usb 转 uart cp210x 驱动解析

USB 转 uart (cp210x.c) 驱动解析

* usb_serial_driver 结构体解析

    include/linux/usb/serial.h
    /**                     描述一个usb 串口设备驱动                                                       
    * usb_serial_driver - describes a usb serial driver  
    *  将一串描述这个驱动的字符串保存在其中,这个指针在syslog中打印当设备被插入或被拔出                       
    * @description: pointer to a string that describes this driver.  This string   
    *  used in the syslog messages when a device is inserted or removed.   
    *  指向一个列表有关  usb 设备ID结构体 ,这个结构体定义了所有能支持的设备        
    * @id_table: pointer to a list of usb_device_id structures that define all        
    *  of the devices this structure can support.       
    *  这个设备将有不同的端口                           
    * @num_ports: the number of different ports this device will have.  
    *  bulk-in 缓冲区最小的申请的空间           
    * @bulk_in_size: minimum number of bytes to allocate for bulk-in buffer        
    *  (0 = end-point size)                    
    *  申请的bulk-out 缓冲区大小                                    
    * @bulk_out_size: bytes to allocate for bulk-out buffer (0 = end-point size) 
    *  指向一个函数去决定多少个端口这个设备已经动态申请,这个将在probe 之后被调用
    * @calc_num_ports: pointer to a function to determine how many ports this         
    *  device has dynamically.  It will be called after the probe()                
    *  callback is called, but before attach()    
    *  指向一个驱动的 probe 函数                                 
    * @probe: pointer to the driver's probe function.     
    *  这个函数将在设备被插入的时候被调用,但是这个设备必须完全被usb_serial系统完全初始化                         
    *  This will be called when the device is inserted into the system,            
    *  but before the device has been fully initialized by the usb_serial          
    *  subsystem.  Use this function to download any firmware to the device,       
    *  or any other early initialization that might be needed.                     
    *  Return 0 to continue on with the initialization sequence.  Anything         
    *  else will abort it.
    *  指向驱动的attach 函数                                                         
    * @attach: pointer to the driver's attach function. 
    *  这个函数将在usb_serial 结构体完全启动后被调用                  
    *  This will be called when the struct usb_serial structure is fully set       
    *  set up.  Do any local initialization of the device, or any private          
    *  memory structure allocation at this point in time.   
    *  指向驱动断开连接函数,这个函数将在设备被断开活被释放的时候被调用                    
    * @disconnect: pointer to the driver's disconnect function.  This will be      
    *  called when the device is unplugged or unbound from the driver.     
    *  指向驱动释放函数,这个将在usb_serial 数据结构体被销毁的时候被调用        
    * @release: pointer to the driver's release function.  This will be called     
    *  when the usb_serial data structure is about to be destroyed.   
    *  指向控制这个设备的usb_driver 结构体,这个是必须动态添加这个驱动在 sysfs里面            
    * @usb_driver: pointer to the struct usb_driver that controls this             
    *  device.  This is necessary to allow dynamic ids to be added to              
    *  the driver from sysfs.                                                      
    *  这个结构体是定义了USB serial 驱动,他提供了所有的信息有关usb serial 核心代码需要。
    *  如果这个功能被定义,那么当对应的 tty 端口要使用对应功能的时候被调用                                                             
    * This structure is defines a USB Serial driver.  It provides all of           
    * the information that the USB serial core code needs.  If the function        
    * pointers are defined, then the USB serial core code will call them when      
    * the corresponding tty port functions are called.  If they are not            
    * called, the generic serial function will be used instead.                    
    *                                                                              
    * The driver.owner field should be set to the module owner of this driver.     
    * The driver.name field should be set to the name of this driver (remember     
    * it will show up in sysfs, so it needs to be short and to the point.          
    * Using the module name is a good idea.)                                       
    */                                                                             
    struct usb_serial_driver {                                                      
        const char *description;                                                    
        const struct usb_device_id *id_table;                                       
        char    num_ports;                                                          
                                                                                    
        struct list_head    driver_list;                                            
        struct device_driver    driver;                                             
        struct usb_driver   *usb_driver;                                            
        struct usb_dynids   dynids;                                                 
                                                                                    
        size_t          bulk_in_size;                                               
        size_t          bulk_out_size;                                              
                                                                                    
        int (*probe)(struct usb_serial *serial, const struct usb_device_id *id);    
        int (*attach)(struct usb_serial *serial);                                   
        int (*calc_num_ports) (struct usb_serial *serial);                          
                                                                                    
        void (*disconnect)(struct usb_serial *serial);                              
        void (*release)(struct usb_serial *serial);                                 
    
        int (*port_probe)(struct usb_serial_port *port);                            
        int (*port_remove)(struct usb_serial_port *port);                           
                                                                                    
        int (*suspend)(struct usb_serial *serial, pm_message_t message);            
        int (*resume)(struct usb_serial *serial);                                   
                                                                                    
        /* serial function calls */                                                 
        /* Called by console and by the tty layer */                                
        int  (*open)(struct tty_struct *tty, struct usb_serial_port *port);         
        void (*close)(struct usb_serial_port *port);                                
        int  (*write)(struct tty_struct *tty, struct usb_serial_port *port,         
                const unsigned char *buf, int count);                               
        /* Called only by the tty layer */                                          
        int  (*write_room)(struct tty_struct *tty);                                 
        int  (*ioctl)(struct tty_struct *tty,                                       
                  unsigned int cmd, unsigned long arg);                             
        void (*set_termios)(struct tty_struct *tty,                                 
                struct usb_serial_port *port, struct ktermios *old);                
        void (*break_ctl)(struct tty_struct *tty, int break_state);                 
        int  (*chars_in_buffer)(struct tty_struct *tty);                            
        void (*throttle)(struct tty_struct *tty);                                   
        void (*unthrottle)(struct tty_struct *tty);                                 
        int  (*tiocmget)(struct tty_struct *tty);                                   
        int  (*tiocmset)(struct tty_struct *tty,                                    
                 unsigned int set, unsigned int clear);                             
        int  (*get_icount)(struct tty_struct *tty,                                  
                struct serial_icounter_struct *icount);                             
        /* Called by the tty layer for port level work. There may or may not        
           be an attached tty at this point */                                      
        void (*dtr_rts)(struct usb_serial_port *port, int on);                      
        int  (*carrier_raised)(struct usb_serial_port *port);                       
        /* Called by the usb serial hooks to allow the user to rework the           
           termios state */                                                         
        void (*init_termios)(struct tty_struct *tty);                               
        /* USB events */                                                            
        void (*read_int_callback)(struct urb *urb);                                 
        void (*write_int_callback)(struct urb *urb);                                
        void (*read_bulk_callback)(struct urb *urb);                                
        void (*write_bulk_callback)(struct urb *urb);                               
        /* Called by the generic read bulk callback */                              
        void (*process_read_urb)(struct urb *urb);                                  
        /* Called by the generic write implementation */                            
        int (*prepare_write_buffer)(struct usb_serial_port *port,                   
                            void *dest, size_t size);                               
    };                                                        

