diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index f52db558a38c..36f3e67447be 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -508,7 +508,7 @@ endif # V4L_RADIO_ISA_DRIVERS config I2C_RTC6226_QCA tristate "Richwave RTC6226 FM Radio Receiver support with I2C for QCA" - depends on I2C && RADIO_RTC6226_QCA + depends on I2C && VIDEO_V4L2 ---help--- This is a driver for I2C devices with the Richwave RTC6226 chip. diff --git a/drivers/media/radio/rtc6226/radio-rtc6226-common.c b/drivers/media/radio/rtc6226/radio-rtc6226-common.c index ae8c75e172e8..7b8750a5527c 100644 --- a/drivers/media/radio/rtc6226/radio-rtc6226-common.c +++ b/drivers/media/radio/rtc6226/radio-rtc6226-common.c @@ -112,7 +112,6 @@ #include #include #include "radio-rtc6226.h" -#define SEEK_TIME_OUT_VALUE 13000 /************************************************************************** * Module Parameters **************************************************************************/ @@ -121,73 +120,11 @@ /* 0: 87.5 - 108 MHz (USA, Europe)*/ /* 1: 76 - 108 MHz (Japan wide band) */ /* 2: 76 - 90 MHz (Japan) */ -static unsigned short band; -MODULE_PARM_DESC(band, "Band: *0=87.5-108MHz* 1=76-108MHz 2=76-91MHz 3=65-76MHz"); /* De-emphasis */ /* 0: 75 us (USA) */ /* 1: 50 us (Europe, Australia, Japan) */ static unsigned short de; -MODULE_PARM_DESC(de, "De-emphasis: *0=75us* 1=50us"); - -/* Tune timeout */ -static unsigned int tune_timeout = 3000; -MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*"); - -/* Seek timeout */ -static unsigned int seek_timeout = SEEK_TIME_OUT_VALUE; -MODULE_PARM_DESC(seek_timeout, "Seek timeout: *13000*"); - -static const struct v4l2_frequency_band bands[] = { - { - .type = V4L2_TUNER_RADIO, - .index = 0, - .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | - V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | - V4L2_TUNER_CAP_FREQ_BANDS | - V4L2_TUNER_CAP_HWSEEK_BOUNDED | - V4L2_TUNER_CAP_HWSEEK_WRAP, - .rangelow = 87500, - .rangehigh = 108000, - .modulation = V4L2_BAND_MODULATION_FM, - }, - { - .type = V4L2_TUNER_RADIO, - .index = 1, - .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | - V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | - V4L2_TUNER_CAP_FREQ_BANDS | - V4L2_TUNER_CAP_HWSEEK_BOUNDED | - V4L2_TUNER_CAP_HWSEEK_WRAP, - .rangelow = 76000, - .rangehigh = 108000, - .modulation = V4L2_BAND_MODULATION_FM, - }, - { - .type = V4L2_TUNER_RADIO, - .index = 2, - .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | - V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | - V4L2_TUNER_CAP_FREQ_BANDS | - V4L2_TUNER_CAP_HWSEEK_BOUNDED | - V4L2_TUNER_CAP_HWSEEK_WRAP, - .rangelow = 76000, - .rangehigh = 91000, - .modulation = V4L2_BAND_MODULATION_FM, - }, - { - .type = V4L2_TUNER_RADIO, - .index = 3, - .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | - V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | - V4L2_TUNER_CAP_FREQ_BANDS | - V4L2_TUNER_CAP_HWSEEK_BOUNDED | - V4L2_TUNER_CAP_HWSEEK_WRAP, - .rangelow = 64000, - .rangehigh = 76000, - .modulation = V4L2_BAND_MODULATION_FM, - }, -}; wait_queue_head_t rtc6226_wq; int rtc6226_wq_flag = NO_WAIT; @@ -204,7 +141,7 @@ void rtc6226_q_event(struct rtc6226_device *radio, data_b = &radio->data_buf[RTC6226_FM_BUF_EVENTS]; - pr_info("%s updating event_q with event %x\n", __func__, event); + FMDBG("%s updating event_q with event %x\n", __func__, event); if (kfifo_in_locked(data_b, &evt, 1, @@ -218,11 +155,10 @@ void rtc6226_q_event(struct rtc6226_device *radio, static int rtc6226_set_chan(struct rtc6226_device *radio, unsigned short chan) { int retval; - bool timed_out = false; unsigned short current_chan = radio->registers[CHANNEL] & CHANNEL_CSR0_CH; - pr_info("%s CHAN=%d chan=%d\n", __func__, radio->registers[CHANNEL], + FMDBG("%s CHAN=%d chan=%d\n", __func__, radio->registers[CHANNEL], chan); /* start tuning */ @@ -233,34 +169,9 @@ static int rtc6226_set_chan(struct rtc6226_device *radio, unsigned short chan) radio->registers[CHANNEL] = current_chan; goto done; } - reinit_completion(&radio->completion); - retval = wait_for_completion_timeout(&radio->completion, - msecs_to_jiffies(tune_timeout)); - if (!retval) - timed_out = true; - - if ((radio->registers[STATUS] & STATUS_STD) == 0) - pr_info("%s tune does not complete\n", __func__); - else { - radio->seek_tune_status = TUNE_PENDING; - rtc6226_q_event(radio, RTC6226_EVT_TUNE_SUCC); - } - if (timed_out) - pr_info("%s tune timed out after %u ms\n", __func__, - tune_timeout); - - /* stop tuning */ - current_chan = radio->registers[CHANNEL] & CHANNEL_CSR0_CH; - - radio->registers[CHANNEL] &= ~CHANNEL_CSR0_TUNE; - retval = rtc6226_set_register(radio, CHANNEL); - if (retval < 0) { - radio->registers[CHANNEL] = current_chan; - goto done; - } done: - pr_info("%s exit %d\n", __func__, retval); + FMDBG("%s exit %d\n", __func__, retval); return retval; } @@ -269,37 +180,29 @@ done: */ static int rtc6226_get_freq(struct rtc6226_device *radio, unsigned int *freq) { - unsigned int spacing, band_bottom; unsigned short chan; unsigned short rssi = 0; int retval; - pr_info("%s enter\n", __func__); - spacing = - ((radio->registers[RADIOCFG] & CHANNEL_CSR0_CHSPACE) >> 8) * 10; - band_bottom = - (radio->registers[RADIOSEEKCFG2] & CHANNEL_CSR0_FREQ_BOT) * 10; + FMDBG("%s enter\n", __func__); /* read channel */ retval = rtc6226_get_register(radio, CHANNEL1); if (retval < 0) { - pr_info("%s fail to get register\n", __func__); + FMDBG("%s fail to get register\n", __func__); goto end; } chan = radio->registers[CHANNEL1] & STATUS_READCH; - #ifdef andrew retval = rtc6226_get_register(radio, RSSI); - if (retval < 0) { - pr_err("%s read fail to RSSI\n", __func__); - goto end; - } - rssi = radio->registers[RSSI] & RSSI_RSSI; - #endif + FMDBG("%s chan %d\n", __func__, chan); + *freq = chan * TUNE_STEP_SIZE; + FMDBG("FMRICHWAVE, freq= %d, rssi= %d dBuV\n", *freq, rssi); - pr_info("%s chan %d\n", __func__, chan); - *freq = chan * 10; - pr_info("FMRICHWAVE, freq= %d, rssi= %d dBuV\n", *freq, rssi); + if (rssi < radio->rssi_th) + rtc6226_q_event(radio, RTC6226_EVT_BELOW_TH); + else + rtc6226_q_event(radio, RTC6226_EVT_ABOVE_TH); end: return retval; @@ -316,29 +219,29 @@ int rtc6226_set_freq(struct rtc6226_device *radio, unsigned int freq) unsigned char i; int retval = 0; - pr_info("%s enter freq:%d\n", __func__, freq); + FMDBG("%s enter freq:%d\n", __func__, freq); band_bottom = (radio->registers[RADIOSEEKCFG2] & - CHANNEL_CSR0_FREQ_BOT) * 10; + CHANNEL_CSR0_FREQ_BOT) * TUNE_STEP_SIZE; if (freq < band_bottom) freq = band_bottom; /* Chan = Freq (Mhz) / 10 */ - chan = freq / 10; + chan = (u16)(freq / TUNE_STEP_SIZE); - pr_info("%s chan:%d freq:%d band_bottom:%d\n", __func__, + FMDBG("%s chan:%d freq:%d band_bottom:%d\n", __func__, chan, freq, band_bottom); retval = rtc6226_set_chan(radio, chan); if (retval < 0) { - pr_info("%s fail to set chan\n", __func__); + FMDBG("%s fail to set chan\n", __func__); goto end; } for (i = 0x12; i < RADIO_REGISTER_NUM; i++) { retval = rtc6226_get_register(radio, i); if (retval < 0) { - pr_info("%s fail to get register\n", __func__); + FMDBG("%s fail to get register\n", __func__); goto end; } } @@ -355,11 +258,9 @@ static int rtc6226_set_seek(struct rtc6226_device *radio, unsigned int seek_up, unsigned int seek_wrap) { int retval = 0; - bool timed_out = false; unsigned short seekcfg1_val = radio->registers[SEEKCFG1]; - int i; - pr_info("%s enter up:%d wrap:%d, th:%d\n", __func__, seek_up, seek_wrap, + FMDBG("%s enter up:%d wrap:%d, th:%d\n", __func__, seek_up, seek_wrap, seekcfg1_val); if (seek_wrap) radio->registers[SEEKCFG1] &= ~SEEKCFG1_CSR0_SKMODE; @@ -386,34 +287,8 @@ static int rtc6226_set_seek(struct rtc6226_device *radio, goto done; } - reinit_completion(&radio->completion); - retval = wait_for_completion_timeout(&radio->completion, - msecs_to_jiffies(seek_timeout)); - if (!retval) { - timed_out = true; - pr_err("%s timeout\n", __func__); - rtc6226_get_all_registers(radio); - for (i = 0; i < 16; i++) - pr_info("%s registers[%d]:%x\n", __func__, i, - radio->registers[i]); - } - - if ((radio->registers[STATUS] & STATUS_STD) == 0) - pr_info(" %s seek does not complete\n", __func__); - if (radio->registers[STATUS] & STATUS_SF) { - pr_info(" %s seek failed / band limit reached\n", __func__); - //retval = -ESPIPE; - } - - /* stop seeking : clear STD*/ - radio->registers[SEEKCFG1] &= ~SEEKCFG1_CSR0_SEEK; - retval = rtc6226_set_register(radio, SEEKCFG1); - - if (retval == 0 && timed_out) - retval = -EAGAIN; - done: - pr_info("%s exit %d\n", __func__, retval); + FMDBG("%s exit %d\n", __func__, retval); return retval; } @@ -438,95 +313,106 @@ void rtc6226_scan(struct work_struct *work) int len = 0; u32 next_freq_khz; int retval = 0; + int i; - pr_info("%s enter\n", __func__); + FMDBG("%s enter\n", __func__); radio = container_of(work, struct rtc6226_device, work_scan.work); - radio->seek_tune_status = SEEK_PENDING; retval = rtc6226_get_freq(radio, ¤t_freq_khz); if (retval < 0) { - pr_err("%s fail to get freq\n", __func__); + FMDERR("%s fail to get freq\n", __func__); goto seek_tune_fail; } - pr_info("%s cuurent freq %d\n", __func__, current_freq_khz); + FMDBG("%s current freq %d\n", __func__, current_freq_khz); + /* tune to lowest freq of the band */ + radio->seek_tune_status = SCAN_PENDING; + retval = rtc6226_set_freq(radio, + radio->recv_conf.band_low_limit * TUNE_STEP_SIZE); + if (retval < 0) + goto seek_tune_fail; + /* wait for tune to complete. */ + if (!wait_for_completion_timeout(&radio->completion, + msecs_to_jiffies(WAIT_TIMEOUT_MSEC))) + FMDERR("In %s, didn't receive STC for tune\n", __func__); while (1) { if (radio->is_search_cancelled) { - pr_err("%s: scan cancelled\n", __func__); + FMDERR("%s: scan cancelled\n", __func__); if (radio->g_search_mode == SCAN_FOR_STRONG) goto seek_tune_fail; else goto seek_cancelled; goto seek_cancelled; } else if (radio->mode != FM_RECV) { - pr_err("%s: FM is not in proper state\n", __func__); + FMDERR("%s: FM is not in proper state\n", __func__); return; } retval = rtc6226_set_seek(radio, SRCH_UP, WRAP_DISABLE); if (retval < 0) { - pr_err("%s seek fail %d\n", __func__, retval); + FMDERR("%s seek fail %d\n", __func__, retval); goto seek_tune_fail; } - - if (radio->registers[STATUS] & STATUS_SF) { - pr_err("%s band limit reached. Seek one more.\n", - __func__); - seek_timeout = 1000; - retval = rtc6226_set_seek(radio, SRCH_UP, WRAP_ENABLE); - seek_timeout = SEEK_TIME_OUT_VALUE; - if (retval < 0) { - pr_err("%s seek fail %d\n", __func__, retval); - goto seek_tune_fail; - } - retval = rtc6226_get_freq(radio, &next_freq_khz); - if (retval < 0) { - pr_err("%s fail to get freq\n", __func__); - goto seek_tune_fail; - } - pr_info("%s next freq %d\n", __func__, next_freq_khz); - rtc6226_q_event(radio, RTC6226_EVT_TUNE_SUCC); - break; - } + /* wait for seek to complete */ + if (!wait_for_completion_timeout(&radio->completion, + msecs_to_jiffies(WAIT_TIMEOUT_MSEC))) { + FMDERR("%s:timeout didn't receive STC for seek\n", + __func__); + rtc6226_get_all_registers(radio); + for (i = 0; i < 16; i++) + FMDBG("%s registers[%d]:%x\n", __func__, i, + radio->registers[i]); + /* FM is not correct state or scan is cancelled */ + continue; + } else + FMDERR("%s: received STC for seek\n", __func__); retval = rtc6226_get_freq(radio, &next_freq_khz); if (retval < 0) { - pr_err("%s fail to get freq\n", __func__); + FMDERR("%s fail to get freq\n", __func__); goto seek_tune_fail; } - pr_info("%s next freq %d\n", __func__, next_freq_khz); + FMDBG("%s next freq %d\n", __func__, next_freq_khz); retval = rtc6226_get_register(radio, RSSI); if (retval < 0) { - pr_err("%s read fail to RSSI\n", __func__); + FMDERR("%s read fail to RSSI\n", __func__); goto seek_tune_fail; } - pr_info("%s valid channel %d, rssi %d\n", __func__, + FMDBG("%s valid channel %d, rssi %d\n", __func__, next_freq_khz, radio->registers[RSSI] & RSSI_RSSI); + if (radio->registers[STATUS] & STATUS_SF) { + FMDERR("%s band limit reached. Seek one more.\n", + __func__); + break; + } if (radio->g_search_mode == SCAN) rtc6226_q_event(radio, RTC6226_EVT_TUNE_SUCC); - + /* + * If scan is cancelled or FM is not ON, break ASAP so that we + * don't need to sleep for dwell time. + */ if (radio->is_search_cancelled) { - pr_err("%s: scan cancelled\n", __func__); + FMDERR("%s: scan cancelled\n", __func__); if (radio->g_search_mode == SCAN_FOR_STRONG) goto seek_tune_fail; else goto seek_cancelled; goto seek_cancelled; } else if (radio->mode != FM_RECV) { - pr_err("%s: FM is not in proper state\n", __func__); + FMDERR("%s: FM is not in proper state\n", __func__); return; } - pr_info("%s update search list %d\n", __func__, next_freq_khz); + FMDBG("%s update search list %d\n", __func__, next_freq_khz); if (radio->g_search_mode == SCAN) { /* sleep for dwell period */ msleep(radio->dwell_time_sec * 1000); /* need to queue the event when the seek completes */ - pr_info("%s frequency update list %d\n", __func__, - next_freq_khz/16); + FMDBG("%s frequency update list %d\n", __func__, + next_freq_khz); rtc6226_q_event(radio, RTC6226_EVT_SCAN_NEXT); } else if (radio->g_search_mode == SCAN_FOR_STRONG) { rtc6226_update_search_list(radio, next_freq_khz); @@ -543,12 +429,22 @@ seek_tune_fail: &radio->buf_lock[RTC6226_FM_BUF_SRCH_LIST]); rtc6226_q_event(radio, RTC6226_EVT_NEW_SRCH_LIST); } - pr_err("%s seek tune fail %d\n", __func__, retval); - + /* tune to original frequency */ + retval = rtc6226_set_freq(radio, current_freq_khz); + if (retval < 0) + FMDERR("%s: Tune to orig freq failed with error %d\n", + __func__, retval); + else { + if (!wait_for_completion_timeout(&radio->completion, + msecs_to_jiffies(WAIT_TIMEOUT_MSEC))) + FMDERR("%s: didn't receive STD for tune\n", __func__); + else + FMDERR("%s: received STD for tune\n", __func__); + } seek_cancelled: rtc6226_q_event(radio, RTC6226_EVT_SEEK_COMPLETE); radio->seek_tune_status = NO_SEEK_TUNE_PENDING; - pr_err("%s seek cancelled %d\n", __func__, retval); + FMDERR("%s seek cancelled %d\n", __func__, retval); return; } @@ -557,7 +453,7 @@ int rtc6226_cancel_seek(struct rtc6226_device *radio) { int retval = 0; - pr_info("%s enter\n", __func__); + FMDBG("%s enter\n", __func__); mutex_lock(&radio->lock); /* stop seeking */ @@ -579,7 +475,7 @@ void rtc6226_search(struct rtc6226_device *radio, bool on) current_freq_khz = radio->tuned_freq_khz; if (on) { - pr_info("%s: Queuing the work onto scan work q\n", __func__); + FMDBG("%s: Queuing the work onto scan work q\n", __func__); queue_delayed_work(radio->wqueue_scan, &radio->work_scan, msecs_to_jiffies(10)); } else { @@ -610,8 +506,8 @@ int rtc6226_start(struct rtc6226_device *radio) i2c_error++; } - if (retval < 0) { - pr_err("%s set to fail retval = %d\n", __func__, retval); + if (retval < 0) { + FMDERR("%s set to fail retval = %d\n", __func__, retval); /* goto done;*/ } msleep(30); @@ -627,13 +523,13 @@ int rtc6226_start(struct rtc6226_device *radio) } if (retval < 0) - pr_err("%s set to fail 0x96AA %d\n", __func__, retval); + FMDERR("%s set to fail 0x96AA %d\n", __func__, retval); msleep(30); /* get device and chip versions */ rtc6226_get_register(radio, DEVICEID); rtc6226_get_register(radio, CHIPID); - pr_info("%s DeviceID=0x%x ChipID=0x%x Addr=0x%x\n", __func__, + FMDBG("%s DeviceID=0x%x ChipID=0x%x Addr=0x%x\n", __func__, radio->registers[DEVICEID], radio->registers[CHIPID], radio->client->addr); @@ -642,26 +538,26 @@ int rtc6226_start(struct rtc6226_device *radio) if (retval < 0) goto done; - pr_info("%s rtc6226_power_up1: DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", + FMDBG("%s rtc6226_power_up1: DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", __func__, radio->registers[DEVICEID], radio->registers[CHIPID]); - pr_info("%s rtc6226_power_up2: Reg2=0x%4.4hx Reg3=0x%4.4hx\n", __func__, + FMDBG("%s rtc6226_power_up2: Reg2=0x%4.4hx Reg3=0x%4.4hx\n", __func__, radio->registers[MPXCFG], radio->registers[CHANNEL]); - pr_info("%s rtc6226_power_up3: Reg4=0x%4.4hx Reg5=0x%4.4hx\n", __func__, + FMDBG("%s rtc6226_power_up3: Reg4=0x%4.4hx Reg5=0x%4.4hx\n", __func__, radio->registers[SYSCFG], radio->registers[SEEKCFG1]); - pr_info("%s rtc6226_power_up4: Reg6=0x%4.4hx Reg7=0x%4.4hx\n", __func__, + FMDBG("%s rtc6226_power_up4: Reg6=0x%4.4hx Reg7=0x%4.4hx\n", __func__, radio->registers[POWERCFG], radio->registers[PADCFG]); - pr_info("%s rtc6226_power_up5: Reg8=0x%4.4hx Reg9=0x%4.4hx\n", __func__, + FMDBG("%s rtc6226_power_up5: Reg8=0x%4.4hx Reg9=0x%4.4hx\n", __func__, radio->registers[8], radio->registers[9]); - pr_info("%s rtc6226_power_up6: regA=0x%4.4hx RegB=0x%4.4hx\n", __func__, + FMDBG("%s rtc6226_power_up6: regA=0x%4.4hx RegB=0x%4.4hx\n", __func__, radio->registers[10], radio->registers[11]); - pr_info("%s rtc6226_power_up7: regC=0x%4.4hx RegD=0x%4.4hx\n", __func__, + FMDBG("%s rtc6226_power_up7: regC=0x%4.4hx RegD=0x%4.4hx\n", __func__, radio->registers[12], radio->registers[13]); - pr_info("%s rtc6226_power_up8: regE=0x%4.4hx RegF=0x%4.4hx\n", __func__, + FMDBG("%s rtc6226_power_up8: regE=0x%4.4hx RegF=0x%4.4hx\n", __func__, radio->registers[14], radio->registers[15]); - pr_info("%s DeviceID=0x%x ChipID=0x%x Addr=0x%x\n", __func__, + FMDBG("%s DeviceID=0x%x ChipID=0x%x Addr=0x%x\n", __func__, radio->registers[DEVICEID], radio->registers[CHIPID], radio->client->addr); @@ -716,13 +612,12 @@ done: static void rtc6226_get_rds(struct rtc6226_device *radio) { int retval = 0; - int i; mutex_lock(&radio->lock); retval = rtc6226_get_all_registers(radio); if (retval < 0) { - pr_err("%s read fail%d\n", __func__, retval); + FMDERR("%s read fail%d\n", __func__, retval); mutex_unlock(&radio->lock); return; } @@ -731,9 +626,6 @@ static void rtc6226_get_rds(struct rtc6226_device *radio) radio->block[2] = radio->registers[BC_DATA]; radio->block[3] = radio->registers[BD_DATA]; - for (i = 0; i < 4; i++) - pr_info("%s block[%d] %x\n", __func__, i, radio->block[i]); - radio->bler[0] = (radio->registers[RSSI] & RSSI_RDS_BA_ERRS) >> 14; radio->bler[1] = (radio->registers[RSSI] & RSSI_RDS_BB_ERRS) >> 12; radio->bler[2] = (radio->registers[RSSI] & RSSI_RDS_BC_ERRS) >> 10; @@ -744,22 +636,22 @@ static void rtc6226_get_rds(struct rtc6226_device *radio) static void rtc6226_pi_check(struct rtc6226_device *radio, u16 current_pi) { if (radio->pi != current_pi) { - pr_info("%s current_pi %x , radio->pi %x\n" + FMDBG("%s current_pi %x , radio->pi %x\n" , __func__, current_pi, radio->pi); radio->pi = current_pi; } else { - pr_info("%s Received same PI code\n", __func__); + FMDBG("%s Received same PI code\n", __func__); } } static void rtc6226_pty_check(struct rtc6226_device *radio, u8 current_pty) { if (radio->pty != current_pty) { - pr_info("%s PTY code of radio->block[1] = %x\n", + FMDBG("%s PTY code of radio->block[1] = %x\n", __func__, current_pty); radio->pty = current_pty; } else { - pr_info("%s PTY repeated\n", __func__); + FMDBG("%s PTY repeated\n", __func__); } } @@ -805,8 +697,8 @@ static bool is_valid_freq(struct rtc6226_device *radio, u32 freq) u32 band_high_limit; u8 spacing = 0; - band_low_limit = bands[radio->band].rangelow; - band_high_limit = bands[radio->band].rangehigh; + band_low_limit = radio->recv_conf.band_low_limit * TUNE_STEP_SIZE; + band_high_limit = radio->recv_conf.band_high_limit * TUNE_STEP_SIZE; if (radio->space == 0) spacing = CH_SPACING_200; @@ -843,7 +735,7 @@ static void rtc6226_update_af_list(struct rtc6226_device *radio) if (af_data >= MIN_AF_CNT_CODE && af_data <= MAX_AF_CNT_CODE) { - pr_info("%s: resetting af info, freq %u, pi %u\n", + FMDBG("%s: resetting af info, freq %u, pi %u\n", __func__, tuned_freq_khz, radio->pi); radio->af_info2.inval_freq_cnt = 0; radio->af_info2.cnt = 0; @@ -854,7 +746,7 @@ static void rtc6226_update_af_list(struct rtc6226_device *radio) radio->af_info2.orig_freq_khz = tuned_freq_khz; radio->af_info2.pi = radio->pi; - pr_info("%s: current freq is %u, AF cnt is %u\n", + FMDBG("%s: current freq is %u, AF cnt is %u\n", __func__, tuned_freq_khz, radio->af_info2.cnt); } else if (af_data >= MIN_AF_FREQ_CODE && af_data <= MAX_AF_FREQ_CODE && @@ -864,14 +756,14 @@ static void rtc6226_update_af_list(struct rtc6226_device *radio) af_freq_khz = SCALE_AF_CODE_TO_FREQ_KHZ(af_data); retval = is_valid_freq(radio, af_freq_khz); if (!retval) { - pr_info("%s: Invalid AF\n", __func__); + FMDBG("%s: Invalid AF\n", __func__); radio->af_info2.inval_freq_cnt++; continue; } retval = is_new_freq(radio, af_freq_khz); if (!retval) { - pr_info("%s: Duplicate AF\n", __func__); + FMDBG("%s: Duplicate AF\n", __func__); radio->af_info2.inval_freq_cnt++; continue; } @@ -879,7 +771,7 @@ static void rtc6226_update_af_list(struct rtc6226_device *radio) /* update the AF list */ radio->af_info2.af_list[radio->af_info2.size++] = af_freq_khz; - pr_info("%s: AF is %u\n", __func__, af_freq_khz); + FMDBG("%s: AF is %u\n", __func__, af_freq_khz); if ((radio->af_info2.size + radio->af_info2.inval_freq_cnt == radio->af_info2.cnt) && @@ -916,7 +808,7 @@ static void rtc6226_update_af_list(struct rtc6226_device *radio) GET_AF_EVT_LEN(ev.af_size), &lock); - pr_info("%s: posting AF list evt,currfreq %u\n", + FMDBG("%s: posting AF list evt,currfreq %u\n", __func__, ev.tune_freq_khz); rtc6226_q_event(radio, @@ -934,7 +826,7 @@ static void rtc6226_update_ps(struct rtc6226_device *radio, u8 addr, u8 ps) u8 *data; struct kfifo *data_b; - pr_info("%s enter addr:%x ps:%x\n", __func__, addr, ps); + FMDBG("%s enter addr:%x ps:%x\n", __func__, addr, ps); if (radio->ps_tmp0[addr] == ps) { if (radio->ps_cnt[addr] < PS_VALIDATE_LIMIT) { @@ -968,7 +860,7 @@ static void rtc6226_update_ps(struct rtc6226_device *radio, u8 addr, u8 ps) for (i = 0; i < MAX_PS_LEN; i++) { if (radio->ps_cnt[i] < PS_VALIDATE_LIMIT) { - pr_info("%s ps_cnt[%d] %d\n", __func__, i, + FMDBG("%s ps_cnt[%d] %d\n", __func__, i, radio->ps_cnt[i]); ps_cmplt = false; return; @@ -980,7 +872,7 @@ static void rtc6226_update_ps(struct rtc6226_device *radio, u8 addr, u8 ps) (radio->ps_display[i] == radio->ps_tmp0[i]); i++) ; if (i == MAX_PS_LEN) { - pr_info("%s Same PS string repeated\n", __func__); + FMDBG("%s Same PS string repeated\n", __func__); return; } @@ -999,11 +891,11 @@ static void rtc6226_update_ps(struct rtc6226_device *radio, u8 addr, u8 ps) data_b = &radio->data_buf[RTC6226_FM_BUF_PS_RDS]; kfifo_in_locked(data_b, data, PS_EVT_DATA_LEN, &radio->buf_lock[RTC6226_FM_BUF_PS_RDS]); - pr_info("%s Q the PS event\n", __func__); + FMDBG("%s Q the PS event\n", __func__); rtc6226_q_event(radio, RTC6226_EVT_NEW_PS_RDS); kfree(data); } else { - pr_err("%s Memory allocation failed for PTY\n", + FMDERR("%s Memory allocation failed for PTY\n", __func__); } } @@ -1016,11 +908,11 @@ static void display_rt(struct rtc6226_device *radio) struct kfifo *data_b; bool rt_cmplt = true; - pr_info("%s enter\n", __func__); + FMDBG("%s enter\n", __func__); for (i = 0; i < MAX_RT_LEN; i++) { if (radio->rt_cnt[i] < RT_VALIDATE_LIMIT) { - pr_info("%s rt_cnt %d\n", __func__, radio->rt_cnt[i]); + FMDBG("%s rt_cnt %d\n", __func__, radio->rt_cnt[i]); rt_cmplt = false; return; } @@ -1035,7 +927,7 @@ static void display_rt(struct rtc6226_device *radio) (radio->rt_display[i] == radio->rt_tmp0[i]); i++) ; if (i == len) { - pr_info("%s Same RT string repeated\n", __func__); + FMDBG("%s Same RT string repeated\n", __func__); return; } for (i = 0; i < len; i++) @@ -1051,11 +943,11 @@ static void display_rt(struct rtc6226_device *radio) data_b = &radio->data_buf[RTC6226_FM_BUF_RT_RDS]; kfifo_in_locked(data_b, data, OFFSET_OF_RT + len, &radio->buf_lock[RTC6226_FM_BUF_RT_RDS]); - pr_info("%s Q the RT event\n", __func__); + FMDBG("%s Q the RT event\n", __func__); rtc6226_q_event(radio, RTC6226_EVT_NEW_RT_RDS); kfree(data); } else { - pr_err("%s Memory allocation failed for PTY\n", + FMDERR("%s Memory allocation failed for PTY\n", __func__); } } @@ -1067,7 +959,7 @@ static void rt_handler(struct rtc6226_device *radio, u8 ab_flg, u8 i, errcnt, blermax; bool rt_txt_chg = false; - pr_info("%s enter\n", __func__); + FMDBG("%s enter\n", __func__); if (ab_flg != radio->rt_flag && radio->valid_rt_flg) { for (i = 0; i < sizeof(radio->rt_cnt); i++) { @@ -1139,8 +1031,8 @@ static void rtc6226_raw_rds(struct rtc6226_device *radio) aid = radio->block[3]; app_grp_typ = radio->block[1] & APP_GRP_typ_MASK; - pr_info("%s app_grp_typ = %x\n", __func__, app_grp_typ); - pr_info("%s AID = %x\n", __func__, aid); + FMDBG("%s app_grp_typ = %x\n", __func__, app_grp_typ); + FMDBG("%s AID = %x\n", __func__, aid); switch (aid) { case ERT_AID: @@ -1162,7 +1054,7 @@ static void rtc6226_raw_rds(struct rtc6226_device *radio) } break; default: - pr_info("%s Not handling the AID of %x\n", __func__, aid); + FMDBG("%s Not handling the AID of %x\n", __func__, aid); break; } } @@ -1175,7 +1067,7 @@ static void rtc6226_ev_ert(struct rtc6226_device *radio) if (radio->ert_len <= 0) return; - pr_info("%s enter\n", __func__); + FMDBG("%s enter\n", __func__); data = kmalloc((radio->ert_len + ERT_OFFSET), GFP_ATOMIC); if (data != NULL) { data[0] = radio->ert_len; @@ -1204,15 +1096,15 @@ static void rtc6226_buff_ert(struct rtc6226_device *radio) if (radio->c_byt_pair_index == byte_pair_index) { for (i = 2; i <= 3; i++) { info_byte = radio->block[i]; - pr_info("%s info_byte = %x\n", __func__, info_byte); - pr_info("%s ert_len = %x\n", __func__, radio->ert_len); + FMDBG("%s info_byte = %x\n", __func__, info_byte); + FMDBG("%s ert_len = %x\n", __func__, radio->ert_len); if (radio->ert_len > (MAX_ERT_LEN - 2)) return; radio->ert_buf[radio->ert_len] = radio->block[i] >> 8; radio->ert_buf[radio->ert_len + 1] = radio->block[i] & 0xFF; radio->ert_len += ERT_CNT_PER_BLK; - pr_info("%s utf_8_flag = %d\n", __func__, + FMDBG("%s utf_8_flag = %d\n", __func__, radio->utf_8_flag); if ((radio->utf_8_flag == 0) && (info_byte == END_OF_RT)) { @@ -1276,7 +1168,7 @@ static void rtc6226_rt_plus(struct rtc6226_device *radio) len += RT_PLUS_OFFSET; data = kmalloc(len, GFP_ATOMIC); } else { - pr_err("%s:Len is zero\n", __func__); + FMDERR("%s:Len is zero\n", __func__); return; } if (data != NULL) { @@ -1320,7 +1212,7 @@ static void rtc6226_rt_plus(struct rtc6226_device *radio) rtc6226_q_event(radio, RTC6226_EVT_NEW_RT_PLUS); kfree(data); } else { - pr_err("%s:memory allocation failed\n", __func__); + FMDERR("%s:memory allocation failed\n", __func__); } } @@ -1333,11 +1225,11 @@ void rtc6226_rds_handler(struct work_struct *worker) radio = container_of(worker, struct rtc6226_device, rds_worker); if (!radio) { - pr_err("%s:radio is null\n", __func__); + FMDERR("%s:radio is null\n", __func__); return; } - pr_info("%s enter\n", __func__); + FMDBG("%s enter\n", __func__); rtc6226_get_rds(radio); @@ -1346,9 +1238,9 @@ void rtc6226_rds_handler(struct work_struct *worker) if (radio->bler[1] < CORRECTED_ONE_TO_TWO) { grp_type = radio->block[1] >> OFFSET_OF_GRP_TYP; - pr_info("%s grp_type = %d\n", __func__, grp_type); + FMDBG("%s grp_type = %d\n", __func__, grp_type); } else { - pr_err("%s invalid data %d\n", __func__, radio->bler[1]); + /* invalid data case */ return; } if (grp_type & 0x01) @@ -1363,7 +1255,7 @@ void rtc6226_rds_handler(struct work_struct *worker) /* fall through */ case RDS_TYPE_0B: addr = (radio->block[1] & PS_MASK) * NO_OF_CHARS_IN_EACH_ADD; - pr_info("%s RDS is PS\n", __func__); + FMDBG("%s RDS is PS\n", __func__); if (radio->bler[3] <= CORRECTED_THREE_TO_FIVE) { rtc6226_update_ps(radio, addr+0, radio->block[3] >> 8); rtc6226_update_ps(radio, addr+1, @@ -1371,7 +1263,7 @@ void rtc6226_rds_handler(struct work_struct *worker) } break; case RDS_TYPE_2A: - pr_info("%s RDS is RT 2A group\n", __func__); + FMDBG("%s RDS is RT 2A group\n", __func__); rt_blks[0] = (u8)(radio->block[2] >> 8); rt_blks[1] = (u8)(radio->block[2] & 0xFF); rt_blks[2] = (u8)(radio->block[3] >> 8); @@ -1381,7 +1273,7 @@ void rtc6226_rds_handler(struct work_struct *worker) rt_handler(radio, ab_flg, CNT_FOR_2A_GRP_RT, addr, rt_blks); break; case RDS_TYPE_2B: - pr_info("%s RDS is RT 2B group\n", __func__); + FMDBG("%s RDS is RT 2B group\n", __func__); rt_blks[0] = (u8)(radio->block[3] >> 8); rt_blks[1] = (u8)(radio->block[3] & 0xFF); rt_blks[2] = 0; @@ -1394,16 +1286,16 @@ void rtc6226_rds_handler(struct work_struct *worker) rt_handler(radio, ab_flg, CNT_FOR_2B_GRP_RT, addr, rt_blks); break; case RDS_TYPE_3A: - pr_info("%s RDS is 3A group\n", __func__); + FMDBG("%s RDS is 3A group\n", __func__); rtc6226_raw_rds(radio); break; default: - pr_err("%s Not handling the group type %d\n", __func__, + FMDERR("%s Not handling the group type %d\n", __func__, grp_type); break; } - pr_info("%s rt_plus_carrier = %x\n", __func__, radio->rt_plus_carrier); - pr_info("%s ert_carrier = %x\n", __func__, radio->ert_carrier); + FMDBG("%s rt_plus_carrier = %x\n", __func__, radio->rt_plus_carrier); + FMDBG("%s ert_carrier = %x\n", __func__, radio->ert_carrier); if (radio->rt_plus_carrier && (grp_type == radio->rt_plus_carrier)) rtc6226_rt_plus(radio); else if (radio->ert_carrier && (grp_type == radio->ert_carrier)) @@ -1417,7 +1309,7 @@ static int rtc6226_rds_on(struct rtc6226_device *radio) { int retval; - pr_info("%s enter\n", __func__); + FMDBG("%s enter\n", __func__); /* sysconfig */ radio->registers[SYSCFG] |= SYSCFG_CSR0_RDS_EN; retval = rtc6226_set_register(radio, SYSCFG); @@ -1431,7 +1323,17 @@ static int rtc6226_rds_on(struct rtc6226_device *radio) int rtc6226_reset_rds_data(struct rtc6226_device *radio) { mutex_lock(&radio->lock); + radio->pi = 0; + /* reset PS bufferes */ + memset(radio->ps_display, 0, sizeof(radio->ps_display)); + memset(radio->ps_tmp0, 0, sizeof(radio->ps_tmp0)); + memset(radio->ps_tmp1, 0, sizeof(radio->ps_tmp1)); + memset(radio->ps_cnt, 0, sizeof(radio->ps_cnt)); + memset(radio->rt_display, 0, sizeof(radio->rt_display)); + memset(radio->rt_tmp0, 0, sizeof(radio->rt_tmp0)); + memset(radio->rt_tmp1, 0, sizeof(radio->rt_tmp1)); + memset(radio->rt_cnt, 0, sizeof(radio->rt_cnt)); radio->wr_index = 0; radio->rd_index = 0; memset(radio->buffer, 0, radio->buf_size); @@ -1440,11 +1342,26 @@ int rtc6226_reset_rds_data(struct rtc6226_device *radio) return 0; } +int rtc6226_set_rssi_threshold(struct rtc6226_device *radio, u16 rssi) +{ + int retval = 0; + + /*csr_rssi_low_th = RSSI_threshold/4*/ + rssi = rssi/4; + if ((rssi < MIN_RSSI) && (rssi > MAX_RSSI)) + return -EINVAL; + radio->registers[SEEKCFG1] &= ~SEEKCFG1_CSR0_RSSI_LOW_TH; + radio->registers[SEEKCFG1] |= rssi << 8; + retval = rtc6226_set_register(radio, SEEKCFG1); + radio->rssi_th = (u8)(rssi*4); + return retval; +} + int rtc6226_power_down(struct rtc6226_device *radio) { int retval = 0; - pr_info("%s enter\n", __func__); + FMDBG("%s enter\n", __func__); mutex_lock(&radio->lock); /* stop radio */ @@ -1452,7 +1369,7 @@ int rtc6226_power_down(struct rtc6226_device *radio) //rtc6226_disable_irq(radio); mutex_unlock(&radio->lock); - pr_info("%s exit %d\n", __func__, retval); + FMDBG("%s exit %d\n", __func__, retval); return retval; } @@ -1463,18 +1380,18 @@ int rtc6226_power_up(struct rtc6226_device *radio) mutex_lock(&radio->lock); - pr_info("%s enter\n", __func__); + FMDBG("%s enter\n", __func__); /* start radio */ retval = rtc6226_start(radio); if (retval < 0) goto done; - pr_info("%s : after initialization\n", __func__); + FMDBG("%s : after initialization\n", __func__); /* mpxconfig */ - /* Disable Softmute / Disable Mute / De-emphasis / Volume 8 */ - radio->registers[MPXCFG] = 0x0000 | - MPXCFG_CSR0_DIS_SMUTE | MPXCFG_CSR0_DIS_MUTE | + /* Disable Mute / De-emphasis / Volume 12 */ + radio->registers[MPXCFG] = 0x000c | + MPXCFG_CSR0_DIS_MUTE | ((de << 12) & MPXCFG_CSR0_DEEM); retval = rtc6226_set_register(radio, MPXCFG); if (retval < 0) @@ -1494,38 +1411,16 @@ int rtc6226_power_up(struct rtc6226_device *radio) if (retval < 0) goto done; - /* channel */ - /* Top Frequency 108.0MHZ */ - radio->registers[RADIOSEEKCFG1] = 0x2a30; - retval = rtc6226_set_register(radio, RADIOSEEKCFG1); - if (retval < 0) - goto done; - - /* Bottom Frequency 87.5MHz*/ - radio->registers[RADIOSEEKCFG2] = 0x222e; - retval = rtc6226_set_register(radio, RADIOSEEKCFG2); - if (retval < 0) - goto done; - - /* Space 100KHz */ - /* radio->registers[RADIOCFG] &= ~CHANNEL_CSR0_CHSPACE; */ - radio->registers[RADIOCFG] = 0x0a00; - retval = rtc6226_set_register(radio, RADIOCFG); - if (retval < 0) - goto done; - - /* Default channel 90.1Mhz */ - radio->registers[CHANNEL] = 0x2232; - retval = rtc6226_set_register(radio, CHANNEL); - if (retval < 0) - goto done; - /* I2S salve */ radio->registers[I2SCFG] = 0x2480; retval = rtc6226_set_register(radio, I2SCFG); if (retval < 0) goto done; + /*set default rssi threshold*/ + retval = rtc6226_set_rssi_threshold(radio, DEFAULT_RSSI_TH); + if (retval < 0) + FMDERR("%s fail to set rssi threshold\n", __func__); /* powerconfig */ /* Enable FM */ @@ -1533,30 +1428,31 @@ int rtc6226_power_up(struct rtc6226_device *radio) retval = rtc6226_set_register(radio, POWERCFG); if (retval < 0) goto done; - + /*wait for radio enable to complete*/ + msleep(30); retval = rtc6226_get_all_registers(radio); if (retval < 0) goto done; - pr_info("%s : DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", __func__, + FMDBG("%s : DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", __func__, radio->registers[DEVICEID], radio->registers[CHIPID]); - pr_info("%s : Reg2=0x%4.4hx Reg3=0x%4.4hx\n", __func__, + FMDBG("%s : Reg2=0x%4.4hx Reg3=0x%4.4hx\n", __func__, radio->registers[MPXCFG], radio->registers[CHANNEL]); - pr_info("%s : Reg4=0x%4.4hx Reg5=0x%4.4hx\n", __func__, + FMDBG("%s : Reg4=0x%4.4hx Reg5=0x%4.4hx\n", __func__, radio->registers[SYSCFG], radio->registers[SEEKCFG1]); - pr_info("%s : Reg6=0x%4.4hx Reg7=0x%4.4hx\n", __func__, + FMDBG("%s : Reg6=0x%4.4hx Reg7=0x%4.4hx\n", __func__, radio->registers[POWERCFG], radio->registers[PADCFG]); - pr_info("%s : Reg8=0x%4.4hx Reg9=0x%4.4hx\n", __func__, + FMDBG("%s : Reg8=0x%4.4hx Reg9=0x%4.4hx\n", __func__, radio->registers[8], radio->registers[9]); - pr_info("%s : regA=0x%4.4hx RegB=0x%4.4hx\n", __func__, + FMDBG("%s : regA=0x%4.4hx RegB=0x%4.4hx\n", __func__, radio->registers[10], radio->registers[11]); - pr_info("%s : regC=0x%4.4hx RegD=0x%4.4hx\n", __func__, + FMDBG("%s : regC=0x%4.4hx RegD=0x%4.4hx\n", __func__, radio->registers[12], radio->registers[13]); - pr_info("%s : regE=0x%4.4hx RegF=0x%4.4hx\n", __func__, + FMDBG("%s : regE=0x%4.4hx RegF=0x%4.4hx\n", __func__, radio->registers[14], radio->registers[15]); done: - pr_info("%s exit %d\n", __func__, retval); + FMDBG("%s exit %d\n", __func__, retval); mutex_unlock(&radio->lock); return retval; } @@ -1596,9 +1492,7 @@ static ssize_t rtc6226_fops_read(struct file *file, char __user *buf, /* calculate block count from byte count */ count /= 3; - #ifdef _RDSDEBUG - pr_info("%s : count = %zu\n", __func__, count); - #endif + FMDBG("%s : count = %zu\n", __func__, count); /* copy RDS block out of internal buffer and to user buffer */ while (block_count < count) { @@ -1616,10 +1510,8 @@ static ssize_t rtc6226_fops_read(struct file *file, char __user *buf, block_count++; buf += 3; retval += 3; - #ifdef _RDSDEBUG - pr_info("%s : block_count = %d, count = %zu\n", __func__, + FMDBG("%s : block_count = %d, count = %zu\n", __func__, block_count, count); - #endif } done: @@ -1657,17 +1549,17 @@ int rtc6226_vidioc_g_ctrl(struct file *file, void *priv, struct rtc6226_device *radio = video_drvdata(file); int retval = 0; - pr_info("%s enter, ctrl->id: %x, value:%d\n", __func__, + FMDBG("%s enter, ctrl->id: %x, value:%d\n", __func__, ctrl->id, ctrl->value); mutex_lock(&radio->lock); switch (ctrl->id) { case V4L2_CID_PRIVATE_CSR0_ENABLE: - pr_info("V4L2_CID_PRIVATE_CSR0_ENABLE val=%d\n", ctrl->value); + FMDBG("V4L2_CID_PRIVATE_CSR0_ENABLE val=%d\n", ctrl->value); break; case V4L2_CID_PRIVATE_CSR0_DISABLE: - pr_info("V4L2_CID_PRIVATE_CSR0_DISABLE val=%d\n", ctrl->value); + FMDBG("V4L2_CID_PRIVATE_CSR0_DISABLE val=%d\n", ctrl->value); break; case V4L2_CID_PRIVATE_CSR0_VOLUME: case V4L2_CID_AUDIO_VOLUME: @@ -1692,21 +1584,23 @@ int rtc6226_vidioc_g_ctrl(struct file *file, void *priv, case V4L2_CID_PRIVATE_RSSI: rtc6226_get_all_registers(radio); ctrl->value = radio->registers[RSSI] & RSSI_RSSI; - pr_info("Get V4L2_CONTROL V4L2_CID_PRIVATE_RSSI: STATUS=0x%4.4hx RSSI = %d\n", - radio->registers[STATUS], + FMDBG("Get V4L2_CONTROL V4L2_CID_PRIVATE_RSSI: RSSI = %d\n", radio->registers[RSSI] & RSSI_RSSI); - pr_info("Get V4L2_CONTROL V4L2_CID_PRIVATE_RSSI: regC=0x%4.4hx RegD=0x%4.4hx\n", - radio->registers[BA_DATA], radio->registers[BB_DATA]); - pr_info("Get V4L2_CONTROL V4L2_CID_PRIVATE_RSSI: regE=0x%4.4hx RegF=0x%4.4hx\n", - radio->registers[BC_DATA], radio->registers[BD_DATA]); break; case V4L2_CID_PRIVATE_DEVICEID: ctrl->value = radio->registers[DEVICEID] & DEVICE_ID; - pr_info("Get V4L2_CONTROL V4L2_CID_PRIVATE_DEVICEID: DEVICEID=0x%4.4hx\n", + FMDBG("Get V4L2_CID_PRIVATE_DEVICEID: DEVICEID=0x%4.4hx\n", radio->registers[DEVICEID]); break; + case V4L2_CID_PRIVATE_RTC6226_RDSGROUP_PROC: + break; + case V4L2_CID_PRIVATE_RTC6226_SIGNAL_TH: + /* intentional fallthrough */ + case V4L2_CID_PRIVATE_RTC6226_RSSI_TH: + ctrl->value = radio->rssi_th; + break; default: - pr_info("%s in default id:%d\n", __func__, ctrl->id); + FMDBG("%s in default id:%d\n", __func__, ctrl->id); retval = -EINVAL; } @@ -1726,14 +1620,14 @@ static int rtc6226_vidioc_dqbuf(struct file *file, void *priv, int len = 0, retval = -1; if ((radio == NULL) || (buffer == NULL)) { - pr_err("%s radio/buffer is NULL\n", __func__); + FMDERR("%s radio/buffer is NULL\n", __func__); return -ENXIO; } buf_type = buffer->index; buf = (u8 *)buffer->m.userptr; len = buffer->length; - pr_info("%s: requesting buffer %d\n", __func__, buf_type); + FMDBG("%s: requesting buffer %d\n", __func__, buf_type); if ((buf_type < RTC6226_FM_BUF_MAX) && (buf_type >= 0)) { data_fifo = &radio->data_buf[buf_type]; @@ -1744,20 +1638,20 @@ static int rtc6226_vidioc_dqbuf(struct file *file, void *priv, } } } else { - pr_err("%s invalid buffer type\n", __func__); + FMDERR("%s invalid buffer type\n", __func__); return -EINVAL; } if (len <= STD_BUF_SIZE) { buffer->bytesused = kfifo_out_locked(data_fifo, &buf_fifo[0], len, &radio->buf_lock[buf_type]); } else { - pr_err("%s kfifo_out_locked can not use len more than 128\n", + FMDERR("%s kfifo_out_locked can not use len more than 128\n", __func__); return -EINVAL; } retval = copy_to_user(buf, &buf_fifo[0], buffer->bytesused); if (retval > 0) { - pr_err("%s Failed to copy %d bytes data\n", __func__, retval); + FMDERR("%s Failed to copy %d bytes data\n", __func__, retval); return -EAGAIN; } @@ -1786,17 +1680,17 @@ static int rtc6226_disable(struct rtc6226_device *radio) radio->registers[SYSCFG] &= ~SYSCFG_CSR0_STDIRQEN; retval = rtc6226_set_register(radio, SYSCFG); if (retval < 0) { - pr_err("%s fail to disable RDS/SCT interrupt\n", __func__); + FMDERR("%s fail to disable RDS/SCT interrupt\n", __func__); goto done; } retval = rtc6226_power_down(radio); if (retval < 0) { - pr_err("%s fail to turn off fmradio\n", __func__); + FMDERR("%s fail to turn off fmradio\n", __func__); goto done; } if (radio->mode == FM_TURNING_OFF || radio->mode == FM_RECV) { - pr_info("%s: posting RTC6226_EVT_RADIO_DISABLED event\n", + FMDBG("%s: posting RTC6226_EVT_RADIO_DISABLED event\n", __func__); rtc6226_q_event(radio, RTC6226_EVT_RADIO_DISABLED); radio->mode = FM_OFF; @@ -1811,18 +1705,17 @@ static int rtc6226_enable(struct rtc6226_device *radio) { int retval = 0; - retval = rtc6226_get_register(radio, POWERCFG); - if ((radio->registers[POWERCFG] & POWERCFG_CSR0_ENABLE) == 0) - rtc6226_power_up(radio); - else - pr_info("%s already turn on\n", __func__); + rtc6226_get_register(radio, POWERCFG); + retval = rtc6226_power_up(radio); + if (retval < 0) + goto done; if ((radio->registers[SYSCFG] & SYSCFG_CSR0_STDIRQEN) == 0) { radio->registers[SYSCFG] |= SYSCFG_CSR0_RDSIRQEN; radio->registers[SYSCFG] |= SYSCFG_CSR0_STDIRQEN; retval = rtc6226_set_register(radio, SYSCFG); if (retval < 0) { - pr_err("%s set register fail\n", __func__); + FMDERR("%s set register fail\n", __func__); goto done; } else { rtc6226_q_event(radio, RTC6226_EVT_RADIO_READY); @@ -1856,14 +1749,14 @@ int rtc6226_vidioc_s_ctrl(struct file *file, void *priv, int retval = 0; int space_s = 0; - pr_info("%s enter, ctrl->id: %x, value:%d\n", __func__, + FMDBG("%s enter, ctrl->id: %x, value:%d\n", __func__, ctrl->id, ctrl->value); switch (ctrl->id) { case V4L2_CID_PRIVATE_RTC6226_STATE: if (ctrl->value == FM_RECV) { if (check_mode(radio)) { - pr_err("%s:fm is not in proper state\n", + FMDERR("%s:fm is not in proper state\n", __func__); retval = -EINVAL; goto end; @@ -1871,7 +1764,7 @@ int rtc6226_vidioc_s_ctrl(struct file *file, void *priv, radio->mode = FM_RECV_TURNING_ON; retval = rtc6226_enable(radio); if (retval < 0) { - pr_err( + FMDERR( "%s Error while enabling RECV FM %d\n", __func__, retval); radio->mode = FM_OFF; @@ -1881,7 +1774,7 @@ int rtc6226_vidioc_s_ctrl(struct file *file, void *priv, radio->mode = FM_TURNING_OFF; retval = rtc6226_disable(radio); if (retval < 0) { - pr_err("Err on disable recv FM %d\n", retval); + FMDERR("Err on disable recv FM %d\n", retval); radio->mode = FM_RECV; goto end; } @@ -1917,29 +1810,36 @@ int rtc6226_vidioc_s_ctrl(struct file *file, void *priv, rtc6226_search(radio, (bool)ctrl->value); break; case V4L2_CID_PRIVATE_RTC6226_LP_MODE: + if (ctrl->value) { + /* disable RDS interrupts */ + radio->registers[SYSCFG] &= ~SYSCFG_CSR0_RDSIRQEN; + retval = rtc6226_set_register(radio, SYSCFG); + } else { + /* enable RDS interrupts */ + radio->registers[SYSCFG] |= SYSCFG_CSR0_RDSIRQEN; + retval = rtc6226_set_register(radio, SYSCFG); + } + break; case V4L2_CID_PRIVATE_RTC6226_ANTENNA: - case V4L2_CID_PRIVATE_RTC6226_RDSON: case V4L2_CID_PRIVATE_RTC6226_AF_JUMP: case V4L2_CID_PRIVATE_RTC6226_SRCH_CNT: case V4L2_CID_PRIVATE_RTC6226_RXREPEATCOUNT: + case V4L2_CID_PRIVATE_RTC6226_SINR_THRESHOLD: retval = 0; break; - case V4L2_CID_PRIVATE_RTC6226_RSSI_TH: - case V4L2_CID_PRIVATE_RTC6226_SINR_THRESHOLD: - radio->rssi_th = ctrl->value >> 16; - radio->registers[SEEKCFG1] &= ~SEEKCFG1_CSR0_RSSI_LOW_TH; - radio->registers[SEEKCFG1] |= radio->rssi_th; - retval = rtc6226_set_register(radio, SEEKCFG1); + case V4L2_CID_PRIVATE_RTC6226_SIGNAL_TH: + retval = rtc6226_set_rssi_threshold(radio, ctrl->value); if (retval < 0) - pr_err("%s fail to set rssi\n", __func__); + FMDERR("%s fail to set rssi threshold\n", __func__); rtc6226_get_register(radio, SEEKCFG1); - pr_info("FMRICHWAVE RSSI_TH: Dec = %d , Hexa = %x\n", + FMDBG("FMRICHWAVE RSSI_TH: Dec = %d , Hexa = %x\n", radio->registers[SEEKCFG1] & 0xFF, radio->registers[SEEKCFG1] & 0xFF); break; /* case V4L2_CID_PRIVATE_RTC6226_OFS_THRESHOLD: */ case V4L2_CID_PRIVATE_RTC6226_SPUR_FREQ_RMSSI: break; + case V4L2_CID_PRIVATE_RTC6226_RDSD_BUF: case V4L2_CID_PRIVATE_RTC6226_RDSGROUP_MASK: case V4L2_CID_PRIVATE_RTC6226_RDSGROUP_PROC: if ((radio->registers[SYSCFG] & SYSCFG_CSR0_RDS_EN) == 0) @@ -1950,7 +1850,7 @@ int rtc6226_vidioc_s_ctrl(struct file *file, void *priv, if (rtc6226_is_valid_srch_mode(ctrl->value)) { radio->g_search_mode = ctrl->value; } else { - pr_err("%s:srch mode is not valid\n", __func__); + FMDERR("%s:srch mode is not valid\n", __func__); retval = -EINVAL; goto end; } @@ -1962,36 +1862,36 @@ int rtc6226_vidioc_s_ctrl(struct file *file, void *priv, (ctrl->value <= MAX_DWELL_TIME)) { radio->dwell_time_sec = ctrl->value; } else { - pr_err( + FMDERR( "%s:scandwell period is not valid\n", __func__); retval = -EINVAL; } break; case V4L2_CID_PRIVATE_CSR0_ENABLE: - pr_info("V4L2_CID_PRIVATE_CSR0_ENABLE val=%d\n", + FMDBG("V4L2_CID_PRIVATE_CSR0_ENABLE val=%d\n", ctrl->value); retval = rtc6226_power_up(radio); /* must keep below line */ ctrl->value = 0; break; case V4L2_CID_PRIVATE_CSR0_DISABLE: - pr_info("V4L2_CID_PRIVATE_CSR0_DISABLE val=%d\n", + FMDBG("V4L2_CID_PRIVATE_CSR0_DISABLE val=%d\n", ctrl->value); retval = rtc6226_power_down(radio); /* must keep below line */ ctrl->value = 0; break; case V4L2_CID_PRIVATE_DEVICEID: - pr_info("V4L2_CID_PRIVATE_DEVICEID val=%d\n", ctrl->value); + FMDBG("V4L2_CID_PRIVATE_DEVICEID val=%d\n", ctrl->value); break; case V4L2_CID_PRIVATE_CSR0_VOLUME: case V4L2_CID_AUDIO_VOLUME: - pr_info("MPXCFG=0x%4.4hx POWERCFG=0x%4.4hx\n", + FMDBG("MPXCFG=0x%4.4hx POWERCFG=0x%4.4hx\n", radio->registers[MPXCFG], radio->registers[POWERCFG]); radio->registers[MPXCFG] &= ~MPXCFG_CSR0_VOLUME; radio->registers[MPXCFG] |= (ctrl->value > 15) ? 8 : ctrl->value; - pr_info("MPXCFG=0x%4.4hx POWERCFG=0x%4.4hx\n", + FMDBG("MPXCFG=0x%4.4hx POWERCFG=0x%4.4hx\n", radio->registers[MPXCFG], radio->registers[POWERCFG]); retval = rtc6226_set_register(radio, MPXCFG); break; @@ -2003,8 +1903,8 @@ int rtc6226_vidioc_s_ctrl(struct file *file, void *priv, radio->registers[MPXCFG] |= MPXCFG_CSR0_DIS_MUTE; retval = rtc6226_set_register(radio, MPXCFG); break; - case V4L2_CID_PRIVATE_CSR0_DIS_SMUTE: - pr_info("V4L2_CID_PRIVATE_CSR0_DIS_SMUTE\n"); + case V4L2_CID_PRIVATE_RTC6226_SOFT_MUTE: + FMDBG("V4L2_CID_PRIVATE_RTC6226_SOFT_MUTE\n"); if (ctrl->value == 1) radio->registers[MPXCFG] &= ~MPXCFG_CSR0_DIS_SMUTE; else @@ -2012,7 +1912,7 @@ int rtc6226_vidioc_s_ctrl(struct file *file, void *priv, retval = rtc6226_set_register(radio, MPXCFG); break; case V4L2_CID_PRIVATE_CSR0_DEEM: - pr_info("V4L2_CID_PRIVATE_CSR0_DEEM\n"); + FMDBG("V4L2_CID_PRIVATE_CSR0_DEEM\n"); if (ctrl->value == 1) radio->registers[MPXCFG] |= MPXCFG_CSR0_DEEM; else @@ -2020,11 +1920,11 @@ int rtc6226_vidioc_s_ctrl(struct file *file, void *priv, retval = rtc6226_set_register(radio, MPXCFG); break; case V4L2_CID_PRIVATE_CSR0_BLNDADJUST: - pr_info("V4L2_CID_PRIVATE_CSR0_BLNDADJUST val=%d\n", + FMDBG("V4L2_CID_PRIVATE_CSR0_BLNDADJUST val=%d\n", ctrl->value); break; case V4L2_CID_PRIVATE_CSR0_BAND: - pr_info( + FMDBG( "V4L2_CID_PRIVATE_CSR0_BAND : FREQ_TOP=%d FREQ_BOT=%d %d\n", radio->registers[RADIOSEEKCFG1], radio->registers[RADIOSEEKCFG2], ctrl->value); @@ -2049,7 +1949,7 @@ int rtc6226_vidioc_s_ctrl(struct file *file, void *priv, retval = -EINVAL; break; } - pr_info( + FMDBG( "V4L2_CID_PRIVATE_CSR0_BAND : FREQ_TOP=%d FREQ_BOT=%d %d\n", radio->registers[RADIOSEEKCFG1], radio->registers[RADIOSEEKCFG2], ctrl->value); @@ -2058,7 +1958,7 @@ int rtc6226_vidioc_s_ctrl(struct file *file, void *priv, retval = rtc6226_set_register(radio, RADIOSEEKCFG2); break; case V4L2_CID_PRIVATE_CSR0_CHSPACE: - pr_info("V4L2_CID_PRIVATE_CSR0_CHSPACE : FM_SPACE=%d %d\n", + FMDBG("V4L2_CID_PRIVATE_CSR0_CHSPACE : FM_SPACE=%d %d\n", radio->registers[RADIOCFG], ctrl->value); switch (ctrl->value) { case FMSPACE_200_KHZ: @@ -2075,16 +1975,16 @@ int rtc6226_vidioc_s_ctrl(struct file *file, void *priv, break; } radio->space = ctrl->value; - pr_info("V4L2_CID_PRIVATE_CSR0_CHSPACE : FM_SPACE=%d %d\n", + FMDBG("V4L2_CID_PRIVATE_CSR0_CHSPACE : FM_SPACE=%d %d\n", radio->registers[RADIOCFG], ctrl->value); retval = rtc6226_set_register(radio, RADIOCFG); break; case V4L2_CID_PRIVATE_CSR0_DIS_AGC: - pr_info("V4L2_CID_PRIVATE_CSR0_DIS_AGC val=%d\n", + FMDBG("V4L2_CID_PRIVATE_CSR0_DIS_AGC val=%d\n", ctrl->value); break; - case V4L2_CID_PRIVATE_CSR0_RDS_EN: - pr_info( + case V4L2_CID_PRIVATE_RTC6226_RDSON: + FMDBG( "V4L2_CSR0_RDS_EN:CHANNEL=0x%4.4hx SYSCFG=0x%4.4hx\n", radio->registers[CHANNEL], radio->registers[SYSCFG]); @@ -2093,7 +1993,7 @@ int rtc6226_vidioc_s_ctrl(struct file *file, void *priv, radio->registers[SYSCFG] &= ~SYSCFG_CSR0_RDSIRQEN; radio->registers[SYSCFG] |= (ctrl->value << 15); radio->registers[SYSCFG] |= (ctrl->value << 12); - pr_info + FMDBG ("V4L2_CSR0_RDS_EN : CHANNEL=0x%4.4hx SYSCFG=0x%4.4hx\n", radio->registers[CHANNEL], radio->registers[SYSCFG]); @@ -2108,13 +2008,13 @@ int rtc6226_vidioc_s_ctrl(struct file *file, void *priv, retval = rtc6226_set_register(radio, SEEKCFG1); break; default: - pr_info("%s id: %x in default\n", __func__, ctrl->id); + FMDBG("%s id: %x in default\n", __func__, ctrl->id); retval = -EINVAL; break; } end: - pr_info("%s exit id: %x , ret: %d\n", __func__, ctrl->id, retval); + FMDBG("%s exit id: %x , ret: %d\n", __func__, ctrl->id, retval); return retval; } @@ -2144,7 +2044,7 @@ static int rtc6226_vidioc_g_tuner(struct file *file, void *priv, struct rtc6226_device *radio = video_drvdata(file); int retval = 0; - pr_info("%s enter\n", __func__); + FMDBG("%s enter\n", __func__); if (tuner->index != 0) { retval = -EINVAL; @@ -2161,11 +2061,13 @@ static int rtc6226_vidioc_g_tuner(struct file *file, void *priv, tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO; - tuner->rangelow = (radio->registers[RADIOSEEKCFG1] & - CHANNEL_CSR0_FREQ_TOP) * 10; - tuner->rangehigh = (radio->registers[RADIOSEEKCFG2] & - CHANNEL_CSR0_FREQ_BOT) * 10; + tuner->rangehigh = (radio->registers[RADIOSEEKCFG1] & + CHANNEL_CSR0_FREQ_TOP) * TUNE_STEP_SIZE * TUNE_PARAM; + tuner->rangelow = (radio->registers[RADIOSEEKCFG2] & + CHANNEL_CSR0_FREQ_BOT) * TUNE_STEP_SIZE * TUNE_PARAM; + FMDBG("%s low:%d high:%d\n", __func__, + tuner->rangelow, tuner->rangehigh); /* stereo indicator == stereo (instead of mono) */ if ((radio->registers[STATUS] & STATUS_SI) == 0) tuner->rxsubchans = V4L2_TUNER_SUB_MONO; @@ -2178,16 +2080,19 @@ static int rtc6226_vidioc_g_tuner(struct file *file, void *priv, tuner->rxsubchans |= V4L2_TUNER_SUB_RDS; /* mono/stereo selector */ - if ((radio->registers[MPXCFG] & MPXCFG_CSR0_MONO) == 0) + if ((radio->registers[MPXCFG] & MPXCFG_CSR0_MONO) == 0) { tuner->audmode = V4L2_TUNER_MODE_STEREO; - else + rtc6226_q_event(radio, RTC6226_EVT_STEREO); + } else { tuner->audmode = V4L2_TUNER_MODE_MONO; + rtc6226_q_event(radio, RTC6226_EVT_MONO); + } /* min is worst, max is best; rssi: 0..0xff */ tuner->signal = (radio->registers[RSSI] & RSSI_RSSI); done: - pr_info("%s exit %d\n", __func__, retval); + FMDBG("%s exit %d\n", __func__, retval); return retval; } @@ -2201,11 +2106,13 @@ static int rtc6226_vidioc_s_tuner(struct file *file, void *priv, { struct rtc6226_device *radio = video_drvdata(file); int retval = 0; + u16 bottom_freq; + u16 top_freq; - pr_info("%s entry\n", __func__); + FMDBG("%s entry\n", __func__); if (tuner->index != 0) { - pr_info("%s index :%d\n", __func__, tuner->index); + FMDBG("%s index :%d\n", __func__, tuner->index); goto done; } @@ -2218,35 +2125,36 @@ static int rtc6226_vidioc_s_tuner(struct file *file, void *priv, radio->registers[MPXCFG] &= ~MPXCFG_CSR0_MONO; /* try stereo */ break; default: - goto done; + FMDBG("%s audmode is not set\n", __func__); } retval = rtc6226_set_register(radio, MPXCFG); - pr_info("%s low:%d high:%d\n", __func__, - tuner->rangelow, tuner->rangehigh); + /* unit is 10kHz */ + top_freq = (u16)((tuner->rangehigh / TUNE_PARAM) / TUNE_STEP_SIZE); + bottom_freq = (u16)((tuner->rangelow / TUNE_PARAM) / TUNE_STEP_SIZE); - /* set band */ - if (tuner->rangelow || tuner->rangehigh) { - for (band = 0; band < ARRAY_SIZE(bands); band++) { - if (bands[band].rangelow == tuner->rangelow && - bands[band].rangehigh == tuner->rangehigh) - break; - } - if (band == ARRAY_SIZE(bands)) { - pr_err("%s err\n", __func__); - band = 0; - } - } else - band = 0; /* If nothing is specified seek 87.5 - 108 Mhz */ + FMDBG("%s low:%d high:%d\n", __func__, + bottom_freq, top_freq); - if (radio->band != band) { - radio->registers[CHANNEL] |= (band << 12); - rtc6226_set_register(radio, MPXCFG); - radio->band = band; - } + radio->registers[RADIOSEEKCFG1] = top_freq; + radio->registers[RADIOSEEKCFG2] = bottom_freq; + + retval = rtc6226_set_register(radio, RADIOSEEKCFG1); + if (retval < 0) + FMDERR("In %s, error %d setting higher limit freq\n", + __func__, retval); + else + radio->recv_conf.band_high_limit = top_freq; + + retval = rtc6226_set_register(radio, RADIOSEEKCFG2); + if (retval < 0) + FMDERR("In %s, error %d setting lower limit freq\n", + __func__, retval); + else + radio->recv_conf.band_low_limit = bottom_freq; done: - pr_info("%s exit %d\n", __func__, retval); + FMDBG("%s exit %d\n", __func__, retval); return retval; } @@ -2259,15 +2167,18 @@ static int rtc6226_vidioc_g_frequency(struct file *file, void *priv, { struct rtc6226_device *radio = video_drvdata(file); int retval = 0; + unsigned int frq; - pr_info("%s enter freq %d\n", __func__, freq->frequency); + FMDBG("%s enter freq %d\n", __func__, freq->frequency); freq->type = V4L2_TUNER_RADIO; - retval = rtc6226_get_freq(radio, &freq->frequency); - pr_info(" %s *freq=%d, ret %d\n", __func__, freq->frequency, retval); + retval = rtc6226_get_freq(radio, &frq); + freq->frequency = frq * TUNE_PARAM; + radio->tuned_freq_khz = frq * TUNE_STEP_SIZE; + FMDBG(" %s *freq=%d, ret %d\n", __func__, freq->frequency, retval); if (retval < 0) - pr_err(" %s get frequency failed with %d\n", __func__, retval); + FMDERR(" %s get frequency failed with %d\n", __func__, retval); return retval; } @@ -2281,13 +2192,23 @@ static int rtc6226_vidioc_s_frequency(struct file *file, void *priv, { struct rtc6226_device *radio = video_drvdata(file); int retval = 0; + u32 f = 0; - pr_info("%s enter freq = %d\n", __func__, freq->frequency); - - retval = rtc6226_set_freq(radio, freq->frequency); + FMDBG("%s enter freq = %d\n", __func__, freq->frequency); + if (unlikely(freq == NULL)) { + FMDERR("%s:freq is null\n", __func__); + return -EINVAL; + } + if (freq->type != V4L2_TUNER_RADIO) + return -EINVAL; + f = (freq->frequency)/TUNE_PARAM; + radio->seek_tune_status = TUNE_PENDING; + retval = rtc6226_set_freq(radio, f); if (retval < 0) - pr_err("%s set frequency failed with %d\n", __func__, retval); + FMDERR("%s set frequency failed with %d\n", __func__, retval); + else + radio->tuned_freq_khz = f; return retval; } @@ -2302,7 +2223,7 @@ static int rtc6226_vidioc_s_hw_freq_seek(struct file *file, void *priv, struct rtc6226_device *radio = video_drvdata(file); int retval = 0; - pr_info("%s enter\n", __func__); + FMDBG("%s enter\n", __func__); if (file->f_flags & O_NONBLOCK) return -EWOULDBLOCK; @@ -2311,40 +2232,35 @@ static int rtc6226_vidioc_s_hw_freq_seek(struct file *file, void *priv, if (radio->g_search_mode == SEEK) { /* seek */ - pr_info("%s starting seek\n", __func__); + FMDBG("%s starting seek\n", __func__); radio->seek_tune_status = SEEK_PENDING; retval = rtc6226_set_seek(radio, seek->seek_upward, WRAP_ENABLE); - rtc6226_q_event(radio, RTC6226_EVT_TUNE_SUCC); - radio->seek_tune_status = NO_SEEK_TUNE_PENDING; - rtc6226_q_event(radio, RTC6226_EVT_SCAN_NEXT); } else if ((radio->g_search_mode == SCAN) || (radio->g_search_mode == SCAN_FOR_STRONG)) { /* scan */ if (radio->g_search_mode == SCAN_FOR_STRONG) { - pr_info("%s starting search list\n", __func__); + FMDBG("%s starting search list\n", __func__); memset(&radio->srch_list, 0, sizeof(struct rtc6226_srch_list_compl)); } else { - pr_info("%s starting scan\n", __func__); + FMDBG("%s starting scan\n", __func__); } - rtc6226_search(radio, 1); + rtc6226_search(radio, START_SCAN); } else { retval = -EINVAL; - pr_err("In %s, invalid search mode %d\n", + FMDERR("In %s, invalid search mode %d\n", __func__, radio->g_search_mode); } - pr_info("%s exit %d\n", __func__, retval); + FMDBG("%s exit %d\n", __func__, retval); return retval; } -#ifndef RW_Kernel_ENG static int rtc6226_vidioc_g_fmt_type_private(struct file *file, void *priv, struct v4l2_format *f) { return 0; } -#endif static const struct v4l2_file_operations rtc6226_fops = { .owner = THIS_MODULE, @@ -2373,9 +2289,7 @@ const struct v4l2_ioctl_ops rtc6226_ioctl_ops = { .vidioc_s_frequency = rtc6226_vidioc_s_frequency, .vidioc_s_hw_freq_seek = rtc6226_vidioc_s_hw_freq_seek, .vidioc_dqbuf = rtc6226_vidioc_dqbuf, -#ifndef RW_Kernel_ENG .vidioc_g_fmt_type_private = rtc6226_vidioc_g_fmt_type_private, -#endif }; /* @@ -2397,7 +2311,7 @@ struct video_device rtc6226_viddev_template = { */ static __init int rtc6226_init(void) { - pr_info(DRIVER_DESC ", Version " DRIVER_VERSION "\n"); + FMDBG(DRIVER_DESC ", Version " DRIVER_VERSION "\n"); return rtc6226_i2c_init(); } diff --git a/drivers/media/radio/rtc6226/radio-rtc6226-i2c.c b/drivers/media/radio/rtc6226/radio-rtc6226-i2c.c index eb7fb4963b1b..f4e62c19b3df 100644 --- a/drivers/media/radio/rtc6226/radio-rtc6226-i2c.c +++ b/drivers/media/radio/rtc6226/radio-rtc6226-i2c.c @@ -179,7 +179,7 @@ int rtc6226_get_all_registers(struct rtc6226_device *radio) int i; int err; u8 reg[1] = {0x00}; - u8 buf[RADIO_REGISTER_NUM * 2]; + u8 buf[RADIO_REGISTER_NUM]; struct i2c_msg msgs1[1] = { { radio->client->addr, 0, 1, reg}, }; @@ -208,7 +208,7 @@ int rtc6226_get_all_registers(struct rtc6226_device *radio) int rtc6226_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *capability) { - pr_info("%s enter\n", __func__); + FMDBG("%s enter\n", __func__); strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver)); strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_READWRITE | @@ -226,47 +226,81 @@ static void rtc6226_i2c_interrupt_handler(struct rtc6226_device *radio) { unsigned char regnr; int retval = 0; + unsigned short current_chan; - pr_info("%s enter\n", __func__); + FMDBG("%s enter\n", __func__); /* check Seek/Tune Complete */ retval = rtc6226_get_register(radio, STATUS); if (retval < 0) { - pr_err("%s read fail to STATUS\n", __func__); - goto end; - } - retval = rtc6226_get_register(radio, RSSI); - if (retval < 0) { - pr_err("%s read fail to RSSI\n", __func__); + FMDERR("%s read fail to STATUS\n", __func__); goto end; } if (radio->registers[STATUS] & STATUS_STD) { - complete(&radio->completion); - pr_info("%s Seek/Tune Done\n", __func__); - } + FMDBG("%s : STATUS=0x%4.4hx\n", __func__, + radio->registers[STATUS]); - /* Update RDS registers */ - for (regnr = 1; regnr < RDS_REGISTER_NUM; regnr++) { - retval = rtc6226_get_register(radio, STATUS + regnr); - if (retval < 0) + retval = rtc6226_get_register(radio, RSSI); + if (retval < 0) { + FMDERR("%s read fail to RSSI\n", __func__); goto end; - } - - /* get rds blocks */ - if ((radio->registers[STATUS] & STATUS_RDS_RDY) == 0) { - /* No RDS group ready, better luck next time */ - pr_err("%s No RDS group ready\n", __func__); - goto end; + } + FMDBG("%s : RSSI=0x%4.4hx\n", __func__, radio->registers[RSSI]); + /* stop seeking : clear STD*/ + radio->registers[SEEKCFG1] &= ~SEEKCFG1_CSR0_SEEK; + retval = rtc6226_set_register(radio, SEEKCFG1); + /*clear the status bit to allow another tune or seek*/ + current_chan = radio->registers[CHANNEL] & CHANNEL_CSR0_CH; + radio->registers[CHANNEL] &= ~CHANNEL_CSR0_TUNE; + retval = rtc6226_set_register(radio, CHANNEL); + if (retval < 0) + radio->registers[CHANNEL] = current_chan; + rtc6226_reset_rds_data(radio); + FMDBG("%s clear Seek/Tune bit\n", __func__); + if (radio->seek_tune_status == SEEK_PENDING) { + FMDBG("posting RTC6226_EVT_SEEK_COMPLETE event\n"); + rtc6226_q_event(radio, RTC6226_EVT_SEEK_COMPLETE); + /* post tune comp evt since seek results in a tune.*/ + FMDBG("posting RICHWAVE_EVT_TUNE_SUCC event\n"); + rtc6226_q_event(radio, RTC6226_EVT_TUNE_SUCC); + radio->seek_tune_status = NO_SEEK_TUNE_PENDING; + } else if (radio->seek_tune_status == TUNE_PENDING) { + FMDBG("posting RICHWAVE_EVT_TUNE_SUCC event\n"); + rtc6226_q_event(radio, RTC6226_EVT_TUNE_SUCC); + radio->seek_tune_status = NO_SEEK_TUNE_PENDING; + } else if (radio->seek_tune_status == SCAN_PENDING) { + /* when scan is pending and STC int is set, signal + * so that scan can proceed + */ + FMDBG("In %s, signalling scan thread\n", __func__); + complete(&radio->completion); + } + FMDBG("%s Seek/Tune done\n", __func__); } else { + /* Check RDS data after tune/seek interrupt finished + * Update RDS registers + */ + for (regnr = 1; regnr < RDS_REGISTER_NUM; regnr++) { + retval = rtc6226_get_register(radio, STATUS + regnr); + if (retval < 0) + goto end; + } + /* get rds blocks */ + if ((radio->registers[STATUS] & STATUS_RDS_RDY) == 0) { + /* No RDS group ready, better luck next time */ + FMDERR("%s No RDS group ready\n", __func__); + goto end; + } else { /* avoid RDS interrupt lock disable_irq*/ - if ((radio->registers[SYSCFG] & SYSCFG_CSR0_RDS_EN) != 0) { - pr_info("%s start rds handler\n", __func__); - schedule_work(&radio->rds_worker); + if ((radio->registers[SYSCFG] & + SYSCFG_CSR0_RDS_EN) != 0) { + schedule_work(&radio->rds_worker); + } } } end: - pr_info("%s exit :%d\n", __func__, retval); + FMDBG("%s exit :%d\n", __func__, retval); } static irqreturn_t rtc6226_isr(int irq, void *dev_id) @@ -319,7 +353,7 @@ int rtc6226_enable_irq(struct rtc6226_device *radio) retval = gpio_direction_input(radio->int_gpio); if (retval) { - pr_err("%s unable to set the gpio %d direction(%d)\n", + FMDERR("%s unable to set the gpio %d direction(%d)\n", __func__, radio->int_gpio, retval); return retval; } @@ -327,25 +361,25 @@ int rtc6226_enable_irq(struct rtc6226_device *radio) irq = radio->irq; if (radio->irq < 0) { - pr_err("%s: gpio_to_irq returned %d\n", __func__, radio->irq); + FMDERR("%s: gpio_to_irq returned %d\n", __func__, radio->irq); goto open_err_req_irq; } - pr_info("%s irq number is = %d\n", __func__, radio->irq); + FMDBG("%s irq number is = %d\n", __func__, radio->irq); retval = request_any_context_irq(radio->irq, rtc6226_isr, IRQF_TRIGGER_FALLING, DRIVER_NAME, radio); if (retval < 0) { - pr_err("%s Couldn't acquire FM gpio %d, retval:%d\n", + FMDERR("%s Couldn't acquire FM gpio %d, retval:%d\n", __func__, radio->irq, retval); goto open_err_req_irq; } else { - pr_info("%s FM GPIO %d registered\n", __func__, radio->irq); + FMDBG("%s FM GPIO %d registered\n", __func__, radio->irq); } retval = enable_irq_wake(irq); if (retval < 0) { - pr_err("Could not wake FM interrupt\n"); + FMDERR("Could not wake FM interrupt\n"); free_irq(irq, radio); } return retval; @@ -356,6 +390,133 @@ open_err_req_irq: return retval; } +static int rtc6226_fm_vio_reg_cfg(struct rtc6226_device *radio, bool on) +{ + int rc = 0; + struct fm_power_vreg_data *vreg; + + vreg = radio->vioreg; + if (!vreg) { + FMDERR("In %s, vio reg is NULL\n", __func__); + return rc; + } + if (on) { + FMDBG("vreg is : %s\n", vreg->name); + rc = regulator_set_voltage(vreg->reg, + vreg->low_vol_level, + vreg->high_vol_level); + if (rc < 0) { + FMDERR("set_vol(%s) fail %d\n", vreg->name, rc); + return rc; + } + rc = regulator_enable(vreg->reg); + if (rc < 0) { + FMDERR("reg enable(%s) failed.rc=%d\n", vreg->name, rc); + regulator_set_voltage(vreg->reg, + 0, + vreg->high_vol_level); + return rc; + } + vreg->is_enabled = true; + + } else { + rc = regulator_disable(vreg->reg); + if (rc < 0) { + FMDERR("reg disable(%s) fail rc=%d\n", vreg->name, rc); + return rc; + } + vreg->is_enabled = false; + + /* Set the min voltage to 0 */ + rc = regulator_set_voltage(vreg->reg, + 0, + vreg->high_vol_level); + if (rc < 0) { + FMDERR("set_vol(%s) fail %d\n", vreg->name, rc); + return rc; + } + } + return rc; +} + +static int rtc6226_fm_vdd_reg_cfg(struct rtc6226_device *radio, bool on) +{ + int rc = 0; + struct fm_power_vreg_data *vreg; + + vreg = radio->vddreg; + if (!vreg) { + FMDERR("In %s, vdd reg is NULL\n", __func__); + return rc; + } + + if (on) { + FMDBG("vreg is : %s\n", vreg->name); + rc = regulator_set_voltage(vreg->reg, + vreg->low_vol_level, + vreg->high_vol_level); + if (rc < 0) { + FMDERR("set_vol(%s) fail %d\n", vreg->name, rc); + return rc; + } + + rc = regulator_enable(vreg->reg); + if (rc < 0) { + FMDERR("reg enable(%s) failed.rc=%d\n", vreg->name, rc); + regulator_set_voltage(vreg->reg, + 0, + vreg->high_vol_level); + return rc; + } + vreg->is_enabled = true; + } else { + rc = regulator_disable(vreg->reg); + if (rc < 0) { + FMDERR("reg disable(%s) fail. rc=%d\n", vreg->name, rc); + return rc; + } + vreg->is_enabled = false; + + /* Set the min voltage to 0 */ + rc = regulator_set_voltage(vreg->reg, + 0, + vreg->high_vol_level); + if (rc < 0) { + FMDERR("set_vol(%s) fail %d\n", vreg->name, rc); + return rc; + } + } + return rc; +} + +static int rtc6226_fm_power_cfg(struct rtc6226_device *radio, bool powerflag) +{ + int rc = 0; + + if (powerflag) { + /* Turn ON sequence */ + rc = rtc6226_fm_vdd_reg_cfg(radio, powerflag); + if (rc < 0) { + FMDERR("In %s, vdd reg cfg failed %x\n", __func__, rc); + return rc; + } + rc = rtc6226_fm_vio_reg_cfg(radio, powerflag); + if (rc < 0) { + FMDERR("In %s, vio reg cfg failed %x\n", __func__, rc); + rtc6226_fm_vdd_reg_cfg(radio, false); + return rc; + } + } else { + /* Turn OFF sequence */ + rc = rtc6226_fm_vdd_reg_cfg(radio, powerflag); + if (rc < 0) + FMDERR("In %s, vdd reg cfg failed %x\n", __func__, rc); + rc = rtc6226_fm_vio_reg_cfg(radio, powerflag); + if (rc < 0) + FMDERR("In %s, vio reg cfg failed %x\n", __func__, rc); + } + return rc; +} /* * rtc6226_fops_open - file open */ @@ -363,42 +524,43 @@ int rtc6226_fops_open(struct file *file) { struct rtc6226_device *radio = video_drvdata(file); int retval = v4l2_fh_open(file); - int i; - pr_info("%s enter\n", __func__); + FMDBG("%s enter user num = %d\n", __func__, radio->users); if (retval) { - pr_err("%s fail to open v4l2\n", __func__); + FMDERR("%s fail to open v4l2\n", __func__); return retval; } + if (atomic_inc_return(&radio->users) != 1) { + FMDERR("Device already in use. Try again later\n"); + atomic_dec(&radio->users); + return -EBUSY; + } INIT_DELAYED_WORK(&radio->work, rtc6226_handler); INIT_DELAYED_WORK(&radio->work_scan, rtc6226_scan); INIT_WORK(&radio->rds_worker, rtc6226_rds_handler); - if (v4l2_fh_is_singular_file(file)) { - retval = rtc6226_power_up(radio); - if (retval < 0) { - pr_err("%s fail to power_up\n", __func__); - goto done; - //return retval; - } + /* Power up Supply voltage to VDD and VIO */ + retval = rtc6226_fm_power_cfg(radio, TURNING_ON); + if (retval) { + FMDERR("%s: failed to supply voltage\n", __func__); + goto open_err_setup; } - retval = rtc6226_get_all_registers(radio); - if (retval < 0) - pr_err("%s fail to get register %d\n", __func__, retval); - else { - for (i = 0; i < 16; i++) - pr_info("%s registers[%d]:%x\n", __func__, i, - radio->registers[i]); - } + retval = rtc6226_enable_irq(radio); /* Wait for the value to take effect on gpio. */ msleep(100); - rtc6226_enable_irq(radio); + if (retval) { + FMDERR("%s:enable irq failed\n", __func__); + goto open_err_req_irq; + } + return retval; -done: - if (retval) - v4l2_fh_release(file); +open_err_req_irq: + rtc6226_fm_power_cfg(radio, TURNING_OFF); +open_err_setup: + atomic_dec(&radio->users); + v4l2_fh_release(file); return retval; } @@ -408,8 +570,9 @@ done: int rtc6226_fops_release(struct file *file) { struct rtc6226_device *radio = video_drvdata(file); + int retval = 0; - pr_info("%s : Exit\n", __func__); + FMDBG("%s : Exit\n", __func__); if (v4l2_fh_is_singular_file(file)) { if (radio->mode != FM_OFF) { rtc6226_power_down(radio); @@ -417,6 +580,10 @@ int rtc6226_fops_release(struct file *file) } } rtc6226_disable_irq(radio); + atomic_dec(&radio->users); + retval = rtc6226_fm_power_cfg(radio, TURNING_OFF); + if (retval < 0) + FMDERR("%s: failed to apply voltage\n", __func__); return v4l2_fh_release(file); } @@ -428,21 +595,21 @@ static int rtc6226_parse_dt(struct device *dev, radio->int_gpio = of_get_named_gpio(np, "fmint-gpio", 0); if (radio->int_gpio < 0) { - pr_err("%s int-gpio not provided in device tree\n", __func__); + FMDERR("%s int-gpio not provided in device tree\n", __func__); rc = radio->int_gpio; goto err_int_gpio; } rc = gpio_request(radio->int_gpio, "fm_int"); if (rc) { - pr_err("%s unable to request gpio %d (%d)\n", __func__, + FMDERR("%s unable to request gpio %d (%d)\n", __func__, radio->int_gpio, rc); goto err_int_gpio; } rc = gpio_direction_output(radio->int_gpio, 0); if (rc) { - pr_err("%s unable to set the gpio %d direction(%d)\n", + FMDERR("%s unable to set the gpio %d direction(%d)\n", __func__, radio->int_gpio, rc); goto err_int_gpio; } @@ -463,7 +630,7 @@ static int rtc6226_pinctrl_init(struct rtc6226_device *radio) radio->fm_pinctrl = devm_pinctrl_get(&radio->client->dev); if (IS_ERR_OR_NULL(radio->fm_pinctrl)) { - pr_err("%s: target does not use pinctrl\n", __func__); + FMDERR("%s: target does not use pinctrl\n", __func__); retval = PTR_ERR(radio->fm_pinctrl); return retval; } @@ -472,7 +639,7 @@ static int rtc6226_pinctrl_init(struct rtc6226_device *radio) pinctrl_lookup_state(radio->fm_pinctrl, "pmx_fm_active"); if (IS_ERR_OR_NULL(radio->gpio_state_active)) { - pr_err("%s: cannot get FM active state\n", __func__); + FMDERR("%s: cannot get FM active state\n", __func__); retval = PTR_ERR(radio->gpio_state_active); goto err_active_state; } @@ -481,7 +648,7 @@ static int rtc6226_pinctrl_init(struct rtc6226_device *radio) pinctrl_lookup_state(radio->fm_pinctrl, "pmx_fm_suspend"); if (IS_ERR_OR_NULL(radio->gpio_state_suspend)) { - pr_err("%s: cannot get FM suspend state\n", __func__); + FMDERR("%s: cannot get FM suspend state\n", __func__); retval = PTR_ERR(radio->gpio_state_suspend); goto err_suspend_state; } @@ -497,6 +664,23 @@ err_active_state: return retval; } +static int rtc6226_dt_parse_vreg_info(struct device *dev, + struct fm_power_vreg_data *vreg, const char *vreg_name) +{ + int ret = 0; + u32 vol_suply[2]; + struct device_node *np = dev->of_node; + + ret = of_property_read_u32_array(np, vreg_name, vol_suply, 2); + if (ret < 0) { + FMDERR("Invalid property name\n"); + ret = -EINVAL; + } else { + vreg->low_vol_level = vol_suply[0]; + vreg->high_vol_level = vol_suply[1]; + } + return ret; +} /* * rtc6226_i2c_probe - probe for the device @@ -507,6 +691,8 @@ static int rtc6226_i2c_probe(struct i2c_client *client, struct rtc6226_device *radio; struct v4l2_device *v4l2_dev; struct v4l2_ctrl_handler *hdl; + struct regulator *vddvreg = NULL; + struct regulator *viovreg = NULL; int retval = 0; int i = 0; int kfifo_alloc_rc = 0; @@ -514,60 +700,113 @@ static int rtc6226_i2c_probe(struct i2c_client *client, /* struct v4l2_ctrl *ctrl; */ /* need to add description "irq-fm" in dts */ - pr_info("%s enter\n", __func__); + FMDBG("%s enter\n", __func__); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { retval = -ENODEV; - goto err_initial; + return retval; + } + + /* + * if voltage regulator is not ready yet, return the error + * if error is -EPROBE_DEFER to kernel then probe will be called at + * later point of time. + */ + viovreg = regulator_get(&client->dev, "vio"); + if (IS_ERR(viovreg)) { + retval = PTR_ERR(viovreg); + FMDERR("%s: regulator_get(vio) failed. retval=%d\n", + __func__, retval); + return retval; + } + + vddvreg = regulator_get(&client->dev, "vdd"); + if (IS_ERR(vddvreg)) { + retval = PTR_ERR(vddvreg); + FMDERR("%s: regulator_get(vdd) failed. retval=%d\n", + __func__, retval); + regulator_put(viovreg); + return retval; } /* private data allocation and initialization */ radio = kzalloc(sizeof(struct rtc6226_device), GFP_KERNEL); if (!radio) { retval = -ENOMEM; - goto err_initial; + regulator_put(viovreg); + regulator_put(vddvreg); + return retval; } v4l2_dev = &radio->v4l2_dev; retval = v4l2_device_register(&client->dev, v4l2_dev); if (retval < 0) { - pr_err("%s couldn't register v4l2_device\n", __func__); - goto err_radio; + FMDERR("%s couldn't register v4l2_device\n", __func__); + goto err_vreg; } - pr_info("v4l2_device_register successfully\n"); + FMDBG("v4l2_device_register successfully\n"); hdl = &radio->ctrl_handler; - radio->users = 0; + /* initialize the device count */ + atomic_set(&radio->users, 0); radio->client = client; mutex_init(&radio->lock); init_completion(&radio->completion); retval = rtc6226_parse_dt(&client->dev, radio); if (retval) { - pr_err("%s: Parsing DT failed(%d)\n", __func__, retval); - kfree(radio); - return retval; + FMDERR("%s: Parsing DT failed(%d)\n", __func__, retval); + goto err_v4l2; } + radio->vddreg = devm_kzalloc(&client->dev, + sizeof(struct fm_power_vreg_data), + GFP_KERNEL); + if (!radio->vddreg) { + FMDERR("%s: allocating memory for vdd vreg failed\n", + __func__); + retval = -ENOMEM; + goto err_v4l2; + } + + radio->vddreg->reg = vddvreg; + radio->vddreg->name = "vdd"; + radio->vddreg->is_enabled = false; + retval = rtc6226_dt_parse_vreg_info(&client->dev, + radio->vddreg, "rtc6226,vdd-supply-voltage"); + if (retval < 0) { + FMDERR("%s: parsing vdd-supply failed\n", __func__); + goto err_v4l2; + } + + radio->vioreg = devm_kzalloc(&client->dev, + sizeof(struct fm_power_vreg_data), + GFP_KERNEL); + if (!radio->vioreg) { + FMDERR("%s: allocating memory for vio vreg failed\n", + __func__); + retval = -ENOMEM; + goto err_v4l2; + } + radio->vioreg->reg = viovreg; + radio->vioreg->name = "vio"; + radio->vioreg->is_enabled = false; + retval = rtc6226_dt_parse_vreg_info(&client->dev, + radio->vioreg, "rtc6226,vio-supply-voltage"); + if (retval < 0) { + FMDERR("%s: parsing vio-supply failed\n", __func__); + goto err_v4l2; + } /* Initialize pin control*/ retval = rtc6226_pinctrl_init(radio); if (retval) { - pr_err("%s: rtc6226_pinctrl_init returned %d\n", + FMDERR("%s: rtc6226_pinctrl_init returned %d\n", __func__, retval); /* if pinctrl is not supported, -EINVAL is returned*/ if (retval == -EINVAL) retval = 0; } else { - pr_info("%s rtc6226_pinctrl_init success\n", __func__); - } - - if (radio->ext_ldo_gpio > 0) { - retval = gpio_direction_output(radio->ext_ldo_gpio, 1); - if (retval) { - pr_err("%s Unable to set direction(LDO)\n", __func__); - kfree(radio); - return retval; - } + FMDBG("%s rtc6226_pinctrl_init success\n", __func__); } memcpy(&radio->videodev, &rtc6226_viddev_template, @@ -582,7 +821,7 @@ static int rtc6226_i2c_probe(struct i2c_client *client, radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); if (!radio->buffer) { retval = -EIO; - goto err_radio; + goto err; } for (i = 0; i < RTC6226_FM_BUF_MAX; i++) { @@ -592,15 +831,16 @@ static int rtc6226_i2c_probe(struct i2c_client *client, STD_BUF_SIZE, GFP_KERNEL); if (kfifo_alloc_rc != 0) { - pr_err("%s: failed allocating buffers %d\n", + FMDERR("%s: failed allocating buffers %d\n", __func__, kfifo_alloc_rc); retval = -ENOMEM; - goto err; + goto err_rds; } } radio->wqueue = NULL; radio->wqueue_scan = NULL; radio->wqueue_rds = NULL; + radio->band = -1; /* rds buffer configuration */ radio->wr_index = 0; @@ -612,19 +852,19 @@ static int rtc6226_i2c_probe(struct i2c_client *client, radio->wqueue = create_singlethread_workqueue("fmradio"); if (!radio->wqueue) { retval = -ENOMEM; - goto err_wqueue; + goto err_rds; } radio->wqueue_scan = create_singlethread_workqueue("fmradioscan"); if (!radio->wqueue_scan) { retval = -ENOMEM; - goto err_wqueue_scan; + goto err_wqueue; } radio->wqueue_rds = create_singlethread_workqueue("fmradiords"); if (!radio->wqueue_rds) { retval = -ENOMEM; - goto err_all; + goto err_wqueue_scan; } /* register video device */ @@ -632,27 +872,39 @@ static int rtc6226_i2c_probe(struct i2c_client *client, radio_nr); if (retval) { dev_info(&client->dev, "Could not register video device\n"); - goto err_rds; + goto err_all; } i2c_set_clientdata(client, radio); /* move from below */ - pr_info("%s exit\n", __func__); + FMDBG("%s exit\n", __func__); return 0; err_all: destroy_workqueue(radio->wqueue_rds); err_wqueue_scan: destroy_workqueue(radio->wqueue_scan); -err_rds: - kfree(radio->buffer); err_wqueue: destroy_workqueue(radio->wqueue); +err_rds: + kfree(radio->buffer); err: video_device_release(&radio->videodev); +err_v4l2: v4l2_device_unregister(v4l2_dev); -err_radio: +err_vreg: + if (radio && radio->vioreg && radio->vioreg->reg) { + regulator_put(radio->vioreg->reg); + devm_kfree(&client->dev, radio->vioreg); + } else { + regulator_put(viovreg); + } + if (radio && radio->vddreg && radio->vddreg->reg) { + regulator_put(radio->vddreg->reg); + devm_kfree(&client->dev, radio->vddreg); + } else { + regulator_put(vddvreg); + } kfree(radio); -err_initial: return retval; } @@ -670,7 +922,7 @@ static int rtc6226_i2c_remove(struct i2c_client *client) video_unregister_device(&radio->videodev); v4l2_device_unregister(&radio->v4l2_dev); kfree(radio); - pr_info("%s exit\n", __func__); + FMDBG("%s exit\n", __func__); return 0; } @@ -684,7 +936,7 @@ static int rtc6226_i2c_suspend(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct rtc6226_device *radio = i2c_get_clientdata(client); - pr_info("%s %d\n", __func__, radio->client->addr); + FMDBG("%s %d\n", __func__, radio->client->addr); return 0; } @@ -698,7 +950,7 @@ static int rtc6226_i2c_resume(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct rtc6226_device *radio = i2c_get_clientdata(client); - pr_info("%s %d\n", __func__, radio->client->addr); + FMDBG("%s %d\n", __func__, radio->client->addr); return 0; } @@ -730,7 +982,7 @@ struct i2c_driver rtc6226_i2c_driver = { */ int rtc6226_i2c_init(void) { - pr_info(DRIVER_DESC ", Version " DRIVER_VERSION "\n"); + FMDBG(DRIVER_DESC ", Version " DRIVER_VERSION "\n"); return i2c_add_driver(&rtc6226_i2c_driver); } diff --git a/drivers/media/radio/rtc6226/radio-rtc6226.h b/drivers/media/radio/rtc6226/radio-rtc6226.h index b3243fe3aa6d..6b1abd30dbc2 100644 --- a/drivers/media/radio/rtc6226/radio-rtc6226.h +++ b/drivers/media/radio/rtc6226/radio-rtc6226.h @@ -51,6 +51,13 @@ #define RW_Kernel_ENG +#define DEBUG +#undef FMDBG +#define FMDBG(fmt, args...) pr_debug("rtc6226: " fmt, ##args) + +#undef FMDERR +#define FMDERR(fmt, args...) pr_err("rtc6226: " fmt, ##args) + /* driver definitions */ #define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 1) #define DRIVER_CARD "Richwave rtc6226 FM Tuner" @@ -182,7 +189,7 @@ #define WRAP_ENABLE 1 #define WRAP_DISABLE 0 - +#define DEFAULT_RSSI_TH 8 /* Standard buffer size */ #define STD_BUF_SIZE 256 @@ -191,6 +198,8 @@ #define TUNE_PENDING 1 #define SEEK_PENDING 2 #define SCAN_PENDING 3 +#define START_SCAN 1 +#define WAIT_TIMEOUT_MSEC 7000 #define RTC6226_MIN_SRCH_MODE 0x00 #define RTC6226_MAX_SRCH_MODE 0x02 @@ -302,6 +311,8 @@ #define GET_AF_LIST_LEN(x) (x*4) #define MIN_AF_FREQ_CODE 1 #define MAX_AF_FREQ_CODE 204 +#define MIN_RSSI 0 +#define MAX_RSSI 15 /* 25 AFs supported for a freq. 224 means 1 AF. 225 means 2 AFs and so on */ #define NO_AF_CNT_CODE 224 @@ -314,6 +325,8 @@ #define CH_SPACING_200 200 #define CH_SPACING_100 100 #define CH_SPACING_50 50 +#define TURNING_ON 1 +#define TURNING_OFF 0 #define RW_PRIBASE (V4L2_CID_USER_BASE | 0xf000) @@ -349,12 +362,11 @@ #define V4L2_CID_PRIVATE_RDS_SYNC (RW_PRIBASE + (CHIPID<<4) + 5) #define V4L2_CID_PRIVATE_SI (RW_PRIBASE + (CHIPID<<4) + 6) -#define WAIT_OVER 0 -#define SEEK_WAITING 1 #define NO_WAIT 2 -#define TUNE_WAITING 4 #define RDS_WAITING 5 #define SEEK_CANCEL 6 +#define TUNE_PARAM 16 + /************************************************************************** * General Driver Definitions **************************************************************************/ @@ -438,6 +450,18 @@ struct rtc6226_af_info { u32 af_list[MAX_NO_OF_AF]; }; +struct fm_power_vreg_data { + /* voltage regulator handle */ + struct regulator *reg; + /* regulator name */ + const char *name; + /* voltage levels to be set */ + unsigned int low_vol_level; + unsigned int high_vol_level; + /* is this regulator enabled? */ + bool is_enabled; +}; + /* * rtc6226_device - private data */ @@ -453,9 +477,11 @@ struct rtc6226_device { struct pinctrl_state *gpio_state_active; struct pinctrl_state *gpio_state_suspend; struct v4l2_ctrl_handler ctrl_handler; + struct fm_power_vreg_data *vddreg; + struct fm_power_vreg_data *vioreg; int band; int space; - unsigned int users; + atomic_t users; unsigned int mode; u8 seek_tune_status; u8 rssi_th; @@ -666,3 +692,5 @@ void rtc6226_scan(struct work_struct *work); void rtc6226_search(struct rtc6226_device *radio, bool on); int rtc6226_cancel_seek(struct rtc6226_device *radio); void rtc6226_rds_handler(struct work_struct *worker); +void rtc6226_q_event(struct rtc6226_device *radio, enum rtc6226_evt_t event); +int rtc6226_reset_rds_data(struct rtc6226_device *radio);