media: radio: sprd: fix only requesting to get snr when used
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / media / radio / sc2331 / fmdrv_v4l2.c
1 /*
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.
5
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
9
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
13  * for more details.
14
15
16  *  Copyright (C) 2009-2014 Broadcom Corporation
17  */
18
19 /************************************************************************************
20  *
21  *  Filename:      fmdrv_v4l2.c
22  *
23  *  Description:   FM Driver for Connectivity chip of Broadcom Corporation.
24 *  This file provides interfaces to V4L2 subsystem.
25 *
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.
29 *
30 *    1) File operation related API (open, close, read, write, poll...etc).
31 *    2) Set of V4L2 IOCTL complaint API.
32 *
33 ************************************************************************************/
34 #include <linux/export.h>
35
36 #include "fmdrv.h"
37 #include "fmdrv_v4l2.h"
38 #include "fmdrv_main.h"
39 #include "fmdrv_rx.h"
40 #include <linux/fm_public.h>
41 #define FMDRV_V4L2_QUERYCTRL
42 #include "fmdrv_config.h"
43
44 /************************************************************************************
45 **  Constants & Macros
46 ************************************************************************************/
47
48 #ifndef DEBUG
49 #ifdef pr_info
50 #undef pr_info
51 #define pr_info(fmt, arg...)
52 #endif
53 #endif
54
55 /************************************************************************************
56 **  Static variables
57 ************************************************************************************/
58
59 static struct video_device *gradio_dev;
60 static unsigned char radio_disconnected;
61
62 static atomic_t v4l2_device_available = ATOMIC_INIT(1);
63
64 /************************************************************************************
65 **  Forward function declarations
66 ************************************************************************************/
67
68 static int fm_v4l2_vidioc_s_hw_freq_seek(struct file *, void *,
69                     const struct v4l2_hw_freq_seek *);
70
71 /************************************************************************************
72 **  Functions
73 ************************************************************************************/
74 /*****************************************************************************
75 **   V4L2 RADIO (/dev/radioX) device file operation interfaces
76 *****************************************************************************/
77
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)
81 {
82     int ret, bytes_read;
83     struct fmdrv_ops *fmdev;
84
85     fmdev = video_drvdata(file);
86
87     pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
88
89     if (!radio_disconnected) {
90         pr_err("(fmdrv): FM device is already disconnected\n");
91         ret = -EIO;
92         return ret;
93     }
94
95         if (mutex_lock_interruptible(&fmdev->mutex))
96                 return -ERESTARTSYS;
97
98         /* Copy RDS data from the cicular buffer to userspace */
99         bytes_read =
100             fmc_transfer_rds_from_cbuff(fmdev, file, buf, count);
101     mutex_unlock(&fmdev->mutex);
102     return bytes_read;
103 }
104
105 /* Write RDS data. Since FM TX is not supported, return EINVAL
106  */
107 static ssize_t fm_v4l2_fops_write(struct file *file, const char __user * buf,
108                     size_t count, loff_t *ppos)
109 {
110     return -EINVAL;
111 }
112
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)
116 {
117     int ret;
118     struct fmdrv_ops *fmdev;
119 #if V4L2_RDS_DEBUG
120     pr_info("(fm_rds): %s, f_count %ld\n", __func__, file_count(file));
121 #endif
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);
127     if (!ret)
128         return POLLIN | POLLRDNORM;
129     return 0;
130 }
131
132 static ssize_t show_fmrx_comp_scan(struct device *dev,
133         struct device_attribute *attr, char *buf)
134 {
135     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
136
137     /* Chip doesn't support complete scan for weather band */
138     if (fmdev->rx.region.fm_band == FM_BAND_WEATHER)
139         return -EINVAL;
140
141     return sprintf(buf, "%d\n", fmdev->rx.no_of_chans);
142 }
143
144 static ssize_t store_fmrx_comp_scan(struct device *dev,
145         struct device_attribute *attr, char *buf, size_t size)
146 {
147     int ret;
148     unsigned long comp_scan;
149     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
150
151     /* Chip doesn't support complete scan for weather band */
152     if (fmdev->rx.region.fm_band == FM_BAND_WEATHER)
153         return -EINVAL;
154
155     if (kstrtoul(buf, 0, &comp_scan))
156         return -EINVAL;
157
158     ret = fm_rx_seek_station(fmdev, 1, 0);// FM_CHANNEL_SPACING_200KHZ, comp_scan);
159     if (ret < 0)
160         pr_err("(fmdrv) %s(): RX complete scan failed - %d\n",
161                                                 __func__, ret);
162
163     if (comp_scan == COMP_SCAN_READ)
164         return (size_t) fmdev->rx.no_of_chans;
165     else
166         return size;
167 }
168
169 static ssize_t show_fmrx_deemphasis(struct device *dev,
170         struct device_attribute *attr, char *buf)
171 {
172     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
173
174     return sprintf(buf, "%d\n", (fmdev->rx.region.deemphasis==
175                 FM_RX_EMPHASIS_FILTER_50_USEC) ? 50 : 75);
176 }
177
178 static ssize_t store_fmrx_deemphasis(struct device *dev,
179         struct device_attribute *attr, char *buf, size_t size)
180 {
181     int ret;
182     unsigned char deemph_mode;
183     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
184
185     if (kstrtoul(buf, 0, (long unsigned int*)&deemph_mode))
186         return -EINVAL;
187
188     ret = fm_rx_config_deemphasis(fmdev,deemph_mode);
189     if (ret < 0) {
190         pr_err("(fmdrv) %s(): Failed to set De-emphasis Mode 0x%x\n",
191                                         __func__, deemph_mode);
192         return ret;
193     }
194
195     return size;
196 }
197
198 static ssize_t show_fmrx_af(struct device *dev,
199         struct device_attribute *attr, char *buf)
200 {
201     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
202
203     return sprintf(buf, "%d\n", fmdev->rx.af_mode);
204 }
205
206 static ssize_t store_fmrx_af(struct device *dev,
207         struct device_attribute *attr, char *buf, size_t size)
208 {
209     int ret;
210     unsigned long af_mode;
211     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
212
213     if (kstrtoul(buf, 0, &af_mode))
214         return -EINVAL;
215
216     if (af_mode < 0 || af_mode > 1)
217         return -EINVAL;
218
219     ret = fm_rx_set_af_switch(fmdev, af_mode);
220     if (ret < 0) {
221         pr_err("(fmdrv) %s(): Failed to set AF Switch %lu\n",
222                         __func__, af_mode);
223         return ret;
224     }
225
226     return size;
227 }
228
229 static ssize_t show_fmrx_band(struct device *dev,
230         struct device_attribute *attr, char *buf)
231 {
232     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
233
234     return sprintf(buf, "%d\n", fmdev->rx.region.fm_band);
235 }
236
237 static ssize_t store_fmrx_band(struct device *dev,
238         struct device_attribute *attr, char *buf, size_t size)
239 {
240     int ret;
241     unsigned long fm_band;
242     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
243     if (kstrtoul(buf, 0, &fm_band))
244         return -EINVAL;
245     pr_info("(fmdrv) %s(): store_fmrx_band In  fm_band %lu\n",
246                                 __func__, fm_band);
247
248     if (fm_band < FM_BAND_EUROPE_US || fm_band > FM_BAND_WEATHER)
249         return -EINVAL;
250
251     ret = fm_rx_set_region(fmdev, fm_band);
252     if (ret < 0) {
253         pr_err("(fmdrv) %s(): Failed to set FM Band %lu\n",
254                                 __func__, fm_band);
255         return ret;
256     }
257
258     return size;
259 }
260
261 static ssize_t show_fmrx_Frequency_Offset_lvl (struct device *dev,
262         struct device_attribute *attr, char *buf) { return 0;}
263
264 static ssize_t show_fmrx_Noise_Power_lvl(struct device *dev,
265         struct device_attribute *attr, char *buf){return 0;}
266
267 static ssize_t show_fmrx_Pilot_Power_lvl(struct device *dev,
268         struct device_attribute *attr, char *buf){return 0;}
269
270 static ssize_t store_fmrx_Frequency_Offset_lvl(struct device *dev,
271         struct device_attribute *attr, char *buf, size_t size)
272 {
273     int ret;
274     unsigned long Frequency_Offset_lvl;
275     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
276
277     if (kstrtoul(buf, 0, &Frequency_Offset_lvl))
278         return -EINVAL;
279
280     ret = fm_rx_set_Frequency_Offset_threshold(fmdev, Frequency_Offset_lvl);
281     if (ret < 0) {
282         pr_err("Failed to set Frequency_Offset level\n");
283         return ret;
284     }
285
286     return size;
287 }
288
289 static ssize_t store_fmrx_Noise_Power_lvl(struct device *dev,
290         struct device_attribute *attr, char *buf, size_t size)
291 {
292     int ret;
293     unsigned long Noise_Power_lvl;
294     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
295
296     if (kstrtoul(buf, 0, &Noise_Power_lvl))
297         return -EINVAL;
298
299     ret = fm_rx_set_Noise_Power_threshold(fmdev, Noise_Power_lvl);
300     if (ret < 0) {
301         pr_err("Failed to set Noise_Power level\n");
302         return ret;
303     }
304
305     return size;
306 }
307
308 static ssize_t store_fmrx_Pilot_Power_lvl(struct device *dev,
309         struct device_attribute *attr, char *buf, size_t size)
310 {
311     int ret;
312     unsigned long Pilot_Power_lvl;
313     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
314
315     if (kstrtoul(buf, 0, &Pilot_Power_lvl))
316         return -EINVAL;
317
318     ret = fm_rx_set_Pilot_Power_threshold(fmdev, Pilot_Power_lvl);
319     if (ret < 0) {
320         pr_err("Failed to set Pilot_Power level\n");
321         return ret;
322     }
323
324     return size;
325 }
326
327
328 static ssize_t show_fmrx_rssi_lvl(struct device *dev,
329         struct device_attribute *attr, char *buf)
330 {
331     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
332
333     return sprintf(buf, "%d\n", fmdev->rx.curr_rssi_threshold);
334 }
335 static ssize_t store_fmrx_rssi_lvl(struct device *dev,
336         struct device_attribute *attr, char *buf, size_t size)
337 {
338     int ret;
339     unsigned long rssi_lvl;
340     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
341
342     if (kstrtoul(buf, 0, &rssi_lvl))
343         return -EINVAL;
344
345     ret = fm_rx_set_rssi_threshold(fmdev, rssi_lvl);
346     if (ret < 0) {
347         pr_err("Failed to set RSSI level\n");
348         return ret;
349     }
350
351     return size;
352 }
353
354 static ssize_t show_fmrx_snr_lvl(struct device *dev,
355         struct device_attribute *attr, char *buf)
356 {
357     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
358
359     return sprintf(buf, "%d\n", fmdev->rx.curr_snr_threshold);
360 }
361
362 static ssize_t store_fmrx_snr_lvl(struct device *dev,
363         struct device_attribute *attr, char *buf, size_t size)
364 {
365     int ret;
366     unsigned long snr_lvl;
367     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
368
369     if (kstrtoul(buf, 0, &snr_lvl))
370         return -EINVAL;
371
372     ret = fm_rx_set_snr_threshold(fmdev, snr_lvl);
373     if (ret < 0) {
374         pr_err("(fmdrv) %s(): Failed to set SNR level %lu\n",
375                         __func__, snr_lvl);
376         return ret;
377     }
378
379     return size;
380 }
381
382
383 static ssize_t show_fmrx_curr_snr(struct device *dev,
384         struct device_attribute *attr, char *buf)
385 {
386     int ret;
387     unsigned int curr_snr = 0;
388     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
389
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);
393
394             if (ret < 0 )
395             {
396                 pr_err("(fmdrv) %s(): fail to get current SNR\n",
397                         __func__);
398             }
399     }
400
401     return sprintf(buf, "%d\n", curr_snr);
402 }
403
404 static ssize_t store_fmrx_curr_snr(struct device *dev,
405         struct device_attribute *attr, char *buf, size_t size)
406 {
407     pr_info("nothing to do for store\n");
408     return size;
409 }
410
411
412
413 static ssize_t show_fmrx_cos_th(struct device *dev,
414         struct device_attribute *attr, char *buf)
415 {
416     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
417
418     return sprintf(buf, "%d\n", fmdev->rx.curr_cos_threshold);
419 }
420
421 static ssize_t store_fmrx_cos_th(struct device *dev,
422         struct device_attribute *attr, char *buf, size_t size)
423 {
424     int ret;
425     signed long cos;
426     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
427
428     if (kstrtol(buf, 0, &cos))
429         return -EINVAL;
430
431     ret = fm_rx_set_cos_threshold(fmdev, cos);
432     if (ret < 0) {
433         pr_err("(fmdrv) %s(): Failed to set COS level\n",
434                                         __func__);
435         return ret;
436     }
437
438     return size;
439 }
440
441
442 static ssize_t show_fmrx_channel_space(struct device *dev,
443         struct device_attribute *attr, char *buf)
444 {
445     int chl_space;
446     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
447
448     switch( fmdev->rx.sch_step){
449         case FM_STEP_50KHZ:
450                 chl_space= CHL_SPACE_ONE;
451                 break;
452         case FM_STEP_100KHZ:
453                 chl_space= CHL_SPACE_TWO;
454                 break;
455         case FM_STEP_200KHZ:
456                 chl_space= CHL_SPACE_FOUR;
457                 break;
458         default:
459                 chl_space= CHL_SPACE_TWO;
460                 break;
461         };
462     return sprintf(buf, "%d\n",chl_space);
463 }
464
465 static ssize_t store_fmrx_channel_space(struct device *dev,
466         struct device_attribute *attr, char *buf, size_t size)
467 {
468     int ret;
469     unsigned long chl_spacing,chl_step;
470     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
471
472     if (kstrtoul(buf, 0, &chl_spacing))
473         return -EINVAL;
474     switch( chl_spacing){
475         case CHL_SPACE_ONE:
476             chl_step= FM_STEP_50KHZ;
477             break;
478         case CHL_SPACE_TWO:
479             chl_step= FM_STEP_100KHZ;
480             break;
481         case CHL_SPACE_FOUR:
482             chl_step= FM_STEP_200KHZ;
483             break;
484         default:
485             chl_step= FM_STEP_100KHZ;
486     };
487     ret = fmc_set_scan_step(fmdev, chl_step);
488     if (ret < 0) {
489         pr_err("(fmdrv) %s(): Failed to set channel spacing\n",
490                                                 __func__);
491         return ret;
492     }
493
494     return size;
495 }
496
497 static ssize_t show_fmrx_start_snr(struct device *dev,
498         struct device_attribute *attr, char *buf)
499 {
500     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
501
502     return sprintf(buf, "%d\n", fmdev->softmute_blend_config.start_snr);
503 }
504
505 static ssize_t store_fmrx_start_snr(struct device *dev,
506         struct device_attribute *attr, char *buf, size_t size)
507 {
508     unsigned long start_snr;
509     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
510
511     if (kstrtoul(buf, 0, &start_snr))
512         return -EINVAL;
513
514     if (start_snr < FM_START_SNR_MIN || start_snr > FM_START_SNR_MAX)
515         return -EINVAL;
516
517     fmdev->softmute_blend_config.start_snr = start_snr;
518
519     return size;
520 }
521
522 static ssize_t show_fmrx_stop_snr(struct device *dev,
523         struct device_attribute *attr, char *buf)
524 {
525     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
526
527     return sprintf(buf, "%d\n", fmdev->softmute_blend_config.stop_snr);
528 }
529
530 static ssize_t store_fmrx_stop_snr(struct device *dev,
531         struct device_attribute *attr, char *buf, size_t size)
532 {
533     unsigned long stop_snr;
534     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
535
536     if (kstrtoul(buf, 0, &stop_snr))
537         return -EINVAL;
538
539     if (stop_snr < FM_STOP_SNR_MIN || stop_snr > FM_STOP_SNR_MAX)
540         return -EINVAL;
541
542     fmdev->softmute_blend_config.stop_snr = stop_snr;
543
544     return size;
545 }
546
547 static ssize_t show_fmrx_start_rssi(struct device *dev,
548         struct device_attribute *attr, char *buf)
549 {
550     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
551
552     return sprintf(buf, "%d\n", fmdev->softmute_blend_config.start_rssi);
553 }
554
555 static ssize_t store_fmrx_start_rssi(struct device *dev,
556         struct device_attribute *attr, char *buf, size_t size)
557 {
558     long start_rssi;
559     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
560
561     if (kstrtol(buf, 0, &start_rssi))
562         return -EINVAL;
563
564     if (start_rssi < FM_START_RSSI_MIN || start_rssi > FM_START_RSSI_MAX)
565         return -EINVAL;
566
567     fmdev->softmute_blend_config.start_rssi = start_rssi;
568
569     return size;
570 }
571
572 static ssize_t show_fmrx_stop_rssi(struct device *dev,
573         struct device_attribute *attr, char *buf)
574 {
575     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
576
577     return sprintf(buf, "%d\n", fmdev->softmute_blend_config.stop_rssi);
578 }
579
580 static ssize_t store_fmrx_stop_rssi(struct device *dev,
581         struct device_attribute *attr, char *buf, size_t size)
582 {
583     signed long stop_rssi;
584     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
585
586     if (kstrtol(buf, 0, &stop_rssi))
587         return -EINVAL;
588
589     if (stop_rssi < FM_STOP_RSSI_MIN || stop_rssi > FM_STOP_RSSI_MAX)
590         return -EINVAL;
591
592     fmdev->softmute_blend_config.stop_rssi = stop_rssi;
593
594     return size;
595 }
596
597 static ssize_t show_fmrx_start_mute(struct device *dev,
598         struct device_attribute *attr, char *buf)
599 {
600     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
601
602     return sprintf(buf, "%d\n", fmdev->softmute_blend_config.start_mute);
603 }
604
605
606 static ssize_t store_fmrx_start_mute(struct device *dev,
607         struct device_attribute *attr, char *buf, size_t size)
608 {
609     unsigned long start_mute;
610     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
611
612     if (kstrtoul(buf, 0, &start_mute))
613         return -EINVAL;
614
615     fmdev->softmute_blend_config.start_mute = start_mute;
616
617     return size;
618 }
619
620 static ssize_t show_fmrx_stop_atten(struct device *dev,
621         struct device_attribute *attr, char *buf)
622 {
623     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
624
625     return sprintf(buf, "%d\n", fmdev->softmute_blend_config.stop_atten);
626 }
627
628 static ssize_t store_fmrx_stop_atten(struct device *dev,
629         struct device_attribute *attr, char *buf, size_t size)
630 {
631     signed long stop_atten;
632     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
633
634     if (kstrtol(buf, 0, &stop_atten))
635         return -EINVAL;
636
637     if (stop_atten < FM_STOP_ATTEN_MIN || stop_atten > FM_STOP_ATTEN_MAX)
638         return -EINVAL;
639
640     fmdev->softmute_blend_config.stop_atten = stop_atten;
641
642     return size;
643 }
644
645 static ssize_t show_fmrx_mute_rate(struct device *dev,
646         struct device_attribute *attr, char *buf)
647 {
648     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
649
650     return sprintf(buf, "%d\n", fmdev->softmute_blend_config.mute_rate);
651 }
652
653 static ssize_t store_fmrx_mute_rate(struct device *dev,
654         struct device_attribute *attr, char *buf, size_t size)
655 {
656     unsigned long mute_rate;
657     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
658
659     if (kstrtoul(buf, 0, &mute_rate))
660         return -EINVAL;
661
662     if (mute_rate < FM_MUTE_RATE_MIN || mute_rate > FM_MUTE_RATE_MAX)
663         return -EINVAL;
664
665     fmdev->softmute_blend_config.mute_rate = mute_rate;
666
667     return size;
668 }
669
670 static ssize_t show_fmrx_snr40(struct device *dev,
671         struct device_attribute *attr, char *buf)
672 {
673     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
674
675     return sprintf(buf, "%d\n", fmdev->softmute_blend_config.snr40);
676 }
677
678 static ssize_t store_fmrx_snr40(struct device *dev,
679         struct device_attribute *attr, char *buf, size_t size)
680 {
681     signed long snr40;
682     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
683
684     if (kstrtol(buf, 0, &snr40))
685         return -EINVAL;
686
687     if (snr40 < FM_SNR40_MIN || snr40 > FM_SNR40_MAX)
688         return -EINVAL;
689
690     fmdev->softmute_blend_config.snr40 = snr40;
691
692     return size;
693 }
694
695
696 static ssize_t show_fmrx_set_blndmute(struct device *dev,
697         struct device_attribute *attr, char *buf)
698 {
699     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
700
701     return sprintf(buf, "%d\n", fmdev->set_blndmute);
702 }
703
704 static ssize_t store_fmrx_set_blndmute(struct device *dev,
705         struct device_attribute *attr, char *buf, size_t size)
706 {
707     int ret;
708     unsigned long set_blndmute;
709     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
710
711     if (kstrtoul(buf, 0, &set_blndmute))
712         return -EINVAL;
713
714     if (set_blndmute < 0 || set_blndmute > 1)
715         return -EINVAL;
716
717     ret = fm_rx_set_cfg_blnd_mute(fmdev,set_blndmute);
718
719     if (ret < 0) {
720         pr_err("(fmdrv) %s(): Failed to set softemute and audio blending\n",
721                                 __func__);
722         return ret;
723     }
724
725     return size;
726 }
727
728
729 static ssize_t show_fmrx_search_abort(struct device *dev,
730         struct device_attribute *attr, char *buf)
731 {
732     return sprintf(buf, "%s\n", "abort search read no impact.");
733 }
734
735 static ssize_t store_fmrx_search_abort(struct device *dev,
736         struct device_attribute *attr, char *buf, size_t size)
737 {
738     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
739
740     fm_rx_seek_station_abort(fmdev);
741
742
743     return size;
744 }
745
746 static ssize_t show_fmrx_status(struct device *dev,
747         struct device_attribute *attr, char *buf)
748 {
749         return sprintf(buf, "%d\n", radio_disconnected);
750 }
751
752 static ssize_t store_fmrx_status(struct device *dev,
753         struct device_attribute *attr, char *buf, size_t size)
754 {
755         pr_info("(fmdrv) %s(): no effect\n", __func__);
756         return size;
757 }
758
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"
763  */
764
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);
769
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);
774
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);
778
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);
782
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);
787
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);
792
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);
797
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);
802
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);
807
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);
812
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);
817
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);
822
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);
827
828
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);
833
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);
838
839
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);
844
845 /* To set snr40 */
846 static struct kobj_attribute v4l2_fmrx_snr40 =
847 __ATTR(fmrx_snr40, 0666, (void *) show_fmrx_snr40,
848         (void *)store_fmrx_snr40);
849
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);
854
855
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);
860
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);
865
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);
869
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);
873
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);
877
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,
902     NULL,
903 };
904 static struct attribute_group v4l2_fm_attr_grp = {
905     .attrs = v4l2_fm_attrs,
906 };
907
908 /* Handle open request for "/dev/radioX" device.
909  * Start with FM RX mode as default.
910  */
911 static int fm_v4l2_fops_open(struct file *file)
912 {
913     int ret = -EINVAL;
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))
919     {
920         atomic_inc(&v4l2_device_available);
921         pr_err("(fmdrv): FM device is already opened .. v4l2 device busy\n");
922         return -EBUSY;
923     }
924
925     if (radio_disconnected) {
926         pr_err("(fmdrv): FM device is already opened .. radio not disconnected\n");
927         return  -EBUSY;
928     }
929
930     fmdev = video_drvdata(file);
931
932     if (mutex_lock_interruptible(&fmdev->mutex))
933             return -ERESTARTSYS;
934
935     /* initialize the driver */
936     ret = fmc_prepare(fmdev);
937     if (ret < 0) {
938         atomic_inc(&v4l2_device_available);
939         pr_err("(fmdrv): Unable to prepare FM CORE");
940         mutex_unlock(&fmdev->mutex);
941         return ret;
942     }
943
944     radio_disconnected = 1;
945
946     ret = fmc_set_mode(fmdev, FM_MODE_RX); /* As of now, support only Rx */
947     if (ret < 0) {
948         radio_disconnected = 0;
949         fmc_release(fmdev);
950         atomic_inc(&v4l2_device_available);
951         pr_err("(fmdrv): Unable to enable FM");
952         mutex_unlock(&fmdev->mutex);
953         return ret;
954     }
955
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;
962 #else
963     option = 0;
964 #endif
965
966     /* Enable FM */
967     pr_info("(fmdrv): FM Enable INIT option : %d\n", option);
968     ret = fmc_enable(fmdev, option);
969     if (ret < 0) {
970         radio_disconnected = 0;
971         fmc_release(fmdev);
972         atomic_inc(&v4l2_device_available);
973         pr_err("(fmdrv): Unable to enable FM\n");
974         mutex_unlock(&fmdev->mutex);
975         return ret;
976     }
977
978     /* Set Audio mode */
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);
981     if (ret < 0) {
982         radio_disconnected = 0;
983         fmc_release(fmdev);
984         atomic_inc(&v4l2_device_available);
985         pr_err("(fmdrv): Error setting Audio mode during FM enable operation\n");
986         mutex_unlock(&fmdev->mutex);
987         return ret;
988     }
989
990     /* Set Audio path */
991         /*
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);
994     if (ret < 0) {
995         radio_disconnected = 0;
996         fmc_release(fmdev);
997         atomic_inc(&v4l2_device_available);
998         pr_err("(fmdrv): Error setting Audio path during FM enable operation\n");
999         mutex_unlock(&fmdev->mutex);
1000         return ret;
1001     }
1002
1003         */
1004     mutex_unlock(&fmdev->mutex);
1005     return 0;
1006 }
1007
1008 /* Handle close request for "/dev/radioX" device.
1009  */
1010 static int fm_v4l2_fops_release(struct file *file)
1011 {
1012     int ret =  -EINVAL;
1013     struct fmdrv_ops *fmdev;
1014     pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1015
1016     fmdev = video_drvdata(file);
1017
1018     if (!radio_disconnected) {
1019         pr_info("(fmdrv):FM dev already closed, close called again?\n");
1020         return ret;
1021     }
1022
1023      mutex_lock(&fmdev->mutex);
1024
1025     /* First set audio path to NONE */
1026     ret = fm_rx_config_audio_path(fmdev, FM_AUDIO_NONE);
1027     if (ret < 0) {
1028         pr_err("(fmdrv): Failed to set audio path to FM_AUDIO_NONE\n");
1029         /*ret = 0;*/
1030     }
1031
1032     /* Now disable FM */
1033     ret = fmc_turn_fm_off(fmdev);
1034     if(ret < 0)
1035     {
1036         pr_err("(fmdrv): Error disabling FM. Continuing to release FM core..\n");
1037         ret = 0;
1038     }
1039
1040     ret = fmc_release(fmdev);
1041     if (ret < 0)
1042     {
1043         pr_err("(fmdrv): FM CORE release failed\n");
1044         radio_disconnected = 0;
1045         atomic_inc(&v4l2_device_available);
1046         mutex_unlock(&fmdev->mutex);
1047         return ret;
1048     }
1049
1050     radio_disconnected = 0;
1051     atomic_inc(&v4l2_device_available);
1052     mutex_unlock(&fmdev->mutex);
1053     pr_info("(fmdrv): %s, E\n", __func__);
1054     return 0;
1055 }
1056
1057 /*****************************************************************************
1058 **   V4L2 RADIO (/dev/radioX) device IOCTL interfaces
1059 *****************************************************************************/
1060
1061 /*
1062 * Function to query the driver capabilities
1063 */
1064 static int fm_v4l2_vidioc_querycap(struct file *file, void *priv,
1065                     struct v4l2_capability *capability)
1066 {
1067     struct fmdrv_ops *fmdev;
1068
1069     pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1070     fmdev = video_drvdata(file);
1071
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;
1078     return 0;
1079 }
1080
1081 /*
1082 * Function to query the driver control params
1083 */
1084 static int fm_v4l2_vidioc_queryctrl(struct file *file, void *priv,
1085                                         struct v4l2_queryctrl *qc)
1086 {
1087     int index;
1088     int ret = -EINVAL;
1089
1090     pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1091     if (qc->id < V4L2_CID_BASE)
1092         return ret;
1093
1094     /* Search control ID and copy its properties */
1095     for (index = 0; index < NO_OF_ENTRIES_IN_ARRAY(fmdrv_v4l2_queryctrl);\
1096             index++) {
1097         if (qc->id && qc->id == fmdrv_v4l2_queryctrl[index].id) {
1098             memcpy(qc, &(fmdrv_v4l2_queryctrl[index]), sizeof(*qc));
1099             ret = 0;
1100             break;
1101         }
1102     }
1103     return ret;
1104 }
1105
1106 /*
1107 * Function to get the driver control params. Called
1108 * by user-space via IOCTL call
1109 */
1110 static int fm_v4l2_vidioc_g_ctrl(struct file *file, void *priv,
1111                     struct v4l2_control *ctrl)
1112 {
1113     int ret = -EINVAL;
1114     unsigned short curr_vol;
1115     unsigned char curr_mute_mode;
1116     struct fmdrv_ops *fmdev;
1117
1118     pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1119     fmdev = video_drvdata(file);
1120
1121     switch (ctrl->id) {
1122         case V4L2_CID_AUDIO_MUTE:    /* get mute mode */
1123             ret = fm_rx_get_mute_mode(fmdev, &curr_mute_mode);
1124             if (ret < 0)
1125                 return ret;
1126             ctrl->value = curr_mute_mode;
1127             break;
1128
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);
1132             if (ret < 0)
1133                 return ret;
1134             ctrl->value = curr_vol;
1135             break;
1136
1137        default:
1138            pr_debug("(fmdrv): Unhandled IOCTL for get Control\n");
1139            break;
1140     }
1141
1142     return ret;
1143 }
1144
1145 /*
1146 * Function to Set the driver control params. Called
1147 * by user-space via IOCTL call
1148 */
1149 static int fm_v4l2_vidioc_s_ctrl(struct file *file, void *priv,
1150                     struct v4l2_control *ctrl)
1151 {
1152     int ret = -EINVAL;
1153     struct fmdrv_ops *fmdev;
1154
1155     pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1156     fmdev = video_drvdata(file);
1157
1158     switch (ctrl->id) {
1159         case V4L2_CID_AUDIO_MUTE:    /* set mute */
1160             ret = fm_rx_set_mute_mode(fmdev, (unsigned char)ctrl->value);
1161             if (ret < 0)
1162                 return ret;
1163             break;
1164
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);
1168             if (ret < 0){
1169                 pr_info ("(fmdrv): V4L2_CID_AUDIO_VOLUME ret : %d\n", ret);
1170                 return ret;
1171             }
1172             break;
1173
1174         default:
1175             pr_debug("(fmdrv): Unhandled IOCTL for set Control\n");
1176             break;
1177     }
1178
1179     return ret;
1180 }
1181
1182 /*
1183 * Function to get the driver audio params. Called
1184 * by user-space via IOCTL call
1185 */
1186 static int fm_v4l2_vidioc_g_audio(struct file *file, void *priv,
1187                     struct v4l2_audio *audio)
1188 {
1189     memset(audio, 0, sizeof(*audio));
1190     audio->index = 0;
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;
1195     return 0;
1196 }
1197
1198 /*
1199 * Function to set the driver audio params. Called
1200 * by user-space via IOCTL call
1201 */
1202 static int fm_v4l2_vidioc_s_audio(struct file *file, void *priv,
1203                     const struct v4l2_audio *audio)
1204 {
1205     if (audio->index != 0)
1206         return -EINVAL;
1207     return 0;
1208 }
1209
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)
1214 {
1215     unsigned short curr_rssi;
1216     unsigned int high = 0, low = 0;
1217     int ret = -EINVAL;
1218     struct fmdrv_ops *fmdev;
1219
1220     if (tuner->index != 0)
1221         return ret;
1222
1223     pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1224
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;
1232
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;
1237
1238     ret = fm_rx_read_curr_rssi_freq(fmdev, TRUE);
1239     curr_rssi = fmdev->rx.curr_rssi;
1240
1241     pr_info ("(fmdrv): fm_v4l2_vidioc_g_tuner curr_rssi : %d\n", curr_rssi);
1242
1243     /* This is absolute value of negative dBm on SC2331 chipset */
1244     tuner->signal = curr_rssi;
1245     ret = 0;
1246     return ret;
1247 }
1248
1249 /* Set tuner attributes. This IOCTL call will set attributes like
1250    upper/lower frequency, audio mode.
1251  */
1252 static int fm_v4l2_vidioc_s_tuner(struct file *file, void *priv,
1253                     const struct v4l2_tuner *tuner)
1254 {
1255     int ret = -EINVAL;
1256     struct fmdrv_ops *fmdev;
1257     unsigned short high_freq, low_freq;
1258     unsigned short mode;
1259     if (tuner->index != 0)
1260         return ret;
1261
1262     pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1263
1264     fmdev = video_drvdata(file);
1265
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)
1271     {
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);
1277         if (ret < 0)
1278             return ret;
1279     }
1280
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;
1284
1285     ret = fmc_set_audio_mode(fmdev, mode);
1286     if (ret < 0)
1287         return ret;
1288     return 0;
1289 }
1290
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)
1294 {
1295     int ret;
1296     struct fmdrv_ops *fmdev;
1297
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);
1305     if (ret < 0)
1306         return ret;
1307     return 0;
1308 }
1309
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)
1313 {
1314     int ret = 0;
1315     struct fmdrv_ops *fmdev;
1316     unsigned int frequency;
1317
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);
1326     if (ret < 0)
1327         return ret;
1328     return 0;
1329 }
1330
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)
1334 {
1335     int ret = -EINVAL;
1336     struct fmdrv_ops *fmdev;
1337     if (seek->tuner != 0)
1338         return -EINVAL;
1339
1340     fmdev = video_drvdata(file);
1341
1342 #if V4L2_FM_DEBUG
1343     pr_debug("(fmdrv) %s direction:%d wrap:%d f_count: %ld\n", __func__,
1344                                 seek->seek_upward, seek->wrap_around, file_count(file));
1345 #endif
1346     ret = fmc_seek_station(fmdev, seek->seek_upward, seek->wrap_around);
1347
1348     if (ret < 0)
1349         return ret;
1350     return 0;
1351 }
1352
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,
1363 };
1364
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
1377 };
1378
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,
1386 };
1387
1388 int fm_v4l2_init_video_device(struct fmdrv_ops *fmdev, int radio_nr)
1389 {
1390     int ret = -ENOMEM;
1391
1392     /* Init mutex for core locking */
1393     mutex_init(&fmdev->mutex);
1394     mutex_init(&fmdev->completionmutex);
1395
1396     gradio_dev = NULL;
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");
1401         return -ENOMEM;
1402     }
1403
1404     /* Setup FM driver's V4L2 properties */
1405     memcpy(gradio_dev, &fm_viddev_template, sizeof(fm_viddev_template));
1406
1407     video_set_drvdata(gradio_dev, fmdev);
1408
1409     gradio_dev->lock = &fmdev->mutex;
1410
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");
1415         return -EINVAL;
1416     }
1417
1418     fmdev->radio_dev = gradio_dev;
1419
1420     pr_info("(fmdrv) registered with video device\n");
1421
1422     /* Register sysfs entries */
1423     ret = sysfs_create_group(&fmdev->radio_dev->dev.kobj,
1424             &v4l2_fm_attr_grp);
1425     if (ret) {
1426         pr_err("(fmdrv) %s(): failed to create sysfs entries\n", __func__);
1427         return -ENOTDIR;
1428     }
1429
1430     kobject_uevent(&fmdev->radio_dev->dev.kobj, KOBJ_ADD);
1431     ret = 0;
1432
1433     return ret;
1434 }
1435
1436 void *fm_v4l2_deinit_video_device(void)
1437 {
1438     struct fmdrv_ops *fmdev;
1439
1440     fmdev = video_get_drvdata(gradio_dev);
1441
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);
1445
1446     /* Unregister RADIO device from V4L2 subsystem */
1447     video_unregister_device(gradio_dev);
1448
1449     return fmdev;
1450 }