This is the bulk of pin control changes for the v5.7 kernel cycle.

There are no core changes this time, only driver developments.
 
 - New driver for the Dialog Semiconductor DA9062 Power Management
   Integrated Circuit (PMIC).
 
 - Renesas SH-PFC has improved consistency, with group and
   register checks in the configuration checker.
 
 - New subdriver for the Qualcomm IPQ6018.
 
 - Add the RGMII pin control functionality to Qualcomm IPQ8064.
 
 - Performance and code quality cleanups in the Mediatek
   driver.
 
 - Improve the Broadcom BCM2835 support to cover all the GPIOs
   that exist in it.
 
 - The Allwinner/Sunxi driver properly masks non-wakeup IRQs on
   suspend.
 
 - Add some missing groups and functions to the Ingenic driver.
 
 - Convert some of the Freescale device tree bindings to use the
   new and all improved JSON YAML markup.
 
 - Refactorings and support for the SFIO/GPIO in the Tegra194
   SoC driver.
 
 - Support high impedance mode in the Spreadtrum/Unisoc driver.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEElDRnuGcz/wPCXQWMQRCzN7AZXXMFAl6FlRoACgkQQRCzN7AZ
 XXPiAxAAuAvY07H739YF4ANvtLpfbtz0KBK4M2XGiD41VMcp5MhZtT9TdXAIRisb
 W4QMHbMxhwO4gdxmhVOetXeQNQnHch4oPsFyd1UdyuwNEtvlm8qst99VcdQPz7Jv
 zyL4cat1fTrwdcnLQl5eaJR7a9bKLqAd4rlb/suQZsaVf+URUWJyZBuU41GEx9A+
 w+EPv8doxTWRaE0NpafIwNCLxTR3i2Vt59fkRT4pSi8fTu9/Zv5yW8yWvbYZdlaO
 2bUaFjN65oyiikjPTgyQxb95A8yDJHkNnkgfTw4ghCY/k8u3GvMfKS7V1tO+nq6B
 bkv9E3jR1u7Ktkq1rLshS2eycl02uSJ3OmzyfL8S/GQxVdUPi3+X3hmyv2ctbEvC
 qy+7F6zx/Pt/WdPnAisdsVai9T3/YGoSN1C3n7Ufltjcrt0w5xP7/AgEVR4nHHMP
 NMWNoauGWsBDKtYPG7beX3thjkm3mUpezcEOxho7+r5tOtBaU623pWr+NHEPZu48
 8oKOCILaUkacUmmMjjOzraAeOxV7Ut+xumu0mgMj0EjZfJZDrgQsqkmfMbGcU5Fa
 y4S5+tAd+cELXveLVJB3Ml9u1R037x8VtAv+Z2a7qVnf1gSgf0bpAJ+SnfC/XbLX
 fBpSCsIMXSpioVNuS9gbkpnfsRPcTOrOXyxinP5onI8AHlIj1Rg=
 =1ZKq
 -----END PGP SIGNATURE-----

Merge tag 'pinctrl-v5.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl

Pull pin control updates from Linus Walleij:
 "This is the bulk of pin control changes for the v5.7 kernel cycle.

  There are no core changes this time, only driver developments:

   - New driver for the Dialog Semiconductor DA9062 Power Management
     Integrated Circuit (PMIC).

   - Renesas SH-PFC has improved consistency, with group and register
     checks in the configuration checker.

   - New subdriver for the Qualcomm IPQ6018.

   - Add the RGMII pin control functionality to Qualcomm IPQ8064.

   - Performance and code quality cleanups in the Mediatek driver.

   - Improve the Broadcom BCM2835 support to cover all the GPIOs that
     exist in it.

   - The Allwinner/Sunxi driver properly masks non-wakeup IRQs on
     suspend.

   - Add some missing groups and functions to the Ingenic driver.

   - Convert some of the Freescale device tree bindings to use the new
     and all improved JSON YAML markup.

   - Refactorings and support for the SFIO/GPIO in the Tegra194 SoC
     driver.

   - Support high impedance mode in the Spreadtrum/Unisoc driver"

* tag 'pinctrl-v5.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (64 commits)
  pinctrl: qcom: fix compilation error
  pinctrl: qcom: use scm_call to route GPIO irq to Apps
  pinctrl: sprd: Add pin high impedance mode support
  pinctrl: sprd: Use the correct pin output configuration
  pinctrl: tegra: Add SFIO/GPIO programming on Tegra194
  pinctrl: tegra: Renumber the GG.0 and GG.1 pins
  pinctrl: tegra: Do not add default pin range on Tegra194
  pinctrl: tegra: Pass struct tegra_pmx for pin range check
  pinctrl: tegra: Fix "Scmitt" -> "Schmitt" typo
  pinctrl: tegra: Fix whitespace issues for improved readability
  pinctrl: mediatek: Use scnprintf() for avoiding potential buffer overflow
  pinctrl: freescale: drop the dependency on ARM64 for i.MX8M
  Revert "pinctrl: mvebu: armada-37xx: use use platform api"
  dt-bindings: pinctrl: at91: Fix a typo ("descibe")
  pinctrl: meson: add tsin pinctrl for meson gxbb/gxl/gxm
  pinctrl: sprd: Fix the kconfig warning
  pinctrl: ingenic: add hdmi-ddc pin control group
  pinctrl: sirf/atlas7: Replace zero-length array with flexible-array member
  pinctrl: sprd: Allow the SPRD pinctrl driver building into a module
  pinctrl: Export some needed symbols at module load time
  ...
This commit is contained in:
Linus Torvalds 2020-04-02 15:47:18 -07:00
commit bc3b3f4bfb
64 changed files with 3365 additions and 758 deletions

View File

@ -38,7 +38,7 @@ Bank: 3 (A, B and C)
0xffffffff 0x7fff3ccf /* pioB */
0xffffffff 0x007fffff /* pioC */
For each peripheral/bank we will descibe in a u32 if a pin can be
For each peripheral/bank we will describe in a u32 if a pin can be
configured in it by putting 1 to the pin bit (1 << pin)
Let's take the pioA on peripheral B

View File

@ -1,36 +0,0 @@
* Freescale IMX8MM IOMUX Controller
Please refer to fsl,imx-pinctrl.txt and pinctrl-bindings.txt in this directory
for common binding part and usage.
Required properties:
- compatible: "fsl,imx8mm-iomuxc"
- reg: should contain the base physical address and size of the iomuxc
registers.
Required properties in sub-nodes:
- fsl,pins: each entry consists of 6 integers and represents the mux and config
setting for one pin. The first 5 integers <mux_reg conf_reg input_reg mux_val
input_val> are specified using a PIN_FUNC_ID macro, which can be found in
<arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h>. The last integer CONFIG is
the pad setting value like pull-up on this pin. Please refer to i.MX8M Mini
Reference Manual for detailed CONFIG settings.
Examples:
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
};
iomuxc: pinctrl@30330000 {
compatible = "fsl,imx8mm-iomuxc";
reg = <0x0 0x30330000 0x0 0x10000>;
pinctrl_uart1: uart1grp {
fsl,pins = <
MX8MM_IOMUXC_UART1_RXD_UART1_DCE_RX 0x140
MX8MM_IOMUXC_UART1_TXD_UART1_DCE_TX 0x140
>;
};
};

View File

@ -0,0 +1,82 @@
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/fsl,imx8mm-pinctrl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale IMX8MM IOMUX Controller
maintainers:
- Anson Huang <Anson.Huang@nxp.com>
description:
Please refer to fsl,imx-pinctrl.txt and pinctrl-bindings.txt in this directory
for common binding part and usage.
properties:
compatible:
const: fsl,imx8mm-iomuxc
reg:
maxItems: 1
# Client device subnode's properties
patternProperties:
'grp$':
type: object
description:
Pinctrl node's client devices use subnodes for desired pin configuration.
Client device subnodes use below standard properties.
properties:
fsl,pins:
description:
each entry consists of 6 integers and represents the mux and config
setting for one pin. The first 5 integers <mux_reg conf_reg input_reg
mux_val input_val> are specified using a PIN_FUNC_ID macro, which can
be found in <arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h>. The last
integer CONFIG is the pad setting value like pull-up on this pin. Please
refer to i.MX8M Mini Reference Manual for detailed CONFIG settings.
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32-matrix
- items:
items:
- description: |
"mux_reg" indicates the offset of mux register.
- description: |
"conf_reg" indicates the offset of pad configuration register.
- description: |
"input_reg" indicates the offset of select input register.
- description: |
"mux_val" indicates the mux value to be applied.
- description: |
"input_val" indicates the select input value to be applied.
- description: |
"pad_setting" indicates the pad configuration value to be applied.
required:
- fsl,pins
additionalProperties: false
required:
- compatible
- reg
additionalProperties: false
examples:
# Pinmux controller node
- |
iomuxc: pinctrl@30330000 {
compatible = "fsl,imx8mm-iomuxc";
reg = <0x30330000 0x10000>;
pinctrl_uart2: uart2grp {
fsl,pins =
<0x23C 0x4A4 0x4FC 0x0 0x0 0x140>,
<0x240 0x4A8 0x000 0x0 0x0 0x140>;
};
};
...

View File

@ -1,39 +0,0 @@
* Freescale IMX8MN IOMUX Controller
Please refer to fsl,imx-pinctrl.txt and pinctrl-bindings.txt in this directory
for common binding part and usage.
Required properties:
- compatible: "fsl,imx8mn-iomuxc"
- reg: should contain the base physical address and size of the iomuxc
registers.
Required properties in sub-nodes:
- fsl,pins: each entry consists of 6 integers and represents the mux and config
setting for one pin. The first 5 integers <mux_reg conf_reg input_reg mux_val
input_val> are specified using a PIN_FUNC_ID macro, which can be found in
<arch/arm64/boot/dts/freescale/imx8mn-pinfunc.h>. The last integer CONFIG is
the pad setting value like pull-up on this pin. Please refer to i.MX8M Nano
Reference Manual for detailed CONFIG settings.
Examples:
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
};
iomuxc: pinctrl@30330000 {
compatible = "fsl,imx8mn-iomuxc";
reg = <0x0 0x30330000 0x0 0x10000>;
pinctrl_uart1: uart1grp {
fsl,pins = <
MX8MN_IOMUXC_UART1_RXD_UART1_DCE_RX 0x140
MX8MN_IOMUXC_UART1_TXD_UART1_DCE_TX 0x140
MX8MN_IOMUXC_UART3_RXD_UART1_DCE_CTS_B 0x140
MX8MN_IOMUXC_UART3_TXD_UART1_DCE_RTS_B 0x140
MX8MN_IOMUXC_SD1_DATA4_GPIO2_IO6 0x19
>;
};
};

View File

@ -0,0 +1,82 @@
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/fsl,imx8mn-pinctrl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale IMX8MN IOMUX Controller
maintainers:
- Anson Huang <Anson.Huang@nxp.com>
description:
Please refer to fsl,imx-pinctrl.txt and pinctrl-bindings.txt in this directory
for common binding part and usage.
properties:
compatible:
const: fsl,imx8mn-iomuxc
reg:
maxItems: 1
# Client device subnode's properties
patternProperties:
'grp$':
type: object
description:
Pinctrl node's client devices use subnodes for desired pin configuration.
Client device subnodes use below standard properties.
properties:
fsl,pins:
description:
each entry consists of 6 integers and represents the mux and config
setting for one pin. The first 5 integers <mux_reg conf_reg input_reg
mux_val input_val> are specified using a PIN_FUNC_ID macro, which can
be found in <arch/arm64/boot/dts/freescale/imx8mn-pinfunc.h>. The last
integer CONFIG is the pad setting value like pull-up on this pin. Please
refer to i.MX8M Nano Reference Manual for detailed CONFIG settings.
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32-matrix
- items:
items:
- description: |
"mux_reg" indicates the offset of mux register.
- description: |
"conf_reg" indicates the offset of pad configuration register.
- description: |
"input_reg" indicates the offset of select input register.
- description: |
"mux_val" indicates the mux value to be applied.
- description: |
"input_val" indicates the select input value to be applied.
- description: |
"pad_setting" indicates the pad configuration value to be applied.
required:
- fsl,pins
additionalProperties: false
required:
- compatible
- reg
additionalProperties: false
examples:
# Pinmux controller node
- |
iomuxc: pinctrl@30330000 {
compatible = "fsl,imx8mn-iomuxc";
reg = <0x30330000 0x10000>;
pinctrl_uart2: uart2grp {
fsl,pins =
<0x23C 0x4A4 0x4FC 0x0 0x0 0x140>,
<0x240 0x4A8 0x000 0x0 0x0 0x140>;
};
};
...

View File

@ -30,8 +30,6 @@ patternProperties:
properties:
fsl,pins:
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32-array
description:
each entry consists of 6 integers and represents the mux and config
setting for one pin. The first 5 integers <mux_reg conf_reg input_reg
@ -39,6 +37,22 @@ patternProperties:
be found in <arch/arm64/boot/dts/freescale/imx8mp-pinfunc.h>. The last
integer CONFIG is the pad setting value like pull-up on this pin. Please
refer to i.MX8M Plus Reference Manual for detailed CONFIG settings.
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32-matrix
- items:
items:
- description: |
"mux_reg" indicates the offset of mux register.
- description: |
"conf_reg" indicates the offset of pad configuration register.
- description: |
"input_reg" indicates the offset of select input register.
- description: |
"mux_val" indicates the mux value to be applied.
- description: |
"input_val" indicates the select input value to be applied.
- description: |
"pad_setting" indicates the pad configuration value to be applied.
required:
- fsl,pins
@ -59,10 +73,9 @@ examples:
reg = <0x30330000 0x10000>;
pinctrl_uart2: uart2grp {
fsl,pins = <
0x228 0x488 0x5F0 0x0 0x6 0x49
0x228 0x488 0x000 0x0 0x0 0x49
>;
fsl,pins =
<0x228 0x488 0x5F0 0x0 0x6 0x49>,
<0x228 0x488 0x000 0x0 0x0 0x49>;
};
};

View File

@ -1,36 +0,0 @@
* Freescale IMX8MQ IOMUX Controller
Please refer to fsl,imx-pinctrl.txt and pinctrl-bindings.txt in this directory
for common binding part and usage.
Required properties:
- compatible: "fsl,imx8mq-iomuxc"
- reg: should contain the base physical address and size of the iomuxc
registers.
Required properties in sub-nodes:
- fsl,pins: each entry consists of 6 integers and represents the mux and config
setting for one pin. The first 5 integers <mux_reg conf_reg input_reg mux_val
input_val> are specified using a PIN_FUNC_ID macro, which can be found in
imx8mq-pinfunc.h under device tree source folder. The last integer CONFIG is
the pad setting value like pull-up on this pin. Please refer to i.MX8M Quad
Reference Manual for detailed CONFIG settings.
Examples:
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
};
iomuxc: pinctrl@30330000 {
compatible = "fsl,imx8mq-iomuxc";
reg = <0x0 0x30330000 0x0 0x10000>;
pinctrl_uart1: uart1grp {
fsl,pins = <
MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX 0x49
MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX 0x49
>;
};
};

View File

@ -0,0 +1,82 @@
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/fsl,imx8mq-pinctrl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale IMX8MQ IOMUX Controller
maintainers:
- Anson Huang <Anson.Huang@nxp.com>
description:
Please refer to fsl,imx-pinctrl.txt and pinctrl-bindings.txt in this directory
for common binding part and usage.
properties:
compatible:
const: fsl,imx8mq-iomuxc
reg:
maxItems: 1
# Client device subnode's properties
patternProperties:
'grp$':
type: object
description:
Pinctrl node's client devices use subnodes for desired pin configuration.
Client device subnodes use below standard properties.
properties:
fsl,pins:
description:
each entry consists of 6 integers and represents the mux and config
setting for one pin. The first 5 integers <mux_reg conf_reg input_reg
mux_val input_val> are specified using a PIN_FUNC_ID macro, which can
be found in <arch/arm64/boot/dts/freescale/imx8mq-pinfunc.h>. The last
integer CONFIG is the pad setting value like pull-up on this pin. Please
refer to i.MX8M Quad Reference Manual for detailed CONFIG settings.
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32-matrix
- items:
items:
- description: |
"mux_reg" indicates the offset of mux register.
- description: |
"conf_reg" indicates the offset of pad configuration register.
- description: |
"input_reg" indicates the offset of select input register.
- description: |
"mux_val" indicates the mux value to be applied.
- description: |
"input_val" indicates the select input value to be applied.
- description: |
"pad_setting" indicates the pad configuration value to be applied.
required:
- fsl,pins
additionalProperties: false
required:
- compatible
- reg
additionalProperties: false
examples:
# Pinmux controller node
- |
iomuxc: pinctrl@30330000 {
compatible = "fsl,imx8mq-iomuxc";
reg = <0x30330000 0x10000>;
pinctrl_uart1: uart1grp {
fsl,pins =
<0x234 0x49C 0x4F4 0x0 0x0 0x49>,
<0x238 0x4A0 0x4F4 0x0 0x0 0x49>;
};
};
...

View File

