1 #include <asm/arch/sci_types.h>
2 #include <linux/usb/ch9.h>
3 #include <linux/usb/cdc.h>
4 #include <linux/usb/gadget.h>
5 #include <linux/byteorder/little_endian.h>
6 #include <linux/string.h>
8 #define THOR_VENDOR_NUM 0x04E8
9 #define THOR_PRODUCT_NUM 0x685D
11 typedef struct { __le16 val; } __attribute__((aligned(16))) __le16_packed;
13 static struct usb_device_descriptor thor_device_desc_high __align (32)= {
14 .bLength = sizeof(thor_device_desc_high),
15 .bDescriptorType = USB_DT_DEVICE,
17 .bcdUSB = __constant_cpu_to_le16(0x0200),
18 .bDeviceClass = USB_CLASS_COMM,
20 .bDeviceSubClass = 0x02,
21 .bDeviceProtocol = 0x00,
23 .bMaxPacketSize0 = 64,
25 .idVendor = __constant_cpu_to_le16(THOR_VENDOR_NUM),
26 .idProduct = __constant_cpu_to_le16(THOR_PRODUCT_NUM),
27 .bcdDevice = cpu_to_le16(0x021B),
29 .iManufacturer = 0x01,
32 .iSerialNumber = 0x00,
33 .bNumConfigurations = 0x01,
36 static struct usb_device_descriptor thor_device_desc_full __align (32) = {
37 .bLength = sizeof(thor_device_desc_full),
38 .bDescriptorType = USB_DT_DEVICE,
40 .bcdUSB = __constant_cpu_to_le16(0x0101),
41 .bDeviceClass = USB_CLASS_COMM,
43 .bDeviceSubClass = 0x02,
44 .bDeviceProtocol = 0x00,
46 .bMaxPacketSize0 = 64,
48 .idVendor = __constant_cpu_to_le16(THOR_VENDOR_NUM),
49 .idProduct = __constant_cpu_to_le16(THOR_PRODUCT_NUM),
50 .bcdDevice = cpu_to_le16(0x021B),
52 .iManufacturer = 0x01,
55 .iSerialNumber = 0x00,
56 .bNumConfigurations = 0x01,
59 /* function descriptor */
60 static const struct usb_config_descriptor thor_config_desc __align (32) = {
61 .bLength = sizeof(thor_config_desc),
62 .bDescriptorType = USB_DT_CONFIG,
64 .wTotalLength = __constant_cpu_to_le16(67),
66 .bNumInterfaces = 0x02,
67 .bConfigurationValue = 0x01,
68 .iConfiguration = 0x00,
70 .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
74 static struct usb_interface_descriptor thor_downloader_intf_init __align (32) = {
75 .bLength = sizeof(thor_downloader_intf_init),
76 .bDescriptorType = USB_DT_INTERFACE,
78 .bInterfaceNumber = 0,
79 .bAlternateSetting = 0,
82 .bInterfaceClass = USB_CLASS_COMM,
84 .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
85 .bInterfaceProtocol = USB_CDC_ACM_PROTO_AT_V25TER,
89 static const struct usb_cdc_header_desc thor_downloader_func_desc __align (32) = {
90 .bLength = sizeof(thor_downloader_func_desc),
91 .bDescriptorType = USB_DT_CS_INTERFACE,
92 .bDescriptorSubType = USB_CDC_HEADER_TYPE,
93 .bcdCDC = __constant_cpu_to_le16(0x0110),
96 static struct usb_cdc_call_mgmt_descriptor thor_downloader_func_desc_call __align (32) = {
97 .bLength = sizeof(thor_downloader_func_desc_call),
98 .bDescriptorType = USB_DT_CS_INTERFACE,
99 .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE,
100 .bmCapabilities = 0x00,
101 .bDataInterface = 0x01,
104 static struct usb_cdc_acm_descriptor thor_downloader_func_desc_abstract __align (32) = {
106 .bDescriptorType = USB_DT_CS_INTERFACE,
107 .bDescriptorSubType = USB_CDC_ACM_TYPE,
108 .bmCapabilities = 0x0F,
111 static struct usb_cdc_union_desc thor_downloader_cdc_union __align (32) = {
113 .bDescriptorType = USB_DT_CS_INTERFACE,
114 .bDescriptorSubType = USB_CDC_UNION_TYPE,
115 .bMasterInterface0 = 0x00,
116 .bSlaveInterface0 = 0x01,
119 static struct usb_endpoint_descriptor thor_downloader_ep3_in __align (32) = {
120 .bLength = USB_DT_ENDPOINT_SIZE,
121 .bDescriptorType = USB_DT_ENDPOINT,
122 .bEndpointAddress = 0x83,
123 .bmAttributes = USB_ENDPOINT_XFER_INT,
124 .wMaxPacketSize = __constant_cpu_to_le16(16),
128 static const struct usb_interface_descriptor thor_downloader_intf_data __align (32) = {
129 .bLength = USB_DT_INTERFACE_SIZE,
130 .bDescriptorType = USB_DT_INTERFACE,
132 .bInterfaceNumber = 1,
133 .bAlternateSetting = 0,
136 .bInterfaceClass = USB_CLASS_CDC_DATA,
138 .bInterfaceSubClass = 0,
139 .bInterfaceProtocol = 0,
143 static struct usb_endpoint_descriptor thor_downloader_ep1_in __align (32) = {
144 .bLength = USB_DT_ENDPOINT_SIZE,
145 .bDescriptorType = USB_DT_ENDPOINT,
146 .bEndpointAddress = 0x81,
147 .bmAttributes = USB_ENDPOINT_XFER_BULK,
148 .wMaxPacketSize = __constant_cpu_to_le16(512),
152 static struct usb_endpoint_descriptor thor_downloader_ep2_out __align (32) = {
153 .bLength = USB_DT_ENDPOINT_SIZE,
154 .bDescriptorType = USB_DT_ENDPOINT,
155 .bEndpointAddress = 0x02,
156 .bmAttributes = USB_ENDPOINT_XFER_BULK,
157 .wMaxPacketSize = __constant_cpu_to_le16(512),
161 static const struct usb_descriptor_header *thor_function_high[] __align (32) = {
162 (struct usb_descriptor_header *) &thor_downloader_intf_init,
163 (struct usb_descriptor_header *) &thor_downloader_func_desc,
164 (struct usb_descriptor_header *) &thor_downloader_func_desc_call,
165 (struct usb_descriptor_header *) &thor_downloader_func_desc_abstract,
166 (struct usb_descriptor_header *) &thor_downloader_cdc_union,
167 (struct usb_descriptor_header *) &thor_downloader_ep3_in,
168 (struct usb_descriptor_header *) &thor_downloader_intf_data,
169 (struct usb_descriptor_header *) &thor_downloader_ep1_in,
170 (struct usb_descriptor_header *) &thor_downloader_ep2_out,
173 static struct usb_cdc_acm_descriptor thor_downloader_func_desc_abstract_full __align (32) = {
175 .bDescriptorType = USB_DT_CS_INTERFACE,
176 .bDescriptorSubType = USB_CDC_ACM_TYPE,
177 .bmCapabilities = 0x00,
180 static struct usb_endpoint_descriptor thor_downloader_ep1_in_full __align (32) = {
181 .bLength = USB_DT_ENDPOINT_SIZE,
182 .bDescriptorType = USB_DT_ENDPOINT,
183 .bEndpointAddress = 0x81,
184 .bmAttributes = USB_ENDPOINT_XFER_BULK,
185 .wMaxPacketSize = __constant_cpu_to_le16(64),
189 static struct usb_endpoint_descriptor thor_downloader_ep2_out_full __align (32) = {
190 .bLength = USB_DT_ENDPOINT_SIZE,
191 .bDescriptorType = USB_DT_ENDPOINT,
192 .bEndpointAddress = 0x02,
193 .bmAttributes = USB_ENDPOINT_XFER_BULK,
194 .wMaxPacketSize = __constant_cpu_to_le16(64),
198 static const struct usb_descriptor_header *thor_function_full[] __align (32) = {
199 (struct usb_descriptor_header *) &thor_downloader_intf_init,
200 (struct usb_descriptor_header *) &thor_downloader_func_desc,
201 (struct usb_descriptor_header *) &thor_downloader_func_desc_call,
202 (struct usb_descriptor_header *) &thor_downloader_func_desc_abstract_full,
203 (struct usb_descriptor_header *) &thor_downloader_cdc_union,
204 (struct usb_descriptor_header *) &thor_downloader_ep3_in,
205 (struct usb_descriptor_header *) &thor_downloader_intf_data,
206 (struct usb_descriptor_header *) &thor_downloader_ep1_in_full,
207 (struct usb_descriptor_header *) &thor_downloader_ep2_out_full,
210 static char function_desc_buf[67] __align(32);
212 #define CONFIG_THOR_STRING_PRODUCT "SAMSUNG USB DRIVER"
213 static char string_product[2 + 2 * (sizeof(CONFIG_THOR_STRING_PRODUCT) - 1)] __align(32);
215 #define CONFIG_THOR_STRING_MANUFACTURER "SAMSUNG"
216 static char string_manufacturer[2 + 2 * (sizeof(CONFIG_THOR_STRING_MANUFACTURER) - 1)] __align(32);
218 static char string_lang_ids[4] __align (32) = {4, USB_DT_STRING, 0x9, 0x4};
220 #define CONFIG_THOR_STRING_INTERFACE "CDC Abstract Control Model"
221 static char string_interface[2 + 2 * (sizeof(CONFIG_THOR_STRING_INTERFACE) - 1)] __align(32);
223 #define CONFIG_THOR_STRING_CONTROL "SAMSUNG SERIAL CONTROL"
224 static char string_control[2 + 2 * (sizeof(CONFIG_THOR_STRING_CONTROL) - 1)] __align(32);
226 static struct usb_qualifier_descriptor thor_dev_qualifier_desc __align(32) = {
227 .bLength = sizeof(thor_dev_qualifier_desc),
228 .bDescriptorType = USB_DT_DEVICE_QUALIFIER,
229 .bcdUSB = __constant_cpu_to_le16(0x0200),
230 .bDeviceClass = USB_CLASS_VENDOR_SPEC,
232 .bDeviceSubClass = 0x00,
233 .bDeviceProtocol = 0x00,
234 .bMaxPacketSize0 = 64,
236 .bNumConfigurations = 0x01,
240 unsigned char g_USB_Other_Speed_ConfigDescr[] __align(32) =
242 0x09,0x07,0x43,0x00,0x02,0x01,0x00,0xC0,
244 0x09,0x04,0x00,0x00,0x01,0x02,0x02,0x01,
246 0x05,0x24,0x00,0x10,0x01,
247 0x05,0x24,0x01,0x00,0x01,
249 0x05,0x24,0x06,0x00,0x01,
250 0x07,0x05,0x83,0x03,0x10,0x00,0x9, //Ep 3 In 64
251 0x09,0x04,0x01,0x00,0x02,0x0A,0x00,0x00,
253 0x07,0x05,0x81,0x02,0x40,0x00,0x00, //Ep 1 In 64
254 0x07,0x05,0x02,0x02,0x40,0x00,0x00, //Ep 2 OUT 64
257 unsigned char *thor_get_device_desc(unsigned int speed)
259 if (speed == 0x00) /* USB HIGH */
260 return (unsigned char *) &thor_device_desc_high;
262 return (unsigned char *) &thor_device_desc_full;
265 unsigned char *thor_get_config_desc(unsigned int speed)
267 usb_gadget_config_buf(&thor_config_desc, &function_desc_buf, 256, thor_function_high);
269 if (speed == 0x00) /* USB_HIGH */
270 usb_gadget_config_buf(&thor_config_desc, &function_desc_buf, 256, thor_function_high);
272 usb_gadget_config_buf(&thor_config_desc, &function_desc_buf, 256, thor_function_full);
274 return (unsigned char *) &function_desc_buf;
277 static void str2wide (char *str, void *wide)
280 __le16_packed *tmp = wide;
281 for (i = 0; i < strlen (str) && str[i]; i++){
282 #if defined(__LITTLE_ENDIAN)
283 tmp[i].val = (u16) str[i];
284 #elif defined(__BIG_ENDIAN)
285 tmp[i].val = ((u16)(str[i])<<8);
287 #error "__LITTLE_ENDIAN or __BIG_ENDIAN undefined"
292 unsigned char *thor_get_string_desc(unsigned char index)
294 struct usb_string_descriptor *string;
298 string = (struct usb_string_descriptor *) string_lang_ids;
300 return (unsigned char *) string_lang_ids;
302 string = (struct usb_string_descriptor *) string_manufacturer;
303 string->bLength = sizeof(string_manufacturer);
304 string->bDescriptorType = USB_DT_STRING;
305 str2wide(CONFIG_THOR_STRING_MANUFACTURER, string->wData);
307 return (unsigned char *) string;
309 string = (struct usb_string_descriptor *) string_interface;
310 string->bLength = sizeof(string_interface);
311 string->bDescriptorType = USB_DT_STRING;
312 str2wide(CONFIG_THOR_STRING_INTERFACE, string->wData);
314 return (unsigned char *) string;
316 string = (struct usb_string_descriptor *) string_control;
317 string->bLength = sizeof(string_control);
318 string->bDescriptorType = USB_DT_STRING;
319 str2wide(CONFIG_THOR_STRING_CONTROL, string->wData);
321 return (unsigned char *) string;
324 string = (struct usb_string_descriptor *) string_product;
325 string->bLength = sizeof(string_product);
326 string->bDescriptorType = USB_DT_STRING;
327 str2wide(CONFIG_THOR_STRING_PRODUCT, string->wData);
329 return (unsigned char *) string;
335 unsigned char *thor_get_qualifer_desc(void)
337 return (unsigned char *) &thor_dev_qualifier_desc;
340 unsigned char *thor_get_other_speed_config_desc(void)
342 return (unsigned char *) g_USB_Other_Speed_ConfigDescr;