Merge git://git.infradead.org/ubi-2.6
[pandora-kernel.git] / drivers / usb / serial / mos7720.c
1 /*
2  * mos7720.c
3  *   Controls the Moschip 7720 usb to dual port serial convertor
4  *
5  * Copyright 2006 Moschip Semiconductor Tech. Ltd.
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, version 2 of the License.
10  *
11  * Developed by:
12  *      Vijaya Kumar <vijaykumar.gn@gmail.com>
13  *      Ajay Kumar <naanuajay@yahoo.com>
14  *      Gurudeva <ngurudeva@yahoo.com>
15  *
16  * Cleaned up from the original by:
17  *      Greg Kroah-Hartman <gregkh@suse.de>
18  *
19  * Originally based on drivers/usb/serial/io_edgeport.c which is:
20  *      Copyright (C) 2000 Inside Out Networks, All rights reserved.
21  *      Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com>
22  */
23 #include <linux/kernel.h>
24 #include <linux/errno.h>
25 #include <linux/init.h>
26 #include <linux/slab.h>
27 #include <linux/tty.h>
28 #include <linux/tty_driver.h>
29 #include <linux/tty_flip.h>
30 #include <linux/module.h>
31 #include <linux/spinlock.h>
32 #include <linux/serial.h>
33 #include <linux/serial_reg.h>
34 #include <linux/usb.h>
35 #include <linux/usb/serial.h>
36 #include <linux/uaccess.h>
37
38
39 /*
40  * Version Information
41  */
42 #define DRIVER_VERSION "1.0.0.4F"
43 #define DRIVER_AUTHOR "Aspire Communications pvt Ltd."
44 #define DRIVER_DESC "Moschip USB Serial Driver"
45
46 /* default urb timeout */
47 #define MOS_WDR_TIMEOUT (HZ * 5)
48
49 #define MOS_PORT1       0x0200
50 #define MOS_PORT2       0x0300
51 #define MOS_VENREG      0x0000
52 #define MOS_MAX_PORT    0x02
53 #define MOS_WRITE       0x0E
54 #define MOS_READ        0x0D
55
56 /* Interrupt Rotinue Defines    */
57 #define SERIAL_IIR_RLS  0x06
58 #define SERIAL_IIR_RDA  0x04
59 #define SERIAL_IIR_CTI  0x0c
60 #define SERIAL_IIR_THR  0x02
61 #define SERIAL_IIR_MS   0x00
62
63 #define NUM_URBS                        16      /* URB Count */
64 #define URB_TRANSFER_BUFFER_SIZE        32      /* URB Size */
65
66 /* This structure holds all of the local port information */
67 struct moschip_port {
68         __u8    shadowLCR;              /* last LCR value received */
69         __u8    shadowMCR;              /* last MCR value received */
70         __u8    shadowMSR;              /* last MSR value received */
71         char                    open;
72         struct async_icount     icount;
73         struct usb_serial_port  *port;  /* loop back to the owner */
74         struct urb              *write_urb_pool[NUM_URBS];
75 };
76
77 /* This structure holds all of the individual serial device information */
78 struct moschip_serial {
79         int interrupt_started;
80 };
81
82 static int debug;
83
84 static struct usb_serial_driver moschip7720_2port_driver;
85
86 #define USB_VENDOR_ID_MOSCHIP           0x9710
87 #define MOSCHIP_DEVICE_ID_7720          0x7720
88 #define MOSCHIP_DEVICE_ID_7715          0x7715
89
90 static const struct usb_device_id moschip_port_id_table[] = {
91         { USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7720) },
92         { USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7715) },
93         { } /* terminating entry */
94 };
95 MODULE_DEVICE_TABLE(usb, moschip_port_id_table);
96
97
98 /*
99  * mos7720_interrupt_callback
100  *      this is the callback function for when we have received data on the
101  *      interrupt endpoint.
102  */
103 static void mos7720_interrupt_callback(struct urb *urb)
104 {
105         int result;
106         int length;
107         int status = urb->status;
108         __u8 *data;
109         __u8 sp1;
110         __u8 sp2;
111
112         dbg(" : Entering");
113
114         switch (status) {
115         case 0:
116                 /* success */
117                 break;
118         case -ECONNRESET:
119         case -ENOENT:
120         case -ESHUTDOWN:
121                 /* this urb is terminated, clean up */
122                 dbg("%s - urb shutting down with status: %d", __func__,
123                     status);
124                 return;
125         default:
126                 dbg("%s - nonzero urb status received: %d", __func__,
127                     status);
128                 goto exit;
129         }
130
131         length = urb->actual_length;
132         data = urb->transfer_buffer;
133
134         /* Moschip get 4 bytes
135          * Byte 1 IIR Port 1 (port.number is 0)
136          * Byte 2 IIR Port 2 (port.number is 1)
137          * Byte 3 --------------
138          * Byte 4 FIFO status for both */
139
140         /* the above description is inverted
141          *      oneukum 2007-03-14 */
142
143         if (unlikely(length != 4)) {
144                 dbg("Wrong data !!!");
145                 return;
146         }
147
148         sp1 = data[3];
149         sp2 = data[2];
150
151         if ((sp1 | sp2) & 0x01) {
152                 /* No Interrupt Pending in both the ports */
153                 dbg("No Interrupt !!!");
154         } else {
155                 switch (sp1 & 0x0f) {
156                 case SERIAL_IIR_RLS:
157                         dbg("Serial Port 1: Receiver status error or address "
158                             "bit detected in 9-bit mode\n");
159                         break;
160                 case SERIAL_IIR_CTI:
161                         dbg("Serial Port 1: Receiver time out");
162                         break;
163                 case SERIAL_IIR_MS:
164                         dbg("Serial Port 1: Modem status change");
165                         break;
166                 }
167
168                 switch (sp2 & 0x0f) {
169                 case SERIAL_IIR_RLS:
170                         dbg("Serial Port 2: Receiver status error or address "
171                             "bit detected in 9-bit mode");
172                         break;
173                 case SERIAL_IIR_CTI:
174                         dbg("Serial Port 2: Receiver time out");
175                         break;
176                 case SERIAL_IIR_MS:
177                         dbg("Serial Port 2: Modem status change");
178                         break;
179                 }
180         }
181
182 exit:
183         result = usb_submit_urb(urb, GFP_ATOMIC);
184         if (result)
185                 dev_err(&urb->dev->dev,
186                         "%s - Error %d submitting control urb\n",
187                         __func__, result);
188         return;
189 }
190
191 /*
192  * mos7715_interrupt_callback
193  *      this is the 7715's callback function for when we have received data on
194  *      the interrupt endpoint.
195  */
196 static void mos7715_interrupt_callback(struct urb *urb)
197 {
198         int result;
199         int length;
200         int status = urb->status;
201         __u8 *data;
202         __u8 iir;
203
204         switch (status) {
205         case 0:
206                 /* success */
207                 break;
208         case -ECONNRESET:
209         case -ENOENT:
210         case -ESHUTDOWN:
211                 /* this urb is terminated, clean up */
212                 dbg("%s - urb shutting down with status: %d", __func__,
213                     status);
214                 return;
215         default:
216                 dbg("%s - nonzero urb status received: %d", __func__,
217                     status);
218                 goto exit;
219         }
220
221         length = urb->actual_length;
222         data = urb->transfer_buffer;
223
224         /* Structure of data from 7715 device:
225          * Byte 1: IIR serial Port
226          * Byte 2: unused
227          * Byte 2: DSR parallel port
228          * Byte 4: FIFO status for both */
229
230         if (unlikely(length != 4)) {
231                 dbg("Wrong data !!!");
232                 return;
233         }
234
235         iir = data[0];
236         if (!(iir & 0x01)) {    /* serial port interrupt pending */
237                 switch (iir & 0x0f) {
238                 case SERIAL_IIR_RLS:
239                         dbg("Serial Port: Receiver status error or address "
240                             "bit detected in 9-bit mode\n");
241                         break;
242                 case SERIAL_IIR_CTI:
243                         dbg("Serial Port: Receiver time out");
244                         break;
245                 case SERIAL_IIR_MS:
246                         dbg("Serial Port: Modem status change");
247                         break;
248                 }
249         }
250
251 exit:
252         result = usb_submit_urb(urb, GFP_ATOMIC);
253         if (result)
254                 dev_err(&urb->dev->dev,
255                         "%s - Error %d submitting control urb\n",
256                         __func__, result);
257         return;
258 }
259
260 /*
261  * mos7720_bulk_in_callback
262  *      this is the callback function for when we have received data on the
263  *      bulk in endpoint.
264  */
265 static void mos7720_bulk_in_callback(struct urb *urb)
266 {
267         int retval;
268         unsigned char *data ;
269         struct usb_serial_port *port;
270         struct moschip_port *mos7720_port;
271         struct tty_struct *tty;
272         int status = urb->status;
273
274         if (status) {
275                 dbg("nonzero read bulk status received: %d", status);
276                 return;
277         }
278
279         mos7720_port = urb->context;
280         if (!mos7720_port) {
281                 dbg("NULL mos7720_port pointer");
282                 return ;
283         }
284
285         port = mos7720_port->port;
286
287         dbg("Entering...%s", __func__);
288
289         data = urb->transfer_buffer;
290
291         tty = tty_port_tty_get(&port->port);
292         if (tty && urb->actual_length) {
293                 tty_insert_flip_string(tty, data, urb->actual_length);
294                 tty_flip_buffer_push(tty);
295         }
296         tty_kref_put(tty);
297
298         if (!port->read_urb) {
299                 dbg("URB KILLED !!!");
300                 return;
301         }
302
303         if (port->read_urb->status != -EINPROGRESS) {
304                 port->read_urb->dev = port->serial->dev;
305
306                 retval = usb_submit_urb(port->read_urb, GFP_ATOMIC);
307                 if (retval)
308                         dbg("usb_submit_urb(read bulk) failed, retval = %d",
309                             retval);
310         }
311 }
312
313 /*
314  * mos7720_bulk_out_data_callback
315  *      this is the callback function for when we have finished sending serial
316  *      data on the bulk out endpoint.
317  */
318 static void mos7720_bulk_out_data_callback(struct urb *urb)
319 {
320         struct moschip_port *mos7720_port;
321         struct tty_struct *tty;
322         int status = urb->status;
323
324         if (status) {
325                 dbg("nonzero write bulk status received:%d", status);
326                 return;
327         }
328
329         mos7720_port = urb->context;
330         if (!mos7720_port) {
331                 dbg("NULL mos7720_port pointer");
332                 return ;
333         }
334
335         dbg("Entering .........");
336
337         tty = tty_port_tty_get(&mos7720_port->port->port);
338
339         if (tty && mos7720_port->open)
340                 tty_wakeup(tty);
341         tty_kref_put(tty);
342 }
343
344 /*
345  * send_mos_cmd
346  *      this function will be used for sending command to device
347  */
348 static int send_mos_cmd(struct usb_serial *serial, __u8 request, __u16 value,
349                         __u16 index, u8 *data)
350 {
351         int status;
352         u8 *buf;
353         u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
354
355         if (value < MOS_MAX_PORT) {
356                 if (product == MOSCHIP_DEVICE_ID_7715)
357                         value = 0x0200; /* identifies the 7715's serial port */
358                 else
359                         value = value*0x100+0x200;
360         } else {
361                 value = 0x0000;
362                 if ((product == MOSCHIP_DEVICE_ID_7715) &&
363                     (index != 0x08)) {
364                         dbg("serial->product== MOSCHIP_DEVICE_ID_7715");
365                         /* index = 0x01 ; */
366                 }
367         }
368
369         if (request == MOS_WRITE) {
370                 value = value + *data;
371                 status = usb_control_msg(serial->dev,
372                                 usb_sndctrlpipe(serial->dev, 0), MOS_WRITE,
373                                 0x40, value, index, NULL, 0, MOS_WDR_TIMEOUT);
374         } else {
375                 buf = kmalloc(1, GFP_KERNEL);
376                 if (!buf) {
377                         status = -ENOMEM;
378                         goto out;
379                 }
380                 status = usb_control_msg(serial->dev,
381                                 usb_rcvctrlpipe(serial->dev, 0), MOS_READ,
382                                 0xc0, value, index, buf, 1, MOS_WDR_TIMEOUT);
383                 *data = *buf;
384                 kfree(buf);
385         }
386 out:
387         if (status < 0)
388                 dbg("Command Write failed Value %x index %x", value, index);
389
390         return status;
391 }
392
393
394 /*
395  * mos77xx_probe
396  *      this function installs the appropriate read interrupt endpoint callback
397  *      depending on whether the device is a 7720 or 7715, thus avoiding costly
398  *      run-time checks in the high-frequency callback routine itself.
399  */
400 static int mos77xx_probe(struct usb_serial *serial,
401                          const struct usb_device_id *id)
402 {
403         if (id->idProduct == MOSCHIP_DEVICE_ID_7715)
404                 moschip7720_2port_driver.read_int_callback =
405                         mos7715_interrupt_callback;
406         else
407                 moschip7720_2port_driver.read_int_callback =
408                         mos7720_interrupt_callback;
409
410         return 0;
411 }
412
413 static int mos77xx_calc_num_ports(struct usb_serial *serial)
414 {
415         u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
416         if (product == MOSCHIP_DEVICE_ID_7715)
417                 return 1;
418
419         return 2;
420 }
421
422 static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port)
423 {
424         struct usb_serial *serial;
425         struct usb_serial_port *port0;
426         struct urb *urb;
427         struct moschip_serial *mos7720_serial;
428         struct moschip_port *mos7720_port;
429         int response;
430         int port_number;
431         char data;
432         int allocated_urbs = 0;
433         int j;
434
435         serial = port->serial;
436
437         mos7720_port = usb_get_serial_port_data(port);
438         if (mos7720_port == NULL)
439                 return -ENODEV;
440
441         port0 = serial->port[0];
442
443         mos7720_serial = usb_get_serial_data(serial);
444
445         if (mos7720_serial == NULL || port0 == NULL)
446                 return -ENODEV;
447
448         usb_clear_halt(serial->dev, port->write_urb->pipe);
449         usb_clear_halt(serial->dev, port->read_urb->pipe);
450
451         /* Initialising the write urb pool */
452         for (j = 0; j < NUM_URBS; ++j) {
453                 urb = usb_alloc_urb(0, GFP_KERNEL);
454                 mos7720_port->write_urb_pool[j] = urb;
455
456                 if (urb == NULL) {
457                         dev_err(&port->dev, "No more urbs???\n");
458                         continue;
459                 }
460
461                 urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
462                                                GFP_KERNEL);
463                 if (!urb->transfer_buffer) {
464                         dev_err(&port->dev,
465                                 "%s-out of memory for urb buffers.\n",
466                                 __func__);
467                         usb_free_urb(mos7720_port->write_urb_pool[j]);
468                         mos7720_port->write_urb_pool[j] = NULL;
469                         continue;
470                 }
471                 allocated_urbs++;
472         }
473
474         if (!allocated_urbs)
475                 return -ENOMEM;
476
477          /* Initialize MCS7720 -- Write Init values to corresponding Registers
478           *
479           * Register Index
480           * 0 : THR/RHR
481           * 1 : IER
482           * 2 : FCR
483           * 3 : LCR
484           * 4 : MCR
485           * 5 : LSR
486           * 6 : MSR
487           * 7 : SPR
488           *
489           * 0x08 : SP1/2 Control Reg
490           */
491         port_number = port->number - port->serial->minor;
492         send_mos_cmd(port->serial, MOS_READ, port_number, UART_LSR, &data);
493         dbg("SS::%p LSR:%x", mos7720_port, data);
494
495         dbg("Check:Sending Command ..........");
496
497         data = 0x02;
498         send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x01, &data);
499         data = 0x02;
500         send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x02, &data);
501
502         data = 0x00;
503         send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
504         data = 0x00;
505         send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data);
506
507         data = 0xCF;
508         send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data);
509         data = 0x03;
510         mos7720_port->shadowLCR  = data;
511         send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
512         data = 0x0b;
513         mos7720_port->shadowMCR  = data;
514         send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
515         data = 0x0b;
516         send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
517
518         data = 0x00;
519         send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data);
520         data = 0x00;
521         send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data);
522
523 /*      data = 0x00;
524         send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, port_number + 1, &data);
525         data = 0x03;
526         send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data);
527         data = 0x00;
528         send_mos_cmd(port->serial, MOS_WRITE, MOS_MAX_PORT,
529                                                 port_number + 1, &data);
530 */
531         data = 0x00;
532         send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data);
533
534         data = data | (port->number - port->serial->minor + 1);
535         send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data);
536
537         data = 0x83;
538         mos7720_port->shadowLCR  = data;
539         send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
540         data = 0x0c;
541         send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data);
542         data = 0x00;
543         send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
544         data = 0x03;
545         mos7720_port->shadowLCR  = data;
546         send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
547         data = 0x0c;
548         send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
549         data = 0x0c;
550         send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
551
552         /* see if we've set up our endpoint info yet   *
553          * (can't set it up in mos7720_startup as the  *
554          * structures were not set up at that time.)   */
555         if (!mos7720_serial->interrupt_started) {
556                 dbg("Interrupt buffer NULL !!!");
557
558                 /* not set up yet, so do it now */
559                 mos7720_serial->interrupt_started = 1;
560
561                 dbg("To Submit URB !!!");
562
563                 /* set up our interrupt urb */
564                 usb_fill_int_urb(port0->interrupt_in_urb, serial->dev,
565                          usb_rcvintpipe(serial->dev,
566                                 port->interrupt_in_endpointAddress),
567                          port0->interrupt_in_buffer,
568                          port0->interrupt_in_urb->transfer_buffer_length,
569                          mos7720_interrupt_callback, mos7720_port,
570                          port0->interrupt_in_urb->interval);
571
572                 /* start interrupt read for this mos7720 this interrupt *
573                  * will continue as long as the mos7720 is connected    */
574                 dbg("Submit URB over !!!");
575                 response = usb_submit_urb(port0->interrupt_in_urb, GFP_KERNEL);
576                 if (response)
577                         dev_err(&port->dev,
578                                 "%s - Error %d submitting control urb\n",
579                                 __func__, response);
580         }
581
582         /* set up our bulk in urb */
583         usb_fill_bulk_urb(port->read_urb, serial->dev,
584                           usb_rcvbulkpipe(serial->dev,
585                                 port->bulk_in_endpointAddress),
586                           port->bulk_in_buffer,
587                           port->read_urb->transfer_buffer_length,
588                           mos7720_bulk_in_callback, mos7720_port);
589         response = usb_submit_urb(port->read_urb, GFP_KERNEL);
590         if (response)
591                 dev_err(&port->dev, "%s - Error %d submitting read urb\n",
592                                                         __func__, response);
593
594         /* initialize our icount structure */
595         memset(&(mos7720_port->icount), 0x00, sizeof(mos7720_port->icount));
596
597         /* initialize our port settings */
598         mos7720_port->shadowMCR = UART_MCR_OUT2; /* Must set to enable ints! */
599
600         /* send a open port command */
601         mos7720_port->open = 1;
602
603         return 0;
604 }
605
606 /*
607  * mos7720_chars_in_buffer
608  *      this function is called by the tty driver when it wants to know how many
609  *      bytes of data we currently have outstanding in the port (data that has
610  *      been written, but hasn't made it out the port yet)
611  *      If successful, we return the number of bytes left to be written in the
612  *      system,
613  *      Otherwise we return a negative error number.
614  */
615 static int mos7720_chars_in_buffer(struct tty_struct *tty)
616 {
617         struct usb_serial_port *port = tty->driver_data;
618         int i;
619         int chars = 0;
620         struct moschip_port *mos7720_port;
621
622         dbg("%s:entering ...........", __func__);
623
624         mos7720_port = usb_get_serial_port_data(port);
625         if (mos7720_port == NULL) {
626                 dbg("%s:leaving ...........", __func__);
627                 return 0;
628         }
629
630         for (i = 0; i < NUM_URBS; ++i) {
631                 if (mos7720_port->write_urb_pool[i] &&
632                     mos7720_port->write_urb_pool[i]->status == -EINPROGRESS)
633                         chars += URB_TRANSFER_BUFFER_SIZE;
634         }
635         dbg("%s - returns %d", __func__, chars);
636         return chars;
637 }
638
639 static void mos7720_close(struct usb_serial_port *port)
640 {
641         struct usb_serial *serial;
642         struct moschip_port *mos7720_port;
643         char data;
644         int j;
645
646         dbg("mos7720_close:entering...");
647
648         serial = port->serial;
649
650         mos7720_port = usb_get_serial_port_data(port);
651         if (mos7720_port == NULL)
652                 return;
653
654         for (j = 0; j < NUM_URBS; ++j)
655                 usb_kill_urb(mos7720_port->write_urb_pool[j]);
656
657         /* Freeing Write URBs */
658         for (j = 0; j < NUM_URBS; ++j) {
659                 if (mos7720_port->write_urb_pool[j]) {
660                         kfree(mos7720_port->write_urb_pool[j]->transfer_buffer);
661                         usb_free_urb(mos7720_port->write_urb_pool[j]);
662                 }
663         }
664
665         /* While closing port, shutdown all bulk read, write  *
666          * and interrupt read if they exists, otherwise nop   */
667         dbg("Shutdown bulk write");
668         usb_kill_urb(port->write_urb);
669         dbg("Shutdown bulk read");
670         usb_kill_urb(port->read_urb);
671
672         mutex_lock(&serial->disc_mutex);
673         /* these commands must not be issued if the device has
674          * been disconnected */
675         if (!serial->disconnected) {
676                 data = 0x00;
677                 send_mos_cmd(serial, MOS_WRITE,
678                         port->number - port->serial->minor, 0x04, &data);
679
680                 data = 0x00;
681                 send_mos_cmd(serial, MOS_WRITE,
682                         port->number - port->serial->minor, 0x01, &data);
683         }
684         mutex_unlock(&serial->disc_mutex);
685         mos7720_port->open = 0;
686
687         dbg("Leaving %s", __func__);
688 }
689
690 static void mos7720_break(struct tty_struct *tty, int break_state)
691 {
692         struct usb_serial_port *port = tty->driver_data;
693         unsigned char data;
694         struct usb_serial *serial;
695         struct moschip_port *mos7720_port;
696
697         dbg("Entering %s", __func__);
698
699         serial = port->serial;
700
701         mos7720_port = usb_get_serial_port_data(port);
702         if (mos7720_port == NULL)
703                 return;
704
705         if (break_state == -1)
706                 data = mos7720_port->shadowLCR | UART_LCR_SBC;
707         else
708                 data = mos7720_port->shadowLCR & ~UART_LCR_SBC;
709
710         mos7720_port->shadowLCR  = data;
711         send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor,
712                      0x03, &data);
713
714         return;
715 }
716
717 /*
718  * mos7720_write_room
719  *      this function is called by the tty driver when it wants to know how many
720  *      bytes of data we can accept for a specific port.
721  *      If successful, we return the amount of room that we have for this port
722  *      Otherwise we return a negative error number.
723  */
724 static int mos7720_write_room(struct tty_struct *tty)
725 {
726         struct usb_serial_port *port = tty->driver_data;
727         struct moschip_port *mos7720_port;
728         int room = 0;
729         int i;
730
731         dbg("%s:entering ...........", __func__);
732
733         mos7720_port = usb_get_serial_port_data(port);
734         if (mos7720_port == NULL) {
735                 dbg("%s:leaving ...........", __func__);
736                 return -ENODEV;
737         }
738
739         /* FIXME: Locking */
740         for (i = 0; i < NUM_URBS; ++i) {
741                 if (mos7720_port->write_urb_pool[i] &&
742                     mos7720_port->write_urb_pool[i]->status != -EINPROGRESS)
743                         room += URB_TRANSFER_BUFFER_SIZE;
744         }
745
746         dbg("%s - returns %d", __func__, room);
747         return room;
748 }
749
750 static int mos7720_write(struct tty_struct *tty, struct usb_serial_port *port,
751                                  const unsigned char *data, int count)
752 {
753         int status;
754         int i;
755         int bytes_sent = 0;
756         int transfer_size;
757
758         struct moschip_port *mos7720_port;
759         struct usb_serial *serial;
760         struct urb    *urb;
761         const unsigned char *current_position = data;
762
763         dbg("%s:entering ...........", __func__);
764
765         serial = port->serial;
766
767         mos7720_port = usb_get_serial_port_data(port);
768         if (mos7720_port == NULL) {
769                 dbg("mos7720_port is NULL");
770                 return -ENODEV;
771         }
772
773         /* try to find a free urb in the list */
774         urb = NULL;
775
776         for (i = 0; i < NUM_URBS; ++i) {
777                 if (mos7720_port->write_urb_pool[i] &&
778                     mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) {
779                         urb = mos7720_port->write_urb_pool[i];
780                         dbg("URB:%d", i);
781                         break;
782                 }
783         }
784
785         if (urb == NULL) {
786                 dbg("%s - no more free urbs", __func__);
787                 goto exit;
788         }
789
790         if (urb->transfer_buffer == NULL) {
791                 urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
792                                                GFP_KERNEL);
793                 if (urb->transfer_buffer == NULL) {
794                         dev_err(&port->dev, "%s no more kernel memory...\n",
795                                 __func__);
796                         goto exit;
797                 }
798         }
799         transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE);
800
801         memcpy(urb->transfer_buffer, current_position, transfer_size);
802         usb_serial_debug_data(debug, &port->dev, __func__, transfer_size,
803                               urb->transfer_buffer);
804
805         /* fill urb with data and submit  */
806         usb_fill_bulk_urb(urb, serial->dev,
807                           usb_sndbulkpipe(serial->dev,
808                                         port->bulk_out_endpointAddress),
809                           urb->transfer_buffer, transfer_size,
810                           mos7720_bulk_out_data_callback, mos7720_port);
811
812         /* send it down the pipe */
813         status = usb_submit_urb(urb, GFP_ATOMIC);
814         if (status) {
815                 dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed "
816                         "with status = %d\n", __func__, status);
817                 bytes_sent = status;
818                 goto exit;
819         }
820         bytes_sent = transfer_size;
821
822 exit:
823         return bytes_sent;
824 }
825
826 static void mos7720_throttle(struct tty_struct *tty)
827 {
828         struct usb_serial_port *port = tty->driver_data;
829         struct moschip_port *mos7720_port;
830         int status;
831
832         dbg("%s- port %d", __func__, port->number);
833
834         mos7720_port = usb_get_serial_port_data(port);
835
836         if (mos7720_port == NULL)
837                 return;
838
839         if (!mos7720_port->open) {
840                 dbg("port not opened");
841                 return;
842         }
843
844         dbg("%s: Entering ..........", __func__);
845
846         /* if we are implementing XON/XOFF, send the stop character */
847         if (I_IXOFF(tty)) {
848                 unsigned char stop_char = STOP_CHAR(tty);
849                 status = mos7720_write(tty, port, &stop_char, 1);
850                 if (status <= 0)
851                         return;
852         }
853
854         /* if we are implementing RTS/CTS, toggle that line */
855         if (tty->termios->c_cflag & CRTSCTS) {
856                 mos7720_port->shadowMCR &= ~UART_MCR_RTS;
857                 status = send_mos_cmd(port->serial, MOS_WRITE,
858                                       port->number - port->serial->minor,
859                                       UART_MCR, &mos7720_port->shadowMCR);
860                 if (status != 0)
861                         return;
862         }
863 }
864
865 static void mos7720_unthrottle(struct tty_struct *tty)
866 {
867         struct usb_serial_port *port = tty->driver_data;
868         struct moschip_port *mos7720_port = usb_get_serial_port_data(port);
869         int status;
870
871         if (mos7720_port == NULL)
872                 return;
873
874         if (!mos7720_port->open) {
875                 dbg("%s - port not opened", __func__);
876                 return;
877         }
878
879         dbg("%s: Entering ..........", __func__);
880
881         /* if we are implementing XON/XOFF, send the start character */
882         if (I_IXOFF(tty)) {
883                 unsigned char start_char = START_CHAR(tty);
884                 status = mos7720_write(tty, port, &start_char, 1);
885                 if (status <= 0)
886                         return;
887         }
888
889         /* if we are implementing RTS/CTS, toggle that line */
890         if (tty->termios->c_cflag & CRTSCTS) {
891                 mos7720_port->shadowMCR |= UART_MCR_RTS;
892                 status = send_mos_cmd(port->serial, MOS_WRITE,
893                                       port->number - port->serial->minor,
894                                       UART_MCR, &mos7720_port->shadowMCR);
895                 if (status != 0)
896                         return;
897         }
898 }
899
900 static int set_higher_rates(struct moschip_port *mos7720_port,
901                             unsigned int baud)
902 {
903         unsigned char data;
904         struct usb_serial_port *port;
905         struct usb_serial *serial;
906         int port_number;
907
908         if (mos7720_port == NULL)
909                 return -EINVAL;
910
911         port = mos7720_port->port;
912         serial = port->serial;
913
914          /***********************************************
915          *      Init Sequence for higher rates
916          ***********************************************/
917         dbg("Sending Setting Commands ..........");
918         port_number = port->number - port->serial->minor;
919
920         data = 0x000;
921         send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
922         data = 0x000;
923         send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data);
924         data = 0x0CF;
925         send_mos_cmd(serial, MOS_WRITE, port->number, 0x02, &data);
926         data = 0x00b;
927         mos7720_port->shadowMCR  = data;
928         send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
929         data = 0x00b;
930         send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
931
932         data = 0x000;
933         send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data);
934         data = 0x000;
935         send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data);
936
937
938         /***********************************************
939          *              Set for higher rates           *
940          ***********************************************/
941
942         data = baud * 0x10;
943         send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data);
944
945         data = 0x003;
946         send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data);
947         data = 0x003;
948         send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data);
949
950         data = 0x02b;
951         mos7720_port->shadowMCR  = data;
952         send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
953         data = 0x02b;
954         send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
955
956         /***********************************************
957          *              Set DLL/DLM
958          ***********************************************/
959
960         data = mos7720_port->shadowLCR | UART_LCR_DLAB;
961         mos7720_port->shadowLCR  = data;
962         send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
963
964         data =  0x001; /* DLL */
965         send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data);
966         data =  0x000; /* DLM */
967         send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
968
969         data = mos7720_port->shadowLCR & ~UART_LCR_DLAB;
970         mos7720_port->shadowLCR  = data;
971         send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
972
973         return 0;
974 }
975
976 /* baud rate information */
977 struct divisor_table_entry {
978         __u32  baudrate;
979         __u16  divisor;
980 };
981
982 /* Define table of divisors for moschip 7720 hardware      *
983  * These assume a 3.6864MHz crystal, the standard /16, and *
984  * MCR.7 = 0.                                              */
985 static struct divisor_table_entry divisor_table[] = {
986         {   50,         2304},
987         {   110,        1047},  /* 2094.545455 => 230450   => .0217 % over */
988         {   134,        857},   /* 1713.011152 => 230398.5 => .00065% under */
989         {   150,        768},
990         {   300,        384},
991         {   600,        192},
992         {   1200,       96},
993         {   1800,       64},
994         {   2400,       48},
995         {   4800,       24},
996         {   7200,       16},
997         {   9600,       12},
998         {   19200,      6},
999         {   38400,      3},
1000         {   57600,      2},
1001         {   115200,     1},
1002 };
1003
1004 /*****************************************************************************
1005  * calc_baud_rate_divisor
1006  *      this function calculates the proper baud rate divisor for the specified
1007  *      baud rate.
1008  *****************************************************************************/
1009 static int calc_baud_rate_divisor(int baudrate, int *divisor)
1010 {
1011         int i;
1012         __u16 custom;
1013         __u16 round1;
1014         __u16 round;
1015
1016
1017         dbg("%s - %d", __func__, baudrate);
1018
1019         for (i = 0; i < ARRAY_SIZE(divisor_table); i++) {
1020                 if (divisor_table[i].baudrate == baudrate) {
1021                         *divisor = divisor_table[i].divisor;
1022                         return 0;
1023                 }
1024         }
1025
1026         /* After trying for all the standard baud rates    *
1027          * Try calculating the divisor for this baud rate  */
1028         if (baudrate > 75 &&  baudrate < 230400) {
1029                 /* get the divisor */
1030                 custom = (__u16)(230400L  / baudrate);
1031
1032                 /* Check for round off */
1033                 round1 = (__u16)(2304000L / baudrate);
1034                 round = (__u16)(round1 - (custom * 10));
1035                 if (round > 4)
1036                         custom++;
1037                 *divisor = custom;
1038
1039                 dbg("Baud %d = %d", baudrate, custom);
1040                 return 0;
1041         }
1042
1043         dbg("Baud calculation Failed...");
1044         return -EINVAL;
1045 }
1046
1047 /*
1048  * send_cmd_write_baud_rate
1049  *      this function sends the proper command to change the baud rate of the
1050  *      specified port.
1051  */
1052 static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port,
1053                                     int baudrate)
1054 {
1055         struct usb_serial_port *port;
1056         struct usb_serial *serial;
1057         int divisor;
1058         int status;
1059         unsigned char data;
1060         unsigned char number;
1061
1062         if (mos7720_port == NULL)
1063                 return -1;
1064
1065         port = mos7720_port->port;
1066         serial = port->serial;
1067
1068         dbg("%s: Entering ..........", __func__);
1069
1070         number = port->number - port->serial->minor;
1071         dbg("%s - port = %d, baud = %d", __func__, port->number, baudrate);
1072
1073         /* Calculate the Divisor */
1074         status = calc_baud_rate_divisor(baudrate, &divisor);
1075         if (status) {
1076                 dev_err(&port->dev, "%s - bad baud rate\n", __func__);
1077                 return status;
1078         }
1079
1080         /* Enable access to divisor latch */
1081         data = mos7720_port->shadowLCR | UART_LCR_DLAB;
1082         mos7720_port->shadowLCR  = data;
1083         send_mos_cmd(serial, MOS_WRITE, number, UART_LCR, &data);
1084
1085         /* Write the divisor */
1086         data = ((unsigned char)(divisor & 0xff));
1087         send_mos_cmd(serial, MOS_WRITE, number, 0x00, &data);
1088
1089         data = ((unsigned char)((divisor & 0xff00) >> 8));
1090         send_mos_cmd(serial, MOS_WRITE, number, 0x01, &data);
1091
1092         /* Disable access to divisor latch */
1093         data = mos7720_port->shadowLCR & ~UART_LCR_DLAB;
1094         mos7720_port->shadowLCR = data;
1095         send_mos_cmd(serial, MOS_WRITE, number, 0x03, &data);
1096
1097         return status;
1098 }
1099
1100 /*
1101  * change_port_settings
1102  *      This routine is called to set the UART on the device to match
1103  *      the specified new settings.
1104  */
1105 static void change_port_settings(struct tty_struct *tty,
1106                                  struct moschip_port *mos7720_port,
1107                                  struct ktermios *old_termios)
1108 {
1109         struct usb_serial_port *port;
1110         struct usb_serial *serial;
1111         int baud;
1112         unsigned cflag;
1113         unsigned iflag;
1114         __u8 mask = 0xff;
1115         __u8 lData;
1116         __u8 lParity;
1117         __u8 lStop;
1118         int status;
1119         int port_number;
1120         char data;
1121
1122         if (mos7720_port == NULL)
1123                 return ;
1124
1125         port = mos7720_port->port;
1126         serial = port->serial;
1127         port_number = port->number - port->serial->minor;
1128
1129         dbg("%s - port %d", __func__, port->number);
1130
1131         if (!mos7720_port->open) {
1132                 dbg("%s - port not opened", __func__);
1133                 return;
1134         }
1135
1136         dbg("%s: Entering ..........", __func__);
1137
1138         lData = UART_LCR_WLEN8;
1139         lStop = 0x00;   /* 1 stop bit */
1140         lParity = 0x00; /* No parity */
1141
1142         cflag = tty->termios->c_cflag;
1143         iflag = tty->termios->c_iflag;
1144
1145         /* Change the number of bits */
1146         switch (cflag & CSIZE) {
1147         case CS5:
1148                 lData = UART_LCR_WLEN5;
1149                 mask = 0x1f;
1150                 break;
1151
1152         case CS6:
1153                 lData = UART_LCR_WLEN6;
1154                 mask = 0x3f;
1155                 break;
1156
1157         case CS7:
1158                 lData = UART_LCR_WLEN7;
1159                 mask = 0x7f;
1160                 break;
1161         default:
1162         case CS8:
1163                 lData = UART_LCR_WLEN8;
1164                 break;
1165         }
1166
1167         /* Change the Parity bit */
1168         if (cflag & PARENB) {
1169                 if (cflag & PARODD) {
1170                         lParity = UART_LCR_PARITY;
1171                         dbg("%s - parity = odd", __func__);
1172                 } else {
1173                         lParity = (UART_LCR_EPAR | UART_LCR_PARITY);
1174                         dbg("%s - parity = even", __func__);
1175                 }
1176
1177         } else {
1178                 dbg("%s - parity = none", __func__);
1179         }
1180
1181         if (cflag & CMSPAR)
1182                 lParity = lParity | 0x20;
1183
1184         /* Change the Stop bit */
1185         if (cflag & CSTOPB) {
1186                 lStop = UART_LCR_STOP;
1187                 dbg("%s - stop bits = 2", __func__);
1188         } else {
1189                 lStop = 0x00;
1190                 dbg("%s - stop bits = 1", __func__);
1191         }
1192
1193 #define LCR_BITS_MASK           0x03    /* Mask for bits/char field */
1194 #define LCR_STOP_MASK           0x04    /* Mask for stop bits field */
1195 #define LCR_PAR_MASK            0x38    /* Mask for parity field */
1196
1197         /* Update the LCR with the correct value */
1198         mos7720_port->shadowLCR &=
1199                         ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK);
1200         mos7720_port->shadowLCR |= (lData | lParity | lStop);
1201
1202
1203         /* Disable Interrupts */
1204         data = 0x00;
1205         send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor,
1206                                                         UART_IER, &data);
1207
1208         data = 0x00;
1209         send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data);
1210
1211         data = 0xcf;
1212         send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data);
1213
1214         /* Send the updated LCR value to the mos7720 */
1215         data = mos7720_port->shadowLCR;
1216         send_mos_cmd(serial, MOS_WRITE, port_number, UART_LCR, &data);
1217
1218         data = 0x00b;
1219         mos7720_port->shadowMCR = data;
1220         send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
1221         data = 0x00b;
1222         send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
1223
1224         /* set up the MCR register and send it to the mos7720 */
1225         mos7720_port->shadowMCR = UART_MCR_OUT2;
1226         if (cflag & CBAUD)
1227                 mos7720_port->shadowMCR |= (UART_MCR_DTR | UART_MCR_RTS);
1228
1229         if (cflag & CRTSCTS) {
1230                 mos7720_port->shadowMCR |= (UART_MCR_XONANY);
1231                 /* To set hardware flow control to the specified *
1232                  * serial port, in SP1/2_CONTROL_REG             */
1233                 if (port->number) {
1234                         data = 0x001;
1235                         send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT,
1236                                      0x08, &data);
1237                 } else {
1238                         data = 0x002;
1239                         send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT,
1240                                      0x08, &data);
1241                 }
1242         } else {
1243                 mos7720_port->shadowMCR &= ~(UART_MCR_XONANY);
1244         }
1245
1246         data = mos7720_port->shadowMCR;
1247         send_mos_cmd(serial, MOS_WRITE, port_number, UART_MCR, &data);
1248
1249         /* Determine divisor based on baud rate */
1250         baud = tty_get_baud_rate(tty);
1251         if (!baud) {
1252                 /* pick a default, any default... */
1253                 dbg("Picked default baud...");
1254                 baud = 9600;
1255         }
1256
1257         if (baud >= 230400) {
1258                 set_higher_rates(mos7720_port, baud);
1259                 /* Enable Interrupts */
1260                 data = 0x0c;
1261                 send_mos_cmd(serial, MOS_WRITE, port_number, UART_IER, &data);
1262                 return;
1263         }
1264
1265         dbg("%s - baud rate = %d", __func__, baud);
1266         status = send_cmd_write_baud_rate(mos7720_port, baud);
1267         /* FIXME: needs to write actual resulting baud back not just
1268            blindly do so */
1269         if (cflag & CBAUD)
1270                 tty_encode_baud_rate(tty, baud, baud);
1271         /* Enable Interrupts */
1272         data = 0x0c;
1273         send_mos_cmd(serial, MOS_WRITE, port_number, UART_IER, &data);
1274
1275         if (port->read_urb->status != -EINPROGRESS) {
1276                 port->read_urb->dev = serial->dev;
1277
1278                 status = usb_submit_urb(port->read_urb, GFP_ATOMIC);
1279                 if (status)
1280                         dbg("usb_submit_urb(read bulk) failed, status = %d",
1281                             status);
1282         }
1283         return;
1284 }
1285
1286 /*
1287  * mos7720_set_termios
1288  *      this function is called by the tty driver when it wants to change the
1289  *      termios structure.
1290  */
1291 static void mos7720_set_termios(struct tty_struct *tty,
1292                 struct usb_serial_port *port, struct ktermios *old_termios)
1293 {
1294         int status;
1295         unsigned int cflag;
1296         struct usb_serial *serial;
1297         struct moschip_port *mos7720_port;
1298
1299         serial = port->serial;
1300
1301         mos7720_port = usb_get_serial_port_data(port);
1302
1303         if (mos7720_port == NULL)
1304                 return;
1305
1306         if (!mos7720_port->open) {
1307                 dbg("%s - port not opened", __func__);
1308                 return;
1309         }
1310
1311         dbg("setting termios - ASPIRE");
1312
1313         cflag = tty->termios->c_cflag;
1314
1315         dbg("%s - cflag %08x iflag %08x", __func__,
1316             tty->termios->c_cflag,
1317             RELEVANT_IFLAG(tty->termios->c_iflag));
1318
1319         dbg("%s - old cflag %08x old iflag %08x", __func__,
1320             old_termios->c_cflag,
1321             RELEVANT_IFLAG(old_termios->c_iflag));
1322
1323         dbg("%s - port %d", __func__, port->number);
1324
1325         /* change the port settings to the new ones specified */
1326         change_port_settings(tty, mos7720_port, old_termios);
1327
1328         if (!port->read_urb) {
1329                 dbg("URB KILLED !!!!!");
1330                 return;
1331         }
1332
1333         if (port->read_urb->status != -EINPROGRESS) {
1334                 port->read_urb->dev = serial->dev;
1335                 status = usb_submit_urb(port->read_urb, GFP_ATOMIC);
1336                 if (status)
1337                         dbg("usb_submit_urb(read bulk) failed, status = %d",
1338                             status);
1339         }
1340         return;
1341 }
1342
1343 /*
1344  * get_lsr_info - get line status register info
1345  *
1346  * Purpose: Let user call ioctl() to get info when the UART physically
1347  *          is emptied.  On bus types like RS485, the transmitter must
1348  *          release the bus after transmitting. This must be done when
1349  *          the transmit shift register is empty, not be done when the
1350  *          transmit holding register is empty.  This functionality
1351  *          allows an RS485 driver to be written in user space.
1352  */
1353 static int get_lsr_info(struct tty_struct *tty,
1354                 struct moschip_port *mos7720_port, unsigned int __user *value)
1355 {
1356         struct usb_serial_port *port = tty->driver_data;
1357         unsigned int result = 0;
1358         unsigned char data = 0;
1359         int port_number = port->number - port->serial->minor;
1360         int count;
1361
1362         count = mos7720_chars_in_buffer(tty);
1363         if (count == 0) {
1364                 send_mos_cmd(port->serial, MOS_READ, port_number,
1365                                                         UART_LSR, &data);
1366                 if ((data & (UART_LSR_TEMT | UART_LSR_THRE))
1367                                         == (UART_LSR_TEMT | UART_LSR_THRE)) {
1368                         dbg("%s -- Empty", __func__);
1369                         result = TIOCSER_TEMT;
1370                 }
1371         }
1372         if (copy_to_user(value, &result, sizeof(int)))
1373                 return -EFAULT;
1374         return 0;
1375 }
1376
1377 static int mos7720_tiocmget(struct tty_struct *tty, struct file *file)
1378 {
1379         struct usb_serial_port *port = tty->driver_data;
1380         struct moschip_port *mos7720_port = usb_get_serial_port_data(port);
1381         unsigned int result = 0;
1382         unsigned int mcr ;
1383         unsigned int msr ;
1384
1385         dbg("%s - port %d", __func__, port->number);
1386
1387         mcr = mos7720_port->shadowMCR;
1388         msr = mos7720_port->shadowMSR;
1389
1390         result = ((mcr & UART_MCR_DTR)  ? TIOCM_DTR : 0)   /* 0x002 */
1391           | ((mcr & UART_MCR_RTS)   ? TIOCM_RTS : 0)   /* 0x004 */
1392           | ((msr & UART_MSR_CTS)   ? TIOCM_CTS : 0)   /* 0x020 */
1393           | ((msr & UART_MSR_DCD)   ? TIOCM_CAR : 0)   /* 0x040 */
1394           | ((msr & UART_MSR_RI)    ? TIOCM_RI :  0)   /* 0x080 */
1395           | ((msr & UART_MSR_DSR)   ? TIOCM_DSR : 0);  /* 0x100 */
1396
1397         dbg("%s -- %x", __func__, result);
1398
1399         return result;
1400 }
1401
1402 static int mos7720_tiocmset(struct tty_struct *tty, struct file *file,
1403                                         unsigned int set, unsigned int clear)
1404 {
1405         struct usb_serial_port *port = tty->driver_data;
1406         struct moschip_port *mos7720_port = usb_get_serial_port_data(port);
1407         unsigned int mcr ;
1408         unsigned char lmcr;
1409
1410         dbg("%s - port %d", __func__, port->number);
1411         dbg("he was at tiocmget");
1412
1413         mcr = mos7720_port->shadowMCR;
1414
1415         if (set & TIOCM_RTS)
1416                 mcr |= UART_MCR_RTS;
1417         if (set & TIOCM_DTR)
1418                 mcr |= UART_MCR_DTR;
1419         if (set & TIOCM_LOOP)
1420                 mcr |= UART_MCR_LOOP;
1421
1422         if (clear & TIOCM_RTS)
1423                 mcr &= ~UART_MCR_RTS;
1424         if (clear & TIOCM_DTR)
1425                 mcr &= ~UART_MCR_DTR;
1426         if (clear & TIOCM_LOOP)
1427                 mcr &= ~UART_MCR_LOOP;
1428
1429         mos7720_port->shadowMCR = mcr;
1430         lmcr = mos7720_port->shadowMCR;
1431
1432         send_mos_cmd(port->serial, MOS_WRITE,
1433                 port->number - port->serial->minor, UART_MCR, &lmcr);
1434
1435         return 0;
1436 }
1437
1438 static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd,
1439                           unsigned int __user *value)
1440 {
1441         unsigned int mcr ;
1442         unsigned int arg;
1443         unsigned char data;
1444
1445         struct usb_serial_port *port;
1446
1447         if (mos7720_port == NULL)
1448                 return -1;
1449
1450         port = (struct usb_serial_port *)mos7720_port->port;
1451         mcr = mos7720_port->shadowMCR;
1452
1453         if (copy_from_user(&arg, value, sizeof(int)))
1454                 return -EFAULT;
1455
1456         switch (cmd) {
1457         case TIOCMBIS:
1458                 if (arg & TIOCM_RTS)
1459                         mcr |= UART_MCR_RTS;
1460                 if (arg & TIOCM_DTR)
1461                         mcr |= UART_MCR_RTS;
1462                 if (arg & TIOCM_LOOP)
1463                         mcr |= UART_MCR_LOOP;
1464                 break;
1465
1466         case TIOCMBIC:
1467                 if (arg & TIOCM_RTS)
1468                         mcr &= ~UART_MCR_RTS;
1469                 if (arg & TIOCM_DTR)
1470                         mcr &= ~UART_MCR_RTS;
1471                 if (arg & TIOCM_LOOP)
1472                         mcr &= ~UART_MCR_LOOP;
1473                 break;
1474
1475         }
1476
1477         mos7720_port->shadowMCR = mcr;
1478
1479         data = mos7720_port->shadowMCR;
1480         send_mos_cmd(port->serial, MOS_WRITE,
1481                      port->number - port->serial->minor, UART_MCR, &data);
1482
1483         return 0;
1484 }
1485
1486 static int get_serial_info(struct moschip_port *mos7720_port,
1487                            struct serial_struct __user *retinfo)
1488 {
1489         struct serial_struct tmp;
1490
1491         if (!retinfo)
1492                 return -EFAULT;
1493
1494         memset(&tmp, 0, sizeof(tmp));
1495
1496         tmp.type                = PORT_16550A;
1497         tmp.line                = mos7720_port->port->serial->minor;
1498         tmp.port                = mos7720_port->port->number;
1499         tmp.irq                 = 0;
1500         tmp.flags               = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
1501         tmp.xmit_fifo_size      = NUM_URBS * URB_TRANSFER_BUFFER_SIZE;
1502         tmp.baud_base           = 9600;
1503         tmp.close_delay         = 5*HZ;
1504         tmp.closing_wait        = 30*HZ;
1505
1506         if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
1507                 return -EFAULT;
1508         return 0;
1509 }
1510
1511 static int mos7720_ioctl(struct tty_struct *tty, struct file *file,
1512                          unsigned int cmd, unsigned long arg)
1513 {
1514         struct usb_serial_port *port = tty->driver_data;
1515         struct moschip_port *mos7720_port;
1516         struct async_icount cnow;
1517         struct async_icount cprev;
1518         struct serial_icounter_struct icount;
1519
1520         mos7720_port = usb_get_serial_port_data(port);
1521         if (mos7720_port == NULL)
1522                 return -ENODEV;
1523
1524         dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
1525
1526         switch (cmd) {
1527         case TIOCSERGETLSR:
1528                 dbg("%s (%d) TIOCSERGETLSR", __func__,  port->number);
1529                 return get_lsr_info(tty, mos7720_port,
1530                                         (unsigned int __user *)arg);
1531                 return 0;
1532
1533         /* FIXME: These should be using the mode methods */
1534         case TIOCMBIS:
1535         case TIOCMBIC:
1536                 dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET",
1537                                         __func__, port->number);
1538                 return set_modem_info(mos7720_port, cmd,
1539                                       (unsigned int __user *)arg);
1540
1541         case TIOCGSERIAL:
1542                 dbg("%s (%d) TIOCGSERIAL", __func__,  port->number);
1543                 return get_serial_info(mos7720_port,
1544                                        (struct serial_struct __user *)arg);
1545
1546         case TIOCMIWAIT:
1547                 dbg("%s (%d) TIOCMIWAIT", __func__,  port->number);
1548                 cprev = mos7720_port->icount;
1549                 while (1) {
1550                         if (signal_pending(current))
1551                                 return -ERESTARTSYS;
1552                         cnow = mos7720_port->icount;
1553                         if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
1554                             cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
1555                                 return -EIO; /* no change => error */
1556                         if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
1557                             ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
1558                             ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
1559                             ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
1560                                 return 0;
1561                         }
1562                         cprev = cnow;
1563                 }
1564                 /* NOTREACHED */
1565                 break;
1566
1567         case TIOCGICOUNT:
1568                 cnow = mos7720_port->icount;
1569                 icount.cts = cnow.cts;
1570                 icount.dsr = cnow.dsr;
1571                 icount.rng = cnow.rng;
1572                 icount.dcd = cnow.dcd;
1573                 icount.rx = cnow.rx;
1574                 icount.tx = cnow.tx;
1575                 icount.frame = cnow.frame;
1576                 icount.overrun = cnow.overrun;
1577                 icount.parity = cnow.parity;
1578                 icount.brk = cnow.brk;
1579                 icount.buf_overrun = cnow.buf_overrun;
1580
1581                 dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __func__,
1582                     port->number, icount.rx, icount.tx);
1583                 if (copy_to_user((void __user *)arg, &icount, sizeof(icount)))
1584                         return -EFAULT;
1585                 return 0;
1586         }
1587
1588         return -ENOIOCTLCMD;
1589 }
1590
1591 static int mos7720_startup(struct usb_serial *serial)
1592 {
1593         struct moschip_serial *mos7720_serial;
1594         struct moschip_port *mos7720_port;
1595         struct usb_device *dev;
1596         int i;
1597         char data;
1598         u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
1599
1600         dbg("%s: Entering ..........", __func__);
1601
1602         if (!serial) {
1603                 dbg("Invalid Handler");
1604                 return -ENODEV;
1605         }
1606
1607         dev = serial->dev;
1608
1609         /* create our private serial structure */
1610         mos7720_serial = kzalloc(sizeof(struct moschip_serial), GFP_KERNEL);
1611         if (mos7720_serial == NULL) {
1612                 dev_err(&dev->dev, "%s - Out of memory\n", __func__);
1613                 return -ENOMEM;
1614         }
1615
1616         usb_set_serial_data(serial, mos7720_serial);
1617
1618         /*
1619          * The 7715 uses the first bulk in/out endpoint pair for the parallel
1620          * port, and the second for the serial port.  Because the usbserial core
1621          * assumes both pairs are serial ports, we must engage in a bit of
1622          * subterfuge and swap the pointers for ports 0 and 1 in order to make
1623          * port 0 point to the serial port.  However, both moschip devices use a
1624          * single interrupt-in endpoint for both ports (as mentioned a little
1625          * further down), and this endpoint was assigned to port 0.  So after
1626          * the swap, we must copy the interrupt endpoint elements from port 1
1627          * (as newly assigned) to port 0, and null out port 1 pointers.
1628          */
1629         if (product == MOSCHIP_DEVICE_ID_7715) {
1630                 struct usb_serial_port *tmp = serial->port[0];
1631                 serial->port[0] = serial->port[1];
1632                 serial->port[1] = tmp;
1633                 serial->port[0]->interrupt_in_urb = tmp->interrupt_in_urb;
1634                 serial->port[0]->interrupt_in_buffer = tmp->interrupt_in_buffer;
1635                 serial->port[0]->interrupt_in_endpointAddress =
1636                         tmp->interrupt_in_endpointAddress;
1637                 serial->port[1]->interrupt_in_urb = NULL;
1638                 serial->port[1]->interrupt_in_buffer = NULL;
1639         }
1640
1641         /* we set up the pointers to the endpoints in the mos7720_open *
1642          * function, as the structures aren't created yet.             */
1643
1644         /* set up port private structures */
1645         for (i = 0; i < serial->num_ports; ++i) {
1646                 mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
1647                 if (mos7720_port == NULL) {
1648                         dev_err(&dev->dev, "%s - Out of memory\n", __func__);
1649                         usb_set_serial_data(serial, NULL);
1650                         kfree(mos7720_serial);
1651                         return -ENOMEM;
1652                 }
1653
1654                 /* Initialize all port interrupt end point to port 0 int
1655                  * endpoint.  Our device has only one interrupt endpoint
1656                  * common to all ports */
1657                 serial->port[i]->interrupt_in_endpointAddress =
1658                                 serial->port[0]->interrupt_in_endpointAddress;
1659
1660                 mos7720_port->port = serial->port[i];
1661                 usb_set_serial_port_data(serial->port[i], mos7720_port);
1662
1663                 dbg("port number is %d", serial->port[i]->number);
1664                 dbg("serial number is %d", serial->minor);
1665         }
1666
1667
1668         /* setting configuration feature to one */
1669         usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
1670                         (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ);
1671
1672         /* LSR For Port 1 */
1673         send_mos_cmd(serial, MOS_READ, 0x00, UART_LSR, &data);
1674         dbg("LSR:%x", data);
1675
1676         /* LSR For Port 2 */
1677         send_mos_cmd(serial, MOS_READ, 0x01, UART_LSR, &data);
1678         dbg("LSR:%x", data);
1679
1680         return 0;
1681 }
1682
1683 static void mos7720_release(struct usb_serial *serial)
1684 {
1685         int i;
1686
1687         /* free private structure allocated for serial port */
1688         for (i = 0; i < serial->num_ports; ++i)
1689                 kfree(usb_get_serial_port_data(serial->port[i]));
1690
1691         /* free private structure allocated for serial device */
1692         kfree(usb_get_serial_data(serial));
1693 }
1694
1695 static struct usb_driver usb_driver = {
1696         .name =         "moschip7720",
1697         .probe =        usb_serial_probe,
1698         .disconnect =   usb_serial_disconnect,
1699         .id_table =     moschip_port_id_table,
1700         .no_dynamic_id =        1,
1701 };
1702
1703 static struct usb_serial_driver moschip7720_2port_driver = {
1704         .driver = {
1705                 .owner =        THIS_MODULE,
1706                 .name =         "moschip7720",
1707         },
1708         .description            = "Moschip 2 port adapter",
1709         .usb_driver             = &usb_driver,
1710         .id_table               = moschip_port_id_table,
1711         .calc_num_ports         = mos77xx_calc_num_ports,
1712         .open                   = mos7720_open,
1713         .close                  = mos7720_close,
1714         .throttle               = mos7720_throttle,
1715         .unthrottle             = mos7720_unthrottle,
1716         .probe                  = mos77xx_probe,
1717         .attach                 = mos7720_startup,
1718         .release                = mos7720_release,
1719         .ioctl                  = mos7720_ioctl,
1720         .tiocmget               = mos7720_tiocmget,
1721         .tiocmset               = mos7720_tiocmset,
1722         .set_termios            = mos7720_set_termios,
1723         .write                  = mos7720_write,
1724         .write_room             = mos7720_write_room,
1725         .chars_in_buffer        = mos7720_chars_in_buffer,
1726         .break_ctl              = mos7720_break,
1727         .read_bulk_callback     = mos7720_bulk_in_callback,
1728         .read_int_callback      = NULL  /* dynamically assigned in probe() */
1729 };
1730
1731 static int __init moschip7720_init(void)
1732 {
1733         int retval;
1734
1735         dbg("%s: Entering ..........", __func__);
1736
1737         /* Register with the usb serial */
1738         retval = usb_serial_register(&moschip7720_2port_driver);
1739         if (retval)
1740                 goto failed_port_device_register;
1741
1742         printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
1743                DRIVER_DESC "\n");
1744
1745         /* Register with the usb */
1746         retval = usb_register(&usb_driver);
1747         if (retval)
1748                 goto failed_usb_register;
1749
1750         return 0;
1751
1752 failed_usb_register:
1753         usb_serial_deregister(&moschip7720_2port_driver);
1754
1755 failed_port_device_register:
1756         return retval;
1757 }
1758
1759 static void __exit moschip7720_exit(void)
1760 {
1761         usb_deregister(&usb_driver);
1762         usb_serial_deregister(&moschip7720_2port_driver);
1763 }
1764
1765 module_init(moschip7720_init);
1766 module_exit(moschip7720_exit);
1767
1768 /* Module information */
1769 MODULE_AUTHOR(DRIVER_AUTHOR);
1770 MODULE_DESCRIPTION(DRIVER_DESC);
1771 MODULE_LICENSE("GPL");
1772
1773 module_param(debug, bool, S_IRUGO | S_IWUSR);
1774 MODULE_PARM_DESC(debug, "Debug enabled or not");