aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorMarek Roszko <mark.roszko@gmail.com>2014-08-23 23:12:04 -0400
committerLinus Walleij <linus.walleij@linaro.org>2014-09-05 04:32:06 -0400
commit4334ac2db2be9e278c95fd15260c1f49f698ffc5 (patch)
treeb6e13a3fda5d1c41495b697abfb0c0a31eff52c3 /drivers/pinctrl
parent0d37899363b0e5486f8800231b7edd75e8b60942 (diff)
pinctrl: at91: add drive strength configuration
The SAMA5 and SAM9x5 series both have drive strength options for the PIOs. This patch adds the ability to set one of three hardware options for drive strengths of low, medium or high for the each pin. The actual current output of the chip based on the setting is defined in the datasheets and varies per pins separate from banks and with supply voltage. This patch adds three new dt-bindings that allow setting the strength when configuring pins. By default, no change will be made to the drive strength of a pin from its reset value. Due to the difference between the register addresses of the SAMA5 and SAM9x5 series, a new sama5d3-pinctrl id was added. Signed-off-by: Marek Roszko <mark.roszko@gmail.com> Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/pinctrl-at91.c162
1 files changed, 161 insertions, 1 deletions
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
index 4839c36a3a1c..03b748ea3810 100644
--- a/drivers/pinctrl/pinctrl-at91.c
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -58,11 +58,28 @@ static int gpio_banks;
58#define DEGLITCH (1 << 2) 58#define DEGLITCH (1 << 2)
59#define PULL_DOWN (1 << 3) 59#define PULL_DOWN (1 << 3)
60#define DIS_SCHMIT (1 << 4) 60#define DIS_SCHMIT (1 << 4)
61#define DRIVE_STRENGTH_SHIFT 5
62#define DRIVE_STRENGTH_MASK 0x3
63#define DRIVE_STRENGTH (DRIVE_STRENGTH_MASK << DRIVE_STRENGTH_SHIFT)
61#define DEBOUNCE (1 << 16) 64#define DEBOUNCE (1 << 16)
62#define DEBOUNCE_VAL_SHIFT 17 65#define DEBOUNCE_VAL_SHIFT 17
63#define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT) 66#define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT)
64 67
65/** 68/**
69 * These defines will translated the dt binding settings to our internal
70 * settings. They are not necessarily the same value as the register setting.
71 * The actual drive strength current of low, medium and high must be looked up
72 * from the corresponding device datasheet. This value is different for pins
73 * that are even in the same banks. It is also dependent on VCC.
74 * DRIVE_STRENGTH_DEFAULT is just a placeholder to avoid changing the drive
75 * strength when there is no dt config for it.
76 */
77#define DRIVE_STRENGTH_DEFAULT (0 << DRIVE_STRENGTH_SHIFT)
78#define DRIVE_STRENGTH_LOW (1 << DRIVE_STRENGTH_SHIFT)
79#define DRIVE_STRENGTH_MED (2 << DRIVE_STRENGTH_SHIFT)
80#define DRIVE_STRENGTH_HI (3 << DRIVE_STRENGTH_SHIFT)
81
82/**
66 * struct at91_pmx_func - describes AT91 pinmux functions 83 * struct at91_pmx_func - describes AT91 pinmux functions
67 * @name: the name of this specific function 84 * @name: the name of this specific function
68 * @groups: corresponding pin groups 85 * @groups: corresponding pin groups
@@ -148,6 +165,9 @@ struct at91_pinctrl_mux_ops {
148 void (*set_pulldown)(void __iomem *pio, unsigned mask, bool is_on); 165 void (*set_pulldown)(void __iomem *pio, unsigned mask, bool is_on);
149 bool (*get_schmitt_trig)(void __iomem *pio, unsigned pin); 166 bool (*get_schmitt_trig)(void __iomem *pio, unsigned pin);
150 void (*disable_schmitt_trig)(void __iomem *pio, unsigned mask); 167 void (*disable_schmitt_trig)(void __iomem *pio, unsigned mask);
168 unsigned (*get_drivestrength)(void __iomem *pio, unsigned pin);
169 void (*set_drivestrength)(void __iomem *pio, unsigned pin,
170 u32 strength);
151 /* irq */ 171 /* irq */
152 int (*irq_type)(struct irq_data *d, unsigned type); 172 int (*irq_type)(struct irq_data *d, unsigned type);
153}; 173};
@@ -315,6 +335,30 @@ static unsigned pin_to_mask(unsigned int pin)
315 return 1 << pin; 335 return 1 << pin;
316} 336}
317 337
338static unsigned two_bit_pin_value_shift_amount(unsigned int pin)
339{
340 /* return the shift value for a pin for "two bit" per pin registers,
341 * i.e. drive strength */
342 return 2*((pin >= MAX_NB_GPIO_PER_BANK/2)
343 ? pin - MAX_NB_GPIO_PER_BANK/2 : pin);
344}
345
346static unsigned sama5d3_get_drive_register(unsigned int pin)
347{
348 /* drive strength is split between two registers
349 * with two bits per pin */
350 return (pin >= MAX_NB_GPIO_PER_BANK/2)
351 ? SAMA5D3_PIO_DRIVER2 : SAMA5D3_PIO_DRIVER1;
352}
353
354static unsigned at91sam9x5_get_drive_register(unsigned int pin)
355{
356 /* drive strength is split between two registers
357 * with two bits per pin */
358 return (pin >= MAX_NB_GPIO_PER_BANK/2)
359 ? AT91SAM9X5_PIO_DRIVER2 : AT91SAM9X5_PIO_DRIVER1;
360}
361
318static void at91_mux_disable_interrupt(void __iomem *pio, unsigned mask) 362static void at91_mux_disable_interrupt(void __iomem *pio, unsigned mask)
319{ 363{
320 writel_relaxed(mask, pio + PIO_IDR); 364 writel_relaxed(mask, pio + PIO_IDR);
@@ -468,6 +512,79 @@ static bool at91_mux_pio3_get_schmitt_trig(void __iomem *pio, unsigned pin)
468 return (__raw_readl(pio + PIO_SCHMITT) >> pin) & 0x1; 512 return (__raw_readl(pio + PIO_SCHMITT) >> pin) & 0x1;
469} 513}
470 514
515static inline u32 read_drive_strength(void __iomem *reg, unsigned pin)
516{
517 unsigned tmp = __raw_readl(reg);
518
519 tmp = tmp >> two_bit_pin_value_shift_amount(pin);
520
521 return tmp & DRIVE_STRENGTH_MASK;
522}
523
524static unsigned at91_mux_sama5d3_get_drivestrength(void __iomem *pio,
525 unsigned pin)
526{
527 unsigned tmp = read_drive_strength(pio +
528 sama5d3_get_drive_register(pin), pin);
529
530 /* SAMA5 strength is 1:1 with our defines,
531 * except 0 is equivalent to low per datasheet */
532 if (!tmp)
533 tmp = DRIVE_STRENGTH_LOW;
534
535 return tmp;
536}
537
538static unsigned at91_mux_sam9x5_get_drivestrength(void __iomem *pio,
539 unsigned pin)
540{
541 unsigned tmp = read_drive_strength(pio +
542 at91sam9x5_get_drive_register(pin), pin);
543
544 /* strength is inverse in SAM9x5s hardware with the pinctrl defines
545 * hardware: 0 = hi, 1 = med, 2 = low, 3 = rsvd */
546 tmp = DRIVE_STRENGTH_HI - tmp;
547
548 return tmp;
549}
550
551static void set_drive_strength(void __iomem *reg, unsigned pin, u32 strength)
552{
553 unsigned tmp = __raw_readl(reg);
554 unsigned shift = two_bit_pin_value_shift_amount(pin);
555
556 tmp &= ~(DRIVE_STRENGTH_MASK << shift);
557 tmp |= strength << shift;
558
559 __raw_writel(tmp, reg);
560}
561
562static void at91_mux_sama5d3_set_drivestrength(void __iomem *pio, unsigned pin,
563 u32 setting)
564{
565 /* do nothing if setting is zero */
566 if (!setting)
567 return;
568
569 /* strength is 1 to 1 with setting for SAMA5 */
570 set_drive_strength(pio + sama5d3_get_drive_register(pin), pin, setting);
571}
572
573static void at91_mux_sam9x5_set_drivestrength(void __iomem *pio, unsigned pin,
574 u32 setting)
575{
576 /* do nothing if setting is zero */
577 if (!setting)
578 return;
579
580 /* strength is inverse on SAM9x5s with our defines
581 * 0 = hi, 1 = med, 2 = low, 3 = rsvd */
582 setting = DRIVE_STRENGTH_HI - setting;
583
584 set_drive_strength(pio + at91sam9x5_get_drive_register(pin), pin,
585 setting);
586}
587
471static struct at91_pinctrl_mux_ops at91rm9200_ops = { 588static struct at91_pinctrl_mux_ops at91rm9200_ops = {
472 .get_periph = at91_mux_get_periph, 589 .get_periph = at91_mux_get_periph,
473 .mux_A_periph = at91_mux_set_A_periph, 590 .mux_A_periph = at91_mux_set_A_periph,
@@ -491,6 +608,27 @@ static struct at91_pinctrl_mux_ops at91sam9x5_ops = {
491 .set_pulldown = at91_mux_pio3_set_pulldown, 608 .set_pulldown = at91_mux_pio3_set_pulldown,
492 .get_schmitt_trig = at91_mux_pio3_get_schmitt_trig, 609 .get_schmitt_trig = at91_mux_pio3_get_schmitt_trig,
493 .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig, 610 .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig,
611 .get_drivestrength = at91_mux_sam9x5_get_drivestrength,
612 .set_drivestrength = at91_mux_sam9x5_set_drivestrength,
613 .irq_type = alt_gpio_irq_type,
614};
615
616static struct at91_pinctrl_mux_ops sama5d3_ops = {
617 .get_periph = at91_mux_pio3_get_periph,
618 .mux_A_periph = at91_mux_pio3_set_A_periph,
619 .mux_B_periph = at91_mux_pio3_set_B_periph,
620 .mux_C_periph = at91_mux_pio3_set_C_periph,
621 .mux_D_periph = at91_mux_pio3_set_D_periph,
622 .get_deglitch = at91_mux_pio3_get_deglitch,
623 .set_deglitch = at91_mux_pio3_set_deglitch,
624 .get_debounce = at91_mux_pio3_get_debounce,
625 .set_debounce = at91_mux_pio3_set_debounce,
626 .get_pulldown = at91_mux_pio3_get_pulldown,
627 .set_pulldown = at91_mux_pio3_set_pulldown,
628 .get_schmitt_trig = at91_mux_pio3_get_schmitt_trig,
629 .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig,
630 .get_drivestrength = at91_mux_sama5d3_get_drivestrength,
631 .set_drivestrength = at91_mux_sama5d3_set_drivestrength,
494 .irq_type = alt_gpio_irq_type, 632 .irq_type = alt_gpio_irq_type,
495}; 633};
496 634
@@ -716,6 +854,9 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev,
716 *config |= PULL_DOWN; 854 *config |= PULL_DOWN;
717 if (info->ops->get_schmitt_trig && info->ops->get_schmitt_trig(pio, pin)) 855 if (info->ops->get_schmitt_trig && info->ops->get_schmitt_trig(pio, pin))
718 *config |= DIS_SCHMIT; 856 *config |= DIS_SCHMIT;
857 if (info->ops->get_drivestrength)
858 *config |= (info->ops->get_drivestrength(pio, pin)
859 << DRIVE_STRENGTH_SHIFT);
719 860
720 return 0; 861 return 0;
721} 862}
@@ -729,6 +870,7 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev,
729 void __iomem *pio; 870 void __iomem *pio;
730 int i; 871 int i;
731 unsigned long config; 872 unsigned long config;
873 unsigned pin;
732 874
733 for (i = 0; i < num_configs; i++) { 875 for (i = 0; i < num_configs; i++) {
734 config = configs[i]; 876 config = configs[i];
@@ -737,7 +879,8 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev,
737 "%s:%d, pin_id=%d, config=0x%lx", 879 "%s:%d, pin_id=%d, config=0x%lx",
738 __func__, __LINE__, pin_id, config); 880 __func__, __LINE__, pin_id, config);
739 pio = pin_to_controller(info, pin_to_bank(pin_id)); 881 pio = pin_to_controller(info, pin_to_bank(pin_id));
740 mask = pin_to_mask(pin_id % MAX_NB_GPIO_PER_BANK); 882 pin = pin_id % MAX_NB_GPIO_PER_BANK;
883 mask = pin_to_mask(pin);
741 884
742 if (config & PULL_UP && config & PULL_DOWN) 885 if (config & PULL_UP && config & PULL_DOWN)
743 return -EINVAL; 886 return -EINVAL;
@@ -753,6 +896,10 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev,
753 info->ops->set_pulldown(pio, mask, config & PULL_DOWN); 896 info->ops->set_pulldown(pio, mask, config & PULL_DOWN);
754 if (info->ops->disable_schmitt_trig && config & DIS_SCHMIT) 897 if (info->ops->disable_schmitt_trig && config & DIS_SCHMIT)
755 info->ops->disable_schmitt_trig(pio, mask); 898 info->ops->disable_schmitt_trig(pio, mask);
899 if (info->ops->set_drivestrength)
900 info->ops->set_drivestrength(pio, pin,
901 (config & DRIVE_STRENGTH)
902 >> DRIVE_STRENGTH_SHIFT);
756 903
757 } /* for each config */ 904 } /* for each config */
758 905
@@ -768,6 +915,15 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev,
768 } \ 915 } \
769} while (0) 916} while (0)
770 917
918#define DBG_SHOW_FLAG_MASKED(mask,flag) do { \
919 if ((config & mask) == flag) { \
920 if (num_conf) \
921 seq_puts(s, "|"); \
922 seq_puts(s, #flag); \
923 num_conf++; \
924 } \
925} while (0)
926
771static void at91_pinconf_dbg_show(struct pinctrl_dev *pctldev, 927static void at91_pinconf_dbg_show(struct pinctrl_dev *pctldev,
772 struct seq_file *s, unsigned pin_id) 928 struct seq_file *s, unsigned pin_id)
773{ 929{
@@ -781,6 +937,9 @@ static void at91_pinconf_dbg_show(struct pinctrl_dev *pctldev,
781 DBG_SHOW_FLAG(PULL_DOWN); 937 DBG_SHOW_FLAG(PULL_DOWN);
782 DBG_SHOW_FLAG(DIS_SCHMIT); 938 DBG_SHOW_FLAG(DIS_SCHMIT);
783 DBG_SHOW_FLAG(DEGLITCH); 939 DBG_SHOW_FLAG(DEGLITCH);
940 DBG_SHOW_FLAG_MASKED(DRIVE_STRENGTH, DRIVE_STRENGTH_LOW);
941 DBG_SHOW_FLAG_MASKED(DRIVE_STRENGTH, DRIVE_STRENGTH_MED);
942 DBG_SHOW_FLAG_MASKED(DRIVE_STRENGTH, DRIVE_STRENGTH_HI);
784 DBG_SHOW_FLAG(DEBOUNCE); 943 DBG_SHOW_FLAG(DEBOUNCE);
785 if (config & DEBOUNCE) { 944 if (config & DEBOUNCE) {
786 val = config >> DEBOUNCE_VAL_SHIFT; 945 val = config >> DEBOUNCE_VAL_SHIFT;
@@ -945,6 +1104,7 @@ static int at91_pinctrl_parse_functions(struct device_node *np,
945} 1104}
946 1105
947static struct of_device_id at91_pinctrl_of_match[] = { 1106static struct of_device_id at91_pinctrl_of_match[] = {
1107 { .compatible = "atmel,sama5d3-pinctrl", .data = &sama5d3_ops },
948 { .compatible = "atmel,at91sam9x5-pinctrl", .data = &at91sam9x5_ops }, 1108 { .compatible = "atmel,at91sam9x5-pinctrl", .data = &at91sam9x5_ops },
949 { .compatible = "atmel,at91rm9200-pinctrl", .data = &at91rm9200_ops }, 1109 { .compatible = "atmel,at91rm9200-pinctrl", .data = &at91rm9200_ops },
950 { /* sentinel */ } 1110 { /* sentinel */ }