Skip to contentSkip to conversation

pinctrl: ingenic: add support for x1600 SoC and MII and I2S for jz4730

PATCH Superseded H. Nikolaus Schaller 2 participants 8 messages Feb 26, 2025

Subsystems (5)

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#6 lore raw

PATCH 3/4 pinctrl: ingenic: jz4730: add pinmux for MII

In reply to H. Nikolaus Schaller

The MII interface is used for the Ethernet connection of the Alpha400.

---
 drivers/pinctrl/pinctrl-ingenic.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/pinctrl/pinctrl-ingenic.c +6 -0
index dfdc89ece9b8a..86d285a800c5d 100644
@@ -210,6 +210,9 @@ static int jz4730_nand_cs5_pins[] = { 0x57, };
 static int jz4730_pwm_pwm0_pins[] = { 0x5e, };
 static int jz4730_pwm_pwm1_pins[] = { 0x5f, };
 
+static int jz4730_mii_pins[] = { 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
+				 0x77, 0x78, 0x19, 0x7a, 0x1b, 0x7c, };
+
 static u8 jz4730_lcd_8bit_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, };
 
 static const struct group_desc jz4730_groups[] = {
@@ -231,6 +234,7 @@ static const struct group_desc jz4730_groups[] = {
 	INGENIC_PIN_GROUP("nand-cs5", jz4730_nand_cs5, 1),
 	INGENIC_PIN_GROUP("pwm0", jz4730_pwm_pwm0, 1),
 	INGENIC_PIN_GROUP("pwm1", jz4730_pwm_pwm1, 1),
+	INGENIC_PIN_GROUP("mii", jz4730_mii, 1),
 };
 
 static const char *jz4730_mmc_groups[] = { "mmc-1bit", "mmc-4bit", };
@@ -246,6 +250,7 @@ static const char *jz4730_nand_groups[] = {
 };
 static const char *jz4730_pwm0_groups[] = { "pwm0", };
 static const char *jz4730_pwm1_groups[] = { "pwm1", };
+static const char *jz4730_mii_groups[] = { "mii", };
 
 static const struct function_desc jz4730_functions[] = {
 	INGENIC_PIN_FUNCTION("mmc", jz4730_mmc),
@@ -257,6 +262,7 @@ static const struct function_desc jz4730_functions[] = {
 	INGENIC_PIN_FUNCTION("nand", jz4730_nand),
 	INGENIC_PIN_FUNCTION("pwm0", jz4730_pwm0),
 	INGENIC_PIN_FUNCTION("pwm1", jz4730_pwm1),
+	INGENIC_PIN_FUNCTION("mii", jz4730_mii),
 };
 
 static const struct ingenic_chip_info jz4730_chip_info = {
Signature · 1 line
2.47.0
#1 lore raw

PATCH 1/4 bindings: ingenic,pinctrl: add x1600

In reply to H. Nikolaus Schaller

Add bindings for the Lumissil/Ingenic X1600 SoC.

---
 Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml | 2 ++
 1 file changed, 2 insertions(+)
Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml +2 -0
index 890961826c6f0..84e960255a36d 100644
@@ -42,6 +42,7 @@ properties:
           - ingenic,jz4780-pinctrl
           - ingenic,x1000-pinctrl
           - ingenic,x1500-pinctrl
+          - ingenic,x1600-pinctrl
           - ingenic,x1830-pinctrl
           - ingenic,x2000-pinctrl
           - ingenic,x2100-pinctrl
@@ -81,6 +82,7 @@ patternProperties:
           - ingenic,jz4780-gpio
           - ingenic,x1000-gpio
           - ingenic,x1500-gpio
+          - ingenic,x1600-gpio
           - ingenic,x1830-gpio
           - ingenic,x2000-gpio
           - ingenic,x2100-gpio
Signature · 1 line
2.47.0
#0 lore raw

cover pinctrl: ingenic: add support for x1600 SoC and MII and I2S for jz4730

PATCH V1 2025-02-26 18:14:53:
This series expands pinctrl support for some Ingenic/Lumissil SoC. For the jz4730 we add MII and I2S pinctrl and general x1600 support.

The x1600 parts were jointly developed.

Code was tested on LX16 board (x1600) and Alpha400 (jz4730) and on CI20 (jz4780).

H. Nikolaus Schaller (3):
bindings: ingenic,pinctrl: add x1600
pinctrl: ingenic: jz4730: add pinmux for MII
pinctrl: ingenic: jz4730: add pinmux for I2S interface

Paul Boddie (1):
pinctrl: ingenic: add x1600 support

 .../bindings/pinctrl/ingenic,pinctrl.yaml     |   2 +
 drivers/pinctrl/pinctrl-ingenic.c             | 259 +++++++++++++++++-
 2 files changed, 259 insertions(+), 2 deletions(-)
Signature · 1 line
2.47.0
#2 lore raw

PATCH 2/4 pinctrl: ingenic: add x1600 support

From: Paul Boddie <[email protected]>

Add support for the Lumissil/Ingenic X1600 SoC.

It uses shadow registers to commit changes to multiple pinctrl registers in parallel.

Define specific Chip ID, register offsets, pin tables etc.

Handling the unique X1600_GPIO_PU only for the x1600 but not for x1830 and above must be carefully taken into account.

---
 drivers/pinctrl/pinctrl-ingenic.c | 242 +++++++++++++++++++++++++++++-
 1 file changed, 240 insertions(+), 2 deletions(-)
drivers/pinctrl/pinctrl-ingenic.c +240 -2
index bc7ee54e062b5..dfdc89ece9b8a 100644
@@ -3,7 +3,7 @@
  * Ingenic SoCs pinctrl driver
  *
  * Copyright (c) 2017 Paul Cercueil <[email protected]>
- * Copyright (c) 2017, 2019 Paul Boddie <[email protected]>
+ * Copyright (c) 2017, 2019, 2020, 2023 Paul Boddie <[email protected]>
  * Copyright (c) 2019, 2020 周琰杰 (Zhou Yanjie) <[email protected]>
  */
 
@@ -58,6 +58,8 @@
 #define JZ4770_GPIO_FLAG			0x50
 #define JZ4770_GPIO_PEN				0x70
 
+#define X1600_GPIO_PU				 0x80
+
 #define X1830_GPIO_PEL				0x110
 #define X1830_GPIO_PEH				0x120
 #define X1830_GPIO_SR				0x150
@@ -112,6 +114,7 @@ enum jz_version {
 	ID_JZ4780,
 	ID_X1000,
 	ID_X1500,
+	ID_X1600,
 	ID_X1830,
 	ID_X2000,
 	ID_X2100,
@@ -162,6 +165,7 @@ static const unsigned long enabled_socs =
 	IS_ENABLED(CONFIG_MACH_JZ4780) << ID_JZ4780 |
 	IS_ENABLED(CONFIG_MACH_X1000) << ID_X1000 |
 	IS_ENABLED(CONFIG_MACH_X1500) << ID_X1500 |
+	IS_ENABLED(CONFIG_MACH_X1600) << ID_X1600 |
 	IS_ENABLED(CONFIG_MACH_X1830) << ID_X1830 |
 	IS_ENABLED(CONFIG_MACH_X2000) << ID_X2000 |
 	IS_ENABLED(CONFIG_MACH_X2100) << ID_X2100;
@@ -2351,6 +2355,231 @@ static const struct ingenic_chip_info x1500_chip_info = {
 	.access_table = &x1000_access_table,
 };
 
+static const u32 x1600_pull_ups[4] = {
+	0xffffffff, 0xdffbf7bf, 0x987e0000, 0x0000003f,
+};
+
+static const u32 x1600_pull_downs[4] = {
+	0x00000000, 0x00000000, 0x07000007, 0x00000000,
+};
+
+static int x1600_uart0_data_pins[] = { 0x27, 0x28, };
+static int x1600_uart0_hwflow_pins[] = { 0x29, 0x2a, };
+static int x1600_uart1_data_pins[] = { 0x23, 0x22, };
+static int x1600_uart1_hwflow_pins[] = { 0x25, 0x24, };
+static int x1600_uart2_data_a_pins[] = { 0x1f, 0x1e, };
+static int x1600_uart2_data_b_pins[] = { 0x21, 0x20, };
+static int x1600_uart3_data_b_pins[] = { 0x25, 0x24, };
+static int x1600_uart3_data_d_pins[] = { 0x65, 0x64, };
+static int x1600_sfc_pins[] = { 0x53, 0x54, 0x55, 0x56, 0x51, 0x52, 0x24, };
+static int x1600_ssi_dt_a_pins[] = { 0x1e, };
+static int x1600_ssi_dt_b_pins[] = { 0x2d, };
+static int x1600_ssi_dr_a_pins[] = { 0x1d, };
+static int x1600_ssi_dr_b_pins[] = { 0x2e, };
+static int x1600_ssi_clk_a_pins[] = { 0x1f, };
+static int x1600_ssi_clk_b_pins[] = { 0x2c, };
+static int x1600_ssi_ce0_a_pins[] = { 0x1c, };
+static int x1600_ssi_ce0_b_pins[] = { 0x31, };
+static int x1600_ssi_ce1_a_pins[] = { 0x22, };
+static int x1600_ssi_ce1_b_pins[] = { 0x30, };
+static int x1600_mmc0_1bit_b_pins[] = { 0x2c, 0x2d, 0x2e, };
+static int x1600_mmc0_4bit_b_pins[] = { 0x2f, 0x30, 0x31, };
+static int x1600_mmc0_1bit_c_pins[] = { 0x51, 0x53, 0x54, };
+static int x1600_mmc0_4bit_c_pins[] = { 0x56, 0x55, 0x52, };
+static int x1600_mmc1_1bit_pins[] = { 0x60, 0x61, 0x62, };
+static int x1600_mmc1_4bit_pins[] = { 0x63, 0x64, 0x65, };
+static int x1600_i2c0_a_pins[] = { 0x1d, 0x1c, };
+static int x1600_i2c0_b_pins[] = { 0x3f, 0x3e, };
+static int x1600_i2c1_b_15_pins[] = { 0x30, 0x2f, };
+static int x1600_i2c1_b_19_pins[] = { 0x34, 0x33, };
+static int x1600_i2s_data_tx_pins[] = { 0x39, };
+static int x1600_i2s_data_rx_pins[] = { 0x35, };
+static int x1600_i2s_clk_rx_pins[] = { 0x37, 0x38, };
+static int x1600_i2s_clk_tx_pins[] = { 0x3b, 0x3c, };
+static int x1600_i2s_sysclk_pins[] = { 0x36, 0x3a, };
+
+static int x1600_cim_pins[] = {
+	0x14, 0x16, 0x15, 0x18, 0x13,
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+};
+
+static int x1600_slcd_8bit_pins[] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	0x17, 0x19, 0x1a, 0x1b,
+};
+
+static int x1600_slcd_16bit_pins[] = {
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+};
+
+static int x1600_lcd_16bit_pins[] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+	0x18, 0x19, 0x1a, 0x1b,
+};
+
+static int x1600_lcd_18bit_pins[] = {
+	0x10, 0x11,
+};
+
+static int x1600_lcd_24bit_pins[] = {
+	0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+};
+
+static int x1600_pwm_pwm0_pins[] = { 0x40, };
+static int x1600_pwm_pwm1_pins[] = { 0x41, };
+static int x1600_pwm_pwm2_pins[] = { 0x42, };
+static int x1600_pwm_pwm3_pins[] = { 0x58, };
+static int x1600_pwm_pwm4_pins[] = { 0x59, };
+static int x1600_pwm_pwm5_pins[] = { 0x33, 0x5a, };
+static int x1600_pwm_pwm6_pins[] = { 0x29, 0x34, };
+static int x1600_pwm_pwm7_pins[] = { 0x2a, 0x35, };
+
+static int x1600_mac_pins[] = {
+	0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c,
+};
+
+static int x1600_sfc_funcs[] = { 0, 0, 0, 0, 0, 0, 2, };
+
+static int x1600_pwm_pwm5_funcs[] = { 2, 1, };
+static int x1600_pwm_pwm6_funcs[] = { 1, 2, };
+static int x1600_pwm_pwm7_funcs[] = { 1, 2, };
+
+static const struct group_desc x1600_groups[] = {
+	INGENIC_PIN_GROUP("uart0-data", x1600_uart0_data, 0),
+	INGENIC_PIN_GROUP("uart0-hwflow", x1600_uart0_hwflow, 0),
+	INGENIC_PIN_GROUP("uart1-data", x1600_uart1_data, 1),
+	INGENIC_PIN_GROUP("uart1-hwflow", x1600_uart1_hwflow, 1),
+	INGENIC_PIN_GROUP("uart2-data-a", x1600_uart2_data_a, 2),
+	INGENIC_PIN_GROUP("uart2-data-b", x1600_uart2_data_b, 1),
+	INGENIC_PIN_GROUP("uart3-data-b", x1600_uart3_data_b, 0),
+	INGENIC_PIN_GROUP("uart3-data-d", x1600_uart3_data_d, 2),
+	INGENIC_PIN_GROUP_FUNCS("sfc", x1600_sfc, x1600_sfc_funcs),
+	INGENIC_PIN_GROUP("ssi-dt-a", x1600_ssi_dt_a, 0),
+	INGENIC_PIN_GROUP("ssi-dt-b", x1600_ssi_dt_b, 1),
+	INGENIC_PIN_GROUP("ssi-dr-a", x1600_ssi_dr_a, 0),
+	INGENIC_PIN_GROUP("ssi-dr-b", x1600_ssi_dr_b, 1),
+	INGENIC_PIN_GROUP("ssi-clk-a", x1600_ssi_clk_a, 0),
+	INGENIC_PIN_GROUP("ssi-clk-b", x1600_ssi_clk_b, 1),
+	INGENIC_PIN_GROUP("ssi-ce0-a", x1600_ssi_ce0_a, 0),
+	INGENIC_PIN_GROUP("ssi-ce0-b", x1600_ssi_ce0_b, 1),
+	INGENIC_PIN_GROUP("ssi-ce1-a", x1600_ssi_ce1_a, 2),
+	INGENIC_PIN_GROUP("ssi-ce1-b", x1600_ssi_ce1_b, 1),
+	INGENIC_PIN_GROUP("mmc0-1bit-b", x1600_mmc0_1bit_b, 0),
+	INGENIC_PIN_GROUP("mmc0-4bit-b", x1600_mmc0_4bit_b, 0),
+	INGENIC_PIN_GROUP("mmc0-1bit-c", x1600_mmc0_1bit_c, 1),
+	INGENIC_PIN_GROUP("mmc0-4bit-c", x1600_mmc0_4bit_c, 1),
+	INGENIC_PIN_GROUP("mmc1-1bit", x1600_mmc1_1bit, 0),
+	INGENIC_PIN_GROUP("mmc1-4bit", x1600_mmc1_4bit, 0),
+	INGENIC_PIN_GROUP("i2c0-data-a", x1600_i2c0_a, 2),
+	INGENIC_PIN_GROUP("i2c0-data-b", x1600_i2c0_b, 0),
+	INGENIC_PIN_GROUP("i2c1-data-b-15", x1600_i2c1_b_15, 2),
+	INGENIC_PIN_GROUP("i2c1-data-b-19", x1600_i2c1_b_19, 0),
+	INGENIC_PIN_GROUP("i2s-data-tx", x1600_i2s_data_tx, 0),
+	INGENIC_PIN_GROUP("i2s-data-rx", x1600_i2s_data_rx, 0),
+	INGENIC_PIN_GROUP("i2s-clk-rx", x1600_i2s_clk_rx, 0),
+	INGENIC_PIN_GROUP("i2s-clk-tx", x1600_i2s_clk_tx, 0),
+	INGENIC_PIN_GROUP("i2s-sysclk", x1600_i2s_sysclk, 0),
+	INGENIC_PIN_GROUP("cim-data", x1600_cim, 2),
+	INGENIC_PIN_GROUP("slcd-8bit", x1600_slcd_8bit, 1),
+	INGENIC_PIN_GROUP("slcd-16bit", x1600_slcd_16bit, 1),
+	INGENIC_PIN_GROUP("lcd-16bit", x1600_lcd_16bit, 0),
+	INGENIC_PIN_GROUP("lcd-18bit", x1600_lcd_18bit, 0),
+	INGENIC_PIN_GROUP("lcd-24bit", x1600_lcd_24bit, 0),
+	INGENIC_PIN_GROUP("pwm0", x1600_pwm_pwm0, 0),
+	INGENIC_PIN_GROUP("pwm1", x1600_pwm_pwm1, 0),
+	INGENIC_PIN_GROUP("pwm2", x1600_pwm_pwm2, 0),
+	INGENIC_PIN_GROUP("pwm3", x1600_pwm_pwm3, 1),
+	INGENIC_PIN_GROUP("pwm4", x1600_pwm_pwm4, 1),
+	INGENIC_PIN_GROUP_FUNCS("pwm5", x1600_pwm_pwm5, x1600_pwm_pwm5_funcs),
+	INGENIC_PIN_GROUP_FUNCS("pwm6", x1600_pwm_pwm6, x1600_pwm_pwm6_funcs),
+	INGENIC_PIN_GROUP_FUNCS("pwm7", x1600_pwm_pwm7, x1600_pwm_pwm7_funcs),
+	INGENIC_PIN_GROUP("mac", x1600_mac, 1),
+};
+
+static const char * const x1600_uart0_groups[] = { "uart0-data", "uart0-hwflow", };
+static const char * const x1600_uart1_groups[] = { "uart1-data", "uart1-hwflow", };
+static const char * const x1600_uart2_groups[] = { "uart2-data-a", "uart2-data-b", };
+static const char * const x1600_uart3_groups[] = { "uart3-data-b", "uart3-data-d", };
+
+static const char * const x1600_sfc_groups[] = { "sfc", };
+
+static const char * const x1600_ssi_groups[] = {
+	"ssi-dt-a", "ssi-dt-b",
+	"ssi-dr-a", "ssi-dr-b",
+	"ssi-clk-a", "ssi-clk-b",
+	"ssi-ce0-a", "ssi-ce0-b",
+	"ssi-ce1-a", "ssi-ce1-b",
+};
+
+static const char * const x1600_mmc0_groups[] = { "mmc0-1bit-b", "mmc0-4bit-b",
+	"mmc0-1bit-c", "mmc0-4bit-c",
+};
+
+static const char * const x1600_mmc1_groups[] = { "mmc1-1bit", "mmc1-4bit", };
+
+static const char * const x1600_i2c0_groups[] = { "i2c0-data-a", "i2c0-data-b", };
+static const char * const x1600_i2c1_groups[] = { "i2c1-data-b-15", "i2c1-data-b-19", };
+
+static const char * const x1600_i2s_groups[] = {
+	"i2s-data-tx", "i2s-data-rx", "i2s-clk-rx", "i2s-clk-tx", "i2s-sysclk",
+};
+
+static const char * const x1600_cim_groups[] = { "cim-data", };
+
+static const char * const x1600_lcd_groups[] = { "slcd-8bit", "slcd-16bit",
+	"lcd-16bit", "lcd-18bit", "lcd-24bit", "lcd-no-pins",
+};
+
+static const char * const x1600_pwm0_groups[] = { "pwm0", };
+static const char * const x1600_pwm1_groups[] = { "pwm1", };
+static const char * const x1600_pwm2_groups[] = { "pwm2", };
+static const char * const x1600_pwm3_groups[] = { "pwm3", };
+static const char * const x1600_pwm4_groups[] = { "pwm4", };
+static const char * const x1600_pwm5_groups[] = { "pwm5", };
+static const char * const x1600_pwm6_groups[] = { "pwm6", };
+static const char * const x1600_pwm7_groups[] = { "pwm7", };
+
+static const char * const x1600_mac_groups[] = { "mac", };
+
+static const struct function_desc x1600_functions[] = {
+	INGENIC_PIN_FUNCTION("uart0", x1600_uart0),
+	INGENIC_PIN_FUNCTION("uart1", x1600_uart1),
+	INGENIC_PIN_FUNCTION("uart2", x1600_uart2),
+	INGENIC_PIN_FUNCTION("uart3", x1600_uart3),
+	INGENIC_PIN_FUNCTION("sfc", x1600_sfc),
+	INGENIC_PIN_FUNCTION("ssi", x1600_ssi),
+	INGENIC_PIN_FUNCTION("mmc0", x1600_mmc0),
+	INGENIC_PIN_FUNCTION("mmc1", x1600_mmc1),
+	INGENIC_PIN_FUNCTION("i2c0", x1600_i2c0),
+	INGENIC_PIN_FUNCTION("i2c1", x1600_i2c1),
+	INGENIC_PIN_FUNCTION("i2s", x1600_i2s),
+	INGENIC_PIN_FUNCTION("cim", x1600_cim),
+	INGENIC_PIN_FUNCTION("lcd", x1600_lcd),
+	INGENIC_PIN_FUNCTION("pwm0", x1600_pwm0),
+	INGENIC_PIN_FUNCTION("pwm1", x1600_pwm1),
+	INGENIC_PIN_FUNCTION("pwm2", x1600_pwm2),
+	INGENIC_PIN_FUNCTION("pwm3", x1600_pwm3),
+	INGENIC_PIN_FUNCTION("pwm4", x1600_pwm4),
+	INGENIC_PIN_FUNCTION("pwm5", x1600_pwm5),
+	INGENIC_PIN_FUNCTION("pwm6", x1600_pwm6),
+	INGENIC_PIN_FUNCTION("pwm7", x1600_pwm7),
+	INGENIC_PIN_FUNCTION("mac", x1600_mac),
+};
+
+static const struct ingenic_chip_info x1600_chip_info = {
+	.num_chips = 4,
+	.reg_offset = 0x100,
+	.version = ID_X1600,
+	.groups = x1600_groups,
+	.num_groups = ARRAY_SIZE(x1600_groups),
+	.functions = x1600_functions,
+	.num_functions = ARRAY_SIZE(x1600_functions),
+	.pull_ups = x1600_pull_ups,
+	.pull_downs = x1600_pull_downs,
+	.access_table = &x1000_access_table,
+};
+
 static const u32 x1830_pull_ups[4] = {
 	0x5fdfffc0, 0xffffefff, 0x1ffffbff, 0x0fcff3fc,
 };
@@ -3860,7 +4089,9 @@ static int ingenic_pinconf_get(struct pinctrl_dev *pctldev,
 		pulldown = (bias == GPIO_PULL_DOWN) && (jzpc->info->pull_downs[offt] & BIT(idx));
 
 	} else {
-		if (is_soc_or_above(jzpc, ID_JZ4770))
+		if (is_soc_or_above(jzpc, ID_X1600))
+			pull = ingenic_get_pin_config(jzpc, pin, X1600_GPIO_PU);
+		else if (is_soc_or_above(jzpc, ID_JZ4770))
 			pull = !ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PEN);
 		else if (is_soc_or_above(jzpc, ID_JZ4740))
 			pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS);
@@ -3959,6 +4190,8 @@ static void ingenic_set_bias(struct ingenic_pinctrl *jzpc,
 					REG_SET(X1830_GPIO_PEH), bias << idxh);
 		}
 