@ -0,0 +1,153 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/qcom,ipq6018-pinctrl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Technologies, Inc. IPQ6018 TLMM block
maintainers:
- Sricharan R <sricharan@codeaurora.org>
description: |
This binding describes the Top Level Mode Multiplexer block found in the
IPQ6018 platform.
properties:
compatible:
const: qcom,ipq6018-pinctrl
reg:
maxItems: 1
interrupts:
description: Specifies the TLMM summary IRQ
maxItems: 1
interrupt-controller: true
'#interrupt-cells':
description:
Specifies the PIN numbers and Flags, as defined in defined in
include/dt-bindings/interrupt-controller/irq.h
const: 2
gpio-controller: true
'#gpio-cells':
description: Specifying the pin number and flags, as defined in
include/dt-bindings/gpio/gpio.h
const: 2
gpio-ranges:
maxItems: 1
#PIN CONFIGURATION NODES
patternProperties:
'-pinmux$':
type: object
description:
Pinctrl node's client devices use subnodes for desired pin configuration.
Client device subnodes use below standard properties.
allOf:
- $ref: "/schemas/pinctrl/pincfg-node.yaml"
properties:
pins:
description:
List of gpio pins affected by the properties specified in this
subnode.
items:
oneOf:
- pattern: "^gpio([1-9]|[1-7][0-9]|80)$"
- enum: [ sdc1_clk, sdc1_cmd, sdc1_data, sdc2_clk, sdc2_cmd,
sdc2_data, qdsd_cmd, qdsd_data0, qdsd_data1, qdsd_data2,
qdsd_data3 ]
minItems: 1
maxItems: 4
function:
description:
Specify the alternative function to be configured for the specified
pins.
enum: [ adsp_ext, alsp_int, atest_bbrx0, atest_bbrx1, atest_char,
atest_char0, atest_char1, atest_char2, atest_char3, atest_combodac,
atest_gpsadc0, atest_gpsadc1, atest_tsens, atest_wlan0,
atest_wlan1, backlight_en, bimc_dte0, bimc_dte1, blsp1_i2c,
blsp2_i2c, blsp3_i2c, blsp4_i2c, blsp5_i2c, blsp6_i2c, blsp1_spi,
blsp1_spi_cs1, blsp1_spi_cs2, blsp1_spi_cs3, blsp2_spi,
blsp2_spi_cs1, blsp2_spi_cs2, blsp2_spi_cs3, blsp3_spi,
blsp3_spi_cs1, blsp3_spi_cs2, blsp3_spi_cs3, blsp4_spi, blsp5_spi,
blsp6_spi, blsp1_uart, blsp2_uart, blsp1_uim, blsp2_uim, cam1_rst,
cam1_standby, cam_mclk0, cam_mclk1, cci_async, cci_i2c, cci_timer0,
cci_timer1, cci_timer2, cdc_pdm0, codec_mad, dbg_out, display_5v,
dmic0_clk, dmic0_data, dsi_rst, ebi0_wrcdc, euro_us, ext_lpass,
flash_strobe, gcc_gp1_clk_a, gcc_gp1_clk_b, gcc_gp2_clk_a,
gcc_gp2_clk_b, gcc_gp3_clk_a, gcc_gp3_clk_b, gpio, gsm0_tx0,
gsm0_tx1, gsm1_tx0, gsm1_tx1, gyro_accl, kpsns0, kpsns1, kpsns2,
ldo_en, ldo_update, mag_int, mdp_vsync, modem_tsync, m_voc,
nav_pps, nav_tsync, pa_indicator, pbs0, pbs1, pbs2, pri_mi2s,
pri_mi2s_ws, prng_rosc, pwr_crypto_enabled_a, pwr_crypto_enabled_b,
pwr_modem_enabled_a, pwr_modem_enabled_b, pwr_nav_enabled_a,
pwr_nav_enabled_b, qdss_ctitrig_in_a0, qdss_ctitrig_in_a1,
qdss_ctitrig_in_b0, qdss_ctitrig_in_b1, qdss_ctitrig_out_a0,
qdss_ctitrig_out_a1, qdss_ctitrig_out_b0, qdss_ctitrig_out_b1,
qdss_traceclk_a, qdss_traceclk_b, qdss_tracectl_a, qdss_tracectl_b,
qdss_tracedata_a, qdss_tracedata_b, reset_n, sd_card, sd_write,
sec_mi2s, smb_int, ssbi_wtr0, ssbi_wtr1, uim1, uim2, uim3,
uim_batt, wcss_bt, wcss_fm, wcss_wlan, webcam1_rst ]
drive-strength:
enum: [2, 4, 6, 8, 10, 12, 14, 16]
default: 2
description:
Selects the drive strength for the specified pins, in mA.
bias-pull-down: true
bias-pull-up: true
bias-disable: true
output-high: true
output-low: true
required:
- pins
- function
additionalProperties: false
required:
- compatible
- reg
- interrupts
- interrupt-controller
- '#interrupt-cells'
- gpio-controller
- '#gpio-cells'
- gpio-ranges
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
tlmm: pinctrl@1000000 {
compatible = "qcom,ipq6018-pinctrl";
reg = <0x01000000 0x300000>;
interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <2>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&tlmm 0 80>;
serial3-pinmux {
pins = "gpio44", "gpio45";
function = "blsp2_uart";
drive-strength = <8>;
bias-pull-down;
};
};

View File

@ -2743,8 +2743,8 @@ L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers)
L: openbmc@lists.ozlabs.org (moderated for non-subscribers)
L: linux-gpio@vger.kernel.org
S: Maintained
F: drivers/pinctrl/aspeed/
F: Documentation/devicetree/bindings/pinctrl/aspeed,*
F: drivers/pinctrl/aspeed/
ASPEED SCU INTERRUPT CONTROLLER DRIVER
M: Eddie James <eajames@linux.ibm.com>
@ -4958,6 +4958,7 @@ F: drivers/leds/leds-da90??.c
F: drivers/mfd/da903x.c
F: drivers/mfd/da90??-*.c
F: drivers/mfd/da91??-*.c
F: drivers/pinctrl/pinctrl-da90??.c
F: drivers/power/supply/da9052-battery.c
F: drivers/power/supply/da91??-*.c
F: drivers/regulator/da903x.c
@ -13267,21 +13268,13 @@ K: \b(clone_args|kernel_clone_args)\b
PIN CONTROL SUBSYSTEM
M: Linus Walleij <linus.walleij@linaro.org>
L: linux-gpio@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git
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: drivers/pinctrl/
F: include/linux/pinctrl/
PIN CONTROLLER - MICROCHIP AT91
M: Ludovic Desroches <ludovic.desroches@microchip.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-gpio@vger.kernel.org
S: Supported
F: drivers/pinctrl/pinctrl-at91*
F: drivers/gpio/gpio-sama5d2-piobu.c
PIN CONTROLLER - FREESCALE
M: Dong Aisheng <aisheng.dong@nxp.com>
M: Fabio Estevam <festevam@gmail.com>
@ -13290,14 +13283,14 @@ M: Stefan Agner <stefan@agner.ch>
R: Pengutronix Kernel Team <kernel@pengutronix.de>
L: linux-gpio@vger.kernel.org
S: Maintained
F: drivers/pinctrl/freescale/
F: Documentation/devicetree/bindings/pinctrl/fsl,*
F: drivers/pinctrl/freescale/
PIN CONTROLLER - INTEL
M: Mika Westerberg <mika.westerberg@linux.intel.com>
M: Andy Shevchenko <andy@kernel.org>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git
F: drivers/pinctrl/intel/
PIN CONTROLLER - MEDIATEK
@ -13308,18 +13301,26 @@ F: Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
F: Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
F: drivers/pinctrl/mediatek/
PIN CONTROLLER - MICROCHIP AT91
M: Ludovic Desroches <ludovic.desroches@microchip.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-gpio@vger.kernel.org
S: Supported
F: drivers/gpio/gpio-sama5d2-piobu.c
F: drivers/pinctrl/pinctrl-at91*
PIN CONTROLLER - QUALCOMM
M: Bjorn Andersson <bjorn.andersson@linaro.org>
S: Maintained
L: linux-arm-msm@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/pinctrl/qcom,*.txt
F: drivers/pinctrl/qcom/
PIN CONTROLLER - RENESAS
M: Geert Uytterhoeven <geert+renesas@glider.be>
L: linux-renesas-soc@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git sh-pfc
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git sh-pfc
F: drivers/pinctrl/pinctrl-rz*
F: drivers/pinctrl/sh-pfc/
@ -13329,12 +13330,12 @@ M: Krzysztof Kozlowski <krzk@kernel.org>
M: Sylwester Nawrocki <s.nawrocki@samsung.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
Q: https://patchwork.kernel.org/project/linux-samsung-soc/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git
Q: https://patchwork.kernel.org/project/linux-samsung-soc/list/
F: Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
F: drivers/pinctrl/samsung/
F: include/dt-bindings/pinctrl/samsung.h
F: Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
PIN CONTROLLER - SINGLE
M: Tony Lindgren <tony@atomide.com>
@ -13347,8 +13348,8 @@ F: drivers/pinctrl/pinctrl-single.c
PIN CONTROLLER - ST SPEAR
M: Viresh Kumar <vireshk@kernel.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
W: http://www.st.com/spear
S: Maintained
W: http://www.st.com/spear
F: drivers/pinctrl/spear/
PISTACHIO SOC SUPPORT

View File

