summaryrefslogtreecommitdiffstats
path: root/include/gpio.h
blob: 81beb4730929e331203734168b1c748f1b9adfb8 (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
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __GPIO_H
#define __GPIO_H

#include <linux/types.h>
#include <linux/list.h>
#include <linux/iopoll.h>

#ifdef CONFIG_GENERIC_GPIO
void gpio_set_value(unsigned gpio, int value);
int gpio_get_value(unsigned gpio);
int gpio_direction_output(unsigned gpio, int value);
int gpio_direction_input(unsigned gpio);
#else
static inline void gpio_set_value(unsigned gpio, int value)
{
}
static inline int gpio_get_value(unsigned gpio)
{
	return 0;
}
static inline int gpio_direction_output(unsigned gpio, int value)
{
	return -EINVAL;
}
static inline int gpio_direction_input(unsigned gpio)
{
	return -EINVAL;
}
#endif

#ifdef CONFIG_GPIOLIB
void gpio_set_active(unsigned gpio, bool state);
int gpio_is_active(unsigned gpio);
int gpio_direction_active(unsigned gpio, bool state);

/**
 * gpio_poll_timeout_us - Poll till GPIO reaches requested active state
 * @gpio: gpio 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 gpio_poll_timeout_us(gpio, active, timeout_us)			\
	({								\
		int __state;						\
		readx_poll_timeout(gpio_is_active, gpio, __state,	\
				   __state == (active), timeout_us);	\
	})
#else
static inline void gpio_set_active(unsigned gpio, int value)
{
}
static inline int gpio_is_active(unsigned gpio)
{
	return 0;
}
static inline int gpio_direction_active(unsigned gpio, int value)
{
	return -EINVAL;
}

#define gpio_poll_timeout_us(gpio, val, timeout_us) (-ENOSYS)
#endif

#if defined(CONFIG_ARCH_NR_GPIO) && CONFIG_ARCH_NR_GPIO > 0
#define ARCH_NR_GPIOS CONFIG_ARCH_NR_GPIO
#else
#define ARCH_NR_GPIOS 256
#endif

static inline int gpio_is_valid(int gpio)
{
	if (gpio < 0)
		return 0;
	if (gpio < ARCH_NR_GPIOS)
		return 1;
	return 0;
}

#define GPIOF_DIR_OUT	(0 << 0)
#define GPIOF_DIR_IN	(1 << 0)

#define GPIOF_INIT_LOW	(0 << 1)
#define GPIOF_INIT_HIGH	(1 << 1)

#define GPIOF_IN		(GPIOF_DIR_IN)
#define GPIOF_OUT_INIT_LOW	(GPIOF_DIR_OUT | GPIOF_INIT_LOW)
#define GPIOF_OUT_INIT_HIGH	(GPIOF_DIR_OUT | GPIOF_INIT_HIGH)

#define GPIOF_LOGICAL		BIT(2)
#define GPIOF_ACTIVE_HIGH	GPIOF_LOGICAL
#define GPIOF_ACTIVE_LOW	(BIT(3) | GPIOF_LOGICAL)
#define GPIOF_INIT_INACTIVE	GPIOF_LOGICAL
#define GPIOF_INIT_ACTIVE	(GPIOF_LOGICAL | GPIOF_INIT_HIGH)
#define GPIOF_OUT_INIT_ACTIVE	(GPIOF_DIR_OUT | GPIOF_INIT_ACTIVE)
#define GPIOF_OUT_INIT_INACTIVE	(GPIOF_DIR_OUT | GPIOF_INIT_INACTIVE)

/**
 * struct gpio - a structure describing a GPIO with configuration
 * @gpio:	the GPIO number
 * @flags:	GPIO configuration as specified by GPIOF_*
 * @label:	a literal description string of this GPIO
 */
struct gpio {
	unsigned	gpio;
	unsigned long	flags;
	const char	*label;
};

#ifndef CONFIG_GPIOLIB
static inline int gpio_request(unsigned gpio, const char *label)
{
	return 0;
}

static inline int gpio_find_by_name(const char *name)
{
	return -ENOSYS;
}

static inline int gpio_find_by_label(const char *label)
{
	return -ENOSYS;
}

static inline void gpio_free(unsigned gpio)
{
}

static inline int gpio_request_one(unsigned gpio,
					unsigned long flags, const char *label)
{
	return -ENOSYS;
}

static inline int gpio_request_array(const struct gpio *array, size_t num)
{
	return -ENOSYS;
}

static inline void gpio_free_array(const struct gpio *array, size_t num)
{
	/* GPIO can never have been requested */
	WARN_ON(1);
}
static inline int gpio_array_to_id(const struct gpio *array, size_t num, u32 *val)
{
	return -EINVAL;
}
#else
int gpio_request(unsigned gpio, const char *label);
int gpio_find_by_name(const char *name);
int gpio_find_by_label(const char *label);
void gpio_free(unsigned gpio);
int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
int gpio_request_array(const struct gpio *array, size_t num);
void gpio_free_array(const struct gpio *array, size_t num);
int gpio_array_to_id(const struct gpio *array, size_t num, u32 *val);
#endif

struct gpio_chip;

struct gpio_ops {
	int (*request)(struct gpio_chip *chip, unsigned offset);
	void (*free)(struct gpio_chip *chip, unsigned offset);
	int (*direction_input)(struct gpio_chip *chip, unsigned offset);
	int (*direction_output)(struct gpio_chip *chip, unsigned offset, int value);
	int (*get_direction)(struct gpio_chip *chip, unsigned offset);
	int (*get)(struct gpio_chip *chip, unsigned offset);
	void (*set)(struct gpio_chip *chip, unsigned offset, int value);
};

struct gpio_chip {
	struct device_d *dev;

	int base;
	int ngpio;

	struct gpio_ops *ops;

	struct list_head list;
};

int gpiochip_add(struct gpio_chip *chip);
void gpiochip_remove(struct gpio_chip *chip);

int gpio_get_num(struct device_d *dev, int gpio);
struct gpio_chip *gpio_get_chip(int gpio);

#endif /* __GPIO_H */