Loading drivers/usb/serial/ch341.c +52 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,18 @@ #define CH341_BAUDBASE_FACTOR 1532620800 #define CH341_BAUDBASE_DIVMAX 3 /* Break support - the information used to implement this was gleaned from * the Net/FreeBSD uchcom.c driver by Takanori Watanabe. Domo arigato. */ #define CH341_REQ_WRITE_REG 0x9A #define CH341_REQ_READ_REG 0x95 #define CH341_REG_BREAK1 0x05 #define CH341_REG_BREAK2 0x18 #define CH341_NBREAK_BITS_REG1 0x01 #define CH341_NBREAK_BITS_REG2 0x40 static int debug; static struct usb_device_id id_table [] = { Loading Loading @@ -373,6 +385,45 @@ static void ch341_set_termios(struct tty_struct *tty, */ } static void ch341_break_ctl(struct tty_struct *tty, int break_state) { const uint16_t ch341_break_reg = CH341_REG_BREAK1 | ((uint16_t) CH341_REG_BREAK2 << 8); struct usb_serial_port *port = tty->driver_data; int r; uint16_t reg_contents; uint8_t break_reg[2]; dbg("%s()", __func__); r = ch341_control_in(port->serial->dev, CH341_REQ_READ_REG, ch341_break_reg, 0, break_reg, sizeof(break_reg)); if (r < 0) { printk(KERN_WARNING "%s: USB control read error whilst getting" " break register contents.\n", __FILE__); return; } dbg("%s - initial ch341 break register contents - reg1: %x, reg2: %x", __func__, break_reg[0], break_reg[1]); if (break_state != 0) { dbg("%s - Enter break state requested", __func__); break_reg[0] &= ~CH341_NBREAK_BITS_REG1; break_reg[1] &= ~CH341_NBREAK_BITS_REG2; } else { dbg("%s - Leave break state requested", __func__); break_reg[0] |= CH341_NBREAK_BITS_REG1; break_reg[1] |= CH341_NBREAK_BITS_REG2; } dbg("%s - New ch341 break register contents - reg1: %x, reg2: %x", __func__, break_reg[0], break_reg[1]); reg_contents = (uint16_t)break_reg[0] | ((uint16_t)break_reg[1] << 8); r = ch341_control_out(port->serial->dev, CH341_REQ_WRITE_REG, ch341_break_reg, reg_contents); if (r < 0) printk(KERN_WARNING "%s: USB control write error whilst setting" " break register contents.\n", __FILE__); } static int ch341_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear) { Loading Loading @@ -576,6 +627,7 @@ static struct usb_serial_driver ch341_device = { .close = ch341_close, .ioctl = ch341_ioctl, .set_termios = ch341_set_termios, .break_ctl = ch341_break_ctl, .tiocmget = ch341_tiocmget, .tiocmset = ch341_tiocmset, .read_int_callback = ch341_read_int_callback, Loading Loading
drivers/usb/serial/ch341.c +52 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,18 @@ #define CH341_BAUDBASE_FACTOR 1532620800 #define CH341_BAUDBASE_DIVMAX 3 /* Break support - the information used to implement this was gleaned from * the Net/FreeBSD uchcom.c driver by Takanori Watanabe. Domo arigato. */ #define CH341_REQ_WRITE_REG 0x9A #define CH341_REQ_READ_REG 0x95 #define CH341_REG_BREAK1 0x05 #define CH341_REG_BREAK2 0x18 #define CH341_NBREAK_BITS_REG1 0x01 #define CH341_NBREAK_BITS_REG2 0x40 static int debug; static struct usb_device_id id_table [] = { Loading Loading @@ -373,6 +385,45 @@ static void ch341_set_termios(struct tty_struct *tty, */ } static void ch341_break_ctl(struct tty_struct *tty, int break_state) { const uint16_t ch341_break_reg = CH341_REG_BREAK1 | ((uint16_t) CH341_REG_BREAK2 << 8); struct usb_serial_port *port = tty->driver_data; int r; uint16_t reg_contents; uint8_t break_reg[2]; dbg("%s()", __func__); r = ch341_control_in(port->serial->dev, CH341_REQ_READ_REG, ch341_break_reg, 0, break_reg, sizeof(break_reg)); if (r < 0) { printk(KERN_WARNING "%s: USB control read error whilst getting" " break register contents.\n", __FILE__); return; } dbg("%s - initial ch341 break register contents - reg1: %x, reg2: %x", __func__, break_reg[0], break_reg[1]); if (break_state != 0) { dbg("%s - Enter break state requested", __func__); break_reg[0] &= ~CH341_NBREAK_BITS_REG1; break_reg[1] &= ~CH341_NBREAK_BITS_REG2; } else { dbg("%s - Leave break state requested", __func__); break_reg[0] |= CH341_NBREAK_BITS_REG1; break_reg[1] |= CH341_NBREAK_BITS_REG2; } dbg("%s - New ch341 break register contents - reg1: %x, reg2: %x", __func__, break_reg[0], break_reg[1]); reg_contents = (uint16_t)break_reg[0] | ((uint16_t)break_reg[1] << 8); r = ch341_control_out(port->serial->dev, CH341_REQ_WRITE_REG, ch341_break_reg, reg_contents); if (r < 0) printk(KERN_WARNING "%s: USB control write error whilst setting" " break register contents.\n", __FILE__); } static int ch341_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear) { Loading Loading @@ -576,6 +627,7 @@ static struct usb_serial_driver ch341_device = { .close = ch341_close, .ioctl = ch341_ioctl, .set_termios = ch341_set_termios, .break_ctl = ch341_break_ctl, .tiocmget = ch341_tiocmget, .tiocmset = ch341_tiocmset, .read_int_callback = ch341_read_int_callback, Loading