summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@google.com>2016-11-09 17:35:22 +0800
committerchrome-bot <chrome-bot@chromium.org>2016-11-16 19:04:47 -0800
commit64f1823a742e4cd39e56f0621d86bae41c709210 (patch)
treef32024c26dd85c36a80021fb1d6f17f971568ff1
parentb565e9223d3fe5131c380030155b90e327bc27ef (diff)
downloadchrome-ec-64f1823a742e4cd39e56f0621d86bae41c709210.tar.gz
chip/stm32/usb_hid: Separate HID keyboard support
In the future, we'd like to have different HID devices on different endpoints (keyboard, trackpad, etc.), so we'd like to separate the keyboard handling. For other chip implementing usb_hid.c (namely, chip/g), we, for now just rename the config option and endpoint/interface definitions. Making the code more generic can be done at a later stage. BRANCH=none BUG=chrome-os-partner:59083 TEST=make buildall -j TEST=make BOARD=hammer -j && util/flash_ec --board=hammer Change-Id: Iad1b00fa226f7635c0f34aae6a435dc53a3ea555 Reviewed-on: https://chromium-review.googlesource.com/409256 Commit-Ready: Nicolas Boichat <drinkcat@chromium.org> Tested-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-by: Mary Ruthven <mruthven@chromium.org>
-rw-r--r--board/cr50/board.c2
-rw-r--r--board/cr50/board.h2
-rw-r--r--board/hammer/board.h5
-rw-r--r--chip/g/build.mk2
-rw-r--r--chip/g/usb_hid_keyboard.c (renamed from chip/g/usb_hid.c)32
-rw-r--r--chip/stm32/build.mk1
-rw-r--r--chip/stm32/usb_hid.c133
-rw-r--r--chip/stm32/usb_hid_hw.h17
-rw-r--r--chip/stm32/usb_hid_keyboard.c140
-rw-r--r--include/config.h3
-rw-r--r--include/usb_hid.h3
-rw-r--r--include/usb_hid_keyboard.h14
12 files changed, 212 insertions, 142 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c
index 46a642b676..6f753559ee 100644
--- a/board/cr50/board.c
+++ b/board/cr50/board.c
@@ -279,7 +279,7 @@ const void * const usb_strings[] = {
[USB_STR_VERSION] = USB_STRING_DESC(CROS_EC_VERSION32),
[USB_STR_CONSOLE_NAME] = USB_STRING_DESC("Shell"),
[USB_STR_BLOB_NAME] = USB_STRING_DESC("Blob"),
- [USB_STR_HID_NAME] = USB_STRING_DESC("PokeyPokey"),
+ [USB_STR_HID_KEYBOARD_NAME] = USB_STRING_DESC("PokeyPokey"),
[USB_STR_AP_NAME] = USB_STRING_DESC("AP"),
[USB_STR_EC_NAME] = USB_STRING_DESC("EC"),
[USB_STR_UPGRADE_NAME] = USB_STRING_DESC("Firmware upgrade"),
diff --git a/board/cr50/board.h b/board/cr50/board.h
index d95acfe5d4..295a6ddf0c 100644
--- a/board/cr50/board.h
+++ b/board/cr50/board.h
@@ -124,7 +124,7 @@ enum usb_strings {
USB_STR_VERSION,
USB_STR_CONSOLE_NAME,
USB_STR_BLOB_NAME,
- USB_STR_HID_NAME,
+ USB_STR_HID_KEYBOARD_NAME,
USB_STR_AP_NAME,
USB_STR_EC_NAME,
USB_STR_UPGRADE_NAME,
diff --git a/board/hammer/board.h b/board/hammer/board.h
index ecb09ef399..86e3cbdce8 100644
--- a/board/hammer/board.h
+++ b/board/hammer/board.h
@@ -28,6 +28,7 @@
#define CONFIG_STREAM_USB
#define CONFIG_USB_UPDATE
#define CONFIG_USB_HID
+#define CONFIG_USB_HID_KEYBOARD
#undef CONFIG_USB_MAXPOWER_MA
#define CONFIG_USB_MAXPOWER_MA 100
@@ -41,13 +42,13 @@
/* USB interface indexes (use define rather than enum to expand them) */
#define USB_IFACE_UPDATE 0
-#define USB_IFACE_HID 1
+#define USB_IFACE_HID_KEYBOARD 1
#define USB_IFACE_COUNT 2
/* USB endpoint indexes (use define rather than enum to expand them) */
#define USB_EP_CONTROL 0
#define USB_EP_UPDATE 1
-#define USB_EP_HID 2
+#define USB_EP_HID_KEYBOARD 2
#define USB_EP_COUNT 3
/* Optional features */
diff --git a/chip/g/build.mk b/chip/g/build.mk
index bb0573958b..950704a03c 100644
--- a/chip/g/build.mk
+++ b/chip/g/build.mk
@@ -57,7 +57,7 @@ chip-$(CONFIG_WATCHDOG)+=watchdog.o
chip-$(CONFIG_USB)+=usb.o usb_endpoints.o
chip-$(CONFIG_USB_CONSOLE)+=usb_console.o
-chip-$(CONFIG_USB_HID)+=usb_hid.o
+chip-$(CONFIG_USB_HID_KEYBOARD)+=usb_hid_keyboard.o
chip-$(CONFIG_USB_BLOB)+=blob.o
chip-$(CONFIG_USB_SPI)+=usb_spi.o
chip-$(CONFIG_RDD)+=rdd.o
diff --git a/chip/g/usb_hid.c b/chip/g/usb_hid_keyboard.c
index a0ea412a61..62167d93ca 100644
--- a/chip/g/usb_hid.c
+++ b/chip/g/usb_hid_keyboard.c
@@ -23,29 +23,26 @@
#define HID_REPORT_SIZE 8
/* HID descriptors */
-const struct usb_interface_descriptor USB_IFACE_DESC(USB_IFACE_HID) =
-{
+const struct usb_interface_descriptor USB_IFACE_DESC(USB_IFACE_HID) = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
- .bInterfaceNumber = USB_IFACE_HID,
+ .bInterfaceNumber = USB_IFACE_HID_KEYBOARD,
.bAlternateSetting = 0,
.bNumEndpoints = 1,
.bInterfaceClass = USB_CLASS_HID,
.bInterfaceSubClass = USB_HID_SUBCLASS_BOOT,
.bInterfaceProtocol = USB_HID_PROTOCOL_KEYBOARD,
- .iInterface = USB_STR_HID_NAME,
+ .iInterface = USB_STR_HID_KEYBOARD_NAME,
};
-const struct usb_endpoint_descriptor USB_EP_DESC(USB_IFACE_HID, 81) =
-{
+const struct usb_endpoint_descriptor USB_EP_DESC(USB_IFACE_HID, 81) = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 0x80 | USB_EP_HID,
+ .bEndpointAddress = 0x80 | USB_EP_HID_KEYBOARD,
.bmAttributes = 0x03 /* Interrupt endpoint */,
.wMaxPacketSize = HID_REPORT_SIZE,
.bInterval = 32 /* ms polling interval */
};
-const struct usb_hid_descriptor USB_CUSTOM_DESC(USB_IFACE_HID, hid) =
-{
+const struct usb_hid_descriptor USB_CUSTOM_DESC(USB_IFACE_HID, hid) = {
.bLength = 9,
.bDescriptorType = USB_HID_DT_HID,
.bcdHID = 0x0100,
@@ -96,13 +93,13 @@ void set_keyboard_report(uint64_t rpt)
hid_ep_desc.flags = DIEPDMA_LAST | DIEPDMA_BS_HOST_RDY | DIEPDMA_IOC |
DIEPDMA_TXBYTES(HID_REPORT_SIZE);
/* enable TX */
- GR_USB_DIEPCTL(USB_EP_HID) |= DXEPCTL_CNAK | DXEPCTL_EPENA;
+ GR_USB_DIEPCTL(USB_EP_HID_KEYBOARD) |= DXEPCTL_CNAK | DXEPCTL_EPENA;
}
static void hid_tx(void)
{
/* clear IT */
- GR_USB_DIEPINT(USB_EP_HID) = 0xffffffff;
+ GR_USB_DIEPINT(USB_EP_HID_KEYBOARD) = 0xffffffff;
return;
}
@@ -110,14 +107,14 @@ static void hid_reset(void)
{
hid_ep_desc.flags = DIEPDMA_LAST | DIEPDMA_BS_HOST_BSY | DIEPDMA_IOC;
hid_ep_desc.addr = hid_ep_buf;
- GR_USB_DIEPDMA(USB_EP_HID) = (uint32_t)&hid_ep_desc;
- GR_USB_DIEPCTL(USB_EP_HID) = DXEPCTL_MPS(HID_REPORT_SIZE) |
+ GR_USB_DIEPDMA(USB_EP_HID_KEYBOARD) = (uint32_t)&hid_ep_desc;
+ GR_USB_DIEPCTL(USB_EP_HID_KEYBOARD) = DXEPCTL_MPS(HID_REPORT_SIZE) |
DXEPCTL_USBACTEP | DXEPCTL_EPTYPE_INT |
- DXEPCTL_TXFNUM(USB_EP_HID);
- GR_USB_DAINTMSK |= DAINT_INEP(USB_EP_HID);
+ DXEPCTL_TXFNUM(USB_EP_HID_KEYBOARD);
+ GR_USB_DAINTMSK |= DAINT_INEP(USB_EP_HID_KEYBOARD);
}
-USB_DECLARE_EP(USB_EP_HID, hid_tx, hid_tx, hid_reset);
+USB_DECLARE_EP(USB_EP_HID_KEYBOARD, hid_tx, hid_tx, hid_reset);
static int hid_iface_request(struct usb_setup_packet *req)
{
@@ -133,7 +130,7 @@ static int hid_iface_request(struct usb_setup_packet *req)
/* Anything else we'll stall */
return -1;
}
-USB_DECLARE_IFACE(USB_IFACE_HID, hid_iface_request);
+USB_DECLARE_IFACE(USB_IFACE_HID_KEYBOARD, hid_iface_request);
#ifdef CR50_DEV
/* Just for debugging */
@@ -143,6 +140,7 @@ static int command_hid(int argc, char **argv)
if (argc >= 2) {
char *e;
+
keycode = strtoi(argv[1], &e, 16);
if (*e)
return EC_ERROR_PARAM1;
diff --git a/chip/stm32/build.mk b/chip/stm32/build.mk
index cb5f8cacd6..e6037f1012 100644
--- a/chip/stm32/build.mk
+++ b/chip/stm32/build.mk
@@ -69,6 +69,7 @@ chip-$(CONFIG_USB)+=usb.o usb-$(CHIP_FAMILY).o usb_endpoints.o
chip-$(CONFIG_USB_CONSOLE)+=usb_console.o
chip-$(CONFIG_USB_GPIO)+=usb_gpio.o
chip-$(CONFIG_USB_HID)+=usb_hid.o
+chip-$(CONFIG_USB_HID_KEYBOARD)+=usb_hid_keyboard.o
chip-$(CONFIG_USB_PD_TCPC)+=usb_pd_phy.o
chip-$(CONFIG_USB_SPI)+=usb_spi.o
endif
diff --git a/chip/stm32/usb_hid.c b/chip/stm32/usb_hid.c
index ddf1c3ccec..b316585e77 100644
--- a/chip/stm32/usb_hid.c
+++ b/chip/stm32/usb_hid.c
@@ -20,105 +20,28 @@
/* Console output macro */
#define CPRINTF(format, args...) cprintf(CC_USB, format, ## args)
-#define HID_REPORT_SIZE 8
-
-/* HID descriptors */
-const struct usb_interface_descriptor USB_IFACE_DESC(USB_IFACE_HID) = {
- .bLength = USB_DT_INTERFACE_SIZE,
- .bDescriptorType = USB_DT_INTERFACE,
- .bInterfaceNumber = USB_IFACE_HID,
- .bAlternateSetting = 0,
- .bNumEndpoints = 1,
- .bInterfaceClass = USB_CLASS_HID,
- .bInterfaceSubClass = USB_HID_SUBCLASS_BOOT,
- .bInterfaceProtocol = USB_HID_PROTOCOL_KEYBOARD,
- .iInterface = 0,
-};
-const struct usb_endpoint_descriptor USB_EP_DESC(USB_IFACE_HID, 81) = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 0x80 | USB_EP_HID,
- .bmAttributes = 0x03 /* Interrupt endpoint */,
- .wMaxPacketSize = HID_REPORT_SIZE,
- .bInterval = 40 /* ms polling interval */
-};
-const struct usb_hid_descriptor USB_CUSTOM_DESC(USB_IFACE_HID, hid) = {
- .bLength = 9,
- .bDescriptorType = USB_HID_DT_HID,
- .bcdHID = 0x0100,
- .bCountryCode = 0x00, /* Hardware target country */
- .bNumDescriptors = 1,
- .desc = {{
- .bDescriptorType = USB_HID_DT_REPORT,
- .wDescriptorLength = 45
- }}
-};
-
-/* HID : Report Descriptor */
-static const uint8_t report_desc[] = {
- 0x05, 0x01, /* Usage Page (Generic Desktop) */
- 0x09, 0x06, /* Usage (Keyboard) */
- 0xA1, 0x01, /* Collection (Application) */
- 0x05, 0x07, /* Usage Page (Key Codes) */
- 0x19, 0xE0, /* Usage Minimum (224) */
- 0x29, 0xE7, /* Usage Maximum (231) */
- 0x15, 0x00, /* Logical Minimum (0) */
- 0x25, 0x01, /* Logical Maximum (1) */
- 0x75, 0x01, /* Report Size (1) */
- 0x95, 0x08, /* Report Count (8) */
- 0x81, 0x02, /* Input (Data, Variable, Absolute), ;Modifier byte */
-
- 0x95, 0x01, /* Report Count (1) */
- 0x75, 0x08, /* Report Size (8) */
- 0x81, 0x01, /* Input (Constant), ;Reserved byte */
-
- 0x95, 0x06, /* Report Count (6) */
- 0x75, 0x08, /* Report Size (8) */
- 0x15, 0x00, /* Logical Minimum (0) */
- 0x25, 0x65, /* Logical Maximum(101) */
- 0x05, 0x07, /* Usage Page (Key Codes) */
- 0x19, 0x00, /* Usage Minimum (0) */
- 0x29, 0x65, /* Usage Maximum (101) */
- 0x81, 0x00, /* Input (Data, Array), ;Key arrays (6 bytes) */
- 0xC0, /* End Collection */
- 0x00 /* Padding */
-};
-
-static usb_uint hid_ep_buf[HID_REPORT_SIZE / 2] __usb_ram;
-
-void set_keyboard_report(uint64_t rpt)
-{
- memcpy_to_usbram((void *) usb_sram_addr(hid_ep_buf), &rpt, sizeof(rpt));
- /* enable TX */
- STM32_TOGGLE_EP(USB_EP_HID, EP_TX_MASK, EP_TX_VALID, 0);
-}
-
-static void hid_tx(void)
+void hid_tx(int ep)
{
- uint16_t ep = STM32_USB_EP(USB_EP_HID);
/* clear IT */
- STM32_USB_EP(USB_EP_HID) = (ep & EP_MASK);
- return;
+ STM32_USB_EP(ep) = (STM32_USB_EP(ep) & EP_MASK);
}
-static void hid_reset(void)
+void hid_reset(int ep, usb_uint *hid_ep_buf, int len)
{
+ int i;
/* HID interrupt endpoint 1 */
- btable_ep[USB_EP_HID].tx_addr = usb_sram_addr(hid_ep_buf);
- btable_ep[USB_EP_HID].tx_count = 8;
- hid_ep_buf[0] = 0;
- hid_ep_buf[1] = 0;
- hid_ep_buf[2] = 0;
- hid_ep_buf[3] = 0;
- STM32_USB_EP(USB_EP_HID) = (USB_EP_HID << 0) /*Endpoint Address*/ |
- (3 << 4) /* TX Valid */ |
- (3 << 9) /* interrupt EP */ |
- (0 << 12) /* RX Disabled */;
+ btable_ep[ep].tx_addr = usb_sram_addr(hid_ep_buf);
+ btable_ep[ep].tx_count = len;
+ for (i = 0; i < (len+1)/2; i++)
+ hid_ep_buf[i] = 0;
+ STM32_USB_EP(ep) = (ep << 0) /* Endpoint Address */ |
+ (3 << 4) /* TX Valid */ |
+ (3 << 9) /* interrupt EP */ |
+ (0 << 12) /* RX Disabled */;
}
-USB_DECLARE_EP(USB_EP_HID, hid_tx, hid_tx, hid_reset);
-
-static int hid_iface_request(usb_uint *ep0_buf_rx, usb_uint *ep0_buf_tx)
+int hid_iface_request(usb_uint *ep0_buf_rx, usb_uint *ep0_buf_tx,
+ const uint8_t *report_desc, int report_size)
{
if ((ep0_buf_rx[0] == (USB_DIR_IN | USB_RECIP_INTERFACE |
(USB_REQ_GET_DESCRIPTOR << 8))) &&
@@ -126,9 +49,8 @@ static int hid_iface_request(usb_uint *ep0_buf_rx, usb_uint *ep0_buf_tx)
/* Setup : HID specific : Get Report descriptor */
memcpy_to_usbram((void *) usb_sram_addr(ep0_buf_tx),
report_desc,
- sizeof(report_desc));
- btable_ep[0].tx_count = MIN(ep0_buf_rx[3],
- sizeof(report_desc));
+ report_size);
+ btable_ep[0].tx_count = MIN(ep0_buf_rx[3], report_size);
STM32_TOGGLE_EP(0, EP_TX_RX_MASK, EP_TX_RX_VALID,
EP_STATUS_OUT);
CPRINTF("RPT %04x[l %04x]\n", STM32_USB_EP(0),
@@ -138,26 +60,3 @@ static int hid_iface_request(usb_uint *ep0_buf_rx, usb_uint *ep0_buf_tx)
return 1;
}
-USB_DECLARE_IFACE(USB_IFACE_HID, hid_iface_request)
-
-static int command_hid(int argc, char **argv)
-{
- uint8_t keycode = 0x0a; /* 'G' key */
-
- if (argc >= 2) {
- char *e;
- keycode = strtoi(argv[1], &e, 16);
- if (*e)
- return EC_ERROR_PARAM1;
- }
-
- /* press then release the key */
- set_keyboard_report((uint32_t)keycode << 16);
- udelay(50000);
- set_keyboard_report(0x000000);
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(hid, command_hid,
- "[<HID keycode>]",
- "test USB HID driver");
diff --git a/chip/stm32/usb_hid_hw.h b/chip/stm32/usb_hid_hw.h
new file mode 100644
index 0000000000..083bfbfeaa
--- /dev/null
+++ b/chip/stm32/usb_hid_hw.h
@@ -0,0 +1,17 @@
+/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * USB HID HW definitions, to be used by class drivers.
+ */
+
+#ifndef __CROS_EC_USB_HID_HW_H
+#define __CROS_EC_USB_HID_HW_H
+
+/* internal callbacks for HID class drivers */
+void hid_tx(int ep);
+void hid_reset(int ep, usb_uint *hid_ep_buf, int len);
+int hid_iface_request(usb_uint *ep0_buf_rx, usb_uint *ep0_buf_tx,
+ const uint8_t *report_desc, int report_size);
+
+#endif
diff --git a/chip/stm32/usb_hid_keyboard.c b/chip/stm32/usb_hid_keyboard.c
new file mode 100644
index 0000000000..4f9e00c43b
--- /dev/null
+++ b/chip/stm32/usb_hid_keyboard.c
@@ -0,0 +1,140 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "clock.h"
+#include "common.h"
+#include "config.h"
+#include "console.h"
+#include "gpio.h"
+#include "hooks.h"
+#include "link_defs.h"
+#include "registers.h"
+#include "task.h"
+#include "timer.h"
+#include "util.h"
+#include "usb_descriptor.h"
+#include "usb_hid.h"
+#include "usb_hid_keyboard.h"
+#include "usb_hid_hw.h"
+
+/* Console output macro */
+#define CPRINTF(format, args...) cprintf(CC_USB, format, ## args)
+
+#define HID_KEYBOARD_REPORT_SIZE 8
+
+/* HID descriptors */
+const struct usb_interface_descriptor USB_IFACE_DESC(USB_IFACE_HID_KEYBOARD) = {
+ .bLength = USB_DT_INTERFACE_SIZE,
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = USB_IFACE_HID_KEYBOARD,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = USB_CLASS_HID,
+ .bInterfaceSubClass = USB_HID_SUBCLASS_BOOT,
+ .bInterfaceProtocol = USB_HID_PROTOCOL_KEYBOARD,
+ .iInterface = 0,
+};
+const struct usb_endpoint_descriptor USB_EP_DESC(USB_IFACE_HID_KEYBOARD, 81) = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 0x80 | USB_EP_HID_KEYBOARD,
+ .bmAttributes = 0x03 /* Interrupt endpoint */,
+ .wMaxPacketSize = HID_KEYBOARD_REPORT_SIZE,
+ .bInterval = 40 /* ms polling interval */
+};
+
+/* HID : Report Descriptor */
+static const uint8_t report_desc[] = {
+ 0x05, 0x01, /* Usage Page (Generic Desktop) */
+ 0x09, 0x06, /* Usage (Keyboard) */
+ 0xA1, 0x01, /* Collection (Application) */
+ 0x05, 0x07, /* Usage Page (Key Codes) */
+ 0x19, 0xE0, /* Usage Minimum (224) */
+ 0x29, 0xE7, /* Usage Maximum (231) */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x25, 0x01, /* Logical Maximum (1) */
+ 0x75, 0x01, /* Report Size (1) */
+ 0x95, 0x08, /* Report Count (8) */
+ 0x81, 0x02, /* Input (Data, Variable, Absolute), ;Modifier byte */
+
+ 0x95, 0x01, /* Report Count (1) */
+ 0x75, 0x08, /* Report Size (8) */
+ 0x81, 0x01, /* Input (Constant), ;Reserved byte */
+
+ 0x95, 0x06, /* Report Count (6) */
+ 0x75, 0x08, /* Report Size (8) */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x25, 0x65, /* Logical Maximum(101) */
+ 0x05, 0x07, /* Usage Page (Key Codes) */
+ 0x19, 0x00, /* Usage Minimum (0) */
+ 0x29, 0x65, /* Usage Maximum (101) */
+ 0x81, 0x00, /* Input (Data, Array), ;Key arrays (6 bytes) */
+ 0xC0 /* End Collection */
+};
+
+const struct usb_hid_descriptor USB_CUSTOM_DESC(USB_IFACE_HID_KEYBOARD, hid) = {
+ .bLength = 9,
+ .bDescriptorType = USB_HID_DT_HID,
+ .bcdHID = 0x0100,
+ .bCountryCode = 0x00, /* Hardware target country */
+ .bNumDescriptors = 1,
+ .desc = {{
+ .bDescriptorType = USB_HID_DT_REPORT,
+ .wDescriptorLength = sizeof(report_desc)
+ }}
+};
+
+static usb_uint hid_ep_buf[HID_KEYBOARD_REPORT_SIZE / 2] __usb_ram;
+
+void set_keyboard_report(uint64_t rpt)
+{
+ memcpy_to_usbram((void *) usb_sram_addr(hid_ep_buf), &rpt, sizeof(rpt));
+ /* enable TX */
+ STM32_TOGGLE_EP(USB_EP_HID_KEYBOARD, EP_TX_MASK, EP_TX_VALID, 0);
+}
+
+static void hid_keyboard_tx(void)
+{
+ hid_tx(USB_EP_HID_KEYBOARD);
+}
+
+static void hid_keyboard_reset(void)
+{
+ hid_reset(USB_EP_HID_KEYBOARD, hid_ep_buf, HID_KEYBOARD_REPORT_SIZE);
+}
+
+USB_DECLARE_EP(USB_EP_HID_KEYBOARD, hid_keyboard_tx, hid_keyboard_tx,
+ hid_keyboard_reset);
+
+static int hid_keyboard_iface_request(usb_uint *ep0_buf_rx,
+ usb_uint *ep0_buf_tx)
+{
+ return hid_iface_request(ep0_buf_rx, ep0_buf_tx,
+ report_desc, sizeof(report_desc));
+}
+USB_DECLARE_IFACE(USB_IFACE_HID_KEYBOARD, hid_keyboard_iface_request)
+
+static int command_hid_kb(int argc, char **argv)
+{
+ uint8_t keycode = 0x0a; /* 'G' key */
+
+ if (argc >= 2) {
+ char *e;
+
+ keycode = strtoi(argv[1], &e, 16);
+ if (*e)
+ return EC_ERROR_PARAM1;
+ }
+
+ /* press then release the key */
+ set_keyboard_report((uint32_t)keycode << 16);
+ udelay(50000);
+ set_keyboard_report(0x000000);
+
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(hid_kb, command_hid_kb,
+ "[<HID keycode>]",
+ "test USB HID driver");
diff --git a/include/config.h b/include/config.h
index 8690a7cf03..09468289e6 100644
--- a/include/config.h
+++ b/include/config.h
@@ -2232,6 +2232,9 @@
/* Support USB HID interface. */
#undef CONFIG_USB_HID
+/* Support USB HID keyboard interface. */
+#undef CONFIG_USB_HID_KEYBOARD
+
/* USB device buffers and descriptors */
#undef CONFIG_USB_RAM_ACCESS_SIZE
#undef CONFIG_USB_RAM_ACCESS_TYPE
diff --git a/include/usb_hid.h b/include/usb_hid.h
index d21449d659..d5b86196a7 100644
--- a/include/usb_hid.h
+++ b/include/usb_hid.h
@@ -39,7 +39,4 @@ struct usb_hid_descriptor {
struct usb_hid_class_descriptor desc[1];
} __packed;
-/* class implementation interfaces */
-void set_keyboard_report(uint64_t rpt);
-
#endif /* USB_H */
diff --git a/include/usb_hid_keyboard.h b/include/usb_hid_keyboard.h
new file mode 100644
index 0000000000..92d8fd7a25
--- /dev/null
+++ b/include/usb_hid_keyboard.h
@@ -0,0 +1,14 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * USB HID definitions.
+ */
+
+#ifndef __CROS_EC_USB_HID_KEYBOARD_H
+#define __CROS_EC_USB_HID_KEYBOARD_H
+
+/* class implementation interfaces */
+void set_keyboard_report(uint64_t rpt);
+
+#endif