summaryrefslogtreecommitdiff
path: root/chip/stm32/usb_gpio.h
blob: a54801048b8d7cd1102f8b1fc1e173a518036eb2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* Copyright 2014 The ChromiumOS Authors
 * 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 */