]> git.sur5r.net Git - u-boot/blob - drivers/usb/emul/sandbox_keyb.c
Remove unnecessary instances of DECLARE_GLOBAL_DATA_PTR
[u-boot] / drivers / usb / emul / sandbox_keyb.c
1 /*
2  * (C) Copyright 2015 Google, Inc
3  * Written by Simon Glass <sjg@chromium.org>
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <dm.h>
10 #include <os.h>
11 #include <scsi.h>
12 #include <usb.h>
13
14 /*
15  * This driver emulates a USB keyboard using the USB HID specification (boot
16  * protocol)
17  */
18
19 enum {
20         SANDBOX_KEYB_EP_IN              = 1,    /* endpoints */
21 };
22
23 enum cmd_phase {
24         PHASE_START,
25         PHASE_DATA,
26         PHASE_STATUS,
27 };
28
29 enum {
30         STRINGID_MANUFACTURER = 1,
31         STRINGID_PRODUCT,
32         STRINGID_SERIAL,
33
34         STRINGID_COUNT,
35 };
36
37 /**
38  * struct sandbox_keyb_priv - private state for this driver
39  *
40  */
41 struct sandbox_keyb_priv {
42         struct membuff in;
43 };
44
45 struct sandbox_keyb_plat {
46         struct usb_string keyb_strings[STRINGID_COUNT];
47 };
48
49 static struct usb_device_descriptor keyb_device_desc = {
50         .bLength =              sizeof(keyb_device_desc),
51         .bDescriptorType =      USB_DT_DEVICE,
52
53         .bcdUSB =               __constant_cpu_to_le16(0x0100),
54
55         .bDeviceClass =         0,
56         .bDeviceSubClass =      0,
57         .bDeviceProtocol =      0,
58
59         .idVendor =             __constant_cpu_to_le16(0x1234),
60         .idProduct =            __constant_cpu_to_le16(0x5679),
61         .iManufacturer =        STRINGID_MANUFACTURER,
62         .iProduct =             STRINGID_PRODUCT,
63         .iSerialNumber =        STRINGID_SERIAL,
64         .bNumConfigurations =   1,
65 };
66
67 static struct usb_config_descriptor keyb_config0 = {
68         .bLength                = sizeof(keyb_config0),
69         .bDescriptorType        = USB_DT_CONFIG,
70
71         /* wTotalLength is set up by usb-emul-uclass */
72         .bNumInterfaces         = 2,
73         .bConfigurationValue    = 0,
74         .iConfiguration         = 0,
75         .bmAttributes           = 1 << 7 | 1 << 5,
76         .bMaxPower              = 50,
77 };
78
79 static struct usb_interface_descriptor keyb_interface0 = {
80         .bLength                = sizeof(keyb_interface0),
81         .bDescriptorType        = USB_DT_INTERFACE,
82
83         .bInterfaceNumber       = 0,
84         .bAlternateSetting      = 0,
85         .bNumEndpoints          = 1,
86         .bInterfaceClass        = USB_CLASS_HID,
87         .bInterfaceSubClass     = USB_SUB_HID_BOOT,
88         .bInterfaceProtocol     = USB_PROT_HID_KEYBOARD,
89         .iInterface             = 0,
90 };
91
92 static struct usb_class_hid_descriptor keyb_report0 = {
93         .bLength                = sizeof(keyb_report0),
94         .bDescriptorType        = USB_DT_HID,
95         .bcdCDC                 = 0x101,
96         .bCountryCode           = 0,
97         .bNumDescriptors        = 1,
98         .bDescriptorType0       = USB_DT_HID_REPORT,
99         .wDescriptorLength0     = 0x3f,
100 };
101
102 static struct usb_endpoint_descriptor keyb_endpoint0_in = {
103         .bLength                = USB_DT_ENDPOINT_SIZE,
104         .bDescriptorType        = USB_DT_ENDPOINT,
105
106         .bEndpointAddress       = SANDBOX_KEYB_EP_IN | USB_ENDPOINT_DIR_MASK,
107         .bmAttributes           = USB_ENDPOINT_XFER_BULK |
108                                         USB_ENDPOINT_XFER_ISOC,
109         .wMaxPacketSize         = __constant_cpu_to_le16(8),
110         .bInterval              = 0xa,
111 };
112
113 static struct usb_interface_descriptor keyb_interface1 = {
114         .bLength                = sizeof(keyb_interface1),
115         .bDescriptorType        = USB_DT_INTERFACE,
116
117         .bInterfaceNumber       = 1,
118         .bAlternateSetting      = 0,
119         .bNumEndpoints          = 1,
120         .bInterfaceClass        = USB_CLASS_HID,
121         .bInterfaceSubClass     = USB_SUB_HID_BOOT,
122         .bInterfaceProtocol     = USB_PROT_HID_MOUSE,
123         .iInterface             = 0,
124 };
125
126 static struct usb_class_hid_descriptor keyb_report1 = {
127         .bLength                = sizeof(struct usb_class_hid_descriptor),
128         .bDescriptorType        = USB_DT_HID,
129         .bcdCDC                 = 0x101,
130         .bCountryCode           = 0,
131         .bNumDescriptors        = 1,
132         .bDescriptorType0       = USB_DT_HID_REPORT,
133         .wDescriptorLength0     = 0x32,
134 };
135
136 static struct usb_endpoint_descriptor keyb_endpoint1_in = {
137         .bLength                = USB_DT_ENDPOINT_SIZE,
138         .bDescriptorType        = USB_DT_ENDPOINT,
139
140         .bEndpointAddress       = SANDBOX_KEYB_EP_IN | USB_ENDPOINT_DIR_MASK,
141         .bmAttributes           = USB_ENDPOINT_XFER_BULK |
142                                         USB_ENDPOINT_XFER_ISOC,
143         .wMaxPacketSize         = __constant_cpu_to_le16(8),
144         .bInterval              = 0xa,
145 };
146
147 static void *keyb_desc_list[] = {
148         &keyb_device_desc,
149         &keyb_config0,
150         &keyb_interface0,
151         &keyb_report0,
152         &keyb_endpoint0_in,
153         &keyb_interface1,
154         &keyb_report1,
155         &keyb_endpoint1_in,
156         NULL,
157 };
158
159 int sandbox_usb_keyb_add_string(struct udevice *dev, const char *str)
160 {
161         struct sandbox_keyb_priv *priv = dev_get_priv(dev);
162         int len, ret;
163
164         len = strlen(str);
165         ret = membuff_put(&priv->in, str, len);
166         if (ret != len)
167                 return -ENOSPC;
168
169         return 0;
170 }
171
172 static int sandbox_keyb_control(struct udevice *dev, struct usb_device *udev,
173                                 unsigned long pipe, void *buff, int len,
174                                 struct devrequest *setup)
175 {
176         debug("pipe=%lx\n", pipe);
177
178         return -EIO;
179 }
180
181 static int sandbox_keyb_interrupt(struct udevice *dev, struct usb_device *udev,
182                 unsigned long pipe, void *buffer, int length, int interval)
183 {
184         struct sandbox_keyb_priv *priv = dev_get_priv(dev);
185         uint8_t *data = buffer;
186         int ch;
187
188         memset(data, '\0', length);
189         ch = membuff_getbyte(&priv->in);
190         if (ch != -1)
191                 data[2] = 4 + ch - 'a';
192
193         return 0;
194 }
195
196 static int sandbox_keyb_bind(struct udevice *dev)
197 {
198         struct sandbox_keyb_plat *plat = dev_get_platdata(dev);
199         struct usb_string *fs;
200
201         fs = plat->keyb_strings;
202         fs[0].id = STRINGID_MANUFACTURER;
203         fs[0].s = "sandbox";
204         fs[1].id = STRINGID_PRODUCT;
205         fs[1].s = "keyboard";
206         fs[2].id = STRINGID_SERIAL;
207         fs[2].s = dev->name;
208
209         return usb_emul_setup_device(dev, plat->keyb_strings, keyb_desc_list);
210 }
211
212 static int sandbox_keyb_probe(struct udevice *dev)
213 {
214         struct sandbox_keyb_priv *priv = dev_get_priv(dev);
215
216         return membuff_new(&priv->in, 256);
217 }
218
219 static const struct dm_usb_ops sandbox_usb_keyb_ops = {
220         .control        = sandbox_keyb_control,
221         .interrupt      = sandbox_keyb_interrupt,
222 };
223
224 static const struct udevice_id sandbox_usb_keyb_ids[] = {
225         { .compatible = "sandbox,usb-keyb" },
226         { }
227 };
228
229 U_BOOT_DRIVER(usb_sandbox_keyb) = {
230         .name   = "usb_sandbox_keyb",
231         .id     = UCLASS_USB_EMUL,
232         .of_match = sandbox_usb_keyb_ids,
233         .bind   = sandbox_keyb_bind,
234         .probe  = sandbox_keyb_probe,
235         .ops    = &sandbox_usb_keyb_ops,
236         .priv_auto_alloc_size = sizeof(struct sandbox_keyb_priv),
237         .platdata_auto_alloc_size = sizeof(struct sandbox_keyb_plat),
238 };