Commit 2b3b1c668be539d897d2a9352bc8dca54467f425

Authored by Bo Shen
Committed by Albert ARIBAUD
1 parent 81f40345d1
Exists in master and in 57 other branches 8qm-imx_v2020.04_5.4.70_2.3.0, emb_lf-6.6.52-2.2.0, emb_lf_v2022.04, emb_lf_v2023.04, emb_lf_v2024.04, imx_v2015.04_4.1.15_1.0.0_ga, pitx_8mp_lf_v2020.04, smarc-8m-android-10.0.0_2.6.0, smarc-8m-android-11.0.0_2.0.0, smarc-8mp-android-11.0.0_2.0.0, smarc-emmc-imx_v2014.04_3.10.53_1.1.0_ga, smarc-emmc-imx_v2014.04_3.14.28_1.0.0_ga, smarc-imx-l5.0.0_1.0.0-ga, smarc-imx6_v2018.03_4.14.98_2.0.0_ga, smarc-imx7_v2017.03_4.9.11_1.0.0_ga, smarc-imx7_v2018.03_4.14.98_2.0.0_ga, smarc-imx_v2014.04_3.14.28_1.0.0_ga, smarc-imx_v2015.04_4.1.15_1.0.0_ga, smarc-imx_v2017.03_4.9.11_1.0.0_ga, smarc-imx_v2017.03_4.9.88_2.0.0_ga, smarc-imx_v2017.03_o8.1.0_1.3.0_8m, smarc-imx_v2018.03_4.14.78_1.0.0_ga, smarc-m6.0.1_2.1.0-ga, smarc-n7.1.2_2.0.0-ga, smarc-rel_imx_4.1.15_2.0.0_ga, smarc_8m-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8m-imx_v2019.04_4.19.35_1.1.0, smarc_8m_00d0-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8mm-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8mm-imx_v2019.04_4.19.35_1.1.0, smarc_8mm-imx_v2020.04_5.4.24_2.1.0, smarc_8mp_lf_v2020.04, smarc_8mq-imx_v2020.04_5.4.24_2.1.0, smarc_8mq_lf_v2020.04, ti-u-boot-2015.07, u-boot-2013.01.y, v2013.10, v2013.10-smarct33, v2013.10-smartmen, v2014.01, v2014.04, v2014.04-smarct33, v2014.04-smarct33-emmc, v2014.04-smartmen, v2014.07, v2014.07-smarct33, v2014.07-smartmen, v2015.07-smarct33, v2015.07-smarct33-emmc, v2015.07-smarct4x, v2016.05-dlt, v2016.05-smarct3x, v2016.05-smarct3x-emmc, v2016.05-smarct4x, v2017.01-smarct3x, v2017.01-smarct3x-emmc, v2017.01-smarct4x

ATMEL/PIO: Enable new feature of PIO on Atmel device

Enable new PIO feature supported by Atmel SoC.
Using CPU_HAS_PIO3 micro to enable PIO new feature.

Signed-off-by: Bo Shen <voice.shen@atmel.com>
Signed-off-by: Andreas Bießmann <andreas.devel@googlemail.com>

Showing 2 changed files with 167 additions and 3 deletions Side-by-side Diff

arch/arm/include/asm/arch-at91/at91_pio.h
... ... @@ -66,14 +66,50 @@
66 66 u32 puer; /* 0x64 Pull-up Enable Register */
67 67 u32 pusr; /* 0x68 Pad Pull-up Status Register */
68 68 u32 reserved4;
  69 +#if defined(CPU_HAS_PIO3)
  70 + u32 abcdsr1; /* 0x70 Peripheral ABCD Select Register 1 */
  71 + u32 abcdsr2; /* 0x74 Peripheral ABCD Select Register 2 */
  72 + u32 reserved5[2];
  73 + u32 ifscdr; /* 0x80 Input Filter SCLK Disable Register */
  74 + u32 ifscer; /* 0x84 Input Filter SCLK Enable Register */
  75 + u32 ifscsr; /* 0x88 Input Filter SCLK Status Register */
  76 + u32 scdr; /* 0x8C SCLK Divider Debouncing Register */
  77 + u32 ppddr; /* 0x90 Pad Pull-down Disable Register */
  78 + u32 ppder; /* 0x94 Pad Pull-down Enable Register */
  79 + u32 ppdsr; /* 0x98 Pad Pull-down Status Register */
  80 + u32 reserved6; /* */
  81 +#else
