From 5f79bbb28be2f09e99ef3477179128af2d8e6f64 Mon Sep 17 00:00:00 2001 From: Niklas Söderlund Date: Tue, 9 Mar 2021 12:49:27 +0100 Subject: pinctrl: renesas: r8a77951: Add vin4_g8 and vin5_high8 pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds vin4_g8 and vin5_high8 support to the R8A77951 SoC. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi Link: https://lore.kernel.org/r/20210309114930.2433711-2-niklas.soderlund+renesas@ragnatech.se Signed-off-by: Geert Uytterhoeven --- drivers/pinctrl/renesas/pfc-r8a77951.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/renesas/pfc-r8a77951.c b/drivers/pinctrl/renesas/pfc-r8a77951.c index bdd605e41303..6f3a1625d789 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77951.c +++ b/drivers/pinctrl/renesas/pfc-r8a77951.c @@ -4126,6 +4126,18 @@ static const union vin_data vin4_data_b_mux = { VI4_DATA22_MARK, VI4_DATA23_MARK, }, }; +static const unsigned int vin4_g8_pins[] = { + RCAR_GP_PIN(1, 0), RCAR_GP_PIN(1, 1), + RCAR_GP_PIN(1, 2), RCAR_GP_PIN(1, 3), + RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 5), + RCAR_GP_PIN(1, 6), RCAR_GP_PIN(1, 7), +}; +static const unsigned int vin4_g8_mux[] = { + VI4_DATA8_MARK, VI4_DATA9_MARK, + VI4_DATA10_MARK, VI4_DATA11_MARK, + VI4_DATA12_MARK, VI4_DATA13_MARK, + VI4_DATA14_MARK, VI4_DATA15_MARK, +}; static const unsigned int vin4_sync_pins[] = { /* HSYNC#, VSYNC# */ RCAR_GP_PIN(1, 18), RCAR_GP_PIN(1, 17), @@ -4180,6 +4192,18 @@ static const union vin_data16 vin5_data_mux = { VI5_DATA14_MARK, VI5_DATA15_MARK, }, }; +static const unsigned int vin5_high8_pins[] = { + RCAR_GP_PIN(1, 12), RCAR_GP_PIN(1, 13), + RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 15), + RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 5), + RCAR_GP_PIN(1, 6), RCAR_GP_PIN(1, 7), +}; +static const unsigned int vin5_high8_mux[] = { + VI5_DATA8_MARK, VI5_DATA9_MARK, + VI5_DATA10_MARK, VI5_DATA11_MARK, + VI5_DATA12_MARK, VI5_DATA13_MARK, + VI5_DATA14_MARK, VI5_DATA15_MARK, +}; static const unsigned int vin5_sync_pins[] = { /* HSYNC#, VSYNC# */ RCAR_GP_PIN(1, 10), RCAR_GP_PIN(1, 9), @@ -4210,7 +4234,7 @@ static const unsigned int vin5_clk_mux[] = { }; static const struct { - struct sh_pfc_pin_group common[326]; + struct sh_pfc_pin_group common[328]; #ifdef CONFIG_PINCTRL_PFC_R8A77951 struct sh_pfc_pin_group automotive[30]; #endif @@ -4530,6 +4554,7 @@ static const struct { SH_PFC_PIN_GROUP(vin4_data18_b), VIN_DATA_PIN_GROUP(vin4_data, 20, _b), VIN_DATA_PIN_GROUP(vin4_data, 24, _b), + SH_PFC_PIN_GROUP(vin4_g8), SH_PFC_PIN_GROUP(vin4_sync), SH_PFC_PIN_GROUP(vin4_field), SH_PFC_PIN_GROUP(vin4_clkenb), @@ -4538,6 +4563,7 @@ static const struct { VIN_DATA_PIN_GROUP(vin5_data, 10), VIN_DATA_PIN_GROUP(vin5_data, 12), VIN_DATA_PIN_GROUP(vin5_data, 16), + SH_PFC_PIN_GROUP(vin5_high8), SH_PFC_PIN_GROUP(vin5_sync), SH_PFC_PIN_GROUP(vin5_field), SH_PFC_PIN_GROUP(vin5_clkenb), @@ -5097,6 +5123,7 @@ static const char * const vin4_groups[] = { "vin4_data18_b", "vin4_data20_b", "vin4_data24_b", + "vin4_g8", "vin4_sync", "vin4_field", "vin4_clkenb", @@ -5108,6 +5135,7 @@ static const char * const vin5_groups[] = { "vin5_data10", "vin5_data12", "vin5_data16", + "vin5_high8", "vin5_sync", "vin5_field", "vin5_clkenb", -- cgit v1.2.3 From 3d250efb8c32bdcf29e307de624afd25b6c1bff7 Mon Sep 17 00:00:00 2001 From: Niklas Söderlund Date: Tue, 9 Mar 2021 12:49:28 +0100 Subject: pinctrl: renesas: r8a7796: Add vin4_g8 and vin5_high8 pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds vin4_g8 and vin5_high8 support to the R8A7796 SoC. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi Link: https://lore.kernel.org/r/20210309114930.2433711-3-niklas.soderlund+renesas@ragnatech.se Signed-off-by: Geert Uytterhoeven --- drivers/pinctrl/renesas/pfc-r8a7796.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/renesas/pfc-r8a7796.c b/drivers/pinctrl/renesas/pfc-r8a7796.c index 96b5b1509bb7..ce2466df5ef2 100644 --- a/drivers/pinctrl/renesas/pfc-r8a7796.c +++ b/drivers/pinctrl/renesas/pfc-r8a7796.c @@ -4100,6 +4100,18 @@ static const union vin_data vin4_data_b_mux = { VI4_DATA22_MARK, VI4_DATA23_MARK, }, }; +static const unsigned int vin4_g8_pins[] = { + RCAR_GP_PIN(1, 0), RCAR_GP_PIN(1, 1), + RCAR_GP_PIN(1, 2), RCAR_GP_PIN(1, 3), + RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 5), + RCAR_GP_PIN(1, 6), RCAR_GP_PIN(1, 7), +}; +static const unsigned int vin4_g8_mux[] = { + VI4_DATA8_MARK, VI4_DATA9_MARK, + VI4_DATA10_MARK, VI4_DATA11_MARK, + VI4_DATA12_MARK, VI4_DATA13_MARK, + VI4_DATA14_MARK, VI4_DATA15_MARK, +}; static const unsigned int vin4_sync_pins[] = { /* HSYNC#, VSYNC# */ RCAR_GP_PIN(1, 18), RCAR_GP_PIN(1, 17), @@ -4154,6 +4166,18 @@ static const union vin_data16 vin5_data_mux = { VI5_DATA14_MARK, VI5_DATA15_MARK, }, }; +static const unsigned int vin5_high8_pins[] = { + RCAR_GP_PIN(1, 12), RCAR_GP_PIN(1, 13), + RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 15), + RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 5), + RCAR_GP_PIN(1, 6), RCAR_GP_PIN(1, 7), +}; +static const unsigned int vin5_high8_mux[] = { + VI5_DATA8_MARK, VI5_DATA9_MARK, + VI5_DATA10_MARK, VI5_DATA11_MARK, + VI5_DATA12_MARK, VI5_DATA13_MARK, + VI5_DATA14_MARK, VI5_DATA15_MARK, +}; static const unsigned int vin5_sync_pins[] = { /* HSYNC#, VSYNC# */ RCAR_GP_PIN(1, 10), RCAR_GP_PIN(1, 9), @@ -4184,7 +4208,7 @@ static const unsigned int vin5_clk_mux[] = { }; static const struct { - struct sh_pfc_pin_group common[322]; + struct sh_pfc_pin_group common[324]; #if defined(CONFIG_PINCTRL_PFC_R8A77960) || defined(CONFIG_PINCTRL_PFC_R8A77961) struct sh_pfc_pin_group automotive[30]; #endif @@ -4500,6 +4524,7 @@ static const struct { SH_PFC_PIN_GROUP(vin4_data18_b), VIN_DATA_PIN_GROUP(vin4_data, 20, _b), VIN_DATA_PIN_GROUP(vin4_data, 24, _b), + SH_PFC_PIN_GROUP(vin4_g8), SH_PFC_PIN_GROUP(vin4_sync), SH_PFC_PIN_GROUP(vin4_field), SH_PFC_PIN_GROUP(vin4_clkenb), @@ -4508,6 +4533,7 @@ static const struct { VIN_DATA_PIN_GROUP(vin5_data, 10), VIN_DATA_PIN_GROUP(vin5_data, 12), VIN_DATA_PIN_GROUP(vin5_data, 16), + SH_PFC_PIN_GROUP(vin5_high8), SH_PFC_PIN_GROUP(vin5_sync), SH_PFC_PIN_GROUP(vin5_field), SH_PFC_PIN_GROUP(vin5_clkenb), @@ -5054,6 +5080,7 @@ static const char * const vin4_groups[] = { "vin4_data18_b", "vin4_data20_b", "vin4_data24_b", + "vin4_g8", "vin4_sync", "vin4_field", "vin4_clkenb", @@ -5065,6 +5092,7 @@ static const char * const vin5_groups[] = { "vin5_data10", "vin5_data12", "vin5_data16", + "vin5_high8", "vin5_sync", "vin5_field", "vin5_clkenb", -- cgit v1.2.3 From 2a9e4f74cd57fb7091d4ad627ec58bfd75b50722 Mon Sep 17 00:00:00 2001 From: Niklas Söderlund Date: Tue, 9 Mar 2021 12:49:29 +0100 Subject: pinctrl: renesas: r8a77990: Add vin4_g8 and vin5_high8 pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds vin4_g8 and vin5_high8 support to the R8A77990 SoC. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi Link: https://lore.kernel.org/r/20210309114930.2433711-4-niklas.soderlund+renesas@ragnatech.se Signed-off-by: Geert Uytterhoeven --- drivers/pinctrl/renesas/pfc-r8a77990.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/renesas/pfc-r8a77990.c b/drivers/pinctrl/renesas/pfc-r8a77990.c index 0a32e3c317c1..a243aa8c5253 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77990.c +++ b/drivers/pinctrl/renesas/pfc-r8a77990.c @@ -3697,6 +3697,20 @@ static const union vin_data vin4_data_b_mux = { }, }; +static const unsigned int vin4_g8_pins[] = { + RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 5), + RCAR_GP_PIN(1, 6), RCAR_GP_PIN(1, 7), + RCAR_GP_PIN(1, 3), RCAR_GP_PIN(1, 10), + RCAR_GP_PIN(1, 13), RCAR_GP_PIN(1, 14), +}; + +static const unsigned int vin4_g8_mux[] = { + VI4_DATA8_MARK, VI4_DATA9_MARK, + VI4_DATA10_MARK, VI4_DATA11_MARK, + VI4_DATA12_MARK, VI4_DATA13_MARK, + VI4_DATA14_MARK, VI4_DATA15_MARK, +}; + static const unsigned int vin4_sync_pins[] = { /* HSYNC, VSYNC */ RCAR_GP_PIN(2, 25), RCAR_GP_PIN(2, 24), @@ -3771,6 +3785,20 @@ static const unsigned int vin5_data8_b_mux[] = { VI5_DATA6_B_MARK, VI5_DATA7_B_MARK, }; +static const unsigned int vin5_high8_pins[] = { + RCAR_GP_PIN(0, 12), RCAR_GP_PIN(0, 13), + RCAR_GP_PIN(0, 9), RCAR_GP_PIN(0, 11), + RCAR_GP_PIN(0, 8), RCAR_GP_PIN(0, 10), + RCAR_GP_PIN(0, 2), RCAR_GP_PIN(0, 3), +}; + +static const unsigned int vin5_high8_mux[] = { + VI5_DATA8_A_MARK, VI5_DATA9_A_MARK, + VI5_DATA10_A_MARK, VI5_DATA11_A_MARK, + VI5_DATA12_A_MARK, VI5_DATA13_A_MARK, + VI5_DATA14_A_MARK, VI5_DATA15_A_MARK, +}; + static const unsigned int vin5_sync_a_pins[] = { /* HSYNC_N, VSYNC_N */ RCAR_GP_PIN(1, 8), RCAR_GP_PIN(1, 9), @@ -3813,7 +3841,7 @@ static const unsigned int vin5_clk_b_mux[] = { }; static const struct { - struct sh_pfc_pin_group common[253]; + struct sh_pfc_pin_group common[255]; #ifdef CONFIG_PINCTRL_PFC_R8A77990 struct sh_pfc_pin_group automotive[21]; #endif @@ -4058,6 +4086,7 @@ static const struct { SH_PFC_PIN_GROUP(vin4_data18_b), VIN_DATA_PIN_GROUP(vin4_data, 20, _b), VIN_DATA_PIN_GROUP(vin4_data, 24, _b), + SH_PFC_PIN_GROUP(vin4_g8), SH_PFC_PIN_GROUP(vin4_sync), SH_PFC_PIN_GROUP(vin4_field), SH_PFC_PIN_GROUP(vin4_clkenb), @@ -4067,6 +4096,7 @@ static const struct { VIN_DATA_PIN_GROUP(vin5_data, 12, _a), VIN_DATA_PIN_GROUP(vin5_data, 16, _a), SH_PFC_PIN_GROUP(vin5_data8_b), + SH_PFC_PIN_GROUP(vin5_high8), SH_PFC_PIN_GROUP(vin5_sync_a), SH_PFC_PIN_GROUP(vin5_field_a), SH_PFC_PIN_GROUP(vin5_clkenb_a), @@ -4516,6 +4546,7 @@ static const char * const vin4_groups[] = { "vin4_data18_b", "vin4_data20_b", "vin4_data24_b", + "vin4_g8", "vin4_sync", "vin4_field", "vin4_clkenb", @@ -4528,6 +4559,7 @@ static const char * const vin5_groups[] = { "vin5_data12_a", "vin5_data16_a", "vin5_data8_b", + "vin5_high8", "vin5_sync_a", "vin5_field_a", "vin5_clkenb_a", -- cgit v1.2.3 From f7adcca27edf05fc1f061a9e5de059fe179f0e1c Mon Sep 17 00:00:00 2001 From: Niklas Söderlund Date: Tue, 9 Mar 2021 12:49:30 +0100 Subject: pinctrl: renesas: r8a77965: Add vin4_g8 and vin5_high8 pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds vin4_g8 and vin5_high8 support to the R8A77965 SoC. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi Link: https://lore.kernel.org/r/20210309114930.2433711-5-niklas.soderlund+renesas@ragnatech.se Signed-off-by: Geert Uytterhoeven --- drivers/pinctrl/renesas/pfc-r8a77965.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/renesas/pfc-r8a77965.c b/drivers/pinctrl/renesas/pfc-r8a77965.c index f15e29383d9b..dd6b0c9ce575 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77965.c +++ b/drivers/pinctrl/renesas/pfc-r8a77965.c @@ -4337,6 +4337,20 @@ static const union vin_data vin4_data_b_mux = { }, }; +static const unsigned int vin4_g8_pins[] = { + RCAR_GP_PIN(1, 0), RCAR_GP_PIN(1, 1), + RCAR_GP_PIN(1, 2), RCAR_GP_PIN(1, 3), + RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 5), + RCAR_GP_PIN(1, 6), RCAR_GP_PIN(1, 7), +}; + +static const unsigned int vin4_g8_mux[] = { + VI4_DATA8_MARK, VI4_DATA9_MARK, + VI4_DATA10_MARK, VI4_DATA11_MARK, + VI4_DATA12_MARK, VI4_DATA13_MARK, + VI4_DATA14_MARK, VI4_DATA15_MARK, +}; + static const unsigned int vin4_sync_pins[] = { /* VSYNC_N, HSYNC_N */ RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 18), @@ -4397,6 +4411,20 @@ static const union vin_data16 vin5_data_mux = { }, }; +static const unsigned int vin5_high8_pins[] = { + RCAR_GP_PIN(1, 12), RCAR_GP_PIN(1, 13), + RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 15), + RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 5), + RCAR_GP_PIN(1, 6), RCAR_GP_PIN(1, 7), +}; + +static const unsigned int vin5_high8_mux[] = { + VI5_DATA8_MARK, VI5_DATA9_MARK, + VI5_DATA10_MARK, VI5_DATA11_MARK, + VI5_DATA12_MARK, VI5_DATA13_MARK, + VI5_DATA14_MARK, VI5_DATA15_MARK, +}; + static const unsigned int vin5_sync_pins[] = { /* VSYNC_N, HSYNC_N */ RCAR_GP_PIN(1, 9), RCAR_GP_PIN(1, 10), @@ -4431,7 +4459,7 @@ static const unsigned int vin5_clk_mux[] = { }; static const struct { - struct sh_pfc_pin_group common[324]; + struct sh_pfc_pin_group common[326]; #ifdef CONFIG_PINCTRL_PFC_R8A77965 struct sh_pfc_pin_group automotive[30]; #endif @@ -4749,6 +4777,7 @@ static const struct { SH_PFC_PIN_GROUP(vin4_data18_b), VIN_DATA_PIN_GROUP(vin4_data, 20, _b), VIN_DATA_PIN_GROUP(vin4_data, 24, _b), + SH_PFC_PIN_GROUP(vin4_g8), SH_PFC_PIN_GROUP(vin4_sync), SH_PFC_PIN_GROUP(vin4_field), SH_PFC_PIN_GROUP(vin4_clkenb), @@ -4757,6 +4786,7 @@ static const struct { VIN_DATA_PIN_GROUP(vin5_data, 10), VIN_DATA_PIN_GROUP(vin5_data, 12), VIN_DATA_PIN_GROUP(vin5_data, 16), + SH_PFC_PIN_GROUP(vin5_high8), SH_PFC_PIN_GROUP(vin5_sync), SH_PFC_PIN_GROUP(vin5_field), SH_PFC_PIN_GROUP(vin5_clkenb), @@ -5307,6 +5337,7 @@ static const char * const vin4_groups[] = { "vin4_data18_b", "vin4_data20_b", "vin4_data24_b", + "vin4_g8", "vin4_sync", "vin4_field", "vin4_clkenb", @@ -5318,6 +5349,7 @@ static const char * const vin5_groups[] = { "vin5_data10", "vin5_data12", "vin5_data16", + "vin5_high8", "vin5_sync", "vin5_field", "vin5_clkenb", -- cgit v1.2.3 From ba434267d07661f3e3712e4e5429ba599b32ab0e Mon Sep 17 00:00:00 2001 From: Junlin Yang Date: Tue, 16 Feb 2021 16:02:31 +0800 Subject: pinctrl: equilibrium: add missing of_node_put Fix OF node leaks by calling of_node_put in for_each_child_of_node when the cycle returns. Generated by: scripts/coccinelle/iterators/for_each_child.cocci Signed-off-by: Junlin Yang Link: https://lore.kernel.org/r/20210216080231.1303-1-angkery@163.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-equilibrium.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-equilibrium.c b/drivers/pinctrl/pinctrl-equilibrium.c index 067271b7d35a..a194d8089b6f 100644 --- a/drivers/pinctrl/pinctrl-equilibrium.c +++ b/drivers/pinctrl/pinctrl-equilibrium.c @@ -628,7 +628,8 @@ static int funcs_utils(struct device *dev, struct eqbr_pmx_func *funcs, break; default: - return -EINVAL; + of_node_put(np); + return -EINVAL; } i++; } @@ -707,34 +708,42 @@ static int eqbr_build_groups(struct eqbr_pinctrl_drv_data *drvdata) group.num_pins = of_property_count_u32_elems(np, "pins"); if (group.num_pins < 0) { dev_err(dev, "No pins in the group: %s\n", prop->name); + of_node_put(np); return -EINVAL; } group.name = prop->value; group.pins = devm_kcalloc(dev, group.num_pins, sizeof(*(group.pins)), GFP_KERNEL); - if (!group.pins) + if (!group.pins) { + of_node_put(np); return -ENOMEM; + } pinmux = devm_kcalloc(dev, group.num_pins, sizeof(*pinmux), GFP_KERNEL); - if (!pinmux) + if (!pinmux) { + of_node_put(np); return -ENOMEM; + } for (j = 0; j < group.num_pins; j++) { if (of_property_read_u32_index(np, "pins", j, &pin_id)) { dev_err(dev, "Group %s: Read intel pins id failed\n", group.name); + of_node_put(np); return -EINVAL; } if (pin_id >= drvdata->pctl_desc.npins) { dev_err(dev, "Group %s: Invalid pin ID, idx: %d, pin %u\n", group.name, j, pin_id); + of_node_put(np); return -EINVAL; } group.pins[j] = pin_id; if (of_property_read_u32_index(np, "pinmux", j, &pinmux_id)) { dev_err(dev, "Group %s: Read intel pinmux id failed\n", group.name); + of_node_put(np); return -EINVAL; } pinmux[j] = pinmux_id; @@ -745,6 +754,7 @@ static int eqbr_build_groups(struct eqbr_pinctrl_drv_data *drvdata) pinmux); if (err < 0) { dev_err(dev, "Failed to register group %s\n", group.name); + of_node_put(np); return err; } memset(&group, 0, sizeof(group)); -- cgit v1.2.3 From b24236f5543335a2953612a13541d5a3e039e8b7 Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Tue, 16 Feb 2021 13:31:17 +0200 Subject: pinctrl: cp110-system-controller: fix the pin function names Fix the pin function names for MPP54 and MPP55. Signed-off-by: Konstantin Porotchkin Link: https://lore.kernel.org/r/20210216113118.17484-2-kostap@marvell.com Signed-off-by: Linus Walleij --- .../devicetree/bindings/arm/marvell/cp110-system-controller.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt index a21f7709596c..0705e765f432 100644 --- a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt +++ b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt @@ -142,8 +142,8 @@ mpp50 50 gpio, ge1(rxclk), mss_i2c(sda), spi1(csn0), uart2(txd), uart0(rxd), xg( mpp51 51 gpio, ge1(rxd0), mss_i2c(sck), spi1(csn1), uart2(rxd), uart0(cts), sdio(pwr10) mpp52 52 gpio, ge1(rxd1), synce1(clk), synce2(clk), spi1(csn2), uart1(cts), led(clk), pcie(rstoutn), pcie0(clkreq) mpp53 53 gpio, ge1(rxd2), ptp(clk), spi1(csn3), uart1(rxd), led(stb), sdio(led) -mpp54 54 gpio, ge1(rxd3), synce2(clk), ptp(pclk_out), synce1(clk), led(data), sdio(hw_rst), sdio(wr_protect) -mpp55 55 gpio, ge1(rxctl_rxdv), ptp(pulse), sdio(led), sdio(card_detect) +mpp54 54 gpio, ge1(rxd3), synce2(clk), ptp(pclk_out), synce1(clk), led(data), sdio(hw_rst), sdio_wp(wr_protect) +mpp55 55 gpio, ge1(rxctl_rxdv), ptp(pulse), sdio(led), sdio_cd(card_detect) mpp56 56 gpio, tdm(drx), au(i2sdo_spdifo), spi0(clk), uart1(rxd), sata1(present_act), sdio(clk) mpp57 57 gpio, mss_i2c(sda), ptp(pclk_out), tdm(intn), au(i2sbclk), spi0(mosi), uart1(txd), sata0(present_act), sdio(cmd) mpp58 58 gpio, mss_i2c(sck), ptp(clk), tdm(rstn), au(i2sdi), spi0(miso), uart1(cts), led(clk), sdio(d0) -- cgit v1.2.3 From a7db796b305bba7b4fd78eac2c50647a7cafe0f7 Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Tue, 16 Feb 2021 13:31:18 +0200 Subject: pinctrl: armada-cp110 - fix MPP54/MPP55 functions The function name is used for selecting MPP functionality and should be unique within function names of the same pin. This patch fixes function names for MPP54 and MPP55 that have two different functions named the same. Signed-off-by: Konstantin Porotchkin Link: https://lore.kernel.org/r/20210216113118.17484-3-kostap@marvell.com Signed-off-by: Linus Walleij --- drivers/pinctrl/mvebu/pinctrl-armada-cp110.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-cp110.c b/drivers/pinctrl/mvebu/pinctrl-armada-cp110.c index 17491b27e487..8ba8f3e9121f 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-cp110.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-cp110.c @@ -519,13 +519,13 @@ static struct mvebu_mpp_mode armada_cp110_mpp_modes[] = { MPP_FUNCTION(4, "synce1", "clk"), MPP_FUNCTION(8, "led", "data"), MPP_FUNCTION(10, "sdio", "hw_rst"), - MPP_FUNCTION(11, "sdio", "wr_protect")), + MPP_FUNCTION(11, "sdio_wp", "wr_protect")), MPP_MODE(55, MPP_FUNCTION(0, "gpio", NULL), MPP_FUNCTION(1, "ge1", "rxctl_rxdv"), MPP_FUNCTION(3, "ptp", "pulse"), MPP_FUNCTION(10, "sdio", "led"), - MPP_FUNCTION(11, "sdio", "card_detect")), + MPP_FUNCTION(11, "sdio_cd", "card_detect")), MPP_MODE(56, MPP_FUNCTION(0, "gpio", NULL), MPP_FUNCTION(4, "tdm", "drx"), -- cgit v1.2.3 From ffeaa23aa001b46b5fb35cb5e3f5ddb796d9b462 Mon Sep 17 00:00:00 2001 From: Junlin Yang Date: Mon, 15 Feb 2021 18:36:43 +0800 Subject: pinctrl: stm32: add missing of_node_put Fix OF node leaks by calling of_node_put in for_each_available_child_of_node when the cycle returns. Generated by: scripts/coccinelle/iterators/for_each_child.cocci Signed-off-by: Junlin Yang Link: https://lore.kernel.org/r/20210215103643.898-1-angkery@163.com Acked-by: Fabien Dessenne Signed-off-by: Linus Walleij --- drivers/pinctrl/stm32/pinctrl-stm32.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index 7d9bdedcd71b..da72e3e5c08d 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -1542,8 +1542,10 @@ int stm32_pctl_probe(struct platform_device *pdev) if (of_property_read_bool(child, "gpio-controller")) { bank->rstc = of_reset_control_get_exclusive(child, NULL); - if (PTR_ERR(bank->rstc) == -EPROBE_DEFER) + if (PTR_ERR(bank->rstc) == -EPROBE_DEFER) { + of_node_put(child); return -EPROBE_DEFER; + } bank->clk = of_clk_get_by_name(child, NULL); if (IS_ERR(bank->clk)) { @@ -1551,6 +1553,7 @@ int stm32_pctl_probe(struct platform_device *pdev) dev_err(dev, "failed to get clk (%ld)\n", PTR_ERR(bank->clk)); + of_node_put(child); return PTR_ERR(bank->clk); } i++; -- cgit v1.2.3 From 35b25fd32b5f138b796664c8183afc0515d9dc89 Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Fri, 12 Feb 2021 10:29:34 +0530 Subject: pinctrl: qcom: sc7280: Add GPIO wakeup interrupt map GPIOs that can be configured as wakeup sources, have their interrupt lines routed to PDC interrupt controller. Provide the interrupt map of the GPIO to its wakeup capable interrupt parent. Signed-off-by: Maulik Shah Signed-off-by: Rajendra Nayak Acked-by: Bjorn Andersson Link: https://lore.kernel.org/r/1613105974-28181-1-git-send-email-rnayak@codeaurora.org Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-sc7280.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/pinctrl/qcom/pinctrl-sc7280.c b/drivers/pinctrl/qcom/pinctrl-sc7280.c index 8daccd530285..99c416ea1bf3 100644 --- a/drivers/pinctrl/qcom/pinctrl-sc7280.c +++ b/drivers/pinctrl/qcom/pinctrl-sc7280.c @@ -1449,6 +1449,28 @@ static const struct msm_pingroup sc7280_groups[] = { [182] = SDC_QDSD_PINGROUP(sdc2_data, 0x1b4000, 9, 0), }; +static const struct msm_gpio_wakeirq_map sc7280_pdc_map[] = { + { 0, 134 }, { 3, 131 }, { 4, 121 }, { 7, 103 }, { 8, 155 }, + { 11, 93 }, { 12, 78 }, { 15, 79 }, { 16, 80 }, { 18, 81 }, + { 19, 107 }, { 20, 82 }, { 21, 83 }, { 23, 99 }, { 24, 86 }, + { 25, 95 }, { 27, 158 }, { 28, 159 }, { 31, 90 }, { 32, 144 }, + { 34, 77 }, { 35, 92 }, { 36, 157 }, { 39, 73 }, { 40, 97 }, + { 41, 98 }, { 43, 85 }, { 44, 100 }, { 45, 101 }, { 47, 102 }, + { 48, 74 }, { 51, 112 }, { 52, 156 }, { 54, 117 }, { 55, 84 }, + { 56, 108 }, { 59, 110 }, { 60, 111 }, { 61, 123 }, { 63, 104 }, + { 68, 127 }, { 72, 150 }, { 75, 133 }, { 77, 125 }, { 78, 105 }, + { 79, 106 }, { 80, 118 }, { 81, 119 }, { 82, 162 }, { 83, 122 }, + { 86, 75 }, { 88, 154 }, { 89, 124 }, { 90, 149 }, { 91, 76 }, + { 93, 128 }, { 95, 160 }, { 101, 126 }, { 102, 96 }, { 103, 116 }, + { 104, 114 }, { 112, 72 }, { 116, 135 }, { 117, 163 }, { 119, 137 }, + { 121, 138 }, { 123, 139 }, { 125, 140 }, { 127, 141 }, { 128, 165 }, + { 129, 143 }, { 130, 94 }, { 131, 145 }, { 133, 146 }, { 136, 147 }, + { 140, 148 }, { 141, 115 }, { 142, 113 }, { 145, 130 }, { 148, 132 }, + { 150, 87 }, { 151, 88 }, { 153, 89 }, { 155, 164 }, { 156, 129 }, + { 157, 161 }, { 158, 120 }, { 161, 136 }, { 163, 142 }, { 172, 166 }, + { 174, 167 }, +}; + static const struct msm_pinctrl_soc_data sc7280_pinctrl = { .pins = sc7280_pins, .npins = ARRAY_SIZE(sc7280_pins), @@ -1457,6 +1479,8 @@ static const struct msm_pinctrl_soc_data sc7280_pinctrl = { .groups = sc7280_groups, .ngroups = ARRAY_SIZE(sc7280_groups), .ngpios = 176, + .wakeirq_map = sc7280_pdc_map, + .nwakeirq_map = ARRAY_SIZE(sc7280_pdc_map), }; static int sc7280_pinctrl_probe(struct platform_device *pdev) -- cgit v1.2.3 From b37c35781d9ad929c150b2b0b1eb0070a312585b Mon Sep 17 00:00:00 2001 From: Jianqun Xu Date: Tue, 23 Feb 2021 18:19:37 +0800 Subject: pinctrl: rockchip: clear int status when driver probed Some devices may do gpio interrupt trigger and make an int status before pinctrl driver probed, then the gpio handler will keep complain untill the device driver works to stop trigger. Signed-off-by: Ziyuan Xu Signed-off-by: Jianqun Xu Reviewed-by: Heiko Stuebner Link: https://lore.kernel.org/r/20210223101937.273085-1-jay.xu@rock-chips.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index aa1a1c850d05..ec4cb88572cf 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -3433,6 +3433,7 @@ static int rockchip_interrupts_register(struct platform_device *pdev, * things enabled, so for us that's all masked and all enabled. */ writel_relaxed(0xffffffff, bank->reg_base + GPIO_INTMASK); + writel_relaxed(0xffffffff, bank->reg_base + GPIO_PORTS_EOI); writel_relaxed(0xffffffff, bank->reg_base + GPIO_INTEN); gc->mask_cache = 0xffffffff; -- cgit v1.2.3 From d2cd54c24e80b3da2d3071311a280aa19b782438 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Fri, 26 Feb 2021 09:34:57 +0800 Subject: pinctrl: ingenic: add missing call to of_node_put() In one of the error paths of the for_each_child_of_node() loop in ingenic_gpio_probe, add missing call to of_node_put(). Fix the following coccicheck warning: ./drivers/pinctrl/pinctrl-ingenic.c:2485:1-23: WARNING: Function "for_each_child_of_node" should have of_node_put() before return around line 2489. Reported-by: Abaci Robot Signed-off-by: Yang Li Acked-by: Paul Cercueil Link: https://lore.kernel.org/r/1614303297-24178-1-git-send-email-yang.lee@linux.alibaba.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index f2746125b077..c8ecd014cf19 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -2485,8 +2485,10 @@ static int __init ingenic_pinctrl_probe(struct platform_device *pdev) for_each_child_of_node(dev->of_node, node) { if (of_match_node(ingenic_gpio_of_match, node)) { err = ingenic_gpio_probe(jzpc, node); - if (err) + if (err) { + of_node_put(node); return err; + } } } -- cgit v1.2.3 From 47473813bdcb8c5ffa87f6d2ccb378b9b0882c83 Mon Sep 17 00:00:00 2001 From: Drew Fustini Date: Mon, 1 Mar 2021 21:30:56 -0800 Subject: pinctrl: use to octal permissions for debugfs files Switch over pinctrl debugfs files to use octal permissions as they are preferred over symbolic permissions. Refer to commit f90774e1fd27 ("checkpatch: look for symbolic permissions and suggest octal instead"). Note: S_IFREG flag is added to the mode by __debugfs_create_file() in fs/debugfs/inode.c Suggested-by: Joe Perches Suggested-by: Andy Shevchenko Reviewed-by: Andy Shevchenko Reviewed-by: Geert Uytterhoeven Reviewed-by: Tony Lindgren Signed-off-by: Drew Fustini Link: https://lore.kernel.org/r/20210302053059.1049035-2-drew@beagleboard.org Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 12 ++++++------ drivers/pinctrl/pinconf.c | 4 ++-- drivers/pinctrl/pinmux.c | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 7d3370289938..6ddf2bc36f15 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -1890,11 +1890,11 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) dev_name(pctldev->dev)); return; } - debugfs_create_file("pins", S_IFREG | S_IRUGO, + debugfs_create_file("pins", 0444, device_root, pctldev, &pinctrl_pins_fops); - debugfs_create_file("pingroups", S_IFREG | S_IRUGO, + debugfs_create_file("pingroups", 0444, device_root, pctldev, &pinctrl_groups_fops); - debugfs_create_file("gpio-ranges", S_IFREG | S_IRUGO, + debugfs_create_file("gpio-ranges", 0444, device_root, pctldev, &pinctrl_gpioranges_fops); if (pctldev->desc->pmxops) pinmux_init_device_debugfs(device_root, pctldev); @@ -1916,11 +1916,11 @@ static void pinctrl_init_debugfs(void) return; } - debugfs_create_file("pinctrl-devices", S_IFREG | S_IRUGO, + debugfs_create_file("pinctrl-devices", 0444, debugfs_root, NULL, &pinctrl_devices_fops); - debugfs_create_file("pinctrl-maps", S_IFREG | S_IRUGO, + debugfs_create_file("pinctrl-maps", 0444, debugfs_root, NULL, &pinctrl_maps_fops); - debugfs_create_file("pinctrl-handles", S_IFREG | S_IRUGO, + debugfs_create_file("pinctrl-handles", 0444, debugfs_root, NULL, &pinctrl_fops); } diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index 02c075cc010b..d9d54065472e 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c @@ -370,9 +370,9 @@ DEFINE_SHOW_ATTRIBUTE(pinconf_groups); void pinconf_init_device_debugfs(struct dentry *devroot, struct pinctrl_dev *pctldev) { - debugfs_create_file("pinconf-pins", S_IFREG | S_IRUGO, + debugfs_create_file("pinconf-pins", 0444, devroot, pctldev, &pinconf_pins_fops); - debugfs_create_file("pinconf-groups", S_IFREG | S_IRUGO, + debugfs_create_file("pinconf-groups", 0444, devroot, pctldev, &pinconf_groups_fops); } diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 36a11c9e893a..9c0174520e78 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -676,9 +676,9 @@ DEFINE_SHOW_ATTRIBUTE(pinmux_pins); void pinmux_init_device_debugfs(struct dentry *devroot, struct pinctrl_dev *pctldev) { - debugfs_create_file("pinmux-functions", S_IFREG | S_IRUGO, + debugfs_create_file("pinmux-functions", 0444, devroot, pctldev, &pinmux_functions_fops); - debugfs_create_file("pinmux-pins", S_IFREG | S_IRUGO, + debugfs_create_file("pinmux-pins", 0444, devroot, pctldev, &pinmux_pins_fops); } -- cgit v1.2.3 From 6199f6becc869d30ca9394ca0f7a484bf9d598eb Mon Sep 17 00:00:00 2001 From: Drew Fustini Date: Mon, 1 Mar 2021 21:30:57 -0800 Subject: pinctrl: pinmux: Add pinmux-select debugfs file Add "pinmux-select" to debugfs which will activate a pin function for a given pin group: echo "" > pinmux-select The write operation pinmux_select() handles this by checking that the names map to valid selectors and then calling ops->set_mux(). The existing "pinmux-functions" debugfs file lists the pin functions registered for the pin controller. For example: function: pinmux-uart0, groups = [ pinmux-uart0-pins ] function: pinmux-mmc0, groups = [ pinmux-mmc0-pins ] function: pinmux-mmc1, groups = [ pinmux-mmc1-pins ] function: pinmux-i2c0, groups = [ pinmux-i2c0-pins ] function: pinmux-i2c1, groups = [ pinmux-i2c1-pins ] function: pinmux-spi1, groups = [ pinmux-spi1-pins ] To activate function pinmux-i2c1 on group pinmux-i2c1-pins: echo "pinmux-i2c1-pins pinmux-i2c1" > pinmux-select Reviewed-by: Andy Shevchenko Reviewed-by: Tony Lindgren Reviewed-by: Geert Uytterhoeven Tested-by: Geert Uytterhoeven Signed-off-by: Drew Fustini Link: https://lore.kernel.org/r/20210302053059.1049035-3-drew@beagleboard.org Signed-off-by: Linus Walleij --- drivers/pinctrl/pinmux.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 9c0174520e78..6cdbd9ccf2f0 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -12,6 +12,7 @@ */ #define pr_fmt(fmt) "pinmux core: " fmt +#include #include #include #include @@ -673,6 +674,105 @@ void pinmux_show_setting(struct seq_file *s, DEFINE_SHOW_ATTRIBUTE(pinmux_functions); DEFINE_SHOW_ATTRIBUTE(pinmux_pins); +#define PINMUX_SELECT_MAX 128 +static ssize_t pinmux_select(struct file *file, const char __user *user_buf, + size_t len, loff_t *ppos) +{ + struct seq_file *sfile = file->private_data; + struct pinctrl_dev *pctldev = sfile->private; + const struct pinmux_ops *pmxops = pctldev->desc->pmxops; + const char *const *groups; + char *buf, *gname, *fname; + unsigned int num_groups; + int fsel, gsel, ret; + + if (len > PINMUX_SELECT_MAX) + return -ENOMEM; + + buf = kzalloc(PINMUX_SELECT_MAX, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + ret = strncpy_from_user(buf, user_buf, PINMUX_SELECT_MAX); + if (ret < 0) + goto exit_free_buf; + buf[len-1] = '\0'; + + /* remove leading and trailing spaces of input buffer */ + gname = strstrip(buf); + if (*gname == '\0') { + ret = -EINVAL; + goto exit_free_buf; + } + + /* find a separator which is a spacelike character */ + for (fname = gname; !isspace(*fname); fname++) { + if (*fname == '\0') { + ret = -EINVAL; + goto exit_free_buf; + } + } + *fname = '\0'; + + /* drop extra spaces between function and group names */ + fname = skip_spaces(fname + 1); + if (*fname == '\0') { + ret = -EINVAL; + goto exit_free_buf; + } + + ret = pinmux_func_name_to_selector(pctldev, fname); + if (ret < 0) { + dev_err(pctldev->dev, "invalid function %s in map table\n", fname); + goto exit_free_buf; + } + fsel = ret; + + ret = pmxops->get_function_groups(pctldev, fsel, &groups, &num_groups); + if (ret) { + dev_err(pctldev->dev, "no groups for function %d (%s)", fsel, fname); + goto exit_free_buf; + } + + ret = match_string(groups, num_groups, gname); + if (ret < 0) { + dev_err(pctldev->dev, "invalid group %s", gname); + goto exit_free_buf; + } + + ret = pinctrl_get_group_selector(pctldev, gname); + if (ret < 0) { + dev_err(pctldev->dev, "failed to get group selector for %s", gname); + goto exit_free_buf; + } + gsel = ret; + + ret = pmxops->set_mux(pctldev, fsel, gsel); + if (ret) { + dev_err(pctldev->dev, "set_mux() failed: %d", ret); + goto exit_free_buf; + } + ret = len; + +exit_free_buf: + kfree(buf); + + return ret; +} + +static int pinmux_select_open(struct inode *inode, struct file *file) +{ + return single_open(file, NULL, inode->i_private); +} + +static const struct file_operations pinmux_select_ops = { + .owner = THIS_MODULE, + .open = pinmux_select_open, + .write = pinmux_select, + .llseek = no_llseek, + .release = single_release, +}; + void pinmux_init_device_debugfs(struct dentry *devroot, struct pinctrl_dev *pctldev) { @@ -680,6 +780,8 @@ void pinmux_init_device_debugfs(struct dentry *devroot, devroot, pctldev, &pinmux_functions_fops); debugfs_create_file("pinmux-pins", 0444, devroot, pctldev, &pinmux_pins_fops); + debugfs_create_file("pinmux-select", 0200, + devroot, pctldev, &pinmux_select_ops); } #endif /* CONFIG_DEBUG_FS */ -- cgit v1.2.3 From 5513b411ea5b6bf1f1aa3a704eca0a4b352ab9c5 Mon Sep 17 00:00:00 2001 From: Drew Fustini Date: Mon, 1 Mar 2021 21:30:58 -0800 Subject: Documentation: rename pinctl to pin-control pinctl is not ideal as pinctrl (with an 'r') is much more common. Linus state that pin-control.rst would be the best name for the documentation. Link: https://lore.kernel.org/linux-gpio/20210126050817.GA187797@x1/#t Suggested-by: Linus Walleij Signed-off-by: Drew Fustini Link: https://lore.kernel.org/r/20210302053059.1049035-4-drew@beagleboard.org Signed-off-by: Linus Walleij --- Documentation/driver-api/gpio/legacy.rst | 2 +- Documentation/driver-api/index.rst | 2 +- Documentation/driver-api/pin-control.rst | 1430 ++++++++++++++++++++++++++++++ Documentation/driver-api/pinctl.rst | 1430 ------------------------------ MAINTAINERS | 2 +- 5 files changed, 1433 insertions(+), 1433 deletions(-) create mode 100644 Documentation/driver-api/pin-control.rst delete mode 100644 Documentation/driver-api/pinctl.rst diff --git a/Documentation/driver-api/gpio/legacy.rst b/Documentation/driver-api/gpio/legacy.rst index 9bc34ba697d9..9b12eeb89170 100644 --- a/Documentation/driver-api/gpio/legacy.rst +++ b/Documentation/driver-api/gpio/legacy.rst @@ -461,7 +461,7 @@ pin controller? This is done by registering "ranges" of pins, which are essentially cross-reference tables. These are described in -Documentation/driver-api/pinctl.rst +Documentation/driver-api/pin-control.rst While the pin allocation is totally managed by the pinctrl subsystem, gpio (under gpiolib) is still maintained by gpio drivers. It may happen diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst index b0ab367896ab..f5a3207aa7fa 100644 --- a/Documentation/driver-api/index.rst +++ b/Documentation/driver-api/index.rst @@ -62,7 +62,7 @@ available subsections can be seen below. 80211/index uio-howto firmware/index - pinctl + pin-control gpio/index md/index media/index diff --git a/Documentation/driver-api/pin-control.rst b/Documentation/driver-api/pin-control.rst new file mode 100644 index 000000000000..3d2deaf48841 --- /dev/null +++ b/Documentation/driver-api/pin-control.rst @@ -0,0 +1,1430 @@ +=============================== +PINCTRL (PIN CONTROL) subsystem +=============================== + +This document outlines the pin control subsystem in Linux + +This subsystem deals with: + +- Enumerating and naming controllable pins + +- Multiplexing of pins, pads, fingers (etc) see below for details + +- Configuration of pins, pads, fingers (etc), such as software-controlled + biasing and driving mode specific pins, such as pull-up/down, open drain, + load capacitance etc. + +Top-level interface +=================== + +Definition of PIN CONTROLLER: + +- A pin controller is a piece of hardware, usually a set of registers, that + can control PINs. It may be able to multiplex, bias, set load capacitance, + set drive strength, etc. for individual pins or groups of pins. + +Definition of PIN: + +- PINS are equal to pads, fingers, balls or whatever packaging input or + output line you want to control and these are denoted by unsigned integers + in the range 0..maxpin. This numberspace is local to each PIN CONTROLLER, so + there may be several such number spaces in a system. This pin space may + be sparse - i.e. there may be gaps in the space with numbers where no + pin exists. + +When a PIN CONTROLLER is instantiated, it will register a descriptor to the +pin control framework, and this descriptor contains an array of pin descriptors +describing the pins handled by this specific pin controller. + +Here is an example of a PGA (Pin Grid Array) chip seen from underneath:: + + A B C D E F G H + + 8 o o o o o o o o + + 7 o o o o o o o o + + 6 o o o o o o o o + + 5 o o o o o o o o + + 4 o o o o o o o o + + 3 o o o o o o o o + + 2 o o o o o o o o + + 1 o o o o o o o o + +To register a pin controller and name all the pins on this package we can do +this in our driver:: + + #include + + const struct pinctrl_pin_desc foo_pins[] = { + PINCTRL_PIN(0, "A8"), + PINCTRL_PIN(1, "B8"), + PINCTRL_PIN(2, "C8"), + ... + PINCTRL_PIN(61, "F1"), + PINCTRL_PIN(62, "G1"), + PINCTRL_PIN(63, "H1"), + }; + + static struct pinctrl_desc foo_desc = { + .name = "foo", + .pins = foo_pins, + .npins = ARRAY_SIZE(foo_pins), + .owner = THIS_MODULE, + }; + + int __init foo_probe(void) + { + int error; + + struct pinctrl_dev *pctl; + + error = pinctrl_register_and_init(&foo_desc, , + NULL, &pctl); + if (error) + return error; + + return pinctrl_enable(pctl); + } + +To enable the pinctrl subsystem and the subgroups for PINMUX and PINCONF and +selected drivers, you need to select them from your machine's Kconfig entry, +since these are so tightly integrated with the machines they are used on. +See for example arch/arm/mach-u300/Kconfig for an example. + +Pins usually have fancier names than this. You can find these in the datasheet +for your chip. Notice that the core pinctrl.h file provides a fancy macro +called PINCTRL_PIN() to create the struct entries. As you can see I enumerated +the pins from 0 in the upper left corner to 63 in the lower right corner. +This enumeration was arbitrarily chosen, in practice you need to think +through your numbering system so that it matches the layout of registers +and such things in your driver, or the code may become complicated. You must +also consider matching of offsets to the GPIO ranges that may be handled by +the pin controller. + +For a padring with 467 pads, as opposed to actual pins, I used an enumeration +like this, walking around the edge of the chip, which seems to be industry +standard too (all these pads had names, too):: + + + 0 ..... 104 + 466 105 + . . + . . + 358 224 + 357 .... 225 + + +Pin groups +========== + +Many controllers need to deal with groups of pins, so the pin controller +subsystem has a mechanism for enumerating groups of pins and retrieving the +actual enumerated pins that are part of a certain group. + +For example, say that we have a group of pins dealing with an SPI interface +on { 0, 8, 16, 24 }, and a group of pins dealing with an I2C interface on pins +on { 24, 25 }. + +These two groups are presented to the pin control subsystem by implementing +some generic pinctrl_ops like this:: + + #include + + struct foo_group { + const char *name; + const unsigned int *pins; + const unsigned num_pins; + }; + + static const unsigned int spi0_pins[] = { 0, 8, 16, 24 }; + static const unsigned int i2c0_pins[] = { 24, 25 }; + + static const struct foo_group foo_groups[] = { + { + .name = "spi0_grp", + .pins = spi0_pins, + .num_pins = ARRAY_SIZE(spi0_pins), + }, + { + .name = "i2c0_grp", + .pins = i2c0_pins, + .num_pins = ARRAY_SIZE(i2c0_pins), + }, + }; + + + static int foo_get_groups_count(struct pinctrl_dev *pctldev) + { + return ARRAY_SIZE(foo_groups); + } + + static const char *foo_get_group_name(struct pinctrl_dev *pctldev, + unsigned selector) + { + return foo_groups[selector].name; + } + + static int foo_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, + const unsigned **pins, + unsigned *num_pins) + { + *pins = (unsigned *) foo_groups[selector].pins; + *num_pins = foo_groups[selector].num_pins; + return 0; + } + + static struct pinctrl_ops foo_pctrl_ops = { + .get_groups_count = foo_get_groups_count, + .get_group_name = foo_get_group_name, + .get_group_pins = foo_get_group_pins, + }; + + + static struct pinctrl_desc foo_desc = { + ... + .pctlops = &foo_pctrl_ops, + }; + +The pin control subsystem will call the .get_groups_count() function to +determine the total number of legal selectors, then it will call the other functions +to retrieve the name and pins of the group. Maintaining the data structure of +the groups is up to the driver, this is just a simple example - in practice you +may need more entries in your group structure, for example specific register +ranges associated with each group and so on. + + +Pin configuration +================= + +Pins can sometimes be software-configured in various ways, mostly related +to their electronic properties when used as inputs or outputs. For example you +may be able to make an output pin high impedance, or "tristate" meaning it is +effectively disconnected. You may be able to connect an input pin to VDD or GND +using a certain resistor value - pull up and pull down - so that the pin has a +stable value when nothing is driving the rail it is connected to, or when it's +unconnected. + +Pin configuration can be programmed by adding configuration entries into the +mapping table; see section "Board/machine configuration" below. + +The format and meaning of the configuration parameter, PLATFORM_X_PULL_UP +above, is entirely defined by the pin controller driver. + +The pin configuration driver implements callbacks for changing pin +configuration in the pin controller ops like this:: + + #include + #include + #include "platform_x_pindefs.h" + + static int foo_pin_config_get(struct pinctrl_dev *pctldev, + unsigned offset, + unsigned long *config) + { + struct my_conftype conf; + + ... Find setting for pin @ offset ... + + *config = (unsigned long) conf; + } + + static int foo_pin_config_set(struct pinctrl_dev *pctldev, + unsigned offset, + unsigned long config) + { + struct my_conftype *conf = (struct my_conftype *) config; + + switch (conf) { + case PLATFORM_X_PULL_UP: + ... + } + } + } + + static int foo_pin_config_group_get (struct pinctrl_dev *pctldev, + unsigned selector, + unsigned long *config) + { + ... + } + + static int foo_pin_config_group_set (struct pinctrl_dev *pctldev, + unsigned selector, + unsigned long config) + { + ... + } + + static struct pinconf_ops foo_pconf_ops = { + .pin_config_get = foo_pin_config_get, + .pin_config_set = foo_pin_config_set, + .pin_config_group_get = foo_pin_config_group_get, + .pin_config_group_set = foo_pin_config_group_set, + }; + + /* Pin config operations are handled by some pin controller */ + static struct pinctrl_desc foo_desc = { + ... + .confops = &foo_pconf_ops, + }; + +Interaction with the GPIO subsystem +=================================== + +The GPIO drivers may want to perform operations of various types on the same +physical pins that are also registered as pin controller pins. + +First and foremost, the two subsystems can be used as completely orthogonal, +see the section named "pin control requests from drivers" and +"drivers needing both pin control and GPIOs" below for details. But in some +situations a cross-subsystem mapping between pins and GPIOs is needed. + +Since the pin controller subsystem has its pinspace local to the pin controller +we need a mapping so that the pin control subsystem can figure out which pin +controller handles control of a certain GPIO pin. Since a single pin controller +may be muxing several GPIO ranges (typically SoCs that have one set of pins, +but internally several GPIO silicon blocks, each modelled as a struct +gpio_chip) any number of GPIO ranges can be added to a pin controller instance +like this:: + + struct gpio_chip chip_a; + struct gpio_chip chip_b; + + static struct pinctrl_gpio_range gpio_range_a = { + .name = "chip a", + .id = 0, + .base = 32, + .pin_base = 32, + .npins = 16, + .gc = &chip_a; + }; + + static struct pinctrl_gpio_range gpio_range_b = { + .name = "chip b", + .id = 0, + .base = 48, + .pin_base = 64, + .npins = 8, + .gc = &chip_b; + }; + + { + struct pinctrl_dev *pctl; + ... + pinctrl_add_gpio_range(pctl, &gpio_range_a); + pinctrl_add_gpio_range(pctl, &gpio_range_b); + } + +So this complex system has one pin controller handling two different +GPIO chips. "chip a" has 16 pins and "chip b" has 8 pins. The "chip a" and +"chip b" have different .pin_base, which means a start pin number of the +GPIO range. + +The GPIO range of "chip a" starts from the GPIO base of 32 and actual +pin range also starts from 32. However "chip b" has different starting +offset for the GPIO range and pin range. The GPIO range of "chip b" starts +from GPIO number 48, while the pin range of "chip b" starts from 64. + +We can convert a gpio number to actual pin number using this "pin_base". +They are mapped in the global GPIO pin space at: + +chip a: + - GPIO range : [32 .. 47] + - pin range : [32 .. 47] +chip b: + - GPIO range : [48 .. 55] + - pin range : [64 .. 71] + +The above examples assume the mapping between the GPIOs and pins is +linear. If the mapping is sparse or haphazard, an array of arbitrary pin +numbers can be encoded in the range like this:: + + static const unsigned range_pins[] = { 14, 1, 22, 17, 10, 8, 6, 2 }; + + static struct pinctrl_gpio_range gpio_range = { + .name = "chip", + .id = 0, + .base = 32, + .pins = &range_pins, + .npins = ARRAY_SIZE(range_pins), + .gc = &chip; + }; + +In this case the pin_base property will be ignored. If the name of a pin +group is known, the pins and npins elements of the above structure can be +initialised using the function pinctrl_get_group_pins(), e.g. for pin +group "foo":: + + pinctrl_get_group_pins(pctl, "foo", &gpio_range.pins, + &gpio_range.npins); + +When GPIO-specific functions in the pin control subsystem are called, these +ranges will be used to look up the appropriate pin controller by inspecting +and matching the pin to the pin ranges across all controllers. When a +pin controller handling the matching range is found, GPIO-specific functions +will be called on that specific pin controller. + +For all functionalities dealing with pin biasing, pin muxing etc, the pin +controller subsystem will look up the corresponding pin number from the passed +in gpio number, and use the range's internals to retrieve a pin number. After +that, the subsystem passes it on to the pin control driver, so the driver +will get a pin number into its handled number range. Further it is also passed +the range ID value, so that the pin controller knows which range it should +deal with. + +Calling pinctrl_add_gpio_range from pinctrl driver is DEPRECATED. Please see +section 2.1 of Documentation/devicetree/bindings/gpio/gpio.txt on how to bind +pinctrl and gpio drivers. + + +PINMUX interfaces +================= + +These calls use the pinmux_* naming prefix. No other calls should use that +prefix. + + +What is pinmuxing? +================== + +PINMUX, also known as padmux, ballmux, alternate functions or mission modes +is a way for chip vendors producing some kind of electrical packages to use +a certain physical pin (ball, pad, finger, etc) for multiple mutually exclusive +functions, depending on the application. By "application" in this context +we usually mean a way of soldering or wiring the package into an electronic +system, even though the framework makes it possible to also change the function +at runtime. + +Here is an example of a PGA (Pin Grid Array) chip seen from underneath:: + + A B C D E F G H + +---+ + 8 | o | o o o o o o o + | | + 7 | o | o o o o o o o + | | + 6 | o | o o o o o o o + +---+---+ + 5 | o | o | o o o o o o + +---+---+ +---+ + 4 o o o o o o | o | o + | | + 3 o o o o o o | o | o + | | + 2 o o o o o o | o | o + +-------+-------+-------+---+---+ + 1 | o o | o o | o o | o | o | + +-------+-------+-------+---+---+ + +This is not tetris. The game to think of is chess. Not all PGA/BGA packages +are chessboard-like, big ones have "holes" in some arrangement according to +different design patterns, but we're using this as a simple example. Of the +pins you see some will be taken by things like a few VCC and GND to feed power +to the chip, and quite a few will be taken by large ports like an external +memory interface. The remaining pins will often be subject to pin multiplexing. + +The example 8x8 PGA package above will have pin numbers 0 through 63 assigned +to its physical pins. It will name the pins { A1, A2, A3 ... H6, H7, H8 } using +pinctrl_register_pins() and a suitable data set as shown earlier. + +In this 8x8 BGA package the pins { A8, A7, A6, A5 } can be used as an SPI port +(these are four pins: CLK, RXD, TXD, FRM). In that case, pin B5 can be used as +some general-purpose GPIO pin. However, in another setting, pins { A5, B5 } can +be used as an I2C port (these are just two pins: SCL, SDA). Needless to say, +we cannot use the SPI port and I2C port at the same time. However in the inside +of the package the silicon performing the SPI logic can alternatively be routed +out on pins { G4, G3, G2, G1 }. + +On the bottom row at { A1, B1, C1, D1, E1, F1, G1, H1 } we have something +special - it's an external MMC bus that can be 2, 4 or 8 bits wide, and it will +consume 2, 4 or 8 pins respectively, so either { A1, B1 } are taken or +{ A1, B1, C1, D1 } or all of them. If we use all 8 bits, we cannot use the SPI +port on pins { G4, G3, G2, G1 } of course. + +This way the silicon blocks present inside the chip can be multiplexed "muxed" +out on different pin ranges. Often contemporary SoC (systems on chip) will +contain several I2C, SPI, SDIO/MMC, etc silicon blocks that can be routed to +different pins by pinmux settings. + +Since general-purpose I/O pins (GPIO) are typically always in shortage, it is +common to be able to use almost any pin as a GPIO pin if it is not currently +in use by some other I/O port. + + +Pinmux conventions +================== + +The purpose of the pinmux functionality in the pin controller subsystem is to +abstract and provide pinmux settings to the devices you choose to instantiate +in your machine configuration. It is inspired by the clk, GPIO and regulator +subsystems, so devices will request their mux setting, but it's also possible +to request a single pin for e.g. GPIO. + +Definitions: + +- FUNCTIONS can be switched in and out by a driver residing with the pin + control subsystem in the drivers/pinctrl/* directory of the kernel. The + pin control driver knows the possible functions. In the example above you can + identify three pinmux functions, one for spi, one for i2c and one for mmc. + +- FUNCTIONS are assumed to be enumerable from zero in a one-dimensional array. + In this case the array could be something like: { spi0, i2c0, mmc0 } + for the three available functions. + +- FUNCTIONS have PIN GROUPS as defined on the generic level - so a certain + function is *always* associated with a certain set of pin groups, could + be just a single one, but could also be many. In the example above the + function i2c is associated with the pins { A5, B5 }, enumerated as + { 24, 25 } in the controller pin space. + + The Function spi is associated with pin groups { A8, A7, A6, A5 } + and { G4, G3, G2, G1 }, which are enumerated as { 0, 8, 16, 24 } and + { 38, 46, 54, 62 } respectively. + + Group names must be unique per pin controller, no two groups on the same + controller may have the same name. + +- The combination of a FUNCTION and a PIN GROUP determine a certain function + for a certain set of pins. The knowledge of the functions and pin groups + and their machine-specific particulars are kept inside the pinmux driver, + from the outside only the enumerators are known, and the driver core can + request: + + - The name of a function with a certain selector (>= 0) + - A list of groups associated with a certain function + - That a certain group in that list to be activated for a certain function + + As already described above, pin groups are in turn self-descriptive, so + the core will retrieve the actual pin range in a certain group from the + driver. + +- FUNCTIONS and GROUPS on a certain PIN CONTROLLER are MAPPED to a certain + device by the board file, device tree or similar machine setup configuration + mechanism, similar to how regulators are connected to devices, usually by + name. Defining a pin controller, function and group thus uniquely identify + the set of pins to be used by a certain device. (If only one possible group + of pins is available for the function, no group name need to be supplied - + the core will simply select the first and only group available.) + + In the example case we can define that this particular machine shall + use device spi0 with pinmux function fspi0 group gspi0 and i2c0 on function + fi2c0 group gi2c0, on the primary pin controller, we get mappings + like these:: + + { + {"map-spi0", spi0, pinctrl0, fspi0, gspi0}, + {"map-i2c0", i2c0, pinctrl0, fi2c0, gi2c0} + } + + Every map must be assigned a state name, pin controller, device and + function. The group is not compulsory - if it is omitted the first group + presented by the driver as applicable for the function will be selected, + which is useful for simple cases. + + It is possible to map several groups to the same combination of device, + pin controller and function. This is for cases where a certain function on + a certain pin controller may use different sets of pins in different + configurations. + +- PINS for a certain FUNCTION using a certain PIN GROUP on a certain + PIN CONTROLLER are provided on a first-come first-serve basis, so if some + other device mux setting or GPIO pin request has already taken your physical + pin, you will be denied the use of it. To get (activate) a new setting, the + old one has to be put (deactivated) first. + +Sometimes the documentation and hardware registers will be oriented around +pads (or "fingers") rather than pins - these are the soldering surfaces on the +silicon inside the package, and may or may not match the actual number of +pins/balls underneath the capsule. Pick some enumeration that makes sense to +you. Define enumerators only for the pins you can control if that makes sense. + +Assumptions: + +We assume that the number of possible function maps to pin groups is limited by +the hardware. I.e. we assume that there is no system where any function can be +mapped to any pin, like in a phone exchange. So the available pin groups for +a certain function will be limited to a few choices (say up to eight or so), +not hundreds or any amount of choices. This is the characteristic we have found +by inspecting available pinmux hardware, and a necessary assumption since we +expect pinmux drivers to present *all* possible function vs pin group mappings +to the subsystem. + + +Pinmux drivers +============== + +The pinmux core takes care of preventing conflicts on pins and calling +the pin controller driver to execute different settings. + +It is the responsibility of the pinmux driver to impose further restrictions +(say for example infer electronic limitations due to load, etc.) to determine +whether or not the requested function can actually be allowed, and in case it +is possible to perform the requested mux setting, poke the hardware so that +this happens. + +Pinmux drivers are required to supply a few callback functions, some are +optional. Usually the set_mux() function is implemented, writing values into +some certain registers to activate a certain mux setting for a certain pin. + +A simple driver for the above example will work by setting bits 0, 1, 2, 3 or 4 +into some register named MUX to select a certain function with a certain +group of pins would work something like this:: + + #include + #include + + struct foo_group { + const char *name; + const unsigned int *pins; + const unsigned num_pins; + }; + + static const unsigned spi0_0_pins[] = { 0, 8, 16, 24 }; + static const unsigned spi0_1_pins[] = { 38, 46, 54, 62 }; + static const unsigned i2c0_pins[] = { 24, 25 }; + static const unsigned mmc0_1_pins[] = { 56, 57 }; + static const unsigned mmc0_2_pins[] = { 58, 59 }; + static const unsigned mmc0_3_pins[] = { 60, 61, 62, 63 }; + + static const struct foo_group foo_groups[] = { + { + .name = "spi0_0_grp", + .pins = spi0_0_pins, + .num_pins = ARRAY_SIZE(spi0_0_pins), + }, + { + .name = "spi0_1_grp", + .pins = spi0_1_pins, + .num_pins = ARRAY_SIZE(spi0_1_pins), + }, + { + .name = "i2c0_grp", + .pins = i2c0_pins, + .num_pins = ARRAY_SIZE(i2c0_pins), + }, + { + .name = "mmc0_1_grp", + .pins = mmc0_1_pins, + .num_pins = ARRAY_SIZE(mmc0_1_pins), + }, + { + .name = "mmc0_2_grp", + .pins = mmc0_2_pins, + .num_pins = ARRAY_SIZE(mmc0_2_pins), + }, + { + .name = "mmc0_3_grp", + .pins = mmc0_3_pins, + .num_pins = ARRAY_SIZE(mmc0_3_pins), + }, + }; + + + static int foo_get_groups_count(struct pinctrl_dev *pctldev) + { + return ARRAY_SIZE(foo_groups); + } + + static const char *foo_get_group_name(struct pinctrl_dev *pctldev, + unsigned selector) + { + return foo_groups[selector].name; + } + + static int foo_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, + const unsigned ** pins, + unsigned * num_pins) + { + *pins = (unsigned *) foo_groups[selector].pins; + *num_pins = foo_groups[selector].num_pins; + return 0; + } + + static struct pinctrl_ops foo_pctrl_ops = { + .get_groups_count = foo_get_groups_count, + .get_group_name = foo_get_group_name, + .get_group_pins = foo_get_group_pins, + }; + + struct foo_pmx_func { + const char *name; + const char * const *groups; + const unsigned num_groups; + }; + + static const char * const spi0_groups[] = { "spi0_0_grp", "spi0_1_grp" }; + static const char * const i2c0_groups[] = { "i2c0_grp" }; + static const char * const mmc0_groups[] = { "mmc0_1_grp", "mmc0_2_grp", + "mmc0_3_grp" }; + + static const struct foo_pmx_func foo_functions[] = { + { + .name = "spi0", + .groups = spi0_groups, + .num_groups = ARRAY_SIZE(spi0_groups), + }, + { + .name = "i2c0", + .groups = i2c0_groups, + .num_groups = ARRAY_SIZE(i2c0_groups), + }, + { + .name = "mmc0", + .groups = mmc0_groups, + .num_groups = ARRAY_SIZE(mmc0_groups), + }, + }; + + static int foo_get_functions_count(struct pinctrl_dev *pctldev) + { + return ARRAY_SIZE(foo_functions); + } + + static const char *foo_get_fname(struct pinctrl_dev *pctldev, unsigned selector) + { + return foo_functions[selector].name; + } + + static int foo_get_groups(struct pinctrl_dev *pctldev, unsigned selector, + const char * const **groups, + unsigned * const num_groups) + { + *groups = foo_functions[selector].groups; + *num_groups = foo_functions[selector].num_groups; + return 0; + } + + static int foo_set_mux(struct pinctrl_dev *pctldev, unsigned selector, + unsigned group) + { + u8 regbit = (1 << selector + group); + + writeb((readb(MUX)|regbit), MUX); + return 0; + } + + static struct pinmux_ops foo_pmxops = { + .get_functions_count = foo_get_functions_count, + .get_function_name = foo_get_fname, + .get_function_groups = foo_get_groups, + .set_mux = foo_set_mux, + .strict = true, + }; + + /* Pinmux operations are handled by some pin controller */ + static struct pinctrl_desc foo_desc = { + ... + .pctlops = &foo_pctrl_ops, + .pmxops = &foo_pmxops, + }; + +In the example activating muxing 0 and 1 at the same time setting bits +0 and 1, uses one pin in common so they would collide. + +The beauty of the pinmux subsystem is that since it keeps track of all +pins and who is using them, it will already have denied an impossible +request like that, so the driver does not need to worry about such +things - when it gets a selector passed in, the pinmux subsystem makes +sure no other device or GPIO assignment is already using the selected +pins. Thus bits 0 and 1 in the control register will never be set at the +same time. + +All the above functions are mandatory to implement for a pinmux driver. + + +Pin control interaction with the GPIO subsystem +=============================================== + +Note that the following implies that the use case is to use a certain pin +from the Linux kernel using the API in with gpio_request() +and similar functions. There are cases where you may be using something +that your datasheet calls "GPIO mode", but actually is just an electrical +configuration for a certain device. See the section below named +"GPIO mode pitfalls" for more details on this scenario. + +The public pinmux API contains two functions named pinctrl_gpio_request() +and pinctrl_gpio_free(). These two functions shall *ONLY* be called from +gpiolib-based drivers as part of their gpio_request() and +gpio_free() semantics. Likewise the pinctrl_gpio_direction_[input|output] +shall only be called from within respective gpio_direction_[input|output] +gpiolib implementation. + +NOTE that platforms and individual drivers shall *NOT* request GPIO pins to be +controlled e.g. muxed in. Instead, implement a proper gpiolib driver and have +that driver request proper muxing and other control for its pins. + +The function list could become long, especially if you can convert every +individual pin into a GPIO pin independent of any other pins, and then try +the approach to define every pin as a function. + +In this case, the function array would become 64 entries for each GPIO +setting and then the device functions. + +For this reason there are two functions a pin control driver can implement +to enable only GPIO on an individual pin: .gpio_request_enable() and +.gpio_disable_free(). + +This function will pass in the affected GPIO range identified by the pin +controller core, so you know which GPIO pins are being affected by the request +operation. + +If your driver needs to have an indication from the framework of whether the +GPIO pin shall be used for input or output you can implement the +.gpio_set_direction() function. As described this shall be called from the +gpiolib driver and the affected GPIO range, pin offset and desired direction +will be passed along to this function. + +Alternatively to using these special functions, it is fully allowed to use +named functions for each GPIO pin, the pinctrl_gpio_request() will attempt to +obtain the function "gpioN" where "N" is the global GPIO pin number if no +special GPIO-handler is registered. + + +GPIO mode pitfalls +================== + +Due to the naming conventions used by hardware engineers, where "GPIO" +is taken to mean different things than what the kernel does, the developer +may be confused by a datasheet talking about a pin being possible to set +into "GPIO mode". It appears that what hardware engineers mean with +"GPIO mode" is not necessarily the use case that is implied in the kernel +interface : a pin that you grab from kernel code and then +either listen for input or drive high/low to assert/deassert some +external line. + +Rather hardware engineers think that "GPIO mode" means that you can +software-control a few electrical properties of the pin that you would +not be able to control if the pin was in some other mode, such as muxed in +for a device. + +The GPIO portions of a pin and its relation to a certain pin controller +configuration and muxing logic can be constructed in several ways. Here +are two examples:: + + (A) + pin config + logic regs + | +- SPI + Physical pins --- pad --- pinmux -+- I2C + | +- mmc + | +- GPIO + pin + multiplex + logic regs + +Here some electrical properties of the pin can be configured no matter +whether the pin is used for GPIO or not. If you multiplex a GPIO onto a +pin, you can also drive it high/low from "GPIO" registers. +Alternatively, the pin can be controlled by a certain peripheral, while +still applying desired pin config properties. GPIO functionality is thus +orthogonal to any other device using the pin. + +In this arrangement the registers for the GPIO portions of the pin controller, +or the registers for the GPIO hardware module are likely to reside in a +separate memory range only intended for GPIO driving, and the register +range dealing with pin config and pin multiplexing get placed into a +different memory range and a separate section of the data sheet. + +A flag "strict" in struct pinmux_ops is available to check and deny +simultaneous access to the same pin from GPIO and pin multiplexing +consumers on hardware of this type. The pinctrl driver should set this flag +accordingly. + +:: + + (B) + + pin config + logic regs + | +- SPI + Physical pins --- pad --- pinmux -+- I2C + | | +- mmc + | | + GPIO pin + multiplex + logic regs + +In this arrangement, the GPIO functionality can always be enabled, such that +e.g. a GPIO input can be used to "spy" on the SPI/I2C/MMC signal while it is +pulsed out. It is likely possible to disrupt the traffic on the pin by doing +wrong things on the GPIO block, as it is never really disconnected. It is +possible that the GPIO, pin config and pin multiplex registers are placed into +the same memory range and the same section of the data sheet, although that +need not be the case. + +In some pin controllers, although the physical pins are designed in the same +way as (B), the GPIO function still can't be enabled at the same time as the +peripheral functions. So again the "strict" flag should be set, denying +simultaneous activation by GPIO and other muxed in devices. + +From a kernel point of view, however, these are different aspects of the +hardware and shall be put into different subsystems: + +- Registers (or fields within registers) that control electrical + properties of the pin such as biasing and drive strength should be + exposed through the pinctrl subsystem, as "pin configuration" settings. + +- Registers (or fields within registers) that control muxing of signals + from various other HW blocks (e.g. I2C, MMC, or GPIO) onto pins should + be exposed through the pinctrl subsystem, as mux functions. + +- Registers (or fields within registers) that control GPIO functionality + such as setting a GPIO's output value, reading a GPIO's input value, or + setting GPIO pin direction should be exposed through the GPIO subsystem, + and if they also support interrupt capabilities, through the irqchip + abstraction. + +Depending on the exact HW register design, some functions exposed by the +GPIO subsystem may call into the pinctrl subsystem in order to +co-ordinate register settings across HW modules. In particular, this may +be needed for HW with separate GPIO and pin controller HW modules, where +e.g. GPIO direction is determined by a register in the pin controller HW +module rather than the GPIO HW module. + +Electrical properties of the pin such as biasing and drive strength +may be placed at some pin-specific register in all cases or as part +of the GPIO register in case (B) especially. This doesn't mean that such +properties necessarily pertain to what the Linux kernel calls "GPIO". + +Example: a pin is usually muxed in to be used as a UART TX line. But during +system sleep, we need to put this pin into "GPIO mode" and ground it. + +If you make a 1-to-1 map to the GPIO subsystem for this pin, you may start +to think that you need to come up with something really complex, that the +pin shall be used for UART TX and GPIO at the same time, that you will grab +a pin control handle and set it to a certain state to enable UART TX to be +muxed in, then twist it over to GPIO mode and use gpio_direction_output() +to drive it low during sleep, then mux it over to UART TX again when you +wake up and maybe even gpio_request/gpio_free as part of this cycle. This +all gets very complicated. + +The solution is to not think that what the datasheet calls "GPIO mode" +has to be handled by the interface. Instead view this as +a certain pin config setting. Look in e.g. +and you find this in the documentation: + + PIN_CONFIG_OUTPUT: + this will configure the pin in output, use argument + 1 to indicate high level, argument 0 to indicate low level. + +So it is perfectly possible to push a pin into "GPIO mode" and drive the +line low as part of the usual pin control map. So for example your UART +driver may look like this:: + + #include + + struct pinctrl *pinctrl; + struct pinctrl_state *pins_default; + struct pinctrl_state *pins_sleep; + + pins_default = pinctrl_lookup_state(uap->pinctrl, PINCTRL_STATE_DEFAULT); + pins_sleep = pinctrl_lookup_state(uap->pinctrl, PINCTRL_STATE_SLEEP); + + /* Normal mode */ + retval = pinctrl_select_state(pinctrl, pins_default); + /* Sleep mode */ + retval = pinctrl_select_state(pinctrl, pins_sleep); + +And your machine configuration may look like this: +-------------------------------------------------- + +:: + + static unsigned long uart_default_mode[] = { + PIN_CONF_PACKED(PIN_CONFIG_DRIVE_PUSH_PULL, 0), + }; + + static unsigned long uart_sleep_mode[] = { + PIN_CONF_PACKED(PIN_CONFIG_OUTPUT, 0), + }; + + static struct pinctrl_map pinmap[] __initdata = { + PIN_MAP_MUX_GROUP("uart", PINCTRL_STATE_DEFAULT, "pinctrl-foo", + "u0_group", "u0"), + PIN_MAP_CONFIGS_PIN("uart", PINCTRL_STATE_DEFAULT, "pinctrl-foo", + "UART_TX_PIN", uart_default_mode), + PIN_MAP_MUX_GROUP("uart", PINCTRL_STATE_SLEEP, "pinctrl-foo", + "u0_group", "gpio-mode"), + PIN_MAP_CONFIGS_PIN("uart", PINCTRL_STATE_SLEEP, "pinctrl-foo", + "UART_TX_PIN", uart_sleep_mode), + }; + + foo_init(void) { + pinctrl_register_mappings(pinmap, ARRAY_SIZE(pinmap)); + } + +Here the pins we want to control are in the "u0_group" and there is some +function called "u0" that can be enabled on this group of pins, and then +everything is UART business as usual. But there is also some function +named "gpio-mode" that can be mapped onto the same pins to move them into +GPIO mode. + +This will give the desired effect without any bogus interaction with the +GPIO subsystem. It is just an electrical configuration used by that device +when going to sleep, it might imply that the pin is set into something the +datasheet calls "GPIO mode", but that is not the point: it is still used +by that UART device to control the pins that pertain to that very UART +driver, putting them into modes needed by the UART. GPIO in the Linux +kernel sense are just some 1-bit line, and is a different use case. + +How the registers are poked to attain the push or pull, and output low +configuration and the muxing of the "u0" or "gpio-mode" group onto these +pins is a question for the driver. + +Some datasheets will be more helpful and refer to the "GPIO mode" as +"low power mode" rather than anything to do with GPIO. This often means +the same thing electrically speaking, but in this latter case the +software engineers will usually quickly identify that this is some +specific muxing or configuration rather than anything related to the GPIO +API. + + +Board/machine configuration +=========================== + +Boards and machines define how a certain complete running system is put +together, including how GPIOs and devices are muxed, how regulators are +constrained and how the clock tree looks. Of course pinmux settings are also +part of this. + +A pin controller configuration for a machine looks pretty much like a simple +regulator configuration, so for the example array above we want to enable i2c +and spi on the second function mapping:: + + #include + + static const struct pinctrl_map mapping[] __initconst = { + { + .dev_name = "foo-spi.0", + .name = PINCTRL_STATE_DEFAULT, + .type = PIN_MAP_TYPE_MUX_GROUP, + .ctrl_dev_name = "pinctrl-foo", + .data.mux.function = "spi0", + }, + { + .dev_name = "foo-i2c.0", + .name = PINCTRL_STATE_DEFAULT, + .type = PIN_MAP_TYPE_MUX_GROUP, + .ctrl_dev_name = "pinctrl-foo", + .data.mux.function = "i2c0", + }, + { + .dev_name = "foo-mmc.0", + .name = PINCTRL_STATE_DEFAULT, + .type = PIN_MAP_TYPE_MUX_GROUP, + .ctrl_dev_name = "pinctrl-foo", + .data.mux.function = "mmc0", + }, + }; + +The dev_name here matches to the unique device name that can be used to look +up the device struct (just like with clockdev or regulators). The function name +must match a function provided by the pinmux driver handling this pin range. + +As you can see we may have several pin controllers on the system and thus +we need to specify which one of them contains the functions we wish to map. + +You register this pinmux mapping to the pinmux subsystem by simply:: + + ret = pinctrl_register_mappings(mapping, ARRAY_SIZE(mapping)); + +Since the above construct is pretty common there is a helper macro to make +it even more compact which assumes you want to use pinctrl-foo and position +0 for mapping, for example:: + + static struct pinctrl_map mapping[] __initdata = { + PIN_MAP_MUX_GROUP("foo-i2c.o", PINCTRL_STATE_DEFAULT, + "pinctrl-foo", NULL, "i2c0"), + }; + +The mapping table may also contain pin configuration entries. It's common for +each pin/group to have a number of configuration entries that affect it, so +the table entries for configuration reference an array of config parameters +and values. An example using the convenience macros is shown below:: + + static unsigned long i2c_grp_configs[] = { + FOO_PIN_DRIVEN, + FOO_PIN_PULLUP, + }; + + static unsigned long i2c_pin_configs[] = { + FOO_OPEN_COLLECTOR, + FOO_SLEW_RATE_SLOW, + }; + + static struct pinctrl_map mapping[] __initdata = { + PIN_MAP_MUX_GROUP("foo-i2c.0", PINCTRL_STATE_DEFAULT, + "pinctrl-foo", "i2c0", "i2c0"), + PIN_MAP_CONFIGS_GROUP("foo-i2c.0", PINCTRL_STATE_DEFAULT, + "pinctrl-foo", "i2c0", i2c_grp_configs), + PIN_MAP_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, + "pinctrl-foo", "i2c0scl", i2c_pin_configs), + PIN_MAP_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, + "pinctrl-foo", "i2c0sda", i2c_pin_configs), + }; + +Finally, some devices expect the mapping table to contain certain specific +named states. When running on hardware that doesn't need any pin controller +configuration, the mapping table must still contain those named states, in +order to explicitly indicate that the states were provided and intended to +be empty. Table entry macro PIN_MAP_DUMMY_STATE serves the purpose of defining +a named state without causing any pin controller to be programmed:: + + static struct pinctrl_map mapping[] __initdata = { + PIN_MAP_DUMMY_STATE("foo-i2c.0", PINCTRL_STATE_DEFAULT), + }; + + +Complex mappings +================ + +As it is possible to map a function to different groups of pins an optional +.group can be specified like this:: + + ... + { + .dev_name = "foo-spi.0", + .name = "spi0-pos-A", + .type = PIN_MAP_TYPE_MUX_GROUP, + .ctrl_dev_name = "pinctrl-foo", + .function = "spi0", + .group = "spi0_0_grp", + }, + { + .dev_name = "foo-spi.0", + .name = "spi0-pos-B", + .type = PIN_MAP_TYPE_MUX_GROUP, + .ctrl_dev_name = "pinctrl-foo", + .function = "spi0", + .group = "spi0_1_grp", + }, + ... + +This example mapping is used to switch between two positions for spi0 at +runtime, as described further below under the heading "Runtime pinmuxing". + +Further it is possible for one named state to affect the muxing of several +groups of pins, say for example in the mmc0 example above, where you can +additively expand the mmc0 bus from 2 to 4 to 8 pins. If we want to use all +three groups for a total of 2+2+4 = 8 pins (for an 8-bit MMC bus as is the +case), we define a mapping like this:: + + ... + { + .dev_name = "foo-mmc.0", + .name = "2bit" + .type = PIN_MAP_TYPE_MUX_GROUP, + .ctrl_dev_name = "pinctrl-foo", + .function = "mmc0", + .group = "mmc0_1_grp", + }, + { + .dev_name = "foo-mmc.0", + .name = "4bit" + .type = PIN_MAP_TYPE_MUX_GROUP, + .ctrl_dev_name = "pinctrl-foo", + .function = "mmc0", + .group = "mmc0_1_grp", + }, + { + .dev_name = "foo-mmc.0", + .name = "4bit" + .type = PIN_MAP_TYPE_MUX_GROUP, + .ctrl_dev_name = "pinctrl-foo", + .function = "mmc0", + .group = "mmc0_2_grp", + }, + { + .dev_name = "foo-mmc.0", + .name = "8bit" + .type = PIN_MAP_TYPE_MUX_GROUP, + .ctrl_dev_name = "pinctrl-foo", + .function = "mmc0", + .group = "mmc0_1_grp", + }, + { + .dev_name = "foo-mmc.0", + .name = "8bit" + .type = PIN_MAP_TYPE_MUX_GROUP, + .ctrl_dev_name = "pinctrl-foo", + .function = "mmc0", + .group = "mmc0_2_grp", + }, + { + .dev_name = "foo-mmc.0", + .name = "8bit" + .type = PIN_MAP_TYPE_MUX_GROUP, + .ctrl_dev_name = "pinctrl-foo", + .function = "mmc0", + .group = "mmc0_3_grp", + }, + ... + +The result of grabbing this mapping from the device with something like +this (see next paragraph):: + + p = devm_pinctrl_get(dev); + s = pinctrl_lookup_state(p, "8bit"); + ret = pinctrl_select_state(p, s); + +or more simply:: + + p = devm_pinctrl_get_select(dev, "8bit"); + +Will be that you activate all the three bottom records in the mapping at +once. Since they share the same name, pin controller device, function and +device, and since we allow multiple groups to match to a single device, they +all get selected, and they all get enabled and disable simultaneously by the +pinmux core. + + +Pin control requests from drivers +================================= + +When a device driver is about to probe the device core will automatically +attempt to issue pinctrl_get_select_default() on these devices. +This way driver writers do not need to add any of the boilerplate code +of the type found below. However when doing fine-grained state selection +and not using the "default" state, you may have to do some device driver +handling of the pinctrl handles and states. + +So if you just want to put the pins for a certain device into the default +state and be done with it, there is nothing you need to do besides +providing the proper mapping table. The device core will take care of +the rest. + +Generally it is discouraged to let individual drivers get and enable pin +control. So if possible, handle the pin control in platform code or some other +place where you have access to all the affected struct device * pointers. In +some cases where a driver needs to e.g. switch between different mux mappings +at runtime this is not possible. + +A typical case is if a driver needs to switch bias of pins from normal +operation and going to sleep, moving from the PINCTRL_STATE_DEFAULT to +PINCTRL_STATE_SLEEP at runtime, re-biasing or even re-muxing pins to save +current in sleep mode. + +A driver may request a certain control state to be activated, usually just the +default state like this:: + + #include + + struct foo_state { + struct pinctrl *p; + struct pinctrl_state *s; + ... + }; + + foo_probe() + { + /* Allocate a state holder named "foo" etc */ + struct foo_state *foo = ...; + + foo->p = devm_pinctrl_get(&device); + if (IS_ERR(foo->p)) { + /* FIXME: clean up "foo" here */ + return PTR_ERR(foo->p); + } + + foo->s = pinctrl_lookup_state(foo->p, PINCTRL_STATE_DEFAULT); + if (IS_ERR(foo->s)) { + /* FIXME: clean up "foo" here */ + return PTR_ERR(s); + } + + ret = pinctrl_select_state(foo->s); + if (ret < 0) { + /* FIXME: clean up "foo" here */ + return ret; + } + } + +This get/lookup/select/put sequence can just as well be handled by bus drivers +if you don't want each and every driver to handle it and you know the +arrangement on your bus. + +The semantics of the pinctrl APIs are: + +- pinctrl_get() is called in process context to obtain a handle to all pinctrl + information for a given client device. It will allocate a struct from the + kernel memory to hold the pinmux state. All mapping table parsing or similar + slow operations take place within this API. + +- devm_pinctrl_get() is a variant of pinctrl_get() that causes pinctrl_put() + to be called automatically on the retrieved pointer when the associated + device is removed. It is recommended to use this function over plain + pinctrl_get(). + +- pinctrl_lookup_state() is called in process context to obtain a handle to a + specific state for a client device. This operation may be slow, too. + +- pinctrl_select_state() programs pin controller hardware according to the + definition of the state as given by the mapping table. In theory, this is a + fast-path operation, since it only involved blasting some register settings + into hardware. However, note that some pin controllers may have their + registers on a slow/IRQ-based bus, so client devices should not assume they + can call pinctrl_select_state() from non-blocking contexts. + +- pinctrl_put() frees all information associated with a pinctrl handle. + +- devm_pinctrl_put() is a variant of pinctrl_put() that may be used to + explicitly destroy a pinctrl object returned by devm_pinctrl_get(). + However, use of this function will be rare, due to the automatic cleanup + that will occur even without calling it. + + pinctrl_get() must be paired with a plain pinctrl_put(). + pinctrl_get() may not be paired with devm_pinctrl_put(). + devm_pinctrl_get() can optionally be paired with devm_pinctrl_put(). + devm_pinctrl_get() may not be paired with plain pinctrl_put(). + +Usually the pin control core handled the get/put pair and call out to the +device drivers bookkeeping operations, like checking available functions and +the associated pins, whereas select_state pass on to the pin controller +driver which takes care of activating and/or deactivating the mux setting by +quickly poking some registers. + +The pins are allocated for your device when you issue the devm_pinctrl_get() +call, after this you should be able to see this in the debugfs listing of all +pins. + +NOTE: the pinctrl system will return -EPROBE_DEFER if it cannot find the +requested pinctrl handles, for example if the pinctrl driver has not yet +registered. Thus make sure that the error path in your driver gracefully +cleans up and is ready to retry the probing later in the startup process. + + +Drivers needing both pin control and GPIOs +========================================== + +Again, it is discouraged to let drivers lookup and select pin control states +themselves, but again sometimes this is unavoidable. + +So say that your driver is fetching its resources like this:: + + #include + #include + + struct pinctrl *pinctrl; + int gpio; + + pinctrl = devm_pinctrl_get_select_default(&dev); + gpio = devm_gpio_request(&dev, 14, "foo"); + +Here we first request a certain pin state and then request GPIO 14 to be +used. If you're using the subsystems orthogonally like this, you should +nominally always get your pinctrl handle and select the desired pinctrl +state BEFORE requesting the GPIO. This is a semantic convention to avoid +situations that can be electrically unpleasant, you will certainly want to +mux in and bias pins in a certain way before the GPIO subsystems starts to +deal with them. + +The above can be hidden: using the device core, the pinctrl core may be +setting up the config and muxing for the pins right before the device is +probing, nevertheless orthogonal to the GPIO subsystem. + +But there are also situations where it makes sense for the GPIO subsystem +to communicate directly with the pinctrl subsystem, using the latter as a +back-end. This is when the GPIO driver may call out to the functions +described in the section "Pin control interaction with the GPIO subsystem" +above. This only involves per-pin multiplexing, and will be completely +hidden behind the gpio_*() function namespace. In this case, the driver +need not interact with the pin control subsystem at all. + +If a pin control driver and a GPIO driver is dealing with the same pins +and the use cases involve multiplexing, you MUST implement the pin controller +as a back-end for the GPIO driver like this, unless your hardware design +is such that the GPIO controller can override the pin controller's +multiplexing state through hardware without the need to interact with the +pin control system. + + +System pin control hogging +========================== + +Pin control map entries can be hogged by the core when the pin controller +is registered. This means that the core will attempt to call pinctrl_get(), +lookup_state() and select_state() on it immediately after the pin control +device has been registered. + +This occurs for mapping table entries where the client device name is equal +to the pin controller device name, and the state name is PINCTRL_STATE_DEFAULT:: + + { + .dev_name = "pinctrl-foo", + .name = PINCTRL_STATE_DEFAULT, + .type = PIN_MAP_TYPE_MUX_GROUP, + .ctrl_dev_name = "pinctrl-foo", + .function = "power_func", + }, + +Since it may be common to request the core to hog a few always-applicable +mux settings on the primary pin controller, there is a convenience macro for +this:: + + PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-foo", NULL /* group */, + "power_func") + +This gives the exact same result as the above construction. + + +Runtime pinmuxing +================= + +It is possible to mux a certain function in and out at runtime, say to move +an SPI port from one set of pins to another set of pins. Say for example for +spi0 in the example above, we expose two different groups of pins for the same +function, but with different named in the mapping as described under +"Advanced mapping" above. So that for an SPI device, we have two states named +"pos-A" and "pos-B". + +This snippet first initializes a state object for both groups (in foo_probe()), +then muxes the function in the pins defined by group A, and finally muxes it in +on the pins defined by group B:: + + #include + + struct pinctrl *p; + struct pinctrl_state *s1, *s2; + + foo_probe() + { + /* Setup */ + p = devm_pinctrl_get(&device); + if (IS_ERR(p)) + ... + + s1 = pinctrl_lookup_state(foo->p, "pos-A"); + if (IS_ERR(s1)) + ... + + s2 = pinctrl_lookup_state(foo->p, "pos-B"); + if (IS_ERR(s2)) + ... + } + + foo_switch() + { + /* Enable on position A */ + ret = pinctrl_select_state(s1); + if (ret < 0) + ... + + ... + + /* Enable on position B */ + ret = pinctrl_select_state(s2); + if (ret < 0) + ... + + ... + } + +The above has to be done from process context. The reservation of the pins +will be done when the state is activated, so in effect one specific pin +can be used by different functions at different times on a running system. diff --git a/Documentation/driver-api/pinctl.rst b/Documentation/driver-api/pinctl.rst deleted file mode 100644 index 3d2deaf48841..000000000000 --- a/Documentation/driver-api/pinctl.rst +++ /dev/null @@ -1,1430 +0,0 @@ -=============================== -PINCTRL (PIN CONTROL) subsystem -=============================== - -This document outlines the pin control subsystem in Linux - -This subsystem deals with: - -- Enumerating and naming controllable pins - -- Multiplexing of pins, pads, fingers (etc) see below for details - -- Configuration of pins, pads, fingers (etc), such as software-controlled - biasing and driving mode specific pins, such as pull-up/down, open drain, - load capacitance etc. - -Top-level interface -=================== - -Definition of PIN CONTROLLER: - -- A pin controller is a piece of hardware, usually a set of registers, that - can control PINs. It may be able to multiplex, bias, set load capacitance, - set drive strength, etc. for individual pins or groups of pins. - -Definition of PIN: - -- PINS are equal to pads, fingers, balls or whatever packaging input or - output line you want to control and these are denoted by unsigned integers - in the range 0..maxpin. This numberspace is local to each PIN CONTROLLER, so - there may be several such number spaces in a system. This pin space may - be sparse - i.e. there may be gaps in the space with numbers where no - pin exists. - -When a PIN CONTROLLER is instantiated, it will register a descriptor to the -pin control framework, and this descriptor contains an array of pin descriptors -describing the pins handled by this specific pin controller. - -Here is an example of a PGA (Pin Grid Array) chip seen from underneath:: - - A B C D E F G H - - 8 o o o o o o o o - - 7 o o o o o o o o - - 6 o o o o o o o o - - 5 o o o o o o o o - - 4 o o o o o o o o - - 3 o o o o o o o o - - 2 o o o o o o o o - - 1 o o o o o o o o - -To register a pin controller and name all the pins on this package we can do -this in our driver:: - - #include - - const struct pinctrl_pin_desc foo_pins[] = { - PINCTRL_PIN(0, "A8"), - PINCTRL_PIN(1, "B8"), - PINCTRL_PIN(2, "C8"), - ... - PINCTRL_PIN(61, "F1"), - PINCTRL_PIN(62, "G1"), - PINCTRL_PIN(63, "H1"), - }; - - static struct pinctrl_desc foo_desc = { - .name = "foo", - .pins = foo_pins, - .npins = ARRAY_SIZE(foo_pins), - .owner = THIS_MODULE, - }; - - int __init foo_probe(void) - { - int error; - - struct pinctrl_dev *pctl; - - error = pinctrl_register_and_init(&foo_desc, , - NULL, &pctl); - if (error) - return error; - - return pinctrl_enable(pctl); - } - -To enable the pinctrl subsystem and the subgroups for PINMUX and PINCONF and -selected drivers, you need to select them from your machine's Kconfig entry, -since these are so tightly integrated with the machines they are used on. -See for example arch/arm/mach-u300/Kconfig for an example. - -Pins usually have fancier names than this. You can find these in the datasheet -for your chip. Notice that the core pinctrl.h file provides a fancy macro -called PINCTRL_PIN() to create the struct entries. As you can see I enumerated -the pins from 0 in the upper left corner to 63 in the lower right corner. -This enumeration was arbitrarily chosen, in practice you need to think -through your numbering system so that it matches the layout of registers -and such things in your driver, or the code may become complicated. You must -also consider matching of offsets to the GPIO ranges that may be handled by -the pin controller. - -For a padring with 467 pads, as opposed to actual pins, I used an enumeration -like this, walking around the edge of the chip, which seems to be industry -standard too (all these pads had names, too):: - - - 0 ..... 104 - 466 105 - . . - . . - 358 224 - 357 .... 225 - - -Pin groups -========== - -Many controllers need to deal with groups of pins, so the pin controller -subsystem has a mechanism for enumerating groups of pins and retrieving the -actual enumerated pins that are part of a certain group. - -For example, say that we have a group of pins dealing with an SPI interface -on { 0, 8, 16, 24 }, and a group of pins dealing with an I2C interface on pins -on { 24, 25 }. - -These two groups are presented to the pin control subsystem by implementing -some generic pinctrl_ops like this:: - - #include - - struct foo_group { - const char *name; - const unsigned int *pins; - const unsigned num_pins; - }; - - static const unsigned int spi0_pins[] = { 0, 8, 16, 24 }; - static const unsigned int i2c0_pins[] = { 24, 25 }; - - static const struct foo_group foo_groups[] = { - { - .name = "spi0_grp", - .pins = spi0_pins, - .num_pins = ARRAY_SIZE(spi0_pins), - }, - { - .name = "i2c0_grp", - .pins = i2c0_pins, - .num_pins = ARRAY_SIZE(i2c0_pins), - }, - }; - - - static int foo_get_groups_count(struct pinctrl_dev *pctldev) - { - return ARRAY_SIZE(foo_groups); - } - - static const char *foo_get_group_name(struct pinctrl_dev *pctldev, - unsigned selector) - { - return foo_groups[selector].name; - } - - static int foo_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, - const unsigned **pins, - unsigned *num_pins) - { - *pins = (unsigned *) foo_groups[selector].pins; - *num_pins = foo_groups[selector].num_pins; - return 0; - } - - static struct pinctrl_ops foo_pctrl_ops = { - .get_groups_count = foo_get_groups_count, - .get_group_name = foo_get_group_name, - .get_group_pins = foo_get_group_pins, - }; - - - static struct pinctrl_desc foo_desc = { - ... - .pctlops = &foo_pctrl_ops, - }; - -The pin control subsystem will call the .get_groups_count() function to -determine the total number of legal selectors, then it will call the other functions -to retrieve the name and pins of the group. Maintaining the data structure of -the groups is up to the driver, this is just a simple example - in practice you -may need more entries in your group structure, for example specific register -ranges associated with each group and so on. - - -Pin configuration -================= - -Pins can sometimes be software-configured in various ways, mostly related -to their electronic properties when used as inputs or outputs. For example you -may be able to make an output pin high impedance, or "tristate" meaning it is -effectively disconnected. You may be able to connect an input pin to VDD or GND -using a certain resistor value - pull up and pull down - so that the pin has a -stable value when nothing is driving the rail it is connected to, or when it's -unconnected. - -Pin configuration can be programmed by adding configuration entries into the -mapping table; see section "Board/machine configuration" below. - -The format and meaning of the configuration parameter, PLATFORM_X_PULL_UP -above, is entirely defined by the pin controller driver. - -The pin configuration driver implements callbacks for changing pin -configuration in the pin controller ops like this:: - - #include - #include - #include "platform_x_pindefs.h" - - static int foo_pin_config_get(struct pinctrl_dev *pctldev, - unsigned offset, - unsigned long *config) - { - struct my_conftype conf; - - ... Find setting for pin @ offset ... - - *config = (unsigned long) conf; - } - - static int foo_pin_config_set(struct pinctrl_dev *pctldev, - unsigned offset, - unsigned long config) - { - struct my_conftype *conf = (struct my_conftype *) config; - - switch (conf) { - case PLATFORM_X_PULL_UP: - ... - } - } - } - - static int foo_pin_config_group_get (struct pinctrl_dev *pctldev, - unsigned selector, - unsigned long *config) - { - ... - } - - static int foo_pin_config_group_set (struct pinctrl_dev *pctldev, - unsigned selector, - unsigned long config) - { - ... - } - - static struct pinconf_ops foo_pconf_ops = { - .pin_config_get = foo_pin_config_get, - .pin_config_set = foo_pin_config_set, - .pin_config_group_get = foo_pin_config_group_get, - .pin_config_group_set = foo_pin_config_group_set, - }; - - /* Pin config operations are handled by some pin controller */ - static struct pinctrl_desc foo_desc = { - ... - .confops = &foo_pconf_ops, - }; - -Interaction with the GPIO subsystem -=================================== - -The GPIO drivers may want to perform operations of various types on the same -physical pins that are also registered as pin controller pins. - -First and foremost, the two subsystems can be used as completely orthogonal, -see the section named "pin control requests from drivers" and -"drivers needing both pin control and GPIOs" below for details. But in some -situations a cross-subsystem mapping between pins and GPIOs is needed. - -Since the pin controller subsystem has its pinspace local to the pin controller -we need a mapping so that the pin control subsystem can figure out which pin -controller handles control of a certain GPIO pin. Since a single pin controller -may be muxing several GPIO ranges (typically SoCs that have one set of pins, -but internally several GPIO silicon blocks, each modelled as a struct -gpio_chip) any number of GPIO ranges can be added to a pin controller instance -like this:: - - struct gpio_chip chip_a; - struct gpio_chip chip_b; - - static struct pinctrl_gpio_range gpio_range_a = { - .name = "chip a", - .id = 0, - .base = 32, - .pin_base = 32, - .npins = 16, - .gc = &chip_a; - }; - - static struct pinctrl_gpio_range gpio_range_b = { - .name = "chip b", - .id = 0, - .base = 48, - .pin_base = 64, - .npins = 8, - .gc = &chip_b; - }; - - { - struct pinctrl_dev *pctl; - ... - pinctrl_add_gpio_range(pctl, &gpio_range_a); - pinctrl_add_gpio_range(pctl, &gpio_range_b); - } - -So this complex system has one pin controller handling two different -GPIO chips. "chip a" has 16 pins and "chip b" has 8 pins. The "chip a" and -"chip b" have different .pin_base, which means a start pin number of the -GPIO range. - -The GPIO range of "chip a" starts from the GPIO base of 32 and actual -pin range also starts from 32. However "chip b" has different starting -offset for the GPIO range and pin range. The GPIO range of "chip b" starts -from GPIO number 48, while the pin range of "chip b" starts from 64. - -We can convert a gpio number to actual pin number using this "pin_base". -They are mapped in the global GPIO pin space at: - -chip a: - - GPIO range : [32 .. 47] - - pin range : [32 .. 47] -chip b: - - GPIO range : [48 .. 55] - - pin range : [64 .. 71] - -The above examples assume the mapping between the GPIOs and pins is -linear. If the mapping is sparse or haphazard, an array of arbitrary pin -numbers can be encoded in the range like this:: - - static const unsigned range_pins[] = { 14, 1, 22, 17, 10, 8, 6, 2 }; - - static struct pinctrl_gpio_range gpio_range = { - .name = "chip", - .id = 0, - .base = 32, - .pins = &range_pins, - .npins = ARRAY_SIZE(range_pins), - .gc = &chip; - }; - -In this case the pin_base property will be ignored. If the name of a pin -group is known, the pins and npins elements of the above structure can be -initialised using the function pinctrl_get_group_pins(), e.g. for pin -group "foo":: - - pinctrl_get_group_pins(pctl, "foo", &gpio_range.pins, - &gpio_range.npins); - -When GPIO-specific functions in the pin control subsystem are called, these -ranges will be used to look up the appropriate pin controller by inspecting -and matching the pin to the pin ranges across all controllers. When a -pin controller handling the matching range is found, GPIO-specific functions -will be called on that specific pin controller. - -For all functionalities dealing with pin biasing, pin muxing etc, the pin -controller subsystem will look up the corresponding pin number from the passed -in gpio number, and use the range's internals to retrieve a pin number. After -that, the subsystem passes it on to the pin control driver, so the driver -will get a pin number into its handled number range. Further it is also passed -the range ID value, so that the pin controller knows which range it should -deal with. - -Calling pinctrl_add_gpio_range from pinctrl driver is DEPRECATED. Please see -section 2.1 of Documentation/devicetree/bindings/gpio/gpio.txt on how to bind -pinctrl and gpio drivers. - - -PINMUX interfaces -================= - -These calls use the pinmux_* naming prefix. No other calls should use that -prefix. - - -What is pinmuxing? -================== - -PINMUX, also known as padmux, ballmux, alternate functions or mission modes -is a way for chip vendors producing some kind of electrical packages to use -a certain physical pin (ball, pad, finger, etc) for multiple mutually exclusive -functions, depending on the application. By "application" in this context -we usually mean a way of soldering or wiring the package into an electronic -system, even though the framework makes it possible to also change the function -at runtime. - -Here is an example of a PGA (Pin Grid Array) chip seen from underneath:: - - A B C D E F G H - +---+ - 8 | o | o o o o o o o - | | - 7 | o | o o o o o o o - | | - 6 | o | o o o o o o o - +---+---+ - 5 | o | o | o o o o o o - +---+---+ +---+ - 4 o o o o o o | o | o - | | - 3 o o o o o o | o | o - | | - 2 o o o o o o | o | o - +-------+-------+-------+---+---+ - 1 | o o | o o | o o | o | o | - +-------+-------+-------+---+---+ - -This is not tetris. The game to think of is chess. Not all PGA/BGA packages -are chessboard-like, big ones have "holes" in some arrangement according to -different design patterns, but we're using this as a simple example. Of the -pins you see some will be taken by things like a few VCC and GND to feed power -to the chip, and quite a few will be taken by large ports like an external -memory interface. The remaining pins will often be subject to pin multiplexing. - -The example 8x8 PGA package above will have pin numbers 0 through 63 assigned -to its physical pins. It will name the pins { A1, A2, A3 ... H6, H7, H8 } using -pinctrl_register_pins() and a suitable data set as shown earlier. - -In this 8x8 BGA package the pins { A8, A7, A6, A5 } can be used as an SPI port -(these are four pins: CLK, RXD, TXD, FRM). In that case, pin B5 can be used as -some general-purpose GPIO pin. However, in another setting, pins { A5, B5 } can -be used as an I2C port (these are just two pins: SCL, SDA). Needless to say, -we cannot use the SPI port and I2C port at the same time. However in the inside -of the package the silicon performing the SPI logic can alternatively be routed -out on pins { G4, G3, G2, G1 }. - -On the bottom row at { A1, B1, C1, D1, E1, F1, G1, H1 } we have something -special - it's an external MMC bus that can be 2, 4 or 8 bits wide, and it will -consume 2, 4 or 8 pins respectively, so either { A1, B1 } are taken or -{ A1, B1, C1, D1 } or all of them. If we use all 8 bits, we cannot use the SPI -port on pins { G4, G3, G2, G1 } of course. - -This way the silicon blocks present inside the chip can be multiplexed "muxed" -out on different pin ranges. Often contemporary SoC (systems on chip) will -contain several I2C, SPI, SDIO/MMC, etc silicon blocks that can be routed to -different pins by pinmux settings. - -Since general-purpose I/O pins (GPIO) are typically always in shortage, it is -common to be able to use almost any pin as a GPIO pin if it is not currently -in use by some other I/O port. - - -Pinmux conventions -================== - -The purpose of the pinmux functionality in the pin controller subsystem is to -abstract and provide pinmux settings to the devices you choose to instantiate -in your machine configuration. It is inspired by the clk, GPIO and regulator -subsystems, so devices will request their mux setting, but it's also possible -to request a single pin for e.g. GPIO. - -Definitions: - -- FUNCTIONS can be switched in and out by a driver residing with the pin - control subsystem in the drivers/pinctrl/* directory of the kernel. The - pin control driver knows the possible functions. In the example above you can - identify three pinmux functions, one for spi, one for i2c and one for mmc. - -- FUNCTIONS are assumed to be enumerable from zero in a one-dimensional array. - In this case the array could be something like: { spi0, i2c0, mmc0 } - for the three available functions. - -- FUNCTIONS have PIN GROUPS as defined on the generic level - so a certain - function is *always* associated with a certain set of pin groups, could - be just a single one, but could also be many. In the example above the - function i2c is associated with the pins { A5, B5 }, enumerated as - { 24, 25 } in the controller pin space. - - The Function spi is associated with pin groups { A8, A7, A6, A5 } - and { G4, G3, G2, G1 }, which are enumerated as { 0, 8, 16, 24 } and - { 38, 46, 54, 62 } respectively. - - Group names must be unique per pin controller, no two groups on the same - controller may have the same name. - -- The combination of a FUNCTION and a PIN GROUP determine a certain function - for a certain set of pins. The knowledge of the functions and pin groups - and their machine-specific particulars are kept inside the pinmux driver, - from the outside only the enumerators are known, and the driver core can - request: - - - The name of a function with a certain selector (>= 0) - - A list of groups associated with a certain function - - That a certain group in that list to be activated for a certain function - - As already described above, pin groups are in turn self-descriptive, so - the core will retrieve the actual pin range in a certain group from the - driver. - -- FUNCTIONS and GROUPS on a certain PIN CONTROLLER are MAPPED to a certain - device by the board file, device tree or similar machine setup configuration - mechanism, similar to how regulators are connected to devices, usually by - name. Defining a pin controller, function and group thus uniquely identify - the set of pins to be used by a certain device. (If only one possible group - of pins is available for the function, no group name need to be supplied - - the core will simply select the first and only group available.) - - In the example case we can define that this particular machine shall - use device spi0 with pinmux function fspi0 group gspi0 and i2c0 on function - fi2c0 group gi2c0, on the primary pin controller, we get mappings - like these:: - - { - {"map-spi0", spi0, pinctrl0, fspi0, gspi0}, - {"map-i2c0", i2c0, pinctrl0, fi2c0, gi2c0} - } - - Every map must be assigned a state name, pin controller, device and - function. The group is not compulsory - if it is omitted the first group - presented by the driver as applicable for the function will be selected, - which is useful for simple cases. - - It is possible to map several groups to the same combination of device, - pin controller and function. This is for cases where a certain function on - a certain pin controller may use different sets of pins in different - configurations. - -- PINS for a certain FUNCTION using a certain PIN GROUP on a certain - PIN CONTROLLER are provided on a first-come first-serve basis, so if some - other device mux setting or GPIO pin request has already taken your physical - pin, you will be denied the use of it. To get (activate) a new setting, the - old one has to be put (deactivated) first. - -Sometimes the documentation and hardware registers will be oriented around -pads (or "fingers") rather than pins - these are the soldering surfaces on the -silicon inside the package, and may or may not match the actual number of -pins/balls underneath the capsule. Pick some enumeration that makes sense to -you. Define enumerators only for the pins you can control if that makes sense. - -Assumptions: - -We assume that the number of possible function maps to pin groups is limited by -the hardware. I.e. we assume that there is no system where any function can be -mapped to any pin, like in a phone exchange. So the available pin groups for -a certain function will be limited to a few choices (say up to eight or so), -not hundreds or any amount of choices. This is the characteristic we have found -by inspecting available pinmux hardware, and a necessary assumption since we -expect pinmux drivers to present *all* possible function vs pin group mappings -to the subsystem. - - -Pinmux drivers -============== - -The pinmux core takes care of preventing conflicts on pins and calling -the pin controller driver to execute different settings. - -It is the responsibility of the pinmux driver to impose further restrictions -(say for example infer electronic limitations due to load, etc.) to determine -whether or not the requested function can actually be allowed, and in case it -is possible to perform the requested mux setting, poke the hardware so that -this happens. - -Pinmux drivers are required to supply a few callback functions, some are -optional. Usually the set_mux() function is implemented, writing values into -some certain registers to activate a certain mux setting for a certain pin. - -A simple driver for the above example will work by setting bits 0, 1, 2, 3 or 4 -into some register named MUX to select a certain function with a certain -group of pins would work something like this:: - - #include - #include - - struct foo_group { - const char *name; - const unsigned int *pins; - const unsigned num_pins; - }; - - static const unsigned spi0_0_pins[] = { 0, 8, 16, 24 }; - static const unsigned spi0_1_pins[] = { 38, 46, 54, 62 }; - static const unsigned i2c0_pins[] = { 24, 25 }; - static const unsigned mmc0_1_pins[] = { 56, 57 }; - static const unsigned mmc0_2_pins[] = { 58, 59 }; - static const unsigned mmc0_3_pins[] = { 60, 61, 62, 63 }; - - static const struct foo_group foo_groups[] = { - { - .name = "spi0_0_grp", - .pins = spi0_0_pins, - .num_pins = ARRAY_SIZE(spi0_0_pins), - }, - { - .name = "spi0_1_grp", - .pins = spi0_1_pins, - .num_pins = ARRAY_SIZE(spi0_1_pins), - }, - { - .name = "i2c0_grp", - .pins = i2c0_pins, - .num_pins = ARRAY_SIZE(i2c0_pins), - }, - { - .name = "mmc0_1_grp", - .pins = mmc0_1_pins, - .num_pins = ARRAY_SIZE(mmc0_1_pins), - }, - { - .name = "mmc0_2_grp", - .pins = mmc0_2_pins, - .num_pins = ARRAY_SIZE(mmc0_2_pins), - }, - { - .name = "mmc0_3_grp", - .pins = mmc0_3_pins, - .num_pins = ARRAY_SIZE(mmc0_3_pins), - }, - }; - - - static int foo_get_groups_count(struct pinctrl_dev *pctldev) - { - return ARRAY_SIZE(foo_groups); - } - - static const char *foo_get_group_name(struct pinctrl_dev *pctldev, - unsigned selector) - { - return foo_groups[selector].name; - } - - static int foo_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, - const unsigned ** pins, - unsigned * num_pins) - { - *pins = (unsigned *) foo_groups[selector].pins; - *num_pins = foo_groups[selector].num_pins; - return 0; - } - - static struct pinctrl_ops foo_pctrl_ops = { - .get_groups_count = foo_get_groups_count, - .get_group_name = foo_get_group_name, - .get_group_pins = foo_get_group_pins, - }; - - struct foo_pmx_func { - const char *name; - const char * const *groups; - const unsigned num_groups; - }; - - static const char * const spi0_groups[] = { "spi0_0_grp", "spi0_1_grp" }; - static const char * const i2c0_groups[] = { "i2c0_grp" }; - static const char * const mmc0_groups[] = { "mmc0_1_grp", "mmc0_2_grp", - "mmc0_3_grp" }; - - static const struct foo_pmx_func foo_functions[] = { - { - .name = "spi0", - .groups = spi0_groups, - .num_groups = ARRAY_SIZE(spi0_groups), - }, - { - .name = "i2c0", - .groups = i2c0_groups, - .num_groups = ARRAY_SIZE(i2c0_groups), - }, - { - .name = "mmc0", - .groups = mmc0_groups, - .num_groups = ARRAY_SIZE(mmc0_groups), - }, - }; - - static int foo_get_functions_count(struct pinctrl_dev *pctldev) - { - return ARRAY_SIZE(foo_functions); - } - - static const char *foo_get_fname(struct pinctrl_dev *pctldev, unsigned selector) - { - return foo_functions[selector].name; - } - - static int foo_get_groups(struct pinctrl_dev *pctldev, unsigned selector, - const char * const **groups, - unsigned * const num_groups) - { - *groups = foo_functions[selector].groups; - *num_groups = foo_functions[selector].num_groups; - return 0; - } - - static int foo_set_mux(struct pinctrl_dev *pctldev, unsigned selector, - unsigned group) - { - u8 regbit = (1 << selector + group); - - writeb((readb(MUX)|regbit), MUX); - return 0; - } - - static struct pinmux_ops foo_pmxops = { - .get_functions_count = foo_get_functions_count, - .get_function_name = foo_get_fname, - .get_function_groups = foo_get_groups, - .set_mux = foo_set_mux, - .strict = true, - }; - - /* Pinmux operations are handled by some pin controller */ - static struct pinctrl_desc foo_desc = { - ... - .pctlops = &foo_pctrl_ops, - .pmxops = &foo_pmxops, - }; - -In the example activating muxing 0 and 1 at the same time setting bits -0 and 1, uses one pin in common so they would collide. - -The beauty of the pinmux subsystem is that since it keeps track of all -pins and who is using them, it will already have denied an impossible -request like that, so the driver does not need to worry about such -things - when it gets a selector passed in, the pinmux subsystem makes -sure no other device or GPIO assignment is already using the selected -pins. Thus bits 0 and 1 in the control register will never be set at the -same time. - -All the above functions are mandatory to implement for a pinmux driver. - - -Pin control interaction with the GPIO subsystem -=============================================== - -Note that the following implies that the use case is to use a certain pin -from the Linux kernel using the API in with gpio_request() -and similar functions. There are cases where you may be using something -that your datasheet calls "GPIO mode", but actually is just an electrical -configuration for a certain device. See the section below named -"GPIO mode pitfalls" for more details on this scenario. - -The public pinmux API contains two functions named pinctrl_gpio_request() -and pinctrl_gpio_free(). These two functions shall *ONLY* be called from -gpiolib-based drivers as part of their gpio_request() and -gpio_free() semantics. Likewise the pinctrl_gpio_direction_[input|output] -shall only be called from within respective gpio_direction_[input|output] -gpiolib implementation. - -NOTE that platforms and individual drivers shall *NOT* request GPIO pins to be -controlled e.g. muxed in. Instead, implement a proper gpiolib driver and have -that driver request proper muxing and other control for its pins. - -The function list could become long, especially if you can convert every -individual pin into a GPIO pin independent of any other pins, and then try -the approach to define every pin as a function. - -In this case, the function array would become 64 entries for each GPIO -setting and then the device functions. - -For this reason there are two functions a pin control driver can implement -to enable only GPIO on an individual pin: .gpio_request_enable() and -.gpio_disable_free(). - -This function will pass in the affected GPIO range identified by the pin -controller core, so you know which GPIO pins are being affected by the request -operation. - -If your driver needs to have an indication from the framework of whether the -GPIO pin shall be used for input or output you can implement the -.gpio_set_direction() function. As described this shall be called from the -gpiolib driver and the affected GPIO range, pin offset and desired direction -will be passed along to this function. - -Alternatively to using these special functions, it is fully allowed to use -named functions for each GPIO pin, the pinctrl_gpio_request() will attempt to -obtain the function "gpioN" where "N" is the global GPIO pin number if no -special GPIO-handler is registered. - - -GPIO mode pitfalls -================== - -Due to the naming conventions used by hardware engineers, where "GPIO" -is taken to mean different things than what the kernel does, the developer -may be confused by a datasheet talking about a pin being possible to set -into "GPIO mode". It appears that what hardware engineers mean with -"GPIO mode" is not necessarily the use case that is implied in the kernel -interface : a pin that you grab from kernel code and then -either listen for input or drive high/low to assert/deassert some -external line. - -Rather hardware engineers think that "GPIO mode" means that you can -software-control a few electrical properties of the pin that you would -not be able to control if the pin was in some other mode, such as muxed in -for a device. - -The GPIO portions of a pin and its relation to a certain pin controller -configuration and muxing logic can be constructed in several ways. Here -are two examples:: - - (A) - pin config - logic regs - | +- SPI - Physical pins --- pad --- pinmux -+- I2C - | +- mmc - | +- GPIO - pin - multiplex - logic regs - -Here some electrical properties of the pin can be configured no matter -whether the pin is used for GPIO or not. If you multiplex a GPIO onto a -pin, you can also drive it high/low from "GPIO" registers. -Alternatively, the pin can be controlled by a certain peripheral, while -still applying desired pin config properties. GPIO functionality is thus -orthogonal to any other device using the pin. - -In this arrangement the registers for the GPIO portions of the pin controller, -or the registers for the GPIO hardware module are likely to reside in a -separate memory range only intended for GPIO driving, and the register -range dealing with pin config and pin multiplexing get placed into a -different memory range and a separate section of the data sheet. - -A flag "strict" in struct pinmux_ops is available to check and deny -simultaneous access to the same pin from GPIO and pin multiplexing -consumers on hardware of this type. The pinctrl driver should set this flag -accordingly. - -:: - - (B) - - pin config - logic regs - | +- SPI - Physical pins --- pad --- pinmux -+- I2C - | | +- mmc - | | - GPIO pin - multiplex - logic regs - -In this arrangement, the GPIO functionality can always be enabled, such that -e.g. a GPIO input can be used to "spy" on the SPI/I2C/MMC signal while it is -pulsed out. It is likely possible to disrupt the traffic on the pin by doing -wrong things on the GPIO block, as it is never really disconnected. It is -possible that the GPIO, pin config and pin multiplex registers are placed into -the same memory range and the same section of the data sheet, although that -need not be the case. - -In some pin controllers, although the physical pins are designed in the same -way as (B), the GPIO function still can't be enabled at the same time as the -peripheral functions. So again the "strict" flag should be set, denying -simultaneous activation by GPIO and other muxed in devices. - -From a kernel point of view, however, these are different aspects of the -hardware and shall be put into different subsystems: - -- Registers (or fields within registers) that control electrical - properties of the pin such as biasing and drive strength should be - exposed through the pinctrl subsystem, as "pin configuration" settings. - -- Registers (or fields within registers) that control muxing of signals - from various other HW blocks (e.g. I2C, MMC, or GPIO) onto pins should - be exposed through the pinctrl subsystem, as mux functions. - -- Registers (or fields within registers) that control GPIO functionality - such as setting a GPIO's output value, reading a GPIO's input value, or - setting GPIO pin direction should be exposed through the GPIO subsystem, - and if they also support interrupt capabilities, through the irqchip - abstraction. - -Depending on the exact HW register design, some functions exposed by the -GPIO subsystem may call into the pinctrl subsystem in order to -co-ordinate register settings across HW modules. In particular, this may -be needed for HW with separate GPIO and pin controller HW modules, where -e.g. GPIO direction is determined by a register in the pin controller HW -module rather than the GPIO HW module. - -Electrical properties of the pin such as biasing and drive strength -may be placed at some pin-specific register in all cases or as part -of the GPIO register in case (B) especially. This doesn't mean that such -properties necessarily pertain to what the Linux kernel calls "GPIO". - -Example: a pin is usually muxed in to be used as a UART TX line. But during -system sleep, we need to put this pin into "GPIO mode" and ground it. - -If you make a 1-to-1 map to the GPIO subsystem for this pin, you may start -to think that you need to come up with something really complex, that the -pin shall be used for UART TX and GPIO at the same time, that you will grab -a pin control handle and set it to a certain state to enable UART TX to be -muxed in, then twist it over to GPIO mode and use gpio_direction_output() -to drive it low during sleep, then mux it over to UART TX again when you -wake up and maybe even gpio_request/gpio_free as part of this cycle. This -all gets very complicated. - -The solution is to not think that what the datasheet calls "GPIO mode" -has to be handled by the interface. Instead view this as -a certain pin config setting. Look in e.g. -and you find this in the documentation: - - PIN_CONFIG_OUTPUT: - this will configure the pin in output, use argument - 1 to indicate high level, argument 0 to indicate low level. - -So it is perfectly possible to push a pin into "GPIO mode" and drive the -line low as part of the usual pin control map. So for example your UART -driver may look like this:: - - #include - - struct pinctrl *pinctrl; - struct pinctrl_state *pins_default; - struct pinctrl_state *pins_sleep; - - pins_default = pinctrl_lookup_state(uap->pinctrl, PINCTRL_STATE_DEFAULT); - pins_sleep = pinctrl_lookup_state(uap->pinctrl, PINCTRL_STATE_SLEEP); - - /* Normal mode */ - retval = pinctrl_select_state(pinctrl, pins_default); - /* Sleep mode */ - retval = pinctrl_select_state(pinctrl, pins_sleep); - -And your machine configuration may look like this: --------------------------------------------------- - -:: - - static unsigned long uart_default_mode[] = { - PIN_CONF_PACKED(PIN_CONFIG_DRIVE_PUSH_PULL, 0), - }; - - static unsigned long uart_sleep_mode[] = { - PIN_CONF_PACKED(PIN_CONFIG_OUTPUT, 0), - }; - - static struct pinctrl_map pinmap[] __initdata = { - PIN_MAP_MUX_GROUP("uart", PINCTRL_STATE_DEFAULT, "pinctrl-foo", - "u0_group", "u0"), - PIN_MAP_CONFIGS_PIN("uart", PINCTRL_STATE_DEFAULT, "pinctrl-foo", - "UART_TX_PIN", uart_default_mode), - PIN_MAP_MUX_GROUP("uart", PINCTRL_STATE_SLEEP, "pinctrl-foo", - "u0_group", "gpio-mode"), - PIN_MAP_CONFIGS_PIN("uart", PINCTRL_STATE_SLEEP, "pinctrl-foo", - "UART_TX_PIN", uart_sleep_mode), - }; - - foo_init(void) { - pinctrl_register_mappings(pinmap, ARRAY_SIZE(pinmap)); - } - -Here the pins we want to control are in the "u0_group" and there is some -function called "u0" that can be enabled on this group of pins, and then -everything is UART business as usual. But there is also some function -named "gpio-mode" that can be mapped onto the same pins to move them into -GPIO mode. - -This will give the desired effect without any bogus interaction with the -GPIO subsystem. It is just an electrical configuration used by that device -when going to sleep, it might imply that the pin is set into something the -datasheet calls "GPIO mode", but that is not the point: it is still used -by that UART device to control the pins that pertain to that very UART -driver, putting them into modes needed by the UART. GPIO in the Linux -kernel sense are just some 1-bit line, and is a different use case. - -How the registers are poked to attain the push or pull, and output low -configuration and the muxing of the "u0" or "gpio-mode" group onto these -pins is a question for the driver. - -Some datasheets will be more helpful and refer to the "GPIO mode" as -"low power mode" rather than anything to do with GPIO. This often means -the same thing electrically speaking, but in this latter case the -software engineers will usually quickly identify that this is some -specific muxing or configuration rather than anything related to the GPIO -API. - - -Board/machine configuration -=========================== - -Boards and machines define how a certain complete running system is put -together, including how GPIOs and devices are muxed, how regulators are -constrained and how the clock tree looks. Of course pinmux settings are also -part of this. - -A pin controller configuration for a machine looks pretty much like a simple -regulator configuration, so for the example array above we want to enable i2c -and spi on the second function mapping:: - - #include - - static const struct pinctrl_map mapping[] __initconst = { - { - .dev_name = "foo-spi.0", - .name = PINCTRL_STATE_DEFAULT, - .type = PIN_MAP_TYPE_MUX_GROUP, - .ctrl_dev_name = "pinctrl-foo", - .data.mux.function = "spi0", - }, - { - .dev_name = "foo-i2c.0", - .name = PINCTRL_STATE_DEFAULT, - .type = PIN_MAP_TYPE_MUX_GROUP, - .ctrl_dev_name = "pinctrl-foo", - .data.mux.function = "i2c0", - }, - { - .dev_name = "foo-mmc.0", - .name = PINCTRL_STATE_DEFAULT, - .type = PIN_MAP_TYPE_MUX_GROUP, - .ctrl_dev_name = "pinctrl-foo", - .data.mux.function = "mmc0", - }, - }; - -The dev_name here matches to the unique device name that can be used to look -up the device struct (just like with clockdev or regulators). The function name -must match a function provided by the pinmux driver handling this pin range. - -As you can see we may have several pin controllers on the system and thus -we need to specify which one of them contains the functions we wish to map. - -You register this pinmux mapping to the pinmux subsystem by simply:: - - ret = pinctrl_register_mappings(mapping, ARRAY_SIZE(mapping)); - -Since the above construct is pretty common there is a helper macro to make -it even more compact which assumes you want to use pinctrl-foo and position -0 for mapping, for example:: - - static struct pinctrl_map mapping[] __initdata = { - PIN_MAP_MUX_GROUP("foo-i2c.o", PINCTRL_STATE_DEFAULT, - "pinctrl-foo", NULL, "i2c0"), - }; - -The mapping table may also contain pin configuration entries. It's common for -each pin/group to have a number of configuration entries that affect it, so -the table entries for configuration reference an array of config parameters -and values. An example using the convenience macros is shown below:: - - static unsigned long i2c_grp_configs[] = { - FOO_PIN_DRIVEN, - FOO_PIN_PULLUP, - }; - - static unsigned long i2c_pin_configs[] = { - FOO_OPEN_COLLECTOR, - FOO_SLEW_RATE_SLOW, - }; - - static struct pinctrl_map mapping[] __initdata = { - PIN_MAP_MUX_GROUP("foo-i2c.0", PINCTRL_STATE_DEFAULT, - "pinctrl-foo", "i2c0", "i2c0"), - PIN_MAP_CONFIGS_GROUP("foo-i2c.0", PINCTRL_STATE_DEFAULT, - "pinctrl-foo", "i2c0", i2c_grp_configs), - PIN_MAP_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, - "pinctrl-foo", "i2c0scl", i2c_pin_configs), - PIN_MAP_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, - "pinctrl-foo", "i2c0sda", i2c_pin_configs), - }; - -Finally, some devices expect the mapping table to contain certain specific -named states. When running on hardware that doesn't need any pin controller -configuration, the mapping table must still contain those named states, in -order to explicitly indicate that the states were provided and intended to -be empty. Table entry macro PIN_MAP_DUMMY_STATE serves the purpose of defining -a named state without causing any pin controller to be programmed:: - - static struct pinctrl_map mapping[] __initdata = { - PIN_MAP_DUMMY_STATE("foo-i2c.0", PINCTRL_STATE_DEFAULT), - }; - - -Complex mappings -================ - -As it is possible to map a function to different groups of pins an optional -.group can be specified like this:: - - ... - { - .dev_name = "foo-spi.0", - .name = "spi0-pos-A", - .type = PIN_MAP_TYPE_MUX_GROUP, - .ctrl_dev_name = "pinctrl-foo", - .function = "spi0", - .group = "spi0_0_grp", - }, - { - .dev_name = "foo-spi.0", - .name = "spi0-pos-B", - .type = PIN_MAP_TYPE_MUX_GROUP, - .ctrl_dev_name = "pinctrl-foo", - .function = "spi0", - .group = "spi0_1_grp", - }, - ... - -This example mapping is used to switch between two positions for spi0 at -runtime, as described further below under the heading "Runtime pinmuxing". - -Further it is possible for one named state to affect the muxing of several -groups of pins, say for example in the mmc0 example above, where you can -additively expand the mmc0 bus from 2 to 4 to 8 pins. If we want to use all -three groups for a total of 2+2+4 = 8 pins (for an 8-bit MMC bus as is the -case), we define a mapping like this:: - - ... - { - .dev_name = "foo-mmc.0", - .name = "2bit" - .type = PIN_MAP_TYPE_MUX_GROUP, - .ctrl_dev_name = "pinctrl-foo", - .function = "mmc0", - .group = "mmc0_1_grp", - }, - { - .dev_name = "foo-mmc.0", - .name = "4bit" - .type = PIN_MAP_TYPE_MUX_GROUP, - .ctrl_dev_name = "pinctrl-foo", - .function = "mmc0", - .group = "mmc0_1_grp", - }, - { - .dev_name = "foo-mmc.0", - .name = "4bit" - .type = PIN_MAP_TYPE_MUX_GROUP, - .ctrl_dev_name = "pinctrl-foo", - .function = "mmc0", - .group = "mmc0_2_grp", - }, - { - .dev_name = "foo-mmc.0", - .name = "8bit" - .type = PIN_MAP_TYPE_MUX_GROUP, - .ctrl_dev_name = "pinctrl-foo", - .function = "mmc0", - .group = "mmc0_1_grp", - }, - { - .dev_name = "foo-mmc.0", - .name = "8bit" - .type = PIN_MAP_TYPE_MUX_GROUP, - .ctrl_dev_name = "pinctrl-foo", - .function = "mmc0", - .group = "mmc0_2_grp", - }, - { - .dev_name = "foo-mmc.0", - .name = "8bit" - .type = PIN_MAP_TYPE_MUX_GROUP, - .ctrl_dev_name = "pinctrl-foo", - .function = "mmc0", - .group = "mmc0_3_grp", - }, - ... - -The result of grabbing this mapping from the device with something like -this (see next paragraph):: - - p = devm_pinctrl_get(dev); - s = pinctrl_lookup_state(p, "8bit"); - ret = pinctrl_select_state(p, s); - -or more simply:: - - p = devm_pinctrl_get_select(dev, "8bit"); - -Will be that you activate all the three bottom records in the mapping at -once. Since they share the same name, pin controller device, function and -device, and since we allow multiple groups to match to a single device, they -all get selected, and they all get enabled and disable simultaneously by the -pinmux core. - - -Pin control requests from drivers -================================= - -When a device driver is about to probe the device core will automatically -attempt to issue pinctrl_get_select_default() on these devices. -This way driver writers do not need to add any of the boilerplate code -of the type found below. However when doing fine-grained state selection -and not using the "default" state, you may have to do some device driver -handling of the pinctrl handles and states. - -So if you just want to put the pins for a certain device into the default -state and be done with it, there is nothing you need to do besides -providing the proper mapping table. The device core will take care of -the rest. - -Generally it is discouraged to let individual drivers get and enable pin -control. So if possible, handle the pin control in platform code or some other -place where you have access to all the affected struct device * pointers. In -some cases where a driver needs to e.g. switch between different mux mappings -at runtime this is not possible. - -A typical case is if a driver needs to switch bias of pins from normal -operation and going to sleep, moving from the PINCTRL_STATE_DEFAULT to -PINCTRL_STATE_SLEEP at runtime, re-biasing or even re-muxing pins to save -current in sleep mode. - -A driver may request a certain control state to be activated, usually just the -default state like this:: - - #include - - struct foo_state { - struct pinctrl *p; - struct pinctrl_state *s; - ... - }; - - foo_probe() - { - /* Allocate a state holder named "foo" etc */ - struct foo_state *foo = ...; - - foo->p = devm_pinctrl_get(&device); - if (IS_ERR(foo->p)) { - /* FIXME: clean up "foo" here */ - return PTR_ERR(foo->p); - } - - foo->s = pinctrl_lookup_state(foo->p, PINCTRL_STATE_DEFAULT); - if (IS_ERR(foo->s)) { - /* FIXME: clean up "foo" here */ - return PTR_ERR(s); - } - - ret = pinctrl_select_state(foo->s); - if (ret < 0) { - /* FIXME: clean up "foo" here */ - return ret; - } - } - -This get/lookup/select/put sequence can just as well be handled by bus drivers -if you don't want each and every driver to handle it and you know the -arrangement on your bus. - -The semantics of the pinctrl APIs are: - -- pinctrl_get() is called in process context to obtain a handle to all pinctrl - information for a given client device. It will allocate a struct from the - kernel memory to hold the pinmux state. All mapping table parsing or similar - slow operations take place within this API. - -- devm_pinctrl_get() is a variant of pinctrl_get() that causes pinctrl_put() - to be called automatically on the retrieved pointer when the associated - device is removed. It is recommended to use this function over plain - pinctrl_get(). - -- pinctrl_lookup_state() is called in process context to obtain a handle to a - specific state for a client device. This operation may be slow, too. - -- pinctrl_select_state() programs pin controller hardware according to the - definition of the state as given by the mapping table. In theory, this is a - fast-path operation, since it only involved blasting some register settings - into hardware. However, note that some pin controllers may have their - registers on a slow/IRQ-based bus, so client devices should not assume they - can call pinctrl_select_state() from non-blocking contexts. - -- pinctrl_put() frees all information associated with a pinctrl handle. - -- devm_pinctrl_put() is a variant of pinctrl_put() that may be used to - explicitly destroy a pinctrl object returned by devm_pinctrl_get(). - However, use of this function will be rare, due to the automatic cleanup - that will occur even without calling it. - - pinctrl_get() must be paired with a plain pinctrl_put(). - pinctrl_get() may not be paired with devm_pinctrl_put(). - devm_pinctrl_get() can optionally be paired with devm_pinctrl_put(). - devm_pinctrl_get() may not be paired with plain pinctrl_put(). - -Usually the pin control core handled the get/put pair and call out to the -device drivers bookkeeping operations, like checking available functions and -the associated pins, whereas select_state pass on to the pin controller -driver which takes care of activating and/or deactivating the mux setting by -quickly poking some registers. - -The pins are allocated for your device when you issue the devm_pinctrl_get() -call, after this you should be able to see this in the debugfs listing of all -pins. - -NOTE: the pinctrl system will return -EPROBE_DEFER if it cannot find the -requested pinctrl handles, for example if the pinctrl driver has not yet -registered. Thus make sure that the error path in your driver gracefully -cleans up and is ready to retry the probing later in the startup process. - - -Drivers needing both pin control and GPIOs -========================================== - -Again, it is discouraged to let drivers lookup and select pin control states -themselves, but again sometimes this is unavoidable. - -So say that your driver is fetching its resources like this:: - - #include - #include - - struct pinctrl *pinctrl; - int gpio; - - pinctrl = devm_pinctrl_get_select_default(&dev); - gpio = devm_gpio_request(&dev, 14, "foo"); - -Here we first request a certain pin state and then request GPIO 14 to be -used. If you're using the subsystems orthogonally like this, you should -nominally always get your pinctrl handle and select the desired pinctrl -state BEFORE requesting the GPIO. This is a semantic convention to avoid -situations that can be electrically unpleasant, you will certainly want to -mux in and bias pins in a certain way before the GPIO subsystems starts to -deal with them. - -The above can be hidden: using the device core, the pinctrl core may be -setting up the config and muxing for the pins right before the device is -probing, nevertheless orthogonal to the GPIO subsystem. - -But there are also situations where it makes sense for the GPIO subsystem -to communicate directly with the pinctrl subsystem, using the latter as a -back-end. This is when the GPIO driver may call out to the functions -described in the section "Pin control interaction with the GPIO subsystem" -above. This only involves per-pin multiplexing, and will be completely -hidden behind the gpio_*() function namespace. In this case, the driver -need not interact with the pin control subsystem at all. - -If a pin control driver and a GPIO driver is dealing with the same pins -and the use cases involve multiplexing, you MUST implement the pin controller -as a back-end for the GPIO driver like this, unless your hardware design -is such that the GPIO controller can override the pin controller's -multiplexing state through hardware without the need to interact with the -pin control system. - - -System pin control hogging -========================== - -Pin control map entries can be hogged by the core when the pin controller -is registered. This means that the core will attempt to call pinctrl_get(), -lookup_state() and select_state() on it immediately after the pin control -device has been registered. - -This occurs for mapping table entries where the client device name is equal -to the pin controller device name, and the state name is PINCTRL_STATE_DEFAULT:: - - { - .dev_name = "pinctrl-foo", - .name = PINCTRL_STATE_DEFAULT, - .type = PIN_MAP_TYPE_MUX_GROUP, - .ctrl_dev_name = "pinctrl-foo", - .function = "power_func", - }, - -Since it may be common to request the core to hog a few always-applicable -mux settings on the primary pin controller, there is a convenience macro for -this:: - - PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-foo", NULL /* group */, - "power_func") - -This gives the exact same result as the above construction. - - -Runtime pinmuxing -================= - -It is possible to mux a certain function in and out at runtime, say to move -an SPI port from one set of pins to another set of pins. Say for example for -spi0 in the example above, we expose two different groups of pins for the same -function, but with different named in the mapping as described under -"Advanced mapping" above. So that for an SPI device, we have two states named -"pos-A" and "pos-B". - -This snippet first initializes a state object for both groups (in foo_probe()), -then muxes the function in the pins defined by group A, and finally muxes it in -on the pins defined by group B:: - - #include - - struct pinctrl *p; - struct pinctrl_state *s1, *s2; - - foo_probe() - { - /* Setup */ - p = devm_pinctrl_get(&device); - if (IS_ERR(p)) - ... - - s1 = pinctrl_lookup_state(foo->p, "pos-A"); - if (IS_ERR(s1)) - ... - - s2 = pinctrl_lookup_state(foo->p, "pos-B"); - if (IS_ERR(s2)) - ... - } - - foo_switch() - { - /* Enable on position A */ - ret = pinctrl_select_state(s1); - if (ret < 0) - ... - - ... - - /* Enable on position B */ - ret = pinctrl_select_state(s2); - if (ret < 0) - ... - - ... - } - -The above has to be done from process context. The reservation of the pins -will be done when the state is activated, so in effect one specific pin -can be used by different functions at different times on a running system. diff --git a/MAINTAINERS b/MAINTAINERS index d92f85ca831d..6a279837006b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14103,7 +14103,7 @@ L: linux-gpio@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git F: Documentation/devicetree/bindings/pinctrl/ -F: Documentation/driver-api/pinctl.rst +F: Documentation/driver-api/pin-control.rst F: drivers/pinctrl/ F: include/linux/pinctrl/ -- cgit v1.2.3 From 1ae6478b0e6b22e6031b4917d1187d23bdc1ca72 Mon Sep 17 00:00:00 2001 From: Drew Fustini Date: Mon, 1 Mar 2021 21:30:59 -0800 Subject: docs/pinctrl: document debugfs files Document debugfs directories and files created for pinctrl subsystem. Suggested-by: Andy Shevchenko Reviewed-by: Andy Shevchenko Reviewed-by: Tony Lindgren Signed-off-by: Drew Fustini Link: https://lore.kernel.org/r/20210302053059.1049035-5-drew@beagleboard.org Signed-off-by: Linus Walleij --- Documentation/driver-api/pin-control.rst | 37 ++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/Documentation/driver-api/pin-control.rst b/Documentation/driver-api/pin-control.rst index 3d2deaf48841..c905b273e833 100644 --- a/Documentation/driver-api/pin-control.rst +++ b/Documentation/driver-api/pin-control.rst @@ -1428,3 +1428,40 @@ on the pins defined by group B:: The above has to be done from process context. The reservation of the pins will be done when the state is activated, so in effect one specific pin can be used by different functions at different times on a running system. + + +Debugfs files +============= +These files are created in ``/sys/kernel/debug/pinctrl``: + +- ``pinctrl-devices``: prints each pin controller device along with columns to + indicate support for pinmux and pinconf + +- ``pinctrl-handles``: prints each configured pin controller handle and the + corresponding pinmux maps + +- ``pinctrl-maps``: print all pinctrl maps + +A sub-directory is created inside of ``/sys/kernel/debug/pinctrl`` for each pin +controller device containing these files: + +- ``pins``: prints a line for each pin registered on the pin controller. The + pinctrl driver may add additional information such as register contents. + +- ``gpio-ranges``: print ranges that map gpio lines to pins on the controller + +- ``pingroups``: print all pin groups registered on the pin controller + +- ``pinconf-pins``: print pin config settings for each pin + +- ``pinconf-groups``: print pin config settings per pin group + +- ``pinmux-functions``: print each pin function along with the pin groups that + map to the pin function + +- ``pinmux-pins``: iterate through all pins and print mux owner, gpio owner + and if the pin is a hog + +- ``pinmux-select``: write to this file to activate a pin function for a group:: + + echo "" > pinmux-select -- cgit v1.2.3 From 975bad7cbd34352f164dccc98f8292f4efb3a374 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 8 Mar 2021 22:18:44 +0530 Subject: dt-bindings: pinctrl: qcom-pmic-gpio: Add pm8350 and friends Add support for the PM8350, PM8350B, PM8350C, PMK8350, PMR735A and PMR735B GPIO support to the Qualcomm PMIC GPIO binding. Signed-off-by: Vinod Koul Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210308164845.3210393-1-vkoul@kernel.org Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt index 7648ab00f4e2..70e119b39c48 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt @@ -27,6 +27,12 @@ PMIC's from Qualcomm. "qcom,pm660l-gpio" "qcom,pm8150-gpio" "qcom,pm8150b-gpio" + "qcom,pm8350-gpio" + "qcom,pm8350b-gpio" + "qcom,pm8350c-gpio" + "qcom,pmk8350-gpio" + "qcom,pmr735a-gpio" + "qcom,pmr735b-gpio" "qcom,pm6150-gpio" "qcom,pm6150l-gpio" "qcom,pmx55-gpio" @@ -109,6 +115,12 @@ to specify in a pin configuration subnode: and gpio8) gpio1-gpio12 for pm8150b (holes on gpio3, gpio4, gpio7) gpio1-gpio12 for pm8150l (hole on gpio7) + gpio1-gpio10 for pm8350 + gpio1-gpio8 for pm8350b + gpio1-gpio9 for pm8350c + gpio1-gpio4 for pmk8350 + gpio1-gpio4 for pmr735a + gpio1-gpio4 for pmr735b gpio1-gpio10 for pm6150 gpio1-gpio12 for pm6150l gpio1-gpio11 for pmx55 (holes on gpio3, gpio7, gpio10 -- cgit v1.2.3 From 57c0a4f0a071be916e534d6f6e52dcf0cd8df8ba Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 8 Mar 2021 22:18:45 +0530 Subject: pinctrl: qcom: spmi-gpio: Add support for PM8350 and friends Add support for the PM8350, PM8350B, PM8350C, PMK8350, PMR735A and PMR735B GPIO support to the Qualcomm PMIC GPIO driver. Signed-off-by: Vinod Koul Acked-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210308164845.3210393-2-vkoul@kernel.org Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index 9801c717e311..c2b9f2e152bb 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -1127,6 +1127,12 @@ static const struct of_device_id pmic_gpio_of_match[] = { { .compatible = "qcom,pm8150b-gpio", .data = (void *) 12 }, /* pm8150l has 12 GPIOs with holes on 7 */ { .compatible = "qcom,pm8150l-gpio", .data = (void *) 12 }, + { .compatible = "qcom,pm8350-gpio", .data = (void *) 10 }, + { .compatible = "qcom,pm8350b-gpio", .data = (void *) 8 }, + { .compatible = "qcom,pm8350c-gpio", .data = (void *) 9 }, + { .compatible = "qcom,pmk8350-gpio", .data = (void *) 4 }, + { .compatible = "qcom,pmr735a-gpio", .data = (void *) 4 }, + { .compatible = "qcom,pmr735b-gpio", .data = (void *) 4 }, { .compatible = "qcom,pm6150-gpio", .data = (void *) 10 }, { .compatible = "qcom,pm6150l-gpio", .data = (void *) 12 }, /* pmx55 has 11 GPIOs with holes on 3, 7, 10, 11 */ -- cgit v1.2.3 From b991f8c3622c8c9d01a1ada382682a731932e651 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 10 Mar 2021 09:16:54 +0100 Subject: pinctrl: core: Handling pinmux and pinconf separately Right now the handling order depends on how entries are coming which is corresponding with order in DT. We have reached the case with DT overlays where conf and mux descriptions are exchanged which ends up in sequence that firmware has been asked to perform configuration before requesting the pin. The patch is enforcing the order that pin is requested all the time first followed by pin configuration. This change will ensure that firmware gets requests in the right order. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/cfbe01f791c2dd42a596cbda57e15599969b57aa.1615364211.git.michal.simek@xilinx.com Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 6ddf2bc36f15..9063d8f86e60 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -1258,13 +1258,34 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state) p->state = NULL; - /* Apply all the settings for the new state */ + /* Apply all the settings for the new state - pinmux first */ list_for_each_entry(setting, &state->settings, node) { switch (setting->type) { case PIN_MAP_TYPE_MUX_GROUP: ret = pinmux_enable_setting(setting); break; case PIN_MAP_TYPE_CONFIGS_PIN: + case PIN_MAP_TYPE_CONFIGS_GROUP: + break; + default: + ret = -EINVAL; + break; + } + + if (ret < 0) + goto unapply_new_state; + + /* Do not link hogs (circular dependency) */ + if (p != setting->pctldev->p) + pinctrl_link_add(setting->pctldev, p->dev); + } + + /* Apply all the settings for the new state - pinconf after */ + list_for_each_entry(setting, &state->settings, node) { + switch (setting->type) { + case PIN_MAP_TYPE_MUX_GROUP: + break; + case PIN_MAP_TYPE_CONFIGS_PIN: case PIN_MAP_TYPE_CONFIGS_GROUP: ret = pinconf_apply_setting(setting); break; -- cgit v1.2.3 From 024c79520ff5f8cfb9666cdb877af30c554c540f Mon Sep 17 00:00:00 2001 From: Jianqun Xu Date: Fri, 5 Mar 2021 16:06:58 +0800 Subject: kernel/irq: export irq_gc_set_wake Module driver may use irq_gc_set_wake. Signed-off-by: Jianqun Xu Acked-by: Marc Zyngier Link: https://lore.kernel.org/r/20210305080658.2422114-1-jay.xu@rock-chips.com Signed-off-by: Linus Walleij --- kernel/irq/generic-chip.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c index a23ac2bbf433..f8f23af6ab0d 100644 --- a/kernel/irq/generic-chip.c +++ b/kernel/irq/generic-chip.c @@ -200,6 +200,7 @@ int irq_gc_set_wake(struct irq_data *d, unsigned int on) irq_gc_unlock(gc); return 0; } +EXPORT_SYMBOL_GPL(irq_gc_set_wake); static u32 irq_readl_be(void __iomem *addr) { -- cgit v1.2.3 From 25fda51ca33b3d7977c351ab9420b32df3289b5f Mon Sep 17 00:00:00 2001 From: Jianqun Xu Date: Fri, 5 Mar 2021 08:39:06 +0800 Subject: arm64: remove select PINCTRL_ROCKCHIP from ARCH_ROCKCHIP Prepare to make pinctrl driver of rockchip to be module able, this patch remove the select of PINCTRL_ROCKCHIP from ARCH_ROCKCHIP. Signed-off-by: Jianqun Xu Link: https://lore.kernel.org/r/20210305003907.1692515-2-jay.xu@rock-chips.com Signed-off-by: Linus Walleij --- arch/arm64/Kconfig.platforms | 2 -- drivers/pinctrl/Kconfig | 4 ++++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index cdfd5fed457f..7efa42e16d84 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -235,9 +235,7 @@ config ARCH_RENESAS config ARCH_ROCKCHIP bool "Rockchip Platforms" select ARCH_HAS_RESET_CONTROLLER - select GPIOLIB select PINCTRL - select PINCTRL_ROCKCHIP select PM select ROCKCHIP_TIMER help diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index b7675cce0027..439a02890ef7 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -210,11 +210,15 @@ config PINCTRL_OXNAS config PINCTRL_ROCKCHIP bool depends on OF + select GPIOLIB select PINMUX select GENERIC_PINCONF select GENERIC_IRQ_CHIP select MFD_SYSCON select OF_GPIO + default ARCH_ROCKCHIP + help + This support pinctrl and gpio driver for Rockchip SoCs. config PINCTRL_SINGLE tristate "One-register-per-pin type device tree based pinctrl driver" -- cgit v1.2.3 From be786ac5a6c4bf4ef3e4c569a045d302c1e60fe6 Mon Sep 17 00:00:00 2001 From: Jianqun Xu Date: Fri, 5 Mar 2021 08:39:07 +0800 Subject: pinctrl: rockchip: make driver be tristate module Make pinctrl-rockchip driver to be tristate module, support to build as a module, this is useful for GKI. Reviewed-by: Heiko Stuebner Signed-off-by: Jianqun Xu Link: https://lore.kernel.org/r/20210305003907.1692515-3-jay.xu@rock-chips.com Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 2 +- drivers/pinctrl/pinctrl-rockchip.c | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 439a02890ef7..ef0ae9b562cd 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -208,7 +208,7 @@ config PINCTRL_OXNAS select MFD_SYSCON config PINCTRL_ROCKCHIP - bool + tristate "Rockchip gpio and pinctrl driver" depends on OF select GPIOLIB select PINMUX diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index ec4cb88572cf..65aa87476eae 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -16,10 +16,12 @@ */ #include +#include #include #include #include #include +#include #include #include #include @@ -4257,3 +4259,14 @@ static int __init rockchip_pinctrl_drv_register(void) return platform_driver_register(&rockchip_pinctrl_driver); } postcore_initcall(rockchip_pinctrl_drv_register); + +static void __exit rockchip_pinctrl_drv_unregister(void) +{ + platform_driver_unregister(&rockchip_pinctrl_driver); +} +module_exit(rockchip_pinctrl_drv_unregister); + +MODULE_DESCRIPTION("ROCKCHIP Pin Controller Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:pinctrl-rockchip"); +MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match); -- cgit v1.2.3 From 47386ce36f904583d45c82087d992a50ad612c8b Mon Sep 17 00:00:00 2001 From: Jia-Ju Bai Date: Sat, 6 Mar 2021 04:51:22 -0800 Subject: pinctrl: ti: fix error return code of ti_iodelay_probe() When ti_iodelay_pinconf_init_dev() fails, no error return code of ti_iodelay_probe() is assigned. To fix this bug, ret is assigned with the return value of ti_iodelay_pinconf_init_dev(), and then ret is checked. Reported-by: TOTE Robot Signed-off-by: Jia-Ju Bai Link: https://lore.kernel.org/r/20210306125122.15043-1-baijiaju1990@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/ti/pinctrl-ti-iodelay.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/ti/pinctrl-ti-iodelay.c b/drivers/pinctrl/ti/pinctrl-ti-iodelay.c index 60a67139ff0a..e5848269175a 100644 --- a/drivers/pinctrl/ti/pinctrl-ti-iodelay.c +++ b/drivers/pinctrl/ti/pinctrl-ti-iodelay.c @@ -867,7 +867,8 @@ static int ti_iodelay_probe(struct platform_device *pdev) goto exit_out; } - if (ti_iodelay_pinconf_init_dev(iod)) + ret = ti_iodelay_pinconf_init_dev(iod); + if (ret) goto exit_out; ret = ti_iodelay_alloc_pins(dev, iod, res->start); -- cgit v1.2.3 From 6a37d750037827d385672acdebf5788fc2ffa633 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 12 Mar 2021 08:31:34 +0100 Subject: pinctrl: core: Set ret to 0 when group is skipped Static analyzer tool found that the ret variable is not initialized but code expects ret value >=0 when pinconf is skipped in the first pinmux loop. The same expectation is for pinmux in a pinconf loop. That's why initialize ret to 0 to avoid uninitialized ret value in first loop or reusing ret value from first loop in second. Addresses-Coverity: ("Uninitialized variables") Signed-off-by: Michal Simek Cc: Dan Carpenter Reviewed-by: Colin Ian King Link: https://lore.kernel.org/r/e5203bae68eb94b4b8b4e67e5e7b4d86bb989724.1615534291.git.michal.simek@xilinx.com Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 9063d8f86e60..2252db9bbc3a 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -1266,6 +1266,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state) break; case PIN_MAP_TYPE_CONFIGS_PIN: case PIN_MAP_TYPE_CONFIGS_GROUP: + ret = 0; break; default: ret = -EINVAL; @@ -1284,6 +1285,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state) list_for_each_entry(setting, &state->settings, node) { switch (setting->type) { case PIN_MAP_TYPE_MUX_GROUP: + ret = 0; break; case PIN_MAP_TYPE_CONFIGS_PIN: case PIN_MAP_TYPE_CONFIGS_GROUP: -- cgit v1.2.3 From 552bad043709af377aa963a5db0b2bac0b0b2fab Mon Sep 17 00:00:00 2001 From: Lina Iyer Date: Thu, 11 Mar 2021 19:42:17 -0800 Subject: pinctrl: qcom: sm8350: add GPIO wakeup interrupt map GPIOs that can be configured as wakeup sources, have their interrupt lines routed to PDC interrupt controller. Provide the interrupt map of the GPIO to its wakeup capable interrupt parent. Signed-off-by: Lina Iyer Signed-off-by: Bjorn Andersson Reviewed-by: Vinod Koul Link: https://lore.kernel.org/r/20210312034218.3324410-1-bjorn.andersson@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-sm8350.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/pinctrl/qcom/pinctrl-sm8350.c b/drivers/pinctrl/qcom/pinctrl-sm8350.c index a406ed0ec7d3..4d8f8636c2b3 100644 --- a/drivers/pinctrl/qcom/pinctrl-sm8350.c +++ b/drivers/pinctrl/qcom/pinctrl-sm8350.c @@ -1603,6 +1603,25 @@ static const struct msm_pingroup sm8350_groups[] = { [206] = SDC_PINGROUP(sdc2_data, 0x1cf000, 9, 0), }; +static const struct msm_gpio_wakeirq_map sm8350_pdc_map[] = { + { 2, 117 }, { 7, 82 }, { 11, 83 }, { 14, 80 }, { 15, 146 }, + { 19, 121 }, { 23, 84 }, { 26, 86 }, { 27, 75 }, { 31, 85 }, + { 32, 97 }, { 34, 98 }, { 35, 131 }, { 36, 79 }, { 38, 99 }, + { 39, 92 }, { 40, 101 }, { 43, 137 }, { 44, 102 }, { 46, 96 }, + { 47, 93 }, { 50, 108 }, { 51, 127 }, { 55, 128 }, { 56, 81 }, + { 59, 112 }, { 60, 119 }, { 63, 73 }, { 67, 74 }, { 71, 134 }, + { 75, 103 }, { 79, 104 }, { 80, 126 }, { 81, 139 }, { 82, 140 }, + { 83, 141 }, { 84, 124 }, { 85, 109 }, { 86, 143 }, { 87, 138 }, + { 88, 122 }, { 89, 113 }, { 90, 114 }, { 91, 115 }, { 92, 76 }, + { 95, 147 }, { 96, 148 }, { 98, 149 }, { 99, 150 }, { 115, 125 }, + { 116, 106 }, { 117, 105 }, { 118, 116 }, { 119, 123 }, { 130, 145 }, + { 136, 72 }, { 140, 100 }, { 151, 110 }, { 153, 95 }, { 155, 107 }, + { 156, 94 }, { 157, 111 }, { 159, 118 }, { 162, 77 }, { 165, 78 }, + { 169, 70 }, { 172, 132 }, { 174, 87 }, { 175, 88 }, { 177, 89 }, + { 179, 120 }, { 180, 129 }, { 183, 90 }, { 185, 136 }, { 187, 142 }, + { 190, 144 }, { 198, 91 }, { 200, 133 }, { 202, 135 }, +}; + static const struct msm_pinctrl_soc_data sm8350_tlmm = { .pins = sm8350_pins, .npins = ARRAY_SIZE(sm8350_pins), @@ -1611,6 +1630,8 @@ static const struct msm_pinctrl_soc_data sm8350_tlmm = { .groups = sm8350_groups, .ngroups = ARRAY_SIZE(sm8350_groups), .ngpios = 204, + .wakeirq_map = sm8350_pdc_map, + .nwakeirq_map = ARRAY_SIZE(sm8350_pdc_map), }; static int sm8350_tlmm_probe(struct platform_device *pdev) -- cgit v1.2.3 From 6d8d67988b1a2db04d9d6083a729e8abfeb725d7 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 11 Mar 2021 10:41:02 +0800 Subject: pinctrl: qcom: sc8180x: add ACPI probe support It adds ACPI probe support for pinctrl-sc8180x driver. We have one problem with ACPI table, i.e. GIO0 (TLMM) block has one single memory resource to cover 3 tiles defined by SC8180X. To follow the hardware layout of 3 tiles which is already supported DT probe, it adds one function to replace the original single memory resource with 3 named ones for tiles. With that, We can map memory for ACPI in the same way as DT. Signed-off-by: Shawn Guo Reviewed-by: Bjorn Andersson Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210311024102.15450-1-shawn.guo@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/Kconfig | 2 +- drivers/pinctrl/qcom/pinctrl-sc8180x.c | 123 ++++++++++++++++++++++++++++++++- 2 files changed, 122 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index 6853a896c476..9f0218c4f9b3 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -222,7 +222,7 @@ config PINCTRL_SC7280 config PINCTRL_SC8180X tristate "Qualcomm Technologies Inc SC8180x pin controller driver" - depends on GPIOLIB && OF + depends on GPIOLIB && (OF || ACPI) select PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the diff --git a/drivers/pinctrl/qcom/pinctrl-sc8180x.c b/drivers/pinctrl/qcom/pinctrl-sc8180x.c index b765bf667574..0d9654b4ab60 100644 --- a/drivers/pinctrl/qcom/pinctrl-sc8180x.c +++ b/drivers/pinctrl/qcom/pinctrl-sc8180x.c @@ -23,6 +23,21 @@ enum { WEST }; +/* + * ACPI DSDT has one single memory resource for TLMM. The offsets below are + * used to locate different tiles for ACPI probe. + */ +struct tile_info { + u32 offset; + u32 size; +}; + +static const struct tile_info sc8180x_tile_info[] = { + { 0x00d00000, 0x00300000, }, + { 0x00500000, 0x00700000, }, + { 0x00100000, 0x00300000, }, +}; + #define FUNCTION(fname) \ [msm_mux_##fname] = { \ .name = #fname, \ @@ -1557,6 +1572,13 @@ static const struct msm_pingroup sc8180x_groups[] = { [193] = SDC_QDSD_PINGROUP(sdc2_data, 0x4b2000, 9, 0), }; +static const int sc8180x_acpi_reserved_gpios[] = { + 0, 1, 2, 3, + 47, 48, 49, 50, + 126, 127, 128, 129, + -1 /* terminator */ +}; + static const struct msm_gpio_wakeirq_map sc8180x_pdc_map[] = { { 3, 31 }, { 5, 32 }, { 8, 33 }, { 9, 34 }, { 10, 100 }, { 12, 104 }, { 24, 37 }, { 26, 38 }, { 27, 41 }, { 28, 42 }, { 30, 39 }, { 36, 43 }, @@ -1588,13 +1610,109 @@ static struct msm_pinctrl_soc_data sc8180x_pinctrl = { .nwakeirq_map = ARRAY_SIZE(sc8180x_pdc_map), }; +static const struct msm_pinctrl_soc_data sc8180x_acpi_pinctrl = { + .tiles = sc8180x_tiles, + .ntiles = ARRAY_SIZE(sc8180x_tiles), + .pins = sc8180x_pins, + .npins = ARRAY_SIZE(sc8180x_pins), + .groups = sc8180x_groups, + .ngroups = ARRAY_SIZE(sc8180x_groups), + .reserved_gpios = sc8180x_acpi_reserved_gpios, + .ngpios = 190, +}; + +/* + * ACPI DSDT has one single memory resource for TLMM, which voilates the + * hardware layout of 3 sepearte tiles. Let's split the memory resource into + * 3 named ones, so that msm_pinctrl_probe() can map memory for ACPI in the + * same way as for DT probe. + */ +static int sc8180x_pinctrl_add_tile_resources(struct platform_device *pdev) +{ + int nres_num = pdev->num_resources + ARRAY_SIZE(sc8180x_tiles) - 1; + struct resource *mres, *nres, *res; + int i, ret; + + /* + * DT already has tiles defined properly, so nothing needs to be done + * for DT probe. + */ + if (pdev->dev.of_node) + return 0; + + /* Allocate for new resources */ + nres = devm_kzalloc(&pdev->dev, sizeof(*nres) * nres_num, GFP_KERNEL); + if (!nres) + return -ENOMEM; + + res = nres; + + for (i = 0; i < pdev->num_resources; i++) { + struct resource *r = &pdev->resource[i]; + + /* Save memory resource and copy others */ + if (resource_type(r) == IORESOURCE_MEM) + mres = r; + else + *res++ = *r; + } + + /* Append tile memory resources */ + for (i = 0; i < ARRAY_SIZE(sc8180x_tiles); i++, res++) { + const struct tile_info *info = &sc8180x_tile_info[i]; + + res->start = mres->start + info->offset; + res->end = mres->start + info->offset + info->size - 1; + res->flags = mres->flags; + res->name = sc8180x_tiles[i]; + + /* Add new MEM to resource tree */ + insert_resource(mres->parent, res); + } + + /* Remove old MEM from resource tree */ + remove_resource(mres); + + /* Free old resources and install new ones */ + ret = platform_device_add_resources(pdev, nres, nres_num); + if (ret) { + dev_err(&pdev->dev, "failed to add new resources: %d\n", ret); + return ret; + } + + return 0; +} + static int sc8180x_pinctrl_probe(struct platform_device *pdev) { - return msm_pinctrl_probe(pdev, &sc8180x_pinctrl); + const struct msm_pinctrl_soc_data *soc_data; + int ret; + + soc_data = device_get_match_data(&pdev->dev); + if (!soc_data) + return -EINVAL; + + ret = sc8180x_pinctrl_add_tile_resources(pdev); + if (ret) + return ret; + + return msm_pinctrl_probe(pdev, soc_data); } +static const struct acpi_device_id sc8180x_pinctrl_acpi_match[] = { + { + .id = "QCOM040D", + .driver_data = (kernel_ulong_t) &sc8180x_acpi_pinctrl, + }, + { } +}; +MODULE_DEVICE_TABLE(acpi, sc8180x_pinctrl_acpi_match); + static const struct of_device_id sc8180x_pinctrl_of_match[] = { - { .compatible = "qcom,sc8180x-tlmm", }, + { + .compatible = "qcom,sc8180x-tlmm", + .data = &sc8180x_pinctrl, + }, { }, }; MODULE_DEVICE_TABLE(of, sc8180x_pinctrl_of_match); @@ -1603,6 +1721,7 @@ static struct platform_driver sc8180x_pinctrl_driver = { .driver = { .name = "sc8180x-pinctrl", .of_match_table = sc8180x_pinctrl_of_match, + .acpi_match_table = sc8180x_pinctrl_acpi_match, }, .probe = sc8180x_pinctrl_probe, .remove = msm_pinctrl_remove, -- cgit v1.2.3 From b82fd2df17afc53580e8aeaee243dde4b23b9e79 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 3 Mar 2021 14:26:14 +0100 Subject: pinctrl: renesas: Make sh_pfc_pin_to_bias_reg() static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now all R-Car pin control drivers have been converted to the common R-Car bias handling, sh_pfc_pin_to_bias_reg() is only called from a single place. Move it from core.c to pinctrl.c, make it static, and rename it to rcar_pin_to_bias_reg(), as it is specific to R-Car SoCs. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20210303132619.3938128-2-geert+renesas@glider.be --- drivers/pinctrl/renesas/core.c | 20 -------------------- drivers/pinctrl/renesas/core.h | 4 ---- drivers/pinctrl/renesas/pinctrl.c | 24 ++++++++++++++++++++++-- 3 files changed, 22 insertions(+), 26 deletions(-) diff --git a/drivers/pinctrl/renesas/core.c b/drivers/pinctrl/renesas/core.c index 2bfd3006f6fd..5ccc49b387f1 100644 --- a/drivers/pinctrl/renesas/core.c +++ b/drivers/pinctrl/renesas/core.c @@ -394,26 +394,6 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) return 0; } -const struct pinmux_bias_reg * -sh_pfc_pin_to_bias_reg(const struct sh_pfc *pfc, unsigned int pin, - unsigned int *bit) -{ - unsigned int i, j; - - for (i = 0; pfc->info->bias_regs[i].puen; i++) { - for (j = 0; j < ARRAY_SIZE(pfc->info->bias_regs[i].pins); j++) { - if (pfc->info->bias_regs[i].pins[j] == pin) { - *bit = j; - return &pfc->info->bias_regs[i]; - } - } - } - - WARN_ONCE(1, "Pin %u is not in bias info list\n", pin); - - return NULL; -} - static int sh_pfc_init_ranges(struct sh_pfc *pfc) { struct sh_pfc_pin_range *range; diff --git a/drivers/pinctrl/renesas/core.h b/drivers/pinctrl/renesas/core.h index 5ca7e0830ae9..19f7b4308fac 100644 --- a/drivers/pinctrl/renesas/core.h +++ b/drivers/pinctrl/renesas/core.h @@ -29,10 +29,6 @@ void sh_pfc_write(struct sh_pfc *pfc, u32 reg, u32 data); int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin); int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type); -const struct pinmux_bias_reg * -sh_pfc_pin_to_bias_reg(const struct sh_pfc *pfc, unsigned int pin, - unsigned int *bit); - unsigned int rcar_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin); void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, unsigned int bias); diff --git a/drivers/pinctrl/renesas/pinctrl.c b/drivers/pinctrl/renesas/pinctrl.c index a49f74730272..963d217b9403 100644 --- a/drivers/pinctrl/renesas/pinctrl.c +++ b/drivers/pinctrl/renesas/pinctrl.c @@ -840,12 +840,32 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc) return pinctrl_enable(pmx->pctl); } +static const struct pinmux_bias_reg * +rcar_pin_to_bias_reg(const struct sh_pfc *pfc, unsigned int pin, + unsigned int *bit) +{ + unsigned int i, j; + + for (i = 0; pfc->info->bias_regs[i].puen; i++) { + for (j = 0; j < ARRAY_SIZE(pfc->info->bias_regs[i].pins); j++) { + if (pfc->info->bias_regs[i].pins[j] == pin) { + *bit = j; + return &pfc->info->bias_regs[i]; + } + } + } + + WARN_ONCE(1, "Pin %u is not in bias info list\n", pin); + + return NULL; +} + unsigned int rcar_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin) { const struct pinmux_bias_reg *reg; unsigned int bit; - reg = sh_pfc_pin_to_bias_reg(pfc, pin, &bit); + reg = rcar_pin_to_bias_reg(pfc, pin, &bit); if (!reg) return PIN_CONFIG_BIAS_DISABLE; @@ -864,7 +884,7 @@ void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, u32 enable, updown; unsigned int bit; - reg = sh_pfc_pin_to_bias_reg(pfc, pin, &bit); + reg = rcar_pin_to_bias_reg(pfc, pin, &bit); if (!reg) return; -- cgit v1.2.3 From 4b6e6c19895b923b1ebfb5312902e905e2a1f91a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 3 Mar 2021 14:26:15 +0100 Subject: pinctrl: renesas: Move R-Car bias helpers to sh_pfc.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Renesas Pin Function Controller driver uses two header files: - sh_pfc.h, for use by both core code and SoC-specific drivers, - core.h, for internal use by the core code only. Hence move the R-Car bias helper declarations from core.h to sh_pfc.h, and drop the inclusion of core.h from SoC-specific drivers that no longer need it. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20210303132619.3938128-3-geert+renesas@glider.be --- drivers/pinctrl/renesas/core.h | 4 ---- drivers/pinctrl/renesas/pfc-r8a7778.c | 1 - drivers/pinctrl/renesas/pfc-r8a7792.c | 1 - drivers/pinctrl/renesas/pfc-r8a77950.c | 1 - drivers/pinctrl/renesas/pfc-r8a77951.c | 1 - drivers/pinctrl/renesas/pfc-r8a7796.c | 1 - drivers/pinctrl/renesas/pfc-r8a77965.c | 1 - drivers/pinctrl/renesas/pfc-r8a77970.c | 1 - drivers/pinctrl/renesas/pfc-r8a77980.c | 1 - drivers/pinctrl/renesas/pfc-r8a77990.c | 1 - drivers/pinctrl/renesas/pfc-r8a77995.c | 1 - drivers/pinctrl/renesas/pfc-r8a779a0.c | 1 - drivers/pinctrl/renesas/sh_pfc.h | 7 +++++++ 13 files changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/pinctrl/renesas/core.h b/drivers/pinctrl/renesas/core.h index 19f7b4308fac..51f391e9713a 100644 --- a/drivers/pinctrl/renesas/core.h +++ b/drivers/pinctrl/renesas/core.h @@ -29,8 +29,4 @@ void sh_pfc_write(struct sh_pfc *pfc, u32 reg, u32 data); int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin); int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type); -unsigned int rcar_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin); -void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, - unsigned int bias); - #endif /* __SH_PFC_CORE_H__ */ diff --git a/drivers/pinctrl/renesas/pfc-r8a7778.c b/drivers/pinctrl/renesas/pfc-r8a7778.c index 75f52b1798c3..6185af9c4990 100644 --- a/drivers/pinctrl/renesas/pfc-r8a7778.c +++ b/drivers/pinctrl/renesas/pfc-r8a7778.c @@ -16,7 +16,6 @@ #include #include -#include "core.h" #include "sh_pfc.h" #define PORT_GP_PUP_1(bank, pin, fn, sfx) \ diff --git a/drivers/pinctrl/renesas/pfc-r8a7792.c b/drivers/pinctrl/renesas/pfc-r8a7792.c index 258f82fb31c0..f54a7c81005d 100644 --- a/drivers/pinctrl/renesas/pfc-r8a7792.c +++ b/drivers/pinctrl/renesas/pfc-r8a7792.c @@ -8,7 +8,6 @@ #include -#include "core.h" #include "sh_pfc.h" #define CPU_ALL_GP(fn, sfx) \ diff --git a/drivers/pinctrl/renesas/pfc-r8a77950.c b/drivers/pinctrl/renesas/pfc-r8a77950.c index 32fe8caca70a..ee4ce9349aae 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77950.c +++ b/drivers/pinctrl/renesas/pfc-r8a77950.c @@ -8,7 +8,6 @@ #include #include -#include "core.h" #include "sh_pfc.h" #define CFG_FLAGS (SH_PFC_PIN_CFG_DRIVE_STRENGTH | SH_PFC_PIN_CFG_PULL_UP_DOWN) diff --git a/drivers/pinctrl/renesas/pfc-r8a77951.c b/drivers/pinctrl/renesas/pfc-r8a77951.c index 6f3a1625d789..be4eee070842 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77951.c +++ b/drivers/pinctrl/renesas/pfc-r8a77951.c @@ -9,7 +9,6 @@ #include #include -#include "core.h" #include "sh_pfc.h" #define CFG_FLAGS (SH_PFC_PIN_CFG_DRIVE_STRENGTH | SH_PFC_PIN_CFG_PULL_UP_DOWN) diff --git a/drivers/pinctrl/renesas/pfc-r8a7796.c b/drivers/pinctrl/renesas/pfc-r8a7796.c index ce2466df5ef2..44e9d2eea484 100644 --- a/drivers/pinctrl/renesas/pfc-r8a7796.c +++ b/drivers/pinctrl/renesas/pfc-r8a7796.c @@ -14,7 +14,6 @@ #include #include -#include "core.h" #include "sh_pfc.h" #define CFG_FLAGS (SH_PFC_PIN_CFG_DRIVE_STRENGTH | SH_PFC_PIN_CFG_PULL_UP_DOWN) diff --git a/drivers/pinctrl/renesas/pfc-r8a77965.c b/drivers/pinctrl/renesas/pfc-r8a77965.c index dd6b0c9ce575..e69210cc6148 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77965.c +++ b/drivers/pinctrl/renesas/pfc-r8a77965.c @@ -15,7 +15,6 @@ #include #include -#include "core.h" #include "sh_pfc.h" #define CFG_FLAGS (SH_PFC_PIN_CFG_DRIVE_STRENGTH | SH_PFC_PIN_CFG_PULL_UP_DOWN) diff --git a/drivers/pinctrl/renesas/pfc-r8a77970.c b/drivers/pinctrl/renesas/pfc-r8a77970.c index e8a0fc468eb2..7935826cfae7 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77970.c +++ b/drivers/pinctrl/renesas/pfc-r8a77970.c @@ -16,7 +16,6 @@ #include #include -#include "core.h" #include "sh_pfc.h" #define CPU_ALL_GP(fn, sfx) \ diff --git a/drivers/pinctrl/renesas/pfc-r8a77980.c b/drivers/pinctrl/renesas/pfc-r8a77980.c index ebd07bebaeeb..20cff93a2a13 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77980.c +++ b/drivers/pinctrl/renesas/pfc-r8a77980.c @@ -16,7 +16,6 @@ #include #include -#include "core.h" #include "sh_pfc.h" #define CPU_ALL_GP(fn, sfx) \ diff --git a/drivers/pinctrl/renesas/pfc-r8a77990.c b/drivers/pinctrl/renesas/pfc-r8a77990.c index a243aa8c5253..d040eb3e305d 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77990.c +++ b/drivers/pinctrl/renesas/pfc-r8a77990.c @@ -14,7 +14,6 @@ #include #include -#include "core.h" #include "sh_pfc.h" #define CFG_FLAGS (SH_PFC_PIN_CFG_PULL_UP_DOWN) diff --git a/drivers/pinctrl/renesas/pfc-r8a77995.c b/drivers/pinctrl/renesas/pfc-r8a77995.c index 672251d86c2d..b479f87a3b23 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77995.c +++ b/drivers/pinctrl/renesas/pfc-r8a77995.c @@ -14,7 +14,6 @@ #include #include -#include "core.h" #include "sh_pfc.h" #define CPU_ALL_GP(fn, sfx) \ diff --git a/drivers/pinctrl/renesas/pfc-r8a779a0.c b/drivers/pinctrl/renesas/pfc-r8a779a0.c index 2250ccd0470a..ad6532443a78 100644 --- a/drivers/pinctrl/renesas/pfc-r8a779a0.c +++ b/drivers/pinctrl/renesas/pfc-r8a779a0.c @@ -11,7 +11,6 @@ #include #include -#include "core.h" #include "sh_pfc.h" #define CFG_FLAGS (SH_PFC_PIN_CFG_DRIVE_STRENGTH | SH_PFC_PIN_CFG_PULL_UP_DOWN) diff --git a/drivers/pinctrl/renesas/sh_pfc.h b/drivers/pinctrl/renesas/sh_pfc.h index 5934faeb23d7..2d511c7280fa 100644 --- a/drivers/pinctrl/renesas/sh_pfc.h +++ b/drivers/pinctrl/renesas/sh_pfc.h @@ -773,4 +773,11 @@ extern const struct sh_pfc_soc_info shx3_pinmux_info; */ #define RCAR_GP_PIN(bank, pin) (((bank) * 32) + (pin)) +/* + * Bias helpers + */ +unsigned int rcar_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin); +void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, + unsigned int bias); + #endif /* __SH_PFC_H */ -- cgit v1.2.3 From ec0794a122db146ac58984afd198062d0349b92a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 3 Mar 2021 14:26:16 +0100 Subject: pinctrl: renesas: Factor out common R-Mobile bias handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pin control sub-drivers for SH/R-Mobile SoCs contain almost identical bias handling. The only SoC-specific part is the mapping from pin numbers to PORTnCR registers. Reduce code duplication by factoring out the bias handling to the common pinctrl.c code. Use a callback to handle the pin/register mapping. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20210303132619.3938128-4-geert+renesas@glider.be --- drivers/pinctrl/renesas/pfc-r8a73a4.c | 48 ++++------------------------------- drivers/pinctrl/renesas/pfc-r8a7740.c | 46 +++------------------------------ drivers/pinctrl/renesas/pfc-sh73a0.c | 46 ++++----------------------------- drivers/pinctrl/renesas/pinctrl.c | 40 +++++++++++++++++++++++++++++ drivers/pinctrl/renesas/sh_pfc.h | 5 ++++ 5 files changed, 59 insertions(+), 126 deletions(-) diff --git a/drivers/pinctrl/renesas/pfc-r8a73a4.c b/drivers/pinctrl/renesas/pfc-r8a73a4.c index b21f5afe610f..b26ff9d6ead4 100644 --- a/drivers/pinctrl/renesas/pfc-r8a73a4.c +++ b/drivers/pinctrl/renesas/pfc-r8a73a4.c @@ -2649,59 +2649,21 @@ static const struct pinmux_irq pinmux_irqs[] = { PINMUX_IRQ(329), /* IRQ57 */ }; -#define PORTCR_PULMD_OFF (0 << 6) -#define PORTCR_PULMD_DOWN (2 << 6) -#define PORTCR_PULMD_UP (3 << 6) -#define PORTCR_PULMD_MASK (3 << 6) - static const unsigned int r8a73a4_portcr_offsets[] = { 0x00000000, 0x00001000, 0x00000000, 0x00001000, 0x00001000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00003000, 0x00003000, }; -static unsigned int r8a73a4_pinmux_get_bias(struct sh_pfc *pfc, - unsigned int pin) -{ - void __iomem *addr; - - addr = pfc->windows->virt + r8a73a4_portcr_offsets[pin >> 5] + pin; - - switch (ioread8(addr) & PORTCR_PULMD_MASK) { - case PORTCR_PULMD_UP: - return PIN_CONFIG_BIAS_PULL_UP; - case PORTCR_PULMD_DOWN: - return PIN_CONFIG_BIAS_PULL_DOWN; - case PORTCR_PULMD_OFF: - default: - return PIN_CONFIG_BIAS_DISABLE; - } -} - -static void r8a73a4_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, - unsigned int bias) +static void __iomem *r8a73a4_pin_to_portcr(struct sh_pfc *pfc, unsigned int pin) { - void __iomem *addr; - u32 value; - - addr = pfc->windows->virt + r8a73a4_portcr_offsets[pin >> 5] + pin; - value = ioread8(addr) & ~PORTCR_PULMD_MASK; - - switch (bias) { - case PIN_CONFIG_BIAS_PULL_UP: - value |= PORTCR_PULMD_UP; - break; - case PIN_CONFIG_BIAS_PULL_DOWN: - value |= PORTCR_PULMD_DOWN; - break; - } - - iowrite8(value, addr); + return pfc->windows->virt + r8a73a4_portcr_offsets[pin >> 5] + pin; } static const struct sh_pfc_soc_operations r8a73a4_pfc_ops = { - .get_bias = r8a73a4_pinmux_get_bias, - .set_bias = r8a73a4_pinmux_set_bias, + .get_bias = rmobile_pinmux_get_bias, + .set_bias = rmobile_pinmux_set_bias, + .pin_to_portcr = r8a73a4_pin_to_portcr, }; const struct sh_pfc_soc_info r8a73a4_pinmux_info = { diff --git a/drivers/pinctrl/renesas/pfc-r8a7740.c b/drivers/pinctrl/renesas/pfc-r8a7740.c index fdf1b0f09f57..4eac3899d69b 100644 --- a/drivers/pinctrl/renesas/pfc-r8a7740.c +++ b/drivers/pinctrl/renesas/pfc-r8a7740.c @@ -3672,11 +3672,6 @@ static const struct pinmux_irq pinmux_irqs[] = { PINMUX_IRQ(41, 167), /* IRQ31A */ }; -#define PORTnCR_PULMD_OFF (0 << 6) -#define PORTnCR_PULMD_DOWN (2 << 6) -#define PORTnCR_PULMD_UP (3 << 6) -#define PORTnCR_PULMD_MASK (3 << 6) - struct r8a7740_portcr_group { unsigned int end_pin; unsigned int offset; @@ -3686,7 +3681,7 @@ static const struct r8a7740_portcr_group r8a7740_portcr_offsets[] = { { 83, 0x0000 }, { 114, 0x1000 }, { 209, 0x2000 }, { 211, 0x3000 }, }; -static void __iomem *r8a7740_pinmux_portcr(struct sh_pfc *pfc, unsigned int pin) +static void __iomem *r8a7740_pin_to_portcr(struct sh_pfc *pfc, unsigned int pin) { unsigned int i; @@ -3701,43 +3696,10 @@ static void __iomem *r8a7740_pinmux_portcr(struct sh_pfc *pfc, unsigned int pin) return NULL; } -static unsigned int r8a7740_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin) -{ - void __iomem *addr = r8a7740_pinmux_portcr(pfc, pin); - u32 value = ioread8(addr) & PORTnCR_PULMD_MASK; - - switch (value) { - case PORTnCR_PULMD_UP: - return PIN_CONFIG_BIAS_PULL_UP; - case PORTnCR_PULMD_DOWN: - return PIN_CONFIG_BIAS_PULL_DOWN; - case PORTnCR_PULMD_OFF: - default: - return PIN_CONFIG_BIAS_DISABLE; - } -} - -static void r8a7740_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, - unsigned int bias) -{ - void __iomem *addr = r8a7740_pinmux_portcr(pfc, pin); - u32 value = ioread8(addr) & ~PORTnCR_PULMD_MASK; - - switch (bias) { - case PIN_CONFIG_BIAS_PULL_UP: - value |= PORTnCR_PULMD_UP; - break; - case PIN_CONFIG_BIAS_PULL_DOWN: - value |= PORTnCR_PULMD_DOWN; - break; - } - - iowrite8(value, addr); -} - static const struct sh_pfc_soc_operations r8a7740_pfc_ops = { - .get_bias = r8a7740_pinmux_get_bias, - .set_bias = r8a7740_pinmux_set_bias, + .get_bias = rmobile_pinmux_get_bias, + .set_bias = rmobile_pinmux_set_bias, + .pin_to_portcr = r8a7740_pin_to_portcr, }; const struct sh_pfc_soc_info r8a7740_pinmux_info = { diff --git a/drivers/pinctrl/renesas/pfc-sh73a0.c b/drivers/pinctrl/renesas/pfc-sh73a0.c index 96b91e95b1e1..ed6db809e80d 100644 --- a/drivers/pinctrl/renesas/pfc-sh73a0.c +++ b/drivers/pinctrl/renesas/pfc-sh73a0.c @@ -13,7 +13,6 @@ #include #include -#include "core.h" #include "sh_pfc.h" #define CPU_ALL_PORT(fn, pfx, sfx) \ @@ -4310,50 +4309,14 @@ static const struct regulator_init_data sh73a0_vccq_mc0_init_data = { * Pin bias */ -#define PORTnCR_PULMD_OFF (0 << 6) -#define PORTnCR_PULMD_DOWN (2 << 6) -#define PORTnCR_PULMD_UP (3 << 6) -#define PORTnCR_PULMD_MASK (3 << 6) - static const unsigned int sh73a0_portcr_offsets[] = { 0x00000000, 0x00001000, 0x00001000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00003000, 0x00003000, 0x00002000, }; -static unsigned int sh73a0_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin) +static void __iomem *sh73a0_pin_to_portcr(struct sh_pfc *pfc, unsigned int pin) { - void __iomem *addr = pfc->windows->virt - + sh73a0_portcr_offsets[pin >> 5] + pin; - u32 value = ioread8(addr) & PORTnCR_PULMD_MASK; - - switch (value) { - case PORTnCR_PULMD_UP: - return PIN_CONFIG_BIAS_PULL_UP; - case PORTnCR_PULMD_DOWN: - return PIN_CONFIG_BIAS_PULL_DOWN; - case PORTnCR_PULMD_OFF: - default: - return PIN_CONFIG_BIAS_DISABLE; - } -} - -static void sh73a0_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, - unsigned int bias) -{ - void __iomem *addr = pfc->windows->virt - + sh73a0_portcr_offsets[pin >> 5] + pin; - u32 value = ioread8(addr) & ~PORTnCR_PULMD_MASK; - - switch (bias) { - case PIN_CONFIG_BIAS_PULL_UP: - value |= PORTnCR_PULMD_UP; - break; - case PIN_CONFIG_BIAS_PULL_DOWN: - value |= PORTnCR_PULMD_DOWN; - break; - } - - iowrite8(value, addr); + return pfc->windows->virt + sh73a0_portcr_offsets[pin >> 5] + pin; } /* ----------------------------------------------------------------------------- @@ -4383,8 +4346,9 @@ static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc) static const struct sh_pfc_soc_operations sh73a0_pfc_ops = { .init = sh73a0_pinmux_soc_init, - .get_bias = sh73a0_pinmux_get_bias, - .set_bias = sh73a0_pinmux_set_bias, + .get_bias = rmobile_pinmux_get_bias, + .set_bias = rmobile_pinmux_set_bias, + .pin_to_portcr = sh73a0_pin_to_portcr, }; const struct sh_pfc_soc_info sh73a0_pinmux_info = { diff --git a/drivers/pinctrl/renesas/pinctrl.c b/drivers/pinctrl/renesas/pinctrl.c index 963d217b9403..b7ebbc877b54 100644 --- a/drivers/pinctrl/renesas/pinctrl.c +++ b/drivers/pinctrl/renesas/pinctrl.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -902,3 +903,42 @@ void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, sh_pfc_write(pfc, reg->puen, enable); } + +#define PORTnCR_PULMD_OFF (0 << 6) +#define PORTnCR_PULMD_DOWN (2 << 6) +#define PORTnCR_PULMD_UP (3 << 6) +#define PORTnCR_PULMD_MASK (3 << 6) + +unsigned int rmobile_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin) +{ + void __iomem *reg = pfc->info->ops->pin_to_portcr(pfc, pin); + u32 value = ioread8(reg) & PORTnCR_PULMD_MASK; + + switch (value) { + case PORTnCR_PULMD_UP: + return PIN_CONFIG_BIAS_PULL_UP; + case PORTnCR_PULMD_DOWN: + return PIN_CONFIG_BIAS_PULL_DOWN; + case PORTnCR_PULMD_OFF: + default: + return PIN_CONFIG_BIAS_DISABLE; + } +} + +void rmobile_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, + unsigned int bias) +{ + void __iomem *reg = pfc->info->ops->pin_to_portcr(pfc, pin); + u32 value = ioread8(reg) & ~PORTnCR_PULMD_MASK; + + switch (bias) { + case PIN_CONFIG_BIAS_PULL_UP: + value |= PORTnCR_PULMD_UP; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + value |= PORTnCR_PULMD_DOWN; + break; + } + + iowrite8(value, reg); +} diff --git a/drivers/pinctrl/renesas/sh_pfc.h b/drivers/pinctrl/renesas/sh_pfc.h index 2d511c7280fa..8dc0fbb012b0 100644 --- a/drivers/pinctrl/renesas/sh_pfc.h +++ b/drivers/pinctrl/renesas/sh_pfc.h @@ -273,6 +273,7 @@ struct sh_pfc_soc_operations { void (*set_bias)(struct sh_pfc *pfc, unsigned int pin, unsigned int bias); int (*pin_to_pocctrl)(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl); + void __iomem * (*pin_to_portcr)(struct sh_pfc *pfc, unsigned int pin); }; struct sh_pfc_soc_info { @@ -780,4 +781,8 @@ unsigned int rcar_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin); void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, unsigned int bias); +unsigned int rmobile_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin); +void rmobile_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, + unsigned int bias); + #endif /* __SH_PFC_H */ -- cgit v1.2.3 From 93d6c7d676d2640e223f6b3fac11c76173655a44 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 3 Mar 2021 14:26:17 +0100 Subject: pinctrl: renesas: Add PORT_GP_CFG_7 macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add PORT_GP_CFG_7() and PORT_GP_7() helper macros, to be used by the r8a7791 subdriver. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20210303132619.3938128-5-geert+renesas@glider.be --- drivers/pinctrl/renesas/sh_pfc.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/renesas/sh_pfc.h b/drivers/pinctrl/renesas/sh_pfc.h index 8dc0fbb012b0..fc8391712af8 100644 --- a/drivers/pinctrl/renesas/sh_pfc.h +++ b/drivers/pinctrl/renesas/sh_pfc.h @@ -479,9 +479,13 @@ extern const struct sh_pfc_soc_info shx3_pinmux_info; PORT_GP_CFG_1(bank, 5, fn, sfx, cfg) #define PORT_GP_6(bank, fn, sfx) PORT_GP_CFG_6(bank, fn, sfx, 0) -#define PORT_GP_CFG_8(bank, fn, sfx, cfg) \ +#define PORT_GP_CFG_7(bank, fn, sfx, cfg) \ PORT_GP_CFG_6(bank, fn, sfx, cfg), \ - PORT_GP_CFG_1(bank, 6, fn, sfx, cfg), \ + PORT_GP_CFG_1(bank, 6, fn, sfx, cfg) +#define PORT_GP_7(bank, fn, sfx) PORT_GP_CFG_7(bank, fn, sfx, 0) + +#define PORT_GP_CFG_8(bank, fn, sfx, cfg) \ + PORT_GP_CFG_7(bank, fn, sfx, cfg), \ PORT_GP_CFG_1(bank, 7, fn, sfx, cfg) #define PORT_GP_8(bank, fn, sfx) PORT_GP_CFG_8(bank, fn, sfx, 0) -- cgit v1.2.3 From 1d3928a3e69cd6ec0ea837d3eeccb2ff604b5072 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 3 Mar 2021 14:26:18 +0100 Subject: pinctrl: renesas: Add support for R-Car SoCs with pull-down only pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, the common R-Car bias handling supports pin controllers with either: 1. Separate pin Pull-Enable (PUEN) and pin Pull-Up/Down control (PUD) registers, for controlling both pin pull-up and pin pull-down, 2. A single pin Pull-Up control register (PUPR), for controlling pin pull-up. Add support for a variant of #2, where some bits in the single pin Pull-Up control register (PUPR) control pin pull-down instead of pin pull-up. This is the case for the "ASEBRK#/ACK" pin on R-Car M2-W, M2-N, and E2, and the "ACK" pin on RZ/G1M, RZ/G1N, RZ/G1E, and RZ/G1C. To describe such a register, SoC-specific drivers need to provide two instances of pinmux_bias_reg: a first one with the puen field filled in, listing pins with pull-up functionality, and a second one with the pud field filled in, listing pins with pull-down functionality. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20210303132619.3938128-6-geert+renesas@glider.be --- drivers/pinctrl/renesas/pinctrl.c | 49 +++++++++++++++++++++++++-------------- drivers/pinctrl/renesas/sh_pfc.h | 4 ++-- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/drivers/pinctrl/renesas/pinctrl.c b/drivers/pinctrl/renesas/pinctrl.c index b7ebbc877b54..bb488af29862 100644 --- a/drivers/pinctrl/renesas/pinctrl.c +++ b/drivers/pinctrl/renesas/pinctrl.c @@ -847,7 +847,7 @@ rcar_pin_to_bias_reg(const struct sh_pfc *pfc, unsigned int pin, { unsigned int i, j; - for (i = 0; pfc->info->bias_regs[i].puen; i++) { + for (i = 0; pfc->info->bias_regs[i].puen || pfc->info->bias_regs[i].pud; i++) { for (j = 0; j < ARRAY_SIZE(pfc->info->bias_regs[i].pins); j++) { if (pfc->info->bias_regs[i].pins[j] == pin) { *bit = j; @@ -870,12 +870,19 @@ unsigned int rcar_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin) if (!reg) return PIN_CONFIG_BIAS_DISABLE; - if (!(sh_pfc_read(pfc, reg->puen) & BIT(bit))) - return PIN_CONFIG_BIAS_DISABLE; - else if (!reg->pud || (sh_pfc_read(pfc, reg->pud) & BIT(bit))) - return PIN_CONFIG_BIAS_PULL_UP; - else - return PIN_CONFIG_BIAS_PULL_DOWN; + if (reg->puen) { + if (!(sh_pfc_read(pfc, reg->puen) & BIT(bit))) + return PIN_CONFIG_BIAS_DISABLE; + else if (!reg->pud || (sh_pfc_read(pfc, reg->pud) & BIT(bit))) + return PIN_CONFIG_BIAS_PULL_UP; + else + return PIN_CONFIG_BIAS_PULL_DOWN; + } else { + if (sh_pfc_read(pfc, reg->pud) & BIT(bit)) + return PIN_CONFIG_BIAS_PULL_DOWN; + else + return PIN_CONFIG_BIAS_DISABLE; + } } void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, @@ -889,19 +896,27 @@ void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, if (!reg) return; - enable = sh_pfc_read(pfc, reg->puen) & ~BIT(bit); - if (bias != PIN_CONFIG_BIAS_DISABLE) - enable |= BIT(bit); + if (reg->puen) { + enable = sh_pfc_read(pfc, reg->puen) & ~BIT(bit); + if (bias != PIN_CONFIG_BIAS_DISABLE) + enable |= BIT(bit); - if (reg->pud) { - updown = sh_pfc_read(pfc, reg->pud) & ~BIT(bit); - if (bias == PIN_CONFIG_BIAS_PULL_UP) - updown |= BIT(bit); + if (reg->pud) { + updown = sh_pfc_read(pfc, reg->pud) & ~BIT(bit); + if (bias == PIN_CONFIG_BIAS_PULL_UP) + updown |= BIT(bit); - sh_pfc_write(pfc, reg->pud, updown); - } + sh_pfc_write(pfc, reg->pud, updown); + } - sh_pfc_write(pfc, reg->puen, enable); + sh_pfc_write(pfc, reg->puen, enable); + } else { + enable = sh_pfc_read(pfc, reg->pud) & ~BIT(bit); + if (bias == PIN_CONFIG_BIAS_PULL_DOWN) + enable |= BIT(bit); + + sh_pfc_write(pfc, reg->pud, enable); + } } #define PORTnCR_PULMD_OFF (0 << 6) diff --git a/drivers/pinctrl/renesas/sh_pfc.h b/drivers/pinctrl/renesas/sh_pfc.h index fc8391712af8..320898861c4b 100644 --- a/drivers/pinctrl/renesas/sh_pfc.h +++ b/drivers/pinctrl/renesas/sh_pfc.h @@ -188,9 +188,9 @@ struct pinmux_drive_reg { .reg = r, \ .fields = -struct pinmux_bias_reg { +struct pinmux_bias_reg { /* At least one of puen/pud must exist */ u32 puen; /* Pull-enable or pull-up control register */ - u32 pud; /* Pull-up/down control register (optional) */ + u32 pud; /* Pull-up/down or pull-down control register */ const u16 pins[32]; }; -- cgit v1.2.3 From 61232cd6efca6e4d2705993850d014343ba604c4 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 3 Mar 2021 14:26:19 +0100 Subject: pinctrl: renesas: r8a7791: Add bias pinconf support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement support for pull-up (most pins) and pull-down (ASEBRK#/ACK) handling for R-Car M2-W and M2-N, and RZ/G1M and RZ/G1N SoCs, using the common R-Car bias handling. Note that on RZ/G1 SoCs, the "ASEBRK#/ACK" pin is called "ACK", but the code doesn't handle that naming difference. Hence users should use the R-Car naming in DTS files. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20210303132619.3938128-7-geert+renesas@glider.be --- drivers/pinctrl/renesas/pfc-r8a7791.c | 387 ++++++++++++++++++++++++++++++++-- 1 file changed, 371 insertions(+), 16 deletions(-) diff --git a/drivers/pinctrl/renesas/pfc-r8a7791.c b/drivers/pinctrl/renesas/pfc-r8a7791.c index 6fce9fe2e98f..fe4ccab6b0b8 100644 --- a/drivers/pinctrl/renesas/pfc-r8a7791.c +++ b/drivers/pinctrl/renesas/pfc-r8a7791.c @@ -16,22 +16,50 @@ * which case they support both 3.3V and 1.8V signalling. */ #define CPU_ALL_GP(fn, sfx) \ - PORT_GP_32(0, fn, sfx), \ - PORT_GP_26(1, fn, sfx), \ - PORT_GP_32(2, fn, sfx), \ - PORT_GP_32(3, fn, sfx), \ - PORT_GP_32(4, fn, sfx), \ - PORT_GP_32(5, fn, sfx), \ - PORT_GP_CFG_24(6, fn, sfx, SH_PFC_PIN_CFG_IO_VOLTAGE), \ - PORT_GP_1(6, 24, fn, sfx), \ - PORT_GP_1(6, 25, fn, sfx), \ - PORT_GP_1(6, 26, fn, sfx), \ - PORT_GP_1(6, 27, fn, sfx), \ - PORT_GP_1(6, 28, fn, sfx), \ - PORT_GP_1(6, 29, fn, sfx), \ - PORT_GP_1(6, 30, fn, sfx), \ - PORT_GP_1(6, 31, fn, sfx), \ - PORT_GP_26(7, fn, sfx) + PORT_GP_CFG_32(0, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_26(1, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_32(2, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_32(3, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_32(4, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_32(5, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_24(6, fn, sfx, SH_PFC_PIN_CFG_IO_VOLTAGE | SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(6, 24, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(6, 25, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(6, 26, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(6, 27, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(6, 28, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(6, 29, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(6, 30, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(6, 31, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_7(7, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_1(7, 7, fn, sfx), \ + PORT_GP_1(7, 8, fn, sfx), \ + PORT_GP_1(7, 9, fn, sfx), \ + PORT_GP_CFG_1(7, 10, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(7, 11, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(7, 12, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(7, 13, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(7, 14, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(7, 15, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(7, 16, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(7, 17, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(7, 18, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(7, 19, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(7, 20, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(7, 21, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(7, 22, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(7, 23, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(7, 24, fn, sfx, SH_PFC_PIN_CFG_PULL_UP), \ + PORT_GP_CFG_1(7, 25, fn, sfx, SH_PFC_PIN_CFG_PULL_UP) + +#define CPU_ALL_NOGP(fn) \ + PIN_NOGP_CFG(ASEBRK_N_ACK, "ASEBRK#/ACK", fn, SH_PFC_PIN_CFG_PULL_DOWN), \ + PIN_NOGP_CFG(AVS1, "AVS1", fn, SH_PFC_PIN_CFG_PULL_UP), \ + PIN_NOGP_CFG(AVS2, "AVS2", fn, SH_PFC_PIN_CFG_PULL_UP), \ + PIN_NOGP_CFG(TCK, "TCK", fn, SH_PFC_PIN_CFG_PULL_UP), \ + PIN_NOGP_CFG(TDI, "TDI", fn, SH_PFC_PIN_CFG_PULL_UP), \ + PIN_NOGP_CFG(TMS, "TMS", fn, SH_PFC_PIN_CFG_PULL_UP), \ + PIN_NOGP_CFG(TRST_N, "TRST#", fn, SH_PFC_PIN_CFG_PULL_UP) enum { PINMUX_RESERVED = 0, @@ -1696,8 +1724,17 @@ static const u16 pinmux_data[] = { PINMUX_IPSR_MSEL(IP16_11_10, CAN1_RX_B, SEL_CAN1_1), }; +/* + * Pins not associated with a GPIO port. + */ +enum { + GP_ASSIGN_LAST(), + NOGP_ALL(), +}; + static const struct sh_pfc_pin pinmux_pins[] = { PINMUX_GPIO_GP_ALL(), + PINMUX_NOGP_ALL(), }; #if defined(CONFIG_PINCTRL_PFC_R8A7791) || defined(CONFIG_PINCTRL_PFC_R8A7793) @@ -6645,8 +6682,322 @@ static int r8a7791_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin, u32 *poc return 31 - (pin & 0x1f); } +static const struct pinmux_bias_reg pinmux_bias_regs[] = { + { PINMUX_BIAS_REG("PUPR0", 0xe6060100, "N/A", 0) { + [ 0] = RCAR_GP_PIN(1, 4), /* A20 */ + [ 1] = RCAR_GP_PIN(1, 5), /* A21 */ + [ 2] = RCAR_GP_PIN(1, 6), /* A22 */ + [ 3] = RCAR_GP_PIN(1, 7), /* A23 */ + [ 4] = RCAR_GP_PIN(1, 8), /* A24 */ + [ 5] = RCAR_GP_PIN(6, 31), /* DU0_DOTCLKIN */ + [ 6] = RCAR_GP_PIN(0, 0), /* D0 */ + [ 7] = RCAR_GP_PIN(0, 1), /* D1 */ + [ 8] = RCAR_GP_PIN(0, 2), /* D2 */ + [ 9] = RCAR_GP_PIN(0, 3), /* D3 */ + [10] = RCAR_GP_PIN(0, 4), /* D4 */ + [11] = RCAR_GP_PIN(0, 5), /* D5 */ + [12] = RCAR_GP_PIN(0, 6), /* D6 */ + [13] = RCAR_GP_PIN(0, 7), /* D7 */ + [14] = RCAR_GP_PIN(0, 8), /* D8 */ + [15] = RCAR_GP_PIN(0, 9), /* D9 */ + [16] = RCAR_GP_PIN(0, 10), /* D10 */ + [17] = RCAR_GP_PIN(0, 11), /* D11 */ + [18] = RCAR_GP_PIN(0, 12), /* D12 */ + [19] = RCAR_GP_PIN(0, 13), /* D13 */ + [20] = RCAR_GP_PIN(0, 14), /* D14 */ + [21] = RCAR_GP_PIN(0, 15), /* D15 */ + [22] = RCAR_GP_PIN(0, 16), /* A0 */ + [23] = RCAR_GP_PIN(0, 17), /* A1 */ + [24] = RCAR_GP_PIN(0, 18), /* A2 */ + [25] = RCAR_GP_PIN(0, 19), /* A3 */ + [26] = RCAR_GP_PIN(0, 20), /* A4 */ + [27] = RCAR_GP_PIN(0, 21), /* A5 */ + [28] = RCAR_GP_PIN(0, 22), /* A6 */ + [29] = RCAR_GP_PIN(0, 23), /* A7 */ + [30] = RCAR_GP_PIN(0, 24), /* A8 */ + [31] = RCAR_GP_PIN(0, 25), /* A9 */ + } }, + { PINMUX_BIAS_REG("PUPR1", 0xe6060104, "N/A", 0) { + [ 0] = RCAR_GP_PIN(0, 26), /* A10 */ + [ 1] = RCAR_GP_PIN(0, 27), /* A11 */ + [ 2] = RCAR_GP_PIN(0, 28), /* A12 */ + [ 3] = RCAR_GP_PIN(0, 29), /* A13 */ + [ 4] = RCAR_GP_PIN(0, 30), /* A14 */ + [ 5] = RCAR_GP_PIN(0, 31), /* A15 */ + [ 6] = RCAR_GP_PIN(1, 0), /* A16 */ + [ 7] = RCAR_GP_PIN(1, 1), /* A17 */ + [ 8] = RCAR_GP_PIN(1, 2), /* A18 */ + [ 9] = RCAR_GP_PIN(1, 3), /* A19 */ + [10] = PIN_TRST_N, /* TRST# */ + [11] = PIN_TCK, /* TCK */ + [12] = PIN_TMS, /* TMS */ + [13] = PIN_TDI, /* TDI */ + [14] = RCAR_GP_PIN(1, 11), /* CS1#/A26 */ + [15] = RCAR_GP_PIN(1, 12), /* EX_CS0# */ + [16] = RCAR_GP_PIN(1, 13), /* EX_CS1# */ + [17] = RCAR_GP_PIN(1, 14), /* EX_CS2# */ + [18] = RCAR_GP_PIN(1, 15), /* EX_CS3# */ + [19] = RCAR_GP_PIN(1, 16), /* EX_CS4# */ + [20] = RCAR_GP_PIN(1, 17), /* EX_CS5# */ + [21] = RCAR_GP_PIN(1, 18), /* BS# */ + [22] = RCAR_GP_PIN(1, 19), /* RD# */ + [23] = RCAR_GP_PIN(1, 20), /* RD/WR# */ + [24] = RCAR_GP_PIN(1, 21), /* WE0# */ + [25] = RCAR_GP_PIN(1, 22), /* WE1# */ + [26] = RCAR_GP_PIN(1, 23), /* EX_WAIT0 */ + [27] = RCAR_GP_PIN(1, 24), /* DREQ0 */ + [28] = RCAR_GP_PIN(1, 25), /* DACK0 */ + [29] = RCAR_GP_PIN(5, 31), /* SPEEDIN */ + [30] = RCAR_GP_PIN(2, 0), /* SSI_SCK0129 */ + [31] = RCAR_GP_PIN(2, 1), /* SSI_WS0129 */ + } }, + { PINMUX_BIAS_REG("PUPR2", 0xe6060108, "N/A", 0) { + [ 0] = RCAR_GP_PIN(2, 2), /* SSI_SDATA0 */ + [ 1] = RCAR_GP_PIN(2, 3), /* SSI_SCK1 */ + [ 2] = RCAR_GP_PIN(2, 4), /* SSI_WS1 */ + [ 3] = RCAR_GP_PIN(2, 5), /* SSI_SDATA1 */ + [ 4] = RCAR_GP_PIN(2, 6), /* SSI_SCK2 */ + [ 5] = RCAR_GP_PIN(2, 7), /* SSI_WS2 */ + [ 6] = RCAR_GP_PIN(2, 8), /* SSI_SDATA2 */ + [ 7] = RCAR_GP_PIN(2, 9), /* SSI_SCK34 */ + [ 8] = RCAR_GP_PIN(2, 10), /* SSI_WS34 */ + [ 9] = RCAR_GP_PIN(2, 11), /* SSI_SDATA3 */ + [10] = RCAR_GP_PIN(2, 12), /* SSI_SCK4 */ + [11] = RCAR_GP_PIN(2, 13), /* SSI_WS4 */ + [12] = RCAR_GP_PIN(2, 14), /* SSI_SDATA4 */ + [13] = RCAR_GP_PIN(2, 15), /* SSI_SCK5 */ + [14] = RCAR_GP_PIN(2, 16), /* SSI_WS5 */ + [15] = RCAR_GP_PIN(2, 17), /* SSI_SDATA5 */ + [16] = RCAR_GP_PIN(2, 18), /* SSI_SCK6 */ + [17] = RCAR_GP_PIN(2, 19), /* SSI_WS6 */ + [18] = RCAR_GP_PIN(2, 20), /* SSI_SDATA6 */ + [19] = RCAR_GP_PIN(2, 21), /* SSI_SCK78 */ + [20] = RCAR_GP_PIN(2, 22), /* SSI_WS78 */ + [21] = RCAR_GP_PIN(2, 23), /* SSI_SDATA7 */ + [22] = RCAR_GP_PIN(2, 24), /* SSI_SDATA8 */ + [23] = RCAR_GP_PIN(2, 25), /* SSI_SCK9 */ + [24] = RCAR_GP_PIN(2, 26), /* SSI_WS9 */ + [25] = RCAR_GP_PIN(2, 27), /* SSI_SDATA9 */ + [26] = RCAR_GP_PIN(2, 28), /* AUDIO_CLKA */ + [27] = RCAR_GP_PIN(2, 29), /* AUDIO_CLKB */ + [28] = RCAR_GP_PIN(2, 30), /* AUDIO_CLKC */ + [29] = RCAR_GP_PIN(2, 31), /* AUDIO_CLKOUT */ + [30] = RCAR_GP_PIN(7, 10), /* IRQ0 */ + [31] = RCAR_GP_PIN(7, 11), /* IRQ1 */ + } }, + { PINMUX_BIAS_REG("PUPR3", 0xe606010c, "N/A", 0) { + [ 0] = RCAR_GP_PIN(7, 12), /* IRQ2 */ + [ 1] = RCAR_GP_PIN(7, 13), /* IRQ3 */ + [ 2] = RCAR_GP_PIN(7, 14), /* IRQ4 */ + [ 3] = RCAR_GP_PIN(7, 15), /* IRQ5 */ + [ 4] = RCAR_GP_PIN(7, 16), /* IRQ6 */ + [ 5] = RCAR_GP_PIN(7, 17), /* IRQ7 */ + [ 6] = RCAR_GP_PIN(7, 18), /* IRQ8 */ + [ 7] = RCAR_GP_PIN(7, 19), /* IRQ9 */ + [ 8] = RCAR_GP_PIN(3, 0), /* DU1_DR0 */ + [ 9] = RCAR_GP_PIN(3, 1), /* DU1_DR1 */ + [10] = RCAR_GP_PIN(3, 2), /* DU1_DR2 */ + [11] = RCAR_GP_PIN(3, 3), /* DU1_DR3 */ + [12] = RCAR_GP_PIN(3, 4), /* DU1_DR4 */ + [13] = RCAR_GP_PIN(3, 5), /* DU1_DR5 */ + [14] = RCAR_GP_PIN(3, 6), /* DU1_DR6 */ + [15] = RCAR_GP_PIN(3, 7), /* DU1_DR7 */ + [16] = RCAR_GP_PIN(3, 8), /* DU1_DG0 */ + [17] = RCAR_GP_PIN(3, 9), /* DU1_DG1 */ + [18] = RCAR_GP_PIN(3, 10), /* DU1_DG2 */ + [19] = RCAR_GP_PIN(3, 11), /* DU1_DG3 */ + [20] = RCAR_GP_PIN(3, 12), /* DU1_DG4 */ + [21] = RCAR_GP_PIN(3, 13), /* DU1_DG5 */ + [22] = RCAR_GP_PIN(3, 14), /* DU1_DG6 */ + [23] = RCAR_GP_PIN(3, 15), /* DU1_DG7 */ + [24] = RCAR_GP_PIN(3, 16), /* DU1_DB0 */ + [25] = RCAR_GP_PIN(3, 17), /* DU1_DB1 */ + [26] = RCAR_GP_PIN(3, 18), /* DU1_DB2 */ + [27] = RCAR_GP_PIN(3, 19), /* DU1_DB3 */ + [28] = RCAR_GP_PIN(3, 20), /* DU1_DB4 */ + [29] = RCAR_GP_PIN(3, 21), /* DU1_DB5 */ + [30] = RCAR_GP_PIN(3, 22), /* DU1_DB6 */ + [31] = RCAR_GP_PIN(3, 23), /* DU1_DB7 */ + } }, + { PINMUX_BIAS_REG("PUPR4", 0xe6060110, "N/A", 0) { + [ 0] = RCAR_GP_PIN(3, 24), /* DU1_DOTCLKIN */ + [ 1] = RCAR_GP_PIN(3, 25), /* DU1_DOTCLKOUT0 */ + [ 2] = RCAR_GP_PIN(3, 26), /* DU1_DOTCLKOUT1 */ + [ 3] = RCAR_GP_PIN(3, 27), /* DU1_EXHSYNC_DU1_HSYNC */ + [ 4] = RCAR_GP_PIN(3, 28), /* DU1_EXVSYNC_DU1_VSYNC */ + [ 5] = RCAR_GP_PIN(3, 29), /* DU1_EXODDF_DU1_ODDF_DISP_CDE */ + [ 6] = RCAR_GP_PIN(3, 30), /* DU1_DISP */ + [ 7] = RCAR_GP_PIN(3, 31), /* DU1_CDE */ + [ 8] = RCAR_GP_PIN(4, 0), /* VI0_CLK */ + [ 9] = RCAR_GP_PIN(4, 1), /* VI0_CLKENB */ + [10] = RCAR_GP_PIN(4, 2), /* VI0_FIELD */ + [11] = RCAR_GP_PIN(4, 3), /* VI0_HSYNC# */ + [12] = RCAR_GP_PIN(4, 4), /* VI0_VSYNC# */ + [13] = RCAR_GP_PIN(4, 5), /* VI0_DATA0_VI0_B0 */ + [14] = RCAR_GP_PIN(4, 6), /* VI0_DATA1_VI0_B1 */ + [15] = RCAR_GP_PIN(4, 7), /* VI0_DATA2_VI0_B2 */ + [16] = RCAR_GP_PIN(4, 8), /* VI0_DATA3_VI0_B3 */ + [17] = RCAR_GP_PIN(4, 9), /* VI0_DATA4_VI0_B4 */ + [18] = RCAR_GP_PIN(4, 10), /* VI0_DATA5_VI0_B5 */ + [19] = RCAR_GP_PIN(4, 11), /* VI0_DATA6_VI0_B6 */ + [20] = RCAR_GP_PIN(4, 12), /* VI0_DATA7_VI0_B7 */ + [21] = RCAR_GP_PIN(4, 13), /* VI0_G0 */ + [22] = RCAR_GP_PIN(4, 14), /* VI0_G1 */ + [23] = RCAR_GP_PIN(4, 15), /* VI0_G2 */ + [24] = RCAR_GP_PIN(4, 16), /* VI0_G3 */ + [25] = RCAR_GP_PIN(4, 17), /* VI0_G4 */ + [26] = RCAR_GP_PIN(4, 18), /* VI0_G5 */ + [27] = RCAR_GP_PIN(4, 19), /* VI0_G6 */ + [28] = RCAR_GP_PIN(4, 20), /* VI0_G7 */ + [29] = RCAR_GP_PIN(4, 21), /* VI0_R0 */ + [30] = RCAR_GP_PIN(4, 22), /* VI0_R1 */ + [31] = RCAR_GP_PIN(4, 23), /* VI0_R2 */ + } }, + { PINMUX_BIAS_REG("PUPR5", 0xe6060114, "N/A", 0) { + [ 0] = RCAR_GP_PIN(4, 24), /* VI0_R3 */ + [ 1] = RCAR_GP_PIN(4, 25), /* VI0_R4 */ + [ 2] = RCAR_GP_PIN(4, 26), /* VI0_R5 */ + [ 3] = RCAR_GP_PIN(4, 27), /* VI0_R6 */ + [ 4] = RCAR_GP_PIN(4, 28), /* VI0_R7 */ + [ 5] = RCAR_GP_PIN(5, 0), /* VI1_HSYNC# */ + [ 6] = RCAR_GP_PIN(5, 1), /* VI1_VSYNC# */ + [ 7] = RCAR_GP_PIN(5, 2), /* VI1_CLKENB */ + [ 8] = RCAR_GP_PIN(5, 3), /* VI1_FIELD */ + [ 9] = RCAR_GP_PIN(5, 4), /* VI1_CLK */ + [10] = RCAR_GP_PIN(5, 5), /* VI1_DATA0 */ + [11] = RCAR_GP_PIN(5, 6), /* VI1_DATA1 */ + [12] = RCAR_GP_PIN(5, 7), /* VI1_DATA2 */ + [13] = RCAR_GP_PIN(5, 8), /* VI1_DATA3 */ + [14] = RCAR_GP_PIN(5, 9), /* VI1_DATA4 */ + [15] = RCAR_GP_PIN(5, 10), /* VI1_DATA5 */ + [16] = RCAR_GP_PIN(5, 11), /* VI1_DATA6 */ + [17] = RCAR_GP_PIN(5, 12), /* VI1_DATA7 */ + [18] = RCAR_GP_PIN(5, 13), /* ETH_MDIO */ + [19] = RCAR_GP_PIN(5, 14), /* ETH_CRS_DV */ + [20] = RCAR_GP_PIN(5, 15), /* ETH_RX_ER */ + [21] = RCAR_GP_PIN(5, 16), /* ETH_RXD0 */ + [22] = RCAR_GP_PIN(5, 17), /* ETH_RXD1 */ + [23] = RCAR_GP_PIN(5, 18), /* ETH_LINK */ + [24] = RCAR_GP_PIN(5, 19), /* ETH_REFCLK */ + [25] = RCAR_GP_PIN(5, 20), /* ETH_TXD1 */ + [26] = RCAR_GP_PIN(5, 21), /* ETH_TX_EN */ + [27] = RCAR_GP_PIN(5, 22), /* ETH_MAGIC */ + [28] = RCAR_GP_PIN(5, 23), /* ETH_TXD0 */ + [29] = RCAR_GP_PIN(5, 24), /* ETH_MDC */ + [30] = RCAR_GP_PIN(5, 25), /* STP_IVCXO27_0 */ + [31] = RCAR_GP_PIN(5, 26), /* STP_ISCLK_0 */ + } }, + { PINMUX_BIAS_REG("PUPR6", 0xe6060118, "N/A", 0) { + [ 0] = RCAR_GP_PIN(5, 27), /* STP_ISD_0 */ + [ 1] = RCAR_GP_PIN(5, 28), /* STP_ISEN_0 */ + [ 2] = RCAR_GP_PIN(5, 29), /* STP_ISSYNC_0 */ + [ 3] = RCAR_GP_PIN(5, 30), /* STP_OPWM_0 */ + [ 4] = RCAR_GP_PIN(6, 0), /* SD0_CLK */ + [ 5] = RCAR_GP_PIN(6, 1), /* SD0_CMD */ + [ 6] = RCAR_GP_PIN(6, 2), /* SD0_DATA0 */ + [ 7] = RCAR_GP_PIN(6, 3), /* SD0_DATA1 */ + [ 8] = RCAR_GP_PIN(6, 4), /* SD0_DATA2 */ + [ 9] = RCAR_GP_PIN(6, 5), /* SD0_DATA3 */ + [10] = RCAR_GP_PIN(6, 6), /* SD0_CD */ + [11] = RCAR_GP_PIN(6, 7), /* SD0_WP */ + [12] = RCAR_GP_PIN(6, 8), /* SD2_CLK */ + [13] = RCAR_GP_PIN(6, 9), /* SD2_CMD */ + [14] = RCAR_GP_PIN(6, 10), /* SD2_DATA0 */ + [15] = RCAR_GP_PIN(6, 11), /* SD2_DATA1 */ + [16] = RCAR_GP_PIN(6, 12), /* SD2_DATA2 */ + [17] = RCAR_GP_PIN(6, 13), /* SD2_DATA3 */ + [18] = RCAR_GP_PIN(6, 14), /* SD2_CD */ + [19] = RCAR_GP_PIN(6, 15), /* SD2_WP */ + [20] = RCAR_GP_PIN(6, 16), /* SD3_CLK */ + [21] = RCAR_GP_PIN(6, 17), /* SD3_CMD */ + [22] = RCAR_GP_PIN(6, 18), /* SD3_DATA0 */ + [23] = RCAR_GP_PIN(6, 19), /* SD3_DATA1 */ + [24] = RCAR_GP_PIN(6, 20), /* SD3_DATA2 */ + [25] = RCAR_GP_PIN(6, 21), /* SD3_DATA3 */ + [26] = RCAR_GP_PIN(6, 22), /* SD3_CD */ + [27] = RCAR_GP_PIN(6, 23), /* SD3_WP */ + [28] = RCAR_GP_PIN(6, 24), /* MSIOF0_SCK */ + [29] = RCAR_GP_PIN(6, 25), /* MSIOF0_SYNC */ + [30] = RCAR_GP_PIN(6, 26), /* MSIOF0_TXD */ + [31] = RCAR_GP_PIN(6, 27), /* MSIOF0_RXD */ + } }, + { PINMUX_BIAS_REG("PUPR7", 0xe606011c, "N/A", 0) { + /* PUPR7 pull-up pins */ + [ 0] = RCAR_GP_PIN(6, 28), /* MSIOF0_SS1 */ + [ 1] = RCAR_GP_PIN(6, 29), /* MSIOF0_SS2 */ + [ 2] = RCAR_GP_PIN(4, 29), /* SIM0_RST */ + [ 3] = RCAR_GP_PIN(4, 30), /* SIM0_CLK */ + [ 4] = RCAR_GP_PIN(4, 31), /* SIM0_D */ + [ 5] = RCAR_GP_PIN(7, 20), /* GPS_CLK */ + [ 6] = RCAR_GP_PIN(7, 21), /* GPS_SIGN */ + [ 7] = RCAR_GP_PIN(7, 22), /* GPS_MAG */ + [ 8] = RCAR_GP_PIN(7, 0), /* HCTS0# */ + [ 9] = RCAR_GP_PIN(7, 1), /* HRTS0# */ + [10] = RCAR_GP_PIN(7, 2), /* HSCK0 */ + [11] = RCAR_GP_PIN(7, 3), /* HRX0 */ + [12] = RCAR_GP_PIN(7, 4), /* HTX0 */ + [13] = RCAR_GP_PIN(7, 5), /* HRX1 */ + [14] = RCAR_GP_PIN(7, 6), /* HTX1 */ + [15] = SH_PFC_PIN_NONE, + [16] = SH_PFC_PIN_NONE, + [17] = SH_PFC_PIN_NONE, + [18] = RCAR_GP_PIN(1, 9), /* A25 */ + [19] = SH_PFC_PIN_NONE, + [20] = RCAR_GP_PIN(1, 10), /* CS0# */ + [21] = RCAR_GP_PIN(7, 23), /* USB0_PWEN */ + [22] = RCAR_GP_PIN(7, 24), /* USB0_OVC */ + [23] = RCAR_GP_PIN(7, 25), /* USB1_PWEN */ + [24] = RCAR_GP_PIN(6, 30), /* USB1_OVC */ + [25] = PIN_AVS1, /* AVS1 */ + [26] = PIN_AVS2, /* AVS2 */ + [27] = SH_PFC_PIN_NONE, + [28] = SH_PFC_PIN_NONE, + [29] = SH_PFC_PIN_NONE, + [30] = SH_PFC_PIN_NONE, + [31] = SH_PFC_PIN_NONE, + } }, + { PINMUX_BIAS_REG("N/A", 0, "PUPR7", 0xe606011c) { + /* PUPR7 pull-down pins */ + [ 0] = SH_PFC_PIN_NONE, + [ 1] = SH_PFC_PIN_NONE, + [ 2] = SH_PFC_PIN_NONE, + [ 3] = SH_PFC_PIN_NONE, + [ 4] = SH_PFC_PIN_NONE, + [ 5] = SH_PFC_PIN_NONE, + [ 6] = SH_PFC_PIN_NONE, + [ 7] = SH_PFC_PIN_NONE, + [ 8] = SH_PFC_PIN_NONE, + [ 9] = SH_PFC_PIN_NONE, + [10] = SH_PFC_PIN_NONE, + [11] = SH_PFC_PIN_NONE, + [12] = SH_PFC_PIN_NONE, + [13] = SH_PFC_PIN_NONE, + [14] = SH_PFC_PIN_NONE, + [15] = SH_PFC_PIN_NONE, + [16] = SH_PFC_PIN_NONE, + [17] = SH_PFC_PIN_NONE, + [18] = SH_PFC_PIN_NONE, + [19] = PIN_ASEBRK_N_ACK, /* ASEBRK#/ACK */ + [20] = SH_PFC_PIN_NONE, + [21] = SH_PFC_PIN_NONE, + [22] = SH_PFC_PIN_NONE, + [23] = SH_PFC_PIN_NONE, + [24] = SH_PFC_PIN_NONE, + [25] = SH_PFC_PIN_NONE, + [26] = SH_PFC_PIN_NONE, + [27] = SH_PFC_PIN_NONE, + [28] = SH_PFC_PIN_NONE, + [29] = SH_PFC_PIN_NONE, + [30] = SH_PFC_PIN_NONE, + [31] = SH_PFC_PIN_NONE, + } }, + { /* sentinel */ }, +}; + static const struct sh_pfc_soc_operations r8a7791_pinmux_ops = { .pin_to_pocctrl = r8a7791_pin_to_pocctrl, + .get_bias = rcar_pinmux_get_bias, + .set_bias = rcar_pinmux_set_bias, }; #ifdef CONFIG_PINCTRL_PFC_R8A7743 @@ -6665,6 +7016,7 @@ const struct sh_pfc_soc_info r8a7743_pinmux_info = { .nr_functions = ARRAY_SIZE(pinmux_functions.common), .cfg_regs = pinmux_config_regs, + .bias_regs = pinmux_bias_regs, .pinmux_data = pinmux_data, .pinmux_data_size = ARRAY_SIZE(pinmux_data), @@ -6687,6 +7039,7 @@ const struct sh_pfc_soc_info r8a7744_pinmux_info = { .nr_functions = ARRAY_SIZE(pinmux_functions.common), .cfg_regs = pinmux_config_regs, + .bias_regs = pinmux_bias_regs, .pinmux_data = pinmux_data, .pinmux_data_size = ARRAY_SIZE(pinmux_data), @@ -6711,6 +7064,7 @@ const struct sh_pfc_soc_info r8a7791_pinmux_info = { ARRAY_SIZE(pinmux_functions.automotive), .cfg_regs = pinmux_config_regs, + .bias_regs = pinmux_bias_regs, .pinmux_data = pinmux_data, .pinmux_data_size = ARRAY_SIZE(pinmux_data), @@ -6735,6 +7089,7 @@ const struct sh_pfc_soc_info r8a7793_pinmux_info = { ARRAY_SIZE(pinmux_functions.automotive), .cfg_regs = pinmux_config_regs, + .bias_regs = pinmux_bias_regs, .pinmux_data = pinmux_data, .pinmux_data_size = ARRAY_SIZE(pinmux_data), -- cgit v1.2.3 From 81cc4c37adddf379df16b6590e5ad4fc13948b48 Mon Sep 17 00:00:00 2001 From: Hanna Hawa Date: Fri, 19 Mar 2021 17:21:31 +0200 Subject: pinctrl: pinctrl-single: remove unused variable Remove unused parameter 'num_pins_in_register' from pcs_allocate_pin_table(). Reported-by: kernel test robot Signed-off-by: Hanna Hawa Reviewed-by: Tony Lindgren Reviewed-by: Drew Fustini Link: https://lore.kernel.org/r/20210319152133.28705-2-hhhawa@amazon.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 7771316dfffa..91c638b85d2c 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -703,14 +703,12 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset, static int pcs_allocate_pin_table(struct pcs_device *pcs) { int mux_bytes, nr_pins, i; - int num_pins_in_register = 0; mux_bytes = pcs->width / BITS_PER_BYTE; if (pcs->bits_per_mux) { pcs->bits_per_pin = fls(pcs->fmask); nr_pins = (pcs->size * BITS_PER_BYTE) / pcs->bits_per_pin; - num_pins_in_register = pcs->width / pcs->bits_per_pin; } else { nr_pins = pcs->size / mux_bytes; } -- cgit v1.2.3 From 8fa2ea202b13b6da81e26c399ff1d87488398453 Mon Sep 17 00:00:00 2001 From: Hanna Hawa Date: Fri, 19 Mar 2021 17:21:32 +0200 Subject: pinctrl: pinctrl-single: remove unused parameter Remove unused parameter 'pin_pos' from pcs_add_pin(). Signed-off-by: Hanna Hawa Reviewed-by: Tony Lindgren Reviewed-by: Drew Fustini Link: https://lore.kernel.org/r/20210319152133.28705-3-hhhawa@amazon.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 91c638b85d2c..f3394517cb2e 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -656,10 +656,8 @@ static const struct pinconf_ops pcs_pinconf_ops = { * pcs_add_pin() - add a pin to the static per controller pin array * @pcs: pcs driver instance * @offset: register offset from base - * @pin_pos: unused */ -static int pcs_add_pin(struct pcs_device *pcs, unsigned offset, - unsigned pin_pos) +static int pcs_add_pin(struct pcs_device *pcs, unsigned int offset) { struct pcs_soc_data *pcs_soc = &pcs->socdata; struct pinctrl_pin_desc *pin; @@ -727,16 +725,14 @@ static int pcs_allocate_pin_table(struct pcs_device *pcs) unsigned offset; int res; int byte_num; - int pin_pos = 0; if (pcs->bits_per_mux) { byte_num = (pcs->bits_per_pin * i) / BITS_PER_BYTE; offset = (byte_num / mux_bytes) * mux_bytes; - pin_pos = i % num_pins_in_register; } else { offset = i * mux_bytes; } - res = pcs_add_pin(pcs, offset, pin_pos); + res = pcs_add_pin(pcs, offset); if (res < 0) { dev_err(pcs->dev, "error adding pins: %i\n", res); return res; -- cgit v1.2.3 From bd85125ea88513f637a62a72e8949c579c5c0a87 Mon Sep 17 00:00:00 2001 From: Hanna Hawa Date: Fri, 19 Mar 2021 17:21:33 +0200 Subject: pinctrl: pinctrl-single: fix pcs_pin_dbg_show() when bits_per_mux is not zero A System Error (SError, followed by kernel panic) was detected when trying to print the supported pins in a pinctrl device which supports multiple pins per register. This change fixes the pcs_pin_dbg_show() in pinctrl-single driver when bits_per_mux is not zero. In addition move offset calculation and pin offset in register to common function. Fixes: 4e7e8017a80e ("pinctrl: pinctrl-single: enhance to configure multiple pins of different modules") Signed-off-by: Hanna Hawa Reviewed-by: Andy Shevchenko Reviewed-by: Tony Lindgren Reviewed-by: Drew Fustini Link: https://lore.kernel.org/r/20210319152133.28705-4-hhhawa@amazon.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 55 +++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index f3394517cb2e..39aac32ed09c 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -270,20 +270,44 @@ static void __maybe_unused pcs_writel(unsigned val, void __iomem *reg) writel(val, reg); } +static unsigned int pcs_pin_reg_offset_get(struct pcs_device *pcs, + unsigned int pin) +{ + unsigned int mux_bytes = pcs->width / BITS_PER_BYTE; + + if (pcs->bits_per_mux) { + unsigned int pin_offset_bytes; + + pin_offset_bytes = (pcs->bits_per_pin * pin) / BITS_PER_BYTE; + return (pin_offset_bytes / mux_bytes) * mux_bytes; + } + + return pin * mux_bytes; +} + +static unsigned int pcs_pin_shift_reg_get(struct pcs_device *pcs, + unsigned int pin) +{ + return (pin % (pcs->width / pcs->bits_per_pin)) * pcs->bits_per_pin; +} + static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, unsigned pin) { struct pcs_device *pcs; - unsigned val, mux_bytes; + unsigned int val; unsigned long offset; size_t pa; pcs = pinctrl_dev_get_drvdata(pctldev); - mux_bytes = pcs->width / BITS_PER_BYTE; - offset = pin * mux_bytes; + offset = pcs_pin_reg_offset_get(pcs, pin); val = pcs->read(pcs->base + offset); + + if (pcs->bits_per_mux) + val &= pcs->fmask << pcs_pin_shift_reg_get(pcs, pin); + pa = pcs->res->start + offset; seq_printf(s, "%zx %08x %s ", pa, val, DRIVER_NAME); @@ -384,7 +408,6 @@ static int pcs_request_gpio(struct pinctrl_dev *pctldev, struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); struct pcs_gpiofunc_range *frange = NULL; struct list_head *pos, *tmp; - int mux_bytes = 0; unsigned data; /* If function mask is null, return directly. */ @@ -392,29 +415,27 @@ static int pcs_request_gpio(struct pinctrl_dev *pctldev, return -ENOTSUPP; list_for_each_safe(pos, tmp, &pcs->gpiofuncs) { + u32 offset; + frange = list_entry(pos, struct pcs_gpiofunc_range, node); if (pin >= frange->offset + frange->npins || pin < frange->offset) continue; - mux_bytes = pcs->width / BITS_PER_BYTE; - if (pcs->bits_per_mux) { - int byte_num, offset, pin_shift; + offset = pcs_pin_reg_offset_get(pcs, pin); - byte_num = (pcs->bits_per_pin * pin) / BITS_PER_BYTE; - offset = (byte_num / mux_bytes) * mux_bytes; - pin_shift = pin % (pcs->width / pcs->bits_per_pin) * - pcs->bits_per_pin; + if (pcs->bits_per_mux) { + int pin_shift = pcs_pin_shift_reg_get(pcs, pin); data = pcs->read(pcs->base + offset); data &= ~(pcs->fmask << pin_shift); data |= frange->gpiofunc << pin_shift; pcs->write(data, pcs->base + offset); } else { - data = pcs->read(pcs->base + pin * mux_bytes); + data = pcs->read(pcs->base + offset); data &= ~pcs->fmask; data |= frange->gpiofunc; - pcs->write(data, pcs->base + pin * mux_bytes); + pcs->write(data, pcs->base + offset); } break; } @@ -724,14 +745,8 @@ static int pcs_allocate_pin_table(struct pcs_device *pcs) for (i = 0; i < pcs->desc.npins; i++) { unsigned offset; int res; - int byte_num; - if (pcs->bits_per_mux) { - byte_num = (pcs->bits_per_pin * i) / BITS_PER_BYTE; - offset = (byte_num / mux_bytes) * mux_bytes; - } else { - offset = i * mux_bytes; - } + offset = pcs_pin_reg_offset_get(pcs, i); res = pcs_add_pin(pcs, offset); if (res < 0) { dev_err(pcs->dev, "error adding pins: %i\n", res); -- cgit v1.2.3 From 42a46434e9b18b35d2e57433cdbeff3233ca9765 Mon Sep 17 00:00:00 2001 From: Zhiyong Tao Date: Sun, 21 Mar 2021 11:31:50 +0800 Subject: pinctrl: add lock in mtk_rmw function. When multiple threads operate on the same register resource which include multiple pin, It will make the register resource wrong to control. So we add lock to avoid the case. Signed-off-by: Zhiyong Tao Link: https://lore.kernel.org/r/20210321033150.15380-2-zhiyong.tao@mediatek.com Signed-off-by: Linus Walleij --- drivers/pinctrl/mediatek/pinctrl-moore.c | 2 ++ drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 4 ++++ drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 2 ++ drivers/pinctrl/mediatek/pinctrl-paris.c | 2 ++ 4 files changed, 10 insertions(+) diff --git a/drivers/pinctrl/mediatek/pinctrl-moore.c b/drivers/pinctrl/mediatek/pinctrl-moore.c index 0fa7de43bc4c..f77921957f15 100644 --- a/drivers/pinctrl/mediatek/pinctrl-moore.c +++ b/drivers/pinctrl/mediatek/pinctrl-moore.c @@ -619,6 +619,8 @@ int mtk_moore_pinctrl_probe(struct platform_device *pdev, hw->nbase = hw->soc->nbase_names; + mutex_init(&hw->lock); + /* Copy from internal struct mtk_pin_desc to register to the core */ pins = devm_kmalloc_array(&pdev->dev, hw->soc->npins, sizeof(*pins), GFP_KERNEL); diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c index 72f17f26acd8..fcf7c3eeee4a 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -58,10 +58,14 @@ void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set) { u32 val; + mutex_lock(&pctl->lock); + val = mtk_r32(pctl, i, reg); val &= ~mask; val |= set; mtk_w32(pctl, i, reg, val); + + mutex_unlock(&pctl->lock); } static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw, diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h index e2aae285b5fc..65eac708a3b3 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h @@ -251,6 +251,8 @@ struct mtk_pinctrl { struct mtk_eint *eint; struct mtk_pinctrl_group *groups; const char **grp_names; + /* lock pin's register resource to avoid multiple threads issue*/ + struct mutex lock; }; void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set); diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index da1f19288aa6..48e823f6d293 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -970,6 +970,8 @@ int mtk_paris_pinctrl_probe(struct platform_device *pdev, hw->nbase = hw->soc->nbase_names; + mutex_init(&hw->lock); + err = mtk_pctrl_build_state(pdev); if (err) { dev_err(&pdev->dev, "build state failed: %d\n", err); -- cgit v1.2.3 From febb4ee23a412f42fdd6d0fdef692bb9c5e1fad3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 16 Mar 2021 14:40:59 +0100 Subject: pinctrl: PINCTRL_ROCKCHIP should depend on ARCH_ROCKCHIP The Rockchip GPIO and pin control modules are only present on Rockchip SoCs. Hence add a dependency on ARCH_ROCKCHIP, to prevent asking the user about this driver when configuring a kernel without Rockchip platform support. Note that before, the PINCTRL_ROCKCHIP symbol was not visible, and automatically selected when needed. By making it tristate and user-selectable, it became visible for everyone. Fixes: be786ac5a6c4bf4e ("pinctrl: rockchip: make driver be tristate module") Signed-off-by: Geert Uytterhoeven Reviewed-by: Heiko Stuebner Link: https://lore.kernel.org/r/20210316134059.2377081-1-geert+renesas@glider.be Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index ef0ae9b562cd..9502775afc11 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -209,6 +209,7 @@ config PINCTRL_OXNAS config PINCTRL_ROCKCHIP tristate "Rockchip gpio and pinctrl driver" + depends on ARCH_ROCKCHIP || COMPILE_TEST depends on OF select GPIOLIB select PINMUX -- cgit v1.2.3 From 5b613df3f499e305f3aecd58090a71ec0d92930d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 4 Mar 2021 12:54:32 +0200 Subject: pinctrl: intel: No need to disable IRQs in the handler In IRQ handler interrupts are already disabled, hence no need to repeat it. Even in the threaded case, which is disabled here, it is not a problem because IRQ framework serializes descriptor handling. Remove disabling IRQ part in the handler. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 7283203861ae..795d60d9ebba 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -1173,16 +1173,15 @@ static int intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl, for (gpp = 0; gpp < community->ngpps; gpp++) { const struct intel_padgroup *padgrp = &community->gpps[gpp]; unsigned long pending, enabled, gpp_offset; - unsigned long flags; - raw_spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock(&pctrl->lock); pending = readl(community->regs + community->is_offset + padgrp->reg_num * 4); enabled = readl(community->regs + community->ie_offset + padgrp->reg_num * 4); - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock(&pctrl->lock); /* Only interrupts that are enabled */ pending &= enabled; -- cgit v1.2.3 From 9c7d24693d864f90b27aad5d15fbfe226c02898b Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:02 +0100 Subject: gpio: guard gpiochip_irqchip_add_domain() with GPIOLIB_IRQCHIP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current code doesn't check if GPIOLIB_IRQCHIP is enabled, which results in a compilation error when trying to build gpio-regmap if CONFIG_GPIOLIB_IRQCHIP isn't enabled. Fixes: 6a45b0e2589f ("gpiolib: Introduce gpiochip_irqchip_add_domain()") Suggested-by: Michael Walle Signed-off-by: Álvaro Fernández Rojas Reviewed-by: Linus Walleij Reviewed-by: Michael Walle Acked-by: Bartosz Golaszewski Link: https://lore.kernel.org/r/20210324081923.20379-2-noltari@gmail.com Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 286de0520574..ecf0032a0995 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -624,8 +624,17 @@ void gpiochip_irq_domain_deactivate(struct irq_domain *domain, bool gpiochip_irqchip_irq_valid(const struct gpio_chip *gc, unsigned int offset); +#ifdef CONFIG_GPIOLIB_IRQCHIP int gpiochip_irqchip_add_domain(struct gpio_chip *gc, struct irq_domain *domain); +#else +static inline int gpiochip_irqchip_add_domain(struct gpio_chip *gc, + struct irq_domain *domain) +{ + WARN_ON(1); + return -EINVAL; +} +#endif int gpiochip_generic_request(struct gpio_chip *gc, unsigned int offset); void gpiochip_generic_free(struct gpio_chip *gc, unsigned int offset); -- cgit v1.2.3 From d46bf9ec4596654f36245e3b14765bcb422be6ad Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:03 +0100 Subject: gpio: regmap: set gpio_chip of_node MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is needed for properly registering GPIO regmap as a child of a regmap pin controller. Signed-off-by: Álvaro Fernández Rojas Reviewed-by: Michael Walle Reviewed-by: Andy Shevchenko Acked-by: Bartosz Golaszewski Link: https://lore.kernel.org/r/20210324081923.20379-3-noltari@gmail.com Signed-off-by: Linus Walleij --- drivers/gpio/gpio-regmap.c | 5 +++++ include/linux/gpio/regmap.h | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c index 5412cb3b0b2a..134cedf151a7 100644 --- a/drivers/gpio/gpio-regmap.c +++ b/drivers/gpio/gpio-regmap.c @@ -254,6 +254,11 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config chip->names = config->names; chip->label = config->label ?: dev_name(config->parent); +#if defined(CONFIG_OF_GPIO) + /* gpiolib will use of_node of the parent if chip->of_node is NULL */ + chip->of_node = to_of_node(config->fwnode); +#endif /* CONFIG_OF_GPIO */ + /* * If our regmap is fast_io we should probably set can_sleep to false. * Right now, the regmap doesn't save this property, nor is there any diff --git a/include/linux/gpio/regmap.h b/include/linux/gpio/regmap.h index ad76f3d0a6ba..334dd928042b 100644 --- a/include/linux/gpio/regmap.h +++ b/include/linux/gpio/regmap.h @@ -4,6 +4,7 @@ #define _LINUX_GPIO_REGMAP_H struct device; +struct fwnode_handle; struct gpio_regmap; struct irq_domain; struct regmap; @@ -16,6 +17,8 @@ struct regmap; * @parent: The parent device * @regmap: The regmap used to access the registers * given, the name of the device is used + * @fwnode: (Optional) The firmware node. + * If not given, the fwnode of the parent is used. * @label: (Optional) Descriptive name for GPIO controller. * If not given, the name of the device is used. * @ngpio: Number of GPIOs @@ -57,6 +60,7 @@ struct regmap; struct gpio_regmap_config { struct device *parent; struct regmap *regmap; + struct fwnode_handle *fwnode; const char *label; int ngpio; -- cgit v1.2.3 From fb9da17bd26552f48cda4f2f658379e7f5860691 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:04 +0100 Subject: dt-bindings: improve BCM6345 GPIO binding documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert existing BCM6345 GPIO binding documentation to YAML and add binding documentation for the GPIO controller found in BCM6318, BCM6328, BCM6358, BCM6362, BCM6368 and BCM63268 SoCs. Co-developed-by: Jonas Gorski Signed-off-by: Jonas Gorski Signed-off-by: Álvaro Fernández Rojas Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210324081923.20379-4-noltari@gmail.com Signed-off-by: Linus Walleij --- .../devicetree/bindings/gpio/brcm,bcm6345-gpio.txt | 46 ------------ .../bindings/gpio/brcm,bcm6345-gpio.yaml | 86 ++++++++++++++++++++++ 2 files changed, 86 insertions(+), 46 deletions(-) delete mode 100644 Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.txt create mode 100644 Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml diff --git a/Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.txt b/Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.txt deleted file mode 100644 index e7853143fa42..000000000000 --- a/Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.txt +++ /dev/null @@ -1,46 +0,0 @@ -Bindings for the Broadcom's brcm,bcm6345-gpio memory-mapped GPIO controllers. - -These bindings can be used on any BCM63xx SoC. However, BCM6338 and BCM6345 -are the only ones which don't need a pinctrl driver. -BCM6338 have 8-bit data and dirout registers, where GPIO state can be read -and/or written, and the direction changed from input to output. -BCM6345 have 16-bit data and dirout registers, where GPIO state can be read -and/or written, and the direction changed from input to output. - -Required properties: - - compatible: should be "brcm,bcm6345-gpio" - - reg-names: must contain - "dat" - data register - "dirout" - direction (output) register - - reg: address + size pairs describing the GPIO register sets; - order must correspond with the order of entries in reg-names - - #gpio-cells: must be set to 2. The first cell is the pin number and - the second cell is used to specify the gpio polarity: - 0 = active high - 1 = active low - - gpio-controller: Marks the device node as a gpio controller. - -Optional properties: - - native-endian: use native endian memory. - -Examples: - - BCM6338: - gpio: gpio-controller@fffe0407 { - compatible = "brcm,bcm6345-gpio"; - reg-names = "dirout", "dat"; - reg = <0xfffe0407 1>, <0xfffe040f 1>; - - #gpio-cells = <2>; - gpio-controller; - }; - - - BCM6345: - gpio: gpio-controller@fffe0406 { - compatible = "brcm,bcm6345-gpio"; - reg-names = "dirout", "dat"; - reg = <0xfffe0406 2>, <0xfffe040a 2>; - native-endian; - - #gpio-cells = <2>; - gpio-controller; - }; diff --git a/Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml b/Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml new file mode 100644 index 000000000000..4d69f79df859 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gpio/brcm,bcm6345-gpio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6345 GPIO controller + +maintainers: + - Álvaro Fernández Rojas + - Jonas Gorski + +description: |+ + Bindings for Broadcom's BCM63xx memory-mapped GPIO controllers. + + These bindings can be used on any BCM63xx SoC. However, BCM6338 and BCM6345 + are the only ones which don't need a pinctrl driver. + + BCM6338 have 8-bit data and dirout registers, where GPIO state can be read + and/or written, and the direction changed from input to output. + BCM6345 have 16-bit data and dirout registers, where GPIO state can be read + and/or written, and the direction changed from input to output. + BCM6318, BCM6328, BCM6358, BCM6362, BCM6368 and BCM63268 have 32-bit data + and dirout registers, where GPIO state can be read and/or written, and the + direction changed from input to output. + +properties: + compatible: + enum: + - brcm,bcm6318-gpio + - brcm,bcm6328-gpio + - brcm,bcm6345-gpio + - brcm,bcm6358-gpio + - brcm,bcm6362-gpio + - brcm,bcm6368-gpio + - brcm,bcm63268-gpio + + gpio-controller: true + + "#gpio-cells": + const: 2 + + gpio-ranges: + maxItems: 1 + + native-endian: true + + reg: + maxItems: 2 + + reg-names: + items: + - const: dirout + - const: dat + +required: + - compatible + - reg + - reg-names + - gpio-controller + - '#gpio-cells' + +additionalProperties: false + +examples: + - | + gpio@fffe0406 { + compatible = "brcm,bcm6345-gpio"; + reg-names = "dirout", "dat"; + reg = <0xfffe0406 2>, <0xfffe040a 2>; + native-endian; + + gpio-controller; + #gpio-cells = <2>; + }; + + - | + gpio@0 { + compatible = "brcm,bcm63268-gpio"; + reg-names = "dirout", "dat"; + reg = <0x0 0x8>, <0x8 0x8>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 0 52>; + #gpio-cells = <2>; + }; -- cgit v1.2.3 From 132f95016db0a0a0659e99b471a7d3fd0c60f961 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:05 +0100 Subject: pinctrl: bcm: add bcm63xx base code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a helper for registering BCM63XX pin controllers. Co-developed-by: Jonas Gorski Signed-off-by: Jonas Gorski Signed-off-by: Álvaro Fernández Rojas Link: https://lore.kernel.org/r/20210324081923.20379-5-noltari@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/Kconfig | 7 +++ drivers/pinctrl/bcm/Makefile | 1 + drivers/pinctrl/bcm/pinctrl-bcm63xx.c | 109 ++++++++++++++++++++++++++++++++++ drivers/pinctrl/bcm/pinctrl-bcm63xx.h | 43 ++++++++++++++ 4 files changed, 160 insertions(+) create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.c create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.h diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig index 0ed14de0134c..882f19bdc243 100644 --- a/drivers/pinctrl/bcm/Kconfig +++ b/drivers/pinctrl/bcm/Kconfig @@ -29,6 +29,13 @@ config PINCTRL_BCM2835 help Say Y here to enable the Broadcom BCM2835 GPIO driver. +config PINCTRL_BCM63XX + bool + select GENERIC_PINCONF + select GPIO_REGMAP + select PINCONF + select PINMUX + config PINCTRL_IPROC_GPIO bool "Broadcom iProc GPIO (with PINCONF) driver" depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST) diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile index 79d5e49fdd9a..0e3cf9b15c65 100644 --- a/drivers/pinctrl/bcm/Makefile +++ b/drivers/pinctrl/bcm/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o +obj-$(CONFIG_PINCTRL_BCM63XX) += pinctrl-bcm63xx.o obj-$(CONFIG_PINCTRL_IPROC_GPIO) += pinctrl-iproc-gpio.o obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o obj-$(CONFIG_PINCTRL_NS) += pinctrl-ns.o diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63xx.c b/drivers/pinctrl/bcm/pinctrl-bcm63xx.c new file mode 100644 index 000000000000..e1285fe2fbc0 --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm63xx.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM63xx GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas + * Copyright (C) 2016 Jonas Gorski + */ + +#include +#include +#include +#include +#include + +#include "pinctrl-bcm63xx.h" + +#define BCM63XX_BANK_SIZE 4 + +#define BCM63XX_DIROUT_REG 0x04 +#define BCM63XX_DATA_REG 0x0c + +static int bcm63xx_reg_mask_xlate(struct gpio_regmap *gpio, + unsigned int base, unsigned int offset, + unsigned int *reg, unsigned int *mask) +{ + unsigned int line = offset % BCM63XX_BANK_GPIOS; + unsigned int stride = offset / BCM63XX_BANK_GPIOS; + + *reg = base - stride * BCM63XX_BANK_SIZE; + *mask = BIT(line); + + return 0; +} + +static const struct of_device_id bcm63xx_gpio_of_match[] = { + { .compatible = "brcm,bcm6318-gpio", }, + { .compatible = "brcm,bcm6328-gpio", }, + { .compatible = "brcm,bcm6358-gpio", }, + { .compatible = "brcm,bcm6362-gpio", }, + { .compatible = "brcm,bcm6368-gpio", }, + { .compatible = "brcm,bcm63268-gpio", }, + { /* sentinel */ } +}; + +static int bcm63xx_gpio_probe(struct device *dev, struct device_node *node, + const struct bcm63xx_pinctrl_soc *soc, + struct bcm63xx_pinctrl *pc) +{ + struct gpio_regmap_config grc = {0}; + + grc.parent = dev; + grc.fwnode = &node->fwnode; + grc.ngpio = soc->ngpios; + grc.ngpio_per_reg = BCM63XX_BANK_GPIOS; + grc.regmap = pc->regs; + grc.reg_dat_base = BCM63XX_DATA_REG; + grc.reg_dir_out_base = BCM63XX_DIROUT_REG; + grc.reg_set_base = BCM63XX_DATA_REG; + grc.reg_mask_xlate = bcm63xx_reg_mask_xlate; + + return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &grc)); +} + +int bcm63xx_pinctrl_probe(struct platform_device *pdev, + const struct bcm63xx_pinctrl_soc *soc, + void *driver_data) +{ + struct device *dev = &pdev->dev; + struct bcm63xx_pinctrl *pc; + struct device_node *node; + int err; + + pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); + if (!pc) + return -ENOMEM; + + platform_set_drvdata(pdev, pc); + + pc->dev = dev; + pc->driver_data = driver_data; + + pc->regs = syscon_node_to_regmap(dev->parent->of_node); + if (IS_ERR(pc->regs)) + return PTR_ERR(pc->regs); + + pc->pctl_desc.name = dev_name(dev); + pc->pctl_desc.pins = soc->pins; + pc->pctl_desc.npins = soc->npins; + pc->pctl_desc.pctlops = soc->pctl_ops; + pc->pctl_desc.pmxops = soc->pmx_ops; + pc->pctl_desc.owner = THIS_MODULE; + + pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc); + if (IS_ERR(pc->pctl_dev)) + return PTR_ERR(pc->pctl_dev); + + for_each_child_of_node(dev->parent->of_node, node) { + if (of_match_node(bcm63xx_gpio_of_match, node)) { + err = bcm63xx_gpio_probe(dev, node, soc, pc); + if (err) { + dev_err(dev, "could not add GPIO chip\n"); + of_node_put(node); + return err; + } + } + } + + return 0; +} diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63xx.h b/drivers/pinctrl/bcm/pinctrl-bcm63xx.h new file mode 100644 index 000000000000..3bdb50021f1b --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm63xx.h @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 Álvaro Fernández Rojas + * Copyright (C) 2016 Jonas Gorski + */ + +#ifndef __PINCTRL_BCM63XX_H__ +#define __PINCTRL_BCM63XX_H__ + +#include + +#define BCM63XX_BANK_GPIOS 32 + +struct bcm63xx_pinctrl_soc { + struct pinctrl_ops *pctl_ops; + struct pinmux_ops *pmx_ops; + + const struct pinctrl_pin_desc *pins; + unsigned npins; + + unsigned int ngpios; +}; + +struct bcm63xx_pinctrl { + struct device *dev; + struct regmap *regs; + + struct pinctrl_desc pctl_desc; + struct pinctrl_dev *pctl_dev; + + void *driver_data; +}; + +static inline unsigned int bcm63xx_bank_pin(unsigned int pin) +{ + return pin % BCM63XX_BANK_GPIOS; +} + +int bcm63xx_pinctrl_probe(struct platform_device *pdev, + const struct bcm63xx_pinctrl_soc *soc, + void *driver_data); + +#endif /* __PINCTRL_BCM63XX_H__ */ -- cgit v1.2.3 From 44dbcd8eb08a0febbb46ac7b9331f28a320bdf9a Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:06 +0100 Subject: dt-bindings: add BCM6328 pincontroller binding documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add binding documentation for the pincontrol core found in BCM6328 SoCs. Co-developed-by: Jonas Gorski Signed-off-by: Jonas Gorski Signed-off-by: Álvaro Fernández Rojas Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210324081923.20379-6-noltari@gmail.com Signed-off-by: Linus Walleij --- .../bindings/pinctrl/brcm,bcm6328-pinctrl.yaml | 127 +++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml new file mode 100644 index 000000000000..0fd24f40afb1 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml @@ -0,0 +1,127 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6328 pin controller + +maintainers: + - Álvaro Fernández Rojas + - Jonas Gorski + +description: + Bindings for Broadcom's BCM6328 memory-mapped pin controller. + +properties: + compatible: + const: brcm,bcm6328-pinctrl + + reg: + maxItems: 1 + +patternProperties: + '-pins$': + type: object + $ref: pinmux-node.yaml# + + properties: + function: + enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq, + led, ephy0_act_led, ephy1_act_led, ephy2_act_led, + ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ] + + pins: + enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19, + gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1, + usb_port1 ] + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + pinctrl@18 { + compatible = "brcm,bcm6328-pinctrl"; + reg = <0x18 0x10>; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio6"; + }; + + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio7"; + }; + }; + + pinctrl_inet_act_led: inet_act_led-pins { + function = "inet_act_led"; + pins = "gpio11"; + }; + + pinctrl_pcie_clkreq: pcie_clkreq-pins { + function = "pcie_clkreq"; + pins = "gpio16"; + }; + + pinctrl_ephy0_spd_led: ephy0_spd_led-pins { + function = "led"; + pins = "gpio17"; + }; + + pinctrl_ephy1_spd_led: ephy1_spd_led-pins { + function = "led"; + pins = "gpio18"; + }; + + pinctrl_ephy2_spd_led: ephy2_spd_led-pins { + function = "led"; + pins = "gpio19"; + }; + + pinctrl_ephy3_spd_led: ephy3_spd_led-pins { + function = "led"; + pins = "gpio20"; + }; + + pinctrl_ephy0_act_led: ephy0_act_led-pins { + function = "ephy0_act_led"; + pins = "gpio25"; + }; + + pinctrl_ephy1_act_led: ephy1_act_led-pins { + function = "ephy1_act_led"; + pins = "gpio26"; + }; + + pinctrl_ephy2_act_led: ephy2_act_led-pins { + function = "ephy2_act_led"; + pins = "gpio27"; + }; + + pinctrl_ephy3_act_led: ephy3_act_led-pins { + function = "ephy3_act_led"; + pins = "gpio28"; + }; + + pinctrl_hsspi_cs1: hsspi_cs1-pins { + function = "hsspi_cs1"; + pins = "hsspi_cs1"; + }; + + pinctrl_usb_port1_device: usb_port1_device-pins { + function = "usb_device_port"; + pins = "usb_port1"; + }; + + pinctrl_usb_port1_host: usb_port1_host-pins { + function = "usb_host_port"; + pins = "usb_port1"; + }; + }; -- cgit v1.2.3 From 7f9dfaa2afb6bc3481e531c405b05acf6091af29 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:07 +0100 Subject: dt-bindings: add BCM6328 GPIO sysctl binding documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add binding documentation for the GPIO sysctl found in BCM6328 SoCs. Signed-off-by: Álvaro Fernández Rojas Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210324081923.20379-7-noltari@gmail.com Signed-off-by: Linus Walleij --- .../bindings/mfd/brcm,bcm6328-gpio-sysctl.yaml | 162 +++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/brcm,bcm6328-gpio-sysctl.yaml diff --git a/Documentation/devicetree/bindings/mfd/brcm,bcm6328-gpio-sysctl.yaml b/Documentation/devicetree/bindings/mfd/brcm,bcm6328-gpio-sysctl.yaml new file mode 100644 index 000000000000..33963c11ae62 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/brcm,bcm6328-gpio-sysctl.yaml @@ -0,0 +1,162 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/brcm,bcm6328-gpio-sysctl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6328 GPIO System Controller Device Tree Bindings + +maintainers: + - Álvaro Fernández Rojas + - Jonas Gorski + +description: + Broadcom BCM6328 SoC GPIO system controller which provides a register map + for controlling the GPIO and pins of the SoC. + +properties: + "#address-cells": true + + "#size-cells": true + + compatible: + items: + - const: brcm,bcm6328-gpio-sysctl + - const: syscon + - const: simple-mfd + + ranges: + maxItems: 1 + + reg: + maxItems: 1 + +patternProperties: + "^gpio@[0-9a-f]+$": + # Child node + type: object + $ref: "../gpio/brcm,bcm6345-gpio.yaml" + description: + GPIO controller for the SoC GPIOs. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml. + + "^pinctrl@[0-9a-f]+$": + # Child node + type: object + $ref: "../pinctrl/brcm,bcm6328-pinctrl.yaml" + description: + Pin controller for the SoC pins. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml. + +required: + - "#address-cells" + - compatible + - ranges + - reg + - "#size-cells" + +additionalProperties: false + +examples: + - | + syscon@10000080 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "brcm,bcm6328-gpio-sysctl", "syscon", "simple-mfd"; + reg = <0x10000080 0x80>; + ranges = <0 0x10000080 0x80>; + + gpio@0 { + compatible = "brcm,bcm6328-gpio"; + reg-names = "dirout", "dat"; + reg = <0x0 0x8>, <0x8 0x8>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 0 32>; + #gpio-cells = <2>; + }; + + pinctrl: pinctrl@18 { + compatible = "brcm,bcm6328-pinctrl"; + reg = <0x18 0x10>; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio6"; + }; + + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio7"; + }; + }; + + pinctrl_inet_act_led: inet_act_led-pins { + function = "inet_act_led"; + pins = "gpio11"; + }; + + pinctrl_pcie_clkreq: pcie_clkreq-pins { + function = "pcie_clkreq"; + pins = "gpio16"; + }; + + pinctrl_ephy0_spd_led: ephy0_spd_led-pins { + function = "led"; + pins = "gpio17"; + }; + + pinctrl_ephy1_spd_led: ephy1_spd_led-pins { + function = "led"; + pins = "gpio18"; + }; + + pinctrl_ephy2_spd_led: ephy2_spd_led-pins { + function = "led"; + pins = "gpio19"; + }; + + pinctrl_ephy3_spd_led: ephy3_spd_led-pins { + function = "led"; + pins = "gpio20"; + }; + + pinctrl_ephy0_act_led: ephy0_act_led-pins { + function = "ephy0_act_led"; + pins = "gpio25"; + }; + + pinctrl_ephy1_act_led: ephy1_act_led-pins { + function = "ephy1_act_led"; + pins = "gpio26"; + }; + + pinctrl_ephy2_act_led: ephy2_act_led-pins { + function = "ephy2_act_led"; + pins = "gpio27"; + }; + + pinctrl_ephy3_act_led: ephy3_act_led-pins { + function = "ephy3_act_led"; + pins = "gpio28"; + }; + + pinctrl_hsspi_cs1: hsspi_cs1-pins { + function = "hsspi_cs1"; + pins = "hsspi_cs1"; + }; + + pinctrl_usb_port1_device: usb_port1_device-pins { + function = "usb_device_port"; + pins = "usb_port1"; + }; + + pinctrl_usb_port1_host: usb_port1_host-pins { + function = "usb_host_port"; + pins = "usb_port1"; + }; + }; + }; -- cgit v1.2.3 From 9bf34ac5ab5805f0a798d40423c05596b7a0cee6 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:08 +0100 Subject: pinctrl: add a pincontrol driver for BCM6328 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a pincontrol driver for BCM6328. BCM6328 supports muxing 32 pins as GPIOs, as LEDs for the integrated LED controller, or various other functions. Its pincontrol mux registers also control other aspects, like switching the second USB port between host and device mode. Co-developed-by: Jonas Gorski Signed-off-by: Jonas Gorski Signed-off-by: Álvaro Fernández Rojas Link: https://lore.kernel.org/r/20210324081923.20379-8-noltari@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/Kconfig | 8 + drivers/pinctrl/bcm/Makefile | 1 + drivers/pinctrl/bcm/pinctrl-bcm6328.c | 404 ++++++++++++++++++++++++++++++++++ 3 files changed, 413 insertions(+) create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6328.c diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig index 882f19bdc243..d35e5d3fe26f 100644 --- a/drivers/pinctrl/bcm/Kconfig +++ b/drivers/pinctrl/bcm/Kconfig @@ -36,6 +36,14 @@ config PINCTRL_BCM63XX select PINCONF select PINMUX +config PINCTRL_BCM6328 + bool "Broadcom BCM6328 GPIO driver" + depends on (BMIPS_GENERIC || COMPILE_TEST) + select PINCTRL_BCM63XX + default BMIPS_GENERIC + help + Say Y here to enable the Broadcom BCM6328 GPIO driver. + config PINCTRL_IPROC_GPIO bool "Broadcom iProc GPIO (with PINCONF) driver" depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST) diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile index 0e3cf9b15c65..57e5434a6db6 100644 --- a/drivers/pinctrl/bcm/Makefile +++ b/drivers/pinctrl/bcm/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o obj-$(CONFIG_PINCTRL_BCM63XX) += pinctrl-bcm63xx.o +obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl-bcm6328.o obj-$(CONFIG_PINCTRL_IPROC_GPIO) += pinctrl-iproc-gpio.o obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o obj-$(CONFIG_PINCTRL_NS) += pinctrl-ns.o diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6328.c b/drivers/pinctrl/bcm/pinctrl-bcm6328.c new file mode 100644 index 000000000000..c9efce600550 --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm6328.c @@ -0,0 +1,404 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM6328 GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas + * Copyright (C) 2016 Jonas Gorski + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../pinctrl-utils.h" + +#include "pinctrl-bcm63xx.h" + +#define BCM6328_NUM_GPIOS 32 + +#define BCM6328_MODE_REG 0x18 +#define BCM6328_MUX_HI_REG 0x1c +#define BCM6328_MUX_LO_REG 0x20 +#define BCM6328_MUX_OTHER_REG 0x24 +#define BCM6328_MUX_MASK GENMASK(1, 0) + +struct bcm6328_pingroup { + const char *name; + const unsigned * const pins; + const unsigned num_pins; +}; + +struct bcm6328_function { + const char *name; + const char * const *groups; + const unsigned num_groups; + + unsigned mode_val:1; + unsigned mux_val:2; +}; + +static const unsigned int bcm6328_mux[] = { + BCM6328_MUX_LO_REG, + BCM6328_MUX_HI_REG, + BCM6328_MUX_OTHER_REG +}; + +static const struct pinctrl_pin_desc bcm6328_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + PINCTRL_PIN(2, "gpio2"), + PINCTRL_PIN(3, "gpio3"), + PINCTRL_PIN(4, "gpio4"), + PINCTRL_PIN(5, "gpio5"), + PINCTRL_PIN(6, "gpio6"), + PINCTRL_PIN(7, "gpio7"), + PINCTRL_PIN(8, "gpio8"), + PINCTRL_PIN(9, "gpio9"), + PINCTRL_PIN(10, "gpio10"), + PINCTRL_PIN(11, "gpio11"), + PINCTRL_PIN(12, "gpio12"), + PINCTRL_PIN(13, "gpio13"), + PINCTRL_PIN(14, "gpio14"), + PINCTRL_PIN(15, "gpio15"), + PINCTRL_PIN(16, "gpio16"), + PINCTRL_PIN(17, "gpio17"), + PINCTRL_PIN(18, "gpio18"), + PINCTRL_PIN(19, "gpio19"), + PINCTRL_PIN(20, "gpio20"), + PINCTRL_PIN(21, "gpio21"), + PINCTRL_PIN(22, "gpio22"), + PINCTRL_PIN(23, "gpio23"), + PINCTRL_PIN(24, "gpio24"), + PINCTRL_PIN(25, "gpio25"), + PINCTRL_PIN(26, "gpio26"), + PINCTRL_PIN(27, "gpio27"), + PINCTRL_PIN(28, "gpio28"), + PINCTRL_PIN(29, "gpio29"), + PINCTRL_PIN(30, "gpio30"), + PINCTRL_PIN(31, "gpio31"), + + /* + * No idea where they really are; so let's put them according + * to their mux offsets. + */ + PINCTRL_PIN(36, "hsspi_cs1"), + PINCTRL_PIN(38, "usb_p2"), +}; + +static unsigned gpio0_pins[] = { 0 }; +static unsigned gpio1_pins[] = { 1 }; +static unsigned gpio2_pins[] = { 2 }; +static unsigned gpio3_pins[] = { 3 }; +static unsigned gpio4_pins[] = { 4 }; +static unsigned gpio5_pins[] = { 5 }; +static unsigned gpio6_pins[] = { 6 }; +static unsigned gpio7_pins[] = { 7 }; +static unsigned gpio8_pins[] = { 8 }; +static unsigned gpio9_pins[] = { 9 }; +static unsigned gpio10_pins[] = { 10 }; +static unsigned gpio11_pins[] = { 11 }; +static unsigned gpio12_pins[] = { 12 }; +static unsigned gpio13_pins[] = { 13 }; +static unsigned gpio14_pins[] = { 14 }; +static unsigned gpio15_pins[] = { 15 }; +static unsigned gpio16_pins[] = { 16 }; +static unsigned gpio17_pins[] = { 17 }; +static unsigned gpio18_pins[] = { 18 }; +static unsigned gpio19_pins[] = { 19 }; +static unsigned gpio20_pins[] = { 20 }; +static unsigned gpio21_pins[] = { 21 }; +static unsigned gpio22_pins[] = { 22 }; +static unsigned gpio23_pins[] = { 23 }; +static unsigned gpio24_pins[] = { 24 }; +static unsigned gpio25_pins[] = { 25 }; +static unsigned gpio26_pins[] = { 26 }; +static unsigned gpio27_pins[] = { 27 }; +static unsigned gpio28_pins[] = { 28 }; +static unsigned gpio29_pins[] = { 29 }; +static unsigned gpio30_pins[] = { 30 }; +static unsigned gpio31_pins[] = { 31 }; + +static unsigned hsspi_cs1_pins[] = { 36 }; +static unsigned usb_port1_pins[] = { 38 }; + +#define BCM6328_GROUP(n) \ + { \ + .name = #n, \ + .pins = n##_pins, \ + .num_pins = ARRAY_SIZE(n##_pins), \ + } + +static struct bcm6328_pingroup bcm6328_groups[] = { + BCM6328_GROUP(gpio0), + BCM6328_GROUP(gpio1), + BCM6328_GROUP(gpio2), + BCM6328_GROUP(gpio3), + BCM6328_GROUP(gpio4), + BCM6328_GROUP(gpio5), + BCM6328_GROUP(gpio6), + BCM6328_GROUP(gpio7), + BCM6328_GROUP(gpio8), + BCM6328_GROUP(gpio9), + BCM6328_GROUP(gpio10), + BCM6328_GROUP(gpio11), + BCM6328_GROUP(gpio12), + BCM6328_GROUP(gpio13), + BCM6328_GROUP(gpio14), + BCM6328_GROUP(gpio15), + BCM6328_GROUP(gpio16), + BCM6328_GROUP(gpio17), + BCM6328_GROUP(gpio18), + BCM6328_GROUP(gpio19), + BCM6328_GROUP(gpio20), + BCM6328_GROUP(gpio21), + BCM6328_GROUP(gpio22), + BCM6328_GROUP(gpio23), + BCM6328_GROUP(gpio24), + BCM6328_GROUP(gpio25), + BCM6328_GROUP(gpio26), + BCM6328_GROUP(gpio27), + BCM6328_GROUP(gpio28), + BCM6328_GROUP(gpio29), + BCM6328_GROUP(gpio30), + BCM6328_GROUP(gpio31), + + BCM6328_GROUP(hsspi_cs1), + BCM6328_GROUP(usb_port1), +}; + +/* GPIO_MODE */ +static const char * const led_groups[] = { + "gpio0", + "gpio1", + "gpio2", + "gpio3", + "gpio4", + "gpio5", + "gpio6", + "gpio7", + "gpio8", + "gpio9", + "gpio10", + "gpio11", + "gpio12", + "gpio13", + "gpio14", + "gpio15", + "gpio16", + "gpio17", + "gpio18", + "gpio19", + "gpio20", + "gpio21", + "gpio22", + "gpio23", +}; + +/* PINMUX_SEL */ +static const char * const serial_led_data_groups[] = { + "gpio6", +}; + +static const char * const serial_led_clk_groups[] = { + "gpio7", +}; + +static const char * const inet_act_led_groups[] = { + "gpio11", +}; + +static const char * const pcie_clkreq_groups[] = { + "gpio16", +}; + +static const char * const ephy0_act_led_groups[] = { + "gpio25", +}; + +static const char * const ephy1_act_led_groups[] = { + "gpio26", +}; + +static const char * const ephy2_act_led_groups[] = { + "gpio27", +}; + +static const char * const ephy3_act_led_groups[] = { + "gpio28", +}; + +static const char * const hsspi_cs1_groups[] = { + "hsspi_cs1" +}; + +static const char * const usb_host_port_groups[] = { + "usb_port1", +}; + +static const char * const usb_device_port_groups[] = { + "usb_port1", +}; + +#define BCM6328_MODE_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .mode_val = 1, \ + } + +#define BCM6328_MUX_FUN(n, mux) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .mux_val = mux, \ + } + +static const struct bcm6328_function bcm6328_funcs[] = { + BCM6328_MODE_FUN(led), + BCM6328_MUX_FUN(serial_led_data, 2), + BCM6328_MUX_FUN(serial_led_clk, 2), + BCM6328_MUX_FUN(inet_act_led, 1), + BCM6328_MUX_FUN(pcie_clkreq, 2), + BCM6328_MUX_FUN(ephy0_act_led, 1), + BCM6328_MUX_FUN(ephy1_act_led, 1), + BCM6328_MUX_FUN(ephy2_act_led, 1), + BCM6328_MUX_FUN(ephy3_act_led, 1), + BCM6328_MUX_FUN(hsspi_cs1, 2), + BCM6328_MUX_FUN(usb_host_port, 1), + BCM6328_MUX_FUN(usb_device_port, 2), +}; + +static inline unsigned int bcm6328_mux_off(unsigned int pin) +{ + return bcm6328_mux[pin / 16]; +} + +static int bcm6328_pinctrl_get_group_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6328_groups); +} + +static const char *bcm6328_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + return bcm6328_groups[group].name; +} + +static int bcm6328_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned group, const unsigned **pins, + unsigned *num_pins) +{ + *pins = bcm6328_groups[group].pins; + *num_pins = bcm6328_groups[group].num_pins; + + return 0; +} + +static int bcm6328_pinctrl_get_func_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6328_funcs); +} + +static const char *bcm6328_pinctrl_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return bcm6328_funcs[selector].name; +} + +static int bcm6328_pinctrl_get_groups(struct pinctrl_dev *pctldev, + unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = bcm6328_funcs[selector].groups; + *num_groups = bcm6328_funcs[selector].num_groups; + + return 0; +} + +static void bcm6328_rmw_mux(struct bcm63xx_pinctrl *pc, unsigned pin, + unsigned int mode, unsigned int mux) +{ + if (pin < BCM6328_NUM_GPIOS) + regmap_update_bits(pc->regs, BCM6328_MODE_REG, BIT(pin), + mode ? BIT(pin) : 0); + + regmap_update_bits(pc->regs, bcm6328_mux_off(pin), + BCM6328_MUX_MASK << ((pin % 16) * 2), + mux << ((pin % 16) * 2)); +} + +static int bcm6328_pinctrl_set_mux(struct pinctrl_dev *pctldev, + unsigned selector, unsigned group) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + const struct bcm6328_pingroup *pg = &bcm6328_groups[group]; + const struct bcm6328_function *f = &bcm6328_funcs[selector]; + + bcm6328_rmw_mux(pc, pg->pins[0], f->mode_val, f->mux_val); + + return 0; +} + +static int bcm6328_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + + /* disable all functions using this pin */ + bcm6328_rmw_mux(pc, offset, 0, 0); + + return 0; +} + +static struct pinctrl_ops bcm6328_pctl_ops = { + .dt_free_map = pinctrl_utils_free_map, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .get_group_name = bcm6328_pinctrl_get_group_name, + .get_group_pins = bcm6328_pinctrl_get_group_pins, + .get_groups_count = bcm6328_pinctrl_get_group_count, +}; + +static struct pinmux_ops bcm6328_pmx_ops = { + .get_function_groups = bcm6328_pinctrl_get_groups, + .get_function_name = bcm6328_pinctrl_get_func_name, + .get_functions_count = bcm6328_pinctrl_get_func_count, + .gpio_request_enable = bcm6328_gpio_request_enable, + .set_mux = bcm6328_pinctrl_set_mux, + .strict = true, +}; + +static const struct bcm63xx_pinctrl_soc bcm6328_soc = { + .ngpios = BCM6328_NUM_GPIOS, + .npins = ARRAY_SIZE(bcm6328_pins), + .pctl_ops = &bcm6328_pctl_ops, + .pins = bcm6328_pins, + .pmx_ops = &bcm6328_pmx_ops, +}; + +static int bcm6328_pinctrl_probe(struct platform_device *pdev) +{ + return bcm63xx_pinctrl_probe(pdev, &bcm6328_soc, NULL); +} + +static const struct of_device_id bcm6328_pinctrl_match[] = { + { .compatible = "brcm,bcm6328-pinctrl", }, + { /* sentinel */ } +}; + +static struct platform_driver bcm6328_pinctrl_driver = { + .probe = bcm6328_pinctrl_probe, + .driver = { + .name = "bcm6328-pinctrl", + .of_match_table = bcm6328_pinctrl_match, + }, +}; + +builtin_platform_driver(bcm6328_pinctrl_driver); -- cgit v1.2.3 From 6d591614bfe881bb7664c9bebb6a48231c059411 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:09 +0100 Subject: dt-bindings: add BCM6358 pincontroller binding documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add binding documentation for the pincontrol core found in BCM6358 SoCs. Co-developed-by: Jonas Gorski Signed-off-by: Jonas Gorski Signed-off-by: Álvaro Fernández Rojas Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210324081923.20379-9-noltari@gmail.com Signed-off-by: Linus Walleij --- .../bindings/pinctrl/brcm,bcm6358-pinctrl.yaml | 93 ++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml new file mode 100644 index 000000000000..0c3ce256aa78 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml @@ -0,0 +1,93 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6358-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6358 pin controller + +maintainers: + - Álvaro Fernández Rojas + - Jonas Gorski + +description: + Bindings for Broadcom's BCM6358 memory-mapped pin controller. + +properties: + compatible: + const: brcm,bcm6358-pinctrl + + reg: + maxItems: 1 + +patternProperties: + '-pins$': + type: object + $ref: pinmux-node.yaml# + + properties: + function: + enum: [ ebi_cs, uart1, serial_led, legacy_led, led, spi_cs, utopia, + pwm_syn_clk, sys_irq ] + + pins: + enum: [ ebi_cs_grp, uart1_grp, serial_led_grp, legacy_led_grp, + led_grp, spi_cs_grp, utopia_grp, pwm_syn_clk, sys_irq_grp ] + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + pinctrl@18 { + compatible = "brcm,bcm6358-pinctrl"; + reg = <0x18 0x4>; + + pinctrl_ebi_cs: ebi_cs-pins { + function = "ebi_cs"; + groups = "ebi_cs_grp"; + }; + + pinctrl_uart1: uart1-pins { + function = "uart1"; + groups = "uart1_grp"; + }; + + pinctrl_serial_led: serial_led-pins { + function = "serial_led"; + groups = "serial_led_grp"; + }; + + pinctrl_legacy_led: legacy_led-pins { + function = "legacy_led"; + groups = "legacy_led_grp"; + }; + + pinctrl_led: led-pins { + function = "led"; + groups = "led_grp"; + }; + + pinctrl_spi_cs_23: spi_cs-pins { + function = "spi_cs"; + groups = "spi_cs_grp"; + }; + + pinctrl_utopia: utopia-pins { + function = "utopia"; + groups = "utopia_grp"; + }; + + pinctrl_pwm_syn_clk: pwm_syn_clk-pins { + function = "pwm_syn_clk"; + groups = "pwm_syn_clk_grp"; + }; + + pinctrl_sys_irq: sys_irq-pins { + function = "sys_irq"; + groups = "sys_irq_grp"; + }; + }; -- cgit v1.2.3 From cfb1b98bc8d5ffd813428cb03c63b54cf63dd785 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:10 +0100 Subject: dt-bindings: add BCM6358 GPIO sysctl binding documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add binding documentation for the GPIO sysctl found in BCM6358 SoCs. Signed-off-by: Álvaro Fernández Rojas Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210324081923.20379-10-noltari@gmail.com Signed-off-by: Linus Walleij --- .../bindings/mfd/brcm,bcm6358-gpio-sysctl.yaml | 130 +++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/brcm,bcm6358-gpio-sysctl.yaml diff --git a/Documentation/devicetree/bindings/mfd/brcm,bcm6358-gpio-sysctl.yaml b/Documentation/devicetree/bindings/mfd/brcm,bcm6358-gpio-sysctl.yaml new file mode 100644 index 000000000000..3e44bea78b03 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/brcm,bcm6358-gpio-sysctl.yaml @@ -0,0 +1,130 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/brcm,bcm6358-gpio-sysctl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6358 GPIO System Controller Device Tree Bindings + +maintainers: + - Álvaro Fernández Rojas + - Jonas Gorski + +description: + Broadcom BCM6358 SoC GPIO system controller which provides a register map + for controlling the GPIO and pins of the SoC. + +properties: + "#address-cells": true + + "#size-cells": true + + compatible: + items: + - const: brcm,bcm6358-gpio-sysctl + - const: syscon + - const: simple-mfd + + ranges: + maxItems: 1 + + reg: + maxItems: 1 + +patternProperties: + "^gpio@[0-9a-f]+$": + # Child node + type: object + $ref: "../gpio/brcm,bcm6345-gpio.yaml" + description: + GPIO controller for the SoC GPIOs. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml. + + "^pinctrl@[0-9a-f]+$": + # Child node + type: object + $ref: "../pinctrl/brcm,bcm6358-pinctrl.yaml" + description: + Pin controller for the SoC pins. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml. + +required: + - "#address-cells" + - compatible + - ranges + - reg + - "#size-cells" + +additionalProperties: false + +examples: + - | + syscon@fffe0080 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "brcm,bcm6358-gpio-sysctl", "syscon", "simple-mfd"; + reg = <0xfffe0080 0x80>; + ranges = <0 0xfffe0080 0x80>; + + gpio@0 { + compatible = "brcm,bcm6358-gpio"; + reg-names = "dirout", "dat"; + reg = <0x0 0x8>, <0x8 0x8>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 0 40>; + #gpio-cells = <2>; + }; + + pinctrl: pinctrl@18 { + compatible = "brcm,bcm6358-pinctrl"; + reg = <0x18 0x4>; + + pinctrl_ebi_cs: ebi_cs-pins { + function = "ebi_cs"; + groups = "ebi_cs_grp"; + }; + + pinctrl_uart1: uart1-pins { + function = "uart1"; + groups = "uart1_grp"; + }; + + pinctrl_serial_led: serial_led-pins { + function = "serial_led"; + groups = "serial_led_grp"; + }; + + pinctrl_legacy_led: legacy_led-pins { + function = "legacy_led"; + groups = "legacy_led_grp"; + }; + + pinctrl_led: led-pins { + function = "led"; + groups = "led_grp"; + }; + + pinctrl_spi_cs_23: spi_cs-pins { + function = "spi_cs"; + groups = "spi_cs_grp"; + }; + + pinctrl_utopia: utopia-pins { + function = "utopia"; + groups = "utopia_grp"; + }; + + pinctrl_pwm_syn_clk: pwm_syn_clk-pins { + function = "pwm_syn_clk"; + groups = "pwm_syn_clk_grp"; + }; + + pinctrl_sys_irq: sys_irq-pins { + function = "sys_irq"; + groups = "sys_irq_grp"; + }; + }; + }; -- cgit v1.2.3 From 9494b16976e1ae3afc643abf638a25f2ce4c3f2b Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:11 +0100 Subject: pinctrl: add a pincontrol driver for BCM6358 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a pincotrol driver for BCM6358. BCM6358 allow overlaying different functions onto the GPIO pins. It does not support configuring individual pins but only whole groups. These groups may overlap, and still require the directions to be set correctly in the GPIO register. In addition the functions register controls other, not directly mux related functions. Co-developed-by: Jonas Gorski Signed-off-by: Jonas Gorski Signed-off-by: Álvaro Fernández Rojas Link: https://lore.kernel.org/r/20210324081923.20379-11-noltari@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/Kconfig | 8 + drivers/pinctrl/bcm/Makefile | 1 + drivers/pinctrl/bcm/pinctrl-bcm6358.c | 369 ++++++++++++++++++++++++++++++++++ 3 files changed, 378 insertions(+) create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6358.c diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig index d35e5d3fe26f..ced7cc6ab44f 100644 --- a/drivers/pinctrl/bcm/Kconfig +++ b/drivers/pinctrl/bcm/Kconfig @@ -44,6 +44,14 @@ config PINCTRL_BCM6328 help Say Y here to enable the Broadcom BCM6328 GPIO driver. +config PINCTRL_BCM6358 + bool "Broadcom BCM6358 GPIO driver" + depends on (BMIPS_GENERIC || COMPILE_TEST) + select PINCTRL_BCM63XX + default BMIPS_GENERIC + help + Say Y here to enable the Broadcom BCM6358 GPIO driver. + config PINCTRL_IPROC_GPIO bool "Broadcom iProc GPIO (with PINCONF) driver" depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST) diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile index 57e5434a6db6..c3f5b7b2f2f0 100644 --- a/drivers/pinctrl/bcm/Makefile +++ b/drivers/pinctrl/bcm/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o obj-$(CONFIG_PINCTRL_BCM63XX) += pinctrl-bcm63xx.o obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl-bcm6328.o +obj-$(CONFIG_PINCTRL_BCM6358) += pinctrl-bcm6358.o obj-$(CONFIG_PINCTRL_IPROC_GPIO) += pinctrl-iproc-gpio.o obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o obj-$(CONFIG_PINCTRL_NS) += pinctrl-ns.o diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6358.c b/drivers/pinctrl/bcm/pinctrl-bcm6358.c new file mode 100644 index 000000000000..d638578727f3 --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm6358.c @@ -0,0 +1,369 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM6358 GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas + * Copyright (C) 2016 Jonas Gorski + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../pinctrl-utils.h" + +#include "pinctrl-bcm63xx.h" + +#define BCM6358_NUM_GPIOS 40 + +#define BCM6358_MODE_REG 0x18 +#define BCM6358_MODE_MUX_NONE 0 +#define BCM6358_MODE_MUX_EBI_CS BIT(5) +#define BCM6358_MODE_MUX_UART1 BIT(6) +#define BCM6358_MODE_MUX_SPI_CS BIT(7) +#define BCM6358_MODE_MUX_ASYNC_MODEM BIT(8) +#define BCM6358_MODE_MUX_LEGACY_LED BIT(9) +#define BCM6358_MODE_MUX_SERIAL_LED BIT(10) +#define BCM6358_MODE_MUX_LED BIT(11) +#define BCM6358_MODE_MUX_UTOPIA BIT(12) +#define BCM6358_MODE_MUX_CLKRST BIT(13) +#define BCM6358_MODE_MUX_PWM_SYN_CLK BIT(14) +#define BCM6358_MODE_MUX_SYS_IRQ BIT(15) + +struct bcm6358_pingroup { + const char *name; + const unsigned * const pins; + const unsigned num_pins; + + const uint16_t mode_val; + + /* non-GPIO function muxes require the gpio direction to be set */ + const uint16_t direction; +}; + +struct bcm6358_function { + const char *name; + const char * const *groups; + const unsigned num_groups; +}; + +struct bcm6358_priv { + struct regmap_field *overlays; +}; + +#define BCM6358_GPIO_PIN(a, b, bit1, bit2, bit3) \ + { \ + .number = a, \ + .name = b, \ + .drv_data = (void *)(BCM6358_MODE_MUX_##bit1 | \ + BCM6358_MODE_MUX_##bit2 | \ + BCM6358_MODE_MUX_##bit3), \ + } + +static const struct pinctrl_pin_desc bcm6358_pins[] = { + BCM6358_GPIO_PIN(0, "gpio0", LED, NONE, NONE), + BCM6358_GPIO_PIN(1, "gpio1", LED, NONE, NONE), + BCM6358_GPIO_PIN(2, "gpio2", LED, NONE, NONE), + BCM6358_GPIO_PIN(3, "gpio3", LED, NONE, NONE), + PINCTRL_PIN(4, "gpio4"), + BCM6358_GPIO_PIN(5, "gpio5", SYS_IRQ, NONE, NONE), + BCM6358_GPIO_PIN(6, "gpio6", SERIAL_LED, NONE, NONE), + BCM6358_GPIO_PIN(7, "gpio7", SERIAL_LED, NONE, NONE), + BCM6358_GPIO_PIN(8, "gpio8", PWM_SYN_CLK, NONE, NONE), + BCM6358_GPIO_PIN(9, "gpio09", LEGACY_LED, NONE, NONE), + BCM6358_GPIO_PIN(10, "gpio10", LEGACY_LED, NONE, NONE), + BCM6358_GPIO_PIN(11, "gpio11", LEGACY_LED, NONE, NONE), + BCM6358_GPIO_PIN(12, "gpio12", LEGACY_LED, ASYNC_MODEM, UTOPIA), + BCM6358_GPIO_PIN(13, "gpio13", LEGACY_LED, ASYNC_MODEM, UTOPIA), + BCM6358_GPIO_PIN(14, "gpio14", LEGACY_LED, ASYNC_MODEM, UTOPIA), + BCM6358_GPIO_PIN(15, "gpio15", LEGACY_LED, ASYNC_MODEM, UTOPIA), + PINCTRL_PIN(16, "gpio16"), + PINCTRL_PIN(17, "gpio17"), + PINCTRL_PIN(18, "gpio18"), + PINCTRL_PIN(19, "gpio19"), + PINCTRL_PIN(20, "gpio20"), + PINCTRL_PIN(21, "gpio21"), + BCM6358_GPIO_PIN(22, "gpio22", UTOPIA, NONE, NONE), + BCM6358_GPIO_PIN(23, "gpio23", UTOPIA, NONE, NONE), + BCM6358_GPIO_PIN(24, "gpio24", UTOPIA, NONE, NONE), + BCM6358_GPIO_PIN(25, "gpio25", UTOPIA, NONE, NONE), + BCM6358_GPIO_PIN(26, "gpio26", UTOPIA, NONE, NONE), + BCM6358_GPIO_PIN(27, "gpio27", UTOPIA, NONE, NONE), + BCM6358_GPIO_PIN(28, "gpio28", UTOPIA, UART1, NONE), + BCM6358_GPIO_PIN(29, "gpio29", UTOPIA, UART1, NONE), + BCM6358_GPIO_PIN(30, "gpio30", UTOPIA, UART1, EBI_CS), + BCM6358_GPIO_PIN(31, "gpio31", UTOPIA, UART1, EBI_CS), + BCM6358_GPIO_PIN(32, "gpio32", SPI_CS, NONE, NONE), + BCM6358_GPIO_PIN(33, "gpio33", SPI_CS, NONE, NONE), + PINCTRL_PIN(34, "gpio34"), + PINCTRL_PIN(35, "gpio35"), + PINCTRL_PIN(36, "gpio36"), + PINCTRL_PIN(37, "gpio37"), + PINCTRL_PIN(38, "gpio38"), + PINCTRL_PIN(39, "gpio39"), +}; + +static unsigned ebi_cs_grp_pins[] = { 30, 31 }; + +static unsigned uart1_grp_pins[] = { 28, 29, 30, 31 }; + +static unsigned spi_cs_grp_pins[] = { 32, 33 }; + +static unsigned async_modem_grp_pins[] = { 12, 13, 14, 15 }; + +static unsigned serial_led_grp_pins[] = { 6, 7 }; + +static unsigned legacy_led_grp_pins[] = { 9, 10, 11, 12, 13, 14, 15 }; + +static unsigned led_grp_pins[] = { 0, 1, 2, 3 }; + +static unsigned utopia_grp_pins[] = { + 12, 13, 14, 15, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, +}; + +static unsigned pwm_syn_clk_grp_pins[] = { 8 }; + +static unsigned sys_irq_grp_pins[] = { 5 }; + +#define BCM6358_GPIO_MUX_GROUP(n, bit, dir) \ + { \ + .name = #n, \ + .pins = n##_pins, \ + .num_pins = ARRAY_SIZE(n##_pins), \ + .mode_val = BCM6358_MODE_MUX_##bit, \ + .direction = dir, \ + } + +static const struct bcm6358_pingroup bcm6358_groups[] = { + BCM6358_GPIO_MUX_GROUP(ebi_cs_grp, EBI_CS, 0x3), + BCM6358_GPIO_MUX_GROUP(uart1_grp, UART1, 0x2), + BCM6358_GPIO_MUX_GROUP(spi_cs_grp, SPI_CS, 0x6), + BCM6358_GPIO_MUX_GROUP(async_modem_grp, ASYNC_MODEM, 0x6), + BCM6358_GPIO_MUX_GROUP(legacy_led_grp, LEGACY_LED, 0x7f), + BCM6358_GPIO_MUX_GROUP(serial_led_grp, SERIAL_LED, 0x3), + BCM6358_GPIO_MUX_GROUP(led_grp, LED, 0xf), + BCM6358_GPIO_MUX_GROUP(utopia_grp, UTOPIA, 0x000f), + BCM6358_GPIO_MUX_GROUP(pwm_syn_clk_grp, PWM_SYN_CLK, 0x1), + BCM6358_GPIO_MUX_GROUP(sys_irq_grp, SYS_IRQ, 0x1), +}; + +static const char * const ebi_cs_groups[] = { + "ebi_cs_grp" +}; + +static const char * const uart1_groups[] = { + "uart1_grp" +}; + +static const char * const spi_cs_2_3_groups[] = { + "spi_cs_2_3_grp" +}; + +static const char * const async_modem_groups[] = { + "async_modem_grp" +}; + +static const char * const legacy_led_groups[] = { + "legacy_led_grp", +}; + +static const char * const serial_led_groups[] = { + "serial_led_grp", +}; + +static const char * const led_groups[] = { + "led_grp", +}; + +static const char * const clkrst_groups[] = { + "clkrst_grp", +}; + +static const char * const pwm_syn_clk_groups[] = { + "pwm_syn_clk_grp", +}; + +static const char * const sys_irq_groups[] = { + "sys_irq_grp", +}; + +#define BCM6358_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + } + +static const struct bcm6358_function bcm6358_funcs[] = { + BCM6358_FUN(ebi_cs), + BCM6358_FUN(uart1), + BCM6358_FUN(spi_cs_2_3), + BCM6358_FUN(async_modem), + BCM6358_FUN(legacy_led), + BCM6358_FUN(serial_led), + BCM6358_FUN(led), + BCM6358_FUN(clkrst), + BCM6358_FUN(pwm_syn_clk), + BCM6358_FUN(sys_irq), +}; + +static int bcm6358_pinctrl_get_group_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6358_groups); +} + +static const char *bcm6358_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + return bcm6358_groups[group].name; +} + +static int bcm6358_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned group, const unsigned **pins, + unsigned *num_pins) +{ + *pins = bcm6358_groups[group].pins; + *num_pins = bcm6358_groups[group].num_pins; + + return 0; +} + +static int bcm6358_pinctrl_get_func_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6358_funcs); +} + +static const char *bcm6358_pinctrl_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return bcm6358_funcs[selector].name; +} + +static int bcm6358_pinctrl_get_groups(struct pinctrl_dev *pctldev, + unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = bcm6358_funcs[selector].groups; + *num_groups = bcm6358_funcs[selector].num_groups; + + return 0; +} + +static int bcm6358_pinctrl_set_mux(struct pinctrl_dev *pctldev, + unsigned selector, unsigned group) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + struct bcm6358_priv *priv = pc->driver_data; + const struct bcm6358_pingroup *pg = &bcm6358_groups[group]; + unsigned int val = pg->mode_val; + unsigned int mask = val; + unsigned pin; + + for (pin = 0; pin < pg->num_pins; pin++) + mask |= (unsigned long)bcm6358_pins[pin].drv_data; + + regmap_field_update_bits(priv->overlays, mask, val); + + for (pin = 0; pin < pg->num_pins; pin++) { + struct pinctrl_gpio_range *range; + unsigned int hw_gpio = bcm6358_pins[pin].number; + + range = pinctrl_find_gpio_range_from_pin(pctldev, hw_gpio); + if (range) { + struct gpio_chip *gc = range->gc; + + if (pg->direction & BIT(pin)) + gc->direction_output(gc, hw_gpio, 0); + else + gc->direction_input(gc, hw_gpio); + } + } + + return 0; +} + +static int bcm6358_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + struct bcm6358_priv *priv = pc->driver_data; + unsigned int mask; + + mask = (unsigned long) bcm6358_pins[offset].drv_data; + if (!mask) + return 0; + + /* disable all functions using this pin */ + return regmap_field_update_bits(priv->overlays, mask, 0); +} + +static struct pinctrl_ops bcm6358_pctl_ops = { + .dt_free_map = pinctrl_utils_free_map, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .get_group_name = bcm6358_pinctrl_get_group_name, + .get_group_pins = bcm6358_pinctrl_get_group_pins, + .get_groups_count = bcm6358_pinctrl_get_group_count, +}; + +static struct pinmux_ops bcm6358_pmx_ops = { + .get_function_groups = bcm6358_pinctrl_get_groups, + .get_function_name = bcm6358_pinctrl_get_func_name, + .get_functions_count = bcm6358_pinctrl_get_func_count, + .gpio_request_enable = bcm6358_gpio_request_enable, + .set_mux = bcm6358_pinctrl_set_mux, + .strict = true, +}; + +static const struct bcm63xx_pinctrl_soc bcm6358_soc = { + .ngpios = BCM6358_NUM_GPIOS, + .npins = ARRAY_SIZE(bcm6358_pins), + .pctl_ops = &bcm6358_pctl_ops, + .pins = bcm6358_pins, + .pmx_ops = &bcm6358_pmx_ops, +}; + +static int bcm6358_pinctrl_probe(struct platform_device *pdev) +{ + struct reg_field overlays = REG_FIELD(BCM6358_MODE_REG, 0, 15); + struct device *dev = &pdev->dev; + struct bcm63xx_pinctrl *pc; + struct bcm6358_priv *priv; + int err; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + err = bcm63xx_pinctrl_probe(pdev, &bcm6358_soc, (void *) priv); + if (err) + return err; + + pc = platform_get_drvdata(pdev); + + priv->overlays = devm_regmap_field_alloc(dev, pc->regs, overlays); + if (IS_ERR(priv->overlays)) + return PTR_ERR(priv->overlays); + + return 0; +} + +static const struct of_device_id bcm6358_pinctrl_match[] = { + { .compatible = "brcm,bcm6358-pinctrl", }, + { /* sentinel */ } +}; + +static struct platform_driver bcm6358_pinctrl_driver = { + .probe = bcm6358_pinctrl_probe, + .driver = { + .name = "bcm6358-pinctrl", + .of_match_table = bcm6358_pinctrl_match, + }, +}; + +builtin_platform_driver(bcm6358_pinctrl_driver); -- cgit v1.2.3 From 6e4b5e1fc77513359989112e002e08553d0d8d5c Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:12 +0100 Subject: dt-bindings: add BCM6362 pincontroller binding documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add binding documentation for the pincontrol core found in BCM6362 SoCs. Co-developed-by: Jonas Gorski Signed-off-by: Jonas Gorski Signed-off-by: Álvaro Fernández Rojas Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210324081923.20379-12-noltari@gmail.com Signed-off-by: Linus Walleij --- .../bindings/pinctrl/brcm,bcm6362-pinctrl.yaml | 206 +++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml new file mode 100644 index 000000000000..6f68fee373bd --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml @@ -0,0 +1,206 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6362-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6362 pin controller + +maintainers: + - Álvaro Fernández Rojas + - Jonas Gorski + +description: + Bindings for Broadcom's BCM6362 memory-mapped pin controller. + +properties: + compatible: + const: brcm,bcm6362-pinctrl + + reg: + maxItems: 2 + +patternProperties: + '-pins$': + type: object + $ref: pinmux-node.yaml# + + properties: + function: + enum: [ usb_device_led, sys_irq, serial_led_clk, serial_led_data, + robosw_led_data, robosw_led_clk, robosw_led0, robosw_led1, + inet_led, spi_cs2, spi_cs3, ntr_pulse, uart1_scts, + uart1_srts, uart1_sdin, uart1_sdout, adsl_spi_miso, + adsl_spi_mosi, adsl_spi_clk, adsl_spi_cs, ephy0_led, + ephy1_led, ephy2_led, ephy3_led, ext_irq0, ext_irq1, + ext_irq2, ext_irq3, nand ] + + pins: + enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7, + gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio14, + gpio15, gpio16, gpio17, gpio18, gpio19, gpio20, gpio21, + gpio22, gpio23, gpio24, gpio25, gpio26, gpio27, nand_grp ] + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + pinctrl@18 { + compatible = "brcm,bcm6362-pinctrl"; + reg = <0x18 0x10>, <0x38 0x4>; + + pinctrl_usb_device_led: usb_device_led-pins { + function = "usb_device_led"; + pins = "gpio0"; + }; + + pinctrl_sys_irq: sys_irq-pins { + function = "sys_irq"; + pins = "gpio1"; + }; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio2"; + }; + + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio3"; + }; + }; + + pinctrl_robosw_led_data: robosw_led_data-pins { + function = "robosw_led_data"; + pins = "gpio4"; + }; + + pinctrl_robosw_led_clk: robosw_led_clk-pins { + function = "robosw_led_clk"; + pins = "gpio5"; + }; + + pinctrl_robosw_led0: robosw_led0-pins { + function = "robosw_led0"; + pins = "gpio6"; + }; + + pinctrl_robosw_led1: robosw_led1-pins { + function = "robosw_led1"; + pins = "gpio7"; + }; + + pinctrl_inet_led: inet_led-pins { + function = "inet_led"; + pins = "gpio8"; + }; + + pinctrl_spi_cs2: spi_cs2-pins { + function = "spi_cs2"; + pins = "gpio9"; + }; + + pinctrl_spi_cs3: spi_cs3-pins { + function = "spi_cs3"; + pins = "gpio10"; + }; + + pinctrl_ntr_pulse: ntr_pulse-pins { + function = "ntr_pulse"; + pins = "gpio11"; + }; + + pinctrl_uart1_scts: uart1_scts-pins { + function = "uart1_scts"; + pins = "gpio12"; + }; + + pinctrl_uart1_srts: uart1_srts-pins { + function = "uart1_srts"; + pins = "gpio13"; + }; + + pinctrl_uart1: uart1-pins { + pinctrl_uart1_sdin: uart1_sdin-pins { + function = "uart1_sdin"; + pins = "gpio14"; + }; + + pinctrl_uart1_sdout: uart1_sdout-pins { + function = "uart1_sdout"; + pins = "gpio15"; + }; + }; + + pinctrl_adsl_spi: adsl_spi-pins { + pinctrl_adsl_spi_miso: adsl_spi_miso-pins { + function = "adsl_spi_miso"; + pins = "gpio16"; + }; + + pinctrl_adsl_spi_mosi: adsl_spi_mosi-pins { + function = "adsl_spi_mosi"; + pins = "gpio17"; + }; + + pinctrl_adsl_spi_clk: adsl_spi_clk-pins { + function = "adsl_spi_clk"; + pins = "gpio18"; + }; + + pinctrl_adsl_spi_cs: adsl_spi_cs-pins { + function = "adsl_spi_cs"; + pins = "gpio19"; + }; + }; + + pinctrl_ephy0_led: ephy0_led-pins { + function = "ephy0_led"; + pins = "gpio20"; + }; + + pinctrl_ephy1_led: ephy1_led-pins { + function = "ephy1_led"; + pins = "gpio21"; + }; + + pinctrl_ephy2_led: ephy2_led-pins { + function = "ephy2_led"; + pins = "gpio22"; + }; + + pinctrl_ephy3_led: ephy3_led-pins { + function = "ephy3_led"; + pins = "gpio23"; + }; + + pinctrl_ext_irq0: ext_irq0-pins { + function = "ext_irq0"; + pins = "gpio24"; + }; + + pinctrl_ext_irq1: ext_irq1-pins { + function = "ext_irq1"; + pins = "gpio25"; + }; + + pinctrl_ext_irq2: ext_irq2-pins { + function = "ext_irq2"; + pins = "gpio26"; + }; + + pinctrl_ext_irq3: ext_irq3-pins { + function = "ext_irq3"; + pins = "gpio27"; + }; + + pinctrl_nand: nand-pins { + function = "nand"; + group = "nand_grp"; + }; + }; -- cgit v1.2.3 From 7ca989eafbd6ce1c216a775556c4893baab1959b Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:13 +0100 Subject: dt-bindings: add BCM6362 GPIO sysctl binding documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add binding documentation for the GPIO sysctl found in BCM6362 SoCs. Signed-off-by: Álvaro Fernández Rojas Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210324081923.20379-13-noltari@gmail.com Signed-off-by: Linus Walleij --- .../bindings/mfd/brcm,bcm6362-gpio-sysctl.yaml | 236 +++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/brcm,bcm6362-gpio-sysctl.yaml diff --git a/Documentation/devicetree/bindings/mfd/brcm,bcm6362-gpio-sysctl.yaml b/Documentation/devicetree/bindings/mfd/brcm,bcm6362-gpio-sysctl.yaml new file mode 100644 index 000000000000..48d14a5fe0d5 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/brcm,bcm6362-gpio-sysctl.yaml @@ -0,0 +1,236 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/brcm,bcm6362-gpio-sysctl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6362 GPIO System Controller Device Tree Bindings + +maintainers: + - Álvaro Fernández Rojas + - Jonas Gorski + +description: + Broadcom BCM6362 SoC GPIO system controller which provides a register map + for controlling the GPIO and pins of the SoC. + +properties: + "#address-cells": true + + "#size-cells": true + + compatible: + items: + - const: brcm,bcm6362-gpio-sysctl + - const: syscon + - const: simple-mfd + + ranges: + maxItems: 1 + + reg: + maxItems: 1 + +patternProperties: + "^gpio@[0-9a-f]+$": + # Child node + type: object + $ref: "../gpio/brcm,bcm6345-gpio.yaml" + description: + GPIO controller for the SoC GPIOs. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml. + + "^pinctrl@[0-9a-f]+$": + # Child node + type: object + $ref: "../pinctrl/brcm,bcm6362-pinctrl.yaml" + description: + Pin controller for the SoC pins. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml. + +required: + - "#address-cells" + - compatible + - ranges + - reg + - "#size-cells" + +additionalProperties: false + +examples: + - | + syscon@10000080 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "brcm,bcm6362-gpio-sysctl", "syscon", "simple-mfd"; + reg = <0x10000080 0x80>; + ranges = <0 0x10000080 0x80>; + + gpio@0 { + compatible = "brcm,bcm6362-gpio"; + reg-names = "dirout", "dat"; + reg = <0x0 0x8>, <0x8 0x8>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 0 48>; + #gpio-cells = <2>; + }; + + pinctrl: pinctrl@18 { + compatible = "brcm,bcm6362-pinctrl"; + reg = <0x18 0x10>, <0x38 0x4>; + + pinctrl_usb_device_led: usb_device_led-pins { + function = "usb_device_led"; + pins = "gpio0"; + }; + + pinctrl_sys_irq: sys_irq-pins { + function = "sys_irq"; + pins = "gpio1"; + }; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio2"; + }; + + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio3"; + }; + }; + + pinctrl_robosw_led_data: robosw_led_data-pins { + function = "robosw_led_data"; + pins = "gpio4"; + }; + + pinctrl_robosw_led_clk: robosw_led_clk-pins { + function = "robosw_led_clk"; + pins = "gpio5"; + }; + + pinctrl_robosw_led0: robosw_led0-pins { + function = "robosw_led0"; + pins = "gpio6"; + }; + + pinctrl_robosw_led1: robosw_led1-pins { + function = "robosw_led1"; + pins = "gpio7"; + }; + + pinctrl_inet_led: inet_led-pins { + function = "inet_led"; + pins = "gpio8"; + }; + + pinctrl_spi_cs2: spi_cs2-pins { + function = "spi_cs2"; + pins = "gpio9"; + }; + + pinctrl_spi_cs3: spi_cs3-pins { + function = "spi_cs3"; + pins = "gpio10"; + }; + + pinctrl_ntr_pulse: ntr_pulse-pins { + function = "ntr_pulse"; + pins = "gpio11"; + }; + + pinctrl_uart1_scts: uart1_scts-pins { + function = "uart1_scts"; + pins = "gpio12"; + }; + + pinctrl_uart1_srts: uart1_srts-pins { + function = "uart1_srts"; + pins = "gpio13"; + }; + + pinctrl_uart1: uart1-pins { + pinctrl_uart1_sdin: uart1_sdin-pins { + function = "uart1_sdin"; + pins = "gpio14"; + }; + + pinctrl_uart1_sdout: uart1_sdout-pins { + function = "uart1_sdout"; + pins = "gpio15"; + }; + }; + + pinctrl_adsl_spi: adsl_spi-pins { + pinctrl_adsl_spi_miso: adsl_spi_miso-pins { + function = "adsl_spi_miso"; + pins = "gpio16"; + }; + + pinctrl_adsl_spi_mosi: adsl_spi_mosi-pins { + function = "adsl_spi_mosi"; + pins = "gpio17"; + }; + + pinctrl_adsl_spi_clk: adsl_spi_clk-pins { + function = "adsl_spi_clk"; + pins = "gpio18"; + }; + + pinctrl_adsl_spi_cs: adsl_spi_cs-pins { + function = "adsl_spi_cs"; + pins = "gpio19"; + }; + }; + + pinctrl_ephy0_led: ephy0_led-pins { + function = "ephy0_led"; + pins = "gpio20"; + }; + + pinctrl_ephy1_led: ephy1_led-pins { + function = "ephy1_led"; + pins = "gpio21"; + }; + + pinctrl_ephy2_led: ephy2_led-pins { + function = "ephy2_led"; + pins = "gpio22"; + }; + + pinctrl_ephy3_led: ephy3_led-pins { + function = "ephy3_led"; + pins = "gpio23"; + }; + + pinctrl_ext_irq0: ext_irq0-pins { + function = "ext_irq0"; + pins = "gpio24"; + }; + + pinctrl_ext_irq1: ext_irq1-pins { + function = "ext_irq1"; + pins = "gpio25"; + }; + + pinctrl_ext_irq2: ext_irq2-pins { + function = "ext_irq2"; + pins = "gpio26"; + }; + + pinctrl_ext_irq3: ext_irq3-pins { + function = "ext_irq3"; + pins = "gpio27"; + }; + + pinctrl_nand: nand-pins { + function = "nand"; + group = "nand_grp"; + }; + }; + }; -- cgit v1.2.3 From 705791e23ecd93d6c2697234fdf0c22b499c0a5b Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:14 +0100 Subject: pinctrl: add a pincontrol driver for BCM6362 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a pincotrol driver for BCM6362. BCM6362 allows muxing individual GPIO pins to the LED controller, to be available by the integrated wifi, or other functions. It also supports overlay groups, of which only NAND is documented. Co-developed-by: Jonas Gorski Signed-off-by: Jonas Gorski Signed-off-by: Álvaro Fernández Rojas Link: https://lore.kernel.org/r/20210324081923.20379-14-noltari@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/Kconfig | 8 + drivers/pinctrl/bcm/Makefile | 1 + drivers/pinctrl/bcm/pinctrl-bcm6362.c | 617 ++++++++++++++++++++++++++++++++++ 3 files changed, 626 insertions(+) create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6362.c diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig index ced7cc6ab44f..d3101d5e750f 100644 --- a/drivers/pinctrl/bcm/Kconfig +++ b/drivers/pinctrl/bcm/Kconfig @@ -52,6 +52,14 @@ config PINCTRL_BCM6358 help Say Y here to enable the Broadcom BCM6358 GPIO driver. +config PINCTRL_BCM6362 + bool "Broadcom BCM6362 GPIO driver" + depends on (BMIPS_GENERIC || COMPILE_TEST) + select PINCTRL_BCM63XX + default BMIPS_GENERIC + help + Say Y here to enable the Broadcom BCM6362 GPIO driver. + config PINCTRL_IPROC_GPIO bool "Broadcom iProc GPIO (with PINCONF) driver" depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST) diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile index c3f5b7b2f2f0..b9b09e5b914c 100644 --- a/drivers/pinctrl/bcm/Makefile +++ b/drivers/pinctrl/bcm/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o obj-$(CONFIG_PINCTRL_BCM63XX) += pinctrl-bcm63xx.o obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl-bcm6328.o obj-$(CONFIG_PINCTRL_BCM6358) += pinctrl-bcm6358.o +obj-$(CONFIG_PINCTRL_BCM6362) += pinctrl-bcm6362.o obj-$(CONFIG_PINCTRL_IPROC_GPIO) += pinctrl-iproc-gpio.o obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o obj-$(CONFIG_PINCTRL_NS) += pinctrl-ns.o diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6362.c b/drivers/pinctrl/bcm/pinctrl-bcm6362.c new file mode 100644 index 000000000000..eb7ec80353e9 --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm6362.c @@ -0,0 +1,617 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM6362 GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas + * Copyright (C) 2016 Jonas Gorski + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../pinctrl-utils.h" + +#include "pinctrl-bcm63xx.h" + +#define BCM6362_BANK_GPIOS 32 +#define BCM6362_NUM_GPIOS 48 +#define BCM6362_NUM_LEDS 24 + +#define BCM6362_LED_REG 0x10 +#define BCM6362_MODE_REG 0x18 +#define BCM6362_CTRL_REG 0x1c +#define BCM6362_BASEMODE_REG 0x38 +#define BASEMODE_NAND BIT(2) + +enum bcm6362_pinctrl_reg { + BCM6362_LEDCTRL, + BCM6362_MODE, + BCM6362_CTRL, + BCM6362_BASEMODE, +}; + +struct bcm6362_pingroup { + const char *name; + const unsigned * const pins; + const unsigned num_pins; +}; + +struct bcm6362_function { + const char *name; + const char * const *groups; + const unsigned num_groups; + + enum bcm6362_pinctrl_reg reg; + uint32_t basemode_mask; +}; + +#define BCM6362_PIN(a, b, mask) \ + { \ + .number = a, \ + .name = b, \ + .drv_data = (void *)(mask), \ + } + +static const struct pinctrl_pin_desc bcm6362_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + PINCTRL_PIN(2, "gpio2"), + PINCTRL_PIN(3, "gpio3"), + PINCTRL_PIN(4, "gpio4"), + PINCTRL_PIN(5, "gpio5"), + PINCTRL_PIN(6, "gpio6"), + PINCTRL_PIN(7, "gpio7"), + BCM6362_PIN(8, "gpio8", BASEMODE_NAND), + PINCTRL_PIN(9, "gpio9"), + PINCTRL_PIN(10, "gpio10"), + PINCTRL_PIN(11, "gpio11"), + BCM6362_PIN(12, "gpio12", BASEMODE_NAND), + BCM6362_PIN(13, "gpio13", BASEMODE_NAND), + BCM6362_PIN(14, "gpio14", BASEMODE_NAND), + BCM6362_PIN(15, "gpio15", BASEMODE_NAND), + BCM6362_PIN(16, "gpio16", BASEMODE_NAND), + BCM6362_PIN(17, "gpio17", BASEMODE_NAND), + BCM6362_PIN(18, "gpio18", BASEMODE_NAND), + BCM6362_PIN(19, "gpio19", BASEMODE_NAND), + BCM6362_PIN(20, "gpio20", BASEMODE_NAND), + BCM6362_PIN(21, "gpio21", BASEMODE_NAND), + BCM6362_PIN(22, "gpio22", BASEMODE_NAND), + BCM6362_PIN(23, "gpio23", BASEMODE_NAND), + PINCTRL_PIN(24, "gpio24"), + PINCTRL_PIN(25, "gpio25"), + PINCTRL_PIN(26, "gpio26"), + BCM6362_PIN(27, "gpio27", BASEMODE_NAND), + PINCTRL_PIN(28, "gpio28"), + PINCTRL_PIN(29, "gpio29"), + PINCTRL_PIN(30, "gpio30"), + PINCTRL_PIN(31, "gpio31"), + PINCTRL_PIN(32, "gpio32"), + PINCTRL_PIN(33, "gpio33"), + PINCTRL_PIN(34, "gpio34"), + PINCTRL_PIN(35, "gpio35"), + PINCTRL_PIN(36, "gpio36"), + PINCTRL_PIN(37, "gpio37"), + PINCTRL_PIN(38, "gpio38"), + PINCTRL_PIN(39, "gpio39"), + PINCTRL_PIN(40, "gpio40"), + PINCTRL_PIN(41, "gpio41"), + PINCTRL_PIN(42, "gpio42"), + PINCTRL_PIN(43, "gpio43"), + PINCTRL_PIN(44, "gpio44"), + PINCTRL_PIN(45, "gpio45"), + PINCTRL_PIN(46, "gpio46"), + PINCTRL_PIN(47, "gpio47"), +}; + +static unsigned gpio0_pins[] = { 0 }; +static unsigned gpio1_pins[] = { 1 }; +static unsigned gpio2_pins[] = { 2 }; +static unsigned gpio3_pins[] = { 3 }; +static unsigned gpio4_pins[] = { 4 }; +static unsigned gpio5_pins[] = { 5 }; +static unsigned gpio6_pins[] = { 6 }; +static unsigned gpio7_pins[] = { 7 }; +static unsigned gpio8_pins[] = { 8 }; +static unsigned gpio9_pins[] = { 9 }; +static unsigned gpio10_pins[] = { 10 }; +static unsigned gpio11_pins[] = { 11 }; +static unsigned gpio12_pins[] = { 12 }; +static unsigned gpio13_pins[] = { 13 }; +static unsigned gpio14_pins[] = { 14 }; +static unsigned gpio15_pins[] = { 15 }; +static unsigned gpio16_pins[] = { 16 }; +static unsigned gpio17_pins[] = { 17 }; +static unsigned gpio18_pins[] = { 18 }; +static unsigned gpio19_pins[] = { 19 }; +static unsigned gpio20_pins[] = { 20 }; +static unsigned gpio21_pins[] = { 21 }; +static unsigned gpio22_pins[] = { 22 }; +static unsigned gpio23_pins[] = { 23 }; +static unsigned gpio24_pins[] = { 24 }; +static unsigned gpio25_pins[] = { 25 }; +static unsigned gpio26_pins[] = { 26 }; +static unsigned gpio27_pins[] = { 27 }; +static unsigned gpio28_pins[] = { 28 }; +static unsigned gpio29_pins[] = { 29 }; +static unsigned gpio30_pins[] = { 30 }; +static unsigned gpio31_pins[] = { 31 }; +static unsigned gpio32_pins[] = { 32 }; +static unsigned gpio33_pins[] = { 33 }; +static unsigned gpio34_pins[] = { 34 }; +static unsigned gpio35_pins[] = { 35 }; +static unsigned gpio36_pins[] = { 36 }; +static unsigned gpio37_pins[] = { 37 }; +static unsigned gpio38_pins[] = { 38 }; +static unsigned gpio39_pins[] = { 39 }; +static unsigned gpio40_pins[] = { 40 }; +static unsigned gpio41_pins[] = { 41 }; +static unsigned gpio42_pins[] = { 42 }; +static unsigned gpio43_pins[] = { 43 }; +static unsigned gpio44_pins[] = { 44 }; +static unsigned gpio45_pins[] = { 45 }; +static unsigned gpio46_pins[] = { 46 }; +static unsigned gpio47_pins[] = { 47 }; + +static unsigned nand_grp_pins[] = { + 8, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 27, +}; + +#define BCM6362_GROUP(n) \ + { \ + .name = #n, \ + .pins = n##_pins, \ + .num_pins = ARRAY_SIZE(n##_pins), \ + } + +static struct bcm6362_pingroup bcm6362_groups[] = { + BCM6362_GROUP(gpio0), + BCM6362_GROUP(gpio1), + BCM6362_GROUP(gpio2), + BCM6362_GROUP(gpio3), + BCM6362_GROUP(gpio4), + BCM6362_GROUP(gpio5), + BCM6362_GROUP(gpio6), + BCM6362_GROUP(gpio7), + BCM6362_GROUP(gpio8), + BCM6362_GROUP(gpio9), + BCM6362_GROUP(gpio10), + BCM6362_GROUP(gpio11), + BCM6362_GROUP(gpio12), + BCM6362_GROUP(gpio13), + BCM6362_GROUP(gpio14), + BCM6362_GROUP(gpio15), + BCM6362_GROUP(gpio16), + BCM6362_GROUP(gpio17), + BCM6362_GROUP(gpio18), + BCM6362_GROUP(gpio19), + BCM6362_GROUP(gpio20), + BCM6362_GROUP(gpio21), + BCM6362_GROUP(gpio22), + BCM6362_GROUP(gpio23), + BCM6362_GROUP(gpio24), + BCM6362_GROUP(gpio25), + BCM6362_GROUP(gpio26), + BCM6362_GROUP(gpio27), + BCM6362_GROUP(gpio28), + BCM6362_GROUP(gpio29), + BCM6362_GROUP(gpio30), + BCM6362_GROUP(gpio31), + BCM6362_GROUP(gpio32), + BCM6362_GROUP(gpio33), + BCM6362_GROUP(gpio34), + BCM6362_GROUP(gpio35), + BCM6362_GROUP(gpio36), + BCM6362_GROUP(gpio37), + BCM6362_GROUP(gpio38), + BCM6362_GROUP(gpio39), + BCM6362_GROUP(gpio40), + BCM6362_GROUP(gpio41), + BCM6362_GROUP(gpio42), + BCM6362_GROUP(gpio43), + BCM6362_GROUP(gpio44), + BCM6362_GROUP(gpio45), + BCM6362_GROUP(gpio46), + BCM6362_GROUP(gpio47), + BCM6362_GROUP(nand_grp), +}; + +static const char * const led_groups[] = { + "gpio0", + "gpio1", + "gpio2", + "gpio3", + "gpio4", + "gpio5", + "gpio6", + "gpio7", + "gpio8", + "gpio9", + "gpio10", + "gpio11", + "gpio12", + "gpio13", + "gpio14", + "gpio15", + "gpio16", + "gpio17", + "gpio18", + "gpio19", + "gpio20", + "gpio21", + "gpio22", + "gpio23", +}; + +static const char * const usb_device_led_groups[] = { + "gpio0", +}; + +static const char * const sys_irq_groups[] = { + "gpio1", +}; + +static const char * const serial_led_clk_groups[] = { + "gpio2", +}; + +static const char * const serial_led_data_groups[] = { + "gpio3", +}; + +static const char * const robosw_led_data_groups[] = { + "gpio4", +}; + +static const char * const robosw_led_clk_groups[] = { + "gpio5", +}; + +static const char * const robosw_led0_groups[] = { + "gpio6", +}; + +static const char * const robosw_led1_groups[] = { + "gpio7", +}; + +static const char * const inet_led_groups[] = { + "gpio8", +}; + +static const char * const spi_cs2_groups[] = { + "gpio9", +}; + +static const char * const spi_cs3_groups[] = { + "gpio10", +}; + +static const char * const ntr_pulse_groups[] = { + "gpio11", +}; + +static const char * const uart1_scts_groups[] = { + "gpio12", +}; + +static const char * const uart1_srts_groups[] = { + "gpio13", +}; + +static const char * const uart1_sdin_groups[] = { + "gpio14", +}; + +static const char * const uart1_sdout_groups[] = { + "gpio15", +}; + +static const char * const adsl_spi_miso_groups[] = { + "gpio16", +}; + +static const char * const adsl_spi_mosi_groups[] = { + "gpio17", +}; + +static const char * const adsl_spi_clk_groups[] = { + "gpio18", +}; + +static const char * const adsl_spi_cs_groups[] = { + "gpio19", +}; + +static const char * const ephy0_led_groups[] = { + "gpio20", +}; + +static const char * const ephy1_led_groups[] = { + "gpio21", +}; + +static const char * const ephy2_led_groups[] = { + "gpio22", +}; + +static const char * const ephy3_led_groups[] = { + "gpio23", +}; + +static const char * const ext_irq0_groups[] = { + "gpio24", +}; + +static const char * const ext_irq1_groups[] = { + "gpio25", +}; + +static const char * const ext_irq2_groups[] = { + "gpio26", +}; + +static const char * const ext_irq3_groups[] = { + "gpio27", +}; + +static const char * const wifi_groups[] = { + "gpio32", + "gpio33", + "gpio34", + "gpio35", + "gpio36", + "gpio37", + "gpio38", + "gpio39", + "gpio40", + "gpio41", + "gpio42", + "gpio43", + "gpio44", + "gpio45", + "gpio46", + "gpio47", +}; + +static const char * const nand_groups[] = { + "nand_grp", +}; + +#define BCM6362_LED_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM6362_LEDCTRL, \ + } + +#define BCM6362_MODE_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM6362_MODE, \ + } + +#define BCM6362_CTRL_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM6362_CTRL, \ + } + +#define BCM6362_BASEMODE_FUN(n, mask) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM6362_BASEMODE, \ + .basemode_mask = (mask), \ + } + +static const struct bcm6362_function bcm6362_funcs[] = { + BCM6362_LED_FUN(led), + BCM6362_MODE_FUN(usb_device_led), + BCM6362_MODE_FUN(sys_irq), + BCM6362_MODE_FUN(serial_led_clk), + BCM6362_MODE_FUN(serial_led_data), + BCM6362_MODE_FUN(robosw_led_data), + BCM6362_MODE_FUN(robosw_led_clk), + BCM6362_MODE_FUN(robosw_led0), + BCM6362_MODE_FUN(robosw_led1), + BCM6362_MODE_FUN(inet_led), + BCM6362_MODE_FUN(spi_cs2), + BCM6362_MODE_FUN(spi_cs3), + BCM6362_MODE_FUN(ntr_pulse), + BCM6362_MODE_FUN(uart1_scts), + BCM6362_MODE_FUN(uart1_srts), + BCM6362_MODE_FUN(uart1_sdin), + BCM6362_MODE_FUN(uart1_sdout), + BCM6362_MODE_FUN(adsl_spi_miso), + BCM6362_MODE_FUN(adsl_spi_mosi), + BCM6362_MODE_FUN(adsl_spi_clk), + BCM6362_MODE_FUN(adsl_spi_cs), + BCM6362_MODE_FUN(ephy0_led), + BCM6362_MODE_FUN(ephy1_led), + BCM6362_MODE_FUN(ephy2_led), + BCM6362_MODE_FUN(ephy3_led), + BCM6362_MODE_FUN(ext_irq0), + BCM6362_MODE_FUN(ext_irq1), + BCM6362_MODE_FUN(ext_irq2), + BCM6362_MODE_FUN(ext_irq3), + BCM6362_CTRL_FUN(wifi), + BCM6362_BASEMODE_FUN(nand, BASEMODE_NAND), +}; + +static int bcm6362_pinctrl_get_group_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6362_groups); +} + +static const char *bcm6362_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + return bcm6362_groups[group].name; +} + +static int bcm6362_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned group, const unsigned **pins, + unsigned *num_pins) +{ + *pins = bcm6362_groups[group].pins; + *num_pins = bcm6362_groups[group].num_pins; + + return 0; +} + +static int bcm6362_pinctrl_get_func_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6362_funcs); +} + +static const char *bcm6362_pinctrl_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return bcm6362_funcs[selector].name; +} + +static int bcm6362_pinctrl_get_groups(struct pinctrl_dev *pctldev, + unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = bcm6362_funcs[selector].groups; + *num_groups = bcm6362_funcs[selector].num_groups; + + return 0; +} + +static void bcm6362_set_gpio(struct bcm63xx_pinctrl *pc, unsigned pin) +{ + const struct pinctrl_pin_desc *desc = &bcm6362_pins[pin]; + unsigned int mask = bcm63xx_bank_pin(pin); + + if (desc->drv_data) + regmap_update_bits(pc->regs, BCM6362_BASEMODE_REG, + (uint32_t) desc->drv_data, 0); + + if (pin < BCM63XX_BANK_GPIOS) { + /* base mode 0 => gpio 1 => mux function */ + regmap_update_bits(pc->regs, BCM6362_MODE_REG, mask, 0); + + /* pins 0-23 might be muxed to led */ + if (pin < BCM6362_NUM_LEDS) + regmap_update_bits(pc->regs, BCM6362_LED_REG, mask, 0); + } else { + /* ctrl reg 0 => wifi function 1 => gpio */ + regmap_update_bits(pc->regs, BCM6362_CTRL_REG, mask, mask); + } +} + +static int bcm6362_pinctrl_set_mux(struct pinctrl_dev *pctldev, + unsigned selector, unsigned group) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + const struct bcm6362_pingroup *pg = &bcm6362_groups[group]; + const struct bcm6362_function *f = &bcm6362_funcs[selector]; + unsigned i; + unsigned int reg; + unsigned int val, mask; + + for (i = 0; i < pg->num_pins; i++) + bcm6362_set_gpio(pc, pg->pins[i]); + + switch (f->reg) { + case BCM6362_LEDCTRL: + reg = BCM6362_LED_REG; + mask = BIT(pg->pins[0]); + val = BIT(pg->pins[0]); + break; + case BCM6362_MODE: + reg = BCM6362_MODE_REG; + mask = BIT(pg->pins[0]); + val = BIT(pg->pins[0]); + break; + case BCM6362_CTRL: + reg = BCM6362_CTRL_REG; + mask = BIT(pg->pins[0]); + val = 0; + break; + case BCM6362_BASEMODE: + reg = BCM6362_BASEMODE_REG; + mask = f->basemode_mask; + val = f->basemode_mask; + break; + default: + WARN_ON(1); + return -EINVAL; + } + + regmap_update_bits(pc->regs, reg, mask, val); + + return 0; +} + +static int bcm6362_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + + /* disable all functions using this pin */ + bcm6362_set_gpio(pc, offset); + + return 0; +} + +static struct pinctrl_ops bcm6362_pctl_ops = { + .dt_free_map = pinctrl_utils_free_map, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .get_group_name = bcm6362_pinctrl_get_group_name, + .get_group_pins = bcm6362_pinctrl_get_group_pins, + .get_groups_count = bcm6362_pinctrl_get_group_count, +}; + +static struct pinmux_ops bcm6362_pmx_ops = { + .get_function_groups = bcm6362_pinctrl_get_groups, + .get_function_name = bcm6362_pinctrl_get_func_name, + .get_functions_count = bcm6362_pinctrl_get_func_count, + .gpio_request_enable = bcm6362_gpio_request_enable, + .set_mux = bcm6362_pinctrl_set_mux, + .strict = true, +}; + +static const struct bcm63xx_pinctrl_soc bcm6362_soc = { + .ngpios = BCM6362_NUM_GPIOS, + .npins = ARRAY_SIZE(bcm6362_pins), + .pctl_ops = &bcm6362_pctl_ops, + .pins = bcm6362_pins, + .pmx_ops = &bcm6362_pmx_ops, +}; + +static int bcm6362_pinctrl_probe(struct platform_device *pdev) +{ + return bcm63xx_pinctrl_probe(pdev, &bcm6362_soc, NULL); +} + +static const struct of_device_id bcm6362_pinctrl_match[] = { + { .compatible = "brcm,bcm6362-pinctrl", }, + { /* sentinel */ } +}; + +static struct platform_driver bcm6362_pinctrl_driver = { + .probe = bcm6362_pinctrl_probe, + .driver = { + .name = "bcm6362-pinctrl", + .of_match_table = bcm6362_pinctrl_match, + }, +}; + +builtin_platform_driver(bcm6362_pinctrl_driver); -- cgit v1.2.3 From 9fbf8303796c89ecab026eb3dbadae7f98c49922 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:15 +0100 Subject: dt-bindings: add BCM6368 pincontroller binding documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add binding documentation for the pincontrol core found in BCM6368 SoCs. Co-developed-by: Jonas Gorski Signed-off-by: Jonas Gorski Signed-off-by: Álvaro Fernández Rojas Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210324081923.20379-15-noltari@gmail.com Signed-off-by: Linus Walleij --- .../bindings/pinctrl/brcm,bcm6368-pinctrl.yaml | 217 +++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml new file mode 100644 index 000000000000..f4168b9f4460 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml @@ -0,0 +1,217 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6368-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6368 pin controller + +maintainers: + - Álvaro Fernández Rojas + - Jonas Gorski + +description: + Bindings for Broadcom's BCM6368 memory-mapped pin controller. + +properties: + compatible: + const: brcm,bcm6368-pinctrl + + reg: + maxItems: 2 + +patternProperties: + '-pins$': + type: object + $ref: pinmux-node.yaml# + + properties: + function: + enum: [ analog_afe_0, analog_afe_1, sys_irq, serial_led_data, + serial_led_clk, inet_led, ephy0_led, ephy1_led, ephy2_led, + ephy3_led, robosw_led_data, robosw_led_clk, robosw_led0, + robosw_led1, usb_device_led, pci_req1, pci_gnt1, pci_intb, + pci_req0, pci_gnt0, pcmcia_cd1, pcmcia_cd2, pcmcia_vs1, + pcmcia_vs2, ebi_cs2, ebi_cs3, spi_cs2, spi_cs3, spi_cs4, + spi_cs5, uart1 ] + + pins: + enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7, + gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio14, + gpio16, gpio17, gpio18, gpio19, gpio20, gpio22, gpio23, + gpio24, gpio25, gpio26, gpio27, gpio28, gpio29, gpio30, + gpio31, uart1_grp ] + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + pinctrl@18 { + compatible = "brcm,bcm6368-pinctrl"; + reg = <0x18 0x4>, <0x38 0x4>; + + pinctrl_analog_afe_0: analog_afe_0-pins { + function = "analog_afe_0"; + pins = "gpio0"; + }; + + pinctrl_analog_afe_1: analog_afe_1-pins { + function = "analog_afe_1"; + pins = "gpio1"; + }; + + pinctrl_sys_irq: sys_irq-pins { + function = "sys_irq"; + pins = "gpio2"; + }; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio3"; + }; + + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio4"; + }; + }; + + pinctrl_inet_led: inet_led-pins { + function = "inet_led"; + pins = "gpio5"; + }; + + pinctrl_ephy0_led: ephy0_led-pins { + function = "ephy0_led"; + pins = "gpio6"; + }; + + pinctrl_ephy1_led: ephy1_led-pins { + function = "ephy1_led"; + pins = "gpio7"; + }; + + pinctrl_ephy2_led: ephy2_led-pins { + function = "ephy2_led"; + pins = "gpio8"; + }; + + pinctrl_ephy3_led: ephy3_led-pins { + function = "ephy3_led"; + pins = "gpio9"; + }; + + pinctrl_robosw_led_data: robosw_led_data-pins { + function = "robosw_led_data"; + pins = "gpio10"; + }; + + pinctrl_robosw_led_clk: robosw_led_clk-pins { + function = "robosw_led_clk"; + pins = "gpio11"; + }; + + pinctrl_robosw_led0: robosw_led0-pins { + function = "robosw_led0"; + pins = "gpio12"; + }; + + pinctrl_robosw_led1: robosw_led1-pins { + function = "robosw_led1"; + pins = "gpio13"; + }; + + pinctrl_usb_device_led: usb_device_led-pins { + function = "usb_device_led"; + pins = "gpio14"; + }; + + pinctrl_pci: pci-pins { + pinctrl_pci_req1: pci_req1-pins { + function = "pci_req1"; + pins = "gpio16"; + }; + + pinctrl_pci_gnt1: pci_gnt1-pins { + function = "pci_gnt1"; + pins = "gpio17"; + }; + + pinctrl_pci_intb: pci_intb-pins { + function = "pci_intb"; + pins = "gpio18"; + }; + + pinctrl_pci_req0: pci_req0-pins { + function = "pci_req0"; + pins = "gpio19"; + }; + + pinctrl_pci_gnt0: pci_gnt0-pins { + function = "pci_gnt0"; + pins = "gpio20"; + }; + }; + + pinctrl_pcmcia: pcmcia-pins { + pinctrl_pcmcia_cd1: pcmcia_cd1-pins { + function = "pcmcia_cd1"; + pins = "gpio22"; + }; + + pinctrl_pcmcia_cd2: pcmcia_cd2-pins { + function = "pcmcia_cd2"; + pins = "gpio23"; + }; + + pinctrl_pcmcia_vs1: pcmcia_vs1-pins { + function = "pcmcia_vs1"; + pins = "gpio24"; + }; + + pinctrl_pcmcia_vs2: pcmcia_vs2-pins { + function = "pcmcia_vs2"; + pins = "gpio25"; + }; + }; + + pinctrl_ebi_cs2: ebi_cs2-pins { + function = "ebi_cs2"; + pins = "gpio26"; + }; + + pinctrl_ebi_cs3: ebi_cs3-pins { + function = "ebi_cs3"; + pins = "gpio27"; + }; + + pinctrl_spi_cs2: spi_cs2-pins { + function = "spi_cs2"; + pins = "gpio28"; + }; + + pinctrl_spi_cs3: spi_cs3-pins { + function = "spi_cs3"; + pins = "gpio29"; + }; + + pinctrl_spi_cs4: spi_cs4-pins { + function = "spi_cs4"; + pins = "gpio30"; + }; + + pinctrl_spi_cs5: spi_cs5-pins { + function = "spi_cs5"; + pins = "gpio31"; + }; + + pinctrl_uart1: uart1-pins { + function = "uart1"; + group = "uart1_grp"; + }; + }; -- cgit v1.2.3 From fd22635f222f44dcb4dd6382d97de13144edad2b Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:16 +0100 Subject: dt-bindings: add BCM6368 GPIO sysctl binding documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add binding documentation for the GPIO sysctl found in BCM6368 SoCs. Signed-off-by: Álvaro Fernández Rojas Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210324081923.20379-16-noltari@gmail.com Signed-off-by: Linus Walleij --- .../bindings/mfd/brcm,bcm6368-gpio-sysctl.yaml | 246 +++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/brcm,bcm6368-gpio-sysctl.yaml diff --git a/Documentation/devicetree/bindings/mfd/brcm,bcm6368-gpio-sysctl.yaml b/Documentation/devicetree/bindings/mfd/brcm,bcm6368-gpio-sysctl.yaml new file mode 100644 index 000000000000..307270b0cfed --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/brcm,bcm6368-gpio-sysctl.yaml @@ -0,0 +1,246 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/brcm,bcm6368-gpio-sysctl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6368 GPIO System Controller Device Tree Bindings + +maintainers: + - Álvaro Fernández Rojas + - Jonas Gorski + +description: + Broadcom BCM6368 SoC GPIO system controller which provides a register map + for controlling the GPIO and pins of the SoC. + +properties: + "#address-cells": true + + "#size-cells": true + + compatible: + items: + - const: brcm,bcm6368-gpio-sysctl + - const: syscon + - const: simple-mfd + + ranges: + maxItems: 1 + + reg: + maxItems: 1 + +patternProperties: + "^gpio@[0-9a-f]+$": + # Child node + type: object + $ref: "../gpio/brcm,bcm6345-gpio.yaml" + description: + GPIO controller for the SoC GPIOs. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml. + + "^pinctrl@[0-9a-f]+$": + # Child node + type: object + $ref: "../pinctrl/brcm,bcm6368-pinctrl.yaml" + description: + Pin controller for the SoC pins. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml. + +required: + - "#address-cells" + - compatible + - ranges + - reg + - "#size-cells" + +additionalProperties: false + +examples: + - | + syscon@10000080 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "brcm,bcm6368-gpio-sysctl", "syscon", "simple-mfd"; + reg = <0x10000080 0x80>; + ranges = <0 0x10000080 0x80>; + + gpio@0 { + compatible = "brcm,bcm6368-gpio"; + reg-names = "dirout", "dat"; + reg = <0x0 0x8>, <0x8 0x8>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 0 38>; + #gpio-cells = <2>; + }; + + pinctrl: pinctrl@18 { + compatible = "brcm,bcm6368-pinctrl"; + reg = <0x18 0x4>, <0x38 0x4>; + + pinctrl_analog_afe_0: analog_afe_0-pins { + function = "analog_afe_0"; + pins = "gpio0"; + }; + + pinctrl_analog_afe_1: analog_afe_1-pins { + function = "analog_afe_1"; + pins = "gpio1"; + }; + + pinctrl_sys_irq: sys_irq-pins { + function = "sys_irq"; + pins = "gpio2"; + }; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio3"; + }; + + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio4"; + }; + }; + + pinctrl_inet_led: inet_led-pins { + function = "inet_led"; + pins = "gpio5"; + }; + + pinctrl_ephy0_led: ephy0_led-pins { + function = "ephy0_led"; + pins = "gpio6"; + }; + + pinctrl_ephy1_led: ephy1_led-pins { + function = "ephy1_led"; + pins = "gpio7"; + }; + + pinctrl_ephy2_led: ephy2_led-pins { + function = "ephy2_led"; + pins = "gpio8"; + }; + + pinctrl_ephy3_led: ephy3_led-pins { + function = "ephy3_led"; + pins = "gpio9"; + }; + + pinctrl_robosw_led_data: robosw_led_data-pins { + function = "robosw_led_data"; + pins = "gpio10"; + }; + + pinctrl_robosw_led_clk: robosw_led_clk-pins { + function = "robosw_led_clk"; + pins = "gpio11"; + }; + + pinctrl_robosw_led0: robosw_led0-pins { + function = "robosw_led0"; + pins = "gpio12"; + }; + + pinctrl_robosw_led1: robosw_led1-pins { + function = "robosw_led1"; + pins = "gpio13"; + }; + + pinctrl_usb_device_led: usb_device_led-pins { + function = "usb_device_led"; + pins = "gpio14"; + }; + + pinctrl_pci: pci-pins { + pinctrl_pci_req1: pci_req1-pins { + function = "pci_req1"; + pins = "gpio16"; + }; + + pinctrl_pci_gnt1: pci_gnt1-pins { + function = "pci_gnt1"; + pins = "gpio17"; + }; + + pinctrl_pci_intb: pci_intb-pins { + function = "pci_intb"; + pins = "gpio18"; + }; + + pinctrl_pci_req0: pci_req0-pins { + function = "pci_req0"; + pins = "gpio19"; + }; + + pinctrl_pci_gnt0: pci_gnt0-pins { + function = "pci_gnt0"; + pins = "gpio20"; + }; + }; + + pinctrl_pcmcia: pcmcia-pins { + pinctrl_pcmcia_cd1: pcmcia_cd1-pins { + function = "pcmcia_cd1"; + pins = "gpio22"; + }; + + pinctrl_pcmcia_cd2: pcmcia_cd2-pins { + function = "pcmcia_cd2"; + pins = "gpio23"; + }; + + pinctrl_pcmcia_vs1: pcmcia_vs1-pins { + function = "pcmcia_vs1"; + pins = "gpio24"; + }; + + pinctrl_pcmcia_vs2: pcmcia_vs2-pins { + function = "pcmcia_vs2"; + pins = "gpio25"; + }; + }; + + pinctrl_ebi_cs2: ebi_cs2-pins { + function = "ebi_cs2"; + pins = "gpio26"; + }; + + pinctrl_ebi_cs3: ebi_cs3-pins { + function = "ebi_cs3"; + pins = "gpio27"; + }; + + pinctrl_spi_cs2: spi_cs2-pins { + function = "spi_cs2"; + pins = "gpio28"; + }; + + pinctrl_spi_cs3: spi_cs3-pins { + function = "spi_cs3"; + pins = "gpio29"; + }; + + pinctrl_spi_cs4: spi_cs4-pins { + function = "spi_cs4"; + pins = "gpio30"; + }; + + pinctrl_spi_cs5: spi_cs5-pins { + function = "spi_cs5"; + pins = "gpio31"; + }; + + pinctrl_uart1: uart1-pins { + function = "uart1"; + group = "uart1_grp"; + }; + }; + }; -- cgit v1.2.3 From 50554accf7a79980cd04481e8903073bdb706daf Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:17 +0100 Subject: pinctrl: add a pincontrol driver for BCM6368 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a pincontrol driver for BCM6368. BCM6368 allows muxing the first 32 GPIOs onto alternative functions. Not all are documented. Co-developed-by: Jonas Gorski Signed-off-by: Jonas Gorski Signed-off-by: Álvaro Fernández Rojas Link: https://lore.kernel.org/r/20210324081923.20379-17-noltari@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/Kconfig | 8 + drivers/pinctrl/bcm/Makefile | 1 + drivers/pinctrl/bcm/pinctrl-bcm6368.c | 523 ++++++++++++++++++++++++++++++++++ 3 files changed, 532 insertions(+) create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6368.c diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig index d3101d5e750f..aabd4b762aed 100644 --- a/drivers/pinctrl/bcm/Kconfig +++ b/drivers/pinctrl/bcm/Kconfig @@ -60,6 +60,14 @@ config PINCTRL_BCM6362 help Say Y here to enable the Broadcom BCM6362 GPIO driver. +config PINCTRL_BCM6368 + bool "Broadcom BCM6368 GPIO driver" + depends on (BMIPS_GENERIC || COMPILE_TEST) + select PINCTRL_BCM63XX + default BMIPS_GENERIC + help + Say Y here to enable the Broadcom BCM6368 GPIO driver. + config PINCTRL_IPROC_GPIO bool "Broadcom iProc GPIO (with PINCONF) driver" depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST) diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile index b9b09e5b914c..a1331bb9680e 100644 --- a/drivers/pinctrl/bcm/Makefile +++ b/drivers/pinctrl/bcm/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_PINCTRL_BCM63XX) += pinctrl-bcm63xx.o obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl-bcm6328.o obj-$(CONFIG_PINCTRL_BCM6358) += pinctrl-bcm6358.o obj-$(CONFIG_PINCTRL_BCM6362) += pinctrl-bcm6362.o +obj-$(CONFIG_PINCTRL_BCM6368) += pinctrl-bcm6368.o obj-$(CONFIG_PINCTRL_IPROC_GPIO) += pinctrl-iproc-gpio.o obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o obj-$(CONFIG_PINCTRL_NS) += pinctrl-ns.o diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6368.c b/drivers/pinctrl/bcm/pinctrl-bcm6368.c new file mode 100644 index 000000000000..838095f9e890 --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm6368.c @@ -0,0 +1,523 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM6368 GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas + * Copyright (C) 2016 Jonas Gorski + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../pinctrl-utils.h" + +#include "pinctrl-bcm63xx.h" + +#define BCM6368_NUM_GPIOS 38 + +#define BCM6368_MODE_REG 0x18 +#define BCM6368_BASEMODE_REG 0x38 +#define BCM6368_BASEMODE_MASK 0x7 +#define BCM6368_BASEMODE_GPIO 0x0 +#define BCM6368_BASEMODE_UART1 0x1 + +struct bcm6368_pingroup { + const char *name; + const unsigned * const pins; + const unsigned num_pins; +}; + +struct bcm6368_function { + const char *name; + const char * const *groups; + const unsigned num_groups; + + unsigned dir_out:16; + unsigned basemode:3; +}; + +struct bcm6368_priv { + struct regmap_field *overlays; +}; + +#define BCM6368_BASEMODE_PIN(a, b) \ + { \ + .number = a, \ + .name = b, \ + .drv_data = (void *)true \ + } + +static const struct pinctrl_pin_desc bcm6368_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + PINCTRL_PIN(2, "gpio2"), + PINCTRL_PIN(3, "gpio3"), + PINCTRL_PIN(4, "gpio4"), + PINCTRL_PIN(5, "gpio5"), + PINCTRL_PIN(6, "gpio6"), + PINCTRL_PIN(7, "gpio7"), + PINCTRL_PIN(8, "gpio8"), + PINCTRL_PIN(9, "gpio9"), + PINCTRL_PIN(10, "gpio10"), + PINCTRL_PIN(11, "gpio11"), + PINCTRL_PIN(12, "gpio12"), + PINCTRL_PIN(13, "gpio13"), + PINCTRL_PIN(14, "gpio14"), + PINCTRL_PIN(15, "gpio15"), + PINCTRL_PIN(16, "gpio16"), + PINCTRL_PIN(17, "gpio17"), + PINCTRL_PIN(18, "gpio18"), + PINCTRL_PIN(19, "gpio19"), + PINCTRL_PIN(20, "gpio20"), + PINCTRL_PIN(21, "gpio21"), + PINCTRL_PIN(22, "gpio22"), + PINCTRL_PIN(23, "gpio23"), + PINCTRL_PIN(24, "gpio24"), + PINCTRL_PIN(25, "gpio25"), + PINCTRL_PIN(26, "gpio26"), + PINCTRL_PIN(27, "gpio27"), + PINCTRL_PIN(28, "gpio28"), + PINCTRL_PIN(29, "gpio29"), + BCM6368_BASEMODE_PIN(30, "gpio30"), + BCM6368_BASEMODE_PIN(31, "gpio31"), + BCM6368_BASEMODE_PIN(32, "gpio32"), + BCM6368_BASEMODE_PIN(33, "gpio33"), + PINCTRL_PIN(34, "gpio34"), + PINCTRL_PIN(35, "gpio35"), + PINCTRL_PIN(36, "gpio36"), + PINCTRL_PIN(37, "gpio37"), +}; + +static unsigned gpio0_pins[] = { 0 }; +static unsigned gpio1_pins[] = { 1 }; +static unsigned gpio2_pins[] = { 2 }; +static unsigned gpio3_pins[] = { 3 }; +static unsigned gpio4_pins[] = { 4 }; +static unsigned gpio5_pins[] = { 5 }; +static unsigned gpio6_pins[] = { 6 }; +static unsigned gpio7_pins[] = { 7 }; +static unsigned gpio8_pins[] = { 8 }; +static unsigned gpio9_pins[] = { 9 }; +static unsigned gpio10_pins[] = { 10 }; +static unsigned gpio11_pins[] = { 11 }; +static unsigned gpio12_pins[] = { 12 }; +static unsigned gpio13_pins[] = { 13 }; +static unsigned gpio14_pins[] = { 14 }; +static unsigned gpio15_pins[] = { 15 }; +static unsigned gpio16_pins[] = { 16 }; +static unsigned gpio17_pins[] = { 17 }; +static unsigned gpio18_pins[] = { 18 }; +static unsigned gpio19_pins[] = { 19 }; +static unsigned gpio20_pins[] = { 20 }; +static unsigned gpio21_pins[] = { 21 }; +static unsigned gpio22_pins[] = { 22 }; +static unsigned gpio23_pins[] = { 23 }; +static unsigned gpio24_pins[] = { 24 }; +static unsigned gpio25_pins[] = { 25 }; +static unsigned gpio26_pins[] = { 26 }; +static unsigned gpio27_pins[] = { 27 }; +static unsigned gpio28_pins[] = { 28 }; +static unsigned gpio29_pins[] = { 29 }; +static unsigned gpio30_pins[] = { 30 }; +static unsigned gpio31_pins[] = { 31 }; +static unsigned uart1_grp_pins[] = { 30, 31, 32, 33 }; + +#define BCM6368_GROUP(n) \ + { \ + .name = #n, \ + .pins = n##_pins, \ + .num_pins = ARRAY_SIZE(n##_pins), \ + } + +static struct bcm6368_pingroup bcm6368_groups[] = { + BCM6368_GROUP(gpio0), + BCM6368_GROUP(gpio1), + BCM6368_GROUP(gpio2), + BCM6368_GROUP(gpio3), + BCM6368_GROUP(gpio4), + BCM6368_GROUP(gpio5), + BCM6368_GROUP(gpio6), + BCM6368_GROUP(gpio7), + BCM6368_GROUP(gpio8), + BCM6368_GROUP(gpio9), + BCM6368_GROUP(gpio10), + BCM6368_GROUP(gpio11), + BCM6368_GROUP(gpio12), + BCM6368_GROUP(gpio13), + BCM6368_GROUP(gpio14), + BCM6368_GROUP(gpio15), + BCM6368_GROUP(gpio16), + BCM6368_GROUP(gpio17), + BCM6368_GROUP(gpio18), + BCM6368_GROUP(gpio19), + BCM6368_GROUP(gpio20), + BCM6368_GROUP(gpio21), + BCM6368_GROUP(gpio22), + BCM6368_GROUP(gpio23), + BCM6368_GROUP(gpio24), + BCM6368_GROUP(gpio25), + BCM6368_GROUP(gpio26), + BCM6368_GROUP(gpio27), + BCM6368_GROUP(gpio28), + BCM6368_GROUP(gpio29), + BCM6368_GROUP(gpio30), + BCM6368_GROUP(gpio31), + BCM6368_GROUP(uart1_grp), +}; + +static const char * const analog_afe_0_groups[] = { + "gpio0", +}; + +static const char * const analog_afe_1_groups[] = { + "gpio1", +}; + +static const char * const sys_irq_groups[] = { + "gpio2", +}; + +static const char * const serial_led_data_groups[] = { + "gpio3", +}; + +static const char * const serial_led_clk_groups[] = { + "gpio4", +}; + +static const char * const inet_led_groups[] = { + "gpio5", +}; + +static const char * const ephy0_led_groups[] = { + "gpio6", +}; + +static const char * const ephy1_led_groups[] = { + "gpio7", +}; + +static const char * const ephy2_led_groups[] = { + "gpio8", +}; + +static const char * const ephy3_led_groups[] = { + "gpio9", +}; + +static const char * const robosw_led_data_groups[] = { + "gpio10", +}; + +static const char * const robosw_led_clk_groups[] = { + "gpio11", +}; + +static const char * const robosw_led0_groups[] = { + "gpio12", +}; + +static const char * const robosw_led1_groups[] = { + "gpio13", +}; + +static const char * const usb_device_led_groups[] = { + "gpio14", +}; + +static const char * const pci_req1_groups[] = { + "gpio16", +}; + +static const char * const pci_gnt1_groups[] = { + "gpio17", +}; + +static const char * const pci_intb_groups[] = { + "gpio18", +}; + +static const char * const pci_req0_groups[] = { + "gpio19", +}; + +static const char * const pci_gnt0_groups[] = { + "gpio20", +}; + +static const char * const pcmcia_cd1_groups[] = { + "gpio22", +}; + +static const char * const pcmcia_cd2_groups[] = { + "gpio23", +}; + +static const char * const pcmcia_vs1_groups[] = { + "gpio24", +}; + +static const char * const pcmcia_vs2_groups[] = { + "gpio25", +}; + +static const char * const ebi_cs2_groups[] = { + "gpio26", +}; + +static const char * const ebi_cs3_groups[] = { + "gpio27", +}; + +static const char * const spi_cs2_groups[] = { + "gpio28", +}; + +static const char * const spi_cs3_groups[] = { + "gpio29", +}; + +static const char * const spi_cs4_groups[] = { + "gpio30", +}; + +static const char * const spi_cs5_groups[] = { + "gpio31", +}; + +static const char * const uart1_groups[] = { + "uart1_grp", +}; + +#define BCM6368_FUN(n, out) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .dir_out = out, \ + } + +#define BCM6368_BASEMODE_FUN(n, val, out) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .basemode = BCM6368_BASEMODE_##val, \ + .dir_out = out, \ + } + +static const struct bcm6368_function bcm6368_funcs[] = { + BCM6368_FUN(analog_afe_0, 1), + BCM6368_FUN(analog_afe_1, 1), + BCM6368_FUN(sys_irq, 1), + BCM6368_FUN(serial_led_data, 1), + BCM6368_FUN(serial_led_clk, 1), + BCM6368_FUN(inet_led, 1), + BCM6368_FUN(ephy0_led, 1), + BCM6368_FUN(ephy1_led, 1), + BCM6368_FUN(ephy2_led, 1), + BCM6368_FUN(ephy3_led, 1), + BCM6368_FUN(robosw_led_data, 1), + BCM6368_FUN(robosw_led_clk, 1), + BCM6368_FUN(robosw_led0, 1), + BCM6368_FUN(robosw_led1, 1), + BCM6368_FUN(usb_device_led, 1), + BCM6368_FUN(pci_req1, 0), + BCM6368_FUN(pci_gnt1, 0), + BCM6368_FUN(pci_intb, 0), + BCM6368_FUN(pci_req0, 0), + BCM6368_FUN(pci_gnt0, 0), + BCM6368_FUN(pcmcia_cd1, 0), + BCM6368_FUN(pcmcia_cd2, 0), + BCM6368_FUN(pcmcia_vs1, 0), + BCM6368_FUN(pcmcia_vs2, 0), + BCM6368_FUN(ebi_cs2, 1), + BCM6368_FUN(ebi_cs3, 1), + BCM6368_FUN(spi_cs2, 1), + BCM6368_FUN(spi_cs3, 1), + BCM6368_FUN(spi_cs4, 1), + BCM6368_FUN(spi_cs5, 1), + BCM6368_BASEMODE_FUN(uart1, UART1, 0x6), +}; + +static int bcm6368_pinctrl_get_group_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6368_groups); +} + +static const char *bcm6368_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + return bcm6368_groups[group].name; +} + +static int bcm6368_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned group, const unsigned **pins, + unsigned *num_pins) +{ + *pins = bcm6368_groups[group].pins; + *num_pins = bcm6368_groups[group].num_pins; + + return 0; +} + +static int bcm6368_pinctrl_get_func_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6368_funcs); +} + +static const char *bcm6368_pinctrl_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return bcm6368_funcs[selector].name; +} + +static int bcm6368_pinctrl_get_groups(struct pinctrl_dev *pctldev, + unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = bcm6368_funcs[selector].groups; + *num_groups = bcm6368_funcs[selector].num_groups; + + return 0; +} + +static int bcm6368_pinctrl_set_mux(struct pinctrl_dev *pctldev, + unsigned selector, unsigned group) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + struct bcm6368_priv *priv = pc->driver_data; + const struct bcm6368_pingroup *pg = &bcm6368_groups[group]; + const struct bcm6368_function *fun = &bcm6368_funcs[selector]; + int i, pin; + + if (fun->basemode) { + unsigned int mask = 0; + + for (i = 0; i < pg->num_pins; i++) { + pin = pg->pins[i]; + if (pin < BCM63XX_BANK_GPIOS) + mask |= BIT(pin); + } + + regmap_update_bits(pc->regs, BCM6368_MODE_REG, mask, 0); + regmap_field_write(priv->overlays, fun->basemode); + } else { + pin = pg->pins[0]; + + if (bcm6368_pins[pin].drv_data) + regmap_field_write(priv->overlays, + BCM6368_BASEMODE_GPIO); + + regmap_update_bits(pc->regs, BCM6368_MODE_REG, BIT(pin), + BIT(pin)); + } + + for (pin = 0; pin < pg->num_pins; pin++) { + struct pinctrl_gpio_range *range; + int hw_gpio = bcm6368_pins[pin].number; + + range = pinctrl_find_gpio_range_from_pin(pctldev, hw_gpio); + if (range) { + struct gpio_chip *gc = range->gc; + + if (fun->dir_out & BIT(pin)) + gc->direction_output(gc, hw_gpio, 0); + else + gc->direction_input(gc, hw_gpio); + } + } + + return 0; +} + +static int bcm6368_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + struct bcm6368_priv *priv = pc->driver_data; + + if (offset >= BCM63XX_BANK_GPIOS && !bcm6368_pins[offset].drv_data) + return 0; + + /* disable all functions using this pin */ + if (offset < BCM63XX_BANK_GPIOS) + regmap_update_bits(pc->regs, BCM6368_MODE_REG, BIT(offset), 0); + + if (bcm6368_pins[offset].drv_data) + regmap_field_write(priv->overlays, BCM6368_BASEMODE_GPIO); + + return 0; +} + +static struct pinctrl_ops bcm6368_pctl_ops = { + .dt_free_map = pinctrl_utils_free_map, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .get_group_name = bcm6368_pinctrl_get_group_name, + .get_group_pins = bcm6368_pinctrl_get_group_pins, + .get_groups_count = bcm6368_pinctrl_get_group_count, +}; + +static struct pinmux_ops bcm6368_pmx_ops = { + .get_function_groups = bcm6368_pinctrl_get_groups, + .get_function_name = bcm6368_pinctrl_get_func_name, + .get_functions_count = bcm6368_pinctrl_get_func_count, + .gpio_request_enable = bcm6368_gpio_request_enable, + .set_mux = bcm6368_pinctrl_set_mux, + .strict = true, +}; + +static const struct bcm63xx_pinctrl_soc bcm6368_soc = { + .ngpios = BCM6368_NUM_GPIOS, + .npins = ARRAY_SIZE(bcm6368_pins), + .pctl_ops = &bcm6368_pctl_ops, + .pins = bcm6368_pins, + .pmx_ops = &bcm6368_pmx_ops, +}; + +static int bcm6368_pinctrl_probe(struct platform_device *pdev) +{ + struct reg_field overlays = REG_FIELD(BCM6368_BASEMODE_REG, 0, 15); + struct device *dev = &pdev->dev; + struct bcm63xx_pinctrl *pc; + struct bcm6368_priv *priv; + int err; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + err = bcm63xx_pinctrl_probe(pdev, &bcm6368_soc, (void *) priv); + if (err) + return err; + + pc = platform_get_drvdata(pdev); + + priv->overlays = devm_regmap_field_alloc(dev, pc->regs, overlays); + if (IS_ERR(priv->overlays)) + return PTR_ERR(priv->overlays); + + return 0; +} + +static const struct of_device_id bcm6368_pinctrl_match[] = { + { .compatible = "brcm,bcm6368-pinctrl", }, + { /* sentinel */ } +}; + +static struct platform_driver bcm6368_pinctrl_driver = { + .probe = bcm6368_pinctrl_probe, + .driver = { + .name = "bcm6368-pinctrl", + .of_match_table = bcm6368_pinctrl_match, + }, +}; + +builtin_platform_driver(bcm6368_pinctrl_driver); -- cgit v1.2.3 From 9b3303413379af8bed307cd465fe7aa1bc3569ea Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:18 +0100 Subject: dt-bindings: add BCM63268 pincontroller binding documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add binding documentation for the pincontrol core found in the BCM63268 family SoCs. Co-developed-by: Jonas Gorski Signed-off-by: Jonas Gorski Signed-off-by: Álvaro Fernández Rojas Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210324081923.20379-18-noltari@gmail.com Signed-off-by: Linus Walleij --- .../bindings/pinctrl/brcm,bcm63268-pinctrl.yaml | 164 +++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml new file mode 100644 index 000000000000..58ffed44b3c4 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml @@ -0,0 +1,164 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm63268-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM63268 pin controller + +maintainers: + - Álvaro Fernández Rojas + - Jonas Gorski + +description: + Bindings for Broadcom's BCM63268 memory-mapped pin controller. + +properties: + compatible: + const: brcm,bcm63268-pinctrl + + reg: + maxItems: 3 + +patternProperties: + '-pins$': + type: object + $ref: pinmux-node.yaml# + + properties: + function: + enum: [ serial_led_clk, serial_led_data, hsspi_cs4, hsspi_cs5, + hsspi_cs6, hsspi_cs7, adsl_spi_miso, adsl_spi_mosi, + vreq_clk, pcie_clkreq_b, robosw_led_clk, robosw_led_data, + nand, gpio35_alt, dectpd, vdsl_phy_override_0, + vdsl_phy_override_1, vdsl_phy_override_2, + vdsl_phy_override_3, dsl_gpio8, dsl_gpio9 ] + + pins: + enum: [ gpio0, gpio1, gpio16, gpio17, gpio8, gpio9, gpio18, gpio19, + gpio22, gpio23, gpio30, gpio31, nand_grp, gpio35 + dectpd_grp, vdsl_phy_override_0_grp, + vdsl_phy_override_1_grp, vdsl_phy_override_2_grp, + vdsl_phy_override_3_grp, dsl_gpio8, dsl_gpio9 ] + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + pinctrl@10 { + compatible = "brcm,bcm63268-pinctrl"; + reg = <0x10 0x4>, <0x18 0x8>, <0x38 0x4>; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio0"; + }; + + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio1"; + }; + }; + + pinctrl_hsspi_cs4: hsspi_cs4-pins { + function = "hsspi_cs4"; + pins = "gpio16"; + }; + + pinctrl_hsspi_cs5: hsspi_cs5-pins { + function = "hsspi_cs5"; + pins = "gpio17"; + }; + + pinctrl_hsspi_cs6: hsspi_cs6-pins { + function = "hsspi_cs6"; + pins = "gpio8"; + }; + + pinctrl_hsspi_cs7: hsspi_cs7-pins { + function = "hsspi_cs7"; + pins = "gpio9"; + }; + + pinctrl_adsl_spi: adsl_spi-pins { + pinctrl_adsl_spi_miso: adsl_spi_miso-pins { + function = "adsl_spi_miso"; + pins = "gpio18"; + }; + + pinctrl_adsl_spi_mosi: adsl_spi_mosi-pins { + function = "adsl_spi_mosi"; + pins = "gpio19"; + }; + }; + + pinctrl_vreq_clk: vreq_clk-pins { + function = "vreq_clk"; + pins = "gpio22"; + }; + + pinctrl_pcie_clkreq_b: pcie_clkreq_b-pins { + function = "pcie_clkreq_b"; + pins = "gpio23"; + }; + + pinctrl_robosw_led_clk: robosw_led_clk-pins { + function = "robosw_led_clk"; + pins = "gpio30"; + }; + + pinctrl_robosw_led_data: robosw_led_data-pins { + function = "robosw_led_data"; + pins = "gpio31"; + }; + + pinctrl_nand: nand-pins { + function = "nand"; + group = "nand_grp"; + }; + + pinctrl_gpio35_alt: gpio35_alt-pins { + function = "gpio35_alt"; + pin = "gpio35"; + }; + + pinctrl_dectpd: dectpd-pins { + function = "dectpd"; + group = "dectpd_grp"; + }; + + pinctrl_vdsl_phy_override_0: vdsl_phy_override_0-pins { + function = "vdsl_phy_override_0"; + group = "vdsl_phy_override_0_grp"; + }; + + pinctrl_vdsl_phy_override_1: vdsl_phy_override_1-pins { + function = "vdsl_phy_override_1"; + group = "vdsl_phy_override_1_grp"; + }; + + pinctrl_vdsl_phy_override_2: vdsl_phy_override_2-pins { + function = "vdsl_phy_override_2"; + group = "vdsl_phy_override_2_grp"; + }; + + pinctrl_vdsl_phy_override_3: vdsl_phy_override_3-pins { + function = "vdsl_phy_override_3"; + group = "vdsl_phy_override_3_grp"; + }; + + pinctrl_dsl_gpio8: dsl_gpio8-pins { + function = "dsl_gpio8"; + group = "dsl_gpio8"; + }; + + pinctrl_dsl_gpio9: dsl_gpio9-pins { + function = "dsl_gpio9"; + group = "dsl_gpio9"; + }; + }; -- cgit v1.2.3 From ff8324355d7ae2e4ebbd304de27bb5fa75e20c6a Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:19 +0100 Subject: dt-bindings: add BCM63268 GPIO sysctl binding documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add binding documentation for the GPIO sysctl found in BCM63268 SoCs. Signed-off-by: Álvaro Fernández Rojas Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210324081923.20379-19-noltari@gmail.com Signed-off-by: Linus Walleij --- .../bindings/mfd/brcm,bcm63268-gpio-sysctl.yaml | 194 +++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/brcm,bcm63268-gpio-sysctl.yaml diff --git a/Documentation/devicetree/bindings/mfd/brcm,bcm63268-gpio-sysctl.yaml b/Documentation/devicetree/bindings/mfd/brcm,bcm63268-gpio-sysctl.yaml new file mode 100644 index 000000000000..c7771c86d7c1 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/brcm,bcm63268-gpio-sysctl.yaml @@ -0,0 +1,194 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/brcm,bcm63268-gpio-sysctl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM63268 GPIO System Controller Device Tree Bindings + +maintainers: + - Álvaro Fernández Rojas + - Jonas Gorski + +description: + Broadcom BCM63268 SoC GPIO system controller which provides a register map + for controlling the GPIO and pins of the SoC. + +properties: + "#address-cells": true + + "#size-cells": true + + compatible: + items: + - const: brcm,bcm63268-gpio-sysctl + - const: syscon + - const: simple-mfd + + ranges: + maxItems: 1 + + reg: + maxItems: 1 + +patternProperties: + "^gpio@[0-9a-f]+$": + # Child node + type: object + $ref: "../gpio/brcm,bcm6345-gpio.yaml" + description: + GPIO controller for the SoC GPIOs. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml. + + "^pinctrl@[0-9a-f]+$": + # Child node + type: object + $ref: "../pinctrl/brcm,bcm63268-pinctrl.yaml" + description: + Pin controller for the SoC pins. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml. + +required: + - "#address-cells" + - compatible + - ranges + - reg + - "#size-cells" + +additionalProperties: false + +examples: + - | + syscon@100000c0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "brcm,bcm63268-gpio-sysctl", "syscon", "simple-mfd"; + reg = <0x100000c0 0x80>; + ranges = <0 0x100000c0 0x80>; + + gpio@0 { + compatible = "brcm,bcm63268-gpio"; + reg-names = "dirout", "dat"; + reg = <0x0 0x8>, <0x8 0x8>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 0 52>; + #gpio-cells = <2>; + }; + + pinctrl: pinctrl@10 { + compatible = "brcm,bcm63268-pinctrl"; + reg = <0x10 0x4>, <0x18 0x8>, <0x38 0x4>; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio0"; + }; + + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio1"; + }; + }; + + pinctrl_hsspi_cs4: hsspi_cs4-pins { + function = "hsspi_cs4"; + pins = "gpio16"; + }; + + pinctrl_hsspi_cs5: hsspi_cs5-pins { + function = "hsspi_cs5"; + pins = "gpio17"; + }; + + pinctrl_hsspi_cs6: hsspi_cs6-pins { + function = "hsspi_cs6"; + pins = "gpio8"; + }; + + pinctrl_hsspi_cs7: hsspi_cs7-pins { + function = "hsspi_cs7"; + pins = "gpio9"; + }; + + pinctrl_adsl_spi: adsl_spi-pins { + pinctrl_adsl_spi_miso: adsl_spi_miso-pins { + function = "adsl_spi_miso"; + pins = "gpio18"; + }; + + pinctrl_adsl_spi_mosi: adsl_spi_mosi-pins { + function = "adsl_spi_mosi"; + pins = "gpio19"; + }; + }; + + pinctrl_vreq_clk: vreq_clk-pins { + function = "vreq_clk"; + pins = "gpio22"; + }; + + pinctrl_pcie_clkreq_b: pcie_clkreq_b-pins { + function = "pcie_clkreq_b"; + pins = "gpio23"; + }; + + pinctrl_robosw_led_clk: robosw_led_clk-pins { + function = "robosw_led_clk"; + pins = "gpio30"; + }; + + pinctrl_robosw_led_data: robosw_led_data-pins { + function = "robosw_led_data"; + pins = "gpio31"; + }; + + pinctrl_nand: nand-pins { + function = "nand"; + group = "nand_grp"; + }; + + pinctrl_gpio35_alt: gpio35_alt-pins { + function = "gpio35_alt"; + pin = "gpio35"; + }; + + pinctrl_dectpd: dectpd-pins { + function = "dectpd"; + group = "dectpd_grp"; + }; + + pinctrl_vdsl_phy_override_0: vdsl_phy_override_0-pins { + function = "vdsl_phy_override_0"; + group = "vdsl_phy_override_0_grp"; + }; + + pinctrl_vdsl_phy_override_1: vdsl_phy_override_1-pins { + function = "vdsl_phy_override_1"; + group = "vdsl_phy_override_1_grp"; + }; + + pinctrl_vdsl_phy_override_2: vdsl_phy_override_2-pins { + function = "vdsl_phy_override_2"; + group = "vdsl_phy_override_2_grp"; + }; + + pinctrl_vdsl_phy_override_3: vdsl_phy_override_3-pins { + function = "vdsl_phy_override_3"; + group = "vdsl_phy_override_3_grp"; + }; + + pinctrl_dsl_gpio8: dsl_gpio8-pins { + function = "dsl_gpio8"; + group = "dsl_gpio8"; + }; + + pinctrl_dsl_gpio9: dsl_gpio9-pins { + function = "dsl_gpio9"; + group = "dsl_gpio9"; + }; + }; + }; -- cgit v1.2.3 From 155cca1b0794a8f541e7eaa45be70df0a49964f3 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:20 +0100 Subject: pinctrl: add a pincontrol driver for BCM63268 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a pincontrol driver for BCM63268. BCM63268 allows muxing GPIOs to different functions. Depending on the mux, these are either single pin configurations or whole pin groups. Co-developed-by: Jonas Gorski Signed-off-by: Jonas Gorski Signed-off-by: Álvaro Fernández Rojas Link: https://lore.kernel.org/r/20210324081923.20379-20-noltari@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/Kconfig | 8 + drivers/pinctrl/bcm/Makefile | 1 + drivers/pinctrl/bcm/pinctrl-bcm63268.c | 643 +++++++++++++++++++++++++++++++++ 3 files changed, 652 insertions(+) create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63268.c diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig index aabd4b762aed..186985846120 100644 --- a/drivers/pinctrl/bcm/Kconfig +++ b/drivers/pinctrl/bcm/Kconfig @@ -68,6 +68,14 @@ config PINCTRL_BCM6368 help Say Y here to enable the Broadcom BCM6368 GPIO driver. +config PINCTRL_BCM63268 + bool "Broadcom BCM63268 GPIO driver" + depends on (BMIPS_GENERIC || COMPILE_TEST) + select PINCTRL_BCM63XX + default BMIPS_GENERIC + help + Say Y here to enable the Broadcom BCM63268 GPIO driver. + config PINCTRL_IPROC_GPIO bool "Broadcom iProc GPIO (with PINCONF) driver" depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST) diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile index a1331bb9680e..4117847fd279 100644 --- a/drivers/pinctrl/bcm/Makefile +++ b/drivers/pinctrl/bcm/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl-bcm6328.o obj-$(CONFIG_PINCTRL_BCM6358) += pinctrl-bcm6358.o obj-$(CONFIG_PINCTRL_BCM6362) += pinctrl-bcm6362.o obj-$(CONFIG_PINCTRL_BCM6368) += pinctrl-bcm6368.o +obj-$(CONFIG_PINCTRL_BCM63268) += pinctrl-bcm63268.o obj-$(CONFIG_PINCTRL_IPROC_GPIO) += pinctrl-iproc-gpio.o obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o obj-$(CONFIG_PINCTRL_NS) += pinctrl-ns.o diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63268.c b/drivers/pinctrl/bcm/pinctrl-bcm63268.c new file mode 100644 index 000000000000..d4c5fad7fb7d --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm63268.c @@ -0,0 +1,643 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM63268 GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas + * Copyright (C) 2016 Jonas Gorski + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../pinctrl-utils.h" + +#include "pinctrl-bcm63xx.h" + +#define BCM63268_NUM_GPIOS 52 +#define BCM63268_NUM_LEDS 24 + +#define BCM63268_LED_REG 0x10 +#define BCM63268_MODE_REG 0x18 +#define BCM63268_CTRL_REG 0x1c +#define BCM63268_BASEMODE_REG 0x38 +#define BCM63268_BASEMODE_NAND BIT(2) /* GPIOs 2-7, 24-31 */ +#define BCM63268_BASEMODE_GPIO35 BIT(4) /* GPIO 35 */ +#define BCM63268_BASEMODE_DECTPD BIT(5) /* GPIOs 8/9 */ +#define BCM63268_BASEMODE_VDSL_PHY_0 BIT(6) /* GPIOs 10/11 */ +#define BCM63268_BASEMODE_VDSL_PHY_1 BIT(7) /* GPIOs 12/13 */ +#define BCM63268_BASEMODE_VDSL_PHY_2 BIT(8) /* GPIOs 24/25 */ +#define BCM63268_BASEMODE_VDSL_PHY_3 BIT(9) /* GPIOs 26/27 */ + +enum bcm63268_pinctrl_reg { + BCM63268_LEDCTRL, + BCM63268_MODE, + BCM63268_CTRL, + BCM63268_BASEMODE, +}; + +struct bcm63268_pingroup { + const char *name; + const unsigned * const pins; + const unsigned num_pins; +}; + +struct bcm63268_function { + const char *name; + const char * const *groups; + const unsigned num_groups; + + enum bcm63268_pinctrl_reg reg; + uint32_t mask; +}; + +#define BCM63268_PIN(a, b, basemode) \ + { \ + .number = a, \ + .name = b, \ + .drv_data = (void *)(basemode) \ + } + +static const struct pinctrl_pin_desc bcm63268_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + BCM63268_PIN(2, "gpio2", BCM63268_BASEMODE_NAND), + BCM63268_PIN(3, "gpio3", BCM63268_BASEMODE_NAND), + BCM63268_PIN(4, "gpio4", BCM63268_BASEMODE_NAND), + BCM63268_PIN(5, "gpio5", BCM63268_BASEMODE_NAND), + BCM63268_PIN(6, "gpio6", BCM63268_BASEMODE_NAND), + BCM63268_PIN(7, "gpio7", BCM63268_BASEMODE_NAND), + BCM63268_PIN(8, "gpio8", BCM63268_BASEMODE_DECTPD), + BCM63268_PIN(9, "gpio9", BCM63268_BASEMODE_DECTPD), + BCM63268_PIN(10, "gpio10", BCM63268_BASEMODE_VDSL_PHY_0), + BCM63268_PIN(11, "gpio11", BCM63268_BASEMODE_VDSL_PHY_0), + BCM63268_PIN(12, "gpio12", BCM63268_BASEMODE_VDSL_PHY_1), + BCM63268_PIN(13, "gpio13", BCM63268_BASEMODE_VDSL_PHY_1), + PINCTRL_PIN(14, "gpio14"), + PINCTRL_PIN(15, "gpio15"), + PINCTRL_PIN(16, "gpio16"), + PINCTRL_PIN(17, "gpio17"), + PINCTRL_PIN(18, "gpio18"), + PINCTRL_PIN(19, "gpio19"), + PINCTRL_PIN(20, "gpio20"), + PINCTRL_PIN(21, "gpio21"), + PINCTRL_PIN(22, "gpio22"), + PINCTRL_PIN(23, "gpio23"), + BCM63268_PIN(24, "gpio24", + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_2), + BCM63268_PIN(25, "gpio25", + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_2), + BCM63268_PIN(26, "gpio26", + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_3), + BCM63268_PIN(27, "gpio27", + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_3), + BCM63268_PIN(28, "gpio28", BCM63268_BASEMODE_NAND), + BCM63268_PIN(29, "gpio29", BCM63268_BASEMODE_NAND), + BCM63268_PIN(30, "gpio30", BCM63268_BASEMODE_NAND), + BCM63268_PIN(31, "gpio31", BCM63268_BASEMODE_NAND), + PINCTRL_PIN(32, "gpio32"), + PINCTRL_PIN(33, "gpio33"), + PINCTRL_PIN(34, "gpio34"), + PINCTRL_PIN(35, "gpio35"), + PINCTRL_PIN(36, "gpio36"), + PINCTRL_PIN(37, "gpio37"), + PINCTRL_PIN(38, "gpio38"), + PINCTRL_PIN(39, "gpio39"), + PINCTRL_PIN(40, "gpio40"), + PINCTRL_PIN(41, "gpio41"), + PINCTRL_PIN(42, "gpio42"), + PINCTRL_PIN(43, "gpio43"), + PINCTRL_PIN(44, "gpio44"), + PINCTRL_PIN(45, "gpio45"), + PINCTRL_PIN(46, "gpio46"), + PINCTRL_PIN(47, "gpio47"), + PINCTRL_PIN(48, "gpio48"), + PINCTRL_PIN(49, "gpio49"), + PINCTRL_PIN(50, "gpio50"), + PINCTRL_PIN(51, "gpio51"), +}; + +static unsigned gpio0_pins[] = { 0 }; +static unsigned gpio1_pins[] = { 1 }; +static unsigned gpio2_pins[] = { 2 }; +static unsigned gpio3_pins[] = { 3 }; +static unsigned gpio4_pins[] = { 4 }; +static unsigned gpio5_pins[] = { 5 }; +static unsigned gpio6_pins[] = { 6 }; +static unsigned gpio7_pins[] = { 7 }; +static unsigned gpio8_pins[] = { 8 }; +static unsigned gpio9_pins[] = { 9 }; +static unsigned gpio10_pins[] = { 10 }; +static unsigned gpio11_pins[] = { 11 }; +static unsigned gpio12_pins[] = { 12 }; +static unsigned gpio13_pins[] = { 13 }; +static unsigned gpio14_pins[] = { 14 }; +static unsigned gpio15_pins[] = { 15 }; +static unsigned gpio16_pins[] = { 16 }; +static unsigned gpio17_pins[] = { 17 }; +static unsigned gpio18_pins[] = { 18 }; +static unsigned gpio19_pins[] = { 19 }; +static unsigned gpio20_pins[] = { 20 }; +static unsigned gpio21_pins[] = { 21 }; +static unsigned gpio22_pins[] = { 22 }; +static unsigned gpio23_pins[] = { 23 }; +static unsigned gpio24_pins[] = { 24 }; +static unsigned gpio25_pins[] = { 25 }; +static unsigned gpio26_pins[] = { 26 }; +static unsigned gpio27_pins[] = { 27 }; +static unsigned gpio28_pins[] = { 28 }; +static unsigned gpio29_pins[] = { 29 }; +static unsigned gpio30_pins[] = { 30 }; +static unsigned gpio31_pins[] = { 31 }; +static unsigned gpio32_pins[] = { 32 }; +static unsigned gpio33_pins[] = { 33 }; +static unsigned gpio34_pins[] = { 34 }; +static unsigned gpio35_pins[] = { 35 }; +static unsigned gpio36_pins[] = { 36 }; +static unsigned gpio37_pins[] = { 37 }; +static unsigned gpio38_pins[] = { 38 }; +static unsigned gpio39_pins[] = { 39 }; +static unsigned gpio40_pins[] = { 40 }; +static unsigned gpio41_pins[] = { 41 }; +static unsigned gpio42_pins[] = { 42 }; +static unsigned gpio43_pins[] = { 43 }; +static unsigned gpio44_pins[] = { 44 }; +static unsigned gpio45_pins[] = { 45 }; +static unsigned gpio46_pins[] = { 46 }; +static unsigned gpio47_pins[] = { 47 }; +static unsigned gpio48_pins[] = { 48 }; +static unsigned gpio49_pins[] = { 49 }; +static unsigned gpio50_pins[] = { 50 }; +static unsigned gpio51_pins[] = { 51 }; + +static unsigned nand_grp_pins[] = { + 2, 3, 4, 5, 6, 7, 24, + 25, 26, 27, 28, 29, 30, 31, +}; + +static unsigned dectpd_grp_pins[] = { 8, 9 }; +static unsigned vdsl_phy0_grp_pins[] = { 10, 11 }; +static unsigned vdsl_phy1_grp_pins[] = { 12, 13 }; +static unsigned vdsl_phy2_grp_pins[] = { 24, 25 }; +static unsigned vdsl_phy3_grp_pins[] = { 26, 27 }; + +#define BCM63268_GROUP(n) \ + { \ + .name = #n, \ + .pins = n##_pins, \ + .num_pins = ARRAY_SIZE(n##_pins), \ + } + +static struct bcm63268_pingroup bcm63268_groups[] = { + BCM63268_GROUP(gpio0), + BCM63268_GROUP(gpio1), + BCM63268_GROUP(gpio2), + BCM63268_GROUP(gpio3), + BCM63268_GROUP(gpio4), + BCM63268_GROUP(gpio5), + BCM63268_GROUP(gpio6), + BCM63268_GROUP(gpio7), + BCM63268_GROUP(gpio8), + BCM63268_GROUP(gpio9), + BCM63268_GROUP(gpio10), + BCM63268_GROUP(gpio11), + BCM63268_GROUP(gpio12), + BCM63268_GROUP(gpio13), + BCM63268_GROUP(gpio14), + BCM63268_GROUP(gpio15), + BCM63268_GROUP(gpio16), + BCM63268_GROUP(gpio17), + BCM63268_GROUP(gpio18), + BCM63268_GROUP(gpio19), + BCM63268_GROUP(gpio20), + BCM63268_GROUP(gpio21), + BCM63268_GROUP(gpio22), + BCM63268_GROUP(gpio23), + BCM63268_GROUP(gpio24), + BCM63268_GROUP(gpio25), + BCM63268_GROUP(gpio26), + BCM63268_GROUP(gpio27), + BCM63268_GROUP(gpio28), + BCM63268_GROUP(gpio29), + BCM63268_GROUP(gpio30), + BCM63268_GROUP(gpio31), + BCM63268_GROUP(gpio32), + BCM63268_GROUP(gpio33), + BCM63268_GROUP(gpio34), + BCM63268_GROUP(gpio35), + BCM63268_GROUP(gpio36), + BCM63268_GROUP(gpio37), + BCM63268_GROUP(gpio38), + BCM63268_GROUP(gpio39), + BCM63268_GROUP(gpio40), + BCM63268_GROUP(gpio41), + BCM63268_GROUP(gpio42), + BCM63268_GROUP(gpio43), + BCM63268_GROUP(gpio44), + BCM63268_GROUP(gpio45), + BCM63268_GROUP(gpio46), + BCM63268_GROUP(gpio47), + BCM63268_GROUP(gpio48), + BCM63268_GROUP(gpio49), + BCM63268_GROUP(gpio50), + BCM63268_GROUP(gpio51), + + /* multi pin groups */ + BCM63268_GROUP(nand_grp), + BCM63268_GROUP(dectpd_grp), + BCM63268_GROUP(vdsl_phy0_grp), + BCM63268_GROUP(vdsl_phy1_grp), + BCM63268_GROUP(vdsl_phy2_grp), + BCM63268_GROUP(vdsl_phy3_grp), +}; + +static const char * const led_groups[] = { + "gpio0", + "gpio1", + "gpio2", + "gpio3", + "gpio4", + "gpio5", + "gpio6", + "gpio7", + "gpio8", + "gpio9", + "gpio10", + "gpio11", + "gpio12", + "gpio13", + "gpio14", + "gpio15", + "gpio16", + "gpio17", + "gpio18", + "gpio19", + "gpio20", + "gpio21", + "gpio22", + "gpio23", +}; + +static const char * const serial_led_clk_groups[] = { + "gpio0", +}; + +static const char * const serial_led_data_groups[] = { + "gpio1", +}; + +static const char * const hsspi_cs4_groups[] = { + "gpio16", +}; + +static const char * const hsspi_cs5_groups[] = { + "gpio17", +}; + +static const char * const hsspi_cs6_groups[] = { + "gpio8", +}; + +static const char * const hsspi_cs7_groups[] = { + "gpio9", +}; + +static const char * const uart1_scts_groups[] = { + "gpio10", + "gpio24", +}; + +static const char * const uart1_srts_groups[] = { + "gpio11", + "gpio25", +}; + +static const char * const uart1_sdin_groups[] = { + "gpio12", + "gpio26", +}; + +static const char * const uart1_sdout_groups[] = { + "gpio13", + "gpio27", +}; + +static const char * const ntr_pulse_in_groups[] = { + "gpio14", + "gpio28", +}; + +static const char * const dsl_ntr_pulse_out_groups[] = { + "gpio15", + "gpio29", +}; + +static const char * const adsl_spi_miso_groups[] = { + "gpio18", +}; + +static const char * const adsl_spi_mosi_groups[] = { + "gpio19", +}; + +static const char * const vreg_clk_groups[] = { + "gpio22", +}; + +static const char * const pcie_clkreq_b_groups[] = { + "gpio23", +}; + +static const char * const switch_led_clk_groups[] = { + "gpio30", +}; + +static const char * const switch_led_data_groups[] = { + "gpio31", +}; + +static const char * const wifi_groups[] = { + "gpio32", + "gpio33", + "gpio34", + "gpio35", + "gpio36", + "gpio37", + "gpio38", + "gpio39", + "gpio40", + "gpio41", + "gpio42", + "gpio43", + "gpio44", + "gpio45", + "gpio46", + "gpio47", + "gpio48", + "gpio49", + "gpio50", + "gpio51", +}; + +static const char * const nand_groups[] = { + "nand_grp", +}; + +static const char * const dectpd_groups[] = { + "dectpd_grp", +}; + +static const char * const vdsl_phy_override_0_groups[] = { + "vdsl_phy_override_0_grp", +}; + +static const char * const vdsl_phy_override_1_groups[] = { + "vdsl_phy_override_1_grp", +}; + +static const char * const vdsl_phy_override_2_groups[] = { + "vdsl_phy_override_2_grp", +}; + +static const char * const vdsl_phy_override_3_groups[] = { + "vdsl_phy_override_3_grp", +}; + +#define BCM63268_LED_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM63268_LEDCTRL, \ + } + +#define BCM63268_MODE_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM63268_MODE, \ + } + +#define BCM63268_CTRL_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM63268_CTRL, \ + } + +#define BCM63268_BASEMODE_FUN(n, val) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .reg = BCM63268_BASEMODE, \ + .mask = val, \ + } + +static const struct bcm63268_function bcm63268_funcs[] = { + BCM63268_LED_FUN(led), + BCM63268_MODE_FUN(serial_led_clk), + BCM63268_MODE_FUN(serial_led_data), + BCM63268_MODE_FUN(hsspi_cs6), + BCM63268_MODE_FUN(hsspi_cs7), + BCM63268_MODE_FUN(uart1_scts), + BCM63268_MODE_FUN(uart1_srts), + BCM63268_MODE_FUN(uart1_sdin), + BCM63268_MODE_FUN(uart1_sdout), + BCM63268_MODE_FUN(ntr_pulse_in), + BCM63268_MODE_FUN(dsl_ntr_pulse_out), + BCM63268_MODE_FUN(hsspi_cs4), + BCM63268_MODE_FUN(hsspi_cs5), + BCM63268_MODE_FUN(adsl_spi_miso), + BCM63268_MODE_FUN(adsl_spi_mosi), + BCM63268_MODE_FUN(vreg_clk), + BCM63268_MODE_FUN(pcie_clkreq_b), + BCM63268_MODE_FUN(switch_led_clk), + BCM63268_MODE_FUN(switch_led_data), + BCM63268_CTRL_FUN(wifi), + BCM63268_BASEMODE_FUN(nand, BCM63268_BASEMODE_NAND), + BCM63268_BASEMODE_FUN(dectpd, BCM63268_BASEMODE_DECTPD), + BCM63268_BASEMODE_FUN(vdsl_phy_override_0, + BCM63268_BASEMODE_VDSL_PHY_0), + BCM63268_BASEMODE_FUN(vdsl_phy_override_1, + BCM63268_BASEMODE_VDSL_PHY_1), + BCM63268_BASEMODE_FUN(vdsl_phy_override_2, + BCM63268_BASEMODE_VDSL_PHY_2), + BCM63268_BASEMODE_FUN(vdsl_phy_override_3, + BCM63268_BASEMODE_VDSL_PHY_3), +}; + +static int bcm63268_pinctrl_get_group_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm63268_groups); +} + +static const char *bcm63268_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + return bcm63268_groups[group].name; +} + +static int bcm63268_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned group, + const unsigned **pins, + unsigned *num_pins) +{ + *pins = bcm63268_groups[group].pins; + *num_pins = bcm63268_groups[group].num_pins; + + return 0; +} + +static int bcm63268_pinctrl_get_func_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm63268_funcs); +} + +static const char *bcm63268_pinctrl_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return bcm63268_funcs[selector].name; +} + +static int bcm63268_pinctrl_get_groups(struct pinctrl_dev *pctldev, + unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = bcm63268_funcs[selector].groups; + *num_groups = bcm63268_funcs[selector].num_groups; + + return 0; +} + +static void bcm63268_set_gpio(struct bcm63xx_pinctrl *pc, unsigned pin) +{ + const struct pinctrl_pin_desc *desc = &bcm63268_pins[pin]; + unsigned int basemode = (unsigned long) desc->drv_data; + unsigned int mask = BIT(bcm63xx_bank_pin(pin)); + + if (basemode) + regmap_update_bits(pc->regs, BCM63268_BASEMODE_REG, basemode, + 0); + + if (pin < BCM63XX_BANK_GPIOS) { + /* base mode: 0 => gpio, 1 => mux function */ + regmap_update_bits(pc->regs, BCM63268_MODE_REG, mask, 0); + + /* pins 0-23 might be muxed to led */ + if (pin < BCM63268_NUM_LEDS) + regmap_update_bits(pc->regs, BCM63268_LED_REG, mask, + 0); + } else if (pin < BCM63268_NUM_GPIOS) { + /* ctrl reg: 0 => wifi function, 1 => gpio */ + regmap_update_bits(pc->regs, BCM63268_CTRL_REG, mask, mask); + } +} + +static int bcm63268_pinctrl_set_mux(struct pinctrl_dev *pctldev, + unsigned selector, unsigned group) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + const struct bcm63268_pingroup *pg = &bcm63268_groups[group]; + const struct bcm63268_function *f = &bcm63268_funcs[selector]; + unsigned i; + unsigned int reg; + unsigned int val, mask; + + for (i = 0; i < pg->num_pins; i++) + bcm63268_set_gpio(pc, pg->pins[i]); + + switch (f->reg) { + case BCM63268_LEDCTRL: + reg = BCM63268_LED_REG; + mask = BIT(pg->pins[0]); + val = BIT(pg->pins[0]); + break; + case BCM63268_MODE: + reg = BCM63268_MODE_REG; + mask = BIT(pg->pins[0]); + val = BIT(pg->pins[0]); + break; + case BCM63268_CTRL: + reg = BCM63268_CTRL_REG; + mask = BIT(pg->pins[0]); + val = 0; + break; + case BCM63268_BASEMODE: + reg = BCM63268_BASEMODE_REG; + mask = f->mask; + val = f->mask; + break; + default: + WARN_ON(1); + return -EINVAL; + } + + regmap_update_bits(pc->regs, reg, mask, val); + + return 0; +} + +static int bcm63268_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + + /* disable all functions using this pin */ + bcm63268_set_gpio(pc, offset); + + return 0; +} + +static struct pinctrl_ops bcm63268_pctl_ops = { + .dt_free_map = pinctrl_utils_free_map, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .get_group_name = bcm63268_pinctrl_get_group_name, + .get_group_pins = bcm63268_pinctrl_get_group_pins, + .get_groups_count = bcm63268_pinctrl_get_group_count, +}; + +static struct pinmux_ops bcm63268_pmx_ops = { + .get_function_groups = bcm63268_pinctrl_get_groups, + .get_function_name = bcm63268_pinctrl_get_func_name, + .get_functions_count = bcm63268_pinctrl_get_func_count, + .gpio_request_enable = bcm63268_gpio_request_enable, + .set_mux = bcm63268_pinctrl_set_mux, + .strict = true, +}; + +static const struct bcm63xx_pinctrl_soc bcm63268_soc = { + .ngpios = BCM63268_NUM_GPIOS, + .npins = ARRAY_SIZE(bcm63268_pins), + .pctl_ops = &bcm63268_pctl_ops, + .pins = bcm63268_pins, + .pmx_ops = &bcm63268_pmx_ops, +}; + +static int bcm63268_pinctrl_probe(struct platform_device *pdev) +{ + return bcm63xx_pinctrl_probe(pdev, &bcm63268_soc, NULL); +} + +static const struct of_device_id bcm63268_pinctrl_match[] = { + { .compatible = "brcm,bcm63268-pinctrl", }, + { /* sentinel */ } +}; + +static struct platform_driver bcm63268_pinctrl_driver = { + .probe = bcm63268_pinctrl_probe, + .driver = { + .name = "bcm63268-pinctrl", + .of_match_table = bcm63268_pinctrl_match, + }, +}; + +builtin_platform_driver(bcm63268_pinctrl_driver); -- cgit v1.2.3 From b2f215141b985d5d39ed16fe7e2089d5aa162302 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:21 +0100 Subject: dt-bindings: add BCM6318 pincontroller binding documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add binding documentation for the pincontrol core found in BCM6318 SoCs. Co-developed-by: Jonas Gorski Signed-off-by: Jonas Gorski Signed-off-by: Álvaro Fernández Rojas Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210324081923.20379-21-noltari@gmail.com Signed-off-by: Linus Walleij --- .../bindings/pinctrl/brcm,bcm6318-pinctrl.yaml | 143 +++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml new file mode 100644 index 000000000000..08995a4f854b --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml @@ -0,0 +1,143 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6318-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6318 pin controller + +maintainers: + - Álvaro Fernández Rojas + - Jonas Gorski + +description: + Bindings for Broadcom's BCM6318 memory-mapped pin controller. + +properties: + compatible: + const: brcm,bcm6318-pinctrl + + reg: + maxItems: 2 + +patternProperties: + '-pins$': + type: object + $ref: pinmux-node.yaml# + + properties: + function: + enum: [ ephy0_spd_led, ephy1_spd_led, ephy2_spd_led, ephy3_spd_led, + ephy0_act_led, ephy1_act_led, ephy2_act_led, ephy3_act_led, + serial_led_data, serial_led_clk, inet_act_led, inet_fail_led, + dsl_led, post_fail_led, wlan_wps_led, usb_pwron, + usb_device_led, usb_active ] + + pins: + enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7, + gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio40 ] + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + pinctrl@18 { + compatible = "brcm,bcm6318-pinctrl"; + reg = <0x18 0x10>, <0x54 0x18>; + + pinctrl_ephy0_spd_led: ephy0_spd_led-pins { + function = "ephy0_spd_led"; + pins = "gpio0"; + }; + + pinctrl_ephy1_spd_led: ephy1_spd_led-pins { + function = "ephy1_spd_led"; + pins = "gpio1"; + }; + + pinctrl_ephy2_spd_led: ephy2_spd_led-pins { + function = "ephy2_spd_led"; + pins = "gpio2"; + }; + + pinctrl_ephy3_spd_led: ephy3_spd_led-pins { + function = "ephy3_spd_led"; + pins = "gpio3"; + }; + + pinctrl_ephy0_act_led: ephy0_act_led-pins { + function = "ephy0_act_led"; + pins = "gpio4"; + }; + + pinctrl_ephy1_act_led: ephy1_act_led-pins { + function = "ephy1_act_led"; + pins = "gpio5"; + }; + + pinctrl_ephy2_act_led: ephy2_act_led-pins { + function = "ephy2_act_led"; + pins = "gpio6"; + }; + + pinctrl_ephy3_act_led: ephy3_act_led-pins { + function = "ephy3_act_led"; + pins = "gpio7"; + }; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio6"; + }; + + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio7"; + }; + }; + + pinctrl_inet_act_led: inet_act_led-pins { + function = "inet_act_led"; + pins = "gpio8"; + }; + + pinctrl_inet_fail_led: inet_fail_led-pins { + function = "inet_fail_led"; + pins = "gpio9"; + }; + + pinctrl_dsl_led: dsl_led-pins { + function = "dsl_led"; + pins = "gpio10"; + }; + + pinctrl_post_fail_led: post_fail_led-pins { + function = "post_fail_led"; + pins = "gpio11"; + }; + + pinctrl_wlan_wps_led: wlan_wps_led-pins { + function = "wlan_wps_led"; + pins = "gpio12"; + }; + + pinctrl_usb_pwron: usb_pwron-pins { + function = "usb_pwron"; + pins = "gpio13"; + }; + + pinctrl_usb_device_led: usb_device_led-pins { + function = "usb_device_led"; + pins = "gpio13"; + }; + + pinctrl_usb_active: usb_active-pins { + function = "usb_active"; + pins = "gpio40"; + }; + }; -- cgit v1.2.3 From b6d46b9454742a25f9d923be072869e40b2ecebb Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:22 +0100 Subject: dt-bindings: add BCM6318 GPIO sysctl binding documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add binding documentation for the GPIO sysctl found in BCM6318 SoCs. Signed-off-by: Álvaro Fernández Rojas Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210324081923.20379-22-noltari@gmail.com Signed-off-by: Linus Walleij --- .../bindings/mfd/brcm,bcm6318-gpio-sysctl.yaml | 177 +++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/brcm,bcm6318-gpio-sysctl.yaml diff --git a/Documentation/devicetree/bindings/mfd/brcm,bcm6318-gpio-sysctl.yaml b/Documentation/devicetree/bindings/mfd/brcm,bcm6318-gpio-sysctl.yaml new file mode 100644 index 000000000000..afc569bc15cf --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/brcm,bcm6318-gpio-sysctl.yaml @@ -0,0 +1,177 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/brcm,bcm6318-gpio-sysctl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom BCM6318 GPIO System Controller Device Tree Bindings + +maintainers: + - Álvaro Fernández Rojas + - Jonas Gorski + +description: + Broadcom BCM6318 SoC GPIO system controller which provides a register map + for controlling the GPIO and pins of the SoC. + +properties: + "#address-cells": true + + "#size-cells": true + + compatible: + items: + - const: brcm,bcm6318-gpio-sysctl + - const: syscon + - const: simple-mfd + + ranges: + maxItems: 1 + + reg: + maxItems: 1 + +patternProperties: + "^gpio@[0-9a-f]+$": + # Child node + type: object + $ref: "../gpio/brcm,bcm6345-gpio.yaml" + description: + GPIO controller for the SoC GPIOs. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml. + + "^pinctrl@[0-9a-f]+$": + # Child node + type: object + $ref: "../pinctrl/brcm,bcm6318-pinctrl.yaml" + description: + Pin controller for the SoC pins. This child node definition + should follow the bindings specified in + Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml. + +required: + - "#address-cells" + - compatible + - ranges + - reg + - "#size-cells" + +additionalProperties: false + +examples: + - | + syscon@10000080 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "brcm,bcm6318-gpio-sysctl", "syscon", "simple-mfd"; + reg = <0x10000080 0x80>; + ranges = <0 0x10000080 0x80>; + + gpio@0 { + compatible = "brcm,bcm6318-gpio"; + reg-names = "dirout", "dat"; + reg = <0x0 0x8>, <0x8 0x8>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 0 50>; + #gpio-cells = <2>; + }; + + pinctrl: pinctrl@10 { + compatible = "brcm,bcm6318-pinctrl"; + reg = <0x18 0x10>, <0x54 0x18>; + + pinctrl_ephy0_spd_led: ephy0_spd_led-pins { + function = "ephy0_spd_led"; + pins = "gpio0"; + }; + + pinctrl_ephy1_spd_led: ephy1_spd_led-pins { + function = "ephy1_spd_led"; + pins = "gpio1"; + }; + + pinctrl_ephy2_spd_led: ephy2_spd_led-pins { + function = "ephy2_spd_led"; + pins = "gpio2"; + }; + + pinctrl_ephy3_spd_led: ephy3_spd_led-pins { + function = "ephy3_spd_led"; + pins = "gpio3"; + }; + + pinctrl_ephy0_act_led: ephy0_act_led-pins { + function = "ephy0_act_led"; + pins = "gpio4"; + }; + + pinctrl_ephy1_act_led: ephy1_act_led-pins { + function = "ephy1_act_led"; + pins = "gpio5"; + }; + + pinctrl_ephy2_act_led: ephy2_act_led-pins { + function = "ephy2_act_led"; + pins = "gpio6"; + }; + + pinctrl_ephy3_act_led: ephy3_act_led-pins { + function = "ephy3_act_led"; + pins = "gpio7"; + }; + + pinctrl_serial_led: serial_led-pins { + pinctrl_serial_led_data: serial_led_data-pins { + function = "serial_led_data"; + pins = "gpio6"; + }; + + pinctrl_serial_led_clk: serial_led_clk-pins { + function = "serial_led_clk"; + pins = "gpio7"; + }; + }; + + pinctrl_inet_act_led: inet_act_led-pins { + function = "inet_act_led"; + pins = "gpio8"; + }; + + pinctrl_inet_fail_led: inet_fail_led-pins { + function = "inet_fail_led"; + pins = "gpio9"; + }; + + pinctrl_dsl_led: dsl_led-pins { + function = "dsl_led"; + pins = "gpio10"; + }; + + pinctrl_post_fail_led: post_fail_led-pins { + function = "post_fail_led"; + pins = "gpio11"; + }; + + pinctrl_wlan_wps_led: wlan_wps_led-pins { + function = "wlan_wps_led"; + pins = "gpio12"; + }; + + pinctrl_usb_pwron: usb_pwron-pins { + function = "usb_pwron"; + pins = "gpio13"; + }; + + pinctrl_usb_device_led: usb_device_led-pins { + function = "usb_device_led"; + pins = "gpio13"; + }; + + pinctrl_usb_active: usb_active-pins { + function = "usb_active"; + pins = "gpio40"; + }; + }; + }; -- cgit v1.2.3 From d28039fccf948a407de69106465caa465b1dcf32 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Wed, 24 Mar 2021 09:19:23 +0100 Subject: pinctrl: add a pincontrol driver for BCM6318 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a pincontrol driver for BCM6318. BCM6318 allows muxing most GPIOs to different functions. BCM6318 is similar to BCM6328 with the addition of a pad register, and the GPIO meaning of the mux register changes based on the GPIO number. Co-developed-by: Jonas Gorski Signed-off-by: Jonas Gorski Signed-off-by: Álvaro Fernández Rojas Link: https://lore.kernel.org/r/20210324081923.20379-23-noltari@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/Kconfig | 8 + drivers/pinctrl/bcm/Makefile | 1 + drivers/pinctrl/bcm/pinctrl-bcm6318.c | 498 ++++++++++++++++++++++++++++++++++ 3 files changed, 507 insertions(+) create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6318.c diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig index 186985846120..33660e8fec05 100644 --- a/drivers/pinctrl/bcm/Kconfig +++ b/drivers/pinctrl/bcm/Kconfig @@ -36,6 +36,14 @@ config PINCTRL_BCM63XX select PINCONF select PINMUX +config PINCTRL_BCM6318 + bool "Broadcom BCM6318 GPIO driver" + depends on (BMIPS_GENERIC || COMPILE_TEST) + select PINCTRL_BCM63XX + default BMIPS_GENERIC + help + Say Y here to enable the Broadcom BCM6318 GPIO driver. + config PINCTRL_BCM6328 bool "Broadcom BCM6328 GPIO driver" depends on (BMIPS_GENERIC || COMPILE_TEST) diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile index 4117847fd279..00c7b7775e63 100644 --- a/drivers/pinctrl/bcm/Makefile +++ b/drivers/pinctrl/bcm/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o obj-$(CONFIG_PINCTRL_BCM63XX) += pinctrl-bcm63xx.o +obj-$(CONFIG_PINCTRL_BCM6318) += pinctrl-bcm6318.o obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl-bcm6328.o obj-$(CONFIG_PINCTRL_BCM6358) += pinctrl-bcm6358.o obj-$(CONFIG_PINCTRL_BCM6362) += pinctrl-bcm6362.o diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6318.c b/drivers/pinctrl/bcm/pinctrl-bcm6318.c new file mode 100644 index 000000000000..77fd9b58067d --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-bcm6318.c @@ -0,0 +1,498 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for BCM6318 GPIO unit (pinctrl + GPIO) + * + * Copyright (C) 2021 Álvaro Fernández Rojas + * Copyright (C) 2016 Jonas Gorski + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../pinctrl-utils.h" + +#include "pinctrl-bcm63xx.h" + +#define BCM6318_NUM_GPIOS 50 +#define BCM6318_NUM_MUX 48 + +#define BCM6318_MODE_REG 0x18 +#define BCM6318_MUX_REG 0x1c +#define BCM6328_MUX_MASK GENMASK(1, 0) +#define BCM6318_PAD_REG 0x54 +#define BCM6328_PAD_MASK GENMASK(3, 0) + +struct bcm6318_pingroup { + const char *name; + const unsigned * const pins; + const unsigned num_pins; +}; + +struct bcm6318_function { + const char *name; + const char * const *groups; + const unsigned num_groups; + + unsigned mode_val:1; + unsigned mux_val:2; +}; + +static const struct pinctrl_pin_desc bcm6318_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + PINCTRL_PIN(2, "gpio2"), + PINCTRL_PIN(3, "gpio3"), + PINCTRL_PIN(4, "gpio4"), + PINCTRL_PIN(5, "gpio5"), + PINCTRL_PIN(6, "gpio6"), + PINCTRL_PIN(7, "gpio7"), + PINCTRL_PIN(8, "gpio8"), + PINCTRL_PIN(9, "gpio9"), + PINCTRL_PIN(10, "gpio10"), + PINCTRL_PIN(11, "gpio11"), + PINCTRL_PIN(12, "gpio12"), + PINCTRL_PIN(13, "gpio13"), + PINCTRL_PIN(14, "gpio14"), + PINCTRL_PIN(15, "gpio15"), + PINCTRL_PIN(16, "gpio16"), + PINCTRL_PIN(17, "gpio17"), + PINCTRL_PIN(18, "gpio18"), + PINCTRL_PIN(19, "gpio19"), + PINCTRL_PIN(20, "gpio20"), + PINCTRL_PIN(21, "gpio21"), + PINCTRL_PIN(22, "gpio22"), + PINCTRL_PIN(23, "gpio23"), + PINCTRL_PIN(24, "gpio24"), + PINCTRL_PIN(25, "gpio25"), + PINCTRL_PIN(26, "gpio26"), + PINCTRL_PIN(27, "gpio27"), + PINCTRL_PIN(28, "gpio28"), + PINCTRL_PIN(29, "gpio29"), + PINCTRL_PIN(30, "gpio30"), + PINCTRL_PIN(31, "gpio31"), + PINCTRL_PIN(32, "gpio32"), + PINCTRL_PIN(33, "gpio33"), + PINCTRL_PIN(34, "gpio34"), + PINCTRL_PIN(35, "gpio35"), + PINCTRL_PIN(36, "gpio36"), + PINCTRL_PIN(37, "gpio37"), + PINCTRL_PIN(38, "gpio38"), + PINCTRL_PIN(39, "gpio39"), + PINCTRL_PIN(40, "gpio40"), + PINCTRL_PIN(41, "gpio41"), + PINCTRL_PIN(42, "gpio42"), + PINCTRL_PIN(43, "gpio43"), + PINCTRL_PIN(44, "gpio44"), + PINCTRL_PIN(45, "gpio45"), + PINCTRL_PIN(46, "gpio46"), + PINCTRL_PIN(47, "gpio47"), + PINCTRL_PIN(48, "gpio48"), + PINCTRL_PIN(49, "gpio49"), +}; + +static unsigned gpio0_pins[] = { 0 }; +static unsigned gpio1_pins[] = { 1 }; +static unsigned gpio2_pins[] = { 2 }; +static unsigned gpio3_pins[] = { 3 }; +static unsigned gpio4_pins[] = { 4 }; +static unsigned gpio5_pins[] = { 5 }; +static unsigned gpio6_pins[] = { 6 }; +static unsigned gpio7_pins[] = { 7 }; +static unsigned gpio8_pins[] = { 8 }; +static unsigned gpio9_pins[] = { 9 }; +static unsigned gpio10_pins[] = { 10 }; +static unsigned gpio11_pins[] = { 11 }; +static unsigned gpio12_pins[] = { 12 }; +static unsigned gpio13_pins[] = { 13 }; +static unsigned gpio14_pins[] = { 14 }; +static unsigned gpio15_pins[] = { 15 }; +static unsigned gpio16_pins[] = { 16 }; +static unsigned gpio17_pins[] = { 17 }; +static unsigned gpio18_pins[] = { 18 }; +static unsigned gpio19_pins[] = { 19 }; +static unsigned gpio20_pins[] = { 20 }; +static unsigned gpio21_pins[] = { 21 }; +static unsigned gpio22_pins[] = { 22 }; +static unsigned gpio23_pins[] = { 23 }; +static unsigned gpio24_pins[] = { 24 }; +static unsigned gpio25_pins[] = { 25 }; +static unsigned gpio26_pins[] = { 26 }; +static unsigned gpio27_pins[] = { 27 }; +static unsigned gpio28_pins[] = { 28 }; +static unsigned gpio29_pins[] = { 29 }; +static unsigned gpio30_pins[] = { 30 }; +static unsigned gpio31_pins[] = { 31 }; +static unsigned gpio32_pins[] = { 32 }; +static unsigned gpio33_pins[] = { 33 }; +static unsigned gpio34_pins[] = { 34 }; +static unsigned gpio35_pins[] = { 35 }; +static unsigned gpio36_pins[] = { 36 }; +static unsigned gpio37_pins[] = { 37 }; +static unsigned gpio38_pins[] = { 38 }; +static unsigned gpio39_pins[] = { 39 }; +static unsigned gpio40_pins[] = { 40 }; +static unsigned gpio41_pins[] = { 41 }; +static unsigned gpio42_pins[] = { 42 }; +static unsigned gpio43_pins[] = { 43 }; +static unsigned gpio44_pins[] = { 44 }; +static unsigned gpio45_pins[] = { 45 }; +static unsigned gpio46_pins[] = { 46 }; +static unsigned gpio47_pins[] = { 47 }; +static unsigned gpio48_pins[] = { 48 }; +static unsigned gpio49_pins[] = { 49 }; + +#define BCM6318_GROUP(n) \ + { \ + .name = #n, \ + .pins = n##_pins, \ + .num_pins = ARRAY_SIZE(n##_pins), \ + } + +static struct bcm6318_pingroup bcm6318_groups[] = { + BCM6318_GROUP(gpio0), + BCM6318_GROUP(gpio1), + BCM6318_GROUP(gpio2), + BCM6318_GROUP(gpio3), + BCM6318_GROUP(gpio4), + BCM6318_GROUP(gpio5), + BCM6318_GROUP(gpio6), + BCM6318_GROUP(gpio7), + BCM6318_GROUP(gpio8), + BCM6318_GROUP(gpio9), + BCM6318_GROUP(gpio10), + BCM6318_GROUP(gpio11), + BCM6318_GROUP(gpio12), + BCM6318_GROUP(gpio13), + BCM6318_GROUP(gpio14), + BCM6318_GROUP(gpio15), + BCM6318_GROUP(gpio16), + BCM6318_GROUP(gpio17), + BCM6318_GROUP(gpio18), + BCM6318_GROUP(gpio19), + BCM6318_GROUP(gpio20), + BCM6318_GROUP(gpio21), + BCM6318_GROUP(gpio22), + BCM6318_GROUP(gpio23), + BCM6318_GROUP(gpio24), + BCM6318_GROUP(gpio25), + BCM6318_GROUP(gpio26), + BCM6318_GROUP(gpio27), + BCM6318_GROUP(gpio28), + BCM6318_GROUP(gpio29), + BCM6318_GROUP(gpio30), + BCM6318_GROUP(gpio31), + BCM6318_GROUP(gpio32), + BCM6318_GROUP(gpio33), + BCM6318_GROUP(gpio34), + BCM6318_GROUP(gpio35), + BCM6318_GROUP(gpio36), + BCM6318_GROUP(gpio37), + BCM6318_GROUP(gpio38), + BCM6318_GROUP(gpio39), + BCM6318_GROUP(gpio40), + BCM6318_GROUP(gpio41), + BCM6318_GROUP(gpio42), + BCM6318_GROUP(gpio43), + BCM6318_GROUP(gpio44), + BCM6318_GROUP(gpio45), + BCM6318_GROUP(gpio46), + BCM6318_GROUP(gpio47), + BCM6318_GROUP(gpio48), + BCM6318_GROUP(gpio49), +}; + +/* GPIO_MODE */ +static const char * const led_groups[] = { + "gpio0", + "gpio1", + "gpio2", + "gpio3", + "gpio4", + "gpio5", + "gpio6", + "gpio7", + "gpio8", + "gpio9", + "gpio10", + "gpio11", + "gpio12", + "gpio13", + "gpio14", + "gpio15", + "gpio16", + "gpio17", + "gpio18", + "gpio19", + "gpio20", + "gpio21", + "gpio22", + "gpio23", +}; + +/* PINMUX_SEL */ +static const char * const ephy0_spd_led_groups[] = { + "gpio0", +}; + +static const char * const ephy1_spd_led_groups[] = { + "gpio1", +}; + +static const char * const ephy2_spd_led_groups[] = { + "gpio2", +}; + +static const char * const ephy3_spd_led_groups[] = { + "gpio3", +}; + +static const char * const ephy0_act_led_groups[] = { + "gpio4", +}; + +static const char * const ephy1_act_led_groups[] = { + "gpio5", +}; + +static const char * const ephy2_act_led_groups[] = { + "gpio6", +}; + +static const char * const ephy3_act_led_groups[] = { + "gpio7", +}; + +static const char * const serial_led_data_groups[] = { + "gpio6", +}; + +static const char * const serial_led_clk_groups[] = { + "gpio7", +}; + +static const char * const inet_act_led_groups[] = { + "gpio8", +}; + +static const char * const inet_fail_led_groups[] = { + "gpio9", +}; + +static const char * const dsl_led_groups[] = { + "gpio10", +}; + +static const char * const post_fail_led_groups[] = { + "gpio11", +}; + +static const char * const wlan_wps_led_groups[] = { + "gpio12", +}; + +static const char * const usb_pwron_groups[] = { + "gpio13", +}; + +static const char * const usb_device_led_groups[] = { + "gpio13", +}; + +static const char * const usb_active_groups[] = { + "gpio40", +}; + +#define BCM6318_MODE_FUN(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .mode_val = 1, \ + } + +#define BCM6318_MUX_FUN(n, mux) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .num_groups = ARRAY_SIZE(n##_groups), \ + .mux_val = mux, \ + } + +static const struct bcm6318_function bcm6318_funcs[] = { + BCM6318_MODE_FUN(led), + BCM6318_MUX_FUN(ephy0_spd_led, 1), + BCM6318_MUX_FUN(ephy1_spd_led, 1), + BCM6318_MUX_FUN(ephy2_spd_led, 1), + BCM6318_MUX_FUN(ephy3_spd_led, 1), + BCM6318_MUX_FUN(ephy0_act_led, 1), + BCM6318_MUX_FUN(ephy1_act_led, 1), + BCM6318_MUX_FUN(ephy2_act_led, 1), + BCM6318_MUX_FUN(ephy3_act_led, 1), + BCM6318_MUX_FUN(serial_led_data, 3), + BCM6318_MUX_FUN(serial_led_clk, 3), + BCM6318_MUX_FUN(inet_act_led, 1), + BCM6318_MUX_FUN(inet_fail_led, 1), + BCM6318_MUX_FUN(dsl_led, 1), + BCM6318_MUX_FUN(post_fail_led, 1), + BCM6318_MUX_FUN(wlan_wps_led, 1), + BCM6318_MUX_FUN(usb_pwron, 1), + BCM6318_MUX_FUN(usb_device_led, 2), + BCM6318_MUX_FUN(usb_active, 2), +}; + +static inline unsigned int bcm6318_mux_off(unsigned int pin) +{ + return BCM6318_MUX_REG + (pin / 16) * 4; +} + +static inline unsigned int bcm6318_pad_off(unsigned int pin) +{ + return BCM6318_PAD_REG + (pin / 8) * 4; +} + +static int bcm6318_pinctrl_get_group_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6318_groups); +} + +static const char *bcm6318_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + return bcm6318_groups[group].name; +} + +static int bcm6318_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned group, const unsigned **pins, + unsigned *num_pins) +{ + *pins = bcm6318_groups[group].pins; + *num_pins = bcm6318_groups[group].num_pins; + + return 0; +} + +static int bcm6318_pinctrl_get_func_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(bcm6318_funcs); +} + +static const char *bcm6318_pinctrl_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return bcm6318_funcs[selector].name; +} + +static int bcm6318_pinctrl_get_groups(struct pinctrl_dev *pctldev, + unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = bcm6318_funcs[selector].groups; + *num_groups = bcm6318_funcs[selector].num_groups; + + return 0; +} + +static inline void bcm6318_rmw_mux(struct bcm63xx_pinctrl *pc, unsigned pin, + unsigned int mode, unsigned int mux) +{ + if (pin < BCM63XX_BANK_GPIOS) + regmap_update_bits(pc->regs, BCM6318_MODE_REG, BIT(pin), + mode ? BIT(pin) : 0); + + if (pin < BCM6318_NUM_MUX) + regmap_update_bits(pc->regs, + bcm6318_mux_off(pin), + BCM6328_MUX_MASK << ((pin % 16) * 2), + mux << ((pin % 16) * 2)); +} + +static inline void bcm6318_set_pad(struct bcm63xx_pinctrl *pc, unsigned pin, + uint8_t val) +{ + regmap_update_bits(pc->regs, bcm6318_pad_off(pin), + BCM6328_PAD_MASK << ((pin % 8) * 4), + val << ((pin % 8) * 4)); +} + +static int bcm6318_pinctrl_set_mux(struct pinctrl_dev *pctldev, + unsigned selector, unsigned group) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + const struct bcm6318_pingroup *pg = &bcm6318_groups[group]; + const struct bcm6318_function *f = &bcm6318_funcs[selector]; + + bcm6318_rmw_mux(pc, pg->pins[0], f->mode_val, f->mux_val); + + return 0; +} + +static int bcm6318_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + + /* disable all functions using this pin */ + if (offset < 13) { + /* GPIOs 0-12 use mux 0 as GPIO function */ + bcm6318_rmw_mux(pc, offset, 0, 0); + } else if (offset < 42) { + /* GPIOs 13-41 use mux 3 as GPIO function */ + bcm6318_rmw_mux(pc, offset, 0, 3); + + bcm6318_set_pad(pc, offset, 0); + } + + return 0; +} + +static struct pinctrl_ops bcm6318_pctl_ops = { + .dt_free_map = pinctrl_utils_free_map, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .get_group_name = bcm6318_pinctrl_get_group_name, + .get_group_pins = bcm6318_pinctrl_get_group_pins, + .get_groups_count = bcm6318_pinctrl_get_group_count, +}; + +static struct pinmux_ops bcm6318_pmx_ops = { + .get_function_groups = bcm6318_pinctrl_get_groups, + .get_function_name = bcm6318_pinctrl_get_func_name, + .get_functions_count = bcm6318_pinctrl_get_func_count, + .gpio_request_enable = bcm6318_gpio_request_enable, + .set_mux = bcm6318_pinctrl_set_mux, + .strict = true, +}; + +static const struct bcm63xx_pinctrl_soc bcm6318_soc = { + .ngpios = BCM6318_NUM_GPIOS, + .npins = ARRAY_SIZE(bcm6318_pins), + .pctl_ops = &bcm6318_pctl_ops, + .pins = bcm6318_pins, + .pmx_ops = &bcm6318_pmx_ops, +}; + +static int bcm6318_pinctrl_probe(struct platform_device *pdev) +{ + return bcm63xx_pinctrl_probe(pdev, &bcm6318_soc, NULL); +} + +static const struct of_device_id bcm6318_pinctrl_match[] = { + { .compatible = "brcm,bcm6318-pinctrl", }, + { /* sentinel */ } +}; + +static struct platform_driver bcm6318_pinctrl_driver = { + .probe = bcm6318_pinctrl_probe, + .driver = { + .name = "bcm6318-pinctrl", + .of_match_table = bcm6318_pinctrl_match, + }, +}; + +builtin_platform_driver(bcm6318_pinctrl_driver); -- cgit v1.2.3 From 05bc941403d6695f063022531ae2acae9f79b362 Mon Sep 17 00:00:00 2001 From: Wan Jiabing Date: Tue, 23 Mar 2021 09:37:27 +0800 Subject: drivers: pinctrl: Remove duplicate include of io.h linux/io.h has been included at line 6, so remove the duplicate include at line 18. Signed-off-by: Wan Jiabing Reviewed-by: Damien Le Moal Link: https://lore.kernel.org/r/20210323013727.135571-1-wanjiabing@vivo.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-k210.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-k210.c b/drivers/pinctrl/pinctrl-k210.c index 8a733cf77ba0..f831526d06ff 100644 --- a/drivers/pinctrl/pinctrl-k210.c +++ b/drivers/pinctrl/pinctrl-k210.c @@ -15,7 +15,6 @@ #include #include #include -#include #include -- cgit v1.2.3 From 1978d88cdc8eb0986d36cac0e9541220fa71d87d Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Tue, 30 Mar 2021 12:32:25 +0200 Subject: pinctrl: bcm: bcm6362: fix warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current implementation of bcm6362_set_gpio() produces the following warning on x86_64: drivers/pinctrl/bcm/pinctrl-bcm6362.c: In function 'bcm6362_set_gpio': drivers/pinctrl/bcm/pinctrl-bcm6362.c:503:8: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] 503 | (uint32_t) desc->drv_data, 0); | ^ Modify the code to make it similar to bcm63268_set_gpio() in order to fix the warning. Fixes: 705791e23ecd ("pinctrl: add a pincontrol driver for BCM6362") Signed-off-by: Álvaro Fernández Rojas Link: https://lore.kernel.org/r/20210330103225.3949-1-noltari@gmail.com Reviewed-by: Andy Shevchenko Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/pinctrl-bcm6362.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6362.c b/drivers/pinctrl/bcm/pinctrl-bcm6362.c index eb7ec80353e9..40ef495b6301 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm6362.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm6362.c @@ -496,11 +496,11 @@ static int bcm6362_pinctrl_get_groups(struct pinctrl_dev *pctldev, static void bcm6362_set_gpio(struct bcm63xx_pinctrl *pc, unsigned pin) { const struct pinctrl_pin_desc *desc = &bcm6362_pins[pin]; + unsigned int basemode = (uintptr_t)desc->drv_data; unsigned int mask = bcm63xx_bank_pin(pin); - if (desc->drv_data) - regmap_update_bits(pc->regs, BCM6362_BASEMODE_REG, - (uint32_t) desc->drv_data, 0); + if (basemode) + regmap_update_bits(pc->regs, BCM6362_BASEMODE_REG, basemode, 0); if (pin < BCM63XX_BANK_GPIOS) { /* base mode 0 => gpio 1 => mux function */ -- cgit v1.2.3 From 26ea7ac92836ba616f75a1ab57e64ffc21da7758 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 31 Mar 2021 14:45:05 +0200 Subject: pinctrl: bcm63xx: Fix dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add depends on OF so we don't get weird build errors on randconfig. Also order selects the same as the other drivers for pure aestetic reasons. Reported-by: Randy Dunlap Cc: Álvaro Fernández Rojas Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/Kconfig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig index 33660e8fec05..17615674ac1a 100644 --- a/drivers/pinctrl/bcm/Kconfig +++ b/drivers/pinctrl/bcm/Kconfig @@ -31,10 +31,12 @@ config PINCTRL_BCM2835 config PINCTRL_BCM63XX bool + depends on OF + select PINMUX + select PINCONF select GENERIC_PINCONF + select GPIOLIB select GPIO_REGMAP - select PINCONF - select PINMUX config PINCTRL_BCM6318 bool "Broadcom BCM6318 GPIO driver" -- cgit v1.2.3 From da35b19d62c17f1f25878be5cb2d8cd501b1c3c6 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 1 Apr 2021 10:47:03 -0700 Subject: pinctrl: bcm63xx: Fix More dependencies The additional patch below fixes all of the kconfig warnings and build errors for me. Link: https://lore.kernel.org/r/9e1cec76-1c0a-9203-7995-4c2d09b711d8@infradead.org Signed-off-by: Randy Dunlap [Tweaked some other line in the BCMxxx] Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/Kconfig | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig index 17615674ac1a..c9c5efc92731 100644 --- a/drivers/pinctrl/bcm/Kconfig +++ b/drivers/pinctrl/bcm/Kconfig @@ -31,7 +31,6 @@ config PINCTRL_BCM2835 config PINCTRL_BCM63XX bool - depends on OF select PINMUX select PINCONF select GENERIC_PINCONF @@ -41,6 +40,7 @@ config PINCTRL_BCM63XX config PINCTRL_BCM6318 bool "Broadcom BCM6318 GPIO driver" depends on (BMIPS_GENERIC || COMPILE_TEST) + depends on OF select PINCTRL_BCM63XX default BMIPS_GENERIC help @@ -49,6 +49,7 @@ config PINCTRL_BCM6318 config PINCTRL_BCM6328 bool "Broadcom BCM6328 GPIO driver" depends on (BMIPS_GENERIC || COMPILE_TEST) + depends on OF select PINCTRL_BCM63XX default BMIPS_GENERIC help @@ -57,6 +58,7 @@ config PINCTRL_BCM6328 config PINCTRL_BCM6358 bool "Broadcom BCM6358 GPIO driver" depends on (BMIPS_GENERIC || COMPILE_TEST) + depends on OF select PINCTRL_BCM63XX default BMIPS_GENERIC help @@ -65,6 +67,7 @@ config PINCTRL_BCM6358 config PINCTRL_BCM6362 bool "Broadcom BCM6362 GPIO driver" depends on (BMIPS_GENERIC || COMPILE_TEST) + depends on OF select PINCTRL_BCM63XX default BMIPS_GENERIC help @@ -73,6 +76,7 @@ config PINCTRL_BCM6362 config PINCTRL_BCM6368 bool "Broadcom BCM6368 GPIO driver" depends on (BMIPS_GENERIC || COMPILE_TEST) + depends on OF select PINCTRL_BCM63XX default BMIPS_GENERIC help @@ -81,6 +85,7 @@ config PINCTRL_BCM6368 config PINCTRL_BCM63268 bool "Broadcom BCM63268 GPIO driver" depends on (BMIPS_GENERIC || COMPILE_TEST) + depends on OF select PINCTRL_BCM63XX default BMIPS_GENERIC help -- cgit v1.2.3 From 589b9b8b7b98ef091d1a5c5c6e27e9cef221d83f Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 6 Apr 2021 20:00:35 +0200 Subject: pinctrl: stm32: Print invalid AF warning inside stm32_pctrl_is_function_valid() The "invalid function %d on pin %d .\n" message is triplicated in the driver in different variants, just pull it into the function and have it once in the driver. The bonus is that all variants of the message now print the pin number and AF consistently, so it is easier to debug such pinmux problems. Signed-off-by: Marek Vasut Cc: Fabien Dessenne Cc: Alexandre Torgue Cc: Linus Walleij Cc: linux-stm32@st-md-mailman.stormreply.com To: linux-arm-kernel@lists.infradead.org Acked-by: Fabien Dessenne Link: https://lore.kernel.org/r/20210406180035.279249-1-marex@denx.de Signed-off-by: Linus Walleij --- drivers/pinctrl/stm32/pinctrl-stm32.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index da72e3e5c08d..ad9eb5ed8e81 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -531,6 +531,8 @@ static bool stm32_pctrl_is_function_valid(struct stm32_pinctrl *pctl, break; } + dev_err(pctl->dev, "invalid function %d on pin %d .\n", fnum, pin_num); + return false; } @@ -545,11 +547,8 @@ static int stm32_pctrl_dt_node_to_map_func(struct stm32_pinctrl *pctl, (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP; (*map)[*num_maps].data.mux.group = grp->name; - if (!stm32_pctrl_is_function_valid(pctl, pin, fnum)) { - dev_err(pctl->dev, "invalid function %d on pin %d .\n", - fnum, pin); + if (!stm32_pctrl_is_function_valid(pctl, pin, fnum)) return -EINVAL; - } (*map)[*num_maps].data.mux.function = stm32_gpio_functions[fnum]; (*num_maps)++; @@ -620,7 +619,6 @@ static int stm32_pctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, func = STM32_GET_PIN_FUNC(pinfunc); if (!stm32_pctrl_is_function_valid(pctl, pin, func)) { - dev_err(pctl->dev, "invalid function.\n"); err = -EINVAL; goto exit; } @@ -821,11 +819,8 @@ static int stm32_pmx_set_mux(struct pinctrl_dev *pctldev, int pin; ret = stm32_pctrl_is_function_valid(pctl, g->pin, function); - if (!ret) { - dev_err(pctl->dev, "invalid function %d on group %d .\n", - function, group); + if (!ret) return -EINVAL; - } range = pinctrl_find_gpio_range_from_pin(pctldev, g->pin); if (!range) { -- cgit v1.2.3 From c0dadc0e47a895e95c17a4df1fa12737e1d57d6f Mon Sep 17 00:00:00 2001 From: Jianqun Xu Date: Fri, 19 Mar 2021 16:14:41 +0800 Subject: pinctrl: rockchip: add support for rk3568 RK3568 SoCs have 5 gpio controllers, each gpio has 32 pins. GPIO supports set iomux, pull, drive strength and schmitt. Signed-off-by: Jianqun Xu Link: https://lore.kernel.org/r/20210319081441.368358-1-jay.xu@rock-chips.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 292 ++++++++++++++++++++++++++++++++++++- 1 file changed, 290 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 65aa87476eae..05128f53824c 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -63,8 +63,17 @@ enum rockchip_pinctrl_type { RK3308, RK3368, RK3399, + RK3568, }; + +/** + * Generate a bitmask for setting a value (v) with a write mask bit in hiword + * register 31:16 area. + */ +#define WRITE_MASK_VAL(h, l, v) \ + (GENMASK(((h) + 16), ((l) + 16)) | (((v) << (l)) & GENMASK((h), (l)))) + /* * Encode variants of iomux registers into a type variable */ @@ -292,6 +301,25 @@ struct rockchip_pin_bank { .pull_type[3] = pull3, \ } +#define PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, FLAG) \ + { \ + .bank_num = ID, \ + .pin = PIN, \ + .func = FUNC, \ + .route_offset = REG, \ + .route_val = VAL, \ + .route_location = FLAG, \ + } + +#define RK_MUXROUTE_SAME(ID, PIN, FUNC, REG, VAL) \ + PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_SAME) + +#define RK_MUXROUTE_GRF(ID, PIN, FUNC, REG, VAL) \ + PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_GRF) + +#define RK_MUXROUTE_PMU(ID, PIN, FUNC, REG, VAL) \ + PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_PMU) + /** * struct rockchip_mux_recalced_data: represent a pin iomux data. * @num: bank number. @@ -1396,6 +1424,102 @@ static struct rockchip_mux_route_data rk3399_mux_route_data[] = { }, }; +static struct rockchip_mux_route_data rk3568_mux_route_data[] = { + RK_MUXROUTE_PMU(0, RK_PB7, 1, 0x0110, WRITE_MASK_VAL(1, 0, 0)), /* PWM0 IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PC7, 2, 0x0110, WRITE_MASK_VAL(1, 0, 1)), /* PWM0 IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PC0, 1, 0x0110, WRITE_MASK_VAL(3, 2, 0)), /* PWM1 IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PB5, 4, 0x0110, WRITE_MASK_VAL(3, 2, 1)), /* PWM1 IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PC1, 1, 0x0110, WRITE_MASK_VAL(5, 4, 0)), /* PWM2 IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PB6, 4, 0x0110, WRITE_MASK_VAL(5, 4, 1)), /* PWM2 IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PA1, 4, 0x0300, WRITE_MASK_VAL(0, 0, 1)), /* CAN0 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA1, 3, 0x0300, WRITE_MASK_VAL(2, 2, 0)), /* CAN1 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC3, 3, 0x0300, WRITE_MASK_VAL(2, 2, 1)), /* CAN1 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PB5, 3, 0x0300, WRITE_MASK_VAL(4, 4, 0)), /* CAN2 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PB2, 4, 0x0300, WRITE_MASK_VAL(4, 4, 1)), /* CAN2 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PC4, 1, 0x0300, WRITE_MASK_VAL(6, 6, 0)), /* HPDIN IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB1, 3, 0x0300, WRITE_MASK_VAL(8, 8, 0)), /* GMAC1 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PA7, 3, 0x0300, WRITE_MASK_VAL(8, 8, 1)), /* GMAC1 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PD1, 1, 0x0300, WRITE_MASK_VAL(10, 10, 0)), /* HDMITX IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PB4, 1, 0x0300, WRITE_MASK_VAL(14, 14, 1)), /* I2C2 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA0, 1, 0x0304, WRITE_MASK_VAL(0, 0, 0)), /* I2C3 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PB6, 4, 0x0304, WRITE_MASK_VAL(0, 0, 1)), /* I2C3 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PB2, 1, 0x0304, WRITE_MASK_VAL(2, 2, 0)), /* I2C4 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PB1, 2, 0x0304, WRITE_MASK_VAL(2, 2, 1)), /* I2C4 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB4, 4, 0x0304, WRITE_MASK_VAL(4, 4, 0)), /* I2C5 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PD0, 2, 0x0304, WRITE_MASK_VAL(4, 4, 1)), /* I2C5 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB1, 5, 0x0304, WRITE_MASK_VAL(14, 14, 0)), /* PWM8 IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PD5, 4, 0x0304, WRITE_MASK_VAL(14, 14, 1)), /* PWM8 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB2, 5, 0x0308, WRITE_MASK_VAL(0, 0, 0)), /* PWM9 IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PD6, 4, 0x0308, WRITE_MASK_VAL(0, 0, 1)), /* PWM9 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB5, 5, 0x0308, WRITE_MASK_VAL(2, 2, 0)), /* PWM10 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PA1, 2, 0x0308, WRITE_MASK_VAL(2, 2, 1)), /* PWM10 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB6, 5, 0x0308, WRITE_MASK_VAL(4, 4, 0)), /* PWM11 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC0, 3, 0x0308, WRITE_MASK_VAL(4, 4, 1)), /* PWM11 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB7, 2, 0x0308, WRITE_MASK_VAL(6, 6, 0)), /* PWM12 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(6, 6, 1)), /* PWM12 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PC0, 2, 0x0308, WRITE_MASK_VAL(8, 8, 0)), /* PWM13 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC6, 1, 0x0308, WRITE_MASK_VAL(8, 8, 1)), /* PWM13 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PC4, 1, 0x0308, WRITE_MASK_VAL(10, 10, 0)), /* PWM14 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC2, 1, 0x0308, WRITE_MASK_VAL(10, 10, 1)), /* PWM14 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(12, 12, 0)), /* PWM15 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC3, 1, 0x0308, WRITE_MASK_VAL(12, 12, 1)), /* PWM15 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PD2, 3, 0x0308, WRITE_MASK_VAL(14, 14, 0)), /* SDMMC2 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PA5, 5, 0x0308, WRITE_MASK_VAL(14, 14, 1)), /* SDMMC2 IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD3, 3, 0x030c, WRITE_MASK_VAL(0, 0, 1)), /* SPI0 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PB5, 3, 0x030c, WRITE_MASK_VAL(2, 2, 0)), /* SPI1 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PC3, 3, 0x030c, WRITE_MASK_VAL(2, 2, 1)), /* SPI1 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PC1, 4, 0x030c, WRITE_MASK_VAL(4, 4, 0)), /* SPI2 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PA0, 3, 0x030c, WRITE_MASK_VAL(4, 4, 1)), /* SPI2 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PB3, 4, 0x030c, WRITE_MASK_VAL(6, 6, 0)), /* SPI3 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC2, 2, 0x030c, WRITE_MASK_VAL(6, 6, 1)), /* SPI3 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PB4, 2, 0x030c, WRITE_MASK_VAL(8, 8, 0)), /* UART1 IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x030c, WRITE_MASK_VAL(10, 10, 1)), /* UART2 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA1, 2, 0x030c, WRITE_MASK_VAL(12, 12, 0)), /* UART3 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PB7, 4, 0x030c, WRITE_MASK_VAL(12, 12, 1)), /* UART3 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA6, 2, 0x030c, WRITE_MASK_VAL(14, 14, 0)), /* UART4 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PB2, 4, 0x030c, WRITE_MASK_VAL(14, 14, 1)), /* UART4 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PA2, 3, 0x0310, WRITE_MASK_VAL(0, 0, 0)), /* UART5 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PC2, 4, 0x0310, WRITE_MASK_VAL(0, 0, 1)), /* UART5 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PA4, 3, 0x0310, WRITE_MASK_VAL(2, 2, 0)), /* UART6 IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PD5, 3, 0x0310, WRITE_MASK_VAL(2, 2, 1)), /* UART6 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PA6, 3, 0x0310, WRITE_MASK_VAL(5, 4, 0)), /* UART7 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PC4, 4, 0x0310, WRITE_MASK_VAL(5, 4, 1)), /* UART7 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(5, 4, 2)), /* UART7 IO mux M2 */ + RK_MUXROUTE_GRF(2, RK_PC5, 3, 0x0310, WRITE_MASK_VAL(6, 6, 0)), /* UART8 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD7, 4, 0x0310, WRITE_MASK_VAL(6, 6, 1)), /* UART8 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PB0, 3, 0x0310, WRITE_MASK_VAL(9, 8, 0)), /* UART9 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC5, 4, 0x0310, WRITE_MASK_VAL(9, 8, 1)), /* UART9 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PA4, 4, 0x0310, WRITE_MASK_VAL(9, 8, 2)), /* UART9 IO mux M2 */ + RK_MUXROUTE_GRF(1, RK_PA2, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PC6, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PD0, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 IO mux M2 */ + RK_MUXROUTE_GRF(2, RK_PC1, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PB6, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC2, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PA6, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PD6, 5, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PC4, 5, 0x0314, WRITE_MASK_VAL(1, 0, 2)), /* PDM IO mux M2 */ + RK_MUXROUTE_PMU(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 1)), /* PCIE20 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PB0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 2)), /* PCIE20 IO mux M2 */ + RK_MUXROUTE_PMU(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD2, 4, 0x0314, WRITE_MASK_VAL(5, 4, 1)), /* PCIE30X1 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA5, 4, 0x0314, WRITE_MASK_VAL(5, 4, 2)), /* PCIE30X1 IO mux M2 */ + RK_MUXROUTE_PMU(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD4, 4, 0x0314, WRITE_MASK_VAL(7, 6, 1)), /* PCIE30X2 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PC2, 4, 0x0314, WRITE_MASK_VAL(7, 6, 2)), /* PCIE30X2 IO mux M2 */ +}; + static bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin, int mux, u32 *loc, u32 *reg, u32 *value) { @@ -2104,6 +2228,68 @@ static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, *bit = (pin_num % 8) * 2; } +#define RK3568_PULL_PMU_OFFSET 0x20 +#define RK3568_PULL_GRF_OFFSET 0x80 +#define RK3568_PULL_BITS_PER_PIN 2 +#define RK3568_PULL_PINS_PER_REG 8 +#define RK3568_PULL_BANK_STRIDE 0x10 + +static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + if (bank->bank_num == 0) { + *regmap = info->regmap_pmu; + *reg = RK3568_PULL_PMU_OFFSET; + *reg += bank->bank_num * RK3568_PULL_BANK_STRIDE; + *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); + + *bit = pin_num % RK3568_PULL_PINS_PER_REG; + *bit *= RK3568_PULL_BITS_PER_PIN; + } else { + *regmap = info->regmap_base; + *reg = RK3568_PULL_GRF_OFFSET; + *reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE; + *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); + + *bit = (pin_num % RK3568_PULL_PINS_PER_REG); + *bit *= RK3568_PULL_BITS_PER_PIN; + } +} + +#define RK3568_DRV_PMU_OFFSET 0x70 +#define RK3568_DRV_GRF_OFFSET 0x200 +#define RK3568_DRV_BITS_PER_PIN 8 +#define RK3568_DRV_PINS_PER_REG 2 +#define RK3568_DRV_BANK_STRIDE 0x40 + +static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + /* The first 32 pins of the first bank are located in PMU */ + if (bank->bank_num == 0) { + *regmap = info->regmap_pmu; + *reg = RK3568_DRV_PMU_OFFSET; + *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); + + *bit = pin_num % RK3568_DRV_PINS_PER_REG; + *bit *= RK3568_DRV_BITS_PER_PIN; + } else { + *regmap = info->regmap_base; + *reg = RK3568_DRV_GRF_OFFSET; + *reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE; + *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); + + *bit = (pin_num % RK3568_DRV_PINS_PER_REG); + *bit *= RK3568_DRV_BITS_PER_PIN; + } +} + static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = { { 2, 4, 8, 12, -1, -1, -1, -1 }, { 3, 6, 9, 12, -1, -1, -1, -1 }, @@ -2204,6 +2390,11 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, bank->bank_num, pin_num, strength); ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit); + if (ctrl->type == RK3568) { + rmask_bits = RK3568_DRV_BITS_PER_PIN; + ret = (1 << (strength + 1)) - 1; + goto config; + } ret = -EINVAL; for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) { @@ -2273,6 +2464,7 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, return -EINVAL; } +config: /* enable the write to the equivalent lower bits */ data = ((1 << rmask_bits) - 1) << (bit + 16); rmask = data | (data >> 16); @@ -2375,6 +2567,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, case RK3308: case RK3368: case RK3399: + case RK3568: pull_type = bank->pull_type[pin_num / 8]; ret = -EINVAL; for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]); @@ -2384,6 +2577,14 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, break; } } + /* + * In the TRM, pull-up being 1 for everything except the GPIO0_D0-D6, + * where that pull up value becomes 3. + */ + if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) { + if (ret == 1) + ret = 3; + } if (ret < 0) { dev_err(info->dev, "unsupported pull setting %d\n", @@ -2428,6 +2629,35 @@ static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, return 0; } +#define RK3568_SCHMITT_BITS_PER_PIN 2 +#define RK3568_SCHMITT_PINS_PER_REG 8 +#define RK3568_SCHMITT_BANK_STRIDE 0x10 +#define RK3568_SCHMITT_GRF_OFFSET 0xc0 +#define RK3568_SCHMITT_PMUGRF_OFFSET 0x30 + +static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, + struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + if (bank->bank_num == 0) { + *regmap = info->regmap_pmu; + *reg = RK3568_SCHMITT_PMUGRF_OFFSET; + } else { + *regmap = info->regmap_base; + *reg = RK3568_SCHMITT_GRF_OFFSET; + *reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE; + } + + *reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4); + *bit = pin_num % RK3568_SCHMITT_PINS_PER_REG; + *bit *= RK3568_SCHMITT_BITS_PER_PIN; + + return 0; +} + static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num) { struct rockchip_pinctrl *info = bank->drvdata; @@ -2446,6 +2676,13 @@ static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num) return ret; data >>= bit; + switch (ctrl->type) { + case RK3568: + return data & ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1); + default: + break; + } + return data & 0x1; } @@ -2467,8 +2704,17 @@ static int rockchip_set_schmitt(struct rockchip_pin_bank *bank, return ret; /* enable the write to the equivalent lower bits */ - data = BIT(bit + 16) | (enable << bit); - rmask = BIT(bit + 16) | BIT(bit); + switch (ctrl->type) { + case RK3568: + data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16); + rmask = data | (data >> 16); + data |= ((enable ? 0x2 : 0x1) << bit); + break; + default: + data = BIT(bit + 16) | (enable << bit); + rmask = BIT(bit + 16) | BIT(bit); + break; + } return regmap_update_bits(regmap, reg, rmask, data); } @@ -2642,6 +2888,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, case RK3308: case RK3368: case RK3399: + case RK3568: return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); } @@ -4213,6 +4460,45 @@ static struct rockchip_pin_ctrl rk3399_pin_ctrl = { .drv_calc_reg = rk3399_calc_drv_reg_and_bit, }; +static struct rockchip_pin_bank rk3568_pin_banks[] = { + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), +}; + +static struct rockchip_pin_ctrl rk3568_pin_ctrl = { + .pin_banks = rk3568_pin_banks, + .nr_banks = ARRAY_SIZE(rk3568_pin_banks), + .label = "RK3568-GPIO", + .type = RK3568, + .grf_mux_offset = 0x0, + .pmu_mux_offset = 0x0, + .grf_drv_offset = 0x0200, + .pmu_drv_offset = 0x0070, + .iomux_routes = rk3568_mux_route_data, + .niomux_routes = ARRAY_SIZE(rk3568_mux_route_data), + .pull_calc_reg = rk3568_calc_pull_reg_and_bit, + .drv_calc_reg = rk3568_calc_drv_reg_and_bit, + .schmitt_calc_reg = rk3568_calc_schmitt_reg_and_bit, +}; + static const struct of_device_id rockchip_pinctrl_dt_match[] = { { .compatible = "rockchip,px30-pinctrl", .data = &px30_pin_ctrl }, @@ -4242,6 +4528,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = { .data = &rk3368_pin_ctrl }, { .compatible = "rockchip,rk3399-pinctrl", .data = &rk3399_pin_ctrl }, + { .compatible = "rockchip,rk3568-pinctrl", + .data = &rk3568_pin_ctrl }, {}, }; -- cgit v1.2.3 From 57c855f742c192a42fc4f37c8aff6ebebb61ae72 Mon Sep 17 00:00:00 2001 From: Junlin Yang Date: Tue, 30 Mar 2021 14:26:55 +0800 Subject: pinctrl: ti: fix error return code of ti_iodelay_dt_node_to_map() when devm_kcalloc fails, use -ENOMEM instead of -EINVAL, and consistent with other devm_kcalloc return values. Signed-off-by: Junlin Yang Link: https://lore.kernel.org/r/20210330062655.1027-1-angkery@163.com Signed-off-by: Linus Walleij --- drivers/pinctrl/ti/pinctrl-ti-iodelay.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/ti/pinctrl-ti-iodelay.c b/drivers/pinctrl/ti/pinctrl-ti-iodelay.c index e5848269175a..4e2382778d38 100644 --- a/drivers/pinctrl/ti/pinctrl-ti-iodelay.c +++ b/drivers/pinctrl/ti/pinctrl-ti-iodelay.c @@ -511,8 +511,10 @@ static int ti_iodelay_dt_node_to_map(struct pinctrl_dev *pctldev, } pins = devm_kcalloc(iod->dev, rows, sizeof(*pins), GFP_KERNEL); - if (!pins) + if (!pins) { + error = -ENOMEM; goto free_group; + } cfg = devm_kcalloc(iod->dev, rows, sizeof(*cfg), GFP_KERNEL); if (!cfg) { -- cgit v1.2.3 From f6b6db2dfd617522de702d85095d6d33e3b86e93 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 28 Mar 2021 15:30:33 -0300 Subject: pinctrl: imx: Remove unneeded of_match_ptr() i.MX is a DT-only platform, so of_match_ptr() can be safely removed. Remove the unneeded of_match_ptr(). Signed-off-by: Fabio Estevam Link: https://lore.kernel.org/r/20210328183034.555702-1-festevam@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/pinctrl-imx25.c | 2 +- drivers/pinctrl/freescale/pinctrl-imx27.c | 2 +- drivers/pinctrl/freescale/pinctrl-imx50.c | 2 +- drivers/pinctrl/freescale/pinctrl-imx6sll.c | 2 +- drivers/pinctrl/freescale/pinctrl-imx6sx.c | 2 +- drivers/pinctrl/freescale/pinctrl-imx6ul.c | 2 +- drivers/pinctrl/freescale/pinctrl-imx7d.c | 2 +- drivers/pinctrl/freescale/pinctrl-imx7ulp.c | 2 +- drivers/pinctrl/freescale/pinctrl-imx8dxl.c | 2 +- drivers/pinctrl/freescale/pinctrl-imx8mm.c | 2 +- drivers/pinctrl/freescale/pinctrl-imx8mn.c | 2 +- drivers/pinctrl/freescale/pinctrl-imx8mp.c | 2 +- drivers/pinctrl/freescale/pinctrl-imx8mq.c | 2 +- drivers/pinctrl/freescale/pinctrl-imx8qm.c | 2 +- drivers/pinctrl/freescale/pinctrl-imx8qxp.c | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/pinctrl/freescale/pinctrl-imx25.c b/drivers/pinctrl/freescale/pinctrl-imx25.c index a899a398b6bb..d7acd532ca8c 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx25.c +++ b/drivers/pinctrl/freescale/pinctrl-imx25.c @@ -323,7 +323,7 @@ static int imx25_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx25_pinctrl_driver = { .driver = { .name = "imx25-pinctrl", - .of_match_table = of_match_ptr(imx25_pinctrl_of_match), + .of_match_table = imx25_pinctrl_of_match, }, .probe = imx25_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx27.c b/drivers/pinctrl/freescale/pinctrl-imx27.c index b4dfc1676cbc..e87e7798e89d 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx27.c +++ b/drivers/pinctrl/freescale/pinctrl-imx27.c @@ -396,7 +396,7 @@ static int imx27_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx27_pinctrl_driver = { .driver = { .name = "imx27-pinctrl", - .of_match_table = of_match_ptr(imx27_pinctrl_of_match), + .of_match_table = imx27_pinctrl_of_match, }, .probe = imx27_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx50.c b/drivers/pinctrl/freescale/pinctrl-imx50.c index cf182c040e0b..7069a2fcd10a 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx50.c +++ b/drivers/pinctrl/freescale/pinctrl-imx50.c @@ -399,7 +399,7 @@ static int imx50_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx50_pinctrl_driver = { .driver = { .name = "imx50-pinctrl", - .of_match_table = of_match_ptr(imx50_pinctrl_of_match), + .of_match_table = imx50_pinctrl_of_match, }, .probe = imx50_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx6sll.c b/drivers/pinctrl/freescale/pinctrl-imx6sll.c index 0618f4d887fd..dfefcecbe072 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx6sll.c +++ b/drivers/pinctrl/freescale/pinctrl-imx6sll.c @@ -345,7 +345,7 @@ static int imx6sll_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx6sll_pinctrl_driver = { .driver = { .name = "imx6sll-pinctrl", - .of_match_table = of_match_ptr(imx6sll_pinctrl_of_match), + .of_match_table = imx6sll_pinctrl_of_match, .suppress_bind_attrs = true, }, .probe = imx6sll_pinctrl_probe, diff --git a/drivers/pinctrl/freescale/pinctrl-imx6sx.c b/drivers/pinctrl/freescale/pinctrl-imx6sx.c index c7e2b1f94f01..594185745029 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx6sx.c +++ b/drivers/pinctrl/freescale/pinctrl-imx6sx.c @@ -382,7 +382,7 @@ static int imx6sx_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx6sx_pinctrl_driver = { .driver = { .name = "imx6sx-pinctrl", - .of_match_table = of_match_ptr(imx6sx_pinctrl_of_match), + .of_match_table = imx6sx_pinctrl_of_match, }, .probe = imx6sx_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx6ul.c b/drivers/pinctrl/freescale/pinctrl-imx6ul.c index 7e37627c63f5..3c62bb38e551 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx6ul.c +++ b/drivers/pinctrl/freescale/pinctrl-imx6ul.c @@ -342,7 +342,7 @@ static int imx6ul_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx6ul_pinctrl_driver = { .driver = { .name = "imx6ul-pinctrl", - .of_match_table = of_match_ptr(imx6ul_pinctrl_of_match), + .of_match_table = imx6ul_pinctrl_of_match, }, .probe = imx6ul_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx7d.c b/drivers/pinctrl/freescale/pinctrl-imx7d.c index 369d3e59fdd6..38cbad3dba3a 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx7d.c +++ b/drivers/pinctrl/freescale/pinctrl-imx7d.c @@ -386,7 +386,7 @@ static int imx7d_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx7d_pinctrl_driver = { .driver = { .name = "imx7d-pinctrl", - .of_match_table = of_match_ptr(imx7d_pinctrl_of_match), + .of_match_table = imx7d_pinctrl_of_match, }, .probe = imx7d_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx7ulp.c b/drivers/pinctrl/freescale/pinctrl-imx7ulp.c index 922ff73c7087..1915378d92b2 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx7ulp.c +++ b/drivers/pinctrl/freescale/pinctrl-imx7ulp.c @@ -303,7 +303,7 @@ static int imx7ulp_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx7ulp_pinctrl_driver = { .driver = { .name = "imx7ulp-pinctrl", - .of_match_table = of_match_ptr(imx7ulp_pinctrl_of_match), + .of_match_table = imx7ulp_pinctrl_of_match, .suppress_bind_attrs = true, }, .probe = imx7ulp_pinctrl_probe, diff --git a/drivers/pinctrl/freescale/pinctrl-imx8dxl.c b/drivers/pinctrl/freescale/pinctrl-imx8dxl.c index d3020c0cd55d..041455c13d0d 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8dxl.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8dxl.c @@ -184,7 +184,7 @@ static int imx8dxl_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx8dxl_pinctrl_driver = { .driver = { .name = "fsl,imx8dxl-iomuxc", - .of_match_table = of_match_ptr(imx8dxl_pinctrl_of_match), + .of_match_table = imx8dxl_pinctrl_of_match, .suppress_bind_attrs = true, }, .probe = imx8dxl_pinctrl_probe, diff --git a/drivers/pinctrl/freescale/pinctrl-imx8mm.c b/drivers/pinctrl/freescale/pinctrl-imx8mm.c index 31c5d8861406..39dc73281ce6 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8mm.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8mm.c @@ -337,7 +337,7 @@ static int imx8mm_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx8mm_pinctrl_driver = { .driver = { .name = "imx8mm-pinctrl", - .of_match_table = of_match_ptr(imx8mm_pinctrl_of_match), + .of_match_table = imx8mm_pinctrl_of_match, .suppress_bind_attrs = true, }, .probe = imx8mm_pinctrl_probe, diff --git a/drivers/pinctrl/freescale/pinctrl-imx8mn.c b/drivers/pinctrl/freescale/pinctrl-imx8mn.c index 14c9deb51fec..448a79eb4568 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8mn.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8mn.c @@ -337,7 +337,7 @@ static int imx8mn_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx8mn_pinctrl_driver = { .driver = { .name = "imx8mn-pinctrl", - .of_match_table = of_match_ptr(imx8mn_pinctrl_of_match), + .of_match_table = imx8mn_pinctrl_of_match, .suppress_bind_attrs = true, }, .probe = imx8mn_pinctrl_probe, diff --git a/drivers/pinctrl/freescale/pinctrl-imx8mp.c b/drivers/pinctrl/freescale/pinctrl-imx8mp.c index bf4bbb5e2446..0cacf5ba162c 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8mp.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8mp.c @@ -335,7 +335,7 @@ static int imx8mp_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx8mp_pinctrl_driver = { .driver = { .name = "imx8mp-pinctrl", - .of_match_table = of_match_ptr(imx8mp_pinctrl_of_match), + .of_match_table = imx8mp_pinctrl_of_match, }, .probe = imx8mp_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx8mq.c b/drivers/pinctrl/freescale/pinctrl-imx8mq.c index ae3ea5b5c204..3ed3c98bcedb 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8mq.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8mq.c @@ -340,7 +340,7 @@ static int imx8mq_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx8mq_pinctrl_driver = { .driver = { .name = "imx8mq-pinctrl", - .of_match_table = of_match_ptr(imx8mq_pinctrl_of_match), + .of_match_table = imx8mq_pinctrl_of_match, .pm = &imx_pinctrl_pm_ops, .suppress_bind_attrs = true, }, diff --git a/drivers/pinctrl/freescale/pinctrl-imx8qm.c b/drivers/pinctrl/freescale/pinctrl-imx8qm.c index 8f46b9404cd7..2e2d30dc13f7 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8qm.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8qm.c @@ -317,7 +317,7 @@ static int imx8qm_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx8qm_pinctrl_driver = { .driver = { .name = "imx8qm-pinctrl", - .of_match_table = of_match_ptr(imx8qm_pinctrl_of_match), + .of_match_table = imx8qm_pinctrl_of_match, .suppress_bind_attrs = true, }, .probe = imx8qm_pinctrl_probe, diff --git a/drivers/pinctrl/freescale/pinctrl-imx8qxp.c b/drivers/pinctrl/freescale/pinctrl-imx8qxp.c index 6776ad6a3a27..4f97813ba8b7 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8qxp.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8qxp.c @@ -223,7 +223,7 @@ static int imx8qxp_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx8qxp_pinctrl_driver = { .driver = { .name = "imx8qxp-pinctrl", - .of_match_table = of_match_ptr(imx8qxp_pinctrl_of_match), + .of_match_table = imx8qxp_pinctrl_of_match, .suppress_bind_attrs = true, }, .probe = imx8qxp_pinctrl_probe, -- cgit v1.2.3 From 8a83ecd8ec6ce8c1c15e00a8ae3ebc71107ef044 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 28 Mar 2021 15:30:34 -0300 Subject: pinctrl: imx: Disallow driver unbind Performing the 'unbind' operation on pinctrl drivers is not a sensible usecase, so pass the suppress_bind_attrs atribute to prevent it. Signed-off-by: Fabio Estevam Link: https://lore.kernel.org/r/20210328183034.555702-2-festevam@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/pinctrl-imx1.c | 1 + drivers/pinctrl/freescale/pinctrl-imx25.c | 1 + drivers/pinctrl/freescale/pinctrl-imx27.c | 1 + drivers/pinctrl/freescale/pinctrl-imx35.c | 1 + drivers/pinctrl/freescale/pinctrl-imx50.c | 1 + drivers/pinctrl/freescale/pinctrl-imx51.c | 1 + drivers/pinctrl/freescale/pinctrl-imx53.c | 1 + drivers/pinctrl/freescale/pinctrl-imx6dl.c | 1 + drivers/pinctrl/freescale/pinctrl-imx6q.c | 1 + drivers/pinctrl/freescale/pinctrl-imx6sl.c | 1 + drivers/pinctrl/freescale/pinctrl-imx6sx.c | 1 + drivers/pinctrl/freescale/pinctrl-imx6ul.c | 1 + drivers/pinctrl/freescale/pinctrl-imx7d.c | 1 + drivers/pinctrl/freescale/pinctrl-imx8mp.c | 1 + drivers/pinctrl/freescale/pinctrl-vf610.c | 1 + 15 files changed, 15 insertions(+) diff --git a/drivers/pinctrl/freescale/pinctrl-imx1.c b/drivers/pinctrl/freescale/pinctrl-imx1.c index faf770f13bc7..1e2b0fe9ffd6 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx1.c +++ b/drivers/pinctrl/freescale/pinctrl-imx1.c @@ -262,6 +262,7 @@ static struct platform_driver imx1_pinctrl_driver = { .driver = { .name = "imx1-pinctrl", .of_match_table = imx1_pinctrl_of_match, + .suppress_bind_attrs = true, }, }; builtin_platform_driver_probe(imx1_pinctrl_driver, imx1_pinctrl_probe); diff --git a/drivers/pinctrl/freescale/pinctrl-imx25.c b/drivers/pinctrl/freescale/pinctrl-imx25.c index d7acd532ca8c..51748da1668f 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx25.c +++ b/drivers/pinctrl/freescale/pinctrl-imx25.c @@ -324,6 +324,7 @@ static struct platform_driver imx25_pinctrl_driver = { .driver = { .name = "imx25-pinctrl", .of_match_table = imx25_pinctrl_of_match, + .suppress_bind_attrs = true, }, .probe = imx25_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx27.c b/drivers/pinctrl/freescale/pinctrl-imx27.c index e87e7798e89d..67e7105be4f3 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx27.c +++ b/drivers/pinctrl/freescale/pinctrl-imx27.c @@ -397,6 +397,7 @@ static struct platform_driver imx27_pinctrl_driver = { .driver = { .name = "imx27-pinctrl", .of_match_table = imx27_pinctrl_of_match, + .suppress_bind_attrs = true, }, .probe = imx27_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx35.c b/drivers/pinctrl/freescale/pinctrl-imx35.c index 871bb419e2f0..c8671ad5214c 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx35.c +++ b/drivers/pinctrl/freescale/pinctrl-imx35.c @@ -1014,6 +1014,7 @@ static struct platform_driver imx35_pinctrl_driver = { .driver = { .name = "imx35-pinctrl", .of_match_table = imx35_pinctrl_of_match, + .suppress_bind_attrs = true, }, .probe = imx35_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx50.c b/drivers/pinctrl/freescale/pinctrl-imx50.c index 7069a2fcd10a..a245b4011c00 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx50.c +++ b/drivers/pinctrl/freescale/pinctrl-imx50.c @@ -400,6 +400,7 @@ static struct platform_driver imx50_pinctrl_driver = { .driver = { .name = "imx50-pinctrl", .of_match_table = imx50_pinctrl_of_match, + .suppress_bind_attrs = true, }, .probe = imx50_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx51.c b/drivers/pinctrl/freescale/pinctrl-imx51.c index e5c261e2bf1e..307cf5fe4d15 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx51.c +++ b/drivers/pinctrl/freescale/pinctrl-imx51.c @@ -776,6 +776,7 @@ static struct platform_driver imx51_pinctrl_driver = { .driver = { .name = "imx51-pinctrl", .of_match_table = imx51_pinctrl_of_match, + .suppress_bind_attrs = true, }, .probe = imx51_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx53.c b/drivers/pinctrl/freescale/pinctrl-imx53.c index 64c97aaf20c7..02bf3bda69ac 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx53.c +++ b/drivers/pinctrl/freescale/pinctrl-imx53.c @@ -463,6 +463,7 @@ static struct platform_driver imx53_pinctrl_driver = { .driver = { .name = "imx53-pinctrl", .of_match_table = imx53_pinctrl_of_match, + .suppress_bind_attrs = true, }, .probe = imx53_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx6dl.c b/drivers/pinctrl/freescale/pinctrl-imx6dl.c index 0858b4d79ed2..2b6d5141a477 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx6dl.c +++ b/drivers/pinctrl/freescale/pinctrl-imx6dl.c @@ -473,6 +473,7 @@ static struct platform_driver imx6dl_pinctrl_driver = { .driver = { .name = "imx6dl-pinctrl", .of_match_table = imx6dl_pinctrl_of_match, + .suppress_bind_attrs = true, }, .probe = imx6dl_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx6q.c b/drivers/pinctrl/freescale/pinctrl-imx6q.c index 078ed6a331fd..a7507def26a9 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx6q.c +++ b/drivers/pinctrl/freescale/pinctrl-imx6q.c @@ -475,6 +475,7 @@ static struct platform_driver imx6q_pinctrl_driver = { .driver = { .name = "imx6q-pinctrl", .of_match_table = imx6q_pinctrl_of_match, + .suppress_bind_attrs = true, }, .probe = imx6q_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx6sl.c b/drivers/pinctrl/freescale/pinctrl-imx6sl.c index 9d2e6f987aa7..236f3bf120c2 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx6sl.c +++ b/drivers/pinctrl/freescale/pinctrl-imx6sl.c @@ -379,6 +379,7 @@ static struct platform_driver imx6sl_pinctrl_driver = { .driver = { .name = "imx6sl-pinctrl", .of_match_table = imx6sl_pinctrl_of_match, + .suppress_bind_attrs = true, }, .probe = imx6sl_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx6sx.c b/drivers/pinctrl/freescale/pinctrl-imx6sx.c index 594185745029..b7b97c274dcc 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx6sx.c +++ b/drivers/pinctrl/freescale/pinctrl-imx6sx.c @@ -383,6 +383,7 @@ static struct platform_driver imx6sx_pinctrl_driver = { .driver = { .name = "imx6sx-pinctrl", .of_match_table = imx6sx_pinctrl_of_match, + .suppress_bind_attrs = true, }, .probe = imx6sx_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx6ul.c b/drivers/pinctrl/freescale/pinctrl-imx6ul.c index 3c62bb38e551..3b8747482e36 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx6ul.c +++ b/drivers/pinctrl/freescale/pinctrl-imx6ul.c @@ -343,6 +343,7 @@ static struct platform_driver imx6ul_pinctrl_driver = { .driver = { .name = "imx6ul-pinctrl", .of_match_table = imx6ul_pinctrl_of_match, + .suppress_bind_attrs = true, }, .probe = imx6ul_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx7d.c b/drivers/pinctrl/freescale/pinctrl-imx7d.c index 38cbad3dba3a..4126387344cb 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx7d.c +++ b/drivers/pinctrl/freescale/pinctrl-imx7d.c @@ -387,6 +387,7 @@ static struct platform_driver imx7d_pinctrl_driver = { .driver = { .name = "imx7d-pinctrl", .of_match_table = imx7d_pinctrl_of_match, + .suppress_bind_attrs = true, }, .probe = imx7d_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx8mp.c b/drivers/pinctrl/freescale/pinctrl-imx8mp.c index 0cacf5ba162c..88abc257318f 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8mp.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8mp.c @@ -336,6 +336,7 @@ static struct platform_driver imx8mp_pinctrl_driver = { .driver = { .name = "imx8mp-pinctrl", .of_match_table = imx8mp_pinctrl_of_match, + .suppress_bind_attrs = true, }, .probe = imx8mp_pinctrl_probe, }; diff --git a/drivers/pinctrl/freescale/pinctrl-vf610.c b/drivers/pinctrl/freescale/pinctrl-vf610.c index 37602b053ed2..700e5a136814 100644 --- a/drivers/pinctrl/freescale/pinctrl-vf610.c +++ b/drivers/pinctrl/freescale/pinctrl-vf610.c @@ -336,6 +336,7 @@ static struct platform_driver vf610_pinctrl_driver = { .driver = { .name = "vf610-pinctrl", .of_match_table = vf610_pinctrl_of_match, + .suppress_bind_attrs = true, }, .probe = vf610_pinctrl_probe, }; -- cgit v1.2.3 From 775c93a7c5b4d31f716db21fd097a64e9b5bf3b7 Mon Sep 17 00:00:00 2001 From: Niklas Söderlund Date: Sun, 28 Mar 2021 18:42:22 +0200 Subject: docs: pin-control: Fix error path for control state example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The error is constructed using the wrong variable. Signed-off-by: Niklas Söderlund Link: https://lore.kernel.org/r/20210328164222.720525-1-niklas.soderlund+renesas@ragnatech.se Signed-off-by: Linus Walleij --- Documentation/driver-api/pin-control.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/driver-api/pin-control.rst b/Documentation/driver-api/pin-control.rst index c905b273e833..e2474425fb0c 100644 --- a/Documentation/driver-api/pin-control.rst +++ b/Documentation/driver-api/pin-control.rst @@ -1235,7 +1235,7 @@ default state like this:: foo->s = pinctrl_lookup_state(foo->p, PINCTRL_STATE_DEFAULT); if (IS_ERR(foo->s)) { /* FIXME: clean up "foo" here */ - return PTR_ERR(s); + return PTR_ERR(foo->s); } ret = pinctrl_select_state(foo->s); -- cgit v1.2.3 From 18d2719f46bc1cbbc17673b6a0f7576c622e5694 Mon Sep 17 00:00:00 2001 From: Guru Das Srinagesh Date: Thu, 8 Apr 2021 10:25:06 -0700 Subject: dt-bindings: pinctrl: qcom-pmic-gpio: Add pm8008 support Add support for the 2 GPIOs present on Qualcomm Technologies, Inc. PM8008. Acked-by: Bjorn Andersson Signed-off-by: Guru Das Srinagesh Link: https://lore.kernel.org/r/2be34cc205ae96d40b04a9efdcf9287d5da9d1c0.1617901945.git.gurus@codeaurora.org Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt index 70e119b39c48..f6a9760558a6 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt @@ -35,6 +35,7 @@ PMIC's from Qualcomm. "qcom,pmr735b-gpio" "qcom,pm6150-gpio" "qcom,pm6150l-gpio" + "qcom,pm8008-gpio" "qcom,pmx55-gpio" And must contain either "qcom,spmi-gpio" or "qcom,ssbi-gpio" @@ -123,6 +124,7 @@ to specify in a pin configuration subnode: gpio1-gpio4 for pmr735b gpio1-gpio10 for pm6150 gpio1-gpio12 for pm6150l + gpio1-gpio2 for pm8008 gpio1-gpio11 for pmx55 (holes on gpio3, gpio7, gpio10 and gpio11) -- cgit v1.2.3 From ea119e5a482aaf08dd22cf53400c29cb16af8416 Mon Sep 17 00:00:00 2001 From: Guru Das Srinagesh Date: Thu, 8 Apr 2021 10:25:07 -0700 Subject: pinctrl: qcom-pmic-gpio: Add support for pm8008 Add support for the two GPIOs present on Qualcomm Technologies, Inc. PM8008. Reviewed-by: Bjorn Andersson Signed-off-by: Guru Das Srinagesh Link: https://lore.kernel.org/r/129d241ee510e28536d35dbfeee75474e12d8d22.1617901945.git.gurus@codeaurora.org Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index c2b9f2e152bb..00870da0c94e 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -1135,6 +1135,7 @@ static const struct of_device_id pmic_gpio_of_match[] = { { .compatible = "qcom,pmr735b-gpio", .data = (void *) 4 }, { .compatible = "qcom,pm6150-gpio", .data = (void *) 10 }, { .compatible = "qcom,pm6150l-gpio", .data = (void *) 12 }, + { .compatible = "qcom,pm8008-gpio", .data = (void *) 2 }, /* pmx55 has 11 GPIOs with holes on 3, 7, 10, 11 */ { .compatible = "qcom,pmx55-gpio", .data = (void *) 11 }, { }, -- cgit v1.2.3 From fa0c10a5f3a49130dd11281aa27e7e1c8654abc7 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 8 Apr 2021 21:50:29 +0200 Subject: pinctrl: samsung: use 'int' for register masks in Exynos The Special Function Registers on all Exynos SoC, including ARM64, are 32-bit wide, so entire driver uses matching functions like readl() or writel(). On 64-bit ARM using unsigned long for register masks: 1. makes little sense as immediately after bitwise operation it will be cast to 32-bit value when calling writel(), 2. is actually error-prone because it might promote other operands to 64-bit. Addresses-Coverity: Unintentional integer overflow Signed-off-by: Krzysztof Kozlowski Reviewed-by: Sylwester Nawrocki Link: https://lore.kernel.org/r/20210408195029.69974-1-krzysztof.kozlowski@canonical.com Signed-off-by: Linus Walleij --- drivers/pinctrl/samsung/pinctrl-exynos.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index 0cd7f33cdf25..2b99f4130e1e 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -55,7 +55,7 @@ static void exynos_irq_mask(struct irq_data *irqd) struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset; - unsigned long mask; + unsigned int mask; unsigned long flags; raw_spin_lock_irqsave(&bank->slock, flags); @@ -83,7 +83,7 @@ static void exynos_irq_unmask(struct irq_data *irqd) struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset; - unsigned long mask; + unsigned int mask; unsigned long flags; /* @@ -483,7 +483,7 @@ static void exynos_irq_eint0_15(struct irq_desc *desc) chained_irq_exit(chip, desc); } -static inline void exynos_irq_demux_eint(unsigned long pend, +static inline void exynos_irq_demux_eint(unsigned int pend, struct irq_domain *domain) { unsigned int irq; @@ -500,8 +500,8 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc) { struct irq_chip *chip = irq_desc_get_chip(desc); struct exynos_muxed_weint_data *eintd = irq_desc_get_handler_data(desc); - unsigned long pend; - unsigned long mask; + unsigned int pend; + unsigned int mask; int i; chained_irq_enter(chip, desc); -- cgit v1.2.3 From cbde6c823bfaa553fb162257a5926ba15ebaaa43 Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Fri, 9 Apr 2021 11:25:22 +0300 Subject: pinctrl: at91-pio4: Fix slew rate disablement The slew rate was enabled by default for each configuration of the pin. In case the pin had more than one configuration, even if we set the slew rate as disabled in the device tree, the next pin configuration would set again the slew rate enabled by default, overwriting the slew rate disablement. Instead of enabling the slew rate by default for each pin configuration, enable the slew rate by default just once per pin, regardless of the number of configurations. This way the slew rate disablement will also work for cases where pins have multiple configurations. Fixes: c709135e576b ("pinctrl: at91-pio4: add support for slew-rate") Signed-off-by: Tudor Ambarus Reviewed-by: Claudiu Beznea Acked-by: Ludovic Desroches Link: https://lore.kernel.org/r/20210409082522.625168-1-tudor.ambarus@microchip.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-at91-pio4.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c index e71ebccc479c..03c32b2c5d30 100644 --- a/drivers/pinctrl/pinctrl-at91-pio4.c +++ b/drivers/pinctrl/pinctrl-at91-pio4.c @@ -801,6 +801,10 @@ static int atmel_conf_pin_config_group_set(struct pinctrl_dev *pctldev, conf = atmel_pin_config_read(pctldev, pin_id); + /* Keep slew rate enabled by default. */ + if (atmel_pioctrl->slew_rate_support) + conf |= ATMEL_PIO_SR_MASK; + for (i = 0; i < num_configs; i++) { unsigned int param = pinconf_to_config_param(configs[i]); unsigned int arg = pinconf_to_config_argument(configs[i]); @@ -808,10 +812,6 @@ static int atmel_conf_pin_config_group_set(struct pinctrl_dev *pctldev, dev_dbg(pctldev->dev, "%s: pin=%u, config=0x%lx\n", __func__, pin_id, configs[i]); - /* Keep slew rate enabled by default. */ - if (atmel_pioctrl->slew_rate_support) - conf |= ATMEL_PIO_SR_MASK; - switch (param) { case PIN_CONFIG_BIAS_DISABLE: conf &= (~ATMEL_PIO_PUEN_MASK); -- cgit v1.2.3 From 376f9e34c10faa3e94b881088b160cfda540ae5f Mon Sep 17 00:00:00 2001 From: Julian Braha Date: Tue, 13 Apr 2021 22:51:38 -0400 Subject: drivers: pinctrl: qcom: fix Kconfig dependency on GPIOLIB When PINCTRL_MSM is enabled, and GPIOLIB is disabled, Kbuild gives the following warning: WARNING: unmet direct dependencies detected for GPIOLIB_IRQCHIP Depends on [n]: GPIOLIB [=n] Selected by [y]: - PINCTRL_MSM [=y] && PINCTRL [=y] && (ARCH_QCOM || COMPILE_TEST [=y]) This is because PINCTRL_MSM selects GPIOLIB_IRQCHIP, without selecting or depending on GPIOLIB, despite GPIOLIB_IRQCHIP depending on GPIOLIB. Having PINCTRL_MSM select GPIOLIB will cause a recursive dependency error. Signed-off-by: Julian Braha Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210414025138.480085-1-julianbraha@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index 9f0218c4f9b3..25d2f7f7f3b6 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -3,7 +3,7 @@ if (ARCH_QCOM || COMPILE_TEST) config PINCTRL_MSM tristate "Qualcomm core pin controller driver" - depends on QCOM_SCM || !QCOM_SCM #if QCOM_SCM=m this can't be =y + depends on GPIOLIB && (QCOM_SCM || !QCOM_SCM) #if QCOM_SCM=m this can't be =y select PINMUX select PINCONF select GENERIC_PINCONF -- cgit v1.2.3 From 914a307c3b4f2eb3401a1778bb98a7dfbfed1ccb Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Sat, 10 Apr 2021 17:45:00 -0300 Subject: dt-bindings: pinctrl: rockchip: add RK3568 SoC support Add RK3568/RK3566 SoC support to pinctrl. Signed-off-by: Ezequiel Garcia Reviewed-by: Heiko Stuebner Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210410204500.18091-1-ezequiel@collabora.com Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt index d3eae61a340d..91fab614c381 100644 --- a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt @@ -33,6 +33,7 @@ Required properties for iomux controller: "rockchip,rk3328-pinctrl": for Rockchip RK3328 "rockchip,rk3368-pinctrl": for Rockchip RK3368 "rockchip,rk3399-pinctrl": for Rockchip RK3399 + "rockchip,rk3568-pinctrl": for Rockchip RK3568 - rockchip,grf: phandle referencing a syscon providing the "general register files" -- cgit v1.2.3 From 65afd97630a9d6dd9ea83ff182dfdb15bc58c5d1 Mon Sep 17 00:00:00 2001 From: "周琰杰 (Zhou Yanjie)" Date: Sun, 18 Apr 2021 22:44:22 +0800 Subject: pinctrl: Ingenic: Add missing pins to the JZ4770 MAC MII group. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MII group of JZ4770's MAC should have 7 pins, add missing pins to the MII group. Fixes: 5de1a73e78ed ("Pinctrl: Ingenic: Add missing parts for JZ4770 and JZ4780.") Cc: Signed-off-by: 周琰杰 (Zhou Yanjie) Reviewed-by: Andy Shevchenko Reviewed-by: Paul Cercueil Link: https://lore.kernel.org/r/1618757073-1724-2-git-send-email-zhouyanjie@wanyeetech.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index c8ecd014cf19..f15ef814b75a 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -667,7 +667,9 @@ static int jz4770_pwm_pwm7_pins[] = { 0x6b, }; static int jz4770_mac_rmii_pins[] = { 0xa9, 0xab, 0xaa, 0xac, 0xa5, 0xa4, 0xad, 0xae, 0xa6, 0xa8, }; -static int jz4770_mac_mii_pins[] = { 0xa7, 0xaf, }; +static int jz4770_mac_mii_pins[] = { + 0x7b, 0x7a, 0x7d, 0x7c, 0xa7, 0x24, 0xaf, +}; static const struct group_desc jz4770_groups[] = { INGENIC_PIN_GROUP("uart0-data", jz4770_uart0_data, 0), -- cgit v1.2.3 From 1d0bd580ef83b78a10c0b37f3313eaa59d8c80db Mon Sep 17 00:00:00 2001 From: "周琰杰 (Zhou Yanjie)" Date: Sun, 18 Apr 2021 22:44:23 +0800 Subject: pinctrl: Ingenic: Add support for read the pin configuration of X1830. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add X1830 support in "ingenic_pinconf_get()", so that it can read the configuration of X1830 SoC correctly. Fixes: d7da2a1e4e08 ("pinctrl: Ingenic: Add pinctrl driver for X1830.") Cc: Signed-off-by: 周琰杰 (Zhou Yanjie) Reviewed-by: Andy Shevchenko Reviewed-by: Paul Cercueil Link: https://lore.kernel.org/r/1618757073-1724-3-git-send-email-zhouyanjie@wanyeetech.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 40 ++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index f15ef814b75a..02729da8abd6 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -2109,26 +2109,48 @@ static int ingenic_pinconf_get(struct pinctrl_dev *pctldev, enum pin_config_param param = pinconf_to_config_param(*config); unsigned int idx = pin % PINS_PER_GPIO_CHIP; unsigned int offt = pin / PINS_PER_GPIO_CHIP; - bool pull; + unsigned int bias; + bool pull, pullup, pulldown; - if (jzpc->info->version >= ID_JZ4770) - pull = !ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PEN); - else - pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS); + if (jzpc->info->version >= ID_X1830) { + unsigned int half = PINS_PER_GPIO_CHIP / 2; + unsigned int idxh = (pin % half) * 2; + + if (idx < half) + regmap_read(jzpc->map, offt * jzpc->info->reg_offset + + X1830_GPIO_PEL, &bias); + else + regmap_read(jzpc->map, offt * jzpc->info->reg_offset + + X1830_GPIO_PEH, &bias); + + bias = (bias >> idxh) & (GPIO_PULL_UP | GPIO_PULL_DOWN); + + pullup = (bias == GPIO_PULL_UP) && (jzpc->info->pull_ups[offt] & BIT(idx)); + pulldown = (bias == GPIO_PULL_DOWN) && (jzpc->info->pull_downs[offt] & BIT(idx)); + + } else { + if (jzpc->info->version >= ID_JZ4770) + pull = !ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PEN); + else + pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS); + + pullup = pull && (jzpc->info->pull_ups[offt] & BIT(idx)); + pulldown = pull && (jzpc->info->pull_downs[offt] & BIT(idx)); + } switch (param) { case PIN_CONFIG_BIAS_DISABLE: - if (pull) + if (pullup || pulldown) return -EINVAL; break; case PIN_CONFIG_BIAS_PULL_UP: - if (!pull || !(jzpc->info->pull_ups[offt] & BIT(idx))) + if (!pullup) return -EINVAL; break; case PIN_CONFIG_BIAS_PULL_DOWN: - if (!pull || !(jzpc->info->pull_downs[offt] & BIT(idx))) + if (!pulldown) return -EINVAL; break; @@ -2146,7 +2168,7 @@ static void ingenic_set_bias(struct ingenic_pinctrl *jzpc, if (jzpc->info->version >= ID_X1830) { unsigned int idx = pin % PINS_PER_GPIO_CHIP; unsigned int half = PINS_PER_GPIO_CHIP / 2; - unsigned int idxh = pin % half * 2; + unsigned int idxh = (pin % half) * 2; unsigned int offt = pin / PINS_PER_GPIO_CHIP; if (idx < half) { -- cgit v1.2.3 From 1101519695d0594f353bced77bc9995c13f31048 Mon Sep 17 00:00:00 2001 From: "周琰杰 (Zhou Yanjie)" Date: Sun, 18 Apr 2021 22:44:24 +0800 Subject: pinctrl: Ingenic: Adjust the sequence of X1830 SSI pin groups. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adjust the sequence of X1830's SSI related codes to make it consistent with other Ingenic SoCs. Signed-off-by: 周琰杰 (Zhou Yanjie) Reviewed-by: Andy Shevchenko Reviewed-by: Paul Cercueil Link: https://lore.kernel.org/r/1618757073-1724-4-git-send-email-zhouyanjie@wanyeetech.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 02729da8abd6..761e42dc471e 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -1473,16 +1473,16 @@ static int x1830_ssi0_gpc_pins[] = { 0x4d, }; static int x1830_ssi0_ce0_pins[] = { 0x50, }; static int x1830_ssi0_ce1_pins[] = { 0x4e, }; static int x1830_ssi1_dt_c_pins[] = { 0x53, }; -static int x1830_ssi1_dr_c_pins[] = { 0x54, }; -static int x1830_ssi1_clk_c_pins[] = { 0x57, }; -static int x1830_ssi1_gpc_c_pins[] = { 0x55, }; -static int x1830_ssi1_ce0_c_pins[] = { 0x58, }; -static int x1830_ssi1_ce1_c_pins[] = { 0x56, }; static int x1830_ssi1_dt_d_pins[] = { 0x62, }; +static int x1830_ssi1_dr_c_pins[] = { 0x54, }; static int x1830_ssi1_dr_d_pins[] = { 0x63, }; +static int x1830_ssi1_clk_c_pins[] = { 0x57, }; static int x1830_ssi1_clk_d_pins[] = { 0x66, }; +static int x1830_ssi1_gpc_c_pins[] = { 0x55, }; static int x1830_ssi1_gpc_d_pins[] = { 0x64, }; +static int x1830_ssi1_ce0_c_pins[] = { 0x58, }; static int x1830_ssi1_ce0_d_pins[] = { 0x67, }; +static int x1830_ssi1_ce1_c_pins[] = { 0x56, }; static int x1830_ssi1_ce1_d_pins[] = { 0x65, }; static int x1830_mmc0_1bit_pins[] = { 0x24, 0x25, 0x20, }; static int x1830_mmc0_4bit_pins[] = { 0x21, 0x22, 0x23, }; -- cgit v1.2.3 From 5e6332a7ff39eb7701c717c3b5ec652659a7fb6a Mon Sep 17 00:00:00 2001 From: "周琰杰 (Zhou Yanjie)" Date: Sun, 18 Apr 2021 22:44:25 +0800 Subject: pinctrl: Ingenic: Improve LCD pins related code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.In the JZ4740 part, remove pointless "lcd-no-pins", use "lcd-special" and "lcd-generic" instead "lcd-18bit-tft". Currently, in the mainline, no other devicetree out there is using the "lcd-18bit-tft" ABI, so we should be able to replace it safely. 2.In the JZ4725B part, adjust the location of the LCD pins related code to keep them consistent with the style of other parts. 3.In the JZ4760 part, add the missing comma and adjust element order in "jz4760_lcd_special_pins[]", keep them in the order of CLS/SPL/PS/REV like other "lcd_special_pins" arrays. And adjust the location of the "jz4760_lcd_generic" related code to keep them consistent with the style of other parts. 4.In the JZ4770 part, remove pointless "lcd-no-pins", add the missing "lcd-16bit", "lcd-18bit", "lcd-special", "lcd-generic". 5.In the X1000 part and the X1500 part, remove pointless "lcd-no-pins". 6.In the X1830 part, replace "lcd-rgb-18bit" with "lcd-tft-8bit" and "lcd-tft-24bit", because of the description of the TRANS_CONFIG.MODE register bits in the PM manual of the X1830, shows that the X1830 only supppots 24bit mode and 8bit mode for tft interface, only 18 pins in the GPIO table are because of the data[17:16], the data[9:8], and the data[1:0] has not been connected. And according to the description, the two interfaces supported by X1830 are respectively referred to as "TFT interface" and "SLCD interface", so the "lcd-rgb-xxx" is replaced with "lcd-tft-xxx" to avoid confusion. Signed-off-by: 周琰杰 (Zhou Yanjie) Reviewed-by: Paul Cercueil Link: https://lore.kernel.org/r/1618757073-1724-5-git-send-email-zhouyanjie@wanyeetech.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 110 +++++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 49 deletions(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 761e42dc471e..7114b78da41f 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -113,13 +113,15 @@ static int jz4740_uart0_data_pins[] = { 0x7a, 0x79, }; static int jz4740_uart0_hwflow_pins[] = { 0x7e, 0x7f, }; static int jz4740_uart1_data_pins[] = { 0x7e, 0x7f, }; static int jz4740_lcd_8bit_pins[] = { - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x52, 0x53, 0x54, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x52, 0x53, 0x54, }; static int jz4740_lcd_16bit_pins[] = { - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x55, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, }; static int jz4740_lcd_18bit_pins[] = { 0x50, 0x51, }; -static int jz4740_lcd_18bit_tft_pins[] = { 0x56, 0x57, 0x31, 0x32, }; +static int jz4740_lcd_special_pins[] = { 0x31, 0x32, 0x56, 0x57, }; +static int jz4740_lcd_generic_pins[] = { 0x55, }; static int jz4740_nand_cs1_pins[] = { 0x39, }; static int jz4740_nand_cs2_pins[] = { 0x3a, }; static int jz4740_nand_cs3_pins[] = { 0x3b, }; @@ -155,8 +157,8 @@ static const struct group_desc jz4740_groups[] = { INGENIC_PIN_GROUP("lcd-8bit", jz4740_lcd_8bit, 0), INGENIC_PIN_GROUP("lcd-16bit", jz4740_lcd_16bit, 0), INGENIC_PIN_GROUP("lcd-18bit", jz4740_lcd_18bit, 0), - INGENIC_PIN_GROUP("lcd-18bit-tft", jz4740_lcd_18bit_tft, 0), - { "lcd-no-pins", }, + INGENIC_PIN_GROUP("lcd-special", jz4740_lcd_special, 0), + INGENIC_PIN_GROUP("lcd-generic", jz4740_lcd_generic, 0), INGENIC_PIN_GROUP("nand-cs1", jz4740_nand_cs1, 0), INGENIC_PIN_GROUP("nand-cs2", jz4740_nand_cs2, 0), INGENIC_PIN_GROUP("nand-cs3", jz4740_nand_cs3, 0), @@ -176,7 +178,7 @@ static const char *jz4740_mmc_groups[] = { "mmc-1bit", "mmc-4bit", }; static const char *jz4740_uart0_groups[] = { "uart0-data", "uart0-hwflow", }; static const char *jz4740_uart1_groups[] = { "uart1-data", }; static const char *jz4740_lcd_groups[] = { - "lcd-8bit", "lcd-16bit", "lcd-18bit", "lcd-18bit-tft", "lcd-no-pins", + "lcd-8bit", "lcd-16bit", "lcd-18bit", "lcd-special", "lcd-generic", }; static const char *jz4740_nand_groups[] = { "nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4", "nand-fre-fwe", @@ -223,6 +225,17 @@ static int jz4725b_mmc0_4bit_pins[] = { 0x5d, 0x5b, 0x56, }; static int jz4725b_mmc1_1bit_pins[] = { 0x7a, 0x7b, 0x7c, }; static int jz4725b_mmc1_4bit_pins[] = { 0x7d, 0x7e, 0x7f, }; static int jz4725b_uart_data_pins[] = { 0x4c, 0x4d, }; +static int jz4725b_lcd_8bit_pins[] = { + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x72, 0x73, 0x74, +}; +static int jz4725b_lcd_16bit_pins[] = { + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, +}; +static int jz4725b_lcd_18bit_pins[] = { 0x70, 0x71, }; +static int jz4725b_lcd_24bit_pins[] = { 0x76, 0x77, 0x78, 0x79, }; +static int jz4725b_lcd_special_pins[] = { 0x76, 0x77, 0x78, 0x79, }; +static int jz4725b_lcd_generic_pins[] = { 0x75, }; static int jz4725b_nand_cs1_pins[] = { 0x55, }; static int jz4725b_nand_cs2_pins[] = { 0x56, }; static int jz4725b_nand_cs3_pins[] = { 0x57, }; @@ -235,19 +248,6 @@ static int jz4725b_pwm_pwm2_pins[] = { 0x4c, }; static int jz4725b_pwm_pwm3_pins[] = { 0x4d, }; static int jz4725b_pwm_pwm4_pins[] = { 0x4e, }; static int jz4725b_pwm_pwm5_pins[] = { 0x4f, }; -static int jz4725b_lcd_8bit_pins[] = { - 0x72, 0x73, 0x74, - 0x60, 0x61, 0x62, 0x63, - 0x64, 0x65, 0x66, 0x67, -}; -static int jz4725b_lcd_16bit_pins[] = { - 0x68, 0x69, 0x6a, 0x6b, - 0x6c, 0x6d, 0x6e, 0x6f, -}; -static int jz4725b_lcd_18bit_pins[] = { 0x70, 0x71, }; -static int jz4725b_lcd_24bit_pins[] = { 0x76, 0x77, 0x78, 0x79, }; -static int jz4725b_lcd_special_pins[] = { 0x76, 0x77, 0x78, 0x79, }; -static int jz4725b_lcd_generic_pins[] = { 0x75, }; static u8 jz4725b_mmc0_4bit_funcs[] = { 1, 0, 1, }; @@ -258,6 +258,12 @@ static const struct group_desc jz4725b_groups[] = { INGENIC_PIN_GROUP("mmc1-1bit", jz4725b_mmc1_1bit, 0), INGENIC_PIN_GROUP("mmc1-4bit", jz4725b_mmc1_4bit, 0), INGENIC_PIN_GROUP("uart-data", jz4725b_uart_data, 1), + INGENIC_PIN_GROUP("lcd-8bit", jz4725b_lcd_8bit, 0), + INGENIC_PIN_GROUP("lcd-16bit", jz4725b_lcd_16bit, 0), + INGENIC_PIN_GROUP("lcd-18bit", jz4725b_lcd_18bit, 0), + INGENIC_PIN_GROUP("lcd-24bit", jz4725b_lcd_24bit, 1), + INGENIC_PIN_GROUP("lcd-special", jz4725b_lcd_special, 0), + INGENIC_PIN_GROUP("lcd-generic", jz4725b_lcd_generic, 0), INGENIC_PIN_GROUP("nand-cs1", jz4725b_nand_cs1, 0), INGENIC_PIN_GROUP("nand-cs2", jz4725b_nand_cs2, 0), INGENIC_PIN_GROUP("nand-cs3", jz4725b_nand_cs3, 0), @@ -270,17 +276,15 @@ static const struct group_desc jz4725b_groups[] = { INGENIC_PIN_GROUP("pwm3", jz4725b_pwm_pwm3, 0), INGENIC_PIN_GROUP("pwm4", jz4725b_pwm_pwm4, 0), INGENIC_PIN_GROUP("pwm5", jz4725b_pwm_pwm5, 0), - INGENIC_PIN_GROUP("lcd-8bit", jz4725b_lcd_8bit, 0), - INGENIC_PIN_GROUP("lcd-16bit", jz4725b_lcd_16bit, 0), - INGENIC_PIN_GROUP("lcd-18bit", jz4725b_lcd_18bit, 0), - INGENIC_PIN_GROUP("lcd-24bit", jz4725b_lcd_24bit, 1), - INGENIC_PIN_GROUP("lcd-special", jz4725b_lcd_special, 0), - INGENIC_PIN_GROUP("lcd-generic", jz4725b_lcd_generic, 0), }; static const char *jz4725b_mmc0_groups[] = { "mmc0-1bit", "mmc0-4bit", }; static const char *jz4725b_mmc1_groups[] = { "mmc1-1bit", "mmc1-4bit", }; static const char *jz4725b_uart_groups[] = { "uart-data", }; +static const char *jz4725b_lcd_groups[] = { + "lcd-8bit", "lcd-16bit", "lcd-18bit", "lcd-24bit", + "lcd-special", "lcd-generic", +}; static const char *jz4725b_nand_groups[] = { "nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4", "nand-cle-ale", "nand-fre-fwe", @@ -291,10 +295,6 @@ static const char *jz4725b_pwm2_groups[] = { "pwm2", }; static const char *jz4725b_pwm3_groups[] = { "pwm3", }; static const char *jz4725b_pwm4_groups[] = { "pwm4", }; static const char *jz4725b_pwm5_groups[] = { "pwm5", }; -static const char *jz4725b_lcd_groups[] = { - "lcd-8bit", "lcd-16bit", "lcd-18bit", "lcd-24bit", - "lcd-special", "lcd-generic", -}; static const struct function_desc jz4725b_functions[] = { { "mmc0", jz4725b_mmc0_groups, ARRAY_SIZE(jz4725b_mmc0_groups), }, @@ -389,7 +389,7 @@ static int jz4760_lcd_18bit_pins[] = { static int jz4760_lcd_24bit_pins[] = { 0x40, 0x41, 0x4a, 0x4b, 0x54, 0x55, }; -static int jz4760_lcd_special_pins[] = { 0x40, 0x41, 0x4a, 0x54 }; +static int jz4760_lcd_special_pins[] = { 0x54, 0x4a, 0x41, 0x40, }; static int jz4760_lcd_generic_pins[] = { 0x49, }; static int jz4760_pwm_pwm0_pins[] = { 0x80, }; static int jz4760_pwm_pwm1_pins[] = { 0x81, }; @@ -450,8 +450,8 @@ static const struct group_desc jz4760_groups[] = { INGENIC_PIN_GROUP("lcd-16bit", jz4760_lcd_16bit, 0), INGENIC_PIN_GROUP("lcd-18bit", jz4760_lcd_18bit, 0), INGENIC_PIN_GROUP("lcd-24bit", jz4760_lcd_24bit, 0), - INGENIC_PIN_GROUP("lcd-generic", jz4760_lcd_generic, 0), INGENIC_PIN_GROUP("lcd-special", jz4760_lcd_special, 1), + INGENIC_PIN_GROUP("lcd-generic", jz4760_lcd_generic, 0), INGENIC_PIN_GROUP("pwm0", jz4760_pwm_pwm0, 0), INGENIC_PIN_GROUP("pwm1", jz4760_pwm_pwm1, 0), INGENIC_PIN_GROUP("pwm2", jz4760_pwm_pwm2, 0), @@ -648,7 +648,13 @@ static int jz4770_cim_12bit_pins[] = { }; static int jz4770_lcd_8bit_pins[] = { 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x4c, 0x4d, - 0x48, 0x49, 0x52, 0x53, + 0x48, 0x52, 0x53, +}; +static int jz4770_lcd_16bit_pins[] = { + 0x4e, 0x4f, 0x50, 0x51, 0x56, 0x57, 0x58, 0x59, +}; +static int jz4770_lcd_18bit_pins[] = { + 0x5a, 0x5b, }; static int jz4770_lcd_24bit_pins[] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, @@ -656,6 +662,8 @@ static int jz4770_lcd_24bit_pins[] = { 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, }; +static int jz4770_lcd_special_pins[] = { 0x54, 0x4a, 0x41, 0x40, }; +static int jz4770_lcd_generic_pins[] = { 0x49, }; static int jz4770_pwm_pwm0_pins[] = { 0x80, }; static int jz4770_pwm_pwm1_pins[] = { 0x81, }; static int jz4770_pwm_pwm2_pins[] = { 0x82, }; @@ -756,8 +764,11 @@ static const struct group_desc jz4770_groups[] = { INGENIC_PIN_GROUP("cim-data-8bit", jz4770_cim_8bit, 0), INGENIC_PIN_GROUP("cim-data-12bit", jz4770_cim_12bit, 0), INGENIC_PIN_GROUP("lcd-8bit", jz4770_lcd_8bit, 0), + INGENIC_PIN_GROUP("lcd-16bit", jz4770_lcd_16bit, 0), + INGENIC_PIN_GROUP("lcd-18bit", jz4770_lcd_18bit, 0), INGENIC_PIN_GROUP("lcd-24bit", jz4770_lcd_24bit, 0), - { "lcd-no-pins", }, + INGENIC_PIN_GROUP("lcd-special", jz4770_lcd_special, 1), + INGENIC_PIN_GROUP("lcd-generic", jz4770_lcd_generic, 0), INGENIC_PIN_GROUP("pwm0", jz4770_pwm_pwm0, 0), INGENIC_PIN_GROUP("pwm1", jz4770_pwm_pwm1, 0), INGENIC_PIN_GROUP("pwm2", jz4770_pwm_pwm2, 0), @@ -818,7 +829,8 @@ static const char *jz4770_i2c1_groups[] = { "i2c1-data", }; static const char *jz4770_i2c2_groups[] = { "i2c2-data", }; static const char *jz4770_cim_groups[] = { "cim-data-8bit", "cim-data-12bit", }; static const char *jz4770_lcd_groups[] = { - "lcd-8bit", "lcd-24bit", "lcd-no-pins", + "lcd-8bit", "lcd-16bit", "lcd-18bit", "lcd-24bit", + "lcd-special", "lcd-generic", }; static const char *jz4770_pwm0_groups[] = { "pwm0", }; static const char *jz4770_pwm1_groups[] = { "pwm1", }; @@ -1030,8 +1042,12 @@ static const struct group_desc jz4780_groups[] = { INGENIC_PIN_GROUP("hdmi-ddc", jz4780_hdmi_ddc, 0), INGENIC_PIN_GROUP("cim-data", jz4770_cim_8bit, 0), INGENIC_PIN_GROUP("cim-data-12bit", jz4770_cim_12bit, 0), + INGENIC_PIN_GROUP("lcd-8bit", jz4770_lcd_8bit, 0), + INGENIC_PIN_GROUP("lcd-16bit", jz4770_lcd_16bit, 0), + INGENIC_PIN_GROUP("lcd-18bit", jz4770_lcd_18bit, 0), INGENIC_PIN_GROUP("lcd-24bit", jz4770_lcd_24bit, 0), - { "lcd-no-pins", }, + INGENIC_PIN_GROUP("lcd-special", jz4770_lcd_special, 1), + INGENIC_PIN_GROUP("lcd-generic", jz4770_lcd_generic, 0), INGENIC_PIN_GROUP("pwm0", jz4770_pwm_pwm0, 0), INGENIC_PIN_GROUP("pwm1", jz4770_pwm_pwm1, 0), INGENIC_PIN_GROUP("pwm2", jz4770_pwm_pwm2, 0), @@ -1259,7 +1275,6 @@ static const struct group_desc x1000_groups[] = { INGENIC_PIN_GROUP("cim-data", x1000_cim, 2), INGENIC_PIN_GROUP("lcd-8bit", x1000_lcd_8bit, 1), INGENIC_PIN_GROUP("lcd-16bit", x1000_lcd_16bit, 1), - { "lcd-no-pins", }, INGENIC_PIN_GROUP("pwm0", x1000_pwm_pwm0, 0), INGENIC_PIN_GROUP("pwm1", x1000_pwm_pwm1, 1), INGENIC_PIN_GROUP("pwm2", x1000_pwm_pwm2, 1), @@ -1301,9 +1316,7 @@ static const char *x1000_i2s_groups[] = { "i2s-data-tx", "i2s-data-rx", "i2s-clk-txrx", "i2s-sysclk", }; static const char *x1000_cim_groups[] = { "cim-data", }; -static const char *x1000_lcd_groups[] = { - "lcd-8bit", "lcd-16bit", "lcd-no-pins", -}; +static const char *x1000_lcd_groups[] = { "lcd-8bit", "lcd-16bit", }; static const char *x1000_pwm0_groups[] = { "pwm0", }; static const char *x1000_pwm1_groups[] = { "pwm1", }; static const char *x1000_pwm2_groups[] = { "pwm2", }; @@ -1395,7 +1408,6 @@ static const struct group_desc x1500_groups[] = { INGENIC_PIN_GROUP("i2s-clk-txrx", x1500_i2s_clk_txrx, 1), INGENIC_PIN_GROUP("i2s-sysclk", x1500_i2s_sysclk, 1), INGENIC_PIN_GROUP("cim-data", x1500_cim, 2), - { "lcd-no-pins", }, INGENIC_PIN_GROUP("pwm0", x1500_pwm_pwm0, 0), INGENIC_PIN_GROUP("pwm1", x1500_pwm_pwm1, 1), INGENIC_PIN_GROUP("pwm2", x1500_pwm_pwm2, 1), @@ -1416,7 +1428,6 @@ static const char *x1500_i2s_groups[] = { "i2s-data-tx", "i2s-data-rx", "i2s-clk-txrx", "i2s-sysclk", }; static const char *x1500_cim_groups[] = { "cim-data", }; -static const char *x1500_lcd_groups[] = { "lcd-no-pins", }; static const char *x1500_pwm0_groups[] = { "pwm0", }; static const char *x1500_pwm1_groups[] = { "pwm1", }; static const char *x1500_pwm2_groups[] = { "pwm2", }; @@ -1434,7 +1445,6 @@ static const struct function_desc x1500_functions[] = { { "i2c2", x1500_i2c2_groups, ARRAY_SIZE(x1500_i2c2_groups), }, { "i2s", x1500_i2s_groups, ARRAY_SIZE(x1500_i2s_groups), }, { "cim", x1500_cim_groups, ARRAY_SIZE(x1500_cim_groups), }, - { "lcd", x1500_lcd_groups, ARRAY_SIZE(x1500_lcd_groups), }, { "pwm0", x1500_pwm0_groups, ARRAY_SIZE(x1500_pwm0_groups), }, { "pwm1", x1500_pwm1_groups, ARRAY_SIZE(x1500_pwm1_groups), }, { "pwm2", x1500_pwm2_groups, ARRAY_SIZE(x1500_pwm2_groups), }, @@ -1496,11 +1506,13 @@ static int x1830_i2s_data_rx_pins[] = { 0x54, }; static int x1830_i2s_clk_txrx_pins[] = { 0x58, 0x52, }; static int x1830_i2s_clk_rx_pins[] = { 0x56, 0x55, }; static int x1830_i2s_sysclk_pins[] = { 0x57, }; -static int x1830_lcd_rgb_18bit_pins[] = { +static int x1830_lcd_tft_8bit_pins[] = { 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, + 0x68, 0x73, 0x72, 0x69, +}; +static int x1830_lcd_tft_24bit_pins[] = { + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, + 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, }; static int x1830_lcd_slcd_8bit_pins[] = { 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x6c, 0x6d, @@ -1564,10 +1576,10 @@ static const struct group_desc x1830_groups[] = { INGENIC_PIN_GROUP("i2s-clk-txrx", x1830_i2s_clk_txrx, 0), INGENIC_PIN_GROUP("i2s-clk-rx", x1830_i2s_clk_rx, 0), INGENIC_PIN_GROUP("i2s-sysclk", x1830_i2s_sysclk, 0), - INGENIC_PIN_GROUP("lcd-rgb-18bit", x1830_lcd_rgb_18bit, 0), + INGENIC_PIN_GROUP("lcd-tft-8bit", x1830_lcd_tft_8bit, 0), + INGENIC_PIN_GROUP("lcd-tft-24bit", x1830_lcd_tft_24bit, 0), INGENIC_PIN_GROUP("lcd-slcd-8bit", x1830_lcd_slcd_8bit, 1), INGENIC_PIN_GROUP("lcd-slcd-16bit", x1830_lcd_slcd_16bit, 1), - { "lcd-no-pins", }, INGENIC_PIN_GROUP("pwm0-b", x1830_pwm_pwm0_b, 0), INGENIC_PIN_GROUP("pwm0-c", x1830_pwm_pwm0_c, 1), INGENIC_PIN_GROUP("pwm1-b", x1830_pwm_pwm1_b, 0), @@ -1610,7 +1622,7 @@ static const char *x1830_i2s_groups[] = { "i2s-data-tx", "i2s-data-rx", "i2s-clk-txrx", "i2s-clk-rx", "i2s-sysclk", }; static const char *x1830_lcd_groups[] = { - "lcd-rgb-18bit", "lcd-slcd-8bit", "lcd-slcd-16bit", "lcd-no-pins", + "lcd-tft-8bit", "lcd-tft-24bit", "lcd-slcd-8bit", "lcd-slcd-16bit", }; static const char *x1830_pwm0_groups[] = { "pwm0-b", "pwm0-c", }; static const char *x1830_pwm1_groups[] = { "pwm1-b", "pwm1-c", }; -- cgit v1.2.3 From 6adf2c5607377d22831af009241fc0a6e62d4077 Mon Sep 17 00:00:00 2001 From: "周琰杰 (Zhou Yanjie)" Date: Sun, 18 Apr 2021 22:44:26 +0800 Subject: pinctrl: Ingenic: Add DMIC pins support for Ingenic SoCs. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.Add DMIC pins support for the JZ4780 SoC. 2.Add DMIC pins support for the X1000 SoC. 3.Add DMIC pins support for the X1500 SoC. 4.Add DMIC pins support for the X1830 SoC. Signed-off-by: 周琰杰 (Zhou Yanjie) Reviewed-by: Paul Cercueil Link: https://lore.kernel.org/r/1618757073-1724-6-git-send-email-zhouyanjie@wanyeetech.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 7114b78da41f..20833d7d26ed 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -941,6 +941,7 @@ static int jz4780_i2s_data_rx_pins[] = { 0x86, }; static int jz4780_i2s_clk_txrx_pins[] = { 0x6c, 0x6d, }; static int jz4780_i2s_clk_rx_pins[] = { 0x88, 0x89, }; static int jz4780_i2s_sysclk_pins[] = { 0x85, }; +static int jz4780_dmic_pins[] = { 0x32, 0x33, }; static int jz4780_hdmi_ddc_pins[] = { 0xb9, 0xb8, }; static u8 jz4780_i2s_clk_txrx_funcs[] = { 1, 0, }; @@ -1039,6 +1040,7 @@ static const struct group_desc jz4780_groups[] = { jz4780_i2s_clk_txrx_funcs), INGENIC_PIN_GROUP("i2s-clk-rx", jz4780_i2s_clk_rx, 1), INGENIC_PIN_GROUP("i2s-sysclk", jz4780_i2s_sysclk, 2), + INGENIC_PIN_GROUP("dmic", jz4780_dmic, 1), INGENIC_PIN_GROUP("hdmi-ddc", jz4780_hdmi_ddc, 0), INGENIC_PIN_GROUP("cim-data", jz4770_cim_8bit, 0), INGENIC_PIN_GROUP("cim-data-12bit", jz4770_cim_12bit, 0), @@ -1095,6 +1097,7 @@ static const char *jz4780_i2c4_groups[] = { "i2c4-data-e", "i2c4-data-f", }; static const char *jz4780_i2s_groups[] = { "i2s-data-tx", "i2s-data-rx", "i2s-clk-txrx", "i2s-clk-rx", "i2s-sysclk", }; +static const char *jz4780_dmic_groups[] = { "dmic", }; static const char *jz4780_cim_groups[] = { "cim-data", }; static const char *jz4780_hdmi_ddc_groups[] = { "hdmi-ddc", }; @@ -1122,6 +1125,7 @@ static const struct function_desc jz4780_functions[] = { { "i2c3", jz4780_i2c3_groups, ARRAY_SIZE(jz4780_i2c3_groups), }, { "i2c4", jz4780_i2c4_groups, ARRAY_SIZE(jz4780_i2c4_groups), }, { "i2s", jz4780_i2s_groups, ARRAY_SIZE(jz4780_i2s_groups), }, + { "dmic", jz4780_dmic_groups, ARRAY_SIZE(jz4780_dmic_groups), }, { "cim", jz4780_cim_groups, ARRAY_SIZE(jz4780_cim_groups), }, { "lcd", jz4770_lcd_groups, ARRAY_SIZE(jz4770_lcd_groups), }, { "pwm0", jz4770_pwm0_groups, ARRAY_SIZE(jz4770_pwm0_groups), }, @@ -1207,6 +1211,8 @@ static int x1000_i2s_data_tx_pins[] = { 0x24, }; static int x1000_i2s_data_rx_pins[] = { 0x23, }; static int x1000_i2s_clk_txrx_pins[] = { 0x21, 0x22, }; static int x1000_i2s_sysclk_pins[] = { 0x20, }; +static int x1000_dmic0_pins[] = { 0x35, 0x36, }; +static int x1000_dmic1_pins[] = { 0x25, }; static int x1000_cim_pins[] = { 0x08, 0x09, 0x0a, 0x0b, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0c, @@ -1272,6 +1278,8 @@ static const struct group_desc x1000_groups[] = { INGENIC_PIN_GROUP("i2s-data-rx", x1000_i2s_data_rx, 1), INGENIC_PIN_GROUP("i2s-clk-txrx", x1000_i2s_clk_txrx, 1), INGENIC_PIN_GROUP("i2s-sysclk", x1000_i2s_sysclk, 1), + INGENIC_PIN_GROUP("dmic0", x1000_dmic0, 0), + INGENIC_PIN_GROUP("dmic1", x1000_dmic1, 1), INGENIC_PIN_GROUP("cim-data", x1000_cim, 2), INGENIC_PIN_GROUP("lcd-8bit", x1000_lcd_8bit, 1), INGENIC_PIN_GROUP("lcd-16bit", x1000_lcd_16bit, 1), @@ -1315,6 +1323,7 @@ static const char *x1000_i2c2_groups[] = { "i2c2-data", }; static const char *x1000_i2s_groups[] = { "i2s-data-tx", "i2s-data-rx", "i2s-clk-txrx", "i2s-sysclk", }; +static const char *x1000_dmic_groups[] = { "dmic0", "dmic1", }; static const char *x1000_cim_groups[] = { "cim-data", }; static const char *x1000_lcd_groups[] = { "lcd-8bit", "lcd-16bit", }; static const char *x1000_pwm0_groups[] = { "pwm0", }; @@ -1339,6 +1348,7 @@ static const struct function_desc x1000_functions[] = { { "i2c1", x1000_i2c1_groups, ARRAY_SIZE(x1000_i2c1_groups), }, { "i2c2", x1000_i2c2_groups, ARRAY_SIZE(x1000_i2c2_groups), }, { "i2s", x1000_i2s_groups, ARRAY_SIZE(x1000_i2s_groups), }, + { "dmic", x1000_dmic_groups, ARRAY_SIZE(x1000_dmic_groups), }, { "cim", x1000_cim_groups, ARRAY_SIZE(x1000_cim_groups), }, { "lcd", x1000_lcd_groups, ARRAY_SIZE(x1000_lcd_groups), }, { "pwm0", x1000_pwm0_groups, ARRAY_SIZE(x1000_pwm0_groups), }, @@ -1378,6 +1388,8 @@ static int x1500_i2s_data_tx_pins[] = { 0x24, }; static int x1500_i2s_data_rx_pins[] = { 0x23, }; static int x1500_i2s_clk_txrx_pins[] = { 0x21, 0x22, }; static int x1500_i2s_sysclk_pins[] = { 0x20, }; +static int x1500_dmic0_pins[] = { 0x35, 0x36, }; +static int x1500_dmic1_pins[] = { 0x25, }; static int x1500_cim_pins[] = { 0x08, 0x09, 0x0a, 0x0b, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0c, @@ -1407,6 +1419,8 @@ static const struct group_desc x1500_groups[] = { INGENIC_PIN_GROUP("i2s-data-rx", x1500_i2s_data_rx, 1), INGENIC_PIN_GROUP("i2s-clk-txrx", x1500_i2s_clk_txrx, 1), INGENIC_PIN_GROUP("i2s-sysclk", x1500_i2s_sysclk, 1), + INGENIC_PIN_GROUP("dmic0", x1500_dmic0, 0), + INGENIC_PIN_GROUP("dmic1", x1500_dmic1, 1), INGENIC_PIN_GROUP("cim-data", x1500_cim, 2), INGENIC_PIN_GROUP("pwm0", x1500_pwm_pwm0, 0), INGENIC_PIN_GROUP("pwm1", x1500_pwm_pwm1, 1), @@ -1427,6 +1441,7 @@ static const char *x1500_i2c2_groups[] = { "i2c2-data", }; static const char *x1500_i2s_groups[] = { "i2s-data-tx", "i2s-data-rx", "i2s-clk-txrx", "i2s-sysclk", }; +static const char *x1500_dmic_groups[] = { "dmic0", "dmic1", }; static const char *x1500_cim_groups[] = { "cim-data", }; static const char *x1500_pwm0_groups[] = { "pwm0", }; static const char *x1500_pwm1_groups[] = { "pwm1", }; @@ -1444,6 +1459,7 @@ static const struct function_desc x1500_functions[] = { { "i2c1", x1500_i2c1_groups, ARRAY_SIZE(x1500_i2c1_groups), }, { "i2c2", x1500_i2c2_groups, ARRAY_SIZE(x1500_i2c2_groups), }, { "i2s", x1500_i2s_groups, ARRAY_SIZE(x1500_i2s_groups), }, + { "dmic", x1500_dmic_groups, ARRAY_SIZE(x1500_dmic_groups), }, { "cim", x1500_cim_groups, ARRAY_SIZE(x1500_cim_groups), }, { "pwm0", x1500_pwm0_groups, ARRAY_SIZE(x1500_pwm0_groups), }, { "pwm1", x1500_pwm1_groups, ARRAY_SIZE(x1500_pwm1_groups), }, @@ -1506,6 +1522,8 @@ static int x1830_i2s_data_rx_pins[] = { 0x54, }; static int x1830_i2s_clk_txrx_pins[] = { 0x58, 0x52, }; static int x1830_i2s_clk_rx_pins[] = { 0x56, 0x55, }; static int x1830_i2s_sysclk_pins[] = { 0x57, }; +static int x1830_dmic0_pins[] = { 0x48, 0x59, }; +static int x1830_dmic1_pins[] = { 0x5a, }; static int x1830_lcd_tft_8bit_pins[] = { 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x73, 0x72, 0x69, @@ -1576,6 +1594,8 @@ static const struct group_desc x1830_groups[] = { INGENIC_PIN_GROUP("i2s-clk-txrx", x1830_i2s_clk_txrx, 0), INGENIC_PIN_GROUP("i2s-clk-rx", x1830_i2s_clk_rx, 0), INGENIC_PIN_GROUP("i2s-sysclk", x1830_i2s_sysclk, 0), + INGENIC_PIN_GROUP("dmic0", x1830_dmic0, 2), + INGENIC_PIN_GROUP("dmic1", x1830_dmic1, 2), INGENIC_PIN_GROUP("lcd-tft-8bit", x1830_lcd_tft_8bit, 0), INGENIC_PIN_GROUP("lcd-tft-24bit", x1830_lcd_tft_24bit, 0), INGENIC_PIN_GROUP("lcd-slcd-8bit", x1830_lcd_slcd_8bit, 1), @@ -1621,6 +1641,7 @@ static const char *x1830_i2c2_groups[] = { "i2c2-data", }; static const char *x1830_i2s_groups[] = { "i2s-data-tx", "i2s-data-rx", "i2s-clk-txrx", "i2s-clk-rx", "i2s-sysclk", }; +static const char *x1830_dmic_groups[] = { "dmic0", "dmic1", }; static const char *x1830_lcd_groups[] = { "lcd-tft-8bit", "lcd-tft-24bit", "lcd-slcd-8bit", "lcd-slcd-16bit", }; @@ -1646,6 +1667,7 @@ static const struct function_desc x1830_functions[] = { { "i2c1", x1830_i2c1_groups, ARRAY_SIZE(x1830_i2c1_groups), }, { "i2c2", x1830_i2c2_groups, ARRAY_SIZE(x1830_i2c2_groups), }, { "i2s", x1830_i2s_groups, ARRAY_SIZE(x1830_i2s_groups), }, + { "dmic", x1830_dmic_groups, ARRAY_SIZE(x1830_dmic_groups), }, { "lcd", x1830_lcd_groups, ARRAY_SIZE(x1830_lcd_groups), }, { "pwm0", x1830_pwm0_groups, ARRAY_SIZE(x1830_pwm0_groups), }, { "pwm1", x1830_pwm1_groups, ARRAY_SIZE(x1830_pwm1_groups), }, -- cgit v1.2.3 From 863becff89b291ca6772626ea4312db6955126b8 Mon Sep 17 00:00:00 2001 From: "周琰杰 (Zhou Yanjie)" Date: Sun, 18 Apr 2021 22:44:27 +0800 Subject: pinctrl: Ingenic: Reformat the code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.Move the "INGENIC_PIN_GROUP_FUNCS" to the macro definition section. 2.Add tabs before values to align the code in the macro definition section. Signed-off-by: 周琰杰 (Zhou Yanjie) Reviewed-by: Andy Shevchenko Reviewed-by: Paul Cercueil Link: https://lore.kernel.org/r/1618757073-1724-7-git-send-email-zhouyanjie@wanyeetech.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 71 +++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 20833d7d26ed..4df6ba4de97e 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -26,37 +26,48 @@ #include "pinconf.h" #include "pinmux.h" -#define GPIO_PIN 0x00 -#define GPIO_MSK 0x20 +#define GPIO_PIN 0x00 +#define GPIO_MSK 0x20 -#define JZ4740_GPIO_DATA 0x10 -#define JZ4740_GPIO_PULL_DIS 0x30 -#define JZ4740_GPIO_FUNC 0x40 -#define JZ4740_GPIO_SELECT 0x50 -#define JZ4740_GPIO_DIR 0x60 -#define JZ4740_GPIO_TRIG 0x70 -#define JZ4740_GPIO_FLAG 0x80 +#define JZ4740_GPIO_DATA 0x10 +#define JZ4740_GPIO_PULL_DIS 0x30 +#define JZ4740_GPIO_FUNC 0x40 +#define JZ4740_GPIO_SELECT 0x50 +#define JZ4740_GPIO_DIR 0x60 +#define JZ4740_GPIO_TRIG 0x70 +#define JZ4740_GPIO_FLAG 0x80 -#define JZ4770_GPIO_INT 0x10 -#define JZ4770_GPIO_PAT1 0x30 -#define JZ4770_GPIO_PAT0 0x40 -#define JZ4770_GPIO_FLAG 0x50 -#define JZ4770_GPIO_PEN 0x70 +#define JZ4770_GPIO_INT 0x10 +#define JZ4770_GPIO_PAT1 0x30 +#define JZ4770_GPIO_PAT0 0x40 +#define JZ4770_GPIO_FLAG 0x50 +#define JZ4770_GPIO_PEN 0x70 -#define X1830_GPIO_PEL 0x110 -#define X1830_GPIO_PEH 0x120 +#define X1830_GPIO_PEL 0x110 +#define X1830_GPIO_PEH 0x120 -#define REG_SET(x) ((x) + 0x4) -#define REG_CLEAR(x) ((x) + 0x8) +#define REG_SET(x) ((x) + 0x4) +#define REG_CLEAR(x) ((x) + 0x8) -#define REG_PZ_BASE(x) ((x) * 7) -#define REG_PZ_GID2LD(x) ((x) * 7 + 0xf0) +#define REG_PZ_BASE(x) ((x) * 7) +#define REG_PZ_GID2LD(x) ((x) * 7 + 0xf0) -#define GPIO_PULL_DIS 0 -#define GPIO_PULL_UP 1 -#define GPIO_PULL_DOWN 2 +#define GPIO_PULL_DIS 0 +#define GPIO_PULL_UP 1 +#define GPIO_PULL_DOWN 2 -#define PINS_PER_GPIO_CHIP 32 +#define PINS_PER_GPIO_CHIP 32 + +#define INGENIC_PIN_GROUP_FUNCS(name, id, funcs) \ + { \ + name, \ + id##_pins, \ + ARRAY_SIZE(id##_pins), \ + funcs, \ + } + +#define INGENIC_PIN_GROUP(name, id, func) \ + INGENIC_PIN_GROUP_FUNCS(name, id, (void *)(func)) enum jz_version { ID_JZ4740, @@ -136,18 +147,6 @@ static int jz4740_pwm_pwm5_pins[] = { 0x7c, }; static int jz4740_pwm_pwm6_pins[] = { 0x7e, }; static int jz4740_pwm_pwm7_pins[] = { 0x7f, }; - -#define INGENIC_PIN_GROUP_FUNCS(name, id, funcs) \ - { \ - name, \ - id##_pins, \ - ARRAY_SIZE(id##_pins), \ - funcs, \ - } - -#define INGENIC_PIN_GROUP(name, id, func) \ - INGENIC_PIN_GROUP_FUNCS(name, id, (void *)(func)) - static const struct group_desc jz4740_groups[] = { INGENIC_PIN_GROUP("mmc-1bit", jz4740_mmc_1bit, 0), INGENIC_PIN_GROUP("mmc-4bit", jz4740_mmc_4bit, 0), -- cgit v1.2.3 From beadd1b4b48236d49f4b32f0c1dfcc27671f65c2 Mon Sep 17 00:00:00 2001 From: "周琰杰 (Zhou Yanjie)" Date: Sun, 18 Apr 2021 22:44:28 +0800 Subject: dt-bindings: pinctrl: Add bindings for new Ingenic SoCs. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the pinctrl bindings for the JZ4730 SoC, the JZ4750 SoC, the JZ4755 SoC, the JZ4775 SoC and the X2000 SoC from Ingenic. Signed-off-by: 周琰杰 (Zhou Yanjie) Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/1618757073-1724-8-git-send-email-zhouyanjie@wanyeetech.com Signed-off-by: Linus Walleij --- .../bindings/pinctrl/ingenic,pinctrl.yaml | 23 ++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml index 44c04d11ae4c..a4846d78111c 100644 --- a/Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml @@ -17,10 +17,12 @@ description: > naming scheme "PxN" where x is a character identifying the GPIO port with which the pin is associated and N is an integer from 0 to 31 identifying the pin within that GPIO port. For example PA0 is the first pin in GPIO port A, - and PB31 is the last pin in GPIO port B. The JZ4740, the X1000 and the X1830 - contains 4 GPIO ports, PA to PD, for a total of 128 pins. The JZ4760, the - JZ4770 and the JZ4780 contains 6 GPIO ports, PA to PF, for a total of 192 - pins. + and PB31 is the last pin in GPIO port B. The JZ4730, the JZ4740, the JZ4725B, + the X1000 and the X1830 contains 4 GPIO ports, PA to PD, for a total of 128 + pins. The X2000 contains 5 GPIO ports, PA to PE, for a total of 160 pins. + The JZ4750, the JZ4755 the JZ4760, the JZ4770 and the JZ4780 contains 6 GPIO + ports, PA to PF, for a total of 192 pins. The JZ4775 contains 7 GPIO ports, + PA to PG, for a total of 224 pins. maintainers: - Paul Cercueil @@ -32,20 +34,28 @@ properties: compatible: oneOf: - enum: + - ingenic,jz4730-pinctrl - ingenic,jz4740-pinctrl - ingenic,jz4725b-pinctrl + - ingenic,jz4750-pinctrl + - ingenic,jz4755-pinctrl - ingenic,jz4760-pinctrl - ingenic,jz4770-pinctrl + - ingenic,jz4775-pinctrl - ingenic,jz4780-pinctrl - ingenic,x1000-pinctrl - ingenic,x1500-pinctrl - ingenic,x1830-pinctrl + - ingenic,x2000-pinctrl - items: - const: ingenic,jz4760b-pinctrl - const: ingenic,jz4760-pinctrl - items: - const: ingenic,x1000e-pinctrl - const: ingenic,x1000-pinctrl + - items: + - const: ingenic,x2000e-pinctrl + - const: ingenic,x2000-pinctrl reg: maxItems: 1 @@ -62,14 +72,19 @@ patternProperties: properties: compatible: enum: + - ingenic,jz4730-gpio - ingenic,jz4740-gpio - ingenic,jz4725b-gpio + - ingenic,jz4750-gpio + - ingenic,jz4755-gpio - ingenic,jz4760-gpio - ingenic,jz4770-gpio + - ingenic,jz4775-gpio - ingenic,jz4780-gpio - ingenic,x1000-gpio - ingenic,x1500-gpio - ingenic,x1830-gpio + - ingenic,x2000-gpio reg: items: -- cgit v1.2.3 From 424f39691f2d6f69fdad9904c958880f4ebd3ece Mon Sep 17 00:00:00 2001 From: "周琰杰 (Zhou Yanjie)" Date: Sun, 18 Apr 2021 22:44:29 +0800 Subject: pinctrl: Ingenic: Add pinctrl driver for JZ4730. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for probing the pinctrl-ingenic driver on the JZ4730 SoC from Ingenic. This driver is derived from Paul Boddie. It is worth to noting that the JZ4730 SoC is special in having two control registers (upper/lower), so add code to handle the JZ4730 specific register offsets and some register pairs which have 2 bits for each GPIO pin. Tested-by: H. Nikolaus Schaller # on Letux400 Co-developed-by: Paul Boddie Signed-off-by: Paul Boddie Signed-off-by: H. Nikolaus Schaller Signed-off-by: 周琰杰 (Zhou Yanjie) Reviewed-by: Andy Shevchenko Reviewed-by: Paul Cercueil Link: https://lore.kernel.org/r/1618757073-1724-9-git-send-email-zhouyanjie@wanyeetech.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 232 +++++++++++++++++++++++++++++++++++--- 1 file changed, 216 insertions(+), 16 deletions(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 4df6ba4de97e..24cc803fd450 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -3,8 +3,8 @@ * Ingenic SoCs pinctrl driver * * Copyright (c) 2017 Paul Cercueil - * Copyright (c) 2019 周琰杰 (Zhou Yanjie) * Copyright (c) 2017, 2019 Paul Boddie + * Copyright (c) 2019, 2020 周琰杰 (Zhou Yanjie) */ #include @@ -29,6 +29,17 @@ #define GPIO_PIN 0x00 #define GPIO_MSK 0x20 +#define JZ4730_GPIO_DATA 0x00 +#define JZ4730_GPIO_GPDIR 0x04 +#define JZ4730_GPIO_GPPUR 0x0c +#define JZ4730_GPIO_GPALR 0x10 +#define JZ4730_GPIO_GPAUR 0x14 +#define JZ4730_GPIO_GPIDLR 0x18 +#define JZ4730_GPIO_GPIDUR 0x1c +#define JZ4730_GPIO_GPIER 0x20 +#define JZ4730_GPIO_GPIMR 0x24 +#define JZ4730_GPIO_GPFR 0x28 + #define JZ4740_GPIO_DATA 0x10 #define JZ4740_GPIO_PULL_DIS 0x30 #define JZ4740_GPIO_FUNC 0x40 @@ -57,6 +68,7 @@ #define GPIO_PULL_DOWN 2 #define PINS_PER_GPIO_CHIP 32 +#define JZ4730_PINS_PER_PAIRED_REG 16 #define INGENIC_PIN_GROUP_FUNCS(name, id, funcs) \ { \ @@ -70,6 +82,7 @@ INGENIC_PIN_GROUP_FUNCS(name, id, (void *)(func)) enum jz_version { + ID_JZ4730, ID_JZ4740, ID_JZ4725B, ID_JZ4760, @@ -110,6 +123,99 @@ struct ingenic_gpio_chip { unsigned int irq, reg_base; }; +static const u32 jz4730_pull_ups[4] = { + 0x3fa3320f, 0xf200ffff, 0xffffffff, 0xffffffff, +}; + +static const u32 jz4730_pull_downs[4] = { + 0x00000df0, 0x0dff0000, 0x00000000, 0x00000000, +}; + +static int jz4730_mmc_1bit_pins[] = { 0x27, 0x26, 0x22, }; +static int jz4730_mmc_4bit_pins[] = { 0x23, 0x24, 0x25, }; +static int jz4730_uart0_data_pins[] = { 0x7e, 0x7f, }; +static int jz4730_uart1_data_pins[] = { 0x18, 0x19, }; +static int jz4730_uart2_data_pins[] = { 0x6f, 0x7d, }; +static int jz4730_uart3_data_pins[] = { 0x10, 0x15, }; +static int jz4730_uart3_hwflow_pins[] = { 0x11, 0x17, }; +static int jz4730_lcd_8bit_pins[] = { + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x3a, 0x39, 0x38, +}; +static int jz4730_lcd_16bit_pins[] = { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +}; +static int jz4730_lcd_special_pins[] = { 0x3d, 0x3c, 0x3e, 0x3f, }; +static int jz4730_lcd_generic_pins[] = { 0x3b, }; +static int jz4730_nand_cs1_pins[] = { 0x53, }; +static int jz4730_nand_cs2_pins[] = { 0x54, }; +static int jz4730_nand_cs3_pins[] = { 0x55, }; +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 u8 jz4730_lcd_8bit_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, }; + +static const struct group_desc jz4730_groups[] = { + INGENIC_PIN_GROUP("mmc-1bit", jz4730_mmc_1bit, 1), + INGENIC_PIN_GROUP("mmc-4bit", jz4730_mmc_4bit, 1), + INGENIC_PIN_GROUP("uart0-data", jz4730_uart0_data, 1), + INGENIC_PIN_GROUP("uart1-data", jz4730_uart1_data, 1), + INGENIC_PIN_GROUP("uart2-data", jz4730_uart2_data, 1), + INGENIC_PIN_GROUP("uart3-data", jz4730_uart3_data, 1), + INGENIC_PIN_GROUP("uart3-hwflow", jz4730_uart3_hwflow, 1), + INGENIC_PIN_GROUP_FUNCS("lcd-8bit", jz4730_lcd_8bit, jz4730_lcd_8bit_funcs), + INGENIC_PIN_GROUP("lcd-16bit", jz4730_lcd_16bit, 1), + INGENIC_PIN_GROUP("lcd-special", jz4730_lcd_special, 1), + INGENIC_PIN_GROUP("lcd-generic", jz4730_lcd_generic, 1), + INGENIC_PIN_GROUP("nand-cs1", jz4730_nand_cs1, 1), + INGENIC_PIN_GROUP("nand-cs2", jz4730_nand_cs2, 1), + INGENIC_PIN_GROUP("nand-cs3", jz4730_nand_cs3, 1), + INGENIC_PIN_GROUP("nand-cs4", jz4730_nand_cs4, 1), + 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), +}; + +static const char *jz4730_mmc_groups[] = { "mmc-1bit", "mmc-4bit", }; +static const char *jz4730_uart0_groups[] = { "uart0-data", }; +static const char *jz4730_uart1_groups[] = { "uart1-data", }; +static const char *jz4730_uart2_groups[] = { "uart2-data", }; +static const char *jz4730_uart3_groups[] = { "uart3-data", "uart3-hwflow", }; +static const char *jz4730_lcd_groups[] = { + "lcd-8bit", "lcd-16bit", "lcd-special", "lcd-generic", +}; +static const char *jz4730_nand_groups[] = { + "nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4", "nand-cs5", +}; +static const char *jz4730_pwm0_groups[] = { "pwm0", }; +static const char *jz4730_pwm1_groups[] = { "pwm1", }; + +static const struct function_desc jz4730_functions[] = { + { "mmc", jz4730_mmc_groups, ARRAY_SIZE(jz4730_mmc_groups), }, + { "uart0", jz4730_uart0_groups, ARRAY_SIZE(jz4730_uart0_groups), }, + { "uart1", jz4730_uart1_groups, ARRAY_SIZE(jz4730_uart1_groups), }, + { "uart2", jz4730_uart2_groups, ARRAY_SIZE(jz4730_uart2_groups), }, + { "uart3", jz4730_uart3_groups, ARRAY_SIZE(jz4730_uart3_groups), }, + { "lcd", jz4730_lcd_groups, ARRAY_SIZE(jz4730_lcd_groups), }, + { "nand", jz4730_nand_groups, ARRAY_SIZE(jz4730_nand_groups), }, + { "pwm0", jz4730_pwm0_groups, ARRAY_SIZE(jz4730_pwm0_groups), }, + { "pwm1", jz4730_pwm1_groups, ARRAY_SIZE(jz4730_pwm1_groups), }, +}; + +static const struct ingenic_chip_info jz4730_chip_info = { + .num_chips = 4, + .reg_offset = 0x30, + .version = ID_JZ4730, + .groups = jz4730_groups, + .num_groups = ARRAY_SIZE(jz4730_groups), + .functions = jz4730_functions, + .num_functions = ARRAY_SIZE(jz4730_functions), + .pull_ups = jz4730_pull_ups, + .pull_downs = jz4730_pull_downs, +}; + static const u32 jz4740_pull_ups[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, }; @@ -1703,6 +1809,12 @@ static u32 ingenic_gpio_read_reg(struct ingenic_gpio_chip *jzgc, u8 reg) static void ingenic_gpio_set_bit(struct ingenic_gpio_chip *jzgc, u8 reg, u8 offset, bool set) { + if (jzgc->jzpc->info->version == ID_JZ4730) { + regmap_update_bits(jzgc->jzpc->map, jzgc->reg_base + reg, + BIT(offset), set ? BIT(offset) : 0); + return; + } + if (set) reg = REG_SET(reg); else @@ -1730,6 +1842,20 @@ static void ingenic_gpio_shadow_set_bit_load(struct ingenic_gpio_chip *jzgc) jzgc->gc.base / PINS_PER_GPIO_CHIP); } +static void jz4730_gpio_set_bits(struct ingenic_gpio_chip *jzgc, + u8 reg_upper, u8 reg_lower, u8 offset, u8 value) +{ + /* + * JZ4730 function and IRQ registers support two-bits-per-pin + * definitions, split into two groups of 16. + */ + u8 reg = offset < JZ4730_PINS_PER_PAIRED_REG ? reg_lower : reg_upper; + unsigned int idx = offset % JZ4730_PINS_PER_PAIRED_REG; + unsigned int mask = GENMASK(1, 0) << idx * 2; + + regmap_update_bits(jzgc->jzpc->map, jzgc->reg_base + reg, mask, value << (idx * 2)); +} + static inline bool ingenic_gpio_get_value(struct ingenic_gpio_chip *jzgc, u8 offset) { @@ -1743,8 +1869,10 @@ static void ingenic_gpio_set_value(struct ingenic_gpio_chip *jzgc, { if (jzgc->jzpc->info->version >= ID_JZ4770) ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_PAT0, offset, !!value); - else + else if (jzgc->jzpc->info->version >= ID_JZ4740) ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, offset, !!value); + else + ingenic_gpio_set_bit(jzgc, JZ4730_GPIO_DATA, offset, !!value); } static void irq_set_type(struct ingenic_gpio_chip *jzgc, @@ -1774,9 +1902,14 @@ static void irq_set_type(struct ingenic_gpio_chip *jzgc, if (jzgc->jzpc->info->version >= ID_JZ4770) { reg1 = JZ4770_GPIO_PAT1; reg2 = JZ4770_GPIO_PAT0; - } else { + } else if (jzgc->jzpc->info->version >= ID_JZ4740) { reg1 = JZ4740_GPIO_TRIG; reg2 = JZ4740_GPIO_DIR; + } else { + ingenic_gpio_set_bit(jzgc, JZ4730_GPIO_GPDIR, offset, false); + jz4730_gpio_set_bits(jzgc, JZ4730_GPIO_GPIDUR, + JZ4730_GPIO_GPIDLR, offset, (val2 << 1) | val1); + return; } if (jzgc->jzpc->info->version >= ID_X1000) { @@ -1793,16 +1926,24 @@ static void ingenic_gpio_irq_mask(struct irq_data *irqd) { struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc); + int irq = irqd->hwirq; - ingenic_gpio_set_bit(jzgc, GPIO_MSK, irqd->hwirq, true); + if (jzgc->jzpc->info->version >= ID_JZ4740) + ingenic_gpio_set_bit(jzgc, GPIO_MSK, irq, true); + else + ingenic_gpio_set_bit(jzgc, JZ4730_GPIO_GPIMR, irq, true); } static void ingenic_gpio_irq_unmask(struct irq_data *irqd) { struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc); + int irq = irqd->hwirq; - ingenic_gpio_set_bit(jzgc, GPIO_MSK, irqd->hwirq, false); + if (jzgc->jzpc->info->version >= ID_JZ4740) + ingenic_gpio_set_bit(jzgc, GPIO_MSK, irq, false); + else + ingenic_gpio_set_bit(jzgc, JZ4730_GPIO_GPIMR, irq, false); } static void ingenic_gpio_irq_enable(struct irq_data *irqd) @@ -1813,8 +1954,10 @@ static void ingenic_gpio_irq_enable(struct irq_data *irqd) if (jzgc->jzpc->info->version >= ID_JZ4770) ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_INT, irq, true); - else + else if (jzgc->jzpc->info->version >= ID_JZ4740) ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, true); + else + ingenic_gpio_set_bit(jzgc, JZ4730_GPIO_GPIER, irq, true); ingenic_gpio_irq_unmask(irqd); } @@ -1829,8 +1972,10 @@ static void ingenic_gpio_irq_disable(struct irq_data *irqd) if (jzgc->jzpc->info->version >= ID_JZ4770) ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_INT, irq, false); - else + else if (jzgc->jzpc->info->version >= ID_JZ4740) ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, false); + else + ingenic_gpio_set_bit(jzgc, JZ4730_GPIO_GPIER, irq, false); } static void ingenic_gpio_irq_ack(struct irq_data *irqd) @@ -1854,8 +1999,10 @@ static void ingenic_gpio_irq_ack(struct irq_data *irqd) if (jzgc->jzpc->info->version >= ID_JZ4770) ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_FLAG, irq, false); - else + else if (jzgc->jzpc->info->version >= ID_JZ4740) ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, irq, true); + else + ingenic_gpio_set_bit(jzgc, JZ4730_GPIO_GPFR, irq, false); } static int ingenic_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) @@ -1911,8 +2058,10 @@ static void ingenic_gpio_irq_handler(struct irq_desc *desc) if (jzgc->jzpc->info->version >= ID_JZ4770) flag = ingenic_gpio_read_reg(jzgc, JZ4770_GPIO_FLAG); - else + else if (jzgc->jzpc->info->version >= ID_JZ4740) flag = ingenic_gpio_read_reg(jzgc, JZ4740_GPIO_FLAG); + else + flag = ingenic_gpio_read_reg(jzgc, JZ4730_GPIO_GPFR); for_each_set_bit(i, &flag, 32) generic_handle_irq(irq_linear_revmap(gc->irq.domain, i)); @@ -1953,8 +2102,21 @@ static inline void ingenic_config_pin(struct ingenic_pinctrl *jzpc, unsigned int idx = pin % PINS_PER_GPIO_CHIP; unsigned int offt = pin / PINS_PER_GPIO_CHIP; - regmap_write(jzpc->map, offt * jzpc->info->reg_offset + - (set ? REG_SET(reg) : REG_CLEAR(reg)), BIT(idx)); + if (set) { + if (jzpc->info->version >= ID_JZ4740) + regmap_write(jzpc->map, offt * jzpc->info->reg_offset + + REG_SET(reg), BIT(idx)); + else + regmap_set_bits(jzpc->map, offt * jzpc->info->reg_offset + + reg, BIT(idx)); + } else { + if (jzpc->info->version >= ID_JZ4740) + regmap_write(jzpc->map, offt * jzpc->info->reg_offset + + REG_CLEAR(reg), BIT(idx)); + else + regmap_clear_bits(jzpc->map, offt * jzpc->info->reg_offset + + reg, BIT(idx)); + } } static inline void ingenic_shadow_config_pin(struct ingenic_pinctrl *jzpc, @@ -1973,6 +2135,22 @@ static inline void ingenic_shadow_config_pin_load(struct ingenic_pinctrl *jzpc, pin / PINS_PER_GPIO_CHIP); } +static inline void jz4730_config_pin_function(struct ingenic_pinctrl *jzpc, + unsigned int pin, u8 reg_upper, u8 reg_lower, u8 value) +{ + /* + * JZ4730 function and IRQ registers support two-bits-per-pin + * definitions, split into two groups of 16. + */ + unsigned int idx = pin % JZ4730_PINS_PER_PAIRED_REG; + unsigned int mask = GENMASK(1, 0) << idx * 2; + unsigned int offt = pin / PINS_PER_GPIO_CHIP; + u8 reg = (pin % PINS_PER_GPIO_CHIP) < JZ4730_PINS_PER_PAIRED_REG ? reg_lower : reg_upper; + + regmap_update_bits(jzpc->map, offt * jzpc->info->reg_offset + reg, + mask, value << (idx * 2)); +} + static inline bool ingenic_get_pin_config(struct ingenic_pinctrl *jzpc, unsigned int pin, u8 reg) { @@ -1996,6 +2174,10 @@ static int ingenic_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PAT1)) return GPIO_LINE_DIRECTION_IN; return GPIO_LINE_DIRECTION_OUT; + } else if (jzpc->info->version == ID_JZ4730) { + if (!ingenic_get_pin_config(jzpc, pin, JZ4730_GPIO_GPDIR)) + return GPIO_LINE_DIRECTION_IN; + return GPIO_LINE_DIRECTION_OUT; } if (ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_SELECT)) @@ -2054,10 +2236,13 @@ static int ingenic_pinmux_set_pin_fn(struct ingenic_pinctrl *jzpc, ingenic_config_pin(jzpc, pin, GPIO_MSK, false); ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, func & 0x2); ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT0, func & 0x1); - } else { + } else if (jzpc->info->version >= ID_JZ4740) { ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, true); ingenic_config_pin(jzpc, pin, JZ4740_GPIO_TRIG, func & 0x2); ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func & 0x1); + } else { + ingenic_config_pin(jzpc, pin, JZ4730_GPIO_GPIER, false); + jz4730_config_pin_function(jzpc, pin, JZ4730_GPIO_GPAUR, JZ4730_GPIO_GPALR, func); } return 0; @@ -2118,10 +2303,14 @@ static int ingenic_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, ingenic_config_pin(jzpc, pin, JZ4770_GPIO_INT, false); ingenic_config_pin(jzpc, pin, GPIO_MSK, true); ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, input); - } else { + } else if (jzpc->info->version >= ID_JZ4740) { ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, false); ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DIR, !input); ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, false); + } else { + ingenic_config_pin(jzpc, pin, JZ4730_GPIO_GPIER, false); + ingenic_config_pin(jzpc, pin, JZ4730_GPIO_GPDIR, !input); + jz4730_config_pin_function(jzpc, pin, JZ4730_GPIO_GPAUR, JZ4730_GPIO_GPALR, 0); } return 0; @@ -2164,8 +2353,10 @@ static int ingenic_pinconf_get(struct pinctrl_dev *pctldev, } else { if (jzpc->info->version >= ID_JZ4770) pull = !ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PEN); - else + else if (jzpc->info->version >= ID_JZ4740) pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS); + else + pull = ingenic_get_pin_config(jzpc, pin, JZ4730_GPIO_GPPUR); pullup = pull && (jzpc->info->pull_ups[offt] & BIT(idx)); pulldown = pull && (jzpc->info->pull_downs[offt] & BIT(idx)); @@ -2218,8 +2409,10 @@ static void ingenic_set_bias(struct ingenic_pinctrl *jzpc, } else if (jzpc->info->version >= ID_JZ4770) { ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PEN, !bias); - } else { + } else if (jzpc->info->version >= ID_JZ4740) { ingenic_config_pin(jzpc, pin, JZ4740_GPIO_PULL_DIS, !bias); + } else { + ingenic_config_pin(jzpc, pin, JZ4730_GPIO_GPPUR, bias); } } @@ -2228,8 +2421,10 @@ static void ingenic_set_output_level(struct ingenic_pinctrl *jzpc, { if (jzpc->info->version >= ID_JZ4770) ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT0, high); - else + else if (jzpc->info->version >= ID_JZ4740) ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DATA, high); + else + ingenic_config_pin(jzpc, pin, JZ4730_GPIO_DATA, high); } static int ingenic_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, @@ -2358,6 +2553,7 @@ static const struct regmap_config ingenic_pinctrl_regmap_config = { }; static const struct of_device_id ingenic_gpio_of_match[] __initconst = { + { .compatible = "ingenic,jz4730-gpio", }, { .compatible = "ingenic,jz4740-gpio", }, { .compatible = "ingenic,jz4725b-gpio", }, { .compatible = "ingenic,jz4760-gpio", }, @@ -2553,6 +2749,10 @@ static int __init ingenic_pinctrl_probe(struct platform_device *pdev) } static const struct of_device_id ingenic_pinctrl_of_match[] = { + { + .compatible = "ingenic,jz4730-pinctrl", + .data = IF_ENABLED(CONFIG_MACH_JZ4730, &jz4730_chip_info) + }, { .compatible = "ingenic,jz4740-pinctrl", .data = IF_ENABLED(CONFIG_MACH_JZ4740, &jz4740_chip_info) -- cgit v1.2.3 From 215c81a3e96964bd5d2e96aa22191ebff2d198c3 Mon Sep 17 00:00:00 2001 From: "周琰杰 (Zhou Yanjie)" Date: Sun, 18 Apr 2021 22:44:30 +0800 Subject: pinctrl: Ingenic: Add pinctrl driver for JZ4750. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for probing the pinctrl-ingenic driver on the JZ4750 SoC from Ingenic. Signed-off-by: 周琰杰 (Zhou Yanjie) Reviewed-by: Andy Shevchenko Reviewed-by: Paul Cercueil Link: https://lore.kernel.org/r/1618757073-1724-10-git-send-email-zhouyanjie@wanyeetech.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 142 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 24cc803fd450..d6ca094cfd6f 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -85,6 +85,7 @@ enum jz_version { ID_JZ4730, ID_JZ4740, ID_JZ4725B, + ID_JZ4750, ID_JZ4760, ID_JZ4770, ID_JZ4780, @@ -427,6 +428,143 @@ static const struct ingenic_chip_info jz4725b_chip_info = { .pull_downs = jz4740_pull_downs, }; +static const u32 jz4750_pull_ups[6] = { + 0xffffffff, 0xffffffff, 0x3fffffff, 0x7fffffff, 0x1fff3fff, 0x00ffffff, +}; + +static const u32 jz4750_pull_downs[6] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static int jz4750_uart0_data_pins[] = { 0xa4, 0xa5, }; +static int jz4750_uart0_hwflow_pins[] = { 0xa6, 0xa7, }; +static int jz4750_uart1_data_pins[] = { 0x90, 0x91, }; +static int jz4750_uart1_hwflow_pins[] = { 0x92, 0x93, }; +static int jz4750_uart2_data_pins[] = { 0x9b, 0x9a, }; +static int jz4750_uart3_data_pins[] = { 0xb0, 0xb1, }; +static int jz4750_uart3_hwflow_pins[] = { 0xb2, 0xb3, }; +static int jz4750_mmc0_1bit_pins[] = { 0xa8, 0xa9, 0xa0, }; +static int jz4750_mmc0_4bit_pins[] = { 0xa1, 0xa2, 0xa3, }; +static int jz4750_mmc0_8bit_pins[] = { 0xa4, 0xa5, 0xa6, 0xa7, }; +static int jz4750_mmc1_1bit_pins[] = { 0xae, 0xaf, 0xaa, }; +static int jz4750_mmc1_4bit_pins[] = { 0xab, 0xac, 0xad, }; +static int jz4750_i2c_pins[] = { 0x8c, 0x8d, }; +static int jz4750_cim_pins[] = { + 0x89, 0x8b, 0x8a, 0x88, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, +}; +static int jz4750_lcd_8bit_pins[] = { + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x72, 0x73, 0x74, +}; +static int jz4750_lcd_16bit_pins[] = { + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, +}; +static int jz4750_lcd_18bit_pins[] = { 0x70, 0x71, }; +static int jz4750_lcd_24bit_pins[] = { 0x76, 0x77, 0x78, 0x79, 0xb2, 0xb3, }; +static int jz4750_lcd_special_pins[] = { 0x76, 0x77, 0x78, 0x79, }; +static int jz4750_lcd_generic_pins[] = { 0x75, }; +static int jz4750_nand_cs1_pins[] = { 0x55, }; +static int jz4750_nand_cs2_pins[] = { 0x56, }; +static int jz4750_nand_cs3_pins[] = { 0x57, }; +static int jz4750_nand_cs4_pins[] = { 0x58, }; +static int jz4750_nand_fre_fwe_pins[] = { 0x5c, 0x5d, }; +static int jz4750_pwm_pwm0_pins[] = { 0x94, }; +static int jz4750_pwm_pwm1_pins[] = { 0x95, }; +static int jz4750_pwm_pwm2_pins[] = { 0x96, }; +static int jz4750_pwm_pwm3_pins[] = { 0x97, }; +static int jz4750_pwm_pwm4_pins[] = { 0x98, }; +static int jz4750_pwm_pwm5_pins[] = { 0x99, }; + +static const struct group_desc jz4750_groups[] = { + INGENIC_PIN_GROUP("uart0-data", jz4750_uart0_data, 1), + INGENIC_PIN_GROUP("uart0-hwflow", jz4750_uart0_hwflow, 1), + INGENIC_PIN_GROUP("uart1-data", jz4750_uart1_data, 0), + INGENIC_PIN_GROUP("uart1-hwflow", jz4750_uart1_hwflow, 0), + INGENIC_PIN_GROUP("uart2-data", jz4750_uart2_data, 1), + INGENIC_PIN_GROUP("uart3-data", jz4750_uart3_data, 0), + INGENIC_PIN_GROUP("uart3-hwflow", jz4750_uart3_hwflow, 0), + INGENIC_PIN_GROUP("mmc0-1bit", jz4750_mmc0_1bit, 0), + INGENIC_PIN_GROUP("mmc0-4bit", jz4750_mmc0_4bit, 0), + INGENIC_PIN_GROUP("mmc0-8bit", jz4750_mmc0_8bit, 0), + INGENIC_PIN_GROUP("mmc1-1bit", jz4750_mmc1_1bit, 0), + INGENIC_PIN_GROUP("mmc1-4bit", jz4750_mmc1_4bit, 0), + INGENIC_PIN_GROUP("i2c-data", jz4750_i2c, 0), + INGENIC_PIN_GROUP("cim-data", jz4750_cim, 0), + INGENIC_PIN_GROUP("lcd-8bit", jz4750_lcd_8bit, 0), + INGENIC_PIN_GROUP("lcd-16bit", jz4750_lcd_16bit, 0), + INGENIC_PIN_GROUP("lcd-18bit", jz4750_lcd_18bit, 0), + INGENIC_PIN_GROUP("lcd-24bit", jz4750_lcd_24bit, 1), + INGENIC_PIN_GROUP("lcd-special", jz4750_lcd_special, 0), + INGENIC_PIN_GROUP("lcd-generic", jz4750_lcd_generic, 0), + INGENIC_PIN_GROUP("nand-cs1", jz4750_nand_cs1, 0), + INGENIC_PIN_GROUP("nand-cs2", jz4750_nand_cs2, 0), + INGENIC_PIN_GROUP("nand-cs3", jz4750_nand_cs3, 0), + INGENIC_PIN_GROUP("nand-cs4", jz4750_nand_cs4, 0), + INGENIC_PIN_GROUP("nand-fre-fwe", jz4750_nand_fre_fwe, 0), + INGENIC_PIN_GROUP("pwm0", jz4750_pwm_pwm0, 0), + INGENIC_PIN_GROUP("pwm1", jz4750_pwm_pwm1, 0), + INGENIC_PIN_GROUP("pwm2", jz4750_pwm_pwm2, 0), + INGENIC_PIN_GROUP("pwm3", jz4750_pwm_pwm3, 0), + INGENIC_PIN_GROUP("pwm4", jz4750_pwm_pwm4, 0), + INGENIC_PIN_GROUP("pwm5", jz4750_pwm_pwm5, 0), +}; + +static const char *jz4750_uart0_groups[] = { "uart0-data", "uart0-hwflow", }; +static const char *jz4750_uart1_groups[] = { "uart1-data", "uart1-hwflow", }; +static const char *jz4750_uart2_groups[] = { "uart2-data", }; +static const char *jz4750_uart3_groups[] = { "uart3-data", "uart3-hwflow", }; +static const char *jz4750_mmc0_groups[] = { + "mmc0-1bit", "mmc0-4bit", "mmc0-8bit", +}; +static const char *jz4750_mmc1_groups[] = { "mmc0-1bit", "mmc0-4bit", }; +static const char *jz4750_i2c_groups[] = { "i2c-data", }; +static const char *jz4750_cim_groups[] = { "cim-data", }; +static const char *jz4750_lcd_groups[] = { + "lcd-8bit", "lcd-16bit", "lcd-18bit", "lcd-24bit", + "lcd-special", "lcd-generic", +}; +static const char *jz4750_nand_groups[] = { + "nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4", "nand-fre-fwe", +}; +static const char *jz4750_pwm0_groups[] = { "pwm0", }; +static const char *jz4750_pwm1_groups[] = { "pwm1", }; +static const char *jz4750_pwm2_groups[] = { "pwm2", }; +static const char *jz4750_pwm3_groups[] = { "pwm3", }; +static const char *jz4750_pwm4_groups[] = { "pwm4", }; +static const char *jz4750_pwm5_groups[] = { "pwm5", }; + +static const struct function_desc jz4750_functions[] = { + { "uart0", jz4750_uart0_groups, ARRAY_SIZE(jz4750_uart0_groups), }, + { "uart1", jz4750_uart1_groups, ARRAY_SIZE(jz4750_uart1_groups), }, + { "uart2", jz4750_uart2_groups, ARRAY_SIZE(jz4750_uart2_groups), }, + { "uart3", jz4750_uart3_groups, ARRAY_SIZE(jz4750_uart3_groups), }, + { "mmc0", jz4750_mmc0_groups, ARRAY_SIZE(jz4750_mmc0_groups), }, + { "mmc1", jz4750_mmc1_groups, ARRAY_SIZE(jz4750_mmc1_groups), }, + { "i2c", jz4750_i2c_groups, ARRAY_SIZE(jz4750_i2c_groups), }, + { "cim", jz4750_cim_groups, ARRAY_SIZE(jz4750_cim_groups), }, + { "lcd", jz4750_lcd_groups, ARRAY_SIZE(jz4750_lcd_groups), }, + { "nand", jz4750_nand_groups, ARRAY_SIZE(jz4750_nand_groups), }, + { "pwm0", jz4750_pwm0_groups, ARRAY_SIZE(jz4750_pwm0_groups), }, + { "pwm1", jz4750_pwm1_groups, ARRAY_SIZE(jz4750_pwm1_groups), }, + { "pwm2", jz4750_pwm2_groups, ARRAY_SIZE(jz4750_pwm2_groups), }, + { "pwm3", jz4750_pwm3_groups, ARRAY_SIZE(jz4750_pwm3_groups), }, + { "pwm4", jz4750_pwm4_groups, ARRAY_SIZE(jz4750_pwm4_groups), }, + { "pwm5", jz4750_pwm5_groups, ARRAY_SIZE(jz4750_pwm5_groups), }, +}; + +static const struct ingenic_chip_info jz4750_chip_info = { + .num_chips = 6, + .reg_offset = 0x100, + .version = ID_JZ4750, + .groups = jz4750_groups, + .num_groups = ARRAY_SIZE(jz4750_groups), + .functions = jz4750_functions, + .num_functions = ARRAY_SIZE(jz4750_functions), + .pull_ups = jz4750_pull_ups, + .pull_downs = jz4750_pull_downs, +}; + static const u32 jz4760_pull_ups[6] = { 0xffffffff, 0xfffcf3ff, 0xffffffff, 0xffffcfff, 0xfffffb7c, 0xfffff00f, }; @@ -2556,6 +2694,7 @@ static const struct of_device_id ingenic_gpio_of_match[] __initconst = { { .compatible = "ingenic,jz4730-gpio", }, { .compatible = "ingenic,jz4740-gpio", }, { .compatible = "ingenic,jz4725b-gpio", }, + { .compatible = "ingenic,jz4750-gpio", }, { .compatible = "ingenic,jz4760-gpio", }, { .compatible = "ingenic,jz4770-gpio", }, { .compatible = "ingenic,jz4780-gpio", }, @@ -2762,6 +2901,9 @@ static const struct of_device_id ingenic_pinctrl_of_match[] = { .data = IF_ENABLED(CONFIG_MACH_JZ4725B, &jz4725b_chip_info) }, { + .compatible = "ingenic,jz4750-pinctrl", + .data = IF_ENABLED(CONFIG_MACH_JZ4750, &jz4750_chip_info) + }, .compatible = "ingenic,jz4760-pinctrl", .data = IF_ENABLED(CONFIG_MACH_JZ4760, &jz4760_chip_info) }, -- cgit v1.2.3 From b582b5a434d35b617c9fde73210138365d681c26 Mon Sep 17 00:00:00 2001 From: "周琰杰 (Zhou Yanjie)" Date: Sun, 18 Apr 2021 22:44:31 +0800 Subject: pinctrl: Ingenic: Add pinctrl driver for JZ4755. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for probing the pinctrl-ingenic driver on the JZ4755 SoC from Ingenic. Signed-off-by: 周琰杰 (Zhou Yanjie) Reviewed-by: Andy Shevchenko Reviewed-by: Paul Cercueil Link: https://lore.kernel.org/r/1618757073-1724-11-git-send-email-zhouyanjie@wanyeetech.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 139 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index d6ca094cfd6f..c8a15e2660dd 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -86,6 +86,7 @@ enum jz_version { ID_JZ4740, ID_JZ4725B, ID_JZ4750, + ID_JZ4755, ID_JZ4760, ID_JZ4770, ID_JZ4780, @@ -565,6 +566,138 @@ static const struct ingenic_chip_info jz4750_chip_info = { .pull_downs = jz4750_pull_downs, }; +static const u32 jz4755_pull_ups[6] = { + 0xffffffff, 0xffffffff, 0x0fffffff, 0xffffffff, 0x33dc3fff, 0x0000fc00, +}; + +static const u32 jz4755_pull_downs[6] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static int jz4755_uart0_data_pins[] = { 0x7c, 0x7d, }; +static int jz4755_uart0_hwflow_pins[] = { 0x7e, 0x7f, }; +static int jz4755_uart1_data_pins[] = { 0x97, 0x99, }; +static int jz4755_uart2_data_pins[] = { 0x9f, }; +static int jz4755_mmc0_1bit_pins[] = { 0x2f, 0x50, 0x5c, }; +static int jz4755_mmc0_4bit_pins[] = { 0x5d, 0x5b, 0x51, }; +static int jz4755_mmc1_1bit_pins[] = { 0x3a, 0x3d, 0x3c, }; +static int jz4755_mmc1_4bit_pins[] = { 0x3b, 0x3e, 0x3f, }; +static int jz4755_i2c_pins[] = { 0x8c, 0x8d, }; +static int jz4755_cim_pins[] = { + 0x89, 0x8b, 0x8a, 0x88, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, +}; +static int jz4755_lcd_8bit_pins[] = { + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x72, 0x73, 0x74, +}; +static int jz4755_lcd_16bit_pins[] = { + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, +}; +static int jz4755_lcd_18bit_pins[] = { 0x70, 0x71, }; +static int jz4755_lcd_24bit_pins[] = { 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, }; +static int jz4755_lcd_special_pins[] = { 0x76, 0x77, 0x78, 0x79, }; +static int jz4755_lcd_generic_pins[] = { 0x75, }; +static int jz4755_nand_cs1_pins[] = { 0x55, }; +static int jz4755_nand_cs2_pins[] = { 0x56, }; +static int jz4755_nand_cs3_pins[] = { 0x57, }; +static int jz4755_nand_cs4_pins[] = { 0x58, }; +static int jz4755_nand_fre_fwe_pins[] = { 0x5c, 0x5d, }; +static int jz4755_pwm_pwm0_pins[] = { 0x94, }; +static int jz4755_pwm_pwm1_pins[] = { 0xab, }; +static int jz4755_pwm_pwm2_pins[] = { 0x96, }; +static int jz4755_pwm_pwm3_pins[] = { 0x97, }; +static int jz4755_pwm_pwm4_pins[] = { 0x98, }; +static int jz4755_pwm_pwm5_pins[] = { 0x99, }; + +static u8 jz4755_mmc0_1bit_funcs[] = { 2, 2, 1, }; +static u8 jz4755_mmc0_4bit_funcs[] = { 1, 0, 1, }; +static u8 jz4755_lcd_24bit_funcs[] = { 1, 1, 1, 1, 0, 0, }; + +static const struct group_desc jz4755_groups[] = { + INGENIC_PIN_GROUP("uart0-data", jz4755_uart0_data, 0), + INGENIC_PIN_GROUP("uart0-hwflow", jz4755_uart0_hwflow, 0), + INGENIC_PIN_GROUP("uart1-data", jz4755_uart1_data, 0), + INGENIC_PIN_GROUP("uart2-data", jz4755_uart2_data, 1), + INGENIC_PIN_GROUP_FUNCS("mmc0-1bit", jz4755_mmc0_1bit, + jz4755_mmc0_1bit_funcs), + INGENIC_PIN_GROUP_FUNCS("mmc0-4bit", jz4755_mmc0_4bit, + jz4755_mmc0_4bit_funcs), + INGENIC_PIN_GROUP("mmc1-1bit", jz4755_mmc1_1bit, 1), + INGENIC_PIN_GROUP("mmc1-4bit", jz4755_mmc1_4bit, 1), + INGENIC_PIN_GROUP("i2c-data", jz4755_i2c, 0), + INGENIC_PIN_GROUP("cim-data", jz4755_cim, 0), + INGENIC_PIN_GROUP("lcd-8bit", jz4755_lcd_8bit, 0), + INGENIC_PIN_GROUP("lcd-16bit", jz4755_lcd_16bit, 0), + INGENIC_PIN_GROUP("lcd-18bit", jz4755_lcd_18bit, 0), + INGENIC_PIN_GROUP_FUNCS("lcd-24bit", jz4755_lcd_24bit, + jz4755_lcd_24bit_funcs), + INGENIC_PIN_GROUP("lcd-special", jz4755_lcd_special, 0), + INGENIC_PIN_GROUP("lcd-generic", jz4755_lcd_generic, 0), + INGENIC_PIN_GROUP("nand-cs1", jz4755_nand_cs1, 0), + INGENIC_PIN_GROUP("nand-cs2", jz4755_nand_cs2, 0), + INGENIC_PIN_GROUP("nand-cs3", jz4755_nand_cs3, 0), + INGENIC_PIN_GROUP("nand-cs4", jz4755_nand_cs4, 0), + INGENIC_PIN_GROUP("nand-fre-fwe", jz4755_nand_fre_fwe, 0), + INGENIC_PIN_GROUP("pwm0", jz4755_pwm_pwm0, 0), + INGENIC_PIN_GROUP("pwm1", jz4755_pwm_pwm1, 1), + INGENIC_PIN_GROUP("pwm2", jz4755_pwm_pwm2, 0), + INGENIC_PIN_GROUP("pwm3", jz4755_pwm_pwm3, 0), + INGENIC_PIN_GROUP("pwm4", jz4755_pwm_pwm4, 0), + INGENIC_PIN_GROUP("pwm5", jz4755_pwm_pwm5, 0), +}; + +static const char *jz4755_uart0_groups[] = { "uart0-data", "uart0-hwflow", }; +static const char *jz4755_uart1_groups[] = { "uart1-data", }; +static const char *jz4755_uart2_groups[] = { "uart2-data", }; +static const char *jz4755_mmc0_groups[] = { "mmc0-1bit", "mmc0-4bit", }; +static const char *jz4755_mmc1_groups[] = { "mmc0-1bit", "mmc0-4bit", }; +static const char *jz4755_i2c_groups[] = { "i2c-data", }; +static const char *jz4755_cim_groups[] = { "cim-data", }; +static const char *jz4755_lcd_groups[] = { + "lcd-8bit", "lcd-16bit", "lcd-18bit", "lcd-24bit", + "lcd-special", "lcd-generic", +}; +static const char *jz4755_nand_groups[] = { + "nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4", "nand-fre-fwe", +}; +static const char *jz4755_pwm0_groups[] = { "pwm0", }; +static const char *jz4755_pwm1_groups[] = { "pwm1", }; +static const char *jz4755_pwm2_groups[] = { "pwm2", }; +static const char *jz4755_pwm3_groups[] = { "pwm3", }; +static const char *jz4755_pwm4_groups[] = { "pwm4", }; +static const char *jz4755_pwm5_groups[] = { "pwm5", }; + +static const struct function_desc jz4755_functions[] = { + { "uart0", jz4755_uart0_groups, ARRAY_SIZE(jz4755_uart0_groups), }, + { "uart1", jz4755_uart1_groups, ARRAY_SIZE(jz4755_uart1_groups), }, + { "uart2", jz4755_uart2_groups, ARRAY_SIZE(jz4755_uart2_groups), }, + { "mmc0", jz4755_mmc0_groups, ARRAY_SIZE(jz4755_mmc0_groups), }, + { "mmc1", jz4755_mmc1_groups, ARRAY_SIZE(jz4755_mmc1_groups), }, + { "i2c", jz4755_i2c_groups, ARRAY_SIZE(jz4755_i2c_groups), }, + { "cim", jz4755_cim_groups, ARRAY_SIZE(jz4755_cim_groups), }, + { "lcd", jz4755_lcd_groups, ARRAY_SIZE(jz4755_lcd_groups), }, + { "nand", jz4755_nand_groups, ARRAY_SIZE(jz4755_nand_groups), }, + { "pwm0", jz4755_pwm0_groups, ARRAY_SIZE(jz4755_pwm0_groups), }, + { "pwm1", jz4755_pwm1_groups, ARRAY_SIZE(jz4755_pwm1_groups), }, + { "pwm2", jz4755_pwm2_groups, ARRAY_SIZE(jz4755_pwm2_groups), }, + { "pwm3", jz4755_pwm3_groups, ARRAY_SIZE(jz4755_pwm3_groups), }, + { "pwm4", jz4755_pwm4_groups, ARRAY_SIZE(jz4755_pwm4_groups), }, + { "pwm5", jz4755_pwm5_groups, ARRAY_SIZE(jz4755_pwm5_groups), }, +}; + +static const struct ingenic_chip_info jz4755_chip_info = { + .num_chips = 6, + .reg_offset = 0x100, + .version = ID_JZ4755, + .groups = jz4755_groups, + .num_groups = ARRAY_SIZE(jz4755_groups), + .functions = jz4755_functions, + .num_functions = ARRAY_SIZE(jz4755_functions), + .pull_ups = jz4755_pull_ups, + .pull_downs = jz4755_pull_downs, +}; + static const u32 jz4760_pull_ups[6] = { 0xffffffff, 0xfffcf3ff, 0xffffffff, 0xffffcfff, 0xfffffb7c, 0xfffff00f, }; @@ -2695,6 +2828,7 @@ static const struct of_device_id ingenic_gpio_of_match[] __initconst = { { .compatible = "ingenic,jz4740-gpio", }, { .compatible = "ingenic,jz4725b-gpio", }, { .compatible = "ingenic,jz4750-gpio", }, + { .compatible = "ingenic,jz4755-gpio", }, { .compatible = "ingenic,jz4760-gpio", }, { .compatible = "ingenic,jz4770-gpio", }, { .compatible = "ingenic,jz4780-gpio", }, @@ -2904,6 +3038,11 @@ static const struct of_device_id ingenic_pinctrl_of_match[] = { .compatible = "ingenic,jz4750-pinctrl", .data = IF_ENABLED(CONFIG_MACH_JZ4750, &jz4750_chip_info) }, + { + .compatible = "ingenic,jz4755-pinctrl", + .data = IF_ENABLED(CONFIG_MACH_JZ4755, &jz4755_chip_info) + }, + { .compatible = "ingenic,jz4760-pinctrl", .data = IF_ENABLED(CONFIG_MACH_JZ4760, &jz4760_chip_info) }, -- cgit v1.2.3 From 0c9907404d24220f5a5196816d069f0e05dd4459 Mon Sep 17 00:00:00 2001 From: "周琰杰 (Zhou Yanjie)" Date: Sun, 18 Apr 2021 22:44:32 +0800 Subject: pinctrl: Ingenic: Add pinctrl driver for JZ4775. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for probing the pinctrl-ingenic driver on the JZ4775 SoC from Ingenic. Signed-off-by: 周琰杰 (Zhou Yanjie) Reviewed-by: Andy Shevchenko Reviewed-by: Paul Cercueil Link: https://lore.kernel.org/r/1618757073-1724-12-git-send-email-zhouyanjie@wanyeetech.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 279 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index c8a15e2660dd..22caef8de8c5 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -89,6 +89,7 @@ enum jz_version { ID_JZ4755, ID_JZ4760, ID_JZ4770, + ID_JZ4775, ID_JZ4780, ID_X1000, ID_X1500, @@ -1264,6 +1265,279 @@ static const struct ingenic_chip_info jz4770_chip_info = { .pull_downs = jz4770_pull_downs, }; +static const u32 jz4775_pull_ups[7] = { + 0x28ff00ff, 0xf030f3fc, 0x0fffffff, 0xfffe4000, 0xf0f0000c, 0x0000f00f, 0x0000f3c0, +}; + +static const u32 jz4775_pull_downs[7] = { + 0x00000000, 0x00030c03, 0x00000000, 0x00008000, 0x00000403, 0x00000ff0, 0x00030c00, +}; + +static int jz4775_uart0_data_pins[] = { 0xa0, 0xa3, }; +static int jz4775_uart0_hwflow_pins[] = { 0xa1, 0xa2, }; +static int jz4775_uart1_data_pins[] = { 0x7a, 0x7c, }; +static int jz4775_uart1_hwflow_pins[] = { 0x7b, 0x7d, }; +static int jz4775_uart2_data_c_pins[] = { 0x54, 0x4a, }; +static int jz4775_uart2_data_f_pins[] = { 0xa5, 0xa4, }; +static int jz4775_uart3_data_pins[] = { 0x1e, 0x1f, }; +static int jz4775_ssi_dt_a_pins[] = { 0x13, }; +static int jz4775_ssi_dt_d_pins[] = { 0x75, }; +static int jz4775_ssi_dr_a_pins[] = { 0x14, }; +static int jz4775_ssi_dr_d_pins[] = { 0x74, }; +static int jz4775_ssi_clk_a_pins[] = { 0x12, }; +static int jz4775_ssi_clk_d_pins[] = { 0x78, }; +static int jz4775_ssi_gpc_pins[] = { 0x76, }; +static int jz4775_ssi_ce0_a_pins[] = { 0x17, }; +static int jz4775_ssi_ce0_d_pins[] = { 0x79, }; +static int jz4775_ssi_ce1_pins[] = { 0x77, }; +static int jz4775_mmc0_1bit_a_pins[] = { 0x12, 0x13, 0x14, }; +static int jz4775_mmc0_4bit_a_pins[] = { 0x15, 0x16, 0x17, }; +static int jz4775_mmc0_8bit_a_pins[] = { 0x04, 0x05, 0x06, 0x07, }; +static int jz4775_mmc0_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, }; +static int jz4775_mmc0_4bit_e_pins[] = { 0x95, 0x96, 0x97, }; +static int jz4775_mmc1_1bit_d_pins[] = { 0x78, 0x79, 0x74, }; +static int jz4775_mmc1_4bit_d_pins[] = { 0x75, 0x76, 0x77, }; +static int jz4775_mmc1_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, }; +static int jz4775_mmc1_4bit_e_pins[] = { 0x95, 0x96, 0x97, }; +static int jz4775_mmc2_1bit_b_pins[] = { 0x3c, 0x3d, 0x34, }; +static int jz4775_mmc2_4bit_b_pins[] = { 0x35, 0x3e, 0x3f, }; +static int jz4775_mmc2_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, }; +static int jz4775_mmc2_4bit_e_pins[] = { 0x95, 0x96, 0x97, }; +static int jz4775_nemc_8bit_data_pins[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, +}; +static int jz4775_nemc_16bit_data_pins[] = { + 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, +}; +static int jz4775_nemc_cle_ale_pins[] = { 0x20, 0x21, }; +static int jz4775_nemc_addr_pins[] = { 0x22, 0x23, 0x24, 0x25, }; +static int jz4775_nemc_rd_we_pins[] = { 0x10, 0x11, }; +static int jz4775_nemc_frd_fwe_pins[] = { 0x12, 0x13, }; +static int jz4775_nemc_wait_pins[] = { 0x1b, }; +static int jz4775_nemc_cs1_pins[] = { 0x15, }; +static int jz4775_nemc_cs2_pins[] = { 0x16, }; +static int jz4775_nemc_cs3_pins[] = { 0x17, }; +static int jz4775_i2c0_pins[] = { 0x7e, 0x7f, }; +static int jz4775_i2c1_pins[] = { 0x9e, 0x9f, }; +static int jz4775_i2c2_pins[] = { 0x80, 0x83, }; +static int jz4775_i2s_data_tx_pins[] = { 0xa3, }; +static int jz4775_i2s_data_rx_pins[] = { 0xa2, }; +static int jz4775_i2s_clk_txrx_pins[] = { 0xa0, 0xa1, }; +static int jz4775_i2s_sysclk_pins[] = { 0x83, }; +static int jz4775_dmic_pins[] = { 0xaa, 0xab, }; +static int jz4775_cim_pins[] = { + 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, +}; +static int jz4775_lcd_8bit_pins[] = { + 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x4c, 0x4d, + 0x48, 0x52, 0x53, +}; +static int jz4775_lcd_16bit_pins[] = { + 0x4e, 0x4f, 0x50, 0x51, 0x56, 0x57, 0x58, 0x59, +}; +static int jz4775_lcd_18bit_pins[] = { + 0x5a, 0x5b, +}; +static int jz4775_lcd_24bit_pins[] = { + 0x40, 0x41, 0x4a, 0x4b, 0x54, 0x55, +}; +static int jz4775_lcd_special_pins[] = { 0x54, 0x4a, 0x41, 0x40, }; +static int jz4775_lcd_generic_pins[] = { 0x49, }; +static int jz4775_pwm_pwm0_pins[] = { 0x80, }; +static int jz4775_pwm_pwm1_pins[] = { 0x81, }; +static int jz4775_pwm_pwm2_pins[] = { 0x82, }; +static int jz4775_pwm_pwm3_pins[] = { 0x83, }; +static int jz4775_mac_rmii_pins[] = { + 0xa9, 0xab, 0xaa, 0xac, 0xa5, 0xa4, 0xad, 0xae, 0xa6, 0xa8, +}; +static int jz4775_mac_mii_pins[] = { + 0x7b, 0x7a, 0x7d, 0x7c, 0xa7, 0x24, 0xaf, +}; +static int jz4775_mac_rgmii_pins[] = { + 0xa9, 0x7b, 0x7a, 0xab, 0xaa, 0xac, 0x7d, 0x7c, 0xa5, 0xa4, + 0xad, 0xae, 0xa7, 0xa6, +}; +static int jz4775_mac_gmii_pins[] = { + 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, + 0xa8, 0x28, 0x24, 0xaf, +}; +static int jz4775_otg_pins[] = { 0x8a, }; + +static u8 jz4775_uart3_data_funcs[] = { 0, 1, }; +static u8 jz4775_mac_mii_funcs[] = { 1, 1, 1, 1, 0, 1, 0, }; +static u8 jz4775_mac_rgmii_funcs[] = { + 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, +}; +static u8 jz4775_mac_gmii_funcs[] = { + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 0, +}; + +static const struct group_desc jz4775_groups[] = { + INGENIC_PIN_GROUP("uart0-data", jz4775_uart0_data, 0), + INGENIC_PIN_GROUP("uart0-hwflow", jz4775_uart0_hwflow, 0), + INGENIC_PIN_GROUP("uart1-data", jz4775_uart1_data, 0), + INGENIC_PIN_GROUP("uart1-hwflow", jz4775_uart1_hwflow, 0), + INGENIC_PIN_GROUP("uart2-data-c", jz4775_uart2_data_c, 2), + INGENIC_PIN_GROUP("uart2-data-f", jz4775_uart2_data_f, 1), + INGENIC_PIN_GROUP_FUNCS("uart3-data", jz4775_uart3_data, + jz4775_uart3_data_funcs), + INGENIC_PIN_GROUP("ssi-dt-a", jz4775_ssi_dt_a, 2), + INGENIC_PIN_GROUP("ssi-dt-d", jz4775_ssi_dt_d, 1), + INGENIC_PIN_GROUP("ssi-dr-a", jz4775_ssi_dr_a, 2), + INGENIC_PIN_GROUP("ssi-dr-d", jz4775_ssi_dr_d, 1), + INGENIC_PIN_GROUP("ssi-clk-a", jz4775_ssi_clk_a, 2), + INGENIC_PIN_GROUP("ssi-clk-d", jz4775_ssi_clk_d, 1), + INGENIC_PIN_GROUP("ssi-gpc", jz4775_ssi_gpc, 1), + INGENIC_PIN_GROUP("ssi-ce0-a", jz4775_ssi_ce0_a, 2), + INGENIC_PIN_GROUP("ssi-ce0-d", jz4775_ssi_ce0_d, 1), + INGENIC_PIN_GROUP("ssi-ce1", jz4775_ssi_ce1, 1), + INGENIC_PIN_GROUP("mmc0-1bit-a", jz4775_mmc0_1bit_a, 1), + INGENIC_PIN_GROUP("mmc0-4bit-a", jz4775_mmc0_4bit_a, 1), + INGENIC_PIN_GROUP("mmc0-8bit-a", jz4775_mmc0_8bit_a, 1), + INGENIC_PIN_GROUP("mmc0-1bit-e", jz4775_mmc0_1bit_e, 0), + INGENIC_PIN_GROUP("mmc0-4bit-e", jz4775_mmc0_4bit_e, 0), + INGENIC_PIN_GROUP("mmc1-1bit-d", jz4775_mmc1_1bit_d, 0), + INGENIC_PIN_GROUP("mmc1-4bit-d", jz4775_mmc1_4bit_d, 0), + INGENIC_PIN_GROUP("mmc1-1bit-e", jz4775_mmc1_1bit_e, 1), + INGENIC_PIN_GROUP("mmc1-4bit-e", jz4775_mmc1_4bit_e, 1), + INGENIC_PIN_GROUP("mmc2-1bit-b", jz4775_mmc2_1bit_b, 0), + INGENIC_PIN_GROUP("mmc2-4bit-b", jz4775_mmc2_4bit_b, 0), + INGENIC_PIN_GROUP("mmc2-1bit-e", jz4775_mmc2_1bit_e, 2), + INGENIC_PIN_GROUP("mmc2-4bit-e", jz4775_mmc2_4bit_e, 2), + INGENIC_PIN_GROUP("nemc-8bit-data", jz4775_nemc_8bit_data, 0), + INGENIC_PIN_GROUP("nemc-16bit-data", jz4775_nemc_16bit_data, 1), + INGENIC_PIN_GROUP("nemc-cle-ale", jz4775_nemc_cle_ale, 0), + INGENIC_PIN_GROUP("nemc-addr", jz4775_nemc_addr, 0), + INGENIC_PIN_GROUP("nemc-rd-we", jz4775_nemc_rd_we, 0), + INGENIC_PIN_GROUP("nemc-frd-fwe", jz4775_nemc_frd_fwe, 0), + INGENIC_PIN_GROUP("nemc-wait", jz4775_nemc_wait, 0), + INGENIC_PIN_GROUP("nemc-cs1", jz4775_nemc_cs1, 0), + INGENIC_PIN_GROUP("nemc-cs2", jz4775_nemc_cs2, 0), + INGENIC_PIN_GROUP("nemc-cs3", jz4775_nemc_cs3, 0), + INGENIC_PIN_GROUP("i2c0-data", jz4775_i2c0, 0), + INGENIC_PIN_GROUP("i2c1-data", jz4775_i2c1, 0), + INGENIC_PIN_GROUP("i2c2-data", jz4775_i2c2, 1), + INGENIC_PIN_GROUP("i2s-data-tx", jz4775_i2s_data_tx, 1), + INGENIC_PIN_GROUP("i2s-data-rx", jz4775_i2s_data_rx, 1), + INGENIC_PIN_GROUP("i2s-clk-txrx", jz4775_i2s_clk_txrx, 1), + INGENIC_PIN_GROUP("i2s-sysclk", jz4775_i2s_sysclk, 2), + INGENIC_PIN_GROUP("dmic", jz4775_dmic, 1), + INGENIC_PIN_GROUP("cim-data", jz4775_cim, 0), + INGENIC_PIN_GROUP("lcd-8bit", jz4775_lcd_8bit, 0), + INGENIC_PIN_GROUP("lcd-16bit", jz4775_lcd_16bit, 0), + INGENIC_PIN_GROUP("lcd-18bit", jz4775_lcd_18bit, 0), + INGENIC_PIN_GROUP("lcd-24bit", jz4775_lcd_24bit, 0), + INGENIC_PIN_GROUP("lcd-generic", jz4775_lcd_generic, 0), + INGENIC_PIN_GROUP("lcd-special", jz4775_lcd_special, 1), + INGENIC_PIN_GROUP("pwm0", jz4775_pwm_pwm0, 0), + INGENIC_PIN_GROUP("pwm1", jz4775_pwm_pwm1, 0), + INGENIC_PIN_GROUP("pwm2", jz4775_pwm_pwm2, 0), + INGENIC_PIN_GROUP("pwm3", jz4775_pwm_pwm3, 0), + INGENIC_PIN_GROUP("mac-rmii", jz4775_mac_rmii, 0), + INGENIC_PIN_GROUP_FUNCS("mac-mii", jz4775_mac_mii, + jz4775_mac_mii_funcs), + INGENIC_PIN_GROUP_FUNCS("mac-rgmii", jz4775_mac_rgmii, + jz4775_mac_rgmii_funcs), + INGENIC_PIN_GROUP_FUNCS("mac-gmii", jz4775_mac_gmii, + jz4775_mac_gmii_funcs), + INGENIC_PIN_GROUP("otg-vbus", jz4775_otg, 0), +}; + +static const char *jz4775_uart0_groups[] = { "uart0-data", "uart0-hwflow", }; +static const char *jz4775_uart1_groups[] = { "uart1-data", "uart1-hwflow", }; +static const char *jz4775_uart2_groups[] = { "uart2-data-c", "uart2-data-f", }; +static const char *jz4775_uart3_groups[] = { "uart3-data", }; +static const char *jz4775_ssi_groups[] = { + "ssi-dt-a", "ssi-dt-d", + "ssi-dr-a", "ssi-dr-d", + "ssi-clk-a", "ssi-clk-d", + "ssi-gpc", + "ssi-ce0-a", "ssi-ce0-d", + "ssi-ce1", +}; +static const char *jz4775_mmc0_groups[] = { + "mmc0-1bit-a", "mmc0-4bit-a", "mmc0-8bit-a", + "mmc0-1bit-e", "mmc0-4bit-e", +}; +static const char *jz4775_mmc1_groups[] = { + "mmc1-1bit-d", "mmc1-4bit-d", + "mmc1-1bit-e", "mmc1-4bit-e", +}; +static const char *jz4775_mmc2_groups[] = { + "mmc2-1bit-b", "mmc2-4bit-b", + "mmc2-1bit-e", "mmc2-4bit-e", +}; +static const char *jz4775_nemc_groups[] = { + "nemc-8bit-data", "nemc-16bit-data", "nemc-cle-ale", + "nemc-addr", "nemc-rd-we", "nemc-frd-fwe", "nemc-wait", +}; +static const char *jz4775_cs1_groups[] = { "nemc-cs1", }; +static const char *jz4775_cs2_groups[] = { "nemc-cs2", }; +static const char *jz4775_cs3_groups[] = { "nemc-cs3", }; +static const char *jz4775_i2c0_groups[] = { "i2c0-data", }; +static const char *jz4775_i2c1_groups[] = { "i2c1-data", }; +static const char *jz4775_i2c2_groups[] = { "i2c2-data", }; +static const char *jz4775_i2s_groups[] = { + "i2s-data-tx", "i2s-data-rx", "i2s-clk-txrx", "i2s-sysclk", +}; +static const char *jz4775_dmic_groups[] = { "dmic", }; +static const char *jz4775_cim_groups[] = { "cim-data", }; +static const char *jz4775_lcd_groups[] = { + "lcd-8bit", "lcd-16bit", "lcd-18bit", "lcd-24bit", + "lcd-special", "lcd-generic", +}; +static const char *jz4775_pwm0_groups[] = { "pwm0", }; +static const char *jz4775_pwm1_groups[] = { "pwm1", }; +static const char *jz4775_pwm2_groups[] = { "pwm2", }; +static const char *jz4775_pwm3_groups[] = { "pwm3", }; +static const char *jz4775_mac_groups[] = { + "mac-rmii", "mac-mii", "mac-rgmii", "mac-gmii", +}; +static const char *jz4775_otg_groups[] = { "otg-vbus", }; + +static const struct function_desc jz4775_functions[] = { + { "uart0", jz4775_uart0_groups, ARRAY_SIZE(jz4775_uart0_groups), }, + { "uart1", jz4775_uart1_groups, ARRAY_SIZE(jz4775_uart1_groups), }, + { "uart2", jz4775_uart2_groups, ARRAY_SIZE(jz4775_uart2_groups), }, + { "uart3", jz4775_uart3_groups, ARRAY_SIZE(jz4775_uart3_groups), }, + { "ssi", jz4775_ssi_groups, ARRAY_SIZE(jz4775_ssi_groups), }, + { "mmc0", jz4775_mmc0_groups, ARRAY_SIZE(jz4775_mmc0_groups), }, + { "mmc1", jz4775_mmc1_groups, ARRAY_SIZE(jz4775_mmc1_groups), }, + { "mmc2", jz4775_mmc2_groups, ARRAY_SIZE(jz4775_mmc2_groups), }, + { "nemc", jz4775_nemc_groups, ARRAY_SIZE(jz4775_nemc_groups), }, + { "nemc-cs1", jz4775_cs1_groups, ARRAY_SIZE(jz4775_cs1_groups), }, + { "nemc-cs2", jz4775_cs2_groups, ARRAY_SIZE(jz4775_cs2_groups), }, + { "nemc-cs3", jz4775_cs3_groups, ARRAY_SIZE(jz4775_cs3_groups), }, + { "i2c0", jz4775_i2c0_groups, ARRAY_SIZE(jz4775_i2c0_groups), }, + { "i2c1", jz4775_i2c1_groups, ARRAY_SIZE(jz4775_i2c1_groups), }, + { "i2c2", jz4775_i2c2_groups, ARRAY_SIZE(jz4775_i2c2_groups), }, + { "i2s", jz4775_i2s_groups, ARRAY_SIZE(jz4775_i2s_groups), }, + { "dmic", jz4775_dmic_groups, ARRAY_SIZE(jz4775_dmic_groups), }, + { "cim", jz4775_cim_groups, ARRAY_SIZE(jz4775_cim_groups), }, + { "lcd", jz4775_lcd_groups, ARRAY_SIZE(jz4775_lcd_groups), }, + { "pwm0", jz4775_pwm0_groups, ARRAY_SIZE(jz4775_pwm0_groups), }, + { "pwm1", jz4775_pwm1_groups, ARRAY_SIZE(jz4775_pwm1_groups), }, + { "pwm2", jz4775_pwm2_groups, ARRAY_SIZE(jz4775_pwm2_groups), }, + { "pwm3", jz4775_pwm3_groups, ARRAY_SIZE(jz4775_pwm3_groups), }, + { "mac", jz4775_mac_groups, ARRAY_SIZE(jz4775_mac_groups), }, + { "otg", jz4775_otg_groups, ARRAY_SIZE(jz4775_otg_groups), }, +}; + +static const struct ingenic_chip_info jz4775_chip_info = { + .num_chips = 7, + .reg_offset = 0x100, + .version = ID_JZ4775, + .groups = jz4775_groups, + .num_groups = ARRAY_SIZE(jz4775_groups), + .functions = jz4775_functions, + .num_functions = ARRAY_SIZE(jz4775_functions), + .pull_ups = jz4775_pull_ups, + .pull_downs = jz4775_pull_downs, +}; + static const u32 jz4780_pull_ups[6] = { 0x3fffffff, 0xfff0f3fc, 0x0fffffff, 0xffff4fff, 0xfffffb7c, 0x7fa7f00f, }; @@ -2831,6 +3105,7 @@ static const struct of_device_id ingenic_gpio_of_match[] __initconst = { { .compatible = "ingenic,jz4755-gpio", }, { .compatible = "ingenic,jz4760-gpio", }, { .compatible = "ingenic,jz4770-gpio", }, + { .compatible = "ingenic,jz4775-gpio", }, { .compatible = "ingenic,jz4780-gpio", }, { .compatible = "ingenic,x1000-gpio", }, { .compatible = "ingenic,x1830-gpio", }, @@ -3054,6 +3329,10 @@ static const struct of_device_id ingenic_pinctrl_of_match[] = { .compatible = "ingenic,jz4770-pinctrl", .data = IF_ENABLED(CONFIG_MACH_JZ4770, &jz4770_chip_info) }, + { + .compatible = "ingenic,jz4775-pinctrl", + .data = IF_ENABLED(CONFIG_MACH_JZ4775, &jz4775_chip_info) + }, { .compatible = "ingenic,jz4780-pinctrl", .data = IF_ENABLED(CONFIG_MACH_JZ4780, &jz4780_chip_info) -- cgit v1.2.3 From 943e0da15370341a6e5d9baa5b6a7649c020e105 Mon Sep 17 00:00:00 2001 From: "周琰杰 (Zhou Yanjie)" Date: Sun, 18 Apr 2021 22:44:33 +0800 Subject: pinctrl: Ingenic: Add pinctrl driver for X2000. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for probing the pinctrl-ingenic driver on the X2000 SoC from Ingenic. Signed-off-by: 周琰杰 (Zhou Yanjie) Reviewed-by: Andy Shevchenko Reviewed-by: Paul Cercueil Link: https://lore.kernel.org/r/1618757073-1724-13-git-send-email-zhouyanjie@wanyeetech.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 592 +++++++++++++++++++++++++++++++++++++- 1 file changed, 579 insertions(+), 13 deletions(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 22caef8de8c5..651a36b9dcc0 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -56,6 +56,14 @@ #define X1830_GPIO_PEL 0x110 #define X1830_GPIO_PEH 0x120 +#define X1830_GPIO_SR 0x150 +#define X1830_GPIO_SMT 0x160 + +#define X2000_GPIO_EDG 0x70 +#define X2000_GPIO_PEPU 0x80 +#define X2000_GPIO_PEPD 0x90 +#define X2000_GPIO_SR 0xd0 +#define X2000_GPIO_SMT 0xe0 #define REG_SET(x) ((x) + 0x4) #define REG_CLEAR(x) ((x) + 0x8) @@ -94,6 +102,7 @@ enum jz_version { ID_X1000, ID_X1500, ID_X1830, + ID_X2000, }; struct ingenic_chip_info { @@ -2342,6 +2351,456 @@ static const struct ingenic_chip_info x1830_chip_info = { .pull_downs = x1830_pull_downs, }; +static const u32 x2000_pull_ups[5] = { + 0x0003ffff, 0xffffffff, 0x1ff0ffff, 0xc7fe3f3f, 0x8fff003f, +}; + +static const u32 x2000_pull_downs[5] = { + 0x0003ffff, 0xffffffff, 0x1ff0ffff, 0x00000000, 0x8fff003f, +}; + +static int x2000_uart0_data_pins[] = { 0x77, 0x78, }; +static int x2000_uart0_hwflow_pins[] = { 0x79, 0x7a, }; +static int x2000_uart1_data_pins[] = { 0x57, 0x58, }; +static int x2000_uart1_hwflow_pins[] = { 0x55, 0x56, }; +static int x2000_uart2_data_pins[] = { 0x7e, 0x7f, }; +static int x2000_uart3_data_c_pins[] = { 0x59, 0x5a, }; +static int x2000_uart3_data_d_pins[] = { 0x62, 0x63, }; +static int x2000_uart3_hwflow_c_pins[] = { 0x5b, 0x5c, }; +static int x2000_uart3_hwflow_d_pins[] = { 0x60, 0x61, }; +static int x2000_uart4_data_a_pins[] = { 0x02, 0x03, }; +static int x2000_uart4_data_c_pins[] = { 0x4b, 0x4c, }; +static int x2000_uart4_hwflow_a_pins[] = { 0x00, 0x01, }; +static int x2000_uart4_hwflow_c_pins[] = { 0x49, 0x4a, }; +static int x2000_uart5_data_a_pins[] = { 0x04, 0x05, }; +static int x2000_uart5_data_c_pins[] = { 0x45, 0x46, }; +static int x2000_uart6_data_a_pins[] = { 0x06, 0x07, }; +static int x2000_uart6_data_c_pins[] = { 0x47, 0x48, }; +static int x2000_uart7_data_a_pins[] = { 0x08, 0x09, }; +static int x2000_uart7_data_c_pins[] = { 0x41, 0x42, }; +static int x2000_uart8_data_pins[] = { 0x3c, 0x3d, }; +static int x2000_uart9_data_pins[] = { 0x3e, 0x3f, }; +static int x2000_sfc0_d_pins[] = { 0x73, 0x74, 0x75, 0x76, 0x71, 0x72, }; +static int x2000_sfc0_e_pins[] = { 0x92, 0x93, 0x94, 0x95, 0x90, 0x91, }; +static int x2000_sfc1_pins[] = { 0x77, 0x78, 0x79, 0x7a, }; +static int x2000_ssi0_dt_b_pins[] = { 0x3e, }; +static int x2000_ssi0_dt_d_pins[] = { 0x69, }; +static int x2000_ssi0_dr_b_pins[] = { 0x3d, }; +static int x2000_ssi0_dr_d_pins[] = { 0x6a, }; +static int x2000_ssi0_clk_b_pins[] = { 0x3f, }; +static int x2000_ssi0_clk_d_pins[] = { 0x68, }; +static int x2000_ssi0_ce0_b_pins[] = { 0x3c, }; +static int x2000_ssi0_ce0_d_pins[] = { 0x6d, }; +static int x2000_ssi1_dt_c_pins[] = { 0x4b, }; +static int x2000_ssi1_dt_d_pins[] = { 0x72, }; +static int x2000_ssi1_dt_e_pins[] = { 0x91, }; +static int x2000_ssi1_dr_c_pins[] = { 0x4a, }; +static int x2000_ssi1_dr_d_pins[] = { 0x73, }; +static int x2000_ssi1_dr_e_pins[] = { 0x92, }; +static int x2000_ssi1_clk_c_pins[] = { 0x4c, }; +static int x2000_ssi1_clk_d_pins[] = { 0x71, }; +static int x2000_ssi1_clk_e_pins[] = { 0x90, }; +static int x2000_ssi1_ce0_c_pins[] = { 0x49, }; +static int x2000_ssi1_ce0_d_pins[] = { 0x76, }; +static int x2000_ssi1_ce0_e_pins[] = { 0x95, }; +static int x2000_mmc0_1bit_pins[] = { 0x71, 0x72, 0x73, }; +static int x2000_mmc0_4bit_pins[] = { 0x74, 0x75, 0x75, }; +static int x2000_mmc0_8bit_pins[] = { 0x77, 0x78, 0x79, 0x7a, }; +static int x2000_mmc1_1bit_pins[] = { 0x68, 0x69, 0x6a, }; +static int x2000_mmc1_4bit_pins[] = { 0x6b, 0x6c, 0x6d, }; +static int x2000_mmc2_1bit_pins[] = { 0x80, 0x81, 0x82, }; +static int x2000_mmc2_4bit_pins[] = { 0x83, 0x84, 0x85, }; +static int x2000_emc_8bit_data_pins[] = { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +}; +static int x2000_emc_16bit_data_pins[] = { + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, +}; +static int x2000_emc_addr_pins[] = { + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, +}; +static int x2000_emc_rd_we_pins[] = { 0x2d, 0x2e, }; +static int x2000_emc_wait_pins[] = { 0x2f, }; +static int x2000_emc_cs1_pins[] = { 0x57, }; +static int x2000_emc_cs2_pins[] = { 0x58, }; +static int x2000_i2c0_pins[] = { 0x4e, 0x4d, }; +static int x2000_i2c1_c_pins[] = { 0x58, 0x57, }; +static int x2000_i2c1_d_pins[] = { 0x6c, 0x6b, }; +static int x2000_i2c2_b_pins[] = { 0x37, 0x36, }; +static int x2000_i2c2_d_pins[] = { 0x75, 0x74, }; +static int x2000_i2c2_e_pins[] = { 0x94, 0x93, }; +static int x2000_i2c3_a_pins[] = { 0x11, 0x10, }; +static int x2000_i2c3_d_pins[] = { 0x7f, 0x7e, }; +static int x2000_i2c4_c_pins[] = { 0x5a, 0x59, }; +static int x2000_i2c4_d_pins[] = { 0x61, 0x60, }; +static int x2000_i2c5_c_pins[] = { 0x5c, 0x5b, }; +static int x2000_i2c5_d_pins[] = { 0x65, 0x64, }; +static int x2000_i2s1_data_tx_pins[] = { 0x47, }; +static int x2000_i2s1_data_rx_pins[] = { 0x44, }; +static int x2000_i2s1_clk_tx_pins[] = { 0x45, 0x46, }; +static int x2000_i2s1_clk_rx_pins[] = { 0x42, 0x43, }; +static int x2000_i2s1_sysclk_tx_pins[] = { 0x48, }; +static int x2000_i2s1_sysclk_rx_pins[] = { 0x41, }; +static int x2000_i2s2_data_rx0_pins[] = { 0x0a, }; +static int x2000_i2s2_data_rx1_pins[] = { 0x0b, }; +static int x2000_i2s2_data_rx2_pins[] = { 0x0c, }; +static int x2000_i2s2_data_rx3_pins[] = { 0x0d, }; +static int x2000_i2s2_clk_rx_pins[] = { 0x11, 0x09, }; +static int x2000_i2s2_sysclk_rx_pins[] = { 0x07, }; +static int x2000_i2s3_data_tx0_pins[] = { 0x03, }; +static int x2000_i2s3_data_tx1_pins[] = { 0x04, }; +static int x2000_i2s3_data_tx2_pins[] = { 0x05, }; +static int x2000_i2s3_data_tx3_pins[] = { 0x06, }; +static int x2000_i2s3_clk_tx_pins[] = { 0x10, 0x02, }; +static int x2000_i2s3_sysclk_tx_pins[] = { 0x00, }; +static int x2000_dmic0_pins[] = { 0x54, 0x55, }; +static int x2000_dmic1_pins[] = { 0x56, }; +static int x2000_dmic2_pins[] = { 0x57, }; +static int x2000_dmic3_pins[] = { 0x58, }; +static int x2000_cim_8bit_pins[] = { + 0x0e, 0x0c, 0x0d, 0x4f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, +}; +static int x2000_cim_12bit_pins[] = { 0x08, 0x09, 0x0a, 0x0b, }; +static int x2000_lcd_tft_8bit_pins[] = { + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x38, 0x3a, 0x39, 0x3b, +}; +static int x2000_lcd_tft_16bit_pins[] = { + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, +}; +static int x2000_lcd_tft_18bit_pins[] = { + 0x30, 0x31, +}; +static int x2000_lcd_tft_24bit_pins[] = { + 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +}; +static int x2000_lcd_slcd_8bit_pins[] = { + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x3a, 0x38, 0x3b, 0x30, 0x39, +}; +static int x2000_pwm_pwm0_c_pins[] = { 0x40, }; +static int x2000_pwm_pwm0_d_pins[] = { 0x7e, }; +static int x2000_pwm_pwm1_c_pins[] = { 0x41, }; +static int x2000_pwm_pwm1_d_pins[] = { 0x7f, }; +static int x2000_pwm_pwm2_c_pins[] = { 0x42, }; +static int x2000_pwm_pwm2_e_pins[] = { 0x80, }; +static int x2000_pwm_pwm3_c_pins[] = { 0x43, }; +static int x2000_pwm_pwm3_e_pins[] = { 0x81, }; +static int x2000_pwm_pwm4_c_pins[] = { 0x44, }; +static int x2000_pwm_pwm4_e_pins[] = { 0x82, }; +static int x2000_pwm_pwm5_c_pins[] = { 0x45, }; +static int x2000_pwm_pwm5_e_pins[] = { 0x83, }; +static int x2000_pwm_pwm6_c_pins[] = { 0x46, }; +static int x2000_pwm_pwm6_e_pins[] = { 0x84, }; +static int x2000_pwm_pwm7_c_pins[] = { 0x47, }; +static int x2000_pwm_pwm7_e_pins[] = { 0x85, }; +static int x2000_pwm_pwm8_pins[] = { 0x48, }; +static int x2000_pwm_pwm9_pins[] = { 0x49, }; +static int x2000_pwm_pwm10_pins[] = { 0x4a, }; +static int x2000_pwm_pwm11_pins[] = { 0x4b, }; +static int x2000_pwm_pwm12_pins[] = { 0x4c, }; +static int x2000_pwm_pwm13_pins[] = { 0x4d, }; +static int x2000_pwm_pwm14_pins[] = { 0x4e, }; +static int x2000_pwm_pwm15_pins[] = { 0x4f, }; +static int x2000_mac0_rmii_pins[] = { + 0x4b, 0x47, 0x46, 0x4a, 0x43, 0x42, 0x4c, 0x4d, 0x4e, 0x41, +}; +static int x2000_mac0_rgmii_pins[] = { + 0x4b, 0x49, 0x48, 0x47, 0x46, 0x4a, 0x45, 0x44, 0x43, 0x42, + 0x4c, 0x4d, 0x4f, 0x4e, 0x41, +}; +static int x2000_mac1_rmii_pins[] = { + 0x32, 0x2d, 0x2c, 0x31, 0x29, 0x28, 0x33, 0x34, 0x35, 0x37, +}; +static int x2000_mac1_rgmii_pins[] = { + 0x32, 0x2f, 0x2e, 0x2d, 0x2c, 0x31, 0x2b, 0x2a, 0x29, 0x28, + 0x33, 0x34, 0x36, 0x35, 0x37, +}; +static int x2000_otg_pins[] = { 0x96, }; + +static u8 x2000_cim_8bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, }; + +static const struct group_desc x2000_groups[] = { + INGENIC_PIN_GROUP("uart0-data", x2000_uart0_data, 2), + INGENIC_PIN_GROUP("uart0-hwflow", x2000_uart0_hwflow, 2), + INGENIC_PIN_GROUP("uart1-data", x2000_uart1_data, 1), + INGENIC_PIN_GROUP("uart1-hwflow", x2000_uart1_hwflow, 1), + INGENIC_PIN_GROUP("uart2-data", x2000_uart2_data, 0), + INGENIC_PIN_GROUP("uart3-data-c", x2000_uart3_data_c, 0), + INGENIC_PIN_GROUP("uart3-data-d", x2000_uart3_data_d, 1), + INGENIC_PIN_GROUP("uart3-hwflow-c", x2000_uart3_hwflow_c, 0), + INGENIC_PIN_GROUP("uart3-hwflow-d", x2000_uart3_hwflow_d, 1), + INGENIC_PIN_GROUP("uart4-data-a", x2000_uart4_data_a, 1), + INGENIC_PIN_GROUP("uart4-data-c", x2000_uart4_data_c, 3), + INGENIC_PIN_GROUP("uart4-hwflow-a", x2000_uart4_hwflow_a, 1), + INGENIC_PIN_GROUP("uart4-hwflow-c", x2000_uart4_hwflow_c, 3), + INGENIC_PIN_GROUP("uart5-data-a", x2000_uart5_data_a, 1), + INGENIC_PIN_GROUP("uart5-data-c", x2000_uart5_data_c, 3), + INGENIC_PIN_GROUP("uart6-data-a", x2000_uart6_data_a, 1), + INGENIC_PIN_GROUP("uart6-data-c", x2000_uart6_data_c, 3), + INGENIC_PIN_GROUP("uart7-data-a", x2000_uart7_data_a, 1), + INGENIC_PIN_GROUP("uart7-data-c", x2000_uart7_data_c, 3), + INGENIC_PIN_GROUP("uart8-data", x2000_uart8_data, 3), + INGENIC_PIN_GROUP("uart9-data", x2000_uart9_data, 3), + INGENIC_PIN_GROUP("sfc0-d", x2000_sfc0_d, 1), + INGENIC_PIN_GROUP("sfc0-e", x2000_sfc0_e, 0), + INGENIC_PIN_GROUP("sfc1", x2000_sfc1, 1), + INGENIC_PIN_GROUP("ssi0-dt-b", x2000_ssi0_dt_b, 1), + INGENIC_PIN_GROUP("ssi0-dt-d", x2000_ssi0_dt_d, 1), + INGENIC_PIN_GROUP("ssi0-dr-b", x2000_ssi0_dr_b, 1), + INGENIC_PIN_GROUP("ssi0-dr-d", x2000_ssi0_dr_d, 1), + INGENIC_PIN_GROUP("ssi0-clk-b", x2000_ssi0_clk_b, 1), + INGENIC_PIN_GROUP("ssi0-clk-d", x2000_ssi0_clk_d, 1), + INGENIC_PIN_GROUP("ssi0-ce0-b", x2000_ssi0_ce0_b, 1), + INGENIC_PIN_GROUP("ssi0-ce0-d", x2000_ssi0_ce0_d, 1), + INGENIC_PIN_GROUP("ssi1-dt-c", x2000_ssi1_dt_c, 2), + INGENIC_PIN_GROUP("ssi1-dt-d", x2000_ssi1_dt_d, 2), + INGENIC_PIN_GROUP("ssi1-dt-e", x2000_ssi1_dt_e, 1), + INGENIC_PIN_GROUP("ssi1-dr-c", x2000_ssi1_dr_c, 2), + INGENIC_PIN_GROUP("ssi1-dr-d", x2000_ssi1_dr_d, 2), + INGENIC_PIN_GROUP("ssi1-dr-e", x2000_ssi1_dr_e, 1), + INGENIC_PIN_GROUP("ssi1-clk-c", x2000_ssi1_clk_c, 2), + INGENIC_PIN_GROUP("ssi1-clk-d", x2000_ssi1_clk_d, 2), + INGENIC_PIN_GROUP("ssi1-clk-e", x2000_ssi1_clk_e, 1), + INGENIC_PIN_GROUP("ssi1-ce0-c", x2000_ssi1_ce0_c, 2), + INGENIC_PIN_GROUP("ssi1-ce0-d", x2000_ssi1_ce0_d, 2), + INGENIC_PIN_GROUP("ssi1-ce0-e", x2000_ssi1_ce0_e, 1), + INGENIC_PIN_GROUP("mmc0-1bit", x2000_mmc0_1bit, 0), + INGENIC_PIN_GROUP("mmc0-4bit", x2000_mmc0_4bit, 0), + INGENIC_PIN_GROUP("mmc0-8bit", x2000_mmc0_8bit, 0), + INGENIC_PIN_GROUP("mmc1-1bit", x2000_mmc1_1bit, 0), + INGENIC_PIN_GROUP("mmc1-4bit", x2000_mmc1_4bit, 0), + INGENIC_PIN_GROUP("mmc2-1bit", x2000_mmc2_1bit, 0), + INGENIC_PIN_GROUP("mmc2-4bit", x2000_mmc2_4bit, 0), + INGENIC_PIN_GROUP("emc-8bit-data", x2000_emc_8bit_data, 0), + INGENIC_PIN_GROUP("emc-16bit-data", x2000_emc_16bit_data, 0), + INGENIC_PIN_GROUP("emc-addr", x2000_emc_addr, 0), + INGENIC_PIN_GROUP("emc-rd-we", x2000_emc_rd_we, 0), + INGENIC_PIN_GROUP("emc-wait", x2000_emc_wait, 0), + INGENIC_PIN_GROUP("emc-cs1", x2000_emc_cs1, 3), + INGENIC_PIN_GROUP("emc-cs2", x2000_emc_cs2, 3), + INGENIC_PIN_GROUP("i2c0-data", x2000_i2c0, 3), + INGENIC_PIN_GROUP("i2c1-data-c", x2000_i2c1_c, 2), + INGENIC_PIN_GROUP("i2c1-data-d", x2000_i2c1_d, 1), + INGENIC_PIN_GROUP("i2c2-data-b", x2000_i2c2_b, 2), + INGENIC_PIN_GROUP("i2c2-data-d", x2000_i2c2_d, 2), + INGENIC_PIN_GROUP("i2c2-data-e", x2000_i2c2_e, 1), + INGENIC_PIN_GROUP("i2c3-data-a", x2000_i2c3_a, 0), + INGENIC_PIN_GROUP("i2c3-data-d", x2000_i2c3_d, 1), + INGENIC_PIN_GROUP("i2c4-data-c", x2000_i2c4_c, 1), + INGENIC_PIN_GROUP("i2c4-data-d", x2000_i2c4_d, 2), + INGENIC_PIN_GROUP("i2c5-data-c", x2000_i2c5_c, 1), + INGENIC_PIN_GROUP("i2c5-data-d", x2000_i2c5_d, 1), + INGENIC_PIN_GROUP("i2s1-data-tx", x2000_i2s1_data_tx, 2), + INGENIC_PIN_GROUP("i2s1-data-rx", x2000_i2s1_data_rx, 2), + INGENIC_PIN_GROUP("i2s1-clk-tx", x2000_i2s1_clk_tx, 2), + INGENIC_PIN_GROUP("i2s1-clk-rx", x2000_i2s1_clk_rx, 2), + INGENIC_PIN_GROUP("i2s1-sysclk-tx", x2000_i2s1_sysclk_tx, 2), + INGENIC_PIN_GROUP("i2s1-sysclk-rx", x2000_i2s1_sysclk_rx, 2), + INGENIC_PIN_GROUP("i2s2-data-rx0", x2000_i2s2_data_rx0, 2), + INGENIC_PIN_GROUP("i2s2-data-rx1", x2000_i2s2_data_rx1, 2), + INGENIC_PIN_GROUP("i2s2-data-rx2", x2000_i2s2_data_rx2, 2), + INGENIC_PIN_GROUP("i2s2-data-rx3", x2000_i2s2_data_rx3, 2), + INGENIC_PIN_GROUP("i2s2-clk-rx", x2000_i2s2_clk_rx, 2), + INGENIC_PIN_GROUP("i2s2-sysclk-rx", x2000_i2s2_sysclk_rx, 2), + INGENIC_PIN_GROUP("i2s3-data-tx0", x2000_i2s3_data_tx0, 2), + INGENIC_PIN_GROUP("i2s3-data-tx1", x2000_i2s3_data_tx1, 2), + INGENIC_PIN_GROUP("i2s3-data-tx2", x2000_i2s3_data_tx2, 2), + INGENIC_PIN_GROUP("i2s3-data-tx3", x2000_i2s3_data_tx3, 2), + INGENIC_PIN_GROUP("i2s3-clk-tx", x2000_i2s3_clk_tx, 2), + INGENIC_PIN_GROUP("i2s3-sysclk-tx", x2000_i2s3_sysclk_tx, 2), + INGENIC_PIN_GROUP("dmic0", x2000_dmic0, 0), + INGENIC_PIN_GROUP("dmic1", x2000_dmic1, 0), + INGENIC_PIN_GROUP("dmic2", x2000_dmic2, 0), + INGENIC_PIN_GROUP("dmic3", x2000_dmic3, 0), + INGENIC_PIN_GROUP_FUNCS("cim-data-8bit", x2000_cim_8bit, + x2000_cim_8bit_funcs), + INGENIC_PIN_GROUP("cim-data-12bit", x2000_cim_12bit, 0), + INGENIC_PIN_GROUP("lcd-tft-8bit", x2000_lcd_tft_8bit, 1), + INGENIC_PIN_GROUP("lcd-tft-16bit", x2000_lcd_tft_16bit, 1), + INGENIC_PIN_GROUP("lcd-tft-18bit", x2000_lcd_tft_18bit, 1), + INGENIC_PIN_GROUP("lcd-tft-24bit", x2000_lcd_tft_24bit, 1), + INGENIC_PIN_GROUP("lcd-slcd-8bit", x2000_lcd_slcd_8bit, 2), + INGENIC_PIN_GROUP("lcd-slcd-16bit", x2000_lcd_tft_16bit, 2), + INGENIC_PIN_GROUP("pwm0-c", x2000_pwm_pwm0_c, 0), + INGENIC_PIN_GROUP("pwm0-d", x2000_pwm_pwm0_d, 2), + INGENIC_PIN_GROUP("pwm1-c", x2000_pwm_pwm1_c, 0), + INGENIC_PIN_GROUP("pwm1-d", x2000_pwm_pwm1_d, 2), + INGENIC_PIN_GROUP("pwm2-c", x2000_pwm_pwm2_c, 0), + INGENIC_PIN_GROUP("pwm2-e", x2000_pwm_pwm2_e, 1), + INGENIC_PIN_GROUP("pwm3-c", x2000_pwm_pwm3_c, 0), + INGENIC_PIN_GROUP("pwm3-e", x2000_pwm_pwm3_e, 1), + INGENIC_PIN_GROUP("pwm4-c", x2000_pwm_pwm4_c, 0), + INGENIC_PIN_GROUP("pwm4-e", x2000_pwm_pwm4_e, 1), + INGENIC_PIN_GROUP("pwm5-c", x2000_pwm_pwm5_c, 0), + INGENIC_PIN_GROUP("pwm5-e", x2000_pwm_pwm5_e, 1), + INGENIC_PIN_GROUP("pwm6-c", x2000_pwm_pwm6_c, 0), + INGENIC_PIN_GROUP("pwm6-e", x2000_pwm_pwm6_e, 1), + INGENIC_PIN_GROUP("pwm7-c", x2000_pwm_pwm7_c, 0), + INGENIC_PIN_GROUP("pwm7-e", x2000_pwm_pwm7_e, 1), + INGENIC_PIN_GROUP("pwm8", x2000_pwm_pwm8, 0), + INGENIC_PIN_GROUP("pwm9", x2000_pwm_pwm9, 0), + INGENIC_PIN_GROUP("pwm10", x2000_pwm_pwm10, 0), + INGENIC_PIN_GROUP("pwm11", x2000_pwm_pwm11, 0), + INGENIC_PIN_GROUP("pwm12", x2000_pwm_pwm12, 0), + INGENIC_PIN_GROUP("pwm13", x2000_pwm_pwm13, 0), + INGENIC_PIN_GROUP("pwm14", x2000_pwm_pwm14, 0), + INGENIC_PIN_GROUP("pwm15", x2000_pwm_pwm15, 0), + INGENIC_PIN_GROUP("mac0-rmii", x2000_mac0_rmii, 1), + INGENIC_PIN_GROUP("mac0-rgmii", x2000_mac0_rgmii, 1), + INGENIC_PIN_GROUP("mac1-rmii", x2000_mac1_rmii, 3), + INGENIC_PIN_GROUP("mac1-rgmii", x2000_mac1_rgmii, 3), + INGENIC_PIN_GROUP("otg-vbus", x2000_otg, 0), +}; + +static const char *x2000_uart0_groups[] = { "uart0-data", "uart0-hwflow", }; +static const char *x2000_uart1_groups[] = { "uart1-data", "uart1-hwflow", }; +static const char *x2000_uart2_groups[] = { "uart2-data", }; +static const char *x2000_uart3_groups[] = { + "uart3-data-c", "uart3-data-d", "uart3-hwflow-c", "uart3-hwflow-d", +}; +static const char *x2000_uart4_groups[] = { + "uart4-data-a", "uart4-data-c", "uart4-hwflow-a", "uart4-hwflow-c", +}; +static const char *x2000_uart5_groups[] = { "uart5-data-a", "uart5-data-c", }; +static const char *x2000_uart6_groups[] = { "uart6-data-a", "uart6-data-c", }; +static const char *x2000_uart7_groups[] = { "uart7-data-a", "uart7-data-c", }; +static const char *x2000_uart8_groups[] = { "uart8-data", }; +static const char *x2000_uart9_groups[] = { "uart9-data", }; +static const char *x2000_sfc_groups[] = { "sfc0-d", "sfc0-e", "sfc1", }; +static const char *x2000_ssi0_groups[] = { + "ssi0-dt-b", "ssi0-dt-d", + "ssi0-dr-b", "ssi0-dr-d", + "ssi0-clk-b", "ssi0-clk-d", + "ssi0-ce0-b", "ssi0-ce0-d", +}; +static const char *x2000_ssi1_groups[] = { + "ssi1-dt-c", "ssi1-dt-d", "ssi1-dt-e", + "ssi1-dr-c", "ssi1-dr-d", "ssi1-dr-e", + "ssi1-clk-c", "ssi1-clk-d", "ssi1-clk-e", + "ssi1-ce0-c", "ssi1-ce0-d", "ssi1-ce0-e", +}; +static const char *x2000_mmc0_groups[] = { "mmc0-1bit", "mmc0-4bit", "mmc0-8bit", }; +static const char *x2000_mmc1_groups[] = { "mmc1-1bit", "mmc1-4bit", }; +static const char *x2000_mmc2_groups[] = { "mmc2-1bit", "mmc2-4bit", }; +static const char *x2000_emc_groups[] = { + "emc-8bit-data", "emc-16bit-data", + "emc-addr", "emc-rd-we", "emc-wait", +}; +static const char *x2000_cs1_groups[] = { "emc-cs1", }; +static const char *x2000_cs2_groups[] = { "emc-cs2", }; +static const char *x2000_i2c0_groups[] = { "i2c0-data", }; +static const char *x2000_i2c1_groups[] = { "i2c1-data-c", "i2c1-data-d", }; +static const char *x2000_i2c2_groups[] = { "i2c2-data-b", "i2c2-data-d", }; +static const char *x2000_i2c3_groups[] = { "i2c3-data-a", "i2c3-data-d", }; +static const char *x2000_i2c4_groups[] = { "i2c4-data-c", "i2c4-data-d", }; +static const char *x2000_i2c5_groups[] = { "i2c5-data-c", "i2c5-data-d", }; +static const char *x2000_i2s1_groups[] = { + "i2s1-data-tx", "i2s1-data-rx", + "i2s1-clk-tx", "i2s1-clk-rx", + "i2s1-sysclk-tx", "i2s1-sysclk-rx", +}; +static const char *x2000_i2s2_groups[] = { + "i2s2-data-rx0", "i2s2-data-rx1", "i2s2-data-rx2", "i2s2-data-rx3", + "i2s2-clk-rx", "i2s2-sysclk-rx", +}; +static const char *x2000_i2s3_groups[] = { + "i2s3-data-tx0", "i2s3-data-tx1", "i2s3-data-tx2", "i2s3-data-tx3", + "i2s3-clk-tx", "i2s3-sysclk-tx", +}; +static const char *x2000_dmic_groups[] = { "dmic0", "dmic1", "dmic2", "dmic3", }; +static const char *x2000_cim_groups[] = { "cim-data-8bit", "cim-data-12bit", }; +static const char *x2000_lcd_groups[] = { + "lcd-tft-8bit", "lcd-tft-16bit", "lcd-tft-18bit", "lcd-tft-24bit", + "lcd-slcd-8bit", "lcd-slcd-16bit", +}; +static const char *x2000_pwm0_groups[] = { "pwm0-c", "pwm0-d", }; +static const char *x2000_pwm1_groups[] = { "pwm1-c", "pwm1-d", }; +static const char *x2000_pwm2_groups[] = { "pwm2-c", "pwm2-e", }; +static const char *x2000_pwm3_groups[] = { "pwm3-c", "pwm3-r", }; +static const char *x2000_pwm4_groups[] = { "pwm4-c", "pwm4-e", }; +static const char *x2000_pwm5_groups[] = { "pwm5-c", "pwm5-e", }; +static const char *x2000_pwm6_groups[] = { "pwm6-c", "pwm6-e", }; +static const char *x2000_pwm7_groups[] = { "pwm7-c", "pwm7-e", }; +static const char *x2000_pwm8_groups[] = { "pwm8", }; +static const char *x2000_pwm9_groups[] = { "pwm9", }; +static const char *x2000_pwm10_groups[] = { "pwm10", }; +static const char *x2000_pwm11_groups[] = { "pwm11", }; +static const char *x2000_pwm12_groups[] = { "pwm12", }; +static const char *x2000_pwm13_groups[] = { "pwm13", }; +static const char *x2000_pwm14_groups[] = { "pwm14", }; +static const char *x2000_pwm15_groups[] = { "pwm15", }; +static const char *x2000_mac0_groups[] = { "mac0-rmii", "mac0-rgmii", }; +static const char *x2000_mac1_groups[] = { "mac1-rmii", "mac1-rgmii", }; +static const char *x2000_otg_groups[] = { "otg-vbus", }; + +static const struct function_desc x2000_functions[] = { + { "uart0", x2000_uart0_groups, ARRAY_SIZE(x2000_uart0_groups), }, + { "uart1", x2000_uart1_groups, ARRAY_SIZE(x2000_uart1_groups), }, + { "uart2", x2000_uart2_groups, ARRAY_SIZE(x2000_uart2_groups), }, + { "uart3", x2000_uart3_groups, ARRAY_SIZE(x2000_uart3_groups), }, + { "uart4", x2000_uart4_groups, ARRAY_SIZE(x2000_uart4_groups), }, + { "uart5", x2000_uart5_groups, ARRAY_SIZE(x2000_uart5_groups), }, + { "uart6", x2000_uart6_groups, ARRAY_SIZE(x2000_uart6_groups), }, + { "uart7", x2000_uart7_groups, ARRAY_SIZE(x2000_uart7_groups), }, + { "uart8", x2000_uart8_groups, ARRAY_SIZE(x2000_uart8_groups), }, + { "uart9", x2000_uart9_groups, ARRAY_SIZE(x2000_uart9_groups), }, + { "sfc", x2000_sfc_groups, ARRAY_SIZE(x2000_sfc_groups), }, + { "ssi0", x2000_ssi0_groups, ARRAY_SIZE(x2000_ssi0_groups), }, + { "ssi1", x2000_ssi1_groups, ARRAY_SIZE(x2000_ssi1_groups), }, + { "mmc0", x2000_mmc0_groups, ARRAY_SIZE(x2000_mmc0_groups), }, + { "mmc1", x2000_mmc1_groups, ARRAY_SIZE(x2000_mmc1_groups), }, + { "mmc2", x2000_mmc2_groups, ARRAY_SIZE(x2000_mmc2_groups), }, + { "emc", x2000_emc_groups, ARRAY_SIZE(x2000_emc_groups), }, + { "emc-cs1", x2000_cs1_groups, ARRAY_SIZE(x2000_cs1_groups), }, + { "emc-cs2", x2000_cs2_groups, ARRAY_SIZE(x2000_cs2_groups), }, + { "i2c0", x2000_i2c0_groups, ARRAY_SIZE(x2000_i2c0_groups), }, + { "i2c1", x2000_i2c1_groups, ARRAY_SIZE(x2000_i2c1_groups), }, + { "i2c2", x2000_i2c2_groups, ARRAY_SIZE(x2000_i2c2_groups), }, + { "i2c3", x2000_i2c3_groups, ARRAY_SIZE(x2000_i2c3_groups), }, + { "i2c4", x2000_i2c4_groups, ARRAY_SIZE(x2000_i2c4_groups), }, + { "i2c5", x2000_i2c5_groups, ARRAY_SIZE(x2000_i2c5_groups), }, + { "i2s1", x2000_i2s1_groups, ARRAY_SIZE(x2000_i2s1_groups), }, + { "i2s2", x2000_i2s2_groups, ARRAY_SIZE(x2000_i2s2_groups), }, + { "i2s3", x2000_i2s3_groups, ARRAY_SIZE(x2000_i2s3_groups), }, + { "dmic", x2000_dmic_groups, ARRAY_SIZE(x2000_dmic_groups), }, + { "cim", x2000_cim_groups, ARRAY_SIZE(x2000_cim_groups), }, + { "lcd", x2000_lcd_groups, ARRAY_SIZE(x2000_lcd_groups), }, + { "pwm0", x2000_pwm0_groups, ARRAY_SIZE(x2000_pwm0_groups), }, + { "pwm1", x2000_pwm1_groups, ARRAY_SIZE(x2000_pwm1_groups), }, + { "pwm2", x2000_pwm2_groups, ARRAY_SIZE(x2000_pwm2_groups), }, + { "pwm3", x2000_pwm3_groups, ARRAY_SIZE(x2000_pwm3_groups), }, + { "pwm4", x2000_pwm4_groups, ARRAY_SIZE(x2000_pwm4_groups), }, + { "pwm5", x2000_pwm5_groups, ARRAY_SIZE(x2000_pwm5_groups), }, + { "pwm6", x2000_pwm6_groups, ARRAY_SIZE(x2000_pwm6_groups), }, + { "pwm7", x2000_pwm7_groups, ARRAY_SIZE(x2000_pwm7_groups), }, + { "pwm8", x2000_pwm8_groups, ARRAY_SIZE(x2000_pwm8_groups), }, + { "pwm9", x2000_pwm9_groups, ARRAY_SIZE(x2000_pwm9_groups), }, + { "pwm10", x2000_pwm10_groups, ARRAY_SIZE(x2000_pwm10_groups), }, + { "pwm11", x2000_pwm11_groups, ARRAY_SIZE(x2000_pwm11_groups), }, + { "pwm12", x2000_pwm12_groups, ARRAY_SIZE(x2000_pwm12_groups), }, + { "pwm13", x2000_pwm13_groups, ARRAY_SIZE(x2000_pwm13_groups), }, + { "pwm14", x2000_pwm14_groups, ARRAY_SIZE(x2000_pwm14_groups), }, + { "pwm15", x2000_pwm15_groups, ARRAY_SIZE(x2000_pwm15_groups), }, + { "mac0", x2000_mac0_groups, ARRAY_SIZE(x2000_mac0_groups), }, + { "mac1", x2000_mac1_groups, ARRAY_SIZE(x2000_mac1_groups), }, + { "otg", x2000_otg_groups, ARRAY_SIZE(x2000_otg_groups), }, +}; + +static const struct ingenic_chip_info x2000_chip_info = { + .num_chips = 5, + .reg_offset = 0x100, + .version = ID_X2000, + .groups = x2000_groups, + .num_groups = ARRAY_SIZE(x2000_groups), + .functions = x2000_functions, + .num_functions = ARRAY_SIZE(x2000_functions), + .pull_ups = x2000_pull_ups, + .pull_downs = x2000_pull_downs, +}; + static u32 ingenic_gpio_read_reg(struct ingenic_gpio_chip *jzgc, u8 reg) { unsigned int val; @@ -2424,23 +2883,28 @@ static void irq_set_type(struct ingenic_gpio_chip *jzgc, u8 offset, unsigned int type) { u8 reg1, reg2; - bool val1, val2; + bool val1, val2, val3; switch (type) { + case IRQ_TYPE_EDGE_BOTH: + val1 = val2 = false; + val3 = true; + break; case IRQ_TYPE_EDGE_RISING: val1 = val2 = true; + val3 = false; break; case IRQ_TYPE_EDGE_FALLING: - val1 = false; + val1 = val3 = false; val2 = true; break; case IRQ_TYPE_LEVEL_HIGH: val1 = true; - val2 = false; + val2 = val3 = false; break; case IRQ_TYPE_LEVEL_LOW: default: - val1 = val2 = false; + val1 = val2 = val3 = false; break; } @@ -2457,7 +2921,12 @@ static void irq_set_type(struct ingenic_gpio_chip *jzgc, return; } - if (jzgc->jzpc->info->version >= ID_X1000) { + if (jzgc->jzpc->info->version >= ID_X2000) { + ingenic_gpio_shadow_set_bit(jzgc, reg2, offset, val1); + ingenic_gpio_shadow_set_bit(jzgc, reg1, offset, val2); + ingenic_gpio_shadow_set_bit_load(jzgc); + ingenic_gpio_set_bit(jzgc, X2000_GPIO_EDG, offset, val3); + } else if (jzgc->jzpc->info->version >= ID_X1000) { ingenic_gpio_shadow_set_bit(jzgc, reg2, offset, val1); ingenic_gpio_shadow_set_bit(jzgc, reg1, offset, val2); ingenic_gpio_shadow_set_bit_load(jzgc); @@ -2530,7 +2999,8 @@ static void ingenic_gpio_irq_ack(struct irq_data *irqd) int irq = irqd->hwirq; bool high; - if (irqd_get_trigger_type(irqd) == IRQ_TYPE_EDGE_BOTH) { + if ((irqd_get_trigger_type(irqd) == IRQ_TYPE_EDGE_BOTH) && + (jzgc->jzpc->info->version < ID_X2000)) { /* * Switch to an interrupt for the opposite edge to the one that * triggered the interrupt being ACKed. @@ -2569,7 +3039,7 @@ static int ingenic_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) irq_set_handler_locked(irqd, handle_bad_irq); } - if (type == IRQ_TYPE_EDGE_BOTH) { + if ((type == IRQ_TYPE_EDGE_BOTH) && (jzgc->jzpc->info->version < ID_X2000)) { /* * The hardware does not support interrupts on both edges. The * best we can do is to set up a single-edge interrupt and then @@ -2642,7 +3112,7 @@ static int ingenic_gpio_direction_output(struct gpio_chip *gc, } static inline void ingenic_config_pin(struct ingenic_pinctrl *jzpc, - unsigned int pin, u8 reg, bool set) + unsigned int pin, unsigned int reg, bool set) { unsigned int idx = pin % PINS_PER_GPIO_CHIP; unsigned int offt = pin / PINS_PER_GPIO_CHIP; @@ -2697,7 +3167,7 @@ static inline void jz4730_config_pin_function(struct ingenic_pinctrl *jzpc, } static inline bool ingenic_get_pin_config(struct ingenic_pinctrl *jzpc, - unsigned int pin, u8 reg) + unsigned int pin, unsigned int reg) { unsigned int idx = pin % PINS_PER_GPIO_CHIP; unsigned int offt = pin / PINS_PER_GPIO_CHIP; @@ -2876,10 +3346,19 @@ static int ingenic_pinconf_get(struct pinctrl_dev *pctldev, enum pin_config_param param = pinconf_to_config_param(*config); unsigned int idx = pin % PINS_PER_GPIO_CHIP; unsigned int offt = pin / PINS_PER_GPIO_CHIP; - unsigned int bias; + unsigned int arg = 1; + unsigned int bias, reg; bool pull, pullup, pulldown; - if (jzpc->info->version >= ID_X1830) { + if (jzpc->info->version >= ID_X2000) { + pullup = ingenic_get_pin_config(jzpc, pin, X2000_GPIO_PEPU) && + !ingenic_get_pin_config(jzpc, pin, X2000_GPIO_PEPD) && + (jzpc->info->pull_ups[offt] & BIT(idx)); + pulldown = ingenic_get_pin_config(jzpc, pin, X2000_GPIO_PEPD) && + !ingenic_get_pin_config(jzpc, pin, X2000_GPIO_PEPU) && + (jzpc->info->pull_downs[offt] & BIT(idx)); + + } else if (jzpc->info->version >= ID_X1830) { unsigned int half = PINS_PER_GPIO_CHIP / 2; unsigned int idxh = (pin % half) * 2; @@ -2911,30 +3390,73 @@ static int ingenic_pinconf_get(struct pinctrl_dev *pctldev, case PIN_CONFIG_BIAS_DISABLE: if (pullup || pulldown) return -EINVAL; + break; case PIN_CONFIG_BIAS_PULL_UP: if (!pullup) return -EINVAL; + break; case PIN_CONFIG_BIAS_PULL_DOWN: if (!pulldown) return -EINVAL; + + break; + + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + if (jzpc->info->version >= ID_X2000) + reg = X2000_GPIO_SMT; + else if (jzpc->info->version >= ID_X1830) + reg = X1830_GPIO_SMT; + else + return -EINVAL; + + arg = !!ingenic_get_pin_config(jzpc, pin, reg); + break; + + case PIN_CONFIG_SLEW_RATE: + if (jzpc->info->version >= ID_X2000) + reg = X2000_GPIO_SR; + else if (jzpc->info->version >= ID_X1830) + reg = X1830_GPIO_SR; + else + return -EINVAL; + + arg = !!ingenic_get_pin_config(jzpc, pin, reg); break; default: return -ENOTSUPP; } - *config = pinconf_to_config_packed(param, 1); + *config = pinconf_to_config_packed(param, arg); return 0; } static void ingenic_set_bias(struct ingenic_pinctrl *jzpc, unsigned int pin, unsigned int bias) { - if (jzpc->info->version >= ID_X1830) { + if (jzpc->info->version >= ID_X2000) { + switch (bias) { + case PIN_CONFIG_BIAS_PULL_UP: + ingenic_config_pin(jzpc, pin, X2000_GPIO_PEPD, false); + ingenic_config_pin(jzpc, pin, X2000_GPIO_PEPU, true); + break; + + case PIN_CONFIG_BIAS_PULL_DOWN: + ingenic_config_pin(jzpc, pin, X2000_GPIO_PEPU, false); + ingenic_config_pin(jzpc, pin, X2000_GPIO_PEPD, true); + break; + + case PIN_CONFIG_BIAS_DISABLE: + default: + ingenic_config_pin(jzpc, pin, X2000_GPIO_PEPU, false); + ingenic_config_pin(jzpc, pin, X2000_GPIO_PEPD, false); + } + + } else if (jzpc->info->version >= ID_X1830) { unsigned int idx = pin % PINS_PER_GPIO_CHIP; unsigned int half = PINS_PER_GPIO_CHIP / 2; unsigned int idxh = (pin % half) * 2; @@ -2961,6 +3483,15 @@ static void ingenic_set_bias(struct ingenic_pinctrl *jzpc, } } +static void ingenic_set_schmitt_trigger(struct ingenic_pinctrl *jzpc, + unsigned int pin, bool enable) +{ + if (jzpc->info->version >= ID_X2000) + ingenic_config_pin(jzpc, pin, X2000_GPIO_SMT, enable); + else + ingenic_config_pin(jzpc, pin, X1830_GPIO_SMT, enable); +} + static void ingenic_set_output_level(struct ingenic_pinctrl *jzpc, unsigned int pin, bool high) { @@ -2972,6 +3503,15 @@ static void ingenic_set_output_level(struct ingenic_pinctrl *jzpc, ingenic_config_pin(jzpc, pin, JZ4730_GPIO_DATA, high); } +static void ingenic_set_slew_rate(struct ingenic_pinctrl *jzpc, + unsigned int pin, unsigned int slew) +{ + if (jzpc->info->version >= ID_X2000) + ingenic_config_pin(jzpc, pin, X2000_GPIO_SR, slew); + else + ingenic_config_pin(jzpc, pin, X1830_GPIO_SR, slew); +} + static int ingenic_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, unsigned long *configs, unsigned int num_configs) { @@ -2986,7 +3526,9 @@ static int ingenic_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, case PIN_CONFIG_BIAS_DISABLE: case PIN_CONFIG_BIAS_PULL_UP: case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: case PIN_CONFIG_OUTPUT: + case PIN_CONFIG_SLEW_RATE: continue; default: return -ENOTSUPP; @@ -3019,6 +3561,13 @@ static int ingenic_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, ingenic_set_bias(jzpc, pin, GPIO_PULL_DOWN); break; + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + if (jzpc->info->version < ID_X1830) + return -EINVAL; + + ingenic_set_schmitt_trigger(jzpc, pin, arg); + break; + case PIN_CONFIG_OUTPUT: ret = pinctrl_gpio_direction_output(pin); if (ret) @@ -3027,6 +3576,13 @@ static int ingenic_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, ingenic_set_output_level(jzpc, pin, arg); break; + case PIN_CONFIG_SLEW_RATE: + if (jzpc->info->version < ID_X1830) + return -EINVAL; + + ingenic_set_slew_rate(jzpc, pin, arg); + break; + default: /* unreachable */ break; @@ -3109,6 +3665,7 @@ static const struct of_device_id ingenic_gpio_of_match[] __initconst = { { .compatible = "ingenic,jz4780-gpio", }, { .compatible = "ingenic,x1000-gpio", }, { .compatible = "ingenic,x1830-gpio", }, + { .compatible = "ingenic,x2000-gpio", }, {}, }; @@ -3181,6 +3738,7 @@ static int __init ingenic_gpio_probe(struct ingenic_pinctrl *jzpc, GFP_KERNEL); if (!girq->parents) return -ENOMEM; + girq->parents[0] = jzgc->irq; girq->default_type = IRQ_TYPE_NONE; girq->handler = handle_level_irq; @@ -3353,6 +3911,14 @@ static const struct of_device_id ingenic_pinctrl_of_match[] = { .compatible = "ingenic,x1830-pinctrl", .data = IF_ENABLED(CONFIG_MACH_X1830, &x1830_chip_info) }, + { + .compatible = "ingenic,x2000-pinctrl", + .data = IF_ENABLED(CONFIG_MACH_X2000, &x2000_chip_info) + }, + { + .compatible = "ingenic,x2000e-pinctrl", + .data = IF_ENABLED(CONFIG_MACH_X2000, &x2000_chip_info) + }, { /* sentinel */ }, }; -- cgit v1.2.3 From 7f7663899d9429476db74d8aceb042fe4a3756b7 Mon Sep 17 00:00:00 2001 From: Zhiyong Tao Date: Tue, 13 Apr 2021 13:56:59 +0800 Subject: dt-bindings: pinctrl: mt8195: add pinctrl file and binding document 1. This patch adds pinctrl file for mt8195. 2. This patch adds mt8195 compatible node in binding document. Signed-off-by: Zhiyong Tao Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210413055702.27535-2-zhiyong.tao@mediatek.com Signed-off-by: Linus Walleij --- .../bindings/pinctrl/pinctrl-mt8195.yaml | 151 ++++ include/dt-bindings/pinctrl/mt8195-pinfunc.h | 962 +++++++++++++++++++++ 2 files changed, 1113 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml create mode 100644 include/dt-bindings/pinctrl/mt8195-pinfunc.h diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml new file mode 100644 index 000000000000..2f12ec59eee5 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml @@ -0,0 +1,151 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/pinctrl-mt8195.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek MT8195 Pin Controller + +maintainers: + - Sean Wang + +description: | + The Mediatek's Pin controller is used to control SoC pins. + +properties: + compatible: + const: mediatek,mt8195-pinctrl + + gpio-controller: true + + '#gpio-cells': + description: | + Number of cells in GPIO specifier. Since the generic GPIO binding is used, + the amount of cells must be specified as 2. See the below + mentioned gpio binding representation for description of particular cells. + const: 2 + + gpio-ranges: + description: gpio valid number range. + maxItems: 1 + + reg: + description: | + Physical address base for gpio base registers. There are 8 GPIO + physical address base in mt8195. + maxItems: 8 + + reg-names: + description: | + Gpio base register names. + maxItems: 8 + + interrupt-controller: true + + '#interrupt-cells': + const: 2 + + interrupts: + description: The interrupt outputs to sysirq. + maxItems: 1 + +#PIN CONFIGURATION NODES +patternProperties: + '-pins$': + type: object + description: | + A pinctrl node should contain at least one subnodes representing the + pinctrl groups available on the machine. Each subnode will list the + pins it needs, and how they should be configured, with regard to muxer + configuration, pullups, drive strength, input enable/disable and + input schmitt. + An example of using macro: + pincontroller { + /* GPIO0 set as multifunction GPIO0 */ + gpio_pin { + pinmux = ; + }; + /* GPIO8 set as multifunction SDA0 */ + i2c0_pin { + pinmux = ; + }; + }; + $ref: "pinmux-node.yaml" + + properties: + pinmux: + description: | + Integer array, represents gpio pin number and mux setting. + Supported pin number and mux varies for different SoCs, and are defined + as macros in dt-bindings/pinctrl/-pinfunc.h directly. + + drive-strength: + description: | + It can support some arguments which is from 0 to 7. It can only support + 2/4/6/8/10/12/14/16mA in mt8195. + enum: [0, 1, 2, 3, 4, 5, 6, 7] + + bias-pull-down: true + + bias-pull-up: true + + bias-disable: true + + output-high: true + + output-low: true + + input-enable: true + + input-disable: true + + input-schmitt-enable: true + + input-schmitt-disable: true + + required: + - pinmux + + additionalProperties: false + +required: + - compatible + - reg + - interrupts + - interrupt-controller + - '#interrupt-cells' + - gpio-controller + - '#gpio-cells' + - gpio-ranges + +additionalProperties: false + +examples: + - | + #include + #include + pio: pinctrl@10005000 { + compatible = "mediatek,mt8195-pinctrl"; + reg = <0x10005000 0x1000>, + <0x11d10000 0x1000>, + <0x11d30000 0x1000>, + <0x11d40000 0x1000>, + <0x11e20000 0x1000>, + <0x11eb0000 0x1000>, + <0x11f40000 0x1000>, + <0x1000b000 0x1000>; + reg-names = "iocfg0", "iocfg_bm", "iocfg_bl", + "iocfg_br", "iocfg_lm", "iocfg_rb", + "iocfg_tl", "eint"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pio 0 0 144>; + interrupt-controller; + interrupts = ; + #interrupt-cells = <2>; + + pio-pins { + pinmux = ; + output-low; + }; + }; diff --git a/include/dt-bindings/pinctrl/mt8195-pinfunc.h b/include/dt-bindings/pinctrl/mt8195-pinfunc.h new file mode 100644 index 000000000000..666331bb9b40 --- /dev/null +++ b/include/dt-bindings/pinctrl/mt8195-pinfunc.h @@ -0,0 +1,962 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 MediaTek Inc. + * Author: Zhiyong Tao + */ + +#ifndef __MT8195_PINFUNC_H +#define __MT8195_PINFUNC_H + +#include "mt65xx.h" + +#define PINMUX_GPIO0__FUNC_GPIO0 (MTK_PIN_NO(0) | 0) +#define PINMUX_GPIO0__FUNC_TP_GPIO0_AO (MTK_PIN_NO(0) | 1) +#define PINMUX_GPIO0__FUNC_MSDC2_CMD (MTK_PIN_NO(0) | 2) +#define PINMUX_GPIO0__FUNC_TDMIN_MCK (MTK_PIN_NO(0) | 3) +#define PINMUX_GPIO0__FUNC_CLKM0 (MTK_PIN_NO(0) | 4) +#define PINMUX_GPIO0__FUNC_PERSTN_1 (MTK_PIN_NO(0) | 5) +#define PINMUX_GPIO0__FUNC_IDDIG_1P (MTK_PIN_NO(0) | 6) +#define PINMUX_GPIO0__FUNC_DMIC4_CLK (MTK_PIN_NO(0) | 7) + +#define PINMUX_GPIO1__FUNC_GPIO1 (MTK_PIN_NO(1) | 0) +#define PINMUX_GPIO1__FUNC_TP_GPIO1_AO (MTK_PIN_NO(1) | 1) +#define PINMUX_GPIO1__FUNC_MSDC2_CLK (MTK_PIN_NO(1) | 2) +#define PINMUX_GPIO1__FUNC_TDMIN_DI (MTK_PIN_NO(1) | 3) +#define PINMUX_GPIO1__FUNC_CLKM1 (MTK_PIN_NO(1) | 4) +#define PINMUX_GPIO1__FUNC_CLKREQN_1 (MTK_PIN_NO(1) | 5) +#define PINMUX_GPIO1__FUNC_USB_DRVVBUS_1P (MTK_PIN_NO(1) | 6) +#define PINMUX_GPIO1__FUNC_DMIC4_DAT (MTK_PIN_NO(1) | 7) + +#define PINMUX_GPIO2__FUNC_GPIO2 (MTK_PIN_NO(2) | 0) +#define PINMUX_GPIO2__FUNC_TP_GPIO2_AO (MTK_PIN_NO(2) | 1) +#define PINMUX_GPIO2__FUNC_MSDC2_DAT3 (MTK_PIN_NO(2) | 2) +#define PINMUX_GPIO2__FUNC_TDMIN_LRCK (MTK_PIN_NO(2) | 3) +#define PINMUX_GPIO2__FUNC_CLKM2 (MTK_PIN_NO(2) | 4) +#define PINMUX_GPIO2__FUNC_WAKEN_1 (MTK_PIN_NO(2) | 5) +#define PINMUX_GPIO2__FUNC_DMIC2_CLK (MTK_PIN_NO(2) | 7) + +#define PINMUX_GPIO3__FUNC_GPIO3 (MTK_PIN_NO(3) | 0) +#define PINMUX_GPIO3__FUNC_TP_GPIO3_AO (MTK_PIN_NO(3) | 1) +#define PINMUX_GPIO3__FUNC_MSDC2_DAT0 (MTK_PIN_NO(3) | 2) +#define PINMUX_GPIO3__FUNC_TDMIN_BCK (MTK_PIN_NO(3) | 3) +#define PINMUX_GPIO3__FUNC_CLKM3 (MTK_PIN_NO(3) | 4) +#define PINMUX_GPIO3__FUNC_DMIC2_DAT (MTK_PIN_NO(3) | 7) + +#define PINMUX_GPIO4__FUNC_GPIO4 (MTK_PIN_NO(4) | 0) +#define PINMUX_GPIO4__FUNC_TP_GPIO4_AO (MTK_PIN_NO(4) | 1) +#define PINMUX_GPIO4__FUNC_MSDC2_DAT2 (MTK_PIN_NO(4) | 2) +#define PINMUX_GPIO4__FUNC_SPDIF_IN1 (MTK_PIN_NO(4) | 3) +#define PINMUX_GPIO4__FUNC_UTXD3 (MTK_PIN_NO(4) | 4) +#define PINMUX_GPIO4__FUNC_SDA2 (MTK_PIN_NO(4) | 5) +#define PINMUX_GPIO4__FUNC_IDDIG_2P (MTK_PIN_NO(4) | 7) + +#define PINMUX_GPIO5__FUNC_GPIO5 (MTK_PIN_NO(5) | 0) +#define PINMUX_GPIO5__FUNC_TP_GPIO5_AO (MTK_PIN_NO(5) | 1) +#define PINMUX_GPIO5__FUNC_MSDC2_DAT1 (MTK_PIN_NO(5) | 2) +#define PINMUX_GPIO5__FUNC_SPDIF_IN0 (MTK_PIN_NO(5) | 3) +#define PINMUX_GPIO5__FUNC_URXD3 (MTK_PIN_NO(5) | 4) +#define PINMUX_GPIO5__FUNC_SCL2 (MTK_PIN_NO(5) | 5) +#define PINMUX_GPIO5__FUNC_USB_DRVVBUS_2P (MTK_PIN_NO(5) | 7) + +#define PINMUX_GPIO6__FUNC_GPIO6 (MTK_PIN_NO(6) | 0) +#define PINMUX_GPIO6__FUNC_TP_GPIO6_AO (MTK_PIN_NO(6) | 1) +#define PINMUX_GPIO6__FUNC_DP_TX_HPD (MTK_PIN_NO(6) | 2) +#define PINMUX_GPIO6__FUNC_I2SO1_D4 (MTK_PIN_NO(6) | 3) +#define PINMUX_GPIO6__FUNC_UTXD4 (MTK_PIN_NO(6) | 4) +#define PINMUX_GPIO6__FUNC_CMVREF3 (MTK_PIN_NO(6) | 5) +#define PINMUX_GPIO6__FUNC_DMIC3_CLK (MTK_PIN_NO(6) | 7) + +#define PINMUX_GPIO7__FUNC_GPIO7 (MTK_PIN_NO(7) | 0) +#define PINMUX_GPIO7__FUNC_TP_GPIO7_AO (MTK_PIN_NO(7) | 1) +#define PINMUX_GPIO7__FUNC_EDP_TX_HPD (MTK_PIN_NO(7) | 2) +#define PINMUX_GPIO7__FUNC_I2SO1_D5 (MTK_PIN_NO(7) | 3) +#define PINMUX_GPIO7__FUNC_URXD4 (MTK_PIN_NO(7) | 4) +#define PINMUX_GPIO7__FUNC_CMVREF4 (MTK_PIN_NO(7) | 5) +#define PINMUX_GPIO7__FUNC_DMIC3_DAT (MTK_PIN_NO(7) | 7) + +#define PINMUX_GPIO8__FUNC_GPIO8 (MTK_PIN_NO(8) | 0) +#define PINMUX_GPIO8__FUNC_SDA0 (MTK_PIN_NO(8) | 1) +#define PINMUX_GPIO8__FUNC_PWM_0 (MTK_PIN_NO(8) | 2) +#define PINMUX_GPIO8__FUNC_SPDIF_OUT (MTK_PIN_NO(8) | 4) +#define PINMUX_GPIO8__FUNC_LVTS_FOUT (MTK_PIN_NO(8) | 6) +#define PINMUX_GPIO8__FUNC_DBG_MON_A0 (MTK_PIN_NO(8) | 7) + +#define PINMUX_GPIO9__FUNC_GPIO9 (MTK_PIN_NO(9) | 0) +#define PINMUX_GPIO9__FUNC_SCL0 (MTK_PIN_NO(9) | 1) +#define PINMUX_GPIO9__FUNC_PWM_1 (MTK_PIN_NO(9) | 2) +#define PINMUX_GPIO9__FUNC_IR_IN (MTK_PIN_NO(9) | 4) +#define PINMUX_GPIO9__FUNC_LVTS_SDO (MTK_PIN_NO(9) | 6) +#define PINMUX_GPIO9__FUNC_DBG_MON_A1 (MTK_PIN_NO(9) | 7) + +#define PINMUX_GPIO10__FUNC_GPIO10 (MTK_PIN_NO(10) | 0) +#define PINMUX_GPIO10__FUNC_SDA1 (MTK_PIN_NO(10) | 1) +#define PINMUX_GPIO10__FUNC_PWM_2 (MTK_PIN_NO(10) | 2) +#define PINMUX_GPIO10__FUNC_ADSP_URXD0 (MTK_PIN_NO(10) | 3) +#define PINMUX_GPIO10__FUNC_SPDIF_IN1 (MTK_PIN_NO(10) | 4) +#define PINMUX_GPIO10__FUNC_LVTS_SCF (MTK_PIN_NO(10) | 6) +#define PINMUX_GPIO10__FUNC_DBG_MON_A2 (MTK_PIN_NO(10) | 7) + +#define PINMUX_GPIO11__FUNC_GPIO11 (MTK_PIN_NO(11) | 0) +#define PINMUX_GPIO11__FUNC_SCL1 (MTK_PIN_NO(11) | 1) +#define PINMUX_GPIO11__FUNC_PWM_3 (MTK_PIN_NO(11) | 2) +#define PINMUX_GPIO11__FUNC_ADSP_UTXD0 (MTK_PIN_NO(11) | 3) +#define PINMUX_GPIO11__FUNC_SPDIF_IN0 (MTK_PIN_NO(11) | 4) +#define PINMUX_GPIO11__FUNC_LVTS_SCK (MTK_PIN_NO(11) | 6) +#define PINMUX_GPIO11__FUNC_DBG_MON_A3 (MTK_PIN_NO(11) | 7) + +#define PINMUX_GPIO12__FUNC_GPIO12 (MTK_PIN_NO(12) | 0) +#define PINMUX_GPIO12__FUNC_SDA2 (MTK_PIN_NO(12) | 1) +#define PINMUX_GPIO12__FUNC_DMIC3_DAT_R (MTK_PIN_NO(12) | 2) +#define PINMUX_GPIO12__FUNC_I2SO1_D6 (MTK_PIN_NO(12) | 3) +#define PINMUX_GPIO12__FUNC_LVTS_SDI (MTK_PIN_NO(12) | 6) +#define PINMUX_GPIO12__FUNC_DBG_MON_A4 (MTK_PIN_NO(12) | 7) + +#define PINMUX_GPIO13__FUNC_GPIO13 (MTK_PIN_NO(13) | 0) +#define PINMUX_GPIO13__FUNC_SCL2 (MTK_PIN_NO(13) | 1) +#define PINMUX_GPIO13__FUNC_DMIC4_DAT_R (MTK_PIN_NO(13) | 2) +#define PINMUX_GPIO13__FUNC_I2SO1_D7 (MTK_PIN_NO(13) | 3) +#define PINMUX_GPIO13__FUNC_DBG_MON_A5 (MTK_PIN_NO(13) | 7) + +#define PINMUX_GPIO14__FUNC_GPIO14 (MTK_PIN_NO(14) | 0) +#define PINMUX_GPIO14__FUNC_SDA3 (MTK_PIN_NO(14) | 1) +#define PINMUX_GPIO14__FUNC_DMIC3_DAT (MTK_PIN_NO(14) | 2) +#define PINMUX_GPIO14__FUNC_TDMIN_MCK (MTK_PIN_NO(14) | 3) +#define PINMUX_GPIO14__FUNC_DBG_MON_A6 (MTK_PIN_NO(14) | 7) + +#define PINMUX_GPIO15__FUNC_GPIO15 (MTK_PIN_NO(15) | 0) +#define PINMUX_GPIO15__FUNC_SCL3 (MTK_PIN_NO(15) | 1) +#define PINMUX_GPIO15__FUNC_DMIC3_CLK (MTK_PIN_NO(15) | 2) +#define PINMUX_GPIO15__FUNC_TDMIN_DI (MTK_PIN_NO(15) | 3) +#define PINMUX_GPIO15__FUNC_DBG_MON_A7 (MTK_PIN_NO(15) | 7) + +#define PINMUX_GPIO16__FUNC_GPIO16 (MTK_PIN_NO(16) | 0) +#define PINMUX_GPIO16__FUNC_SDA4 (MTK_PIN_NO(16) | 1) +#define PINMUX_GPIO16__FUNC_DMIC4_DAT (MTK_PIN_NO(16) | 2) +#define PINMUX_GPIO16__FUNC_TDMIN_LRCK (MTK_PIN_NO(16) | 3) +#define PINMUX_GPIO16__FUNC_DBG_MON_A8 (MTK_PIN_NO(16) | 7) + +#define PINMUX_GPIO17__FUNC_GPIO17 (MTK_PIN_NO(17) | 0) +#define PINMUX_GPIO17__FUNC_SCL4 (MTK_PIN_NO(17) | 1) +#define PINMUX_GPIO17__FUNC_DMIC4_CLK (MTK_PIN_NO(17) | 2) +#define PINMUX_GPIO17__FUNC_TDMIN_BCK (MTK_PIN_NO(17) | 3) +#define PINMUX_GPIO17__FUNC_DBG_MON_A9 (MTK_PIN_NO(17) | 7) + +#define PINMUX_GPIO18__FUNC_GPIO18 (MTK_PIN_NO(18) | 0) +#define PINMUX_GPIO18__FUNC_DP_TX_HPD (MTK_PIN_NO(18) | 1) + +#define PINMUX_GPIO19__FUNC_GPIO19 (MTK_PIN_NO(19) | 0) +#define PINMUX_GPIO19__FUNC_WAKEN (MTK_PIN_NO(19) | 1) +#define PINMUX_GPIO19__FUNC_SCP_SDA1 (MTK_PIN_NO(19) | 2) +#define PINMUX_GPIO19__FUNC_MD32_0_JTAG_TCK (MTK_PIN_NO(19) | 3) +#define PINMUX_GPIO19__FUNC_ADSP_JTAG0_TCK (MTK_PIN_NO(19) | 4) +#define PINMUX_GPIO19__FUNC_SDA6 (MTK_PIN_NO(19) | 5) + +#define PINMUX_GPIO20__FUNC_GPIO20 (MTK_PIN_NO(20) | 0) +#define PINMUX_GPIO20__FUNC_PERSTN (MTK_PIN_NO(20) | 1) +#define PINMUX_GPIO20__FUNC_SCP_SCL1 (MTK_PIN_NO(20) | 2) +#define PINMUX_GPIO20__FUNC_MD32_0_JTAG_TMS (MTK_PIN_NO(20) | 3) +#define PINMUX_GPIO20__FUNC_ADSP_JTAG0_TMS (MTK_PIN_NO(20) | 4) +#define PINMUX_GPIO20__FUNC_SCL6 (MTK_PIN_NO(20) | 5) + +#define PINMUX_GPIO21__FUNC_GPIO21 (MTK_PIN_NO(21) | 0) +#define PINMUX_GPIO21__FUNC_CLKREQN (MTK_PIN_NO(21) | 1) +#define PINMUX_GPIO21__FUNC_MD32_0_JTAG_TDI (MTK_PIN_NO(21) | 3) +#define PINMUX_GPIO21__FUNC_ADSP_JTAG0_TDI (MTK_PIN_NO(21) | 4) +#define PINMUX_GPIO21__FUNC_SCP_SDA1 (MTK_PIN_NO(21) | 5) + +#define PINMUX_GPIO22__FUNC_GPIO22 (MTK_PIN_NO(22) | 0) +#define PINMUX_GPIO22__FUNC_CMMCLK0 (MTK_PIN_NO(22) | 1) +#define PINMUX_GPIO22__FUNC_PERSTN_1 (MTK_PIN_NO(22) | 2) +#define PINMUX_GPIO22__FUNC_SCP_SCL1 (MTK_PIN_NO(22) | 5) +#define PINMUX_GPIO22__FUNC_MD32_0_GPIO0 (MTK_PIN_NO(22) | 7) + +#define PINMUX_GPIO23__FUNC_GPIO23 (MTK_PIN_NO(23) | 0) +#define PINMUX_GPIO23__FUNC_CMMCLK1 (MTK_PIN_NO(23) | 1) +#define PINMUX_GPIO23__FUNC_CLKREQN_1 (MTK_PIN_NO(23) | 2) +#define PINMUX_GPIO23__FUNC_SDA4 (MTK_PIN_NO(23) | 3) +#define PINMUX_GPIO23__FUNC_DMIC1_CLK (MTK_PIN_NO(23) | 4) +#define PINMUX_GPIO23__FUNC_SCP_SDA0 (MTK_PIN_NO(23) | 5) +#define PINMUX_GPIO23__FUNC_MD32_0_GPIO1 (MTK_PIN_NO(23) | 7) + +#define PINMUX_GPIO24__FUNC_GPIO24 (MTK_PIN_NO(24) | 0) +#define PINMUX_GPIO24__FUNC_CMMCLK2 (MTK_PIN_NO(24) | 1) +#define PINMUX_GPIO24__FUNC_WAKEN_1 (MTK_PIN_NO(24) | 2) +#define PINMUX_GPIO24__FUNC_SCL4 (MTK_PIN_NO(24) | 3) +#define PINMUX_GPIO24__FUNC_DMIC1_DAT (MTK_PIN_NO(24) | 4) +#define PINMUX_GPIO24__FUNC_SCP_SCL0 (MTK_PIN_NO(24) | 5) +#define PINMUX_GPIO24__FUNC_LVTS_26M (MTK_PIN_NO(24) | 6) +#define PINMUX_GPIO24__FUNC_MD32_0_GPIO2 (MTK_PIN_NO(24) | 7) + +#define PINMUX_GPIO25__FUNC_GPIO25 (MTK_PIN_NO(25) | 0) +#define PINMUX_GPIO25__FUNC_CMMRST (MTK_PIN_NO(25) | 1) +#define PINMUX_GPIO25__FUNC_CMMCLK3 (MTK_PIN_NO(25) | 2) +#define PINMUX_GPIO25__FUNC_SPDIF_OUT (MTK_PIN_NO(25) | 3) +#define PINMUX_GPIO25__FUNC_SDA6 (MTK_PIN_NO(25) | 4) +#define PINMUX_GPIO25__FUNC_ADSP_JTAG0_TRSTN (MTK_PIN_NO(25) | 5) +#define PINMUX_GPIO25__FUNC_MD32_0_JTAG_TRST (MTK_PIN_NO(25) | 6) + +#define PINMUX_GPIO26__FUNC_GPIO26 (MTK_PIN_NO(26) | 0) +#define PINMUX_GPIO26__FUNC_CMMPDN (MTK_PIN_NO(26) | 1) +#define PINMUX_GPIO26__FUNC_CMMCLK4 (MTK_PIN_NO(26) | 2) +#define PINMUX_GPIO26__FUNC_IR_IN (MTK_PIN_NO(26) | 3) +#define PINMUX_GPIO26__FUNC_SCL6 (MTK_PIN_NO(26) | 4) +#define PINMUX_GPIO26__FUNC_ADSP_JTAG0_TDO (MTK_PIN_NO(26) | 5) +#define PINMUX_GPIO26__FUNC_MD32_0_JTAG_TDO (MTK_PIN_NO(26) | 6) + +#define PINMUX_GPIO27__FUNC_GPIO27 (MTK_PIN_NO(27) | 0) +#define PINMUX_GPIO27__FUNC_HDMIRX20_HTPLG (MTK_PIN_NO(27) | 1) +#define PINMUX_GPIO27__FUNC_CMFLASH0 (MTK_PIN_NO(27) | 2) +#define PINMUX_GPIO27__FUNC_MD32_0_TXD (MTK_PIN_NO(27) | 3) +#define PINMUX_GPIO27__FUNC_TP_UTXD2_AO (MTK_PIN_NO(27) | 4) +#define PINMUX_GPIO27__FUNC_SCL7 (MTK_PIN_NO(27) | 5) +#define PINMUX_GPIO27__FUNC_UCTS2 (MTK_PIN_NO(27) | 6) +#define PINMUX_GPIO27__FUNC_DBG_MON_A18 (MTK_PIN_NO(27) | 7) + +#define PINMUX_GPIO28__FUNC_GPIO28 (MTK_PIN_NO(28) | 0) +#define PINMUX_GPIO28__FUNC_HDMIRX20_PWR5V (MTK_PIN_NO(28) | 1) +#define PINMUX_GPIO28__FUNC_CMFLASH1 (MTK_PIN_NO(28) | 2) +#define PINMUX_GPIO28__FUNC_MD32_0_RXD (MTK_PIN_NO(28) | 3) +#define PINMUX_GPIO28__FUNC_TP_URXD2_AO (MTK_PIN_NO(28) | 4) +#define PINMUX_GPIO28__FUNC_SDA7 (MTK_PIN_NO(28) | 5) +#define PINMUX_GPIO28__FUNC_URTS2 (MTK_PIN_NO(28) | 6) +#define PINMUX_GPIO28__FUNC_DBG_MON_A19 (MTK_PIN_NO(28) | 7) + +#define PINMUX_GPIO29__FUNC_GPIO29 (MTK_PIN_NO(29) | 0) +#define PINMUX_GPIO29__FUNC_HDMIRX20_SCL (MTK_PIN_NO(29) | 1) +#define PINMUX_GPIO29__FUNC_CMFLASH2 (MTK_PIN_NO(29) | 2) +#define PINMUX_GPIO29__FUNC_SCL5 (MTK_PIN_NO(29) | 3) +#define PINMUX_GPIO29__FUNC_TP_URTS2_AO (MTK_PIN_NO(29) | 4) +#define PINMUX_GPIO29__FUNC_UTXD2 (MTK_PIN_NO(29) | 6) +#define PINMUX_GPIO29__FUNC_DBG_MON_A20 (MTK_PIN_NO(29) | 7) + +#define PINMUX_GPIO30__FUNC_GPIO30 (MTK_PIN_NO(30) | 0) +#define PINMUX_GPIO30__FUNC_HDMIRX20_SDA (MTK_PIN_NO(30) | 1) +#define PINMUX_GPIO30__FUNC_CMFLASH3 (MTK_PIN_NO(30) | 2) +#define PINMUX_GPIO30__FUNC_SDA5 (MTK_PIN_NO(30) | 3) +#define PINMUX_GPIO30__FUNC_TP_UCTS2_AO (MTK_PIN_NO(30) | 4) +#define PINMUX_GPIO30__FUNC_URXD2 (MTK_PIN_NO(30) | 6) +#define PINMUX_GPIO30__FUNC_DBG_MON_A21 (MTK_PIN_NO(30) | 7) + +#define PINMUX_GPIO31__FUNC_GPIO31 (MTK_PIN_NO(31) | 0) +#define PINMUX_GPIO31__FUNC_HDMITX20_PWR5V (MTK_PIN_NO(31) | 1) +#define PINMUX_GPIO31__FUNC_DMIC1_DAT_R (MTK_PIN_NO(31) | 2) +#define PINMUX_GPIO31__FUNC_PERSTN (MTK_PIN_NO(31) | 3) +#define PINMUX_GPIO31__FUNC_DBG_MON_A22 (MTK_PIN_NO(31) | 7) + +#define PINMUX_GPIO32__FUNC_GPIO32 (MTK_PIN_NO(32) | 0) +#define PINMUX_GPIO32__FUNC_HDMITX20_HTPLG (MTK_PIN_NO(32) | 1) +#define PINMUX_GPIO32__FUNC_CLKREQN (MTK_PIN_NO(32) | 3) +#define PINMUX_GPIO32__FUNC_DBG_MON_A23 (MTK_PIN_NO(32) | 7) + +#define PINMUX_GPIO33__FUNC_GPIO33 (MTK_PIN_NO(33) | 0) +#define PINMUX_GPIO33__FUNC_HDMITX20_CEC (MTK_PIN_NO(33) | 1) +#define PINMUX_GPIO33__FUNC_CMVREF0 (MTK_PIN_NO(33) | 2) +#define PINMUX_GPIO33__FUNC_WAKEN (MTK_PIN_NO(33) | 3) + +#define PINMUX_GPIO34__FUNC_GPIO34 (MTK_PIN_NO(34) | 0) +#define PINMUX_GPIO34__FUNC_HDMITX20_SCL (MTK_PIN_NO(34) | 1) +#define PINMUX_GPIO34__FUNC_CMVREF1 (MTK_PIN_NO(34) | 2) +#define PINMUX_GPIO34__FUNC_SCL7 (MTK_PIN_NO(34) | 3) +#define PINMUX_GPIO34__FUNC_SCL6 (MTK_PIN_NO(34) | 4) +#define PINMUX_GPIO34__FUNC_DBG_MON_A24 (MTK_PIN_NO(34) | 7) + +#define PINMUX_GPIO35__FUNC_GPIO35 (MTK_PIN_NO(35) | 0) +#define PINMUX_GPIO35__FUNC_HDMITX20_SDA (MTK_PIN_NO(35) | 1) +#define PINMUX_GPIO35__FUNC_CMVREF2 (MTK_PIN_NO(35) | 2) +#define PINMUX_GPIO35__FUNC_SDA7 (MTK_PIN_NO(35) | 3) +#define PINMUX_GPIO35__FUNC_SDA6 (MTK_PIN_NO(35) | 4) +#define PINMUX_GPIO35__FUNC_DBG_MON_A25 (MTK_PIN_NO(35) | 7) + +#define PINMUX_GPIO36__FUNC_GPIO36 (MTK_PIN_NO(36) | 0) +#define PINMUX_GPIO36__FUNC_RTC32K_CK (MTK_PIN_NO(36) | 1) +#define PINMUX_GPIO36__FUNC_DBG_MON_A27 (MTK_PIN_NO(36) | 7) + +#define PINMUX_GPIO37__FUNC_GPIO37 (MTK_PIN_NO(37) | 0) +#define PINMUX_GPIO37__FUNC_WATCHDOG (MTK_PIN_NO(37) | 1) +#define PINMUX_GPIO37__FUNC_DBG_MON_A28 (MTK_PIN_NO(37) | 7) + +#define PINMUX_GPIO38__FUNC_GPIO38 (MTK_PIN_NO(38) | 0) +#define PINMUX_GPIO38__FUNC_SRCLKENA0 (MTK_PIN_NO(38) | 1) +#define PINMUX_GPIO38__FUNC_DBG_MON_A29 (MTK_PIN_NO(38) | 7) + +#define PINMUX_GPIO39__FUNC_GPIO39 (MTK_PIN_NO(39) | 0) +#define PINMUX_GPIO39__FUNC_SRCLKENA1 (MTK_PIN_NO(39) | 1) +#define PINMUX_GPIO39__FUNC_DMIC2_DAT_R (MTK_PIN_NO(39) | 2) +#define PINMUX_GPIO39__FUNC_DBG_MON_A30 (MTK_PIN_NO(39) | 7) + +#define PINMUX_GPIO40__FUNC_GPIO40 (MTK_PIN_NO(40) | 0) +#define PINMUX_GPIO40__FUNC_PWRAP_SPI0_CSN (MTK_PIN_NO(40) | 1) +#define PINMUX_GPIO40__FUNC_SPIM3_CSB (MTK_PIN_NO(40) | 3) +#define PINMUX_GPIO40__FUNC_DBG_MON_A31 (MTK_PIN_NO(40) | 7) + +#define PINMUX_GPIO41__FUNC_GPIO41 (MTK_PIN_NO(41) | 0) +#define PINMUX_GPIO41__FUNC_PWRAP_SPI0_CK (MTK_PIN_NO(41) | 1) +#define PINMUX_GPIO41__FUNC_SPIM3_CLK (MTK_PIN_NO(41) | 3) +#define PINMUX_GPIO41__FUNC_DBG_MON_A32 (MTK_PIN_NO(41) | 7) + +#define PINMUX_GPIO42__FUNC_GPIO42 (MTK_PIN_NO(42) | 0) +#define PINMUX_GPIO42__FUNC_PWRAP_SPI0_MO (MTK_PIN_NO(42) | 1) +#define PINMUX_GPIO42__FUNC_PWRAP_SPI0_MI (MTK_PIN_NO(42) | 2) +#define PINMUX_GPIO42__FUNC_SPIM3_MO (MTK_PIN_NO(42) | 3) +#define PINMUX_GPIO42__FUNC_DBG_MON_B0 (MTK_PIN_NO(42) | 7) + +#define PINMUX_GPIO43__FUNC_GPIO43 (MTK_PIN_NO(43) | 0) +#define PINMUX_GPIO43__FUNC_PWRAP_SPI0_MI (MTK_PIN_NO(43) | 1) +#define PINMUX_GPIO43__FUNC_PWRAP_SPI0_MO (MTK_PIN_NO(43) | 2) +#define PINMUX_GPIO43__FUNC_SPIM3_MI (MTK_PIN_NO(43) | 3) +#define PINMUX_GPIO43__FUNC_DBG_MON_B1 (MTK_PIN_NO(43) | 7) + +#define PINMUX_GPIO44__FUNC_GPIO44 (MTK_PIN_NO(44) | 0) +#define PINMUX_GPIO44__FUNC_SPMI_M_SCL (MTK_PIN_NO(44) | 1) +#define PINMUX_GPIO44__FUNC_I2SI00_DATA1 (MTK_PIN_NO(44) | 2) +#define PINMUX_GPIO44__FUNC_SCL5 (MTK_PIN_NO(44) | 3) +#define PINMUX_GPIO44__FUNC_UTXD5 (MTK_PIN_NO(44) | 4) +#define PINMUX_GPIO44__FUNC_DBG_MON_B2 (MTK_PIN_NO(44) | 7) + +#define PINMUX_GPIO45__FUNC_GPIO45 (MTK_PIN_NO(45) | 0) +#define PINMUX_GPIO45__FUNC_SPMI_M_SDA (MTK_PIN_NO(45) | 1) +#define PINMUX_GPIO45__FUNC_I2SI00_DATA2 (MTK_PIN_NO(45) | 2) +#define PINMUX_GPIO45__FUNC_SDA5 (MTK_PIN_NO(45) | 3) +#define PINMUX_GPIO45__FUNC_URXD5 (MTK_PIN_NO(45) | 4) +#define PINMUX_GPIO45__FUNC_DBG_MON_B3 (MTK_PIN_NO(45) | 7) + +#define PINMUX_GPIO46__FUNC_GPIO46 (MTK_PIN_NO(46) | 0) +#define PINMUX_GPIO46__FUNC_I2SIN_MCK (MTK_PIN_NO(46) | 1) +#define PINMUX_GPIO46__FUNC_I2SI00_DATA3 (MTK_PIN_NO(46) | 2) +#define PINMUX_GPIO46__FUNC_SPLIN_MCK (MTK_PIN_NO(46) | 3) +#define PINMUX_GPIO46__FUNC_DBG_MON_B4 (MTK_PIN_NO(46) | 7) + +#define PINMUX_GPIO47__FUNC_GPIO47 (MTK_PIN_NO(47) | 0) +#define PINMUX_GPIO47__FUNC_I2SIN_BCK (MTK_PIN_NO(47) | 1) +#define PINMUX_GPIO47__FUNC_I2SIN0_BCK (MTK_PIN_NO(47) | 2) +#define PINMUX_GPIO47__FUNC_SPLIN_LRCK (MTK_PIN_NO(47) | 3) +#define PINMUX_GPIO47__FUNC_DBG_MON_B5 (MTK_PIN_NO(47) | 7) + +#define PINMUX_GPIO48__FUNC_GPIO48 (MTK_PIN_NO(48) | 0) +#define PINMUX_GPIO48__FUNC_I2SIN_WS (MTK_PIN_NO(48) | 1) +#define PINMUX_GPIO48__FUNC_I2SIN0_LRCK (MTK_PIN_NO(48) | 2) +#define PINMUX_GPIO48__FUNC_SPLIN_BCK (MTK_PIN_NO(48) | 3) +#define PINMUX_GPIO48__FUNC_DBG_MON_B6 (MTK_PIN_NO(48) | 7) + +#define PINMUX_GPIO49__FUNC_GPIO49 (MTK_PIN_NO(49) | 0) +#define PINMUX_GPIO49__FUNC_I2SIN_D0 (MTK_PIN_NO(49) | 1) +#define PINMUX_GPIO49__FUNC_I2SI00_DATA0 (MTK_PIN_NO(49) | 2) +#define PINMUX_GPIO49__FUNC_SPLIN_D0 (MTK_PIN_NO(49) | 3) +#define PINMUX_GPIO49__FUNC_DBG_MON_B7 (MTK_PIN_NO(49) | 7) + +#define PINMUX_GPIO50__FUNC_GPIO50 (MTK_PIN_NO(50) | 0) +#define PINMUX_GPIO50__FUNC_I2SO1_MCK (MTK_PIN_NO(50) | 1) +#define PINMUX_GPIO50__FUNC_I2SI5_D0 (MTK_PIN_NO(50) | 2) +#define PINMUX_GPIO50__FUNC_I2SO4_MCK (MTK_PIN_NO(50) | 4) +#define PINMUX_GPIO50__FUNC_DBG_MON_B8 (MTK_PIN_NO(50) | 7) + +#define PINMUX_GPIO51__FUNC_GPIO51 (MTK_PIN_NO(51) | 0) +#define PINMUX_GPIO51__FUNC_I2SO1_BCK (MTK_PIN_NO(51) | 1) +#define PINMUX_GPIO51__FUNC_I2SI5_BCK (MTK_PIN_NO(51) | 2) +#define PINMUX_GPIO51__FUNC_DBG_MON_B9 (MTK_PIN_NO(51) | 7) + +#define PINMUX_GPIO52__FUNC_GPIO52 (MTK_PIN_NO(52) | 0) +#define PINMUX_GPIO52__FUNC_I2SO1_WS (MTK_PIN_NO(52) | 1) +#define PINMUX_GPIO52__FUNC_I2SI5_WS (MTK_PIN_NO(52) | 2) +#define PINMUX_GPIO52__FUNC_DBG_MON_B10 (MTK_PIN_NO(52) | 7) + +#define PINMUX_GPIO53__FUNC_GPIO53 (MTK_PIN_NO(53) | 0) +#define PINMUX_GPIO53__FUNC_I2SO1_D0 (MTK_PIN_NO(53) | 1) +#define PINMUX_GPIO53__FUNC_I2SI5_MCK (MTK_PIN_NO(53) | 2) +#define PINMUX_GPIO53__FUNC_DBG_MON_B11 (MTK_PIN_NO(53) | 7) + +#define PINMUX_GPIO54__FUNC_GPIO54 (MTK_PIN_NO(54) | 0) +#define PINMUX_GPIO54__FUNC_I2SO1_D1 (MTK_PIN_NO(54) | 1) +#define PINMUX_GPIO54__FUNC_I2SI01_DATA1 (MTK_PIN_NO(54) | 2) +#define PINMUX_GPIO54__FUNC_SPLIN_D1 (MTK_PIN_NO(54) | 3) +#define PINMUX_GPIO54__FUNC_I2SO4_BCK (MTK_PIN_NO(54) | 4) +#define PINMUX_GPIO54__FUNC_DBG_MON_B12 (MTK_PIN_NO(54) | 7) + +#define PINMUX_GPIO55__FUNC_GPIO55 (MTK_PIN_NO(55) | 0) +#define PINMUX_GPIO55__FUNC_I2SO1_D2 (MTK_PIN_NO(55) | 1) +#define PINMUX_GPIO55__FUNC_I2SI01_DATA2 (MTK_PIN_NO(55) | 2) +#define PINMUX_GPIO55__FUNC_SPLIN_D2 (MTK_PIN_NO(55) | 3) +#define PINMUX_GPIO55__FUNC_I2SO4_WS (MTK_PIN_NO(55) | 4) +#define PINMUX_GPIO55__FUNC_DBG_MON_B13 (MTK_PIN_NO(55) | 7) + +#define PINMUX_GPIO56__FUNC_GPIO56 (MTK_PIN_NO(56) | 0) +#define PINMUX_GPIO56__FUNC_I2SO1_D3 (MTK_PIN_NO(56) | 1) +#define PINMUX_GPIO56__FUNC_I2SI01_DATA3 (MTK_PIN_NO(56) | 2) +#define PINMUX_GPIO56__FUNC_SPLIN_D3 (MTK_PIN_NO(56) | 3) +#define PINMUX_GPIO56__FUNC_I2SO4_D0 (MTK_PIN_NO(56) | 4) +#define PINMUX_GPIO56__FUNC_DBG_MON_B14 (MTK_PIN_NO(56) | 7) + +#define PINMUX_GPIO57__FUNC_GPIO57 (MTK_PIN_NO(57) | 0) +#define PINMUX_GPIO57__FUNC_I2SO2_MCK (MTK_PIN_NO(57) | 1) +#define PINMUX_GPIO57__FUNC_I2SO1_D12 (MTK_PIN_NO(57) | 2) +#define PINMUX_GPIO57__FUNC_LCM1_RST (MTK_PIN_NO(57) | 3) +#define PINMUX_GPIO57__FUNC_DBG_MON_B15 (MTK_PIN_NO(57) | 7) + +#define PINMUX_GPIO58__FUNC_GPIO58 (MTK_PIN_NO(58) | 0) +#define PINMUX_GPIO58__FUNC_I2SO2_BCK (MTK_PIN_NO(58) | 1) +#define PINMUX_GPIO58__FUNC_I2SO1_D13 (MTK_PIN_NO(58) | 2) +#define PINMUX_GPIO58__FUNC_I2SIN1_BCK (MTK_PIN_NO(58) | 3) +#define PINMUX_GPIO58__FUNC_DBG_MON_B16 (MTK_PIN_NO(58) | 7) + +#define PINMUX_GPIO59__FUNC_GPIO59 (MTK_PIN_NO(59) | 0) +#define PINMUX_GPIO59__FUNC_I2SO2_WS (MTK_PIN_NO(59) | 1) +#define PINMUX_GPIO59__FUNC_I2SO1_D14 (MTK_PIN_NO(59) | 2) +#define PINMUX_GPIO59__FUNC_I2SIN1_LRCK (MTK_PIN_NO(59) | 3) +#define PINMUX_GPIO59__FUNC_DBG_MON_B17 (MTK_PIN_NO(59) | 7) + +#define PINMUX_GPIO60__FUNC_GPIO60 (MTK_PIN_NO(60) | 0) +#define PINMUX_GPIO60__FUNC_I2SO2_D0 (MTK_PIN_NO(60) | 1) +#define PINMUX_GPIO60__FUNC_I2SO1_D15 (MTK_PIN_NO(60) | 2) +#define PINMUX_GPIO60__FUNC_I2SI01_DATA0 (MTK_PIN_NO(60) | 3) +#define PINMUX_GPIO60__FUNC_DBG_MON_B18 (MTK_PIN_NO(60) | 7) + +#define PINMUX_GPIO61__FUNC_GPIO61 (MTK_PIN_NO(61) | 0) +#define PINMUX_GPIO61__FUNC_DMIC1_CLK (MTK_PIN_NO(61) | 1) +#define PINMUX_GPIO61__FUNC_I2SO2_BCK (MTK_PIN_NO(61) | 2) +#define PINMUX_GPIO61__FUNC_SCP_SPI2_CK (MTK_PIN_NO(61) | 3) +#define PINMUX_GPIO61__FUNC_DBG_MON_B19 (MTK_PIN_NO(61) | 7) + +#define PINMUX_GPIO62__FUNC_GPIO62 (MTK_PIN_NO(62) | 0) +#define PINMUX_GPIO62__FUNC_DMIC1_DAT (MTK_PIN_NO(62) | 1) +#define PINMUX_GPIO62__FUNC_I2SO2_WS (MTK_PIN_NO(62) | 2) +#define PINMUX_GPIO62__FUNC_SCP_SPI2_MI (MTK_PIN_NO(62) | 3) +#define PINMUX_GPIO62__FUNC_DBG_MON_B20 (MTK_PIN_NO(62) | 7) + +#define PINMUX_GPIO63__FUNC_GPIO63 (MTK_PIN_NO(63) | 0) +#define PINMUX_GPIO63__FUNC_DMIC2_CLK (MTK_PIN_NO(63) | 1) +#define PINMUX_GPIO63__FUNC_VBUSVALID (MTK_PIN_NO(63) | 2) +#define PINMUX_GPIO63__FUNC_SCP_SPI2_MO (MTK_PIN_NO(63) | 3) +#define PINMUX_GPIO63__FUNC_SCP_SCL2 (MTK_PIN_NO(63) | 4) +#define PINMUX_GPIO63__FUNC_SCP_JTAG1_TDO (MTK_PIN_NO(63) | 5) +#define PINMUX_GPIO63__FUNC_JTDO_SEL1 (MTK_PIN_NO(63) | 6) +#define PINMUX_GPIO63__FUNC_DBG_MON_B21 (MTK_PIN_NO(63) | 7) + +#define PINMUX_GPIO64__FUNC_GPIO64 (MTK_PIN_NO(64) | 0) +#define PINMUX_GPIO64__FUNC_DMIC2_DAT (MTK_PIN_NO(64) | 1) +#define PINMUX_GPIO64__FUNC_VBUSVALID_1P (MTK_PIN_NO(64) | 2) +#define PINMUX_GPIO64__FUNC_SCP_SPI2_CS (MTK_PIN_NO(64) | 3) +#define PINMUX_GPIO64__FUNC_SCP_SDA2 (MTK_PIN_NO(64) | 4) +#define PINMUX_GPIO64__FUNC_DBG_MON_B22 (MTK_PIN_NO(64) | 7) + +#define PINMUX_GPIO65__FUNC_GPIO65 (MTK_PIN_NO(65) | 0) +#define PINMUX_GPIO65__FUNC_PCM_DO (MTK_PIN_NO(65) | 1) +#define PINMUX_GPIO65__FUNC_AUXIF_ST0 (MTK_PIN_NO(65) | 2) +#define PINMUX_GPIO65__FUNC_UCTS2 (MTK_PIN_NO(65) | 3) +#define PINMUX_GPIO65__FUNC_SCP_JTAG1_TMS (MTK_PIN_NO(65) | 5) +#define PINMUX_GPIO65__FUNC_JTMS_SEL1 (MTK_PIN_NO(65) | 6) +#define PINMUX_GPIO65__FUNC_DBG_MON_B23 (MTK_PIN_NO(65) | 7) + +#define PINMUX_GPIO66__FUNC_GPIO66 (MTK_PIN_NO(66) | 0) +#define PINMUX_GPIO66__FUNC_PCM_CLK (MTK_PIN_NO(66) | 1) +#define PINMUX_GPIO66__FUNC_AUXIF_CLK0 (MTK_PIN_NO(66) | 2) +#define PINMUX_GPIO66__FUNC_URTS2 (MTK_PIN_NO(66) | 3) +#define PINMUX_GPIO66__FUNC_SCP_JTAG1_TCK (MTK_PIN_NO(66) | 5) +#define PINMUX_GPIO66__FUNC_JTCK_SEL1 (MTK_PIN_NO(66) | 6) +#define PINMUX_GPIO66__FUNC_DBG_MON_B24 (MTK_PIN_NO(66) | 7) + +#define PINMUX_GPIO67__FUNC_GPIO67 (MTK_PIN_NO(67) | 0) +#define PINMUX_GPIO67__FUNC_PCM_DI (MTK_PIN_NO(67) | 1) +#define PINMUX_GPIO67__FUNC_AUXIF_ST1 (MTK_PIN_NO(67) | 2) +#define PINMUX_GPIO67__FUNC_UTXD2 (MTK_PIN_NO(67) | 3) +#define PINMUX_GPIO67__FUNC_SCP_JTAG1_TRSTN (MTK_PIN_NO(67) | 5) +#define PINMUX_GPIO67__FUNC_JTRSTn_SEL1 (MTK_PIN_NO(67) | 6) +#define PINMUX_GPIO67__FUNC_DBG_MON_B25 (MTK_PIN_NO(67) | 7) + +#define PINMUX_GPIO68__FUNC_GPIO68 (MTK_PIN_NO(68) | 0) +#define PINMUX_GPIO68__FUNC_PCM_SYNC (MTK_PIN_NO(68) | 1) +#define PINMUX_GPIO68__FUNC_AUXIF_CLK1 (MTK_PIN_NO(68) | 2) +#define PINMUX_GPIO68__FUNC_URXD2 (MTK_PIN_NO(68) | 3) +#define PINMUX_GPIO68__FUNC_SCP_JTAG1_TDI (MTK_PIN_NO(68) | 5) +#define PINMUX_GPIO68__FUNC_JTDI_SEL1 (MTK_PIN_NO(68) | 6) +#define PINMUX_GPIO68__FUNC_DBG_MON_B26 (MTK_PIN_NO(68) | 7) + +#define PINMUX_GPIO69__FUNC_GPIO69 (MTK_PIN_NO(69) | 0) +#define PINMUX_GPIO69__FUNC_AUD_CLK_MOSI (MTK_PIN_NO(69) | 1) +#define PINMUX_GPIO69__FUNC_I2SIN2_BCK (MTK_PIN_NO(69) | 2) +#define PINMUX_GPIO69__FUNC_PWM_0 (MTK_PIN_NO(69) | 3) +#define PINMUX_GPIO69__FUNC_WAKEN (MTK_PIN_NO(69) | 4) +#define PINMUX_GPIO69__FUNC_DBG_MON_B27 (MTK_PIN_NO(69) | 7) + +#define PINMUX_GPIO70__FUNC_GPIO70 (MTK_PIN_NO(70) | 0) +#define PINMUX_GPIO70__FUNC_AUD_SYNC_MOSI (MTK_PIN_NO(70) | 1) +#define PINMUX_GPIO70__FUNC_I2SIN2_LRCK (MTK_PIN_NO(70) | 2) +#define PINMUX_GPIO70__FUNC_PWM_1 (MTK_PIN_NO(70) | 3) +#define PINMUX_GPIO70__FUNC_PERSTN (MTK_PIN_NO(70) | 4) +#define PINMUX_GPIO70__FUNC_DBG_MON_B28 (MTK_PIN_NO(70) | 7) + +#define PINMUX_GPIO71__FUNC_GPIO71 (MTK_PIN_NO(71) | 0) +#define PINMUX_GPIO71__FUNC_AUD_DAT_MOSI0 (MTK_PIN_NO(71) | 1) +#define PINMUX_GPIO71__FUNC_IDDIG_2P (MTK_PIN_NO(71) | 2) +#define PINMUX_GPIO71__FUNC_PWM_2 (MTK_PIN_NO(71) | 3) +#define PINMUX_GPIO71__FUNC_CLKREQN (MTK_PIN_NO(71) | 4) +#define PINMUX_GPIO71__FUNC_DBG_MON_B29 (MTK_PIN_NO(71) | 7) + +#define PINMUX_GPIO72__FUNC_GPIO72 (MTK_PIN_NO(72) | 0) +#define PINMUX_GPIO72__FUNC_AUD_DAT_MOSI1 (MTK_PIN_NO(72) | 1) +#define PINMUX_GPIO72__FUNC_USB_DRVVBUS_2P (MTK_PIN_NO(72) | 2) +#define PINMUX_GPIO72__FUNC_PWM_3 (MTK_PIN_NO(72) | 3) +#define PINMUX_GPIO72__FUNC_PERSTN_1 (MTK_PIN_NO(72) | 4) +#define PINMUX_GPIO72__FUNC_DBG_MON_B30 (MTK_PIN_NO(72) | 7) + +#define PINMUX_GPIO73__FUNC_GPIO73 (MTK_PIN_NO(73) | 0) +#define PINMUX_GPIO73__FUNC_AUD_DAT_MISO0 (MTK_PIN_NO(73) | 1) +#define PINMUX_GPIO73__FUNC_I2SI02_DATA0 (MTK_PIN_NO(73) | 2) +#define PINMUX_GPIO73__FUNC_CLKREQN_1 (MTK_PIN_NO(73) | 4) +#define PINMUX_GPIO73__FUNC_VOW_DAT_MISO (MTK_PIN_NO(73) | 5) +#define PINMUX_GPIO73__FUNC_DBG_MON_B31 (MTK_PIN_NO(73) | 7) + +#define PINMUX_GPIO74__FUNC_GPIO74 (MTK_PIN_NO(74) | 0) +#define PINMUX_GPIO74__FUNC_AUD_DAT_MISO1 (MTK_PIN_NO(74) | 1) +#define PINMUX_GPIO74__FUNC_I2SI02_DATA1 (MTK_PIN_NO(74) | 2) +#define PINMUX_GPIO74__FUNC_WAKEN_1 (MTK_PIN_NO(74) | 4) +#define PINMUX_GPIO74__FUNC_VOW_CLK_MISO (MTK_PIN_NO(74) | 5) +#define PINMUX_GPIO74__FUNC_DBG_MON_B32 (MTK_PIN_NO(74) | 7) + +#define PINMUX_GPIO75__FUNC_GPIO75 (MTK_PIN_NO(75) | 0) +#define PINMUX_GPIO75__FUNC_AUD_DAT_MISO2 (MTK_PIN_NO(75) | 1) +#define PINMUX_GPIO75__FUNC_I2SI02_DATA2 (MTK_PIN_NO(75) | 2) + +#define PINMUX_GPIO76__FUNC_GPIO76 (MTK_PIN_NO(76) | 0) +#define PINMUX_GPIO76__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(76) | 1) +#define PINMUX_GPIO76__FUNC_I2SI02_DATA3 (MTK_PIN_NO(76) | 2) +#define PINMUX_GPIO76__FUNC_DBG_MON_A26 (MTK_PIN_NO(76) | 7) + +#define PINMUX_GPIO77__FUNC_GPIO77 (MTK_PIN_NO(77) | 0) +#define PINMUX_GPIO77__FUNC_DGI_D0 (MTK_PIN_NO(77) | 1) +#define PINMUX_GPIO77__FUNC_DPI_D0 (MTK_PIN_NO(77) | 2) +#define PINMUX_GPIO77__FUNC_I2SI4_MCK (MTK_PIN_NO(77) | 3) +#define PINMUX_GPIO77__FUNC_SPIM4_CLK (MTK_PIN_NO(77) | 4) +#define PINMUX_GPIO77__FUNC_GBE_TXD3 (MTK_PIN_NO(77) | 5) +#define PINMUX_GPIO77__FUNC_SPM_JTAG_TCK (MTK_PIN_NO(77) | 6) + +#define PINMUX_GPIO78__FUNC_GPIO78 (MTK_PIN_NO(78) | 0) +#define PINMUX_GPIO78__FUNC_DGI_D1 (MTK_PIN_NO(78) | 1) +#define PINMUX_GPIO78__FUNC_DPI_D1 (MTK_PIN_NO(78) | 2) +#define PINMUX_GPIO78__FUNC_I2SI4_BCK (MTK_PIN_NO(78) | 3) +#define PINMUX_GPIO78__FUNC_SPIM4_MO (MTK_PIN_NO(78) | 4) +#define PINMUX_GPIO78__FUNC_GBE_TXD2 (MTK_PIN_NO(78) | 5) +#define PINMUX_GPIO78__FUNC_SPM_JTAG_TMS (MTK_PIN_NO(78) | 6) + +#define PINMUX_GPIO79__FUNC_GPIO79 (MTK_PIN_NO(79) | 0) +#define PINMUX_GPIO79__FUNC_DGI_D2 (MTK_PIN_NO(79) | 1) +#define PINMUX_GPIO79__FUNC_DPI_D2 (MTK_PIN_NO(79) | 2) +#define PINMUX_GPIO79__FUNC_I2SI4_WS (MTK_PIN_NO(79) | 3) +#define PINMUX_GPIO79__FUNC_SPIM4_CSB (MTK_PIN_NO(79) | 4) +#define PINMUX_GPIO79__FUNC_GBE_TXD1 (MTK_PIN_NO(79) | 5) +#define PINMUX_GPIO79__FUNC_SPM_JTAG_TDI (MTK_PIN_NO(79) | 6) + +#define PINMUX_GPIO80__FUNC_GPIO80 (MTK_PIN_NO(80) | 0) +#define PINMUX_GPIO80__FUNC_DGI_D3 (MTK_PIN_NO(80) | 1) +#define PINMUX_GPIO80__FUNC_DPI_D3 (MTK_PIN_NO(80) | 2) +#define PINMUX_GPIO80__FUNC_I2SI4_D0 (MTK_PIN_NO(80) | 3) +#define PINMUX_GPIO80__FUNC_SPIM4_MI (MTK_PIN_NO(80) | 4) +#define PINMUX_GPIO80__FUNC_GBE_TXD0 (MTK_PIN_NO(80) | 5) +#define PINMUX_GPIO80__FUNC_SPM_JTAG_TDO (MTK_PIN_NO(80) | 6) + +#define PINMUX_GPIO81__FUNC_GPIO81 (MTK_PIN_NO(81) | 0) +#define PINMUX_GPIO81__FUNC_DGI_D4 (MTK_PIN_NO(81) | 1) +#define PINMUX_GPIO81__FUNC_DPI_D4 (MTK_PIN_NO(81) | 2) +#define PINMUX_GPIO81__FUNC_I2SI5_MCK (MTK_PIN_NO(81) | 3) +#define PINMUX_GPIO81__FUNC_SPIM5_CLK (MTK_PIN_NO(81) | 4) +#define PINMUX_GPIO81__FUNC_GBE_RXD3 (MTK_PIN_NO(81) | 5) +#define PINMUX_GPIO81__FUNC_SPM_JTAG_TRSTN (MTK_PIN_NO(81) | 6) + +#define PINMUX_GPIO82__FUNC_GPIO82 (MTK_PIN_NO(82) | 0) +#define PINMUX_GPIO82__FUNC_DGI_D5 (MTK_PIN_NO(82) | 1) +#define PINMUX_GPIO82__FUNC_DPI_D5 (MTK_PIN_NO(82) | 2) +#define PINMUX_GPIO82__FUNC_I2SI5_BCK (MTK_PIN_NO(82) | 3) +#define PINMUX_GPIO82__FUNC_SPIM5_MO (MTK_PIN_NO(82) | 4) +#define PINMUX_GPIO82__FUNC_GBE_RXD2 (MTK_PIN_NO(82) | 5) +#define PINMUX_GPIO82__FUNC_MCUPM_JTAG_TDO (MTK_PIN_NO(82) | 6) + +#define PINMUX_GPIO83__FUNC_GPIO83 (MTK_PIN_NO(83) | 0) +#define PINMUX_GPIO83__FUNC_DGI_D6 (MTK_PIN_NO(83) | 1) +#define PINMUX_GPIO83__FUNC_DPI_D6 (MTK_PIN_NO(83) | 2) +#define PINMUX_GPIO83__FUNC_I2SI5_WS (MTK_PIN_NO(83) | 3) +#define PINMUX_GPIO83__FUNC_SPIM5_CSB (MTK_PIN_NO(83) | 4) +#define PINMUX_GPIO83__FUNC_GBE_RXD1 (MTK_PIN_NO(83) | 5) +#define PINMUX_GPIO83__FUNC_MCUPM_JTAG_TMS (MTK_PIN_NO(83) | 6) + +#define PINMUX_GPIO84__FUNC_GPIO84 (MTK_PIN_NO(84) | 0) +#define PINMUX_GPIO84__FUNC_DGI_D7 (MTK_PIN_NO(84) | 1) +#define PINMUX_GPIO84__FUNC_DPI_D7 (MTK_PIN_NO(84) | 2) +#define PINMUX_GPIO84__FUNC_I2SI5_D0 (MTK_PIN_NO(84) | 3) +#define PINMUX_GPIO84__FUNC_SPIM5_MI (MTK_PIN_NO(84) | 4) +#define PINMUX_GPIO84__FUNC_GBE_RXD0 (MTK_PIN_NO(84) | 5) +#define PINMUX_GPIO84__FUNC_MCUPM_JTAG_TCK (MTK_PIN_NO(84) | 6) + +#define PINMUX_GPIO85__FUNC_GPIO85 (MTK_PIN_NO(85) | 0) +#define PINMUX_GPIO85__FUNC_DGI_D8 (MTK_PIN_NO(85) | 1) +#define PINMUX_GPIO85__FUNC_DPI_D8 (MTK_PIN_NO(85) | 2) +#define PINMUX_GPIO85__FUNC_I2SO4_MCK (MTK_PIN_NO(85) | 3) +#define PINMUX_GPIO85__FUNC_SCP_SPI1_B_CK (MTK_PIN_NO(85) | 4) +#define PINMUX_GPIO85__FUNC_GBE_TXC (MTK_PIN_NO(85) | 5) +#define PINMUX_GPIO85__FUNC_MCUPM_JTAG_TDI (MTK_PIN_NO(85) | 6) + +#define PINMUX_GPIO86__FUNC_GPIO86 (MTK_PIN_NO(86) | 0) +#define PINMUX_GPIO86__FUNC_DGI_D9 (MTK_PIN_NO(86) | 1) +#define PINMUX_GPIO86__FUNC_DPI_D9 (MTK_PIN_NO(86) | 2) +#define PINMUX_GPIO86__FUNC_I2SO4_BCK (MTK_PIN_NO(86) | 3) +#define PINMUX_GPIO86__FUNC_SCP_SPI1_B_MI (MTK_PIN_NO(86) | 4) +#define PINMUX_GPIO86__FUNC_GBE_RXC (MTK_PIN_NO(86) | 5) +#define PINMUX_GPIO86__FUNC_MCUPM_JTAG_TRSTN (MTK_PIN_NO(86) | 6) + +#define PINMUX_GPIO87__FUNC_GPIO87 (MTK_PIN_NO(87) | 0) +#define PINMUX_GPIO87__FUNC_DGI_D10 (MTK_PIN_NO(87) | 1) +#define PINMUX_GPIO87__FUNC_DPI_D10 (MTK_PIN_NO(87) | 2) +#define PINMUX_GPIO87__FUNC_I2SO4_WS (MTK_PIN_NO(87) | 3) +#define PINMUX_GPIO87__FUNC_SCP_SPI1_B_CS (MTK_PIN_NO(87) | 4) +#define PINMUX_GPIO87__FUNC_GBE_RXDV (MTK_PIN_NO(87) | 5) +#define PINMUX_GPIO87__FUNC_SSPM_JTAG_TDO (MTK_PIN_NO(87) | 6) + +#define PINMUX_GPIO88__FUNC_GPIO88 (MTK_PIN_NO(88) | 0) +#define PINMUX_GPIO88__FUNC_DGI_D11 (MTK_PIN_NO(88) | 1) +#define PINMUX_GPIO88__FUNC_DPI_D11 (MTK_PIN_NO(88) | 2) +#define PINMUX_GPIO88__FUNC_I2SO4_D0 (MTK_PIN_NO(88) | 3) +#define PINMUX_GPIO88__FUNC_SCP_SPI1_B_MO (MTK_PIN_NO(88) | 4) +#define PINMUX_GPIO88__FUNC_GBE_TXEN (MTK_PIN_NO(88) | 5) +#define PINMUX_GPIO88__FUNC_SSPM_JTAG_TMS (MTK_PIN_NO(88) | 6) + +#define PINMUX_GPIO89__FUNC_GPIO89 (MTK_PIN_NO(89) | 0) +#define PINMUX_GPIO89__FUNC_DGI_D12 (MTK_PIN_NO(89) | 1) +#define PINMUX_GPIO89__FUNC_DPI_D12 (MTK_PIN_NO(89) | 2) +#define PINMUX_GPIO89__FUNC_MSDC2_CMD_A (MTK_PIN_NO(89) | 3) +#define PINMUX_GPIO89__FUNC_I2SO5_BCK (MTK_PIN_NO(89) | 4) +#define PINMUX_GPIO89__FUNC_GBE_MDC (MTK_PIN_NO(89) | 5) +#define PINMUX_GPIO89__FUNC_SSPM_JTAG_TCK (MTK_PIN_NO(89) | 6) + +#define PINMUX_GPIO90__FUNC_GPIO90 (MTK_PIN_NO(90) | 0) +#define PINMUX_GPIO90__FUNC_DGI_D13 (MTK_PIN_NO(90) | 1) +#define PINMUX_GPIO90__FUNC_DPI_D13 (MTK_PIN_NO(90) | 2) +#define PINMUX_GPIO90__FUNC_MSDC2_CLK_A (MTK_PIN_NO(90) | 3) +#define PINMUX_GPIO90__FUNC_I2SO5_WS (MTK_PIN_NO(90) | 4) +#define PINMUX_GPIO90__FUNC_GBE_MDIO (MTK_PIN_NO(90) | 5) +#define PINMUX_GPIO90__FUNC_SSPM_JTAG_TDI (MTK_PIN_NO(90) | 6) + +#define PINMUX_GPIO91__FUNC_GPIO91 (MTK_PIN_NO(91) | 0) +#define PINMUX_GPIO91__FUNC_DGI_D14 (MTK_PIN_NO(91) | 1) +#define PINMUX_GPIO91__FUNC_DPI_D14 (MTK_PIN_NO(91) | 2) +#define PINMUX_GPIO91__FUNC_MSDC2_DAT3_A (MTK_PIN_NO(91) | 3) +#define PINMUX_GPIO91__FUNC_I2SO5_D0 (MTK_PIN_NO(91) | 4) +#define PINMUX_GPIO91__FUNC_GBE_TXER (MTK_PIN_NO(91) | 5) +#define PINMUX_GPIO91__FUNC_SSPM_JTAG_TRSTN (MTK_PIN_NO(91) | 6) + +#define PINMUX_GPIO92__FUNC_GPIO92 (MTK_PIN_NO(92) | 0) +#define PINMUX_GPIO92__FUNC_DGI_D15 (MTK_PIN_NO(92) | 1) +#define PINMUX_GPIO92__FUNC_DPI_D15 (MTK_PIN_NO(92) | 2) +#define PINMUX_GPIO92__FUNC_MSDC2_DAT0_A (MTK_PIN_NO(92) | 3) +#define PINMUX_GPIO92__FUNC_I2SO2_D1 (MTK_PIN_NO(92) | 4) +#define PINMUX_GPIO92__FUNC_GBE_RXER (MTK_PIN_NO(92) | 5) +#define PINMUX_GPIO92__FUNC_CCU0_JTAG_TDO (MTK_PIN_NO(92) | 6) + +#define PINMUX_GPIO93__FUNC_GPIO93 (MTK_PIN_NO(93) | 0) +#define PINMUX_GPIO93__FUNC_DGI_HSYNC (MTK_PIN_NO(93) | 1) +#define PINMUX_GPIO93__FUNC_DPI_HSYNC (MTK_PIN_NO(93) | 2) +#define PINMUX_GPIO93__FUNC_MSDC2_DAT2_A (MTK_PIN_NO(93) | 3) +#define PINMUX_GPIO93__FUNC_I2SO2_D2 (MTK_PIN_NO(93) | 4) +#define PINMUX_GPIO93__FUNC_GBE_COL (MTK_PIN_NO(93) | 5) +#define PINMUX_GPIO93__FUNC_CCU0_JTAG_TMS (MTK_PIN_NO(93) | 6) + +#define PINMUX_GPIO94__FUNC_GPIO94 (MTK_PIN_NO(94) | 0) +#define PINMUX_GPIO94__FUNC_DGI_VSYNC (MTK_PIN_NO(94) | 1) +#define PINMUX_GPIO94__FUNC_DPI_VSYNC (MTK_PIN_NO(94) | 2) +#define PINMUX_GPIO94__FUNC_MSDC2_DAT1_A (MTK_PIN_NO(94) | 3) +#define PINMUX_GPIO94__FUNC_I2SO2_D3 (MTK_PIN_NO(94) | 4) +#define PINMUX_GPIO94__FUNC_GBE_INTR (MTK_PIN_NO(94) | 5) +#define PINMUX_GPIO94__FUNC_CCU0_JTAG_TDI (MTK_PIN_NO(94) | 6) + +#define PINMUX_GPIO95__FUNC_GPIO95 (MTK_PIN_NO(95) | 0) +#define PINMUX_GPIO95__FUNC_DGI_DE (MTK_PIN_NO(95) | 1) +#define PINMUX_GPIO95__FUNC_DPI_DE (MTK_PIN_NO(95) | 2) +#define PINMUX_GPIO95__FUNC_UTXD2 (MTK_PIN_NO(95) | 3) +#define PINMUX_GPIO95__FUNC_I2SIN_D1 (MTK_PIN_NO(95) | 5) +#define PINMUX_GPIO95__FUNC_CCU0_JTAG_TCK (MTK_PIN_NO(95) | 6) + +#define PINMUX_GPIO96__FUNC_GPIO96 (MTK_PIN_NO(96) | 0) +#define PINMUX_GPIO96__FUNC_DGI_CK (MTK_PIN_NO(96) | 1) +#define PINMUX_GPIO96__FUNC_DPI_CK (MTK_PIN_NO(96) | 2) +#define PINMUX_GPIO96__FUNC_URXD2 (MTK_PIN_NO(96) | 3) +#define PINMUX_GPIO96__FUNC_I2SO5_MCK (MTK_PIN_NO(96) | 4) +#define PINMUX_GPIO96__FUNC_I2SIN_D2 (MTK_PIN_NO(96) | 5) +#define PINMUX_GPIO96__FUNC_CCU0_JTAG_TRST (MTK_PIN_NO(96) | 6) + +#define PINMUX_GPIO97__FUNC_GPIO97 (MTK_PIN_NO(97) | 0) +#define PINMUX_GPIO97__FUNC_DISP_PWM0 (MTK_PIN_NO(97) | 1) +#define PINMUX_GPIO97__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(97) | 2) + +#define PINMUX_GPIO98__FUNC_GPIO98 (MTK_PIN_NO(98) | 0) +#define PINMUX_GPIO98__FUNC_UTXD0 (MTK_PIN_NO(98) | 1) + +#define PINMUX_GPIO99__FUNC_GPIO99 (MTK_PIN_NO(99) | 0) +#define PINMUX_GPIO99__FUNC_URXD0 (MTK_PIN_NO(99) | 1) + +#define PINMUX_GPIO100__FUNC_GPIO100 (MTK_PIN_NO(100) | 0) +#define PINMUX_GPIO100__FUNC_URTS1 (MTK_PIN_NO(100) | 1) +#define PINMUX_GPIO100__FUNC_DSI_TE (MTK_PIN_NO(100) | 2) +#define PINMUX_GPIO100__FUNC_I2SO1_D8 (MTK_PIN_NO(100) | 3) +#define PINMUX_GPIO100__FUNC_KPROW2 (MTK_PIN_NO(100) | 4) +#define PINMUX_GPIO100__FUNC_PWM_0 (MTK_PIN_NO(100) | 5) +#define PINMUX_GPIO100__FUNC_TP_URTS1_AO (MTK_PIN_NO(100) | 6) +#define PINMUX_GPIO100__FUNC_I2SIN_D0 (MTK_PIN_NO(100) | 7) + +#define PINMUX_GPIO101__FUNC_GPIO101 (MTK_PIN_NO(101) | 0) +#define PINMUX_GPIO101__FUNC_UCTS1 (MTK_PIN_NO(101) | 1) +#define PINMUX_GPIO101__FUNC_DSI1_TE (MTK_PIN_NO(101) | 2) +#define PINMUX_GPIO101__FUNC_I2SO1_D9 (MTK_PIN_NO(101) | 3) +#define PINMUX_GPIO101__FUNC_KPCOL2 (MTK_PIN_NO(101) | 4) +#define PINMUX_GPIO101__FUNC_PWM_1 (MTK_PIN_NO(101) | 5) +#define PINMUX_GPIO101__FUNC_TP_UCTS1_AO (MTK_PIN_NO(101) | 6) +#define PINMUX_GPIO101__FUNC_I2SIN_D1 (MTK_PIN_NO(101) | 7) + +#define PINMUX_GPIO102__FUNC_GPIO102 (MTK_PIN_NO(102) | 0) +#define PINMUX_GPIO102__FUNC_UTXD1 (MTK_PIN_NO(102) | 1) +#define PINMUX_GPIO102__FUNC_VBUSVALID_2P (MTK_PIN_NO(102) | 2) +#define PINMUX_GPIO102__FUNC_I2SO1_D10 (MTK_PIN_NO(102) | 3) +#define PINMUX_GPIO102__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(102) | 4) +#define PINMUX_GPIO102__FUNC_TP_UTXD1_AO (MTK_PIN_NO(102) | 5) +#define PINMUX_GPIO102__FUNC_MD32_1_TXD (MTK_PIN_NO(102) | 6) +#define PINMUX_GPIO102__FUNC_I2SIN_D2 (MTK_PIN_NO(102) | 7) + +#define PINMUX_GPIO103__FUNC_GPIO103 (MTK_PIN_NO(103) | 0) +#define PINMUX_GPIO103__FUNC_URXD1 (MTK_PIN_NO(103) | 1) +#define PINMUX_GPIO103__FUNC_VBUSVALID_3P (MTK_PIN_NO(103) | 2) +#define PINMUX_GPIO103__FUNC_I2SO1_D11 (MTK_PIN_NO(103) | 3) +#define PINMUX_GPIO103__FUNC_SSPM_URXD_AO (MTK_PIN_NO(103) | 4) +#define PINMUX_GPIO103__FUNC_TP_URXD1_AO (MTK_PIN_NO(103) | 5) +#define PINMUX_GPIO103__FUNC_MD32_1_RXD (MTK_PIN_NO(103) | 6) +#define PINMUX_GPIO103__FUNC_I2SIN_D3 (MTK_PIN_NO(103) | 7) + +#define PINMUX_GPIO104__FUNC_GPIO104 (MTK_PIN_NO(104) | 0) +#define PINMUX_GPIO104__FUNC_KPROW0 (MTK_PIN_NO(104) | 1) +#define PINMUX_GPIO104__FUNC_DISP_PWM1 (MTK_PIN_NO(104) | 2) + +#define PINMUX_GPIO105__FUNC_GPIO105 (MTK_PIN_NO(105) | 0) +#define PINMUX_GPIO105__FUNC_KPROW1 (MTK_PIN_NO(105) | 1) +#define PINMUX_GPIO105__FUNC_EDP_TX_HPD (MTK_PIN_NO(105) | 2) +#define PINMUX_GPIO105__FUNC_PWM_2 (MTK_PIN_NO(105) | 3) + +#define PINMUX_GPIO106__FUNC_GPIO106 (MTK_PIN_NO(106) | 0) +#define PINMUX_GPIO106__FUNC_KPCOL0 (MTK_PIN_NO(106) | 1) + +#define PINMUX_GPIO107__FUNC_GPIO107 (MTK_PIN_NO(107) | 0) +#define PINMUX_GPIO107__FUNC_KPCOL1 (MTK_PIN_NO(107) | 1) +#define PINMUX_GPIO107__FUNC_DSI1_TE (MTK_PIN_NO(107) | 2) +#define PINMUX_GPIO107__FUNC_PWM_3 (MTK_PIN_NO(107) | 3) +#define PINMUX_GPIO107__FUNC_SCP_SCL3 (MTK_PIN_NO(107) | 4) +#define PINMUX_GPIO107__FUNC_I2SIN_MCK (MTK_PIN_NO(107) | 5) + +#define PINMUX_GPIO108__FUNC_GPIO108 (MTK_PIN_NO(108) | 0) +#define PINMUX_GPIO108__FUNC_LCM_RST (MTK_PIN_NO(108) | 1) +#define PINMUX_GPIO108__FUNC_KPCOL1 (MTK_PIN_NO(108) | 2) +#define PINMUX_GPIO108__FUNC_SCP_SDA3 (MTK_PIN_NO(108) | 4) +#define PINMUX_GPIO108__FUNC_I2SIN_BCK (MTK_PIN_NO(108) | 5) + +#define PINMUX_GPIO109__FUNC_GPIO109 (MTK_PIN_NO(109) | 0) +#define PINMUX_GPIO109__FUNC_DSI_TE (MTK_PIN_NO(109) | 1) +#define PINMUX_GPIO109__FUNC_I2SIN_D3 (MTK_PIN_NO(109) | 2) +#define PINMUX_GPIO109__FUNC_I2SIN_WS (MTK_PIN_NO(109) | 5) + +#define PINMUX_GPIO110__FUNC_GPIO110 (MTK_PIN_NO(110) | 0) +#define PINMUX_GPIO110__FUNC_MSDC1_CMD (MTK_PIN_NO(110) | 1) +#define PINMUX_GPIO110__FUNC_JTMS_SEL3 (MTK_PIN_NO(110) | 2) +#define PINMUX_GPIO110__FUNC_UDI_TMS (MTK_PIN_NO(110) | 3) +#define PINMUX_GPIO110__FUNC_CCU1_JTAG_TMS (MTK_PIN_NO(110) | 5) +#define PINMUX_GPIO110__FUNC_IPU_JTAG_TMS (MTK_PIN_NO(110) | 6) + +#define PINMUX_GPIO111__FUNC_GPIO111 (MTK_PIN_NO(111) | 0) +#define PINMUX_GPIO111__FUNC_MSDC1_CLK (MTK_PIN_NO(111) | 1) +#define PINMUX_GPIO111__FUNC_JTCK_SEL3 (MTK_PIN_NO(111) | 2) +#define PINMUX_GPIO111__FUNC_UDI_TCK (MTK_PIN_NO(111) | 3) +#define PINMUX_GPIO111__FUNC_CCU1_JTAG_TCK (MTK_PIN_NO(111) | 5) +#define PINMUX_GPIO111__FUNC_IPU_JTAG_TCK (MTK_PIN_NO(111) | 6) + +#define PINMUX_GPIO112__FUNC_GPIO112 (MTK_PIN_NO(112) | 0) +#define PINMUX_GPIO112__FUNC_MSDC1_DAT0 (MTK_PIN_NO(112) | 1) +#define PINMUX_GPIO112__FUNC_JTDI_SEL3 (MTK_PIN_NO(112) | 2) +#define PINMUX_GPIO112__FUNC_UDI_TDI (MTK_PIN_NO(112) | 3) +#define PINMUX_GPIO112__FUNC_I2SO2_D0 (MTK_PIN_NO(112) | 4) +#define PINMUX_GPIO112__FUNC_CCU1_JTAG_TDI (MTK_PIN_NO(112) | 5) +#define PINMUX_GPIO112__FUNC_IPU_JTAG_TDI (MTK_PIN_NO(112) | 6) + +#define PINMUX_GPIO113__FUNC_GPIO113 (MTK_PIN_NO(113) | 0) +#define PINMUX_GPIO113__FUNC_MSDC1_DAT1 (MTK_PIN_NO(113) | 1) +#define PINMUX_GPIO113__FUNC_JTDO_SEL3 (MTK_PIN_NO(113) | 2) +#define PINMUX_GPIO113__FUNC_UDI_TDO (MTK_PIN_NO(113) | 3) +#define PINMUX_GPIO113__FUNC_I2SO2_D1 (MTK_PIN_NO(113) | 4) +#define PINMUX_GPIO113__FUNC_CCU1_JTAG_TDO (MTK_PIN_NO(113) | 5) +#define PINMUX_GPIO113__FUNC_IPU_JTAG_TDO (MTK_PIN_NO(113) | 6) + +#define PINMUX_GPIO114__FUNC_GPIO114 (MTK_PIN_NO(114) | 0) +#define PINMUX_GPIO114__FUNC_MSDC1_DAT2 (MTK_PIN_NO(114) | 1) +#define PINMUX_GPIO114__FUNC_JTRSTn_SEL3 (MTK_PIN_NO(114) | 2) +#define PINMUX_GPIO114__FUNC_UDI_NTRST (MTK_PIN_NO(114) | 3) +#define PINMUX_GPIO114__FUNC_I2SO2_D2 (MTK_PIN_NO(114) | 4) +#define PINMUX_GPIO114__FUNC_CCU1_JTAG_TRST (MTK_PIN_NO(114) | 5) +#define PINMUX_GPIO114__FUNC_IPU_JTAG_TRST (MTK_PIN_NO(114) | 6) + +#define PINMUX_GPIO115__FUNC_GPIO115 (MTK_PIN_NO(115) | 0) +#define PINMUX_GPIO115__FUNC_MSDC1_DAT3 (MTK_PIN_NO(115) | 1) +#define PINMUX_GPIO115__FUNC_I2SO2_D3 (MTK_PIN_NO(115) | 4) +#define PINMUX_GPIO115__FUNC_MD32_1_GPIO2 (MTK_PIN_NO(115) | 6) + +#define PINMUX_GPIO116__FUNC_GPIO116 (MTK_PIN_NO(116) | 0) +#define PINMUX_GPIO116__FUNC_MSDC0_DAT7 (MTK_PIN_NO(116) | 1) + +#define PINMUX_GPIO117__FUNC_GPIO117 (MTK_PIN_NO(117) | 0) +#define PINMUX_GPIO117__FUNC_MSDC0_DAT6 (MTK_PIN_NO(117) | 1) + +#define PINMUX_GPIO118__FUNC_GPIO118 (MTK_PIN_NO(118) | 0) +#define PINMUX_GPIO118__FUNC_MSDC0_DAT5 (MTK_PIN_NO(118) | 1) + +#define PINMUX_GPIO119__FUNC_GPIO119 (MTK_PIN_NO(119) | 0) +#define PINMUX_GPIO119__FUNC_MSDC0_DAT4 (MTK_PIN_NO(119) | 1) + +#define PINMUX_GPIO120__FUNC_GPIO120 (MTK_PIN_NO(120) | 0) +#define PINMUX_GPIO120__FUNC_MSDC0_RSTB (MTK_PIN_NO(120) | 1) + +#define PINMUX_GPIO121__FUNC_GPIO121 (MTK_PIN_NO(121) | 0) +#define PINMUX_GPIO121__FUNC_MSDC0_CMD (MTK_PIN_NO(121) | 1) + +#define PINMUX_GPIO122__FUNC_GPIO122 (MTK_PIN_NO(122) | 0) +#define PINMUX_GPIO122__FUNC_MSDC0_CLK (MTK_PIN_NO(122) | 1) + +#define PINMUX_GPIO123__FUNC_GPIO123 (MTK_PIN_NO(123) | 0) +#define PINMUX_GPIO123__FUNC_MSDC0_DAT3 (MTK_PIN_NO(123) | 1) + +#define PINMUX_GPIO124__FUNC_GPIO124 (MTK_PIN_NO(124) | 0) +#define PINMUX_GPIO124__FUNC_MSDC0_DAT2 (MTK_PIN_NO(124) | 1) + +#define PINMUX_GPIO125__FUNC_GPIO125 (MTK_PIN_NO(125) | 0) +#define PINMUX_GPIO125__FUNC_MSDC0_DAT1 (MTK_PIN_NO(125) | 1) + +#define PINMUX_GPIO126__FUNC_GPIO126 (MTK_PIN_NO(126) | 0) +#define PINMUX_GPIO126__FUNC_MSDC0_DAT0 (MTK_PIN_NO(126) | 1) + +#define PINMUX_GPIO127__FUNC_GPIO127 (MTK_PIN_NO(127) | 0) +#define PINMUX_GPIO127__FUNC_MSDC0_DSL (MTK_PIN_NO(127) | 1) + +#define PINMUX_GPIO128__FUNC_GPIO128 (MTK_PIN_NO(128) | 0) +#define PINMUX_GPIO128__FUNC_IDDIG (MTK_PIN_NO(128) | 1) +#define PINMUX_GPIO128__FUNC_UCTS2 (MTK_PIN_NO(128) | 2) +#define PINMUX_GPIO128__FUNC_UTXD5 (MTK_PIN_NO(128) | 3) +#define PINMUX_GPIO128__FUNC_UFS_MPHY_SCL (MTK_PIN_NO(128) | 4) +#define PINMUX_GPIO128__FUNC_mbistreaden_trigger (MTK_PIN_NO(128) | 5) +#define PINMUX_GPIO128__FUNC_MD32_1_GPIO0 (MTK_PIN_NO(128) | 6) +#define PINMUX_GPIO128__FUNC_SCP_SCL2 (MTK_PIN_NO(128) | 7) + +#define PINMUX_GPIO129__FUNC_GPIO129 (MTK_PIN_NO(129) | 0) +#define PINMUX_GPIO129__FUNC_USB_DRVVBUS (MTK_PIN_NO(129) | 1) +#define PINMUX_GPIO129__FUNC_URTS2 (MTK_PIN_NO(129) | 2) +#define PINMUX_GPIO129__FUNC_URXD5 (MTK_PIN_NO(129) | 3) +#define PINMUX_GPIO129__FUNC_UFS_MPHY_SDA (MTK_PIN_NO(129) | 4) +#define PINMUX_GPIO129__FUNC_mbistwriteen_trigger (MTK_PIN_NO(129) | 5) +#define PINMUX_GPIO129__FUNC_MD32_1_GPIO1 (MTK_PIN_NO(129) | 6) +#define PINMUX_GPIO129__FUNC_SCP_SDA2 (MTK_PIN_NO(129) | 7) + +#define PINMUX_GPIO130__FUNC_GPIO130 (MTK_PIN_NO(130) | 0) +#define PINMUX_GPIO130__FUNC_IDDIG_1P (MTK_PIN_NO(130) | 1) +#define PINMUX_GPIO130__FUNC_SPINOR_IO2 (MTK_PIN_NO(130) | 2) +#define PINMUX_GPIO130__FUNC_SNFI_WP (MTK_PIN_NO(130) | 3) +#define PINMUX_GPIO130__FUNC_VPU_UDI_NTRST (MTK_PIN_NO(130) | 4) + +#define PINMUX_GPIO131__FUNC_GPIO131 (MTK_PIN_NO(131) | 0) +#define PINMUX_GPIO131__FUNC_USB_DRVVBUS_1P (MTK_PIN_NO(131) | 1) +#define PINMUX_GPIO131__FUNC_SPINOR_IO3 (MTK_PIN_NO(131) | 2) +#define PINMUX_GPIO131__FUNC_SNFI_HOLD (MTK_PIN_NO(131) | 3) +#define PINMUX_GPIO131__FUNC_MD32_1_JTAG_TRST (MTK_PIN_NO(131) | 4) +#define PINMUX_GPIO131__FUNC_SCP_JTAG0_TRSTN (MTK_PIN_NO(131) | 5) +#define PINMUX_GPIO131__FUNC_APU_JTAG_TRST (MTK_PIN_NO(131) | 6) + +#define PINMUX_GPIO132__FUNC_GPIO132 (MTK_PIN_NO(132) | 0) +#define PINMUX_GPIO132__FUNC_SPIM0_CSB (MTK_PIN_NO(132) | 1) +#define PINMUX_GPIO132__FUNC_SCP_SPI0_CS (MTK_PIN_NO(132) | 2) +#define PINMUX_GPIO132__FUNC_SPIS0_CSB (MTK_PIN_NO(132) | 3) +#define PINMUX_GPIO132__FUNC_VPU_UDI_TMS (MTK_PIN_NO(132) | 4) +#define PINMUX_GPIO132__FUNC_I2SO5_D0 (MTK_PIN_NO(132) | 6) + +#define PINMUX_GPIO133__FUNC_GPIO133 (MTK_PIN_NO(133) | 0) +#define PINMUX_GPIO133__FUNC_SPIM0_CLK (MTK_PIN_NO(133) | 1) +#define PINMUX_GPIO133__FUNC_SCP_SPI0_CK (MTK_PIN_NO(133) | 2) +#define PINMUX_GPIO133__FUNC_SPIS0_CLK (MTK_PIN_NO(133) | 3) +#define PINMUX_GPIO133__FUNC_VPU_UDI_TCK (MTK_PIN_NO(133) | 4) +#define PINMUX_GPIO133__FUNC_I2SO5_BCK (MTK_PIN_NO(133) | 6) + +#define PINMUX_GPIO134__FUNC_GPIO134 (MTK_PIN_NO(134) | 0) +#define PINMUX_GPIO134__FUNC_SPIM0_MO (MTK_PIN_NO(134) | 1) +#define PINMUX_GPIO134__FUNC_SCP_SPI0_MO (MTK_PIN_NO(134) | 2) +#define PINMUX_GPIO134__FUNC_SPIS0_SI (MTK_PIN_NO(134) | 3) +#define PINMUX_GPIO134__FUNC_VPU_UDI_TDO (MTK_PIN_NO(134) | 4) +#define PINMUX_GPIO134__FUNC_I2SO5_WS (MTK_PIN_NO(134) | 6) + +#define PINMUX_GPIO135__FUNC_GPIO135 (MTK_PIN_NO(135) | 0) +#define PINMUX_GPIO135__FUNC_SPIM0_MI (MTK_PIN_NO(135) | 1) +#define PINMUX_GPIO135__FUNC_SCP_SPI0_MI (MTK_PIN_NO(135) | 2) +#define PINMUX_GPIO135__FUNC_SPIS0_SO (MTK_PIN_NO(135) | 3) +#define PINMUX_GPIO135__FUNC_VPU_UDI_TDI (MTK_PIN_NO(135) | 4) +#define PINMUX_GPIO135__FUNC_I2SO5_MCK (MTK_PIN_NO(135) | 6) + +#define PINMUX_GPIO136__FUNC_GPIO136 (MTK_PIN_NO(136) | 0) +#define PINMUX_GPIO136__FUNC_SPIM1_CSB (MTK_PIN_NO(136) | 1) +#define PINMUX_GPIO136__FUNC_SCP_SPI1_A_CS (MTK_PIN_NO(136) | 2) +#define PINMUX_GPIO136__FUNC_SPIS1_CSB (MTK_PIN_NO(136) | 3) +#define PINMUX_GPIO136__FUNC_MD32_1_JTAG_TMS (MTK_PIN_NO(136) | 4) +#define PINMUX_GPIO136__FUNC_SCP_JTAG0_TMS (MTK_PIN_NO(136) | 5) +#define PINMUX_GPIO136__FUNC_APU_JTAG_TMS (MTK_PIN_NO(136) | 6) +#define PINMUX_GPIO136__FUNC_DBG_MON_A15 (MTK_PIN_NO(136) | 7) + +#define PINMUX_GPIO137__FUNC_GPIO137 (MTK_PIN_NO(137) | 0) +#define PINMUX_GPIO137__FUNC_SPIM1_CLK (MTK_PIN_NO(137) | 1) +#define PINMUX_GPIO137__FUNC_SCP_SPI1_A_CK (MTK_PIN_NO(137) | 2) +#define PINMUX_GPIO137__FUNC_SPIS1_CLK (MTK_PIN_NO(137) | 3) +#define PINMUX_GPIO137__FUNC_MD32_1_JTAG_TCK (MTK_PIN_NO(137) | 4) +#define PINMUX_GPIO137__FUNC_SCP_JTAG0_TCK (MTK_PIN_NO(137) | 5) +#define PINMUX_GPIO137__FUNC_APU_JTAG_TCK (MTK_PIN_NO(137) | 6) +#define PINMUX_GPIO137__FUNC_DBG_MON_A14 (MTK_PIN_NO(137) | 7) + +#define PINMUX_GPIO138__FUNC_GPIO138 (MTK_PIN_NO(138) | 0) +#define PINMUX_GPIO138__FUNC_SPIM1_MO (MTK_PIN_NO(138) | 1) +#define PINMUX_GPIO138__FUNC_SCP_SPI1_A_MO (MTK_PIN_NO(138) | 2) +#define PINMUX_GPIO138__FUNC_SPIS1_SI (MTK_PIN_NO(138) | 3) +#define PINMUX_GPIO138__FUNC_MD32_1_JTAG_TDO (MTK_PIN_NO(138) | 4) +#define PINMUX_GPIO138__FUNC_SCP_JTAG0_TDO (MTK_PIN_NO(138) | 5) +#define PINMUX_GPIO138__FUNC_APU_JTAG_TDO (MTK_PIN_NO(138) | 6) +#define PINMUX_GPIO138__FUNC_DBG_MON_A16 (MTK_PIN_NO(138) | 7) + +#define PINMUX_GPIO139__FUNC_GPIO139 (MTK_PIN_NO(139) | 0) +#define PINMUX_GPIO139__FUNC_SPIM1_MI (MTK_PIN_NO(139) | 1) +#define PINMUX_GPIO139__FUNC_SCP_SPI1_A_MI (MTK_PIN_NO(139) | 2) +#define PINMUX_GPIO139__FUNC_SPIS1_SO (MTK_PIN_NO(139) | 3) +#define PINMUX_GPIO139__FUNC_MD32_1_JTAG_TDI (MTK_PIN_NO(139) | 4) +#define PINMUX_GPIO139__FUNC_SCP_JTAG0_TDI (MTK_PIN_NO(139) | 5) +#define PINMUX_GPIO139__FUNC_APU_JTAG_TDI (MTK_PIN_NO(139) | 6) +#define PINMUX_GPIO139__FUNC_DBG_MON_A17 (MTK_PIN_NO(139) | 7) + +#define PINMUX_GPIO140__FUNC_GPIO140 (MTK_PIN_NO(140) | 0) +#define PINMUX_GPIO140__FUNC_SPIM2_CSB (MTK_PIN_NO(140) | 1) +#define PINMUX_GPIO140__FUNC_SPINOR_CS (MTK_PIN_NO(140) | 2) +#define PINMUX_GPIO140__FUNC_SNFI_CS (MTK_PIN_NO(140) | 3) +#define PINMUX_GPIO140__FUNC_DMIC3_DAT (MTK_PIN_NO(140) | 4) +#define PINMUX_GPIO140__FUNC_DBG_MON_A11 (MTK_PIN_NO(140) | 7) + +#define PINMUX_GPIO141__FUNC_GPIO141 (MTK_PIN_NO(141) | 0) +#define PINMUX_GPIO141__FUNC_SPIM2_CLK (MTK_PIN_NO(141) | 1) +#define PINMUX_GPIO141__FUNC_SPINOR_CK (MTK_PIN_NO(141) | 2) +#define PINMUX_GPIO141__FUNC_SNFI_CLK (MTK_PIN_NO(141) | 3) +#define PINMUX_GPIO141__FUNC_DMIC3_CLK (MTK_PIN_NO(141) | 4) +#define PINMUX_GPIO141__FUNC_DBG_MON_A10 (MTK_PIN_NO(141) | 7) + +#define PINMUX_GPIO142__FUNC_GPIO142 (MTK_PIN_NO(142) | 0) +#define PINMUX_GPIO142__FUNC_SPIM2_MO (MTK_PIN_NO(142) | 1) +#define PINMUX_GPIO142__FUNC_SPINOR_IO0 (MTK_PIN_NO(142) | 2) +#define PINMUX_GPIO142__FUNC_SNFI_MOSI (MTK_PIN_NO(142) | 3) +#define PINMUX_GPIO142__FUNC_DMIC4_DAT (MTK_PIN_NO(142) | 4) +#define PINMUX_GPIO142__FUNC_DBG_MON_A12 (MTK_PIN_NO(142) | 7) + +#define PINMUX_GPIO143__FUNC_GPIO143 (MTK_PIN_NO(143) | 0) +#define PINMUX_GPIO143__FUNC_SPIM2_MI (MTK_PIN_NO(143) | 1) +#define PINMUX_GPIO143__FUNC_SPINOR_IO1 (MTK_PIN_NO(143) | 2) +#define PINMUX_GPIO143__FUNC_SNFI_MISO (MTK_PIN_NO(143) | 3) +#define PINMUX_GPIO143__FUNC_DMIC4_CLK (MTK_PIN_NO(143) | 4) +#define PINMUX_GPIO143__FUNC_DBG_MON_A13 (MTK_PIN_NO(143) | 7) + +#endif /* __MT8195-PINFUNC_H */ -- cgit v1.2.3 From 6cf5e9ef362af824de2e4e8afb78d74537f1e3db Mon Sep 17 00:00:00 2001 From: Zhiyong Tao Date: Tue, 13 Apr 2021 13:57:00 +0800 Subject: pinctrl: add pinctrl driver on mt8195 This commit includes pinctrl driver for mt8195. Signed-off-by: Zhiyong Tao Acked-by: Sean Wang Link: https://lore.kernel.org/r/20210413055702.27535-3-zhiyong.tao@mediatek.com Signed-off-by: Linus Walleij --- drivers/pinctrl/mediatek/Kconfig | 6 + drivers/pinctrl/mediatek/Makefile | 1 + drivers/pinctrl/mediatek/pinctrl-mt8195.c | 828 ++++++++++++ drivers/pinctrl/mediatek/pinctrl-mtk-mt8195.h | 1669 +++++++++++++++++++++++++ 4 files changed, 2504 insertions(+) create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt8195.c create mode 100644 drivers/pinctrl/mediatek/pinctrl-mtk-mt8195.h diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig index eef17f228669..90f0c8255eaf 100644 --- a/drivers/pinctrl/mediatek/Kconfig +++ b/drivers/pinctrl/mediatek/Kconfig @@ -147,6 +147,12 @@ config PINCTRL_MT8192 default ARM64 && ARCH_MEDIATEK select PINCTRL_MTK_PARIS +config PINCTRL_MT8195 + bool "Mediatek MT8195 pin control" + depends on OF + depends on ARM64 || COMPILE_TEST + select PINCTRL_MTK_PARIS + config PINCTRL_MT8516 bool "Mediatek MT8516 pin control" depends on OF diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile index 01218bf4dc30..06fde993ace2 100644 --- a/drivers/pinctrl/mediatek/Makefile +++ b/drivers/pinctrl/mediatek/Makefile @@ -21,5 +21,6 @@ obj-$(CONFIG_PINCTRL_MT8167) += pinctrl-mt8167.o obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o obj-$(CONFIG_PINCTRL_MT8183) += pinctrl-mt8183.o obj-$(CONFIG_PINCTRL_MT8192) += pinctrl-mt8192.o +obj-$(CONFIG_PINCTRL_MT8195) += pinctrl-mt8195.o obj-$(CONFIG_PINCTRL_MT8516) += pinctrl-mt8516.o obj-$(CONFIG_PINCTRL_MT6397) += pinctrl-mt6397.o diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8195.c b/drivers/pinctrl/mediatek/pinctrl-mt8195.c new file mode 100644 index 000000000000..063f164d7c9b --- /dev/null +++ b/drivers/pinctrl/mediatek/pinctrl-mt8195.c @@ -0,0 +1,828 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 MediaTek Inc. + * + * Author: Zhiyong Tao + * + */ + +#include "pinctrl-mtk-mt8195.h" +#include "pinctrl-paris.h" + +/* MT8195 have multiple bases to program pin configuration listed as the below: + * iocfg[0]:0x10005000, iocfg[1]:0x11d10000, iocfg[2]:0x11d30000, + * iocfg[3]:0x11d40000, iocfg[4]:0x11e20000, iocfg[5]:0x11eb0000, + * iocfg[6]:0x11f40000. + * _i_based could be used to indicate what base the pin should be mapped into. + */ + +#define PIN_FIELD_BASE(s_pin, e_pin, i_base, s_addr, x_addrs, s_bit, x_bits) \ + PIN_FIELD_CALC(s_pin, e_pin, i_base, s_addr, x_addrs, s_bit, x_bits, \ + 32, 0) + +#define PINS_FIELD_BASE(s_pin, e_pin, i_base, s_addr, x_addrs, s_bit, x_bits) \ + PIN_FIELD_CALC(s_pin, e_pin, i_base, s_addr, x_addrs, s_bit, x_bits, \ + 32, 1) + +static const struct mtk_pin_field_calc mt8195_pin_mode_range[] = { + PIN_FIELD(0, 144, 0x300, 0x10, 0, 4), +}; + +static const struct mtk_pin_field_calc mt8195_pin_dir_range[] = { + PIN_FIELD(0, 144, 0x0, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt8195_pin_di_range[] = { + PIN_FIELD(0, 144, 0x200, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt8195_pin_do_range[] = { + PIN_FIELD(0, 144, 0x100, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt8195_pin_ies_range[] = { + PIN_FIELD_BASE(0, 0, 4, 0x040, 0x10, 0, 1), + PIN_FIELD_BASE(1, 1, 4, 0x040, 0x10, 1, 1), + PIN_FIELD_BASE(2, 2, 4, 0x040, 0x10, 2, 1), + PIN_FIELD_BASE(3, 3, 4, 0x040, 0x10, 3, 1), + PIN_FIELD_BASE(4, 4, 4, 0x040, 0x10, 4, 1), + PIN_FIELD_BASE(5, 5, 4, 0x040, 0x10, 5, 1), + PIN_FIELD_BASE(6, 6, 4, 0x040, 0x10, 6, 1), + PIN_FIELD_BASE(7, 7, 4, 0x040, 0x10, 7, 1), + PIN_FIELD_BASE(8, 8, 4, 0x040, 0x10, 13, 1), + PIN_FIELD_BASE(9, 9, 4, 0x040, 0x10, 8, 1), + PIN_FIELD_BASE(10, 10, 4, 0x040, 0x10, 14, 1), + PIN_FIELD_BASE(11, 11, 4, 0x040, 0x10, 9, 1), + PIN_FIELD_BASE(12, 12, 4, 0x040, 0x10, 15, 1), + PIN_FIELD_BASE(13, 13, 4, 0x040, 0x10, 10, 1), + PIN_FIELD_BASE(14, 14, 4, 0x040, 0x10, 16, 1), + PIN_FIELD_BASE(15, 15, 4, 0x040, 0x10, 11, 1), + PIN_FIELD_BASE(16, 16, 4, 0x040, 0x10, 17, 1), + PIN_FIELD_BASE(17, 17, 4, 0x040, 0x10, 12, 1), + PIN_FIELD_BASE(18, 18, 2, 0x040, 0x10, 5, 1), + PIN_FIELD_BASE(19, 19, 2, 0x040, 0x10, 12, 1), + PIN_FIELD_BASE(20, 20, 2, 0x040, 0x10, 11, 1), + PIN_FIELD_BASE(21, 21, 2, 0x040, 0x10, 10, 1), + PIN_FIELD_BASE(22, 22, 2, 0x040, 0x10, 0, 1), + PIN_FIELD_BASE(23, 23, 2, 0x040, 0x10, 1, 1), + PIN_FIELD_BASE(24, 24, 2, 0x040, 0x10, 2, 1), + PIN_FIELD_BASE(25, 25, 2, 0x040, 0x10, 4, 1), + PIN_FIELD_BASE(26, 26, 2, 0x040, 0x10, 3, 1), + PIN_FIELD_BASE(27, 27, 2, 0x040, 0x10, 6, 1), + PIN_FIELD_BASE(28, 28, 2, 0x040, 0x10, 7, 1), + PIN_FIELD_BASE(29, 29, 2, 0x040, 0x10, 8, 1), + PIN_FIELD_BASE(30, 30, 2, 0x040, 0x10, 9, 1), + PIN_FIELD_BASE(31, 31, 1, 0x060, 0x10, 13, 1), + PIN_FIELD_BASE(32, 32, 1, 0x060, 0x10, 12, 1), + PIN_FIELD_BASE(33, 33, 1, 0x060, 0x10, 11, 1), + PIN_FIELD_BASE(34, 34, 1, 0x060, 0x10, 14, 1), + PIN_FIELD_BASE(35, 35, 1, 0x060, 0x10, 15, 1), + PIN_FIELD_BASE(36, 36, 1, 0x070, 0x10, 3, 1), + PIN_FIELD_BASE(37, 37, 1, 0x070, 0x10, 6, 1), + PIN_FIELD_BASE(38, 38, 1, 0x070, 0x10, 4, 1), + PIN_FIELD_BASE(39, 39, 1, 0x070, 0x10, 5, 1), + PIN_FIELD_BASE(40, 40, 1, 0x070, 0x10, 8, 1), + PIN_FIELD_BASE(41, 41, 1, 0x070, 0x10, 7, 1), + PIN_FIELD_BASE(42, 42, 1, 0x070, 0x10, 10, 1), + PIN_FIELD_BASE(43, 43, 1, 0x070, 0x10, 9, 1), + PIN_FIELD_BASE(44, 44, 1, 0x070, 0x10, 20, 1), + PIN_FIELD_BASE(45, 45, 1, 0x070, 0x10, 21, 1), + PIN_FIELD_BASE(46, 46, 1, 0x060, 0x10, 18, 1), + PIN_FIELD_BASE(47, 47, 1, 0x060, 0x10, 16, 1), + PIN_FIELD_BASE(48, 48, 1, 0x060, 0x10, 19, 1), + PIN_FIELD_BASE(49, 49, 1, 0x060, 0x10, 17, 1), + PIN_FIELD_BASE(50, 50, 1, 0x060, 0x10, 25, 1), + PIN_FIELD_BASE(51, 51, 1, 0x060, 0x10, 20, 1), + PIN_FIELD_BASE(52, 52, 1, 0x060, 0x10, 26, 1), + PIN_FIELD_BASE(53, 53, 1, 0x060, 0x10, 21, 1), + PIN_FIELD_BASE(54, 54, 1, 0x060, 0x10, 22, 1), + PIN_FIELD_BASE(55, 55, 1, 0x060, 0x10, 23, 1), + PIN_FIELD_BASE(56, 56, 1, 0x060, 0x10, 24, 1), + PIN_FIELD_BASE(57, 57, 1, 0x060, 0x10, 29, 1), + PIN_FIELD_BASE(58, 58, 1, 0x060, 0x10, 27, 1), + PIN_FIELD_BASE(59, 59, 1, 0x060, 0x10, 30, 1), + PIN_FIELD_BASE(60, 60, 1, 0x060, 0x10, 28, 1), + PIN_FIELD_BASE(61, 61, 1, 0x060, 0x10, 8, 1), + PIN_FIELD_BASE(62, 62, 1, 0x060, 0x10, 7, 1), + PIN_FIELD_BASE(63, 63, 1, 0x060, 0x10, 10, 1), + PIN_FIELD_BASE(64, 64, 1, 0x060, 0x10, 9, 1), + PIN_FIELD_BASE(65, 65, 1, 0x070, 0x10, 1, 1), + PIN_FIELD_BASE(66, 66, 1, 0x060, 0x10, 31, 1), + PIN_FIELD_BASE(67, 67, 1, 0x070, 0x10, 0, 1), + PIN_FIELD_BASE(68, 68, 1, 0x070, 0x10, 2, 1), + PIN_FIELD_BASE(69, 69, 1, 0x060, 0x10, 0, 1), + PIN_FIELD_BASE(70, 70, 1, 0x060, 0x10, 6, 1), + PIN_FIELD_BASE(71, 71, 1, 0x060, 0x10, 4, 1), + PIN_FIELD_BASE(72, 72, 1, 0x060, 0x10, 5, 1), + PIN_FIELD_BASE(73, 73, 1, 0x060, 0x10, 1, 1), + PIN_FIELD_BASE(74, 74, 1, 0x060, 0x10, 2, 1), + PIN_FIELD_BASE(75, 75, 1, 0x060, 0x10, 3, 1), + PIN_FIELD_BASE(76, 76, 1, 0x070, 0x10, 11, 1), + PIN_FIELD_BASE(77, 77, 3, 0x030, 0x10, 1, 1), + PIN_FIELD_BASE(78, 78, 3, 0x030, 0x10, 2, 1), + PIN_FIELD_BASE(79, 79, 3, 0x030, 0x10, 9, 1), + PIN_FIELD_BASE(80, 80, 3, 0x030, 0x10, 10, 1), + PIN_FIELD_BASE(81, 81, 3, 0x030, 0x10, 11, 1), + PIN_FIELD_BASE(82, 82, 3, 0x030, 0x10, 12, 1), + PIN_FIELD_BASE(83, 83, 3, 0x030, 0x10, 13, 1), + PIN_FIELD_BASE(84, 84, 3, 0x030, 0x10, 14, 1), + PIN_FIELD_BASE(85, 85, 3, 0x030, 0x10, 15, 1), + PIN_FIELD_BASE(86, 86, 3, 0x030, 0x10, 16, 1), + PIN_FIELD_BASE(87, 87, 3, 0x030, 0x10, 3, 1), + PIN_FIELD_BASE(88, 88, 3, 0x030, 0x10, 4, 1), + PIN_FIELD_BASE(89, 89, 3, 0x030, 0x10, 5, 1), + PIN_FIELD_BASE(90, 90, 3, 0x030, 0x10, 6, 1), + PIN_FIELD_BASE(91, 91, 3, 0x030, 0x10, 7, 1), + PIN_FIELD_BASE(92, 92, 3, 0x030, 0x10, 8, 1), + PIN_FIELD_BASE(93, 93, 3, 0x030, 0x10, 18, 1), + PIN_FIELD_BASE(94, 94, 3, 0x030, 0x10, 19, 1), + PIN_FIELD_BASE(95, 95, 3, 0x030, 0x10, 17, 1), + PIN_FIELD_BASE(96, 96, 3, 0x030, 0x10, 0, 1), + PIN_FIELD_BASE(97, 97, 3, 0x030, 0x10, 20, 1), + PIN_FIELD_BASE(98, 98, 3, 0x030, 0x10, 28, 1), + PIN_FIELD_BASE(99, 99, 3, 0x030, 0x10, 27, 1), + PIN_FIELD_BASE(100, 100, 3, 0x030, 0x10, 30, 1), + PIN_FIELD_BASE(101, 101, 3, 0x030, 0x10, 29, 1), + PIN_FIELD_BASE(102, 102, 3, 0x040, 0x10, 0, 1), + PIN_FIELD_BASE(103, 103, 3, 0x030, 0x10, 31, 1), + PIN_FIELD_BASE(104, 104, 3, 0x030, 0x10, 25, 1), + PIN_FIELD_BASE(105, 105, 3, 0x030, 0x10, 26, 1), + PIN_FIELD_BASE(106, 106, 3, 0x030, 0x10, 23, 1), + PIN_FIELD_BASE(107, 107, 3, 0x030, 0x10, 24, 1), + PIN_FIELD_BASE(108, 108, 3, 0x030, 0x10, 22, 1), + PIN_FIELD_BASE(109, 109, 3, 0x030, 0x10, 21, 1), + PIN_FIELD_BASE(110, 110, 5, 0x010, 0x10, 1, 1), + PIN_FIELD_BASE(111, 111, 5, 0x010, 0x10, 0, 1), + PIN_FIELD_BASE(112, 112, 5, 0x010, 0x10, 2, 1), + PIN_FIELD_BASE(113, 113, 5, 0x010, 0x10, 3, 1), + PIN_FIELD_BASE(114, 114, 5, 0x010, 0x10, 4, 1), + PIN_FIELD_BASE(115, 115, 5, 0x010, 0x10, 5, 1), + PIN_FIELD_BASE(116, 116, 6, 0x030, 0x10, 9, 1), + PIN_FIELD_BASE(117, 117, 6, 0x030, 0x10, 8, 1), + PIN_FIELD_BASE(118, 118, 6, 0x030, 0x10, 7, 1), + PIN_FIELD_BASE(119, 119, 6, 0x030, 0x10, 6, 1), + PIN_FIELD_BASE(120, 120, 6, 0x030, 0x10, 11, 1), + PIN_FIELD_BASE(121, 121, 6, 0x030, 0x10, 1, 1), + PIN_FIELD_BASE(122, 122, 6, 0x030, 0x10, 0, 1), + PIN_FIELD_BASE(123, 123, 6, 0x030, 0x10, 5, 1), + PIN_FIELD_BASE(124, 124, 6, 0x030, 0x10, 4, 1), + PIN_FIELD_BASE(125, 125, 6, 0x030, 0x10, 3, 1), + PIN_FIELD_BASE(126, 126, 6, 0x030, 0x10, 2, 1), + PIN_FIELD_BASE(127, 127, 6, 0x030, 0x10, 10, 1), + PIN_FIELD_BASE(128, 128, 3, 0x040, 0x10, 3, 1), + PIN_FIELD_BASE(129, 129, 3, 0x040, 0x10, 1, 1), + PIN_FIELD_BASE(130, 130, 3, 0x040, 0x10, 4, 1), + PIN_FIELD_BASE(131, 131, 3, 0x040, 0x10, 2, 1), + PIN_FIELD_BASE(132, 132, 6, 0x030, 0x10, 13, 1), + PIN_FIELD_BASE(133, 133, 6, 0x030, 0x10, 12, 1), + PIN_FIELD_BASE(134, 134, 6, 0x030, 0x10, 15, 1), + PIN_FIELD_BASE(135, 135, 6, 0x030, 0x10, 14, 1), + PIN_FIELD_BASE(136, 136, 1, 0x070, 0x10, 13, 1), + PIN_FIELD_BASE(137, 137, 1, 0x070, 0x10, 12, 1), + PIN_FIELD_BASE(138, 138, 1, 0x070, 0x10, 15, 1), + PIN_FIELD_BASE(139, 139, 1, 0x070, 0x10, 14, 1), + PIN_FIELD_BASE(140, 140, 1, 0x070, 0x10, 17, 1), + PIN_FIELD_BASE(141, 141, 1, 0x070, 0x10, 16, 1), + PIN_FIELD_BASE(142, 142, 1, 0x070, 0x10, 19, 1), + PIN_FIELD_BASE(143, 143, 1, 0x070, 0x10, 18, 1), +}; + +static const struct mtk_pin_field_calc mt8195_pin_smt_range[] = { + PIN_FIELD_BASE(0, 0, 4, 0x0d0, 0x10, 0, 1), + PIN_FIELD_BASE(1, 1, 4, 0x0d0, 0x10, 1, 1), + PIN_FIELD_BASE(2, 2, 4, 0x0d0, 0x10, 2, 1), + PIN_FIELD_BASE(3, 3, 4, 0x0d0, 0x10, 3, 1), + PIN_FIELD_BASE(4, 4, 4, 0x0d0, 0x10, 4, 1), + PIN_FIELD_BASE(5, 5, 4, 0x0d0, 0x10, 5, 1), + PINS_FIELD_BASE(6, 7, 4, 0x0d0, 0x10, 6, 1), + PIN_FIELD_BASE(8, 8, 4, 0x0d0, 0x10, 12, 1), + PIN_FIELD_BASE(9, 9, 4, 0x0d0, 0x10, 7, 1), + PIN_FIELD_BASE(10, 10, 4, 0x0d0, 0x10, 13, 1), + PIN_FIELD_BASE(11, 11, 4, 0x0d0, 0x10, 8, 1), + PIN_FIELD_BASE(12, 12, 4, 0x0d0, 0x10, 14, 1), + PIN_FIELD_BASE(13, 13, 4, 0x0d0, 0x10, 9, 1), + PIN_FIELD_BASE(14, 14, 4, 0x0d0, 0x10, 15, 1), + PIN_FIELD_BASE(15, 15, 4, 0x0d0, 0x10, 10, 1), + PIN_FIELD_BASE(16, 16, 4, 0x0d0, 0x10, 16, 1), + PIN_FIELD_BASE(17, 17, 4, 0x0d0, 0x10, 11, 1), + PIN_FIELD_BASE(18, 18, 2, 0x090, 0x10, 11, 1), + PIN_FIELD_BASE(19, 19, 2, 0x090, 0x10, 10, 1), + PIN_FIELD_BASE(20, 20, 2, 0x090, 0x10, 9, 1), + PIN_FIELD_BASE(21, 21, 2, 0x090, 0x10, 11, 1), + PIN_FIELD_BASE(22, 22, 2, 0x090, 0x10, 0, 1), + PIN_FIELD_BASE(23, 23, 2, 0x090, 0x10, 1, 1), + PIN_FIELD_BASE(24, 24, 2, 0x090, 0x10, 2, 1), + PIN_FIELD_BASE(25, 25, 2, 0x090, 0x10, 4, 1), + PIN_FIELD_BASE(26, 26, 2, 0x090, 0x10, 3, 1), + PIN_FIELD_BASE(27, 27, 2, 0x090, 0x10, 5, 1), + PIN_FIELD_BASE(28, 28, 2, 0x090, 0x10, 6, 1), + PIN_FIELD_BASE(29, 29, 2, 0x090, 0x10, 7, 1), + PIN_FIELD_BASE(30, 30, 2, 0x090, 0x10, 8, 1), + PINS_FIELD_BASE(31, 33, 1, 0x0f0, 0x10, 4, 1), + PIN_FIELD_BASE(34, 34, 1, 0x0f0, 0x10, 0, 1), + PIN_FIELD_BASE(35, 35, 1, 0x0f0, 0x10, 1, 1), + PIN_FIELD_BASE(36, 36, 1, 0x0f0, 0x10, 4, 1), + PIN_FIELD_BASE(37, 37, 1, 0x0f0, 0x10, 2, 1), + PINS_FIELD_BASE(38, 39, 1, 0x0f0, 0x10, 5, 1), + PIN_FIELD_BASE(40, 40, 1, 0x0f0, 0x10, 14, 1), + PIN_FIELD_BASE(41, 41, 1, 0x0f0, 0x10, 13, 1), + PIN_FIELD_BASE(42, 42, 1, 0x0f0, 0x10, 16, 1), + PIN_FIELD_BASE(43, 43, 1, 0x0f0, 0x10, 15, 1), + PIN_FIELD_BASE(44, 44, 1, 0x0f0, 0x10, 25, 1), + PIN_FIELD_BASE(45, 45, 1, 0x0f0, 0x10, 26, 1), + PINS_FIELD_BASE(46, 47, 1, 0x0f0, 0x10, 5, 1), + PINS_FIELD_BASE(48, 51, 1, 0x0f0, 0x10, 6, 1), + PINS_FIELD_BASE(52, 55, 1, 0x0f0, 0x10, 7, 1), + PINS_FIELD_BASE(56, 59, 1, 0x0f0, 0x10, 8, 1), + PINS_FIELD_BASE(60, 63, 1, 0x0f0, 0x10, 9, 1), + PIN_FIELD_BASE(64, 64, 1, 0x0f0, 0x10, 10, 1), + PINS_FIELD_BASE(65, 68, 1, 0x0f0, 0x10, 3, 1), + PINS_FIELD_BASE(69, 71, 1, 0x0f0, 0x10, 10, 1), + PINS_FIELD_BASE(72, 75, 1, 0x0f0, 0x10, 11, 1), + PIN_FIELD_BASE(76, 76, 1, 0x0f0, 0x10, 12, 1), + PIN_FIELD_BASE(77, 77, 3, 0x0e0, 0x10, 0, 1), + PIN_FIELD_BASE(78, 78, 3, 0x0e0, 0x10, 1, 1), + PIN_FIELD_BASE(79, 79, 3, 0x0e0, 0x10, 6, 1), + PIN_FIELD_BASE(80, 80, 3, 0x0e0, 0x10, 7, 1), + PIN_FIELD_BASE(81, 81, 3, 0x0e0, 0x10, 8, 1), + PIN_FIELD_BASE(82, 82, 3, 0x0e0, 0x10, 9, 1), + PIN_FIELD_BASE(83, 83, 3, 0x0e0, 0x10, 10, 1), + PIN_FIELD_BASE(84, 84, 3, 0x0e0, 0x10, 11, 1), + PINS_FIELD_BASE(85, 88, 3, 0x0e0, 0x10, 14, 1), + PIN_FIELD_BASE(89, 89, 3, 0x0e0, 0x10, 2, 1), + PIN_FIELD_BASE(90, 90, 3, 0x0e0, 0x10, 3, 1), + PIN_FIELD_BASE(91, 91, 3, 0x0e0, 0x10, 4, 1), + PIN_FIELD_BASE(92, 92, 3, 0x0e0, 0x10, 5, 1), + PIN_FIELD_BASE(93, 93, 3, 0x0e0, 0x10, 12, 1), + PIN_FIELD_BASE(94, 94, 3, 0x0e0, 0x10, 13, 1), + PINS_FIELD_BASE(95, 98, 3, 0x0e0, 0x10, 15, 1), + PINS_FIELD_BASE(99, 102, 3, 0x0e0, 0x10, 16, 1), + PINS_FIELD_BASE(103, 104, 3, 0x0e0, 0x10, 17, 1), + PIN_FIELD_BASE(105, 105, 3, 0x0e0, 0x10, 18, 1), + PINS_FIELD_BASE(106, 107, 3, 0x0e0, 0x10, 17, 1), + PINS_FIELD_BASE(108, 109, 3, 0x0e0, 0x10, 18, 1), + PIN_FIELD_BASE(110, 110, 5, 0x070, 0x10, 1, 1), + PIN_FIELD_BASE(111, 111, 5, 0x070, 0x10, 0, 1), + PIN_FIELD_BASE(112, 112, 5, 0x070, 0x10, 2, 1), + PIN_FIELD_BASE(113, 113, 5, 0x070, 0x10, 3, 1), + PIN_FIELD_BASE(114, 114, 5, 0x070, 0x10, 4, 1), + PIN_FIELD_BASE(115, 115, 5, 0x070, 0x10, 5, 1), + PIN_FIELD_BASE(116, 116, 6, 0x0c0, 0x10, 9, 1), + PIN_FIELD_BASE(117, 117, 6, 0x0c0, 0x10, 8, 1), + PIN_FIELD_BASE(118, 118, 6, 0x0c0, 0x10, 7, 1), + PIN_FIELD_BASE(119, 119, 6, 0x0c0, 0x10, 6, 1), + PIN_FIELD_BASE(120, 120, 6, 0x0c0, 0x10, 11, 1), + PIN_FIELD_BASE(121, 121, 6, 0x0c0, 0x10, 1, 1), + PIN_FIELD_BASE(122, 122, 6, 0x0c0, 0x10, 0, 1), + PIN_FIELD_BASE(123, 123, 6, 0x0c0, 0x10, 5, 1), + PIN_FIELD_BASE(124, 124, 6, 0x0c0, 0x10, 4, 1), + PIN_FIELD_BASE(125, 125, 6, 0x0c0, 0x10, 3, 1), + PIN_FIELD_BASE(126, 126, 6, 0x0c0, 0x10, 2, 1), + PIN_FIELD_BASE(127, 127, 6, 0x0c0, 0x10, 10, 1), + PIN_FIELD_BASE(128, 128, 3, 0x0e0, 0x10, 18, 1), + PINS_FIELD_BASE(129, 131, 3, 0x0e0, 0x10, 19, 1), + PIN_FIELD_BASE(132, 132, 6, 0x0c0, 0x10, 13, 1), + PIN_FIELD_BASE(133, 133, 6, 0x0c0, 0x10, 12, 1), + PIN_FIELD_BASE(134, 134, 6, 0x0c0, 0x10, 15, 1), + PIN_FIELD_BASE(135, 135, 6, 0x0c0, 0x10, 14, 1), + PIN_FIELD_BASE(136, 136, 1, 0x0f0, 0x10, 18, 1), + PIN_FIELD_BASE(137, 137, 1, 0x0f0, 0x10, 17, 1), + PIN_FIELD_BASE(138, 138, 1, 0x0f0, 0x10, 20, 1), + PIN_FIELD_BASE(139, 139, 1, 0x0f0, 0x10, 19, 1), + PIN_FIELD_BASE(140, 140, 1, 0x0f0, 0x10, 22, 1), + PIN_FIELD_BASE(141, 141, 1, 0x0f0, 0x10, 21, 1), + PIN_FIELD_BASE(142, 142, 1, 0x0f0, 0x10, 24, 1), + PIN_FIELD_BASE(143, 143, 1, 0x0f0, 0x10, 23, 1), +}; + +static const struct mtk_pin_field_calc mt8195_pin_pu_range[] = { + PIN_FIELD_BASE(6, 6, 4, 0x0070, 0x10, 0, 1), + PIN_FIELD_BASE(7, 7, 4, 0x0070, 0x10, 1, 1), + PIN_FIELD_BASE(8, 8, 4, 0x0070, 0x10, 7, 1), + PIN_FIELD_BASE(9, 9, 4, 0x0070, 0x10, 2, 1), + PIN_FIELD_BASE(10, 10, 4, 0x0070, 0x10, 8, 1), + PIN_FIELD_BASE(11, 11, 4, 0x0070, 0x10, 3, 1), + PIN_FIELD_BASE(12, 12, 4, 0x0070, 0x10, 9, 1), + PIN_FIELD_BASE(13, 13, 4, 0x0070, 0x10, 4, 1), + PIN_FIELD_BASE(14, 14, 4, 0x0070, 0x10, 10, 1), + PIN_FIELD_BASE(15, 15, 4, 0x0070, 0x10, 5, 1), + PIN_FIELD_BASE(16, 16, 4, 0x0070, 0x10, 11, 1), + PIN_FIELD_BASE(17, 17, 4, 0x0070, 0x10, 6, 1), + PIN_FIELD_BASE(18, 18, 2, 0x0060, 0x10, 5, 1), + PIN_FIELD_BASE(19, 19, 2, 0x0060, 0x10, 12, 1), + PIN_FIELD_BASE(20, 20, 2, 0x0060, 0x10, 11, 1), + PIN_FIELD_BASE(21, 21, 2, 0x0060, 0x10, 10, 1), + PIN_FIELD_BASE(22, 22, 2, 0x0060, 0x10, 0, 1), + PIN_FIELD_BASE(23, 23, 2, 0x0060, 0x10, 1, 1), + PIN_FIELD_BASE(24, 24, 2, 0x0060, 0x10, 2, 1), + PIN_FIELD_BASE(25, 25, 2, 0x0060, 0x10, 4, 1), + PIN_FIELD_BASE(26, 26, 2, 0x0060, 0x10, 3, 1), + PIN_FIELD_BASE(27, 27, 2, 0x0060, 0x10, 6, 1), + PIN_FIELD_BASE(28, 28, 2, 0x0060, 0x10, 7, 1), + PIN_FIELD_BASE(29, 29, 2, 0x0060, 0x10, 8, 1), + PIN_FIELD_BASE(30, 30, 2, 0x0060, 0x10, 9, 1), + PIN_FIELD_BASE(31, 31, 1, 0x00a0, 0x10, 13, 1), + PIN_FIELD_BASE(32, 32, 1, 0x00a0, 0x10, 12, 1), + PIN_FIELD_BASE(33, 33, 1, 0x00a0, 0x10, 11, 1), + PIN_FIELD_BASE(34, 34, 1, 0x00a0, 0x10, 14, 1), + PIN_FIELD_BASE(35, 35, 1, 0x00a0, 0x10, 15, 1), + PIN_FIELD_BASE(36, 36, 1, 0x00b0, 0x10, 3, 1), + PIN_FIELD_BASE(37, 37, 1, 0x00b0, 0x10, 6, 1), + PIN_FIELD_BASE(38, 38, 1, 0x00b0, 0x10, 4, 1), + PIN_FIELD_BASE(39, 39, 1, 0x00b0, 0x10, 5, 1), + PIN_FIELD_BASE(40, 40, 1, 0x00b0, 0x10, 8, 1), + PIN_FIELD_BASE(41, 41, 1, 0x00b0, 0x10, 7, 1), + PIN_FIELD_BASE(42, 42, 1, 0x00b0, 0x10, 10, 1), + PIN_FIELD_BASE(43, 43, 1, 0x00b0, 0x10, 9, 1), + PIN_FIELD_BASE(44, 44, 1, 0x00b0, 0x10, 21, 1), + PIN_FIELD_BASE(45, 45, 1, 0x00b0, 0x10, 22, 1), + PIN_FIELD_BASE(46, 46, 1, 0x00a0, 0x10, 18, 1), + PIN_FIELD_BASE(47, 47, 1, 0x00a0, 0x10, 16, 1), + PIN_FIELD_BASE(48, 48, 1, 0x00a0, 0x10, 19, 1), + PIN_FIELD_BASE(49, 49, 1, 0x00a0, 0x10, 17, 1), + PIN_FIELD_BASE(50, 50, 1, 0x00a0, 0x10, 25, 1), + PIN_FIELD_BASE(51, 51, 1, 0x00a0, 0x10, 20, 1), + PIN_FIELD_BASE(52, 52, 1, 0x00a0, 0x10, 26, 1), + PIN_FIELD_BASE(53, 53, 1, 0x00a0, 0x10, 21, 1), + PIN_FIELD_BASE(54, 54, 1, 0x00a0, 0x10, 22, 1), + PIN_FIELD_BASE(55, 55, 1, 0x00a0, 0x10, 23, 1), + PIN_FIELD_BASE(56, 56, 1, 0x00a0, 0x10, 24, 1), + PIN_FIELD_BASE(57, 57, 1, 0x00a0, 0x10, 29, 1), + PIN_FIELD_BASE(58, 58, 1, 0x00a0, 0x10, 27, 1), + PIN_FIELD_BASE(59, 59, 1, 0x00a0, 0x10, 30, 1), + PIN_FIELD_BASE(60, 60, 1, 0x00a0, 0x10, 28, 1), + PIN_FIELD_BASE(61, 61, 1, 0x00a0, 0x10, 8, 1), + PIN_FIELD_BASE(62, 62, 1, 0x00a0, 0x10, 7, 1), + PIN_FIELD_BASE(63, 63, 1, 0x00a0, 0x10, 10, 1), + PIN_FIELD_BASE(64, 64, 1, 0x00a0, 0x10, 9, 1), + PIN_FIELD_BASE(65, 65, 1, 0x00b0, 0x10, 1, 1), + PIN_FIELD_BASE(66, 66, 1, 0x00a0, 0x10, 31, 1), + PIN_FIELD_BASE(67, 67, 1, 0x00b0, 0x10, 0, 1), + PIN_FIELD_BASE(68, 68, 1, 0x00b0, 0x10, 2, 1), + PIN_FIELD_BASE(69, 69, 1, 0x00a0, 0x10, 0, 1), + PIN_FIELD_BASE(70, 70, 1, 0x00a0, 0x10, 6, 1), + PIN_FIELD_BASE(71, 71, 1, 0x00a0, 0x10, 4, 1), + PIN_FIELD_BASE(72, 72, 1, 0x00a0, 0x10, 5, 1), + PIN_FIELD_BASE(73, 73, 1, 0x00a0, 0x10, 1, 1), + PIN_FIELD_BASE(74, 74, 1, 0x00a0, 0x10, 2, 1), + PIN_FIELD_BASE(75, 75, 1, 0x00a0, 0x10, 3, 1), + PIN_FIELD_BASE(76, 76, 1, 0x00b0, 0x10, 11, 1), + PIN_FIELD_BASE(97, 97, 3, 0x0070, 0x10, 0, 1), + PIN_FIELD_BASE(98, 98, 3, 0x0070, 0x10, 4, 1), + PIN_FIELD_BASE(99, 99, 3, 0x0070, 0x10, 3, 1), + PIN_FIELD_BASE(100, 100, 3, 0x0070, 0x10, 6, 1), + PIN_FIELD_BASE(101, 101, 3, 0x0070, 0x10, 5, 1), + PIN_FIELD_BASE(102, 102, 3, 0x0070, 0x10, 8, 1), + PIN_FIELD_BASE(103, 103, 3, 0x0070, 0x10, 7, 1), + PIN_FIELD_BASE(108, 108, 3, 0x0070, 0x10, 2, 1), + PIN_FIELD_BASE(109, 109, 3, 0x0070, 0x10, 1, 1), + PIN_FIELD_BASE(128, 128, 3, 0x0070, 0x10, 11, 1), + PIN_FIELD_BASE(129, 129, 3, 0x0070, 0x10, 9, 1), + PIN_FIELD_BASE(130, 130, 3, 0x0070, 0x10, 12, 1), + PIN_FIELD_BASE(131, 131, 3, 0x0070, 0x10, 10, 1), + PIN_FIELD_BASE(132, 132, 6, 0x0060, 0x10, 1, 1), + PIN_FIELD_BASE(133, 133, 6, 0x0060, 0x10, 0, 1), + PIN_FIELD_BASE(134, 134, 6, 0x0060, 0x10, 3, 1), + PIN_FIELD_BASE(135, 135, 6, 0x0060, 0x10, 2, 1), + PIN_FIELD_BASE(136, 136, 1, 0x00b0, 0x10, 14, 1), + PIN_FIELD_BASE(137, 137, 1, 0x00b0, 0x10, 13, 1), + PIN_FIELD_BASE(138, 138, 1, 0x00b0, 0x10, 16, 1), + PIN_FIELD_BASE(139, 139, 1, 0x00b0, 0x10, 15, 1), + PIN_FIELD_BASE(140, 140, 1, 0x00b0, 0x10, 18, 1), + PIN_FIELD_BASE(141, 141, 1, 0x00b0, 0x10, 17, 1), + PIN_FIELD_BASE(142, 142, 1, 0x00b0, 0x10, 20, 1), + PIN_FIELD_BASE(143, 143, 1, 0x00b0, 0x10, 19, 1), +}; + +static const struct mtk_pin_field_calc mt8195_pin_pd_range[] = { + PIN_FIELD_BASE(6, 6, 4, 0x0050, 0x10, 0, 1), + PIN_FIELD_BASE(7, 7, 4, 0x0050, 0x10, 1, 1), + PIN_FIELD_BASE(8, 8, 4, 0x0050, 0x10, 7, 1), + PIN_FIELD_BASE(9, 9, 4, 0x0050, 0x10, 2, 1), + PIN_FIELD_BASE(10, 10, 4, 0x0050, 0x10, 8, 1), + PIN_FIELD_BASE(11, 11, 4, 0x0050, 0x10, 3, 1), + PIN_FIELD_BASE(12, 12, 4, 0x0050, 0x10, 9, 1), + PIN_FIELD_BASE(13, 13, 4, 0x0050, 0x10, 4, 1), + PIN_FIELD_BASE(14, 14, 4, 0x0050, 0x10, 10, 1), + PIN_FIELD_BASE(15, 15, 4, 0x0050, 0x10, 5, 1), + PIN_FIELD_BASE(16, 16, 4, 0x0050, 0x10, 11, 1), + PIN_FIELD_BASE(17, 17, 4, 0x0050, 0x10, 6, 1), + PIN_FIELD_BASE(18, 18, 2, 0x0050, 0x10, 5, 1), + PIN_FIELD_BASE(19, 19, 2, 0x0050, 0x10, 12, 1), + PIN_FIELD_BASE(20, 20, 2, 0x0050, 0x10, 11, 1), + PIN_FIELD_BASE(21, 21, 2, 0x0050, 0x10, 10, 1), + PIN_FIELD_BASE(22, 22, 2, 0x0050, 0x10, 0, 1), + PIN_FIELD_BASE(23, 23, 2, 0x0050, 0x10, 1, 1), + PIN_FIELD_BASE(24, 24, 2, 0x0050, 0x10, 2, 1), + PIN_FIELD_BASE(25, 25, 2, 0x0050, 0x10, 4, 1), + PIN_FIELD_BASE(26, 26, 2, 0x0050, 0x10, 3, 1), + PIN_FIELD_BASE(27, 27, 2, 0x0050, 0x10, 6, 1), + PIN_FIELD_BASE(28, 28, 2, 0x0050, 0x10, 7, 1), + PIN_FIELD_BASE(29, 29, 2, 0x0050, 0x10, 8, 1), + PIN_FIELD_BASE(30, 30, 2, 0x0050, 0x10, 9, 1), + PIN_FIELD_BASE(31, 31, 1, 0x0080, 0x10, 13, 1), + PIN_FIELD_BASE(32, 32, 1, 0x0080, 0x10, 12, 1), + PIN_FIELD_BASE(33, 33, 1, 0x0080, 0x10, 11, 1), + PIN_FIELD_BASE(34, 34, 1, 0x0080, 0x10, 14, 1), + PIN_FIELD_BASE(35, 35, 1, 0x0080, 0x10, 15, 1), + PIN_FIELD_BASE(36, 36, 1, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(37, 37, 1, 0x0090, 0x10, 6, 1), + PIN_FIELD_BASE(38, 38, 1, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(39, 39, 1, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(40, 40, 1, 0x0090, 0x10, 8, 1), + PIN_FIELD_BASE(41, 41, 1, 0x0090, 0x10, 7, 1), + PIN_FIELD_BASE(42, 42, 1, 0x0090, 0x10, 10, 1), + PIN_FIELD_BASE(43, 43, 1, 0x0090, 0x10, 9, 1), + PIN_FIELD_BASE(44, 44, 1, 0x0090, 0x10, 21, 1), + PIN_FIELD_BASE(45, 45, 1, 0x0090, 0x10, 22, 1), + PIN_FIELD_BASE(46, 46, 1, 0x0080, 0x10, 18, 1), + PIN_FIELD_BASE(47, 47, 1, 0x0080, 0x10, 16, 1), + PIN_FIELD_BASE(48, 48, 1, 0x0080, 0x10, 19, 1), + PIN_FIELD_BASE(49, 49, 1, 0x0080, 0x10, 17, 1), + PIN_FIELD_BASE(50, 50, 1, 0x0080, 0x10, 25, 1), + PIN_FIELD_BASE(51, 51, 1, 0x0080, 0x10, 20, 1), + PIN_FIELD_BASE(52, 52, 1, 0x0080, 0x10, 26, 1), + PIN_FIELD_BASE(53, 53, 1, 0x0080, 0x10, 21, 1), + PIN_FIELD_BASE(54, 54, 1, 0x0080, 0x10, 22, 1), + PIN_FIELD_BASE(55, 55, 1, 0x0080, 0x10, 23, 1), + PIN_FIELD_BASE(56, 56, 1, 0x0080, 0x10, 24, 1), + PIN_FIELD_BASE(57, 57, 1, 0x0080, 0x10, 29, 1), + PIN_FIELD_BASE(58, 58, 1, 0x0080, 0x10, 27, 1), + PIN_FIELD_BASE(59, 59, 1, 0x0080, 0x10, 30, 1), + PIN_FIELD_BASE(60, 60, 1, 0x0080, 0x10, 28, 1), + PIN_FIELD_BASE(61, 61, 1, 0x0080, 0x10, 8, 1), + PIN_FIELD_BASE(62, 62, 1, 0x0080, 0x10, 7, 1), + PIN_FIELD_BASE(63, 63, 1, 0x0080, 0x10, 10, 1), + PIN_FIELD_BASE(64, 64, 1, 0x0080, 0x10, 9, 1), + PIN_FIELD_BASE(65, 65, 1, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(66, 66, 1, 0x0080, 0x10, 31, 1), + PIN_FIELD_BASE(67, 67, 1, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(68, 68, 1, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(69, 69, 1, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(70, 70, 1, 0x0080, 0x10, 6, 1), + PIN_FIELD_BASE(71, 71, 1, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(72, 72, 1, 0x0080, 0x10, 5, 1), + PIN_FIELD_BASE(73, 73, 1, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(74, 74, 1, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(75, 75, 1, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(76, 76, 1, 0x0090, 0x10, 11, 1), + PIN_FIELD_BASE(97, 97, 3, 0x0050, 0x10, 0, 1), + PIN_FIELD_BASE(98, 98, 3, 0x0050, 0x10, 4, 1), + PIN_FIELD_BASE(99, 99, 3, 0x0050, 0x10, 3, 1), + PIN_FIELD_BASE(100, 100, 3, 0x0050, 0x10, 6, 1), + PIN_FIELD_BASE(101, 101, 3, 0x0050, 0x10, 5, 1), + PIN_FIELD_BASE(102, 102, 3, 0x0050, 0x10, 8, 1), + PIN_FIELD_BASE(103, 103, 3, 0x0050, 0x10, 7, 1), + PIN_FIELD_BASE(108, 108, 3, 0x0050, 0x10, 2, 1), + PIN_FIELD_BASE(109, 109, 3, 0x0050, 0x10, 1, 1), + PIN_FIELD_BASE(128, 128, 3, 0x0050, 0x10, 11, 1), + PIN_FIELD_BASE(129, 129, 3, 0x0050, 0x10, 9, 1), + PIN_FIELD_BASE(130, 130, 3, 0x0050, 0x10, 12, 1), + PIN_FIELD_BASE(131, 131, 3, 0x0050, 0x10, 10, 1), + PIN_FIELD_BASE(132, 132, 6, 0x0040, 0x10, 1, 1), + PIN_FIELD_BASE(133, 133, 6, 0x0040, 0x10, 0, 1), + PIN_FIELD_BASE(134, 134, 6, 0x0040, 0x10, 3, 1), + PIN_FIELD_BASE(135, 135, 6, 0x0040, 0x10, 2, 1), + PIN_FIELD_BASE(136, 136, 1, 0x0090, 0x10, 14, 1), + PIN_FIELD_BASE(137, 137, 1, 0x0090, 0x10, 13, 1), + PIN_FIELD_BASE(138, 138, 1, 0x0090, 0x10, 16, 1), + PIN_FIELD_BASE(139, 139, 1, 0x0090, 0x10, 15, 1), + PIN_FIELD_BASE(140, 140, 1, 0x0090, 0x10, 18, 1), + PIN_FIELD_BASE(141, 141, 1, 0x0090, 0x10, 17, 1), + PIN_FIELD_BASE(142, 142, 1, 0x0090, 0x10, 20, 1), + PIN_FIELD_BASE(143, 143, 1, 0x0090, 0x10, 19, 1), +}; + +static const struct mtk_pin_field_calc mt8195_pin_pupd_range[] = { + PIN_FIELD_BASE(0, 0, 4, 0x0060, 0x10, 0, 1), + PIN_FIELD_BASE(1, 1, 4, 0x0060, 0x10, 1, 1), + PIN_FIELD_BASE(2, 2, 4, 0x0060, 0x10, 2, 1), + PIN_FIELD_BASE(3, 3, 4, 0x0060, 0x10, 3, 1), + PIN_FIELD_BASE(4, 4, 4, 0x0060, 0x10, 4, 1), + PIN_FIELD_BASE(5, 5, 4, 0x0060, 0x10, 5, 1), + PIN_FIELD_BASE(77, 77, 3, 0x0060, 0x10, 1, 1), + PIN_FIELD_BASE(78, 78, 3, 0x0060, 0x10, 2, 1), + PIN_FIELD_BASE(79, 79, 3, 0x0060, 0x10, 9, 1), + PIN_FIELD_BASE(80, 80, 3, 0x0060, 0x10, 10, 1), + PIN_FIELD_BASE(81, 81, 3, 0x0060, 0x10, 11, 1), + PIN_FIELD_BASE(82, 82, 3, 0x0060, 0x10, 12, 1), + PIN_FIELD_BASE(83, 83, 3, 0x0060, 0x10, 13, 1), + PIN_FIELD_BASE(84, 84, 3, 0x0060, 0x10, 14, 1), + PIN_FIELD_BASE(85, 85, 3, 0x0060, 0x10, 15, 1), + PIN_FIELD_BASE(86, 86, 3, 0x0060, 0x10, 16, 1), + PIN_FIELD_BASE(87, 87, 3, 0x0060, 0x10, 3, 1), + PIN_FIELD_BASE(88, 88, 3, 0x0060, 0x10, 4, 1), + PIN_FIELD_BASE(89, 89, 3, 0x0060, 0x10, 5, 1), + PIN_FIELD_BASE(90, 90, 3, 0x0060, 0x10, 6, 1), + PIN_FIELD_BASE(91, 91, 3, 0x0060, 0x10, 7, 1), + PIN_FIELD_BASE(92, 92, 3, 0x0060, 0x10, 8, 1), + PIN_FIELD_BASE(93, 93, 3, 0x0060, 0x10, 18, 1), + PIN_FIELD_BASE(94, 94, 3, 0x0060, 0x10, 19, 1), + PIN_FIELD_BASE(95, 95, 3, 0x0060, 0x10, 17, 1), + PIN_FIELD_BASE(96, 96, 3, 0x0060, 0x10, 0, 1), + PIN_FIELD_BASE(104, 104, 3, 0x0060, 0x10, 22, 1), + PIN_FIELD_BASE(105, 105, 3, 0x0060, 0x10, 23, 1), + PIN_FIELD_BASE(106, 106, 3, 0x0060, 0x10, 20, 1), + PIN_FIELD_BASE(107, 107, 3, 0x0060, 0x10, 21, 1), + PIN_FIELD_BASE(110, 110, 5, 0x0020, 0x10, 1, 1), + PIN_FIELD_BASE(111, 111, 5, 0x0020, 0x10, 0, 1), + PIN_FIELD_BASE(112, 112, 5, 0x0020, 0x10, 2, 1), + PIN_FIELD_BASE(113, 113, 5, 0x0020, 0x10, 3, 1), + PIN_FIELD_BASE(114, 114, 5, 0x0020, 0x10, 4, 1), + PIN_FIELD_BASE(115, 115, 5, 0x0020, 0x10, 5, 1), + PIN_FIELD_BASE(116, 116, 6, 0x0050, 0x10, 9, 1), + PIN_FIELD_BASE(117, 117, 6, 0x0050, 0x10, 8, 1), + PIN_FIELD_BASE(118, 118, 6, 0x0050, 0x10, 7, 1), + PIN_FIELD_BASE(119, 119, 6, 0x0050, 0x10, 6, 1), + PIN_FIELD_BASE(120, 120, 6, 0x0050, 0x10, 11, 1), + PIN_FIELD_BASE(121, 121, 6, 0x0050, 0x10, 1, 1), + PIN_FIELD_BASE(122, 122, 6, 0x0050, 0x10, 0, 1), + PIN_FIELD_BASE(123, 123, 6, 0x0050, 0x10, 5, 1), + PIN_FIELD_BASE(124, 124, 6, 0x0050, 0x10, 4, 1), + PIN_FIELD_BASE(125, 125, 6, 0x0050, 0x10, 3, 1), + PIN_FIELD_BASE(126, 126, 6, 0x0050, 0x10, 2, 1), + PIN_FIELD_BASE(127, 127, 6, 0x0050, 0x10, 10, 1), +}; + +static const struct mtk_pin_field_calc mt8195_pin_r0_range[] = { + PIN_FIELD_BASE(0, 0, 4, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(1, 1, 4, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(2, 2, 4, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(3, 3, 4, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(4, 4, 4, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(5, 5, 4, 0x0080, 0x10, 5, 1), + PIN_FIELD_BASE(77, 77, 3, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(78, 78, 3, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(79, 79, 3, 0x0080, 0x10, 9, 1), + PIN_FIELD_BASE(80, 80, 3, 0x0080, 0x10, 10, 1), + PIN_FIELD_BASE(81, 81, 3, 0x0080, 0x10, 11, 1), + PIN_FIELD_BASE(82, 82, 3, 0x0080, 0x10, 12, 1), + PIN_FIELD_BASE(83, 83, 3, 0x0080, 0x10, 13, 1), + PIN_FIELD_BASE(84, 84, 3, 0x0080, 0x10, 14, 1), + PIN_FIELD_BASE(85, 85, 3, 0x0080, 0x10, 15, 1), + PIN_FIELD_BASE(86, 86, 3, 0x0080, 0x10, 16, 1), + PIN_FIELD_BASE(87, 87, 3, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(88, 88, 3, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(89, 89, 3, 0x0080, 0x10, 5, 1), + PIN_FIELD_BASE(90, 90, 3, 0x0080, 0x10, 6, 1), + PIN_FIELD_BASE(91, 91, 3, 0x0080, 0x10, 7, 1), + PIN_FIELD_BASE(92, 92, 3, 0x0080, 0x10, 8, 1), + PIN_FIELD_BASE(93, 93, 3, 0x0080, 0x10, 18, 1), + PIN_FIELD_BASE(94, 94, 3, 0x0080, 0x10, 19, 1), + PIN_FIELD_BASE(95, 95, 3, 0x0080, 0x10, 17, 1), + PIN_FIELD_BASE(96, 96, 3, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(104, 104, 3, 0x0080, 0x10, 22, 1), + PIN_FIELD_BASE(105, 105, 3, 0x0080, 0x10, 23, 1), + PIN_FIELD_BASE(106, 106, 3, 0x0080, 0x10, 20, 1), + PIN_FIELD_BASE(107, 107, 3, 0x0080, 0x10, 21, 1), + PIN_FIELD_BASE(110, 110, 5, 0x0030, 0x10, 1, 1), + PIN_FIELD_BASE(111, 111, 5, 0x0030, 0x10, 0, 1), + PIN_FIELD_BASE(112, 112, 5, 0x0030, 0x10, 2, 1), + PIN_FIELD_BASE(113, 113, 5, 0x0030, 0x10, 3, 1), + PIN_FIELD_BASE(114, 114, 5, 0x0030, 0x10, 4, 1), + PIN_FIELD_BASE(115, 115, 5, 0x0030, 0x10, 5, 1), + PIN_FIELD_BASE(116, 116, 6, 0x0070, 0x10, 9, 1), + PIN_FIELD_BASE(117, 117, 6, 0x0070, 0x10, 8, 1), + PIN_FIELD_BASE(118, 118, 6, 0x0070, 0x10, 7, 1), + PIN_FIELD_BASE(119, 119, 6, 0x0070, 0x10, 6, 1), + PIN_FIELD_BASE(120, 120, 6, 0x0070, 0x10, 11, 1), + PIN_FIELD_BASE(121, 121, 6, 0x0070, 0x10, 1, 1), + PIN_FIELD_BASE(122, 122, 6, 0x0070, 0x10, 0, 1), + PIN_FIELD_BASE(123, 123, 6, 0x0070, 0x10, 5, 1), + PIN_FIELD_BASE(124, 124, 6, 0x0070, 0x10, 4, 1), + PIN_FIELD_BASE(125, 125, 6, 0x0070, 0x10, 3, 1), + PIN_FIELD_BASE(126, 126, 6, 0x0070, 0x10, 2, 1), + PIN_FIELD_BASE(127, 127, 6, 0x0070, 0x10, 10, 1), +}; + +static const struct mtk_pin_field_calc mt8195_pin_r1_range[] = { + PIN_FIELD_BASE(0, 0, 4, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(1, 1, 4, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(2, 2, 4, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(3, 3, 4, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(4, 4, 4, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(5, 5, 4, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(77, 77, 3, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(78, 78, 3, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(79, 79, 3, 0x0090, 0x10, 9, 1), + PIN_FIELD_BASE(80, 80, 3, 0x0090, 0x10, 10, 1), + PIN_FIELD_BASE(81, 81, 3, 0x0090, 0x10, 11, 1), + PIN_FIELD_BASE(82, 82, 3, 0x0090, 0x10, 12, 1), + PIN_FIELD_BASE(83, 83, 3, 0x0090, 0x10, 13, 1), + PIN_FIELD_BASE(84, 84, 3, 0x0090, 0x10, 14, 1), + PIN_FIELD_BASE(85, 85, 3, 0x0090, 0x10, 15, 1), + PIN_FIELD_BASE(86, 86, 3, 0x0090, 0x10, 16, 1), + PIN_FIELD_BASE(87, 87, 3, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(88, 88, 3, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(89, 89, 3, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(90, 90, 3, 0x0090, 0x10, 6, 1), + PIN_FIELD_BASE(91, 91, 3, 0x0090, 0x10, 7, 1), + PIN_FIELD_BASE(92, 92, 3, 0x0090, 0x10, 8, 1), + PIN_FIELD_BASE(93, 93, 3, 0x0090, 0x10, 18, 1), + PIN_FIELD_BASE(94, 94, 3, 0x0090, 0x10, 19, 1), + PIN_FIELD_BASE(95, 95, 3, 0x0090, 0x10, 17, 1), + PIN_FIELD_BASE(96, 96, 3, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(104, 104, 3, 0x0090, 0x10, 22, 1), + PIN_FIELD_BASE(105, 105, 3, 0x0090, 0x10, 23, 1), + PIN_FIELD_BASE(106, 106, 3, 0x0090, 0x10, 20, 1), + PIN_FIELD_BASE(107, 107, 3, 0x0090, 0x10, 21, 1), + PIN_FIELD_BASE(110, 110, 5, 0x0040, 0x10, 1, 1), + PIN_FIELD_BASE(111, 111, 5, 0x0040, 0x10, 0, 1), + PIN_FIELD_BASE(112, 112, 5, 0x0040, 0x10, 2, 1), + PIN_FIELD_BASE(113, 113, 5, 0x0040, 0x10, 3, 1), + PIN_FIELD_BASE(114, 114, 5, 0x0040, 0x10, 4, 1), + PIN_FIELD_BASE(115, 115, 5, 0x0040, 0x10, 5, 1), + PIN_FIELD_BASE(116, 116, 6, 0x0080, 0x10, 9, 1), + PIN_FIELD_BASE(117, 117, 6, 0x0080, 0x10, 8, 1), + PIN_FIELD_BASE(118, 118, 6, 0x0080, 0x10, 7, 1), + PIN_FIELD_BASE(119, 119, 6, 0x0080, 0x10, 6, 1), + PIN_FIELD_BASE(120, 120, 6, 0x0080, 0x10, 11, 1), + PIN_FIELD_BASE(121, 121, 6, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(122, 122, 6, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(123, 123, 6, 0x0080, 0x10, 5, 1), + PIN_FIELD_BASE(124, 124, 6, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(125, 125, 6, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(126, 126, 6, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(127, 127, 6, 0x0080, 0x10, 10, 1), +}; + +static const struct mtk_pin_field_calc mt8195_pin_drv_range[] = { + PIN_FIELD_BASE(0, 0, 4, 0x000, 0x10, 0, 3), + PIN_FIELD_BASE(1, 1, 4, 0x000, 0x10, 3, 3), + PIN_FIELD_BASE(2, 2, 4, 0x000, 0x10, 6, 3), + PIN_FIELD_BASE(3, 3, 4, 0x000, 0x10, 9, 3), + PIN_FIELD_BASE(4, 4, 4, 0x000, 0x10, 12, 3), + PIN_FIELD_BASE(5, 5, 4, 0x000, 0x10, 15, 3), + PINS_FIELD_BASE(6, 7, 4, 0x000, 0x10, 18, 3), + PIN_FIELD_BASE(8, 8, 4, 0x010, 0x10, 6, 3), + PIN_FIELD_BASE(9, 9, 4, 0x000, 0x10, 21, 3), + PIN_FIELD_BASE(10, 10, 4, 0x010, 0x10, 9, 3), + PIN_FIELD_BASE(11, 11, 4, 0x000, 0x10, 24, 3), + PIN_FIELD_BASE(12, 12, 4, 0x010, 0x10, 12, 3), + PIN_FIELD_BASE(13, 13, 4, 0x010, 0x10, 27, 3), + PIN_FIELD_BASE(14, 14, 4, 0x010, 0x10, 15, 3), + PIN_FIELD_BASE(15, 15, 4, 0x010, 0x10, 0, 3), + PIN_FIELD_BASE(16, 16, 4, 0x010, 0x10, 18, 3), + PIN_FIELD_BASE(17, 17, 4, 0x010, 0x10, 3, 3), + PIN_FIELD_BASE(18, 18, 2, 0x010, 0x10, 6, 3), + PIN_FIELD_BASE(19, 19, 2, 0x010, 0x10, 3, 3), + PIN_FIELD_BASE(20, 20, 2, 0x010, 0x10, 0, 3), + PIN_FIELD_BASE(21, 21, 2, 0x000, 0x10, 27, 3), + PIN_FIELD_BASE(22, 22, 2, 0x000, 0x10, 0, 3), + PIN_FIELD_BASE(23, 23, 2, 0x000, 0x10, 3, 3), + PIN_FIELD_BASE(24, 24, 2, 0x000, 0x10, 6, 3), + PIN_FIELD_BASE(25, 25, 2, 0x000, 0x10, 12, 3), + PIN_FIELD_BASE(26, 26, 2, 0x000, 0x10, 9, 3), + PIN_FIELD_BASE(27, 27, 2, 0x000, 0x10, 15, 3), + PIN_FIELD_BASE(28, 28, 2, 0x000, 0x10, 18, 3), + PIN_FIELD_BASE(29, 29, 2, 0x000, 0x10, 21, 3), + PIN_FIELD_BASE(30, 30, 2, 0x000, 0x10, 24, 3), + PINS_FIELD_BASE(31, 33, 1, 0x010, 0x10, 0, 3), + PIN_FIELD_BASE(34, 34, 1, 0x000, 0x10, 21, 3), + PIN_FIELD_BASE(35, 35, 1, 0x000, 0x10, 24, 3), + PIN_FIELD_BASE(36, 36, 1, 0x010, 0x10, 0, 3), + PIN_FIELD_BASE(37, 37, 1, 0x010, 0x10, 21, 3), + PINS_FIELD_BASE(38, 39, 1, 0x010, 0x10, 3, 3), + PIN_FIELD_BASE(40, 40, 1, 0x010, 0x10, 27, 3), + PIN_FIELD_BASE(41, 41, 1, 0x010, 0x10, 24, 3), + PIN_FIELD_BASE(42, 42, 1, 0x020, 0x10, 3, 3), + PIN_FIELD_BASE(43, 43, 1, 0x020, 0x10, 0, 3), + PIN_FIELD_BASE(44, 44, 1, 0x030, 0x10, 0, 3), + PIN_FIELD_BASE(45, 45, 1, 0x030, 0x10, 3, 3), + PINS_FIELD_BASE(46, 47, 1, 0x010, 0x10, 3, 3), + PINS_FIELD_BASE(48, 51, 1, 0x010, 0x10, 6, 3), + PINS_FIELD_BASE(52, 55, 1, 0x010, 0x10, 9, 3), + PINS_FIELD_BASE(56, 59, 1, 0x010, 0x10, 12, 3), + PINS_FIELD_BASE(60, 63, 1, 0x010, 0x10, 15, 3), + PIN_FIELD_BASE(64, 64, 1, 0x010, 0x10, 18, 3), + PINS_FIELD_BASE(65, 68, 1, 0x000, 0x10, 27, 3), + PIN_FIELD_BASE(69, 69, 1, 0x000, 0x10, 0, 3), + PIN_FIELD_BASE(70, 70, 1, 0x000, 0x10, 18, 3), + PIN_FIELD_BASE(71, 71, 1, 0x000, 0x10, 12, 3), + PIN_FIELD_BASE(72, 72, 1, 0x000, 0x10, 15, 3), + PIN_FIELD_BASE(73, 73, 1, 0x000, 0x10, 3, 3), + PIN_FIELD_BASE(74, 74, 1, 0x000, 0x10, 6, 3), + PIN_FIELD_BASE(75, 75, 1, 0x000, 0x10, 9, 3), + PIN_FIELD_BASE(76, 76, 1, 0x010, 0x10, 18, 3), + PIN_FIELD_BASE(77, 77, 3, 0x000, 0x10, 0, 3), + PIN_FIELD_BASE(78, 78, 3, 0x000, 0x10, 15, 3), + PIN_FIELD_BASE(79, 79, 3, 0x000, 0x10, 18, 3), + PIN_FIELD_BASE(80, 80, 3, 0x000, 0x10, 21, 3), + PIN_FIELD_BASE(81, 81, 3, 0x000, 0x10, 28, 3), + PIN_FIELD_BASE(82, 82, 3, 0x000, 0x10, 27, 3), + PIN_FIELD_BASE(83, 83, 3, 0x010, 0x10, 0, 3), + PIN_FIELD_BASE(84, 84, 3, 0x010, 0x10, 3, 3), + PINS_FIELD_BASE(85, 88, 3, 0x010, 0x10, 15, 3), + PIN_FIELD_BASE(89, 89, 3, 0x000, 0x10, 3, 3), + PIN_FIELD_BASE(90, 90, 3, 0x000, 0x10, 6, 3), + PIN_FIELD_BASE(91, 91, 3, 0x000, 0x10, 9, 3), + PIN_FIELD_BASE(92, 92, 3, 0x000, 0x10, 12, 3), + PIN_FIELD_BASE(93, 93, 3, 0x010, 0x10, 6, 3), + PIN_FIELD_BASE(94, 94, 3, 0x010, 0x10, 9, 3), + PINS_FIELD_BASE(95, 98, 3, 0x010, 0x10, 18, 3), + PINS_FIELD_BASE(99, 102, 3, 0x010, 0x10, 21, 3), + PINS_FIELD_BASE(103, 104, 3, 0x010, 0x10, 24, 3), + PIN_FIELD_BASE(105, 105, 3, 0x010, 0x10, 27, 3), + PINS_FIELD_BASE(106, 107, 3, 0x010, 0x10, 24, 3), + PINS_FIELD_BASE(108, 109, 3, 0x010, 0x10, 27, 3), + PIN_FIELD_BASE(110, 110, 5, 0x000, 0x10, 3, 3), + PIN_FIELD_BASE(111, 111, 5, 0x000, 0x10, 0, 3), + PIN_FIELD_BASE(112, 112, 5, 0x000, 0x10, 6, 3), + PIN_FIELD_BASE(113, 113, 5, 0x000, 0x10, 9, 3), + PIN_FIELD_BASE(114, 114, 5, 0x000, 0x10, 12, 3), + PIN_FIELD_BASE(115, 115, 5, 0x000, 0x10, 15, 3), + PIN_FIELD_BASE(116, 116, 6, 0x000, 0x10, 27, 3), + PIN_FIELD_BASE(117, 117, 6, 0x000, 0x10, 24, 3), + PIN_FIELD_BASE(118, 118, 6, 0x000, 0x10, 21, 3), + PIN_FIELD_BASE(119, 119, 6, 0x000, 0x10, 18, 3), + PIN_FIELD_BASE(120, 120, 6, 0x010, 0x10, 3, 3), + PIN_FIELD_BASE(121, 121, 6, 0x000, 0x10, 3, 3), + PIN_FIELD_BASE(122, 122, 6, 0x000, 0x10, 0, 3), + PIN_FIELD_BASE(123, 123, 6, 0x000, 0x10, 15, 3), + PIN_FIELD_BASE(124, 124, 6, 0x000, 0x10, 12, 3), + PIN_FIELD_BASE(125, 125, 6, 0x000, 0x10, 9, 3), + PIN_FIELD_BASE(126, 126, 6, 0x000, 0x10, 6, 3), + PIN_FIELD_BASE(127, 127, 6, 0x010, 0x10, 0, 3), + PIN_FIELD_BASE(128, 128, 3, 0x010, 0x10, 27, 3), + PINS_FIELD_BASE(129, 130, 3, 0x020, 0x10, 0, 3), + PINS_FIELD_BASE(131, 131, 3, 0x010, 0x10, 12, 3), + PIN_FIELD_BASE(132, 132, 6, 0x010, 0x10, 9, 3), + PIN_FIELD_BASE(133, 133, 6, 0x010, 0x10, 6, 3), + PIN_FIELD_BASE(134, 134, 6, 0x010, 0x10, 15, 3), + PIN_FIELD_BASE(135, 135, 6, 0x010, 0x10, 12, 3), + PIN_FIELD_BASE(136, 136, 1, 0x020, 0x10, 9, 3), + PIN_FIELD_BASE(137, 137, 1, 0x020, 0x10, 6, 3), + PIN_FIELD_BASE(138, 138, 1, 0x020, 0x10, 15, 3), + PIN_FIELD_BASE(139, 139, 1, 0x020, 0x10, 12, 3), + PIN_FIELD_BASE(140, 140, 1, 0x020, 0x10, 21, 3), + PIN_FIELD_BASE(141, 141, 1, 0x020, 0x10, 18, 3), + PIN_FIELD_BASE(142, 142, 1, 0x020, 0x10, 27, 3), + PIN_FIELD_BASE(143, 143, 1, 0x020, 0x10, 24, 3), +}; + +static const struct mtk_pin_reg_calc mt8195_reg_cals[PINCTRL_PIN_REG_MAX] = { + [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt8195_pin_mode_range), + [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt8195_pin_dir_range), + [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt8195_pin_di_range), + [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt8195_pin_do_range), + [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt8195_pin_smt_range), + [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt8195_pin_ies_range), + [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt8195_pin_pu_range), + [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt8195_pin_pd_range), + [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt8195_pin_drv_range), + [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt8195_pin_pupd_range), + [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt8195_pin_r0_range), + [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt8195_pin_r1_range), +}; + +static const char * const mt8195_pinctrl_register_base_names[] = { + "iocfg0", "iocfg_bm", "iocfg_bl", "iocfg_br", "iocfg_lm", + "iocfg_rb", "iocfg_tl", +}; + +static const struct mtk_eint_hw mt8195_eint_hw = { + .port_mask = 0xf, + .ports = 7, + .ap_num = 225, + .db_cnt = 32, +}; + +static const struct mtk_pin_soc mt8195_data = { + .reg_cal = mt8195_reg_cals, + .pins = mtk_pins_mt8195, + .npins = ARRAY_SIZE(mtk_pins_mt8195), + .ngrps = ARRAY_SIZE(mtk_pins_mt8195), + .eint_hw = &mt8195_eint_hw, + .nfuncs = 8, + .gpio_m = 0, + .base_names = mt8195_pinctrl_register_base_names, + .nbase_names = ARRAY_SIZE(mt8195_pinctrl_register_base_names), + .bias_set_combo = mtk_pinconf_bias_set_combo, + .bias_get_combo = mtk_pinconf_bias_get_combo, + .drive_set = mtk_pinconf_drive_set_rev1, + .drive_get = mtk_pinconf_drive_get_rev1, +}; + +static const struct of_device_id mt8195_pinctrl_of_match[] = { + { .compatible = "mediatek,mt8195-pinctrl", }, + { } +}; + +static int mt8195_pinctrl_probe(struct platform_device *pdev) +{ + return mtk_paris_pinctrl_probe(pdev, &mt8195_data); +} + +static struct platform_driver mt8195_pinctrl_driver = { + .driver = { + .name = "mt8195-pinctrl", + .of_match_table = mt8195_pinctrl_of_match, + }, + .probe = mt8195_pinctrl_probe, +}; + +static int __init mt8195_pinctrl_init(void) +{ + return platform_driver_register(&mt8195_pinctrl_driver); +} +arch_initcall(mt8195_pinctrl_init); diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-mt8195.h b/drivers/pinctrl/mediatek/pinctrl-mtk-mt8195.h new file mode 100644 index 000000000000..de4a8a80bf1d --- /dev/null +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-mt8195.h @@ -0,0 +1,1669 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 MediaTek Inc. + * + * Author: Zhiyong Tao + * + */ + +#ifndef __PINCTRL_MTK_MT8195_H +#define __PINCTRL_MTK_MT8195_H + +#include "pinctrl-paris.h" + +static const struct mtk_pin_desc mtk_pins_mt8195[] = { + MTK_PIN( + 0, "GPIO0", + MTK_EINT_FUNCTION(0, 0), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO0"), + MTK_FUNCTION(1, "TP_GPIO0_AO"), + MTK_FUNCTION(2, "MSDC2_CMD"), + MTK_FUNCTION(3, "TDMIN_MCK"), + MTK_FUNCTION(4, "CLKM0"), + MTK_FUNCTION(5, "PERSTN_1"), + MTK_FUNCTION(6, "IDDIG_1P"), + MTK_FUNCTION(7, "DMIC4_CLK") + ), + MTK_PIN( + 1, "GPIO1", + MTK_EINT_FUNCTION(0, 1), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO1"), + MTK_FUNCTION(1, "TP_GPIO1_AO"), + MTK_FUNCTION(2, "MSDC2_CLK"), + MTK_FUNCTION(3, "TDMIN_DI"), + MTK_FUNCTION(4, "CLKM1"), + MTK_FUNCTION(5, "CLKREQN_1"), + MTK_FUNCTION(6, "USB_DRVVBUS_1P"), + MTK_FUNCTION(7, "DMIC4_DAT") + ), + MTK_PIN( + 2, "GPIO2", + MTK_EINT_FUNCTION(0, 2), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO2"), + MTK_FUNCTION(1, "TP_GPIO2_AO"), + MTK_FUNCTION(2, "MSDC2_DAT3"), + MTK_FUNCTION(3, "TDMIN_LRCK"), + MTK_FUNCTION(4, "CLKM2"), + MTK_FUNCTION(5, "WAKEN_1"), + MTK_FUNCTION(7, "DMIC2_CLK") + ), + MTK_PIN( + 3, "GPIO3", + MTK_EINT_FUNCTION(0, 3), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO3"), + MTK_FUNCTION(1, "TP_GPIO3_AO"), + MTK_FUNCTION(2, "MSDC2_DAT0"), + MTK_FUNCTION(3, "TDMIN_BCK"), + MTK_FUNCTION(4, "CLKM3"), + MTK_FUNCTION(7, "DMIC2_DAT") + ), + MTK_PIN( + 4, "GPIO4", + MTK_EINT_FUNCTION(0, 4), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO4"), + MTK_FUNCTION(1, "TP_GPIO4_AO"), + MTK_FUNCTION(2, "MSDC2_DAT2"), + MTK_FUNCTION(3, "SPDIF_IN1"), + MTK_FUNCTION(4, "UTXD3"), + MTK_FUNCTION(5, "SDA2"), + MTK_FUNCTION(7, "IDDIG_2P") + ), + MTK_PIN( + 5, "GPIO5", + MTK_EINT_FUNCTION(0, 5), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO5"), + MTK_FUNCTION(1, "TP_GPIO5_AO"), + MTK_FUNCTION(2, "MSDC2_DAT1"), + MTK_FUNCTION(3, "SPDIF_IN0"), + MTK_FUNCTION(4, "URXD3"), + MTK_FUNCTION(5, "SCL2"), + MTK_FUNCTION(7, "USB_DRVVBUS_2P") + ), + MTK_PIN( + 6, "GPIO6", + MTK_EINT_FUNCTION(0, 6), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO6"), + MTK_FUNCTION(1, "TP_GPIO6_AO"), + MTK_FUNCTION(2, "DP_TX_HPD"), + MTK_FUNCTION(3, "I2SO1_D4"), + MTK_FUNCTION(4, "UTXD4"), + MTK_FUNCTION(5, "CMVREF3"), + MTK_FUNCTION(7, "DMIC3_CLK") + ), + MTK_PIN( + 7, "GPIO7", + MTK_EINT_FUNCTION(0, 7), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO7"), + MTK_FUNCTION(1, "TP_GPIO7_AO"), + MTK_FUNCTION(2, "EDP_TX_HPD"), + MTK_FUNCTION(3, "I2SO1_D5"), + MTK_FUNCTION(4, "URXD4"), + MTK_FUNCTION(5, "CMVREF4"), + MTK_FUNCTION(7, "DMIC3_DAT") + ), + MTK_PIN( + 8, "GPIO8", + MTK_EINT_FUNCTION(0, 8), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO8"), + MTK_FUNCTION(1, "SDA0"), + MTK_FUNCTION(2, "PWM_0"), + MTK_FUNCTION(4, "SPDIF_OUT"), + MTK_FUNCTION(6, "LVTS_FOUT"), + MTK_FUNCTION(7, "DBG_MON_A0") + ), + MTK_PIN( + 9, "GPIO9", + MTK_EINT_FUNCTION(0, 9), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO9"), + MTK_FUNCTION(1, "SCL0"), + MTK_FUNCTION(2, "PWM_1"), + MTK_FUNCTION(4, "IR_IN"), + MTK_FUNCTION(6, "LVTS_SDO"), + MTK_FUNCTION(7, "DBG_MON_A1") + ), + MTK_PIN( + 10, "GPIO10", + MTK_EINT_FUNCTION(0, 10), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO10"), + MTK_FUNCTION(1, "SDA1"), + MTK_FUNCTION(2, "PWM_2"), + MTK_FUNCTION(3, "ADSP_URXD0"), + MTK_FUNCTION(4, "SPDIF_IN1"), + MTK_FUNCTION(6, "LVTS_SCF"), + MTK_FUNCTION(7, "DBG_MON_A2") + ), + MTK_PIN( + 11, "GPIO11", + MTK_EINT_FUNCTION(0, 11), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO11"), + MTK_FUNCTION(1, "SCL1"), + MTK_FUNCTION(2, "PWM_3"), + MTK_FUNCTION(3, "ADSP_UTXD0"), + MTK_FUNCTION(4, "SPDIF_IN0"), + MTK_FUNCTION(6, "LVTS_SCK"), + MTK_FUNCTION(7, "DBG_MON_A3") + ), + MTK_PIN( + 12, "GPIO12", + MTK_EINT_FUNCTION(0, 12), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO12"), + MTK_FUNCTION(1, "SDA2"), + MTK_FUNCTION(2, "DMIC3_DAT_R"), + MTK_FUNCTION(3, "I2SO1_D6"), + MTK_FUNCTION(6, "LVTS_SDI"), + MTK_FUNCTION(7, "DBG_MON_A4") + ), + MTK_PIN( + 13, "GPIO13", + MTK_EINT_FUNCTION(0, 13), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO13"), + MTK_FUNCTION(1, "SCL2"), + MTK_FUNCTION(2, "DMIC4_DAT_R"), + MTK_FUNCTION(3, "I2SO1_D7"), + MTK_FUNCTION(7, "DBG_MON_A5") + ), + MTK_PIN( + 14, "GPIO14", + MTK_EINT_FUNCTION(0, 14), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO14"), + MTK_FUNCTION(1, "SDA3"), + MTK_FUNCTION(2, "DMIC3_DAT"), + MTK_FUNCTION(3, "TDMIN_MCK"), + MTK_FUNCTION(7, "DBG_MON_A6") + ), + MTK_PIN( + 15, "GPIO15", + MTK_EINT_FUNCTION(0, 15), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO15"), + MTK_FUNCTION(1, "SCL3"), + MTK_FUNCTION(2, "DMIC3_CLK"), + MTK_FUNCTION(3, "TDMIN_DI"), + MTK_FUNCTION(7, "DBG_MON_A7") + ), + MTK_PIN( + 16, "GPIO16", + MTK_EINT_FUNCTION(0, 16), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO16"), + MTK_FUNCTION(1, "SDA4"), + MTK_FUNCTION(2, "DMIC4_DAT"), + MTK_FUNCTION(3, "TDMIN_LRCK"), + MTK_FUNCTION(7, "DBG_MON_A8") + ), + MTK_PIN( + 17, "GPIO17", + MTK_EINT_FUNCTION(0, 17), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO17"), + MTK_FUNCTION(1, "SCL4"), + MTK_FUNCTION(2, "DMIC4_CLK"), + MTK_FUNCTION(3, "TDMIN_BCK"), + MTK_FUNCTION(7, "DBG_MON_A9") + ), + MTK_PIN( + 18, "GPIO18", + MTK_EINT_FUNCTION(0, 18), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO18"), + MTK_FUNCTION(1, "DP_TX_HPD") + ), + MTK_PIN( + 19, "GPIO19", + MTK_EINT_FUNCTION(0, 19), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO19"), + MTK_FUNCTION(1, "WAKEN"), + MTK_FUNCTION(2, "SCP_SDA1"), + MTK_FUNCTION(3, "MD32_0_JTAG_TCK"), + MTK_FUNCTION(4, "ADSP_JTAG0_TCK"), + MTK_FUNCTION(5, "SDA6") + ), + MTK_PIN( + 20, "GPIO20", + MTK_EINT_FUNCTION(0, 20), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO20"), + MTK_FUNCTION(1, "PERSTN"), + MTK_FUNCTION(2, "SCP_SCL1"), + MTK_FUNCTION(3, "MD32_0_JTAG_TMS"), + MTK_FUNCTION(4, "ADSP_JTAG0_TMS"), + MTK_FUNCTION(5, "SCL6") + ), + MTK_PIN( + 21, "GPIO21", + MTK_EINT_FUNCTION(0, 21), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO21"), + MTK_FUNCTION(1, "CLKREQN"), + MTK_FUNCTION(3, "MD32_0_JTAG_TDI"), + MTK_FUNCTION(4, "ADSP_JTAG0_TDI"), + MTK_FUNCTION(5, "SCP_SDA1") + ), + MTK_PIN( + 22, "GPIO22", + MTK_EINT_FUNCTION(0, 22), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO22"), + MTK_FUNCTION(1, "CMMCLK0"), + MTK_FUNCTION(2, "PERSTN_1"), + MTK_FUNCTION(5, "SCP_SCL1"), + MTK_FUNCTION(7, "MD32_0_GPIO0") + ), + MTK_PIN( + 23, "GPIO23", + MTK_EINT_FUNCTION(0, 23), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO23"), + MTK_FUNCTION(1, "CMMCLK1"), + MTK_FUNCTION(2, "CLKREQN_1"), + MTK_FUNCTION(3, "SDA4"), + MTK_FUNCTION(4, "DMIC1_CLK"), + MTK_FUNCTION(5, "SCP_SDA0"), + MTK_FUNCTION(7, "MD32_0_GPIO1") + ), + MTK_PIN( + 24, "GPIO24", + MTK_EINT_FUNCTION(0, 24), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO24"), + MTK_FUNCTION(1, "CMMCLK2"), + MTK_FUNCTION(2, "WAKEN_1"), + MTK_FUNCTION(3, "SCL4"), + MTK_FUNCTION(4, "DMIC1_DAT"), + MTK_FUNCTION(5, "SCP_SCL0"), + MTK_FUNCTION(6, "LVTS_26M"), + MTK_FUNCTION(7, "MD32_0_GPIO2") + ), + MTK_PIN( + 25, "GPIO25", + MTK_EINT_FUNCTION(0, 25), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO25"), + MTK_FUNCTION(1, "CMMRST"), + MTK_FUNCTION(2, "CMMCLK3"), + MTK_FUNCTION(3, "SPDIF_OUT"), + MTK_FUNCTION(4, "SDA6"), + MTK_FUNCTION(5, "ADSP_JTAG0_TRSTN"), + MTK_FUNCTION(6, "MD32_0_JTAG_TRST") + ), + MTK_PIN( + 26, "GPIO26", + MTK_EINT_FUNCTION(0, 26), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO26"), + MTK_FUNCTION(1, "CMMPDN"), + MTK_FUNCTION(2, "CMMCLK4"), + MTK_FUNCTION(3, "IR_IN"), + MTK_FUNCTION(4, "SCL6"), + MTK_FUNCTION(5, "ADSP_JTAG0_TDO"), + MTK_FUNCTION(6, "MD32_0_JTAG_TDO") + ), + MTK_PIN( + 27, "GPIO27", + MTK_EINT_FUNCTION(0, 27), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO27"), + MTK_FUNCTION(1, "HDMIRX20_HTPLG"), + MTK_FUNCTION(2, "CMFLASH0"), + MTK_FUNCTION(3, "MD32_0_TXD"), + MTK_FUNCTION(4, "TP_UTXD2_AO"), + MTK_FUNCTION(5, "SCL7"), + MTK_FUNCTION(6, "UCTS2"), + MTK_FUNCTION(7, "DBG_MON_A18") + ), + MTK_PIN( + 28, "GPIO28", + MTK_EINT_FUNCTION(0, 28), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO28"), + MTK_FUNCTION(1, "HDMIRX20_PWR5V"), + MTK_FUNCTION(2, "CMFLASH1"), + MTK_FUNCTION(3, "MD32_0_RXD"), + MTK_FUNCTION(4, "TP_URXD2_AO"), + MTK_FUNCTION(5, "SDA7"), + MTK_FUNCTION(6, "URTS2"), + MTK_FUNCTION(7, "DBG_MON_A19") + ), + MTK_PIN( + 29, "GPIO29", + MTK_EINT_FUNCTION(0, 29), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO29"), + MTK_FUNCTION(1, "HDMIRX20_SCL"), + MTK_FUNCTION(2, "CMFLASH2"), + MTK_FUNCTION(3, "SCL5"), + MTK_FUNCTION(4, "TP_URTS2_AO"), + MTK_FUNCTION(6, "UTXD2"), + MTK_FUNCTION(7, "DBG_MON_A20") + ), + MTK_PIN( + 30, "GPIO30", + MTK_EINT_FUNCTION(0, 30), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO30"), + MTK_FUNCTION(1, "HDMIRX20_SDA"), + MTK_FUNCTION(2, "CMFLASH3"), + MTK_FUNCTION(3, "SDA5"), + MTK_FUNCTION(4, "TP_UCTS2_AO"), + MTK_FUNCTION(6, "URXD2"), + MTK_FUNCTION(7, "DBG_MON_A21") + ), + MTK_PIN( + 31, "GPIO31", + MTK_EINT_FUNCTION(0, 31), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO31"), + MTK_FUNCTION(1, "HDMITX20_PWR5V"), + MTK_FUNCTION(2, "DMIC1_DAT_R"), + MTK_FUNCTION(3, "PERSTN"), + MTK_FUNCTION(7, "DBG_MON_A22") + ), + MTK_PIN( + 32, "GPIO32", + MTK_EINT_FUNCTION(0, 32), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO32"), + MTK_FUNCTION(1, "HDMITX20_HTPLG"), + MTK_FUNCTION(3, "CLKREQN"), + MTK_FUNCTION(7, "DBG_MON_A23") + ), + MTK_PIN( + 33, "GPIO33", + MTK_EINT_FUNCTION(0, 33), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO33"), + MTK_FUNCTION(1, "HDMITX20_CEC"), + MTK_FUNCTION(2, "CMVREF0"), + MTK_FUNCTION(3, "WAKEN") + ), + MTK_PIN( + 34, "GPIO34", + MTK_EINT_FUNCTION(0, 34), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO34"), + MTK_FUNCTION(1, "HDMITX20_SCL"), + MTK_FUNCTION(2, "CMVREF1"), + MTK_FUNCTION(3, "SCL7"), + MTK_FUNCTION(4, "SCL6"), + MTK_FUNCTION(7, "DBG_MON_A24") + ), + MTK_PIN( + 35, "GPIO35", + MTK_EINT_FUNCTION(0, 35), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO35"), + MTK_FUNCTION(1, "HDMITX20_SDA"), + MTK_FUNCTION(2, "CMVREF2"), + MTK_FUNCTION(3, "SDA7"), + MTK_FUNCTION(4, "SDA6"), + MTK_FUNCTION(7, "DBG_MON_A25") + ), + MTK_PIN( + 36, "GPIO36", + MTK_EINT_FUNCTION(0, 36), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO36"), + MTK_FUNCTION(1, "RTC32K_CK"), + MTK_FUNCTION(7, "DBG_MON_A27") + ), + MTK_PIN( + 37, "GPIO37", + MTK_EINT_FUNCTION(0, 37), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO37"), + MTK_FUNCTION(1, "WATCHDOG"), + MTK_FUNCTION(7, "DBG_MON_A28") + ), + MTK_PIN( + 38, "GPIO38", + MTK_EINT_FUNCTION(0, 38), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO38"), + MTK_FUNCTION(1, "SRCLKENA0"), + MTK_FUNCTION(7, "DBG_MON_A29") + ), + MTK_PIN( + 39, "GPIO39", + MTK_EINT_FUNCTION(0, 39), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO39"), + MTK_FUNCTION(1, "SRCLKENA1"), + MTK_FUNCTION(2, "DMIC2_DAT_R"), + MTK_FUNCTION(7, "DBG_MON_A30") + ), + MTK_PIN( + 40, "GPIO40", + MTK_EINT_FUNCTION(0, 40), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO40"), + MTK_FUNCTION(1, "PWRAP_SPI0_CSN"), + MTK_FUNCTION(3, "SPIM3_CSB"), + MTK_FUNCTION(7, "DBG_MON_A31") + ), + MTK_PIN( + 41, "GPIO41", + MTK_EINT_FUNCTION(0, 41), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO41"), + MTK_FUNCTION(1, "PWRAP_SPI0_CK"), + MTK_FUNCTION(3, "SPIM3_CLK"), + MTK_FUNCTION(7, "DBG_MON_A32") + ), + MTK_PIN( + 42, "GPIO42", + MTK_EINT_FUNCTION(0, 42), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO42"), + MTK_FUNCTION(1, "PWRAP_SPI0_MO"), + MTK_FUNCTION(2, "PWRAP_SPI0_MI"), + MTK_FUNCTION(3, "SPIM3_MO"), + MTK_FUNCTION(7, "DBG_MON_B0") + ), + MTK_PIN( + 43, "GPIO43", + MTK_EINT_FUNCTION(0, 43), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO43"), + MTK_FUNCTION(1, "PWRAP_SPI0_MI"), + MTK_FUNCTION(2, "PWRAP_SPI0_MO"), + MTK_FUNCTION(3, "SPIM3_MI"), + MTK_FUNCTION(7, "DBG_MON_B1") + ), + MTK_PIN( + 44, "GPIO44", + MTK_EINT_FUNCTION(0, 44), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO44"), + MTK_FUNCTION(1, "SPMI_M_SCL"), + MTK_FUNCTION(2, "I2SI00_DATA1"), + MTK_FUNCTION(3, "SCL5"), + MTK_FUNCTION(4, "UTXD5"), + MTK_FUNCTION(7, "DBG_MON_B2") + ), + MTK_PIN( + 45, "GPIO45", + MTK_EINT_FUNCTION(0, 45), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO45"), + MTK_FUNCTION(1, "SPMI_M_SDA"), + MTK_FUNCTION(2, "I2SI00_DATA2"), + MTK_FUNCTION(3, "SDA5"), + MTK_FUNCTION(4, "URXD5"), + MTK_FUNCTION(7, "DBG_MON_B3") + ), + MTK_PIN( + 46, "GPIO46", + MTK_EINT_FUNCTION(0, 46), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO46"), + MTK_FUNCTION(1, "I2SIN_MCK"), + MTK_FUNCTION(2, "I2SI00_DATA3"), + MTK_FUNCTION(3, "SPLIN_MCK"), + MTK_FUNCTION(7, "DBG_MON_B4") + ), + MTK_PIN( + 47, "GPIO47", + MTK_EINT_FUNCTION(0, 47), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO47"), + MTK_FUNCTION(1, "I2SIN_BCK"), + MTK_FUNCTION(2, "I2SIN0_BCK"), + MTK_FUNCTION(3, "SPLIN_LRCK"), + MTK_FUNCTION(7, "DBG_MON_B5") + ), + MTK_PIN( + 48, "GPIO48", + MTK_EINT_FUNCTION(0, 48), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO48"), + MTK_FUNCTION(1, "I2SIN_WS"), + MTK_FUNCTION(2, "I2SIN0_LRCK"), + MTK_FUNCTION(3, "SPLIN_BCK"), + MTK_FUNCTION(7, "DBG_MON_B6") + ), + MTK_PIN( + 49, "GPIO49", + MTK_EINT_FUNCTION(0, 49), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO49"), + MTK_FUNCTION(1, "I2SIN_D0"), + MTK_FUNCTION(2, "I2SI00_DATA0"), + MTK_FUNCTION(3, "SPLIN_D0"), + MTK_FUNCTION(7, "DBG_MON_B7") + ), + MTK_PIN( + 50, "GPIO50", + MTK_EINT_FUNCTION(0, 50), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO50"), + MTK_FUNCTION(1, "I2SO1_MCK"), + MTK_FUNCTION(2, "I2SI5_D0"), + MTK_FUNCTION(4, "I2SO4_MCK"), + MTK_FUNCTION(7, "DBG_MON_B8") + ), + MTK_PIN( + 51, "GPIO51", + MTK_EINT_FUNCTION(0, 51), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO51"), + MTK_FUNCTION(1, "I2SO1_BCK"), + MTK_FUNCTION(2, "I2SI5_BCK"), + MTK_FUNCTION(7, "DBG_MON_B9") + ), + MTK_PIN( + 52, "GPIO52", + MTK_EINT_FUNCTION(0, 52), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO52"), + MTK_FUNCTION(1, "I2SO1_WS"), + MTK_FUNCTION(2, "I2SI5_WS"), + MTK_FUNCTION(7, "DBG_MON_B10") + ), + MTK_PIN( + 53, "GPIO53", + MTK_EINT_FUNCTION(0, 53), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO53"), + MTK_FUNCTION(1, "I2SO1_D0"), + MTK_FUNCTION(2, "I2SI5_MCK"), + MTK_FUNCTION(7, "DBG_MON_B11") + ), + MTK_PIN( + 54, "GPIO54", + MTK_EINT_FUNCTION(0, 54), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO54"), + MTK_FUNCTION(1, "I2SO1_D1"), + MTK_FUNCTION(2, "I2SI01_DATA1"), + MTK_FUNCTION(3, "SPLIN_D1"), + MTK_FUNCTION(4, "I2SO4_BCK"), + MTK_FUNCTION(7, "DBG_MON_B12") + ), + MTK_PIN( + 55, "GPIO55", + MTK_EINT_FUNCTION(0, 55), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO55"), + MTK_FUNCTION(1, "I2SO1_D2"), + MTK_FUNCTION(2, "I2SI01_DATA2"), + MTK_FUNCTION(3, "SPLIN_D2"), + MTK_FUNCTION(4, "I2SO4_WS"), + MTK_FUNCTION(7, "DBG_MON_B13") + ), + MTK_PIN( + 56, "GPIO56", + MTK_EINT_FUNCTION(0, 56), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO56"), + MTK_FUNCTION(1, "I2SO1_D3"), + MTK_FUNCTION(2, "I2SI01_DATA3"), + MTK_FUNCTION(3, "SPLIN_D3"), + MTK_FUNCTION(4, "I2SO4_D0"), + MTK_FUNCTION(7, "DBG_MON_B14") + ), + MTK_PIN( + 57, "GPIO57", + MTK_EINT_FUNCTION(0, 57), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO57"), + MTK_FUNCTION(1, "I2SO2_MCK"), + MTK_FUNCTION(2, "I2SO1_D12"), + MTK_FUNCTION(3, "LCM1_RST"), + MTK_FUNCTION(7, "DBG_MON_B15") + ), + MTK_PIN( + 58, "GPIO58", + MTK_EINT_FUNCTION(0, 58), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO58"), + MTK_FUNCTION(1, "I2SO2_BCK"), + MTK_FUNCTION(2, "I2SO1_D13"), + MTK_FUNCTION(3, "I2SIN1_BCK"), + MTK_FUNCTION(7, "DBG_MON_B16") + ), + MTK_PIN( + 59, "GPIO59", + MTK_EINT_FUNCTION(0, 59), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO59"), + MTK_FUNCTION(1, "I2SO2_WS"), + MTK_FUNCTION(2, "I2SO1_D14"), + MTK_FUNCTION(3, "I2SIN1_LRCK"), + MTK_FUNCTION(7, "DBG_MON_B17") + ), + MTK_PIN( + 60, "GPIO60", + MTK_EINT_FUNCTION(0, 60), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO60"), + MTK_FUNCTION(1, "I2SO2_D0"), + MTK_FUNCTION(2, "I2SO1_D15"), + MTK_FUNCTION(3, "I2SI01_DATA0"), + MTK_FUNCTION(7, "DBG_MON_B18") + ), + MTK_PIN( + 61, "GPIO61", + MTK_EINT_FUNCTION(0, 61), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO61"), + MTK_FUNCTION(1, "DMIC1_CLK"), + MTK_FUNCTION(2, "I2SO2_BCK"), + MTK_FUNCTION(3, "SCP_SPI2_CK"), + MTK_FUNCTION(7, "DBG_MON_B19") + ), + MTK_PIN( + 62, "GPIO62", + MTK_EINT_FUNCTION(0, 62), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO62"), + MTK_FUNCTION(1, "DMIC1_DAT"), + MTK_FUNCTION(2, "I2SO2_WS"), + MTK_FUNCTION(3, "SCP_SPI2_MI"), + MTK_FUNCTION(7, "DBG_MON_B20") + ), + MTK_PIN( + 63, "GPIO63", + MTK_EINT_FUNCTION(0, 63), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO63"), + MTK_FUNCTION(1, "DMIC2_CLK"), + MTK_FUNCTION(2, "VBUSVALID"), + MTK_FUNCTION(3, "SCP_SPI2_MO"), + MTK_FUNCTION(4, "SCP_SCL2"), + MTK_FUNCTION(5, "SCP_JTAG1_TDO"), + MTK_FUNCTION(6, "JTDO_SEL1"), + MTK_FUNCTION(7, "DBG_MON_B21") + ), + MTK_PIN( + 64, "GPIO64", + MTK_EINT_FUNCTION(0, 64), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO64"), + MTK_FUNCTION(1, "DMIC2_DAT"), + MTK_FUNCTION(2, "VBUSVALID_1P"), + MTK_FUNCTION(3, "SCP_SPI2_CS"), + MTK_FUNCTION(4, "SCP_SDA2"), + MTK_FUNCTION(7, "DBG_MON_B22") + ), + MTK_PIN( + 65, "GPIO65", + MTK_EINT_FUNCTION(0, 65), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO65"), + MTK_FUNCTION(1, "PCM_DO"), + MTK_FUNCTION(2, "AUXIF_ST0"), + MTK_FUNCTION(3, "UCTS2"), + MTK_FUNCTION(5, "SCP_JTAG1_TMS"), + MTK_FUNCTION(6, "JTMS_SEL1"), + MTK_FUNCTION(7, "DBG_MON_B23") + ), + MTK_PIN( + 66, "GPIO66", + MTK_EINT_FUNCTION(0, 66), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO66"), + MTK_FUNCTION(1, "PCM_CLK"), + MTK_FUNCTION(2, "AUXIF_CLK0"), + MTK_FUNCTION(3, "URTS2"), + MTK_FUNCTION(5, "SCP_JTAG1_TCK"), + MTK_FUNCTION(6, "JTCK_SEL1"), + MTK_FUNCTION(7, "DBG_MON_B24") + ), + MTK_PIN( + 67, "GPIO67", + MTK_EINT_FUNCTION(0, 67), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO67"), + MTK_FUNCTION(1, "PCM_DI"), + MTK_FUNCTION(2, "AUXIF_ST1"), + MTK_FUNCTION(3, "UTXD2"), + MTK_FUNCTION(5, "SCP_JTAG1_TRSTN"), + MTK_FUNCTION(6, "JTRSTn_SEL1"), + MTK_FUNCTION(7, "DBG_MON_B25") + ), + MTK_PIN( + 68, "GPIO68", + MTK_EINT_FUNCTION(0, 68), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO68"), + MTK_FUNCTION(1, "PCM_SYNC"), + MTK_FUNCTION(2, "AUXIF_CLK1"), + MTK_FUNCTION(3, "URXD2"), + MTK_FUNCTION(5, "SCP_JTAG1_TDI"), + MTK_FUNCTION(6, "JTDI_SEL1"), + MTK_FUNCTION(7, "DBG_MON_B26") + ), + MTK_PIN( + 69, "GPIO69", + MTK_EINT_FUNCTION(0, 69), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO69"), + MTK_FUNCTION(1, "AUD_CLK_MOSI"), + MTK_FUNCTION(2, "I2SIN2_BCK"), + MTK_FUNCTION(3, "PWM_0"), + MTK_FUNCTION(4, "WAKEN"), + MTK_FUNCTION(7, "DBG_MON_B27") + ), + MTK_PIN( + 70, "GPIO70", + MTK_EINT_FUNCTION(0, 70), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO70"), + MTK_FUNCTION(1, "AUD_SYNC_MOSI"), + MTK_FUNCTION(2, "I2SIN2_LRCK"), + MTK_FUNCTION(3, "PWM_1"), + MTK_FUNCTION(4, "PERSTN"), + MTK_FUNCTION(7, "DBG_MON_B28") + ), + MTK_PIN( + 71, "GPIO71", + MTK_EINT_FUNCTION(0, 71), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO71"), + MTK_FUNCTION(1, "AUD_DAT_MOSI0"), + MTK_FUNCTION(2, "IDDIG_2P"), + MTK_FUNCTION(3, "PWM_2"), + MTK_FUNCTION(4, "CLKREQN"), + MTK_FUNCTION(7, "DBG_MON_B29") + ), + MTK_PIN( + 72, "GPIO72", + MTK_EINT_FUNCTION(0, 72), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO72"), + MTK_FUNCTION(1, "AUD_DAT_MOSI1"), + MTK_FUNCTION(2, "USB_DRVVBUS_2P"), + MTK_FUNCTION(3, "PWM_3"), + MTK_FUNCTION(4, "PERSTN_1"), + MTK_FUNCTION(7, "DBG_MON_B30") + ), + MTK_PIN( + 73, "GPIO73", + MTK_EINT_FUNCTION(0, 73), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO73"), + MTK_FUNCTION(1, "AUD_DAT_MISO0"), + MTK_FUNCTION(2, "I2SI02_DATA0"), + MTK_FUNCTION(4, "CLKREQN_1"), + MTK_FUNCTION(5, "VOW_DAT_MISO"), + MTK_FUNCTION(7, "DBG_MON_B31") + ), + MTK_PIN( + 74, "GPIO74", + MTK_EINT_FUNCTION(0, 74), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO74"), + MTK_FUNCTION(1, "AUD_DAT_MISO1"), + MTK_FUNCTION(2, "I2SI02_DATA1"), + MTK_FUNCTION(4, "WAKEN_1"), + MTK_FUNCTION(5, "VOW_CLK_MISO"), + MTK_FUNCTION(7, "DBG_MON_B32") + ), + MTK_PIN( + 75, "GPIO75", + MTK_EINT_FUNCTION(0, 75), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO75"), + MTK_FUNCTION(1, "AUD_DAT_MISO2"), + MTK_FUNCTION(2, "I2SI02_DATA2") + ), + MTK_PIN( + 76, "GPIO76", + MTK_EINT_FUNCTION(0, 76), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO76"), + MTK_FUNCTION(1, "SCP_VREQ_VAO"), + MTK_FUNCTION(2, "I2SI02_DATA3"), + MTK_FUNCTION(7, "DBG_MON_A26") + ), + MTK_PIN( + 77, "GPIO77", + MTK_EINT_FUNCTION(0, 77), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO77"), + MTK_FUNCTION(1, "DGI_D0"), + MTK_FUNCTION(2, "DPI_D0"), + MTK_FUNCTION(3, "I2SI4_MCK"), + MTK_FUNCTION(4, "SPIM4_CLK"), + MTK_FUNCTION(5, "GBE_TXD3"), + MTK_FUNCTION(6, "SPM_JTAG_TCK") + ), + MTK_PIN( + 78, "GPIO78", + MTK_EINT_FUNCTION(0, 78), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO78"), + MTK_FUNCTION(1, "DGI_D1"), + MTK_FUNCTION(2, "DPI_D1"), + MTK_FUNCTION(3, "I2SI4_BCK"), + MTK_FUNCTION(4, "SPIM4_MO"), + MTK_FUNCTION(5, "GBE_TXD2"), + MTK_FUNCTION(6, "SPM_JTAG_TMS") + ), + MTK_PIN( + 79, "GPIO79", + MTK_EINT_FUNCTION(0, 79), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO79"), + MTK_FUNCTION(1, "DGI_D2"), + MTK_FUNCTION(2, "DPI_D2"), + MTK_FUNCTION(3, "I2SI4_WS"), + MTK_FUNCTION(4, "SPIM4_CSB"), + MTK_FUNCTION(5, "GBE_TXD1"), + MTK_FUNCTION(6, "SPM_JTAG_TDI") + ), + MTK_PIN( + 80, "GPIO80", + MTK_EINT_FUNCTION(0, 80), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO80"), + MTK_FUNCTION(1, "DGI_D3"), + MTK_FUNCTION(2, "DPI_D3"), + MTK_FUNCTION(3, "I2SI4_D0"), + MTK_FUNCTION(4, "SPIM4_MI"), + MTK_FUNCTION(5, "GBE_TXD0"), + MTK_FUNCTION(6, "SPM_JTAG_TDO") + ), + MTK_PIN( + 81, "GPIO81", + MTK_EINT_FUNCTION(0, 81), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO81"), + MTK_FUNCTION(1, "DGI_D4"), + MTK_FUNCTION(2, "DPI_D4"), + MTK_FUNCTION(3, "I2SI5_MCK"), + MTK_FUNCTION(4, "SPIM5_CLK"), + MTK_FUNCTION(5, "GBE_RXD3"), + MTK_FUNCTION(6, "SPM_JTAG_TRSTN") + ), + MTK_PIN( + 82, "GPIO82", + MTK_EINT_FUNCTION(0, 82), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO82"), + MTK_FUNCTION(1, "DGI_D5"), + MTK_FUNCTION(2, "DPI_D5"), + MTK_FUNCTION(3, "I2SI5_BCK"), + MTK_FUNCTION(4, "SPIM5_MO"), + MTK_FUNCTION(5, "GBE_RXD2"), + MTK_FUNCTION(6, "MCUPM_JTAG_TDO") + ), + MTK_PIN( + 83, "GPIO83", + MTK_EINT_FUNCTION(0, 83), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO83"), + MTK_FUNCTION(1, "DGI_D6"), + MTK_FUNCTION(2, "DPI_D6"), + MTK_FUNCTION(3, "I2SI5_WS"), + MTK_FUNCTION(4, "SPIM5_CSB"), + MTK_FUNCTION(5, "GBE_RXD1"), + MTK_FUNCTION(6, "MCUPM_JTAG_TMS") + ), + MTK_PIN( + 84, "GPIO84", + MTK_EINT_FUNCTION(0, 84), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO84"), + MTK_FUNCTION(1, "DGI_D7"), + MTK_FUNCTION(2, "DPI_D7"), + MTK_FUNCTION(3, "I2SI5_D0"), + MTK_FUNCTION(4, "SPIM5_MI"), + MTK_FUNCTION(5, "GBE_RXD0"), + MTK_FUNCTION(6, "MCUPM_JTAG_TCK") + ), + MTK_PIN( + 85, "GPIO85", + MTK_EINT_FUNCTION(0, 85), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO85"), + MTK_FUNCTION(1, "DGI_D8"), + MTK_FUNCTION(2, "DPI_D8"), + MTK_FUNCTION(3, "I2SO4_MCK"), + MTK_FUNCTION(4, "SCP_SPI1_B_CK"), + MTK_FUNCTION(5, "GBE_TXC"), + MTK_FUNCTION(6, "MCUPM_JTAG_TDI") + ), + MTK_PIN( + 86, "GPIO86", + MTK_EINT_FUNCTION(0, 86), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO86"), + MTK_FUNCTION(1, "DGI_D9"), + MTK_FUNCTION(2, "DPI_D9"), + MTK_FUNCTION(3, "I2SO4_BCK"), + MTK_FUNCTION(4, "SCP_SPI1_B_MI"), + MTK_FUNCTION(5, "GBE_RXC"), + MTK_FUNCTION(6, "MCUPM_JTAG_TRSTN") + ), + MTK_PIN( + 87, "GPIO87", + MTK_EINT_FUNCTION(0, 87), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO87"), + MTK_FUNCTION(1, "DGI_D10"), + MTK_FUNCTION(2, "DPI_D10"), + MTK_FUNCTION(3, "I2SO4_WS"), + MTK_FUNCTION(4, "SCP_SPI1_B_CS"), + MTK_FUNCTION(5, "GBE_RXDV"), + MTK_FUNCTION(6, "SSPM_JTAG_TDO") + ), + MTK_PIN( + 88, "GPIO88", + MTK_EINT_FUNCTION(0, 88), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO88"), + MTK_FUNCTION(1, "DGI_D11"), + MTK_FUNCTION(2, "DPI_D11"), + MTK_FUNCTION(3, "I2SO4_D0"), + MTK_FUNCTION(4, "SCP_SPI1_B_MO"), + MTK_FUNCTION(5, "GBE_TXEN"), + MTK_FUNCTION(6, "SSPM_JTAG_TMS") + ), + MTK_PIN( + 89, "GPIO89", + MTK_EINT_FUNCTION(0, 89), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO89"), + MTK_FUNCTION(1, "DGI_D12"), + MTK_FUNCTION(2, "DPI_D12"), + MTK_FUNCTION(3, "MSDC2_CMD_A"), + MTK_FUNCTION(4, "I2SO5_BCK"), + MTK_FUNCTION(5, "GBE_MDC"), + MTK_FUNCTION(6, "SSPM_JTAG_TCK") + ), + MTK_PIN( + 90, "GPIO90", + MTK_EINT_FUNCTION(0, 90), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO90"), + MTK_FUNCTION(1, "DGI_D13"), + MTK_FUNCTION(2, "DPI_D13"), + MTK_FUNCTION(3, "MSDC2_CLK_A"), + MTK_FUNCTION(4, "I2SO5_WS"), + MTK_FUNCTION(5, "GBE_MDIO"), + MTK_FUNCTION(6, "SSPM_JTAG_TDI") + ), + MTK_PIN( + 91, "GPIO91", + MTK_EINT_FUNCTION(0, 91), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO91"), + MTK_FUNCTION(1, "DGI_D14"), + MTK_FUNCTION(2, "DPI_D14"), + MTK_FUNCTION(3, "MSDC2_DAT3_A"), + MTK_FUNCTION(4, "I2SO5_D0"), + MTK_FUNCTION(5, "GBE_TXER"), + MTK_FUNCTION(6, "SSPM_JTAG_TRSTN") + ), + MTK_PIN( + 92, "GPIO92", + MTK_EINT_FUNCTION(0, 92), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO92"), + MTK_FUNCTION(1, "DGI_D15"), + MTK_FUNCTION(2, "DPI_D15"), + MTK_FUNCTION(3, "MSDC2_DAT0_A"), + MTK_FUNCTION(4, "I2SO2_D1"), + MTK_FUNCTION(5, "GBE_RXER"), + MTK_FUNCTION(6, "CCU0_JTAG_TDO") + ), + MTK_PIN( + 93, "GPIO93", + MTK_EINT_FUNCTION(0, 93), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO93"), + MTK_FUNCTION(1, "DGI_HSYNC"), + MTK_FUNCTION(2, "DPI_HSYNC"), + MTK_FUNCTION(3, "MSDC2_DAT2_A"), + MTK_FUNCTION(4, "I2SO2_D2"), + MTK_FUNCTION(5, "GBE_COL"), + MTK_FUNCTION(6, "CCU0_JTAG_TMS") + ), + MTK_PIN( + 94, "GPIO94", + MTK_EINT_FUNCTION(0, 94), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO94"), + MTK_FUNCTION(1, "DGI_VSYNC"), + MTK_FUNCTION(2, "DPI_VSYNC"), + MTK_FUNCTION(3, "MSDC2_DAT1_A"), + MTK_FUNCTION(4, "I2SO2_D3"), + MTK_FUNCTION(5, "GBE_INTR"), + MTK_FUNCTION(6, "CCU0_JTAG_TDI") + ), + MTK_PIN( + 95, "GPIO95", + MTK_EINT_FUNCTION(0, 95), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO95"), + MTK_FUNCTION(1, "DGI_DE"), + MTK_FUNCTION(2, "DPI_DE"), + MTK_FUNCTION(3, "UTXD2"), + MTK_FUNCTION(5, "I2SIN_D1"), + MTK_FUNCTION(6, "CCU0_JTAG_TCK") + ), + MTK_PIN( + 96, "GPIO96", + MTK_EINT_FUNCTION(0, 96), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO96"), + MTK_FUNCTION(1, "DGI_CK"), + MTK_FUNCTION(2, "DPI_CK"), + MTK_FUNCTION(3, "URXD2"), + MTK_FUNCTION(4, "I2SO5_MCK"), + MTK_FUNCTION(5, "I2SIN_D2"), + MTK_FUNCTION(6, "CCU0_JTAG_TRST") + ), + MTK_PIN( + 97, "GPIO97", + MTK_EINT_FUNCTION(0, 97), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO97"), + MTK_FUNCTION(1, "DISP_PWM0"), + MTK_FUNCTION(2, "DVFSRC_EXT_REQ") + ), + MTK_PIN( + 98, "GPIO98", + MTK_EINT_FUNCTION(0, 98), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO98"), + MTK_FUNCTION(1, "UTXD0") + ), + MTK_PIN( + 99, "GPIO99", + MTK_EINT_FUNCTION(0, 99), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO99"), + MTK_FUNCTION(1, "URXD0") + ), + MTK_PIN( + 100, "GPIO100", + MTK_EINT_FUNCTION(0, 100), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO100"), + MTK_FUNCTION(1, "URTS1"), + MTK_FUNCTION(2, "DSI_TE"), + MTK_FUNCTION(3, "I2SO1_D8"), + MTK_FUNCTION(4, "KPROW2"), + MTK_FUNCTION(5, "PWM_0"), + MTK_FUNCTION(6, "TP_URTS1_AO"), + MTK_FUNCTION(7, "I2SIN_D0") + ), + MTK_PIN( + 101, "GPIO101", + MTK_EINT_FUNCTION(0, 101), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO101"), + MTK_FUNCTION(1, "UCTS1"), + MTK_FUNCTION(2, "DSI1_TE"), + MTK_FUNCTION(3, "I2SO1_D9"), + MTK_FUNCTION(4, "KPCOL2"), + MTK_FUNCTION(5, "PWM_1"), + MTK_FUNCTION(6, "TP_UCTS1_AO"), + MTK_FUNCTION(7, "I2SIN_D1") + ), + MTK_PIN( + 102, "GPIO102", + MTK_EINT_FUNCTION(0, 102), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO102"), + MTK_FUNCTION(1, "UTXD1"), + MTK_FUNCTION(2, "VBUSVALID_2P"), + MTK_FUNCTION(3, "I2SO1_D10"), + MTK_FUNCTION(4, "SSPM_UTXD_AO"), + MTK_FUNCTION(5, "TP_UTXD1_AO"), + MTK_FUNCTION(6, "MD32_1_TXD"), + MTK_FUNCTION(7, "I2SIN_D2") + ), + MTK_PIN( + 103, "GPIO103", + MTK_EINT_FUNCTION(0, 103), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO103"), + MTK_FUNCTION(1, "URXD1"), + MTK_FUNCTION(2, "VBUSVALID_3P"), + MTK_FUNCTION(3, "I2SO1_D11"), + MTK_FUNCTION(4, "SSPM_URXD_AO"), + MTK_FUNCTION(5, "TP_URXD1_AO"), + MTK_FUNCTION(6, "MD32_1_RXD"), + MTK_FUNCTION(7, "I2SIN_D3") + ), + MTK_PIN( + 104, "GPIO104", + MTK_EINT_FUNCTION(0, 104), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO104"), + MTK_FUNCTION(1, "KPROW0"), + MTK_FUNCTION(2, "DISP_PWM1") + ), + MTK_PIN( + 105, "GPIO105", + MTK_EINT_FUNCTION(0, 105), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO105"), + MTK_FUNCTION(1, "KPROW1"), + MTK_FUNCTION(2, "EDP_TX_HPD"), + MTK_FUNCTION(3, "PWM_2") + ), + MTK_PIN( + 106, "GPIO106", + MTK_EINT_FUNCTION(0, 106), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO106"), + MTK_FUNCTION(1, "KPCOL0") + ), + MTK_PIN( + 107, "GPIO107", + MTK_EINT_FUNCTION(0, 107), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO107"), + MTK_FUNCTION(1, "KPCOL1"), + MTK_FUNCTION(2, "DSI1_TE"), + MTK_FUNCTION(3, "PWM_3"), + MTK_FUNCTION(4, "SCP_SCL3"), + MTK_FUNCTION(5, "I2SIN_MCK") + ), + MTK_PIN( + 108, "GPIO108", + MTK_EINT_FUNCTION(0, 108), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO108"), + MTK_FUNCTION(1, "LCM_RST"), + MTK_FUNCTION(2, "KPCOL1"), + MTK_FUNCTION(4, "SCP_SDA3"), + MTK_FUNCTION(5, "I2SIN_BCK") + ), + MTK_PIN( + 109, "GPIO109", + MTK_EINT_FUNCTION(0, 109), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO109"), + MTK_FUNCTION(1, "DSI_TE"), + MTK_FUNCTION(2, "I2SIN_D3"), + MTK_FUNCTION(5, "I2SIN_WS") + ), + MTK_PIN( + 110, "GPIO110", + MTK_EINT_FUNCTION(0, 110), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO110"), + MTK_FUNCTION(1, "MSDC1_CMD"), + MTK_FUNCTION(2, "JTMS_SEL3"), + MTK_FUNCTION(3, "UDI_TMS"), + MTK_FUNCTION(5, "CCU1_JTAG_TMS"), + MTK_FUNCTION(6, "IPU_JTAG_TMS") + ), + MTK_PIN( + 111, "GPIO111", + MTK_EINT_FUNCTION(0, 111), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO111"), + MTK_FUNCTION(1, "MSDC1_CLK"), + MTK_FUNCTION(2, "JTCK_SEL3"), + MTK_FUNCTION(3, "UDI_TCK"), + MTK_FUNCTION(5, "CCU1_JTAG_TCK"), + MTK_FUNCTION(6, "IPU_JTAG_TCK") + ), + MTK_PIN( + 112, "GPIO112", + MTK_EINT_FUNCTION(0, 112), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO112"), + MTK_FUNCTION(1, "MSDC1_DAT0"), + MTK_FUNCTION(2, "JTDI_SEL3"), + MTK_FUNCTION(3, "UDI_TDI"), + MTK_FUNCTION(4, "I2SO2_D0"), + MTK_FUNCTION(5, "CCU1_JTAG_TDI"), + MTK_FUNCTION(6, "IPU_JTAG_TDI") + ), + MTK_PIN( + 113, "GPIO113", + MTK_EINT_FUNCTION(0, 113), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO113"), + MTK_FUNCTION(1, "MSDC1_DAT1"), + MTK_FUNCTION(2, "JTDO_SEL3"), + MTK_FUNCTION(3, "UDI_TDO"), + MTK_FUNCTION(4, "I2SO2_D1"), + MTK_FUNCTION(5, "CCU1_JTAG_TDO"), + MTK_FUNCTION(6, "IPU_JTAG_TDO") + ), + MTK_PIN( + 114, "GPIO114", + MTK_EINT_FUNCTION(0, 114), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO114"), + MTK_FUNCTION(1, "MSDC1_DAT2"), + MTK_FUNCTION(2, "JTRSTn_SEL3"), + MTK_FUNCTION(3, "UDI_NTRST"), + MTK_FUNCTION(4, "I2SO2_D2"), + MTK_FUNCTION(5, "CCU1_JTAG_TRST"), + MTK_FUNCTION(6, "IPU_JTAG_TRST") + ), + MTK_PIN( + 115, "GPIO115", + MTK_EINT_FUNCTION(0, 115), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO115"), + MTK_FUNCTION(1, "MSDC1_DAT3"), + MTK_FUNCTION(4, "I2SO2_D3"), + MTK_FUNCTION(6, "MD32_1_GPIO2") + ), + MTK_PIN( + 116, "GPIO116", + MTK_EINT_FUNCTION(0, 116), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO116"), + MTK_FUNCTION(1, "MSDC0_DAT7") + ), + MTK_PIN( + 117, "GPIO117", + MTK_EINT_FUNCTION(0, 117), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO117"), + MTK_FUNCTION(1, "MSDC0_DAT6") + ), + MTK_PIN( + 118, "GPIO118", + MTK_EINT_FUNCTION(0, 118), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO118"), + MTK_FUNCTION(1, "MSDC0_DAT5") + ), + MTK_PIN( + 119, "GPIO119", + MTK_EINT_FUNCTION(0, 119), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO119"), + MTK_FUNCTION(1, "MSDC0_DAT4") + ), + MTK_PIN( + 120, "GPIO120", + MTK_EINT_FUNCTION(0, 120), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO120"), + MTK_FUNCTION(1, "MSDC0_RSTB") + ), + MTK_PIN( + 121, "GPIO121", + MTK_EINT_FUNCTION(0, 121), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO121"), + MTK_FUNCTION(1, "MSDC0_CMD") + ), + MTK_PIN( + 122, "GPIO122", + MTK_EINT_FUNCTION(0, 122), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO122"), + MTK_FUNCTION(1, "MSDC0_CLK") + ), + MTK_PIN( + 123, "GPIO123", + MTK_EINT_FUNCTION(0, 123), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO123"), + MTK_FUNCTION(1, "MSDC0_DAT3") + ), + MTK_PIN( + 124, "GPIO124", + MTK_EINT_FUNCTION(0, 124), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO124"), + MTK_FUNCTION(1, "MSDC0_DAT2") + ), + MTK_PIN( + 125, "GPIO125", + MTK_EINT_FUNCTION(0, 125), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO125"), + MTK_FUNCTION(1, "MSDC0_DAT1") + ), + MTK_PIN( + 126, "GPIO126", + MTK_EINT_FUNCTION(0, 126), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO126"), + MTK_FUNCTION(1, "MSDC0_DAT0") + ), + MTK_PIN( + 127, "GPIO127", + MTK_EINT_FUNCTION(0, 127), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO127"), + MTK_FUNCTION(1, "MSDC0_DSL") + ), + MTK_PIN( + 128, "GPIO128", + MTK_EINT_FUNCTION(0, 128), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO128"), + MTK_FUNCTION(1, "IDDIG"), + MTK_FUNCTION(2, "UCTS2"), + MTK_FUNCTION(3, "UTXD5"), + MTK_FUNCTION(4, "UFS_MPHY_SCL"), + MTK_FUNCTION(5, "mbistreaden_trigger"), + MTK_FUNCTION(6, "MD32_1_GPIO0"), + MTK_FUNCTION(7, "SCP_SCL2") + ), + MTK_PIN( + 129, "GPIO129", + MTK_EINT_FUNCTION(0, 129), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO129"), + MTK_FUNCTION(1, "USB_DRVVBUS"), + MTK_FUNCTION(2, "URTS2"), + MTK_FUNCTION(3, "URXD5"), + MTK_FUNCTION(4, "UFS_MPHY_SDA"), + MTK_FUNCTION(5, "mbistwriteen_trigger"), + MTK_FUNCTION(6, "MD32_1_GPIO1"), + MTK_FUNCTION(7, "SCP_SDA2") + ), + MTK_PIN( + 130, "GPIO130", + MTK_EINT_FUNCTION(0, 130), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO130"), + MTK_FUNCTION(1, "IDDIG_1P"), + MTK_FUNCTION(2, "SPINOR_IO2"), + MTK_FUNCTION(3, "SNFI_WP"), + MTK_FUNCTION(4, "VPU_UDI_NTRST") + ), + MTK_PIN( + 131, "GPIO131", + MTK_EINT_FUNCTION(0, 131), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO131"), + MTK_FUNCTION(1, "USB_DRVVBUS_1P"), + MTK_FUNCTION(2, "SPINOR_IO3"), + MTK_FUNCTION(3, "SNFI_HOLD"), + MTK_FUNCTION(4, "MD32_1_JTAG_TRST"), + MTK_FUNCTION(5, "SCP_JTAG0_TRSTN"), + MTK_FUNCTION(6, "APU_JTAG_TRST") + ), + MTK_PIN( + 132, "GPIO132", + MTK_EINT_FUNCTION(0, 132), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO132"), + MTK_FUNCTION(1, "SPIM0_CSB"), + MTK_FUNCTION(2, "SCP_SPI0_CS"), + MTK_FUNCTION(3, "SPIS0_CSB"), + MTK_FUNCTION(4, "VPU_UDI_TMS"), + MTK_FUNCTION(6, "I2SO5_D0") + ), + MTK_PIN( + 133, "GPIO133", + MTK_EINT_FUNCTION(0, 133), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO133"), + MTK_FUNCTION(1, "SPIM0_CLK"), + MTK_FUNCTION(2, "SCP_SPI0_CK"), + MTK_FUNCTION(3, "SPIS0_CLK"), + MTK_FUNCTION(4, "VPU_UDI_TCK"), + MTK_FUNCTION(6, "I2SO5_BCK") + ), + MTK_PIN( + 134, "GPIO134", + MTK_EINT_FUNCTION(0, 134), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO134"), + MTK_FUNCTION(1, "SPIM0_MO"), + MTK_FUNCTION(2, "SCP_SPI0_MO"), + MTK_FUNCTION(3, "SPIS0_SI"), + MTK_FUNCTION(4, "VPU_UDI_TDO"), + MTK_FUNCTION(6, "I2SO5_WS") + ), + MTK_PIN( + 135, "GPIO135", + MTK_EINT_FUNCTION(0, 135), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO135"), + MTK_FUNCTION(1, "SPIM0_MI"), + MTK_FUNCTION(2, "SCP_SPI0_MI"), + MTK_FUNCTION(3, "SPIS0_SO"), + MTK_FUNCTION(4, "VPU_UDI_TDI"), + MTK_FUNCTION(6, "I2SO5_MCK") + ), + MTK_PIN( + 136, "GPIO136", + MTK_EINT_FUNCTION(0, 136), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO136"), + MTK_FUNCTION(1, "SPIM1_CSB"), + MTK_FUNCTION(2, "SCP_SPI1_A_CS"), + MTK_FUNCTION(3, "SPIS1_CSB"), + MTK_FUNCTION(4, "MD32_1_JTAG_TMS"), + MTK_FUNCTION(5, "SCP_JTAG0_TMS"), + MTK_FUNCTION(6, "APU_JTAG_TMS"), + MTK_FUNCTION(7, "DBG_MON_A15") + ), + MTK_PIN( + 137, "GPIO137", + MTK_EINT_FUNCTION(0, 137), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO137"), + MTK_FUNCTION(1, "SPIM1_CLK"), + MTK_FUNCTION(2, "SCP_SPI1_A_CK"), + MTK_FUNCTION(3, "SPIS1_CLK"), + MTK_FUNCTION(4, "MD32_1_JTAG_TCK"), + MTK_FUNCTION(5, "SCP_JTAG0_TCK"), + MTK_FUNCTION(6, "APU_JTAG_TCK"), + MTK_FUNCTION(7, "DBG_MON_A14") + ), + MTK_PIN( + 138, "GPIO138", + MTK_EINT_FUNCTION(0, 138), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO138"), + MTK_FUNCTION(1, "SPIM1_MO"), + MTK_FUNCTION(2, "SCP_SPI1_A_MO"), + MTK_FUNCTION(3, "SPIS1_SI"), + MTK_FUNCTION(4, "MD32_1_JTAG_TDO"), + MTK_FUNCTION(5, "SCP_JTAG0_TDO"), + MTK_FUNCTION(6, "APU_JTAG_TDO"), + MTK_FUNCTION(7, "DBG_MON_A16") + ), + MTK_PIN( + 139, "GPIO139", + MTK_EINT_FUNCTION(0, 139), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO139"), + MTK_FUNCTION(1, "SPIM1_MI"), + MTK_FUNCTION(2, "SCP_SPI1_A_MI"), + MTK_FUNCTION(3, "SPIS1_SO"), + MTK_FUNCTION(4, "MD32_1_JTAG_TDI"), + MTK_FUNCTION(5, "SCP_JTAG0_TDI"), + MTK_FUNCTION(6, "APU_JTAG_TDI"), + MTK_FUNCTION(7, "DBG_MON_A17") + ), + MTK_PIN( + 140, "GPIO140", + MTK_EINT_FUNCTION(0, 140), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO140"), + MTK_FUNCTION(1, "SPIM2_CSB"), + MTK_FUNCTION(2, "SPINOR_CS"), + MTK_FUNCTION(3, "SNFI_CS"), + MTK_FUNCTION(4, "DMIC3_DAT"), + MTK_FUNCTION(7, "DBG_MON_A11") + ), + MTK_PIN( + 141, "GPIO141", + MTK_EINT_FUNCTION(0, 141), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO141"), + MTK_FUNCTION(1, "SPIM2_CLK"), + MTK_FUNCTION(2, "SPINOR_CK"), + MTK_FUNCTION(3, "SNFI_CLK"), + MTK_FUNCTION(4, "DMIC3_CLK"), + MTK_FUNCTION(7, "DBG_MON_A10") + ), + MTK_PIN( + 142, "GPIO142", + MTK_EINT_FUNCTION(0, 142), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO142"), + MTK_FUNCTION(1, "SPIM2_MO"), + MTK_FUNCTION(2, "SPINOR_IO0"), + MTK_FUNCTION(3, "SNFI_MOSI"), + MTK_FUNCTION(4, "DMIC4_DAT"), + MTK_FUNCTION(7, "DBG_MON_A12") + ), + MTK_PIN( + 143, "GPIO143", + MTK_EINT_FUNCTION(0, 143), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO143"), + MTK_FUNCTION(1, "SPIM2_MI"), + MTK_FUNCTION(2, "SPINOR_IO1"), + MTK_FUNCTION(3, "SNFI_MISO"), + MTK_FUNCTION(4, "DMIC4_CLK"), + MTK_FUNCTION(7, "DBG_MON_A13") + ), + MTK_PIN( + 144, "GPIO144", + MTK_EINT_FUNCTION(0, 144), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 145, "GPIO145", + MTK_EINT_FUNCTION(0, 145), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 146, "GPIO146", + MTK_EINT_FUNCTION(0, 146), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 147, "GPIO147", + MTK_EINT_FUNCTION(0, 147), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 148, "GPIO148", + MTK_EINT_FUNCTION(0, 148), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 149, "GPIO149", + MTK_EINT_FUNCTION(0, 149), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 150, "GPIO150", + MTK_EINT_FUNCTION(0, 150), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 151, "GPIO151", + MTK_EINT_FUNCTION(0, 151), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 152, "GPIO152", + MTK_EINT_FUNCTION(0, 152), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 153, "GPIO153", + MTK_EINT_FUNCTION(0, 153), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 154, "GPIO154", + MTK_EINT_FUNCTION(0, 154), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 155, "GPIO155", + MTK_EINT_FUNCTION(0, 155), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 156, "GPIO156", + MTK_EINT_FUNCTION(0, 216), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 157, "GPIO157", + MTK_EINT_FUNCTION(0, 217), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 158, "GPIO158", + MTK_EINT_FUNCTION(0, 218), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 159, "GPIO159", + MTK_EINT_FUNCTION(0, 219), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 160, "GPIO160", + MTK_EINT_FUNCTION(0, 220), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 161, "GPIO161", + MTK_EINT_FUNCTION(0, 221), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 162, "GPIO162", + MTK_EINT_FUNCTION(0, 222), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 163, "GPIO163", + MTK_EINT_FUNCTION(0, 223), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 164, "GPIO164", + MTK_EINT_FUNCTION(0, 224), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ) +}; + +#endif /* __PINCTRL_MTK_MT8195_H */ -- cgit v1.2.3 From ea9d2ed46520a3fb0b865143cc824aea27deb8fa Mon Sep 17 00:00:00 2001 From: Zhiyong Tao Date: Tue, 13 Apr 2021 13:57:01 +0800 Subject: pinctrl: add drive for I2C related pins on MT8195 This patch provides the advanced drive raw data setting version for I2C used pins on MT8195. Signed-off-by: Zhiyong Tao Acked-by: Sean Wang Link: https://lore.kernel.org/r/20210413055702.27535-4-zhiyong.tao@mediatek.com Signed-off-by: Linus Walleij --- drivers/pinctrl/mediatek/pinctrl-mt8195.c | 22 ++++++++++++++++++++++ drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 14 ++++++++++++++ drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 5 +++++ 3 files changed, 41 insertions(+) diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8195.c b/drivers/pinctrl/mediatek/pinctrl-mt8195.c index 063f164d7c9b..a7500e18bb1d 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt8195.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt8195.c @@ -760,6 +760,25 @@ static const struct mtk_pin_field_calc mt8195_pin_drv_range[] = { PIN_FIELD_BASE(143, 143, 1, 0x020, 0x10, 24, 3), }; +static const struct mtk_pin_field_calc mt8195_pin_drv_adv_range[] = { + PIN_FIELD_BASE(8, 8, 4, 0x020, 0x10, 15, 3), + PIN_FIELD_BASE(9, 9, 4, 0x020, 0x10, 0, 3), + PIN_FIELD_BASE(10, 10, 4, 0x020, 0x10, 18, 3), + PIN_FIELD_BASE(11, 11, 4, 0x020, 0x10, 3, 3), + PIN_FIELD_BASE(12, 12, 4, 0x020, 0x10, 21, 3), + PIN_FIELD_BASE(13, 13, 4, 0x020, 0x10, 6, 3), + PIN_FIELD_BASE(14, 14, 4, 0x020, 0x10, 24, 3), + PIN_FIELD_BASE(15, 15, 4, 0x020, 0x10, 9, 3), + PIN_FIELD_BASE(16, 16, 4, 0x020, 0x10, 27, 3), + PIN_FIELD_BASE(17, 17, 4, 0x020, 0x10, 12, 3), + PIN_FIELD_BASE(29, 29, 2, 0x020, 0x10, 0, 3), + PIN_FIELD_BASE(30, 30, 2, 0x020, 0x10, 3, 3), + PIN_FIELD_BASE(34, 34, 1, 0x040, 0x10, 0, 3), + PIN_FIELD_BASE(35, 35, 1, 0x040, 0x10, 3, 3), + PIN_FIELD_BASE(44, 44, 1, 0x040, 0x10, 6, 3), + PIN_FIELD_BASE(45, 45, 1, 0x040, 0x10, 9, 3), +}; + static const struct mtk_pin_reg_calc mt8195_reg_cals[PINCTRL_PIN_REG_MAX] = { [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt8195_pin_mode_range), [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt8195_pin_dir_range), @@ -773,6 +792,7 @@ static const struct mtk_pin_reg_calc mt8195_reg_cals[PINCTRL_PIN_REG_MAX] = { [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt8195_pin_pupd_range), [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt8195_pin_r0_range), [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt8195_pin_r1_range), + [PINCTRL_PIN_REG_DRV_ADV] = MTK_RANGE(mt8195_pin_drv_adv_range), }; static const char * const mt8195_pinctrl_register_base_names[] = { @@ -801,6 +821,8 @@ static const struct mtk_pin_soc mt8195_data = { .bias_get_combo = mtk_pinconf_bias_get_combo, .drive_set = mtk_pinconf_drive_set_rev1, .drive_get = mtk_pinconf_drive_get_rev1, + .adv_drive_get = mtk_pinconf_adv_drive_get_raw, + .adv_drive_set = mtk_pinconf_adv_drive_set_raw, }; static const struct of_device_id mt8195_pinctrl_of_match[] = { diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c index fcf7c3eeee4a..c068a2259741 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -1031,6 +1031,20 @@ int mtk_pinconf_adv_drive_get(struct mtk_pinctrl *hw, } EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_get); +int mtk_pinconf_adv_drive_set_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 arg) +{ + return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV_ADV, arg); +} +EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_set_raw); + +int mtk_pinconf_adv_drive_get_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 *val) +{ + return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV_ADV, val); +} +EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_get_raw); + MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Sean Wang "); MODULE_DESCRIPTION("Pin configuration library module for mediatek SoCs"); diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h index 65eac708a3b3..be35443d81f8 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h @@ -66,6 +66,7 @@ enum { PINCTRL_PIN_REG_DRV_EN, PINCTRL_PIN_REG_DRV_E0, PINCTRL_PIN_REG_DRV_E1, + PINCTRL_PIN_REG_DRV_ADV, PINCTRL_PIN_REG_MAX, }; @@ -316,6 +317,10 @@ int mtk_pinconf_adv_drive_set(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, u32 arg); int mtk_pinconf_adv_drive_get(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, u32 *val); +int mtk_pinconf_adv_drive_set_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 arg); +int mtk_pinconf_adv_drive_get_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 *val); bool mtk_is_virt_gpio(struct mtk_pinctrl *hw, unsigned int gpio_n); #endif /* __PINCTRL_MTK_COMMON_V2_H */ -- cgit v1.2.3 From 56ab29ec6ff6c1441fda6ddcca0193be32d395b7 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Mon, 19 Apr 2021 17:34:49 +0800 Subject: pinctrl: mediatek: use spin lock in mtk_rmw Commit 42a46434e9b1 ("pinctrl: add lock in mtk_rmw function.") uses mutex lock in mtk_rmw. However the function is possible called from atomic context. For example call trace: mutex_lock+0x28/0x64 mtk_rmw+0x38/0x80 [snip] max98357a_daiops_trigger+0x8c/0x9c soc_pcm_trigger+0x5c/0x10c The max98357a_daiops_trigger() could run in either atomic or non-atomic context. As a result, dmesg shows some similar messages: "BUG: sleeping function called from invalid context at kernel/locking/mutex.c:254". Uses spin lock in mtk_rmw instead. Fixes: 42a46434e9b1 ("pinctrl: add lock in mtk_rmw function.") Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20210419093449.3125704-1-tzungbi@google.com Signed-off-by: Linus Walleij --- drivers/pinctrl/mediatek/pinctrl-moore.c | 2 +- drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 5 +++-- drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 2 +- drivers/pinctrl/mediatek/pinctrl-paris.c | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/mediatek/pinctrl-moore.c b/drivers/pinctrl/mediatek/pinctrl-moore.c index f77921957f15..3a4a23c40a71 100644 --- a/drivers/pinctrl/mediatek/pinctrl-moore.c +++ b/drivers/pinctrl/mediatek/pinctrl-moore.c @@ -619,7 +619,7 @@ int mtk_moore_pinctrl_probe(struct platform_device *pdev, hw->nbase = hw->soc->nbase_names; - mutex_init(&hw->lock); + spin_lock_init(&hw->lock); /* Copy from internal struct mtk_pin_desc to register to the core */ pins = devm_kmalloc_array(&pdev->dev, hw->soc->npins, sizeof(*pins), diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c index c068a2259741..5b3b048725cc 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -57,15 +57,16 @@ static u32 mtk_r32(struct mtk_pinctrl *pctl, u8 i, u32 reg) void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set) { u32 val; + unsigned long flags; - mutex_lock(&pctl->lock); + spin_lock_irqsave(&pctl->lock, flags); val = mtk_r32(pctl, i, reg); val &= ~mask; val |= set; mtk_w32(pctl, i, reg, val); - mutex_unlock(&pctl->lock); + spin_unlock_irqrestore(&pctl->lock, flags); } static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw, diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h index be35443d81f8..a6f1bdb2083b 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h @@ -253,7 +253,7 @@ struct mtk_pinctrl { struct mtk_pinctrl_group *groups; const char **grp_names; /* lock pin's register resource to avoid multiple threads issue*/ - struct mutex lock; + spinlock_t lock; }; void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set); diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index 48e823f6d293..85db2e4377f0 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -970,7 +970,7 @@ int mtk_paris_pinctrl_probe(struct platform_device *pdev, hw->nbase = hw->soc->nbase_names; - mutex_init(&hw->lock); + spin_lock_init(&hw->lock); err = mtk_pctrl_build_state(pdev); if (err) { -- cgit v1.2.3 From 11f054c114f261ae04fc0b2ad9c1d4e1becd8b14 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 15 Apr 2021 15:35:21 +0300 Subject: pinctrl: core: Fix kernel doc string for pin_get_name() The kernel doc string mistakenly advertises the pin_get_name_from_id(). Fix it, otherwise kernel doc validator is not happy: .../core.c:168: warning: expecting prototype for pin_get_name_from_id(). Prototype was for pin_get_name() instead Fixes: dcb5dbc305b9 ("pinctrl: show pin name for pingroups in sysfs") Cc: Dong Aisheng Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210415123521.86894-1-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 2252db9bbc3a..3b40402f0f4a 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -160,7 +160,7 @@ int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name) } /** - * pin_get_name_from_id() - look up a pin name from a pin id + * pin_get_name() - look up a pin name from a pin id * @pctldev: the pin control device to lookup the pin on * @pin: pin number/id to look up */ -- cgit v1.2.3 From 1dccb5ec01231156b06420633e3eedef95b17eac Mon Sep 17 00:00:00 2001 From: Sai Krishna Potthuri Date: Thu, 15 Apr 2021 16:43:12 +0530 Subject: dt-bindings: pinctrl: Add binding for ZynqMP pinctrl driver Adding documentation and dt-bindings file which contains MIO pin configuration defines for Xilinx ZynqMP pinctrl driver. Signed-off-by: Sai Krishna Potthuri Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/1618485193-5403-3-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com Signed-off-by: Linus Walleij --- .../bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml | 336 +++++++++++++++++++++ include/dt-bindings/pinctrl/pinctrl-zynqmp.h | 19 ++ 2 files changed, 355 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml create mode 100644 include/dt-bindings/pinctrl/pinctrl-zynqmp.h diff --git a/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml new file mode 100644 index 000000000000..8ef0d07d35fe --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml @@ -0,0 +1,336 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/xlnx,zynqmp-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx ZynqMP Pinctrl + +maintainers: + - Sai Krishna Potthuri + - Rajan Vaja + +description: | + Please refer to pinctrl-bindings.txt in this directory for details of the + common pinctrl bindings used by client devices, including the meaning of the + phrase "pin configuration node". + + ZynqMP's pin configuration nodes act as a container for an arbitrary number of + subnodes. Each of these subnodes represents some desired configuration for a + pin, a group, or a list of pins or groups. This configuration can include the + mux function to select on those pin(s)/group(s), and various pin configuration + parameters, such as pull-up, slew rate, etc. + + Each configuration node can consist of multiple nodes describing the pinmux and + pinconf options. Those nodes can be pinmux nodes or pinconf nodes. + + The name of each subnode is not important; all subnodes should be enumerated + and processed purely based on their content. + +properties: + compatible: + const: xlnx,zynqmp-pinctrl + +patternProperties: + '^(.*-)?(default|gpio)$': + type: object + patternProperties: + '^mux': + type: object + description: + Pinctrl node's client devices use subnodes for pin muxes, + which in turn use below standard properties. + $ref: pinmux-node.yaml# + + properties: + groups: + description: + List of groups to select (either this or "pins" must be + specified), available groups for this subnode. + items: + enum: [ethernet0_0_grp, ethernet1_0_grp, ethernet2_0_grp, + ethernet3_0_grp, gemtsu0_0_grp, gemtsu0_1_grp, + gemtsu0_2_grp, mdio0_0_grp, mdio1_0_grp, + mdio1_1_grp, mdio2_0_grp, mdio3_0_grp, + qspi0_0_grp, qspi_ss_0_grp, qspi_fbclk_0_grp, + spi0_0_grp, spi0_ss_0_grp, spi0_ss_1_grp, + spi0_ss_2_grp, spi0_1_grp, spi0_ss_3_grp, + spi0_ss_4_grp, spi0_ss_5_grp, spi0_2_grp, + spi0_ss_6_grp, spi0_ss_7_grp, spi0_ss_8_grp, + spi0_3_grp, spi0_ss_9_grp, spi0_ss_10_grp, + spi0_ss_11_grp, spi0_4_grp, spi0_ss_12_grp, + spi0_ss_13_grp, spi0_ss_14_grp, spi0_5_grp, + spi0_ss_15_grp, spi0_ss_16_grp, spi0_ss_17_grp, + spi1_0_grp, spi1_ss_0_grp, spi1_ss_1_grp, + spi1_ss_2_grp, spi1_1_grp, spi1_ss_3_grp, + spi1_ss_4_grp, spi1_ss_5_grp, spi1_2_grp, + spi1_ss_6_grp, spi1_ss_7_grp, spi1_ss_8_grp, + spi1_3_grp, spi1_ss_9_grp, spi1_ss_10_grp, + spi1_ss_11_grp, spi1_4_grp, spi1_ss_12_grp, + spi1_ss_13_grp, spi1_ss_14_grp, spi1_5_grp, + spi1_ss_15_grp, spi1_ss_16_grp, spi1_ss_17_grp, + sdio0_0_grp, sdio0_1_grp, sdio0_2_grp, + sdio0_3_grp, sdio0_4_grp, sdio0_5_grp, + sdio0_6_grp, sdio0_7_grp, sdio0_8_grp, + sdio0_9_grp, sdio0_10_grp, sdio0_11_grp, + sdio0_12_grp, sdio0_13_grp, sdio0_14_grp, + sdio0_15_grp, sdio0_16_grp, sdio0_17_grp, + sdio0_18_grp, sdio0_19_grp, sdio0_20_grp, + sdio0_21_grp, sdio0_22_grp, sdio0_23_grp, + sdio0_24_grp, sdio0_25_grp, sdio0_26_grp, + sdio0_27_grp, sdio0_28_grp, sdio0_29_grp, + sdio0_30_grp, sdio0_31_grp, sdio0_32_grp, + sdio0_pc_0_grp, sdio0_cd_0_grp, sdio0_wp_0_grp, + sdio0_pc_1_grp, sdio0_cd_1_grp, sdio0_wp_1_grp, + sdio0_pc_2_grp, sdio0_cd_2_grp, sdio0_wp_2_grp, + sdio1_0_grp, sdio1_1_grp, sdio1_2_grp, + sdio1_3_grp, sdio1_4_grp, sdio1_5_grp, + sdio1_6_grp, sdio1_7_grp, sdio1_8_grp, + sdio1_9_grp, sdio1_10_grp, sdio1_11_grp, + sdio1_12_grp, sdio1_13_grp, sdio1_14_grp, + sdio1_15_grp, sdio1_pc_0_grp, sdio1_cd_0_grp, + sdio1_wp_0_grp, sdio1_pc_1_grp, sdio1_cd_1_grp, + sdio1_wp_1_grp, nand0_0_grp, nand0_ce_0_grp, + nand0_rb_0_grp, nand0_dqs_0_grp, nand0_ce_1_grp, + nand0_rb_1_grp, nand0_dqs_1_grp, can0_0_grp, + can0_1_grp, can0_2_grp, can0_3_grp, + can0_4_grp, can0_5_grp, can0_6_grp, + can0_7_grp, can0_8_grp, can0_9_grp, + can0_10_grp, can0_11_grp, can0_12_grp, + can0_13_grp, can0_14_grp, can0_15_grp, + can0_16_grp, can0_17_grp, can0_18_grp, + can1_0_grp, can1_1_grp, can1_2_grp, + can1_3_grp, can1_4_grp, can1_5_grp, + can1_6_grp, can1_7_grp, can1_8_grp, + can1_9_grp, can1_10_grp, can1_11_grp, + can1_12_grp, can1_13_grp, can1_14_grp, + can1_15_grp, can1_16_grp, can1_17_grp, + can1_18_grp, can1_19_grp, uart0_0_grp, + uart0_1_grp, uart0_2_grp, uart0_3_grp, + uart0_4_grp, uart0_5_grp, uart0_6_grp, + uart0_7_grp, uart0_8_grp, uart0_9_grp, + uart0_10_grp, uart0_11_grp, uart0_12_grp, + uart0_13_grp, uart0_14_grp, uart0_15_grp, + uart0_16_grp, uart0_17_grp, uart0_18_grp, + uart1_0_grp, uart1_1_grp, uart1_2_grp, + uart1_3_grp, uart1_4_grp, uart1_5_grp, + uart1_6_grp, uart1_7_grp, uart1_8_grp, + uart1_9_grp, uart1_10_grp, uart1_11_grp, + uart1_12_grp, uart1_13_grp, uart1_14_grp, + uart1_15_grp, uart1_16_grp, uart1_17_grp, + uart1_18_grp, i2c0_0_grp, i2c0_1_grp, + i2c0_2_grp, i2c0_3_grp, i2c0_4_grp, + i2c0_5_grp, i2c0_6_grp, i2c0_7_grp, + i2c0_8_grp, i2c0_9_grp, i2c0_10_grp, + i2c0_11_grp, i2c0_12_grp, i2c0_13_grp, + i2c0_14_grp, i2c0_15_grp, i2c0_16_grp, + i2c0_17_grp, i2c0_18_grp, i2c1_0_grp, + i2c1_1_grp, i2c1_2_grp, i2c1_3_grp, + i2c1_4_grp, i2c1_5_grp, i2c1_6_grp, + i2c1_7_grp, i2c1_8_grp, i2c1_9_grp, + i2c1_10_grp, i2c1_11_grp, i2c1_12_grp, + i2c1_13_grp, i2c1_14_grp, i2c1_15_grp, + i2c1_16_grp, i2c1_17_grp, i2c1_18_grp, + i2c1_19_grp, ttc0_clk_0_grp, ttc0_wav_0_grp, + ttc0_clk_1_grp, ttc0_wav_1_grp, ttc0_clk_2_grp, + ttc0_wav_2_grp, ttc0_clk_3_grp, ttc0_wav_3_grp, + ttc0_clk_4_grp, ttc0_wav_4_grp, ttc0_clk_5_grp, + ttc0_wav_5_grp, ttc0_clk_6_grp, ttc0_wav_6_grp, + ttc0_clk_7_grp, ttc0_wav_7_grp, ttc0_clk_8_grp, + ttc0_wav_8_grp, ttc1_clk_0_grp, ttc1_wav_0_grp, + ttc1_clk_1_grp, ttc1_wav_1_grp, ttc1_clk_2_grp, + ttc1_wav_2_grp, ttc1_clk_3_grp, ttc1_wav_3_grp, + ttc1_clk_4_grp, ttc1_wav_4_grp, ttc1_clk_5_grp, + ttc1_wav_5_grp, ttc1_clk_6_grp, ttc1_wav_6_grp, + ttc1_clk_7_grp, ttc1_wav_7_grp, ttc1_clk_8_grp, + ttc1_wav_8_grp, ttc2_clk_0_grp, ttc2_wav_0_grp, + ttc2_clk_1_grp, ttc2_wav_1_grp, ttc2_clk_2_grp, + ttc2_wav_2_grp, ttc2_clk_3_grp, ttc2_wav_3_grp, + ttc2_clk_4_grp, ttc2_wav_4_grp, ttc2_clk_5_grp, + ttc2_wav_5_grp, ttc2_clk_6_grp, ttc2_wav_6_grp, + ttc2_clk_7_grp, ttc2_wav_7_grp, ttc2_clk_8_grp, + ttc2_wav_8_grp, ttc3_clk_0_grp, ttc3_wav_0_grp, + ttc3_clk_1_grp, ttc3_wav_1_grp, ttc3_clk_2_grp, + ttc3_wav_2_grp, ttc3_clk_3_grp, ttc3_wav_3_grp, + ttc3_clk_4_grp, ttc3_wav_4_grp, ttc3_clk_5_grp, + ttc3_wav_5_grp, ttc3_clk_6_grp, ttc3_wav_6_grp, + ttc3_clk_7_grp, ttc3_wav_7_grp, ttc3_clk_8_grp, + ttc3_wav_8_grp, swdt0_clk_0_grp, swdt0_rst_0_grp, + swdt0_clk_1_grp, swdt0_rst_1_grp, swdt0_clk_2_grp, + swdt0_rst_2_grp, swdt0_clk_3_grp, swdt0_rst_3_grp, + swdt0_clk_4_grp, swdt0_rst_4_grp, swdt0_clk_5_grp, + swdt0_rst_5_grp, swdt0_clk_6_grp, swdt0_rst_6_grp, + swdt0_clk_7_grp, swdt0_rst_7_grp, swdt0_clk_8_grp, + swdt0_rst_8_grp, swdt0_clk_9_grp, swdt0_rst_9_grp, + swdt0_clk_10_grp, swdt0_rst_10_grp, swdt0_clk_11_grp, + swdt0_rst_11_grp, swdt0_clk_12_grp, swdt0_rst_12_grp, + swdt1_clk_0_grp, swdt1_rst_0_grp, swdt1_clk_1_grp, + swdt1_rst_1_grp, swdt1_clk_2_grp, swdt1_rst_2_grp, + swdt1_clk_3_grp, swdt1_rst_3_grp, swdt1_clk_4_grp, + swdt1_rst_4_grp, swdt1_clk_5_grp, swdt1_rst_5_grp, + swdt1_clk_6_grp, swdt1_rst_6_grp, swdt1_clk_7_grp, + swdt1_rst_7_grp, swdt1_clk_8_grp, swdt1_rst_8_grp, + swdt1_clk_9_grp, swdt1_rst_9_grp, swdt1_clk_10_grp, + swdt1_rst_10_grp, swdt1_clk_11_grp, swdt1_rst_11_grp, + swdt1_clk_12_grp, swdt1_rst_12_grp, gpio0_0_grp, + gpio0_1_grp, gpio0_2_grp, gpio0_3_grp, + gpio0_4_grp, gpio0_5_grp, gpio0_6_grp, + gpio0_7_grp, gpio0_8_grp, gpio0_9_grp, + gpio0_10_grp, gpio0_11_grp, gpio0_12_grp, + gpio0_13_grp, gpio0_14_grp, gpio0_15_grp, + gpio0_16_grp, gpio0_17_grp, gpio0_18_grp, + gpio0_19_grp, gpio0_20_grp, gpio0_21_grp, + gpio0_22_grp, gpio0_23_grp, gpio0_24_grp, + gpio0_25_grp, gpio0_26_grp, gpio0_27_grp, + gpio0_28_grp, gpio0_29_grp, gpio0_30_grp, + gpio0_31_grp, gpio0_32_grp, gpio0_33_grp, + gpio0_34_grp, gpio0_35_grp, gpio0_36_grp, + gpio0_37_grp, gpio0_38_grp, gpio0_39_grp, + gpio0_40_grp, gpio0_41_grp, gpio0_42_grp, + gpio0_43_grp, gpio0_44_grp, gpio0_45_grp, + gpio0_46_grp, gpio0_47_grp, gpio0_48_grp, + gpio0_49_grp, gpio0_50_grp, gpio0_51_grp, + gpio0_52_grp, gpio0_53_grp, gpio0_54_grp, + gpio0_55_grp, gpio0_56_grp, gpio0_57_grp, + gpio0_58_grp, gpio0_59_grp, gpio0_60_grp, + gpio0_61_grp, gpio0_62_grp, gpio0_63_grp, + gpio0_64_grp, gpio0_65_grp, gpio0_66_grp, + gpio0_67_grp, gpio0_68_grp, gpio0_69_grp, + gpio0_70_grp, gpio0_71_grp, gpio0_72_grp, + gpio0_73_grp, gpio0_74_grp, gpio0_75_grp, + gpio0_76_grp, gpio0_77_grp, usb0_0_grp, + usb1_0_grp, pmu0_0_grp, pmu0_1_grp, + pmu0_2_grp, pmu0_3_grp, pmu0_4_grp, + pmu0_5_grp, pmu0_6_grp, pmu0_7_grp, + pmu0_8_grp, pmu0_9_grp, pmu0_10_grp, + pmu0_11_grp, pcie0_0_grp, pcie0_1_grp, + pcie0_2_grp, pcie0_3_grp, pcie0_4_grp, + pcie0_5_grp, pcie0_6_grp, pcie0_7_grp, + csu0_0_grp, csu0_1_grp, csu0_2_grp, + csu0_3_grp, csu0_4_grp, csu0_5_grp, + csu0_6_grp, csu0_7_grp, csu0_8_grp, + csu0_9_grp, csu0_10_grp, csu0_11_grp, + dpaux0_0_grp, dpaux0_1_grp, dpaux0_2_grp, + dpaux0_3_grp, pjtag0_0_grp, pjtag0_1_grp, + pjtag0_2_grp, pjtag0_3_grp, pjtag0_4_grp, + pjtag0_5_grp, trace0_0_grp, trace0_clk_0_grp, + trace0_1_grp, trace0_clk_1_grp, trace0_2_grp, + trace0_clk_2_grp, testscan0_0_grp] + maxItems: 78 + + function: + description: + Specify the alternative function to be configured for the + given pin groups. + enum: [ethernet0, ethernet1, ethernet2, ethernet3, gemtsu0, usb0, usb1, mdio0, + mdio1, mdio2, mdio3, qspi0, qspi_fbclk, qspi_ss, spi0, spi1, spi0_ss, + spi1_ss, sdio0, sdio0_pc, sdio0_wp, sdio0_cd, sdio1, sdio1_pc, sdio1_wp, + sdio1_cd, nand0, nand0_ce, nand0_rb, nand0_dqs, can0, can1, uart0, uart1, + i2c0, i2c1, ttc0_clk, ttc0_wav, ttc1_clk, ttc1_wav, ttc2_clk, ttc2_wav, + ttc3_clk, ttc3_wav, swdt0_clk, swdt0_rst, swdt1_clk, swdt1_rst, gpio0, pmu0, + pcie0, csu0, dpaux0, pjtag0, trace0, trace0_clk, testscan0] + + required: + - groups + - function + + additionalProperties: false + + '^conf': + type: object + description: + Pinctrl node's client devices use subnodes for pin configurations, + which in turn use the standard properties below. + $ref: pincfg-node.yaml# + + properties: + groups: + description: + List of pin groups as mentioned above. + + pins: + description: + List of pin names to select in this subnode. + items: + pattern: '^MIO([0-9]|[1-6][0-9]|7[0-7])$' + maxItems: 78 + + bias-pull-up: true + + bias-pull-down: true + + bias-disable: true + + input-schmitt-enable: true + + input-schmitt-disable: true + + bias-high-impedance: true + + low-power-enable: true + + low-power-disable: true + + slew-rate: + enum: [0, 1] + + drive-strength: + description: + Selects the drive strength for MIO pins, in mA. + enum: [2, 4, 8, 12] + + power-source: + enum: [0, 1] + + oneOf: + - required: [ groups ] + - required: [ pins ] + + additionalProperties: false + + additionalProperties: false + +required: + - compatible + +additionalProperties: false + +examples: + - | + #include + zynqmp_firmware: zynqmp-firmware { + pinctrl0: pinctrl { + compatible = "xlnx,zynqmp-pinctrl"; + + pinctrl_uart1_default: uart1-default { + mux { + groups = "uart0_4_grp", "uart0_5_grp"; + function = "uart0"; + }; + + conf { + groups = "uart0_4_grp"; + slew-rate = ; + power-source = ; + }; + + conf-rx { + pins = "MIO18"; + bias-pull-up; + }; + + conf-tx { + pins = "MIO19"; + bias-disable; + input-schmitt-disable; + }; + }; + }; + }; + + uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1_default>; + }; + +... diff --git a/include/dt-bindings/pinctrl/pinctrl-zynqmp.h b/include/dt-bindings/pinctrl/pinctrl-zynqmp.h new file mode 100644 index 000000000000..cdb215734bdf --- /dev/null +++ b/include/dt-bindings/pinctrl/pinctrl-zynqmp.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * MIO pin configuration defines for Xilinx ZynqMP + * + * Copyright (C) 2020 Xilinx, Inc. + */ + +#ifndef _DT_BINDINGS_PINCTRL_ZYNQMP_H +#define _DT_BINDINGS_PINCTRL_ZYNQMP_H + +/* Bit value for different voltage levels */ +#define IO_STANDARD_LVCMOS33 0 +#define IO_STANDARD_LVCMOS18 1 + +/* Bit values for Slew Rates */ +#define SLEW_RATE_FAST 0 +#define SLEW_RATE_SLOW 1 + +#endif /* _DT_BINDINGS_PINCTRL_ZYNQMP_H */ -- cgit v1.2.3 From 1de15e99a242a66ef4f803fe1ad357f86b3a75f8 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 12 Apr 2021 17:07:39 +0300 Subject: pinctrl: Keep enum pin_config_param ordered by name It seems the ordering is by name. Keep it that way. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210412140741.39946-1-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- include/linux/pinctrl/pinconf-generic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h index 6aeb711f7cd1..188db8d84162 100644 --- a/include/linux/pinctrl/pinconf-generic.h +++ b/include/linux/pinctrl/pinconf-generic.h @@ -90,6 +90,7 @@ struct pinctrl_map; * value on the line. Use argument 1 to indicate high level, argument 0 to * indicate low level. (Please see Documentation/driver-api/pinctl.rst, * section "GPIO mode pitfalls" for a discussion around this parameter.) + * @PIN_CONFIG_PERSIST_STATE: retain pin state across sleep or controller reset * @PIN_CONFIG_POWER_SOURCE: if the pin can select between different power * supplies, the argument to this parameter (on a custom format) tells * the driver which alternative power source to use. @@ -101,7 +102,6 @@ struct pinctrl_map; * or latch delay (on outputs) this parameter (in a custom format) * specifies the clock skew or latch delay. It typically controls how * many double inverters are put in front of the line. - * @PIN_CONFIG_PERSIST_STATE: retain pin state across sleep or controller reset * @PIN_CONFIG_END: this is the last enumerator for pin configurations, if * you need to pass in custom configurations to the pin controller, use * PIN_CONFIG_END+1 as the base offset. @@ -127,11 +127,11 @@ enum pin_config_param { PIN_CONFIG_LOW_POWER_MODE, PIN_CONFIG_OUTPUT_ENABLE, PIN_CONFIG_OUTPUT, + PIN_CONFIG_PERSIST_STATE, PIN_CONFIG_POWER_SOURCE, PIN_CONFIG_SLEEP_HARDWARE_STATE, PIN_CONFIG_SLEW_RATE, PIN_CONFIG_SKEW_DELAY, - PIN_CONFIG_PERSIST_STATE, PIN_CONFIG_END = 0x7F, PIN_CONFIG_MAX = 0xFF, }; -- cgit v1.2.3 From 31f9a421a1d01538776db37ec9c5419a3a49d650 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 12 Apr 2021 17:07:40 +0300 Subject: pinctrl: Introduce MODE group in enum pin_config_param Better to have a MODE group of settings to keep them together when ordered alphabetically. Hence, rename PIN_CONFIG_LOW_POWER_MODE to PIN_CONFIG_MODE_LOW_POWER. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210412140741.39946-2-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinconf-generic.c | 6 +++--- drivers/pinctrl/pinctrl-lpc18xx.c | 4 ++-- drivers/pinctrl/pinctrl-single.c | 6 +++--- drivers/pinctrl/pinctrl-zynq.c | 4 ++-- drivers/pinctrl/pxa/pinctrl-pxa2xx.c | 4 ++-- drivers/soc/tegra/pmc.c | 4 ++-- include/linux/pinctrl/pinconf-generic.h | 4 ++-- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c index 1e225d513988..22e8d4c4040e 100644 --- a/drivers/pinctrl/pinconf-generic.c +++ b/drivers/pinctrl/pinconf-generic.c @@ -43,7 +43,7 @@ static const struct pin_config_item conf_items[] = { PCONFDUMP(PIN_CONFIG_INPUT_ENABLE, "input enabled", NULL, false), PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL, false), PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_ENABLE, "input schmitt enabled", NULL, false), - PCONFDUMP(PIN_CONFIG_LOW_POWER_MODE, "pin low power", "mode", true), + PCONFDUMP(PIN_CONFIG_MODE_LOW_POWER, "pin low power", "mode", true), PCONFDUMP(PIN_CONFIG_OUTPUT_ENABLE, "output enabled", NULL, false), PCONFDUMP(PIN_CONFIG_OUTPUT, "pin output", "level", true), PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector", true), @@ -174,8 +174,8 @@ static const struct pinconf_generic_params dt_params[] = { { "input-schmitt", PIN_CONFIG_INPUT_SCHMITT, 0 }, { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 }, { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 }, - { "low-power-disable", PIN_CONFIG_LOW_POWER_MODE, 0 }, - { "low-power-enable", PIN_CONFIG_LOW_POWER_MODE, 1 }, + { "low-power-disable", PIN_CONFIG_MODE_LOW_POWER, 0 }, + { "low-power-enable", PIN_CONFIG_MODE_LOW_POWER, 1 }, { "output-disable", PIN_CONFIG_OUTPUT_ENABLE, 0 }, { "output-enable", PIN_CONFIG_OUTPUT_ENABLE, 1 }, { "output-high", PIN_CONFIG_OUTPUT, 1, }, diff --git a/drivers/pinctrl/pinctrl-lpc18xx.c b/drivers/pinctrl/pinctrl-lpc18xx.c index 7b2f885e68bd..ed9bf2c89998 100644 --- a/drivers/pinctrl/pinctrl-lpc18xx.c +++ b/drivers/pinctrl/pinctrl-lpc18xx.c @@ -646,7 +646,7 @@ static const struct pin_config_item lpc18xx_conf_items[ARRAY_SIZE(lpc18xx_params static int lpc18xx_pconf_get_usb1(enum pin_config_param param, int *arg, u32 reg) { switch (param) { - case PIN_CONFIG_LOW_POWER_MODE: + case PIN_CONFIG_MODE_LOW_POWER: if (reg & LPC18XX_SCU_USB1_EPWR) *arg = 0; else @@ -904,7 +904,7 @@ static int lpc18xx_pconf_set_usb1(struct pinctrl_dev *pctldev, u32 param_val, u32 *reg) { switch (param) { - case PIN_CONFIG_LOW_POWER_MODE: + case PIN_CONFIG_MODE_LOW_POWER: if (param_val) *reg &= ~LPC18XX_SCU_USB1_EPWR; else diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 39aac32ed09c..2c9c9835f375 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -533,7 +533,7 @@ static int pcs_pinconf_get(struct pinctrl_dev *pctldev, break; case PIN_CONFIG_DRIVE_STRENGTH: case PIN_CONFIG_SLEW_RATE: - case PIN_CONFIG_LOW_POWER_MODE: + case PIN_CONFIG_MODE_LOW_POWER: default: *config = data; break; @@ -571,7 +571,7 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, case PIN_CONFIG_INPUT_SCHMITT: case PIN_CONFIG_DRIVE_STRENGTH: case PIN_CONFIG_SLEW_RATE: - case PIN_CONFIG_LOW_POWER_MODE: + case PIN_CONFIG_MODE_LOW_POWER: shift = ffs(func->conf[i].mask) - 1; data &= ~func->conf[i].mask; data |= (arg << shift) & func->conf[i].mask; @@ -919,7 +919,7 @@ static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np, { "pinctrl-single,drive-strength", PIN_CONFIG_DRIVE_STRENGTH, }, { "pinctrl-single,slew-rate", PIN_CONFIG_SLEW_RATE, }, { "pinctrl-single,input-schmitt", PIN_CONFIG_INPUT_SCHMITT, }, - { "pinctrl-single,low-power-mode", PIN_CONFIG_LOW_POWER_MODE, }, + { "pinctrl-single,low-power-mode", PIN_CONFIG_MODE_LOW_POWER, }, }; static const struct pcs_conf_type prop4[] = { { "pinctrl-single,bias-pullup", PIN_CONFIG_BIAS_PULL_UP, }, diff --git a/drivers/pinctrl/pinctrl-zynq.c b/drivers/pinctrl/pinctrl-zynq.c index c6052a0e827a..5fb924a2eedd 100644 --- a/drivers/pinctrl/pinctrl-zynq.c +++ b/drivers/pinctrl/pinctrl-zynq.c @@ -1016,7 +1016,7 @@ static int zynq_pinconf_cfg_get(struct pinctrl_dev *pctldev, case PIN_CONFIG_SLEW_RATE: arg = !!(reg & ZYNQ_PINCONF_SPEED); break; - case PIN_CONFIG_LOW_POWER_MODE: + case PIN_CONFIG_MODE_LOW_POWER: { enum zynq_io_standards iostd = zynq_pinconf_iostd_get(reg); @@ -1087,7 +1087,7 @@ static int zynq_pinconf_cfg_set(struct pinctrl_dev *pctldev, reg &= ~ZYNQ_PINCONF_IOTYPE_MASK; reg |= arg << ZYNQ_PINCONF_IOTYPE_SHIFT; break; - case PIN_CONFIG_LOW_POWER_MODE: + case PIN_CONFIG_MODE_LOW_POWER: if (arg) reg |= ZYNQ_PINCONF_DISABLE_RECVR; else diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c index eab029a21643..d2568dab8c78 100644 --- a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c +++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c @@ -194,7 +194,7 @@ static int pxa2xx_pconf_group_get(struct pinctrl_dev *pctldev, spin_lock_irqsave(&pctl->lock, flags); val = readl_relaxed(pgsr) & BIT(pin % 32); - *config = val ? PIN_CONFIG_LOW_POWER_MODE : 0; + *config = val ? PIN_CONFIG_MODE_LOW_POWER : 0; spin_unlock_irqrestore(&pctl->lock, flags); dev_dbg(pctl->dev, "get sleep gpio state(pin=%d) %d\n", @@ -217,7 +217,7 @@ static int pxa2xx_pconf_group_set(struct pinctrl_dev *pctldev, for (i = 0; i < num_configs; i++) { switch (pinconf_to_config_param(configs[i])) { - case PIN_CONFIG_LOW_POWER_MODE: + case PIN_CONFIG_MODE_LOW_POWER: is_set = pinconf_to_config_argument(configs[i]); break; default: diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index df9a5ca8c99c..46bcdbef1675 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -1738,7 +1738,7 @@ static int tegra_io_pad_pinconf_get(struct pinctrl_dev *pctl_dev, arg = ret; break; - case PIN_CONFIG_LOW_POWER_MODE: + case PIN_CONFIG_MODE_LOW_POWER: ret = tegra_io_pad_is_powered(pmc, pad->id); if (ret < 0) return ret; @@ -1775,7 +1775,7 @@ static int tegra_io_pad_pinconf_set(struct pinctrl_dev *pctl_dev, arg = pinconf_to_config_argument(configs[i]); switch (param) { - case PIN_CONFIG_LOW_POWER_MODE: + case PIN_CONFIG_MODE_LOW_POWER: if (arg) err = tegra_io_pad_power_disable(pad->id); else diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h index 188db8d84162..189e701832ea 100644 --- a/include/linux/pinctrl/pinconf-generic.h +++ b/include/linux/pinctrl/pinconf-generic.h @@ -76,7 +76,7 @@ struct pinctrl_map; * @PIN_CONFIG_INPUT_SCHMITT_ENABLE: control schmitt-trigger mode on the pin. * If the argument != 0, schmitt-trigger mode is enabled. If it's 0, * schmitt-trigger mode is disabled. - * @PIN_CONFIG_LOW_POWER_MODE: this will configure the pin for low power + * @PIN_CONFIG_MODE_LOW_POWER: this will configure the pin for low power * operation, if several modes of operation are supported these can be * passed in the argument on a custom form, else just use argument 1 * to indicate low power mode, argument 0 turns low power mode off. @@ -124,7 +124,7 @@ enum pin_config_param { PIN_CONFIG_INPUT_ENABLE, PIN_CONFIG_INPUT_SCHMITT, PIN_CONFIG_INPUT_SCHMITT_ENABLE, - PIN_CONFIG_LOW_POWER_MODE, + PIN_CONFIG_MODE_LOW_POWER, PIN_CONFIG_OUTPUT_ENABLE, PIN_CONFIG_OUTPUT, PIN_CONFIG_PERSIST_STATE, -- cgit v1.2.3 From 09e11caaa4cffac681963688b774e1aa3063b3a9 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 12 Apr 2021 17:07:41 +0300 Subject: pinctrl: Add PIN_CONFIG_MODE_PWM to enum pin_config_param It seems that we will have more and more pin controllers that support PWM function on the (selected) pins. Due to it being a part of pin controller IP the idea is to have some code that will switch the mode and attach the corresponding driver, for example, via using it as a library. Meanwhile, put a corresponding item to the pin_config_param enumerator. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210412140741.39946-3-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- include/linux/pinctrl/pinconf-generic.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h index 189e701832ea..e18ab3d5908f 100644 --- a/include/linux/pinctrl/pinconf-generic.h +++ b/include/linux/pinctrl/pinconf-generic.h @@ -80,6 +80,7 @@ struct pinctrl_map; * operation, if several modes of operation are supported these can be * passed in the argument on a custom form, else just use argument 1 * to indicate low power mode, argument 0 turns low power mode off. + * @PIN_CONFIG_MODE_PWM: this will configure the pin for PWM * @PIN_CONFIG_OUTPUT_ENABLE: this will enable the pin's output mode * without driving a value there. For most platforms this reduces to * enable the output buffers and then let the pin controller current @@ -125,6 +126,7 @@ enum pin_config_param { PIN_CONFIG_INPUT_SCHMITT, PIN_CONFIG_INPUT_SCHMITT_ENABLE, PIN_CONFIG_MODE_LOW_POWER, + PIN_CONFIG_MODE_PWM, PIN_CONFIG_OUTPUT_ENABLE, PIN_CONFIG_OUTPUT, PIN_CONFIG_PERSIST_STATE, -- cgit v1.2.3 From fe202ea8e5b170ef7b3741da885e8cb7bae1106e Mon Sep 17 00:00:00 2001 From: Jianqun Xu Date: Tue, 20 Apr 2021 17:12:40 +0800 Subject: pinctrl: rockchip: do coding style for mux route struct The mux route tables take many lines for each SoC, and it will be more instances for newly SoC, that makes the file size increase larger. This patch only do coding style for mux route struct, by adding a new definition and replace the structs by script which supplied by huangtao@rock-chips.com sed -i -e " /static struct rockchip_mux_route_data /bcheck b :append-next-line N :check /^[^;]*$/bappend-next-line s/[[:blank:]]*.bank_num = \([[:digit:]]*,\)\n/\tRK_MUXROUTE_SAME(\1/g s/[[:blank:]]*.pin =[[:blank:]]*0,\n/ RK_PA0,/g s/[[:blank:]]*.pin =[[:blank:]]*1,\n/ RK_PA1,/g s/[[:blank:]]*.pin =[[:blank:]]*2,\n/ RK_PA2,/g s/[[:blank:]]*.pin =[[:blank:]]*3,\n/ RK_PA3,/g s/[[:blank:]]*.pin =[[:blank:]]*4,\n/ RK_PA4,/g s/[[:blank:]]*.pin =[[:blank:]]*5,\n/ RK_PA5,/g s/[[:blank:]]*.pin =[[:blank:]]*6,\n/ RK_PA6,/g s/[[:blank:]]*.pin =[[:blank:]]*7,\n/ RK_PA7,/g s/[[:blank:]]*.pin =[[:blank:]]*8,\n/ RK_PB0,/g s/[[:blank:]]*.pin =[[:blank:]]*9,\n/ RK_PB1,/g s/[[:blank:]]*.pin =[[:blank:]]*10,\n/ RK_PB2,/g s/[[:blank:]]*.pin =[[:blank:]]*11,\n/ RK_PB3,/g s/[[:blank:]]*.pin =[[:blank:]]*12,\n/ RK_PB4,/g s/[[:blank:]]*.pin =[[:blank:]]*13,\n/ RK_PB5,/g s/[[:blank:]]*.pin =[[:blank:]]*14,\n/ RK_PB6,/g s/[[:blank:]]*.pin =[[:blank:]]*15,\n/ RK_PB7,/g s/[[:blank:]]*.pin =[[:blank:]]*16,\n/ RK_PC0,/g s/[[:blank:]]*.pin =[[:blank:]]*17,\n/ RK_PC1,/g s/[[:blank:]]*.pin =[[:blank:]]*18,\n/ RK_PC2,/g s/[[:blank:]]*.pin =[[:blank:]]*19,\n/ RK_PC3,/g s/[[:blank:]]*.pin =[[:blank:]]*20,\n/ RK_PC4,/g s/[[:blank:]]*.pin =[[:blank:]]*21,\n/ RK_PC5,/g s/[[:blank:]]*.pin =[[:blank:]]*22,\n/ RK_PC6,/g s/[[:blank:]]*.pin =[[:blank:]]*23,\n/ RK_PC7,/g s/[[:blank:]]*.pin =[[:blank:]]*24,\n/ RK_PD0,/g s/[[:blank:]]*.pin =[[:blank:]]*25,\n/ RK_PD1,/g s/[[:blank:]]*.pin =[[:blank:]]*26,\n/ RK_PD2,/g s/[[:blank:]]*.pin =[[:blank:]]*27,\n/ RK_PD3,/g s/[[:blank:]]*.pin =[[:blank:]]*28,\n/ RK_PD4,/g s/[[:blank:]]*.pin =[[:blank:]]*29,\n/ RK_PD5,/g s/[[:blank:]]*.pin =[[:blank:]]*30,\n/ RK_PD6,/g s/[[:blank:]]*.pin =[[:blank:]]*31,\n/ RK_PD7,/g s/[[:blank:]]*.func = \([[:digit:]]*,\)\n/ \1/g s/[[:blank:]]*.route_location =[[:blank:]]*\([[:print:]]*,\)\n//g s/[[:blank:]]*.route_offset = \(0x[[:xdigit:]]*,\)\n/ \1/g s/[[:blank:]]*.route_val =[[:blank:]]*\([[:print:]]*\),\n/ \1),/g s/\t{\n//g s/\t}, {\n//g s/\t},//g s/[[:blank:]]*\(\/\*[[:print:]]*\*\/\)\n[[:blank:]]*RK_MUXROUTE_SAME(\([[:print:]]*\)),\n/\tRK_MUXROUTE_SAME(\2), \1\n/g s/[[:blank:]]*\(\/\*[[:print:]]*\*\/\)\n[[:blank:]]*RK_MUXROUTE_SAME(\([[:print:]]*\)),/\tRK_MUXROUTE_SAME(\2), \1\n/g " drivers/pinctrl/pinctrl-rockchip.c Reviewed-by: Heiko Stuebner Signed-off-by: Jianqun Xu Link: https://lore.kernel.org/r/20210420091240.1246429-1-jay.xu@rock-chips.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 650 +++++-------------------------------- 1 file changed, 80 insertions(+), 570 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 05128f53824c..94fa18cdcd8d 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -831,597 +831,107 @@ static void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin, } static struct rockchip_mux_route_data px30_mux_route_data[] = { - { - /* cif-d2m0 */ - .bank_num = 2, - .pin = 0, - .func = 1, - .route_offset = 0x184, - .route_val = BIT(16 + 7), - }, { - /* cif-d2m1 */ - .bank_num = 3, - .pin = 3, - .func = 3, - .route_offset = 0x184, - .route_val = BIT(16 + 7) | BIT(7), - }, { - /* pdm-m0 */ - .bank_num = 3, - .pin = 22, - .func = 2, - .route_offset = 0x184, - .route_val = BIT(16 + 8), - }, { - /* pdm-m1 */ - .bank_num = 2, - .pin = 22, - .func = 1, - .route_offset = 0x184, - .route_val = BIT(16 + 8) | BIT(8), - }, { - /* uart2-rxm0 */ - .bank_num = 1, - .pin = 27, - .func = 2, - .route_offset = 0x184, - .route_val = BIT(16 + 10), - }, { - /* uart2-rxm1 */ - .bank_num = 2, - .pin = 14, - .func = 2, - .route_offset = 0x184, - .route_val = BIT(16 + 10) | BIT(10), - }, { - /* uart3-rxm0 */ - .bank_num = 0, - .pin = 17, - .func = 2, - .route_offset = 0x184, - .route_val = BIT(16 + 9), - }, { - /* uart3-rxm1 */ - .bank_num = 1, - .pin = 15, - .func = 2, - .route_offset = 0x184, - .route_val = BIT(16 + 9) | BIT(9), - }, + RK_MUXROUTE_SAME(2, RK_PA0, 1, 0x184, BIT(16 + 7)), /* cif-d2m0 */ + RK_MUXROUTE_SAME(3, RK_PA3, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d2m1 */ + RK_MUXROUTE_SAME(3, RK_PC6, 2, 0x184, BIT(16 + 8)), /* pdm-m0 */ + RK_MUXROUTE_SAME(2, RK_PC6, 1, 0x184, BIT(16 + 8) | BIT(8)), /* pdm-m1 */ + RK_MUXROUTE_SAME(1, RK_PD3, 2, 0x184, BIT(16 + 10)), /* uart2-rxm0 */ + RK_MUXROUTE_SAME(2, RK_PB6, 2, 0x184, BIT(16 + 10) | BIT(10)), /* uart2-rxm1 */ + RK_MUXROUTE_SAME(0, RK_PC1, 2, 0x184, BIT(16 + 9)), /* uart3-rxm0 */ + RK_MUXROUTE_SAME(1, RK_PB7, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-rxm1 */ }; static struct rockchip_mux_route_data rk3128_mux_route_data[] = { - { - /* spi-0 */ - .bank_num = 1, - .pin = 10, - .func = 1, - .route_offset = 0x144, - .route_val = BIT(16 + 3) | BIT(16 + 4), - }, { - /* spi-1 */ - .bank_num = 1, - .pin = 27, - .func = 3, - .route_offset = 0x144, - .route_val = BIT(16 + 3) | BIT(16 + 4) | BIT(3), - }, { - /* spi-2 */ - .bank_num = 0, - .pin = 13, - .func = 2, - .route_offset = 0x144, - .route_val = BIT(16 + 3) | BIT(16 + 4) | BIT(4), - }, { - /* i2s-0 */ - .bank_num = 1, - .pin = 5, - .func = 1, - .route_offset = 0x144, - .route_val = BIT(16 + 5), - }, { - /* i2s-1 */ - .bank_num = 0, - .pin = 14, - .func = 1, - .route_offset = 0x144, - .route_val = BIT(16 + 5) | BIT(5), - }, { - /* emmc-0 */ - .bank_num = 1, - .pin = 22, - .func = 2, - .route_offset = 0x144, - .route_val = BIT(16 + 6), - }, { - /* emmc-1 */ - .bank_num = 2, - .pin = 4, - .func = 2, - .route_offset = 0x144, - .route_val = BIT(16 + 6) | BIT(6), - }, + RK_MUXROUTE_SAME(1, RK_PB2, 1, 0x144, BIT(16 + 3) | BIT(16 + 4)), /* spi-0 */ + RK_MUXROUTE_SAME(1, RK_PD3, 3, 0x144, BIT(16 + 3) | BIT(16 + 4) | BIT(3)), /* spi-1 */ + RK_MUXROUTE_SAME(0, RK_PB5, 2, 0x144, BIT(16 + 3) | BIT(16 + 4) | BIT(4)), /* spi-2 */ + RK_MUXROUTE_SAME(1, RK_PA5, 1, 0x144, BIT(16 + 5)), /* i2s-0 */ + RK_MUXROUTE_SAME(0, RK_PB6, 1, 0x144, BIT(16 + 5) | BIT(5)), /* i2s-1 */ + RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x144, BIT(16 + 6)), /* emmc-0 */ + RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x144, BIT(16 + 6) | BIT(6)), /* emmc-1 */ }; static struct rockchip_mux_route_data rk3188_mux_route_data[] = { - { - /* non-iomuxed emmc/flash pins on flash-dqs */ - .bank_num = 0, - .pin = 24, - .func = 1, - .route_location = ROCKCHIP_ROUTE_GRF, - .route_offset = 0xa0, - .route_val = BIT(16 + 11), - }, { - /* non-iomuxed emmc/flash pins on emmc-clk */ - .bank_num = 0, - .pin = 24, - .func = 2, - .route_location = ROCKCHIP_ROUTE_GRF, - .route_offset = 0xa0, - .route_val = BIT(16 + 11) | BIT(11), - }, + RK_MUXROUTE_SAME(0, RK_PD0, 1, 0xa0, BIT(16 + 11)), /* non-iomuxed emmc/flash pins on flash-dqs */ + RK_MUXROUTE_SAME(0, RK_PD0, 2, 0xa0, BIT(16 + 11) | BIT(11)), /* non-iomuxed emmc/flash pins on emmc-clk */ }; static struct rockchip_mux_route_data rk3228_mux_route_data[] = { - { - /* pwm0-0 */ - .bank_num = 0, - .pin = 26, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16), - }, { - /* pwm0-1 */ - .bank_num = 3, - .pin = 21, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16) | BIT(0), - }, { - /* pwm1-0 */ - .bank_num = 0, - .pin = 27, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16 + 1), - }, { - /* pwm1-1 */ - .bank_num = 0, - .pin = 30, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 1) | BIT(1), - }, { - /* pwm2-0 */ - .bank_num = 0, - .pin = 28, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16 + 2), - }, { - /* pwm2-1 */ - .bank_num = 1, - .pin = 12, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 2) | BIT(2), - }, { - /* pwm3-0 */ - .bank_num = 3, - .pin = 26, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16 + 3), - }, { - /* pwm3-1 */ - .bank_num = 1, - .pin = 11, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 3) | BIT(3), - }, { - /* sdio-0_d0 */ - .bank_num = 1, - .pin = 1, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16 + 4), - }, { - /* sdio-1_d0 */ - .bank_num = 3, - .pin = 2, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16 + 4) | BIT(4), - }, { - /* spi-0_rx */ - .bank_num = 0, - .pin = 13, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 5), - }, { - /* spi-1_rx */ - .bank_num = 2, - .pin = 0, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 5) | BIT(5), - }, { - /* emmc-0_cmd */ - .bank_num = 1, - .pin = 22, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 7), - }, { - /* emmc-1_cmd */ - .bank_num = 2, - .pin = 4, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 7) | BIT(7), - }, { - /* uart2-0_rx */ - .bank_num = 1, - .pin = 19, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 8), - }, { - /* uart2-1_rx */ - .bank_num = 1, - .pin = 10, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 8) | BIT(8), - }, { - /* uart1-0_rx */ - .bank_num = 1, - .pin = 10, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16 + 11), - }, { - /* uart1-1_rx */ - .bank_num = 3, - .pin = 13, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16 + 11) | BIT(11), - }, + RK_MUXROUTE_SAME(0, RK_PD2, 1, 0x50, BIT(16)), /* pwm0-0 */ + RK_MUXROUTE_SAME(3, RK_PC5, 1, 0x50, BIT(16) | BIT(0)), /* pwm0-1 */ + RK_MUXROUTE_SAME(0, RK_PD3, 1, 0x50, BIT(16 + 1)), /* pwm1-0 */ + RK_MUXROUTE_SAME(0, RK_PD6, 2, 0x50, BIT(16 + 1) | BIT(1)), /* pwm1-1 */ + RK_MUXROUTE_SAME(0, RK_PD4, 1, 0x50, BIT(16 + 2)), /* pwm2-0 */ + RK_MUXROUTE_SAME(1, RK_PB4, 2, 0x50, BIT(16 + 2) | BIT(2)), /* pwm2-1 */ + RK_MUXROUTE_SAME(3, RK_PD2, 1, 0x50, BIT(16 + 3)), /* pwm3-0 */ + RK_MUXROUTE_SAME(1, RK_PB3, 2, 0x50, BIT(16 + 3) | BIT(3)), /* pwm3-1 */ + RK_MUXROUTE_SAME(1, RK_PA1, 1, 0x50, BIT(16 + 4)), /* sdio-0_d0 */ + RK_MUXROUTE_SAME(3, RK_PA2, 1, 0x50, BIT(16 + 4) | BIT(4)), /* sdio-1_d0 */ + RK_MUXROUTE_SAME(0, RK_PB5, 2, 0x50, BIT(16 + 5)), /* spi-0_rx */ + RK_MUXROUTE_SAME(2, RK_PA0, 2, 0x50, BIT(16 + 5) | BIT(5)), /* spi-1_rx */ + RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x50, BIT(16 + 7)), /* emmc-0_cmd */ + RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x50, BIT(16 + 7) | BIT(7)), /* emmc-1_cmd */ + RK_MUXROUTE_SAME(1, RK_PC3, 2, 0x50, BIT(16 + 8)), /* uart2-0_rx */ + RK_MUXROUTE_SAME(1, RK_PB2, 2, 0x50, BIT(16 + 8) | BIT(8)), /* uart2-1_rx */ + RK_MUXROUTE_SAME(1, RK_PB2, 1, 0x50, BIT(16 + 11)), /* uart1-0_rx */ + RK_MUXROUTE_SAME(3, RK_PB5, 1, 0x50, BIT(16 + 11) | BIT(11)), /* uart1-1_rx */ }; static struct rockchip_mux_route_data rk3288_mux_route_data[] = { - { - /* edphdmi_cecinoutt1 */ - .bank_num = 7, - .pin = 16, - .func = 2, - .route_offset = 0x264, - .route_val = BIT(16 + 12) | BIT(12), - }, { - /* edphdmi_cecinout */ - .bank_num = 7, - .pin = 23, - .func = 4, - .route_offset = 0x264, - .route_val = BIT(16 + 12), - }, + RK_MUXROUTE_SAME(7, RK_PC0, 2, 0x264, BIT(16 + 12) | BIT(12)), /* edphdmi_cecinoutt1 */ + RK_MUXROUTE_SAME(7, RK_PC7, 4, 0x264, BIT(16 + 12)), /* edphdmi_cecinout */ }; static struct rockchip_mux_route_data rk3308_mux_route_data[] = { - { - /* rtc_clk */ - .bank_num = 0, - .pin = 19, - .func = 1, - .route_offset = 0x314, - .route_val = BIT(16 + 0) | BIT(0), - }, { - /* uart2_rxm0 */ - .bank_num = 1, - .pin = 22, - .func = 2, - .route_offset = 0x314, - .route_val = BIT(16 + 2) | BIT(16 + 3), - }, { - /* uart2_rxm1 */ - .bank_num = 4, - .pin = 26, - .func = 2, - .route_offset = 0x314, - .route_val = BIT(16 + 2) | BIT(16 + 3) | BIT(2), - }, { - /* i2c3_sdam0 */ - .bank_num = 0, - .pin = 15, - .func = 2, - .route_offset = 0x608, - .route_val = BIT(16 + 8) | BIT(16 + 9), - }, { - /* i2c3_sdam1 */ - .bank_num = 3, - .pin = 12, - .func = 2, - .route_offset = 0x608, - .route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(8), - }, { - /* i2c3_sdam2 */ - .bank_num = 2, - .pin = 0, - .func = 3, - .route_offset = 0x608, - .route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(9), - }, { - /* i2s-8ch-1-sclktxm0 */ - .bank_num = 1, - .pin = 3, - .func = 2, - .route_offset = 0x308, - .route_val = BIT(16 + 3), - }, { - /* i2s-8ch-1-sclkrxm0 */ - .bank_num = 1, - .pin = 4, - .func = 2, - .route_offset = 0x308, - .route_val = BIT(16 + 3), - }, { - /* i2s-8ch-1-sclktxm1 */ - .bank_num = 1, - .pin = 13, - .func = 2, - .route_offset = 0x308, - .route_val = BIT(16 + 3) | BIT(3), - }, { - /* i2s-8ch-1-sclkrxm1 */ - .bank_num = 1, - .pin = 14, - .func = 2, - .route_offset = 0x308, - .route_val = BIT(16 + 3) | BIT(3), - }, { - /* pdm-clkm0 */ - .bank_num = 1, - .pin = 4, - .func = 3, - .route_offset = 0x308, - .route_val = BIT(16 + 12) | BIT(16 + 13), - }, { - /* pdm-clkm1 */ - .bank_num = 1, - .pin = 14, - .func = 4, - .route_offset = 0x308, - .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(12), - }, { - /* pdm-clkm2 */ - .bank_num = 2, - .pin = 6, - .func = 2, - .route_offset = 0x308, - .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(13), - }, { - /* pdm-clkm-m2 */ - .bank_num = 2, - .pin = 4, - .func = 3, - .route_offset = 0x600, - .route_val = BIT(16 + 2) | BIT(2), - }, { - /* spi1_miso */ - .bank_num = 3, - .pin = 10, - .func = 3, - .route_offset = 0x314, - .route_val = BIT(16 + 9), - }, { - /* spi1_miso_m1 */ - .bank_num = 2, - .pin = 4, - .func = 2, - .route_offset = 0x314, - .route_val = BIT(16 + 9) | BIT(9), - }, { - /* owire_m0 */ - .bank_num = 0, - .pin = 11, - .func = 3, - .route_offset = 0x314, - .route_val = BIT(16 + 10) | BIT(16 + 11), - }, { - /* owire_m1 */ - .bank_num = 1, - .pin = 22, - .func = 7, - .route_offset = 0x314, - .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10), - }, { - /* owire_m2 */ - .bank_num = 2, - .pin = 2, - .func = 5, - .route_offset = 0x314, - .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11), - }, { - /* can_rxd_m0 */ - .bank_num = 0, - .pin = 11, - .func = 2, - .route_offset = 0x314, - .route_val = BIT(16 + 12) | BIT(16 + 13), - }, { - /* can_rxd_m1 */ - .bank_num = 1, - .pin = 22, - .func = 5, - .route_offset = 0x314, - .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(12), - }, { - /* can_rxd_m2 */ - .bank_num = 2, - .pin = 2, - .func = 4, - .route_offset = 0x314, - .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(13), - }, { - /* mac_rxd0_m0 */ - .bank_num = 1, - .pin = 20, - .func = 3, - .route_offset = 0x314, - .route_val = BIT(16 + 14), - }, { - /* mac_rxd0_m1 */ - .bank_num = 4, - .pin = 2, - .func = 2, - .route_offset = 0x314, - .route_val = BIT(16 + 14) | BIT(14), - }, { - /* uart3_rx */ - .bank_num = 3, - .pin = 12, - .func = 4, - .route_offset = 0x314, - .route_val = BIT(16 + 15), - }, { - /* uart3_rx_m1 */ - .bank_num = 0, - .pin = 17, - .func = 3, - .route_offset = 0x314, - .route_val = BIT(16 + 15) | BIT(15), - }, + RK_MUXROUTE_SAME(0, RK_PC3, 1, 0x314, BIT(16 + 0) | BIT(0)), /* rtc_clk */ + RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x314, BIT(16 + 2) | BIT(16 + 3)), /* uart2_rxm0 */ + RK_MUXROUTE_SAME(4, RK_PD2, 2, 0x314, BIT(16 + 2) | BIT(16 + 3) | BIT(2)), /* uart2_rxm1 */ + RK_MUXROUTE_SAME(0, RK_PB7, 2, 0x608, BIT(16 + 8) | BIT(16 + 9)), /* i2c3_sdam0 */ + RK_MUXROUTE_SAME(3, RK_PB4, 2, 0x608, BIT(16 + 8) | BIT(16 + 9) | BIT(8)), /* i2c3_sdam1 */ + RK_MUXROUTE_SAME(2, RK_PA0, 3, 0x608, BIT(16 + 8) | BIT(16 + 9) | BIT(9)), /* i2c3_sdam2 */ + RK_MUXROUTE_SAME(1, RK_PA3, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclktxm0 */ + RK_MUXROUTE_SAME(1, RK_PA4, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclkrxm0 */ + RK_MUXROUTE_SAME(1, RK_PB5, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclktxm1 */ + RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclkrxm1 */ + RK_MUXROUTE_SAME(1, RK_PA4, 3, 0x308, BIT(16 + 12) | BIT(16 + 13)), /* pdm-clkm0 */ + RK_MUXROUTE_SAME(1, RK_PB6, 4, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* pdm-clkm1 */ + RK_MUXROUTE_SAME(2, RK_PA6, 2, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* pdm-clkm2 */ + RK_MUXROUTE_SAME(2, RK_PA4, 3, 0x600, BIT(16 + 2) | BIT(2)), /* pdm-clkm-m2 */ + RK_MUXROUTE_SAME(3, RK_PB2, 3, 0x314, BIT(16 + 9)), /* spi1_miso */ + RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x314, BIT(16 + 9) | BIT(9)), /* spi1_miso_m1 */ + RK_MUXROUTE_SAME(0, RK_PB3, 3, 0x314, BIT(16 + 10) | BIT(16 + 11)), /* owire_m0 */ + RK_MUXROUTE_SAME(1, RK_PC6, 7, 0x314, BIT(16 + 10) | BIT(16 + 11) | BIT(10)), /* owire_m1 */ + RK_MUXROUTE_SAME(2, RK_PA2, 5, 0x314, BIT(16 + 10) | BIT(16 + 11) | BIT(11)), /* owire_m2 */ + RK_MUXROUTE_SAME(0, RK_PB3, 2, 0x314, BIT(16 + 12) | BIT(16 + 13)), /* can_rxd_m0 */ + RK_MUXROUTE_SAME(1, RK_PC6, 5, 0x314, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* can_rxd_m1 */ + RK_MUXROUTE_SAME(2, RK_PA2, 4, 0x314, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* can_rxd_m2 */ + RK_MUXROUTE_SAME(1, RK_PC4, 3, 0x314, BIT(16 + 14)), /* mac_rxd0_m0 */ + RK_MUXROUTE_SAME(4, RK_PA2, 2, 0x314, BIT(16 + 14) | BIT(14)), /* mac_rxd0_m1 */ + RK_MUXROUTE_SAME(3, RK_PB4, 4, 0x314, BIT(16 + 15)), /* uart3_rx */ + RK_MUXROUTE_SAME(0, RK_PC1, 3, 0x314, BIT(16 + 15) | BIT(15)), /* uart3_rx_m1 */ }; static struct rockchip_mux_route_data rk3328_mux_route_data[] = { - { - /* uart2dbg_rxm0 */ - .bank_num = 1, - .pin = 1, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16) | BIT(16 + 1), - }, { - /* uart2dbg_rxm1 */ - .bank_num = 2, - .pin = 1, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16) | BIT(16 + 1) | BIT(0), - }, { - /* gmac-m1_rxd0 */ - .bank_num = 1, - .pin = 11, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 2) | BIT(2), - }, { - /* gmac-m1-optimized_rxd3 */ - .bank_num = 1, - .pin = 14, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 10) | BIT(10), - }, { - /* pdm_sdi0m0 */ - .bank_num = 2, - .pin = 19, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 3), - }, { - /* pdm_sdi0m1 */ - .bank_num = 1, - .pin = 23, - .func = 3, - .route_offset = 0x50, - .route_val = BIT(16 + 3) | BIT(3), - }, { - /* spi_rxdm2 */ - .bank_num = 3, - .pin = 2, - .func = 4, - .route_offset = 0x50, - .route_val = BIT(16 + 4) | BIT(16 + 5) | BIT(5), - }, { - /* i2s2_sdim0 */ - .bank_num = 1, - .pin = 24, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16 + 6), - }, { - /* i2s2_sdim1 */ - .bank_num = 3, - .pin = 2, - .func = 6, - .route_offset = 0x50, - .route_val = BIT(16 + 6) | BIT(6), - }, { - /* card_iom1 */ - .bank_num = 2, - .pin = 22, - .func = 3, - .route_offset = 0x50, - .route_val = BIT(16 + 7) | BIT(7), - }, { - /* tsp_d5m1 */ - .bank_num = 2, - .pin = 16, - .func = 3, - .route_offset = 0x50, - .route_val = BIT(16 + 8) | BIT(8), - }, { - /* cif_data5m1 */ - .bank_num = 2, - .pin = 16, - .func = 4, - .route_offset = 0x50, - .route_val = BIT(16 + 9) | BIT(9), - }, + RK_MUXROUTE_SAME(1, RK_PA1, 2, 0x50, BIT(16) | BIT(16 + 1)), /* uart2dbg_rxm0 */ + RK_MUXROUTE_SAME(2, RK_PA1, 1, 0x50, BIT(16) | BIT(16 + 1) | BIT(0)), /* uart2dbg_rxm1 */ + RK_MUXROUTE_SAME(1, RK_PB3, 2, 0x50, BIT(16 + 2) | BIT(2)), /* gmac-m1_rxd0 */ + RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x50, BIT(16 + 10) | BIT(10)), /* gmac-m1-optimized_rxd3 */ + RK_MUXROUTE_SAME(2, RK_PC3, 2, 0x50, BIT(16 + 3)), /* pdm_sdi0m0 */ + RK_MUXROUTE_SAME(1, RK_PC7, 3, 0x50, BIT(16 + 3) | BIT(3)), /* pdm_sdi0m1 */ + RK_MUXROUTE_SAME(3, RK_PA2, 4, 0x50, BIT(16 + 4) | BIT(16 + 5) | BIT(5)), /* spi_rxdm2 */ + RK_MUXROUTE_SAME(1, RK_PD0, 1, 0x50, BIT(16 + 6)), /* i2s2_sdim0 */ + RK_MUXROUTE_SAME(3, RK_PA2, 6, 0x50, BIT(16 + 6) | BIT(6)), /* i2s2_sdim1 */ + RK_MUXROUTE_SAME(2, RK_PC6, 3, 0x50, BIT(16 + 7) | BIT(7)), /* card_iom1 */ + RK_MUXROUTE_SAME(2, RK_PC0, 3, 0x50, BIT(16 + 8) | BIT(8)), /* tsp_d5m1 */ + RK_MUXROUTE_SAME(2, RK_PC0, 4, 0x50, BIT(16 + 9) | BIT(9)), /* cif_data5m1 */ }; static struct rockchip_mux_route_data rk3399_mux_route_data[] = { - { - /* uart2dbga_rx */ - .bank_num = 4, - .pin = 8, - .func = 2, - .route_offset = 0xe21c, - .route_val = BIT(16 + 10) | BIT(16 + 11), - }, { - /* uart2dbgb_rx */ - .bank_num = 4, - .pin = 16, - .func = 2, - .route_offset = 0xe21c, - .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10), - }, { - /* uart2dbgc_rx */ - .bank_num = 4, - .pin = 19, - .func = 1, - .route_offset = 0xe21c, - .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11), - }, { - /* pcie_clkreqn */ - .bank_num = 2, - .pin = 26, - .func = 2, - .route_offset = 0xe21c, - .route_val = BIT(16 + 14), - }, { - /* pcie_clkreqnb */ - .bank_num = 4, - .pin = 24, - .func = 1, - .route_offset = 0xe21c, - .route_val = BIT(16 + 14) | BIT(14), - }, + RK_MUXROUTE_SAME(4, RK_PB0, 2, 0xe21c, BIT(16 + 10) | BIT(16 + 11)), /* uart2dbga_rx */ + RK_MUXROUTE_SAME(4, RK_PC0, 2, 0xe21c, BIT(16 + 10) | BIT(16 + 11) | BIT(10)), /* uart2dbgb_rx */ + RK_MUXROUTE_SAME(4, RK_PC3, 1, 0xe21c, BIT(16 + 10) | BIT(16 + 11) | BIT(11)), /* uart2dbgc_rx */ + RK_MUXROUTE_SAME(2, RK_PD2, 2, 0xe21c, BIT(16 + 14)), /* pcie_clkreqn */ + RK_MUXROUTE_SAME(4, RK_PD0, 1, 0xe21c, BIT(16 + 14) | BIT(14)), /* pcie_clkreqnb */ }; static struct rockchip_mux_route_data rk3568_mux_route_data[] = { -- cgit v1.2.3 From fa989ae7c7b38efbc6c3370571fb8a6f7350029a Mon Sep 17 00:00:00 2001 From: Sai Krishna Potthuri Date: Thu, 22 Apr 2021 14:00:00 +0530 Subject: firmware: xilinx: Add pinctrl support Adding pinctrl support to query platform specific information (pins) from firmware. Signed-off-by: Sai Krishna Potthuri Acked-by: Michal Simek Link: https://lore.kernel.org/r/1619080202-31924-2-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com Signed-off-by: Linus Walleij --- drivers/firmware/xilinx/zynqmp.c | 114 +++++++++++++++++++++++++++++++++++ include/linux/firmware/xlnx-zynqmp.h | 90 +++++++++++++++++++++++++++ 2 files changed, 204 insertions(+) diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c index 7eb9958662dd..fc01a3632815 100644 --- a/drivers/firmware/xilinx/zynqmp.c +++ b/drivers/firmware/xilinx/zynqmp.c @@ -811,6 +811,120 @@ int zynqmp_pm_fpga_get_status(u32 *value) } EXPORT_SYMBOL_GPL(zynqmp_pm_fpga_get_status); +/** + * zynqmp_pm_pinctrl_request - Request Pin from firmware + * @pin: Pin number to request + * + * This function requests pin from firmware. + * + * Return: Returns status, either success or error+reason. + */ +int zynqmp_pm_pinctrl_request(const u32 pin) +{ + return zynqmp_pm_invoke_fn(PM_PINCTRL_REQUEST, pin, 0, 0, 0, NULL); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_request); + +/** + * zynqmp_pm_pinctrl_release - Inform firmware that Pin control is released + * @pin: Pin number to release + * + * This function release pin from firmware. + * + * Return: Returns status, either success or error+reason. + */ +int zynqmp_pm_pinctrl_release(const u32 pin) +{ + return zynqmp_pm_invoke_fn(PM_PINCTRL_RELEASE, pin, 0, 0, 0, NULL); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_release); + +/** + * zynqmp_pm_pinctrl_get_function - Read function id set for the given pin + * @pin: Pin number + * @id: Buffer to store function ID + * + * This function provides the function currently set for the given pin. + * + * Return: Returns status, either success or error+reason + */ +int zynqmp_pm_pinctrl_get_function(const u32 pin, u32 *id) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + if (!id) + return -EINVAL; + + ret = zynqmp_pm_invoke_fn(PM_PINCTRL_GET_FUNCTION, pin, 0, + 0, 0, ret_payload); + *id = ret_payload[1]; + + return ret; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_get_function); + +/** + * zynqmp_pm_pinctrl_set_function - Set requested function for the pin + * @pin: Pin number + * @id: Function ID to set + * + * This function sets requested function for the given pin. + * + * Return: Returns status, either success or error+reason. + */ +int zynqmp_pm_pinctrl_set_function(const u32 pin, const u32 id) +{ + return zynqmp_pm_invoke_fn(PM_PINCTRL_SET_FUNCTION, pin, id, + 0, 0, NULL); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_set_function); + +/** + * zynqmp_pm_pinctrl_get_config - Get configuration parameter for the pin + * @pin: Pin number + * @param: Parameter to get + * @value: Buffer to store parameter value + * + * This function gets requested configuration parameter for the given pin. + * + * Return: Returns status, either success or error+reason. + */ +int zynqmp_pm_pinctrl_get_config(const u32 pin, const u32 param, + u32 *value) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + if (!value) + return -EINVAL; + + ret = zynqmp_pm_invoke_fn(PM_PINCTRL_CONFIG_PARAM_GET, pin, param, + 0, 0, ret_payload); + *value = ret_payload[1]; + + return ret; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_get_config); + +/** + * zynqmp_pm_pinctrl_set_config - Set configuration parameter for the pin + * @pin: Pin number + * @param: Parameter to set + * @value: Parameter value to set + * + * This function sets requested configuration parameter for the given pin. + * + * Return: Returns status, either success or error+reason. + */ +int zynqmp_pm_pinctrl_set_config(const u32 pin, const u32 param, + u32 value) +{ + return zynqmp_pm_invoke_fn(PM_PINCTRL_CONFIG_PARAM_SET, pin, + param, value, 0, NULL); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_set_config); + /** * zynqmp_pm_init_finalize() - PM call to inform firmware that the caller * master has initialized its own power management diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h index 71177b17eee5..8285a4bcfc2d 100644 --- a/include/linux/firmware/xlnx-zynqmp.h +++ b/include/linux/firmware/xlnx-zynqmp.h @@ -72,6 +72,12 @@ enum pm_api_id { PM_FPGA_LOAD = 22, PM_FPGA_GET_STATUS = 23, PM_GET_CHIPID = 24, + PM_PINCTRL_REQUEST = 28, + PM_PINCTRL_RELEASE = 29, + PM_PINCTRL_GET_FUNCTION = 30, + PM_PINCTRL_SET_FUNCTION = 31, + PM_PINCTRL_CONFIG_PARAM_GET = 32, + PM_PINCTRL_CONFIG_PARAM_SET = 33, PM_IOCTL = 34, PM_QUERY_DATA = 35, PM_CLOCK_ENABLE = 36, @@ -122,6 +128,12 @@ enum pm_query_id { PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS = 3, PM_QID_CLOCK_GET_PARENTS = 4, PM_QID_CLOCK_GET_ATTRIBUTES = 5, + PM_QID_PINCTRL_GET_NUM_PINS = 6, + PM_QID_PINCTRL_GET_NUM_FUNCTIONS = 7, + PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS = 8, + PM_QID_PINCTRL_GET_FUNCTION_NAME = 9, + PM_QID_PINCTRL_GET_FUNCTION_GROUPS = 10, + PM_QID_PINCTRL_GET_PIN_GROUPS = 11, PM_QID_CLOCK_GET_NUM_CLOCKS = 12, PM_QID_CLOCK_GET_MAX_DIVISOR = 13, }; @@ -285,6 +297,44 @@ enum dll_reset_type { PM_DLL_RESET_PULSE = 2, }; +enum pm_pinctrl_config_param { + PM_PINCTRL_CONFIG_SLEW_RATE = 0, + PM_PINCTRL_CONFIG_BIAS_STATUS = 1, + PM_PINCTRL_CONFIG_PULL_CTRL = 2, + PM_PINCTRL_CONFIG_SCHMITT_CMOS = 3, + PM_PINCTRL_CONFIG_DRIVE_STRENGTH = 4, + PM_PINCTRL_CONFIG_VOLTAGE_STATUS = 5, + PM_PINCTRL_CONFIG_TRI_STATE = 6, + PM_PINCTRL_CONFIG_MAX = 7, +}; + +enum pm_pinctrl_slew_rate { + PM_PINCTRL_SLEW_RATE_FAST = 0, + PM_PINCTRL_SLEW_RATE_SLOW = 1, +}; + +enum pm_pinctrl_bias_status { + PM_PINCTRL_BIAS_DISABLE = 0, + PM_PINCTRL_BIAS_ENABLE = 1, +}; + +enum pm_pinctrl_pull_ctrl { + PM_PINCTRL_BIAS_PULL_DOWN = 0, + PM_PINCTRL_BIAS_PULL_UP = 1, +}; + +enum pm_pinctrl_schmitt_cmos { + PM_PINCTRL_INPUT_TYPE_CMOS = 0, + PM_PINCTRL_INPUT_TYPE_SCHMITT = 1, +}; + +enum pm_pinctrl_drive_strength { + PM_PINCTRL_DRIVE_STRENGTH_2MA = 0, + PM_PINCTRL_DRIVE_STRENGTH_4MA = 1, + PM_PINCTRL_DRIVE_STRENGTH_8MA = 2, + PM_PINCTRL_DRIVE_STRENGTH_12MA = 3, +}; + enum zynqmp_pm_shutdown_type { ZYNQMP_PM_SHUTDOWN_TYPE_SHUTDOWN = 0, ZYNQMP_PM_SHUTDOWN_TYPE_RESET = 1, @@ -353,6 +403,14 @@ int zynqmp_pm_write_pggs(u32 index, u32 value); int zynqmp_pm_read_pggs(u32 index, u32 *value); int zynqmp_pm_system_shutdown(const u32 type, const u32 subtype); int zynqmp_pm_set_boot_health_status(u32 value); +int zynqmp_pm_pinctrl_request(const u32 pin); +int zynqmp_pm_pinctrl_release(const u32 pin); +int zynqmp_pm_pinctrl_get_function(const u32 pin, u32 *id); +int zynqmp_pm_pinctrl_set_function(const u32 pin, const u32 id); +int zynqmp_pm_pinctrl_get_config(const u32 pin, const u32 param, + u32 *value); +int zynqmp_pm_pinctrl_set_config(const u32 pin, const u32 param, + u32 value); #else static inline struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops(void) { @@ -537,6 +595,38 @@ static inline int zynqmp_pm_set_boot_health_status(u32 value) { return -ENODEV; } + +static inline int zynqmp_pm_pinctrl_request(const u32 pin) +{ + return -ENODEV; +} + +static inline int zynqmp_pm_pinctrl_release(const u32 pin) +{ + return -ENODEV; +} + +static inline int zynqmp_pm_pinctrl_get_function(const u32 pin, u32 *id) +{ + return -ENODEV; +} + +static inline int zynqmp_pm_pinctrl_set_function(const u32 pin, const u32 id) +{ + return -ENODEV; +} + +static inline int zynqmp_pm_pinctrl_get_config(const u32 pin, const u32 param, + u32 *value) +{ + return -ENODEV; +} + +static inline int zynqmp_pm_pinctrl_set_config(const u32 pin, const u32 param, + u32 value) +{ + return -ENODEV; +} #endif #endif /* __FIRMWARE_ZYNQMP_H__ */ -- cgit v1.2.3 From 8b242ca700f8043be56542efd8360056358a42ed Mon Sep 17 00:00:00 2001 From: Sai Krishna Potthuri Date: Thu, 22 Apr 2021 14:00:02 +0530 Subject: pinctrl: Add Xilinx ZynqMP pinctrl driver support Adding pinctrl driver for Xilinx ZynqMP platform. This driver queries pin information from firmware and registers pin control accordingly. Signed-off-by: Sai Krishna Potthuri Link: https://lore.kernel.org/r/1619080202-31924-4-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 14 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-zynqmp.c | 906 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 921 insertions(+) create mode 100644 drivers/pinctrl/pinctrl-zynqmp.c diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 9502775afc11..c2c7e7963ed0 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -323,6 +323,20 @@ config PINCTRL_ZYNQ help This selects the pinctrl driver for Xilinx Zynq. +config PINCTRL_ZYNQMP + tristate "Pinctrl driver for Xilinx ZynqMP" + depends on ZYNQMP_FIRMWARE + select PINMUX + select GENERIC_PINCONF + default ZYNQMP_FIRMWARE + help + This selects the pinctrl driver for Xilinx ZynqMP platform. + This driver will query the pin information from the firmware + and allow configuring the pins. + Configuration can include the mux function to select on those + pin(s)/group(s), and various pin configuration parameters + such as pull-up, slew rate, etc. + config PINCTRL_INGENIC bool "Pinctrl driver for the Ingenic JZ47xx SoCs" default MACH_INGENIC diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 8bf459c32a76..5ef5334a797f 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o obj-$(CONFIG_PINCTRL_STMFX) += pinctrl-stmfx.o obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o +obj-$(CONFIG_PINCTRL_ZYNQMP) += pinctrl-zynqmp.o obj-$(CONFIG_PINCTRL_INGENIC) += pinctrl-ingenic.o obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o obj-$(CONFIG_PINCTRL_OCELOT) += pinctrl-ocelot.o diff --git a/drivers/pinctrl/pinctrl-zynqmp.c b/drivers/pinctrl/pinctrl-zynqmp.c new file mode 100644 index 000000000000..d5497003ce71 --- /dev/null +++ b/drivers/pinctrl/pinctrl-zynqmp.c @@ -0,0 +1,906 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ZynqMP pin controller + * + * Copyright (C) 2020 Xilinx, Inc. + * + * Sai Krishna Potthuri + * Rajan Vaja + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "core.h" +#include "pinctrl-utils.h" + +#define ZYNQMP_PIN_PREFIX "MIO" +#define PINCTRL_GET_FUNC_NAME_RESP_LEN 16 +#define MAX_FUNC_NAME_LEN 16 +#define MAX_GROUP_PIN 50 +#define MAX_PIN_GROUPS 50 +#define END_OF_FUNCTIONS "END_OF_FUNCTIONS" +#define NUM_GROUPS_PER_RESP 6 + +#define PINCTRL_GET_FUNC_GROUPS_RESP_LEN 12 +#define PINCTRL_GET_PIN_GROUPS_RESP_LEN 12 +#define NA_GROUP 0xFFFF +#define RESERVED_GROUP 0xFFFE + +#define DRIVE_STRENGTH_2MA 2 +#define DRIVE_STRENGTH_4MA 4 +#define DRIVE_STRENGTH_8MA 8 +#define DRIVE_STRENGTH_12MA 12 + +/** + * struct zynqmp_pmux_function - a pinmux function + * @name: Name of the pin mux function + * @groups: List of pin groups for this function + * @ngroups: Number of entries in @groups + * @node: Firmware node matching with the function + * + * This structure holds information about pin control function + * and function group names supporting that function. + */ +struct zynqmp_pmux_function { + char name[MAX_FUNC_NAME_LEN]; + const char * const *groups; + unsigned int ngroups; +}; + +/** + * struct zynqmp_pinctrl - driver data + * @pctrl: Pin control device + * @groups: Pin groups + * @ngroups: Number of @groups + * @funcs: Pin mux functions + * @nfuncs: Number of @funcs + * + * This struct is stored as driver data and used to retrieve + * information regarding pin control functions, groups and + * group pins. + */ +struct zynqmp_pinctrl { + struct pinctrl_dev *pctrl; + const struct zynqmp_pctrl_group *groups; + unsigned int ngroups; + const struct zynqmp_pmux_function *funcs; + unsigned int nfuncs; +}; + +/** + * struct zynqmp_pctrl_group - Pin control group info + * @name: Group name + * @pins: Group pin numbers + * @npins: Number of pins in the group + */ +struct zynqmp_pctrl_group { + const char *name; + unsigned int pins[MAX_GROUP_PIN]; + unsigned int npins; +}; + +static struct pinctrl_desc zynqmp_desc; + +static int zynqmp_pctrl_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + return pctrl->ngroups; +} + +static const char *zynqmp_pctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + return pctrl->groups[selector].name; +} + +static int zynqmp_pctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int selector, + const unsigned int **pins, + unsigned int *npins) +{ + struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + *pins = pctrl->groups[selector].pins; + *npins = pctrl->groups[selector].npins; + + return 0; +} + +static const struct pinctrl_ops zynqmp_pctrl_ops = { + .get_groups_count = zynqmp_pctrl_get_groups_count, + .get_group_name = zynqmp_pctrl_get_group_name, + .get_group_pins = zynqmp_pctrl_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_all, + .dt_free_map = pinctrl_utils_free_map, +}; + +static int zynqmp_pinmux_request_pin(struct pinctrl_dev *pctldev, + unsigned int pin) +{ + int ret; + + ret = zynqmp_pm_pinctrl_request(pin); + if (ret) { + dev_err(pctldev->dev, "request failed for pin %u\n", pin); + return ret; + } + + return 0; +} + +static int zynqmp_pmux_get_functions_count(struct pinctrl_dev *pctldev) +{ + struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + return pctrl->nfuncs; +} + +static const char *zynqmp_pmux_get_function_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + return pctrl->funcs[selector].name; +} + +/** + * zynqmp_pmux_get_function_groups() - Get groups for the function + * @pctldev: Pincontrol device pointer. + * @selector: Function ID + * @groups: Group names. + * @num_groups: Number of function groups. + * + * Get function's group count and group names. + */ +static int zynqmp_pmux_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int selector, + const char * const **groups, + unsigned * const num_groups) +{ + struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + *groups = pctrl->funcs[selector].groups; + *num_groups = pctrl->funcs[selector].ngroups; + + return 0; +} + +/** + * zynqmp_pinmux_set_mux() - Set requested function for the group + * @pctldev: Pincontrol device pointer. + * @function: Function ID. + * @group: Group ID. + * + * Loop through all pins of the group and call firmware API + * to set requested function for all pins in the group. + * + * Return: 0 on success else error code. + */ +static int zynqmp_pinmux_set_mux(struct pinctrl_dev *pctldev, + unsigned int function, + unsigned int group) +{ + struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + const struct zynqmp_pctrl_group *pgrp = &pctrl->groups[group]; + int ret, i; + + for (i = 0; i < pgrp->npins; i++) { + unsigned int pin = pgrp->pins[i]; + + ret = zynqmp_pm_pinctrl_set_function(pin, function); + if (ret) { + dev_err(pctldev->dev, "set mux failed for pin %u\n", + pin); + return ret; + } + } + + return 0; +} + +static int zynqmp_pinmux_release_pin(struct pinctrl_dev *pctldev, + unsigned int pin) +{ + int ret; + + ret = zynqmp_pm_pinctrl_release(pin); + if (ret) { + dev_err(pctldev->dev, "free pin failed for pin %u\n", + pin); + return ret; + } + + return 0; +} + +static const struct pinmux_ops zynqmp_pinmux_ops = { + .request = zynqmp_pinmux_request_pin, + .get_functions_count = zynqmp_pmux_get_functions_count, + .get_function_name = zynqmp_pmux_get_function_name, + .get_function_groups = zynqmp_pmux_get_function_groups, + .set_mux = zynqmp_pinmux_set_mux, + .free = zynqmp_pinmux_release_pin, +}; + +/** + * zynqmp_pinconf_cfg_get() - get config value for the pin + * @pctldev: Pin control device pointer. + * @pin: Pin number. + * @config: Value of config param. + * + * Get value of the requested configuration parameter for the + * given pin. + * + * Return: 0 on success else error code. + */ +static int zynqmp_pinconf_cfg_get(struct pinctrl_dev *pctldev, + unsigned int pin, + unsigned long *config) +{ + unsigned int arg, param = pinconf_to_config_param(*config); + int ret; + + if (pin >= zynqmp_desc.npins) + return -EOPNOTSUPP; + + switch (param) { + case PIN_CONFIG_SLEW_RATE: + param = PM_PINCTRL_CONFIG_SLEW_RATE; + ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); + break; + case PIN_CONFIG_BIAS_PULL_UP: + param = PM_PINCTRL_CONFIG_PULL_CTRL; + ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); + if (arg != PM_PINCTRL_BIAS_PULL_UP) + return -EINVAL; + + arg = 1; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + param = PM_PINCTRL_CONFIG_PULL_CTRL; + ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); + if (arg != PM_PINCTRL_BIAS_PULL_DOWN) + return -EINVAL; + + arg = 1; + break; + case PIN_CONFIG_BIAS_DISABLE: + param = PM_PINCTRL_CONFIG_BIAS_STATUS; + ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); + if (arg != PM_PINCTRL_BIAS_DISABLE) + return -EINVAL; + + arg = 1; + break; + case PIN_CONFIG_POWER_SOURCE: + param = PM_PINCTRL_CONFIG_VOLTAGE_STATUS; + ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); + break; + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + param = PM_PINCTRL_CONFIG_SCHMITT_CMOS; + ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); + break; + case PIN_CONFIG_DRIVE_STRENGTH: + param = PM_PINCTRL_CONFIG_DRIVE_STRENGTH; + ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); + switch (arg) { + case PM_PINCTRL_DRIVE_STRENGTH_2MA: + arg = DRIVE_STRENGTH_2MA; + break; + case PM_PINCTRL_DRIVE_STRENGTH_4MA: + arg = DRIVE_STRENGTH_4MA; + break; + case PM_PINCTRL_DRIVE_STRENGTH_8MA: + arg = DRIVE_STRENGTH_8MA; + break; + case PM_PINCTRL_DRIVE_STRENGTH_12MA: + arg = DRIVE_STRENGTH_12MA; + break; + default: + /* Invalid drive strength */ + dev_warn(pctldev->dev, + "Invalid drive strength for pin %d\n", + pin); + return -EINVAL; + } + break; + default: + ret = -EOPNOTSUPP; + break; + } + + if (ret) + return ret; + + param = pinconf_to_config_param(*config); + *config = pinconf_to_config_packed(param, arg); + + return 0; +} + +/** + * zynqmp_pinconf_cfg_set() - Set requested config for the pin + * @pctldev: Pincontrol device pointer. + * @pin: Pin number. + * @configs: Configuration to set. + * @num_configs: Number of configurations. + * + * Loop through all configurations and call firmware API + * to set requested configurations for the pin. + * + * Return: 0 on success else error code. + */ +static int zynqmp_pinconf_cfg_set(struct pinctrl_dev *pctldev, + unsigned int pin, unsigned long *configs, + unsigned int num_configs) +{ + int i, ret; + + if (pin >= zynqmp_desc.npins) + return -EOPNOTSUPP; + + for (i = 0; i < num_configs; i++) { + unsigned int param = pinconf_to_config_param(configs[i]); + unsigned int arg = pinconf_to_config_argument(configs[i]); + unsigned int value; + + switch (param) { + case PIN_CONFIG_SLEW_RATE: + param = PM_PINCTRL_CONFIG_SLEW_RATE; + ret = zynqmp_pm_pinctrl_set_config(pin, param, arg); + break; + case PIN_CONFIG_BIAS_PULL_UP: + param = PM_PINCTRL_CONFIG_PULL_CTRL; + arg = PM_PINCTRL_BIAS_PULL_UP; + ret = zynqmp_pm_pinctrl_set_config(pin, param, arg); + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + param = PM_PINCTRL_CONFIG_PULL_CTRL; + arg = PM_PINCTRL_BIAS_PULL_DOWN; + ret = zynqmp_pm_pinctrl_set_config(pin, param, arg); + break; + case PIN_CONFIG_BIAS_DISABLE: + param = PM_PINCTRL_CONFIG_BIAS_STATUS; + arg = PM_PINCTRL_BIAS_DISABLE; + ret = zynqmp_pm_pinctrl_set_config(pin, param, arg); + break; + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + param = PM_PINCTRL_CONFIG_SCHMITT_CMOS; + ret = zynqmp_pm_pinctrl_set_config(pin, param, arg); + break; + case PIN_CONFIG_DRIVE_STRENGTH: + switch (arg) { + case DRIVE_STRENGTH_2MA: + value = PM_PINCTRL_DRIVE_STRENGTH_2MA; + break; + case DRIVE_STRENGTH_4MA: + value = PM_PINCTRL_DRIVE_STRENGTH_4MA; + break; + case DRIVE_STRENGTH_8MA: + value = PM_PINCTRL_DRIVE_STRENGTH_8MA; + break; + case DRIVE_STRENGTH_12MA: + value = PM_PINCTRL_DRIVE_STRENGTH_12MA; + break; + default: + /* Invalid drive strength */ + dev_warn(pctldev->dev, + "Invalid drive strength for pin %d\n", + pin); + return -EINVAL; + } + + param = PM_PINCTRL_CONFIG_DRIVE_STRENGTH; + ret = zynqmp_pm_pinctrl_set_config(pin, param, value); + break; + case PIN_CONFIG_POWER_SOURCE: + param = PM_PINCTRL_CONFIG_VOLTAGE_STATUS; + ret = zynqmp_pm_pinctrl_get_config(pin, param, &value); + + if (arg != value) + dev_warn(pctldev->dev, + "Invalid IO Standard requested for pin %d\n", + pin); + + break; + case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: + case PIN_CONFIG_MODE_LOW_POWER: + /* + * These cases are mentioned in dts but configurable + * registers are unknown. So falling through to ignore + * boot time warnings as of now. + */ + ret = 0; + break; + default: + dev_warn(pctldev->dev, + "unsupported configuration parameter '%u'\n", + param); + ret = -EOPNOTSUPP; + break; + } + + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + if (ret) + dev_warn(pctldev->dev, + "failed to set: pin %u param %u value %u\n", + pin, param, arg); + } + + return 0; +} + +/** + * zynqmp_pinconf_group_set() - Set requested config for the group + * @pctldev: Pincontrol device pointer. + * @selector: Group ID. + * @configs: Configuration to set. + * @num_configs: Number of configurations. + * + * Call function to set configs for each pin in the group. + * + * Return: 0 on success else error code. + */ +static int zynqmp_pinconf_group_set(struct pinctrl_dev *pctldev, + unsigned int selector, + unsigned long *configs, + unsigned int num_configs) +{ + int i, ret; + struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + const struct zynqmp_pctrl_group *pgrp = &pctrl->groups[selector]; + + for (i = 0; i < pgrp->npins; i++) { + ret = zynqmp_pinconf_cfg_set(pctldev, pgrp->pins[i], configs, + num_configs); + if (ret) + return ret; + } + + return 0; +} + +static const struct pinconf_ops zynqmp_pinconf_ops = { + .is_generic = true, + .pin_config_get = zynqmp_pinconf_cfg_get, + .pin_config_set = zynqmp_pinconf_cfg_set, + .pin_config_group_set = zynqmp_pinconf_group_set, +}; + +static struct pinctrl_desc zynqmp_desc = { + .name = "zynqmp_pinctrl", + .owner = THIS_MODULE, + .pctlops = &zynqmp_pctrl_ops, + .pmxops = &zynqmp_pinmux_ops, + .confops = &zynqmp_pinconf_ops, +}; + +static int zynqmp_pinctrl_get_function_groups(u32 fid, u32 index, u16 *groups) +{ + struct zynqmp_pm_query_data qdata = {0}; + u32 payload[PAYLOAD_ARG_CNT]; + int ret; + + qdata.qid = PM_QID_PINCTRL_GET_FUNCTION_GROUPS; + qdata.arg1 = fid; + qdata.arg2 = index; + + ret = zynqmp_pm_query_data(qdata, payload); + if (ret) + return ret; + + memcpy(groups, &payload[1], PINCTRL_GET_FUNC_GROUPS_RESP_LEN); + + return ret; +} + +static int zynqmp_pinctrl_get_func_num_groups(u32 fid, unsigned int *ngroups) +{ + struct zynqmp_pm_query_data qdata = {0}; + u32 payload[PAYLOAD_ARG_CNT]; + int ret; + + qdata.qid = PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS; + qdata.arg1 = fid; + + ret = zynqmp_pm_query_data(qdata, payload); + if (ret) + return ret; + + *ngroups = payload[1]; + + return ret; +} + +/** + * zynqmp_pinctrl_prepare_func_groups() - prepare function and groups data + * @dev: Device pointer. + * @fid: Function ID. + * @func: Function data. + * @groups: Groups data. + * + * Query firmware to get group IDs for each function. Firmware returns + * group IDs. Based on group index for the function, group names in + * the function are stored. For example, the first group in "eth0" function + * is named as "eth0_0" and second group as "eth0_1" and so on. + * + * Based on the group ID received from the firmware, function stores name of + * the group for that group ID. For example, if "eth0" first group ID + * is x, groups[x] name will be stored as "eth0_0". + * + * Once done for each function, each function would have its group names + * and each groups would also have their names. + * + * Return: 0 on success else error code. + */ +static int zynqmp_pinctrl_prepare_func_groups(struct device *dev, u32 fid, + struct zynqmp_pmux_function *func, + struct zynqmp_pctrl_group *groups) +{ + u16 resp[NUM_GROUPS_PER_RESP] = {0}; + const char **fgroups; + int ret = 0, index, i; + + fgroups = devm_kzalloc(dev, sizeof(*fgroups) * func->ngroups, GFP_KERNEL); + if (!fgroups) + return -ENOMEM; + + for (index = 0; index < func->ngroups; index += NUM_GROUPS_PER_RESP) { + ret = zynqmp_pinctrl_get_function_groups(fid, index, resp); + if (ret) + return ret; + + for (i = 0; i < NUM_GROUPS_PER_RESP; i++) { + if (resp[i] == NA_GROUP) + goto done; + + if (resp[i] == RESERVED_GROUP) + continue; + + fgroups[index + i] = devm_kasprintf(dev, GFP_KERNEL, + "%s_%d_grp", + func->name, + index + i); + if (!fgroups[index + i]) + return -ENOMEM; + + groups[resp[i]].name = devm_kasprintf(dev, GFP_KERNEL, + "%s_%d_grp", + func->name, + index + i); + if (!groups[resp[i]].name) + return -ENOMEM; + } + } +done: + func->groups = fgroups; + + return ret; +} + +static void zynqmp_pinctrl_get_function_name(u32 fid, char *name) +{ + struct zynqmp_pm_query_data qdata = {0}; + u32 payload[PAYLOAD_ARG_CNT]; + + qdata.qid = PM_QID_PINCTRL_GET_FUNCTION_NAME; + qdata.arg1 = fid; + + /* + * Name of the function is maximum 16 bytes and cannot + * accommodate the return value in SMC buffers, hence ignoring + * the return value for this specific qid. + */ + zynqmp_pm_query_data(qdata, payload); + memcpy(name, payload, PINCTRL_GET_FUNC_NAME_RESP_LEN); +} + +static int zynqmp_pinctrl_get_num_functions(unsigned int *nfuncs) +{ + struct zynqmp_pm_query_data qdata = {0}; + u32 payload[PAYLOAD_ARG_CNT]; + int ret; + + qdata.qid = PM_QID_PINCTRL_GET_NUM_FUNCTIONS; + + ret = zynqmp_pm_query_data(qdata, payload); + if (ret) + return ret; + + *nfuncs = payload[1]; + + return ret; +} + +static int zynqmp_pinctrl_get_pin_groups(u32 pin, u32 index, u16 *groups) +{ + struct zynqmp_pm_query_data qdata = {0}; + u32 payload[PAYLOAD_ARG_CNT]; + int ret; + + qdata.qid = PM_QID_PINCTRL_GET_PIN_GROUPS; + qdata.arg1 = pin; + qdata.arg2 = index; + + ret = zynqmp_pm_query_data(qdata, payload); + if (ret) + return ret; + + memcpy(groups, &payload[1], PINCTRL_GET_PIN_GROUPS_RESP_LEN); + + return ret; +} + +static void zynqmp_pinctrl_group_add_pin(struct zynqmp_pctrl_group *group, + unsigned int pin) +{ + group->pins[group->npins++] = pin; +} + +/** + * zynqmp_pinctrl_create_pin_groups() - assign pins to respective groups + * @dev: Device pointer. + * @groups: Groups data. + * @pin: Pin number. + * + * Query firmware to get groups available for the given pin. + * Based on the firmware response(group IDs for the pin), add + * pin number to the respective group's pin array. + * + * Once all pins are queries, each groups would have its number + * of pins and pin numbers data. + * + * Return: 0 on success else error code. + */ +static int zynqmp_pinctrl_create_pin_groups(struct device *dev, + struct zynqmp_pctrl_group *groups, + unsigned int pin) +{ + u16 resp[NUM_GROUPS_PER_RESP] = {0}; + int ret, i, index = 0; + + do { + ret = zynqmp_pinctrl_get_pin_groups(pin, index, resp); + if (ret) + return ret; + + for (i = 0; i < NUM_GROUPS_PER_RESP; i++) { + if (resp[i] == NA_GROUP) + return ret; + + if (resp[i] == RESERVED_GROUP) + continue; + + zynqmp_pinctrl_group_add_pin(&groups[resp[i]], pin); + } + index += NUM_GROUPS_PER_RESP; + } while (index <= MAX_PIN_GROUPS); + + return ret; +} + +/** + * zynqmp_pinctrl_prepare_group_pins() - prepare each group's pin data + * @dev: Device pointer. + * @groups: Groups data. + * @ngroups: Number of groups. + * + * Prepare pin number and number of pins data for each pins. + * + * Return: 0 on success else error code. + */ +static int zynqmp_pinctrl_prepare_group_pins(struct device *dev, + struct zynqmp_pctrl_group *groups, + unsigned int ngroups) +{ + unsigned int pin; + int ret; + + for (pin = 0; pin < zynqmp_desc.npins; pin++) { + ret = zynqmp_pinctrl_create_pin_groups(dev, groups, pin); + if (ret) + return ret; + } + + return 0; +} + +/** + * zynqmp_pinctrl_prepare_function_info() - prepare function info + * @dev: Device pointer. + * @pctrl: Pin control driver data. + * + * Query firmware for functions, groups and pin information and + * prepare pin control driver data. + * + * Query number of functions and number of function groups (number + * of groups in given function) to allocate required memory buffers + * for functions and groups. Once buffers are allocated to store + * functions and groups data, query and store required information + * (number of groups and group names for each function, number of + * pins and pin numbers for each group). + * + * Return: 0 on success else error code. + */ +static int zynqmp_pinctrl_prepare_function_info(struct device *dev, + struct zynqmp_pinctrl *pctrl) +{ + struct zynqmp_pmux_function *funcs; + struct zynqmp_pctrl_group *groups; + int ret, i; + + ret = zynqmp_pinctrl_get_num_functions(&pctrl->nfuncs); + if (ret) + return ret; + + funcs = devm_kzalloc(dev, sizeof(*funcs) * pctrl->nfuncs, GFP_KERNEL); + if (!funcs) + return -ENOMEM; + + for (i = 0; i < pctrl->nfuncs; i++) { + zynqmp_pinctrl_get_function_name(i, funcs[i].name); + + ret = zynqmp_pinctrl_get_func_num_groups(i, &funcs[i].ngroups); + if (ret) + return ret; + + pctrl->ngroups += funcs[i].ngroups; + } + + groups = devm_kzalloc(dev, sizeof(*groups) * pctrl->ngroups, GFP_KERNEL); + if (!groups) + return -ENOMEM; + + for (i = 0; i < pctrl->nfuncs; i++) { + ret = zynqmp_pinctrl_prepare_func_groups(dev, i, &funcs[i], + groups); + if (ret) + return ret; + } + + ret = zynqmp_pinctrl_prepare_group_pins(dev, groups, pctrl->ngroups); + if (ret) + return ret; + + pctrl->funcs = funcs; + pctrl->groups = groups; + + return ret; +} + +static int zynqmp_pinctrl_get_num_pins(unsigned int *npins) +{ + struct zynqmp_pm_query_data qdata = {0}; + u32 payload[PAYLOAD_ARG_CNT]; + int ret; + + qdata.qid = PM_QID_PINCTRL_GET_NUM_PINS; + + ret = zynqmp_pm_query_data(qdata, payload); + if (ret) + return ret; + + *npins = payload[1]; + + return ret; +} + +/** + * zynqmp_pinctrl_prepare_pin_desc() - prepare pin description info + * @dev: Device pointer. + * @zynqmp_pins: Pin information. + * @npins: Number of pins. + * + * Query number of pins information from firmware and prepare pin + * description containing pin number and pin name. + * + * Return: 0 on success else error code. + */ +static int zynqmp_pinctrl_prepare_pin_desc(struct device *dev, + const struct pinctrl_pin_desc + **zynqmp_pins, + unsigned int *npins) +{ + struct pinctrl_pin_desc *pins, *pin; + int ret; + int i; + + ret = zynqmp_pinctrl_get_num_pins(npins); + if (ret) + return ret; + + pins = devm_kzalloc(dev, sizeof(*pins) * *npins, GFP_KERNEL); + if (!pins) + return -ENOMEM; + + for (i = 0; i < *npins; i++) { + pin = &pins[i]; + pin->number = i; + pin->name = devm_kasprintf(dev, GFP_KERNEL, "%s%d", + ZYNQMP_PIN_PREFIX, i); + if (!pin->name) + return -ENOMEM; + } + + *zynqmp_pins = pins; + + return 0; +} + +static int zynqmp_pinctrl_probe(struct platform_device *pdev) +{ + struct zynqmp_pinctrl *pctrl; + int ret; + + pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL); + if (!pctrl) + return -ENOMEM; + + ret = zynqmp_pinctrl_prepare_pin_desc(&pdev->dev, + &zynqmp_desc.pins, + &zynqmp_desc.npins); + if (ret) { + dev_err(&pdev->dev, "pin desc prepare fail with %d\n", + ret); + return ret; + } + + ret = zynqmp_pinctrl_prepare_function_info(&pdev->dev, pctrl); + if (ret) { + dev_err(&pdev->dev, "function info prepare fail with %d\n", + ret); + return ret; + } + + pctrl->pctrl = pinctrl_register(&zynqmp_desc, &pdev->dev, pctrl); + if (IS_ERR(pctrl->pctrl)) + return PTR_ERR(pctrl->pctrl); + + platform_set_drvdata(pdev, pctrl); + + return ret; +} + +static int zynqmp_pinctrl_remove(struct platform_device *pdev) +{ + struct zynqmp_pinctrl *pctrl = platform_get_drvdata(pdev); + + pinctrl_unregister(pctrl->pctrl); + + return 0; +} + +static const struct of_device_id zynqmp_pinctrl_of_match[] = { + { .compatible = "xlnx,zynqmp-pinctrl" }, + { } +}; + +MODULE_DEVICE_TABLE(of, zynqmp_pinctrl_of_match); + +static struct platform_driver zynqmp_pinctrl_driver = { + .driver = { + .name = "zynqmp-pinctrl", + .of_match_table = zynqmp_pinctrl_of_match, + }, + .probe = zynqmp_pinctrl_probe, + .remove = zynqmp_pinctrl_remove, +}; + +module_platform_driver(zynqmp_pinctrl_driver); + +MODULE_AUTHOR("Sai Krishna Potthuri "); +MODULE_DESCRIPTION("ZynqMP Pin Controller Driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3