6dba80f91ef650e9dc133dc213c485db3d1207d8
[profile/mobile/platform/kernel/u-boot-tm1.git] / property / usb / cdc_descriptor.c
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>
7
8 #define THOR_VENDOR_NUM                 0x04E8
9 #define THOR_PRODUCT_NUM                0x685D
10
11 typedef struct { __le16 val; } __attribute__((aligned(16))) __le16_packed;
12
13 static struct usb_device_descriptor thor_device_desc_high __align (32)= {
14         .bLength                        = sizeof(thor_device_desc_high),
15         .bDescriptorType        = USB_DT_DEVICE,
16
17         .bcdUSB                         = __constant_cpu_to_le16(0x0200),
18         .bDeviceClass           = USB_CLASS_COMM,
19
20         .bDeviceSubClass        = 0x02,
21         .bDeviceProtocol        = 0x00,
22
23         .bMaxPacketSize0        = 64,
24
25         .idVendor                       = __constant_cpu_to_le16(THOR_VENDOR_NUM),
26         .idProduct                      = __constant_cpu_to_le16(THOR_PRODUCT_NUM),
27         .bcdDevice                      = cpu_to_le16(0x021B),
28
29         .iManufacturer          = 0x01,
30         .iProduct                       = 0x02,
31
32         .iSerialNumber          = 0x00,
33         .bNumConfigurations     = 0x01,
34 };
35
36 static struct usb_device_descriptor thor_device_desc_full __align (32) = {
37         .bLength                        = sizeof(thor_device_desc_full),
38         .bDescriptorType        = USB_DT_DEVICE,
39
40         .bcdUSB                         = __constant_cpu_to_le16(0x0101),
41         .bDeviceClass           = USB_CLASS_COMM,
42
43         .bDeviceSubClass        = 0x02,
44         .bDeviceProtocol        = 0x00,
45
46         .bMaxPacketSize0        = 64,
47
48         .idVendor                       = __constant_cpu_to_le16(THOR_VENDOR_NUM),
49         .idProduct                      = __constant_cpu_to_le16(THOR_PRODUCT_NUM),
50         .bcdDevice                      = cpu_to_le16(0x021B),
51
52         .iManufacturer          = 0x01,
53         .iProduct                       = 0x02,
54
55         .iSerialNumber          = 0x00,
56         .bNumConfigurations     = 0x01,
57 };
58
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,
63
64         .wTotalLength                   = __constant_cpu_to_le16(67),
65
66         .bNumInterfaces                 = 0x02,
67         .bConfigurationValue    = 0x01,
68         .iConfiguration                 = 0x00,
69
70         .bmAttributes                   = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
71         .bMaxPower                              = 0x19,
72 };
73
74 static struct usb_interface_descriptor thor_downloader_intf_init __align (32) = {
75         .bLength                                = sizeof(thor_downloader_intf_init),
76         .bDescriptorType                = USB_DT_INTERFACE,
77
78         .bInterfaceNumber               = 0,
79         .bAlternateSetting              = 0,
80         .bNumEndpoints                  = 1,
81
82         .bInterfaceClass                = USB_CLASS_COMM,
83
84         .bInterfaceSubClass             = USB_CDC_SUBCLASS_ACM,
85         .bInterfaceProtocol             = USB_CDC_ACM_PROTO_AT_V25TER,
86         .iInterface                             = 3,
87 };
88
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),
94 };
95
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,
102 };
103
104 static struct usb_cdc_acm_descriptor thor_downloader_func_desc_abstract __align (32) = {
105         .bLength                                = 0x04,
106         .bDescriptorType                = USB_DT_CS_INTERFACE,
107         .bDescriptorSubType             = USB_CDC_ACM_TYPE,
108         .bmCapabilities                 = 0x0F,
109 };
110
111 static struct usb_cdc_union_desc thor_downloader_cdc_union __align (32) = {
112         .bLength                                = 0x05,
113         .bDescriptorType                = USB_DT_CS_INTERFACE,
114         .bDescriptorSubType             = USB_CDC_UNION_TYPE,
115         .bMasterInterface0              = 0x00,
116         .bSlaveInterface0               = 0x01,
117 };
118
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),
125         .bInterval = 0x9,
126 };
127
128 static const struct usb_interface_descriptor thor_downloader_intf_data __align (32) = {
129         .bLength                                = USB_DT_INTERFACE_SIZE,
130         .bDescriptorType                = USB_DT_INTERFACE,
131
132         .bInterfaceNumber               = 1,
133         .bAlternateSetting              = 0,
134
135         .bNumEndpoints                  = 2,
136         .bInterfaceClass                = USB_CLASS_CDC_DATA,
137
138         .bInterfaceSubClass             = 0,
139         .bInterfaceProtocol             = 0,
140         .iInterface                             = 4,
141 };
142
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),
149         .bInterval                      = 0,
150 };
151
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),
158         .bInterval                      = 0,
159 };
160
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,
171 };
172
173 static struct usb_cdc_acm_descriptor thor_downloader_func_desc_abstract_full __align (32) = {
174         .bLength                                = 0x04,
175         .bDescriptorType                = USB_DT_CS_INTERFACE,
176         .bDescriptorSubType             = USB_CDC_ACM_TYPE,
177         .bmCapabilities                 = 0x00,
178 };
179
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),
186         .bInterval                      = 0,
187 };
188
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),
195         .bInterval                      = 0,
196 };
197
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,
208 };
209
210 static char function_desc_buf[67] __align(32);
211
212 #define CONFIG_THOR_STRING_PRODUCT                      "SAMSUNG USB DRIVER"
213 static char string_product[2 + 2 * (sizeof(CONFIG_THOR_STRING_PRODUCT) - 1)] __align(32);
214
215 #define CONFIG_THOR_STRING_MANUFACTURER         "SAMSUNG"
216 static char string_manufacturer[2 + 2 * (sizeof(CONFIG_THOR_STRING_MANUFACTURER) - 1)] __align(32);
217
218 static char string_lang_ids[4] __align (32) = {4, USB_DT_STRING, 0x9, 0x4};
219
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);
222
223 #define CONFIG_THOR_STRING_CONTROL                      "SAMSUNG SERIAL CONTROL"
224 static char string_control[2 + 2 * (sizeof(CONFIG_THOR_STRING_CONTROL) - 1)] __align(32);
225
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,
231
232         .bDeviceSubClass        = 0x00,
233         .bDeviceProtocol        = 0x00,
234         .bMaxPacketSize0        = 64,
235
236         .bNumConfigurations     = 0x01,
237         .bRESERVED                      = 0x00,
238 };
239
240 unsigned char g_USB_Other_Speed_ConfigDescr[] __align(32) =
241 {
242         0x09,0x07,0x43,0x00,0x02,0x01,0x00,0xC0,
243         0x19,
244         0x09,0x04,0x00,0x00,0x01,0x02,0x02,0x01,
245         0x03,
246         0x05,0x24,0x00,0x10,0x01,
247         0x05,0x24,0x01,0x00,0x01,
248         0x04,0x24,0x02,0x0f,
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,
252         0x04,
253         0x07,0x05,0x81,0x02,0x40,0x00,0x00,  //Ep 1 In  64    
254         0x07,0x05,0x02,0x02,0x40,0x00,0x00,  //Ep 2 OUT  64                     
255 };
256
257 unsigned char *thor_get_device_desc(unsigned int speed)
258 {
259         if (speed == 0x00)              /* USB HIGH */
260                 return (unsigned char *) &thor_device_desc_high;
261         else
262                 return (unsigned char *) &thor_device_desc_full;
263 }
264
265 unsigned char *thor_get_config_desc(unsigned int speed)
266 {
267         usb_gadget_config_buf(&thor_config_desc, &function_desc_buf, 256, thor_function_high);
268
269         if (speed == 0x00)              /* USB_HIGH */
270                 usb_gadget_config_buf(&thor_config_desc, &function_desc_buf, 256, thor_function_high);
271         else
272                 usb_gadget_config_buf(&thor_config_desc, &function_desc_buf, 256, thor_function_full);
273
274         return (unsigned char *) &function_desc_buf;
275 }
276
277 static void str2wide (char *str, void *wide)
278 {
279         int i;
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);
286                 #else
287                         #error "__LITTLE_ENDIAN or __BIG_ENDIAN undefined"
288                 #endif
289         }
290 }
291
292 unsigned char *thor_get_string_desc(unsigned char index)
293 {
294         struct usb_string_descriptor *string;
295
296         switch (index) {
297                 case 0:
298                         string = (struct usb_string_descriptor *) string_lang_ids;
299
300                         return (unsigned char *) string_lang_ids;
301                 case 1:
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);
306
307                         return (unsigned char *) string;
308                 case 3:
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);
313
314                         return (unsigned char *) string;
315                 case 6:
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);
320
321                         return (unsigned char *) string;
322                 case 2:
323                 default:
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);
328
329                         return (unsigned char *) string;
330         }
331
332     return NULL;
333 }
334
335 unsigned char *thor_get_qualifer_desc(void)
336 {
337     return (unsigned char *) &thor_dev_qualifier_desc;
338 }
339
340 unsigned char *thor_get_other_speed_config_desc(void)
341 {
342     return (unsigned char *) g_USB_Other_Speed_ConfigDescr;
343 }