1/* 2 USB Modem Driver for Longcheer devices 3 4 Copyright (C) 2011 caoweigang <caoweigang@longcheer.net> <caowai@gmail.com> 5 6 This driver is free software; you can redistribute it and/or modify 7 it under the terms of Version 2 of the GNU General Public License as 8 published by the Free Software Foundation. 9 10*/ 11 12#include <linux/kernel.h> 13#include <linux/init.h> 14#include <linux/tty.h> 15#include <linux/module.h> 16#include <linux/usb.h> 17#include <linux/usb/serial.h> 18#include <linux/version.h> 19 20/* 21 * Driver information 22 */ 23#define LCT_DRIVER_VERSION "v0.03" 24#define LCT_DRIVER_DESC "Longcheer usb modem driver" 25#define LCT_DRIVER_NAME "Longcheer" 26#define LCT_DEVICE_DESC "Longcheer usb modem" 27 28#define LCT_VENDOR_ID 0x1c9e 29#define LCT_CM55_PID 0x9e00 30#define LCT_WM6100_PID 0x9604 31#define LCT_WM71_PID 0x9603 32#define LCT_WM7608_PID 0x9800 33#define LCT_WM7211_PID 0x9605 34#define LCT_WM7211_TATA_PID 0x9803 35 36static struct usb_device_id lct_id_table [] = { 37 { USB_DEVICE(LCT_VENDOR_ID,LCT_CM55_PID) }, 38 { USB_DEVICE(LCT_VENDOR_ID,LCT_WM6100_PID)}, 39 { USB_DEVICE(LCT_VENDOR_ID,LCT_WM7608_PID)}, 40 { USB_DEVICE(LCT_VENDOR_ID,LCT_WM71_PID)}, 41 { USB_DEVICE(LCT_VENDOR_ID,LCT_WM7211_PID)}, 42 { USB_DEVICE(LCT_VENDOR_ID,LCT_WM7211_TATA_PID)}, 43 { } 44}; 45 46MODULE_DEVICE_TABLE(usb, lct_id_table); 47 48#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,31) 49static int lct_serial_open(struct tty_struct *tty, 50 struct usb_serial_port *port, struct file *filp) 51#else 52static int lct_serial_open(struct tty_struct *tty, 53 struct usb_serial_port *port) 54#endif 55{ 56 struct usb_serial *serial = port->serial; 57 usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 0x22, 0x21, 3, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); 58#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,31) 59 return usb_serial_generic_open(tty,port,filp); 60#else 61 return usb_serial_generic_open(tty,port); 62#endif 63} 64#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,30) 65static void lct_serial_close(struct tty_struct *tty, 66 struct usb_serial_port *port, struct file *filp) 67#else 68static void lct_serial_close(struct usb_serial_port *port) 69#endif 70{ 71 struct usb_serial *serial = port->serial; 72 usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 0x22, 0x21, 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); 73 74 if (serial->dev) 75 { 76 if (serial->num_bulk_out) 77 usb_kill_urb(port->write_urb); 78 if (serial->num_bulk_in) 79 usb_kill_urb(port->read_urb); 80 } 81} 82//#endif 83 84 85static struct usb_driver lct_modem_driver = { 86 .name = LCT_DRIVER_NAME, 87 .probe = usb_serial_probe, 88 .disconnect = usb_serial_disconnect, 89 .no_dynamic_id = 1, 90 .id_table = lct_id_table, 91}; 92 93 94static struct usb_serial_driver lct_modem_device = { 95 .driver = { 96 .owner = THIS_MODULE, 97 .name = LCT_DRIVER_NAME, 98 }, 99 .description = LCT_DEVICE_DESC, 100 .id_table = lct_id_table, 101 .usb_driver = &lct_modem_driver, 102 .num_ports = 1, 103//#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,30) 104 .open = lct_serial_open, 105 .close = lct_serial_close, 106//#endif 107}; 108 109static int __init lct_modem_init(void) 110{ 111 int retval; 112 113 retval = usb_serial_register(&lct_modem_device); 114 115 if (retval) 116 { 117 return retval; 118 } 119 120 retval = usb_register(&lct_modem_driver); 121 122 if (retval) 123 { 124 usb_serial_deregister(&lct_modem_device); 125 return retval; 126 } 127 128 printk(LCT_DRIVER_VERSION": "LCT_DRIVER_DESC"\n"); 129 130 return 0; 131} 132 133static void __exit lct_modem_exit(void) 134{ 135 usb_deregister(&lct_modem_driver); 136 usb_serial_deregister(&lct_modem_device); 137} 138 139module_init(lct_modem_init); 140module_exit(lct_modem_exit); 141 142MODULE_DESCRIPTION(LCT_DRIVER_DESC); 143MODULE_VERSION(LCT_DRIVER_VERSION); 144MODULE_LICENSE("GPL"); 145