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 = (struct sms_msg_hdr *) buffer; 222 int dummy; 223 224 if (dev->state != SMSUSB_ACTIVE) { 225 pr_debug("Device not active yet\n"); 226 return -ENOENT; 227 } 228 229 pr_debug("sending %s(%d) size: %d\n", 230 smscore_translate_msg(phdr->msg_type), phdr->msg_type, 231 phdr->msg_length); 232 233 smsendian_handle_tx_message((struct sms_msg_data *) phdr); 234 smsendian_handle_message_header((struct sms_msg_hdr *)buffer); 235 return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), 236 buffer, size, &dummy, 1000); 237 } 238 239 static char *smsusb1_fw_lkup[] = { 240 "dvbt_stellar_usb.inp", 241 "dvbh_stellar_usb.inp", 242 "tdmb_stellar_usb.inp", 243 "none", 244 "dvbt_bda_stellar_usb.inp", 245 }; 246 247 static inline char *sms_get_fw_name(int mode, int board_id) 248 { 249 char **fw = sms_get_board(board_id)->fw; 250 return (fw && fw[mode]) ? fw[mode] : smsusb1_fw_lkup[mode]; 251 } 252 253 static int smsusb1_load_firmware(struct usb_device *udev, int id, int board_id) 254 { 255 const struct firmware *fw; 256 u8 *fw_buffer; 257 int rc, dummy; 258 char *fw_filename; 259 260 if (id < 0) 261 id = sms_get_board(board_id)->default_mode; 262 263 if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) { 264 pr_err("invalid firmware id specified %d\n", id); 265 return -EINVAL; 266 } 267 268 fw_filename = sms_get_fw_name(id, board_id); 269 270 rc = request_firmware(&fw, fw_filename, &udev->dev); 271 if (rc < 0) { 272 pr_warn("failed to open '%s' mode %d, trying again with default firmware\n", 273 fw_filename, id); 274 275 fw_filename = smsusb1_fw_lkup[id]; 276 rc = request_firmware(&fw, fw_filename, &udev->dev); 277 if (rc < 0) { 278 pr_warn("failed to open '%s' mode %d\n", 279 fw_filename, id); 280 281 return rc; 282 } 283 } 284 285 fw_buffer = kmalloc(fw->size, GFP_KERNEL); 286 if (fw_buffer) { 287 memcpy(fw_buffer, fw->data, fw->size); 288 289 rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2), 290 fw_buffer, fw->size, &dummy, 1000); 291 292 pr_debug("sent %zu(%d) bytes, rc %d\n", fw->size, dummy, rc); 293 294 kfree(fw_buffer); 295 } else { 296 pr_err("failed to allocate firmware buffer\n"); 297 rc = -ENOMEM; 298 } 299 pr_debug("read FW %s, size=%zu\n", fw_filename, fw->size); 300 301 release_firmware(fw); 302 303 return rc; 304 } 305 306 static void smsusb1_detectmode(void *context, int *mode) 307 { 308 char *product_string = 309 ((struct smsusb_device_t *) context)->udev->product; 310 311 *mode = DEVICE_MODE_NONE; 312 313 if (!product_string) { 314 product_string = "none"; 315 pr_err("product string not found\n"); 316 } else if (strstr(product_string, "DVBH")) 317 *mode = 1; 318 else if (strstr(product_string, "BDA")) 319 *mode = 4; 320 else if (strstr(product_string, "DVBT")) 321 *mode = 0; 322 else if (strstr(product_string, "TDMB")) 323 *mode = 2; 324 325 pr_debug("%d \"%s\"\n", *mode, product_string); 326 } 327 328 static int smsusb1_setmode(void *context, int mode) 329 { 330 struct sms_msg_hdr msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK, 331 sizeof(struct sms_msg_hdr), 0 }; 332 333 if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { 334 pr_err("invalid firmware id specified %d\n", mode); 335 return -EINVAL; 336 } 337 338 return smsusb_sendrequest(context, &msg, sizeof(msg)); 339 } 340 341 static void smsusb_term_device(struct usb_interface *intf) 342 { 343 struct smsusb_device_t *dev = usb_get_intfdata(intf); 344 345 if (dev) { 346 dev->state = SMSUSB_DISCONNECTED; 347 348 smsusb_stop_streaming(dev); 349 350 /* unregister from smscore */ 351 if (dev->coredev) 352 smscore_unregister_device(dev->coredev); 353 354 pr_debug("device 0x%p destroyed\n", dev); 355 kfree(dev); 356 } 357 358 usb_set_intfdata(intf, NULL); 359 } 360 361 static void *siano_media_device_register(struct smsusb_device_t *dev, 362 int board_id) 363 { 364 #ifdef CONFIG_MEDIA_CONTROLLER_DVB 365 struct media_device *mdev; 366 struct usb_device *udev = dev->udev; 367 struct sms_board *board = sms_get_board(board_id); 368 int ret; 369 370 mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); 371 if (!mdev) 372 return NULL; 373 374 media_device_usb_init(mdev, udev, board->name); 375 376 ret = media_device_register(mdev); 377 if (ret) { 378 media_device_cleanup(mdev); 379 kfree(mdev); 380 return NULL; 381 } 382 383 pr_info("media controller created\n"); 384 385 return mdev; 386 #else 387 return NULL; 388 #endif 389 } 390 391 static int smsusb_init_device(struct usb_interface *intf, int board_id) 392 { 393 struct smsdevice_params_t params; 394 struct smsusb_device_t *dev; 395 void *mdev; 396 int i, rc; 397 398 /* create device object */ 399 dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL); 400 if (!dev) 401 return -ENOMEM; 402 403 memset(¶ms, 0, sizeof(params)); 404 usb_set_intfdata(intf, dev); 405 dev->udev = interface_to_usbdev(intf); 406 dev->state = SMSUSB_DISCONNECTED; 407 408 params.device_type = sms_get_board(board_id)->type; 409 410 switch (params.device_type) { 411 case SMS_STELLAR: 412 dev->buffer_size = USB1_BUFFER_SIZE; 413 414 params.setmode_handler = smsusb1_setmode; 415 params.detectmode_handler = smsusb1_detectmode; 416 break; 417 case SMS_UNKNOWN_TYPE: 418 pr_err("Unspecified sms device type!\n"); 419 /* fall-thru */ 420 default: 421 dev->buffer_size = USB2_BUFFER_SIZE; 422 dev->response_alignment = 423 le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) - 424 sizeof(struct sms_msg_hdr); 425 426 params.flags |= SMS_DEVICE_FAMILY2; 427 break; 428 } 429 430 for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { 431 if (intf->cur_altsetting->endpoint[i].desc. bEndpointAddress & USB_DIR_IN) 432 dev->in_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress; 433 else 434 dev->out_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress; 435 } 436 437 pr_debug("in_ep = %02x, out_ep = %02x\n", 438 dev->in_ep, dev->out_ep); 439 440 params.device = &dev->udev->dev; 441 params.buffer_size = dev->buffer_size; 442 params.num_buffers = MAX_BUFFERS; 443 params.sendrequest_handler = smsusb_sendrequest; 444 params.context = dev; 445 usb_make_path(dev->udev, params.devpath, sizeof(params.devpath)); 446 447 mdev = siano_media_device_register(dev, board_id); 448 449 /* register in smscore */ 450 rc = smscore_register_device(¶ms, &dev->coredev, mdev); 451 if (rc < 0) { 452 pr_err("smscore_register_device(...) failed, rc %d\n", rc); 453 smsusb_term_device(intf); 454 #ifdef CONFIG_MEDIA_CONTROLLER_DVB 455 media_device_unregister(mdev); 456 #endif 457 kfree(mdev); 458 return rc; 459 } 460 461 smscore_set_board_id(dev->coredev, board_id); 462 463 dev->coredev->is_usb_device = true; 464 465 /* initialize urbs */ 466 for (i = 0; i < MAX_URBS; i++) { 467 dev->surbs[i].dev = dev; 468 usb_init_urb(&dev->surbs[i].urb); 469 } 470 471 pr_debug("smsusb_start_streaming(...).\n"); 472 rc = smsusb_start_streaming(dev); 473 if (rc < 0) { 474 pr_err("smsusb_start_streaming(...) failed\n"); 475 smsusb_term_device(intf); 476 return rc; 477 } 478 479 dev->state = SMSUSB_ACTIVE; 480 481 rc = smscore_start_device(dev->coredev); 482 if (rc < 0) { 483 pr_err("smscore_start_device(...) failed\n"); 484 smsusb_term_device(intf); 485 return rc; 486 } 487 488 pr_debug("device 0x%p created\n", dev); 489 490 return rc; 491 } 492 493 static int smsusb_probe(struct usb_interface *intf, 494 const struct usb_device_id *id) 495 { 496 struct usb_device *udev = interface_to_usbdev(intf); 497 char devpath[32]; 498 int i, rc; 499 500 pr_info("board id=%lu, interface number %d\n", 501 id->driver_info, 502 intf->cur_altsetting->desc.bInterfaceNumber); 503 504 if (sms_get_board(id->driver_info)->intf_num != 505 intf->cur_altsetting->desc.bInterfaceNumber) { 506 pr_debug("interface %d won't be used. Expecting interface %d to popup\n", 507 intf->cur_altsetting->desc.bInterfaceNumber, 508 sms_get_board(id->driver_info)->intf_num); 509 return -ENODEV; 510 } 511 512 if (intf->num_altsetting > 1) { 513 rc = usb_set_interface(udev, 514 intf->cur_altsetting->desc.bInterfaceNumber, 515 0); 516 if (rc < 0) { 517 pr_err("usb_set_interface failed, rc %d\n", rc); 518 return rc; 519 } 520 } 521 522 pr_debug("smsusb_probe %d\n", 523 intf->cur_altsetting->desc.bInterfaceNumber); 524 for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { 525 pr_debug("endpoint %d %02x %02x %d\n", i, 526 intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, 527 intf->cur_altsetting->endpoint[i].desc.bmAttributes, 528 intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); 529 if (intf->cur_altsetting->endpoint[i].desc.bEndpointAddress & 530 USB_DIR_IN) 531 rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 532 intf->cur_altsetting->endpoint[i].desc.bEndpointAddress)); 533 else 534 rc = usb_clear_halt(udev, usb_sndbulkpipe(udev, 535 intf->cur_altsetting->endpoint[i].desc.bEndpointAddress)); 536 } 537 if ((udev->actconfig->desc.bNumInterfaces == 2) && 538 (intf->cur_altsetting->desc.bInterfaceNumber == 0)) { 539 pr_debug("rom interface 0 is not used\n"); 540 return -ENODEV; 541 } 542 543 if (id->driver_info == SMS1XXX_BOARD_SIANO_STELLAR_ROM) { 544 /* Detected a Siano Stellar uninitialized */ 545 546 snprintf(devpath, sizeof(devpath), "usb\\%d-%s", 547 udev->bus->busnum, udev->devpath); 548 pr_info("stellar device in cold state was found at %s.\n", 549 devpath); 550 rc = smsusb1_load_firmware( 551 udev, smscore_registry_getmode(devpath), 552 id->driver_info); 553 554 /* This device will reset and gain another USB ID */ 555 if (!rc) 556 pr_info("stellar device now in warm state\n"); 557 else 558 pr_err("Failed to put stellar in warm state. Error: %d\n", 559 rc); 560 561 return rc; 562 } else { 563 rc = smsusb_init_device(intf, id->driver_info); 564 } 565 566 pr_info("Device initialized with return code %d\n", rc); 567 sms_board_load_modules(id->driver_info); 568 return rc; 569 } 570 571 static void smsusb_disconnect(struct usb_interface *intf) 572 { 573 smsusb_term_device(intf); 574 } 575 576 static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg) 577 { 578 struct smsusb_device_t *dev = usb_get_intfdata(intf); 579 printk(KERN_INFO "%s Entering status %d.\n", __func__, msg.event); 580 dev->state = SMSUSB_SUSPENDED; 581 /*smscore_set_power_mode(dev, SMS_POWER_MODE_SUSPENDED);*/ 582 smsusb_stop_streaming(dev); 583 return 0; 584 } 585 586 static int smsusb_resume(struct usb_interface *intf) 587 { 588 int rc, i; 589 struct smsusb_device_t *dev = usb_get_intfdata(intf); 590 struct usb_device *udev = interface_to_usbdev(intf); 591 592 printk(KERN_INFO "%s Entering.\n", __func__); 593 usb_clear_halt(udev, usb_rcvbulkpipe(udev, dev->in_ep)); 594 usb_clear_halt(udev, usb_sndbulkpipe(udev, dev->out_ep)); 595 596 for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) 597 printk(KERN_INFO "endpoint %d %02x %02x %d\n", i, 598 intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, 599 intf->cur_altsetting->endpoint[i].desc.bmAttributes, 600 intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); 601 602 if (intf->num_altsetting > 0) { 603 rc = usb_set_interface(udev, 604 intf->cur_altsetting->desc. 605 bInterfaceNumber, 0); 606 if (rc < 0) { 607 printk(KERN_INFO "%s usb_set_interface failed, " 608 "rc %d\n", __func__, rc); 609 return rc; 610 } 611 } 612 613 smsusb_start_streaming(dev); 614 return 0; 615 } 616 617 static const struct usb_device_id smsusb_id_table[] = { 618 /* This device is only present before firmware load */ 619 { USB_DEVICE(0x187f, 0x0010), 620 .driver_info = SMS1XXX_BOARD_SIANO_STELLAR_ROM }, 621 /* This device pops up after firmware load */ 622 { USB_DEVICE(0x187f, 0x0100), 623 .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, 624 625 { USB_DEVICE(0x187f, 0x0200), 626 .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A }, 627 { USB_DEVICE(0x187f, 0x0201), 628 .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B }, 629 { USB_DEVICE(0x187f, 0x0300), 630 .driver_info = SMS1XXX_BOARD_SIANO_VEGA }, 631 { USB_DEVICE(0x2040, 0x1700), 632 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT }, 633 { USB_DEVICE(0x2040, 0x1800), 634 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A }, 635 { USB_DEVICE(0x2040, 0x1801), 636 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B }, 637 { USB_DEVICE(0x2040, 0x2000), 638 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, 639 { USB_DEVICE(0x2040, 0x2009), 640 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 }, 641 { USB_DEVICE(0x2040, 0x200a), 642 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, 643 { USB_DEVICE(0x2040, 0x2010), 644 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, 645 { USB_DEVICE(0x2040, 0x2011), 646 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, 647 { USB_DEVICE(0x2040, 0x2019), 648 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, 649 { USB_DEVICE(0x2040, 0x5500), 650 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 651 { USB_DEVICE(0x2040, 0x5510), 652 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 653 { USB_DEVICE(0x2040, 0x5520), 654 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 655 { USB_DEVICE(0x2040, 0x5530), 656 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 657 { USB_DEVICE(0x2040, 0x5580), 658 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 659 { USB_DEVICE(0x2040, 0x5590), 660 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 661 { USB_DEVICE(0x187f, 0x0202), 662 .driver_info = SMS1XXX_BOARD_SIANO_NICE }, 663 { USB_DEVICE(0x187f, 0x0301), 664 .driver_info = SMS1XXX_BOARD_SIANO_VENICE }, 665 { USB_DEVICE(0x2040, 0xb900), 666 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 667 { USB_DEVICE(0x2040, 0xb910), 668 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 669 { USB_DEVICE(0x2040, 0xb980), 670 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 671 { USB_DEVICE(0x2040, 0xb990), 672 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 673 { USB_DEVICE(0x2040, 0xc000), 674 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 675 { USB_DEVICE(0x2040, 0xc010), 676 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 677 { USB_DEVICE(0x2040, 0xc080), 678 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 679 { USB_DEVICE(0x2040, 0xc090), 680 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 681 { USB_DEVICE(0x2040, 0xc0a0), 682 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 683 { USB_DEVICE(0x2040, 0xf5a0), 684 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 685 { USB_DEVICE(0x187f, 0x0202), 686 .driver_info = SMS1XXX_BOARD_SIANO_NICE }, 687 { USB_DEVICE(0x187f, 0x0301), 688 .driver_info = SMS1XXX_BOARD_SIANO_VENICE }, 689 { USB_DEVICE(0x187f, 0x0302), 690 .driver_info = SMS1XXX_BOARD_SIANO_VENICE }, 691 { USB_DEVICE(0x187f, 0x0310), 692 .driver_info = SMS1XXX_BOARD_SIANO_MING }, 693 { USB_DEVICE(0x187f, 0x0500), 694 .driver_info = SMS1XXX_BOARD_SIANO_PELE }, 695 { USB_DEVICE(0x187f, 0x0600), 696 .driver_info = SMS1XXX_BOARD_SIANO_RIO }, 697 { USB_DEVICE(0x187f, 0x0700), 698 .driver_info = SMS1XXX_BOARD_SIANO_DENVER_2160 }, 699 { USB_DEVICE(0x187f, 0x0800), 700 .driver_info = SMS1XXX_BOARD_SIANO_DENVER_1530 }, 701 { USB_DEVICE(0x19D2, 0x0086), 702 .driver_info = SMS1XXX_BOARD_ZTE_DVB_DATA_CARD }, 703 { USB_DEVICE(0x19D2, 0x0078), 704 .driver_info = SMS1XXX_BOARD_ONDA_MDTV_DATA_CARD }, 705 { USB_DEVICE(0x3275, 0x0080), 706 .driver_info = SMS1XXX_BOARD_SIANO_RIO }, 707 { USB_DEVICE(0x2013, 0x0257), 708 .driver_info = SMS1XXX_BOARD_PCTV_77E }, 709 { } /* Terminating entry */ 710 }; 711 712 MODULE_DEVICE_TABLE(usb, smsusb_id_table); 713 714 static struct usb_driver smsusb_driver = { 715 .name = "smsusb", 716 .probe = smsusb_probe, 717 .disconnect = smsusb_disconnect, 718 .id_table = smsusb_id_table, 719 720 .suspend = smsusb_suspend, 721 .resume = smsusb_resume, 722 }; 723 724 module_usb_driver(smsusb_driver); 725 726 MODULE_DESCRIPTION("Driver for the Siano SMS1xxx USB dongle"); 727 MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)"); 728 MODULE_LICENSE("GPL"); 729