1 // SPDX-License-Identifier: GPL-2.0+
3 * spcp8x5 USB to serial adaptor driver
5 * Copyright (C) 2010-2013 Johan Hovold (jhovold@gmail.com)
6 * Copyright (C) 2006 Linxb (xubin.lin@worldplus.com.cn)
7 * Copyright (C) 2006 S1 Corp.
9 * Original driver for 2.6.10 pl2303 driver by
10 * Greg Kroah-Hartman (greg@kroah.com)
11 * Changes for 2.6.20 by Harald Klein <hari@vt100.at>
13 #include <linux/kernel.h>
14 #include <linux/errno.h>
15 #include <linux/slab.h>
16 #include <linux/tty.h>
17 #include <linux/tty_driver.h>
18 #include <linux/tty_flip.h>
19 #include <linux/module.h>
20 #include <linux/spinlock.h>
21 #include <linux/usb.h>
22 #include <linux/usb/serial.h>
24 #define DRIVER_DESC "SPCP8x5 USB to serial adaptor driver"
26 #define SPCP825_QUIRK_NO_UART_STATUS 0x01
27 #define SPCP825_QUIRK_NO_WORK_MODE 0x02
29 #define SPCP8x5_007_VID 0x04FC
30 #define SPCP8x5_007_PID 0x0201
31 #define SPCP8x5_008_VID 0x04fc
32 #define SPCP8x5_008_PID 0x0235
33 #define SPCP8x5_PHILIPS_VID 0x0471
34 #define SPCP8x5_PHILIPS_PID 0x081e
35 #define SPCP8x5_INTERMATIC_VID 0x04FC
36 #define SPCP8x5_INTERMATIC_PID 0x0204
37 #define SPCP8x5_835_VID 0x04fc
38 #define SPCP8x5_835_PID 0x0231
40 static const struct usb_device_id id_table
[] = {
41 { USB_DEVICE(SPCP8x5_PHILIPS_VID
, SPCP8x5_PHILIPS_PID
)},
42 { USB_DEVICE(SPCP8x5_INTERMATIC_VID
, SPCP8x5_INTERMATIC_PID
)},
43 { USB_DEVICE(SPCP8x5_835_VID
, SPCP8x5_835_PID
)},
44 { USB_DEVICE(SPCP8x5_008_VID
, SPCP8x5_008_PID
)},
45 { USB_DEVICE(SPCP8x5_007_VID
, SPCP8x5_007_PID
),
46 .driver_info
= SPCP825_QUIRK_NO_UART_STATUS
|
47 SPCP825_QUIRK_NO_WORK_MODE
},
48 { } /* Terminating entry */
50 MODULE_DEVICE_TABLE(usb
, id_table
);
52 /* spcp8x5 spec register define */
53 #define MCR_CONTROL_LINE_RTS 0x02
54 #define MCR_CONTROL_LINE_DTR 0x01
58 #define MSR_STATUS_LINE_DCD 0x80
59 #define MSR_STATUS_LINE_RI 0x40
60 #define MSR_STATUS_LINE_DSR 0x20
61 #define MSR_STATUS_LINE_CTS 0x10
63 /* verdor command here , we should define myself */
64 #define SET_DEFAULT 0x40
65 #define SET_DEFAULT_TYPE 0x20
67 #define SET_UART_FORMAT 0x40
68 #define SET_UART_FORMAT_TYPE 0x21
69 #define SET_UART_FORMAT_SIZE_5 0x00
70 #define SET_UART_FORMAT_SIZE_6 0x01
71 #define SET_UART_FORMAT_SIZE_7 0x02
72 #define SET_UART_FORMAT_SIZE_8 0x03
73 #define SET_UART_FORMAT_STOP_1 0x00
74 #define SET_UART_FORMAT_STOP_2 0x04
75 #define SET_UART_FORMAT_PAR_NONE 0x00
76 #define SET_UART_FORMAT_PAR_ODD 0x10
77 #define SET_UART_FORMAT_PAR_EVEN 0x30
78 #define SET_UART_FORMAT_PAR_MASK 0xD0
79 #define SET_UART_FORMAT_PAR_SPACE 0x90
81 #define GET_UART_STATUS_TYPE 0xc0
82 #define GET_UART_STATUS 0x22
83 #define GET_UART_STATUS_MSR 0x06
85 #define SET_UART_STATUS 0x40
86 #define SET_UART_STATUS_TYPE 0x23
87 #define SET_UART_STATUS_MCR 0x0004
88 #define SET_UART_STATUS_MCR_DTR 0x01
89 #define SET_UART_STATUS_MCR_RTS 0x02
90 #define SET_UART_STATUS_MCR_LOOP 0x10
92 #define SET_WORKING_MODE 0x40
93 #define SET_WORKING_MODE_TYPE 0x24
94 #define SET_WORKING_MODE_U2C 0x00
95 #define SET_WORKING_MODE_RS485 0x01
96 #define SET_WORKING_MODE_PDMA 0x02
97 #define SET_WORKING_MODE_SPP 0x03
99 #define SET_FLOWCTL_CHAR 0x40
100 #define SET_FLOWCTL_CHAR_TYPE 0x25
102 #define GET_VERSION 0xc0
103 #define GET_VERSION_TYPE 0x26
105 #define SET_REGISTER 0x40
106 #define SET_REGISTER_TYPE 0x27
108 #define GET_REGISTER 0xc0
109 #define GET_REGISTER_TYPE 0x28
112 #define SET_RAM_TYPE 0x31
115 #define GET_RAM_TYPE 0x32
118 #define UART_STATE 0x08
119 #define UART_STATE_TRANSIENT_MASK 0x75
120 #define UART_DCD 0x01
121 #define UART_DSR 0x02
122 #define UART_BREAK_ERROR 0x04
123 #define UART_RING 0x08
124 #define UART_FRAME_ERROR 0x10
125 #define UART_PARITY_ERROR 0x20
126 #define UART_OVERRUN_ERROR 0x40
127 #define UART_CTS 0x80
129 struct spcp8x5_private
{
135 static int spcp8x5_probe(struct usb_serial
*serial
,
136 const struct usb_device_id
*id
)
138 usb_set_serial_data(serial
, (void *)id
);
143 static int spcp8x5_port_probe(struct usb_serial_port
*port
)
145 const struct usb_device_id
*id
= usb_get_serial_data(port
->serial
);
146 struct spcp8x5_private
*priv
;
148 priv
= kzalloc(sizeof(*priv
), GFP_KERNEL
);
152 spin_lock_init(&priv
->lock
);
153 priv
->quirks
= id
->driver_info
;
155 usb_set_serial_port_data(port
, priv
);
157 port
->port
.drain_delay
= 256;
162 static void spcp8x5_port_remove(struct usb_serial_port
*port
)
164 struct spcp8x5_private
*priv
;
166 priv
= usb_get_serial_port_data(port
);
170 static int spcp8x5_set_ctrl_line(struct usb_serial_port
*port
, u8 mcr
)
172 struct spcp8x5_private
*priv
= usb_get_serial_port_data(port
);
173 struct usb_device
*dev
= port
->serial
->dev
;
176 if (priv
->quirks
& SPCP825_QUIRK_NO_UART_STATUS
)
179 retval
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
180 SET_UART_STATUS_TYPE
, SET_UART_STATUS
,
181 mcr
, 0x04, NULL
, 0, 100);
183 dev_err(&port
->dev
, "failed to set control lines: %d\n",
189 static int spcp8x5_get_msr(struct usb_serial_port
*port
, u8
*status
)
191 struct spcp8x5_private
*priv
= usb_get_serial_port_data(port
);
192 struct usb_device
*dev
= port
->serial
->dev
;
196 if (priv
->quirks
& SPCP825_QUIRK_NO_UART_STATUS
)
199 buf
= kzalloc(1, GFP_KERNEL
);
203 ret
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
204 GET_UART_STATUS
, GET_UART_STATUS_TYPE
,
205 0, GET_UART_STATUS_MSR
, buf
, 1, 100);
207 dev_err(&port
->dev
, "failed to get modem status: %d\n", ret
);
213 dev_dbg(&port
->dev
, "0xc0:0x22:0:6 %d - 0x02%x\n", ret
, *buf
);
222 static void spcp8x5_set_work_mode(struct usb_serial_port
*port
, u16 value
,
225 struct spcp8x5_private
*priv
= usb_get_serial_port_data(port
);
226 struct usb_device
*dev
= port
->serial
->dev
;
229 if (priv
->quirks
& SPCP825_QUIRK_NO_WORK_MODE
)
232 ret
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
233 SET_WORKING_MODE_TYPE
, SET_WORKING_MODE
,
234 value
, index
, NULL
, 0, 100);
235 dev_dbg(&port
->dev
, "value = %#x , index = %#x\n", value
, index
);
237 dev_err(&port
->dev
, "failed to set work mode: %d\n", ret
);
240 static int spcp8x5_carrier_raised(struct usb_serial_port
*port
)
245 ret
= spcp8x5_get_msr(port
, &msr
);
246 if (ret
|| msr
& MSR_STATUS_LINE_DCD
)
252 static void spcp8x5_dtr_rts(struct usb_serial_port
*port
, int on
)
254 struct spcp8x5_private
*priv
= usb_get_serial_port_data(port
);
258 spin_lock_irqsave(&priv
->lock
, flags
);
260 priv
->line_control
= MCR_CONTROL_LINE_DTR
261 | MCR_CONTROL_LINE_RTS
;
263 priv
->line_control
&= ~ (MCR_CONTROL_LINE_DTR
264 | MCR_CONTROL_LINE_RTS
);
265 control
= priv
->line_control
;
266 spin_unlock_irqrestore(&priv
->lock
, flags
);
267 spcp8x5_set_ctrl_line(port
, control
);
270 static void spcp8x5_init_termios(struct tty_struct
*tty
)
272 tty_encode_baud_rate(tty
, 115200, 115200);
275 static void spcp8x5_set_termios(struct tty_struct
*tty
,
276 struct usb_serial_port
*port
,
277 const struct ktermios
*old_termios
)
279 struct usb_serial
*serial
= port
->serial
;
280 struct spcp8x5_private
*priv
= usb_get_serial_port_data(port
);
282 unsigned int cflag
= tty
->termios
.c_cflag
;
283 unsigned short uartdata
;
284 unsigned char buf
[2] = {0, 0};
289 /* check that they really want us to change something */
290 if (old_termios
&& !tty_termios_hw_change(&tty
->termios
, old_termios
))
293 /* set DTR/RTS active */
294 spin_lock_irqsave(&priv
->lock
, flags
);
295 control
= priv
->line_control
;
296 if (old_termios
&& (old_termios
->c_cflag
& CBAUD
) == B0
) {
297 priv
->line_control
|= MCR_DTR
;
298 if (!(old_termios
->c_cflag
& CRTSCTS
))
299 priv
->line_control
|= MCR_RTS
;
301 if (control
!= priv
->line_control
) {
302 control
= priv
->line_control
;
303 spin_unlock_irqrestore(&priv
->lock
, flags
);
304 spcp8x5_set_ctrl_line(port
, control
);
306 spin_unlock_irqrestore(&priv
->lock
, flags
);
310 baud
= tty_get_baud_rate(tty
);
312 case 300: buf
[0] = 0x00; break;
313 case 600: buf
[0] = 0x01; break;
314 case 1200: buf
[0] = 0x02; break;
315 case 2400: buf
[0] = 0x03; break;
316 case 4800: buf
[0] = 0x04; break;
317 case 9600: buf
[0] = 0x05; break;
318 case 19200: buf
[0] = 0x07; break;
319 case 38400: buf
[0] = 0x09; break;
320 case 57600: buf
[0] = 0x0a; break;
321 case 115200: buf
[0] = 0x0b; break;
322 case 230400: buf
[0] = 0x0c; break;
323 case 460800: buf
[0] = 0x0d; break;
324 case 921600: buf
[0] = 0x0e; break;
325 /* case 1200000: buf[0] = 0x0f; break; */
326 /* case 2400000: buf[0] = 0x10; break; */
327 case 3000000: buf
[0] = 0x11; break;
328 /* case 6000000: buf[0] = 0x12; break; */
331 buf
[0] = 0x0b; break;
333 dev_err(&port
->dev
, "unsupported baudrate, using 9600\n");
336 /* Set Data Length : 00:5bit, 01:6bit, 10:7bit, 11:8bit */
337 switch (cflag
& CSIZE
) {
339 buf
[1] |= SET_UART_FORMAT_SIZE_5
;
342 buf
[1] |= SET_UART_FORMAT_SIZE_6
;
345 buf
[1] |= SET_UART_FORMAT_SIZE_7
;
349 buf
[1] |= SET_UART_FORMAT_SIZE_8
;
353 /* Set Stop bit2 : 0:1bit 1:2bit */
354 buf
[1] |= (cflag
& CSTOPB
) ? SET_UART_FORMAT_STOP_2
:
355 SET_UART_FORMAT_STOP_1
;
357 /* Set Parity bit3-4 01:Odd 11:Even */
358 if (cflag
& PARENB
) {
359 buf
[1] |= (cflag
& PARODD
) ?
360 SET_UART_FORMAT_PAR_ODD
: SET_UART_FORMAT_PAR_EVEN
;
362 buf
[1] |= SET_UART_FORMAT_PAR_NONE
;
364 uartdata
= buf
[0] | buf
[1]<<8;
366 i
= usb_control_msg(serial
->dev
, usb_sndctrlpipe(serial
->dev
, 0),
367 SET_UART_FORMAT_TYPE
, SET_UART_FORMAT
,
368 uartdata
, 0, NULL
, 0, 100);
370 dev_err(&port
->dev
, "Set UART format %#x failed (error = %d)\n",
372 dev_dbg(&port
->dev
, "0x21:0x40:0:0 %d\n", i
);
374 if (cflag
& CRTSCTS
) {
375 /* enable hardware flow control */
376 spcp8x5_set_work_mode(port
, 0x000a, SET_WORKING_MODE_U2C
);
380 static int spcp8x5_open(struct tty_struct
*tty
, struct usb_serial_port
*port
)
382 struct usb_serial
*serial
= port
->serial
;
383 struct spcp8x5_private
*priv
= usb_get_serial_port_data(port
);
386 usb_clear_halt(serial
->dev
, port
->write_urb
->pipe
);
387 usb_clear_halt(serial
->dev
, port
->read_urb
->pipe
);
389 ret
= usb_control_msg(serial
->dev
, usb_sndctrlpipe(serial
->dev
, 0),
391 0x01, 0x00, NULL
, 0x00, 100);
395 spcp8x5_set_ctrl_line(port
, priv
->line_control
);
398 spcp8x5_set_termios(tty
, port
, NULL
);
400 return usb_serial_generic_open(tty
, port
);
403 static int spcp8x5_tiocmset(struct tty_struct
*tty
,
404 unsigned int set
, unsigned int clear
)
406 struct usb_serial_port
*port
= tty
->driver_data
;
407 struct spcp8x5_private
*priv
= usb_get_serial_port_data(port
);
411 spin_lock_irqsave(&priv
->lock
, flags
);
413 priv
->line_control
|= MCR_RTS
;
415 priv
->line_control
|= MCR_DTR
;
416 if (clear
& TIOCM_RTS
)
417 priv
->line_control
&= ~MCR_RTS
;
418 if (clear
& TIOCM_DTR
)
419 priv
->line_control
&= ~MCR_DTR
;
420 control
= priv
->line_control
;
421 spin_unlock_irqrestore(&priv
->lock
, flags
);
423 return spcp8x5_set_ctrl_line(port
, control
);
426 static int spcp8x5_tiocmget(struct tty_struct
*tty
)
428 struct usb_serial_port
*port
= tty
->driver_data
;
429 struct spcp8x5_private
*priv
= usb_get_serial_port_data(port
);
435 result
= spcp8x5_get_msr(port
, &status
);
439 spin_lock_irqsave(&priv
->lock
, flags
);
440 mcr
= priv
->line_control
;
441 spin_unlock_irqrestore(&priv
->lock
, flags
);
443 result
= ((mcr
& MCR_DTR
) ? TIOCM_DTR
: 0)
444 | ((mcr
& MCR_RTS
) ? TIOCM_RTS
: 0)
445 | ((status
& MSR_STATUS_LINE_CTS
) ? TIOCM_CTS
: 0)
446 | ((status
& MSR_STATUS_LINE_DSR
) ? TIOCM_DSR
: 0)
447 | ((status
& MSR_STATUS_LINE_RI
) ? TIOCM_RI
: 0)
448 | ((status
& MSR_STATUS_LINE_DCD
) ? TIOCM_CD
: 0);
453 static struct usb_serial_driver spcp8x5_device
= {
457 .id_table
= id_table
,
461 .open
= spcp8x5_open
,
462 .dtr_rts
= spcp8x5_dtr_rts
,
463 .carrier_raised
= spcp8x5_carrier_raised
,
464 .set_termios
= spcp8x5_set_termios
,
465 .init_termios
= spcp8x5_init_termios
,
466 .tiocmget
= spcp8x5_tiocmget
,
467 .tiocmset
= spcp8x5_tiocmset
,
468 .probe
= spcp8x5_probe
,
469 .port_probe
= spcp8x5_port_probe
,
470 .port_remove
= spcp8x5_port_remove
,
473 static struct usb_serial_driver
* const serial_drivers
[] = {
474 &spcp8x5_device
, NULL
477 module_usb_serial_driver(serial_drivers
, id_table
);
479 MODULE_DESCRIPTION(DRIVER_DESC
);
480 MODULE_LICENSE("GPL");