diff options
Diffstat (limited to 'drivers/samsung/fm_si4709/Si4705_dev.c')
-rw-r--r-- | drivers/samsung/fm_si4709/Si4705_dev.c | 2064 |
1 files changed, 0 insertions, 2064 deletions
diff --git a/drivers/samsung/fm_si4709/Si4705_dev.c b/drivers/samsung/fm_si4709/Si4705_dev.c deleted file mode 100644 index 0898882..0000000 --- a/drivers/samsung/fm_si4709/Si4705_dev.c +++ /dev/null @@ -1,2064 +0,0 @@ -#include <linux/kernel.h> -#include <linux/i2c.h> -#include <linux/mutex.h> -#include <linux/delay.h> -#include <linux/time.h> -#include <linux/workqueue.h> -#include <linux/interrupt.h> - -#include <mach/gpio.h> -#include <plat/gpio-cfg.h> - -#include "Si4709_regs.h" -#include "Si4709_main.h" -#include "Si4709_dev.h" -#include "Si4709_common.h" - -#if 1 /* To do */ -#include "commanddefs.h" -#include "propertydefs.h" -#endif - - -enum { - eTRUE, - eFALSE, -} dev_struct_status_t; - -/*dev_state*/ -/*power_state*/ -#define RADIO_ON 1 -#define RADIO_POWERDOWN 0 -/*seek_state*/ -#define RADIO_SEEK_ON 1 -#define RADIO_SEEK_OFF 0 - -#define FREQ_87500_kHz 8750 -#define FREQ_76000_kHz 7600 - -#define RSSI_seek_th_MAX 0x7F -#define RSSI_seek_th_MIN 0x00 - -#define seek_SNR_th_DISB 0x00 -#define seek_SNR_th_MIN 0x01 /*most stops */ -#define seek_SNR_th_MAX 0x0F /*fewest stops */ - -#define seek_FM_ID_th_DISB 0x00 -#define seek_FM_ID_th_MAX 0x01 /*most stops */ -#define seek_FM_ID_th_MIN 0x0F /*fewest stops */ - -#define TUNE_RSSI_THRESHOLD 10 -#define TUNE_SNR_THRESHOLD 4 -#define TUNE_CNT_THRESHOLD 0x00 - -#define _ENABLE_RDS_ - -#ifdef RDS_INTERRUPT_ON_ALWAYS -#define RDS_BUFFER_LENGTH 50 -static u16 *RDS_Block_Data_buffer; -static u8 *RDS_Block_Error_buffer; -static u8 RDS_Buffer_Index_read; /* index number for last read data */ -static u8 RDS_Buffer_Index_write; /* index number for last written data */ - -int Si4709_RDS_flag; -int RDS_Data_Available; -int RDS_Data_Lost; -int RDS_Groups_Available_till_now; -struct workqueue_struct *Si4709_wq; -struct work_struct Si4709_work; -#endif - -u8 cmd[8]; -u8 rsp[13]; -u8 RsqInts; -u8 Status; -u8 SMUTE; -u8 AFCRL; -u8 Valid; -u8 Pilot; -u8 Blend; -u16 Freq; -u8 RSSI; -u8 ASNR; -u8 FreqOff; -u8 STC; -u8 BLTF; -u16 AntCap; -u8 RdsInts; -u8 RdsSync; -u8 GrpLost; -u8 RdsFifoUsed; -u16 BlockA; -u16 BlockB; -u16 BlockC; -u16 BlockD; -u8 BleA; -u8 BleB; -u8 BleC; -u8 BleD; - - - -/*static functions*/ -/**********************************************/ -static void wait(void); - -#ifndef RDS_INTERRUPT_ON_ALWAYS -static void wait_RDS(void); -#endif - -static int powerup(void); -static int powerdown(void); - -static int seek(u32 *, int, int); -static int tune_freq(u32); -static u16 freq_to_channel(u32); -static void fmTuneStatus(u8 cancel, u8 intack); -static void fmRsqStatus(u8 intack); -static void si47xx_set_property(u16 propNumber, u16 propValue); -static int si47xx_command(u8 cmd_size, u8 *cmd, u8 reply_size, u8 *reply); -static void fmRdsStatus(u8 intack, u8 mtfifo); -static void fmTuneFreq(u16 frequency); -static void fmSeekStart(u8 seekUp, u8 wrap); -static u8 si47xx_readStatus(void); -static void si47xx_waitForCTS(void); -static u8 getIntStatus(void); -static int i2c_write(u8 number_bytes, u8 *data_out); -static int i2c_read(u8 number_bytes, u8 *data_in); -/**********************************************/ - -/*Si4709 device structure*/ -static struct Si4709_device_t Si4709_dev = { - .client = NULL, - .valid = eFALSE, - .valid_client_state = eFALSE, -}; - -/*Wait flag*/ -/*WAITING or WAIT_OVER or NO_WAIT*/ -int Si4709_dev_wait_flag = NO_WAIT; -#ifdef RDS_INTERRUPT_ON_ALWAYS -int Si4709_RDS_flag = NO_WAIT; -#endif - -unsigned int Si4709_dev_int; -unsigned int Si4709_dev_irq; - -#if defined(CONFIG_MACH_M0) -unsigned int Si4709_dev_sw; -#endif - -#if defined(CONFIG_MACH_M0_CTC) -static const u16 rx_vol[] = { -0x0, 0x15, 0x18, 0x1B, 0x1E, 0x21, 0x24, 0x27, -0x2A, 0x2D, 0x30, 0x33, 0x36, 0x39, 0x3C, 0x3F}; -#else -static const u16 rx_vol[] = { -0x0, 0x13, 0x16, 0x19, 0x1C, 0x1F, 0x22, 0x25, -0x28, 0x2B, 0x2E, 0x31, 0x34, 0x37, 0x3A, 0x3D}; -#endif - - -int Si4709_dev_init(struct i2c_client *client) -{ - int ret = 0; - - debug("Si4709_dev_init called"); - - mutex_lock(&(Si4709_dev.lock)); - - Si4709_dev.client = client; - -#if defined(CONFIG_MACH_M0) - if (system_rev >= 15) - Si4709_dev_int = GPIO_FM_INT_REV15; - else -#endif - Si4709_dev_int = GPIO_FM_INT; - - Si4709_dev_irq = gpio_to_irq(Si4709_dev_int); - -#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_M0_CTC) - Si4709_dev_sw = GPIO_FM_MIC_SW; -#endif - - disable_irq(Si4709_dev_irq); - - Si4709_dev.state.power_state = RADIO_POWERDOWN; - Si4709_dev.state.seek_state = RADIO_SEEK_OFF; - Si4709_dev.valid_client_state = eTRUE; - -#ifdef RDS_INTERRUPT_ON_ALWAYS - /*Creating Circular Buffer */ - /*Single RDS_Block_Data buffer size is 4x16 bits */ - RDS_Block_Data_buffer = kzalloc(RDS_BUFFER_LENGTH * 8, GFP_KERNEL); - if (!RDS_Block_Data_buffer) { - error("Not sufficient memory for creating " - "RDS_Block_Data_buffer"); - ret = -ENOMEM; - goto EXIT; - } - - /*Single RDS_Block_Error buffer size is 4x8 bits */ - RDS_Block_Error_buffer = kzalloc(RDS_BUFFER_LENGTH * 4, GFP_KERNEL); - if (!RDS_Block_Error_buffer) { - error("Not sufficient memory for creating " - "RDS_Block_Error_buffer"); - ret = -ENOMEM; - kfree(RDS_Block_Data_buffer); - goto EXIT; - } - - /*Initialising read and write indices */ - RDS_Buffer_Index_read = 0; - RDS_Buffer_Index_write = 0; - - /*Creating work-queue */ - Si4709_wq = create_singlethread_workqueue("Si4709_wq"); - if (!Si4709_wq) { - error("Not sufficient memory for Si4709_wq, work-queue"); - ret = -ENOMEM; - kfree(RDS_Block_Error_buffer); - kfree(RDS_Block_Data_buffer); - goto EXIT; - } - - /*Initialising work_queue */ - INIT_WORK(&Si4709_work, Si4709_work_func); - - RDS_Data_Available = 0; - RDS_Data_Lost = 0; - RDS_Groups_Available_till_now = 0; -EXIT: -#endif - - mutex_unlock(&(Si4709_dev.lock)); - - debug("Si4709_dev_init call over"); - - return ret; -} - -int Si4709_dev_exit(void) -{ - int ret = 0; - - debug("Si4709_dev_exit called"); - - mutex_lock(&(Si4709_dev.lock)); - - /* Temporary blocked by abnormal function call(E-CIM 2657654) */ - /* DW Shim. 2010.03.04 */ - /* Si4709_dev.client = NULL; */ - - /* Si4709_dev.valid_client_state = eFALSE; */ - /* Si4709_dev.valid = eFALSE; */ - -#ifdef RDS_INTERRUPT_ON_ALWAYS - if (Si4709_wq) - destroy_workqueue(Si4709_wq); - - kfree(RDS_Block_Error_buffer); - kfree(RDS_Block_Data_buffer); -#endif - - mutex_unlock(&(Si4709_dev.lock)); - - debug("Si4709_dev_exit call over"); - - return ret; -} - -void Si4709_dev_mutex_init(void) -{ - mutex_init(&(Si4709_dev.lock)); -} - -int Si4709_dev_powerup(void) -{ - int ret = 0; - u32 value = 100; - - debug("Si4709_dev_powerup called"); - - if (!(RADIO_ON == Si4709_dev.state.power_state)) { - ret = powerup(); - if (ret < 0) { - debug("powerup failed"); - } else if (Si4709_dev.valid_client_state == eFALSE) { - debug("Si4709_dev_powerup called " - "when DS(state, client) is invalid"); - ret = -1; - } else { -/* initial settings */ -#ifdef _ENABLE_RDS_ - si47xx_set_property(FM_RDS_CONFIG, 1); - si47xx_set_property(GPO_IEN, GPO_IEN_STCIEN_MASK | - GPO_IEN_STCREP_MASK); - si47xx_set_property(GPO_IEN, GPO_IEN_STCIEN_MASK | - GPO_IEN_RDSIEN_MASK | GPO_IEN_STCREP_MASK); - si47xx_set_property(FM_RDS_INTERRUPT_SOURCE, - FM_RDS_INTERRUPT_SOURCE_RECV_MASK); - si47xx_set_property(FM_RDS_CONFIG, - FM_RDS_CONFIG_RDSEN_MASK | - (3 << FM_RDS_CONFIG_BLETHA_SHFT) | - (3 << FM_RDS_CONFIG_BLETHB_SHFT) | - (3 << FM_RDS_CONFIG_BLETHC_SHFT) | - (3 << FM_RDS_CONFIG_BLETHD_SHFT)); -#endif -/*VNVS:18-NOV'09 : Setting DE-Time Constant as 50us(Europe,Japan,Australia)*/ - si47xx_set_property(FM_DEEMPHASIS, FM_DEEMPH_50US); - /* SYSCONFIG2_BITSET_SEEKTH( */ - /* &Si4709_dev.registers[SYSCONFIG2],2); */ -/*VNVS:18-NOV'09 : modified for detecting more stations of good quality*/ - si47xx_set_property(FM_SEEK_TUNE_RSSI_THRESHOLD, - TUNE_RSSI_THRESHOLD); - si47xx_set_property(FM_SEEK_BAND_BOTTOM, 8750); - si47xx_set_property(FM_SEEK_BAND_TOP, 10800); - Si4709_dev.settings.band = BAND_87500_108000_kHz; - Si4709_dev.settings.bottom_of_band = FREQ_87500_kHz; - si47xx_set_property(FM_SEEK_FREQ_SPACING, - CHAN_SPACING_100_kHz); - Si4709_dev.settings.channel_spacing = - CHAN_SPACING_100_kHz; - - /* SYSCONFIG3_BITSET_SKSNR( */ - /* &Si4709_dev.registers[SYSCONFIG3],3); */ -/*VNVS:18-NOV'09 : modified for detecting more stations of good quality*/ - si47xx_set_property(FM_SEEK_TUNE_SNR_THRESHOLD, - TUNE_SNR_THRESHOLD); - Si4709_dev.settings.timeout_RDS = - msecs_to_jiffies(value); - Si4709_dev.settings.curr_snr = TUNE_SNR_THRESHOLD; - Si4709_dev.settings.curr_rssi_th = TUNE_RSSI_THRESHOLD; - Si4709_dev_STEREO_SET(); - -/*this will write all the above registers */ - if (ret < 0) - debug("Si4709_dev_powerup i2c_write 1 failed"); - else { - Si4709_dev.valid = eTRUE; -#ifdef RDS_INTERRUPT_ON_ALWAYS -/*Initialising read and write indices */ - RDS_Buffer_Index_read = 0; - RDS_Buffer_Index_write = 0; - - RDS_Data_Available = 0; - RDS_Data_Lost = 0; - RDS_Groups_Available_till_now = 0; -#endif - } - } - } else - debug("Device already Powered-ON"); - enable_irq(Si4709_dev_irq); - si47xx_set_property(0xff00, 0); - - return ret; -} - -int Si4709_dev_powerdown(void) -{ - int ret = 0; - - msleep(500); /* For avoiding turned off pop noise */ - debug("Si4709_dev_powerdown called"); - - mutex_lock(&(Si4709_dev.lock)); - - disable_irq(Si4709_dev_irq); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_powerdown called when DS is invalid"); - ret = -1; - } else { - ret = powerdown(); - if (ret < 0) - debug("powerdown failed"); - } - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_suspend(void) -{ - int ret = 0; - - debug("Si4709_dev_suspend called"); - -#ifndef _ENABLE_RDS_ - disable_irq(Si4709_dev_irq); -#endif - - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid_client_state == eFALSE) { - debug("Si4709_dev_suspend called " - "when DS(state, client) is invalid"); - ret = -1; - } - mutex_unlock(&(Si4709_dev.lock)); - - debug("Si4709_dev_enable call over"); - - return ret; -} - -int Si4709_dev_resume(void) -{ - int ret = 0; - - debug("Si4709_dev_resume called"); - -#ifndef _ENABLE_RDS_ - enable_irq(Si4709_dev_irq); -#endif - - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid_client_state == eFALSE) { - debug("Si4709_dev_resume called " - "when DS(state, client) is invalid"); - ret = -1; - } - - mutex_unlock(&(Si4709_dev.lock)); - debug("Si4709_dev_disable call over"); - - return ret; -} - -int Si4709_dev_band_set(int band) -{ - int ret = 0; - u16 prev_band = 0; - u32 prev_bottom_of_band = 0; - - debug("Si4709_dev_band_set called"); - - prev_band = Si4709_dev.settings.band; - prev_bottom_of_band = Si4709_dev.settings.bottom_of_band; - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_band_set called when DS is invalid"); - ret = -1; - } else { - switch (band) { - case BAND_87500_108000_kHz: - si47xx_set_property(FM_SEEK_BAND_BOTTOM, 8750); - si47xx_set_property(FM_SEEK_BAND_TOP, 10800); - Si4709_dev.settings.band = BAND_87500_108000_kHz; - Si4709_dev.settings.bottom_of_band = FREQ_87500_kHz; - break; - case BAND_76000_108000_kHz: - si47xx_set_property(FM_SEEK_BAND_BOTTOM, 7600); - si47xx_set_property(FM_SEEK_BAND_TOP, 10800); - Si4709_dev.settings.band = BAND_76000_108000_kHz; - Si4709_dev.settings.bottom_of_band = FREQ_76000_kHz; - break; - case BAND_76000_90000_kHz: - si47xx_set_property(FM_SEEK_BAND_BOTTOM, 7600); - si47xx_set_property(FM_SEEK_BAND_TOP, 9000); - Si4709_dev.settings.band = BAND_76000_90000_kHz; - Si4709_dev.settings.bottom_of_band = FREQ_76000_kHz; - break; - default: - ret = -1; - } - } - - return ret; -} - -int Si4709_dev_ch_spacing_set(int ch_spacing) -{ - int ret = 0; - u16 prev_ch_spacing = 0; - - debug("Si4709_dev_ch_spacing_set called"); - - mutex_lock(&(Si4709_dev.lock)); - prev_ch_spacing = Si4709_dev.settings.channel_spacing; - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_ch_spacing_set called " - "when DS is invalid"); - ret = -1; - } else { - switch (ch_spacing) { - case CHAN_SPACING_200_kHz: - si47xx_set_property(FM_SEEK_FREQ_SPACING, 20); - Si4709_dev.settings.channel_spacing = - CHAN_SPACING_200_kHz; - break; - - case CHAN_SPACING_100_kHz: - si47xx_set_property(FM_SEEK_FREQ_SPACING, 10); - Si4709_dev.settings.channel_spacing = - CHAN_SPACING_100_kHz; - break; - - case CHAN_SPACING_50_kHz: - si47xx_set_property(FM_SEEK_FREQ_SPACING, 5); - Si4709_dev.settings.channel_spacing = - CHAN_SPACING_50_kHz; - break; - - default: - ret = -1; - } - - if (ret == 0) { - if (ret < 0) { - debug("Si4709_dev_ch_spacing_set " - "i2c_write 1 failed"); - Si4709_dev.settings.channel_spacing = - prev_ch_spacing; - } - } - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_chan_select(u32 frequency) -{ - int ret = 0; - - debug("Si4709_dev_chan_select called"); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_chan_select called when DS is invalid"); - ret = -1; - } else { - Si4709_dev.state.seek_state = RADIO_SEEK_ON; - - ret = tune_freq(frequency); - debug("Si4709_dev_chan_select called1"); - Si4709_dev.state.seek_state = RADIO_SEEK_OFF; - } - return ret; -} - -int Si4709_dev_chan_get(u32 *frequency) -{ - int ret = 0; - - debug("Si4709_dev_chan_get called"); - - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_chan_get called when DS is invalid"); - ret = -1; - } else { - if (ret < 0) - debug("Si4709_dev_chan_get i2c_read failed"); - else { - fmTuneStatus(0, 0); - *frequency = Freq; - } - } - mutex_unlock(&(Si4709_dev.lock)); - return ret; -} - -int Si4709_dev_seek_full(u32 *frequency) -{ - int ret = 0; - - debug("Si4709_dev_seek_full called\n"); - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_seek_full called when DS is invalid"); - ret = -1; - } else { - Si4709_dev.state.seek_state = RADIO_SEEK_ON; - ret = seek(frequency, 1, 0); - Si4709_dev.state.seek_state = RADIO_SEEK_OFF; - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_seek_up(u32 *frequency) -{ - int ret = 0; - - debug("Si4709_dev_seek_up called\n"); - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_seek_up called when DS is invalid"); - ret = -1; - } else { - Si4709_dev.state.seek_state = RADIO_SEEK_ON; - ret = seek(frequency, 1, 1); - Si4709_dev.state.seek_state = RADIO_SEEK_OFF; - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_seek_down(u32 *frequency) -{ - int ret = 0; - - debug("Si4709_dev_seek_down called\n"); - - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_seek_down called when DS is invalid"); - ret = -1; - } else { - Si4709_dev.state.seek_state = RADIO_SEEK_ON; - - ret = seek(frequency, 0, 1); - - Si4709_dev.state.seek_state = RADIO_SEEK_OFF; - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_RSSI_seek_th_set(u8 seek_th) -{ - int ret = 0; - - debug("Si4709_dev_RSSI_seek_th_set called"); - - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_RSSI_seek_th_set called " - "when DS is invalid"); - ret = -1; - } else { - si47xx_set_property(FM_SEEK_TUNE_RSSI_THRESHOLD, seek_th); - Si4709_dev.settings.curr_rssi_th = seek_th; - if (ret < 0) - debug("Si4709_dev_RSSI_seek_th_set i2c_write 1 failed"); - } - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_seek_SNR_th_set(u8 seek_SNR) -{ - int ret = 0; - - debug("Si4709_dev_seek_SNR_th_set called"); - - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_seek_SNR_th_set called " - "when DS is invalid"); - ret = -1; - } else { - si47xx_set_property(FM_SEEK_TUNE_SNR_THRESHOLD, seek_SNR); - Si4709_dev.settings.curr_snr = seek_SNR; - - if (ret < 0) - debug("Si4709_dev_seek_SNR_th_set i2c_write 1 failed"); - } - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_seek_FM_ID_th_set(u8 seek_FM_ID_th) -{ - int ret = 0; - - debug("Si4709_dev_seek_FM_ID_th_set called"); - - return ret; -} - -int Si4709_dev_cur_RSSI_get(struct rssi_snr_t *cur_RSSI) -{ - int ret = 0; - - debug("Si4709_dev_cur_RSSI_get called"); - - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_cur_RSSI_get called when DS is invalid"); - ret = -1; - } else { - fmRsqStatus(0); - if (ret < 0) { - debug("Si4709_dev_cur_RSSI_get i2c_read 1 failed"); - } else { - cur_RSSI->curr_rssi = RSSI; - cur_RSSI->curr_rssi_th = - Si4709_dev.settings.curr_rssi_th; - cur_RSSI->curr_snr = Si4709_dev.settings.curr_snr; - } - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -/* VNVS:START 13-OCT'09 : - Functions which reads device-id,chip-id,power configuration, - system configuration2 registers - */ -int Si4709_dev_device_id(struct device_id *dev_id) -{ - int ret = 0; - - debug("Si4709_dev_device_id called"); -#if 0 /*To Do*/ - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_device_id called when DS is invalid"); - ret = -1; - } else { - ret = i2c_read(DEVICE_ID); - if (ret < 0) { - debug("Si4709_dev_device_id i2c_read failed"); - } else { - dev_id->part_number = - DEVICE_ID_PART_NUMBER(Si4709_dev. - registers[DEVICE_ID]); - dev_id->manufact_number = - DEVICE_ID_MANUFACT_NUMBER(Si4709_dev. - registers[DEVICE_ID]); - } - } - - mutex_unlock(&(Si4709_dev.lock)); -#endif - return ret; -} - -int Si4709_dev_chip_id(struct chip_id *chp_id) -{ - int ret = 0; - - debug("Si4709_dev_chip_id called"); -#if 0 /*To Do*/ - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_chip_id called when DS is invalid"); - ret = -1; - } else { - ret = i2c_read(CHIP_ID); - if (ret < 0) { - debug("Si4709_dev_chip_id i2c_read failed"); - } else { - chp_id->chip_version = - CHIP_ID_CHIP_VERSION( - Si4709_dev.registers[CHIP_ID]); - chp_id->device = - CHIP_ID_DEVICE(Si4709_dev.registers[CHIP_ID]); - chp_id->firmware_version = - CHIP_ID_FIRMWARE_VERSION(Si4709_dev. - registers[CHIP_ID]); - } - } - - mutex_unlock(&(Si4709_dev.lock)); -#endif - return ret; -} - -int Si4709_dev_sys_config2(struct sys_config2 *sys_conf2) -{ - int ret = 0; - - debug("Si4709_sys_config2 called\n"); - - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_sys_config2 called when DS is invalid"); - ret = -1; - } else { - if (ret < 0) { - debug("Si4709_sys_config2 i2c_read failed"); - } else { - sys_conf2->rssi_th = Si4709_dev.settings.curr_rssi_th; - sys_conf2->fm_band = Si4709_dev.settings.band; - sys_conf2->fm_chan_spac = - Si4709_dev.settings.channel_spacing; - sys_conf2->fm_vol = 0; - } - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_sys_config3(struct sys_config3 *sys_conf3) -{ - int ret = 0; - - debug("Si4709_sys_config3 called\n"); - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_sys_config3 called when DS is invalid"); - mutex_unlock(&(Si4709_dev.lock)); - return -1; - } - if (ret < 0) { - debug("Si4709_sys_config3 i2c_read failed"); - } else { - sys_conf3->smmute = 0; - sys_conf3->smutea = 0; - sys_conf3->volext = 0; - sys_conf3->sksnr = Si4709_dev.settings.curr_snr; - sys_conf3->skcnt = 0; - } - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_status_rssi(struct status_rssi *status) -{ - int ret = 0; - - debug("Si4709_dev_status_rssi called"); - - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_status_rssi called when DS is invalid"); - mutex_unlock(&(Si4709_dev.lock)); - return -1; - } - fmRsqStatus(0); - if (ret < 0) { - debug("Si4709_sys_config3 i2c_read failed"); - } else { - debug("Si4709_dev_status_rssi %d\n", RSSI); - status->rssi = RSSI; - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_sys_config2_set(struct sys_config2 *sys_conf2) -{ - int ret = 0; - u16 register_bak = 0; - - debug("Si4709_dev_sys_config2_set called"); - - mutex_lock(&(Si4709_dev.lock)); - - register_bak = Si4709_dev.registers[SYSCONFIG2]; - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_sys_config2_set called when DS is invalid"); - ret = -1; - } else { - si47xx_set_property(FM_SEEK_TUNE_RSSI_THRESHOLD, - sys_conf2->rssi_th); - Si4709_dev_band_set(sys_conf2->fm_band); - si47xx_set_property(FM_SEEK_FREQ_SPACING, - sys_conf2->fm_chan_spac); - Si4709_dev.settings.curr_rssi_th = sys_conf2->rssi_th; - Si4709_dev.settings.band = sys_conf2->fm_band; - Si4709_dev.settings.channel_spacing = sys_conf2->fm_chan_spac; - - if (ret < 0) { - debug("Si4709_dev_sys_config2_set i2c_write 1 failed"); - } else - debug(KERN_ERR "Si4709_dev_sys_config2_set() " - ": Write Sucess!!"); - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_sys_config3_set(struct sys_config3 *sys_conf3) -{ - int ret = 0; - u16 register_bak = 0; - - debug("Si4709_dev_sys_config3_set called"); - - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_sys_config3_set called " - "when DS is invalid"); - ret = -1; - } else { - si47xx_set_property(FM_SEEK_TUNE_SNR_THRESHOLD, - sys_conf3->sksnr); - Si4709_dev.settings.curr_snr = sys_conf3->sksnr; - if (ret < 0) { - debug("Si4709_dev_sys_config3_set i2c_write 1 failed"); - Si4709_dev.registers[SYSCONFIG3] = register_bak; - } - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_power_config(struct power_config *pow_conf) -{ - int ret = 0; - - debug("Si4709_dev_power_config called"); - - return ret; -} - -/* VNVS:END */ - -/* VNVS:START 18-NOV'09 */ -/* Reading AFCRL Bit */ -int Si4709_dev_AFCRL_get(u8 *afc) -{ - int ret = 0; - - debug("Si4709_dev_AFCRL_get called"); - - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_AFCRL_get called when DS is invalid"); - ret = -1; - } else { - fmRsqStatus(0); - if (ret < 0) - debug("Si4709_dev_AFCRL_get i2c_read failed"); - *afc = AFCRL; - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -/* Setting DE - emphasis time constant 50us(Europe,Japan,Australia) or 75us(USA) - */ -int Si4709_dev_DE_set(u8 de_tc) -{ - u16 sysconfig1 = 0; - int ret = 0; - - debug("Si4709_dev_DE_set called"); - - mutex_lock(&(Si4709_dev.lock)); - - sysconfig1 = Si4709_dev.registers[SYSCONFIG1]; - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_DE_set called when DS is invalid"); - ret = -1; - } else { - switch (de_tc) { - case DE_TIME_CONSTANT_50: - si47xx_set_property(FM_DEEMPHASIS, FM_DEEMPH_50US); - break; - - case DE_TIME_CONSTANT_75: - si47xx_set_property(FM_DEEMPHASIS, FM_DEEMPH_75US); - break; - - default: - ret = -1; - } - - if (0 == ret) { - if (ret < 0) - debug("Si4709_dev_DE_set i2c_write failed"); - } - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -/*Resetting the RDS Data Buffer*/ -int Si4709_dev_reset_rds_data() -{ - int ret = 0; - - debug_rds("Si4709_dev_reset_rds_data called"); - - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_reset_rds_data called when DS is invalid"); - ret = -1; - } else { - RDS_Buffer_Index_write = 0; - RDS_Buffer_Index_read = 0; - RDS_Data_Lost = 0; - RDS_Data_Available = 0; - memset(RDS_Block_Data_buffer, 0, RDS_BUFFER_LENGTH * 8); - memset(RDS_Block_Error_buffer, 0, RDS_BUFFER_LENGTH * 4); - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -/*VNVS:END*/ - -int Si4709_dev_VOLEXT_ENB(void) -{ - int ret = 0; - - debug("Si4709_dev_VOLEXT_ENB called"); - - return ret; -} - -int Si4709_dev_VOLEXT_DISB(void) -{ - int ret = 0; - - debug("Si4709_dev_VOLEXT_DISB called"); - - return ret; -} - -int Si4709_dev_volume_set(u8 volume) -{ - int ret = 0; - u16 sysconfig2 = 0; - - debug("Si4709_dev_volume_set called"); - - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_volume_set called when DS is invalid"); - ret = -1; - } else { - si47xx_set_property(RX_VOLUME, rx_vol[volume] & RX_VOLUME_MASK); - - if (ret < 0) { - debug("Si4709_dev_volume_set i2c_write failed"); - Si4709_dev.registers[SYSCONFIG2] = sysconfig2; - } - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_volume_get(u8 *volume) -{ - int ret = 0; - - debug("Si4709_dev_volume_get called"); -#if 0 /*To Do*/ - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_volume_get called when DS is invalid"); - ret = -1; - } else - *volume = - SYSCONFIG2_GET_VOLUME(Si4709_dev.registers[SYSCONFIG2]); - - mutex_unlock(&(Si4709_dev.lock)); -#endif - return ret; -} - -/* -VNVS:START 19-AUG'10 : Adding DSMUTE ON/OFF feature. -The Soft Mute feature is available to attenuate the audio -outputs and minimize audible noise in very weak signal conditions. - */ -int Si4709_dev_DSMUTE_ON(void) -{ - int ret = 0; - u16 powercfg = 0; - - debug("Si4709_dev_DSMUTE_ON called"); - - mutex_lock(&(Si4709_dev.lock)); - - powercfg = Si4709_dev.registers[POWERCFG]; - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_DSMUTE_ON called when DS is invalid"); - ret = -1; - } else { - si47xx_set_property(FM_SOFT_MUTE_RATE, 64); - si47xx_set_property(FM_SOFT_MUTE_MAX_ATTENUATION, 0); - si47xx_set_property(FM_SOFT_MUTE_SNR_THRESHOLD, 4); - if (ret < 0) - error("Si4709_dev_DSMUTE_ON i2c_write failed"); - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_DSMUTE_OFF(void) -{ - int ret = 0; - u16 powercfg = 0; - - debug("Si4709_dev_DSMUTE_OFF called"); - - mutex_lock(&(Si4709_dev.lock)); - - powercfg = Si4709_dev.registers[POWERCFG]; - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_DSMUTE_OFF called when DS is invalid"); - ret = -1; - } else { - si47xx_set_property(FM_SOFT_MUTE_RATE, 64); - si47xx_set_property(FM_SOFT_MUTE_MAX_ATTENUATION, 16); - si47xx_set_property(FM_SOFT_MUTE_SNR_THRESHOLD, 4); - if (ret < 0) - error("Si4709_dev_DSMUTE_OFF i2c_write failed"); - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -/*VNVS:END*/ - -int Si4709_dev_MUTE_ON(void) -{ - int ret = 0; - u16 powercfg = 0; - - debug("Si4709_dev_MUTE_ON called"); - - mutex_lock(&(Si4709_dev.lock)); - - powercfg = Si4709_dev.registers[POWERCFG]; - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_MUTE_ON called when DS is invalid"); - ret = -1; - } else { - si47xx_set_property(RX_HARD_MUTE, - RX_HARD_MUTE_RMUTE_MASK | - RX_HARD_MUTE_LMUTE_MASK); - if (ret < 0) - debug("Si4709_dev_MUTE_ON i2c_write failed"); - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_MUTE_OFF(void) -{ - int ret = 0; - u16 powercfg = 0; - - debug("Si4709_dev_MUTE_OFF called"); - - mutex_lock(&(Si4709_dev.lock)); - - powercfg = Si4709_dev.registers[POWERCFG]; - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_MUTE_OFF called when DS is invalid"); - ret = -1; - } else { - si47xx_set_property(RX_HARD_MUTE, 0); - if (ret < 0) - debug("Si4709_dev_MUTE_OFF i2c_write failed"); - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_MONO_SET(void) -{ - int ret = 0; - u16 powercfg = 0; - - debug("Si4709_dev_MONO_SET called"); - - mutex_lock(&(Si4709_dev.lock)); - - powercfg = Si4709_dev.registers[POWERCFG]; - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_MONO_SET called when DS is invalid"); - ret = -1; - } else { - si47xx_set_property(FM_BLEND_MONO_THRESHOLD, 127); - si47xx_set_property(FM_BLEND_STEREO_THRESHOLD, 127); - if (ret < 0) - debug("Si4709_dev_MONO_SET i2c_write failed"); - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_STEREO_SET(void) -{ - int ret = 0; - u16 powercfg = 0; - - debug("Si4709_dev_STEREO_SET called"); - - mutex_lock(&(Si4709_dev.lock)); - - powercfg = Si4709_dev.registers[POWERCFG]; - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_STEREO_SET called when DS is invalid"); - ret = -1; - } else { - si47xx_set_property(FM_BLEND_MONO_THRESHOLD, 30); - si47xx_set_property(FM_BLEND_STEREO_THRESHOLD, 49); - if (ret < 0) - debug("Si4709_dev_STEREO_SET i2c_write failed"); - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_RDS_ENABLE(void) -{ - int ret = 0; - - debug("Si4709_dev_RDS_ENABLE called"); - - mutex_lock(&(Si4709_dev.lock)); - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_RDS_ENABLE called when DS is invalid"); - ret = -1; - } else { -#ifdef RDS_INTERRUPT_ON_ALWAYS - si47xx_set_property(GPO_IEN, GPO_IEN_STCIEN_MASK | - GPO_IEN_STCREP_MASK | GPO_IEN_RDSIEN_MASK | - GPO_IEN_RDSREP_MASK); -#endif - si47xx_set_property(FM_RDS_INTERRUPT_SOURCE, - FM_RDS_INTERRUPT_SOURCE_RECV_MASK); - si47xx_set_property(FM_RDS_CONFIG, FM_RDS_CONFIG_RDSEN_MASK | - (3 << FM_RDS_CONFIG_BLETHA_SHFT) | - (3 << FM_RDS_CONFIG_BLETHB_SHFT) | - (3 << FM_RDS_CONFIG_BLETHC_SHFT) | - (3 << FM_RDS_CONFIG_BLETHD_SHFT)); - if (ret < 0) - debug("Si4709_dev_RDS_ENABLE i2c_write failed"); -#ifdef RDS_INTERRUPT_ON_ALWAYS - else - Si4709_RDS_flag = RDS_WAITING; -#endif - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_RDS_DISABLE(void) -{ - int ret = 0; - - debug("Si4709_dev_RDS_DISABLE called"); - - mutex_lock(&(Si4709_dev.lock)); - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_RDS_DISABLE called when DS is invalid"); - ret = -1; - } else { - si47xx_set_property(FM_RDS_CONFIG, 0); - - if (ret < 0) - debug("Si4709_dev_RDS_DISABLE i2c_write failed"); -#ifdef RDS_INTERRUPT_ON_ALWAYS - else - Si4709_RDS_flag = NO_WAIT; -#endif - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_rstate_get(struct dev_state_t *dev_state) -{ - int ret = 0; - - debug("Si4709_dev_rstate_get called"); - - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_rstate_get called when DS is invalid"); - ret = -1; - } else { - dev_state->power_state = Si4709_dev.state.power_state; - dev_state->seek_state = Si4709_dev.state.seek_state; - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -/* VNVS:START 7-JUNE'10 Function call for work-queue "Si4709_wq" */ -#ifdef RDS_INTERRUPT_ON_ALWAYS -void Si4709_work_func(struct work_struct *work) -{ - int i = 0; -#ifdef RDS_TESTING - u8 group_type; -#endif - debug_rds("%s", __func__); -mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - error("Si4709_dev_RDS_data_get called when DS is invalid"); - return; - } - - if (RDS_Data_Lost > 1) - debug_rds("No_of_RDS_groups_Lost till now : %d", - RDS_Data_Lost); - fmRdsStatus(1, 0); - /* RDSR bit and RDS Block data, so reading the RDS registers */ - do { - /* Writing into RDS_Block_Data_buffer */ - i = 0; - RDS_Block_Data_buffer[i++ + 4 * RDS_Buffer_Index_write] = - BlockA; - RDS_Block_Data_buffer[i++ + 4 * RDS_Buffer_Index_write] = - BlockB; - RDS_Block_Data_buffer[i++ + 4 * RDS_Buffer_Index_write] = - BlockC; - RDS_Block_Data_buffer[i++ + 4 * RDS_Buffer_Index_write] = - BlockD; - - /*Writing into RDS_Block_Error_buffer */ - i = 0; - - RDS_Block_Error_buffer[i++ + 4 * RDS_Buffer_Index_write] = - BleA; - RDS_Block_Error_buffer[i++ + 4 * RDS_Buffer_Index_write] = - BleB; - RDS_Block_Error_buffer[i++ + 4 * RDS_Buffer_Index_write] = - BleC; - RDS_Block_Error_buffer[i++ + 4 * RDS_Buffer_Index_write] = - BleD; - fmRdsStatus(1, 0); - } while (RdsFifoUsed != 0); - -#ifdef RDS_TESTING - if (RDS_Block_Error_buffer - [0 + 4 * RDS_Buffer_Index_write] < 3) { - debug_rds("PI Code is %d", - RDS_Block_Data_buffer[0 + 4 - * RDS_Buffer_Index_write]); - } - if (RDS_Block_Error_buffer - [1 + 4 * RDS_Buffer_Index_write] < 2) { - group_type = RDS_Block_Data_buffer[1 + 4 - * RDS_Buffer_Index_write] >> 11; - - if (group_type & 0x01) { - debug_rds("PI Code is %d", - RDS_Block_Data_buffer[2 + 4 - * RDS_Buffer_Index_write]); - } - if (group_type == GROUP_TYPE_2A - || group_type == GROUP_TYPE_2B) { - if (RDS_Block_Error_buffer - [2 + 4 * RDS_Buffer_Index_write] < 3) { - debug_rds("Update RT with RDSC"); - } else { - debug_rds("RDS_Block_Error_buffer" - " of Block C is greater than 3"); - } - } - } -#endif - RDS_Buffer_Index_write++; - - if (RDS_Buffer_Index_write >= RDS_BUFFER_LENGTH) - RDS_Buffer_Index_write = 0; - - debug_rds("RDS_Buffer_Index_write = %d", RDS_Buffer_Index_write); - mutex_unlock(&(Si4709_dev.lock)); -} -#endif -/*VNVS:END*/ - -int Si4709_dev_RDS_data_get(struct radio_data_t *data) -{ - int i, ret = 0; - - debug_rds("Si4709_dev_RDS_data_get called"); - - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - error("Si4709_dev_RDS_data_get called when DS is invalid"); - mutex_unlock(&(Si4709_dev.lock)); - return -1; - } -#ifdef RDS_INTERRUPT_ON_ALWAYS - debug_rds("RDS_Buffer_Index_read = %d", RDS_Buffer_Index_read); - - /*If No New RDS Data is available return error */ - if (RDS_Buffer_Index_read == RDS_Buffer_Index_write) { - debug_rds("No_New_RDS_Data_is_available"); - if (ret < 0) - error("Si4709_dev_RDS_data_get i2c_read 1 failed"); - else { - fmTuneStatus(0, 0); - data->curr_channel = Freq; - data->curr_rssi = RSSI; - debug_rds("curr_channel: %u, curr_rssi:%u", - data->curr_channel, - (u32) data->curr_rssi); - } - mutex_unlock(&(Si4709_dev.lock)); - return -1; - } - if (ret < 0) - error("Si4709_dev_RDS_data_get i2c_read 2 failed"); - else { - fmTuneStatus(0, 0); - data->curr_channel = Freq; - data->curr_rssi = RSSI; - debug_rds("curr_channel: %u, curr_rssi:%u", - data->curr_channel, (u32) data->curr_rssi); - - /* Reading from RDS_Block_Data_buffer */ - i = 0; - data->rdsa = RDS_Block_Data_buffer[i++ + 4 - * RDS_Buffer_Index_read]; - data->rdsb = RDS_Block_Data_buffer[i++ + 4 - * RDS_Buffer_Index_read]; - data->rdsc = RDS_Block_Data_buffer[i++ + 4 - * RDS_Buffer_Index_read]; - data->rdsd = RDS_Block_Data_buffer[i++ + 4 - * RDS_Buffer_Index_read]; - - /* Reading from RDS_Block_Error_buffer */ - i = 0; - data->blera = RDS_Block_Error_buffer[i++ + 4 - * RDS_Buffer_Index_read]; - data->blerb = RDS_Block_Error_buffer[i++ + 4 - * RDS_Buffer_Index_read]; - data->blerc = RDS_Block_Error_buffer[i++ + 4 - * RDS_Buffer_Index_read]; - data->blerd = RDS_Block_Error_buffer[i++ + 4 - * RDS_Buffer_Index_read]; - - /*Flushing the read data */ - memset(&RDS_Block_Data_buffer[0 + 4 * RDS_Buffer_Index_read], - 0, 8); - memset(&RDS_Block_Error_buffer[0 + 4 * RDS_Buffer_Index_read], - 0, 4); - - RDS_Buffer_Index_read++; - - if (RDS_Buffer_Index_read >= RDS_BUFFER_LENGTH) - RDS_Buffer_Index_read = 0; - } - - debug_rds("RDS_Buffer_Index_read = %d", RDS_Buffer_Index_read); -#else -#if 0 /*To Do*/ - SYSCONFIG1_BITSET_RDSIEN_HIGH(&Si4709_dev.registers[SYSCONFIG1]); - - ret = i2c_write(SYSCONFIG1); - if (ret < 0) { - debug("Si4709_dev_RDS_data_get i2c_write 1 failed"); - Si4709_dev.registers[SYSCONFIG1] = sysconfig1; - } else { - ret = i2c_read(SYSCONFIG1); - if (ret < 0) - debug("Si4709_dev_RDS_data_get i2c_read 1 failed"); - - debug("sysconfig1: 0x%x", Si4709_dev.registers[SYSCONFIG1]); - - sysconfig1 = Si4709_dev.registers[SYSCONFIG1]; - - Si4709_dev_wait_flag = RDS_WAITING; - - wait_RDS(); - - ret = i2c_read(STATUSRSSI); - if (ret < 0) - debug("Si4709_dev_RDS_data_get i2c_read 2 failed"); - - debug("statusrssi: 0x%x", Si4709_dev.registers[STATUSRSSI]); - - SYSCONFIG1_BITSET_RDSIEN_LOW(&Si4709_dev.registers[SYSCONFIG1]); - - ret = i2c_write(SYSCONFIG1); - if (ret < 0) { - debug("Si4709_dev_RDS_data_get i2c_write 2 failed"); - Si4709_dev.registers[SYSCONFIG1] = sysconfig1; - } else if (Si4709_dev_wait_flag == WAIT_OVER) { - Si4709_dev_wait_flag = NO_WAIT; - - ret = i2c_read(RDSD); - if (ret < 0) - debug("Si4709_dev_RDS_data_get " - "i2c_read 3 failed"); - else { - data->rdsa = Si4709_dev.registers[RDSA]; - data->rdsb = Si4709_dev.registers[RDSB]; - data->rdsc = Si4709_dev.registers[RDSC]; - data->rdsd = Si4709_dev.registers[RDSD]; - - get_cur_chan_freq(&(data->curr_channel), - Si4709_dev.registers[READCHAN]); - debug("curr_channel: %u", data->curr_channel); - data->curr_rssi = - STATUSRSSI_RSSI_SIGNAL_STRENGTH - (Si4709_dev.registers[STATUSRSSI]); - debug("curr_rssi:%u", (u32)data->curr_rssi); - data->blera = - STATUSRSSI_RDS_BLOCK_A_ERRORS - (Si4709_dev.registers[STATUSRSSI]); - data->blerb = - READCHAN_BLOCK_B_ERRORS(Si4709_dev. - registers[READCHAN]); - data->blerc = - READCHAN_BLOCK_C_ERRORS(Si4709_dev. - registers[READCHAN]); - data->blerd = - READCHAN_BLOCK_D_ERRORS(Si4709_dev. - registers[READCHAN]); - } - } else { - debug("Si4709_dev_RDS_data_get failure " - "no interrupt or timeout"); - Si4709_dev_wait_flag = NO_WAIT; - mutex_unlock(&(Si4709_dev.lock)); - return -1; - } - } -#endif -#endif - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -int Si4709_dev_RDS_timeout_set(u32 time_out) -{ - int ret = 0; - u32 jiffy_count = 0; - - debug("Si4709_dev_RDS_timeout_set called"); - /****convert time_out(in milliseconds) into jiffies*****/ - - jiffy_count = msecs_to_jiffies(time_out); - - debug("jiffy_count%d", jiffy_count); - - mutex_lock(&(Si4709_dev.lock)); - - if (Si4709_dev.valid == eFALSE) { - debug("Si4709_dev_RDS_timeout_set called when DS is invalid"); - ret = -1; - } else { - Si4709_dev.settings.timeout_RDS = jiffy_count; - } - - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -/**************************************************************/ -static int powerup(void) -{ - int ret = 0; - u16 powercfg = Si4709_dev.registers[POWERCFG]; - -#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_M0_CTC) - gpio_set_value(Si4709_dev_sw, GPIO_LEVEL_HIGH); -#endif - - gpio_set_value(GPIO_FM_RST, GPIO_LEVEL_LOW); - usleep_range(5, 10); - s3c_gpio_cfgpin(Si4709_dev_int, S3C_GPIO_OUTPUT); - s3c_gpio_setpull(Si4709_dev_int, S3C_GPIO_PULL_DOWN); - gpio_set_value(Si4709_dev_int, GPIO_LEVEL_LOW); - usleep_range(10, 15); - gpio_set_value(GPIO_FM_RST, GPIO_LEVEL_HIGH); - usleep_range(5, 10); - s3c_gpio_cfgpin(Si4709_dev_int, S3C_GPIO_SFN(0xF)); - s3c_gpio_setpull(Si4709_dev_int, S3C_GPIO_PULL_UP); - usleep_range(10, 15); - - cmd[0] = POWER_UP; - cmd[1] = POWER_UP_IN_GPO2OEN; - cmd[1] |= POWER_UP_IN_FUNC_FMRX; - cmd[2] = POWER_UP_IN_OPMODE_RX_ANALOG; - ret = si47xx_command(3, cmd, 8, rsp); - - if (ret < 0) { - debug("powerup->i2c_write 1 failed"); - Si4709_dev.registers[POWERCFG] = powercfg; - } else { - /* Si4709/09 datasheet: Table 7 */ - msleep(110); - Si4709_dev.state.power_state = RADIO_ON; - } - return ret; -} - -static int powerdown(void) -{ - int ret = 0; - - if (!(RADIO_POWERDOWN == Si4709_dev.state.power_state)) { - cmd[0] = POWER_DOWN; - ret = si47xx_command(1, cmd, 1, rsp); - msleep(110); - - if (ret < 0) - debug("powerdown->i2c_write failed"); - else - Si4709_dev.state.power_state = RADIO_POWERDOWN; - - gpio_set_value(GPIO_FM_RST, GPIO_LEVEL_LOW); - } else - debug("Device already Powered-OFF\n"); - -#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_M0_CTC) - gpio_set_value(Si4709_dev_sw, GPIO_LEVEL_LOW); -#endif - - return ret; -} - -static int seek(u32 *frequency, int up, int mode) -{ - int ret = 0; - u8 get_int; - - if (ret < 0) { - debug("seek i2c_write 1 failed"); - } else { - Si4709_dev_wait_flag = SEEK_WAITING; - fmSeekStart(up, mode); /* mode 0 is full scan */ - wait(); - do { - get_int = getIntStatus(); - } while (!(get_int & STCINT)); - - if (Si4709_dev_wait_flag == SEEK_CANCEL) { - fmTuneStatus(1, 0); - if (ret < 0) { - debug("seek i2c_write 2 failed"); - } - if (ret < 0) - debug("seek i2c_read 1 failed"); - else - *frequency = Freq; - - *frequency = 0; - } - - Si4709_dev_wait_flag = NO_WAIT; - - fmTuneStatus(0, 1); - if (BLTF != 1) - *frequency = Freq; - - else { - if (Valid) - *frequency = Freq; - else - *frequency = 0; - } - } - return ret; -} - -static int tune_freq(u32 frequency) -{ - int ret = 0; - - u16 channel = Si4709_dev.registers[CHANNEL]; - mutex_lock(&(Si4709_dev.lock)); - - channel = freq_to_channel(frequency); - if (ret < 0) { - debug("tune_freq i2c_write 1 failed"); - Si4709_dev.registers[CHANNEL] = channel; - } else { - Si4709_dev_wait_flag = TUNE_WAITING; - fmTuneFreq(frequency); - wait(); - Si4709_dev_wait_flag = NO_WAIT; - debug("Si4709_dev_wait_flag = TUNE_WAITING\n"); - - if (!(getIntStatus() & STCINT)) { - printk(KERN_INFO "%s tune is failed!\n", __func__); - fmTuneStatus(1, 1); - mutex_unlock(&(Si4709_dev.lock)); - return -1; - } - - fmTuneStatus(0, 1); - - debug("Si4709 tune_freq fmTuneStatus %x\n", rsp[0]); - - } - mutex_unlock(&(Si4709_dev.lock)); - - return ret; -} - -static u16 freq_to_channel(u32 frequency) -{ - u16 channel; - - if (frequency < Si4709_dev.settings.bottom_of_band) - frequency = Si4709_dev.settings.bottom_of_band; - - channel = (frequency - Si4709_dev.settings.bottom_of_band) - / Si4709_dev.settings.channel_spacing; - - return channel; -} - -/* Only one thread will be able to call this, since this function call is - protected by a mutex, so no race conditions can arise */ -static void wait(void) -{ - wait_event_interruptible(Si4709_waitq, - (Si4709_dev_wait_flag == WAIT_OVER) || - (Si4709_dev_wait_flag == SEEK_CANCEL)); -} - -#ifndef RDS_INTERRUPT_ON_ALWAYS -static void wait_RDS(void) -{ - wait_event_interruptible_timeout(Si4709_waitq, - (Si4709_dev_wait_flag == WAIT_OVER), - Si4709_dev.settings.timeout_RDS); -} -#endif - -/*----------------------------------------------------------------------------- - Helper function that sends the GET_INT_STATUS command to the part - - Returns: - The status byte from the part. ------------------------------------------------------------------------------*/ -u8 getIntStatus(void) -{ - cmd[0] = GET_INT_STATUS; - si47xx_command(1, cmd, 1, rsp); - - debug("Si4709 getIntStatus return %x\n", rsp[0]); - return rsp[0]; -} - -/*----------------------------------------------------------------------------- - Helper function that sends the FM_TUNE_FREQ command to the part - - Inputs: - frequency in 10kHz steps ------------------------------------------------------------------------------*/ -static void fmTuneFreq(u16 frequency) -{ - cmd[0] = FM_TUNE_FREQ; - cmd[1] = 0; - cmd[2] = (u8)(frequency >> 8); - cmd[3] = (u8)(frequency & 0x00FF); - cmd[4] = (u8)0; - si47xx_command(5, cmd, 1, rsp); -} - -/*----------------------------------------------------------------------------- - Helper function that sends the FM_TUNE_STATUS command to the part - - Inputs: - cancel: If non-zero the current seek will be cancelled. - intack: If non-zero the interrupt for STCINT will be cleared. - -Outputs: These are global variables and are set by this method -STC: The seek/tune is complete -BLTF: The seek reached the band limit or original start frequency -AFCRL: The AFC is railed if this is non-zero -Valid: The station is valid if this is non-zero -Freq: The current frequency -RSSI: The RSSI level read at tune. -ASNR: The audio SNR level read at tune. -AntCap: The current level of the tuning capacitor. ------------------------------------------------------------------------------*/ - -static void fmTuneStatus(u8 cancel, u8 intack) -{ - cmd[0] = FM_TUNE_STATUS; - cmd[1] = 0; - if (cancel) - cmd[1] |= FM_TUNE_STATUS_IN_CANCEL; - if (intack) - cmd[1] |= FM_TUNE_STATUS_IN_INTACK; - - si47xx_command(2, cmd, 8, rsp); - - STC = !!(rsp[0] & STCINT); - BLTF = !!(rsp[1] & FM_TUNE_STATUS_OUT_BTLF); - AFCRL = !!(rsp[1] & FM_TUNE_STATUS_OUT_AFCRL); - Valid = !!(rsp[1] & FM_TUNE_STATUS_OUT_VALID); - Freq = ((u16)rsp[2] << 8) | (u16)rsp[3]; - RSSI = rsp[4]; - ASNR = rsp[5]; - AntCap = rsp[7]; -} - -/*----------------------------------------------------------------------------- - Helper function that sends the FM_RDS_STATUS command to the part - - Inputs: - intack: If non-zero the interrupt for STCINT will be cleared. - mtfifo: If non-zero the fifo will be cleared. - -Outputs: -Status: Contains bits about the status returned from the part. -RdsInts: Contains bits about the interrupts that have fired -related to RDS. -RdsSync: If non-zero the RDS is currently synced. -GrpLost: If non-zero some RDS groups were lost. -RdsFifoUsed: The amount of groups currently remaining -in the RDS fifo. -BlockA: Block A group data from the oldest FIFO entry. -BlockB: Block B group data from the oldest FIFO entry. -BlockC: Block C group data from the oldest FIFO entry. -BlockD: Block D group data from the oldest FIFO entry. -BleA: Block A corrected error information. -BleB: Block B corrected error information. -BleC: Block C corrected error information. -BleD: Block D corrected error information. ------------------------------------------------------------------------------*/ -void fmRdsStatus(u8 intack, u8 mtfifo) -{ - cmd[0] = FM_RDS_STATUS; - cmd[1] = 0; - if (intack) - cmd[1] |= FM_RDS_STATUS_IN_INTACK; - if (mtfifo) - cmd[1] |= FM_RDS_STATUS_IN_MTFIFO; - - si47xx_command(2, cmd, 13, rsp); - - Status = rsp[0]; - RdsInts = rsp[1]; - RdsSync = !!(rsp[2] & FM_RDS_STATUS_OUT_SYNC); - GrpLost = !!(rsp[2] & FM_RDS_STATUS_OUT_GRPLOST); - RdsFifoUsed = rsp[3]; - BlockA = ((u16)rsp[4] << 8) | (u16)rsp[5]; - BlockB = ((u16)rsp[6] << 8) | (u16)rsp[7]; - BlockC = ((u16)rsp[8] << 8) | (u16)rsp[9]; - BlockD = ((u16)rsp[10] << 8) | (u16)rsp[11]; - BleA = (rsp[12] & FM_RDS_STATUS_OUT_BLEA) >> - FM_RDS_STATUS_OUT_BLEA_SHFT; - BleB = (rsp[12] & FM_RDS_STATUS_OUT_BLEB) >> - FM_RDS_STATUS_OUT_BLEB_SHFT; - BleC = (rsp[12] & FM_RDS_STATUS_OUT_BLEC) >> - FM_RDS_STATUS_OUT_BLEC_SHFT; - BleD = (rsp[12] & FM_RDS_STATUS_OUT_BLED) >> - FM_RDS_STATUS_OUT_BLED_SHFT; -} - - -/*----------------------------------------------------------------------------- - Helper function that sends the FM_RSQ_STATUS command to the part - - Inputs: - intack: If non-zero the interrupt for STCINT will be cleared. - -Outputs: -Status: Contains bits about the status returned from the part. -RsqInts: Contains bits about the interrupts that have fired related to RSQ. -SMUTE: The soft mute function is currently enabled -AFCRL: The AFC is railed if this is non-zero -Valid: The station is valid if this is non-zero -Pilot: A pilot tone is currently present -Blend: Percentage of blend for stereo. (100 = full stereo) -RSSI: The RSSI level read at tune. -ASNR: The audio SNR level read at tune. -FreqOff: The frequency offset in kHz of the current station from the tuned -frequency. ------------------------------------------------------------------------------*/ -static void fmRsqStatus(u8 intack) -{ - cmd[0] = FM_RSQ_STATUS; - cmd[1] = 0; - if (intack) - cmd[1] |= FM_RSQ_STATUS_IN_INTACK; - - si47xx_command(2, cmd, 8, rsp); - - Status = rsp[0]; - RsqInts = rsp[1]; - SMUTE = !!(rsp[2] & FM_RSQ_STATUS_OUT_SMUTE); - AFCRL = !!(rsp[2] & FM_RSQ_STATUS_OUT_AFCRL); - Valid = !!(rsp[2] & FM_RSQ_STATUS_OUT_VALID); - Pilot = !!(rsp[3] & FM_RSQ_STATUS_OUT_PILOT); - Blend = rsp[3] & FM_RSQ_STATUS_OUT_STBLEND; - RSSI = rsp[4]; - ASNR = rsp[5]; - FreqOff = rsp[7]; -} - - -/*----------------------------------------------------------------------------- - Helper function that sends the FM_SEEK_START command to the part - -Inputs: -seekUp: If non-zero seek will increment otherwise decrement -wrap: If non-zero seek will wrap around band limits when hitting the end -of the band limit. ------------------------------------------------------------------------------*/ -static void fmSeekStart(u8 seekUp, u8 wrap) -{ - cmd[0] = FM_SEEK_START; - cmd[1] = 0; - if (seekUp) - cmd[1] |= FM_SEEK_START_IN_SEEKUP; - if (wrap) - cmd[1] |= FM_SEEK_START_IN_WRAP; - - si47xx_command(2, cmd, 1, rsp); -} - - -/*----------------------------------------------------------------------------- - Set the passed property number to the passed value. - - Inputs: - propNumber: The number identifying the property to set - propValue: The value of the property. ------------------------------------------------------------------------------*/ -void si47xx_set_property(u16 propNumber, u16 propValue) -{ - cmd[0] = SET_PROPERTY; - cmd[1] = 0; - cmd[2] = (u8)(propNumber >> 8); - cmd[3] = (u8)(propNumber & 0x00FF); - cmd[4] = (u8)(propValue >> 8); - cmd[5] = (u8)(propValue & 0x00FF); - - si47xx_command(6, cmd, 0, NULL); -} - -/*----------------------------------------------------------------------------- - This command returns the status ------------------------------------------------------------------------------*/ -u8 si47xx_readStatus(void) -{ - u8 status; - i2c_read(1, &status); - - return status; -} - - -/*----------------------------------------------------------------------------- - Command that will wait for CTS before returning ------------------------------------------------------------------------------*/ -void si47xx_waitForCTS(void) -{ - u16 i = 1000; - u8 rStatus = 0; - - do { - rStatus = si47xx_readStatus(); - usleep_range(5, 10); - } while (--i && !(rStatus & CTS)); -} - -/*----------------------------------------------------------------------------- - Sends a command to the part and returns the reply bytes ------------------------------------------------------------------------------*/ -int si47xx_command(u8 cmd_size, u8 *cmd, u8 reply_size, u8 *reply) -{ - int ret = 0; - ret = i2c_write(cmd_size, cmd); - si47xx_waitForCTS(); - - if (reply_size) - i2c_read(reply_size, reply); - - if (ret < 0) - printk(KERN_INFO "%s i2c_write failed %d\n", __func__, ret); - - return ret; -} - -static int i2c_write(u8 number_bytes, u8 *data_out) -{ - int ret = 0; - - ret = i2c_master_send((struct i2c_client *)(Si4709_dev.client), - (const char *)data_out, number_bytes); - if (ret == number_bytes) - ret = 0; - else - ret = -1; - - return ret; -} - -static int i2c_read(u8 number_bytes, u8 *data_in) -{ - int ret = 0; - - ret = i2c_master_recv((struct i2c_client *)(Si4709_dev.client), data_in, - number_bytes); - if (ret < 0) - printk(KERN_INFO "%s i2c_read failed %d\n", __func__, ret); - - return ret; -} |