2 * FM Driver for Connectivity chip of Texas Instruments.
3 * This sub-module of FM driver implements FM RX functionality.
5 * Copyright (C) 2011 Texas Instruments
6 * Author: Raja Mani <raja_mani@ti.com>
7 * Author: Manjunatha Halli <manjunatha_halli@ti.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
21 #include "fmdrv_common.h"
24 void fm_rx_reset_rds_cache(struct fmdev
*fmdev
)
26 fmdev
->rx
.rds
.flag
= FM_RDS_DISABLE
;
27 fmdev
->rx
.rds
.last_blk_idx
= 0;
28 fmdev
->rx
.rds
.wr_idx
= 0;
29 fmdev
->rx
.rds
.rd_idx
= 0;
31 if (fmdev
->rx
.af_mode
== FM_RX_RDS_AF_SWITCH_MODE_ON
)
32 fmdev
->irq_info
.mask
|= FM_LEV_EVENT
;
35 void fm_rx_reset_station_info(struct fmdev
*fmdev
)
37 fmdev
->rx
.stat_info
.picode
= FM_NO_PI_CODE
;
38 fmdev
->rx
.stat_info
.afcache_size
= 0;
39 fmdev
->rx
.stat_info
.af_list_max
= 0;
42 int fm_rx_set_freq(struct fmdev
*fmdev
, u32 freq
)
44 unsigned long timeleft
;
45 u16 payload
, curr_frq
, intr_flag
;
50 if (freq
< fmdev
->rx
.region
.bot_freq
|| freq
> fmdev
->rx
.region
.top_freq
) {
51 fmerr("Invalid frequency %d\n", freq
);
55 /* Set audio enable */
56 payload
= FM_RX_AUDIO_ENABLE_I2S_AND_ANALOG
;
58 ret
= fmc_send_cmd(fmdev
, AUDIO_ENABLE_SET
, REG_WR
, &payload
,
59 sizeof(payload
), NULL
, NULL
);
63 /* Set hilo to automatic selection */
64 payload
= FM_RX_IFFREQ_HILO_AUTOMATIC
;
65 ret
= fmc_send_cmd(fmdev
, HILO_SET
, REG_WR
, &payload
,
66 sizeof(payload
), NULL
, NULL
);
70 /* Calculate frequency index and set*/
71 payload
= (freq
- fmdev
->rx
.region
.bot_freq
) / FM_FREQ_MUL
;
73 ret
= fmc_send_cmd(fmdev
, FREQ_SET
, REG_WR
, &payload
,
74 sizeof(payload
), NULL
, NULL
);
78 /* Read flags - just to clear any pending interrupts if we had */
79 ret
= fmc_send_cmd(fmdev
, FLAG_GET
, REG_RD
, NULL
, 2, NULL
, NULL
);
83 /* Enable FR, BL interrupts */
84 intr_flag
= fmdev
->irq_info
.mask
;
85 fmdev
->irq_info
.mask
= (FM_FR_EVENT
| FM_BL_EVENT
);
86 payload
= fmdev
->irq_info
.mask
;
87 ret
= fmc_send_cmd(fmdev
, INT_MASK_SET
, REG_WR
, &payload
,
88 sizeof(payload
), NULL
, NULL
);
93 payload
= FM_TUNER_PRESET_MODE
;
94 ret
= fmc_send_cmd(fmdev
, TUNER_MODE_SET
, REG_WR
, &payload
,
95 sizeof(payload
), NULL
, NULL
);
99 /* Wait for tune ended interrupt */
100 init_completion(&fmdev
->maintask_comp
);
101 timeleft
= wait_for_completion_timeout(&fmdev
->maintask_comp
,
104 fmerr("Timeout(%d sec),didn't get tune ended int\n",
105 jiffies_to_msecs(FM_DRV_TX_TIMEOUT
) / 1000);
110 /* Read freq back to confirm */
111 ret
= fmc_send_cmd(fmdev
, FREQ_SET
, REG_RD
, NULL
, 2, &curr_frq
, &resp_len
);
115 curr_frq
= be16_to_cpu((__force __be16
)curr_frq
);
116 curr_frq_in_khz
= (fmdev
->rx
.region
.bot_freq
+ ((u32
)curr_frq
* FM_FREQ_MUL
));
118 if (curr_frq_in_khz
!= freq
) {
119 pr_info("Frequency is set to (%d) but requested freq is (%d)\n",
120 curr_frq_in_khz
, freq
);
123 /* Update local cache */
124 fmdev
->rx
.freq
= curr_frq_in_khz
;
126 /* Re-enable default FM interrupts */
127 fmdev
->irq_info
.mask
= intr_flag
;
128 payload
= fmdev
->irq_info
.mask
;
129 ret
= fmc_send_cmd(fmdev
, INT_MASK_SET
, REG_WR
, &payload
,
130 sizeof(payload
), NULL
, NULL
);
134 /* Reset RDS cache and current station pointers */
135 fm_rx_reset_rds_cache(fmdev
);
136 fm_rx_reset_station_info(fmdev
);
141 static int fm_rx_set_channel_spacing(struct fmdev
*fmdev
, u32 spacing
)
146 if (spacing
> 0 && spacing
<= 50000)
147 spacing
= FM_CHANNEL_SPACING_50KHZ
;
148 else if (spacing
> 50000 && spacing
<= 100000)
149 spacing
= FM_CHANNEL_SPACING_100KHZ
;
151 spacing
= FM_CHANNEL_SPACING_200KHZ
;
153 /* set channel spacing */
155 ret
= fmc_send_cmd(fmdev
, CHANL_BW_SET
, REG_WR
, &payload
,
156 sizeof(payload
), NULL
, NULL
);
160 fmdev
->rx
.region
.chanl_space
= spacing
* FM_FREQ_MUL
;
165 int fm_rx_seek(struct fmdev
*fmdev
, u32 seek_upward
,
166 u32 wrap_around
, u32 spacing
)
169 u16 curr_frq
, next_frq
, last_frq
;
170 u16 payload
, int_reason
, intr_flag
;
171 u16 offset
, space_idx
;
172 unsigned long timeleft
;
175 /* Set channel spacing */
176 ret
= fm_rx_set_channel_spacing(fmdev
, spacing
);
178 fmerr("Failed to set channel spacing\n");
182 /* Read the current frequency from chip */
183 ret
= fmc_send_cmd(fmdev
, FREQ_SET
, REG_RD
, NULL
,
184 sizeof(curr_frq
), &curr_frq
, &resp_len
);
188 curr_frq
= be16_to_cpu((__force __be16
)curr_frq
);
189 last_frq
= (fmdev
->rx
.region
.top_freq
- fmdev
->rx
.region
.bot_freq
) / FM_FREQ_MUL
;
191 /* Check the offset in order to be aligned to the channel spacing*/
192 space_idx
= fmdev
->rx
.region
.chanl_space
/ FM_FREQ_MUL
;
193 offset
= curr_frq
% space_idx
;
195 next_frq
= seek_upward
? curr_frq
+ space_idx
/* Seek Up */ :
196 curr_frq
- space_idx
/* Seek Down */ ;
199 * Add or subtract offset in order to stay aligned to the channel
202 if ((short)next_frq
< 0)
203 next_frq
= last_frq
- offset
;
204 else if (next_frq
> last_frq
)
205 next_frq
= 0 + offset
;
208 /* Set calculated next frequency to perform seek */
210 ret
= fmc_send_cmd(fmdev
, FREQ_SET
, REG_WR
, &payload
,
211 sizeof(payload
), NULL
, NULL
);
215 /* Set search direction (0:Seek Down, 1:Seek Up) */
216 payload
= (seek_upward
? FM_SEARCH_DIRECTION_UP
: FM_SEARCH_DIRECTION_DOWN
);
217 ret
= fmc_send_cmd(fmdev
, SEARCH_DIR_SET
, REG_WR
, &payload
,
218 sizeof(payload
), NULL
, NULL
);
222 /* Read flags - just to clear any pending interrupts if we had */
223 ret
= fmc_send_cmd(fmdev
, FLAG_GET
, REG_RD
, NULL
, 2, NULL
, NULL
);
227 /* Enable FR, BL interrupts */
228 intr_flag
= fmdev
->irq_info
.mask
;
229 fmdev
->irq_info
.mask
= (FM_FR_EVENT
| FM_BL_EVENT
);
230 payload
= fmdev
->irq_info
.mask
;
231 ret
= fmc_send_cmd(fmdev
, INT_MASK_SET
, REG_WR
, &payload
,
232 sizeof(payload
), NULL
, NULL
);
237 payload
= FM_TUNER_AUTONOMOUS_SEARCH_MODE
;
238 ret
= fmc_send_cmd(fmdev
, TUNER_MODE_SET
, REG_WR
, &payload
,
239 sizeof(payload
), NULL
, NULL
);
243 /* Wait for tune ended/band limit reached interrupt */
244 init_completion(&fmdev
->maintask_comp
);
245 timeleft
= wait_for_completion_timeout(&fmdev
->maintask_comp
,
246 FM_DRV_RX_SEEK_TIMEOUT
);
248 fmerr("Timeout(%d sec),didn't get tune ended int\n",
249 jiffies_to_msecs(FM_DRV_RX_SEEK_TIMEOUT
) / 1000);
253 int_reason
= fmdev
->irq_info
.flag
& (FM_TUNE_COMPLETE
| FM_BAND_LIMIT
);
255 /* Re-enable default FM interrupts */
256 fmdev
->irq_info
.mask
= intr_flag
;
257 payload
= fmdev
->irq_info
.mask
;
258 ret
= fmc_send_cmd(fmdev
, INT_MASK_SET
, REG_WR
, &payload
,
259 sizeof(payload
), NULL
, NULL
);
263 if (int_reason
& FM_BL_EVENT
) {
264 if (wrap_around
== 0) {
265 fmdev
->rx
.freq
= seek_upward
?
266 fmdev
->rx
.region
.top_freq
:
267 fmdev
->rx
.region
.bot_freq
;
269 fmdev
->rx
.freq
= seek_upward
?
270 fmdev
->rx
.region
.bot_freq
:
271 fmdev
->rx
.region
.top_freq
;
272 /* Calculate frequency index to write */
273 next_frq
= (fmdev
->rx
.freq
-
274 fmdev
->rx
.region
.bot_freq
) / FM_FREQ_MUL
;
278 /* Read freq to know where operation tune operation stopped */
279 ret
= fmc_send_cmd(fmdev
, FREQ_SET
, REG_RD
, NULL
, 2,
280 &curr_frq
, &resp_len
);
284 curr_frq
= be16_to_cpu((__force __be16
)curr_frq
);
285 fmdev
->rx
.freq
= (fmdev
->rx
.region
.bot_freq
+
286 ((u32
)curr_frq
* FM_FREQ_MUL
));
289 /* Reset RDS cache and current station pointers */
290 fm_rx_reset_rds_cache(fmdev
);
291 fm_rx_reset_station_info(fmdev
);
296 int fm_rx_set_volume(struct fmdev
*fmdev
, u16 vol_to_set
)
301 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
304 if (vol_to_set
> FM_RX_VOLUME_MAX
) {
305 fmerr("Volume is not within(%d-%d) range\n",
306 FM_RX_VOLUME_MIN
, FM_RX_VOLUME_MAX
);
309 vol_to_set
*= FM_RX_VOLUME_GAIN_STEP
;
311 payload
= vol_to_set
;
312 ret
= fmc_send_cmd(fmdev
, VOLUME_SET
, REG_WR
, &payload
,
313 sizeof(payload
), NULL
, NULL
);
317 fmdev
->rx
.volume
= vol_to_set
;
322 int fm_rx_get_volume(struct fmdev
*fmdev
, u16
*curr_vol
)
324 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
327 if (curr_vol
== NULL
) {
328 fmerr("Invalid memory\n");
332 *curr_vol
= fmdev
->rx
.volume
/ FM_RX_VOLUME_GAIN_STEP
;
337 /* To get current band's bottom and top frequency */
338 int fm_rx_get_band_freq_range(struct fmdev
*fmdev
, u32
*bot_freq
, u32
*top_freq
)
340 if (bot_freq
!= NULL
)
341 *bot_freq
= fmdev
->rx
.region
.bot_freq
;
343 if (top_freq
!= NULL
)
344 *top_freq
= fmdev
->rx
.region
.top_freq
;
349 /* Returns current band index (0-Europe/US; 1-Japan) */
350 void fm_rx_get_region(struct fmdev
*fmdev
, u8
*region
)
352 *region
= fmdev
->rx
.region
.fm_band
;
355 /* Sets band (0-Europe/US; 1-Japan) */
356 int fm_rx_set_region(struct fmdev
*fmdev
, u8 region_to_set
)
362 if (region_to_set
!= FM_BAND_EUROPE_US
&&
363 region_to_set
!= FM_BAND_JAPAN
) {
364 fmerr("Invalid band\n");
368 if (fmdev
->rx
.region
.fm_band
== region_to_set
) {
369 fmerr("Requested band is already configured\n");
373 /* Send cmd to set the band */
374 payload
= (u16
)region_to_set
;
375 ret
= fmc_send_cmd(fmdev
, BAND_SET
, REG_WR
, &payload
,
376 sizeof(payload
), NULL
, NULL
);
380 fmc_update_region_info(fmdev
, region_to_set
);
382 /* Check whether current RX frequency is within band boundary */
383 if (fmdev
->rx
.freq
< fmdev
->rx
.region
.bot_freq
)
384 new_frq
= fmdev
->rx
.region
.bot_freq
;
385 else if (fmdev
->rx
.freq
> fmdev
->rx
.region
.top_freq
)
386 new_frq
= fmdev
->rx
.region
.top_freq
;
389 fmdbg("Current freq is not within band limit boundary,switching to %d KHz\n",
391 /* Current RX frequency is not in range. So, update it */
392 ret
= fm_rx_set_freq(fmdev
, new_frq
);
398 /* Reads current mute mode (Mute Off/On/Attenuate)*/
399 int fm_rx_get_mute_mode(struct fmdev
*fmdev
, u8
*curr_mute_mode
)
401 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
404 if (curr_mute_mode
== NULL
) {
405 fmerr("Invalid memory\n");
409 *curr_mute_mode
= fmdev
->rx
.mute_mode
;
414 static int fm_config_rx_mute_reg(struct fmdev
*fmdev
)
416 u16 payload
, muteval
;
420 switch (fmdev
->rx
.mute_mode
) {
422 muteval
= FM_RX_AC_MUTE_MODE
;
426 muteval
= FM_RX_UNMUTE_MODE
;
429 case FM_MUTE_ATTENUATE
:
430 muteval
= FM_RX_SOFT_MUTE_FORCE_MODE
;
433 if (fmdev
->rx
.rf_depend_mute
== FM_RX_RF_DEPENDENT_MUTE_ON
)
434 muteval
|= FM_RX_RF_DEP_MODE
;
436 muteval
&= ~FM_RX_RF_DEP_MODE
;
439 ret
= fmc_send_cmd(fmdev
, MUTE_STATUS_SET
, REG_WR
, &payload
,
440 sizeof(payload
), NULL
, NULL
);
447 /* Configures mute mode (Mute Off/On/Attenuate) */
448 int fm_rx_set_mute_mode(struct fmdev
*fmdev
, u8 mute_mode_toset
)
453 if (fmdev
->rx
.mute_mode
== mute_mode_toset
)
456 org_state
= fmdev
->rx
.mute_mode
;
457 fmdev
->rx
.mute_mode
= mute_mode_toset
;
459 ret
= fm_config_rx_mute_reg(fmdev
);
461 fmdev
->rx
.mute_mode
= org_state
;
468 /* Gets RF dependent soft mute mode enable/disable status */
469 int fm_rx_get_rfdepend_softmute(struct fmdev
*fmdev
, u8
*curr_mute_mode
)
471 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
474 if (curr_mute_mode
== NULL
) {
475 fmerr("Invalid memory\n");
479 *curr_mute_mode
= fmdev
->rx
.rf_depend_mute
;
484 /* Sets RF dependent soft mute mode */
485 int fm_rx_set_rfdepend_softmute(struct fmdev
*fmdev
, u8 rfdepend_mute
)
490 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
493 if (rfdepend_mute
!= FM_RX_RF_DEPENDENT_MUTE_ON
&&
494 rfdepend_mute
!= FM_RX_RF_DEPENDENT_MUTE_OFF
) {
495 fmerr("Invalid RF dependent soft mute\n");
498 if (fmdev
->rx
.rf_depend_mute
== rfdepend_mute
)
501 org_state
= fmdev
->rx
.rf_depend_mute
;
502 fmdev
->rx
.rf_depend_mute
= rfdepend_mute
;
504 ret
= fm_config_rx_mute_reg(fmdev
);
506 fmdev
->rx
.rf_depend_mute
= org_state
;
513 /* Returns the signal strength level of current channel */
514 int fm_rx_get_rssi_level(struct fmdev
*fmdev
, u16
*rssilvl
)
516 __be16 curr_rssi_lel
;
520 if (rssilvl
== NULL
) {
521 fmerr("Invalid memory\n");
524 /* Read current RSSI level */
525 ret
= fmc_send_cmd(fmdev
, RSSI_LVL_GET
, REG_RD
, NULL
, 2,
526 &curr_rssi_lel
, &resp_len
);
530 *rssilvl
= be16_to_cpu(curr_rssi_lel
);
536 * Sets the signal strength level that once reached
537 * will stop the auto search process
539 int fm_rx_set_rssi_threshold(struct fmdev
*fmdev
, short rssi_lvl_toset
)
544 if (rssi_lvl_toset
< FM_RX_RSSI_THRESHOLD_MIN
||
545 rssi_lvl_toset
> FM_RX_RSSI_THRESHOLD_MAX
) {
546 fmerr("Invalid RSSI threshold level\n");
549 payload
= (u16
)rssi_lvl_toset
;
550 ret
= fmc_send_cmd(fmdev
, SEARCH_LVL_SET
, REG_WR
, &payload
,
551 sizeof(payload
), NULL
, NULL
);
555 fmdev
->rx
.rssi_threshold
= rssi_lvl_toset
;
560 /* Returns current RX RSSI threshold value */
561 int fm_rx_get_rssi_threshold(struct fmdev
*fmdev
, short *curr_rssi_lvl
)
563 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
566 if (curr_rssi_lvl
== NULL
) {
567 fmerr("Invalid memory\n");
571 *curr_rssi_lvl
= fmdev
->rx
.rssi_threshold
;
576 /* Sets RX stereo/mono modes */
577 int fm_rx_set_stereo_mono(struct fmdev
*fmdev
, u16 mode
)
582 if (mode
!= FM_STEREO_MODE
&& mode
!= FM_MONO_MODE
) {
583 fmerr("Invalid mode\n");
587 /* Set stereo/mono mode */
589 ret
= fmc_send_cmd(fmdev
, MOST_MODE_SET
, REG_WR
, &payload
,
590 sizeof(payload
), NULL
, NULL
);
594 /* Set stereo blending mode */
595 payload
= FM_STEREO_SOFT_BLEND
;
596 ret
= fmc_send_cmd(fmdev
, MOST_BLEND_SET
, REG_WR
, &payload
,
597 sizeof(payload
), NULL
, NULL
);
604 /* Gets current RX stereo/mono mode */
605 int fm_rx_get_stereo_mono(struct fmdev
*fmdev
, u16
*mode
)
612 fmerr("Invalid memory\n");
616 ret
= fmc_send_cmd(fmdev
, MOST_MODE_SET
, REG_RD
, NULL
, 2,
617 &curr_mode
, &resp_len
);
621 *mode
= be16_to_cpu(curr_mode
);
626 /* Choose RX de-emphasis filter mode (50us/75us) */
627 int fm_rx_set_deemphasis_mode(struct fmdev
*fmdev
, u16 mode
)
632 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
635 if (mode
!= FM_RX_EMPHASIS_FILTER_50_USEC
&&
636 mode
!= FM_RX_EMPHASIS_FILTER_75_USEC
) {
637 fmerr("Invalid rx de-emphasis mode (%d)\n", mode
);
642 ret
= fmc_send_cmd(fmdev
, DEMPH_MODE_SET
, REG_WR
, &payload
,
643 sizeof(payload
), NULL
, NULL
);
647 fmdev
->rx
.deemphasis_mode
= mode
;
652 /* Gets current RX de-emphasis filter mode */
653 int fm_rx_get_deemph_mode(struct fmdev
*fmdev
, u16
*curr_deemphasis_mode
)
655 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
658 if (curr_deemphasis_mode
== NULL
) {
659 fmerr("Invalid memory\n");
663 *curr_deemphasis_mode
= fmdev
->rx
.deemphasis_mode
;
668 /* Enable/Disable RX RDS */
669 int fm_rx_set_rds_mode(struct fmdev
*fmdev
, u8 rds_en_dis
)
674 if (rds_en_dis
!= FM_RDS_ENABLE
&& rds_en_dis
!= FM_RDS_DISABLE
) {
675 fmerr("Invalid rds option\n");
679 if (rds_en_dis
== FM_RDS_ENABLE
680 && fmdev
->rx
.rds
.flag
== FM_RDS_DISABLE
) {
681 /* Turn on RX RDS and RDS circuit */
682 payload
= FM_RX_PWR_SET_FM_AND_RDS_BLK_ON
;
683 ret
= fmc_send_cmd(fmdev
, POWER_SET
, REG_WR
, &payload
,
684 sizeof(payload
), NULL
, NULL
);
688 /* Clear and reset RDS FIFO */
689 payload
= FM_RX_RDS_FLUSH_FIFO
;
690 ret
= fmc_send_cmd(fmdev
, RDS_CNTRL_SET
, REG_WR
, &payload
,
691 sizeof(payload
), NULL
, NULL
);
695 /* Read flags - just to clear any pending interrupts. */
696 ret
= fmc_send_cmd(fmdev
, FLAG_GET
, REG_RD
, NULL
, 2,
701 /* Set RDS FIFO threshold value */
702 payload
= FM_RX_RDS_FIFO_THRESHOLD
;
703 ret
= fmc_send_cmd(fmdev
, RDS_MEM_SET
, REG_WR
, &payload
,
704 sizeof(payload
), NULL
, NULL
);
708 /* Enable RDS interrupt */
709 fmdev
->irq_info
.mask
|= FM_RDS_EVENT
;
710 payload
= fmdev
->irq_info
.mask
;
711 ret
= fmc_send_cmd(fmdev
, INT_MASK_SET
, REG_WR
, &payload
,
712 sizeof(payload
), NULL
, NULL
);
714 fmdev
->irq_info
.mask
&= ~FM_RDS_EVENT
;
718 /* Update our local flag */
719 fmdev
->rx
.rds
.flag
= FM_RDS_ENABLE
;
720 } else if (rds_en_dis
== FM_RDS_DISABLE
721 && fmdev
->rx
.rds
.flag
== FM_RDS_ENABLE
) {
722 /* Turn off RX RDS */
723 payload
= FM_RX_PWR_SET_FM_ON_RDS_OFF
;
724 ret
= fmc_send_cmd(fmdev
, POWER_SET
, REG_WR
, &payload
,
725 sizeof(payload
), NULL
, NULL
);
729 /* Reset RDS pointers */
730 fmdev
->rx
.rds
.last_blk_idx
= 0;
731 fmdev
->rx
.rds
.wr_idx
= 0;
732 fmdev
->rx
.rds
.rd_idx
= 0;
733 fm_rx_reset_station_info(fmdev
);
735 /* Update RDS local cache */
736 fmdev
->irq_info
.mask
&= ~(FM_RDS_EVENT
);
737 fmdev
->rx
.rds
.flag
= FM_RDS_DISABLE
;
743 /* Returns current RX RDS enable/disable status */
744 int fm_rx_get_rds_mode(struct fmdev
*fmdev
, u8
*curr_rds_en_dis
)
746 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
749 if (curr_rds_en_dis
== NULL
) {
750 fmerr("Invalid memory\n");
754 *curr_rds_en_dis
= fmdev
->rx
.rds
.flag
;
759 /* Sets RDS operation mode (RDS/RDBS) */
760 int fm_rx_set_rds_system(struct fmdev
*fmdev
, u8 rds_mode
)
765 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
768 if (rds_mode
!= FM_RDS_SYSTEM_RDS
&& rds_mode
!= FM_RDS_SYSTEM_RBDS
) {
769 fmerr("Invalid rds mode\n");
772 /* Set RDS operation mode */
773 payload
= (u16
)rds_mode
;
774 ret
= fmc_send_cmd(fmdev
, RDS_SYSTEM_SET
, REG_WR
, &payload
,
775 sizeof(payload
), NULL
, NULL
);
779 fmdev
->rx
.rds_mode
= rds_mode
;
784 /* Configures Alternate Frequency switch mode */
785 int fm_rx_set_af_switch(struct fmdev
*fmdev
, u8 af_mode
)
790 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
793 if (af_mode
!= FM_RX_RDS_AF_SWITCH_MODE_ON
&&
794 af_mode
!= FM_RX_RDS_AF_SWITCH_MODE_OFF
) {
795 fmerr("Invalid af mode\n");
798 /* Enable/disable low RSSI interrupt based on af_mode */
799 if (af_mode
== FM_RX_RDS_AF_SWITCH_MODE_ON
)
800 fmdev
->irq_info
.mask
|= FM_LEV_EVENT
;
802 fmdev
->irq_info
.mask
&= ~FM_LEV_EVENT
;
804 payload
= fmdev
->irq_info
.mask
;
805 ret
= fmc_send_cmd(fmdev
, INT_MASK_SET
, REG_WR
, &payload
,
806 sizeof(payload
), NULL
, NULL
);
810 fmdev
->rx
.af_mode
= af_mode
;
815 /* Returns Alternate Frequency switch status */
816 int fm_rx_get_af_switch(struct fmdev
*fmdev
, u8
*af_mode
)
818 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
821 if (af_mode
== NULL
) {
822 fmerr("Invalid memory\n");
826 *af_mode
= fmdev
->rx
.af_mode
;