aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/radio')
-rw-r--r--drivers/media/radio/Kconfig4
-rw-r--r--drivers/media/radio/Makefile1
-rw-r--r--drivers/media/radio/dsbr100.c128
-rw-r--r--drivers/media/radio/radio-si4713.c3
-rw-r--r--drivers/media/radio/radio-timb.c3
-rw-r--r--drivers/media/radio/radio-wl1273.c367
-rw-r--r--drivers/media/radio/si470x/radio-si470x-common.c1
-rw-r--r--drivers/media/radio/wl128x/Kconfig17
-rw-r--r--drivers/media/radio/wl128x/Makefile6
-rw-r--r--drivers/media/radio/wl128x/fmdrv.h244
-rw-r--r--drivers/media/radio/wl128x/fmdrv_common.c1677
-rw-r--r--drivers/media/radio/wl128x/fmdrv_common.h402
-rw-r--r--drivers/media/radio/wl128x/fmdrv_rx.c847
-rw-r--r--drivers/media/radio/wl128x/fmdrv_rx.h59
-rw-r--r--drivers/media/radio/wl128x/fmdrv_tx.c425
-rw-r--r--drivers/media/radio/wl128x/fmdrv_tx.h37
-rw-r--r--drivers/media/radio/wl128x/fmdrv_v4l2.c580
-rw-r--r--drivers/media/radio/wl128x/fmdrv_v4l2.h33
18 files changed, 4481 insertions, 353 deletions
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 851716a7da0e..e4c97fd6f05a 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -426,6 +426,7 @@ config RADIO_TIMBERDALE
426config RADIO_WL1273 426config RADIO_WL1273
427 tristate "Texas Instruments WL1273 I2C FM Radio" 427 tristate "Texas Instruments WL1273 I2C FM Radio"
428 depends on I2C && VIDEO_V4L2 428 depends on I2C && VIDEO_V4L2
429 select MFD_CORE
429 select MFD_WL1273_CORE 430 select MFD_WL1273_CORE
430 select FW_LOADER 431 select FW_LOADER
431 ---help--- 432 ---help---
@@ -439,4 +440,7 @@ config RADIO_WL1273
439 To compile this driver as a module, choose M here: the 440 To compile this driver as a module, choose M here: the
440 module will be called radio-wl1273. 441 module will be called radio-wl1273.
441 442
443# TI's ST based wl128x FM radio
444source "drivers/media/radio/wl128x/Kconfig"
445
442endif # RADIO_ADAPTERS 446endif # RADIO_ADAPTERS
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index d68907fc7925..f484a6e04eb2 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -25,5 +25,6 @@ obj-$(CONFIG_RADIO_SAA7706H) += saa7706h.o
25obj-$(CONFIG_RADIO_TEF6862) += tef6862.o 25obj-$(CONFIG_RADIO_TEF6862) += tef6862.o
26obj-$(CONFIG_RADIO_TIMBERDALE) += radio-timb.o 26obj-$(CONFIG_RADIO_TIMBERDALE) += radio-timb.o
27obj-$(CONFIG_RADIO_WL1273) += radio-wl1273.o 27obj-$(CONFIG_RADIO_WL1273) += radio-wl1273.o
28obj-$(CONFIG_RADIO_WL128X) += wl128x/
28 29
29EXTRA_CFLAGS += -Isound 30EXTRA_CFLAGS += -Isound
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index ed9cd7ad0604..3d8cc425fa6b 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -129,7 +129,7 @@ devices, that would be 76 and 91. */
129#define STARTED 0 129#define STARTED 0
130#define STOPPED 1 130#define STOPPED 1
131 131
132#define videodev_to_radio(d) container_of(d, struct dsbr100_device, videodev) 132#define v4l2_dev_to_radio(d) container_of(d, struct dsbr100_device, v4l2_dev)
133 133
134static int usb_dsbr100_probe(struct usb_interface *intf, 134static int usb_dsbr100_probe(struct usb_interface *intf,
135 const struct usb_device_id *id); 135 const struct usb_device_id *id);
@@ -148,10 +148,9 @@ struct dsbr100_device {
148 struct v4l2_device v4l2_dev; 148 struct v4l2_device v4l2_dev;
149 149
150 u8 *transfer_buffer; 150 u8 *transfer_buffer;
151 struct mutex lock; /* buffer locking */ 151 struct mutex v4l2_lock;
152 int curfreq; 152 int curfreq;
153 int stereo; 153 int stereo;
154 int removed;
155 int status; 154 int status;
156}; 155};
157 156
@@ -182,8 +181,6 @@ static int dsbr100_start(struct dsbr100_device *radio)
182 int retval; 181 int retval;
183 int request; 182 int request;
184 183
185 mutex_lock(&radio->lock);
186
187 retval = usb_control_msg(radio->usbdev, 184 retval = usb_control_msg(radio->usbdev,
188 usb_rcvctrlpipe(radio->usbdev, 0), 185 usb_rcvctrlpipe(radio->usbdev, 0),
189 USB_REQ_GET_STATUS, 186 USB_REQ_GET_STATUS,
@@ -207,11 +204,9 @@ static int dsbr100_start(struct dsbr100_device *radio)
207 } 204 }
208 205
209 radio->status = STARTED; 206 radio->status = STARTED;
210 mutex_unlock(&radio->lock);
211 return (radio->transfer_buffer)[0]; 207 return (radio->transfer_buffer)[0];
212 208
213usb_control_msg_failed: 209usb_control_msg_failed:
214 mutex_unlock(&radio->lock);
215 dev_err(&radio->usbdev->dev, 210 dev_err(&radio->usbdev->dev,
216 "%s - usb_control_msg returned %i, request %i\n", 211 "%s - usb_control_msg returned %i, request %i\n",
217 __func__, retval, request); 212 __func__, retval, request);
@@ -225,8 +220,6 @@ static int dsbr100_stop(struct dsbr100_device *radio)
225 int retval; 220 int retval;
226 int request; 221 int request;
227 222
228 mutex_lock(&radio->lock);
229
230 retval = usb_control_msg(radio->usbdev, 223 retval = usb_control_msg(radio->usbdev,
231 usb_rcvctrlpipe(radio->usbdev, 0), 224 usb_rcvctrlpipe(radio->usbdev, 0),
232 USB_REQ_GET_STATUS, 225 USB_REQ_GET_STATUS,
@@ -250,11 +243,9 @@ static int dsbr100_stop(struct dsbr100_device *radio)
250 } 243 }
251 244
252 radio->status = STOPPED; 245 radio->status = STOPPED;
253 mutex_unlock(&radio->lock);
254 return (radio->transfer_buffer)[0]; 246 return (radio->transfer_buffer)[0];
255 247
256usb_control_msg_failed: 248usb_control_msg_failed:
257 mutex_unlock(&radio->lock);
258 dev_err(&radio->usbdev->dev, 249 dev_err(&radio->usbdev->dev,
259 "%s - usb_control_msg returned %i, request %i\n", 250 "%s - usb_control_msg returned %i, request %i\n",
260 __func__, retval, request); 251 __func__, retval, request);
@@ -269,8 +260,6 @@ static int dsbr100_setfreq(struct dsbr100_device *radio)
269 int request; 260 int request;
270 int freq = (radio->curfreq / 16 * 80) / 1000 + 856; 261 int freq = (radio->curfreq / 16 * 80) / 1000 + 856;
271 262
272 mutex_lock(&radio->lock);
273
274 retval = usb_control_msg(radio->usbdev, 263 retval = usb_control_msg(radio->usbdev,
275 usb_rcvctrlpipe(radio->usbdev, 0), 264 usb_rcvctrlpipe(radio->usbdev, 0),
276 DSB100_TUNE, 265 DSB100_TUNE,
@@ -306,12 +295,10 @@ static int dsbr100_setfreq(struct dsbr100_device *radio)
306 } 295 }
307 296
308 radio->stereo = !((radio->transfer_buffer)[0] & 0x01); 297 radio->stereo = !((radio->transfer_buffer)[0] & 0x01);
309 mutex_unlock(&radio->lock);
310 return (radio->transfer_buffer)[0]; 298 return (radio->transfer_buffer)[0];
311 299
312usb_control_msg_failed: 300usb_control_msg_failed:
313 radio->stereo = -1; 301 radio->stereo = -1;
314 mutex_unlock(&radio->lock);
315 dev_err(&radio->usbdev->dev, 302 dev_err(&radio->usbdev->dev,
316 "%s - usb_control_msg returned %i, request %i\n", 303 "%s - usb_control_msg returned %i, request %i\n",
317 __func__, retval, request); 304 __func__, retval, request);
@@ -324,8 +311,6 @@ static void dsbr100_getstat(struct dsbr100_device *radio)
324{ 311{
325 int retval; 312 int retval;
326 313
327 mutex_lock(&radio->lock);
328
329 retval = usb_control_msg(radio->usbdev, 314 retval = usb_control_msg(radio->usbdev,
330 usb_rcvctrlpipe(radio->usbdev, 0), 315 usb_rcvctrlpipe(radio->usbdev, 0),
331 USB_REQ_GET_STATUS, 316 USB_REQ_GET_STATUS,
@@ -340,33 +325,8 @@ static void dsbr100_getstat(struct dsbr100_device *radio)
340 } else { 325 } else {
341 radio->stereo = !(radio->transfer_buffer[0] & 0x01); 326 radio->stereo = !(radio->transfer_buffer[0] & 0x01);
342 } 327 }
343
344 mutex_unlock(&radio->lock);
345} 328}
346 329
347/* USB subsystem interface begins here */
348
349/*
350 * Handle unplugging of the device.
351 * We call video_unregister_device in any case.
352 * The last function called in this procedure is
353 * usb_dsbr100_video_device_release
354 */
355static void usb_dsbr100_disconnect(struct usb_interface *intf)
356{
357 struct dsbr100_device *radio = usb_get_intfdata(intf);
358
359 usb_set_intfdata (intf, NULL);
360
361 mutex_lock(&radio->lock);
362 radio->removed = 1;
363 mutex_unlock(&radio->lock);
364
365 video_unregister_device(&radio->videodev);
366 v4l2_device_disconnect(&radio->v4l2_dev);
367}
368
369
370static int vidioc_querycap(struct file *file, void *priv, 330static int vidioc_querycap(struct file *file, void *priv,
371 struct v4l2_capability *v) 331 struct v4l2_capability *v)
372{ 332{
@@ -385,10 +345,6 @@ static int vidioc_g_tuner(struct file *file, void *priv,
385{ 345{
386 struct dsbr100_device *radio = video_drvdata(file); 346 struct dsbr100_device *radio = video_drvdata(file);
387 347
388 /* safety check */
389 if (radio->removed)
390 return -EIO;
391
392 if (v->index > 0) 348 if (v->index > 0)
393 return -EINVAL; 349 return -EINVAL;
394 350
@@ -410,16 +366,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
410static int vidioc_s_tuner(struct file *file, void *priv, 366static int vidioc_s_tuner(struct file *file, void *priv,
411 struct v4l2_tuner *v) 367 struct v4l2_tuner *v)
412{ 368{
413 struct dsbr100_device *radio = video_drvdata(file); 369 return v->index ? -EINVAL : 0;
414
415 /* safety check */
416 if (radio->removed)
417 return -EIO;
418
419 if (v->index > 0)
420 return -EINVAL;
421
422 return 0;
423} 370}
424 371
425static int vidioc_s_frequency(struct file *file, void *priv, 372static int vidioc_s_frequency(struct file *file, void *priv,
@@ -428,13 +375,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
428 struct dsbr100_device *radio = video_drvdata(file); 375 struct dsbr100_device *radio = video_drvdata(file);
429 int retval; 376 int retval;
430 377
431 /* safety check */
432 if (radio->removed)
433 return -EIO;
434
435 mutex_lock(&radio->lock);
436 radio->curfreq = f->frequency; 378 radio->curfreq = f->frequency;
437 mutex_unlock(&radio->lock);
438 379
439 retval = dsbr100_setfreq(radio); 380 retval = dsbr100_setfreq(radio);
440 if (retval < 0) 381 if (retval < 0)
@@ -447,10 +388,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
447{ 388{
448 struct dsbr100_device *radio = video_drvdata(file); 389 struct dsbr100_device *radio = video_drvdata(file);
449 390
450 /* safety check */
451 if (radio->removed)
452 return -EIO;
453
454 f->type = V4L2_TUNER_RADIO; 391 f->type = V4L2_TUNER_RADIO;
455 f->frequency = radio->curfreq; 392 f->frequency = radio->curfreq;
456 return 0; 393 return 0;
@@ -472,10 +409,6 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
472{ 409{
473 struct dsbr100_device *radio = video_drvdata(file); 410 struct dsbr100_device *radio = video_drvdata(file);
474 411
475 /* safety check */
476 if (radio->removed)
477 return -EIO;
478
479 switch (ctrl->id) { 412 switch (ctrl->id) {
480 case V4L2_CID_AUDIO_MUTE: 413 case V4L2_CID_AUDIO_MUTE:
481 ctrl->value = radio->status; 414 ctrl->value = radio->status;
@@ -490,10 +423,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
490 struct dsbr100_device *radio = video_drvdata(file); 423 struct dsbr100_device *radio = video_drvdata(file);
491 int retval; 424 int retval;
492 425
493 /* safety check */
494 if (radio->removed)
495 return -EIO;
496
497 switch (ctrl->id) { 426 switch (ctrl->id) {
498 case V4L2_CID_AUDIO_MUTE: 427 case V4L2_CID_AUDIO_MUTE:
499 if (ctrl->value) { 428 if (ctrl->value) {
@@ -535,25 +464,44 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
535 464
536static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 465static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
537{ 466{
538 if (i != 0) 467 return i ? -EINVAL : 0;
539 return -EINVAL;
540 return 0;
541} 468}
542 469
543static int vidioc_s_audio(struct file *file, void *priv, 470static int vidioc_s_audio(struct file *file, void *priv,
544 struct v4l2_audio *a) 471 struct v4l2_audio *a)
545{ 472{
546 if (a->index != 0) 473 return a->index ? -EINVAL : 0;
547 return -EINVAL; 474}
548 return 0; 475
476/* USB subsystem interface begins here */
477
478/*
479 * Handle unplugging of the device.
480 * We call video_unregister_device in any case.
481 * The last function called in this procedure is
482 * usb_dsbr100_video_device_release
483 */
484static void usb_dsbr100_disconnect(struct usb_interface *intf)
485{
486 struct dsbr100_device *radio = usb_get_intfdata(intf);
487
488 v4l2_device_get(&radio->v4l2_dev);
489 mutex_lock(&radio->v4l2_lock);
490 usb_set_intfdata(intf, NULL);
491 video_unregister_device(&radio->videodev);
492 v4l2_device_disconnect(&radio->v4l2_dev);
493 mutex_unlock(&radio->v4l2_lock);
494 v4l2_device_put(&radio->v4l2_dev);
549} 495}
550 496
497
551/* Suspend device - stop device. */ 498/* Suspend device - stop device. */
552static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message) 499static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message)
553{ 500{
554 struct dsbr100_device *radio = usb_get_intfdata(intf); 501 struct dsbr100_device *radio = usb_get_intfdata(intf);
555 int retval; 502 int retval;
556 503
504 mutex_lock(&radio->v4l2_lock);
557 if (radio->status == STARTED) { 505 if (radio->status == STARTED) {
558 retval = dsbr100_stop(radio); 506 retval = dsbr100_stop(radio);
559 if (retval < 0) 507 if (retval < 0)
@@ -564,11 +512,9 @@ static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message)
564 * we set status equal to STARTED. 512 * we set status equal to STARTED.
565 * On resume we will check status and run radio if needed. 513 * On resume we will check status and run radio if needed.
566 */ 514 */
567
568 mutex_lock(&radio->lock);
569 radio->status = STARTED; 515 radio->status = STARTED;
570 mutex_unlock(&radio->lock);
571 } 516 }
517 mutex_unlock(&radio->v4l2_lock);
572 518
573 dev_info(&intf->dev, "going into suspend..\n"); 519 dev_info(&intf->dev, "going into suspend..\n");
574 520
@@ -581,11 +527,13 @@ static int usb_dsbr100_resume(struct usb_interface *intf)
581 struct dsbr100_device *radio = usb_get_intfdata(intf); 527 struct dsbr100_device *radio = usb_get_intfdata(intf);
582 int retval; 528 int retval;
583 529
530 mutex_lock(&radio->v4l2_lock);
584 if (radio->status == STARTED) { 531 if (radio->status == STARTED) {
585 retval = dsbr100_start(radio); 532 retval = dsbr100_start(radio);
586 if (retval < 0) 533 if (retval < 0)
587 dev_warn(&intf->dev, "dsbr100_start failed\n"); 534 dev_warn(&intf->dev, "dsbr100_start failed\n");
588 } 535 }
536 mutex_unlock(&radio->v4l2_lock);
589 537
590 dev_info(&intf->dev, "coming out of suspend..\n"); 538 dev_info(&intf->dev, "coming out of suspend..\n");
591 539
@@ -593,9 +541,9 @@ static int usb_dsbr100_resume(struct usb_interface *intf)
593} 541}
594 542
595/* free data structures */ 543/* free data structures */
596static void usb_dsbr100_video_device_release(struct video_device *videodev) 544static void usb_dsbr100_release(struct v4l2_device *v4l2_dev)
597{ 545{
598 struct dsbr100_device *radio = videodev_to_radio(videodev); 546 struct dsbr100_device *radio = v4l2_dev_to_radio(v4l2_dev);
599 547
600 v4l2_device_unregister(&radio->v4l2_dev); 548 v4l2_device_unregister(&radio->v4l2_dev);
601 kfree(radio->transfer_buffer); 549 kfree(radio->transfer_buffer);
@@ -605,7 +553,7 @@ static void usb_dsbr100_video_device_release(struct video_device *videodev)
605/* File system interface */ 553/* File system interface */
606static const struct v4l2_file_operations usb_dsbr100_fops = { 554static const struct v4l2_file_operations usb_dsbr100_fops = {
607 .owner = THIS_MODULE, 555 .owner = THIS_MODULE,
608 .ioctl = video_ioctl2, 556 .unlocked_ioctl = video_ioctl2,
609}; 557};
610 558
611static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = { 559static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = {
@@ -644,6 +592,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
644 } 592 }
645 593
646 v4l2_dev = &radio->v4l2_dev; 594 v4l2_dev = &radio->v4l2_dev;
595 v4l2_dev->release = usb_dsbr100_release;
647 596
648 retval = v4l2_device_register(&intf->dev, v4l2_dev); 597 retval = v4l2_device_register(&intf->dev, v4l2_dev);
649 if (retval < 0) { 598 if (retval < 0) {
@@ -653,15 +602,14 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
653 return retval; 602 return retval;
654 } 603 }
655 604
605 mutex_init(&radio->v4l2_lock);
656 strlcpy(radio->videodev.name, v4l2_dev->name, sizeof(radio->videodev.name)); 606 strlcpy(radio->videodev.name, v4l2_dev->name, sizeof(radio->videodev.name));
657 radio->videodev.v4l2_dev = v4l2_dev; 607 radio->videodev.v4l2_dev = v4l2_dev;
658 radio->videodev.fops = &usb_dsbr100_fops; 608 radio->videodev.fops = &usb_dsbr100_fops;
659 radio->videodev.ioctl_ops = &usb_dsbr100_ioctl_ops; 609 radio->videodev.ioctl_ops = &usb_dsbr100_ioctl_ops;
660 radio->videodev.release = usb_dsbr100_video_device_release; 610 radio->videodev.release = video_device_release_empty;
661 611 radio->videodev.lock = &radio->v4l2_lock;
662 mutex_init(&radio->lock);
663 612
664 radio->removed = 0;
665 radio->usbdev = interface_to_usbdev(intf); 613 radio->usbdev = interface_to_usbdev(intf);
666 radio->curfreq = FREQ_MIN * FREQ_MUL; 614 radio->curfreq = FREQ_MIN * FREQ_MUL;
667 radio->status = STOPPED; 615 radio->status = STOPPED;
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c
index 726d367ad8d0..444b4cf7e65c 100644
--- a/drivers/media/radio/radio-si4713.c
+++ b/drivers/media/radio/radio-si4713.c
@@ -224,7 +224,8 @@ static int radio_si4713_s_frequency(struct file *file, void *p,
224 s_frequency, vf); 224 s_frequency, vf);
225} 225}
226 226
227static long radio_si4713_default(struct file *file, void *p, int cmd, void *arg) 227static long radio_si4713_default(struct file *file, void *p,
228 bool valid_prio, int cmd, void *arg)
228{ 229{
229 return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core, 230 return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core,
230 ioctl, cmd, arg); 231 ioctl, cmd, arg);
diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c
index a185610b376b..1e3a8dd820a4 100644
--- a/drivers/media/radio/radio-timb.c
+++ b/drivers/media/radio/radio-timb.c
@@ -21,6 +21,7 @@
21#include <media/v4l2-ioctl.h> 21#include <media/v4l2-ioctl.h>
22#include <media/v4l2-device.h> 22#include <media/v4l2-device.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/mfd/core.h>
24#include <linux/interrupt.h> 25#include <linux/interrupt.h>
25#include <linux/slab.h> 26#include <linux/slab.h>
26#include <linux/i2c.h> 27#include <linux/i2c.h>
@@ -148,7 +149,7 @@ static const struct v4l2_file_operations timbradio_fops = {
148 149
149static int __devinit timbradio_probe(struct platform_device *pdev) 150static int __devinit timbradio_probe(struct platform_device *pdev)
150{ 151{
151 struct timb_radio_platform_data *pdata = pdev->dev.platform_data; 152 struct timb_radio_platform_data *pdata = mfd_get_data(pdev);
152 struct timbradio *tr; 153 struct timbradio *tr;
153 int err; 154 int err;
154 155
diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c
index 7ecc8e657663..e2550dc2944f 100644
--- a/drivers/media/radio/radio-wl1273.c
+++ b/drivers/media/radio/radio-wl1273.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the Texas Instruments WL1273 FM radio. 2 * Driver for the Texas Instruments WL1273 FM radio.
3 * 3 *
4 * Copyright (C) 2010 Nokia Corporation 4 * Copyright (C) 2011 Nokia Corporation
5 * Author: Matti J. Aaltonen <matti.j.aaltonen@nokia.com> 5 * Author: Matti J. Aaltonen <matti.j.aaltonen@nokia.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
@@ -67,7 +67,6 @@ struct wl1273_device {
67 67
68 /* RDS */ 68 /* RDS */
69 unsigned int rds_on; 69 unsigned int rds_on;
70 struct delayed_work work;
71 70
72 wait_queue_head_t read_queue; 71 wait_queue_head_t read_queue;
73 struct mutex lock; /* for serializing fm radio operations */ 72 struct mutex lock; /* for serializing fm radio operations */
@@ -104,58 +103,6 @@ static unsigned int rds_buf = 100;
104module_param(rds_buf, uint, 0); 103module_param(rds_buf, uint, 0);
105MODULE_PARM_DESC(rds_buf, "Number of RDS buffer entries. Default = 100"); 104MODULE_PARM_DESC(rds_buf, "Number of RDS buffer entries. Default = 100");
106 105
107static int wl1273_fm_read_reg(struct wl1273_core *core, u8 reg, u16 *value)
108{
109 struct i2c_client *client = core->client;
110 u8 b[2];
111 int r;
112
113 r = i2c_smbus_read_i2c_block_data(client, reg, sizeof(b), b);
114 if (r != 2) {
115 dev_err(&client->dev, "%s: Read: %d fails.\n", __func__, reg);
116 return -EREMOTEIO;
117 }
118
119 *value = (u16)b[0] << 8 | b[1];
120
121 return 0;
122}
123
124static int wl1273_fm_write_cmd(struct wl1273_core *core, u8 cmd, u16 param)
125{
126 struct i2c_client *client = core->client;
127 u8 buf[] = { (param >> 8) & 0xff, param & 0xff };
128 int r;
129
130 r = i2c_smbus_write_i2c_block_data(client, cmd, sizeof(buf), buf);
131 if (r) {
132 dev_err(&client->dev, "%s: Cmd: %d fails.\n", __func__, cmd);
133 return r;
134 }
135
136 return 0;
137}
138
139static int wl1273_fm_write_data(struct wl1273_core *core, u8 *data, u16 len)
140{
141 struct i2c_client *client = core->client;
142 struct i2c_msg msg;
143 int r;
144
145 msg.addr = client->addr;
146 msg.flags = 0;
147 msg.buf = data;
148 msg.len = len;
149
150 r = i2c_transfer(client->adapter, &msg, 1);
151 if (r != 1) {
152 dev_err(&client->dev, "%s: write error.\n", __func__);
153 return -EREMOTEIO;
154 }
155
156 return 0;
157}
158
159static int wl1273_fm_write_fw(struct wl1273_core *core, 106static int wl1273_fm_write_fw(struct wl1273_core *core,
160 __u8 *fw, int len) 107 __u8 *fw, int len)
161{ 108{
@@ -188,94 +135,6 @@ static int wl1273_fm_write_fw(struct wl1273_core *core,
188 return r; 135 return r;
189} 136}
190 137
191/**
192 * wl1273_fm_set_audio() - Set audio mode.
193 * @core: A pointer to the device struct.
194 * @new_mode: The new audio mode.
195 *
196 * Audio modes are WL1273_AUDIO_DIGITAL and WL1273_AUDIO_ANALOG.
197 */
198static int wl1273_fm_set_audio(struct wl1273_core *core, unsigned int new_mode)
199{
200 int r = 0;
201
202 if (core->mode == WL1273_MODE_OFF ||
203 core->mode == WL1273_MODE_SUSPENDED)
204 return -EPERM;
205
206 if (core->mode == WL1273_MODE_RX && new_mode == WL1273_AUDIO_DIGITAL) {
207 r = wl1273_fm_write_cmd(core, WL1273_PCM_MODE_SET,
208 WL1273_PCM_DEF_MODE);
209 if (r)
210 goto out;
211
212 r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
213 core->i2s_mode);
214 if (r)
215 goto out;
216
217 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
218 WL1273_AUDIO_ENABLE_I2S);
219 if (r)
220 goto out;
221
222 } else if (core->mode == WL1273_MODE_RX &&
223 new_mode == WL1273_AUDIO_ANALOG) {
224 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
225 WL1273_AUDIO_ENABLE_ANALOG);
226 if (r)
227 goto out;
228
229 } else if (core->mode == WL1273_MODE_TX &&
230 new_mode == WL1273_AUDIO_DIGITAL) {
231 r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
232 core->i2s_mode);
233 if (r)
234 goto out;
235
236 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
237 WL1273_AUDIO_IO_SET_I2S);
238 if (r)
239 goto out;
240
241 } else if (core->mode == WL1273_MODE_TX &&
242 new_mode == WL1273_AUDIO_ANALOG) {
243 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
244 WL1273_AUDIO_IO_SET_ANALOG);
245 if (r)
246 goto out;
247 }
248
249 core->audio_mode = new_mode;
250out:
251 return r;
252}
253
254/**
255 * wl1273_fm_set_volume() - Set volume.
256 * @core: A pointer to the device struct.
257 * @volume: The new volume value.
258 */
259static int wl1273_fm_set_volume(struct wl1273_core *core, unsigned int volume)
260{
261 u16 val;
262 int r;
263
264 if (volume > WL1273_MAX_VOLUME)
265 return -EINVAL;
266
267 if (core->volume == volume)
268 return 0;
269
270 val = volume;
271 r = wl1273_fm_read_reg(core, WL1273_VOLUME_SET, &val);
272 if (r)
273 return r;
274
275 core->volume = volume;
276 return 0;
277}
278
279#define WL1273_FIFO_HAS_DATA(status) (1 << 5 & status) 138#define WL1273_FIFO_HAS_DATA(status) (1 << 5 & status)
280#define WL1273_RDS_CORRECTABLE_ERROR (1 << 3) 139#define WL1273_RDS_CORRECTABLE_ERROR (1 << 3)
281#define WL1273_RDS_UNCORRECTABLE_ERROR (1 << 4) 140#define WL1273_RDS_UNCORRECTABLE_ERROR (1 << 4)
@@ -306,7 +165,7 @@ static int wl1273_fm_rds(struct wl1273_device *radio)
306 if (core->mode != WL1273_MODE_RX) 165 if (core->mode != WL1273_MODE_RX)
307 return 0; 166 return 0;
308 167
309 r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val); 168 r = core->read(core, WL1273_RDS_SYNC_GET, &val);
310 if (r) 169 if (r)
311 return r; 170 return r;
312 171
@@ -374,7 +233,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
374 u16 flags; 233 u16 flags;
375 int r; 234 int r;
376 235
377 r = wl1273_fm_read_reg(core, WL1273_FLAG_GET, &flags); 236 r = core->read(core, WL1273_FLAG_GET, &flags);
378 if (r) 237 if (r)
379 goto out; 238 goto out;
380 239
@@ -398,7 +257,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
398 if (flags & WL1273_LEV_EVENT) { 257 if (flags & WL1273_LEV_EVENT) {
399 u16 level; 258 u16 level;
400 259
401 r = wl1273_fm_read_reg(core, WL1273_RSSI_LVL_GET, &level); 260 r = core->read(core, WL1273_RSSI_LVL_GET, &level);
402 if (r) 261 if (r)
403 goto out; 262 goto out;
404 263
@@ -439,8 +298,8 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
439 dev_dbg(radio->dev, "IRQ: FR:\n"); 298 dev_dbg(radio->dev, "IRQ: FR:\n");
440 299
441 if (core->mode == WL1273_MODE_RX) { 300 if (core->mode == WL1273_MODE_RX) {
442 r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET, 301 r = core->write(core, WL1273_TUNER_MODE_SET,
443 TUNER_MODE_STOP_SEARCH); 302 TUNER_MODE_STOP_SEARCH);
444 if (r) { 303 if (r) {
445 dev_err(radio->dev, 304 dev_err(radio->dev,
446 "%s: TUNER_MODE_SET fails: %d\n", 305 "%s: TUNER_MODE_SET fails: %d\n",
@@ -448,7 +307,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
448 goto out; 307 goto out;
449 } 308 }
450 309
451 r = wl1273_fm_read_reg(core, WL1273_FREQ_SET, &freq); 310 r = core->read(core, WL1273_FREQ_SET, &freq);
452 if (r) 311 if (r)
453 goto out; 312 goto out;
454 313
@@ -467,7 +326,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
467 dev_dbg(radio->dev, "%dkHz\n", radio->rx_frequency); 326 dev_dbg(radio->dev, "%dkHz\n", radio->rx_frequency);
468 327
469 } else { 328 } else {
470 r = wl1273_fm_read_reg(core, WL1273_CHANL_SET, &freq); 329 r = core->read(core, WL1273_CHANL_SET, &freq);
471 if (r) 330 if (r)
472 goto out; 331 goto out;
473 332
@@ -477,8 +336,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
477 } 336 }
478 337
479out: 338out:
480 wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, 339 core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
481 radio->irq_flags);
482 complete(&radio->busy); 340 complete(&radio->busy);
483 341
484 return IRQ_HANDLED; 342 return IRQ_HANDLED;
@@ -512,7 +370,7 @@ static int wl1273_fm_set_tx_freq(struct wl1273_device *radio, unsigned int freq)
512 dev_dbg(radio->dev, "%s: freq: %d kHz\n", __func__, freq); 370 dev_dbg(radio->dev, "%s: freq: %d kHz\n", __func__, freq);
513 371
514 /* Set the current tx channel */ 372 /* Set the current tx channel */
515 r = wl1273_fm_write_cmd(core, WL1273_CHANL_SET, freq / 10); 373 r = core->write(core, WL1273_CHANL_SET, freq / 10);
516 if (r) 374 if (r)
517 return r; 375 return r;
518 376
@@ -526,7 +384,7 @@ static int wl1273_fm_set_tx_freq(struct wl1273_device *radio, unsigned int freq)
526 dev_dbg(radio->dev, "WL1273_CHANL_SET: %d\n", r); 384 dev_dbg(radio->dev, "WL1273_CHANL_SET: %d\n", r);
527 385
528 /* Enable the output power */ 386 /* Enable the output power */
529 r = wl1273_fm_write_cmd(core, WL1273_POWER_ENB_SET, 1); 387 r = core->write(core, WL1273_POWER_ENB_SET, 1);
530 if (r) 388 if (r)
531 return r; 389 return r;
532 390
@@ -566,20 +424,20 @@ static int wl1273_fm_set_rx_freq(struct wl1273_device *radio, unsigned int freq)
566 424
567 dev_dbg(radio->dev, "%s: %dkHz\n", __func__, freq); 425 dev_dbg(radio->dev, "%s: %dkHz\n", __func__, freq);
568 426
569 wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, radio->irq_flags); 427 core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
570 428
571 if (radio->band == WL1273_BAND_JAPAN) 429 if (radio->band == WL1273_BAND_JAPAN)
572 f = (freq - WL1273_BAND_JAPAN_LOW) / 50; 430 f = (freq - WL1273_BAND_JAPAN_LOW) / 50;
573 else 431 else
574 f = (freq - WL1273_BAND_OTHER_LOW) / 50; 432 f = (freq - WL1273_BAND_OTHER_LOW) / 50;
575 433
576 r = wl1273_fm_write_cmd(core, WL1273_FREQ_SET, f); 434 r = core->write(core, WL1273_FREQ_SET, f);
577 if (r) { 435 if (r) {
578 dev_err(radio->dev, "FREQ_SET fails\n"); 436 dev_err(radio->dev, "FREQ_SET fails\n");
579 goto err; 437 goto err;
580 } 438 }
581 439
582 r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET, TUNER_MODE_PRESET); 440 r = core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_PRESET);
583 if (r) { 441 if (r) {
584 dev_err(radio->dev, "TUNER_MODE_SET fails\n"); 442 dev_err(radio->dev, "TUNER_MODE_SET fails\n");
585 goto err; 443 goto err;
@@ -609,7 +467,7 @@ static int wl1273_fm_get_freq(struct wl1273_device *radio)
609 int r; 467 int r;
610 468
611 if (core->mode == WL1273_MODE_RX) { 469 if (core->mode == WL1273_MODE_RX) {
612 r = wl1273_fm_read_reg(core, WL1273_FREQ_SET, &f); 470 r = core->read(core, WL1273_FREQ_SET, &f);
613 if (r) 471 if (r)
614 return r; 472 return r;
615 473
@@ -619,7 +477,7 @@ static int wl1273_fm_get_freq(struct wl1273_device *radio)
619 else 477 else
620 freq = WL1273_BAND_OTHER_LOW + 50 * f; 478 freq = WL1273_BAND_OTHER_LOW + 50 * f;
621 } else { 479 } else {
622 r = wl1273_fm_read_reg(core, WL1273_CHANL_SET, &f); 480 r = core->read(core, WL1273_CHANL_SET, &f);
623 if (r) 481 if (r)
624 return r; 482 return r;
625 483
@@ -670,7 +528,7 @@ static int wl1273_fm_upload_firmware_patch(struct wl1273_device *radio)
670 } 528 }
671 529
672 /* ignore possible error here */ 530 /* ignore possible error here */
673 wl1273_fm_write_cmd(core, WL1273_RESET, 0); 531 core->write(core, WL1273_RESET, 0);
674 532
675 dev_dbg(dev, "%s - download OK, r: %d\n", __func__, r); 533 dev_dbg(dev, "%s - download OK, r: %d\n", __func__, r);
676out: 534out:
@@ -683,14 +541,14 @@ static int wl1273_fm_stop(struct wl1273_device *radio)
683 struct wl1273_core *core = radio->core; 541 struct wl1273_core *core = radio->core;
684 542
685 if (core->mode == WL1273_MODE_RX) { 543 if (core->mode == WL1273_MODE_RX) {
686 int r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, 544 int r = core->write(core, WL1273_POWER_SET,
687 WL1273_POWER_SET_OFF); 545 WL1273_POWER_SET_OFF);
688 if (r) 546 if (r)
689 dev_err(radio->dev, "%s: POWER_SET fails: %d\n", 547 dev_err(radio->dev, "%s: POWER_SET fails: %d\n",
690 __func__, r); 548 __func__, r);
691 } else if (core->mode == WL1273_MODE_TX) { 549 } else if (core->mode == WL1273_MODE_TX) {
692 int r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET, 550 int r = core->write(core, WL1273_PUPD_SET,
693 WL1273_PUPD_SET_OFF); 551 WL1273_PUPD_SET_OFF);
694 if (r) 552 if (r)
695 dev_err(radio->dev, 553 dev_err(radio->dev,
696 "%s: PUPD_SET fails: %d\n", __func__, r); 554 "%s: PUPD_SET fails: %d\n", __func__, r);
@@ -725,11 +583,11 @@ static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)
725 val |= WL1273_POWER_SET_RDS; 583 val |= WL1273_POWER_SET_RDS;
726 584
727 /* If this fails try again */ 585 /* If this fails try again */
728 r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, val); 586 r = core->write(core, WL1273_POWER_SET, val);
729 if (r) { 587 if (r) {
730 msleep(100); 588 msleep(100);
731 589
732 r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, val); 590 r = core->write(core, WL1273_POWER_SET, val);
733 if (r) { 591 if (r) {
734 dev_err(dev, "%s: POWER_SET fails\n", __func__); 592 dev_err(dev, "%s: POWER_SET fails\n", __func__);
735 goto fail; 593 goto fail;
@@ -742,11 +600,10 @@ static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)
742 600
743 } else if (new_mode == WL1273_MODE_TX) { 601 } else if (new_mode == WL1273_MODE_TX) {
744 /* If this fails try again once */ 602 /* If this fails try again once */
745 r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET, 603 r = core->write(core, WL1273_PUPD_SET, WL1273_PUPD_SET_ON);
746 WL1273_PUPD_SET_ON);
747 if (r) { 604 if (r) {
748 msleep(100); 605 msleep(100);
749 r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET, 606 r = core->write(core, WL1273_PUPD_SET,
750 WL1273_PUPD_SET_ON); 607 WL1273_PUPD_SET_ON);
751 if (r) { 608 if (r) {
752 dev_err(dev, "%s: PUPD_SET fails\n", __func__); 609 dev_err(dev, "%s: PUPD_SET fails\n", __func__);
@@ -755,9 +612,9 @@ static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)
755 } 612 }
756 613
757 if (radio->rds_on) 614 if (radio->rds_on)
758 r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 1); 615 r = core->write(core, WL1273_RDS_DATA_ENB, 1);
759 else 616 else
760 r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 0); 617 r = core->write(core, WL1273_RDS_DATA_ENB, 0);
761 } else { 618 } else {
762 dev_warn(dev, "%s: Illegal mode.\n", __func__); 619 dev_warn(dev, "%s: Illegal mode.\n", __func__);
763 } 620 }
@@ -777,14 +634,14 @@ static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)
777 if (radio->rds_on) 634 if (radio->rds_on)
778 val |= WL1273_POWER_SET_RDS; 635 val |= WL1273_POWER_SET_RDS;
779 636
780 r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, val); 637 r = core->write(core, WL1273_POWER_SET, val);
781 if (r) { 638 if (r) {
782 dev_err(dev, "%s: POWER_SET fails\n", __func__); 639 dev_err(dev, "%s: POWER_SET fails\n", __func__);
783 goto fail; 640 goto fail;
784 } 641 }
785 } else if (new_mode == WL1273_MODE_TX) { 642 } else if (new_mode == WL1273_MODE_TX) {
786 r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET, 643 r = core->write(core, WL1273_PUPD_SET,
787 WL1273_PUPD_SET_ON); 644 WL1273_PUPD_SET_ON);
788 if (r) { 645 if (r) {
789 dev_err(dev, "%s: PUPD_SET fails\n", __func__); 646 dev_err(dev, "%s: PUPD_SET fails\n", __func__);
790 goto fail; 647 goto fail;
@@ -808,10 +665,10 @@ static int wl1273_fm_suspend(struct wl1273_device *radio)
808 665
809 /* Cannot go from OFF to SUSPENDED */ 666 /* Cannot go from OFF to SUSPENDED */
810 if (core->mode == WL1273_MODE_RX) 667 if (core->mode == WL1273_MODE_RX)
811 r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, 668 r = core->write(core, WL1273_POWER_SET,
812 WL1273_POWER_SET_RETENTION); 669 WL1273_POWER_SET_RETENTION);
813 else if (core->mode == WL1273_MODE_TX) 670 else if (core->mode == WL1273_MODE_TX)
814 r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET, 671 r = core->write(core, WL1273_PUPD_SET,
815 WL1273_PUPD_SET_RETENTION); 672 WL1273_PUPD_SET_RETENTION);
816 else 673 else
817 r = -EINVAL; 674 r = -EINVAL;
@@ -852,8 +709,7 @@ static int wl1273_fm_set_mode(struct wl1273_device *radio, int mode)
852 } 709 }
853 710
854 core->mode = mode; 711 core->mode = mode;
855 r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, 712 r = core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
856 radio->irq_flags);
857 if (r) { 713 if (r) {
858 dev_err(dev, "INT_MASK_SET fails.\n"); 714 dev_err(dev, "INT_MASK_SET fails.\n");
859 goto out; 715 goto out;
@@ -951,22 +807,21 @@ static int wl1273_fm_set_seek(struct wl1273_device *radio,
951 INIT_COMPLETION(radio->busy); 807 INIT_COMPLETION(radio->busy);
952 dev_dbg(radio->dev, "%s: BUSY\n", __func__); 808 dev_dbg(radio->dev, "%s: BUSY\n", __func__);
953 809
954 r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, radio->irq_flags); 810 r = core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
955 if (r) 811 if (r)
956 goto out; 812 goto out;
957 813
958 dev_dbg(radio->dev, "%s\n", __func__); 814 dev_dbg(radio->dev, "%s\n", __func__);
959 815
960 r = wl1273_fm_write_cmd(core, WL1273_SEARCH_LVL_SET, level); 816 r = core->write(core, WL1273_SEARCH_LVL_SET, level);
961 if (r) 817 if (r)
962 goto out; 818 goto out;
963 819
964 r = wl1273_fm_write_cmd(core, WL1273_SEARCH_DIR_SET, dir); 820 r = core->write(core, WL1273_SEARCH_DIR_SET, dir);
965 if (r) 821 if (r)
966 goto out; 822 goto out;
967 823
968 r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET, 824 r = core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_AUTO_SEEK);
969 TUNER_MODE_AUTO_SEEK);
970 if (r) 825 if (r)
971 goto out; 826 goto out;
972 827
@@ -994,8 +849,7 @@ static int wl1273_fm_set_seek(struct wl1273_device *radio,
994 INIT_COMPLETION(radio->busy); 849 INIT_COMPLETION(radio->busy);
995 dev_dbg(radio->dev, "%s: BUSY\n", __func__); 850 dev_dbg(radio->dev, "%s: BUSY\n", __func__);
996 851
997 r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET, 852 r = core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_AUTO_SEEK);
998 TUNER_MODE_AUTO_SEEK);
999 if (r) 853 if (r)
1000 goto out; 854 goto out;
1001 855
@@ -1020,7 +874,7 @@ static unsigned int wl1273_fm_get_tx_ctune(struct wl1273_device *radio)
1020 core->mode == WL1273_MODE_SUSPENDED) 874 core->mode == WL1273_MODE_SUSPENDED)
1021 return -EPERM; 875 return -EPERM;
1022 876
1023 r = wl1273_fm_read_reg(core, WL1273_READ_FMANT_TUNE_VALUE, &val); 877 r = core->read(core, WL1273_READ_FMANT_TUNE_VALUE, &val);
1024 if (r) { 878 if (r) {
1025 dev_err(dev, "%s: read error: %d\n", __func__, r); 879 dev_err(dev, "%s: read error: %d\n", __func__, r);
1026 goto out; 880 goto out;
@@ -1066,7 +920,7 @@ static int wl1273_fm_set_preemphasis(struct wl1273_device *radio,
1066 goto out; 920 goto out;
1067 } 921 }
1068 922
1069 r = wl1273_fm_write_cmd(core, WL1273_PREMPH_SET, em); 923 r = core->write(core, WL1273_PREMPH_SET, em);
1070 if (r) 924 if (r)
1071 goto out; 925 goto out;
1072 926
@@ -1086,7 +940,7 @@ static int wl1273_fm_rds_on(struct wl1273_device *radio)
1086 if (radio->rds_on) 940 if (radio->rds_on)
1087 return 0; 941 return 0;
1088 942
1089 r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, 943 r = core->write(core, WL1273_POWER_SET,
1090 WL1273_POWER_SET_FM | WL1273_POWER_SET_RDS); 944 WL1273_POWER_SET_FM | WL1273_POWER_SET_RDS);
1091 if (r) 945 if (r)
1092 goto out; 946 goto out;
@@ -1108,19 +962,16 @@ static int wl1273_fm_rds_off(struct wl1273_device *radio)
1108 962
1109 radio->irq_flags &= ~WL1273_RDS_EVENT; 963 radio->irq_flags &= ~WL1273_RDS_EVENT;
1110 964
1111 r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, radio->irq_flags); 965 r = core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
1112 if (r) 966 if (r)
1113 goto out; 967 goto out;
1114 968
1115 /* stop rds reception */
1116 cancel_delayed_work(&radio->work);
1117
1118 /* Service pending read */ 969 /* Service pending read */
1119 wake_up_interruptible(&radio->read_queue); 970 wake_up_interruptible(&radio->read_queue);
1120 971
1121 dev_dbg(radio->dev, "%s\n", __func__); 972 dev_dbg(radio->dev, "%s\n", __func__);
1122 973
1123 r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, WL1273_POWER_SET_FM); 974 r = core->write(core, WL1273_POWER_SET, WL1273_POWER_SET_FM);
1124 if (r) 975 if (r)
1125 goto out; 976 goto out;
1126 977
@@ -1143,14 +994,14 @@ static int wl1273_fm_set_rds(struct wl1273_device *radio, unsigned int new_mode)
1143 return -EPERM; 994 return -EPERM;
1144 995
1145 if (new_mode == WL1273_RDS_RESET) { 996 if (new_mode == WL1273_RDS_RESET) {
1146 r = wl1273_fm_write_cmd(core, WL1273_RDS_CNTRL_SET, 1); 997 r = core->write(core, WL1273_RDS_CNTRL_SET, 1);
1147 return r; 998 return r;
1148 } 999 }
1149 1000
1150 if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_OFF) { 1001 if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_OFF) {
1151 r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 0); 1002 r = core->write(core, WL1273_RDS_DATA_ENB, 0);
1152 } else if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_ON) { 1003 } else if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_ON) {
1153 r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 1); 1004 r = core->write(core, WL1273_RDS_DATA_ENB, 1);
1154 } else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_OFF) { 1005 } else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_OFF) {
1155 r = wl1273_fm_rds_off(radio); 1006 r = wl1273_fm_rds_off(radio);
1156 } else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_ON) { 1007 } else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_ON) {
@@ -1171,12 +1022,13 @@ static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *buf,
1171 size_t count, loff_t *ppos) 1022 size_t count, loff_t *ppos)
1172{ 1023{
1173 struct wl1273_device *radio = video_get_drvdata(video_devdata(file)); 1024 struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
1025 struct wl1273_core *core = radio->core;
1174 u16 val; 1026 u16 val;
1175 int r; 1027 int r;
1176 1028
1177 dev_dbg(radio->dev, "%s\n", __func__); 1029 dev_dbg(radio->dev, "%s\n", __func__);
1178 1030
1179 if (radio->core->mode != WL1273_MODE_TX) 1031 if (core->mode != WL1273_MODE_TX)
1180 return count; 1032 return count;
1181 1033
1182 if (radio->rds_users == 0) { 1034 if (radio->rds_users == 0) {
@@ -1184,7 +1036,7 @@ static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *buf,
1184 return 0; 1036 return 0;
1185 } 1037 }
1186 1038
1187 if (mutex_lock_interruptible(&radio->core->lock)) 1039 if (mutex_lock_interruptible(&core->lock))
1188 return -EINTR; 1040 return -EINTR;
1189 /* 1041 /*
1190 * Multiple processes can open the device, but only 1042 * Multiple processes can open the device, but only
@@ -1202,7 +1054,7 @@ static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *buf,
1202 else 1054 else
1203 val = count; 1055 val = count;
1204 1056
1205 wl1273_fm_write_cmd(radio->core, WL1273_RDS_CONFIG_DATA_SET, val); 1057 core->write(core, WL1273_RDS_CONFIG_DATA_SET, val);
1206 1058
1207 if (copy_from_user(radio->write_buf + 1, buf, val)) { 1059 if (copy_from_user(radio->write_buf + 1, buf, val)) {
1208 r = -EFAULT; 1060 r = -EFAULT;
@@ -1213,11 +1065,11 @@ static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *buf,
1213 dev_dbg(radio->dev, "From user: \"%s\"\n", radio->write_buf); 1065 dev_dbg(radio->dev, "From user: \"%s\"\n", radio->write_buf);
1214 1066
1215 radio->write_buf[0] = WL1273_RDS_DATA_SET; 1067 radio->write_buf[0] = WL1273_RDS_DATA_SET;
1216 wl1273_fm_write_data(radio->core, radio->write_buf, val + 1); 1068 core->write_data(core, radio->write_buf, val + 1);
1217 1069
1218 r = val; 1070 r = val;
1219out: 1071out:
1220 mutex_unlock(&radio->core->lock); 1072 mutex_unlock(&core->lock);
1221 1073
1222 return r; 1074 return r;
1223} 1075}
@@ -1263,8 +1115,8 @@ static int wl1273_fm_fops_open(struct file *file)
1263 1115
1264 radio->irq_flags |= WL1273_RDS_EVENT; 1116 radio->irq_flags |= WL1273_RDS_EVENT;
1265 1117
1266 r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, 1118 r = core->write(core, WL1273_INT_MASK_SET,
1267 radio->irq_flags); 1119 radio->irq_flags);
1268 if (r) { 1120 if (r) {
1269 mutex_unlock(&core->lock); 1121 mutex_unlock(&core->lock);
1270 goto out; 1122 goto out;
@@ -1295,9 +1147,9 @@ static int wl1273_fm_fops_release(struct file *file)
1295 radio->irq_flags &= ~WL1273_RDS_EVENT; 1147 radio->irq_flags &= ~WL1273_RDS_EVENT;
1296 1148
1297 if (core->mode == WL1273_MODE_RX) { 1149 if (core->mode == WL1273_MODE_RX) {
1298 r = wl1273_fm_write_cmd(core, 1150 r = core->write(core,
1299 WL1273_INT_MASK_SET, 1151 WL1273_INT_MASK_SET,
1300 radio->irq_flags); 1152 radio->irq_flags);
1301 if (r) { 1153 if (r) {
1302 mutex_unlock(&core->lock); 1154 mutex_unlock(&core->lock);
1303 goto out; 1155 goto out;
@@ -1324,7 +1176,7 @@ static ssize_t wl1273_fm_fops_read(struct file *file, char __user *buf,
1324 1176
1325 dev_dbg(radio->dev, "%s\n", __func__); 1177 dev_dbg(radio->dev, "%s\n", __func__);
1326 1178
1327 if (radio->core->mode != WL1273_MODE_RX) 1179 if (core->mode != WL1273_MODE_RX)
1328 return 0; 1180 return 0;
1329 1181
1330 if (radio->rds_users == 0) { 1182 if (radio->rds_users == 0) {
@@ -1345,7 +1197,7 @@ static ssize_t wl1273_fm_fops_read(struct file *file, char __user *buf,
1345 } 1197 }
1346 radio->owner = file; 1198 radio->owner = file;
1347 1199
1348 r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val); 1200 r = core->read(core, WL1273_RDS_SYNC_GET, &val);
1349 if (r) { 1201 if (r) {
1350 dev_err(radio->dev, "%s: Get RDS_SYNC fails.\n", __func__); 1202 dev_err(radio->dev, "%s: Get RDS_SYNC fails.\n", __func__);
1351 goto out; 1203 goto out;
@@ -1466,23 +1318,24 @@ static int wl1273_fm_vidioc_s_input(struct file *file, void *priv,
1466 */ 1318 */
1467static int wl1273_fm_set_tx_power(struct wl1273_device *radio, u16 power) 1319static int wl1273_fm_set_tx_power(struct wl1273_device *radio, u16 power)
1468{ 1320{
1321 struct wl1273_core *core = radio->core;
1469 int r; 1322 int r;
1470 1323
1471 if (radio->core->mode == WL1273_MODE_OFF || 1324 if (core->mode == WL1273_MODE_OFF ||
1472 radio->core->mode == WL1273_MODE_SUSPENDED) 1325 core->mode == WL1273_MODE_SUSPENDED)
1473 return -EPERM; 1326 return -EPERM;
1474 1327
1475 mutex_lock(&radio->core->lock); 1328 mutex_lock(&core->lock);
1476 1329
1477 /* Convert the dBuV value to chip presentation */ 1330 /* Convert the dBuV value to chip presentation */
1478 r = wl1273_fm_write_cmd(radio->core, WL1273_POWER_LEV_SET, 122 - power); 1331 r = core->write(core, WL1273_POWER_LEV_SET, 122 - power);
1479 if (r) 1332 if (r)
1480 goto out; 1333 goto out;
1481 1334
1482 radio->tx_power = power; 1335 radio->tx_power = power;
1483 1336
1484out: 1337out:
1485 mutex_unlock(&radio->core->lock); 1338 mutex_unlock(&core->lock);
1486 return r; 1339 return r;
1487} 1340}
1488 1341
@@ -1493,23 +1346,24 @@ out:
1493static int wl1273_fm_tx_set_spacing(struct wl1273_device *radio, 1346static int wl1273_fm_tx_set_spacing(struct wl1273_device *radio,
1494 unsigned int spacing) 1347 unsigned int spacing)
1495{ 1348{
1349 struct wl1273_core *core = radio->core;
1496 int r; 1350 int r;
1497 1351
1498 if (spacing == 0) { 1352 if (spacing == 0) {
1499 r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET, 1353 r = core->write(core, WL1273_SCAN_SPACING_SET,
1500 WL1273_SPACING_100kHz); 1354 WL1273_SPACING_100kHz);
1501 radio->spacing = 100; 1355 radio->spacing = 100;
1502 } else if (spacing - 50000 < 25000) { 1356 } else if (spacing - 50000 < 25000) {
1503 r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET, 1357 r = core->write(core, WL1273_SCAN_SPACING_SET,
1504 WL1273_SPACING_50kHz); 1358 WL1273_SPACING_50kHz);
1505 radio->spacing = 50; 1359 radio->spacing = 50;
1506 } else if (spacing - 100000 < 50000) { 1360 } else if (spacing - 100000 < 50000) {
1507 r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET, 1361 r = core->write(core, WL1273_SCAN_SPACING_SET,
1508 WL1273_SPACING_100kHz); 1362 WL1273_SPACING_100kHz);
1509 radio->spacing = 100; 1363 radio->spacing = 100;
1510 } else { 1364 } else {
1511 r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET, 1365 r = core->write(core, WL1273_SCAN_SPACING_SET,
1512 WL1273_SPACING_200kHz); 1366 WL1273_SPACING_200kHz);
1513 radio->spacing = 200; 1367 radio->spacing = 200;
1514 } 1368 }
1515 1369
@@ -1567,17 +1421,17 @@ static int wl1273_fm_vidioc_s_ctrl(struct v4l2_ctrl *ctrl)
1567 return -EINTR; 1421 return -EINTR;
1568 1422
1569 if (core->mode == WL1273_MODE_RX && ctrl->val) 1423 if (core->mode == WL1273_MODE_RX && ctrl->val)
1570 r = wl1273_fm_write_cmd(core, 1424 r = core->write(core,
1571 WL1273_MUTE_STATUS_SET, 1425 WL1273_MUTE_STATUS_SET,
1572 WL1273_MUTE_HARD_LEFT | 1426 WL1273_MUTE_HARD_LEFT |
1573 WL1273_MUTE_HARD_RIGHT); 1427 WL1273_MUTE_HARD_RIGHT);
1574 else if (core->mode == WL1273_MODE_RX) 1428 else if (core->mode == WL1273_MODE_RX)
1575 r = wl1273_fm_write_cmd(core, 1429 r = core->write(core,
1576 WL1273_MUTE_STATUS_SET, 0x0); 1430 WL1273_MUTE_STATUS_SET, 0x0);
1577 else if (core->mode == WL1273_MODE_TX && ctrl->val) 1431 else if (core->mode == WL1273_MODE_TX && ctrl->val)
1578 r = wl1273_fm_write_cmd(core, WL1273_MUTE, 1); 1432 r = core->write(core, WL1273_MUTE, 1);
1579 else if (core->mode == WL1273_MODE_TX) 1433 else if (core->mode == WL1273_MODE_TX)
1580 r = wl1273_fm_write_cmd(core, WL1273_MUTE, 0); 1434 r = core->write(core, WL1273_MUTE, 0);
1581 1435
1582 mutex_unlock(&core->lock); 1436 mutex_unlock(&core->lock);
1583 break; 1437 break;
@@ -1672,7 +1526,7 @@ static int wl1273_fm_vidioc_g_tuner(struct file *file, void *priv,
1672 if (mutex_lock_interruptible(&core->lock)) 1526 if (mutex_lock_interruptible(&core->lock))
1673 return -EINTR; 1527 return -EINTR;
1674 1528
1675 r = wl1273_fm_read_reg(core, WL1273_STEREO_GET, &val); 1529 r = core->read(core, WL1273_STEREO_GET, &val);
1676 if (r) 1530 if (r)
1677 goto out; 1531 goto out;
1678 1532
@@ -1681,7 +1535,7 @@ static int wl1273_fm_vidioc_g_tuner(struct file *file, void *priv,
1681 else 1535 else
1682 tuner->rxsubchans = V4L2_TUNER_SUB_MONO; 1536 tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
1683 1537
1684 r = wl1273_fm_read_reg(core, WL1273_RSSI_LVL_GET, &val); 1538 r = core->read(core, WL1273_RSSI_LVL_GET, &val);
1685 if (r) 1539 if (r)
1686 goto out; 1540 goto out;
1687 1541
@@ -1690,7 +1544,7 @@ static int wl1273_fm_vidioc_g_tuner(struct file *file, void *priv,
1690 1544
1691 tuner->afc = 0; 1545 tuner->afc = 0;
1692 1546
1693 r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val); 1547 r = core->read(core, WL1273_RDS_SYNC_GET, &val);
1694 if (r) 1548 if (r)
1695 goto out; 1549 goto out;
1696 1550
@@ -1736,8 +1590,7 @@ static int wl1273_fm_vidioc_s_tuner(struct file *file, void *priv,
1736 dev_warn(radio->dev, "%s: RDS fails: %d\n", __func__, r); 1590 dev_warn(radio->dev, "%s: RDS fails: %d\n", __func__, r);
1737 1591
1738 if (tuner->audmode == V4L2_TUNER_MODE_MONO) { 1592 if (tuner->audmode == V4L2_TUNER_MODE_MONO) {
1739 r = wl1273_fm_write_cmd(core, WL1273_MOST_MODE_SET, 1593 r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_MONO);
1740 WL1273_RX_MONO);
1741 if (r < 0) { 1594 if (r < 0) {
1742 dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n", 1595 dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n",
1743 __func__, r); 1596 __func__, r);
@@ -1745,8 +1598,7 @@ static int wl1273_fm_vidioc_s_tuner(struct file *file, void *priv,
1745 } 1598 }
1746 radio->stereo = false; 1599 radio->stereo = false;
1747 } else if (tuner->audmode == V4L2_TUNER_MODE_STEREO) { 1600 } else if (tuner->audmode == V4L2_TUNER_MODE_STEREO) {
1748 r = wl1273_fm_write_cmd(core, WL1273_MOST_MODE_SET, 1601 r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_STEREO);
1749 WL1273_RX_STEREO);
1750 if (r < 0) { 1602 if (r < 0) {
1751 dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n", 1603 dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n",
1752 __func__, r); 1604 __func__, r);
@@ -1885,10 +1737,10 @@ static int wl1273_fm_vidioc_s_modulator(struct file *file, void *priv,
1885 r = wl1273_fm_set_rds(radio, WL1273_RDS_OFF); 1737 r = wl1273_fm_set_rds(radio, WL1273_RDS_OFF);
1886 1738
1887 if (modulator->txsubchans & V4L2_TUNER_SUB_MONO) 1739 if (modulator->txsubchans & V4L2_TUNER_SUB_MONO)
1888 r = wl1273_fm_write_cmd(core, WL1273_MONO_SET, WL1273_TX_MONO); 1740 r = core->write(core, WL1273_MONO_SET, WL1273_TX_MONO);
1889 else 1741 else
1890 r = wl1273_fm_write_cmd(core, WL1273_MONO_SET, 1742 r = core->write(core, WL1273_MONO_SET,
1891 WL1273_RX_STEREO); 1743 WL1273_RX_STEREO);
1892 if (r < 0) 1744 if (r < 0)
1893 dev_warn(radio->dev, WL1273_FM_DRIVER_NAME 1745 dev_warn(radio->dev, WL1273_FM_DRIVER_NAME
1894 "MONO_SET fails: %d\n", r); 1746 "MONO_SET fails: %d\n", r);
@@ -1923,7 +1775,7 @@ static int wl1273_fm_vidioc_g_modulator(struct file *file, void *priv,
1923 if (mutex_lock_interruptible(&core->lock)) 1775 if (mutex_lock_interruptible(&core->lock))
1924 return -EINTR; 1776 return -EINTR;
1925 1777
1926 r = wl1273_fm_read_reg(core, WL1273_MONO_SET, &val); 1778 r = core->read(core, WL1273_MONO_SET, &val);
1927 if (r) 1779 if (r)
1928 goto out; 1780 goto out;
1929 1781
@@ -1960,38 +1812,38 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
1960 return 0; 1812 return 0;
1961 } 1813 }
1962 1814
1963 r = wl1273_fm_read_reg(core, WL1273_ASIC_ID_GET, &val); 1815 r = core->read(core, WL1273_ASIC_ID_GET, &val);
1964 if (r) 1816 if (r)
1965 dev_err(dev, "%s: Get ASIC_ID fails.\n", __func__); 1817 dev_err(dev, "%s: Get ASIC_ID fails.\n", __func__);
1966 else 1818 else
1967 dev_info(dev, "ASIC_ID: 0x%04x\n", val); 1819 dev_info(dev, "ASIC_ID: 0x%04x\n", val);
1968 1820
1969 r = wl1273_fm_read_reg(core, WL1273_ASIC_VER_GET, &val); 1821 r = core->read(core, WL1273_ASIC_VER_GET, &val);
1970 if (r) 1822 if (r)
1971 dev_err(dev, "%s: Get ASIC_VER fails.\n", __func__); 1823 dev_err(dev, "%s: Get ASIC_VER fails.\n", __func__);
1972 else 1824 else
1973 dev_info(dev, "ASIC Version: 0x%04x\n", val); 1825 dev_info(dev, "ASIC Version: 0x%04x\n", val);
1974 1826
1975 r = wl1273_fm_read_reg(core, WL1273_FIRM_VER_GET, &val); 1827 r = core->read(core, WL1273_FIRM_VER_GET, &val);
1976 if (r) 1828 if (r)
1977 dev_err(dev, "%s: Get FIRM_VER fails.\n", __func__); 1829 dev_err(dev, "%s: Get FIRM_VER fails.\n", __func__);
1978 else 1830 else
1979 dev_info(dev, "FW version: %d(0x%04x)\n", val, val); 1831 dev_info(dev, "FW version: %d(0x%04x)\n", val, val);
1980 1832
1981 r = wl1273_fm_read_reg(core, WL1273_BAND_SET, &val); 1833 r = core->read(core, WL1273_BAND_SET, &val);
1982 if (r) 1834 if (r)
1983 dev_err(dev, "%s: Get BAND fails.\n", __func__); 1835 dev_err(dev, "%s: Get BAND fails.\n", __func__);
1984 else 1836 else
1985 dev_info(dev, "BAND: %d\n", val); 1837 dev_info(dev, "BAND: %d\n", val);
1986 1838
1987 if (core->mode == WL1273_MODE_TX) { 1839 if (core->mode == WL1273_MODE_TX) {
1988 r = wl1273_fm_read_reg(core, WL1273_PUPD_SET, &val); 1840 r = core->read(core, WL1273_PUPD_SET, &val);
1989 if (r) 1841 if (r)
1990 dev_err(dev, "%s: Get PUPD fails.\n", __func__); 1842 dev_err(dev, "%s: Get PUPD fails.\n", __func__);
1991 else 1843 else
1992 dev_info(dev, "PUPD: 0x%04x\n", val); 1844 dev_info(dev, "PUPD: 0x%04x\n", val);
1993 1845
1994 r = wl1273_fm_read_reg(core, WL1273_CHANL_SET, &val); 1846 r = core->read(core, WL1273_CHANL_SET, &val);
1995 if (r) 1847 if (r)
1996 dev_err(dev, "%s: Get CHANL fails.\n", __func__); 1848 dev_err(dev, "%s: Get CHANL fails.\n", __func__);
1997 else 1849 else
@@ -1999,13 +1851,13 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
1999 } else if (core->mode == WL1273_MODE_RX) { 1851 } else if (core->mode == WL1273_MODE_RX) {
2000 int bf = radio->rangelow; 1852 int bf = radio->rangelow;
2001 1853
2002 r = wl1273_fm_read_reg(core, WL1273_FREQ_SET, &val); 1854 r = core->read(core, WL1273_FREQ_SET, &val);
2003 if (r) 1855 if (r)
2004 dev_err(dev, "%s: Get FREQ fails.\n", __func__); 1856 dev_err(dev, "%s: Get FREQ fails.\n", __func__);
2005 else 1857 else
2006 dev_info(dev, "RX Frequency: %dkHz\n", bf + val*50); 1858 dev_info(dev, "RX Frequency: %dkHz\n", bf + val*50);
2007 1859
2008 r = wl1273_fm_read_reg(core, WL1273_MOST_MODE_SET, &val); 1860 r = core->read(core, WL1273_MOST_MODE_SET, &val);
2009 if (r) 1861 if (r)
2010 dev_err(dev, "%s: Get MOST_MODE fails.\n", 1862 dev_err(dev, "%s: Get MOST_MODE fails.\n",
2011 __func__); 1863 __func__);
@@ -2016,7 +1868,7 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
2016 else 1868 else
2017 dev_info(dev, "MOST_MODE: Unexpected value: %d\n", val); 1869 dev_info(dev, "MOST_MODE: Unexpected value: %d\n", val);
2018 1870
2019 r = wl1273_fm_read_reg(core, WL1273_MOST_BLEND_SET, &val); 1871 r = core->read(core, WL1273_MOST_BLEND_SET, &val);
2020 if (r) 1872 if (r)
2021 dev_err(dev, "%s: Get MOST_BLEND fails.\n", __func__); 1873 dev_err(dev, "%s: Get MOST_BLEND fails.\n", __func__);
2022 else if (val == 0) 1874 else if (val == 0)
@@ -2027,7 +1879,7 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
2027 else 1879 else
2028 dev_info(dev, "MOST_BLEND: Unexpected val: %d\n", val); 1880 dev_info(dev, "MOST_BLEND: Unexpected val: %d\n", val);
2029 1881
2030 r = wl1273_fm_read_reg(core, WL1273_STEREO_GET, &val); 1882 r = core->read(core, WL1273_STEREO_GET, &val);
2031 if (r) 1883 if (r)
2032 dev_err(dev, "%s: Get STEREO fails.\n", __func__); 1884 dev_err(dev, "%s: Get STEREO fails.\n", __func__);
2033 else if (val == 0) 1885 else if (val == 0)
@@ -2037,25 +1889,25 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
2037 else 1889 else
2038 dev_info(dev, "STEREO: Unexpected value: %d\n", val); 1890 dev_info(dev, "STEREO: Unexpected value: %d\n", val);
2039 1891
2040 r = wl1273_fm_read_reg(core, WL1273_RSSI_LVL_GET, &val); 1892 r = core->read(core, WL1273_RSSI_LVL_GET, &val);
2041 if (r) 1893 if (r)
2042 dev_err(dev, "%s: Get RSSI_LVL fails.\n", __func__); 1894 dev_err(dev, "%s: Get RSSI_LVL fails.\n", __func__);
2043 else 1895 else
2044 dev_info(dev, "RX signal strength: %d\n", (s16) val); 1896 dev_info(dev, "RX signal strength: %d\n", (s16) val);
2045 1897
2046 r = wl1273_fm_read_reg(core, WL1273_POWER_SET, &val); 1898 r = core->read(core, WL1273_POWER_SET, &val);
2047 if (r) 1899 if (r)
2048 dev_err(dev, "%s: Get POWER fails.\n", __func__); 1900 dev_err(dev, "%s: Get POWER fails.\n", __func__);
2049 else 1901 else
2050 dev_info(dev, "POWER: 0x%04x\n", val); 1902 dev_info(dev, "POWER: 0x%04x\n", val);
2051 1903
2052 r = wl1273_fm_read_reg(core, WL1273_INT_MASK_SET, &val); 1904 r = core->read(core, WL1273_INT_MASK_SET, &val);
2053 if (r) 1905 if (r)
2054 dev_err(dev, "%s: Get INT_MASK fails.\n", __func__); 1906 dev_err(dev, "%s: Get INT_MASK fails.\n", __func__);
2055 else 1907 else
2056 dev_info(dev, "INT_MASK: 0x%04x\n", val); 1908 dev_info(dev, "INT_MASK: 0x%04x\n", val);
2057 1909
2058 r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val); 1910 r = core->read(core, WL1273_RDS_SYNC_GET, &val);
2059 if (r) 1911 if (r)
2060 dev_err(dev, "%s: Get RDS_SYNC fails.\n", 1912 dev_err(dev, "%s: Get RDS_SYNC fails.\n",
2061 __func__); 1913 __func__);
@@ -2067,14 +1919,14 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
2067 else 1919 else
2068 dev_info(dev, "RDS_SYNC: Unexpected value: %d\n", val); 1920 dev_info(dev, "RDS_SYNC: Unexpected value: %d\n", val);
2069 1921
2070 r = wl1273_fm_read_reg(core, WL1273_I2S_MODE_CONFIG_SET, &val); 1922 r = core->read(core, WL1273_I2S_MODE_CONFIG_SET, &val);
2071 if (r) 1923 if (r)
2072 dev_err(dev, "%s: Get I2S_MODE_CONFIG fails.\n", 1924 dev_err(dev, "%s: Get I2S_MODE_CONFIG fails.\n",
2073 __func__); 1925 __func__);
2074 else 1926 else
2075 dev_info(dev, "I2S_MODE_CONFIG: 0x%04x\n", val); 1927 dev_info(dev, "I2S_MODE_CONFIG: 0x%04x\n", val);
2076 1928
2077 r = wl1273_fm_read_reg(core, WL1273_VOLUME_SET, &val); 1929 r = core->read(core, WL1273_VOLUME_SET, &val);
2078 if (r) 1930 if (r)
2079 dev_err(dev, "%s: Get VOLUME fails.\n", __func__); 1931 dev_err(dev, "%s: Get VOLUME fails.\n", __func__);
2080 else 1932 else
@@ -2138,7 +1990,7 @@ static int wl1273_fm_radio_remove(struct platform_device *pdev)
2138 1990
2139static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev) 1991static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev)
2140{ 1992{
2141 struct wl1273_core **core = pdev->dev.platform_data; 1993 struct wl1273_core **core = mfd_get_data(pdev);
2142 struct wl1273_device *radio; 1994 struct wl1273_device *radio;
2143 struct v4l2_ctrl *ctrl; 1995 struct v4l2_ctrl *ctrl;
2144 int r = 0; 1996 int r = 0;
@@ -2184,10 +2036,6 @@ static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev)
2184 radio->stereo = true; 2036 radio->stereo = true;
2185 radio->bus_type = "I2C"; 2037 radio->bus_type = "I2C";
2186 2038
2187 radio->core->write = wl1273_fm_write_cmd;
2188 radio->core->set_audio = wl1273_fm_set_audio;
2189 radio->core->set_volume = wl1273_fm_set_volume;
2190
2191 if (radio->core->pdata->request_resources) { 2039 if (radio->core->pdata->request_resources) {
2192 r = radio->core->pdata->request_resources(radio->core->client); 2040 r = radio->core->pdata->request_resources(radio->core->client);
2193 if (r) { 2041 if (r) {
@@ -2319,7 +2167,6 @@ module_init(wl1273_fm_module_init);
2319 2167
2320static void __exit wl1273_fm_module_exit(void) 2168static void __exit wl1273_fm_module_exit(void)
2321{ 2169{
2322 flush_scheduled_work();
2323 platform_driver_unregister(&wl1273_fm_radio_driver); 2170 platform_driver_unregister(&wl1273_fm_radio_driver);
2324 pr_info(DRIVER_DESC ", Exiting.\n"); 2171 pr_info(DRIVER_DESC ", Exiting.\n");
2325} 2172}
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c
index 60c176fe328e..38ae6cd65790 100644
--- a/drivers/media/radio/si470x/radio-si470x-common.c
+++ b/drivers/media/radio/si470x/radio-si470x-common.c
@@ -460,7 +460,6 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf,
460 count /= 3; 460 count /= 3;
461 461
462 /* copy RDS block out of internal buffer and to user buffer */ 462 /* copy RDS block out of internal buffer and to user buffer */
463 mutex_lock(&radio->lock);
464 while (block_count < count) { 463 while (block_count < count) {
465 if (radio->rd_index == radio->wr_index) 464 if (radio->rd_index == radio->wr_index)
466 break; 465 break;
diff --git a/drivers/media/radio/wl128x/Kconfig b/drivers/media/radio/wl128x/Kconfig
new file mode 100644
index 000000000000..749f67b192e7
--- /dev/null
+++ b/drivers/media/radio/wl128x/Kconfig
@@ -0,0 +1,17 @@
1#
2# TI's wl128x FM driver based on TI's ST driver.
3#
4menu "Texas Instruments WL128x FM driver (ST based)"
5config RADIO_WL128X
6 tristate "Texas Instruments WL128x FM Radio"
7 depends on VIDEO_V4L2 && RFKILL
8 select TI_ST
9 help
10 Choose Y here if you have this FM radio chip.
11
12 In order to control your radio card, you will need to use programs
13 that are compatible with the Video For Linux 2 API. Information on
14 this API and pointers to "v4l2" programs may be found at
15 <file:Documentation/video4linux/API.html>.
16
17endmenu
diff --git a/drivers/media/radio/wl128x/Makefile b/drivers/media/radio/wl128x/Makefile
new file mode 100644
index 000000000000..32a0ead09845
--- /dev/null
+++ b/drivers/media/radio/wl128x/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for TI's shared transport driver based wl128x
3# FM radio.
4#
5obj-$(CONFIG_RADIO_WL128X) += fm_drv.o
6fm_drv-objs := fmdrv_common.o fmdrv_rx.o fmdrv_tx.o fmdrv_v4l2.o
diff --git a/drivers/media/radio/wl128x/fmdrv.h b/drivers/media/radio/wl128x/fmdrv.h
new file mode 100644
index 000000000000..5db6fd14cf3c
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv.h
@@ -0,0 +1,244 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 *
4 * Common header for all FM driver sub-modules.
5 *
6 * Copyright (C) 2011 Texas Instruments
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#ifndef _FM_DRV_H
24#define _FM_DRV_H
25
26#include <linux/skbuff.h>
27#include <linux/interrupt.h>
28#include <sound/core.h>
29#include <sound/initval.h>
30#include <linux/timer.h>
31#include <linux/version.h>
32#include <media/v4l2-ioctl.h>
33#include <media/v4l2-common.h>
34#include <media/v4l2-ctrls.h>
35
36#define FM_DRV_VERSION "0.10"
37/* Should match with FM_DRV_VERSION */
38#define FM_DRV_RADIO_VERSION KERNEL_VERSION(0, 0, 1)
39#define FM_DRV_NAME "ti_fmdrv"
40#define FM_DRV_CARD_SHORT_NAME "TI FM Radio"
41#define FM_DRV_CARD_LONG_NAME "Texas Instruments FM Radio"
42
43/* Flag info */
44#define FM_INTTASK_RUNNING 0
45#define FM_INTTASK_SCHEDULE_PENDING 1
46#define FM_FW_DW_INPROGRESS 2
47#define FM_CORE_READY 3
48#define FM_CORE_TRANSPORT_READY 4
49#define FM_AF_SWITCH_INPROGRESS 5
50#define FM_CORE_TX_XMITING 6
51
52#define FM_TUNE_COMPLETE 0x1
53#define FM_BAND_LIMIT 0x2
54
55#define FM_DRV_TX_TIMEOUT (5*HZ) /* 5 seconds */
56#define FM_DRV_RX_SEEK_TIMEOUT (20*HZ) /* 20 seconds */
57
58#define NO_OF_ENTRIES_IN_ARRAY(array) (sizeof(array) / sizeof(array[0]))
59
60#define fmerr(format, ...) \
61 printk(KERN_ERR "fmdrv: " format, ## __VA_ARGS__)
62#define fmwarn(format, ...) \
63 printk(KERN_WARNING "fmdrv: " format, ##__VA_ARGS__)
64#ifdef DEBUG
65#define fmdbg(format, ...) \
66 printk(KERN_DEBUG "fmdrv: " format, ## __VA_ARGS__)
67#else /* DEBUG */
68#define fmdbg(format, ...)
69#endif
70enum {
71 FM_MODE_OFF,
72 FM_MODE_TX,
73 FM_MODE_RX,
74 FM_MODE_ENTRY_MAX
75};
76
77#define FM_RX_RDS_INFO_FIELD_MAX 8 /* 4 Group * 2 Bytes */
78
79/* RX RDS data format */
80struct fm_rdsdata_format {
81 union {
82 struct {
83 u8 buff[FM_RX_RDS_INFO_FIELD_MAX];
84 } groupdatabuff;
85 struct {
86 u16 pidata;
87 u8 blk_b[2];
88 u8 blk_c[2];
89 u8 blk_d[2];
90 } groupgeneral;
91 struct {
92 u16 pidata;
93 u8 blk_b[2];
94 u8 af[2];
95 u8 ps[2];
96 } group0A;
97 struct {
98 u16 pi[2];
99 u8 blk_b[2];
100 u8 ps[2];
101 } group0B;
102 } data;
103};
104
105/* FM region (Europe/US, Japan) info */
106struct region_info {
107 u32 chanl_space;
108 u32 bot_freq;
109 u32 top_freq;
110 u8 fm_band;
111};
112struct fmdev;
113typedef void (*int_handler_prototype) (struct fmdev *);
114
115/* FM Interrupt processing related info */
116struct fm_irq {
117 u8 stage;
118 u16 flag; /* FM interrupt flag */
119 u16 mask; /* FM interrupt mask */
120 /* Interrupt process timeout handler */
121 struct timer_list timer;
122 u8 retry;
123 int_handler_prototype *handlers;
124};
125
126/* RDS info */
127struct fm_rds {
128 u8 flag; /* RX RDS on/off status */
129 u8 last_blk_idx; /* Last received RDS block */
130
131 /* RDS buffer */
132 wait_queue_head_t read_queue;
133 u32 buf_size; /* Size is always multiple of 3 */
134 u32 wr_idx;
135 u32 rd_idx;
136 u8 *buff;
137};
138
139#define FM_RDS_MAX_AF_LIST 25
140
141/*
142 * Current RX channel Alternate Frequency cache.
143 * This info is used to switch to other freq (AF)
144 * when current channel signal strengh is below RSSI threshold.
145 */
146struct tuned_station_info {
147 u16 picode;
148 u32 af_cache[FM_RDS_MAX_AF_LIST];
149 u8 afcache_size;
150 u8 af_list_max;
151};
152
153/* FM RX mode info */
154struct fm_rx {
155 struct region_info region; /* Current selected band */
156 u32 freq; /* Current RX frquency */
157 u8 mute_mode; /* Current mute mode */
158 u8 deemphasis_mode; /* Current deemphasis mode */
159 /* RF dependent soft mute mode */
160 u8 rf_depend_mute;
161 u16 volume; /* Current volume level */
162 u16 rssi_threshold; /* Current RSSI threshold level */
163 /* Holds the index of the current AF jump */
164 u8 afjump_idx;
165 /* Will hold the frequency before the jump */
166 u32 freq_before_jump;
167 u8 rds_mode; /* RDS operation mode (RDS/RDBS) */
168 u8 af_mode; /* Alternate frequency on/off */
169 struct tuned_station_info stat_info;
170 struct fm_rds rds;
171};
172
173#define FMTX_RDS_TXT_STR_SIZE 25
174/*
175 * FM TX RDS data
176 *
177 * @ text_type: is the text following PS or RT
178 * @ text: radio text string which could either be PS or RT
179 * @ af_freq: alternate frequency for Tx
180 * TODO: to be declared in application
181 */
182struct tx_rds {
183 u8 text_type;
184 u8 text[FMTX_RDS_TXT_STR_SIZE];
185 u8 flag;
186 u32 af_freq;
187};
188/*
189 * FM TX global data
190 *
191 * @ pwr_lvl: Power Level of the Transmission from mixer control
192 * @ xmit_state: Transmission state = Updated locally upon Start/Stop
193 * @ audio_io: i2S/Analog
194 * @ tx_frq: Transmission frequency
195 */
196struct fmtx_data {
197 u8 pwr_lvl;
198 u8 xmit_state;
199 u8 audio_io;
200 u8 region;
201 u16 aud_mode;
202 u32 preemph;
203 u32 tx_frq;
204 struct tx_rds rds;
205};
206
207/* FM driver operation structure */
208struct fmdev {
209 struct video_device *radio_dev; /* V4L2 video device pointer */
210 struct snd_card *card; /* Card which holds FM mixer controls */
211 u16 asci_id;
212 spinlock_t rds_buff_lock; /* To protect access to RDS buffer */
213 spinlock_t resp_skb_lock; /* To protect access to received SKB */
214
215 long flag; /* FM driver state machine info */
216 u8 streg_cbdata; /* status of ST registration */
217
218 struct sk_buff_head rx_q; /* RX queue */
219 struct tasklet_struct rx_task; /* RX Tasklet */
220
221 struct sk_buff_head tx_q; /* TX queue */
222 struct tasklet_struct tx_task; /* TX Tasklet */
223 unsigned long last_tx_jiffies; /* Timestamp of last pkt sent */
224 atomic_t tx_cnt; /* Number of packets can send at a time */
225
226 struct sk_buff *resp_skb; /* Response from the chip */
227 /* Main task completion handler */
228 struct completion maintask_comp;
229 /* Opcode of last command sent to the chip */
230 u8 pre_op;
231 /* Handler used for wakeup when response packet is received */
232 struct completion *resp_comp;
233 struct fm_irq irq_info;
234 u8 curr_fmmode; /* Current FM chip mode (TX, RX, OFF) */
235 struct fm_rx rx; /* FM receiver info */
236 struct fmtx_data tx_data;
237
238 /* V4L2 ctrl framwork handler*/
239 struct v4l2_ctrl_handler ctrl_handler;
240
241 /* For core assisted locking */
242 struct mutex mutex;
243};
244#endif
diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c
new file mode 100644
index 000000000000..64454d39c0ca
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_common.c
@@ -0,0 +1,1677 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 *
4 * This sub-module of FM driver is common for FM RX and TX
5 * functionality. This module is responsible for:
6 * 1) Forming group of Channel-8 commands to perform particular
7 * functionality (eg., frequency set require more than
8 * one Channel-8 command to be sent to the chip).
9 * 2) Sending each Channel-8 command to the chip and reading
10 * response back over Shared Transport.
11 * 3) Managing TX and RX Queues and Tasklets.
12 * 4) Handling FM Interrupt packet and taking appropriate action.
13 * 5) Loading FM firmware to the chip (common, FM TX, and FM RX
14 * firmware files based on mode selection)
15 *
16 * Copyright (C) 2011 Texas Instruments
17 * Author: Raja Mani <raja_mani@ti.com>
18 * Author: Manjunatha Halli <manjunatha_halli@ti.com>
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License version 2 as
22 * published by the Free Software Foundation.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 *
33 */
34
35#include <linux/module.h>
36#include <linux/firmware.h>
37#include <linux/delay.h>
38#include "fmdrv.h"
39#include "fmdrv_v4l2.h"
40#include "fmdrv_common.h"
41#include <linux/ti_wilink_st.h>
42#include "fmdrv_rx.h"
43#include "fmdrv_tx.h"
44
45/* Region info */
46static struct region_info region_configs[] = {
47 /* Europe/US */
48 {
49 .chanl_space = FM_CHANNEL_SPACING_200KHZ * FM_FREQ_MUL,
50 .bot_freq = 87500, /* 87.5 MHz */
51 .top_freq = 108000, /* 108 MHz */
52 .fm_band = 0,
53 },
54 /* Japan */
55 {
56 .chanl_space = FM_CHANNEL_SPACING_200KHZ * FM_FREQ_MUL,
57 .bot_freq = 76000, /* 76 MHz */
58 .top_freq = 90000, /* 90 MHz */
59 .fm_band = 1,
60 },
61};
62
63/* Band selection */
64static u8 default_radio_region; /* Europe/US */
65module_param(default_radio_region, byte, 0);
66MODULE_PARM_DESC(default_radio_region, "Region: 0=Europe/US, 1=Japan");
67
68/* RDS buffer blocks */
69static u32 default_rds_buf = 300;
70module_param(default_rds_buf, uint, 0444);
71MODULE_PARM_DESC(rds_buf, "RDS buffer entries");
72
73/* Radio Nr */
74static u32 radio_nr = -1;
75module_param(radio_nr, int, 0444);
76MODULE_PARM_DESC(radio_nr, "Radio Nr");
77
78/* FM irq handlers forward declaration */
79static void fm_irq_send_flag_getcmd(struct fmdev *);
80static void fm_irq_handle_flag_getcmd_resp(struct fmdev *);
81static void fm_irq_handle_hw_malfunction(struct fmdev *);
82static void fm_irq_handle_rds_start(struct fmdev *);
83static void fm_irq_send_rdsdata_getcmd(struct fmdev *);
84static void fm_irq_handle_rdsdata_getcmd_resp(struct fmdev *);
85static void fm_irq_handle_rds_finish(struct fmdev *);
86static void fm_irq_handle_tune_op_ended(struct fmdev *);
87static void fm_irq_handle_power_enb(struct fmdev *);
88static void fm_irq_handle_low_rssi_start(struct fmdev *);
89static void fm_irq_afjump_set_pi(struct fmdev *);
90static void fm_irq_handle_set_pi_resp(struct fmdev *);
91static void fm_irq_afjump_set_pimask(struct fmdev *);
92static void fm_irq_handle_set_pimask_resp(struct fmdev *);
93static void fm_irq_afjump_setfreq(struct fmdev *);
94static void fm_irq_handle_setfreq_resp(struct fmdev *);
95static void fm_irq_afjump_enableint(struct fmdev *);
96static void fm_irq_afjump_enableint_resp(struct fmdev *);
97static void fm_irq_start_afjump(struct fmdev *);
98static void fm_irq_handle_start_afjump_resp(struct fmdev *);
99static void fm_irq_afjump_rd_freq(struct fmdev *);
100static void fm_irq_afjump_rd_freq_resp(struct fmdev *);
101static void fm_irq_handle_low_rssi_finish(struct fmdev *);
102static void fm_irq_send_intmsk_cmd(struct fmdev *);
103static void fm_irq_handle_intmsk_cmd_resp(struct fmdev *);
104
105/*
106 * When FM common module receives interrupt packet, following handlers
107 * will be executed one after another to service the interrupt(s)
108 */
109enum fmc_irq_handler_index {
110 FM_SEND_FLAG_GETCMD_IDX,
111 FM_HANDLE_FLAG_GETCMD_RESP_IDX,
112
113 /* HW malfunction irq handler */
114 FM_HW_MAL_FUNC_IDX,
115
116 /* RDS threshold reached irq handler */
117 FM_RDS_START_IDX,
118 FM_RDS_SEND_RDS_GETCMD_IDX,
119 FM_RDS_HANDLE_RDS_GETCMD_RESP_IDX,
120 FM_RDS_FINISH_IDX,
121
122 /* Tune operation ended irq handler */
123 FM_HW_TUNE_OP_ENDED_IDX,
124
125 /* TX power enable irq handler */
126 FM_HW_POWER_ENB_IDX,
127
128 /* Low RSSI irq handler */
129 FM_LOW_RSSI_START_IDX,
130 FM_AF_JUMP_SETPI_IDX,
131 FM_AF_JUMP_HANDLE_SETPI_RESP_IDX,
132 FM_AF_JUMP_SETPI_MASK_IDX,
133 FM_AF_JUMP_HANDLE_SETPI_MASK_RESP_IDX,
134 FM_AF_JUMP_SET_AF_FREQ_IDX,
135 FM_AF_JUMP_HANDLE_SET_AFFREQ_RESP_IDX,
136 FM_AF_JUMP_ENABLE_INT_IDX,
137 FM_AF_JUMP_ENABLE_INT_RESP_IDX,
138 FM_AF_JUMP_START_AFJUMP_IDX,
139 FM_AF_JUMP_HANDLE_START_AFJUMP_RESP_IDX,
140 FM_AF_JUMP_RD_FREQ_IDX,
141 FM_AF_JUMP_RD_FREQ_RESP_IDX,
142 FM_LOW_RSSI_FINISH_IDX,
143
144 /* Interrupt process post action */
145 FM_SEND_INTMSK_CMD_IDX,
146 FM_HANDLE_INTMSK_CMD_RESP_IDX,
147};
148
149/* FM interrupt handler table */
150static int_handler_prototype int_handler_table[] = {
151 fm_irq_send_flag_getcmd,
152 fm_irq_handle_flag_getcmd_resp,
153 fm_irq_handle_hw_malfunction,
154 fm_irq_handle_rds_start, /* RDS threshold reached irq handler */
155 fm_irq_send_rdsdata_getcmd,
156 fm_irq_handle_rdsdata_getcmd_resp,
157 fm_irq_handle_rds_finish,
158 fm_irq_handle_tune_op_ended,
159 fm_irq_handle_power_enb, /* TX power enable irq handler */
160 fm_irq_handle_low_rssi_start,
161 fm_irq_afjump_set_pi,
162 fm_irq_handle_set_pi_resp,
163 fm_irq_afjump_set_pimask,
164 fm_irq_handle_set_pimask_resp,
165 fm_irq_afjump_setfreq,
166 fm_irq_handle_setfreq_resp,
167 fm_irq_afjump_enableint,
168 fm_irq_afjump_enableint_resp,
169 fm_irq_start_afjump,
170 fm_irq_handle_start_afjump_resp,
171 fm_irq_afjump_rd_freq,
172 fm_irq_afjump_rd_freq_resp,
173 fm_irq_handle_low_rssi_finish,
174 fm_irq_send_intmsk_cmd, /* Interrupt process post action */
175 fm_irq_handle_intmsk_cmd_resp
176};
177
178long (*g_st_write) (struct sk_buff *skb);
179static struct completion wait_for_fmdrv_reg_comp;
180
181static inline void fm_irq_call(struct fmdev *fmdev)
182{
183 fmdev->irq_info.handlers[fmdev->irq_info.stage](fmdev);
184}
185
186/* Continue next function in interrupt handler table */
187static inline void fm_irq_call_stage(struct fmdev *fmdev, u8 stage)
188{
189 fmdev->irq_info.stage = stage;
190 fm_irq_call(fmdev);
191}
192
193static inline void fm_irq_timeout_stage(struct fmdev *fmdev, u8 stage)
194{
195 fmdev->irq_info.stage = stage;
196 mod_timer(&fmdev->irq_info.timer, jiffies + FM_DRV_TX_TIMEOUT);
197}
198
199#ifdef FM_DUMP_TXRX_PKT
200 /* To dump outgoing FM Channel-8 packets */
201inline void dump_tx_skb_data(struct sk_buff *skb)
202{
203 int len, len_org;
204 u8 index;
205 struct fm_cmd_msg_hdr *cmd_hdr;
206
207 cmd_hdr = (struct fm_cmd_msg_hdr *)skb->data;
208 printk(KERN_INFO "<<%shdr:%02x len:%02x opcode:%02x type:%s dlen:%02x",
209 fm_cb(skb)->completion ? " " : "*", cmd_hdr->hdr,
210 cmd_hdr->len, cmd_hdr->op,
211 cmd_hdr->rd_wr ? "RD" : "WR", cmd_hdr->dlen);
212
213 len_org = skb->len - FM_CMD_MSG_HDR_SIZE;
214 if (len_org > 0) {
215 printk("\n data(%d): ", cmd_hdr->dlen);
216 len = min(len_org, 14);
217 for (index = 0; index < len; index++)
218 printk("%x ",
219 skb->data[FM_CMD_MSG_HDR_SIZE + index]);
220 printk("%s", (len_org > 14) ? ".." : "");
221 }
222 printk("\n");
223}
224
225 /* To dump incoming FM Channel-8 packets */
226inline void dump_rx_skb_data(struct sk_buff *skb)
227{
228 int len, len_org;
229 u8 index;
230 struct fm_event_msg_hdr *evt_hdr;
231
232 evt_hdr = (struct fm_event_msg_hdr *)skb->data;
233 printk(KERN_INFO ">> hdr:%02x len:%02x sts:%02x numhci:%02x "
234 "opcode:%02x type:%s dlen:%02x", evt_hdr->hdr, evt_hdr->len,
235 evt_hdr->status, evt_hdr->num_fm_hci_cmds, evt_hdr->op,
236 (evt_hdr->rd_wr) ? "RD" : "WR", evt_hdr->dlen);
237
238 len_org = skb->len - FM_EVT_MSG_HDR_SIZE;
239 if (len_org > 0) {
240 printk("\n data(%d): ", evt_hdr->dlen);
241 len = min(len_org, 14);
242 for (index = 0; index < len; index++)
243 printk("%x ",
244 skb->data[FM_EVT_MSG_HDR_SIZE + index]);
245 printk("%s", (len_org > 14) ? ".." : "");
246 }
247 printk("\n");
248}
249#endif
250
251void fmc_update_region_info(struct fmdev *fmdev, u8 region_to_set)
252{
253 fmdev->rx.region = region_configs[region_to_set];
254}
255
256/*
257 * FM common sub-module will schedule this tasklet whenever it receives
258 * FM packet from ST driver.
259 */
260static void recv_tasklet(unsigned long arg)
261{
262 struct fmdev *fmdev;
263 struct fm_irq *irq_info;
264 struct fm_event_msg_hdr *evt_hdr;
265 struct sk_buff *skb;
266 u8 num_fm_hci_cmds;
267 unsigned long flags;
268
269 fmdev = (struct fmdev *)arg;
270 irq_info = &fmdev->irq_info;
271 /* Process all packets in the RX queue */
272 while ((skb = skb_dequeue(&fmdev->rx_q))) {
273 if (skb->len < sizeof(struct fm_event_msg_hdr)) {
274 fmerr("skb(%p) has only %d bytes, "
275 "at least need %zu bytes to decode\n", skb,
276 skb->len, sizeof(struct fm_event_msg_hdr));
277 kfree_skb(skb);
278 continue;
279 }
280
281 evt_hdr = (void *)skb->data;
282 num_fm_hci_cmds = evt_hdr->num_fm_hci_cmds;
283
284 /* FM interrupt packet? */
285 if (evt_hdr->op == FM_INTERRUPT) {
286 /* FM interrupt handler started already? */
287 if (!test_bit(FM_INTTASK_RUNNING, &fmdev->flag)) {
288 set_bit(FM_INTTASK_RUNNING, &fmdev->flag);
289 if (irq_info->stage != 0) {
290 fmerr("Inval stage resetting to zero\n");
291 irq_info->stage = 0;
292 }
293
294 /*
295 * Execute first function in interrupt handler
296 * table.
297 */
298 irq_info->handlers[irq_info->stage](fmdev);
299 } else {
300 set_bit(FM_INTTASK_SCHEDULE_PENDING, &fmdev->flag);
301 }
302 kfree_skb(skb);
303 }
304 /* Anyone waiting for this with completion handler? */
305 else if (evt_hdr->op == fmdev->pre_op && fmdev->resp_comp != NULL) {
306
307 spin_lock_irqsave(&fmdev->resp_skb_lock, flags);
308 fmdev->resp_skb = skb;
309 spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags);
310 complete(fmdev->resp_comp);
311
312 fmdev->resp_comp = NULL;
313 atomic_set(&fmdev->tx_cnt, 1);
314 }
315 /* Is this for interrupt handler? */
316 else if (evt_hdr->op == fmdev->pre_op && fmdev->resp_comp == NULL) {
317 if (fmdev->resp_skb != NULL)
318 fmerr("Response SKB ptr not NULL\n");
319
320 spin_lock_irqsave(&fmdev->resp_skb_lock, flags);
321 fmdev->resp_skb = skb;
322 spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags);
323
324 /* Execute interrupt handler where state index points */
325 irq_info->handlers[irq_info->stage](fmdev);
326
327 kfree_skb(skb);
328 atomic_set(&fmdev->tx_cnt, 1);
329 } else {
330 fmerr("Nobody claimed SKB(%p),purging\n", skb);
331 }
332
333 /*
334 * Check flow control field. If Num_FM_HCI_Commands field is
335 * not zero, schedule FM TX tasklet.
336 */
337 if (num_fm_hci_cmds && atomic_read(&fmdev->tx_cnt))
338 if (!skb_queue_empty(&fmdev->tx_q))
339 tasklet_schedule(&fmdev->tx_task);
340 }
341}
342
343/* FM send tasklet: is scheduled when FM packet has to be sent to chip */
344static void send_tasklet(unsigned long arg)
345{
346 struct fmdev *fmdev;
347 struct sk_buff *skb;
348 int len;
349
350 fmdev = (struct fmdev *)arg;
351
352 if (!atomic_read(&fmdev->tx_cnt))
353 return;
354
355 /* Check, is there any timeout happenned to last transmitted packet */
356 if ((jiffies - fmdev->last_tx_jiffies) > FM_DRV_TX_TIMEOUT) {
357 fmerr("TX timeout occurred\n");
358 atomic_set(&fmdev->tx_cnt, 1);
359 }
360
361 /* Send queued FM TX packets */
362 skb = skb_dequeue(&fmdev->tx_q);
363 if (!skb)
364 return;
365
366 atomic_dec(&fmdev->tx_cnt);
367 fmdev->pre_op = fm_cb(skb)->fm_op;
368
369 if (fmdev->resp_comp != NULL)
370 fmerr("Response completion handler is not NULL\n");
371
372 fmdev->resp_comp = fm_cb(skb)->completion;
373
374 /* Write FM packet to ST driver */
375 len = g_st_write(skb);
376 if (len < 0) {
377 kfree_skb(skb);
378 fmdev->resp_comp = NULL;
379 fmerr("TX tasklet failed to send skb(%p)\n", skb);
380 atomic_set(&fmdev->tx_cnt, 1);
381 } else {
382 fmdev->last_tx_jiffies = jiffies;
383 }
384}
385
386/*
387 * Queues FM Channel-8 packet to FM TX queue and schedules FM TX tasklet for
388 * transmission
389 */
390static u32 fm_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload,
391 int payload_len, struct completion *wait_completion)
392{
393 struct sk_buff *skb;
394 struct fm_cmd_msg_hdr *hdr;
395 int size;
396
397 if (fm_op >= FM_INTERRUPT) {
398 fmerr("Invalid fm opcode - %d\n", fm_op);
399 return -EINVAL;
400 }
401 if (test_bit(FM_FW_DW_INPROGRESS, &fmdev->flag) && payload == NULL) {
402 fmerr("Payload data is NULL during fw download\n");
403 return -EINVAL;
404 }
405 if (!test_bit(FM_FW_DW_INPROGRESS, &fmdev->flag))
406 size =
407 FM_CMD_MSG_HDR_SIZE + ((payload == NULL) ? 0 : payload_len);
408 else
409 size = payload_len;
410
411 skb = alloc_skb(size, GFP_ATOMIC);
412 if (!skb) {
413 fmerr("No memory to create new SKB\n");
414 return -ENOMEM;
415 }
416 /*
417 * Don't fill FM header info for the commands which come from
418 * FM firmware file.
419 */
420 if (!test_bit(FM_FW_DW_INPROGRESS, &fmdev->flag) ||
421 test_bit(FM_INTTASK_RUNNING, &fmdev->flag)) {
422 /* Fill command header info */
423 hdr = (struct fm_cmd_msg_hdr *)skb_put(skb, FM_CMD_MSG_HDR_SIZE);
424 hdr->hdr = FM_PKT_LOGICAL_CHAN_NUMBER; /* 0x08 */
425
426 /* 3 (fm_opcode,rd_wr,dlen) + payload len) */
427 hdr->len = ((payload == NULL) ? 0 : payload_len) + 3;
428
429 /* FM opcode */
430 hdr->op = fm_op;
431
432 /* read/write type */
433 hdr->rd_wr = type;
434 hdr->dlen = payload_len;
435 fm_cb(skb)->fm_op = fm_op;
436
437 /*
438 * If firmware download has finished and the command is
439 * not a read command then payload is != NULL - a write
440 * command with u16 payload - convert to be16
441 */
442 if (payload != NULL)
443 *(u16 *)payload = cpu_to_be16(*(u16 *)payload);
444
445 } else if (payload != NULL) {
446 fm_cb(skb)->fm_op = *((u8 *)payload + 2);
447 }
448 if (payload != NULL)
449 memcpy(skb_put(skb, payload_len), payload, payload_len);
450
451 fm_cb(skb)->completion = wait_completion;
452 skb_queue_tail(&fmdev->tx_q, skb);
453 tasklet_schedule(&fmdev->tx_task);
454
455 return 0;
456}
457
458/* Sends FM Channel-8 command to the chip and waits for the response */
459u32 fmc_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload,
460 unsigned int payload_len, void *response, int *response_len)
461{
462 struct sk_buff *skb;
463 struct fm_event_msg_hdr *evt_hdr;
464 unsigned long flags;
465 u32 ret;
466
467 init_completion(&fmdev->maintask_comp);
468 ret = fm_send_cmd(fmdev, fm_op, type, payload, payload_len,
469 &fmdev->maintask_comp);
470 if (ret)
471 return ret;
472
473 ret = wait_for_completion_timeout(&fmdev->maintask_comp, FM_DRV_TX_TIMEOUT);
474 if (!ret) {
475 fmerr("Timeout(%d sec),didn't get reg"
476 "completion signal from RX tasklet\n",
477 jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000);
478 return -ETIMEDOUT;
479 }
480 if (!fmdev->resp_skb) {
481 fmerr("Reponse SKB is missing\n");
482 return -EFAULT;
483 }
484 spin_lock_irqsave(&fmdev->resp_skb_lock, flags);
485 skb = fmdev->resp_skb;
486 fmdev->resp_skb = NULL;
487 spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags);
488
489 evt_hdr = (void *)skb->data;
490 if (evt_hdr->status != 0) {
491 fmerr("Received event pkt status(%d) is not zero\n",
492 evt_hdr->status);
493 kfree_skb(skb);
494 return -EIO;
495 }
496 /* Send response data to caller */
497 if (response != NULL && response_len != NULL && evt_hdr->dlen) {
498 /* Skip header info and copy only response data */
499 skb_pull(skb, sizeof(struct fm_event_msg_hdr));
500 memcpy(response, skb->data, evt_hdr->dlen);
501 *response_len = evt_hdr->dlen;
502 } else if (response_len != NULL && evt_hdr->dlen == 0) {
503 *response_len = 0;
504 }
505 kfree_skb(skb);
506
507 return 0;
508}
509
510/* --- Helper functions used in FM interrupt handlers ---*/
511static inline u32 check_cmdresp_status(struct fmdev *fmdev,
512 struct sk_buff **skb)
513{
514 struct fm_event_msg_hdr *fm_evt_hdr;
515 unsigned long flags;
516
517 del_timer(&fmdev->irq_info.timer);
518
519 spin_lock_irqsave(&fmdev->resp_skb_lock, flags);
520 *skb = fmdev->resp_skb;
521 fmdev->resp_skb = NULL;
522 spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags);
523
524 fm_evt_hdr = (void *)(*skb)->data;
525 if (fm_evt_hdr->status != 0) {
526 fmerr("irq: opcode %x response status is not zero "
527 "Initiating irq recovery process\n",
528 fm_evt_hdr->op);
529
530 mod_timer(&fmdev->irq_info.timer, jiffies + FM_DRV_TX_TIMEOUT);
531 return -1;
532 }
533
534 return 0;
535}
536
537static inline void fm_irq_common_cmd_resp_helper(struct fmdev *fmdev, u8 stage)
538{
539 struct sk_buff *skb;
540
541 if (!check_cmdresp_status(fmdev, &skb))
542 fm_irq_call_stage(fmdev, stage);
543}
544
545/*
546 * Interrupt process timeout handler.
547 * One of the irq handler did not get proper response from the chip. So take
548 * recovery action here. FM interrupts are disabled in the beginning of
549 * interrupt process. Therefore reset stage index to re-enable default
550 * interrupts. So that next interrupt will be processed as usual.
551 */
552static void int_timeout_handler(unsigned long data)
553{
554 struct fmdev *fmdev;
555 struct fm_irq *fmirq;
556
557 fmdbg("irq: timeout,trying to re-enable fm interrupts\n");
558 fmdev = (struct fmdev *)data;
559 fmirq = &fmdev->irq_info;
560 fmirq->retry++;
561
562 if (fmirq->retry > FM_IRQ_TIMEOUT_RETRY_MAX) {
563 /* Stop recovery action (interrupt reenable process) and
564 * reset stage index & retry count values */
565 fmirq->stage = 0;
566 fmirq->retry = 0;
567 fmerr("Recovery action failed during"
568 "irq processing, max retry reached\n");
569 return;
570 }
571 fm_irq_call_stage(fmdev, FM_SEND_INTMSK_CMD_IDX);
572}
573
574/* --------- FM interrupt handlers ------------*/
575static void fm_irq_send_flag_getcmd(struct fmdev *fmdev)
576{
577 u16 flag;
578
579 /* Send FLAG_GET command , to know the source of interrupt */
580 if (!fm_send_cmd(fmdev, FLAG_GET, REG_RD, NULL, sizeof(flag), NULL))
581 fm_irq_timeout_stage(fmdev, FM_HANDLE_FLAG_GETCMD_RESP_IDX);
582}
583
584static void fm_irq_handle_flag_getcmd_resp(struct fmdev *fmdev)
585{
586 struct sk_buff *skb;
587 struct fm_event_msg_hdr *fm_evt_hdr;
588
589 if (check_cmdresp_status(fmdev, &skb))
590 return;
591
592 fm_evt_hdr = (void *)skb->data;
593
594 /* Skip header info and copy only response data */
595 skb_pull(skb, sizeof(struct fm_event_msg_hdr));
596 memcpy(&fmdev->irq_info.flag, skb->data, fm_evt_hdr->dlen);
597
598 fmdev->irq_info.flag = be16_to_cpu(fmdev->irq_info.flag);
599 fmdbg("irq: flag register(0x%x)\n", fmdev->irq_info.flag);
600
601 /* Continue next function in interrupt handler table */
602 fm_irq_call_stage(fmdev, FM_HW_MAL_FUNC_IDX);
603}
604
605static void fm_irq_handle_hw_malfunction(struct fmdev *fmdev)
606{
607 if (fmdev->irq_info.flag & FM_MAL_EVENT & fmdev->irq_info.mask)
608 fmerr("irq: HW MAL int received - do nothing\n");
609
610 /* Continue next function in interrupt handler table */
611 fm_irq_call_stage(fmdev, FM_RDS_START_IDX);
612}
613
614static void fm_irq_handle_rds_start(struct fmdev *fmdev)
615{
616 if (fmdev->irq_info.flag & FM_RDS_EVENT & fmdev->irq_info.mask) {
617 fmdbg("irq: rds threshold reached\n");
618 fmdev->irq_info.stage = FM_RDS_SEND_RDS_GETCMD_IDX;
619 } else {
620 /* Continue next function in interrupt handler table */
621 fmdev->irq_info.stage = FM_HW_TUNE_OP_ENDED_IDX;
622 }
623
624 fm_irq_call(fmdev);
625}
626
627static void fm_irq_send_rdsdata_getcmd(struct fmdev *fmdev)
628{
629 /* Send the command to read RDS data from the chip */
630 if (!fm_send_cmd(fmdev, RDS_DATA_GET, REG_RD, NULL,
631 (FM_RX_RDS_FIFO_THRESHOLD * 3), NULL))
632 fm_irq_timeout_stage(fmdev, FM_RDS_HANDLE_RDS_GETCMD_RESP_IDX);
633}
634
635/* Keeps track of current RX channel AF (Alternate Frequency) */
636static void fm_rx_update_af_cache(struct fmdev *fmdev, u8 af)
637{
638 struct tuned_station_info *stat_info = &fmdev->rx.stat_info;
639 u8 reg_idx = fmdev->rx.region.fm_band;
640 u8 index;
641 u32 freq;
642
643 /* First AF indicates the number of AF follows. Reset the list */
644 if ((af >= FM_RDS_1_AF_FOLLOWS) && (af <= FM_RDS_25_AF_FOLLOWS)) {
645 fmdev->rx.stat_info.af_list_max = (af - FM_RDS_1_AF_FOLLOWS + 1);
646 fmdev->rx.stat_info.afcache_size = 0;
647 fmdbg("No of expected AF : %d\n", fmdev->rx.stat_info.af_list_max);
648 return;
649 }
650
651 if (af < FM_RDS_MIN_AF)
652 return;
653 if (reg_idx == FM_BAND_EUROPE_US && af > FM_RDS_MAX_AF)
654 return;
655 if (reg_idx == FM_BAND_JAPAN && af > FM_RDS_MAX_AF_JAPAN)
656 return;
657
658 freq = fmdev->rx.region.bot_freq + (af * 100);
659 if (freq == fmdev->rx.freq) {
660 fmdbg("Current freq(%d) is matching with received AF(%d)\n",
661 fmdev->rx.freq, freq);
662 return;
663 }
664 /* Do check in AF cache */
665 for (index = 0; index < stat_info->afcache_size; index++) {
666 if (stat_info->af_cache[index] == freq)
667 break;
668 }
669 /* Reached the limit of the list - ignore the next AF */
670 if (index == stat_info->af_list_max) {
671 fmdbg("AF cache is full\n");
672 return;
673 }
674 /*
675 * If we reached the end of the list then this AF is not
676 * in the list - add it.
677 */
678 if (index == stat_info->afcache_size) {
679 fmdbg("Storing AF %d to cache index %d\n", freq, index);
680 stat_info->af_cache[index] = freq;
681 stat_info->afcache_size++;
682 }
683}
684
685/*
686 * Converts RDS buffer data from big endian format
687 * to little endian format.
688 */
689static void fm_rdsparse_swapbytes(struct fmdev *fmdev,
690 struct fm_rdsdata_format *rds_format)
691{
692 u8 byte1;
693 u8 index = 0;
694 u8 *rds_buff;
695
696 /*
697 * Since in Orca the 2 RDS Data bytes are in little endian and
698 * in Dolphin they are in big endian, the parsing of the RDS data
699 * is chip dependent
700 */
701 if (fmdev->asci_id != 0x6350) {
702 rds_buff = &rds_format->data.groupdatabuff.buff[0];
703 while (index + 1 < FM_RX_RDS_INFO_FIELD_MAX) {
704 byte1 = rds_buff[index];
705 rds_buff[index] = rds_buff[index + 1];
706 rds_buff[index + 1] = byte1;
707 index += 2;
708 }
709 }
710}
711
712static void fm_irq_handle_rdsdata_getcmd_resp(struct fmdev *fmdev)
713{
714 struct sk_buff *skb;
715 struct fm_rdsdata_format rds_fmt;
716 struct fm_rds *rds = &fmdev->rx.rds;
717 unsigned long group_idx, flags;
718 u8 *rds_data, meta_data, tmpbuf[3];
719 u8 type, blk_idx;
720 u16 cur_picode;
721 u32 rds_len;
722
723 if (check_cmdresp_status(fmdev, &skb))
724 return;
725
726 /* Skip header info */
727 skb_pull(skb, sizeof(struct fm_event_msg_hdr));
728 rds_data = skb->data;
729 rds_len = skb->len;
730
731 /* Parse the RDS data */
732 while (rds_len >= FM_RDS_BLK_SIZE) {
733 meta_data = rds_data[2];
734 /* Get the type: 0=A, 1=B, 2=C, 3=C', 4=D, 5=E */
735 type = (meta_data & 0x07);
736
737 /* Transform the blk type into index sequence (0, 1, 2, 3, 4) */
738 blk_idx = (type <= FM_RDS_BLOCK_C ? type : (type - 1));
739 fmdbg("Block index:%d(%s)\n", blk_idx,
740 (meta_data & FM_RDS_STATUS_ERR_MASK) ? "Bad" : "Ok");
741
742 if ((meta_data & FM_RDS_STATUS_ERR_MASK) != 0)
743 break;
744
745 if (blk_idx < FM_RDS_BLK_IDX_A || blk_idx > FM_RDS_BLK_IDX_D) {
746 fmdbg("Block sequence mismatch\n");
747 rds->last_blk_idx = -1;
748 break;
749 }
750
751 /* Skip checkword (control) byte and copy only data byte */
752 memcpy(&rds_fmt.data.groupdatabuff.
753 buff[blk_idx * (FM_RDS_BLK_SIZE - 1)],
754 rds_data, (FM_RDS_BLK_SIZE - 1));
755
756 rds->last_blk_idx = blk_idx;
757
758 /* If completed a whole group then handle it */
759 if (blk_idx == FM_RDS_BLK_IDX_D) {
760 fmdbg("Good block received\n");
761 fm_rdsparse_swapbytes(fmdev, &rds_fmt);
762
763 /*
764 * Extract PI code and store in local cache.
765 * We need this during AF switch processing.
766 */
767 cur_picode = be16_to_cpu(rds_fmt.data.groupgeneral.pidata);
768 if (fmdev->rx.stat_info.picode != cur_picode)
769 fmdev->rx.stat_info.picode = cur_picode;
770
771 fmdbg("picode:%d\n", cur_picode);
772
773 group_idx = (rds_fmt.data.groupgeneral.blk_b[0] >> 3);
774 fmdbg("(fmdrv):Group:%ld%s\n", group_idx/2,
775 (group_idx % 2) ? "B" : "A");
776
777 group_idx = 1 << (rds_fmt.data.groupgeneral.blk_b[0] >> 3);
778 if (group_idx == FM_RDS_GROUP_TYPE_MASK_0A) {
779 fm_rx_update_af_cache(fmdev, rds_fmt.data.group0A.af[0]);
780 fm_rx_update_af_cache(fmdev, rds_fmt.data.group0A.af[1]);
781 }
782 }
783 rds_len -= FM_RDS_BLK_SIZE;
784 rds_data += FM_RDS_BLK_SIZE;
785 }
786
787 /* Copy raw rds data to internal rds buffer */
788 rds_data = skb->data;
789 rds_len = skb->len;
790
791 spin_lock_irqsave(&fmdev->rds_buff_lock, flags);
792 while (rds_len > 0) {
793 /*
794 * Fill RDS buffer as per V4L2 specification.
795 * Store control byte
796 */
797 type = (rds_data[2] & 0x07);
798 blk_idx = (type <= FM_RDS_BLOCK_C ? type : (type - 1));
799 tmpbuf[2] = blk_idx; /* Offset name */
800 tmpbuf[2] |= blk_idx << 3; /* Received offset */
801
802 /* Store data byte */
803 tmpbuf[0] = rds_data[0];
804 tmpbuf[1] = rds_data[1];
805
806 memcpy(&rds->buff[rds->wr_idx], &tmpbuf, FM_RDS_BLK_SIZE);
807 rds->wr_idx = (rds->wr_idx + FM_RDS_BLK_SIZE) % rds->buf_size;
808
809 /* Check for overflow & start over */
810 if (rds->wr_idx == rds->rd_idx) {
811 fmdbg("RDS buffer overflow\n");
812 rds->wr_idx = 0;
813 rds->rd_idx = 0;
814 break;
815 }
816 rds_len -= FM_RDS_BLK_SIZE;
817 rds_data += FM_RDS_BLK_SIZE;
818 }
819 spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags);
820
821 /* Wakeup read queue */
822 if (rds->wr_idx != rds->rd_idx)
823 wake_up_interruptible(&rds->read_queue);
824
825 fm_irq_call_stage(fmdev, FM_RDS_FINISH_IDX);
826}
827
828static void fm_irq_handle_rds_finish(struct fmdev *fmdev)
829{
830 fm_irq_call_stage(fmdev, FM_HW_TUNE_OP_ENDED_IDX);
831}
832
833static void fm_irq_handle_tune_op_ended(struct fmdev *fmdev)
834{
835 if (fmdev->irq_info.flag & (FM_FR_EVENT | FM_BL_EVENT) & fmdev->
836 irq_info.mask) {
837 fmdbg("irq: tune ended/bandlimit reached\n");
838 if (test_and_clear_bit(FM_AF_SWITCH_INPROGRESS, &fmdev->flag)) {
839 fmdev->irq_info.stage = FM_AF_JUMP_RD_FREQ_IDX;
840 } else {
841 complete(&fmdev->maintask_comp);
842 fmdev->irq_info.stage = FM_HW_POWER_ENB_IDX;
843 }
844 } else
845 fmdev->irq_info.stage = FM_HW_POWER_ENB_IDX;
846
847 fm_irq_call(fmdev);
848}
849
850static void fm_irq_handle_power_enb(struct fmdev *fmdev)
851{
852 if (fmdev->irq_info.flag & FM_POW_ENB_EVENT) {
853 fmdbg("irq: Power Enabled/Disabled\n");
854 complete(&fmdev->maintask_comp);
855 }
856
857 fm_irq_call_stage(fmdev, FM_LOW_RSSI_START_IDX);
858}
859
860static void fm_irq_handle_low_rssi_start(struct fmdev *fmdev)
861{
862 if ((fmdev->rx.af_mode == FM_RX_RDS_AF_SWITCH_MODE_ON) &&
863 (fmdev->irq_info.flag & FM_LEV_EVENT & fmdev->irq_info.mask) &&
864 (fmdev->rx.freq != FM_UNDEFINED_FREQ) &&
865 (fmdev->rx.stat_info.afcache_size != 0)) {
866 fmdbg("irq: rssi level has fallen below threshold level\n");
867
868 /* Disable further low RSSI interrupts */
869 fmdev->irq_info.mask &= ~FM_LEV_EVENT;
870
871 fmdev->rx.afjump_idx = 0;
872 fmdev->rx.freq_before_jump = fmdev->rx.freq;
873 fmdev->irq_info.stage = FM_AF_JUMP_SETPI_IDX;
874 } else {
875 /* Continue next function in interrupt handler table */
876 fmdev->irq_info.stage = FM_SEND_INTMSK_CMD_IDX;
877 }
878
879 fm_irq_call(fmdev);
880}
881
882static void fm_irq_afjump_set_pi(struct fmdev *fmdev)
883{
884 u16 payload;
885
886 /* Set PI code - must be updated if the AF list is not empty */
887 payload = fmdev->rx.stat_info.picode;
888 if (!fm_send_cmd(fmdev, RDS_PI_SET, REG_WR, &payload, sizeof(payload), NULL))
889 fm_irq_timeout_stage(fmdev, FM_AF_JUMP_HANDLE_SETPI_RESP_IDX);
890}
891
892static void fm_irq_handle_set_pi_resp(struct fmdev *fmdev)
893{
894 fm_irq_common_cmd_resp_helper(fmdev, FM_AF_JUMP_SETPI_MASK_IDX);
895}
896
897/*
898 * Set PI mask.
899 * 0xFFFF = Enable PI code matching
900 * 0x0000 = Disable PI code matching
901 */
902static void fm_irq_afjump_set_pimask(struct fmdev *fmdev)
903{
904 u16 payload;
905
906 payload = 0x0000;
907 if (!fm_send_cmd(fmdev, RDS_PI_MASK_SET, REG_WR, &payload, sizeof(payload), NULL))
908 fm_irq_timeout_stage(fmdev, FM_AF_JUMP_HANDLE_SETPI_MASK_RESP_IDX);
909}
910
911static void fm_irq_handle_set_pimask_resp(struct fmdev *fmdev)
912{
913 fm_irq_common_cmd_resp_helper(fmdev, FM_AF_JUMP_SET_AF_FREQ_IDX);
914}
915
916static void fm_irq_afjump_setfreq(struct fmdev *fmdev)
917{
918 u16 frq_index;
919 u16 payload;
920
921 fmdbg("Swtich to %d KHz\n", fmdev->rx.stat_info.af_cache[fmdev->rx.afjump_idx]);
922 frq_index = (fmdev->rx.stat_info.af_cache[fmdev->rx.afjump_idx] -
923 fmdev->rx.region.bot_freq) / FM_FREQ_MUL;
924
925 payload = frq_index;
926 if (!fm_send_cmd(fmdev, AF_FREQ_SET, REG_WR, &payload, sizeof(payload), NULL))
927 fm_irq_timeout_stage(fmdev, FM_AF_JUMP_HANDLE_SET_AFFREQ_RESP_IDX);
928}
929
930static void fm_irq_handle_setfreq_resp(struct fmdev *fmdev)
931{
932 fm_irq_common_cmd_resp_helper(fmdev, FM_AF_JUMP_ENABLE_INT_IDX);
933}
934
935static void fm_irq_afjump_enableint(struct fmdev *fmdev)
936{
937 u16 payload;
938
939 /* Enable FR (tuning operation ended) interrupt */
940 payload = FM_FR_EVENT;
941 if (!fm_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload, sizeof(payload), NULL))
942 fm_irq_timeout_stage(fmdev, FM_AF_JUMP_ENABLE_INT_RESP_IDX);
943}
944
945static void fm_irq_afjump_enableint_resp(struct fmdev *fmdev)
946{
947 fm_irq_common_cmd_resp_helper(fmdev, FM_AF_JUMP_START_AFJUMP_IDX);
948}
949
950static void fm_irq_start_afjump(struct fmdev *fmdev)
951{
952 u16 payload;
953
954 payload = FM_TUNER_AF_JUMP_MODE;
955 if (!fm_send_cmd(fmdev, TUNER_MODE_SET, REG_WR, &payload,
956 sizeof(payload), NULL))
957 fm_irq_timeout_stage(fmdev, FM_AF_JUMP_HANDLE_START_AFJUMP_RESP_IDX);
958}
959
960static void fm_irq_handle_start_afjump_resp(struct fmdev *fmdev)
961{
962 struct sk_buff *skb;
963
964 if (check_cmdresp_status(fmdev, &skb))
965 return;
966
967 fmdev->irq_info.stage = FM_SEND_FLAG_GETCMD_IDX;
968 set_bit(FM_AF_SWITCH_INPROGRESS, &fmdev->flag);
969 clear_bit(FM_INTTASK_RUNNING, &fmdev->flag);
970}
971
972static void fm_irq_afjump_rd_freq(struct fmdev *fmdev)
973{
974 u16 payload;
975
976 if (!fm_send_cmd(fmdev, FREQ_SET, REG_RD, NULL, sizeof(payload), NULL))
977 fm_irq_timeout_stage(fmdev, FM_AF_JUMP_RD_FREQ_RESP_IDX);
978}
979
980static void fm_irq_afjump_rd_freq_resp(struct fmdev *fmdev)
981{
982 struct sk_buff *skb;
983 u16 read_freq;
984 u32 curr_freq, jumped_freq;
985
986 if (check_cmdresp_status(fmdev, &skb))
987 return;
988
989 /* Skip header info and copy only response data */
990 skb_pull(skb, sizeof(struct fm_event_msg_hdr));
991 memcpy(&read_freq, skb->data, sizeof(read_freq));
992 read_freq = be16_to_cpu(read_freq);
993 curr_freq = fmdev->rx.region.bot_freq + ((u32)read_freq * FM_FREQ_MUL);
994
995 jumped_freq = fmdev->rx.stat_info.af_cache[fmdev->rx.afjump_idx];
996
997 /* If the frequency was changed the jump succeeded */
998 if ((curr_freq != fmdev->rx.freq_before_jump) && (curr_freq == jumped_freq)) {
999 fmdbg("Successfully switched to alternate freq %d\n", curr_freq);
1000 fmdev->rx.freq = curr_freq;
1001 fm_rx_reset_rds_cache(fmdev);
1002
1003 /* AF feature is on, enable low level RSSI interrupt */
1004 if (fmdev->rx.af_mode == FM_RX_RDS_AF_SWITCH_MODE_ON)
1005 fmdev->irq_info.mask |= FM_LEV_EVENT;
1006
1007 fmdev->irq_info.stage = FM_LOW_RSSI_FINISH_IDX;
1008 } else { /* jump to the next freq in the AF list */
1009 fmdev->rx.afjump_idx++;
1010
1011 /* If we reached the end of the list - stop searching */
1012 if (fmdev->rx.afjump_idx >= fmdev->rx.stat_info.afcache_size) {
1013 fmdbg("AF switch processing failed\n");
1014 fmdev->irq_info.stage = FM_LOW_RSSI_FINISH_IDX;
1015 } else { /* AF List is not over - try next one */
1016
1017 fmdbg("Trying next freq in AF cache\n");
1018 fmdev->irq_info.stage = FM_AF_JUMP_SETPI_IDX;
1019 }
1020 }
1021 fm_irq_call(fmdev);
1022}
1023
1024static void fm_irq_handle_low_rssi_finish(struct fmdev *fmdev)
1025{
1026 fm_irq_call_stage(fmdev, FM_SEND_INTMSK_CMD_IDX);
1027}
1028
1029static void fm_irq_send_intmsk_cmd(struct fmdev *fmdev)
1030{
1031 u16 payload;
1032
1033 /* Re-enable FM interrupts */
1034 payload = fmdev->irq_info.mask;
1035
1036 if (!fm_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
1037 sizeof(payload), NULL))
1038 fm_irq_timeout_stage(fmdev, FM_HANDLE_INTMSK_CMD_RESP_IDX);
1039}
1040
1041static void fm_irq_handle_intmsk_cmd_resp(struct fmdev *fmdev)
1042{
1043 struct sk_buff *skb;
1044
1045 if (check_cmdresp_status(fmdev, &skb))
1046 return;
1047 /*
1048 * This is last function in interrupt table to be executed.
1049 * So, reset stage index to 0.
1050 */
1051 fmdev->irq_info.stage = FM_SEND_FLAG_GETCMD_IDX;
1052
1053 /* Start processing any pending interrupt */
1054 if (test_and_clear_bit(FM_INTTASK_SCHEDULE_PENDING, &fmdev->flag))
1055 fmdev->irq_info.handlers[fmdev->irq_info.stage](fmdev);
1056 else
1057 clear_bit(FM_INTTASK_RUNNING, &fmdev->flag);
1058}
1059
1060/* Returns availability of RDS data in internel buffer */
1061u32 fmc_is_rds_data_available(struct fmdev *fmdev, struct file *file,
1062 struct poll_table_struct *pts)
1063{
1064 poll_wait(file, &fmdev->rx.rds.read_queue, pts);
1065 if (fmdev->rx.rds.rd_idx != fmdev->rx.rds.wr_idx)
1066 return 0;
1067
1068 return -EAGAIN;
1069}
1070
1071/* Copies RDS data from internal buffer to user buffer */
1072u32 fmc_transfer_rds_from_internal_buff(struct fmdev *fmdev, struct file *file,
1073 u8 __user *buf, size_t count)
1074{
1075 u32 block_count;
1076 unsigned long flags;
1077 int ret;
1078
1079 if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx) {
1080 if (file->f_flags & O_NONBLOCK)
1081 return -EWOULDBLOCK;
1082
1083 ret = wait_event_interruptible(fmdev->rx.rds.read_queue,
1084 (fmdev->rx.rds.wr_idx != fmdev->rx.rds.rd_idx));
1085 if (ret)
1086 return -EINTR;
1087 }
1088
1089 /* Calculate block count from byte count */
1090 count /= 3;
1091 block_count = 0;
1092 ret = 0;
1093
1094 spin_lock_irqsave(&fmdev->rds_buff_lock, flags);
1095
1096 while (block_count < count) {
1097 if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx)
1098 break;
1099
1100 if (copy_to_user(buf, &fmdev->rx.rds.buff[fmdev->rx.rds.rd_idx],
1101 FM_RDS_BLK_SIZE))
1102 break;
1103
1104 fmdev->rx.rds.rd_idx += FM_RDS_BLK_SIZE;
1105 if (fmdev->rx.rds.rd_idx >= fmdev->rx.rds.buf_size)
1106 fmdev->rx.rds.rd_idx = 0;
1107
1108 block_count++;
1109 buf += FM_RDS_BLK_SIZE;
1110 ret += FM_RDS_BLK_SIZE;
1111 }
1112 spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags);
1113 return ret;
1114}
1115
1116u32 fmc_set_freq(struct fmdev *fmdev, u32 freq_to_set)
1117{
1118 switch (fmdev->curr_fmmode) {
1119 case FM_MODE_RX:
1120 return fm_rx_set_freq(fmdev, freq_to_set);
1121
1122 case FM_MODE_TX:
1123 return fm_tx_set_freq(fmdev, freq_to_set);
1124
1125 default:
1126 return -EINVAL;
1127 }
1128}
1129
1130u32 fmc_get_freq(struct fmdev *fmdev, u32 *cur_tuned_frq)
1131{
1132 if (fmdev->rx.freq == FM_UNDEFINED_FREQ) {
1133 fmerr("RX frequency is not set\n");
1134 return -EPERM;
1135 }
1136 if (cur_tuned_frq == NULL) {
1137 fmerr("Invalid memory\n");
1138 return -ENOMEM;
1139 }
1140
1141 switch (fmdev->curr_fmmode) {
1142 case FM_MODE_RX:
1143 *cur_tuned_frq = fmdev->rx.freq;
1144 return 0;
1145
1146 case FM_MODE_TX:
1147 *cur_tuned_frq = 0; /* TODO : Change this later */
1148 return 0;
1149
1150 default:
1151 return -EINVAL;
1152 }
1153
1154}
1155
1156u32 fmc_set_region(struct fmdev *fmdev, u8 region_to_set)
1157{
1158 switch (fmdev->curr_fmmode) {
1159 case FM_MODE_RX:
1160 return fm_rx_set_region(fmdev, region_to_set);
1161
1162 case FM_MODE_TX:
1163 return fm_tx_set_region(fmdev, region_to_set);
1164
1165 default:
1166 return -EINVAL;
1167 }
1168}
1169
1170u32 fmc_set_mute_mode(struct fmdev *fmdev, u8 mute_mode_toset)
1171{
1172 switch (fmdev->curr_fmmode) {
1173 case FM_MODE_RX:
1174 return fm_rx_set_mute_mode(fmdev, mute_mode_toset);
1175
1176 case FM_MODE_TX:
1177 return fm_tx_set_mute_mode(fmdev, mute_mode_toset);
1178
1179 default:
1180 return -EINVAL;
1181 }
1182}
1183
1184u32 fmc_set_stereo_mono(struct fmdev *fmdev, u16 mode)
1185{
1186 switch (fmdev->curr_fmmode) {
1187 case FM_MODE_RX:
1188 return fm_rx_set_stereo_mono(fmdev, mode);
1189
1190 case FM_MODE_TX:
1191 return fm_tx_set_stereo_mono(fmdev, mode);
1192
1193 default:
1194 return -EINVAL;
1195 }
1196}
1197
1198u32 fmc_set_rds_mode(struct fmdev *fmdev, u8 rds_en_dis)
1199{
1200 switch (fmdev->curr_fmmode) {
1201 case FM_MODE_RX:
1202 return fm_rx_set_rds_mode(fmdev, rds_en_dis);
1203
1204 case FM_MODE_TX:
1205 return fm_tx_set_rds_mode(fmdev, rds_en_dis);
1206
1207 default:
1208 return -EINVAL;
1209 }
1210}
1211
1212/* Sends power off command to the chip */
1213static u32 fm_power_down(struct fmdev *fmdev)
1214{
1215 u16 payload;
1216 u32 ret;
1217
1218 if (!test_bit(FM_CORE_READY, &fmdev->flag)) {
1219 fmerr("FM core is not ready\n");
1220 return -EPERM;
1221 }
1222 if (fmdev->curr_fmmode == FM_MODE_OFF) {
1223 fmdbg("FM chip is already in OFF state\n");
1224 return 0;
1225 }
1226
1227 payload = 0x0;
1228 ret = fmc_send_cmd(fmdev, FM_POWER_MODE, REG_WR, &payload,
1229 sizeof(payload), NULL, NULL);
1230 if (ret < 0)
1231 return ret;
1232
1233 return fmc_release(fmdev);
1234}
1235
1236/* Reads init command from FM firmware file and loads to the chip */
1237static u32 fm_download_firmware(struct fmdev *fmdev, const u8 *fw_name)
1238{
1239 const struct firmware *fw_entry;
1240 struct bts_header *fw_header;
1241 struct bts_action *action;
1242 struct bts_action_delay *delay;
1243 u8 *fw_data;
1244 int ret, fw_len, cmd_cnt;
1245
1246 cmd_cnt = 0;
1247 set_bit(FM_FW_DW_INPROGRESS, &fmdev->flag);
1248
1249 ret = request_firmware(&fw_entry, fw_name,
1250 &fmdev->radio_dev->dev);
1251 if (ret < 0) {
1252 fmerr("Unable to read firmware(%s) content\n", fw_name);
1253 return ret;
1254 }
1255 fmdbg("Firmware(%s) length : %d bytes\n", fw_name, fw_entry->size);
1256
1257 fw_data = (void *)fw_entry->data;
1258 fw_len = fw_entry->size;
1259
1260 fw_header = (struct bts_header *)fw_data;
1261 if (fw_header->magic != FM_FW_FILE_HEADER_MAGIC) {
1262 fmerr("%s not a legal TI firmware file\n", fw_name);
1263 ret = -EINVAL;
1264 goto rel_fw;
1265 }
1266 fmdbg("FW(%s) magic number : 0x%x\n", fw_name, fw_header->magic);
1267
1268 /* Skip file header info , we already verified it */
1269 fw_data += sizeof(struct bts_header);
1270 fw_len -= sizeof(struct bts_header);
1271
1272 while (fw_data && fw_len > 0) {
1273 action = (struct bts_action *)fw_data;
1274
1275 switch (action->type) {
1276 case ACTION_SEND_COMMAND: /* Send */
1277 if (fmc_send_cmd(fmdev, 0, 0, action->data,
1278 action->size, NULL, NULL))
1279 goto rel_fw;
1280
1281 cmd_cnt++;
1282 break;
1283
1284 case ACTION_DELAY: /* Delay */
1285 delay = (struct bts_action_delay *)action->data;
1286 mdelay(delay->msec);
1287 break;
1288 }
1289
1290 fw_data += (sizeof(struct bts_action) + (action->size));
1291 fw_len -= (sizeof(struct bts_action) + (action->size));
1292 }
1293 fmdbg("Firmware commands(%d) loaded to chip\n", cmd_cnt);
1294rel_fw:
1295 release_firmware(fw_entry);
1296 clear_bit(FM_FW_DW_INPROGRESS, &fmdev->flag);
1297
1298 return ret;
1299}
1300
1301/* Loads default RX configuration to the chip */
1302static u32 load_default_rx_configuration(struct fmdev *fmdev)
1303{
1304 int ret;
1305
1306 ret = fm_rx_set_volume(fmdev, FM_DEFAULT_RX_VOLUME);
1307 if (ret < 0)
1308 return ret;
1309
1310 return fm_rx_set_rssi_threshold(fmdev, FM_DEFAULT_RSSI_THRESHOLD);
1311}
1312
1313/* Does FM power on sequence */
1314static u32 fm_power_up(struct fmdev *fmdev, u8 mode)
1315{
1316 u16 payload, asic_id, asic_ver;
1317 int resp_len, ret;
1318 u8 fw_name[50];
1319
1320 if (mode >= FM_MODE_ENTRY_MAX) {
1321 fmerr("Invalid firmware download option\n");
1322 return -EINVAL;
1323 }
1324
1325 /*
1326 * Initialize FM common module. FM GPIO toggling is
1327 * taken care in Shared Transport driver.
1328 */
1329 ret = fmc_prepare(fmdev);
1330 if (ret < 0) {
1331 fmerr("Unable to prepare FM Common\n");
1332 return ret;
1333 }
1334
1335 payload = FM_ENABLE;
1336 if (fmc_send_cmd(fmdev, FM_POWER_MODE, REG_WR, &payload,
1337 sizeof(payload), NULL, NULL))
1338 goto rel;
1339
1340 /* Allow the chip to settle down in Channel-8 mode */
1341 msleep(20);
1342
1343 if (fmc_send_cmd(fmdev, ASIC_ID_GET, REG_RD, NULL,
1344 sizeof(asic_id), &asic_id, &resp_len))
1345 goto rel;
1346
1347 if (fmc_send_cmd(fmdev, ASIC_VER_GET, REG_RD, NULL,
1348 sizeof(asic_ver), &asic_ver, &resp_len))
1349 goto rel;
1350
1351 fmdbg("ASIC ID: 0x%x , ASIC Version: %d\n",
1352 be16_to_cpu(asic_id), be16_to_cpu(asic_ver));
1353
1354 sprintf(fw_name, "%s_%x.%d.bts", FM_FMC_FW_FILE_START,
1355 be16_to_cpu(asic_id), be16_to_cpu(asic_ver));
1356
1357 ret = fm_download_firmware(fmdev, fw_name);
1358 if (ret < 0) {
1359 fmdbg("Failed to download firmware file %s\n", fw_name);
1360 goto rel;
1361 }
1362 sprintf(fw_name, "%s_%x.%d.bts", (mode == FM_MODE_RX) ?
1363 FM_RX_FW_FILE_START : FM_TX_FW_FILE_START,
1364 be16_to_cpu(asic_id), be16_to_cpu(asic_ver));
1365
1366 ret = fm_download_firmware(fmdev, fw_name);
1367 if (ret < 0) {
1368 fmdbg("Failed to download firmware file %s\n", fw_name);
1369 goto rel;
1370 } else
1371 return ret;
1372rel:
1373 return fmc_release(fmdev);
1374}
1375
1376/* Set FM Modes(TX, RX, OFF) */
1377u32 fmc_set_mode(struct fmdev *fmdev, u8 fm_mode)
1378{
1379 int ret = 0;
1380
1381 if (fm_mode >= FM_MODE_ENTRY_MAX) {
1382 fmerr("Invalid FM mode\n");
1383 return -EINVAL;
1384 }
1385 if (fmdev->curr_fmmode == fm_mode) {
1386 fmdbg("Already fm is in mode(%d)\n", fm_mode);
1387 return ret;
1388 }
1389
1390 switch (fm_mode) {
1391 case FM_MODE_OFF: /* OFF Mode */
1392 ret = fm_power_down(fmdev);
1393 if (ret < 0) {
1394 fmerr("Failed to set OFF mode\n");
1395 return ret;
1396 }
1397 break;
1398
1399 case FM_MODE_TX: /* TX Mode */
1400 case FM_MODE_RX: /* RX Mode */
1401 /* Power down before switching to TX or RX mode */
1402 if (fmdev->curr_fmmode != FM_MODE_OFF) {
1403 ret = fm_power_down(fmdev);
1404 if (ret < 0) {
1405 fmerr("Failed to set OFF mode\n");
1406 return ret;
1407 }
1408 msleep(30);
1409 }
1410 ret = fm_power_up(fmdev, fm_mode);
1411 if (ret < 0) {
1412 fmerr("Failed to load firmware\n");
1413 return ret;
1414 }
1415 }
1416 fmdev->curr_fmmode = fm_mode;
1417
1418 /* Set default configuration */
1419 if (fmdev->curr_fmmode == FM_MODE_RX) {
1420 fmdbg("Loading default rx configuration..\n");
1421 ret = load_default_rx_configuration(fmdev);
1422 if (ret < 0)
1423 fmerr("Failed to load default values\n");
1424 }
1425
1426 return ret;
1427}
1428
1429/* Returns current FM mode (TX, RX, OFF) */
1430u32 fmc_get_mode(struct fmdev *fmdev, u8 *fmmode)
1431{
1432 if (!test_bit(FM_CORE_READY, &fmdev->flag)) {
1433 fmerr("FM core is not ready\n");
1434 return -EPERM;
1435 }
1436 if (fmmode == NULL) {
1437 fmerr("Invalid memory\n");
1438 return -ENOMEM;
1439 }
1440
1441 *fmmode = fmdev->curr_fmmode;
1442 return 0;
1443}
1444
1445/* Called by ST layer when FM packet is available */
1446static long fm_st_receive(void *arg, struct sk_buff *skb)
1447{
1448 struct fmdev *fmdev;
1449
1450 fmdev = (struct fmdev *)arg;
1451
1452 if (skb == NULL) {
1453 fmerr("Invalid SKB received from ST\n");
1454 return -EFAULT;
1455 }
1456
1457 if (skb->cb[0] != FM_PKT_LOGICAL_CHAN_NUMBER) {
1458 fmerr("Received SKB (%p) is not FM Channel 8 pkt\n", skb);
1459 return -EINVAL;
1460 }
1461
1462 memcpy(skb_push(skb, 1), &skb->cb[0], 1);
1463 skb_queue_tail(&fmdev->rx_q, skb);
1464 tasklet_schedule(&fmdev->rx_task);
1465
1466 return 0;
1467}
1468
1469/*
1470 * Called by ST layer to indicate protocol registration completion
1471 * status.
1472 */
1473static void fm_st_reg_comp_cb(void *arg, char data)
1474{
1475 struct fmdev *fmdev;
1476
1477 fmdev = (struct fmdev *)arg;
1478 fmdev->streg_cbdata = data;
1479 complete(&wait_for_fmdrv_reg_comp);
1480}
1481
1482/*
1483 * This function will be called from FM V4L2 open function.
1484 * Register with ST driver and initialize driver data.
1485 */
1486u32 fmc_prepare(struct fmdev *fmdev)
1487{
1488 static struct st_proto_s fm_st_proto;
1489 u32 ret;
1490
1491 if (test_bit(FM_CORE_READY, &fmdev->flag)) {
1492 fmdbg("FM Core is already up\n");
1493 return 0;
1494 }
1495
1496 memset(&fm_st_proto, 0, sizeof(fm_st_proto));
1497 fm_st_proto.type = ST_FM;
1498 fm_st_proto.recv = fm_st_receive;
1499 fm_st_proto.match_packet = NULL;
1500 fm_st_proto.reg_complete_cb = fm_st_reg_comp_cb;
1501 fm_st_proto.write = NULL; /* TI ST driver will fill write pointer */
1502 fm_st_proto.priv_data = fmdev;
1503
1504 ret = st_register(&fm_st_proto);
1505 if (ret == -EINPROGRESS) {
1506 init_completion(&wait_for_fmdrv_reg_comp);
1507 fmdev->streg_cbdata = -EINPROGRESS;
1508 fmdbg("%s waiting for ST reg completion signal\n", __func__);
1509
1510 ret = wait_for_completion_timeout(&wait_for_fmdrv_reg_comp,
1511 FM_ST_REG_TIMEOUT);
1512
1513 if (!ret) {
1514 fmerr("Timeout(%d sec), didn't get reg "
1515 "completion signal from ST\n",
1516 jiffies_to_msecs(FM_ST_REG_TIMEOUT) / 1000);
1517 return -ETIMEDOUT;
1518 }
1519 if (fmdev->streg_cbdata != 0) {
1520 fmerr("ST reg comp CB called with error "
1521 "status %d\n", fmdev->streg_cbdata);
1522 return -EAGAIN;
1523 }
1524
1525 ret = 0;
1526 } else if (ret == -1) {
1527 fmerr("st_register failed %d\n", ret);
1528 return -EAGAIN;
1529 }
1530
1531 if (fm_st_proto.write != NULL) {
1532 g_st_write = fm_st_proto.write;
1533 } else {
1534 fmerr("Failed to get ST write func pointer\n");
1535 ret = st_unregister(ST_FM);
1536 if (ret < 0)
1537 fmerr("st_unregister failed %d\n", ret);
1538 return -EAGAIN;
1539 }
1540
1541 spin_lock_init(&fmdev->rds_buff_lock);
1542 spin_lock_init(&fmdev->resp_skb_lock);
1543
1544 /* Initialize TX queue and TX tasklet */
1545 skb_queue_head_init(&fmdev->tx_q);
1546 tasklet_init(&fmdev->tx_task, send_tasklet, (unsigned long)fmdev);
1547
1548 /* Initialize RX Queue and RX tasklet */
1549 skb_queue_head_init(&fmdev->rx_q);
1550 tasklet_init(&fmdev->rx_task, recv_tasklet, (unsigned long)fmdev);
1551
1552 fmdev->irq_info.stage = 0;
1553 atomic_set(&fmdev->tx_cnt, 1);
1554 fmdev->resp_comp = NULL;
1555
1556 init_timer(&fmdev->irq_info.timer);
1557 fmdev->irq_info.timer.function = &int_timeout_handler;
1558 fmdev->irq_info.timer.data = (unsigned long)fmdev;
1559 /*TODO: add FM_STIC_EVENT later */
1560 fmdev->irq_info.mask = FM_MAL_EVENT;
1561
1562 /* Region info */
1563 memcpy(&fmdev->rx.region, &region_configs[default_radio_region],
1564 sizeof(struct region_info));
1565
1566 fmdev->rx.mute_mode = FM_MUTE_OFF;
1567 fmdev->rx.rf_depend_mute = FM_RX_RF_DEPENDENT_MUTE_OFF;
1568 fmdev->rx.rds.flag = FM_RDS_DISABLE;
1569 fmdev->rx.freq = FM_UNDEFINED_FREQ;
1570 fmdev->rx.rds_mode = FM_RDS_SYSTEM_RDS;
1571 fmdev->rx.af_mode = FM_RX_RDS_AF_SWITCH_MODE_OFF;
1572 fmdev->irq_info.retry = 0;
1573
1574 fm_rx_reset_rds_cache(fmdev);
1575 init_waitqueue_head(&fmdev->rx.rds.read_queue);
1576
1577 fm_rx_reset_station_info(fmdev);
1578 set_bit(FM_CORE_READY, &fmdev->flag);
1579
1580 return ret;
1581}
1582
1583/*
1584 * This function will be called from FM V4L2 release function.
1585 * Unregister from ST driver.
1586 */
1587u32 fmc_release(struct fmdev *fmdev)
1588{
1589 u32 ret;
1590
1591 if (!test_bit(FM_CORE_READY, &fmdev->flag)) {
1592 fmdbg("FM Core is already down\n");
1593 return 0;
1594 }
1595 /* Sevice pending read */
1596 wake_up_interruptible(&fmdev->rx.rds.read_queue);
1597
1598 tasklet_kill(&fmdev->tx_task);
1599 tasklet_kill(&fmdev->rx_task);
1600
1601 skb_queue_purge(&fmdev->tx_q);
1602 skb_queue_purge(&fmdev->rx_q);
1603
1604 fmdev->resp_comp = NULL;
1605 fmdev->rx.freq = 0;
1606
1607 ret = st_unregister(ST_FM);
1608 if (ret < 0)
1609 fmerr("Failed to de-register FM from ST %d\n", ret);
1610 else
1611 fmdbg("Successfully unregistered from ST\n");
1612
1613 clear_bit(FM_CORE_READY, &fmdev->flag);
1614 return ret;
1615}
1616
1617/*
1618 * Module init function. Ask FM V4L module to register video device.
1619 * Allocate memory for FM driver context and RX RDS buffer.
1620 */
1621static int __init fm_drv_init(void)
1622{
1623 struct fmdev *fmdev = NULL;
1624 u32 ret = -ENOMEM;
1625
1626 fmdbg("FM driver version %s\n", FM_DRV_VERSION);
1627
1628 fmdev = kzalloc(sizeof(struct fmdev), GFP_KERNEL);
1629 if (NULL == fmdev) {
1630 fmerr("Can't allocate operation structure memory\n");
1631 return ret;
1632 }
1633 fmdev->rx.rds.buf_size = default_rds_buf * FM_RDS_BLK_SIZE;
1634 fmdev->rx.rds.buff = kzalloc(fmdev->rx.rds.buf_size, GFP_KERNEL);
1635 if (NULL == fmdev->rx.rds.buff) {
1636 fmerr("Can't allocate rds ring buffer\n");
1637 goto rel_dev;
1638 }
1639
1640 ret = fm_v4l2_init_video_device(fmdev, radio_nr);
1641 if (ret < 0)
1642 goto rel_rdsbuf;
1643
1644 fmdev->irq_info.handlers = int_handler_table;
1645 fmdev->curr_fmmode = FM_MODE_OFF;
1646 fmdev->tx_data.pwr_lvl = FM_PWR_LVL_DEF;
1647 fmdev->tx_data.preemph = FM_TX_PREEMPH_50US;
1648 return ret;
1649
1650rel_rdsbuf:
1651 kfree(fmdev->rx.rds.buff);
1652rel_dev:
1653 kfree(fmdev);
1654
1655 return ret;
1656}
1657
1658/* Module exit function. Ask FM V4L module to unregister video device */
1659static void __exit fm_drv_exit(void)
1660{
1661 struct fmdev *fmdev = NULL;
1662
1663 fmdev = fm_v4l2_deinit_video_device();
1664 if (fmdev != NULL) {
1665 kfree(fmdev->rx.rds.buff);
1666 kfree(fmdev);
1667 }
1668}
1669
1670module_init(fm_drv_init);
1671module_exit(fm_drv_exit);
1672
1673/* ------------- Module Info ------------- */
1674MODULE_AUTHOR("Manjunatha Halli <manjunatha_halli@ti.com>");
1675MODULE_DESCRIPTION("FM Driver for TI's Connectivity chip. " FM_DRV_VERSION);
1676MODULE_VERSION(FM_DRV_VERSION);
1677MODULE_LICENSE("GPL");
diff --git a/drivers/media/radio/wl128x/fmdrv_common.h b/drivers/media/radio/wl128x/fmdrv_common.h
new file mode 100644
index 000000000000..427c4164cece
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_common.h
@@ -0,0 +1,402 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 * FM Common module header file
4 *
5 * Copyright (C) 2011 Texas Instruments
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#ifndef _FMDRV_COMMON_H
23#define _FMDRV_COMMON_H
24
25#define FM_ST_REG_TIMEOUT msecs_to_jiffies(6000) /* 6 sec */
26#define FM_PKT_LOGICAL_CHAN_NUMBER 0x08 /* Logical channel 8 */
27
28#define REG_RD 0x1
29#define REG_WR 0x0
30
31struct fm_reg_table {
32 u8 opcode;
33 u8 type;
34 u8 *name;
35};
36
37#define STEREO_GET 0
38#define RSSI_LVL_GET 1
39#define IF_COUNT_GET 2
40#define FLAG_GET 3
41#define RDS_SYNC_GET 4
42#define RDS_DATA_GET 5
43#define FREQ_SET 10
44#define AF_FREQ_SET 11
45#define MOST_MODE_SET 12
46#define MOST_BLEND_SET 13
47#define DEMPH_MODE_SET 14
48#define SEARCH_LVL_SET 15
49#define BAND_SET 16
50#define MUTE_STATUS_SET 17
51#define RDS_PAUSE_LVL_SET 18
52#define RDS_PAUSE_DUR_SET 19
53#define RDS_MEM_SET 20
54#define RDS_BLK_B_SET 21
55#define RDS_MSK_B_SET 22
56#define RDS_PI_MASK_SET 23
57#define RDS_PI_SET 24
58#define RDS_SYSTEM_SET 25
59#define INT_MASK_SET 26
60#define SEARCH_DIR_SET 27
61#define VOLUME_SET 28
62#define AUDIO_ENABLE_SET 29
63#define PCM_MODE_SET 30
64#define I2S_MODE_CONFIG_SET 31
65#define POWER_SET 32
66#define INTX_CONFIG_SET 33
67#define PULL_EN_SET 34
68#define HILO_SET 35
69#define SWITCH2FREF 36
70#define FREQ_DRIFT_REPORT 37
71
72#define PCE_GET 40
73#define FIRM_VER_GET 41
74#define ASIC_VER_GET 42
75#define ASIC_ID_GET 43
76#define MAN_ID_GET 44
77#define TUNER_MODE_SET 45
78#define STOP_SEARCH 46
79#define RDS_CNTRL_SET 47
80
81#define WRITE_HARDWARE_REG 100
82#define CODE_DOWNLOAD 101
83#define RESET 102
84
85#define FM_POWER_MODE 254
86#define FM_INTERRUPT 255
87
88/* Transmitter API */
89
90#define CHANL_SET 55
91#define CHANL_BW_SET 56
92#define REF_SET 57
93#define POWER_ENB_SET 90
94#define POWER_ATT_SET 58
95#define POWER_LEV_SET 59
96#define AUDIO_DEV_SET 60
97#define PILOT_DEV_SET 61
98#define RDS_DEV_SET 62
99#define TX_BAND_SET 65
100#define PUPD_SET 91
101#define AUDIO_IO_SET 63
102#define PREMPH_SET 64
103#define MONO_SET 66
104#define MUTE 92
105#define MPX_LMT_ENABLE 67
106#define PI_SET 93
107#define ECC_SET 69
108#define PTY 70
109#define AF 71
110#define DISPLAY_MODE 74
111#define RDS_REP_SET 77
112#define RDS_CONFIG_DATA_SET 98
113#define RDS_DATA_SET 99
114#define RDS_DATA_ENB 94
115#define TA_SET 78
116#define TP_SET 79
117#define DI_SET 80
118#define MS_SET 81
119#define PS_SCROLL_SPEED 82
120#define TX_AUDIO_LEVEL_TEST 96
121#define TX_AUDIO_LEVEL_TEST_THRESHOLD 73
122#define TX_AUDIO_INPUT_LEVEL_RANGE_SET 54
123#define RX_ANTENNA_SELECT 87
124#define I2C_DEV_ADDR_SET 86
125#define REF_ERR_CALIB_PARAM_SET 88
126#define REF_ERR_CALIB_PERIODICITY_SET 89
127#define SOC_INT_TRIGGER 52
128#define SOC_AUDIO_PATH_SET 83
129#define SOC_PCMI_OVERRIDE 84
130#define SOC_I2S_OVERRIDE 85
131#define RSSI_BLOCK_SCAN_FREQ_SET 95
132#define RSSI_BLOCK_SCAN_START 97
133#define RSSI_BLOCK_SCAN_DATA_GET 5
134#define READ_FMANT_TUNE_VALUE 104
135
136/* SKB helpers */
137struct fm_skb_cb {
138 __u8 fm_op;
139 struct completion *completion;
140};
141
142#define fm_cb(skb) ((struct fm_skb_cb *)(skb->cb))
143
144/* FM Channel-8 command message format */
145struct fm_cmd_msg_hdr {
146 __u8 hdr; /* Logical Channel-8 */
147 __u8 len; /* Number of bytes follows */
148 __u8 op; /* FM Opcode */
149 __u8 rd_wr; /* Read/Write command */
150 __u8 dlen; /* Length of payload */
151} __attribute__ ((packed));
152
153#define FM_CMD_MSG_HDR_SIZE 5 /* sizeof(struct fm_cmd_msg_hdr) */
154
155/* FM Channel-8 event messgage format */
156struct fm_event_msg_hdr {
157 __u8 header; /* Logical Channel-8 */
158 __u8 len; /* Number of bytes follows */
159 __u8 status; /* Event status */
160 __u8 num_fm_hci_cmds; /* Number of pkts the host allowed to send */
161 __u8 op; /* FM Opcode */
162 __u8 rd_wr; /* Read/Write command */
163 __u8 dlen; /* Length of payload */
164} __attribute__ ((packed));
165
166#define FM_EVT_MSG_HDR_SIZE 7 /* sizeof(struct fm_event_msg_hdr) */
167
168/* TI's magic number in firmware file */
169#define FM_FW_FILE_HEADER_MAGIC 0x42535442
170
171#define FM_ENABLE 1
172#define FM_DISABLE 0
173
174/* FLAG_GET register bits */
175#define FM_FR_EVENT (1 << 0)
176#define FM_BL_EVENT (1 << 1)
177#define FM_RDS_EVENT (1 << 2)
178#define FM_BBLK_EVENT (1 << 3)
179#define FM_LSYNC_EVENT (1 << 4)
180#define FM_LEV_EVENT (1 << 5)
181#define FM_IFFR_EVENT (1 << 6)
182#define FM_PI_EVENT (1 << 7)
183#define FM_PD_EVENT (1 << 8)
184#define FM_STIC_EVENT (1 << 9)
185#define FM_MAL_EVENT (1 << 10)
186#define FM_POW_ENB_EVENT (1 << 11)
187
188/*
189 * Firmware files of FM. ASIC ID and ASIC version will be appened to this,
190 * later.
191 */
192#define FM_FMC_FW_FILE_START ("fmc_ch8")
193#define FM_RX_FW_FILE_START ("fm_rx_ch8")
194#define FM_TX_FW_FILE_START ("fm_tx_ch8")
195
196#define FM_UNDEFINED_FREQ 0xFFFFFFFF
197
198/* Band types */
199#define FM_BAND_EUROPE_US 0
200#define FM_BAND_JAPAN 1
201
202/* Seek directions */
203#define FM_SEARCH_DIRECTION_DOWN 0
204#define FM_SEARCH_DIRECTION_UP 1
205
206/* Tunner modes */
207#define FM_TUNER_STOP_SEARCH_MODE 0
208#define FM_TUNER_PRESET_MODE 1
209#define FM_TUNER_AUTONOMOUS_SEARCH_MODE 2
210#define FM_TUNER_AF_JUMP_MODE 3
211
212/* Min and Max volume */
213#define FM_RX_VOLUME_MIN 0
214#define FM_RX_VOLUME_MAX 70
215
216/* Volume gain step */
217#define FM_RX_VOLUME_GAIN_STEP 0x370
218
219/* Mute modes */
220#define FM_MUTE_ON 0
221#define FM_MUTE_OFF 1
222#define FM_MUTE_ATTENUATE 2
223
224#define FM_RX_UNMUTE_MODE 0x00
225#define FM_RX_RF_DEP_MODE 0x01
226#define FM_RX_AC_MUTE_MODE 0x02
227#define FM_RX_HARD_MUTE_LEFT_MODE 0x04
228#define FM_RX_HARD_MUTE_RIGHT_MODE 0x08
229#define FM_RX_SOFT_MUTE_FORCE_MODE 0x10
230
231/* RF dependent mute mode */
232#define FM_RX_RF_DEPENDENT_MUTE_ON 1
233#define FM_RX_RF_DEPENDENT_MUTE_OFF 0
234
235/* RSSI threshold min and max */
236#define FM_RX_RSSI_THRESHOLD_MIN -128
237#define FM_RX_RSSI_THRESHOLD_MAX 127
238
239/* Stereo/Mono mode */
240#define FM_STEREO_MODE 0
241#define FM_MONO_MODE 1
242#define FM_STEREO_SOFT_BLEND 1
243
244/* FM RX De-emphasis filter modes */
245#define FM_RX_EMPHASIS_FILTER_50_USEC 0
246#define FM_RX_EMPHASIS_FILTER_75_USEC 1
247
248/* FM RDS modes */
249#define FM_RDS_DISABLE 0
250#define FM_RDS_ENABLE 1
251
252#define FM_NO_PI_CODE 0
253
254/* FM and RX RDS block enable/disable */
255#define FM_RX_PWR_SET_FM_ON_RDS_OFF 0x1
256#define FM_RX_PWR_SET_FM_AND_RDS_BLK_ON 0x3
257#define FM_RX_PWR_SET_FM_AND_RDS_BLK_OFF 0x0
258
259/* RX RDS */
260#define FM_RX_RDS_FLUSH_FIFO 0x1
261#define FM_RX_RDS_FIFO_THRESHOLD 64 /* tuples */
262#define FM_RDS_BLK_SIZE 3 /* 3 bytes */
263
264/* RDS block types */
265#define FM_RDS_BLOCK_A 0
266#define FM_RDS_BLOCK_B 1
267#define FM_RDS_BLOCK_C 2
268#define FM_RDS_BLOCK_Ctag 3
269#define FM_RDS_BLOCK_D 4
270#define FM_RDS_BLOCK_E 5
271
272#define FM_RDS_BLK_IDX_A 0
273#define FM_RDS_BLK_IDX_B 1
274#define FM_RDS_BLK_IDX_C 2
275#define FM_RDS_BLK_IDX_D 3
276#define FM_RDS_BLK_IDX_UNKNOWN 0xF0
277
278#define FM_RDS_STATUS_ERR_MASK 0x18
279
280/*
281 * Represents an RDS group type & version.
282 * There are 15 groups, each group has 2 versions: A and B.
283 */
284#define FM_RDS_GROUP_TYPE_MASK_0A ((unsigned long)1<<0)
285#define FM_RDS_GROUP_TYPE_MASK_0B ((unsigned long)1<<1)
286#define FM_RDS_GROUP_TYPE_MASK_1A ((unsigned long)1<<2)
287#define FM_RDS_GROUP_TYPE_MASK_1B ((unsigned long)1<<3)
288#define FM_RDS_GROUP_TYPE_MASK_2A ((unsigned long)1<<4)
289#define FM_RDS_GROUP_TYPE_MASK_2B ((unsigned long)1<<5)
290#define FM_RDS_GROUP_TYPE_MASK_3A ((unsigned long)1<<6)
291#define FM_RDS_GROUP_TYPE_MASK_3B ((unsigned long)1<<7)
292#define FM_RDS_GROUP_TYPE_MASK_4A ((unsigned long)1<<8)
293#define FM_RDS_GROUP_TYPE_MASK_4B ((unsigned long)1<<9)
294#define FM_RDS_GROUP_TYPE_MASK_5A ((unsigned long)1<<10)
295#define FM_RDS_GROUP_TYPE_MASK_5B ((unsigned long)1<<11)
296#define FM_RDS_GROUP_TYPE_MASK_6A ((unsigned long)1<<12)
297#define FM_RDS_GROUP_TYPE_MASK_6B ((unsigned long)1<<13)
298#define FM_RDS_GROUP_TYPE_MASK_7A ((unsigned long)1<<14)
299#define FM_RDS_GROUP_TYPE_MASK_7B ((unsigned long)1<<15)
300#define FM_RDS_GROUP_TYPE_MASK_8A ((unsigned long)1<<16)
301#define FM_RDS_GROUP_TYPE_MASK_8B ((unsigned long)1<<17)
302#define FM_RDS_GROUP_TYPE_MASK_9A ((unsigned long)1<<18)
303#define FM_RDS_GROUP_TYPE_MASK_9B ((unsigned long)1<<19)
304#define FM_RDS_GROUP_TYPE_MASK_10A ((unsigned long)1<<20)
305#define FM_RDS_GROUP_TYPE_MASK_10B ((unsigned long)1<<21)
306#define FM_RDS_GROUP_TYPE_MASK_11A ((unsigned long)1<<22)
307#define FM_RDS_GROUP_TYPE_MASK_11B ((unsigned long)1<<23)
308#define FM_RDS_GROUP_TYPE_MASK_12A ((unsigned long)1<<24)
309#define FM_RDS_GROUP_TYPE_MASK_12B ((unsigned long)1<<25)
310#define FM_RDS_GROUP_TYPE_MASK_13A ((unsigned long)1<<26)
311#define FM_RDS_GROUP_TYPE_MASK_13B ((unsigned long)1<<27)
312#define FM_RDS_GROUP_TYPE_MASK_14A ((unsigned long)1<<28)
313#define FM_RDS_GROUP_TYPE_MASK_14B ((unsigned long)1<<29)
314#define FM_RDS_GROUP_TYPE_MASK_15A ((unsigned long)1<<30)
315#define FM_RDS_GROUP_TYPE_MASK_15B ((unsigned long)1<<31)
316
317/* RX Alternate Frequency info */
318#define FM_RDS_MIN_AF 1
319#define FM_RDS_MAX_AF 204
320#define FM_RDS_MAX_AF_JAPAN 140
321#define FM_RDS_1_AF_FOLLOWS 225
322#define FM_RDS_25_AF_FOLLOWS 249
323
324/* RDS system type (RDS/RBDS) */
325#define FM_RDS_SYSTEM_RDS 0
326#define FM_RDS_SYSTEM_RBDS 1
327
328/* AF on/off */
329#define FM_RX_RDS_AF_SWITCH_MODE_ON 1
330#define FM_RX_RDS_AF_SWITCH_MODE_OFF 0
331
332/* Retry count when interrupt process goes wrong */
333#define FM_IRQ_TIMEOUT_RETRY_MAX 5 /* 5 times */
334
335/* Audio IO set values */
336#define FM_RX_AUDIO_ENABLE_I2S 0x01
337#define FM_RX_AUDIO_ENABLE_ANALOG 0x02
338#define FM_RX_AUDIO_ENABLE_I2S_AND_ANALOG 0x03
339#define FM_RX_AUDIO_ENABLE_DISABLE 0x00
340
341/* HI/LO set values */
342#define FM_RX_IFFREQ_TO_HI_SIDE 0x0
343#define FM_RX_IFFREQ_TO_LO_SIDE 0x1
344#define FM_RX_IFFREQ_HILO_AUTOMATIC 0x2
345
346/*
347 * Default RX mode configuration. Chip will be configured
348 * with this default values after loading RX firmware.
349 */
350#define FM_DEFAULT_RX_VOLUME 10
351#define FM_DEFAULT_RSSI_THRESHOLD 3
352
353/* Range for TX power level in units for dB/uV */
354#define FM_PWR_LVL_LOW 91
355#define FM_PWR_LVL_HIGH 122
356
357/* Chip specific default TX power level value */
358#define FM_PWR_LVL_DEF 4
359
360/* FM TX Pre-emphasis filter values */
361#define FM_TX_PREEMPH_OFF 1
362#define FM_TX_PREEMPH_50US 0
363#define FM_TX_PREEMPH_75US 2
364
365/* FM TX antenna impedence values */
366#define FM_TX_ANT_IMP_50 0
367#define FM_TX_ANT_IMP_200 1
368#define FM_TX_ANT_IMP_500 2
369
370/* Functions exported by FM common sub-module */
371u32 fmc_prepare(struct fmdev *);
372u32 fmc_release(struct fmdev *);
373
374void fmc_update_region_info(struct fmdev *, u8);
375u32 fmc_send_cmd(struct fmdev *, u8, u16,
376 void *, unsigned int, void *, int *);
377u32 fmc_is_rds_data_available(struct fmdev *, struct file *,
378 struct poll_table_struct *);
379u32 fmc_transfer_rds_from_internal_buff(struct fmdev *, struct file *,
380 u8 __user *, size_t);
381
382u32 fmc_set_freq(struct fmdev *, u32);
383u32 fmc_set_mode(struct fmdev *, u8);
384u32 fmc_set_region(struct fmdev *, u8);
385u32 fmc_set_mute_mode(struct fmdev *, u8);
386u32 fmc_set_stereo_mono(struct fmdev *, u16);
387u32 fmc_set_rds_mode(struct fmdev *, u8);
388
389u32 fmc_get_freq(struct fmdev *, u32 *);
390u32 fmc_get_region(struct fmdev *, u8 *);
391u32 fmc_get_mode(struct fmdev *, u8 *);
392
393/*
394 * channel spacing
395 */
396#define FM_CHANNEL_SPACING_50KHZ 1
397#define FM_CHANNEL_SPACING_100KHZ 2
398#define FM_CHANNEL_SPACING_200KHZ 4
399#define FM_FREQ_MUL 50
400
401#endif
402
diff --git a/drivers/media/radio/wl128x/fmdrv_rx.c b/drivers/media/radio/wl128x/fmdrv_rx.c
new file mode 100644
index 000000000000..ec529b55b040
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_rx.c
@@ -0,0 +1,847 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 * This sub-module of FM driver implements FM RX functionality.
4 *
5 * Copyright (C) 2011 Texas Instruments
6 * Author: Raja Mani <raja_mani@ti.com>
7 * Author: Manjunatha Halli <manjunatha_halli@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include "fmdrv.h"
25#include "fmdrv_common.h"
26#include "fmdrv_rx.h"
27
28void fm_rx_reset_rds_cache(struct fmdev *fmdev)
29{
30 fmdev->rx.rds.flag = FM_RDS_DISABLE;
31 fmdev->rx.rds.last_blk_idx = 0;
32 fmdev->rx.rds.wr_idx = 0;
33 fmdev->rx.rds.rd_idx = 0;
34
35 if (fmdev->rx.af_mode == FM_RX_RDS_AF_SWITCH_MODE_ON)
36 fmdev->irq_info.mask |= FM_LEV_EVENT;
37}
38
39void fm_rx_reset_station_info(struct fmdev *fmdev)
40{
41 fmdev->rx.stat_info.picode = FM_NO_PI_CODE;
42 fmdev->rx.stat_info.afcache_size = 0;
43 fmdev->rx.stat_info.af_list_max = 0;
44}
45
46u32 fm_rx_set_freq(struct fmdev *fmdev, u32 freq)
47{
48 unsigned long timeleft;
49 u16 payload, curr_frq, intr_flag;
50 u32 curr_frq_in_khz;
51 u32 ret, resp_len;
52
53 if (freq < fmdev->rx.region.bot_freq || freq > fmdev->rx.region.top_freq) {
54 fmerr("Invalid frequency %d\n", freq);
55 return -EINVAL;
56 }
57
58 /* Set audio enable */
59 payload = FM_RX_AUDIO_ENABLE_I2S_AND_ANALOG;
60
61 ret = fmc_send_cmd(fmdev, AUDIO_ENABLE_SET, REG_WR, &payload,
62 sizeof(payload), NULL, NULL);
63 if (ret < 0)
64 return ret;
65
66 /* Set hilo to automatic selection */
67 payload = FM_RX_IFFREQ_HILO_AUTOMATIC;
68 ret = fmc_send_cmd(fmdev, HILO_SET, REG_WR, &payload,
69 sizeof(payload), NULL, NULL);
70 if (ret < 0)
71 return ret;
72
73 /* Calculate frequency index and set*/
74 payload = (freq - fmdev->rx.region.bot_freq) / FM_FREQ_MUL;
75
76 ret = fmc_send_cmd(fmdev, FREQ_SET, REG_WR, &payload,
77 sizeof(payload), NULL, NULL);
78 if (ret < 0)
79 return ret;
80
81 /* Read flags - just to clear any pending interrupts if we had */
82 ret = fmc_send_cmd(fmdev, FLAG_GET, REG_RD, NULL, 2, NULL, NULL);
83 if (ret < 0)
84 return ret;
85
86 /* Enable FR, BL interrupts */
87 intr_flag = fmdev->irq_info.mask;
88 fmdev->irq_info.mask = (FM_FR_EVENT | FM_BL_EVENT);
89 payload = fmdev->irq_info.mask;
90 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
91 sizeof(payload), NULL, NULL);
92 if (ret < 0)
93 return ret;
94
95 /* Start tune */
96 payload = FM_TUNER_PRESET_MODE;
97 ret = fmc_send_cmd(fmdev, TUNER_MODE_SET, REG_WR, &payload,
98 sizeof(payload), NULL, NULL);
99 if (ret < 0)
100 goto exit;
101
102 /* Wait for tune ended interrupt */
103 init_completion(&fmdev->maintask_comp);
104 timeleft = wait_for_completion_timeout(&fmdev->maintask_comp,
105 FM_DRV_TX_TIMEOUT);
106 if (!timeleft) {
107 fmerr("Timeout(%d sec),didn't get tune ended int\n",
108 jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000);
109 ret = -ETIMEDOUT;
110 goto exit;
111 }
112
113 /* Read freq back to confirm */
114 ret = fmc_send_cmd(fmdev, FREQ_SET, REG_RD, NULL, 2, &curr_frq, &resp_len);
115 if (ret < 0)
116 goto exit;
117
118 curr_frq = be16_to_cpu(curr_frq);
119 curr_frq_in_khz = (fmdev->rx.region.bot_freq + ((u32)curr_frq * FM_FREQ_MUL));
120
121 if (curr_frq_in_khz != freq) {
122 pr_info("Frequency is set to (%d) but "
123 "requested freq is (%d)\n", curr_frq_in_khz, freq);
124 }
125
126 /* Update local cache */
127 fmdev->rx.freq = curr_frq_in_khz;
128exit:
129 /* Re-enable default FM interrupts */
130 fmdev->irq_info.mask = intr_flag;
131 payload = fmdev->irq_info.mask;
132 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
133 sizeof(payload), NULL, NULL);
134 if (ret < 0)
135 return ret;
136
137 /* Reset RDS cache and current station pointers */
138 fm_rx_reset_rds_cache(fmdev);
139 fm_rx_reset_station_info(fmdev);
140
141 return ret;
142}
143
144static u32 fm_rx_set_channel_spacing(struct fmdev *fmdev, u32 spacing)
145{
146 u16 payload;
147 u32 ret;
148
149 if (spacing > 0 && spacing <= 50000)
150 spacing = FM_CHANNEL_SPACING_50KHZ;
151 else if (spacing > 50000 && spacing <= 100000)
152 spacing = FM_CHANNEL_SPACING_100KHZ;
153 else
154 spacing = FM_CHANNEL_SPACING_200KHZ;
155
156 /* set channel spacing */
157 payload = spacing;
158 ret = fmc_send_cmd(fmdev, CHANL_BW_SET, REG_WR, &payload,
159 sizeof(payload), NULL, NULL);
160 if (ret < 0)
161 return ret;
162
163 fmdev->rx.region.chanl_space = spacing * FM_FREQ_MUL;
164
165 return ret;
166}
167
168u32 fm_rx_seek(struct fmdev *fmdev, u32 seek_upward,
169 u32 wrap_around, u32 spacing)
170{
171 u32 resp_len;
172 u16 curr_frq, next_frq, last_frq;
173 u16 payload, int_reason, intr_flag;
174 u16 offset, space_idx;
175 unsigned long timeleft;
176 u32 ret;
177
178 /* Set channel spacing */
179 ret = fm_rx_set_channel_spacing(fmdev, spacing);
180 if (ret < 0) {
181 fmerr("Failed to set channel spacing\n");
182 return ret;
183 }
184
185 /* Read the current frequency from chip */
186 ret = fmc_send_cmd(fmdev, FREQ_SET, REG_RD, NULL,
187 sizeof(curr_frq), &curr_frq, &resp_len);
188 if (ret < 0)
189 return ret;
190
191 curr_frq = be16_to_cpu(curr_frq);
192 last_frq = (fmdev->rx.region.top_freq - fmdev->rx.region.bot_freq) / FM_FREQ_MUL;
193
194 /* Check the offset in order to be aligned to the channel spacing*/
195 space_idx = fmdev->rx.region.chanl_space / FM_FREQ_MUL;
196 offset = curr_frq % space_idx;
197
198 next_frq = seek_upward ? curr_frq + space_idx /* Seek Up */ :
199 curr_frq - space_idx /* Seek Down */ ;
200
201 /*
202 * Add or subtract offset in order to stay aligned to the channel
203 * spacing.
204 */
205 if ((short)next_frq < 0)
206 next_frq = last_frq - offset;
207 else if (next_frq > last_frq)
208 next_frq = 0 + offset;
209
210again:
211 /* Set calculated next frequency to perform seek */
212 payload = next_frq;
213 ret = fmc_send_cmd(fmdev, FREQ_SET, REG_WR, &payload,
214 sizeof(payload), NULL, NULL);
215 if (ret < 0)
216 return ret;
217
218 /* Set search direction (0:Seek Down, 1:Seek Up) */
219 payload = (seek_upward ? FM_SEARCH_DIRECTION_UP : FM_SEARCH_DIRECTION_DOWN);
220 ret = fmc_send_cmd(fmdev, SEARCH_DIR_SET, REG_WR, &payload,
221 sizeof(payload), NULL, NULL);
222 if (ret < 0)
223 return ret;
224
225 /* Read flags - just to clear any pending interrupts if we had */
226 ret = fmc_send_cmd(fmdev, FLAG_GET, REG_RD, NULL, 2, NULL, NULL);
227 if (ret < 0)
228 return ret;
229
230 /* Enable FR, BL interrupts */
231 intr_flag = fmdev->irq_info.mask;
232 fmdev->irq_info.mask = (FM_FR_EVENT | FM_BL_EVENT);
233 payload = fmdev->irq_info.mask;
234 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
235 sizeof(payload), NULL, NULL);
236 if (ret < 0)
237 return ret;
238
239 /* Start seek */
240 payload = FM_TUNER_AUTONOMOUS_SEARCH_MODE;
241 ret = fmc_send_cmd(fmdev, TUNER_MODE_SET, REG_WR, &payload,
242 sizeof(payload), NULL, NULL);
243 if (ret < 0)
244 return ret;
245
246 /* Wait for tune ended/band limit reached interrupt */
247 init_completion(&fmdev->maintask_comp);
248 timeleft = wait_for_completion_timeout(&fmdev->maintask_comp,
249 FM_DRV_RX_SEEK_TIMEOUT);
250 if (!timeleft) {
251 fmerr("Timeout(%d sec),didn't get tune ended int\n",
252 jiffies_to_msecs(FM_DRV_RX_SEEK_TIMEOUT) / 1000);
253 return -ETIMEDOUT;
254 }
255
256 int_reason = fmdev->irq_info.flag & (FM_TUNE_COMPLETE | FM_BAND_LIMIT);
257
258 /* Re-enable default FM interrupts */
259 fmdev->irq_info.mask = intr_flag;
260 payload = fmdev->irq_info.mask;
261 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
262 sizeof(payload), NULL, NULL);
263 if (ret < 0)
264 return ret;
265
266 if (int_reason & FM_BL_EVENT) {
267 if (wrap_around == 0) {
268 fmdev->rx.freq = seek_upward ?
269 fmdev->rx.region.top_freq :
270 fmdev->rx.region.bot_freq;
271 } else {
272 fmdev->rx.freq = seek_upward ?
273 fmdev->rx.region.bot_freq :
274 fmdev->rx.region.top_freq;
275 /* Calculate frequency index to write */
276 next_frq = (fmdev->rx.freq -
277 fmdev->rx.region.bot_freq) / FM_FREQ_MUL;
278 goto again;
279 }
280 } else {
281 /* Read freq to know where operation tune operation stopped */
282 ret = fmc_send_cmd(fmdev, FREQ_SET, REG_RD, NULL, 2,
283 &curr_frq, &resp_len);
284 if (ret < 0)
285 return ret;
286
287 curr_frq = be16_to_cpu(curr_frq);
288 fmdev->rx.freq = (fmdev->rx.region.bot_freq +
289 ((u32)curr_frq * FM_FREQ_MUL));
290
291 }
292 /* Reset RDS cache and current station pointers */
293 fm_rx_reset_rds_cache(fmdev);
294 fm_rx_reset_station_info(fmdev);
295
296 return ret;
297}
298
299u32 fm_rx_set_volume(struct fmdev *fmdev, u16 vol_to_set)
300{
301 u16 payload;
302 u32 ret;
303
304 if (fmdev->curr_fmmode != FM_MODE_RX)
305 return -EPERM;
306
307 if (vol_to_set < FM_RX_VOLUME_MIN || vol_to_set > FM_RX_VOLUME_MAX) {
308 fmerr("Volume is not within(%d-%d) range\n",
309 FM_RX_VOLUME_MIN, FM_RX_VOLUME_MAX);
310 return -EINVAL;
311 }
312 vol_to_set *= FM_RX_VOLUME_GAIN_STEP;
313
314 payload = vol_to_set;
315 ret = fmc_send_cmd(fmdev, VOLUME_SET, REG_WR, &payload,
316 sizeof(payload), NULL, NULL);
317 if (ret < 0)
318 return ret;
319
320 fmdev->rx.volume = vol_to_set;
321 return ret;
322}
323
324/* Get volume */
325u32 fm_rx_get_volume(struct fmdev *fmdev, u16 *curr_vol)
326{
327 if (fmdev->curr_fmmode != FM_MODE_RX)
328 return -EPERM;
329
330 if (curr_vol == NULL) {
331 fmerr("Invalid memory\n");
332 return -ENOMEM;
333 }
334
335 *curr_vol = fmdev->rx.volume / FM_RX_VOLUME_GAIN_STEP;
336
337 return 0;
338}
339
340/* To get current band's bottom and top frequency */
341u32 fm_rx_get_band_freq_range(struct fmdev *fmdev, u32 *bot_freq, u32 *top_freq)
342{
343 if (bot_freq != NULL)
344 *bot_freq = fmdev->rx.region.bot_freq;
345
346 if (top_freq != NULL)
347 *top_freq = fmdev->rx.region.top_freq;
348
349 return 0;
350}
351
352/* Returns current band index (0-Europe/US; 1-Japan) */
353void fm_rx_get_region(struct fmdev *fmdev, u8 *region)
354{
355 *region = fmdev->rx.region.fm_band;
356}
357
358/* Sets band (0-Europe/US; 1-Japan) */
359u32 fm_rx_set_region(struct fmdev *fmdev, u8 region_to_set)
360{
361 u16 payload;
362 u32 new_frq = 0;
363 u32 ret;
364
365 if (region_to_set != FM_BAND_EUROPE_US &&
366 region_to_set != FM_BAND_JAPAN) {
367 fmerr("Invalid band\n");
368 return -EINVAL;
369 }
370
371 if (fmdev->rx.region.fm_band == region_to_set) {
372 fmerr("Requested band is already configured\n");
373 return 0;
374 }
375
376 /* Send cmd to set the band */
377 payload = (u16)region_to_set;
378 ret = fmc_send_cmd(fmdev, BAND_SET, REG_WR, &payload,
379 sizeof(payload), NULL, NULL);
380 if (ret < 0)
381 return ret;
382
383 fmc_update_region_info(fmdev, region_to_set);
384
385 /* Check whether current RX frequency is within band boundary */
386 if (fmdev->rx.freq < fmdev->rx.region.bot_freq)
387 new_frq = fmdev->rx.region.bot_freq;
388 else if (fmdev->rx.freq > fmdev->rx.region.top_freq)
389 new_frq = fmdev->rx.region.top_freq;
390
391 if (new_frq) {
392 fmdbg("Current freq is not within band limit boundary,"
393 "switching to %d KHz\n", new_frq);
394 /* Current RX frequency is not in range. So, update it */
395 ret = fm_rx_set_freq(fmdev, new_frq);
396 }
397
398 return ret;
399}
400
401/* Reads current mute mode (Mute Off/On/Attenuate)*/
402u32 fm_rx_get_mute_mode(struct fmdev *fmdev, u8 *curr_mute_mode)
403{
404 if (fmdev->curr_fmmode != FM_MODE_RX)
405 return -EPERM;
406
407 if (curr_mute_mode == NULL) {
408 fmerr("Invalid memory\n");
409 return -ENOMEM;
410 }
411
412 *curr_mute_mode = fmdev->rx.mute_mode;
413
414 return 0;
415}
416
417static u32 fm_config_rx_mute_reg(struct fmdev *fmdev)
418{
419 u16 payload, muteval;
420 u32 ret;
421
422 muteval = 0;
423 switch (fmdev->rx.mute_mode) {
424 case FM_MUTE_ON:
425 muteval = FM_RX_AC_MUTE_MODE;
426 break;
427
428 case FM_MUTE_OFF:
429 muteval = FM_RX_UNMUTE_MODE;
430 break;
431
432 case FM_MUTE_ATTENUATE:
433 muteval = FM_RX_SOFT_MUTE_FORCE_MODE;
434 break;
435 }
436 if (fmdev->rx.rf_depend_mute == FM_RX_RF_DEPENDENT_MUTE_ON)
437 muteval |= FM_RX_RF_DEP_MODE;
438 else
439 muteval &= ~FM_RX_RF_DEP_MODE;
440
441 payload = muteval;
442 ret = fmc_send_cmd(fmdev, MUTE_STATUS_SET, REG_WR, &payload,
443 sizeof(payload), NULL, NULL);
444 if (ret < 0)
445 return ret;
446
447 return 0;
448}
449
450/* Configures mute mode (Mute Off/On/Attenuate) */
451u32 fm_rx_set_mute_mode(struct fmdev *fmdev, u8 mute_mode_toset)
452{
453 u8 org_state;
454 u32 ret;
455
456 if (fmdev->rx.mute_mode == mute_mode_toset)
457 return 0;
458
459 org_state = fmdev->rx.mute_mode;
460 fmdev->rx.mute_mode = mute_mode_toset;
461
462 ret = fm_config_rx_mute_reg(fmdev);
463 if (ret < 0) {
464 fmdev->rx.mute_mode = org_state;
465 return ret;
466 }
467
468 return 0;
469}
470
471/* Gets RF dependent soft mute mode enable/disable status */
472u32 fm_rx_get_rfdepend_softmute(struct fmdev *fmdev, u8 *curr_mute_mode)
473{
474 if (fmdev->curr_fmmode != FM_MODE_RX)
475 return -EPERM;
476
477 if (curr_mute_mode == NULL) {
478 fmerr("Invalid memory\n");
479 return -ENOMEM;
480 }
481
482 *curr_mute_mode = fmdev->rx.rf_depend_mute;
483
484 return 0;
485}
486
487/* Sets RF dependent soft mute mode */
488u32 fm_rx_set_rfdepend_softmute(struct fmdev *fmdev, u8 rfdepend_mute)
489{
490 u8 org_state;
491 u32 ret;
492
493 if (fmdev->curr_fmmode != FM_MODE_RX)
494 return -EPERM;
495
496 if (rfdepend_mute != FM_RX_RF_DEPENDENT_MUTE_ON &&
497 rfdepend_mute != FM_RX_RF_DEPENDENT_MUTE_OFF) {
498 fmerr("Invalid RF dependent soft mute\n");
499 return -EINVAL;
500 }
501 if (fmdev->rx.rf_depend_mute == rfdepend_mute)
502 return 0;
503
504 org_state = fmdev->rx.rf_depend_mute;
505 fmdev->rx.rf_depend_mute = rfdepend_mute;
506
507 ret = fm_config_rx_mute_reg(fmdev);
508 if (ret < 0) {
509 fmdev->rx.rf_depend_mute = org_state;
510 return ret;
511 }
512
513 return 0;
514}
515
516/* Returns the signal strength level of current channel */
517u32 fm_rx_get_rssi_level(struct fmdev *fmdev, u16 *rssilvl)
518{
519 u16 curr_rssi_lel;
520 u32 resp_len;
521 u32 ret;
522
523 if (rssilvl == NULL) {
524 fmerr("Invalid memory\n");
525 return -ENOMEM;
526 }
527 /* Read current RSSI level */
528 ret = fmc_send_cmd(fmdev, RSSI_LVL_GET, REG_RD, NULL, 2,
529 &curr_rssi_lel, &resp_len);
530 if (ret < 0)
531 return ret;
532
533 *rssilvl = be16_to_cpu(curr_rssi_lel);
534
535 return 0;
536}
537
538/*
539 * Sets the signal strength level that once reached
540 * will stop the auto search process
541 */
542u32 fm_rx_set_rssi_threshold(struct fmdev *fmdev, short rssi_lvl_toset)
543{
544 u16 payload;
545 u32 ret;
546
547 if (rssi_lvl_toset < FM_RX_RSSI_THRESHOLD_MIN ||
548 rssi_lvl_toset > FM_RX_RSSI_THRESHOLD_MAX) {
549 fmerr("Invalid RSSI threshold level\n");
550 return -EINVAL;
551 }
552 payload = (u16)rssi_lvl_toset;
553 ret = fmc_send_cmd(fmdev, SEARCH_LVL_SET, REG_WR, &payload,
554 sizeof(payload), NULL, NULL);
555 if (ret < 0)
556 return ret;
557
558 fmdev->rx.rssi_threshold = rssi_lvl_toset;
559
560 return 0;
561}
562
563/* Returns current RX RSSI threshold value */
564u32 fm_rx_get_rssi_threshold(struct fmdev *fmdev, short *curr_rssi_lvl)
565{
566 if (fmdev->curr_fmmode != FM_MODE_RX)
567 return -EPERM;
568
569 if (curr_rssi_lvl == NULL) {
570 fmerr("Invalid memory\n");
571 return -ENOMEM;
572 }
573
574 *curr_rssi_lvl = fmdev->rx.rssi_threshold;
575
576 return 0;
577}
578
579/* Sets RX stereo/mono modes */
580u32 fm_rx_set_stereo_mono(struct fmdev *fmdev, u16 mode)
581{
582 u16 payload;
583 u32 ret;
584
585 if (mode != FM_STEREO_MODE && mode != FM_MONO_MODE) {
586 fmerr("Invalid mode\n");
587 return -EINVAL;
588 }
589
590 /* Set stereo/mono mode */
591 payload = (u16)mode;
592 ret = fmc_send_cmd(fmdev, MOST_MODE_SET, REG_WR, &payload,
593 sizeof(payload), NULL, NULL);
594 if (ret < 0)
595 return ret;
596
597 /* Set stereo blending mode */
598 payload = FM_STEREO_SOFT_BLEND;
599 ret = fmc_send_cmd(fmdev, MOST_BLEND_SET, REG_WR, &payload,
600 sizeof(payload), NULL, NULL);
601 if (ret < 0)
602 return ret;
603
604 return 0;
605}
606
607/* Gets current RX stereo/mono mode */
608u32 fm_rx_get_stereo_mono(struct fmdev *fmdev, u16 *mode)
609{
610 u16 curr_mode;
611 u32 ret, resp_len;
612
613 if (mode == NULL) {
614 fmerr("Invalid memory\n");
615 return -ENOMEM;
616 }
617
618 ret = fmc_send_cmd(fmdev, MOST_MODE_SET, REG_RD, NULL, 2,
619 &curr_mode, &resp_len);
620 if (ret < 0)
621 return ret;
622
623 *mode = be16_to_cpu(curr_mode);
624
625 return 0;
626}
627
628/* Choose RX de-emphasis filter mode (50us/75us) */
629u32 fm_rx_set_deemphasis_mode(struct fmdev *fmdev, u16 mode)
630{
631 u16 payload;
632 u32 ret;
633
634 if (fmdev->curr_fmmode != FM_MODE_RX)
635 return -EPERM;
636
637 if (mode != FM_RX_EMPHASIS_FILTER_50_USEC &&
638 mode != FM_RX_EMPHASIS_FILTER_75_USEC) {
639 fmerr("Invalid rx de-emphasis mode (%d)\n", mode);
640 return -EINVAL;
641 }
642
643 payload = mode;
644 ret = fmc_send_cmd(fmdev, DEMPH_MODE_SET, REG_WR, &payload,
645 sizeof(payload), NULL, NULL);
646 if (ret < 0)
647 return ret;
648
649 fmdev->rx.deemphasis_mode = mode;
650
651 return 0;
652}
653
654/* Gets current RX de-emphasis filter mode */
655u32 fm_rx_get_deemph_mode(struct fmdev *fmdev, u16 *curr_deemphasis_mode)
656{
657 if (fmdev->curr_fmmode != FM_MODE_RX)
658 return -EPERM;
659
660 if (curr_deemphasis_mode == NULL) {
661 fmerr("Invalid memory\n");
662 return -ENOMEM;
663 }
664
665 *curr_deemphasis_mode = fmdev->rx.deemphasis_mode;
666
667 return 0;
668}
669
670/* Enable/Disable RX RDS */
671u32 fm_rx_set_rds_mode(struct fmdev *fmdev, u8 rds_en_dis)
672{
673 u16 payload;
674 u32 ret;
675
676 if (rds_en_dis != FM_RDS_ENABLE && rds_en_dis != FM_RDS_DISABLE) {
677 fmerr("Invalid rds option\n");
678 return -EINVAL;
679 }
680
681 if (rds_en_dis == FM_RDS_ENABLE
682 && fmdev->rx.rds.flag == FM_RDS_DISABLE) {
683 /* Turn on RX RDS and RDS circuit */
684 payload = FM_RX_PWR_SET_FM_AND_RDS_BLK_ON;
685 ret = fmc_send_cmd(fmdev, POWER_SET, REG_WR, &payload,
686 sizeof(payload), NULL, NULL);
687 if (ret < 0)
688 return ret;
689
690 /* Clear and reset RDS FIFO */
691 payload = FM_RX_RDS_FLUSH_FIFO;
692 ret = fmc_send_cmd(fmdev, RDS_CNTRL_SET, REG_WR, &payload,
693 sizeof(payload), NULL, NULL);
694 if (ret < 0)
695 return ret;
696
697 /* Read flags - just to clear any pending interrupts. */
698 ret = fmc_send_cmd(fmdev, FLAG_GET, REG_RD, NULL, 2,
699 NULL, NULL);
700 if (ret < 0)
701 return ret;
702
703 /* Set RDS FIFO threshold value */
704 payload = FM_RX_RDS_FIFO_THRESHOLD;
705 ret = fmc_send_cmd(fmdev, RDS_MEM_SET, REG_WR, &payload,
706 sizeof(payload), NULL, NULL);
707 if (ret < 0)
708 return ret;
709
710 /* Enable RDS interrupt */
711 fmdev->irq_info.mask |= FM_RDS_EVENT;
712 payload = fmdev->irq_info.mask;
713 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
714 sizeof(payload), NULL, NULL);
715 if (ret < 0) {
716 fmdev->irq_info.mask &= ~FM_RDS_EVENT;
717 return ret;
718 }
719
720 /* Update our local flag */
721 fmdev->rx.rds.flag = FM_RDS_ENABLE;
722 } else if (rds_en_dis == FM_RDS_DISABLE
723 && fmdev->rx.rds.flag == FM_RDS_ENABLE) {
724 /* Turn off RX RDS */
725 payload = FM_RX_PWR_SET_FM_ON_RDS_OFF;
726 ret = fmc_send_cmd(fmdev, POWER_SET, REG_WR, &payload,
727 sizeof(payload), NULL, NULL);
728 if (ret < 0)
729 return ret;
730
731 /* Reset RDS pointers */
732 fmdev->rx.rds.last_blk_idx = 0;
733 fmdev->rx.rds.wr_idx = 0;
734 fmdev->rx.rds.rd_idx = 0;
735 fm_rx_reset_station_info(fmdev);
736
737 /* Update RDS local cache */
738 fmdev->irq_info.mask &= ~(FM_RDS_EVENT);
739 fmdev->rx.rds.flag = FM_RDS_DISABLE;
740 }
741
742 return 0;
743}
744
745/* Returns current RX RDS enable/disable status */
746u32 fm_rx_get_rds_mode(struct fmdev *fmdev, u8 *curr_rds_en_dis)
747{
748 if (fmdev->curr_fmmode != FM_MODE_RX)
749 return -EPERM;
750
751 if (curr_rds_en_dis == NULL) {
752 fmerr("Invalid memory\n");
753 return -ENOMEM;
754 }
755
756 *curr_rds_en_dis = fmdev->rx.rds.flag;
757
758 return 0;
759}
760
761/* Sets RDS operation mode (RDS/RDBS) */
762u32 fm_rx_set_rds_system(struct fmdev *fmdev, u8 rds_mode)
763{
764 u16 payload;
765 u32 ret;
766
767 if (fmdev->curr_fmmode != FM_MODE_RX)
768 return -EPERM;
769
770 if (rds_mode != FM_RDS_SYSTEM_RDS && rds_mode != FM_RDS_SYSTEM_RBDS) {
771 fmerr("Invalid rds mode\n");
772 return -EINVAL;
773 }
774 /* Set RDS operation mode */
775 payload = (u16)rds_mode;
776 ret = fmc_send_cmd(fmdev, RDS_SYSTEM_SET, REG_WR, &payload,
777 sizeof(payload), NULL, NULL);
778 if (ret < 0)
779 return ret;
780
781 fmdev->rx.rds_mode = rds_mode;
782
783 return 0;
784}
785
786/* Returns current RDS operation mode */
787u32 fm_rx_get_rds_system(struct fmdev *fmdev, u8 *rds_mode)
788{
789 if (fmdev->curr_fmmode != FM_MODE_RX)
790 return -EPERM;
791
792 if (rds_mode == NULL) {
793 fmerr("Invalid memory\n");
794 return -ENOMEM;
795 }
796
797 *rds_mode = fmdev->rx.rds_mode;
798
799 return 0;
800}
801
802/* Configures Alternate Frequency switch mode */
803u32 fm_rx_set_af_switch(struct fmdev *fmdev, u8 af_mode)
804{
805 u16 payload;
806 u32 ret;
807
808 if (fmdev->curr_fmmode != FM_MODE_RX)
809 return -EPERM;
810
811 if (af_mode != FM_RX_RDS_AF_SWITCH_MODE_ON &&
812 af_mode != FM_RX_RDS_AF_SWITCH_MODE_OFF) {
813 fmerr("Invalid af mode\n");
814 return -EINVAL;
815 }
816 /* Enable/disable low RSSI interrupt based on af_mode */
817 if (af_mode == FM_RX_RDS_AF_SWITCH_MODE_ON)
818 fmdev->irq_info.mask |= FM_LEV_EVENT;
819 else
820 fmdev->irq_info.mask &= ~FM_LEV_EVENT;
821
822 payload = fmdev->irq_info.mask;
823 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
824 sizeof(payload), NULL, NULL);
825 if (ret < 0)
826 return ret;
827
828 fmdev->rx.af_mode = af_mode;
829
830 return 0;
831}
832
833/* Returns Alternate Frequency switch status */
834u32 fm_rx_get_af_switch(struct fmdev *fmdev, u8 *af_mode)
835{
836 if (fmdev->curr_fmmode != FM_MODE_RX)
837 return -EPERM;
838
839 if (af_mode == NULL) {
840 fmerr("Invalid memory\n");
841 return -ENOMEM;
842 }
843
844 *af_mode = fmdev->rx.af_mode;
845
846 return 0;
847}
diff --git a/drivers/media/radio/wl128x/fmdrv_rx.h b/drivers/media/radio/wl128x/fmdrv_rx.h
new file mode 100644
index 000000000000..329e62f6be76
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_rx.h
@@ -0,0 +1,59 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 * FM RX module header.
4 *
5 * Copyright (C) 2011 Texas Instruments
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#ifndef _FMDRV_RX_H
23#define _FMDRV_RX_H
24
25u32 fm_rx_set_freq(struct fmdev *, u32);
26u32 fm_rx_set_mute_mode(struct fmdev *, u8);
27u32 fm_rx_set_stereo_mono(struct fmdev *, u16);
28u32 fm_rx_set_rds_mode(struct fmdev *, u8);
29u32 fm_rx_set_rds_system(struct fmdev *, u8);
30u32 fm_rx_set_volume(struct fmdev *, u16);
31u32 fm_rx_set_rssi_threshold(struct fmdev *, short);
32u32 fm_rx_set_region(struct fmdev *, u8);
33u32 fm_rx_set_rfdepend_softmute(struct fmdev *, u8);
34u32 fm_rx_set_deemphasis_mode(struct fmdev *, u16);
35u32 fm_rx_set_af_switch(struct fmdev *, u8);
36
37void fm_rx_reset_rds_cache(struct fmdev *);
38void fm_rx_reset_station_info(struct fmdev *);
39
40u32 fm_rx_seek(struct fmdev *, u32, u32, u32);
41
42u32 fm_rx_get_rds_mode(struct fmdev *, u8 *);
43u32 fm_rx_get_rds_system(struct fmdev *, u8 *);
44u32 fm_rx_get_mute_mode(struct fmdev *, u8 *);
45u32 fm_rx_get_volume(struct fmdev *, u16 *);
46u32 fm_rx_get_band_freq_range(struct fmdev *,
47 u32 *, u32 *);
48u32 fm_rx_get_stereo_mono(struct fmdev *, u16 *);
49u32 fm_rx_get_rssi_level(struct fmdev *, u16 *);
50u32 fm_rx_get_rssi_threshold(struct fmdev *, short *);
51u32 fm_rx_get_rfdepend_softmute(struct fmdev *, u8 *);
52u32 fm_rx_get_deemph_mode(struct fmdev *, u16 *);
53u32 fm_rx_get_af_switch(struct fmdev *, u8 *);
54void fm_rx_get_region(struct fmdev *, u8 *);
55
56u32 fm_rx_set_chanl_spacing(struct fmdev *, u8);
57u32 fm_rx_get_chanl_spacing(struct fmdev *, u8 *);
58#endif
59
diff --git a/drivers/media/radio/wl128x/fmdrv_tx.c b/drivers/media/radio/wl128x/fmdrv_tx.c
new file mode 100644
index 000000000000..be54068b56a8
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_tx.c
@@ -0,0 +1,425 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 * This sub-module of FM driver implements FM TX functionality.
4 *
5 * Copyright (C) 2011 Texas Instruments
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <linux/delay.h>
23#include "fmdrv.h"
24#include "fmdrv_common.h"
25#include "fmdrv_tx.h"
26
27u32 fm_tx_set_stereo_mono(struct fmdev *fmdev, u16 mode)
28{
29 u16 payload;
30 u32 ret;
31
32 if (fmdev->tx_data.aud_mode == mode)
33 return 0;
34
35 fmdbg("stereo mode: %d\n", mode);
36
37 /* Set Stereo/Mono mode */
38 payload = (1 - mode);
39 ret = fmc_send_cmd(fmdev, MONO_SET, REG_WR, &payload,
40 sizeof(payload), NULL, NULL);
41 if (ret < 0)
42 return ret;
43
44 fmdev->tx_data.aud_mode = mode;
45
46 return ret;
47}
48
49static u32 set_rds_text(struct fmdev *fmdev, u8 *rds_text)
50{
51 u16 payload;
52 u32 ret;
53
54 ret = fmc_send_cmd(fmdev, RDS_DATA_SET, REG_WR, rds_text,
55 strlen(rds_text), NULL, NULL);
56 if (ret < 0)
57 return ret;
58
59 /* Scroll mode */
60 payload = (u16)0x1;
61 ret = fmc_send_cmd(fmdev, DISPLAY_MODE, REG_WR, &payload,
62 sizeof(payload), NULL, NULL);
63 if (ret < 0)
64 return ret;
65
66 return 0;
67}
68
69static u32 set_rds_data_mode(struct fmdev *fmdev, u8 mode)
70{
71 u16 payload;
72 u32 ret;
73
74 /* Setting unique PI TODO: how unique? */
75 payload = (u16)0xcafe;
76 ret = fmc_send_cmd(fmdev, PI_SET, REG_WR, &payload,
77 sizeof(payload), NULL, NULL);
78 if (ret < 0)
79 return ret;
80
81 /* Set decoder id */
82 payload = (u16)0xa;
83 ret = fmc_send_cmd(fmdev, DI_SET, REG_WR, &payload,
84 sizeof(payload), NULL, NULL);
85 if (ret < 0)
86 return ret;
87
88 /* TODO: RDS_MODE_GET? */
89 return 0;
90}
91
92static u32 set_rds_len(struct fmdev *fmdev, u8 type, u16 len)
93{
94 u16 payload;
95 u32 ret;
96
97 len |= type << 8;
98 payload = len;
99 ret = fmc_send_cmd(fmdev, RDS_CONFIG_DATA_SET, REG_WR, &payload,
100 sizeof(payload), NULL, NULL);
101 if (ret < 0)
102 return ret;
103
104 /* TODO: LENGTH_GET? */
105 return 0;
106}
107
108u32 fm_tx_set_rds_mode(struct fmdev *fmdev, u8 rds_en_dis)
109{
110 u16 payload;
111 u32 ret;
112 u8 rds_text[] = "Zoom2\n";
113
114 fmdbg("rds_en_dis:%d(E:%d, D:%d)\n", rds_en_dis,
115 FM_RDS_ENABLE, FM_RDS_DISABLE);
116
117 if (rds_en_dis == FM_RDS_ENABLE) {
118 /* Set RDS length */
119 set_rds_len(fmdev, 0, strlen(rds_text));
120
121 /* Set RDS text */
122 set_rds_text(fmdev, rds_text);
123
124 /* Set RDS mode */
125 set_rds_data_mode(fmdev, 0x0);
126 }
127
128 /* Send command to enable RDS */
129 if (rds_en_dis == FM_RDS_ENABLE)
130 payload = 0x01;
131 else
132 payload = 0x00;
133
134 ret = fmc_send_cmd(fmdev, RDS_DATA_ENB, REG_WR, &payload,
135 sizeof(payload), NULL, NULL);
136 if (ret < 0)
137 return ret;
138
139 if (rds_en_dis == FM_RDS_ENABLE) {
140 /* Set RDS length */
141 set_rds_len(fmdev, 0, strlen(rds_text));
142
143 /* Set RDS text */
144 set_rds_text(fmdev, rds_text);
145 }
146 fmdev->tx_data.rds.flag = rds_en_dis;
147
148 return 0;
149}
150
151u32 fm_tx_set_radio_text(struct fmdev *fmdev, u8 *rds_text, u8 rds_type)
152{
153 u16 payload;
154 u32 ret;
155
156 if (fmdev->curr_fmmode != FM_MODE_TX)
157 return -EPERM;
158
159 fm_tx_set_rds_mode(fmdev, 0);
160
161 /* Set RDS length */
162 set_rds_len(fmdev, rds_type, strlen(rds_text));
163
164 /* Set RDS text */
165 set_rds_text(fmdev, rds_text);
166
167 /* Set RDS mode */
168 set_rds_data_mode(fmdev, 0x0);
169
170 payload = 1;
171 ret = fmc_send_cmd(fmdev, RDS_DATA_ENB, REG_WR, &payload,
172 sizeof(payload), NULL, NULL);
173 if (ret < 0)
174 return ret;
175
176 return 0;
177}
178
179u32 fm_tx_set_af(struct fmdev *fmdev, u32 af)
180{
181 u16 payload;
182 u32 ret;
183
184 if (fmdev->curr_fmmode != FM_MODE_TX)
185 return -EPERM;
186
187 fmdbg("AF: %d\n", af);
188
189 af = (af - 87500) / 100;
190 payload = (u16)af;
191 ret = fmc_send_cmd(fmdev, TA_SET, REG_WR, &payload,
192 sizeof(payload), NULL, NULL);
193 if (ret < 0)
194 return ret;
195
196 return 0;
197}
198
199u32 fm_tx_set_region(struct fmdev *fmdev, u8 region)
200{
201 u16 payload;
202 u32 ret;
203
204 if (region != FM_BAND_EUROPE_US && region != FM_BAND_JAPAN) {
205 fmerr("Invalid band\n");
206 return -EINVAL;
207 }
208
209 /* Send command to set the band */
210 payload = (u16)region;
211 ret = fmc_send_cmd(fmdev, TX_BAND_SET, REG_WR, &payload,
212 sizeof(payload), NULL, NULL);
213 if (ret < 0)
214 return ret;
215
216 return 0;
217}
218
219u32 fm_tx_set_mute_mode(struct fmdev *fmdev, u8 mute_mode_toset)
220{
221 u16 payload;
222 u32 ret;
223
224 fmdbg("tx: mute mode %d\n", mute_mode_toset);
225
226 payload = mute_mode_toset;
227 ret = fmc_send_cmd(fmdev, MUTE, REG_WR, &payload,
228 sizeof(payload), NULL, NULL);
229 if (ret < 0)
230 return ret;
231
232 return 0;
233}
234
235/* Set TX Audio I/O */
236static u32 set_audio_io(struct fmdev *fmdev)
237{
238 struct fmtx_data *tx = &fmdev->tx_data;
239 u16 payload;
240 u32 ret;
241
242 /* Set Audio I/O Enable */
243 payload = tx->audio_io;
244 ret = fmc_send_cmd(fmdev, AUDIO_IO_SET, REG_WR, &payload,
245 sizeof(payload), NULL, NULL);
246 if (ret < 0)
247 return ret;
248
249 /* TODO: is audio set? */
250 return 0;
251}
252
253/* Start TX Transmission */
254static u32 enable_xmit(struct fmdev *fmdev, u8 new_xmit_state)
255{
256 struct fmtx_data *tx = &fmdev->tx_data;
257 unsigned long timeleft;
258 u16 payload;
259 u32 ret;
260
261 /* Enable POWER_ENB interrupts */
262 payload = FM_POW_ENB_EVENT;
263 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
264 sizeof(payload), NULL, NULL);
265 if (ret < 0)
266 return ret;
267
268 /* Set Power Enable */
269 payload = new_xmit_state;
270 ret = fmc_send_cmd(fmdev, POWER_ENB_SET, REG_WR, &payload,
271 sizeof(payload), NULL, NULL);
272 if (ret < 0)
273 return ret;
274
275 /* Wait for Power Enabled */
276 init_completion(&fmdev->maintask_comp);
277 timeleft = wait_for_completion_timeout(&fmdev->maintask_comp,
278 FM_DRV_TX_TIMEOUT);
279 if (!timeleft) {
280 fmerr("Timeout(%d sec),didn't get tune ended interrupt\n",
281 jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000);
282 return -ETIMEDOUT;
283 }
284
285 set_bit(FM_CORE_TX_XMITING, &fmdev->flag);
286 tx->xmit_state = new_xmit_state;
287
288 return 0;
289}
290
291/* Set TX power level */
292u32 fm_tx_set_pwr_lvl(struct fmdev *fmdev, u8 new_pwr_lvl)
293{
294 u16 payload;
295 struct fmtx_data *tx = &fmdev->tx_data;
296 u32 ret;
297
298 if (fmdev->curr_fmmode != FM_MODE_TX)
299 return -EPERM;
300 fmdbg("tx: pwr_level_to_set %ld\n", (long int)new_pwr_lvl);
301
302 /* If the core isn't ready update global variable */
303 if (!test_bit(FM_CORE_READY, &fmdev->flag)) {
304 tx->pwr_lvl = new_pwr_lvl;
305 return 0;
306 }
307
308 /* Set power level: Application will specify power level value in
309 * units of dB/uV, whereas range and step are specific to FM chip.
310 * For TI's WL chips, convert application specified power level value
311 * to chip specific value by subtracting 122 from it. Refer to TI FM
312 * data sheet for details.
313 * */
314
315 payload = (FM_PWR_LVL_HIGH - new_pwr_lvl);
316 ret = fmc_send_cmd(fmdev, POWER_LEV_SET, REG_WR, &payload,
317 sizeof(payload), NULL, NULL);
318 if (ret < 0)
319 return ret;
320
321 /* TODO: is the power level set? */
322 tx->pwr_lvl = new_pwr_lvl;
323
324 return 0;
325}
326
327/*
328 * Sets FM TX pre-emphasis filter value (OFF, 50us, or 75us)
329 * Convert V4L2 specified filter values to chip specific filter values.
330 */
331u32 fm_tx_set_preemph_filter(struct fmdev *fmdev, u32 preemphasis)
332{
333 struct fmtx_data *tx = &fmdev->tx_data;
334 u16 payload;
335 u32 ret;
336
337 if (fmdev->curr_fmmode != FM_MODE_TX)
338 return -EPERM;
339
340 switch (preemphasis) {
341 case V4L2_PREEMPHASIS_DISABLED:
342 payload = FM_TX_PREEMPH_OFF;
343 break;
344 case V4L2_PREEMPHASIS_50_uS:
345 payload = FM_TX_PREEMPH_50US;
346 break;
347 case V4L2_PREEMPHASIS_75_uS:
348 payload = FM_TX_PREEMPH_75US;
349 break;
350 }
351
352 ret = fmc_send_cmd(fmdev, PREMPH_SET, REG_WR, &payload,
353 sizeof(payload), NULL, NULL);
354 if (ret < 0)
355 return ret;
356
357 tx->preemph = payload;
358
359 return ret;
360}
361
362/* Get the TX tuning capacitor value.*/
363u32 fm_tx_get_tune_cap_val(struct fmdev *fmdev)
364{
365 u16 curr_val;
366 u32 ret, resp_len;
367
368 if (fmdev->curr_fmmode != FM_MODE_TX)
369 return -EPERM;
370
371 ret = fmc_send_cmd(fmdev, READ_FMANT_TUNE_VALUE, REG_RD,
372 NULL, sizeof(curr_val), &curr_val, &resp_len);
373 if (ret < 0)
374 return ret;
375
376 curr_val = be16_to_cpu(curr_val);
377
378 return curr_val;
379}
380
381/* Set TX Frequency */
382u32 fm_tx_set_freq(struct fmdev *fmdev, u32 freq_to_set)
383{
384 struct fmtx_data *tx = &fmdev->tx_data;
385 u16 payload, chanl_index;
386 u32 ret;
387
388 if (test_bit(FM_CORE_TX_XMITING, &fmdev->flag)) {
389 enable_xmit(fmdev, 0);
390 clear_bit(FM_CORE_TX_XMITING, &fmdev->flag);
391 }
392
393 /* Enable FR, BL interrupts */
394 payload = (FM_FR_EVENT | FM_BL_EVENT);
395 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
396 sizeof(payload), NULL, NULL);
397 if (ret < 0)
398 return ret;
399
400 tx->tx_frq = (unsigned long)freq_to_set;
401 fmdbg("tx: freq_to_set %ld\n", (long int)tx->tx_frq);
402
403 chanl_index = freq_to_set / 10;
404
405 /* Set current tuner channel */
406 payload = chanl_index;
407 ret = fmc_send_cmd(fmdev, CHANL_SET, REG_WR, &payload,
408 sizeof(payload), NULL, NULL);
409 if (ret < 0)
410 return ret;
411
412 fm_tx_set_pwr_lvl(fmdev, tx->pwr_lvl);
413 fm_tx_set_preemph_filter(fmdev, tx->preemph);
414
415 tx->audio_io = 0x01; /* I2S */
416 set_audio_io(fmdev);
417
418 enable_xmit(fmdev, 0x01); /* Enable transmission */
419
420 tx->aud_mode = FM_STEREO_MODE;
421 tx->rds.flag = FM_RDS_DISABLE;
422
423 return 0;
424}
425
diff --git a/drivers/media/radio/wl128x/fmdrv_tx.h b/drivers/media/radio/wl128x/fmdrv_tx.h
new file mode 100644
index 000000000000..e393a2bdd49e
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_tx.h
@@ -0,0 +1,37 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 * FM TX module header.
4 *
5 * Copyright (C) 2011 Texas Instruments
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#ifndef _FMDRV_TX_H
23#define _FMDRV_TX_H
24
25u32 fm_tx_set_freq(struct fmdev *, u32);
26u32 fm_tx_set_pwr_lvl(struct fmdev *, u8);
27u32 fm_tx_set_region(struct fmdev *, u8);
28u32 fm_tx_set_mute_mode(struct fmdev *, u8);
29u32 fm_tx_set_stereo_mono(struct fmdev *, u16);
30u32 fm_tx_set_rds_mode(struct fmdev *, u8);
31u32 fm_tx_set_radio_text(struct fmdev *, u8 *, u8);
32u32 fm_tx_set_af(struct fmdev *, u32);
33u32 fm_tx_set_preemph_filter(struct fmdev *, u32);
34u32 fm_tx_get_tune_cap_val(struct fmdev *);
35
36#endif
37
diff --git a/drivers/media/radio/wl128x/fmdrv_v4l2.c b/drivers/media/radio/wl128x/fmdrv_v4l2.c
new file mode 100644
index 000000000000..d50e5ac75ab6
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_v4l2.c
@@ -0,0 +1,580 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 * This file provides interfaces to V4L2 subsystem.
4 *
5 * This module registers with V4L2 subsystem as Radio
6 * data system interface (/dev/radio). During the registration,
7 * it will expose two set of function pointers.
8 *
9 * 1) File operation related API (open, close, read, write, poll...etc).
10 * 2) Set of V4L2 IOCTL complaint API.
11 *
12 * Copyright (C) 2011 Texas Instruments
13 * Author: Raja Mani <raja_mani@ti.com>
14 * Author: Manjunatha Halli <manjunatha_halli@ti.com>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2 as
18 * published by the Free Software Foundation.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 *
29 */
30
31#include "fmdrv.h"
32#include "fmdrv_v4l2.h"
33#include "fmdrv_common.h"
34#include "fmdrv_rx.h"
35#include "fmdrv_tx.h"
36
37static struct video_device *gradio_dev;
38static u8 radio_disconnected;
39
40/* -- V4L2 RADIO (/dev/radioX) device file operation interfaces --- */
41
42/* Read RX RDS data */
43static ssize_t fm_v4l2_fops_read(struct file *file, char __user * buf,
44 size_t count, loff_t *ppos)
45{
46 u8 rds_mode;
47 int ret;
48 struct fmdev *fmdev;
49
50 fmdev = video_drvdata(file);
51
52 if (!radio_disconnected) {
53 fmerr("FM device is already disconnected\n");
54 return -EIO;
55 }
56
57 /* Turn on RDS mode , if it is disabled */
58 ret = fm_rx_get_rds_mode(fmdev, &rds_mode);
59 if (ret < 0) {
60 fmerr("Unable to read current rds mode\n");
61 return ret;
62 }
63
64 if (rds_mode == FM_RDS_DISABLE) {
65 ret = fmc_set_rds_mode(fmdev, FM_RDS_ENABLE);
66 if (ret < 0) {
67 fmerr("Failed to enable rds mode\n");
68 return ret;
69 }
70 }
71
72 /* Copy RDS data from internal buffer to user buffer */
73 return fmc_transfer_rds_from_internal_buff(fmdev, file, buf, count);
74}
75
76/* Write TX RDS data */
77static ssize_t fm_v4l2_fops_write(struct file *file, const char __user * buf,
78 size_t count, loff_t *ppos)
79{
80 struct tx_rds rds;
81 int ret;
82 struct fmdev *fmdev;
83
84 ret = copy_from_user(&rds, buf, sizeof(rds));
85 fmdbg("(%d)type: %d, text %s, af %d\n",
86 ret, rds.text_type, rds.text, rds.af_freq);
87
88 fmdev = video_drvdata(file);
89 fm_tx_set_radio_text(fmdev, rds.text, rds.text_type);
90 fm_tx_set_af(fmdev, rds.af_freq);
91
92 return 0;
93}
94
95static u32 fm_v4l2_fops_poll(struct file *file, struct poll_table_struct *pts)
96{
97 int ret;
98 struct fmdev *fmdev;
99
100 fmdev = video_drvdata(file);
101 ret = fmc_is_rds_data_available(fmdev, file, pts);
102 if (ret < 0)
103 return POLLIN | POLLRDNORM;
104
105 return 0;
106}
107
108/*
109 * Handle open request for "/dev/radioX" device.
110 * Start with FM RX mode as default.
111 */
112static int fm_v4l2_fops_open(struct file *file)
113{
114 int ret;
115 struct fmdev *fmdev = NULL;
116
117 /* Don't allow multiple open */
118 if (radio_disconnected) {
119 fmerr("FM device is already opened\n");
120 return -EBUSY;
121 }
122
123 fmdev = video_drvdata(file);
124
125 ret = fmc_prepare(fmdev);
126 if (ret < 0) {
127 fmerr("Unable to prepare FM CORE\n");
128 return ret;
129 }
130
131 fmdbg("Load FM RX firmware..\n");
132
133 ret = fmc_set_mode(fmdev, FM_MODE_RX);
134 if (ret < 0) {
135 fmerr("Unable to load FM RX firmware\n");
136 return ret;
137 }
138 radio_disconnected = 1;
139
140 return ret;
141}
142
143static int fm_v4l2_fops_release(struct file *file)
144{
145 int ret;
146 struct fmdev *fmdev;
147
148 fmdev = video_drvdata(file);
149 if (!radio_disconnected) {
150 fmdbg("FM device is already closed\n");
151 return 0;
152 }
153
154 ret = fmc_set_mode(fmdev, FM_MODE_OFF);
155 if (ret < 0) {
156 fmerr("Unable to turn off the chip\n");
157 return ret;
158 }
159
160 ret = fmc_release(fmdev);
161 if (ret < 0) {
162 fmerr("FM CORE release failed\n");
163 return ret;
164 }
165 radio_disconnected = 0;
166
167 return ret;
168}
169
170/* V4L2 RADIO (/dev/radioX) device IOCTL interfaces */
171static int fm_v4l2_vidioc_querycap(struct file *file, void *priv,
172 struct v4l2_capability *capability)
173{
174 strlcpy(capability->driver, FM_DRV_NAME, sizeof(capability->driver));
175 strlcpy(capability->card, FM_DRV_CARD_SHORT_NAME,
176 sizeof(capability->card));
177 sprintf(capability->bus_info, "UART");
178 capability->version = FM_DRV_RADIO_VERSION;
179 capability->capabilities = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_TUNER |
180 V4L2_CAP_RADIO | V4L2_CAP_MODULATOR |
181 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE |
182 V4L2_CAP_RDS_CAPTURE;
183
184 return 0;
185}
186
187static int fm_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
188{
189 struct fmdev *fmdev = container_of(ctrl->handler,
190 struct fmdev, ctrl_handler);
191
192 switch (ctrl->id) {
193 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
194 ctrl->val = fm_tx_get_tune_cap_val(fmdev);
195 break;
196 default:
197 fmwarn("%s: Unknown IOCTL: %d\n", __func__, ctrl->id);
198 break;
199 }
200
201 return 0;
202}
203
204static int fm_v4l2_s_ctrl(struct v4l2_ctrl *ctrl)
205{
206 struct fmdev *fmdev = container_of(ctrl->handler,
207 struct fmdev, ctrl_handler);
208
209 switch (ctrl->id) {
210 case V4L2_CID_AUDIO_VOLUME: /* set volume */
211 return fm_rx_set_volume(fmdev, (u16)ctrl->val);
212
213 case V4L2_CID_AUDIO_MUTE: /* set mute */
214 return fmc_set_mute_mode(fmdev, (u8)ctrl->val);
215
216 case V4L2_CID_TUNE_POWER_LEVEL:
217 /* set TX power level - ext control */
218 return fm_tx_set_pwr_lvl(fmdev, (u8)ctrl->val);
219
220 case V4L2_CID_TUNE_PREEMPHASIS:
221 return fm_tx_set_preemph_filter(fmdev, (u8) ctrl->val);
222
223 default:
224 return -EINVAL;
225 }
226}
227
228static int fm_v4l2_vidioc_g_audio(struct file *file, void *priv,
229 struct v4l2_audio *audio)
230{
231 memset(audio, 0, sizeof(*audio));
232 strcpy(audio->name, "Radio");
233 audio->capability = V4L2_AUDCAP_STEREO;
234
235 return 0;
236}
237
238static int fm_v4l2_vidioc_s_audio(struct file *file, void *priv,
239 struct v4l2_audio *audio)
240{
241 if (audio->index != 0)
242 return -EINVAL;
243
244 return 0;
245}
246
247/* Get tuner attributes. If current mode is NOT RX, return error */
248static int fm_v4l2_vidioc_g_tuner(struct file *file, void *priv,
249 struct v4l2_tuner *tuner)
250{
251 struct fmdev *fmdev = video_drvdata(file);
252 u32 bottom_freq;
253 u32 top_freq;
254 u16 stereo_mono_mode;
255 u16 rssilvl;
256 int ret;
257
258 if (tuner->index != 0)
259 return -EINVAL;
260
261 if (fmdev->curr_fmmode != FM_MODE_RX)
262 return -EPERM;
263
264 ret = fm_rx_get_band_freq_range(fmdev, &bottom_freq, &top_freq);
265 if (ret != 0)
266 return ret;
267
268 ret = fm_rx_get_stereo_mono(fmdev, &stereo_mono_mode);
269 if (ret != 0)
270 return ret;
271
272 ret = fm_rx_get_rssi_level(fmdev, &rssilvl);
273 if (ret != 0)
274 return ret;
275
276 strcpy(tuner->name, "FM");
277 tuner->type = V4L2_TUNER_RADIO;
278 /* Store rangelow and rangehigh freq in unit of 62.5 Hz */
279 tuner->rangelow = bottom_freq * 16;
280 tuner->rangehigh = top_freq * 16;
281 tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO |
282 ((fmdev->rx.rds.flag == FM_RDS_ENABLE) ? V4L2_TUNER_SUB_RDS : 0);
283 tuner->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS |
284 V4L2_TUNER_CAP_LOW;
285 tuner->audmode = (stereo_mono_mode ?
286 V4L2_TUNER_MODE_MONO : V4L2_TUNER_MODE_STEREO);
287
288 /*
289 * Actual rssi value lies in between -128 to +127.
290 * Convert this range from 0 to 255 by adding +128
291 */
292 rssilvl += 128;
293
294 /*
295 * Return signal strength value should be within 0 to 65535.
296 * Find out correct signal radio by multiplying (65535/255) = 257
297 */
298 tuner->signal = rssilvl * 257;
299 tuner->afc = 0;
300
301 return ret;
302}
303
304/*
305 * Set tuner attributes. If current mode is NOT RX, set to RX.
306 * Currently, we set only audio mode (mono/stereo) and RDS state (on/off).
307 * Should we set other tuner attributes, too?
308 */
309static int fm_v4l2_vidioc_s_tuner(struct file *file, void *priv,
310 struct v4l2_tuner *tuner)
311{
312 struct fmdev *fmdev = video_drvdata(file);
313 u16 aud_mode;
314 u8 rds_mode;
315 int ret;
316
317 if (tuner->index != 0)
318 return -EINVAL;
319
320 aud_mode = (tuner->audmode == V4L2_TUNER_MODE_STEREO) ?
321 FM_STEREO_MODE : FM_MONO_MODE;
322 rds_mode = (tuner->rxsubchans & V4L2_TUNER_SUB_RDS) ?
323 FM_RDS_ENABLE : FM_RDS_DISABLE;
324
325 if (fmdev->curr_fmmode != FM_MODE_RX) {
326 ret = fmc_set_mode(fmdev, FM_MODE_RX);
327 if (ret < 0) {
328 fmerr("Failed to set RX mode\n");
329 return ret;
330 }
331 }
332
333 ret = fmc_set_stereo_mono(fmdev, aud_mode);
334 if (ret < 0) {
335 fmerr("Failed to set RX stereo/mono mode\n");
336 return ret;
337 }
338
339 ret = fmc_set_rds_mode(fmdev, rds_mode);
340 if (ret < 0)
341 fmerr("Failed to set RX RDS mode\n");
342
343 return ret;
344}
345
346/* Get tuner or modulator radio frequency */
347static int fm_v4l2_vidioc_g_freq(struct file *file, void *priv,
348 struct v4l2_frequency *freq)
349{
350 struct fmdev *fmdev = video_drvdata(file);
351 int ret;
352
353 ret = fmc_get_freq(fmdev, &freq->frequency);
354 if (ret < 0) {
355 fmerr("Failed to get frequency\n");
356 return ret;
357 }
358
359 /* Frequency unit of 62.5 Hz*/
360 freq->frequency = (u32) freq->frequency * 16;
361
362 return 0;
363}
364
365/* Set tuner or modulator radio frequency */
366static int fm_v4l2_vidioc_s_freq(struct file *file, void *priv,
367 struct v4l2_frequency *freq)
368{
369 struct fmdev *fmdev = video_drvdata(file);
370
371 /*
372 * As V4L2_TUNER_CAP_LOW is set 1 user sends the frequency
373 * in units of 62.5 Hz.
374 */
375 freq->frequency = (u32)(freq->frequency / 16);
376
377 return fmc_set_freq(fmdev, freq->frequency);
378}
379
380/* Set hardware frequency seek. If current mode is NOT RX, set it RX. */
381static int fm_v4l2_vidioc_s_hw_freq_seek(struct file *file, void *priv,
382 struct v4l2_hw_freq_seek *seek)
383{
384 struct fmdev *fmdev = video_drvdata(file);
385 int ret;
386
387 if (fmdev->curr_fmmode != FM_MODE_RX) {
388 ret = fmc_set_mode(fmdev, FM_MODE_RX);
389 if (ret != 0) {
390 fmerr("Failed to set RX mode\n");
391 return ret;
392 }
393 }
394
395 ret = fm_rx_seek(fmdev, seek->seek_upward, seek->wrap_around,
396 seek->spacing);
397 if (ret < 0)
398 fmerr("RX seek failed - %d\n", ret);
399
400 return ret;
401}
402/* Get modulator attributes. If mode is not TX, return no attributes. */
403static int fm_v4l2_vidioc_g_modulator(struct file *file, void *priv,
404 struct v4l2_modulator *mod)
405{
406 struct fmdev *fmdev = video_drvdata(file);;
407
408 if (mod->index != 0)
409 return -EINVAL;
410
411 if (fmdev->curr_fmmode != FM_MODE_TX)
412 return -EPERM;
413
414 mod->txsubchans = ((fmdev->tx_data.aud_mode == FM_STEREO_MODE) ?
415 V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO) |
416 ((fmdev->tx_data.rds.flag == FM_RDS_ENABLE) ?
417 V4L2_TUNER_SUB_RDS : 0);
418
419 mod->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS |
420 V4L2_TUNER_CAP_LOW;
421
422 return 0;
423}
424
425/* Set modulator attributes. If mode is not TX, set to TX. */
426static int fm_v4l2_vidioc_s_modulator(struct file *file, void *priv,
427 struct v4l2_modulator *mod)
428{
429 struct fmdev *fmdev = video_drvdata(file);
430 u8 rds_mode;
431 u16 aud_mode;
432 int ret;
433
434 if (mod->index != 0)
435 return -EINVAL;
436
437 if (fmdev->curr_fmmode != FM_MODE_TX) {
438 ret = fmc_set_mode(fmdev, FM_MODE_TX);
439 if (ret != 0) {
440 fmerr("Failed to set TX mode\n");
441 return ret;
442 }
443 }
444
445 aud_mode = (mod->txsubchans & V4L2_TUNER_SUB_STEREO) ?
446 FM_STEREO_MODE : FM_MONO_MODE;
447 rds_mode = (mod->txsubchans & V4L2_TUNER_SUB_RDS) ?
448 FM_RDS_ENABLE : FM_RDS_DISABLE;
449 ret = fm_tx_set_stereo_mono(fmdev, aud_mode);
450 if (ret < 0) {
451 fmerr("Failed to set mono/stereo mode for TX\n");
452 return ret;
453 }
454 ret = fm_tx_set_rds_mode(fmdev, rds_mode);
455 if (ret < 0)
456 fmerr("Failed to set rds mode for TX\n");
457
458 return ret;
459}
460
461static const struct v4l2_file_operations fm_drv_fops = {
462 .owner = THIS_MODULE,
463 .read = fm_v4l2_fops_read,
464 .write = fm_v4l2_fops_write,
465 .poll = fm_v4l2_fops_poll,
466 .unlocked_ioctl = video_ioctl2,
467 .open = fm_v4l2_fops_open,
468 .release = fm_v4l2_fops_release,
469};
470
471static const struct v4l2_ctrl_ops fm_ctrl_ops = {
472 .s_ctrl = fm_v4l2_s_ctrl,
473 .g_volatile_ctrl = fm_g_volatile_ctrl,
474};
475static const struct v4l2_ioctl_ops fm_drv_ioctl_ops = {
476 .vidioc_querycap = fm_v4l2_vidioc_querycap,
477 .vidioc_g_audio = fm_v4l2_vidioc_g_audio,
478 .vidioc_s_audio = fm_v4l2_vidioc_s_audio,
479 .vidioc_g_tuner = fm_v4l2_vidioc_g_tuner,
480 .vidioc_s_tuner = fm_v4l2_vidioc_s_tuner,
481 .vidioc_g_frequency = fm_v4l2_vidioc_g_freq,
482 .vidioc_s_frequency = fm_v4l2_vidioc_s_freq,
483 .vidioc_s_hw_freq_seek = fm_v4l2_vidioc_s_hw_freq_seek,
484 .vidioc_g_modulator = fm_v4l2_vidioc_g_modulator,
485 .vidioc_s_modulator = fm_v4l2_vidioc_s_modulator
486};
487
488/* V4L2 RADIO device parent structure */
489static struct video_device fm_viddev_template = {
490 .fops = &fm_drv_fops,
491 .ioctl_ops = &fm_drv_ioctl_ops,
492 .name = FM_DRV_NAME,
493 .release = video_device_release,
494};
495
496int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr)
497{
498 struct v4l2_ctrl *ctrl;
499 int ret;
500
501 /* Init mutex for core locking */
502 mutex_init(&fmdev->mutex);
503
504 /* Allocate new video device */
505 gradio_dev = video_device_alloc();
506 if (NULL == gradio_dev) {
507 fmerr("Can't allocate video device\n");
508 return -ENOMEM;
509 }
510
511 /* Setup FM driver's V4L2 properties */
512 memcpy(gradio_dev, &fm_viddev_template, sizeof(fm_viddev_template));
513
514 video_set_drvdata(gradio_dev, fmdev);
515
516 gradio_dev->lock = &fmdev->mutex;
517
518 /* Register with V4L2 subsystem as RADIO device */
519 if (video_register_device(gradio_dev, VFL_TYPE_RADIO, radio_nr)) {
520 video_device_release(gradio_dev);
521 fmerr("Could not register video device\n");
522 return -ENOMEM;
523 }
524
525 fmdev->radio_dev = gradio_dev;
526
527 /* Register to v4l2 ctrl handler framework */
528 fmdev->radio_dev->ctrl_handler = &fmdev->ctrl_handler;
529
530 ret = v4l2_ctrl_handler_init(&fmdev->ctrl_handler, 5);
531 if (ret < 0) {
532 fmerr("(fmdev): Can't init ctrl handler\n");
533 v4l2_ctrl_handler_free(&fmdev->ctrl_handler);
534 return -EBUSY;
535 }
536
537 /*
538 * Following controls are handled by V4L2 control framework.
539 * Added in ascending ID order.
540 */
541 v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops,
542 V4L2_CID_AUDIO_VOLUME, FM_RX_VOLUME_MIN,
543 FM_RX_VOLUME_MAX, 1, FM_RX_VOLUME_MAX);
544
545 v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops,
546 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
547
548 v4l2_ctrl_new_std_menu(&fmdev->ctrl_handler, &fm_ctrl_ops,
549 V4L2_CID_TUNE_PREEMPHASIS, V4L2_PREEMPHASIS_75_uS,
550 0, V4L2_PREEMPHASIS_75_uS);
551
552 v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops,
553 V4L2_CID_TUNE_POWER_LEVEL, FM_PWR_LVL_LOW,
554 FM_PWR_LVL_HIGH, 1, FM_PWR_LVL_HIGH);
555
556 ctrl = v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops,
557 V4L2_CID_TUNE_ANTENNA_CAPACITOR, 0,
558 255, 1, 255);
559
560 if (ctrl)
561 ctrl->is_volatile = 1;
562
563 return 0;
564}
565
566void *fm_v4l2_deinit_video_device(void)
567{
568 struct fmdev *fmdev;
569
570
571 fmdev = video_get_drvdata(gradio_dev);
572
573 /* Unregister to v4l2 ctrl handler framework*/
574 v4l2_ctrl_handler_free(&fmdev->ctrl_handler);
575
576 /* Unregister RADIO device from V4L2 subsystem */
577 video_unregister_device(gradio_dev);
578
579 return fmdev;
580}
diff --git a/drivers/media/radio/wl128x/fmdrv_v4l2.h b/drivers/media/radio/wl128x/fmdrv_v4l2.h
new file mode 100644
index 000000000000..0ba79d745e2f
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_v4l2.h
@@ -0,0 +1,33 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 *
4 * FM V4L2 module header.
5 *
6 * Copyright (C) 2011 Texas Instruments
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#ifndef _FMDRV_V4L2_H
24#define _FMDRV_V4L2_H
25
26#include <media/v4l2-ioctl.h>
27#include <media/v4l2-common.h>
28#include <media/v4l2-ctrls.h>
29
30int fm_v4l2_init_video_device(struct fmdev *, int);
31void *fm_v4l2_deinit_video_device(void);
32
33#endif