@ -149,6 +149,7 @@ struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip,
return &gdev->descs[hwnum];
}
EXPORT_SYMBOL_GPL(gpiochip_get_desc);
/**
* desc_to_gpio - convert a GPIO descriptor to the integer namespace

View File

@ -126,6 +126,18 @@ config PINCTRL_DA850_PUPD
Driver for TI DA850/OMAP-L138/AM18XX pinconf. Used to control
pullup/pulldown pin groups.
config PINCTRL_DA9062
tristate "Dialog Semiconductor DA9062 PMIC pinctrl and GPIO Support"
depends on MFD_DA9062
select GPIOLIB
help
The Dialog DA9062 PMIC provides multiple GPIOs that can be muxed for
different functions. This driver bundles a pinctrl driver to select the
function muxing and a GPIO driver to handle the GPIO when the GPIO
function is selected.
Say yes to enable pinctrl and GPIO support for the DA9062 PMIC.
config PINCTRL_DIGICOLOR
bool
depends on OF && (ARCH_DIGICOLOR || COMPILE_TEST)

View File

@ -16,6 +16,7 @@ obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o
obj-$(CONFIG_PINCTRL_AMD) += pinctrl-amd.o
obj-$(CONFIG_PINCTRL_BM1880) += pinctrl-bm1880.o
obj-$(CONFIG_PINCTRL_DA850_PUPD) += pinctrl-da850-pupd.o
obj-$(CONFIG_PINCTRL_DA9062) += pinctrl-da9062.o
obj-$(CONFIG_PINCTRL_DIGICOLOR) += pinctrl-digicolor.o
obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o
obj-$(CONFIG_PINCTRL_GEMINI) += pinctrl-gemini.o

View File

@ -1125,317 +1125,317 @@ static const struct owl_pingroup s700_groups[] = {
};
static const char * const nor_groups[] = {
"lcd0_d18",
"i2s_d0",
"i2s0_pcm0",
"i2s1_pcm0",
"i2s_d1",
"ks_in2",
"ks_in1",
"ks_in0",
"ks_in3",
"ks_out0",
"ks_out1",
"ks_out2",
"lcd0_d2",
"lvds_ee_pn",
"uart2_rx_tx",
"spi0_i2c_pcm",
"lvds_e_pn",
"sd0_d0",
"sd0_d1",
"sd0_d2_d3",
"sd1_d0_d3",
"sd0_cmd",
"sd1_cmd",
"sens0_ckout",
"sen0_pclk",
"lcd0_d18_mfp",
"i2s_d0_mfp",
"i2s0_pcm0_mfp",
"i2s1_pcm0_mfp",
"i2s_d1_mfp",
"ks_in2_mfp",
"ks_in1_mfp",
"ks_in0_mfp",
"ks_in3_mfp",
"ks_out0_mfp",
"ks_out1_mfp",
"ks_out2_mfp",
"lcd0_d2_mfp",
"lvds_ee_pn_mfp",
"uart2_rx_tx_mfp",
"spi0_i2c_pcm_mfp",
"lvds_e_pn_mfp",
"sd0_d0_mfp",
"sd0_d1_mfp",
"sd0_d2_d3_mfp",
"sd1_d0_d3_mfp",
"sd0_cmd_mfp",
"sd1_cmd_mfp",
"sens0_ckout_mfp",
"sen0_pclk_mfp",
};
static const char * const eth_rmii_groups[] = {
"rgmii_txd23",
"rgmii_rxd2",
"rgmii_rxd3",
"rgmii_txd01",
"rgmii_txd0",
"rgmii_txd1",
"rgmii_txen",
"rgmii_rxen",
"rgmii_rxd1",
"rgmii_rxd0",
"rgmii_ref_clk",
"rgmii_txd23_mfp",
"rgmii_rxd2_mfp",
"rgmii_rxd3_mfp",
"rgmii_txd01_mfp",
"rgmii_txd0_mfp",
"rgmii_txd1_mfp",
"rgmii_txen_mfp",
"rgmii_rxen_mfp",
"rgmii_rxd1_mfp",
"rgmii_rxd0_mfp",
"rgmii_ref_clk_mfp",
"eth_smi_dummy",
};
static const char * const eth_smii_groups[] = {
"rgmii_txd0",
"rgmii_txd1",
"rgmii_rxd0",
"rgmii_rxd1",
"rgmii_ref_clk",
"rgmii_txd0_mfp",
"rgmii_txd1_mfp",
"rgmii_rxd0_mfp",
"rgmii_rxd1_mfp",
"rgmii_ref_clk_mfp",
"eth_smi_dummy",
};
static const char * const spi0_groups[] = {
"dsi_dn0",
"dsi_dp2",
"dsi_dp0",
"uart2_rx_tx",
"spi0_i2c_pcm",
"dsi_dn2",
"dsi_dn0_mfp",
"dsi_dp2_mfp",
"dsi_dp0_mfp",
"uart2_rx_tx_mfp",
"spi0_i2c_pcm_mfp",
"dsi_dn2_mfp",
};
static const char * const spi1_groups[] = {
"uart0_rx",
"uart0_tx",
"uart0_rx_mfp",
"uart0_tx_mfp",
"i2c0_mfp",
};
static const char * const spi2_groups[] = {
"rgmii_txd01",
"rgmii_txd0",
"rgmii_txd1",
"rgmii_ref_clk",
"dnand_acle_ce0",
"rgmii_txd01_mfp",
"rgmii_txd0_mfp",
"rgmii_txd1_mfp",
"rgmii_ref_clk_mfp",
"dnand_acle_ce0_mfp",
};
static const char * const spi3_groups[] = {
"rgmii_txen",
"rgmii_rxen",
"rgmii_rxd1",
"rgmii_rxd0",
"rgmii_txen_mfp",
"rgmii_rxen_mfp",
"rgmii_rxd1_mfp",
"rgmii_rxd0_mfp",
};
static const char * const sens0_groups[] = {
"csi_cn_cp",
"sens0_ckout",
"csi_dn_dp",
"sen0_pclk",
"csi_cn_cp_mfp",
"sens0_ckout_mfp",
"csi_dn_dp_mfp",
"sen0_pclk_mfp",
};
static const char * const sens1_groups[] = {
"lcd0_d18",
"ks_in2",
"ks_in1",
"ks_in0",
"ks_in3",
"ks_out0",
"ks_out1",
"ks_out2",
"sens0_ckout",
"pcm1_in",
"pcm1_clk",
"pcm1_sync",
"pcm1_out",
"lcd0_d18_mfp",
"ks_in2_mfp",
"ks_in1_mfp",
"ks_in0_mfp",
"ks_in3_mfp",
"ks_out0_mfp",
"ks_out1_mfp",
"ks_out2_mfp",
"sens0_ckout_mfp",
"pcm1_in_mfp",
"pcm1_clk_mfp",
"pcm1_sync_mfp",
"pcm1_out_mfp",
};
static const char * const uart0_groups[] = {
"uart2_rtsb",
"uart2_ctsb",
"uart0_rx",
"uart0_tx",
"uart2_rtsb_mfp",
"uart2_ctsb_mfp",
"uart0_rx_mfp",
"uart0_tx_mfp",
};
static const char * const uart1_groups[] = {
"sd0_d2_d3",
"sd0_d2_d3_mfp",
"i2c0_mfp",
};
static const char * const uart2_groups[] = {
"rgmii_txen",
"rgmii_rxen",
"rgmii_rxd1",
"rgmii_rxd0",
"dsi_dn0",
"dsi_dp2",
"dsi_dp0",
"uart2_rx_tx",
"dsi_dn2",
"uart2_rtsb",
"uart2_ctsb",
"sd0_d0",
"sd0_d1",
"sd0_d2_d3",
"uart0_rx",
"uart0_tx",
"rgmii_txen_mfp",
"rgmii_rxen_mfp",
"rgmii_rxd1_mfp",
"rgmii_rxd0_mfp",
"dsi_dn0_mfp",
"dsi_dp2_mfp",
"dsi_dp0_mfp",
"uart2_rx_tx_mfp",
"dsi_dn2_mfp",
"uart2_rtsb_mfp",
"uart2_ctsb_mfp",
"sd0_d0_mfp",
"sd0_d1_mfp",
"sd0_d2_d3_mfp",
"uart0_rx_mfp",
"uart0_tx_mfp",
"i2c0_mfp",
"uart2_dummy"
};
static const char * const uart3_groups[] = {
"rgmii_txd23",
"rgmii_rxd2",
"rgmii_rxd3",
"uart3_rtsb",
"uart3_ctsb",
"rgmii_txd23_mfp",
"rgmii_rxd2_mfp",
"rgmii_rxd3_mfp",
"uart3_rtsb_mfp",
"uart3_ctsb_mfp",
"uart3_dummy"
};
static const char * const uart4_groups[] = {
"rgmii_txd01",
"rgmii_ref_clk",
"ks_out0",
"ks_out1",
"rgmii_txd01_mfp",
"rgmii_ref_clk_mfp",
"ks_out0_mfp",
"ks_out1_mfp",
};
static const char * const uart5_groups[] = {
"rgmii_rxd1",
"rgmii_rxd0",
"ks_out0",
"ks_out2",
"uart3_rtsb",
"uart3_ctsb",
"sd0_d0",
"sd0_d1",
"rgmii_rxd1_mfp",
"rgmii_rxd0_mfp",
"ks_out0_mfp",
"ks_out2_mfp",
"uart3_rtsb_mfp",
"uart3_ctsb_mfp",
"sd0_d0_mfp",
"sd0_d1_mfp",
};
static const char * const uart6_groups[] = {
"rgmii_txd0",
"rgmii_txd1",
"rgmii_txd0_mfp",
"rgmii_txd1_mfp",
};
static const char * const i2s0_groups[] = {
"i2s_d0",
"i2s_pcm1",
"i2s0_pcm0",
"i2s_d0_mfp",
"i2s_pcm1_mfp",
"i2s0_pcm0_mfp",
};
static const char * const i2s1_groups[] = {
"i2s1_pcm0",
"i2s_d1",
"i2s1_pcm0_mfp",
"i2s_d1_mfp",
"i2s1_dummy",
"spi0_i2c_pcm",
"uart0_rx",
"uart0_tx",
"spi0_i2c_pcm_mfp",
"uart0_rx_mfp",
"uart0_tx_mfp",
};
static const char * const pcm1_groups[] = {
"i2s_pcm1",
"spi0_i2c_pcm",
"uart0_rx",
"uart0_tx",
"pcm1_in",
"pcm1_clk",
"pcm1_sync",
"pcm1_out",
"i2s_pcm1_mfp",
"spi0_i2c_pcm_mfp",
"uart0_rx_mfp",
"uart0_tx_mfp",
"pcm1_in_mfp",
"pcm1_clk_mfp",
"pcm1_sync_mfp",
"pcm1_out_mfp",
};
static const char * const pcm0_groups[] = {
"i2s0_pcm0",
"i2s1_pcm0",
"uart2_rx_tx",
"spi0_i2c_pcm",
"i2s0_pcm0_mfp",
"i2s1_pcm0_mfp",
"uart2_rx_tx_mfp",
"spi0_i2c_pcm_mfp",
};
static const char * const ks_groups[] = {
"ks_in2",
"ks_in1",
"ks_in0",
"ks_in3",
"ks_out0",
"ks_out1",
"ks_out2",
"ks_in2_mfp",
"ks_in1_mfp",
"ks_in0_mfp",
"ks_in3_mfp",
"ks_out0_mfp",
"ks_out1_mfp",
"ks_out2_mfp",
};
static const char * const jtag_groups[] = {
"ks_in2",
"ks_in1",
"ks_in0",
"ks_in3",
"ks_out1",
"sd0_d0",
"sd0_d2_d3",
"sd0_cmd",
"sd0_clk",
"ks_in2_mfp",
"ks_in1_mfp",
"ks_in0_mfp",
"ks_in3_mfp",
"ks_out1_mfp",
"sd0_d0_mfp",
"sd0_d2_d3_mfp",
"sd0_cmd_mfp",
"sd0_clk_mfp",
};
static const char * const pwm0_groups[] = {
"rgmii_rxd2",
"rgmii_txen",
"ks_in2",
"sen0_pclk",
"rgmii_rxd2_mfp",
"rgmii_txen_mfp",
"ks_in2_mfp",
"sen0_pclk_mfp",
};
static const char * const pwm1_groups[] = {
"rgmii_rxen",
"ks_in1",
"ks_in3",
"sens0_ckout",
"rgmii_rxen_mfp",
"ks_in1_mfp",
"ks_in3_mfp",
"sens0_ckout_mfp",
};
static const char * const pwm2_groups[] = {
"lcd0_d18",
"rgmii_rxd3",
"rgmii_rxd1",
"ks_out0",
"ks_out2",
"lcd0_d18_mfp",
"rgmii_rxd3_mfp",
"rgmii_rxd1_mfp",
"ks_out0_mfp",
"ks_out2_mfp",
};
static const char * const pwm3_groups[] = {
"rgmii_rxd0",
"ks_out1",
"lcd0_d2",
"rgmii_rxd0_mfp",
"ks_out1_mfp",
"lcd0_d2_mfp",
};
static const char * const pwm4_groups[] = {
"lcd0_d18",
"rgmii_txd01",
"rgmii_txd0",
"ks_in0",
"pcm1_in",
"nand_ceb3",
"lcd0_d18_mfp",
"rgmii_txd01_mfp",
"rgmii_txd0_mfp",
"ks_in0_mfp",
"pcm1_in_mfp",
"nand_ceb3_mfp",
};
static const char * const pwm5_groups[] = {
"rgmii_txd1",
"ks_in1",
"pcm1_clk",
"nand_ceb2",
"rgmii_txd1_mfp",
"ks_in1_mfp",
"pcm1_clk_mfp",
"nand_ceb2_mfp",
};
static const char * const p0_groups[] = {
"ks_in2",
"ks_in0",
"ks_in2_mfp",
"ks_in0_mfp",
};
static const char * const sd0_groups[] = {
"ks_out0",
"ks_out1",
"ks_out2",
"lcd0_d2",
"dsi_dp3",
"dsi_dp0",
"sd0_d0",
"sd0_d1",
"sd0_d2_d3",
"sd1_d0_d3",
"sd0_cmd",
"sd0_clk",
"ks_out0_mfp",
"ks_out1_mfp",
"ks_out2_mfp",
"lcd0_d2_mfp",
"dsi_dp3_mfp",
"dsi_dp0_mfp",
"sd0_d0_mfp",
"sd0_d1_mfp",
"sd0_d2_d3_mfp",
"sd1_d0_d3_mfp",
"sd0_cmd_mfp",
"sd0_clk_mfp",
};
static const char * const sd1_groups[] = {
"dsi_dp2",
"mfp1_16_14",
"lcd0_d2",
"mfp1_16_14_d17",
"dsi_dp3",
"dsi_dn3",
"dsi_dnp1_cp_d2",
"dsi_dnp1_cp_d17",
"dsi_dn2",
"sd1_d0_d3",
"sd1_cmd",
"dsi_dp2_mfp",
"mfp1_16_14_mfp",
"lcd0_d2_mfp",
"mfp1_16_14_d17_mfp",
"dsi_dp3_mfp",
"dsi_dn3_mfp",
"dsi_dnp1_cp_d2_mfp",
"dsi_dnp1_cp_d17_mfp",
"dsi_dn2_mfp",
"sd1_d0_d3_mfp",
"sd1_cmd_mfp",
"sd1_dummy",
};
static const char * const sd2_groups[] = {
"dnand_data_wr",
"dnand_data_wr_mfp",
};
static const char * const i2c0_groups[] = {
"uart0_rx",
"uart0_tx",
"i2c0_mfp",
"uart0_rx_mfp",
"uart0_tx_mfp",
"i2c0_mfp_mfp",
};
static const char * const i2c1_groups[] = {
@ -1448,85 +1448,85 @@ static const char * const i2c2_groups[] = {
};
static const char * const i2c3_groups[] = {
"uart2_rx_tx",
"pcm1_sync",
"pcm1_out",
"uart2_rx_tx_mfp",
"pcm1_sync_mfp",
"pcm1_out_mfp",
};
static const char * const lvds_groups[] = {
"lvds_o_pn",
"lvds_ee_pn",
"lvds_e_pn",
"lvds_o_pn_mfp",
"lvds_ee_pn_mfp",
"lvds_e_pn_mfp",
};
static const char * const bt_groups[] = {
"i2s_pcm1",
"i2s0_pcm0",
"i2s1_pcm0",
"ks_in2",
"ks_in1",
"ks_in0",
"ks_in3",
"ks_out0",
"ks_out1",
"ks_out2",
"lvds_o_pn",
"lvds_ee_pn",
"pcm1_in",
"pcm1_clk",
"pcm1_sync",
"pcm1_out",
"i2s_pcm1_mfp",
"i2s0_pcm0_mfp",
"i2s1_pcm0_mfp",
"ks_in2_mfp",
"ks_in1_mfp",
"ks_in0_mfp",
"ks_in3_mfp",
"ks_out0_mfp",
"ks_out1_mfp",
"ks_out2_mfp",
"lvds_o_pn_mfp",
"lvds_ee_pn_mfp",
"pcm1_in_mfp",
"pcm1_clk_mfp",
"pcm1_sync_mfp",
"pcm1_out_mfp",
};
static const char * const lcd0_groups[] = {
"lcd0_d18",
"lcd0_d2",
"mfp1_16_14_d17",
"lvds_o_pn",
"dsi_dp3",
"dsi_dn3",
"lvds_ee_pn",
"dsi_dnp1_cp_d2",
"dsi_dnp1_cp_d17",
"lvds_e_pn",
"lcd0_d18_mfp",
"lcd0_d2_mfp",
"mfp1_16_14_d17_mfp",
"lvds_o_pn_mfp",
"dsi_dp3_mfp",
"dsi_dn3_mfp",
"lvds_ee_pn_mfp",
"dsi_dnp1_cp_d2_mfp",
"dsi_dnp1_cp_d17_mfp",
"lvds_e_pn_mfp",
};
static const char * const usb30_groups[] = {
"ks_in1",
"ks_in1_mfp",
};
static const char * const clko_25m_groups[] = {
"clko_25m",
"clko_25m_mfp",
};
static const char * const mipi_csi_groups[] = {
"csi_cn_cp",
"csi_dn_dp",
"csi_cn_cp_mfp",
"csi_dn_dp_mfp",
};
static const char * const dsi_groups[] = {
"dsi_dn0",
"dsi_dp2",
"dsi_dp3",
"dsi_dn3",
"dsi_dp0",
"dsi_dnp1_cp_d2",
"dsi_dnp1_cp_d17",
"dsi_dn2",
"dsi_dn0_mfp",
"dsi_dp2_mfp",
"dsi_dp3_mfp",
"dsi_dn3_mfp",
"dsi_dp0_mfp",
"dsi_dnp1_cp_d2_mfp",
"dsi_dnp1_cp_d17_mfp",
"dsi_dn2_mfp",
"dsi_dummy",
};
static const char * const nand_groups[] = {
"dnand_data_wr",
"dnand_acle_ce0",
"nand_ceb2",
"nand_ceb3",
"dnand_data_wr_mfp",
"dnand_acle_ce0_mfp",
"nand_ceb2_mfp",
"nand_ceb3_mfp",
"nand_dummy",
};
static const char * const spdif_groups[] = {
"uart0_tx",
"uart0_tx_mfp",
};
static const char * const sirq0_groups[] = {

View File

@ -37,12 +37,10 @@
#define MODULE_NAME "pinctrl-bcm2835"
#define BCM2835_NUM_GPIOS 54
#define BCM2711_NUM_GPIOS 58
#define BCM2835_NUM_BANKS 2
#define BCM2835_NUM_IRQS 3
#define BCM2835_PIN_BITMAP_SZ \
DIV_ROUND_UP(BCM2835_NUM_GPIOS, sizeof(unsigned long) * 8)
/* GPIO register offsets */
#define GPFSEL0 0x0 /* Function Select */
#define GPSET0 0x1c /* Pin Output Set */
@ -81,10 +79,11 @@ struct bcm2835_pinctrl {
/* note: locking assumes each bank will have its own unsigned long */
unsigned long enabled_irq_map[BCM2835_NUM_BANKS];
unsigned int irq_type[BCM2835_NUM_GPIOS];
unsigned int irq_type[BCM2711_NUM_GPIOS];
struct pinctrl_dev *pctl_dev;
struct gpio_chip gpio_chip;
struct pinctrl_desc pctl_desc;
struct pinctrl_gpio_range gpio_range;
raw_spinlock_t irq_lock[BCM2835_NUM_BANKS];
@ -147,6 +146,10 @@ static struct pinctrl_pin_desc bcm2835_gpio_pins[] = {
BCM2835_GPIO_PIN(51),
BCM2835_GPIO_PIN(52),
BCM2835_GPIO_PIN(53),
BCM2835_GPIO_PIN(54),
BCM2835_GPIO_PIN(55),
BCM2835_GPIO_PIN(56),
BCM2835_GPIO_PIN(57),
};
/* one pin per group */
@ -205,6 +208,10 @@ static const char * const bcm2835_gpio_groups[] = {
"gpio51",
"gpio52",
"gpio53",
"gpio54",
"gpio55",
"gpio56",
"gpio57",
};
enum bcm2835_fsel {
@ -322,7 +329,10 @@ static int bcm2835_gpio_get_direction(struct gpio_chip *chip, unsigned int offse
if (fsel > BCM2835_FSEL_GPIO_OUT)
return -EINVAL;
return (fsel == BCM2835_FSEL_GPIO_IN);
if (fsel == BCM2835_FSEL_GPIO_IN)
return GPIO_LINE_DIRECTION_IN;
return GPIO_LINE_DIRECTION_OUT;
}
static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
@ -355,6 +365,22 @@ static const struct gpio_chip bcm2835_gpio_chip = {
.can_sleep = false,
};
static const struct gpio_chip bcm2711_gpio_chip = {
.label = "pinctrl-bcm2711",
.owner = THIS_MODULE,
.request = gpiochip_generic_request,
.free = gpiochip_generic_free,
.direction_input = bcm2835_gpio_direction_input,
.direction_output = bcm2835_gpio_direction_output,
.get_direction = bcm2835_gpio_get_direction,
.get = bcm2835_gpio_get,
.set = bcm2835_gpio_set,
.set_config = gpiochip_generic_config,
.base = -1,
.ngpio = BCM2711_NUM_GPIOS,
.can_sleep = false,
};
static void bcm2835_gpio_irq_handle_bank(struct bcm2835_pinctrl *pc,
unsigned int bank, u32 mask)
{
@ -401,7 +427,7 @@ static void bcm2835_gpio_irq_handler(struct irq_desc *desc)
bcm2835_gpio_irq_handle_bank(pc, 0, 0xf0000000);
bcm2835_gpio_irq_handle_bank(pc, 1, 0x00003fff);
break;
case 2: /* IRQ2 covers GPIOs 46-53 */
case 2: /* IRQ2 covers GPIOs 46-57 */
bcm2835_gpio_irq_handle_bank(pc, 1, 0x003fc000);
break;
}
@ -620,7 +646,7 @@ static struct irq_chip bcm2835_gpio_irq_chip = {
static int bcm2835_pctl_get_groups_count(struct pinctrl_dev *pctldev)
{
return ARRAY_SIZE(bcm2835_gpio_groups);
return BCM2835_NUM_GPIOS;
}
static const char *bcm2835_pctl_get_group_name(struct pinctrl_dev *pctldev,
@ -778,7 +804,7 @@ static int bcm2835_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
err = of_property_read_u32_index(np, "brcm,pins", i, &pin);
if (err)
goto out;
if (pin >= ARRAY_SIZE(bcm2835_gpio_pins)) {
if (pin >= pc->pctl_desc.npins) {
dev_err(pc->dev, "%pOF: invalid brcm,pins value %d\n",
np, pin);
err = -EINVAL;
@ -854,7 +880,7 @@ static int bcm2835_pmx_get_function_groups(struct pinctrl_dev *pctldev,
{
/* every pin can do every function */
*groups = bcm2835_gpio_groups;
*num_groups = ARRAY_SIZE(bcm2835_gpio_groups);
*num_groups = BCM2835_NUM_GPIOS;
return 0;
}
@ -1054,29 +1080,62 @@ static const struct pinconf_ops bcm2711_pinconf_ops = {
.pin_config_set = bcm2711_pinconf_set,
};
static struct pinctrl_desc bcm2835_pinctrl_desc = {
static const struct pinctrl_desc bcm2835_pinctrl_desc = {
.name = MODULE_NAME,
.pins = bcm2835_gpio_pins,
.npins = ARRAY_SIZE(bcm2835_gpio_pins),
.npins = BCM2835_NUM_GPIOS,
.pctlops = &bcm2835_pctl_ops,
.pmxops = &bcm2835_pmx_ops,
.confops = &bcm2835_pinconf_ops,
.owner = THIS_MODULE,
};
static struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = {
static const struct pinctrl_desc bcm2711_pinctrl_desc = {
.name = "pinctrl-bcm2711",
.pins = bcm2835_gpio_pins,
.npins = BCM2711_NUM_GPIOS,
.pctlops = &bcm2835_pctl_ops,
.pmxops = &bcm2835_pmx_ops,
.confops = &bcm2711_pinconf_ops,
.owner = THIS_MODULE,
};
static const struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = {
.name = MODULE_NAME,
.npins = BCM2835_NUM_GPIOS,
};
static const struct pinctrl_gpio_range bcm2711_pinctrl_gpio_range = {
.name = "pinctrl-bcm2711",
.npins = BCM2711_NUM_GPIOS,
};
struct bcm_plat_data {
const struct gpio_chip *gpio_chip;
const struct pinctrl_desc *pctl_desc;
const struct pinctrl_gpio_range *gpio_range;
};
static const struct bcm_plat_data bcm2835_plat_data = {
.gpio_chip = &bcm2835_gpio_chip,
.pctl_desc = &bcm2835_pinctrl_desc,
.gpio_range = &bcm2835_pinctrl_gpio_range,
};
static const struct bcm_plat_data bcm2711_plat_data = {
.gpio_chip = &bcm2711_gpio_chip,
.pctl_desc = &bcm2711_pinctrl_desc,
.gpio_range = &bcm2711_pinctrl_gpio_range,
};
static const struct of_device_id bcm2835_pinctrl_match[] = {
{
.compatible = "brcm,bcm2835-gpio",
.data = &bcm2835_pinconf_ops,
.data = &bcm2835_plat_data,
},
{
.compatible = "brcm,bcm2711-gpio",
.data = &bcm2711_pinconf_ops,
.data = &bcm2711_plat_data,
},
{}
};
@ -1085,14 +1144,15 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
const struct bcm_plat_data *pdata;
struct bcm2835_pinctrl *pc;
struct gpio_irq_chip *girq;
struct resource iomem;
int err, i;
const struct of_device_id *match;
BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2835_NUM_GPIOS);
BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2835_NUM_GPIOS);
BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2711_NUM_GPIOS);
BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2711_NUM_GPIOS);
pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
if (!pc)
@ -1111,7 +1171,13 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
if (IS_ERR(pc->base))
return PTR_ERR(pc->base);
pc->gpio_chip = bcm2835_gpio_chip;
match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node);
if (!match)
return -EINVAL;
pdata = match->data;
pc->gpio_chip = *pdata->gpio_chip;
pc->gpio_chip.parent = dev;
pc->gpio_chip.of_node = np;
@ -1162,19 +1228,14 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
return err;
}
match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node);
if (match) {
bcm2835_pinctrl_desc.confops =
(const struct pinconf_ops *)match->data;
}
pc->pctl_dev = devm_pinctrl_register(dev, &bcm2835_pinctrl_desc, pc);
pc->pctl_desc = *pdata->pctl_desc;
pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
if (IS_ERR(pc->pctl_dev)) {
gpiochip_remove(&pc->gpio_chip);
return PTR_ERR(pc->pctl_dev);
}
pc->gpio_range = bcm2835_pinctrl_gpio_range;
pc->gpio_range = *pdata->gpio_range;
pc->gpio_range.base = pc->gpio_chip.base;
pc->gpio_range.gc = &pc->gpio_chip;
pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);

View File

@ -363,7 +363,10 @@ static int iproc_gpio_get_direction(struct gpio_chip *gc, unsigned int gpio)
unsigned int offset = IPROC_GPIO_REG(gpio, IPROC_GPIO_OUT_EN_OFFSET);
unsigned int shift = IPROC_GPIO_SHIFT(gpio);
return !(readl(chip->base + offset) & BIT(shift));
if (readl(chip->base + offset) & BIT(shift))
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
}
static void iproc_gpio_set(struct gpio_chip *gc, unsigned gpio, int val)

View File

@ -176,6 +176,7 @@ const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin)
return desc->name;
}
EXPORT_SYMBOL_GPL(pin_get_name);
/* Deletes a range of pin descriptors */
static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev,

View File

