aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorChristian Ruppert <christian.ruppert@abilis.com>2013-06-13 08:55:31 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-06-17 12:18:28 -0400
commitc8587eeef8fc219e806e868c6f0c7170c769efab (patch)
treee97d8c30c967cf08b8b92d4653acebe52f942ca8 /drivers/pinctrl
parent5ace03fb6abfa3b316c7ee6a105959cb45bd4af4 (diff)
pinctrl: add pin list based GPIO ranges
Traditionally, GPIO ranges are based on consecutive ranges of both GPIO and pin numbers. This patch allows for GPIO ranges with arbitrary lists of pin numbers. Signed-off-by: Christian Ruppert <christian.ruppert@abilis.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/core.c59
1 files changed, 49 insertions, 10 deletions
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index dca9208f5463..33710b5e7bb5 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -283,6 +283,29 @@ static int pinctrl_register_pins(struct pinctrl_dev *pctldev,
283} 283}
284 284
285/** 285/**
286 * gpio_to_pin() - GPIO range GPIO number to pin number translation
287 * @range: GPIO range used for the translation
288 * @gpio: gpio pin to translate to a pin number
289 *
290 * Finds the pin number for a given GPIO using the specified GPIO range
291 * as a base for translation. The distinction between linear GPIO ranges
292 * and pin list based GPIO ranges is managed correctly by this function.
293 *
294 * This function assumes the gpio is part of the specified GPIO range, use
295 * only after making sure this is the case (e.g. by calling it on the
296 * result of successful pinctrl_get_device_gpio_range calls)!
297 */
298static inline int gpio_to_pin(struct pinctrl_gpio_range *range,
299 unsigned int gpio)
300{
301 unsigned int offset = gpio - range->base;
302 if (range->pins)
303 return range->pins[offset];
304 else
305 return range->pin_base + offset;
306}
307
308/**
286 * pinctrl_match_gpio_range() - check if a certain GPIO pin is in range 309 * pinctrl_match_gpio_range() - check if a certain GPIO pin is in range
287 * @pctldev: pin controller device to check 310 * @pctldev: pin controller device to check
288 * @gpio: gpio pin to check taken from the global GPIO pin space 311 * @gpio: gpio pin to check taken from the global GPIO pin space
@@ -448,8 +471,14 @@ pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev,
448 /* Loop over the ranges */ 471 /* Loop over the ranges */
449 list_for_each_entry(range, &pctldev->gpio_ranges, node) { 472 list_for_each_entry(range, &pctldev->gpio_ranges, node) {
450 /* Check if we're in the valid range */ 473 /* Check if we're in the valid range */
451 if (pin >= range->pin_base && 474 if (range->pins) {
452 pin < range->pin_base + range->npins) { 475 int a;
476 for (a = 0; a < range->npins; a++) {
477 if (range->pins[a] == pin)
478 return range;
479 }
480 } else if (pin >= range->pin_base &&
481 pin < range->pin_base + range->npins) {
453 mutex_unlock(&pctldev->mutex); 482 mutex_unlock(&pctldev->mutex);
454 return range; 483 return range;
455 } 484 }
@@ -529,7 +558,7 @@ int pinctrl_request_gpio(unsigned gpio)
529 } 558 }
530 559
531 /* Convert to the pin controllers number space */ 560 /* Convert to the pin controllers number space */
532 pin = gpio - range->base + range->pin_base; 561 pin = gpio_to_pin(range, gpio);
533 562
534 ret = pinmux_request_gpio(pctldev, range, pin, gpio); 563 ret = pinmux_request_gpio(pctldev, range, pin, gpio);
535 564
@@ -559,7 +588,7 @@ void pinctrl_free_gpio(unsigned gpio)
559 mutex_lock(&pctldev->mutex); 588 mutex_lock(&pctldev->mutex);
560 589
561 /* Convert to the pin controllers number space */ 590 /* Convert to the pin controllers number space */
562 pin = gpio - range->base + range->pin_base; 591 pin = gpio_to_pin(range, gpio);
563 592
564 pinmux_free_gpio(pctldev, pin, range); 593 pinmux_free_gpio(pctldev, pin, range);
565 594
@@ -582,7 +611,7 @@ static int pinctrl_gpio_direction(unsigned gpio, bool input)
582 mutex_lock(&pctldev->mutex); 611 mutex_lock(&pctldev->mutex);
583 612
584 /* Convert to the pin controllers number space */ 613 /* Convert to the pin controllers number space */
585 pin = gpio - range->base + range->pin_base; 614 pin = gpio_to_pin(range, gpio);
586 ret = pinmux_gpio_direction(pctldev, range, pin, input); 615 ret = pinmux_gpio_direction(pctldev, range, pin, input);
587 616
588 mutex_unlock(&pctldev->mutex); 617 mutex_unlock(&pctldev->mutex);
@@ -1349,11 +1378,21 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what)
1349 1378
1350 /* Loop over the ranges */ 1379 /* Loop over the ranges */
1351 list_for_each_entry(range, &pctldev->gpio_ranges, node) { 1380 list_for_each_entry(range, &pctldev->gpio_ranges, node) {
1352 seq_printf(s, "%u: %s GPIOS [%u - %u] PINS [%u - %u]\n", 1381 if (range->pins) {
1353 range->id, range->name, 1382 int a;
1354 range->base, (range->base + range->npins - 1), 1383 seq_printf(s, "%u: %s GPIOS [%u - %u] PINS {",
1355 range->pin_base, 1384 range->id, range->name,
1356 (range->pin_base + range->npins - 1)); 1385 range->base, (range->base + range->npins - 1));
1386 for (a = 0; a < range->npins - 1; a++)
1387 seq_printf(s, "%u, ", range->pins[a]);
1388 seq_printf(s, "%u}\n", range->pins[a]);
1389 }
1390 else
1391 seq_printf(s, "%u: %s GPIOS [%u - %u] PINS [%u - %u]\n",
1392 range->id, range->name,
1393 range->base, (range->base + range->npins - 1),
1394 range->pin_base,
1395 (range->pin_base + range->npins - 1));
1357 } 1396 }
1358 1397
1359 mutex_unlock(&pctldev->mutex); 1398 mutex_unlock(&pctldev->mutex);