[08/17] pinctrl: uniphier: support 3-bit drive strength control
diff mbox

Message ID 1464681923-7469-9-git-send-email-yamada.masahiro@socionext.com
State New, archived
Headers show

Commit Message

Masahiro Yamada May 31, 2016, 8:05 a.m. UTC
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>
---

 drivers/pinctrl/uniphier/pinctrl-uniphier-core.c | 25 ++++++++++++++++++------
 drivers/pinctrl/uniphier/pinctrl-uniphier.h      |  2 ++
 2 files changed, 21 insertions(+), 6 deletions(-)

Comments

Linus Walleij May 31, 2016, 10:46 a.m. UTC | #1
On Tue, May 31, 2016 at 10:05 AM, Masahiro Yamada
<yamada.masahiro@socionext.com> wrote:

> 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>

Patch applied.

Yours,
Linus Walleij

Patch
diff mbox

diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c
index 7f7274e..017b84f 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,
 	case UNIPHIER_PIN_DRV_2BIT:
 		drv_type = "8/12/16/20(mA)";
 		break;
+	case UNIPHIER_PIN_DRV_3BIT:
+		drv_type = "4/5/7/9/11/12/14/16(mA)";
+		break;
 	case UNIPHIER_PIN_DRV_FIXED4:
 		drv_type = "4(mA)";
 		break;
@@ -184,6 +187,7 @@  static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev,
 				uniphier_pin_get_drv_type(pin->drv_data);
 	const unsigned int strength_1bit[] = {4, 8};
 	const unsigned int strength_2bit[] = {8, 12, 16, 20};
+	const unsigned int strength_3bit[] = {4, 5, 7, 9, 11, 12, 14, 16};
 	const unsigned int *supported_strength;
 	unsigned int drvctrl, reg, shift, mask, width, val;
 	int ret;
@@ -191,12 +195,19 @@  static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev,
 	switch (type) {
 	case UNIPHIER_PIN_DRV_1BIT:
 		supported_strength = strength_1bit;
+		reg = UNIPHIER_PINCTRL_DRVCTRL_BASE;
 		width = 1;
 		break;
 	case UNIPHIER_PIN_DRV_2BIT:
 		supported_strength = strength_2bit;
+		reg = UNIPHIER_PINCTRL_DRV2CTRL_BASE;
 		width = 2;
 		break;
+	case UNIPHIER_PIN_DRV_3BIT:
+		supported_strength = strength_3bit;
+		reg = UNIPHIER_PINCTRL_DRV3CTRL_BASE;
+		width = 4;
+		break;
 	case UNIPHIER_PIN_DRV_FIXED4:
 		*strength = 4;
 		return 0;
@@ -214,9 +225,6 @@  static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev,
 	drvctrl = uniphier_pin_get_drvctrl(pin->drv_data);
 	drvctrl *= width;
 
-	reg = (width == 2) ? UNIPHIER_PINCTRL_DRV2CTRL_BASE :
-			     UNIPHIER_PINCTRL_DRVCTRL_BASE;
-
 	reg += drvctrl / 32 * 4;
 	shift = drvctrl % 32;
 	mask = (1U << width) - 1;
@@ -368,18 +376,26 @@  static int uniphier_conf_pin_drive_set(struct pinctrl_dev *pctldev,
 				uniphier_pin_get_drv_type(pin->drv_data);
 	const unsigned int strength_1bit[] = {4, 8, -1};
 	const unsigned int strength_2bit[] = {8, 12, 16, 20, -1};
+	const unsigned int strength_3bit[] = {4, 5, 7, 9, 11, 12, 14, 16, -1};
 	const unsigned int *supported_strength;
 	unsigned int drvctrl, reg, shift, mask, width, val;
 
 	switch (type) {
 	case UNIPHIER_PIN_DRV_1BIT:
 		supported_strength = strength_1bit;
+		reg = UNIPHIER_PINCTRL_DRVCTRL_BASE;
 		width = 1;
 		break;
 	case UNIPHIER_PIN_DRV_2BIT:
 		supported_strength = strength_2bit;
+		reg = UNIPHIER_PINCTRL_DRV2CTRL_BASE;
 		width = 2;
 		break;
+	case UNIPHIER_PIN_DRV_3BIT:
+		supported_strength = strength_3bit;
+		reg = UNIPHIER_PINCTRL_DRV3CTRL_BASE;
+		width = 4;
+		break;
 	default:
 		dev_err(pctldev->dev,
 			"cannot change drive strength for pin %u (%s)\n",
@@ -404,9 +420,6 @@  static int uniphier_conf_pin_drive_set(struct pinctrl_dev *pctldev,
 	drvctrl = uniphier_pin_get_drvctrl(pin->drv_data);
 	drvctrl *= width;
 
-	reg = (width == 2) ? UNIPHIER_PINCTRL_DRV2CTRL_BASE :
-			     UNIPHIER_PINCTRL_DRVCTRL_BASE;
-
 	reg += drvctrl / 32 * 4;
 	shift = drvctrl % 32;
 	mask = (1U << width) - 1;
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier.h b/drivers/pinctrl/uniphier/pinctrl-uniphier.h
index 7f3e7ff..eca379a 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier.h
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier.h
@@ -25,6 +25,7 @@  struct platform_device;
 #define UNIPHIER_PINCTRL_LOAD_PINMUX	0x700
 #define UNIPHIER_PINCTRL_DRVCTRL_BASE	0x800
 #define UNIPHIER_PINCTRL_DRV2CTRL_BASE	0x900
+#define UNIPHIER_PINCTRL_DRV3CTRL_BASE	0x980
 #define UNIPHIER_PINCTRL_PUPDCTRL_BASE	0xa00
 #define UNIPHIER_PINCTRL_IECTRL		0xd00
 
@@ -72,6 +73,7 @@  struct platform_device;
 enum uniphier_pin_drv_type {
 	UNIPHIER_PIN_DRV_1BIT,		/* 2 level control: 4/8 mA */
 	UNIPHIER_PIN_DRV_2BIT,		/* 4 level control: 8/12/16/20 mA */
+	UNIPHIER_PIN_DRV_3BIT,		/* 8 level control: 4/5/7/9/11/12/14/16 mA */
 	UNIPHIER_PIN_DRV_FIXED4,	/* fixed to 4mA */
 	UNIPHIER_PIN_DRV_FIXED5,	/* fixed to 5mA */
 	UNIPHIER_PIN_DRV_FIXED8,	/* fixed to 8mA */