diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-04-27 12:28:34 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-07 14:29:10 -0400 |
commit | 77cf393434898d1299c77c32bdd0629b2b4df170 (patch) | |
tree | 1cb16fbe4201817a90b44215142edaaa21f28154 /drivers | |
parent | 85578b0fdc107e0d7022d38271fdcf0567afd212 (diff) |
[media] radio-mr800: add support for stereo and signal detection
Thanks to an older driver by Faidon Liambotis <paravoid@debian.org> (as noted
in the radio-mr800 comment block at the start) for figuring out how to get the
signal/stereo state.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/radio/radio-mr800.c | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 0a96edae678..0b39a8cfee8 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c | |||
@@ -103,6 +103,7 @@ devices, that would be 76 and 91. */ | |||
103 | * List isn't full and will be updated with implementation of new functions | 103 | * List isn't full and will be updated with implementation of new functions |
104 | */ | 104 | */ |
105 | #define AMRADIO_SET_FREQ 0xa4 | 105 | #define AMRADIO_SET_FREQ 0xa4 |
106 | #define AMRADIO_GET_SIGNAL 0xa7 | ||
106 | #define AMRADIO_SET_MUTE 0xab | 107 | #define AMRADIO_SET_MUTE 0xab |
107 | #define AMRADIO_SET_MONO 0xae | 108 | #define AMRADIO_SET_MONO 0xae |
108 | 109 | ||
@@ -236,6 +237,35 @@ static int amradio_set_stereo(struct amradio_device *radio, char argument) | |||
236 | return 0; | 237 | return 0; |
237 | } | 238 | } |
238 | 239 | ||
240 | static int amradio_get_stat(struct amradio_device *radio, bool *is_stereo, u32 *signal) | ||
241 | { | ||
242 | int retval; | ||
243 | int size; | ||
244 | |||
245 | radio->buffer[0] = 0x00; | ||
246 | radio->buffer[1] = 0x55; | ||
247 | radio->buffer[2] = 0xaa; | ||
248 | radio->buffer[3] = 0x00; | ||
249 | radio->buffer[4] = AMRADIO_GET_SIGNAL; | ||
250 | radio->buffer[5] = 0x00; | ||
251 | radio->buffer[6] = 0x00; | ||
252 | radio->buffer[7] = 0x08; | ||
253 | |||
254 | retval = usb_bulk_msg(radio->usbdev, usb_sndbulkpipe(radio->usbdev, 0x02), | ||
255 | radio->buffer, BUFFER_LENGTH, &size, USB_TIMEOUT); | ||
256 | if (!retval) | ||
257 | retval = usb_bulk_msg(radio->usbdev, usb_rcvbulkpipe(radio->usbdev, 0x81), | ||
258 | radio->buffer, BUFFER_LENGTH, &size, USB_TIMEOUT); | ||
259 | |||
260 | if (retval || size != BUFFER_LENGTH) { | ||
261 | amradio_dev_warn(&radio->vdev.dev, "get stat failed\n"); | ||
262 | return retval; | ||
263 | } | ||
264 | *is_stereo = radio->buffer[2] >> 7; | ||
265 | *signal = (radio->buffer[3] & 0xf0) << 8; | ||
266 | return 0; | ||
267 | } | ||
268 | |||
239 | /* Handle unplugging the device. | 269 | /* Handle unplugging the device. |
240 | * We call video_unregister_device in any case. | 270 | * We call video_unregister_device in any case. |
241 | * The last function called in this procedure is | 271 | * The last function called in this procedure is |
@@ -272,20 +302,23 @@ static int vidioc_g_tuner(struct file *file, void *priv, | |||
272 | struct v4l2_tuner *v) | 302 | struct v4l2_tuner *v) |
273 | { | 303 | { |
274 | struct amradio_device *radio = video_drvdata(file); | 304 | struct amradio_device *radio = video_drvdata(file); |
305 | bool is_stereo = false; | ||
306 | int retval; | ||
275 | 307 | ||
276 | if (v->index > 0) | 308 | if (v->index > 0) |
277 | return -EINVAL; | 309 | return -EINVAL; |
278 | 310 | ||
311 | v->signal = 0; | ||
312 | retval = amradio_get_stat(radio, &is_stereo, &v->signal); | ||
313 | if (retval) | ||
314 | return retval; | ||
315 | |||
279 | strcpy(v->name, "FM"); | 316 | strcpy(v->name, "FM"); |
280 | v->type = V4L2_TUNER_RADIO; | 317 | v->type = V4L2_TUNER_RADIO; |
281 | v->rangelow = FREQ_MIN * FREQ_MUL; | 318 | v->rangelow = FREQ_MIN * FREQ_MUL; |
282 | v->rangehigh = FREQ_MAX * FREQ_MUL; | 319 | v->rangehigh = FREQ_MAX * FREQ_MUL; |
283 | v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; | 320 | v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; |
284 | /* We do not know how to get hold of the stereo indicator, so | 321 | v->rxsubchans = is_stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; |
285 | all we can do is give back both mono and stereo, which | ||
286 | effectively means that we don't know. */ | ||
287 | v->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; | ||
288 | v->signal = 0xffff; | ||
289 | v->audmode = radio->stereo ? | 322 | v->audmode = radio->stereo ? |
290 | V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO; | 323 | V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO; |
291 | return 0; | 324 | return 0; |