* usb_serial 实现的各个函数描述

    include/linux/usb/serial.h
    #  利用usb_serial_driver 里面的某一个成员找到整个结构体
    #define to_usb_serial_driver(d) \                                               
        container_of(d, struct usb_serial_driver, driver)                           
    #  register usb 串口驱动注册                                                                                
    extern int  usb_serial_register(struct usb_serial_driver *driver);  
    #  deregister 解除注册            
    extern void usb_serial_deregister(struct usb_serial_driver *driver);            
    extern void usb_serial_port_softint(struct usb_serial_port *port);              
    #  usb serial 的probe 函数                                                                                
    extern int usb_serial_probe(struct usb_interface *iface,                        
                    const struct usb_device_id *id);   
    #  disconnect 断开连接函数                             
    extern void usb_serial_disconnect(struct usb_interface *iface);                 
    #  suspend 挂起,可以理解为睡眠状态                                                                                
    extern int usb_serial_suspend(struct usb_interface *intf, pm_message_t message);
    #  resume 重新启动
    extern int usb_serial_resume(struct usb_interface *intf);                       
                                                                                    
    extern int ezusb_writememory(struct usb_serial *serial, int address,            
                     unsigned char *data, int length, __u8 bRequest);               
    extern int ezusb_set_reset(struct usb_serial *serial, unsigned char reset_bit); 
    /* USB Serial console functions */                                              
    #ifdef CONFIG_USB_SERIAL_CONSOLE  
    #  usb serial 控制台初始化                                              
    extern void usb_serial_console_init(int debug, int minor); 
    #  退出                     
    extern void usb_serial_console_exit(void);     
    #  断开连接                                 
    extern void usb_serial_console_disconnect(struct usb_serial *serial);           
    #else                                                                           
    static inline void usb_serial_console_init(int debug, int minor) { }            
    static inline void usb_serial_console_exit(void) { }                            
    static inline void usb_serial_console_disconnect(struct usb_serial *serial) {}  
    #endif                                                                          
    /* Functions needed by other parts of the usbserial core */    
    #  usb serial 核心的其他部分功能               
    extern struct usb_serial *usb_serial_get_by_index(unsigned int minor);
    #            
    extern void usb_serial_put(struct usb_serial *serial);                          
    extern int usb_serial_generic_open(struct tty_struct *tty,                      
        struct usb_serial_port *port);                                              
    extern int usb_serial_generic_write(struct tty_struct *tty,                     
        struct usb_serial_port *port, const unsigned char *buf, int count);         
    extern void usb_serial_generic_close(struct usb_serial_port *port);             
    extern int usb_serial_generic_resume(struct usb_serial *serial);                
    extern int usb_serial_generic_write_room(struct tty_struct *tty);               
    extern int usb_serial_generic_chars_in_buffer(struct tty_struct *tty);          
    extern void usb_serial_generic_read_bulk_callback(struct urb *urb);             
    extern void usb_serial_generic_write_bulk_callback(struct urb *urb);            
    extern void usb_serial_generic_throttle(struct tty_struct *tty);                
    extern void usb_serial_generic_unthrottle(struct tty_struct *tty);              
    extern void usb_serial_generic_disconnect(struct usb_serial *serial);           
    extern void usb_serial_generic_release(struct usb_serial *serial);              
    extern int usb_serial_generic_register(int debug);                              
    extern void usb_serial_generic_deregister(void);                                
    extern int usb_serial_generic_submit_read_urb(struct usb_serial_port *port,     
                             gfp_t mem_flags);                                      
    extern void usb_serial_generic_process_read_urb(struct urb *urb);               
    extern int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port,
                            void *dest, size_t size);                               
    extern int usb_serial_handle_sysrq_char(struct usb_serial_port *port,           
                        unsigned int ch);                                           
    extern int usb_serial_handle_break(struct usb_serial_port *port);               
    extern void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port,      
                         struct tty_struct *tty,                                    
                         unsigned int status);                                      
                                                                                                                                                          
    extern int usb_serial_bus_register(struct usb_serial_driver *device);           
    extern void usb_serial_bus_deregister(struct usb_serial_driver *device);    
                                                                                    
    extern struct usb_serial_driver usb_serial_generic_device;                      
    extern struct bus_type usb_serial_bus_type;                                     
    extern struct tty_driver *usb_serial_tty_driver;                                                                                                               

