2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
6 * You should have received a copy of the GNU General Public License
7 * along with this program; if not, write to the Free Software
8 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * Copyright (C) 2009-2014 Broadcom Corporation
19 /*******************************************************************************
21 * Filename: fmdrv_rx.c
23 * Description: This sub-module of FM driver implements FM RX functionality.
25 ***********************************************************************************/
28 #include "fmdrv_main.h"
30 #include "fmdrv_config.h"
31 #include <linux/fm_public.h>
33 /*******************************************************************************
35 *******************************************************************************/
40 #define pr_info(fmt, arg...)
44 const unsigned short fm_sch_step_size[] = /* darrel issue_06 : 50Khz scan step add. */
51 /************************************************************************************
53 ************************************************************************************/
54 /************************************************************************************
56 *******************************************************************************/
58 /* Configures Alternate Frequency switch mode */
59 int fm_rx_set_af_switch(struct fmdrv_ops *fmdev, u8 af_mode)
64 if (fmdev->curr_fmmode != FM_MODE_RX)
67 if (af_mode != FM_RX_RDS_AF_SWITCH_MODE_ON &&
68 af_mode != FM_RX_RDS_AF_SWITCH_MODE_OFF) {
69 pr_err("(fmdrv) %s(): Invalid af mode 0x%x\n", __func__, af_mode);
72 /* Enable/disable low RSSI interrupt based on af_mode */
73 if (af_mode == FM_RX_RDS_AF_SWITCH_MODE_ON)
74 fmdev->rx.fm_rds_mask |= I2C_MASK_RSSI_LOW_BIT;
76 fmdev->rx.fm_rds_mask &= ~I2C_MASK_RSSI_LOW_BIT;
78 payload = fmdev->rx.fm_rds_mask;
80 ret = fmc_send_cmd(fmdev, FM_REG_FM_RDS_MSK, &fmdev->rx.fm_rds_mask,
81 2, REG_WR,&fmdev->maintask_completion, NULL, NULL);
86 fmdev->rx.af_mode = af_mode;
93 * Sets the signal strength level that once reached
94 * will stop the auto search process
96 int fm_rx_set_rssi_threshold(struct fmdrv_ops *fmdev, short rssi_lvl_toset)
98 pr_info("(fmdrv) %s(): fm_rx_set_rssi_threshold to set is %d\n",
99 __func__,rssi_lvl_toset);
101 if (rssi_lvl_toset < FM_RX_RSSI_THRESHOLD_MIN ||
102 rssi_lvl_toset > FM_RX_RSSI_THRESHOLD_MAX) {
103 pr_err("(fmdrv) %s(): Invalid RSSI threshold level\n",
108 fmdev->rx.curr_rssi_threshold = rssi_lvl_toset;
115 * Sets the signal strength level that once reached
116 * will stop the auto search process
118 int fm_rx_set_snr_threshold(struct fmdrv_ops *fmdev, short snr_lvl_toset)
123 if (snr_lvl_toset < FM_RX_SNR_THRESHOLD_MIN ||
124 snr_lvl_toset > FM_RX_SNR_THRESHOLD_MAX) {
125 pr_err("(fmdrv) %s(): Invalid SNR threshold level, %d\n",
126 __func__, snr_lvl_toset);
129 payload = (u16) snr_lvl_toset;
130 ret = fmc_send_cmd(fmdev, FM_SEARCH_SNR, &payload, sizeof(payload),
131 REG_WR, &fmdev->maintask_completion, NULL,NULL);
136 fmdev->rx.curr_snr_threshold= snr_lvl_toset;
142 * Sets the Carrier Offset Slop
144 int fm_rx_set_cos_threshold(struct fmdrv_ops *fmdev, short cos_toset)
149 if (cos_toset < FM_RX_COS_MIN||
150 cos_toset > FM_RX_COS_MAX) {
151 pr_err("(fmdrv) %s(): Invalid COS threshold value, %d\n",
152 __func__, cos_toset);
155 payload = (u16) cos_toset;
156 ret = fmc_send_cmd(fmdev, FM_RES_PRESCAN_QUALITY, &payload, sizeof(payload),
157 REG_WR, &fmdev->maintask_completion, NULL,NULL);
162 fmdev->rx.curr_cos_threshold= cos_toset;
169 * Function to validate if the tuned/scanned frequency is valid
172 int check_if_valid_freq(struct fmdrv_ops *fmdev, unsigned short frequency)
174 /* darrel issue_01 : 87.50 Mhz, 87.55 Mhz , 107.95 Mhz, 108.00Mhz is valid frequency */
175 if(frequency < fmdev->rx.region.low_bound ||
176 frequency > fmdev->rx.region.high_bound)
178 pr_info("(fmdrv) %s(): %d - Literally out of range",
179 __func__, FM_SET_FREQ(frequency));
184 pr_info("(fmdrv) %s(): %d - Freq in range",
185 __func__, FM_SET_FREQ(frequency));
191 * Function to read the FM_RDS_FLAG registry
193 int read_fm_rds_flag(struct fmdrv_ops *fmdev, unsigned short *value)
195 unsigned char read_length;
198 unsigned char resp_buf [2];
200 read_length = FM_READ_2_BYTE_DATA;
201 ret = fmc_send_cmd(fmdev, FM_REG_FM_RDS_FLAG, &read_length, sizeof(read_length), REG_RD,
202 &fmdev->maintask_completion, &resp_buf, &resp_len);
203 *value = (unsigned short)resp_buf[0] +
204 ((unsigned short)resp_buf[1] << 8);
205 pr_info("(fmdrv) %s: FM Mask : 0x%x ", __func__, *value);
210 * Function to read the FM_RDS_FLAG registry
212 int fm_rx_set_mask(struct fmdrv_ops *fmdev, unsigned short mask)
217 fmdev->rx.fm_rds_flag|= FM_RDS_FLAG_CLEAN_BIT; /* clean FM_RDS_FLAG */
218 ret = read_fm_rds_flag(fmdev, &flag);
219 FM_CHECK_SEND_CMD_STATUS(ret);
221 ret = fmc_send_cmd(fmdev, FM_REG_FM_RDS_MSK, &mask, sizeof(mask), REG_WR,
222 &fmdev->maintask_completion, NULL, NULL);
223 FM_CHECK_SEND_CMD_STATUS(ret);
228 * Helper Function to initialize and start a search operation
229 * (SEEK or TUNE). This method is internally called by fm_rx_set_frequency()
230 * and fm_rx_seek_station().
232 int init_start_search(struct fmdrv_ops *fmdev, unsigned short start_freq, unsigned char mode)
234 unsigned char payload;
235 unsigned short tmp_fm_rds_mask;
238 if(mode == FM_TUNER_SEEK_MODE)
241 payload = FM_TUNER_NORMAL_SCAN_MODE;
242 ret = fmc_send_cmd(fmdev, FM_SEARCH_METHOD, &payload, 1, REG_WR,
243 &fmdev->maintask_completion, NULL, NULL);
244 FM_CHECK_SEND_CMD_STATUS(ret);
246 pr_info("(fmdev) %s(): FM_SEARCH_METHOD set to 0x%x\n", __func__, payload);
249 /* Set Preset stations number to 0 */
251 ret = fmc_send_cmd(fmdev, FM_REG_PRESET_MAX, &payload, 1, REG_WR,
252 &fmdev->maintask_completion, NULL, NULL);
253 FM_CHECK_SEND_CMD_STATUS(ret);
255 pr_info("(fmdev) %s(): FM_REG_PRESET_MAX set to 0x%x\n", __func__, payload);
258 /* Set FM Search control params to controller */
259 payload = fmdev->rx.curr_rssi_threshold | (fmdev->rx.curr_sch_mode & FM_SCAN_DIRECT_MASK);
260 ret = fmc_send_cmd(fmdev, FM_REG_SCH_CTL0, &payload, 1, REG_WR,
261 &fmdev->maintask_completion, NULL, NULL);
262 FM_CHECK_SEND_CMD_STATUS(ret);
264 pr_info("(fmdev) %s(): FM_REG_SCH_CTL0 set to 0x%x\n", __func__, payload);
268 /* freeze interrupt event before SCH_TUNE is commanded */
269 fmdev->rx.fm_rds_flag |= FM_RDS_FLAG_SCH_FRZ_BIT;
270 /* set sch_tune pending bit */
271 fmdev->rx.fm_rds_flag |= FM_RDS_FLAG_SCH_BIT;
273 /* Write Frequency */
274 /* Write FM_REG_FM_FREQ (0x0a) register first */
275 ret = fmc_send_cmd(fmdev, FM_REG_FM_FREQ, &start_freq,
276 sizeof(start_freq), REG_WR, &fmdev->maintask_completion, NULL, NULL);
277 FM_CHECK_SEND_CMD_STATUS(ret);
279 pr_info("(fmdev) %s(): FM_REG_FM_FREQ set to 0x%x\n", __func__, FM_SET_FREQ(start_freq));
282 /* Set the mask flag to Register FM_REG_FM_RDS_MSK(0x10)
283 & FM_REG_FM_RDS_MSK1(0x11) */
284 tmp_fm_rds_mask= I2C_MASK_SRH_TUNE_CMPL_BIT | I2C_MASK_SRH_TUNE_FAIL_BIT;
285 ret = fm_rx_set_mask(fmdev, tmp_fm_rds_mask);
286 FM_CHECK_SEND_CMD_STATUS(ret);
288 /* Reset the fm_rds_flag here as for the first time we dont get
289 any interrupt during ENABLE to cleanup the bit */
290 fmdev->rx.fm_rds_flag &= ~FM_RDS_FLAG_CLEAN_BIT;
292 /* Write FM_REG_SCH_TUNE (0x09) register */
293 /*payload = FM_TUNER_SEEK_MODE;*/ /* Scan parameter (0x02) */
295 ret = fmc_send_cmd(fmdev, FM_REG_SCH_TUNE, &payload, sizeof(payload),
296 REG_WR, &fmdev->maintask_completion, NULL, NULL);
297 FM_CHECK_SEND_CMD_STATUS(ret);
298 fmdev->rx.curr_search_state = (mode == FM_TUNER_SEEK_MODE)?FM_STATE_SEEKING:FM_STATE_TUNING;
300 fmc_reset_rds_cache(fmdev);
306 * Function to process a SEEK complete event. This function determines
307 * whether to wrap the search, or stop the search or return error
308 * to user-space. This is called internally by fm_rx_seek_station() function.
310 int process_seek_event(struct fmdrv_ops *fmdev)
312 unsigned short tmp_freq, start_freq;
316 tmp_freq = fmdev->rx.curr_freq;
317 is_valid_freq = check_if_valid_freq(fmdev, tmp_freq);
319 /* darrel issue_01 : to check boundary frequency */
320 if(((FM_SET_FREQ(tmp_freq) - 5) <= FM_SET_FREQ(fmdev->rx.region.low_bound)) ||
321 ((FM_SET_FREQ(tmp_freq) + 5) >= FM_SET_FREQ(fmdev->rx.region.high_bound)))
323 is_valid_freq = FALSE;
327 pr_info("(fmdrv) %s(): tmp:%d low:%d high:%d\n", __func__,
328 tmp_freq, fmdev->rx.region.low_bound, fmdev->rx.region.high_bound);
330 /* First check if Scan suceeded or not */
331 if(fmdev->rx.curr_search_state == FM_STATE_SEEK_ERR)
333 fmdev->rx.fm_rds_flag &= ~FM_RDS_FLAG_SCH_FRZ_BIT;
334 if(!fmdev->rx.seek_wrap && !is_valid_freq)
336 fmdev->rx.curr_search_state = FM_STATE_SEEK_ERR;
337 pr_err("(fmdrv) %s(): Seek ended with out of bound frequency %d.\n",
338 __func__, FM_SET_FREQ(tmp_freq));
341 else if(fmdev->rx.seek_wrap && !is_valid_freq)
343 pr_err("(fmdrv) %s(): Scan ended with out of bound frequency. Wrapping search again..\n",
346 start_freq = (fmdev->rx.seek_direction==FM_SCAN_DOWN)?
347 (fmdev->rx.region.high_bound):(fmdev->rx.region.low_bound);
348 pr_info("(fmdev) %s(): Current scanned frequency is out of bounds. Resetting to freq (%d)\n",
349 __func__, FM_SET_FREQ(start_freq));
351 ret = init_start_search(fmdev, start_freq, FM_TUNER_SEEK_MODE);
354 fmdev->rx.curr_search_state = FM_STATE_SEEK_ERR;
355 fmdev->rx.curr_freq = 0;
356 pr_err ("(fmdrv) %s(): Error starting search for Seek operation\n", __func__);
360 fmdev->rx.curr_search_state = FM_STATE_SEEKING;
361 pr_info ("(fmdrv) %s(): Started wrapped-up Seek operation\n",
367 fmdev->rx.curr_search_state = FM_STATE_SEEK_ERR;
368 pr_err("(fmdrv) %s(): *** ERROR :: Seek failed for %d frequency ***\n",
369 __func__, FM_SET_FREQ(tmp_freq));
375 pr_info("(fmdrv) %s(): Seek success!\n", __func__);
376 fmdev->rx.curr_search_state = FM_STATE_SEEK_CMPL;
381 /************************************************************************************
382 ** Main functions - Called by fmdrv_main and fmdrv_v4l2.
383 ************************************************************************************/
386 * Function to read current RSSI and tuned frequency
388 int fm_rx_read_curr_rssi_freq(struct fmdrv_ops *fmdev, unsigned char rssi_only)
390 int ret = 0, resp_len;
391 unsigned char payload;
392 unsigned short tmp_frq;
393 unsigned char resp_buf[2];
395 /* Read current RSSI */
396 payload = FM_READ_1_BYTE_DATA;
397 ret = fmc_send_cmd(fmdev, FM_REG_RSSI, &payload, 1,
398 REG_RD, &fmdev->maintask_completion, &resp_buf[0], &resp_len);
399 FM_CHECK_SEND_CMD_STATUS(ret);
400 /* Calculating 2's compliment number into an absolute value number */
401 fmdev->rx.curr_rssi = (unsigned char) ((0x80 - resp_buf[0]) & (~0x80));
402 pr_info("(fmdev) %s(): FM_REG_RSSI : %d\n", __func__, fmdev->rx.curr_rssi);
407 /* Read current frequency */
408 payload = FM_READ_2_BYTE_DATA;
410 ret = fmc_send_cmd(fmdev, FM_REG_FM_FREQ, &payload, 1,
411 REG_RD, &fmdev->maintask_completion, &tmp_frq, &resp_len);
412 FM_CHECK_SEND_CMD_STATUS(ret);
413 pr_info("(fmdev) %s(): FM_REG_FM_FREQ : %d\n", __func__, FM_SET_FREQ(tmp_frq));
415 fmdev->rx.curr_freq = tmp_frq;
421 * Function for FM TUNE frequency implementation
422 * * Set the other registries such as Search method, search
424 * * Start preset search.
425 * * Based on interrupt received, read the current tuned freq
426 * and validate the search.
427 * * If search frequency out of bound, return error code -EAGAIN
428 * * If not, read RSSI, reset RDS cache and set RDS MASK to the earlier value.
430 int fm_rx_set_frequency(struct fmdrv_ops *fmdev, unsigned int freq_to_set)
432 unsigned short tmp_frq;
434 unsigned long timeleft;
436 if (fmdev->curr_fmmode != FM_MODE_RX)
438 tmp_frq = FM_GET_FREQ(freq_to_set);
439 if(!check_if_valid_freq(fmdev, tmp_frq))
441 pr_err("(fmdrv): %s(): called with %d - out of bound range (%d-%d)\n",
442 __func__, freq_to_set, FM_SET_FREQ(fmdev->rx.region.low_bound),
443 FM_SET_FREQ(fmdev->rx.region.high_bound));
447 ret = init_start_search(fmdev, tmp_frq, FM_TUNER_PRESET_MODE);
450 pr_err ("(fmdrv) %s(): Error starting search for Seek operation\n",
455 /* Wait for tune ended interrupt */
456 init_completion(&fmdev->maintask_completion);
457 timeleft = wait_for_completion_timeout(&fmdev->maintask_completion,
461 pr_err("(fmdrv) %s(): Timeout(%d sec), didn't get tune ended interrupt\n",
462 __func__, jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000);
463 fmdev->rx.fm_rds_flag &= ~FM_RDS_FLAG_SCH_FRZ_BIT;
468 pr_info("(fmdrv) %s(): Seek %u ms\n", __func__,
469 jiffies_to_msecs(FM_DRV_TX_TIMEOUT - timeleft));
473 /* First check if Tune suceeded or not */
474 if(fmdev->rx.curr_search_state == FM_STATE_TUNE_ERR)
476 pr_err("(fmdrv) %s(): failed for %d MHz frequency\n",
477 __func__, FM_SET_FREQ(tmp_frq));
478 fmdev->rx.fm_rds_flag &= ~FM_RDS_FLAG_SCH_FRZ_BIT;
481 pr_info("(fmdrv) %s(): Set frequency done!\n", __func__);
482 fmdev->rx.fm_rds_flag &= ~FM_RDS_FLAG_SCH_FRZ_BIT;
484 fm_rx_read_curr_rssi_freq(fmdev, FALSE);
485 /* Reset RDS Cache */
486 fmc_reset_rds_cache(fmdev);
488 if(fmdev->rx.fm_rds_mask)
490 /* Update the FM_RDS_MASK to set the earlier bits */
491 pr_info("(fmdrv) %s(): Update FM_RDS_MASK : 0x%x\n",
492 __func__, fmdev->rx.fm_rds_mask);
493 ret = fmc_send_cmd(fmdev, FM_REG_FM_RDS_MSK, &fmdev->rx.fm_rds_mask,
494 sizeof(fmdev->rx.fm_rds_mask), REG_WR,
495 &fmdev->maintask_completion, NULL, NULL);
502 * Function to get the current tuned frequency
503 * This function will query controller by reading the FM_REG_FM_FREQ(0x0a)
504 * to determine the current tuned frequency.
506 int fm_rx_get_frequency(struct fmdrv_ops *fmdev, unsigned int *curr_freq)
508 unsigned char payload;
509 unsigned short tmp_frq;
514 ret = fmc_send_cmd(fmdev, FM_REG_FM_FREQ, &payload, 1, REG_RD,
515 &fmdev->maintask_completion, &tmp_frq, &resp_len);
516 FM_CHECK_SEND_CMD_STATUS(ret);
517 pr_info("(fmdev) %s(): FM_REG_FM_FREQ - %d\n", __func__, FM_SET_FREQ(tmp_frq));
519 *curr_freq = FM_SET_FREQ(tmp_frq);
525 * Function to get the current SNR
526 * This function will query controller by reading the FM_REG_SNR(0xdf)
527 * to read current SNR.
529 int fm_rx_get_snr(struct fmdrv_ops *fmdev, unsigned int *curr_snr)
531 unsigned char payload;
537 ret = fmc_send_cmd(fmdev, FM_REG_SNR, &payload, 1, REG_RD,
538 &fmdev->maintask_completion, curr_snr, &resp_len);
539 FM_CHECK_SEND_CMD_STATUS(ret);
540 pr_info("(fmdev) %s(): FM_REG_SNR : %d\n", __func__, *curr_snr);
547 * Function to start a FM SEEK Operation.
548 * * Set the start frequency.
549 * * Set the other registries such as Search method, search
552 * * Based on interrupt received, read the current tuned freq
553 * and validate the search.
554 * * If search frequency out of bound and no wrap_around needed,
555 * end the search and return error code -EINVAL
556 * * If not, start the search again and check for interrupt.
557 * * If no interrupt is received by 20 sec, timeout the seek operation
559 int fm_rx_seek_station(struct fmdrv_ops *fmdev, unsigned char direction_upward,
560 unsigned char wrap_around)
563 unsigned short tmp_freq, start_freq;
564 unsigned long timeleft;
566 fmdev->rx.seek_direction = (direction_upward)?FM_SCAN_UP:FM_SCAN_DOWN;
567 fmdev->rx.curr_sch_mode = ((FM_TUNER_NORMAL_SCAN_MODE & 0x01) |
568 (fmdev->rx.seek_direction & 0x80));
571 fmdev->rx.seek_wrap = wrap_around;
573 pr_info("(fmdrv) %s(): seek_direction:0x%x curr_sch_mode:0x%x seek_wrap:0x%x\n", __func__,
574 fmdev->rx.seek_direction, fmdev->rx.curr_sch_mode, fmdev->rx.seek_wrap);
576 ret = fm_rx_get_frequency(fmdev, &freq);
577 tmp_freq = FM_GET_FREQ(freq);
579 if(!check_if_valid_freq(fmdev, tmp_freq))
581 start_freq = (direction_upward)?(fmdev->rx.region.low_bound+ fm_sch_step_size[fmdev->rx.sch_step]) /* darrel issue_06 */
582 :(fmdev->rx.region.high_bound - fm_sch_step_size[fmdev->rx.sch_step]);
583 pr_info("(fmdev) %s(): Current frequency is out of bounds. Resetting to freq (%d)\n",
584 __func__, FM_SET_FREQ(start_freq));
588 start_freq = (direction_upward)?(tmp_freq + fm_sch_step_size[fmdev->rx.sch_step]) /* darrel issue_06 */
589 :(tmp_freq - fm_sch_step_size[fmdev->rx.sch_step]);
590 if(start_freq >= fmdev->rx.region.high_bound ||
591 start_freq <= fmdev->rx.region.low_bound)
592 start_freq = (direction_upward)?
593 (fmdev->rx.region.low_bound):(fmdev->rx.region.high_bound);
595 pr_info("(fmdrv) %s(): Starting FM seek (%s) from %d..\n",
596 __func__, (direction_upward?"SEEKUP":"SEEKDOWN"), FM_SET_FREQ(start_freq));
600 ret = init_start_search(fmdev, start_freq, FM_TUNER_SEEK_MODE);
603 pr_err ("(fmdrv) %s(): Error starting search for Seek operation\n",
608 /* Wait for tune ended interrupt */
609 init_completion(&fmdev->seektask_completion);
610 timeleft = wait_for_completion_timeout(&fmdev->seektask_completion,
611 FM_DRV_RX_SEEK_TIMEOUT);
614 pr_err("(fmdrv) %s(): Timeout(%d sec),didn't get seek ended interrupt\n",
615 __func__, jiffies_to_msecs(FM_DRV_RX_SEEK_TIMEOUT) / 1000);
616 fmdev->rx.fm_rds_flag &= ~FM_RDS_FLAG_SCH_FRZ_BIT;
620 fm_rx_read_curr_rssi_freq(fmdev, FALSE);
621 tmp_freq = fmdev->rx.curr_freq;
622 ret = process_seek_event(fmdev);
623 if(ret && fmdev->rx.curr_search_state == FM_STATE_SEEK_CMPL)
625 /* Reset RDS Cache */
626 fmc_reset_rds_cache(fmdev);
627 if(fmdev->rx.fm_rds_mask)
628 /* Update the FM_RDS_MASK to set the earlier bits */
629 ret = fmc_send_cmd(fmdev, FM_REG_FM_RDS_MSK, &fmdev->rx.fm_rds_mask,
630 sizeof(fmdev->rx.fm_rds_mask), REG_WR,
631 &fmdev->maintask_completion, NULL, NULL);
636 pr_err("(fmdrv) %s(): Error during Seek. Try again!\n", __func__);
639 else if(ret && fmdev->rx.curr_search_state == FM_STATE_SEEKING)
642 /* Wait for tune ended interrupt */
643 init_completion(&fmdev->seektask_completion);
644 timeleft = wait_for_completion_timeout(&fmdev->seektask_completion,
645 FM_DRV_RX_SEEK_TIMEOUT);
647 fmdev->rx.fm_rds_flag &= ~FM_RDS_FLAG_SCH_FRZ_BIT;
650 pr_err("(fmdrv) %s(): Timeout(%d sec),didn't get Seek ended interrupt\n",
651 __func__, jiffies_to_msecs(FM_DRV_RX_SEEK_TIMEOUT) / 1000);
655 fm_rx_read_curr_rssi_freq(fmdev, FALSE);
657 /* First check if Scan suceeded or not */
658 if(fmdev->rx.curr_search_state == FM_STATE_SEEK_ERR)
660 pr_err("(fmdrv) %s(): Wrap Seek failed for %d frequency\n",
661 __func__, FM_SET_FREQ(fmdev->rx.curr_freq));
664 pr_info("(fmdrv) %s(): Wrap Seek done!\n", __func__);
665 /* Reset RDS Cache */
666 fmc_reset_rds_cache(fmdev);
667 /* Update the FM_RDS_MASK to set the earlier bits */
668 ret = fmc_send_cmd(fmdev, FM_REG_FM_RDS_MSK, &fmdev->rx.fm_rds_mask,
669 sizeof(fmdev->rx.fm_rds_mask), REG_WR,
670 &fmdev->maintask_completion, NULL, NULL);
674 pr_err("(fmdrv) %s(): Unhandled case in Seek\n", __func__);
679 * Function to Abort on-going scanning operation.
681 int fm_rx_seek_station_abort(struct fmdrv_ops *fmdev)
683 unsigned char payload;
686 payload = FM_TUNER_NORMAL_SCAN_MODE;
688 ret = fmc_send_cmd(fmdev, FM_REG_SCH_TUNE, &payload, sizeof(payload),
689 REG_WR, &fmdev->maintask_completion, NULL, NULL);
691 pr_info("(fmdrv) %s(): ret %d\n", __func__, ret);
701 *Function to set band's high and low frequencies
703 int fm_rx_set_band_frequencies(struct fmdrv_ops *fmdev, unsigned int low_freq,
704 unsigned int high_freq)
706 if((fmdev->rx.region.high_bound == FM_GET_FREQ(high_freq)) &&
707 (fmdev->rx.region.low_bound = FM_GET_FREQ(low_freq)))
709 pr_err("(fmdrv) %s(): Ignoring setting the same band frequencies\n",
713 fmdev->rx.region.high_bound = FM_GET_FREQ(high_freq);
714 fmdev->rx.region.low_bound = FM_GET_FREQ(low_freq);
719 *Function to get the current band's high and low frequencies
721 int fm_rx_get_band_frequencies(struct fmdrv_ops *fmdev, unsigned int *low_freq,
722 unsigned int *high_freq)
724 *high_freq= FM_SET_FREQ(fmdev->rx.region.high_bound);
725 *low_freq= FM_SET_FREQ(fmdev->rx.region.low_bound) ;
730 * Function to set the volume
732 int fm_rx_set_volume(struct fmdrv_ops *fmdev, unsigned short vol_to_set)
735 /* darrel issue_04 : FM_REG_VOLUME_CTRL use UINT16 (0 - 256) */
736 /*payload type changed unsigned char=> unsigned short*/
737 /* unsigned char payload; */
738 unsigned short payload;
741 unsigned char read_length;
742 unsigned short actual_volume;
744 if(vol_to_set > FM_RX_VOLUME_MAX)
745 actual_volume = (vol_to_set/FM_RX_VOLUME_RATIO);
747 actual_volume = vol_to_set;
748 pr_info("(fmdrv) %s() Actual volume to set : %d\n",
749 __func__,actual_volume);
751 if (fmdev->curr_fmmode != FM_MODE_RX)
754 if (actual_volume > FM_RX_VOLUME_MAX)
756 pr_err("(fmdrv) %s(): Volume %d is not within(%d-%d) range\n",
757 __func__, vol_to_set, FM_RX_VOLUME_MIN, FM_RX_VOLUME_MAX);
758 actual_volume = 0xFF;
761 payload = actual_volume & 0x1ff;
762 ret = fmc_send_cmd(fmdev, FM_REG_VOLUME_CTRL, &payload, sizeof(payload),
763 REG_WR, &fmdev->maintask_completion, NULL, NULL);
764 FM_CHECK_SEND_CMD_STATUS(ret);
766 fmdev->rx.curr_volume = vol_to_set;
767 /* Read current volume */
768 read_length = FM_READ_1_BYTE_DATA;
769 ret = fm_rx_get_volume(fmdev, &(fmdev->rx.curr_volume));
770 pr_info("(fmdrv) %s(): Volume read : %d\n", __func__, fmdev->rx.curr_volume);
771 if(ret == -ETIMEDOUT)
777 *Function to Get volume
779 int fm_rx_get_volume(struct fmdrv_ops *fmdev, unsigned short *curr_vol)
783 /* darrel issue_04 : FM_REG_VOLUME_CTRL use UINT16 (0 - 256) */
784 //unsigned char resp_buf[2];
785 unsigned short resp_buf;
787 unsigned char read_length;
789 if (fmdev->curr_fmmode != FM_MODE_RX)
792 if (curr_vol == NULL)
794 pr_err("(fmdrv) %s(): Invalid memory\n", __func__);
798 /* Read current volume */
799 read_length = FM_READ_2_BYTE_DATA;
800 ret = fmc_send_cmd(fmdev, FM_REG_VOLUME_CTRL, &read_length, 1, REG_RD,
801 &fmdev->maintask_completion, &resp_buf, &resp_len);
802 FM_CHECK_SEND_CMD_STATUS(ret);
803 pr_info("(fmdrv) %s(): fm_rx_get_volume ret : %d\n", __func__, ret);
805 *curr_vol = fmdev->rx.curr_volume = resp_buf;
806 pr_info("(fmdrv) %s(): Volume read : 0x%x\n",
807 __func__, fmdev->rx.curr_volume);
811 /* Sets band (0-US; 1-Europe; 2-Japan) */
812 int fm_rx_set_region(struct fmdrv_ops *fmdev,
813 unsigned char region_to_set)
815 unsigned char payload = FM_STEREO_AUTO|FM_BAND_REG_WEST;
819 if (fmdev->curr_fmmode != FM_MODE_RX)
822 if (region_to_set != FM_REGION_NA &&
823 region_to_set != FM_REGION_EUR &&
824 region_to_set != FM_REGION_JP)
826 pr_err("(fmdrv) %s(): Invalid band\n", __func__);
830 if (region_to_set == FM_REGION_JP)/* set japan region */
832 payload |= FM_BAND_REG_EAST;
835 /* Send cmd to set the band */
836 ret = fmc_send_cmd(fmdev, FM_REG_FM_CTRL, &payload, sizeof(payload), REG_WR,
837 &fmdev->maintask_completion, NULL, NULL);
838 FM_CHECK_SEND_CMD_STATUS(ret);
840 fmc_update_region_info(fmdev, region_to_set);
846 * Function to retrieve audio control param
849 int fm_rx_get_audio_ctrl(struct fmdrv_ops *fmdev, uint16_t *audio_ctrl)
851 uint16_t payload = FM_READ_2_BYTE_DATA;
852 int ret = -EINVAL, resp_len;
854 if (fmdev->curr_fmmode != FM_MODE_RX)
857 /* Send cmd to set the band */
858 ret = fmc_send_cmd(fmdev, FM_REG_AUD_CTL0, &payload, sizeof(payload), REG_RD,
859 &fmdev->maintask_completion, audio_ctrl, &resp_len);
860 FM_CHECK_SEND_CMD_STATUS(ret);
861 fmdev->aud_ctrl = fmdev->rx.aud_ctrl = *audio_ctrl;
862 if(ret == -ETIMEDOUT)
868 * Function to set the audio control param
871 int fm_rx_set_audio_ctrl(struct fmdrv_ops *fmdev,uint16_t audio_ctrl)
873 uint16_t payload = audio_ctrl;
876 if (fmdev->curr_fmmode != FM_MODE_RX)
879 /* Send cmd to set the band */
880 ret = fmc_send_cmd(fmdev, FM_REG_AUD_CTL0, &payload, sizeof(payload), REG_WR,
881 &fmdev->maintask_completion, NULL, NULL);
882 FM_CHECK_SEND_CMD_STATUS(ret);
883 fmdev->aud_ctrl = fmdev->rx.aud_ctrl = audio_ctrl;
884 if(ret == -ETIMEDOUT)
890 * Function to Read current mute mode (Mute Off/On)
892 int fm_rx_get_mute_mode(struct fmdrv_ops *fmdev,
893 unsigned char *curr_mute_mode)
897 if (fmdev->curr_fmmode != FM_MODE_RX)
900 if (curr_mute_mode == NULL) {
901 pr_err("(fmdrv) %s(): Invalid memory\n", __func__);
904 ret = fm_rx_get_audio_ctrl(fmdev, &tmp);
905 *curr_mute_mode = fmdev->rx.curr_mute_mode = tmp & FM_MANUAL_MUTE;
906 pr_info("(fmdrv) %s(): Mute is %s\n", __func__, ((*curr_mute_mode)?"ON":"OFF"));
911 * Configures mute mode (Mute Off/On)
913 int fm_rx_set_mute_mode(struct fmdrv_ops *fmdev,
914 unsigned char mute_mode_toset)
919 if (fmdev->curr_fmmode != FM_MODE_RX)
921 /* First read the aud_ctrl*/
922 ret = fm_rx_get_audio_ctrl(fmdev, &aud_ctrl);
926 aud_ctrl|= FM_MANUAL_MUTE;
930 aud_ctrl &= (~FM_MANUAL_MUTE);
932 ret = fm_rx_set_audio_ctrl (fmdev, aud_ctrl);
933 FM_CHECK_SEND_CMD_STATUS(ret);
936 pr_info("(fmdrv) %s(): Current mute state : %d\n", __func__, mute_mode_toset);
937 fmdev->rx.curr_mute_mode = mute_mode_toset;
941 /* Sets RX stereo/mono modes */
942 int fm_rx_set_audio_mode(struct fmdrv_ops *fmdev, unsigned char mode)
944 unsigned char audio_ctrl = FM_STEREO_SWITCH|FM_STEREO_AUTO;
947 if (fmdev->curr_fmmode != FM_MODE_RX)
950 if (mode != FM_STEREO_MODE && mode != FM_MONO_MODE &&
951 mode != FM_AUTO_MODE && mode != FM_SWITCH_MODE)
953 pr_err("(fmdrv) %s(): Invalid mode :%d\n", __func__, mode);
957 if (fmdev->rx.audio_mode == mode)
959 pr_info ("(fmdrv) %s(): no change in audio mode\n", __func__);
964 case FM_SWITCH_MODE: /* stereo witch in auto mode */
967 case FM_MONO_MODE: /* manually set to mono, bit2 OFF is mono */
968 audio_ctrl &= ~FM_STEREO_AUTO;/* set to manual mono */
970 case FM_STEREO_MODE: /* manually set to stereo */
971 audio_ctrl &= ~FM_STEREO_AUTO; /* set to manual */
972 audio_ctrl |= FM_STEREO_MANUAL; /* set to stereo in manual mode */
974 case FM_AUTO_MODE:/* auto blend as default, */
975 audio_ctrl &= ~FM_STEREO_SWITCH; /* turn OFF bit3 to activate blend */
980 /* set the region bit */
981 audio_ctrl |= (fmdev->rx.curr_region == FM_REGION_JP) ? \
982 FM_BAND_REG_EAST : FM_BAND_REG_WEST;
984 /* Set stereo/mono mode */
985 ret = fmc_send_cmd(fmdev, FM_REG_FM_CTRL, &audio_ctrl, sizeof(audio_ctrl),
986 REG_WR, &fmdev->maintask_completion, NULL, NULL);
987 FM_CHECK_SEND_CMD_STATUS(ret);
988 fmdev->rx.audio_mode = mode;
989 if(mode == FM_MONO_MODE)
991 fmdev->device_info.rxsubchans |= V4L2_TUNER_SUB_MONO;
992 fmdev->device_info.rxsubchans &= ~V4L2_TUNER_SUB_STEREO;
994 if(mode == FM_STEREO_MODE)
996 fmdev->device_info.rxsubchans |= V4L2_TUNER_SUB_STEREO;
997 fmdev->device_info.rxsubchans &= ~V4L2_TUNER_SUB_MONO;
1002 /* Gets current RX stereo/mono mode */
1003 int fm_rx_get_audio_mode(struct fmdrv_ops *fmdev, unsigned char *mode)
1006 unsigned char payload = FM_READ_1_BYTE_DATA, resp;
1007 if (fmdev->curr_fmmode != FM_MODE_RX)
1012 pr_err("(fmdrv) %s(): Invalid memory\n", __func__);
1015 ret = fmc_send_cmd(fmdev, FM_REG_FM_CTRL, &payload, sizeof(payload),
1016 REG_RD, &fmdev->maintask_completion, &resp, &len);
1017 if((resp & FM_STEREO_SWITCH) && (resp & FM_STEREO_AUTO))
1018 *mode = FM_SWITCH_MODE;
1019 else if(!(resp & FM_STEREO_AUTO))
1020 *mode = FM_MONO_MODE;
1021 else if(!(resp & FM_STEREO_AUTO) && (resp & FM_STEREO_MANUAL))
1022 *mode = FM_STEREO_MODE;
1023 else if(!(resp & FM_STEREO_SWITCH))
1024 *mode = FM_AUTO_MODE;
1025 fmdev->rx.audio_mode = resp;
1029 /* Sets RX stereo/mono modes */
1030 int fm_rx_config_audio_path(struct fmdrv_ops *fmdev, unsigned char path)
1034 if (fmdev->curr_fmmode != FM_MODE_RX)
1037 if (fmdev->rx.audio_path == path)
1039 pr_info ("(fmdrv) %s(): no change in audio path\n", __func__);
1042 /* if FM is on SCO and request to turn off FM over SCO */
1043 if (!(path & FM_AUDIO_BT_MONO) &&
1044 (fmdev->rx.pcm_reg & FM_PCM_ROUTE_ON_BIT))
1046 /* disable pcm_reg CB value FM routing bit */
1047 fmdev->rx.pcm_reg &= ~FM_PCM_ROUTE_ON_BIT;
1049 else if((path & FM_AUDIO_BT_MONO) &&
1050 !(fmdev->rx.pcm_reg & FM_PCM_ROUTE_ON_BIT)) /* turn on FM via SCO */
1052 /* when FM to SCO active, FM enforce I2S output */
1053 path |= FM_AUDIO_I2S;
1054 /* turn on pcm_reg CB value FM routing bit */
1055 fmdev->rx.pcm_reg |= FM_PCM_ROUTE_ON_BIT;
1058 /* write to PCM_ROUTE register */
1059 ret = fmc_send_cmd(fmdev, FM_REG_PCM_ROUTE,
1060 &fmdev->rx.pcm_reg, sizeof(fmdev->rx.pcm_reg), REG_WR,
1061 &fmdev->maintask_completion, NULL, NULL);
1063 FM_CHECK_SEND_CMD_STATUS(ret);
1065 if (path & FM_AUDIO_I2S)
1066 fmdev->rx.aud_ctrl |= FM_AUDIO_I2S_ON;
1068 fmdev->rx.aud_ctrl &= ~((unsigned short)FM_AUDIO_I2S_ON);
1070 if (path & FM_AUDIO_DAC)
1071 fmdev->rx.aud_ctrl |= FM_AUDIO_DAC_ON;
1073 fmdev->rx.aud_ctrl &= ~((unsigned short)FM_AUDIO_DAC_ON);
1075 ret = fm_rx_set_audio_ctrl (fmdev, fmdev->rx.aud_ctrl);
1077 FM_CHECK_SEND_CMD_STATUS(ret);
1078 fmdev->rx.audio_path = path;
1083 /* Choose RX de-emphasis filter mode (50us/75us) */
1084 int fm_rx_config_deemphasis(struct fmdrv_ops *fmdev, unsigned char mode)
1088 if (fmdev->curr_fmmode != FM_MODE_RX)
1091 if (mode != FM_DEEMPHA_50U &&
1092 mode != FM_DEEMPHA_75U)
1094 pr_err("(fmdrv) %s(): Invalid rx de-emphasis mode\n", __func__);
1098 if (mode == FM_DEEMPHA_50U )
1099 /* set to 50us by turning off 6th bit */
1100 fmdev->rx.aud_ctrl &= (~FM_DEEMPHA_75_ON);
1102 /* set to 75us by turning on 6th bit */
1103 fmdev->rx.aud_ctrl |= FM_DEEMPHA_75_ON;
1105 ret = fm_rx_set_audio_ctrl (fmdev, fmdev->rx.aud_ctrl);
1107 FM_CHECK_SEND_CMD_STATUS(ret);
1113 * Function to get the current scan step.
1114 * Returns FM_STEP_100KHZ or FM_STEP_200KHZ
1116 int fm_rx_get_scan_step(struct fmdrv_ops *fmdev,
1117 unsigned char *step_type)
1119 if (fmdev->curr_fmmode != FM_MODE_RX)
1122 if (step_type == NULL)
1124 pr_err("(fmdrv) %s(): Invalid memory\n", __func__);
1127 *step_type = fmdev->rx.sch_step;
1132 * Sets scan step to 100 or 200 KHz based on step type :
1133 * FM_STEP_100KHZ or FM_STEP_200KHZ
1135 int fm_rx_set_scan_step(struct fmdrv_ops *fmdev,
1136 unsigned char step_type)
1139 unsigned short payload;
1140 if (fmdev->curr_fmmode != FM_MODE_RX)
1144 if (fmdev->rx.sch_step == step_type)
1146 pr_info ("(fmdrv) %s(): no change in scan step size\n", __func__);
1149 payload = fm_sch_step_size[step_type]; /* darrel issue_06 */
1150 ret = fmc_send_cmd(fmdev, FM_REG_SCH_STEP, &payload, sizeof(payload),
1151 REG_WR, &fmdev->maintask_completion, NULL, NULL);
1152 FM_CHECK_SEND_CMD_STATUS(ret);
1154 fmdev->rx.sch_step = step_type;
1158 /************************************************************************************
1160 ************************************************************************************/
1162 /* Sets RDS operation mode (RDS/RDBS) */
1163 int fm_rx_set_rds_system(struct fmdrv_ops *fmdev, unsigned char rdbs_en_dis)
1165 unsigned char payload;
1167 pr_debug("(fmdrv) %s()\n", __func__);
1168 if (fmdev->curr_fmmode != FM_MODE_RX)
1171 /* Set RDS control */
1172 if (rdbs_en_dis == FM_RDBS_ENABLE)
1173 payload = (FM_RDS_CTRL_RBDS|FM_RDS_CTRL_FIFO_FLUSH);
1175 payload = FM_RDS_CTRL_FIFO_FLUSH;
1177 ret = fmc_send_cmd(fmdev, FM_REG_RDS_CTL0, &payload, sizeof(payload),
1178 REG_WR, &fmdev->maintask_completion, NULL, NULL);
1179 FM_CHECK_SEND_CMD_STATUS(ret);
1185 * Function to enable RDS. Called during FM enable.
1187 void fm_rx_enable_rds(struct fmdrv_ops *fmdev)
1189 unsigned char payload;
1191 if(fmdev->rx.fm_func_mask & (FM_RDS_BIT | FM_RBDS_BIT))
1193 payload = FM_RDS_UPD_TUPLE;
1194 /* write RDS FIFO waterline in depth of RDS tuples */
1195 ret = fmc_send_cmd(fmdev, FM_REG_RDS_WLINE, &payload, sizeof(payload),
1196 REG_WR, &fmdev->maintask_completion, NULL, NULL);
1198 pr_err("(fmdrv) %s(): Error writing to RDS FIFO waterline register\n",
1200 /* drain RDS FIFO */
1201 payload = FM_RDS_FIFO_MAX;
1202 ret = fmc_send_cmd(fmdev, FM_REG_RDS_DATA, &payload, 1,
1203 REG_RD, &fmdev->maintask_completion, NULL, NULL);
1205 /* set new FM_RDS mask so that RDS read */
1206 fmdev->rx.fm_rds_mask |= I2C_MASK_RDS_FIFO_WLINE_BIT;
1210 pr_err("(fmdrv) %s(): RDS not enabled during FM enable\n", __func__);
1211 fmdev->rx.fm_rds_mask &= ~I2C_MASK_RDS_FIFO_WLINE_BIT;
1213 fm_rx_set_mask(fmdev, fmdev->rx.fm_rds_mask);
1214 /* Reset the fm_rds_flag here as for the first time we dont get
1215 any interrupt during ENABLE to cleanup the bit */
1216 fmdev->rx.fm_rds_flag &= ~FM_RDS_FLAG_CLEAN_BIT;
1221 * Returns availability of RDS data in internel buffer.
1222 * If data is present in RDS buffer, return 0. Else, return -EAGAIN.
1223 * The V4L2 driver's poll() uses this method to determine RDS data availability.
1225 int fm_rx_is_rds_data_available(struct fmdrv_ops *fmdev, struct file *file,
1226 struct poll_table_struct *pts)
1228 poll_wait(file, &fmdev->rx.rds.read_queue, pts);
1229 if (fmdev->rx.rds.rd_index != fmdev->rx.rds.wr_index) {
1230 pr_info("(fmdrv) %s(): Poll success. RDS data is available in buffer\n",
1234 pr_err("(fmdev) %s(): RDS Buffer is empty\n", __func__);
1241 * Sets the signal strength level that once reached
1242 * will stop the auto search process
1244 int fm_rx_set_cfg_blnd_mute(struct fmdrv_ops *fmdev, unsigned char set_blndmute)
1248 ret = fmc_send_cmd(fmdev, FM_REG_BLEND_MUTE, &(fmdev->softmute_blend_config), sizeof(fmdev->softmute_blend_config),
1249 REG_WR, &fmdev->maintask_completion, NULL,NULL);
1254 fmdev->set_blndmute = set_blndmute;