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