All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
@ 2017-06-05 12:11 ` Baolin Wang
  0 siblings, 0 replies; 24+ messages in thread
From: Baolin Wang @ 2017-06-05 12:11 UTC (permalink / raw)
  To: linus.walleij, mark.rutland, robh+dt
  Cc: linux-gpio, devicetree, linux-kernel, broonie, baolin.wang, baolin.wang

This patch adds the binding documentation for Spreadtrum SC9860 pin
controller device.

Signed-off-by: Baolin Wang <baolin.wang@spreadtrum.com>
---
Changes since v1:
 - Remove magic numbers and get to use the standard bindings.
 - Fix some typos.
---
 .../devicetree/bindings/pinctrl/sprd,pinctrl.txt   |   56 +++++++++++++++++
 .../bindings/pinctrl/sprd,sc9860-pinctrl.txt       |   66 ++++++++++++++++++++
 2 files changed, 122 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/sprd,pinctrl.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/sprd,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/sprd,pinctrl.txt
new file mode 100644
index 0000000..2f544cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/sprd,pinctrl.txt
@@ -0,0 +1,56 @@
+* Spreadtrum Pin Controller
+
+The Spreadtrum pin controller are organized in 3 blocks (types).
+
+The first block comprises some global control registers, and each
+register contains several bit fields with one bit or several bits
+to configure for some global common configuration, such as domain
+pad driving level, system control select and so on. We recognise
+every fields comprising one bit or several bits in one global control
+register as one pin, thus we should record every pin's bit offset,
+bit width and register offset to configure this field (pin). Since
+this type pins' configuration are very tricky and different for each
+register, we introduce "sprd,ctrl" property to set the various global
+control configuration.
+
+The second block comprises some common registers which have unified
+register definition, and each register described one pin is used
+to configure the pin sleep mode and function select. Now we have 4
+systems on SC9860 SoC: AP system, PUBCP system, TGLDSP system and
+AGDSP system. In some situation we have some pin-sleep related
+configuration need to set when one of system goes into deep sleep
+mode. For example, if we set the pin sleep mode as AP_SLEEP, which
+means when AP system goes into deep sleep mode, this pin's sleep
+related properties (input/output or pullup/down) will be set
+automatically. Thus we intoduce "sprd,sleep_mode" to set pin sleep
+mode.
+
+The last block comprises some misc registers which also have unified
+register definition, and each register described one pin is used to
+configure drive strength, pull up/down and so on. Especially for pull
+up, we introduce "sprd,pullup" property for two kind configuration:
+PULLUP_20K or PULLUP_4_7K, which means the pullup resistor is 20K or
+4.7K.
+
+Required properties for Spreadtrum pin controller:
+- compatible: "sprd,<soc>-pinctrl"
+  Please refer to each sprd,<soc>-pinctrl.txt binding doc for supported SoCs.
+- reg: The register address of pin controller device.
+- pins : An array of pin names.
+
+Optional properties:
+- function: Specified the function name.
+- drive-strength: Drive strength in mA.
+- input-schmitt-disable: Enable schmitt-trigger mode.
+- input-schmitt-enable: Disable schmitt-trigger mode.
+- bias-disable: Disable pin bias.
+- bias-pull-down: Pull down on pin.
+- sprd,ctrl: Control values referring to databook for global control pins.
+- sprd,sleep_mode: Sleep mode selection.
+- sprd,pullup: Pull up on pin.
+- sprd,input-sleep: Input enable when system goes into deep sleep mode.
+- sprd,output-sleep: Output enable when system goes into deep sleep mode.
+- sprd,pullup_sleep: Pull up enable when system goes into deep sleep mode.
+- sprd,pulldown_sleep: Pull down enable when system goes into deep sleep mode.
+
+Please refer to each sprd,<soc>-pinctrl.txt binding doc for supported values.
diff --git a/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt
new file mode 100644
index 0000000..10b77e1
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt
@@ -0,0 +1,66 @@
+* Spreadtrum SC9860 Pin Controller
+
+Please refer to sprd,pinctrl.txt in this directory for common binding part
+and usage.
+
+Required properties:
+- compatible: Must be "sprd,sc9860-pinctrl".
+- reg: The register address of pin controller device.
+- pins : An array of strings, each string containing the name of a pin.
+
+Optional properties:
+- function: A string containing the name of the function, values must be
+  one of: "func1", "func2", "func3" and "func4".
+- drive-strength: Drive strength in mA. Supported values: 2, 4, 6, 8, 10,
+  12, 14, 16, 20, 21, 24, 25, 27, 29, 31 and 33.
+- input-schmitt-disable: Enable schmitt-trigger mode.
+- input-schmitt-enable: Disable schmitt-trigger mode.
+- bias-disable: Disable pin bias.
+- bias-pull-down: Pull down on pin.
+- sprd,ctrl: Control values referring to databook for global control pins.
+- sprd,sleep_mode: Choose the pin sleep mode, and supported values are:
+  AP_SLEEP, PUBCP_SLEEP, TGLDSP_SLEEP and AGDSP_SLEEP.
+- sprd,pullup: Pull up on pin, the value should be PULLUP_20K or PULLUP_4_7K.
+- sprd,input-sleep: Input enable when system goes into deep sleep mode.
+- sprd,output-sleep: Output enable when system goes into deep sleep mode.
+- sprd,pullup_sleep: Pull up enable when system goes into deep sleep mode.
+- sprd,pulldown_sleep: Pull down enable when system goes into deep sleep mode.
+
+Pin sleep mode definition:
+enum pin_sleep_mode {
+	AP_SLEEP = BIT(0),
+	PUBCP_SLEEP = BIT(1),
+	TGLDSP_SLEEP = BIT(2),
+	AGDSP_SLEEP = BIT(3),
+};
+
+Pin pullup mode definition:
+enum pin_pullup_sel {
+	PULLUP_20K,
+	PULLUP_4_7K,
+};
+
+Example:
+pin_controller: pinctrl@402a0000 {
+	compatible = "sprd,sc9860-pinctrl";
+	reg = <0x402a0000 0x10000>;
+
+	grp1: sd0 {
+		pins = "SC9860_VIO_SD2_IRTE", "SC9860_VIO_SD0_IRTE";
+		sprd,ctrl = <0x1>;
+	};
+
+	grp2: rfctl_33 {
+		pins = "SC9860_RFCTL33";
+		function = "func2";
+		sprd,sleep_mode = <AP_SLEEP | PUBCP_SLEEP>;
+		sprd,output-sleep;
+	};
+
+	grp3: rfctl_misc_20 {
+		pins = "SC9860_RFCTL20_MISC";
+		drive-strength = <10>;
+		sprd,pullup = <PULLUP_4_7K>;
+		sprd,pullup-sleep;
+	};
+};
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
@ 2017-06-05 12:11 ` Baolin Wang
  0 siblings, 0 replies; 24+ messages in thread
From: Baolin Wang @ 2017-06-05 12:11 UTC (permalink / raw)
  To: linus.walleij, mark.rutland, robh+dt
  Cc: linux-gpio, devicetree, linux-kernel, broonie, baolin.wang, baolin.wang

This patch adds the binding documentation for Spreadtrum SC9860 pin
controller device.

Signed-off-by: Baolin Wang <baolin.wang@spreadtrum.com>
---
Changes since v1:
 - Remove magic numbers and get to use the standard bindings.
 - Fix some typos.
---
 .../devicetree/bindings/pinctrl/sprd,pinctrl.txt   |   56 +++++++++++++++++
 .../bindings/pinctrl/sprd,sc9860-pinctrl.txt       |   66 ++++++++++++++++++++
 2 files changed, 122 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/sprd,pinctrl.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/sprd,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/sprd,pinctrl.txt
new file mode 100644
index 0000000..2f544cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/sprd,pinctrl.txt
@@ -0,0 +1,56 @@
+* Spreadtrum Pin Controller
+
+The Spreadtrum pin controller are organized in 3 blocks (types).
+
+The first block comprises some global control registers, and each
+register contains several bit fields with one bit or several bits
+to configure for some global common configuration, such as domain
+pad driving level, system control select and so on. We recognise
+every fields comprising one bit or several bits in one global control
+register as one pin, thus we should record every pin's bit offset,
+bit width and register offset to configure this field (pin). Since
+this type pins' configuration are very tricky and different for each
+register, we introduce "sprd,ctrl" property to set the various global
+control configuration.
+
+The second block comprises some common registers which have unified
+register definition, and each register described one pin is used
+to configure the pin sleep mode and function select. Now we have 4
+systems on SC9860 SoC: AP system, PUBCP system, TGLDSP system and
+AGDSP system. In some situation we have some pin-sleep related
+configuration need to set when one of system goes into deep sleep
+mode. For example, if we set the pin sleep mode as AP_SLEEP, which
+means when AP system goes into deep sleep mode, this pin's sleep
+related properties (input/output or pullup/down) will be set
+automatically. Thus we intoduce "sprd,sleep_mode" to set pin sleep
+mode.
+
+The last block comprises some misc registers which also have unified
+register definition, and each register described one pin is used to
+configure drive strength, pull up/down and so on. Especially for pull
+up, we introduce "sprd,pullup" property for two kind configuration:
+PULLUP_20K or PULLUP_4_7K, which means the pullup resistor is 20K or
+4.7K.
+
+Required properties for Spreadtrum pin controller:
+- compatible: "sprd,<soc>-pinctrl"
+  Please refer to each sprd,<soc>-pinctrl.txt binding doc for supported SoCs.
+- reg: The register address of pin controller device.
+- pins : An array of pin names.
+
+Optional properties:
+- function: Specified the function name.
+- drive-strength: Drive strength in mA.
+- input-schmitt-disable: Enable schmitt-trigger mode.
+- input-schmitt-enable: Disable schmitt-trigger mode.
+- bias-disable: Disable pin bias.
+- bias-pull-down: Pull down on pin.
+- sprd,ctrl: Control values referring to databook for global control pins.
+- sprd,sleep_mode: Sleep mode selection.
+- sprd,pullup: Pull up on pin.
+- sprd,input-sleep: Input enable when system goes into deep sleep mode.
+- sprd,output-sleep: Output enable when system goes into deep sleep mode.
+- sprd,pullup_sleep: Pull up enable when system goes into deep sleep mode.
+- sprd,pulldown_sleep: Pull down enable when system goes into deep sleep mode.
+
+Please refer to each sprd,<soc>-pinctrl.txt binding doc for supported values.
diff --git a/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt
new file mode 100644
index 0000000..10b77e1
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt
@@ -0,0 +1,66 @@
+* Spreadtrum SC9860 Pin Controller
+
+Please refer to sprd,pinctrl.txt in this directory for common binding part
+and usage.
+
+Required properties:
+- compatible: Must be "sprd,sc9860-pinctrl".
+- reg: The register address of pin controller device.
+- pins : An array of strings, each string containing the name of a pin.
+
+Optional properties:
+- function: A string containing the name of the function, values must be
+  one of: "func1", "func2", "func3" and "func4".
+- drive-strength: Drive strength in mA. Supported values: 2, 4, 6, 8, 10,
+  12, 14, 16, 20, 21, 24, 25, 27, 29, 31 and 33.
+- input-schmitt-disable: Enable schmitt-trigger mode.
+- input-schmitt-enable: Disable schmitt-trigger mode.
+- bias-disable: Disable pin bias.
+- bias-pull-down: Pull down on pin.
+- sprd,ctrl: Control values referring to databook for global control pins.
+- sprd,sleep_mode: Choose the pin sleep mode, and supported values are:
+  AP_SLEEP, PUBCP_SLEEP, TGLDSP_SLEEP and AGDSP_SLEEP.
+- sprd,pullup: Pull up on pin, the value should be PULLUP_20K or PULLUP_4_7K.
+- sprd,input-sleep: Input enable when system goes into deep sleep mode.
+- sprd,output-sleep: Output enable when system goes into deep sleep mode.
+- sprd,pullup_sleep: Pull up enable when system goes into deep sleep mode.
+- sprd,pulldown_sleep: Pull down enable when system goes into deep sleep mode.
+
+Pin sleep mode definition:
+enum pin_sleep_mode {
+	AP_SLEEP = BIT(0),
+	PUBCP_SLEEP = BIT(1),
+	TGLDSP_SLEEP = BIT(2),
+	AGDSP_SLEEP = BIT(3),
+};
+
+Pin pullup mode definition:
+enum pin_pullup_sel {
+	PULLUP_20K,
+	PULLUP_4_7K,
+};
+
+Example:
+pin_controller: pinctrl@402a0000 {
+	compatible = "sprd,sc9860-pinctrl";
+	reg = <0x402a0000 0x10000>;
+
+	grp1: sd0 {
+		pins = "SC9860_VIO_SD2_IRTE", "SC9860_VIO_SD0_IRTE";
+		sprd,ctrl = <0x1>;
+	};
+
+	grp2: rfctl_33 {
+		pins = "SC9860_RFCTL33";
+		function = "func2";
+		sprd,sleep_mode = <AP_SLEEP | PUBCP_SLEEP>;
+		sprd,output-sleep;
+	};
+
+	grp3: rfctl_misc_20 {
+		pins = "SC9860_RFCTL20_MISC";
+		drive-strength = <10>;
+		sprd,pullup = <PULLUP_4_7K>;
+		sprd,pullup-sleep;
+	};
+};
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 2/2] pinctrl: sprd: Add Spreadtrum pin control driver
  2017-06-05 12:11 ` Baolin Wang
@ 2017-06-05 12:11   ` Baolin Wang
  -1 siblings, 0 replies; 24+ messages in thread
From: Baolin Wang @ 2017-06-05 12:11 UTC (permalink / raw)
  To: linus.walleij, mark.rutland, robh+dt
  Cc: linux-gpio, devicetree, linux-kernel, broonie, baolin.wang, baolin.wang

This patch adds the pin control driver for Spreadtrum SC9860 platform.

Signed-off-by: Baolin Wang <baolin.wang@spreadtrum.com>
---
Changes since v1:
 - Remove magic numbers and use generic pin control bindings.
---
 drivers/pinctrl/Kconfig                    |    1 +
 drivers/pinctrl/Makefile                   |    1 +
 drivers/pinctrl/sprd/Kconfig               |   17 +
 drivers/pinctrl/sprd/Makefile              |    2 +
 drivers/pinctrl/sprd/pinctrl-sprd-sc9860.c |  972 ++++++++++++++++++++++++++++
 drivers/pinctrl/sprd/pinctrl-sprd.c        |  912 ++++++++++++++++++++++++++
 drivers/pinctrl/sprd/pinctrl-sprd.h        |   95 +++
 7 files changed, 2000 insertions(+)
 create mode 100644 drivers/pinctrl/sprd/Kconfig
 create mode 100644 drivers/pinctrl/sprd/Makefile
 create mode 100644 drivers/pinctrl/sprd/pinctrl-sprd-sc9860.c
 create mode 100644 drivers/pinctrl/sprd/pinctrl-sprd.c
 create mode 100644 drivers/pinctrl/sprd/pinctrl-sprd.h

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 8f8c2af..681e593 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -304,6 +304,7 @@ source "drivers/pinctrl/ti/Kconfig"
 source "drivers/pinctrl/uniphier/Kconfig"
 source "drivers/pinctrl/vt8500/Kconfig"
 source "drivers/pinctrl/mediatek/Kconfig"
+source "drivers/pinctrl/sprd/Kconfig"
 
 config PINCTRL_XWAY
 	bool
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index a251f43..006e352 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -57,3 +57,4 @@ obj-y				+= ti/
 obj-$(CONFIG_PINCTRL_UNIPHIER)	+= uniphier/
 obj-$(CONFIG_ARCH_VT8500)	+= vt8500/
 obj-$(CONFIG_PINCTRL_MTK)	+= mediatek/
