diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2012-11-21 04:48:33 -0500 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2012-11-21 04:48:33 -0500 |
commit | 17d6b293e72547f75f5d9b680b75459cb8f2c9cf (patch) | |
tree | 54e794b046e0c7c1f819d49e9ff4499f9b6f19e5 /drivers/pinctrl | |
parent | e59d969f441fb8e25b30125bdf201153adc5a7e3 (diff) | |
parent | ad8a15d99cf2c8ab8ac1ab28402c49ec2548358d (diff) |
Merge branch 'delivery/pinctrl-at91-3.8' of http://github.com/at91linux/linux-at91 into at91
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/pinctrl-at91.c | 126 |
1 files changed, 125 insertions, 1 deletions
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index b9e2cbd2ea7b..0d7e6c3c33a7 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c | |||
@@ -59,6 +59,12 @@ static int gpio_banks; | |||
59 | 59 | ||
60 | #define PULL_UP (1 << 0) | 60 | #define PULL_UP (1 << 0) |
61 | #define MULTI_DRIVE (1 << 1) | 61 | #define MULTI_DRIVE (1 << 1) |
62 | #define DEGLITCH (1 << 2) | ||
63 | #define PULL_DOWN (1 << 3) | ||
64 | #define DIS_SCHMIT (1 << 4) | ||
65 | #define DEBOUNCE (1 << 16) | ||
66 | #define DEBOUNCE_VAL_SHIFT 17 | ||
67 | #define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT) | ||
62 | 68 | ||
63 | /** | 69 | /** |
64 | * struct at91_pmx_func - describes AT91 pinmux functions | 70 | * struct at91_pmx_func - describes AT91 pinmux functions |
@@ -122,6 +128,14 @@ struct at91_pin_group { | |||
122 | * @mux_B_periph: mux as periph B | 128 | * @mux_B_periph: mux as periph B |
123 | * @mux_C_periph: mux as periph C | 129 | * @mux_C_periph: mux as periph C |
124 | * @mux_D_periph: mux as periph D | 130 | * @mux_D_periph: mux as periph D |
131 | * @get_deglitch: get deglitch status | ||
132 | * @set_deglitch: enable/disable deglitch | ||
133 | * @get_debounce: get debounce status | ||
134 | * @set_debounce: enable/disable debounce | ||
135 | * @get_pulldown: get pulldown status | ||
136 | * @set_pulldown: enable/disable pulldown | ||
137 | * @get_schmitt_trig: get schmitt trigger status | ||
138 | * @disable_schmitt_trig: disable schmitt trigger | ||
125 | * @irq_type: return irq type | 139 | * @irq_type: return irq type |
126 | */ | 140 | */ |
127 | struct at91_pinctrl_mux_ops { | 141 | struct at91_pinctrl_mux_ops { |
@@ -130,6 +144,14 @@ struct at91_pinctrl_mux_ops { | |||
130 | void (*mux_B_periph)(void __iomem *pio, unsigned mask); | 144 | void (*mux_B_periph)(void __iomem *pio, unsigned mask); |
131 | void (*mux_C_periph)(void __iomem *pio, unsigned mask); | 145 | void (*mux_C_periph)(void __iomem *pio, unsigned mask); |
132 | void (*mux_D_periph)(void __iomem *pio, unsigned mask); | 146 | void (*mux_D_periph)(void __iomem *pio, unsigned mask); |
147 | bool (*get_deglitch)(void __iomem *pio, unsigned pin); | ||
148 | void (*set_deglitch)(void __iomem *pio, unsigned mask, bool in_on); | ||
149 | bool (*get_debounce)(void __iomem *pio, unsigned pin, u32 *div); | ||
150 | void (*set_debounce)(void __iomem *pio, unsigned mask, bool in_on, u32 div); | ||
151 | bool (*get_pulldown)(void __iomem *pio, unsigned pin); | ||
152 | void (*set_pulldown)(void __iomem *pio, unsigned mask, bool in_on); | ||
153 | bool (*get_schmitt_trig)(void __iomem *pio, unsigned pin); | ||
154 | void (*disable_schmitt_trig)(void __iomem *pio, unsigned mask); | ||
133 | /* irq */ | 155 | /* irq */ |
134 | int (*irq_type)(struct irq_data *d, unsigned type); | 156 | int (*irq_type)(struct irq_data *d, unsigned type); |
135 | }; | 157 | }; |
@@ -386,10 +408,68 @@ static enum at91_mux at91_mux_get_periph(void __iomem *pio, unsigned mask) | |||
386 | return select + 1; | 408 | return select + 1; |
387 | } | 409 | } |
388 | 410 | ||
411 | static bool at91_mux_get_deglitch(void __iomem *pio, unsigned pin) | ||
412 | { | ||
413 | return (__raw_readl(pio + PIO_IFSR) >> pin) & 0x1; | ||
414 | } | ||
415 | |||
416 | static void at91_mux_set_deglitch(void __iomem *pio, unsigned mask, bool is_on) | ||
417 | { | ||
418 | __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR)); | ||
419 | } | ||
420 | |||
421 | static void at91_mux_pio3_set_deglitch(void __iomem *pio, unsigned mask, bool is_on) | ||
422 | { | ||
423 | if (is_on) | ||
424 | __raw_writel(mask, pio + PIO_IFSCDR); | ||
425 | at91_mux_set_deglitch(pio, mask, is_on); | ||
426 | } | ||
427 | |||
428 | static bool at91_mux_pio3_get_debounce(void __iomem *pio, unsigned pin, u32 *div) | ||
429 | { | ||
430 | *div = __raw_readl(pio + PIO_SCDR); | ||
431 | |||
432 | return (__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1; | ||
433 | } | ||
434 | |||
435 | static void at91_mux_pio3_set_debounce(void __iomem *pio, unsigned mask, | ||
436 | bool is_on, u32 div) | ||
437 | { | ||
438 | if (is_on) { | ||
439 | __raw_writel(mask, pio + PIO_IFSCER); | ||
440 | __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR); | ||
441 | __raw_writel(mask, pio + PIO_IFER); | ||
442 | } else { | ||
443 | __raw_writel(mask, pio + PIO_IFDR); | ||
444 | } | ||
445 | } | ||
446 | |||
447 | static bool at91_mux_pio3_get_pulldown(void __iomem *pio, unsigned pin) | ||
448 | { | ||
449 | return (__raw_readl(pio + PIO_PPDSR) >> pin) & 0x1; | ||
450 | } | ||
451 | |||
452 | static void at91_mux_pio3_set_pulldown(void __iomem *pio, unsigned mask, bool is_on) | ||
453 | { | ||
454 | __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR)); | ||
455 | } | ||
456 | |||
457 | static void at91_mux_pio3_disable_schmitt_trig(void __iomem *pio, unsigned mask) | ||
458 | { | ||
459 | __raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT); | ||
460 | } | ||
461 | |||
462 | static bool at91_mux_pio3_get_schmitt_trig(void __iomem *pio, unsigned pin) | ||
463 | { | ||
464 | return (__raw_readl(pio + PIO_SCHMITT) >> pin) & 0x1; | ||
465 | } | ||
466 | |||
389 | static struct at91_pinctrl_mux_ops at91rm9200_ops = { | 467 | static struct at91_pinctrl_mux_ops at91rm9200_ops = { |
390 | .get_periph = at91_mux_get_periph, | 468 | .get_periph = at91_mux_get_periph, |
391 | .mux_A_periph = at91_mux_set_A_periph, | 469 | .mux_A_periph = at91_mux_set_A_periph, |
392 | .mux_B_periph = at91_mux_set_B_periph, | 470 | .mux_B_periph = at91_mux_set_B_periph, |
471 | .get_deglitch = at91_mux_get_deglitch, | ||
472 | .set_deglitch = at91_mux_set_deglitch, | ||
393 | .irq_type = gpio_irq_type, | 473 | .irq_type = gpio_irq_type, |
394 | }; | 474 | }; |
395 | 475 | ||
@@ -399,6 +479,14 @@ static struct at91_pinctrl_mux_ops at91sam9x5_ops = { | |||
399 | .mux_B_periph = at91_mux_pio3_set_B_periph, | 479 | .mux_B_periph = at91_mux_pio3_set_B_periph, |
400 | .mux_C_periph = at91_mux_pio3_set_C_periph, | 480 | .mux_C_periph = at91_mux_pio3_set_C_periph, |
401 | .mux_D_periph = at91_mux_pio3_set_D_periph, | 481 | .mux_D_periph = at91_mux_pio3_set_D_periph, |
482 | .get_deglitch = at91_mux_get_deglitch, | ||
483 | .set_deglitch = at91_mux_pio3_set_deglitch, | ||
484 | .get_debounce = at91_mux_pio3_get_debounce, | ||
485 | .set_debounce = at91_mux_pio3_set_debounce, | ||
486 | .get_pulldown = at91_mux_pio3_get_pulldown, | ||
487 | .set_pulldown = at91_mux_pio3_set_pulldown, | ||
488 | .get_schmitt_trig = at91_mux_pio3_get_schmitt_trig, | ||
489 | .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig, | ||
402 | .irq_type = alt_gpio_irq_type, | 490 | .irq_type = alt_gpio_irq_type, |
403 | }; | 491 | }; |
404 | 492 | ||
@@ -624,6 +712,7 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev, | |||
624 | struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | 712 | struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); |
625 | void __iomem *pio; | 713 | void __iomem *pio; |
626 | unsigned pin; | 714 | unsigned pin; |
715 | int div; | ||
627 | 716 | ||
628 | dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__, __LINE__, pin_id, *config); | 717 | dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__, __LINE__, pin_id, *config); |
629 | pio = pin_to_controller(info, pin_to_bank(pin_id)); | 718 | pio = pin_to_controller(info, pin_to_bank(pin_id)); |
@@ -635,6 +724,15 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev, | |||
635 | if (at91_mux_get_pullup(pio, pin)) | 724 | if (at91_mux_get_pullup(pio, pin)) |
636 | *config |= PULL_UP; | 725 | *config |= PULL_UP; |
637 | 726 | ||
727 | if (info->ops->get_deglitch && info->ops->get_deglitch(pio, pin)) | ||
728 | *config |= DEGLITCH; | ||
729 | if (info->ops->get_debounce && info->ops->get_debounce(pio, pin, &div)) | ||
730 | *config |= DEBOUNCE | (div << DEBOUNCE_VAL_SHIFT); | ||
731 | if (info->ops->get_pulldown && info->ops->get_pulldown(pio, pin)) | ||
732 | *config |= PULL_DOWN; | ||
733 | if (info->ops->get_schmitt_trig && info->ops->get_schmitt_trig(pio, pin)) | ||
734 | *config |= DIS_SCHMIT; | ||
735 | |||
638 | return 0; | 736 | return 0; |
639 | } | 737 | } |
640 | 738 | ||
@@ -649,8 +747,21 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev, | |||
649 | pio = pin_to_controller(info, pin_to_bank(pin_id)); | 747 | pio = pin_to_controller(info, pin_to_bank(pin_id)); |
650 | mask = pin_to_mask(pin_id % MAX_NB_GPIO_PER_BANK); | 748 | mask = pin_to_mask(pin_id % MAX_NB_GPIO_PER_BANK); |
651 | 749 | ||
750 | if (config & PULL_UP && config & PULL_DOWN) | ||
751 | return -EINVAL; | ||
752 | |||
652 | at91_mux_set_pullup(pio, mask, config & PULL_UP); | 753 | at91_mux_set_pullup(pio, mask, config & PULL_UP); |
653 | at91_mux_set_multidrive(pio, mask, config & MULTI_DRIVE); | 754 | at91_mux_set_multidrive(pio, mask, config & MULTI_DRIVE); |
755 | if (info->ops->set_deglitch) | ||
756 | info->ops->set_deglitch(pio, mask, config & DEGLITCH); | ||
757 | if (info->ops->set_debounce) | ||
758 | info->ops->set_debounce(pio, mask, config & DEBOUNCE, | ||
759 | (config & DEBOUNCE_VAL) >> DEBOUNCE_VAL_SHIFT); | ||
760 | if (info->ops->set_pulldown) | ||
761 | info->ops->set_pulldown(pio, mask, config & PULL_DOWN); | ||
762 | if (info->ops->disable_schmitt_trig && config & DIS_SCHMIT) | ||
763 | info->ops->disable_schmitt_trig(pio, mask); | ||
764 | |||
654 | return 0; | 765 | return 0; |
655 | } | 766 | } |
656 | 767 | ||
@@ -1364,9 +1475,10 @@ static int __devinit at91_gpio_probe(struct platform_device *pdev) | |||
1364 | struct gpio_chip *chip; | 1475 | struct gpio_chip *chip; |
1365 | struct pinctrl_gpio_range *range; | 1476 | struct pinctrl_gpio_range *range; |
1366 | int ret = 0; | 1477 | int ret = 0; |
1367 | int irq; | 1478 | int irq, i; |
1368 | int alias_idx = of_alias_get_id(np, "gpio"); | 1479 | int alias_idx = of_alias_get_id(np, "gpio"); |
1369 | uint32_t ngpio; | 1480 | uint32_t ngpio; |
1481 | char **names; | ||
1370 | 1482 | ||
1371 | BUG_ON(alias_idx >= ARRAY_SIZE(gpio_chips)); | 1483 | BUG_ON(alias_idx >= ARRAY_SIZE(gpio_chips)); |
1372 | if (gpio_chips[alias_idx]) { | 1484 | if (gpio_chips[alias_idx]) { |
@@ -1436,6 +1548,18 @@ static int __devinit at91_gpio_probe(struct platform_device *pdev) | |||
1436 | chip->ngpio = ngpio; | 1548 | chip->ngpio = ngpio; |
1437 | } | 1549 | } |
1438 | 1550 | ||
1551 | names = devm_kzalloc(&pdev->dev, sizeof(char*) * chip->ngpio, GFP_KERNEL); | ||
1552 | |||
1553 | if (!names) { | ||
1554 | ret = -ENOMEM; | ||
1555 | goto clk_err; | ||
1556 | } | ||
1557 | |||
1558 | for (i = 0; i < chip->ngpio; i++) | ||
1559 | names[i] = kasprintf(GFP_KERNEL, "pio%c%d", alias_idx + 'A', i); | ||
1560 | |||
1561 | chip->names = (const char*const*)names; | ||
1562 | |||
1439 | range = &at91_chip->range; | 1563 | range = &at91_chip->range; |
1440 | range->name = chip->label; | 1564 | range->name = chip->label; |
1441 | range->id = alias_idx; | 1565 | range->id = alias_idx; |