* cp210x.c

    drivers/usb/serial/cp210x.c  (kernel 3.2.0)
    887 module_init(cp210x_init);   # 模块入口函数                                                      
    888 module_exit(cp210x_exit);   # 模块出口函数                                          
    889                                                                                 
    890 MODULE_DESCRIPTION(DRIVER_DESC); # 模块描述                                               
    891 MODULE_VERSION(DRIVER_VERSION);  # 模块版本                                                
    892 MODULE_LICENSE("GPL");           # 遵循 GPL 协议                                               
    893                                                                                 
    894 module_param(debug, bool, S_IRUGO | S_IWUSR);                                   
    895 MODULE_PARM_DESC(debug, "Enable verbose debugging messages");                   

    # ---> 入口
    860 static int __init cp210x_init(void)                                             
    861 {                                                                               
    862     int retval;                                                                 
    863               # usb 串口设备注册                                                                  
    864     retval = usb_serial_register(&cp210x_device);                               
    865     if (retval)                                                                 
    866         return retval; /* Failed to register */                                 
    867               # usb 串口驱动注册                                                                  
    868     retval = usb_register(&cp210x_driver);                                      
    869     if (retval) {                                                               
    870         /* Failed to register */                                                
    871         usb_serial_deregister(&cp210x_device);                                  
    872         return retval;                                                          
    873     }                                                                           
    874                                                                                 
    875     /* Success */                                                               
    876     printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"                     
    877            DRIVER_DESC "\n");                                                   
    878     return 0;                                                                   
    879 }     

    # ---> cp210x_device 结构体
    155 static struct usb_serial_driver cp210x_device = {                               
    156     .driver = {                                                                 
    157         .owner =    THIS_MODULE,                                                
    158         .name =     "cp210x",                                                   
    159     },                                                                          
    160     .usb_driver     = &cp210x_driver,                                           
    161     .id_table       = id_table,                                                 
    162     .num_ports      = 1,                                                        
    163     .bulk_in_size       = 256,                                                  
    164     .bulk_out_size      = 256,                                                  
    165     .open           = cp210x_open,      # 打开函数                                        
    166     .close          = cp210x_close,     # 关闭函数                               
    167     .break_ctl      = cp210x_break_ctl,                                         
    168     .set_termios        = cp210x_set_termios,                                   
    169     .tiocmget       = cp210x_tiocmget,                                          
    170     .tiocmset       = cp210x_tiocmset,                                          
    171     .attach         = cp210x_startup,   # 设备启动函数                                        
    172     .dtr_rts        = cp210x_dtr_rts                                            
    173 };  

    #  ---> cp210x_driver 结构体
    147 static struct usb_driver cp210x_driver = {                                      
    148     .name       = "cp210x",                                                     
    149     .probe      = usb_serial_probe,                                             
    150     .disconnect = usb_serial_disconnect,                                        
    151     .id_table   = id_table,                                                     
    152     .no_dynamic_id  =   1,                                                      
    153 };                                                                              
                                                                                                                                                    

