Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * spcp8x5 USB to serial adaptor driver
0004  *
0005  * Copyright (C) 2010-2013 Johan Hovold (jhovold@gmail.com)
0006  * Copyright (C) 2006 Linxb (xubin.lin@worldplus.com.cn)
0007  * Copyright (C) 2006 S1 Corp.
0008  *
0009  * Original driver for 2.6.10 pl2303 driver by
0010  *   Greg Kroah-Hartman (greg@kroah.com)
0011  * Changes for 2.6.20 by Harald Klein <hari@vt100.at>
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     { }                 /* Terminating entry */
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 /* spcp8x5 spec register define */
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 /* verdor command here , we should define myself */
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 /* how come ??? */
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     /* check that they really want us to change something */
0299     if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios))
0300         return;
0301 
0302     /* set DTR/RTS active */
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     /* Set Baud Rate */
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 /*  case 1200000:   buf[0] = 0x0f;  break; */
0335 /*  case 2400000:   buf[0] = 0x10;  break; */
0336     case 3000000:   buf[0] = 0x11;  break;
0337 /*  case 6000000:   buf[0] = 0x12;  break; */
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     /* Set Data Length : 00:5bit, 01:6bit, 10:7bit, 11:8bit */
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     /* Set Stop bit2 : 0:1bit 1:2bit */
0363     buf[1] |= (cflag & CSTOPB) ? SET_UART_FORMAT_STOP_2 :
0364                      SET_UART_FORMAT_STOP_1;
0365 
0366     /* Set Parity bit3-4 01:Odd 11:Even */
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         /* enable hardware flow control */
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");