blob: ddb925bb6eef1f4e736e571c9c71172bd085c14f [file] [log] [blame]
Harald Welte34a87062019-04-19 22:33:36 +02001#include "usbd_config.h"
2#include "usbdc.h"
3#include "usb_protocol.h"
4#include "usb_protocol_cdc.h"
5#include "ccid_proto.h"
6#include "cdcdf_acm_desc.h"
7
8/* aggregate descriptors for the combined CDC-ACM + CCID device that we expose
9 * from sysmoQMOD */
10
11enum str_desc_num {
12 STR_DESC_MANUF = 1,
13 STR_DESC_PRODUCT,
14 STR_DESC_CONFIG,
15 STR_DESC_INTF_ACM_COMM,
16 STR_DESC_INTF_ACM_DATA,
17 STR_DESC_INTF_CCID,
18 STR_DESC_SERIAL,
19};
20
21/* a struct of structs representing the concatenated collection of USB descriptors */
22struct usb_desc_collection {
23 struct usb_dev_desc dev;
24 struct usb_config_desc cfg;
25
26 /* CDC-ACM: Two interfaces, one with IRQ EP and one with BULK IN + OUT */
27 struct {
28 struct {
29 struct usb_iface_desc iface;
30 struct usb_cdc_hdr_desc cdc_hdr;
31 struct usb_cdc_call_mgmt_desc cdc_call_mgmt;
32 struct usb_cdc_acm_desc cdc_acm;
33 struct usb_cdc_union_desc cdc_union;
34 struct usb_ep_desc ep[1];
35 } comm;
36 struct {
37 struct usb_iface_desc iface;
38 struct usb_ep_desc ep[2];
39 } data;
40 } cdc;
41
42 /* CCID: One interface with CCID class descriptor and three endpoints */
43 struct {
44 struct usb_iface_desc iface;
45 struct usb_ccid_class_descriptor class;
46 struct usb_ep_desc ep[3];
47 } ccid;
48 uint8_t str[116];
49} __attribute__((packed));
50
51static const struct usb_desc_collection usb_fs_descs = {
52 .dev = {
53 .bLength = sizeof(struct usb_dev_desc),
54 .bDescriptorType = USB_DT_DEVICE,
55 .bcdUSB = USB_V2_0,
56 .bDeviceClass = 0x02,
57 .bDeviceSubClass = 0,
58 .bDeviceProtocol = 0,
59 .bMaxPacketSize0 = CONF_USB_CDCD_ACM_BMAXPKSZ0,
60 .idVendor = CONF_USB_CDCD_ACM_IDVENDER,
61 .idProduct = CONF_USB_CDCD_ACM_IDPRODUCT,
62 .iManufacturer = STR_DESC_MANUF,
63 .iProduct = STR_DESC_PRODUCT,
64 .iSerialNumber = STR_DESC_SERIAL,
65 .bNumConfigurations = 1,
66 },
67 .cfg = {
68 .bLength = sizeof(struct usb_config_desc),
69 .bDescriptorType = USB_DT_CONFIG,
70 .wTotalLength = sizeof(usb_fs_descs.cfg) +
71 sizeof(usb_fs_descs.cdc) +
72 sizeof(usb_fs_descs.ccid),
73 .bNumInterfaces = 3,
74 .bConfigurationValue = CONF_USB_CDCD_ACM_BCONFIGVAL,
75 .iConfiguration = STR_DESC_CONFIG,
76 .bmAttributes = CONF_USB_CDCD_ACM_BMATTRI,
77 .bMaxPower = CONF_USB_CDCD_ACM_BMAXPOWER,
78 },
79 .cdc = {
80 .comm = {
81 .iface = {
82 .bLength = sizeof(struct usb_iface_desc),
83 .bDescriptorType = USB_DT_INTERFACE,
84 .bInterfaceNumber = CONF_USB_CDCD_ACM_COMM_BIFCNUM,
85 .bAlternateSetting = CONF_USB_CDCD_ACM_COMM_BALTSET,
86 .bNumEndpoints = 1,
87 .bInterfaceClass = CDC_CLASS_COMM,
88 .bInterfaceSubClass = CDC_SUBCLASS_ACM,
89 .bInterfaceProtocol = 0x00,
90 .iInterface = STR_DESC_INTF_ACM_COMM,
91 },
92 .cdc_hdr = {
93 .bFunctionLength = sizeof(struct usb_cdc_hdr_desc),
94 .bDescriptorType = CDC_CS_INTERFACE,
95 .bDescriptorSubtype = CDC_SCS_HEADER,
96 .bcdCDC = LE16(0x1001),
97 },
98 .cdc_call_mgmt = {
99 .bFunctionLength = sizeof(struct usb_cdc_call_mgmt_desc),
100 .bDescriptorType = CDC_CS_INTERFACE,
101 .bDescriptorSubtype = CDC_SCS_CALL_MGMT,
102 .bmCapabilities = 0x01,
103 .bDataInterface = 0x00,
104 },
105 .cdc_acm = {
106 .bFunctionLength = sizeof(struct usb_cdc_acm_desc),
107 .bDescriptorType = CDC_CS_INTERFACE,
108 .bDescriptorSubtype = CDC_SCS_ACM,
109 .bmCapabilities = 0x02,
110 },
111 .cdc_union = {
112 .bFunctionLength = sizeof(struct usb_cdc_union_desc),
113 .bDescriptorType = CDC_CS_INTERFACE,
114 .bDescriptorSubtype = CDC_SCS_UNION,
115 .bMasterInterface = CONF_USB_CDCD_ACM_COMM_BIFCNUM,
116 .bSlaveInterface0 = 0x01,
117 },
118 .ep = {
119 {
120 .bLength = sizeof(struct usb_ep_desc),
121 .bDescriptorType = USB_DT_ENDPOINT,
122 .bEndpointAddress = CONF_USB_CDCD_ACM_COMM_INT_EPADDR,
123 .bmAttributes = USB_EP_TYPE_INTERRUPT,
124 .wMaxPacketSize = CONF_USB_CDCD_ACM_COMM_INT_MAXPKSZ,
125 .bInterval = CONF_USB_CDCD_ACM_COMM_INT_INTERVAL,
126 },
127 },
128 },
129 .data = {
130 .iface = {
131 .bLength = sizeof(struct usb_iface_desc),
132 .bDescriptorType = USB_DT_INTERFACE,
133 .bInterfaceNumber = CONF_USB_CDCD_ACM_DATA_BIFCNUM,
134 .bAlternateSetting = CONF_USB_CDCD_ACM_DATA_BALTSET,
135 .bNumEndpoints = 2,
136 .bInterfaceClass = CDC_CLASS_DATA,
137 .bInterfaceSubClass = 0x00,
138 .bInterfaceProtocol = 0x00,
139 .iInterface = STR_DESC_INTF_ACM_DATA,
140 },
141 .ep = {
142 {
143 .bLength = sizeof(struct usb_ep_desc),
144 .bDescriptorType = USB_DT_ENDPOINT,
145 .bEndpointAddress = CONF_USB_CDCD_ACM_DATA_BULKOUT_EPADDR,
146 .bmAttributes = USB_EP_TYPE_BULK,
147 .wMaxPacketSize = CONF_USB_CDCD_ACM_DATA_BULKOUT_MAXPKSZ,
148 .bInterval = 0,
149 },
150 {
151 .bLength = sizeof(struct usb_ep_desc),
152 .bDescriptorType = USB_DT_ENDPOINT,
153 .bEndpointAddress = CONF_USB_CDCD_ACM_DATA_BULKIN_EPADDR,
154 .bmAttributes = USB_EP_TYPE_BULK,
155 .wMaxPacketSize = CONF_USB_CDCD_ACM_DATA_BULKIN_MAXPKSZ,
156 .bInterval = 0,
157 },
158 },
159 },
160 },
161 .ccid = {
162 .iface = {
163 .bLength = sizeof(struct usb_iface_desc),
164 .bDescriptorType = USB_DT_INTERFACE,
Eric Wildab193652019-08-27 01:50:10 +0200165 .bInterfaceNumber = 0,
Harald Welte34a87062019-04-19 22:33:36 +0200166 .bAlternateSetting = 0,
167 .bNumEndpoints = 3,
168 .bInterfaceClass = 11,
169 .bInterfaceSubClass = 0,
170 .bInterfaceProtocol = 0,
171 .iInterface = STR_DESC_INTF_CCID,
172 },
173 .class = {
174 .bLength = sizeof(struct usb_ccid_class_descriptor),
175 .bDescriptorType = 33,
176 .bcdCCID = LE16(0x0110),
177 .bMaxSlotIndex = 7,
Eric Wildab193652019-08-27 01:50:10 +0200178 .bVoltageSupport = 0x07, /* 5/3/1.8V */
179 .dwProtocols = 0x03,
Harald Welte34a87062019-04-19 22:33:36 +0200180 .dwDefaultClock = LE32(2500),
181 .dwMaximumClock = LE32(20000),
182 .bNumClockSupported = 4,
183 .dwDataRate = LE32(9600),
184 .dwMaxDataRate = LE32(921600),
185 .bNumDataRatesSupported = 0,
186 .dwMaxIFSD = LE32(0),
187 .dwSynchProtocols = LE32(0),
188 .dwMechanical = LE32(0),
Eric Wildab193652019-08-27 01:50:10 +0200189 .dwFeatures = LE32(0x10 | 0x00010000),
Harald Welte34a87062019-04-19 22:33:36 +0200190 .dwMaxCCIDMessageLength = 272,
191 .bClassGetResponse = 0xff,
192 .bClassEnvelope = 0xff,
193 .wLcdLayout = LE16(0),
194 .bPINSupport = 0,
195 .bMaxCCIDBusySlots = 8,
196 },
197 .ep = {
198 { /* Bulk-OUT descriptor */
199 .bLength = sizeof(struct usb_ep_desc),
200 .bDescriptorType = USB_DT_ENDPOINT,
201 .bEndpointAddress = 0x02,
202 .bmAttributes = USB_EP_TYPE_BULK,
203 .wMaxPacketSize = 64,
204 .bInterval = 0,
205 },
206 { /* Bulk-IN descriptor */
207 .bLength = sizeof(struct usb_ep_desc),
208 .bDescriptorType = USB_DT_ENDPOINT,
209 .bEndpointAddress = 0x83,
210 .bmAttributes = USB_EP_TYPE_BULK,
211 .wMaxPacketSize = 64,
212 .bInterval = 0,
213 },
214 { /* Interrupt dscriptor */
215 .bLength = sizeof(struct usb_ep_desc),
216 .bDescriptorType = USB_DT_ENDPOINT,
217 .bEndpointAddress = 0x84,
218 .bmAttributes = USB_EP_TYPE_INTERRUPT,
219 .wMaxPacketSize = 64,
220 .bInterval = 0x10,
221 },
222 },
223 },
224 //DFURT_IF_DESCRIPTOR,
225 .str = {
226#if 0
227 CDCD_ACM_STR_DESCES
228#else
229 4, 3, 0x09, 0x04,
230 18, 3, 's',0, 'y',0, 's',0, 'm',0, 'o',0, 'c',0, 'o',0, 'm',0,
231 24, 3, 's',0, 'y',0, 's',0, 'm',0, 'o',0, 'O',0, 'C',0, 'T',0, 'S',0, 'I',0, 'M',0,
232 4, 3, 'A', 0,
233 22, 3, 'd',0, 'e',0, 'b',0, 'u',0, 'g',0, ' ',0, 'U',0, 'A',0, 'R',0, 'T',0,
234 22, 3, 'd',0, 'e',0, 'b',0, 'u',0, 'g',0, ' ',0, 'U',0, 'A',0, 'R',0, 'T',0,
235 10, 3, 'C',0, 'C',0, 'I',0, 'D',0,
236 12, 3, 'F',0, 'I',0, 'X',0, 'M',0, 'E',0,
237#endif
238 }
239};
240
241const struct usbd_descriptors usb_descs[]
242 = {{ (uint8_t *)&usb_fs_descs, (uint8_t *)&usb_fs_descs + sizeof(usb_fs_descs) }};