1 /**************************************************************** 2 3 Siano Mobile Silicon, Inc. 4 MDTV receiver kernel modules. 5 Copyright (C) 2005-2009, Uri Shkolnik, Anatoly Greenblat 6 7 This program is free software: you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation, either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. 19 20 ****************************************************************/ 21 22 #include "smscoreapi.h" 23 24 #include <linux/kernel.h> 25 #include <linux/init.h> 26 #include <linux/usb.h> 27 #include <linux/firmware.h> 28 #include <linux/slab.h> 29 #include <linux/module.h> 30 #include <media/media-device.h> 31 32 #include "sms-cards.h" 33 #include "smsendian.h" 34 35 #define USB1_BUFFER_SIZE 0x1000 36 #define USB2_BUFFER_SIZE 0x2000 37 38 #define MAX_BUFFERS 50 39 #define MAX_URBS 10 40 41 struct smsusb_device_t; 42 43 enum smsusb_state { 44 SMSUSB_DISCONNECTED, 45 SMSUSB_SUSPENDED, 46 SMSUSB_ACTIVE 47 }; 48 49 struct smsusb_urb_t { 50 struct list_head entry; 51 struct smscore_buffer_t *cb; 52 struct smsusb_device_t *dev; 53 54 struct urb urb; 55 56 /* For the bottom half */ 57 struct work_struct wq; 58 }; 59 60 struct smsusb_device_t { 61 struct usb_device *udev; 62 struct smscore_device_t *coredev; 63 64 struct smsusb_urb_t surbs[MAX_URBS]; 65 66 int response_alignment; 67 int buffer_size; 68 69 unsigned char in_ep; 70 unsigned char out_ep; 71 enum smsusb_state state; 72 }; 73 74 static int smsusb_submit_urb(struct smsusb_device_t *dev, 75 struct smsusb_urb_t *surb); 76 77 /* 78 * Completing URB's callback handler - bottom half (proccess context) 79 * submits the URB prepared on smsusb_onresponse() 80 */ 81 static void do_submit_urb(struct work_struct *work) 82 { 83 struct smsusb_urb_t *surb = container_of(work, struct smsusb_urb_t, wq); 84 struct smsusb_device_t *dev = surb->dev; 85 86 smsusb_submit_urb(dev, surb); 87 } 88 89 /* 90 * Completing URB's callback handler - top half (interrupt context) 91 * adds completing sms urb to the global surbs list and activtes the worker 92 * thread the surb 93 * IMPORTANT - blocking functions must not be called from here !!! 94 95 * @param urb pointer to a completing urb object 96 */ 97 static void smsusb_onresponse(struct urb *urb) 98 { 99 struct smsusb_urb_t *surb = (struct smsusb_urb_t *) urb->context; 100 struct smsusb_device_t *dev = surb->dev; 101 102 if (urb->status == -ESHUTDOWN) { 103 pr_err("error, urb status %d (-ESHUTDOWN), %d bytes\n", 104 urb->status, urb->actual_length); 105 return; 106 } 107 108 if ((urb->actual_length > 0) && (urb->status == 0)) { 109 struct sms_msg_hdr *phdr = (struct sms_msg_hdr *)surb->cb->p; 110 111 smsendian_handle_message_header(phdr); 112 if (urb->actual_length >= phdr->msg_length) { 113 surb->cb->size = phdr->msg_length; 114 115 if (dev->response_alignment && 116 (phdr->msg_flags & MSG_HDR_FLAG_SPLIT_MSG)) { 117 118 surb->cb->offset = 119 dev->response_alignment + 120 ((phdr->msg_flags >> 8) & 3); 121 122 /* sanity check */ 123 if (((int) phdr->msg_length + 124 surb->cb->offset) > urb->actual_length) { 125 pr_err("invalid response msglen %d offset %d size %d\n", 126 phdr->msg_length, 127 surb->cb->offset, 128 urb->actual_length); 129 goto exit_and_resubmit; 130 } 131 132 /* move buffer pointer and 133 * copy header to its new location */ 134 memcpy((char *) phdr + surb->cb->offset, 135 phdr, sizeof(struct sms_msg_hdr)); 136 } else 137 surb->cb->offset = 0; 138 139 pr_debug("received %s(%d) size: %d\n", 140 smscore_translate_msg(phdr->msg_type), 141 phdr->msg_type, phdr->msg_length); 142 143 smsendian_handle_rx_message((struct sms_msg_data *) phdr); 144 145 smscore_onresponse(dev->coredev, surb->cb); 146 surb->cb = NULL; 147 } else { 148 pr_err("invalid response msglen %d actual %d\n", 149 phdr->msg_length, urb->actual_length); 150 } 151 } else 152 pr_err("error, urb status %d, %d bytes\n", 153 urb->status, urb->actual_length); 154 155 156 exit_and_resubmit: 157 INIT_WORK(&surb->wq, do_submit_urb); 158 schedule_work(&surb->wq); 159 } 160 161 static int smsusb_submit_urb(struct smsusb_device_t *dev, 162 struct smsusb_urb_t *surb) 163 { 164 if (!surb->cb) { 165 /* This function can sleep */ 166 surb->cb = smscore_getbuffer(dev->coredev); 167 if (!surb->cb) { 168 pr_err("smscore_getbuffer(...) returned NULL\n"); 169 return -ENOMEM; 170 } 171 } 172 173 usb_fill_bulk_urb( 174 &surb->urb, 175 dev->udev, 176 usb_rcvbulkpipe(dev->udev, dev->in_ep), 177 surb->cb->p, 178 dev->buffer_size, 179 smsusb_onresponse, 180 surb 181 ); 182 surb->urb.transfer_dma = surb->cb->phys; 183 surb->urb.transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 184 185 return usb_submit_urb(&surb->urb, GFP_ATOMIC); 186 } 187 188 static void smsusb_stop_streaming(struct smsusb_device_t *dev) 189 { 190 int i; 191 192 for (i = 0; i < MAX_URBS; i++) { 193 usb_kill_urb(&dev->surbs[i].urb); 194 195 if (dev->surbs[i].cb) { 196 smscore_putbuffer(dev->coredev, dev->surbs[i].cb); 197 dev->surbs[i].cb = NULL; 198 } 199 } 200 } 201 202 static int smsusb_start_streaming(struct smsusb_device_t *dev) 203 { 204 int i, rc; 205 206 for (i = 0; i < MAX_URBS; i++) { 207 rc = smsusb_submit_urb(dev, &dev->surbs[i]); 208 if (rc < 0) { 209 pr_err("smsusb_submit_urb(...) failed\n"); 210 smsusb_stop_streaming(dev); 211 break; 212 } 213 } 214 215 return rc; 216 } 217 218 static int smsusb_sendrequest(void *context, void *buffer, size_t size) 219 { 220 struct smsusb_device_t *dev = (struct smsusb_device_t *) context; 221 struct sms_msg_hdr *phdr; 222 int dummy, ret; 223 224 if (dev->state != SMSUSB_ACTIVE) { 225 pr_debug("Device not active yet\n"); 226 return -ENOENT; 227 } 228 229 phdr = kmalloc(size, GFP_KERNEL); 230 if (!phdr) 231 return -ENOMEM; 232 memcpy(phdr, buffer, size); 233 234 pr_debug("sending %s(%d) size: %d\n", 235 smscore_translate_msg(phdr->msg_type), phdr->msg_type, 236 phdr->msg_length); 237 238 smsendian_handle_tx_message((struct sms_msg_data *) phdr); 239 smsendian_handle_message_header((struct sms_msg_hdr *)phdr); 240 ret = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), 241 phdr, size, &dummy, 1000); 242 243 kfree(phdr); 244 return ret; 245 } 246 247 static char *smsusb1_fw_lkup[] = { 248 "dvbt_stellar_usb.inp", 249 "dvbh_stellar_usb.inp", 250 "tdmb_stellar_usb.inp", 251 "none", 252 "dvbt_bda_stellar_usb.inp", 253 }; 254 255 static inline char *sms_get_fw_name(int mode, int board_id) 256 { 257 char **fw = sms_get_board(board_id)->fw; 258 return (fw && fw[mode]) ? fw[mode] : smsusb1_fw_lkup[mode]; 259 } 260 261 static int smsusb1_load_firmware(struct usb_device *udev, int id, int board_id) 262 { 263 const struct firmware *fw; 264 u8 *fw_buffer; 265 int rc, dummy; 266 char *fw_filename; 267 268 if (id < 0) 269 id = sms_get_board(board_id)->default_mode; 270 271 if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) { 272 pr_err("invalid firmware id specified %d\n", id); 273 return -EINVAL; 274 } 275 276 fw_filename = sms_get_fw_name(id, board_id); 277 278 rc = request_firmware(&fw, fw_filename, &udev->dev); 279 if (rc < 0) { 280 pr_warn("failed to open '%s' mode %d, trying again with default firmware\n", 281 fw_filename, id); 282 283 fw_filename = smsusb1_fw_lkup[id]; 284 rc = request_firmware(&fw, fw_filename, &udev->dev); 285 if (rc < 0) { 286 pr_warn("failed to open '%s' mode %d\n", 287 fw_filename, id); 288 289 return rc; 290 } 291 } 292 293 fw_buffer = kmalloc(fw->size, GFP_KERNEL); 294 if (fw_buffer) { 295 memcpy(fw_buffer, fw->data, fw->size); 296 297 rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2), 298 fw_buffer, fw->size, &dummy, 1000); 299 300 pr_debug("sent %zu(%d) bytes, rc %d\n", fw->size, dummy, rc); 301 302 kfree(fw_buffer); 303 } else { 304 pr_err("failed to allocate firmware buffer\n"); 305 rc = -ENOMEM; 306 } 307 pr_debug("read FW %s, size=%zu\n", fw_filename, fw->size); 308 309 release_firmware(fw); 310 311 return rc; 312 } 313 314 static void smsusb1_detectmode(void *context, int *mode) 315 { 316 char *product_string = 317 ((struct smsusb_device_t *) context)->udev->product; 318 319 *mode = DEVICE_MODE_NONE; 320 321 if (!product_string) { 322 product_string = "none"; 323 pr_err("product string not found\n"); 324 } else if (strstr(product_string, "DVBH")) 325 *mode = 1; 326 else if (strstr(product_string, "BDA")) 327 *mode = 4; 328 else if (strstr(product_string, "DVBT")) 329 *mode = 0; 330 else if (strstr(product_string, "TDMB")) 331 *mode = 2; 332 333 pr_debug("%d \"%s\"\n", *mode, product_string); 334 } 335 336 static int smsusb1_setmode(void *context, int mode) 337 { 338 struct sms_msg_hdr msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK, 339 sizeof(struct sms_msg_hdr), 0 }; 340 341 if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { 342 pr_err("invalid firmware id specified %d\n", mode); 343 return -EINVAL; 344 } 345 346 return smsusb_sendrequest(context, &msg, sizeof(msg)); 347 } 348 349 static void smsusb_term_device(struct usb_interface *intf) 350 { 351 struct smsusb_device_t *dev = usb_get_intfdata(intf); 352 353 if (dev) { 354 dev->state = SMSUSB_DISCONNECTED; 355 356 smsusb_stop_streaming(dev); 357 358 /* unregister from smscore */ 359 if (dev->coredev) 360 smscore_unregister_device(dev->coredev); 361 362 pr_debug("device 0x%p destroyed\n", dev); 363 kfree(dev); 364 } 365 366 usb_set_intfdata(intf, NULL); 367 } 368 369 static void *siano_media_device_register(struct smsusb_device_t *dev, 370 int board_id) 371 { 372 #ifdef CONFIG_MEDIA_CONTROLLER_DVB 373 struct media_device *mdev; 374 struct usb_device *udev = dev->udev; 375 struct sms_board *board = sms_get_board(board_id); 376 int ret; 377 378 mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); 379 if (!mdev) 380 return NULL; 381 382 media_device_usb_init(mdev, udev, board->name); 383 384 ret = media_device_register(mdev); 385 if (ret) { 386 media_device_cleanup(mdev); 387 kfree(mdev); 388 return NULL; 389 } 390 391 pr_info("media controller created\n"); 392 393 return mdev; 394 #else 395 return NULL; 396 #endif 397 } 398 399 static int smsusb_init_device(struct usb_interface *intf, int board_id) 400 { 401 struct smsdevice_params_t params; 402 struct smsusb_device_t *dev; 403 void *mdev; 404 int i, rc; 405 406 /* create device object */ 407 dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL); 408 if (!dev) 409 return -ENOMEM; 410 411 memset(¶ms, 0, sizeof(params)); 412 usb_set_intfdata(intf, dev); 413 dev->udev = interface_to_usbdev(intf); 414 dev->state = SMSUSB_DISCONNECTED; 415 416 params.device_type = sms_get_board(board_id)->type; 417 418 switch (params.device_type) { 419 case SMS_STELLAR: 420 dev->buffer_size = USB1_BUFFER_SIZE; 421 422 params.setmode_handler = smsusb1_setmode; 423 params.detectmode_handler = smsusb1_detectmode; 424 break; 425 case SMS_UNKNOWN_TYPE: 426 pr_err("Unspecified sms device type!\n"); 427 /* fall-thru */ 428 default: 429 dev->buffer_size = USB2_BUFFER_SIZE; 430 dev->response_alignment = 431 le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) - 432 sizeof(struct sms_msg_hdr); 433 434 params.flags |= SMS_DEVICE_FAMILY2; 435 break; 436 } 437 438 for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { 439 if (intf->cur_altsetting->endpoint[i].desc. bEndpointAddress & USB_DIR_IN) 440 dev->in_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress; 441 else 442 dev->out_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress; 443 } 444 445 pr_debug("in_ep = %02x, out_ep = %02x\n", 446 dev->in_ep, dev->out_ep); 447 448 params.device = &dev->udev->dev; 449 params.buffer_size = dev->buffer_size; 450 params.num_buffers = MAX_BUFFERS; 451 params.sendrequest_handler = smsusb_sendrequest; 452 params.context = dev; 453 usb_make_path(dev->udev, params.devpath, sizeof(params.devpath)); 454 455 mdev = siano_media_device_register(dev, board_id); 456 457 /* register in smscore */ 458 rc = smscore_register_device(¶ms, &dev->coredev, mdev); 459 if (rc < 0) { 460 pr_err("smscore_register_device(...) failed, rc %d\n", rc); 461 smsusb_term_device(intf); 462 #ifdef CONFIG_MEDIA_CONTROLLER_DVB 463 media_device_unregister(mdev); 464 #endif 465 kfree(mdev); 466 return rc; 467 } 468 469 smscore_set_board_id(dev->coredev, board_id); 470 471 dev->coredev->is_usb_device = true; 472 473 /* initialize urbs */ 474 for (i = 0; i < MAX_URBS; i++) { 475 dev->surbs[i].dev = dev; 476 usb_init_urb(&dev->surbs[i].urb); 477 } 478 479 pr_debug("smsusb_start_streaming(...).\n"); 480 rc = smsusb_start_streaming(dev); 481 if (rc < 0) { 482 pr_err("smsusb_start_streaming(...) failed\n"); 483 smsusb_term_device(intf); 484 return rc; 485 } 486 487 dev->state = SMSUSB_ACTIVE; 488 489 rc = smscore_start_device(dev->coredev); 490 if (rc < 0) { 491 pr_err("smscore_start_device(...) failed\n"); 492 smsusb_term_device(intf); 493 return rc; 494 } 495 496 pr_debug("device 0x%p created\n", dev); 497 498 return rc; 499 } 500 501 static int smsusb_probe(struct usb_interface *intf, 502 const struct usb_device_id *id) 503 { 504 struct usb_device *udev = interface_to_usbdev(intf); 505 char devpath[32]; 506 int i, rc; 507 508 pr_info("board id=%lu, interface number %d\n", 509 id->driver_info, 510 intf->cur_altsetting->desc.bInterfaceNumber); 511 512 if (sms_get_board(id->driver_info)->intf_num != 513 intf->cur_altsetting->desc.bInterfaceNumber) { 514 pr_debug("interface %d won't be used. Expecting interface %d to popup\n", 515 intf->cur_altsetting->desc.bInterfaceNumber, 516 sms_get_board(id->driver_info)->intf_num); 517 return -ENODEV; 518 } 519 520 if (intf->num_altsetting > 1) { 521 rc = usb_set_interface(udev, 522 intf->cur_altsetting->desc.bInterfaceNumber, 523 0); 524 if (rc < 0) { 525 pr_err("usb_set_interface failed, rc %d\n", rc); 526 return rc; 527 } 528 } 529 530 pr_debug("smsusb_probe %d\n", 531 intf->cur_altsetting->desc.bInterfaceNumber); 532 for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { 533 pr_debug("endpoint %d %02x %02x %d\n", i, 534 intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, 535 intf->cur_altsetting->endpoint[i].desc.bmAttributes, 536 intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); 537 if (intf->cur_altsetting->endpoint[i].desc.bEndpointAddress & 538 USB_DIR_IN) 539 rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 540 intf->cur_altsetting->endpoint[i].desc.bEndpointAddress)); 541 else 542 rc = usb_clear_halt(udev, usb_sndbulkpipe(udev, 543 intf->cur_altsetting->endpoint[i].desc.bEndpointAddress)); 544 } 545 if ((udev->actconfig->desc.bNumInterfaces == 2) && 546 (intf->cur_altsetting->desc.bInterfaceNumber == 0)) { 547 pr_debug("rom interface 0 is not used\n"); 548 return -ENODEV; 549 } 550 551 if (id->driver_info == SMS1XXX_BOARD_SIANO_STELLAR_ROM) { 552 /* Detected a Siano Stellar uninitialized */ 553 554 snprintf(devpath, sizeof(devpath), "usb\\%d-%s", 555 udev->bus->busnum, udev->devpath); 556 pr_info("stellar device in cold state was found at %s.\n", 557 devpath); 558 rc = smsusb1_load_firmware( 559 udev, smscore_registry_getmode(devpath), 560 id->driver_info); 561 562 /* This device will reset and gain another USB ID */ 563 if (!rc) 564 pr_info("stellar device now in warm state\n"); 565 else 566 pr_err("Failed to put stellar in warm state. Error: %d\n", 567 rc); 568 569 return rc; 570 } else { 571 rc = smsusb_init_device(intf, id->driver_info); 572 } 573 574 pr_info("Device initialized with return code %d\n", rc); 575 sms_board_load_modules(id->driver_info); 576 return rc; 577 } 578 579 static void smsusb_disconnect(struct usb_interface *intf) 580 { 581 smsusb_term_device(intf); 582 } 583 584 static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg) 585 { 586 struct smsusb_device_t *dev = usb_get_intfdata(intf); 587 printk(KERN_INFO "%s Entering status %d.\n", __func__, msg.event); 588 dev->state = SMSUSB_SUSPENDED; 589 /*smscore_set_power_mode(dev, SMS_POWER_MODE_SUSPENDED);*/ 590 smsusb_stop_streaming(dev); 591 return 0; 592 } 593 594 static int smsusb_resume(struct usb_interface *intf) 595 { 596 int rc, i; 597 struct smsusb_device_t *dev = usb_get_intfdata(intf); 598 struct usb_device *udev = interface_to_usbdev(intf); 599 600 printk(KERN_INFO "%s Entering.\n", __func__); 601 usb_clear_halt(udev, usb_rcvbulkpipe(udev, dev->in_ep)); 602 usb_clear_halt(udev, usb_sndbulkpipe(udev, dev->out_ep)); 603 604 for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) 605 printk(KERN_INFO "endpoint %d %02x %02x %d\n", i, 606 intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, 607 intf->cur_altsetting->endpoint[i].desc.bmAttributes, 608 intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); 609 610 if (intf->num_altsetting > 0) { 611 rc = usb_set_interface(udev, 612 intf->cur_altsetting->desc. 613 bInterfaceNumber, 0); 614 if (rc < 0) { 615 printk(KERN_INFO "%s usb_set_interface failed, rc %d\n", 616 __func__, rc); 617 return rc; 618 } 619 } 620 621 smsusb_start_streaming(dev); 622 return 0; 623 } 624 625 static const struct usb_device_id smsusb_id_table[] = { 626 /* This device is only present before firmware load */ 627 { USB_DEVICE(0x187f, 0x0010), 628 .driver_info = SMS1XXX_BOARD_SIANO_STELLAR_ROM }, 629 /* This device pops up after firmware load */ 630 { USB_DEVICE(0x187f, 0x0100), 631 .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, 632 633 { USB_DEVICE(0x187f, 0x0200), 634 .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A }, 635 { USB_DEVICE(0x187f, 0x0201), 636 .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B }, 637 { USB_DEVICE(0x187f, 0x0300), 638 .driver_info = SMS1XXX_BOARD_SIANO_VEGA }, 639 { USB_DEVICE(0x2040, 0x1700), 640 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT }, 641 { USB_DEVICE(0x2040, 0x1800), 642 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A }, 643 { USB_DEVICE(0x2040, 0x1801), 644 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B }, 645 { USB_DEVICE(0x2040, 0x2000), 646 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, 647 { USB_DEVICE(0x2040, 0x2009), 648 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 }, 649 { USB_DEVICE(0x2040, 0x200a), 650 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, 651 { USB_DEVICE(0x2040, 0x2010), 652 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, 653 { USB_DEVICE(0x2040, 0x2011), 654 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, 655 { USB_DEVICE(0x2040, 0x2019), 656 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, 657 { USB_DEVICE(0x2040, 0x5500), 658 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 659 { USB_DEVICE(0x2040, 0x5510), 660 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 661 { USB_DEVICE(0x2040, 0x5520), 662 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 663 { USB_DEVICE(0x2040, 0x5530), 664 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 665 { USB_DEVICE(0x2040, 0x5580), 666 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 667 { USB_DEVICE(0x2040, 0x5590), 668 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 669 { USB_DEVICE(0x187f, 0x0202), 670 .driver_info = SMS1XXX_BOARD_SIANO_NICE }, 671 { USB_DEVICE(0x187f, 0x0301), 672 .driver_info = SMS1XXX_BOARD_SIANO_VENICE }, 673 { USB_DEVICE(0x2040, 0xb900), 674 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 675 { USB_DEVICE(0x2040, 0xb910), 676 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 677 { USB_DEVICE(0x2040, 0xb980), 678 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 679 { USB_DEVICE(0x2040, 0xb990), 680 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 681 { USB_DEVICE(0x2040, 0xc000), 682 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 683 { USB_DEVICE(0x2040, 0xc010), 684 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 685 { USB_DEVICE(0x2040, 0xc080), 686 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 687 { USB_DEVICE(0x2040, 0xc090), 688 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 689 { USB_DEVICE(0x2040, 0xc0a0), 690 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 691 { USB_DEVICE(0x2040, 0xf5a0), 692 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 693 { USB_DEVICE(0x187f, 0x0202), 694 .driver_info = SMS1XXX_BOARD_SIANO_NICE }, 695 { USB_DEVICE(0x187f, 0x0301), 696 .driver_info = SMS1XXX_BOARD_SIANO_VENICE }, 697 { USB_DEVICE(0x187f, 0x0302), 698 .driver_info = SMS1XXX_BOARD_SIANO_VENICE }, 699 { USB_DEVICE(0x187f, 0x0310), 700 .driver_info = SMS1XXX_BOARD_SIANO_MING }, 701 { USB_DEVICE(0x187f, 0x0500), 702 .driver_info = SMS1XXX_BOARD_SIANO_PELE }, 703 { USB_DEVICE(0x187f, 0x0600), 704 .driver_info = SMS1XXX_BOARD_SIANO_RIO }, 705 { USB_DEVICE(0x187f, 0x0700), 706 .driver_info = SMS1XXX_BOARD_SIANO_DENVER_2160 }, 707 { USB_DEVICE(0x187f, 0x0800), 708 .driver_info = SMS1XXX_BOARD_SIANO_DENVER_1530 }, 709 { USB_DEVICE(0x19D2, 0x0086), 710 .driver_info = SMS1XXX_BOARD_ZTE_DVB_DATA_CARD }, 711 { USB_DEVICE(0x19D2, 0x0078), 712 .driver_info = SMS1XXX_BOARD_ONDA_MDTV_DATA_CARD }, 713 { USB_DEVICE(0x3275, 0x0080), 714 .driver_info = SMS1XXX_BOARD_SIANO_RIO }, 715 { USB_DEVICE(0x2013, 0x0257), 716 .driver_info = SMS1XXX_BOARD_PCTV_77E }, 717 { } /* Terminating entry */ 718 }; 719 720 MODULE_DEVICE_TABLE(usb, smsusb_id_table); 721 722 static struct usb_driver smsusb_driver = { 723 .name = "smsusb", 724 .probe = smsusb_probe, 725 .disconnect = smsusb_disconnect, 726 .id_table = smsusb_id_table, 727 728 .suspend = smsusb_suspend, 729 .resume = smsusb_resume, 730 }; 731 732 module_usb_driver(smsusb_driver); 733 734 MODULE_DESCRIPTION("Driver for the Siano SMS1xxx USB dongle"); 735 MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)"); 736 MODULE_LICENSE("GPL"); 737