@ -125,28 +125,28 @@ config PINCTRL_IMX7ULP
config PINCTRL_IMX8MM
bool "IMX8MM pinctrl driver"
depends on ARCH_MXC && ARM64
depends on ARCH_MXC
select PINCTRL_IMX
help
Say Y here to enable the imx8mm pinctrl driver
config PINCTRL_IMX8MN
bool "IMX8MN pinctrl driver"
depends on ARCH_MXC && ARM64
depends on ARCH_MXC
select PINCTRL_IMX
help
Say Y here to enable the imx8mn pinctrl driver
config PINCTRL_IMX8MP
bool "IMX8MP pinctrl driver"
depends on ARCH_MXC && ARM64
depends on ARCH_MXC
select PINCTRL_IMX
help
Say Y here to enable the imx8mp pinctrl driver
config PINCTRL_IMX8MQ
bool "IMX8MQ pinctrl driver"
depends on ARCH_MXC && ARM64
depends on ARCH_MXC
select PINCTRL_IMX
help
Say Y here to enable the imx8mq pinctrl driver

View File

@ -1070,15 +1070,12 @@ static const struct mtk_pin_soc mt6765_data = {
.ngrps = ARRAY_SIZE(mtk_pins_mt6765),
.eint_hw = &mt6765_eint_hw,
.gpio_m = 0,
.ies_present = true,
.base_names = mt6765_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
.bias_disable_set = mtk_pinconf_bias_disable_set,
.bias_disable_get = mtk_pinconf_bias_disable_get,
.bias_set = mtk_pinconf_bias_set,
.bias_get = mtk_pinconf_bias_get,
.drive_set = mtk_pinconf_drive_set_rev1,
.drive_get = mtk_pinconf_drive_get_rev1,
.bias_set_combo = mtk_pinconf_bias_set_combo,
.bias_get_combo = mtk_pinconf_bias_get_combo,
.drive_set = mtk_pinconf_drive_set_raw,
.drive_get = mtk_pinconf_drive_get_raw,
.adv_pull_get = mtk_pinconf_adv_pull_get,
.adv_pull_set = mtk_pinconf_adv_pull_set,
};

View File

@ -554,13 +554,10 @@ static const struct mtk_pin_soc mt8183_data = {
.ngrps = ARRAY_SIZE(mtk_pins_mt8183),
.eint_hw = &mt8183_eint_hw,
.gpio_m = 0,
.ies_present = true,
.base_names = mt8183_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt8183_pinctrl_register_base_names),
.bias_disable_set = mtk_pinconf_bias_disable_set_rev1,
.bias_disable_get = mtk_pinconf_bias_disable_get_rev1,
.bias_set = mtk_pinconf_bias_set_rev1,
.bias_get = mtk_pinconf_bias_get_rev1,
.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,
.adv_pull_get = mtk_pinconf_adv_pull_get,

View File

@ -6,6 +6,7 @@
*
*/
#include <dt-bindings/pinctrl/mt65xx.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/gpio/driver.h>
@ -66,34 +67,44 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
int field, struct mtk_pin_field *pfd)
{
const struct mtk_pin_field_calc *c, *e;
const struct mtk_pin_field_calc *c;
const struct mtk_pin_reg_calc *rc;
int start = 0, end, check;
bool found = false;
u32 bits;
if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
rc = &hw->soc->reg_cal[field];
} else {
dev_dbg(hw->dev,
"Not support field %d for pin %d (%s)\n",
field, desc->number, desc->name);
"Not support field %d for this soc\n", field);
return -ENOTSUPP;
}
c = rc->range;
e = c + rc->nranges;
end = rc->nranges - 1;
while (c < e) {
if (desc->number >= c->s_pin && desc->number <= c->e_pin)
while (start <= end) {
check = (start + end) >> 1;
if (desc->number >= rc->range[check].s_pin
&& desc->number <= rc->range[check].e_pin) {
found = true;
break;
c++;
} else if (start == end)
break;
else if (desc->number < rc->range[check].s_pin)
end = check - 1;
else
start = check + 1;
}
if (c >= e) {
if (!found) {
dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
field, desc->number, desc->name);
return -ENOTSUPP;
}
c = rc->range + check;
if (c->i_base > hw->nbase - 1) {
dev_err(hw->dev,
"Invalid base for field %d for pin = %d (%s)\n",
@ -182,6 +193,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
if (err)
return err;
if (value < 0 || value > pf.mask)
return -EINVAL;
if (!pf.next)
mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
(value & pf.mask) << pf.bitpos);
@ -502,6 +516,226 @@ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
return 0;
}
/* Combo for the following pull register type:
* 1. PU + PD
* 2. PULLSEL + PULLEN
* 3. PUPD + R0 + R1
*/
static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 pullup, u32 arg)
{
int err, pu, pd;
if (arg == MTK_DISABLE) {
pu = 0;
pd = 0;
} else if ((arg == MTK_ENABLE) && pullup) {
pu = 1;
pd = 0;
} else if ((arg == MTK_ENABLE) && !pullup) {
pu = 0;
pd = 1;
} else {
err = -EINVAL;
goto out;
}
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu);
if (err)
goto out;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
out:
return err;
}
static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 pullup, u32 arg)
{
int err, enable;
if (arg == MTK_DISABLE)
enable = 0;
else if (arg == MTK_ENABLE)
enable = 1;
else {
err = -EINVAL;
goto out;
}
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
if (err)
goto out;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
out:
return err;
}
static int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 pullup, u32 arg)
{
int err, r0, r1;
if ((arg == MTK_DISABLE) || (arg == MTK_PUPD_SET_R1R0_00)) {
pullup = 0;
r0 = 0;
r1 = 0;
} else if (arg == MTK_PUPD_SET_R1R0_01) {
r0 = 1;
r1 = 0;
} else if (arg == MTK_PUPD_SET_R1R0_10) {
r0 = 0;
r1 = 1;
} else if (arg == MTK_PUPD_SET_R1R0_11) {
r0 = 1;
r1 = 1;
} else {
err = -EINVAL;
goto out;
}
/* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, !pullup);
if (err)
goto out;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, r0);
if (err)
goto out;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1, r1);
out:
return err;
}
static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 *pullup, u32 *enable)
{
int err, pu, pd;
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu);
if (err)
goto out;
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
if (err)
goto out;
if (pu == 0 && pd == 0) {
*pullup = 0;
*enable = MTK_DISABLE;
} else if (pu == 1 && pd == 0) {
*pullup = 1;
*enable = MTK_ENABLE;
} else if (pu == 0 && pd == 1) {
*pullup = 0;
*enable = MTK_ENABLE;
} else
err = -EINVAL;
out:
return err;
}
static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 *pullup, u32 *enable)
{
int err;
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
if (err)
goto out;
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
out:
return err;
}
static int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 *pullup, u32 *enable)
{
int err, r0, r1;
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, pullup);
if (err)
goto out;
/* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
*pullup = !(*pullup);
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &r0);
if (err)
goto out;
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &r1);
if (err)
goto out;
if ((r1 == 0) && (r0 == 0))
*enable = MTK_PUPD_SET_R1R0_00;
else if ((r1 == 0) && (r0 == 1))
*enable = MTK_PUPD_SET_R1R0_01;
else if ((r1 == 1) && (r0 == 0))
*enable = MTK_PUPD_SET_R1R0_10;
else if ((r1 == 1) && (r0 == 1))
*enable = MTK_PUPD_SET_R1R0_11;
else
err = -EINVAL;
out:
return err;
}
int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 pullup, u32 arg)
{
int err;
err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
if (!err)
goto out;
err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, pullup, arg);
if (!err)
goto out;
err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg);
out:
return err;
}
int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 *pullup, u32 *enable)
{
int err;
err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
if (!err)
goto out;
err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, pullup, enable);
if (!err)
goto out;
err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable);
out:
return err;
}
/* Revision 0 */
int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg)
@ -593,6 +827,18 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
return 0;
}
int mtk_pinconf_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, arg);
}
int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *val)
{
return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val);
}
int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup,
u32 arg)

View File

@ -216,6 +216,11 @@ struct mtk_pin_soc {
int (*bias_get)(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup, int *res);
int (*bias_set_combo)(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 pullup, u32 arg);
int (*bias_get_combo)(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 *pullup, u32 *arg);
int (*drive_set)(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg);
int (*drive_get)(struct mtk_pinctrl *hw,
@ -277,6 +282,12 @@ int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw,
int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup,
int *res);
int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 pullup, u32 enable);
int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 *pullup, u32 *enable);
int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg);
@ -288,6 +299,11 @@ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *val);
int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg);
int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *val);
int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup,
u32 arg);

View File

@ -804,7 +804,10 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
pctl->devdata->spec_dir_set(&reg_addr, offset);
regmap_read(pctl->regmap1, reg_addr, &read_val);
return !(read_val & bit);
if (read_val & bit)
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
}
static int mtk_gpio_get(struct gpio_chip *chip, unsigned offset)

View File

@ -78,93 +78,88 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
u32 param = pinconf_to_config_param(*config);
int val, val2, err, reg, ret = 1;
int pullup, err, reg, ret = 1;
const struct mtk_pin_desc *desc;
if (pin >= hw->soc->npins) {
err = -EINVAL;
goto out;
}
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
if (hw->soc->bias_disable_get) {
err = hw->soc->bias_disable_get(hw, desc, &ret);
if (err)
return err;
} else {
return -ENOTSUPP;
}
break;
case PIN_CONFIG_BIAS_PULL_UP:
if (hw->soc->bias_get) {
err = hw->soc->bias_get(hw, desc, 1, &ret);
if (err)
return err;
} else {
return -ENOTSUPP;
}
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
if (hw->soc->bias_get) {
err = hw->soc->bias_get(hw, desc, 0, &ret);
if (hw->soc->bias_get_combo) {
err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
if (err)
return err;
} else {
return -ENOTSUPP;
}
break;
case PIN_CONFIG_SLEW_RATE:
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val);
if (err)
return err;
if (!val)
return -EINVAL;
break;
case PIN_CONFIG_INPUT_ENABLE:
case PIN_CONFIG_OUTPUT_ENABLE:
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
if (err)
return err;
/* HW takes input mode as zero; output mode as non-zero */
if ((val && param == PIN_CONFIG_INPUT_ENABLE) ||
(!val && param == PIN_CONFIG_OUTPUT_ENABLE))
return -EINVAL;
break;
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
if (err)
return err;
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &val2);
if (err)
return err;
if (val || !val2)
return -EINVAL;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
if (hw->soc->drive_get) {
err = hw->soc->drive_get(hw, desc, &ret);
if (err)
return err;
goto out;
if (param == PIN_CONFIG_BIAS_DISABLE) {
if (ret == MTK_PUPD_SET_R1R0_00)
ret = MTK_DISABLE;
} else if (param == PIN_CONFIG_BIAS_PULL_UP) {
/* When desire to get pull-up value, return
* error if current setting is pull-down
*/
if (!pullup)
err = -EINVAL;
} else if (param == PIN_CONFIG_BIAS_PULL_DOWN) {
/* When desire to get pull-down value, return
* error if current setting is pull-up
*/
if (pullup)
err = -EINVAL;
}
} else {
err = -ENOTSUPP;
}
break;
case PIN_CONFIG_SLEW_RATE:
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
break;
case PIN_CONFIG_INPUT_ENABLE:
case PIN_CONFIG_OUTPUT_ENABLE:
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
if (err)
goto out;
/* CONFIG Current direction return value
* ------------- ----------------- ----------------------
* OUTPUT_ENABLE output 1 (= HW value)
* input 0 (= HW value)
* INPUT_ENABLE output 0 (= reverse HW value)
* input 1 (= reverse HW value)
*/
if (param == PIN_CONFIG_INPUT_ENABLE)
ret = !ret;
break;
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
if (err)
goto out;
/* return error when in output mode
* because schmitt trigger only work in input mode
*/
if (ret) {
err = -EINVAL;
goto out;
}
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret);
break;
case PIN_CONFIG_DRIVE_STRENGTH:
if (hw->soc->drive_get)
err = hw->soc->drive_get(hw, desc, &ret);
else
err = -ENOTSUPP;
break;
case MTK_PIN_CONFIG_TDSEL:
case MTK_PIN_CONFIG_RDSEL:
reg = (param == MTK_PIN_CONFIG_TDSEL) ?
PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
err = mtk_hw_get_value(hw, desc, reg, &val);
if (err)
return err;
ret = val;
err = mtk_hw_get_value(hw, desc, reg, &ret);
break;
case MTK_PIN_CONFIG_PU_ADV:
case MTK_PIN_CONFIG_PD_ADV:
@ -173,28 +168,24 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
pullup = param == MTK_PIN_CONFIG_PU_ADV;
err = hw->soc->adv_pull_get(hw, desc, pullup, &ret);
if (err)
return err;
} else {
return -ENOTSUPP;
}
} else
err = -ENOTSUPP;
break;
case MTK_PIN_CONFIG_DRV_ADV:
if (hw->soc->adv_drive_get) {
if (hw->soc->adv_drive_get)
err = hw->soc->adv_drive_get(hw, desc, &ret);
if (err)
return err;
} else {
return -ENOTSUPP;
}
else
err = -ENOTSUPP;
break;
default:
return -ENOTSUPP;
err = -ENOTSUPP;
}
*config = pinconf_to_config_packed(param, ret);
out:
if (!err)
*config = pinconf_to_config_packed(param, ret);
return 0;
return err;
}
static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
@ -206,64 +197,55 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
int err = 0;
u32 reg;
if (pin >= hw->soc->npins) {
err = -EINVAL;
goto err;
}
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
switch ((u32)param) {
case PIN_CONFIG_BIAS_DISABLE:
if (hw->soc->bias_disable_set) {
err = hw->soc->bias_disable_set(hw, desc);
if (err)
return err;
} else {
return -ENOTSUPP;
}
if (hw->soc->bias_set_combo)
err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE);
else
err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_UP:
if (hw->soc->bias_set) {
err = hw->soc->bias_set(hw, desc, 1);
if (err)
return err;
} else {
return -ENOTSUPP;
}
if (hw->soc->bias_set_combo)
err = hw->soc->bias_set_combo(hw, desc, 1, arg);
else
err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
if (hw->soc->bias_set) {
err = hw->soc->bias_set(hw, desc, 0);
if (err)
return err;
} else {
return -ENOTSUPP;
}
if (hw->soc->bias_set_combo)
err = hw->soc->bias_set_combo(hw, desc, 0, arg);
else
err = -ENOTSUPP;
break;
case PIN_CONFIG_OUTPUT_ENABLE:
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
MTK_DISABLE);
if (err)
/* Keep set direction to consider the case that a GPIO pin
* does not have SMT control
*/
if (err != -ENOTSUPP)
goto err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
MTK_OUTPUT);
if (err)
goto err;
break;
case PIN_CONFIG_INPUT_ENABLE:
if (hw->soc->ies_present) {
mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES,
MTK_ENABLE);
}
/* regard all non-zero value as enable */
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg);
if (err)
goto err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
MTK_INPUT);
if (err)
goto err;
break;
case PIN_CONFIG_SLEW_RATE:
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR,
arg);
if (err)
goto err;
/* regard all non-zero value as enable */
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR, !!arg);
break;
case PIN_CONFIG_OUTPUT:
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
@ -273,41 +255,29 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO,
arg);
if (err)
goto err;
break;
case PIN_CONFIG_INPUT_SCHMITT:
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
/* arg = 1: Input mode & SMT enable ;
* arg = 0: Output mode & SMT disable
*/
arg = arg ? 2 : 1;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
arg & 1);
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !arg);
if (err)
goto err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
!!(arg & 2));
if (err)
goto err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, !!arg);
break;
case PIN_CONFIG_DRIVE_STRENGTH:
if (hw->soc->drive_set) {
if (hw->soc->drive_set)
err = hw->soc->drive_set(hw, desc, arg);
if (err)
return err;
} else {
return -ENOTSUPP;
}
else
err = -ENOTSUPP;
break;
case MTK_PIN_CONFIG_TDSEL:
case MTK_PIN_CONFIG_RDSEL:
reg = (param == MTK_PIN_CONFIG_TDSEL) ?
PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
err = mtk_hw_set_value(hw, desc, reg, arg);
if (err)
goto err;
break;
case MTK_PIN_CONFIG_PU_ADV:
case MTK_PIN_CONFIG_PD_ADV:
@ -317,20 +287,14 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
pullup = param == MTK_PIN_CONFIG_PU_ADV;
err = hw->soc->adv_pull_set(hw, desc, pullup,
arg);
if (err)
return err;
} else {
return -ENOTSUPP;
}
} else
err = -ENOTSUPP;
break;
case MTK_PIN_CONFIG_DRV_ADV:
if (hw->soc->adv_drive_set) {
if (hw->soc->adv_drive_set)
err = hw->soc->adv_drive_set(hw, desc, arg);
if (err)
return err;
} else {
return -ENOTSUPP;
}
else
err = -ENOTSUPP;
break;
default:
err = -ENOTSUPP;
@ -575,12 +539,120 @@ static int mtk_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
return 0;
}
static int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int field)
{
const struct mtk_pin_desc *desc;
int value, err;
if (gpio >= hw->soc->npins)
return -EINVAL;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
err = mtk_hw_get_value(hw, desc, field, &value);
if (err)
return err;
return value;
}
#define mtk_pctrl_get_pinmux(hw, gpio) \
mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_MODE)
#define mtk_pctrl_get_direction(hw, gpio) \
mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DIR)
#define mtk_pctrl_get_out(hw, gpio) \
mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DO)
#define mtk_pctrl_get_in(hw, gpio) \
mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DI)
#define mtk_pctrl_get_smt(hw, gpio) \
mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_SMT)
#define mtk_pctrl_get_ies(hw, gpio) \
mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_IES)
#define mtk_pctrl_get_driving(hw, gpio) \
mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DRV)
ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
unsigned int gpio, char *buf, unsigned int bufLen)
{
int pinmux, pullup, pullen, len = 0, r1 = -1, r0 = -1;
const struct mtk_pin_desc *desc;
if (gpio >= hw->soc->npins)
return -EINVAL;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
pinmux = mtk_pctrl_get_pinmux(hw, gpio);
if (pinmux >= hw->soc->nfuncs)
pinmux -= hw->soc->nfuncs;
mtk_pinconf_bias_get_combo(hw, desc, &pullup, &pullen);
if (pullen == MTK_PUPD_SET_R1R0_00) {
pullen = 0;
r1 = 0;
r0 = 0;
} else if (pullen == MTK_PUPD_SET_R1R0_01) {
pullen = 1;
r1 = 0;
r0 = 1;
} else if (pullen == MTK_PUPD_SET_R1R0_10) {
pullen = 1;
r1 = 1;
r0 = 0;
} else if (pullen == MTK_PUPD_SET_R1R0_11) {
pullen = 1;
r1 = 1;
r0 = 1;
} else if (pullen != MTK_DISABLE && pullen != MTK_ENABLE) {
pullen = 0;
}
len += scnprintf(buf + len, bufLen - len,
"%03d: %1d%1d%1d%1d%02d%1d%1d%1d%1d",
gpio,
pinmux,
mtk_pctrl_get_direction(hw, gpio),
mtk_pctrl_get_out(hw, gpio),
mtk_pctrl_get_in(hw, gpio),
mtk_pctrl_get_driving(hw, gpio),
mtk_pctrl_get_smt(hw, gpio),
mtk_pctrl_get_ies(hw, gpio),
pullen,
pullup);
if (r1 != -1) {
len += scnprintf(buf + len, bufLen - len, " (%1d %1d)\n",
r1, r0);
} else {
len += scnprintf(buf + len, bufLen - len, "\n");
}
return len;
}
#define PIN_DBG_BUF_SZ 96
static void mtk_pctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
unsigned int gpio)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
char buf[PIN_DBG_BUF_SZ];
(void)mtk_pctrl_show_one_pin(hw, gpio, buf, PIN_DBG_BUF_SZ);
seq_printf(s, "%s", buf);
}
static const struct pinctrl_ops mtk_pctlops = {
.dt_node_to_map = mtk_pctrl_dt_node_to_map,
.dt_free_map = pinctrl_utils_free_map,
.get_groups_count = mtk_pctrl_get_groups_count,
.get_group_name = mtk_pctrl_get_group_name,
.get_group_pins = mtk_pctrl_get_group_pins,
.pin_dbg_show = mtk_pctrl_dbg_show,
};
static int mtk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
@ -677,6 +749,7 @@ static const struct pinconf_ops mtk_confops = {
.pin_config_get = mtk_pinconf_get,
.pin_config_group_get = mtk_pconf_group_get,
.pin_config_group_set = mtk_pconf_group_set,
.is_generic = true,
};
static struct pinctrl_desc mtk_desc = {
@ -693,13 +766,19 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
const struct mtk_pin_desc *desc;
int value, err;
if (gpio >= hw->soc->npins)
return -EINVAL;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value);
if (err)
return err;
return !value;
if (value)
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
}
static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)
@ -708,6 +787,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)
const struct mtk_pin_desc *desc;
int value, err;
if (gpio >= hw->soc->npins)
return -EINVAL;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
@ -722,6 +804,9 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
const struct mtk_pin_desc *desc;
if (gpio >= hw->soc->npins)
return;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
@ -729,12 +814,22 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
{
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
if (gpio >= hw->soc->npins)
return -EINVAL;
return pinctrl_gpio_direction_input(chip->base + gpio);
}
static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,
int value)
{
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
if (gpio >= hw->soc->npins)
return -EINVAL;
mtk_gpio_set(chip, gpio, value);
return pinctrl_gpio_direction_output(chip->base + gpio);

View File

@ -60,6 +60,9 @@
int mtk_paris_pinctrl_probe(struct platform_device *pdev,
const struct mtk_pin_soc *soc);
ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
unsigned int gpio, char *buf, unsigned int bufLen);
extern const struct dev_pm_ops mtk_paris_pinctrl_pm_ops;
#endif /* __PINCTRL_PARIS_H */

