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_v4l2.c
23 * Description: FM Driver for Connectivity chip of Broadcom Corporation.
24 * This file provides interfaces to V4L2 subsystem.
26 * This module registers with V4L2 subsystem as Radio
27 * data system interface (/dev/radio). During the registration,
28 * it will expose three set of function pointers to V4L2 subsystem.
30 * 1) File operation related API (open, close, read, write, poll...etc).
31 * 2) Set of V4L2 IOCTL complaint API.
33 ************************************************************************************/
34 #include <linux/export.h>
37 #include "fmdrv_v4l2.h"
38 #include "fmdrv_main.h"
40 #include <linux/fm_public.h>
41 #define FMDRV_V4L2_QUERYCTRL
42 #include "fmdrv_config.h"
44 /************************************************************************************
46 ************************************************************************************/
51 #define pr_info(fmt, arg...)
55 /************************************************************************************
57 ************************************************************************************/
59 static struct video_device *gradio_dev;
60 static unsigned char radio_disconnected;
62 static atomic_t v4l2_device_available = ATOMIC_INIT(1);
64 /************************************************************************************
65 ** Forward function declarations
66 ************************************************************************************/
68 static int fm_v4l2_vidioc_s_hw_freq_seek(struct file *, void *,
69 const struct v4l2_hw_freq_seek *);
71 /************************************************************************************
73 ************************************************************************************/
74 /*****************************************************************************
75 ** V4L2 RADIO (/dev/radioX) device file operation interfaces
76 *****************************************************************************/
78 /* Read RX RDS data */
79 static ssize_t fm_v4l2_fops_read(struct file *file, char __user * buf,
80 size_t count, loff_t *ppos)
83 struct fmdrv_ops *fmdev;
85 fmdev = video_drvdata(file);
87 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
89 if (!radio_disconnected) {
90 pr_err("(fmdrv): FM device is already disconnected\n");
95 if (mutex_lock_interruptible(&fmdev->mutex))
98 /* Copy RDS data from the cicular buffer to userspace */
100 fmc_transfer_rds_from_cbuff(fmdev, file, buf, count);
101 mutex_unlock(&fmdev->mutex);
105 /* Write RDS data. Since FM TX is not supported, return EINVAL
107 static ssize_t fm_v4l2_fops_write(struct file *file, const char __user * buf,
108 size_t count, loff_t *ppos)
113 /* Handle Poll event for "/dev/radioX" device.*/
114 static unsigned int fm_v4l2_fops_poll(struct file *file,
115 struct poll_table_struct *pts)
118 struct fmdrv_ops *fmdev;
120 pr_info("(fm_rds): %s, f_count %ld\n", __func__, file_count(file));
122 fmdev = video_drvdata(file);
123 mutex_lock(&fmdev->mutex);
124 /* Check if RDS data is available */
125 ret = fm_rx_is_rds_data_available(fmdev, file, pts);
126 mutex_unlock(&fmdev->mutex);
128 return POLLIN | POLLRDNORM;
132 static ssize_t show_fmrx_comp_scan(struct device *dev,
133 struct device_attribute *attr, char *buf)
135 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
137 /* Chip doesn't support complete scan for weather band */
138 if (fmdev->rx.region.fm_band == FM_BAND_WEATHER)
141 return sprintf(buf, "%d\n", fmdev->rx.no_of_chans);
144 static ssize_t store_fmrx_comp_scan(struct device *dev,
145 struct device_attribute *attr, char *buf, size_t size)
148 unsigned long comp_scan;
149 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
151 /* Chip doesn't support complete scan for weather band */
152 if (fmdev->rx.region.fm_band == FM_BAND_WEATHER)
155 if (kstrtoul(buf, 0, &comp_scan))
158 ret = fm_rx_seek_station(fmdev, 1, 0);// FM_CHANNEL_SPACING_200KHZ, comp_scan);
160 pr_err("(fmdrv) %s(): RX complete scan failed - %d\n",
163 if (comp_scan == COMP_SCAN_READ)
164 return (size_t) fmdev->rx.no_of_chans;
169 static ssize_t show_fmrx_deemphasis(struct device *dev,
170 struct device_attribute *attr, char *buf)
172 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
174 return sprintf(buf, "%d\n", (fmdev->rx.region.deemphasis==
175 FM_RX_EMPHASIS_FILTER_50_USEC) ? 50 : 75);
178 static ssize_t store_fmrx_deemphasis(struct device *dev,
179 struct device_attribute *attr, char *buf, size_t size)
182 unsigned char deemph_mode;
183 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
185 if (kstrtoul(buf, 0, (long unsigned int*)&deemph_mode))
188 ret = fm_rx_config_deemphasis(fmdev,deemph_mode);
190 pr_err("(fmdrv) %s(): Failed to set De-emphasis Mode 0x%x\n",
191 __func__, deemph_mode);
198 static ssize_t show_fmrx_af(struct device *dev,
199 struct device_attribute *attr, char *buf)
201 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
203 return sprintf(buf, "%d\n", fmdev->rx.af_mode);
206 static ssize_t store_fmrx_af(struct device *dev,
207 struct device_attribute *attr, char *buf, size_t size)
210 unsigned long af_mode;
211 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
213 if (kstrtoul(buf, 0, &af_mode))
216 if (af_mode < 0 || af_mode > 1)
219 ret = fm_rx_set_af_switch(fmdev, af_mode);
221 pr_err("(fmdrv) %s(): Failed to set AF Switch %lu\n",
229 static ssize_t show_fmrx_band(struct device *dev,
230 struct device_attribute *attr, char *buf)
232 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
234 return sprintf(buf, "%d\n", fmdev->rx.region.fm_band);
237 static ssize_t store_fmrx_band(struct device *dev,
238 struct device_attribute *attr, char *buf, size_t size)
241 unsigned long fm_band;
242 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
243 if (kstrtoul(buf, 0, &fm_band))
245 pr_info("(fmdrv) %s(): store_fmrx_band In fm_band %lu\n",
248 if (fm_band < FM_BAND_EUROPE_US || fm_band > FM_BAND_WEATHER)
251 ret = fm_rx_set_region(fmdev, fm_band);
253 pr_err("(fmdrv) %s(): Failed to set FM Band %lu\n",
261 static ssize_t show_fmrx_Frequency_Offset_lvl (struct device *dev,
262 struct device_attribute *attr, char *buf) { return 0;}
264 static ssize_t show_fmrx_Noise_Power_lvl(struct device *dev,
265 struct device_attribute *attr, char *buf){return 0;}
267 static ssize_t show_fmrx_Pilot_Power_lvl(struct device *dev,
268 struct device_attribute *attr, char *buf){return 0;}
270 static ssize_t store_fmrx_Frequency_Offset_lvl(struct device *dev,
271 struct device_attribute *attr, char *buf, size_t size)
274 unsigned long Frequency_Offset_lvl;
275 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
277 if (kstrtoul(buf, 0, &Frequency_Offset_lvl))
280 ret = fm_rx_set_Frequency_Offset_threshold(fmdev, Frequency_Offset_lvl);
282 pr_err("Failed to set Frequency_Offset level\n");
289 static ssize_t store_fmrx_Noise_Power_lvl(struct device *dev,
290 struct device_attribute *attr, char *buf, size_t size)
293 unsigned long Noise_Power_lvl;
294 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
296 if (kstrtoul(buf, 0, &Noise_Power_lvl))
299 ret = fm_rx_set_Noise_Power_threshold(fmdev, Noise_Power_lvl);
301 pr_err("Failed to set Noise_Power level\n");
308 static ssize_t store_fmrx_Pilot_Power_lvl(struct device *dev,
309 struct device_attribute *attr, char *buf, size_t size)
312 unsigned long Pilot_Power_lvl;
313 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
315 if (kstrtoul(buf, 0, &Pilot_Power_lvl))
318 ret = fm_rx_set_Pilot_Power_threshold(fmdev, Pilot_Power_lvl);
320 pr_err("Failed to set Pilot_Power level\n");
328 static ssize_t show_fmrx_rssi_lvl(struct device *dev,
329 struct device_attribute *attr, char *buf)
331 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
333 return sprintf(buf, "%d\n", fmdev->rx.curr_rssi_threshold);
335 static ssize_t store_fmrx_rssi_lvl(struct device *dev,
336 struct device_attribute *attr, char *buf, size_t size)
339 unsigned long rssi_lvl;
340 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
342 if (kstrtoul(buf, 0, &rssi_lvl))
345 ret = fm_rx_set_rssi_threshold(fmdev, rssi_lvl);
347 pr_err("Failed to set RSSI level\n");
354 static ssize_t show_fmrx_snr_lvl(struct device *dev,
355 struct device_attribute *attr, char *buf)
357 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
359 return sprintf(buf, "%d\n", fmdev->rx.curr_snr_threshold);
362 static ssize_t store_fmrx_snr_lvl(struct device *dev,
363 struct device_attribute *attr, char *buf, size_t size)
366 unsigned long snr_lvl;
367 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
369 if (kstrtoul(buf, 0, &snr_lvl))
372 ret = fm_rx_set_snr_threshold(fmdev, snr_lvl);
374 pr_err("(fmdrv) %s(): Failed to set SNR level %lu\n",
383 static ssize_t show_fmrx_curr_snr(struct device *dev,
384 struct device_attribute *attr, char *buf)
387 unsigned int curr_snr = 0;
388 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
390 if(atomic_read(&v4l2_device_available) != 1) {
391 /* only request when it is currently used */
392 ret = fm_rx_get_snr(fmdev,&curr_snr);
396 pr_err("(fmdrv) %s(): fail to get current SNR\n",
401 return sprintf(buf, "%d\n", curr_snr);
404 static ssize_t store_fmrx_curr_snr(struct device *dev,
405 struct device_attribute *attr, char *buf, size_t size)
407 pr_info("nothing to do for store\n");
413 static ssize_t show_fmrx_cos_th(struct device *dev,
414 struct device_attribute *attr, char *buf)
416 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
418 return sprintf(buf, "%d\n", fmdev->rx.curr_cos_threshold);
421 static ssize_t store_fmrx_cos_th(struct device *dev,
422 struct device_attribute *attr, char *buf, size_t size)
426 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
428 if (kstrtol(buf, 0, &cos))
431 ret = fm_rx_set_cos_threshold(fmdev, cos);
433 pr_err("(fmdrv) %s(): Failed to set COS level\n",
442 static ssize_t show_fmrx_channel_space(struct device *dev,
443 struct device_attribute *attr, char *buf)
446 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
448 switch( fmdev->rx.sch_step){
450 chl_space= CHL_SPACE_ONE;
453 chl_space= CHL_SPACE_TWO;
456 chl_space= CHL_SPACE_FOUR;
459 chl_space= CHL_SPACE_TWO;
462 return sprintf(buf, "%d\n",chl_space);
465 static ssize_t store_fmrx_channel_space(struct device *dev,
466 struct device_attribute *attr, char *buf, size_t size)
469 unsigned long chl_spacing,chl_step;
470 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
472 if (kstrtoul(buf, 0, &chl_spacing))
474 switch( chl_spacing){
476 chl_step= FM_STEP_50KHZ;
479 chl_step= FM_STEP_100KHZ;
482 chl_step= FM_STEP_200KHZ;
485 chl_step= FM_STEP_100KHZ;
487 ret = fmc_set_scan_step(fmdev, chl_step);
489 pr_err("(fmdrv) %s(): Failed to set channel spacing\n",
497 static ssize_t show_fmrx_start_snr(struct device *dev,
498 struct device_attribute *attr, char *buf)
500 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
502 return sprintf(buf, "%d\n", fmdev->softmute_blend_config.start_snr);
505 static ssize_t store_fmrx_start_snr(struct device *dev,
506 struct device_attribute *attr, char *buf, size_t size)
508 unsigned long start_snr;
509 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
511 if (kstrtoul(buf, 0, &start_snr))
514 if (start_snr < FM_START_SNR_MIN || start_snr > FM_START_SNR_MAX)
517 fmdev->softmute_blend_config.start_snr = start_snr;
522 static ssize_t show_fmrx_stop_snr(struct device *dev,
523 struct device_attribute *attr, char *buf)
525 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
527 return sprintf(buf, "%d\n", fmdev->softmute_blend_config.stop_snr);
530 static ssize_t store_fmrx_stop_snr(struct device *dev,
531 struct device_attribute *attr, char *buf, size_t size)
533 unsigned long stop_snr;
534 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
536 if (kstrtoul(buf, 0, &stop_snr))
539 if (stop_snr < FM_STOP_SNR_MIN || stop_snr > FM_STOP_SNR_MAX)
542 fmdev->softmute_blend_config.stop_snr = stop_snr;
547 static ssize_t show_fmrx_start_rssi(struct device *dev,
548 struct device_attribute *attr, char *buf)
550 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
552 return sprintf(buf, "%d\n", fmdev->softmute_blend_config.start_rssi);
555 static ssize_t store_fmrx_start_rssi(struct device *dev,
556 struct device_attribute *attr, char *buf, size_t size)
559 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
561 if (kstrtol(buf, 0, &start_rssi))
564 if (start_rssi < FM_START_RSSI_MIN || start_rssi > FM_START_RSSI_MAX)
567 fmdev->softmute_blend_config.start_rssi = start_rssi;
572 static ssize_t show_fmrx_stop_rssi(struct device *dev,
573 struct device_attribute *attr, char *buf)
575 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
577 return sprintf(buf, "%d\n", fmdev->softmute_blend_config.stop_rssi);
580 static ssize_t store_fmrx_stop_rssi(struct device *dev,
581 struct device_attribute *attr, char *buf, size_t size)
583 signed long stop_rssi;
584 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
586 if (kstrtol(buf, 0, &stop_rssi))
589 if (stop_rssi < FM_STOP_RSSI_MIN || stop_rssi > FM_STOP_RSSI_MAX)
592 fmdev->softmute_blend_config.stop_rssi = stop_rssi;
597 static ssize_t show_fmrx_start_mute(struct device *dev,
598 struct device_attribute *attr, char *buf)
600 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
602 return sprintf(buf, "%d\n", fmdev->softmute_blend_config.start_mute);
606 static ssize_t store_fmrx_start_mute(struct device *dev,
607 struct device_attribute *attr, char *buf, size_t size)
609 unsigned long start_mute;
610 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
612 if (kstrtoul(buf, 0, &start_mute))
615 fmdev->softmute_blend_config.start_mute = start_mute;
620 static ssize_t show_fmrx_stop_atten(struct device *dev,
621 struct device_attribute *attr, char *buf)
623 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
625 return sprintf(buf, "%d\n", fmdev->softmute_blend_config.stop_atten);
628 static ssize_t store_fmrx_stop_atten(struct device *dev,
629 struct device_attribute *attr, char *buf, size_t size)
631 signed long stop_atten;
632 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
634 if (kstrtol(buf, 0, &stop_atten))
637 if (stop_atten < FM_STOP_ATTEN_MIN || stop_atten > FM_STOP_ATTEN_MAX)
640 fmdev->softmute_blend_config.stop_atten = stop_atten;
645 static ssize_t show_fmrx_mute_rate(struct device *dev,
646 struct device_attribute *attr, char *buf)
648 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
650 return sprintf(buf, "%d\n", fmdev->softmute_blend_config.mute_rate);
653 static ssize_t store_fmrx_mute_rate(struct device *dev,
654 struct device_attribute *attr, char *buf, size_t size)
656 unsigned long mute_rate;
657 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
659 if (kstrtoul(buf, 0, &mute_rate))
662 if (mute_rate < FM_MUTE_RATE_MIN || mute_rate > FM_MUTE_RATE_MAX)
665 fmdev->softmute_blend_config.mute_rate = mute_rate;
670 static ssize_t show_fmrx_snr40(struct device *dev,
671 struct device_attribute *attr, char *buf)
673 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
675 return sprintf(buf, "%d\n", fmdev->softmute_blend_config.snr40);
678 static ssize_t store_fmrx_snr40(struct device *dev,
679 struct device_attribute *attr, char *buf, size_t size)
682 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
684 if (kstrtol(buf, 0, &snr40))
687 if (snr40 < FM_SNR40_MIN || snr40 > FM_SNR40_MAX)
690 fmdev->softmute_blend_config.snr40 = snr40;
696 static ssize_t show_fmrx_set_blndmute(struct device *dev,
697 struct device_attribute *attr, char *buf)
699 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
701 return sprintf(buf, "%d\n", fmdev->set_blndmute);
704 static ssize_t store_fmrx_set_blndmute(struct device *dev,
705 struct device_attribute *attr, char *buf, size_t size)
708 unsigned long set_blndmute;
709 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
711 if (kstrtoul(buf, 0, &set_blndmute))
714 if (set_blndmute < 0 || set_blndmute > 1)
717 ret = fm_rx_set_cfg_blnd_mute(fmdev,set_blndmute);
720 pr_err("(fmdrv) %s(): Failed to set softemute and audio blending\n",
729 static ssize_t show_fmrx_search_abort(struct device *dev,
730 struct device_attribute *attr, char *buf)
732 return sprintf(buf, "%s\n", "abort search read no impact.");
735 static ssize_t store_fmrx_search_abort(struct device *dev,
736 struct device_attribute *attr, char *buf, size_t size)
738 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
740 fm_rx_seek_station_abort(fmdev);
746 static ssize_t show_fmrx_status(struct device *dev,
747 struct device_attribute *attr, char *buf)
749 return sprintf(buf, "%d\n", radio_disconnected);
752 static ssize_t store_fmrx_status(struct device *dev,
753 struct device_attribute *attr, char *buf, size_t size)
755 pr_info("(fmdrv) %s(): no effect\n", __func__);
759 /* structures specific for sysfs entries
760 * FM GUI app belongs to group "fmradio", these sysfs entries belongs to "root",
761 * but GUI app needs both read and write permissions to these sysfs entires for
762 * below features, so these entries got permission "666"
765 /* To start FM RX complete scan*/
766 static struct kobj_attribute v4l2_fmrx_comp_scan =
767 __ATTR(fmrx_comp_scan, 0666, (void *)show_fmrx_comp_scan,
768 (void *)store_fmrx_comp_scan);
770 /* To Set De-Emphasis filter mode */
771 static struct kobj_attribute v4l2_fmrx_deemph_mode =
772 __ATTR(fmrx_deemph_mode, 0666, (void *)show_fmrx_deemphasis,
773 (void *)store_fmrx_deemphasis);
775 /* To Enable/Disable FM RX RDS AF feature */
776 static struct kobj_attribute v4l2_fmrx_rds_af =
777 __ATTR(fmrx_rds_af, 0666, (void *)show_fmrx_af, (void *)store_fmrx_af);
779 /* To switch between Japan/US bands */
780 static struct kobj_attribute v4l2_fmrx_band =
781 __ATTR(fmrx_band, 0666, (void *)show_fmrx_band, (void *)store_fmrx_band);
783 /* To set the desired FM reception RSSI level */
784 static struct kobj_attribute v4l2_fmrx_rssi_lvl =
785 __ATTR(fmrx_rssi_lvl, 0666, (void *) show_fmrx_rssi_lvl,
786 (void *)store_fmrx_rssi_lvl);
788 /* To set the desired FM reception SNR level */
789 static struct kobj_attribute v4l2_fmrx_snr_lvl =
790 __ATTR(fmrx_snr_lvl, 0666, (void *) show_fmrx_snr_lvl,
791 (void *)store_fmrx_snr_lvl);
793 /* To read current SNR level */
794 static struct kobj_attribute v4l2_fmrx_curr_snr =
795 __ATTR(fmrx_curr_snr, 0666, (void *) show_fmrx_curr_snr,
796 (void *)store_fmrx_curr_snr);
798 /* To set COS value */
799 static struct kobj_attribute v4l2_fmrx_cos_th =
800 __ATTR(fmrx_cos_th, 0666, (void *) show_fmrx_cos_th,
801 (void *)store_fmrx_cos_th);
803 /* To set the desired channel spacing */
804 static struct kobj_attribute v4l2_fmrx_channel_space =
805 __ATTR(fmrx_chl_lvl, 0666, (void *) show_fmrx_channel_space,
806 (void *)store_fmrx_channel_space);
808 /* To set start snr */
809 static struct kobj_attribute v4l2_fmrx_start_snr =
810 __ATTR(fmrx_start_snr, 0666, (void *) show_fmrx_start_snr,
811 (void *)store_fmrx_start_snr);
813 /* To set stop snr */
814 static struct kobj_attribute v4l2_fmrx_stop_snr =
815 __ATTR(fmrx_stop_snr, 0666, (void *) show_fmrx_stop_snr,
816 (void *)store_fmrx_stop_snr);
818 /* To set start rssi */
819 static struct kobj_attribute v4l2_fmrx_start_rssi =
820 __ATTR(fmrx_start_rssi, 0666, (void *) show_fmrx_start_rssi,
821 (void *)store_fmrx_start_rssi);
823 /* To set stop rssi */
824 static struct kobj_attribute v4l2_fmrx_stop_rssi =
825 __ATTR(fmrx_stop_rssi, 0666, (void *) show_fmrx_stop_rssi,
826 (void *)store_fmrx_stop_rssi);
829 /* To set start mute */
830 static struct kobj_attribute v4l2_fmrx_start_mute =
831 __ATTR(fmrx_start_mute, 0666, (void *) show_fmrx_start_mute,
832 (void *)store_fmrx_start_mute);
834 /* To set stop atten */
835 static struct kobj_attribute v4l2_fmrx_stop_atten =
836 __ATTR(fmrx_stop_atten, 0666, (void *) show_fmrx_stop_atten,
837 (void *)store_fmrx_stop_atten);
840 /* To set mute rate */
841 static struct kobj_attribute v4l2_fmrx_mute_rate =
842 __ATTR(fmrx_mute_rate, 0666, (void *) show_fmrx_mute_rate,
843 (void *)store_fmrx_mute_rate);
846 static struct kobj_attribute v4l2_fmrx_snr40 =
847 __ATTR(fmrx_snr40, 0666, (void *) show_fmrx_snr40,
848 (void *)store_fmrx_snr40);
850 /* To start blendmute */
851 static struct kobj_attribute v4l2_fmrx_set_blndmute =
852 __ATTR(fmrx_set_blndmute, 0666, (void *) show_fmrx_set_blndmute,
853 (void *)store_fmrx_set_blndmute);
856 /* To abort search */
857 static struct kobj_attribute v4l2_fmrx_search_abort =
858 __ATTR(fmrx_search_abort, 0666, (void *) show_fmrx_search_abort,
859 (void *)store_fmrx_search_abort);
861 /* To check radio status */
862 static struct kobj_attribute v4l2_fmrx_status =
863 __ATTR(fmrx_status, 0666, (void *) show_fmrx_status,
864 (void *)store_fmrx_status);
866 static struct kobj_attribute v4l2_fmrx_freq_offset =
867 __ATTR(fmrx_freq_offset, 0666, (void *) show_fmrx_Frequency_Offset_lvl,
868 (void *)store_fmrx_Frequency_Offset_lvl);
870 static struct kobj_attribute v4l2_fmrx_noise_power =
871 __ATTR(fmrx_noise_power, 0666, (void *) show_fmrx_Noise_Power_lvl,
872 (void *)store_fmrx_Noise_Power_lvl);
874 static struct kobj_attribute v4l2_fmrx_pilot_power =
875 __ATTR(fmrx_pilot_power, 0666, (void *) show_fmrx_Pilot_Power_lvl,
876 (void *)store_fmrx_Pilot_Power_lvl);
878 static struct attribute *v4l2_fm_attrs[] = {
879 &v4l2_fmrx_comp_scan.attr,
880 &v4l2_fmrx_deemph_mode.attr,
881 &v4l2_fmrx_rds_af.attr,
882 &v4l2_fmrx_band.attr,
883 &v4l2_fmrx_rssi_lvl.attr,
884 &v4l2_fmrx_snr_lvl.attr,
885 &v4l2_fmrx_curr_snr.attr,
886 &v4l2_fmrx_cos_th.attr,
887 &v4l2_fmrx_channel_space.attr,
888 &v4l2_fmrx_start_snr.attr,
889 &v4l2_fmrx_stop_snr.attr,
890 &v4l2_fmrx_start_rssi.attr,
891 &v4l2_fmrx_stop_rssi.attr,
892 &v4l2_fmrx_start_mute.attr,
893 &v4l2_fmrx_stop_atten.attr,
894 &v4l2_fmrx_mute_rate.attr,
895 &v4l2_fmrx_snr40.attr,
896 &v4l2_fmrx_set_blndmute.attr,
897 &v4l2_fmrx_search_abort.attr,
898 &v4l2_fmrx_status.attr,
899 &v4l2_fmrx_freq_offset.attr,
900 &v4l2_fmrx_noise_power.attr,
901 &v4l2_fmrx_pilot_power.attr,
904 static struct attribute_group v4l2_fm_attr_grp = {
905 .attrs = v4l2_fm_attrs,
908 /* Handle open request for "/dev/radioX" device.
909 * Start with FM RX mode as default.
911 static int fm_v4l2_fops_open(struct file *file)
914 unsigned char option;
915 struct fmdrv_ops *fmdev = NULL;
916 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
917 /* Don't allow multiple open */
918 if(!atomic_dec_and_test(&v4l2_device_available))
920 atomic_inc(&v4l2_device_available);
921 pr_err("(fmdrv): FM device is already opened .. v4l2 device busy\n");
925 if (radio_disconnected) {
926 pr_err("(fmdrv): FM device is already opened .. radio not disconnected\n");
930 fmdev = video_drvdata(file);
932 if (mutex_lock_interruptible(&fmdev->mutex))
935 /* initialize the driver */
936 ret = fmc_prepare(fmdev);
938 atomic_inc(&v4l2_device_available);
939 pr_err("(fmdrv): Unable to prepare FM CORE");
940 mutex_unlock(&fmdev->mutex);
944 radio_disconnected = 1;
946 ret = fmc_set_mode(fmdev, FM_MODE_RX); /* As of now, support only Rx */
948 radio_disconnected = 0;
950 atomic_inc(&v4l2_device_available);
951 pr_err("(fmdrv): Unable to enable FM");
952 mutex_unlock(&fmdev->mutex);
956 #if(defined(DEF_V4L2_FM_WORLD_REGION) && DEF_V4L2_FM_WORLD_REGION == FM_REGION_NA)
957 option = FM_REGION_NA | FM_RBDS_BIT;
958 #elif(defined(DEF_V4L2_FM_WORLD_REGION) && DEF_V4L2_FM_WORLD_REGION == FM_REGION_EUR)
959 option = FM_REGION_EUR | FM_RDS_BIT;
960 #elif(defined(DEF_V4L2_FM_WORLD_REGION) && DEF_V4L2_FM_WORLD_REGION == FM_REGION_JP)
961 option = FM_REGION_JP | FM_RDS_BIT;
967 pr_info("(fmdrv): FM Enable INIT option : %d\n", option);
968 ret = fmc_enable(fmdev, option);
970 radio_disconnected = 0;
972 atomic_inc(&v4l2_device_available);
973 pr_err("(fmdrv): Unable to enable FM\n");
974 mutex_unlock(&fmdev->mutex);
979 pr_info("(fmdrv): FM Set Audio mode option : %d\n", DEF_V4L2_FM_AUDIO_MODE);
980 ret = fmc_set_audio_mode(fmdev, DEF_V4L2_FM_AUDIO_MODE);
982 radio_disconnected = 0;
984 atomic_inc(&v4l2_device_available);
985 pr_err("(fmdrv): Error setting Audio mode during FM enable operation\n");
986 mutex_unlock(&fmdev->mutex);
992 pr_info("(fmdrv): FM Set Audio path option : %d\n", DEF_V4L2_FM_AUDIO_PATH);
993 ret = fm_rx_config_audio_path(fmdev, DEF_V4L2_FM_AUDIO_PATH);
995 radio_disconnected = 0;
997 atomic_inc(&v4l2_device_available);
998 pr_err("(fmdrv): Error setting Audio path during FM enable operation\n");
999 mutex_unlock(&fmdev->mutex);
1004 mutex_unlock(&fmdev->mutex);
1008 /* Handle close request for "/dev/radioX" device.
1010 static int fm_v4l2_fops_release(struct file *file)
1013 struct fmdrv_ops *fmdev;
1014 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1016 fmdev = video_drvdata(file);
1018 if (!radio_disconnected) {
1019 pr_info("(fmdrv):FM dev already closed, close called again?\n");
1023 mutex_lock(&fmdev->mutex);
1025 /* First set audio path to NONE */
1026 ret = fm_rx_config_audio_path(fmdev, FM_AUDIO_NONE);
1028 pr_err("(fmdrv): Failed to set audio path to FM_AUDIO_NONE\n");
1032 /* Now disable FM */
1033 ret = fmc_turn_fm_off(fmdev);
1036 pr_err("(fmdrv): Error disabling FM. Continuing to release FM core..\n");
1040 ret = fmc_release(fmdev);
1043 pr_err("(fmdrv): FM CORE release failed\n");
1044 radio_disconnected = 0;
1045 atomic_inc(&v4l2_device_available);
1046 mutex_unlock(&fmdev->mutex);
1050 radio_disconnected = 0;
1051 atomic_inc(&v4l2_device_available);
1052 mutex_unlock(&fmdev->mutex);
1053 pr_info("(fmdrv): %s, E\n", __func__);
1057 /*****************************************************************************
1058 ** V4L2 RADIO (/dev/radioX) device IOCTL interfaces
1059 *****************************************************************************/
1062 * Function to query the driver capabilities
1064 static int fm_v4l2_vidioc_querycap(struct file *file, void *priv,
1065 struct v4l2_capability *capability)
1067 struct fmdrv_ops *fmdev;
1069 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1070 fmdev = video_drvdata(file);
1072 strlcpy(capability->driver, FM_DRV_NAME, sizeof(capability->driver));
1073 strlcpy(capability->card, FM_DRV_CARD_SHORT_NAME,
1074 sizeof(capability->card));
1075 sprintf(capability->bus_info, "UART");
1076 capability->version = FM_DRV_RADIO_VERSION;
1077 capability->capabilities = fmdev->device_info.capabilities;
1082 * Function to query the driver control params
1084 static int fm_v4l2_vidioc_queryctrl(struct file *file, void *priv,
1085 struct v4l2_queryctrl *qc)
1090 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1091 if (qc->id < V4L2_CID_BASE)
1094 /* Search control ID and copy its properties */
1095 for (index = 0; index < NO_OF_ENTRIES_IN_ARRAY(fmdrv_v4l2_queryctrl);\
1097 if (qc->id && qc->id == fmdrv_v4l2_queryctrl[index].id) {
1098 memcpy(qc, &(fmdrv_v4l2_queryctrl[index]), sizeof(*qc));
1107 * Function to get the driver control params. Called
1108 * by user-space via IOCTL call
1110 static int fm_v4l2_vidioc_g_ctrl(struct file *file, void *priv,
1111 struct v4l2_control *ctrl)
1114 unsigned short curr_vol;
1115 unsigned char curr_mute_mode;
1116 struct fmdrv_ops *fmdev;
1118 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1119 fmdev = video_drvdata(file);
1122 case V4L2_CID_AUDIO_MUTE: /* get mute mode */
1123 ret = fm_rx_get_mute_mode(fmdev, &curr_mute_mode);
1126 ctrl->value = curr_mute_mode;
1129 case V4L2_CID_AUDIO_VOLUME: /* get volume */
1130 pr_debug ("(fmdrv): V4L2_CID_AUDIO_VOLUME get\n");
1131 ret = fm_rx_get_volume(fmdev, &curr_vol);
1134 ctrl->value = curr_vol;
1138 pr_debug("(fmdrv): Unhandled IOCTL for get Control\n");
1146 * Function to Set the driver control params. Called
1147 * by user-space via IOCTL call
1149 static int fm_v4l2_vidioc_s_ctrl(struct file *file, void *priv,
1150 struct v4l2_control *ctrl)
1153 struct fmdrv_ops *fmdev;
1155 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1156 fmdev = video_drvdata(file);
1159 case V4L2_CID_AUDIO_MUTE: /* set mute */
1160 ret = fm_rx_set_mute_mode(fmdev, (unsigned char)ctrl->value);
1165 case V4L2_CID_AUDIO_VOLUME: /* set volume */
1166 pr_info ("(fmdrv): V4L2_CID_AUDIO_VOLUME set : %d\n", ctrl->value);
1167 ret = fm_rx_set_volume(fmdev, (unsigned short)ctrl->value);
1169 pr_info ("(fmdrv): V4L2_CID_AUDIO_VOLUME ret : %d\n", ret);
1175 pr_debug("(fmdrv): Unhandled IOCTL for set Control\n");
1183 * Function to get the driver audio params. Called
1184 * by user-space via IOCTL call
1186 static int fm_v4l2_vidioc_g_audio(struct file *file, void *priv,
1187 struct v4l2_audio *audio)
1189 memset(audio, 0, sizeof(*audio));
1191 strcpy(audio->name, "Radio");
1192 /* For FM Radio device, the audio capability should always return
1193 V4L2_AUDCAP_STEREO */
1194 audio->capability = V4L2_AUDCAP_STEREO;
1199 * Function to set the driver audio params. Called
1200 * by user-space via IOCTL call
1202 static int fm_v4l2_vidioc_s_audio(struct file *file, void *priv,
1203 const struct v4l2_audio *audio)
1205 if (audio->index != 0)
1210 /* Get tuner attributes. This IOCTL call will return attributes like tuner type,
1211 upper/lower frequency, audio mode, RSSI value and AF channel */
1212 static int fm_v4l2_vidioc_g_tuner(struct file *file, void *priv,
1213 struct v4l2_tuner *tuner)
1215 unsigned short curr_rssi;
1216 unsigned int high = 0, low = 0;
1218 struct fmdrv_ops *fmdev;
1220 if (tuner->index != 0)
1223 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1225 fmdev = video_drvdata(file);
1226 strcpy(tuner->name, "FM");
1227 tuner->type = fmdev->device_info.type;
1228 /* The V4L2 specification defines all frequencies in unit of 62.5 kHz */
1229 ret = fm_rx_get_band_frequencies(fmdev, &low, &high);
1230 tuner->rangelow = (low * 100000)/625;
1231 tuner->rangehigh = (high * 100000)/625;
1233 tuner->audmode = ((fmdev->rx.audio_mode == FM_AUTO_MODE) ?
1234 V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO);
1235 tuner->capability = fmdev->device_info.tuner_capability;
1236 tuner->rxsubchans = fmdev->device_info.rxsubchans;
1238 ret = fm_rx_read_curr_rssi_freq(fmdev, TRUE);
1239 curr_rssi = fmdev->rx.curr_rssi;
1241 pr_info ("(fmdrv): fm_v4l2_vidioc_g_tuner curr_rssi : %d\n", curr_rssi);
1243 /* This is absolute value of negative dBm on SC2331 chipset */
1244 tuner->signal = curr_rssi;
1249 /* Set tuner attributes. This IOCTL call will set attributes like
1250 upper/lower frequency, audio mode.
1252 static int fm_v4l2_vidioc_s_tuner(struct file *file, void *priv,
1253 const struct v4l2_tuner *tuner)
1256 struct fmdrv_ops *fmdev;
1257 unsigned short high_freq, low_freq;
1258 unsigned short mode;
1259 if (tuner->index != 0)
1262 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1264 fmdev = video_drvdata(file);
1266 /* TODO : Figure out how to set the region based on lower/upper freq */
1267 /* The V4L2 specification defines all frequencies in unit of 62.5 kHz.
1268 Hence translate the incoming tuner band frequencies to controller
1269 recognized values. Set only if rangelow/rangehigh is not 0*/
1270 if(tuner->rangelow != 0 && tuner->rangehigh != 0)
1272 pr_info("(fmdrv) rangelow:%d rangehigh:%d\n", tuner->rangelow, tuner->rangehigh);
1273 low_freq = ((tuner->rangelow) * 625)/100000;
1274 high_freq= ((tuner->rangehigh) * 625)/100000;
1275 pr_info("(fmdrv) low_freq:%d high_freq:%d\n", low_freq, high_freq);
1276 ret = fm_rx_set_band_frequencies(fmdev, low_freq, high_freq);
1281 /* Map V4L2 stereo/mono macro to Broadcom controller equivalent audio mode */
1282 mode = (tuner->audmode == V4L2_TUNER_MODE_STEREO) ?
1283 FM_AUTO_MODE : FM_MONO_MODE;
1285 ret = fmc_set_audio_mode(fmdev, mode);
1291 /* Get tuner or modulator radio frequency */
1292 static int fm_v4l2_vidioc_g_frequency(struct file *file, void *priv,
1293 struct v4l2_frequency *freq)
1296 struct fmdrv_ops *fmdev;
1298 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1299 fmdev = video_drvdata(file);
1300 ret = fmc_get_frequency(fmdev, &freq->frequency);
1301 /* Translate the controller frequency to V4L2 specific frequency
1302 (frequencies in unit of 62.5 Hz):
1303 x = (y * 100) * 1000/62.5 = y * 160 */
1304 freq->frequency = (freq->frequency * 160);
1310 /* Set tuner or modulator radio frequency, this is tune channel */
1311 static int fm_v4l2_vidioc_s_frequency(struct file *file, void *priv,
1312 const struct v4l2_frequency *freq)
1315 struct fmdrv_ops *fmdev;
1316 unsigned int frequency;
1318 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1319 fmdev = video_drvdata(file);
1320 /* Translate the incoming tuner band frequencies
1321 (frequencies in unit of 62.5 Hz to controller
1322 recognized values. x = y * (62.5/1000000) * 100 = y / 160 */
1323 pr_info("(fmdrv): %s, frequency %d\n", __func__, freq->frequency);
1324 frequency = (freq->frequency/160);
1325 ret = fmc_set_frequency(fmdev, frequency);
1331 /* Set hardware frequency seek. This is scanning radio stations. */
1332 static int fm_v4l2_vidioc_s_hw_freq_seek(struct file *file, void *priv,
1333 const struct v4l2_hw_freq_seek *seek)
1336 struct fmdrv_ops *fmdev;
1337 if (seek->tuner != 0)
1340 fmdev = video_drvdata(file);
1343 pr_debug("(fmdrv) %s direction:%d wrap:%d f_count: %ld\n", __func__,
1344 seek->seek_upward, seek->wrap_around, file_count(file));
1346 ret = fmc_seek_station(fmdev, seek->seek_upward, seek->wrap_around);
1353 static const struct v4l2_file_operations fm_drv_fops = {
1354 .owner = THIS_MODULE,
1355 .read = fm_v4l2_fops_read,
1356 .write = fm_v4l2_fops_write,
1357 .poll = fm_v4l2_fops_poll,
1358 /* Since no private IOCTLs are supported currently,
1359 direct all calls to video_ioctl2() */
1360 .ioctl = video_ioctl2,
1361 .open = fm_v4l2_fops_open,
1362 .release = fm_v4l2_fops_release,
1365 static const struct v4l2_ioctl_ops fm_drv_ioctl_ops = {
1366 .vidioc_querycap = fm_v4l2_vidioc_querycap,
1367 .vidioc_queryctrl = fm_v4l2_vidioc_queryctrl,
1368 .vidioc_g_ctrl = fm_v4l2_vidioc_g_ctrl,
1369 .vidioc_s_ctrl = fm_v4l2_vidioc_s_ctrl,
1370 .vidioc_g_audio = fm_v4l2_vidioc_g_audio,
1371 .vidioc_s_audio = fm_v4l2_vidioc_s_audio,
1372 .vidioc_g_tuner = fm_v4l2_vidioc_g_tuner,
1373 .vidioc_s_tuner = fm_v4l2_vidioc_s_tuner,
1374 .vidioc_g_frequency = fm_v4l2_vidioc_g_frequency,
1375 .vidioc_s_frequency = fm_v4l2_vidioc_s_frequency,
1376 .vidioc_s_hw_freq_seek = fm_v4l2_vidioc_s_hw_freq_seek
1379 /* V4L2 RADIO device parent structure */
1380 static struct video_device fm_viddev_template = {
1381 .fops = &fm_drv_fops,
1382 .ioctl_ops = &fm_drv_ioctl_ops,
1383 .name = FM_DRV_NAME,
1384 .release = video_device_release,
1385 .vfl_type = VFL_TYPE_RADIO,
1388 int fm_v4l2_init_video_device(struct fmdrv_ops *fmdev, int radio_nr)
1392 /* Init mutex for core locking */
1393 mutex_init(&fmdev->mutex);
1394 mutex_init(&fmdev->completionmutex);
1397 /* Allocate new video device */
1398 gradio_dev = video_device_alloc();
1399 if (NULL == gradio_dev) {
1400 pr_err("(fmdrv): Can't allocate video device\n");
1404 /* Setup FM driver's V4L2 properties */
1405 memcpy(gradio_dev, &fm_viddev_template, sizeof(fm_viddev_template));
1407 video_set_drvdata(gradio_dev, fmdev);
1409 gradio_dev->lock = &fmdev->mutex;
1411 /* Register with V4L2 subsystem as RADIO device */
1412 if (video_register_device(gradio_dev, VFL_TYPE_RADIO, radio_nr)) {
1413 video_device_release(gradio_dev);
1414 pr_err("(fmdrv): Could not register video device\n");
1418 fmdev->radio_dev = gradio_dev;
1420 pr_info("(fmdrv) registered with video device\n");
1422 /* Register sysfs entries */
1423 ret = sysfs_create_group(&fmdev->radio_dev->dev.kobj,
1426 pr_err("(fmdrv) %s(): failed to create sysfs entries\n", __func__);
1430 kobject_uevent(&fmdev->radio_dev->dev.kobj, KOBJ_ADD);
1436 void *fm_v4l2_deinit_video_device(void)
1438 struct fmdrv_ops *fmdev;
1440 fmdev = video_get_drvdata(gradio_dev);
1442 /* Unregister sysfs entries */
1443 kobject_uevent(&fmdev->radio_dev->dev.kobj, KOBJ_REMOVE);
1444 sysfs_remove_group(&fmdev->radio_dev->dev.kobj, &v4l2_fm_attr_grp);
1446 /* Unregister RADIO device from V4L2 subsystem */
1447 video_unregister_device(gradio_dev);