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