aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-04-27 12:28:34 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-07 14:29:10 -0400
commit77cf393434898d1299c77c32bdd0629b2b4df170 (patch)
tree1cb16fbe4201817a90b44215142edaaa21f28154 /drivers
parent85578b0fdc107e0d7022d38271fdcf0567afd212 (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.c43
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
240static 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;