diff options
-rw-r--r-- | Documentation/gpio.txt | 64 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 58 | ||||
-rw-r--r-- | include/asm-generic/gpio.h | 26 |
3 files changed, 148 insertions, 0 deletions
diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt index 1866c27eec69..c2c6e9b39bbe 100644 --- a/Documentation/gpio.txt +++ b/Documentation/gpio.txt | |||
@@ -253,6 +253,70 @@ pin setup (e.g. controlling which pin the GPIO uses, pullup/pulldown). | |||
253 | Also note that it's your responsibility to have stopped using a GPIO | 253 | Also note that it's your responsibility to have stopped using a GPIO |
254 | before you free it. | 254 | before you free it. |
255 | 255 | ||
256 | Considering in most cases GPIOs are actually configured right after they | ||
257 | are claimed, three additional calls are defined: | ||
258 | |||
259 | /* request a single GPIO, with initial configuration specified by | ||
260 | * 'flags', identical to gpio_request() wrt other arguments and | ||
261 | * return value | ||
262 | */ | ||
263 | int gpio_request_one(unsigned gpio, unsigned long flags, const char *label); | ||
264 | |||
265 | /* request multiple GPIOs in a single call | ||
266 | */ | ||
267 | int gpio_request_array(struct gpio *array, size_t num); | ||
268 | |||
269 | /* release multiple GPIOs in a single call | ||
270 | */ | ||
271 | void gpio_free_array(struct gpio *array, size_t num); | ||
272 | |||
273 | where 'flags' is currently defined to specify the following properties: | ||
274 | |||
275 | * GPIOF_DIR_IN - to configure direction as input | ||
276 | * GPIOF_DIR_OUT - to configure direction as output | ||
277 | |||
278 | * GPIOF_INIT_LOW - as output, set initial level to LOW | ||
279 | * GPIOF_INIT_HIGH - as output, set initial level to HIGH | ||
280 | |||
281 | since GPIOF_INIT_* are only valid when configured as output, so group valid | ||
282 | combinations as: | ||
283 | |||
284 | * GPIOF_IN - configure as input | ||
285 | * GPIOF_OUT_INIT_LOW - configured as output, initial level LOW | ||
286 | * GPIOF_OUT_INIT_HIGH - configured as output, initial level HIGH | ||
287 | |||
288 | In the future, these flags can be extended to support more properties such | ||
289 | as open-drain status. | ||
290 | |||
291 | Further more, to ease the claim/release of multiple GPIOs, 'struct gpio' is | ||
292 | introduced to encapsulate all three fields as: | ||
293 | |||
294 | struct gpio { | ||
295 | unsigned gpio; | ||
296 | unsigned long flags; | ||
297 | const char *label; | ||
298 | }; | ||
299 | |||
300 | A typical example of usage: | ||
301 | |||
302 | static struct gpio leds_gpios[] = { | ||
303 | { 32, GPIOF_OUT_INIT_HIGH, "Power LED" }, /* default to ON */ | ||
304 | { 33, GPIOF_OUT_INIT_LOW, "Green LED" }, /* default to OFF */ | ||
305 | { 34, GPIOF_OUT_INIT_LOW, "Red LED" }, /* default to OFF */ | ||
306 | { 35, GPIOF_OUT_INIT_LOW, "Blue LED" }, /* default to OFF */ | ||
307 | { ... }, | ||
308 | }; | ||
309 | |||
310 | err = gpio_request_one(31, GPIOF_IN, "Reset Button"); | ||
311 | if (err) | ||
312 | ... | ||
313 | |||
314 | err = gpio_request_array(leds_gpios, ARRAY_SIZE(leds_gpios)); | ||
315 | if (err) | ||
316 | ... | ||
317 | |||
318 | gpio_free_array(leds_gpios, ARRAY_SIZE(leds_gpios)); | ||
319 | |||
256 | 320 | ||
257 | GPIOs mapped to IRQs | 321 | GPIOs mapped to IRQs |
258 | -------------------- | 322 | -------------------- |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 350842ad3632..9006fdb26fea 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -1237,6 +1237,64 @@ void gpio_free(unsigned gpio) | |||
1237 | } | 1237 | } |
1238 | EXPORT_SYMBOL_GPL(gpio_free); | 1238 | EXPORT_SYMBOL_GPL(gpio_free); |
1239 | 1239 | ||
1240 | /** | ||
1241 | * gpio_request_one - request a single GPIO with initial configuration | ||
1242 | * @gpio: the GPIO number | ||
1243 | * @flags: GPIO configuration as specified by GPIOF_* | ||
1244 | * @label: a literal description string of this GPIO | ||
1245 | */ | ||
1246 | int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) | ||
1247 | { | ||
1248 | int err; | ||
1249 | |||
1250 | err = gpio_request(gpio, label); | ||
1251 | if (err) | ||
1252 | return err; | ||
1253 | |||
1254 | if (flags & GPIOF_DIR_IN) | ||
1255 | err = gpio_direction_input(gpio); | ||
1256 | else | ||
1257 | err = gpio_direction_output(gpio, | ||
1258 | (flags & GPIOF_INIT_HIGH) ? 1 : 0); | ||
1259 | |||
1260 | return err; | ||
1261 | } | ||
1262 | EXPORT_SYMBOL_GPL(gpio_request_one); | ||
1263 | |||
1264 | /** | ||
1265 | * gpio_request_array - request multiple GPIOs in a single call | ||
1266 | * @array: array of the 'struct gpio' | ||
1267 | * @num: how many GPIOs in the array | ||
1268 | */ | ||
1269 | int gpio_request_array(struct gpio *array, size_t num) | ||
1270 | { | ||
1271 | int i, err; | ||
1272 | |||
1273 | for (i = 0; i < num; i++, array++) { | ||
1274 | err = gpio_request_one(array->gpio, array->flags, array->label); | ||
1275 | if (err) | ||
1276 | goto err_free; | ||
1277 | } | ||
1278 | return 0; | ||
1279 | |||
1280 | err_free: | ||
1281 | while (i--) | ||
1282 | gpio_free((--array)->gpio); | ||
1283 | return err; | ||
1284 | } | ||
1285 | EXPORT_SYMBOL_GPL(gpio_request_array); | ||
1286 | |||
1287 | /** | ||
1288 | * gpio_free_array - release multiple GPIOs in a single call | ||
1289 | * @array: array of the 'struct gpio' | ||
1290 | * @num: how many GPIOs in the array | ||
1291 | */ | ||
1292 | void gpio_free_array(struct gpio *array, size_t num) | ||
1293 | { | ||
1294 | while (num--) | ||
1295 | gpio_free((array++)->gpio); | ||
1296 | } | ||
1297 | EXPORT_SYMBOL_GPL(gpio_free_array); | ||
1240 | 1298 | ||
1241 | /** | 1299 | /** |
1242 | * gpiochip_is_requested - return string iff signal was requested | 1300 | * gpiochip_is_requested - return string iff signal was requested |
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 485eeb6c4ef3..979c6a57f2f1 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h | |||
@@ -136,6 +136,32 @@ extern int __gpio_cansleep(unsigned gpio); | |||
136 | 136 | ||
137 | extern int __gpio_to_irq(unsigned gpio); | 137 | extern int __gpio_to_irq(unsigned gpio); |
138 | 138 | ||
139 | #define GPIOF_DIR_OUT (0 << 0) | ||
140 | #define GPIOF_DIR_IN (1 << 0) | ||
141 | |||
142 | #define GPIOF_INIT_LOW (0 << 1) | ||
143 | #define GPIOF_INIT_HIGH (1 << 1) | ||
144 | |||
145 | #define GPIOF_IN (GPIOF_DIR_IN) | ||
146 | #define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW) | ||
147 | #define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH) | ||
148 | |||
149 | /** | ||
150 | * struct gpio - a structure describing a GPIO with configuration | ||
151 | * @gpio: the GPIO number | ||
152 | * @flags: GPIO configuration as specified by GPIOF_* | ||
153 | * @label: a literal description string of this GPIO | ||
154 | */ | ||
155 | struct gpio { | ||
156 | unsigned gpio; | ||
157 | unsigned long flags; | ||
158 | const char *label; | ||
159 | }; | ||
160 | |||
161 | extern int gpio_request_one(unsigned gpio, unsigned long flags, const char *label); | ||
162 | extern int gpio_request_array(struct gpio *array, size_t num); | ||
163 | extern void gpio_free_array(struct gpio *array, size_t num); | ||
164 | |||
139 | #ifdef CONFIG_GPIO_SYSFS | 165 | #ifdef CONFIG_GPIO_SYSFS |
140 | 166 | ||
141 | /* | 167 | /* |