diff options
author | Alexey Klimov <klimov.linux@gmail.com> | 2009-02-05 06:56:07 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:42:40 -0400 |
commit | 1bb16d7156d7d6b7e357de561bf965fd65545bb0 (patch) | |
tree | 9c5284dfc4d4831218bb390c0c3a45f10b5280d0 /drivers/media/radio | |
parent | f7c1a3809bbcf45bf801cef1954f9500140697b7 (diff) |
V4L/DVB (10460): radio-mr800: add stereo support
Patch introduces new amradio_set_stereo function.
Driver calls this func to make stereo radio reception.
Corrects checking of returned value after usb_bulk_msg.
Signed-off-by: Alexey Klimov <klimov.linux@gmail.com>
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/radio')
-rw-r--r-- | drivers/media/radio/radio-mr800.c | 81 |
1 files changed, 79 insertions, 2 deletions
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 0374c6ada43f..25ccf21c469e 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c | |||
@@ -93,11 +93,16 @@ devices, that would be 76 and 91. */ | |||
93 | */ | 93 | */ |
94 | #define AMRADIO_SET_FREQ 0xa4 | 94 | #define AMRADIO_SET_FREQ 0xa4 |
95 | #define AMRADIO_SET_MUTE 0xab | 95 | #define AMRADIO_SET_MUTE 0xab |
96 | #define AMRADIO_SET_MONO 0xae | ||
96 | 97 | ||
97 | /* Comfortable defines for amradio_set_mute */ | 98 | /* Comfortable defines for amradio_set_mute */ |
98 | #define AMRADIO_START 0x00 | 99 | #define AMRADIO_START 0x00 |
99 | #define AMRADIO_STOP 0x01 | 100 | #define AMRADIO_STOP 0x01 |
100 | 101 | ||
102 | /* Comfortable defines for amradio_set_stereo */ | ||
103 | #define WANT_STEREO 0x00 | ||
104 | #define WANT_MONO 0x01 | ||
105 | |||
101 | /* module parameter */ | 106 | /* module parameter */ |
102 | static int radio_nr = -1; | 107 | static int radio_nr = -1; |
103 | module_param(radio_nr, int, 0); | 108 | module_param(radio_nr, int, 0); |
@@ -263,13 +268,49 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) | |||
263 | return retval; | 268 | return retval; |
264 | } | 269 | } |
265 | 270 | ||
266 | radio->stereo = 0; | 271 | mutex_unlock(&radio->lock); |
272 | |||
273 | return retval; | ||
274 | } | ||
275 | |||
276 | static int amradio_set_stereo(struct amradio_device *radio, char argument) | ||
277 | { | ||
278 | int retval; | ||
279 | int size; | ||
280 | |||
281 | /* safety check */ | ||
282 | if (radio->removed) | ||
283 | return -EIO; | ||
284 | |||
285 | mutex_lock(&radio->lock); | ||
286 | |||
287 | radio->buffer[0] = 0x00; | ||
288 | radio->buffer[1] = 0x55; | ||
289 | radio->buffer[2] = 0xaa; | ||
290 | radio->buffer[3] = 0x00; | ||
291 | radio->buffer[4] = AMRADIO_SET_MONO; | ||
292 | radio->buffer[5] = argument; | ||
293 | radio->buffer[6] = 0x00; | ||
294 | radio->buffer[7] = 0x00; | ||
295 | |||
296 | retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), | ||
297 | (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); | ||
298 | |||
299 | if (retval < 0 || size != BUFFER_LENGTH) { | ||
300 | radio->stereo = -1; | ||
301 | mutex_unlock(&radio->lock); | ||
302 | return retval; | ||
303 | } | ||
304 | |||
305 | radio->stereo = 1; | ||
267 | 306 | ||
268 | mutex_unlock(&radio->lock); | 307 | mutex_unlock(&radio->lock); |
269 | 308 | ||
270 | return retval; | 309 | return retval; |
271 | } | 310 | } |
272 | 311 | ||
312 | |||
313 | |||
273 | /* USB subsystem interface begins here */ | 314 | /* USB subsystem interface begins here */ |
274 | 315 | ||
275 | /* handle unplugging of the device, release data structures | 316 | /* handle unplugging of the device, release data structures |
@@ -307,6 +348,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, | |||
307 | struct v4l2_tuner *v) | 348 | struct v4l2_tuner *v) |
308 | { | 349 | { |
309 | struct amradio_device *radio = video_get_drvdata(video_devdata(file)); | 350 | struct amradio_device *radio = video_get_drvdata(video_devdata(file)); |
351 | int retval; | ||
310 | 352 | ||
311 | /* safety check */ | 353 | /* safety check */ |
312 | if (radio->removed) | 354 | if (radio->removed) |
@@ -318,7 +360,16 @@ static int vidioc_g_tuner(struct file *file, void *priv, | |||
318 | /* TODO: Add function which look is signal stereo or not | 360 | /* TODO: Add function which look is signal stereo or not |
319 | * amradio_getstat(radio); | 361 | * amradio_getstat(radio); |
320 | */ | 362 | */ |
321 | radio->stereo = -1; | 363 | |
364 | /* we call amradio_set_stereo to set radio->stereo | ||
365 | * Honestly, amradio_getstat should cover this in future and | ||
366 | * amradio_set_stereo shouldn't be here | ||
367 | */ | ||
368 | retval = amradio_set_stereo(radio, WANT_STEREO); | ||
369 | if (retval < 0) | ||
370 | amradio_dev_warn(&radio->videodev->dev, | ||
371 | "set stereo failed\n"); | ||
372 | |||
322 | strcpy(v->name, "FM"); | 373 | strcpy(v->name, "FM"); |
323 | v->type = V4L2_TUNER_RADIO; | 374 | v->type = V4L2_TUNER_RADIO; |
324 | v->rangelow = FREQ_MIN * FREQ_MUL; | 375 | v->rangelow = FREQ_MIN * FREQ_MUL; |
@@ -339,6 +390,7 @@ static int vidioc_s_tuner(struct file *file, void *priv, | |||
339 | struct v4l2_tuner *v) | 390 | struct v4l2_tuner *v) |
340 | { | 391 | { |
341 | struct amradio_device *radio = video_get_drvdata(video_devdata(file)); | 392 | struct amradio_device *radio = video_get_drvdata(video_devdata(file)); |
393 | int retval; | ||
342 | 394 | ||
343 | /* safety check */ | 395 | /* safety check */ |
344 | if (radio->removed) | 396 | if (radio->removed) |
@@ -346,6 +398,25 @@ static int vidioc_s_tuner(struct file *file, void *priv, | |||
346 | 398 | ||
347 | if (v->index > 0) | 399 | if (v->index > 0) |
348 | return -EINVAL; | 400 | return -EINVAL; |
401 | |||
402 | /* mono/stereo selector */ | ||
403 | switch (v->audmode) { | ||
404 | case V4L2_TUNER_MODE_MONO: | ||
405 | retval = amradio_set_stereo(radio, WANT_MONO); | ||
406 | if (retval < 0) | ||
407 | amradio_dev_warn(&radio->videodev->dev, | ||
408 | "set mono failed\n"); | ||
409 | break; | ||
410 | case V4L2_TUNER_MODE_STEREO: | ||
411 | retval = amradio_set_stereo(radio, WANT_STEREO); | ||
412 | if (retval < 0) | ||
413 | amradio_dev_warn(&radio->videodev->dev, | ||
414 | "set stereo failed\n"); | ||
415 | break; | ||
416 | default: | ||
417 | return -EINVAL; | ||
418 | } | ||
419 | |||
349 | return 0; | 420 | return 0; |
350 | } | 421 | } |
351 | 422 | ||
@@ -505,6 +576,11 @@ static int usb_amradio_open(struct file *file) | |||
505 | return -EIO; | 576 | return -EIO; |
506 | } | 577 | } |
507 | 578 | ||
579 | retval = amradio_set_stereo(radio, WANT_STEREO); | ||
580 | if (retval < 0) | ||
581 | amradio_dev_warn(&radio->videodev->dev, | ||
582 | "set stereo failed\n"); | ||
583 | |||
508 | retval = amradio_setfreq(radio, radio->curfreq); | 584 | retval = amradio_setfreq(radio, radio->curfreq); |
509 | if (retval < 0) | 585 | if (retval < 0) |
510 | amradio_dev_warn(&radio->videodev->dev, | 586 | amradio_dev_warn(&radio->videodev->dev, |
@@ -646,6 +722,7 @@ static int usb_amradio_probe(struct usb_interface *intf, | |||
646 | radio->users = 0; | 722 | radio->users = 0; |
647 | radio->usbdev = interface_to_usbdev(intf); | 723 | radio->usbdev = interface_to_usbdev(intf); |
648 | radio->curfreq = 95.16 * FREQ_MUL; | 724 | radio->curfreq = 95.16 * FREQ_MUL; |
725 | radio->stereo = -1; | ||
649 | 726 | ||
650 | mutex_init(&radio->lock); | 727 | mutex_init(&radio->lock); |
651 | 728 | ||