0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>"
0019 #define DRIVER_CARD "Silicon Labs Si470x FM Radio"
0020 #define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
0021 #define DRIVER_VERSION "1.0.10"
0022
0023
0024 #include <linux/usb.h>
0025 #include <linux/hid.h>
0026 #include <linux/slab.h>
0027
0028 #include "radio-si470x.h"
0029
0030
0031
0032 static const struct usb_device_id si470x_usb_driver_id_table[] = {
0033
0034 { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) },
0035
0036 { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) },
0037
0038 { USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) },
0039
0040 { USB_DEVICE_AND_INTERFACE_INFO(0x10c5, 0x819a, USB_CLASS_HID, 0, 0) },
0041
0042 { USB_DEVICE_AND_INTERFACE_INFO(0x12cf, 0x7111, USB_CLASS_HID, 0, 0) },
0043
0044 { }
0045 };
0046 MODULE_DEVICE_TABLE(usb, si470x_usb_driver_id_table);
0047
0048
0049
0050
0051
0052
0053
0054
0055 static int radio_nr = -1;
0056 module_param(radio_nr, int, 0444);
0057 MODULE_PARM_DESC(radio_nr, "Radio Nr");
0058
0059
0060 static unsigned int usb_timeout = 500;
0061 module_param(usb_timeout, uint, 0644);
0062 MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*");
0063
0064
0065 static unsigned int rds_buf = 100;
0066 module_param(rds_buf, uint, 0444);
0067 MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
0068
0069
0070 static unsigned short max_rds_errors = 1;
0071
0072
0073
0074
0075 module_param(max_rds_errors, ushort, 0644);
0076 MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087 #define REGISTER_REPORT_SIZE (RADIO_REGISTER_SIZE + 1)
0088 #define REGISTER_REPORT(reg) ((reg) + 1)
0089
0090
0091
0092 #define ENTIRE_REPORT_SIZE (RADIO_REGISTER_NUM * RADIO_REGISTER_SIZE + 1)
0093 #define ENTIRE_REPORT 17
0094
0095
0096
0097 #define RDS_REPORT_SIZE (RDS_REGISTER_NUM * RADIO_REGISTER_SIZE + 1)
0098 #define RDS_REPORT 18
0099
0100
0101 #define LED_REPORT_SIZE 3
0102 #define LED_REPORT 19
0103
0104
0105 #define STREAM_REPORT_SIZE 3
0106 #define STREAM_REPORT 19
0107
0108
0109 #define SCRATCH_PAGE_SIZE 63
0110 #define SCRATCH_REPORT_SIZE (SCRATCH_PAGE_SIZE + 1)
0111 #define SCRATCH_REPORT 20
0112
0113
0114 #define WRITE_REPORT_SIZE 4
0115 #define WRITE_REPORT 19
0116 #define FLASH_REPORT_SIZE 64
0117 #define FLASH_REPORT 20
0118 #define CRC_REPORT_SIZE 3
0119 #define CRC_REPORT 21
0120 #define RESPONSE_REPORT_SIZE 2
0121 #define RESPONSE_REPORT 22
0122
0123
0124
0125 #define UNUSED_REPORT 23
0126
0127 #define MAX_REPORT_SIZE 64
0128
0129
0130
0131
0132
0133
0134 #define RADIO_HW_VERSION 1
0135
0136
0137
0138
0139
0140
0141 #define LED_COMMAND 0x35
0142
0143 #define NO_CHANGE_LED 0x00
0144 #define ALL_COLOR_LED 0x01
0145 #define BLINK_GREEN_LED 0x02
0146 #define BLINK_RED_LED 0x04
0147 #define BLINK_ORANGE_LED 0x10
0148 #define SOLID_GREEN_LED 0x20
0149 #define SOLID_RED_LED 0x40
0150 #define SOLID_ORANGE_LED 0x80
0151
0152
0153
0154
0155
0156
0157 #define STREAM_COMMAND 0x36
0158 #define STREAM_VIDPID 0x00
0159 #define STREAM_AUDIO 0xff
0160
0161
0162
0163
0164
0165
0166
0167
0168 #define UNIQUE_BL_ID 0x34
0169
0170
0171 #define FLASH_DATA_MASK 0x55
0172
0173
0174 #define GET_SW_VERSION_COMMAND 0x00
0175 #define SET_PAGE_COMMAND 0x01
0176 #define ERASE_PAGE_COMMAND 0x02
0177 #define WRITE_PAGE_COMMAND 0x03
0178 #define CRC_ON_PAGE_COMMAND 0x04
0179 #define READ_FLASH_BYTE_COMMAND 0x05
0180 #define RESET_DEVICE_COMMAND 0x06
0181 #define GET_HW_VERSION_COMMAND 0x07
0182 #define BLANK 0xff
0183
0184
0185 #define COMMAND_OK 0x01
0186 #define COMMAND_FAILED 0x02
0187 #define COMMAND_PENDING 0x03
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198 static int si470x_get_report(struct si470x_device *radio, void *buf, int size)
0199 {
0200 unsigned char *report = buf;
0201 int retval;
0202
0203 retval = usb_control_msg(radio->usbdev,
0204 usb_rcvctrlpipe(radio->usbdev, 0),
0205 HID_REQ_GET_REPORT,
0206 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
0207 report[0], 2,
0208 buf, size, usb_timeout);
0209
0210 if (retval < 0)
0211 dev_warn(&radio->intf->dev,
0212 "si470x_get_report: usb_control_msg returned %d\n",
0213 retval);
0214 return retval;
0215 }
0216
0217
0218
0219
0220
0221 static int si470x_set_report(struct si470x_device *radio, void *buf, int size)
0222 {
0223 unsigned char *report = buf;
0224 int retval;
0225
0226 retval = usb_control_msg(radio->usbdev,
0227 usb_sndctrlpipe(radio->usbdev, 0),
0228 HID_REQ_SET_REPORT,
0229 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
0230 report[0], 2,
0231 buf, size, usb_timeout);
0232
0233 if (retval < 0)
0234 dev_warn(&radio->intf->dev,
0235 "si470x_set_report: usb_control_msg returned %d\n",
0236 retval);
0237 return retval;
0238 }
0239
0240
0241
0242
0243
0244 static int si470x_get_register(struct si470x_device *radio, int regnr)
0245 {
0246 int retval;
0247
0248 radio->usb_buf[0] = REGISTER_REPORT(regnr);
0249
0250 retval = si470x_get_report(radio, radio->usb_buf, REGISTER_REPORT_SIZE);
0251
0252 if (retval >= 0)
0253 radio->registers[regnr] = get_unaligned_be16(&radio->usb_buf[1]);
0254
0255 return (retval < 0) ? -EINVAL : 0;
0256 }
0257
0258
0259
0260
0261
0262 static int si470x_set_register(struct si470x_device *radio, int regnr)
0263 {
0264 int retval;
0265
0266 radio->usb_buf[0] = REGISTER_REPORT(regnr);
0267 put_unaligned_be16(radio->registers[regnr], &radio->usb_buf[1]);
0268
0269 retval = si470x_set_report(radio, radio->usb_buf, REGISTER_REPORT_SIZE);
0270
0271 return (retval < 0) ? -EINVAL : 0;
0272 }
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283 static int si470x_get_all_registers(struct si470x_device *radio)
0284 {
0285 int retval;
0286 unsigned char regnr;
0287
0288 radio->usb_buf[0] = ENTIRE_REPORT;
0289
0290 retval = si470x_get_report(radio, radio->usb_buf, ENTIRE_REPORT_SIZE);
0291
0292 if (retval >= 0)
0293 for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
0294 radio->registers[regnr] = get_unaligned_be16(
0295 &radio->usb_buf[regnr * RADIO_REGISTER_SIZE + 1]);
0296
0297 return (retval < 0) ? -EINVAL : 0;
0298 }
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309 static int si470x_set_led_state(struct si470x_device *radio,
0310 unsigned char led_state)
0311 {
0312 int retval;
0313
0314 radio->usb_buf[0] = LED_REPORT;
0315 radio->usb_buf[1] = LED_COMMAND;
0316 radio->usb_buf[2] = led_state;
0317
0318 retval = si470x_set_report(radio, radio->usb_buf, LED_REPORT_SIZE);
0319
0320 return (retval < 0) ? -EINVAL : 0;
0321 }
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332 static int si470x_get_scratch_page_versions(struct si470x_device *radio)
0333 {
0334 int retval;
0335
0336 radio->usb_buf[0] = SCRATCH_REPORT;
0337
0338 retval = si470x_get_report(radio, radio->usb_buf, SCRATCH_REPORT_SIZE);
0339
0340 if (retval < 0)
0341 dev_warn(&radio->intf->dev, "si470x_get_scratch: si470x_get_report returned %d\n",
0342 retval);
0343 else {
0344 radio->software_version = radio->usb_buf[1];
0345 radio->hardware_version = radio->usb_buf[2];
0346 }
0347
0348 return (retval < 0) ? -EINVAL : 0;
0349 }
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362 static void si470x_int_in_callback(struct urb *urb)
0363 {
0364 struct si470x_device *radio = urb->context;
0365 int retval;
0366 unsigned char regnr;
0367 unsigned char blocknum;
0368 unsigned short bler;
0369 unsigned short rds;
0370 unsigned char tmpbuf[3];
0371
0372 if (urb->status) {
0373 if (urb->status == -ENOENT ||
0374 urb->status == -ECONNRESET ||
0375 urb->status == -ESHUTDOWN) {
0376 return;
0377 } else {
0378 dev_warn(&radio->intf->dev,
0379 "non-zero urb status (%d)\n", urb->status);
0380 goto resubmit;
0381 }
0382 }
0383
0384
0385 if (urb->actual_length != RDS_REPORT_SIZE)
0386 goto resubmit;
0387
0388 radio->registers[STATUSRSSI] =
0389 get_unaligned_be16(&radio->int_in_buffer[1]);
0390
0391 if (radio->registers[STATUSRSSI] & STATUSRSSI_STC)
0392 complete(&radio->completion);
0393
0394 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS)) {
0395
0396 for (regnr = 1; regnr < RDS_REGISTER_NUM; regnr++)
0397 radio->registers[STATUSRSSI + regnr] =
0398 get_unaligned_be16(&radio->int_in_buffer[
0399 regnr * RADIO_REGISTER_SIZE + 1]);
0400
0401 if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0) {
0402
0403 goto resubmit;
0404 }
0405 if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSS) == 0) {
0406
0407 goto resubmit;
0408 }
0409 for (blocknum = 0; blocknum < 4; blocknum++) {
0410 switch (blocknum) {
0411 default:
0412 bler = (radio->registers[STATUSRSSI] &
0413 STATUSRSSI_BLERA) >> 9;
0414 rds = radio->registers[RDSA];
0415 break;
0416 case 1:
0417 bler = (radio->registers[READCHAN] &
0418 READCHAN_BLERB) >> 14;
0419 rds = radio->registers[RDSB];
0420 break;
0421 case 2:
0422 bler = (radio->registers[READCHAN] &
0423 READCHAN_BLERC) >> 12;
0424 rds = radio->registers[RDSC];
0425 break;
0426 case 3:
0427 bler = (radio->registers[READCHAN] &
0428 READCHAN_BLERD) >> 10;
0429 rds = radio->registers[RDSD];
0430 break;
0431 }
0432
0433
0434 put_unaligned_le16(rds, &tmpbuf);
0435 tmpbuf[2] = blocknum;
0436 tmpbuf[2] |= blocknum << 3;
0437 if (bler > max_rds_errors)
0438 tmpbuf[2] |= 0x80;
0439 else if (bler > 0)
0440 tmpbuf[2] |= 0x40;
0441
0442
0443 memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3);
0444 radio->wr_index += 3;
0445
0446
0447 if (radio->wr_index >= radio->buf_size)
0448 radio->wr_index = 0;
0449
0450
0451 if (radio->wr_index == radio->rd_index) {
0452
0453 radio->rd_index += 3;
0454 if (radio->rd_index >= radio->buf_size)
0455 radio->rd_index = 0;
0456 }
0457 }
0458 if (radio->wr_index != radio->rd_index)
0459 wake_up_interruptible(&radio->read_queue);
0460 }
0461
0462 resubmit:
0463
0464 if (radio->int_in_running && radio->usbdev) {
0465 retval = usb_submit_urb(radio->int_in_urb, GFP_ATOMIC);
0466 if (retval) {
0467 dev_warn(&radio->intf->dev,
0468 "resubmitting urb failed (%d)", retval);
0469 radio->int_in_running = 0;
0470 }
0471 }
0472 radio->status_rssi_auto_update = radio->int_in_running;
0473 }
0474
0475
0476 static int si470x_fops_open(struct file *file)
0477 {
0478 return v4l2_fh_open(file);
0479 }
0480
0481 static int si470x_fops_release(struct file *file)
0482 {
0483 return v4l2_fh_release(file);
0484 }
0485
0486 static void si470x_usb_release(struct v4l2_device *v4l2_dev)
0487 {
0488 struct si470x_device *radio =
0489 container_of(v4l2_dev, struct si470x_device, v4l2_dev);
0490
0491 usb_free_urb(radio->int_in_urb);
0492 v4l2_ctrl_handler_free(&radio->hdl);
0493 v4l2_device_unregister(&radio->v4l2_dev);
0494 kfree(radio->int_in_buffer);
0495 kfree(radio->buffer);
0496 kfree(radio->usb_buf);
0497 kfree(radio);
0498 }
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508 static int si470x_vidioc_querycap(struct file *file, void *priv,
0509 struct v4l2_capability *capability)
0510 {
0511 struct si470x_device *radio = video_drvdata(file);
0512
0513 strscpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
0514 strscpy(capability->card, DRIVER_CARD, sizeof(capability->card));
0515 usb_make_path(radio->usbdev, capability->bus_info,
0516 sizeof(capability->bus_info));
0517 return 0;
0518 }
0519
0520
0521 static int si470x_start_usb(struct si470x_device *radio)
0522 {
0523 int retval;
0524
0525
0526 usb_fill_int_urb(radio->int_in_urb, radio->usbdev,
0527 usb_rcvintpipe(radio->usbdev,
0528 radio->int_in_endpoint->bEndpointAddress),
0529 radio->int_in_buffer,
0530 le16_to_cpu(radio->int_in_endpoint->wMaxPacketSize),
0531 si470x_int_in_callback,
0532 radio,
0533 radio->int_in_endpoint->bInterval);
0534
0535 radio->int_in_running = 1;
0536 mb();
0537
0538 retval = usb_submit_urb(radio->int_in_urb, GFP_KERNEL);
0539 if (retval) {
0540 dev_info(&radio->intf->dev,
0541 "submitting int urb failed (%d)\n", retval);
0542 radio->int_in_running = 0;
0543 }
0544 radio->status_rssi_auto_update = radio->int_in_running;
0545
0546
0547 retval = si470x_start(radio);
0548 if (retval < 0)
0549 return retval;
0550
0551 v4l2_ctrl_handler_setup(&radio->hdl);
0552
0553 return retval;
0554 }
0555
0556
0557
0558
0559
0560
0561
0562
0563 static int si470x_usb_driver_probe(struct usb_interface *intf,
0564 const struct usb_device_id *id)
0565 {
0566 struct si470x_device *radio;
0567 struct usb_host_interface *iface_desc;
0568 struct usb_endpoint_descriptor *endpoint;
0569 int i, int_end_size, retval;
0570 unsigned char version_warning = 0;
0571
0572
0573 radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL);
0574 if (!radio) {
0575 retval = -ENOMEM;
0576 goto err_initial;
0577 }
0578 radio->usb_buf = kmalloc(MAX_REPORT_SIZE, GFP_KERNEL);
0579 if (radio->usb_buf == NULL) {
0580 retval = -ENOMEM;
0581 goto err_radio;
0582 }
0583 radio->usbdev = interface_to_usbdev(intf);
0584 radio->intf = intf;
0585 radio->band = 1;
0586 mutex_init(&radio->lock);
0587 init_completion(&radio->completion);
0588
0589 radio->get_register = si470x_get_register;
0590 radio->set_register = si470x_set_register;
0591 radio->fops_open = si470x_fops_open;
0592 radio->fops_release = si470x_fops_release;
0593 radio->vidioc_querycap = si470x_vidioc_querycap;
0594
0595 iface_desc = intf->cur_altsetting;
0596
0597
0598 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
0599 endpoint = &iface_desc->endpoint[i].desc;
0600 if (usb_endpoint_is_int_in(endpoint))
0601 radio->int_in_endpoint = endpoint;
0602 }
0603 if (!radio->int_in_endpoint) {
0604 dev_info(&intf->dev, "could not find interrupt in endpoint\n");
0605 retval = -EIO;
0606 goto err_usbbuf;
0607 }
0608
0609 int_end_size = le16_to_cpu(radio->int_in_endpoint->wMaxPacketSize);
0610
0611 radio->int_in_buffer = kmalloc(int_end_size, GFP_KERNEL);
0612 if (!radio->int_in_buffer) {
0613 dev_info(&intf->dev, "could not allocate int_in_buffer");
0614 retval = -ENOMEM;
0615 goto err_usbbuf;
0616 }
0617
0618 radio->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
0619 if (!radio->int_in_urb) {
0620 retval = -ENOMEM;
0621 goto err_intbuffer;
0622 }
0623
0624 radio->v4l2_dev.release = si470x_usb_release;
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634 if (id->idVendor == 0x10c4 && id->idProduct == 0x818a) {
0635 retval = usb_control_msg(radio->usbdev,
0636 usb_rcvctrlpipe(radio->usbdev, 0),
0637 HID_REQ_GET_REPORT,
0638 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
0639 1, 2,
0640 radio->usb_buf, 3, 500);
0641 if (retval != 3 ||
0642 (get_unaligned_be16(&radio->usb_buf[1]) & 0xfff) != 0x0242) {
0643 dev_info(&intf->dev, "this is not a si470x device.\n");
0644 retval = -ENODEV;
0645 goto err_urb;
0646 }
0647 }
0648
0649 retval = v4l2_device_register(&intf->dev, &radio->v4l2_dev);
0650 if (retval < 0) {
0651 dev_err(&intf->dev, "couldn't register v4l2_device\n");
0652 goto err_urb;
0653 }
0654
0655 v4l2_ctrl_handler_init(&radio->hdl, 2);
0656 v4l2_ctrl_new_std(&radio->hdl, &si470x_ctrl_ops,
0657 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
0658 v4l2_ctrl_new_std(&radio->hdl, &si470x_ctrl_ops,
0659 V4L2_CID_AUDIO_VOLUME, 0, 15, 1, 15);
0660 if (radio->hdl.error) {
0661 retval = radio->hdl.error;
0662 dev_err(&intf->dev, "couldn't register control\n");
0663 goto err_dev;
0664 }
0665 radio->videodev = si470x_viddev_template;
0666 radio->videodev.ctrl_handler = &radio->hdl;
0667 radio->videodev.lock = &radio->lock;
0668 radio->videodev.v4l2_dev = &radio->v4l2_dev;
0669 radio->videodev.release = video_device_release_empty;
0670 radio->videodev.device_caps =
0671 V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_READWRITE | V4L2_CAP_TUNER |
0672 V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE;
0673 video_set_drvdata(&radio->videodev, radio);
0674
0675
0676 if (si470x_get_all_registers(radio) < 0) {
0677 retval = -EIO;
0678 goto err_ctrl;
0679 }
0680 dev_info(&intf->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
0681 radio->registers[DEVICEID], radio->registers[SI_CHIPID]);
0682 if ((radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE) < RADIO_FW_VERSION) {
0683 dev_warn(&intf->dev,
0684 "This driver is known to work with firmware version %u, but the device has firmware version %u.\n",
0685 RADIO_FW_VERSION,
0686 radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE);
0687 version_warning = 1;
0688 }
0689
0690
0691 if (si470x_get_scratch_page_versions(radio) < 0) {
0692 retval = -EIO;
0693 goto err_ctrl;
0694 }
0695 dev_info(&intf->dev, "software version %d, hardware version %d\n",
0696 radio->software_version, radio->hardware_version);
0697 if (radio->hardware_version < RADIO_HW_VERSION) {
0698 dev_warn(&intf->dev,
0699 "This driver is known to work with hardware version %u, but the device has hardware version %u.\n",
0700 RADIO_HW_VERSION,
0701 radio->hardware_version);
0702 version_warning = 1;
0703 }
0704
0705
0706 if (version_warning == 1) {
0707 dev_warn(&intf->dev,
0708 "If you have some trouble using this driver, please report to V4L ML at linux-media@vger.kernel.org\n");
0709 }
0710
0711
0712 si470x_set_led_state(radio, BLINK_GREEN_LED);
0713
0714
0715 radio->buf_size = rds_buf * 3;
0716 radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
0717 if (!radio->buffer) {
0718 retval = -EIO;
0719 goto err_ctrl;
0720 }
0721
0722
0723 radio->wr_index = 0;
0724 radio->rd_index = 0;
0725 init_waitqueue_head(&radio->read_queue);
0726 usb_set_intfdata(intf, radio);
0727
0728
0729 retval = si470x_start_usb(radio);
0730 if (retval < 0)
0731 goto err_buf;
0732
0733
0734 si470x_set_freq(radio, 87.5 * FREQ_MUL);
0735
0736
0737 retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO,
0738 radio_nr);
0739 if (retval) {
0740 dev_err(&intf->dev, "Could not register video device\n");
0741 goto err_all;
0742 }
0743
0744 return 0;
0745 err_all:
0746 usb_kill_urb(radio->int_in_urb);
0747 err_buf:
0748 kfree(radio->buffer);
0749 err_ctrl:
0750 v4l2_ctrl_handler_free(&radio->hdl);
0751 err_dev:
0752 v4l2_device_unregister(&radio->v4l2_dev);
0753 err_urb:
0754 usb_free_urb(radio->int_in_urb);
0755 err_intbuffer:
0756 kfree(radio->int_in_buffer);
0757 err_usbbuf:
0758 kfree(radio->usb_buf);
0759 err_radio:
0760 kfree(radio);
0761 err_initial:
0762 return retval;
0763 }
0764
0765
0766
0767
0768
0769 static int si470x_usb_driver_suspend(struct usb_interface *intf,
0770 pm_message_t message)
0771 {
0772 struct si470x_device *radio = usb_get_intfdata(intf);
0773
0774 dev_info(&intf->dev, "suspending now...\n");
0775
0776
0777 if (radio->int_in_running) {
0778 radio->int_in_running = 0;
0779 if (radio->int_in_urb)
0780 usb_kill_urb(radio->int_in_urb);
0781 }
0782
0783
0784 wake_up_interruptible(&radio->read_queue);
0785
0786
0787 si470x_stop(radio);
0788 return 0;
0789 }
0790
0791
0792
0793
0794
0795 static int si470x_usb_driver_resume(struct usb_interface *intf)
0796 {
0797 struct si470x_device *radio = usb_get_intfdata(intf);
0798 int ret;
0799
0800 dev_info(&intf->dev, "resuming now...\n");
0801
0802
0803 ret = si470x_start_usb(radio);
0804 if (ret == 0)
0805 v4l2_ctrl_handler_setup(&radio->hdl);
0806
0807 return ret;
0808 }
0809
0810
0811
0812
0813
0814 static void si470x_usb_driver_disconnect(struct usb_interface *intf)
0815 {
0816 struct si470x_device *radio = usb_get_intfdata(intf);
0817
0818 mutex_lock(&radio->lock);
0819 v4l2_device_disconnect(&radio->v4l2_dev);
0820 video_unregister_device(&radio->videodev);
0821 usb_kill_urb(radio->int_in_urb);
0822 usb_set_intfdata(intf, NULL);
0823 mutex_unlock(&radio->lock);
0824 v4l2_device_put(&radio->v4l2_dev);
0825 }
0826
0827
0828
0829
0830
0831
0832
0833
0834
0835
0836
0837 static struct usb_driver si470x_usb_driver = {
0838 .name = DRIVER_NAME,
0839 .probe = si470x_usb_driver_probe,
0840 .disconnect = si470x_usb_driver_disconnect,
0841 .suspend = si470x_usb_driver_suspend,
0842 .resume = si470x_usb_driver_resume,
0843 .reset_resume = si470x_usb_driver_resume,
0844 .id_table = si470x_usb_driver_id_table,
0845 };
0846
0847 module_usb_driver(si470x_usb_driver);
0848
0849 MODULE_LICENSE("GPL");
0850 MODULE_AUTHOR(DRIVER_AUTHOR);
0851 MODULE_DESCRIPTION(DRIVER_DESC);
0852 MODULE_VERSION(DRIVER_VERSION);