summaryrefslogtreecommitdiffstats
path: root/include/linux/gpio/consumer.h
blob: e04f516b315554090a0d74941258b4a7557f2399 (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
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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_GPIO_CONSUMER_H
#define __LINUX_GPIO_CONSUMER_H

#include <gpio.h>
#include <of_gpio.h>
#include <driver.h>
#include <linux/bug.h>
#include <linux/iopoll.h>

/**
 * Optional flags that can be passed to one of gpiod_* to configure direction
 * and output value. These values cannot be OR'd.
 */
enum gpiod_flags {
	GPIOD_ASIS	= 0,
	GPIOD_IN	= GPIOF_IN,
	/*
	 * To change this later to a different logic level (i.e. taking
	 * active low into account), use gpiod_set_value()
	 */
	GPIOD_OUT_LOW	= GPIOF_OUT_INIT_INACTIVE,
	GPIOD_OUT_HIGH	= GPIOF_OUT_INIT_ACTIVE,
};

#define gpiod_not_found(desc)	(IS_ERR(desc) && PTR_ERR(desc) == -ENOENT)

struct gpio_desc;
struct gpio_array;

/**
 * struct gpio_descs - Struct containing an array of descriptors that can be
 *                     obtained using gpiod_get_array()
 *
 * @info:	Pointer to the opaque gpio_array structure
 * @ndescs:	Number of held descriptors
 * @desc:	Array of pointers to GPIO descriptors
 */
struct gpio_descs {
	unsigned int ndescs;
	/* info is used for fastpath, which we don't have in barebox.
	 * We define the member anyway, as not to change API
	 */
	struct gpio_array *info;
	DECLARE_FLEX_ARRAY(struct gpio_desc *, desc);
};

bool gpiod_slice_acquired(struct gpio_desc *);

#if defined(CONFIG_OFDEVICE) && defined(CONFIG_GPIOLIB)

/* returned gpio descriptor can be passed to any normal gpio_* function */
struct gpio_desc *dev_gpiod_get_index(struct device *dev,
			struct device_node *np,
			const char *_con_id, int index,
			enum gpiod_flags flags,
			const char *label);

#else
static inline struct gpio_desc *dev_gpiod_get_index(struct device *dev,
		struct device_node *np,
		const char *_con_id, int index,
		enum gpiod_flags flags,
		const char *label)
{
	return ERR_PTR(-ENODEV);
}
#endif

#ifdef CONFIG_GPIOLIB

int gpiod_direction_input(struct gpio_desc *desc);

int gpiod_direction_output_raw(struct gpio_desc *desc, int value);
int gpiod_direction_output(struct gpio_desc *desc, int value);

void gpiod_set_raw_value(struct gpio_desc *desc, int value);
void gpiod_set_value(struct gpio_desc *desc, int value);

int gpiod_get_raw_value(const struct gpio_desc *desc);
int gpiod_get_value(const struct gpio_desc *desc);

void gpiod_put(struct gpio_desc *desc);

int gpiod_count(struct device *dev, const char *con_id);

struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
						const char *con_id,
						enum gpiod_flags flags);

void gpiod_put_array(struct gpio_descs *descs);

int gpiod_set_array_value(unsigned int array_size,
			  struct gpio_desc **desc_array,
			  struct gpio_array *array_info,
			  unsigned long *value_bitmap);

#else

static inline int gpiod_direction_input(struct gpio_desc *desc)
{
	/* GPIO can never have been requested */
	WARN_ON(desc);
	return 0;
}

static inline int gpiod_direction_output_raw(struct gpio_desc *desc, int value)
{
	/* GPIO can never have been requested */
	WARN_ON(desc);
	return 0;
}

static inline int gpiod_direction_output(struct gpio_desc *desc, int value)
{
	/* GPIO can never have been requested */
	WARN_ON(desc);
	return 0;
}

static inline void gpiod_set_raw_value(struct gpio_desc *desc, int value)
{
	/* GPIO can never have been requested */
	WARN_ON(desc);
}

static inline void gpiod_set_value(struct gpio_desc *desc, int value)
{
	/* GPIO can never have been requested */
	WARN_ON(desc);
}

static inline int gpiod_get_raw_value(const struct gpio_desc *desc)
{
	/* GPIO can never have been requested */
	WARN_ON(desc);
	return 0;
}

static inline int gpiod_get_value(const struct gpio_desc *desc)
{
	/* GPIO can never have been requested */
	WARN_ON(desc);
	return 0;
}

static inline void gpiod_put(struct gpio_desc *desc)
{
	/* GPIO can never have been requested */
	WARN_ON(desc);
}

static inline int gpiod_count(struct device *dev, const char *con_id)
{
	return 0;
}

static inline struct gpio_descs *__must_check
gpiod_get_array(struct device *dev, const char *con_id, enum gpiod_flags flags)
{
	return ERR_PTR(-ENOSYS);
}

static inline void gpiod_put_array(struct gpio_descs *descs)
{
	/* GPIO can never have been requested */
	WARN_ON(descs);
}

static inline int gpiod_set_array_value(unsigned int array_size,
			  struct gpio_desc **desc_array,
			  struct gpio_array *array_info,
			  unsigned long *value_bitmap)
{
	/* GPIO can never have been requested */
	WARN_ON(desc_array);
	return 0;
}

#endif

static inline struct gpio_desc *dev_gpiod_get(struct device *dev,
				struct device_node *np,
				const char *con_id,
				enum gpiod_flags flags,
				const char *label)
{
	return dev_gpiod_get_index(dev, np, con_id, 0, flags, label);
}

static inline struct gpio_desc *gpiod_get(struct device *dev,
			    const char *_con_id,
			    enum gpiod_flags flags)
{
	return dev_gpiod_get(dev, dev->of_node, _con_id, flags, NULL);
}

static inline struct gpio_desc *__must_check
gpiod_get_optional(struct device *dev, const char *con_id,
		   enum gpiod_flags flags)
{
	struct gpio_desc *desc;

	desc = gpiod_get(dev, con_id, flags);
	if (gpiod_not_found(desc))
		return NULL;

	return desc;
}

/**
 * gpiod_poll_timeout_us - poll till gpio descriptor reaches requested active state
 * @gpiod: gpio descriptor to poll
 * @active: wait till gpio is active if true, wait till it's inactive if false
 * @timeout_us: timeout in microseconds
 *
 * during the wait barebox pollers are called, if any.
 */
#define gpiod_poll_timeout_us(gpiod, active, timeout_us)		\
	({								\
		int __state;						\
		readx_poll_timeout(gpiod_get_value, gpiod, __state,	\
				   __state == (active), timeout_us);	\
	})

#endif