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 ret = fm_rx_get_snr(fmdev,&curr_snr);
394 pr_err("(fmdrv) %s(): fail to get current SNR\n",
398 return sprintf(buf, "%d\n", curr_snr);
401 static ssize_t store_fmrx_curr_snr(struct device *dev,
402 struct device_attribute *attr, char *buf, size_t size)
404 pr_info("nothing to do for store\n");
410 static ssize_t show_fmrx_cos_th(struct device *dev,
411 struct device_attribute *attr, char *buf)
413 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
415 return sprintf(buf, "%d\n", fmdev->rx.curr_cos_threshold);
418 static ssize_t store_fmrx_cos_th(struct device *dev,
419 struct device_attribute *attr, char *buf, size_t size)
423 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
425 if (kstrtol(buf, 0, &cos))
428 ret = fm_rx_set_cos_threshold(fmdev, cos);
430 pr_err("(fmdrv) %s(): Failed to set COS level\n",
439 static ssize_t show_fmrx_channel_space(struct device *dev,
440 struct device_attribute *attr, char *buf)
443 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
445 switch( fmdev->rx.sch_step){
447 chl_space= CHL_SPACE_ONE;
450 chl_space= CHL_SPACE_TWO;
453 chl_space= CHL_SPACE_FOUR;
456 chl_space= CHL_SPACE_TWO;
459 return sprintf(buf, "%d\n",chl_space);
462 static ssize_t store_fmrx_channel_space(struct device *dev,
463 struct device_attribute *attr, char *buf, size_t size)
466 unsigned long chl_spacing,chl_step;
467 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
469 if (kstrtoul(buf, 0, &chl_spacing))
471 switch( chl_spacing){
473 chl_step= FM_STEP_50KHZ;
476 chl_step= FM_STEP_100KHZ;
479 chl_step= FM_STEP_200KHZ;
482 chl_step= FM_STEP_100KHZ;
484 ret = fmc_set_scan_step(fmdev, chl_step);
486 pr_err("(fmdrv) %s(): Failed to set channel spacing\n",
494 static ssize_t show_fmrx_start_snr(struct device *dev,
495 struct device_attribute *attr, char *buf)
497 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
499 return sprintf(buf, "%d\n", fmdev->softmute_blend_config.start_snr);
502 static ssize_t store_fmrx_start_snr(struct device *dev,
503 struct device_attribute *attr, char *buf, size_t size)
505 unsigned long start_snr;
506 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
508 if (kstrtoul(buf, 0, &start_snr))
511 if (start_snr < FM_START_SNR_MIN || start_snr > FM_START_SNR_MAX)
514 fmdev->softmute_blend_config.start_snr = start_snr;
519 static ssize_t show_fmrx_stop_snr(struct device *dev,
520 struct device_attribute *attr, char *buf)
522 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
524 return sprintf(buf, "%d\n", fmdev->softmute_blend_config.stop_snr);
527 static ssize_t store_fmrx_stop_snr(struct device *dev,
528 struct device_attribute *attr, char *buf, size_t size)
530 unsigned long stop_snr;
531 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
533 if (kstrtoul(buf, 0, &stop_snr))
536 if (stop_snr < FM_STOP_SNR_MIN || stop_snr > FM_STOP_SNR_MAX)
539 fmdev->softmute_blend_config.stop_snr = stop_snr;
544 static ssize_t show_fmrx_start_rssi(struct device *dev,
545 struct device_attribute *attr, char *buf)
547 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
549 return sprintf(buf, "%d\n", fmdev->softmute_blend_config.start_rssi);
552 static ssize_t store_fmrx_start_rssi(struct device *dev,
553 struct device_attribute *attr, char *buf, size_t size)
556 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
558 if (kstrtol(buf, 0, &start_rssi))
561 if (start_rssi < FM_START_RSSI_MIN || start_rssi > FM_START_RSSI_MAX)
564 fmdev->softmute_blend_config.start_rssi = start_rssi;
569 static ssize_t show_fmrx_stop_rssi(struct device *dev,
570 struct device_attribute *attr, char *buf)
572 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
574 return sprintf(buf, "%d\n", fmdev->softmute_blend_config.stop_rssi);
577 static ssize_t store_fmrx_stop_rssi(struct device *dev,
578 struct device_attribute *attr, char *buf, size_t size)
580 signed long stop_rssi;
581 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
583 if (kstrtol(buf, 0, &stop_rssi))
586 if (stop_rssi < FM_STOP_RSSI_MIN || stop_rssi > FM_STOP_RSSI_MAX)
589 fmdev->softmute_blend_config.stop_rssi = stop_rssi;
594 static ssize_t show_fmrx_start_mute(struct device *dev,
595 struct device_attribute *attr, char *buf)
597 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
599 return sprintf(buf, "%d\n", fmdev->softmute_blend_config.start_mute);
603 static ssize_t store_fmrx_start_mute(struct device *dev,
604 struct device_attribute *attr, char *buf, size_t size)
606 unsigned long start_mute;
607 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
609 if (kstrtoul(buf, 0, &start_mute))
612 fmdev->softmute_blend_config.start_mute = start_mute;
617 static ssize_t show_fmrx_stop_atten(struct device *dev,
618 struct device_attribute *attr, char *buf)
620 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
622 return sprintf(buf, "%d\n", fmdev->softmute_blend_config.stop_atten);
625 static ssize_t store_fmrx_stop_atten(struct device *dev,
626 struct device_attribute *attr, char *buf, size_t size)
628 signed long stop_atten;
629 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
631 if (kstrtol(buf, 0, &stop_atten))
634 if (stop_atten < FM_STOP_ATTEN_MIN || stop_atten > FM_STOP_ATTEN_MAX)
637 fmdev->softmute_blend_config.stop_atten = stop_atten;
642 static ssize_t show_fmrx_mute_rate(struct device *dev,
643 struct device_attribute *attr, char *buf)
645 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
647 return sprintf(buf, "%d\n", fmdev->softmute_blend_config.mute_rate);
650 static ssize_t store_fmrx_mute_rate(struct device *dev,
651 struct device_attribute *attr, char *buf, size_t size)
653 unsigned long mute_rate;
654 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
656 if (kstrtoul(buf, 0, &mute_rate))
659 if (mute_rate < FM_MUTE_RATE_MIN || mute_rate > FM_MUTE_RATE_MAX)
662 fmdev->softmute_blend_config.mute_rate = mute_rate;
667 static ssize_t show_fmrx_snr40(struct device *dev,
668 struct device_attribute *attr, char *buf)
670 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
672 return sprintf(buf, "%d\n", fmdev->softmute_blend_config.snr40);
675 static ssize_t store_fmrx_snr40(struct device *dev,
676 struct device_attribute *attr, char *buf, size_t size)
679 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
681 if (kstrtol(buf, 0, &snr40))
684 if (snr40 < FM_SNR40_MIN || snr40 > FM_SNR40_MAX)
687 fmdev->softmute_blend_config.snr40 = snr40;
693 static ssize_t show_fmrx_set_blndmute(struct device *dev,
694 struct device_attribute *attr, char *buf)
696 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
698 return sprintf(buf, "%d\n", fmdev->set_blndmute);
701 static ssize_t store_fmrx_set_blndmute(struct device *dev,
702 struct device_attribute *attr, char *buf, size_t size)
705 unsigned long set_blndmute;
706 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
708 if (kstrtoul(buf, 0, &set_blndmute))
711 if (set_blndmute < 0 || set_blndmute > 1)
714 ret = fm_rx_set_cfg_blnd_mute(fmdev,set_blndmute);
717 pr_err("(fmdrv) %s(): Failed to set softemute and audio blending\n",
726 static ssize_t show_fmrx_search_abort(struct device *dev,
727 struct device_attribute *attr, char *buf)
729 return sprintf(buf, "%s\n", "abort search read no impact.");
732 static ssize_t store_fmrx_search_abort(struct device *dev,
733 struct device_attribute *attr, char *buf, size_t size)
735 struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
737 fm_rx_seek_station_abort(fmdev);
743 static ssize_t show_fmrx_status(struct device *dev,
744 struct device_attribute *attr, char *buf)
746 return sprintf(buf, "%d\n", radio_disconnected);
749 static ssize_t store_fmrx_status(struct device *dev,
750 struct device_attribute *attr, char *buf, size_t size)
752 pr_info("(fmdrv) %s(): no effect\n", __func__);
756 /* structures specific for sysfs entries
757 * FM GUI app belongs to group "fmradio", these sysfs entries belongs to "root",
758 * but GUI app needs both read and write permissions to these sysfs entires for
759 * below features, so these entries got permission "666"
762 /* To start FM RX complete scan*/
763 static struct kobj_attribute v4l2_fmrx_comp_scan =
764 __ATTR(fmrx_comp_scan, 0666, (void *)show_fmrx_comp_scan,
765 (void *)store_fmrx_comp_scan);
767 /* To Set De-Emphasis filter mode */
768 static struct kobj_attribute v4l2_fmrx_deemph_mode =
769 __ATTR(fmrx_deemph_mode, 0666, (void *)show_fmrx_deemphasis,
770 (void *)store_fmrx_deemphasis);
772 /* To Enable/Disable FM RX RDS AF feature */
773 static struct kobj_attribute v4l2_fmrx_rds_af =
774 __ATTR(fmrx_rds_af, 0666, (void *)show_fmrx_af, (void *)store_fmrx_af);
776 /* To switch between Japan/US bands */
777 static struct kobj_attribute v4l2_fmrx_band =
778 __ATTR(fmrx_band, 0666, (void *)show_fmrx_band, (void *)store_fmrx_band);
780 /* To set the desired FM reception RSSI level */
781 static struct kobj_attribute v4l2_fmrx_rssi_lvl =
782 __ATTR(fmrx_rssi_lvl, 0666, (void *) show_fmrx_rssi_lvl,
783 (void *)store_fmrx_rssi_lvl);
785 /* To set the desired FM reception SNR level */
786 static struct kobj_attribute v4l2_fmrx_snr_lvl =
787 __ATTR(fmrx_snr_lvl, 0666, (void *) show_fmrx_snr_lvl,
788 (void *)store_fmrx_snr_lvl);
790 /* To read current SNR level */
791 static struct kobj_attribute v4l2_fmrx_curr_snr =
792 __ATTR(fmrx_curr_snr, 0666, (void *) show_fmrx_curr_snr,
793 (void *)store_fmrx_curr_snr);
795 /* To set COS value */
796 static struct kobj_attribute v4l2_fmrx_cos_th =
797 __ATTR(fmrx_cos_th, 0666, (void *) show_fmrx_cos_th,
798 (void *)store_fmrx_cos_th);
800 /* To set the desired channel spacing */
801 static struct kobj_attribute v4l2_fmrx_channel_space =
802 __ATTR(fmrx_chl_lvl, 0666, (void *) show_fmrx_channel_space,
803 (void *)store_fmrx_channel_space);
805 /* To set start snr */
806 static struct kobj_attribute v4l2_fmrx_start_snr =
807 __ATTR(fmrx_start_snr, 0666, (void *) show_fmrx_start_snr,
808 (void *)store_fmrx_start_snr);
810 /* To set stop snr */
811 static struct kobj_attribute v4l2_fmrx_stop_snr =
812 __ATTR(fmrx_stop_snr, 0666, (void *) show_fmrx_stop_snr,
813 (void *)store_fmrx_stop_snr);
815 /* To set start rssi */
816 static struct kobj_attribute v4l2_fmrx_start_rssi =
817 __ATTR(fmrx_start_rssi, 0666, (void *) show_fmrx_start_rssi,
818 (void *)store_fmrx_start_rssi);
820 /* To set stop rssi */
821 static struct kobj_attribute v4l2_fmrx_stop_rssi =
822 __ATTR(fmrx_stop_rssi, 0666, (void *) show_fmrx_stop_rssi,
823 (void *)store_fmrx_stop_rssi);
826 /* To set start mute */
827 static struct kobj_attribute v4l2_fmrx_start_mute =
828 __ATTR(fmrx_start_mute, 0666, (void *) show_fmrx_start_mute,
829 (void *)store_fmrx_start_mute);
831 /* To set stop atten */
832 static struct kobj_attribute v4l2_fmrx_stop_atten =
833 __ATTR(fmrx_stop_atten, 0666, (void *) show_fmrx_stop_atten,
834 (void *)store_fmrx_stop_atten);
837 /* To set mute rate */
838 static struct kobj_attribute v4l2_fmrx_mute_rate =
839 __ATTR(fmrx_mute_rate, 0666, (void *) show_fmrx_mute_rate,
840 (void *)store_fmrx_mute_rate);
843 static struct kobj_attribute v4l2_fmrx_snr40 =
844 __ATTR(fmrx_snr40, 0666, (void *) show_fmrx_snr40,
845 (void *)store_fmrx_snr40);
847 /* To start blendmute */
848 static struct kobj_attribute v4l2_fmrx_set_blndmute =
849 __ATTR(fmrx_set_blndmute, 0666, (void *) show_fmrx_set_blndmute,
850 (void *)store_fmrx_set_blndmute);
853 /* To abort search */
854 static struct kobj_attribute v4l2_fmrx_search_abort =
855 __ATTR(fmrx_search_abort, 0666, (void *) show_fmrx_search_abort,
856 (void *)store_fmrx_search_abort);
858 /* To check radio status */
859 static struct kobj_attribute v4l2_fmrx_status =
860 __ATTR(fmrx_status, 0666, (void *) show_fmrx_status,
861 (void *)store_fmrx_status);
863 static struct kobj_attribute v4l2_fmrx_freq_offset =
864 __ATTR(fmrx_freq_offset, 0666, (void *) show_fmrx_Frequency_Offset_lvl,
865 (void *)store_fmrx_Frequency_Offset_lvl);
867 static struct kobj_attribute v4l2_fmrx_noise_power =
868 __ATTR(fmrx_noise_power, 0666, (void *) show_fmrx_Noise_Power_lvl,
869 (void *)store_fmrx_Noise_Power_lvl);
871 static struct kobj_attribute v4l2_fmrx_pilot_power =
872 __ATTR(fmrx_pilot_power, 0666, (void *) show_fmrx_Pilot_Power_lvl,
873 (void *)store_fmrx_Pilot_Power_lvl);
875 static struct attribute *v4l2_fm_attrs[] = {
876 &v4l2_fmrx_comp_scan.attr,
877 &v4l2_fmrx_deemph_mode.attr,
878 &v4l2_fmrx_rds_af.attr,
879 &v4l2_fmrx_band.attr,
880 &v4l2_fmrx_rssi_lvl.attr,
881 &v4l2_fmrx_snr_lvl.attr,
882 &v4l2_fmrx_curr_snr.attr,
883 &v4l2_fmrx_cos_th.attr,
884 &v4l2_fmrx_channel_space.attr,
885 &v4l2_fmrx_start_snr.attr,
886 &v4l2_fmrx_stop_snr.attr,
887 &v4l2_fmrx_start_rssi.attr,
888 &v4l2_fmrx_stop_rssi.attr,
889 &v4l2_fmrx_start_mute.attr,
890 &v4l2_fmrx_stop_atten.attr,
891 &v4l2_fmrx_mute_rate.attr,
892 &v4l2_fmrx_snr40.attr,
893 &v4l2_fmrx_set_blndmute.attr,
894 &v4l2_fmrx_search_abort.attr,
895 &v4l2_fmrx_status.attr,
896 &v4l2_fmrx_freq_offset.attr,
897 &v4l2_fmrx_noise_power.attr,
898 &v4l2_fmrx_pilot_power.attr,
901 static struct attribute_group v4l2_fm_attr_grp = {
902 .attrs = v4l2_fm_attrs,
905 /* Handle open request for "/dev/radioX" device.
906 * Start with FM RX mode as default.
908 static int fm_v4l2_fops_open(struct file *file)
911 unsigned char option;
912 struct fmdrv_ops *fmdev = NULL;
913 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
914 /* Don't allow multiple open */
915 if(!atomic_dec_and_test(&v4l2_device_available))
917 atomic_inc(&v4l2_device_available);
918 pr_err("(fmdrv): FM device is already opened .. v4l2 device busy\n");
922 if (radio_disconnected) {
923 pr_err("(fmdrv): FM device is already opened .. radio not disconnected\n");
927 fmdev = video_drvdata(file);
929 if (mutex_lock_interruptible(&fmdev->mutex))
932 /* initialize the driver */
933 ret = fmc_prepare(fmdev);
935 atomic_inc(&v4l2_device_available);
936 pr_err("(fmdrv): Unable to prepare FM CORE");
937 mutex_unlock(&fmdev->mutex);
941 radio_disconnected = 1;
943 ret = fmc_set_mode(fmdev, FM_MODE_RX); /* As of now, support only Rx */
945 radio_disconnected = 0;
947 atomic_inc(&v4l2_device_available);
948 pr_err("(fmdrv): Unable to enable FM");
949 mutex_unlock(&fmdev->mutex);
953 #if(defined(DEF_V4L2_FM_WORLD_REGION) && DEF_V4L2_FM_WORLD_REGION == FM_REGION_NA)
954 option = FM_REGION_NA | FM_RBDS_BIT;
955 #elif(defined(DEF_V4L2_FM_WORLD_REGION) && DEF_V4L2_FM_WORLD_REGION == FM_REGION_EUR)
956 option = FM_REGION_EUR | FM_RDS_BIT;
957 #elif(defined(DEF_V4L2_FM_WORLD_REGION) && DEF_V4L2_FM_WORLD_REGION == FM_REGION_JP)
958 option = FM_REGION_JP | FM_RDS_BIT;
964 pr_info("(fmdrv): FM Enable INIT option : %d\n", option);
965 ret = fmc_enable(fmdev, option);
967 radio_disconnected = 0;
969 atomic_inc(&v4l2_device_available);
970 pr_err("(fmdrv): Unable to enable FM\n");
971 mutex_unlock(&fmdev->mutex);
976 pr_info("(fmdrv): FM Set Audio mode option : %d\n", DEF_V4L2_FM_AUDIO_MODE);
977 ret = fmc_set_audio_mode(fmdev, DEF_V4L2_FM_AUDIO_MODE);
979 radio_disconnected = 0;
981 atomic_inc(&v4l2_device_available);
982 pr_err("(fmdrv): Error setting Audio mode during FM enable operation\n");
983 mutex_unlock(&fmdev->mutex);
989 pr_info("(fmdrv): FM Set Audio path option : %d\n", DEF_V4L2_FM_AUDIO_PATH);
990 ret = fm_rx_config_audio_path(fmdev, DEF_V4L2_FM_AUDIO_PATH);
992 radio_disconnected = 0;
994 atomic_inc(&v4l2_device_available);
995 pr_err("(fmdrv): Error setting Audio path during FM enable operation\n");
996 mutex_unlock(&fmdev->mutex);
1001 mutex_unlock(&fmdev->mutex);
1005 /* Handle close request for "/dev/radioX" device.
1007 static int fm_v4l2_fops_release(struct file *file)
1010 struct fmdrv_ops *fmdev;
1011 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1013 fmdev = video_drvdata(file);
1015 if (!radio_disconnected) {
1016 pr_info("(fmdrv):FM dev already closed, close called again?\n");
1020 mutex_lock(&fmdev->mutex);
1022 /* First set audio path to NONE */
1023 ret = fm_rx_config_audio_path(fmdev, FM_AUDIO_NONE);
1025 pr_err("(fmdrv): Failed to set audio path to FM_AUDIO_NONE\n");
1029 /* Now disable FM */
1030 ret = fmc_turn_fm_off(fmdev);
1033 pr_err("(fmdrv): Error disabling FM. Continuing to release FM core..\n");
1037 ret = fmc_release(fmdev);
1040 pr_err("(fmdrv): FM CORE release failed\n");
1041 radio_disconnected = 0;
1042 atomic_inc(&v4l2_device_available);
1043 mutex_unlock(&fmdev->mutex);
1047 radio_disconnected = 0;
1048 atomic_inc(&v4l2_device_available);
1049 mutex_unlock(&fmdev->mutex);
1050 pr_info("(fmdrv): %s, E\n", __func__);
1054 /*****************************************************************************
1055 ** V4L2 RADIO (/dev/radioX) device IOCTL interfaces
1056 *****************************************************************************/
1059 * Function to query the driver capabilities
1061 static int fm_v4l2_vidioc_querycap(struct file *file, void *priv,
1062 struct v4l2_capability *capability)
1064 struct fmdrv_ops *fmdev;
1066 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1067 fmdev = video_drvdata(file);
1069 strlcpy(capability->driver, FM_DRV_NAME, sizeof(capability->driver));
1070 strlcpy(capability->card, FM_DRV_CARD_SHORT_NAME,
1071 sizeof(capability->card));
1072 sprintf(capability->bus_info, "UART");
1073 capability->version = FM_DRV_RADIO_VERSION;
1074 capability->capabilities = fmdev->device_info.capabilities;
1079 * Function to query the driver control params
1081 static int fm_v4l2_vidioc_queryctrl(struct file *file, void *priv,
1082 struct v4l2_queryctrl *qc)
1087 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1088 if (qc->id < V4L2_CID_BASE)
1091 /* Search control ID and copy its properties */
1092 for (index = 0; index < NO_OF_ENTRIES_IN_ARRAY(fmdrv_v4l2_queryctrl);\
1094 if (qc->id && qc->id == fmdrv_v4l2_queryctrl[index].id) {
1095 memcpy(qc, &(fmdrv_v4l2_queryctrl[index]), sizeof(*qc));
1104 * Function to get the driver control params. Called
1105 * by user-space via IOCTL call
1107 static int fm_v4l2_vidioc_g_ctrl(struct file *file, void *priv,
1108 struct v4l2_control *ctrl)
1111 unsigned short curr_vol;
1112 unsigned char curr_mute_mode;
1113 struct fmdrv_ops *fmdev;
1115 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1116 fmdev = video_drvdata(file);
1119 case V4L2_CID_AUDIO_MUTE: /* get mute mode */
1120 ret = fm_rx_get_mute_mode(fmdev, &curr_mute_mode);
1123 ctrl->value = curr_mute_mode;
1126 case V4L2_CID_AUDIO_VOLUME: /* get volume */
1127 pr_debug ("(fmdrv): V4L2_CID_AUDIO_VOLUME get\n");
1128 ret = fm_rx_get_volume(fmdev, &curr_vol);
1131 ctrl->value = curr_vol;
1135 pr_debug("(fmdrv): Unhandled IOCTL for get Control\n");
1143 * Function to Set the driver control params. Called
1144 * by user-space via IOCTL call
1146 static int fm_v4l2_vidioc_s_ctrl(struct file *file, void *priv,
1147 struct v4l2_control *ctrl)
1150 struct fmdrv_ops *fmdev;
1152 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1153 fmdev = video_drvdata(file);
1156 case V4L2_CID_AUDIO_MUTE: /* set mute */
1157 ret = fm_rx_set_mute_mode(fmdev, (unsigned char)ctrl->value);
1162 case V4L2_CID_AUDIO_VOLUME: /* set volume */
1163 pr_info ("(fmdrv): V4L2_CID_AUDIO_VOLUME set : %d\n", ctrl->value);
1164 ret = fm_rx_set_volume(fmdev, (unsigned short)ctrl->value);
1166 pr_info ("(fmdrv): V4L2_CID_AUDIO_VOLUME ret : %d\n", ret);
1172 pr_debug("(fmdrv): Unhandled IOCTL for set Control\n");
1180 * Function to get the driver audio params. Called
1181 * by user-space via IOCTL call
1183 static int fm_v4l2_vidioc_g_audio(struct file *file, void *priv,
1184 struct v4l2_audio *audio)
1186 memset(audio, 0, sizeof(*audio));
1188 strcpy(audio->name, "Radio");
1189 /* For FM Radio device, the audio capability should always return
1190 V4L2_AUDCAP_STEREO */
1191 audio->capability = V4L2_AUDCAP_STEREO;
1196 * Function to set the driver audio params. Called
1197 * by user-space via IOCTL call
1199 static int fm_v4l2_vidioc_s_audio(struct file *file, void *priv,
1200 const struct v4l2_audio *audio)
1202 if (audio->index != 0)
1207 /* Get tuner attributes. This IOCTL call will return attributes like tuner type,
1208 upper/lower frequency, audio mode, RSSI value and AF channel */
1209 static int fm_v4l2_vidioc_g_tuner(struct file *file, void *priv,
1210 struct v4l2_tuner *tuner)
1212 unsigned short curr_rssi;
1213 unsigned int high = 0, low = 0;
1215 struct fmdrv_ops *fmdev;
1217 if (tuner->index != 0)
1220 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1222 fmdev = video_drvdata(file);
1223 strcpy(tuner->name, "FM");
1224 tuner->type = fmdev->device_info.type;
1225 /* The V4L2 specification defines all frequencies in unit of 62.5 kHz */
1226 ret = fm_rx_get_band_frequencies(fmdev, &low, &high);
1227 tuner->rangelow = (low * 100000)/625;
1228 tuner->rangehigh = (high * 100000)/625;
1230 tuner->audmode = ((fmdev->rx.audio_mode == FM_AUTO_MODE) ?
1231 V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO);
1232 tuner->capability = fmdev->device_info.tuner_capability;
1233 tuner->rxsubchans = fmdev->device_info.rxsubchans;
1235 ret = fm_rx_read_curr_rssi_freq(fmdev, TRUE);
1236 curr_rssi = fmdev->rx.curr_rssi;
1238 pr_info ("(fmdrv): fm_v4l2_vidioc_g_tuner curr_rssi : %d\n", curr_rssi);
1240 /* This is absolute value of negative dBm on SC2331 chipset */
1241 tuner->signal = curr_rssi;
1246 /* Set tuner attributes. This IOCTL call will set attributes like
1247 upper/lower frequency, audio mode.
1249 static int fm_v4l2_vidioc_s_tuner(struct file *file, void *priv,
1250 const struct v4l2_tuner *tuner)
1253 struct fmdrv_ops *fmdev;
1254 unsigned short high_freq, low_freq;
1255 unsigned short mode;
1256 if (tuner->index != 0)
1259 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1261 fmdev = video_drvdata(file);
1263 /* TODO : Figure out how to set the region based on lower/upper freq */
1264 /* The V4L2 specification defines all frequencies in unit of 62.5 kHz.
1265 Hence translate the incoming tuner band frequencies to controller
1266 recognized values. Set only if rangelow/rangehigh is not 0*/
1267 if(tuner->rangelow != 0 && tuner->rangehigh != 0)
1269 pr_info("(fmdrv) rangelow:%d rangehigh:%d\n", tuner->rangelow, tuner->rangehigh);
1270 low_freq = ((tuner->rangelow) * 625)/100000;
1271 high_freq= ((tuner->rangehigh) * 625)/100000;
1272 pr_info("(fmdrv) low_freq:%d high_freq:%d\n", low_freq, high_freq);
1273 ret = fm_rx_set_band_frequencies(fmdev, low_freq, high_freq);
1278 /* Map V4L2 stereo/mono macro to Broadcom controller equivalent audio mode */
1279 mode = (tuner->audmode == V4L2_TUNER_MODE_STEREO) ?
1280 FM_AUTO_MODE : FM_MONO_MODE;
1282 ret = fmc_set_audio_mode(fmdev, mode);
1288 /* Get tuner or modulator radio frequency */
1289 static int fm_v4l2_vidioc_g_frequency(struct file *file, void *priv,
1290 struct v4l2_frequency *freq)
1293 struct fmdrv_ops *fmdev;
1295 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1296 fmdev = video_drvdata(file);
1297 ret = fmc_get_frequency(fmdev, &freq->frequency);
1298 /* Translate the controller frequency to V4L2 specific frequency
1299 (frequencies in unit of 62.5 Hz):
1300 x = (y * 100) * 1000/62.5 = y * 160 */
1301 freq->frequency = (freq->frequency * 160);
1307 /* Set tuner or modulator radio frequency, this is tune channel */
1308 static int fm_v4l2_vidioc_s_frequency(struct file *file, void *priv,
1309 const struct v4l2_frequency *freq)
1312 struct fmdrv_ops *fmdev;
1313 unsigned int frequency;
1315 pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1316 fmdev = video_drvdata(file);
1317 /* Translate the incoming tuner band frequencies
1318 (frequencies in unit of 62.5 Hz to controller
1319 recognized values. x = y * (62.5/1000000) * 100 = y / 160 */
1320 pr_info("(fmdrv): %s, frequency %d\n", __func__, freq->frequency);
1321 frequency = (freq->frequency/160);
1322 ret = fmc_set_frequency(fmdev, frequency);
1328 /* Set hardware frequency seek. This is scanning radio stations. */
1329 static int fm_v4l2_vidioc_s_hw_freq_seek(struct file *file, void *priv,
1330 const struct v4l2_hw_freq_seek *seek)
1333 struct fmdrv_ops *fmdev;
1334 if (seek->tuner != 0)
1337 fmdev = video_drvdata(file);
1340 pr_debug("(fmdrv) %s direction:%d wrap:%d f_count: %ld\n", __func__,
1341 seek->seek_upward, seek->wrap_around, file_count(file));
1343 ret = fmc_seek_station(fmdev, seek->seek_upward, seek->wrap_around);
1350 static const struct v4l2_file_operations fm_drv_fops = {
1351 .owner = THIS_MODULE,
1352 .read = fm_v4l2_fops_read,
1353 .write = fm_v4l2_fops_write,
1354 .poll = fm_v4l2_fops_poll,
1355 /* Since no private IOCTLs are supported currently,
1356 direct all calls to video_ioctl2() */
1357 .ioctl = video_ioctl2,
1358 .open = fm_v4l2_fops_open,
1359 .release = fm_v4l2_fops_release,
1362 static const struct v4l2_ioctl_ops fm_drv_ioctl_ops = {
1363 .vidioc_querycap = fm_v4l2_vidioc_querycap,
1364 .vidioc_queryctrl = fm_v4l2_vidioc_queryctrl,
1365 .vidioc_g_ctrl = fm_v4l2_vidioc_g_ctrl,
1366 .vidioc_s_ctrl = fm_v4l2_vidioc_s_ctrl,
1367 .vidioc_g_audio = fm_v4l2_vidioc_g_audio,
1368 .vidioc_s_audio = fm_v4l2_vidioc_s_audio,
1369 .vidioc_g_tuner = fm_v4l2_vidioc_g_tuner,
1370 .vidioc_s_tuner = fm_v4l2_vidioc_s_tuner,
1371 .vidioc_g_frequency = fm_v4l2_vidioc_g_frequency,
1372 .vidioc_s_frequency = fm_v4l2_vidioc_s_frequency,
1373 .vidioc_s_hw_freq_seek = fm_v4l2_vidioc_s_hw_freq_seek
1376 /* V4L2 RADIO device parent structure */
1377 static struct video_device fm_viddev_template = {
1378 .fops = &fm_drv_fops,
1379 .ioctl_ops = &fm_drv_ioctl_ops,
1380 .name = FM_DRV_NAME,
1381 .release = video_device_release,
1382 .vfl_type = VFL_TYPE_RADIO,
1385 int fm_v4l2_init_video_device(struct fmdrv_ops *fmdev, int radio_nr)
1389 /* Init mutex for core locking */
1390 mutex_init(&fmdev->mutex);
1391 mutex_init(&fmdev->completionmutex);
1394 /* Allocate new video device */
1395 gradio_dev = video_device_alloc();
1396 if (NULL == gradio_dev) {
1397 pr_err("(fmdrv): Can't allocate video device\n");
1401 /* Setup FM driver's V4L2 properties */
1402 memcpy(gradio_dev, &fm_viddev_template, sizeof(fm_viddev_template));
1404 video_set_drvdata(gradio_dev, fmdev);
1406 gradio_dev->lock = &fmdev->mutex;
1408 /* Register with V4L2 subsystem as RADIO device */
1409 if (video_register_device(gradio_dev, VFL_TYPE_RADIO, radio_nr)) {
1410 video_device_release(gradio_dev);
1411 pr_err("(fmdrv): Could not register video device\n");
1415 fmdev->radio_dev = gradio_dev;
1417 pr_info("(fmdrv) registered with video device\n");
1419 /* Register sysfs entries */
1420 ret = sysfs_create_group(&fmdev->radio_dev->dev.kobj,
1423 pr_err("(fmdrv) %s(): failed to create sysfs entries\n", __func__);
1427 kobject_uevent(&fmdev->radio_dev->dev.kobj, KOBJ_ADD);
1433 void *fm_v4l2_deinit_video_device(void)
1435 struct fmdrv_ops *fmdev;
1437 fmdev = video_get_drvdata(gradio_dev);
1439 /* Unregister sysfs entries */
1440 kobject_uevent(&fmdev->radio_dev->dev.kobj, KOBJ_REMOVE);
1441 sysfs_remove_group(&fmdev->radio_dev->dev.kobj, &v4l2_fm_attr_grp);
1443 /* Unregister RADIO device from V4L2 subsystem */
1444 video_unregister_device(gradio_dev);