1 /*
2  * Copyright (c) 2013 Travis Geiselbrecht
3  *
4  * Use of this source code is governed by a MIT-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/MIT
7  */
8 #include <lk/err.h>
9 #include <lk/debug.h>
10 #include <stdio.h>
11 #include <target.h>
12 #include <lk/compiler.h>
13 #include <dev/usb.h>
14 #include <hw/usb.h>
15 #include <lk/init.h>
16 
17 #define W(w) (w & 0xff), (w >> 8)
18 #define W3(w) (w & 0xff), ((w >> 8) & 0xff), ((w >> 16) & 0xff)
19 
20 /* top level device descriptor */
21 static const uint8_t dev_descr[] = {
22     0x12,           /* descriptor length */
23     DEVICE,         /* Device Descriptor type */
24     W(0x0200),      /* USB Version */
25     0xff,           /* class */
26     0xff,           /* subclass */
27     0xff,           /* protocol */
28     64,             /* max packet size, ept0 */
29     W(0x9999),      /* vendor */
30     W(0x9999),      /* product */
31     W(0x9999),      /* release */
32     0x0,            /* manufacturer string */
33     0x0,            /* product string */
34     0x0,            /* serialno string */
35     0x1,            /* num configs */
36 };
37 
38 /* high/low speed device qualifier */
39 static const uint8_t devqual_descr[] = {
40     0x0a,           /* len */
41     DEVICE_QUALIFIER, /* Device Qualifier type */
42     W(0x0200),      /* USB version */
43     0x00,           /* class */
44     0x00,           /* subclass */
45     0x00,           /* protocol */
46     64,             /* max packet size, ept0 */
47     0x01,           /* num configs */
48     0x00            /* reserved */
49 };
50 
51 static const uint8_t cfg_descr[] = {
52     0x09,           /* Length of Cfg Descr */
53     CONFIGURATION,  /* Type of Cfg Descr */
54     W(0x09),        /* Total Length (incl ifc, ept) */
55     0x00,           /* # Interfaces */
56     0x01,           /* Cfg Value */
57     0x00,           /* Cfg String */
58     0xc0,           /* Attributes -- self powered */
59     250,            /* Power Consumption - 500mA */
60 };
61 
62 static const uchar langid[] = { 0x04, 0x03, 0x09, 0x04 };
63 
64 static const uint8_t if_descriptor_lowspeed[] = {
65     0x09,           /* length */
66     INTERFACE,      /* type */
67     0x01,           /* interface num */
68     0x00,           /* alternates */
69     0x02,           /* endpoint count */
70     0xff,           /* interface class */
71     0xff,           /* interface subclass */
72     0x00,           /* interface protocol */
73     0x00,           /* string index */
74 
75     /* endpoint 1 IN */
76     0x07,           /* length */
77     ENDPOINT,       /* type */
78     0x81,           /* address: 1 IN */
79     0x02,           /* type: bulk */
80     W(64),          /* max packet size: 64 */
81     00,             /* interval */
82 
83     /* endpoint 1 OUT */
84     0x07,           /* length */
85     ENDPOINT,       /* type */
86     0x01,           /* address: 1 OUT */
87     0x02,           /* type: bulk */
88     W(64),          /* max packet size: 64 */
89     00,             /* interval */
90 };
91 
92 usb_config config = {
93     .lowspeed = {
94         .device = USB_DESC_STATIC(dev_descr),
95         .device_qual = USB_DESC_STATIC(devqual_descr),
96         .config = USB_DESC_STATIC(cfg_descr),
97     },
98     .highspeed = {
99         .device = USB_DESC_STATIC(dev_descr),
100         .device_qual = USB_DESC_STATIC(devqual_descr),
101         .config = USB_DESC_STATIC(cfg_descr),
102     },
103 
104     .langid = USB_DESC_STATIC(langid),
105 };
106 
target_usb_setup(void)107 void target_usb_setup(void) {
108     usb_setup(&config);
109     printf("appending interfaces\n");
110     usb_append_interface_lowspeed(if_descriptor_lowspeed, sizeof(if_descriptor_lowspeed));
111     usb_append_interface_highspeed(if_descriptor_lowspeed, sizeof(if_descriptor_lowspeed));
112 
113     usb_start();
114 }
115