Lines Matching +full:debian +full:- +full:release
1 // SPDX-License-Identifier: GPL-2.0-or-later
12 * Big thanks to authors and contributors of dsbr100.c and radio-si470x.c
15 * http://av-usbradio.sourceforge.net/index.php
16 * http://sourceforge.net/projects/av-usbradio/
17 * Latest release of theirs project was in 2005.
20 * Also, Faidon Liambotis <paravoid@debian.org> wrote nice driver for this radio
22 * http://www.spinics.net/lists/linux-usb-devel/msg10109.html
26 * in usbhid/hid-quirks.c
36 * - Correct power management of device (suspend & resume)
37 * - Add code for scanning and smooth tuning
38 * - Add code for sensitivity value
39 * - Correct mistakes
40 * - In Japan another FREQ_MIN and FREQ_MAX
50 #include <media/v4l2-device.h>
51 #include <media/v4l2-ioctl.h>
52 #include <media/v4l2-ctrls.h>
53 #include <media/v4l2-event.h>
71 #define MR800_DRIVER_NAME "radio-mr800"
73 dev_warn(dev, MR800_DRIVER_NAME " - " fmt, ##arg)
76 dev_err(dev, MR800_DRIVER_NAME " - " fmt, ##arg)
82 /* Frequency limits in MHz -- these are European values. For Japanese
110 static int radio_nr = -1;
141 radio->buffer[0] = 0x00; in amradio_send_cmd()
142 radio->buffer[1] = 0x55; in amradio_send_cmd()
143 radio->buffer[2] = 0xaa; in amradio_send_cmd()
144 radio->buffer[3] = extralen; in amradio_send_cmd()
145 radio->buffer[4] = cmd; in amradio_send_cmd()
146 radio->buffer[5] = arg; in amradio_send_cmd()
147 radio->buffer[6] = 0x00; in amradio_send_cmd()
148 radio->buffer[7] = extra || reply ? 8 : 0; in amradio_send_cmd()
150 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), in amradio_send_cmd()
151 radio->buffer, BUFFER_LENGTH, &size, USB_TIMEOUT); in amradio_send_cmd()
154 if (video_is_registered(&radio->vdev)) in amradio_send_cmd()
155 amradio_dev_warn(&radio->vdev.dev, in amradio_send_cmd()
157 return retval ? retval : -EIO; in amradio_send_cmd()
163 memcpy(radio->buffer, extra, extralen); in amradio_send_cmd()
164 memset(radio->buffer + extralen, 0, 8 - extralen); in amradio_send_cmd()
165 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), in amradio_send_cmd()
166 radio->buffer, BUFFER_LENGTH, &size, USB_TIMEOUT); in amradio_send_cmd()
168 memset(radio->buffer, 0, 8); in amradio_send_cmd()
169 retval = usb_bulk_msg(radio->usbdev, usb_rcvbulkpipe(radio->usbdev, 0x81), in amradio_send_cmd()
170 radio->buffer, BUFFER_LENGTH, &size, USB_TIMEOUT); in amradio_send_cmd()
174 if (video_is_registered(&radio->vdev) && cmd != AMRADIO_GET_READY_FLAG) in amradio_send_cmd()
175 amradio_dev_warn(&radio->vdev.dev, "follow-up to cmd %02x failed\n", cmd); in amradio_send_cmd()
176 return retval ? retval : -EIO; in amradio_send_cmd()
186 radio->muted = mute; in amradio_set_mute()
209 radio->curfreq = freq; in amradio_set_freq()
220 radio->stereo = stereo; in amradio_set_stereo()
231 *is_stereo = radio->buffer[2] >> 7; in amradio_get_stat()
232 *signal = (radio->buffer[3] & 0xf0) << 8; in amradio_get_stat()
245 mutex_lock(&radio->lock); in usb_amradio_disconnect()
246 video_unregister_device(&radio->vdev); in usb_amradio_disconnect()
249 v4l2_device_disconnect(&radio->v4l2_dev); in usb_amradio_disconnect()
250 mutex_unlock(&radio->lock); in usb_amradio_disconnect()
251 v4l2_device_put(&radio->v4l2_dev); in usb_amradio_disconnect()
254 /* vidioc_querycap - query device capabilities */
260 strscpy(v->driver, "radio-mr800", sizeof(v->driver)); in vidioc_querycap()
261 strscpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card)); in vidioc_querycap()
262 usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info)); in vidioc_querycap()
266 /* vidioc_g_tuner - get tuner attributes */
274 if (v->index > 0) in vidioc_g_tuner()
275 return -EINVAL; in vidioc_g_tuner()
277 v->signal = 0; in vidioc_g_tuner()
278 retval = amradio_get_stat(radio, &is_stereo, &v->signal); in vidioc_g_tuner()
282 strscpy(v->name, "FM", sizeof(v->name)); in vidioc_g_tuner()
283 v->type = V4L2_TUNER_RADIO; in vidioc_g_tuner()
284 v->rangelow = FREQ_MIN * FREQ_MUL; in vidioc_g_tuner()
285 v->rangehigh = FREQ_MAX * FREQ_MUL; in vidioc_g_tuner()
286 v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | in vidioc_g_tuner()
288 v->rxsubchans = is_stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; in vidioc_g_tuner()
289 v->audmode = radio->stereo ? in vidioc_g_tuner()
294 /* vidioc_s_tuner - set tuner attributes */
300 if (v->index > 0) in vidioc_s_tuner()
301 return -EINVAL; in vidioc_s_tuner()
304 switch (v->audmode) { in vidioc_s_tuner()
312 /* vidioc_s_frequency - set tuner radio frequency */
318 if (f->tuner != 0) in vidioc_s_frequency()
319 return -EINVAL; in vidioc_s_frequency()
320 return amradio_set_freq(radio, f->frequency); in vidioc_s_frequency()
323 /* vidioc_g_frequency - get tuner radio frequency */
329 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) in vidioc_g_frequency()
330 return -EINVAL; in vidioc_g_frequency()
331 f->type = V4L2_TUNER_RADIO; in vidioc_g_frequency()
332 f->frequency = radio->curfreq; in vidioc_g_frequency()
347 if (seek->tuner != 0 || !seek->wrap_around) in vidioc_s_hw_freq_seek()
348 return -EINVAL; in vidioc_s_hw_freq_seek()
350 if (file->f_flags & O_NONBLOCK) in vidioc_s_hw_freq_seek()
351 return -EWOULDBLOCK; in vidioc_s_hw_freq_seek()
357 amradio_set_freq(radio, radio->curfreq); in vidioc_s_hw_freq_seek()
359 seek->seek_upward ? AMRADIO_SET_SEARCH_UP : AMRADIO_SET_SEARCH_DOWN, in vidioc_s_hw_freq_seek()
366 retval = -ENODATA; in vidioc_s_hw_freq_seek()
370 retval = -ERESTARTSYS; in vidioc_s_hw_freq_seek()
378 if (radio->buffer[1] || radio->buffer[2]) { in vidioc_s_hw_freq_seek()
379 /* To check: sometimes radio->curfreq is set to out of range value */ in vidioc_s_hw_freq_seek()
380 radio->curfreq = (radio->buffer[1] << 8) | radio->buffer[2]; in vidioc_s_hw_freq_seek()
381 radio->curfreq = (radio->curfreq - 0x10) * 200; in vidioc_s_hw_freq_seek()
384 amradio_set_freq(radio, radio->curfreq); in vidioc_s_hw_freq_seek()
390 amradio_set_freq(radio, radio->curfreq); in vidioc_s_hw_freq_seek()
397 container_of(ctrl->handler, struct amradio_device, hdl); in usb_amradio_s_ctrl()
399 switch (ctrl->id) { in usb_amradio_s_ctrl()
401 return amradio_set_mute(radio, ctrl->val); in usb_amradio_s_ctrl()
404 return -EINVAL; in usb_amradio_s_ctrl()
417 retval = amradio_set_freq(radio, radio->curfreq); in usb_amradio_init()
423 amradio_dev_err(&radio->vdev.dev, "initialization failed\n"); in usb_amradio_init()
427 /* Suspend device - stop device. Need to be checked and fixed */
432 mutex_lock(&radio->lock); in usb_amradio_suspend()
433 if (!radio->muted) { in usb_amradio_suspend()
435 radio->muted = false; in usb_amradio_suspend()
437 mutex_unlock(&radio->lock); in usb_amradio_suspend()
439 dev_info(&intf->dev, "going into suspend..\n"); in usb_amradio_suspend()
443 /* Resume device - start device. Need to be checked and fixed */
448 mutex_lock(&radio->lock); in usb_amradio_resume()
449 amradio_set_stereo(radio, radio->stereo); in usb_amradio_resume()
450 amradio_set_freq(radio, radio->curfreq); in usb_amradio_resume()
452 if (!radio->muted) in usb_amradio_resume()
455 mutex_unlock(&radio->lock); in usb_amradio_resume()
457 dev_info(&intf->dev, "coming out of suspend..\n"); in usb_amradio_resume()
469 .release = v4l2_fh_release,
491 v4l2_ctrl_handler_free(&radio->hdl); in usb_amradio_release()
492 v4l2_device_unregister(&radio->v4l2_dev); in usb_amradio_release()
493 kfree(radio->buffer); in usb_amradio_release()
507 dev_err(&intf->dev, "kmalloc for amradio_device failed\n"); in usb_amradio_probe()
508 retval = -ENOMEM; in usb_amradio_probe()
512 radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL); in usb_amradio_probe()
514 if (!radio->buffer) { in usb_amradio_probe()
515 dev_err(&intf->dev, "kmalloc for radio->buffer failed\n"); in usb_amradio_probe()
516 retval = -ENOMEM; in usb_amradio_probe()
520 retval = v4l2_device_register(&intf->dev, &radio->v4l2_dev); in usb_amradio_probe()
522 dev_err(&intf->dev, "couldn't register v4l2_device\n"); in usb_amradio_probe()
526 v4l2_ctrl_handler_init(&radio->hdl, 1); in usb_amradio_probe()
527 v4l2_ctrl_new_std(&radio->hdl, &usb_amradio_ctrl_ops, in usb_amradio_probe()
529 if (radio->hdl.error) { in usb_amradio_probe()
530 retval = radio->hdl.error; in usb_amradio_probe()
531 dev_err(&intf->dev, "couldn't register control\n"); in usb_amradio_probe()
534 mutex_init(&radio->lock); in usb_amradio_probe()
536 radio->v4l2_dev.ctrl_handler = &radio->hdl; in usb_amradio_probe()
537 radio->v4l2_dev.release = usb_amradio_release; in usb_amradio_probe()
538 strscpy(radio->vdev.name, radio->v4l2_dev.name, in usb_amradio_probe()
539 sizeof(radio->vdev.name)); in usb_amradio_probe()
540 radio->vdev.v4l2_dev = &radio->v4l2_dev; in usb_amradio_probe()
541 radio->vdev.fops = &usb_amradio_fops; in usb_amradio_probe()
542 radio->vdev.ioctl_ops = &usb_amradio_ioctl_ops; in usb_amradio_probe()
543 radio->vdev.release = video_device_release_empty; in usb_amradio_probe()
544 radio->vdev.lock = &radio->lock; in usb_amradio_probe()
545 radio->vdev.device_caps = V4L2_CAP_RADIO | V4L2_CAP_TUNER | in usb_amradio_probe()
548 radio->usbdev = interface_to_usbdev(intf); in usb_amradio_probe()
549 radio->intf = intf; in usb_amradio_probe()
550 usb_set_intfdata(intf, &radio->v4l2_dev); in usb_amradio_probe()
551 radio->curfreq = 95.16 * FREQ_MUL; in usb_amradio_probe()
553 video_set_drvdata(&radio->vdev, radio); in usb_amradio_probe()
558 retval = video_register_device(&radio->vdev, VFL_TYPE_RADIO, in usb_amradio_probe()
561 dev_err(&intf->dev, "could not register video device\n"); in usb_amradio_probe()
568 v4l2_ctrl_handler_free(&radio->hdl); in usb_amradio_probe()
570 v4l2_device_unregister(&radio->v4l2_dev); in usb_amradio_probe()
572 kfree(radio->buffer); in usb_amradio_probe()