USB: add SPDX identifiers to all remaining files in drivers/usb/
[linux-2.6-block.git] / drivers / usb / serial / mos7840.c
CommitLineData
5fd54ace 1// SPDX-License-Identifier: GPL-2.0+
3f542974
PS
2/*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Clean ups from Moschip version and a few ioctl implementations by:
18 * Paul B Schroeder <pschroeder "at" uplogix "dot" com>
19 *
20 * Originally based on drivers/usb/serial/io_edgeport.c which is:
21 * Copyright (C) 2000 Inside Out Networks, All rights reserved.
22 * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com>
23 *
24 */
25
26#include <linux/kernel.h>
27#include <linux/errno.h>
3f542974
PS
28#include <linux/slab.h>
29#include <linux/tty.h>
30#include <linux/tty_driver.h>
31#include <linux/tty_flip.h>
32#include <linux/module.h>
33#include <linux/serial.h>
34#include <linux/usb.h>
35#include <linux/usb/serial.h>
880af9db 36#include <linux/uaccess.h>
3f542974 37
3f542974
PS
38#define DRIVER_DESC "Moschip 7840/7820 USB Serial Driver"
39
40/*
41 * 16C50 UART register defines
42 */
43
44#define LCR_BITS_5 0x00 /* 5 bits/char */
45#define LCR_BITS_6 0x01 /* 6 bits/char */
46#define LCR_BITS_7 0x02 /* 7 bits/char */
47#define LCR_BITS_8 0x03 /* 8 bits/char */
48#define LCR_BITS_MASK 0x03 /* Mask for bits/char field */
49
50#define LCR_STOP_1 0x00 /* 1 stop bit */
51#define LCR_STOP_1_5 0x04 /* 1.5 stop bits (if 5 bits/char) */
52#define LCR_STOP_2 0x04 /* 2 stop bits (if 6-8 bits/char) */
53#define LCR_STOP_MASK 0x04 /* Mask for stop bits field */
54
55#define LCR_PAR_NONE 0x00 /* No parity */
56#define LCR_PAR_ODD 0x08 /* Odd parity */
57#define LCR_PAR_EVEN 0x18 /* Even parity */
58#define LCR_PAR_MARK 0x28 /* Force parity bit to 1 */
59#define LCR_PAR_SPACE 0x38 /* Force parity bit to 0 */
60#define LCR_PAR_MASK 0x38 /* Mask for parity field */
61
62#define LCR_SET_BREAK 0x40 /* Set Break condition */
63#define LCR_DL_ENABLE 0x80 /* Enable access to divisor latch */
64
65#define MCR_DTR 0x01 /* Assert DTR */
66#define MCR_RTS 0x02 /* Assert RTS */
67#define MCR_OUT1 0x04 /* Loopback only: Sets state of RI */
68#define MCR_MASTER_IE 0x08 /* Enable interrupt outputs */
69#define MCR_LOOPBACK 0x10 /* Set internal (digital) loopback mode */
70#define MCR_XON_ANY 0x20 /* Enable any char to exit XOFF mode */
71
72#define MOS7840_MSR_CTS 0x10 /* Current state of CTS */
73#define MOS7840_MSR_DSR 0x20 /* Current state of DSR */
74#define MOS7840_MSR_RI 0x40 /* Current state of RI */
75#define MOS7840_MSR_CD 0x80 /* Current state of CD */
76
77/*
78 * Defines used for sending commands to port
79 */
80
1e658489 81#define MOS_WDR_TIMEOUT 5000 /* default urb timeout */
3f542974
PS
82
83#define MOS_PORT1 0x0200
84#define MOS_PORT2 0x0300
85#define MOS_VENREG 0x0000
86#define MOS_MAX_PORT 0x02
87#define MOS_WRITE 0x0E
88#define MOS_READ 0x0D
89
90/* Requests */
91#define MCS_RD_RTYPE 0xC0
92#define MCS_WR_RTYPE 0x40
93#define MCS_RDREQ 0x0D
94#define MCS_WRREQ 0x0E
95#define MCS_CTRL_TIMEOUT 500
96#define VENDOR_READ_LENGTH (0x01)
97
98#define MAX_NAME_LEN 64
99
880af9db
AC
100#define ZLP_REG1 0x3A /* Zero_Flag_Reg1 58 */
101#define ZLP_REG5 0x3E /* Zero_Flag_Reg5 62 */
3f542974
PS
102
103/* For higher baud Rates use TIOCEXBAUD */
104#define TIOCEXBAUD 0x5462
105
106/* vendor id and device id defines */
107
11e1abb4 108/* The native mos7840/7820 component */
3f542974
PS
109#define USB_VENDOR_ID_MOSCHIP 0x9710
110#define MOSCHIP_DEVICE_ID_7840 0x7840
111#define MOSCHIP_DEVICE_ID_7820 0x7820
0eafe4de 112#define MOSCHIP_DEVICE_ID_7810 0x7810
11e1abb4
DL
113/* The native component can have its vendor/device id's overridden
114 * in vendor-specific implementations. Such devices can be handled
68e24113 115 * by making a change here, in id_table.
11e1abb4 116 */
870408c8
DL
117#define USB_VENDOR_ID_BANDB 0x0856
118#define BANDB_DEVICE_ID_USO9ML2_2 0xAC22
119#define BANDB_DEVICE_ID_USO9ML2_2P 0xBC00
120#define BANDB_DEVICE_ID_USO9ML2_4 0xAC24
121#define BANDB_DEVICE_ID_USO9ML2_4P 0xBC01
122#define BANDB_DEVICE_ID_US9ML2_2 0xAC29
123#define BANDB_DEVICE_ID_US9ML2_4 0xAC30
124#define BANDB_DEVICE_ID_USPTL4_2 0xAC31
125#define BANDB_DEVICE_ID_USPTL4_4 0xAC32
126#define BANDB_DEVICE_ID_USOPTL4_2 0xAC42
127#define BANDB_DEVICE_ID_USOPTL4_2P 0xBC02
128#define BANDB_DEVICE_ID_USOPTL4_4 0xAC44
129#define BANDB_DEVICE_ID_USOPTL4_4P 0xBC03
130#define BANDB_DEVICE_ID_USOPTL2_4 0xAC24
3f542974 131
9d498bea
RL
132/* This driver also supports
133 * ATEN UC2324 device using Moschip MCS7840
134 * ATEN UC2322 device using Moschip MCS7820
135 */
e9b8cffa
TC
136#define USB_VENDOR_ID_ATENINTL 0x0557
137#define ATENINTL_DEVICE_ID_UC2324 0x2011
9d498bea 138#define ATENINTL_DEVICE_ID_UC2322 0x7820
e9b8cffa 139
11e1abb4 140/* Interrupt Routine Defines */
3f542974
PS
141
142#define SERIAL_IIR_RLS 0x06
143#define SERIAL_IIR_MS 0x00
144
145/*
146 * Emulation of the bit mask on the LINE STATUS REGISTER.
147 */
148#define SERIAL_LSR_DR 0x0001
149#define SERIAL_LSR_OE 0x0002
150#define SERIAL_LSR_PE 0x0004
151#define SERIAL_LSR_FE 0x0008
152#define SERIAL_LSR_BI 0x0010
153
154#define MOS_MSR_DELTA_CTS 0x10
155#define MOS_MSR_DELTA_DSR 0x20
156#define MOS_MSR_DELTA_RI 0x40
157#define MOS_MSR_DELTA_CD 0x80
158
880af9db 159/* Serial Port register Address */
3f542974
PS
160#define INTERRUPT_ENABLE_REGISTER ((__u16)(0x01))
161#define FIFO_CONTROL_REGISTER ((__u16)(0x02))
162#define LINE_CONTROL_REGISTER ((__u16)(0x03))
163#define MODEM_CONTROL_REGISTER ((__u16)(0x04))
164#define LINE_STATUS_REGISTER ((__u16)(0x05))
165#define MODEM_STATUS_REGISTER ((__u16)(0x06))
166#define SCRATCH_PAD_REGISTER ((__u16)(0x07))
167#define DIVISOR_LATCH_LSB ((__u16)(0x00))
168#define DIVISOR_LATCH_MSB ((__u16)(0x01))
169
170#define CLK_MULTI_REGISTER ((__u16)(0x02))
171#define CLK_START_VALUE_REGISTER ((__u16)(0x03))
093ea2d3 172#define GPIO_REGISTER ((__u16)(0x07))
3f542974
PS
173
174#define SERIAL_LCR_DLAB ((__u16)(0x0080))
175
176/*
177 * URB POOL related defines
178 */
179#define NUM_URBS 16 /* URB Count */
180#define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */
181
0eafe4de
D
182/* LED on/off milliseconds*/
183#define LED_ON_MS 500
184#define LED_OFF_MS 500
185
d8a083cc
JH
186enum mos7840_flag {
187 MOS7840_FLAG_CTRL_BUSY,
05cf0dec 188 MOS7840_FLAG_LED_BUSY,
d8a083cc 189};
3f542974 190
b9c87663 191static const struct usb_device_id id_table[] = {
3f542974
PS
192 {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
193 {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
0eafe4de 194 {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7810)},
acf509ae 195 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
870408c8 196 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)},
acf509ae 197 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
870408c8 198 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4P)},
acf509ae
CB
199 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)},
200 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)},
201 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)},
202 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)},
11e1abb4 203 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
870408c8 204 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2P)},
acf509ae 205 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
870408c8 206 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4P)},
27f1281d 207 {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)},
e9b8cffa 208 {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
9d498bea 209 {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)},
3f542974
PS
210 {} /* terminating entry */
211};
68e24113 212MODULE_DEVICE_TABLE(usb, id_table);
3f542974
PS
213
214/* This structure holds all of the local port information */
215
216struct moschip_port {
217 int port_num; /*Actual port number in the device(1,2,etc) */
3f542974
PS
218 struct urb *read_urb; /* read URB for this port */
219 __u8 shadowLCR; /* last LCR value received */
220 __u8 shadowMCR; /* last MCR value received */
221 char open;
0de9a702 222 char open_ports;
3f542974
PS
223 struct usb_serial_port *port; /* loop back to the owner of this object */
224
880af9db 225 /* Offsets */
3f542974
PS
226 __u8 SpRegOffset;
227 __u8 ControlRegOffset;
228 __u8 DcrRegOffset;
880af9db 229 /* for processing control URBS in interrupt context */
3f542974 230 struct urb *control_urb;
0de9a702 231 struct usb_ctrlrequest *dr;
3f542974
PS
232 char *ctrl_buf;
233 int MsrLsr;
234
0de9a702 235 spinlock_t pool_lock;
3f542974 236 struct urb *write_urb_pool[NUM_URBS];
0de9a702 237 char busy[NUM_URBS];
50de36f7 238 bool read_urb_busy;
3f542974 239
0eafe4de
D
240 /* For device(s) with LED indicator */
241 bool has_led;
0eafe4de
D
242 struct timer_list led_timer1; /* Timer for LED on */
243 struct timer_list led_timer2; /* Timer for LED off */
05cf0dec
JH
244 struct urb *led_urb;
245 struct usb_ctrlrequest *led_dr;
d8a083cc
JH
246
247 unsigned long flags;
0eafe4de 248};
3f542974 249
3f542974
PS
250/*
251 * mos7840_set_reg_sync
252 * To set the Control register by calling usb_fill_control_urb function
253 * by passing usb_sndctrlpipe function as parameter.
254 */
255
256static int mos7840_set_reg_sync(struct usb_serial_port *port, __u16 reg,
257 __u16 val)
258{
259 struct usb_device *dev = port->serial->dev;
260 val = val & 0x00ff;
9c134a14 261 dev_dbg(&port->dev, "mos7840_set_reg_sync offset is %x, value %x\n", reg, val);
3f542974
PS
262
263 return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ,
264 MCS_WR_RTYPE, val, reg, NULL, 0,
265 MOS_WDR_TIMEOUT);
266}
267
268/*
269 * mos7840_get_reg_sync
270 * To set the Uart register by calling usb_fill_control_urb function by
271 * passing usb_rcvctrlpipe function as parameter.
272 */
273
274static int mos7840_get_reg_sync(struct usb_serial_port *port, __u16 reg,
880af9db 275 __u16 *val)
3f542974
PS
276{
277 struct usb_device *dev = port->serial->dev;
278 int ret = 0;
9e221a35
JH
279 u8 *buf;
280
281 buf = kmalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
282 if (!buf)
283 return -ENOMEM;
3f542974
PS
284
285 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
9e221a35 286 MCS_RD_RTYPE, 0, reg, buf, VENDOR_READ_LENGTH,
3f542974 287 MOS_WDR_TIMEOUT);
cd8db057
JH
288 if (ret < VENDOR_READ_LENGTH) {
289 if (ret >= 0)
290 ret = -EIO;
291 goto out;
292 }
293
9e221a35 294 *val = buf[0];
9c134a14 295 dev_dbg(&port->dev, "%s offset is %x, return val %x\n", __func__, reg, *val);
cd8db057 296out:
9e221a35 297 kfree(buf);
3f542974
PS
298 return ret;
299}
300
301/*
302 * mos7840_set_uart_reg
303 * To set the Uart register by calling usb_fill_control_urb function by
304 * passing usb_sndctrlpipe function as parameter.
305 */
306
307static int mos7840_set_uart_reg(struct usb_serial_port *port, __u16 reg,
308 __u16 val)
309{
310
311 struct usb_device *dev = port->serial->dev;
312 val = val & 0x00ff;
880af9db
AC
313 /* For the UART control registers, the application number need
314 to be Or'ed */
0de9a702 315 if (port->serial->num_ports == 4) {
1143832e 316 val |= ((__u16)port->port_number + 1) << 8;
3f542974 317 } else {
1143832e
GKH
318 if (port->port_number == 0) {
319 val |= ((__u16)port->port_number + 1) << 8;
3f542974 320 } else {
1143832e 321 val |= ((__u16)port->port_number + 2) << 8;
3f542974
PS
322 }
323 }
9c134a14 324 dev_dbg(&port->dev, "%s application number is %x\n", __func__, val);
3f542974
PS
325 return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ,
326 MCS_WR_RTYPE, val, reg, NULL, 0,
327 MOS_WDR_TIMEOUT);
328
329}
330
331/*
332 * mos7840_get_uart_reg
333 * To set the Control register by calling usb_fill_control_urb function
334 * by passing usb_rcvctrlpipe function as parameter.
335 */
336static int mos7840_get_uart_reg(struct usb_serial_port *port, __u16 reg,
880af9db 337 __u16 *val)
3f542974
PS
338{
339 struct usb_device *dev = port->serial->dev;
340 int ret = 0;
341 __u16 Wval;
9e221a35
JH
342 u8 *buf;
343
344 buf = kmalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
345 if (!buf)
346 return -ENOMEM;
3f542974 347
880af9db 348 /* Wval is same as application number */
0de9a702 349 if (port->serial->num_ports == 4) {
1143832e 350 Wval = ((__u16)port->port_number + 1) << 8;
3f542974 351 } else {
1143832e
GKH
352 if (port->port_number == 0) {
353 Wval = ((__u16)port->port_number + 1) << 8;
3f542974 354 } else {
1143832e 355 Wval = ((__u16)port->port_number + 2) << 8;
3f542974
PS
356 }
357 }
9c134a14 358 dev_dbg(&port->dev, "%s application number is %x\n", __func__, Wval);
3f542974 359 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
9e221a35 360 MCS_RD_RTYPE, Wval, reg, buf, VENDOR_READ_LENGTH,
3f542974 361 MOS_WDR_TIMEOUT);
cd8db057
JH
362 if (ret < VENDOR_READ_LENGTH) {
363 if (ret >= 0)
364 ret = -EIO;
365 goto out;
366 }
9e221a35 367 *val = buf[0];
cd8db057 368out:
9e221a35 369 kfree(buf);
3f542974
PS
370 return ret;
371}
372
9c134a14
GKH
373static void mos7840_dump_serial_port(struct usb_serial_port *port,
374 struct moschip_port *mos7840_port)
3f542974
PS
375{
376
9c134a14
GKH
377 dev_dbg(&port->dev, "SpRegOffset is %2x\n", mos7840_port->SpRegOffset);
378 dev_dbg(&port->dev, "ControlRegOffset is %2x\n", mos7840_port->ControlRegOffset);
379 dev_dbg(&port->dev, "DCRRegOffset is %2x\n", mos7840_port->DcrRegOffset);
3f542974
PS
380
381}
382
383/************************************************************************/
384/************************************************************************/
385/* I N T E R F A C E F U N C T I O N S */
386/* I N T E R F A C E F U N C T I O N S */
387/************************************************************************/
388/************************************************************************/
389
390static inline void mos7840_set_port_private(struct usb_serial_port *port,
391 struct moschip_port *data)
392{
393 usb_set_serial_port_data(port, (void *)data);
394}
395
396static inline struct moschip_port *mos7840_get_port_private(struct
397 usb_serial_port
398 *port)
399{
400 return (struct moschip_port *)usb_get_serial_port_data(port);
401}
402
0de9a702 403static void mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr)
3f542974
PS
404{
405 struct moschip_port *mos7840_port;
406 struct async_icount *icount;
407 mos7840_port = port;
3f542974
PS
408 if (new_msr &
409 (MOS_MSR_DELTA_CTS | MOS_MSR_DELTA_DSR | MOS_MSR_DELTA_RI |
410 MOS_MSR_DELTA_CD)) {
8c1a07ff 411 icount = &mos7840_port->port->icount;
3f542974
PS
412
413 /* update input line counters */
c9fac853 414 if (new_msr & MOS_MSR_DELTA_CTS)
3f542974 415 icount->cts++;
c9fac853 416 if (new_msr & MOS_MSR_DELTA_DSR)
3f542974 417 icount->dsr++;
c9fac853 418 if (new_msr & MOS_MSR_DELTA_CD)
3f542974 419 icount->dcd++;
c9fac853 420 if (new_msr & MOS_MSR_DELTA_RI)
3f542974 421 icount->rng++;
e670c6af 422
0c613371 423 wake_up_interruptible(&port->port->port.delta_msr_wait);
3f542974 424 }
3f542974
PS
425}
426
0de9a702 427static void mos7840_handle_new_lsr(struct moschip_port *port, __u8 new_lsr)
3f542974
PS
428{
429 struct async_icount *icount;
430
3f542974 431 if (new_lsr & SERIAL_LSR_BI) {
880af9db
AC
432 /*
433 * Parity and Framing errors only count if they
434 * occur exclusive of a break being
435 * received.
436 */
3f542974
PS
437 new_lsr &= (__u8) (SERIAL_LSR_OE | SERIAL_LSR_BI);
438 }
439
440 /* update input line counters */
8c1a07ff 441 icount = &port->port->icount;
c9fac853 442 if (new_lsr & SERIAL_LSR_BI)
3f542974 443 icount->brk++;
c9fac853 444 if (new_lsr & SERIAL_LSR_OE)
3f542974 445 icount->overrun++;
c9fac853 446 if (new_lsr & SERIAL_LSR_PE)
3f542974 447 icount->parity++;
c9fac853 448 if (new_lsr & SERIAL_LSR_FE)
3f542974 449 icount->frame++;
3f542974
PS
450}
451
452/************************************************************************/
453/************************************************************************/
454/* U S B C A L L B A C K F U N C T I O N S */
455/* U S B C A L L B A C K F U N C T I O N S */
456/************************************************************************/
457/************************************************************************/
458
7d12e780 459static void mos7840_control_callback(struct urb *urb)
3f542974
PS
460{
461 unsigned char *data;
462 struct moschip_port *mos7840_port;
9c134a14 463 struct device *dev = &urb->dev->dev;
3f542974 464 __u8 regval = 0x0;
0643c724 465 int status = urb->status;
3f542974 466
cdc97792 467 mos7840_port = urb->context;
0de9a702 468
0643c724 469 switch (status) {
3f542974
PS
470 case 0:
471 /* success */
472 break;
473 case -ECONNRESET:
474 case -ENOENT:
475 case -ESHUTDOWN:
476 /* this urb is terminated, clean up */
9c134a14 477 dev_dbg(dev, "%s - urb shutting down with status: %d\n", __func__, status);
d8a083cc 478 goto out;
3f542974 479 default:
9c134a14 480 dev_dbg(dev, "%s - nonzero urb status received: %d\n", __func__, status);
d8a083cc 481 goto out;
3f542974
PS
482 }
483
9c134a14
GKH
484 dev_dbg(dev, "%s urb buffer size is %d\n", __func__, urb->actual_length);
485 dev_dbg(dev, "%s mos7840_port->MsrLsr is %d port %d\n", __func__,
486 mos7840_port->MsrLsr, mos7840_port->port_num);
3f542974
PS
487 data = urb->transfer_buffer;
488 regval = (__u8) data[0];
9c134a14 489 dev_dbg(dev, "%s data is %x\n", __func__, regval);
3f542974
PS
490 if (mos7840_port->MsrLsr == 0)
491 mos7840_handle_new_msr(mos7840_port, regval);
492 else if (mos7840_port->MsrLsr == 1)
493 mos7840_handle_new_lsr(mos7840_port, regval);
d8a083cc
JH
494out:
495 clear_bit_unlock(MOS7840_FLAG_CTRL_BUSY, &mos7840_port->flags);
3f542974
PS
496}
497
498static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg,
880af9db 499 __u16 *val)
3f542974
PS
500{
501 struct usb_device *dev = mcs->port->serial->dev;
0de9a702
ON
502 struct usb_ctrlrequest *dr = mcs->dr;
503 unsigned char *buffer = mcs->ctrl_buf;
504 int ret;
3f542974 505
d8a083cc
JH
506 if (test_and_set_bit_lock(MOS7840_FLAG_CTRL_BUSY, &mcs->flags))
507 return -EBUSY;
508
3f542974
PS
509 dr->bRequestType = MCS_RD_RTYPE;
510 dr->bRequest = MCS_RDREQ;
880af9db 511 dr->wValue = cpu_to_le16(Wval); /* 0 */
3f542974
PS
512 dr->wIndex = cpu_to_le16(reg);
513 dr->wLength = cpu_to_le16(2);
514
515 usb_fill_control_urb(mcs->control_urb, dev, usb_rcvctrlpipe(dev, 0),
516 (unsigned char *)dr, buffer, 2,
517 mos7840_control_callback, mcs);
518 mcs->control_urb->transfer_buffer_length = 2;
519 ret = usb_submit_urb(mcs->control_urb, GFP_ATOMIC);
d8a083cc
JH
520 if (ret)
521 clear_bit_unlock(MOS7840_FLAG_CTRL_BUSY, &mcs->flags);
522
3f542974
PS
523 return ret;
524}
525
0eafe4de
D
526static void mos7840_set_led_callback(struct urb *urb)
527{
528 switch (urb->status) {
529 case 0:
530 /* Success */
531 break;
532 case -ECONNRESET:
533 case -ENOENT:
534 case -ESHUTDOWN:
535 /* This urb is terminated, clean up */
d9a38a87 536 dev_dbg(&urb->dev->dev, "%s - urb shutting down: %d\n",
9c134a14 537 __func__, urb->status);
0eafe4de
D
538 break;
539 default:
d9a38a87 540 dev_dbg(&urb->dev->dev, "%s - nonzero urb status: %d\n",
9c134a14 541 __func__, urb->status);
0eafe4de
D
542 }
543}
544
545static void mos7840_set_led_async(struct moschip_port *mcs, __u16 wval,
546 __u16 reg)
547{
548 struct usb_device *dev = mcs->port->serial->dev;
05cf0dec 549 struct usb_ctrlrequest *dr = mcs->led_dr;
0eafe4de
D
550
551 dr->bRequestType = MCS_WR_RTYPE;
552 dr->bRequest = MCS_WRREQ;
553 dr->wValue = cpu_to_le16(wval);
554 dr->wIndex = cpu_to_le16(reg);
555 dr->wLength = cpu_to_le16(0);
556
05cf0dec 557 usb_fill_control_urb(mcs->led_urb, dev, usb_sndctrlpipe(dev, 0),
0eafe4de
D
558 (unsigned char *)dr, NULL, 0, mos7840_set_led_callback, NULL);
559
05cf0dec 560 usb_submit_urb(mcs->led_urb, GFP_ATOMIC);
0eafe4de
D
561}
562
563static void mos7840_set_led_sync(struct usb_serial_port *port, __u16 reg,
564 __u16 val)
565{
566 struct usb_device *dev = port->serial->dev;
567
568 usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ, MCS_WR_RTYPE,
569 val, reg, NULL, 0, MOS_WDR_TIMEOUT);
570}
571
572static void mos7840_led_off(unsigned long arg)
573{
574 struct moschip_port *mcs = (struct moschip_port *) arg;
575
576 /* Turn off LED */
577 mos7840_set_led_async(mcs, 0x0300, MODEM_CONTROL_REGISTER);
578 mod_timer(&mcs->led_timer2,
579 jiffies + msecs_to_jiffies(LED_OFF_MS));
580}
581
582static void mos7840_led_flag_off(unsigned long arg)
583{
584 struct moschip_port *mcs = (struct moschip_port *) arg;
585
05cf0dec
JH
586 clear_bit_unlock(MOS7840_FLAG_LED_BUSY, &mcs->flags);
587}
588
589static void mos7840_led_activity(struct usb_serial_port *port)
590{
591 struct moschip_port *mos7840_port = usb_get_serial_port_data(port);
592
593 if (test_and_set_bit_lock(MOS7840_FLAG_LED_BUSY, &mos7840_port->flags))
594 return;
595
596 mos7840_set_led_async(mos7840_port, 0x0301, MODEM_CONTROL_REGISTER);
597 mod_timer(&mos7840_port->led_timer1,
598 jiffies + msecs_to_jiffies(LED_ON_MS));
0eafe4de
D
599}
600
3f542974
PS
601/*****************************************************************************
602 * mos7840_interrupt_callback
603 * this is the callback function for when we have received data on the
604 * interrupt endpoint.
605 *****************************************************************************/
606
7d12e780 607static void mos7840_interrupt_callback(struct urb *urb)
3f542974
PS
608{
609 int result;
610 int length;
611 struct moschip_port *mos7840_port;
612 struct usb_serial *serial;
613 __u16 Data;
614 unsigned char *data;
615 __u8 sp[5], st;
0de9a702
ON
616 int i, rv = 0;
617 __u16 wval, wreg = 0;
0643c724 618 int status = urb->status;
3f542974 619
0643c724 620 switch (status) {
3f542974
PS
621 case 0:
622 /* success */
623 break;
624 case -ECONNRESET:
625 case -ENOENT:
626 case -ESHUTDOWN:
627 /* this urb is terminated, clean up */
9c134a14
GKH
628 dev_dbg(&urb->dev->dev, "%s - urb shutting down with status: %d\n",
629 __func__, status);
3f542974
PS
630 return;
631 default:
9c134a14
GKH
632 dev_dbg(&urb->dev->dev, "%s - nonzero urb status received: %d\n",
633 __func__, status);
3f542974
PS
634 goto exit;
635 }
636
637 length = urb->actual_length;
638 data = urb->transfer_buffer;
639
cdc97792 640 serial = urb->context;
3f542974
PS
641
642 /* Moschip get 5 bytes
643 * Byte 1 IIR Port 1 (port.number is 0)
644 * Byte 2 IIR Port 2 (port.number is 1)
645 * Byte 3 IIR Port 3 (port.number is 2)
646 * Byte 4 IIR Port 4 (port.number is 3)
647 * Byte 5 FIFO status for both */
648
365a0442 649 if (length > 5) {
9c134a14 650 dev_dbg(&urb->dev->dev, "%s", "Wrong data !!!\n");
3f542974
PS
651 return;
652 }
653
654 sp[0] = (__u8) data[0];
655 sp[1] = (__u8) data[1];
656 sp[2] = (__u8) data[2];
657 sp[3] = (__u8) data[3];
658 st = (__u8) data[4];
659
660 for (i = 0; i < serial->num_ports; i++) {
661 mos7840_port = mos7840_get_port_private(serial->port[i]);
1143832e 662 wval = ((__u16)serial->port[i]->port_number + 1) << 8;
3f542974
PS
663 if (mos7840_port->open) {
664 if (sp[i] & 0x01) {
9c134a14 665 dev_dbg(&urb->dev->dev, "SP%d No Interrupt !!!\n", i);
3f542974
PS
666 } else {
667 switch (sp[i] & 0x0f) {
668 case SERIAL_IIR_RLS:
9c134a14
GKH
669 dev_dbg(&urb->dev->dev, "Serial Port %d: Receiver status error or \n", i);
670 dev_dbg(&urb->dev->dev, "address bit detected in 9-bit mode\n");
3f542974 671 mos7840_port->MsrLsr = 1;
0de9a702 672 wreg = LINE_STATUS_REGISTER;
3f542974
PS
673 break;
674 case SERIAL_IIR_MS:
9c134a14 675 dev_dbg(&urb->dev->dev, "Serial Port %d: Modem status change\n", i);
3f542974 676 mos7840_port->MsrLsr = 0;
0de9a702 677 wreg = MODEM_STATUS_REGISTER;
3f542974
PS
678 break;
679 }
e681b66f 680 rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data);
3f542974
PS
681 }
682 }
683 }
880af9db
AC
684 if (!(rv < 0))
685 /* the completion handler for the control urb will resubmit */
0de9a702
ON
686 return;
687exit:
3f542974
PS
688 result = usb_submit_urb(urb, GFP_ATOMIC);
689 if (result) {
690 dev_err(&urb->dev->dev,
691 "%s - Error %d submitting interrupt urb\n",
441b62c1 692 __func__, result);
3f542974 693 }
3f542974
PS
694}
695
696static int mos7840_port_paranoia_check(struct usb_serial_port *port,
697 const char *function)
698{
699 if (!port) {
9c134a14 700 pr_debug("%s - port == NULL\n", function);
3f542974
PS
701 return -1;
702 }
703 if (!port->serial) {
9c134a14 704 pr_debug("%s - port->serial == NULL\n", function);
3f542974
PS
705 return -1;
706 }
707
708 return 0;
709}
710
711/* Inline functions to check the sanity of a pointer that is passed to us */
712static int mos7840_serial_paranoia_check(struct usb_serial *serial,
713 const char *function)
714{
715 if (!serial) {
9c134a14 716 pr_debug("%s - serial == NULL\n", function);
3f542974
PS
717 return -1;
718 }
719 if (!serial->type) {
9c134a14 720 pr_debug("%s - serial->type == NULL!\n", function);
3f542974
PS
721 return -1;
722 }
723
724 return 0;
725}
726
727static struct usb_serial *mos7840_get_usb_serial(struct usb_serial_port *port,
728 const char *function)
729{
730 /* if no port was specified, or it fails a paranoia check */
731 if (!port ||
732 mos7840_port_paranoia_check(port, function) ||
733 mos7840_serial_paranoia_check(port->serial, function)) {
880af9db
AC
734 /* then say that we don't have a valid usb_serial thing,
735 * which will end up genrating -ENODEV return values */
3f542974
PS
736 return NULL;
737 }
738
739 return port->serial;
740}
741
742/*****************************************************************************
743 * mos7840_bulk_in_callback
744 * this is the callback function for when we have received data on the
745 * bulk in endpoint.
746 *****************************************************************************/
747
7d12e780 748static void mos7840_bulk_in_callback(struct urb *urb)
3f542974 749{
0643c724 750 int retval;
3f542974
PS
751 unsigned char *data;
752 struct usb_serial *serial;
753 struct usb_serial_port *port;
754 struct moschip_port *mos7840_port;
0643c724 755 int status = urb->status;
3f542974 756
cdc97792 757 mos7840_port = urb->context;
9c134a14 758 if (!mos7840_port)
50de36f7 759 return;
50de36f7
GKH
760
761 if (status) {
9c134a14 762 dev_dbg(&urb->dev->dev, "nonzero read bulk status received: %d\n", status);
50de36f7 763 mos7840_port->read_urb_busy = false;
3f542974
PS
764 return;
765 }
766
9c134a14 767 port = mos7840_port->port;
441b62c1 768 if (mos7840_port_paranoia_check(port, __func__)) {
50de36f7 769 mos7840_port->read_urb_busy = false;
3f542974
PS
770 return;
771 }
772
441b62c1 773 serial = mos7840_get_usb_serial(port, __func__);
3f542974 774 if (!serial) {
50de36f7 775 mos7840_port->read_urb_busy = false;
3f542974
PS
776 return;
777 }
778
3f542974 779 data = urb->transfer_buffer;
59d33f2f 780 usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
3f542974 781
3f542974 782 if (urb->actual_length) {
05c7cd39 783 struct tty_port *tport = &mos7840_port->port->port;
2e124b4a
JS
784 tty_insert_flip_string(tport, data, urb->actual_length);
785 tty_flip_buffer_push(tport);
8c1a07ff
JH
786 port->icount.rx += urb->actual_length;
787 dev_dbg(&port->dev, "icount.rx is %d:\n", port->icount.rx);
3f542974
PS
788 }
789
790 if (!mos7840_port->read_urb) {
9c134a14 791 dev_dbg(&port->dev, "%s", "URB KILLED !!!\n");
50de36f7 792 mos7840_port->read_urb_busy = false;
3f542974
PS
793 return;
794 }
795
05cf0dec
JH
796 if (mos7840_port->has_led)
797 mos7840_led_activity(port);
3f542974 798
50de36f7 799 mos7840_port->read_urb_busy = true;
0643c724 800 retval = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);
0de9a702 801
0643c724 802 if (retval) {
9c134a14 803 dev_dbg(&port->dev, "usb_submit_urb(read bulk) failed, retval = %d\n", retval);
50de36f7 804 mos7840_port->read_urb_busy = false;
3f542974
PS
805 }
806}
807
808/*****************************************************************************
809 * mos7840_bulk_out_data_callback
880af9db
AC
810 * this is the callback function for when we have finished sending
811 * serial data on the bulk out endpoint.
3f542974
PS
812 *****************************************************************************/
813
7d12e780 814static void mos7840_bulk_out_data_callback(struct urb *urb)
3f542974
PS
815{
816 struct moschip_port *mos7840_port;
9c134a14 817 struct usb_serial_port *port;
0643c724 818 int status = urb->status;
0de9a702
ON
819 int i;
820
cdc97792 821 mos7840_port = urb->context;
9c134a14 822 port = mos7840_port->port;
0de9a702
ON
823 spin_lock(&mos7840_port->pool_lock);
824 for (i = 0; i < NUM_URBS; i++) {
825 if (urb == mos7840_port->write_urb_pool[i]) {
826 mos7840_port->busy[i] = 0;
827 break;
828 }
829 }
830 spin_unlock(&mos7840_port->pool_lock);
831
0643c724 832 if (status) {
9c134a14 833 dev_dbg(&port->dev, "nonzero write bulk status received:%d\n", status);
3f542974
PS
834 return;
835 }
836
9c134a14 837 if (mos7840_port_paranoia_check(port, __func__))
3f542974 838 return;
3f542974 839
6aad04f2
JS
840 if (mos7840_port->open)
841 tty_port_tty_wakeup(&port->port);
3f542974
PS
842
843}
844
845/************************************************************************/
846/* D R I V E R T T Y I N T E R F A C E F U N C T I O N S */
847/************************************************************************/
3f542974
PS
848
849/*****************************************************************************
850 * mos7840_open
851 * this function is called by the tty driver when a port is opened
852 * If successful, we return 0
853 * Otherwise we return a negative error number.
854 *****************************************************************************/
855
a509a7e4 856static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port)
3f542974
PS
857{
858 int response;
859 int j;
860 struct usb_serial *serial;
861 struct urb *urb;
862 __u16 Data;
863 int status;
864 struct moschip_port *mos7840_port;
0de9a702 865 struct moschip_port *port0;
3f542974 866
9c134a14 867 if (mos7840_port_paranoia_check(port, __func__))
3f542974 868 return -ENODEV;
3f542974 869
3f542974
PS
870 serial = port->serial;
871
9c134a14 872 if (mos7840_serial_paranoia_check(serial, __func__))
3f542974 873 return -ENODEV;
3f542974
PS
874
875 mos7840_port = mos7840_get_port_private(port);
0de9a702 876 port0 = mos7840_get_port_private(serial->port[0]);
3f542974 877
0de9a702 878 if (mos7840_port == NULL || port0 == NULL)
3f542974
PS
879 return -ENODEV;
880
881 usb_clear_halt(serial->dev, port->write_urb->pipe);
882 usb_clear_halt(serial->dev, port->read_urb->pipe);
0de9a702 883 port0->open_ports++;
3f542974
PS
884
885 /* Initialising the write urb pool */
886 for (j = 0; j < NUM_URBS; ++j) {
0de9a702 887 urb = usb_alloc_urb(0, GFP_KERNEL);
3f542974 888 mos7840_port->write_urb_pool[j] = urb;
10c642d0 889 if (!urb)
3f542974 890 continue;
3f542974 891
880af9db
AC
892 urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
893 GFP_KERNEL);
3f542974 894 if (!urb->transfer_buffer) {
0de9a702
ON
895 usb_free_urb(urb);
896 mos7840_port->write_urb_pool[j] = NULL;
3f542974
PS
897 continue;
898 }
899 }
900
901/*****************************************************************************
902 * Initialize MCS7840 -- Write Init values to corresponding Registers
903 *
904 * Register Index
905 * 1 : IER
906 * 2 : FCR
907 * 3 : LCR
908 * 4 : MCR
909 *
910 * 0x08 : SP1/2 Control Reg
911 *****************************************************************************/
912
880af9db 913 /* NEED to check the following Block */
3f542974 914
3f542974
PS
915 Data = 0x0;
916 status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data);
917 if (status < 0) {
9c134a14 918 dev_dbg(&port->dev, "Reading Spreg failed\n");
5f8a2e68 919 goto err;
3f542974
PS
920 }
921 Data |= 0x80;
922 status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
923 if (status < 0) {
9c134a14 924 dev_dbg(&port->dev, "writing Spreg failed\n");
5f8a2e68 925 goto err;
3f542974
PS
926 }
927
928 Data &= ~0x80;
929 status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
930 if (status < 0) {
9c134a14 931 dev_dbg(&port->dev, "writing Spreg failed\n");
5f8a2e68 932 goto err;
3f542974 933 }
880af9db 934 /* End of block to be checked */
3f542974 935
3f542974 936 Data = 0x0;
880af9db
AC
937 status = mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset,
938 &Data);
3f542974 939 if (status < 0) {
9c134a14 940 dev_dbg(&port->dev, "Reading Controlreg failed\n");
5f8a2e68 941 goto err;
3f542974 942 }
880af9db
AC
943 Data |= 0x08; /* Driver done bit */
944 Data |= 0x20; /* rx_disable */
945 status = mos7840_set_reg_sync(port,
946 mos7840_port->ControlRegOffset, Data);
3f542974 947 if (status < 0) {
9c134a14 948 dev_dbg(&port->dev, "writing Controlreg failed\n");
5f8a2e68 949 goto err;
3f542974 950 }
880af9db
AC
951 /* do register settings here */
952 /* Set all regs to the device default values. */
953 /***********************************
954 * First Disable all interrupts.
955 ***********************************/
3f542974 956 Data = 0x00;
3f542974
PS
957 status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
958 if (status < 0) {
9c134a14 959 dev_dbg(&port->dev, "disabling interrupts failed\n");
5f8a2e68 960 goto err;
3f542974 961 }
880af9db 962 /* Set FIFO_CONTROL_REGISTER to the default value */
3f542974 963 Data = 0x00;
3f542974
PS
964 status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
965 if (status < 0) {
9c134a14 966 dev_dbg(&port->dev, "Writing FIFO_CONTROL_REGISTER failed\n");
5f8a2e68 967 goto err;
3f542974
PS
968 }
969
970 Data = 0xcf;
3f542974
PS
971 status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
972 if (status < 0) {
9c134a14 973 dev_dbg(&port->dev, "Writing FIFO_CONTROL_REGISTER failed\n");
5f8a2e68 974 goto err;
3f542974
PS
975 }
976
977 Data = 0x03;
3f542974
PS
978 status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
979 mos7840_port->shadowLCR = Data;
980
981 Data = 0x0b;
3f542974
PS
982 status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
983 mos7840_port->shadowMCR = Data;
984
985 Data = 0x00;
3f542974
PS
986 status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
987 mos7840_port->shadowLCR = Data;
988
880af9db 989 Data |= SERIAL_LCR_DLAB; /* data latch enable in LCR 0x80 */
3f542974
PS
990 status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
991
992 Data = 0x0c;
3f542974
PS
993 status = mos7840_set_uart_reg(port, DIVISOR_LATCH_LSB, Data);
994
995 Data = 0x0;
3f542974
PS
996 status = mos7840_set_uart_reg(port, DIVISOR_LATCH_MSB, Data);
997
998 Data = 0x00;
3f542974
PS
999 status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
1000
1001 Data = Data & ~SERIAL_LCR_DLAB;
3f542974
PS
1002 status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
1003 mos7840_port->shadowLCR = Data;
1004
880af9db 1005 /* clearing Bulkin and Bulkout Fifo */
3f542974 1006 Data = 0x0;
3f542974
PS
1007 status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data);
1008
1009 Data = Data | 0x0c;
3f542974
PS
1010 status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
1011
1012 Data = Data & ~0x0c;
3f542974 1013 status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
880af9db 1014 /* Finally enable all interrupts */
3f542974 1015 Data = 0x0c;
3f542974
PS
1016 status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
1017
880af9db 1018 /* clearing rx_disable */
3f542974 1019 Data = 0x0;
880af9db
AC
1020 status = mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset,
1021 &Data);
3f542974 1022 Data = Data & ~0x20;
880af9db
AC
1023 status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset,
1024 Data);
3f542974 1025
880af9db 1026 /* rx_negate */
3f542974 1027 Data = 0x0;
880af9db
AC
1028 status = mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset,
1029 &Data);
3f542974 1030 Data = Data | 0x10;
880af9db
AC
1031 status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset,
1032 Data);
3f542974 1033
880af9db
AC
1034 /* Check to see if we've set up our endpoint info yet *
1035 * (can't set it up in mos7840_startup as the structures *
1036 * were not set up at that time.) */
0de9a702 1037 if (port0->open_ports == 1) {
5182c2cf 1038 /* FIXME: Buffer never NULL, so URB is not submitted. */
3f542974 1039 if (serial->port[0]->interrupt_in_buffer == NULL) {
3f542974 1040 /* set up interrupt urb */
3f542974 1041 usb_fill_int_urb(serial->port[0]->interrupt_in_urb,
880af9db
AC
1042 serial->dev,
1043 usb_rcvintpipe(serial->dev,
1044 serial->port[0]->interrupt_in_endpointAddress),
1045 serial->port[0]->interrupt_in_buffer,
1046 serial->port[0]->interrupt_in_urb->
1047 transfer_buffer_length,
1048 mos7840_interrupt_callback,
1049 serial,
1050 serial->port[0]->interrupt_in_urb->interval);
3f542974 1051
472d7e55 1052 /* start interrupt read for mos7840 */
3f542974
PS
1053 response =
1054 usb_submit_urb(serial->port[0]->interrupt_in_urb,
1055 GFP_KERNEL);
1056 if (response) {
194343d9
GKH
1057 dev_err(&port->dev, "%s - Error %d submitting "
1058 "interrupt urb\n", __func__, response);
3f542974
PS
1059 }
1060
1061 }
1062
1063 }
1064
1065 /* see if we've set up our endpoint info yet *
1066 * (can't set it up in mos7840_startup as the *
1067 * structures were not set up at that time.) */
1068
1143832e 1069 dev_dbg(&port->dev, "port number is %d\n", port->port_number);
e5b1e206 1070 dev_dbg(&port->dev, "minor number is %d\n", port->minor);
9c134a14
GKH
1071 dev_dbg(&port->dev, "Bulkin endpoint is %d\n", port->bulk_in_endpointAddress);
1072 dev_dbg(&port->dev, "BulkOut endpoint is %d\n", port->bulk_out_endpointAddress);
1073 dev_dbg(&port->dev, "Interrupt endpoint is %d\n", port->interrupt_in_endpointAddress);
1074 dev_dbg(&port->dev, "port's number in the device is %d\n", mos7840_port->port_num);
3f542974
PS
1075 mos7840_port->read_urb = port->read_urb;
1076
1077 /* set up our bulk in urb */
1143832e 1078 if ((serial->num_ports == 2) && (((__u16)port->port_number % 2) != 0)) {
093ea2d3
DL
1079 usb_fill_bulk_urb(mos7840_port->read_urb,
1080 serial->dev,
1081 usb_rcvbulkpipe(serial->dev,
1082 (port->bulk_in_endpointAddress) + 2),
1083 port->bulk_in_buffer,
1084 mos7840_port->read_urb->transfer_buffer_length,
1085 mos7840_bulk_in_callback, mos7840_port);
1086 } else {
1087 usb_fill_bulk_urb(mos7840_port->read_urb,
1088 serial->dev,
1089 usb_rcvbulkpipe(serial->dev,
1090 port->bulk_in_endpointAddress),
1091 port->bulk_in_buffer,
1092 mos7840_port->read_urb->transfer_buffer_length,
1093 mos7840_bulk_in_callback, mos7840_port);
1094 }
3f542974 1095
9c134a14 1096 dev_dbg(&port->dev, "%s: bulkin endpoint is %d\n", __func__, port->bulk_in_endpointAddress);
50de36f7 1097 mos7840_port->read_urb_busy = true;
3f542974
PS
1098 response = usb_submit_urb(mos7840_port->read_urb, GFP_KERNEL);
1099 if (response) {
194343d9
GKH
1100 dev_err(&port->dev, "%s - Error %d submitting control urb\n",
1101 __func__, response);
50de36f7 1102 mos7840_port->read_urb_busy = false;
3f542974
PS
1103 }
1104
3f542974 1105 /* initialize our port settings */
880af9db
AC
1106 /* Must set to enable ints! */
1107 mos7840_port->shadowMCR = MCR_MASTER_IE;
3f542974
PS
1108 /* send a open port command */
1109 mos7840_port->open = 1;
880af9db 1110 /* mos7840_change_port_settings(mos7840_port,old_termios); */
3f542974 1111
3f542974 1112 return 0;
5f8a2e68
JH
1113err:
1114 for (j = 0; j < NUM_URBS; ++j) {
1115 urb = mos7840_port->write_urb_pool[j];
1116 if (!urb)
1117 continue;
1118 kfree(urb->transfer_buffer);
1119 usb_free_urb(urb);
1120 }
1121 return status;
3f542974
PS
1122}
1123
1124/*****************************************************************************
1125 * mos7840_chars_in_buffer
1126 * this function is called by the tty driver when it wants to know how many
1127 * bytes of data we currently have outstanding in the port (data that has
1128 * been written, but hasn't made it out the port yet)
1129 * If successful, we return the number of bytes left to be written in the
1130 * system,
95da310e 1131 * Otherwise we return zero.
3f542974
PS
1132 *****************************************************************************/
1133
95da310e 1134static int mos7840_chars_in_buffer(struct tty_struct *tty)
3f542974 1135{
95da310e 1136 struct usb_serial_port *port = tty->driver_data;
3f542974
PS
1137 int i;
1138 int chars = 0;
0de9a702 1139 unsigned long flags;
3f542974
PS
1140 struct moschip_port *mos7840_port;
1141
9c134a14 1142 if (mos7840_port_paranoia_check(port, __func__))
95da310e 1143 return 0;
3f542974
PS
1144
1145 mos7840_port = mos7840_get_port_private(port);
3363155b 1146 if (mos7840_port == NULL)
95da310e 1147 return 0;
3f542974 1148
880af9db 1149 spin_lock_irqsave(&mos7840_port->pool_lock, flags);
5c263b92
MF
1150 for (i = 0; i < NUM_URBS; ++i) {
1151 if (mos7840_port->busy[i]) {
1152 struct urb *urb = mos7840_port->write_urb_pool[i];
1153 chars += urb->transfer_buffer_length;
1154 }
1155 }
880af9db 1156 spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
9c134a14 1157 dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars);
0de9a702 1158 return chars;
3f542974
PS
1159
1160}
1161
3f542974
PS
1162/*****************************************************************************
1163 * mos7840_close
1164 * this function is called by the tty driver when a port is closed
1165 *****************************************************************************/
1166
335f8514 1167static void mos7840_close(struct usb_serial_port *port)
3f542974
PS
1168{
1169 struct usb_serial *serial;
1170 struct moschip_port *mos7840_port;
0de9a702 1171 struct moschip_port *port0;
3f542974
PS
1172 int j;
1173 __u16 Data;
1174
9c134a14 1175 if (mos7840_port_paranoia_check(port, __func__))
3f542974 1176 return;
3f542974 1177
441b62c1 1178 serial = mos7840_get_usb_serial(port, __func__);
9c134a14 1179 if (!serial)
3f542974 1180 return;
3f542974
PS
1181
1182 mos7840_port = mos7840_get_port_private(port);
0de9a702 1183 port0 = mos7840_get_port_private(serial->port[0]);
3f542974 1184
0de9a702 1185 if (mos7840_port == NULL || port0 == NULL)
3f542974 1186 return;
3f542974
PS
1187
1188 for (j = 0; j < NUM_URBS; ++j)
1189 usb_kill_urb(mos7840_port->write_urb_pool[j]);
1190
1191 /* Freeing Write URBs */
1192 for (j = 0; j < NUM_URBS; ++j) {
1193 if (mos7840_port->write_urb_pool[j]) {
91c72df1 1194 kfree(mos7840_port->write_urb_pool[j]->transfer_buffer);
3f542974
PS
1195 usb_free_urb(mos7840_port->write_urb_pool[j]);
1196 }
1197 }
1198
bb3529c6
JH
1199 usb_kill_urb(mos7840_port->read_urb);
1200 mos7840_port->read_urb_busy = false;
1201
0de9a702 1202 port0->open_ports--;
1143832e 1203 dev_dbg(&port->dev, "%s in close%d\n", __func__, port0->open_ports);
0de9a702 1204 if (port0->open_ports == 0) {
3f542974 1205 if (serial->port[0]->interrupt_in_urb) {
9c134a14 1206 dev_dbg(&port->dev, "Shutdown interrupt_in_urb\n");
0de9a702 1207 usb_kill_urb(serial->port[0]->interrupt_in_urb);
3f542974
PS
1208 }
1209 }
1210
3f542974
PS
1211 Data = 0x0;
1212 mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
1213
1214 Data = 0x00;
1215 mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
1216
1217 mos7840_port->open = 0;
3f542974
PS
1218}
1219
3f542974
PS
1220/*****************************************************************************
1221 * mos7840_break
1222 * this function sends a break to the port
1223 *****************************************************************************/
95da310e 1224static void mos7840_break(struct tty_struct *tty, int break_state)
3f542974 1225{
95da310e 1226 struct usb_serial_port *port = tty->driver_data;
3f542974
PS
1227 unsigned char data;
1228 struct usb_serial *serial;
1229 struct moschip_port *mos7840_port;
1230
9c134a14 1231 if (mos7840_port_paranoia_check(port, __func__))
3f542974 1232 return;
3f542974 1233
441b62c1 1234 serial = mos7840_get_usb_serial(port, __func__);
9c134a14 1235 if (!serial)
3f542974 1236 return;
3f542974
PS
1237
1238 mos7840_port = mos7840_get_port_private(port);
1239
880af9db 1240 if (mos7840_port == NULL)
3f542974 1241 return;
3f542974 1242
95da310e 1243 if (break_state == -1)
3f542974 1244 data = mos7840_port->shadowLCR | LCR_SET_BREAK;
95da310e 1245 else
3f542974 1246 data = mos7840_port->shadowLCR & ~LCR_SET_BREAK;
3f542974 1247
6b447f04 1248 /* FIXME: no locking on shadowLCR anywhere in driver */
3f542974 1249 mos7840_port->shadowLCR = data;
9c134a14 1250 dev_dbg(&port->dev, "%s mos7840_port->shadowLCR is %x\n", __func__, mos7840_port->shadowLCR);
3f542974
PS
1251 mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER,
1252 mos7840_port->shadowLCR);
3f542974
PS
1253}
1254
1255/*****************************************************************************
1256 * mos7840_write_room
1257 * this function is called by the tty driver when it wants to know how many
1258 * bytes of data we can accept for a specific port.
1259 * If successful, we return the amount of room that we have for this port
1260 * Otherwise we return a negative error number.
1261 *****************************************************************************/
1262
95da310e 1263static int mos7840_write_room(struct tty_struct *tty)
3f542974 1264{
95da310e 1265 struct usb_serial_port *port = tty->driver_data;
3f542974
PS
1266 int i;
1267 int room = 0;
0de9a702 1268 unsigned long flags;
3f542974
PS
1269 struct moschip_port *mos7840_port;
1270
9c134a14 1271 if (mos7840_port_paranoia_check(port, __func__))
3f542974 1272 return -1;
3f542974
PS
1273
1274 mos7840_port = mos7840_get_port_private(port);
9c134a14 1275 if (mos7840_port == NULL)
3f542974 1276 return -1;
3f542974 1277
0de9a702 1278 spin_lock_irqsave(&mos7840_port->pool_lock, flags);
3f542974 1279 for (i = 0; i < NUM_URBS; ++i) {
880af9db 1280 if (!mos7840_port->busy[i])
3f542974 1281 room += URB_TRANSFER_BUFFER_SIZE;
3f542974 1282 }
0de9a702 1283 spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
3f542974 1284
0de9a702 1285 room = (room == 0) ? 0 : room - URB_TRANSFER_BUFFER_SIZE + 1;
9c134a14 1286 dev_dbg(&mos7840_port->port->dev, "%s - returns %d\n", __func__, room);
0de9a702 1287 return room;
3f542974
PS
1288
1289}
1290
1291/*****************************************************************************
1292 * mos7840_write
1293 * this function is called by the tty driver when data should be written to
1294 * the port.
1295 * If successful, we return the number of bytes written, otherwise we
1296 * return a negative error number.
1297 *****************************************************************************/
1298
95da310e 1299static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port,
3f542974
PS
1300 const unsigned char *data, int count)
1301{
1302 int status;
1303 int i;
1304 int bytes_sent = 0;
1305 int transfer_size;
0de9a702 1306 unsigned long flags;
3f542974
PS
1307
1308 struct moschip_port *mos7840_port;
1309 struct usb_serial *serial;
1310 struct urb *urb;
880af9db 1311 /* __u16 Data; */
3f542974
PS
1312 const unsigned char *current_position = data;
1313 unsigned char *data1;
3f542974 1314
9c134a14 1315 if (mos7840_port_paranoia_check(port, __func__))
3f542974 1316 return -1;
3f542974
PS
1317
1318 serial = port->serial;
9c134a14 1319 if (mos7840_serial_paranoia_check(serial, __func__))
3f542974 1320 return -1;
3f542974
PS
1321
1322 mos7840_port = mos7840_get_port_private(port);
9c134a14 1323 if (mos7840_port == NULL)
3f542974 1324 return -1;
3f542974
PS
1325
1326 /* try to find a free urb in the list */
1327 urb = NULL;
1328
0de9a702 1329 spin_lock_irqsave(&mos7840_port->pool_lock, flags);
3f542974 1330 for (i = 0; i < NUM_URBS; ++i) {
0de9a702
ON
1331 if (!mos7840_port->busy[i]) {
1332 mos7840_port->busy[i] = 1;
3f542974 1333 urb = mos7840_port->write_urb_pool[i];
9c134a14 1334 dev_dbg(&port->dev, "URB:%d\n", i);
3f542974
PS
1335 break;
1336 }
1337 }
0de9a702 1338 spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
3f542974
PS
1339
1340 if (urb == NULL) {
9c134a14 1341 dev_dbg(&port->dev, "%s - no more free urbs\n", __func__);
3f542974
PS
1342 goto exit;
1343 }
1344
1345 if (urb->transfer_buffer == NULL) {
3b7c7e52
AK
1346 urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
1347 GFP_ATOMIC);
10c642d0 1348 if (!urb->transfer_buffer)
3f542974 1349 goto exit;
3f542974
PS
1350 }
1351 transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE);
1352
97c4965d 1353 memcpy(urb->transfer_buffer, current_position, transfer_size);
3f542974
PS
1354
1355 /* fill urb with data and submit */
1143832e 1356 if ((serial->num_ports == 2) && (((__u16)port->port_number % 2) != 0)) {
093ea2d3
DL
1357 usb_fill_bulk_urb(urb,
1358 serial->dev,
1359 usb_sndbulkpipe(serial->dev,
1360 (port->bulk_out_endpointAddress) + 2),
1361 urb->transfer_buffer,
1362 transfer_size,
1363 mos7840_bulk_out_data_callback, mos7840_port);
1364 } else {
1365 usb_fill_bulk_urb(urb,
1366 serial->dev,
1367 usb_sndbulkpipe(serial->dev,
1368 port->bulk_out_endpointAddress),
1369 urb->transfer_buffer,
1370 transfer_size,
1371 mos7840_bulk_out_data_callback, mos7840_port);
1372 }
3f542974
PS
1373
1374 data1 = urb->transfer_buffer;
9c134a14 1375 dev_dbg(&port->dev, "bulkout endpoint is %d\n", port->bulk_out_endpointAddress);
3f542974 1376
05cf0dec
JH
1377 if (mos7840_port->has_led)
1378 mos7840_led_activity(port);
0eafe4de 1379
3f542974
PS
1380 /* send it down the pipe */
1381 status = usb_submit_urb(urb, GFP_ATOMIC);
1382
1383 if (status) {
0de9a702 1384 mos7840_port->busy[i] = 0;
22a416c4 1385 dev_err_console(port, "%s - usb_submit_urb(write bulk) failed "
194343d9 1386 "with status = %d\n", __func__, status);
3f542974
PS
1387 bytes_sent = status;
1388 goto exit;
1389 }
1390 bytes_sent = transfer_size;
8c1a07ff
JH
1391 port->icount.tx += transfer_size;
1392 dev_dbg(&port->dev, "icount.tx is %d:\n", port->icount.tx);
95da310e 1393exit:
3f542974
PS
1394 return bytes_sent;
1395
1396}
1397
1398/*****************************************************************************
1399 * mos7840_throttle
1400 * this function is called by the tty driver when it wants to stop the data
1401 * being read from the port.
1402 *****************************************************************************/
1403
95da310e 1404static void mos7840_throttle(struct tty_struct *tty)
3f542974 1405{
95da310e 1406 struct usb_serial_port *port = tty->driver_data;
3f542974 1407 struct moschip_port *mos7840_port;
3f542974
PS
1408 int status;
1409
9c134a14 1410 if (mos7840_port_paranoia_check(port, __func__))
3f542974 1411 return;
3f542974
PS
1412
1413 mos7840_port = mos7840_get_port_private(port);
1414
1415 if (mos7840_port == NULL)
1416 return;
1417
1418 if (!mos7840_port->open) {
9c134a14 1419 dev_dbg(&port->dev, "%s", "port not opened\n");
3f542974
PS
1420 return;
1421 }
1422
3f542974
PS
1423 /* if we are implementing XON/XOFF, send the stop character */
1424 if (I_IXOFF(tty)) {
1425 unsigned char stop_char = STOP_CHAR(tty);
95da310e
AC
1426 status = mos7840_write(tty, port, &stop_char, 1);
1427 if (status <= 0)
3f542974 1428 return;
3f542974 1429 }
3f542974 1430 /* if we are implementing RTS/CTS, toggle that line */
9db276f8 1431 if (C_CRTSCTS(tty)) {
3f542974 1432 mos7840_port->shadowMCR &= ~MCR_RTS;
95da310e 1433 status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
3f542974 1434 mos7840_port->shadowMCR);
95da310e 1435 if (status < 0)
3f542974 1436 return;
3f542974 1437 }
3f542974
PS
1438}
1439
1440/*****************************************************************************
1441 * mos7840_unthrottle
880af9db
AC
1442 * this function is called by the tty driver when it wants to resume
1443 * the data being read from the port (called after mos7840_throttle is
1444 * called)
3f542974 1445 *****************************************************************************/
95da310e 1446static void mos7840_unthrottle(struct tty_struct *tty)
3f542974 1447{
95da310e 1448 struct usb_serial_port *port = tty->driver_data;
3f542974
PS
1449 int status;
1450 struct moschip_port *mos7840_port = mos7840_get_port_private(port);
1451
9c134a14 1452 if (mos7840_port_paranoia_check(port, __func__))
3f542974 1453 return;
3f542974
PS
1454
1455 if (mos7840_port == NULL)
1456 return;
1457
1458 if (!mos7840_port->open) {
9c134a14 1459 dev_dbg(&port->dev, "%s - port not opened\n", __func__);
3f542974
PS
1460 return;
1461 }
1462
3f542974
PS
1463 /* if we are implementing XON/XOFF, send the start character */
1464 if (I_IXOFF(tty)) {
1465 unsigned char start_char = START_CHAR(tty);
95da310e
AC
1466 status = mos7840_write(tty, port, &start_char, 1);
1467 if (status <= 0)
3f542974 1468 return;
3f542974
PS
1469 }
1470
1471 /* if we are implementing RTS/CTS, toggle that line */
9db276f8 1472 if (C_CRTSCTS(tty)) {
3f542974 1473 mos7840_port->shadowMCR |= MCR_RTS;
95da310e 1474 status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
3f542974 1475 mos7840_port->shadowMCR);
95da310e 1476 if (status < 0)
3f542974 1477 return;
3f542974 1478 }
3f542974
PS
1479}
1480
60b33c13 1481static int mos7840_tiocmget(struct tty_struct *tty)
3f542974 1482{
95da310e 1483 struct usb_serial_port *port = tty->driver_data;
3f542974
PS
1484 struct moschip_port *mos7840_port;
1485 unsigned int result;
1486 __u16 msr;
1487 __u16 mcr;
880af9db 1488 int status;
3f542974
PS
1489 mos7840_port = mos7840_get_port_private(port);
1490
3f542974
PS
1491 if (mos7840_port == NULL)
1492 return -ENODEV;
1493
1494 status = mos7840_get_uart_reg(port, MODEM_STATUS_REGISTER, &msr);
cd8db057 1495 if (status < 0)
a91ccd26 1496 return -EIO;
3f542974 1497 status = mos7840_get_uart_reg(port, MODEM_CONTROL_REGISTER, &mcr);
cd8db057 1498 if (status < 0)
a91ccd26 1499 return -EIO;
3f542974
PS
1500 result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0)
1501 | ((mcr & MCR_RTS) ? TIOCM_RTS : 0)
1502 | ((mcr & MCR_LOOPBACK) ? TIOCM_LOOP : 0)
1503 | ((msr & MOS7840_MSR_CTS) ? TIOCM_CTS : 0)
1504 | ((msr & MOS7840_MSR_CD) ? TIOCM_CAR : 0)
1505 | ((msr & MOS7840_MSR_RI) ? TIOCM_RI : 0)
1506 | ((msr & MOS7840_MSR_DSR) ? TIOCM_DSR : 0);
1507
9c134a14 1508 dev_dbg(&port->dev, "%s - 0x%04X\n", __func__, result);
3f542974
PS
1509
1510 return result;
1511}
1512
20b9d177 1513static int mos7840_tiocmset(struct tty_struct *tty,
3f542974
PS
1514 unsigned int set, unsigned int clear)
1515{
95da310e 1516 struct usb_serial_port *port = tty->driver_data;
3f542974
PS
1517 struct moschip_port *mos7840_port;
1518 unsigned int mcr;
87521c46 1519 int status;
3f542974 1520
3f542974
PS
1521 mos7840_port = mos7840_get_port_private(port);
1522
1523 if (mos7840_port == NULL)
1524 return -ENODEV;
1525
e2984494 1526 /* FIXME: What locks the port registers ? */
3f542974
PS
1527 mcr = mos7840_port->shadowMCR;
1528 if (clear & TIOCM_RTS)
1529 mcr &= ~MCR_RTS;
1530 if (clear & TIOCM_DTR)
1531 mcr &= ~MCR_DTR;
1532 if (clear & TIOCM_LOOP)
1533 mcr &= ~MCR_LOOPBACK;
1534
1535 if (set & TIOCM_RTS)
1536 mcr |= MCR_RTS;
1537 if (set & TIOCM_DTR)
1538 mcr |= MCR_DTR;
1539 if (set & TIOCM_LOOP)
1540 mcr |= MCR_LOOPBACK;
1541
1542 mos7840_port->shadowMCR = mcr;
1543
3f542974
PS
1544 status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, mcr);
1545 if (status < 0) {
9c134a14 1546 dev_dbg(&port->dev, "setting MODEM_CONTROL_REGISTER Failed\n");
87521c46 1547 return status;
3f542974
PS
1548 }
1549
1550 return 0;
1551}
1552
1553/*****************************************************************************
1554 * mos7840_calc_baud_rate_divisor
1555 * this function calculates the proper baud rate divisor for the specified
1556 * baud rate.
1557 *****************************************************************************/
9c134a14
GKH
1558static int mos7840_calc_baud_rate_divisor(struct usb_serial_port *port,
1559 int baudRate, int *divisor,
880af9db 1560 __u16 *clk_sel_val)
3f542974 1561{
9c134a14 1562 dev_dbg(&port->dev, "%s - %d\n", __func__, baudRate);
3f542974
PS
1563
1564 if (baudRate <= 115200) {
1565 *divisor = 115200 / baudRate;
1566 *clk_sel_val = 0x0;
1567 }
1568 if ((baudRate > 115200) && (baudRate <= 230400)) {
1569 *divisor = 230400 / baudRate;
1570 *clk_sel_val = 0x10;
1571 } else if ((baudRate > 230400) && (baudRate <= 403200)) {
1572 *divisor = 403200 / baudRate;
1573 *clk_sel_val = 0x20;
1574 } else if ((baudRate > 403200) && (baudRate <= 460800)) {
1575 *divisor = 460800 / baudRate;
1576 *clk_sel_val = 0x30;
1577 } else if ((baudRate > 460800) && (baudRate <= 806400)) {
1578 *divisor = 806400 / baudRate;
1579 *clk_sel_val = 0x40;
1580 } else if ((baudRate > 806400) && (baudRate <= 921600)) {
1581 *divisor = 921600 / baudRate;
1582 *clk_sel_val = 0x50;
1583 } else if ((baudRate > 921600) && (baudRate <= 1572864)) {
1584 *divisor = 1572864 / baudRate;
1585 *clk_sel_val = 0x60;
1586 } else if ((baudRate > 1572864) && (baudRate <= 3145728)) {
1587 *divisor = 3145728 / baudRate;
1588 *clk_sel_val = 0x70;
1589 }
1590 return 0;
3f542974
PS
1591}
1592
1593/*****************************************************************************
1594 * mos7840_send_cmd_write_baud_rate
1595 * this function sends the proper command to change the baud rate of the
1596 * specified port.
1597 *****************************************************************************/
1598
1599static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port,
1600 int baudRate)
1601{
1602 int divisor = 0;
1603 int status;
1604 __u16 Data;
1605 unsigned char number;
1606 __u16 clk_sel_val;
1607 struct usb_serial_port *port;
1608
1609 if (mos7840_port == NULL)
1610 return -1;
1611
9c134a14
GKH
1612 port = mos7840_port->port;
1613 if (mos7840_port_paranoia_check(port, __func__))
3f542974 1614 return -1;
3f542974 1615
9c134a14 1616 if (mos7840_serial_paranoia_check(port->serial, __func__))
3f542974 1617 return -1;
3f542974 1618
1143832e 1619 number = mos7840_port->port->port_number;
3f542974 1620
1143832e 1621 dev_dbg(&port->dev, "%s - baud = %d\n", __func__, baudRate);
880af9db 1622 /* reset clk_uart_sel in spregOffset */
3f542974
PS
1623 if (baudRate > 115200) {
1624#ifdef HW_flow_control
880af9db
AC
1625 /* NOTE: need to see the pther register to modify */
1626 /* setting h/w flow control bit to 1 */
3f542974
PS
1627 Data = 0x2b;
1628 mos7840_port->shadowMCR = Data;
880af9db
AC
1629 status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
1630 Data);
3f542974 1631 if (status < 0) {
9c134a14 1632 dev_dbg(&port->dev, "Writing spreg failed in set_serial_baud\n");
3f542974
PS
1633 return -1;
1634 }
1635#endif
1636
1637 } else {
1638#ifdef HW_flow_control
093ea2d3 1639 /* setting h/w flow control bit to 0 */
3f542974
PS
1640 Data = 0xb;
1641 mos7840_port->shadowMCR = Data;
880af9db
AC
1642 status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
1643 Data);
3f542974 1644 if (status < 0) {
9c134a14 1645 dev_dbg(&port->dev, "Writing spreg failed in set_serial_baud\n");
3f542974
PS
1646 return -1;
1647 }
1648#endif
1649
1650 }
1651
880af9db 1652 if (1) { /* baudRate <= 115200) */
3f542974
PS
1653 clk_sel_val = 0x0;
1654 Data = 0x0;
9c134a14 1655 status = mos7840_calc_baud_rate_divisor(port, baudRate, &divisor,
3f542974 1656 &clk_sel_val);
880af9db
AC
1657 status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset,
1658 &Data);
3f542974 1659 if (status < 0) {
9c134a14 1660 dev_dbg(&port->dev, "reading spreg failed in set_serial_baud\n");
3f542974
PS
1661 return -1;
1662 }
1663 Data = (Data & 0x8f) | clk_sel_val;
880af9db
AC
1664 status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset,
1665 Data);
3f542974 1666 if (status < 0) {
9c134a14 1667 dev_dbg(&port->dev, "Writing spreg failed in set_serial_baud\n");
3f542974
PS
1668 return -1;
1669 }
1670 /* Calculate the Divisor */
1671
1672 if (status) {
194343d9 1673 dev_err(&port->dev, "%s - bad baud rate\n", __func__);
3f542974
PS
1674 return status;
1675 }
1676 /* Enable access to divisor latch */
1677 Data = mos7840_port->shadowLCR | SERIAL_LCR_DLAB;
1678 mos7840_port->shadowLCR = Data;
1679 mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
1680
1681 /* Write the divisor */
1682 Data = (unsigned char)(divisor & 0xff);
9c134a14 1683 dev_dbg(&port->dev, "set_serial_baud Value to write DLL is %x\n", Data);
3f542974
PS
1684 mos7840_set_uart_reg(port, DIVISOR_LATCH_LSB, Data);
1685
1686 Data = (unsigned char)((divisor & 0xff00) >> 8);
9c134a14 1687 dev_dbg(&port->dev, "set_serial_baud Value to write DLM is %x\n", Data);
3f542974
PS
1688 mos7840_set_uart_reg(port, DIVISOR_LATCH_MSB, Data);
1689
1690 /* Disable access to divisor latch */
1691 Data = mos7840_port->shadowLCR & ~SERIAL_LCR_DLAB;
1692 mos7840_port->shadowLCR = Data;
1693 mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
1694
1695 }
3f542974
PS
1696 return status;
1697}
1698
1699/*****************************************************************************
1700 * mos7840_change_port_settings
1701 * This routine is called to set the UART on the device to match
1702 * the specified new settings.
1703 *****************************************************************************/
1704
95da310e
AC
1705static void mos7840_change_port_settings(struct tty_struct *tty,
1706 struct moschip_port *mos7840_port, struct ktermios *old_termios)
3f542974 1707{
3f542974
PS
1708 int baud;
1709 unsigned cflag;
1710 unsigned iflag;
1711 __u8 lData;
1712 __u8 lParity;
1713 __u8 lStop;
1714 int status;
1715 __u16 Data;
1716 struct usb_serial_port *port;
1717 struct usb_serial *serial;
1718
1719 if (mos7840_port == NULL)
1720 return;
1721
9c134a14 1722 port = mos7840_port->port;
3f542974 1723
9c134a14 1724 if (mos7840_port_paranoia_check(port, __func__))
3f542974 1725 return;
3f542974 1726
9c134a14 1727 if (mos7840_serial_paranoia_check(port->serial, __func__))
3f542974 1728 return;
3f542974
PS
1729
1730 serial = port->serial;
1731
3f542974 1732 if (!mos7840_port->open) {
9c134a14 1733 dev_dbg(&port->dev, "%s - port not opened\n", __func__);
3f542974
PS
1734 return;
1735 }
1736
3f542974
PS
1737 lData = LCR_BITS_8;
1738 lStop = LCR_STOP_1;
1739 lParity = LCR_PAR_NONE;
1740
adc8d746
AC
1741 cflag = tty->termios.c_cflag;
1742 iflag = tty->termios.c_iflag;
3f542974
PS
1743
1744 /* Change the number of bits */
78692cc3
CL
1745 switch (cflag & CSIZE) {
1746 case CS5:
1747 lData = LCR_BITS_5;
1748 break;
3f542974 1749
78692cc3
CL
1750 case CS6:
1751 lData = LCR_BITS_6;
1752 break;
3f542974 1753
78692cc3
CL
1754 case CS7:
1755 lData = LCR_BITS_7;
1756 break;
1757
1758 default:
1759 case CS8:
1760 lData = LCR_BITS_8;
1761 break;
3f542974 1762 }
78692cc3 1763
3f542974
PS
1764 /* Change the Parity bit */
1765 if (cflag & PARENB) {
1766 if (cflag & PARODD) {
1767 lParity = LCR_PAR_ODD;
9c134a14 1768 dev_dbg(&port->dev, "%s - parity = odd\n", __func__);
3f542974
PS
1769 } else {
1770 lParity = LCR_PAR_EVEN;
9c134a14 1771 dev_dbg(&port->dev, "%s - parity = even\n", __func__);
3f542974
PS
1772 }
1773
1774 } else {
9c134a14 1775 dev_dbg(&port->dev, "%s - parity = none\n", __func__);
3f542974
PS
1776 }
1777
880af9db 1778 if (cflag & CMSPAR)
3f542974 1779 lParity = lParity | 0x20;
3f542974
PS
1780
1781 /* Change the Stop bit */
1782 if (cflag & CSTOPB) {
1783 lStop = LCR_STOP_2;
9c134a14 1784 dev_dbg(&port->dev, "%s - stop bits = 2\n", __func__);
3f542974
PS
1785 } else {
1786 lStop = LCR_STOP_1;
9c134a14 1787 dev_dbg(&port->dev, "%s - stop bits = 1\n", __func__);
3f542974
PS
1788 }
1789
1790 /* Update the LCR with the correct value */
1791 mos7840_port->shadowLCR &=
1792 ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK);
1793 mos7840_port->shadowLCR |= (lData | lParity | lStop);
1794
9c134a14
GKH
1795 dev_dbg(&port->dev, "%s - mos7840_port->shadowLCR is %x\n", __func__,
1796 mos7840_port->shadowLCR);
3f542974
PS
1797 /* Disable Interrupts */
1798 Data = 0x00;
1799 mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
1800
1801 Data = 0x00;
1802 mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
1803
1804 Data = 0xcf;
1805 mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
1806
1807 /* Send the updated LCR value to the mos7840 */
1808 Data = mos7840_port->shadowLCR;
1809
1810 mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
1811
1812 Data = 0x00b;
1813 mos7840_port->shadowMCR = Data;
1814 mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
1815 Data = 0x00b;
1816 mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
1817
1818 /* set up the MCR register and send it to the mos7840 */
1819
1820 mos7840_port->shadowMCR = MCR_MASTER_IE;
880af9db 1821 if (cflag & CBAUD)
3f542974 1822 mos7840_port->shadowMCR |= (MCR_DTR | MCR_RTS);
3f542974 1823
880af9db 1824 if (cflag & CRTSCTS)
3f542974 1825 mos7840_port->shadowMCR |= (MCR_XON_ANY);
880af9db 1826 else
3f542974 1827 mos7840_port->shadowMCR &= ~(MCR_XON_ANY);
3f542974
PS
1828
1829 Data = mos7840_port->shadowMCR;
1830 mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
1831
1832 /* Determine divisor based on baud rate */
1833 baud = tty_get_baud_rate(tty);
1834
1835 if (!baud) {
1836 /* pick a default, any default... */
9c134a14 1837 dev_dbg(&port->dev, "%s", "Picked default baud...\n");
3f542974
PS
1838 baud = 9600;
1839 }
1840
9c134a14 1841 dev_dbg(&port->dev, "%s - baud rate = %d\n", __func__, baud);
3f542974
PS
1842 status = mos7840_send_cmd_write_baud_rate(mos7840_port, baud);
1843
1844 /* Enable Interrupts */
1845 Data = 0x0c;
1846 mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
1847
ce9d8562 1848 if (!mos7840_port->read_urb_busy) {
50de36f7 1849 mos7840_port->read_urb_busy = true;
9d380190 1850 status = usb_submit_urb(mos7840_port->read_urb, GFP_KERNEL);
3f542974 1851 if (status) {
9c134a14 1852 dev_dbg(&port->dev, "usb_submit_urb(read bulk) failed, status = %d\n",
3f542974 1853 status);
50de36f7 1854 mos7840_port->read_urb_busy = false;
3f542974
PS
1855 }
1856 }
9c134a14
GKH
1857 dev_dbg(&port->dev, "%s - mos7840_port->shadowLCR is End %x\n", __func__,
1858 mos7840_port->shadowLCR);
3f542974
PS
1859}
1860
1861/*****************************************************************************
1862 * mos7840_set_termios
1863 * this function is called by the tty driver when it wants to change
1864 * the termios structure
1865 *****************************************************************************/
1866
95da310e
AC
1867static void mos7840_set_termios(struct tty_struct *tty,
1868 struct usb_serial_port *port,
606d099c 1869 struct ktermios *old_termios)
3f542974
PS
1870{
1871 int status;
3f542974
PS
1872 struct usb_serial *serial;
1873 struct moschip_port *mos7840_port;
3363155b 1874
9c134a14 1875 if (mos7840_port_paranoia_check(port, __func__))
3f542974 1876 return;
3f542974
PS
1877
1878 serial = port->serial;
1879
9c134a14 1880 if (mos7840_serial_paranoia_check(serial, __func__))
3f542974 1881 return;
3f542974
PS
1882
1883 mos7840_port = mos7840_get_port_private(port);
1884
1885 if (mos7840_port == NULL)
1886 return;
1887
3f542974 1888 if (!mos7840_port->open) {
9c134a14 1889 dev_dbg(&port->dev, "%s - port not opened\n", __func__);
3f542974
PS
1890 return;
1891 }
1892
3f542974
PS
1893 /* change the port settings to the new ones specified */
1894
95da310e 1895 mos7840_change_port_settings(tty, mos7840_port, old_termios);
3f542974
PS
1896
1897 if (!mos7840_port->read_urb) {
9c134a14 1898 dev_dbg(&port->dev, "%s", "URB KILLED !!!!!\n");
3f542974
PS
1899 return;
1900 }
1901
ce9d8562 1902 if (!mos7840_port->read_urb_busy) {
50de36f7 1903 mos7840_port->read_urb_busy = true;
9d380190 1904 status = usb_submit_urb(mos7840_port->read_urb, GFP_KERNEL);
3f542974 1905 if (status) {
9c134a14 1906 dev_dbg(&port->dev, "usb_submit_urb(read bulk) failed, status = %d\n",
3f542974 1907 status);
50de36f7 1908 mos7840_port->read_urb_busy = false;
3f542974
PS
1909 }
1910 }
3f542974
PS
1911}
1912
1913/*****************************************************************************
1914 * mos7840_get_lsr_info - get line status register info
1915 *
1916 * Purpose: Let user call ioctl() to get info when the UART physically
1917 * is emptied. On bus types like RS485, the transmitter must
1918 * release the bus after transmitting. This must be done when
1919 * the transmit shift register is empty, not be done when the
1920 * transmit holding register is empty. This functionality
1921 * allows an RS485 driver to be written in user space.
1922 *****************************************************************************/
1923
95da310e 1924static int mos7840_get_lsr_info(struct tty_struct *tty,
97c4965d 1925 unsigned int __user *value)
3f542974
PS
1926{
1927 int count;
1928 unsigned int result = 0;
1929
95da310e 1930 count = mos7840_chars_in_buffer(tty);
9c134a14 1931 if (count == 0)
3f542974 1932 result = TIOCSER_TEMT;
3f542974
PS
1933
1934 if (copy_to_user(value, &result, sizeof(int)))
1935 return -EFAULT;
1936 return 0;
1937}
1938
3f542974
PS
1939/*****************************************************************************
1940 * mos7840_get_serial_info
1941 * function to get information about serial port
1942 *****************************************************************************/
1943
1944static int mos7840_get_serial_info(struct moschip_port *mos7840_port,
97c4965d 1945 struct serial_struct __user *retinfo)
3f542974
PS
1946{
1947 struct serial_struct tmp;
1948
1949 if (mos7840_port == NULL)
1950 return -1;
1951
3f542974
PS
1952 memset(&tmp, 0, sizeof(tmp));
1953
1954 tmp.type = PORT_16550A;
e5b1e206 1955 tmp.line = mos7840_port->port->minor;
1143832e 1956 tmp.port = mos7840_port->port->port_number;
3f542974 1957 tmp.irq = 0;
3f542974
PS
1958 tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE;
1959 tmp.baud_base = 9600;
1960 tmp.close_delay = 5 * HZ;
1961 tmp.closing_wait = 30 * HZ;
1962
1963 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
1964 return -EFAULT;
1965 return 0;
1966}
1967
1968/*****************************************************************************
1969 * SerialIoctl
1970 * this function handles any ioctl calls to the driver
1971 *****************************************************************************/
1972
00a0d0d6 1973static int mos7840_ioctl(struct tty_struct *tty,
3f542974
PS
1974 unsigned int cmd, unsigned long arg)
1975{
95da310e 1976 struct usb_serial_port *port = tty->driver_data;
97c4965d 1977 void __user *argp = (void __user *)arg;
3f542974 1978 struct moschip_port *mos7840_port;
3f542974 1979
9c134a14 1980 if (mos7840_port_paranoia_check(port, __func__))
3f542974 1981 return -1;
3f542974
PS
1982
1983 mos7840_port = mos7840_get_port_private(port);
3f542974
PS
1984
1985 if (mos7840_port == NULL)
1986 return -1;
1987
3f542974
PS
1988 switch (cmd) {
1989 /* return number of bytes available */
1990
3f542974 1991 case TIOCSERGETLSR:
9c134a14 1992 dev_dbg(&port->dev, "%s TIOCSERGETLSR\n", __func__);
95da310e 1993 return mos7840_get_lsr_info(tty, argp);
3f542974 1994
3f542974 1995 case TIOCGSERIAL:
9c134a14 1996 dev_dbg(&port->dev, "%s TIOCGSERIAL\n", __func__);
97c4965d 1997 return mos7840_get_serial_info(mos7840_port, argp);
3f542974
PS
1998
1999 case TIOCSSERIAL:
9c134a14 2000 dev_dbg(&port->dev, "%s TIOCSSERIAL\n", __func__);
3f542974 2001 break;
3f542974
PS
2002 default:
2003 break;
2004 }
3f542974
PS
2005 return -ENOIOCTLCMD;
2006}
2007
0eafe4de
D
2008static int mos7810_check(struct usb_serial *serial)
2009{
2010 int i, pass_count = 0;
15ee89c3 2011 u8 *buf;
0eafe4de
D
2012 __u16 data = 0, mcr_data = 0;
2013 __u16 test_pattern = 0x55AA;
15ee89c3
JH
2014 int res;
2015
2016 buf = kmalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
2017 if (!buf)
2018 return 0; /* failed to identify 7810 */
0eafe4de
D
2019
2020 /* Store MCR setting */
15ee89c3 2021 res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
0eafe4de 2022 MCS_RDREQ, MCS_RD_RTYPE, 0x0300, MODEM_CONTROL_REGISTER,
15ee89c3
JH
2023 buf, VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
2024 if (res == VENDOR_READ_LENGTH)
2025 mcr_data = *buf;
0eafe4de
D
2026
2027 for (i = 0; i < 16; i++) {
2028 /* Send the 1-bit test pattern out to MCS7810 test pin */
2029 usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
2030 MCS_WRREQ, MCS_WR_RTYPE,
2031 (0x0300 | (((test_pattern >> i) & 0x0001) << 1)),
2032 MODEM_CONTROL_REGISTER, NULL, 0, MOS_WDR_TIMEOUT);
2033
2034 /* Read the test pattern back */
15ee89c3
JH
2035 res = usb_control_msg(serial->dev,
2036 usb_rcvctrlpipe(serial->dev, 0), MCS_RDREQ,
2037 MCS_RD_RTYPE, 0, GPIO_REGISTER, buf,
2038 VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
2039 if (res == VENDOR_READ_LENGTH)
2040 data = *buf;
0eafe4de
D
2041
2042 /* If this is a MCS7810 device, both test patterns must match */
2043 if (((test_pattern >> i) ^ (~data >> 1)) & 0x0001)
2044 break;
2045
2046 pass_count++;
2047 }
2048
2049 /* Restore MCR setting */
2050 usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), MCS_WRREQ,
2051 MCS_WR_RTYPE, 0x0300 | mcr_data, MODEM_CONTROL_REGISTER, NULL,
2052 0, MOS_WDR_TIMEOUT);
2053
15ee89c3
JH
2054 kfree(buf);
2055
0eafe4de
D
2056 if (pass_count == 16)
2057 return 1;
2058
2059 return 0;
2060}
2061
40c24f28
JH
2062static int mos7840_probe(struct usb_serial *serial,
2063 const struct usb_device_id *id)
3f542974 2064{
d551ec9b 2065 u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
15ee89c3 2066 u8 *buf;
40c24f28
JH
2067 int device_type;
2068
2069 if (product == MOSCHIP_DEVICE_ID_7810 ||
2070 product == MOSCHIP_DEVICE_ID_7820) {
2071 device_type = product;
2072 goto out;
2073 }
093ea2d3 2074
15ee89c3 2075 buf = kzalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
40c24f28
JH
2076 if (!buf)
2077 return -ENOMEM;
2078
2079 usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
15ee89c3
JH
2080 MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, buf,
2081 VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
093ea2d3 2082
40c24f28
JH
2083 /* For a MCS7840 device GPIO0 must be set to 1 */
2084 if (buf[0] & 0x01)
2085 device_type = MOSCHIP_DEVICE_ID_7840;
2086 else if (mos7810_check(serial))
2087 device_type = MOSCHIP_DEVICE_ID_7810;
2088 else
2089 device_type = MOSCHIP_DEVICE_ID_7820;
2090
2091 kfree(buf);
2092out:
683a0e4d 2093 usb_set_serial_data(serial, (void *)(unsigned long)device_type);
40c24f28
JH
2094
2095 return 0;
2096}
2097
07814246
JH
2098static int mos7840_calc_num_ports(struct usb_serial *serial,
2099 struct usb_serial_endpoints *epds)
40c24f28 2100{
683a0e4d 2101 int device_type = (unsigned long)usb_get_serial_data(serial);
95254020 2102 int num_ports;
093ea2d3 2103
95254020 2104 num_ports = (device_type >> 4) & 0x000F;
0eafe4de 2105
95254020
JH
2106 /*
2107 * num_ports is currently never zero as device_type is one of
2108 * MOSCHIP_DEVICE_ID_78{1,2,4}0.
2109 */
2110 if (num_ports == 0)
2111 return -ENODEV;
3f542974 2112
95254020 2113 if (epds->num_bulk_in < num_ports || epds->num_bulk_out < num_ports) {
5c75633e
JH
2114 dev_err(&serial->interface->dev, "missing endpoints\n");
2115 return -ENODEV;
2116 }
2117
95254020 2118 return num_ports;
5c75633e
JH
2119}
2120
80c00750 2121static int mos7840_port_probe(struct usb_serial_port *port)
3f542974 2122{
80c00750 2123 struct usb_serial *serial = port->serial;
683a0e4d 2124 int device_type = (unsigned long)usb_get_serial_data(serial);
3f542974 2125 struct moschip_port *mos7840_port;
80c00750
JH
2126 int status;
2127 int pnum;
3f542974 2128 __u16 Data;
3f542974 2129
3f542974
PS
2130 /* we set up the pointers to the endpoints in the mos7840_open *
2131 * function, as the structures aren't created yet. */
2132
1143832e 2133 pnum = port->port_number;
80c00750 2134
ae685eff
JH
2135 dev_dbg(&port->dev, "mos7840_startup: configuring port %d\n", pnum);
2136 mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
10c642d0 2137 if (!mos7840_port)
ae685eff 2138 return -ENOMEM;
3f542974 2139
ae685eff
JH
2140 /* Initialize all port interrupt end point to port 0 int
2141 * endpoint. Our device has only one interrupt end point
2142 * common to all port */
2143
2144 mos7840_port->port = port;
2145 mos7840_set_port_private(port, mos7840_port);
2146 spin_lock_init(&mos7840_port->pool_lock);
2147
2148 /* minor is not initialised until later by
2149 * usb-serial.c:get_free_serial() and cannot therefore be used
2150 * to index device instances */
2151 mos7840_port->port_num = pnum + 1;
e5b1e206 2152 dev_dbg(&port->dev, "port->minor = %d\n", port->minor);
ae685eff 2153 dev_dbg(&port->dev, "mos7840_port->port_num = %d\n", mos7840_port->port_num);
ae685eff
JH
2154
2155 if (mos7840_port->port_num == 1) {
2156 mos7840_port->SpRegOffset = 0x0;
2157 mos7840_port->ControlRegOffset = 0x1;
2158 mos7840_port->DcrRegOffset = 0x4;
2159 } else if ((mos7840_port->port_num == 2) && (serial->num_ports == 4)) {
2160 mos7840_port->SpRegOffset = 0x8;
2161 mos7840_port->ControlRegOffset = 0x9;
2162 mos7840_port->DcrRegOffset = 0x16;
2163 } else if ((mos7840_port->port_num == 2) && (serial->num_ports == 2)) {
2164 mos7840_port->SpRegOffset = 0xa;
2165 mos7840_port->ControlRegOffset = 0xb;
2166 mos7840_port->DcrRegOffset = 0x19;
2167 } else if ((mos7840_port->port_num == 3) && (serial->num_ports == 4)) {
2168 mos7840_port->SpRegOffset = 0xa;
2169 mos7840_port->ControlRegOffset = 0xb;
2170 mos7840_port->DcrRegOffset = 0x19;
2171 } else if ((mos7840_port->port_num == 4) && (serial->num_ports == 4)) {
2172 mos7840_port->SpRegOffset = 0xc;
2173 mos7840_port->ControlRegOffset = 0xd;
2174 mos7840_port->DcrRegOffset = 0x1c;
2175 }
2176 mos7840_dump_serial_port(port, mos7840_port);
2177 mos7840_set_port_private(port, mos7840_port);
2178
2179 /* enable rx_disable bit in control register */
2180 status = mos7840_get_reg_sync(port,
2181 mos7840_port->ControlRegOffset, &Data);
2182 if (status < 0) {
2183 dev_dbg(&port->dev, "Reading ControlReg failed status-0x%x\n", status);
2184 goto out;
2185 } else
2186 dev_dbg(&port->dev, "ControlReg Reading success val is %x, status%d\n", Data, status);
2187 Data |= 0x08; /* setting driver done bit */
2188 Data |= 0x04; /* sp1_bit to have cts change reflect in
2189 modem status reg */
2190
2191 /* Data |= 0x20; //rx_disable bit */
2192 status = mos7840_set_reg_sync(port,
2193 mos7840_port->ControlRegOffset, Data);
2194 if (status < 0) {
2195 dev_dbg(&port->dev, "Writing ControlReg failed(rx_disable) status-0x%x\n", status);
2196 goto out;
2197 } else
2198 dev_dbg(&port->dev, "ControlReg Writing success(rx_disable) status%d\n", status);
2199
2200 /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2
2201 and 0x24 in DCR3 */
2202 Data = 0x01;
2203 status = mos7840_set_reg_sync(port,
2204 (__u16) (mos7840_port->DcrRegOffset + 0), Data);
2205 if (status < 0) {
2206 dev_dbg(&port->dev, "Writing DCR0 failed status-0x%x\n", status);
2207 goto out;
2208 } else
2209 dev_dbg(&port->dev, "DCR0 Writing success status%d\n", status);
3f542974 2210
ae685eff
JH
2211 Data = 0x05;
2212 status = mos7840_set_reg_sync(port,
2213 (__u16) (mos7840_port->DcrRegOffset + 1), Data);
2214 if (status < 0) {
2215 dev_dbg(&port->dev, "Writing DCR1 failed status-0x%x\n", status);
2216 goto out;
2217 } else
2218 dev_dbg(&port->dev, "DCR1 Writing success status%d\n", status);
3f542974 2219
ae685eff
JH
2220 Data = 0x24;
2221 status = mos7840_set_reg_sync(port,
2222 (__u16) (mos7840_port->DcrRegOffset + 2), Data);
2223 if (status < 0) {
2224 dev_dbg(&port->dev, "Writing DCR2 failed status-0x%x\n", status);
2225 goto out;
2226 } else
2227 dev_dbg(&port->dev, "DCR2 Writing success status%d\n", status);
3f542974 2228
ae685eff
JH
2229 /* write values in clkstart0x0 and clkmulti 0x20 */
2230 Data = 0x0;
2231 status = mos7840_set_reg_sync(port, CLK_START_VALUE_REGISTER, Data);
2232 if (status < 0) {
2233 dev_dbg(&port->dev, "Writing CLK_START_VALUE_REGISTER failed status-0x%x\n", status);
2234 goto out;
2235 } else
2236 dev_dbg(&port->dev, "CLK_START_VALUE_REGISTER Writing success status%d\n", status);
3f542974 2237
ae685eff
JH
2238 Data = 0x20;
2239 status = mos7840_set_reg_sync(port, CLK_MULTI_REGISTER, Data);
2240 if (status < 0) {
2241 dev_dbg(&port->dev, "Writing CLK_MULTI_REGISTER failed status-0x%x\n", status);
2242 goto error;
2243 } else
2244 dev_dbg(&port->dev, "CLK_MULTI_REGISTER Writing success status%d\n", status);
3f542974 2245
ae685eff
JH
2246 /* write value 0x0 to scratchpad register */
2247 Data = 0x00;
2248 status = mos7840_set_uart_reg(port, SCRATCH_PAD_REGISTER, Data);
2249 if (status < 0) {
2250 dev_dbg(&port->dev, "Writing SCRATCH_PAD_REGISTER failed status-0x%x\n", status);
2251 goto out;
2252 } else
2253 dev_dbg(&port->dev, "SCRATCH_PAD_REGISTER Writing success status%d\n", status);
2254
2255 /* Zero Length flag register */
2256 if ((mos7840_port->port_num != 1) && (serial->num_ports == 2)) {
2257 Data = 0xff;
80c00750 2258 status = mos7840_set_reg_sync(port,
ae685eff
JH
2259 (__u16) (ZLP_REG1 +
2260 ((__u16)mos7840_port->port_num)), Data);
2261 dev_dbg(&port->dev, "ZLIP offset %x\n",
2262 (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num)));
3f542974 2263 if (status < 0) {
ae685eff
JH
2264 dev_dbg(&port->dev, "Writing ZLP_REG%d failed status-0x%x\n", pnum + 2, status);
2265 goto out;
3f542974 2266 } else
ae685eff
JH
2267 dev_dbg(&port->dev, "ZLP_REG%d Writing success status%d\n", pnum + 2, status);
2268 } else {
2269 Data = 0xff;
80c00750 2270 status = mos7840_set_reg_sync(port,
ae685eff
JH
2271 (__u16) (ZLP_REG1 +
2272 ((__u16)mos7840_port->port_num) - 0x1), Data);
2273 dev_dbg(&port->dev, "ZLIP offset %x\n",
2274 (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num) - 0x1));
3f542974 2275 if (status < 0) {
ae685eff
JH
2276 dev_dbg(&port->dev, "Writing ZLP_REG%d failed status-0x%x\n", pnum + 1, status);
2277 goto out;
3f542974 2278 } else
ae685eff 2279 dev_dbg(&port->dev, "ZLP_REG%d Writing success status%d\n", pnum + 1, status);
3f542974 2280
ae685eff
JH
2281 }
2282 mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL);
2283 mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL);
2284 mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest),
2285 GFP_KERNEL);
2286 if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf ||
2287 !mos7840_port->dr) {
2288 status = -ENOMEM;
2289 goto error;
2290 }
0eafe4de 2291
ae685eff 2292 mos7840_port->has_led = false;
0eafe4de 2293
ae685eff
JH
2294 /* Initialize LED timers */
2295 if (device_type == MOSCHIP_DEVICE_ID_7810) {
2296 mos7840_port->has_led = true;
0eafe4de 2297
05cf0dec
JH
2298 mos7840_port->led_urb = usb_alloc_urb(0, GFP_KERNEL);
2299 mos7840_port->led_dr = kmalloc(sizeof(*mos7840_port->led_dr),
2300 GFP_KERNEL);
2301 if (!mos7840_port->led_urb || !mos7840_port->led_dr) {
2302 status = -ENOMEM;
2303 goto error;
2304 }
2305
f05b7cb6
VT
2306 setup_timer(&mos7840_port->led_timer1, mos7840_led_off,
2307 (unsigned long)mos7840_port);
ae685eff
JH
2308 mos7840_port->led_timer1.expires =
2309 jiffies + msecs_to_jiffies(LED_ON_MS);
f05b7cb6
VT
2310 setup_timer(&mos7840_port->led_timer2, mos7840_led_flag_off,
2311 (unsigned long)mos7840_port);
ae685eff
JH
2312 mos7840_port->led_timer2.expires =
2313 jiffies + msecs_to_jiffies(LED_OFF_MS);
0eafe4de 2314
ae685eff
JH
2315 /* Turn off LED */
2316 mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300);
2317 }
2318out:
80c00750
JH
2319 if (pnum == serial->num_ports - 1) {
2320 /* Zero Length flag enable */
2321 Data = 0x0f;
2322 status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data);
2323 if (status < 0) {
2324 dev_dbg(&port->dev, "Writing ZLP_REG5 failed status-0x%x\n", status);
2325 goto error;
2326 } else
2327 dev_dbg(&port->dev, "ZLP_REG5 Writing success status%d\n", status);
2328
2329 /* setting configuration feature to one */
2330 usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
2331 0x03, 0x00, 0x01, 0x00, NULL, 0x00,
2332 MOS_WDR_TIMEOUT);
2333 }
3f542974 2334 return 0;
0de9a702 2335error:
05cf0dec
JH
2336 kfree(mos7840_port->led_dr);
2337 usb_free_urb(mos7840_port->led_urb);
80c00750
JH
2338 kfree(mos7840_port->dr);
2339 kfree(mos7840_port->ctrl_buf);
2340 usb_free_urb(mos7840_port->control_urb);
2341 kfree(mos7840_port);
0de9a702 2342
0de9a702 2343 return status;
3f542974
PS
2344}
2345
80c00750 2346static int mos7840_port_remove(struct usb_serial_port *port)
3f542974 2347{
3f542974 2348 struct moschip_port *mos7840_port;
3f542974 2349
80c00750 2350 mos7840_port = mos7840_get_port_private(port);
3f542974 2351
80c00750
JH
2352 if (mos7840_port->has_led) {
2353 /* Turn off LED */
2354 mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300);
3f542974 2355
80c00750
JH
2356 del_timer_sync(&mos7840_port->led_timer1);
2357 del_timer_sync(&mos7840_port->led_timer2);
05cf0dec
JH
2358
2359 usb_kill_urb(mos7840_port->led_urb);
2360 usb_free_urb(mos7840_port->led_urb);
2361 kfree(mos7840_port->led_dr);
f9c99bb8 2362 }
80c00750
JH
2363 usb_kill_urb(mos7840_port->control_urb);
2364 usb_free_urb(mos7840_port->control_urb);
2365 kfree(mos7840_port->ctrl_buf);
2366 kfree(mos7840_port->dr);
2367 kfree(mos7840_port);
f9c99bb8 2368
80c00750 2369 return 0;
3f542974
PS
2370}
2371
2372static struct usb_serial_driver moschip7840_4port_device = {
2373 .driver = {
2374 .owner = THIS_MODULE,
2375 .name = "mos7840",
2376 },
2377 .description = DRIVER_DESC,
68e24113 2378 .id_table = id_table,
95254020 2379 .num_interrupt_in = 1,
3f542974
PS
2380 .open = mos7840_open,
2381 .close = mos7840_close,
2382 .write = mos7840_write,
2383 .write_room = mos7840_write_room,
2384 .chars_in_buffer = mos7840_chars_in_buffer,
2385 .throttle = mos7840_throttle,
2386 .unthrottle = mos7840_unthrottle,
2387 .calc_num_ports = mos7840_calc_num_ports,
40c24f28 2388 .probe = mos7840_probe,
3f542974
PS
2389 .ioctl = mos7840_ioctl,
2390 .set_termios = mos7840_set_termios,
2391 .break_ctl = mos7840_break,
2392 .tiocmget = mos7840_tiocmget,
2393 .tiocmset = mos7840_tiocmset,
0c613371 2394 .tiocmiwait = usb_serial_generic_tiocmiwait,
8c1a07ff 2395 .get_icount = usb_serial_generic_get_icount,
80c00750
JH
2396 .port_probe = mos7840_port_probe,
2397 .port_remove = mos7840_port_remove,
3f542974
PS
2398 .read_bulk_callback = mos7840_bulk_in_callback,
2399 .read_int_callback = mos7840_interrupt_callback,
2400};
2401
4d2a7aff
AS
2402static struct usb_serial_driver * const serial_drivers[] = {
2403 &moschip7840_4port_device, NULL
2404};
2405
68e24113 2406module_usb_serial_driver(serial_drivers, id_table);
3f542974 2407
3f542974
PS
2408MODULE_DESCRIPTION(DRIVER_DESC);
2409MODULE_LICENSE("GPL");