altos/chaoskey: Add another USB endpoint to read raw data
[fw/altos] / src / kernel / ao_product.c
1 /*
2  * Copyright © 2009 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 #include "ao.h"
19 #include "ao_product.h"
20
21 /* Defines which mark this particular AltOS product */
22
23 const char ao_version[AO_MAX_VERSION] = AO_iVersion_STRING;
24 const char ao_manufacturer[] = AO_iManufacturer_STRING;
25 const char ao_product[] = AO_iProduct_STRING;
26
27 #define LE_WORD(x)    ((x)&0xFF),((uint8_t) (((uint16_t) (x))>>8))
28
29 #if HAS_USB
30
31 /* Maximum power in mA */
32 #ifndef AO_USB_MAX_POWER
33 #define AO_USB_MAX_POWER        100
34 #endif
35
36 #ifndef AO_USB_SELF_POWER
37 #define AO_USB_SELF_POWER       1
38 #endif
39
40 #define AO_USB_DEVICE_CLASS_COMMUNICATION       0x02
41 #define AO_USB_INTERFACE_CLASS_CONTROL_CDC      0x02
42 #define AO_USB_INTERFACE_CLASS_DATA_CDC         0x0A
43
44 #ifndef AO_USB_DEVICE_CLASS
45 #define AO_USB_DEVICE_CLASS             AO_USB_DEVICE_CLASS_COMMUNICATION
46 #endif
47
48 #ifndef AO_USB_INTERFACE_CLASS_DATA
49 #define AO_USB_INTERFACE_CLASS_CONTROL  AO_USB_INTERFACE_CLASS_CONTROL_CDC
50 #define AO_USB_INTERFACE_CLASS_DATA     AO_USB_INTERFACE_CLASS_DATA_CDC
51 #endif
52
53 #include "ao_usb.h"
54
55 #define HEADER_LEN              9
56 #define CONTROL_CLASS_LEN       35
57 #define DATA_LEN                (9 + 7 * AO_USB_HAS_OUT + 7 * AO_USB_HAS_IN + 7 * AO_USB_HAS_IN2)
58
59 #define TOTAL_LENGTH            (HEADER_LEN + AO_USB_HAS_INT * CONTROL_CLASS_LEN + DATA_LEN)
60 #define NUM_INTERFACES          (AO_USB_HAS_INT + 1)
61
62 /* USB descriptors in one giant block of bytes */
63 AO_ROMCONFIG_SYMBOL(0x00aa) uint8_t ao_usb_descriptors [] =
64 {
65         /* Device descriptor */
66         0x12,
67         AO_USB_DESC_DEVICE,
68         LE_WORD(0x0110),        /*  bcdUSB */
69         AO_USB_DEVICE_CLASS,    /*  bDeviceClass */
70         0x00,                   /*  bDeviceSubClass */
71         0x00,                   /*  bDeviceProtocol */
72         AO_USB_CONTROL_SIZE,    /*  bMaxPacketSize */
73         LE_WORD(AO_idVendor_NUMBER),    /*  idVendor */
74         LE_WORD(AO_idProduct_NUMBER),   /*  idProduct */
75         LE_WORD(0x0100),        /*  bcdDevice */
76         0x01,                   /*  iManufacturer */
77         0x02,                   /*  iProduct */
78         0x03,                   /*  iSerialNumber */
79         0x01,                   /*  bNumConfigurations */
80
81         /* Configuration descriptor */
82         0x09,
83         AO_USB_DESC_CONFIGURATION,
84         LE_WORD(TOTAL_LENGTH),  /*  wTotalLength */
85         NUM_INTERFACES,         /*  bNumInterfaces */
86         0x01,                   /*  bConfigurationValue */
87         0x00,                   /*  iConfiguration */
88         0x80 | (AO_USB_SELF_POWER << 6),        /*  bmAttributes */
89         AO_USB_MAX_POWER >> 1,  /*  bMaxPower, 2mA units */
90
91 #if AO_USB_HAS_INT
92         /* Control class interface */
93         0x09,
94         AO_USB_DESC_INTERFACE,
95         0x00,                   /*  bInterfaceNumber */
96         0x00,                   /*  bAlternateSetting */
97         0x01,                   /*  bNumEndPoints */
98         AO_USB_INTERFACE_CLASS_CONTROL, /*  bInterfaceClass */
99         0x02,                   /*  bInterfaceSubClass */
100         0x01,                   /*  bInterfaceProtocol, linux requires value of 1 for the cdc_acm module */
101         0x00,                   /*  iInterface */
102
103         /* Header functional descriptor */
104         0x05,
105         AO_USB_CS_INTERFACE,
106         0x00,                   /*  bDescriptor SubType Header */
107         LE_WORD(0x0110),        /*  CDC version 1.1 */
108
109         /* Call management functional descriptor */
110         0x05,
111         AO_USB_CS_INTERFACE,
112         0x01,                   /* bDescriptor SubType Call Management */
113         0x01,                   /* bmCapabilities = device handles call management */
114         0x01,                   /* bDataInterface call management interface number */
115
116         /* ACM functional descriptor */
117         0x04,
118         AO_USB_CS_INTERFACE,
119         0x02,                   /* bDescriptor SubType Abstract Control Management */
120         0x02,                   /* bmCapabilities = D1 (Set_line_Coding, Set_Control_Line_State, Get_Line_Coding and Serial_State) */
121
122         /* Union functional descriptor */
123         0x05,
124         AO_USB_CS_INTERFACE,
125         0x06,                   /* bDescriptor SubType Union Functional descriptor */
126         0x00,                   /* bMasterInterface */
127         0x01,                   /* bSlaveInterface0 */
128
129         /* Notification EP */
130         0x07,
131         AO_USB_DESC_ENDPOINT,
132         AO_USB_INT_EP|0x80,     /* bEndpointAddress */
133         0x03,                   /* bmAttributes = intr */
134         LE_WORD(8),             /* wMaxPacketSize */
135         0xff,                   /* bInterval */
136 #endif
137
138         /* Data class interface descriptor */
139         0x09,
140         AO_USB_DESC_INTERFACE,
141         AO_USB_HAS_INT,                 /* bInterfaceNumber */
142         0x00,                           /* bAlternateSetting */
143         AO_USB_HAS_OUT + AO_USB_HAS_IN + AO_USB_HAS_IN2,        /* bNumEndPoints */
144         AO_USB_INTERFACE_CLASS_DATA,    /* bInterfaceClass = data */
145         0x00,                           /* bInterfaceSubClass */
146         0x00,                           /* bInterfaceProtocol */
147         0x00,                           /* iInterface */
148
149 #if AO_USB_HAS_OUT
150         /* Data EP OUT */
151         0x07,
152         AO_USB_DESC_ENDPOINT,
153         AO_USB_OUT_EP,          /* bEndpointAddress */
154         0x02,                   /* bmAttributes = bulk */
155         LE_WORD(AO_USB_OUT_SIZE),/* wMaxPacketSize */
156         0x00,                   /* bInterval */
157 #endif
158
159 #if AO_USB_HAS_IN
160         /* Data EP in */
161         0x07,
162         AO_USB_DESC_ENDPOINT,
163         AO_USB_IN_EP|0x80,      /* bEndpointAddress */
164         0x02,                   /* bmAttributes = bulk */
165         LE_WORD(AO_USB_IN_SIZE),/* wMaxPacketSize */
166         0x00,                   /* bInterval */
167 #endif
168
169 #if AO_USB_HAS_IN2
170         /* Data EP in 2 */
171         0x07,
172         AO_USB_DESC_ENDPOINT,
173         AO_USB_IN2_EP|0x80,     /* bEndpointAddress */
174         0x02,                   /* bmAttributes = bulk */
175         LE_WORD(AO_USB_IN_SIZE),/* wMaxPacketSize */
176         0x00,                   /* bInterval */
177 #endif
178
179         /* String descriptors */
180         0x04,
181         AO_USB_DESC_STRING,
182         LE_WORD(0x0409),
183
184         /* iManufacturer */
185         AO_iManufacturer_LEN,
186         AO_USB_DESC_STRING,
187         AO_iManufacturer_UCS2,
188
189         /* iProduct */
190         AO_iProduct_LEN,
191         AO_USB_DESC_STRING,
192         AO_iProduct_UCS2,
193
194         /* iSerial */
195         AO_iSerial_LEN,
196         AO_USB_DESC_STRING,
197         AO_iSerial_UCS2,
198
199         /* Terminating zero */
200         0
201 };
202 #endif