/* Copyright 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 __CROS_EC_USB_GPIO_H #define __CROS_EC_USB_GPIO_H /* STM32 USB GPIO driver for Chrome EC */ #include "compile_time_macros.h" #include "usb_descriptor.h" #include "usb_hw.h" struct usb_gpio_state { uint32_t set_mask; uint32_t clear_mask; }; /* * 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 { struct usb_gpio_state *state; /* * 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 = { \ .state = &((struct usb_gpio_state){}), \ .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_event)(enum usb_ep_event evt) \ { \ usb_gpio_event(&NAME, evt); \ } \ USB_DECLARE_EP(ENDPOINT, \ CONCAT2(NAME, _ep_tx), \ CONCAT2(NAME, _ep_rx), \ CONCAT2(NAME, _ep_event)) /* * 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_event(struct usb_gpio_config const *config, enum usb_ep_event evt); #endif /* __CROS_EC_USB_GPIO_H */