+obj-y				+= sprd/
diff --git a/drivers/pinctrl/sprd/Kconfig b/drivers/pinctrl/sprd/Kconfig
new file mode 100644
index 0000000..6f4a7f9
--- /dev/null
+++ b/drivers/pinctrl/sprd/Kconfig
@@ -0,0 +1,17 @@
+#
+# Spreadtrum pin control drivers
+#
+
+config PINCTRL_SPRD
+	bool "Spreadtrum pinctrl driver"
+	select PINMUX
+	select PINCONF
+	select GENERIC_PINCONF
+	select GENERIC_PINMUX_FUNCTIONS
+	help
+	  Say Y here to enable Spreadtrum pinctrl driver
+
+config PINCTRL_SPRD_SC9860
+	bool "Spreadtrum SC9860 pinctrl driver"
+	help
+	  Say Y here to enable Spreadtrum SC9860 pinctrl driver
diff --git a/drivers/pinctrl/sprd/Makefile b/drivers/pinctrl/sprd/Makefile
new file mode 100644
index 0000000..b6caa8c
--- /dev/null
+++ b/drivers/pinctrl/sprd/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_PINCTRL_SPRD)		+= pinctrl-sprd.o
+obj-$(CONFIG_PINCTRL_SPRD_SC9860)	+= pinctrl-sprd-sc9860.o
diff --git a/drivers/pinctrl/sprd/pinctrl-sprd-sc9860.c b/drivers/pinctrl/sprd/pinctrl-sprd-sc9860.c
new file mode 100644
index 0000000..3cdad8b
--- /dev/null
+++ b/drivers/pinctrl/sprd/pinctrl-sprd-sc9860.c
@@ -0,0 +1,972 @@
+/*
+ * Spreadtrum pin controller driver
+ * Copyright (C) 2017 Spreadtrum  - http://www.spreadtrum.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "pinctrl-sprd.h"
+
+enum sprd_sc9860_pins {
+	/* pin global control register 0 */
+	SC9860_VIO28_0_IRTE = SPRD_PIN_INFO(0, GLOBAL_CTRL_PIN, 11, 1, 0),
+	SC9860_VIO_SD2_IRTE = SPRD_PIN_INFO(1, GLOBAL_CTRL_PIN, 10, 1, 0),
+	SC9860_VIO_SD0_IRTE = SPRD_PIN_INFO(2, GLOBAL_CTRL_PIN, 9, 1, 0),
+	SC9860_VIO_SIM2_IRTE = SPRD_PIN_INFO(3, GLOBAL_CTRL_PIN, 8, 1, 0),
+	SC9860_VIO_SIM1_IRTE = SPRD_PIN_INFO(4, GLOBAL_CTRL_PIN, 7, 1, 0),
+	SC9860_VIO_SIM0_IRTE = SPRD_PIN_INFO(5, GLOBAL_CTRL_PIN, 6, 1, 0),
+	SC9860_VIO28_0_MS = SPRD_PIN_INFO(6, GLOBAL_CTRL_PIN, 5, 1, 0),
+	SC9860_VIO_SD2_MS = SPRD_PIN_INFO(7, GLOBAL_CTRL_PIN, 4, 1, 0),
+	SC9860_VIO_SD0_MS = SPRD_PIN_INFO(8, GLOBAL_CTRL_PIN, 3, 1, 0),
+	SC9860_VIO_SIM2_MS = SPRD_PIN_INFO(9, GLOBAL_CTRL_PIN, 2, 1, 0),
+	SC9860_VIO_SIM1_MS = SPRD_PIN_INFO(10, GLOBAL_CTRL_PIN, 1, 1, 0),
+	SC9860_VIO_SIM0_MS = SPRD_PIN_INFO(11, GLOBAL_CTRL_PIN, 0, 1, 0),
+
+	/* pin global control register 2 */
+	SC9860_SPSPI_PIN_IN_SEL = SPRD_PIN_INFO(12, GLOBAL_CTRL_PIN, 31, 1, 2),
+	SC9860_UART1_USB30_PHY_SEL = SPRD_PIN_INFO(13, GLOBAL_CTRL_PIN, 30, 1, 2),
+	SC9860_USB30_PHY_DM_OE = SPRD_PIN_INFO(14, GLOBAL_CTRL_PIN, 29, 1, 2),
+	SC9860_USB30_PHY_DP_OE = SPRD_PIN_INFO(15, GLOBAL_CTRL_PIN, 28, 1, 2),
+	SC9860_UART5_SYS_SEL = SPRD_PIN_INFO(16, GLOBAL_CTRL_PIN, 25, 3, 2),
+	SC9860_ORP_URXD_PIN_IN_SEL = SPRD_PIN_INFO(17, GLOBAL_CTRL_PIN, 24, 1, 2),
+	SC9860_SIM2_SYS_SEL = SPRD_PIN_INFO(18, GLOBAL_CTRL_PIN, 23, 1, 2),
+	SC9860_SIM1_SYS_SEL = SPRD_PIN_INFO(19, GLOBAL_CTRL_PIN, 22, 1, 2),
+	SC9860_SIM0_SYS_SEL = SPRD_PIN_INFO(20, GLOBAL_CTRL_PIN, 21, 1, 2),
+	SC9860_CLK26MHZ_BUF_OUT_SEL = SPRD_PIN_INFO(21, GLOBAL_CTRL_PIN, 20, 1, 2),
+	SC9860_UART4_SYS_SEL = SPRD_PIN_INFO(22, GLOBAL_CTRL_PIN, 16, 3, 2),
+	SC9860_UART3_SYS_SEL = SPRD_PIN_INFO(23, GLOBAL_CTRL_PIN, 13, 3, 2),
+	SC9860_UART2_SYS_SEL = SPRD_PIN_INFO(24, GLOBAL_CTRL_PIN, 10, 3, 2),
+	SC9860_UART1_SYS_SEL = SPRD_PIN_INFO(25, GLOBAL_CTRL_PIN, 7, 3, 2),
+	SC9860_UART0_SYS_SEL = SPRD_PIN_INFO(26, GLOBAL_CTRL_PIN, 4, 3, 2),
+	SC9860_UART24_LOOP_SEL = SPRD_PIN_INFO(27, GLOBAL_CTRL_PIN, 3, 1, 2),
+	SC9860_UART23_LOOP_SEL = SPRD_PIN_INFO(28, GLOBAL_CTRL_PIN, 2, 1, 2),
+	SC9860_UART14_LOOP_SEL = SPRD_PIN_INFO(29, GLOBAL_CTRL_PIN, 1, 1, 2),
+	SC9860_UART13_LOOP_SEL = SPRD_PIN_INFO(30, GLOBAL_CTRL_PIN, 0, 1, 2),
+
+	/* pin global control register 3 */
+	SC9860_IIS3_SYS_SEL = SPRD_PIN_INFO(31, GLOBAL_CTRL_PIN, 18, 4, 3),
+	SC9860_IIS2_SYS_SEL = SPRD_PIN_INFO(32, GLOBAL_CTRL_PIN, 14, 4, 3),
+	SC9860_IIS1_SYS_SEL = SPRD_PIN_INFO(33, GLOBAL_CTRL_PIN, 10, 4, 3),
+	SC9860_IIS0_SYS_SEL = SPRD_PIN_INFO(34, GLOBAL_CTRL_PIN, 6, 4, 3),
+	SC9860_IIS23_LOOP_SEL = SPRD_PIN_INFO(35, GLOBAL_CTRL_PIN, 5, 1, 3),
+	SC9860_IIS13_LOOP_SEL = SPRD_PIN_INFO(36, GLOBAL_CTRL_PIN, 4, 1, 3),
+	SC9860_IIS12_LOOP_SEL = SPRD_PIN_INFO(37, GLOBAL_CTRL_PIN, 3, 1, 3),
+	SC9860_IIS03_LOOP_SEL = SPRD_PIN_INFO(38, GLOBAL_CTRL_PIN, 2, 1, 3),
+	SC9860_IIS02_LOOP_SEL = SPRD_PIN_INFO(39, GLOBAL_CTRL_PIN, 1, 1, 3),
+	SC9860_IIS01_LOOP_SEL = SPRD_PIN_INFO(40, GLOBAL_CTRL_PIN, 0, 1, 3),
+
+	/* pin global control register 4 */
+	SC9860_IIS6_SYS_SEL = SPRD_PIN_INFO(41, GLOBAL_CTRL_PIN, 27, 4, 4),
+	SC9860_IIS5_SYS_SEL = SPRD_PIN_INFO(42, GLOBAL_CTRL_PIN, 23, 4, 4),
+	SC9860_IIS4_SYS_SEL = SPRD_PIN_INFO(43, GLOBAL_CTRL_PIN, 19, 4, 4),
+	SC9860_I2C_INF6_SYS_SEL = SPRD_PIN_INFO(44, GLOBAL_CTRL_PIN, 8, 2, 4),
+	SC9860_I2C_INF4_SYS_SEL = SPRD_PIN_INFO(45, GLOBAL_CTRL_PIN, 6, 2, 4),
+	SC9860_I2C_INF2_SYS_SEL = SPRD_PIN_INFO(46, GLOBAL_CTRL_PIN, 4, 2, 4),
+	SC9860_I2C_INF1_SYS_SEL = SPRD_PIN_INFO(47, GLOBAL_CTRL_PIN, 2, 2, 4),
+	SC9860_I2C_INF0_SYS_SEL = SPRD_PIN_INFO(48, GLOBAL_CTRL_PIN, 0, 2, 4),
+
+	/* pin global control register 5 */
+	SC9860_GPIO_INF7_SYS_SEL = SPRD_PIN_INFO(49, GLOBAL_CTRL_PIN, 27, 1, 5),
+	SC9860_GPIO_INF6_SYS_SEL = SPRD_PIN_INFO(50, GLOBAL_CTRL_PIN, 26, 1, 5),
+	SC9860_GPIO_INF5_SYS_SEL = SPRD_PIN_INFO(51, GLOBAL_CTRL_PIN, 25, 1, 5),
+	SC9860_GPIO_INF4_SYS_SEL = SPRD_PIN_INFO(52, GLOBAL_CTRL_PIN, 24, 1, 5),
+	SC9860_GPIO_INF3_SYS_SEL = SPRD_PIN_INFO(53, GLOBAL_CTRL_PIN, 23, 1, 5),
+	SC9860_GPIO_INF2_SYS_SEL = SPRD_PIN_INFO(54, GLOBAL_CTRL_PIN, 22, 1, 5),
+	SC9860_GPIO_INF1_SYS_SEL = SPRD_PIN_INFO(55, GLOBAL_CTRL_PIN, 21, 1, 5),
+	SC9860_GPIO_INF0_SYS_SEL = SPRD_PIN_INFO(56, GLOBAL_CTRL_PIN, 20, 1, 5),
+	SC9860_WDRST_OUT_SEL = SPRD_PIN_INFO(57, GLOBAL_CTRL_PIN, 16, 3, 5),
+	SC9860_ADI_SYNC_PIN_OUT_SEL = SPRD_PIN_INFO(58, GLOBAL_CTRL_PIN, 14, 1, 5),
+	SC9860_CMRST_SEL = SPRD_PIN_INFO(59, GLOBAL_CTRL_PIN, 13, 1, 5),
+	SC9860_CMPD_SEL = SPRD_PIN_INFO(60, GLOBAL_CTRL_PIN, 12, 1, 5),
+	SC9860_TEST_DBG_MODE11 = SPRD_PIN_INFO(61, GLOBAL_CTRL_PIN, 11, 1, 5),
+	SC9860_TEST_DBG_MODE10 = SPRD_PIN_INFO(62, GLOBAL_CTRL_PIN, 10, 1, 5),
+	SC9860_TEST_DBG_MODE9 = SPRD_PIN_INFO(63, GLOBAL_CTRL_PIN, 9, 1, 5),
+	SC9860_TEST_DBG_MODE8 = SPRD_PIN_INFO(64, GLOBAL_CTRL_PIN, 8, 1, 5),
+	SC9860_TEST_DBG_MODE7 = SPRD_PIN_INFO(65, GLOBAL_CTRL_PIN, 7, 1, 5),
+	SC9860_TEST_DBG_MODE6 = SPRD_PIN_INFO(66, GLOBAL_CTRL_PIN, 6, 1, 5),
+	SC9860_TEST_DBG_MODE5 = SPRD_PIN_INFO(67, GLOBAL_CTRL_PIN, 5, 1, 5),
+	SC9860_TEST_DBG_MODE4 = SPRD_PIN_INFO(68, GLOBAL_CTRL_PIN, 4, 1, 5),
+	SC9860_TEST_DBG_MODE3 = SPRD_PIN_INFO(69, GLOBAL_CTRL_PIN, 3, 1, 5),
+	SC9860_TEST_DBG_MODE2 = SPRD_PIN_INFO(70, GLOBAL_CTRL_PIN, 2, 1, 5),
+	SC9860_TEST_DBG_MODE1 = SPRD_PIN_INFO(71, GLOBAL_CTRL_PIN, 1, 1, 5),
+	SC9860_TEST_DBG_MODE0 = SPRD_PIN_INFO(72, GLOBAL_CTRL_PIN, 0, 1, 5),
+
+	/* pin global control register 6 */
+	SC9860_SP_EIC_DPAD3_SEL = SPRD_PIN_INFO(73, GLOBAL_CTRL_PIN, 24, 8, 6),
+	SC9860_SP_EIC_DPAD2_SEL = SPRD_PIN_INFO(74, GLOBAL_CTRL_PIN, 16, 8, 6),
+	SC9860_SP_EIC_DPAD1_SEL = SPRD_PIN_INFO(75, GLOBAL_CTRL_PIN, 8, 8, 6),
+	SC9860_SP_EIC_DPAD0_SEL = SPRD_PIN_INFO(76, GLOBAL_CTRL_PIN, 0, 8, 6),
+
+	/* pin global control register 7 */
+	SC9860_SP_EIC_DPAD7_SEL = SPRD_PIN_INFO(77, GLOBAL_CTRL_PIN, 24, 8, 7),
+	SC9860_SP_EIC_DPAD6_SEL = SPRD_PIN_INFO(78, GLOBAL_CTRL_PIN, 16, 8, 7),
+	SC9860_SP_EIC_DPAD5_SEL = SPRD_PIN_INFO(79, GLOBAL_CTRL_PIN, 8, 8, 7),
+	SC9860_SP_EIC_DPAD4_SEL = SPRD_PIN_INFO(80, GLOBAL_CTRL_PIN, 0, 8, 7),
+
+	/* common pin registers definitions */
+	SC9860_RFCTL20 = SPRD_PIN_INFO(81, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL21 = SPRD_PIN_INFO(83, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL30 = SPRD_PIN_INFO(85, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL31 = SPRD_PIN_INFO(87, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL32 = SPRD_PIN_INFO(89, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL33 = SPRD_PIN_INFO(91, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL34 = SPRD_PIN_INFO(93, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL35 = SPRD_PIN_INFO(95, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL36 = SPRD_PIN_INFO(97, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL37 = SPRD_PIN_INFO(99, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL22 = SPRD_PIN_INFO(101, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL23 = SPRD_PIN_INFO(103, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL24 = SPRD_PIN_INFO(105, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL25 = SPRD_PIN_INFO(107, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL26 = SPRD_PIN_INFO(109, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL27 = SPRD_PIN_INFO(111, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL28 = SPRD_PIN_INFO(113, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL29 = SPRD_PIN_INFO(115, COMMON_PIN, 0, 0, 0),
+	SC9860_SCL2 = SPRD_PIN_INFO(117, COMMON_PIN, 0, 0, 0),
+	SC9860_SDA2 = SPRD_PIN_INFO(119, COMMON_PIN, 0, 0, 0),
+	SC9860_MTCK_ARM = SPRD_PIN_INFO(121, COMMON_PIN, 0, 0, 0),
+	SC9860_MTMS_ARM = SPRD_PIN_INFO(123, COMMON_PIN, 0, 0, 0),
+	SC9860_XTL_EN0 = SPRD_PIN_INFO(125, COMMON_PIN, 0, 0, 0),
+	SC9860_PTEST = SPRD_PIN_INFO(127, COMMON_PIN, 0, 0, 0),
+	SC9860_AUD_DAD1 = SPRD_PIN_INFO(129, COMMON_PIN, 0, 0, 0),
+	SC9860_AUD_ADD0 = SPRD_PIN_INFO(131, COMMON_PIN, 0, 0, 0),
+	SC9860_AUD_ADSYNC = SPRD_PIN_INFO(133, COMMON_PIN, 0, 0, 0),
+	SC9860_AUD_SCLK = SPRD_PIN_INFO(135, COMMON_PIN, 0, 0, 0),
+	SC9860_CHIP_SLEEP = SPRD_PIN_INFO(137, COMMON_PIN, 0, 0, 0),
+	SC9860_CLK_32K = SPRD_PIN_INFO(139, COMMON_PIN, 0, 0, 0),
+	SC9860_DCDC_ARM_EN = SPRD_PIN_INFO(141, COMMON_PIN, 0, 0, 0),
+	SC9860_EXT_RST_B = SPRD_PIN_INFO(143, COMMON_PIN, 0, 0, 0),
+	SC9860_ADI_D = SPRD_PIN_INFO(145, COMMON_PIN, 0, 0, 0),
+	SC9860_ADI_SCLK = SPRD_PIN_INFO(147, COMMON_PIN, 0, 0, 0),
+	SC9860_XTL_EN1 = SPRD_PIN_INFO(149, COMMON_PIN, 0, 0, 0),
+	SC9860_ANA_INT = SPRD_PIN_INFO(151, COMMON_PIN, 0, 0, 0),
+	SC9860_AUD_DAD0 = SPRD_PIN_INFO(153, COMMON_PIN, 0, 0, 0),
+	SC9860_AUD_DASYNC = SPRD_PIN_INFO(155, COMMON_PIN, 0, 0, 0),
+	SC9860_LCM_RSTN = SPRD_PIN_INFO(157, COMMON_PIN, 0, 0, 0),
+	SC9860_DSI_TE = SPRD_PIN_INFO(159, COMMON_PIN, 0, 0, 0),
+	SC9860_PWMA = SPRD_PIN_INFO(161, COMMON_PIN, 0, 0, 0),
+	SC9860_EXTINT0 = SPRD_PIN_INFO(163, COMMON_PIN, 0, 0, 0),
+	SC9860_EXTINT1 = SPRD_PIN_INFO(165, COMMON_PIN, 0, 0, 0),
+	SC9860_SDA1 = SPRD_PIN_INFO(167, COMMON_PIN, 0, 0, 0),
+	SC9860_SCL1 = SPRD_PIN_INFO(169, COMMON_PIN, 0, 0, 0),
+	SC9860_SIMCLK2 = SPRD_PIN_INFO(171, COMMON_PIN, 0, 0, 0),
+	SC9860_SIMDA2 = SPRD_PIN_INFO(173, COMMON_PIN, 0, 0, 0),
+	SC9860_SIMRST2 = SPRD_PIN_INFO(175, COMMON_PIN, 0, 0, 0),
+	SC9860_SIMCLK1 = SPRD_PIN_INFO(177, COMMON_PIN, 0, 0, 0),
+	SC9860_SIMDA1 = SPRD_PIN_INFO(179, COMMON_PIN, 0, 0, 0),
+	SC9860_SIMRST1 = SPRD_PIN_INFO(181, COMMON_PIN, 0, 0, 0),
+	SC9860_SIMCLK0 = SPRD_PIN_INFO(183, COMMON_PIN, 0, 0, 0),
+	SC9860_SIMDA0 = SPRD_PIN_INFO(185, COMMON_PIN, 0, 0, 0),
+	SC9860_SIMRST0 = SPRD_PIN_INFO(187, COMMON_PIN, 0, 0, 0),
+	SC9860_SD2_CMD = SPRD_PIN_INFO(189, COMMON_PIN, 0, 0, 0),
+	SC9860_SD2_D0 = SPRD_PIN_INFO(191, COMMON_PIN, 0, 0, 0),
+	SC9860_SD2_D1 = SPRD_PIN_INFO(193, COMMON_PIN, 0, 0, 0),
+	SC9860_SD2_CLK = SPRD_PIN_INFO(195, COMMON_PIN, 0, 0, 0),
+	SC9860_SD2_D2 = SPRD_PIN_INFO(197, COMMON_PIN, 0, 0, 0),
+	SC9860_SD2_D3 = SPRD_PIN_INFO(199, COMMON_PIN, 0, 0, 0),
+	SC9860_SD0_D3 = SPRD_PIN_INFO(201, COMMON_PIN, 0, 0, 0),
+	SC9860_SD0_D2 = SPRD_PIN_INFO(203, COMMON_PIN, 0, 0, 0),
+	SC9860_SD0_CMD = SPRD_PIN_INFO(205, COMMON_PIN, 0, 0, 0),
+	SC9860_SD0_D0 = SPRD_PIN_INFO(207, COMMON_PIN, 0, 0, 0),
+	SC9860_SD0_D1 = SPRD_PIN_INFO(209, COMMON_PIN, 0, 0, 0),
+	SC9860_SD0_CLK = SPRD_PIN_INFO(211, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_CMD_reserved = SPRD_PIN_INFO(213, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_CMD = SPRD_PIN_INFO(215, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_D6 = SPRD_PIN_INFO(217, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_D7 = SPRD_PIN_INFO(219, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_CLK = SPRD_PIN_INFO(221, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_D5 = SPRD_PIN_INFO(223, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_D4 = SPRD_PIN_INFO(225, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_DS = SPRD_PIN_INFO(227, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_D3_reserved = SPRD_PIN_INFO(229, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_D3 = SPRD_PIN_INFO(231, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_RST = SPRD_PIN_INFO(233, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_D1 = SPRD_PIN_INFO(235, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_D2 = SPRD_PIN_INFO(237, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_D0 = SPRD_PIN_INFO(239, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS0DI = SPRD_PIN_INFO(241, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS0DO = SPRD_PIN_INFO(243, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS0CLK = SPRD_PIN_INFO(245, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS0LRCK = SPRD_PIN_INFO(247, COMMON_PIN, 0, 0, 0),
+	SC9860_SD1_CLK = SPRD_PIN_INFO(249, COMMON_PIN, 0, 0, 0),
+	SC9860_SD1_CMD = SPRD_PIN_INFO(251, COMMON_PIN, 0, 0, 0),
+	SC9860_SD1_D0 = SPRD_PIN_INFO(253, COMMON_PIN, 0, 0, 0),
+	SC9860_SD1_D1 = SPRD_PIN_INFO(255, COMMON_PIN, 0, 0, 0),
+	SC9860_SD1_D2 = SPRD_PIN_INFO(257, COMMON_PIN, 0, 0, 0),
+	SC9860_SD1_D3 = SPRD_PIN_INFO(259, COMMON_PIN, 0, 0, 0),
+	SC9860_CLK_AUX0 = SPRD_PIN_INFO(261, COMMON_PIN, 0, 0, 0),
+	SC9860_WIFI_COEXIST = SPRD_PIN_INFO(263, COMMON_PIN, 0, 0, 0),
+	SC9860_BEIDOU_COEXIST = SPRD_PIN_INFO(265, COMMON_PIN, 0, 0, 0),
+	SC9860_U3TXD = SPRD_PIN_INFO(267, COMMON_PIN, 0, 0, 0),
+	SC9860_U3RXD = SPRD_PIN_INFO(269, COMMON_PIN, 0, 0, 0),
+	SC9860_U3CTS = SPRD_PIN_INFO(271, COMMON_PIN, 0, 0, 0),
+	SC9860_U3RTS = SPRD_PIN_INFO(273, COMMON_PIN, 0, 0, 0),
+	SC9860_U0TXD = SPRD_PIN_INFO(275, COMMON_PIN, 0, 0, 0),
+	SC9860_U0RXD = SPRD_PIN_INFO(277, COMMON_PIN, 0, 0, 0),
+	SC9860_U0CTS = SPRD_PIN_INFO(279, COMMON_PIN, 0, 0, 0),
+	SC9860_U0RTS = SPRD_PIN_INFO(281, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS1DI = SPRD_PIN_INFO(283, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS1DO = SPRD_PIN_INFO(285, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS1CLK = SPRD_PIN_INFO(287, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS1LRCK = SPRD_PIN_INFO(289, COMMON_PIN, 0, 0, 0),
+	SC9860_SPI0_CSN = SPRD_PIN_INFO(291, COMMON_PIN, 0, 0, 0),
+	SC9860_SPI0_DO = SPRD_PIN_INFO(293, COMMON_PIN, 0, 0, 0),
+	SC9860_SPI0_DI = SPRD_PIN_INFO(295, COMMON_PIN, 0, 0, 0),
+	SC9860_SPI0_CLK = SPRD_PIN_INFO(297, COMMON_PIN, 0, 0, 0),
+	SC9860_U2TXD = SPRD_PIN_INFO(299, COMMON_PIN, 0, 0, 0),
+	SC9860_U2RXD = SPRD_PIN_INFO(301, COMMON_PIN, 0, 0, 0),
+	SC9860_U4TXD = SPRD_PIN_INFO(303, COMMON_PIN, 0, 0, 0),
+	SC9860_U4RXD = SPRD_PIN_INFO(305, COMMON_PIN, 0, 0, 0),
+	SC9860_CMMCLK1 = SPRD_PIN_INFO(307, COMMON_PIN, 0, 0, 0),
+	SC9860_CMRST1 = SPRD_PIN_INFO(309, COMMON_PIN, 0, 0, 0),
+	SC9860_CMMCLK0 = SPRD_PIN_INFO(311, COMMON_PIN, 0, 0, 0),
+	SC9860_CMRST0 = SPRD_PIN_INFO(313, COMMON_PIN, 0, 0, 0),
+	SC9860_CMPD0 = SPRD_PIN_INFO(315, COMMON_PIN, 0, 0, 0),
+	SC9860_CMPD1 = SPRD_PIN_INFO(317, COMMON_PIN, 0, 0, 0),
+	SC9860_SCL0 = SPRD_PIN_INFO(319, COMMON_PIN, 0, 0, 0),
+	SC9860_SDA0 = SPRD_PIN_INFO(321, COMMON_PIN, 0, 0, 0),
+	SC9860_SDA6 = SPRD_PIN_INFO(323, COMMON_PIN, 0, 0, 0),
+	SC9860_SCL6 = SPRD_PIN_INFO(325, COMMON_PIN, 0, 0, 0),
+	SC9860_U1TXD = SPRD_PIN_INFO(327, COMMON_PIN, 0, 0, 0),
+	SC9860_U1RXD = SPRD_PIN_INFO(329, COMMON_PIN, 0, 0, 0),
+	SC9860_KEYOUT0 = SPRD_PIN_INFO(331, COMMON_PIN, 0, 0, 0),
+	SC9860_KEYOUT1 = SPRD_PIN_INFO(333, COMMON_PIN, 0, 0, 0),
+	SC9860_KEYOUT2 = SPRD_PIN_INFO(335, COMMON_PIN, 0, 0, 0),
+	SC9860_KEYIN0 = SPRD_PIN_INFO(337, COMMON_PIN, 0, 0, 0),
+	SC9860_KEYIN1 = SPRD_PIN_INFO(339, COMMON_PIN, 0, 0, 0),
+	SC9860_KEYIN2 = SPRD_PIN_INFO(341, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS3DI = SPRD_PIN_INFO(343, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS3DO = SPRD_PIN_INFO(345, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS3CLK = SPRD_PIN_INFO(347, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS3LRCK = SPRD_PIN_INFO(349, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL0 = SPRD_PIN_INFO(351, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL1 = SPRD_PIN_INFO(353, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL10 = SPRD_PIN_INFO(355, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL11 = SPRD_PIN_INFO(357, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL12 = SPRD_PIN_INFO(359, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL13 = SPRD_PIN_INFO(361, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL14 = SPRD_PIN_INFO(363, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL15 = SPRD_PIN_INFO(365, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL16 = SPRD_PIN_INFO(367, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL17 = SPRD_PIN_INFO(369, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL18 = SPRD_PIN_INFO(371, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL19 = SPRD_PIN_INFO(373, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL2 = SPRD_PIN_INFO(375, COMMON_PIN, 0, 0, 0),
+	SC9860_EXTINT5 = SPRD_PIN_INFO(377, COMMON_PIN, 0, 0, 0),
+	SC9860_EXTINT6 = SPRD_PIN_INFO(379, COMMON_PIN, 0, 0, 0),
+	SC9860_EXTINT7 = SPRD_PIN_INFO(381, COMMON_PIN, 0, 0, 0),
+	SC9860_GPIO30 = SPRD_PIN_INFO(383, COMMON_PIN, 0, 0, 0),
+	SC9860_GPIO31 = SPRD_PIN_INFO(385, COMMON_PIN, 0, 0, 0),
+	SC9860_GPIO32 = SPRD_PIN_INFO(387, COMMON_PIN, 0, 0, 0),
+	SC9860_GPIO33 = SPRD_PIN_INFO(389, COMMON_PIN, 0, 0, 0),
+	SC9860_GPIO34 = SPRD_PIN_INFO(391, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL3 = SPRD_PIN_INFO(393, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL4 = SPRD_PIN_INFO(395, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL5 = SPRD_PIN_INFO(397, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL6 = SPRD_PIN_INFO(399, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL7 = SPRD_PIN_INFO(401, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL8 = SPRD_PIN_INFO(403, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL9 = SPRD_PIN_INFO(405, COMMON_PIN, 0, 0, 0),
+	SC9860_RFFE0_SCK0 = SPRD_PIN_INFO(407, COMMON_PIN, 0, 0, 0),
+	SC9860_GPIO38 = SPRD_PIN_INFO(409, COMMON_PIN, 0, 0, 0),
+	SC9860_RFFE0_SDA0 = SPRD_PIN_INFO(411, COMMON_PIN, 0, 0, 0),
+	SC9860_GPIO39 = SPRD_PIN_INFO(413, COMMON_PIN, 0, 0, 0),
+	SC9860_RFFE1_SCK0 = SPRD_PIN_INFO(415, COMMON_PIN, 0, 0, 0),
+	SC9860_GPIO181 = SPRD_PIN_INFO(417, COMMON_PIN, 0, 0, 0),
+	SC9860_RFFE1_SDA0 = SPRD_PIN_INFO(419, COMMON_PIN, 0, 0, 0),
+	SC9860_GPIO182 = SPRD_PIN_INFO(421, COMMON_PIN, 0, 0, 0),
+	SC9860_RF_LVDS0_ADC_ON = SPRD_PIN_INFO(423, COMMON_PIN, 0, 0, 0),
+	SC9860_RF_LVDS0_DAC_ON = SPRD_PIN_INFO(425, COMMON_PIN, 0, 0, 0),
+	SC9860_RFSCK0 = SPRD_PIN_INFO(427, COMMON_PIN, 0, 0, 0),
+	SC9860_RFSDA0 = SPRD_PIN_INFO(429, COMMON_PIN, 0, 0, 0),
+	SC9860_RFSEN0 = SPRD_PIN_INFO(431, COMMON_PIN, 0, 0, 0),
+	SC9860_RF_LVDS1_ADC_ON = SPRD_PIN_INFO(433, COMMON_PIN, 0, 0, 0),
+	SC9860_RF_LVDS1_DAC_ON = SPRD_PIN_INFO(435, COMMON_PIN, 0, 0, 0),
+	SC9860_RFSCK1 = SPRD_PIN_INFO(437, COMMON_PIN, 0, 0, 0),
+	SC9860_RFSDA1 = SPRD_PIN_INFO(439, COMMON_PIN, 0, 0, 0),
+	SC9860_RFSEN1 = SPRD_PIN_INFO(441, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL38 = SPRD_PIN_INFO(443, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL39 = SPRD_PIN_INFO(445, COMMON_PIN, 0, 0, 0),
+
+	/* MSIC pin registers definitions */
+	SC9860_RFCTL20_MISC = SPRD_PIN_INFO(82, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL21_MISC = SPRD_PIN_INFO(84, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL30_MISC = SPRD_PIN_INFO(86, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL31_MISC = SPRD_PIN_INFO(88, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL32_MISC = SPRD_PIN_INFO(90, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL33_MISC = SPRD_PIN_INFO(92, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL34_MISC = SPRD_PIN_INFO(94, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL35_MISC = SPRD_PIN_INFO(96, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL36_MISC = SPRD_PIN_INFO(98, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL37_MISC = SPRD_PIN_INFO(100, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL22_MISC = SPRD_PIN_INFO(102, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL23_MISC = SPRD_PIN_INFO(104, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL24_MISC = SPRD_PIN_INFO(106, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL25_MISC = SPRD_PIN_INFO(108, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL26_MISC = SPRD_PIN_INFO(110, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL27_MISC = SPRD_PIN_INFO(112, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL28_MISC = SPRD_PIN_INFO(114, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL29_MISC = SPRD_PIN_INFO(116, MISC_PIN, 0, 0, 0),
+	SC9860_SCL2_MISC = SPRD_PIN_INFO(118, MISC_PIN, 0, 0, 0),
+	SC9860_SDA2_MISC = SPRD_PIN_INFO(120, MISC_PIN, 0, 0, 0),
+	SC9860_MTCK_ARM_MISC = SPRD_PIN_INFO(122, MISC_PIN, 0, 0, 0),
+	SC9860_MTMS_ARM_MISC = SPRD_PIN_INFO(124, MISC_PIN, 0, 0, 0),
+	SC9860_XTL_EN0_MISC = SPRD_PIN_INFO(126, MISC_PIN, 0, 0, 0),
+	SC9860_PTEST_MISC = SPRD_PIN_INFO(128, MISC_PIN, 0, 0, 0),
+	SC9860_AUD_DAD1_MISC = SPRD_PIN_INFO(130, MISC_PIN, 0, 0, 0),
+	SC9860_AUD_ADD0_MISC = SPRD_PIN_INFO(132, MISC_PIN, 0, 0, 0),
+	SC9860_AUD_ADSYNC_MISC = SPRD_PIN_INFO(134, MISC_PIN, 0, 0, 0),
+	SC9860_AUD_SCLK_MISC = SPRD_PIN_INFO(136, MISC_PIN, 0, 0, 0),
+	SC9860_CHIP_SLEEP_MISC = SPRD_PIN_INFO(138, MISC_PIN, 0, 0, 0),
+	SC9860_CLK_32K_MISC = SPRD_PIN_INFO(140, MISC_PIN, 0, 0, 0),
+	SC9860_DCDC_ARM_EN_MISC = SPRD_PIN_INFO(142, MISC_PIN, 0, 0, 0),
+	SC9860_EXT_RST_B_MISC = SPRD_PIN_INFO(144, MISC_PIN, 0, 0, 0),
+	SC9860_ADI_D_MISC = SPRD_PIN_INFO(146, MISC_PIN, 0, 0, 0),
+	SC9860_ADI_SCLK_MISC = SPRD_PIN_INFO(148, MISC_PIN, 0, 0, 0),
+	SC9860_XTL_EN1_MISC = SPRD_PIN_INFO(150, MISC_PIN, 0, 0, 0),
+	SC9860_ANA_INT_MISC = SPRD_PIN_INFO(152, MISC_PIN, 0, 0, 0),
+	SC9860_AUD_DAD0_MISC = SPRD_PIN_INFO(154, MISC_PIN, 0, 0, 0),
+	SC9860_AUD_DASYNC_MISC = SPRD_PIN_INFO(156, MISC_PIN, 0, 0, 0),
+	SC9860_LCM_RSTN_MISC = SPRD_PIN_INFO(158, MISC_PIN, 0, 0, 0),
+	SC9860_DSI_TE_MISC = SPRD_PIN_INFO(160, MISC_PIN, 0, 0, 0),
+	SC9860_PWMA_MISC = SPRD_PIN_INFO(162, MISC_PIN, 0, 0, 0),
+	SC9860_EXTINT0_MISC = SPRD_PIN_INFO(164, MISC_PIN, 0, 0, 0),
+	SC9860_EXTINT1_MISC = SPRD_PIN_INFO(166, MISC_PIN, 0, 0, 0),
+	SC9860_SDA1_MISC = SPRD_PIN_INFO(168, MISC_PIN, 0, 0, 0),
+	SC9860_SCL1_MISC = SPRD_PIN_INFO(170, MISC_PIN, 0, 0, 0),
+	SC9860_SIMCLK2_MISC = SPRD_PIN_INFO(172, MISC_PIN, 0, 0, 0),
+	SC9860_SIMDA2_MISC = SPRD_PIN_INFO(174, MISC_PIN, 0, 0, 0),
+	SC9860_SIMRST2_MISC = SPRD_PIN_INFO(176, MISC_PIN, 0, 0, 0),
+	SC9860_SIMCLK1_MISC = SPRD_PIN_INFO(178, MISC_PIN, 0, 0, 0),
+	SC9860_SIMDA1_MISC = SPRD_PIN_INFO(180, MISC_PIN, 0, 0, 0),
+	SC9860_SIMRST1_MISC = SPRD_PIN_INFO(182, MISC_PIN, 0, 0, 0),
+	SC9860_SIMCLK0_MISC = SPRD_PIN_INFO(184, MISC_PIN, 0, 0, 0),
+	SC9860_SIMDA0_MISC = SPRD_PIN_INFO(186, MISC_PIN, 0, 0, 0),
+	SC9860_SIMRST0_MISC = SPRD_PIN_INFO(188, MISC_PIN, 0, 0, 0),
+	SC9860_SD2_CMD_MISC = SPRD_PIN_INFO(190, MISC_PIN, 0, 0, 0),
+	SC9860_SD2_D0_MISC = SPRD_PIN_INFO(192, MISC_PIN, 0, 0, 0),
+	SC9860_SD2_D1_MISC = SPRD_PIN_INFO(194, MISC_PIN, 0, 0, 0),
+	SC9860_SD2_CLK_MISC = SPRD_PIN_INFO(196, MISC_PIN, 0, 0, 0),
+	SC9860_SD2_D2_MISC = SPRD_PIN_INFO(198, MISC_PIN, 0, 0, 0),
+	SC9860_SD2_D3_MISC = SPRD_PIN_INFO(200, MISC_PIN, 0, 0, 0),
+	SC9860_SD0_D3_MISC = SPRD_PIN_INFO(202, MISC_PIN, 0, 0, 0),
+	SC9860_SD0_D2_MISC = SPRD_PIN_INFO(204, MISC_PIN, 0, 0, 0),
+	SC9860_SD0_CMD_MISC = SPRD_PIN_INFO(206, MISC_PIN, 0, 0, 0),
+	SC9860_SD0_D0_MISC = SPRD_PIN_INFO(208, MISC_PIN, 0, 0, 0),
+	SC9860_SD0_D1_MISC = SPRD_PIN_INFO(210, MISC_PIN, 0, 0, 0),
+	SC9860_SD0_CLK_MISC = SPRD_PIN_INFO(212, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_CMD_reserved_MISC = SPRD_PIN_INFO(214, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_CMD_MISC = SPRD_PIN_INFO(216, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_D6_MISC = SPRD_PIN_INFO(218, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_D7_MISC = SPRD_PIN_INFO(220, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_CLK_MISC = SPRD_PIN_INFO(222, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_D5_MISC = SPRD_PIN_INFO(224, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_D4_MISC = SPRD_PIN_INFO(226, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_DS_MISC = SPRD_PIN_INFO(228, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_D3_reserved_MISC = SPRD_PIN_INFO(230, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_D3_MISC = SPRD_PIN_INFO(232, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_RST_MISC = SPRD_PIN_INFO(234, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_D1_MISC = SPRD_PIN_INFO(236, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_D2_MISC = SPRD_PIN_INFO(238, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_D0_MISC = SPRD_PIN_INFO(240, MISC_PIN, 0, 0, 0),
+	SC9860_IIS0DI_MISC = SPRD_PIN_INFO(242, MISC_PIN, 0, 0, 0),
+	SC9860_IIS0DO_MISC = SPRD_PIN_INFO(244, MISC_PIN, 0, 0, 0),
+	SC9860_IIS0CLK_MISC = SPRD_PIN_INFO(246, MISC_PIN, 0, 0, 0),
+	SC9860_IIS0LRCK_MISC = SPRD_PIN_INFO(248, MISC_PIN, 0, 0, 0),
+	SC9860_SD1_CLK_MISC = SPRD_PIN_INFO(250, MISC_PIN, 0, 0, 0),
+	SC9860_SD1_CMD_MISC = SPRD_PIN_INFO(252, MISC_PIN, 0, 0, 0),
+	SC9860_SD1_D0_MISC = SPRD_PIN_INFO(254, MISC_PIN, 0, 0, 0),
+	SC9860_SD1_D1_MISC = SPRD_PIN_INFO(256, MISC_PIN, 0, 0, 0),
+	SC9860_SD1_D2_MISC = SPRD_PIN_INFO(258, MISC_PIN, 0, 0, 0),
+	SC9860_SD1_D3_MISC = SPRD_PIN_INFO(260, MISC_PIN, 0, 0, 0),
+	SC9860_CLK_AUX0_MISC = SPRD_PIN_INFO(262, MISC_PIN, 0, 0, 0),
+	SC9860_WIFI_COEXIST_MISC = SPRD_PIN_INFO(264, MISC_PIN, 0, 0, 0),
+	SC9860_BEIDOU_COEXIST_MISC = SPRD_PIN_INFO(266, MISC_PIN, 0, 0, 0),
+	SC9860_U3TXD_MISC = SPRD_PIN_INFO(268, MISC_PIN, 0, 0, 0),
+	SC9860_U3RXD_MISC = SPRD_PIN_INFO(270, MISC_PIN, 0, 0, 0),
+	SC9860_U3CTS_MISC = SPRD_PIN_INFO(272, MISC_PIN, 0, 0, 0),
+	SC9860_U3RTS_MISC = SPRD_PIN_INFO(274, MISC_PIN, 0, 0, 0),
+	SC9860_U0TXD_MISC = SPRD_PIN_INFO(276, MISC_PIN, 0, 0, 0),
+	SC9860_U0RXD_MISC = SPRD_PIN_INFO(278, MISC_PIN, 0, 0, 0),
+	SC9860_U0CTS_MISC = SPRD_PIN_INFO(280, MISC_PIN, 0, 0, 0),
+	SC9860_U0RTS_MISC = SPRD_PIN_INFO(282, MISC_PIN, 0, 0, 0),
+	SC9860_IIS1DI_MISC = SPRD_PIN_INFO(284, MISC_PIN, 0, 0, 0),
+	SC9860_IIS1DO_MISC = SPRD_PIN_INFO(286, MISC_PIN, 0, 0, 0),
+	SC9860_IIS1CLK_MISC = SPRD_PIN_INFO(288, MISC_PIN, 0, 0, 0),
+	SC9860_IIS1LRCK_MISC = SPRD_PIN_INFO(290, MISC_PIN, 0, 0, 0),
+	SC9860_SPI0_CSN_MISC = SPRD_PIN_INFO(292, MISC_PIN, 0, 0, 0),
+	SC9860_SPI0_DO_MISC = SPRD_PIN_INFO(294, MISC_PIN, 0, 0, 0),
+	SC9860_SPI0_DI_MISC = SPRD_PIN_INFO(296, MISC_PIN, 0, 0, 0),
+	SC9860_SPI0_CLK_MISC = SPRD_PIN_INFO(298, MISC_PIN, 0, 0, 0),
+	SC9860_U2TXD_MISC = SPRD_PIN_INFO(300, MISC_PIN, 0, 0, 0),
+	SC9860_U2RXD_MISC = SPRD_PIN_INFO(302, MISC_PIN, 0, 0, 0),
+	SC9860_U4TXD_MISC = SPRD_PIN_INFO(304, MISC_PIN, 0, 0, 0),
+	SC9860_U4RXD_MISC = SPRD_PIN_INFO(306, MISC_PIN, 0, 0, 0),
+	SC9860_CMMCLK1_MISC = SPRD_PIN_INFO(308, MISC_PIN, 0, 0, 0),
+	SC9860_CMRST1_MISC = SPRD_PIN_INFO(310, MISC_PIN, 0, 0, 0),
+	SC9860_CMMCLK0_MISC = SPRD_PIN_INFO(312, MISC_PIN, 0, 0, 0),
+	SC9860_CMRST0_MISC = SPRD_PIN_INFO(314, MISC_PIN, 0, 0, 0),
+	SC9860_CMPD0_MISC = SPRD_PIN_INFO(316, MISC_PIN, 0, 0, 0),
+	SC9860_CMPD1_MISC = SPRD_PIN_INFO(318, MISC_PIN, 0, 0, 0),
+	SC9860_SCL0_MISC = SPRD_PIN_INFO(320, MISC_PIN, 0, 0, 0),
+	SC9860_SDA0_MISC = SPRD_PIN_INFO(322, MISC_PIN, 0, 0, 0),
+	SC9860_SDA6_MISC = SPRD_PIN_INFO(324, MISC_PIN, 0, 0, 0),
+	SC9860_SCL6_MISC = SPRD_PIN_INFO(326, MISC_PIN, 0, 0, 0),
+	SC9860_U1TXD_MISC = SPRD_PIN_INFO(328, MISC_PIN, 0, 0, 0),
+	SC9860_U1RXD_MISC = SPRD_PIN_INFO(330, MISC_PIN, 0, 0, 0),
+	SC9860_KEYOUT0_MISC = SPRD_PIN_INFO(332, MISC_PIN, 0, 0, 0),
+	SC9860_KEYOUT1_MISC = SPRD_PIN_INFO(334, MISC_PIN, 0, 0, 0),
+	SC9860_KEYOUT2_MISC = SPRD_PIN_INFO(336, MISC_PIN, 0, 0, 0),
+	SC9860_KEYIN0_MISC = SPRD_PIN_INFO(338, MISC_PIN, 0, 0, 0),
+	SC9860_KEYIN1_MISC = SPRD_PIN_INFO(340, MISC_PIN, 0, 0, 0),
+	SC9860_KEYIN2_MISC = SPRD_PIN_INFO(342, MISC_PIN, 0, 0, 0),
+	SC9860_IIS3DI_MISC = SPRD_PIN_INFO(344, MISC_PIN, 0, 0, 0),
+	SC9860_IIS3DO_MISC = SPRD_PIN_INFO(346, MISC_PIN, 0, 0, 0),
+	SC9860_IIS3CLK_MISC = SPRD_PIN_INFO(348, MISC_PIN, 0, 0, 0),
+	SC9860_IIS3LRCK_MISC = SPRD_PIN_INFO(350, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL0_MISC = SPRD_PIN_INFO(352, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL1_MISC = SPRD_PIN_INFO(354, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL10_MISC = SPRD_PIN_INFO(356, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL11_MISC = SPRD_PIN_INFO(358, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL12_MISC = SPRD_PIN_INFO(360, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL13_MISC = SPRD_PIN_INFO(362, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL14_MISC = SPRD_PIN_INFO(364, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL15_MISC = SPRD_PIN_INFO(366, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL16_MISC = SPRD_PIN_INFO(368, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL17_MISC = SPRD_PIN_INFO(370, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL18_MISC = SPRD_PIN_INFO(372, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL19_MISC = SPRD_PIN_INFO(374, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL2_MISC = SPRD_PIN_INFO(376, MISC_PIN, 0, 0, 0),
+	SC9860_EXTINT5_MISC = SPRD_PIN_INFO(378, MISC_PIN, 0, 0, 0),
+	SC9860_EXTINT6_MISC = SPRD_PIN_INFO(380, MISC_PIN, 0, 0, 0),
+	SC9860_EXTINT7_MISC = SPRD_PIN_INFO(382, MISC_PIN, 0, 0, 0),
+	SC9860_GPIO30_MISC = SPRD_PIN_INFO(384, MISC_PIN, 0, 0, 0),
+	SC9860_GPIO31_MISC = SPRD_PIN_INFO(386, MISC_PIN, 0, 0, 0),
+	SC9860_GPIO32_MISC = SPRD_PIN_INFO(388, MISC_PIN, 0, 0, 0),
+	SC9860_GPIO33_MISC = SPRD_PIN_INFO(390, MISC_PIN, 0, 0, 0),
+	SC9860_GPIO34_MISC = SPRD_PIN_INFO(392, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL3_MISC = SPRD_PIN_INFO(394, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL4_MISC = SPRD_PIN_INFO(396, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL5_MISC = SPRD_PIN_INFO(398, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL6_MISC = SPRD_PIN_INFO(400, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL7_MISC = SPRD_PIN_INFO(402, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL8_MISC = SPRD_PIN_INFO(404, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL9_MISC = SPRD_PIN_INFO(406, MISC_PIN, 0, 0, 0),
+	SC9860_RFFE0_SCK0_MISC = SPRD_PIN_INFO(408, MISC_PIN, 0, 0, 0),
+	SC9860_GPIO38_MISC = SPRD_PIN_INFO(410, MISC_PIN, 0, 0, 0),
+	SC9860_RFFE0_SDA0_MISC = SPRD_PIN_INFO(412, MISC_PIN, 0, 0, 0),
+	SC9860_GPIO39_MISC = SPRD_PIN_INFO(414, MISC_PIN, 0, 0, 0),
+	SC9860_RFFE1_SCK0_MISC = SPRD_PIN_INFO(416, MISC_PIN, 0, 0, 0),
+	SC9860_GPIO181_MISC = SPRD_PIN_INFO(418, MISC_PIN, 0, 0, 0),
+	SC9860_RFFE1_SDA0_MISC = SPRD_PIN_INFO(420, MISC_PIN, 0, 0, 0),
+	SC9860_GPIO182_MISC = SPRD_PIN_INFO(422, MISC_PIN, 0, 0, 0),
+	SC9860_RF_LVDS0_ADC_ON_MISC = SPRD_PIN_INFO(424, MISC_PIN, 0, 0, 0),
+	SC9860_RF_LVDS0_DAC_ON_MISC = SPRD_PIN_INFO(426, MISC_PIN, 0, 0, 0),
+	SC9860_RFSCK0_MISC = SPRD_PIN_INFO(428, MISC_PIN, 0, 0, 0),
+	SC9860_RFSDA0_MISC = SPRD_PIN_INFO(430, MISC_PIN, 0, 0, 0),
+	SC9860_RFSEN0_MISC = SPRD_PIN_INFO(432, MISC_PIN, 0, 0, 0),
+	SC9860_RF_LVDS1_ADC_ON_MISC = SPRD_PIN_INFO(434, MISC_PIN, 0, 0, 0),
+	SC9860_RF_LVDS1_DAC_ON_MISC = SPRD_PIN_INFO(436, MISC_PIN, 0, 0, 0),
+	SC9860_RFSCK1_MISC = SPRD_PIN_INFO(438, MISC_PIN, 0, 0, 0),
+	SC9860_RFSDA1_MISC = SPRD_PIN_INFO(440, MISC_PIN, 0, 0, 0),
+	SC9860_RFSEN1_MISC = SPRD_PIN_INFO(442, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL38_MISC = SPRD_PIN_INFO(444, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL39_MISC = SPRD_PIN_INFO(446, MISC_PIN, 0, 0, 0),
+};
+
+static struct sprd_pins_info sprd_sc9860_pins_info[] = {
+	SPRD_PINCTRL_PIN(SC9860_VIO28_0_IRTE),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SD2_IRTE),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SD0_IRTE),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SIM2_IRTE),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SIM1_IRTE),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SIM0_IRTE),
+	SPRD_PINCTRL_PIN(SC9860_VIO28_0_MS),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SD2_MS),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SD0_MS),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SIM2_MS),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SIM1_MS),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SIM0_MS),
+	SPRD_PINCTRL_PIN(SC9860_SPSPI_PIN_IN_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART1_USB30_PHY_SEL),
+	SPRD_PINCTRL_PIN(SC9860_USB30_PHY_DM_OE),
+	SPRD_PINCTRL_PIN(SC9860_USB30_PHY_DP_OE),
+	SPRD_PINCTRL_PIN(SC9860_UART5_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_ORP_URXD_PIN_IN_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SIM2_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SIM1_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SIM0_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_CLK26MHZ_BUF_OUT_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART4_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART3_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART2_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART1_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART0_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART24_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART23_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART14_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART13_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS3_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS2_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS1_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS0_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS23_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS13_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS12_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS03_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS02_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS01_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS6_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS5_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS4_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_I2C_INF6_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_I2C_INF4_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_I2C_INF2_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_I2C_INF1_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_I2C_INF0_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_GPIO_INF7_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_GPIO_INF6_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_GPIO_INF5_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_GPIO_INF4_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_GPIO_INF3_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_GPIO_INF2_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_GPIO_INF1_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_GPIO_INF0_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_WDRST_OUT_SEL),
+	SPRD_PINCTRL_PIN(SC9860_ADI_SYNC_PIN_OUT_SEL),
+	SPRD_PINCTRL_PIN(SC9860_CMRST_SEL),
+	SPRD_PINCTRL_PIN(SC9860_CMPD_SEL),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE11),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE10),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE9),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE8),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE7),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE6),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE5),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE4),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE3),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE2),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE1),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE0),
+	SPRD_PINCTRL_PIN(SC9860_SP_EIC_DPAD3_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SP_EIC_DPAD2_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SP_EIC_DPAD1_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SP_EIC_DPAD0_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SP_EIC_DPAD7_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SP_EIC_DPAD6_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SP_EIC_DPAD5_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SP_EIC_DPAD4_SEL),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL20),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL21),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL30),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL31),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL32),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL33),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL34),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL35),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL36),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL37),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL22),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL23),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL24),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL25),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL26),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL27),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL28),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL29),
+	SPRD_PINCTRL_PIN(SC9860_SCL2),
+	SPRD_PINCTRL_PIN(SC9860_SDA2),
+	SPRD_PINCTRL_PIN(SC9860_MTCK_ARM),
+	SPRD_PINCTRL_PIN(SC9860_MTMS_ARM),
+	SPRD_PINCTRL_PIN(SC9860_XTL_EN0),
+	SPRD_PINCTRL_PIN(SC9860_PTEST),
+	SPRD_PINCTRL_PIN(SC9860_AUD_DAD1),
+	SPRD_PINCTRL_PIN(SC9860_AUD_ADD0),
+	SPRD_PINCTRL_PIN(SC9860_AUD_ADSYNC),
+	SPRD_PINCTRL_PIN(SC9860_AUD_SCLK),
+	SPRD_PINCTRL_PIN(SC9860_CHIP_SLEEP),
+	SPRD_PINCTRL_PIN(SC9860_CLK_32K),
+	SPRD_PINCTRL_PIN(SC9860_DCDC_ARM_EN),
+	SPRD_PINCTRL_PIN(SC9860_EXT_RST_B),
+	SPRD_PINCTRL_PIN(SC9860_ADI_D),
+	SPRD_PINCTRL_PIN(SC9860_ADI_SCLK),
+	SPRD_PINCTRL_PIN(SC9860_XTL_EN1),
+	SPRD_PINCTRL_PIN(SC9860_ANA_INT),
+	SPRD_PINCTRL_PIN(SC9860_AUD_DAD0),
+	SPRD_PINCTRL_PIN(SC9860_AUD_DASYNC),
+	SPRD_PINCTRL_PIN(SC9860_LCM_RSTN),
+	SPRD_PINCTRL_PIN(SC9860_DSI_TE),
+	SPRD_PINCTRL_PIN(SC9860_PWMA),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT0),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT1),
+	SPRD_PINCTRL_PIN(SC9860_SDA1),
+	SPRD_PINCTRL_PIN(SC9860_SCL1),
+	SPRD_PINCTRL_PIN(SC9860_SIMCLK2),
+	SPRD_PINCTRL_PIN(SC9860_SIMDA2),
+	SPRD_PINCTRL_PIN(SC9860_SIMRST2),
+	SPRD_PINCTRL_PIN(SC9860_SIMCLK1),
+	SPRD_PINCTRL_PIN(SC9860_SIMDA1),
+	SPRD_PINCTRL_PIN(SC9860_SIMRST1),
+	SPRD_PINCTRL_PIN(SC9860_SIMCLK0),
+	SPRD_PINCTRL_PIN(SC9860_SIMDA0),
+	SPRD_PINCTRL_PIN(SC9860_SIMRST0),
+	SPRD_PINCTRL_PIN(SC9860_SD2_CMD),
+	SPRD_PINCTRL_PIN(SC9860_SD2_D0),
+	SPRD_PINCTRL_PIN(SC9860_SD2_D1),
+	SPRD_PINCTRL_PIN(SC9860_SD2_CLK),
+	SPRD_PINCTRL_PIN(SC9860_SD2_D2),
+	SPRD_PINCTRL_PIN(SC9860_SD2_D3),
+	SPRD_PINCTRL_PIN(SC9860_SD0_D3),
+	SPRD_PINCTRL_PIN(SC9860_SD0_D2),
+	SPRD_PINCTRL_PIN(SC9860_SD0_CMD),
+	SPRD_PINCTRL_PIN(SC9860_SD0_D0),
+	SPRD_PINCTRL_PIN(SC9860_SD0_D1),
+	SPRD_PINCTRL_PIN(SC9860_SD0_CLK),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_CMD),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D6),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D7),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_CLK),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D5),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D4),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_DS),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D3),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_RST),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D1),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D2),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D0),
+	SPRD_PINCTRL_PIN(SC9860_IIS0DI),
+	SPRD_PINCTRL_PIN(SC9860_IIS0DO),
+	SPRD_PINCTRL_PIN(SC9860_IIS0CLK),
+	SPRD_PINCTRL_PIN(SC9860_IIS0LRCK),
+	SPRD_PINCTRL_PIN(SC9860_SD1_CLK),
+	SPRD_PINCTRL_PIN(SC9860_SD1_CMD),
+	SPRD_PINCTRL_PIN(SC9860_SD1_D0),
+	SPRD_PINCTRL_PIN(SC9860_SD1_D1),
+	SPRD_PINCTRL_PIN(SC9860_SD1_D2),
+	SPRD_PINCTRL_PIN(SC9860_SD1_D3),
+	SPRD_PINCTRL_PIN(SC9860_CLK_AUX0),
+	SPRD_PINCTRL_PIN(SC9860_WIFI_COEXIST),
+	SPRD_PINCTRL_PIN(SC9860_BEIDOU_COEXIST),
+	SPRD_PINCTRL_PIN(SC9860_U3TXD),
+	SPRD_PINCTRL_PIN(SC9860_U3RXD),
+	SPRD_PINCTRL_PIN(SC9860_U3CTS),
+	SPRD_PINCTRL_PIN(SC9860_U3RTS),
+	SPRD_PINCTRL_PIN(SC9860_U0TXD),
+	SPRD_PINCTRL_PIN(SC9860_U0RXD),
+	SPRD_PINCTRL_PIN(SC9860_U0CTS),
+	SPRD_PINCTRL_PIN(SC9860_U0RTS),
+	SPRD_PINCTRL_PIN(SC9860_IIS1DI),
+	SPRD_PINCTRL_PIN(SC9860_IIS1DO),
+	SPRD_PINCTRL_PIN(SC9860_IIS1CLK),
+	SPRD_PINCTRL_PIN(SC9860_IIS1LRCK),
+	SPRD_PINCTRL_PIN(SC9860_SPI0_CSN),
+	SPRD_PINCTRL_PIN(SC9860_SPI0_DO),
+	SPRD_PINCTRL_PIN(SC9860_SPI0_DI),
+	SPRD_PINCTRL_PIN(SC9860_SPI0_CLK),
+	SPRD_PINCTRL_PIN(SC9860_U2TXD),
+	SPRD_PINCTRL_PIN(SC9860_U2RXD),
+	SPRD_PINCTRL_PIN(SC9860_U4TXD),
+	SPRD_PINCTRL_PIN(SC9860_U4RXD),
+	SPRD_PINCTRL_PIN(SC9860_CMMCLK1),
+	SPRD_PINCTRL_PIN(SC9860_CMRST1),
+	SPRD_PINCTRL_PIN(SC9860_CMMCLK0),
+	SPRD_PINCTRL_PIN(SC9860_CMRST0),
+	SPRD_PINCTRL_PIN(SC9860_CMPD0),
+	SPRD_PINCTRL_PIN(SC9860_CMPD1),
+	SPRD_PINCTRL_PIN(SC9860_SCL0),
+	SPRD_PINCTRL_PIN(SC9860_SDA0),
+	SPRD_PINCTRL_PIN(SC9860_SDA6),
+	SPRD_PINCTRL_PIN(SC9860_SCL6),
+	SPRD_PINCTRL_PIN(SC9860_U1TXD),
+	SPRD_PINCTRL_PIN(SC9860_U1RXD),
+	SPRD_PINCTRL_PIN(SC9860_KEYOUT0),
+	SPRD_PINCTRL_PIN(SC9860_KEYOUT1),
+	SPRD_PINCTRL_PIN(SC9860_KEYOUT2),
+	SPRD_PINCTRL_PIN(SC9860_KEYIN0),
+	SPRD_PINCTRL_PIN(SC9860_KEYIN1),
+	SPRD_PINCTRL_PIN(SC9860_KEYIN2),
+	SPRD_PINCTRL_PIN(SC9860_IIS3DI),
+	SPRD_PINCTRL_PIN(SC9860_IIS3DO),
+	SPRD_PINCTRL_PIN(SC9860_IIS3CLK),
+	SPRD_PINCTRL_PIN(SC9860_IIS3LRCK),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL0),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL1),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL10),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL11),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL12),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL13),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL14),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL15),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL16),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL17),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL18),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL19),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL2),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT5),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT6),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT7),
+	SPRD_PINCTRL_PIN(SC9860_GPIO30),
+	SPRD_PINCTRL_PIN(SC9860_GPIO31),
+	SPRD_PINCTRL_PIN(SC9860_GPIO32),
+	SPRD_PINCTRL_PIN(SC9860_GPIO33),
+	SPRD_PINCTRL_PIN(SC9860_GPIO34),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL3),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL4),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL5),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL6),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL7),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL8),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL9),
+	SPRD_PINCTRL_PIN(SC9860_RFFE0_SCK0),
+	SPRD_PINCTRL_PIN(SC9860_GPIO38),
+	SPRD_PINCTRL_PIN(SC9860_RFFE0_SDA0),
+	SPRD_PINCTRL_PIN(SC9860_GPIO39),
+	SPRD_PINCTRL_PIN(SC9860_RFFE1_SCK0),
+	SPRD_PINCTRL_PIN(SC9860_GPIO181),
+	SPRD_PINCTRL_PIN(SC9860_RFFE1_SDA0),
+	SPRD_PINCTRL_PIN(SC9860_GPIO182),
+	SPRD_PINCTRL_PIN(SC9860_RF_LVDS0_ADC_ON),
+	SPRD_PINCTRL_PIN(SC9860_RF_LVDS0_DAC_ON),
+	SPRD_PINCTRL_PIN(SC9860_RFSCK0),
+	SPRD_PINCTRL_PIN(SC9860_RFSDA0),
+	SPRD_PINCTRL_PIN(SC9860_RFSEN0),
+	SPRD_PINCTRL_PIN(SC9860_RF_LVDS1_ADC_ON),
+	SPRD_PINCTRL_PIN(SC9860_RF_LVDS1_DAC_ON),
+	SPRD_PINCTRL_PIN(SC9860_RFSCK1),
+	SPRD_PINCTRL_PIN(SC9860_RFSDA1),
+	SPRD_PINCTRL_PIN(SC9860_RFSEN1),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL38),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL39),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL20_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL21_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL30_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL31_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL32_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL33_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL34_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL35_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL36_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL37_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL22_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL23_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL24_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL25_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL26_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL27_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL28_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL29_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SCL2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SDA2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_MTCK_ARM_MISC),
+	SPRD_PINCTRL_PIN(SC9860_MTMS_ARM_MISC),
+	SPRD_PINCTRL_PIN(SC9860_XTL_EN0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_PTEST_MISC),
+	SPRD_PINCTRL_PIN(SC9860_AUD_DAD1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_AUD_ADD0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_AUD_ADSYNC_MISC),
+	SPRD_PINCTRL_PIN(SC9860_AUD_SCLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_CHIP_SLEEP_MISC),
+	SPRD_PINCTRL_PIN(SC9860_CLK_32K_MISC),
+	SPRD_PINCTRL_PIN(SC9860_DCDC_ARM_EN_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EXT_RST_B_MISC),
+	SPRD_PINCTRL_PIN(SC9860_ADI_D_MISC),
+	SPRD_PINCTRL_PIN(SC9860_ADI_SCLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_XTL_EN1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_ANA_INT_MISC),
+	SPRD_PINCTRL_PIN(SC9860_AUD_DAD0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_AUD_DASYNC_MISC),
+	SPRD_PINCTRL_PIN(SC9860_LCM_RSTN_MISC),
+	SPRD_PINCTRL_PIN(SC9860_DSI_TE_MISC),
+	SPRD_PINCTRL_PIN(SC9860_PWMA_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SDA1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SCL1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SIMCLK2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SIMDA2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SIMRST2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SIMCLK1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SIMDA1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SIMRST1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SIMCLK0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SIMDA0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SIMRST0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD2_CMD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD2_D0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD2_D1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD2_CLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD2_D2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD2_D3_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD0_D3_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD0_D2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD0_CMD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD0_D0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD0_D1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD0_CLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_CMD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D6_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D7_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_CLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D5_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D4_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_DS_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D3_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_RST_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS0DI_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS0DO_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS0CLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS0LRCK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD1_CLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD1_CMD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD1_D0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD1_D1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD1_D2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD1_D3_MISC),
+	SPRD_PINCTRL_PIN(SC9860_CLK_AUX0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_WIFI_COEXIST_MISC),
+	SPRD_PINCTRL_PIN(SC9860_BEIDOU_COEXIST_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U3TXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U3RXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U3CTS_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U3RTS_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U0TXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U0RXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U0CTS_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U0RTS_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS1DI_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS1DO_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS1CLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS1LRCK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SPI0_CSN_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SPI0_DO_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SPI0_DI_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SPI0_CLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U2TXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U2RXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U4TXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U4RXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_CMMCLK1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_CMRST1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_CMMCLK0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_CMRST0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_CMPD0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_CMPD1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SCL0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SDA0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SDA6_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SCL6_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U1TXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U1RXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_KEYOUT0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_KEYOUT1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_KEYOUT2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_KEYIN0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_KEYIN1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_KEYIN2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS3DI_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS3DO_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS3CLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS3LRCK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL10_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL11_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL12_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL13_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL14_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL15_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL16_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL17_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL18_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL19_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT5_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT6_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT7_MISC),
+	SPRD_PINCTRL_PIN(SC9860_GPIO30_MISC),
+	SPRD_PINCTRL_PIN(SC9860_GPIO31_MISC),
+	SPRD_PINCTRL_PIN(SC9860_GPIO32_MISC),
+	SPRD_PINCTRL_PIN(SC9860_GPIO33_MISC),
+	SPRD_PINCTRL_PIN(SC9860_GPIO34_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL3_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL4_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL5_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL6_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL7_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL8_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL9_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFFE0_SCK0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_GPIO38_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFFE0_SDA0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_GPIO39_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFFE1_SCK0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_GPIO181_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFFE1_SDA0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_GPIO182_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RF_LVDS0_ADC_ON_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RF_LVDS0_DAC_ON_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFSCK0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFSDA0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFSEN0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RF_LVDS1_ADC_ON_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RF_LVDS1_DAC_ON_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFSCK1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFSDA1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFSEN1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL38_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL39_MISC),
+};
+
+static int sprd_pinctrl_probe(struct platform_device *pdev)
+{
+	return sprd_pinctrl_core_probe(pdev, sprd_sc9860_pins_info,
+				       ARRAY_SIZE(sprd_sc9860_pins_info));
+}
+
+static const struct of_device_id sprd_pinctrl_of_match[] = {
+	{
+		.compatible = "sprd,sc9860-pinctrl",
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, sprd_pinctrl_of_match);
+
+static struct platform_driver sprd_pinctrl_driver = {
+	.driver = {
+		.name = "sprd-pinctrl",
+		.owner = THIS_MODULE,
+		.of_match_table = sprd_pinctrl_of_match,
+	},
+	.probe = sprd_pinctrl_probe,
+	.remove = sprd_pinctrl_remove,
+	.shutdown = sprd_pinctrl_shutdown,
+};
+
+static int sprd_pinctrl_init(void)
+{
+	return platform_driver_register(&sprd_pinctrl_driver);
+}
+module_init(sprd_pinctrl_init);
+
+static void sprd_pinctrl_exit(void)
+{
+	platform_driver_unregister(&sprd_pinctrl_driver);
+}
+module_exit(sprd_pinctrl_exit);
+
+MODULE_DESCRIPTION("SPREADTRUM Pin Controller Driver");
+MODULE_AUTHOR("Baolin Wang <baolin.wang@spreadtrum.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/sprd/pinctrl-sprd.c b/drivers/pinctrl/sprd/pinctrl-sprd.c
new file mode 100644
index 0000000..bf4f358
--- /dev/null
+++ b/drivers/pinctrl/sprd/pinctrl-sprd.c
@@ -0,0 +1,912 @@
+/*
+ * Spreadtrum pin controller driver
+ * Copyright (C) 2017 Spreadtrum  - http://www.spreadtrum.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/debugfs.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/slab.h>
+
+#include "../core.h"
+#include "../pinmux.h"
+#include "../pinconf.h"
+#include "../pinctrl-utils.h"
+#include "pinctrl-sprd.h"
+
+#define PINCTRL_BIT_MASK(width)		(~(~0UL << (width)))
+#define PINCTRL_REG_OFFSET		0x20
+#define PINCTRL_REG_MISC_OFFSET		0x4020
+
+/**
+ * struct sprd_pin: represent one pin's description
+ * @name: pin name
+ * @number: pin number
+ * @type: pin type, can be GLOBAL_CTRL_PIN/COMMON_PIN/MISC_PIN
+ * @reg: pin register address
+ * @bit_offset: bit offset in pin register
+ * @bit_width: bit width in pin register
+ */
+struct sprd_pin {
+	const char *name;
+	unsigned int number;
+	enum pin_type type;
+	unsigned long reg;
+	unsigned long bit_offset;
+	unsigned long bit_width;
+};
+
+/**
+ * struct sprd_pin_group: represent one group's description
+ * @name: group name
+ * @npins: pin numbers of this group
+ * @pins: pointer to pins array
+ */
+struct sprd_pin_group {
+	const char *name;
+	unsigned int npins;
+	unsigned int *pins;
+};
+
+/**
+ * struct sprd_pinctrl_soc_info: represent the SoC's pins description
+ * @groups: pointer to groups of pins
+ * @ngroups: group numbers of the whole SoC
+ * @pins: pointer to pins description
+ * @npins: pin numbers of the whole SoC
+ * @grp_names: pointer to group names array
+ */
+struct sprd_pinctrl_soc_info {
+	struct sprd_pin_group *groups;
+	unsigned int ngroups;
+	struct sprd_pin *pins;
+	unsigned int npins;
+	const char **grp_names;
+};
+
+/**
+ * struct sprd_pinctrl: represent the pin controller device
+ * @dev: pointer to the device structure
+ * @pctl: pointer to the pinctrl handle
+ * @base: base address of the controller
+ * @info: pointer to SoC's pins description information
+ */
+struct sprd_pinctrl {
+	struct device *dev;
+	struct pinctrl_dev *pctl;
+	void __iomem *base;
+	struct sprd_pinctrl_soc_info *info;
+};
+
+static int sprd_pinctrl_get_id_by_name(struct sprd_pinctrl *sprd_pctl,
+				       const char *name)
+{
+	struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
+	int i;
+
+	for (i = 0; i < info->npins; i++) {
+		if (!strcmp(info->pins[i].name, name))
+			return info->pins[i].number;
+	}
+
+	return -ENODEV;
+}
+
+static struct sprd_pin *
+sprd_pinctrl_get_pin_by_id(struct sprd_pinctrl *sprd_pctl, unsigned int id)
+{
+	struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
+	struct sprd_pin *pin = NULL;
+	int i;
+
+	for (i = 0; i < info->npins; i++) {
+		if (info->pins[i].number == id) {
+			pin = &info->pins[i];
+			break;
+		}
+	}
+
+	return pin;
+}
+
+static const struct sprd_pin_group *
+sprd_pinctrl_find_group_by_name(struct sprd_pinctrl *sprd_pctl,
+				const char *name)
+{
+	struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
+	const struct sprd_pin_group *grp = NULL;
+	int i;
+
+	for (i = 0; i < info->ngroups; i++) {
+		if (!strcmp(info->groups[i].name, name)) {
+			grp = &info->groups[i];
+			break;
+		}
+	}
+
+	return grp;
+}
+
+static int sprd_pctrl_group_count(struct pinctrl_dev *pctldev)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pinctrl_soc_info *info = pctl->info;
+
+	return info->ngroups;
+}
+
+static const char *sprd_pctrl_group_name(struct pinctrl_dev *pctldev,
+					 unsigned int selector)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pinctrl_soc_info *info = pctl->info;
+
+	return info->groups[selector].name;
+}
+
+static int sprd_pctrl_group_pins(struct pinctrl_dev *pctldev,
+				 unsigned int selector,
+				 const unsigned int **pins,
+				 unsigned int *npins)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pinctrl_soc_info *info = pctl->info;
+
+	if (selector >= info->ngroups)
+		return -EINVAL;
+
+	*pins = info->groups[selector].pins;
+	*npins = info->groups[selector].npins;
+
+	return 0;
+}
+
+static int sprd_dt_node_to_map(struct pinctrl_dev *pctldev,
+			       struct device_node *np,
+			       struct pinctrl_map **map,
+			       unsigned int *num_maps)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	const struct sprd_pin_group *grp;
+	unsigned long *configs = NULL;
+	unsigned int num_configs = 0;
+	unsigned int reserved_maps = 0;
+	unsigned int reserve = 0;
+	const char *function;
+	enum pinctrl_map_type type;
+	int ret;
+
+	grp = sprd_pinctrl_find_group_by_name(pctl, np->name);
+	if (!grp) {
+		dev_err(pctl->dev, "unable to find group for node %s\n",
+			of_node_full_name(np));
+		return -EINVAL;
+	}
+
+	ret = of_property_count_strings(np, "pins");
+	if (ret < 0)
+		return ret;
+
+	if (ret == 1)
+		type = PIN_MAP_TYPE_CONFIGS_PIN;
+	else
+		type = PIN_MAP_TYPE_CONFIGS_GROUP;
+
+	ret = of_property_read_string(np, "function", &function);
+	if (ret < 0) {
+		if (ret != -EINVAL)
+			dev_err(pctl->dev,
+				"%s: could not parse property function\n",
+				of_node_full_name(np));
+		function = NULL;
+	}
+
+	ret = pinconf_generic_parse_dt_config(np, pctldev, &configs,
+					      &num_configs);
+	if (ret < 0) {
+		dev_err(pctl->dev, "%s: could not parse node property\n",
+			of_node_full_name(np));
+		return ret;
+	}
+
+	*map = NULL;
+	*num_maps = 0;
+
+	if (function != NULL)
+		reserve++;
+	if (num_configs)
+		reserve++;
+
+	ret = pinctrl_utils_reserve_map(pctldev, map, &reserved_maps,
+					num_maps, reserve);
+	if (ret < 0)
+		goto out;
+
+	if (function) {
+		ret = pinctrl_utils_add_map_mux(pctldev, map,
+						&reserved_maps, num_maps,
+						grp->name, function);
+		if (ret < 0)
+			goto out;
+	}
+
+	if (num_configs) {
+		const char *group_or_pin;
+		unsigned int pin_id;
+
+		if (type == PIN_MAP_TYPE_CONFIGS_PIN) {
+			pin_id = grp->pins[0];
+			group_or_pin = pin_get_name(pctldev, pin_id);
+		} else {
+			group_or_pin = grp->name;
+		}
+
+		ret = pinctrl_utils_add_map_configs(pctldev, map,
+						    &reserved_maps, num_maps,
+						    group_or_pin, configs,
+						    num_configs, type);
+	}
+
+out:
+	kfree(configs);
+	return ret;
+}
+
+static void sprd_pctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+				unsigned int offset)
+{
+	seq_printf(s, "%s", dev_name(pctldev->dev));
+}
+
+static const struct pinctrl_ops sprd_pctrl_ops = {
+	.get_groups_count = sprd_pctrl_group_count,
+	.get_group_name = sprd_pctrl_group_name,
+	.get_group_pins = sprd_pctrl_group_pins,
+	.pin_dbg_show = sprd_pctrl_dbg_show,
+	.dt_node_to_map = sprd_dt_node_to_map,
+	.dt_free_map = pinctrl_utils_free_map,
+};
+
+int sprd_pmx_get_function_count(struct pinctrl_dev *pctldev)
+{
+	return PIN_FUNC_MAX;
+}
+
+const char *sprd_pmx_get_function_name(struct pinctrl_dev *pctldev,
+				       unsigned int selector)
+{
+	switch (selector) {
+	case PIN_FUNC_1:
+		return "func1";
+	case PIN_FUNC_2:
+		return "func2";
+	case PIN_FUNC_3:
+		return "func3";
+	case PIN_FUNC_4:
+		return "func4";
+	default:
+		return "null";
+	}
+}
+
+int sprd_pmx_get_function_groups(struct pinctrl_dev *pctldev,
+				 unsigned int selector,
+				 const char * const **groups,
+				 unsigned int * const num_groups)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pinctrl_soc_info *info = pctl->info;
+
+	*groups = info->grp_names;
+	*num_groups = info->ngroups;
+
+	return 0;
+}
+
+static int sprd_pmx_set_mux(struct pinctrl_dev *pctldev,
+			    unsigned int func_selector,
+			    unsigned int group_selector)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pinctrl_soc_info *info = pctl->info;
+	struct sprd_pin_group *grp = &info->groups[group_selector];
+	unsigned int i, grp_pins = grp->npins;
+	unsigned long reg;
+	u32 val = 0;
+
+	if (group_selector > info->ngroups)
+		return -EINVAL;
+
+	switch (func_selector) {
+	case PIN_FUNC_1:
+		val &= ~(BIT(4) | BIT(5));
+		break;
+	case PIN_FUNC_2:
+		val |= BIT(4);
+		break;
+	case PIN_FUNC_3:
+		val |= BIT(5);
+		break;
+	case PIN_FUNC_4:
+		val |= BIT(4) | BIT(5);
+		break;
+	default:
+		break;
+	}
+
+	for (i = 0; i < grp_pins; i++) {
+		unsigned int pin_id = grp->pins[i];
+		struct sprd_pin *pin = sprd_pinctrl_get_pin_by_id(pctl, pin_id);
+
+		if (!pin || pin->type != COMMON_PIN)
+			continue;
+
+		reg = readl((void __iomem *)pin->reg);
+		reg &= ~(BIT(4) | BIT(5));
+		reg |= val;
+		writel(reg, (void __iomem *)pin->reg);
+	}
+
+	return 0;
+}
+
+static const struct pinmux_ops sprd_pmx_ops = {
+	.get_functions_count = sprd_pmx_get_function_count,
+	.get_function_name = sprd_pmx_get_function_name,
+	.get_function_groups = sprd_pmx_get_function_groups,
+	.set_mux = sprd_pmx_set_mux,
+};
+
+static int sprd_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin_id,
+			    unsigned long *config)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pin *pin = sprd_pinctrl_get_pin_by_id(pctl, pin_id);
+
+	if (!pin)
+		return -EINVAL;
+
+	if (pin->type == GLOBAL_CTRL_PIN) {
+		*config = (readl((void __iomem *)pin->reg) >>
+			   pin->bit_offset) & PINCTRL_BIT_MASK(pin->bit_width);
+	} else {
+		*config = readl((void __iomem *)pin->reg);
+	}
+
+	return 0;
+}
+
+static unsigned int sprd_pinconf_drive(unsigned int arg)
+{
+	u32 val = 0;
+
+	switch (arg) {
+	case 2:
+		break;
+	case 4:
+		val |= BIT(19);
+		break;
+	case 6:
+		val |= BIT(20);
+		break;
+	case 8:
+		val |= BIT(19) | BIT(20);
+		break;
+	case 10:
+		val |= BIT(21);
+		break;
+	case 12:
+		val |= BIT(21) | BIT(19);
+		break;
+	case 14:
+		val |= BIT(21) | BIT(20);
+		break;
+	case 16:
+		val |= BIT(19) | BIT(20) | BIT(21);
+		break;
+	case 20:
+		val |= BIT(22);
+		break;
+	case 21:
+		val |= BIT(22) | BIT(19);
+		break;
+	case 24:
+		val |= BIT(22) | BIT(20);
+		break;
+	case 25:
+		val |= BIT(22) | BIT(20) | BIT(19);
+		break;
+	case 27:
+		val |= BIT(22) | BIT(21);
+		break;
+	case 29:
+		val |= BIT(22) | BIT(21) | BIT(19);
+		break;
+	case 31:
+		val |= BIT(22) | BIT(21) | BIT(20);
+		break;
+	case 33:
+		val |= BIT(22) | BIT(21) | BIT(20) | BIT(19);
+		break;
+	default:
+		break;
+	}
+
+	return val;
+}
+
+static int sprd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin_id,
+			    unsigned long *configs, unsigned int num_configs)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pin *pin = sprd_pinctrl_get_pin_by_id(pctl, pin_id);
+	unsigned long reg;
+	int i;
+
+	if (!pin)
+		return -EINVAL;
+
+	for (i = 0; i < num_configs; i++) {
+		enum pin_config_param param;
+		u32 shift, mask, arg, val;
+
+		param = pinconf_to_config_param(configs[i]);
+		arg = pinconf_to_config_argument(configs[i]);
+
+		val = 0;
+		shift = 0;
+		mask = 0;
+		if (pin->type == GLOBAL_CTRL_PIN &&
+		    param == SPRD_PIN_CONFIG_CONTROL) {
+			val = arg;
+		} else if (pin->type == COMMON_PIN) {
+			switch (param) {
+			case SPRD_PIN_CONFIG_SLEEP_MODE:
+				if (arg & AP_SLEEP)
+					val |= BIT(13);
+				if (arg & PUBCP_SLEEP)
+					val |= BIT(14);
+				if (arg & TGLDSP_SLEEP)
+					val |= BIT(15);
+				if (arg & AGDSP_SLEEP)
+					val |= BIT(16);
+
+				mask = 0xf;
+				shift = 13;
+				break;
+			case SPRD_PIN_CONFIG_INPUT_SLEEP:
+				val |= BIT(1);
+				mask = 0x1;
+				shift = 1;
+				break;
+			case SPRD_PIN_CONFIG_OUTPUT_SLEEP:
+				val |= BIT(0);
+				mask = 0x1;
+				shift = 0;
+				break;
+			default:
+				return -ENOTSUPP;
+			}
+		} else if (pin->type == MISC_PIN) {
+			switch (param) {
+			case PIN_CONFIG_DRIVE_STRENGTH:
+				if (arg < 2 || arg > 60)
+					return -EINVAL;
+
+				val = sprd_pinconf_drive(arg);
+				mask = 0xf;
+				shift = 19;
+				break;
+			case PIN_CONFIG_BIAS_PULL_DOWN:
+				val |= BIT(6);
+				mask = 0x1;
+				shift = 6;
+				break;
+			case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+				if (arg > 0)
+					val |= BIT(11);
+				else
+					val &= ~BIT(11);
+
+				mask = 0x1;
+				shift = 11;
+				break;
+			case SPRD_PIN_CONFIG_PULLUP:
+				if (arg == PULLUP_20K)
+					val |= BIT(12) | BIT(7);
+				else if (arg == PULLUP_4_7K)
+					val |= BIT(12);
+
+				mask = 0x21;
+				shift = 7;
+				break;
+			case SPRD_PIN_CONFIG_PULLUP_SLEEP:
+				val |= BIT(3);
+				mask = 0x1;
+				shift = 3;
+				break;
+			case SPRD_PIN_CONFIG_PULLDOWN_SLEEP:
+				val |= BIT(2);
+				mask = 0x1;
+				shift = 2;
+				break;
+			default:
+				return -ENOTSUPP;
+			}
+		} else {
+			return -ENOTSUPP;
+		}
+
+		if (pin->type == GLOBAL_CTRL_PIN) {
+			reg = readl((void __iomem *)pin->reg);
+			reg &= ~(PINCTRL_BIT_MASK(pin->bit_width)
+				<< pin->bit_offset);
+			reg |= (val & PINCTRL_BIT_MASK(pin->bit_width))
+				<< pin->bit_offset;
+			writel(reg, (void __iomem *)pin->reg);
+		} else {
+			reg = readl((void __iomem *)pin->reg);
+			reg &= ~(mask << shift);
+			reg |= val;
+			writel(reg, (void __iomem *)pin->reg);
+		}
+	}
+
+	return 0;
+}
+
+static int sprd_pinconf_group_get(struct pinctrl_dev *pctldev,
+				  unsigned int selector, unsigned long *config)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pinctrl_soc_info *info = pctl->info;
+	struct sprd_pin_group *grp;
+	int ret, i;
+
+	if (selector > info->ngroups)
+		return -EINVAL;
+
+	grp = &info->groups[selector];
+
+	for (i = 0; i < grp->npins; i++, config++) {
+		unsigned int pin_id = grp->pins[i];
+
+		ret = sprd_pinconf_get(pctldev, pin_id, config);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int sprd_pinconf_group_set(struct pinctrl_dev *pctldev,
+				  unsigned int selector,
+				  unsigned long *configs,
+				  unsigned int num_configs)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pinctrl_soc_info *info = pctl->info;
+	struct sprd_pin_group *grp;
+	int ret, i;
+
+	if (selector > info->ngroups)
+		return -EINVAL;
+
+	grp = &info->groups[selector];
+
+	for (i = 0; i < grp->npins; i++) {
+		unsigned int pin_id = grp->pins[i];
+
+		ret = sprd_pinconf_set(pctldev, pin_id, configs, num_configs);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static void sprd_pinconf_dbg_show(struct pinctrl_dev *pctldev,
+				  struct seq_file *s, unsigned int pin_id)
+{
+	unsigned long config;
+	int ret;
+
+	ret = sprd_pinconf_get(pctldev, pin_id, &config);
+	if (ret)
+		return;
+
+	seq_printf(s, "0x%lx", config);
+}
+
+static void sprd_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
+					struct seq_file *s,
+					unsigned int selector)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pinctrl_soc_info *info = pctl->info;
+	struct sprd_pin_group *grp;
+	unsigned long config;
+	const char *name;
+	int i, ret;
+
+	if (selector > info->ngroups)
+		return;
+
+	grp = &info->groups[selector];
+
+	seq_printf(s, "\n");
+	for (i = 0; i < grp->npins; i++, config++) {
+		unsigned int pin_id = grp->pins[i];
+
+		name = pin_get_name(pctldev, pin_id);
+		ret = sprd_pinconf_get(pctldev, pin_id, &config);
+		if (ret)
+			return;
+
+		seq_printf(s, "%s: 0x%lx", name, config);
+	}
+}
+
+static const struct pinconf_ops sprd_pinconf_ops = {
+	.pin_config_get = sprd_pinconf_get,
+	.pin_config_set = sprd_pinconf_set,
+	.pin_config_group_get = sprd_pinconf_group_get,
+	.pin_config_group_set = sprd_pinconf_group_set,
+	.pin_config_dbg_show = sprd_pinconf_dbg_show,
+	.pin_config_group_dbg_show = sprd_pinconf_group_dbg_show,
+};
+
+static const struct pinconf_generic_params sprd_dt_params[] = {
+	{"sprd,ctrl", SPRD_PIN_CONFIG_CONTROL, 0},
+	{"sprd,sleep_mode", SPRD_PIN_CONFIG_SLEEP_MODE, 0},
+	{"sprd,pullup", SPRD_PIN_CONFIG_PULLUP,	0},
+	{"sprd,input-sleep", SPRD_PIN_CONFIG_INPUT_SLEEP, 0},
+	{"sprd,output-sleep", SPRD_PIN_CONFIG_OUTPUT_SLEEP,	0},
+	{"sprd,pullup-sleep", SPRD_PIN_CONFIG_PULLUP_SLEEP,	0},
+	{"sprd,pulldown-sleep", SPRD_PIN_CONFIG_PULLDOWN_SLEEP,	0},
+};
+
+static struct pinctrl_desc sprd_pinctrl_desc = {
+	.pctlops = &sprd_pctrl_ops,
+	.pmxops = &sprd_pmx_ops,
+	.confops = &sprd_pinconf_ops,
+	.num_custom_params = ARRAY_SIZE(sprd_dt_params),
+	.custom_params = sprd_dt_params,
+	.owner = THIS_MODULE,
+};
+
+static int sprd_pinctrl_parse_groups(struct device_node *np,
+				     struct sprd_pinctrl *sprd_pctl,
+				     struct sprd_pin_group *grp)
+{
+	struct property *prop;
+	const char *pin_name;
+	int ret, i = 0;
+
+	ret = of_property_count_strings(np, "pins");
+	if (ret < 0)
+		return ret;
+
+	grp->name = np->name;
+	grp->npins = ret;
+	grp->pins = devm_kzalloc(sprd_pctl->dev, grp->npins *
+				 sizeof(unsigned int), GFP_KERNEL);
+	if (!grp->pins)
+		return -ENOMEM;
+
+	of_property_for_each_string(np, "pins", prop, pin_name) {
+		ret = sprd_pinctrl_get_id_by_name(sprd_pctl, pin_name);
+		if (ret >= 0)
+			grp->pins[i++] = ret;
+	}
+
+	for (i = 0; i < grp->npins; i++) {
+		dev_dbg(sprd_pctl->dev,
+			"Group[%s] contains [%d] pins: id = %d\n",
+			grp->name, grp->npins, grp->pins[i]);
+	}
+
+	return 0;
+}
+
+static int sprd_pinctrl_parse_dt(struct sprd_pinctrl *sprd_pctl)
+{
+	struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
+	struct device_node *np = sprd_pctl->dev->of_node;
+	struct device_node *child;
+	struct sprd_pin_group *grp;
+	const char **temp;
+	int ret;
+
+	if (!np)
+		return -ENODEV;
+
+	info->ngroups = of_get_child_count(np);
+	if (!info->ngroups)
+		return 0;
+
+	info->groups = devm_kzalloc(sprd_pctl->dev, info->ngroups *
+				    sizeof(struct sprd_pin_group),
+				    GFP_KERNEL);
+	if (!info->groups)
+		return -ENOMEM;
+
+	info->grp_names = devm_kzalloc(sprd_pctl->dev,
+				       info->ngroups * sizeof(char *),
+				       GFP_KERNEL);
+	if (!info->grp_names)
+		return -ENOMEM;
+
+	temp = info->grp_names;
+	grp = info->groups;
+	for_each_child_of_node(np, child) {
+		ret = sprd_pinctrl_parse_groups(child, sprd_pctl, grp);
+		if (ret)
+			return ret;
+
+		*temp++ = grp->name;
+		grp++;
+	}
+
+	return 0;
+}
+
+static int sprd_pinctrl_add_pins(struct sprd_pinctrl *sprd_pctl,
+				 struct sprd_pins_info *sprd_soc_pin_info,
+				 int pins_cnt)
+{
+	struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
+	unsigned int ctrl_pin = 0, com_pin = 0;
+	struct sprd_pin *pin;
+	int i;
+
+	info->npins = pins_cnt;
+	info->pins = devm_kzalloc(sprd_pctl->dev,
+				  info->npins * sizeof(struct sprd_pin),
+				  GFP_KERNEL);
+	if (!info->pins)
+		return -ENOMEM;
+
+	for (i = 0, pin = info->pins; i < info->npins; i++, pin++) {
+		unsigned int reg;
+
+		pin->name = sprd_soc_pin_info[i].name;
+		pin->type = sprd_soc_pin_info[i].type;
+		pin->number = sprd_soc_pin_info[i].num;
+		reg = sprd_soc_pin_info[i].reg;
+		if (pin->type == GLOBAL_CTRL_PIN) {
+			pin->reg = (unsigned long)sprd_pctl->base + 0x4 * reg;
+			pin->bit_offset = sprd_soc_pin_info[i].bit_offset;
+			pin->bit_width = sprd_soc_pin_info[i].bit_width;
+			ctrl_pin++;
+		} else if (pin->type == COMMON_PIN) {
+			pin->reg = (unsigned long)sprd_pctl->base +
+				PINCTRL_REG_OFFSET + 0x4 * (i - ctrl_pin);
+			com_pin++;
+		} else if (pin->type == MISC_PIN) {
+			pin->reg = (unsigned long)sprd_pctl->base +
+				PINCTRL_REG_MISC_OFFSET +
+					0x4 * (i - ctrl_pin - com_pin);
+		}
+	}
+
+	for (i = 0, pin = info->pins; i < info->npins; pin++, i++) {
+		dev_dbg(sprd_pctl->dev, "pin name[%s-%d], type = %d, "
+			"bit offset = %ld, bit width = %ld, reg = 0x%lx\n",
+			pin->name, pin->number, pin->type,
+			pin->bit_offset, pin->bit_width, pin->reg);
+	}
+
+	return 0;
+}
+
+int sprd_pinctrl_core_probe(struct platform_device *pdev,
+			    struct sprd_pins_info *sprd_soc_pin_info,
+			    int pins_cnt)
+{
+	struct sprd_pinctrl *sprd_pctl;
+	struct sprd_pinctrl_soc_info *pinctrl_info;
+	struct pinctrl_pin_desc *pin_desc;
+	struct resource *res;
+	int ret, i;
+
+	sprd_pctl = devm_kzalloc(&pdev->dev, sizeof(struct sprd_pinctrl),
+				 GFP_KERNEL);
+	if (!sprd_pctl)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	sprd_pctl->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(sprd_pctl->base))
+		return PTR_ERR(sprd_pctl->base);
+
+	pinctrl_info = devm_kzalloc(&pdev->dev,
+				    sizeof(struct sprd_pinctrl_soc_info),
+				    GFP_KERNEL);
+	if (!pinctrl_info)
+		return -ENOMEM;
+
+	sprd_pctl->info = pinctrl_info;
+	sprd_pctl->dev = &pdev->dev;
+	platform_set_drvdata(pdev, sprd_pctl);
+
+	ret = sprd_pinctrl_add_pins(sprd_pctl, sprd_soc_pin_info, pins_cnt);
+	if (ret) {
+		dev_err(&pdev->dev, "fail to add pins information\n");
+		return ret;
+	}
+
+	pin_desc = devm_kzalloc(&pdev->dev, pinctrl_info->npins *
+				sizeof(struct pinctrl_pin_desc),
+				GFP_KERNEL);
+	if (!pin_desc)
+		return -ENOMEM;
+
+	for (i = 0; i < pinctrl_info->npins; i++) {
+		pin_desc[i].number = pinctrl_info->pins[i].number;
+		pin_desc[i].name = pinctrl_info->pins[i].name;
+		pin_desc[i].drv_data = pinctrl_info;
+	}
+
+	sprd_pinctrl_desc.pins = pin_desc;
+	sprd_pinctrl_desc.name = dev_name(&pdev->dev);
+	sprd_pinctrl_desc.npins = pinctrl_info->npins;
+
+	sprd_pctl->pctl = pinctrl_register(&sprd_pinctrl_desc,
+					   &pdev->dev, (void *)sprd_pctl);
+	if (IS_ERR(sprd_pctl->pctl)) {
+		dev_err(&pdev->dev, "could not register pinctrl driver\n");
+		return PTR_ERR(sprd_pctl->pctl);
+	}
+
+	ret = sprd_pinctrl_parse_dt(sprd_pctl);
+	if (ret) {
+		dev_err(&pdev->dev, "fail to parse dt properties\n");
+		pinctrl_unregister(sprd_pctl->pctl);
+		return ret;
+	}
+
+	return 0;
+}
+
+int sprd_pinctrl_remove(struct platform_device *pdev)
+{
+	struct sprd_pinctrl *sprd_pctl = platform_get_drvdata(pdev);
+
+	pinctrl_unregister(sprd_pctl->pctl);
+	return 0;
+}
+
+void sprd_pinctrl_shutdown(struct platform_device *pdev)
+{
+	struct pinctrl *pinctl = devm_pinctrl_get(&pdev->dev);
+	struct pinctrl_state *state;
+
+	state = pinctrl_lookup_state(pinctl, "pins-shutdown");
+	if (!IS_ERR(state))
+		pinctrl_select_state(pinctl, state);
+}
+
+MODULE_DESCRIPTION("SPREADTRUM Pin Controller Driver");
+MODULE_AUTHOR("Baolin Wang <baolin.wang@spreadtrum.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/sprd/pinctrl-sprd.h b/drivers/pinctrl/sprd/pinctrl-sprd.h
new file mode 100644
index 0000000..7cc3c36
--- /dev/null
+++ b/drivers/pinctrl/sprd/pinctrl-sprd.h
@@ -0,0 +1,95 @@
+/*
+ * Driver header file for pin controller driver
+ * Copyright (C) 2017 Spreadtrum  - http://www.spreadtrum.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef __PINCTRL_SPRD_H__
+#define __PINCTRL_SPRD_H__
+
+struct platform_device;
+
+#define SPRD_PIN_CONFIG_CONTROL		(PIN_CONFIG_END + 1)
+#define SPRD_PIN_CONFIG_SLEEP_MODE	(PIN_CONFIG_END + 2)
+#define SPRD_PIN_CONFIG_PULLUP		(PIN_CONFIG_END + 3)
+#define SPRD_PIN_CONFIG_INPUT_SLEEP	(PIN_CONFIG_END + 4)
+#define SPRD_PIN_CONFIG_OUTPUT_SLEEP	(PIN_CONFIG_END + 5)
+#define SPRD_PIN_CONFIG_PULLUP_SLEEP	(PIN_CONFIG_END + 6)
+#define SPRD_PIN_CONFIG_PULLDOWN_SLEEP	(PIN_CONFIG_END + 7)
+
+#define NUM_OFFSET	(20)
+#define TYPE_OFFSET	(16)
+#define BIT_OFFSET	(8)
+#define WIDTH_OFFSET	(4)
+
+#define SPRD_PIN_INFO(num, type, offset, width, reg)	\
+		(((num) & 0xFFF) << NUM_OFFSET |	\
+		 ((type) & 0xF) << TYPE_OFFSET |	\
+		 ((offset) & 0xFF) << BIT_OFFSET |	\
+		 ((width) & 0xF) << WIDTH_OFFSET |	\
+		 ((reg) & 0xF))
+
+#define SPRD_PINCTRL_PIN(pin)	SPRD_PINCTRL_PIN_DATA(pin, #pin)
+
+#define SPRD_PINCTRL_PIN_DATA(a, b)				\
+	{							\
+		.name = b,					\
+		.num = (((a) >> NUM_OFFSET) & 0xfff),		\
+		.type = (((a) >> TYPE_OFFSET) & 0xf),		\
+		.bit_offset = (((a) >> BIT_OFFSET) & 0xff),	\
+		.bit_width = ((a) >> WIDTH_OFFSET & 0xf),	\
+		.reg = ((a) & 0xf)				\
+	}
+
+enum pin_sleep_mode {
+	AP_SLEEP = BIT(0),
+	PUBCP_SLEEP = BIT(1),
+	TGLDSP_SLEEP = BIT(2),
+	AGDSP_SLEEP = BIT(3),
+};
+
+enum pin_func_sel {
+	PIN_FUNC_1,
+	PIN_FUNC_2,
+	PIN_FUNC_3,
+	PIN_FUNC_4,
+	PIN_FUNC_MAX,
+};
+
+enum pin_pullup_sel {
+	PULLUP_20K,
+	PULLUP_4_7K,
+};
+
+enum pin_type {
+	GLOBAL_CTRL_PIN,
+	COMMON_PIN,
+	MISC_PIN,
+};
+
+struct sprd_pins_info {
+	const char *name;
+	unsigned int num;
+	enum pin_type type;
+
+	/* for global control pins configuration */
+	unsigned long bit_offset;
+	unsigned long bit_width;
+	unsigned int reg;
+};
+
+int sprd_pinctrl_core_probe(struct platform_device *pdev,
+			    struct sprd_pins_info *sprd_soc_pin_info,
+			    int pins_cnt);
+int sprd_pinctrl_remove(struct platform_device *pdev);
+void sprd_pinctrl_shutdown(struct platform_device *pdev);
+
+#endif /* __PINCTRL_SPRD_H__ */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 2/2] pinctrl: sprd: Add Spreadtrum pin control driver
@ 2017-06-05 12:11   ` Baolin Wang
  0 siblings, 0 replies; 24+ messages in thread
From: Baolin Wang @ 2017-06-05 12:11 UTC (permalink / raw)
  To: linus.walleij, mark.rutland, robh+dt
  Cc: linux-gpio, devicetree, linux-kernel, broonie, baolin.wang, baolin.wang

This patch adds the pin control driver for Spreadtrum SC9860 platform.

Signed-off-by: Baolin Wang <baolin.wang@spreadtrum.com>
---
Changes since v1:
 - Remove magic numbers and use generic pin control bindings.
---
 drivers/pinctrl/Kconfig                    |    1 +
 drivers/pinctrl/Makefile                   |    1 +
 drivers/pinctrl/sprd/Kconfig               |   17 +
 drivers/pinctrl/sprd/Makefile              |    2 +
 drivers/pinctrl/sprd/pinctrl-sprd-sc9860.c |  972 ++++++++++++++++++++++++++++
 drivers/pinctrl/sprd/pinctrl-sprd.c        |  912 ++++++++++++++++++++++++++
 drivers/pinctrl/sprd/pinctrl-sprd.h        |   95 +++
 7 files changed, 2000 insertions(+)
 create mode 100644 drivers/pinctrl/sprd/Kconfig
 create mode 100644 drivers/pinctrl/sprd/Makefile
 create mode 100644 drivers/pinctrl/sprd/pinctrl-sprd-sc9860.c
 create mode 100644 drivers/pinctrl/sprd/pinctrl-sprd.c
 create mode 100644 drivers/pinctrl/sprd/pinctrl-sprd.h

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 8f8c2af..681e593 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -304,6 +304,7 @@ source "drivers/pinctrl/ti/Kconfig"
 source "drivers/pinctrl/uniphier/Kconfig"
 source "drivers/pinctrl/vt8500/Kconfig"
 source "drivers/pinctrl/mediatek/Kconfig"
+source "drivers/pinctrl/sprd/Kconfig"
 
 config PINCTRL_XWAY
 	bool
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index a251f43..006e352 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -57,3 +57,4 @@ obj-y				+= ti/
 obj-$(CONFIG_PINCTRL_UNIPHIER)	+= uniphier/
 obj-$(CONFIG_ARCH_VT8500)	+= vt8500/
 obj-$(CONFIG_PINCTRL_MTK)	+= mediatek/
+obj-y				+= sprd/
diff --git a/drivers/pinctrl/sprd/Kconfig b/drivers/pinctrl/sprd/Kconfig
new file mode 100644
index 0000000..6f4a7f9
--- /dev/null
+++ b/drivers/pinctrl/sprd/Kconfig
@@ -0,0 +1,17 @@
+#
+# Spreadtrum pin control drivers
+#
+
+config PINCTRL_SPRD
+	bool "Spreadtrum pinctrl driver"
+	select PINMUX
+	select PINCONF
+	select GENERIC_PINCONF
+	select GENERIC_PINMUX_FUNCTIONS
+	help
+	  Say Y here to enable Spreadtrum pinctrl driver
+
+config PINCTRL_SPRD_SC9860
+	bool "Spreadtrum SC9860 pinctrl driver"
+	help
+	  Say Y here to enable Spreadtrum SC9860 pinctrl driver
diff --git a/drivers/pinctrl/sprd/Makefile b/drivers/pinctrl/sprd/Makefile
new file mode 100644
index 0000000..b6caa8c
--- /dev/null
+++ b/drivers/pinctrl/sprd/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_PINCTRL_SPRD)		+= pinctrl-sprd.o
+obj-$(CONFIG_PINCTRL_SPRD_SC9860)	+= pinctrl-sprd-sc9860.o
diff --git a/drivers/pinctrl/sprd/pinctrl-sprd-sc9860.c b/drivers/pinctrl/sprd/pinctrl-sprd-sc9860.c
new file mode 100644
index 0000000..3cdad8b
--- /dev/null
+++ b/drivers/pinctrl/sprd/pinctrl-sprd-sc9860.c
@@ -0,0 +1,972 @@
+/*
+ * Spreadtrum pin controller driver
+ * Copyright (C) 2017 Spreadtrum  - http://www.spreadtrum.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "pinctrl-sprd.h"
+
+enum sprd_sc9860_pins {
+	/* pin global control register 0 */
+	SC9860_VIO28_0_IRTE = SPRD_PIN_INFO(0, GLOBAL_CTRL_PIN, 11, 1, 0),
+	SC9860_VIO_SD2_IRTE = SPRD_PIN_INFO(1, GLOBAL_CTRL_PIN, 10, 1, 0),
+	SC9860_VIO_SD0_IRTE = SPRD_PIN_INFO(2, GLOBAL_CTRL_PIN, 9, 1, 0),
+	SC9860_VIO_SIM2_IRTE = SPRD_PIN_INFO(3, GLOBAL_CTRL_PIN, 8, 1, 0),
+	SC9860_VIO_SIM1_IRTE = SPRD_PIN_INFO(4, GLOBAL_CTRL_PIN, 7, 1, 0),
+	SC9860_VIO_SIM0_IRTE = SPRD_PIN_INFO(5, GLOBAL_CTRL_PIN, 6, 1, 0),
+	SC9860_VIO28_0_MS = SPRD_PIN_INFO(6, GLOBAL_CTRL_PIN, 5, 1, 0),
+	SC9860_VIO_SD2_MS = SPRD_PIN_INFO(7, GLOBAL_CTRL_PIN, 4, 1, 0),
+	SC9860_VIO_SD0_MS = SPRD_PIN_INFO(8, GLOBAL_CTRL_PIN, 3, 1, 0),
+	SC9860_VIO_SIM2_MS = SPRD_PIN_INFO(9, GLOBAL_CTRL_PIN, 2, 1, 0),
+	SC9860_VIO_SIM1_MS = SPRD_PIN_INFO(10, GLOBAL_CTRL_PIN, 1, 1, 0),
+	SC9860_VIO_SIM0_MS = SPRD_PIN_INFO(11, GLOBAL_CTRL_PIN, 0, 1, 0),
+
+	/* pin global control register 2 */
+	SC9860_SPSPI_PIN_IN_SEL = SPRD_PIN_INFO(12, GLOBAL_CTRL_PIN, 31, 1, 2),
+	SC9860_UART1_USB30_PHY_SEL = SPRD_PIN_INFO(13, GLOBAL_CTRL_PIN, 30, 1, 2),
+	SC9860_USB30_PHY_DM_OE = SPRD_PIN_INFO(14, GLOBAL_CTRL_PIN, 29, 1, 2),
+	SC9860_USB30_PHY_DP_OE = SPRD_PIN_INFO(15, GLOBAL_CTRL_PIN, 28, 1, 2),
+	SC9860_UART5_SYS_SEL = SPRD_PIN_INFO(16, GLOBAL_CTRL_PIN, 25, 3, 2),
+	SC9860_ORP_URXD_PIN_IN_SEL = SPRD_PIN_INFO(17, GLOBAL_CTRL_PIN, 24, 1, 2),
+	SC9860_SIM2_SYS_SEL = SPRD_PIN_INFO(18, GLOBAL_CTRL_PIN, 23, 1, 2),
+	SC9860_SIM1_SYS_SEL = SPRD_PIN_INFO(19, GLOBAL_CTRL_PIN, 22, 1, 2),
+	SC9860_SIM0_SYS_SEL = SPRD_PIN_INFO(20, GLOBAL_CTRL_PIN, 21, 1, 2),
+	SC9860_CLK26MHZ_BUF_OUT_SEL = SPRD_PIN_INFO(21, GLOBAL_CTRL_PIN, 20, 1, 2),
+	SC9860_UART4_SYS_SEL = SPRD_PIN_INFO(22, GLOBAL_CTRL_PIN, 16, 3, 2),
+	SC9860_UART3_SYS_SEL = SPRD_PIN_INFO(23, GLOBAL_CTRL_PIN, 13, 3, 2),
+	SC9860_UART2_SYS_SEL = SPRD_PIN_INFO(24, GLOBAL_CTRL_PIN, 10, 3, 2),
+	SC9860_UART1_SYS_SEL = SPRD_PIN_INFO(25, GLOBAL_CTRL_PIN, 7, 3, 2),
+	SC9860_UART0_SYS_SEL = SPRD_PIN_INFO(26, GLOBAL_CTRL_PIN, 4, 3, 2),
+	SC9860_UART24_LOOP_SEL = SPRD_PIN_INFO(27, GLOBAL_CTRL_PIN, 3, 1, 2),
+	SC9860_UART23_LOOP_SEL = SPRD_PIN_INFO(28, GLOBAL_CTRL_PIN, 2, 1, 2),
+	SC9860_UART14_LOOP_SEL = SPRD_PIN_INFO(29, GLOBAL_CTRL_PIN, 1, 1, 2),
+	SC9860_UART13_LOOP_SEL = SPRD_PIN_INFO(30, GLOBAL_CTRL_PIN, 0, 1, 2),
+
+	/* pin global control register 3 */
+	SC9860_IIS3_SYS_SEL = SPRD_PIN_INFO(31, GLOBAL_CTRL_PIN, 18, 4, 3),
+	SC9860_IIS2_SYS_SEL = SPRD_PIN_INFO(32, GLOBAL_CTRL_PIN, 14, 4, 3),
+	SC9860_IIS1_SYS_SEL = SPRD_PIN_INFO(33, GLOBAL_CTRL_PIN, 10, 4, 3),
+	SC9860_IIS0_SYS_SEL = SPRD_PIN_INFO(34, GLOBAL_CTRL_PIN, 6, 4, 3),
+	SC9860_IIS23_LOOP_SEL = SPRD_PIN_INFO(35, GLOBAL_CTRL_PIN, 5, 1, 3),
+	SC9860_IIS13_LOOP_SEL = SPRD_PIN_INFO(36, GLOBAL_CTRL_PIN, 4, 1, 3),
+	SC9860_IIS12_LOOP_SEL = SPRD_PIN_INFO(37, GLOBAL_CTRL_PIN, 3, 1, 3),
+	SC9860_IIS03_LOOP_SEL = SPRD_PIN_INFO(38, GLOBAL_CTRL_PIN, 2, 1, 3),
+	SC9860_IIS02_LOOP_SEL = SPRD_PIN_INFO(39, GLOBAL_CTRL_PIN, 1, 1, 3),
+	SC9860_IIS01_LOOP_SEL = SPRD_PIN_INFO(40, GLOBAL_CTRL_PIN, 0, 1, 3),
+
+	/* pin global control register 4 */
+	SC9860_IIS6_SYS_SEL = SPRD_PIN_INFO(41, GLOBAL_CTRL_PIN, 27, 4, 4),
+	SC9860_IIS5_SYS_SEL = SPRD_PIN_INFO(42, GLOBAL_CTRL_PIN, 23, 4, 4),
+	SC9860_IIS4_SYS_SEL = SPRD_PIN_INFO(43, GLOBAL_CTRL_PIN, 19, 4, 4),
+	SC9860_I2C_INF6_SYS_SEL = SPRD_PIN_INFO(44, GLOBAL_CTRL_PIN, 8, 2, 4),
+	SC9860_I2C_INF4_SYS_SEL = SPRD_PIN_INFO(45, GLOBAL_CTRL_PIN, 6, 2, 4),
+	SC9860_I2C_INF2_SYS_SEL = SPRD_PIN_INFO(46, GLOBAL_CTRL_PIN, 4, 2, 4),
+	SC9860_I2C_INF1_SYS_SEL = SPRD_PIN_INFO(47, GLOBAL_CTRL_PIN, 2, 2, 4),
+	SC9860_I2C_INF0_SYS_SEL = SPRD_PIN_INFO(48, GLOBAL_CTRL_PIN, 0, 2, 4),
+
+	/* pin global control register 5 */
+	SC9860_GPIO_INF7_SYS_SEL = SPRD_PIN_INFO(49, GLOBAL_CTRL_PIN, 27, 1, 5),
+	SC9860_GPIO_INF6_SYS_SEL = SPRD_PIN_INFO(50, GLOBAL_CTRL_PIN, 26, 1, 5),
+	SC9860_GPIO_INF5_SYS_SEL = SPRD_PIN_INFO(51, GLOBAL_CTRL_PIN, 25, 1, 5),
+	SC9860_GPIO_INF4_SYS_SEL = SPRD_PIN_INFO(52, GLOBAL_CTRL_PIN, 24, 1, 5),
+	SC9860_GPIO_INF3_SYS_SEL = SPRD_PIN_INFO(53, GLOBAL_CTRL_PIN, 23, 1, 5),
+	SC9860_GPIO_INF2_SYS_SEL = SPRD_PIN_INFO(54, GLOBAL_CTRL_PIN, 22, 1, 5),
+	SC9860_GPIO_INF1_SYS_SEL = SPRD_PIN_INFO(55, GLOBAL_CTRL_PIN, 21, 1, 5),
+	SC9860_GPIO_INF0_SYS_SEL = SPRD_PIN_INFO(56, GLOBAL_CTRL_PIN, 20, 1, 5),
+	SC9860_WDRST_OUT_SEL = SPRD_PIN_INFO(57, GLOBAL_CTRL_PIN, 16, 3, 5),
+	SC9860_ADI_SYNC_PIN_OUT_SEL = SPRD_PIN_INFO(58, GLOBAL_CTRL_PIN, 14, 1, 5),
+	SC9860_CMRST_SEL = SPRD_PIN_INFO(59, GLOBAL_CTRL_PIN, 13, 1, 5),
+	SC9860_CMPD_SEL = SPRD_PIN_INFO(60, GLOBAL_CTRL_PIN, 12, 1, 5),
+	SC9860_TEST_DBG_MODE11 = SPRD_PIN_INFO(61, GLOBAL_CTRL_PIN, 11, 1, 5),
+	SC9860_TEST_DBG_MODE10 = SPRD_PIN_INFO(62, GLOBAL_CTRL_PIN, 10, 1, 5),
+	SC9860_TEST_DBG_MODE9 = SPRD_PIN_INFO(63, GLOBAL_CTRL_PIN, 9, 1, 5),
+	SC9860_TEST_DBG_MODE8 = SPRD_PIN_INFO(64, GLOBAL_CTRL_PIN, 8, 1, 5),
+	SC9860_TEST_DBG_MODE7 = SPRD_PIN_INFO(65, GLOBAL_CTRL_PIN, 7, 1, 5),
+	SC9860_TEST_DBG_MODE6 = SPRD_PIN_INFO(66, GLOBAL_CTRL_PIN, 6, 1, 5),
+	SC9860_TEST_DBG_MODE5 = SPRD_PIN_INFO(67, GLOBAL_CTRL_PIN, 5, 1, 5),
+	SC9860_TEST_DBG_MODE4 = SPRD_PIN_INFO(68, GLOBAL_CTRL_PIN, 4, 1, 5),
+	SC9860_TEST_DBG_MODE3 = SPRD_PIN_INFO(69, GLOBAL_CTRL_PIN, 3, 1, 5),
+	SC9860_TEST_DBG_MODE2 = SPRD_PIN_INFO(70, GLOBAL_CTRL_PIN, 2, 1, 5),
+	SC9860_TEST_DBG_MODE1 = SPRD_PIN_INFO(71, GLOBAL_CTRL_PIN, 1, 1, 5),
+	SC9860_TEST_DBG_MODE0 = SPRD_PIN_INFO(72, GLOBAL_CTRL_PIN, 0, 1, 5),
+
+	/* pin global control register 6 */
+	SC9860_SP_EIC_DPAD3_SEL = SPRD_PIN_INFO(73, GLOBAL_CTRL_PIN, 24, 8, 6),
+	SC9860_SP_EIC_DPAD2_SEL = SPRD_PIN_INFO(74, GLOBAL_CTRL_PIN, 16, 8, 6),
+	SC9860_SP_EIC_DPAD1_SEL = SPRD_PIN_INFO(75, GLOBAL_CTRL_PIN, 8, 8, 6),
+	SC9860_SP_EIC_DPAD0_SEL = SPRD_PIN_INFO(76, GLOBAL_CTRL_PIN, 0, 8, 6),
+
+	/* pin global control register 7 */
+	SC9860_SP_EIC_DPAD7_SEL = SPRD_PIN_INFO(77, GLOBAL_CTRL_PIN, 24, 8, 7),
+	SC9860_SP_EIC_DPAD6_SEL = SPRD_PIN_INFO(78, GLOBAL_CTRL_PIN, 16, 8, 7),
+	SC9860_SP_EIC_DPAD5_SEL = SPRD_PIN_INFO(79, GLOBAL_CTRL_PIN, 8, 8, 7),
+	SC9860_SP_EIC_DPAD4_SEL = SPRD_PIN_INFO(80, GLOBAL_CTRL_PIN, 0, 8, 7),
+
+	/* common pin registers definitions */
+	SC9860_RFCTL20 = SPRD_PIN_INFO(81, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL21 = SPRD_PIN_INFO(83, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL30 = SPRD_PIN_INFO(85, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL31 = SPRD_PIN_INFO(87, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL32 = SPRD_PIN_INFO(89, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL33 = SPRD_PIN_INFO(91, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL34 = SPRD_PIN_INFO(93, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL35 = SPRD_PIN_INFO(95, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL36 = SPRD_PIN_INFO(97, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL37 = SPRD_PIN_INFO(99, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL22 = SPRD_PIN_INFO(101, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL23 = SPRD_PIN_INFO(103, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL24 = SPRD_PIN_INFO(105, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL25 = SPRD_PIN_INFO(107, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL26 = SPRD_PIN_INFO(109, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL27 = SPRD_PIN_INFO(111, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL28 = SPRD_PIN_INFO(113, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL29 = SPRD_PIN_INFO(115, COMMON_PIN, 0, 0, 0),
+	SC9860_SCL2 = SPRD_PIN_INFO(117, COMMON_PIN, 0, 0, 0),
+	SC9860_SDA2 = SPRD_PIN_INFO(119, COMMON_PIN, 0, 0, 0),
+	SC9860_MTCK_ARM = SPRD_PIN_INFO(121, COMMON_PIN, 0, 0, 0),
+	SC9860_MTMS_ARM = SPRD_PIN_INFO(123, COMMON_PIN, 0, 0, 0),
+	SC9860_XTL_EN0 = SPRD_PIN_INFO(125, COMMON_PIN, 0, 0, 0),
+	SC9860_PTEST = SPRD_PIN_INFO(127, COMMON_PIN, 0, 0, 0),
+	SC9860_AUD_DAD1 = SPRD_PIN_INFO(129, COMMON_PIN, 0, 0, 0),
+	SC9860_AUD_ADD0 = SPRD_PIN_INFO(131, COMMON_PIN, 0, 0, 0),
+	SC9860_AUD_ADSYNC = SPRD_PIN_INFO(133, COMMON_PIN, 0, 0, 0),
+	SC9860_AUD_SCLK = SPRD_PIN_INFO(135, COMMON_PIN, 0, 0, 0),
+	SC9860_CHIP_SLEEP = SPRD_PIN_INFO(137, COMMON_PIN, 0, 0, 0),
+	SC9860_CLK_32K = SPRD_PIN_INFO(139, COMMON_PIN, 0, 0, 0),
+	SC9860_DCDC_ARM_EN = SPRD_PIN_INFO(141, COMMON_PIN, 0, 0, 0),
+	SC9860_EXT_RST_B = SPRD_PIN_INFO(143, COMMON_PIN, 0, 0, 0),
+	SC9860_ADI_D = SPRD_PIN_INFO(145, COMMON_PIN, 0, 0, 0),
+	SC9860_ADI_SCLK = SPRD_PIN_INFO(147, COMMON_PIN, 0, 0, 0),
+	SC9860_XTL_EN1 = SPRD_PIN_INFO(149, COMMON_PIN, 0, 0, 0),
+	SC9860_ANA_INT = SPRD_PIN_INFO(151, COMMON_PIN, 0, 0, 0),
+	SC9860_AUD_DAD0 = SPRD_PIN_INFO(153, COMMON_PIN, 0, 0, 0),
+	SC9860_AUD_DASYNC = SPRD_PIN_INFO(155, COMMON_PIN, 0, 0, 0),
+	SC9860_LCM_RSTN = SPRD_PIN_INFO(157, COMMON_PIN, 0, 0, 0),
+	SC9860_DSI_TE = SPRD_PIN_INFO(159, COMMON_PIN, 0, 0, 0),
+	SC9860_PWMA = SPRD_PIN_INFO(161, COMMON_PIN, 0, 0, 0),
+	SC9860_EXTINT0 = SPRD_PIN_INFO(163, COMMON_PIN, 0, 0, 0),
+	SC9860_EXTINT1 = SPRD_PIN_INFO(165, COMMON_PIN, 0, 0, 0),
+	SC9860_SDA1 = SPRD_PIN_INFO(167, COMMON_PIN, 0, 0, 0),
+	SC9860_SCL1 = SPRD_PIN_INFO(169, COMMON_PIN, 0, 0, 0),
+	SC9860_SIMCLK2 = SPRD_PIN_INFO(171, COMMON_PIN, 0, 0, 0),
+	SC9860_SIMDA2 = SPRD_PIN_INFO(173, COMMON_PIN, 0, 0, 0),
+	SC9860_SIMRST2 = SPRD_PIN_INFO(175, COMMON_PIN, 0, 0, 0),
+	SC9860_SIMCLK1 = SPRD_PIN_INFO(177, COMMON_PIN, 0, 0, 0),
+	SC9860_SIMDA1 = SPRD_PIN_INFO(179, COMMON_PIN, 0, 0, 0),
+	SC9860_SIMRST1 = SPRD_PIN_INFO(181, COMMON_PIN, 0, 0, 0),
+	SC9860_SIMCLK0 = SPRD_PIN_INFO(183, COMMON_PIN, 0, 0, 0),
+	SC9860_SIMDA0 = SPRD_PIN_INFO(185, COMMON_PIN, 0, 0, 0),
+	SC9860_SIMRST0 = SPRD_PIN_INFO(187, COMMON_PIN, 0, 0, 0),
+	SC9860_SD2_CMD = SPRD_PIN_INFO(189, COMMON_PIN, 0, 0, 0),
+	SC9860_SD2_D0 = SPRD_PIN_INFO(191, COMMON_PIN, 0, 0, 0),
+	SC9860_SD2_D1 = SPRD_PIN_INFO(193, COMMON_PIN, 0, 0, 0),
+	SC9860_SD2_CLK = SPRD_PIN_INFO(195, COMMON_PIN, 0, 0, 0),
+	SC9860_SD2_D2 = SPRD_PIN_INFO(197, COMMON_PIN, 0, 0, 0),
+	SC9860_SD2_D3 = SPRD_PIN_INFO(199, COMMON_PIN, 0, 0, 0),
+	SC9860_SD0_D3 = SPRD_PIN_INFO(201, COMMON_PIN, 0, 0, 0),
+	SC9860_SD0_D2 = SPRD_PIN_INFO(203, COMMON_PIN, 0, 0, 0),
+	SC9860_SD0_CMD = SPRD_PIN_INFO(205, COMMON_PIN, 0, 0, 0),
+	SC9860_SD0_D0 = SPRD_PIN_INFO(207, COMMON_PIN, 0, 0, 0),
+	SC9860_SD0_D1 = SPRD_PIN_INFO(209, COMMON_PIN, 0, 0, 0),
+	SC9860_SD0_CLK = SPRD_PIN_INFO(211, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_CMD_reserved = SPRD_PIN_INFO(213, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_CMD = SPRD_PIN_INFO(215, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_D6 = SPRD_PIN_INFO(217, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_D7 = SPRD_PIN_INFO(219, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_CLK = SPRD_PIN_INFO(221, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_D5 = SPRD_PIN_INFO(223, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_D4 = SPRD_PIN_INFO(225, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_DS = SPRD_PIN_INFO(227, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_D3_reserved = SPRD_PIN_INFO(229, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_D3 = SPRD_PIN_INFO(231, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_RST = SPRD_PIN_INFO(233, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_D1 = SPRD_PIN_INFO(235, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_D2 = SPRD_PIN_INFO(237, COMMON_PIN, 0, 0, 0),
+	SC9860_EMMC_D0 = SPRD_PIN_INFO(239, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS0DI = SPRD_PIN_INFO(241, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS0DO = SPRD_PIN_INFO(243, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS0CLK = SPRD_PIN_INFO(245, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS0LRCK = SPRD_PIN_INFO(247, COMMON_PIN, 0, 0, 0),
+	SC9860_SD1_CLK = SPRD_PIN_INFO(249, COMMON_PIN, 0, 0, 0),
+	SC9860_SD1_CMD = SPRD_PIN_INFO(251, COMMON_PIN, 0, 0, 0),
+	SC9860_SD1_D0 = SPRD_PIN_INFO(253, COMMON_PIN, 0, 0, 0),
+	SC9860_SD1_D1 = SPRD_PIN_INFO(255, COMMON_PIN, 0, 0, 0),
+	SC9860_SD1_D2 = SPRD_PIN_INFO(257, COMMON_PIN, 0, 0, 0),
+	SC9860_SD1_D3 = SPRD_PIN_INFO(259, COMMON_PIN, 0, 0, 0),
+	SC9860_CLK_AUX0 = SPRD_PIN_INFO(261, COMMON_PIN, 0, 0, 0),
+	SC9860_WIFI_COEXIST = SPRD_PIN_INFO(263, COMMON_PIN, 0, 0, 0),
+	SC9860_BEIDOU_COEXIST = SPRD_PIN_INFO(265, COMMON_PIN, 0, 0, 0),
+	SC9860_U3TXD = SPRD_PIN_INFO(267, COMMON_PIN, 0, 0, 0),
+	SC9860_U3RXD = SPRD_PIN_INFO(269, COMMON_PIN, 0, 0, 0),
+	SC9860_U3CTS = SPRD_PIN_INFO(271, COMMON_PIN, 0, 0, 0),
+	SC9860_U3RTS = SPRD_PIN_INFO(273, COMMON_PIN, 0, 0, 0),
+	SC9860_U0TXD = SPRD_PIN_INFO(275, COMMON_PIN, 0, 0, 0),
+	SC9860_U0RXD = SPRD_PIN_INFO(277, COMMON_PIN, 0, 0, 0),
+	SC9860_U0CTS = SPRD_PIN_INFO(279, COMMON_PIN, 0, 0, 0),
+	SC9860_U0RTS = SPRD_PIN_INFO(281, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS1DI = SPRD_PIN_INFO(283, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS1DO = SPRD_PIN_INFO(285, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS1CLK = SPRD_PIN_INFO(287, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS1LRCK = SPRD_PIN_INFO(289, COMMON_PIN, 0, 0, 0),
+	SC9860_SPI0_CSN = SPRD_PIN_INFO(291, COMMON_PIN, 0, 0, 0),
+	SC9860_SPI0_DO = SPRD_PIN_INFO(293, COMMON_PIN, 0, 0, 0),
+	SC9860_SPI0_DI = SPRD_PIN_INFO(295, COMMON_PIN, 0, 0, 0),
+	SC9860_SPI0_CLK = SPRD_PIN_INFO(297, COMMON_PIN, 0, 0, 0),
+	SC9860_U2TXD = SPRD_PIN_INFO(299, COMMON_PIN, 0, 0, 0),
+	SC9860_U2RXD = SPRD_PIN_INFO(301, COMMON_PIN, 0, 0, 0),
+	SC9860_U4TXD = SPRD_PIN_INFO(303, COMMON_PIN, 0, 0, 0),
+	SC9860_U4RXD = SPRD_PIN_INFO(305, COMMON_PIN, 0, 0, 0),
+	SC9860_CMMCLK1 = SPRD_PIN_INFO(307, COMMON_PIN, 0, 0, 0),
+	SC9860_CMRST1 = SPRD_PIN_INFO(309, COMMON_PIN, 0, 0, 0),
+	SC9860_CMMCLK0 = SPRD_PIN_INFO(311, COMMON_PIN, 0, 0, 0),
+	SC9860_CMRST0 = SPRD_PIN_INFO(313, COMMON_PIN, 0, 0, 0),
+	SC9860_CMPD0 = SPRD_PIN_INFO(315, COMMON_PIN, 0, 0, 0),
+	SC9860_CMPD1 = SPRD_PIN_INFO(317, COMMON_PIN, 0, 0, 0),
+	SC9860_SCL0 = SPRD_PIN_INFO(319, COMMON_PIN, 0, 0, 0),
+	SC9860_SDA0 = SPRD_PIN_INFO(321, COMMON_PIN, 0, 0, 0),
+	SC9860_SDA6 = SPRD_PIN_INFO(323, COMMON_PIN, 0, 0, 0),
+	SC9860_SCL6 = SPRD_PIN_INFO(325, COMMON_PIN, 0, 0, 0),
+	SC9860_U1TXD = SPRD_PIN_INFO(327, COMMON_PIN, 0, 0, 0),
+	SC9860_U1RXD = SPRD_PIN_INFO(329, COMMON_PIN, 0, 0, 0),
+	SC9860_KEYOUT0 = SPRD_PIN_INFO(331, COMMON_PIN, 0, 0, 0),
+	SC9860_KEYOUT1 = SPRD_PIN_INFO(333, COMMON_PIN, 0, 0, 0),
+	SC9860_KEYOUT2 = SPRD_PIN_INFO(335, COMMON_PIN, 0, 0, 0),
+	SC9860_KEYIN0 = SPRD_PIN_INFO(337, COMMON_PIN, 0, 0, 0),
+	SC9860_KEYIN1 = SPRD_PIN_INFO(339, COMMON_PIN, 0, 0, 0),
+	SC9860_KEYIN2 = SPRD_PIN_INFO(341, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS3DI = SPRD_PIN_INFO(343, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS3DO = SPRD_PIN_INFO(345, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS3CLK = SPRD_PIN_INFO(347, COMMON_PIN, 0, 0, 0),
+	SC9860_IIS3LRCK = SPRD_PIN_INFO(349, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL0 = SPRD_PIN_INFO(351, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL1 = SPRD_PIN_INFO(353, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL10 = SPRD_PIN_INFO(355, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL11 = SPRD_PIN_INFO(357, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL12 = SPRD_PIN_INFO(359, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL13 = SPRD_PIN_INFO(361, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL14 = SPRD_PIN_INFO(363, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL15 = SPRD_PIN_INFO(365, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL16 = SPRD_PIN_INFO(367, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL17 = SPRD_PIN_INFO(369, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL18 = SPRD_PIN_INFO(371, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL19 = SPRD_PIN_INFO(373, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL2 = SPRD_PIN_INFO(375, COMMON_PIN, 0, 0, 0),
+	SC9860_EXTINT5 = SPRD_PIN_INFO(377, COMMON_PIN, 0, 0, 0),
+	SC9860_EXTINT6 = SPRD_PIN_INFO(379, COMMON_PIN, 0, 0, 0),
+	SC9860_EXTINT7 = SPRD_PIN_INFO(381, COMMON_PIN, 0, 0, 0),
+	SC9860_GPIO30 = SPRD_PIN_INFO(383, COMMON_PIN, 0, 0, 0),
+	SC9860_GPIO31 = SPRD_PIN_INFO(385, COMMON_PIN, 0, 0, 0),
+	SC9860_GPIO32 = SPRD_PIN_INFO(387, COMMON_PIN, 0, 0, 0),
+	SC9860_GPIO33 = SPRD_PIN_INFO(389, COMMON_PIN, 0, 0, 0),
+	SC9860_GPIO34 = SPRD_PIN_INFO(391, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL3 = SPRD_PIN_INFO(393, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL4 = SPRD_PIN_INFO(395, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL5 = SPRD_PIN_INFO(397, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL6 = SPRD_PIN_INFO(399, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL7 = SPRD_PIN_INFO(401, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL8 = SPRD_PIN_INFO(403, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL9 = SPRD_PIN_INFO(405, COMMON_PIN, 0, 0, 0),
+	SC9860_RFFE0_SCK0 = SPRD_PIN_INFO(407, COMMON_PIN, 0, 0, 0),
+	SC9860_GPIO38 = SPRD_PIN_INFO(409, COMMON_PIN, 0, 0, 0),
+	SC9860_RFFE0_SDA0 = SPRD_PIN_INFO(411, COMMON_PIN, 0, 0, 0),
+	SC9860_GPIO39 = SPRD_PIN_INFO(413, COMMON_PIN, 0, 0, 0),
+	SC9860_RFFE1_SCK0 = SPRD_PIN_INFO(415, COMMON_PIN, 0, 0, 0),
+	SC9860_GPIO181 = SPRD_PIN_INFO(417, COMMON_PIN, 0, 0, 0),
+	SC9860_RFFE1_SDA0 = SPRD_PIN_INFO(419, COMMON_PIN, 0, 0, 0),
+	SC9860_GPIO182 = SPRD_PIN_INFO(421, COMMON_PIN, 0, 0, 0),
+	SC9860_RF_LVDS0_ADC_ON = SPRD_PIN_INFO(423, COMMON_PIN, 0, 0, 0),
+	SC9860_RF_LVDS0_DAC_ON = SPRD_PIN_INFO(425, COMMON_PIN, 0, 0, 0),
+	SC9860_RFSCK0 = SPRD_PIN_INFO(427, COMMON_PIN, 0, 0, 0),
+	SC9860_RFSDA0 = SPRD_PIN_INFO(429, COMMON_PIN, 0, 0, 0),
+	SC9860_RFSEN0 = SPRD_PIN_INFO(431, COMMON_PIN, 0, 0, 0),
+	SC9860_RF_LVDS1_ADC_ON = SPRD_PIN_INFO(433, COMMON_PIN, 0, 0, 0),
+	SC9860_RF_LVDS1_DAC_ON = SPRD_PIN_INFO(435, COMMON_PIN, 0, 0, 0),
+	SC9860_RFSCK1 = SPRD_PIN_INFO(437, COMMON_PIN, 0, 0, 0),
+	SC9860_RFSDA1 = SPRD_PIN_INFO(439, COMMON_PIN, 0, 0, 0),
+	SC9860_RFSEN1 = SPRD_PIN_INFO(441, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL38 = SPRD_PIN_INFO(443, COMMON_PIN, 0, 0, 0),
+	SC9860_RFCTL39 = SPRD_PIN_INFO(445, COMMON_PIN, 0, 0, 0),
+
+	/* MSIC pin registers definitions */
+	SC9860_RFCTL20_MISC = SPRD_PIN_INFO(82, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL21_MISC = SPRD_PIN_INFO(84, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL30_MISC = SPRD_PIN_INFO(86, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL31_MISC = SPRD_PIN_INFO(88, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL32_MISC = SPRD_PIN_INFO(90, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL33_MISC = SPRD_PIN_INFO(92, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL34_MISC = SPRD_PIN_INFO(94, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL35_MISC = SPRD_PIN_INFO(96, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL36_MISC = SPRD_PIN_INFO(98, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL37_MISC = SPRD_PIN_INFO(100, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL22_MISC = SPRD_PIN_INFO(102, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL23_MISC = SPRD_PIN_INFO(104, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL24_MISC = SPRD_PIN_INFO(106, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL25_MISC = SPRD_PIN_INFO(108, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL26_MISC = SPRD_PIN_INFO(110, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL27_MISC = SPRD_PIN_INFO(112, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL28_MISC = SPRD_PIN_INFO(114, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL29_MISC = SPRD_PIN_INFO(116, MISC_PIN, 0, 0, 0),
+	SC9860_SCL2_MISC = SPRD_PIN_INFO(118, MISC_PIN, 0, 0, 0),
+	SC9860_SDA2_MISC = SPRD_PIN_INFO(120, MISC_PIN, 0, 0, 0),
+	SC9860_MTCK_ARM_MISC = SPRD_PIN_INFO(122, MISC_PIN, 0, 0, 0),
+	SC9860_MTMS_ARM_MISC = SPRD_PIN_INFO(124, MISC_PIN, 0, 0, 0),
+	SC9860_XTL_EN0_MISC = SPRD_PIN_INFO(126, MISC_PIN, 0, 0, 0),
+	SC9860_PTEST_MISC = SPRD_PIN_INFO(128, MISC_PIN, 0, 0, 0),
+	SC9860_AUD_DAD1_MISC = SPRD_PIN_INFO(130, MISC_PIN, 0, 0, 0),
+	SC9860_AUD_ADD0_MISC = SPRD_PIN_INFO(132, MISC_PIN, 0, 0, 0),
+	SC9860_AUD_ADSYNC_MISC = SPRD_PIN_INFO(134, MISC_PIN, 0, 0, 0),
+	SC9860_AUD_SCLK_MISC = SPRD_PIN_INFO(136, MISC_PIN, 0, 0, 0),
+	SC9860_CHIP_SLEEP_MISC = SPRD_PIN_INFO(138, MISC_PIN, 0, 0, 0),
+	SC9860_CLK_32K_MISC = SPRD_PIN_INFO(140, MISC_PIN, 0, 0, 0),
+	SC9860_DCDC_ARM_EN_MISC = SPRD_PIN_INFO(142, MISC_PIN, 0, 0, 0),
+	SC9860_EXT_RST_B_MISC = SPRD_PIN_INFO(144, MISC_PIN, 0, 0, 0),
+	SC9860_ADI_D_MISC = SPRD_PIN_INFO(146, MISC_PIN, 0, 0, 0),
+	SC9860_ADI_SCLK_MISC = SPRD_PIN_INFO(148, MISC_PIN, 0, 0, 0),
+	SC9860_XTL_EN1_MISC = SPRD_PIN_INFO(150, MISC_PIN, 0, 0, 0),
+	SC9860_ANA_INT_MISC = SPRD_PIN_INFO(152, MISC_PIN, 0, 0, 0),
+	SC9860_AUD_DAD0_MISC = SPRD_PIN_INFO(154, MISC_PIN, 0, 0, 0),
+	SC9860_AUD_DASYNC_MISC = SPRD_PIN_INFO(156, MISC_PIN, 0, 0, 0),
+	SC9860_LCM_RSTN_MISC = SPRD_PIN_INFO(158, MISC_PIN, 0, 0, 0),
+	SC9860_DSI_TE_MISC = SPRD_PIN_INFO(160, MISC_PIN, 0, 0, 0),
+	SC9860_PWMA_MISC = SPRD_PIN_INFO(162, MISC_PIN, 0, 0, 0),
+	SC9860_EXTINT0_MISC = SPRD_PIN_INFO(164, MISC_PIN, 0, 0, 0),
+	SC9860_EXTINT1_MISC = SPRD_PIN_INFO(166, MISC_PIN, 0, 0, 0),
+	SC9860_SDA1_MISC = SPRD_PIN_INFO(168, MISC_PIN, 0, 0, 0),
+	SC9860_SCL1_MISC = SPRD_PIN_INFO(170, MISC_PIN, 0, 0, 0),
+	SC9860_SIMCLK2_MISC = SPRD_PIN_INFO(172, MISC_PIN, 0, 0, 0),
+	SC9860_SIMDA2_MISC = SPRD_PIN_INFO(174, MISC_PIN, 0, 0, 0),
+	SC9860_SIMRST2_MISC = SPRD_PIN_INFO(176, MISC_PIN, 0, 0, 0),
+	SC9860_SIMCLK1_MISC = SPRD_PIN_INFO(178, MISC_PIN, 0, 0, 0),
+	SC9860_SIMDA1_MISC = SPRD_PIN_INFO(180, MISC_PIN, 0, 0, 0),
+	SC9860_SIMRST1_MISC = SPRD_PIN_INFO(182, MISC_PIN, 0, 0, 0),
+	SC9860_SIMCLK0_MISC = SPRD_PIN_INFO(184, MISC_PIN, 0, 0, 0),
+	SC9860_SIMDA0_MISC = SPRD_PIN_INFO(186, MISC_PIN, 0, 0, 0),
+	SC9860_SIMRST0_MISC = SPRD_PIN_INFO(188, MISC_PIN, 0, 0, 0),
+	SC9860_SD2_CMD_MISC = SPRD_PIN_INFO(190, MISC_PIN, 0, 0, 0),
+	SC9860_SD2_D0_MISC = SPRD_PIN_INFO(192, MISC_PIN, 0, 0, 0),
+	SC9860_SD2_D1_MISC = SPRD_PIN_INFO(194, MISC_PIN, 0, 0, 0),
+	SC9860_SD2_CLK_MISC = SPRD_PIN_INFO(196, MISC_PIN, 0, 0, 0),
+	SC9860_SD2_D2_MISC = SPRD_PIN_INFO(198, MISC_PIN, 0, 0, 0),
+	SC9860_SD2_D3_MISC = SPRD_PIN_INFO(200, MISC_PIN, 0, 0, 0),
+	SC9860_SD0_D3_MISC = SPRD_PIN_INFO(202, MISC_PIN, 0, 0, 0),
+	SC9860_SD0_D2_MISC = SPRD_PIN_INFO(204, MISC_PIN, 0, 0, 0),
+	SC9860_SD0_CMD_MISC = SPRD_PIN_INFO(206, MISC_PIN, 0, 0, 0),
+	SC9860_SD0_D0_MISC = SPRD_PIN_INFO(208, MISC_PIN, 0, 0, 0),
+	SC9860_SD0_D1_MISC = SPRD_PIN_INFO(210, MISC_PIN, 0, 0, 0),
+	SC9860_SD0_CLK_MISC = SPRD_PIN_INFO(212, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_CMD_reserved_MISC = SPRD_PIN_INFO(214, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_CMD_MISC = SPRD_PIN_INFO(216, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_D6_MISC = SPRD_PIN_INFO(218, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_D7_MISC = SPRD_PIN_INFO(220, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_CLK_MISC = SPRD_PIN_INFO(222, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_D5_MISC = SPRD_PIN_INFO(224, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_D4_MISC = SPRD_PIN_INFO(226, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_DS_MISC = SPRD_PIN_INFO(228, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_D3_reserved_MISC = SPRD_PIN_INFO(230, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_D3_MISC = SPRD_PIN_INFO(232, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_RST_MISC = SPRD_PIN_INFO(234, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_D1_MISC = SPRD_PIN_INFO(236, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_D2_MISC = SPRD_PIN_INFO(238, MISC_PIN, 0, 0, 0),
+	SC9860_EMMC_D0_MISC = SPRD_PIN_INFO(240, MISC_PIN, 0, 0, 0),
+	SC9860_IIS0DI_MISC = SPRD_PIN_INFO(242, MISC_PIN, 0, 0, 0),
+	SC9860_IIS0DO_MISC = SPRD_PIN_INFO(244, MISC_PIN, 0, 0, 0),
+	SC9860_IIS0CLK_MISC = SPRD_PIN_INFO(246, MISC_PIN, 0, 0, 0),
+	SC9860_IIS0LRCK_MISC = SPRD_PIN_INFO(248, MISC_PIN, 0, 0, 0),
+	SC9860_SD1_CLK_MISC = SPRD_PIN_INFO(250, MISC_PIN, 0, 0, 0),
+	SC9860_SD1_CMD_MISC = SPRD_PIN_INFO(252, MISC_PIN, 0, 0, 0),
+	SC9860_SD1_D0_MISC = SPRD_PIN_INFO(254, MISC_PIN, 0, 0, 0),
+	SC9860_SD1_D1_MISC = SPRD_PIN_INFO(256, MISC_PIN, 0, 0, 0),
+	SC9860_SD1_D2_MISC = SPRD_PIN_INFO(258, MISC_PIN, 0, 0, 0),
+	SC9860_SD1_D3_MISC = SPRD_PIN_INFO(260, MISC_PIN, 0, 0, 0),
+	SC9860_CLK_AUX0_MISC = SPRD_PIN_INFO(262, MISC_PIN, 0, 0, 0),
+	SC9860_WIFI_COEXIST_MISC = SPRD_PIN_INFO(264, MISC_PIN, 0, 0, 0),
+	SC9860_BEIDOU_COEXIST_MISC = SPRD_PIN_INFO(266, MISC_PIN, 0, 0, 0),
+	SC9860_U3TXD_MISC = SPRD_PIN_INFO(268, MISC_PIN, 0, 0, 0),
+	SC9860_U3RXD_MISC = SPRD_PIN_INFO(270, MISC_PIN, 0, 0, 0),
+	SC9860_U3CTS_MISC = SPRD_PIN_INFO(272, MISC_PIN, 0, 0, 0),
+	SC9860_U3RTS_MISC = SPRD_PIN_INFO(274, MISC_PIN, 0, 0, 0),
+	SC9860_U0TXD_MISC = SPRD_PIN_INFO(276, MISC_PIN, 0, 0, 0),
+	SC9860_U0RXD_MISC = SPRD_PIN_INFO(278, MISC_PIN, 0, 0, 0),
+	SC9860_U0CTS_MISC = SPRD_PIN_INFO(280, MISC_PIN, 0, 0, 0),
+	SC9860_U0RTS_MISC = SPRD_PIN_INFO(282, MISC_PIN, 0, 0, 0),
+	SC9860_IIS1DI_MISC = SPRD_PIN_INFO(284, MISC_PIN, 0, 0, 0),
+	SC9860_IIS1DO_MISC = SPRD_PIN_INFO(286, MISC_PIN, 0, 0, 0),
+	SC9860_IIS1CLK_MISC = SPRD_PIN_INFO(288, MISC_PIN, 0, 0, 0),
+	SC9860_IIS1LRCK_MISC = SPRD_PIN_INFO(290, MISC_PIN, 0, 0, 0),
+	SC9860_SPI0_CSN_MISC = SPRD_PIN_INFO(292, MISC_PIN, 0, 0, 0),
+	SC9860_SPI0_DO_MISC = SPRD_PIN_INFO(294, MISC_PIN, 0, 0, 0),
+	SC9860_SPI0_DI_MISC = SPRD_PIN_INFO(296, MISC_PIN, 0, 0, 0),
+	SC9860_SPI0_CLK_MISC = SPRD_PIN_INFO(298, MISC_PIN, 0, 0, 0),
+	SC9860_U2TXD_MISC = SPRD_PIN_INFO(300, MISC_PIN, 0, 0, 0),
+	SC9860_U2RXD_MISC = SPRD_PIN_INFO(302, MISC_PIN, 0, 0, 0),
+	SC9860_U4TXD_MISC = SPRD_PIN_INFO(304, MISC_PIN, 0, 0, 0),
+	SC9860_U4RXD_MISC = SPRD_PIN_INFO(306, MISC_PIN, 0, 0, 0),
+	SC9860_CMMCLK1_MISC = SPRD_PIN_INFO(308, MISC_PIN, 0, 0, 0),
+	SC9860_CMRST1_MISC = SPRD_PIN_INFO(310, MISC_PIN, 0, 0, 0),
+	SC9860_CMMCLK0_MISC = SPRD_PIN_INFO(312, MISC_PIN, 0, 0, 0),
+	SC9860_CMRST0_MISC = SPRD_PIN_INFO(314, MISC_PIN, 0, 0, 0),
+	SC9860_CMPD0_MISC = SPRD_PIN_INFO(316, MISC_PIN, 0, 0, 0),
+	SC9860_CMPD1_MISC = SPRD_PIN_INFO(318, MISC_PIN, 0, 0, 0),
+	SC9860_SCL0_MISC = SPRD_PIN_INFO(320, MISC_PIN, 0, 0, 0),
+	SC9860_SDA0_MISC = SPRD_PIN_INFO(322, MISC_PIN, 0, 0, 0),
+	SC9860_SDA6_MISC = SPRD_PIN_INFO(324, MISC_PIN, 0, 0, 0),
+	SC9860_SCL6_MISC = SPRD_PIN_INFO(326, MISC_PIN, 0, 0, 0),
+	SC9860_U1TXD_MISC = SPRD_PIN_INFO(328, MISC_PIN, 0, 0, 0),
+	SC9860_U1RXD_MISC = SPRD_PIN_INFO(330, MISC_PIN, 0, 0, 0),
+	SC9860_KEYOUT0_MISC = SPRD_PIN_INFO(332, MISC_PIN, 0, 0, 0),
+	SC9860_KEYOUT1_MISC = SPRD_PIN_INFO(334, MISC_PIN, 0, 0, 0),
+	SC9860_KEYOUT2_MISC = SPRD_PIN_INFO(336, MISC_PIN, 0, 0, 0),
+	SC9860_KEYIN0_MISC = SPRD_PIN_INFO(338, MISC_PIN, 0, 0, 0),
+	SC9860_KEYIN1_MISC = SPRD_PIN_INFO(340, MISC_PIN, 0, 0, 0),
+	SC9860_KEYIN2_MISC = SPRD_PIN_INFO(342, MISC_PIN, 0, 0, 0),
+	SC9860_IIS3DI_MISC = SPRD_PIN_INFO(344, MISC_PIN, 0, 0, 0),
+	SC9860_IIS3DO_MISC = SPRD_PIN_INFO(346, MISC_PIN, 0, 0, 0),
+	SC9860_IIS3CLK_MISC = SPRD_PIN_INFO(348, MISC_PIN, 0, 0, 0),
+	SC9860_IIS3LRCK_MISC = SPRD_PIN_INFO(350, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL0_MISC = SPRD_PIN_INFO(352, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL1_MISC = SPRD_PIN_INFO(354, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL10_MISC = SPRD_PIN_INFO(356, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL11_MISC = SPRD_PIN_INFO(358, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL12_MISC = SPRD_PIN_INFO(360, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL13_MISC = SPRD_PIN_INFO(362, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL14_MISC = SPRD_PIN_INFO(364, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL15_MISC = SPRD_PIN_INFO(366, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL16_MISC = SPRD_PIN_INFO(368, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL17_MISC = SPRD_PIN_INFO(370, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL18_MISC = SPRD_PIN_INFO(372, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL19_MISC = SPRD_PIN_INFO(374, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL2_MISC = SPRD_PIN_INFO(376, MISC_PIN, 0, 0, 0),
+	SC9860_EXTINT5_MISC = SPRD_PIN_INFO(378, MISC_PIN, 0, 0, 0),
+	SC9860_EXTINT6_MISC = SPRD_PIN_INFO(380, MISC_PIN, 0, 0, 0),
+	SC9860_EXTINT7_MISC = SPRD_PIN_INFO(382, MISC_PIN, 0, 0, 0),
+	SC9860_GPIO30_MISC = SPRD_PIN_INFO(384, MISC_PIN, 0, 0, 0),
+	SC9860_GPIO31_MISC = SPRD_PIN_INFO(386, MISC_PIN, 0, 0, 0),
+	SC9860_GPIO32_MISC = SPRD_PIN_INFO(388, MISC_PIN, 0, 0, 0),
+	SC9860_GPIO33_MISC = SPRD_PIN_INFO(390, MISC_PIN, 0, 0, 0),
+	SC9860_GPIO34_MISC = SPRD_PIN_INFO(392, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL3_MISC = SPRD_PIN_INFO(394, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL4_MISC = SPRD_PIN_INFO(396, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL5_MISC = SPRD_PIN_INFO(398, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL6_MISC = SPRD_PIN_INFO(400, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL7_MISC = SPRD_PIN_INFO(402, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL8_MISC = SPRD_PIN_INFO(404, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL9_MISC = SPRD_PIN_INFO(406, MISC_PIN, 0, 0, 0),
+	SC9860_RFFE0_SCK0_MISC = SPRD_PIN_INFO(408, MISC_PIN, 0, 0, 0),
+	SC9860_GPIO38_MISC = SPRD_PIN_INFO(410, MISC_PIN, 0, 0, 0),
+	SC9860_RFFE0_SDA0_MISC = SPRD_PIN_INFO(412, MISC_PIN, 0, 0, 0),
+	SC9860_GPIO39_MISC = SPRD_PIN_INFO(414, MISC_PIN, 0, 0, 0),
+	SC9860_RFFE1_SCK0_MISC = SPRD_PIN_INFO(416, MISC_PIN, 0, 0, 0),
+	SC9860_GPIO181_MISC = SPRD_PIN_INFO(418, MISC_PIN, 0, 0, 0),
+	SC9860_RFFE1_SDA0_MISC = SPRD_PIN_INFO(420, MISC_PIN, 0, 0, 0),
+	SC9860_GPIO182_MISC = SPRD_PIN_INFO(422, MISC_PIN, 0, 0, 0),
+	SC9860_RF_LVDS0_ADC_ON_MISC = SPRD_PIN_INFO(424, MISC_PIN, 0, 0, 0),
+	SC9860_RF_LVDS0_DAC_ON_MISC = SPRD_PIN_INFO(426, MISC_PIN, 0, 0, 0),
+	SC9860_RFSCK0_MISC = SPRD_PIN_INFO(428, MISC_PIN, 0, 0, 0),
+	SC9860_RFSDA0_MISC = SPRD_PIN_INFO(430, MISC_PIN, 0, 0, 0),
+	SC9860_RFSEN0_MISC = SPRD_PIN_INFO(432, MISC_PIN, 0, 0, 0),
+	SC9860_RF_LVDS1_ADC_ON_MISC = SPRD_PIN_INFO(434, MISC_PIN, 0, 0, 0),
+	SC9860_RF_LVDS1_DAC_ON_MISC = SPRD_PIN_INFO(436, MISC_PIN, 0, 0, 0),
+	SC9860_RFSCK1_MISC = SPRD_PIN_INFO(438, MISC_PIN, 0, 0, 0),
+	SC9860_RFSDA1_MISC = SPRD_PIN_INFO(440, MISC_PIN, 0, 0, 0),
+	SC9860_RFSEN1_MISC = SPRD_PIN_INFO(442, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL38_MISC = SPRD_PIN_INFO(444, MISC_PIN, 0, 0, 0),
+	SC9860_RFCTL39_MISC = SPRD_PIN_INFO(446, MISC_PIN, 0, 0, 0),
+};
+
+static struct sprd_pins_info sprd_sc9860_pins_info[] = {
+	SPRD_PINCTRL_PIN(SC9860_VIO28_0_IRTE),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SD2_IRTE),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SD0_IRTE),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SIM2_IRTE),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SIM1_IRTE),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SIM0_IRTE),
+	SPRD_PINCTRL_PIN(SC9860_VIO28_0_MS),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SD2_MS),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SD0_MS),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SIM2_MS),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SIM1_MS),
+	SPRD_PINCTRL_PIN(SC9860_VIO_SIM0_MS),
+	SPRD_PINCTRL_PIN(SC9860_SPSPI_PIN_IN_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART1_USB30_PHY_SEL),
+	SPRD_PINCTRL_PIN(SC9860_USB30_PHY_DM_OE),
+	SPRD_PINCTRL_PIN(SC9860_USB30_PHY_DP_OE),
+	SPRD_PINCTRL_PIN(SC9860_UART5_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_ORP_URXD_PIN_IN_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SIM2_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SIM1_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SIM0_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_CLK26MHZ_BUF_OUT_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART4_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART3_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART2_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART1_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART0_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART24_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART23_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART14_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_UART13_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS3_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS2_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS1_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS0_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS23_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS13_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS12_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS03_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS02_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS01_LOOP_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS6_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS5_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_IIS4_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_I2C_INF6_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_I2C_INF4_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_I2C_INF2_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_I2C_INF1_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_I2C_INF0_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_GPIO_INF7_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_GPIO_INF6_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_GPIO_INF5_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_GPIO_INF4_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_GPIO_INF3_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_GPIO_INF2_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_GPIO_INF1_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_GPIO_INF0_SYS_SEL),
+	SPRD_PINCTRL_PIN(SC9860_WDRST_OUT_SEL),
+	SPRD_PINCTRL_PIN(SC9860_ADI_SYNC_PIN_OUT_SEL),
+	SPRD_PINCTRL_PIN(SC9860_CMRST_SEL),
+	SPRD_PINCTRL_PIN(SC9860_CMPD_SEL),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE11),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE10),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE9),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE8),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE7),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE6),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE5),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE4),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE3),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE2),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE1),
+	SPRD_PINCTRL_PIN(SC9860_TEST_DBG_MODE0),
+	SPRD_PINCTRL_PIN(SC9860_SP_EIC_DPAD3_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SP_EIC_DPAD2_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SP_EIC_DPAD1_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SP_EIC_DPAD0_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SP_EIC_DPAD7_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SP_EIC_DPAD6_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SP_EIC_DPAD5_SEL),
+	SPRD_PINCTRL_PIN(SC9860_SP_EIC_DPAD4_SEL),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL20),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL21),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL30),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL31),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL32),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL33),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL34),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL35),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL36),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL37),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL22),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL23),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL24),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL25),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL26),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL27),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL28),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL29),
+	SPRD_PINCTRL_PIN(SC9860_SCL2),
+	SPRD_PINCTRL_PIN(SC9860_SDA2),
+	SPRD_PINCTRL_PIN(SC9860_MTCK_ARM),
+	SPRD_PINCTRL_PIN(SC9860_MTMS_ARM),
+	SPRD_PINCTRL_PIN(SC9860_XTL_EN0),
+	SPRD_PINCTRL_PIN(SC9860_PTEST),
+	SPRD_PINCTRL_PIN(SC9860_AUD_DAD1),
+	SPRD_PINCTRL_PIN(SC9860_AUD_ADD0),
+	SPRD_PINCTRL_PIN(SC9860_AUD_ADSYNC),
+	SPRD_PINCTRL_PIN(SC9860_AUD_SCLK),
+	SPRD_PINCTRL_PIN(SC9860_CHIP_SLEEP),
+	SPRD_PINCTRL_PIN(SC9860_CLK_32K),
+	SPRD_PINCTRL_PIN(SC9860_DCDC_ARM_EN),
+	SPRD_PINCTRL_PIN(SC9860_EXT_RST_B),
+	SPRD_PINCTRL_PIN(SC9860_ADI_D),
+	SPRD_PINCTRL_PIN(SC9860_ADI_SCLK),
+	SPRD_PINCTRL_PIN(SC9860_XTL_EN1),
+	SPRD_PINCTRL_PIN(SC9860_ANA_INT),
+	SPRD_PINCTRL_PIN(SC9860_AUD_DAD0),
+	SPRD_PINCTRL_PIN(SC9860_AUD_DASYNC),
+	SPRD_PINCTRL_PIN(SC9860_LCM_RSTN),
+	SPRD_PINCTRL_PIN(SC9860_DSI_TE),
+	SPRD_PINCTRL_PIN(SC9860_PWMA),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT0),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT1),
+	SPRD_PINCTRL_PIN(SC9860_SDA1),
+	SPRD_PINCTRL_PIN(SC9860_SCL1),
+	SPRD_PINCTRL_PIN(SC9860_SIMCLK2),
+	SPRD_PINCTRL_PIN(SC9860_SIMDA2),
+	SPRD_PINCTRL_PIN(SC9860_SIMRST2),
+	SPRD_PINCTRL_PIN(SC9860_SIMCLK1),
+	SPRD_PINCTRL_PIN(SC9860_SIMDA1),
+	SPRD_PINCTRL_PIN(SC9860_SIMRST1),
+	SPRD_PINCTRL_PIN(SC9860_SIMCLK0),
+	SPRD_PINCTRL_PIN(SC9860_SIMDA0),
+	SPRD_PINCTRL_PIN(SC9860_SIMRST0),
+	SPRD_PINCTRL_PIN(SC9860_SD2_CMD),
+	SPRD_PINCTRL_PIN(SC9860_SD2_D0),
+	SPRD_PINCTRL_PIN(SC9860_SD2_D1),
+	SPRD_PINCTRL_PIN(SC9860_SD2_CLK),
+	SPRD_PINCTRL_PIN(SC9860_SD2_D2),
+	SPRD_PINCTRL_PIN(SC9860_SD2_D3),
+	SPRD_PINCTRL_PIN(SC9860_SD0_D3),
+	SPRD_PINCTRL_PIN(SC9860_SD0_D2),
+	SPRD_PINCTRL_PIN(SC9860_SD0_CMD),
+	SPRD_PINCTRL_PIN(SC9860_SD0_D0),
+	SPRD_PINCTRL_PIN(SC9860_SD0_D1),
+	SPRD_PINCTRL_PIN(SC9860_SD0_CLK),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_CMD),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D6),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D7),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_CLK),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D5),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D4),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_DS),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D3),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_RST),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D1),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D2),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D0),
+	SPRD_PINCTRL_PIN(SC9860_IIS0DI),
+	SPRD_PINCTRL_PIN(SC9860_IIS0DO),
+	SPRD_PINCTRL_PIN(SC9860_IIS0CLK),
+	SPRD_PINCTRL_PIN(SC9860_IIS0LRCK),
+	SPRD_PINCTRL_PIN(SC9860_SD1_CLK),
+	SPRD_PINCTRL_PIN(SC9860_SD1_CMD),
+	SPRD_PINCTRL_PIN(SC9860_SD1_D0),
+	SPRD_PINCTRL_PIN(SC9860_SD1_D1),
+	SPRD_PINCTRL_PIN(SC9860_SD1_D2),
+	SPRD_PINCTRL_PIN(SC9860_SD1_D3),
+	SPRD_PINCTRL_PIN(SC9860_CLK_AUX0),
+	SPRD_PINCTRL_PIN(SC9860_WIFI_COEXIST),
+	SPRD_PINCTRL_PIN(SC9860_BEIDOU_COEXIST),
+	SPRD_PINCTRL_PIN(SC9860_U3TXD),
+	SPRD_PINCTRL_PIN(SC9860_U3RXD),
+	SPRD_PINCTRL_PIN(SC9860_U3CTS),
+	SPRD_PINCTRL_PIN(SC9860_U3RTS),
+	SPRD_PINCTRL_PIN(SC9860_U0TXD),
+	SPRD_PINCTRL_PIN(SC9860_U0RXD),
+	SPRD_PINCTRL_PIN(SC9860_U0CTS),
+	SPRD_PINCTRL_PIN(SC9860_U0RTS),
+	SPRD_PINCTRL_PIN(SC9860_IIS1DI),
+	SPRD_PINCTRL_PIN(SC9860_IIS1DO),
+	SPRD_PINCTRL_PIN(SC9860_IIS1CLK),
+	SPRD_PINCTRL_PIN(SC9860_IIS1LRCK),
+	SPRD_PINCTRL_PIN(SC9860_SPI0_CSN),
+	SPRD_PINCTRL_PIN(SC9860_SPI0_DO),
+	SPRD_PINCTRL_PIN(SC9860_SPI0_DI),
+	SPRD_PINCTRL_PIN(SC9860_SPI0_CLK),
+	SPRD_PINCTRL_PIN(SC9860_U2TXD),
+	SPRD_PINCTRL_PIN(SC9860_U2RXD),
+	SPRD_PINCTRL_PIN(SC9860_U4TXD),
+	SPRD_PINCTRL_PIN(SC9860_U4RXD),
+	SPRD_PINCTRL_PIN(SC9860_CMMCLK1),
+	SPRD_PINCTRL_PIN(SC9860_CMRST1),
+	SPRD_PINCTRL_PIN(SC9860_CMMCLK0),
+	SPRD_PINCTRL_PIN(SC9860_CMRST0),
+	SPRD_PINCTRL_PIN(SC9860_CMPD0),
+	SPRD_PINCTRL_PIN(SC9860_CMPD1),
+	SPRD_PINCTRL_PIN(SC9860_SCL0),
+	SPRD_PINCTRL_PIN(SC9860_SDA0),
+	SPRD_PINCTRL_PIN(SC9860_SDA6),
+	SPRD_PINCTRL_PIN(SC9860_SCL6),
+	SPRD_PINCTRL_PIN(SC9860_U1TXD),
+	SPRD_PINCTRL_PIN(SC9860_U1RXD),
+	SPRD_PINCTRL_PIN(SC9860_KEYOUT0),
+	SPRD_PINCTRL_PIN(SC9860_KEYOUT1),
+	SPRD_PINCTRL_PIN(SC9860_KEYOUT2),
+	SPRD_PINCTRL_PIN(SC9860_KEYIN0),
+	SPRD_PINCTRL_PIN(SC9860_KEYIN1),
+	SPRD_PINCTRL_PIN(SC9860_KEYIN2),
+	SPRD_PINCTRL_PIN(SC9860_IIS3DI),
+	SPRD_PINCTRL_PIN(SC9860_IIS3DO),
+	SPRD_PINCTRL_PIN(SC9860_IIS3CLK),
+	SPRD_PINCTRL_PIN(SC9860_IIS3LRCK),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL0),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL1),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL10),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL11),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL12),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL13),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL14),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL15),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL16),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL17),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL18),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL19),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL2),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT5),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT6),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT7),
+	SPRD_PINCTRL_PIN(SC9860_GPIO30),
+	SPRD_PINCTRL_PIN(SC9860_GPIO31),
+	SPRD_PINCTRL_PIN(SC9860_GPIO32),
+	SPRD_PINCTRL_PIN(SC9860_GPIO33),
+	SPRD_PINCTRL_PIN(SC9860_GPIO34),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL3),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL4),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL5),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL6),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL7),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL8),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL9),
+	SPRD_PINCTRL_PIN(SC9860_RFFE0_SCK0),
+	SPRD_PINCTRL_PIN(SC9860_GPIO38),
+	SPRD_PINCTRL_PIN(SC9860_RFFE0_SDA0),
+	SPRD_PINCTRL_PIN(SC9860_GPIO39),
+	SPRD_PINCTRL_PIN(SC9860_RFFE1_SCK0),
+	SPRD_PINCTRL_PIN(SC9860_GPIO181),
+	SPRD_PINCTRL_PIN(SC9860_RFFE1_SDA0),
+	SPRD_PINCTRL_PIN(SC9860_GPIO182),
+	SPRD_PINCTRL_PIN(SC9860_RF_LVDS0_ADC_ON),
+	SPRD_PINCTRL_PIN(SC9860_RF_LVDS0_DAC_ON),
+	SPRD_PINCTRL_PIN(SC9860_RFSCK0),
+	SPRD_PINCTRL_PIN(SC9860_RFSDA0),
+	SPRD_PINCTRL_PIN(SC9860_RFSEN0),
+	SPRD_PINCTRL_PIN(SC9860_RF_LVDS1_ADC_ON),
+	SPRD_PINCTRL_PIN(SC9860_RF_LVDS1_DAC_ON),
+	SPRD_PINCTRL_PIN(SC9860_RFSCK1),
+	SPRD_PINCTRL_PIN(SC9860_RFSDA1),
+	SPRD_PINCTRL_PIN(SC9860_RFSEN1),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL38),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL39),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL20_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL21_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL30_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL31_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL32_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL33_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL34_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL35_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL36_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL37_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL22_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL23_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL24_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL25_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL26_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL27_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL28_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL29_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SCL2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SDA2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_MTCK_ARM_MISC),
+	SPRD_PINCTRL_PIN(SC9860_MTMS_ARM_MISC),
+	SPRD_PINCTRL_PIN(SC9860_XTL_EN0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_PTEST_MISC),
+	SPRD_PINCTRL_PIN(SC9860_AUD_DAD1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_AUD_ADD0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_AUD_ADSYNC_MISC),
+	SPRD_PINCTRL_PIN(SC9860_AUD_SCLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_CHIP_SLEEP_MISC),
+	SPRD_PINCTRL_PIN(SC9860_CLK_32K_MISC),
+	SPRD_PINCTRL_PIN(SC9860_DCDC_ARM_EN_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EXT_RST_B_MISC),
+	SPRD_PINCTRL_PIN(SC9860_ADI_D_MISC),
+	SPRD_PINCTRL_PIN(SC9860_ADI_SCLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_XTL_EN1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_ANA_INT_MISC),
+	SPRD_PINCTRL_PIN(SC9860_AUD_DAD0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_AUD_DASYNC_MISC),
+	SPRD_PINCTRL_PIN(SC9860_LCM_RSTN_MISC),
+	SPRD_PINCTRL_PIN(SC9860_DSI_TE_MISC),
+	SPRD_PINCTRL_PIN(SC9860_PWMA_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SDA1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SCL1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SIMCLK2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SIMDA2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SIMRST2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SIMCLK1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SIMDA1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SIMRST1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SIMCLK0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SIMDA0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SIMRST0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD2_CMD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD2_D0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD2_D1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD2_CLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD2_D2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD2_D3_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD0_D3_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD0_D2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD0_CMD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD0_D0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD0_D1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD0_CLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_CMD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D6_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D7_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_CLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D5_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D4_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_DS_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D3_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_RST_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EMMC_D0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS0DI_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS0DO_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS0CLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS0LRCK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD1_CLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD1_CMD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD1_D0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD1_D1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD1_D2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SD1_D3_MISC),
+	SPRD_PINCTRL_PIN(SC9860_CLK_AUX0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_WIFI_COEXIST_MISC),
+	SPRD_PINCTRL_PIN(SC9860_BEIDOU_COEXIST_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U3TXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U3RXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U3CTS_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U3RTS_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U0TXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U0RXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U0CTS_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U0RTS_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS1DI_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS1DO_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS1CLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS1LRCK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SPI0_CSN_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SPI0_DO_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SPI0_DI_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SPI0_CLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U2TXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U2RXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U4TXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U4RXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_CMMCLK1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_CMRST1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_CMMCLK0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_CMRST0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_CMPD0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_CMPD1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SCL0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SDA0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SDA6_MISC),
+	SPRD_PINCTRL_PIN(SC9860_SCL6_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U1TXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_U1RXD_MISC),
+	SPRD_PINCTRL_PIN(SC9860_KEYOUT0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_KEYOUT1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_KEYOUT2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_KEYIN0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_KEYIN1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_KEYIN2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS3DI_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS3DO_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS3CLK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_IIS3LRCK_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL10_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL11_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL12_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL13_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL14_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL15_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL16_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL17_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL18_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL19_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL2_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT5_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT6_MISC),
+	SPRD_PINCTRL_PIN(SC9860_EXTINT7_MISC),
+	SPRD_PINCTRL_PIN(SC9860_GPIO30_MISC),
+	SPRD_PINCTRL_PIN(SC9860_GPIO31_MISC),
+	SPRD_PINCTRL_PIN(SC9860_GPIO32_MISC),
+	SPRD_PINCTRL_PIN(SC9860_GPIO33_MISC),
+	SPRD_PINCTRL_PIN(SC9860_GPIO34_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL3_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL4_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL5_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL6_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL7_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL8_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL9_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFFE0_SCK0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_GPIO38_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFFE0_SDA0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_GPIO39_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFFE1_SCK0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_GPIO181_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFFE1_SDA0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_GPIO182_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RF_LVDS0_ADC_ON_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RF_LVDS0_DAC_ON_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFSCK0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFSDA0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFSEN0_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RF_LVDS1_ADC_ON_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RF_LVDS1_DAC_ON_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFSCK1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFSDA1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFSEN1_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL38_MISC),
+	SPRD_PINCTRL_PIN(SC9860_RFCTL39_MISC),
+};
+
+static int sprd_pinctrl_probe(struct platform_device *pdev)
+{
+	return sprd_pinctrl_core_probe(pdev, sprd_sc9860_pins_info,
+				       ARRAY_SIZE(sprd_sc9860_pins_info));
+}
+
+static const struct of_device_id sprd_pinctrl_of_match[] = {
+	{
+		.compatible = "sprd,sc9860-pinctrl",
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, sprd_pinctrl_of_match);
+
+static struct platform_driver sprd_pinctrl_driver = {
+	.driver = {
+		.name = "sprd-pinctrl",
+		.owner = THIS_MODULE,
+		.of_match_table = sprd_pinctrl_of_match,
+	},
+	.probe = sprd_pinctrl_probe,
+	.remove = sprd_pinctrl_remove,
+	.shutdown = sprd_pinctrl_shutdown,
+};
+
+static int sprd_pinctrl_init(void)
+{
+	return platform_driver_register(&sprd_pinctrl_driver);
+}
+module_init(sprd_pinctrl_init);
+
+static void sprd_pinctrl_exit(void)
+{
+	platform_driver_unregister(&sprd_pinctrl_driver);
+}
+module_exit(sprd_pinctrl_exit);
+
+MODULE_DESCRIPTION("SPREADTRUM Pin Controller Driver");
+MODULE_AUTHOR("Baolin Wang <baolin.wang@spreadtrum.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/sprd/pinctrl-sprd.c b/drivers/pinctrl/sprd/pinctrl-sprd.c
new file mode 100644
index 0000000..bf4f358
--- /dev/null
+++ b/drivers/pinctrl/sprd/pinctrl-sprd.c
@@ -0,0 +1,912 @@
+/*
+ * Spreadtrum pin controller driver
+ * Copyright (C) 2017 Spreadtrum  - http://www.spreadtrum.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/debugfs.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/slab.h>
+
+#include "../core.h"
+#include "../pinmux.h"
+#include "../pinconf.h"
+#include "../pinctrl-utils.h"
+#include "pinctrl-sprd.h"
+
+#define PINCTRL_BIT_MASK(width)		(~(~0UL << (width)))
+#define PINCTRL_REG_OFFSET		0x20
+#define PINCTRL_REG_MISC_OFFSET		0x4020
+
+/**
+ * struct sprd_pin: represent one pin's description
+ * @name: pin name
+ * @number: pin number
+ * @type: pin type, can be GLOBAL_CTRL_PIN/COMMON_PIN/MISC_PIN
+ * @reg: pin register address
+ * @bit_offset: bit offset in pin register
+ * @bit_width: bit width in pin register
+ */
+struct sprd_pin {
+	const char *name;
+	unsigned int number;
+	enum pin_type type;
+	unsigned long reg;
+	unsigned long bit_offset;
+	unsigned long bit_width;
+};
+
+/**
+ * struct sprd_pin_group: represent one group's description
+ * @name: group name
+ * @npins: pin numbers of this group
+ * @pins: pointer to pins array
+ */
+struct sprd_pin_group {
+	const char *name;
+	unsigned int npins;
+	unsigned int *pins;
+};
+
+/**
+ * struct sprd_pinctrl_soc_info: represent the SoC's pins description
+ * @groups: pointer to groups of pins
+ * @ngroups: group numbers of the whole SoC
+ * @pins: pointer to pins description
+ * @npins: pin numbers of the whole SoC
+ * @grp_names: pointer to group names array
+ */
+struct sprd_pinctrl_soc_info {
+	struct sprd_pin_group *groups;
+	unsigned int ngroups;
+	struct sprd_pin *pins;
+	unsigned int npins;
+	const char **grp_names;
+};
+
+/**
+ * struct sprd_pinctrl: represent the pin controller device
+ * @dev: pointer to the device structure
+ * @pctl: pointer to the pinctrl handle
+ * @base: base address of the controller
+ * @info: pointer to SoC's pins description information
+ */
+struct sprd_pinctrl {
+	struct device *dev;
+	struct pinctrl_dev *pctl;
+	void __iomem *base;
+	struct sprd_pinctrl_soc_info *info;
+};
+
+static int sprd_pinctrl_get_id_by_name(struct sprd_pinctrl *sprd_pctl,
+				       const char *name)
+{
+	struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
+	int i;
+
+	for (i = 0; i < info->npins; i++) {
+		if (!strcmp(info->pins[i].name, name))
+			return info->pins[i].number;
+	}
+
+	return -ENODEV;
+}
+
+static struct sprd_pin *
+sprd_pinctrl_get_pin_by_id(struct sprd_pinctrl *sprd_pctl, unsigned int id)
+{
+	struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
+	struct sprd_pin *pin = NULL;
+	int i;
+
+	for (i = 0; i < info->npins; i++) {
+		if (info->pins[i].number == id) {
+			pin = &info->pins[i];
+			break;
+		}
+	}
+
+	return pin;
+}
+
+static const struct sprd_pin_group *
+sprd_pinctrl_find_group_by_name(struct sprd_pinctrl *sprd_pctl,
+				const char *name)
+{
+	struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
+	const struct sprd_pin_group *grp = NULL;
+	int i;
+
+	for (i = 0; i < info->ngroups; i++) {
+		if (!strcmp(info->groups[i].name, name)) {
+			grp = &info->groups[i];
+			break;
+		}
+	}
+
+	return grp;
+}
+
+static int sprd_pctrl_group_count(struct pinctrl_dev *pctldev)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pinctrl_soc_info *info = pctl->info;
+
+	return info->ngroups;
+}
+
+static const char *sprd_pctrl_group_name(struct pinctrl_dev *pctldev,
+					 unsigned int selector)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pinctrl_soc_info *info = pctl->info;
+
+	return info->groups[selector].name;
+}
+
+static int sprd_pctrl_group_pins(struct pinctrl_dev *pctldev,
+				 unsigned int selector,
+				 const unsigned int **pins,
+				 unsigned int *npins)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pinctrl_soc_info *info = pctl->info;
+
+	if (selector >= info->ngroups)
+		return -EINVAL;
+
+	*pins = info->groups[selector].pins;
+	*npins = info->groups[selector].npins;
+
+	return 0;
+}
+
+static int sprd_dt_node_to_map(struct pinctrl_dev *pctldev,
+			       struct device_node *np,
+			       struct pinctrl_map **map,
+			       unsigned int *num_maps)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	const struct sprd_pin_group *grp;
+	unsigned long *configs = NULL;
+	unsigned int num_configs = 0;
+	unsigned int reserved_maps = 0;
+	unsigned int reserve = 0;
+	const char *function;
+	enum pinctrl_map_type type;
+	int ret;
+
+	grp = sprd_pinctrl_find_group_by_name(pctl, np->name);
+	if (!grp) {
+		dev_err(pctl->dev, "unable to find group for node %s\n",
+			of_node_full_name(np));
+		return -EINVAL;
+	}
+
+	ret = of_property_count_strings(np, "pins");
+	if (ret < 0)
+		return ret;
+
+	if (ret == 1)
+		type = PIN_MAP_TYPE_CONFIGS_PIN;
+	else
+		type = PIN_MAP_TYPE_CONFIGS_GROUP;
+
+	ret = of_property_read_string(np, "function", &function);
+	if (ret < 0) {
+		if (ret != -EINVAL)
+			dev_err(pctl->dev,
+				"%s: could not parse property function\n",
+				of_node_full_name(np));
+		function = NULL;
+	}
+
+	ret = pinconf_generic_parse_dt_config(np, pctldev, &configs,
+					      &num_configs);
+	if (ret < 0) {
+		dev_err(pctl->dev, "%s: could not parse node property\n",
+			of_node_full_name(np));
+		return ret;
+	}
+
+	*map = NULL;
+	*num_maps = 0;
+
+	if (function != NULL)
+		reserve++;
+	if (num_configs)
+		reserve++;
+
+	ret = pinctrl_utils_reserve_map(pctldev, map, &reserved_maps,
+					num_maps, reserve);
+	if (ret < 0)
+		goto out;
+
+	if (function) {
+		ret = pinctrl_utils_add_map_mux(pctldev, map,
+						&reserved_maps, num_maps,
+						grp->name, function);
+		if (ret < 0)
+			goto out;
+	}
+
+	if (num_configs) {
+		const char *group_or_pin;
+		unsigned int pin_id;
+
+		if (type == PIN_MAP_TYPE_CONFIGS_PIN) {
+			pin_id = grp->pins[0];
+			group_or_pin = pin_get_name(pctldev, pin_id);
+		} else {
+			group_or_pin = grp->name;
+		}
+
+		ret = pinctrl_utils_add_map_configs(pctldev, map,
+						    &reserved_maps, num_maps,
+						    group_or_pin, configs,
+						    num_configs, type);
+	}
+
+out:
+	kfree(configs);
+	return ret;
+}
+
+static void sprd_pctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+				unsigned int offset)
+{
+	seq_printf(s, "%s", dev_name(pctldev->dev));
+}
+
+static const struct pinctrl_ops sprd_pctrl_ops = {
+	.get_groups_count = sprd_pctrl_group_count,
+	.get_group_name = sprd_pctrl_group_name,
+	.get_group_pins = sprd_pctrl_group_pins,
+	.pin_dbg_show = sprd_pctrl_dbg_show,
+	.dt_node_to_map = sprd_dt_node_to_map,
+	.dt_free_map = pinctrl_utils_free_map,
+};
+
+int sprd_pmx_get_function_count(struct pinctrl_dev *pctldev)
+{
+	return PIN_FUNC_MAX;
+}
+
+const char *sprd_pmx_get_function_name(struct pinctrl_dev *pctldev,
+				       unsigned int selector)
+{
+	switch (selector) {
+	case PIN_FUNC_1:
+		return "func1";
+	case PIN_FUNC_2:
+		return "func2";
+	case PIN_FUNC_3:
+		return "func3";
+	case PIN_FUNC_4:
+		return "func4";
+	default:
+		return "null";
+	}
+}
+
+int sprd_pmx_get_function_groups(struct pinctrl_dev *pctldev,
+				 unsigned int selector,
+				 const char * const **groups,
+				 unsigned int * const num_groups)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pinctrl_soc_info *info = pctl->info;
+
+	*groups = info->grp_names;
+	*num_groups = info->ngroups;
+
+	return 0;
+}
+
+static int sprd_pmx_set_mux(struct pinctrl_dev *pctldev,
+			    unsigned int func_selector,
+			    unsigned int group_selector)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pinctrl_soc_info *info = pctl->info;
+	struct sprd_pin_group *grp = &info->groups[group_selector];
+	unsigned int i, grp_pins = grp->npins;
+	unsigned long reg;
+	u32 val = 0;
+
+	if (group_selector > info->ngroups)
+		return -EINVAL;
+
+	switch (func_selector) {
+	case PIN_FUNC_1:
+		val &= ~(BIT(4) | BIT(5));
+		break;
+	case PIN_FUNC_2:
+		val |= BIT(4);
+		break;
+	case PIN_FUNC_3:
+		val |= BIT(5);
+		break;
+	case PIN_FUNC_4:
+		val |= BIT(4) | BIT(5);
+		break;
+	default:
+		break;
+	}
+
+	for (i = 0; i < grp_pins; i++) {
+		unsigned int pin_id = grp->pins[i];
+		struct sprd_pin *pin = sprd_pinctrl_get_pin_by_id(pctl, pin_id);
+
+		if (!pin || pin->type != COMMON_PIN)
+			continue;
+
+		reg = readl((void __iomem *)pin->reg);
+		reg &= ~(BIT(4) | BIT(5));
+		reg |= val;
+		writel(reg, (void __iomem *)pin->reg);
+	}
+
+	return 0;
+}
+
+static const struct pinmux_ops sprd_pmx_ops = {
+	.get_functions_count = sprd_pmx_get_function_count,
+	.get_function_name = sprd_pmx_get_function_name,
+	.get_function_groups = sprd_pmx_get_function_groups,
+	.set_mux = sprd_pmx_set_mux,
+};
+
+static int sprd_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin_id,
+			    unsigned long *config)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pin *pin = sprd_pinctrl_get_pin_by_id(pctl, pin_id);
+
+	if (!pin)
+		return -EINVAL;
+
+	if (pin->type == GLOBAL_CTRL_PIN) {
+		*config = (readl((void __iomem *)pin->reg) >>
+			   pin->bit_offset) & PINCTRL_BIT_MASK(pin->bit_width);
+	} else {
+		*config = readl((void __iomem *)pin->reg);
+	}
+
+	return 0;
+}
+
+static unsigned int sprd_pinconf_drive(unsigned int arg)
+{
+	u32 val = 0;
+
+	switch (arg) {
+	case 2:
+		break;
+	case 4:
+		val |= BIT(19);
+		break;
+	case 6:
+		val |= BIT(20);
+		break;
+	case 8:
+		val |= BIT(19) | BIT(20);
+		break;
+	case 10:
+		val |= BIT(21);
+		break;
+	case 12:
+		val |= BIT(21) | BIT(19);
+		break;
+	case 14:
+		val |= BIT(21) | BIT(20);
+		break;
+	case 16:
+		val |= BIT(19) | BIT(20) | BIT(21);
+		break;
+	case 20:
+		val |= BIT(22);
+		break;
+	case 21:
+		val |= BIT(22) | BIT(19);
+		break;
+	case 24:
+		val |= BIT(22) | BIT(20);
+		break;
+	case 25:
+		val |= BIT(22) | BIT(20) | BIT(19);
+		break;
+	case 27:
+		val |= BIT(22) | BIT(21);
+		break;
+	case 29:
+		val |= BIT(22) | BIT(21) | BIT(19);
+		break;
+	case 31:
+		val |= BIT(22) | BIT(21) | BIT(20);
+		break;
+	case 33:
+		val |= BIT(22) | BIT(21) | BIT(20) | BIT(19);
+		break;
+	default:
+		break;
+	}
+
+	return val;
+}
+
+static int sprd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin_id,
+			    unsigned long *configs, unsigned int num_configs)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pin *pin = sprd_pinctrl_get_pin_by_id(pctl, pin_id);
+	unsigned long reg;
+	int i;
+
+	if (!pin)
+		return -EINVAL;
+
+	for (i = 0; i < num_configs; i++) {
+		enum pin_config_param param;
+		u32 shift, mask, arg, val;
+
+		param = pinconf_to_config_param(configs[i]);
+		arg = pinconf_to_config_argument(configs[i]);
+
+		val = 0;
+		shift = 0;
+		mask = 0;
+		if (pin->type == GLOBAL_CTRL_PIN &&
+		    param == SPRD_PIN_CONFIG_CONTROL) {
+			val = arg;
+		} else if (pin->type == COMMON_PIN) {
+			switch (param) {
+			case SPRD_PIN_CONFIG_SLEEP_MODE:
+				if (arg & AP_SLEEP)
+					val |= BIT(13);
+				if (arg & PUBCP_SLEEP)
+					val |= BIT(14);
+				if (arg & TGLDSP_SLEEP)
+					val |= BIT(15);
+				if (arg & AGDSP_SLEEP)
+					val |= BIT(16);
+
+				mask = 0xf;
+				shift = 13;
+				break;
+			case SPRD_PIN_CONFIG_INPUT_SLEEP:
+				val |= BIT(1);
+				mask = 0x1;
+				shift = 1;
+				break;
+			case SPRD_PIN_CONFIG_OUTPUT_SLEEP:
+				val |= BIT(0);
+				mask = 0x1;
+				shift = 0;
+				break;
+			default:
+				return -ENOTSUPP;
+			}
+		} else if (pin->type == MISC_PIN) {
+			switch (param) {
+			case PIN_CONFIG_DRIVE_STRENGTH:
+				if (arg < 2 || arg > 60)
+					return -EINVAL;
+
+				val = sprd_pinconf_drive(arg);
+				mask = 0xf;
+				shift = 19;
+				break;
+			case PIN_CONFIG_BIAS_PULL_DOWN:
+				val |= BIT(6);
+				mask = 0x1;
+				shift = 6;
+				break;
+			case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+				if (arg > 0)
+					val |= BIT(11);
+				else
+					val &= ~BIT(11);
+
+				mask = 0x1;
+				shift = 11;
+				break;
+			case SPRD_PIN_CONFIG_PULLUP:
+				if (arg == PULLUP_20K)
+					val |= BIT(12) | BIT(7);
+				else if (arg == PULLUP_4_7K)
+					val |= BIT(12);
+
+				mask = 0x21;
+				shift = 7;
+				break;
+			case SPRD_PIN_CONFIG_PULLUP_SLEEP:
+				val |= BIT(3);
+				mask = 0x1;
+				shift = 3;
+				break;
+			case SPRD_PIN_CONFIG_PULLDOWN_SLEEP:
+				val |= BIT(2);
+				mask = 0x1;
+				shift = 2;
+				break;
+			default:
+				return -ENOTSUPP;
+			}
+		} else {
+			return -ENOTSUPP;
+		}
+
+		if (pin->type == GLOBAL_CTRL_PIN) {
+			reg = readl((void __iomem *)pin->reg);
+			reg &= ~(PINCTRL_BIT_MASK(pin->bit_width)
+				<< pin->bit_offset);
+			reg |= (val & PINCTRL_BIT_MASK(pin->bit_width))
+				<< pin->bit_offset;
+			writel(reg, (void __iomem *)pin->reg);
+		} else {
+			reg = readl((void __iomem *)pin->reg);
+			reg &= ~(mask << shift);
+			reg |= val;
+			writel(reg, (void __iomem *)pin->reg);
+		}
+	}
+
+	return 0;
+}
+
+static int sprd_pinconf_group_get(struct pinctrl_dev *pctldev,
+				  unsigned int selector, unsigned long *config)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pinctrl_soc_info *info = pctl->info;
+	struct sprd_pin_group *grp;
+	int ret, i;
+
+	if (selector > info->ngroups)
+		return -EINVAL;
+
+	grp = &info->groups[selector];
+
+	for (i = 0; i < grp->npins; i++, config++) {
+		unsigned int pin_id = grp->pins[i];
+
+		ret = sprd_pinconf_get(pctldev, pin_id, config);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int sprd_pinconf_group_set(struct pinctrl_dev *pctldev,
+				  unsigned int selector,
+				  unsigned long *configs,
+				  unsigned int num_configs)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pinctrl_soc_info *info = pctl->info;
+	struct sprd_pin_group *grp;
+	int ret, i;
+
+	if (selector > info->ngroups)
+		return -EINVAL;
+
+	grp = &info->groups[selector];
+
+	for (i = 0; i < grp->npins; i++) {
+		unsigned int pin_id = grp->pins[i];
+
+		ret = sprd_pinconf_set(pctldev, pin_id, configs, num_configs);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static void sprd_pinconf_dbg_show(struct pinctrl_dev *pctldev,
+				  struct seq_file *s, unsigned int pin_id)
+{
+	unsigned long config;
+	int ret;
+
+	ret = sprd_pinconf_get(pctldev, pin_id, &config);
+	if (ret)
+		return;
+
+	seq_printf(s, "0x%lx", config);
+}
+
+static void sprd_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
+					struct seq_file *s,
+					unsigned int selector)
+{
+	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sprd_pinctrl_soc_info *info = pctl->info;
+	struct sprd_pin_group *grp;
+	unsigned long config;
+	const char *name;
+	int i, ret;
+
+	if (selector > info->ngroups)
+		return;
+
+	grp = &info->groups[selector];
+
+	seq_printf(s, "\n");
+	for (i = 0; i < grp->npins; i++, config++) {
+		unsigned int pin_id = grp->pins[i];
+
+		name = pin_get_name(pctldev, pin_id);
+		ret = sprd_pinconf_get(pctldev, pin_id, &config);
+		if (ret)
+			return;
+
+		seq_printf(s, "%s: 0x%lx", name, config);
+	}
+}
+
+static const struct pinconf_ops sprd_pinconf_ops = {
+	.pin_config_get = sprd_pinconf_get,
+	.pin_config_set = sprd_pinconf_set,
+	.pin_config_group_get = sprd_pinconf_group_get,
+	.pin_config_group_set = sprd_pinconf_group_set,
+	.pin_config_dbg_show = sprd_pinconf_dbg_show,
+	.pin_config_group_dbg_show = sprd_pinconf_group_dbg_show,
+};
+
+static const struct pinconf_generic_params sprd_dt_params[] = {
+	{"sprd,ctrl", SPRD_PIN_CONFIG_CONTROL, 0},
+	{"sprd,sleep_mode", SPRD_PIN_CONFIG_SLEEP_MODE, 0},
+	{"sprd,pullup", SPRD_PIN_CONFIG_PULLUP,	0},
+	{"sprd,input-sleep", SPRD_PIN_CONFIG_INPUT_SLEEP, 0},
+	{"sprd,output-sleep", SPRD_PIN_CONFIG_OUTPUT_SLEEP,	0},
+	{"sprd,pullup-sleep", SPRD_PIN_CONFIG_PULLUP_SLEEP,	0},
+	{"sprd,pulldown-sleep", SPRD_PIN_CONFIG_PULLDOWN_SLEEP,	0},
+};
+
+static struct pinctrl_desc sprd_pinctrl_desc = {
+	.pctlops = &sprd_pctrl_ops,
+	.pmxops = &sprd_pmx_ops,
+	.confops = &sprd_pinconf_ops,
+	.num_custom_params = ARRAY_SIZE(sprd_dt_params),
+	.custom_params = sprd_dt_params,
+	.owner = THIS_MODULE,
+};
+
+static int sprd_pinctrl_parse_groups(struct device_node *np,
+				     struct sprd_pinctrl *sprd_pctl,
+				     struct sprd_pin_group *grp)
+{
+	struct property *prop;
+	const char *pin_name;
+	int ret, i = 0;
+
+	ret = of_property_count_strings(np, "pins");
+	if (ret < 0)
+		return ret;
+
+	grp->name = np->name;
+	grp->npins = ret;
+	grp->pins = devm_kzalloc(sprd_pctl->dev, grp->npins *
+				 sizeof(unsigned int), GFP_KERNEL);
+	if (!grp->pins)
+		return -ENOMEM;
+
+	of_property_for_each_string(np, "pins", prop, pin_name) {
+		ret = sprd_pinctrl_get_id_by_name(sprd_pctl, pin_name);
+		if (ret >= 0)
+			grp->pins[i++] = ret;
+	}
+
+	for (i = 0; i < grp->npins; i++) {
+		dev_dbg(sprd_pctl->dev,
+			"Group[%s] contains [%d] pins: id = %d\n",
+			grp->name, grp->npins, grp->pins[i]);
+	}
+
+	return 0;
+}
+
+static int sprd_pinctrl_parse_dt(struct sprd_pinctrl *sprd_pctl)
+{
+	struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
+	struct device_node *np = sprd_pctl->dev->of_node;
+	struct device_node *child;
+	struct sprd_pin_group *grp;
+	const char **temp;
+	int ret;
+
+	if (!np)
+		return -ENODEV;
+
+	info->ngroups = of_get_child_count(np);
+	if (!info->ngroups)
+		return 0;
+
+	info->groups = devm_kzalloc(sprd_pctl->dev, info->ngroups *
+				    sizeof(struct sprd_pin_group),
+				    GFP_KERNEL);
+	if (!info->groups)
+		return -ENOMEM;
+
+	info->grp_names = devm_kzalloc(sprd_pctl->dev,
+				       info->ngroups * sizeof(char *),
+				       GFP_KERNEL);
+	if (!info->grp_names)
+		return -ENOMEM;
+
+	temp = info->grp_names;
+	grp = info->groups;
+	for_each_child_of_node(np, child) {
+		ret = sprd_pinctrl_parse_groups(child, sprd_pctl, grp);
+		if (ret)
+			return ret;
+
+		*temp++ = grp->name;
+		grp++;
+	}
+
+	return 0;
+}
+
+static int sprd_pinctrl_add_pins(struct sprd_pinctrl *sprd_pctl,
+				 struct sprd_pins_info *sprd_soc_pin_info,
+				 int pins_cnt)
+{
+	struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
+	unsigned int ctrl_pin = 0, com_pin = 0;
+	struct sprd_pin *pin;
+	int i;
+
+	info->npins = pins_cnt;
+	info->pins = devm_kzalloc(sprd_pctl->dev,
+				  info->npins * sizeof(struct sprd_pin),
+				  GFP_KERNEL);
+	if (!info->pins)
+		return -ENOMEM;
+
+	for (i = 0, pin = info->pins; i < info->npins; i++, pin++) {
+		unsigned int reg;
+
+		pin->name = sprd_soc_pin_info[i].name;
+		pin->type = sprd_soc_pin_info[i].type;
+		pin->number = sprd_soc_pin_info[i].num;
+		reg = sprd_soc_pin_info[i].reg;
+		if (pin->type == GLOBAL_CTRL_PIN) {
+			pin->reg = (unsigned long)sprd_pctl->base + 0x4 * reg;
+			pin->bit_offset = sprd_soc_pin_info[i].bit_offset;
+			pin->bit_width = sprd_soc_pin_info[i].bit_width;
+			ctrl_pin++;
+		} else if (pin->type == COMMON_PIN) {
+			pin->reg = (unsigned long)sprd_pctl->base +
+				PINCTRL_REG_OFFSET + 0x4 * (i - ctrl_pin);
+			com_pin++;
+		} else if (pin->type == MISC_PIN) {
+			pin->reg = (unsigned long)sprd_pctl->base +
+				PINCTRL_REG_MISC_OFFSET +
+					0x4 * (i - ctrl_pin - com_pin);
+		}
+	}
+
+	for (i = 0, pin = info->pins; i < info->npins; pin++, i++) {
+		dev_dbg(sprd_pctl->dev, "pin name[%s-%d], type = %d, "
+			"bit offset = %ld, bit width = %ld, reg = 0x%lx\n",
+			pin->name, pin->number, pin->type,
+			pin->bit_offset, pin->bit_width, pin->reg);
+	}
+
+	return 0;
+}
+
+int sprd_pinctrl_core_probe(struct platform_device *pdev,
+			    struct sprd_pins_info *sprd_soc_pin_info,
+			    int pins_cnt)
+{
+	struct sprd_pinctrl *sprd_pctl;
+	struct sprd_pinctrl_soc_info *pinctrl_info;
+	struct pinctrl_pin_desc *pin_desc;
+	struct resource *res;
+	int ret, i;
+
+	sprd_pctl = devm_kzalloc(&pdev->dev, sizeof(struct sprd_pinctrl),
+				 GFP_KERNEL);
+	if (!sprd_pctl)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	sprd_pctl->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(sprd_pctl->base))
+		return PTR_ERR(sprd_pctl->base);
+
+	pinctrl_info = devm_kzalloc(&pdev->dev,
+				    sizeof(struct sprd_pinctrl_soc_info),
+				    GFP_KERNEL);
+	if (!pinctrl_info)
+		return -ENOMEM;
+
+	sprd_pctl->info = pinctrl_info;
+	sprd_pctl->dev = &pdev->dev;
+	platform_set_drvdata(pdev, sprd_pctl);
+
+	ret = sprd_pinctrl_add_pins(sprd_pctl, sprd_soc_pin_info, pins_cnt);
+	if (ret) {
+		dev_err(&pdev->dev, "fail to add pins information\n");
+		return ret;
+	}
+
+	pin_desc = devm_kzalloc(&pdev->dev, pinctrl_info->npins *
+				sizeof(struct pinctrl_pin_desc),
+				GFP_KERNEL);
+	if (!pin_desc)
+		return -ENOMEM;
+
+	for (i = 0; i < pinctrl_info->npins; i++) {
+		pin_desc[i].number = pinctrl_info->pins[i].number;
+		pin_desc[i].name = pinctrl_info->pins[i].name;
+		pin_desc[i].drv_data = pinctrl_info;
+	}
+
+	sprd_pinctrl_desc.pins = pin_desc;
+	sprd_pinctrl_desc.name = dev_name(&pdev->dev);
+	sprd_pinctrl_desc.npins = pinctrl_info->npins;
+
+	sprd_pctl->pctl = pinctrl_register(&sprd_pinctrl_desc,
+					   &pdev->dev, (void *)sprd_pctl);
+	if (IS_ERR(sprd_pctl->pctl)) {
+		dev_err(&pdev->dev, "could not register pinctrl driver\n");
+		return PTR_ERR(sprd_pctl->pctl);
+	}
+
+	ret = sprd_pinctrl_parse_dt(sprd_pctl);
+	if (ret) {
+		dev_err(&pdev->dev, "fail to parse dt properties\n");
+		pinctrl_unregister(sprd_pctl->pctl);
+		return ret;
+	}
+
+	return 0;
+}
+
+int sprd_pinctrl_remove(struct platform_device *pdev)
+{
+	struct sprd_pinctrl *sprd_pctl = platform_get_drvdata(pdev);
+
+	pinctrl_unregister(sprd_pctl->pctl);
+	return 0;
+}
+
+void sprd_pinctrl_shutdown(struct platform_device *pdev)
+{
+	struct pinctrl *pinctl = devm_pinctrl_get(&pdev->dev);
+	struct pinctrl_state *state;
+
+	state = pinctrl_lookup_state(pinctl, "pins-shutdown");
+	if (!IS_ERR(state))
+		pinctrl_select_state(pinctl, state);
+}
+
+MODULE_DESCRIPTION("SPREADTRUM Pin Controller Driver");
+MODULE_AUTHOR("Baolin Wang <baolin.wang@spreadtrum.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/sprd/pinctrl-sprd.h b/drivers/pinctrl/sprd/pinctrl-sprd.h
new file mode 100644
index 0000000..7cc3c36
--- /dev/null
+++ b/drivers/pinctrl/sprd/pinctrl-sprd.h
@@ -0,0 +1,95 @@
+/*
+ * Driver header file for pin controller driver
+ * Copyright (C) 2017 Spreadtrum  - http://www.spreadtrum.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef __PINCTRL_SPRD_H__
+#define __PINCTRL_SPRD_H__
+
+struct platform_device;
+
+#define SPRD_PIN_CONFIG_CONTROL		(PIN_CONFIG_END + 1)
+#define SPRD_PIN_CONFIG_SLEEP_MODE	(PIN_CONFIG_END + 2)
+#define SPRD_PIN_CONFIG_PULLUP		(PIN_CONFIG_END + 3)
+#define SPRD_PIN_CONFIG_INPUT_SLEEP	(PIN_CONFIG_END + 4)
+#define SPRD_PIN_CONFIG_OUTPUT_SLEEP	(PIN_CONFIG_END + 5)
+#define SPRD_PIN_CONFIG_PULLUP_SLEEP	(PIN_CONFIG_END + 6)
+#define SPRD_PIN_CONFIG_PULLDOWN_SLEEP	(PIN_CONFIG_END + 7)
+
+#define NUM_OFFSET	(20)
+#define TYPE_OFFSET	(16)
+#define BIT_OFFSET	(8)
+#define WIDTH_OFFSET	(4)
+
+#define SPRD_PIN_INFO(num, type, offset, width, reg)	\
+		(((num) & 0xFFF) << NUM_OFFSET |	\
+		 ((type) & 0xF) << TYPE_OFFSET |	\
+		 ((offset) & 0xFF) << BIT_OFFSET |	\
+		 ((width) & 0xF) << WIDTH_OFFSET |	\
+		 ((reg) & 0xF))
+
+#define SPRD_PINCTRL_PIN(pin)	SPRD_PINCTRL_PIN_DATA(pin, #pin)
+
+#define SPRD_PINCTRL_PIN_DATA(a, b)				\
+	{							\
+		.name = b,					\
+		.num = (((a) >> NUM_OFFSET) & 0xfff),		\
+		.type = (((a) >> TYPE_OFFSET) & 0xf),		\
+		.bit_offset = (((a) >> BIT_OFFSET) & 0xff),	\
+		.bit_width = ((a) >> WIDTH_OFFSET & 0xf),	\
+		.reg = ((a) & 0xf)				\
+	}
+
+enum pin_sleep_mode {
+	AP_SLEEP = BIT(0),
+	PUBCP_SLEEP = BIT(1),
+	TGLDSP_SLEEP = BIT(2),
+	AGDSP_SLEEP = BIT(3),
+};
+
+enum pin_func_sel {
+	PIN_FUNC_1,
+	PIN_FUNC_2,
+	PIN_FUNC_3,
+	PIN_FUNC_4,
+	PIN_FUNC_MAX,
+};
+
+enum pin_pullup_sel {
+	PULLUP_20K,
+	PULLUP_4_7K,
+};
+
+enum pin_type {
+	GLOBAL_CTRL_PIN,
+	COMMON_PIN,
+	MISC_PIN,
+};
+
+struct sprd_pins_info {
+	const char *name;
+	unsigned int num;
+	enum pin_type type;
+
+	/* for global control pins configuration */
+	unsigned long bit_offset;
+	unsigned long bit_width;
+	unsigned int reg;
+};
+
+int sprd_pinctrl_core_probe(struct platform_device *pdev,
+			    struct sprd_pins_info *sprd_soc_pin_info,
+			    int pins_cnt);
+int sprd_pinctrl_remove(struct platform_device *pdev);
+void sprd_pinctrl_shutdown(struct platform_device *pdev);
+
+#endif /* __PINCTRL_SPRD_H__ */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/2] pinctrl: sprd: Add Spreadtrum pin control driver
  2017-06-05 12:11   ` Baolin Wang
@ 2017-06-05 19:07     ` kbuild test robot
  -1 siblings, 0 replies; 24+ messages in thread
From: kbuild test robot @ 2017-06-05 19:07 UTC (permalink / raw)
  Cc: kbuild-all, linus.walleij, mark.rutland, robh+dt, linux-gpio,
	devicetree, linux-kernel, broonie, baolin.wang, baolin.wang

[-- Attachment #1: Type: text/plain, Size: 2856 bytes --]

Hi Baolin,

[auto build test WARNING on robh/for-next]
[also build test WARNING on v4.12-rc4]
[cannot apply to pinctrl/devel next-20170605]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Baolin-Wang/DT-pinctrl-Add-binding-documentation-for-Spreadtrum-pin-controller/20170605-222351
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: i386-allmodconfig (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

   drivers/pinctrl/sprd/pinctrl-sprd.c: In function 'sprd_pinconf_set':
>> drivers/pinctrl/sprd/pinctrl-sprd.c:484:4: warning: case value '129' not in enumerated type 'enum pin_config_param' [-Wswitch]
       case SPRD_PIN_CONFIG_SLEEP_MODE:
       ^~~~
   drivers/pinctrl/sprd/pinctrl-sprd.c:497:4: warning: case value '131' not in enumerated type 'enum pin_config_param' [-Wswitch]
       case SPRD_PIN_CONFIG_INPUT_SLEEP:
       ^~~~
   drivers/pinctrl/sprd/pinctrl-sprd.c:502:4: warning: case value '132' not in enumerated type 'enum pin_config_param' [-Wswitch]
       case SPRD_PIN_CONFIG_OUTPUT_SLEEP:
       ^~~~
   drivers/pinctrl/sprd/pinctrl-sprd.c:534:4: warning: case value '130' not in enumerated type 'enum pin_config_param' [-Wswitch]
       case SPRD_PIN_CONFIG_PULLUP:
       ^~~~
   drivers/pinctrl/sprd/pinctrl-sprd.c:543:4: warning: case value '133' not in enumerated type 'enum pin_config_param' [-Wswitch]
       case SPRD_PIN_CONFIG_PULLUP_SLEEP:
       ^~~~
   drivers/pinctrl/sprd/pinctrl-sprd.c:548:4: warning: case value '134' not in enumerated type 'enum pin_config_param' [-Wswitch]
       case SPRD_PIN_CONFIG_PULLDOWN_SLEEP:
       ^~~~

vim +484 drivers/pinctrl/sprd/pinctrl-sprd.c

   468	
   469		for (i = 0; i < num_configs; i++) {
   470			enum pin_config_param param;
   471			u32 shift, mask, arg, val;
   472	
   473			param = pinconf_to_config_param(configs[i]);
   474			arg = pinconf_to_config_argument(configs[i]);
   475	
   476			val = 0;
   477			shift = 0;
   478			mask = 0;
   479			if (pin->type == GLOBAL_CTRL_PIN &&
   480			    param == SPRD_PIN_CONFIG_CONTROL) {
   481				val = arg;
   482			} else if (pin->type == COMMON_PIN) {
   483				switch (param) {
 > 484				case SPRD_PIN_CONFIG_SLEEP_MODE:
   485					if (arg & AP_SLEEP)
   486						val |= BIT(13);
   487					if (arg & PUBCP_SLEEP)
   488						val |= BIT(14);
   489					if (arg & TGLDSP_SLEEP)
   490						val |= BIT(15);
   491					if (arg & AGDSP_SLEEP)
   492						val |= BIT(16);

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 60113 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/2] pinctrl: sprd: Add Spreadtrum pin control driver
@ 2017-06-05 19:07     ` kbuild test robot
  0 siblings, 0 replies; 24+ messages in thread
From: kbuild test robot @ 2017-06-05 19:07 UTC (permalink / raw)
  To: Baolin Wang
  Cc: kbuild-all, linus.walleij, mark.rutland, robh+dt, linux-gpio,
	devicetree, linux-kernel, broonie, baolin.wang, baolin.wang

[-- Attachment #1: Type: text/plain, Size: 2856 bytes --]

Hi Baolin,

[auto build test WARNING on robh/for-next]
[also build test WARNING on v4.12-rc4]
[cannot apply to pinctrl/devel next-20170605]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Baolin-Wang/DT-pinctrl-Add-binding-documentation-for-Spreadtrum-pin-controller/20170605-222351
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: i386-allmodconfig (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

   drivers/pinctrl/sprd/pinctrl-sprd.c: In function 'sprd_pinconf_set':
>> drivers/pinctrl/sprd/pinctrl-sprd.c:484:4: warning: case value '129' not in enumerated type 'enum pin_config_param' [-Wswitch]
       case SPRD_PIN_CONFIG_SLEEP_MODE:
       ^~~~
   drivers/pinctrl/sprd/pinctrl-sprd.c:497:4: warning: case value '131' not in enumerated type 'enum pin_config_param' [-Wswitch]
       case SPRD_PIN_CONFIG_INPUT_SLEEP:
       ^~~~
   drivers/pinctrl/sprd/pinctrl-sprd.c:502:4: warning: case value '132' not in enumerated type 'enum pin_config_param' [-Wswitch]
       case SPRD_PIN_CONFIG_OUTPUT_SLEEP:
       ^~~~
   drivers/pinctrl/sprd/pinctrl-sprd.c:534:4: warning: case value '130' not in enumerated type 'enum pin_config_param' [-Wswitch]
       case SPRD_PIN_CONFIG_PULLUP:
       ^~~~
   drivers/pinctrl/sprd/pinctrl-sprd.c:543:4: warning: case value '133' not in enumerated type 'enum pin_config_param' [-Wswitch]
       case SPRD_PIN_CONFIG_PULLUP_SLEEP:
       ^~~~
   drivers/pinctrl/sprd/pinctrl-sprd.c:548:4: warning: case value '134' not in enumerated type 'enum pin_config_param' [-Wswitch]
       case SPRD_PIN_CONFIG_PULLDOWN_SLEEP:
       ^~~~

vim +484 drivers/pinctrl/sprd/pinctrl-sprd.c

   468	
   469		for (i = 0; i < num_configs; i++) {
   470			enum pin_config_param param;
   471			u32 shift, mask, arg, val;
   472	
   473			param = pinconf_to_config_param(configs[i]);
   474			arg = pinconf_to_config_argument(configs[i]);
   475	
   476			val = 0;
   477			shift = 0;
   478			mask = 0;
   479			if (pin->type == GLOBAL_CTRL_PIN &&
   480			    param == SPRD_PIN_CONFIG_CONTROL) {
   481				val = arg;
   482			} else if (pin->type == COMMON_PIN) {
   483				switch (param) {
 > 484				case SPRD_PIN_CONFIG_SLEEP_MODE:
   485					if (arg & AP_SLEEP)
   486						val |= BIT(13);
   487					if (arg & PUBCP_SLEEP)
   488						val |= BIT(14);
   489					if (arg & TGLDSP_SLEEP)
   490						val |= BIT(15);
   491					if (arg & AGDSP_SLEEP)
   492						val |= BIT(16);

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 60113 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/2] pinctrl: sprd: Add Spreadtrum pin control driver
  2017-06-05 19:07     ` kbuild test robot
@ 2017-06-06  7:20       ` Baolin Wang
  -1 siblings, 0 replies; 24+ messages in thread
From: Baolin Wang @ 2017-06-06  7:20 UTC (permalink / raw)
  To: kbuild test robot
  Cc: kbuild-all, linus.walleij, mark.rutland, robh+dt, linux-gpio,
	devicetree, linux-kernel, broonie, baolin.wang

Hi,

O 二,  6月 06, 2017 at 03:07:22上午 +0800, kbuild test robot wrote:
> Hi Baolin,
> 
> [auto build test WARNING on robh/for-next]
> [also build test WARNING on v4.12-rc4]
> [cannot apply to pinctrl/devel next-20170605]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> 
> url:    https://github.com/0day-ci/linux/commits/Baolin-Wang/DT-pinctrl-Add-binding-documentation-for-Spreadtrum-pin-controller/20170605-222351
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
> config: i386-allmodconfig (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=i386 
> 
> All warnings (new ones prefixed by >>):
> 
>    drivers/pinctrl/sprd/pinctrl-sprd.c: In function 'sprd_pinconf_set':
> >> drivers/pinctrl/sprd/pinctrl-sprd.c:484:4: warning: case value '129' not in enumerated type 'enum pin_config_param' [-Wswitch]
>        case SPRD_PIN_CONFIG_SLEEP_MODE:
>        ^~~~
>    drivers/pinctrl/sprd/pinctrl-sprd.c:497:4: warning: case value '131' not in enumerated type 'enum pin_config_param' [-Wswitch]
>        case SPRD_PIN_CONFIG_INPUT_SLEEP:
>        ^~~~
>    drivers/pinctrl/sprd/pinctrl-sprd.c:502:4: warning: case value '132' not in enumerated type 'enum pin_config_param' [-Wswitch]
>        case SPRD_PIN_CONFIG_OUTPUT_SLEEP:
>        ^~~~
>    drivers/pinctrl/sprd/pinctrl-sprd.c:534:4: warning: case value '130' not in enumerated type 'enum pin_config_param' [-Wswitch]
>        case SPRD_PIN_CONFIG_PULLUP:
>        ^~~~
>    drivers/pinctrl/sprd/pinctrl-sprd.c:543:4: warning: case value '133' not in enumerated type 'enum pin_config_param' [-Wswitch]
>        case SPRD_PIN_CONFIG_PULLUP_SLEEP:
>        ^~~~
>    drivers/pinctrl/sprd/pinctrl-sprd.c:548:4: warning: case value '134' not in enumerated type 'enum pin_config_param' [-Wswitch]
>        case SPRD_PIN_CONFIG_PULLDOWN_SLEEP:
>        ^~~~

>From kernel doc for 'enum pin_config_param', user need use
PIN_CONFIG_END + 1 as the base offset if the user need to
pass in custom configuration to the pin controller. So I do
not think I need to fix this warning. Thanks.

> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/2] pinctrl: sprd: Add Spreadtrum pin control driver
@ 2017-06-06  7:20       ` Baolin Wang
  0 siblings, 0 replies; 24+ messages in thread
From: Baolin Wang @ 2017-06-06  7:20 UTC (permalink / raw)
  To: kbuild test robot
  Cc: kbuild-all, linus.walleij, mark.rutland, robh+dt, linux-gpio,
	devicetree, linux-kernel, broonie, baolin.wang

Hi,

O 二,  6月 06, 2017 at 03:07:22上午 +0800, kbuild test robot wrote:
> Hi Baolin,
> 
> [auto build test WARNING on robh/for-next]
> [also build test WARNING on v4.12-rc4]
> [cannot apply to pinctrl/devel next-20170605]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> 
> url:    https://github.com/0day-ci/linux/commits/Baolin-Wang/DT-pinctrl-Add-binding-documentation-for-Spreadtrum-pin-controller/20170605-222351
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
> config: i386-allmodconfig (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=i386 
> 
> All warnings (new ones prefixed by >>):
> 
>    drivers/pinctrl/sprd/pinctrl-sprd.c: In function 'sprd_pinconf_set':
> >> drivers/pinctrl/sprd/pinctrl-sprd.c:484:4: warning: case value '129' not in enumerated type 'enum pin_config_param' [-Wswitch]
>        case SPRD_PIN_CONFIG_SLEEP_MODE:
>        ^~~~
>    drivers/pinctrl/sprd/pinctrl-sprd.c:497:4: warning: case value '131' not in enumerated type 'enum pin_config_param' [-Wswitch]
>        case SPRD_PIN_CONFIG_INPUT_SLEEP:
>        ^~~~
>    drivers/pinctrl/sprd/pinctrl-sprd.c:502:4: warning: case value '132' not in enumerated type 'enum pin_config_param' [-Wswitch]
>        case SPRD_PIN_CONFIG_OUTPUT_SLEEP:
>        ^~~~
>    drivers/pinctrl/sprd/pinctrl-sprd.c:534:4: warning: case value '130' not in enumerated type 'enum pin_config_param' [-Wswitch]
>        case SPRD_PIN_CONFIG_PULLUP:
>        ^~~~
>    drivers/pinctrl/sprd/pinctrl-sprd.c:543:4: warning: case value '133' not in enumerated type 'enum pin_config_param' [-Wswitch]
>        case SPRD_PIN_CONFIG_PULLUP_SLEEP:
>        ^~~~
>    drivers/pinctrl/sprd/pinctrl-sprd.c:548:4: warning: case value '134' not in enumerated type 'enum pin_config_param' [-Wswitch]
>        case SPRD_PIN_CONFIG_PULLDOWN_SLEEP:
>        ^~~~

>From kernel doc for 'enum pin_config_param', user need use
PIN_CONFIG_END + 1 as the base offset if the user need to
pass in custom configuration to the pin controller. So I do
not think I need to fix this warning. Thanks.

> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/2] pinctrl: sprd: Add Spreadtrum pin control driver
  2017-06-06  7:20       ` Baolin Wang
@ 2017-06-06  7:40         ` Baolin Wang
  -1 siblings, 0 replies; 24+ messages in thread
From: Baolin Wang @ 2017-06-06  7:40 UTC (permalink / raw)
  To: kbuild test robot, kbuild-all, linus.walleij, mark.rutland,
	robh+dt, linux-gpio, devicetree, linux-kernel, broonie,
	baolin.wang

Hi,

O 二,  6月 06, 2017 at 03:20:55下午 +0800, Baolin Wang wrote:
> Hi,
> 
> O 二,  6月 06, 2017 at 03:07:22上午 +0800, kbuild test robot wrote:
> > Hi Baolin,
> > 
> > [auto build test WARNING on robh/for-next]
> > [also build test WARNING on v4.12-rc4]
> > [cannot apply to pinctrl/devel next-20170605]
> > [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> > 
> > url:    https://github.com/0day-ci/linux/commits/Baolin-Wang/DT-pinctrl-Add-binding-documentation-for-Spreadtrum-pin-controller/20170605-222351
> > base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
> > config: i386-allmodconfig (attached as .config)
> > compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> > reproduce:
> >         # save the attached .config to linux build tree
> >         make ARCH=i386 
> > 
> > All warnings (new ones prefixed by >>):
> > 
> >    drivers/pinctrl/sprd/pinctrl-sprd.c: In function 'sprd_pinconf_set':
> > >> drivers/pinctrl/sprd/pinctrl-sprd.c:484:4: warning: case value '129' not in enumerated type 'enum pin_config_param' [-Wswitch]
> >        case SPRD_PIN_CONFIG_SLEEP_MODE:
> >        ^~~~
> >    drivers/pinctrl/sprd/pinctrl-sprd.c:497:4: warning: case value '131' not in enumerated type 'enum pin_config_param' [-Wswitch]
> >        case SPRD_PIN_CONFIG_INPUT_SLEEP:
> >        ^~~~
> >    drivers/pinctrl/sprd/pinctrl-sprd.c:502:4: warning: case value '132' not in enumerated type 'enum pin_config_param' [-Wswitch]
> >        case SPRD_PIN_CONFIG_OUTPUT_SLEEP:
> >        ^~~~
> >    drivers/pinctrl/sprd/pinctrl-sprd.c:534:4: warning: case value '130' not in enumerated type 'enum pin_config_param' [-Wswitch]
> >        case SPRD_PIN_CONFIG_PULLUP:
> >        ^~~~
> >    drivers/pinctrl/sprd/pinctrl-sprd.c:543:4: warning: case value '133' not in enumerated type 'enum pin_config_param' [-Wswitch]
> >        case SPRD_PIN_CONFIG_PULLUP_SLEEP:
> >        ^~~~
> >    drivers/pinctrl/sprd/pinctrl-sprd.c:548:4: warning: case value '134' not in enumerated type 'enum pin_config_param' [-Wswitch]
> >        case SPRD_PIN_CONFIG_PULLDOWN_SLEEP:
> >        ^~~~
> 
> From kernel doc for 'enum pin_config_param', user need use
> PIN_CONFIG_END + 1 as the base offset if the user need to
> pass in custom configuration to the pin controller. So I do
> not think I need to fix this warning. Thanks.

Sorry for misunderstanding the warning, I've found the reason
of the warning and I will fix it in next version. Thanks.

> 
> > ---
> > 0-DAY kernel test infrastructure                Open Source Technology Center
> > https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
> 
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/2] pinctrl: sprd: Add Spreadtrum pin control driver
@ 2017-06-06  7:40         ` Baolin Wang
  0 siblings, 0 replies; 24+ messages in thread
From: Baolin Wang @ 2017-06-06  7:40 UTC (permalink / raw)
  To: kbuild test robot, kbuild-all, linus.walleij, mark.rutland,
	robh+dt, linux-gpio, devicetree, linux-kernel, broonie,
	baolin.wang

Hi,

O 二,  6月 06, 2017 at 03:20:55下午 +0800, Baolin Wang wrote:
> Hi,
> 
> O 二,  6月 06, 2017 at 03:07:22上午 +0800, kbuild test robot wrote:
> > Hi Baolin,
> > 
> > [auto build test WARNING on robh/for-next]
> > [also build test WARNING on v4.12-rc4]
> > [cannot apply to pinctrl/devel next-20170605]
> > [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> > 
> > url:    https://github.com/0day-ci/linux/commits/Baolin-Wang/DT-pinctrl-Add-binding-documentation-for-Spreadtrum-pin-controller/20170605-222351
> > base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
> > config: i386-allmodconfig (attached as .config)
> > compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> > reproduce:
> >         # save the attached .config to linux build tree
> >         make ARCH=i386 
> > 
> > All warnings (new ones prefixed by >>):
> > 
> >    drivers/pinctrl/sprd/pinctrl-sprd.c: In function 'sprd_pinconf_set':
> > >> drivers/pinctrl/sprd/pinctrl-sprd.c:484:4: warning: case value '129' not in enumerated type 'enum pin_config_param' [-Wswitch]
> >        case SPRD_PIN_CONFIG_SLEEP_MODE:
> >        ^~~~
> >    drivers/pinctrl/sprd/pinctrl-sprd.c:497:4: warning: case value '131' not in enumerated type 'enum pin_config_param' [-Wswitch]
> >        case SPRD_PIN_CONFIG_INPUT_SLEEP:
> >        ^~~~
> >    drivers/pinctrl/sprd/pinctrl-sprd.c:502:4: warning: case value '132' not in enumerated type 'enum pin_config_param' [-Wswitch]
> >        case SPRD_PIN_CONFIG_OUTPUT_SLEEP:
> >        ^~~~
> >    drivers/pinctrl/sprd/pinctrl-sprd.c:534:4: warning: case value '130' not in enumerated type 'enum pin_config_param' [-Wswitch]
> >        case SPRD_PIN_CONFIG_PULLUP:
> >        ^~~~
> >    drivers/pinctrl/sprd/pinctrl-sprd.c:543:4: warning: case value '133' not in enumerated type 'enum pin_config_param' [-Wswitch]
> >        case SPRD_PIN_CONFIG_PULLUP_SLEEP:
> >        ^~~~
> >    drivers/pinctrl/sprd/pinctrl-sprd.c:548:4: warning: case value '134' not in enumerated type 'enum pin_config_param' [-Wswitch]
> >        case SPRD_PIN_CONFIG_PULLDOWN_SLEEP:
> >        ^~~~
> 
> From kernel doc for 'enum pin_config_param', user need use
> PIN_CONFIG_END + 1 as the base offset if the user need to
> pass in custom configuration to the pin controller. So I do
> not think I need to fix this warning. Thanks.

Sorry for misunderstanding the warning, I've found the reason
of the warning and I will fix it in next version. Thanks.

> 
> > ---
> > 0-DAY kernel test infrastructure                Open Source Technology Center
> > https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
> 
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
  2017-06-05 12:11 ` Baolin Wang
  (?)
  (?)
@ 2017-06-09 11:00 ` Linus Walleij
  2017-06-12  6:07     ` Baolin Wang
  -1 siblings, 1 reply; 24+ messages in thread
From: Linus Walleij @ 2017-06-09 11:00 UTC (permalink / raw)
  To: Baolin Wang
  Cc: Mark Rutland, Rob Herring, linux-gpio, devicetree, linux-kernel,
	Mark Brown, Baolin Wang

On Mon, Jun 5, 2017 at 2:11 PM, Baolin Wang <baolin.wang@spreadtrum.com> wrote:

> This patch adds the binding documentation for Spreadtrum SC9860 pin
> controller device.
>
> Signed-off-by: Baolin Wang <baolin.wang@spreadtrum.com>

Good improvements since last iteration!

(...)

> +The Spreadtrum pin controller are organized in 3 blocks (types).
> +
> +The first block comprises some global control registers, and each
> +register contains several bit fields with one bit or several bits
> +to configure for some global common configuration, such as domain
> +pad driving level, system control select and so on.

Insert your explanations about domain pads and system
control from the other mail here.

> + We recognise
> +every fields comprising one bit or several bits in one global control
> +register as one pin, thus we should record every pin's bit offset,
> +bit width and register offset to configure this field (pin). Since
> +this type pins' configuration are very tricky and different for each
> +register, we introduce "sprd,ctrl" property to set the various global
> +control configuration.

Hm I still don't fully understand this property.

> + In some situation we have some pin-sleep related
> +configuration need to set when one of system goes into deep sleep
> +mode. For example, if we set the pin sleep mode as AP_SLEEP, which
> +means when AP system goes into deep sleep mode, this pin's sleep
> +related properties (input/output or pullup/down) will be set
> +automatically. Thus we intoduce "sprd,sleep_mode" to set pin sleep
> +mode.

So what you mean is that there is a special register for the sleep
mode, so that we do not need to write the sleep mode explicitly,
it will instead hit the hardware automatically when the system
switches to sleep mode on some global level?

Please detail this.

This is not a spreadtrum-specific feature. Look for example in:
include/dt-bindings/pinctrl/nomadik.h

We have things like this:

#define SLPM_DISABLED           0
#define SLPM_ENABLED            1
#define SLPM_INPUT_NOPULL       0
#define SLPM_INPUT_PULLUP       1
#define SLPM_INPUT_PULLDOWN     2
#define SLPM_DIR_INPUT          3
#define SLPM_OUTPUT_LOW         0
#define SLPM_OUTPUT_HIGH        1
#define SLPM_DIR_OUTPUT         2
#define SLPM_WAKEUP_DISABLE     0
#define SLPM_WAKEUP_ENABLE      1

These (also custom) properties predate the generic pin config,
and that is why it was done like this.

But moving forward, we may need to think about coming up with
something generic for this.

I think this kind of overlaps the pin control states "default"
and "sleep".

What we want to do is read out both "default" and "sleep" modes
from the device tree and program *both* into the hardware
when "default" is normally initialized.

This is better, because then the device tree looks the same
whether we use hardware-backed switch from "default" to
"sleep" and back or not.

I don't know how to do this practically unfortunately, it may need
some modifications of the pin control core code so that drivers
can get the "sleep" mode configuration out and program it.

> +The last block comprises some misc registers which also have unified
> +register definition, and each register described one pin is used to
> +configure drive strength, pull up/down and so on.

OK

> + Especially for pull
> +up, we introduce "sprd,pullup" property for two kind configuration:
> +PULLUP_20K or PULLUP_4_7K, which means the pullup resistor is 20K or
> +4.7K.

Do not use this. The generic bias-pull-up already supports an
argument.

Use this:

bias-pull-up = <20000>;
bias-pull-up = <4700>;

Just unpack the argument in the .set_config() callback and deny
it setting anything else than 20000 or 4700 Ohms.

> +Optional properties:
> +- function: Specified the function name.
> +- drive-strength: Drive strength in mA.
> +- input-schmitt-disable: Enable schmitt-trigger mode.
> +- input-schmitt-enable: Disable schmitt-trigger mode.
> +- bias-disable: Disable pin bias.
> +- bias-pull-down: Pull down on pin.

OK

> +- sprd,ctrl: Control values referring to databook for global control pins.

Uncertain on this.

> +- sprd,sleep_mode: Sleep mode selection.
> +- sprd,pullup: Pull up on pin.

Switch to bias-pull-up as per above.

> +- sprd,input-sleep: Input enable when system goes into deep sleep mode.
> +- sprd,output-sleep: Output enable when system goes into deep sleep mode.
> +- sprd,pullup_sleep: Pull up enable when system goes into deep sleep mode.
> +- sprd,pulldown_sleep: Pull down enable when system goes into deep sleep mode.

This is not good. We need to handle these using the standard

input-enable
output-enable
bias-pull-up
bias-pull-down

Just inside a state named "sleep" and then let the driver read and program
this state into the sleep registers at first convenience.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
  2017-06-09 11:00 ` [PATCH v2 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller Linus Walleij
@ 2017-06-12  6:07     ` Baolin Wang
  0 siblings, 0 replies; 24+ messages in thread
From: Baolin Wang @ 2017-06-12  6:07 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mark Rutland, Rob Herring, linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mark Brown, Baolin Wang

Hi Linus,

On 五,  6月 09, 2017 at 01:00:17下午 +0200, Linus Walleij wrote:
> On Mon, Jun 5, 2017 at 2:11 PM, Baolin Wang <baolin.wang-lxIno14LUO0EEoCn2XhGlw@public.gmane.org> wrote:
> 
> > This patch adds the binding documentation for Spreadtrum SC9860 pin
> > controller device.
> >
> > Signed-off-by: Baolin Wang <baolin.wang-lxIno14LUO0EEoCn2XhGlw@public.gmane.org>
> 
> Good improvements since last iteration!
> 
> (...)
> 
> > +The Spreadtrum pin controller are organized in 3 blocks (types).
> > +
> > +The first block comprises some global control registers, and each
> > +register contains several bit fields with one bit or several bits
> > +to configure for some global common configuration, such as domain
> > +pad driving level, system control select and so on.
> 
> Insert your explanations about domain pads and system
> control from the other mail here.

OK.

> 
> > + We recognise
> > +every fields comprising one bit or several bits in one global control
> > +register as one pin, thus we should record every pin's bit offset,
> > +bit width and register offset to configure this field (pin). Since
> > +this type pins' configuration are very tricky and different for each
> > +register, we introduce "sprd,ctrl" property to set the various global
> > +control configuration.
> 
> Hm I still don't fully understand this property.

I try to explain these special pins definition on Spreadtrum platform.
This type pins (containing one bit or several bits) are used to configure
various global control, not only domain pad driving level, system control,
and also some other configuration:
EIC (external interrupt controller) source select, debug mode select,
camera pd signal select, camera reset signal select, ADI sync signal
require, watchdog reset select .......

There are too much various configuration that I can not list all of them,
so we can not make every special configuration as one generic configuration,
and maybe it will add more strange globle configuration in future. Then
we add one "sprd,ctrl" (maybe "sprd,control" will be better) to set these
various global control configuration, and we need use magic number for this
property.

> 
> > + In some situation we have some pin-sleep related
> > +configuration need to set when one of system goes into deep sleep
> > +mode. For example, if we set the pin sleep mode as AP_SLEEP, which
> > +means when AP system goes into deep sleep mode, this pin's sleep
> > +related properties (input/output or pullup/down) will be set
> > +automatically. Thus we intoduce "sprd,sleep_mode" to set pin sleep
> > +mode.
> 
> So what you mean is that there is a special register for the sleep
> mode, so that we do not need to write the sleep mode explicitly,
> it will instead hit the hardware automatically when the system
> switches to sleep mode on some global level?

No. Sorry for confusing. What I mean is if we set one pin's sleep mode
as AP_SLEEP, when the AP system goes into deep sleep mode, then the sleep
related configuration of this pin will be set automatically. If we set
the sleep mode as PUBCP_SLEEP, which means when the pubcp system goes into
deep sleep mode, this pin's sleep related configuration will be set.

The sleep related configuration of one pin are described (need modify as
you pointed) as below:
- sprd,input-sleep: Input enable when system goes into deep sleep mode.
- sprd,output-sleep: Output enable when system goes into deep sleep mode.
- sprd,pullup_sleep: Pull up enable when system goes into deep sleep mode.
- sprd,pulldown_sleep: Pull down enable when system goes into deep sleep mode.

So if we set one pin's sleep related configuration, we also should choose
the sleep mode (means which system).

> 
> Please detail this.
> 
> This is not a spreadtrum-specific feature. Look for example in:
> include/dt-bindings/pinctrl/nomadik.h
> 
> We have things like this:
> 
> #define SLPM_DISABLED           0
> #define SLPM_ENABLED            1
> #define SLPM_INPUT_NOPULL       0
> #define SLPM_INPUT_PULLUP       1
> #define SLPM_INPUT_PULLDOWN     2
> #define SLPM_DIR_INPUT          3
> #define SLPM_OUTPUT_LOW         0
> #define SLPM_OUTPUT_HIGH        1
> #define SLPM_DIR_OUTPUT         2
> #define SLPM_WAKEUP_DISABLE     0
> #define SLPM_WAKEUP_ENABLE      1
> 
> These (also custom) properties predate the generic pin config,
> and that is why it was done like this.
> 
> But moving forward, we may need to think about coming up with
> something generic for this.
> 
> I think this kind of overlaps the pin control states "default"
> and "sleep".
> 
> What we want to do is read out both "default" and "sleep" modes
> from the device tree and program *both* into the hardware
> when "default" is normally initialized.
> 
> This is better, because then the device tree looks the same
> whether we use hardware-backed switch from "default" to
> "sleep" and back or not.
> 
> I don't know how to do this practically unfortunately, it may need
> some modifications of the pin control core code so that drivers
> can get the "sleep" mode configuration out and program it.

Yes, I think these "sleep" related configuration are not like
what "sprd,sleep-mode" describes, it looks like below properties:
- sprd,input-sleep: Input enable when system goes into deep sleep mode.
- sprd,output-sleep: Output enable when system goes into deep sleep mode.
- sprd,pullup_sleep: Pull up enable when system goes into deep sleep mode.
- sprd,pulldown_sleep: Pull down enable when system goes into deep sleep mode.

I agree we should add these into core code, something like:
static const struct pinconf_generic_params dt_params[] = {
	{ "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 },
	{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
	{ "bias-high-impedance", PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0 },
	{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
	{ "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 },
	{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
	{ "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 },
	{ "drive-open-source", PIN_CONFIG_DRIVE_OPEN_SOURCE, 0 },
	{ "drive-push-pull", PIN_CONFIG_DRIVE_PUSH_PULL, 0 },
	{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
	{ "input-debounce", PIN_CONFIG_INPUT_DEBOUNCE, 0 },
	{ "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
	{ "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
	{ "input-schmitt", PIN_CONFIG_INPUT_SCHMITT, 0 },
	{ "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
	{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
	{ "low-power-disable", PIN_CONFIG_LOW_POWER_MODE, 0 },
	{ "low-power-enable", PIN_CONFIG_LOW_POWER_MODE, 1 },
	{ "output-high", PIN_CONFIG_OUTPUT, 1, },
	{ "output-low", PIN_CONFIG_OUTPUT, 0, },
	{ "power-source", PIN_CONFIG_POWER_SOURCE, 0 },
	{ "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
+	{ "sleep-bias-pull-up", PIN_CONFIG_SLEEP_BIAS_PULL_UP, 1},
+	{ "sleep-bias-pull-down", PIN_CONFIG_SLEEP_BIAS_PULL_DOWN 1},
	......
};

If you agree that, I can help to add these configuration.

> 
> > +The last block comprises some misc registers which also have unified
> > +register definition, and each register described one pin is used to
> > +configure drive strength, pull up/down and so on.
> 
> OK
> 
> > + Especially for pull
> > +up, we introduce "sprd,pullup" property for two kind configuration:
> > +PULLUP_20K or PULLUP_4_7K, which means the pullup resistor is 20K or
> > +4.7K.
> 
> Do not use this. The generic bias-pull-up already supports an
> argument.
> 
> Use this:
> 
> bias-pull-up = <20000>;
> bias-pull-up = <4700>;
> 
> Just unpack the argument in the .set_config() callback and deny
> it setting anything else than 20000 or 4700 Ohms.

Yes, you are right. I missed this and will fix in next version.

> 
> > +Optional properties:
> > +- function: Specified the function name.
> > +- drive-strength: Drive strength in mA.
> > +- input-schmitt-disable: Enable schmitt-trigger mode.
> > +- input-schmitt-enable: Disable schmitt-trigger mode.
> > +- bias-disable: Disable pin bias.
> > +- bias-pull-down: Pull down on pin.
> 
> OK
> 
> > +- sprd,ctrl: Control values referring to databook for global control pins.
> 
> Uncertain on this.
> 
> > +- sprd,sleep_mode: Sleep mode selection.
> > +- sprd,pullup: Pull up on pin.
> 
> Switch to bias-pull-up as per above.

OK.

> 
> > +- sprd,input-sleep: Input enable when system goes into deep sleep mode.
> > +- sprd,output-sleep: Output enable when system goes into deep sleep mode.
> > +- sprd,pullup_sleep: Pull up enable when system goes into deep sleep mode.
> > +- sprd,pulldown_sleep: Pull down enable when system goes into deep sleep mode.
> 
> This is not good. We need to handle these using the standard
> 
> input-enable
> output-enable
> bias-pull-up
> bias-pull-down
> 
> Just inside a state named "sleep" and then let the driver read and program
> this state into the sleep registers at first convenience.

I am afraid I can not use the "sleep" state. Since if we set the "sleep" state,
and usually we will issue "pinctrl_force_sleep()" in suspend function, but I am
afraid it will be too late for pin sleep related configuration when system goes
into deep sleep.

As I explained above, these 4 sleep related configuration bind with the pin sleep
mode, we should set them as generic config before system goes into deep sleep.
We can add these sleep related configuration into pinctrl core like I suggested
above, which will be more reasonable. What do you think?
static const struct pinconf_generic_params dt_params[] = {
	......
	{ "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
+	{ "sleep-bias-pull-up", PIN_CONFIG_SLEEP_BIAS_PULL_UP, 1},
+	{ "sleep-bias-pull-down", PIN_CONFIG_SLEEP_BIAS_PULL_DOWN, 1},
+	{ "sleep-bias-input-enable", PIN_CONFIG_SLEEP_INPUT_ENABLE, 1},
+	{ "sleep-bias-output-enable", PIN_CONFIG_SLEEP_OUTPUT_ENABLE, 1},

Really appreciate for your comments.

};
> 
> Yours,
> Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
@ 2017-06-12  6:07     ` Baolin Wang
  0 siblings, 0 replies; 24+ messages in thread
From: Baolin Wang @ 2017-06-12  6:07 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mark Rutland, Rob Herring, linux-gpio, devicetree, linux-kernel,
	Mark Brown, Baolin Wang

Hi Linus,

On 五,  6月 09, 2017 at 01:00:17下午 +0200, Linus Walleij wrote:
> On Mon, Jun 5, 2017 at 2:11 PM, Baolin Wang <baolin.wang@spreadtrum.com> wrote:
> 
> > This patch adds the binding documentation for Spreadtrum SC9860 pin
> > controller device.
> >
> > Signed-off-by: Baolin Wang <baolin.wang@spreadtrum.com>
> 
> Good improvements since last iteration!
> 
> (...)
> 
> > +The Spreadtrum pin controller are organized in 3 blocks (types).
> > +
> > +The first block comprises some global control registers, and each
> > +register contains several bit fields with one bit or several bits
> > +to configure for some global common configuration, such as domain
> > +pad driving level, system control select and so on.
> 
> Insert your explanations about domain pads and system
> control from the other mail here.

OK.

> 
> > + We recognise
> > +every fields comprising one bit or several bits in one global control
> > +register as one pin, thus we should record every pin's bit offset,
> > +bit width and register offset to configure this field (pin). Since
> > +this type pins' configuration are very tricky and different for each
> > +register, we introduce "sprd,ctrl" property to set the various global
> > +control configuration.
> 
> Hm I still don't fully understand this property.

I try to explain these special pins definition on Spreadtrum platform.
This type pins (containing one bit or several bits) are used to configure
various global control, not only domain pad driving level, system control,
and also some other configuration:
EIC (external interrupt controller) source select, debug mode select,
camera pd signal select, camera reset signal select, ADI sync signal
require, watchdog reset select .......

There are too much various configuration that I can not list all of them,
so we can not make every special configuration as one generic configuration,
and maybe it will add more strange globle configuration in future. Then
we add one "sprd,ctrl" (maybe "sprd,control" will be better) to set these
various global control configuration, and we need use magic number for this
property.

> 
> > + In some situation we have some pin-sleep related
> > +configuration need to set when one of system goes into deep sleep
> > +mode. For example, if we set the pin sleep mode as AP_SLEEP, which
> > +means when AP system goes into deep sleep mode, this pin's sleep
> > +related properties (input/output or pullup/down) will be set
> > +automatically. Thus we intoduce "sprd,sleep_mode" to set pin sleep
> > +mode.
> 
> So what you mean is that there is a special register for the sleep
> mode, so that we do not need to write the sleep mode explicitly,
> it will instead hit the hardware automatically when the system
> switches to sleep mode on some global level?

No. Sorry for confusing. What I mean is if we set one pin's sleep mode
as AP_SLEEP, when the AP system goes into deep sleep mode, then the sleep
related configuration of this pin will be set automatically. If we set
the sleep mode as PUBCP_SLEEP, which means when the pubcp system goes into
deep sleep mode, this pin's sleep related configuration will be set.

The sleep related configuration of one pin are described (need modify as
you pointed) as below:
- sprd,input-sleep: Input enable when system goes into deep sleep mode.
- sprd,output-sleep: Output enable when system goes into deep sleep mode.
- sprd,pullup_sleep: Pull up enable when system goes into deep sleep mode.
- sprd,pulldown_sleep: Pull down enable when system goes into deep sleep mode.

So if we set one pin's sleep related configuration, we also should choose
the sleep mode (means which system).

> 
> Please detail this.
> 
> This is not a spreadtrum-specific feature. Look for example in:
> include/dt-bindings/pinctrl/nomadik.h
> 
> We have things like this:
> 
> #define SLPM_DISABLED           0
> #define SLPM_ENABLED            1
> #define SLPM_INPUT_NOPULL       0
> #define SLPM_INPUT_PULLUP       1
> #define SLPM_INPUT_PULLDOWN     2
> #define SLPM_DIR_INPUT          3
> #define SLPM_OUTPUT_LOW         0
> #define SLPM_OUTPUT_HIGH        1
> #define SLPM_DIR_OUTPUT         2
> #define SLPM_WAKEUP_DISABLE     0
> #define SLPM_WAKEUP_ENABLE      1
> 
> These (also custom) properties predate the generic pin config,
> and that is why it was done like this.
> 
> But moving forward, we may need to think about coming up with
> something generic for this.
> 
> I think this kind of overlaps the pin control states "default"
> and "sleep".
> 
> What we want to do is read out both "default" and "sleep" modes
> from the device tree and program *both* into the hardware
> when "default" is normally initialized.
> 
> This is better, because then the device tree looks the same
> whether we use hardware-backed switch from "default" to
> "sleep" and back or not.
> 
> I don't know how to do this practically unfortunately, it may need
> some modifications of the pin control core code so that drivers
> can get the "sleep" mode configuration out and program it.

Yes, I think these "sleep" related configuration are not like
what "sprd,sleep-mode" describes, it looks like below properties:
- sprd,input-sleep: Input enable when system goes into deep sleep mode.
- sprd,output-sleep: Output enable when system goes into deep sleep mode.
- sprd,pullup_sleep: Pull up enable when system goes into deep sleep mode.
- sprd,pulldown_sleep: Pull down enable when system goes into deep sleep mode.

I agree we should add these into core code, something like:
static const struct pinconf_generic_params dt_params[] = {
	{ "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 },
	{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
	{ "bias-high-impedance", PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0 },
	{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
	{ "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 },
	{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
	{ "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 },
	{ "drive-open-source", PIN_CONFIG_DRIVE_OPEN_SOURCE, 0 },
	{ "drive-push-pull", PIN_CONFIG_DRIVE_PUSH_PULL, 0 },
	{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
	{ "input-debounce", PIN_CONFIG_INPUT_DEBOUNCE, 0 },
	{ "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
	{ "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
	{ "input-schmitt", PIN_CONFIG_INPUT_SCHMITT, 0 },
	{ "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
	{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
	{ "low-power-disable", PIN_CONFIG_LOW_POWER_MODE, 0 },
	{ "low-power-enable", PIN_CONFIG_LOW_POWER_MODE, 1 },
	{ "output-high", PIN_CONFIG_OUTPUT, 1, },
	{ "output-low", PIN_CONFIG_OUTPUT, 0, },
	{ "power-source", PIN_CONFIG_POWER_SOURCE, 0 },
	{ "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
+	{ "sleep-bias-pull-up", PIN_CONFIG_SLEEP_BIAS_PULL_UP, 1},
+	{ "sleep-bias-pull-down", PIN_CONFIG_SLEEP_BIAS_PULL_DOWN 1},
	......
};

If you agree that, I can help to add these configuration.

> 
> > +The last block comprises some misc registers which also have unified
> > +register definition, and each register described one pin is used to
> > +configure drive strength, pull up/down and so on.
> 
> OK
> 
> > + Especially for pull
> > +up, we introduce "sprd,pullup" property for two kind configuration:
> > +PULLUP_20K or PULLUP_4_7K, which means the pullup resistor is 20K or
> > +4.7K.
> 
> Do not use this. The generic bias-pull-up already supports an
> argument.
> 
> Use this:
> 
> bias-pull-up = <20000>;
> bias-pull-up = <4700>;
> 
> Just unpack the argument in the .set_config() callback and deny
> it setting anything else than 20000 or 4700 Ohms.

Yes, you are right. I missed this and will fix in next version.

> 
> > +Optional properties:
> > +- function: Specified the function name.
> > +- drive-strength: Drive strength in mA.
> > +- input-schmitt-disable: Enable schmitt-trigger mode.
> > +- input-schmitt-enable: Disable schmitt-trigger mode.
> > +- bias-disable: Disable pin bias.
> > +- bias-pull-down: Pull down on pin.
> 
> OK
> 
> > +- sprd,ctrl: Control values referring to databook for global control pins.
> 
> Uncertain on this.
> 
> > +- sprd,sleep_mode: Sleep mode selection.
> > +- sprd,pullup: Pull up on pin.
> 
> Switch to bias-pull-up as per above.

OK.

> 
> > +- sprd,input-sleep: Input enable when system goes into deep sleep mode.
> > +- sprd,output-sleep: Output enable when system goes into deep sleep mode.
> > +- sprd,pullup_sleep: Pull up enable when system goes into deep sleep mode.
> > +- sprd,pulldown_sleep: Pull down enable when system goes into deep sleep mode.
> 
> This is not good. We need to handle these using the standard
> 
> input-enable
> output-enable
> bias-pull-up
> bias-pull-down
> 
> Just inside a state named "sleep" and then let the driver read and program
> this state into the sleep registers at first convenience.

I am afraid I can not use the "sleep" state. Since if we set the "sleep" state,
and usually we will issue "pinctrl_force_sleep()" in suspend function, but I am
afraid it will be too late for pin sleep related configuration when system goes
into deep sleep.

As I explained above, these 4 sleep related configuration bind with the pin sleep
mode, we should set them as generic config before system goes into deep sleep.
We can add these sleep related configuration into pinctrl core like I suggested
above, which will be more reasonable. What do you think?
static const struct pinconf_generic_params dt_params[] = {
	......
	{ "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
+	{ "sleep-bias-pull-up", PIN_CONFIG_SLEEP_BIAS_PULL_UP, 1},
+	{ "sleep-bias-pull-down", PIN_CONFIG_SLEEP_BIAS_PULL_DOWN, 1},
+	{ "sleep-bias-input-enable", PIN_CONFIG_SLEEP_INPUT_ENABLE, 1},
+	{ "sleep-bias-output-enable", PIN_CONFIG_SLEEP_OUTPUT_ENABLE, 1},

Really appreciate for your comments.

};
> 
> Yours,
> Linus Walleij

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
  2017-06-12  6:07     ` Baolin Wang
  (?)
@ 2017-06-13  3:15     ` Baolin Wang
       [not found]       ` <20170613031547.GA29679-lxIno14LUO0EEoCn2XhGlw@public.gmane.org>
  -1 siblings, 1 reply; 24+ messages in thread
From: Baolin Wang @ 2017-06-13  3:15 UTC (permalink / raw)
  To: Linus Walleij, Mark Rutland, Rob Herring, linux-gpio, devicetree,
	linux-kernel, Mark Brown, Baolin Wang

Hi Linus,

On 一,  6月 12, 2017 at 02:07:18下午 +0800, Baolin Wang wrote:
> Hi Linus,
> 
> On 五,  6月 09, 2017 at 01:00:17下午 +0200, Linus Walleij wrote:
> > On Mon, Jun 5, 2017 at 2:11 PM, Baolin Wang <baolin.wang@spreadtrum.com> wrote:
> > 
> > > This patch adds the binding documentation for Spreadtrum SC9860 pin
> > > controller device.
> > >
> > > Signed-off-by: Baolin Wang <baolin.wang@spreadtrum.com>
> > 
> > Good improvements since last iteration!
> > 
> > (...)
> > 
> > > +The Spreadtrum pin controller are organized in 3 blocks (types).
> > > +
> > > +The first block comprises some global control registers, and each
> > > +register contains several bit fields with one bit or several bits
> > > +to configure for some global common configuration, such as domain
> > > +pad driving level, system control select and so on.
> > 
> > Insert your explanations about domain pads and system
> > control from the other mail here.
> 
> OK.
> 
> > 
> > > + We recognise
> > > +every fields comprising one bit or several bits in one global control
> > > +register as one pin, thus we should record every pin's bit offset,
> > > +bit width and register offset to configure this field (pin). Since
> > > +this type pins' configuration are very tricky and different for each
> > > +register, we introduce "sprd,ctrl" property to set the various global
> > > +control configuration.
> > 
> > Hm I still don't fully understand this property.
> 
> I try to explain these special pins definition on Spreadtrum platform.
> This type pins (containing one bit or several bits) are used to configure
> various global control, not only domain pad driving level, system control,
> and also some other configuration:
> EIC (external interrupt controller) source select, debug mode select,
> camera pd signal select, camera reset signal select, ADI sync signal
> require, watchdog reset select .......
> 
> There are too much various configuration that I can not list all of them,
> so we can not make every special configuration as one generic configuration,
> and maybe it will add more strange globle configuration in future. Then
> we add one "sprd,ctrl" (maybe "sprd,control" will be better) to set these
> various global control configuration, and we need use magic number for this
> property.
> 
> > 
> > > + In some situation we have some pin-sleep related
> > > +configuration need to set when one of system goes into deep sleep
> > > +mode. For example, if we set the pin sleep mode as AP_SLEEP, which
> > > +means when AP system goes into deep sleep mode, this pin's sleep
> > > +related properties (input/output or pullup/down) will be set
> > > +automatically. Thus we intoduce "sprd,sleep_mode" to set pin sleep
> > > +mode.
> > 
> > So what you mean is that there is a special register for the sleep
> > mode, so that we do not need to write the sleep mode explicitly,
> > it will instead hit the hardware automatically when the system
> > switches to sleep mode on some global level?
> 
> No. Sorry for confusing. What I mean is if we set one pin's sleep mode
> as AP_SLEEP, when the AP system goes into deep sleep mode, then the sleep
> related configuration of this pin will be set automatically. If we set
> the sleep mode as PUBCP_SLEEP, which means when the pubcp system goes into
> deep sleep mode, this pin's sleep related configuration will be set.
> 
> The sleep related configuration of one pin are described (need modify as
> you pointed) as below:
> - sprd,input-sleep: Input enable when system goes into deep sleep mode.
> - sprd,output-sleep: Output enable when system goes into deep sleep mode.
> - sprd,pullup_sleep: Pull up enable when system goes into deep sleep mode.
> - sprd,pulldown_sleep: Pull down enable when system goes into deep sleep mode.
> 
> So if we set one pin's sleep related configuration, we also should choose
> the sleep mode (means which system).
> 
> > 
> > Please detail this.
> > 
> > This is not a spreadtrum-specific feature. Look for example in:
> > include/dt-bindings/pinctrl/nomadik.h
> > 
> > We have things like this:
> > 
> > #define SLPM_DISABLED           0
> > #define SLPM_ENABLED            1
> > #define SLPM_INPUT_NOPULL       0
> > #define SLPM_INPUT_PULLUP       1
> > #define SLPM_INPUT_PULLDOWN     2
> > #define SLPM_DIR_INPUT          3
> > #define SLPM_OUTPUT_LOW         0
> > #define SLPM_OUTPUT_HIGH        1
> > #define SLPM_DIR_OUTPUT         2
> > #define SLPM_WAKEUP_DISABLE     0
> > #define SLPM_WAKEUP_ENABLE      1
> > 
> > These (also custom) properties predate the generic pin config,
> > and that is why it was done like this.
> > 
> > But moving forward, we may need to think about coming up with
> > something generic for this.
> > 
> > I think this kind of overlaps the pin control states "default"
> > and "sleep".
> > 
> > What we want to do is read out both "default" and "sleep" modes
> > from the device tree and program *both* into the hardware
> > when "default" is normally initialized.
> > 
> > This is better, because then the device tree looks the same
> > whether we use hardware-backed switch from "default" to
> > "sleep" and back or not.
> > 
> > I don't know how to do this practically unfortunately, it may need
> > some modifications of the pin control core code so that drivers
> > can get the "sleep" mode configuration out and program it.
> 
> Yes, I think these "sleep" related configuration are not like
> what "sprd,sleep-mode" describes, it looks like below properties:
> - sprd,input-sleep: Input enable when system goes into deep sleep mode.
> - sprd,output-sleep: Output enable when system goes into deep sleep mode.
> - sprd,pullup_sleep: Pull up enable when system goes into deep sleep mode.
> - sprd,pulldown_sleep: Pull down enable when system goes into deep sleep mode.
> 
> I agree we should add these into core code, something like:
> static const struct pinconf_generic_params dt_params[] = {
> 	{ "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 },
> 	{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
> 	{ "bias-high-impedance", PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0 },
> 	{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
> 	{ "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 },
> 	{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
> 	{ "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 },
> 	{ "drive-open-source", PIN_CONFIG_DRIVE_OPEN_SOURCE, 0 },
> 	{ "drive-push-pull", PIN_CONFIG_DRIVE_PUSH_PULL, 0 },
> 	{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
> 	{ "input-debounce", PIN_CONFIG_INPUT_DEBOUNCE, 0 },
> 	{ "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
> 	{ "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
> 	{ "input-schmitt", PIN_CONFIG_INPUT_SCHMITT, 0 },
> 	{ "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
> 	{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
> 	{ "low-power-disable", PIN_CONFIG_LOW_POWER_MODE, 0 },
> 	{ "low-power-enable", PIN_CONFIG_LOW_POWER_MODE, 1 },
> 	{ "output-high", PIN_CONFIG_OUTPUT, 1, },
> 	{ "output-low", PIN_CONFIG_OUTPUT, 0, },
> 	{ "power-source", PIN_CONFIG_POWER_SOURCE, 0 },
> 	{ "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
> +	{ "sleep-bias-pull-up", PIN_CONFIG_SLEEP_BIAS_PULL_UP, 1},
> +	{ "sleep-bias-pull-down", PIN_CONFIG_SLEEP_BIAS_PULL_DOWN 1},
> 	......
> };
> 
> If you agree that, I can help to add these configuration.
> 
> > 
> > > +The last block comprises some misc registers which also have unified
> > > +register definition, and each register described one pin is used to
> > > +configure drive strength, pull up/down and so on.
> > 
> > OK
> > 
> > > + Especially for pull
> > > +up, we introduce "sprd,pullup" property for two kind configuration:
> > > +PULLUP_20K or PULLUP_4_7K, which means the pullup resistor is 20K or
> > > +4.7K.
> > 
> > Do not use this. The generic bias-pull-up already supports an
> > argument.
> > 
> > Use this:
> > 
> > bias-pull-up = <20000>;
> > bias-pull-up = <4700>;
> > 
> > Just unpack the argument in the .set_config() callback and deny
> > it setting anything else than 20000 or 4700 Ohms.
> 
> Yes, you are right. I missed this and will fix in next version.
> 
> > 
> > > +Optional properties:
> > > +- function: Specified the function name.
> > > +- drive-strength: Drive strength in mA.
> > > +- input-schmitt-disable: Enable schmitt-trigger mode.
> > > +- input-schmitt-enable: Disable schmitt-trigger mode.
> > > +- bias-disable: Disable pin bias.
> > > +- bias-pull-down: Pull down on pin.
> > 
> > OK
> > 
> > > +- sprd,ctrl: Control values referring to databook for global control pins.
> > 
> > Uncertain on this.
> > 
> > > +- sprd,sleep_mode: Sleep mode selection.
> > > +- sprd,pullup: Pull up on pin.
> > 
> > Switch to bias-pull-up as per above.
> 
> OK.
> 
> > 
> > > +- sprd,input-sleep: Input enable when system goes into deep sleep mode.
> > > +- sprd,output-sleep: Output enable when system goes into deep sleep mode.
> > > +- sprd,pullup_sleep: Pull up enable when system goes into deep sleep mode.
> > > +- sprd,pulldown_sleep: Pull down enable when system goes into deep sleep mode.
> > 
> > This is not good. We need to handle these using the standard
> > 
> > input-enable
> > output-enable
> > bias-pull-up
> > bias-pull-down
> > 
> > Just inside a state named "sleep" and then let the driver read and program
> > this state into the sleep registers at first convenience.
> 
> I am afraid I can not use the "sleep" state. Since if we set the "sleep" state,
> and usually we will issue "pinctrl_force_sleep()" in suspend function, but I am
> afraid it will be too late for pin sleep related configuration when system goes
> into deep sleep.
> 
> As I explained above, these 4 sleep related configuration bind with the pin sleep
> mode, we should set them as generic config before system goes into deep sleep.
> We can add these sleep related configuration into pinctrl core like I suggested
> above, which will be more reasonable. What do you think?
> static const struct pinconf_generic_params dt_params[] = {
> 	......
> 	{ "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
> +	{ "sleep-bias-pull-up", PIN_CONFIG_SLEEP_BIAS_PULL_UP, 1},
> +	{ "sleep-bias-pull-down", PIN_CONFIG_SLEEP_BIAS_PULL_DOWN, 1},
> +	{ "sleep-bias-input-enable", PIN_CONFIG_SLEEP_INPUT_ENABLE, 1},
> +	{ "sleep-bias-output-enable", PIN_CONFIG_SLEEP_OUTPUT_ENABLE, 1},
> 
> Really appreciate for your comments.

I forgot one most important reason why we can not use the "sleep" state. As I explained
above, the sleep related configuration will bind with the pin's sleep mode. If we set the
pin's sleep mode as AP_SLEEP, then we can select "sleep" state when AP system goes into
deep sleep mode by issuing "pinctrl_force_sleep()" in pinctrl suspend function.

But if we set the pin's sleep mode as PUBCP_SLEEP and pubcp system doesn't run linux kernel
(it run another thread OS), then we can not select "sleep" state since the AP system does
not go into deep sleep mode (AP system run linux kernel OS).
 
> };
> > 
> > Yours,
> > Linus Walleij

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
  2017-06-12  6:07     ` Baolin Wang
  (?)
  (?)
@ 2017-06-20  9:10     ` Linus Walleij
  2017-06-21  2:35       ` Baolin Wang
  -1 siblings, 1 reply; 24+ messages in thread
From: Linus Walleij @ 2017-06-20  9:10 UTC (permalink / raw)
  To: Linus Walleij, Mark Rutland, Rob Herring, linux-gpio, devicetree,
	linux-kernel, Mark Brown, Baolin Wang

On Mon, Jun 12, 2017 at 8:07 AM, Baolin Wang <baolin.wang@spreadtrum.com> wrote:

> I agree we should add these into core code, something like:
> static const struct pinconf_generic_params dt_params[] = {
(...)
>         { "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
> +       { "sleep-bias-pull-up", PIN_CONFIG_SLEEP_BIAS_PULL_UP, 1},
> +       { "sleep-bias-pull-down", PIN_CONFIG_SLEEP_BIAS_PULL_DOWN 1},
>         ......
> };
>
> If you agree that, I can help to add these configuration.

Actually, yes indeed, that is a nice thing. Very nice. I think my Nomadik
driver could use this too.

Just need to hear what the DT maintainers have to say about it.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
  2017-06-13  3:15     ` Baolin Wang
@ 2017-06-20  9:31           ` Linus Walleij
  0 siblings, 0 replies; 24+ messages in thread
From: Linus Walleij @ 2017-06-20  9:31 UTC (permalink / raw)
  To: Linus Walleij, Mark Rutland, Rob Herring,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mark Brown, Baolin Wang

On Tue, Jun 13, 2017 at 5:15 AM, Baolin Wang <baolin.wang-lxIno14LUO0EEoCn2XhGlw@public.gmane.org> wrote:

> I forgot one most important reason why we can not use the "sleep" state. As I explained
> above, the sleep related configuration will bind with the pin's sleep mode. If we set the
> pin's sleep mode as AP_SLEEP, then we can select "sleep" state when AP system goes into
> deep sleep mode by issuing "pinctrl_force_sleep()" in pinctrl suspend function.
>
> But if we set the pin's sleep mode as PUBCP_SLEEP and pubcp system doesn't run linux kernel
> (it run another thread OS), then we can not select "sleep" state since the AP system does
> not go into deep sleep mode (AP system run linux kernel OS).

Allright yes it makes sense, and also there are systems that just go into
"hardware sleep" and just put the pin into some pre-programmed mode.

I'm a bit back-and-forth. I didn't mean that some code would actually
switch the state to "sleep" when we go to sleep, I meant that when
the system configures "default" mode it should also look up and
program the "sleep" mode, but this approach with a special property
is just another way of achieveing the same thing.

But then we should add a whole slew of sleep states.

I was thinking whether we could avoid having a special DT property
by parsing ahead to states we do not currently use and programming
that into the sleep mode registers.


Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
@ 2017-06-20  9:31           ` Linus Walleij
  0 siblings, 0 replies; 24+ messages in thread
From: Linus Walleij @ 2017-06-20  9:31 UTC (permalink / raw)
  To: Linus Walleij, Mark Rutland, Rob Herring, linux-gpio, devicetree,
	linux-kernel, Mark Brown, Baolin Wang

On Tue, Jun 13, 2017 at 5:15 AM, Baolin Wang <baolin.wang@spreadtrum.com> wrote:

> I forgot one most important reason why we can not use the "sleep" state. As I explained
> above, the sleep related configuration will bind with the pin's sleep mode. If we set the
> pin's sleep mode as AP_SLEEP, then we can select "sleep" state when AP system goes into
> deep sleep mode by issuing "pinctrl_force_sleep()" in pinctrl suspend function.
>
> But if we set the pin's sleep mode as PUBCP_SLEEP and pubcp system doesn't run linux kernel
> (it run another thread OS), then we can not select "sleep" state since the AP system does
> not go into deep sleep mode (AP system run linux kernel OS).

Allright yes it makes sense, and also there are systems that just go into
"hardware sleep" and just put the pin into some pre-programmed mode.

I'm a bit back-and-forth. I didn't mean that some code would actually
switch the state to "sleep" when we go to sleep, I meant that when
the system configures "default" mode it should also look up and
program the "sleep" mode, but this approach with a special property
is just another way of achieveing the same thing.

But then we should add a whole slew of sleep states.

I was thinking whether we could avoid having a special DT property
by parsing ahead to states we do not currently use and programming
that into the sleep mode registers.


Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
  2017-06-20  9:10     ` Linus Walleij
@ 2017-06-21  2:35       ` Baolin Wang
  0 siblings, 0 replies; 24+ messages in thread
From: Baolin Wang @ 2017-06-21  2:35 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mark Rutland, Rob Herring, linux-gpio, devicetree, linux-kernel,
	Mark Brown

On 20 June 2017 at 17:10, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Mon, Jun 12, 2017 at 8:07 AM, Baolin Wang <baolin.wang@spreadtrum.com> wrote:
>
>> I agree we should add these into core code, something like:
>> static const struct pinconf_generic_params dt_params[] = {
> (...)
>>         { "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
>> +       { "sleep-bias-pull-up", PIN_CONFIG_SLEEP_BIAS_PULL_UP, 1},
>> +       { "sleep-bias-pull-down", PIN_CONFIG_SLEEP_BIAS_PULL_DOWN 1},
>>         ......
>> };
>>
>> If you agree that, I can help to add these configuration.
>
> Actually, yes indeed, that is a nice thing. Very nice. I think my Nomadik
> driver could use this too.
>
> Just need to hear what the DT maintainers have to say about it.

OK, I will submit one patch to review. Thanks.

-- 
Baolin.wang
Best Regards

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
  2017-06-20  9:31           ` Linus Walleij
  (?)
@ 2017-06-21  8:10           ` Baolin Wang
       [not found]             ` <CAMz4ku+jZ-S6sBL=ib++j+ooqweU9UC+MTgFca7ScrQiJDeZVQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  -1 siblings, 1 reply; 24+ messages in thread
From: Baolin Wang @ 2017-06-21  8:10 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mark Rutland, Rob Herring, linux-gpio, devicetree, linux-kernel,
	Mark Brown

On 20 June 2017 at 17:31, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Tue, Jun 13, 2017 at 5:15 AM, Baolin Wang <baolin.wang@spreadtrum.com> wrote:
>
>> I forgot one most important reason why we can not use the "sleep" state. As I explained
>> above, the sleep related configuration will bind with the pin's sleep mode. If we set the
>> pin's sleep mode as AP_SLEEP, then we can select "sleep" state when AP system goes into
>> deep sleep mode by issuing "pinctrl_force_sleep()" in pinctrl suspend function.
>>
>> But if we set the pin's sleep mode as PUBCP_SLEEP and pubcp system doesn't run linux kernel
>> (it run another thread OS), then we can not select "sleep" state since the AP system does
>> not go into deep sleep mode (AP system run linux kernel OS).
>
> Allright yes it makes sense, and also there are systems that just go into
> "hardware sleep" and just put the pin into some pre-programmed mode.
>
> I'm a bit back-and-forth. I didn't mean that some code would actually
> switch the state to "sleep" when we go to sleep, I meant that when
> the system configures "default" mode it should also look up and
> program the "sleep" mode, but this approach with a special property
> is just another way of achieveing the same thing.
>
> But then we should add a whole slew of sleep states.
>
> I was thinking whether we could avoid having a special DT property
> by parsing ahead to states we do not currently use and programming
> that into the sleep mode registers.

Yes, for most scenarios, it can work with the "sleep" state to set
sleep-related config. But for our Spreadtrum platform scenario (I do
not know if there are other platforms need this feature), we can not
select the "sleep" state when pubcp system goes into deep sleep mode
but ap system does not go into deep sleep mode. So I think we still
need these "sleep-bias-pull-up", "sleep-bias-pull-down",
"sleep-input-enable" and "sleep-output-enable" properties.

-- 
Baolin.wang
Best Regards

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
  2017-06-21  8:10           ` Baolin Wang
@ 2017-06-25 22:19                 ` Linus Walleij
  0 siblings, 0 replies; 24+ messages in thread
From: Linus Walleij @ 2017-06-25 22:19 UTC (permalink / raw)
  To: Baolin Wang
  Cc: Mark Rutland, Rob Herring, linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mark Brown

On Wed, Jun 21, 2017 at 10:10 AM, Baolin Wang <baolin.wang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> On 20 June 2017 at 17:31, Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
>> On Tue, Jun 13, 2017 at 5:15 AM, Baolin Wang <baolin.wang-lxIno14LUO0EEoCn2XhGlw@public.gmane.org> wrote:
>>
>>> I forgot one most important reason why we can not use the "sleep" state. As I explained
>>> above, the sleep related configuration will bind with the pin's sleep mode. If we set the
>>> pin's sleep mode as AP_SLEEP, then we can select "sleep" state when AP system goes into
>>> deep sleep mode by issuing "pinctrl_force_sleep()" in pinctrl suspend function.
>>>
>>> But if we set the pin's sleep mode as PUBCP_SLEEP and pubcp system doesn't run linux kernel
>>> (it run another thread OS), then we can not select "sleep" state since the AP system does
>>> not go into deep sleep mode (AP system run linux kernel OS).
>>
>> Allright yes it makes sense, and also there are systems that just go into
>> "hardware sleep" and just put the pin into some pre-programmed mode.
>>
>> I'm a bit back-and-forth. I didn't mean that some code would actually
>> switch the state to "sleep" when we go to sleep, I meant that when
>> the system configures "default" mode it should also look up and
>> program the "sleep" mode, but this approach with a special property
>> is just another way of achieveing the same thing.
>>
>> But then we should add a whole slew of sleep states.
>>
>> I was thinking whether we could avoid having a special DT property
>> by parsing ahead to states we do not currently use and programming
>> that into the sleep mode registers.
>
> Yes, for most scenarios, it can work with the "sleep" state to set
> sleep-related config. But for our Spreadtrum platform scenario (I do
> not know if there are other platforms need this feature), we can not
> select the "sleep" state when pubcp system goes into deep sleep mode
> but ap system does not go into deep sleep mode. So I think we still
> need these "sleep-bias-pull-up", "sleep-bias-pull-down",
> "sleep-input-enable" and "sleep-output-enable" properties.

I don't really mean you should select the "sleep" state.

I meant, as part of setting the "default" state or even the "init"
state, we would inspect the "sleep" state, use those settings, and
program them into the registers at this early point.

Then never touch the registers again, and never really go to the
sleep state by software, just by hardware.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
@ 2017-06-25 22:19                 ` Linus Walleij
  0 siblings, 0 replies; 24+ messages in thread
From: Linus Walleij @ 2017-06-25 22:19 UTC (permalink / raw)
  To: Baolin Wang
  Cc: Mark Rutland, Rob Herring, linux-gpio, devicetree, linux-kernel,
	Mark Brown

On Wed, Jun 21, 2017 at 10:10 AM, Baolin Wang <baolin.wang@linaro.org> wrote:
> On 20 June 2017 at 17:31, Linus Walleij <linus.walleij@linaro.org> wrote:
>> On Tue, Jun 13, 2017 at 5:15 AM, Baolin Wang <baolin.wang@spreadtrum.com> wrote:
>>
>>> I forgot one most important reason why we can not use the "sleep" state. As I explained
>>> above, the sleep related configuration will bind with the pin's sleep mode. If we set the
>>> pin's sleep mode as AP_SLEEP, then we can select "sleep" state when AP system goes into
>>> deep sleep mode by issuing "pinctrl_force_sleep()" in pinctrl suspend function.
>>>
>>> But if we set the pin's sleep mode as PUBCP_SLEEP and pubcp system doesn't run linux kernel
>>> (it run another thread OS), then we can not select "sleep" state since the AP system does
>>> not go into deep sleep mode (AP system run linux kernel OS).
>>
>> Allright yes it makes sense, and also there are systems that just go into
>> "hardware sleep" and just put the pin into some pre-programmed mode.
>>
>> I'm a bit back-and-forth. I didn't mean that some code would actually
>> switch the state to "sleep" when we go to sleep, I meant that when
>> the system configures "default" mode it should also look up and
>> program the "sleep" mode, but this approach with a special property
>> is just another way of achieveing the same thing.
>>
>> But then we should add a whole slew of sleep states.
>>
>> I was thinking whether we could avoid having a special DT property
>> by parsing ahead to states we do not currently use and programming
>> that into the sleep mode registers.
>
> Yes, for most scenarios, it can work with the "sleep" state to set
> sleep-related config. But for our Spreadtrum platform scenario (I do
> not know if there are other platforms need this feature), we can not
> select the "sleep" state when pubcp system goes into deep sleep mode
> but ap system does not go into deep sleep mode. So I think we still
> need these "sleep-bias-pull-up", "sleep-bias-pull-down",
> "sleep-input-enable" and "sleep-output-enable" properties.

I don't really mean you should select the "sleep" state.

I meant, as part of setting the "default" state or even the "init"
state, we would inspect the "sleep" state, use those settings, and
program them into the registers at this early point.

Then never touch the registers again, and never really go to the
sleep state by software, just by hardware.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
  2017-06-25 22:19                 ` Linus Walleij
  (?)
@ 2017-06-27  7:59                 ` Baolin Wang
       [not found]                   ` <CAMz4kuJigdhbV5+J1CcqP6zb7pqi9HaW=dxe_rsNi-=RsQ70vA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  -1 siblings, 1 reply; 24+ messages in thread
From: Baolin Wang @ 2017-06-27  7:59 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mark Rutland, Rob Herring, linux-gpio, devicetree, linux-kernel,
	Mark Brown

On 26 June 2017 at 06:19, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Wed, Jun 21, 2017 at 10:10 AM, Baolin Wang <baolin.wang@linaro.org> wrote:
>> On 20 June 2017 at 17:31, Linus Walleij <linus.walleij@linaro.org> wrote:
>>> On Tue, Jun 13, 2017 at 5:15 AM, Baolin Wang <baolin.wang@spreadtrum.com> wrote:
>>>
>>>> I forgot one most important reason why we can not use the "sleep" state. As I explained
>>>> above, the sleep related configuration will bind with the pin's sleep mode. If we set the
>>>> pin's sleep mode as AP_SLEEP, then we can select "sleep" state when AP system goes into
>>>> deep sleep mode by issuing "pinctrl_force_sleep()" in pinctrl suspend function.
>>>>
>>>> But if we set the pin's sleep mode as PUBCP_SLEEP and pubcp system doesn't run linux kernel
>>>> (it run another thread OS), then we can not select "sleep" state since the AP system does
>>>> not go into deep sleep mode (AP system run linux kernel OS).
>>>
>>> Allright yes it makes sense, and also there are systems that just go into
>>> "hardware sleep" and just put the pin into some pre-programmed mode.
>>>
>>> I'm a bit back-and-forth. I didn't mean that some code would actually
>>> switch the state to "sleep" when we go to sleep, I meant that when
>>> the system configures "default" mode it should also look up and
>>> program the "sleep" mode, but this approach with a special property
>>> is just another way of achieveing the same thing.
>>>
>>> But then we should add a whole slew of sleep states.
>>>
>>> I was thinking whether we could avoid having a special DT property
>>> by parsing ahead to states we do not currently use and programming
>>> that into the sleep mode registers.
>>
>> Yes, for most scenarios, it can work with the "sleep" state to set
>> sleep-related config. But for our Spreadtrum platform scenario (I do
>> not know if there are other platforms need this feature), we can not
>> select the "sleep" state when pubcp system goes into deep sleep mode
>> but ap system does not go into deep sleep mode. So I think we still
>> need these "sleep-bias-pull-up", "sleep-bias-pull-down",
>> "sleep-input-enable" and "sleep-output-enable" properties.
>
> I don't really mean you should select the "sleep" state.
>
> I meant, as part of setting the "default" state or even the "init"
> state, we would inspect the "sleep" state, use those settings, and
> program them into the registers at this early point.

I understood your points. But we can not program all into the
registers at one early point, sometimes these sleep-related configs
need depend on some conditions in users' drivers, like on condition 1:
driver need to set one pin as input-enable when specified system goes
into deep sleep, on condition 2: driver need set this pin as
output-enable when specified system goes into deep sleep. So I still
think it is better if we introduce some standard sleep related
configs.

>
> Then never touch the registers again, and never really go to the
> sleep state by software, just by hardware.
>
> Yours,
> Linus Walleij



-- 
Baolin.wang
Best Regards

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
  2017-06-27  7:59                 ` Baolin Wang
@ 2017-07-12 12:04                       ` Linus Walleij
  0 siblings, 0 replies; 24+ messages in thread
From: Linus Walleij @ 2017-07-12 12:04 UTC (permalink / raw)
  To: Baolin Wang
  Cc: Mark Rutland, Rob Herring, linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mark Brown

On Tue, Jun 27, 2017 at 9:59 AM, Baolin Wang <baolin.wang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> On 26 June 2017 at 06:19, Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:

>> I meant, as part of setting the "default" state or even the "init"
>> state, we would inspect the "sleep" state, use those settings, and
>> program them into the registers at this early point.
>
> I understood your points. But we can not program all into the
> registers at one early point, sometimes these sleep-related configs
> need depend on some conditions in users' drivers, like on condition 1:
> driver need to set one pin as input-enable when specified system goes
> into deep sleep, on condition 2: driver need set this pin as
> output-enable when specified system goes into deep sleep. So I still
> think it is better if we introduce some standard sleep related
> configs.

So you mean you need special runtime states to set up sleep states?

Do you have an example of how this would look in the device tree?

I am sorry but I have a hard time following the use case :(

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
@ 2017-07-12 12:04                       ` Linus Walleij
  0 siblings, 0 replies; 24+ messages in thread
From: Linus Walleij @ 2017-07-12 12:04 UTC (permalink / raw)
  To: Baolin Wang
  Cc: Mark Rutland, Rob Herring, linux-gpio, devicetree, linux-kernel,
	Mark Brown

On Tue, Jun 27, 2017 at 9:59 AM, Baolin Wang <baolin.wang@linaro.org> wrote:
> On 26 June 2017 at 06:19, Linus Walleij <linus.walleij@linaro.org> wrote:

>> I meant, as part of setting the "default" state or even the "init"
>> state, we would inspect the "sleep" state, use those settings, and
>> program them into the registers at this early point.
>
> I understood your points. But we can not program all into the
> registers at one early point, sometimes these sleep-related configs
> need depend on some conditions in users' drivers, like on condition 1:
> driver need to set one pin as input-enable when specified system goes
> into deep sleep, on condition 2: driver need set this pin as
> output-enable when specified system goes into deep sleep. So I still
> think it is better if we introduce some standard sleep related
> configs.

So you mean you need special runtime states to set up sleep states?

Do you have an example of how this would look in the device tree?

I am sorry but I have a hard time following the use case :(

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2017-07-12 12:04 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-05 12:11 [PATCH v2 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller Baolin Wang
2017-06-05 12:11 ` Baolin Wang
2017-06-05 12:11 ` [PATCH v2 2/2] pinctrl: sprd: Add Spreadtrum pin control driver Baolin Wang
2017-06-05 12:11   ` Baolin Wang
2017-06-05 19:07   ` kbuild test robot
2017-06-05 19:07     ` kbuild test robot
2017-06-06  7:20     ` Baolin Wang
2017-06-06  7:20       ` Baolin Wang
2017-06-06  7:40       ` Baolin Wang
2017-06-06  7:40         ` Baolin Wang
2017-06-09 11:00 ` [PATCH v2 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller Linus Walleij
2017-06-12  6:07   ` Baolin Wang
2017-06-12  6:07     ` Baolin Wang
2017-06-13  3:15     ` Baolin Wang
     [not found]       ` <20170613031547.GA29679-lxIno14LUO0EEoCn2XhGlw@public.gmane.org>
2017-06-20  9:31         ` Linus Walleij
2017-06-20  9:31           ` Linus Walleij
2017-06-21  8:10           ` Baolin Wang
     [not found]             ` <CAMz4ku+jZ-S6sBL=ib++j+ooqweU9UC+MTgFca7ScrQiJDeZVQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-06-25 22:19               ` Linus Walleij
2017-06-25 22:19                 ` Linus Walleij
2017-06-27  7:59                 ` Baolin Wang
     [not found]                   ` <CAMz4kuJigdhbV5+J1CcqP6zb7pqi9HaW=dxe_rsNi-=RsQ70vA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-07-12 12:04                     ` Linus Walleij
2017-07-12 12:04                       ` Linus Walleij
2017-06-20  9:10     ` Linus Walleij
2017-06-21  2:35       ` Baolin Wang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.