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