diff options
Diffstat (limited to 'chip/g/usb-stream.h')
-rw-r--r-- | chip/g/usb-stream.h | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/chip/g/usb-stream.h b/chip/g/usb-stream.h new file mode 100644 index 0000000000..761065d8b6 --- /dev/null +++ b/chip/g/usb-stream.h @@ -0,0 +1,192 @@ +/* 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. + */ +#ifndef __CROS_EC_USB_STREAM_H +#define __CROS_EC_USB_STREAM_H + +/* USB STREAM driver for Chrome EC */ + +#include "compile_time_macros.h" +#include "consumer.h" +#include "hooks.h" +#include "registers.h" +#include "producer.h" +#include "queue.h" +#include "usb_descriptor.h" + +/* + * Compile time Per-USB stream configuration stored in flash. Instances of this + * structure are provided by the user of the USB stream. This structure binds + * together all information required to operate a USB stream. + */ +struct usb_stream_config { + /* + * Endpoint index, and pointers to the USB packet RAM buffers. + */ + int endpoint; + + int *is_reset; + + /* + * Deferred function to call to handle USB and Queue request. + */ + void (*deferred_tx)(void); + void (*deferred_rx)(void); + + int tx_size; + int rx_size; + + uint8_t *tx_ram; + uint8_t *rx_ram; + + struct consumer consumer; + struct producer producer; + + struct g_usb_desc *out_desc; + struct g_usb_desc *in_desc; +}; + +/* + * These function tables are defined by the USB Stream driver and are used to + * initialize the consumer and producer in the usb_stream_config. + */ +extern struct consumer_ops const usb_stream_consumer_ops; +extern struct producer_ops const usb_stream_producer_ops; + + +/* + * Convenience macro for defining USB streams and their associated state and + * buffers. + * + * NAME is used to construct the names of the packet RAM buffers, trampoline + * functions, usb_stream_state struct, and usb_stream_config struct, the + * latter is just called NAME. + * + * INTERFACE is the index of the USB interface to associate with this + * stream. + * + * INTERFACE_NAME is the index of the USB string descriptor (iInterface). + * + * ENDPOINT is the index of the USB bulk endpoint used for receiving and + * transmitting bytes. + * + * RX_SIZE and TX_SIZE are the number of bytes of USB packet RAM to allocate + * for the RX and TX packets respectively. The valid values for these + * parameters are dictated by the USB peripheral. + * + * RX_QUEUE and TX_QUEUE are the names of the RX and TX queues that this driver + * should write to and read from respectively. + */ +/* + * The following assertions can not be made because they require access to + * non-const fields, but should be kept in mind. + * + * BUILD_ASSERT(RX_QUEUE.buffer_units >= RX_SIZE); + * BUILD_ASSERT(TX_QUEUE.buffer_units >= TX_SIZE); + * BUILD_ASSERT(RX_QUEUE.unit_bytes == 1); + * BUILD_ASSERT(TX_QUEUE.unit_bytes == 1); + */ +#define USB_STREAM_CONFIG(NAME, \ + INTERFACE, \ + INTERFACE_NAME, \ + ENDPOINT, \ + RX_SIZE, \ + TX_SIZE, \ + RX_QUEUE, \ + TX_QUEUE) \ + \ + static struct g_usb_desc CONCAT2(NAME, _out_desc_); \ + static struct g_usb_desc CONCAT2(NAME, _in_desc_); \ + static uint8_t CONCAT2(NAME, _buf_rx_)[RX_SIZE]; \ + static uint8_t CONCAT2(NAME, _buf_tx_)[TX_SIZE]; \ + static int CONCAT2(NAME, _is_reset_); \ + static void CONCAT2(NAME, _deferred_tx_)(void); \ + static void CONCAT2(NAME, _deferred_rx_)(void); \ + struct usb_stream_config const NAME = { \ + .endpoint = ENDPOINT, \ + .is_reset = &CONCAT2(NAME, _is_reset_), \ + .in_desc = &CONCAT2(NAME, _in_desc_), \ + .out_desc = &CONCAT2(NAME, _out_desc_), \ + .deferred_tx = CONCAT2(NAME, _deferred_tx_), \ + .deferred_rx = CONCAT2(NAME, _deferred_rx_), \ + .tx_size = TX_SIZE, \ + .rx_size = RX_SIZE, \ + .tx_ram = CONCAT2(NAME, _buf_tx_), \ + .rx_ram = CONCAT2(NAME, _buf_rx_), \ + .consumer = { \ + .queue = &TX_QUEUE, \ + .ops = &usb_stream_consumer_ops, \ + }, \ + .producer = { \ + .queue = &RX_QUEUE, \ + .ops = &usb_stream_producer_ops, \ + }, \ + }; \ + 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 = USB_SUBCLASS_GOOGLE_SERIAL, \ + .bInterfaceProtocol = USB_PROTOCOL_GOOGLE_SERIAL, \ + .iInterface = INTERFACE_NAME, \ + }; \ + 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 = TX_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 = RX_SIZE, \ + .bInterval = 0, \ + }; \ + static void CONCAT2(NAME, _deferred_tx_)(void) \ + { tx_stream_handler(&NAME); } \ + DECLARE_DEFERRED(CONCAT2(NAME, _deferred_tx_)); \ + static void CONCAT2(NAME, _deferred_rx_)(void) \ + { rx_stream_handler(&NAME); } \ + DECLARE_DEFERRED(CONCAT2(NAME, _deferred_rx_)); \ + static void CONCAT2(NAME, _ep_tx)(void) \ + { \ + usb_stream_tx(&NAME); \ + } \ + static void CONCAT2(NAME, _ep_rx)(void) \ + { \ + usb_stream_rx(&NAME); \ + } \ + static void CONCAT2(NAME, _ep_reset)(void) \ + { \ + usb_stream_reset(&NAME); \ + } \ + USB_DECLARE_EP(ENDPOINT, \ + CONCAT2(NAME, _ep_tx), \ + CONCAT2(NAME, _ep_rx), \ + CONCAT2(NAME, _ep_reset)); \ +/* + * Handle USB and Queue request in a deferred callback. + */ +int rx_stream_handler(struct usb_stream_config const *config); +int tx_stream_handler(struct usb_stream_config const *config); + +/* + * These functions are used by the trampoline functions defined above to + * connect USB endpoint events with the generic USB stream driver. + */ +void usb_stream_tx(struct usb_stream_config const *config); +void usb_stream_rx(struct usb_stream_config const *config); +void usb_stream_reset(struct usb_stream_config const *config); + +#endif /* __CROS_EC_USB_STREAM_H */ |