0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/kernel.h>
0014 #include <linux/errno.h>
0015 #include <linux/slab.h>
0016 #include <linux/tty.h>
0017 #include <linux/tty_driver.h>
0018 #include <linux/tty_flip.h>
0019 #include <linux/module.h>
0020 #include <linux/spinlock.h>
0021 #include <linux/usb.h>
0022 #include <linux/usb/serial.h>
0023
0024 #define DRIVER_DESC "SPCP8x5 USB to serial adaptor driver"
0025
0026 #define SPCP825_QUIRK_NO_UART_STATUS 0x01
0027 #define SPCP825_QUIRK_NO_WORK_MODE 0x02
0028
0029 #define SPCP8x5_007_VID 0x04FC
0030 #define SPCP8x5_007_PID 0x0201
0031 #define SPCP8x5_008_VID 0x04fc
0032 #define SPCP8x5_008_PID 0x0235
0033 #define SPCP8x5_PHILIPS_VID 0x0471
0034 #define SPCP8x5_PHILIPS_PID 0x081e
0035 #define SPCP8x5_INTERMATIC_VID 0x04FC
0036 #define SPCP8x5_INTERMATIC_PID 0x0204
0037 #define SPCP8x5_835_VID 0x04fc
0038 #define SPCP8x5_835_PID 0x0231
0039
0040 static const struct usb_device_id id_table[] = {
0041 { USB_DEVICE(SPCP8x5_PHILIPS_VID , SPCP8x5_PHILIPS_PID)},
0042 { USB_DEVICE(SPCP8x5_INTERMATIC_VID, SPCP8x5_INTERMATIC_PID)},
0043 { USB_DEVICE(SPCP8x5_835_VID, SPCP8x5_835_PID)},
0044 { USB_DEVICE(SPCP8x5_008_VID, SPCP8x5_008_PID)},
0045 { USB_DEVICE(SPCP8x5_007_VID, SPCP8x5_007_PID),
0046 .driver_info = SPCP825_QUIRK_NO_UART_STATUS |
0047 SPCP825_QUIRK_NO_WORK_MODE },
0048 { }
0049 };
0050 MODULE_DEVICE_TABLE(usb, id_table);
0051
0052 struct spcp8x5_usb_ctrl_arg {
0053 u8 type;
0054 u8 cmd;
0055 u8 cmd_type;
0056 u16 value;
0057 u16 index;
0058 u16 length;
0059 };
0060
0061
0062
0063 #define MCR_CONTROL_LINE_RTS 0x02
0064 #define MCR_CONTROL_LINE_DTR 0x01
0065 #define MCR_DTR 0x01
0066 #define MCR_RTS 0x02
0067
0068 #define MSR_STATUS_LINE_DCD 0x80
0069 #define MSR_STATUS_LINE_RI 0x40
0070 #define MSR_STATUS_LINE_DSR 0x20
0071 #define MSR_STATUS_LINE_CTS 0x10
0072
0073
0074 #define SET_DEFAULT 0x40
0075 #define SET_DEFAULT_TYPE 0x20
0076
0077 #define SET_UART_FORMAT 0x40
0078 #define SET_UART_FORMAT_TYPE 0x21
0079 #define SET_UART_FORMAT_SIZE_5 0x00
0080 #define SET_UART_FORMAT_SIZE_6 0x01
0081 #define SET_UART_FORMAT_SIZE_7 0x02
0082 #define SET_UART_FORMAT_SIZE_8 0x03
0083 #define SET_UART_FORMAT_STOP_1 0x00
0084 #define SET_UART_FORMAT_STOP_2 0x04
0085 #define SET_UART_FORMAT_PAR_NONE 0x00
0086 #define SET_UART_FORMAT_PAR_ODD 0x10
0087 #define SET_UART_FORMAT_PAR_EVEN 0x30
0088 #define SET_UART_FORMAT_PAR_MASK 0xD0
0089 #define SET_UART_FORMAT_PAR_SPACE 0x90
0090
0091 #define GET_UART_STATUS_TYPE 0xc0
0092 #define GET_UART_STATUS 0x22
0093 #define GET_UART_STATUS_MSR 0x06
0094
0095 #define SET_UART_STATUS 0x40
0096 #define SET_UART_STATUS_TYPE 0x23
0097 #define SET_UART_STATUS_MCR 0x0004
0098 #define SET_UART_STATUS_MCR_DTR 0x01
0099 #define SET_UART_STATUS_MCR_RTS 0x02
0100 #define SET_UART_STATUS_MCR_LOOP 0x10
0101
0102 #define SET_WORKING_MODE 0x40
0103 #define SET_WORKING_MODE_TYPE 0x24
0104 #define SET_WORKING_MODE_U2C 0x00
0105 #define SET_WORKING_MODE_RS485 0x01
0106 #define SET_WORKING_MODE_PDMA 0x02
0107 #define SET_WORKING_MODE_SPP 0x03
0108
0109 #define SET_FLOWCTL_CHAR 0x40
0110 #define SET_FLOWCTL_CHAR_TYPE 0x25
0111
0112 #define GET_VERSION 0xc0
0113 #define GET_VERSION_TYPE 0x26
0114
0115 #define SET_REGISTER 0x40
0116 #define SET_REGISTER_TYPE 0x27
0117
0118 #define GET_REGISTER 0xc0
0119 #define GET_REGISTER_TYPE 0x28
0120
0121 #define SET_RAM 0x40
0122 #define SET_RAM_TYPE 0x31
0123
0124 #define GET_RAM 0xc0
0125 #define GET_RAM_TYPE 0x32
0126
0127
0128 #define UART_STATE 0x08
0129 #define UART_STATE_TRANSIENT_MASK 0x75
0130 #define UART_DCD 0x01
0131 #define UART_DSR 0x02
0132 #define UART_BREAK_ERROR 0x04
0133 #define UART_RING 0x08
0134 #define UART_FRAME_ERROR 0x10
0135 #define UART_PARITY_ERROR 0x20
0136 #define UART_OVERRUN_ERROR 0x40
0137 #define UART_CTS 0x80
0138
0139 struct spcp8x5_private {
0140 unsigned quirks;
0141 spinlock_t lock;
0142 u8 line_control;
0143 };
0144
0145 static int spcp8x5_probe(struct usb_serial *serial,
0146 const struct usb_device_id *id)
0147 {
0148 usb_set_serial_data(serial, (void *)id);
0149
0150 return 0;
0151 }
0152
0153 static int spcp8x5_port_probe(struct usb_serial_port *port)
0154 {
0155 const struct usb_device_id *id = usb_get_serial_data(port->serial);
0156 struct spcp8x5_private *priv;
0157
0158 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
0159 if (!priv)
0160 return -ENOMEM;
0161
0162 spin_lock_init(&priv->lock);
0163 priv->quirks = id->driver_info;
0164
0165 usb_set_serial_port_data(port, priv);
0166
0167 port->port.drain_delay = 256;
0168
0169 return 0;
0170 }
0171
0172 static void spcp8x5_port_remove(struct usb_serial_port *port)
0173 {
0174 struct spcp8x5_private *priv;
0175
0176 priv = usb_get_serial_port_data(port);
0177 kfree(priv);
0178 }
0179
0180 static int spcp8x5_set_ctrl_line(struct usb_serial_port *port, u8 mcr)
0181 {
0182 struct spcp8x5_private *priv = usb_get_serial_port_data(port);
0183 struct usb_device *dev = port->serial->dev;
0184 int retval;
0185
0186 if (priv->quirks & SPCP825_QUIRK_NO_UART_STATUS)
0187 return -EPERM;
0188
0189 retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
0190 SET_UART_STATUS_TYPE, SET_UART_STATUS,
0191 mcr, 0x04, NULL, 0, 100);
0192 if (retval != 0) {
0193 dev_err(&port->dev, "failed to set control lines: %d\n",
0194 retval);
0195 }
0196 return retval;
0197 }
0198
0199 static int spcp8x5_get_msr(struct usb_serial_port *port, u8 *status)
0200 {
0201 struct spcp8x5_private *priv = usb_get_serial_port_data(port);
0202 struct usb_device *dev = port->serial->dev;
0203 u8 *buf;
0204 int ret;
0205
0206 if (priv->quirks & SPCP825_QUIRK_NO_UART_STATUS)
0207 return -EPERM;
0208
0209 buf = kzalloc(1, GFP_KERNEL);
0210 if (!buf)
0211 return -ENOMEM;
0212
0213 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
0214 GET_UART_STATUS, GET_UART_STATUS_TYPE,
0215 0, GET_UART_STATUS_MSR, buf, 1, 100);
0216 if (ret < 1) {
0217 dev_err(&port->dev, "failed to get modem status: %d\n", ret);
0218 if (ret >= 0)
0219 ret = -EIO;
0220 goto out;
0221 }
0222
0223 dev_dbg(&port->dev, "0xc0:0x22:0:6 %d - 0x02%x\n", ret, *buf);
0224 *status = *buf;
0225 ret = 0;
0226 out:
0227 kfree(buf);
0228
0229 return ret;
0230 }
0231
0232 static void spcp8x5_set_work_mode(struct usb_serial_port *port, u16 value,
0233 u16 index)
0234 {
0235 struct spcp8x5_private *priv = usb_get_serial_port_data(port);
0236 struct usb_device *dev = port->serial->dev;
0237 int ret;
0238
0239 if (priv->quirks & SPCP825_QUIRK_NO_WORK_MODE)
0240 return;
0241
0242 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
0243 SET_WORKING_MODE_TYPE, SET_WORKING_MODE,
0244 value, index, NULL, 0, 100);
0245 dev_dbg(&port->dev, "value = %#x , index = %#x\n", value, index);
0246 if (ret < 0)
0247 dev_err(&port->dev, "failed to set work mode: %d\n", ret);
0248 }
0249
0250 static int spcp8x5_carrier_raised(struct usb_serial_port *port)
0251 {
0252 u8 msr;
0253 int ret;
0254
0255 ret = spcp8x5_get_msr(port, &msr);
0256 if (ret || msr & MSR_STATUS_LINE_DCD)
0257 return 1;
0258
0259 return 0;
0260 }
0261
0262 static void spcp8x5_dtr_rts(struct usb_serial_port *port, int on)
0263 {
0264 struct spcp8x5_private *priv = usb_get_serial_port_data(port);
0265 unsigned long flags;
0266 u8 control;
0267
0268 spin_lock_irqsave(&priv->lock, flags);
0269 if (on)
0270 priv->line_control = MCR_CONTROL_LINE_DTR
0271 | MCR_CONTROL_LINE_RTS;
0272 else
0273 priv->line_control &= ~ (MCR_CONTROL_LINE_DTR
0274 | MCR_CONTROL_LINE_RTS);
0275 control = priv->line_control;
0276 spin_unlock_irqrestore(&priv->lock, flags);
0277 spcp8x5_set_ctrl_line(port, control);
0278 }
0279
0280 static void spcp8x5_init_termios(struct tty_struct *tty)
0281 {
0282 tty_encode_baud_rate(tty, 115200, 115200);
0283 }
0284
0285 static void spcp8x5_set_termios(struct tty_struct *tty,
0286 struct usb_serial_port *port, struct ktermios *old_termios)
0287 {
0288 struct usb_serial *serial = port->serial;
0289 struct spcp8x5_private *priv = usb_get_serial_port_data(port);
0290 unsigned long flags;
0291 unsigned int cflag = tty->termios.c_cflag;
0292 unsigned short uartdata;
0293 unsigned char buf[2] = {0, 0};
0294 int baud;
0295 int i;
0296 u8 control;
0297
0298
0299 if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios))
0300 return;
0301
0302
0303 spin_lock_irqsave(&priv->lock, flags);
0304 control = priv->line_control;
0305 if (old_termios && (old_termios->c_cflag & CBAUD) == B0) {
0306 priv->line_control |= MCR_DTR;
0307 if (!(old_termios->c_cflag & CRTSCTS))
0308 priv->line_control |= MCR_RTS;
0309 }
0310 if (control != priv->line_control) {
0311 control = priv->line_control;
0312 spin_unlock_irqrestore(&priv->lock, flags);
0313 spcp8x5_set_ctrl_line(port, control);
0314 } else {
0315 spin_unlock_irqrestore(&priv->lock, flags);
0316 }
0317
0318
0319 baud = tty_get_baud_rate(tty);
0320 switch (baud) {
0321 case 300: buf[0] = 0x00; break;
0322 case 600: buf[0] = 0x01; break;
0323 case 1200: buf[0] = 0x02; break;
0324 case 2400: buf[0] = 0x03; break;
0325 case 4800: buf[0] = 0x04; break;
0326 case 9600: buf[0] = 0x05; break;
0327 case 19200: buf[0] = 0x07; break;
0328 case 38400: buf[0] = 0x09; break;
0329 case 57600: buf[0] = 0x0a; break;
0330 case 115200: buf[0] = 0x0b; break;
0331 case 230400: buf[0] = 0x0c; break;
0332 case 460800: buf[0] = 0x0d; break;
0333 case 921600: buf[0] = 0x0e; break;
0334
0335
0336 case 3000000: buf[0] = 0x11; break;
0337
0338 case 0:
0339 case 1000000:
0340 buf[0] = 0x0b; break;
0341 default:
0342 dev_err(&port->dev, "unsupported baudrate, using 9600\n");
0343 }
0344
0345
0346 switch (cflag & CSIZE) {
0347 case CS5:
0348 buf[1] |= SET_UART_FORMAT_SIZE_5;
0349 break;
0350 case CS6:
0351 buf[1] |= SET_UART_FORMAT_SIZE_6;
0352 break;
0353 case CS7:
0354 buf[1] |= SET_UART_FORMAT_SIZE_7;
0355 break;
0356 default:
0357 case CS8:
0358 buf[1] |= SET_UART_FORMAT_SIZE_8;
0359 break;
0360 }
0361
0362
0363 buf[1] |= (cflag & CSTOPB) ? SET_UART_FORMAT_STOP_2 :
0364 SET_UART_FORMAT_STOP_1;
0365
0366
0367 if (cflag & PARENB) {
0368 buf[1] |= (cflag & PARODD) ?
0369 SET_UART_FORMAT_PAR_ODD : SET_UART_FORMAT_PAR_EVEN ;
0370 } else {
0371 buf[1] |= SET_UART_FORMAT_PAR_NONE;
0372 }
0373 uartdata = buf[0] | buf[1]<<8;
0374
0375 i = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
0376 SET_UART_FORMAT_TYPE, SET_UART_FORMAT,
0377 uartdata, 0, NULL, 0, 100);
0378 if (i < 0)
0379 dev_err(&port->dev, "Set UART format %#x failed (error = %d)\n",
0380 uartdata, i);
0381 dev_dbg(&port->dev, "0x21:0x40:0:0 %d\n", i);
0382
0383 if (cflag & CRTSCTS) {
0384
0385 spcp8x5_set_work_mode(port, 0x000a, SET_WORKING_MODE_U2C);
0386 }
0387 }
0388
0389 static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port)
0390 {
0391 struct usb_serial *serial = port->serial;
0392 struct spcp8x5_private *priv = usb_get_serial_port_data(port);
0393 int ret;
0394
0395 usb_clear_halt(serial->dev, port->write_urb->pipe);
0396 usb_clear_halt(serial->dev, port->read_urb->pipe);
0397
0398 ret = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
0399 0x09, 0x00,
0400 0x01, 0x00, NULL, 0x00, 100);
0401 if (ret)
0402 return ret;
0403
0404 spcp8x5_set_ctrl_line(port, priv->line_control);
0405
0406 if (tty)
0407 spcp8x5_set_termios(tty, port, NULL);
0408
0409 return usb_serial_generic_open(tty, port);
0410 }
0411
0412 static int spcp8x5_tiocmset(struct tty_struct *tty,
0413 unsigned int set, unsigned int clear)
0414 {
0415 struct usb_serial_port *port = tty->driver_data;
0416 struct spcp8x5_private *priv = usb_get_serial_port_data(port);
0417 unsigned long flags;
0418 u8 control;
0419
0420 spin_lock_irqsave(&priv->lock, flags);
0421 if (set & TIOCM_RTS)
0422 priv->line_control |= MCR_RTS;
0423 if (set & TIOCM_DTR)
0424 priv->line_control |= MCR_DTR;
0425 if (clear & TIOCM_RTS)
0426 priv->line_control &= ~MCR_RTS;
0427 if (clear & TIOCM_DTR)
0428 priv->line_control &= ~MCR_DTR;
0429 control = priv->line_control;
0430 spin_unlock_irqrestore(&priv->lock, flags);
0431
0432 return spcp8x5_set_ctrl_line(port, control);
0433 }
0434
0435 static int spcp8x5_tiocmget(struct tty_struct *tty)
0436 {
0437 struct usb_serial_port *port = tty->driver_data;
0438 struct spcp8x5_private *priv = usb_get_serial_port_data(port);
0439 unsigned long flags;
0440 unsigned int mcr;
0441 u8 status;
0442 unsigned int result;
0443
0444 result = spcp8x5_get_msr(port, &status);
0445 if (result)
0446 return result;
0447
0448 spin_lock_irqsave(&priv->lock, flags);
0449 mcr = priv->line_control;
0450 spin_unlock_irqrestore(&priv->lock, flags);
0451
0452 result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0)
0453 | ((mcr & MCR_RTS) ? TIOCM_RTS : 0)
0454 | ((status & MSR_STATUS_LINE_CTS) ? TIOCM_CTS : 0)
0455 | ((status & MSR_STATUS_LINE_DSR) ? TIOCM_DSR : 0)
0456 | ((status & MSR_STATUS_LINE_RI) ? TIOCM_RI : 0)
0457 | ((status & MSR_STATUS_LINE_DCD) ? TIOCM_CD : 0);
0458
0459 return result;
0460 }
0461
0462 static struct usb_serial_driver spcp8x5_device = {
0463 .driver = {
0464 .owner = THIS_MODULE,
0465 .name = "SPCP8x5",
0466 },
0467 .id_table = id_table,
0468 .num_ports = 1,
0469 .num_bulk_in = 1,
0470 .num_bulk_out = 1,
0471 .open = spcp8x5_open,
0472 .dtr_rts = spcp8x5_dtr_rts,
0473 .carrier_raised = spcp8x5_carrier_raised,
0474 .set_termios = spcp8x5_set_termios,
0475 .init_termios = spcp8x5_init_termios,
0476 .tiocmget = spcp8x5_tiocmget,
0477 .tiocmset = spcp8x5_tiocmset,
0478 .probe = spcp8x5_probe,
0479 .port_probe = spcp8x5_port_probe,
0480 .port_remove = spcp8x5_port_remove,
0481 };
0482
0483 static struct usb_serial_driver * const serial_drivers[] = {
0484 &spcp8x5_device, NULL
0485 };
0486
0487 module_usb_serial_driver(serial_drivers, id_table);
0488
0489 MODULE_DESCRIPTION(DRIVER_DESC);
0490 MODULE_LICENSE("GPL");