View File

@ -231,10 +231,24 @@ static const unsigned int hdmi_hpd_pins[] = { GPIOH_0 };
static const unsigned int hdmi_sda_pins[] = { GPIOH_1 };
static const unsigned int hdmi_scl_pins[] = { GPIOH_2 };
static const unsigned int tsin_a_d_valid_pins[] = { GPIOY_0 };
static const unsigned int tsin_a_sop_pins[] = { GPIOY_1 };
static const unsigned int tsin_a_clk_pins[] = { GPIOY_2 };
static const unsigned int tsin_a_d0_pins[] = { GPIOY_3 };
static const unsigned int tsin_a_dp_pins[] = {
GPIOY_4, GPIOY_5, GPIOY_6, GPIOY_7, GPIOY_8, GPIOY_9, GPIOY_10
};
static const unsigned int tsin_a_fail_pins[] = { GPIOY_11 };
static const unsigned int i2s_out_ch23_y_pins[] = { GPIOY_8 };
static const unsigned int i2s_out_ch45_y_pins[] = { GPIOY_9 };
static const unsigned int i2s_out_ch67_y_pins[] = { GPIOY_10 };
static const unsigned int tsin_b_d_valid_pins[] = { GPIOX_6 };
static const unsigned int tsin_b_sop_pins[] = { GPIOX_7 };
static const unsigned int tsin_b_clk_pins[] = { GPIOX_8 };
static const unsigned int tsin_b_d0_pins[] = { GPIOX_9 };
static const unsigned int spdif_out_y_pins[] = { GPIOY_12 };
static const unsigned int gen_clk_out_pins[] = { GPIOY_15 };
@ -437,12 +451,22 @@ static struct meson_pmx_group meson_gxbb_periphs_groups[] = {
GROUP(pwm_a_x, 3, 17),
GROUP(pwm_e, 2, 30),
GROUP(pwm_f_x, 3, 18),
GROUP(tsin_b_d_valid, 3, 9),
GROUP(tsin_b_sop, 3, 8),
GROUP(tsin_b_clk, 3, 10),
GROUP(tsin_b_d0, 3, 7),
/* Bank Y */
GROUP(uart_cts_c, 1, 17),
GROUP(uart_rts_c, 1, 16),
GROUP(uart_tx_c, 1, 19),
GROUP(uart_rx_c, 1, 18),
GROUP(tsin_a_fail, 3, 3),
GROUP(tsin_a_d_valid, 3, 2),
GROUP(tsin_a_sop, 3, 1),
GROUP(tsin_a_clk, 3, 0),
GROUP(tsin_a_d0, 3, 4),
GROUP(tsin_a_dp, 3, 5),
GROUP(pwm_a_y, 1, 21),
GROUP(pwm_f_y, 1, 20),
GROUP(i2s_out_ch23_y, 1, 5),
@ -601,6 +625,15 @@ static const char * const gpio_periphs_groups[] = {
"GPIOX_20", "GPIOX_21", "GPIOX_22",
};
static const char * const tsin_a_groups[] = {
"tsin_a_clk", "tsin_a_sop", "tsin_a_d_valid", "tsin_a_d0",
"tsin_a_dp", "tsin_a_fail",
};
static const char * const tsin_b_groups[] = {
"tsin_b_clk", "tsin_b_sop", "tsin_b_d_valid", "tsin_b_d0",
};
static const char * const emmc_groups[] = {
"emmc_nand_d07", "emmc_clk", "emmc_cmd", "emmc_ds",
};
@ -792,6 +825,8 @@ static struct meson_pmx_func meson_gxbb_periphs_functions[] = {
FUNCTION(i2s_out),
FUNCTION(spdif_out),
FUNCTION(gen_clk_out),
FUNCTION(tsin_a),
FUNCTION(tsin_b),
};
static struct meson_pmx_func meson_gxbb_aobus_functions[] = {

View File

@ -241,6 +241,17 @@ static const unsigned int tsin_a_dp_pins[] = {
GPIODV_1, GPIODV_2, GPIODV_3, GPIODV_4, GPIODV_5, GPIODV_6, GPIODV_7,
};
static const unsigned int tsin_b_clk_pins[] = { GPIOH_6 };
static const unsigned int tsin_b_d0_pins[] = { GPIOH_7 };
static const unsigned int tsin_b_sop_pins[] = { GPIOH_8 };
static const unsigned int tsin_b_d_valid_pins[] = { GPIOH_9 };
static const unsigned int tsin_b_fail_z4_pins[] = { GPIOZ_4 };
static const unsigned int tsin_b_clk_z3_pins[] = { GPIOZ_3 };
static const unsigned int tsin_b_d0_z2_pins[] = { GPIOZ_2 };
static const unsigned int tsin_b_sop_z1_pins[] = { GPIOZ_1 };
static const unsigned int tsin_b_d_valid_z0_pins[] = { GPIOZ_0 };
static const struct pinctrl_pin_desc meson_gxl_aobus_pins[] = {
MESON_PIN(GPIOAO_0),
MESON_PIN(GPIOAO_1),
@ -438,6 +449,11 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = {
GROUP(eth_txd1, 4, 12),
GROUP(eth_txd2, 4, 11),
GROUP(eth_txd3, 4, 10),
GROUP(tsin_b_fail_z4, 3, 15),
GROUP(tsin_b_clk_z3, 3, 16),
GROUP(tsin_b_d0_z2, 3, 17),
GROUP(tsin_b_sop_z1, 3, 18),
GROUP(tsin_b_d_valid_z0, 3, 19),
GROUP(pwm_c, 3, 20),
GROUP(i2s_out_ch23_z, 3, 26),
GROUP(i2s_out_ch45_z, 3, 25),
@ -454,6 +470,10 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = {
GROUP(i2s_out_lr_clk, 6, 24),
GROUP(i2s_out_ch01, 6, 23),
GROUP(spdif_out_h, 6, 28),
GROUP(tsin_b_d0, 6, 17),
GROUP(tsin_b_sop, 6, 18),
GROUP(tsin_b_d_valid, 6, 19),
GROUP(tsin_b_clk, 6, 20),
/* Bank DV */
GROUP(uart_tx_b, 2, 16),
@ -689,6 +709,12 @@ static const char * const tsin_a_groups[] = {
"tsin_a_dp", "tsin_a_fail",
};
static const char * const tsin_b_groups[] = {
"tsin_b_clk", "tsin_b_sop", "tsin_b_d_valid", "tsin_b_d0",
"tsin_b_clk_z3", "tsin_b_sop_z1", "tsin_b_d_valid_z0", "tsin_b_d0_z2",
"tsin_b_fail_z4",
};
static const char * const gpio_aobus_groups[] = {
"GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4",
"GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9",
@ -764,6 +790,7 @@ static struct meson_pmx_func meson_gxl_periphs_functions[] = {
FUNCTION(spdif_out),
FUNCTION(eth_led),
FUNCTION(tsin_a),
FUNCTION(tsin_b),
};
static struct meson_pmx_func meson_gxl_aobus_functions[] = {

View File

@ -15,6 +15,7 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinctrl.h>
@ -402,7 +403,10 @@ static int armada_37xx_gpio_get_direction(struct gpio_chip *chip,
mask = BIT(offset);
regmap_read(info->regmap, reg, &val);
return !(val & mask);
if (val & mask)
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
}
static int armada_37xx_gpio_direction_output(struct gpio_chip *chip,
@ -738,14 +742,7 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev,
return ret;
}
nr_irq_parent = platform_irq_count(pdev);
if (nr_irq_parent < 0) {
if (nr_irq_parent != -EPROBE_DEFER)
dev_err(dev, "Couldn't determine irq count: %pe\n",
ERR_PTR(nr_irq_parent));
return nr_irq_parent;
}
nr_irq_parent = of_irq_count(np);
spin_lock_init(&info->irq_lock);
if (!nr_irq_parent) {
@ -782,7 +779,7 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev,
if (!girq->parents)
return -ENOMEM;
for (i = 0; i < nr_irq_parent; i++) {
int irq = platform_get_irq(pdev, i);
int irq = irq_of_parse_and_map(np, i);
if (irq < 0)
continue;

View File

@ -831,11 +831,14 @@ static int nmk_gpio_get_dir(struct gpio_chip *chip, unsigned offset)
clk_enable(nmk_chip->clk);
dir = !(readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset));
dir = readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset);
clk_disable(nmk_chip->clk);
return dir;
if (dir)
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
}
static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)

View File

@ -286,6 +286,7 @@ out:
kfree(cfg);
return ret;
}
EXPORT_SYMBOL_GPL(pinconf_generic_parse_dt_config);
int pinconf_generic_dt_subnode_to_map(struct pinctrl_dev *pctldev,
struct device_node *np, struct pinctrl_map **map,

View File

@ -46,7 +46,10 @@ static int amd_gpio_get_direction(struct gpio_chip *gc, unsigned offset)
pin_reg = readl(gpio_dev->base + offset * 4);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
return !(pin_reg & BIT(OUTPUT_ENABLE_OFF));
if (pin_reg & BIT(OUTPUT_ENABLE_OFF))
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
}
static int amd_gpio_direction_input(struct gpio_chip *gc, unsigned offset)

View File

@ -1414,7 +1414,10 @@ static int at91_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
u32 osr;
osr = readl_relaxed(pio + PIO_OSR);
return !(osr & mask);
if (osr & mask)
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
}
static int at91_gpio_direction_input(struct gpio_chip *chip, unsigned offset)

View File

@ -149,13 +149,16 @@ static int axp20x_gpio_get_direction(struct gpio_chip *chip,
* going to change the value soon anyway. Default to output.
*/
if ((val & AXP20X_GPIO_FUNCTIONS) > 2)
return 0;
return GPIO_LINE_DIRECTION_OUT;
/*
* The GPIO directions are the three lowest values.
* 2 is input, 0 and 1 are output
*/
return val & 2;
if (val & 2)
return GPIO_LINE_DIRECTION_IN;
return GPIO_LINE_DIRECTION_OUT;
}
static int axp20x_gpio_output(struct gpio_chip *chip, unsigned int offset,

View File

@ -0,0 +1,300 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Dialog DA9062 pinctrl and GPIO driver.
* Based on DA9055 GPIO driver.
*
* TODO:
* - add pinmux and pinctrl support (gpio alternate mode)
*
* Documents:
* [1] https://www.dialog-semiconductor.com/sites/default/files/da9062_datasheet_3v6.pdf
*
* Copyright (C) 2019 Pengutronix, Marco Felsch <kernel@pengutronix.de>
*/
#include <linux/bits.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/gpio/driver.h>
#include <linux/mfd/da9062/core.h>
#include <linux/mfd/da9062/registers.h>
/*
* We need this get the gpio_desc from a <gpio_chip,offset> tuple to decide if
* the gpio is active low without a vendor specific dt-binding.
*/
#include "../gpio/gpiolib.h"
#define DA9062_TYPE(offset) (4 * (offset % 2))
#define DA9062_PIN_SHIFT(offset) (4 * (offset % 2))
#define DA9062_PIN_ALTERNATE 0x00 /* gpio alternate mode */
#define DA9062_PIN_GPI 0x01 /* gpio in */
#define DA9062_PIN_GPO_OD 0x02 /* gpio out open-drain */
#define DA9062_PIN_GPO_PP 0x03 /* gpio out push-pull */
#define DA9062_GPIO_NUM 5
struct da9062_pctl {
struct da9062 *da9062;
struct gpio_chip gc;
unsigned int pin_config[DA9062_GPIO_NUM];
};
static int da9062_pctl_get_pin_mode(struct da9062_pctl *pctl,
unsigned int offset)
{
struct regmap *regmap = pctl->da9062->regmap;
int ret, val;
ret = regmap_read(regmap, DA9062AA_GPIO_0_1 + (offset >> 1), &val);
if (ret < 0)
return ret;
val >>= DA9062_PIN_SHIFT(offset);
val &= DA9062AA_GPIO0_PIN_MASK;
return val;
}
static int da9062_pctl_set_pin_mode(struct da9062_pctl *pctl,
unsigned int offset, unsigned int mode_req)
{
struct regmap *regmap = pctl->da9062->regmap;
unsigned int mode = mode_req;
unsigned int mask;
int ret;
mode &= DA9062AA_GPIO0_PIN_MASK;
mode <<= DA9062_PIN_SHIFT(offset);
mask = DA9062AA_GPIO0_PIN_MASK << DA9062_PIN_SHIFT(offset);
ret = regmap_update_bits(regmap, DA9062AA_GPIO_0_1 + (offset >> 1),
mask, mode);
if (!ret)
pctl->pin_config[offset] = mode_req;
return ret;
}
static int da9062_gpio_get(struct gpio_chip *gc, unsigned int offset)
{
struct da9062_pctl *pctl = gpiochip_get_data(gc);
struct regmap *regmap = pctl->da9062->regmap;
int gpio_mode, val;
int ret;
gpio_mode = da9062_pctl_get_pin_mode(pctl, offset);
if (gpio_mode < 0)
return gpio_mode;
switch (gpio_mode) {
case DA9062_PIN_ALTERNATE:
return -ENOTSUPP;
case DA9062_PIN_GPI:
ret = regmap_read(regmap, DA9062AA_STATUS_B, &val);
if (ret < 0)
return ret;
break;
case DA9062_PIN_GPO_OD:
case DA9062_PIN_GPO_PP:
ret = regmap_read(regmap, DA9062AA_GPIO_MODE0_4, &val);
if (ret < 0)
return ret;
}
return !!(val & BIT(offset));
}
static void da9062_gpio_set(struct gpio_chip *gc, unsigned int offset,
int value)
{
struct da9062_pctl *pctl = gpiochip_get_data(gc);
struct regmap *regmap = pctl->da9062->regmap;
regmap_update_bits(regmap, DA9062AA_GPIO_MODE0_4, BIT(offset),
value << offset);
}
static int da9062_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
{
struct da9062_pctl *pctl = gpiochip_get_data(gc);
int gpio_mode;
gpio_mode = da9062_pctl_get_pin_mode(pctl, offset);
if (gpio_mode < 0)
return gpio_mode;
switch (gpio_mode) {
case DA9062_PIN_ALTERNATE:
return -ENOTSUPP;
case DA9062_PIN_GPI:
return GPIO_LINE_DIRECTION_IN;
case DA9062_PIN_GPO_OD:
case DA9062_PIN_GPO_PP:
return GPIO_LINE_DIRECTION_OUT;
}
return -EINVAL;
}
static int da9062_gpio_direction_input(struct gpio_chip *gc,
unsigned int offset)
{
struct da9062_pctl *pctl = gpiochip_get_data(gc);
struct regmap *regmap = pctl->da9062->regmap;
struct gpio_desc *desc = gpiochip_get_desc(gc, offset);
unsigned int gpi_type;
int ret;
ret = da9062_pctl_set_pin_mode(pctl, offset, DA9062_PIN_GPI);
if (ret)
return ret;
/*
* If the gpio is active low we should set it in hw too. No worries
* about gpio_get() because we read and return the gpio-level. So the
* gpiolib active_low handling is still correct.
*
* 0 - active low, 1 - active high
*/
gpi_type = !gpiod_is_active_low(desc);
return regmap_update_bits(regmap, DA9062AA_GPIO_0_1 + (offset >> 1),
DA9062AA_GPIO0_TYPE_MASK << DA9062_TYPE(offset),
gpi_type << DA9062_TYPE(offset));
}
static int da9062_gpio_direction_output(struct gpio_chip *gc,
unsigned int offset, int value)
{
struct da9062_pctl *pctl = gpiochip_get_data(gc);
unsigned int pin_config = pctl->pin_config[offset];
int ret;
ret = da9062_pctl_set_pin_mode(pctl, offset, pin_config);
if (ret)
return ret;
da9062_gpio_set(gc, offset, value);
return 0;
}
static int da9062_gpio_set_config(struct gpio_chip *gc, unsigned int offset,
unsigned long config)
{
struct da9062_pctl *pctl = gpiochip_get_data(gc);
struct regmap *regmap = pctl->da9062->regmap;
int gpio_mode;
/*
* We need to meet the following restrictions [1, Figure 18]:
* - PIN_CONFIG_BIAS_PULL_DOWN -> only allowed if the pin is used as
* gpio input
* - PIN_CONFIG_BIAS_PULL_UP -> only allowed if the pin is used as
* gpio output open-drain.
*/
switch (pinconf_to_config_param(config)) {
case PIN_CONFIG_BIAS_DISABLE:
return regmap_update_bits(regmap, DA9062AA_CONFIG_K,
BIT(offset), 0);
case PIN_CONFIG_BIAS_PULL_DOWN:
gpio_mode = da9062_pctl_get_pin_mode(pctl, offset);
if (gpio_mode < 0)
return -EINVAL;
else if (gpio_mode != DA9062_PIN_GPI)
return -ENOTSUPP;
return regmap_update_bits(regmap, DA9062AA_CONFIG_K,
BIT(offset), BIT(offset));
case PIN_CONFIG_BIAS_PULL_UP:
gpio_mode = da9062_pctl_get_pin_mode(pctl, offset);
if (gpio_mode < 0)
return -EINVAL;
else if (gpio_mode != DA9062_PIN_GPO_OD)
return -ENOTSUPP;
return regmap_update_bits(regmap, DA9062AA_CONFIG_K,
BIT(offset), BIT(offset));
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
return da9062_pctl_set_pin_mode(pctl, offset,
DA9062_PIN_GPO_OD);
case PIN_CONFIG_DRIVE_PUSH_PULL:
return da9062_pctl_set_pin_mode(pctl, offset,
DA9062_PIN_GPO_PP);
default:
return -ENOTSUPP;
}
}
static int da9062_gpio_to_irq(struct gpio_chip *gc, unsigned int offset)
{
struct da9062_pctl *pctl = gpiochip_get_data(gc);
struct da9062 *da9062 = pctl->da9062;
return regmap_irq_get_virq(da9062->regmap_irq,
DA9062_IRQ_GPI0 + offset);
}
static const struct gpio_chip reference_gc = {
.owner = THIS_MODULE,
.get = da9062_gpio_get,
.set = da9062_gpio_set,
.get_direction = da9062_gpio_get_direction,
.direction_input = da9062_gpio_direction_input,
.direction_output = da9062_gpio_direction_output,
.set_config = da9062_gpio_set_config,
.to_irq = da9062_gpio_to_irq,
.can_sleep = true,
.ngpio = DA9062_GPIO_NUM,
.base = -1,
};
static int da9062_pctl_probe(struct platform_device *pdev)
{
struct device *parent = pdev->dev.parent;
struct da9062_pctl *pctl;
int i;
pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
if (!pctl)
return -ENOMEM;
pctl->da9062 = dev_get_drvdata(parent);
if (!pctl->da9062)
return -EINVAL;
if (!device_property_present(parent, "gpio-controller"))
return 0;
for (i = 0; i < ARRAY_SIZE(pctl->pin_config); i++)
pctl->pin_config[i] = DA9062_PIN_GPO_PP;
/*
* Currently the driver handles only the GPIO support. The
* pinctrl/pinmux support can be added later if needed.
*/
pctl->gc = reference_gc;
pctl->gc.label = dev_name(&pdev->dev);
pctl->gc.parent = &pdev->dev;
#ifdef CONFIG_OF_GPIO
pctl->gc.of_node = parent->of_node;
#endif
platform_set_drvdata(pdev, pctl);
return devm_gpiochip_add_data(&pdev->dev, &pctl->gc, pctl);
}
static struct platform_driver da9062_pctl_driver = {
.probe = da9062_pctl_probe,
.driver = {
.name = "da9062-gpio",
},
};
module_platform_driver(da9062_pctl_driver);
MODULE_AUTHOR("Marco Felsch <kernel@pengutronix.de>");
MODULE_DESCRIPTION("DA9062 PMIC pinctrl and GPIO Driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:da9062-gpio");

View File

@ -4,6 +4,7 @@
*
* Copyright (c) 2017 Paul Cercueil <paul@crapouillou.net>
* Copyright (c) 2019 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
* Copyright (c) 2017, 2019 Paul Boddie <paul@boddie.org.uk>
*/
#include <linux/compiler.h>
@ -900,6 +901,7 @@ static int jz4780_mmc0_8bit_a_pins[] = { 0x04, 0x05, 0x06, 0x07, 0x18, };
static int jz4780_i2c3_pins[] = { 0x6a, 0x6b, };
static int jz4780_i2c4_e_pins[] = { 0x8c, 0x8d, };
static int jz4780_i2c4_f_pins[] = { 0xb9, 0xb8, };
static int jz4780_hdmi_ddc_pins[] = { 0xb9, 0xb8, };
static int jz4780_uart2_data_funcs[] = { 1, 1, };
static int jz4780_uart2_hwflow_funcs[] = { 1, 1, };
@ -908,6 +910,7 @@ static int jz4780_mmc0_8bit_a_funcs[] = { 1, 1, 1, 1, 1, };
static int jz4780_i2c3_funcs[] = { 1, 1, };
static int jz4780_i2c4_e_funcs[] = { 1, 1, };
static int jz4780_i2c4_f_funcs[] = { 1, 1, };
static int jz4780_hdmi_ddc_funcs[] = { 0, 0, };
static const struct group_desc jz4780_groups[] = {
INGENIC_PIN_GROUP("uart0-data", jz4770_uart0_data),
@ -950,6 +953,7 @@ static const struct group_desc jz4780_groups[] = {
INGENIC_PIN_GROUP("i2c3-data", jz4780_i2c3),
INGENIC_PIN_GROUP("i2c4-data-e", jz4780_i2c4_e),
INGENIC_PIN_GROUP("i2c4-data-f", jz4780_i2c4_f),
INGENIC_PIN_GROUP("hdmi-ddc", jz4780_hdmi_ddc),
INGENIC_PIN_GROUP("cim-data", jz4770_cim_8bit),
INGENIC_PIN_GROUP("lcd-24bit", jz4770_lcd_24bit),
{ "lcd-no-pins", },
@ -982,6 +986,7 @@ static const char *jz4780_nemc_groups[] = {
static const char *jz4780_i2c3_groups[] = { "i2c3-data", };
static const char *jz4780_i2c4_groups[] = { "i2c4-data-e", "i2c4-data-f", };
static const char *jz4780_cim_groups[] = { "cim-data", };
static const char *jz4780_hdmi_ddc_groups[] = { "hdmi-ddc", };
static const struct function_desc jz4780_functions[] = {
{ "uart0", jz4770_uart0_groups, ARRAY_SIZE(jz4770_uart0_groups), },
@ -1014,6 +1019,8 @@ static const struct function_desc jz4780_functions[] = {
{ "pwm5", jz4770_pwm5_groups, ARRAY_SIZE(jz4770_pwm5_groups), },
{ "pwm6", jz4770_pwm6_groups, ARRAY_SIZE(jz4770_pwm6_groups), },
{ "pwm7", jz4770_pwm7_groups, ARRAY_SIZE(jz4770_pwm7_groups), },
{ "hdmi-ddc", jz4780_hdmi_ddc_groups,
ARRAY_SIZE(jz4780_hdmi_ddc_groups), },
};
static const struct ingenic_chip_info jz4780_chip_info = {
@ -1437,6 +1444,19 @@ static int x1830_mmc1_4bit_pins[] = { 0x45, 0x46, 0x47, };
static int x1830_i2c0_pins[] = { 0x0c, 0x0d, };
static int x1830_i2c1_pins[] = { 0x39, 0x3a, };
static int x1830_i2c2_pins[] = { 0x5b, 0x5c, };
static int x1830_lcd_rgb_18bit_pins[] = {
0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b,
};
static int x1830_lcd_slcd_8bit_pins[] = {
0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x6c, 0x6d,
0x69, 0x72, 0x73, 0x7b, 0x7a,
};
static int x1830_lcd_slcd_16bit_pins[] = {
0x6e, 0x6f, 0x70, 0x71, 0x76, 0x77, 0x78, 0x79,
};
static int x1830_pwm_pwm0_b_pins[] = { 0x31, };
static int x1830_pwm_pwm0_c_pins[] = { 0x4b, };
static int x1830_pwm_pwm1_b_pins[] = { 0x32, };
@ -1486,6 +1506,16 @@ static int x1830_mmc1_4bit_funcs[] = { 0, 0, 0, };
static int x1830_i2c0_funcs[] = { 1, 1, };
static int x1830_i2c1_funcs[] = { 0, 0, };
static int x1830_i2c2_funcs[] = { 1, 1, };
static int x1830_lcd_rgb_18bit_funcs[] = {
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0,
};
static int x1830_lcd_slcd_8bit_funcs[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
};
static int x1830_lcd_slcd_16bit_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, };
static int x1830_pwm_pwm0_b_funcs[] = { 0, };
static int x1830_pwm_pwm0_c_funcs[] = { 1, };
static int x1830_pwm_pwm1_b_funcs[] = { 0, };
@ -1534,6 +1564,10 @@ static const struct group_desc x1830_groups[] = {
INGENIC_PIN_GROUP("i2c0-data", x1830_i2c0),
INGENIC_PIN_GROUP("i2c1-data", x1830_i2c1),
INGENIC_PIN_GROUP("i2c2-data", x1830_i2c2),
INGENIC_PIN_GROUP("lcd-rgb-18bit", x1830_lcd_rgb_18bit),
INGENIC_PIN_GROUP("lcd-slcd-8bit", x1830_lcd_slcd_8bit),
INGENIC_PIN_GROUP("lcd-slcd-16bit", x1830_lcd_slcd_16bit),
{ "lcd-no-pins", },
INGENIC_PIN_GROUP("pwm0-b", x1830_pwm_pwm0_b),
INGENIC_PIN_GROUP("pwm0-c", x1830_pwm_pwm0_c),
INGENIC_PIN_GROUP("pwm1-b", x1830_pwm_pwm1_b),
@ -1572,6 +1606,9 @@ static const char *x1830_mmc1_groups[] = { "mmc1-1bit", "mmc1-4bit", };
static const char *x1830_i2c0_groups[] = { "i2c0-data", };
static const char *x1830_i2c1_groups[] = { "i2c1-data", };
static const char *x1830_i2c2_groups[] = { "i2c2-data", };
static const char *x1830_lcd_groups[] = {
"lcd-rgb-18bit", "lcd-slcd-8bit", "lcd-slcd-16bit", "lcd-no-pins",
};
static const char *x1830_pwm0_groups[] = { "pwm0-b", "pwm0-c", };
static const char *x1830_pwm1_groups[] = { "pwm1-b", "pwm1-c", };
static const char *x1830_pwm2_groups[] = { "pwm2-c-8", "pwm2-c-13", };
@ -1593,6 +1630,7 @@ static const struct function_desc x1830_functions[] = {
{ "i2c0", x1830_i2c0_groups, ARRAY_SIZE(x1830_i2c0_groups), },
{ "i2c1", x1830_i2c1_groups, ARRAY_SIZE(x1830_i2c1_groups), },
{ "i2c2", x1830_i2c2_groups, ARRAY_SIZE(x1830_i2c2_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), },
{ "pwm2", x1830_pwm2_groups, ARRAY_SIZE(x1830_pwm2_groups), },
@ -1916,13 +1954,19 @@ static int ingenic_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
struct ingenic_pinctrl *jzpc = jzgc->jzpc;
unsigned int pin = gc->base + offset;
if (jzpc->info->version >= ID_JZ4760)
return ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PAT1);
if (jzpc->info->version >= ID_JZ4760) {
if (ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PAT1))
return GPIO_LINE_DIRECTION_IN;
return GPIO_LINE_DIRECTION_OUT;
}
if (ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_SELECT))
return true;
return GPIO_LINE_DIRECTION_IN;
return !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_DIR);
if (ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_DIR))
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
}
static const struct pinctrl_ops ingenic_pctlops = {
@ -2158,7 +2202,8 @@ static int ingenic_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
break;
default:
unreachable();
/* unreachable */
break;
}
}

View File

@ -604,7 +604,10 @@ static int ocelot_gpio_get_direction(struct gpio_chip *chip,
regmap_read(info->map, REG(OCELOT_GPIO_OE, info, offset), &val);
return !(val & BIT(offset % 32));
if (val & BIT(offset % 32))
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
}
static int ocelot_gpio_direction_input(struct gpio_chip *chip,

View File

@ -756,7 +756,10 @@ static int oxnas_gpio_get_direction(struct gpio_chip *chip,
struct oxnas_gpio_bank *bank = gpiochip_get_data(chip);
u32 mask = BIT(offset);
return !(readl_relaxed(bank->reg_base + OUTPUT_EN) & mask);
if (readl_relaxed(bank->reg_base + OUTPUT_EN) & mask)
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
}
static int oxnas_gpio_direction_input(struct gpio_chip *chip,

View File

@ -1990,7 +1990,10 @@ static int pic32_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
{
struct pic32_gpio_bank *bank = gpiochip_get_data(chip);
return !!(readl(bank->reg_base + TRIS_REG) & BIT(offset));
if (readl(bank->reg_base + TRIS_REG) & BIT(offset))
return GPIO_LINE_DIRECTION_IN;
return GPIO_LINE_DIRECTION_OUT;
}
static void pic32_gpio_irq_ack(struct irq_data *data)

View File

@ -1166,7 +1166,10 @@ static int pistachio_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
{
struct pistachio_gpio_bank *bank = gpiochip_get_data(chip);
return !(gpio_readl(bank, GPIO_OUTPUT_EN) & BIT(offset));
if (gpio_readl(bank, GPIO_OUTPUT_EN) & BIT(offset))
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
}
static int pistachio_gpio_get(struct gpio_chip *chip, unsigned offset)

View File

@ -184,7 +184,7 @@ static int rk805_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
/* default output*/
if (!pci->pin_cfg[offset].dir_msk)
return 0;
return GPIO_LINE_DIRECTION_OUT;
ret = regmap_read(pci->rk808->regmap,
pci->pin_cfg[offset].reg,
@ -194,7 +194,10 @@ static int rk805_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
return ret;
}
return !(val & pci->pin_cfg[offset].dir_msk);
if (val & pci->pin_cfg[offset].dir_msk)
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
}
static const struct gpio_chip rk805_gpio_chip = {

View File

@ -2549,7 +2549,10 @@ static int rockchip_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
clk_disable(bank->clk);
return !(data & BIT(offset));
if (data & BIT(offset))
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
}
/*

View File

@ -777,7 +777,10 @@ static int rza1_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
{
struct rza1_port *port = gpiochip_get_data(chip);
return !!rza1_get_bit(port, RZA1_PM_REG, gpio);
if (rza1_get_bit(port, RZA1_PM_REG, gpio))
return GPIO_LINE_DIRECTION_IN;
return GPIO_LINE_DIRECTION_OUT;
}
static int rza1_gpio_direction_input(struct gpio_chip *chip,

View File

@ -135,10 +135,10 @@ static int rza2_chip_get_direction(struct gpio_chip *chip, unsigned int offset)
reg16 = (reg16 >> (pin * 2)) & RZA2_PDR_MASK;
if (reg16 == RZA2_PDR_OUTPUT)
return 0;
return GPIO_LINE_DIRECTION_OUT;
if (reg16 == RZA2_PDR_INPUT)
return 1;
return GPIO_LINE_DIRECTION_IN;
/*
* This GPIO controller has a default Hi-Z state that is not input or
@ -146,7 +146,7 @@ static int rza2_chip_get_direction(struct gpio_chip *chip, unsigned int offset)
*/
rza2_pin_to_gpio(priv->base, offset, 1);
return 1;
return GPIO_LINE_DIRECTION_IN;
}
static int rza2_chip_direction_input(struct gpio_chip *chip,

View File

@ -746,7 +746,10 @@ static int st_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
function = st_pctl_get_pin_function(&pc, offset);
if (function) {
st_pinconf_get_direction(&pc, offset, &config);
return !ST_PINCONF_UNPACK_OE(config);
if (ST_PINCONF_UNPACK_OE(config))
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
}
/*
@ -758,7 +761,10 @@ static int st_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
direction |= ((value >> offset) & 0x1) << i;
}
return (direction == ST_GPIO_DIRECTION_IN);
if (direction == ST_GPIO_DIRECTION_IN)
return GPIO_LINE_DIRECTION_IN;
return GPIO_LINE_DIRECTION_OUT;
}
/* Pinctrl Groups */
@ -996,6 +1002,7 @@ static void st_pinconf_dbg_show(struct pinctrl_dev *pctldev,
unsigned int function;
int offset = st_gpio_pin(pin_id);
char f[16];
int oe;
mutex_unlock(&pctldev->mutex);
pc = st_get_pio_control(pctldev, pin_id);
@ -1008,10 +1015,11 @@ static void st_pinconf_dbg_show(struct pinctrl_dev *pctldev,
else
snprintf(f, 5, "GPIO");
oe = st_gpio_get_direction(&pc_to_bank(pc)->gpio_chip, offset);
seq_printf(s, "[OE:%d,PU:%ld,OD:%ld]\t%s\n"
"\t\t[retime:%ld,invclk:%ld,clknotdat:%ld,"
"de:%ld,rt-clk:%ld,rt-delay:%ld]",
!st_gpio_get_direction(&pc_to_bank(pc)->gpio_chip, offset),
(oe == GPIO_LINE_DIRECTION_OUT),
ST_PINCONF_UNPACK_PU(config),
ST_PINCONF_UNPACK_OD(config),
f,

View File

@ -134,10 +134,14 @@ static int stmfx_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
ret = regmap_read(pctl->stmfx->map, reg, &val);
/*
* On stmfx, gpio pins direction is (0)input, (1)output.
* .get_direction returns 0=out, 1=in
*/
if (ret)
return ret;
return ret ? ret : !(val & mask);
if (val & mask)
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
}
static int stmfx_gpio_direction_input(struct gpio_chip *gc, unsigned int offset)
@ -223,6 +227,13 @@ static int stmfx_pinconf_get(struct pinctrl_dev *pctldev,
dir = stmfx_gpio_get_direction(&pctl->gpio_chip, pin);
if (dir < 0)
return dir;
/*
* Currently the gpiolib IN is 1 and OUT is 0 but let's not count
* on it just to be on the safe side also in the future :)
*/
dir = (dir == GPIO_LINE_DIRECTION_IN) ? 1 : 0;
type = stmfx_pinconf_get_type(pctl, pin);
if (type < 0)
return type;
@ -360,7 +371,7 @@ static void stmfx_pinconf_dbg_show(struct pinctrl_dev *pctldev,
if (val < 0)
return;
if (!dir) {
if (dir == GPIO_LINE_DIRECTION_OUT) {
seq_printf(s, "output %s ", val ? "high" : "low");
if (type)
seq_printf(s, "open drain %s internal pull-up ",

View File

@ -391,13 +391,16 @@ static int sx150x_gpio_get_direction(struct gpio_chip *chip,
int ret;
if (sx150x_pin_is_oscio(pctl, offset))
return false;
return GPIO_LINE_DIRECTION_OUT;
ret = regmap_read(pctl->regmap, pctl->data->reg_dir, &value);
if (ret < 0)
return ret;
return !!(value & BIT(offset));
if (value & BIT(offset))
return GPIO_LINE_DIRECTION_IN;
return GPIO_LINE_DIRECTION_OUT;
}
static int sx150x_gpio_get(struct gpio_chip *chip, unsigned int offset)
@ -687,7 +690,7 @@ static int sx150x_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
if (ret < 0)
return ret;
if (ret)
if (ret == GPIO_LINE_DIRECTION_IN)
return -EINVAL;
ret = sx150x_gpio_get(&pctl->gpio, pin);

View File

@ -50,6 +50,16 @@ config PINCTRL_IPQ8074
Qualcomm Technologies Inc. IPQ8074 platform. Select this for
IPQ8074.
config PINCTRL_IPQ6018
tristate "Qualcomm Technologies, Inc. IPQ6018 pin controller driver"
depends on GPIOLIB && OF
select PINCTRL_MSM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for
the Qualcomm Technologies Inc. TLMM block found on the
Qualcomm Technologies Inc. IPQ6018 platform. Select this for
IPQ6018.
config PINCTRL_MSM8660
tristate "Qualcomm 8660 pin controller driver"
depends on GPIOLIB && OF

View File

@ -6,6 +6,7 @@ obj-$(CONFIG_PINCTRL_APQ8084) += pinctrl-apq8084.o
obj-$(CONFIG_PINCTRL_IPQ4019) += pinctrl-ipq4019.o
obj-$(CONFIG_PINCTRL_IPQ8064) += pinctrl-ipq8064.o
obj-$(CONFIG_PINCTRL_IPQ8074) += pinctrl-ipq8074.o
obj-$(CONFIG_PINCTRL_IPQ6018) += pinctrl-ipq6018.o
obj-$(CONFIG_PINCTRL_MSM8660) += pinctrl-msm8660.o
obj-$(CONFIG_PINCTRL_MSM8960) += pinctrl-msm8960.o
obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o

File diff suppressed because it is too large Load Diff

View File

@ -299,7 +299,7 @@ static const char * const gpio_groups[] = {
};
static const char * const mdio_groups[] = {
"gpio0", "gpio1", "gpio10", "gpio11",
"gpio0", "gpio1", "gpio2", "gpio10", "gpio11", "gpio66",
};
static const char * const mi2s_groups[] = {
@ -403,8 +403,8 @@ static const char * const usb2_hsic_groups[] = {
};
static const char * const rgmii2_groups[] = {
"gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
"gpio51", "gpio52", "gpio59", "gpio60", "gpio61", "gpio62",
"gpio2", "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
"gpio51", "gpio52", "gpio59", "gpio60", "gpio61", "gpio62", "gpio66",
};
static const char * const sata_groups[] = {
@ -539,7 +539,7 @@ static const struct msm_function ipq8064_functions[] = {
static const struct msm_pingroup ipq8064_groups[] = {
PINGROUP(0, mdio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(1, mdio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(2, gsbi5_spi_cs3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(2, gsbi5_spi_cs3, rgmii2, mdio, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(3, pcie1_rst, pcie1_prsnt, pdm, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(4, pcie1_pwren_n, pcie1_pwren, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(5, pcie1_clk_req, pcie1_pwrflt, NA, NA, NA, NA, NA, NA, NA, NA),
@ -603,7 +603,7 @@ static const struct msm_pingroup ipq8064_groups[] = {
PINGROUP(63, pcie3_rst, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(64, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(65, pcie3_clk_req, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(66, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(66, rgmii2, mdio, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(67, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(68, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
SDC_PINGROUP(sdc3_clk, 0x204a, 14, 6),

View File

@ -22,6 +22,8 @@
#include <linux/reboot.h>
#include <linux/pm.h>
#include <linux/log2.h>
#include <linux/qcom_scm.h>
#include <linux/io.h>
#include <linux/soc/qcom/irq.h>
@ -60,6 +62,8 @@ struct msm_pinctrl {
struct irq_chip irq_chip;
int irq;
bool intr_target_use_scm;
raw_spinlock_t lock;
DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO);
@ -68,6 +72,7 @@ struct msm_pinctrl {
const struct msm_pinctrl_soc_data *soc;
void __iomem *regs[MAX_NR_TILES];
u32 phys_base[MAX_NR_TILES];
};
#define MSM_ACCESSOR(name) \
@ -489,8 +494,8 @@ static int msm_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
val = msm_readl_ctl(pctrl, g);
/* 0 = output, 1 = input */
return val & BIT(g->oe_bit) ? 0 : 1;
return val & BIT(g->oe_bit) ? GPIO_LINE_DIRECTION_OUT :
GPIO_LINE_DIRECTION_IN;
}
static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
@ -882,11 +887,30 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
else
clear_bit(d->hwirq, pctrl->dual_edge_irqs);
/* Route interrupts to application cpu */
val = msm_readl_intr_target(pctrl, g);
val &= ~(7 << g->intr_target_bit);
val |= g->intr_target_kpss_val << g->intr_target_bit;
msm_writel_intr_target(val, pctrl, g);
/* Route interrupts to application cpu.
* With intr_target_use_scm interrupts are routed to
* application cpu using scm calls.
*/
if (pctrl->intr_target_use_scm) {
u32 addr = pctrl->phys_base[0] + g->intr_target_reg;
int ret;
qcom_scm_io_readl(addr, &val);
val &= ~(7 << g->intr_target_bit);
val |= g->intr_target_kpss_val << g->intr_target_bit;
ret = qcom_scm_io_writel(addr, val);
if (ret)
dev_err(pctrl->dev,
"Failed routing %lu interrupt to Apps proc",
d->hwirq);
} else {
val = msm_readl_intr_target(pctrl, g);
val &= ~(7 << g->intr_target_bit);
val |= g->intr_target_kpss_val << g->intr_target_bit;
msm_writel_intr_target(val, pctrl, g);
}
/* Update configuration for gpio.
* RAW_STATUS_EN is left on for all gpio irqs. Due to the
@ -1240,6 +1264,9 @@ int msm_pinctrl_probe(struct platform_device *pdev,
pctrl->dev = &pdev->dev;
pctrl->soc = soc_data;
pctrl->chip = msm_gpio_template;
pctrl->intr_target_use_scm = of_device_is_compatible(
pctrl->dev->of_node,
"qcom,ipq8064-pinctrl");
raw_spin_lock_init(&pctrl->lock);
@ -1252,9 +1279,12 @@ int msm_pinctrl_probe(struct platform_device *pdev,
return PTR_ERR(pctrl->regs[i]);
}
} else {
pctrl->regs[0] = devm_platform_ioremap_resource(pdev, 0);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pctrl->regs[0] = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(pctrl->regs[0]))
return PTR_ERR(pctrl->regs[0]);
pctrl->phys_base[0] = res->start;
}
msm_pinctrl_setup_pm_reset(pctrl);

View File

@ -26,8 +26,8 @@ config PINCTRL_SH_PFC
select PINCTRL_PFC_R8A7792 if ARCH_R8A7792
select PINCTRL_PFC_R8A7793 if ARCH_R8A7793
select PINCTRL_PFC_R8A7794 if ARCH_R8A7794
select PINCTRL_PFC_R8A77950 if ARCH_R8A77950 || ARCH_R8A7795
select PINCTRL_PFC_R8A77951 if ARCH_R8A77951 || ARCH_R8A7795
select PINCTRL_PFC_R8A77950 if ARCH_R8A77950
select PINCTRL_PFC_R8A77951 if ARCH_R8A77951
select PINCTRL_PFC_R8A77960 if ARCH_R8A77960
select PINCTRL_PFC_R8A77961 if ARCH_R8A77961
select PINCTRL_PFC_R8A77965 if ARCH_R8A77965

View File

@ -726,6 +726,27 @@ static int sh_pfc_suspend_init(struct sh_pfc *pfc) { return 0; }
#endif /* CONFIG_PM_SLEEP && CONFIG_ARM_PSCI_FW */
#ifdef DEBUG
#define SH_PFC_MAX_REGS 300
#define SH_PFC_MAX_ENUMS 3000
static unsigned int sh_pfc_errors __initdata = 0;
static unsigned int sh_pfc_warnings __initdata = 0;
static u32 *sh_pfc_regs __initdata = NULL;
static u32 sh_pfc_num_regs __initdata = 0;
static u16 *sh_pfc_enums __initdata = NULL;
static u32 sh_pfc_num_enums __initdata = 0;
#define sh_pfc_err(fmt, ...) \
do { \
pr_err("%s: " fmt, drvname, ##__VA_ARGS__); \
sh_pfc_errors++; \
} while (0)
#define sh_pfc_warn(fmt, ...) \
do { \
pr_warn("%s: " fmt, drvname, ##__VA_ARGS__); \
sh_pfc_warnings++; \
} while (0)
static bool __init is0s(const u16 *enum_ids, unsigned int n)
{
unsigned int i;
@ -737,77 +758,181 @@ static bool __init is0s(const u16 *enum_ids, unsigned int n)
return true;
}
static unsigned int sh_pfc_errors __initdata = 0;
static unsigned int sh_pfc_warnings __initdata = 0;
static bool __init same_name(const char *a, const char *b)
{
if (!a || !b)
return false;
return !strcmp(a, b);
}
static void __init sh_pfc_check_reg(const char *drvname, u32 reg)
{
unsigned int i;
for (i = 0; i < sh_pfc_num_regs; i++)
if (reg == sh_pfc_regs[i]) {
sh_pfc_err("reg 0x%x conflict\n", reg);
return;
}
if (sh_pfc_num_regs == SH_PFC_MAX_REGS) {
pr_warn_once("%s: Please increase SH_PFC_MAX_REGS\n", drvname);
return;
}
sh_pfc_regs[sh_pfc_num_regs++] = reg;
}
static int __init sh_pfc_check_enum(const char *drvname, u16 enum_id)
{
unsigned int i;
for (i = 0; i < sh_pfc_num_enums; i++) {
if (enum_id == sh_pfc_enums[i])
return -EINVAL;
}
if (sh_pfc_num_enums == SH_PFC_MAX_ENUMS) {
pr_warn_once("%s: Please increase SH_PFC_MAX_ENUMS\n", drvname);
return 0;
}
sh_pfc_enums[sh_pfc_num_enums++] = enum_id;
return 0;
}
static void __init sh_pfc_check_reg_enums(const char *drvname, u32 reg,
const u16 *enums, unsigned int n)
{
unsigned int i;
for (i = 0; i < n; i++) {
if (enums[i] && sh_pfc_check_enum(drvname, enums[i]))
sh_pfc_err("reg 0x%x enum_id %u conflict\n", reg,
enums[i]);
}
}
static void __init sh_pfc_check_pin(const struct sh_pfc_soc_info *info,
u32 reg, unsigned int pin)
{
const char *drvname = info->name;
unsigned int i;
if (pin == SH_PFC_PIN_NONE)
return;
for (i = 0; i < info->nr_pins; i++) {
if (pin == info->pins[i].pin)
return;
}
sh_pfc_err("reg 0x%x: pin %u not found\n", reg, pin);
}
static void __init sh_pfc_check_cfg_reg(const char *drvname,
const struct pinmux_cfg_reg *cfg_reg)
{
unsigned int i, n, rw, fw;
sh_pfc_check_reg(drvname, cfg_reg->reg);
if (cfg_reg->field_width) {
/* Checked at build time */
return;
n = cfg_reg->reg_width / cfg_reg->field_width;
/* Skip field checks (done at build time) */
goto check_enum_ids;
}
for (i = 0, n = 0, rw = 0; (fw = cfg_reg->var_field_width[i]); i++) {
if (fw > 3 && is0s(&cfg_reg->enum_ids[n], 1 << fw)) {
pr_warn("%s: reg 0x%x: reserved field [%u:%u] can be split to reduce table size\n",
drvname, cfg_reg->reg, rw, rw + fw - 1);
sh_pfc_warnings++;
}
if (fw > 3 && is0s(&cfg_reg->enum_ids[n], 1 << fw))
sh_pfc_warn("reg 0x%x: reserved field [%u:%u] can be split to reduce table size\n",
cfg_reg->reg, rw, rw + fw - 1);
n += 1 << fw;
rw += fw;
}
if (rw != cfg_reg->reg_width) {
pr_err("%s: reg 0x%x: var_field_width declares %u instead of %u bits\n",
drvname, cfg_reg->reg, rw, cfg_reg->reg_width);
sh_pfc_errors++;
}
if (rw != cfg_reg->reg_width)
sh_pfc_err("reg 0x%x: var_field_width declares %u instead of %u bits\n",
cfg_reg->reg, rw, cfg_reg->reg_width);
if (n != cfg_reg->nr_enum_ids) {
pr_err("%s: reg 0x%x: enum_ids[] has %u instead of %u values\n",
drvname, cfg_reg->reg, cfg_reg->nr_enum_ids, n);
sh_pfc_errors++;
if (n != cfg_reg->nr_enum_ids)
sh_pfc_err("reg 0x%x: enum_ids[] has %u instead of %u values\n",
cfg_reg->reg, cfg_reg->nr_enum_ids, n);
check_enum_ids:
sh_pfc_check_reg_enums(drvname, cfg_reg->reg, cfg_reg->enum_ids, n);
}
static void __init sh_pfc_check_drive_reg(const struct sh_pfc_soc_info *info,
const struct pinmux_drive_reg *drive)
{
const char *drvname = info->name;
unsigned long seen = 0, mask;
unsigned int i;
sh_pfc_check_reg(info->name, drive->reg);
for (i = 0; i < ARRAY_SIZE(drive->fields); i++) {
const struct pinmux_drive_reg_field *field = &drive->fields[i];
if (!field->pin && !field->offset && !field->size)
continue;
mask = GENMASK(field->offset + field->size, field->offset);
if (mask & seen)
sh_pfc_err("drive_reg 0x%x: field %u overlap\n",
drive->reg, i);
seen |= mask;
sh_pfc_check_pin(info, drive->reg, field->pin);
}
}
static void __init sh_pfc_check_bias_reg(const struct sh_pfc_soc_info *info,
const struct pinmux_bias_reg *bias)
{
unsigned int i;
sh_pfc_check_reg(info->name, bias->puen);
if (bias->pud)
sh_pfc_check_reg(info->name, bias->pud);
for (i = 0; i < ARRAY_SIZE(bias->pins); i++)
sh_pfc_check_pin(info, bias->puen, bias->pins[i]);
}
static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info)
{
const struct sh_pfc_function *func;
const char *drvname = info->name;
unsigned int *refcnts;
unsigned int i, j, k;
pr_info("Checking %s\n", drvname);
sh_pfc_num_regs = 0;
sh_pfc_num_enums = 0;
/* Check pins */
for (i = 0; i < info->nr_pins; i++) {
const struct sh_pfc_pin *pin = &info->pins[i];
if (!pin->name) {
sh_pfc_err("empty pin %u\n", i);
continue;
}
for (j = 0; j < i; j++) {
if (!strcmp(info->pins[i].name, info->pins[j].name)) {
pr_err("%s: pin %s/%s: name conflict\n",
drvname, info->pins[i].name,
info->pins[j].name);
sh_pfc_errors++;
}
const struct sh_pfc_pin *pin2 = &info->pins[j];
if (info->pins[i].pin != (u16)-1 &&
info->pins[i].pin == info->pins[j].pin) {
pr_err("%s: pin %s/%s: pin %u conflict\n",
drvname, info->pins[i].name,
info->pins[j].name, info->pins[i].pin);
sh_pfc_errors++;
}
if (same_name(pin->name, pin2->name))
sh_pfc_err("pin %s: name conflict\n",
pin->name);
if (info->pins[i].enum_id &&
info->pins[i].enum_id == info->pins[j].enum_id) {
pr_err("%s: pin %s/%s: enum_id %u conflict\n",
drvname, info->pins[i].name,
info->pins[j].name,
info->pins[i].enum_id);
sh_pfc_errors++;
}
if (pin->pin != (u16)-1 && pin->pin == pin2->pin)
sh_pfc_err("pin %s/%s: pin %u conflict\n",
pin->name, pin2->name, pin->pin);
if (pin->enum_id && pin->enum_id == pin2->enum_id)
sh_pfc_err("pin %s/%s: enum_id %u conflict\n",
pin->name, pin2->name,
pin->enum_id);
}
}
@ -817,45 +942,49 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info)
return;
for (i = 0; i < info->nr_functions; i++) {
func = &info->functions[i];
const struct sh_pfc_function *func = &info->functions[i];
if (!func->name) {
pr_err("%s: empty function %u\n", drvname, i);
sh_pfc_errors++;
sh_pfc_err("empty function %u\n", i);
continue;
}
for (j = 0; j < i; j++) {
if (same_name(func->name, info->functions[j].name))
sh_pfc_err("function %s: name conflict\n",
func->name);
}
for (j = 0; j < func->nr_groups; j++) {
for (k = 0; k < info->nr_groups; k++) {
if (info->groups[k].name &&
!strcmp(func->groups[j],
info->groups[k].name)) {
if (same_name(func->groups[j],
info->groups[k].name)) {
refcnts[k]++;
break;
}
}
if (k == info->nr_groups) {
pr_err("%s: function %s: group %s not found\n",
drvname, func->name, func->groups[j]);
sh_pfc_errors++;
}
if (k == info->nr_groups)
sh_pfc_err("function %s: group %s not found\n",
func->name, func->groups[j]);
}
}
for (i = 0; i < info->nr_groups; i++) {
if (!info->groups[i].name) {
pr_err("%s: empty group %u\n", drvname, i);
sh_pfc_errors++;
const struct sh_pfc_pin_group *group = &info->groups[i];
if (!group->name) {
sh_pfc_err("empty group %u\n", i);
continue;
}
if (!refcnts[i]) {
pr_err("%s: orphan group %s\n", drvname,
info->groups[i].name);
sh_pfc_errors++;
} else if (refcnts[i] > 1) {
pr_warn("%s: group %s referenced by %u functions\n",
drvname, info->groups[i].name, refcnts[i]);
sh_pfc_warnings++;
for (j = 0; j < i; j++) {
if (same_name(group->name, info->groups[j].name))
sh_pfc_err("group %s: name conflict\n",
group->name);
}
if (!refcnts[i])
sh_pfc_err("orphan group %s\n", group->name);
else if (refcnts[i] > 1)
sh_pfc_warn("group %s referenced by %u functions\n",
group->name, refcnts[i]);
}
kfree(refcnts);
@ -863,12 +992,62 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info)
/* Check config register descriptions */
for (i = 0; info->cfg_regs && info->cfg_regs[i].reg; i++)
sh_pfc_check_cfg_reg(drvname, &info->cfg_regs[i]);
/* Check drive strength registers */
for (i = 0; info->drive_regs && info->drive_regs[i].reg; i++)
sh_pfc_check_drive_reg(info, &info->drive_regs[i]);
/* Check bias registers */
for (i = 0; info->bias_regs && info->bias_regs[i].puen; i++)
sh_pfc_check_bias_reg(info, &info->bias_regs[i]);
/* Check ioctrl registers */
for (i = 0; info->ioctrl_regs && info->ioctrl_regs[i].reg; i++)
sh_pfc_check_reg(drvname, info->ioctrl_regs[i].reg);
/* Check data registers */
for (i = 0; info->data_regs && info->data_regs[i].reg; i++) {
sh_pfc_check_reg(drvname, info->data_regs[i].reg);
sh_pfc_check_reg_enums(drvname, info->data_regs[i].reg,
info->data_regs[i].enum_ids,
info->data_regs[i].reg_width);
}
#ifdef CONFIG_PINCTRL_SH_FUNC_GPIO
/* Check function GPIOs */
for (i = 0; i < info->nr_func_gpios; i++) {
const struct pinmux_func *func = &info->func_gpios[i];
if (!func->name) {
sh_pfc_err("empty function gpio %u\n", i);
continue;
}
for (j = 0; j < i; j++) {
if (same_name(func->name, info->func_gpios[j].name))
sh_pfc_err("func_gpio %s: name conflict\n",
func->name);
}
if (sh_pfc_check_enum(drvname, func->enum_id))
sh_pfc_err("%s enum_id %u conflict\n", func->name,
func->enum_id);
}
#endif
}
static void __init sh_pfc_check_driver(const struct platform_driver *pdrv)
{
unsigned int i;
sh_pfc_regs = kcalloc(SH_PFC_MAX_REGS, sizeof(*sh_pfc_regs),
GFP_KERNEL);
if (!sh_pfc_regs)
return;
sh_pfc_enums = kcalloc(SH_PFC_MAX_ENUMS, sizeof(*sh_pfc_enums),
GFP_KERNEL);
if (!sh_pfc_enums)
goto free_regs;
pr_warn("Checking builtin pinmux tables\n");
for (i = 0; pdrv->id_table[i].name[0]; i++)
@ -881,6 +1060,10 @@ static void __init sh_pfc_check_driver(const struct platform_driver *pdrv)
pr_warn("Detected %u errors and %u warnings\n", sh_pfc_errors,
sh_pfc_warnings);
kfree(sh_pfc_enums);
free_regs:
kfree(sh_pfc_regs);
}
#else /* !DEBUG */

View File

@ -205,14 +205,11 @@ static int gpio_pin_to_irq(struct gpio_chip *gc, unsigned offset)
for (k = 0; gpios[k] >= 0; k++) {
if (gpios[k] == offset)
goto found;
return pfc->irqs[i];
}
}
return 0;
found:
return pfc->irqs[i];
}
static int gpio_pin_setup(struct sh_pfc_chip *chip)

View File

@ -352,7 +352,7 @@ struct atlas7_gpio_chip {
int nbank;
raw_spinlock_t lock;
struct gpio_chip chip;
struct atlas7_gpio_bank banks[0];
struct atlas7_gpio_bank banks[];
};
/**

View File

@ -4,9 +4,7 @@
#
config PINCTRL_SPRD
bool "Spreadtrum pinctrl driver"
depends on OF
depends on ARCH_SPRD || COMPILE_TEST
tristate
select PINMUX
select PINCONF
select GENERIC_PINCONF
@ -15,7 +13,9 @@ config PINCTRL_SPRD
Say Y here to enable Spreadtrum pinctrl driver
config PINCTRL_SPRD_SC9860
bool "Spreadtrum SC9860 pinctrl driver"
depends on PINCTRL_SPRD
tristate "Spreadtrum SC9860 pinctrl driver"
depends on OF
depends on ARCH_SPRD || COMPILE_TEST
select PINCTRL_SPRD
help
Say Y here to enable Spreadtrum SC9860 pinctrl driver

View File

@ -464,9 +464,15 @@ static int sprd_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin_id,
case PIN_CONFIG_INPUT_ENABLE:
arg = (reg >> SLEEP_INPUT_SHIFT) & SLEEP_INPUT_MASK;
break;
case PIN_CONFIG_OUTPUT:
case PIN_CONFIG_OUTPUT_ENABLE:
arg = reg & SLEEP_OUTPUT_MASK;
break;
case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
if ((reg & SLEEP_OUTPUT) || (reg & SLEEP_INPUT))
return -EINVAL;
arg = 1;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
arg = (reg >> DRIVE_STRENGTH_SHIFT) &
DRIVE_STRENGTH_MASK;
@ -635,13 +641,23 @@ static int sprd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin_id,
shift = SLEEP_INPUT_SHIFT;
}
break;
case PIN_CONFIG_OUTPUT:
case PIN_CONFIG_OUTPUT_ENABLE:
if (is_sleep_config == true) {
val |= SLEEP_OUTPUT;
if (arg > 0)
val |= SLEEP_OUTPUT;
else
val &= ~SLEEP_OUTPUT;
mask = SLEEP_OUTPUT_MASK;
shift = SLEEP_OUTPUT_SHIFT;
}
break;
case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
if (is_sleep_config == true) {
val = shift = 0;
mask = SLEEP_OUTPUT | SLEEP_INPUT;
}
break;
case PIN_CONFIG_DRIVE_STRENGTH:
if (arg < 2 || arg > 60)
return -EINVAL;
@ -1090,6 +1106,7 @@ int sprd_pinctrl_core_probe(struct platform_device *pdev,
return 0;
}
EXPORT_SYMBOL_GPL(sprd_pinctrl_core_probe);
int sprd_pinctrl_remove(struct platform_device *pdev)
{
@ -1098,6 +1115,7 @@ int sprd_pinctrl_remove(struct platform_device *pdev)
pinctrl_unregister(sprd_pctl->pctl);
return 0;
}
EXPORT_SYMBOL_GPL(sprd_pinctrl_remove);
void sprd_pinctrl_shutdown(struct platform_device *pdev)
{
@ -1112,6 +1130,7 @@ void sprd_pinctrl_shutdown(struct platform_device *pdev)
return;
pinctrl_select_state(pinctl, state);
}
EXPORT_SYMBOL_GPL(sprd_pinctrl_shutdown);
MODULE_DESCRIPTION("SPREADTRUM Pin Controller Driver");
MODULE_AUTHOR("Baolin Wang <baolin.wang@spreadtrum.com>");

View File

@ -284,9 +284,9 @@ static int stm32_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
stm32_pmx_get_mode(bank, pin, &mode, &alt);
if ((alt == 0) && (mode == 0))
ret = 1;
ret = GPIO_LINE_DIRECTION_IN;
else if ((alt == 0) && (mode == 1))
ret = 0;
ret = GPIO_LINE_DIRECTION_OUT;
else
ret = -EINVAL;

View File

@ -13,6 +13,7 @@
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/export.h>
@ -1058,6 +1059,14 @@ static void sunxi_pinctrl_irq_ack_unmask(struct irq_data *d)
sunxi_pinctrl_irq_unmask(d);
}
static int sunxi_pinctrl_irq_set_wake(struct irq_data *d, unsigned int on)
{
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
u8 bank = d->hwirq / IRQ_PER_BANK;
return irq_set_irq_wake(pctl->irq[bank], on);
}
static struct irq_chip sunxi_pinctrl_edge_irq_chip = {
.name = "sunxi_pio_edge",
.irq_ack = sunxi_pinctrl_irq_ack,
@ -1066,7 +1075,8 @@ static struct irq_chip sunxi_pinctrl_edge_irq_chip = {
.irq_request_resources = sunxi_pinctrl_irq_request_resources,
.irq_release_resources = sunxi_pinctrl_irq_release_resources,
.irq_set_type = sunxi_pinctrl_irq_set_type,
.flags = IRQCHIP_SKIP_SET_WAKE,
.irq_set_wake = sunxi_pinctrl_irq_set_wake,
.flags = IRQCHIP_MASK_ON_SUSPEND,
};
static struct irq_chip sunxi_pinctrl_level_irq_chip = {
@ -1081,7 +1091,9 @@ static struct irq_chip sunxi_pinctrl_level_irq_chip = {
.irq_request_resources = sunxi_pinctrl_irq_request_resources,
.irq_release_resources = sunxi_pinctrl_irq_release_resources,
.irq_set_type = sunxi_pinctrl_irq_set_type,
.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_EOI_THREADED |
.irq_set_wake = sunxi_pinctrl_irq_set_wake,
.flags = IRQCHIP_EOI_THREADED |
IRQCHIP_MASK_ON_SUSPEND |
IRQCHIP_EOI_IF_HANDLED,
};

View File

@ -275,11 +275,57 @@ static int tegra_pinctrl_set_mux(struct pinctrl_dev *pctldev,
return 0;
}
static int tegra_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int offset)
{
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
const struct tegra_pingroup *group;
u32 value;
if (!pmx->soc->sfsel_in_mux)
return 0;
group = &pmx->soc->groups[offset];
if (group->mux_reg < 0 || group->sfsel_bit < 0)
return -EINVAL;
value = pmx_readl(pmx, group->mux_bank, group->mux_reg);
value &= ~BIT(group->sfsel_bit);
pmx_writel(pmx, value, group->mux_bank, group->mux_reg);
return 0;
}
static void tegra_pinctrl_gpio_disable_free(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int offset)
{
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
const struct tegra_pingroup *group;
u32 value;
if (!pmx->soc->sfsel_in_mux)
return;
group = &pmx->soc->groups[offset];
if (group->mux_reg < 0 || group->sfsel_bit < 0)
return;
value = pmx_readl(pmx, group->mux_bank, group->mux_reg);
value |= BIT(group->sfsel_bit);
pmx_writel(pmx, value, group->mux_bank, group->mux_reg);
}
static const struct pinmux_ops tegra_pinmux_ops = {
.get_functions_count = tegra_pinctrl_get_funcs_count,
.get_function_name = tegra_pinctrl_get_func_name,
.get_function_groups = tegra_pinctrl_get_func_groups,
.set_mux = tegra_pinctrl_set_mux,
.gpio_request_enable = tegra_pinctrl_gpio_request_enable,
.gpio_disable_free = tegra_pinctrl_gpio_disable_free,
};
static int tegra_pinconf_reg(struct tegra_pmx *pmx,
@ -689,12 +735,12 @@ const struct dev_pm_ops tegra_pinctrl_pm = {
.resume = &tegra_pinctrl_resume
};
static bool gpio_node_has_range(const char *compatible)
static bool tegra_pinctrl_gpio_node_has_range(struct tegra_pmx *pmx)
{
struct device_node *np;
bool has_prop = false;
np = of_find_compatible_node(NULL, NULL, compatible);
np = of_find_compatible_node(NULL, NULL, pmx->soc->gpio_compatible);
if (!np)
return has_prop;
@ -794,7 +840,7 @@ int tegra_pinctrl_probe(struct platform_device *pdev,
tegra_pinctrl_clear_parked_bits(pmx);
if (!gpio_node_has_range(pmx->soc->gpio_compatible))
if (pmx->soc->ngpios > 0 && !tegra_pinctrl_gpio_node_has_range(pmx))
pinctrl_add_gpio_range(pmx->pctl, &tegra_pinctrl_gpio_range);
platform_set_drvdata(pdev, pmx);

View File

@ -107,7 +107,8 @@ struct tegra_function {
* drvup, slwr, slwf, and drvtype parameters.
* @drv_bank: Drive fields register bank.
* @hsm_bit: High Speed Mode register bit.
* @schmitt_bit: Scmitt register bit.
* @sfsel_bit: GPIO/SFIO selection register bit.
* @schmitt_bit: Schmitt register bit.
* @lpmd_bit: Low Power Mode register bit.
* @drvdn_bit: Drive Down register bit.
* @drvdn_width: Drive Down field width.
@ -153,6 +154,7 @@ struct tegra_pingroup {
s32 ioreset_bit:6;
s32 rcv_sel_bit:6;
s32 hsm_bit:6;
s32 sfsel_bit:6;
s32 schmitt_bit:6;
s32 lpmd_bit:6;
s32 drvdn_bit:6;
@ -192,6 +194,7 @@ struct tegra_pinctrl_soc_data {
bool hsm_in_mux;
bool schmitt_in_mux;
bool drvtype_in_mux;
bool sfsel_in_mux;
};
extern const struct dev_pm_ops tegra_pinctrl_pm;

View File

@ -24,17 +24,14 @@
/* Define unique ID for each pins */
enum pin_id {
TEGRA_PIN_PEX_L5_CLKREQ_N_PGG0 = 256,
TEGRA_PIN_PEX_L5_RST_N_PGG1 = 257,
TEGRA_PIN_NUM_GPIOS = 258,
TEGRA_PIN_PEX_L5_CLKREQ_N_PGG0,
TEGRA_PIN_PEX_L5_RST_N_PGG1,
};
/* Table for pin descriptor */
static const struct pinctrl_pin_desc tegra194_pins[] = {
PINCTRL_PIN(TEGRA_PIN_PEX_L5_CLKREQ_N_PGG0,
"TEGRA_PIN_PEX_L5_CLKREQ_N_PGG0"),
PINCTRL_PIN(TEGRA_PIN_PEX_L5_RST_N_PGG1,
"TEGRA_PIN_PEX_L5_RST_N_PGG1"),
PINCTRL_PIN(TEGRA_PIN_PEX_L5_CLKREQ_N_PGG0, "PEX_L5_CLKREQ_N_PGG0"),
PINCTRL_PIN(TEGRA_PIN_PEX_L5_RST_N_PGG1, "PEX_L5_RST_N_PGG1"),
};
static const unsigned int pex_l5_clkreq_n_pgg0_pins[] = {
@ -59,6 +56,7 @@ enum tegra_mux_dt {
{ \
.name = #lid, \
}
static struct tegra_function tegra194_functions[] = {
TEGRA_PIN_FUNCTION(rsvd0),
TEGRA_PIN_FUNCTION(rsvd1),
@ -70,7 +68,7 @@ static struct tegra_function tegra194_functions[] = {
#define DRV_PINGROUP_ENTRY_Y(r, drvdn_b, drvdn_w, drvup_b, \
drvup_w, slwr_b, slwr_w, slwf_b, \
slwf_w, bank) \
.drv_reg = ((r)), \
.drv_reg = ((r)), \
.drv_bank = bank, \
.drvdn_bit = drvdn_b, \
.drvdn_width = drvdn_w, \
@ -89,7 +87,7 @@ static struct tegra_function tegra194_functions[] = {
.hsm_bit = -1, \
.mux_bank = bank, \
.mux_bit = 0, \
.pupd_reg = ((r)), \
.pupd_reg = ((r)), \
.pupd_bank = bank, \
.pupd_bit = 2, \
.tri_reg = ((r)), \
@ -97,6 +95,7 @@ static struct tegra_function tegra194_functions[] = {
.tri_bit = 4, \
.einput_bit = e_input, \
.odrain_bit = e_od, \
.sfsel_bit = 10, \
.schmitt_bit = schmitt_b, \
.drvtype_bit = 13, \
.drv_reg = -1, \
@ -109,20 +108,20 @@ static struct tegra_function tegra194_functions[] = {
#define PINGROUP(pg_name, f0, f1, f2, f3, r, bank, pupd, e_lpbk, \
e_input, e_lpdr, e_od, schmitt_b, drvtype, io_rail) \
{ \
.name = #pg_name, \
.pins = pg_name##_pins, \
.npins = ARRAY_SIZE(pg_name##_pins), \
.funcs = { \
TEGRA_MUX_##f0, \
TEGRA_MUX_##f1, \
TEGRA_MUX_##f2, \
TEGRA_MUX_##f3, \
}, \
PIN_PINGROUP_ENTRY_Y(r, bank, pupd, e_lpbk, \
e_input, e_od, \
schmitt_b, drvtype), \
drive_##pg_name, \
{ \
.name = #pg_name, \
.pins = pg_name##_pins, \
.npins = ARRAY_SIZE(pg_name##_pins), \
.funcs = { \
TEGRA_MUX_##f0, \
TEGRA_MUX_##f1, \
TEGRA_MUX_##f2, \
TEGRA_MUX_##f3, \
}, \
PIN_PINGROUP_ENTRY_Y(r, bank, pupd, e_lpbk, \
e_input, e_od, \
schmitt_b, drvtype), \
drive_##pg_name, \
}
static const struct tegra_pingroup tegra194_groups[] = {
@ -133,7 +132,6 @@ static const struct tegra_pingroup tegra194_groups[] = {
};
static const struct tegra_pinctrl_soc_data tegra194_pinctrl = {
.ngpios = TEGRA_PIN_NUM_GPIOS,
.pins = tegra194_pins,
.npins = ARRAY_SIZE(tegra194_pins),
.functions = tegra194_functions,
@ -143,6 +141,7 @@ static const struct tegra_pinctrl_soc_data tegra194_pinctrl = {
.hsm_in_mux = true,
.schmitt_in_mux = true,
.drvtype_in_mux = true,
.sfsel_in_mux = true,
};
static int tegra194_pinctrl_probe(struct platform_device *pdev)

View File

@ -29,7 +29,7 @@ struct uniphier_pinctrl_reg_region {
struct list_head node;
unsigned int base;
unsigned int nregs;
u32 vals[0];
u32 vals[];
};
struct uniphier_pinctrl_priv {

View File

@ -486,8 +486,10 @@ static int wmt_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
u32 val;
val = readl_relaxed(data->base + reg_dir);
/* Return 0 == output, 1 == input */
return !(val & BIT(bit));
if (val & BIT(bit))
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
}
static int wmt_gpio_get_value(struct gpio_chip *chip, unsigned offset)