All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
@ 2017-05-27  5:56 ` Baolin Wang
  0 siblings, 0 replies; 13+ messages in thread
From: Baolin Wang @ 2017-05-27  5:56 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>
---
 .../devicetree/bindings/pinctrl/sprd,pinctrl.txt   |   31 ++++++++++++++++++++
 .../bindings/pinctrl/sprd,sc9860-pinctrl.txt       |   26 ++++++++++++++++
 2 files changed, 57 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..2edf176
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/sprd,pinctrl.txt
@@ -0,0 +1,31 @@
+* 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 feilds with one bit or several bits to
+configurate for some global common configuration, such as domain
+pad driving level, system control select and so on. We recognise
+every feild 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 configurate this feild (pin).
+
+The second block comprises some common registers which have unified
+register definition, and each register described one pin is used
+to configurate pin sleep mode and function select.
+
+The last block comprises some misc registers which also have unified
+register definition, and each register described one pin is used to
+configurate drive strength, pull up/down and so on.
+
+This driver supports the generic pin multiplexing and configuration
+bindings. For details on each properties, you can refer to
+./pinctrl-bindings.txt.
+
+Required properties for Spreadtrum pin controller:
+- compatible: "sprd,<soc>-pinctrl"
+  Please refer to each sprd,<soc>-pinctrl.txt binding doc for supported SoCs.
+
+Required properties for pin configuration node:
+- sprd,pins: each entry consists of 2 integers and represents the pin
+  id and config setting for one pin.
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..26fba5b
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt
@@ -0,0 +1,26 @@
+* 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.
+- sprd,pins: two integers array, represents a group of pins id and config
+  setting. The format is sprd,pins = <PIN_ID CONFIG>, PIN_ID can be found
+  from pinctrl-sprd-sc9860.c file or spec file, CONFIG is the pad setting
+  value like pull-up for this pin.
+
+Example:
+pin_controller: pinctrl@402a0000 {
+	compatible = "sprd,sc9860-pinctrl";
+	reg = <0x402a0000 0x10000>;
+
+	vio_sd0_ms_0: sd0_ms0 {
+		sprd,pins = <8 0x1>;
+	};
+
+	vbc_iis0_0: iis0_c {
+		sprd,pins = <34 0xc>;
+	};
+};
-- 
1.7.9.5


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

* [PATCH 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
@ 2017-05-27  5:56 ` Baolin Wang
  0 siblings, 0 replies; 13+ messages in thread
From: Baolin Wang @ 2017-05-27  5:56 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>
---
 .../devicetree/bindings/pinctrl/sprd,pinctrl.txt   |   31 ++++++++++++++++++++
 .../bindings/pinctrl/sprd,sc9860-pinctrl.txt       |   26 ++++++++++++++++
 2 files changed, 57 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..2edf176
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/sprd,pinctrl.txt
@@ -0,0 +1,31 @@
+* 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 feilds with one bit or several bits to
+configurate for some global common configuration, such as domain
+pad driving level, system control select and so on. We recognise
+every feild 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 configurate this feild (pin).
+
+The second block comprises some common registers which have unified
+register definition, and each register described one pin is used
+to configurate pin sleep mode and function select.
+
+The last block comprises some misc registers which also have unified
+register definition, and each register described one pin is used to
+configurate drive strength, pull up/down and so on.
+
+This driver supports the generic pin multiplexing and configuration
+bindings. For details on each properties, you can refer to
+./pinctrl-bindings.txt.
+
+Required properties for Spreadtrum pin controller:
+- compatible: "sprd,<soc>-pinctrl"
+  Please refer to each sprd,<soc>-pinctrl.txt binding doc for supported SoCs.
+
+Required properties for pin configuration node:
+- sprd,pins: each entry consists of 2 integers and represents the pin
+  id and config setting for one pin.
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..26fba5b
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt
@@ -0,0 +1,26 @@
+* 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.
+- sprd,pins: two integers array, represents a group of pins id and config
+  setting. The format is sprd,pins = <PIN_ID CONFIG>, PIN_ID can be found
+  from pinctrl-sprd-sc9860.c file or spec file, CONFIG is the pad setting
+  value like pull-up for this pin.
+
+Example:
+pin_controller: pinctrl@402a0000 {
+	compatible = "sprd,sc9860-pinctrl";
+	reg = <0x402a0000 0x10000>;
+
+	vio_sd0_ms_0: sd0_ms0 {
+		sprd,pins = <8 0x1>;
+	};
+
+	vbc_iis0_0: iis0_c {
+		sprd,pins = <34 0xc>;
+	};
+};
-- 
1.7.9.5

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

* [PATCH 2/2] pinctrl: sprd: Add Spreadtrum pin control driver
  2017-05-27  5:56 ` Baolin Wang
@ 2017-05-27  5:56   ` Baolin Wang
  -1 siblings, 0 replies; 13+ messages in thread
From: Baolin Wang @ 2017-05-27  5:56 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>
---
 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        |  716 ++++++++++++++++++++
 drivers/pinctrl/sprd/pinctrl-sprd.h        |   67 ++
 7 files changed, 1776 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..726780d
