131 lines
3.9 KiB
C
131 lines
3.9 KiB
C
|
/* 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 */
|