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.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "fmdrv_common.h"
28 void fm_rx_reset_rds_cache(struct fmdev
*fmdev
)
30 fmdev
->rx
.rds
.flag
= FM_RDS_DISABLE
;
31 fmdev
->rx
.rds
.last_blk_idx
= 0;
32 fmdev
->rx
.rds
.wr_idx
= 0;
33 fmdev
->rx
.rds
.rd_idx
= 0;
35 if (fmdev
->rx
.af_mode
== FM_RX_RDS_AF_SWITCH_MODE_ON
)
36 fmdev
->irq_info
.mask
|= FM_LEV_EVENT
;
39 void fm_rx_reset_station_info(struct fmdev
*fmdev
)
41 fmdev
->rx
.stat_info
.picode
= FM_NO_PI_CODE
;
42 fmdev
->rx
.stat_info
.afcache_size
= 0;
43 fmdev
->rx
.stat_info
.af_list_max
= 0;
46 u32
fm_rx_set_freq(struct fmdev
*fmdev
, u32 freq
)
48 unsigned long timeleft
;
49 u16 payload
, curr_frq
, intr_flag
;
53 if (freq
< fmdev
->rx
.region
.bot_freq
|| freq
> fmdev
->rx
.region
.top_freq
) {
54 fmerr("Invalid frequency %d\n", freq
);
58 /* Set audio enable */
59 payload
= FM_RX_AUDIO_ENABLE_I2S_AND_ANALOG
;
61 ret
= fmc_send_cmd(fmdev
, AUDIO_ENABLE_SET
, REG_WR
, &payload
,
62 sizeof(payload
), NULL
, NULL
);
66 /* Set hilo to automatic selection */
67 payload
= FM_RX_IFFREQ_HILO_AUTOMATIC
;
68 ret
= fmc_send_cmd(fmdev
, HILO_SET
, REG_WR
, &payload
,
69 sizeof(payload
), NULL
, NULL
);
73 /* Calculate frequency index and set*/
74 payload
= (freq
- fmdev
->rx
.region
.bot_freq
) / FM_FREQ_MUL
;
76 ret
= fmc_send_cmd(fmdev
, FREQ_SET
, REG_WR
, &payload
,
77 sizeof(payload
), NULL
, NULL
);
81 /* Read flags - just to clear any pending interrupts if we had */
82 ret
= fmc_send_cmd(fmdev
, FLAG_GET
, REG_RD
, NULL
, 2, NULL
, NULL
);
86 /* Enable FR, BL interrupts */
87 intr_flag
= fmdev
->irq_info
.mask
;
88 fmdev
->irq_info
.mask
= (FM_FR_EVENT
| FM_BL_EVENT
);
89 payload
= fmdev
->irq_info
.mask
;
90 ret
= fmc_send_cmd(fmdev
, INT_MASK_SET
, REG_WR
, &payload
,
91 sizeof(payload
), NULL
, NULL
);
96 payload
= FM_TUNER_PRESET_MODE
;
97 ret
= fmc_send_cmd(fmdev
, TUNER_MODE_SET
, REG_WR
, &payload
,
98 sizeof(payload
), NULL
, NULL
);
102 /* Wait for tune ended interrupt */
103 init_completion(&fmdev
->maintask_comp
);
104 timeleft
= wait_for_completion_timeout(&fmdev
->maintask_comp
,
107 fmerr("Timeout(%d sec),didn't get tune ended int\n",
108 jiffies_to_msecs(FM_DRV_TX_TIMEOUT
) / 1000);
113 /* Read freq back to confirm */
114 ret
= fmc_send_cmd(fmdev
, FREQ_SET
, REG_RD
, NULL
, 2, &curr_frq
, &resp_len
);
118 curr_frq
= be16_to_cpu(curr_frq
);
119 curr_frq_in_khz
= (fmdev
->rx
.region
.bot_freq
+ ((u32
)curr_frq
* FM_FREQ_MUL
));
121 if (curr_frq_in_khz
!= freq
) {
122 pr_info("Frequency is set to (%d) but "
123 "requested freq is (%d)\n", curr_frq_in_khz
, freq
);
126 /* Update local cache */
127 fmdev
->rx
.freq
= curr_frq_in_khz
;
129 /* Re-enable default FM interrupts */
130 fmdev
->irq_info
.mask
= intr_flag
;
131 payload
= fmdev
->irq_info
.mask
;
132 ret
= fmc_send_cmd(fmdev
, INT_MASK_SET
, REG_WR
, &payload
,
133 sizeof(payload
), NULL
, NULL
);
137 /* Reset RDS cache and current station pointers */
138 fm_rx_reset_rds_cache(fmdev
);
139 fm_rx_reset_station_info(fmdev
);
144 static u32
fm_rx_set_channel_spacing(struct fmdev
*fmdev
, u32 spacing
)
149 if (spacing
> 0 && spacing
<= 50000)
150 spacing
= FM_CHANNEL_SPACING_50KHZ
;
151 else if (spacing
> 50000 && spacing
<= 100000)
152 spacing
= FM_CHANNEL_SPACING_100KHZ
;
154 spacing
= FM_CHANNEL_SPACING_200KHZ
;
156 /* set channel spacing */
158 ret
= fmc_send_cmd(fmdev
, CHANL_BW_SET
, REG_WR
, &payload
,
159 sizeof(payload
), NULL
, NULL
);
163 fmdev
->rx
.region
.chanl_space
= spacing
* FM_FREQ_MUL
;
168 u32
fm_rx_seek(struct fmdev
*fmdev
, u32 seek_upward
,
169 u32 wrap_around
, u32 spacing
)
172 u16 curr_frq
, next_frq
, last_frq
;
173 u16 payload
, int_reason
, intr_flag
;
174 u16 offset
, space_idx
;
175 unsigned long timeleft
;
178 /* Set channel spacing */
179 ret
= fm_rx_set_channel_spacing(fmdev
, spacing
);
181 fmerr("Failed to set channel spacing\n");
185 /* Read the current frequency from chip */
186 ret
= fmc_send_cmd(fmdev
, FREQ_SET
, REG_RD
, NULL
,
187 sizeof(curr_frq
), &curr_frq
, &resp_len
);
191 curr_frq
= be16_to_cpu(curr_frq
);
192 last_frq
= (fmdev
->rx
.region
.top_freq
- fmdev
->rx
.region
.bot_freq
) / FM_FREQ_MUL
;
194 /* Check the offset in order to be aligned to the channel spacing*/
195 space_idx
= fmdev
->rx
.region
.chanl_space
/ FM_FREQ_MUL
;
196 offset
= curr_frq
% space_idx
;
198 next_frq
= seek_upward
? curr_frq
+ space_idx
/* Seek Up */ :
199 curr_frq
- space_idx
/* Seek Down */ ;
202 * Add or subtract offset in order to stay aligned to the channel
205 if ((short)next_frq
< 0)
206 next_frq
= last_frq
- offset
;
207 else if (next_frq
> last_frq
)
208 next_frq
= 0 + offset
;
211 /* Set calculated next frequency to perform seek */
213 ret
= fmc_send_cmd(fmdev
, FREQ_SET
, REG_WR
, &payload
,
214 sizeof(payload
), NULL
, NULL
);
218 /* Set search direction (0:Seek Down, 1:Seek Up) */
219 payload
= (seek_upward
? FM_SEARCH_DIRECTION_UP
: FM_SEARCH_DIRECTION_DOWN
);
220 ret
= fmc_send_cmd(fmdev
, SEARCH_DIR_SET
, REG_WR
, &payload
,
221 sizeof(payload
), NULL
, NULL
);
225 /* Read flags - just to clear any pending interrupts if we had */
226 ret
= fmc_send_cmd(fmdev
, FLAG_GET
, REG_RD
, NULL
, 2, NULL
, NULL
);
230 /* Enable FR, BL interrupts */
231 intr_flag
= fmdev
->irq_info
.mask
;
232 fmdev
->irq_info
.mask
= (FM_FR_EVENT
| FM_BL_EVENT
);
233 payload
= fmdev
->irq_info
.mask
;
234 ret
= fmc_send_cmd(fmdev
, INT_MASK_SET
, REG_WR
, &payload
,
235 sizeof(payload
), NULL
, NULL
);
240 payload
= FM_TUNER_AUTONOMOUS_SEARCH_MODE
;
241 ret
= fmc_send_cmd(fmdev
, TUNER_MODE_SET
, REG_WR
, &payload
,
242 sizeof(payload
), NULL
, NULL
);
246 /* Wait for tune ended/band limit reached interrupt */
247 init_completion(&fmdev
->maintask_comp
);
248 timeleft
= wait_for_completion_timeout(&fmdev
->maintask_comp
,
249 FM_DRV_RX_SEEK_TIMEOUT
);
251 fmerr("Timeout(%d sec),didn't get tune ended int\n",
252 jiffies_to_msecs(FM_DRV_RX_SEEK_TIMEOUT
) / 1000);
256 int_reason
= fmdev
->irq_info
.flag
& (FM_TUNE_COMPLETE
| FM_BAND_LIMIT
);
258 /* Re-enable default FM interrupts */
259 fmdev
->irq_info
.mask
= intr_flag
;
260 payload
= fmdev
->irq_info
.mask
;
261 ret
= fmc_send_cmd(fmdev
, INT_MASK_SET
, REG_WR
, &payload
,
262 sizeof(payload
), NULL
, NULL
);
266 if (int_reason
& FM_BL_EVENT
) {
267 if (wrap_around
== 0) {
268 fmdev
->rx
.freq
= seek_upward
?
269 fmdev
->rx
.region
.top_freq
:
270 fmdev
->rx
.region
.bot_freq
;
272 fmdev
->rx
.freq
= seek_upward
?
273 fmdev
->rx
.region
.bot_freq
:
274 fmdev
->rx
.region
.top_freq
;
275 /* Calculate frequency index to write */
276 next_frq
= (fmdev
->rx
.freq
-
277 fmdev
->rx
.region
.bot_freq
) / FM_FREQ_MUL
;
281 /* Read freq to know where operation tune operation stopped */
282 ret
= fmc_send_cmd(fmdev
, FREQ_SET
, REG_RD
, NULL
, 2,
283 &curr_frq
, &resp_len
);
287 curr_frq
= be16_to_cpu(curr_frq
);
288 fmdev
->rx
.freq
= (fmdev
->rx
.region
.bot_freq
+
289 ((u32
)curr_frq
* FM_FREQ_MUL
));
292 /* Reset RDS cache and current station pointers */
293 fm_rx_reset_rds_cache(fmdev
);
294 fm_rx_reset_station_info(fmdev
);
299 u32
fm_rx_set_volume(struct fmdev
*fmdev
, u16 vol_to_set
)
304 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
307 if (vol_to_set
< FM_RX_VOLUME_MIN
|| vol_to_set
> FM_RX_VOLUME_MAX
) {
308 fmerr("Volume is not within(%d-%d) range\n",
309 FM_RX_VOLUME_MIN
, FM_RX_VOLUME_MAX
);
312 vol_to_set
*= FM_RX_VOLUME_GAIN_STEP
;
314 payload
= vol_to_set
;
315 ret
= fmc_send_cmd(fmdev
, VOLUME_SET
, REG_WR
, &payload
,
316 sizeof(payload
), NULL
, NULL
);
320 fmdev
->rx
.volume
= vol_to_set
;
325 u32
fm_rx_get_volume(struct fmdev
*fmdev
, u16
*curr_vol
)
327 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
330 if (curr_vol
== NULL
) {
331 fmerr("Invalid memory\n");
335 *curr_vol
= fmdev
->rx
.volume
/ FM_RX_VOLUME_GAIN_STEP
;
340 /* To get current band's bottom and top frequency */
341 u32
fm_rx_get_band_freq_range(struct fmdev
*fmdev
, u32
*bot_freq
, u32
*top_freq
)
343 if (bot_freq
!= NULL
)
344 *bot_freq
= fmdev
->rx
.region
.bot_freq
;
346 if (top_freq
!= NULL
)
347 *top_freq
= fmdev
->rx
.region
.top_freq
;
352 /* Returns current band index (0-Europe/US; 1-Japan) */
353 void fm_rx_get_region(struct fmdev
*fmdev
, u8
*region
)
355 *region
= fmdev
->rx
.region
.fm_band
;
358 /* Sets band (0-Europe/US; 1-Japan) */
359 u32
fm_rx_set_region(struct fmdev
*fmdev
, u8 region_to_set
)
365 if (region_to_set
!= FM_BAND_EUROPE_US
&&
366 region_to_set
!= FM_BAND_JAPAN
) {
367 fmerr("Invalid band\n");
371 if (fmdev
->rx
.region
.fm_band
== region_to_set
) {
372 fmerr("Requested band is already configured\n");
376 /* Send cmd to set the band */
377 payload
= (u16
)region_to_set
;
378 ret
= fmc_send_cmd(fmdev
, BAND_SET
, REG_WR
, &payload
,
379 sizeof(payload
), NULL
, NULL
);
383 fmc_update_region_info(fmdev
, region_to_set
);
385 /* Check whether current RX frequency is within band boundary */
386 if (fmdev
->rx
.freq
< fmdev
->rx
.region
.bot_freq
)
387 new_frq
= fmdev
->rx
.region
.bot_freq
;
388 else if (fmdev
->rx
.freq
> fmdev
->rx
.region
.top_freq
)
389 new_frq
= fmdev
->rx
.region
.top_freq
;
392 fmdbg("Current freq is not within band limit boundary,"
393 "switching to %d KHz\n", new_frq
);
394 /* Current RX frequency is not in range. So, update it */
395 ret
= fm_rx_set_freq(fmdev
, new_frq
);
401 /* Reads current mute mode (Mute Off/On/Attenuate)*/
402 u32
fm_rx_get_mute_mode(struct fmdev
*fmdev
, u8
*curr_mute_mode
)
404 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
407 if (curr_mute_mode
== NULL
) {
408 fmerr("Invalid memory\n");
412 *curr_mute_mode
= fmdev
->rx
.mute_mode
;
417 static u32
fm_config_rx_mute_reg(struct fmdev
*fmdev
)
419 u16 payload
, muteval
;
423 switch (fmdev
->rx
.mute_mode
) {
425 muteval
= FM_RX_AC_MUTE_MODE
;
429 muteval
= FM_RX_UNMUTE_MODE
;
432 case FM_MUTE_ATTENUATE
:
433 muteval
= FM_RX_SOFT_MUTE_FORCE_MODE
;
436 if (fmdev
->rx
.rf_depend_mute
== FM_RX_RF_DEPENDENT_MUTE_ON
)
437 muteval
|= FM_RX_RF_DEP_MODE
;
439 muteval
&= ~FM_RX_RF_DEP_MODE
;
442 ret
= fmc_send_cmd(fmdev
, MUTE_STATUS_SET
, REG_WR
, &payload
,
443 sizeof(payload
), NULL
, NULL
);
450 /* Configures mute mode (Mute Off/On/Attenuate) */
451 u32
fm_rx_set_mute_mode(struct fmdev
*fmdev
, u8 mute_mode_toset
)
456 if (fmdev
->rx
.mute_mode
== mute_mode_toset
)
459 org_state
= fmdev
->rx
.mute_mode
;
460 fmdev
->rx
.mute_mode
= mute_mode_toset
;
462 ret
= fm_config_rx_mute_reg(fmdev
);
464 fmdev
->rx
.mute_mode
= org_state
;
471 /* Gets RF dependent soft mute mode enable/disable status */
472 u32
fm_rx_get_rfdepend_softmute(struct fmdev
*fmdev
, u8
*curr_mute_mode
)
474 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
477 if (curr_mute_mode
== NULL
) {
478 fmerr("Invalid memory\n");
482 *curr_mute_mode
= fmdev
->rx
.rf_depend_mute
;
487 /* Sets RF dependent soft mute mode */
488 u32
fm_rx_set_rfdepend_softmute(struct fmdev
*fmdev
, u8 rfdepend_mute
)
493 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
496 if (rfdepend_mute
!= FM_RX_RF_DEPENDENT_MUTE_ON
&&
497 rfdepend_mute
!= FM_RX_RF_DEPENDENT_MUTE_OFF
) {
498 fmerr("Invalid RF dependent soft mute\n");
501 if (fmdev
->rx
.rf_depend_mute
== rfdepend_mute
)
504 org_state
= fmdev
->rx
.rf_depend_mute
;
505 fmdev
->rx
.rf_depend_mute
= rfdepend_mute
;
507 ret
= fm_config_rx_mute_reg(fmdev
);
509 fmdev
->rx
.rf_depend_mute
= org_state
;
516 /* Returns the signal strength level of current channel */
517 u32
fm_rx_get_rssi_level(struct fmdev
*fmdev
, u16
*rssilvl
)
523 if (rssilvl
== NULL
) {
524 fmerr("Invalid memory\n");
527 /* Read current RSSI level */
528 ret
= fmc_send_cmd(fmdev
, RSSI_LVL_GET
, REG_RD
, NULL
, 2,
529 &curr_rssi_lel
, &resp_len
);
533 *rssilvl
= be16_to_cpu(curr_rssi_lel
);
539 * Sets the signal strength level that once reached
540 * will stop the auto search process
542 u32
fm_rx_set_rssi_threshold(struct fmdev
*fmdev
, short rssi_lvl_toset
)
547 if (rssi_lvl_toset
< FM_RX_RSSI_THRESHOLD_MIN
||
548 rssi_lvl_toset
> FM_RX_RSSI_THRESHOLD_MAX
) {
549 fmerr("Invalid RSSI threshold level\n");
552 payload
= (u16
)rssi_lvl_toset
;
553 ret
= fmc_send_cmd(fmdev
, SEARCH_LVL_SET
, REG_WR
, &payload
,
554 sizeof(payload
), NULL
, NULL
);
558 fmdev
->rx
.rssi_threshold
= rssi_lvl_toset
;
563 /* Returns current RX RSSI threshold value */
564 u32
fm_rx_get_rssi_threshold(struct fmdev
*fmdev
, short *curr_rssi_lvl
)
566 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
569 if (curr_rssi_lvl
== NULL
) {
570 fmerr("Invalid memory\n");
574 *curr_rssi_lvl
= fmdev
->rx
.rssi_threshold
;
579 /* Sets RX stereo/mono modes */
580 u32
fm_rx_set_stereo_mono(struct fmdev
*fmdev
, u16 mode
)
585 if (mode
!= FM_STEREO_MODE
&& mode
!= FM_MONO_MODE
) {
586 fmerr("Invalid mode\n");
590 /* Set stereo/mono mode */
592 ret
= fmc_send_cmd(fmdev
, MOST_MODE_SET
, REG_WR
, &payload
,
593 sizeof(payload
), NULL
, NULL
);
597 /* Set stereo blending mode */
598 payload
= FM_STEREO_SOFT_BLEND
;
599 ret
= fmc_send_cmd(fmdev
, MOST_BLEND_SET
, REG_WR
, &payload
,
600 sizeof(payload
), NULL
, NULL
);
607 /* Gets current RX stereo/mono mode */
608 u32
fm_rx_get_stereo_mono(struct fmdev
*fmdev
, u16
*mode
)
614 fmerr("Invalid memory\n");
618 ret
= fmc_send_cmd(fmdev
, MOST_MODE_SET
, REG_RD
, NULL
, 2,
619 &curr_mode
, &resp_len
);
623 *mode
= be16_to_cpu(curr_mode
);
628 /* Choose RX de-emphasis filter mode (50us/75us) */
629 u32
fm_rx_set_deemphasis_mode(struct fmdev
*fmdev
, u16 mode
)
634 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
637 if (mode
!= FM_RX_EMPHASIS_FILTER_50_USEC
&&
638 mode
!= FM_RX_EMPHASIS_FILTER_75_USEC
) {
639 fmerr("Invalid rx de-emphasis mode (%d)\n", mode
);
644 ret
= fmc_send_cmd(fmdev
, DEMPH_MODE_SET
, REG_WR
, &payload
,
645 sizeof(payload
), NULL
, NULL
);
649 fmdev
->rx
.deemphasis_mode
= mode
;
654 /* Gets current RX de-emphasis filter mode */
655 u32
fm_rx_get_deemph_mode(struct fmdev
*fmdev
, u16
*curr_deemphasis_mode
)
657 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
660 if (curr_deemphasis_mode
== NULL
) {
661 fmerr("Invalid memory\n");
665 *curr_deemphasis_mode
= fmdev
->rx
.deemphasis_mode
;
670 /* Enable/Disable RX RDS */
671 u32
fm_rx_set_rds_mode(struct fmdev
*fmdev
, u8 rds_en_dis
)
676 if (rds_en_dis
!= FM_RDS_ENABLE
&& rds_en_dis
!= FM_RDS_DISABLE
) {
677 fmerr("Invalid rds option\n");
681 if (rds_en_dis
== FM_RDS_ENABLE
682 && fmdev
->rx
.rds
.flag
== FM_RDS_DISABLE
) {
683 /* Turn on RX RDS and RDS circuit */
684 payload
= FM_RX_PWR_SET_FM_AND_RDS_BLK_ON
;
685 ret
= fmc_send_cmd(fmdev
, POWER_SET
, REG_WR
, &payload
,
686 sizeof(payload
), NULL
, NULL
);
690 /* Clear and reset RDS FIFO */
691 payload
= FM_RX_RDS_FLUSH_FIFO
;
692 ret
= fmc_send_cmd(fmdev
, RDS_CNTRL_SET
, REG_WR
, &payload
,
693 sizeof(payload
), NULL
, NULL
);
697 /* Read flags - just to clear any pending interrupts. */
698 ret
= fmc_send_cmd(fmdev
, FLAG_GET
, REG_RD
, NULL
, 2,
703 /* Set RDS FIFO threshold value */
704 payload
= FM_RX_RDS_FIFO_THRESHOLD
;
705 ret
= fmc_send_cmd(fmdev
, RDS_MEM_SET
, REG_WR
, &payload
,
706 sizeof(payload
), NULL
, NULL
);
710 /* Enable RDS interrupt */
711 fmdev
->irq_info
.mask
|= FM_RDS_EVENT
;
712 payload
= fmdev
->irq_info
.mask
;
713 ret
= fmc_send_cmd(fmdev
, INT_MASK_SET
, REG_WR
, &payload
,
714 sizeof(payload
), NULL
, NULL
);
716 fmdev
->irq_info
.mask
&= ~FM_RDS_EVENT
;
720 /* Update our local flag */
721 fmdev
->rx
.rds
.flag
= FM_RDS_ENABLE
;
722 } else if (rds_en_dis
== FM_RDS_DISABLE
723 && fmdev
->rx
.rds
.flag
== FM_RDS_ENABLE
) {
724 /* Turn off RX RDS */
725 payload
= FM_RX_PWR_SET_FM_ON_RDS_OFF
;
726 ret
= fmc_send_cmd(fmdev
, POWER_SET
, REG_WR
, &payload
,
727 sizeof(payload
), NULL
, NULL
);
731 /* Reset RDS pointers */
732 fmdev
->rx
.rds
.last_blk_idx
= 0;
733 fmdev
->rx
.rds
.wr_idx
= 0;
734 fmdev
->rx
.rds
.rd_idx
= 0;
735 fm_rx_reset_station_info(fmdev
);
737 /* Update RDS local cache */
738 fmdev
->irq_info
.mask
&= ~(FM_RDS_EVENT
);
739 fmdev
->rx
.rds
.flag
= FM_RDS_DISABLE
;
745 /* Returns current RX RDS enable/disable status */
746 u32
fm_rx_get_rds_mode(struct fmdev
*fmdev
, u8
*curr_rds_en_dis
)
748 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
751 if (curr_rds_en_dis
== NULL
) {
752 fmerr("Invalid memory\n");
756 *curr_rds_en_dis
= fmdev
->rx
.rds
.flag
;
761 /* Sets RDS operation mode (RDS/RDBS) */
762 u32
fm_rx_set_rds_system(struct fmdev
*fmdev
, u8 rds_mode
)
767 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
770 if (rds_mode
!= FM_RDS_SYSTEM_RDS
&& rds_mode
!= FM_RDS_SYSTEM_RBDS
) {
771 fmerr("Invalid rds mode\n");
774 /* Set RDS operation mode */
775 payload
= (u16
)rds_mode
;
776 ret
= fmc_send_cmd(fmdev
, RDS_SYSTEM_SET
, REG_WR
, &payload
,
777 sizeof(payload
), NULL
, NULL
);
781 fmdev
->rx
.rds_mode
= rds_mode
;
786 /* Returns current RDS operation mode */
787 u32
fm_rx_get_rds_system(struct fmdev
*fmdev
, u8
*rds_mode
)
789 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
792 if (rds_mode
== NULL
) {
793 fmerr("Invalid memory\n");
797 *rds_mode
= fmdev
->rx
.rds_mode
;
802 /* Configures Alternate Frequency switch mode */
803 u32
fm_rx_set_af_switch(struct fmdev
*fmdev
, u8 af_mode
)
808 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
811 if (af_mode
!= FM_RX_RDS_AF_SWITCH_MODE_ON
&&
812 af_mode
!= FM_RX_RDS_AF_SWITCH_MODE_OFF
) {
813 fmerr("Invalid af mode\n");
816 /* Enable/disable low RSSI interrupt based on af_mode */
817 if (af_mode
== FM_RX_RDS_AF_SWITCH_MODE_ON
)
818 fmdev
->irq_info
.mask
|= FM_LEV_EVENT
;
820 fmdev
->irq_info
.mask
&= ~FM_LEV_EVENT
;
822 payload
= fmdev
->irq_info
.mask
;
823 ret
= fmc_send_cmd(fmdev
, INT_MASK_SET
, REG_WR
, &payload
,
824 sizeof(payload
), NULL
, NULL
);
828 fmdev
->rx
.af_mode
= af_mode
;
833 /* Returns Alternate Frequency switch status */
834 u32
fm_rx_get_af_switch(struct fmdev
*fmdev
, u8
*af_mode
)
836 if (fmdev
->curr_fmmode
!= FM_MODE_RX
)
839 if (af_mode
== NULL
) {
840 fmerr("Invalid memory\n");
844 *af_mode
= fmdev
->rx
.af_mode
;