--- /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..049fce8
--- /dev/null
+++ b/drivers/pinctrl/sprd/pinctrl-sprd.c
@@ -0,0 +1,716 @@
+/*
+ * 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/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/slab.h>
+
+#include "../core.h"
+#include "../pinmux.h"
+#include "pinctrl-sprd.h"
+
+#define PINCTRL_BIT_MASK(width)		(~(~0UL << (width)))
+#define PINCTRL_REG_OFFSET		0x20
+#define PINCTRL_REG_MISC_OFFSET		0x4020
+#define SPRD_PIN_SIZE			8
+
+/**
+ * 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
+ * @config: pin configuration values
+ */
+struct sprd_pin {
+	const char *name;
+	unsigned int number;
+	enum pin_type type;
+	unsigned long reg;
+	unsigned long bit_offset;
+	unsigned long bit_width;
+	unsigned long config;
+};
+
+/**
+ * struct sprd_pin_group: represent one group's description
+ * @name: group name
+ * @npins: pin numbers of this group
+ * @pins: pointer to pins array
+ * @configs: pointer to pins configuration array
+ */
+struct sprd_pin_group {
+	const char *name;
+	unsigned int npins;
+	unsigned int *pins;
+	unsigned long *configs;
+};
+
+/**
+ * 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
+ */
+struct sprd_pinctrl_soc_info {
+	struct sprd_pin_group *groups;
+	unsigned int ngroups;
+	struct sprd_pin *pins;
+	unsigned int npins;
+};
+
+/**
+ * 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 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;
+	struct pinctrl_map *new_map;
+	struct device_node *parent;
+	int map_num;
+
+	grp = sprd_pinctrl_find_group_by_name(pctl, np->name);
+	if (!grp) {
+		pr_err("unable to find group for node %s\n", np->name);
+		return -EINVAL;
+	}
+
+	map_num = 1;
+	new_map = kmalloc(sizeof(struct pinctrl_map) * map_num, GFP_KERNEL);
+	if (!new_map)
+		return -ENOMEM;
+
+	*map = new_map;
+	*num_maps = map_num;
+
+	parent = of_get_parent(np);
+	if (!parent) {
+		kfree(new_map);
+		return -EINVAL;
+	}
+
+	/* create mux map */
+	if (parent != pctl->dev->of_node) {
+		new_map[0].type = PIN_MAP_TYPE_MUX_GROUP;
+		new_map[0].data.mux.function = parent->name;
+		new_map[0].data.mux.group = np->name;
+
+		of_node_put(parent);
+		return 0;
+	}
+
+	of_node_put(parent);
+
+	if (grp->npins == 1) {
+		unsigned int pin_id = grp->pins[0];
+
+		/* create config map for one pin */
+		new_map->type = PIN_MAP_TYPE_CONFIGS_PIN;
+		new_map->data.configs.group_or_pin =
+			pin_get_name(pctldev, pin_id);
+		new_map->data.configs.configs = grp->configs;
+		new_map->data.configs.num_configs = 1;
+	} else {
+		/* create config map for group */
+		new_map->type = PIN_MAP_TYPE_CONFIGS_GROUP;
+		new_map->data.configs.group_or_pin = grp->name;
+		new_map->data.configs.num_configs = grp->npins;
+		new_map->data.configs.configs = grp->configs;
+	}
+
+	return 0;
+}
+
+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 void sprd_dt_free_map(struct pinctrl_dev *pctldev,
+			     struct pinctrl_map *map, unsigned int num_maps)
+{
+	kfree(map);
+}
+
+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 = sprd_dt_free_map,
+};
+
+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 grp_pins = grp->npins;
+	struct function_desc *func;
+	unsigned long reg;
+	int i;
+
+	if (group_selector > info->ngroups)
+		return -EINVAL;
+
+	func = pinmux_generic_get_function(pctldev, func_selector);
+	if (!func)
+		return -EINVAL;
+
+	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->type == GLOBAL_CTRL_PIN) {
+			reg = readl((void __iomem *)pin->reg);
+			reg |= (grp->configs[i] &
+				PINCTRL_BIT_MASK(pin->bit_width))
+				<< pin->bit_offset;
+			writel(reg, (void __iomem *)pin->reg);
+		} else {
+			writel(grp->configs[i], (void __iomem *)pin->reg);
+		}
+
+		pin->config = grp->configs[i];
+	}
+
+	return 0;
+}
+
+static const struct pinmux_ops sprd_pmx_ops = {
+	.get_functions_count = pinmux_generic_get_function_count,
+	.get_function_name = pinmux_generic_get_function_name,
+	.get_function_groups = pinmux_generic_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 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++) {
+		if (pin->type == GLOBAL_CTRL_PIN) {
+			reg = readl((void __iomem *)pin->reg);
+			reg &= ~(PINCTRL_BIT_MASK(pin->bit_width)
+				<< pin->bit_offset);
+			reg |= (configs[i] & PINCTRL_BIT_MASK(pin->bit_width))
+				<< pin->bit_offset;
+			writel(reg, (void __iomem *)pin->reg);
+		} else {
+			writel(configs[i], (void __iomem *)pin->reg);
+		}
+		pin->config = configs[i];
+	}
+
+	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];
+	if (grp->npins != num_configs)
+		return -EINVAL;
+
+	for (i = 0; i < grp->npins; i++, configs++) {
+		unsigned int pin_id = grp->pins[i];
+
+		ret = sprd_pinconf_set(pctldev, pin_id, configs, 1);
+		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 struct pinctrl_desc sprd_pinctrl_desc = {
+	.pctlops = &sprd_pctrl_ops,
+	.pmxops = &sprd_pmx_ops,
+	.confops = &sprd_pinconf_ops,
+	.owner = THIS_MODULE,
+};
+
+static int sprd_pinctrl_parse_groups(struct device_node *np,
+				     struct sprd_pinctrl *sprd_pctl,
+				     struct sprd_pin_group *grp)
+{
+	int i, size, pin_cnt;
+	const __be32 *list;
+
+	list = of_get_property(np, "sprd,pins", &size);
+	if (!size || !list) {
+		dev_err(sprd_pctl->dev, "no pins property in node %s\n",
+			np->full_name);
+		return -EINVAL;
+	}
+
+	pin_cnt = size / SPRD_PIN_SIZE;
+	grp->name = np->name;
+	grp->npins = pin_cnt;
+	grp->pins = devm_kzalloc(sprd_pctl->dev, grp->npins *
+				 sizeof(unsigned int), GFP_KERNEL);
+	if (!grp->pins)
+		return -ENOMEM;
+
+	grp->configs = devm_kzalloc(sprd_pctl->dev, grp->npins *
+				    sizeof(unsigned long), GFP_KERNEL);
+	if (!grp->configs)
+		return -ENOMEM;
+
+	for (i = 0; i < grp->npins; i++) {
+		grp->pins[i] = be32_to_cpu(*list++);
+		grp->configs[i] = be32_to_cpu(*list++);
+	}
+
+	for (i = 0; i < grp->npins; i++) {
+		dev_dbg(sprd_pctl->dev, "Group[%s] contains [%d] pins: "
+			"pin id = %d, pin config = %ld\n",
+			grp->name, grp->npins, grp->pins[i],
+			grp->configs[i]);
+	}
+
+	return 0;
+}
+
+static unsigned int sprd_pinctrl_get_groups(struct device_node *np)
+{
+	struct device_node *child;
+	unsigned int group_cnt, cnt;
+
+	group_cnt = of_get_child_count(np);
+
+	for_each_child_of_node(np, child) {
+		cnt = of_get_child_count(child);
+		if (cnt > 0)
+			group_cnt += cnt - 1;
+	}
+
+	return group_cnt;
+}
+
+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, *sub_child;
+	struct sprd_pin_group *grp;
+	int ret, num_groups;
+
+	if (!np)
+		return -ENODEV;
+
+	info->ngroups = sprd_pinctrl_get_groups(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;
+
+	grp = info->groups;
+	for_each_child_of_node(np, child) {
+		num_groups = of_get_child_count(child);
+
+		if (num_groups == 0) {
+			ret = sprd_pinctrl_parse_groups(child, sprd_pctl, grp);
+			if (ret)
+				return ret;
+
+			grp++;
+		} else {
+			const char **temp;
+			const char **groups = devm_kzalloc(sprd_pctl->dev,
+						num_groups * sizeof(char *),
+						GFP_KERNEL);
+			if (!groups)
+				return -ENOMEM;
+
+			temp = groups;
+			for_each_child_of_node(child, sub_child) {
+				ret = sprd_pinctrl_parse_groups(sub_child,
+								sprd_pctl, grp);
+				if (ret)
+					return ret;
+
+				*temp++ = grp->name;
+				grp++;
+			}
+
+			ret = pinmux_generic_add_function(sprd_pctl->pctl,
+							  child->name,
+							  groups,
+							  num_groups,
+							  sprd_pctl);
+			if (ret)
+				return ret;
+		}
+	}
+
+	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..31a43fe
--- /dev/null
+++ b/drivers/pinctrl/sprd/pinctrl-sprd.h
@@ -0,0 +1,67 @@
+/*
+ * 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 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_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] 13+ messages in thread

* [PATCH 2/2] pinctrl: sprd: Add Spreadtrum pin control driver
@ 2017-05-27  5:56   ` Baolin Wang
  0 siblings, 0 replies; 13+ messages in thread
From: Baolin Wang @ 2017-05-27  5:56 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>
---
 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        |  716 ++++++++++++++++++++
 drivers/pinctrl/sprd/pinctrl-sprd.h        |   67 ++
 7 files changed, 1776 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..726780d
--- /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..049fce8
--- /dev/null
+++ b/drivers/pinctrl/sprd/pinctrl-sprd.c
@@ -0,0 +1,716 @@
+/*
+ * 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/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/slab.h>
+
+#include "../core.h"
+#include "../pinmux.h"
+#include "pinctrl-sprd.h"
+
+#define PINCTRL_BIT_MASK(width)		(~(~0UL << (width)))
+#define PINCTRL_REG_OFFSET		0x20
+#define PINCTRL_REG_MISC_OFFSET		0x4020
+#define SPRD_PIN_SIZE			8
+
+/**
+ * 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
+ * @config: pin configuration values
+ */
+struct sprd_pin {
+	const char *name;
+	unsigned int number;
+	enum pin_type type;
+	unsigned long reg;
+	unsigned long bit_offset;
+	unsigned long bit_width;
+	unsigned long config;
+};
+
+/**
+ * struct sprd_pin_group: represent one group's description
+ * @name: group name
+ * @npins: pin numbers of this group
+ * @pins: pointer to pins array
+ * @configs: pointer to pins configuration array
+ */
+struct sprd_pin_group {
+	const char *name;
+	unsigned int npins;
+	unsigned int *pins;
+	unsigned long *configs;
+};
+
+/**
+ * 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
+ */
+struct sprd_pinctrl_soc_info {
+	struct sprd_pin_group *groups;
+	unsigned int ngroups;
+	struct sprd_pin *pins;
+	unsigned int npins;
+};
+
+/**
+ * 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 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;
+	struct pinctrl_map *new_map;
+	struct device_node *parent;
+	int map_num;
+
+	grp = sprd_pinctrl_find_group_by_name(pctl, np->name);
+	if (!grp) {
+		pr_err("unable to find group for node %s\n", np->name);
+		return -EINVAL;
+	}
+
+	map_num = 1;
+	new_map = kmalloc(sizeof(struct pinctrl_map) * map_num, GFP_KERNEL);
+	if (!new_map)
+		return -ENOMEM;
+
+	*map = new_map;
+	*num_maps = map_num;
+
+	parent = of_get_parent(np);
+	if (!parent) {
+		kfree(new_map);
+		return -EINVAL;
+	}
+
+	/* create mux map */
+	if (parent != pctl->dev->of_node) {
+		new_map[0].type = PIN_MAP_TYPE_MUX_GROUP;
+		new_map[0].data.mux.function = parent->name;
+		new_map[0].data.mux.group = np->name;
+
+		of_node_put(parent);
+		return 0;
+	}
+
+	of_node_put(parent);
+
+	if (grp->npins == 1) {
+		unsigned int pin_id = grp->pins[0];
+
+		/* create config map for one pin */
+		new_map->type = PIN_MAP_TYPE_CONFIGS_PIN;
+		new_map->data.configs.group_or_pin =
+			pin_get_name(pctldev, pin_id);
+		new_map->data.configs.configs = grp->configs;
+		new_map->data.configs.num_configs = 1;
+	} else {
+		/* create config map for group */
+		new_map->type = PIN_MAP_TYPE_CONFIGS_GROUP;
+		new_map->data.configs.group_or_pin = grp->name;
+		new_map->data.configs.num_configs = grp->npins;
+		new_map->data.configs.configs = grp->configs;
+	}
+
+	return 0;
+}
+
+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 void sprd_dt_free_map(struct pinctrl_dev *pctldev,
+			     struct pinctrl_map *map, unsigned int num_maps)
+{
+	kfree(map);
+}
+
+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 = sprd_dt_free_map,
+};
+
+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 grp_pins = grp->npins;
+	struct function_desc *func;
+	unsigned long reg;
+	int i;
+
+	if (group_selector > info->ngroups)
+		return -EINVAL;
+
+	func = pinmux_generic_get_function(pctldev, func_selector);
+	if (!func)
+		return -EINVAL;
+
+	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->type == GLOBAL_CTRL_PIN) {
+			reg = readl((void __iomem *)pin->reg);
+			reg |= (grp->configs[i] &
+				PINCTRL_BIT_MASK(pin->bit_width))
+				<< pin->bit_offset;
+			writel(reg, (void __iomem *)pin->reg);
+		} else {
+			writel(grp->configs[i], (void __iomem *)pin->reg);
+		}
+
+		pin->config = grp->configs[i];
+	}
+
+	return 0;
+}
+
+static const struct pinmux_ops sprd_pmx_ops = {
+	.get_functions_count = pinmux_generic_get_function_count,
+	.get_function_name = pinmux_generic_get_function_name,
+	.get_function_groups = pinmux_generic_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 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++) {
+		if (pin->type == GLOBAL_CTRL_PIN) {
+			reg = readl((void __iomem *)pin->reg);
+			reg &= ~(PINCTRL_BIT_MASK(pin->bit_width)
+				<< pin->bit_offset);
+			reg |= (configs[i] & PINCTRL_BIT_MASK(pin->bit_width))
+				<< pin->bit_offset;
+			writel(reg, (void __iomem *)pin->reg);
+		} else {
+			writel(configs[i], (void __iomem *)pin->reg);
+		}
+		pin->config = configs[i];
+	}
+
+	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];
+	if (grp->npins != num_configs)
+		return -EINVAL;
+
+	for (i = 0; i < grp->npins; i++, configs++) {
+		unsigned int pin_id = grp->pins[i];
+
+		ret = sprd_pinconf_set(pctldev, pin_id, configs, 1);
+		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 struct pinctrl_desc sprd_pinctrl_desc = {
+	.pctlops = &sprd_pctrl_ops,
+	.pmxops = &sprd_pmx_ops,
+	.confops = &sprd_pinconf_ops,
+	.owner = THIS_MODULE,
+};
+
+static int sprd_pinctrl_parse_groups(struct device_node *np,
+				     struct sprd_pinctrl *sprd_pctl,
+				     struct sprd_pin_group *grp)
+{
+	int i, size, pin_cnt;
+	const __be32 *list;
+
+	list = of_get_property(np, "sprd,pins", &size);
+	if (!size || !list) {
+		dev_err(sprd_pctl->dev, "no pins property in node %s\n",
+			np->full_name);
+		return -EINVAL;
+	}
+
+	pin_cnt = size / SPRD_PIN_SIZE;
+	grp->name = np->name;
+	grp->npins = pin_cnt;
+	grp->pins = devm_kzalloc(sprd_pctl->dev, grp->npins *
+				 sizeof(unsigned int), GFP_KERNEL);
+	if (!grp->pins)
+		return -ENOMEM;
+
+	grp->configs = devm_kzalloc(sprd_pctl->dev, grp->npins *
+				    sizeof(unsigned long), GFP_KERNEL);
+	if (!grp->configs)
+		return -ENOMEM;
+
+	for (i = 0; i < grp->npins; i++) {
+		grp->pins[i] = be32_to_cpu(*list++);
+		grp->configs[i] = be32_to_cpu(*list++);
+	}
+
+	for (i = 0; i < grp->npins; i++) {
+		dev_dbg(sprd_pctl->dev, "Group[%s] contains [%d] pins: "
+			"pin id = %d, pin config = %ld\n",
+			grp->name, grp->npins, grp->pins[i],
+			grp->configs[i]);
+	}
+
+	return 0;
+}
+
+static unsigned int sprd_pinctrl_get_groups(struct device_node *np)
+{
+	struct device_node *child;
+	unsigned int group_cnt, cnt;
+
+	group_cnt = of_get_child_count(np);
+
+	for_each_child_of_node(np, child) {
+		cnt = of_get_child_count(child);
+		if (cnt > 0)
+			group_cnt += cnt - 1;
+	}
+
+	return group_cnt;
+}
+
+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, *sub_child;
+	struct sprd_pin_group *grp;
+	int ret, num_groups;
+
+	if (!np)
+		return -ENODEV;
+
+	info->ngroups = sprd_pinctrl_get_groups(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;
+
+	grp = info->groups;
+	for_each_child_of_node(np, child) {
+		num_groups = of_get_child_count(child);
+
+		if (num_groups == 0) {
+			ret = sprd_pinctrl_parse_groups(child, sprd_pctl, grp);
+			if (ret)
+				return ret;
+
+			grp++;
+		} else {
+			const char **temp;
+			const char **groups = devm_kzalloc(sprd_pctl->dev,
+						num_groups * sizeof(char *),
+						GFP_KERNEL);
+			if (!groups)
+				return -ENOMEM;
+
+			temp = groups;
+			for_each_child_of_node(child, sub_child) {
+				ret = sprd_pinctrl_parse_groups(sub_child,
+								sprd_pctl, grp);
+				if (ret)
+					return ret;
+
+				*temp++ = grp->name;
+				grp++;
+			}
+
+			ret = pinmux_generic_add_function(sprd_pctl->pctl,
+							  child->name,
+							  groups,
+							  num_groups,
+							  sprd_pctl);
+			if (ret)
+				return ret;
+		}
+	}
+
+	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..31a43fe
--- /dev/null
+++ b/drivers/pinctrl/sprd/pinctrl-sprd.h
@@ -0,0 +1,67 @@
+/*
+ * 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 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_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] 13+ messages in thread

* Re: [PATCH 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
  2017-05-27  5:56 ` Baolin Wang
  (?)
  (?)
@ 2017-05-29 16:18 ` Linus Walleij
       [not found]   ` <CACRpkdZFUDrfoyvk-CramNP2OVwVAazVsw3S-wCayx8HP6cSZQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  -1 siblings, 1 reply; 13+ messages in thread
From: Linus Walleij @ 2017-05-29 16:18 UTC (permalink / raw)
  To: Baolin Wang
  Cc: Mark Rutland, Rob Herring, linux-gpio, devicetree, linux-kernel,
	Mark Brown, Baolin Wang

On Sat, May 27, 2017 at 7:56 AM, 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>
(...)

> +* 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 feilds with one bit or several bits to

feilds -> fields

Do you mean "bitfields", i.e a few bits inside a configuration register
word?

> +configurate for some global common configuration, such as domain

configurate -> configure

> +pad driving level, system control select

Actually I do not understand at all what "domain pad driving level"
or "system control select" means, those are very generic terms.
Can you describe precisely what it means? What domain? What
is a domain pad? What kind of system control? What is it selecting
between?

>  and so on. We recognise
> +every feild comprising one bit or several bits in one global control

feild -> field

> +register as one pin, thus we should record every pin's bit offset,
> +bit width and register offset to configurate this feild (pin).

feild -> field

> +The second block comprises some common registers which have unified
> +register definition, and each register described one pin is used
> +to configurate pin sleep mode and function select.

OK

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

configurate -> configure

OK that is pin configuration.

> +This driver supports the generic pin multiplexing and configuration
> +bindings. For details on each properties, you can refer to
> +./pinctrl-bindings.txt.

Do not talk about the driver in the bindings. Talk about the bindings per
se, these bindings are supposed to be OS neutral.

> +Required properties for Spreadtrum pin controller:
> +- compatible: "sprd,<soc>-pinctrl"
> +  Please refer to each sprd,<soc>-pinctrl.txt binding doc for supported SoCs.
> +
> +Required properties for pin configuration node:
> +- sprd,pins: each entry consists of 2 integers and represents the pin
> +  id and config setting for one pin.

Do not use the custom property "sprd,pins" for this, if you want to set up pin
muxing with a magic value use the generic binding "pinmux", see:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt?id=8d5e7c5df0a6c442373628be5221321172b1badf

But consider using groups+functions for defining multiplexing instead.

But please do NOT combine pin configuration into a magic value. Use
the generic pin control bindings, er have bindings for all kinds of pin
config, and using them makes the driver much more readable for
humans.

I understand that you may have a lot of magic number tables around that
you are using today, but it is necessary to decompose that into the proper
generic pin configuration properties to make it usable.

> +++ b/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt
> @@ -0,0 +1,26 @@
> +* 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.
> +- sprd,pins: two integers array, represents a group of pins id and config
> +  setting. The format is sprd,pins = <PIN_ID CONFIG>, PIN_ID can be found
> +  from pinctrl-sprd-sc9860.c file or spec file, CONFIG is the pad setting
> +  value like pull-up for this pin.

Same comments.

> +Example:
> +pin_controller: pinctrl@402a0000 {
> +       compatible = "sprd,sc9860-pinctrl";
> +       reg = <0x402a0000 0x10000>;
> +
> +       vio_sd0_ms_0: sd0_ms0 {
> +               sprd,pins = <8 0x1>;
> +       };
> +
> +       vbc_iis0_0: iis0_c {
> +               sprd,pins = <34 0xc>;
> +       };
> +};

Magic numbers are very hard to understand. Compare to this
from Qualcomm APQ8064 using just standard bindings:

pinmux@800000 {
        i2c4_pins: i2c4_pinmux {
               pins = "gpio12", "gpio13";
               function = "gsbi4";
               bias-disable;
        };

        spi_pins: spi_pins {
               mux {
                      pins = "gpio18", "gpio19", "gpio21";
                      function = "gsbi5";
                      drive-strength = <10>;
                      bias-none;
                };
        };
};

Please try go get rid of the magic numbers and get to use pins, function,
drive-strength bias etc from the standard bindings. We also have a lot
of helper code available to use this.

Yours,
Linus Walleij

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

* Re: [PATCH 2/2] pinctrl: sprd: Add Spreadtrum pin control driver
  2017-05-27  5:56   ` Baolin Wang
@ 2017-05-29 16:28       ` Linus Walleij
  -1 siblings, 0 replies; 13+ messages in thread
From: Linus Walleij @ 2017-05-29 16:28 UTC (permalink / raw)
  To: Baolin Wang
  Cc: Mark Rutland, Rob Herring, linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mark Brown, Baolin Wang

On Sat, May 27, 2017 at 7:56 AM, Baolin Wang <baolin.wang-lxIno14LUO0EEoCn2XhGlw@public.gmane.org> wrote:

> This patch adds the pin control driver for Spreadtrum SC9860 platform.
>
> Signed-off-by: Baolin Wang <baolin.wang-lxIno14LUO0EEoCn2XhGlw@public.gmane.org>

Overall I see that you want to store functions and groups in the device tree
using the current helpers from Tony. That is OK if you want to take that
approach, though I prefer the pins/groups/function encoding in plaintext.

But when it comes to pin config:

> +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 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++) {
> +               if (pin->type == GLOBAL_CTRL_PIN) {
> +                       reg = readl((void __iomem *)pin->reg);
> +                       reg &= ~(PINCTRL_BIT_MASK(pin->bit_width)
> +                               << pin->bit_offset);
> +                       reg |= (configs[i] & PINCTRL_BIT_MASK(pin->bit_width))
> +                               << pin->bit_offset;
> +                       writel(reg, (void __iomem *)pin->reg);
> +               } else {
> +                       writel(configs[i], (void __iomem *)pin->reg);
> +               }
> +               pin->config = configs[i];
> +       }
> +
> +       return 0;
> +}

This is just hammering the register values, you have effectively defined your
register layout as your device tree ABI.

Please don't do this, please use genric pin config and use the approach
other drivers take with explicit strings encoding the pin configuration.

Even pinctrl-single that maintain quite a bit of muxing data in the device
tree still use the generic pin config API, see:
drivers/pinctrl/pinctrl-single.c
pcs_pinconf_get(), pcs_pinconf_set()

Same for group config.

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] 13+ messages in thread

* Re: [PATCH 2/2] pinctrl: sprd: Add Spreadtrum pin control driver
@ 2017-05-29 16:28       ` Linus Walleij
  0 siblings, 0 replies; 13+ messages in thread
From: Linus Walleij @ 2017-05-29 16:28 UTC (permalink / raw)
  To: Baolin Wang
  Cc: Mark Rutland, Rob Herring, linux-gpio, devicetree, linux-kernel,
	Mark Brown, Baolin Wang

On Sat, May 27, 2017 at 7:56 AM, Baolin Wang <baolin.wang@spreadtrum.com> wrote:

> This patch adds the pin control driver for Spreadtrum SC9860 platform.
>
> Signed-off-by: Baolin Wang <baolin.wang@spreadtrum.com>

Overall I see that you want to store functions and groups in the device tree
using the current helpers from Tony. That is OK if you want to take that
approach, though I prefer the pins/groups/function encoding in plaintext.

But when it comes to pin config:

> +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 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++) {
> +               if (pin->type == GLOBAL_CTRL_PIN) {
> +                       reg = readl((void __iomem *)pin->reg);
> +                       reg &= ~(PINCTRL_BIT_MASK(pin->bit_width)
> +                               << pin->bit_offset);
> +                       reg |= (configs[i] & PINCTRL_BIT_MASK(pin->bit_width))
> +                               << pin->bit_offset;
> +                       writel(reg, (void __iomem *)pin->reg);
> +               } else {
> +                       writel(configs[i], (void __iomem *)pin->reg);
> +               }
> +               pin->config = configs[i];
> +       }
> +
> +       return 0;
> +}

This is just hammering the register values, you have effectively defined your
register layout as your device tree ABI.

Please don't do this, please use genric pin config and use the approach
other drivers take with explicit strings encoding the pin configuration.

Even pinctrl-single that maintain quite a bit of muxing data in the device
tree still use the generic pin config API, see:
drivers/pinctrl/pinctrl-single.c
pcs_pinconf_get(), pcs_pinconf_set()

Same for group config.

Yours,
Linus Walleij

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

* Re: [PATCH 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller
  2017-05-29 16:18 ` [PATCH 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller Linus Walleij
@ 2017-05-31  7:58       ` Baolin Wang
  0 siblings, 0 replies; 13+ messages in thread
From: Baolin Wang @ 2017-05-31  7:58 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 一,  5月 29, 2017 at 06:18:29下午 +0200, Linus Walleij wrote:
> On Sat, May 27, 2017 at 7:56 AM, 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>
> (...)
> 
> > +* 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 feilds with one bit or several bits to
> 
> feilds -> fields

Sorry for typos, will fix in next version.

> 
> Do you mean "bitfields", i.e a few bits inside a configuration register
> word?

Yes.

> 
> > +configurate for some global common configuration, such as domain
> 
> configurate -> configure

OK.

> 
> > +pad driving level, system control select
> 
> Actually I do not understand at all what "domain pad driving level"
> or "system control select" means, those are very generic terms.
> Can you describe precisely what it means? What domain? What
> is a domain pad? What kind of system control? What is it selecting
> between?

I try to explain what they are on Spreadtrum platform. One pin can output
3.0v or 1.8v, depending on the related domain pad driving selection, if
the related domain pad slect 3.0v, then the pin can output 3.0v.

"system control" is used to choose this function (like: UART0) for which
system, since we have several systems (AP/CP/CM4) on one SoC.

> 
> >  and so on. We recognise
> > +every feild comprising one bit or several bits in one global control
> 
> feild -> field
> 
> > +register as one pin, thus we should record every pin's bit offset,
> > +bit width and register offset to configurate this feild (pin).
> 
> feild -> field
> 
> > +The second block comprises some common registers which have unified
> > +register definition, and each register described one pin is used
> > +to configurate pin sleep mode and function select.
> 
> OK
> 
> > +The last block comprises some misc registers which also have unified
> > +register definition, and each register described one pin is used to
> > +configurate drive strength, pull up/down and so on.
> 
> configurate -> configure
> 
> OK that is pin configuration.
> 
> > +This driver supports the generic pin multiplexing and configuration
> > +bindings. For details on each properties, you can refer to
> > +./pinctrl-bindings.txt.
> 
> Do not talk about the driver in the bindings. Talk about the bindings per
> se, these bindings are supposed to be OS neutral.

Sure, will remove these.

> 
> > +Required properties for Spreadtrum pin controller:
> > +- compatible: "sprd,<soc>-pinctrl"
> > +  Please refer to each sprd,<soc>-pinctrl.txt binding doc for supported SoCs.
> > +
> > +Required properties for pin configuration node:
> > +- sprd,pins: each entry consists of 2 integers and represents the pin
> > +  id and config setting for one pin.
> 
> Do not use the custom property "sprd,pins" for this, if you want to set up pin
> muxing with a magic value use the generic binding "pinmux", see:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt?id=8d5e7c5df0a6c442373628be5221321172b1badf
> 
> But consider using groups+functions for defining multiplexing instead.
> 
> But please do NOT combine pin configuration into a magic value. Use
> the generic pin control bindings, er have bindings for all kinds of pin
> config, and using them makes the driver much more readable for
> humans.
> 
> I understand that you may have a lot of magic number tables around that
> you are using today, but it is necessary to decompose that into the proper
> generic pin configuration properties to make it usable.

Since we have lots of different pin configuration to set, it will be hard to
use the standard pin config describing in binding files. But I will try to
remove the magic number and use the common pin config.

> 
> > +++ b/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt
> > @@ -0,0 +1,26 @@
> > +* 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.
> > +- sprd,pins: two integers array, represents a group of pins id and config
> > +  setting. The format is sprd,pins = <PIN_ID CONFIG>, PIN_ID can be found
> > +  from pinctrl-sprd-sc9860.c file or spec file, CONFIG is the pad setting
> > +  value like pull-up for this pin.
> 
> Same comments.
> 
> > +Example:
> > +pin_controller: pinctrl@402a0000 {
> > +       compatible = "sprd,sc9860-pinctrl";
> > +       reg = <0x402a0000 0x10000>;
> > +
> > +       vio_sd0_ms_0: sd0_ms0 {
> > +               sprd,pins = <8 0x1>;
> > +       };
> > +
> > +       vbc_iis0_0: iis0_c {
> > +               sprd,pins = <34 0xc>;
> > +       };
> > +};
> 
> Magic numbers are very hard to understand. Compare to this
> from Qualcomm APQ8064 using just standard bindings:
> 
> pinmux@800000 {
>         i2c4_pins: i2c4_pinmux {
>                pins = "gpio12", "gpio13";
>                function = "gsbi4";
>                bias-disable;
>         };
> 
>         spi_pins: spi_pins {
>                mux {
>                       pins = "gpio18", "gpio19", "gpio21";
>                       function = "gsbi5";
>                       drive-strength = <10>;
>                       bias-none;
>                 };
>         };
> };
> 
> Please try go get rid of the magic numbers and get to use pins, function,
> drive-strength bias etc from the standard bindings. We also have a lot
> of helper code available to use this.

Sure. I will try o fix this. Thanks for your helpful 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] 13+ messages in thread

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

Hi Linus,

On 一,  5月 29, 2017 at 06:18:29下午 +0200, Linus Walleij wrote:
> On Sat, May 27, 2017 at 7:56 AM, 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>
> (...)
> 
> > +* 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 feilds with one bit or several bits to
> 
> feilds -> fields

Sorry for typos, will fix in next version.

> 
> Do you mean "bitfields", i.e a few bits inside a configuration register
> word?

Yes.

> 
> > +configurate for some global common configuration, such as domain
> 
> configurate -> configure

OK.

> 
> > +pad driving level, system control select
> 
> Actually I do not understand at all what "domain pad driving level"
> or "system control select" means, those are very generic terms.
> Can you describe precisely what it means? What domain? What
> is a domain pad? What kind of system control? What is it selecting
> between?

I try to explain what they are on Spreadtrum platform. One pin can output
3.0v or 1.8v, depending on the related domain pad driving selection, if
the related domain pad slect 3.0v, then the pin can output 3.0v.

"system control" is used to choose this function (like: UART0) for which
system, since we have several systems (AP/CP/CM4) on one SoC.

> 
> >  and so on. We recognise
> > +every feild comprising one bit or several bits in one global control
> 
> feild -> field
> 
> > +register as one pin, thus we should record every pin's bit offset,
> > +bit width and register offset to configurate this feild (pin).
> 
> feild -> field
> 
> > +The second block comprises some common registers which have unified
> > +register definition, and each register described one pin is used
> > +to configurate pin sleep mode and function select.
> 
> OK
> 
> > +The last block comprises some misc registers which also have unified
> > +register definition, and each register described one pin is used to
> > +configurate drive strength, pull up/down and so on.
> 
> configurate -> configure
> 
> OK that is pin configuration.
> 
> > +This driver supports the generic pin multiplexing and configuration
> > +bindings. For details on each properties, you can refer to
> > +./pinctrl-bindings.txt.
> 
> Do not talk about the driver in the bindings. Talk about the bindings per
> se, these bindings are supposed to be OS neutral.

Sure, will remove these.

> 
> > +Required properties for Spreadtrum pin controller:
> > +- compatible: "sprd,<soc>-pinctrl"
> > +  Please refer to each sprd,<soc>-pinctrl.txt binding doc for supported SoCs.
> > +
> > +Required properties for pin configuration node:
> > +- sprd,pins: each entry consists of 2 integers and represents the pin
> > +  id and config setting for one pin.
> 
> Do not use the custom property "sprd,pins" for this, if you want to set up pin
> muxing with a magic value use the generic binding "pinmux", see:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt?id=8d5e7c5df0a6c442373628be5221321172b1badf
> 
> But consider using groups+functions for defining multiplexing instead.
> 
> But please do NOT combine pin configuration into a magic value. Use
> the generic pin control bindings, er have bindings for all kinds of pin
> config, and using them makes the driver much more readable for
> humans.
> 
> I understand that you may have a lot of magic number tables around that
> you are using today, but it is necessary to decompose that into the proper
> generic pin configuration properties to make it usable.

Since we have lots of different pin configuration to set, it will be hard to
use the standard pin config describing in binding files. But I will try to
remove the magic number and use the common pin config.

> 
> > +++ b/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt
> > @@ -0,0 +1,26 @@
> > +* 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.
> > +- sprd,pins: two integers array, represents a group of pins id and config
> > +  setting. The format is sprd,pins = <PIN_ID CONFIG>, PIN_ID can be found
> > +  from pinctrl-sprd-sc9860.c file or spec file, CONFIG is the pad setting
> > +  value like pull-up for this pin.
> 
> Same comments.
> 
> > +Example:
> > +pin_controller: pinctrl@402a0000 {
> > +       compatible = "sprd,sc9860-pinctrl";
> > +       reg = <0x402a0000 0x10000>;
> > +
> > +       vio_sd0_ms_0: sd0_ms0 {
> > +               sprd,pins = <8 0x1>;
> > +       };
> > +
> > +       vbc_iis0_0: iis0_c {
> > +               sprd,pins = <34 0xc>;
> > +       };
> > +};
> 
> Magic numbers are very hard to understand. Compare to this
> from Qualcomm APQ8064 using just standard bindings:
> 
> pinmux@800000 {
>         i2c4_pins: i2c4_pinmux {
>                pins = "gpio12", "gpio13";
>                function = "gsbi4";
>                bias-disable;
>         };
> 
>         spi_pins: spi_pins {
>                mux {
>                       pins = "gpio18", "gpio19", "gpio21";
>                       function = "gsbi5";
>                       drive-strength = <10>;
>                       bias-none;
>                 };
>         };
> };
> 
> Please try go get rid of the magic numbers and get to use pins, function,
> drive-strength bias etc from the standard bindings. We also have a lot
> of helper code available to use this.

Sure. I will try o fix this. Thanks for your helpful comments.

> 
> Yours,
> Linus Walleij

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

* Re: [PATCH 2/2] pinctrl: sprd: Add Spreadtrum pin control driver
  2017-05-29 16:28       ` Linus Walleij
@ 2017-05-31  8:00           ` Baolin Wang
  -1 siblings, 0 replies; 13+ messages in thread
From: Baolin Wang @ 2017-05-31  8:00 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 一,  5月 29, 2017 at 06:28:49下午 +0200, Linus Walleij wrote:
> On Sat, May 27, 2017 at 7:56 AM, Baolin Wang <baolin.wang-lxIno14LUO0EEoCn2XhGlw@public.gmane.org> wrote:
> 
> > This patch adds the pin control driver for Spreadtrum SC9860 platform.
> >
> > Signed-off-by: Baolin Wang <baolin.wang-lxIno14LUO0EEoCn2XhGlw@public.gmane.org>
> 
> Overall I see that you want to store functions and groups in the device tree
> using the current helpers from Tony. That is OK if you want to take that
> approach, though I prefer the pins/groups/function encoding in plaintext.
> 
> But when it comes to pin config:
> 
> > +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 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++) {
> > +               if (pin->type == GLOBAL_CTRL_PIN) {
> > +                       reg = readl((void __iomem *)pin->reg);
> > +                       reg &= ~(PINCTRL_BIT_MASK(pin->bit_width)
> > +                               << pin->bit_offset);
> > +                       reg |= (configs[i] & PINCTRL_BIT_MASK(pin->bit_width))
> > +                               << pin->bit_offset;
> > +                       writel(reg, (void __iomem *)pin->reg);
> > +               } else {
> > +                       writel(configs[i], (void __iomem *)pin->reg);
> > +               }
> > +               pin->config = configs[i];
> > +       }
> > +
> > +       return 0;
> > +}
> 
> This is just hammering the register values, you have effectively defined your
> register layout as your device tree ABI.
> 
> Please don't do this, please use genric pin config and use the approach
> other drivers take with explicit strings encoding the pin configuration.

Make sense. I will try to use genric pin config instead of the magic number.
Thanks for your comments.

> 
> Even pinctrl-single that maintain quite a bit of muxing data in the device
> tree still use the generic pin config API, see:
> drivers/pinctrl/pinctrl-single.c
> pcs_pinconf_get(), pcs_pinconf_set()
> 
> Same for group config.
> 
> 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] 13+ messages in thread

* Re: [PATCH 2/2] pinctrl: sprd: Add Spreadtrum pin control driver
@ 2017-05-31  8:00           ` Baolin Wang
  0 siblings, 0 replies; 13+ messages in thread
From: Baolin Wang @ 2017-05-31  8:00 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mark Rutland, Rob Herring, linux-gpio, devicetree, linux-kernel,
	Mark Brown, Baolin Wang

Hi Linus,

On 一,  5月 29, 2017 at 06:28:49下午 +0200, Linus Walleij wrote:
> On Sat, May 27, 2017 at 7:56 AM, Baolin Wang <baolin.wang@spreadtrum.com> wrote:
> 
> > This patch adds the pin control driver for Spreadtrum SC9860 platform.
> >
> > Signed-off-by: Baolin Wang <baolin.wang@spreadtrum.com>
> 
> Overall I see that you want to store functions and groups in the device tree
> using the current helpers from Tony. That is OK if you want to take that
> approach, though I prefer the pins/groups/function encoding in plaintext.
> 
> But when it comes to pin config:
> 
> > +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 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++) {
> > +               if (pin->type == GLOBAL_CTRL_PIN) {
> > +                       reg = readl((void __iomem *)pin->reg);
> > +                       reg &= ~(PINCTRL_BIT_MASK(pin->bit_width)
> > +                               << pin->bit_offset);
> > +                       reg |= (configs[i] & PINCTRL_BIT_MASK(pin->bit_width))
> > +                               << pin->bit_offset;
> > +                       writel(reg, (void __iomem *)pin->reg);
> > +               } else {
> > +                       writel(configs[i], (void __iomem *)pin->reg);
> > +               }
> > +               pin->config = configs[i];
> > +       }
> > +
> > +       return 0;
> > +}
> 
> This is just hammering the register values, you have effectively defined your
> register layout as your device tree ABI.
> 
> Please don't do this, please use genric pin config and use the approach
> other drivers take with explicit strings encoding the pin configuration.

Make sense. I will try to use genric pin config instead of the magic number.
Thanks for your comments.

> 
> Even pinctrl-single that maintain quite a bit of muxing data in the device
> tree still use the generic pin config API, see:
> drivers/pinctrl/pinctrl-single.c
> pcs_pinconf_get(), pcs_pinconf_set()
> 
> Same for group config.
> 
> Yours,
> Linus Walleij

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

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

On Wed, May 31, 2017 at 9:58 AM, Baolin Wang <baolin.wang-lxIno14LUO0EEoCn2XhGlw@public.gmane.org> wrote:
> On 一,  5月 29, 2017 at 06:18:29下午 +0200, Linus Walleij wrote:

>> > +pad driving level, system control select
>>
>> Actually I do not understand at all what "domain pad driving level"
>> or "system control select" means, those are very generic terms.
>> Can you describe precisely what it means? What domain? What
>> is a domain pad? What kind of system control? What is it selecting
>> between?
>
> I try to explain what they are on Spreadtrum platform. One pin can output
> 3.0v or 1.8v, depending on the related domain pad driving selection, if
> the related domain pad slect 3.0v, then the pin can output 3.0v.

This can probably use the generic pin control property
PIN_CONFIG_POWER_SOURCE (see include/linux/pinctrl/pinconf-generic.h)
and the corresponding DT binding "power-source" see
drivers/pinctrl/pinconf-generic.c and
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt

> "system control" is used to choose this function (like: UART0) for which
> system, since we have several systems (AP/CP/CM4) on one SoC.

Aha, that sounds like a very spreadtrum-specific feature actually.

> Since we have lots of different pin configuration to set, it will be hard to
> use the standard pin config describing in binding files. But I will try to
> remove the magic number and use the common pin config.

It is possible to use generic config and add a few custom bindings
"on top" of it. See for example:
Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt
mixing a few generic and Qualcomm-specific pin config things,
and their driver is here:
drivers/pinctrl/qcom/pinctrl-spmi-mpp.c

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] 13+ messages in thread

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

On Wed, May 31, 2017 at 9:58 AM, Baolin Wang <baolin.wang@spreadtrum.com> wrote:
> On 一,  5月 29, 2017 at 06:18:29下午 +0200, Linus Walleij wrote:

>> > +pad driving level, system control select
>>
>> Actually I do not understand at all what "domain pad driving level"
>> or "system control select" means, those are very generic terms.
>> Can you describe precisely what it means? What domain? What
>> is a domain pad? What kind of system control? What is it selecting
>> between?
>
> I try to explain what they are on Spreadtrum platform. One pin can output
> 3.0v or 1.8v, depending on the related domain pad driving selection, if
> the related domain pad slect 3.0v, then the pin can output 3.0v.

This can probably use the generic pin control property
PIN_CONFIG_POWER_SOURCE (see include/linux/pinctrl/pinconf-generic.h)
and the corresponding DT binding "power-source" see
drivers/pinctrl/pinconf-generic.c and
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt

> "system control" is used to choose this function (like: UART0) for which
> system, since we have several systems (AP/CP/CM4) on one SoC.

Aha, that sounds like a very spreadtrum-specific feature actually.

> Since we have lots of different pin configuration to set, it will be hard to
> use the standard pin config describing in binding files. But I will try to
> remove the magic number and use the common pin config.

It is possible to use generic config and add a few custom bindings
"on top" of it. See for example:
Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt
mixing a few generic and Qualcomm-specific pin config things,
and their driver is here:
drivers/pinctrl/qcom/pinctrl-spmi-mpp.c

Yours,
Linus Walleij

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

end of thread, other threads:[~2017-06-09  7:59 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-27  5:56 [PATCH 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller Baolin Wang
2017-05-27  5:56 ` Baolin Wang
2017-05-27  5:56 ` [PATCH 2/2] pinctrl: sprd: Add Spreadtrum pin control driver Baolin Wang
2017-05-27  5:56   ` Baolin Wang
     [not found]   ` <58b4b6fb2765ab9d5d3ac77f3854d0a88a0973bd.1495863824.git.baolin.wang-lxIno14LUO0EEoCn2XhGlw@public.gmane.org>
2017-05-29 16:28     ` Linus Walleij
2017-05-29 16:28       ` Linus Walleij
     [not found]       ` <CACRpkdaBcGNTeUDCcVgK9JKZUPKD-qfO8PVHURR2F_pgvEgViQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-05-31  8:00         ` Baolin Wang
2017-05-31  8:00           ` Baolin Wang
2017-05-29 16:18 ` [PATCH 1/2] DT: pinctrl: Add binding documentation for Spreadtrum pin controller Linus Walleij
     [not found]   ` <CACRpkdZFUDrfoyvk-CramNP2OVwVAazVsw3S-wCayx8HP6cSZQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-05-31  7:58     ` Baolin Wang
2017-05-31  7:58       ` Baolin Wang
     [not found]       ` <20170531075827.GA31518-lxIno14LUO0EEoCn2XhGlw@public.gmane.org>
2017-06-09  7:59         ` Linus Walleij
2017-06-09  7:59           ` Linus Walleij

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.