d512bb82cdb2c4291ac26e2855e67a2bb7068fee
[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     ret = fm_rx_get_snr(fmdev,&curr_snr);
391
392     if (ret < 0 )
393     {
394         pr_err("(fmdrv) %s(): fail to get current SNR\n",
395                         __func__);
396     }
397
398     return sprintf(buf, "%d\n", curr_snr);
399 }
400
401 static ssize_t store_fmrx_curr_snr(struct device *dev,
402         struct device_attribute *attr, char *buf, size_t size)
403 {
404     pr_info("nothing to do for store\n");
405     return size;
406 }
407
408
409
410 static ssize_t show_fmrx_cos_th(struct device *dev,
411         struct device_attribute *attr, char *buf)
412 {
413     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
414
415     return sprintf(buf, "%d\n", fmdev->rx.curr_cos_threshold);
416 }
417
418 static ssize_t store_fmrx_cos_th(struct device *dev,
419         struct device_attribute *attr, char *buf, size_t size)
420 {
421     int ret;
422     signed long cos;
423     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
424
425     if (kstrtol(buf, 0, &cos))
426         return -EINVAL;
427
428     ret = fm_rx_set_cos_threshold(fmdev, cos);
429     if (ret < 0) {
430         pr_err("(fmdrv) %s(): Failed to set COS level\n",
431                                         __func__);
432         return ret;
433     }
434
435     return size;
436 }
437
438
439 static ssize_t show_fmrx_channel_space(struct device *dev,
440         struct device_attribute *attr, char *buf)
441 {
442     int chl_space;
443     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
444
445     switch( fmdev->rx.sch_step){
446         case FM_STEP_50KHZ:
447                 chl_space= CHL_SPACE_ONE;
448                 break;
449         case FM_STEP_100KHZ:
450                 chl_space= CHL_SPACE_TWO;
451                 break;
452         case FM_STEP_200KHZ:
453                 chl_space= CHL_SPACE_FOUR;
454                 break;
455         default:
456                 chl_space= CHL_SPACE_TWO;
457                 break;
458         };
459     return sprintf(buf, "%d\n",chl_space);
460 }
461
462 static ssize_t store_fmrx_channel_space(struct device *dev,
463         struct device_attribute *attr, char *buf, size_t size)
464 {
465     int ret;
466     unsigned long chl_spacing,chl_step;
467     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
468
469     if (kstrtoul(buf, 0, &chl_spacing))
470         return -EINVAL;
471     switch( chl_spacing){
472         case CHL_SPACE_ONE:
473             chl_step= FM_STEP_50KHZ;
474             break;
475         case CHL_SPACE_TWO:
476             chl_step= FM_STEP_100KHZ;
477             break;
478         case CHL_SPACE_FOUR:
479             chl_step= FM_STEP_200KHZ;
480             break;
481         default:
482             chl_step= FM_STEP_100KHZ;
483     };
484     ret = fmc_set_scan_step(fmdev, chl_step);
485     if (ret < 0) {
486         pr_err("(fmdrv) %s(): Failed to set channel spacing\n",
487                                                 __func__);
488         return ret;
489     }
490
491     return size;
492 }
493
494 static ssize_t show_fmrx_start_snr(struct device *dev,
495         struct device_attribute *attr, char *buf)
496 {
497     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
498
499     return sprintf(buf, "%d\n", fmdev->softmute_blend_config.start_snr);
500 }
501
502 static ssize_t store_fmrx_start_snr(struct device *dev,
503         struct device_attribute *attr, char *buf, size_t size)
504 {
505     unsigned long start_snr;
506     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
507
508     if (kstrtoul(buf, 0, &start_snr))
509         return -EINVAL;
510
511     if (start_snr < FM_START_SNR_MIN || start_snr > FM_START_SNR_MAX)
512         return -EINVAL;
513
514     fmdev->softmute_blend_config.start_snr = start_snr;
515
516     return size;
517 }
518
519 static ssize_t show_fmrx_stop_snr(struct device *dev,
520         struct device_attribute *attr, char *buf)
521 {
522     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
523
524     return sprintf(buf, "%d\n", fmdev->softmute_blend_config.stop_snr);
525 }
526
527 static ssize_t store_fmrx_stop_snr(struct device *dev,
528         struct device_attribute *attr, char *buf, size_t size)
529 {
530     unsigned long stop_snr;
531     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
532
533     if (kstrtoul(buf, 0, &stop_snr))
534         return -EINVAL;
535
536     if (stop_snr < FM_STOP_SNR_MIN || stop_snr > FM_STOP_SNR_MAX)
537         return -EINVAL;
538
539     fmdev->softmute_blend_config.stop_snr = stop_snr;
540
541     return size;
542 }
543
544 static ssize_t show_fmrx_start_rssi(struct device *dev,
545         struct device_attribute *attr, char *buf)
546 {
547     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
548
549     return sprintf(buf, "%d\n", fmdev->softmute_blend_config.start_rssi);
550 }
551
552 static ssize_t store_fmrx_start_rssi(struct device *dev,
553         struct device_attribute *attr, char *buf, size_t size)
554 {
555     long start_rssi;
556     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
557
558     if (kstrtol(buf, 0, &start_rssi))
559         return -EINVAL;
560
561     if (start_rssi < FM_START_RSSI_MIN || start_rssi > FM_START_RSSI_MAX)
562         return -EINVAL;
563
564     fmdev->softmute_blend_config.start_rssi = start_rssi;
565
566     return size;
567 }
568
569 static ssize_t show_fmrx_stop_rssi(struct device *dev,
570         struct device_attribute *attr, char *buf)
571 {
572     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
573
574     return sprintf(buf, "%d\n", fmdev->softmute_blend_config.stop_rssi);
575 }
576
577 static ssize_t store_fmrx_stop_rssi(struct device *dev,
578         struct device_attribute *attr, char *buf, size_t size)
579 {
580     signed long stop_rssi;
581     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
582
583     if (kstrtol(buf, 0, &stop_rssi))
584         return -EINVAL;
585
586     if (stop_rssi < FM_STOP_RSSI_MIN || stop_rssi > FM_STOP_RSSI_MAX)
587         return -EINVAL;
588
589     fmdev->softmute_blend_config.stop_rssi = stop_rssi;
590
591     return size;
592 }
593
594 static ssize_t show_fmrx_start_mute(struct device *dev,
595         struct device_attribute *attr, char *buf)
596 {
597     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
598
599     return sprintf(buf, "%d\n", fmdev->softmute_blend_config.start_mute);
600 }
601
602
603 static ssize_t store_fmrx_start_mute(struct device *dev,
604         struct device_attribute *attr, char *buf, size_t size)
605 {
606     unsigned long start_mute;
607     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
608
609     if (kstrtoul(buf, 0, &start_mute))
610         return -EINVAL;
611
612     fmdev->softmute_blend_config.start_mute = start_mute;
613
614     return size;
615 }
616
617 static ssize_t show_fmrx_stop_atten(struct device *dev,
618         struct device_attribute *attr, char *buf)
619 {
620     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
621
622     return sprintf(buf, "%d\n", fmdev->softmute_blend_config.stop_atten);
623 }
624
625 static ssize_t store_fmrx_stop_atten(struct device *dev,
626         struct device_attribute *attr, char *buf, size_t size)
627 {
628     signed long stop_atten;
629     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
630
631     if (kstrtol(buf, 0, &stop_atten))
632         return -EINVAL;
633
634     if (stop_atten < FM_STOP_ATTEN_MIN || stop_atten > FM_STOP_ATTEN_MAX)
635         return -EINVAL;
636
637     fmdev->softmute_blend_config.stop_atten = stop_atten;
638
639     return size;
640 }
641
642 static ssize_t show_fmrx_mute_rate(struct device *dev,
643         struct device_attribute *attr, char *buf)
644 {
645     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
646
647     return sprintf(buf, "%d\n", fmdev->softmute_blend_config.mute_rate);
648 }
649
650 static ssize_t store_fmrx_mute_rate(struct device *dev,
651         struct device_attribute *attr, char *buf, size_t size)
652 {
653     unsigned long mute_rate;
654     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
655
656     if (kstrtoul(buf, 0, &mute_rate))
657         return -EINVAL;
658
659     if (mute_rate < FM_MUTE_RATE_MIN || mute_rate > FM_MUTE_RATE_MAX)
660         return -EINVAL;
661
662     fmdev->softmute_blend_config.mute_rate = mute_rate;
663
664     return size;
665 }
666
667 static ssize_t show_fmrx_snr40(struct device *dev,
668         struct device_attribute *attr, char *buf)
669 {
670     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
671
672     return sprintf(buf, "%d\n", fmdev->softmute_blend_config.snr40);
673 }
674
675 static ssize_t store_fmrx_snr40(struct device *dev,
676         struct device_attribute *attr, char *buf, size_t size)
677 {
678     signed long snr40;
679     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
680
681     if (kstrtol(buf, 0, &snr40))
682         return -EINVAL;
683
684     if (snr40 < FM_SNR40_MIN || snr40 > FM_SNR40_MAX)
685         return -EINVAL;
686
687     fmdev->softmute_blend_config.snr40 = snr40;
688
689     return size;
690 }
691
692
693 static ssize_t show_fmrx_set_blndmute(struct device *dev,
694         struct device_attribute *attr, char *buf)
695 {
696     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
697
698     return sprintf(buf, "%d\n", fmdev->set_blndmute);
699 }
700
701 static ssize_t store_fmrx_set_blndmute(struct device *dev,
702         struct device_attribute *attr, char *buf, size_t size)
703 {
704     int ret;
705     unsigned long set_blndmute;
706     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
707
708     if (kstrtoul(buf, 0, &set_blndmute))
709         return -EINVAL;
710
711     if (set_blndmute < 0 || set_blndmute > 1)
712         return -EINVAL;
713
714     ret = fm_rx_set_cfg_blnd_mute(fmdev,set_blndmute);
715
716     if (ret < 0) {
717         pr_err("(fmdrv) %s(): Failed to set softemute and audio blending\n",
718                                 __func__);
719         return ret;
720     }
721
722     return size;
723 }
724
725
726 static ssize_t show_fmrx_search_abort(struct device *dev,
727         struct device_attribute *attr, char *buf)
728 {
729     return sprintf(buf, "%s\n", "abort search read no impact.");
730 }
731
732 static ssize_t store_fmrx_search_abort(struct device *dev,
733         struct device_attribute *attr, char *buf, size_t size)
734 {
735     struct fmdrv_ops *fmdev = dev_get_drvdata(dev);
736
737     fm_rx_seek_station_abort(fmdev);
738
739
740     return size;
741 }
742
743 static ssize_t show_fmrx_status(struct device *dev,
744         struct device_attribute *attr, char *buf)
745 {
746         return sprintf(buf, "%d\n", radio_disconnected);
747 }
748
749 static ssize_t store_fmrx_status(struct device *dev,
750         struct device_attribute *attr, char *buf, size_t size)
751 {
752         pr_info("(fmdrv) %s(): no effect\n", __func__);
753         return size;
754 }
755
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"
760  */
761
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);
766
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);
771
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);
775
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);
779
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);
784
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);
789
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);
794
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);
799
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);
804
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);
809
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);
814
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);
819
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);
824
825
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);
830
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);
835
836
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);
841
842 /* To set snr40 */
843 static struct kobj_attribute v4l2_fmrx_snr40 =
844 __ATTR(fmrx_snr40, 0666, (void *) show_fmrx_snr40,
845         (void *)store_fmrx_snr40);
846
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);
851
852
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);
857
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);
862
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);
866
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);
870
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);
874
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,
899     NULL,
900 };
901 static struct attribute_group v4l2_fm_attr_grp = {
902     .attrs = v4l2_fm_attrs,
903 };
904
905 /* Handle open request for "/dev/radioX" device.
906  * Start with FM RX mode as default.
907  */
908 static int fm_v4l2_fops_open(struct file *file)
909 {
910     int ret = -EINVAL;
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))
916     {
917         atomic_inc(&v4l2_device_available);
918         pr_err("(fmdrv): FM device is already opened .. v4l2 device busy\n");
919         return -EBUSY;
920     }
921
922     if (radio_disconnected) {
923         pr_err("(fmdrv): FM device is already opened .. radio not disconnected\n");
924         return  -EBUSY;
925     }
926
927     fmdev = video_drvdata(file);
928
929     if (mutex_lock_interruptible(&fmdev->mutex))
930             return -ERESTARTSYS;
931
932     /* initialize the driver */
933     ret = fmc_prepare(fmdev);
934     if (ret < 0) {
935         atomic_inc(&v4l2_device_available);
936         pr_err("(fmdrv): Unable to prepare FM CORE");
937         mutex_unlock(&fmdev->mutex);
938         return ret;
939     }
940
941     radio_disconnected = 1;
942
943     ret = fmc_set_mode(fmdev, FM_MODE_RX); /* As of now, support only Rx */
944     if (ret < 0) {
945         radio_disconnected = 0;
946         fmc_release(fmdev);
947         atomic_inc(&v4l2_device_available);
948         pr_err("(fmdrv): Unable to enable FM");
949         mutex_unlock(&fmdev->mutex);
950         return ret;
951     }
952
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;
959 #else
960     option = 0;
961 #endif
962
963     /* Enable FM */
964     pr_info("(fmdrv): FM Enable INIT option : %d\n", option);
965     ret = fmc_enable(fmdev, option);
966     if (ret < 0) {
967         radio_disconnected = 0;
968         fmc_release(fmdev);
969         atomic_inc(&v4l2_device_available);
970         pr_err("(fmdrv): Unable to enable FM\n");
971         mutex_unlock(&fmdev->mutex);
972         return ret;
973     }
974
975     /* Set Audio mode */
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);
978     if (ret < 0) {
979         radio_disconnected = 0;
980         fmc_release(fmdev);
981         atomic_inc(&v4l2_device_available);
982         pr_err("(fmdrv): Error setting Audio mode during FM enable operation\n");
983         mutex_unlock(&fmdev->mutex);
984         return ret;
985     }
986
987     /* Set Audio path */
988         /*
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);
991     if (ret < 0) {
992         radio_disconnected = 0;
993         fmc_release(fmdev);
994         atomic_inc(&v4l2_device_available);
995         pr_err("(fmdrv): Error setting Audio path during FM enable operation\n");
996         mutex_unlock(&fmdev->mutex);
997         return ret;
998     }
999
1000         */
1001     mutex_unlock(&fmdev->mutex);
1002     return 0;
1003 }
1004
1005 /* Handle close request for "/dev/radioX" device.
1006  */
1007 static int fm_v4l2_fops_release(struct file *file)
1008 {
1009     int ret =  -EINVAL;
1010     struct fmdrv_ops *fmdev;
1011     pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1012
1013     fmdev = video_drvdata(file);
1014
1015     if (!radio_disconnected) {
1016         pr_info("(fmdrv):FM dev already closed, close called again?\n");
1017         return ret;
1018     }
1019
1020      mutex_lock(&fmdev->mutex);
1021
1022     /* First set audio path to NONE */
1023     ret = fm_rx_config_audio_path(fmdev, FM_AUDIO_NONE);
1024     if (ret < 0) {
1025         pr_err("(fmdrv): Failed to set audio path to FM_AUDIO_NONE\n");
1026         /*ret = 0;*/
1027     }
1028
1029     /* Now disable FM */
1030     ret = fmc_turn_fm_off(fmdev);
1031     if(ret < 0)
1032     {
1033         pr_err("(fmdrv): Error disabling FM. Continuing to release FM core..\n");
1034         ret = 0;
1035     }
1036
1037     ret = fmc_release(fmdev);
1038     if (ret < 0)
1039     {
1040         pr_err("(fmdrv): FM CORE release failed\n");
1041         radio_disconnected = 0;
1042         atomic_inc(&v4l2_device_available);
1043         mutex_unlock(&fmdev->mutex);
1044         return ret;
1045     }
1046
1047     radio_disconnected = 0;
1048     atomic_inc(&v4l2_device_available);
1049     mutex_unlock(&fmdev->mutex);
1050     pr_info("(fmdrv): %s, E\n", __func__);
1051     return 0;
1052 }
1053
1054 /*****************************************************************************
1055 **   V4L2 RADIO (/dev/radioX) device IOCTL interfaces
1056 *****************************************************************************/
1057
1058 /*
1059 * Function to query the driver capabilities
1060 */
1061 static int fm_v4l2_vidioc_querycap(struct file *file, void *priv,
1062                     struct v4l2_capability *capability)
1063 {
1064     struct fmdrv_ops *fmdev;
1065
1066     pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1067     fmdev = video_drvdata(file);
1068
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;
1075     return 0;
1076 }
1077
1078 /*
1079 * Function to query the driver control params
1080 */
1081 static int fm_v4l2_vidioc_queryctrl(struct file *file, void *priv,
1082                                         struct v4l2_queryctrl *qc)
1083 {
1084     int index;
1085     int ret = -EINVAL;
1086
1087     pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1088     if (qc->id < V4L2_CID_BASE)
1089         return ret;
1090
1091     /* Search control ID and copy its properties */
1092     for (index = 0; index < NO_OF_ENTRIES_IN_ARRAY(fmdrv_v4l2_queryctrl);\
1093             index++) {
1094         if (qc->id && qc->id == fmdrv_v4l2_queryctrl[index].id) {
1095             memcpy(qc, &(fmdrv_v4l2_queryctrl[index]), sizeof(*qc));
1096             ret = 0;
1097             break;
1098         }
1099     }
1100     return ret;
1101 }
1102
1103 /*
1104 * Function to get the driver control params. Called
1105 * by user-space via IOCTL call
1106 */
1107 static int fm_v4l2_vidioc_g_ctrl(struct file *file, void *priv,
1108                     struct v4l2_control *ctrl)
1109 {
1110     int ret = -EINVAL;
1111     unsigned short curr_vol;
1112     unsigned char curr_mute_mode;
1113     struct fmdrv_ops *fmdev;
1114
1115     pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1116     fmdev = video_drvdata(file);
1117
1118     switch (ctrl->id) {
1119         case V4L2_CID_AUDIO_MUTE:    /* get mute mode */
1120             ret = fm_rx_get_mute_mode(fmdev, &curr_mute_mode);
1121             if (ret < 0)
1122                 return ret;
1123             ctrl->value = curr_mute_mode;
1124             break;
1125
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);
1129             if (ret < 0)
1130                 return ret;
1131             ctrl->value = curr_vol;
1132             break;
1133
1134        default:
1135            pr_debug("(fmdrv): Unhandled IOCTL for get Control\n");
1136            break;
1137     }
1138
1139     return ret;
1140 }
1141
1142 /*
1143 * Function to Set the driver control params. Called
1144 * by user-space via IOCTL call
1145 */
1146 static int fm_v4l2_vidioc_s_ctrl(struct file *file, void *priv,
1147                     struct v4l2_control *ctrl)
1148 {
1149     int ret = -EINVAL;
1150     struct fmdrv_ops *fmdev;
1151
1152     pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1153     fmdev = video_drvdata(file);
1154
1155     switch (ctrl->id) {
1156         case V4L2_CID_AUDIO_MUTE:    /* set mute */
1157             ret = fm_rx_set_mute_mode(fmdev, (unsigned char)ctrl->value);
1158             if (ret < 0)
1159                 return ret;
1160             break;
1161
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);
1165             if (ret < 0){
1166                 pr_info ("(fmdrv): V4L2_CID_AUDIO_VOLUME ret : %d\n", ret);
1167                 return ret;
1168             }
1169             break;
1170
1171         default:
1172             pr_debug("(fmdrv): Unhandled IOCTL for set Control\n");
1173             break;
1174     }
1175
1176     return ret;
1177 }
1178
1179 /*
1180 * Function to get the driver audio params. Called
1181 * by user-space via IOCTL call
1182 */
1183 static int fm_v4l2_vidioc_g_audio(struct file *file, void *priv,
1184                     struct v4l2_audio *audio)
1185 {
1186     memset(audio, 0, sizeof(*audio));
1187     audio->index = 0;
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;
1192     return 0;
1193 }
1194
1195 /*
1196 * Function to set the driver audio params. Called
1197 * by user-space via IOCTL call
1198 */
1199 static int fm_v4l2_vidioc_s_audio(struct file *file, void *priv,
1200                     const struct v4l2_audio *audio)
1201 {
1202     if (audio->index != 0)
1203         return -EINVAL;
1204     return 0;
1205 }
1206
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)
1211 {
1212     unsigned short curr_rssi;
1213     unsigned int high = 0, low = 0;
1214     int ret = -EINVAL;
1215     struct fmdrv_ops *fmdev;
1216
1217     if (tuner->index != 0)
1218         return ret;
1219
1220     pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1221
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;
1229
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;
1234
1235     ret = fm_rx_read_curr_rssi_freq(fmdev, TRUE);
1236     curr_rssi = fmdev->rx.curr_rssi;
1237
1238     pr_info ("(fmdrv): fm_v4l2_vidioc_g_tuner curr_rssi : %d\n", curr_rssi);
1239
1240     /* This is absolute value of negative dBm on SC2331 chipset */
1241     tuner->signal = curr_rssi;
1242     ret = 0;
1243     return ret;
1244 }
1245
1246 /* Set tuner attributes. This IOCTL call will set attributes like
1247    upper/lower frequency, audio mode.
1248  */
1249 static int fm_v4l2_vidioc_s_tuner(struct file *file, void *priv,
1250                     const struct v4l2_tuner *tuner)
1251 {
1252     int ret = -EINVAL;
1253     struct fmdrv_ops *fmdev;
1254     unsigned short high_freq, low_freq;
1255     unsigned short mode;
1256     if (tuner->index != 0)
1257         return ret;
1258
1259     pr_info("(fmdrv): %s, f_count %ld\n", __func__, file_count(file));
1260
1261     fmdev = video_drvdata(file);
1262
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)
1268     {
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);
1274         if (ret < 0)
1275             return ret;
1276     }
1277
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;
1281
1282     ret = fmc_set_audio_mode(fmdev, mode);
1283     if (ret < 0)
1284         return ret;
1285     return 0;
1286 }
1287
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)
1291 {
1292     int ret;
1293     struct fmdrv_ops *fmdev;
1294
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);
1302     if (ret < 0)
1303         return ret;
1304     return 0;
1305 }
1306
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)
1310 {
1311     int ret = 0;
1312     struct fmdrv_ops *fmdev;
1313     unsigned int frequency;
1314
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);
1323     if (ret < 0)
1324         return ret;
1325     return 0;
1326 }
1327
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)
1331 {
1332     int ret = -EINVAL;
1333     struct fmdrv_ops *fmdev;
1334     if (seek->tuner != 0)
1335         return -EINVAL;
1336
1337     fmdev = video_drvdata(file);
1338
1339 #if V4L2_FM_DEBUG
1340     pr_debug("(fmdrv) %s direction:%d wrap:%d f_count: %ld\n", __func__,
1341                                 seek->seek_upward, seek->wrap_around, file_count(file));
1342 #endif
1343     ret = fmc_seek_station(fmdev, seek->seek_upward, seek->wrap_around);
1344
1345     if (ret < 0)
1346         return ret;
1347     return 0;
1348 }
1349
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,
1360 };
1361
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
1374 };
1375
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,
1383 };
1384
1385 int fm_v4l2_init_video_device(struct fmdrv_ops *fmdev, int radio_nr)
1386 {
1387     int ret = -ENOMEM;
1388
1389     /* Init mutex for core locking */
1390     mutex_init(&fmdev->mutex);
1391     mutex_init(&fmdev->completionmutex);
1392
1393     gradio_dev = NULL;
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");
1398         return -ENOMEM;
1399     }
1400
1401     /* Setup FM driver's V4L2 properties */
1402     memcpy(gradio_dev, &fm_viddev_template, sizeof(fm_viddev_template));
1403
1404     video_set_drvdata(gradio_dev, fmdev);
1405
1406     gradio_dev->lock = &fmdev->mutex;
1407
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");
1412         return -EINVAL;
1413     }
1414
1415     fmdev->radio_dev = gradio_dev;
1416
1417     pr_info("(fmdrv) registered with video device\n");
1418
1419     /* Register sysfs entries */
1420     ret = sysfs_create_group(&fmdev->radio_dev->dev.kobj,
1421             &v4l2_fm_attr_grp);
1422     if (ret) {
1423         pr_err("(fmdrv) %s(): failed to create sysfs entries\n", __func__);
1424         return -ENOTDIR;
1425     }
1426
1427     kobject_uevent(&fmdev->radio_dev->dev.kobj, KOBJ_ADD);
1428     ret = 0;
1429
1430     return ret;
1431 }
1432
1433 void *fm_v4l2_deinit_video_device(void)
1434 {
1435     struct fmdrv_ops *fmdev;
1436
1437     fmdev = video_get_drvdata(gradio_dev);
1438
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);
1442
1443     /* Unregister RADIO device from V4L2 subsystem */
1444     video_unregister_device(gradio_dev);
1445
1446     return fmdev;
1447 }