69 82 u32 asr; /* 0x70 Select A Register */
70 83 u32 bsr; /* 0x74 Select B Register */
71 84 u32 absr; /* 0x78 AB Select Status Register */
72 85 u32 reserved5[9]; /* */
  86 +#endif
73 87 u32 ower; /* 0xA0 Output Write Enable Register */
74 88 u32 owdr; /* 0xA4 Output Write Disable Register */
75   - u32 owsr; /* OxA8 utput Write Status Register */
  89 + u32 owsr; /* OxA8 Output Write Status Register */
  90 +#if defined(CPU_HAS_PIO3)
  91 + u32 reserved7; /* */
  92 + u32 aimer; /* 0xB0 Additional INT Modes Enable Register */
  93 + u32 aimdr; /* 0xB4 Additional INT Modes Disable Register */
  94 + u32 aimmr; /* 0xB8 Additional INT Modes Mask Register */
  95 + u32 reserved8; /* */
  96 + u32 esr; /* 0xC0 Edge Select Register */
  97 + u32 lsr; /* 0xC4 Level Select Register */
  98 + u32 elsr; /* 0xC8 Edge/Level Status Register */
  99 + u32 reserved9; /* 0xCC */
  100 + u32 fellsr; /* 0xD0 Falling /Low Level Select Register */
  101 + u32 rehlsr; /* 0xD4 Rising /High Level Select Register */
  102 + u32 frlhsr; /* 0xD8 Fall/Rise - Low/High Status Register */
  103 + u32 reserved10; /* */
  104 + u32 locksr; /* 0xE0 Lock Status */
  105 + u32 wpmr; /* 0xE4 Write Protect Mode Register */
  106 + u32 wpsr; /* 0xE8 Write Protect Status Register */
  107 + u32 reserved11[5]; /* */
  108 + u32 schmitt; /* 0x100 Schmitt Trigger Register */
  109 + u32 reserved12[63];
  110 +#else
76 111 u32 reserved6[85];
  112 +#endif
77 113 } at91_port_t;
78 114  
79 115 typedef union at91_pio {
... ... @@ -94,6 +130,13 @@
94 130 #ifdef CONFIG_AT91_GPIO
95 131 int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup);
96 132 int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup);
  133 +#if defined(CPU_HAS_PIO3)
  134 +int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup);
  135 +int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup);
  136 +int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div);
  137 +int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on);
  138 +int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin);
  139 +#endif
97 140 int at91_set_pio_input(unsigned port, unsigned pin, int use_pullup);
98 141 int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on);
99 142 int at91_set_pio_output(unsigned port, unsigned pin, int value);
drivers/gpio/at91_gpio.c
... ... @@ -86,7 +86,14 @@
86 86 mask = 1 << pin;
87 87 writel(mask, &pio->port[port].idr);
88 88 at91_set_pio_pullup(port, pin, use_pullup);
  89 +#if defined(CPU_HAS_PIO3)
  90 + writel(readl(&pio->port[port].abcdsr1) & ~mask,
  91 + &pio->port[port].abcdsr1);
  92 + writel(readl(&pio->port[port].abcdsr2) & ~mask,
  93 + &pio->port[port].abcdsr2);
  94 +#else
89 95 writel(mask, &pio->port[port].asr);
  96 +#endif
90 97 writel(mask, &pio->port[port].pdr);
91 98 }
92 99 return 0;
93 100  
94 101  
95 102  
... ... @@ -104,13 +111,64 @@
104 111 mask = 1 << pin;
105 112 writel(mask, &pio->port[port].idr);
106 113 at91_set_pio_pullup(port, pin, use_pullup);
  114 +#if defined(CPU_HAS_PIO3)
  115 + writel(readl(&pio->port[port].abcdsr1) | mask,
  116 + &pio->port[port].abcdsr1);
  117 + writel(readl(&pio->port[port].abcdsr2) & ~mask,
  118 + &pio->port[port].abcdsr2);
  119 +#else
