1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115#include "radio-si470x.h"
116
117
118
119
120
121
122
123
124
125
126
127static unsigned short space = 2;
128module_param(space, ushort, 0444);
129MODULE_PARM_DESC(space, "Spacing: 0=200kHz 1=100kHz *2=50kHz*");
130
131
132
133
134static unsigned short de = 1;
135module_param(de, ushort, 0444);
136MODULE_PARM_DESC(de, "De-emphasis: 0=75us *1=50us*");
137
138
139static unsigned int tune_timeout = 3000;
140module_param(tune_timeout, uint, 0644);
141MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*");
142
143
144static unsigned int seek_timeout = 5000;
145module_param(seek_timeout, uint, 0644);
146MODULE_PARM_DESC(seek_timeout, "Seek timeout: *5000*");
147
148static const struct v4l2_frequency_band bands[] = {
149 {
150 .type = V4L2_TUNER_RADIO,
151 .index = 0,
152 .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
153 V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO |
154 V4L2_TUNER_CAP_FREQ_BANDS |
155 V4L2_TUNER_CAP_HWSEEK_BOUNDED |
156 V4L2_TUNER_CAP_HWSEEK_WRAP,
157 .rangelow = 87500 * 16,
158 .rangehigh = 108000 * 16,
159 .modulation = V4L2_BAND_MODULATION_FM,
160 },
161 {
162 .type = V4L2_TUNER_RADIO,
163 .index = 1,
164 .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
165 V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO |
166 V4L2_TUNER_CAP_FREQ_BANDS |
167 V4L2_TUNER_CAP_HWSEEK_BOUNDED |
168 V4L2_TUNER_CAP_HWSEEK_WRAP,
169 .rangelow = 76000 * 16,
170 .rangehigh = 108000 * 16,
171 .modulation = V4L2_BAND_MODULATION_FM,
172 },
173 {
174 .type = V4L2_TUNER_RADIO,
175 .index = 2,
176 .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
177 V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO |
178 V4L2_TUNER_CAP_FREQ_BANDS |
179 V4L2_TUNER_CAP_HWSEEK_BOUNDED |
180 V4L2_TUNER_CAP_HWSEEK_WRAP,
181 .rangelow = 76000 * 16,
182 .rangehigh = 90000 * 16,
183 .modulation = V4L2_BAND_MODULATION_FM,
184 },
185};
186
187
188
189
190
191
192
193
194static int si470x_set_band(struct si470x_device *radio, int band)
195{
196 if (radio->band == band)
197 return 0;
198
199 radio->band = band;
200 radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_BAND;
201 radio->registers[SYSCONFIG2] |= radio->band << 6;
202 return si470x_set_register(radio, SYSCONFIG2);
203}
204
205
206
207
208static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
209{
210 int retval;
211 bool timed_out = 0;
212
213
214 radio->registers[CHANNEL] &= ~CHANNEL_CHAN;
215 radio->registers[CHANNEL] |= CHANNEL_TUNE | chan;
216 retval = si470x_set_register(radio, CHANNEL);
217 if (retval < 0)
218 goto done;
219
220
221 INIT_COMPLETION(radio->completion);
222 retval = wait_for_completion_timeout(&radio->completion,
223 msecs_to_jiffies(tune_timeout));
224 if (!retval)
225 timed_out = true;
226
227 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
228 dev_warn(&radio->videodev.dev, "tune does not complete\n");
229 if (timed_out)
230 dev_warn(&radio->videodev.dev,
231 "tune timed out after %u ms\n", tune_timeout);
232
233
234 radio->registers[CHANNEL] &= ~CHANNEL_TUNE;
235 retval = si470x_set_register(radio, CHANNEL);
236
237done:
238 return retval;
239}
240
241
242
243
244static unsigned int si470x_get_step(struct si470x_device *radio)
245{
246
247 switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) {
248
249 case 0:
250 return 200 * 16;
251
252 case 1:
253 return 100 * 16;
254
255 default:
256 return 50 * 16;
257 };
258}
259
260
261
262
263
264static int si470x_get_freq(struct si470x_device *radio, unsigned int *freq)
265{
266 int chan, retval;
267
268
269 retval = si470x_get_register(radio, READCHAN);
270 chan = radio->registers[READCHAN] & READCHAN_READCHAN;
271
272
273 *freq = chan * si470x_get_step(radio) + bands[radio->band].rangelow;
274
275 return retval;
276}
277
278
279
280
281
282int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
283{
284 unsigned short chan;
285
286 freq = clamp(freq, bands[radio->band].rangelow,
287 bands[radio->band].rangehigh);
288
289 chan = (freq - bands[radio->band].rangelow) / si470x_get_step(radio);
290
291 return si470x_set_chan(radio, chan);
292}
293
294
295
296
297
298static int si470x_set_seek(struct si470x_device *radio,
299 const struct v4l2_hw_freq_seek *seek)
300{
301 int band, retval;
302 unsigned int freq;
303 bool timed_out = 0;
304
305
306 if (seek->rangelow || seek->rangehigh) {
307 for (band = 0; band < ARRAY_SIZE(bands); band++) {
308 if (bands[band].rangelow == seek->rangelow &&
309 bands[band].rangehigh == seek->rangehigh)
310 break;
311 }
312 if (band == ARRAY_SIZE(bands))
313 return -EINVAL;
314 } else
315 band = 1;
316
317 if (radio->band != band) {
318 retval = si470x_get_freq(radio, &freq);
319 if (retval)
320 return retval;
321 retval = si470x_set_band(radio, band);
322 if (retval)
323 return retval;
324 retval = si470x_set_freq(radio, freq);
325 if (retval)
326 return retval;
327 }
328
329
330 radio->registers[POWERCFG] |= POWERCFG_SEEK;
331 if (seek->wrap_around)
332 radio->registers[POWERCFG] &= ~POWERCFG_SKMODE;
333 else
334 radio->registers[POWERCFG] |= POWERCFG_SKMODE;
335 if (seek->seek_upward)
336 radio->registers[POWERCFG] |= POWERCFG_SEEKUP;
337 else
338 radio->registers[POWERCFG] &= ~POWERCFG_SEEKUP;
339 retval = si470x_set_register(radio, POWERCFG);
340 if (retval < 0)
341 return retval;
342
343
344 INIT_COMPLETION(radio->completion);
345 retval = wait_for_completion_timeout(&radio->completion,
346 msecs_to_jiffies(seek_timeout));
347 if (!retval)
348 timed_out = true;
349
350 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
351 dev_warn(&radio->videodev.dev, "seek does not complete\n");
352 if (radio->registers[STATUSRSSI] & STATUSRSSI_SF)
353 dev_warn(&radio->videodev.dev,
354 "seek failed / band limit reached\n");
355
356
357 radio->registers[POWERCFG] &= ~POWERCFG_SEEK;
358 retval = si470x_set_register(radio, POWERCFG);
359
360
361 if (retval == 0 && timed_out)
362 return -ENODATA;
363 return retval;
364}
365
366
367
368
369
370int si470x_start(struct si470x_device *radio)
371{
372 int retval;
373
374
375 radio->registers[POWERCFG] =
376 POWERCFG_DMUTE | POWERCFG_ENABLE | POWERCFG_RDSM;
377 retval = si470x_set_register(radio, POWERCFG);
378 if (retval < 0)
379 goto done;
380
381
382 radio->registers[SYSCONFIG1] =
383 (de << 11) & SYSCONFIG1_DE;
384 retval = si470x_set_register(radio, SYSCONFIG1);
385 if (retval < 0)
386 goto done;
387
388
389 radio->registers[SYSCONFIG2] =
390 (0x1f << 8) |
391 ((radio->band << 6) & SYSCONFIG2_BAND) |
392 ((space << 4) & SYSCONFIG2_SPACE) |
393 15;
394 retval = si470x_set_register(radio, SYSCONFIG2);
395 if (retval < 0)
396 goto done;
397
398
399 retval = si470x_set_chan(radio,
400 radio->registers[CHANNEL] & CHANNEL_CHAN);
401
402done:
403 return retval;
404}
405
406
407
408
409
410int si470x_stop(struct si470x_device *radio)
411{
412 int retval;
413
414
415 radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS;
416 retval = si470x_set_register(radio, SYSCONFIG1);
417 if (retval < 0)
418 goto done;
419
420
421 radio->registers[POWERCFG] &= ~POWERCFG_DMUTE;
422
423 radio->registers[POWERCFG] |= POWERCFG_ENABLE | POWERCFG_DISABLE;
424 retval = si470x_set_register(radio, POWERCFG);
425
426done:
427 return retval;
428}
429
430
431
432
433
434static int si470x_rds_on(struct si470x_device *radio)
435{
436 int retval;
437
438
439 radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDS;
440 retval = si470x_set_register(radio, SYSCONFIG1);
441 if (retval < 0)
442 radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS;
443
444 return retval;
445}
446
447
448
449
450
451
452
453
454
455
456static ssize_t si470x_fops_read(struct file *file, char __user *buf,
457 size_t count, loff_t *ppos)
458{
459 struct si470x_device *radio = video_drvdata(file);
460 int retval = 0;
461 unsigned int block_count = 0;
462
463
464 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
465 si470x_rds_on(radio);
466
467
468 while (radio->wr_index == radio->rd_index) {
469 if (file->f_flags & O_NONBLOCK) {
470 retval = -EWOULDBLOCK;
471 goto done;
472 }
473 if (wait_event_interruptible(radio->read_queue,
474 radio->wr_index != radio->rd_index) < 0) {
475 retval = -EINTR;
476 goto done;
477 }
478 }
479
480
481 count /= 3;
482
483
484 while (block_count < count) {
485 if (radio->rd_index == radio->wr_index)
486 break;
487
488
489 if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3))
490
491 break;
492
493
494 radio->rd_index += 3;
495 if (radio->rd_index >= radio->buf_size)
496 radio->rd_index = 0;
497
498
499 block_count++;
500 buf += 3;
501 retval += 3;
502 }
503
504done:
505 return retval;
506}
507
508
509
510
511
512static unsigned int si470x_fops_poll(struct file *file,
513 struct poll_table_struct *pts)
514{
515 struct si470x_device *radio = video_drvdata(file);
516 unsigned long req_events = poll_requested_events(pts);
517 int retval = v4l2_ctrl_poll(file, pts);
518
519 if (req_events & (POLLIN | POLLRDNORM)) {
520
521 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
522 si470x_rds_on(radio);
523
524 poll_wait(file, &radio->read_queue, pts);
525
526 if (radio->rd_index != radio->wr_index)
527 retval |= POLLIN | POLLRDNORM;
528 }
529
530 return retval;
531}
532
533
534
535
536
537static const struct v4l2_file_operations si470x_fops = {
538 .owner = THIS_MODULE,
539 .read = si470x_fops_read,
540 .poll = si470x_fops_poll,
541 .unlocked_ioctl = video_ioctl2,
542 .open = si470x_fops_open,
543 .release = si470x_fops_release,
544};
545
546
547
548
549
550
551
552
553static int si470x_s_ctrl(struct v4l2_ctrl *ctrl)
554{
555 struct si470x_device *radio =
556 container_of(ctrl->handler, struct si470x_device, hdl);
557
558 switch (ctrl->id) {
559 case V4L2_CID_AUDIO_VOLUME:
560 radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME;
561 radio->registers[SYSCONFIG2] |= ctrl->val;
562 return si470x_set_register(radio, SYSCONFIG2);
563 case V4L2_CID_AUDIO_MUTE:
564 if (ctrl->val)
565 radio->registers[POWERCFG] &= ~POWERCFG_DMUTE;
566 else
567 radio->registers[POWERCFG] |= POWERCFG_DMUTE;
568 return si470x_set_register(radio, POWERCFG);
569 default:
570 return -EINVAL;
571 }
572}
573
574
575
576
577
578static int si470x_vidioc_g_tuner(struct file *file, void *priv,
579 struct v4l2_tuner *tuner)
580{
581 struct si470x_device *radio = video_drvdata(file);
582 int retval = 0;
583
584 if (tuner->index != 0)
585 return -EINVAL;
586
587 if (!radio->status_rssi_auto_update) {
588 retval = si470x_get_register(radio, STATUSRSSI);
589 if (retval < 0)
590 return retval;
591 }
592
593
594 strcpy(tuner->name, "FM");
595 tuner->type = V4L2_TUNER_RADIO;
596 tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
597 V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO |
598 V4L2_TUNER_CAP_HWSEEK_BOUNDED |
599 V4L2_TUNER_CAP_HWSEEK_WRAP;
600 tuner->rangelow = 76 * FREQ_MUL;
601 tuner->rangehigh = 108 * FREQ_MUL;
602
603
604 if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 0)
605 tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
606 else
607 tuner->rxsubchans = V4L2_TUNER_SUB_STEREO;
608
609
610
611 tuner->rxsubchans |= V4L2_TUNER_SUB_RDS;
612
613
614 if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 0)
615 tuner->audmode = V4L2_TUNER_MODE_STEREO;
616 else
617 tuner->audmode = V4L2_TUNER_MODE_MONO;
618
619
620
621 tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI);
622
623 tuner->signal = (tuner->signal * 873) + (8 * tuner->signal / 10);
624 if (tuner->signal > 0xffff)
625 tuner->signal = 0xffff;
626
627
628
629 tuner->afc = (radio->registers[STATUSRSSI] & STATUSRSSI_AFCRL) ? 1 : 0;
630
631 return retval;
632}
633
634
635
636
637
638static int si470x_vidioc_s_tuner(struct file *file, void *priv,
639 const struct v4l2_tuner *tuner)
640{
641 struct si470x_device *radio = video_drvdata(file);
642
643 if (tuner->index != 0)
644 return -EINVAL;
645
646
647 switch (tuner->audmode) {
648 case V4L2_TUNER_MODE_MONO:
649 radio->registers[POWERCFG] |= POWERCFG_MONO;
650 break;
651 case V4L2_TUNER_MODE_STEREO:
652 default:
653 radio->registers[POWERCFG] &= ~POWERCFG_MONO;
654 break;
655 }
656
657 return si470x_set_register(radio, POWERCFG);
658}
659
660
661
662
663
664static int si470x_vidioc_g_frequency(struct file *file, void *priv,
665 struct v4l2_frequency *freq)
666{
667 struct si470x_device *radio = video_drvdata(file);
668
669 if (freq->tuner != 0)
670 return -EINVAL;
671
672 freq->type = V4L2_TUNER_RADIO;
673 return si470x_get_freq(radio, &freq->frequency);
674}
675
676
677
678
679
680static int si470x_vidioc_s_frequency(struct file *file, void *priv,
681 const struct v4l2_frequency *freq)
682{
683 struct si470x_device *radio = video_drvdata(file);
684 int retval;
685
686 if (freq->tuner != 0)
687 return -EINVAL;
688
689 if (freq->frequency < bands[radio->band].rangelow ||
690 freq->frequency > bands[radio->band].rangehigh) {
691
692 retval = si470x_set_band(radio, 1);
693 if (retval)
694 return retval;
695 }
696 return si470x_set_freq(radio, freq->frequency);
697}
698
699
700
701
702
703static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv,
704 const struct v4l2_hw_freq_seek *seek)
705{
706 struct si470x_device *radio = video_drvdata(file);
707
708 if (seek->tuner != 0)
709 return -EINVAL;
710
711 if (file->f_flags & O_NONBLOCK)
712 return -EWOULDBLOCK;
713
714 return si470x_set_seek(radio, seek);
715}
716
717
718
719
720static int si470x_vidioc_enum_freq_bands(struct file *file, void *priv,
721 struct v4l2_frequency_band *band)
722{
723 if (band->tuner != 0)
724 return -EINVAL;
725 if (band->index >= ARRAY_SIZE(bands))
726 return -EINVAL;
727 *band = bands[band->index];
728 return 0;
729}
730
731const struct v4l2_ctrl_ops si470x_ctrl_ops = {
732 .s_ctrl = si470x_s_ctrl,
733};
734
735
736
737
738static const struct v4l2_ioctl_ops si470x_ioctl_ops = {
739 .vidioc_querycap = si470x_vidioc_querycap,
740 .vidioc_g_tuner = si470x_vidioc_g_tuner,
741 .vidioc_s_tuner = si470x_vidioc_s_tuner,
742 .vidioc_g_frequency = si470x_vidioc_g_frequency,
743 .vidioc_s_frequency = si470x_vidioc_s_frequency,
744 .vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek,
745 .vidioc_enum_freq_bands = si470x_vidioc_enum_freq_bands,
746 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
747 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
748};
749
750
751
752
753
754struct video_device si470x_viddev_template = {
755 .fops = &si470x_fops,
756 .name = DRIVER_NAME,
757 .release = video_device_release_empty,
758 .ioctl_ops = &si470x_ioctl_ops,
759};
760