Quectel EC200A-CN移植

Quectel EC200A-CN移植

  • 一:usb转串口
  • 二:usb网卡驱动
  • 三:源码修改
  • 四:测试

一:usb转串口

usb-serial-option,USB转串口驱动,生产/dev/ttyUSB0-2,分别是DM,AT,PPP
需要使能内核选项如下:

CONFIG_USB_SERIAL=y
CONFIG_USB_SERIAL_WWAN=y
CONFIG_USB_SERIAL_OPTION=y

Quectel EC200A-CN移植_第1张图片
Quectel EC200A-CN移植_第2张图片

二:usb网卡驱动

USB网卡驱动,模块可通过AT配置成RNDIS或者ecm,默认是ecm。
需要使能内核选项

USB_USBNET=y
USB_NET_CDCETHER=y        #用ECM  使能此项
USB_NET_RNDIS_HOST=y      #用RNDIS 使能此项

Quectel EC200A-CN移植_第3张图片
Quectel EC200A-CN移植_第4张图片

三:源码修改

  1. 增加usb vid和pid
    增加vid和pid,设备连接,使用lsusb命令查看设备的vid和pid,如下图所示:
    Quectel EC200A-CN移植_第5张图片
vid:3763
pid:3c93

文件修改:linux-3.10/drivers/usb/serial/option.c

static const struct usb_device_id option_ids[] = {
#if 1 //Added by Quectel
        { USB_DEVICE(0x3763, 0x3c93) }, /* Quectel EC200A-CN 内置GPS */
        { USB_DEVICE(0x3c93, 0xffff) }, /* Quectel EC200A-CN 外置GPS*/
#endif

文件修改:linux-3.10/drivers/usb/serial/option.c

1790 #if 1 //Added by Quectel
1791 static void cfmakeraw(struct ktermios *t)
1792 {
1793         t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
1794         t->c_oflag &= ~OPOST;
1795         t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
1796         t->c_cflag &= ~(CSIZE|PARENB);
1797         t->c_cflag |= CS8;
1798         t->c_cc[VMIN] = 1;
1799         t->c_cc[VTIME] = 0;
1800 }
1801 
1802 static void option_init_termios(struct tty_struct *tty)
1803 {
1804         cfmakeraw(&tty->termios);
1805 }
1806 #endif

文件修改:linux-3.10/drivers/usb/serial/option.c:option_1port_device

1813 static struct usb_serial_driver option_1port_device = {
1814         .driver = {
1815                 .owner =        THIS_MODULE,
1816                 .name =         "option1",
1817         },
1818         .description       = "GSM modem (1-port)",
1819         .id_table          = option_ids,
1820         .num_ports         = 1,
1821         .probe             = option_probe,
1822         .open              = usb_wwan_open,
1823         .close             = usb_wwan_close,
1824         .dtr_rts           = usb_wwan_dtr_rts,
1825         .write             = usb_wwan_write,
1826         .write_room        = usb_wwan_write_room,
1827         .chars_in_buffer   = usb_wwan_chars_in_buffer,
1828         .set_termios       = usb_wwan_set_termios,
1829         .tiocmget          = usb_wwan_tiocmget,
1830         .tiocmset          = usb_wwan_tiocmset,
1831         .ioctl             = usb_wwan_ioctl,
1832         .attach            = option_attach,
1833         .release           = option_release,
1834         .port_probe        = usb_wwan_port_probe,
1835         .port_remove       = usb_wwan_port_remove,
1836         .read_int_callback = option_instat_callback,
1837 #ifdef CONFIG_PM
1838         .suspend           = usb_wwan_suspend,
1839         .resume            = usb_wwan_resume,
1840 #if 1 //Added by Quectel
1841         .reset_resume = usb_wwan_resume,
1842 #endif
1843 #endif
1844 };

文件修改:linux-3.10/drivers/usb/serial/option.c:option_probe

if (serial->dev->descriptor.idVendor == cpu_to_le16(0x3c93))
{
        __u16 idProduct = le16_to_cpu(serial->dev->descriptor.idProduct);
        struct usb_interface_descriptor *intf = &serial->interface->cur_altsetting->desc;

        if (intf->bInterfaceClass != 0xFF || intf->bInterfaceSubClass == 0x42)
        {
                //ECM, RNDIS, NCM, MBIM, ACM, UAC, ADB
                return -ENODEV;
        }

        if ((idProduct&0xF000) == 0x0000)
        {
                //MDM interface 4 is QMI
                if (intf->bInterfaceNumber == 4 &&
                    intf->bNumEndpoints == 3 &&
                    intf->bInterfaceSubClass == 0xFF &&
                    intf->bInterfaceProtocol == 0xFF)
                        return -ENODEV;
        }
}
if (serial->dev->descriptor.idVendor == cpu_to_le16(0x3763))
{
        __u16 idProduct = le16_to_cpu(serial->dev->descriptor.idProduct);
        struct usb_interface_descriptor *intf = &serial->interface->cur_altsetting->desc;

        if (intf->bInterfaceClass != 0xFF || intf->bInterfaceSubClass == 0x42)
        {
                //ECM, RNDIS, NCM, MBIM, ACM, UAC, ADB
                return -ENODEV;
        }

        if ((idProduct&0xF000) == 0x0000)
        {
                //MDM interface 4 is QMI
                if (intf->bInterfaceNumber == 4 &&
                    intf->bNumEndpoints == 3 &&
                    intf->bInterfaceSubClass == 0xFF &&
                    intf->bInterfaceProtocol == 0xFF)
                        return -ENODEV;
        }
}
  1. linux-3.10/drivers/usb/serial/usb_wwan.c:usb_wwan_setup_urb
    usb_wwan_setup_urb函数中添加如下内容
 //Added by Quectel for Zero Packet
 if (dir == USB_DIR_OUT) {
         struct usb_device_descriptor *desc = &serial->dev->descriptor;
 if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9090))
         urb->transfer_flags |= URB_ZERO_PACKET;
 if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9003))
         urb->transfer_flags |= URB_ZERO_PACKET;
 if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9215))
         urb->transfer_flags |= URB_ZERO_PACKET;
 if (desc->idVendor == cpu_to_le16(0x2C7C))
         urb->transfer_flags |= URB_ZERO_PACKET;
 if (desc->idVendor == cpu_to_le16(0x3c93))
         urb->transfer_flags |= URB_ZERO_PACKET;
 if (desc->idVendor == cpu_to_le16(0x3763))
         urb->transfer_flags |= URB_ZERO_PACKET;
 }

四:测试

  1. 查看usb网卡是否生成
ifconfig -a

Quectel EC200A-CN移植_第6张图片

  1. 测试方法一
busybox microcom /dev/ttyUSB2

Quectel EC200A-CN移植_第7张图片
3. 测试方法二

cat /dev/ttyUSB2 &
echo AT > /dev/ttyUSB2

你可能感兴趣的:(#,Linux,Driver,linux,驱动开发)