107 120 writel(mask, &pio->port[port].bsr);
  121 +#endif
108 122 writel(mask, &pio->port[port].pdr);
109 123 }
110 124 return 0;
111 125 }
112 126  
  127 +#if defined(CPU_HAS_PIO3)
113 128 /*
  129 + * mux the pin to the "C" internal peripheral role.
  130 + */
  131 +int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup)
  132 +{
  133 + at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  134 + u32 mask;
  135 +
  136 + if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  137 + mask = 1 << pin;
  138 + writel(mask, &pio->port[port].idr);
  139 + at91_set_pio_pullup(port, pin, use_pullup);
  140 + writel(readl(&pio->port[port].abcdsr1) & ~mask,
  141 + &pio->port[port].abcdsr1);
  142 + writel(readl(&pio->port[port].abcdsr2) | mask,
  143 + &pio->port[port].abcdsr2);
  144 + writel(mask, &pio->port[port].pdr);
  145 + }
  146 + return 0;
  147 +}
  148 +
  149 +/*
  150 + * mux the pin to the "D" internal peripheral role.
  151 + */
  152 +int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup)
  153 +{
  154 + at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  155 + u32 mask;
  156 +
  157 + if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  158 + mask = 1 << pin;
  159 + writel(mask, &pio->port[port].idr);
  160 + at91_set_pio_pullup(port, pin, use_pullup);
  161 + writel(readl(&pio->port[port].abcdsr1) | mask,
  162 + &pio->port[port].abcdsr1);
  163 + writel(readl(&pio->port[port].abcdsr2) | mask,
  164 + &pio->port[port].abcdsr2);
  165 + writel(mask, &pio->port[port].pdr);
  166 + }
  167 + return 0;
  168 +}
  169 +#endif
  170 +
  171 +/*
114 172 * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and
115 173 * configure it for an input.
116 174 */
117 175  
118 176  
119 177  
... ... @@ -162,13 +220,76 @@
162 220  
163 221 if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
164 222 mask = 1 << pin;
165   - if (is_on)
  223 + if (is_on) {
  224 +#if defined(CPU_HAS_PIO3)
  225 + writel(mask, &pio->port[port].ifscdr);
  226 +#endif
166 227 writel(mask, &pio->port[port].ifer);
167   - else
  228 + } else {
168 229 writel(mask, &pio->port[port].ifdr);
  230 + }
169 231 }
170 232 return 0;
171 233 }
  234 +
  235 +#if defined(CPU_HAS_PIO3)
  236 +/*
  237 + * enable/disable the debounce filter.
  238 + */
  239 +int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div)
  240 +{
  241 + at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  242 + u32 mask;
  243 +
  244 + if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  245 + mask = 1 << pin;
  246 + if (is_on) {
  247 + writel(mask, &pio->port[port].ifscer);
  248 + writel(div & PIO_SCDR_DIV, &pio->port[port].scdr);
  249 + writel(mask, &pio->port[port].ifer);
  250 + } else {
  251 + writel(mask, &pio->port[port].ifdr);
  252 + }
  253 + }
  254 + return 0;
  255 +}
  256 +
  257 +/*
  258 + * enable/disable the pull-down.
  259 + * If pull-up already enabled while calling the function, we disable it.
  260 + */
  261 +int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on)
  262 +{
  263 + at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  264 + u32 mask;
  265 +
  266 + if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  267 + mask = 1 << pin;
  268 + writel(mask, &pio->port[port].pudr);
  269 + if (is_on)
  270 + writel(mask, &pio->port[port].ppder);
  271 + else
  272 + writel(mask, &pio->port[port].ppddr);
  273 + }
  274 + return 0;
  275 +}
  276 +
  277 +/*
  278 + * disable Schmitt trigger
  279 + */
  280 +int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin)
  281 +{
  282 + at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
  283 + u32 mask;
  284 +
  285 + if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
  286 + mask = 1 << pin;
  287 + writel(readl(&pio->port[port].schmitt) | mask,
  288 + &pio->port[port].schmitt);
  289 + }
  290 + return 0;
  291 +}
  292 +#endif
172 293  
173 294 /*
174 295 * enable/disable the multi-driver. This is only valid for output and