summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chip/stm32/build.mk1
-rw-r--r--chip/stm32/usb_gpio.c81
-rw-r--r--chip/stm32/usb_gpio.h119
-rw-r--r--include/config.h4
4 files changed, 205 insertions, 0 deletions
diff --git a/chip/stm32/build.mk b/chip/stm32/build.mk
index b23f044554..1c5081a5da 100644
--- a/chip/stm32/build.mk
+++ b/chip/stm32/build.mk
@@ -39,6 +39,7 @@ chip-$(CONFIG_ADC)+=adc-$(CHIP_FAMILY).o
chip-$(CONFIG_PWM)+=pwm.o
chip-$(CONFIG_USB)+=usb.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_MS)+=usb_ms.o usb_ms_scsi.o
chip-$(CONFIG_USB_POWER_DELIVERY)+=usb_pd_phy.o
diff --git a/chip/stm32/usb_gpio.c b/chip/stm32/usb_gpio.c
new file mode 100644
index 0000000000..027ddadaae
--- /dev/null
+++ b/chip/stm32/usb_gpio.c
@@ -0,0 +1,81 @@
+/* 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.
+ */
+
+#include "common.h"
+#include "gpio.h"
+#include "link_defs.h"
+#include "registers.h"
+#include "usb_gpio.h"
+
+void usb_gpio_tx(struct usb_gpio_config const *config)
+{
+ size_t i;
+ uint32_t mask = 1;
+ uint32_t value = 0;
+
+ for (i = 0; i < config->num_gpios; ++i, mask <<= 1)
+ value |= (gpio_get_level(config->gpios[i])) ? mask : 0;
+
+ config->tx_ram[0] = value;
+ config->tx_ram[1] = value >> 16;
+
+ btable_ep[config->endpoint].tx_count = USB_GPIO_TX_PACKET_SIZE;
+
+ /*
+ * TX packet updated, mark the packet as VALID.
+ */
+ STM32_TOGGLE_EP(config->endpoint, EP_TX_MASK, EP_TX_VALID, 0);
+}
+
+void usb_gpio_rx(struct usb_gpio_config const *config)
+{
+ size_t i;
+ uint32_t mask = 1;
+ uint32_t set_mask = ((uint32_t)(config->rx_ram[0]) |
+ (uint32_t)(config->rx_ram[1]) << 16);
+ uint32_t clear_mask = ((uint32_t)(config->rx_ram[2]) |
+ (uint32_t)(config->rx_ram[3]) << 16);
+ uint32_t ignore_mask = set_mask & clear_mask;
+
+ if ((btable_ep[config->endpoint].rx_count & 0x3ff) ==
+ USB_GPIO_RX_PACKET_SIZE) {
+ for (i = 0; i < config->num_gpios; ++i, mask <<= 1) {
+ if (ignore_mask & mask)
+ ;
+ else if (set_mask & mask)
+ gpio_set_level(config->gpios[i], 1);
+ else if (clear_mask & mask)
+ gpio_set_level(config->gpios[i], 0);
+ }
+ }
+
+ /*
+ * RX packet consumed, mark the packet as VALID.
+ */
+ STM32_TOGGLE_EP(config->endpoint, EP_RX_MASK, EP_RX_VALID, 0);
+}
+
+void usb_gpio_reset(struct usb_gpio_config const *config)
+{
+ int i = config->endpoint;
+
+ btable_ep[i].tx_addr = usb_sram_addr(config->tx_ram);
+ btable_ep[i].tx_count = USB_GPIO_TX_PACKET_SIZE;
+
+ btable_ep[i].rx_addr = usb_sram_addr(config->rx_ram);
+ btable_ep[i].rx_count = ((USB_GPIO_RX_PACKET_SIZE / 2) << 10);
+
+ /*
+ * Initialize TX buffer with zero, the first IN transaction will fill
+ * this in with a valid value.
+ */
+ config->tx_ram[0] = 0;
+ config->tx_ram[1] = 0;
+
+ STM32_USB_EP(i) = ((i << 0) | /* Endpoint Addr*/
+ (3 << 4) | /* TX Valid */
+ (0 << 9) | /* Bulk EP */
+ (3 << 12)); /* RX Valid */
+}
diff --git a/chip/stm32/usb_gpio.h b/chip/stm32/usb_gpio.h
new file mode 100644
index 0000000000..2027df9d21
--- /dev/null
+++ b/chip/stm32/usb_gpio.h
@@ -0,0 +1,119 @@
+/* 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.
+ */
+#ifndef CHIP_STM32_USB_GPIO_H
+#define CHIP_STM32_USB_GPIO_H
+
+/* STM32 USB GPIO driver for Chrome EC */
+
+#include "compile_time_macros.h"
+#include "usb.h"
+
+/*
+ * Compile time Per-USB gpio configuration stored in flash. Instances of this
+ * structure are provided by the user of the USB gpio. This structure binds
+ * together all information required to operate a USB gpio.
+ */
+struct usb_gpio_config {
+ /*
+ * Endpoint index, and pointers to the USB packet RAM buffers.
+ */
+ int endpoint;
+
+ usb_uint *rx_ram;
+ usb_uint *tx_ram;
+
+ /*
+ * GPIO list
+ */
+ enum gpio_signal const *gpios;
+ size_t num_gpios;
+};
+
+#define USB_GPIO_RX_PACKET_SIZE 8
+#define USB_GPIO_TX_PACKET_SIZE 4
+
+/*
+ * Convenience macro for defining a USB GPIO driver and its associated state.
+ *
+ * NAME is used to construct the names of the trampoline functions,
+ * usb_gpio_state struct, and usb_gpio_config struct, the latter is just
+ * called NAME.
+ *
+ * INTERFACE is the index of the USB interface to associate with this
+ * GPIO driver.
+ *
+ * ENDPOINT is the index of the USB bulk endpoint used for receiving and
+ * transmitting bytes.
+ */
+#define USB_GPIO_CONFIG(NAME, \
+ GPIO_LIST, \
+ INTERFACE, \
+ ENDPOINT) \
+ BUILD_ASSERT(ARRAY_SIZE(GPIO_LIST) <= 32); \
+ static usb_uint CONCAT2(NAME, _ep_rx_buffer)[USB_GPIO_RX_PACKET_SIZE / 2] __usb_ram; \
+ static usb_uint CONCAT2(NAME, _ep_tx_buffer)[USB_GPIO_TX_PACKET_SIZE / 2] __usb_ram; \
+ struct usb_gpio_config const NAME = { \
+ .endpoint = ENDPOINT, \
+ .rx_ram = CONCAT2(NAME, _ep_rx_buffer), \
+ .tx_ram = CONCAT2(NAME, _ep_tx_buffer), \
+ .gpios = GPIO_LIST, \
+ .num_gpios = ARRAY_SIZE(GPIO_LIST), \
+ }; \
+ const struct usb_interface_descriptor \
+ USB_IFACE_DESC(INTERFACE) = { \
+ .bLength = USB_DT_INTERFACE_SIZE, \
+ .bDescriptorType = USB_DT_INTERFACE, \
+ .bInterfaceNumber = INTERFACE, \
+ .bAlternateSetting = 0, \
+ .bNumEndpoints = 2, \
+ .bInterfaceClass = USB_CLASS_VENDOR_SPEC, \
+ .bInterfaceSubClass = 0, \
+ .bInterfaceProtocol = 0, \
+ .iInterface = 0, \
+ }; \
+ const struct usb_endpoint_descriptor \
+ USB_EP_DESC(INTERFACE, 0) = { \
+ .bLength = USB_DT_ENDPOINT_SIZE, \
+ .bDescriptorType = USB_DT_ENDPOINT, \
+ .bEndpointAddress = 0x80 | ENDPOINT, \
+ .bmAttributes = 0x02 /* Bulk IN */, \
+ .wMaxPacketSize = USB_GPIO_TX_PACKET_SIZE, \
+ .bInterval = 10, \
+ }; \
+ const struct usb_endpoint_descriptor \
+ USB_EP_DESC(INTERFACE, 1) = { \
+ .bLength = USB_DT_ENDPOINT_SIZE, \
+ .bDescriptorType = USB_DT_ENDPOINT, \
+ .bEndpointAddress = ENDPOINT, \
+ .bmAttributes = 0x02 /* Bulk OUT */, \
+ .wMaxPacketSize = USB_GPIO_RX_PACKET_SIZE, \
+ .bInterval = 0, \
+ }; \
+ static void CONCAT2(NAME, _ep_tx)(void) \
+ { \
+ usb_gpio_tx(&NAME); \
+ } \
+ static void CONCAT2(NAME, _ep_rx)(void) \
+ { \
+ usb_gpio_rx(&NAME); \
+ } \
+ static void CONCAT2(NAME, _ep_reset)(void) \
+ { \
+ usb_gpio_reset(&NAME); \
+ } \
+ USB_DECLARE_EP(ENDPOINT, \
+ CONCAT2(NAME, _ep_tx), \
+ CONCAT2(NAME, _ep_rx), \
+ CONCAT2(NAME, _ep_reset));
+
+/*
+ * These functions are used by the trampoline functions defined above to
+ * connect USB endpoint events with the generic USB GPIO driver.
+ */
+void usb_gpio_tx(struct usb_gpio_config const *config);
+void usb_gpio_rx(struct usb_gpio_config const *config);
+void usb_gpio_reset(struct usb_gpio_config const *config);
+
+#endif /* CHIP_STM32_USB_GPIO_H */
diff --git a/include/config.h b/include/config.h
index fdb980eb4c..e6cb68c132 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1092,6 +1092,10 @@
#undef CONFIG_USB_SWITCH_PI3USB9281_MUX_GPIO
/*****************************************************************************/
+/* USB GPIO config */
+#undef CONFIG_USB_GPIO
+
+/*****************************************************************************/
/* Support computing hash of code for verified boot */
#undef CONFIG_VBOOT_HASH