radio-mr800.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. /*
  2. * A driver for the AverMedia MR 800 USB FM radio. This device plugs
  3. * into both the USB and an analog audio input, so this thing
  4. * only deals with initialization and frequency setting, the
  5. * audio data has to be handled by a sound driver.
  6. *
  7. * Copyright (c) 2008 Alexey Klimov <klimov.linux@gmail.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 as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22. */
  23. /*
  24. * Big thanks to authors and contributors of dsbr100.c and radio-si470x.c
  25. *
  26. * When work was looked pretty good, i discover this:
  27. * http://av-usbradio.sourceforge.net/index.php
  28. * http://sourceforge.net/projects/av-usbradio/
  29. * Latest release of theirs project was in 2005.
  30. * Probably, this driver could be improved through using their
  31. * achievements (specifications given).
  32. * Also, Faidon Liambotis <paravoid@debian.org> wrote nice driver for this radio
  33. * in 2007. He allowed to use his driver to improve current mr800 radio driver.
  34. * http://kerneltrap.org/mailarchive/linux-usb-devel/2007/10/11/342492
  35. *
  36. * Version 0.01: First working version.
  37. * It's required to blacklist AverMedia USB Radio
  38. * in usbhid/hid-quirks.c
  39. * Version 0.10: A lot of cleanups and fixes: unpluging the device,
  40. * few mutex locks were added, codinstyle issues, etc.
  41. * Added stereo support. Thanks to
  42. * Douglas Schilling Landgraf <dougsland@gmail.com> and
  43. * David Ellingsworth <david@identd.dyndns.org>
  44. * for discussion, help and support.
  45. * Version 0.11: Converted to v4l2_device.
  46. *
  47. * Many things to do:
  48. * - Correct power management of device (suspend & resume)
  49. * - Add code for scanning and smooth tuning
  50. * - Add code for sensitivity value
  51. * - Correct mistakes
  52. * - In Japan another FREQ_MIN and FREQ_MAX
  53. */
  54. /* kernel includes */
  55. #include <linux/kernel.h>
  56. #include <linux/module.h>
  57. #include <linux/init.h>
  58. #include <linux/slab.h>
  59. #include <linux/input.h>
  60. #include <linux/videodev2.h>
  61. #include <media/v4l2-device.h>
  62. #include <media/v4l2-ioctl.h>
  63. #include <media/v4l2-ctrls.h>
  64. #include <media/v4l2-event.h>
  65. #include <linux/usb.h>
  66. #include <linux/mutex.h>
  67. /* driver and module definitions */
  68. #define DRIVER_AUTHOR "Alexey Klimov <klimov.linux@gmail.com>"
  69. #define DRIVER_DESC "AverMedia MR 800 USB FM radio driver"
  70. #define DRIVER_VERSION "0.1.2"
  71. MODULE_AUTHOR(DRIVER_AUTHOR);
  72. MODULE_DESCRIPTION(DRIVER_DESC);
  73. MODULE_LICENSE("GPL");
  74. MODULE_VERSION(DRIVER_VERSION);
  75. #define USB_AMRADIO_VENDOR 0x07ca
  76. #define USB_AMRADIO_PRODUCT 0xb800
  77. /* dev_warn macro with driver name */
  78. #define MR800_DRIVER_NAME "radio-mr800"
  79. #define amradio_dev_warn(dev, fmt, arg...) \
  80. dev_warn(dev, MR800_DRIVER_NAME " - " fmt, ##arg)
  81. #define amradio_dev_err(dev, fmt, arg...) \
  82. dev_err(dev, MR800_DRIVER_NAME " - " fmt, ##arg)
  83. /* Probably USB_TIMEOUT should be modified in module parameter */
  84. #define BUFFER_LENGTH 8
  85. #define USB_TIMEOUT 500
  86. /* Frequency limits in MHz -- these are European values. For Japanese
  87. devices, that would be 76 and 91. */
  88. #define FREQ_MIN 87.5
  89. #define FREQ_MAX 108.0
  90. #define FREQ_MUL 16000
  91. /*
  92. * Commands that device should understand
  93. * List isn't full and will be updated with implementation of new functions
  94. */
  95. #define AMRADIO_SET_FREQ 0xa4
  96. #define AMRADIO_SET_MUTE 0xab
  97. #define AMRADIO_SET_MONO 0xae
  98. /* Comfortable defines for amradio_set_mute */
  99. #define AMRADIO_START 0x00
  100. #define AMRADIO_STOP 0x01
  101. /* Comfortable defines for amradio_set_stereo */
  102. #define WANT_STEREO 0x00
  103. #define WANT_MONO 0x01
  104. /* module parameter */
  105. static int radio_nr = -1;
  106. module_param(radio_nr, int, 0);
  107. MODULE_PARM_DESC(radio_nr, "Radio Nr");
  108. /* Data for one (physical) device */
  109. struct amradio_device {
  110. /* reference to USB and video device */
  111. struct usb_device *usbdev;
  112. struct usb_interface *intf;
  113. struct video_device vdev;
  114. struct v4l2_device v4l2_dev;
  115. struct v4l2_ctrl_handler hdl;
  116. unsigned char *buffer;
  117. struct mutex lock; /* buffer locking */
  118. int curfreq;
  119. int stereo;
  120. int muted;
  121. };
  122. static inline struct amradio_device *to_amradio_dev(struct v4l2_device *v4l2_dev)
  123. {
  124. return container_of(v4l2_dev, struct amradio_device, v4l2_dev);
  125. }
  126. /* switch on/off the radio. Send 8 bytes to device */
  127. static int amradio_set_mute(struct amradio_device *radio, char argument)
  128. {
  129. int retval;
  130. int size;
  131. radio->buffer[0] = 0x00;
  132. radio->buffer[1] = 0x55;
  133. radio->buffer[2] = 0xaa;
  134. radio->buffer[3] = 0x00;
  135. radio->buffer[4] = AMRADIO_SET_MUTE;
  136. radio->buffer[5] = argument;
  137. radio->buffer[6] = 0x00;
  138. radio->buffer[7] = 0x00;
  139. retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
  140. (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
  141. if (retval < 0 || size != BUFFER_LENGTH) {
  142. amradio_dev_warn(&radio->vdev.dev, "set mute failed\n");
  143. return retval < 0 ? retval : -EIO;
  144. }
  145. radio->muted = argument;
  146. return 0;
  147. }
  148. /* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
  149. static int amradio_setfreq(struct amradio_device *radio, int freq)
  150. {
  151. unsigned short freq_send = 0x10 + (freq >> 3) / 25;
  152. int retval;
  153. int size;
  154. radio->buffer[0] = 0x00;
  155. radio->buffer[1] = 0x55;
  156. radio->buffer[2] = 0xaa;
  157. radio->buffer[3] = 0x03;
  158. radio->buffer[4] = AMRADIO_SET_FREQ;
  159. radio->buffer[5] = 0x00;
  160. radio->buffer[6] = 0x00;
  161. radio->buffer[7] = 0x08;
  162. retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
  163. (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
  164. if (retval < 0 || size != BUFFER_LENGTH)
  165. goto out;
  166. /* frequency is calculated from freq_send and placed in first 2 bytes */
  167. radio->buffer[0] = (freq_send >> 8) & 0xff;
  168. radio->buffer[1] = freq_send & 0xff;
  169. radio->buffer[2] = 0x01;
  170. radio->buffer[3] = 0x00;
  171. radio->buffer[4] = 0x00;
  172. /* 5 and 6 bytes of buffer already = 0x00 */
  173. radio->buffer[7] = 0x00;
  174. retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
  175. (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
  176. if (retval >= 0 && size == BUFFER_LENGTH) {
  177. radio->curfreq = freq;
  178. return 0;
  179. }
  180. out:
  181. amradio_dev_warn(&radio->vdev.dev, "set frequency failed\n");
  182. return retval < 0 ? retval : -EIO;
  183. }
  184. static int amradio_set_stereo(struct amradio_device *radio, char argument)
  185. {
  186. int retval;
  187. int size;
  188. radio->buffer[0] = 0x00;
  189. radio->buffer[1] = 0x55;
  190. radio->buffer[2] = 0xaa;
  191. radio->buffer[3] = 0x00;
  192. radio->buffer[4] = AMRADIO_SET_MONO;
  193. radio->buffer[5] = argument;
  194. radio->buffer[6] = 0x00;
  195. radio->buffer[7] = 0x00;
  196. retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
  197. (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
  198. if (retval < 0 || size != BUFFER_LENGTH) {
  199. amradio_dev_warn(&radio->vdev.dev, "set stereo failed\n");
  200. return retval < 0 ? retval : -EIO;
  201. }
  202. radio->stereo = (argument == WANT_STEREO);
  203. return 0;
  204. }
  205. /* Handle unplugging the device.
  206. * We call video_unregister_device in any case.
  207. * The last function called in this procedure is
  208. * usb_amradio_device_release.
  209. */
  210. static void usb_amradio_disconnect(struct usb_interface *intf)
  211. {
  212. struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf));
  213. mutex_lock(&radio->lock);
  214. usb_set_intfdata(intf, NULL);
  215. video_unregister_device(&radio->vdev);
  216. v4l2_device_disconnect(&radio->v4l2_dev);
  217. mutex_unlock(&radio->lock);
  218. v4l2_device_put(&radio->v4l2_dev);
  219. }
  220. /* vidioc_querycap - query device capabilities */
  221. static int vidioc_querycap(struct file *file, void *priv,
  222. struct v4l2_capability *v)
  223. {
  224. struct amradio_device *radio = video_drvdata(file);
  225. strlcpy(v->driver, "radio-mr800", sizeof(v->driver));
  226. strlcpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card));
  227. usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
  228. v->device_caps = V4L2_CAP_RADIO | V4L2_CAP_TUNER;
  229. v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
  230. return 0;
  231. }
  232. /* vidioc_g_tuner - get tuner attributes */
  233. static int vidioc_g_tuner(struct file *file, void *priv,
  234. struct v4l2_tuner *v)
  235. {
  236. struct amradio_device *radio = video_drvdata(file);
  237. if (v->index > 0)
  238. return -EINVAL;
  239. strcpy(v->name, "FM");
  240. v->type = V4L2_TUNER_RADIO;
  241. v->rangelow = FREQ_MIN * FREQ_MUL;
  242. v->rangehigh = FREQ_MAX * FREQ_MUL;
  243. v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
  244. /* We do not know how to get hold of the stereo indicator, so
  245. all we can do is give back both mono and stereo, which
  246. effectively means that we don't know. */
  247. v->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
  248. v->signal = 0xffff;
  249. v->audmode = radio->stereo ?
  250. V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO;
  251. return 0;
  252. }
  253. /* vidioc_s_tuner - set tuner attributes */
  254. static int vidioc_s_tuner(struct file *file, void *priv,
  255. struct v4l2_tuner *v)
  256. {
  257. struct amradio_device *radio = video_drvdata(file);
  258. if (v->index > 0)
  259. return -EINVAL;
  260. /* mono/stereo selector */
  261. switch (v->audmode) {
  262. case V4L2_TUNER_MODE_MONO:
  263. return amradio_set_stereo(radio, WANT_MONO);
  264. default:
  265. return amradio_set_stereo(radio, WANT_STEREO);
  266. }
  267. }
  268. /* vidioc_s_frequency - set tuner radio frequency */
  269. static int vidioc_s_frequency(struct file *file, void *priv,
  270. struct v4l2_frequency *f)
  271. {
  272. struct amradio_device *radio = video_drvdata(file);
  273. if (f->tuner != 0)
  274. return -EINVAL;
  275. return amradio_setfreq(radio, clamp_t(unsigned, f->frequency,
  276. FREQ_MIN * FREQ_MUL, FREQ_MAX * FREQ_MUL));
  277. }
  278. /* vidioc_g_frequency - get tuner radio frequency */
  279. static int vidioc_g_frequency(struct file *file, void *priv,
  280. struct v4l2_frequency *f)
  281. {
  282. struct amradio_device *radio = video_drvdata(file);
  283. if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
  284. return -EINVAL;
  285. f->type = V4L2_TUNER_RADIO;
  286. f->frequency = radio->curfreq;
  287. return 0;
  288. }
  289. static int usb_amradio_s_ctrl(struct v4l2_ctrl *ctrl)
  290. {
  291. struct amradio_device *radio =
  292. container_of(ctrl->handler, struct amradio_device, hdl);
  293. switch (ctrl->id) {
  294. case V4L2_CID_AUDIO_MUTE:
  295. return amradio_set_mute(radio,
  296. ctrl->val ? AMRADIO_STOP : AMRADIO_START);
  297. }
  298. return -EINVAL;
  299. }
  300. static int usb_amradio_init(struct amradio_device *radio)
  301. {
  302. int retval;
  303. retval = amradio_set_mute(radio, AMRADIO_STOP);
  304. if (retval)
  305. goto out_err;
  306. retval = amradio_set_stereo(radio, WANT_STEREO);
  307. if (retval)
  308. goto out_err;
  309. goto out;
  310. out_err:
  311. amradio_dev_err(&radio->vdev.dev, "initialization failed\n");
  312. out:
  313. return retval;
  314. }
  315. /* Suspend device - stop device. Need to be checked and fixed */
  316. static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
  317. {
  318. struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf));
  319. mutex_lock(&radio->lock);
  320. if (!radio->muted) {
  321. amradio_set_mute(radio, AMRADIO_STOP);
  322. radio->muted = 0;
  323. }
  324. mutex_unlock(&radio->lock);
  325. dev_info(&intf->dev, "going into suspend..\n");
  326. return 0;
  327. }
  328. /* Resume device - start device. Need to be checked and fixed */
  329. static int usb_amradio_resume(struct usb_interface *intf)
  330. {
  331. struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf));
  332. mutex_lock(&radio->lock);
  333. if (radio->stereo)
  334. amradio_set_stereo(radio, WANT_STEREO);
  335. else
  336. amradio_set_stereo(radio, WANT_MONO);
  337. amradio_setfreq(radio, radio->curfreq);
  338. if (!radio->muted)
  339. amradio_set_mute(radio, AMRADIO_START);
  340. mutex_unlock(&radio->lock);
  341. dev_info(&intf->dev, "coming out of suspend..\n");
  342. return 0;
  343. }
  344. static const struct v4l2_ctrl_ops usb_amradio_ctrl_ops = {
  345. .s_ctrl = usb_amradio_s_ctrl,
  346. };
  347. /* File system interface */
  348. static const struct v4l2_file_operations usb_amradio_fops = {
  349. .owner = THIS_MODULE,
  350. .open = v4l2_fh_open,
  351. .release = v4l2_fh_release,
  352. .poll = v4l2_ctrl_poll,
  353. .unlocked_ioctl = video_ioctl2,
  354. };
  355. static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = {
  356. .vidioc_querycap = vidioc_querycap,
  357. .vidioc_g_tuner = vidioc_g_tuner,
  358. .vidioc_s_tuner = vidioc_s_tuner,
  359. .vidioc_g_frequency = vidioc_g_frequency,
  360. .vidioc_s_frequency = vidioc_s_frequency,
  361. .vidioc_log_status = v4l2_ctrl_log_status,
  362. .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
  363. .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
  364. };
  365. static void usb_amradio_release(struct v4l2_device *v4l2_dev)
  366. {
  367. struct amradio_device *radio = to_amradio_dev(v4l2_dev);
  368. /* free rest memory */
  369. v4l2_ctrl_handler_free(&radio->hdl);
  370. v4l2_device_unregister(&radio->v4l2_dev);
  371. kfree(radio->buffer);
  372. kfree(radio);
  373. }
  374. /* check if the device is present and register with v4l and usb if it is */
  375. static int usb_amradio_probe(struct usb_interface *intf,
  376. const struct usb_device_id *id)
  377. {
  378. struct amradio_device *radio;
  379. int retval = 0;
  380. radio = kzalloc(sizeof(struct amradio_device), GFP_KERNEL);
  381. if (!radio) {
  382. dev_err(&intf->dev, "kmalloc for amradio_device failed\n");
  383. retval = -ENOMEM;
  384. goto err;
  385. }
  386. radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL);
  387. if (!radio->buffer) {
  388. dev_err(&intf->dev, "kmalloc for radio->buffer failed\n");
  389. retval = -ENOMEM;
  390. goto err_nobuf;
  391. }
  392. retval = v4l2_device_register(&intf->dev, &radio->v4l2_dev);
  393. if (retval < 0) {
  394. dev_err(&intf->dev, "couldn't register v4l2_device\n");
  395. goto err_v4l2;
  396. }
  397. v4l2_ctrl_handler_init(&radio->hdl, 1);
  398. v4l2_ctrl_new_std(&radio->hdl, &usb_amradio_ctrl_ops,
  399. V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
  400. if (radio->hdl.error) {
  401. retval = radio->hdl.error;
  402. dev_err(&intf->dev, "couldn't register control\n");
  403. goto err_ctrl;
  404. }
  405. mutex_init(&radio->lock);
  406. radio->v4l2_dev.ctrl_handler = &radio->hdl;
  407. radio->v4l2_dev.release = usb_amradio_release;
  408. strlcpy(radio->vdev.name, radio->v4l2_dev.name,
  409. sizeof(radio->vdev.name));
  410. radio->vdev.v4l2_dev = &radio->v4l2_dev;
  411. radio->vdev.fops = &usb_amradio_fops;
  412. radio->vdev.ioctl_ops = &usb_amradio_ioctl_ops;
  413. radio->vdev.release = video_device_release_empty;
  414. radio->vdev.lock = &radio->lock;
  415. set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);
  416. radio->usbdev = interface_to_usbdev(intf);
  417. radio->intf = intf;
  418. usb_set_intfdata(intf, &radio->v4l2_dev);
  419. radio->curfreq = 95.16 * FREQ_MUL;
  420. video_set_drvdata(&radio->vdev, radio);
  421. retval = usb_amradio_init(radio);
  422. if (retval)
  423. goto err_vdev;
  424. retval = video_register_device(&radio->vdev, VFL_TYPE_RADIO,
  425. radio_nr);
  426. if (retval < 0) {
  427. dev_err(&intf->dev, "could not register video device\n");
  428. goto err_vdev;
  429. }
  430. return 0;
  431. err_vdev:
  432. v4l2_ctrl_handler_free(&radio->hdl);
  433. err_ctrl:
  434. v4l2_device_unregister(&radio->v4l2_dev);
  435. err_v4l2:
  436. kfree(radio->buffer);
  437. err_nobuf:
  438. kfree(radio);
  439. err:
  440. return retval;
  441. }
  442. /* USB Device ID List */
  443. static struct usb_device_id usb_amradio_device_table[] = {
  444. { USB_DEVICE_AND_INTERFACE_INFO(USB_AMRADIO_VENDOR, USB_AMRADIO_PRODUCT,
  445. USB_CLASS_HID, 0, 0) },
  446. { } /* Terminating entry */
  447. };
  448. MODULE_DEVICE_TABLE(usb, usb_amradio_device_table);
  449. /* USB subsystem interface */
  450. static struct usb_driver usb_amradio_driver = {
  451. .name = MR800_DRIVER_NAME,
  452. .probe = usb_amradio_probe,
  453. .disconnect = usb_amradio_disconnect,
  454. .suspend = usb_amradio_suspend,
  455. .resume = usb_amradio_resume,
  456. .reset_resume = usb_amradio_resume,
  457. .id_table = usb_amradio_device_table,
  458. };
  459. module_usb_driver(usb_amradio_driver);