+	} else if (is_soc_or_above(jzpc, ID_X1600)) {
+		ingenic_config_pin(jzpc, pin, X1600_GPIO_PU, bias);
 	} else if (is_soc_or_above(jzpc, ID_JZ4770)) {
 		ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PEN, !bias);
 	} else if (is_soc_or_above(jzpc, ID_JZ4740)) {
@@ -4150,6 +4383,7 @@ static const struct of_device_id ingenic_gpio_of_matches[] __initconst = {
 	{ .compatible = "ingenic,jz4775-gpio" },
 	{ .compatible = "ingenic,jz4780-gpio" },
 	{ .compatible = "ingenic,x1000-gpio" },
+	{ .compatible = "ingenic,x1600-gpio" },
 	{ .compatible = "ingenic,x1830-gpio" },
 	{ .compatible = "ingenic,x2000-gpio" },
 	{ .compatible = "ingenic,x2100-gpio" },
@@ -4397,6 +4631,10 @@ static const struct of_device_id ingenic_pinctrl_of_matches[] = {
 		.compatible = "ingenic,x1500-pinctrl",
 		.data = IF_ENABLED(CONFIG_MACH_X1500, &x1500_chip_info)
 	},
+	{
+		.compatible = "ingenic,x1600-pinctrl",
+		.data = IF_ENABLED(CONFIG_MACH_X1600, &x1600_chip_info)
+	},
 	{
 		.compatible = "ingenic,x1830-pinctrl",
 		.data = IF_ENABLED(CONFIG_MACH_X1830, &x1830_chip_info)
Signature · 1 line
2.47.0
#7 lore raw

PATCH 4/4 pinctrl: ingenic: jz4730: add pinmux for I2S interface

In reply to H. Nikolaus Schaller

I2S is used for the sound codec of the Alpha400.

---
 drivers/pinctrl/pinctrl-ingenic.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/pinctrl/pinctrl-ingenic.c +12 -1
index 86d285a800c5d..6a16729d0a235 100644
@@ -209,10 +209,14 @@ static int jz4730_nand_cs4_pins[] = { 0x56, };
 static int jz4730_nand_cs5_pins[] = { 0x57, };
 static int jz4730_pwm_pwm0_pins[] = { 0x5e, };
 static int jz4730_pwm_pwm1_pins[] = { 0x5f, };
-
 static int jz4730_mii_pins[] = { 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
 				 0x77, 0x78, 0x19, 0x7a, 0x1b, 0x7c, };
 
+static int jz4730_i2s_mclk_pins[] = { 0x44, };
+static int jz4730_i2s_acreset_pins[] = { 0x45, };
+static int jz4730_i2s_data_pins[] = { 0x46, 0x47, };
+static int jz4730_i2s_clock_pins[] = { 0x4d, 0x4e, };
+
 static u8 jz4730_lcd_8bit_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, };
 
 static const struct group_desc jz4730_groups[] = {
@@ -235,6 +239,11 @@ static const struct group_desc jz4730_groups[] = {
 	INGENIC_PIN_GROUP("pwm0", jz4730_pwm_pwm0, 1),
 	INGENIC_PIN_GROUP("pwm1", jz4730_pwm_pwm1, 1),
 	INGENIC_PIN_GROUP("mii", jz4730_mii, 1),
+	INGENIC_PIN_GROUP("i2s-mclk-out", jz4730_i2s_mclk, 1),
+	INGENIC_PIN_GROUP("i2s-acreset", jz4730_i2s_acreset, 1),
+	INGENIC_PIN_GROUP("i2s-data", jz4730_i2s_data, 1),
+	INGENIC_PIN_GROUP("i2s-master", jz4730_i2s_clock, 1),
+	INGENIC_PIN_GROUP("i2s-slave", jz4730_i2s_clock, 2),
 };
 
 static const char *jz4730_mmc_groups[] = { "mmc-1bit", "mmc-4bit", };
@@ -251,6 +260,7 @@ static const char *jz4730_nand_groups[] = {
 static const char *jz4730_pwm0_groups[] = { "pwm0", };
 static const char *jz4730_pwm1_groups[] = { "pwm1", };
 static const char *jz4730_mii_groups[] = { "mii", };
+static const char *jz4730_i2s_groups[] = { "i2s-data", "i2s-master", "i2s-slave", };
 
 static const struct function_desc jz4730_functions[] = {
 	INGENIC_PIN_FUNCTION("mmc", jz4730_mmc),
@@ -263,6 +273,7 @@ static const struct function_desc jz4730_functions[] = {
 	INGENIC_PIN_FUNCTION("pwm0", jz4730_pwm0),
 	INGENIC_PIN_FUNCTION("pwm1", jz4730_pwm1),
 	INGENIC_PIN_FUNCTION("mii", jz4730_mii),
+	INGENIC_PIN_FUNCTION("i2s", jz4730_i2s),
 };
 
 static const struct ingenic_chip_info jz4730_chip_info = {
Signature · 1 line
2.47.0
maintainer
#3 lore raw

Re: [PATCH 2/4] pinctrl: ingenic: add x1600 support

In reply to H. Nikolaus Schaller

Hi Nikolaus, and everyone involved,

Le mercredi 26 février 2025 à 18:16 +0100, H. Nikolaus Schaller a écrit :

Quoted 138 lines

From: Paul Boddie <[email protected]>

Add support for the Lumissil/Ingenic X1600 SoC.

It uses shadow registers to commit changes to multiple pinctrl registers in parallel.

Define specific Chip ID, register offsets, pin tables etc.

Handling the unique X1600_GPIO_PU only for the x1600 but not for x1830 and above must be carefully taken into account.

---
 drivers/pinctrl/pinctrl-ingenic.c | 242
+++++++++++++++++++++++++++++-

 1 file changed, 240 insertions(+), 2 deletions(-)
drivers/pinctrl/pinctrl-ingenic.c +1 -1
index bc7ee54e062b5..dfdc89ece9b8a 100644
@@ -3,7 +3,7 @@
   * Ingenic SoCs pinctrl driver
   *
   * Copyright (c) 2017 Paul Cercueil <[email protected]>
- * Copyright (c) 2017, 2019 Paul Boddie <[email protected]>
+ * Copyright (c) 2017, 2019, 2020, 2023 Paul Boddie

<[email protected]>
  * Copyright (c) 2019, 2020 周琰杰 (Zhou Yanjie) <[email protected]>
  */

drivers/pinctrl/pinctrl-ingenic.c +0 -0
@@ -58,6 +58,8 @@
  #define JZ4770_GPIO_FLAG			0x50
  #define JZ4770_GPIO_PEN				0x70

drivers/pinctrl/pinctrl-ingenic.c +2 -0
+#define X1600_GPIO_PU				 0x80
+

 #define X1830_GPIO_PEL 0x110
 #define X1830_GPIO_PEH 0x120
 #define X1830_GPIO_SR 0x150

drivers/pinctrl/pinctrl-ingenic.c +1 -0
@@ -112,6 +114,7 @@ enum jz_version {
  	ID_JZ4780,
  	ID_X1000,
  	ID_X1500,
+	ID_X1600,
  	ID_X1830,
  	ID_X2000,
  	ID_X2100,
@@ -162,6 +165,7 @@ static const unsigned long enabled_socs =

  IS_ENABLED(CONFIG_MACH_JZ4780) << ID_JZ4780 | IS_ENABLED(CONFIG_MACH_X1000) << ID_X1000 | IS_ENABLED(CONFIG_MACH_X1500) << ID_X1500 |

drivers/pinctrl/pinctrl-ingenic.c +1 -0
+	IS_ENABLED(CONFIG_MACH_X1600) << ID_X1600 |

  IS_ENABLED(CONFIG_MACH_X1830) << ID_X1830 | IS_ENABLED(CONFIG_MACH_X2000) << ID_X2000 | IS_ENABLED(CONFIG_MACH_X2100) << ID_X2100;

drivers/pinctrl/pinctrl-ingenic.c +0 -0
@@ -2351,6 +2355,231 @@ static const struct ingenic_chip_info
 x1500_chip_info = {
  	.access_table = &x1000_access_table,
  };

drivers/pinctrl/pinctrl-ingenic.c +17 -0
+static const u32 x1600_pull_ups[4] = {
+	0xffffffff, 0xdffbf7bf, 0x987e0000, 0x0000003f,
+};
+
+static const u32 x1600_pull_downs[4] = {
+	0x00000000, 0x00000000, 0x07000007, 0x00000000,
+};
+
+static int x1600_uart0_data_pins[] = { 0x27, 0x28, };
+static int x1600_uart0_hwflow_pins[] = { 0x29, 0x2a, };
+static int x1600_uart1_data_pins[] = { 0x23, 0x22, };
+static int x1600_uart1_hwflow_pins[] = { 0x25, 0x24, };
+static int x1600_uart2_data_a_pins[] = { 0x1f, 0x1e, };
+static int x1600_uart2_data_b_pins[] = { 0x21, 0x20, };
+static int x1600_uart3_data_b_pins[] = { 0x25, 0x24, };
+static int x1600_uart3_data_d_pins[] = { 0x65, 0x64, };
+static int x1600_sfc_pins[] = { 0x53, 0x54, 0x55, 0x56, 0x51, 0x52,

0x24, };

drivers/pinctrl/pinctrl-ingenic.c +52 -0
+static int x1600_ssi_dt_a_pins[] = { 0x1e, };
+static int x1600_ssi_dt_b_pins[] = { 0x2d, };
+static int x1600_ssi_dr_a_pins[] = { 0x1d, };
+static int x1600_ssi_dr_b_pins[] = { 0x2e, };
+static int x1600_ssi_clk_a_pins[] = { 0x1f, };
+static int x1600_ssi_clk_b_pins[] = { 0x2c, };
+static int x1600_ssi_ce0_a_pins[] = { 0x1c, };
+static int x1600_ssi_ce0_b_pins[] = { 0x31, };
+static int x1600_ssi_ce1_a_pins[] = { 0x22, };
+static int x1600_ssi_ce1_b_pins[] = { 0x30, };
+static int x1600_mmc0_1bit_b_pins[] = { 0x2c, 0x2d, 0x2e, };
+static int x1600_mmc0_4bit_b_pins[] = { 0x2f, 0x30, 0x31, };
+static int x1600_mmc0_1bit_c_pins[] = { 0x51, 0x53, 0x54, };
+static int x1600_mmc0_4bit_c_pins[] = { 0x56, 0x55, 0x52, };
+static int x1600_mmc1_1bit_pins[] = { 0x60, 0x61, 0x62, };
+static int x1600_mmc1_4bit_pins[] = { 0x63, 0x64, 0x65, };
+static int x1600_i2c0_a_pins[] = { 0x1d, 0x1c, };
+static int x1600_i2c0_b_pins[] = { 0x3f, 0x3e, };
+static int x1600_i2c1_b_15_pins[] = { 0x30, 0x2f, };
+static int x1600_i2c1_b_19_pins[] = { 0x34, 0x33, };
+static int x1600_i2s_data_tx_pins[] = { 0x39, };
+static int x1600_i2s_data_rx_pins[] = { 0x35, };
+static int x1600_i2s_clk_rx_pins[] = { 0x37, 0x38, };
+static int x1600_i2s_clk_tx_pins[] = { 0x3b, 0x3c, };
+static int x1600_i2s_sysclk_pins[] = { 0x36, 0x3a, };
+
+static int x1600_cim_pins[] = {
+	0x14, 0x16, 0x15, 0x18, 0x13,
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+};
+
+static int x1600_slcd_8bit_pins[] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	0x17, 0x19, 0x1a, 0x1b,
+};
+
+static int x1600_slcd_16bit_pins[] = {
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+};
+
+static int x1600_lcd_16bit_pins[] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+	0x18, 0x19, 0x1a, 0x1b,
+};
+
+static int x1600_lcd_18bit_pins[] = {
+	0x10, 0x11,
+};
+
+static int x1600_lcd_24bit_pins[] = {
+	0x12, 0x13, 0x14, 0x15, 0x16, 0x17,

drivers/pinctrl/pinctrl-ingenic.c static const struct ingenic_chip_info x1500_chip_info = { · line 2436

Quoted 10 lines
drivers/pinctrl/pinctrl-ingenic.c +10 -0
+};
+
+static int x1600_pwm_pwm0_pins[] = { 0x40, };
+static int x1600_pwm_pwm1_pins[] = { 0x41, };
+static int x1600_pwm_pwm2_pins[] = { 0x42, };
+static int x1600_pwm_pwm3_pins[] = { 0x58, };
+static int x1600_pwm_pwm4_pins[] = { 0x59, };
+static int x1600_pwm_pwm5_pins[] = { 0x33, 0x5a, };
+static int x1600_pwm_pwm6_pins[] = { 0x29, 0x34, };
+static int x1600_pwm_pwm7_pins[] = { 0x2a, 0x35, };

Just a quick question about these ones: why are there 2 pins here? If you have the PWM5/6/7 function on two different pins then you should probably have two groups.

The rest looks OK.

Cheers,
-Paul

Quoted 214 lines
drivers/pinctrl/pinctrl-ingenic.c +58 -0
+
+static int x1600_mac_pins[] = {
+	0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c,
+};
+
+static int x1600_sfc_funcs[] = { 0, 0, 0, 0, 0, 0, 2, };
+
+static int x1600_pwm_pwm5_funcs[] = { 2, 1, };
+static int x1600_pwm_pwm6_funcs[] = { 1, 2, };
+static int x1600_pwm_pwm7_funcs[] = { 1, 2, };
+
+static const struct group_desc x1600_groups[] = {
+	INGENIC_PIN_GROUP("uart0-data", x1600_uart0_data, 0),
+	INGENIC_PIN_GROUP("uart0-hwflow", x1600_uart0_hwflow, 0),
+	INGENIC_PIN_GROUP("uart1-data", x1600_uart1_data, 1),
+	INGENIC_PIN_GROUP("uart1-hwflow", x1600_uart1_hwflow, 1),
+	INGENIC_PIN_GROUP("uart2-data-a", x1600_uart2_data_a, 2),
+	INGENIC_PIN_GROUP("uart2-data-b", x1600_uart2_data_b, 1),
+	INGENIC_PIN_GROUP("uart3-data-b", x1600_uart3_data_b, 0),
+	INGENIC_PIN_GROUP("uart3-data-d", x1600_uart3_data_d, 2),
+	INGENIC_PIN_GROUP_FUNCS("sfc", x1600_sfc, x1600_sfc_funcs),
+	INGENIC_PIN_GROUP("ssi-dt-a", x1600_ssi_dt_a, 0),
+	INGENIC_PIN_GROUP("ssi-dt-b", x1600_ssi_dt_b, 1),
+	INGENIC_PIN_GROUP("ssi-dr-a", x1600_ssi_dr_a, 0),
+	INGENIC_PIN_GROUP("ssi-dr-b", x1600_ssi_dr_b, 1),
+	INGENIC_PIN_GROUP("ssi-clk-a", x1600_ssi_clk_a, 0),
+	INGENIC_PIN_GROUP("ssi-clk-b", x1600_ssi_clk_b, 1),
+	INGENIC_PIN_GROUP("ssi-ce0-a", x1600_ssi_ce0_a, 0),
+	INGENIC_PIN_GROUP("ssi-ce0-b", x1600_ssi_ce0_b, 1),
+	INGENIC_PIN_GROUP("ssi-ce1-a", x1600_ssi_ce1_a, 2),
+	INGENIC_PIN_GROUP("ssi-ce1-b", x1600_ssi_ce1_b, 1),
+	INGENIC_PIN_GROUP("mmc0-1bit-b", x1600_mmc0_1bit_b, 0),
+	INGENIC_PIN_GROUP("mmc0-4bit-b", x1600_mmc0_4bit_b, 0),
+	INGENIC_PIN_GROUP("mmc0-1bit-c", x1600_mmc0_1bit_c, 1),
+	INGENIC_PIN_GROUP("mmc0-4bit-c", x1600_mmc0_4bit_c, 1),
+	INGENIC_PIN_GROUP("mmc1-1bit", x1600_mmc1_1bit, 0),
+	INGENIC_PIN_GROUP("mmc1-4bit", x1600_mmc1_4bit, 0),
+	INGENIC_PIN_GROUP("i2c0-data-a", x1600_i2c0_a, 2),
+	INGENIC_PIN_GROUP("i2c0-data-b", x1600_i2c0_b, 0),
+	INGENIC_PIN_GROUP("i2c1-data-b-15", x1600_i2c1_b_15, 2),
+	INGENIC_PIN_GROUP("i2c1-data-b-19", x1600_i2c1_b_19, 0),
+	INGENIC_PIN_GROUP("i2s-data-tx", x1600_i2s_data_tx, 0),
+	INGENIC_PIN_GROUP("i2s-data-rx", x1600_i2s_data_rx, 0),
+	INGENIC_PIN_GROUP("i2s-clk-rx", x1600_i2s_clk_rx, 0),
+	INGENIC_PIN_GROUP("i2s-clk-tx", x1600_i2s_clk_tx, 0),
+	INGENIC_PIN_GROUP("i2s-sysclk", x1600_i2s_sysclk, 0),
+	INGENIC_PIN_GROUP("cim-data", x1600_cim, 2),
+	INGENIC_PIN_GROUP("slcd-8bit", x1600_slcd_8bit, 1),
+	INGENIC_PIN_GROUP("slcd-16bit", x1600_slcd_16bit, 1),
+	INGENIC_PIN_GROUP("lcd-16bit", x1600_lcd_16bit, 0),
+	INGENIC_PIN_GROUP("lcd-18bit", x1600_lcd_18bit, 0),
+	INGENIC_PIN_GROUP("lcd-24bit", x1600_lcd_24bit, 0),
+	INGENIC_PIN_GROUP("pwm0", x1600_pwm_pwm0, 0),
+	INGENIC_PIN_GROUP("pwm1", x1600_pwm_pwm1, 0),
+	INGENIC_PIN_GROUP("pwm2", x1600_pwm_pwm2, 0),
+	INGENIC_PIN_GROUP("pwm3", x1600_pwm_pwm3, 1),
+	INGENIC_PIN_GROUP("pwm4", x1600_pwm_pwm4, 1),
+	INGENIC_PIN_GROUP_FUNCS("pwm5", x1600_pwm_pwm5,

x1600_pwm_pwm5_funcs),

drivers/pinctrl/pinctrl-ingenic.c +1 -0
+	INGENIC_PIN_GROUP_FUNCS("pwm6", x1600_pwm_pwm6,

x1600_pwm_pwm6_funcs),

drivers/pinctrl/pinctrl-ingenic.c +1 -0
+	INGENIC_PIN_GROUP_FUNCS("pwm7", x1600_pwm_pwm7,

x1600_pwm_pwm7_funcs),

drivers/pinctrl/pinctrl-ingenic.c +4 -0
+	INGENIC_PIN_GROUP("mac", x1600_mac, 1),
+};
+
+static const char * const x1600_uart0_groups[] = { "uart0-data",

"uart0-hwflow", };
+static const char * const x1600_uart1_groups[] = { "uart1-data", "uart1-hwflow", };
+static const char * const x1600_uart2_groups[] = { "uart2-data-a", "uart2-data-b", };
+static const char * const x1600_uart3_groups[] = { "uart3-data-b", "uart3-data-d", };

drivers/pinctrl/pinctrl-ingenic.c +12 -0
+
+static const char * const x1600_sfc_groups[] = { "sfc", };
+
+static const char * const x1600_ssi_groups[] = {
+	"ssi-dt-a", "ssi-dt-b",
+	"ssi-dr-a", "ssi-dr-b",
+	"ssi-clk-a", "ssi-clk-b",
+	"ssi-ce0-a", "ssi-ce0-b",
+	"ssi-ce1-a", "ssi-ce1-b",
+};
+
+static const char * const x1600_mmc0_groups[] = { "mmc0-1bit-b",

"mmc0-4bit-b",

drivers/pinctrl/pinctrl-ingenic.c +4 -0
+	"mmc0-1bit-c", "mmc0-4bit-c",
+};
+
+static const char * const x1600_mmc1_groups[] = { "mmc1-1bit",

"mmc1-4bit", };

drivers/pinctrl/pinctrl-ingenic.c +2 -0
+
+static const char * const x1600_i2c0_groups[] = { "i2c0-data-a",

"i2c0-data-b", };
+static const char * const x1600_i2c1_groups[] = { "i2c1-data-b-15", "i2c1-data-b-19", };

drivers/pinctrl/pinctrl-ingenic.c +3 -0
+
+static const char * const x1600_i2s_groups[] = {
+	"i2s-data-tx", "i2s-data-rx", "i2s-clk-rx", "i2s-clk-tx",

"i2s-sysclk",

drivers/pinctrl/pinctrl-ingenic.c +5 -0
+};
+
+static const char * const x1600_cim_groups[] = { "cim-data", };
+
+static const char * const x1600_lcd_groups[] = { "slcd-8bit", "slcd-

16bit",

drivers/pinctrl/pinctrl-ingenic.c +52 -0
+	"lcd-16bit", "lcd-18bit", "lcd-24bit", "lcd-no-pins",
+};
+
+static const char * const x1600_pwm0_groups[] = { "pwm0", };
+static const char * const x1600_pwm1_groups[] = { "pwm1", };
+static const char * const x1600_pwm2_groups[] = { "pwm2", };
+static const char * const x1600_pwm3_groups[] = { "pwm3", };
+static const char * const x1600_pwm4_groups[] = { "pwm4", };
+static const char * const x1600_pwm5_groups[] = { "pwm5", };
+static const char * const x1600_pwm6_groups[] = { "pwm6", };
+static const char * const x1600_pwm7_groups[] = { "pwm7", };
+
+static const char * const x1600_mac_groups[] = { "mac", };
+
+static const struct function_desc x1600_functions[] = {
+	INGENIC_PIN_FUNCTION("uart0", x1600_uart0),
+	INGENIC_PIN_FUNCTION("uart1", x1600_uart1),
+	INGENIC_PIN_FUNCTION("uart2", x1600_uart2),
+	INGENIC_PIN_FUNCTION("uart3", x1600_uart3),
+	INGENIC_PIN_FUNCTION("sfc", x1600_sfc),
+	INGENIC_PIN_FUNCTION("ssi", x1600_ssi),
+	INGENIC_PIN_FUNCTION("mmc0", x1600_mmc0),
+	INGENIC_PIN_FUNCTION("mmc1", x1600_mmc1),
+	INGENIC_PIN_FUNCTION("i2c0", x1600_i2c0),
+	INGENIC_PIN_FUNCTION("i2c1", x1600_i2c1),
+	INGENIC_PIN_FUNCTION("i2s", x1600_i2s),
+	INGENIC_PIN_FUNCTION("cim", x1600_cim),
+	INGENIC_PIN_FUNCTION("lcd", x1600_lcd),
+	INGENIC_PIN_FUNCTION("pwm0", x1600_pwm0),
+	INGENIC_PIN_FUNCTION("pwm1", x1600_pwm1),
+	INGENIC_PIN_FUNCTION("pwm2", x1600_pwm2),
+	INGENIC_PIN_FUNCTION("pwm3", x1600_pwm3),
+	INGENIC_PIN_FUNCTION("pwm4", x1600_pwm4),
+	INGENIC_PIN_FUNCTION("pwm5", x1600_pwm5),
+	INGENIC_PIN_FUNCTION("pwm6", x1600_pwm6),
+	INGENIC_PIN_FUNCTION("pwm7", x1600_pwm7),
+	INGENIC_PIN_FUNCTION("mac", x1600_mac),
+};
+
+static const struct ingenic_chip_info x1600_chip_info = {
+	.num_chips = 4,
+	.reg_offset = 0x100,
+	.version = ID_X1600,
+	.groups = x1600_groups,
+	.num_groups = ARRAY_SIZE(x1600_groups),
+	.functions = x1600_functions,
+	.num_functions = ARRAY_SIZE(x1600_functions),
+	.pull_ups = x1600_pull_ups,
+	.pull_downs = x1600_pull_downs,
+	.access_table = &x1000_access_table,
+};
+

 static const u32 x1830_pull_ups[4] = { 0x5fdfffc0, 0xffffefff, 0x1ffffbff, 0x0fcff3fc, };

drivers/pinctrl/pinctrl-ingenic.c +0 -0
@@ -3860,7 +4089,9 @@ static int ingenic_pinconf_get(struct
 pinctrl_dev *pctldev,

  pulldown = (bias == GPIO_PULL_DOWN) && (jzpc->info-

Quoted 1 line

pull_downs[offt] & BIT(idx));


  } else {

drivers/pinctrl/pinctrl-ingenic.c +2 -1
-		if (is_soc_or_above(jzpc, ID_JZ4770))
+		if (is_soc_or_above(jzpc, ID_X1600))
+			pull = ingenic_get_pin_config(jzpc, pin,

X1600_GPIO_PU);

drivers/pinctrl/pinctrl-ingenic.c +1 -0
+		else if (is_soc_or_above(jzpc, ID_JZ4770))

  pull = !ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PEN);
  else if (is_soc_or_above(jzpc, ID_JZ4740)) pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS);

drivers/pinctrl/pinctrl-ingenic.c +0 -0
@@ -3959,6 +4190,8 @@ static void ingenic_set_bias(struct
 ingenic_pinctrl *jzpc,
  					REG_SET(X1830_GPIO_PEH),
 bias << idxh);
  		}

drivers/pinctrl/pinctrl-ingenic.c +2 -0
+	} else if (is_soc_or_above(jzpc, ID_X1600)) {
+		ingenic_config_pin(jzpc, pin, X1600_GPIO_PU, bias);

  } else if (is_soc_or_above(jzpc, ID_JZ4770)) { ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PEN, !bias);
  } else if (is_soc_or_above(jzpc, ID_JZ4740)) {

drivers/pinctrl/pinctrl-ingenic.c +1 -0
@@ -4150,6 +4383,7 @@ static const struct of_device_id
 ingenic_gpio_of_matches[] __initconst = {
  	{ .compatible = "ingenic,jz4775-gpio" },
  	{ .compatible = "ingenic,jz4780-gpio" },
  	{ .compatible = "ingenic,x1000-gpio" },
+	{ .compatible = "ingenic,x1600-gpio" },
  	{ .compatible = "ingenic,x1830-gpio" },
  	{ .compatible = "ingenic,x2000-gpio" },

  { .compatible = "ingenic,x2100-gpio" },

drivers/pinctrl/pinctrl-ingenic.c +4 -0
@@ -4397,6 +4631,10 @@ static const struct of_device_id
 ingenic_pinctrl_of_matches[] = {
  		.compatible = "ingenic,x1500-pinctrl",
  		.data = IF_ENABLED(CONFIG_MACH_X1500,
 &x1500_chip_info)
  	},
+	{
+		.compatible = "ingenic,x1600-pinctrl",
+		.data = IF_ENABLED(CONFIG_MACH_X1600,
 &x1600_chip_info)
+	},

  {
  .compatible = "ingenic,x1830-pinctrl", .data = IF_ENABLED(CONFIG_MACH_X1830, &x1830_chip_info)

#4 lore raw

Re: [PATCH 2/4] pinctrl: ingenic: add x1600 support

Hi Paul,

Quoted 150 lines

Am 26.02.2025 um 19:43 schrieb Paul Cercueil <[email protected]>:

Hi Nikolaus, and everyone involved,

Le mercredi 26 février 2025 à 18:16 +0100, H. Nikolaus Schaller a écrit :

Quoted 144 lines

From: Paul Boddie <[email protected]>

Add support for the Lumissil/Ingenic X1600 SoC.

It uses shadow registers to commit changes to multiple pinctrl registers in parallel.

Define specific Chip ID, register offsets, pin tables etc.

Handling the unique X1600_GPIO_PU only for the x1600 but not for x1830 and above must be carefully taken into account.

---
 drivers/pinctrl/pinctrl-ingenic.c | 242
+++++++++++++++++++++++++++++-
 1 file changed, 240 insertions(+), 2 deletions(-)
drivers/pinctrl/pinctrl-ingenic.c +1 -1
index bc7ee54e062b5..dfdc89ece9b8a 100644
@@ -3,7 +3,7 @@
  * Ingenic SoCs pinctrl driver
  *
  * Copyright (c) 2017 Paul Cercueil <[email protected]>
- * Copyright (c) 2017, 2019 Paul Boddie <[email protected]>
+ * Copyright (c) 2017, 2019, 2020, 2023 Paul Boddie

<[email protected]>
* Copyright (c) 2019, 2020 周琰杰 (Zhou Yanjie)
<[email protected]>
*/

drivers/pinctrl/pinctrl-ingenic.c +79 -0
@@ -58,6 +58,8 @@
 #define JZ4770_GPIO_FLAG 0x50
 #define JZ4770_GPIO_PEN 0x70
 
+#define X1600_GPIO_PU 0x80
+
 #define X1830_GPIO_PEL 0x110
 #define X1830_GPIO_PEH 0x120
 #define X1830_GPIO_SR 0x150
@@ -112,6 +114,7 @@ enum jz_version {
  ID_JZ4780,
  ID_X1000,
  ID_X1500,
+ ID_X1600,
  ID_X1830,
  ID_X2000,
  ID_X2100,
@@ -162,6 +165,7 @@ static const unsigned long enabled_socs =
  IS_ENABLED(CONFIG_MACH_JZ4780) << ID_JZ4780 |
  IS_ENABLED(CONFIG_MACH_X1000) << ID_X1000 |
  IS_ENABLED(CONFIG_MACH_X1500) << ID_X1500 |
+ IS_ENABLED(CONFIG_MACH_X1600) << ID_X1600 |
  IS_ENABLED(CONFIG_MACH_X1830) << ID_X1830 |
  IS_ENABLED(CONFIG_MACH_X2000) << ID_X2000 |
  IS_ENABLED(CONFIG_MACH_X2100) << ID_X2100;
@@ -2351,6 +2355,231 @@ static const struct ingenic_chip_info
 x1500_chip_info = {
  .access_table = &x1000_access_table,
 };
 
+static const u32 x1600_pull_ups[4] = {
+ 0xffffffff, 0xdffbf7bf, 0x987e0000, 0x0000003f,
+};
+
+static const u32 x1600_pull_downs[4] = {
+ 0x00000000, 0x00000000, 0x07000007, 0x00000000,
+};
+
+static int x1600_uart0_data_pins[] = { 0x27, 0x28, };
+static int x1600_uart0_hwflow_pins[] = { 0x29, 0x2a, };
+static int x1600_uart1_data_pins[] = { 0x23, 0x22, };
+static int x1600_uart1_hwflow_pins[] = { 0x25, 0x24, };
+static int x1600_uart2_data_a_pins[] = { 0x1f, 0x1e, };
+static int x1600_uart2_data_b_pins[] = { 0x21, 0x20, };
+static int x1600_uart3_data_b_pins[] = { 0x25, 0x24, };
+static int x1600_uart3_data_d_pins[] = { 0x65, 0x64, };
+static int x1600_sfc_pins[] = { 0x53, 0x54, 0x55, 0x56, 0x51, 0x52,
 0x24, };
+static int x1600_ssi_dt_a_pins[] = { 0x1e, };
+static int x1600_ssi_dt_b_pins[] = { 0x2d, };
+static int x1600_ssi_dr_a_pins[] = { 0x1d, };
+static int x1600_ssi_dr_b_pins[] = { 0x2e, };
+static int x1600_ssi_clk_a_pins[] = { 0x1f, };
+static int x1600_ssi_clk_b_pins[] = { 0x2c, };
+static int x1600_ssi_ce0_a_pins[] = { 0x1c, };
+static int x1600_ssi_ce0_b_pins[] = { 0x31, };
+static int x1600_ssi_ce1_a_pins[] = { 0x22, };
+static int x1600_ssi_ce1_b_pins[] = { 0x30, };
+static int x1600_mmc0_1bit_b_pins[] = { 0x2c, 0x2d, 0x2e, };
+static int x1600_mmc0_4bit_b_pins[] = { 0x2f, 0x30, 0x31, };
+static int x1600_mmc0_1bit_c_pins[] = { 0x51, 0x53, 0x54, };
+static int x1600_mmc0_4bit_c_pins[] = { 0x56, 0x55, 0x52, };
+static int x1600_mmc1_1bit_pins[] = { 0x60, 0x61, 0x62, };
+static int x1600_mmc1_4bit_pins[] = { 0x63, 0x64, 0x65, };
+static int x1600_i2c0_a_pins[] = { 0x1d, 0x1c, };
+static int x1600_i2c0_b_pins[] = { 0x3f, 0x3e, };
+static int x1600_i2c1_b_15_pins[] = { 0x30, 0x2f, };
+static int x1600_i2c1_b_19_pins[] = { 0x34, 0x33, };
+static int x1600_i2s_data_tx_pins[] = { 0x39, };
+static int x1600_i2s_data_rx_pins[] = { 0x35, };
+static int x1600_i2s_clk_rx_pins[] = { 0x37, 0x38, };
+static int x1600_i2s_clk_tx_pins[] = { 0x3b, 0x3c, };
+static int x1600_i2s_sysclk_pins[] = { 0x36, 0x3a, };
+
+static int x1600_cim_pins[] = {
+ 0x14, 0x16, 0x15, 0x18, 0x13,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+};
+
+static int x1600_slcd_8bit_pins[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x17, 0x19, 0x1a, 0x1b,
+};
+
+static int x1600_slcd_16bit_pins[] = {
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+};
+
+static int x1600_lcd_16bit_pins[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x18, 0x19, 0x1a, 0x1b,
+};
+
+static int x1600_lcd_18bit_pins[] = {
+ 0x10, 0x11,
+};
+
+static int x1600_lcd_24bit_pins[] = {
+ 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+};
+
+static int x1600_pwm_pwm0_pins[] = { 0x40, };
+static int x1600_pwm_pwm1_pins[] = { 0x41, };
+static int x1600_pwm_pwm2_pins[] = { 0x42, };
+static int x1600_pwm_pwm3_pins[] = { 0x58, };
Quoted 8 lines

drivers/pinctrl/pinctrl-ingenic.c static const struct ingenic_chip_info x1500_chip_info = { · line 2436

Quoted 4 lines
drivers/pinctrl/pinctrl-ingenic.c +4 -0
+static int x1600_pwm_pwm4_pins[] = { 0x59, };
+static int x1600_pwm_pwm5_pins[] = { 0x33, 0x5a, };
+static int x1600_pwm_pwm6_pins[] = { 0x29, 0x34, };
+static int x1600_pwm_pwm7_pins[] = { 0x2a, 0x35, };

Just a quick question about these ones: why are there 2 pins here? If you have the PWM5/6/7 function on two different pins then you should probably have two groups.

I think they are added through INGENIC_PIN_GROUP_FUNCS() to x1600_groups[].

So the pins list is different from pwm0 to 4 which uses INGENIC_PIN_GROUP().

But Paul Boddie should know even better than me.

Quoted 5 lines

The rest looks OK.

Cheers,
-Paul

Best regards and thanks,
Nikolaus

Quoted 216 lines
Quoted 215 lines
drivers/pinctrl/pinctrl-ingenic.c +59 -0
+
+static int x1600_mac_pins[] = {
+ 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c,
+};
+
+static int x1600_sfc_funcs[] = { 0, 0, 0, 0, 0, 0, 2, };
+
+static int x1600_pwm_pwm5_funcs[] = { 2, 1, };
+static int x1600_pwm_pwm6_funcs[] = { 1, 2, };
+static int x1600_pwm_pwm7_funcs[] = { 1, 2, };
+
+static const struct group_desc x1600_groups[] = {
+ INGENIC_PIN_GROUP("uart0-data", x1600_uart0_data, 0),
+ INGENIC_PIN_GROUP("uart0-hwflow", x1600_uart0_hwflow, 0),
+ INGENIC_PIN_GROUP("uart1-data", x1600_uart1_data, 1),
+ INGENIC_PIN_GROUP("uart1-hwflow", x1600_uart1_hwflow, 1),
+ INGENIC_PIN_GROUP("uart2-data-a", x1600_uart2_data_a, 2),
+ INGENIC_PIN_GROUP("uart2-data-b", x1600_uart2_data_b, 1),
+ INGENIC_PIN_GROUP("uart3-data-b", x1600_uart3_data_b, 0),
+ INGENIC_PIN_GROUP("uart3-data-d", x1600_uart3_data_d, 2),
+ INGENIC_PIN_GROUP_FUNCS("sfc", x1600_sfc, x1600_sfc_funcs),
+ INGENIC_PIN_GROUP("ssi-dt-a", x1600_ssi_dt_a, 0),
+ INGENIC_PIN_GROUP("ssi-dt-b", x1600_ssi_dt_b, 1),
+ INGENIC_PIN_GROUP("ssi-dr-a", x1600_ssi_dr_a, 0),
+ INGENIC_PIN_GROUP("ssi-dr-b", x1600_ssi_dr_b, 1),
+ INGENIC_PIN_GROUP("ssi-clk-a", x1600_ssi_clk_a, 0),
+ INGENIC_PIN_GROUP("ssi-clk-b", x1600_ssi_clk_b, 1),
+ INGENIC_PIN_GROUP("ssi-ce0-a", x1600_ssi_ce0_a, 0),
+ INGENIC_PIN_GROUP("ssi-ce0-b", x1600_ssi_ce0_b, 1),
+ INGENIC_PIN_GROUP("ssi-ce1-a", x1600_ssi_ce1_a, 2),
+ INGENIC_PIN_GROUP("ssi-ce1-b", x1600_ssi_ce1_b, 1),
+ INGENIC_PIN_GROUP("mmc0-1bit-b", x1600_mmc0_1bit_b, 0),
+ INGENIC_PIN_GROUP("mmc0-4bit-b", x1600_mmc0_4bit_b, 0),
+ INGENIC_PIN_GROUP("mmc0-1bit-c", x1600_mmc0_1bit_c, 1),
+ INGENIC_PIN_GROUP("mmc0-4bit-c", x1600_mmc0_4bit_c, 1),
+ INGENIC_PIN_GROUP("mmc1-1bit", x1600_mmc1_1bit, 0),
+ INGENIC_PIN_GROUP("mmc1-4bit", x1600_mmc1_4bit, 0),
+ INGENIC_PIN_GROUP("i2c0-data-a", x1600_i2c0_a, 2),
+ INGENIC_PIN_GROUP("i2c0-data-b", x1600_i2c0_b, 0),
+ INGENIC_PIN_GROUP("i2c1-data-b-15", x1600_i2c1_b_15, 2),
+ INGENIC_PIN_GROUP("i2c1-data-b-19", x1600_i2c1_b_19, 0),
+ INGENIC_PIN_GROUP("i2s-data-tx", x1600_i2s_data_tx, 0),
+ INGENIC_PIN_GROUP("i2s-data-rx", x1600_i2s_data_rx, 0),
+ INGENIC_PIN_GROUP("i2s-clk-rx", x1600_i2s_clk_rx, 0),
+ INGENIC_PIN_GROUP("i2s-clk-tx", x1600_i2s_clk_tx, 0),
+ INGENIC_PIN_GROUP("i2s-sysclk", x1600_i2s_sysclk, 0),
+ INGENIC_PIN_GROUP("cim-data", x1600_cim, 2),
+ INGENIC_PIN_GROUP("slcd-8bit", x1600_slcd_8bit, 1),
+ INGENIC_PIN_GROUP("slcd-16bit", x1600_slcd_16bit, 1),
+ INGENIC_PIN_GROUP("lcd-16bit", x1600_lcd_16bit, 0),
+ INGENIC_PIN_GROUP("lcd-18bit", x1600_lcd_18bit, 0),
+ INGENIC_PIN_GROUP("lcd-24bit", x1600_lcd_24bit, 0),
+ INGENIC_PIN_GROUP("pwm0", x1600_pwm_pwm0, 0),
+ INGENIC_PIN_GROUP("pwm1", x1600_pwm_pwm1, 0),
+ INGENIC_PIN_GROUP("pwm2", x1600_pwm_pwm2, 0),
+ INGENIC_PIN_GROUP("pwm3", x1600_pwm_pwm3, 1),
+ INGENIC_PIN_GROUP("pwm4", x1600_pwm_pwm4, 1),
+ INGENIC_PIN_GROUP_FUNCS("pwm5", x1600_pwm_pwm5,
 x1600_pwm_pwm5_funcs),
+ INGENIC_PIN_GROUP_FUNCS("pwm6", x1600_pwm_pwm6,

x1600_pwm_pwm6_funcs),
+ INGENIC_PIN_GROUP_FUNCS("pwm7", x1600_pwm_pwm7, x1600_pwm_pwm7_funcs),
+ INGENIC_PIN_GROUP("mac", x1600_mac, 1),

drivers/pinctrl/pinctrl-ingenic.c +3 -0
+};
+
+static const char * const x1600_uart0_groups[] = { "uart0-data",

"uart0-hwflow", };
+static const char * const x1600_uart1_groups[] = { "uart1-data", "uart1-hwflow", };
+static const char * const x1600_uart2_groups[] = { "uart2-data-a", "uart2-data-b", };
+static const char * const x1600_uart3_groups[] = { "uart3-data-b", "uart3-data-d", };

drivers/pinctrl/pinctrl-ingenic.c +12 -0
+
+static const char * const x1600_sfc_groups[] = { "sfc", };
+
+static const char * const x1600_ssi_groups[] = {
+ "ssi-dt-a", "ssi-dt-b",
+ "ssi-dr-a", "ssi-dr-b",
+ "ssi-clk-a", "ssi-clk-b",
+ "ssi-ce0-a", "ssi-ce0-b",
+ "ssi-ce1-a", "ssi-ce1-b",
+};
+
+static const char * const x1600_mmc0_groups[] = { "mmc0-1bit-b",

"mmc0-4bit-b",
+ "mmc0-1bit-c", "mmc0-4bit-c",

drivers/pinctrl/pinctrl-ingenic.c +3 -0
+};
+
+static const char * const x1600_mmc1_groups[] = { "mmc1-1bit",

"mmc1-4bit", };

drivers/pinctrl/pinctrl-ingenic.c +2 -0
+
+static const char * const x1600_i2c0_groups[] = { "i2c0-data-a",

"i2c0-data-b", };
+static const char * const x1600_i2c1_groups[] = { "i2c1-data-b-15", "i2c1-data-b-19", };

drivers/pinctrl/pinctrl-ingenic.c +3 -0
+
+static const char * const x1600_i2s_groups[] = {
+ "i2s-data-tx", "i2s-data-rx", "i2s-clk-rx", "i2s-clk-tx",

"i2s-sysclk",

drivers/pinctrl/pinctrl-ingenic.c +5 -0
+};
+
+static const char * const x1600_cim_groups[] = { "cim-data", };
+
+static const char * const x1600_lcd_groups[] = { "slcd-8bit", "slcd-

16bit",
+ "lcd-16bit", "lcd-18bit", "lcd-24bit", "lcd-no-pins",

drivers/pinctrl/pinctrl-ingenic.c +54 -1
+};
+
+static const char * const x1600_pwm0_groups[] = { "pwm0", };
+static const char * const x1600_pwm1_groups[] = { "pwm1", };
+static const char * const x1600_pwm2_groups[] = { "pwm2", };
+static const char * const x1600_pwm3_groups[] = { "pwm3", };
+static const char * const x1600_pwm4_groups[] = { "pwm4", };
+static const char * const x1600_pwm5_groups[] = { "pwm5", };
+static const char * const x1600_pwm6_groups[] = { "pwm6", };
+static const char * const x1600_pwm7_groups[] = { "pwm7", };
+
+static const char * const x1600_mac_groups[] = { "mac", };
+
+static const struct function_desc x1600_functions[] = {
+ INGENIC_PIN_FUNCTION("uart0", x1600_uart0),
+ INGENIC_PIN_FUNCTION("uart1", x1600_uart1),
+ INGENIC_PIN_FUNCTION("uart2", x1600_uart2),
+ INGENIC_PIN_FUNCTION("uart3", x1600_uart3),
+ INGENIC_PIN_FUNCTION("sfc", x1600_sfc),
+ INGENIC_PIN_FUNCTION("ssi", x1600_ssi),
+ INGENIC_PIN_FUNCTION("mmc0", x1600_mmc0),
+ INGENIC_PIN_FUNCTION("mmc1", x1600_mmc1),
+ INGENIC_PIN_FUNCTION("i2c0", x1600_i2c0),
+ INGENIC_PIN_FUNCTION("i2c1", x1600_i2c1),
+ INGENIC_PIN_FUNCTION("i2s", x1600_i2s),
+ INGENIC_PIN_FUNCTION("cim", x1600_cim),
+ INGENIC_PIN_FUNCTION("lcd", x1600_lcd),
+ INGENIC_PIN_FUNCTION("pwm0", x1600_pwm0),
+ INGENIC_PIN_FUNCTION("pwm1", x1600_pwm1),
+ INGENIC_PIN_FUNCTION("pwm2", x1600_pwm2),
+ INGENIC_PIN_FUNCTION("pwm3", x1600_pwm3),
+ INGENIC_PIN_FUNCTION("pwm4", x1600_pwm4),
+ INGENIC_PIN_FUNCTION("pwm5", x1600_pwm5),
+ INGENIC_PIN_FUNCTION("pwm6", x1600_pwm6),
+ INGENIC_PIN_FUNCTION("pwm7", x1600_pwm7),
+ INGENIC_PIN_FUNCTION("mac", x1600_mac),
+};
+
+static const struct ingenic_chip_info x1600_chip_info = {
+ .num_chips = 4,
+ .reg_offset = 0x100,
+ .version = ID_X1600,
+ .groups = x1600_groups,
+ .num_groups = ARRAY_SIZE(x1600_groups),
+ .functions = x1600_functions,
+ .num_functions = ARRAY_SIZE(x1600_functions),
+ .pull_ups = x1600_pull_ups,
+ .pull_downs = x1600_pull_downs,
+ .access_table = &x1000_access_table,
+};
+
 static const u32 x1830_pull_ups[4] = {
  0x5fdfffc0, 0xffffefff, 0x1ffffbff, 0x0fcff3fc,
 };
@@ -3860,7 +4089,9 @@ static int ingenic_pinconf_get(struct
 pinctrl_dev *pctldev,
  pulldown = (bias == GPIO_PULL_DOWN) && (jzpc->info-
 > pull_downs[offt] & BIT(idx));
 
  } else {
- if (is_soc_or_above(jzpc, ID_JZ4770))
+ if (is_soc_or_above(jzpc, ID_X1600))
+ pull = ingenic_get_pin_config(jzpc, pin,
 X1600_GPIO_PU);
+ else if (is_soc_or_above(jzpc, ID_JZ4770))

pull = !ingenic_get_pin_config(jzpc, pin,
JZ4770_GPIO_PEN);
else if (is_soc_or_above(jzpc, ID_JZ4740)) pull = !ingenic_get_pin_config(jzpc, pin,
JZ4740_GPIO_PULL_DIS);

drivers/pinctrl/pinctrl-ingenic.c +2 -0
@@ -3959,6 +4190,8 @@ static void ingenic_set_bias(struct
 ingenic_pinctrl *jzpc,
  REG_SET(X1830_GPIO_PEH),
 bias << idxh);
  }
 
+ } else if (is_soc_or_above(jzpc, ID_X1600)) {
+ ingenic_config_pin(jzpc, pin, X1600_GPIO_PU, bias);
  } else if (is_soc_or_above(jzpc, ID_JZ4770)) {

ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PEN,
!bias);
} else if (is_soc_or_above(jzpc, ID_JZ4740)) {

drivers/pinctrl/pinctrl-ingenic.c +1 -0
@@ -4150,6 +4383,7 @@ static const struct of_device_id
 ingenic_gpio_of_matches[] __initconst = {
  { .compatible = "ingenic,jz4775-gpio" },
  { .compatible = "ingenic,jz4780-gpio" },
  { .compatible = "ingenic,x1000-gpio" },
+ { .compatible = "ingenic,x1600-gpio" },
  { .compatible = "ingenic,x1830-gpio" },
  { .compatible = "ingenic,x2000-gpio" },

{ .compatible = "ingenic,x2100-gpio" },

drivers/pinctrl/pinctrl-ingenic.c +4 -0
@@ -4397,6 +4631,10 @@ static const struct of_device_id
 ingenic_pinctrl_of_matches[] = {
  .compatible = "ingenic,x1500-pinctrl",
  .data = IF_ENABLED(CONFIG_MACH_X1500,
 &x1500_chip_info)
  },
+ {
+ .compatible = "ingenic,x1600-pinctrl",
+ .data = IF_ENABLED(CONFIG_MACH_X1600,
 &x1600_chip_info)
+ },

{
.compatible = "ingenic,x1830-pinctrl",
.data = IF_ENABLED(CONFIG_MACH_X1830,
&x1830_chip_info)

#5 lore raw

Re: [PATCH 2/4] pinctrl: ingenic: add x1600 support

Hi all,

Quoted 38 lines

Am 26.02.2025 um 20:42 schrieb H. Nikolaus Schaller <[email protected]>:

Hi Paul,

Quoted 34 lines

Am 26.02.2025 um 19:43 schrieb Paul Cercueil <[email protected]>:

Hi Nikolaus, and everyone involved,

Le mercredi 26 février 2025 à 18:16 +0100, H. Nikolaus Schaller a écrit :

Quoted 28 lines

From: Paul Boddie <[email protected]>

Add support for the Lumissil/Ingenic X1600 SoC.

It uses shadow registers to commit changes to multiple pinctrl registers in parallel.

Define specific Chip ID, register offsets, pin tables etc.

Handling the unique X1600_GPIO_PU only for the x1600 but not for x1830 and above must be carefully taken into account.

---
drivers/pinctrl/pinctrl-ingenic.c | 242
+++++++++++++++++++++++++++++-

1 file changed, 240 insertions(+), 2 deletions(-)
drivers/pinctrl/pinctrl-ingenic.c +0 -0
index bc7ee54e062b5..dfdc89ece9b8a 100644

...

Quoted 13 lines
Quoted 4 lines
Quoted 4 lines
drivers/pinctrl/pinctrl-ingenic.c +4 -0
+static int x1600_pwm_pwm0_pins[] = { 0x40, };
+static int x1600_pwm_pwm1_pins[] = { 0x41, };
+static int x1600_pwm_pwm2_pins[] = { 0x42, };
+static int x1600_pwm_pwm3_pins[] = { 0x58, };
Quoted 8 lines

drivers/pinctrl/pinctrl-ingenic.c static const struct ingenic_chip_info x1500_chip_info = { · line 2436

Quoted 4 lines
drivers/pinctrl/pinctrl-ingenic.c +4 -0
+static int x1600_pwm_pwm4_pins[] = { 0x59, };
+static int x1600_pwm_pwm5_pins[] = { 0x33, 0x5a, };
+static int x1600_pwm_pwm6_pins[] = { 0x29, 0x34, };
+static int x1600_pwm_pwm7_pins[] = { 0x2a, 0x35, };

Just a quick question about these ones: why are there 2 pins here? If you have the PWM5/6/7 function on two different pins then you should probably have two groups.

Quoted 5 lines

I think they are added through INGENIC_PIN_GROUP_FUNCS() to x1600_groups[].

So the pins list is different from pwm0 to 4 which uses INGENIC_PIN_GROUP().

I have now checked with the programming manual.

Yes, pwm5 to pwm7 can be pinmuxed to different pads, while pwm0 to pwm4 have only one option.

E.g. pwm5: PC26 in function 1 or PB19 in function 2.

This is simular to what we have with uart2-data-a and uart2-data-b.

So I tend to agree that we need different pin groups ("pwm5-a", "pwm5-b") and no need to use INGENIC_PIN_GROUP_FUNCS().

Maybe we didn't realize since we have not yet used PWM in any x1600 based device.

...

Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
drivers/pinctrl/pinctrl-ingenic.c +13 -0
+static int x1600_pwm_pwm5_funcs[] = { 2, 1, };
+static int x1600_pwm_pwm6_funcs[] = { 1, 2, };
+static int x1600_pwm_pwm7_funcs[] = { 1, 2, };
+
+static const struct group_desc x1600_groups[] = {
+ INGENIC_PIN_GROUP("uart0-data", x1600_uart0_data, 0),
+ INGENIC_PIN_GROUP("uart0-hwflow", x1600_uart0_hwflow, 0),
+ INGENIC_PIN_GROUP("uart1-data", x1600_uart1_data, 1),
+ INGENIC_PIN_GROUP("uart1-hwflow", x1600_uart1_hwflow, 1),
+ INGENIC_PIN_GROUP("uart2-data-a", x1600_uart2_data_a, 2),
+ INGENIC_PIN_GROUP("uart2-data-b", x1600_uart2_data_b, 1),
+ INGENIC_PIN_GROUP("uart3-data-b", x1600_uart3_data_b, 0),
+ INGENIC_PIN_GROUP("uart3-data-d", x1600_uart3_data_d, 2),

...

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

+ INGENIC_PIN_GROUP("pwm0", x1600_pwm_pwm0, 0),
+ INGENIC_PIN_GROUP("pwm1", x1600_pwm_pwm1, 0),
+ INGENIC_PIN_GROUP("pwm2", x1600_pwm_pwm2, 0),
+ INGENIC_PIN_GROUP("pwm3", x1600_pwm_pwm3, 1),
+ INGENIC_PIN_GROUP("pwm4", x1600_pwm_pwm4, 1),
+ INGENIC_PIN_GROUP_FUNCS("pwm5", x1600_pwm_pwm5,

Quoted 8 lines
Quoted 8 lines

drivers/pinctrl/pinctrl-ingenic.c

Quoted 8 lines

x1600_pwm_pwm5_funcs),
+ INGENIC_PIN_GROUP_FUNCS("pwm6", x1600_pwm_pwm6, x1600_pwm_pwm6_funcs),
+ INGENIC_PIN_GROUP_FUNCS("pwm7", x1600_pwm_pwm7, x1600_pwm_pwm7_funcs),
+ INGENIC_PIN_GROUP("mac", x1600_mac, 1),

drivers/pinctrl/pinctrl-ingenic.c +2 -0
+};
+

If Paul Boddie agrees, I will add it to the V2.

BR and thanks,
Nikolaus