aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/uniphier
diff options
context:
space:
mode:
authorMasahiro Yamada <yamada.masahiro@socionext.com>2016-05-31 04:05:14 -0400
committerLinus Walleij <linus.walleij@linaro.org>2016-05-31 06:46:18 -0400
commit72e5706aa786f6640b229717b7d9d537058c59cf (patch)
tree8e14a67f1e887411ac0dbdcd5daa139b18eeb3c4 /drivers/pinctrl/uniphier
parent9eaa98a63c8a34a807ba95e384aacd28fa60ddd9 (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.c25
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier.h2
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;
72enum uniphier_pin_drv_type { 73enum 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 */