aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/mos7840.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/mos7840.c')
-rw-r--r--drivers/usb/serial/mos7840.c298
1 files changed, 193 insertions, 105 deletions
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index c526550694a..29160f8b510 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -114,10 +114,10 @@
114#define USB_VENDOR_ID_MOSCHIP 0x9710 114#define USB_VENDOR_ID_MOSCHIP 0x9710
115#define MOSCHIP_DEVICE_ID_7840 0x7840 115#define MOSCHIP_DEVICE_ID_7840 0x7840
116#define MOSCHIP_DEVICE_ID_7820 0x7820 116#define MOSCHIP_DEVICE_ID_7820 0x7820
117#define MOSCHIP_DEVICE_ID_7810 0x7810
117/* The native component can have its vendor/device id's overridden 118/* The native component can have its vendor/device id's overridden
118 * in vendor-specific implementations. Such devices can be handled 119 * in vendor-specific implementations. Such devices can be handled
119 * by making a change here, in moschip_port_id_table, and in 120 * by making a change here, in id_table.
120 * moschip_id_table_combined
121 */ 121 */
122#define USB_VENDOR_ID_BANDB 0x0856 122#define USB_VENDOR_ID_BANDB 0x0856
123#define BANDB_DEVICE_ID_USO9ML2_2 0xAC22 123#define BANDB_DEVICE_ID_USO9ML2_2 0xAC22
@@ -184,31 +184,16 @@
184#define NUM_URBS 16 /* URB Count */ 184#define NUM_URBS 16 /* URB Count */
185#define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */ 185#define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */
186 186
187/* LED on/off milliseconds*/
188#define LED_ON_MS 500
189#define LED_OFF_MS 500
187 190
188static const struct usb_device_id moschip_port_id_table[] = { 191static int device_type;
189 {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
190 {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
191 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
192 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)},
193 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
194 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4P)},
195 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)},
196 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)},
197 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)},
198 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)},
199 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
200 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2P)},
201 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
202 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4P)},
203 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)},
204 {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
205 {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)},
206 {} /* terminating entry */
207};
208 192
209static const struct usb_device_id moschip_id_table_combined[] __devinitconst = { 193static const struct usb_device_id id_table[] __devinitconst = {
210 {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, 194 {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
211 {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, 195 {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
196 {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7810)},
212 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, 197 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
213 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)}, 198 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)},
214 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)}, 199 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
@@ -226,8 +211,7 @@ static const struct usb_device_id moschip_id_table_combined[] __devinitconst = {
226 {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, 211 {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)},
227 {} /* terminating entry */ 212 {} /* terminating entry */
228}; 213};
229 214MODULE_DEVICE_TABLE(usb, id_table);
230MODULE_DEVICE_TABLE(usb, moschip_id_table_combined);
231 215
232/* This structure holds all of the local port information */ 216/* This structure holds all of the local port information */
233 217
@@ -261,8 +245,13 @@ struct moschip_port {
261 struct urb *write_urb_pool[NUM_URBS]; 245 struct urb *write_urb_pool[NUM_URBS];
262 char busy[NUM_URBS]; 246 char busy[NUM_URBS];
263 bool read_urb_busy; 247 bool read_urb_busy;
264};
265 248
249 /* For device(s) with LED indicator */
250 bool has_led;
251 bool led_flag;
252 struct timer_list led_timer1; /* Timer for LED on */
253 struct timer_list led_timer2; /* Timer for LED off */
254};
266 255
267static bool debug; 256static bool debug;
268 257
@@ -572,6 +561,69 @@ static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg,
572 return ret; 561 return ret;
573} 562}
574 563
564static void mos7840_set_led_callback(struct urb *urb)
565{
566 switch (urb->status) {
567 case 0:
568 /* Success */
569 break;
570 case -ECONNRESET:
571 case -ENOENT:
572 case -ESHUTDOWN:
573 /* This urb is terminated, clean up */
574 dbg("%s - urb shutting down with status: %d", __func__,
575 urb->status);
576 break;
577 default:
578 dbg("%s - nonzero urb status received: %d", __func__,
579 urb->status);
580 }
581}
582
583static void mos7840_set_led_async(struct moschip_port *mcs, __u16 wval,
584 __u16 reg)
585{
586 struct usb_device *dev = mcs->port->serial->dev;
587 struct usb_ctrlrequest *dr = mcs->dr;
588
589 dr->bRequestType = MCS_WR_RTYPE;
590 dr->bRequest = MCS_WRREQ;
591 dr->wValue = cpu_to_le16(wval);
592 dr->wIndex = cpu_to_le16(reg);
593 dr->wLength = cpu_to_le16(0);
594
595 usb_fill_control_urb(mcs->control_urb, dev, usb_sndctrlpipe(dev, 0),
596 (unsigned char *)dr, NULL, 0, mos7840_set_led_callback, NULL);
597
598 usb_submit_urb(mcs->control_urb, GFP_ATOMIC);
599}
600
601static void mos7840_set_led_sync(struct usb_serial_port *port, __u16 reg,
602 __u16 val)
603{
604 struct usb_device *dev = port->serial->dev;
605
606 usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ, MCS_WR_RTYPE,
607 val, reg, NULL, 0, MOS_WDR_TIMEOUT);
608}
609
610static void mos7840_led_off(unsigned long arg)
611{
612 struct moschip_port *mcs = (struct moschip_port *) arg;
613
614 /* Turn off LED */
615 mos7840_set_led_async(mcs, 0x0300, MODEM_CONTROL_REGISTER);
616 mod_timer(&mcs->led_timer2,
617 jiffies + msecs_to_jiffies(LED_OFF_MS));
618}
619
620static void mos7840_led_flag_off(unsigned long arg)
621{
622 struct moschip_port *mcs = (struct moschip_port *) arg;
623
624 mcs->led_flag = false;
625}
626
575/***************************************************************************** 627/*****************************************************************************
576 * mos7840_interrupt_callback 628 * mos7840_interrupt_callback
577 * this is the callback function for when we have received data on the 629 * this is the callback function for when we have received data on the
@@ -591,8 +643,6 @@ static void mos7840_interrupt_callback(struct urb *urb)
591 __u16 wval, wreg = 0; 643 __u16 wval, wreg = 0;
592 int status = urb->status; 644 int status = urb->status;
593 645
594 dbg("%s", " : Entering");
595
596 switch (status) { 646 switch (status) {
597 case 0: 647 case 0:
598 /* success */ 648 /* success */
@@ -766,12 +816,8 @@ static void mos7840_bulk_in_callback(struct urb *urb)
766 return; 816 return;
767 } 817 }
768 818
769 dbg("%s", "Entering... ");
770
771 data = urb->transfer_buffer; 819 data = urb->transfer_buffer;
772 820
773 dbg("%s", "Entering ...........");
774
775 if (urb->actual_length) { 821 if (urb->actual_length) {
776 tty = tty_port_tty_get(&mos7840_port->port->port); 822 tty = tty_port_tty_get(&mos7840_port->port->port);
777 if (tty) { 823 if (tty) {
@@ -792,6 +838,14 @@ static void mos7840_bulk_in_callback(struct urb *urb)
792 return; 838 return;
793 } 839 }
794 840
841 /* Turn on LED */
842 if (mos7840_port->has_led && !mos7840_port->led_flag) {
843 mos7840_port->led_flag = true;
844 mos7840_set_led_async(mos7840_port, 0x0301,
845 MODEM_CONTROL_REGISTER);
846 mod_timer(&mos7840_port->led_timer1,
847 jiffies + msecs_to_jiffies(LED_ON_MS));
848 }
795 849
796 mos7840_port->read_urb_busy = true; 850 mos7840_port->read_urb_busy = true;
797 retval = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC); 851 retval = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);
@@ -835,8 +889,6 @@ static void mos7840_bulk_out_data_callback(struct urb *urb)
835 return; 889 return;
836 } 890 }
837 891
838 dbg("%s", "Entering .........");
839
840 tty = tty_port_tty_get(&mos7840_port->port->port); 892 tty = tty_port_tty_get(&mos7840_port->port->port);
841 if (tty && mos7840_port->open) 893 if (tty && mos7840_port->open)
842 tty_wakeup(tty); 894 tty_wakeup(tty);
@@ -878,8 +930,6 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port)
878 struct moschip_port *mos7840_port; 930 struct moschip_port *mos7840_port;
879 struct moschip_port *port0; 931 struct moschip_port *port0;
880 932
881 dbg ("%s enter", __func__);
882
883 if (mos7840_port_paranoia_check(port, __func__)) { 933 if (mos7840_port_paranoia_check(port, __func__)) {
884 dbg("%s", "Port Paranoia failed"); 934 dbg("%s", "Port Paranoia failed");
885 return -ENODEV; 935 return -ENODEV;
@@ -1151,10 +1201,7 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port)
1151 dbg("usb_serial serial:%p mos7840_port:%p\n usb_serial_port port:%p", 1201 dbg("usb_serial serial:%p mos7840_port:%p\n usb_serial_port port:%p",
1152 serial, mos7840_port, port); 1202 serial, mos7840_port, port);
1153 1203
1154 dbg ("%s leave", __func__);
1155
1156 return 0; 1204 return 0;
1157
1158} 1205}
1159 1206
1160/***************************************************************************** 1207/*****************************************************************************
@@ -1175,18 +1222,14 @@ static int mos7840_chars_in_buffer(struct tty_struct *tty)
1175 unsigned long flags; 1222 unsigned long flags;
1176 struct moschip_port *mos7840_port; 1223 struct moschip_port *mos7840_port;
1177 1224
1178 dbg("%s", " mos7840_chars_in_buffer:entering ...........");
1179
1180 if (mos7840_port_paranoia_check(port, __func__)) { 1225 if (mos7840_port_paranoia_check(port, __func__)) {
1181 dbg("%s", "Invalid port"); 1226 dbg("%s", "Invalid port");
1182 return 0; 1227 return 0;
1183 } 1228 }
1184 1229
1185 mos7840_port = mos7840_get_port_private(port); 1230 mos7840_port = mos7840_get_port_private(port);
1186 if (mos7840_port == NULL) { 1231 if (mos7840_port == NULL)
1187 dbg("%s", "mos7840_break:leaving ...........");
1188 return 0; 1232 return 0;
1189 }
1190 1233
1191 spin_lock_irqsave(&mos7840_port->pool_lock, flags); 1234 spin_lock_irqsave(&mos7840_port->pool_lock, flags);
1192 for (i = 0; i < NUM_URBS; ++i) 1235 for (i = 0; i < NUM_URBS; ++i)
@@ -1211,8 +1254,6 @@ static void mos7840_close(struct usb_serial_port *port)
1211 int j; 1254 int j;
1212 __u16 Data; 1255 __u16 Data;
1213 1256
1214 dbg("%s", "mos7840_close:entering...");
1215
1216 if (mos7840_port_paranoia_check(port, __func__)) { 1257 if (mos7840_port_paranoia_check(port, __func__)) {
1217 dbg("%s", "Port Paranoia failed"); 1258 dbg("%s", "Port Paranoia failed");
1218 return; 1259 return;
@@ -1287,8 +1328,6 @@ static void mos7840_close(struct usb_serial_port *port)
1287 mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); 1328 mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
1288 1329
1289 mos7840_port->open = 0; 1330 mos7840_port->open = 0;
1290
1291 dbg("%s", "Leaving ............");
1292} 1331}
1293 1332
1294/************************************************************************ 1333/************************************************************************
@@ -1343,9 +1382,6 @@ static void mos7840_break(struct tty_struct *tty, int break_state)
1343 struct usb_serial *serial; 1382 struct usb_serial *serial;
1344 struct moschip_port *mos7840_port; 1383 struct moschip_port *mos7840_port;
1345 1384
1346 dbg("%s", "Entering ...........");
1347 dbg("mos7840_break: Start");
1348
1349 if (mos7840_port_paranoia_check(port, __func__)) { 1385 if (mos7840_port_paranoia_check(port, __func__)) {
1350 dbg("%s", "Port Paranoia failed"); 1386 dbg("%s", "Port Paranoia failed");
1351 return; 1387 return;
@@ -1395,8 +1431,6 @@ static int mos7840_write_room(struct tty_struct *tty)
1395 unsigned long flags; 1431 unsigned long flags;
1396 struct moschip_port *mos7840_port; 1432 struct moschip_port *mos7840_port;
1397 1433
1398 dbg("%s", " mos7840_write_room:entering ...........");
1399
1400 if (mos7840_port_paranoia_check(port, __func__)) { 1434 if (mos7840_port_paranoia_check(port, __func__)) {
1401 dbg("%s", "Invalid port"); 1435 dbg("%s", "Invalid port");
1402 dbg("%s", " mos7840_write_room:leaving ..........."); 1436 dbg("%s", " mos7840_write_room:leaving ...........");
@@ -1445,9 +1479,6 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port,
1445 /* __u16 Data; */ 1479 /* __u16 Data; */
1446 const unsigned char *current_position = data; 1480 const unsigned char *current_position = data;
1447 unsigned char *data1; 1481 unsigned char *data1;
1448 dbg("%s", "entering ...........");
1449 /* dbg("mos7840_write: mos7840_port->shadowLCR is %x",
1450 mos7840_port->shadowLCR); */
1451 1482
1452#ifdef NOTMOS7840 1483#ifdef NOTMOS7840
1453 Data = 0x00; 1484 Data = 0x00;
@@ -1554,6 +1585,14 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port,
1554 data1 = urb->transfer_buffer; 1585 data1 = urb->transfer_buffer;
1555 dbg("bulkout endpoint is %d", port->bulk_out_endpointAddress); 1586 dbg("bulkout endpoint is %d", port->bulk_out_endpointAddress);
1556 1587
1588 /* Turn on LED */
1589 if (mos7840_port->has_led && !mos7840_port->led_flag) {
1590 mos7840_port->led_flag = true;
1591 mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0301);
1592 mod_timer(&mos7840_port->led_timer1,
1593 jiffies + msecs_to_jiffies(LED_ON_MS));
1594 }
1595
1557 /* send it down the pipe */ 1596 /* send it down the pipe */
1558 status = usb_submit_urb(urb, GFP_ATOMIC); 1597 status = usb_submit_urb(urb, GFP_ATOMIC);
1559 1598
@@ -1602,8 +1641,6 @@ static void mos7840_throttle(struct tty_struct *tty)
1602 return; 1641 return;
1603 } 1642 }
1604 1643
1605 dbg("%s", "Entering ..........");
1606
1607 /* if we are implementing XON/XOFF, send the stop character */ 1644 /* if we are implementing XON/XOFF, send the stop character */
1608 if (I_IXOFF(tty)) { 1645 if (I_IXOFF(tty)) {
1609 unsigned char stop_char = STOP_CHAR(tty); 1646 unsigned char stop_char = STOP_CHAR(tty);
@@ -1646,8 +1683,6 @@ static void mos7840_unthrottle(struct tty_struct *tty)
1646 return; 1683 return;
1647 } 1684 }
1648 1685
1649 dbg("%s", "Entering ..........");
1650
1651 /* if we are implementing XON/XOFF, send the start character */ 1686 /* if we are implementing XON/XOFF, send the start character */
1652 if (I_IXOFF(tty)) { 1687 if (I_IXOFF(tty)) {
1653 unsigned char start_char = START_CHAR(tty); 1688 unsigned char start_char = START_CHAR(tty);
@@ -1676,8 +1711,6 @@ static int mos7840_tiocmget(struct tty_struct *tty)
1676 int status; 1711 int status;
1677 mos7840_port = mos7840_get_port_private(port); 1712 mos7840_port = mos7840_get_port_private(port);
1678 1713
1679 dbg("%s - port %d", __func__, port->number);
1680
1681 if (mos7840_port == NULL) 1714 if (mos7840_port == NULL)
1682 return -ENODEV; 1715 return -ENODEV;
1683 1716
@@ -1704,8 +1737,6 @@ static int mos7840_tiocmset(struct tty_struct *tty,
1704 unsigned int mcr; 1737 unsigned int mcr;
1705 int status; 1738 int status;
1706 1739
1707 dbg("%s - port %d", __func__, port->number);
1708
1709 mos7840_port = mos7840_get_port_private(port); 1740 mos7840_port = mos7840_get_port_private(port);
1710 1741
1711 if (mos7840_port == NULL) 1742 if (mos7840_port == NULL)
@@ -1746,7 +1777,6 @@ static int mos7840_tiocmset(struct tty_struct *tty,
1746static int mos7840_calc_baud_rate_divisor(int baudRate, int *divisor, 1777static int mos7840_calc_baud_rate_divisor(int baudRate, int *divisor,
1747 __u16 *clk_sel_val) 1778 __u16 *clk_sel_val)
1748{ 1779{
1749
1750 dbg("%s - %d", __func__, baudRate); 1780 dbg("%s - %d", __func__, baudRate);
1751 1781
1752 if (baudRate <= 115200) { 1782 if (baudRate <= 115200) {
@@ -1839,8 +1869,6 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port,
1839 return -1; 1869 return -1;
1840 } 1870 }
1841 1871
1842 dbg("%s", "Entering ..........");
1843
1844 number = mos7840_port->port->number - mos7840_port->port->serial->minor; 1872 number = mos7840_port->port->number - mos7840_port->port->serial->minor;
1845 1873
1846 dbg("%s - port = %d, baud = %d", __func__, 1874 dbg("%s - port = %d, baud = %d", __func__,
@@ -1966,8 +1994,6 @@ static void mos7840_change_port_settings(struct tty_struct *tty,
1966 return; 1994 return;
1967 } 1995 }
1968 1996
1969 dbg("%s", "Entering ..........");
1970
1971 lData = LCR_BITS_8; 1997 lData = LCR_BITS_8;
1972 lStop = LCR_STOP_1; 1998 lStop = LCR_STOP_1;
1973 lParity = LCR_PAR_NONE; 1999 lParity = LCR_PAR_NONE;
@@ -2108,7 +2134,7 @@ static void mos7840_set_termios(struct tty_struct *tty,
2108 unsigned int cflag; 2134 unsigned int cflag;
2109 struct usb_serial *serial; 2135 struct usb_serial *serial;
2110 struct moschip_port *mos7840_port; 2136 struct moschip_port *mos7840_port;
2111 dbg("mos7840_set_termios: START"); 2137
2112 if (mos7840_port_paranoia_check(port, __func__)) { 2138 if (mos7840_port_paranoia_check(port, __func__)) {
2113 dbg("%s", "Invalid port"); 2139 dbg("%s", "Invalid port");
2114 return; 2140 return;
@@ -2327,28 +2353,74 @@ static int mos7840_ioctl(struct tty_struct *tty,
2327 return -ENOIOCTLCMD; 2353 return -ENOIOCTLCMD;
2328} 2354}
2329 2355
2356static int mos7810_check(struct usb_serial *serial)
2357{
2358 int i, pass_count = 0;
2359 __u16 data = 0, mcr_data = 0;
2360 __u16 test_pattern = 0x55AA;
2361
2362 /* Store MCR setting */
2363 usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
2364 MCS_RDREQ, MCS_RD_RTYPE, 0x0300, MODEM_CONTROL_REGISTER,
2365 &mcr_data, VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
2366
2367 for (i = 0; i < 16; i++) {
2368 /* Send the 1-bit test pattern out to MCS7810 test pin */
2369 usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
2370 MCS_WRREQ, MCS_WR_RTYPE,
2371 (0x0300 | (((test_pattern >> i) & 0x0001) << 1)),
2372 MODEM_CONTROL_REGISTER, NULL, 0, MOS_WDR_TIMEOUT);
2373
2374 /* Read the test pattern back */
2375 usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
2376 MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data,
2377 VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
2378
2379 /* If this is a MCS7810 device, both test patterns must match */
2380 if (((test_pattern >> i) ^ (~data >> 1)) & 0x0001)
2381 break;
2382
2383 pass_count++;
2384 }
2385
2386 /* Restore MCR setting */
2387 usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), MCS_WRREQ,
2388 MCS_WR_RTYPE, 0x0300 | mcr_data, MODEM_CONTROL_REGISTER, NULL,
2389 0, MOS_WDR_TIMEOUT);
2390
2391 if (pass_count == 16)
2392 return 1;
2393
2394 return 0;
2395}
2396
2330static int mos7840_calc_num_ports(struct usb_serial *serial) 2397static int mos7840_calc_num_ports(struct usb_serial *serial)
2331{ 2398{
2332 __u16 Data = 0x00; 2399 __u16 data = 0x00;
2333 int ret = 0;
2334 int mos7840_num_ports; 2400 int mos7840_num_ports;
2335 2401
2336 ret = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 2402 usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
2337 MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &Data, 2403 MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data,
2338 VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT); 2404 VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
2339 2405
2340 if ((Data & 0x01) == 0) { 2406 if (serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7810 ||
2341 mos7840_num_ports = 2; 2407 serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7820) {
2342 serial->num_bulk_in = 2; 2408 device_type = serial->dev->descriptor.idProduct;
2343 serial->num_bulk_out = 2;
2344 serial->num_ports = 2;
2345 } else { 2409 } else {
2346 mos7840_num_ports = 4; 2410 /* For a MCS7840 device GPIO0 must be set to 1 */
2347 serial->num_bulk_in = 4; 2411 if ((data & 0x01) == 1)
2348 serial->num_bulk_out = 4; 2412 device_type = MOSCHIP_DEVICE_ID_7840;
2349 serial->num_ports = 4; 2413 else if (mos7810_check(serial))
2414 device_type = MOSCHIP_DEVICE_ID_7810;
2415 else
2416 device_type = MOSCHIP_DEVICE_ID_7820;
2350 } 2417 }
2351 2418
2419 mos7840_num_ports = (device_type >> 4) & 0x000F;
2420 serial->num_bulk_in = mos7840_num_ports;
2421 serial->num_bulk_out = mos7840_num_ports;
2422 serial->num_ports = mos7840_num_ports;
2423
2352 return mos7840_num_ports; 2424 return mos7840_num_ports;
2353} 2425}
2354 2426
@@ -2361,9 +2433,7 @@ static int mos7840_startup(struct usb_serial *serial)
2361 struct moschip_port *mos7840_port; 2433 struct moschip_port *mos7840_port;
2362 struct usb_device *dev; 2434 struct usb_device *dev;
2363 int i, status; 2435 int i, status;
2364
2365 __u16 Data; 2436 __u16 Data;
2366 dbg("%s", "mos7840_startup :Entering..........");
2367 2437
2368 if (!serial) { 2438 if (!serial) {
2369 dbg("%s", "Invalid Handler"); 2439 dbg("%s", "Invalid Handler");
@@ -2372,9 +2442,6 @@ static int mos7840_startup(struct usb_serial *serial)
2372 2442
2373 dev = serial->dev; 2443 dev = serial->dev;
2374 2444
2375 dbg("%s", "Entering...");
2376 dbg ("mos7840_startup: serial = %p", serial);
2377
2378 /* we set up the pointers to the endpoints in the mos7840_open * 2445 /* we set up the pointers to the endpoints in the mos7840_open *
2379 * function, as the structures aren't created yet. */ 2446 * function, as the structures aren't created yet. */
2380 2447
@@ -2563,6 +2630,34 @@ static int mos7840_startup(struct usb_serial *serial)
2563 status = -ENOMEM; 2630 status = -ENOMEM;
2564 goto error; 2631 goto error;
2565 } 2632 }
2633
2634 mos7840_port->has_led = false;
2635
2636 /* Initialize LED timers */
2637 if (device_type == MOSCHIP_DEVICE_ID_7810) {
2638 mos7840_port->has_led = true;
2639
2640 init_timer(&mos7840_port->led_timer1);
2641 mos7840_port->led_timer1.function = mos7840_led_off;
2642 mos7840_port->led_timer1.expires =
2643 jiffies + msecs_to_jiffies(LED_ON_MS);
2644 mos7840_port->led_timer1.data =
2645 (unsigned long)mos7840_port;
2646
2647 init_timer(&mos7840_port->led_timer2);
2648 mos7840_port->led_timer2.function =
2649 mos7840_led_flag_off;
2650 mos7840_port->led_timer2.expires =
2651 jiffies + msecs_to_jiffies(LED_OFF_MS);
2652 mos7840_port->led_timer2.data =
2653 (unsigned long)mos7840_port;
2654
2655 mos7840_port->led_flag = false;
2656
2657 /* Turn off LED */
2658 mos7840_set_led_sync(serial->port[i],
2659 MODEM_CONTROL_REGISTER, 0x0300);
2660 }
2566 } 2661 }
2567 dbg ("mos7840_startup: all ports configured..........."); 2662 dbg ("mos7840_startup: all ports configured...........");
2568 2663
@@ -2602,7 +2697,6 @@ static void mos7840_disconnect(struct usb_serial *serial)
2602 int i; 2697 int i;
2603 unsigned long flags; 2698 unsigned long flags;
2604 struct moschip_port *mos7840_port; 2699 struct moschip_port *mos7840_port;
2605 dbg("%s", " disconnect :entering..........");
2606 2700
2607 if (!serial) { 2701 if (!serial) {
2608 dbg("%s", "Invalid Handler"); 2702 dbg("%s", "Invalid Handler");
@@ -2624,9 +2718,6 @@ static void mos7840_disconnect(struct usb_serial *serial)
2624 usb_kill_urb(mos7840_port->control_urb); 2718 usb_kill_urb(mos7840_port->control_urb);
2625 } 2719 }
2626 } 2720 }
2627
2628 dbg("%s", "Thank u :: ");
2629
2630} 2721}
2631 2722
2632/**************************************************************************** 2723/****************************************************************************
@@ -2638,7 +2729,6 @@ static void mos7840_release(struct usb_serial *serial)
2638{ 2729{
2639 int i; 2730 int i;
2640 struct moschip_port *mos7840_port; 2731 struct moschip_port *mos7840_port;
2641 dbg("%s", " release :entering..........");
2642 2732
2643 if (!serial) { 2733 if (!serial) {
2644 dbg("%s", "Invalid Handler"); 2734 dbg("%s", "Invalid Handler");
@@ -2654,30 +2744,28 @@ static void mos7840_release(struct usb_serial *serial)
2654 mos7840_port = mos7840_get_port_private(serial->port[i]); 2744 mos7840_port = mos7840_get_port_private(serial->port[i]);
2655 dbg("mos7840_port %d = %p", i, mos7840_port); 2745 dbg("mos7840_port %d = %p", i, mos7840_port);
2656 if (mos7840_port) { 2746 if (mos7840_port) {
2747 if (mos7840_port->has_led) {
2748 /* Turn off LED */
2749 mos7840_set_led_sync(mos7840_port->port,
2750 MODEM_CONTROL_REGISTER, 0x0300);
2751
2752 del_timer_sync(&mos7840_port->led_timer1);
2753 del_timer_sync(&mos7840_port->led_timer2);
2754 }
2657 kfree(mos7840_port->ctrl_buf); 2755 kfree(mos7840_port->ctrl_buf);
2658 kfree(mos7840_port->dr); 2756 kfree(mos7840_port->dr);
2659 kfree(mos7840_port); 2757 kfree(mos7840_port);
2660 } 2758 }
2661 } 2759 }
2662
2663 dbg("%s", "Thank u :: ");
2664
2665} 2760}
2666 2761
2667static struct usb_driver io_driver = {
2668 .name = "mos7840",
2669 .probe = usb_serial_probe,
2670 .disconnect = usb_serial_disconnect,
2671 .id_table = moschip_id_table_combined,
2672};
2673
2674static struct usb_serial_driver moschip7840_4port_device = { 2762static struct usb_serial_driver moschip7840_4port_device = {
2675 .driver = { 2763 .driver = {
2676 .owner = THIS_MODULE, 2764 .owner = THIS_MODULE,
2677 .name = "mos7840", 2765 .name = "mos7840",
2678 }, 2766 },
2679 .description = DRIVER_DESC, 2767 .description = DRIVER_DESC,
2680 .id_table = moschip_port_id_table, 2768 .id_table = id_table,
2681 .num_ports = 4, 2769 .num_ports = 4,
2682 .open = mos7840_open, 2770 .open = mos7840_open,
2683 .close = mos7840_close, 2771 .close = mos7840_close,
@@ -2707,7 +2795,7 @@ static struct usb_serial_driver * const serial_drivers[] = {
2707 &moschip7840_4port_device, NULL 2795 &moschip7840_4port_device, NULL
2708}; 2796};
2709 2797
2710module_usb_serial_driver(io_driver, serial_drivers); 2798module_usb_serial_driver(serial_drivers, id_table);
2711 2799
2712MODULE_DESCRIPTION(DRIVER_DESC); 2800MODULE_DESCRIPTION(DRIVER_DESC);
2713MODULE_LICENSE("GPL"); 2801MODULE_LICENSE("GPL");