linux/drivers/media/radio/radio-ma901.c
<<
>>
Prefs
   1/*
   2 * Driver for the MasterKit MA901 USB FM radio. This device plugs
   3 * into the USB port and an analog audio input or headphones, so this thing
   4 * only deals with initialization, frequency setting, volume.
   5 *
   6 * Copyright (c) 2012 Alexey Klimov <klimov.linux@gmail.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21 */
  22
  23#include <linux/kernel.h>
  24#include <linux/module.h>
  25#include <linux/init.h>
  26#include <linux/slab.h>
  27#include <linux/input.h>
  28#include <linux/videodev2.h>
  29#include <media/v4l2-device.h>
  30#include <media/v4l2-ioctl.h>
  31#include <media/v4l2-ctrls.h>
  32#include <media/v4l2-event.h>
  33#include <linux/usb.h>
  34#include <linux/mutex.h>
  35
  36#define DRIVER_AUTHOR "Alexey Klimov <klimov.linux@gmail.com>"
  37#define DRIVER_DESC "Masterkit MA901 USB FM radio driver"
  38#define DRIVER_VERSION "0.0.1"
  39
  40MODULE_AUTHOR(DRIVER_AUTHOR);
  41MODULE_DESCRIPTION(DRIVER_DESC);
  42MODULE_LICENSE("GPL");
  43MODULE_VERSION(DRIVER_VERSION);
  44
  45#define USB_MA901_VENDOR  0x16c0
  46#define USB_MA901_PRODUCT 0x05df
  47
  48/* dev_warn macro with driver name */
  49#define MA901_DRIVER_NAME "radio-ma901"
  50#define ma901radio_dev_warn(dev, fmt, arg...)                           \
  51                dev_warn(dev, MA901_DRIVER_NAME " - " fmt, ##arg)
  52
  53#define ma901radio_dev_err(dev, fmt, arg...) \
  54                dev_err(dev, MA901_DRIVER_NAME " - " fmt, ##arg)
  55
  56/* Probably USB_TIMEOUT should be modified in module parameter */
  57#define BUFFER_LENGTH 8
  58#define USB_TIMEOUT 500
  59
  60#define FREQ_MIN  87.5
  61#define FREQ_MAX 108.0
  62#define FREQ_MUL 16000
  63
  64#define MA901_VOLUME_MAX 16
  65#define MA901_VOLUME_MIN 0
  66
  67/* Commands that device should understand
  68 * List isn't full and will be updated with implementation of new functions
  69 */
  70#define MA901_RADIO_SET_FREQ            0x03
  71#define MA901_RADIO_SET_VOLUME          0x04
  72#define MA901_RADIO_SET_MONO_STEREO     0x05
  73
  74/* Comfortable defines for ma901radio_set_stereo */
  75#define MA901_WANT_STEREO               0x50
  76#define MA901_WANT_MONO                 0xd0
  77
  78/* module parameter */
  79static int radio_nr = -1;
  80module_param(radio_nr, int, 0);
  81MODULE_PARM_DESC(radio_nr, "Radio file number");
  82
  83/* Data for one (physical) device */
  84struct ma901radio_device {
  85        /* reference to USB and video device */
  86        struct usb_device *usbdev;
  87        struct usb_interface *intf;
  88        struct video_device vdev;
  89        struct v4l2_device v4l2_dev;
  90        struct v4l2_ctrl_handler hdl;
  91
  92        u8 *buffer;
  93        struct mutex lock;      /* buffer locking */
  94        int curfreq;
  95        u16 volume;
  96        int stereo;
  97        bool muted;
  98};
  99
 100static inline struct ma901radio_device *to_ma901radio_dev(struct v4l2_device *v4l2_dev)
 101{
 102        return container_of(v4l2_dev, struct ma901radio_device, v4l2_dev);
 103}
 104
 105/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
 106static int ma901radio_set_freq(struct ma901radio_device *radio, int freq)
 107{
 108        unsigned int freq_send = 0x300 + (freq >> 5) / 25;
 109        int retval;
 110
 111        radio->buffer[0] = 0x0a;
 112        radio->buffer[1] = MA901_RADIO_SET_FREQ;
 113        radio->buffer[2] = ((freq_send >> 8) & 0xff) + 0x80;
 114        radio->buffer[3] = freq_send & 0xff;
 115        radio->buffer[4] = 0x00;
 116        radio->buffer[5] = 0x00;
 117        radio->buffer[6] = 0x00;
 118        radio->buffer[7] = 0x00;
 119
 120        retval = usb_control_msg(radio->usbdev, usb_sndctrlpipe(radio->usbdev, 0),
 121                                9, 0x21, 0x0300, 0,
 122                                radio->buffer, BUFFER_LENGTH, USB_TIMEOUT);
 123        if (retval < 0)
 124                return retval;
 125
 126        radio->curfreq = freq;
 127        return 0;
 128}
 129
 130static int ma901radio_set_volume(struct ma901radio_device *radio, u16 vol_to_set)
 131{
 132        int retval;
 133
 134        radio->buffer[0] = 0x0a;
 135        radio->buffer[1] = MA901_RADIO_SET_VOLUME;
 136        radio->buffer[2] = 0xc2;
 137        radio->buffer[3] = vol_to_set + 0x20;
 138        radio->buffer[4] = 0x00;
 139        radio->buffer[5] = 0x00;
 140        radio->buffer[6] = 0x00;
 141        radio->buffer[7] = 0x00;
 142
 143        retval = usb_control_msg(radio->usbdev, usb_sndctrlpipe(radio->usbdev, 0),
 144                                9, 0x21, 0x0300, 0,
 145                                radio->buffer, BUFFER_LENGTH, USB_TIMEOUT);
 146        if (retval < 0)
 147                return retval;
 148
 149        radio->volume = vol_to_set;
 150        return retval;
 151}
 152
 153static int ma901_set_stereo(struct ma901radio_device *radio, u8 stereo)
 154{
 155        int retval;
 156
 157        radio->buffer[0] = 0x0a;
 158        radio->buffer[1] = MA901_RADIO_SET_MONO_STEREO;
 159        radio->buffer[2] = stereo;
 160        radio->buffer[3] = 0x00;
 161        radio->buffer[4] = 0x00;
 162        radio->buffer[5] = 0x00;
 163        radio->buffer[6] = 0x00;
 164        radio->buffer[7] = 0x00;
 165
 166        retval = usb_control_msg(radio->usbdev, usb_sndctrlpipe(radio->usbdev, 0),
 167                                9, 0x21, 0x0300, 0,
 168                                radio->buffer, BUFFER_LENGTH, USB_TIMEOUT);
 169
 170        if (retval < 0)
 171                return retval;
 172
 173        if (stereo == MA901_WANT_STEREO)
 174                radio->stereo = V4L2_TUNER_MODE_STEREO;
 175        else
 176                radio->stereo = V4L2_TUNER_MODE_MONO;
 177
 178        return retval;
 179}
 180
 181/* Handle unplugging the device.
 182 * We call video_unregister_device in any case.
 183 * The last function called in this procedure is
 184 * usb_ma901radio_device_release.
 185 */
 186static void usb_ma901radio_disconnect(struct usb_interface *intf)
 187{
 188        struct ma901radio_device *radio = to_ma901radio_dev(usb_get_intfdata(intf));
 189
 190        mutex_lock(&radio->lock);
 191        video_unregister_device(&radio->vdev);
 192        usb_set_intfdata(intf, NULL);
 193        v4l2_device_disconnect(&radio->v4l2_dev);
 194        mutex_unlock(&radio->lock);
 195        v4l2_device_put(&radio->v4l2_dev);
 196}
 197
 198/* vidioc_querycap - query device capabilities */
 199static int vidioc_querycap(struct file *file, void *priv,
 200                                        struct v4l2_capability *v)
 201{
 202        struct ma901radio_device *radio = video_drvdata(file);
 203
 204        strlcpy(v->driver, "radio-ma901", sizeof(v->driver));
 205        strlcpy(v->card, "Masterkit MA901 USB FM Radio", sizeof(v->card));
 206        usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
 207        v->device_caps = V4L2_CAP_RADIO | V4L2_CAP_TUNER;
 208        v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
 209        return 0;
 210}
 211
 212/* vidioc_g_tuner - get tuner attributes */
 213static int vidioc_g_tuner(struct file *file, void *priv,
 214                                struct v4l2_tuner *v)
 215{
 216        struct ma901radio_device *radio = video_drvdata(file);
 217
 218        if (v->index > 0)
 219                return -EINVAL;
 220
 221        v->signal = 0;
 222
 223        /* TODO: the same words like in _probe() goes here.
 224         * When receiving of stats will be implemented then we can call
 225         * ma901radio_get_stat().
 226         * retval = ma901radio_get_stat(radio, &is_stereo, &v->signal);
 227         */
 228
 229        strcpy(v->name, "FM");
 230        v->type = V4L2_TUNER_RADIO;
 231        v->rangelow = FREQ_MIN * FREQ_MUL;
 232        v->rangehigh = FREQ_MAX * FREQ_MUL;
 233        v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
 234        /* v->rxsubchans = is_stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; */
 235        v->audmode = radio->stereo ?
 236                V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO;
 237        return 0;
 238}
 239
 240/* vidioc_s_tuner - set tuner attributes */
 241static int vidioc_s_tuner(struct file *file, void *priv,
 242                                const struct v4l2_tuner *v)
 243{
 244        struct ma901radio_device *radio = video_drvdata(file);
 245
 246        if (v->index > 0)
 247                return -EINVAL;
 248
 249        /* mono/stereo selector */
 250        switch (v->audmode) {
 251        case V4L2_TUNER_MODE_MONO:
 252                return ma901_set_stereo(radio, MA901_WANT_MONO);
 253        default:
 254                return ma901_set_stereo(radio, MA901_WANT_STEREO);
 255        }
 256}
 257
 258/* vidioc_s_frequency - set tuner radio frequency */
 259static int vidioc_s_frequency(struct file *file, void *priv,
 260                                const struct v4l2_frequency *f)
 261{
 262        struct ma901radio_device *radio = video_drvdata(file);
 263
 264        if (f->tuner != 0)
 265                return -EINVAL;
 266
 267        return ma901radio_set_freq(radio, clamp_t(unsigned, f->frequency,
 268                                FREQ_MIN * FREQ_MUL, FREQ_MAX * FREQ_MUL));
 269}
 270
 271/* vidioc_g_frequency - get tuner radio frequency */
 272static int vidioc_g_frequency(struct file *file, void *priv,
 273                                struct v4l2_frequency *f)
 274{
 275        struct ma901radio_device *radio = video_drvdata(file);
 276
 277        if (f->tuner != 0)
 278                return -EINVAL;
 279        f->frequency = radio->curfreq;
 280
 281        return 0;
 282}
 283
 284static int usb_ma901radio_s_ctrl(struct v4l2_ctrl *ctrl)
 285{
 286        struct ma901radio_device *radio =
 287                container_of(ctrl->handler, struct ma901radio_device, hdl);
 288
 289        switch (ctrl->id) {
 290        case V4L2_CID_AUDIO_VOLUME:     /* set volume */
 291                return ma901radio_set_volume(radio, (u16)ctrl->val);
 292        }
 293
 294        return -EINVAL;
 295}
 296
 297/* TODO: Should we really need to implement suspend and resume functions?
 298 * Radio has it's own memory and will continue playing if power is present
 299 * on usb port and on resume it will start to play again based on freq, volume
 300 * values in device memory.
 301 */
 302static int usb_ma901radio_suspend(struct usb_interface *intf, pm_message_t message)
 303{
 304        return 0;
 305}
 306
 307static int usb_ma901radio_resume(struct usb_interface *intf)
 308{
 309        return 0;
 310}
 311
 312static const struct v4l2_ctrl_ops usb_ma901radio_ctrl_ops = {
 313        .s_ctrl = usb_ma901radio_s_ctrl,
 314};
 315
 316/* File system interface */
 317static const struct v4l2_file_operations usb_ma901radio_fops = {
 318        .owner          = THIS_MODULE,
 319        .open           = v4l2_fh_open,
 320        .release        = v4l2_fh_release,
 321        .poll           = v4l2_ctrl_poll,
 322        .unlocked_ioctl = video_ioctl2,
 323};
 324
 325static const struct v4l2_ioctl_ops usb_ma901radio_ioctl_ops = {
 326        .vidioc_querycap    = vidioc_querycap,
 327        .vidioc_g_tuner     = vidioc_g_tuner,
 328        .vidioc_s_tuner     = vidioc_s_tuner,
 329        .vidioc_g_frequency = vidioc_g_frequency,
 330        .vidioc_s_frequency = vidioc_s_frequency,
 331        .vidioc_log_status  = v4l2_ctrl_log_status,
 332        .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
 333        .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 334};
 335
 336static void usb_ma901radio_release(struct v4l2_device *v4l2_dev)
 337{
 338        struct ma901radio_device *radio = to_ma901radio_dev(v4l2_dev);
 339
 340        v4l2_ctrl_handler_free(&radio->hdl);
 341        v4l2_device_unregister(&radio->v4l2_dev);
 342        kfree(radio->buffer);
 343        kfree(radio);
 344}
 345
 346/* check if the device is present and register with v4l and usb if it is */
 347static int usb_ma901radio_probe(struct usb_interface *intf,
 348                                const struct usb_device_id *id)
 349{
 350        struct usb_device *dev = interface_to_usbdev(intf);
 351        struct ma901radio_device *radio;
 352        int retval = 0;
 353
 354        /* Masterkit MA901 usb radio has the same USB ID as many others
 355         * Atmel V-USB devices. Let's make additional checks to be sure
 356         * that this is our device.
 357         */
 358
 359        if (dev->product && dev->manufacturer &&
 360                (strncmp(dev->product, "MA901", 5) != 0
 361                || strncmp(dev->manufacturer, "www.masterkit.ru", 16) != 0))
 362                return -ENODEV;
 363
 364        radio = kzalloc(sizeof(struct ma901radio_device), GFP_KERNEL);
 365        if (!radio) {
 366                dev_err(&intf->dev, "kzalloc for ma901radio_device failed\n");
 367                retval = -ENOMEM;
 368                goto err;
 369        }
 370
 371        radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL);
 372        if (!radio->buffer) {
 373                dev_err(&intf->dev, "kmalloc for radio->buffer failed\n");
 374                retval = -ENOMEM;
 375                goto err_nobuf;
 376        }
 377
 378        retval = v4l2_device_register(&intf->dev, &radio->v4l2_dev);
 379        if (retval < 0) {
 380                dev_err(&intf->dev, "couldn't register v4l2_device\n");
 381                goto err_v4l2;
 382        }
 383
 384        v4l2_ctrl_handler_init(&radio->hdl, 1);
 385
 386        /* TODO:It looks like this radio doesn't have mute/unmute control
 387         * and windows program just emulate it using volume control.
 388         * Let's plan to do the same in this driver.
 389         *
 390         * v4l2_ctrl_new_std(&radio->hdl, &usb_ma901radio_ctrl_ops,
 391         *                V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
 392         */
 393
 394        v4l2_ctrl_new_std(&radio->hdl, &usb_ma901radio_ctrl_ops,
 395                          V4L2_CID_AUDIO_VOLUME, MA901_VOLUME_MIN,
 396                          MA901_VOLUME_MAX, 1, MA901_VOLUME_MAX);
 397
 398        if (radio->hdl.error) {
 399                retval = radio->hdl.error;
 400                dev_err(&intf->dev, "couldn't register control\n");
 401                goto err_ctrl;
 402        }
 403        mutex_init(&radio->lock);
 404
 405        radio->v4l2_dev.ctrl_handler = &radio->hdl;
 406        radio->v4l2_dev.release = usb_ma901radio_release;
 407        strlcpy(radio->vdev.name, radio->v4l2_dev.name,
 408                sizeof(radio->vdev.name));
 409        radio->vdev.v4l2_dev = &radio->v4l2_dev;
 410        radio->vdev.fops = &usb_ma901radio_fops;
 411        radio->vdev.ioctl_ops = &usb_ma901radio_ioctl_ops;
 412        radio->vdev.release = video_device_release_empty;
 413        radio->vdev.lock = &radio->lock;
 414        set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);
 415
 416        radio->usbdev = interface_to_usbdev(intf);
 417        radio->intf = intf;
 418        usb_set_intfdata(intf, &radio->v4l2_dev);
 419        radio->curfreq = 95.21 * FREQ_MUL;
 420
 421        video_set_drvdata(&radio->vdev, radio);
 422
 423        /* TODO: we can get some statistics (freq, volume) from device
 424         * but it's not implemented yet. After insertion in usb-port radio
 425         * setups frequency and starts playing without any initialization.
 426         * So we don't call usb_ma901radio_init/get_stat() here.
 427         * retval = usb_ma901radio_init(radio);
 428         */
 429
 430        retval = video_register_device(&radio->vdev, VFL_TYPE_RADIO,
 431                                        radio_nr);
 432        if (retval < 0) {
 433                dev_err(&intf->dev, "could not register video device\n");
 434                goto err_vdev;
 435        }
 436
 437        return 0;
 438
 439err_vdev:
 440        v4l2_ctrl_handler_free(&radio->hdl);
 441err_ctrl:
 442        v4l2_device_unregister(&radio->v4l2_dev);
 443err_v4l2:
 444        kfree(radio->buffer);
 445err_nobuf:
 446        kfree(radio);
 447err:
 448        return retval;
 449}
 450
 451/* USB Device ID List */
 452static struct usb_device_id usb_ma901radio_device_table[] = {
 453        { USB_DEVICE_AND_INTERFACE_INFO(USB_MA901_VENDOR, USB_MA901_PRODUCT,
 454                                                        USB_CLASS_HID, 0, 0) },
 455        { }                                             /* Terminating entry */
 456};
 457
 458MODULE_DEVICE_TABLE(usb, usb_ma901radio_device_table);
 459
 460/* USB subsystem interface */
 461static struct usb_driver usb_ma901radio_driver = {
 462        .name                   = MA901_DRIVER_NAME,
 463        .probe                  = usb_ma901radio_probe,
 464        .disconnect             = usb_ma901radio_disconnect,
 465        .suspend                = usb_ma901radio_suspend,
 466        .resume                 = usb_ma901radio_resume,
 467        .reset_resume           = usb_ma901radio_resume,
 468        .id_table               = usb_ma901radio_device_table,
 469};
 470
 471module_usb_driver(usb_ma901radio_driver);
 472