* 具体的各个函数实现解析

  • open 函数
    //---> open 函数
    399 static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port)    
    400 {                                                                               
    401     int result;                                                                 
    402                                                                                 
    403     dbg("%s - port %d", __func__, port->number);                                
    404        /* 这里面是通过USB传输控制信号使能cp210x  */                                                                 
    405     if (cp210x_set_config_single(port, CP210X_IFC_ENABLE, UART_ENABLE)) {       
    406         dev_err(&port->dev, "%s - Unable to enable UART\n",                     
    407                 __func__);                                                      
    408         return -EPROTO;                                                         
    409     }                                                                           
    410                                                                                 
    411     result = usb_serial_generic_open(tty, port);                                
    412     if (result)                                                                 
    413         return result;                                                          
    414                                                                                 
    415     /* Configure the termios structure */                                       
    416     cp210x_get_termios(tty, port);  /*获取termios 信息,包括波特率数据位等信息*/                                          
    417     return 0;                                                                   
    418 }   

    // ---> cp210x_get_termios 函数
    438 static void cp210x_get_termios(struct tty_struct *tty,                          
    439     struct usb_serial_port *port)                                               
    440 {                                                                               
    441     unsigned int baud;                                                          
    442                                                                                 
    443     if (tty) {     // 获取相关终端的信息                                                             
    444         cp210x_get_termios_port(tty->driver_data,                               
    445             &tty->termios->c_cflag, &baud);                                     
    446         tty_encode_baud_rate(tty, baud, baud);                                  
    447     }                                                                           
    448                                                                                 
    449     else {                                                                      
    450         unsigned int cflag;                                                     
    451         cflag = 0;                                                              
    452         cp210x_get_termios_port(port, &cflag, &baud);                           
    453     }                                                                           
    454 }                                                                               

    // ---> cp210x_get_termios_port 函数
    460 static void cp210x_get_termios_port(struct usb_serial_port *port,               
    461     unsigned int *cflagp, unsigned int *baudp)                                  
    462 {                                                                               
    463     unsigned int cflag, modem_ctl[4];                                           
    464     unsigned int baud;                                                          
    465     unsigned int bits;                                                          
    466                                                                                 
    467     dbg("%s - port %d", __func__, port->number);                                
    468     //  核心是通过这个函数进行获取相关的配置信息,读取到baud rate                                                                         
    469     cp210x_get_config(port, CP210X_GET_BAUDDIV, &baud, 2);                      
    470     /* Convert to baudrate */                                                   
    471     if (baud)    // 波特率的计算                                                            
    472         baud = cp210x_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud);   
            // ... ...
    475     *baudp = baud;                                                              
    476                                                                                 
    477     cflag = *cflagp;                                                            
    478                                              读取数据位                               
    479     cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2);                   
            // ... ...          
    583     *cflagp = cflag;                                                            
    584 }                                                                               
    585                                                                                 
         
    // --->  cp210x_get_config  函数
    248 /*                                                                              
    249  * cp210x_get_config    从cp210x 配置寄存器中读取相关信息                                                        
    250  * Reads from the CP210x configuration registers                                 
    251  * 'size' is specified in bytes.                                                
    252  * 'data' is a pointer to a pre-allocated array of integers large               
    253  * enough to hold 'size' bytes (with 4 bytes to each integer)                   
    254  */                 data 即是读到的数据                                                         
    255 static int cp210x_get_config(struct usb_serial_port *port, u8 request,          
    256         unsigned int *data, int size)                                           
    257 {                                                                               
    258     struct usb_serial *serial = port->serial;                                   
    259     __le32 *buf;                                                                
    260     int result, i, length;                                                      
    261                                                                                 
    262     /* Number of integers required to contain the array */                      
    263     length = (((size - 1) | 3) + 1)/4;                                          
    264     // 申请一段空间                                                                          
    265     buf = kcalloc(length, sizeof(__le32), GFP_KERNEL);                          
    266     if (!buf) {                                                                 
    267         dev_err(&port->dev, "%s - out of memory.\n", __func__);                 
    268         return -ENOMEM;                                                         
    269     }                                                                           
    270                                                                                 
    271     /* Issue the request, attempting to read 'size' bytes */
                    /*   通过USB的控制传输读取相关数据 ,读到buf里面 */                  
    272     result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),      
    273                 request, REQTYPE_DEVICE_TO_HOST, 0x0000,                        
    274                 0, buf, size, 300);                                             
    275                                                                                 
    276     /* Convert data into an array of integers */                                
    277     for (i = 0; i < length; i++)                                                
    278         data[i] = le32_to_cpu(buf[i]);                                          
    279             // 转换成data                                                                    
    280     kfree(buf);                                                                 
    281                                                                                 
    282     if (result != size) {                                                       
    283         dbg("%s - Unable to send config request, "                              
    284                 "request=0x%x size=%d result=%d\n",                             
    285                 __func__, request, size, result);                               
    286         return -EPROTO;                                                         
    287     }                                                                           
    288                                                                                 
    289     return 0;                                                                   
    290 }                                                                               
                                                  
  • cp210x_break_ctl 函数解析
    // ---> cp210x_break_ctl 函数
    838 static void cp210x_break_ctl (struct tty_struct *tty, int break_state)          
    839 {                                                                               
    840     struct usb_serial_port *port = tty->driver_data;                            
    841     unsigned int state;                                                         
    842                                                                                 
    843     dbg("%s - port %d", __func__, port->number);                                
    844     if (break_state == 0)                                                       
    845         state = BREAK_OFF;                                                      
    846     else                                                                        
    847         state = BREAK_ON;                                                       
    848     dbg("%s - turning break %s", __func__,                                      
    849             state == BREAK_OFF ? "off" : "on");                                 
    850     cp210x_set_config(port, CP210X_SET_BREAK, &state, 2);                       
    851 }     // 设置 break 的状态,如果break_state为0,state == BREAK_OFF
    
    // --->   // request表示要设置什么,data 表示设置的数据,size 为大小                                                     
    298 static int cp210x_set_config(struct usb_serial_port *port, u8 request,          
    299         unsigned int *data, int size)                                           
    300 {                                                                               
    301     struct usb_serial *serial = port->serial;                                   
    302     __le32 *buf;                                                                
    303     int result, i, length;                                                      
    304                                                                                 
    305     if (request == CP210X_SET_BAUDDIV)                                          
    306     {                                                                           
    307         printk("---------------baud  rate : %d\n", *data);                      
    308     }                                                                           
    309     /* Number of integers required to contain the array */                      
    310     length = (((size - 1) | 3) + 1)/4;                                          
    311     // 申请一段大小的空间                                                                            
    312     buf = kmalloc(length * sizeof(__le32), GFP_KERNEL);                         
    313     if (!buf) {                                                                 
    314         dev_err(&port->dev, "%s - out of memory.\n",                            
    315                 __func__);                                                      
    316         return -ENOMEM;                                                         
    317     }                                                                           
    318                                                                                 
    319     /* Array of integers into bytes */                                          
    320     for (i = 0; i < length; i++)                                                
    321         buf[i] = cpu_to_le32(data[i]);                                          
    322     // 判断数据大小是否大于2                                                                           
    323     if (size > 2) {                                                             
    324         result = usb_control_msg(serial->dev,                                   
    325                 usb_sndctrlpipe(serial->dev, 0),                                
    326                 request, REQTYPE_HOST_TO_DEVICE, 0x0000,                        
    327                 0, buf, size, 300);                                             
    328     } else {                                                                    
    329         result = usb_control_msg(serial->dev,                                   
    330                 usb_sndctrlpipe(serial->dev, 0),                                
    331                 request, REQTYPE_HOST_TO_DEVICE, data[0],                       
    332                 0, NULL, 0, 300);                                               
    333     }                                                                           
    334     // 释放                                                                           
    335     kfree(buf);                                                                 
    336                                                                                 
    337     if ((size > 2 && result != size) || result < 0) {                           
    338         dbg("%s - Unable to send request, "                                     
    339                 "request=0x%x size=%d result=%d\n",                             
    340                 __func__, request, size, result);                               
    341         return -EPROTO;                                                         
    342     }                                                                           
    343                                                                                 
    344     return 0;                                                                   
    345 }                                                                               
  • 配置函数 cp210x_set_termios
    639 static void cp210x_set_termios(struct tty_struct *tty,                          
    640         struct usb_serial_port *port, struct ktermios *old_termios)             
    641 {                                                                               
    642     unsigned int cflag, old_cflag;                                              
    643     unsigned int baud = 0, bits;                                                
    644     unsigned int modem_ctl[4];                                                  
    645                                                                                 
    646     dbg("%s - port %d", __func__, port->number);                                
    647                                                                                 
    648     if (!tty)                                                                   
    649         return;                                                                 
    650                                                                                 
    651     tty->termios->c_cflag &= ~CMSPAR;                                           
    652     cflag = tty->termios->c_cflag;                                              
    653     old_cflag = old_termios->c_cflag;                                           
    654                                                                                 
    655     // 改变其波特率,这个是我根据kernel4.4.12的函数该过来的                    
    656     cp210x_change_speed(tty, port, old_termios);                                
    657     // 如果数据位需要升级                                                                         
    658     /* If the number of data bits is to be updated */                           
    659     if ((cflag & CSIZE) != (old_cflag & CSIZE)) {       
                // 先读旧的数据位                        
    660         cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2);                 
    661         bits &= ~BITS_DATA_MASK;  
    662         switch (cflag & CSIZE) {                                                
    663         case CS5:                                                               
    664             bits |= BITS_DATA_5;                                                
    665             dbg("%s - data bits = 5", __func__);                                
    666             break;                                                              
                // ... ...
    689         }              // 设置数据位                                                         
    690         if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2))             
    691             dbg("Number of data bits requested "                                
    692                     "not supported by device\n");                               
    693     }
            // ... ...  8n1 115200  各种配置
    750                                                                                 
    751 }                                                                               
  • cp210x_tiocmget 函数
    797 static int cp210x_tiocmget (struct tty_struct *tty)                             
    798 {                                                                               
    799     struct usb_serial_port *port = tty->driver_data;                            
    800     unsigned int control;                                                       
    801     int result;                                                                 
    802                                                                                 
    803     dbg("%s - port %d", __func__, port->number);                                
    804                                                                                 
    805     cp210x_get_config(port, CP210X_GET_MDMSTS, &control, 1);                    
    806                                                                                 
    807     result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0)                          
    808         |((control & CONTROL_RTS) ? TIOCM_RTS : 0)                              
    809         |((control & CONTROL_CTS) ? TIOCM_CTS : 0)                              
    810         |((control & CONTROL_DSR) ? TIOCM_DSR : 0)                              
    811         |((control & CONTROL_RING)? TIOCM_RI  : 0)                              
    812         |((control & CONTROL_DCD) ? TIOCM_CD  : 0);                             
    813     将所有的状态 | 在一起返回结果                                                                             
    814     dbg("%s - control = 0x%.2x", __func__, control);                            
    815                                                                                 
    816     return result;                                                              
    817 }                                                                               
  • cp210x_tiocmset 函数,设置相关的配置
    753 static int cp210x_tiocmset (struct tty_struct *tty,                             
    754         unsigned int set, unsigned int clear)                                   
    755 {                                                                               
    756     struct usb_serial_port *port = tty->driver_data;                            
    757     return cp210x_tiocmset_port(port, set, clear);                              
    758 }                                                                               
    759  

    // ---> cp210x_tiocmset_port
    760 static int cp210x_tiocmset_port(struct usb_serial_port *port,                   
    761         unsigned int set, unsigned int clear)                                   
    762 {                                                                               
    763     unsigned int control = 0;                                                   
    764                                                                                 
    765     dbg("%s - port %d", __func__, port->number);                                
    766                                                                                 
    767     if (set & TIOCM_RTS) {                                                      
    768         control |= CONTROL_RTS;                                                 
    769         control |= CONTROL_WRITE_RTS;                                           
    770     }                                                                           
    771     if (set & TIOCM_DTR) {                                                      
    772         control |= CONTROL_DTR;                                                 
    773         control |= CONTROL_WRITE_DTR;                                           
    774     }                                                                           
    775     if (clear & TIOCM_RTS) {                                                    
    776         control &= ~CONTROL_RTS;                                                
    777         control |= CONTROL_WRITE_RTS;                                           
    778     }                                                                           
    779     if (clear & TIOCM_DTR) {                                                    
    780         control &= ~CONTROL_DTR;                                                
    781         control |= CONTROL_WRITE_DTR;                                           
    782     }                                                                           
    783                                                                                 
    784     dbg("%s - control = 0x%.4x", __func__, control);                            
    785     //  配置函数                                                                            
    786     return cp210x_set_config(port, CP210X_SET_MHS, &control, 2);                
    787 }                                                                                                                                                         
  • cp210x_dtr_rts 函数
    789 static void cp210x_dtr_rts(struct usb_serial_port *p, int on)                   
    790 {                                                                               
    791     if (on)                                                                     
    792         cp210x_tiocmset_port(p, TIOCM_DTR|TIOCM_RTS, 0);                        
    793     else                                                                        
    794         cp210x_tiocmset_port(p, 0, TIOCM_DTR|TIOCM_RTS);                        
    795 }                                                                               

你可能感兴趣的:(开发工具)