diff options
author | Masahiro Yamada <yamada.masahiro@socionext.com> | 2016-05-31 04:05:14 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2016-05-31 06:46:18 -0400 |
commit | 72e5706aa786f6640b229717b7d9d537058c59cf (patch) | |
tree | 8e14a67f1e887411ac0dbdcd5daa139b18eeb3c4 /drivers/pinctrl/uniphier | |
parent | 9eaa98a63c8a34a807ba95e384aacd28fa60ddd9 (diff) |
pinctrl: uniphier: support 3-bit drive strength control
The new ARMv8 SoC, PH1-LD20, supports more fine-grained drive
strength control. Drive strength of some pins are controlled by
3-bit width registers (8-level granularity).
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/uniphier')
-rw-r--r-- | drivers/pinctrl/uniphier/pinctrl-uniphier-core.c | 25 | ||||
-rw-r--r-- | drivers/pinctrl/uniphier/pinctrl-uniphier.h | 2 |
2 files changed, 21 insertions, 6 deletions
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c index 7f7274eae36a..017b84fd9333 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c | |||
@@ -94,6 +94,9 @@ static void uniphier_pctl_pin_dbg_show(struct pinctrl_dev *pctldev, | |||
94 | case UNIPHIER_PIN_DRV_2BIT: | 94 | case UNIPHIER_PIN_DRV_2BIT: |
95 | drv_type = "8/12/16/20(mA)"; | 95 | drv_type = "8/12/16/20(mA)"; |
96 | break; | 96 | break; |
97 | case UNIPHIER_PIN_DRV_3BIT: | ||
98 | drv_type = "4/5/7/9/11/12/14/16(mA)"; | ||
99 | break; | ||
97 | case UNIPHIER_PIN_DRV_FIXED4: | 100 | case UNIPHIER_PIN_DRV_FIXED4: |
98 | drv_type = "4(mA)"; | 101 | drv_type = "4(mA)"; |
99 | break; | 102 | break; |
@@ -184,6 +187,7 @@ static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev, | |||
184 | uniphier_pin_get_drv_type(pin->drv_data); | 187 | uniphier_pin_get_drv_type(pin->drv_data); |
185 | const unsigned int strength_1bit[] = {4, 8}; | 188 | const unsigned int strength_1bit[] = {4, 8}; |
186 | const unsigned int strength_2bit[] = {8, 12, 16, 20}; | 189 | const unsigned int strength_2bit[] = {8, 12, 16, 20}; |
190 | const unsigned int strength_3bit[] = {4, 5, 7, 9, 11, 12, 14, 16}; | ||
187 | const unsigned int *supported_strength; | 191 | const unsigned int *supported_strength; |
188 | unsigned int drvctrl, reg, shift, mask, width, val; | 192 | unsigned int drvctrl, reg, shift, mask, width, val; |
189 | int ret; | 193 | int ret; |
@@ -191,12 +195,19 @@ static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev, | |||
191 | switch (type) { | 195 | switch (type) { |
192 | case UNIPHIER_PIN_DRV_1BIT: | 196 | case UNIPHIER_PIN_DRV_1BIT: |
193 | supported_strength = strength_1bit; | 197 | supported_strength = strength_1bit; |
198 | reg = UNIPHIER_PINCTRL_DRVCTRL_BASE; | ||
194 | width = 1; | 199 | width = 1; |
195 | break; | 200 | break; |
196 | case UNIPHIER_PIN_DRV_2BIT: | 201 | case UNIPHIER_PIN_DRV_2BIT: |
197 | supported_strength = strength_2bit; | 202 | supported_strength = strength_2bit; |
203 | reg = UNIPHIER_PINCTRL_DRV2CTRL_BASE; | ||
198 | width = 2; | 204 | width = 2; |
199 | break; | 205 | break; |
206 | case UNIPHIER_PIN_DRV_3BIT: | ||
207 | supported_strength = strength_3bit; | ||
208 | reg = UNIPHIER_PINCTRL_DRV3CTRL_BASE; | ||
209 | width = 4; | ||
210 | break; | ||
200 | case UNIPHIER_PIN_DRV_FIXED4: | 211 | case UNIPHIER_PIN_DRV_FIXED4: |
201 | *strength = 4; | 212 | *strength = 4; |
202 | return 0; | 213 | return 0; |
@@ -214,9 +225,6 @@ static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev, | |||
214 | drvctrl = uniphier_pin_get_drvctrl(pin->drv_data); | 225 | drvctrl = uniphier_pin_get_drvctrl(pin->drv_data); |
215 | drvctrl *= width; | 226 | drvctrl *= width; |
216 | 227 | ||
217 | reg = (width == 2) ? UNIPHIER_PINCTRL_DRV2CTRL_BASE : | ||
218 | UNIPHIER_PINCTRL_DRVCTRL_BASE; | ||
219 | |||
220 | reg += drvctrl / 32 * 4; | 228 | reg += drvctrl / 32 * 4; |
221 | shift = drvctrl % 32; | 229 | shift = drvctrl % 32; |
222 | mask = (1U << width) - 1; | 230 | mask = (1U << width) - 1; |
@@ -368,18 +376,26 @@ static int uniphier_conf_pin_drive_set(struct pinctrl_dev *pctldev, | |||
368 | uniphier_pin_get_drv_type(pin->drv_data); | 376 | uniphier_pin_get_drv_type(pin->drv_data); |
369 | const unsigned int strength_1bit[] = {4, 8, -1}; | 377 | const unsigned int strength_1bit[] = {4, 8, -1}; |
370 | const unsigned int strength_2bit[] = {8, 12, 16, 20, -1}; | 378 | const unsigned int strength_2bit[] = {8, 12, 16, 20, -1}; |
379 | const unsigned int strength_3bit[] = {4, 5, 7, 9, 11, 12, 14, 16, -1}; | ||
371 | const unsigned int *supported_strength; | 380 | const unsigned int *supported_strength; |
372 | unsigned int drvctrl, reg, shift, mask, width, val; | 381 | unsigned int drvctrl, reg, shift, mask, width, val; |
373 | 382 | ||
374 | switch (type) { | 383 | switch (type) { |
375 | case UNIPHIER_PIN_DRV_1BIT: | 384 | case UNIPHIER_PIN_DRV_1BIT: |
376 | supported_strength = strength_1bit; | 385 | supported_strength = strength_1bit; |
386 | reg = UNIPHIER_PINCTRL_DRVCTRL_BASE; | ||
377 | width = 1; | 387 | width = 1; |
378 | break; | 388 | break; |
379 | case UNIPHIER_PIN_DRV_2BIT: | 389 | case UNIPHIER_PIN_DRV_2BIT: |
380 | supported_strength = strength_2bit; | 390 | supported_strength = strength_2bit; |
391 | reg = UNIPHIER_PINCTRL_DRV2CTRL_BASE; | ||
381 | width = 2; | 392 | width = 2; |
382 | break; | 393 | break; |
394 | case UNIPHIER_PIN_DRV_3BIT: | ||
395 | supported_strength = strength_3bit; | ||
396 | reg = UNIPHIER_PINCTRL_DRV3CTRL_BASE; | ||
397 | width = 4; | ||
398 | break; | ||
383 | default: | 399 | default: |
384 | dev_err(pctldev->dev, | 400 | dev_err(pctldev->dev, |
385 | "cannot change drive strength for pin %u (%s)\n", | 401 | "cannot change drive strength for pin %u (%s)\n", |
@@ -404,9 +420,6 @@ static int uniphier_conf_pin_drive_set(struct pinctrl_dev *pctldev, | |||
404 | drvctrl = uniphier_pin_get_drvctrl(pin->drv_data); | 420 | drvctrl = uniphier_pin_get_drvctrl(pin->drv_data); |
405 | drvctrl *= width; | 421 | drvctrl *= width; |
406 | 422 | ||
407 | reg = (width == 2) ? UNIPHIER_PINCTRL_DRV2CTRL_BASE : | ||
408 | UNIPHIER_PINCTRL_DRVCTRL_BASE; | ||
409 | |||
410 | reg += drvctrl / 32 * 4; | 423 | reg += drvctrl / 32 * 4; |
411 | shift = drvctrl % 32; | 424 | shift = drvctrl % 32; |
412 | mask = (1U << width) - 1; | 425 | mask = (1U << width) - 1; |
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier.h b/drivers/pinctrl/uniphier/pinctrl-uniphier.h index 7f3e7ffe0096..eca379a2b976 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier.h +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier.h | |||
@@ -25,6 +25,7 @@ struct platform_device; | |||
25 | #define UNIPHIER_PINCTRL_LOAD_PINMUX 0x700 | 25 | #define UNIPHIER_PINCTRL_LOAD_PINMUX 0x700 |
26 | #define UNIPHIER_PINCTRL_DRVCTRL_BASE 0x800 | 26 | #define UNIPHIER_PINCTRL_DRVCTRL_BASE 0x800 |
27 | #define UNIPHIER_PINCTRL_DRV2CTRL_BASE 0x900 | 27 | #define UNIPHIER_PINCTRL_DRV2CTRL_BASE 0x900 |
28 | #define UNIPHIER_PINCTRL_DRV3CTRL_BASE 0x980 | ||
28 | #define UNIPHIER_PINCTRL_PUPDCTRL_BASE 0xa00 | 29 | #define UNIPHIER_PINCTRL_PUPDCTRL_BASE 0xa00 |
29 | #define UNIPHIER_PINCTRL_IECTRL 0xd00 | 30 | #define UNIPHIER_PINCTRL_IECTRL 0xd00 |
30 | 31 | ||
@@ -72,6 +73,7 @@ struct platform_device; | |||
72 | enum uniphier_pin_drv_type { | 73 | enum uniphier_pin_drv_type { |
73 | UNIPHIER_PIN_DRV_1BIT, /* 2 level control: 4/8 mA */ | 74 | UNIPHIER_PIN_DRV_1BIT, /* 2 level control: 4/8 mA */ |
74 | UNIPHIER_PIN_DRV_2BIT, /* 4 level control: 8/12/16/20 mA */ | 75 | UNIPHIER_PIN_DRV_2BIT, /* 4 level control: 8/12/16/20 mA */ |
76 | UNIPHIER_PIN_DRV_3BIT, /* 8 level control: 4/5/7/9/11/12/14/16 mA */ | ||
75 | UNIPHIER_PIN_DRV_FIXED4, /* fixed to 4mA */ | 77 | UNIPHIER_PIN_DRV_FIXED4, /* fixed to 4mA */ |
76 | UNIPHIER_PIN_DRV_FIXED5, /* fixed to 5mA */ | 78 | UNIPHIER_PIN_DRV_FIXED5, /* fixed to 5mA */ |
77 | UNIPHIER_PIN_DRV_FIXED8, /* fixed to 8mA */ | 79 | UNIPHIER_PIN_DRV_FIXED8, /* fixed to 8mA */ |