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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
|
#ifndef _IPXE_GPIO_H
#define _IPXE_GPIO_H
/** @file
*
* General purpose I/O
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/list.h>
#include <ipxe/refcnt.h>
#include <ipxe/device.h>
/** A GPIO pin */
struct gpio {
/** GPIO controller */
struct gpios *gpios;
/** Pin index */
unsigned int index;
/** Configuration */
unsigned int config;
};
/** GPIO is active low
*
* This bit is chosen to match the devicetree standard usage.
*/
#define GPIO_CFG_ACTIVE_LOW 0x01
/** GPIO is an output */
#define GPIO_CFG_OUTPUT 0x0100
/** A GPIO controller */
struct gpios {
/** Reference count */
struct refcnt refcnt;
/** List of GPIO controllers */
struct list_head list;
/** Generic device */
struct device *dev;
/** Number of GPIOs */
unsigned int count;
/** Individual GPIOs */
struct gpio *gpio;
/** GPIO operations */
struct gpio_operations *op;
/** Driver-private data */
void *priv;
};
/** GPIO operations */
struct gpio_operations {
/**
* Get current GPIO input value
*
* @v gpios GPIO controller
* @v gpio GPIO pin
* @ret active Pin is in the active state
*/
int ( * in ) ( struct gpios *gpios, struct gpio *gpio );
/**
* Set current GPIO output value
*
* @v gpios GPIO controller
* @v gpio GPIO pin
* @v active Set pin to active state
*/
void ( * out ) ( struct gpios *gpios, struct gpio *gpio, int active );
/**
* Configure GPIO pin
*
* @v gpios GPIO controller
* @v gpio GPIO pin
* @v config Configuration
* @ret rc Return status code
*/
int ( * config ) ( struct gpios *gpios, struct gpio *gpio,
unsigned int config );
};
extern struct gpio_operations null_gpio_operations;
/**
* Get reference to GPIO controller
*
* @v gpios GPIO controller
* @ret gpios GPIO controller
*/
static inline __attribute__ (( always_inline )) struct gpios *
gpios_get ( struct gpios *gpios ) {
ref_get ( &gpios->refcnt );
return gpios;
}
/**
* Drop reference to GPIO controller
*
* @v gpios GPIO controller
*/
static inline __attribute__ (( always_inline )) void
gpios_put ( struct gpios *gpios ) {
ref_put ( &gpios->refcnt );
}
/**
* Get reference to GPIO pin
*
* @v gpio GPIO pin
* @ret gpio GPIO pin
*/
static inline __attribute__ (( always_inline )) struct gpio *
gpio_get ( struct gpio *gpio ) {
gpios_get ( gpio->gpios );
return gpio;
}
/**
* Drop reference to GPIO ping
*
* @v gpio GPIO pin
*/
static inline __attribute__ (( always_inline )) void
gpio_put ( struct gpio *gpio ) {
gpios_put ( gpio->gpios );
}
/**
* Initialise a GPIO controller
*
* @v gpios GPIO controller
* @v op GPIO operations
*/
static inline __attribute__ (( always_inline )) void
gpios_init ( struct gpios *gpios, struct gpio_operations *op ) {
gpios->op = op;
}
/**
* Stop using a GPIO controller
*
* @v gpios GPIO controller
*
* Drivers should call this method immediately before the final call
* to gpios_put().
*/
static inline __attribute__ (( always_inline )) void
gpios_nullify ( struct gpios *gpios ) {
gpios->op = &null_gpio_operations;
}
/**
* Get current GPIO input value
*
* @v gpio GPIO pin
* @ret active Pin is in the active state
*/
static inline int gpio_in ( struct gpio *gpio ) {
struct gpios *gpios = gpio->gpios;
return gpios->op->in ( gpios, gpio );
}
/**
* Set current GPIO output value
*
* @v gpio GPIO pin
* @v active Set pin to active state
*/
static inline void gpio_out ( struct gpio *gpio, int active ) {
struct gpios *gpios = gpio->gpios;
gpios->op->out ( gpios, gpio, active );
}
/**
* Configure GPIO pin
*
* @v gpio GPIO pin
* @v config Configuration
* @ret rc Return status code
*/
static inline int gpio_config ( struct gpio *gpio, unsigned int config ) {
struct gpios *gpios = gpio->gpios;
return gpios->op->config ( gpios, gpio, config );
}
extern struct gpios * alloc_gpios ( unsigned int count, size_t priv_len );
extern int gpios_register ( struct gpios *gpios );
extern void gpios_unregister ( struct gpios *gpios );
extern struct gpios * gpios_find ( unsigned int bus_type,
unsigned int location );
#endif /* _IPXE_GPIO_H */
|