2 * (C) Copyright 2015 Google, Inc
3 * Written by Simon Glass <sjg@chromium.org>
5 * SPDX-License-Identifier: GPL-2.0+
14 DECLARE_GLOBAL_DATA_PTR
;
17 * This driver emulates a USB keyboard using the USB HID specification (boot
22 SANDBOX_KEYB_EP_IN
= 1, /* endpoints */
32 STRINGID_MANUFACTURER
= 1,
40 * struct sandbox_keyb_priv - private state for this driver
43 struct sandbox_keyb_priv
{
47 struct sandbox_keyb_plat
{
48 struct usb_string keyb_strings
[STRINGID_COUNT
];
51 static struct usb_device_descriptor keyb_device_desc
= {
52 .bLength
= sizeof(keyb_device_desc
),
53 .bDescriptorType
= USB_DT_DEVICE
,
55 .bcdUSB
= __constant_cpu_to_le16(0x0100),
61 .idVendor
= __constant_cpu_to_le16(0x1234),
62 .idProduct
= __constant_cpu_to_le16(0x5679),
63 .iManufacturer
= STRINGID_MANUFACTURER
,
64 .iProduct
= STRINGID_PRODUCT
,
65 .iSerialNumber
= STRINGID_SERIAL
,
66 .bNumConfigurations
= 1,
69 static struct usb_config_descriptor keyb_config0
= {
70 .bLength
= sizeof(keyb_config0
),
71 .bDescriptorType
= USB_DT_CONFIG
,
73 /* wTotalLength is set up by usb-emul-uclass */
75 .bConfigurationValue
= 0,
77 .bmAttributes
= 1 << 7 | 1 << 5,
81 static struct usb_interface_descriptor keyb_interface0
= {
82 .bLength
= sizeof(keyb_interface0
),
83 .bDescriptorType
= USB_DT_INTERFACE
,
85 .bInterfaceNumber
= 0,
86 .bAlternateSetting
= 0,
88 .bInterfaceClass
= USB_CLASS_HID
,
89 .bInterfaceSubClass
= USB_SUB_HID_BOOT
,
90 .bInterfaceProtocol
= USB_PROT_HID_KEYBOARD
,
94 static struct usb_class_hid_descriptor keyb_report0
= {
95 .bLength
= sizeof(keyb_report0
),
96 .bDescriptorType
= USB_DT_HID
,
100 .bDescriptorType0
= USB_DT_HID_REPORT
,
101 .wDescriptorLength0
= 0x3f,
104 static struct usb_endpoint_descriptor keyb_endpoint0_in
= {
105 .bLength
= USB_DT_ENDPOINT_SIZE
,
106 .bDescriptorType
= USB_DT_ENDPOINT
,
108 .bEndpointAddress
= SANDBOX_KEYB_EP_IN
| USB_ENDPOINT_DIR_MASK
,
109 .bmAttributes
= USB_ENDPOINT_XFER_BULK
|
110 USB_ENDPOINT_XFER_ISOC
,
111 .wMaxPacketSize
= __constant_cpu_to_le16(8),
115 static struct usb_interface_descriptor keyb_interface1
= {
116 .bLength
= sizeof(keyb_interface1
),
117 .bDescriptorType
= USB_DT_INTERFACE
,
119 .bInterfaceNumber
= 1,
120 .bAlternateSetting
= 0,
122 .bInterfaceClass
= USB_CLASS_HID
,
123 .bInterfaceSubClass
= USB_SUB_HID_BOOT
,
124 .bInterfaceProtocol
= USB_PROT_HID_MOUSE
,
128 static struct usb_class_hid_descriptor keyb_report1
= {
129 .bLength
= sizeof(struct usb_class_hid_descriptor
),
130 .bDescriptorType
= USB_DT_HID
,
133 .bNumDescriptors
= 1,
134 .bDescriptorType0
= USB_DT_HID_REPORT
,
135 .wDescriptorLength0
= 0x32,
138 static struct usb_endpoint_descriptor keyb_endpoint1_in
= {
139 .bLength
= USB_DT_ENDPOINT_SIZE
,
140 .bDescriptorType
= USB_DT_ENDPOINT
,
142 .bEndpointAddress
= SANDBOX_KEYB_EP_IN
| USB_ENDPOINT_DIR_MASK
,
143 .bmAttributes
= USB_ENDPOINT_XFER_BULK
|
144 USB_ENDPOINT_XFER_ISOC
,
145 .wMaxPacketSize
= __constant_cpu_to_le16(8),
149 static void *keyb_desc_list
[] = {
161 int sandbox_usb_keyb_add_string(struct udevice
*dev
, const char *str
)
163 struct sandbox_keyb_priv
*priv
= dev_get_priv(dev
);
167 ret
= membuff_put(&priv
->in
, str
, len
);
174 static int sandbox_keyb_control(struct udevice
*dev
, struct usb_device
*udev
,
175 unsigned long pipe
, void *buff
, int len
,
176 struct devrequest
*setup
)
178 debug("pipe=%lx\n", pipe
);
183 static int sandbox_keyb_interrupt(struct udevice
*dev
, struct usb_device
*udev
,
184 unsigned long pipe
, void *buffer
, int length
, int interval
)
186 struct sandbox_keyb_priv
*priv
= dev_get_priv(dev
);
187 uint8_t *data
= buffer
;
190 memset(data
, '\0', length
);
191 ch
= membuff_getbyte(&priv
->in
);
193 data
[2] = 4 + ch
- 'a';
198 static int sandbox_keyb_bind(struct udevice
*dev
)
200 struct sandbox_keyb_plat
*plat
= dev_get_platdata(dev
);
201 struct usb_string
*fs
;
203 fs
= plat
->keyb_strings
;
204 fs
[0].id
= STRINGID_MANUFACTURER
;
206 fs
[1].id
= STRINGID_PRODUCT
;
207 fs
[1].s
= "keyboard";
208 fs
[2].id
= STRINGID_SERIAL
;
211 return usb_emul_setup_device(dev
, PACKET_SIZE_8
, plat
->keyb_strings
,
215 static int sandbox_keyb_probe(struct udevice
*dev
)
217 struct sandbox_keyb_priv
*priv
= dev_get_priv(dev
);
219 return membuff_new(&priv
->in
, 256);
222 static const struct dm_usb_ops sandbox_usb_keyb_ops
= {
223 .control
= sandbox_keyb_control
,
224 .interrupt
= sandbox_keyb_interrupt
,
227 static const struct udevice_id sandbox_usb_keyb_ids
[] = {
228 { .compatible
= "sandbox,usb-keyb" },
232 U_BOOT_DRIVER(usb_sandbox_keyb
) = {
233 .name
= "usb_sandbox_keyb",
234 .id
= UCLASS_USB_EMUL
,
235 .of_match
= sandbox_usb_keyb_ids
,
236 .bind
= sandbox_keyb_bind
,
237 .probe
= sandbox_keyb_probe
,
238 .ops
= &sandbox_usb_keyb_ops
,
239 .priv_auto_alloc_size
= sizeof(struct sandbox_keyb_priv
),
240 .platdata_auto_alloc_size
= sizeof(struct sandbox_keyb_plat
),