aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-at91.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/pinctrl-at91.c')
-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 */ }