blob: ec018548058e9df23b46e5538fc5c24e99bf7776 [file] [log] [blame]
Sylvain Munautbc9f5c42020-09-14 10:22:29 +02001/*
2 * usb_desc_app.c
3 *
4 * Copyright (C) 2019-2020 Sylvain Munaut <tnt@246tNt.com>
5 * SPDX-License-Identifier: GPL-3.0-or-later
6 */
7
8#include <no2usb/usb_proto.h>
Sylvain Munautb9d93632021-05-31 14:03:44 +02009#include <no2usb/usb_cdc_proto.h>
Sylvain Munaut4ea7d272020-10-29 13:17:11 +010010#include <no2usb/usb_dfu_proto.h>
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020011#include <no2usb/usb.h>
12
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +010013#include "usb_desc_ids.h"
14
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020015#define NULL ((void*)0)
16#define num_elem(a) (sizeof(a) / sizeof(a[0]))
17
18
Sylvain Munautb9d93632021-05-31 14:03:44 +020019usb_cdc_union_desc_def(1);
20
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020021static const struct {
22 /* Configuration */
23 struct usb_conf_desc conf;
24
25 /* E1 */
26 struct {
Harald Welte30fc5602020-12-14 15:56:28 +010027 /* Two altsettings are required, as isochronous
28 * interfaces must have a setting where they don't
Sylvain Munaut96744362022-01-03 17:03:26 +010029 * transceive any data. We just remove the isochronous
30 * endpoints in the 'off' altsetting */
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020031 struct {
32 struct usb_intf_desc intf;
Harald Welte805f2cf2020-12-14 17:31:03 +010033 struct usb_ep_desc ep_interrupt;
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020034 } __attribute__ ((packed)) off;
35 struct {
36 struct usb_intf_desc intf;
37 struct usb_ep_desc ep_data_in;
38 struct usb_ep_desc ep_data_out;
39 struct usb_ep_desc ep_fb;
Harald Welte805f2cf2020-12-14 17:31:03 +010040 struct usb_ep_desc ep_interrupt;
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020041 } __attribute__ ((packed)) on;
42 } __attribute__ ((packed)) e1;
43
44 /* CDC */
45#if 0
46 struct {
47 struct usb_intf_desc intf_ctl;
Sylvain Munautb9d93632021-05-31 14:03:44 +020048 struct usb_cdc_hdr_desc cdc_hdr;
49 struct usb_cdc_acm_desc cdc_acm;
50 struct usb_cdc_union_desc__1 cdc_union;
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020051 struct usb_ep_desc ep_ctl;
52 struct usb_intf_desc intf_data;
53 struct usb_ep_desc ep_data_out;
54 struct usb_ep_desc ep_data_in;
55 } __attribute__ ((packed)) cdc;
56#endif
57
58 /* DFU Runtime */
59 struct {
60 struct usb_intf_desc intf;
Sylvain Munaut4ea7d272020-10-29 13:17:11 +010061 struct usb_dfu_func_desc func;
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020062 } __attribute__ ((packed)) dfu;
63} __attribute__ ((packed)) _app_conf_desc = {
64 .conf = {
65 .bLength = sizeof(struct usb_conf_desc),
66 .bDescriptorType = USB_DT_CONF,
67 .wTotalLength = sizeof(_app_conf_desc),
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +010068 .bNumInterfaces = USB_INTF_NUM,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020069 .bConfigurationValue = 1,
70 .iConfiguration = 4,
71 .bmAttributes = 0x80,
72 .bMaxPower = 0x32, /* 100 mA */
73 },
74 .e1 = {
75 .off = {
76 .intf = {
77 .bLength = sizeof(struct usb_intf_desc),
78 .bDescriptorType = USB_DT_INTF,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +010079 .bInterfaceNumber = USB_INTF_E1(0),
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020080 .bAlternateSetting = 0,
Sylvain Munaut96744362022-01-03 17:03:26 +010081 .bNumEndpoints = 1,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020082 .bInterfaceClass = 0xff,
83 .bInterfaceSubClass = 0xe1,
84 .bInterfaceProtocol = 0x00,
85 .iInterface = 5,
86 },
Harald Welte805f2cf2020-12-14 17:31:03 +010087 .ep_interrupt = {
88 .bLength = sizeof(struct usb_ep_desc),
89 .bDescriptorType = USB_DT_EP,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +010090 .bEndpointAddress = USB_EP_E1_INT(0),
Harald Welte805f2cf2020-12-14 17:31:03 +010091 .bmAttributes = 0x03,
92 .wMaxPacketSize = 10,
93 .bInterval = 3,
94 },
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020095 },
96 .on = {
97 .intf = {
98 .bLength = sizeof(struct usb_intf_desc),
99 .bDescriptorType = USB_DT_INTF,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100100 .bInterfaceNumber = USB_INTF_E1(0),
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200101 .bAlternateSetting = 1,
Harald Welte805f2cf2020-12-14 17:31:03 +0100102 .bNumEndpoints = 4,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200103 .bInterfaceClass = 0xff,
104 .bInterfaceSubClass = 0xe1,
105 .bInterfaceProtocol = 0x00,
106 .iInterface = 5,
107 },
108 .ep_data_in = {
109 .bLength = sizeof(struct usb_ep_desc),
110 .bDescriptorType = USB_DT_EP,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100111 .bEndpointAddress = USB_EP_E1_IN(0),
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200112 .bmAttributes = 0x05,
113 .wMaxPacketSize = 388,
114 .bInterval = 1,
115 },
116 .ep_data_out = {
117 .bLength = sizeof(struct usb_ep_desc),
118 .bDescriptorType = USB_DT_EP,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100119 .bEndpointAddress = USB_EP_E1_OUT(0),
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200120 .bmAttributes = 0x05,
121 .wMaxPacketSize = 388,
122 .bInterval = 1,
123 },
124 .ep_fb = {
125 .bLength = sizeof(struct usb_ep_desc),
126 .bDescriptorType = USB_DT_EP,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100127 .bEndpointAddress = USB_EP_E1_FB(0),
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200128 .bmAttributes = 0x11,
129 .wMaxPacketSize = 8,
130 .bInterval = 3,
131 },
Harald Welte805f2cf2020-12-14 17:31:03 +0100132 .ep_interrupt = {
133 .bLength = sizeof(struct usb_ep_desc),
134 .bDescriptorType = USB_DT_EP,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100135 .bEndpointAddress = USB_EP_E1_INT(0),
Harald Welte805f2cf2020-12-14 17:31:03 +0100136 .bmAttributes = 0x03,
137 .wMaxPacketSize = 10,
138 .bInterval = 3,
139 },
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200140 },
141 },
142#if 0
143 .cdc = {
144 .intf_ctl = {
145 .bLength = sizeof(struct usb_intf_desc),
146 .bDescriptorType = USB_DT_INTF,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100147 .bInterfaceNumber = USB_INTF_GPS_CDC_CTL,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200148 .bAlternateSetting = 0,
149 .bNumEndpoints = 1,
Sylvain Munautb9d93632021-05-31 14:03:44 +0200150 .bInterfaceClass = USB_CLS_CDC_CONTROL,
151 .bInterfaceSubClass = USB_CDC_SCLS_ACM,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200152 .bInterfaceProtocol = 0x00,
153 .iInterface = 6,
154 },
Sylvain Munautb9d93632021-05-31 14:03:44 +0200155 .cdc_hdr = {
156 .bLength = sizeof(struct usb_cdc_hdr_desc),
157 .bDescriptorType = USB_CS_DT_INTF,
158 .bDescriptorsubtype = USB_CDC_DST_HEADER,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200159 .bcdCDC = 0x0110,
160 },
Sylvain Munautb9d93632021-05-31 14:03:44 +0200161 .cdc_acm = {
162 .bLength = sizeof(struct usb_cdc_acm_desc),
163 .bDescriptorType = USB_CS_DT_INTF,
164 .bDescriptorsubtype = USB_CDC_DST_ACM,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200165 .bmCapabilities = 0x02,
166 },
Sylvain Munautb9d93632021-05-31 14:03:44 +0200167 .cdc_union = {
168 .bLength = sizeof(struct usb_cdc_union_desc) + 1,
169 .bDescriptorType = USB_CS_DT_INTF,
170 .bDescriptorsubtype = USB_CDC_DST_UNION,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200171 .bMasterInterface = 1,
Sylvain Munautb9d93632021-05-31 14:03:44 +0200172 .bSlaveInterface = { 2 },
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200173 },
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200174 .ep_ctl = {
175 .bLength = sizeof(struct usb_ep_desc),
176 .bDescriptorType = USB_DT_EP,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100177 .bEndpointAddress = USB_EP_GPS_CDC_CTL,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200178 .bmAttributes = 0x03,
179 .wMaxPacketSize = 64,
180 .bInterval = 0x40,
181 },
182 .intf_data = {
183 .bLength = sizeof(struct usb_intf_desc),
184 .bDescriptorType = USB_DT_INTF,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100185 .bInterfaceNumber = USB_INTF_GPS_CDC_DATA,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200186 .bAlternateSetting = 0,
187 .bNumEndpoints = 2,
Sylvain Munautb9d93632021-05-31 14:03:44 +0200188 .bInterfaceClass = USB_CLS_CDC_DATA,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200189 .bInterfaceSubClass = 0x00,
190 .bInterfaceProtocol = 0x00,
191 .iInterface = 7,
192 },
193 .ep_data_out = {
194 .bLength = sizeof(struct usb_ep_desc),
195 .bDescriptorType = USB_DT_EP,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100196 .bEndpointAddress = USB_EP_GPS_CDC_OUT,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200197 .bmAttributes = 0x02,
198 .wMaxPacketSize = 64,
199 .bInterval = 0x00,
200 },
201 .ep_data_in = {
202 .bLength = sizeof(struct usb_ep_desc),
203 .bDescriptorType = USB_DT_EP,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100204 .bEndpointAddress = USB_EP_GPS_CDC_IN,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200205 .bmAttributes = 0x02,
206 .wMaxPacketSize = 64,
207 .bInterval = 0x00,
208 },
209 },
210#endif
211 .dfu = {
212 .intf = {
213 .bLength = sizeof(struct usb_intf_desc),
214 .bDescriptorType = USB_DT_INTF,
Sylvain Munaut8a5a9d42022-01-03 18:44:33 +0100215 .bInterfaceNumber = USB_INTF_DFU,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200216 .bAlternateSetting = 0,
217 .bNumEndpoints = 0,
218 .bInterfaceClass = 0xfe,
219 .bInterfaceSubClass = 0x01,
220 .bInterfaceProtocol = 0x01,
221 .iInterface = 8,
222 },
223 .func = {
Sylvain Munaut4ea7d272020-10-29 13:17:11 +0100224 .bLength = sizeof(struct usb_dfu_func_desc),
225 .bDescriptorType = USB_DFU_DT_FUNC,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200226 .bmAttributes = 0x0d,
Sylvain Munaut3c3ae792022-01-05 20:55:37 +0100227 .wDetachTimeOut = 0,
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200228 .wTransferSize = 4096,
229 .bcdDFUVersion = 0x0101,
230 },
231 },
232};
233
234static const struct usb_conf_desc * const _conf_desc_array[] = {
235 &_app_conf_desc.conf,
236};
237
238static const struct usb_dev_desc _dev_desc = {
239 .bLength = sizeof(struct usb_dev_desc),
240 .bDescriptorType = USB_DT_DEV,
241 .bcdUSB = 0x0200,
242 .bDeviceClass = 0,
243 .bDeviceSubClass = 0,
244 .bDeviceProtocol = 0,
245 .bMaxPacketSize0 = 64,
246 .idVendor = 0x1d50,
247 .idProduct = 0x6145,
248 .bcdDevice = 0x0003, /* v0.3 */
249 .iManufacturer = 2,
250 .iProduct = 3,
251 .iSerialNumber = 1,
252 .bNumConfigurations = num_elem(_conf_desc_array),
253};
254
255#include "usb_str_app.gen.h"
256
257const struct usb_stack_descriptors app_stack_desc = {
258 .dev = &_dev_desc,
259 .conf = _conf_desc_array,
260 .n_conf = num_elem(_conf_desc_array),
261 .str = _str_desc_array,
262 .n_str = num_elem(_str_desc_array),
263};