11378df79SJean-Christophe PLAGNIOL-VILLARD /*
21378df79SJean-Christophe PLAGNIOL-VILLARD * (C) Copyright 2003
31378df79SJean-Christophe PLAGNIOL-VILLARD * Gerry Hamel, geh@ti.com, Texas Instruments
41378df79SJean-Christophe PLAGNIOL-VILLARD *
51378df79SJean-Christophe PLAGNIOL-VILLARD * (C) Copyright 2006
61378df79SJean-Christophe PLAGNIOL-VILLARD * Bryan O'Donoghue, bodonoghue@codehermit.ie
71378df79SJean-Christophe PLAGNIOL-VILLARD *
81a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+
91378df79SJean-Christophe PLAGNIOL-VILLARD */
101378df79SJean-Christophe PLAGNIOL-VILLARD
111378df79SJean-Christophe PLAGNIOL-VILLARD #include <common.h>
12dedacc18SJean-Christophe PLAGNIOL-VILLARD #include <config.h>
131378df79SJean-Christophe PLAGNIOL-VILLARD #include <circbuf.h>
1452cb4d4fSJean-Christophe PLAGNIOL-VILLARD #include <stdio_dev.h>
15b2fb47f1STom Rini #include <asm/unaligned.h>
161378df79SJean-Christophe PLAGNIOL-VILLARD #include "usbtty.h"
171378df79SJean-Christophe PLAGNIOL-VILLARD #include "usb_cdc_acm.h"
181378df79SJean-Christophe PLAGNIOL-VILLARD #include "usbdescriptors.h"
191378df79SJean-Christophe PLAGNIOL-VILLARD
20dedacc18SJean-Christophe PLAGNIOL-VILLARD #ifdef DEBUG
211378df79SJean-Christophe PLAGNIOL-VILLARD #define TTYDBG(fmt,args...)\
221378df79SJean-Christophe PLAGNIOL-VILLARD serial_printf("[%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args)
231378df79SJean-Christophe PLAGNIOL-VILLARD #else
241378df79SJean-Christophe PLAGNIOL-VILLARD #define TTYDBG(fmt,args...) do{}while(0)
251378df79SJean-Christophe PLAGNIOL-VILLARD #endif
261378df79SJean-Christophe PLAGNIOL-VILLARD
271378df79SJean-Christophe PLAGNIOL-VILLARD #if 1
281378df79SJean-Christophe PLAGNIOL-VILLARD #define TTYERR(fmt,args...)\
291378df79SJean-Christophe PLAGNIOL-VILLARD serial_printf("ERROR![%s] %s %d: "fmt, __FILE__,__FUNCTION__,\
301378df79SJean-Christophe PLAGNIOL-VILLARD __LINE__,##args)
311378df79SJean-Christophe PLAGNIOL-VILLARD #else
321378df79SJean-Christophe PLAGNIOL-VILLARD #define TTYERR(fmt,args...) do{}while(0)
331378df79SJean-Christophe PLAGNIOL-VILLARD #endif
341378df79SJean-Christophe PLAGNIOL-VILLARD
351378df79SJean-Christophe PLAGNIOL-VILLARD /*
361378df79SJean-Christophe PLAGNIOL-VILLARD * Defines
371378df79SJean-Christophe PLAGNIOL-VILLARD */
381378df79SJean-Christophe PLAGNIOL-VILLARD #define NUM_CONFIGS 1
391378df79SJean-Christophe PLAGNIOL-VILLARD #define MAX_INTERFACES 2
401378df79SJean-Christophe PLAGNIOL-VILLARD #define NUM_ENDPOINTS 3
411378df79SJean-Christophe PLAGNIOL-VILLARD #define ACM_TX_ENDPOINT 3
421378df79SJean-Christophe PLAGNIOL-VILLARD #define ACM_RX_ENDPOINT 2
431378df79SJean-Christophe PLAGNIOL-VILLARD #define GSERIAL_TX_ENDPOINT 2
441378df79SJean-Christophe PLAGNIOL-VILLARD #define GSERIAL_RX_ENDPOINT 1
451378df79SJean-Christophe PLAGNIOL-VILLARD #define NUM_ACM_INTERFACES 2
461378df79SJean-Christophe PLAGNIOL-VILLARD #define NUM_GSERIAL_INTERFACES 1
471378df79SJean-Christophe PLAGNIOL-VILLARD #define CONFIG_USBD_DATA_INTERFACE_STR "Bulk Data Interface"
481378df79SJean-Christophe PLAGNIOL-VILLARD #define CONFIG_USBD_CTRL_INTERFACE_STR "Control Interface"
491378df79SJean-Christophe PLAGNIOL-VILLARD
501378df79SJean-Christophe PLAGNIOL-VILLARD /*
511378df79SJean-Christophe PLAGNIOL-VILLARD * Buffers to hold input and output data
521378df79SJean-Christophe PLAGNIOL-VILLARD */
53b2caefbbSShiraz Hashim #define USBTTY_BUFFER_SIZE 2048
541378df79SJean-Christophe PLAGNIOL-VILLARD static circbuf_t usbtty_input;
551378df79SJean-Christophe PLAGNIOL-VILLARD static circbuf_t usbtty_output;
561378df79SJean-Christophe PLAGNIOL-VILLARD
571378df79SJean-Christophe PLAGNIOL-VILLARD
581378df79SJean-Christophe PLAGNIOL-VILLARD /*
591378df79SJean-Christophe PLAGNIOL-VILLARD * Instance variables
601378df79SJean-Christophe PLAGNIOL-VILLARD */
6152cb4d4fSJean-Christophe PLAGNIOL-VILLARD static struct stdio_dev usbttydev;
621378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_device_instance device_instance[1];
631378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_bus_instance bus_instance[1];
641378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_configuration_instance config_instance[NUM_CONFIGS];
651378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_interface_instance interface_instance[MAX_INTERFACES];
661378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_alternate_instance alternate_instance[MAX_INTERFACES];
671378df79SJean-Christophe PLAGNIOL-VILLARD /* one extra for control endpoint */
681378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_endpoint_instance endpoint_instance[NUM_ENDPOINTS+1];
691378df79SJean-Christophe PLAGNIOL-VILLARD
701378df79SJean-Christophe PLAGNIOL-VILLARD /*
711378df79SJean-Christophe PLAGNIOL-VILLARD * Global flag
721378df79SJean-Christophe PLAGNIOL-VILLARD */
731378df79SJean-Christophe PLAGNIOL-VILLARD int usbtty_configured_flag = 0;
741378df79SJean-Christophe PLAGNIOL-VILLARD
751378df79SJean-Christophe PLAGNIOL-VILLARD /*
761378df79SJean-Christophe PLAGNIOL-VILLARD * Serial number
771378df79SJean-Christophe PLAGNIOL-VILLARD */
781378df79SJean-Christophe PLAGNIOL-VILLARD static char serial_number[16];
791378df79SJean-Christophe PLAGNIOL-VILLARD
801378df79SJean-Christophe PLAGNIOL-VILLARD
811378df79SJean-Christophe PLAGNIOL-VILLARD /*
821378df79SJean-Christophe PLAGNIOL-VILLARD * Descriptors, Strings, Local variables.
831378df79SJean-Christophe PLAGNIOL-VILLARD */
841378df79SJean-Christophe PLAGNIOL-VILLARD
852731b9a8SJean-Christophe PLAGNIOL-VILLARD /* defined and used by gadget/ep0.c */
861378df79SJean-Christophe PLAGNIOL-VILLARD extern struct usb_string_descriptor **usb_strings;
871378df79SJean-Christophe PLAGNIOL-VILLARD
881378df79SJean-Christophe PLAGNIOL-VILLARD /* Indicies, References */
891378df79SJean-Christophe PLAGNIOL-VILLARD static unsigned short rx_endpoint = 0;
901378df79SJean-Christophe PLAGNIOL-VILLARD static unsigned short tx_endpoint = 0;
911378df79SJean-Christophe PLAGNIOL-VILLARD static unsigned short interface_count = 0;
921378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_string_descriptor *usbtty_string_table[STR_COUNT];
931378df79SJean-Christophe PLAGNIOL-VILLARD
941378df79SJean-Christophe PLAGNIOL-VILLARD /* USB Descriptor Strings */
951378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrLang[4] = {4,USB_DT_STRING,0x9,0x4};
961378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrManufacturer[2 + 2*(sizeof(CONFIG_USBD_MANUFACTURER)-1)];
971378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrProduct[2 + 2*(sizeof(CONFIG_USBD_PRODUCT_NAME)-1)];
981378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrSerial[2 + 2*(sizeof(serial_number) - 1)];
991378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrConfiguration[2 + 2*(sizeof(CONFIG_USBD_CONFIGURATION_STR)-1)];
1001378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrDataInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)];
1011378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrCtrlInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)];
1021378df79SJean-Christophe PLAGNIOL-VILLARD
1031378df79SJean-Christophe PLAGNIOL-VILLARD /* Standard USB Data Structures */
1041378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_interface_descriptor interface_descriptors[MAX_INTERFACES];
1051378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_endpoint_descriptor *ep_descriptor_ptrs[NUM_ENDPOINTS];
1061378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_configuration_descriptor *configuration_descriptor = 0;
1071378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_device_descriptor device_descriptor = {
1081378df79SJean-Christophe PLAGNIOL-VILLARD .bLength = sizeof(struct usb_device_descriptor),
1091378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_DEVICE,
1101378df79SJean-Christophe PLAGNIOL-VILLARD .bcdUSB = cpu_to_le16(USB_BCD_VERSION),
1111378df79SJean-Christophe PLAGNIOL-VILLARD .bDeviceSubClass = 0x00,
1121378df79SJean-Christophe PLAGNIOL-VILLARD .bDeviceProtocol = 0x00,
1131378df79SJean-Christophe PLAGNIOL-VILLARD .bMaxPacketSize0 = EP0_MAX_PACKET_SIZE,
1141378df79SJean-Christophe PLAGNIOL-VILLARD .idVendor = cpu_to_le16(CONFIG_USBD_VENDORID),
1151378df79SJean-Christophe PLAGNIOL-VILLARD .bcdDevice = cpu_to_le16(USBTTY_BCD_DEVICE),
1161378df79SJean-Christophe PLAGNIOL-VILLARD .iManufacturer = STR_MANUFACTURER,
1171378df79SJean-Christophe PLAGNIOL-VILLARD .iProduct = STR_PRODUCT,
1181378df79SJean-Christophe PLAGNIOL-VILLARD .iSerialNumber = STR_SERIAL,
1191378df79SJean-Christophe PLAGNIOL-VILLARD .bNumConfigurations = NUM_CONFIGS
1201378df79SJean-Christophe PLAGNIOL-VILLARD };
1211378df79SJean-Christophe PLAGNIOL-VILLARD
1221378df79SJean-Christophe PLAGNIOL-VILLARD
123f9da0f89SVipin KUMAR #if defined(CONFIG_USBD_HS)
124f9da0f89SVipin KUMAR static struct usb_qualifier_descriptor qualifier_descriptor = {
125f9da0f89SVipin KUMAR .bLength = sizeof(struct usb_qualifier_descriptor),
126f9da0f89SVipin KUMAR .bDescriptorType = USB_DT_QUAL,
127f9da0f89SVipin KUMAR .bcdUSB = cpu_to_le16(USB_BCD_VERSION),
128f9da0f89SVipin KUMAR .bDeviceClass = COMMUNICATIONS_DEVICE_CLASS,
129f9da0f89SVipin KUMAR .bDeviceSubClass = 0x00,
130f9da0f89SVipin KUMAR .bDeviceProtocol = 0x00,
131f9da0f89SVipin KUMAR .bMaxPacketSize0 = EP0_MAX_PACKET_SIZE,
132f9da0f89SVipin KUMAR .bNumConfigurations = NUM_CONFIGS
133f9da0f89SVipin KUMAR };
134f9da0f89SVipin KUMAR #endif
135f9da0f89SVipin KUMAR
1361378df79SJean-Christophe PLAGNIOL-VILLARD /*
1371378df79SJean-Christophe PLAGNIOL-VILLARD * Static CDC ACM specific descriptors
1381378df79SJean-Christophe PLAGNIOL-VILLARD */
1391378df79SJean-Christophe PLAGNIOL-VILLARD
1401378df79SJean-Christophe PLAGNIOL-VILLARD struct acm_config_desc {
1411378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_configuration_descriptor configuration_desc;
1421378df79SJean-Christophe PLAGNIOL-VILLARD
1431378df79SJean-Christophe PLAGNIOL-VILLARD /* Master Interface */
1441378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_interface_descriptor interface_desc;
1451378df79SJean-Christophe PLAGNIOL-VILLARD
1461378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_class_header_function_descriptor usb_class_header;
1471378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_class_call_management_descriptor usb_class_call_mgt;
1481378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_class_abstract_control_descriptor usb_class_acm;
1491378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_class_union_function_descriptor usb_class_union;
1501378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_descriptor notification_endpoint;
1511378df79SJean-Christophe PLAGNIOL-VILLARD
1521378df79SJean-Christophe PLAGNIOL-VILLARD /* Slave Interface */
1531378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_interface_descriptor data_class_interface;
154f3c0de63SAtin Malaviya struct usb_endpoint_descriptor data_endpoints[NUM_ENDPOINTS-1];
1551378df79SJean-Christophe PLAGNIOL-VILLARD } __attribute__((packed));
1561378df79SJean-Christophe PLAGNIOL-VILLARD
1571378df79SJean-Christophe PLAGNIOL-VILLARD static struct acm_config_desc acm_configuration_descriptors[NUM_CONFIGS] = {
1581378df79SJean-Christophe PLAGNIOL-VILLARD {
1591378df79SJean-Christophe PLAGNIOL-VILLARD .configuration_desc ={
1601378df79SJean-Christophe PLAGNIOL-VILLARD .bLength =
1611378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_configuration_descriptor),
1621378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_CONFIG,
1631378df79SJean-Christophe PLAGNIOL-VILLARD .wTotalLength =
1641378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(sizeof(struct acm_config_desc)),
1651378df79SJean-Christophe PLAGNIOL-VILLARD .bNumInterfaces = NUM_ACM_INTERFACES,
1661378df79SJean-Christophe PLAGNIOL-VILLARD .bConfigurationValue = 1,
1671378df79SJean-Christophe PLAGNIOL-VILLARD .iConfiguration = STR_CONFIG,
1681378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes =
1691378df79SJean-Christophe PLAGNIOL-VILLARD BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,
1701378df79SJean-Christophe PLAGNIOL-VILLARD .bMaxPower = USBTTY_MAXPOWER
1711378df79SJean-Christophe PLAGNIOL-VILLARD },
1721378df79SJean-Christophe PLAGNIOL-VILLARD /* Interface 1 */
1731378df79SJean-Christophe PLAGNIOL-VILLARD .interface_desc = {
1741378df79SJean-Christophe PLAGNIOL-VILLARD .bLength = sizeof(struct usb_interface_descriptor),
1751378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_INTERFACE,
1761378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceNumber = 0,
1771378df79SJean-Christophe PLAGNIOL-VILLARD .bAlternateSetting = 0,
1781378df79SJean-Christophe PLAGNIOL-VILLARD .bNumEndpoints = 0x01,
1791378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceClass =
1801378df79SJean-Christophe PLAGNIOL-VILLARD COMMUNICATIONS_INTERFACE_CLASS_CONTROL,
1811378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceSubClass = COMMUNICATIONS_ACM_SUBCLASS,
1821378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceProtocol = COMMUNICATIONS_V25TER_PROTOCOL,
1831378df79SJean-Christophe PLAGNIOL-VILLARD .iInterface = STR_CTRL_INTERFACE,
1841378df79SJean-Christophe PLAGNIOL-VILLARD },
1851378df79SJean-Christophe PLAGNIOL-VILLARD .usb_class_header = {
1861378df79SJean-Christophe PLAGNIOL-VILLARD .bFunctionLength =
1871378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_class_header_function_descriptor),
1881378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = CS_INTERFACE,
1891378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorSubtype = USB_ST_HEADER,
1901378df79SJean-Christophe PLAGNIOL-VILLARD .bcdCDC = cpu_to_le16(110),
1911378df79SJean-Christophe PLAGNIOL-VILLARD },
1921378df79SJean-Christophe PLAGNIOL-VILLARD .usb_class_call_mgt = {
1931378df79SJean-Christophe PLAGNIOL-VILLARD .bFunctionLength =
1941378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_class_call_management_descriptor),
1951378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = CS_INTERFACE,
1961378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorSubtype = USB_ST_CMF,
1971378df79SJean-Christophe PLAGNIOL-VILLARD .bmCapabilities = 0x00,
1981378df79SJean-Christophe PLAGNIOL-VILLARD .bDataInterface = 0x01,
1991378df79SJean-Christophe PLAGNIOL-VILLARD },
2001378df79SJean-Christophe PLAGNIOL-VILLARD .usb_class_acm = {
2011378df79SJean-Christophe PLAGNIOL-VILLARD .bFunctionLength =
2021378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_class_abstract_control_descriptor),
2031378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = CS_INTERFACE,
2041378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorSubtype = USB_ST_ACMF,
2051378df79SJean-Christophe PLAGNIOL-VILLARD .bmCapabilities = 0x00,
2061378df79SJean-Christophe PLAGNIOL-VILLARD },
2071378df79SJean-Christophe PLAGNIOL-VILLARD .usb_class_union = {
2081378df79SJean-Christophe PLAGNIOL-VILLARD .bFunctionLength =
2091378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_class_union_function_descriptor),
2101378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = CS_INTERFACE,
2111378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorSubtype = USB_ST_UF,
2121378df79SJean-Christophe PLAGNIOL-VILLARD .bMasterInterface = 0x00,
2131378df79SJean-Christophe PLAGNIOL-VILLARD .bSlaveInterface0 = 0x01,
2141378df79SJean-Christophe PLAGNIOL-VILLARD },
2151378df79SJean-Christophe PLAGNIOL-VILLARD .notification_endpoint = {
2161378df79SJean-Christophe PLAGNIOL-VILLARD .bLength =
2171378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_endpoint_descriptor),
2181378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_ENDPOINT,
2199e78dae2SVivek Kutal .bEndpointAddress = UDC_INT_ENDPOINT | USB_DIR_IN,
2201378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes = USB_ENDPOINT_XFER_INT,
2211378df79SJean-Christophe PLAGNIOL-VILLARD .wMaxPacketSize
2221378df79SJean-Christophe PLAGNIOL-VILLARD = cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),
2231378df79SJean-Christophe PLAGNIOL-VILLARD .bInterval = 0xFF,
2241378df79SJean-Christophe PLAGNIOL-VILLARD },
2251378df79SJean-Christophe PLAGNIOL-VILLARD
2261378df79SJean-Christophe PLAGNIOL-VILLARD /* Interface 2 */
2271378df79SJean-Christophe PLAGNIOL-VILLARD .data_class_interface = {
2281378df79SJean-Christophe PLAGNIOL-VILLARD .bLength =
2291378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_interface_descriptor),
2301378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_INTERFACE,
2311378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceNumber = 0x01,
2321378df79SJean-Christophe PLAGNIOL-VILLARD .bAlternateSetting = 0x00,
2331378df79SJean-Christophe PLAGNIOL-VILLARD .bNumEndpoints = 0x02,
2341378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceClass =
2351378df79SJean-Christophe PLAGNIOL-VILLARD COMMUNICATIONS_INTERFACE_CLASS_DATA,
2361378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceSubClass = DATA_INTERFACE_SUBCLASS_NONE,
2371378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceProtocol = DATA_INTERFACE_PROTOCOL_NONE,
2381378df79SJean-Christophe PLAGNIOL-VILLARD .iInterface = STR_DATA_INTERFACE,
2391378df79SJean-Christophe PLAGNIOL-VILLARD },
2401378df79SJean-Christophe PLAGNIOL-VILLARD .data_endpoints = {
2411378df79SJean-Christophe PLAGNIOL-VILLARD {
2421378df79SJean-Christophe PLAGNIOL-VILLARD .bLength =
2431378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_endpoint_descriptor),
2441378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_ENDPOINT,
2459e78dae2SVivek Kutal .bEndpointAddress = UDC_OUT_ENDPOINT | USB_DIR_OUT,
2461378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes =
2471378df79SJean-Christophe PLAGNIOL-VILLARD USB_ENDPOINT_XFER_BULK,
2481378df79SJean-Christophe PLAGNIOL-VILLARD .wMaxPacketSize =
2491378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE),
2501378df79SJean-Christophe PLAGNIOL-VILLARD .bInterval = 0xFF,
2511378df79SJean-Christophe PLAGNIOL-VILLARD },
2521378df79SJean-Christophe PLAGNIOL-VILLARD {
2531378df79SJean-Christophe PLAGNIOL-VILLARD .bLength =
2541378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_endpoint_descriptor),
2551378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_ENDPOINT,
2569e78dae2SVivek Kutal .bEndpointAddress = UDC_IN_ENDPOINT | USB_DIR_IN,
2571378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes =
2581378df79SJean-Christophe PLAGNIOL-VILLARD USB_ENDPOINT_XFER_BULK,
2591378df79SJean-Christophe PLAGNIOL-VILLARD .wMaxPacketSize =
2601378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE),
2611378df79SJean-Christophe PLAGNIOL-VILLARD .bInterval = 0xFF,
2621378df79SJean-Christophe PLAGNIOL-VILLARD },
2631378df79SJean-Christophe PLAGNIOL-VILLARD },
2641378df79SJean-Christophe PLAGNIOL-VILLARD },
2651378df79SJean-Christophe PLAGNIOL-VILLARD };
2661378df79SJean-Christophe PLAGNIOL-VILLARD
2671378df79SJean-Christophe PLAGNIOL-VILLARD static struct rs232_emu rs232_desc={
2681378df79SJean-Christophe PLAGNIOL-VILLARD .dter = 115200,
2691378df79SJean-Christophe PLAGNIOL-VILLARD .stop_bits = 0x00,
2701378df79SJean-Christophe PLAGNIOL-VILLARD .parity = 0x00,
2711378df79SJean-Christophe PLAGNIOL-VILLARD .data_bits = 0x08
2721378df79SJean-Christophe PLAGNIOL-VILLARD };
2731378df79SJean-Christophe PLAGNIOL-VILLARD
2741378df79SJean-Christophe PLAGNIOL-VILLARD
2751378df79SJean-Christophe PLAGNIOL-VILLARD /*
2761378df79SJean-Christophe PLAGNIOL-VILLARD * Static Generic Serial specific data
2771378df79SJean-Christophe PLAGNIOL-VILLARD */
2781378df79SJean-Christophe PLAGNIOL-VILLARD
2791378df79SJean-Christophe PLAGNIOL-VILLARD
2801378df79SJean-Christophe PLAGNIOL-VILLARD struct gserial_config_desc {
2811378df79SJean-Christophe PLAGNIOL-VILLARD
2821378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_configuration_descriptor configuration_desc;
283f3c0de63SAtin Malaviya struct usb_interface_descriptor interface_desc[NUM_GSERIAL_INTERFACES];
284f3c0de63SAtin Malaviya struct usb_endpoint_descriptor data_endpoints[NUM_ENDPOINTS];
2851378df79SJean-Christophe PLAGNIOL-VILLARD
2861378df79SJean-Christophe PLAGNIOL-VILLARD } __attribute__((packed));
2871378df79SJean-Christophe PLAGNIOL-VILLARD
2881378df79SJean-Christophe PLAGNIOL-VILLARD static struct gserial_config_desc
2891378df79SJean-Christophe PLAGNIOL-VILLARD gserial_configuration_descriptors[NUM_CONFIGS] ={
2901378df79SJean-Christophe PLAGNIOL-VILLARD {
2911378df79SJean-Christophe PLAGNIOL-VILLARD .configuration_desc ={
2921378df79SJean-Christophe PLAGNIOL-VILLARD .bLength = sizeof(struct usb_configuration_descriptor),
2931378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_CONFIG,
2941378df79SJean-Christophe PLAGNIOL-VILLARD .wTotalLength =
2951378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(sizeof(struct gserial_config_desc)),
2961378df79SJean-Christophe PLAGNIOL-VILLARD .bNumInterfaces = NUM_GSERIAL_INTERFACES,
2971378df79SJean-Christophe PLAGNIOL-VILLARD .bConfigurationValue = 1,
2981378df79SJean-Christophe PLAGNIOL-VILLARD .iConfiguration = STR_CONFIG,
2991378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes =
3001378df79SJean-Christophe PLAGNIOL-VILLARD BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,
3011378df79SJean-Christophe PLAGNIOL-VILLARD .bMaxPower = USBTTY_MAXPOWER
3021378df79SJean-Christophe PLAGNIOL-VILLARD },
3031378df79SJean-Christophe PLAGNIOL-VILLARD .interface_desc = {
3041378df79SJean-Christophe PLAGNIOL-VILLARD {
3051378df79SJean-Christophe PLAGNIOL-VILLARD .bLength =
3061378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_interface_descriptor),
3071378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_INTERFACE,
3081378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceNumber = 0,
3091378df79SJean-Christophe PLAGNIOL-VILLARD .bAlternateSetting = 0,
3101378df79SJean-Christophe PLAGNIOL-VILLARD .bNumEndpoints = NUM_ENDPOINTS,
3111378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceClass =
3121378df79SJean-Christophe PLAGNIOL-VILLARD COMMUNICATIONS_INTERFACE_CLASS_VENDOR,
3131378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceSubClass =
3141378df79SJean-Christophe PLAGNIOL-VILLARD COMMUNICATIONS_NO_SUBCLASS,
3151378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceProtocol =
3161378df79SJean-Christophe PLAGNIOL-VILLARD COMMUNICATIONS_NO_PROTOCOL,
3171378df79SJean-Christophe PLAGNIOL-VILLARD .iInterface = STR_DATA_INTERFACE
3181378df79SJean-Christophe PLAGNIOL-VILLARD },
3191378df79SJean-Christophe PLAGNIOL-VILLARD },
3201378df79SJean-Christophe PLAGNIOL-VILLARD .data_endpoints = {
3211378df79SJean-Christophe PLAGNIOL-VILLARD {
3221378df79SJean-Christophe PLAGNIOL-VILLARD .bLength =
3231378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_endpoint_descriptor),
3241378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_ENDPOINT,
3259e78dae2SVivek Kutal .bEndpointAddress = UDC_OUT_ENDPOINT | USB_DIR_OUT,
3261378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes = USB_ENDPOINT_XFER_BULK,
3271378df79SJean-Christophe PLAGNIOL-VILLARD .wMaxPacketSize =
3281378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_SERIAL_OUT_PKTSIZE),
3291378df79SJean-Christophe PLAGNIOL-VILLARD .bInterval= 0xFF,
3301378df79SJean-Christophe PLAGNIOL-VILLARD },
3311378df79SJean-Christophe PLAGNIOL-VILLARD {
3321378df79SJean-Christophe PLAGNIOL-VILLARD .bLength =
3331378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_endpoint_descriptor),
3341378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_ENDPOINT,
3359e78dae2SVivek Kutal .bEndpointAddress = UDC_IN_ENDPOINT | USB_DIR_IN,
3361378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes = USB_ENDPOINT_XFER_BULK,
3371378df79SJean-Christophe PLAGNIOL-VILLARD .wMaxPacketSize =
3381378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_SERIAL_IN_PKTSIZE),
3391378df79SJean-Christophe PLAGNIOL-VILLARD .bInterval = 0xFF,
3401378df79SJean-Christophe PLAGNIOL-VILLARD },
3411378df79SJean-Christophe PLAGNIOL-VILLARD {
3421378df79SJean-Christophe PLAGNIOL-VILLARD .bLength =
3431378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_endpoint_descriptor),
3441378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_ENDPOINT,
3459e78dae2SVivek Kutal .bEndpointAddress = UDC_INT_ENDPOINT | USB_DIR_IN,
3461378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes = USB_ENDPOINT_XFER_INT,
3471378df79SJean-Christophe PLAGNIOL-VILLARD .wMaxPacketSize =
3481378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),
3491378df79SJean-Christophe PLAGNIOL-VILLARD .bInterval = 0xFF,
3501378df79SJean-Christophe PLAGNIOL-VILLARD },
3511378df79SJean-Christophe PLAGNIOL-VILLARD },
3521378df79SJean-Christophe PLAGNIOL-VILLARD },
3531378df79SJean-Christophe PLAGNIOL-VILLARD };
3541378df79SJean-Christophe PLAGNIOL-VILLARD
3551378df79SJean-Christophe PLAGNIOL-VILLARD /*
3561378df79SJean-Christophe PLAGNIOL-VILLARD * Static Function Prototypes
3571378df79SJean-Christophe PLAGNIOL-VILLARD */
3581378df79SJean-Christophe PLAGNIOL-VILLARD
3591378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_strings (void);
3601378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_instances (void);
3611378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_endpoints (void);
3621378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_terminal_type(short type);
3631378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_event_handler (struct usb_device_instance *device,
3641378df79SJean-Christophe PLAGNIOL-VILLARD usb_device_event_t event, int data);
3651378df79SJean-Christophe PLAGNIOL-VILLARD static int usbtty_cdc_setup(struct usb_device_request *request,
3661378df79SJean-Christophe PLAGNIOL-VILLARD struct urb *urb);
3671378df79SJean-Christophe PLAGNIOL-VILLARD static int usbtty_configured (void);
3681378df79SJean-Christophe PLAGNIOL-VILLARD static int write_buffer (circbuf_t * buf);
3691378df79SJean-Christophe PLAGNIOL-VILLARD static int fill_buffer (circbuf_t * buf);
3701378df79SJean-Christophe PLAGNIOL-VILLARD
3711378df79SJean-Christophe PLAGNIOL-VILLARD void usbtty_poll (void);
3721378df79SJean-Christophe PLAGNIOL-VILLARD
3731378df79SJean-Christophe PLAGNIOL-VILLARD /* utility function for converting char* to wide string used by USB */
str2wide(char * str,u16 * wide)3741378df79SJean-Christophe PLAGNIOL-VILLARD static void str2wide (char *str, u16 * wide)
3751378df79SJean-Christophe PLAGNIOL-VILLARD {
3761378df79SJean-Christophe PLAGNIOL-VILLARD int i;
3771378df79SJean-Christophe PLAGNIOL-VILLARD for (i = 0; i < strlen (str) && str[i]; i++){
3781378df79SJean-Christophe PLAGNIOL-VILLARD #if defined(__LITTLE_ENDIAN)
3791378df79SJean-Christophe PLAGNIOL-VILLARD wide[i] = (u16) str[i];
3801378df79SJean-Christophe PLAGNIOL-VILLARD #elif defined(__BIG_ENDIAN)
3811378df79SJean-Christophe PLAGNIOL-VILLARD wide[i] = ((u16)(str[i])<<8);
3821378df79SJean-Christophe PLAGNIOL-VILLARD #else
3831378df79SJean-Christophe PLAGNIOL-VILLARD #error "__LITTLE_ENDIAN or __BIG_ENDIAN undefined"
3841378df79SJean-Christophe PLAGNIOL-VILLARD #endif
3851378df79SJean-Christophe PLAGNIOL-VILLARD }
3861378df79SJean-Christophe PLAGNIOL-VILLARD }
3871378df79SJean-Christophe PLAGNIOL-VILLARD
3881378df79SJean-Christophe PLAGNIOL-VILLARD /*
3891378df79SJean-Christophe PLAGNIOL-VILLARD * Test whether a character is in the RX buffer
3901378df79SJean-Christophe PLAGNIOL-VILLARD */
3911378df79SJean-Christophe PLAGNIOL-VILLARD
usbtty_tstc(struct stdio_dev * dev)392709ea543SSimon Glass int usbtty_tstc(struct stdio_dev *dev)
3931378df79SJean-Christophe PLAGNIOL-VILLARD {
3941378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_instance *endpoint =
3951378df79SJean-Christophe PLAGNIOL-VILLARD &endpoint_instance[rx_endpoint];
3961378df79SJean-Christophe PLAGNIOL-VILLARD
3971378df79SJean-Christophe PLAGNIOL-VILLARD /* If no input data exists, allow more RX to be accepted */
3981378df79SJean-Christophe PLAGNIOL-VILLARD if(usbtty_input.size <= 0){
3991378df79SJean-Christophe PLAGNIOL-VILLARD udc_unset_nak(endpoint->endpoint_address&0x03);
4001378df79SJean-Christophe PLAGNIOL-VILLARD }
4011378df79SJean-Christophe PLAGNIOL-VILLARD
4021378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_poll ();
4031378df79SJean-Christophe PLAGNIOL-VILLARD return (usbtty_input.size > 0);
4041378df79SJean-Christophe PLAGNIOL-VILLARD }
4051378df79SJean-Christophe PLAGNIOL-VILLARD
4061378df79SJean-Christophe PLAGNIOL-VILLARD /*
4071378df79SJean-Christophe PLAGNIOL-VILLARD * Read a single byte from the usb client port. Returns 1 on success, 0
4081378df79SJean-Christophe PLAGNIOL-VILLARD * otherwise. When the function is succesfull, the character read is
4091378df79SJean-Christophe PLAGNIOL-VILLARD * written into its argument c.
4101378df79SJean-Christophe PLAGNIOL-VILLARD */
4111378df79SJean-Christophe PLAGNIOL-VILLARD
usbtty_getc(struct stdio_dev * dev)412709ea543SSimon Glass int usbtty_getc(struct stdio_dev *dev)
4131378df79SJean-Christophe PLAGNIOL-VILLARD {
4141378df79SJean-Christophe PLAGNIOL-VILLARD char c;
4151378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_instance *endpoint =
4161378df79SJean-Christophe PLAGNIOL-VILLARD &endpoint_instance[rx_endpoint];
4171378df79SJean-Christophe PLAGNIOL-VILLARD
4181378df79SJean-Christophe PLAGNIOL-VILLARD while (usbtty_input.size <= 0) {
4191378df79SJean-Christophe PLAGNIOL-VILLARD udc_unset_nak(endpoint->endpoint_address&0x03);
4201378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_poll ();
4211378df79SJean-Christophe PLAGNIOL-VILLARD }
4221378df79SJean-Christophe PLAGNIOL-VILLARD
4231378df79SJean-Christophe PLAGNIOL-VILLARD buf_pop (&usbtty_input, &c, 1);
4241378df79SJean-Christophe PLAGNIOL-VILLARD udc_set_nak(endpoint->endpoint_address&0x03);
4251378df79SJean-Christophe PLAGNIOL-VILLARD
4261378df79SJean-Christophe PLAGNIOL-VILLARD return c;
4271378df79SJean-Christophe PLAGNIOL-VILLARD }
4281378df79SJean-Christophe PLAGNIOL-VILLARD
4291378df79SJean-Christophe PLAGNIOL-VILLARD /*
4301378df79SJean-Christophe PLAGNIOL-VILLARD * Output a single byte to the usb client port.
4311378df79SJean-Christophe PLAGNIOL-VILLARD */
usbtty_putc(struct stdio_dev * dev,const char c)432709ea543SSimon Glass void usbtty_putc(struct stdio_dev *dev, const char c)
4331378df79SJean-Christophe PLAGNIOL-VILLARD {
434f3c0de63SAtin Malaviya if (!usbtty_configured ())
435f3c0de63SAtin Malaviya return;
436f3c0de63SAtin Malaviya
4371378df79SJean-Christophe PLAGNIOL-VILLARD /* If \n, also do \r */
4381378df79SJean-Christophe PLAGNIOL-VILLARD if (c == '\n')
4391378df79SJean-Christophe PLAGNIOL-VILLARD buf_push (&usbtty_output, "\r", 1);
4401378df79SJean-Christophe PLAGNIOL-VILLARD
441055457efSAlison Wang buf_push(&usbtty_output, &c, 1);
442055457efSAlison Wang
4431378df79SJean-Christophe PLAGNIOL-VILLARD /* Poll at end to handle new data... */
4441378df79SJean-Christophe PLAGNIOL-VILLARD if ((usbtty_output.size + 2) >= usbtty_output.totalsize) {
4451378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_poll ();
4461378df79SJean-Christophe PLAGNIOL-VILLARD }
4471378df79SJean-Christophe PLAGNIOL-VILLARD }
4481378df79SJean-Christophe PLAGNIOL-VILLARD
4491378df79SJean-Christophe PLAGNIOL-VILLARD /* usbtty_puts() helper function for finding the next '\n' in a string */
next_nl_pos(const char * s)4501378df79SJean-Christophe PLAGNIOL-VILLARD static int next_nl_pos (const char *s)
4511378df79SJean-Christophe PLAGNIOL-VILLARD {
4521378df79SJean-Christophe PLAGNIOL-VILLARD int i;
4531378df79SJean-Christophe PLAGNIOL-VILLARD
4541378df79SJean-Christophe PLAGNIOL-VILLARD for (i = 0; s[i] != '\0'; i++) {
4551378df79SJean-Christophe PLAGNIOL-VILLARD if (s[i] == '\n')
4561378df79SJean-Christophe PLAGNIOL-VILLARD return i;
4571378df79SJean-Christophe PLAGNIOL-VILLARD }
4581378df79SJean-Christophe PLAGNIOL-VILLARD return i;
4591378df79SJean-Christophe PLAGNIOL-VILLARD }
4601378df79SJean-Christophe PLAGNIOL-VILLARD
4611378df79SJean-Christophe PLAGNIOL-VILLARD /*
4621378df79SJean-Christophe PLAGNIOL-VILLARD * Output a string to the usb client port - implementing flow control
4631378df79SJean-Christophe PLAGNIOL-VILLARD */
4641378df79SJean-Christophe PLAGNIOL-VILLARD
__usbtty_puts(const char * str,int len)4651378df79SJean-Christophe PLAGNIOL-VILLARD static void __usbtty_puts (const char *str, int len)
4661378df79SJean-Christophe PLAGNIOL-VILLARD {
4671378df79SJean-Christophe PLAGNIOL-VILLARD int maxlen = usbtty_output.totalsize;
4681378df79SJean-Christophe PLAGNIOL-VILLARD int space, n;
4691378df79SJean-Christophe PLAGNIOL-VILLARD
4701378df79SJean-Christophe PLAGNIOL-VILLARD /* break str into chunks < buffer size, if needed */
4711378df79SJean-Christophe PLAGNIOL-VILLARD while (len > 0) {
4721378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_poll ();
4731378df79SJean-Christophe PLAGNIOL-VILLARD
4741378df79SJean-Christophe PLAGNIOL-VILLARD space = maxlen - usbtty_output.size;
4751378df79SJean-Christophe PLAGNIOL-VILLARD /* Empty buffer here, if needed, to ensure space... */
4761378df79SJean-Christophe PLAGNIOL-VILLARD if (space) {
4771378df79SJean-Christophe PLAGNIOL-VILLARD write_buffer (&usbtty_output);
4781378df79SJean-Christophe PLAGNIOL-VILLARD
479c79cba37SMasahiro Yamada n = min(space, min(len, maxlen));
4801378df79SJean-Christophe PLAGNIOL-VILLARD buf_push (&usbtty_output, str, n);
4811378df79SJean-Christophe PLAGNIOL-VILLARD
4821378df79SJean-Christophe PLAGNIOL-VILLARD str += n;
4831378df79SJean-Christophe PLAGNIOL-VILLARD len -= n;
4841378df79SJean-Christophe PLAGNIOL-VILLARD }
4851378df79SJean-Christophe PLAGNIOL-VILLARD }
4861378df79SJean-Christophe PLAGNIOL-VILLARD }
4871378df79SJean-Christophe PLAGNIOL-VILLARD
usbtty_puts(struct stdio_dev * dev,const char * str)488709ea543SSimon Glass void usbtty_puts(struct stdio_dev *dev, const char *str)
4891378df79SJean-Christophe PLAGNIOL-VILLARD {
4901378df79SJean-Christophe PLAGNIOL-VILLARD int n;
491f3c0de63SAtin Malaviya int len;
4921378df79SJean-Christophe PLAGNIOL-VILLARD
493f3c0de63SAtin Malaviya if (!usbtty_configured ())
494f3c0de63SAtin Malaviya return;
495f3c0de63SAtin Malaviya
496f3c0de63SAtin Malaviya len = strlen (str);
4971378df79SJean-Christophe PLAGNIOL-VILLARD /* add '\r' for each '\n' */
4981378df79SJean-Christophe PLAGNIOL-VILLARD while (len > 0) {
4991378df79SJean-Christophe PLAGNIOL-VILLARD n = next_nl_pos (str);
5001378df79SJean-Christophe PLAGNIOL-VILLARD
5011378df79SJean-Christophe PLAGNIOL-VILLARD if (str[n] == '\n') {
5021378df79SJean-Christophe PLAGNIOL-VILLARD __usbtty_puts("\r", 1);
503055457efSAlison Wang __usbtty_puts(str, n + 1);
5041378df79SJean-Christophe PLAGNIOL-VILLARD str += (n + 1);
5051378df79SJean-Christophe PLAGNIOL-VILLARD len -= (n + 1);
5061378df79SJean-Christophe PLAGNIOL-VILLARD } else {
5071378df79SJean-Christophe PLAGNIOL-VILLARD /* No \n found. All done. */
5081378df79SJean-Christophe PLAGNIOL-VILLARD __usbtty_puts (str, n);
5091378df79SJean-Christophe PLAGNIOL-VILLARD break;
5101378df79SJean-Christophe PLAGNIOL-VILLARD }
5111378df79SJean-Christophe PLAGNIOL-VILLARD }
5121378df79SJean-Christophe PLAGNIOL-VILLARD
5131378df79SJean-Christophe PLAGNIOL-VILLARD /* Poll at end to handle new data... */
5141378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_poll ();
5151378df79SJean-Christophe PLAGNIOL-VILLARD }
5161378df79SJean-Christophe PLAGNIOL-VILLARD
5171378df79SJean-Christophe PLAGNIOL-VILLARD /*
5181378df79SJean-Christophe PLAGNIOL-VILLARD * Initialize the usb client port.
5191378df79SJean-Christophe PLAGNIOL-VILLARD *
5201378df79SJean-Christophe PLAGNIOL-VILLARD */
drv_usbtty_init(void)5211378df79SJean-Christophe PLAGNIOL-VILLARD int drv_usbtty_init (void)
5221378df79SJean-Christophe PLAGNIOL-VILLARD {
5231378df79SJean-Christophe PLAGNIOL-VILLARD int rc;
5241378df79SJean-Christophe PLAGNIOL-VILLARD char * sn;
5251378df79SJean-Christophe PLAGNIOL-VILLARD char * tt;
5261378df79SJean-Christophe PLAGNIOL-VILLARD int snlen;
5271378df79SJean-Christophe PLAGNIOL-VILLARD
528*02234e49SHeinrich Schuchardt /* Get serial number */
52900caae6dSSimon Glass sn = env_get("serial#");
53000caae6dSSimon Glass if (!sn)
5311378df79SJean-Christophe PLAGNIOL-VILLARD sn = "000000000000";
5321378df79SJean-Christophe PLAGNIOL-VILLARD snlen = strlen(sn);
5331378df79SJean-Christophe PLAGNIOL-VILLARD if (snlen > sizeof(serial_number) - 1) {
534b64f190bSWolfgang Denk printf ("Warning: serial number %s is too long (%d > %lu)\n",
535b64f190bSWolfgang Denk sn, snlen, (ulong)(sizeof(serial_number) - 1));
5361378df79SJean-Christophe PLAGNIOL-VILLARD snlen = sizeof(serial_number) - 1;
5371378df79SJean-Christophe PLAGNIOL-VILLARD }
5381378df79SJean-Christophe PLAGNIOL-VILLARD memcpy (serial_number, sn, snlen);
5391378df79SJean-Christophe PLAGNIOL-VILLARD serial_number[snlen] = '\0';
5401378df79SJean-Christophe PLAGNIOL-VILLARD
5411378df79SJean-Christophe PLAGNIOL-VILLARD /* Decide on which type of UDC device to be.
5421378df79SJean-Christophe PLAGNIOL-VILLARD */
54300caae6dSSimon Glass tt = env_get("usbtty");
54400caae6dSSimon Glass if (!tt)
5451378df79SJean-Christophe PLAGNIOL-VILLARD tt = "generic";
5461378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_init_terminal_type(strcmp(tt,"cdc_acm"));
5471378df79SJean-Christophe PLAGNIOL-VILLARD
5481378df79SJean-Christophe PLAGNIOL-VILLARD /* prepare buffers... */
5491378df79SJean-Christophe PLAGNIOL-VILLARD buf_init (&usbtty_input, USBTTY_BUFFER_SIZE);
5501378df79SJean-Christophe PLAGNIOL-VILLARD buf_init (&usbtty_output, USBTTY_BUFFER_SIZE);
5511378df79SJean-Christophe PLAGNIOL-VILLARD
5521378df79SJean-Christophe PLAGNIOL-VILLARD /* Now, set up USB controller and infrastructure */
5531378df79SJean-Christophe PLAGNIOL-VILLARD udc_init (); /* Basic USB initialization */
5541378df79SJean-Christophe PLAGNIOL-VILLARD
5551378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_init_strings ();
5561378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_init_instances ();
5571378df79SJean-Christophe PLAGNIOL-VILLARD
558241d9a61SStefan Herbrechtsmeier usbtty_init_endpoints ();
559241d9a61SStefan Herbrechtsmeier
5601378df79SJean-Christophe PLAGNIOL-VILLARD udc_startup_events (device_instance);/* Enable dev, init udc pointers */
5611378df79SJean-Christophe PLAGNIOL-VILLARD udc_connect (); /* Enable pullup for host detection */
5621378df79SJean-Christophe PLAGNIOL-VILLARD
5631378df79SJean-Christophe PLAGNIOL-VILLARD /* Device initialization */
5641378df79SJean-Christophe PLAGNIOL-VILLARD memset (&usbttydev, 0, sizeof (usbttydev));
5651378df79SJean-Christophe PLAGNIOL-VILLARD
5661378df79SJean-Christophe PLAGNIOL-VILLARD strcpy (usbttydev.name, "usbtty");
5671378df79SJean-Christophe PLAGNIOL-VILLARD usbttydev.ext = 0; /* No extensions */
5681378df79SJean-Christophe PLAGNIOL-VILLARD usbttydev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_OUTPUT;
5691378df79SJean-Christophe PLAGNIOL-VILLARD usbttydev.tstc = usbtty_tstc; /* 'tstc' function */
5701378df79SJean-Christophe PLAGNIOL-VILLARD usbttydev.getc = usbtty_getc; /* 'getc' function */
5711378df79SJean-Christophe PLAGNIOL-VILLARD usbttydev.putc = usbtty_putc; /* 'putc' function */
5721378df79SJean-Christophe PLAGNIOL-VILLARD usbttydev.puts = usbtty_puts; /* 'puts' function */
5731378df79SJean-Christophe PLAGNIOL-VILLARD
57452cb4d4fSJean-Christophe PLAGNIOL-VILLARD rc = stdio_register (&usbttydev);
5751378df79SJean-Christophe PLAGNIOL-VILLARD
5761378df79SJean-Christophe PLAGNIOL-VILLARD return (rc == 0) ? 1 : rc;
5771378df79SJean-Christophe PLAGNIOL-VILLARD }
5781378df79SJean-Christophe PLAGNIOL-VILLARD
usbtty_init_strings(void)5791378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_strings (void)
5801378df79SJean-Christophe PLAGNIOL-VILLARD {
5811378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_string_descriptor *string;
5821378df79SJean-Christophe PLAGNIOL-VILLARD
5831378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_LANG] =
5841378df79SJean-Christophe PLAGNIOL-VILLARD (struct usb_string_descriptor*)wstrLang;
5851378df79SJean-Christophe PLAGNIOL-VILLARD
5861378df79SJean-Christophe PLAGNIOL-VILLARD string = (struct usb_string_descriptor *) wstrManufacturer;
5871378df79SJean-Christophe PLAGNIOL-VILLARD string->bLength = sizeof(wstrManufacturer);
5881378df79SJean-Christophe PLAGNIOL-VILLARD string->bDescriptorType = USB_DT_STRING;
5891378df79SJean-Christophe PLAGNIOL-VILLARD str2wide (CONFIG_USBD_MANUFACTURER, string->wData);
5901378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_MANUFACTURER]=string;
5911378df79SJean-Christophe PLAGNIOL-VILLARD
5921378df79SJean-Christophe PLAGNIOL-VILLARD
5931378df79SJean-Christophe PLAGNIOL-VILLARD string = (struct usb_string_descriptor *) wstrProduct;
5941378df79SJean-Christophe PLAGNIOL-VILLARD string->bLength = sizeof(wstrProduct);
5951378df79SJean-Christophe PLAGNIOL-VILLARD string->bDescriptorType = USB_DT_STRING;
5961378df79SJean-Christophe PLAGNIOL-VILLARD str2wide (CONFIG_USBD_PRODUCT_NAME, string->wData);
5971378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_PRODUCT]=string;
5981378df79SJean-Christophe PLAGNIOL-VILLARD
5991378df79SJean-Christophe PLAGNIOL-VILLARD
6001378df79SJean-Christophe PLAGNIOL-VILLARD string = (struct usb_string_descriptor *) wstrSerial;
6011378df79SJean-Christophe PLAGNIOL-VILLARD string->bLength = sizeof(serial_number);
6021378df79SJean-Christophe PLAGNIOL-VILLARD string->bDescriptorType = USB_DT_STRING;
6031378df79SJean-Christophe PLAGNIOL-VILLARD str2wide (serial_number, string->wData);
6041378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_SERIAL]=string;
6051378df79SJean-Christophe PLAGNIOL-VILLARD
6061378df79SJean-Christophe PLAGNIOL-VILLARD
6071378df79SJean-Christophe PLAGNIOL-VILLARD string = (struct usb_string_descriptor *) wstrConfiguration;
6081378df79SJean-Christophe PLAGNIOL-VILLARD string->bLength = sizeof(wstrConfiguration);
6091378df79SJean-Christophe PLAGNIOL-VILLARD string->bDescriptorType = USB_DT_STRING;
6101378df79SJean-Christophe PLAGNIOL-VILLARD str2wide (CONFIG_USBD_CONFIGURATION_STR, string->wData);
6111378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_CONFIG]=string;
6121378df79SJean-Christophe PLAGNIOL-VILLARD
6131378df79SJean-Christophe PLAGNIOL-VILLARD
6141378df79SJean-Christophe PLAGNIOL-VILLARD string = (struct usb_string_descriptor *) wstrDataInterface;
6151378df79SJean-Christophe PLAGNIOL-VILLARD string->bLength = sizeof(wstrDataInterface);
6161378df79SJean-Christophe PLAGNIOL-VILLARD string->bDescriptorType = USB_DT_STRING;
6171378df79SJean-Christophe PLAGNIOL-VILLARD str2wide (CONFIG_USBD_DATA_INTERFACE_STR, string->wData);
6181378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_DATA_INTERFACE]=string;
6191378df79SJean-Christophe PLAGNIOL-VILLARD
6201378df79SJean-Christophe PLAGNIOL-VILLARD string = (struct usb_string_descriptor *) wstrCtrlInterface;
6211378df79SJean-Christophe PLAGNIOL-VILLARD string->bLength = sizeof(wstrCtrlInterface);
6221378df79SJean-Christophe PLAGNIOL-VILLARD string->bDescriptorType = USB_DT_STRING;
6231378df79SJean-Christophe PLAGNIOL-VILLARD str2wide (CONFIG_USBD_CTRL_INTERFACE_STR, string->wData);
6241378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_CTRL_INTERFACE]=string;
6251378df79SJean-Christophe PLAGNIOL-VILLARD
6261378df79SJean-Christophe PLAGNIOL-VILLARD /* Now, initialize the string table for ep0 handling */
6271378df79SJean-Christophe PLAGNIOL-VILLARD usb_strings = usbtty_string_table;
6281378df79SJean-Christophe PLAGNIOL-VILLARD }
6291378df79SJean-Christophe PLAGNIOL-VILLARD
630b2fb47f1STom Rini #define init_wMaxPacketSize(x) le16_to_cpu(get_unaligned(\
631b2fb47f1STom Rini &ep_descriptor_ptrs[(x) - 1]->wMaxPacketSize));
632b2fb47f1STom Rini
usbtty_init_instances(void)6331378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_instances (void)
6341378df79SJean-Christophe PLAGNIOL-VILLARD {
6351378df79SJean-Christophe PLAGNIOL-VILLARD int i;
6361378df79SJean-Christophe PLAGNIOL-VILLARD
6371378df79SJean-Christophe PLAGNIOL-VILLARD /* initialize device instance */
6381378df79SJean-Christophe PLAGNIOL-VILLARD memset (device_instance, 0, sizeof (struct usb_device_instance));
6391378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->device_state = STATE_INIT;
6401378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->device_descriptor = &device_descriptor;
641f9da0f89SVipin KUMAR #if defined(CONFIG_USBD_HS)
642f9da0f89SVipin KUMAR device_instance->qualifier_descriptor = &qualifier_descriptor;
643f9da0f89SVipin KUMAR #endif
6441378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->event = usbtty_event_handler;
6451378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->cdc_recv_setup = usbtty_cdc_setup;
6461378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->bus = bus_instance;
6471378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->configurations = NUM_CONFIGS;
6481378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->configuration_instance_array = config_instance;
6491378df79SJean-Christophe PLAGNIOL-VILLARD
6501378df79SJean-Christophe PLAGNIOL-VILLARD /* initialize bus instance */
6511378df79SJean-Christophe PLAGNIOL-VILLARD memset (bus_instance, 0, sizeof (struct usb_bus_instance));
6521378df79SJean-Christophe PLAGNIOL-VILLARD bus_instance->device = device_instance;
6531378df79SJean-Christophe PLAGNIOL-VILLARD bus_instance->endpoint_array = endpoint_instance;
6541378df79SJean-Christophe PLAGNIOL-VILLARD bus_instance->max_endpoints = 1;
6551378df79SJean-Christophe PLAGNIOL-VILLARD bus_instance->maxpacketsize = 64;
6561378df79SJean-Christophe PLAGNIOL-VILLARD bus_instance->serial_number_str = serial_number;
6571378df79SJean-Christophe PLAGNIOL-VILLARD
6581378df79SJean-Christophe PLAGNIOL-VILLARD /* configuration instance */
6591378df79SJean-Christophe PLAGNIOL-VILLARD memset (config_instance, 0,
6601378df79SJean-Christophe PLAGNIOL-VILLARD sizeof (struct usb_configuration_instance));
6611378df79SJean-Christophe PLAGNIOL-VILLARD config_instance->interfaces = interface_count;
6621378df79SJean-Christophe PLAGNIOL-VILLARD config_instance->configuration_descriptor = configuration_descriptor;
6631378df79SJean-Christophe PLAGNIOL-VILLARD config_instance->interface_instance_array = interface_instance;
6641378df79SJean-Christophe PLAGNIOL-VILLARD
6651378df79SJean-Christophe PLAGNIOL-VILLARD /* interface instance */
6661378df79SJean-Christophe PLAGNIOL-VILLARD memset (interface_instance, 0,
6671378df79SJean-Christophe PLAGNIOL-VILLARD sizeof (struct usb_interface_instance));
6681378df79SJean-Christophe PLAGNIOL-VILLARD interface_instance->alternates = 1;
6691378df79SJean-Christophe PLAGNIOL-VILLARD interface_instance->alternates_instance_array = alternate_instance;
6701378df79SJean-Christophe PLAGNIOL-VILLARD
6711378df79SJean-Christophe PLAGNIOL-VILLARD /* alternates instance */
6721378df79SJean-Christophe PLAGNIOL-VILLARD memset (alternate_instance, 0,
6731378df79SJean-Christophe PLAGNIOL-VILLARD sizeof (struct usb_alternate_instance));
6741378df79SJean-Christophe PLAGNIOL-VILLARD alternate_instance->interface_descriptor = interface_descriptors;
6751378df79SJean-Christophe PLAGNIOL-VILLARD alternate_instance->endpoints = NUM_ENDPOINTS;
6761378df79SJean-Christophe PLAGNIOL-VILLARD alternate_instance->endpoints_descriptor_array = ep_descriptor_ptrs;
6771378df79SJean-Christophe PLAGNIOL-VILLARD
6781378df79SJean-Christophe PLAGNIOL-VILLARD /* endpoint instances */
6791378df79SJean-Christophe PLAGNIOL-VILLARD memset (&endpoint_instance[0], 0,
6801378df79SJean-Christophe PLAGNIOL-VILLARD sizeof (struct usb_endpoint_instance));
6811378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[0].endpoint_address = 0;
6821378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[0].rcv_packetSize = EP0_MAX_PACKET_SIZE;
6831378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[0].rcv_attributes = USB_ENDPOINT_XFER_CONTROL;
6841378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[0].tx_packetSize = EP0_MAX_PACKET_SIZE;
6851378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[0].tx_attributes = USB_ENDPOINT_XFER_CONTROL;
6861378df79SJean-Christophe PLAGNIOL-VILLARD udc_setup_ep (device_instance, 0, &endpoint_instance[0]);
6871378df79SJean-Christophe PLAGNIOL-VILLARD
6881378df79SJean-Christophe PLAGNIOL-VILLARD for (i = 1; i <= NUM_ENDPOINTS; i++) {
6891378df79SJean-Christophe PLAGNIOL-VILLARD memset (&endpoint_instance[i], 0,
6901378df79SJean-Christophe PLAGNIOL-VILLARD sizeof (struct usb_endpoint_instance));
6911378df79SJean-Christophe PLAGNIOL-VILLARD
6921378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[i].endpoint_address =
6931378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[i - 1]->bEndpointAddress;
6941378df79SJean-Christophe PLAGNIOL-VILLARD
6951378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[i].rcv_attributes =
6961378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[i - 1]->bmAttributes;
6971378df79SJean-Christophe PLAGNIOL-VILLARD
698b2fb47f1STom Rini endpoint_instance[i].rcv_packetSize = init_wMaxPacketSize(i);
6991378df79SJean-Christophe PLAGNIOL-VILLARD
7001378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[i].tx_attributes =
7011378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[i - 1]->bmAttributes;
7021378df79SJean-Christophe PLAGNIOL-VILLARD
703b2fb47f1STom Rini endpoint_instance[i].tx_packetSize = init_wMaxPacketSize(i);
7041378df79SJean-Christophe PLAGNIOL-VILLARD
7051378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[i].tx_attributes =
7061378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[i - 1]->bmAttributes;
7071378df79SJean-Christophe PLAGNIOL-VILLARD
7081378df79SJean-Christophe PLAGNIOL-VILLARD urb_link_init (&endpoint_instance[i].rcv);
7091378df79SJean-Christophe PLAGNIOL-VILLARD urb_link_init (&endpoint_instance[i].rdy);
7101378df79SJean-Christophe PLAGNIOL-VILLARD urb_link_init (&endpoint_instance[i].tx);
7111378df79SJean-Christophe PLAGNIOL-VILLARD urb_link_init (&endpoint_instance[i].done);
7121378df79SJean-Christophe PLAGNIOL-VILLARD
7131378df79SJean-Christophe PLAGNIOL-VILLARD if (endpoint_instance[i].endpoint_address & USB_DIR_IN)
7141378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[i].tx_urb =
7151378df79SJean-Christophe PLAGNIOL-VILLARD usbd_alloc_urb (device_instance,
7161378df79SJean-Christophe PLAGNIOL-VILLARD &endpoint_instance[i]);
7171378df79SJean-Christophe PLAGNIOL-VILLARD else
7181378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[i].rcv_urb =
7191378df79SJean-Christophe PLAGNIOL-VILLARD usbd_alloc_urb (device_instance,
7201378df79SJean-Christophe PLAGNIOL-VILLARD &endpoint_instance[i]);
7211378df79SJean-Christophe PLAGNIOL-VILLARD }
7221378df79SJean-Christophe PLAGNIOL-VILLARD }
7231378df79SJean-Christophe PLAGNIOL-VILLARD
usbtty_init_endpoints(void)7241378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_endpoints (void)
7251378df79SJean-Christophe PLAGNIOL-VILLARD {
7261378df79SJean-Christophe PLAGNIOL-VILLARD int i;
7271378df79SJean-Christophe PLAGNIOL-VILLARD
7281378df79SJean-Christophe PLAGNIOL-VILLARD bus_instance->max_endpoints = NUM_ENDPOINTS + 1;
7291378df79SJean-Christophe PLAGNIOL-VILLARD for (i = 1; i <= NUM_ENDPOINTS; i++) {
7301378df79SJean-Christophe PLAGNIOL-VILLARD udc_setup_ep (device_instance, i, &endpoint_instance[i]);
7311378df79SJean-Christophe PLAGNIOL-VILLARD }
7321378df79SJean-Christophe PLAGNIOL-VILLARD }
7331378df79SJean-Christophe PLAGNIOL-VILLARD
7341378df79SJean-Christophe PLAGNIOL-VILLARD /* usbtty_init_terminal_type
7351378df79SJean-Christophe PLAGNIOL-VILLARD *
7361378df79SJean-Christophe PLAGNIOL-VILLARD * Do some late binding for our device type.
7371378df79SJean-Christophe PLAGNIOL-VILLARD */
usbtty_init_terminal_type(short type)7381378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_terminal_type(short type)
7391378df79SJean-Christophe PLAGNIOL-VILLARD {
7401378df79SJean-Christophe PLAGNIOL-VILLARD switch(type){
7411378df79SJean-Christophe PLAGNIOL-VILLARD /* CDC ACM */
7421378df79SJean-Christophe PLAGNIOL-VILLARD case 0:
7431378df79SJean-Christophe PLAGNIOL-VILLARD /* Assign endpoint descriptors */
7441378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[0] =
7451378df79SJean-Christophe PLAGNIOL-VILLARD &acm_configuration_descriptors[0].notification_endpoint;
7461378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[1] =
7471378df79SJean-Christophe PLAGNIOL-VILLARD &acm_configuration_descriptors[0].data_endpoints[0];
7481378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[2] =
7491378df79SJean-Christophe PLAGNIOL-VILLARD &acm_configuration_descriptors[0].data_endpoints[1];
7501378df79SJean-Christophe PLAGNIOL-VILLARD
7511378df79SJean-Christophe PLAGNIOL-VILLARD /* Enumerate Device Descriptor */
7521378df79SJean-Christophe PLAGNIOL-VILLARD device_descriptor.bDeviceClass =
7531378df79SJean-Christophe PLAGNIOL-VILLARD COMMUNICATIONS_DEVICE_CLASS;
7541378df79SJean-Christophe PLAGNIOL-VILLARD device_descriptor.idProduct =
7551378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_PRODUCTID_CDCACM);
7561378df79SJean-Christophe PLAGNIOL-VILLARD
757f9da0f89SVipin KUMAR #if defined(CONFIG_USBD_HS)
758f9da0f89SVipin KUMAR qualifier_descriptor.bDeviceClass =
759f9da0f89SVipin KUMAR COMMUNICATIONS_DEVICE_CLASS;
760f9da0f89SVipin KUMAR #endif
7611378df79SJean-Christophe PLAGNIOL-VILLARD /* Assign endpoint indices */
7621378df79SJean-Christophe PLAGNIOL-VILLARD tx_endpoint = ACM_TX_ENDPOINT;
7631378df79SJean-Christophe PLAGNIOL-VILLARD rx_endpoint = ACM_RX_ENDPOINT;
7641378df79SJean-Christophe PLAGNIOL-VILLARD
7651378df79SJean-Christophe PLAGNIOL-VILLARD /* Configuration Descriptor */
7661378df79SJean-Christophe PLAGNIOL-VILLARD configuration_descriptor =
7671378df79SJean-Christophe PLAGNIOL-VILLARD (struct usb_configuration_descriptor*)
7681378df79SJean-Christophe PLAGNIOL-VILLARD &acm_configuration_descriptors;
7691378df79SJean-Christophe PLAGNIOL-VILLARD
7701378df79SJean-Christophe PLAGNIOL-VILLARD /* Interface count */
7711378df79SJean-Christophe PLAGNIOL-VILLARD interface_count = NUM_ACM_INTERFACES;
7721378df79SJean-Christophe PLAGNIOL-VILLARD break;
7731378df79SJean-Christophe PLAGNIOL-VILLARD
7741378df79SJean-Christophe PLAGNIOL-VILLARD /* BULK IN/OUT & Default */
7751378df79SJean-Christophe PLAGNIOL-VILLARD case 1:
7761378df79SJean-Christophe PLAGNIOL-VILLARD default:
7771378df79SJean-Christophe PLAGNIOL-VILLARD /* Assign endpoint descriptors */
7781378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[0] =
7791378df79SJean-Christophe PLAGNIOL-VILLARD &gserial_configuration_descriptors[0].data_endpoints[0];
7801378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[1] =
7811378df79SJean-Christophe PLAGNIOL-VILLARD &gserial_configuration_descriptors[0].data_endpoints[1];
7821378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[2] =
7831378df79SJean-Christophe PLAGNIOL-VILLARD &gserial_configuration_descriptors[0].data_endpoints[2];
7841378df79SJean-Christophe PLAGNIOL-VILLARD
7851378df79SJean-Christophe PLAGNIOL-VILLARD /* Enumerate Device Descriptor */
7861378df79SJean-Christophe PLAGNIOL-VILLARD device_descriptor.bDeviceClass = 0xFF;
7871378df79SJean-Christophe PLAGNIOL-VILLARD device_descriptor.idProduct =
7881378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_PRODUCTID_GSERIAL);
789f9da0f89SVipin KUMAR #if defined(CONFIG_USBD_HS)
790f9da0f89SVipin KUMAR qualifier_descriptor.bDeviceClass = 0xFF;
791f9da0f89SVipin KUMAR #endif
7921378df79SJean-Christophe PLAGNIOL-VILLARD /* Assign endpoint indices */
7931378df79SJean-Christophe PLAGNIOL-VILLARD tx_endpoint = GSERIAL_TX_ENDPOINT;
7941378df79SJean-Christophe PLAGNIOL-VILLARD rx_endpoint = GSERIAL_RX_ENDPOINT;
7951378df79SJean-Christophe PLAGNIOL-VILLARD
7961378df79SJean-Christophe PLAGNIOL-VILLARD /* Configuration Descriptor */
7971378df79SJean-Christophe PLAGNIOL-VILLARD configuration_descriptor =
7981378df79SJean-Christophe PLAGNIOL-VILLARD (struct usb_configuration_descriptor*)
7991378df79SJean-Christophe PLAGNIOL-VILLARD &gserial_configuration_descriptors;
8001378df79SJean-Christophe PLAGNIOL-VILLARD
8011378df79SJean-Christophe PLAGNIOL-VILLARD /* Interface count */
8021378df79SJean-Christophe PLAGNIOL-VILLARD interface_count = NUM_GSERIAL_INTERFACES;
8031378df79SJean-Christophe PLAGNIOL-VILLARD break;
8041378df79SJean-Christophe PLAGNIOL-VILLARD }
8051378df79SJean-Christophe PLAGNIOL-VILLARD }
8061378df79SJean-Christophe PLAGNIOL-VILLARD
8071378df79SJean-Christophe PLAGNIOL-VILLARD /******************************************************************************/
8081378df79SJean-Christophe PLAGNIOL-VILLARD
next_urb(struct usb_device_instance * device,struct usb_endpoint_instance * endpoint)8091378df79SJean-Christophe PLAGNIOL-VILLARD static struct urb *next_urb (struct usb_device_instance *device,
8101378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_instance *endpoint)
8111378df79SJean-Christophe PLAGNIOL-VILLARD {
8121378df79SJean-Christophe PLAGNIOL-VILLARD struct urb *current_urb = NULL;
8131378df79SJean-Christophe PLAGNIOL-VILLARD int space;
8141378df79SJean-Christophe PLAGNIOL-VILLARD
8151378df79SJean-Christophe PLAGNIOL-VILLARD /* If there's a queue, then we should add to the last urb */
8161378df79SJean-Christophe PLAGNIOL-VILLARD if (!endpoint->tx_queue) {
8171378df79SJean-Christophe PLAGNIOL-VILLARD current_urb = endpoint->tx_urb;
8181378df79SJean-Christophe PLAGNIOL-VILLARD } else {
8191378df79SJean-Christophe PLAGNIOL-VILLARD /* Last urb from tx chain */
8201378df79SJean-Christophe PLAGNIOL-VILLARD current_urb =
8211378df79SJean-Christophe PLAGNIOL-VILLARD p2surround (struct urb, link, endpoint->tx.prev);
8221378df79SJean-Christophe PLAGNIOL-VILLARD }
8231378df79SJean-Christophe PLAGNIOL-VILLARD
8241378df79SJean-Christophe PLAGNIOL-VILLARD /* Make sure this one has enough room */
8251378df79SJean-Christophe PLAGNIOL-VILLARD space = current_urb->buffer_length - current_urb->actual_length;
8261378df79SJean-Christophe PLAGNIOL-VILLARD if (space > 0) {
8271378df79SJean-Christophe PLAGNIOL-VILLARD return current_urb;
8281378df79SJean-Christophe PLAGNIOL-VILLARD } else { /* No space here */
8291378df79SJean-Christophe PLAGNIOL-VILLARD /* First look at done list */
8301378df79SJean-Christophe PLAGNIOL-VILLARD current_urb = first_urb_detached (&endpoint->done);
8311378df79SJean-Christophe PLAGNIOL-VILLARD if (!current_urb) {
8321378df79SJean-Christophe PLAGNIOL-VILLARD current_urb = usbd_alloc_urb (device, endpoint);
8331378df79SJean-Christophe PLAGNIOL-VILLARD }
8341378df79SJean-Christophe PLAGNIOL-VILLARD
8351378df79SJean-Christophe PLAGNIOL-VILLARD urb_append (&endpoint->tx, current_urb);
8361378df79SJean-Christophe PLAGNIOL-VILLARD endpoint->tx_queue++;
8371378df79SJean-Christophe PLAGNIOL-VILLARD }
8381378df79SJean-Christophe PLAGNIOL-VILLARD return current_urb;
8391378df79SJean-Christophe PLAGNIOL-VILLARD }
8401378df79SJean-Christophe PLAGNIOL-VILLARD
write_buffer(circbuf_t * buf)8411378df79SJean-Christophe PLAGNIOL-VILLARD static int write_buffer (circbuf_t * buf)
8421378df79SJean-Christophe PLAGNIOL-VILLARD {
8431378df79SJean-Christophe PLAGNIOL-VILLARD if (!usbtty_configured ()) {
8441378df79SJean-Christophe PLAGNIOL-VILLARD return 0;
8451378df79SJean-Christophe PLAGNIOL-VILLARD }
8461378df79SJean-Christophe PLAGNIOL-VILLARD
8471378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_instance *endpoint =
8481378df79SJean-Christophe PLAGNIOL-VILLARD &endpoint_instance[tx_endpoint];
8491378df79SJean-Christophe PLAGNIOL-VILLARD struct urb *current_urb = NULL;
8501378df79SJean-Christophe PLAGNIOL-VILLARD
8511378df79SJean-Christophe PLAGNIOL-VILLARD current_urb = next_urb (device_instance, endpoint);
85273be5b3fSxypron.glpk@gmx.de
85373be5b3fSxypron.glpk@gmx.de if (!current_urb) {
85473be5b3fSxypron.glpk@gmx.de TTYERR ("current_urb is NULL, buf->size %d\n",
85573be5b3fSxypron.glpk@gmx.de buf->size);
85673be5b3fSxypron.glpk@gmx.de return 0;
85773be5b3fSxypron.glpk@gmx.de }
85873be5b3fSxypron.glpk@gmx.de
8591378df79SJean-Christophe PLAGNIOL-VILLARD /* TX data still exists - send it now
8601378df79SJean-Christophe PLAGNIOL-VILLARD */
8611378df79SJean-Christophe PLAGNIOL-VILLARD if(endpoint->sent < current_urb->actual_length){
8621378df79SJean-Christophe PLAGNIOL-VILLARD if(udc_endpoint_write (endpoint)){
8631378df79SJean-Christophe PLAGNIOL-VILLARD /* Write pre-empted by RX */
8641378df79SJean-Christophe PLAGNIOL-VILLARD return -1;
8651378df79SJean-Christophe PLAGNIOL-VILLARD }
8661378df79SJean-Christophe PLAGNIOL-VILLARD }
8671378df79SJean-Christophe PLAGNIOL-VILLARD
8681378df79SJean-Christophe PLAGNIOL-VILLARD if (buf->size) {
8691378df79SJean-Christophe PLAGNIOL-VILLARD char *dest;
8701378df79SJean-Christophe PLAGNIOL-VILLARD
8711378df79SJean-Christophe PLAGNIOL-VILLARD int space_avail;
8721378df79SJean-Christophe PLAGNIOL-VILLARD int popnum, popped;
8731378df79SJean-Christophe PLAGNIOL-VILLARD int total = 0;
8741378df79SJean-Christophe PLAGNIOL-VILLARD
8751378df79SJean-Christophe PLAGNIOL-VILLARD /* Break buffer into urb sized pieces,
8761378df79SJean-Christophe PLAGNIOL-VILLARD * and link each to the endpoint
8771378df79SJean-Christophe PLAGNIOL-VILLARD */
8781378df79SJean-Christophe PLAGNIOL-VILLARD while (buf->size > 0) {
8791378df79SJean-Christophe PLAGNIOL-VILLARD
8801378df79SJean-Christophe PLAGNIOL-VILLARD dest = (char*)current_urb->buffer +
8811378df79SJean-Christophe PLAGNIOL-VILLARD current_urb->actual_length;
8821378df79SJean-Christophe PLAGNIOL-VILLARD
8831378df79SJean-Christophe PLAGNIOL-VILLARD space_avail =
8841378df79SJean-Christophe PLAGNIOL-VILLARD current_urb->buffer_length -
8851378df79SJean-Christophe PLAGNIOL-VILLARD current_urb->actual_length;
886b4141195SMasahiro Yamada popnum = min(space_avail, (int)buf->size);
8871378df79SJean-Christophe PLAGNIOL-VILLARD if (popnum == 0)
8881378df79SJean-Christophe PLAGNIOL-VILLARD break;
8891378df79SJean-Christophe PLAGNIOL-VILLARD
8901378df79SJean-Christophe PLAGNIOL-VILLARD popped = buf_pop (buf, dest, popnum);
8911378df79SJean-Christophe PLAGNIOL-VILLARD if (popped == 0)
8921378df79SJean-Christophe PLAGNIOL-VILLARD break;
8931378df79SJean-Christophe PLAGNIOL-VILLARD current_urb->actual_length += popped;
8941378df79SJean-Christophe PLAGNIOL-VILLARD total += popped;
8951378df79SJean-Christophe PLAGNIOL-VILLARD
8961378df79SJean-Christophe PLAGNIOL-VILLARD /* If endpoint->last == 0, then transfers have
8971378df79SJean-Christophe PLAGNIOL-VILLARD * not started on this endpoint
8981378df79SJean-Christophe PLAGNIOL-VILLARD */
8991378df79SJean-Christophe PLAGNIOL-VILLARD if (endpoint->last == 0) {
9001378df79SJean-Christophe PLAGNIOL-VILLARD if(udc_endpoint_write (endpoint)){
9011378df79SJean-Christophe PLAGNIOL-VILLARD /* Write pre-empted by RX */
9021378df79SJean-Christophe PLAGNIOL-VILLARD return -1;
9031378df79SJean-Christophe PLAGNIOL-VILLARD }
9041378df79SJean-Christophe PLAGNIOL-VILLARD }
9051378df79SJean-Christophe PLAGNIOL-VILLARD
9061378df79SJean-Christophe PLAGNIOL-VILLARD }/* end while */
9071378df79SJean-Christophe PLAGNIOL-VILLARD return total;
9081378df79SJean-Christophe PLAGNIOL-VILLARD }
9091378df79SJean-Christophe PLAGNIOL-VILLARD
9101378df79SJean-Christophe PLAGNIOL-VILLARD return 0;
9111378df79SJean-Christophe PLAGNIOL-VILLARD }
9121378df79SJean-Christophe PLAGNIOL-VILLARD
fill_buffer(circbuf_t * buf)9131378df79SJean-Christophe PLAGNIOL-VILLARD static int fill_buffer (circbuf_t * buf)
9141378df79SJean-Christophe PLAGNIOL-VILLARD {
9151378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_instance *endpoint =
9161378df79SJean-Christophe PLAGNIOL-VILLARD &endpoint_instance[rx_endpoint];
9171378df79SJean-Christophe PLAGNIOL-VILLARD
9181378df79SJean-Christophe PLAGNIOL-VILLARD if (endpoint->rcv_urb && endpoint->rcv_urb->actual_length) {
9191378df79SJean-Christophe PLAGNIOL-VILLARD unsigned int nb = 0;
9201378df79SJean-Christophe PLAGNIOL-VILLARD char *src = (char *) endpoint->rcv_urb->buffer;
9211378df79SJean-Christophe PLAGNIOL-VILLARD unsigned int rx_avail = buf->totalsize - buf->size;
9221378df79SJean-Christophe PLAGNIOL-VILLARD
9231378df79SJean-Christophe PLAGNIOL-VILLARD if(rx_avail >= endpoint->rcv_urb->actual_length){
9241378df79SJean-Christophe PLAGNIOL-VILLARD
9251378df79SJean-Christophe PLAGNIOL-VILLARD nb = endpoint->rcv_urb->actual_length;
9261378df79SJean-Christophe PLAGNIOL-VILLARD buf_push (buf, src, nb);
9271378df79SJean-Christophe PLAGNIOL-VILLARD endpoint->rcv_urb->actual_length = 0;
9281378df79SJean-Christophe PLAGNIOL-VILLARD
9291378df79SJean-Christophe PLAGNIOL-VILLARD }
9301378df79SJean-Christophe PLAGNIOL-VILLARD return nb;
9311378df79SJean-Christophe PLAGNIOL-VILLARD }
9321378df79SJean-Christophe PLAGNIOL-VILLARD return 0;
9331378df79SJean-Christophe PLAGNIOL-VILLARD }
9341378df79SJean-Christophe PLAGNIOL-VILLARD
usbtty_configured(void)9351378df79SJean-Christophe PLAGNIOL-VILLARD static int usbtty_configured (void)
9361378df79SJean-Christophe PLAGNIOL-VILLARD {
9371378df79SJean-Christophe PLAGNIOL-VILLARD return usbtty_configured_flag;
9381378df79SJean-Christophe PLAGNIOL-VILLARD }
9391378df79SJean-Christophe PLAGNIOL-VILLARD
9401378df79SJean-Christophe PLAGNIOL-VILLARD /******************************************************************************/
9411378df79SJean-Christophe PLAGNIOL-VILLARD
usbtty_event_handler(struct usb_device_instance * device,usb_device_event_t event,int data)9421378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_event_handler (struct usb_device_instance *device,
9431378df79SJean-Christophe PLAGNIOL-VILLARD usb_device_event_t event, int data)
9441378df79SJean-Christophe PLAGNIOL-VILLARD {
945f9da0f89SVipin KUMAR #if defined(CONFIG_USBD_HS)
946f9da0f89SVipin KUMAR int i;
947f9da0f89SVipin KUMAR #endif
9481378df79SJean-Christophe PLAGNIOL-VILLARD switch (event) {
9491378df79SJean-Christophe PLAGNIOL-VILLARD case DEVICE_RESET:
9501378df79SJean-Christophe PLAGNIOL-VILLARD case DEVICE_BUS_INACTIVE:
9511378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_configured_flag = 0;
9521378df79SJean-Christophe PLAGNIOL-VILLARD break;
9531378df79SJean-Christophe PLAGNIOL-VILLARD case DEVICE_CONFIGURED:
9541378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_configured_flag = 1;
9551378df79SJean-Christophe PLAGNIOL-VILLARD break;
9561378df79SJean-Christophe PLAGNIOL-VILLARD
9571378df79SJean-Christophe PLAGNIOL-VILLARD case DEVICE_ADDRESS_ASSIGNED:
958f9da0f89SVipin KUMAR #if defined(CONFIG_USBD_HS)
959f9da0f89SVipin KUMAR /*
960f9da0f89SVipin KUMAR * is_usbd_high_speed routine needs to be defined by
961f9da0f89SVipin KUMAR * specific gadget driver
962472d5460SYork Sun * It returns true if device enumerates at High speed
963472d5460SYork Sun * Retuns false otherwise
964f9da0f89SVipin KUMAR */
965f9da0f89SVipin KUMAR for (i = 0; i < NUM_ENDPOINTS; i++) {
966f9da0f89SVipin KUMAR if (((ep_descriptor_ptrs[i]->bmAttributes &
967f9da0f89SVipin KUMAR USB_ENDPOINT_XFERTYPE_MASK) ==
968f9da0f89SVipin KUMAR USB_ENDPOINT_XFER_BULK)
969f9da0f89SVipin KUMAR && is_usbd_high_speed()) {
970f9da0f89SVipin KUMAR
971f9da0f89SVipin KUMAR ep_descriptor_ptrs[i]->wMaxPacketSize =
972f9da0f89SVipin KUMAR CONFIG_USBD_SERIAL_BULK_HS_PKTSIZE;
973f9da0f89SVipin KUMAR }
974f9da0f89SVipin KUMAR
975f9da0f89SVipin KUMAR endpoint_instance[i + 1].tx_packetSize =
976f9da0f89SVipin KUMAR ep_descriptor_ptrs[i]->wMaxPacketSize;
977f9da0f89SVipin KUMAR endpoint_instance[i + 1].rcv_packetSize =
978f9da0f89SVipin KUMAR ep_descriptor_ptrs[i]->wMaxPacketSize;
979f9da0f89SVipin KUMAR }
980f9da0f89SVipin KUMAR #endif
9811378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_init_endpoints ();
9821378df79SJean-Christophe PLAGNIOL-VILLARD
9831378df79SJean-Christophe PLAGNIOL-VILLARD default:
9841378df79SJean-Christophe PLAGNIOL-VILLARD break;
9851378df79SJean-Christophe PLAGNIOL-VILLARD }
9861378df79SJean-Christophe PLAGNIOL-VILLARD }
9871378df79SJean-Christophe PLAGNIOL-VILLARD
9881378df79SJean-Christophe PLAGNIOL-VILLARD /******************************************************************************/
9891378df79SJean-Christophe PLAGNIOL-VILLARD
usbtty_cdc_setup(struct usb_device_request * request,struct urb * urb)9901378df79SJean-Christophe PLAGNIOL-VILLARD int usbtty_cdc_setup(struct usb_device_request *request, struct urb *urb)
9911378df79SJean-Christophe PLAGNIOL-VILLARD {
9921378df79SJean-Christophe PLAGNIOL-VILLARD switch (request->bRequest){
9931378df79SJean-Christophe PLAGNIOL-VILLARD
9941378df79SJean-Christophe PLAGNIOL-VILLARD case ACM_SET_CONTROL_LINE_STATE: /* Implies DTE ready */
9951378df79SJean-Christophe PLAGNIOL-VILLARD break;
9961378df79SJean-Christophe PLAGNIOL-VILLARD case ACM_SEND_ENCAPSULATED_COMMAND : /* Required */
9971378df79SJean-Christophe PLAGNIOL-VILLARD break;
9981378df79SJean-Christophe PLAGNIOL-VILLARD case ACM_SET_LINE_ENCODING : /* DTE stop/parity bits
9991378df79SJean-Christophe PLAGNIOL-VILLARD * per character */
10001378df79SJean-Christophe PLAGNIOL-VILLARD break;
10011378df79SJean-Christophe PLAGNIOL-VILLARD case ACM_GET_ENCAPSULATED_RESPONSE : /* request response */
10021378df79SJean-Christophe PLAGNIOL-VILLARD break;
10031378df79SJean-Christophe PLAGNIOL-VILLARD case ACM_GET_LINE_ENCODING : /* request DTE rate,
10041378df79SJean-Christophe PLAGNIOL-VILLARD * stop/parity bits */
10051378df79SJean-Christophe PLAGNIOL-VILLARD memcpy (urb->buffer , &rs232_desc, sizeof(rs232_desc));
10061378df79SJean-Christophe PLAGNIOL-VILLARD urb->actual_length = sizeof(rs232_desc);
10071378df79SJean-Christophe PLAGNIOL-VILLARD
10081378df79SJean-Christophe PLAGNIOL-VILLARD break;
10091378df79SJean-Christophe PLAGNIOL-VILLARD default:
10101378df79SJean-Christophe PLAGNIOL-VILLARD return 1;
10111378df79SJean-Christophe PLAGNIOL-VILLARD }
10121378df79SJean-Christophe PLAGNIOL-VILLARD return 0;
10131378df79SJean-Christophe PLAGNIOL-VILLARD }
10141378df79SJean-Christophe PLAGNIOL-VILLARD
10151378df79SJean-Christophe PLAGNIOL-VILLARD /******************************************************************************/
10161378df79SJean-Christophe PLAGNIOL-VILLARD
10171378df79SJean-Christophe PLAGNIOL-VILLARD /*
10181378df79SJean-Christophe PLAGNIOL-VILLARD * Since interrupt handling has not yet been implemented, we use this function
10191378df79SJean-Christophe PLAGNIOL-VILLARD * to handle polling. This is called by the tstc,getc,putc,puts routines to
10201378df79SJean-Christophe PLAGNIOL-VILLARD * update the USB state.
10211378df79SJean-Christophe PLAGNIOL-VILLARD */
usbtty_poll(void)10221378df79SJean-Christophe PLAGNIOL-VILLARD void usbtty_poll (void)
10231378df79SJean-Christophe PLAGNIOL-VILLARD {
10241378df79SJean-Christophe PLAGNIOL-VILLARD /* New interrupts? */
10251378df79SJean-Christophe PLAGNIOL-VILLARD udc_irq();
10261378df79SJean-Christophe PLAGNIOL-VILLARD
10271378df79SJean-Christophe PLAGNIOL-VILLARD /* Write any output data to host buffer
10281378df79SJean-Christophe PLAGNIOL-VILLARD * (do this before checking interrupts to avoid missing one)
10291378df79SJean-Christophe PLAGNIOL-VILLARD */
10301378df79SJean-Christophe PLAGNIOL-VILLARD if (usbtty_configured ()) {
10311378df79SJean-Christophe PLAGNIOL-VILLARD write_buffer (&usbtty_output);
10321378df79SJean-Christophe PLAGNIOL-VILLARD }
10331378df79SJean-Christophe PLAGNIOL-VILLARD
10341378df79SJean-Christophe PLAGNIOL-VILLARD /* New interrupts? */
10351378df79SJean-Christophe PLAGNIOL-VILLARD udc_irq();
10361378df79SJean-Christophe PLAGNIOL-VILLARD
10371378df79SJean-Christophe PLAGNIOL-VILLARD /* Check for new data from host..
10381378df79SJean-Christophe PLAGNIOL-VILLARD * (do this after checking interrupts to get latest data)
10391378df79SJean-Christophe PLAGNIOL-VILLARD */
10401378df79SJean-Christophe PLAGNIOL-VILLARD if (usbtty_configured ()) {
10411378df79SJean-Christophe PLAGNIOL-VILLARD fill_buffer (&usbtty_input);
10421378df79SJean-Christophe PLAGNIOL-VILLARD }
10431378df79SJean-Christophe PLAGNIOL-VILLARD
10441378df79SJean-Christophe PLAGNIOL-VILLARD /* New interrupts? */
10451378df79SJean-Christophe PLAGNIOL-VILLARD udc_irq();
10461378df79SJean-Christophe PLAGNIOL-VILLARD
10471378df79SJean-Christophe PLAGNIOL-VILLARD }
1048