{ "auto_complete": { "selected_items": [ [ "usb", "usb_device\t(ch341.c)" ] ] }, "buffers": [ { "file": "/home/eddy/C-files/stm32samples/F0-nolib/Snippets/fallthru", "settings": { "buffer_size": 30, "line_ending": "Unix" } }, { "contents": "// SPDX-License-Identifier: GPL-2.0\n/*\n * Copyright 2007, Frank A Kingswood \n * Copyright 2007, Werner Cornelius \n * Copyright 2009, Boris Hajduk \n *\n * ch341.c implements a serial port driver for the Winchiphead CH341.\n *\n * The CH341 device can be used to implement an RS232 asynchronous\n * serial port, an IEEE-1284 parallel printer port or a memory-like\n * interface. In all cases the CH341 supports an I2C interface as well.\n * This driver only supports the asynchronous serial interface.\n */\n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n\n#define DEFAULT_BAUD_RATE 9600\n#define DEFAULT_TIMEOUT 1000\n\n/* flags for IO-Bits */\n#define CH341_BIT_RTS (1 << 6)\n#define CH341_BIT_DTR (1 << 5)\n\n/******************************/\n/* interrupt pipe definitions */\n/******************************/\n/* always 4 interrupt bytes */\n/* first irq byte normally 0x08 */\n/* second irq byte base 0x7d + below */\n/* third irq byte base 0x94 + below */\n/* fourth irq byte normally 0xee */\n\n/* second interrupt byte */\n#define CH341_MULT_STAT 0x04 /* multiple status since last interrupt event */\n\n/* status returned in third interrupt answer byte, inverted in data\n from irq */\n#define CH341_BIT_CTS 0x01\n#define CH341_BIT_DSR 0x02\n#define CH341_BIT_RI 0x04\n#define CH341_BIT_DCD 0x08\n#define CH341_BITS_MODEM_STAT 0x0f /* all bits */\n\n/*******************************/\n/* baudrate calculation factor */\n/*******************************/\n#define CH341_BAUDBASE_FACTOR 1532620800\n#define CH341_BAUDBASE_DIVMAX 3\n\n/* Break support - the information used to implement this was gleaned from\n * the Net/FreeBSD uchcom.c driver by Takanori Watanabe. Domo arigato.\n */\n\n#define CH341_REQ_READ_VERSION 0x5F\n#define CH341_REQ_WRITE_REG 0x9A\n#define CH341_REQ_READ_REG 0x95\n#define CH341_REQ_SERIAL_INIT 0xA1\n#define CH341_REQ_MODEM_CTRL 0xA4\n\n#define CH341_REG_BREAK 0x05\n#define CH341_REG_LCR 0x18\n#define CH341_NBREAK_BITS 0x01\n\n#define CH341_LCR_ENABLE_RX 0x80\n#define CH341_LCR_ENABLE_TX 0x40\n#define CH341_LCR_MARK_SPACE 0x20\n#define CH341_LCR_PAR_EVEN 0x10\n#define CH341_LCR_ENABLE_PAR 0x08\n#define CH341_LCR_STOP_BITS_2 0x04\n#define CH341_LCR_CS8 0x03\n#define CH341_LCR_CS7 0x02\n#define CH341_LCR_CS6 0x01\n#define CH341_LCR_CS5 0x00\n\nstatic const struct usb_device_id id_table[] = {\n\t{ USB_DEVICE(0x4348, 0x5523) },\n\t{ USB_DEVICE(0x1a86, 0x7523) },\n\t{ USB_DEVICE(0x1a86, 0x5523) },\n\t{ },\n};\nMODULE_DEVICE_TABLE(usb, id_table);\n\nstruct ch341_private {\n\tspinlock_t lock; /* access lock */\n\tunsigned baud_rate; /* set baud rate */\n\tu8 mcr;\n\tu8 msr;\n\tu8 lcr;\n};\n\nstatic void ch341_set_termios(struct tty_struct *tty,\n\t\t\t struct usb_serial_port *port,\n\t\t\t struct ktermios *old_termios);\n\nstatic int ch341_control_out(struct usb_device *dev, u8 request,\n\t\t\t u16 value, u16 index)\n{\n\tint r;\n\n\tdev_dbg(&dev->dev, \"%s - (%02x,%04x,%04x)\\n\", __func__,\n\t\trequest, value, index);\n\n\tr = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request,\n\t\t\t USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,\n\t\t\t value, index, NULL, 0, DEFAULT_TIMEOUT);\n\tif (r < 0)\n\t\tdev_err(&dev->dev, \"failed to send control message: %d\\n\", r);\n\n\treturn r;\n}\n\nstatic int ch341_control_in(struct usb_device *dev,\n\t\t\t u8 request, u16 value, u16 index,\n\t\t\t char *buf, unsigned bufsize)\n{\n\tint r;\n\n\tdev_dbg(&dev->dev, \"%s - (%02x,%04x,%04x,%u)\\n\", __func__,\n\t\trequest, value, index, bufsize);\n\n\tr = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request,\n\t\t\t USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,\n\t\t\t value, index, buf, bufsize, DEFAULT_TIMEOUT);\n\tif (r < bufsize) {\n\t\tif (r >= 0) {\n\t\t\tdev_err(&dev->dev,\n\t\t\t\t\"short control message received (%d < %u)\\n\",\n\t\t\t\tr, bufsize);\n\t\t\tr = -EIO;\n\t\t}\n\n\t\tdev_err(&dev->dev, \"failed to receive control message: %d\\n\",\n\t\t\tr);\n\t\treturn r;\n\t}\n\n\treturn 0;\n}\n\nstatic int ch341_set_baudrate_lcr(struct usb_device *dev,\n\t\t\t\t struct ch341_private *priv, u8 lcr)\n{\n\tshort a;\n\tint r;\n\tunsigned long factor;\n\tshort divisor;\n\n\tif (!priv->baud_rate)\n\t\treturn -EINVAL;\n\tfactor = (CH341_BAUDBASE_FACTOR / priv->baud_rate);\n\tdivisor = CH341_BAUDBASE_DIVMAX;\n\n\twhile ((factor > 0xfff0) && divisor) {\n\t\tfactor >>= 3;\n\t\tdivisor--;\n\t}\n\n\tif (factor > 0xfff0)\n\t\treturn -EINVAL;\n\n\tfactor = 0x10000 - factor;\n\ta = (factor & 0xff00) | divisor;\n\n\t/*\n\t * CH341A buffers data until a full endpoint-size packet (32 bytes)\n\t * has been received unless bit 7 is set.\n\t */\n\ta |= BIT(7);\n\n\tr = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x1312, a);\n\tif (r)\n\t\treturn r;\n\n\tr = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x2518, lcr);\n\tif (r)\n\t\treturn r;\n\n\treturn r;\n}\n\nstatic int ch341_set_handshake(struct usb_device *dev, u8 control)\n{\n\treturn ch341_control_out(dev, CH341_REQ_MODEM_CTRL, ~control, 0);\n}\n\nstatic int ch341_get_status(struct usb_device *dev, struct ch341_private *priv)\n{\n\tconst unsigned int size = 2;\n\tchar *buffer;\n\tint r;\n\tunsigned long flags;\n\n\tbuffer = kmalloc(size, GFP_KERNEL);\n\tif (!buffer)\n\t\treturn -ENOMEM;\n\n\tr = ch341_control_in(dev, CH341_REQ_READ_REG, 0x0706, 0, buffer, size);\n\tif (r < 0)\n\t\tgoto out;\n\n\tspin_lock_irqsave(&priv->lock, flags);\n\tpriv->msr = (~(*buffer)) & CH341_BITS_MODEM_STAT;\n\tspin_unlock_irqrestore(&priv->lock, flags);\n\nout:\tkfree(buffer);\n\treturn r;\n}\n\n/* -------------------------------------------------------------------------- */\n\nstatic int ch341_configure(struct usb_device *dev, struct ch341_private *priv)\n{\n\tconst unsigned int size = 2;\n\tchar *buffer;\n\tint r;\n\n\tbuffer = kmalloc(size, GFP_KERNEL);\n\tif (!buffer)\n\t\treturn -ENOMEM;\n\n\t/* expect two bytes 0x27 0x00 */\n\tr = ch341_control_in(dev, CH341_REQ_READ_VERSION, 0, 0, buffer, size);\n\tif (r < 0)\n\t\tgoto out;\n\tdev_dbg(&dev->dev, \"Chip version: 0x%02x\\n\", buffer[0]);\n\n\tr = ch341_control_out(dev, CH341_REQ_SERIAL_INIT, 0, 0);\n\tif (r < 0)\n\t\tgoto out;\n\n\tr = ch341_set_baudrate_lcr(dev, priv, priv->lcr);\n\tif (r < 0)\n\t\tgoto out;\n\n\tr = ch341_set_handshake(dev, priv->mcr);\n\nout:\tkfree(buffer);\n\treturn r;\n}\n\nstatic int ch341_port_probe(struct usb_serial_port *port)\n{\n\tstruct ch341_private *priv;\n\tint r;\n\n\tpriv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL);\n\tif (!priv)\n\t\treturn -ENOMEM;\n\n\tspin_lock_init(&priv->lock);\n\tpriv->baud_rate = DEFAULT_BAUD_RATE;\n\t/*\n\t * Some CH340 devices appear unable to change the initial LCR\n\t * settings, so set a sane 8N1 default.\n\t */\n\tpriv->lcr = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX | CH341_LCR_CS8;\n\n\tr = ch341_configure(port->serial->dev, priv);\n\tif (r < 0)\n\t\tgoto error;\n\n\tusb_set_serial_port_data(port, priv);\n\treturn 0;\n\nerror:\tkfree(priv);\n\treturn r;\n}\n\nstatic int ch341_port_remove(struct usb_serial_port *port)\n{\n\tstruct ch341_private *priv;\n\n\tpriv = usb_get_serial_port_data(port);\n\tkfree(priv);\n\n\treturn 0;\n}\n\nstatic int ch341_carrier_raised(struct usb_serial_port *port)\n{\n\tstruct ch341_private *priv = usb_get_serial_port_data(port);\n\tif (priv->msr & CH341_BIT_DCD)\n\t\treturn 1;\n\treturn 0;\n}\n\nstatic void ch341_dtr_rts(struct usb_serial_port *port, int on)\n{\n\tstruct ch341_private *priv = usb_get_serial_port_data(port);\n\tunsigned long flags;\n\n\t/* drop DTR and RTS */\n\tspin_lock_irqsave(&priv->lock, flags);\n\tif (on)\n\t\tpriv->mcr |= CH341_BIT_RTS | CH341_BIT_DTR;\n\telse\n\t\tpriv->mcr &= ~(CH341_BIT_RTS | CH341_BIT_DTR);\n\tspin_unlock_irqrestore(&priv->lock, flags);\n\tch341_set_handshake(port->serial->dev, priv->mcr);\n}\n\nstatic void ch341_close(struct usb_serial_port *port)\n{\n\tusb_serial_generic_close(port);\n\tusb_kill_urb(port->interrupt_in_urb);\n}\n\n\n/* open this device, set default parameters */\nstatic int ch341_open(struct tty_struct *tty, struct usb_serial_port *port)\n{\n\tstruct ch341_private *priv = usb_get_serial_port_data(port);\n\tint r;\n\n\tif (tty)\n\t\tch341_set_termios(tty, port, NULL);\n\n\tdev_dbg(&port->dev, \"%s - submitting interrupt urb\\n\", __func__);\n\tr = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);\n\tif (r) {\n\t\tdev_err(&port->dev, \"%s - failed to submit interrupt urb: %d\\n\",\n\t\t\t__func__, r);\n\t\treturn r;\n\t}\n\n\tr = ch341_get_status(port->serial->dev, priv);\n\tif (r < 0) {\n\t\tdev_err(&port->dev, \"failed to read modem status: %d\\n\", r);\n\t\tgoto err_kill_interrupt_urb;\n\t}\n\n\tr = usb_serial_generic_open(tty, port);\n\tif (r)\n\t\tgoto err_kill_interrupt_urb;\n\n\treturn 0;\n\nerr_kill_interrupt_urb:\n\tusb_kill_urb(port->interrupt_in_urb);\n\n\treturn r;\n}\n\n/* Old_termios contains the original termios settings and\n * tty->termios contains the new setting to be used.\n */\nstatic void ch341_set_termios(struct tty_struct *tty,\n\t\tstruct usb_serial_port *port, struct ktermios *old_termios)\n{\n\tstruct ch341_private *priv = usb_get_serial_port_data(port);\n\tunsigned baud_rate;\n\tunsigned long flags;\n\tu8 lcr;\n\tint r;\n\n\t/* redundant changes may cause the chip to lose bytes */\n\tif (old_termios && !tty_termios_hw_change(&tty->termios, old_termios))\n\t\treturn;\n\n\tbaud_rate = tty_get_baud_rate(tty);\n\n\tlcr = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX;\n\n\tswitch (C_CSIZE(tty)) {\n\tcase CS5:\n\t\tlcr |= CH341_LCR_CS5;\n\t\tbreak;\n\tcase CS6:\n\t\tlcr |= CH341_LCR_CS6;\n\t\tbreak;\n\tcase CS7:\n\t\tlcr |= CH341_LCR_CS7;\n\t\tbreak;\n\tcase CS8:\n\t\tlcr |= CH341_LCR_CS8;\n\t\tbreak;\n\t}\n\n\tif (C_PARENB(tty)) {\n\t\tlcr |= CH341_LCR_ENABLE_PAR;\n\t\tif (C_PARODD(tty) == 0)\n\t\t\tlcr |= CH341_LCR_PAR_EVEN;\n\t\tif (C_CMSPAR(tty))\n\t\t\tlcr |= CH341_LCR_MARK_SPACE;\n\t}\n\n\tif (C_CSTOPB(tty))\n\t\tlcr |= CH341_LCR_STOP_BITS_2;\n\n\tif (baud_rate) {\n\t\tpriv->baud_rate = baud_rate;\n\n\t\tr = ch341_set_baudrate_lcr(port->serial->dev, priv, lcr);\n\t\tif (r < 0 && old_termios) {\n\t\t\tpriv->baud_rate = tty_termios_baud_rate(old_termios);\n\t\t\ttty_termios_copy_hw(&tty->termios, old_termios);\n\t\t} else if (r == 0) {\n\t\t\tpriv->lcr = lcr;\n\t\t}\n\t}\n\n\tspin_lock_irqsave(&priv->lock, flags);\n\tif (C_BAUD(tty) == B0)\n\t\tpriv->mcr &= ~(CH341_BIT_DTR | CH341_BIT_RTS);\n\telse if (old_termios && (old_termios->c_cflag & CBAUD) == B0)\n\t\tpriv->mcr |= (CH341_BIT_DTR | CH341_BIT_RTS);\n\tspin_unlock_irqrestore(&priv->lock, flags);\n\n\tch341_set_handshake(port->serial->dev, priv->mcr);\n}\n\nstatic void ch341_break_ctl(struct tty_struct *tty, int break_state)\n{\n\tconst uint16_t ch341_break_reg =\n\t\t\t((uint16_t) CH341_REG_LCR << 8) | CH341_REG_BREAK;\n\tstruct usb_serial_port *port = tty->driver_data;\n\tint r;\n\tuint16_t reg_contents;\n\tuint8_t *break_reg;\n\n\tbreak_reg = kmalloc(2, GFP_KERNEL);\n\tif (!break_reg)\n\t\treturn;\n\n\tr = ch341_control_in(port->serial->dev, CH341_REQ_READ_REG,\n\t\t\tch341_break_reg, 0, break_reg, 2);\n\tif (r < 0) {\n\t\tdev_err(&port->dev, \"%s - USB control read error (%d)\\n\",\n\t\t\t\t__func__, r);\n\t\tgoto out;\n\t}\n\tdev_dbg(&port->dev, \"%s - initial ch341 break register contents - reg1: %x, reg2: %x\\n\",\n\t\t__func__, break_reg[0], break_reg[1]);\n\tif (break_state != 0) {\n\t\tdev_dbg(&port->dev, \"%s - Enter break state requested\\n\", __func__);\n\t\tbreak_reg[0] &= ~CH341_NBREAK_BITS;\n\t\tbreak_reg[1] &= ~CH341_LCR_ENABLE_TX;\n\t} else {\n\t\tdev_dbg(&port->dev, \"%s - Leave break state requested\\n\", __func__);\n\t\tbreak_reg[0] |= CH341_NBREAK_BITS;\n\t\tbreak_reg[1] |= CH341_LCR_ENABLE_TX;\n\t}\n\tdev_dbg(&port->dev, \"%s - New ch341 break register contents - reg1: %x, reg2: %x\\n\",\n\t\t__func__, break_reg[0], break_reg[1]);\n\treg_contents = get_unaligned_le16(break_reg);\n\tr = ch341_control_out(port->serial->dev, CH341_REQ_WRITE_REG,\n\t\t\tch341_break_reg, reg_contents);\n\tif (r < 0)\n\t\tdev_err(&port->dev, \"%s - USB control write error (%d)\\n\",\n\t\t\t\t__func__, r);\nout:\n\tkfree(break_reg);\n}\n\nstatic int ch341_tiocmset(struct tty_struct *tty,\n\t\t\t unsigned int set, unsigned int clear)\n{\n\tstruct usb_serial_port *port = tty->driver_data;\n\tstruct ch341_private *priv = usb_get_serial_port_data(port);\n\tunsigned long flags;\n\tu8 control;\n\n\tspin_lock_irqsave(&priv->lock, flags);\n\tif (set & TIOCM_RTS)\n\t\tpriv->mcr |= CH341_BIT_RTS;\n\tif (set & TIOCM_DTR)\n\t\tpriv->mcr |= CH341_BIT_DTR;\n\tif (clear & TIOCM_RTS)\n\t\tpriv->mcr &= ~CH341_BIT_RTS;\n\tif (clear & TIOCM_DTR)\n\t\tpriv->mcr &= ~CH341_BIT_DTR;\n\tcontrol = priv->mcr;\n\tspin_unlock_irqrestore(&priv->lock, flags);\n\n\treturn ch341_set_handshake(port->serial->dev, control);\n}\n\nstatic void ch341_update_status(struct usb_serial_port *port,\n\t\t\t\t\tunsigned char *data, size_t len)\n{\n\tstruct ch341_private *priv = usb_get_serial_port_data(port);\n\tstruct tty_struct *tty;\n\tunsigned long flags;\n\tu8 status;\n\tu8 delta;\n\n\tif (len < 4)\n\t\treturn;\n\n\tstatus = ~data[2] & CH341_BITS_MODEM_STAT;\n\n\tspin_lock_irqsave(&priv->lock, flags);\n\tdelta = status ^ priv->msr;\n\tpriv->msr = status;\n\tspin_unlock_irqrestore(&priv->lock, flags);\n\n\tif (data[1] & CH341_MULT_STAT)\n\t\tdev_dbg(&port->dev, \"%s - multiple status change\\n\", __func__);\n\n\tif (!delta)\n\t\treturn;\n\n\tif (delta & CH341_BIT_CTS)\n\t\tport->icount.cts++;\n\tif (delta & CH341_BIT_DSR)\n\t\tport->icount.dsr++;\n\tif (delta & CH341_BIT_RI)\n\t\tport->icount.rng++;\n\tif (delta & CH341_BIT_DCD) {\n\t\tport->icount.dcd++;\n\t\ttty = tty_port_tty_get(&port->port);\n\t\tif (tty) {\n\t\t\tusb_serial_handle_dcd_change(port, tty,\n\t\t\t\t\t\tstatus & CH341_BIT_DCD);\n\t\t\ttty_kref_put(tty);\n\t\t}\n\t}\n\n\twake_up_interruptible(&port->port.delta_msr_wait);\n}\n\nstatic void ch341_read_int_callback(struct urb *urb)\n{\n\tstruct usb_serial_port *port = urb->context;\n\tunsigned char *data = urb->transfer_buffer;\n\tunsigned int len = urb->actual_length;\n\tint status;\n\n\tswitch (urb->status) {\n\tcase 0:\n\t\t/* success */\n\t\tbreak;\n\tcase -ECONNRESET:\n\tcase -ENOENT:\n\tcase -ESHUTDOWN:\n\t\t/* this urb is terminated, clean up */\n\t\tdev_dbg(&urb->dev->dev, \"%s - urb shutting down: %d\\n\",\n\t\t\t__func__, urb->status);\n\t\treturn;\n\tdefault:\n\t\tdev_dbg(&urb->dev->dev, \"%s - nonzero urb status: %d\\n\",\n\t\t\t__func__, urb->status);\n\t\tgoto exit;\n\t}\n\n\tusb_serial_debug_data(&port->dev, __func__, len, data);\n\tch341_update_status(port, data, len);\nexit:\n\tstatus = usb_submit_urb(urb, GFP_ATOMIC);\n\tif (status) {\n\t\tdev_err(&urb->dev->dev, \"%s - usb_submit_urb failed: %d\\n\",\n\t\t\t__func__, status);\n\t}\n}\n\nstatic int ch341_tiocmget(struct tty_struct *tty)\n{\n\tstruct usb_serial_port *port = tty->driver_data;\n\tstruct ch341_private *priv = usb_get_serial_port_data(port);\n\tunsigned long flags;\n\tu8 mcr;\n\tu8 status;\n\tunsigned int result;\n\n\tspin_lock_irqsave(&priv->lock, flags);\n\tmcr = priv->mcr;\n\tstatus = priv->msr;\n\tspin_unlock_irqrestore(&priv->lock, flags);\n\n\tresult = ((mcr & CH341_BIT_DTR)\t\t? TIOCM_DTR : 0)\n\t\t | ((mcr & CH341_BIT_RTS)\t? TIOCM_RTS : 0)\n\t\t | ((status & CH341_BIT_CTS)\t? TIOCM_CTS : 0)\n\t\t | ((status & CH341_BIT_DSR)\t? TIOCM_DSR : 0)\n\t\t | ((status & CH341_BIT_RI)\t? TIOCM_RI : 0)\n\t\t | ((status & CH341_BIT_DCD)\t? TIOCM_CD : 0);\n\n\tdev_dbg(&port->dev, \"%s - result = %x\\n\", __func__, result);\n\n\treturn result;\n}\n\nstatic int ch341_reset_resume(struct usb_serial *serial)\n{\n\tstruct usb_serial_port *port = serial->port[0];\n\tstruct ch341_private *priv = usb_get_serial_port_data(port);\n\tint ret;\n\n\t/* reconfigure ch341 serial port after bus-reset */\n\tch341_configure(serial->dev, priv);\n\n\tif (tty_port_initialized(&port->port)) {\n\t\tret = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);\n\t\tif (ret) {\n\t\t\tdev_err(&port->dev, \"failed to submit interrupt urb: %d\\n\",\n\t\t\t\tret);\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = ch341_get_status(port->serial->dev, priv);\n\t\tif (ret < 0) {\n\t\t\tdev_err(&port->dev, \"failed to read modem status: %d\\n\",\n\t\t\t\tret);\n\t\t}\n\t}\n\n\treturn usb_serial_generic_resume(serial);\n}\n\nstatic struct usb_serial_driver ch341_device = {\n\t.driver = {\n\t\t.owner\t= THIS_MODULE,\n\t\t.name\t= \"ch341-uart\",\n\t},\n\t.id_table = id_table,\n\t.num_ports = 1,\n\t.open = ch341_open,\n\t.dtr_rts\t = ch341_dtr_rts,\n\t.carrier_raised\t = ch341_carrier_raised,\n\t.close = ch341_close,\n\t.set_termios = ch341_set_termios,\n\t.break_ctl = ch341_break_ctl,\n\t.tiocmget = ch341_tiocmget,\n\t.tiocmset = ch341_tiocmset,\n\t.tiocmiwait = usb_serial_generic_tiocmiwait,\n\t.read_int_callback = ch341_read_int_callback,\n\t.port_probe = ch341_port_probe,\n\t.port_remove = ch341_port_remove,\n\t.reset_resume = ch341_reset_resume,\n};\n\nstatic struct usb_serial_driver * const serial_drivers[] = {\n\t&ch341_device, NULL\n};\n\nmodule_usb_serial_driver(serial_drivers, id_table);\n\nMODULE_LICENSE(\"GPL v2\");\n", "file": "/usr/src/linux/drivers/usb/serial/ch341.c", "file_size": 16239, "file_write_time": 131616480330000000, "settings": { "buffer_size": 16239, "line_ending": "Unix" } }, { "file": "/home/eddy/C-files/stm32samples/F1-nolib/led_blink/Makefile", "settings": { "buffer_size": 3346, "line_ending": "Unix" } }, { "file": "/usr/src/linux/drivers/usb/serial/pl2303.c", "settings": { "buffer_size": 27410, "line_ending": "Unix" } }, { "file": "main.c", "settings": { "buffer_size": 4104, "encoding": "UTF-8", "line_ending": "Unix" } }, { "file": "usb.c", "settings": { "buffer_size": 4371, "encoding": "UTF-8", "line_ending": "Unix" } }, { "file": "usb.h", "settings": { "buffer_size": 1129, "line_ending": "Unix" } }, { "file": "usb_lib.c", "settings": { "buffer_size": 18311, "encoding": "Cyrillic (KOI8-R)", "line_ending": "Windows" } }, { "file": "usb_lib.h", "settings": { "buffer_size": 7155, "line_ending": "Windows" } } ], "build_system": "", "build_system_choices": [ ], "build_varint": "", "command_palette": { "height": 0.0, "last_filter": "", "selected_items": [ [ "Package Control: inst", "Package Control: Install Package" ], [ "Package Control: in", "Package Control: Install Package" ], [ "Package Control: install", "Package Control: Install Package" ], [ "Package Control: ", "Package Control: Install Package" ], [ "inst", "Package Control: Install Package" ] ], "width": 0.0 }, "console": { "height": 143.0, "history": [ "import urllib.request,os,hashlib; h = '6f4c264a24d933ce70df5dedcf1dcaee' + 'ebe013ee18cced0ef93d5f746d80ef60'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://packagecontrol.io/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by) " ] }, "distraction_free": { "menu_visible": true, "show_minimap": false, "show_open_files": false, "show_tabs": false, "side_bar_visible": false, "status_bar_visible": false }, "expanded_folders": [ "/home/eddy/C-files/stm32samples/F0-nolib/ch340" ], "file_history": [ "/home/eddy/C-files/stm32samples/чек.c", "/home/eddy/.config/sublime-text-3/Packages/All Autocomplete/All Autocomplete.sublime-settings", "/home/eddy/.config/sublime-text-3/Packages/Package Control/Package Control.sublime-settings", "/home/eddy/C-files/stm32samples/F0-nolib/ch340/usb_defs.h", "/home/eddy/C-files/stm32samples/F0-nolib/ch340/hardware.h", "/home/eddy/C-files/stm32samples/F0-nolib/ch340/hardware.c", "/home/eddy/C-files/stm32samples/F0-nolib/usbcdc/can.c", "/home/eddy/C-files/stm32samples/F0-nolib/ch340/usart.c", "/home/eddy/C-files/stm32samples/F0-nolib/usbcdc/can.h", "/home/eddy/C-files/stm32samples/F0-nolib/ch340/Readme.md" ], "find": { "height": 43.0 }, "find_in_files": { "height": 0.0, "where_history": [ ] }, "find_state": { "case_sensitive": false, "find_history": [ ], "highlight": true, "in_selection": false, "preserve_case": false, "regex": false, "replace_history": [ ], "reverse": false, "show_context": true, "use_buffer2": true, "whole_word": false, "wrap": true }, "groups": [ { "selected": 2, "sheets": [ { "buffer": 0, "file": "/home/eddy/C-files/stm32samples/F0-nolib/Snippets/fallthru", "semi_transient": false, "settings": { "buffer_size": 30, "regions": { }, "selection": [ [ 30, 30 ] ], "settings": { "syntax": "Packages/Text/Plain text.tmLanguage" }, "translation.x": 0.0, "translation.y": 0.0, "zoom_level": 1.0 }, "stack_index": 4, "type": "text" }, { "buffer": 1, "file": "/usr/src/linux/drivers/usb/serial/ch341.c", "semi_transient": false, "settings": { "buffer_size": 16239, "regions": { }, "selection": [ [ 4745, 4745 ] ], "settings": { "syntax": "Packages/C++/C.sublime-syntax", "translate_tabs_to_spaces": false }, "translation.x": 0.0, "translation.y": 3426.0, "zoom_level": 1.0 }, "stack_index": 1, "type": "text" }, { "buffer": 2, "file": "/home/eddy/C-files/stm32samples/F1-nolib/led_blink/Makefile", "semi_transient": false, "settings": { "buffer_size": 3346, "regions": { }, "selection": [ [ 0, 0 ] ], "settings": { "syntax": "Packages/Makefile/Makefile.sublime-syntax" }, "translation.x": 0.0, "translation.y": 0.0, "zoom_level": 1.0 }, "stack_index": 0, "type": "text" }, { "buffer": 3, "file": "/usr/src/linux/drivers/usb/serial/pl2303.c", "semi_transient": false, "settings": { "buffer_size": 27410, "regions": { }, "selection": [ [ 6587, 6587 ] ], "settings": { "syntax": "Packages/C++/C.sublime-syntax", "translate_tabs_to_spaces": false }, "translation.x": 0.0, "translation.y": 3822.0, "zoom_level": 1.0 }, "stack_index": 2, "type": "text" }, { "buffer": 4, "file": "main.c", "semi_transient": false, "settings": { "buffer_size": 4104, "regions": { }, "selection": [ [ 1948, 1948 ] ], "settings": { "syntax": "Packages/C++/C.sublime-syntax", "tab_size": 4, "translate_tabs_to_spaces": true }, "translation.x": 0.0, "translation.y": 330.0, "zoom_level": 1.0 }, "stack_index": 8, "type": "text" }, { "buffer": 5, "file": "usb.c", "semi_transient": false, "settings": { "buffer_size": 4371, "regions": { }, "selection": [ [ 1781, 1781 ] ], "settings": { "syntax": "Packages/C++/C.sublime-syntax", "tab_size": 4, "translate_tabs_to_spaces": true }, "translation.x": 0.0, "translation.y": 818.0, "zoom_level": 1.0 }, "stack_index": 7, "type": "text" }, { "buffer": 6, "file": "usb.h", "semi_transient": false, "settings": { "buffer_size": 1129, "regions": { }, "selection": [ [ 0, 0 ] ], "settings": { "syntax": "Packages/C++/C++.sublime-syntax" }, "translation.x": 0.0, "translation.y": 0.0, "zoom_level": 1.0 }, "stack_index": 6, "type": "text" }, { "buffer": 7, "file": "usb_lib.c", "semi_transient": false, "settings": { "buffer_size": 18311, "regions": { }, "selection": [ [ 6489, 6489 ] ], "settings": { "syntax": "Packages/C++/C.sublime-syntax", "tab_size": 4, "translate_tabs_to_spaces": true }, "translation.x": 0.0, "translation.y": 4469.0, "zoom_level": 1.0 }, "stack_index": 5, "type": "text" }, { "buffer": 8, "file": "usb_lib.h", "semi_transient": false, "settings": { "buffer_size": 7155, "regions": { }, "selection": [ [ 1925, 1925 ] ], "settings": { "syntax": "Packages/C++/C++.sublime-syntax", "tab_size": 4, "translate_tabs_to_spaces": true }, "translation.x": 0.0, "translation.y": 727.0, "zoom_level": 1.0 }, "stack_index": 3, "type": "text" } ] } ], "incremental_find": { "height": 0.0 }, "input": { "height": 37.0 }, "layout": { "cells": [ [ 0, 0, 1, 1 ] ], "cols": [ 0.0, 1.0 ], "rows": [ 0.0, 1.0 ] }, "menu_visible": true, "output.find_results": { "height": 0.0 }, "output.unsaved_changes": { "height": 114.0 }, "pinned_build_system": "", "project": "ch340.sublime-project", "replace": { "height": 0.0 }, "save_all_on_build": true, "select_file": { "height": 0.0, "last_filter": "", "selected_items": [ ], "width": 0.0 }, "select_project": { "height": 0.0, "last_filter": "", "selected_items": [ ], "width": 0.0 }, "select_symbol": { "height": 0.0, "last_filter": "", "selected_items": [ ], "width": 0.0 }, "selected_group": 0, "settings": { }, "show_minimap": true, "show_open_files": false, "show_tabs": true, "side_bar_visible": true, "side_bar_width": 217.0, "status_bar_visible": true, "template_settings": { } }