This is the bulk of pin control changes for the v4.20 series:

There were no significant changes to the core this time!
 
 New drivers:
 
 - Broadcom Northstar pin control driver.
 
 - Mediatek MT8183 subdriver.
 
 - Mediatek MT7623 subdriver.
 
 - Mediatek MT6765 subdriver.
 
 - Meson g12a subdriver.
 
 - Nuvoton NPCM7xx pin control and GPIO driver.
 
 - Qualcomm QCS404 pin control and GPIO subdriver.
 
 - Qualcomm SDM660 pin control and GPIO subdriver.
 
 - Renesas R8A7744 PFC subdriver.
 
 - Renesas R8A774C0 PFC subdriver.
 
 - Renesas RZ/N1 pinctrl driver
 
 Major improvements:
 
 - Pulled the GPIO support for Ingenic over from the GPIO
   subsystem and consolidated it all in the Ingenic pin control
   driver.
 
 - Major cleanups and consolidation work in all Intel drivers.
 
 - Major cleanups and consolidation work in all Mediatek drivers.
 
 - Lots of incremental improvements to the Renesas PFC pin
   controller family.
 
 - All drivers doing GPIO now include <linux/gpio/driver.h> and
   nothing else.
 -----BEGIN PGP SIGNATURE-----
 
 iQIcBAABAgAGBQJbzcMKAAoJEEEQszewGV1z7UYP/1XnwE8EyOam4XuQMQPI5t3w
 q6vUDClR2dgLDFdQOaSU+5+GgO9ke/RLLIcp9e4EWS7a9gcq7Q/w371GL3PplnKZ
 s718SJnJRUGO4Cdzz57emhsqXgJus6Clj11Gqtey+s6a5rlaJJldgRrwha2iGCaP
 Wn3OByCtRNlvRPDmP7EmO+BeZrYvN9xzC7trweetKxx6/QibopnrgRPmARn5HvEq
 0myUQis8RSpZ3ck1Ky375WKnUkeuVoADp7PeH12gQUYdvhQ5+G9/4NDAkUuShYD/
 RLylNCVwgKOU4zhH/z2Rx0zY92u6JjDphiM6GSt1z0DUf3hmp2sJkQWUrLJJmh2t
 MO5csePHn18UXiHSee8Uhc39dHDY5wCywScYetFZuJwhhJY9yGQ0610qpO2HQ67q
 9RobHS6pH8EWqIqwFe9rg4YncWU9R7gkxHAMSEBvnrXKyHNTl35lKHwyKQzgUKDu
 EXbgoE7cKMTGtlD9paMltDNM9rDQfARnKxI8gW43ju0AKfIdBrWlVYwGiGxmfvpm
 Fzb7I6stEKs8EprgHo7/SYUZPhFpQVzX+VMWQxbag2aQoMx1jHGYT4yDf7Z1Liy0
 2/8SZDqOnyWOCt/Npb/v7yS8+9FQ3PL3OndsgfoZIKyyBTO+lnMzXVFkn0g9umXc
 5rASYfGie9JTXW7XeQ17
 =rBtH
 -----END PGP SIGNATURE-----

Merge tag 'pinctrl-v4.20-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 v4.20 series:

  There were no significant changes to the core this time! Bur the new
  Qualcomm, Mediatek and Broadcom drivers are quite interesting as they
  will be used in a few million embedded devices the coming years as it
  seems.

  New drivers:

   - Broadcom Northstar pin control driver.

   - Mediatek MT8183 subdriver.

   - Mediatek MT7623 subdriver.

   - Mediatek MT6765 subdriver.

   - Meson g12a subdriver.

   - Nuvoton NPCM7xx pin control and GPIO driver.

   - Qualcomm QCS404 pin control and GPIO subdriver.

   - Qualcomm SDM660 pin control and GPIO subdriver.

   - Renesas R8A7744 PFC subdriver.

   - Renesas R8A774C0 PFC subdriver.

   - Renesas RZ/N1 pinctrl driver

  Major improvements:

   - Pulled the GPIO support for Ingenic over from the GPIO subsystem
     and consolidated it all in the Ingenic pin control driver.

   - Major cleanups and consolidation work in all Intel drivers.

   - Major cleanups and consolidation work in all Mediatek drivers.

   - Lots of incremental improvements to the Renesas PFC pin controller
     family.

   - All drivers doing GPIO now include <linux/gpio/driver.h> and
     nothing else"

* tag 'pinctrl-v4.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (153 commits)
  pinctrl: sunxi: Fix a memory leak in 'sunxi_pinctrl_build_state()'
  gpio: uniphier: include <linux/bits.h> instead of <linux/bitops.h>
  pinctrl: uniphier: include <linux/bits.h> instead of <linux/bitops.h>
  dt-bindings: pinctrl: bcm4708-pinmux: improve example binding
  pinctrl: geminilake: Sort register offsets by value
  pinctrl: geminilake: Get rid of unneeded ->probe() stub
  pinctrl: geminilake: Update pin list for B0 stepping
  pinctrl: renesas: Fix platform_no_drv_owner.cocci warnings
  pinctrl: mediatek: Make eint_m u16
  pinctrl: bcm: ns: Use uintptr_t for casting data
  pinctrl: madera: Fix uninitialized variable bug in madera_mux_set_mux
  pinctrl: gemini: Fix up TVC clock group
  pinctrl: gemini: Drop noisy debug prints
  pinctrl: gemini: Mask and set properly
  pinctrl: mediatek: select GPIOLIB
  pinctrl: rza1: don't manually release devm managed resources
  MAINTAINERS: update entry for Mediatek pin controller
  pinctrl: bcm: add Northstar driver
  dt-bindings: pinctrl: document Broadcom Northstar pin mux controller
  pinctrl: qcom: fix 'const' pointer handling
  ...
This commit is contained in:
Linus Torvalds 2018-10-23 08:40:16 +01:00
commit b0b6a28bc4
150 changed files with 22657 additions and 2992 deletions

View File

@ -1,46 +0,0 @@
Ingenic jz47xx GPIO controller
That the Ingenic GPIO driver node must be a sub-node of the Ingenic pinctrl
driver node.
Required properties:
--------------------
- compatible: Must contain one of:
- "ingenic,jz4740-gpio"
- "ingenic,jz4770-gpio"
- "ingenic,jz4780-gpio"
- reg: The GPIO bank number.
- interrupt-controller: Marks the device node as an interrupt controller.
- interrupts: Interrupt specifier for the controllers interrupt.
- #interrupt-cells: Should be 2. Refer to
../interrupt-controller/interrupts.txt for more details.
- gpio-controller: Marks the device node as a GPIO controller.
- #gpio-cells: Should be 2. The first cell is the GPIO number and the second
cell specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>. Only the
GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported.
- gpio-ranges: Range of pins managed by the GPIO controller. Refer to
'gpio.txt' in this directory for more details.
Example:
--------
&pinctrl {
#address-cells = <1>;
#size-cells = <0>;
gpa: gpio@0 {
compatible = "ingenic,jz4740-gpio";
reg = <0>;
gpio-controller;
gpio-ranges = <&pinctrl 0 0 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <28>;
};
};

View File

@ -0,0 +1,57 @@
Broadcom Northstar pins mux controller
Some of Northstar SoCs's pins can be used for various purposes thanks to the mux
controller. This binding allows describing mux controller and listing available
functions. They can be referenced later by other bindings to let system
configure controller correctly.
A list of pins varies across chipsets so few bindings are available.
Required properties:
- compatible: must be one of:
"brcm,bcm4708-pinmux"
"brcm,bcm4709-pinmux"
"brcm,bcm53012-pinmux"
- reg: iomem address range of CRU (Central Resource Unit) pin registers
- reg-names: "cru_gpio_control" - the only needed & supported reg right now
Functions and their groups available for all chipsets:
- "spi": "spi_grp"
- "i2c": "i2c_grp"
- "pwm": "pwm0_grp", "pwm1_grp", "pwm2_grp", "pwm3_grp"
- "uart1": "uart1_grp"
Additionally available on BCM4709 and BCM53012:
- "mdio": "mdio_grp"
- "uart2": "uart2_grp"
- "sdio": "sdio_pwr_grp", "sdio_1p8v_grp"
For documentation of subnodes see:
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
Example:
dmu@1800c000 {
compatible = "simple-bus";
ranges = <0 0x1800c000 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
cru@100 {
compatible = "simple-bus";
reg = <0x100 0x1a4>;
ranges;
#address-cells = <1>;
#size-cells = <1>;
pin-controller@1c0 {
compatible = "brcm,bcm4708-pinmux";
reg = <0x1c0 0x24>;
reg-names = "cru_gpio_control";
spi-pins {
function = "spi";
groups = "spi_grp";
};
};
};
};

View File

@ -20,16 +20,30 @@ Required properties:
- compatible: One of:
- "ingenic,jz4740-pinctrl"
- "ingenic,jz4725b-pinctrl"
- "ingenic,jz4770-pinctrl"
- "ingenic,jz4780-pinctrl"
- reg: Address range of the pinctrl registers.
GPIO sub-nodes
--------------
Required properties for sub-nodes (GPIO chips):
-----------------------------------------------
The pinctrl node can have optional sub-nodes for the Ingenic GPIO driver;
please refer to ../gpio/ingenic,gpio.txt.
- compatible: Must contain one of:
- "ingenic,jz4740-gpio"
- "ingenic,jz4770-gpio"
- "ingenic,jz4780-gpio"
- reg: The GPIO bank number.
- interrupt-controller: Marks the device node as an interrupt controller.
- interrupts: Interrupt specifier for the controllers interrupt.
- #interrupt-cells: Should be 2. Refer to
../interrupt-controller/interrupts.txt for more details.
- gpio-controller: Marks the device node as a GPIO controller.
- #gpio-cells: Should be 2. The first cell is the GPIO number and the second
cell specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>. Only the
GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported.
- gpio-ranges: Range of pins managed by the GPIO controller. Refer to
../gpio/gpio.txt for more details.
Example:
@ -38,4 +52,21 @@ Example:
pinctrl: pin-controller@10010000 {
compatible = "ingenic,jz4740-pinctrl";
reg = <0x10010000 0x400>;
#address-cells = <1>;
#size-cells = <0>;
gpa: gpio@0 {
compatible = "ingenic,jz4740-gpio";
reg = <0>;
gpio-controller;
gpio-ranges = <&pinctrl 0 0 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <28>;
};
};

View File

@ -13,6 +13,8 @@ Required properties for the root node:
"amlogic,meson-gxl-aobus-pinctrl"
"amlogic,meson-axg-periphs-pinctrl"
"amlogic,meson-axg-aobus-pinctrl"
"amlogic,meson-g12a-periphs-pinctrl"
"amlogic,meson-g12a-aobus-pinctrl"
- reg: address and size of registers controlling irq functionality
=== GPIO sub-nodes ===

View File

@ -0,0 +1,216 @@
Nuvoton NPCM7XX Pin Controllers
The Nuvoton BMC NPCM7XX Pin Controller multi-function routed through
the multiplexing block, Each pin supports GPIO functionality (GPIOx)
and multiple functions that directly connect the pin to different
hardware blocks.
Required properties:
- #address-cells : should be 1.
- #size-cells : should be 1.
- compatible : "nuvoton,npcm750-pinctrl" for Poleg NPCM7XX.
- ranges : defines mapping ranges between pin controller node (parent)
to GPIO bank node (children).
=== GPIO Bank Subnode ===
The NPCM7XX has 8 GPIO Banks each GPIO bank supports 32 GPIO.
Required GPIO Bank subnode-properties:
- reg : specifies physical base address and size of the GPIO
bank registers.
- gpio-controller : Marks the device node as a GPIO controller.
- #gpio-cells : Must be <2>. The first cell is the gpio pin number
and the second cell is used for optional parameters.
- interrupts : contain the GPIO bank interrupt with flags for falling edge.
- gpio-ranges : defines the range of pins managed by the GPIO bank controller.
For example, GPIO bank subnodes like the following:
gpio0: gpio@f0010000 {
gpio-controller;
#gpio-cells = <2>;
reg = <0x0 0x80>;
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
gpio-ranges = <&pinctrl 0 0 32>;
};
=== Pin Mux Subnode ===
- pin: A string containing the name of the pin
An array of strings, each string containing the name of a pin.
These pin are used for selecting pin configuration.
The following are the list of pins available:
"GPIO0/IOX1DI", "GPIO1/IOX1LD", "GPIO2/IOX1CK", "GPIO3/IOX1D0",
"GPIO4/IOX2DI/SMB1DSDA", "GPIO5/IOX2LD/SMB1DSCL", "GPIO6/IOX2CK/SMB2DSDA",
"GPIO7/IOX2D0/SMB2DSCL", "GPIO8/LKGPO1", "GPIO9/LKGPO2", "GPIO10/IOXHLD",
"GPIO11/IOXHCK", "GPIO12/GSPICK/SMB5BSCL", "GPIO13/GSPIDO/SMB5BSDA",
"GPIO14/GSPIDI/SMB5CSCL", "GPIO15/GSPICS/SMB5CSDA", "GPIO16/LKGPO0",
"GPIO17/PSPI2DI/SMB4DEN","GPIO18/PSPI2D0/SMB4BSDA", "GPIO19/PSPI2CK/SMB4BSCL",
"GPIO20/SMB4CSDA/SMB15SDA", "GPIO21/SMB4CSCL/SMB15SCL", "GPIO22/SMB4DSDA/SMB14SDA",
"GPIO23/SMB4DSCL/SMB14SCL", "GPIO24/IOXHDO", "GPIO25/IOXHDI", "GPIO26/SMB5SDA",
"GPIO27/SMB5SCL", "GPIO28/SMB4SDA", "GPIO29/SMB4SCL", "GPIO30/SMB3SDA",
"GPIO31/SMB3SCL", "GPIO32/nSPI0CS1","SPI0D2", "SPI0D3", "GPIO37/SMB3CSDA",
"GPIO38/SMB3CSCL", "GPIO39/SMB3BSDA", "GPIO40/SMB3BSCL", "GPIO41/BSPRXD",
"GPO42/BSPTXD/STRAP11", "GPIO43/RXD1/JTMS2/BU1RXD", "GPIO44/nCTS1/JTDI2/BU1CTS",
"GPIO45/nDCD1/JTDO2", "GPIO46/nDSR1/JTCK2", "GPIO47/nRI1/JCP_RDY2",
"GPIO48/TXD2/BSPTXD", "GPIO49/RXD2/BSPRXD", "GPIO50/nCTS2", "GPO51/nRTS2/STRAP2",
"GPIO52/nDCD2", "GPO53/nDTR2_BOUT2/STRAP1", "GPIO54/nDSR2", "GPIO55/nRI2",
"GPIO56/R1RXERR", "GPIO57/R1MDC", "GPIO58/R1MDIO", "GPIO59/SMB3DSDA",
"GPIO60/SMB3DSCL", "GPO61/nDTR1_BOUT1/STRAP6", "GPO62/nRTST1/STRAP5",
"GPO63/TXD1/STRAP4", "GPIO64/FANIN0", "GPIO65/FANIN1", "GPIO66/FANIN2",
"GPIO67/FANIN3", "GPIO68/FANIN4", "GPIO69/FANIN5", "GPIO70/FANIN6", "GPIO71/FANIN7",
"GPIO72/FANIN8", "GPIO73/FANIN9", "GPIO74/FANIN10", "GPIO75/FANIN11",
"GPIO76/FANIN12", "GPIO77/FANIN13","GPIO78/FANIN14", "GPIO79/FANIN15",
"GPIO80/PWM0", "GPIO81/PWM1", "GPIO82/PWM2", "GPIO83/PWM3", "GPIO84/R2TXD0",
"GPIO85/R2TXD1", "GPIO86/R2TXEN", "GPIO87/R2RXD0", "GPIO88/R2RXD1", "GPIO89/R2CRSDV",
"GPIO90/R2RXERR", "GPIO91/R2MDC", "GPIO92/R2MDIO", "GPIO93/GA20/SMB5DSCL",
"GPIO94/nKBRST/SMB5DSDA", "GPIO95/nLRESET/nESPIRST", "GPIO96/RG1TXD0",
"GPIO97/RG1TXD1", "GPIO98/RG1TXD2", "GPIO99/RG1TXD3","GPIO100/RG1TXC",
"GPIO101/RG1TXCTL", "GPIO102/RG1RXD0", "GPIO103/RG1RXD1", "GPIO104/RG1RXD2",
"GPIO105/RG1RXD3", "GPIO106/RG1RXC", "GPIO107/RG1RXCTL", "GPIO108/RG1MDC",
"GPIO109/RG1MDIO", "GPIO110/RG2TXD0/DDRV0", "GPIO111/RG2TXD1/DDRV1",
"GPIO112/RG2TXD2/DDRV2", "GPIO113/RG2TXD3/DDRV3", "GPIO114/SMB0SCL",
"GPIO115/SMB0SDA", "GPIO116/SMB1SCL", "GPIO117/SMB1SDA", "GPIO118/SMB2SCL",
"GPIO119/SMB2SDA", "GPIO120/SMB2CSDA", "GPIO121/SMB2CSCL", "GPIO122/SMB2BSDA",
"GPIO123/SMB2BSCL", "GPIO124/SMB1CSDA", "GPIO125/SMB1CSCL","GPIO126/SMB1BSDA",
"GPIO127/SMB1BSCL", "GPIO128/SMB8SCL", "GPIO129/SMB8SDA", "GPIO130/SMB9SCL",
"GPIO131/SMB9SDA", "GPIO132/SMB10SCL", "GPIO133/SMB10SDA","GPIO134/SMB11SCL",
"GPIO135/SMB11SDA", "GPIO136/SD1DT0", "GPIO137/SD1DT1", "GPIO138/SD1DT2",
"GPIO139/SD1DT3", "GPIO140/SD1CLK", "GPIO141/SD1WP", "GPIO142/SD1CMD",
"GPIO143/SD1CD/SD1PWR", "GPIO144/PWM4", "GPIO145/PWM5", "GPIO146/PWM6",
"GPIO147/PWM7", "GPIO148/MMCDT4", "GPIO149/MMCDT5", "GPIO150/MMCDT6",
"GPIO151/MMCDT7", "GPIO152/MMCCLK", "GPIO153/MMCWP", "GPIO154/MMCCMD",
"GPIO155/nMMCCD/nMMCRST", "GPIO156/MMCDT0", "GPIO157/MMCDT1", "GPIO158/MMCDT2",
"GPIO159/MMCDT3", "GPIO160/CLKOUT/RNGOSCOUT", "GPIO161/nLFRAME/nESPICS",
"GPIO162/SERIRQ", "GPIO163/LCLK/ESPICLK", "GPIO164/LAD0/ESPI_IO0",
"GPIO165/LAD1/ESPI_IO1", "GPIO166/LAD2/ESPI_IO2", "GPIO167/LAD3/ESPI_IO3",
"GPIO168/nCLKRUN/nESPIALERT", "GPIO169/nSCIPME", "GPIO170/nSMI", "GPIO171/SMB6SCL",
"GPIO172/SMB6SDA", "GPIO173/SMB7SCL", "GPIO174/SMB7SDA", "GPIO175/PSPI1CK/FANIN19",
"GPIO176/PSPI1DO/FANIN18", "GPIO177/PSPI1DI/FANIN17", "GPIO178/R1TXD0",
"GPIO179/R1TXD1", "GPIO180/R1TXEN", "GPIO181/R1RXD0", "GPIO182/R1RXD1",
"GPIO183/SPI3CK", "GPO184/SPI3D0/STRAP9", "GPO185/SPI3D1/STRAP10",
"GPIO186/nSPI3CS0", "GPIO187/nSPI3CS1", "GPIO188/SPI3D2/nSPI3CS2",
"GPIO189/SPI3D3/nSPI3CS3", "GPIO190/nPRD_SMI", "GPIO191", "GPIO192", "GPIO193/R1CRSDV",
"GPIO194/SMB0BSCL", "GPIO195/SMB0BSDA", "GPIO196/SMB0CSCL", "GPIO197/SMB0DEN",
"GPIO198/SMB0DSDA", "GPIO199/SMB0DSCL", "GPIO200/R2CK", "GPIO201/R1CK",
"GPIO202/SMB0CSDA", "GPIO203/FANIN16", "GPIO204/DDC2SCL", "GPIO205/DDC2SDA",
"GPIO206/HSYNC2", "GPIO207/VSYNC2", "GPIO208/RG2TXC/DVCK", "GPIO209/RG2TXCTL/DDRV4",
"GPIO210/RG2RXD0/DDRV5", "GPIO211/RG2RXD1/DDRV6", "GPIO212/RG2RXD2/DDRV7",
"GPIO213/RG2RXD3/DDRV8", "GPIO214/RG2RXC/DDRV9", "GPIO215/RG2RXCTL/DDRV10",
"GPIO216/RG2MDC/DDRV11", "GPIO217/RG2MDIO/DVHSYNC", "GPIO218/nWDO1",
"GPIO219/nWDO2", "GPIO220/SMB12SCL", "GPIO221/SMB12SDA", "GPIO222/SMB13SCL",
"GPIO223/SMB13SDA", "GPIO224/SPIXCK", "GPO225/SPIXD0/STRAP12", "GPO226/SPIXD1/STRAP13",
"GPIO227/nSPIXCS0", "GPIO228/nSPIXCS1", "GPO229/SPIXD2/STRAP3", "GPIO230/SPIXD3",
"GPIO231/nCLKREQ", "GPI255/DACOSEL"
Optional Properties:
bias-disable, bias-pull-down, bias-pull-up, input-enable,
input-disable, output-high, output-low, drive-push-pull,
drive-open-drain, input-debounce, slew-rate, drive-strength
slew-rate valid arguments are:
<0> - slow
<1> - fast
drive-strength valid arguments are:
<2> - 2mA
<4> - 4mA
<8> - 8mA
<12> - 12mA
<16> - 16mA
<24> - 24mA
For example, pinctrl might have pinmux subnodes like the following:
gpio0_iox1d1_pin: gpio0-iox1d1-pin {
pins = "GPIO0/IOX1DI";
output-high;
};
gpio0_iox1ck_pin: gpio0-iox1ck-pin {
pins = "GPIO2/IOX1CK";
output_high;
};
=== Pin Group Subnode ===
Required pin group subnode-properties:
- groups : A string containing the name of the group to mux.
- function: A string containing the name of the function to mux to the
group.
The following are the list of the available groups and functions :
smb0, smb0b, smb0c, smb0d, smb0den, smb1, smb1b, smb1c, smb1d,
smb2, smb2b, smb2c, smb2d, smb3, smb3b, smb3c, smb3d, smb4, smb4b,
smb4c, smb4d, smb4den, smb5, smb5b, smb5c, smb5d, ga20kbc, smb6,
smb7, smb8, smb9, smb10, smb11, smb12, smb13, smb14, smb15, fanin0,
fanin1, fanin2, fanin3, fanin4, fanin5, fanin6, fanin7, fanin8,
fanin9, fanin10, fanin11 fanin12 fanin13, fanin14, fanin15, faninx,
pwm0, pwm1, pwm2, pwm3, pwm4, pwm5, pwm6, pwm7, rg1, rg1mdio, rg2,
rg2mdio, ddr, uart1, uart2, bmcuart0a, bmcuart0b, bmcuart1, iox1,
iox2, ioxh, gspi, mmc, mmcwp, mmccd, mmcrst, mmc8, r1, r1err, r1md,
r2, r2err, r2md, sd1, sd1pwr, wdog1, wdog2, scipme, sci, serirq,
jtag2, spix, spixcs1, pspi1, pspi2, ddc, clkreq, clkout, spi3, spi3cs1,
spi3quad, spi3cs2, spi3cs3, spi0cs1, lpc, lpcclk, espi, lkgpo0, lkgpo1,
lkgpo2, nprd_smi
For example, pinctrl might have group subnodes like the following:
r1err_pins: r1err-pins {
groups = "r1err";
function = "r1err";
};
r1md_pins: r1md-pins {
groups = "r1md";
function = "r1md";
};
r1_pins: r1-pins {
groups = "r1";
function = "r1";
};
Examples
========
pinctrl: pinctrl@f0800000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "nuvoton,npcm750-pinctrl";
ranges = <0 0xf0010000 0x8000>;
gpio0: gpio@f0010000 {
gpio-controller;
#gpio-cells = <2>;
reg = <0x0 0x80>;
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
gpio-ranges = <&pinctrl 0 0 32>;
};
....
gpio7: gpio@f0017000 {
gpio-controller;
#gpio-cells = <2>;
reg = <0x7000 0x80>;
interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
gpio-ranges = <&pinctrl 0 224 32>;
};
gpio0_iox1d1_pin: gpio0-iox1d1-pin {
pins = "GPIO0/IOX1DI";
output-high;
};
iox1_pins: iox1-pins {
groups = "iox1";
function = "iox1";
};
iox2_pins: iox2-pins {
groups = "iox2";
function = "iox2";
};
....
clkreq_pins: clkreq-pins {
groups = "clkreq";
function = "clkreq";
};
};

View File

@ -19,6 +19,7 @@ PMIC's from Qualcomm.
"qcom,pm8998-gpio"
"qcom,pma8084-gpio"
"qcom,pmi8994-gpio"
"qcom,pms405-gpio"
And must contain either "qcom,spmi-gpio" or "qcom,ssbi-gpio"
if the device is on an spmi bus or an ssbi bus respectively
@ -91,6 +92,7 @@ to specify in a pin configuration subnode:
gpio1-gpio26 for pm8998
gpio1-gpio22 for pma8084
gpio1-gpio10 for pmi8994
gpio1-gpio11 for pms405
- function:
Usage: required

View File

@ -0,0 +1,199 @@
Qualcomm QCS404 TLMM block
This binding describes the Top Level Mode Multiplexer block found in the
QCS404 platform.
- compatible:
Usage: required
Value type: <string>
Definition: must be "qcom,qcs404-pinctrl"
- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: the base address and size of the north, south and east TLMM
tiles.
- reg-names:
Usage: required
Value type: <stringlist>
Defintiion: names for the cells of reg, must contain "north", "south"
and "east".
- interrupts:
Usage: required
Value type: <prop-encoded-array>
Definition: should specify the TLMM summary IRQ.
- interrupt-controller:
Usage: required
Value type: <none>
Definition: identifies this node as an interrupt controller
- #interrupt-cells:
Usage: required
Value type: <u32>
Definition: must be 2. Specifying the pin number and flags, as defined
in <dt-bindings/interrupt-controller/irq.h>
- gpio-controller:
Usage: required
Value type: <none>
Definition: identifies this node as a gpio controller
- #gpio-cells:
Usage: required
Value type: <u32>
Definition: must be 2. Specifying the pin number and flags, as defined
in <dt-bindings/gpio/gpio.h>
- gpio-ranges:
Usage: required
Definition: see ../gpio/gpio.txt
Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
a general description of GPIO and interrupt bindings.
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices, including the meaning of the
phrase "pin configuration node".
The pin configuration nodes act as a container for an arbitrary number of
subnodes. Each of these subnodes represents some desired configuration for a
pin, a group, or a list of pins or groups. This configuration can include the
mux function to select on those pin(s)/group(s), and various pin configuration
parameters, such as pull-up, drive strength, etc.
PIN CONFIGURATION NODES:
The name of each subnode is not important; all subnodes should be enumerated
and processed purely based on their content.
Each subnode only affects those parameters that are explicitly listed. In
other words, a subnode that lists a mux function but no pin configuration
parameters implies no information about any pin configuration parameters.
Similarly, a pin subnode that describes a pullup parameter implies no
information about e.g. the mux function.
The following generic properties as defined in pinctrl-bindings.txt are valid
to specify in a pin configuration subnode:
- pins:
Usage: required
Value type: <string-array>
Definition: List of gpio pins affected by the properties specified in
this subnode.
Valid pins are:
gpio0-gpio119
Supports mux, bias and drive-strength
sdc1_clk, sdc1_cmd, sdc1_data, sdc2_clk, sdc2_cmd,
sdc2_data
Supports bias and drive-strength
ufs_reset
Supports bias and drive-strength
- function:
Usage: required
Value type: <string>
Definition: Specify the alternative function to be configured for the
specified pins. Functions are only valid for gpio pins.
Valid values are:
gpio, hdmi_tx, hdmi_ddc, blsp_uart_tx_a2, blsp_spi2, m_voc,
qdss_cti_trig_in_a0, blsp_uart_rx_a2, qdss_tracectl_a,
blsp_uart2, aud_cdc, blsp_i2c_sda_a2, qdss_tracedata_a,
blsp_i2c_scl_a2, qdss_tracectl_b, qdss_cti_trig_in_b0,
blsp_uart1, blsp_spi_mosi_a1, blsp_spi_miso_a1,
qdss_tracedata_b, blsp_i2c1, blsp_spi_cs_n_a1, gcc_plltest,
blsp_spi_clk_a1, rgb_data0, blsp_uart5, blsp_spi5,
adsp_ext, rgb_data1, prng_rosc, rgb_data2, blsp_i2c5,
gcc_gp1_clk_b, rgb_data3, gcc_gp2_clk_b, blsp_spi0,
blsp_uart0, gcc_gp3_clk_b, blsp_i2c0, qdss_traceclk_b,
pcie_clk, nfc_irq, blsp_spi4, nfc_dwl, audio_ts, rgb_data4,
spi_lcd, blsp_uart_tx_b2, gcc_gp3_clk_a, rgb_data5,
blsp_uart_rx_b2, blsp_i2c_sda_b2, blsp_i2c_scl_b2,
pwm_led11, i2s_3_data0_a, ebi2_lcd, i2s_3_data1_a,
i2s_3_data2_a, atest_char, pwm_led3, i2s_3_data3_a,
pwm_led4, i2s_4, ebi2_a, dsd_clk_b, pwm_led5, pwm_led6,
pwm_led7, pwm_led8, pwm_led24, spkr_dac0, blsp_i2c4,
pwm_led9, pwm_led10, spdifrx_opt, pwm_led12, pwm_led13,
pwm_led14, wlan1_adc1, rgb_data_b0, pwm_led15,
blsp_spi_mosi_b1, wlan1_adc0, rgb_data_b1, pwm_led16,
blsp_spi_miso_b1, qdss_cti_trig_out_b0, wlan2_adc1,
rgb_data_b2, pwm_led17, blsp_spi_cs_n_b1, wlan2_adc0,
rgb_data_b3, pwm_led18, blsp_spi_clk_b1, rgb_data_b4,
pwm_led19, ext_mclk1_b, qdss_traceclk_a, rgb_data_b5,
pwm_led20, atest_char3, i2s_3_sck_b, ldo_update, bimc_dte0,
rgb_hsync, pwm_led21, i2s_3_ws_b, dbg_out, rgb_vsync,
i2s_3_data0_b, ldo_en, hdmi_dtest, rgb_de, i2s_3_data1_b,
hdmi_lbk9, rgb_clk, atest_char1, i2s_3_data2_b, ebi_cdc,
hdmi_lbk8, rgb_mdp, atest_char0, i2s_3_data3_b, hdmi_lbk7,
rgb_data_b6, rgb_data_b7, hdmi_lbk6, rgmii_int, cri_trng1,
rgmii_wol, cri_trng0, gcc_tlmm, rgmii_ck, rgmii_tx,
hdmi_lbk5, hdmi_pixel, hdmi_rcv, hdmi_lbk4, rgmii_ctl,
ext_lpass, rgmii_rx, cri_trng, hdmi_lbk3, hdmi_lbk2,
qdss_cti_trig_out_b1, rgmii_mdio, hdmi_lbk1, rgmii_mdc,
hdmi_lbk0, ir_in, wsa_en, rgb_data6, rgb_data7,
atest_char2, ebi_ch0, blsp_uart3, blsp_spi3, sd_write,
blsp_i2c3, gcc_gp1_clk_a, qdss_cti_trig_in_b1,
gcc_gp2_clk_a, ext_mclk0, mclk_in1, i2s_1, dsd_clk_a,
qdss_cti_trig_in_a1, rgmi_dll1, pwm_led22, pwm_led23,
qdss_cti_trig_out_a0, rgmi_dll2, pwm_led1,
qdss_cti_trig_out_a1, pwm_led2, i2s_2, pll_bist,
ext_mclk1_a, mclk_in2, bimc_dte1, i2s_3_sck_a, i2s_3_ws_a
- bias-disable:
Usage: optional
Value type: <none>
Definition: The specified pins should be configued as no pull.
- bias-pull-down:
Usage: optional
Value type: <none>
Definition: The specified pins should be configued as pull down.
- bias-pull-up:
Usage: optional
Value type: <none>
Definition: The specified pins should be configued as pull up.
- output-high:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
high.
Not valid for sdc pins.
- output-low:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
low.
Not valid for sdc pins.
- drive-strength:
Usage: optional
Value type: <u32>
Definition: Selects the drive strength for the specified pins, in mA.
Valid values are: 2, 4, 6, 8, 10, 12, 14 and 16
Example:
tlmm: pinctrl@1000000 {
compatible = "qcom,qcs404-pinctrl";
reg = <0x01000000 0x200000>,
<0x01300000 0x200000>,
<0x07b00000 0x200000>;
reg-names = "south", "north", "east";
interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&tlmm 0 0 120>;
interrupt-controller;
#interrupt-cells = <2>;
};

View File

@ -0,0 +1,191 @@
Qualcomm Technologies, Inc. SDM660 TLMM block
This binding describes the Top Level Mode Multiplexer block found in the
SDM660 platform.
- compatible:
Usage: required
Value type: <string>
Definition: must be "qcom,sdm660-pinctrl" or
"qcom,sdm630-pinctrl".
- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: the base address and size of the north, center and south
TLMM tiles.
- reg-names:
Usage: required
Value type: <stringlist>
Definition: names for the cells of reg, must contain "north", "center"
and "south".
- interrupts:
Usage: required
Value type: <prop-encoded-array>
Definition: should specify the TLMM summary IRQ.
- interrupt-controller:
Usage: required
Value type: <none>
Definition: identifies this node as an interrupt controller
- #interrupt-cells:
Usage: required
Value type: <u32>
Definition: must be 2. Specifying the pin number and flags, as defined
in <dt-bindings/interrupt-controller/irq.h>
- gpio-controller:
Usage: required
Value type: <none>
Definition: identifies this node as a gpio controller
- gpio-ranges:
Usage: required
Value type: <prop-encoded-array>
Definition: Specifies the mapping between gpio controller and
pin-controller pins.
- #gpio-cells:
Usage: required
Value type: <u32>
Definition: must be 2. Specifying the pin number and flags, as defined
in <dt-bindings/gpio/gpio.h>
Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
a general description of GPIO and interrupt bindings.
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices, including the meaning of the
phrase "pin configuration node".
The pin configuration nodes act as a container for an arbitrary number of
subnodes. Each of these subnodes represents some desired configuration for a
pin, a group, or a list of pins or groups. This configuration can include the
mux function to select on those pin(s)/group(s), and various pin configuration
parameters, such as pull-up, drive strength, etc.
PIN CONFIGURATION NODES:
The name of each subnode is not important; all subnodes should be enumerated
and processed purely based on their content.
Each subnode only affects those parameters that are explicitly listed. In
other words, a subnode that lists a mux function but no pin configuration
parameters implies no information about any pin configuration parameters.
Similarly, a pin subnode that describes a pullup parameter implies no
information about e.g. the mux function.
The following generic properties as defined in pinctrl-bindings.txt are valid
to specify in a pin configuration subnode:
- pins:
Usage: required
Value type: <string-array>
Definition: List of gpio pins affected by the properties specified in
this subnode. Valid pins are:
gpio0-gpio113,
Supports mux, bias and drive-strength
sdc1_clk, sdc1_cmd, sdc1_data sdc2_clk, sdc2_cmd, sdc2_data sdc1_rclk,
Supports bias and drive-strength
- function:
Usage: required
Value type: <string>
Definition: Specify the alternative function to be configured for the
specified pins. Functions are only valid for gpio pins.
Valid values are:
adsp_ext, agera_pll, atest_char, atest_char0, atest_char1,
atest_char2, atest_char3, atest_gpsadc0, atest_gpsadc1,
atest_tsens, atest_tsens2, atest_usb1, atest_usb10,
atest_usb11, atest_usb12, atest_usb13, atest_usb2,
atest_usb20, atest_usb21, atest_usb22, atest_usb23,
audio_ref, bimc_dte0, bimc_dte1, blsp_i2c1, blsp_i2c2,
blsp_i2c3, blsp_i2c4, blsp_i2c5, blsp_i2c6, blsp_i2c7,
blsp_i2c8_a, blsp_i2c8_b, blsp_spi1, blsp_spi2, blsp_spi3,
blsp_spi3_cs1, blsp_spi3_cs2, blsp_spi4, blsp_spi5,
blsp_spi6, blsp_spi7, blsp_spi8_a, blsp_spi8_b,
blsp_spi8_cs1, blsp_spi8_cs2, blsp_uart1, blsp_uart2,
blsp_uart5, blsp_uart6_a, blsp_uart6_b, blsp_uim1,
blsp_uim2, blsp_uim5, blsp_uim6, cam_mclk, cci_async,
cci_i2c, cri_trng, cri_trng0, cri_trng1, dbg_out, ddr_bist,
gcc_gp1, gcc_gp2, gcc_gp3, gpio, gps_tx_a, gps_tx_b, gps_tx_c,
isense_dbg, jitter_bist, ldo_en, ldo_update, m_voc, mdp_vsync,
mdss_vsync0, mdss_vsync1, mdss_vsync2, mdss_vsync3, mss_lte,
nav_pps_a, nav_pps_b, nav_pps_c, pa_indicator, phase_flag0,
phase_flag1, phase_flag10, phase_flag11, phase_flag12,
phase_flag13, phase_flag14, phase_flag15, phase_flag16,
phase_flag17, phase_flag18, phase_flag19, phase_flag2,
phase_flag20, phase_flag21, phase_flag22, phase_flag23,
phase_flag24, phase_flag25, phase_flag26, phase_flag27,
phase_flag28, phase_flag29, phase_flag3, phase_flag30,
phase_flag31, phase_flag4, phase_flag5, phase_flag6,
phase_flag7, phase_flag8, phase_flag9, pll_bypassnl,
pll_reset, pri_mi2s, pri_mi2s_ws, prng_rosc, pwr_crypto,
pwr_modem, pwr_nav, qdss_cti0_a, qdss_cti0_b, qdss_cti1_a,
qdss_cti1_b, qdss_gpio, qdss_gpio0, qdss_gpio1, qdss_gpio10,
qdss_gpio11, qdss_gpio12, qdss_gpio13, qdss_gpio14, qdss_gpio15,
qdss_gpio2, qdss_gpio3, qdss_gpio4, qdss_gpio5, qdss_gpio6,
qdss_gpio7, qdss_gpio8, qdss_gpio9, qlink_enable, qlink_request,
qspi_clk, qspi_cs, qspi_data0, qspi_data1, qspi_data2,
qspi_data3, qspi_resetn, sec_mi2s, sndwire_clk, sndwire_data,
sp_cmu, ssc_irq, tgu_ch0, tgu_ch1, tsense_pwm1, tsense_pwm2,
uim1_clk, uim1_data, uim1_present, uim1_reset, uim2_clk,
uim2_data, uim2_present, uim2_reset, uim_batt, vfr_1,
vsense_clkout, vsense_data0, vsense_data1, vsense_mode,
wlan1_adc0, wlan1_adc1, wlan2_adc0, wlan2_adc1
- bias-disable:
Usage: optional
Value type: <none>
Definition: The specified pins should be configued as no pull.
- bias-pull-down:
Usage: optional
Value type: <none>
Definition: The specified pins should be configued as pull down.
- bias-pull-up:
Usage: optional
Value type: <none>
Definition: The specified pins should be configued as pull up.
- output-high:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
high.
Not valid for sdc pins.
- output-low:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
low.
Not valid for sdc pins.
- drive-strength:
Usage: optional
Value type: <u32>
Definition: Selects the drive strength for the specified pins, in mA.
Valid values are: 2, 4, 6, 8, 10, 12, 14 and 16
Example:
tlmm: pinctrl@3100000 {
compatible = "qcom,sdm660-pinctrl";
reg = <0x3100000 0x200000>,
<0x3500000 0x200000>,
<0x3900000 0x200000>;
reg-names = "south", "center", "north";
interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
gpio-ranges = <&tlmm 0 0 114>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};

View File

@ -14,8 +14,11 @@ Required Properties:
- "renesas,pfc-r8a73a4": for R8A73A4 (R-Mobile APE6) compatible pin-controller.
- "renesas,pfc-r8a7740": for R8A7740 (R-Mobile A1) compatible pin-controller.
- "renesas,pfc-r8a7743": for R8A7743 (RZ/G1M) compatible pin-controller.
- "renesas,pfc-r8a7744": for R8A7744 (RZ/G1N) compatible pin-controller.
- "renesas,pfc-r8a7745": for R8A7745 (RZ/G1E) compatible pin-controller.
- "renesas,pfc-r8a77470": for R8A77470 (RZ/G1C) compatible pin-controller.
- "renesas,pfc-r8a774a1": for R8A774A1 (RZ/G2M) compatible pin-controller.
- "renesas,pfc-r8a774c0": for R8A774C0 (RZ/G2E) compatible pin-controller.
- "renesas,pfc-r8a7778": for R8A7778 (R-Car M1) compatible pin-controller.
- "renesas,pfc-r8a7779": for R8A7779 (R-Car H1) compatible pin-controller.
- "renesas,pfc-r8a7790": for R8A7790 (R-Car H2) compatible pin-controller.

View File

@ -0,0 +1,153 @@
Renesas RZ/N1 SoC Pinctrl node description.
Pin controller node
-------------------
Required properties:
- compatible: SoC-specific compatible string "renesas,<soc-specific>-pinctrl"
followed by "renesas,rzn1-pinctrl" as fallback. The SoC-specific compatible
strings must be one of:
"renesas,r9a06g032-pinctrl" for RZ/N1D
"renesas,r9a06g033-pinctrl" for RZ/N1S
- reg: Address base and length of the memory area where the pin controller
hardware is mapped to.
- clocks: phandle for the clock, see the description of clock-names below.
- clock-names: Contains the name of the clock:
"bus", the bus clock, sometimes described as pclk, for register accesses.
Example:
pinctrl: pin-controller@40067000 {
compatible = "renesas,r9a06g032-pinctrl", "renesas,rzn1-pinctrl";
reg = <0x40067000 0x1000>, <0x51000000 0x480>;
clocks = <&sysctrl R9A06G032_HCLK_PINCONFIG>;
clock-names = "bus";
};
Sub-nodes
---------
The child nodes of the pin controller node describe a pin multiplexing
function.
- Pin multiplexing sub-nodes:
A pin multiplexing sub-node describes how to configure a set of
(or a single) pin in some desired alternate function mode.
A single sub-node may define several pin configurations.
Please refer to pinctrl-bindings.txt to get to know more on generic
pin properties usage.
The allowed generic formats for a pin multiplexing sub-node are the
following ones:
node-1 {
pinmux = <PIN_ID_AND_MUX>, <PIN_ID_AND_MUX>, ... ;
GENERIC_PINCONFIG;
};
node-2 {
sub-node-1 {
pinmux = <PIN_ID_AND_MUX>, <PIN_ID_AND_MUX>, ... ;
GENERIC_PINCONFIG;
};
sub-node-2 {
pinmux = <PIN_ID_AND_MUX>, <PIN_ID_AND_MUX>, ... ;
GENERIC_PINCONFIG;
};
...
sub-node-n {
pinmux = <PIN_ID_AND_MUX>, <PIN_ID_AND_MUX>, ... ;
GENERIC_PINCONFIG;
};
};
node-3 {
pinmux = <PIN_ID_AND_MUX>, <PIN_ID_AND_MUX>, ... ;
GENERIC_PINCONFIG;
sub-node-1 {
pinmux = <PIN_ID_AND_MUX>, <PIN_ID_AND_MUX>, ... ;
GENERIC_PINCONFIG;
};
...
sub-node-n {
pinmux = <PIN_ID_AND_MUX>, <PIN_ID_AND_MUX>, ... ;
GENERIC_PINCONFIG;
};
};
Use the latter two formats when pins part of the same logical group need to
have different generic pin configuration flags applied. Note that the generic
pinconfig in node-3 does not apply to the sub-nodes.
Client sub-nodes shall refer to pin multiplexing sub-nodes using the phandle
of the most external one.
Eg.
client-1 {
...
pinctrl-0 = <&node-1>;
...
};
client-2 {
...
pinctrl-0 = <&node-2>;
...
};
Required properties:
- pinmux:
integer array representing pin number and pin multiplexing configuration.
When a pin has to be configured in alternate function mode, use this
property to identify the pin by its global index, and provide its
alternate function configuration number along with it.
When multiple pins are required to be configured as part of the same
alternate function they shall be specified as members of the same
argument list of a single "pinmux" property.
Integers values in the "pinmux" argument list are assembled as:
(PIN | MUX_FUNC << 8)
where PIN directly corresponds to the pl_gpio pin number and MUX_FUNC is
one of the alternate function identifiers defined in:
<include/dt-bindings/pinctrl/rzn1-pinctrl.h>
These identifiers collapse the IO Multiplex Configuration Level 1 and
Level 2 numbers that are detailed in the hardware reference manual into a
single number. The identifiers for Level 2 are simply offset by 10.
Additional identifiers are provided to specify the MDIO source peripheral.
Optional generic pinconf properties:
- bias-disable - disable any pin bias
- bias-pull-up - pull up the pin with 50 KOhm
- bias-pull-down - pull down the pin with 50 KOhm
- bias-high-impedance - high impedance mode
- drive-strength - sink or source at most 4, 6, 8 or 12 mA
Example:
A serial communication interface with a TX output pin and an RX input pin.
&pinctrl {
pins_uart0: pins_uart0 {
pinmux = <
RZN1_PINMUX(103, RZN1_FUNC_UART0_I) /* UART0_TXD */
RZN1_PINMUX(104, RZN1_FUNC_UART0_I) /* UART0_RXD */
>;
};
};
Example 2:
Here we set the pull up on the RXD pin of the UART.
&pinctrl {
pins_uart0: pins_uart0 {
pinmux = <RZN1_PINMUX(103, RZN1_FUNC_UART0_I)>; /* TXD */
pins_uart6_rx {
pinmux = <RZN1_PINMUX(104, RZN1_FUNC_UART0_I)>; /* RXD */
bias-pull-up;
};
};
};

View File

@ -11519,15 +11519,12 @@ S: Maintained
F: drivers/pinctrl/intel/
PIN CONTROLLER - MEDIATEK
M: Sean Wang <sean.wang@mediatek.com>
M: Sean Wang <sean.wang@kernel.org>
L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
F: Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
F: drivers/pinctrl/mediatek/mtk-eint.*
F: drivers/pinctrl/mediatek/pinctrl-mtk-common.*
F: drivers/pinctrl/mediatek/pinctrl-mt2701.c
F: drivers/pinctrl/mediatek/pinctrl-mt7622.c
F: drivers/pinctrl/mediatek/
PIN CONTROLLER - QUALCOMM
M: Bjorn Andersson <bjorn.andersson@linaro.org>

View File

@ -267,17 +267,6 @@ config GPIO_ICH
If unsure, say N.
config GPIO_INGENIC
tristate "Ingenic JZ47xx SoCs GPIO support"
depends on OF
depends on MACH_INGENIC || COMPILE_TEST
select GPIOLIB_IRQCHIP
help
Say yes here to support the GPIO functionality present on the
JZ4740 and JZ4780 SoCs from Ingenic.
If unsure, say N.
config GPIO_IOP
tristate "Intel IOP GPIO"
depends on ARCH_IOP32X || ARCH_IOP33X || COMPILE_TEST

View File

@ -57,7 +57,6 @@ obj-$(CONFIG_GPIO_GRGPIO) += gpio-grgpio.o
obj-$(CONFIG_GPIO_HLWD) += gpio-hlwd.o
obj-$(CONFIG_HTC_EGPIO) += gpio-htc-egpio.o
obj-$(CONFIG_GPIO_ICH) += gpio-ich.o
obj-$(CONFIG_GPIO_INGENIC) += gpio-ingenic.o
obj-$(CONFIG_GPIO_IOP) += gpio-iop.o
obj-$(CONFIG_GPIO_IT87) += gpio-it87.o
obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o

View File

@ -1,392 +0,0 @@
/*
* Ingenic JZ47xx GPIO driver
*
* Copyright (c) 2017 Paul Cercueil <paul@crapouillou.net>
*
* License terms: GNU General Public License (GPL) version 2
*/
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/pinctrl/consumer.h>
#include <linux/regmap.h>
#define GPIO_PIN 0x00
#define GPIO_MSK 0x20
#define JZ4740_GPIO_DATA 0x10
#define JZ4740_GPIO_SELECT 0x50
#define JZ4740_GPIO_DIR 0x60
#define JZ4740_GPIO_TRIG 0x70
#define JZ4740_GPIO_FLAG 0x80
#define JZ4770_GPIO_INT 0x10
#define JZ4770_GPIO_PAT1 0x30
#define JZ4770_GPIO_PAT0 0x40
#define JZ4770_GPIO_FLAG 0x50
#define REG_SET(x) ((x) + 0x4)
#define REG_CLEAR(x) ((x) + 0x8)
enum jz_version {
ID_JZ4740,
ID_JZ4770,
ID_JZ4780,
};
struct ingenic_gpio_chip {
struct regmap *map;
struct gpio_chip gc;
struct irq_chip irq_chip;
unsigned int irq, reg_base;
enum jz_version version;
};
static u32 gpio_ingenic_read_reg(struct ingenic_gpio_chip *jzgc, u8 reg)
{
unsigned int val;
regmap_read(jzgc->map, jzgc->reg_base + reg, &val);
return (u32) val;
}
static void gpio_ingenic_set_bit(struct ingenic_gpio_chip *jzgc,
u8 reg, u8 offset, bool set)
{
if (set)
reg = REG_SET(reg);
else
reg = REG_CLEAR(reg);
regmap_write(jzgc->map, jzgc->reg_base + reg, BIT(offset));
}
static inline bool gpio_get_value(struct ingenic_gpio_chip *jzgc, u8 offset)
{
unsigned int val = gpio_ingenic_read_reg(jzgc, GPIO_PIN);
return !!(val & BIT(offset));
}
static void gpio_set_value(struct ingenic_gpio_chip *jzgc, u8 offset, int value)
{
if (jzgc->version >= ID_JZ4770)
gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_PAT0, offset, !!value);
else
gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_DATA, offset, !!value);
}
static void irq_set_type(struct ingenic_gpio_chip *jzgc,
u8 offset, unsigned int type)
{
u8 reg1, reg2;
if (jzgc->version >= ID_JZ4770) {
reg1 = JZ4770_GPIO_PAT1;
reg2 = JZ4770_GPIO_PAT0;
} else {
reg1 = JZ4740_GPIO_TRIG;
reg2 = JZ4740_GPIO_DIR;
}
switch (type) {
case IRQ_TYPE_EDGE_RISING:
gpio_ingenic_set_bit(jzgc, reg2, offset, true);
gpio_ingenic_set_bit(jzgc, reg1, offset, true);
break;
case IRQ_TYPE_EDGE_FALLING:
gpio_ingenic_set_bit(jzgc, reg2, offset, false);
gpio_ingenic_set_bit(jzgc, reg1, offset, true);
break;
case IRQ_TYPE_LEVEL_HIGH:
gpio_ingenic_set_bit(jzgc, reg2, offset, true);
gpio_ingenic_set_bit(jzgc, reg1, offset, false);
break;
case IRQ_TYPE_LEVEL_LOW:
default:
gpio_ingenic_set_bit(jzgc, reg2, offset, false);
gpio_ingenic_set_bit(jzgc, reg1, offset, false);
break;
}
}
static void ingenic_gpio_irq_mask(struct irq_data *irqd)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
gpio_ingenic_set_bit(jzgc, GPIO_MSK, irqd->hwirq, true);
}
static void ingenic_gpio_irq_unmask(struct irq_data *irqd)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
gpio_ingenic_set_bit(jzgc, GPIO_MSK, irqd->hwirq, false);
}
static void ingenic_gpio_irq_enable(struct irq_data *irqd)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
int irq = irqd->hwirq;
if (jzgc->version >= ID_JZ4770)
gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_INT, irq, true);
else
gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, true);
ingenic_gpio_irq_unmask(irqd);
}
static void ingenic_gpio_irq_disable(struct irq_data *irqd)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
int irq = irqd->hwirq;
ingenic_gpio_irq_mask(irqd);
if (jzgc->version >= ID_JZ4770)
gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_INT, irq, false);
else
gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, false);
}
static void ingenic_gpio_irq_ack(struct irq_data *irqd)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
int irq = irqd->hwirq;
bool high;
if (irqd_get_trigger_type(irqd) == IRQ_TYPE_EDGE_BOTH) {
/*
* Switch to an interrupt for the opposite edge to the one that
* triggered the interrupt being ACKed.
*/
high = gpio_get_value(jzgc, irq);
if (high)
irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_FALLING);
else
irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_RISING);
}
if (jzgc->version >= ID_JZ4770)
gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_FLAG, irq, false);
else
gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_DATA, irq, true);
}
static int ingenic_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
switch (type) {
case IRQ_TYPE_EDGE_BOTH:
case IRQ_TYPE_EDGE_RISING:
case IRQ_TYPE_EDGE_FALLING:
irq_set_handler_locked(irqd, handle_edge_irq);
break;
case IRQ_TYPE_LEVEL_HIGH:
case IRQ_TYPE_LEVEL_LOW:
irq_set_handler_locked(irqd, handle_level_irq);
break;
default:
irq_set_handler_locked(irqd, handle_bad_irq);
}
if (type == IRQ_TYPE_EDGE_BOTH) {
/*
* The hardware does not support interrupts on both edges. The
* best we can do is to set up a single-edge interrupt and then
* switch to the opposing edge when ACKing the interrupt.
*/
bool high = gpio_get_value(jzgc, irqd->hwirq);
type = high ? IRQ_TYPE_EDGE_FALLING : IRQ_TYPE_EDGE_RISING;
}
irq_set_type(jzgc, irqd->hwirq, type);
return 0;
}
static int ingenic_gpio_irq_set_wake(struct irq_data *irqd, unsigned int on)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
return irq_set_irq_wake(jzgc->irq, on);
}
static void ingenic_gpio_irq_handler(struct irq_desc *desc)
{
struct gpio_chip *gc = irq_desc_get_handler_data(desc);
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
struct irq_chip *irq_chip = irq_data_get_irq_chip(&desc->irq_data);
unsigned long flag, i;
chained_irq_enter(irq_chip, desc);
if (jzgc->version >= ID_JZ4770)
flag = gpio_ingenic_read_reg(jzgc, JZ4770_GPIO_FLAG);
else
flag = gpio_ingenic_read_reg(jzgc, JZ4740_GPIO_FLAG);
for_each_set_bit(i, &flag, 32)
generic_handle_irq(irq_linear_revmap(gc->irq.domain, i));
chained_irq_exit(irq_chip, desc);
}
static void ingenic_gpio_set(struct gpio_chip *gc,
unsigned int offset, int value)
{
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
gpio_set_value(jzgc, offset, value);
}
static int ingenic_gpio_get(struct gpio_chip *gc, unsigned int offset)
{
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
return (int) gpio_get_value(jzgc, offset);
}
static int ingenic_gpio_direction_input(struct gpio_chip *gc,
unsigned int offset)
{
return pinctrl_gpio_direction_input(gc->base + offset);
}
static int ingenic_gpio_direction_output(struct gpio_chip *gc,
unsigned int offset, int value)
{
ingenic_gpio_set(gc, offset, value);
return pinctrl_gpio_direction_output(gc->base + offset);
}
static const struct of_device_id ingenic_gpio_of_match[] = {
{ .compatible = "ingenic,jz4740-gpio", .data = (void *)ID_JZ4740 },
{ .compatible = "ingenic,jz4770-gpio", .data = (void *)ID_JZ4770 },
{ .compatible = "ingenic,jz4780-gpio", .data = (void *)ID_JZ4780 },
{},
};
MODULE_DEVICE_TABLE(of, ingenic_gpio_of_match);
static int ingenic_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct ingenic_gpio_chip *jzgc;
u32 bank;
int err;
jzgc = devm_kzalloc(dev, sizeof(*jzgc), GFP_KERNEL);
if (!jzgc)
return -ENOMEM;
jzgc->map = dev_get_drvdata(dev->parent);
if (!jzgc->map) {
dev_err(dev, "Cannot get parent regmap\n");
return -ENXIO;
}
err = of_property_read_u32(dev->of_node, "reg", &bank);
if (err) {
dev_err(dev, "Cannot read \"reg\" property: %i\n", err);
return err;
}
jzgc->reg_base = bank * 0x100;
jzgc->gc.label = devm_kasprintf(dev, GFP_KERNEL, "GPIO%c", 'A' + bank);
if (!jzgc->gc.label)
return -ENOMEM;
/* DO NOT EXPAND THIS: FOR BACKWARD GPIO NUMBERSPACE COMPATIBIBILITY
* ONLY: WORK TO TRANSITION CONSUMERS TO USE THE GPIO DESCRIPTOR API IN
* <linux/gpio/consumer.h> INSTEAD.
*/
jzgc->gc.base = bank * 32;
jzgc->gc.ngpio = 32;
jzgc->gc.parent = dev;
jzgc->gc.of_node = dev->of_node;
jzgc->gc.owner = THIS_MODULE;
jzgc->version = (enum jz_version)of_device_get_match_data(dev);
jzgc->gc.set = ingenic_gpio_set;
jzgc->gc.get = ingenic_gpio_get;
jzgc->gc.direction_input = ingenic_gpio_direction_input;
jzgc->gc.direction_output = ingenic_gpio_direction_output;
if (of_property_read_bool(dev->of_node, "gpio-ranges")) {
jzgc->gc.request = gpiochip_generic_request;
jzgc->gc.free = gpiochip_generic_free;
}
err = devm_gpiochip_add_data(dev, &jzgc->gc, jzgc);
if (err)
return err;
jzgc->irq = irq_of_parse_and_map(dev->of_node, 0);
if (!jzgc->irq)
return -EINVAL;
jzgc->irq_chip.name = jzgc->gc.label;
jzgc->irq_chip.irq_enable = ingenic_gpio_irq_enable;
jzgc->irq_chip.irq_disable = ingenic_gpio_irq_disable;
jzgc->irq_chip.irq_unmask = ingenic_gpio_irq_unmask;
jzgc->irq_chip.irq_mask = ingenic_gpio_irq_mask;
jzgc->irq_chip.irq_ack = ingenic_gpio_irq_ack;
jzgc->irq_chip.irq_set_type = ingenic_gpio_irq_set_type;
jzgc->irq_chip.irq_set_wake = ingenic_gpio_irq_set_wake;
jzgc->irq_chip.flags = IRQCHIP_MASK_ON_SUSPEND;
err = gpiochip_irqchip_add(&jzgc->gc, &jzgc->irq_chip, 0,
handle_level_irq, IRQ_TYPE_NONE);
if (err)
return err;
gpiochip_set_chained_irqchip(&jzgc->gc, &jzgc->irq_chip,
jzgc->irq, ingenic_gpio_irq_handler);
return 0;
}
static int ingenic_gpio_remove(struct platform_device *pdev)
{
return 0;
}
static struct platform_driver ingenic_gpio_driver = {
.driver = {
.name = "gpio-ingenic",
.of_match_table = of_match_ptr(ingenic_gpio_of_match),
},
.probe = ingenic_gpio_probe,
.remove = ingenic_gpio_remove,
};
static int __init ingenic_gpio_drv_register(void)
{
return platform_driver_register(&ingenic_gpio_driver);
}
subsys_initcall(ingenic_gpio_drv_register);
static void __exit ingenic_gpio_drv_unregister(void)
{
platform_driver_unregister(&ingenic_gpio_driver);
}
module_exit(ingenic_gpio_drv_unregister);
MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
MODULE_DESCRIPTION("Ingenic JZ47xx GPIO driver");
MODULE_LICENSE("GPL");

View File

@ -12,7 +12,7 @@
* GNU General Public License for more details.
*/
#include <linux/bitops.h>
#include <linux/bits.h>
#include <linux/gpio/driver.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>

View File

@ -195,6 +195,16 @@ config PINCTRL_RZA1
help
This selects pinctrl driver for Renesas RZ/A1 platforms.
config PINCTRL_RZN1
bool "Renesas RZ/N1 pinctrl driver"
depends on OF
depends on ARCH_RZN1 || COMPILE_TEST
select GENERIC_PINCTRL_GROUPS
select GENERIC_PINMUX_FUNCTIONS
select GENERIC_PINCONF
help
This selects pinctrl driver for Renesas RZ/N1 devices.
config PINCTRL_SINGLE
tristate "One-register-per-pin type device tree based pinctrl driver"
depends on OF
@ -309,12 +319,14 @@ config PINCTRL_ZYNQ
config PINCTRL_INGENIC
bool "Pinctrl driver for the Ingenic JZ47xx SoCs"
default y
default MACH_INGENIC
depends on OF
depends on MACH_INGENIC || COMPILE_TEST
depends on MIPS || COMPILE_TEST
select GENERIC_PINCONF
select GENERIC_PINCTRL_GROUPS
select GENERIC_PINMUX_FUNCTIONS
select GPIOLIB
select GPIOLIB_IRQCHIP
select REGMAP_MMIO
config PINCTRL_RK805
@ -346,6 +358,7 @@ source "drivers/pinctrl/freescale/Kconfig"
source "drivers/pinctrl/intel/Kconfig"
source "drivers/pinctrl/mvebu/Kconfig"
source "drivers/pinctrl/nomadik/Kconfig"
source "drivers/pinctrl/nuvoton/Kconfig"
source "drivers/pinctrl/pxa/Kconfig"
source "drivers/pinctrl/qcom/Kconfig"
source "drivers/pinctrl/samsung/Kconfig"

View File

@ -27,6 +27,7 @@ obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-pic32.o
obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o
obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
obj-$(CONFIG_PINCTRL_RZA1) += pinctrl-rza1.o
obj-$(CONFIG_PINCTRL_RZN1) += pinctrl-rzn1.o
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
obj-$(CONFIG_PINCTRL_SIRF) += sirf/
obj-$(CONFIG_PINCTRL_SX150X) += pinctrl-sx150x.o
@ -51,6 +52,7 @@ obj-y += freescale/
obj-$(CONFIG_X86) += intel/
obj-y += mvebu/
obj-y += nomadik/
obj-$(CONFIG_ARCH_NPCM7XX) += nuvoton/
obj-$(CONFIG_PINCTRL_PXA) += pxa/
obj-$(CONFIG_ARCH_QCOM) += qcom/
obj-$(CONFIG_PINCTRL_SAMSUNG) += samsung/

View File

@ -715,7 +715,7 @@ int aspeed_pin_config_set(struct pinctrl_dev *pctldev, unsigned int offset,
pmap = find_pinconf_map(param, MAP_TYPE_ARG, arg);
if (unlikely(WARN_ON(!pmap)))
if (WARN_ON(!pmap))
return -EINVAL;
val = pmap->val << pconf->bit;

View File

@ -73,6 +73,19 @@ config PINCTRL_CYGNUS_MUX
configuration, with the exception that certain individual pins
can be overridden to GPIO function
config PINCTRL_NS
bool "Broadcom Northstar pins driver"
depends on OF && (ARCH_BCM_5301X || COMPILE_TEST)
select PINMUX
select GENERIC_PINCONF
default ARCH_BCM_5301X
help
Say yes here to enable the Broadcom NS SoC pins driver.
The Broadcom Northstar pins driver supports muxing multi-purpose pins
that can be used for various functions (e.g. SPI, I2C, UART) as well
as GPIOs.
config PINCTRL_NSP_GPIO
bool "Broadcom NSP GPIO (with PINCONF) driver"
depends on OF_GPIO && (ARCH_BCM_NSP || COMPILE_TEST)

View File

@ -5,6 +5,7 @@ obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o
obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o
obj-$(CONFIG_PINCTRL_IPROC_GPIO) += pinctrl-iproc-gpio.o
obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o
obj-$(CONFIG_PINCTRL_NS) += pinctrl-ns.o
obj-$(CONFIG_PINCTRL_NSP_GPIO) += pinctrl-nsp-gpio.o
obj-$(CONFIG_PINCTRL_NS2_MUX) += pinctrl-ns2-mux.o
obj-$(CONFIG_PINCTRL_NSP_MUX) += pinctrl-nsp-mux.o

View File

@ -0,0 +1,372 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 Rafał Miłecki <rafal@milecki.pl>
*/
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#define FLAG_BCM4708 BIT(1)
#define FLAG_BCM4709 BIT(2)
#define FLAG_BCM53012 BIT(3)
struct ns_pinctrl {
struct device *dev;
unsigned int chipset_flag;
struct pinctrl_dev *pctldev;
void __iomem *base;
struct pinctrl_desc pctldesc;
struct ns_pinctrl_group *groups;
unsigned int num_groups;
struct ns_pinctrl_function *functions;
unsigned int num_functions;
};
/*
* Pins
*/
static const struct pinctrl_pin_desc ns_pinctrl_pins[] = {
{ 0, "spi_clk", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
{ 1, "spi_ss", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
{ 2, "spi_mosi", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
{ 3, "spi_miso", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
{ 4, "i2c_scl", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
{ 5, "i2c_sda", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
{ 6, "mdc", (void *)(FLAG_BCM4709 | FLAG_BCM53012) },
{ 7, "mdio", (void *)(FLAG_BCM4709 | FLAG_BCM53012) },
{ 8, "pwm0", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
{ 9, "pwm1", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
{ 10, "pwm2", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
{ 11, "pwm3", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
{ 12, "uart1_rx", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
{ 13, "uart1_tx", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
{ 14, "uart1_cts", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
{ 15, "uart1_rts", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },
{ 16, "uart2_rx", (void *)(FLAG_BCM4709 | FLAG_BCM53012) },
{ 17, "uart2_tx", (void *)(FLAG_BCM4709 | FLAG_BCM53012) },
/* TODO { ??, "xtal_out", (void *)(FLAG_BCM4709) }, */
{ 22, "sdio_pwr", (void *)(FLAG_BCM4709 | FLAG_BCM53012) },
{ 23, "sdio_en_1p8v", (void *)(FLAG_BCM4709 | FLAG_BCM53012) },
};
/*
* Groups
*/
struct ns_pinctrl_group {
const char *name;
const unsigned int *pins;
const unsigned int num_pins;
unsigned int chipsets;
};
static const unsigned int spi_pins[] = { 0, 1, 2, 3 };
static const unsigned int i2c_pins[] = { 4, 5 };
static const unsigned int mdio_pins[] = { 6, 7 };
static const unsigned int pwm0_pins[] = { 8 };
static const unsigned int pwm1_pins[] = { 9 };
static const unsigned int pwm2_pins[] = { 10 };
static const unsigned int pwm3_pins[] = { 11 };
static const unsigned int uart1_pins[] = { 12, 13, 14, 15 };
static const unsigned int uart2_pins[] = { 16, 17 };
static const unsigned int sdio_pwr_pins[] = { 22 };
static const unsigned int sdio_1p8v_pins[] = { 23 };
#define NS_GROUP(_name, _pins, _chipsets) \
{ \
.name = _name, \
.pins = _pins, \
.num_pins = ARRAY_SIZE(_pins), \
.chipsets = _chipsets, \
}
static const struct ns_pinctrl_group ns_pinctrl_groups[] = {
NS_GROUP("spi_grp", spi_pins, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
NS_GROUP("i2c_grp", i2c_pins, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
NS_GROUP("mdio_grp", mdio_pins, FLAG_BCM4709 | FLAG_BCM53012),
NS_GROUP("pwm0_grp", pwm0_pins, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
NS_GROUP("pwm1_grp", pwm1_pins, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
NS_GROUP("pwm2_grp", pwm2_pins, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
NS_GROUP("pwm3_grp", pwm3_pins, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
NS_GROUP("uart1_grp", uart1_pins, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
NS_GROUP("uart2_grp", uart2_pins, FLAG_BCM4709 | FLAG_BCM53012),
NS_GROUP("sdio_pwr_grp", sdio_pwr_pins, FLAG_BCM4709 | FLAG_BCM53012),
NS_GROUP("sdio_1p8v_grp", sdio_1p8v_pins, FLAG_BCM4709 | FLAG_BCM53012),
};
/*
* Functions
*/
struct ns_pinctrl_function {
const char *name;
const char * const *groups;
const unsigned int num_groups;
unsigned int chipsets;
};
static const char * const spi_groups[] = { "spi_grp" };
static const char * const i2c_groups[] = { "i2c_grp" };
static const char * const mdio_groups[] = { "mdio_grp" };
static const char * const pwm_groups[] = { "pwm0_grp", "pwm1_grp", "pwm2_grp",
"pwm3_grp" };
static const char * const uart1_groups[] = { "uart1_grp" };
static const char * const uart2_groups[] = { "uart2_grp" };
static const char * const sdio_groups[] = { "sdio_pwr_grp", "sdio_1p8v_grp" };
#define NS_FUNCTION(_name, _groups, _chipsets) \
{ \
.name = _name, \
.groups = _groups, \
.num_groups = ARRAY_SIZE(_groups), \
.chipsets = _chipsets, \
}
static const struct ns_pinctrl_function ns_pinctrl_functions[] = {
NS_FUNCTION("spi", spi_groups, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
NS_FUNCTION("i2c", i2c_groups, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
NS_FUNCTION("mdio", mdio_groups, FLAG_BCM4709 | FLAG_BCM53012),
NS_FUNCTION("pwm", pwm_groups, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
NS_FUNCTION("uart1", uart1_groups, FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012),
NS_FUNCTION("uart2", uart2_groups, FLAG_BCM4709 | FLAG_BCM53012),
NS_FUNCTION("sdio", sdio_groups, FLAG_BCM4709 | FLAG_BCM53012),
};
/*
* Groups code
*/
static int ns_pinctrl_get_groups_count(struct pinctrl_dev *pctrl_dev)
{
struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
return ns_pinctrl->num_groups;
}
static const char *ns_pinctrl_get_group_name(struct pinctrl_dev *pctrl_dev,
unsigned int selector)
{
struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
return ns_pinctrl->groups[selector].name;
}
static int ns_pinctrl_get_group_pins(struct pinctrl_dev *pctrl_dev,
unsigned int selector,
const unsigned int **pins,
unsigned int *num_pins)
{
struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
*pins = ns_pinctrl->groups[selector].pins;
*num_pins = ns_pinctrl->groups[selector].num_pins;
return 0;
}
static const struct pinctrl_ops ns_pinctrl_ops = {
.get_groups_count = ns_pinctrl_get_groups_count,
.get_group_name = ns_pinctrl_get_group_name,
.get_group_pins = ns_pinctrl_get_group_pins,
.dt_node_to_map = pinconf_generic_dt_node_to_map_group,
.dt_free_map = pinconf_generic_dt_free_map,
};
/*
* Functions code
*/
static int ns_pinctrl_get_functions_count(struct pinctrl_dev *pctrl_dev)
{
struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
return ns_pinctrl->num_functions;
}
static const char *ns_pinctrl_get_function_name(struct pinctrl_dev *pctrl_dev,
unsigned int selector)
{
struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
return ns_pinctrl->functions[selector].name;
}
static int ns_pinctrl_get_function_groups(struct pinctrl_dev *pctrl_dev,
unsigned int selector,
const char * const **groups,
unsigned * const num_groups)
{
struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
*groups = ns_pinctrl->functions[selector].groups;
*num_groups = ns_pinctrl->functions[selector].num_groups;
return 0;
}
static int ns_pinctrl_set_mux(struct pinctrl_dev *pctrl_dev,
unsigned int func_select,
unsigned int grp_select)
{
struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
u32 unset = 0;
u32 tmp;
int i;
for (i = 0; i < ns_pinctrl->groups[grp_select].num_pins; i++) {
int pin_number = ns_pinctrl->groups[grp_select].pins[i];
unset |= BIT(pin_number);
}
tmp = readl(ns_pinctrl->base);
tmp &= ~unset;
writel(tmp, ns_pinctrl->base);
return 0;
}
static const struct pinmux_ops ns_pinctrl_pmxops = {
.get_functions_count = ns_pinctrl_get_functions_count,
.get_function_name = ns_pinctrl_get_function_name,
.get_function_groups = ns_pinctrl_get_function_groups,
.set_mux = ns_pinctrl_set_mux,
};
/*
* Controller code
*/
static struct pinctrl_desc ns_pinctrl_desc = {
.name = "pinctrl-ns",
.pctlops = &ns_pinctrl_ops,
.pmxops = &ns_pinctrl_pmxops,
};
static const struct of_device_id ns_pinctrl_of_match_table[] = {
{ .compatible = "brcm,bcm4708-pinmux", .data = (void *)FLAG_BCM4708, },
{ .compatible = "brcm,bcm4709-pinmux", .data = (void *)FLAG_BCM4709, },
{ .compatible = "brcm,bcm53012-pinmux", .data = (void *)FLAG_BCM53012, },
{ }
};
static int ns_pinctrl_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct of_device_id *of_id;
struct ns_pinctrl *ns_pinctrl;
struct pinctrl_desc *pctldesc;
struct pinctrl_pin_desc *pin;
struct ns_pinctrl_group *group;
struct ns_pinctrl_function *function;
struct resource *res;
int i;
ns_pinctrl = devm_kzalloc(dev, sizeof(*ns_pinctrl), GFP_KERNEL);
if (!ns_pinctrl)
return -ENOMEM;
pctldesc = &ns_pinctrl->pctldesc;
platform_set_drvdata(pdev, ns_pinctrl);
/* Set basic properties */
ns_pinctrl->dev = dev;
of_id = of_match_device(ns_pinctrl_of_match_table, dev);
if (!of_id)
return -EINVAL;
ns_pinctrl->chipset_flag = (uintptr_t)of_id->data;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"cru_gpio_control");
ns_pinctrl->base = devm_ioremap_resource(dev, res);
if (IS_ERR(ns_pinctrl->base)) {
dev_err(dev, "Failed to map pinctrl regs\n");
return PTR_ERR(ns_pinctrl->base);
}
memcpy(pctldesc, &ns_pinctrl_desc, sizeof(*pctldesc));
/* Set pinctrl properties */
pctldesc->pins = devm_kcalloc(dev, ARRAY_SIZE(ns_pinctrl_pins),
sizeof(struct pinctrl_pin_desc),
GFP_KERNEL);
if (!pctldesc->pins)
return -ENOMEM;
for (i = 0, pin = (struct pinctrl_pin_desc *)&pctldesc->pins[0];
i < ARRAY_SIZE(ns_pinctrl_pins); i++) {
const struct pinctrl_pin_desc *src = &ns_pinctrl_pins[i];
unsigned int chipsets = (uintptr_t)src->drv_data;
if (chipsets & ns_pinctrl->chipset_flag) {
memcpy(pin++, src, sizeof(*src));
pctldesc->npins++;
}
}
ns_pinctrl->groups = devm_kcalloc(dev, ARRAY_SIZE(ns_pinctrl_groups),
sizeof(struct ns_pinctrl_group),
GFP_KERNEL);
if (!ns_pinctrl->groups)
return -ENOMEM;
for (i = 0, group = &ns_pinctrl->groups[0];
i < ARRAY_SIZE(ns_pinctrl_groups); i++) {
const struct ns_pinctrl_group *src = &ns_pinctrl_groups[i];
if (src->chipsets & ns_pinctrl->chipset_flag) {
memcpy(group++, src, sizeof(*src));
ns_pinctrl->num_groups++;
}
}
ns_pinctrl->functions = devm_kcalloc(dev,
ARRAY_SIZE(ns_pinctrl_functions),
sizeof(struct ns_pinctrl_function),
GFP_KERNEL);
if (!ns_pinctrl->functions)
return -ENOMEM;
for (i = 0, function = &ns_pinctrl->functions[0];
i < ARRAY_SIZE(ns_pinctrl_functions); i++) {
const struct ns_pinctrl_function *src = &ns_pinctrl_functions[i];
if (src->chipsets & ns_pinctrl->chipset_flag) {
memcpy(function++, src, sizeof(*src));
ns_pinctrl->num_functions++;
}
}
/* Register */
ns_pinctrl->pctldev = devm_pinctrl_register(dev, pctldesc, ns_pinctrl);
if (IS_ERR(ns_pinctrl->pctldev)) {
dev_err(dev, "Failed to register pinctrl\n");
return PTR_ERR(ns_pinctrl->pctldev);
}
return 0;
}
static struct platform_driver ns_pinctrl_driver = {
.probe = ns_pinctrl_probe,
.driver = {
.name = "ns-pinmux",
.of_match_table = ns_pinctrl_of_match_table,
},
};
module_platform_driver(ns_pinctrl_driver);
MODULE_AUTHOR("Rafał Miłecki");
MODULE_LICENSE("GPL v2");
MODULE_DEVICE_TABLE(of, ns_pinctrl_of_match_table);

View File

@ -64,16 +64,14 @@ static int berlin_pinctrl_dt_node_to_map(struct pinctrl_dev *pctrl_dev,
ret = of_property_read_string(node, "function", &function_name);
if (ret) {
dev_err(pctrl->dev,
"missing function property in node %s\n",
node->name);
"missing function property in node %pOFn\n", node);
return -EINVAL;
}
ngroups = of_property_count_strings(node, "groups");
if (ngroups < 0) {
dev_err(pctrl->dev,
"missing groups property in node %s\n",
node->name);
"missing groups property in node %pOFn\n", node);
return -EINVAL;
}

View File

@ -550,7 +550,7 @@ static void __maybe_unused madera_pin_dbg_show(struct pinctrl_dev *pctldev,
seq_printf(s, " DRV=%umA", madera_pin_unmake_drv_str(priv, conf[1]));
if (conf[0] & MADERA_GP1_IP_CFG_MASK)
seq_puts(s, "SCHMITT");
seq_puts(s, " SCHMITT");
}
@ -608,7 +608,7 @@ static int madera_mux_set_mux(struct pinctrl_dev *pctldev,
unsigned int n_chip_groups = priv->chip->n_pin_groups;
const char *func_name = madera_mux_funcs[selector].name;
unsigned int reg;
int i, ret;
int i, ret = 0;
dev_dbg(priv->dev, "%s selecting %u (%s) for group %u (%s)\n",
__func__, selector, func_name, group,
@ -801,7 +801,7 @@ static int madera_pin_conf_get(struct pinctrl_dev *pctldev, unsigned int pin,
result = 1;
break;
default:
break;
return -ENOTSUPP;
}
*config = pinconf_to_config_packed(param, result);
@ -905,7 +905,7 @@ static int madera_pin_conf_set(struct pinctrl_dev *pctldev, unsigned int pin,
conf[1] &= ~MADERA_GP1_DIR;
break;
default:
break;
return -ENOTSUPP;
}
++configs;
@ -971,10 +971,10 @@ static int madera_pin_conf_group_set(struct pinctrl_dev *pctldev,
}
static const struct pinconf_ops madera_pin_conf_ops = {
.is_generic = true,
.pin_config_get = madera_pin_conf_get,
.pin_config_set = madera_pin_conf_set,
.pin_config_group_set = madera_pin_conf_group_set,
};
static struct pinctrl_desc madera_pin_desc = {

View File

@ -627,7 +627,7 @@ static int pinctrl_generic_group_name_to_selector(struct pinctrl_dev *pctldev,
while (selector < ngroups) {
const char *gname = ops->get_group_name(pctldev, selector);
if (!strcmp(function, gname))
if (gname && !strcmp(function, gname))
return selector;
selector++;
@ -743,7 +743,7 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev,
while (group_selector < ngroups) {
const char *gname = pctlops->get_group_name(pctldev,
group_selector);
if (!strcmp(gname, pin_group)) {
if (gname && !strcmp(gname, pin_group)) {
dev_dbg(pctldev->dev,
"found group selector %u for %s\n",
group_selector,

View File

@ -69,8 +69,7 @@ static int imx_dt_node_to_map(struct pinctrl_dev *pctldev,
*/
grp = imx_pinctrl_find_group_by_name(pctldev, np->name);
if (!grp) {
dev_err(ipctl->dev, "unable to find group for node %s\n",
np->name);
dev_err(ipctl->dev, "unable to find group for node %pOFn\n", np);
return -EINVAL;
}
@ -434,7 +433,7 @@ static int imx_pinctrl_parse_groups(struct device_node *np,
int i;
u32 config;
dev_dbg(ipctl->dev, "group(%d): %s\n", index, np->name);
dev_dbg(ipctl->dev, "group(%d): %pOFn\n", index, np);
if (info->flags & SHARE_MUX_CONF_REG)
pin_size = FSL_PIN_SHARE_SIZE;
@ -544,7 +543,7 @@ static int imx_pinctrl_parse_functions(struct device_node *np,
struct group_desc *grp;
u32 i = 0;
dev_dbg(pctl->dev, "parse function(%d): %s\n", index, np->name);
dev_dbg(pctl->dev, "parse function(%d): %pOFn\n", index, np);
func = pinmux_generic_get_function(pctl, index);
if (!func)

View File

@ -233,8 +233,8 @@ static int imx1_dt_node_to_map(struct pinctrl_dev *pctldev,
*/
grp = imx1_pinctrl_find_group_by_name(info, np->name);
if (!grp) {
dev_err(info->dev, "unable to find group for node %s\n",
np->name);
dev_err(info->dev, "unable to find group for node %pOFn\n",
np);
return -EINVAL;
}
@ -466,7 +466,7 @@ static int imx1_pinctrl_parse_groups(struct device_node *np,
const __be32 *list;
int i;
dev_dbg(info->dev, "group(%d): %s\n", index, np->name);
dev_dbg(info->dev, "group(%d): %pOFn\n", index, np);
/* Initialise group */
grp->name = np->name;
@ -477,8 +477,8 @@ static int imx1_pinctrl_parse_groups(struct device_node *np,
list = of_get_property(np, "fsl,pins", &size);
/* we do not check return since it's safe node passed down */
if (!size || size % 12) {
dev_notice(info->dev, "Not a valid fsl,pins property (%s)\n",
np->name);
dev_notice(info->dev, "Not a valid fsl,pins property (%pOFn)\n",
np);
return -EINVAL;
}
@ -513,7 +513,7 @@ static int imx1_pinctrl_parse_functions(struct device_node *np,
static u32 grp_index;
u32 i = 0;
dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name);
dev_dbg(info->dev, "parse function(%d): %pOFn\n", index, np);
func = &info->functions[index];

View File

@ -556,4 +556,3 @@ err:
iounmap(d->base);
return ret;
}
EXPORT_SYMBOL_GPL(mxs_pinctrl_probe);

View File

@ -6,18 +6,19 @@
* Author: Mathias Nyman <mathias.nyman@linux.intel.com>
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/bitops.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
#include <linux/seq_file.h>
#include <linux/bitops.h>
#include <linux/gpio/driver.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/seq_file.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
@ -682,7 +683,7 @@ static const struct pinctrl_pin_desc byt_ncore_pins[] = {
PINCTRL_PIN(27, "GPIO_NCORE27"),
};
static unsigned const byt_ncore_pins_map[BYT_NGPIO_NCORE] = {
static const unsigned int byt_ncore_pins_map[BYT_NGPIO_NCORE] = {
19, 18, 17, 20, 21, 22, 24, 25, 23, 16,
14, 15, 12, 26, 27, 1, 4, 8, 11, 0,
3, 6, 10, 13, 2, 5, 9, 7,
@ -926,7 +927,7 @@ static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
return 0;
}
static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned offset)
static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned int offset)
{
/* SCORE pin 92-93 */
if (!strcmp(vg->soc_data->uid, BYT_SCORE_ACPI_UID) &&
@ -1310,7 +1311,7 @@ static const struct pinctrl_desc byt_pinctrl_desc = {
.owner = THIS_MODULE,
};
static int byt_gpio_get(struct gpio_chip *chip, unsigned offset)
static int byt_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
struct byt_gpio *vg = gpiochip_get_data(chip);
void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
@ -1324,7 +1325,7 @@ static int byt_gpio_get(struct gpio_chip *chip, unsigned offset)
return !!(val & BYT_LEVEL);
}
static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
static void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
{
struct byt_gpio *vg = gpiochip_get_data(chip);
void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
@ -1358,9 +1359,9 @@ static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
raw_spin_unlock_irqrestore(&vg->lock, flags);
if (!(value & BYT_OUTPUT_EN))
return GPIOF_DIR_OUT;
return 0;
if (!(value & BYT_INPUT_EN))
return GPIOF_DIR_IN;
return 1;
return -EINVAL;
}
@ -1495,7 +1496,7 @@ static void byt_irq_ack(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct byt_gpio *vg = gpiochip_get_data(gc);
unsigned offset = irqd_to_hwirq(d);
unsigned int offset = irqd_to_hwirq(d);
void __iomem *reg;
reg = byt_gpio_reg(vg, offset, BYT_INT_STAT_REG);
@ -1519,7 +1520,7 @@ static void byt_irq_unmask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct byt_gpio *vg = gpiochip_get_data(gc);
unsigned offset = irqd_to_hwirq(d);
unsigned int offset = irqd_to_hwirq(d);
unsigned long flags;
void __iomem *reg;
u32 value;
@ -1775,13 +1776,11 @@ static const struct acpi_device_id byt_gpio_acpi_match[] = {
{ "INT33FC", (kernel_ulong_t)byt_soc_data },
{ }
};
MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match);
static int byt_pinctrl_probe(struct platform_device *pdev)
{
const struct byt_pinctrl_soc_data *soc_data = NULL;
const struct byt_pinctrl_soc_data **soc_table;
const struct acpi_device_id *acpi_id;
struct acpi_device *acpi_dev;
struct byt_gpio *vg;
int i, ret;
@ -1790,11 +1789,7 @@ static int byt_pinctrl_probe(struct platform_device *pdev)
if (!acpi_dev)
return -ENODEV;
acpi_id = acpi_match_device(byt_gpio_acpi_match, &pdev->dev);
if (!acpi_id)
return -ENODEV;
soc_table = (const struct byt_pinctrl_soc_data **)acpi_id->driver_data;
soc_table = (const struct byt_pinctrl_soc_data **)device_get_match_data(&pdev->dev);
for (i = 0; soc_table[i]; i++) {
if (!strcmp(acpi_dev->pnp.unique_id, soc_table[i]->uid)) {

View File

@ -6,10 +6,10 @@
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
*/
#include <linux/acpi.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-intel.h"
@ -117,17 +117,17 @@ static const struct pinctrl_pin_desc bxt_north_pins[] = {
PINCTRL_PIN(82, "TDO"),
};
static const unsigned bxt_north_pwm0_pins[] = { 34 };
static const unsigned bxt_north_pwm1_pins[] = { 35 };
static const unsigned bxt_north_pwm2_pins[] = { 36 };
static const unsigned bxt_north_pwm3_pins[] = { 37 };
static const unsigned bxt_north_uart0_pins[] = { 38, 39, 40, 41 };
static const unsigned bxt_north_uart1_pins[] = { 42, 43, 44, 45 };
static const unsigned bxt_north_uart2_pins[] = { 46, 47, 48, 49 };
static const unsigned bxt_north_uart0b_pins[] = { 50, 51, 52, 53 };
static const unsigned bxt_north_uart1b_pins[] = { 54, 55, 56, 57 };
static const unsigned bxt_north_uart2b_pins[] = { 58, 59, 60, 61 };
static const unsigned bxt_north_uart3_pins[] = { 58, 59, 60, 61 };
static const unsigned int bxt_north_pwm0_pins[] = { 34 };
static const unsigned int bxt_north_pwm1_pins[] = { 35 };
static const unsigned int bxt_north_pwm2_pins[] = { 36 };
static const unsigned int bxt_north_pwm3_pins[] = { 37 };
static const unsigned int bxt_north_uart0_pins[] = { 38, 39, 40, 41 };
static const unsigned int bxt_north_uart1_pins[] = { 42, 43, 44, 45 };
static const unsigned int bxt_north_uart2_pins[] = { 46, 47, 48, 49 };
static const unsigned int bxt_north_uart0b_pins[] = { 50, 51, 52, 53 };
static const unsigned int bxt_north_uart1b_pins[] = { 54, 55, 56, 57 };
static const unsigned int bxt_north_uart2b_pins[] = { 58, 59, 60, 61 };
static const unsigned int bxt_north_uart3_pins[] = { 58, 59, 60, 61 };
static const struct intel_pingroup bxt_north_groups[] = {
PIN_GROUP("pwm0_grp", bxt_north_pwm0_pins, 1),
@ -260,12 +260,12 @@ static const struct pinctrl_pin_desc bxt_northwest_pins[] = {
PINCTRL_PIN(71, "GP_SSP_2_TXD"),
};
static const unsigned bxt_northwest_ssp0_pins[] = { 53, 54, 55, 56, 57, 58 };
static const unsigned bxt_northwest_ssp1_pins[] = {
static const unsigned int bxt_northwest_ssp0_pins[] = { 53, 54, 55, 56, 57, 58 };
static const unsigned int bxt_northwest_ssp1_pins[] = {
59, 60, 61, 62, 63, 64, 65
};
static const unsigned bxt_northwest_ssp2_pins[] = { 66, 67, 68, 69, 70, 71 };
static const unsigned bxt_northwest_uart3_pins[] = { 67, 68, 69, 70 };
static const unsigned int bxt_northwest_ssp2_pins[] = { 66, 67, 68, 69, 70, 71 };
static const unsigned int bxt_northwest_uart3_pins[] = { 67, 68, 69, 70 };
static const struct intel_pingroup bxt_northwest_groups[] = {
PIN_GROUP("ssp0_grp", bxt_northwest_ssp0_pins, 1),
@ -347,17 +347,17 @@ static const struct pinctrl_pin_desc bxt_west_pins[] = {
PINCTRL_PIN(41, "OSC_CLK_OUT_3"),
};
static const unsigned bxt_west_i2c0_pins[] = { 0, 1 };
static const unsigned bxt_west_i2c1_pins[] = { 2, 3 };
static const unsigned bxt_west_i2c2_pins[] = { 4, 5 };
static const unsigned bxt_west_i2c3_pins[] = { 6, 7 };
static const unsigned bxt_west_i2c4_pins[] = { 8, 9 };
static const unsigned bxt_west_i2c5_pins[] = { 10, 11 };
static const unsigned bxt_west_i2c6_pins[] = { 12, 13 };
static const unsigned bxt_west_i2c7_pins[] = { 14, 15 };
static const unsigned bxt_west_i2c5b_pins[] = { 16, 17 };
static const unsigned bxt_west_i2c6b_pins[] = { 18, 19 };
static const unsigned bxt_west_i2c7b_pins[] = { 20, 21 };
static const unsigned int bxt_west_i2c0_pins[] = { 0, 1 };
static const unsigned int bxt_west_i2c1_pins[] = { 2, 3 };
static const unsigned int bxt_west_i2c2_pins[] = { 4, 5 };
static const unsigned int bxt_west_i2c3_pins[] = { 6, 7 };
static const unsigned int bxt_west_i2c4_pins[] = { 8, 9 };
static const unsigned int bxt_west_i2c5_pins[] = { 10, 11 };
static const unsigned int bxt_west_i2c6_pins[] = { 12, 13 };
static const unsigned int bxt_west_i2c7_pins[] = { 14, 15 };
static const unsigned int bxt_west_i2c5b_pins[] = { 16, 17 };
static const unsigned int bxt_west_i2c6b_pins[] = { 18, 19 };
static const unsigned int bxt_west_i2c7b_pins[] = { 20, 21 };
static const struct intel_pingroup bxt_west_groups[] = {
PIN_GROUP("i2c0_grp", bxt_west_i2c0_pins, 1),
@ -443,13 +443,13 @@ static const struct pinctrl_pin_desc bxt_southwest_pins[] = {
PINCTRL_PIN(30, "SDCARD_LVL_WP"),
};
static const unsigned bxt_southwest_emmc0_pins[] = {
static const unsigned int bxt_southwest_emmc0_pins[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 26,
};
static const unsigned bxt_southwest_sdio_pins[] = {
static const unsigned int bxt_southwest_sdio_pins[] = {
10, 11, 12, 13, 14, 15, 27,
};
static const unsigned bxt_southwest_sdcard_pins[] = {
static const unsigned int bxt_southwest_sdcard_pins[] = {
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30,
};
@ -611,13 +611,13 @@ static const struct pinctrl_pin_desc apl_north_pins[] = {
PINCTRL_PIN(77, "SVID0_CLK"),
};
static const unsigned apl_north_pwm0_pins[] = { 34 };
static const unsigned apl_north_pwm1_pins[] = { 35 };
static const unsigned apl_north_pwm2_pins[] = { 36 };
static const unsigned apl_north_pwm3_pins[] = { 37 };
static const unsigned apl_north_uart0_pins[] = { 38, 39, 40, 41 };
static const unsigned apl_north_uart1_pins[] = { 42, 43, 44, 45 };
static const unsigned apl_north_uart2_pins[] = { 46, 47, 48, 49 };
static const unsigned int apl_north_pwm0_pins[] = { 34 };
static const unsigned int apl_north_pwm1_pins[] = { 35 };
static const unsigned int apl_north_pwm2_pins[] = { 36 };
static const unsigned int apl_north_pwm3_pins[] = { 37 };
static const unsigned int apl_north_uart0_pins[] = { 38, 39, 40, 41 };
static const unsigned int apl_north_uart1_pins[] = { 42, 43, 44, 45 };
static const unsigned int apl_north_uart2_pins[] = { 46, 47, 48, 49 };
static const struct intel_pingroup apl_north_groups[] = {
PIN_GROUP("pwm0_grp", apl_north_pwm0_pins, 1),
@ -743,10 +743,10 @@ static const struct pinctrl_pin_desc apl_northwest_pins[] = {
PINCTRL_PIN(76, "GP_SSP_2_TXD"),
};
static const unsigned apl_northwest_ssp0_pins[] = { 61, 62, 63, 64, 65 };
static const unsigned apl_northwest_ssp1_pins[] = { 66, 67, 68, 69, 70 };
static const unsigned apl_northwest_ssp2_pins[] = { 71, 72, 73, 74, 75, 76 };
static const unsigned apl_northwest_uart3_pins[] = { 67, 68, 69, 70 };
static const unsigned int apl_northwest_ssp0_pins[] = { 61, 62, 63, 64, 65 };
static const unsigned int apl_northwest_ssp1_pins[] = { 66, 67, 68, 69, 70 };
static const unsigned int apl_northwest_ssp2_pins[] = { 71, 72, 73, 74, 75, 76 };
static const unsigned int apl_northwest_uart3_pins[] = { 67, 68, 69, 70 };
static const struct intel_pingroup apl_northwest_groups[] = {
PIN_GROUP("ssp0_grp", apl_northwest_ssp0_pins, 1),
@ -833,15 +833,15 @@ static const struct pinctrl_pin_desc apl_west_pins[] = {
PINCTRL_PIN(46, "SUSPWRDNACK"),
};
static const unsigned apl_west_i2c0_pins[] = { 0, 1 };
static const unsigned apl_west_i2c1_pins[] = { 2, 3 };
static const unsigned apl_west_i2c2_pins[] = { 4, 5 };
static const unsigned apl_west_i2c3_pins[] = { 6, 7 };
static const unsigned apl_west_i2c4_pins[] = { 8, 9 };
static const unsigned apl_west_i2c5_pins[] = { 10, 11 };
static const unsigned apl_west_i2c6_pins[] = { 12, 13 };
static const unsigned apl_west_i2c7_pins[] = { 14, 15 };
static const unsigned apl_west_uart2_pins[] = { 20, 21, 22, 34 };
static const unsigned int apl_west_i2c0_pins[] = { 0, 1 };
static const unsigned int apl_west_i2c1_pins[] = { 2, 3 };
static const unsigned int apl_west_i2c2_pins[] = { 4, 5 };
static const unsigned int apl_west_i2c3_pins[] = { 6, 7 };
static const unsigned int apl_west_i2c4_pins[] = { 8, 9 };
static const unsigned int apl_west_i2c5_pins[] = { 10, 11 };
static const unsigned int apl_west_i2c6_pins[] = { 12, 13 };
static const unsigned int apl_west_i2c7_pins[] = { 14, 15 };
static const unsigned int apl_west_uart2_pins[] = { 20, 21, 22, 34 };
static const struct intel_pingroup apl_west_groups[] = {
PIN_GROUP("i2c0_grp", apl_west_i2c0_pins, 1),
@ -939,16 +939,16 @@ static const struct pinctrl_pin_desc apl_southwest_pins[] = {
PINCTRL_PIN(42, "LPC_FRAMEB"),
};
static const unsigned apl_southwest_emmc0_pins[] = {
static const unsigned int apl_southwest_emmc0_pins[] = {
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 29,
};
static const unsigned apl_southwest_sdio_pins[] = {
static const unsigned int apl_southwest_sdio_pins[] = {
14, 15, 16, 17, 18, 19, 30,
};
static const unsigned apl_southwest_sdcard_pins[] = {
static const unsigned int apl_southwest_sdcard_pins[] = {
20, 21, 22, 23, 24, 25, 26, 27, 28,
};
static const unsigned apl_southwest_i2c7_pins[] = { 32, 33 };
static const unsigned int apl_southwest_i2c7_pins[] = { 32, 33 };
static const struct intel_pingroup apl_southwest_groups[] = {
PIN_GROUP("emmc0_grp", apl_southwest_emmc0_pins, 1),
@ -1008,50 +1008,10 @@ static const struct platform_device_id bxt_pinctrl_platform_ids[] = {
static int bxt_pinctrl_probe(struct platform_device *pdev)
{
const struct intel_pinctrl_soc_data *soc_data = NULL;
const struct intel_pinctrl_soc_data **soc_table;
struct acpi_device *adev;
int i;
adev = ACPI_COMPANION(&pdev->dev);
if (adev) {
const struct acpi_device_id *id;
id = acpi_match_device(bxt_pinctrl_acpi_match, &pdev->dev);
if (!id)
return -ENODEV;
soc_table = (const struct intel_pinctrl_soc_data **)
id->driver_data;
for (i = 0; soc_table[i]; i++) {
if (!strcmp(adev->pnp.unique_id, soc_table[i]->uid)) {
soc_data = soc_table[i];
break;
}
}
} else {
const struct platform_device_id *pid;
pid = platform_get_device_id(pdev);
if (!pid)
return -ENODEV;
soc_table = (const struct intel_pinctrl_soc_data **)
pid->driver_data;
soc_data = soc_table[pdev->id];
}
if (!soc_data)
return -ENODEV;
return intel_pinctrl_probe(pdev, soc_data);
return intel_pinctrl_probe_by_uid(pdev);
}
static const struct dev_pm_ops bxt_pinctrl_pm_ops = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
intel_pinctrl_resume)
};
static INTEL_PINCTRL_PM_OPS(bxt_pinctrl_pm_ops);
static struct platform_driver bxt_pinctrl_driver = {
.probe = bxt_pinctrl_probe,

View File

@ -7,10 +7,10 @@
* Mika Westerberg <mika.westerberg@linux.intel.com>
*/
#include <linux/acpi.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-intel.h"
@ -835,21 +835,10 @@ MODULE_DEVICE_TABLE(acpi, cnl_pinctrl_acpi_match);
static int cnl_pinctrl_probe(struct platform_device *pdev)
{
const struct intel_pinctrl_soc_data *soc_data;
const struct acpi_device_id *id;
id = acpi_match_device(cnl_pinctrl_acpi_match, &pdev->dev);
if (!id || !id->driver_data)
return -ENODEV;
soc_data = (const struct intel_pinctrl_soc_data *)id->driver_data;
return intel_pinctrl_probe(pdev, soc_data);
return intel_pinctrl_probe_by_hid(pdev);
}
static const struct dev_pm_ops cnl_pinctrl_pm_ops = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
intel_pinctrl_resume)
};
static INTEL_PINCTRL_PM_OPS(cnl_pinctrl_pm_ops);
static struct platform_driver cnl_pinctrl_driver = {
.probe = cnl_pinctrl_probe,

View File

@ -9,7 +9,7 @@
#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-intel.h"
@ -335,10 +335,7 @@ static int cdf_pinctrl_probe(struct platform_device *pdev)
return intel_pinctrl_probe(pdev, &cdf_soc_data);
}
static const struct dev_pm_ops cdf_pinctrl_pm_ops = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
intel_pinctrl_resume)
};
static INTEL_PINCTRL_PM_OPS(cdf_pinctrl_pm_ops);
static const struct acpi_device_id cdf_pinctrl_acpi_match[] = {
{ "INTC3001" },

View File

@ -10,19 +10,20 @@
* Alan Cox <alan@linux.intel.com>
*/
#include <linux/acpi.h>
#include <linux/dmi.h>
#include <linux/gpio/driver.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/acpi.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/platform_device.h>
#include "pinctrl-intel.h"
#define CHV_INTSTAT 0x300
#define CHV_INTMASK 0x380
@ -73,7 +74,7 @@
* @invert_oe: Invert OE for this pin
*/
struct chv_alternate_function {
unsigned pin;
unsigned int pin;
u8 mode;
bool invert_oe;
};
@ -90,33 +91,21 @@ struct chv_alternate_function {
*/
struct chv_pingroup {
const char *name;
const unsigned *pins;
const unsigned int *pins;
size_t npins;
struct chv_alternate_function altfunc;
const struct chv_alternate_function *overrides;
size_t noverrides;
};
/**
* struct chv_function - A CHV pinmux function
* @name: Name of the function
* @groups: An array of groups for this function
* @ngroups: Number of groups in @groups
*/
struct chv_function {
const char *name;
const char * const *groups;
size_t ngroups;
};
/**
* struct chv_gpio_pinrange - A range of pins that can be used as GPIOs
* @base: Start pin number
* @npins: Number of pins in this range
*/
struct chv_gpio_pinrange {
unsigned base;
unsigned npins;
unsigned int base;
unsigned int npins;
};
/**
@ -131,6 +120,7 @@ struct chv_gpio_pinrange {
* @gpio_ranges: An array of GPIO ranges in this community
* @ngpio_ranges: Number of GPIO ranges
* @nirqs: Total number of IRQs this community can generate
* @acpi_space_id: An address space ID for ACPI OpRegion handler
*/
struct chv_community {
const char *uid;
@ -138,7 +128,7 @@ struct chv_community {
size_t npins;
const struct chv_pingroup *groups;
size_t ngroups;
const struct chv_function *functions;
const struct intel_function *functions;
size_t nfunctions;
const struct chv_gpio_pinrange *gpio_ranges;
size_t ngpio_ranges;
@ -161,6 +151,8 @@ struct chv_pin_context {
* @intr_lines: Stores mapping between 16 HW interrupt wires and GPIO
* offset (in GPIO number space)
* @community: Community this pinctrl instance represents
* @saved_intmask: Interrupt mask saved for system sleep
* @saved_pin_context: Pointer to a context of the pins saved for system sleep
*
* The first group in @groups is expected to contain all pins that can be
* used as GPIOs.
@ -184,7 +176,7 @@ struct chv_pinctrl {
.invert_oe = (i), \
}
#define PIN_GROUP(n, p, m, i) \
#define PIN_GROUP_WITH_ALT(n, p, m, i) \
{ \
.name = (n), \
.pins = (p), \
@ -204,13 +196,6 @@ struct chv_pinctrl {
.noverrides = ARRAY_SIZE((o)), \
}
#define FUNCTION(n, g) \
{ \
.name = (n), \
.groups = (g), \
.ngroups = ARRAY_SIZE((g)), \
}
#define GPIO_PINRANGE(start, end) \
{ \
.base = (start), \
@ -282,7 +267,6 @@ static const struct pinctrl_pin_desc southwest_pins[] = {
PINCTRL_PIN(97, "GP_SSP_2_TXD"),
};
static const unsigned southwest_fspi_pins[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
static const unsigned southwest_uart0_pins[] = { 16, 20 };
static const unsigned southwest_uart1_pins[] = { 15, 16, 18, 20 };
static const unsigned southwest_uart2_pins[] = { 17, 19, 21, 22 };
@ -298,7 +282,6 @@ static const unsigned southwest_i2c4_pins[] = { 46, 50 };
static const unsigned southwest_i2c5_pins[] = { 45, 48 };
static const unsigned southwest_i2c6_pins[] = { 47, 51 };
static const unsigned southwest_i2c_nfc_pins[] = { 49, 52 };
static const unsigned southwest_smbus_pins[] = { 79, 81, 82 };
static const unsigned southwest_spi3_pins[] = { 76, 79, 80, 81, 82 };
/* LPE I2S TXD pins need to have invert_oe set */
@ -318,18 +301,18 @@ static const struct chv_alternate_function southwest_spi3_altfuncs[] = {
};
static const struct chv_pingroup southwest_groups[] = {
PIN_GROUP("uart0_grp", southwest_uart0_pins, 2, false),
PIN_GROUP("uart1_grp", southwest_uart1_pins, 1, false),
PIN_GROUP("uart2_grp", southwest_uart2_pins, 1, false),
PIN_GROUP("hda_grp", southwest_hda_pins, 2, false),
PIN_GROUP("i2c0_grp", southwest_i2c0_pins, 1, true),
PIN_GROUP("i2c1_grp", southwest_i2c1_pins, 1, true),
PIN_GROUP("i2c2_grp", southwest_i2c2_pins, 1, true),
PIN_GROUP("i2c3_grp", southwest_i2c3_pins, 1, true),
PIN_GROUP("i2c4_grp", southwest_i2c4_pins, 1, true),
PIN_GROUP("i2c5_grp", southwest_i2c5_pins, 1, true),
PIN_GROUP("i2c6_grp", southwest_i2c6_pins, 1, true),
PIN_GROUP("i2c_nfc_grp", southwest_i2c_nfc_pins, 2, true),
PIN_GROUP_WITH_ALT("uart0_grp", southwest_uart0_pins, 2, false),
PIN_GROUP_WITH_ALT("uart1_grp", southwest_uart1_pins, 1, false),
PIN_GROUP_WITH_ALT("uart2_grp", southwest_uart2_pins, 1, false),
PIN_GROUP_WITH_ALT("hda_grp", southwest_hda_pins, 2, false),
PIN_GROUP_WITH_ALT("i2c0_grp", southwest_i2c0_pins, 1, true),
PIN_GROUP_WITH_ALT("i2c1_grp", southwest_i2c1_pins, 1, true),
PIN_GROUP_WITH_ALT("i2c2_grp", southwest_i2c2_pins, 1, true),
PIN_GROUP_WITH_ALT("i2c3_grp", southwest_i2c3_pins, 1, true),
PIN_GROUP_WITH_ALT("i2c4_grp", southwest_i2c4_pins, 1, true),
PIN_GROUP_WITH_ALT("i2c5_grp", southwest_i2c5_pins, 1, true),
PIN_GROUP_WITH_ALT("i2c6_grp", southwest_i2c6_pins, 1, true),
PIN_GROUP_WITH_ALT("i2c_nfc_grp", southwest_i2c_nfc_pins, 2, true),
PIN_GROUP_WITH_OVERRIDE("lpe_grp", southwest_lpe_pins, 1, false,
southwest_lpe_altfuncs),
@ -356,7 +339,7 @@ static const char * const southwest_spi3_groups[] = { "spi3_grp" };
* Only do pinmuxing for certain LPSS devices for now. Rest of the pins are
* enabled only as GPIOs.
*/
static const struct chv_function southwest_functions[] = {
static const struct intel_function southwest_functions[] = {
FUNCTION("uart0", southwest_uart0_groups),
FUNCTION("uart1", southwest_uart1_groups),
FUNCTION("uart2", southwest_uart2_groups),
@ -610,13 +593,13 @@ static const unsigned southeast_spi1_pins[] = { 60, 61, 62, 64, 66 };
static const unsigned southeast_spi2_pins[] = { 2, 3, 4, 6, 7 };
static const struct chv_pingroup southeast_groups[] = {
PIN_GROUP("pwm0_grp", southeast_pwm0_pins, 1, false),
PIN_GROUP("pwm1_grp", southeast_pwm1_pins, 1, false),
PIN_GROUP("sdmmc1_grp", southeast_sdmmc1_pins, 1, false),
PIN_GROUP("sdmmc2_grp", southeast_sdmmc2_pins, 1, false),
PIN_GROUP("sdmmc3_grp", southeast_sdmmc3_pins, 1, false),
PIN_GROUP("spi1_grp", southeast_spi1_pins, 1, false),
PIN_GROUP("spi2_grp", southeast_spi2_pins, 4, false),
PIN_GROUP_WITH_ALT("pwm0_grp", southeast_pwm0_pins, 1, false),
PIN_GROUP_WITH_ALT("pwm1_grp", southeast_pwm1_pins, 1, false),
PIN_GROUP_WITH_ALT("sdmmc1_grp", southeast_sdmmc1_pins, 1, false),
PIN_GROUP_WITH_ALT("sdmmc2_grp", southeast_sdmmc2_pins, 1, false),
PIN_GROUP_WITH_ALT("sdmmc3_grp", southeast_sdmmc3_pins, 1, false),
PIN_GROUP_WITH_ALT("spi1_grp", southeast_spi1_pins, 1, false),
PIN_GROUP_WITH_ALT("spi2_grp", southeast_spi2_pins, 4, false),
};
static const char * const southeast_pwm0_groups[] = { "pwm0_grp" };
@ -627,7 +610,7 @@ static const char * const southeast_sdmmc3_groups[] = { "sdmmc3_grp" };
static const char * const southeast_spi1_groups[] = { "spi1_grp" };
static const char * const southeast_spi2_groups[] = { "spi2_grp" };
static const struct chv_function southeast_functions[] = {
static const struct intel_function southeast_functions[] = {
FUNCTION("pwm0", southeast_pwm0_groups),
FUNCTION("pwm1", southeast_pwm1_groups),
FUNCTION("sdmmc1", southeast_sdmmc1_groups),
@ -678,11 +661,11 @@ static const struct chv_community *chv_communities[] = {
*/
static DEFINE_RAW_SPINLOCK(chv_lock);
static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned offset,
unsigned reg)
static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned int offset,
unsigned int reg)
{
unsigned family_no = offset / MAX_FAMILY_PAD_GPIO_NO;
unsigned pad_no = offset % MAX_FAMILY_PAD_GPIO_NO;
unsigned int family_no = offset / MAX_FAMILY_PAD_GPIO_NO;
unsigned int pad_no = offset % MAX_FAMILY_PAD_GPIO_NO;
offset = FAMILY_PAD_REGS_OFF + FAMILY_PAD_REGS_SIZE * family_no +
GPIO_REGS_SIZE * pad_no;
@ -698,7 +681,7 @@ static void chv_writel(u32 value, void __iomem *reg)
}
/* When Pad Cfg is locked, driver can only change GPIOTXState or GPIORXState */
static bool chv_pad_locked(struct chv_pinctrl *pctrl, unsigned offset)
static bool chv_pad_locked(struct chv_pinctrl *pctrl, unsigned int offset)
{
void __iomem *reg;
@ -714,15 +697,15 @@ static int chv_get_groups_count(struct pinctrl_dev *pctldev)
}
static const char *chv_get_group_name(struct pinctrl_dev *pctldev,
unsigned group)
unsigned int group)
{
struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
return pctrl->community->groups[group].name;
}
static int chv_get_group_pins(struct pinctrl_dev *pctldev, unsigned group,
const unsigned **pins, unsigned *npins)
static int chv_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group,
const unsigned int **pins, unsigned int *npins)
{
struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
@ -732,7 +715,7 @@ static int chv_get_group_pins(struct pinctrl_dev *pctldev, unsigned group,
}
static void chv_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
unsigned offset)
unsigned int offset)
{
struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
unsigned long flags;
@ -779,7 +762,7 @@ static int chv_get_functions_count(struct pinctrl_dev *pctldev)
}
static const char *chv_get_function_name(struct pinctrl_dev *pctldev,
unsigned function)
unsigned int function)
{
struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
@ -787,9 +770,9 @@ static const char *chv_get_function_name(struct pinctrl_dev *pctldev,
}
static int chv_get_function_groups(struct pinctrl_dev *pctldev,
unsigned function,
unsigned int function,
const char * const **groups,
unsigned * const ngroups)
unsigned int * const ngroups)
{
struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
@ -798,8 +781,8 @@ static int chv_get_function_groups(struct pinctrl_dev *pctldev,
return 0;
}
static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function,
unsigned group)
static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev,
unsigned int function, unsigned int group)
{
struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
const struct chv_pingroup *grp;
@ -865,7 +848,7 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function,
static int chv_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset)
unsigned int offset)
{
struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
unsigned long flags;
@ -925,7 +908,7 @@ static int chv_gpio_request_enable(struct pinctrl_dev *pctldev,
static void chv_gpio_disable_free(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset)
unsigned int offset)
{
struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
unsigned long flags;
@ -943,7 +926,7 @@ static void chv_gpio_disable_free(struct pinctrl_dev *pctldev,
static int chv_gpio_set_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset, bool input)
unsigned int offset, bool input)
{
struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
void __iomem *reg = chv_padreg(pctrl, offset, CHV_PADCTRL0);
@ -974,7 +957,7 @@ static const struct pinmux_ops chv_pinmux_ops = {
.gpio_set_direction = chv_gpio_set_direction,
};
static int chv_config_get(struct pinctrl_dev *pctldev, unsigned pin,
static int chv_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *config)
{
struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
@ -1054,7 +1037,7 @@ static int chv_config_get(struct pinctrl_dev *pctldev, unsigned pin,
return 0;
}
static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned pin,
static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned int pin,
enum pin_config_param param, u32 arg)
{
void __iomem *reg = chv_padreg(pctrl, pin, CHV_PADCTRL0);
@ -1141,8 +1124,8 @@ static int chv_config_set_oden(struct chv_pinctrl *pctrl, unsigned int pin,
return 0;
}
static int chv_config_set(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long *configs, unsigned nconfigs)
static int chv_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned int nconfigs)
{
struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param;
@ -1243,7 +1226,7 @@ static struct pinctrl_desc chv_pinctrl_desc = {
.owner = THIS_MODULE,
};
static int chv_gpio_get(struct gpio_chip *chip, unsigned offset)
static int chv_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
struct chv_pinctrl *pctrl = gpiochip_get_data(chip);
unsigned long flags;
@ -1261,7 +1244,7 @@ static int chv_gpio_get(struct gpio_chip *chip, unsigned offset)
return !!(ctrl0 & CHV_PADCTRL0_GPIORXSTATE);
}
static void chv_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
static void chv_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
{
struct chv_pinctrl *pctrl = gpiochip_get_data(chip);
unsigned long flags;
@ -1283,7 +1266,7 @@ static void chv_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
raw_spin_unlock_irqrestore(&chv_lock, flags);
}
static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
{
struct chv_pinctrl *pctrl = gpiochip_get_data(chip);
u32 ctrl0, direction;
@ -1299,12 +1282,12 @@ static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
return direction != CHV_PADCTRL0_GPIOCFG_GPO;
}
static int chv_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
static int chv_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
{
return pinctrl_gpio_direction_input(chip->base + offset);
}
static int chv_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
static int chv_gpio_direction_output(struct gpio_chip *chip, unsigned int offset,
int value)
{
chv_gpio_set(chip, offset, value);
@ -1388,7 +1371,7 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d)
if (irqd_get_trigger_type(d) == IRQ_TYPE_NONE) {
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct chv_pinctrl *pctrl = gpiochip_get_data(gc);
unsigned pin = irqd_to_hwirq(d);
unsigned int pin = irqd_to_hwirq(d);
irq_flow_handler_t handler;
unsigned long flags;
u32 intsel, value;
@ -1415,11 +1398,11 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d)
return 0;
}
static int chv_gpio_irq_type(struct irq_data *d, unsigned type)
static int chv_gpio_irq_type(struct irq_data *d, unsigned int type)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct chv_pinctrl *pctrl = gpiochip_get_data(gc);
unsigned pin = irqd_to_hwirq(d);
unsigned int pin = irqd_to_hwirq(d);
unsigned long flags;
u32 value;

View File

@ -9,7 +9,7 @@
#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-intel.h"
@ -262,10 +262,7 @@ static int dnv_pinctrl_probe(struct platform_device *pdev)
return intel_pinctrl_probe(pdev, &dnv_soc_data);
}
static const struct dev_pm_ops dnv_pinctrl_pm_ops = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
intel_pinctrl_resume)
};
static INTEL_PINCTRL_PM_OPS(dnv_pinctrl_pm_ops);
static const struct acpi_device_id dnv_pinctrl_acpi_match[] = {
{ "INTC3000" },

View File

@ -6,17 +6,17 @@
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
*/
#include <linux/acpi.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-intel.h"
#define GLK_PAD_OWN 0x020
#define GLK_HOSTSW_OWN 0x0b0
#define GLK_PADCFGLOCK 0x080
#define GLK_HOSTSW_OWN 0x0b0
#define GLK_GPI_IE 0x110
#define GLK_COMMUNITY(s, e) \
@ -58,16 +58,16 @@ static const struct pinctrl_pin_desc glk_northwest_pins[] = {
PINCTRL_PIN(23, "GPIO_23"),
PINCTRL_PIN(24, "GPIO_24"),
PINCTRL_PIN(25, "GPIO_25"),
PINCTRL_PIN(26, "GPIO_26"),
PINCTRL_PIN(27, "GPIO_27"),
PINCTRL_PIN(28, "GPIO_28"),
PINCTRL_PIN(29, "GPIO_29"),
PINCTRL_PIN(30, "GPIO_30"),
PINCTRL_PIN(31, "GPIO_31"),
PINCTRL_PIN(32, "GPIO_32"),
PINCTRL_PIN(33, "GPIO_33"),
PINCTRL_PIN(34, "GPIO_34"),
PINCTRL_PIN(35, "GPIO_35"),
PINCTRL_PIN(26, "ISH_GPIO_0"),
PINCTRL_PIN(27, "ISH_GPIO_1"),
PINCTRL_PIN(28, "ISH_GPIO_2"),
PINCTRL_PIN(29, "ISH_GPIO_3"),
PINCTRL_PIN(30, "ISH_GPIO_4"),
PINCTRL_PIN(31, "ISH_GPIO_5"),
PINCTRL_PIN(32, "ISH_GPIO_6"),
PINCTRL_PIN(33, "ISH_GPIO_7"),
PINCTRL_PIN(34, "ISH_GPIO_8"),
PINCTRL_PIN(35, "ISH_GPIO_9"),
PINCTRL_PIN(36, "GPIO_36"),
PINCTRL_PIN(37, "GPIO_37"),
PINCTRL_PIN(38, "GPIO_38"),
@ -195,12 +195,12 @@ static const struct pinctrl_pin_desc glk_north_pins[] = {
PINCTRL_PIN(5, "LPSS_SPI_0_FS1"),
PINCTRL_PIN(6, "LPSS_SPI_0_RXD"),
PINCTRL_PIN(7, "LPSS_SPI_0_TXD"),
PINCTRL_PIN(8, "LPSS_SPI_1_CLK"),
PINCTRL_PIN(9, "LPSS_SPI_1_FS0"),
PINCTRL_PIN(10, "LPSS_SPI_1_FS1"),
PINCTRL_PIN(11, "LPSS_SPI_1_FS2"),
PINCTRL_PIN(12, "LPSS_SPI_1_RXD"),
PINCTRL_PIN(13, "LPSS_SPI_1_TXD"),
PINCTRL_PIN(8, "LPSS_SPI_2_CLK"),
PINCTRL_PIN(9, "LPSS_SPI_2_FS0"),
PINCTRL_PIN(10, "LPSS_SPI_2_FS1"),
PINCTRL_PIN(11, "LPSS_SPI_2_FS2"),
PINCTRL_PIN(12, "LPSS_SPI_2_RXD"),
PINCTRL_PIN(13, "LPSS_SPI_2_TXD"),
PINCTRL_PIN(14, "FST_SPI_CS0_B"),
PINCTRL_PIN(15, "FST_SPI_CS1_B"),
PINCTRL_PIN(16, "FST_SPI_MOSI_IO0"),
@ -215,8 +215,8 @@ static const struct pinctrl_pin_desc glk_north_pins[] = {
PINCTRL_PIN(25, "PMU_SLP_S3_B"),
PINCTRL_PIN(26, "PMU_SLP_S4_B"),
PINCTRL_PIN(27, "SUSPWRDNACK"),
PINCTRL_PIN(28, "EMMC_PWR_EN_B"),
PINCTRL_PIN(29, "PMU_AC_PRESENT"),
PINCTRL_PIN(28, "EMMC_DNX_PWR_EN_B"),
PINCTRL_PIN(29, "GPIO_105"),
PINCTRL_PIN(30, "PMU_BATLOW_B"),
PINCTRL_PIN(31, "PMU_RESETBUTTON_B"),
PINCTRL_PIN(32, "PMU_SUSCLK"),
@ -449,42 +449,15 @@ static const struct intel_pinctrl_soc_data *glk_pinctrl_soc_data[] = {
};
static const struct acpi_device_id glk_pinctrl_acpi_match[] = {
{ "INT3453" },
{ "INT3453", (kernel_ulong_t)glk_pinctrl_soc_data },
{ }
};
MODULE_DEVICE_TABLE(acpi, glk_pinctrl_acpi_match);
static int glk_pinctrl_probe(struct platform_device *pdev)
{
const struct intel_pinctrl_soc_data *soc_data = NULL;
struct acpi_device *adev;
int i;
adev = ACPI_COMPANION(&pdev->dev);
if (!adev)
return -ENODEV;
for (i = 0; glk_pinctrl_soc_data[i]; i++) {
if (!strcmp(adev->pnp.unique_id,
glk_pinctrl_soc_data[i]->uid)) {
soc_data = glk_pinctrl_soc_data[i];
break;
}
}
if (!soc_data)
return -ENODEV;
return intel_pinctrl_probe(pdev, soc_data);
}
static const struct dev_pm_ops glk_pinctrl_pm_ops = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
intel_pinctrl_resume)
};
static INTEL_PINCTRL_PM_OPS(glk_pinctrl_pm_ops);
static struct platform_driver glk_pinctrl_driver = {
.probe = glk_pinctrl_probe,
.probe = intel_pinctrl_probe_by_uid,
.driver = {
.name = "geminilake-pinctrl",
.acpi_match_table = glk_pinctrl_acpi_match,

View File

@ -10,7 +10,7 @@
#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-intel.h"
@ -408,10 +408,7 @@ static int icl_pinctrl_probe(struct platform_device *pdev)
return intel_pinctrl_probe(pdev, &icllp_soc_data);
}
static const struct dev_pm_ops icl_pinctrl_pm_ops = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
intel_pinctrl_resume)
};
static INTEL_PINCTRL_PM_OPS(icl_pinctrl_pm_ops);
static const struct acpi_device_id icl_pinctrl_acpi_match[] = {
{ "INT3455" },

View File

@ -7,11 +7,14 @@
* Mika Westerberg <mika.westerberg@linux.intel.com>
*/
#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/gpio/driver.h>
#include <linux/log2.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
@ -115,7 +118,7 @@ struct intel_pinctrl {
#define padgroup_offset(g, p) ((p) - (g)->base)
static struct intel_community *intel_get_community(struct intel_pinctrl *pctrl,
unsigned pin)
unsigned int pin)
{
struct intel_community *community;
int i;
@ -133,7 +136,7 @@ static struct intel_community *intel_get_community(struct intel_pinctrl *pctrl,
static const struct intel_padgroup *
intel_community_get_padgroup(const struct intel_community *community,
unsigned pin)
unsigned int pin)
{
int i;
@ -147,11 +150,11 @@ intel_community_get_padgroup(const struct intel_community *community,
return NULL;
}
static void __iomem *intel_get_padcfg(struct intel_pinctrl *pctrl, unsigned pin,
unsigned reg)
static void __iomem *intel_get_padcfg(struct intel_pinctrl *pctrl,
unsigned int pin, unsigned int reg)
{
const struct intel_community *community;
unsigned padno;
unsigned int padno;
size_t nregs;
community = intel_get_community(pctrl, pin);
@ -167,11 +170,11 @@ static void __iomem *intel_get_padcfg(struct intel_pinctrl *pctrl, unsigned pin,
return community->pad_regs + reg + padno * nregs * 4;
}
static bool intel_pad_owned_by_host(struct intel_pinctrl *pctrl, unsigned pin)
static bool intel_pad_owned_by_host(struct intel_pinctrl *pctrl, unsigned int pin)
{
const struct intel_community *community;
const struct intel_padgroup *padgrp;
unsigned gpp, offset, gpp_offset;
unsigned int gpp, offset, gpp_offset;
void __iomem *padown;
community = intel_get_community(pctrl, pin);
@ -192,11 +195,11 @@ static bool intel_pad_owned_by_host(struct intel_pinctrl *pctrl, unsigned pin)
return !(readl(padown) & PADOWN_MASK(gpp_offset));
}
static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned pin)
static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned int pin)
{
const struct intel_community *community;
const struct intel_padgroup *padgrp;
unsigned offset, gpp_offset;
unsigned int offset, gpp_offset;
void __iomem *hostown;
community = intel_get_community(pctrl, pin);
@ -216,11 +219,11 @@ static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned pin)
return !(readl(hostown) & BIT(gpp_offset));
}
static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned pin)
static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned int pin)
{
struct intel_community *community;
const struct intel_padgroup *padgrp;
unsigned offset, gpp_offset;
unsigned int offset, gpp_offset;
u32 value;
community = intel_get_community(pctrl, pin);
@ -253,7 +256,7 @@ static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned pin)
return false;
}
static bool intel_pad_usable(struct intel_pinctrl *pctrl, unsigned pin)
static bool intel_pad_usable(struct intel_pinctrl *pctrl, unsigned int pin)
{
return intel_pad_owned_by_host(pctrl, pin) &&
!intel_pad_locked(pctrl, pin);
@ -267,15 +270,15 @@ static int intel_get_groups_count(struct pinctrl_dev *pctldev)
}
static const char *intel_get_group_name(struct pinctrl_dev *pctldev,
unsigned group)
unsigned int group)
{
struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
return pctrl->soc->groups[group].name;
}
static int intel_get_group_pins(struct pinctrl_dev *pctldev, unsigned group,
const unsigned **pins, unsigned *npins)
static int intel_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group,
const unsigned int **pins, unsigned int *npins)
{
struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
@ -285,7 +288,7 @@ static int intel_get_group_pins(struct pinctrl_dev *pctldev, unsigned group,
}
static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
unsigned pin)
unsigned int pin)
{
struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
void __iomem *padcfg;
@ -344,7 +347,7 @@ static int intel_get_functions_count(struct pinctrl_dev *pctldev)
}
static const char *intel_get_function_name(struct pinctrl_dev *pctldev,
unsigned function)
unsigned int function)
{
struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
@ -352,9 +355,9 @@ static const char *intel_get_function_name(struct pinctrl_dev *pctldev,
}
static int intel_get_function_groups(struct pinctrl_dev *pctldev,
unsigned function,
unsigned int function,
const char * const **groups,
unsigned * const ngroups)
unsigned int * const ngroups)
{
struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
@ -363,8 +366,8 @@ static int intel_get_function_groups(struct pinctrl_dev *pctldev,
return 0;
}
static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function,
unsigned group)
static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev,
unsigned int function, unsigned int group)
{
struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
const struct intel_pingroup *grp = &pctrl->soc->groups[group];
@ -436,7 +439,7 @@ static void intel_gpio_set_gpio_mode(void __iomem *padcfg0)
static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned pin)
unsigned int pin)
{
struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
void __iomem *padcfg0;
@ -461,7 +464,7 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
static int intel_gpio_set_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned pin, bool input)
unsigned int pin, bool input)
{
struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
void __iomem *padcfg0;
@ -486,7 +489,7 @@ static const struct pinmux_ops intel_pinmux_ops = {
.gpio_set_direction = intel_gpio_set_direction,
};
static int intel_config_get(struct pinctrl_dev *pctldev, unsigned pin,
static int intel_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *config)
{
struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
@ -575,11 +578,11 @@ static int intel_config_get(struct pinctrl_dev *pctldev, unsigned pin,
return 0;
}
static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned pin,
static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin,
unsigned long config)
{
unsigned param = pinconf_to_config_param(config);
unsigned arg = pinconf_to_config_argument(config);
unsigned int param = pinconf_to_config_param(config);
unsigned int arg = pinconf_to_config_argument(config);
const struct intel_community *community;
void __iomem *padcfg1;
unsigned long flags;
@ -653,8 +656,8 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned pin,
return ret;
}
static int intel_config_set_debounce(struct intel_pinctrl *pctrl, unsigned pin,
unsigned debounce)
static int intel_config_set_debounce(struct intel_pinctrl *pctrl,
unsigned int pin, unsigned int debounce)
{
void __iomem *padcfg0, *padcfg2;
unsigned long flags;
@ -700,8 +703,8 @@ exit_unlock:
return ret;
}
static int intel_config_set(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long *configs, unsigned nconfigs)
static int intel_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned int nconfigs)
{
struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
int i, ret;
@ -751,14 +754,14 @@ static const struct pinctrl_desc intel_pinctrl_desc = {
* intel_gpio_to_pin() - Translate from GPIO offset to pin number
* @pctrl: Pinctrl structure
* @offset: GPIO offset from gpiolib
* @commmunity: Community is filled here if not %NULL
* @community: Community is filled here if not %NULL
* @padgrp: Pad group is filled here if not %NULL
*
* When coming through gpiolib irqchip, the GPIO offset is not
* automatically translated to pinctrl pin number. This function can be
* used to find out the corresponding pinctrl pin.
*/
static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned offset,
static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned int offset,
const struct intel_community **community,
const struct intel_padgroup **padgrp)
{
@ -792,7 +795,7 @@ static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned offset,
return -EINVAL;
}
static int intel_gpio_get(struct gpio_chip *chip, unsigned offset)
static int intel_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
void __iomem *reg;
@ -814,7 +817,8 @@ static int intel_gpio_get(struct gpio_chip *chip, unsigned offset)
return !!(padcfg0 & PADCFG0_GPIORXSTATE);
}
static void intel_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
static void intel_gpio_set(struct gpio_chip *chip, unsigned int offset,
int value)
{
struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
unsigned long flags;
@ -863,12 +867,12 @@ static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
return !!(padcfg0 & PADCFG0_GPIOTXDIS);
}
static int intel_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
static int intel_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
{
return pinctrl_gpio_direction_input(chip->base + offset);
}
static int intel_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
static int intel_gpio_direction_output(struct gpio_chip *chip, unsigned int offset,
int value)
{
intel_gpio_set(chip, offset, value);
@ -897,7 +901,7 @@ static void intel_gpio_irq_ack(struct irq_data *d)
pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp);
if (pin >= 0) {
unsigned gpp, gpp_offset, is_offset;
unsigned int gpp, gpp_offset, is_offset;
gpp = padgrp->reg_num;
gpp_offset = padgroup_offset(padgrp, pin);
@ -919,7 +923,7 @@ static void intel_gpio_irq_enable(struct irq_data *d)
pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp);
if (pin >= 0) {
unsigned gpp, gpp_offset, is_offset;
unsigned int gpp, gpp_offset, is_offset;
unsigned long flags;
u32 value;
@ -948,7 +952,7 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp);
if (pin >= 0) {
unsigned gpp, gpp_offset;
unsigned int gpp, gpp_offset;
unsigned long flags;
void __iomem *reg;
u32 value;
@ -979,11 +983,11 @@ static void intel_gpio_irq_unmask(struct irq_data *d)
intel_gpio_irq_mask_unmask(d, false);
}
static int intel_gpio_irq_type(struct irq_data *d, unsigned type)
static int intel_gpio_irq_type(struct irq_data *d, unsigned int type)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
unsigned pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL);
unsigned int pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL);
unsigned long flags;
void __iomem *reg;
u32 value;
@ -1040,7 +1044,7 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
unsigned pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL);
unsigned int pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL);
if (on)
enable_irq_wake(pctrl->irq);
@ -1135,7 +1139,7 @@ static int intel_gpio_add_pin_ranges(struct intel_pinctrl *pctrl,
static unsigned intel_gpio_ngpio(const struct intel_pinctrl *pctrl)
{
const struct intel_community *community;
unsigned ngpio = 0;
unsigned int ngpio = 0;
int i, j;
for (i = 0; i < pctrl->ncommunities; i++) {
@ -1211,8 +1215,8 @@ static int intel_pinctrl_add_padgroups(struct intel_pinctrl *pctrl,
struct intel_community *community)
{
struct intel_padgroup *gpps;
unsigned npins = community->npins;
unsigned padown_num = 0;
unsigned int npins = community->npins;
unsigned int padown_num = 0;
size_t ngpps, i;
if (community->gpps)
@ -1228,7 +1232,7 @@ static int intel_pinctrl_add_padgroups(struct intel_pinctrl *pctrl,
if (community->gpps) {
gpps[i] = community->gpps[i];
} else {
unsigned gpp_size = community->gpp_size;
unsigned int gpp_size = community->gpp_size;
gpps[i].reg_num = i;
gpps[i].base = community->pin_base + i * gpp_size;
@ -1398,8 +1402,52 @@ int intel_pinctrl_probe(struct platform_device *pdev,
}
EXPORT_SYMBOL_GPL(intel_pinctrl_probe);
int intel_pinctrl_probe_by_hid(struct platform_device *pdev)
{
const struct intel_pinctrl_soc_data *data;
data = device_get_match_data(&pdev->dev);
return intel_pinctrl_probe(pdev, data);
}
EXPORT_SYMBOL_GPL(intel_pinctrl_probe_by_hid);
int intel_pinctrl_probe_by_uid(struct platform_device *pdev)
{
const struct intel_pinctrl_soc_data *data = NULL;
const struct intel_pinctrl_soc_data **table;
struct acpi_device *adev;
unsigned int i;
adev = ACPI_COMPANION(&pdev->dev);
if (adev) {
const void *match = device_get_match_data(&pdev->dev);
table = (const struct intel_pinctrl_soc_data **)match;
for (i = 0; table[i]; i++) {
if (!strcmp(adev->pnp.unique_id, table[i]->uid)) {
data = table[i];
break;
}
}
} else {
const struct platform_device_id *id;
id = platform_get_device_id(pdev);
if (!id)
return -ENODEV;
table = (const struct intel_pinctrl_soc_data **)id->driver_data;
data = table[pdev->id];
}
if (!data)
return -ENODEV;
return intel_pinctrl_probe(pdev, data);
}
EXPORT_SYMBOL_GPL(intel_pinctrl_probe_by_uid);
#ifdef CONFIG_PM_SLEEP
static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned pin)
static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int pin)
{
const struct pin_desc *pd = pin_desc_get(pctrl->pctldev, pin);
@ -1450,7 +1498,7 @@ int intel_pinctrl_suspend(struct device *dev)
for (i = 0; i < pctrl->ncommunities; i++) {
struct intel_community *community = &pctrl->communities[i];
void __iomem *base;
unsigned gpp;
unsigned int gpp;
base = community->regs + community->ie_offset;
for (gpp = 0; gpp < community->ngpps; gpp++)
@ -1468,7 +1516,7 @@ static void intel_gpio_irq_init(struct intel_pinctrl *pctrl)
for (i = 0; i < pctrl->ncommunities; i++) {
const struct intel_community *community;
void __iomem *base;
unsigned gpp;
unsigned int gpp;
community = &pctrl->communities[i];
base = community->regs;
@ -1532,7 +1580,7 @@ int intel_pinctrl_resume(struct device *dev)
for (i = 0; i < pctrl->ncommunities; i++) {
struct intel_community *community = &pctrl->communities[i];
void __iomem *base;
unsigned gpp;
unsigned int gpp;
base = community->regs + community->ie_offset;
for (gpp = 0; gpp < community->ngpps; gpp++) {

View File

@ -10,6 +10,8 @@
#ifndef PINCTRL_INTEL_H
#define PINCTRL_INTEL_H
#include <linux/pm.h>
struct pinctrl_pin_desc;
struct platform_device;
struct device;
@ -25,10 +27,10 @@ struct device;
*/
struct intel_pingroup {
const char *name;
const unsigned *pins;
const unsigned int *pins;
size_t npins;
unsigned short mode;
const unsigned *modes;
const unsigned int *modes;
};
/**
@ -56,11 +58,11 @@ struct intel_function {
* to specify them.
*/
struct intel_padgroup {
unsigned reg_num;
unsigned base;
unsigned size;
unsigned int reg_num;
unsigned int base;
unsigned int size;
int gpio_base;
unsigned padown_num;
unsigned int padown_num;
};
/**
@ -96,17 +98,17 @@ struct intel_padgroup {
* pass custom @gpps and @ngpps instead.
*/
struct intel_community {
unsigned barno;
unsigned padown_offset;
unsigned padcfglock_offset;
unsigned hostown_offset;
unsigned is_offset;
unsigned ie_offset;
unsigned pin_base;
unsigned gpp_size;
unsigned gpp_num_padown_regs;
unsigned int barno;
unsigned int padown_offset;
unsigned int padcfglock_offset;
unsigned int hostown_offset;
unsigned int is_offset;
unsigned int ie_offset;
unsigned int pin_base;
unsigned int gpp_size;
unsigned int gpp_num_padown_regs;
size_t npins;
unsigned features;
unsigned int features;
const struct intel_padgroup *gpps;
size_t ngpps;
/* Reserved for the core driver */
@ -173,9 +175,17 @@ struct intel_pinctrl_soc_data {
int intel_pinctrl_probe(struct platform_device *pdev,
const struct intel_pinctrl_soc_data *soc_data);
int intel_pinctrl_probe_by_hid(struct platform_device *pdev);
int intel_pinctrl_probe_by_uid(struct platform_device *pdev);
#ifdef CONFIG_PM_SLEEP
int intel_pinctrl_suspend(struct device *dev);
int intel_pinctrl_resume(struct device *dev);
#endif
#define INTEL_PINCTRL_PM_OPS(_name) \
const struct dev_pm_ops _name = { \
SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend, intel_pinctrl_resume) \
}
#endif /* PINCTRL_INTEL_H */

View File

@ -9,7 +9,7 @@
#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-intel.h"
@ -313,10 +313,7 @@ static int lbg_pinctrl_probe(struct platform_device *pdev)
return intel_pinctrl_probe(pdev, &lbg_soc_data);
}
static const struct dev_pm_ops lbg_pinctrl_pm_ops = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
intel_pinctrl_resume)
};
static INTEL_PINCTRL_PM_OPS(lbg_pinctrl_pm_ops);
static const struct acpi_device_id lbg_pinctrl_acpi_match[] = {
{ "INT3536" },

View File

@ -476,6 +476,34 @@ static void __iomem *mrfld_get_bufcfg(struct mrfld_pinctrl *mp, unsigned int pin
return family->regs + BUFCFG_OFFSET + bufno * 4;
}
static int mrfld_read_bufcfg(struct mrfld_pinctrl *mp, unsigned int pin, u32 *value)
{
void __iomem *bufcfg;
if (!mrfld_buf_available(mp, pin))
return -EBUSY;
bufcfg = mrfld_get_bufcfg(mp, pin);
*value = readl(bufcfg);
return 0;
}
static void mrfld_update_bufcfg(struct mrfld_pinctrl *mp, unsigned int pin,
u32 bits, u32 mask)
{
void __iomem *bufcfg;
u32 value;
bufcfg = mrfld_get_bufcfg(mp, pin);
value = readl(bufcfg);
value &= ~mask;
value |= bits & mask;
writel(value, bufcfg);
}
static int mrfld_get_groups_count(struct pinctrl_dev *pctldev)
{
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
@ -505,17 +533,15 @@ static void mrfld_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
unsigned int pin)
{
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
void __iomem *bufcfg;
u32 value, mode;
int ret;
if (!mrfld_buf_available(mp, pin)) {
ret = mrfld_read_bufcfg(mp, pin, &value);
if (ret) {
seq_puts(s, "not available");
return;
}
bufcfg = mrfld_get_bufcfg(mp, pin);
value = readl(bufcfg);
mode = (value & BUFCFG_PINMODE_MASK) >> BUFCFG_PINMODE_SHIFT;
if (!mode)
seq_puts(s, "GPIO ");
@ -559,21 +585,6 @@ static int mrfld_get_function_groups(struct pinctrl_dev *pctldev,
return 0;
}
static void mrfld_update_bufcfg(struct mrfld_pinctrl *mp, unsigned int pin,
u32 bits, u32 mask)
{
void __iomem *bufcfg;
u32 value;
bufcfg = mrfld_get_bufcfg(mp, pin);
value = readl(bufcfg);
value &= ~mask;
value |= bits & mask;
writel(value, bufcfg);
}
static int mrfld_pinmux_set_mux(struct pinctrl_dev *pctldev,
unsigned int function,
unsigned int group)
@ -637,11 +648,12 @@ static int mrfld_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
enum pin_config_param param = pinconf_to_config_param(*config);
u32 value, term;
u16 arg = 0;
int ret;
if (!mrfld_buf_available(mp, pin))
ret = mrfld_read_bufcfg(mp, pin, &value);
if (ret)
return -ENOTSUPP;
value = readl(mrfld_get_bufcfg(mp, pin));
term = (value & BUFCFG_PUPD_VAL_MASK) >> BUFCFG_PUPD_VAL_SHIFT;
switch (param) {

View File

@ -7,10 +7,10 @@
* Mika Westerberg <mika.westerberg@linux.intel.com>
*/
#include <linux/acpi.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-intel.h"
@ -593,21 +593,10 @@ MODULE_DEVICE_TABLE(acpi, spt_pinctrl_acpi_match);
static int spt_pinctrl_probe(struct platform_device *pdev)
{
const struct intel_pinctrl_soc_data *soc_data;
const struct acpi_device_id *id;
id = acpi_match_device(spt_pinctrl_acpi_match, &pdev->dev);
if (!id || !id->driver_data)
return -ENODEV;
soc_data = (const struct intel_pinctrl_soc_data *)id->driver_data;
return intel_pinctrl_probe(pdev, soc_data);
return intel_pinctrl_probe_by_hid(pdev);
}
static const struct dev_pm_ops spt_pinctrl_pm_ops = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
intel_pinctrl_resume)
};
static INTEL_PINCTRL_PM_OPS(spt_pinctrl_pm_ops);
static struct platform_driver spt_pinctrl_driver = {
.probe = spt_pinctrl_probe,

View File

@ -3,7 +3,8 @@ menu "MediaTek pinctrl drivers"
config EINT_MTK
bool "MediaTek External Interrupt Support"
depends on PINCTRL_MTK || PINCTRL_MT7622 || COMPILE_TEST
depends on PINCTRL_MTK || PINCTRL_MTK_MOORE || COMPILE_TEST
select GPIOLIB
select IRQ_DOMAIN
config PINCTRL_MTK
@ -15,6 +16,24 @@ config PINCTRL_MTK
select EINT_MTK
select OF_GPIO
config PINCTRL_MTK_MOORE
bool "MediaTek Moore Core that implements generic binding"
depends on OF
select GENERIC_PINCONF
select GENERIC_PINCTRL_GROUPS
select GENERIC_PINMUX_FUNCTIONS
select GPIOLIB
select OF_GPIO
config PINCTRL_MTK_PARIS
bool "MediaTek Paris Core that implements vendor binding"
depends on OF
select PINMUX
select GENERIC_PINCONF
select GPIOLIB
select EINT_MTK
select OF_GPIO
# For ARMv7 SoCs
config PINCTRL_MT2701
bool "Mediatek MT2701 pin control"
@ -23,6 +42,12 @@ config PINCTRL_MT2701
default MACH_MT2701
select PINCTRL_MTK
config PINCTRL_MT7623
bool "Mediatek MT7623 pin control with generic binding"
depends on MACH_MT7623 || COMPILE_TEST
depends on PINCTRL_MTK_MOORE
default y
config PINCTRL_MT8135
bool "Mediatek MT8135 pin control"
depends on MACH_MT8135 || COMPILE_TEST
@ -45,15 +70,18 @@ config PINCTRL_MT2712
default ARM64 && ARCH_MEDIATEK
select PINCTRL_MTK
config PINCTRL_MT7622
bool "MediaTek MT7622 pin control"
config PINCTRL_MT6765
bool "Mediatek MT6765 pin control"
depends on OF
depends on ARM64 || COMPILE_TEST
select GENERIC_PINCONF
select GENERIC_PINCTRL_GROUPS
select GENERIC_PINMUX_FUNCTIONS
select GPIOLIB
select OF_GPIO
default ARM64 && ARCH_MEDIATEK
select PINCTRL_MTK_PARIS
config PINCTRL_MT7622
bool "MediaTek MT7622 pin control"
depends on ARM64 || COMPILE_TEST
depends on PINCTRL_MTK_MOORE
default y
config PINCTRL_MT8173
bool "Mediatek MT8173 pin control"
@ -62,6 +90,13 @@ config PINCTRL_MT8173
default ARM64 && ARCH_MEDIATEK
select PINCTRL_MTK
config PINCTRL_MT8183
bool "Mediatek MT8183 pin control"
depends on OF
depends on ARM64 || COMPILE_TEST
default ARM64 && ARCH_MEDIATEK
select PINCTRL_MTK_PARIS
# For PMIC
config PINCTRL_MT6397
bool "Mediatek MT6397 pin control"

View File

@ -2,12 +2,17 @@
# Core
obj-$(CONFIG_EINT_MTK) += mtk-eint.o
obj-$(CONFIG_PINCTRL_MTK) += pinctrl-mtk-common.o
obj-$(CONFIG_PINCTRL_MTK_MOORE) += pinctrl-moore.o pinctrl-mtk-common-v2.o
obj-$(CONFIG_PINCTRL_MTK_PARIS) += pinctrl-paris.o pinctrl-mtk-common-v2.o
# SoC Drivers
obj-$(CONFIG_PINCTRL_MT2701) += pinctrl-mt2701.o
obj-$(CONFIG_PINCTRL_MT2712) += pinctrl-mt2712.o
obj-$(CONFIG_PINCTRL_MT8135) += pinctrl-mt8135.o
obj-$(CONFIG_PINCTRL_MT8127) += pinctrl-mt8127.o
obj-$(CONFIG_PINCTRL_MT6765) += pinctrl-mt6765.o
obj-$(CONFIG_PINCTRL_MT7622) += pinctrl-mt7622.o
obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o
obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o
obj-$(CONFIG_PINCTRL_MT8183) += pinctrl-mt8183.o
obj-$(CONFIG_PINCTRL_MT6397) += pinctrl-mt6397.o

View File

@ -11,7 +11,7 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/io.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>

View File

@ -92,13 +92,13 @@ static inline int mtk_eint_do_resume(struct mtk_eint *eint)
return -EOPNOTSUPP;
}
int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_n,
static inline int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_n,
unsigned int debounce)
{
return -EOPNOTSUPP;
}
int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
static inline int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
{
return -EOPNOTSUPP;
}

View File

@ -0,0 +1,690 @@
// SPDX-License-Identifier: GPL-2.0
/*
* MediaTek Pinctrl Moore Driver, which implement the generic dt-binding
* pinctrl-bindings.txt for MediaTek SoC.
*
* Copyright (C) 2017-2018 MediaTek Inc.
* Author: Sean Wang <sean.wang@mediatek.com>
*
*/
#include <linux/gpio/driver.h>
#include "pinctrl-moore.h"
#define PINCTRL_PINCTRL_DEV KBUILD_MODNAME
/* Custom pinconf parameters */
#define MTK_PIN_CONFIG_TDSEL (PIN_CONFIG_END + 1)
#define MTK_PIN_CONFIG_RDSEL (PIN_CONFIG_END + 2)
#define MTK_PIN_CONFIG_PU_ADV (PIN_CONFIG_END + 3)
#define MTK_PIN_CONFIG_PD_ADV (PIN_CONFIG_END + 4)
static const struct pinconf_generic_params mtk_custom_bindings[] = {
{"mediatek,tdsel", MTK_PIN_CONFIG_TDSEL, 0},
{"mediatek,rdsel", MTK_PIN_CONFIG_RDSEL, 0},
{"mediatek,pull-up-adv", MTK_PIN_CONFIG_PU_ADV, 1},
{"mediatek,pull-down-adv", MTK_PIN_CONFIG_PD_ADV, 1},
};
#ifdef CONFIG_DEBUG_FS
static const struct pin_config_item mtk_conf_items[] = {
PCONFDUMP(MTK_PIN_CONFIG_TDSEL, "tdsel", NULL, true),
PCONFDUMP(MTK_PIN_CONFIG_RDSEL, "rdsel", NULL, true),
PCONFDUMP(MTK_PIN_CONFIG_PU_ADV, "pu-adv", NULL, true),
PCONFDUMP(MTK_PIN_CONFIG_PD_ADV, "pd-adv", NULL, true),
};
#endif
static int mtk_pinmux_set_mux(struct pinctrl_dev *pctldev,
unsigned int selector, unsigned int group)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
struct function_desc *func;
struct group_desc *grp;
int i;
func = pinmux_generic_get_function(pctldev, selector);
if (!func)
return -EINVAL;
grp = pinctrl_generic_get_group(pctldev, group);
if (!grp)
return -EINVAL;
dev_dbg(pctldev->dev, "enable function %s group %s\n",
func->name, grp->name);
for (i = 0; i < grp->num_pins; i++) {
const struct mtk_pin_desc *desc;
int *pin_modes = grp->data;
int pin = grp->pins[i];
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,
pin_modes[i]);
}
return 0;
}
static int mtk_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int pin)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
const struct mtk_pin_desc *desc;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,
hw->soc->gpio_m);
}
static int mtk_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int pin, bool input)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
const struct mtk_pin_desc *desc;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
/* hardware would take 0 as input direction */
return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !input);
}
static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
unsigned int pin, unsigned long *config)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
u32 param = pinconf_to_config_param(*config);
int val, val2, err, reg, ret = 1;
const struct mtk_pin_desc *desc;
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 (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;
} 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;
break;
case MTK_PIN_CONFIG_PU_ADV:
case MTK_PIN_CONFIG_PD_ADV:
if (hw->soc->adv_pull_get) {
bool pullup;
pullup = param == MTK_PIN_CONFIG_PU_ADV;
err = hw->soc->adv_pull_get(hw, desc, pullup, &ret);
if (err)
return err;
} else {
return -ENOTSUPP;
}
break;
default:
return -ENOTSUPP;
}
*config = pinconf_to_config_packed(param, ret);
return 0;
}
static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned int num_configs)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
const struct mtk_pin_desc *desc;
u32 reg, param, arg;
int cfg, err = 0;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
for (cfg = 0; cfg < num_configs; cfg++) {
param = pinconf_to_config_param(configs[cfg]);
arg = pinconf_to_config_argument(configs[cfg]);
switch (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;
}
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;
}
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;
}
break;
case PIN_CONFIG_OUTPUT_ENABLE:
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
MTK_DISABLE);
if (err)
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);
}
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;
break;
case PIN_CONFIG_OUTPUT:
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
MTK_OUTPUT);
if (err)
goto err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO,
arg);
if (err)
goto err;
break;
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);
if (err)
goto err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
!!(arg & 2));
if (err)
goto err;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
if (hw->soc->drive_set) {
err = hw->soc->drive_set(hw, desc, arg);
if (err)
return err;
} 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:
if (hw->soc->adv_pull_set) {
bool pullup;
pullup = param == MTK_PIN_CONFIG_PU_ADV;
err = hw->soc->adv_pull_set(hw, desc, pullup,
arg);
if (err)
return err;
} else {
return -ENOTSUPP;
}
break;
default:
err = -ENOTSUPP;
}
}
err:
return err;
}
static int mtk_pinconf_group_get(struct pinctrl_dev *pctldev,
unsigned int group, unsigned long *config)
{
const unsigned int *pins;
unsigned int i, npins, old = 0;
int ret;
ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
if (ret)
return ret;
for (i = 0; i < npins; i++) {
if (mtk_pinconf_get(pctldev, pins[i], config))
return -ENOTSUPP;
/* configs do not match between two pins */
if (i && old != *config)
return -ENOTSUPP;
old = *config;
}
return 0;
}
static int mtk_pinconf_group_set(struct pinctrl_dev *pctldev,
unsigned int group, unsigned long *configs,
unsigned int num_configs)
{
const unsigned int *pins;
unsigned int i, npins;
int ret;
ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
if (ret)
return ret;
for (i = 0; i < npins; i++) {
ret = mtk_pinconf_set(pctldev, pins[i], configs, num_configs);
if (ret)
return ret;
}
return 0;
}
static const struct pinctrl_ops mtk_pctlops = {
.get_groups_count = pinctrl_generic_get_group_count,
.get_group_name = pinctrl_generic_get_group_name,
.get_group_pins = pinctrl_generic_get_group_pins,
.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
.dt_free_map = pinconf_generic_dt_free_map,
};
static const struct pinmux_ops mtk_pmxops = {
.get_functions_count = pinmux_generic_get_function_count,
.get_function_name = pinmux_generic_get_function_name,
.get_function_groups = pinmux_generic_get_function_groups,
.set_mux = mtk_pinmux_set_mux,
.gpio_request_enable = mtk_pinmux_gpio_request_enable,
.gpio_set_direction = mtk_pinmux_gpio_set_direction,
.strict = true,
};
static const struct pinconf_ops mtk_confops = {
.is_generic = true,
.pin_config_get = mtk_pinconf_get,
.pin_config_set = mtk_pinconf_set,
.pin_config_group_get = mtk_pinconf_group_get,
.pin_config_group_set = mtk_pinconf_group_set,
.pin_config_config_dbg_show = pinconf_generic_dump_config,
};
static struct pinctrl_desc mtk_desc = {
.name = PINCTRL_PINCTRL_DEV,
.pctlops = &mtk_pctlops,
.pmxops = &mtk_pmxops,
.confops = &mtk_confops,
.owner = THIS_MODULE,
};
static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)
{
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
const struct mtk_pin_desc *desc;
int value, err;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
if (err)
return err;
return !!value;
}
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;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
}
static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
{
return pinctrl_gpio_direction_input(chip->base + gpio);
}
static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,
int value)
{
mtk_gpio_set(chip, gpio, value);
return pinctrl_gpio_direction_output(chip->base + gpio);
}
static int mtk_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
{
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
const struct mtk_pin_desc *desc;
if (!hw->eint)
return -ENOTSUPP;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[offset];
if (desc->eint.eint_n == (u16)EINT_NA)
return -ENOTSUPP;
return mtk_eint_find_irq(hw->eint, desc->eint.eint_n);
}
static int mtk_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
unsigned long config)
{
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
const struct mtk_pin_desc *desc;
u32 debounce;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[offset];
if (!hw->eint ||
pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE ||
desc->eint.eint_n == (u16)EINT_NA)
return -ENOTSUPP;
debounce = pinconf_to_config_argument(config);
return mtk_eint_set_debounce(hw->eint, desc->eint.eint_n, debounce);
}
static int mtk_build_gpiochip(struct mtk_pinctrl *hw, struct device_node *np)
{
struct gpio_chip *chip = &hw->chip;
int ret;
chip->label = PINCTRL_PINCTRL_DEV;
chip->parent = hw->dev;
chip->request = gpiochip_generic_request;
chip->free = gpiochip_generic_free;
chip->direction_input = mtk_gpio_direction_input;
chip->direction_output = mtk_gpio_direction_output;
chip->get = mtk_gpio_get;
chip->set = mtk_gpio_set;
chip->to_irq = mtk_gpio_to_irq,
chip->set_config = mtk_gpio_set_config,
chip->base = -1;
chip->ngpio = hw->soc->npins;
chip->of_node = np;
chip->of_gpio_n_cells = 2;
ret = gpiochip_add_data(chip, hw);
if (ret < 0)
return ret;
/* Just for backward compatible for these old pinctrl nodes without
* "gpio-ranges" property. Otherwise, called directly from a
* DeviceTree-supported pinctrl driver is DEPRECATED.
* Please see Section 2.1 of
* Documentation/devicetree/bindings/gpio/gpio.txt on how to
* bind pinctrl and gpio drivers via the "gpio-ranges" property.
*/
if (!of_find_property(np, "gpio-ranges", NULL)) {
ret = gpiochip_add_pin_range(chip, dev_name(hw->dev), 0, 0,
chip->ngpio);
if (ret < 0) {
gpiochip_remove(chip);
return ret;
}
}
return 0;
}
static int mtk_build_groups(struct mtk_pinctrl *hw)
{
int err, i;
for (i = 0; i < hw->soc->ngrps; i++) {
const struct group_desc *group = hw->soc->grps + i;
err = pinctrl_generic_add_group(hw->pctrl, group->name,
group->pins, group->num_pins,
group->data);
if (err < 0) {
dev_err(hw->dev, "Failed to register group %s\n",
group->name);
return err;
}
}
return 0;
}
static int mtk_build_functions(struct mtk_pinctrl *hw)
{
int i, err;
for (i = 0; i < hw->soc->nfuncs ; i++) {
const struct function_desc *func = hw->soc->funcs + i;
err = pinmux_generic_add_function(hw->pctrl, func->name,
func->group_names,
func->num_group_names,
func->data);
if (err < 0) {
dev_err(hw->dev, "Failed to register function %s\n",
func->name);
return err;
}
}
return 0;
}
int mtk_moore_pinctrl_probe(struct platform_device *pdev,
const struct mtk_pin_soc *soc)
{
struct pinctrl_pin_desc *pins;
struct resource *res;
struct mtk_pinctrl *hw;
int err, i;
hw = devm_kzalloc(&pdev->dev, sizeof(*hw), GFP_KERNEL);
if (!hw)
return -ENOMEM;
hw->soc = soc;
hw->dev = &pdev->dev;
if (!hw->soc->nbase_names) {
dev_err(&pdev->dev,
"SoC should be assigned at least one register base\n");
return -EINVAL;
}
hw->base = devm_kmalloc_array(&pdev->dev, hw->soc->nbase_names,
sizeof(*hw->base), GFP_KERNEL);
if (!hw->base)
return -ENOMEM;
for (i = 0; i < hw->soc->nbase_names; i++) {
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
hw->soc->base_names[i]);
if (!res) {
dev_err(&pdev->dev, "missing IO resource\n");
return -ENXIO;
}
hw->base[i] = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(hw->base[i]))
return PTR_ERR(hw->base[i]);
}
hw->nbase = hw->soc->nbase_names;
/* Copy from internal struct mtk_pin_desc to register to the core */
pins = devm_kmalloc_array(&pdev->dev, hw->soc->npins, sizeof(*pins),
GFP_KERNEL);
if (!pins)
return -ENOMEM;
for (i = 0; i < hw->soc->npins; i++) {
pins[i].number = hw->soc->pins[i].number;
pins[i].name = hw->soc->pins[i].name;
}
/* Setup pins descriptions per SoC types */
mtk_desc.pins = (const struct pinctrl_pin_desc *)pins;
mtk_desc.npins = hw->soc->npins;
mtk_desc.num_custom_params = ARRAY_SIZE(mtk_custom_bindings);
mtk_desc.custom_params = mtk_custom_bindings;
#ifdef CONFIG_DEBUG_FS
mtk_desc.custom_conf_items = mtk_conf_items;
#endif
err = devm_pinctrl_register_and_init(&pdev->dev, &mtk_desc, hw,
&hw->pctrl);
if (err)
return err;
/* Setup groups descriptions per SoC types */
err = mtk_build_groups(hw);
if (err) {
dev_err(&pdev->dev, "Failed to build groups\n");
return err;
}
/* Setup functions descriptions per SoC types */
err = mtk_build_functions(hw);
if (err) {
dev_err(&pdev->dev, "Failed to build functions\n");
return err;
}
/* For able to make pinctrl_claim_hogs, we must not enable pinctrl
* until all groups and functions are being added one.
*/
err = pinctrl_enable(hw->pctrl);
if (err)
return err;
err = mtk_build_eint(hw, pdev);
if (err)
dev_warn(&pdev->dev,
"Failed to add EINT, but pinctrl still can work\n");
/* Build gpiochip should be after pinctrl_enable is done */
err = mtk_build_gpiochip(hw, pdev->dev.of_node);
if (err) {
dev_err(&pdev->dev, "Failed to add gpio_chip\n");
return err;
}
platform_set_drvdata(pdev, hw);
return 0;
}

View File

@ -0,0 +1,51 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2017-2018 MediaTek Inc.
*
* Author: Sean Wang <sean.wang@mediatek.com>
*
*/
#ifndef __PINCTRL_MOORE_H
#define __PINCTRL_MOORE_H
#include <linux/io.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include "../core.h"
#include "../pinconf.h"
#include "../pinmux.h"
#include "mtk-eint.h"
#include "pinctrl-mtk-common-v2.h"
#define MTK_RANGE(_a) { .range = (_a), .nranges = ARRAY_SIZE(_a), }
#define MTK_PIN(_number, _name, _eint_m, _eint_n, _drv_n) { \
.number = _number, \
.name = _name, \
.eint = { \
.eint_m = _eint_m, \
.eint_n = _eint_n, \
}, \
.drv_n = _drv_n, \
.funcs = NULL, \
}
#define PINCTRL_PIN_GROUP(name, id) \
{ \
name, \
id##_pins, \
ARRAY_SIZE(id##_pins), \
id##_funcs, \
}
int mtk_moore_pinctrl_probe(struct platform_device *pdev,
const struct mtk_pin_soc *soc);
#endif /* __PINCTRL_MOORE_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,544 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 MediaTek Inc.
*
* Author: Zhiyong Tao <zhiyong.tao@mediatek.com>
*
*/
#include "pinctrl-mtk-mt8183.h"
#include "pinctrl-paris.h"
/* MT8183 have multiple bases to program pin configuration listed as the below:
* iocfg[0]:0x10005000, iocfg[1]:0x11F20000, iocfg[2]:0x11E80000,
* iocfg[3]:0x11E70000, iocfg[4]:0x11E90000, iocfg[5]:0x11D30000,
* iocfg[6]:0x11D20000, iocfg[7]:0x11C50000, iocfg[8]:0x11F30000.
* _i_based could be used to indicate what base the pin should be mapped into.
*/
#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, _x_bits) \
PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \
_x_bits, 32, 0)
#define PINS_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, _x_bits) \
PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \
_x_bits, 32, 1)
static const struct mtk_pin_field_calc mt8183_pin_mode_range[] = {
PIN_FIELD(0, 192, 0x300, 0x10, 0, 4),
};
static const struct mtk_pin_field_calc mt8183_pin_dir_range[] = {
PIN_FIELD(0, 192, 0x0, 0x10, 0, 1),
};
static const struct mtk_pin_field_calc mt8183_pin_di_range[] = {
PIN_FIELD(0, 192, 0x200, 0x10, 0, 1),
};
static const struct mtk_pin_field_calc mt8183_pin_do_range[] = {
PIN_FIELD(0, 192, 0x100, 0x10, 0, 1),
};
static const struct mtk_pin_field_calc mt8183_pin_ies_range[] = {
PINS_FIELD_BASE(0, 3, 6, 0x000, 0x10, 3, 1),
PINS_FIELD_BASE(4, 7, 6, 0x000, 0x10, 5, 1),
PIN_FIELD_BASE(8, 8, 6, 0x000, 0x10, 0, 1),
PINS_FIELD_BASE(9, 10, 6, 0x000, 0x10, 12, 1),
PIN_FIELD_BASE(11, 11, 1, 0x000, 0x10, 3, 1),
PIN_FIELD_BASE(12, 12, 1, 0x000, 0x10, 7, 1),
PINS_FIELD_BASE(13, 16, 2, 0x000, 0x10, 2, 1),
PINS_FIELD_BASE(17, 20, 2, 0x000, 0x10, 3, 1),
PINS_FIELD_BASE(21, 24, 2, 0x000, 0x10, 4, 1),
PINS_FIELD_BASE(25, 28, 2, 0x000, 0x10, 5, 1),
PIN_FIELD_BASE(29, 29, 2, 0x000, 0x10, 6, 1),
PIN_FIELD_BASE(30, 30, 2, 0x000, 0x10, 7, 1),
PINS_FIELD_BASE(31, 31, 2, 0x000, 0x10, 8, 1),
PINS_FIELD_BASE(32, 34, 2, 0x000, 0x10, 7, 1),
PINS_FIELD_BASE(35, 37, 3, 0x000, 0x10, 0, 1),
PINS_FIELD_BASE(38, 40, 3, 0x000, 0x10, 1, 1),
PINS_FIELD_BASE(41, 42, 3, 0x000, 0x10, 2, 1),
PINS_FIELD_BASE(43, 45, 3, 0x000, 0x10, 3, 1),
PINS_FIELD_BASE(46, 47, 3, 0x000, 0x10, 4, 1),
PINS_FIELD_BASE(48, 49, 3, 0x000, 0x10, 5, 1),
PINS_FIELD_BASE(50, 51, 4, 0x000, 0x10, 0, 1),
PINS_FIELD_BASE(52, 57, 4, 0x000, 0x10, 1, 1),
PINS_FIELD_BASE(58, 60, 4, 0x000, 0x10, 2, 1),
PINS_FIELD_BASE(61, 64, 5, 0x000, 0x10, 0, 1),
PINS_FIELD_BASE(65, 66, 5, 0x000, 0x10, 1, 1),
PINS_FIELD_BASE(67, 68, 5, 0x000, 0x10, 2, 1),
PINS_FIELD_BASE(69, 71, 5, 0x000, 0x10, 3, 1),
PINS_FIELD_BASE(72, 76, 5, 0x000, 0x10, 4, 1),
PINS_FIELD_BASE(77, 80, 5, 0x000, 0x10, 5, 1),
PIN_FIELD_BASE(81, 81, 5, 0x000, 0x10, 6, 1),
PINS_FIELD_BASE(82, 83, 5, 0x000, 0x10, 7, 1),
PIN_FIELD_BASE(84, 84, 5, 0x000, 0x10, 6, 1),
PINS_FIELD_BASE(85, 88, 5, 0x000, 0x10, 8, 1),
PIN_FIELD_BASE(89, 89, 6, 0x000, 0x10, 11, 1),
PIN_FIELD_BASE(90, 90, 6, 0x000, 0x10, 1, 1),
PINS_FIELD_BASE(91, 94, 6, 0x000, 0x10, 2, 1),
PINS_FIELD_BASE(95, 96, 6, 0x000, 0x10, 6, 1),
PINS_FIELD_BASE(97, 98, 6, 0x000, 0x10, 7, 1),
PIN_FIELD_BASE(99, 99, 6, 0x000, 0x10, 8, 1),
PIN_FIELD_BASE(100, 100, 6, 0x000, 0x10, 9, 1),
PINS_FIELD_BASE(101, 102, 6, 0x000, 0x10, 10, 1),
PINS_FIELD_BASE(103, 104, 6, 0x000, 0x10, 13, 1),
PINS_FIELD_BASE(105, 106, 6, 0x000, 0x10, 14, 1),
PIN_FIELD_BASE(107, 107, 7, 0x000, 0x10, 0, 1),
PIN_FIELD_BASE(108, 108, 7, 0x000, 0x10, 1, 1),
PIN_FIELD_BASE(109, 109, 7, 0x000, 0x10, 2, 1),
PIN_FIELD_BASE(110, 110, 7, 0x000, 0x10, 0, 1),
PIN_FIELD_BASE(111, 111, 7, 0x000, 0x10, 3, 1),
PIN_FIELD_BASE(112, 112, 7, 0x000, 0x10, 2, 1),
PIN_FIELD_BASE(113, 113, 7, 0x000, 0x10, 4, 1),
PIN_FIELD_BASE(114, 114, 7, 0x000, 0x10, 5, 1),
PIN_FIELD_BASE(115, 115, 7, 0x000, 0x10, 6, 1),
PIN_FIELD_BASE(116, 116, 7, 0x000, 0x10, 7, 1),
PIN_FIELD_BASE(117, 117, 7, 0x000, 0x10, 8, 1),
PIN_FIELD_BASE(118, 118, 7, 0x000, 0x10, 9, 1),
PIN_FIELD_BASE(119, 119, 7, 0x000, 0x10, 10, 1),
PIN_FIELD_BASE(120, 120, 7, 0x000, 0x10, 11, 1),
PIN_FIELD_BASE(121, 121, 7, 0x000, 0x10, 12, 1),
PIN_FIELD_BASE(122, 122, 8, 0x000, 0x10, 0, 1),
PIN_FIELD_BASE(123, 123, 8, 0x000, 0x10, 1, 1),
PIN_FIELD_BASE(124, 124, 8, 0x000, 0x10, 2, 1),
PINS_FIELD_BASE(125, 130, 8, 0x000, 0x10, 1, 1),
PIN_FIELD_BASE(131, 131, 8, 0x000, 0x10, 3, 1),
PIN_FIELD_BASE(132, 132, 8, 0x000, 0x10, 1, 1),
PIN_FIELD_BASE(133, 133, 8, 0x000, 0x10, 4, 1),
PIN_FIELD_BASE(134, 134, 1, 0x000, 0x10, 0, 1),
PIN_FIELD_BASE(135, 135, 1, 0x000, 0x10, 1, 1),
PINS_FIELD_BASE(136, 143, 1, 0x000, 0x10, 2, 1),
PINS_FIELD_BASE(144, 147, 1, 0x000, 0x10, 4, 1),
PIN_FIELD_BASE(148, 148, 1, 0x000, 0x10, 5, 1),
PIN_FIELD_BASE(149, 149, 1, 0x000, 0x10, 6, 1),
PINS_FIELD_BASE(150, 153, 1, 0x000, 0x10, 8, 1),
PIN_FIELD_BASE(154, 154, 1, 0x000, 0x10, 9, 1),
PINS_FIELD_BASE(155, 157, 1, 0x000, 0x10, 10, 1),
PINS_FIELD_BASE(158, 160, 1, 0x000, 0x10, 8, 1),
PINS_FIELD_BASE(161, 164, 2, 0x000, 0x10, 0, 1),
PINS_FIELD_BASE(165, 166, 2, 0x000, 0x10, 1, 1),
PINS_FIELD_BASE(167, 168, 4, 0x000, 0x10, 2, 1),
PIN_FIELD_BASE(169, 169, 4, 0x000, 0x10, 3, 1),
PINS_FIELD_BASE(170, 174, 4, 0x000, 0x10, 4, 1),
PINS_FIELD_BASE(175, 176, 4, 0x000, 0x10, 3, 1),
PINS_FIELD_BASE(177, 179, 6, 0x000, 0x10, 4, 1),
};
static const struct mtk_pin_field_calc mt8183_pin_smt_range[] = {
PINS_FIELD_BASE(0, 3, 6, 0x010, 0x10, 3, 1),
PINS_FIELD_BASE(4, 7, 6, 0x010, 0x10, 5, 1),
PIN_FIELD_BASE(8, 8, 6, 0x010, 0x10, 0, 1),
PINS_FIELD_BASE(9, 10, 6, 0x010, 0x10, 12, 1),
PIN_FIELD_BASE(11, 11, 1, 0x010, 0x10, 3, 1),
PIN_FIELD_BASE(12, 12, 1, 0x010, 0x10, 7, 1),
PINS_FIELD_BASE(13, 16, 2, 0x010, 0x10, 2, 1),
PINS_FIELD_BASE(17, 20, 2, 0x010, 0x10, 3, 1),
PINS_FIELD_BASE(21, 24, 2, 0x010, 0x10, 4, 1),
PINS_FIELD_BASE(25, 28, 2, 0x010, 0x10, 5, 1),
PIN_FIELD_BASE(29, 29, 2, 0x010, 0x10, 6, 1),
PIN_FIELD_BASE(30, 30, 2, 0x010, 0x10, 7, 1),
PINS_FIELD_BASE(31, 31, 2, 0x010, 0x10, 8, 1),
PINS_FIELD_BASE(32, 34, 2, 0x010, 0x10, 7, 1),
PINS_FIELD_BASE(35, 37, 3, 0x010, 0x10, 0, 1),
PINS_FIELD_BASE(38, 40, 3, 0x010, 0x10, 1, 1),
PINS_FIELD_BASE(41, 42, 3, 0x010, 0x10, 2, 1),
PINS_FIELD_BASE(43, 45, 3, 0x010, 0x10, 3, 1),
PINS_FIELD_BASE(46, 47, 3, 0x010, 0x10, 4, 1),
PINS_FIELD_BASE(48, 49, 3, 0x010, 0x10, 5, 1),
PINS_FIELD_BASE(50, 51, 4, 0x010, 0x10, 0, 1),
PINS_FIELD_BASE(52, 57, 4, 0x010, 0x10, 1, 1),
PINS_FIELD_BASE(58, 60, 4, 0x010, 0x10, 2, 1),
PINS_FIELD_BASE(61, 64, 5, 0x010, 0x10, 0, 1),
PINS_FIELD_BASE(65, 66, 5, 0x010, 0x10, 1, 1),
PINS_FIELD_BASE(67, 68, 5, 0x010, 0x10, 2, 1),
PINS_FIELD_BASE(69, 71, 5, 0x010, 0x10, 3, 1),
PINS_FIELD_BASE(72, 76, 5, 0x010, 0x10, 4, 1),
PINS_FIELD_BASE(77, 80, 5, 0x010, 0x10, 5, 1),
PIN_FIELD_BASE(81, 81, 5, 0x010, 0x10, 6, 1),
PINS_FIELD_BASE(82, 83, 5, 0x010, 0x10, 7, 1),
PIN_FIELD_BASE(84, 84, 5, 0x010, 0x10, 6, 1),
PINS_FIELD_BASE(85, 88, 5, 0x010, 0x10, 8, 1),
PIN_FIELD_BASE(89, 89, 6, 0x010, 0x10, 11, 1),
PIN_FIELD_BASE(90, 90, 6, 0x010, 0x10, 1, 1),
PINS_FIELD_BASE(91, 94, 6, 0x010, 0x10, 2, 1),
PINS_FIELD_BASE(95, 96, 6, 0x010, 0x10, 6, 1),
PINS_FIELD_BASE(97, 98, 6, 0x010, 0x10, 7, 1),
PIN_FIELD_BASE(99, 99, 6, 0x010, 0x10, 8, 1),
PIN_FIELD_BASE(100, 100, 6, 0x010, 0x10, 9, 1),
PINS_FIELD_BASE(101, 102, 6, 0x010, 0x10, 10, 1),
PINS_FIELD_BASE(103, 104, 6, 0x010, 0x10, 13, 1),
PINS_FIELD_BASE(105, 106, 6, 0x010, 0x10, 14, 1),
PIN_FIELD_BASE(107, 107, 7, 0x010, 0x10, 0, 1),
PIN_FIELD_BASE(108, 108, 7, 0x010, 0x10, 1, 1),
PIN_FIELD_BASE(109, 109, 7, 0x010, 0x10, 2, 1),
PIN_FIELD_BASE(110, 110, 7, 0x010, 0x10, 0, 1),
PIN_FIELD_BASE(111, 111, 7, 0x010, 0x10, 3, 1),
PIN_FIELD_BASE(112, 112, 7, 0x010, 0x10, 2, 1),
PIN_FIELD_BASE(113, 113, 7, 0x010, 0x10, 4, 1),
PIN_FIELD_BASE(114, 114, 7, 0x010, 0x10, 5, 1),
PIN_FIELD_BASE(115, 115, 7, 0x010, 0x10, 6, 1),
PIN_FIELD_BASE(116, 116, 7, 0x010, 0x10, 7, 1),
PIN_FIELD_BASE(117, 117, 7, 0x010, 0x10, 8, 1),
PIN_FIELD_BASE(118, 118, 7, 0x010, 0x10, 9, 1),
PIN_FIELD_BASE(119, 119, 7, 0x010, 0x10, 10, 1),
PIN_FIELD_BASE(120, 120, 7, 0x010, 0x10, 11, 1),
PIN_FIELD_BASE(121, 121, 7, 0x010, 0x10, 12, 1),
PIN_FIELD_BASE(122, 122, 8, 0x010, 0x10, 0, 1),
PIN_FIELD_BASE(123, 123, 8, 0x010, 0x10, 1, 1),
PIN_FIELD_BASE(124, 124, 8, 0x010, 0x10, 2, 1),
PINS_FIELD_BASE(125, 130, 8, 0x010, 0x10, 1, 1),
PIN_FIELD_BASE(131, 131, 8, 0x010, 0x10, 3, 1),
PIN_FIELD_BASE(132, 132, 8, 0x010, 0x10, 1, 1),
PIN_FIELD_BASE(133, 133, 8, 0x010, 0x10, 4, 1),
PIN_FIELD_BASE(134, 134, 1, 0x010, 0x10, 0, 1),
PIN_FIELD_BASE(135, 135, 1, 0x010, 0x10, 1, 1),
PINS_FIELD_BASE(136, 143, 1, 0x010, 0x10, 2, 1),
PINS_FIELD_BASE(144, 147, 1, 0x010, 0x10, 4, 1),
PIN_FIELD_BASE(148, 148, 1, 0x010, 0x10, 5, 1),
PIN_FIELD_BASE(149, 149, 1, 0x010, 0x10, 6, 1),
PINS_FIELD_BASE(150, 153, 1, 0x010, 0x10, 8, 1),
PIN_FIELD_BASE(154, 154, 1, 0x010, 0x10, 9, 1),
PINS_FIELD_BASE(155, 157, 1, 0x010, 0x10, 10, 1),
PINS_FIELD_BASE(158, 160, 1, 0x010, 0x10, 8, 1),
PINS_FIELD_BASE(161, 164, 2, 0x010, 0x10, 0, 1),
PINS_FIELD_BASE(165, 166, 2, 0x010, 0x10, 1, 1),
PINS_FIELD_BASE(167, 168, 4, 0x010, 0x10, 2, 1),
PIN_FIELD_BASE(169, 169, 4, 0x010, 0x10, 3, 1),
PINS_FIELD_BASE(170, 174, 4, 0x010, 0x10, 4, 1),
PINS_FIELD_BASE(175, 176, 4, 0x010, 0x10, 3, 1),
PINS_FIELD_BASE(177, 179, 6, 0x010, 0x10, 4, 1),
};
static const struct mtk_pin_field_calc mt8183_pin_pullen_range[] = {
PIN_FIELD_BASE(0, 3, 6, 0x060, 0x10, 6, 1),
PIN_FIELD_BASE(4, 7, 6, 0x060, 0x10, 11, 1),
PIN_FIELD_BASE(8, 8, 6, 0x060, 0x10, 0, 1),
PIN_FIELD_BASE(9, 10, 6, 0x060, 0x10, 26, 1),
PIN_FIELD_BASE(11, 11, 1, 0x060, 0x10, 10, 1),
PIN_FIELD_BASE(12, 12, 1, 0x060, 0x10, 17, 1),
PIN_FIELD_BASE(13, 28, 2, 0x060, 0x10, 6, 1),
PIN_FIELD_BASE(43, 49, 3, 0x060, 0x10, 8, 1),
PIN_FIELD_BASE(50, 60, 4, 0x060, 0x10, 0, 1),
PIN_FIELD_BASE(61, 88, 5, 0x060, 0x10, 0, 1),
PIN_FIELD_BASE(89, 89, 6, 0x060, 0x10, 24, 1),
PIN_FIELD_BASE(90, 90, 6, 0x060, 0x10, 1, 1),
PIN_FIELD_BASE(95, 95, 6, 0x060, 0x10, 15, 1),
PIN_FIELD_BASE(96, 102, 6, 0x060, 0x10, 17, 1),
PIN_FIELD_BASE(103, 106, 6, 0x060, 0x10, 28, 1),
PIN_FIELD_BASE(107, 121, 7, 0x060, 0x10, 0, 1),
PIN_FIELD_BASE(134, 143, 1, 0x060, 0x10, 0, 1),
PIN_FIELD_BASE(144, 149, 1, 0x060, 0x10, 11, 1),
PIN_FIELD_BASE(150, 160, 1, 0x060, 0x10, 18, 1),
PIN_FIELD_BASE(161, 166, 2, 0x060, 0x10, 0, 1),
PIN_FIELD_BASE(167, 176, 4, 0x060, 0x10, 11, 1),
PIN_FIELD_BASE(177, 177, 6, 0x060, 0x10, 10, 1),
PIN_FIELD_BASE(178, 178, 6, 0x060, 0x10, 16, 1),
PIN_FIELD_BASE(179, 179, 6, 0x060, 0x10, 25, 1),
};
static const struct mtk_pin_field_calc mt8183_pin_pullsel_range[] = {
PIN_FIELD_BASE(0, 3, 6, 0x080, 0x10, 6, 1),
PIN_FIELD_BASE(4, 7, 6, 0x080, 0x10, 11, 1),
PIN_FIELD_BASE(8, 8, 6, 0x080, 0x10, 0, 1),
PIN_FIELD_BASE(9, 10, 6, 0x080, 0x10, 26, 1),
PIN_FIELD_BASE(11, 11, 1, 0x080, 0x10, 10, 1),
PIN_FIELD_BASE(12, 12, 1, 0x080, 0x10, 17, 1),
PIN_FIELD_BASE(13, 28, 2, 0x080, 0x10, 6, 1),
PIN_FIELD_BASE(43, 49, 3, 0x080, 0x10, 8, 1),
PIN_FIELD_BASE(50, 60, 4, 0x080, 0x10, 0, 1),
PIN_FIELD_BASE(61, 88, 5, 0x080, 0x10, 0, 1),
PIN_FIELD_BASE(89, 89, 6, 0x080, 0x10, 24, 1),
PIN_FIELD_BASE(90, 90, 6, 0x080, 0x10, 1, 1),
PIN_FIELD_BASE(95, 95, 6, 0x080, 0x10, 15, 1),
PIN_FIELD_BASE(96, 102, 6, 0x080, 0x10, 17, 1),
PIN_FIELD_BASE(103, 106, 6, 0x080, 0x10, 28, 1),
PIN_FIELD_BASE(107, 121, 7, 0x080, 0x10, 0, 1),
PIN_FIELD_BASE(134, 143, 1, 0x080, 0x10, 0, 1),
PIN_FIELD_BASE(144, 149, 1, 0x080, 0x10, 11, 1),
PIN_FIELD_BASE(150, 160, 1, 0x080, 0x10, 18, 1),
PIN_FIELD_BASE(161, 166, 2, 0x080, 0x10, 0, 1),
PIN_FIELD_BASE(167, 176, 4, 0x080, 0x10, 11, 1),
PIN_FIELD_BASE(177, 177, 6, 0x080, 0x10, 10, 1),
PIN_FIELD_BASE(178, 178, 6, 0x080, 0x10, 16, 1),
PIN_FIELD_BASE(179, 179, 6, 0x080, 0x10, 25, 1),
};
static const struct mtk_pin_field_calc mt8183_pin_drv_range[] = {
PINS_FIELD_BASE(0, 3, 6, 0x0A0, 0x10, 12, 3),
PINS_FIELD_BASE(4, 7, 6, 0x0A0, 0x10, 20, 3),
PIN_FIELD_BASE(8, 8, 6, 0x0A0, 0x10, 0, 3),
PINS_FIELD_BASE(9, 10, 6, 0x0B0, 0x10, 16, 3),
PIN_FIELD_BASE(11, 11, 1, 0x0A0, 0x10, 12, 3),
PIN_FIELD_BASE(12, 12, 1, 0x0A0, 0x10, 28, 3),
PINS_FIELD_BASE(13, 16, 2, 0x0A0, 0x10, 8, 3),
PINS_FIELD_BASE(17, 20, 2, 0x0A0, 0x10, 12, 3),
PINS_FIELD_BASE(21, 24, 2, 0x0A0, 0x10, 16, 3),
PINS_FIELD_BASE(25, 28, 2, 0x0A0, 0x10, 20, 3),
PIN_FIELD_BASE(29, 29, 2, 0x0A0, 0x10, 24, 3),
PIN_FIELD_BASE(30, 30, 2, 0x0A0, 0x10, 28, 3),
PINS_FIELD_BASE(31, 31, 2, 0x0B0, 0x10, 0, 3),
PINS_FIELD_BASE(32, 34, 2, 0x0A0, 0x10, 28, 3),
PINS_FIELD_BASE(35, 37, 3, 0x0A0, 0x10, 0, 3),
PINS_FIELD_BASE(38, 40, 3, 0x0A0, 0x10, 4, 3),
PINS_FIELD_BASE(41, 42, 3, 0x0A0, 0x10, 8, 3),
PINS_FIELD_BASE(43, 45, 3, 0x0A0, 0x10, 12, 3),
PINS_FIELD_BASE(46, 47, 3, 0x0A0, 0x10, 16, 3),
PINS_FIELD_BASE(48, 49, 3, 0x0A0, 0x10, 20, 3),
PINS_FIELD_BASE(50, 51, 4, 0x0A0, 0x10, 0, 3),
PINS_FIELD_BASE(52, 57, 4, 0x0A0, 0x10, 4, 3),
PINS_FIELD_BASE(58, 60, 4, 0x0A0, 0x10, 8, 3),
PINS_FIELD_BASE(61, 64, 5, 0x0A0, 0x10, 0, 3),
PINS_FIELD_BASE(65, 66, 5, 0x0A0, 0x10, 4, 3),
PINS_FIELD_BASE(67, 68, 5, 0x0A0, 0x10, 8, 3),
PINS_FIELD_BASE(69, 71, 5, 0x0A0, 0x10, 12, 3),
PINS_FIELD_BASE(72, 76, 5, 0x0A0, 0x10, 16, 3),
PINS_FIELD_BASE(77, 80, 5, 0x0A0, 0x10, 20, 3),
PIN_FIELD_BASE(81, 81, 5, 0x0A0, 0x10, 24, 3),
PINS_FIELD_BASE(82, 83, 5, 0x0A0, 0x10, 28, 3),
PIN_FIELD_BASE(84, 84, 5, 0x0A0, 0x10, 24, 3),
PINS_FIELD_BASE(85, 88, 5, 0x0B0, 0x10, 0, 3),
PIN_FIELD_BASE(89, 89, 6, 0x0B0, 0x10, 12, 3),
PIN_FIELD_BASE(90, 90, 6, 0x0A0, 0x10, 4, 3),
PINS_FIELD_BASE(91, 94, 6, 0x0A0, 0x10, 8, 3),
PINS_FIELD_BASE(95, 96, 6, 0x0A0, 0x10, 24, 3),
PINS_FIELD_BASE(97, 98, 6, 0x0A0, 0x10, 28, 3),
PIN_FIELD_BASE(99, 99, 6, 0x0B0, 0x10, 0, 3),
PIN_FIELD_BASE(100, 100, 6, 0x0B0, 0x10, 4, 3),
PINS_FIELD_BASE(101, 102, 6, 0x0B0, 0x10, 8, 3),
PINS_FIELD_BASE(103, 104, 6, 0x0B0, 0x10, 20, 3),
PINS_FIELD_BASE(105, 106, 6, 0x0B0, 0x10, 24, 3),
PIN_FIELD_BASE(107, 107, 7, 0x0A0, 0x10, 0, 3),
PIN_FIELD_BASE(108, 108, 7, 0x0A0, 0x10, 4, 3),
PIN_FIELD_BASE(109, 109, 7, 0x0A0, 0x10, 8, 3),
PIN_FIELD_BASE(110, 110, 7, 0x0A0, 0x10, 0, 3),
PIN_FIELD_BASE(111, 111, 7, 0x0A0, 0x10, 4, 3),
PIN_FIELD_BASE(112, 112, 7, 0x0A0, 0x10, 8, 3),
PIN_FIELD_BASE(113, 113, 7, 0x0A0, 0x10, 16, 3),
PIN_FIELD_BASE(114, 114, 7, 0x0A0, 0x10, 20, 3),
PIN_FIELD_BASE(115, 115, 7, 0x0A0, 0x10, 24, 3),
PIN_FIELD_BASE(116, 116, 7, 0x0A0, 0x10, 28, 3),
PIN_FIELD_BASE(117, 117, 7, 0x0B0, 0x10, 0, 3),
PIN_FIELD_BASE(118, 118, 7, 0x0B0, 0x10, 4, 3),
PIN_FIELD_BASE(119, 119, 7, 0x0B0, 0x10, 8, 3),
PIN_FIELD_BASE(120, 120, 7, 0x0B0, 0x10, 12, 3),
PIN_FIELD_BASE(121, 121, 7, 0x0B0, 0x10, 16, 3),
PIN_FIELD_BASE(122, 122, 8, 0x0A0, 0x10, 0, 3),
PIN_FIELD_BASE(123, 123, 8, 0x0A0, 0x10, 4, 3),
PIN_FIELD_BASE(124, 124, 8, 0x0A0, 0x10, 8, 3),
PINS_FIELD_BASE(125, 130, 8, 0x0A0, 0x10, 4, 3),
PIN_FIELD_BASE(131, 131, 8, 0x0A0, 0x10, 12, 3),
PIN_FIELD_BASE(132, 132, 8, 0x0A0, 0x10, 4, 3),
PIN_FIELD_BASE(133, 133, 8, 0x0A0, 0x10, 16, 3),
PIN_FIELD_BASE(134, 134, 1, 0x0A0, 0x10, 0, 3),
PIN_FIELD_BASE(135, 135, 1, 0x0A0, 0x10, 4, 3),
PINS_FIELD_BASE(136, 143, 1, 0x0A0, 0x10, 8, 3),
PINS_FIELD_BASE(144, 147, 1, 0x0A0, 0x10, 16, 3),
PIN_FIELD_BASE(148, 148, 1, 0x0A0, 0x10, 20, 3),
PIN_FIELD_BASE(149, 149, 1, 0x0A0, 0x10, 24, 3),
PINS_FIELD_BASE(150, 153, 1, 0x0B0, 0x10, 0, 3),
PIN_FIELD_BASE(154, 154, 1, 0x0B0, 0x10, 4, 3),
PINS_FIELD_BASE(155, 157, 1, 0x0B0, 0x10, 8, 3),
PINS_FIELD_BASE(158, 160, 1, 0x0B0, 0x10, 0, 3),
PINS_FIELD_BASE(161, 164, 2, 0x0A0, 0x10, 0, 3),
PINS_FIELD_BASE(165, 166, 2, 0x0A0, 0x10, 4, 3),
PINS_FIELD_BASE(167, 168, 4, 0x0A0, 0x10, 8, 3),
PIN_FIELD_BASE(169, 169, 4, 0x0A0, 0x10, 12, 3),
PINS_FIELD_BASE(170, 174, 4, 0x0A0, 0x10, 16, 3),
PINS_FIELD_BASE(175, 176, 4, 0x0A0, 0x10, 12, 3),
PINS_FIELD_BASE(177, 179, 6, 0x0A0, 0x10, 16, 3),
};
static const struct mtk_pin_field_calc mt8183_pin_pupd_range[] = {
PIN_FIELD_BASE(29, 29, 2, 0x0C0, 0x10, 2, 1),
PIN_FIELD_BASE(30, 30, 2, 0x0C0, 0x10, 6, 1),
PIN_FIELD_BASE(31, 31, 2, 0x0C0, 0x10, 10, 1),
PIN_FIELD_BASE(32, 32, 2, 0x0C0, 0x10, 14, 1),
PIN_FIELD_BASE(33, 33, 2, 0x0C0, 0x10, 18, 1),
PIN_FIELD_BASE(34, 34, 2, 0x0C0, 0x10, 22, 1),
PIN_FIELD_BASE(35, 35, 3, 0x0C0, 0x10, 2, 1),
PIN_FIELD_BASE(36, 36, 3, 0x0C0, 0x10, 6, 1),
PIN_FIELD_BASE(37, 37, 3, 0x0C0, 0x10, 10, 1),
PIN_FIELD_BASE(38, 38, 3, 0x0C0, 0x10, 14, 1),
PIN_FIELD_BASE(39, 39, 3, 0x0C0, 0x10, 18, 1),
PIN_FIELD_BASE(40, 40, 3, 0x0C0, 0x10, 22, 1),
PIN_FIELD_BASE(41, 41, 3, 0x0C0, 0x10, 26, 1),
PIN_FIELD_BASE(42, 42, 3, 0x0C0, 0x10, 30, 1),
PIN_FIELD_BASE(91, 91, 6, 0x0C0, 0x10, 2, 1),
PIN_FIELD_BASE(92, 92, 6, 0x0C0, 0x10, 6, 1),
PIN_FIELD_BASE(93, 93, 6, 0x0C0, 0x10, 10, 1),
PIN_FIELD_BASE(94, 94, 6, 0x0C0, 0x10, 14, 1),
PIN_FIELD_BASE(122, 122, 8, 0x0C0, 0x10, 2, 1),
PIN_FIELD_BASE(123, 123, 8, 0x0C0, 0x10, 6, 1),
PIN_FIELD_BASE(124, 124, 8, 0x0C0, 0x10, 10, 1),
PIN_FIELD_BASE(125, 125, 8, 0x0C0, 0x10, 14, 1),
PIN_FIELD_BASE(126, 126, 8, 0x0C0, 0x10, 18, 1),
PIN_FIELD_BASE(127, 127, 8, 0x0C0, 0x10, 22, 1),
PIN_FIELD_BASE(128, 128, 8, 0x0C0, 0x10, 26, 1),
PIN_FIELD_BASE(129, 129, 8, 0x0C0, 0x10, 30, 1),
PIN_FIELD_BASE(130, 130, 8, 0x0D0, 0x10, 2, 1),
PIN_FIELD_BASE(131, 131, 8, 0x0D0, 0x10, 6, 1),
PIN_FIELD_BASE(132, 132, 8, 0x0D0, 0x10, 10, 1),
PIN_FIELD_BASE(133, 133, 8, 0x0D0, 0x10, 14, 1),
};
static const struct mtk_pin_field_calc mt8183_pin_r0_range[] = {
PIN_FIELD_BASE(29, 29, 2, 0x0C0, 0x10, 0, 1),
PIN_FIELD_BASE(30, 30, 2, 0x0C0, 0x10, 4, 1),
PIN_FIELD_BASE(31, 31, 2, 0x0C0, 0x10, 8, 1),
PIN_FIELD_BASE(32, 32, 2, 0x0C0, 0x10, 12, 1),
PIN_FIELD_BASE(33, 33, 2, 0x0C0, 0x10, 16, 1),
PIN_FIELD_BASE(34, 34, 2, 0x0C0, 0x10, 20, 1),
PIN_FIELD_BASE(35, 35, 3, 0x0C0, 0x10, 0, 1),
PIN_FIELD_BASE(36, 36, 3, 0x0C0, 0x10, 4, 1),
PIN_FIELD_BASE(37, 37, 3, 0x0C0, 0x10, 8, 1),
PIN_FIELD_BASE(38, 38, 3, 0x0C0, 0x10, 12, 1),
PIN_FIELD_BASE(39, 39, 3, 0x0C0, 0x10, 16, 1),
PIN_FIELD_BASE(40, 40, 3, 0x0C0, 0x10, 20, 1),
PIN_FIELD_BASE(41, 41, 3, 0x0C0, 0x10, 24, 1),
PIN_FIELD_BASE(42, 42, 3, 0x0C0, 0x10, 28, 1),
PIN_FIELD_BASE(48, 48, 3, 0x0F0, 0x10, 18, 1),
PIN_FIELD_BASE(49, 49, 3, 0x0F0, 0x10, 13, 1),
PIN_FIELD_BASE(50, 50, 4, 0x0F0, 0x10, 10, 1),
PIN_FIELD_BASE(51, 51, 4, 0x0F0, 0x10, 5, 1),
PIN_FIELD_BASE(81, 81, 5, 0x0F0, 0x10, 7, 1),
PIN_FIELD_BASE(82, 82, 5, 0x0F0, 0x10, 5, 1),
PIN_FIELD_BASE(83, 83, 5, 0x0F0, 0x10, 15, 1),
PIN_FIELD_BASE(84, 84, 5, 0x0F0, 0x10, 17, 1),
PIN_FIELD_BASE(91, 91, 6, 0x0C0, 0x10, 0, 1),
PIN_FIELD_BASE(92, 92, 6, 0x0C0, 0x10, 4, 1),
PIN_FIELD_BASE(93, 93, 6, 0x0C0, 0x10, 8, 1),
PIN_FIELD_BASE(94, 94, 6, 0x0C0, 0x10, 12, 1),
PIN_FIELD_BASE(103, 103, 6, 0x0F0, 0x10, 20, 1),
PIN_FIELD_BASE(104, 104, 6, 0x0F0, 0x10, 10, 1),
PIN_FIELD_BASE(105, 105, 6, 0x0F0, 0x10, 22, 1),
PIN_FIELD_BASE(106, 106, 6, 0x0F0, 0x10, 12, 1),
PIN_FIELD_BASE(122, 122, 8, 0x0C0, 0x10, 0, 1),
PIN_FIELD_BASE(123, 123, 8, 0x0C0, 0x10, 4, 1),
PIN_FIELD_BASE(124, 124, 8, 0x0C0, 0x10, 8, 1),
PIN_FIELD_BASE(125, 125, 8, 0x0C0, 0x10, 12, 1),
PIN_FIELD_BASE(126, 126, 8, 0x0C0, 0x10, 16, 1),
PIN_FIELD_BASE(127, 127, 8, 0x0C0, 0x10, 20, 1),
PIN_FIELD_BASE(128, 128, 8, 0x0C0, 0x10, 24, 1),
PIN_FIELD_BASE(129, 129, 8, 0x0C0, 0x10, 28, 1),
PIN_FIELD_BASE(130, 130, 8, 0x0D0, 0x10, 0, 1),
PIN_FIELD_BASE(131, 131, 8, 0x0D0, 0x10, 4, 1),
PIN_FIELD_BASE(132, 132, 8, 0x0D0, 0x10, 8, 1),
PIN_FIELD_BASE(133, 133, 8, 0x0D0, 0x10, 12, 1),
};
static const struct mtk_pin_field_calc mt8183_pin_r1_range[] = {
PIN_FIELD_BASE(29, 29, 2, 0x0C0, 0x10, 1, 1),
PIN_FIELD_BASE(30, 30, 2, 0x0C0, 0x10, 5, 1),
PIN_FIELD_BASE(31, 31, 2, 0x0C0, 0x10, 9, 1),
PIN_FIELD_BASE(32, 32, 2, 0x0C0, 0x10, 13, 1),
PIN_FIELD_BASE(33, 33, 2, 0x0C0, 0x10, 17, 1),
PIN_FIELD_BASE(34, 34, 2, 0x0C0, 0x10, 21, 1),
PIN_FIELD_BASE(35, 35, 3, 0x0C0, 0x10, 1, 1),
PIN_FIELD_BASE(36, 36, 3, 0x0C0, 0x10, 5, 1),
PIN_FIELD_BASE(37, 37, 3, 0x0C0, 0x10, 9, 1),
PIN_FIELD_BASE(38, 38, 3, 0x0C0, 0x10, 13, 1),
PIN_FIELD_BASE(39, 39, 3, 0x0C0, 0x10, 17, 1),
PIN_FIELD_BASE(40, 40, 3, 0x0C0, 0x10, 21, 1),
PIN_FIELD_BASE(41, 41, 3, 0x0C0, 0x10, 25, 1),
PIN_FIELD_BASE(42, 42, 3, 0x0C0, 0x10, 29, 1),
PIN_FIELD_BASE(48, 48, 3, 0x0F0, 0x10, 19, 1),
PIN_FIELD_BASE(49, 49, 3, 0x0F0, 0x10, 14, 1),
PIN_FIELD_BASE(50, 50, 4, 0x0F0, 0x10, 11, 1),
PIN_FIELD_BASE(51, 51, 4, 0x0F0, 0x10, 6, 1),
PIN_FIELD_BASE(81, 81, 5, 0x0F0, 0x10, 8, 1),
PIN_FIELD_BASE(82, 82, 5, 0x0F0, 0x10, 6, 1),
PIN_FIELD_BASE(83, 83, 5, 0x0F0, 0x10, 16, 1),
PIN_FIELD_BASE(84, 84, 5, 0x0F0, 0x10, 18, 1),
PIN_FIELD_BASE(91, 91, 6, 0x0C0, 0x10, 1, 1),
PIN_FIELD_BASE(92, 92, 6, 0x0C0, 0x10, 5, 1),
PIN_FIELD_BASE(93, 93, 6, 0x0C0, 0x10, 9, 1),
PIN_FIELD_BASE(94, 94, 6, 0x0C0, 0x10, 13, 1),
PIN_FIELD_BASE(103, 103, 6, 0x0F0, 0x10, 21, 1),
PIN_FIELD_BASE(104, 104, 6, 0x0F0, 0x10, 11, 1),
PIN_FIELD_BASE(105, 105, 6, 0x0F0, 0x10, 23, 1),
PIN_FIELD_BASE(106, 106, 6, 0x0F0, 0x10, 13, 1),
PIN_FIELD_BASE(122, 122, 8, 0x0C0, 0x10, 1, 1),
PIN_FIELD_BASE(123, 123, 8, 0x0C0, 0x10, 5, 1),
PIN_FIELD_BASE(124, 124, 8, 0x0C0, 0x10, 9, 1),
PIN_FIELD_BASE(125, 125, 8, 0x0C0, 0x10, 13, 1),
PIN_FIELD_BASE(126, 126, 8, 0x0C0, 0x10, 17, 1),
PIN_FIELD_BASE(127, 127, 8, 0x0C0, 0x10, 21, 1),
PIN_FIELD_BASE(128, 128, 8, 0x0C0, 0x10, 25, 1),
PIN_FIELD_BASE(129, 129, 8, 0x0C0, 0x10, 29, 1),
PIN_FIELD_BASE(130, 130, 8, 0x0D0, 0x10, 1, 1),
PIN_FIELD_BASE(131, 131, 8, 0x0D0, 0x10, 5, 1),
PIN_FIELD_BASE(132, 132, 8, 0x0D0, 0x10, 9, 1),
PIN_FIELD_BASE(133, 133, 8, 0x0D0, 0x10, 13, 1),
};
static const struct mtk_pin_reg_calc mt8183_reg_cals[PINCTRL_PIN_REG_MAX] = {
[PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt8183_pin_mode_range),
[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt8183_pin_dir_range),
[PINCTRL_PIN_REG_DI] = MTK_RANGE(mt8183_pin_di_range),
[PINCTRL_PIN_REG_DO] = MTK_RANGE(mt8183_pin_do_range),
[PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt8183_pin_smt_range),
[PINCTRL_PIN_REG_IES] = MTK_RANGE(mt8183_pin_ies_range),
[PINCTRL_PIN_REG_PULLEN] = MTK_RANGE(mt8183_pin_pullen_range),
[PINCTRL_PIN_REG_PULLSEL] = MTK_RANGE(mt8183_pin_pullsel_range),
[PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt8183_pin_drv_range),
[PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt8183_pin_pupd_range),
[PINCTRL_PIN_REG_R0] = MTK_RANGE(mt8183_pin_r0_range),
[PINCTRL_PIN_REG_R1] = MTK_RANGE(mt8183_pin_r1_range),
};
static const char * const mt8183_pinctrl_register_base_names[] = {
"iocfg0", "iocfg1", "iocfg2", "iocfg3", "iocfg4", "iocfg5",
"iocfg6", "iocfg7", "iocfg8",
};
static const struct mtk_eint_hw mt8183_eint_hw = {
.port_mask = 7,
.ports = 6,
.ap_num = 212,
.db_cnt = 13,
};
static const struct mtk_pin_soc mt8183_data = {
.reg_cal = mt8183_reg_cals,
.pins = mtk_pins_mt8183,
.npins = ARRAY_SIZE(mtk_pins_mt8183),
.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,
.drive_set = mtk_pinconf_drive_set_rev1,
.drive_get = mtk_pinconf_drive_get_rev1,
.adv_pull_get = mtk_pinconf_adv_pull_get,
.adv_pull_set = mtk_pinconf_adv_pull_set,
};
static const struct of_device_id mt8183_pinctrl_of_match[] = {
{ .compatible = "mediatek,mt8183-pinctrl", },
{ }
};
static int mt8183_pinctrl_probe(struct platform_device *pdev)
{
return mtk_paris_pinctrl_probe(pdev, &mt8183_data);
}
static struct platform_driver mt8183_pinctrl_driver = {
.driver = {
.name = "mt8183-pinctrl",
.of_match_table = mt8183_pinctrl_of_match,
},
.probe = mt8183_pinctrl_probe,
};
static int __init mt8183_pinctrl_init(void)
{
return platform_driver_register(&mt8183_pinctrl_driver);
}
arch_initcall(mt8183_pinctrl_init);

View File

@ -0,0 +1,670 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 MediaTek Inc.
*
* Author: Sean Wang <sean.wang@mediatek.com>
*
*/
#include <linux/device.h>
#include <linux/err.h>
#include <linux/gpio/driver.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/of_irq.h>
#include "mtk-eint.h"
#include "pinctrl-mtk-common-v2.h"
/**
* struct mtk_drive_desc - the structure that holds the information
* of the driving current
* @min: the minimum current of this group
* @max: the maximum current of this group
* @step: the step current of this group
* @scal: the weight factor
*
* formula: output = ((input) / step - 1) * scal
*/
struct mtk_drive_desc {
u8 min;
u8 max;
u8 step;
u8 scal;
};
/* The groups of drive strength */
static const struct mtk_drive_desc mtk_drive[] = {
[DRV_GRP0] = { 4, 16, 4, 1 },
[DRV_GRP1] = { 4, 16, 4, 2 },
[DRV_GRP2] = { 2, 8, 2, 1 },
[DRV_GRP3] = { 2, 8, 2, 2 },
[DRV_GRP4] = { 2, 16, 2, 1 },
};
static void mtk_w32(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 val)
{
writel_relaxed(val, pctl->base[i] + reg);
}
static u32 mtk_r32(struct mtk_pinctrl *pctl, u8 i, u32 reg)
{
return readl_relaxed(pctl->base[i] + reg);
}
void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set)
{
u32 val;
val = mtk_r32(pctl, i, reg);
val &= ~mask;
val |= set;
mtk_w32(pctl, i, reg, val);
}
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_reg_calc *rc;
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);
return -ENOTSUPP;
}
c = rc->range;
e = c + rc->nranges;
while (c < e) {
if (desc->number >= c->s_pin && desc->number <= c->e_pin)
break;
c++;
}
if (c >= e) {
dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
field, desc->number, desc->name);
return -ENOTSUPP;
}
if (c->i_base > hw->nbase - 1) {
dev_err(hw->dev,
"Invalid base for field %d for pin = %d (%s)\n",
field, desc->number, desc->name);
return -EINVAL;
}
/* Calculated bits as the overall offset the pin is located at,
* if c->fixed is held, that determines the all the pins in the
* range use the same field with the s_pin.
*/
bits = c->fixed ? c->s_bit : c->s_bit +
(desc->number - c->s_pin) * (c->x_bits);
/* Fill pfd from bits. For example 32-bit register applied is assumed
* when c->sz_reg is equal to 32.
*/
pfd->index = c->i_base;
pfd->offset = c->s_addr + c->x_addrs * (bits / c->sz_reg);
pfd->bitpos = bits % c->sz_reg;
pfd->mask = (1 << c->x_bits) - 1;
/* pfd->next is used for indicating that bit wrapping-around happens
* which requires the manipulation for bit 0 starting in the next
* register to form the complete field read/write.
*/
pfd->next = pfd->bitpos + c->x_bits > c->sz_reg ? c->x_addrs : 0;
return 0;
}
static int mtk_hw_pin_field_get(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
int field, struct mtk_pin_field *pfd)
{
if (field < 0 || field >= PINCTRL_PIN_REG_MAX) {
dev_err(hw->dev, "Invalid Field %d\n", field);
return -EINVAL;
}
return mtk_hw_pin_field_lookup(hw, desc, field, pfd);
}
static void mtk_hw_bits_part(struct mtk_pin_field *pf, int *h, int *l)
{
*l = 32 - pf->bitpos;
*h = get_count_order(pf->mask) - *l;
}
static void mtk_hw_write_cross_field(struct mtk_pinctrl *hw,
struct mtk_pin_field *pf, int value)
{
int nbits_l, nbits_h;
mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
mtk_rmw(hw, pf->index, pf->offset, pf->mask << pf->bitpos,
(value & pf->mask) << pf->bitpos);
mtk_rmw(hw, pf->index, pf->offset + pf->next, BIT(nbits_h) - 1,
(value & pf->mask) >> nbits_l);
}
static void mtk_hw_read_cross_field(struct mtk_pinctrl *hw,
struct mtk_pin_field *pf, int *value)
{
int nbits_l, nbits_h, h, l;
mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
l = (mtk_r32(hw, pf->index, pf->offset)
>> pf->bitpos) & (BIT(nbits_l) - 1);
h = (mtk_r32(hw, pf->index, pf->offset + pf->next))
& (BIT(nbits_h) - 1);
*value = (h << nbits_l) | l;
}
int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
int field, int value)
{
struct mtk_pin_field pf;
int err;
err = mtk_hw_pin_field_get(hw, desc, field, &pf);
if (err)
return err;
if (!pf.next)
mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
(value & pf.mask) << pf.bitpos);
else
mtk_hw_write_cross_field(hw, &pf, value);
return 0;
}
int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
int field, int *value)
{
struct mtk_pin_field pf;
int err;
err = mtk_hw_pin_field_get(hw, desc, field, &pf);
if (err)
return err;
if (!pf.next)
*value = (mtk_r32(hw, pf.index, pf.offset)
>> pf.bitpos) & pf.mask;
else
mtk_hw_read_cross_field(hw, &pf, value);
return 0;
}
static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw, unsigned long eint_n)
{
const struct mtk_pin_desc *desc;
int i = 0;
desc = (const struct mtk_pin_desc *)hw->soc->pins;
while (i < hw->soc->npins) {
if (desc[i].eint.eint_n == eint_n)
return desc[i].number;
i++;
}
return EINT_NA;
}
static int mtk_xt_get_gpio_n(void *data, unsigned long eint_n,
unsigned int *gpio_n,
struct gpio_chip **gpio_chip)
{
struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
const struct mtk_pin_desc *desc;
desc = (const struct mtk_pin_desc *)hw->soc->pins;
*gpio_chip = &hw->chip;
/* Be greedy to guess first gpio_n is equal to eint_n */
if (desc[eint_n].eint.eint_n == eint_n)
*gpio_n = eint_n;
else
*gpio_n = mtk_xt_find_eint_num(hw, eint_n);
return *gpio_n == EINT_NA ? -EINVAL : 0;
}
static int mtk_xt_get_gpio_state(void *data, unsigned long eint_n)
{
struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
const struct mtk_pin_desc *desc;
struct gpio_chip *gpio_chip;
unsigned int gpio_n;
int value, err;
err = mtk_xt_get_gpio_n(hw, eint_n, &gpio_n, &gpio_chip);
if (err)
return err;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n];
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
if (err)
return err;
return !!value;
}
static int mtk_xt_set_gpio_as_eint(void *data, unsigned long eint_n)
{
struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
const struct mtk_pin_desc *desc;
struct gpio_chip *gpio_chip;
unsigned int gpio_n;
int err;
err = mtk_xt_get_gpio_n(hw, eint_n, &gpio_n, &gpio_chip);
if (err)
return err;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n];
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,
desc->eint.eint_m);
if (err)
return err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_INPUT);
if (err)
return err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, MTK_ENABLE);
if (err)
return err;
return 0;
}
static const struct mtk_eint_xt mtk_eint_xt = {
.get_gpio_n = mtk_xt_get_gpio_n,
.get_gpio_state = mtk_xt_get_gpio_state,
.set_gpio_as_eint = mtk_xt_set_gpio_as_eint,
};
int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct resource *res;
if (!IS_ENABLED(CONFIG_EINT_MTK))
return 0;
if (!of_property_read_bool(np, "interrupt-controller"))
return -ENODEV;
hw->eint = devm_kzalloc(hw->dev, sizeof(*hw->eint), GFP_KERNEL);
if (!hw->eint)
return -ENOMEM;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "eint");
if (!res) {
dev_err(&pdev->dev, "Unable to get eint resource\n");
return -ENODEV;
}
hw->eint->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(hw->eint->base))
return PTR_ERR(hw->eint->base);
hw->eint->irq = irq_of_parse_and_map(np, 0);
if (!hw->eint->irq)
return -EINVAL;
if (!hw->soc->eint_hw)
return -ENODEV;
hw->eint->dev = &pdev->dev;
hw->eint->hw = hw->soc->eint_hw;
hw->eint->pctl = hw;
hw->eint->gpio_xlate = &mtk_eint_xt;
return mtk_eint_do_init(hw->eint);
}
/* Revision 0 */
int mtk_pinconf_bias_disable_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc)
{
int err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU,
MTK_DISABLE);
if (err)
return err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD,
MTK_DISABLE);
if (err)
return err;
return 0;
}
int mtk_pinconf_bias_disable_get(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *res)
{
int v, v2;
int err;
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &v);
if (err)
return err;
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &v2);
if (err)
return err;
if (v == MTK_ENABLE || v2 == MTK_ENABLE)
return -EINVAL;
*res = 1;
return 0;
}
int mtk_pinconf_bias_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup)
{
int err, arg;
arg = pullup ? 1 : 2;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, arg & 1);
if (err)
return err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD,
!!(arg & 2));
if (err)
return err;
return 0;
}
int mtk_pinconf_bias_get(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup, int *res)
{
int reg, err, v;
reg = pullup ? PINCTRL_PIN_REG_PU : PINCTRL_PIN_REG_PD;
err = mtk_hw_get_value(hw, desc, reg, &v);
if (err)
return err;
if (!v)
return -EINVAL;
*res = 1;
return 0;
}
/* Revision 1 */
int mtk_pinconf_bias_disable_set_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc)
{
int err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN,
MTK_DISABLE);
if (err)
return err;
return 0;
}
int mtk_pinconf_bias_disable_get_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *res)
{
int v, err;
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, &v);
if (err)
return err;
if (v == MTK_ENABLE)
return -EINVAL;
*res = 1;
return 0;
}
int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup)
{
int err, arg;
arg = pullup ? MTK_PULLUP : MTK_PULLDOWN;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN,
MTK_ENABLE);
if (err)
return err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, arg);
if (err)
return err;
return 0;
}
int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup,
int *res)
{
int err, v;
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, &v);
if (err)
return err;
if (v == MTK_DISABLE)
return -EINVAL;
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, &v);
if (err)
return err;
if (pullup ^ (v == MTK_PULLUP))
return -EINVAL;
*res = 1;
return 0;
}
/* Revision 0 */
int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg)
{
const struct mtk_drive_desc *tb;
int err = -ENOTSUPP;
tb = &mtk_drive[desc->drv_n];
/* 4mA when (e8, e4) = (0, 0)
* 8mA when (e8, e4) = (0, 1)
* 12mA when (e8, e4) = (1, 0)
* 16mA when (e8, e4) = (1, 1)
*/
if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
arg = (arg / tb->step - 1) * tb->scal;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_E4,
arg & 0x1);
if (err)
return err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_E8,
(arg & 0x2) >> 1);
if (err)
return err;
}
return err;
}
int mtk_pinconf_drive_get(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *val)
{
const struct mtk_drive_desc *tb;
int err, val1, val2;
tb = &mtk_drive[desc->drv_n];
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_E4, &val1);
if (err)
return err;
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_E8, &val2);
if (err)
return err;
/* 4mA when (e8, e4) = (0, 0); 8mA when (e8, e4) = (0, 1)
* 12mA when (e8, e4) = (1, 0); 16mA when (e8, e4) = (1, 1)
*/
*val = (((val2 << 1) + val1) / tb->scal + 1) * tb->step;
return 0;
}
/* Revision 1 */
int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg)
{
const struct mtk_drive_desc *tb;
int err = -ENOTSUPP;
tb = &mtk_drive[desc->drv_n];
if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
arg = (arg / tb->step - 1) * tb->scal;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV,
arg);
if (err)
return err;
}
return err;
}
int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *val)
{
const struct mtk_drive_desc *tb;
int err, val1;
tb = &mtk_drive[desc->drv_n];
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, &val1);
if (err)
return err;
*val = ((val1 & 0x7) / tb->scal + 1) * tb->step;
return 0;
}
int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup,
u32 arg)
{
int err;
/* 10K off & 50K (75K) off, when (R0, R1) = (0, 0);
* 10K off & 50K (75K) on, when (R0, R1) = (0, 1);
* 10K on & 50K (75K) off, when (R0, R1) = (1, 0);
* 10K on & 50K (75K) on, when (R0, R1) = (1, 1)
*/
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, arg & 1);
if (err)
return 0;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1,
!!(arg & 2));
if (err)
return 0;
arg = pullup ? 0 : 1;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, arg);
/* If PUPD register is not supported for that pin, let's fallback to
* general bias control.
*/
if (err == -ENOTSUPP) {
if (hw->soc->bias_set) {
err = hw->soc->bias_set(hw, desc, pullup);
if (err)
return err;
} else {
return -ENOTSUPP;
}
}
return err;
}
int mtk_pinconf_adv_pull_get(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup,
u32 *val)
{
u32 t, t2;
int err;
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, &t);
/* If PUPD register is not supported for that pin, let's fallback to
* general bias control.
*/
if (err == -ENOTSUPP) {
if (hw->soc->bias_get) {
err = hw->soc->bias_get(hw, desc, pullup, val);
if (err)
return err;
} else {
return -ENOTSUPP;
}
} else {
/* t == 0 supposes PULLUP for the customized PULL setup */
if (err)
return err;
if (pullup ^ !t)
return -EINVAL;
}
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &t);
if (err)
return err;
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &t2);
if (err)
return err;
*val = (t | t2 << 1) & 0x7;
return 0;
}

View File

@ -0,0 +1,291 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2018 MediaTek Inc.
*
* Author: Sean Wang <sean.wang@mediatek.com>
*
*/
#ifndef __PINCTRL_MTK_COMMON_V2_H
#define __PINCTRL_MTK_COMMON_V2_H
#include <linux/gpio/driver.h>
#define MTK_INPUT 0
#define MTK_OUTPUT 1
#define MTK_DISABLE 0
#define MTK_ENABLE 1
#define MTK_PULLDOWN 0
#define MTK_PULLUP 1
#define EINT_NA U16_MAX
#define NO_EINT_SUPPORT EINT_NA
#define PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, \
_s_bit, _x_bits, _sz_reg, _fixed) { \
.s_pin = _s_pin, \
.e_pin = _e_pin, \
.i_base = _i_base, \
.s_addr = _s_addr, \
.x_addrs = _x_addrs, \
.s_bit = _s_bit, \
.x_bits = _x_bits, \
.sz_reg = _sz_reg, \
.fixed = _fixed, \
}
#define PIN_FIELD(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \
PIN_FIELD_CALC(_s_pin, _e_pin, 0, _s_addr, _x_addrs, _s_bit, \
_x_bits, 32, 0)
#define PINS_FIELD(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \
PIN_FIELD_CALC(_s_pin, _e_pin, 0, _s_addr, _x_addrs, _s_bit, \
_x_bits, 32, 1)
/* List these attributes which could be modified for the pin */
enum {
PINCTRL_PIN_REG_MODE,
PINCTRL_PIN_REG_DIR,
PINCTRL_PIN_REG_DI,
PINCTRL_PIN_REG_DO,
PINCTRL_PIN_REG_SR,
PINCTRL_PIN_REG_SMT,
PINCTRL_PIN_REG_PD,
PINCTRL_PIN_REG_PU,
PINCTRL_PIN_REG_E4,
PINCTRL_PIN_REG_E8,
PINCTRL_PIN_REG_TDSEL,
PINCTRL_PIN_REG_RDSEL,
PINCTRL_PIN_REG_DRV,
PINCTRL_PIN_REG_PUPD,
PINCTRL_PIN_REG_R0,
PINCTRL_PIN_REG_R1,
PINCTRL_PIN_REG_IES,
PINCTRL_PIN_REG_PULLEN,
PINCTRL_PIN_REG_PULLSEL,
PINCTRL_PIN_REG_MAX,
};
/* Group the pins by the driving current */
enum {
DRV_FIXED,
DRV_GRP0,
DRV_GRP1,
DRV_GRP2,
DRV_GRP3,
DRV_GRP4,
DRV_GRP_MAX,
};
static const char * const mtk_default_register_base_names[] = {
"base",
};
/* struct mtk_pin_field - the structure that holds the information of the field
* used to describe the attribute for the pin
* @base: the index pointing to the entry in base address list
* @offset: the register offset relative to the base address
* @mask: the mask used to filter out the field from the register
* @bitpos: the start bit relative to the register
* @next: the indication that the field would be extended to the
next register
*/
struct mtk_pin_field {
u8 index;
u32 offset;
u32 mask;
u8 bitpos;
u8 next;
};
/* struct mtk_pin_field_calc - the structure that holds the range providing
* the guide used to look up the relevant field
* @s_pin: the start pin within the range
* @e_pin: the end pin within the range
* @i_base: the index pointing to the entry in base address list
* @s_addr: the start address for the range
* @x_addrs: the address distance between two consecutive registers
* within the range
* @s_bit: the start bit for the first register within the range
* @x_bits: the bit distance between two consecutive pins within
* the range
* @sz_reg: the size of bits in a register
* @fixed: the consecutive pins share the same bits with the 1st
* pin
*/
struct mtk_pin_field_calc {
u16 s_pin;
u16 e_pin;
u8 i_base;
u32 s_addr;
u8 x_addrs;
u8 s_bit;
u8 x_bits;
u8 sz_reg;
u8 fixed;
};
/* struct mtk_pin_reg_calc - the structure that holds all ranges used to
* determine which register the pin would make use of
* for certain pin attribute.
* @range: the start address for the range
* @nranges: the number of items in the range
*/
struct mtk_pin_reg_calc {
const struct mtk_pin_field_calc *range;
unsigned int nranges;
};
/**
* struct mtk_func_desc - the structure that providing information
* all the funcs for this pin
* @name: the name of function
* @muxval: the mux to the function
*/
struct mtk_func_desc {
const char *name;
u8 muxval;
};
/**
* struct mtk_eint_desc - the structure that providing information
* for eint data per pin
* @eint_m: the eint mux for this pin
* @eitn_n: the eint number for this pin
*/
struct mtk_eint_desc {
u16 eint_m;
u16 eint_n;
};
/**
* struct mtk_pin_desc - the structure that providing information
* for each pin of chips
* @number: unique pin number from the global pin number space
* @name: name for this pin
* @eint: the eint data for this pin
* @drv_n: the index with the driving group
* @funcs: all available functions for this pins (only used in
* those drivers compatible to pinctrl-mtk-common.c-like
* ones)
*/
struct mtk_pin_desc {
unsigned int number;
const char *name;
struct mtk_eint_desc eint;
u8 drv_n;
struct mtk_func_desc *funcs;
};
struct mtk_pinctrl_group {
const char *name;
unsigned long config;
unsigned pin;
};
struct mtk_pinctrl;
/* struct mtk_pin_soc - the structure that holds SoC-specific data */
struct mtk_pin_soc {
const struct mtk_pin_reg_calc *reg_cal;
const struct mtk_pin_desc *pins;
unsigned int npins;
const struct group_desc *grps;
unsigned int ngrps;
const struct function_desc *funcs;
unsigned int nfuncs;
const struct mtk_eint_regs *eint_regs;
const struct mtk_eint_hw *eint_hw;
/* Specific parameters per SoC */
u8 gpio_m;
bool ies_present;
const char * const *base_names;
unsigned int nbase_names;
/* Specific pinconfig operations */
int (*bias_disable_set)(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc);
int (*bias_disable_get)(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *res);
int (*bias_set)(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup);
int (*bias_get)(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup, int *res);
int (*drive_set)(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg);
int (*drive_get)(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *val);
int (*adv_pull_set)(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup,
u32 arg);
int (*adv_pull_get)(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup,
u32 *val);
/* Specific driver data */
void *driver_data;
};
struct mtk_pinctrl {
struct pinctrl_dev *pctrl;
void __iomem **base;
u8 nbase;
struct device *dev;
struct gpio_chip chip;
const struct mtk_pin_soc *soc;
struct mtk_eint *eint;
struct mtk_pinctrl_group *groups;
const char **grp_names;
};
void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set);
int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
int field, int value);
int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
int field, int *value);
int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev);
int mtk_pinconf_bias_disable_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc);
int mtk_pinconf_bias_disable_get(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *res);
int mtk_pinconf_bias_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup);
int mtk_pinconf_bias_get(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup,
int *res);
int mtk_pinconf_bias_disable_set_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc);
int mtk_pinconf_bias_disable_get_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
int *res);
int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup);
int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup,
int *res);
int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg);
int mtk_pinconf_drive_get(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *val);
int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg);
int mtk_pinconf_drive_get_rev1(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);
int mtk_pinconf_adv_pull_get(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup,
u32 *val);
#endif /* __PINCTRL_MTK_COMMON_V2_H */

View File

@ -514,8 +514,8 @@ static int mtk_pctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
pins = of_find_property(node, "pinmux", NULL);
if (!pins) {
dev_err(pctl->dev, "missing pins property in node %s .\n",
node->name);
dev_err(pctl->dev, "missing pins property in node %pOFn .\n",
node);
return -EINVAL;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,907 @@
// SPDX-License-Identifier: GPL-2.0
/*
* MediaTek Pinctrl Paris Driver, which implement the vendor per-pin
* bindings for MediaTek SoC.
*
* Copyright (C) 2018 MediaTek Inc.
* Author: Sean Wang <sean.wang@mediatek.com>
* Zhiyong Tao <zhiyong.tao@mediatek.com>
* Hongzhou.Yang <hongzhou.yang@mediatek.com>
*/
#include <linux/gpio/driver.h>
#include <dt-bindings/pinctrl/mt65xx.h>
#include "pinctrl-paris.h"
#define PINCTRL_PINCTRL_DEV KBUILD_MODNAME
/* Custom pinconf parameters */
#define MTK_PIN_CONFIG_TDSEL (PIN_CONFIG_END + 1)
#define MTK_PIN_CONFIG_RDSEL (PIN_CONFIG_END + 2)
#define MTK_PIN_CONFIG_PU_ADV (PIN_CONFIG_END + 3)
#define MTK_PIN_CONFIG_PD_ADV (PIN_CONFIG_END + 4)
static const struct pinconf_generic_params mtk_custom_bindings[] = {
{"mediatek,tdsel", MTK_PIN_CONFIG_TDSEL, 0},
{"mediatek,rdsel", MTK_PIN_CONFIG_RDSEL, 0},
{"mediatek,pull-up-adv", MTK_PIN_CONFIG_PU_ADV, 1},
{"mediatek,pull-down-adv", MTK_PIN_CONFIG_PD_ADV, 1},
};
#ifdef CONFIG_DEBUG_FS
static const struct pin_config_item mtk_conf_items[] = {
PCONFDUMP(MTK_PIN_CONFIG_TDSEL, "tdsel", NULL, true),
PCONFDUMP(MTK_PIN_CONFIG_RDSEL, "rdsel", NULL, true),
PCONFDUMP(MTK_PIN_CONFIG_PU_ADV, "pu-adv", NULL, true),
PCONFDUMP(MTK_PIN_CONFIG_PD_ADV, "pd-adv", NULL, true),
};
#endif
static const char * const mtk_gpio_functions[] = {
"func0", "func1", "func2", "func3",
"func4", "func5", "func6", "func7",
"func8", "func9", "func10", "func11",
"func12", "func13", "func14", "func15",
};
static int mtk_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int pin)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
const struct mtk_pin_desc *desc;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,
hw->soc->gpio_m);
}
static int mtk_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int pin, bool input)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
const struct mtk_pin_desc *desc;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
/* hardware would take 0 as input direction */
return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !input);
}
static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
unsigned int pin, unsigned long *config)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
u32 param = pinconf_to_config_param(*config);
int val, val2, err, reg, ret = 1;
const struct mtk_pin_desc *desc;
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 (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;
} 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;
break;
case MTK_PIN_CONFIG_PU_ADV:
case MTK_PIN_CONFIG_PD_ADV:
if (hw->soc->adv_pull_get) {
bool pullup;
pullup = param == MTK_PIN_CONFIG_PU_ADV;
err = hw->soc->adv_pull_get(hw, desc, pullup, &ret);
if (err)
return err;
} else {
return -ENOTSUPP;
}
break;
default:
return -ENOTSUPP;
}
*config = pinconf_to_config_packed(param, ret);
return 0;
}
static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
enum pin_config_param param,
enum pin_config_param arg)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
const struct mtk_pin_desc *desc;
int err = 0;
u32 reg;
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;
}
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;
}
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;
}
break;
case PIN_CONFIG_OUTPUT_ENABLE:
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
MTK_DISABLE);
if (err)
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);
}
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;
break;
case PIN_CONFIG_OUTPUT:
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
MTK_OUTPUT);
if (err)
goto err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO,
arg);
if (err)
goto err;
break;
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);
if (err)
goto err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
!!(arg & 2));
if (err)
goto err;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
if (hw->soc->drive_set) {
err = hw->soc->drive_set(hw, desc, arg);
if (err)
return err;
} else {
return -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:
if (hw->soc->adv_pull_set) {
bool pullup;
pullup = param == MTK_PIN_CONFIG_PU_ADV;
err = hw->soc->adv_pull_set(hw, desc, pullup,
arg);
if (err)
return err;
} else {
return -ENOTSUPP;
}
break;
default:
err = -ENOTSUPP;
}
err:
return err;
}
static struct mtk_pinctrl_group *
mtk_pctrl_find_group_by_pin(struct mtk_pinctrl *hw, u32 pin)
{
int i;
for (i = 0; i < hw->soc->ngrps; i++) {
struct mtk_pinctrl_group *grp = hw->groups + i;
if (grp->pin == pin)
return grp;
}
return NULL;
}
static const struct mtk_func_desc *
mtk_pctrl_find_function_by_pin(struct mtk_pinctrl *hw, u32 pin_num, u32 fnum)
{
const struct mtk_pin_desc *pin = hw->soc->pins + pin_num;
const struct mtk_func_desc *func = pin->funcs;
while (func && func->name) {
if (func->muxval == fnum)
return func;
func++;
}
return NULL;
}
static bool mtk_pctrl_is_function_valid(struct mtk_pinctrl *hw, u32 pin_num,
u32 fnum)
{
int i;
for (i = 0; i < hw->soc->npins; i++) {
const struct mtk_pin_desc *pin = hw->soc->pins + i;
if (pin->number == pin_num) {
const struct mtk_func_desc *func = pin->funcs;
while (func && func->name) {
if (func->muxval == fnum)
return true;
func++;
}
break;
}
}
return false;
}
static int mtk_pctrl_dt_node_to_map_func(struct mtk_pinctrl *pctl,
u32 pin, u32 fnum,
struct mtk_pinctrl_group *grp,
struct pinctrl_map **map,
unsigned *reserved_maps,
unsigned *num_maps)
{
bool ret;
if (*num_maps == *reserved_maps)
return -ENOSPC;
(*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
(*map)[*num_maps].data.mux.group = grp->name;
ret = mtk_pctrl_is_function_valid(pctl, pin, fnum);
if (!ret) {
dev_err(pctl->dev, "invalid function %d on pin %d .\n",
fnum, pin);
return -EINVAL;
}
(*map)[*num_maps].data.mux.function = mtk_gpio_functions[fnum];
(*num_maps)++;
return 0;
}
static int mtk_pctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
struct device_node *node,
struct pinctrl_map **map,
unsigned *reserved_maps,
unsigned *num_maps)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
int num_pins, num_funcs, maps_per_pin, i, err;
struct mtk_pinctrl_group *grp;
unsigned int num_configs;
bool has_config = false;
unsigned long *configs;
u32 pinfunc, pin, func;
struct property *pins;
unsigned reserve = 0;
pins = of_find_property(node, "pinmux", NULL);
if (!pins) {
dev_err(hw->dev, "missing pins property in node %s .\n",
node->name);
return -EINVAL;
}
err = pinconf_generic_parse_dt_config(node, pctldev, &configs,
&num_configs);
if (err)
return err;
if (num_configs)
has_config = true;
num_pins = pins->length / sizeof(u32);
num_funcs = num_pins;
maps_per_pin = 0;
if (num_funcs)
maps_per_pin++;
if (has_config && num_pins >= 1)
maps_per_pin++;
if (!num_pins || !maps_per_pin) {
err = -EINVAL;
goto exit;
}
reserve = num_pins * maps_per_pin;
err = pinctrl_utils_reserve_map(pctldev, map, reserved_maps, num_maps,
reserve);
if (err < 0)
goto exit;
for (i = 0; i < num_pins; i++) {
err = of_property_read_u32_index(node, "pinmux", i, &pinfunc);
if (err)
goto exit;
pin = MTK_GET_PIN_NO(pinfunc);
func = MTK_GET_PIN_FUNC(pinfunc);
if (pin >= hw->soc->npins ||
func >= ARRAY_SIZE(mtk_gpio_functions)) {
dev_err(hw->dev, "invalid pins value.\n");
err = -EINVAL;
goto exit;
}
grp = mtk_pctrl_find_group_by_pin(hw, pin);
if (!grp) {
dev_err(hw->dev, "unable to match pin %d to group\n",
pin);
err = -EINVAL;
goto exit;
}
err = mtk_pctrl_dt_node_to_map_func(hw, pin, func, grp, map,
reserved_maps, num_maps);
if (err < 0)
goto exit;
if (has_config) {
err = pinctrl_utils_add_map_configs(pctldev, map,
reserved_maps,
num_maps,
grp->name,
configs,
num_configs,
PIN_MAP_TYPE_CONFIGS_GROUP);
if (err < 0)
goto exit;
}
}
err = 0;
exit:
kfree(configs);
return err;
}
static int mtk_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
struct device_node *np_config,
struct pinctrl_map **map,
unsigned *num_maps)
{
struct device_node *np;
unsigned reserved_maps;
int ret;
*map = NULL;
*num_maps = 0;
reserved_maps = 0;
for_each_child_of_node(np_config, np) {
ret = mtk_pctrl_dt_subnode_to_map(pctldev, np, map,
&reserved_maps,
num_maps);
if (ret < 0) {
pinctrl_utils_free_map(pctldev, *map, *num_maps);
of_node_put(np);
return ret;
}
}
return 0;
}
static int mtk_pctrl_get_groups_count(struct pinctrl_dev *pctldev)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
return hw->soc->ngrps;
}
static const char *mtk_pctrl_get_group_name(struct pinctrl_dev *pctldev,
unsigned group)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
return hw->groups[group].name;
}
static int mtk_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
unsigned group, const unsigned **pins,
unsigned *num_pins)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
*pins = (unsigned *)&hw->groups[group].pin;
*num_pins = 1;
return 0;
}
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,
};
static int mtk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
{
return ARRAY_SIZE(mtk_gpio_functions);
}
static const char *mtk_pmx_get_func_name(struct pinctrl_dev *pctldev,
unsigned selector)
{
return mtk_gpio_functions[selector];
}
static int mtk_pmx_get_func_groups(struct pinctrl_dev *pctldev,
unsigned function,
const char * const **groups,
unsigned * const num_groups)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
*groups = hw->grp_names;
*num_groups = hw->soc->ngrps;
return 0;
}
static int mtk_pmx_set_mux(struct pinctrl_dev *pctldev,
unsigned function,
unsigned group)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
struct mtk_pinctrl_group *grp = hw->groups + group;
const struct mtk_func_desc *desc_func;
const struct mtk_pin_desc *desc;
bool ret;
ret = mtk_pctrl_is_function_valid(hw, grp->pin, function);
if (!ret) {
dev_err(hw->dev, "invalid function %d on group %d .\n",
function, group);
return -EINVAL;
}
desc_func = mtk_pctrl_find_function_by_pin(hw, grp->pin, function);
if (!desc_func)
return -EINVAL;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[grp->pin];
mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE, desc_func->muxval);
return 0;
}
static const struct pinmux_ops mtk_pmxops = {
.get_functions_count = mtk_pmx_get_funcs_cnt,
.get_function_name = mtk_pmx_get_func_name,
.get_function_groups = mtk_pmx_get_func_groups,
.set_mux = mtk_pmx_set_mux,
.gpio_set_direction = mtk_pinmux_gpio_set_direction,
.gpio_request_enable = mtk_pinmux_gpio_request_enable,
};
static int mtk_pconf_group_get(struct pinctrl_dev *pctldev, unsigned group,
unsigned long *config)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
*config = hw->groups[group].config;
return 0;
}
static int mtk_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group,
unsigned long *configs, unsigned num_configs)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
struct mtk_pinctrl_group *grp = &hw->groups[group];
int i, ret;
for (i = 0; i < num_configs; i++) {
ret = mtk_pinconf_set(pctldev, grp->pin,
pinconf_to_config_param(configs[i]),
pinconf_to_config_argument(configs[i]));
if (ret < 0)
return ret;
grp->config = configs[i];
}
return 0;
}
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,
};
static struct pinctrl_desc mtk_desc = {
.name = PINCTRL_PINCTRL_DEV,
.pctlops = &mtk_pctlops,
.pmxops = &mtk_pmxops,
.confops = &mtk_confops,
.owner = THIS_MODULE,
};
static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
{
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
const struct mtk_pin_desc *desc;
int value, err;
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;
}
static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)
{
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
const struct mtk_pin_desc *desc;
int value, err;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
if (err)
return err;
return !!value;
}
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;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
}
static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
{
return pinctrl_gpio_direction_input(chip->base + gpio);
}
static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,
int value)
{
mtk_gpio_set(chip, gpio, value);
return pinctrl_gpio_direction_output(chip->base + gpio);
}
static int mtk_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
{
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
const struct mtk_pin_desc *desc;
if (!hw->eint)
return -ENOTSUPP;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[offset];
if (desc->eint.eint_n == EINT_NA)
return -ENOTSUPP;
return mtk_eint_find_irq(hw->eint, desc->eint.eint_n);
}
static int mtk_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
unsigned long config)
{
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
const struct mtk_pin_desc *desc;
u32 debounce;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[offset];
if (!hw->eint ||
pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE ||
desc->eint.eint_n == EINT_NA)
return -ENOTSUPP;
debounce = pinconf_to_config_argument(config);
return mtk_eint_set_debounce(hw->eint, desc->eint.eint_n, debounce);
}
static int mtk_build_gpiochip(struct mtk_pinctrl *hw, struct device_node *np)
{
struct gpio_chip *chip = &hw->chip;
int ret;
chip->label = PINCTRL_PINCTRL_DEV;
chip->parent = hw->dev;
chip->request = gpiochip_generic_request;
chip->free = gpiochip_generic_free;
chip->get_direction = mtk_gpio_get_direction;
chip->direction_input = mtk_gpio_direction_input;
chip->direction_output = mtk_gpio_direction_output;
chip->get = mtk_gpio_get;
chip->set = mtk_gpio_set;
chip->to_irq = mtk_gpio_to_irq,
chip->set_config = mtk_gpio_set_config,
chip->base = -1;
chip->ngpio = hw->soc->npins;
chip->of_node = np;
chip->of_gpio_n_cells = 2;
ret = gpiochip_add_data(chip, hw);
if (ret < 0)
return ret;
return 0;
}
static int mtk_pctrl_build_state(struct platform_device *pdev)
{
struct mtk_pinctrl *hw = platform_get_drvdata(pdev);
int i;
/* Allocate groups */
hw->groups = devm_kmalloc_array(&pdev->dev, hw->soc->ngrps,
sizeof(*hw->groups), GFP_KERNEL);
if (!hw->groups)
return -ENOMEM;
/* We assume that one pin is one group, use pin name as group name. */
hw->grp_names = devm_kmalloc_array(&pdev->dev, hw->soc->ngrps,
sizeof(*hw->grp_names), GFP_KERNEL);
if (!hw->grp_names)
return -ENOMEM;
for (i = 0; i < hw->soc->npins; i++) {
const struct mtk_pin_desc *pin = hw->soc->pins + i;
struct mtk_pinctrl_group *group = hw->groups + i;
group->name = pin->name;
group->pin = pin->number;
hw->grp_names[i] = pin->name;
}
return 0;
}
int mtk_paris_pinctrl_probe(struct platform_device *pdev,
const struct mtk_pin_soc *soc)
{
struct pinctrl_pin_desc *pins;
struct mtk_pinctrl *hw;
struct resource *res;
int err, i;
hw = devm_kzalloc(&pdev->dev, sizeof(*hw), GFP_KERNEL);
if (!hw)
return -ENOMEM;
platform_set_drvdata(pdev, hw);
hw->soc = soc;
hw->dev = &pdev->dev;
if (!hw->soc->nbase_names) {
dev_err(&pdev->dev,
"SoC should be assigned at least one register base\n");
return -EINVAL;
}
hw->base = devm_kmalloc_array(&pdev->dev, hw->soc->nbase_names,
sizeof(*hw->base), GFP_KERNEL);
if (!hw->base)
return -ENOMEM;
for (i = 0; i < hw->soc->nbase_names; i++) {
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
hw->soc->base_names[i]);
if (!res) {
dev_err(&pdev->dev, "missing IO resource\n");
return -ENXIO;
}
hw->base[i] = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(hw->base[i]))
return PTR_ERR(hw->base[i]);
}
hw->nbase = hw->soc->nbase_names;
err = mtk_pctrl_build_state(pdev);
if (err) {
dev_err(&pdev->dev, "build state failed: %d\n", err);
return -EINVAL;
}
/* Copy from internal struct mtk_pin_desc to register to the core */
pins = devm_kmalloc_array(&pdev->dev, hw->soc->npins, sizeof(*pins),
GFP_KERNEL);
if (!pins)
return -ENOMEM;
for (i = 0; i < hw->soc->npins; i++) {
pins[i].number = hw->soc->pins[i].number;
pins[i].name = hw->soc->pins[i].name;
}
/* Setup pins descriptions per SoC types */
mtk_desc.pins = (const struct pinctrl_pin_desc *)pins;
mtk_desc.npins = hw->soc->npins;
mtk_desc.num_custom_params = ARRAY_SIZE(mtk_custom_bindings);
mtk_desc.custom_params = mtk_custom_bindings;
#ifdef CONFIG_DEBUG_FS
mtk_desc.custom_conf_items = mtk_conf_items;
#endif
err = devm_pinctrl_register_and_init(&pdev->dev, &mtk_desc, hw,
&hw->pctrl);
if (err)
return err;
err = pinctrl_enable(hw->pctrl);
if (err)
return err;
err = mtk_build_eint(hw, pdev);
if (err)
dev_warn(&pdev->dev,
"Failed to add EINT, but pinctrl still can work\n");
/* Build gpiochip should be after pinctrl_enable is done */
err = mtk_build_gpiochip(hw, pdev->dev.of_node);
if (err) {
dev_err(&pdev->dev, "Failed to add gpio_chip\n");
return err;
}
platform_set_drvdata(pdev, hw);
return 0;
}

View File

@ -0,0 +1,63 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2018 MediaTek Inc.
*
* Author: Sean Wang <sean.wang@mediatek.com>
* Zhiyong Tao <zhiyong.tao@mediatek.com>
* Hongzhou.Yang <hongzhou.yang@mediatek.com>
*/
#ifndef __PINCTRL_PARIS_H
#define __PINCTRL_PARIS_H
#include <linux/io.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include "../core.h"
#include "../pinconf.h"
#include "../pinctrl-utils.h"
#include "../pinmux.h"
#include "mtk-eint.h"
#include "pinctrl-mtk-common-v2.h"
#define MTK_RANGE(_a) { .range = (_a), .nranges = ARRAY_SIZE(_a), }
#define MTK_EINT_FUNCTION(_eintmux, _eintnum) \
{ \
.eint_m = _eintmux, \
.eint_n = _eintnum, \
}
#define MTK_FUNCTION(_val, _name) \
{ \
.muxval = _val, \
.name = _name, \
}
#define MTK_PIN(_number, _name, _eint, _drv_n, ...) { \
.number = _number, \
.name = _name, \
.eint = _eint, \
.drv_n = _drv_n, \
.funcs = (struct mtk_func_desc[]){ \
__VA_ARGS__, { } }, \
}
#define PINCTRL_PIN_GROUP(name, id) \
{ \
name, \
id##_pins, \
ARRAY_SIZE(id##_pins), \
id##_funcs, \
}
int mtk_paris_pinctrl_probe(struct platform_device *pdev,
const struct mtk_pin_soc *soc);
#endif /* __PINCTRL_PARIS_H */

View File

@ -47,4 +47,10 @@ config PINCTRL_MESON_AXG
config PINCTRL_MESON_AXG_PMX
bool
config PINCTRL_MESON_G12A
bool "Meson g12a Soc pinctrl driver"
depends on ARM64
select PINCTRL_MESON_AXG_PMX
default y
endif

View File

@ -6,3 +6,4 @@ obj-$(CONFIG_PINCTRL_MESON_GXBB) += pinctrl-meson-gxbb.o
obj-$(CONFIG_PINCTRL_MESON_GXL) += pinctrl-meson-gxl.o
obj-$(CONFIG_PINCTRL_MESON_AXG_PMX) += pinctrl-meson-axg-pmx.o
obj-$(CONFIG_PINCTRL_MESON_AXG) += pinctrl-meson-axg.o
obj-$(CONFIG_PINCTRL_MESON_G12A) += pinctrl-meson-g12a.o

File diff suppressed because it is too large Load Diff

View File

@ -41,7 +41,7 @@
*/
#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/of.h>
@ -451,7 +451,7 @@ static struct regmap *meson_map_resource(struct meson_pinctrl *pc,
meson_regmap_config.max_register = resource_size(&res) - 4;
meson_regmap_config.name = devm_kasprintf(pc->dev, GFP_KERNEL,
"%s-%s", node->name,
"%pOFn-%s", node,
name);
if (!meson_regmap_config.name)
return ERR_PTR(-ENOMEM);

View File

@ -11,7 +11,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

View File

@ -17,7 +17,7 @@
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinctrl.h>
@ -413,14 +413,14 @@ static int mvebu_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
ret = of_property_read_string(np, "marvell,function", &function);
if (ret) {
dev_err(pctl->dev,
"missing marvell,function in node %s\n", np->name);
"missing marvell,function in node %pOFn\n", np);
return 0;
}
nmaps = of_property_count_strings(np, "marvell,pins");
if (nmaps < 0) {
dev_err(pctl->dev,
"missing marvell,pins in node %s\n", np->name);
"missing marvell,pins in node %pOFn\n", np);
return 0;
}

View File

@ -9,7 +9,7 @@
*/
#include <linux/kernel.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/mfd/abx500/ab8500.h>
#include "pinctrl-abx500.h"

View File

@ -9,7 +9,7 @@
*/
#include <linux/kernel.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/mfd/abx500/ab8500.h>
#include "pinctrl-abx500.h"

View File

@ -18,7 +18,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/interrupt.h>

View File

@ -17,7 +17,7 @@
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
@ -203,7 +203,7 @@ typedef unsigned long pin_cfg_t;
#define GPIO_BLOCK_SHIFT 5
#define NMK_GPIO_PER_CHIP (1 << GPIO_BLOCK_SHIFT)
#define NMK_MAX_BANKS DIV_ROUND_UP(ARCH_NR_GPIOS, NMK_GPIO_PER_CHIP)
#define NMK_MAX_BANKS DIV_ROUND_UP(512, NMK_GPIO_PER_CHIP)
/* Register in the logic block */
#define NMK_GPIO_DAT 0x00
@ -971,7 +971,7 @@ static void nmk_gpio_dbg_show_one(struct seq_file *s,
data_out ? "hi" : "lo",
(mode < 0) ? "unknown" : modes[mode]);
} else {
int irq = gpio_to_irq(gpio);
int irq = chip->to_irq(chip, offset);
struct irq_desc *desc = irq_to_desc(irq);
int pullidx = 0;
int val;
@ -1051,7 +1051,7 @@ static struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
gpio_pdev = of_find_device_by_node(np);
if (!gpio_pdev) {
pr_err("populate \"%s\": device not found\n", np->name);
pr_err("populate \"%pOFn\": device not found\n", np);
return ERR_PTR(-ENODEV);
}
if (of_property_read_u32(np, "gpio-bank", &id)) {
@ -1904,8 +1904,8 @@ static int nmk_pinctrl_probe(struct platform_device *pdev)
gpio_np = of_parse_phandle(np, "nomadik-gpio-chips", i);
if (gpio_np) {
dev_info(&pdev->dev,
"populate NMK GPIO %d \"%s\"\n",
i, gpio_np->name);
"populate NMK GPIO %d \"%pOFn\"\n",
i, gpio_np);
nmk_chip = nmk_gpio_populate_chip(gpio_np, pdev);
if (IS_ERR(nmk_chip))
dev_err(&pdev->dev,

View File

@ -0,0 +1,12 @@
config PINCTRL_NPCM7XX
bool "Pinctrl and GPIO driver for Nuvoton NPCM7XX"
depends on (ARCH_NPCM7XX || COMPILE_TEST) && OF
select PINMUX
select PINCONF
select GENERIC_PINCONF
select GPIOLIB
select GPIO_GENERIC
select GPIOLIB_IRQCHIP
help
Say Y here to enable pin controller and GPIO support
for Nuvoton NPCM750/730/715/705 SoCs.

View File

@ -0,0 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
# Nuvoton pinctrl support
obj-$(CONFIG_PINCTRL_NPCM7XX) += pinctrl-npcm7xx.o

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,7 @@
#include <linux/errno.h>
#include <linux/log2.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>

View File

@ -21,7 +21,7 @@
*/
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mfd/as3722.h>

View File

@ -17,8 +17,6 @@
#include <dt-bindings/pinctrl/at91.h>
#include <linux/clk.h>
#include <linux/gpio/driver.h>
/* FIXME: needed for gpio_to_irq(), get rid of this */
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/init.h>
@ -264,6 +262,13 @@ static struct irq_chip atmel_gpio_irq_chip = {
.irq_set_wake = atmel_gpio_irq_set_wake,
};
static int atmel_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip);
return irq_find_mapping(atmel_pioctrl->irq_domain, offset);
}
static void atmel_gpio_irq_handler(struct irq_desc *desc)
{
unsigned int irq = irq_desc_get_irq(desc);
@ -297,8 +302,9 @@ static void atmel_gpio_irq_handler(struct irq_desc *desc)
break;
for_each_set_bit(n, &isr, BITS_PER_LONG)
generic_handle_irq(gpio_to_irq(bank *
ATMEL_PIO_NPINS_PER_BANK + n));
generic_handle_irq(atmel_gpio_to_irq(
atmel_pioctrl->gpio_chip,
bank * ATMEL_PIO_NPINS_PER_BANK + n));
}
chained_irq_exit(chip, desc);
@ -360,13 +366,6 @@ static void atmel_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
BIT(pin->line));
}
static int atmel_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip);
return irq_find_mapping(atmel_pioctrl->irq_domain, offset);
}
static struct gpio_chip atmel_gpio_chip = {
.direction_input = atmel_gpio_direction_input,
.get = atmel_gpio_get,
@ -493,7 +492,6 @@ static int atmel_pctl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
unsigned num_pins, num_configs, reserve;
unsigned long *configs;
struct property *pins;
bool has_config;
u32 pinfunc;
int ret, i;
@ -509,9 +507,6 @@ static int atmel_pctl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
return ret;
}
if (num_configs)
has_config = true;
num_pins = pins->length / sizeof(u32);
if (!num_pins) {
dev_err(pctldev->dev, "no pins found in node %pOF\n", np);
@ -524,7 +519,7 @@ static int atmel_pctl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
* map for each pin.
*/
reserve = 1;
if (has_config && num_pins >= 1)
if (num_configs)
reserve++;
reserve *= num_pins;
ret = pinctrl_utils_reserve_map(pctldev, map, reserved_maps, num_maps,
@ -547,7 +542,7 @@ static int atmel_pctl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
pinctrl_utils_add_map_mux(pctldev, map, reserved_maps, num_maps,
group, func);
if (has_config) {
if (num_configs) {
ret = pinctrl_utils_add_map_configs(pctldev, map,
reserved_maps, num_maps, group,
configs, num_configs,

View File

@ -16,7 +16,7 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinctrl.h>
@ -263,8 +263,8 @@ static int at91_dt_node_to_map(struct pinctrl_dev *pctldev,
*/
grp = at91_pinctrl_find_group_by_name(info, np->name);
if (!grp) {
dev_err(info->dev, "unable to find group for node %s\n",
np->name);
dev_err(info->dev, "unable to find group for node %pOFn\n",
np);
return -EINVAL;
}
@ -1071,7 +1071,7 @@ static int at91_pinctrl_parse_groups(struct device_node *np,
const __be32 *list;
int i, j;
dev_dbg(info->dev, "group(%d): %s\n", index, np->name);
dev_dbg(info->dev, "group(%d): %pOFn\n", index, np);
/* Initialise group */
grp->name = np->name;
@ -1122,7 +1122,7 @@ static int at91_pinctrl_parse_functions(struct device_node *np,
static u32 grp_index;
u32 i = 0;
dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name);
dev_dbg(info->dev, "parse function(%d): %pOFn\n", index, np);
func = &info->functions[index];
@ -1487,7 +1487,7 @@ static int alt_gpio_irq_type(struct irq_data *d, unsigned type)
return 0;
case IRQ_TYPE_NONE:
default:
pr_warn("AT91: No type for irq %d\n", gpio_to_irq(d->irq));
pr_warn("AT91: No type for GPIO irq offset %d\n", d->irq);
return -EINVAL;
}
@ -1574,16 +1574,6 @@ void at91_pinctrl_gpio_resume(void)
#define gpio_irq_set_wake NULL
#endif /* CONFIG_PM */
static struct irq_chip gpio_irqchip = {
.name = "GPIO",
.irq_ack = gpio_irq_ack,
.irq_disable = gpio_irq_mask,
.irq_mask = gpio_irq_mask,
.irq_unmask = gpio_irq_unmask,
/* .irq_set_type is set dynamically */
.irq_set_wake = gpio_irq_set_wake,
};
static void gpio_irq_handler(struct irq_desc *desc)
{
struct irq_chip *chip = irq_desc_get_chip(desc);
@ -1624,12 +1614,22 @@ static int at91_gpio_of_irq_setup(struct platform_device *pdev,
struct gpio_chip *gpiochip_prev = NULL;
struct at91_gpio_chip *prev = NULL;
struct irq_data *d = irq_get_irq_data(at91_gpio->pioc_virq);
struct irq_chip *gpio_irqchip;
int ret, i;
gpio_irqchip = devm_kzalloc(&pdev->dev, sizeof(*gpio_irqchip), GFP_KERNEL);
if (!gpio_irqchip)
return -ENOMEM;
at91_gpio->pioc_hwirq = irqd_to_hwirq(d);
/* Setup proper .irq_set_type function */
gpio_irqchip.irq_set_type = at91_gpio->ops->irq_type;
gpio_irqchip->name = "GPIO";
gpio_irqchip->irq_ack = gpio_irq_ack;
gpio_irqchip->irq_disable = gpio_irq_mask;
gpio_irqchip->irq_mask = gpio_irq_mask;
gpio_irqchip->irq_unmask = gpio_irq_unmask;
gpio_irqchip->irq_set_wake = gpio_irq_set_wake,
gpio_irqchip->irq_set_type = at91_gpio->ops->irq_type;
/* Disable irqs of this PIO controller */
writel_relaxed(~0, at91_gpio->regbase + PIO_IDR);
@ -1640,7 +1640,7 @@ static int at91_gpio_of_irq_setup(struct platform_device *pdev,
* interrupt.
*/
ret = gpiochip_irqchip_add(&at91_gpio->chip,
&gpio_irqchip,
gpio_irqchip,
0,
handle_edge_irq,
IRQ_TYPE_NONE);
@ -1658,7 +1658,7 @@ static int at91_gpio_of_irq_setup(struct platform_device *pdev,
if (!gpiochip_prev) {
/* Then register the chain on the parent IRQ */
gpiochip_set_chained_irqchip(&at91_gpio->chip,
&gpio_irqchip,
gpio_irqchip,
at91_gpio->pioc_virq,
gpio_irq_handler);
return 0;

View File

@ -15,7 +15,7 @@
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/slab.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/pinconf-generic.h>

View File

@ -20,7 +20,6 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/spinlock.h>
#include <linux/pinctrl/machine.h>

View File

@ -10,7 +10,7 @@
* Copyright (C) 2012 John Crispin <john@phrozen.org>
*/
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/export.h>

View File

@ -591,13 +591,16 @@ static const unsigned int tvc_3512_pins[] = {
319, /* TVC_DATA[1] */
301, /* TVC_DATA[2] */
283, /* TVC_DATA[3] */
265, /* TVC_CLK */
320, /* TVC_DATA[4] */
302, /* TVC_DATA[5] */
284, /* TVC_DATA[6] */
266, /* TVC_DATA[7] */
};
static const unsigned int tvc_clk_3512_pins[] = {
265, /* TVC_CLK */
};
/* NAND flash pins */
static const unsigned int nflash_3512_pins[] = {
199, 200, 201, 202, 216, 217, 218, 219, 220, 234, 235, 236, 237, 252,
@ -629,7 +632,7 @@ static const unsigned int pflash_3512_pins_extended[] = {
/* Serial flash pins CE0, CE1, DI, DO, CK */
static const unsigned int sflash_3512_pins[] = { 230, 231, 232, 233, 211 };
/* The GPIO0A (0) pin overlap with TVC and extended parallel flash */
/* The GPIO0A (0) pin overlap with TVC CLK and extended parallel flash */
static const unsigned int gpio0a_3512_pins[] = { 265 };
/* The GPIO0B (1-4) pins overlap with TVC and ICE */
@ -823,7 +826,13 @@ static const struct gemini_pin_group gemini_3512_pin_groups[] = {
.num_pins = ARRAY_SIZE(tvc_3512_pins),
/* Conflict with character LCD and ICE */
.mask = LCD_PADS_ENABLE,
.value = TVC_PADS_ENABLE | TVC_CLK_PAD_ENABLE,
.value = TVC_PADS_ENABLE,
},
{
.name = "tvcclkgrp",
.pins = tvc_clk_3512_pins,
.num_pins = ARRAY_SIZE(tvc_clk_3512_pins),
.value = TVC_CLK_PAD_ENABLE,
},
/*
* The construction is done such that it is possible to use a serial
@ -860,8 +869,8 @@ static const struct gemini_pin_group gemini_3512_pin_groups[] = {
.name = "gpio0agrp",
.pins = gpio0a_3512_pins,
.num_pins = ARRAY_SIZE(gpio0a_3512_pins),
/* Conflict with TVC */
.mask = TVC_PADS_ENABLE,
/* Conflict with TVC CLK */
.mask = TVC_CLK_PAD_ENABLE,
},
{
.name = "gpio0bgrp",
@ -1531,13 +1540,16 @@ static const unsigned int tvc_3516_pins[] = {
311, /* TVC_DATA[1] */
394, /* TVC_DATA[2] */
374, /* TVC_DATA[3] */
333, /* TVC_CLK */
354, /* TVC_DATA[4] */
395, /* TVC_DATA[5] */
312, /* TVC_DATA[6] */
334, /* TVC_DATA[7] */
};
static const unsigned int tvc_clk_3516_pins[] = {
333, /* TVC_CLK */
};
/* NAND flash pins */
static const unsigned int nflash_3516_pins[] = {
243, 260, 261, 224, 280, 262, 281, 264, 300, 263, 282, 301, 320, 283,
@ -1570,7 +1582,7 @@ static const unsigned int pflash_3516_pins_extended[] = {
static const unsigned int sflash_3516_pins[] = { 296, 338, 295, 359, 339 };
/* The GPIO0A (0-4) pins overlap with TVC and extended parallel flash */
static const unsigned int gpio0a_3516_pins[] = { 333, 354, 395, 312, 334 };
static const unsigned int gpio0a_3516_pins[] = { 354, 395, 312, 334 };
/* The GPIO0B (5-7) pins overlap with ICE */
static const unsigned int gpio0b_3516_pins[] = { 375, 396, 376 };
@ -1602,6 +1614,9 @@ static const unsigned int gpio0j_3516_pins[] = { 359, 339 };
/* The GPIO0K (30,31) pins overlap with NAND flash */
static const unsigned int gpio0k_3516_pins[] = { 275, 298 };
/* The GPIO0L (0) pins overlap with TVC_CLK */
static const unsigned int gpio0l_3516_pins[] = { 333 };
/* The GPIO1A (0-4) pins that overlap with IDE and parallel flash */
static const unsigned int gpio1a_3516_pins[] = { 221, 200, 222, 201, 220 };
@ -1761,7 +1776,13 @@ static const struct gemini_pin_group gemini_3516_pin_groups[] = {
.num_pins = ARRAY_SIZE(tvc_3516_pins),
/* Conflict with character LCD */
.mask = LCD_PADS_ENABLE,
.value = TVC_PADS_ENABLE | TVC_CLK_PAD_ENABLE,
.value = TVC_PADS_ENABLE,
},
{
.name = "tvcclkgrp",
.pins = tvc_clk_3516_pins,
.num_pins = ARRAY_SIZE(tvc_clk_3516_pins),
.value = TVC_CLK_PAD_ENABLE,
},
/*
* The construction is done such that it is possible to use a serial
@ -1872,6 +1893,13 @@ static const struct gemini_pin_group gemini_3516_pin_groups[] = {
/* Conflict with parallel and NAND flash */
.value = PFLASH_PADS_DISABLE | NAND_PADS_DISABLE,
},
{
.name = "gpio0lgrp",
.pins = gpio0l_3516_pins,
.num_pins = ARRAY_SIZE(gpio0l_3516_pins),
/* Conflict with TVE CLK */
.mask = TVC_CLK_PAD_ENABLE,
},
{
.name = "gpio1agrp",
.pins = gpio1a_3516_pins,
@ -2179,12 +2207,13 @@ static int gemini_pmx_set_mux(struct pinctrl_dev *pctldev,
return -ENODEV;
}
dev_info(pmx->dev,
"ACTIVATE function \"%s\" with group \"%s\"\n",
func->name, grp->name);
dev_dbg(pmx->dev,
"ACTIVATE function \"%s\" with group \"%s\"\n",
func->name, grp->name);
regmap_read(pmx->map, GLOBAL_MISC_CTRL, &before);
regmap_update_bits(pmx->map, GLOBAL_MISC_CTRL, grp->mask,
regmap_update_bits(pmx->map, GLOBAL_MISC_CTRL,
grp->mask | grp->value,
grp->value);
regmap_read(pmx->map, GLOBAL_MISC_CTRL, &after);
@ -2211,10 +2240,10 @@ static int gemini_pmx_set_mux(struct pinctrl_dev *pctldev,
"GLOBAL MISC CTRL before: %08x, after %08x, expected %08x\n",
before, after, expected);
} else {
dev_info(pmx->dev,
"padgroup %s %s\n",
gemini_padgroups[i],
enabled ? "enabled" : "disabled");
dev_dbg(pmx->dev,
"padgroup %s %s\n",
gemini_padgroups[i],
enabled ? "enabled" : "disabled");
}
}
@ -2233,10 +2262,10 @@ static int gemini_pmx_set_mux(struct pinctrl_dev *pctldev,
"GLOBAL MISC CTRL before: %08x, after %08x, expected %08x\n",
before, after, expected);
} else {
dev_info(pmx->dev,
"padgroup %s %s\n",
gemini_padgroups[i],
enabled ? "enabled" : "disabled");
dev_dbg(pmx->dev,
"padgroup %s %s\n",
gemini_padgroups[i],
enabled ? "enabled" : "disabled");
}
}
@ -2463,9 +2492,9 @@ static int gemini_pinconf_group_set(struct pinctrl_dev *pctldev,
regmap_update_bits(pmx->map, GLOBAL_IODRIVE,
grp->driving_mask,
val);
dev_info(pmx->dev,
"set group %s to %d mA drive strength mask %08x val %08x\n",
grp->name, arg, grp->driving_mask, val);
dev_dbg(pmx->dev,
"set group %s to %d mA drive strength mask %08x val %08x\n",
grp->name, arg, grp->driving_mask, val);
break;
default:
dev_err(pmx->dev, "invalid config param %04x\n", param);
@ -2556,8 +2585,8 @@ static int gemini_pmx_probe(struct platform_device *pdev)
/* Print initial state */
tmp = val;
for_each_set_bit(i, &tmp, PADS_MAXBIT) {
dev_info(dev, "pad group %s %s\n", gemini_padgroups[i],
(val & BIT(i)) ? "enabled" : "disabled");
dev_dbg(dev, "pad group %s %s\n", gemini_padgroups[i],
(val & BIT(i)) ? "enabled" : "disabled");
}
/* Check if flash pin is set */

View File

@ -7,10 +7,11 @@
*/
#include <linux/compiler.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
@ -24,6 +25,9 @@
#include "pinconf.h"
#include "pinmux.h"
#define GPIO_PIN 0x00
#define GPIO_MSK 0x20
#define JZ4740_GPIO_DATA 0x10
#define JZ4740_GPIO_PULL_DIS 0x30
#define JZ4740_GPIO_FUNC 0x40
@ -33,7 +37,6 @@
#define JZ4740_GPIO_FLAG 0x80
#define JZ4770_GPIO_INT 0x10
#define JZ4770_GPIO_MSK 0x20
#define JZ4770_GPIO_PAT1 0x30
#define JZ4770_GPIO_PAT0 0x40
#define JZ4770_GPIO_FLAG 0x50
@ -46,6 +49,7 @@
enum jz_version {
ID_JZ4740,
ID_JZ4725B,
ID_JZ4770,
ID_JZ4780,
};
@ -72,6 +76,13 @@ struct ingenic_pinctrl {
const struct ingenic_chip_info *info;
};
struct ingenic_gpio_chip {
struct ingenic_pinctrl *jzpc;
struct gpio_chip gc;
struct irq_chip irq_chip;
unsigned int irq, reg_base;
};
static const u32 jz4740_pull_ups[4] = {
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
};
@ -205,6 +216,99 @@ static const struct ingenic_chip_info jz4740_chip_info = {
.pull_downs = jz4740_pull_downs,
};
static int jz4725b_mmc0_1bit_pins[] = { 0x48, 0x49, 0x5c, };
static int jz4725b_mmc0_4bit_pins[] = { 0x5d, 0x5b, 0x56, };
static int jz4725b_mmc1_1bit_pins[] = { 0x7a, 0x7b, 0x7c, };
static int jz4725b_mmc1_4bit_pins[] = { 0x7d, 0x7e, 0x7f, };
static int jz4725b_uart_data_pins[] = { 0x4c, 0x4d, };
static int jz4725b_nand_cs1_pins[] = { 0x55, };
static int jz4725b_nand_cs2_pins[] = { 0x56, };
static int jz4725b_nand_cs3_pins[] = { 0x57, };
static int jz4725b_nand_cs4_pins[] = { 0x58, };
static int jz4725b_nand_cle_ale_pins[] = { 0x48, 0x49 };
static int jz4725b_nand_fre_fwe_pins[] = { 0x5c, 0x5d };
static int jz4725b_pwm_pwm0_pins[] = { 0x4a, };
static int jz4725b_pwm_pwm1_pins[] = { 0x4b, };
static int jz4725b_pwm_pwm2_pins[] = { 0x4c, };
static int jz4725b_pwm_pwm3_pins[] = { 0x4d, };
static int jz4725b_pwm_pwm4_pins[] = { 0x4e, };
static int jz4725b_pwm_pwm5_pins[] = { 0x4f, };
static int jz4725b_mmc0_1bit_funcs[] = { 1, 1, 1, };
static int jz4725b_mmc0_4bit_funcs[] = { 1, 0, 1, };
static int jz4725b_mmc1_1bit_funcs[] = { 0, 0, 0, };
static int jz4725b_mmc1_4bit_funcs[] = { 0, 0, 0, };
static int jz4725b_uart_data_funcs[] = { 1, 1, };
static int jz4725b_nand_cs1_funcs[] = { 0, };
static int jz4725b_nand_cs2_funcs[] = { 0, };
static int jz4725b_nand_cs3_funcs[] = { 0, };
static int jz4725b_nand_cs4_funcs[] = { 0, };
static int jz4725b_nand_cle_ale_funcs[] = { 0, 0, };
static int jz4725b_nand_fre_fwe_funcs[] = { 0, 0, };
static int jz4725b_pwm_pwm0_funcs[] = { 0, };
static int jz4725b_pwm_pwm1_funcs[] = { 0, };
static int jz4725b_pwm_pwm2_funcs[] = { 0, };
static int jz4725b_pwm_pwm3_funcs[] = { 0, };
static int jz4725b_pwm_pwm4_funcs[] = { 0, };
static int jz4725b_pwm_pwm5_funcs[] = { 0, };
static const struct group_desc jz4725b_groups[] = {
INGENIC_PIN_GROUP("mmc0-1bit", jz4725b_mmc0_1bit),
INGENIC_PIN_GROUP("mmc0-4bit", jz4725b_mmc0_4bit),
INGENIC_PIN_GROUP("mmc1-1bit", jz4725b_mmc1_1bit),
INGENIC_PIN_GROUP("mmc1-4bit", jz4725b_mmc1_4bit),
INGENIC_PIN_GROUP("uart-data", jz4725b_uart_data),
INGENIC_PIN_GROUP("nand-cs1", jz4725b_nand_cs1),
INGENIC_PIN_GROUP("nand-cs2", jz4725b_nand_cs2),
INGENIC_PIN_GROUP("nand-cs3", jz4725b_nand_cs3),
INGENIC_PIN_GROUP("nand-cs4", jz4725b_nand_cs4),
INGENIC_PIN_GROUP("nand-cle-ale", jz4725b_nand_cle_ale),
INGENIC_PIN_GROUP("nand-fre-fwe", jz4725b_nand_fre_fwe),
INGENIC_PIN_GROUP("pwm0", jz4725b_pwm_pwm0),
INGENIC_PIN_GROUP("pwm1", jz4725b_pwm_pwm1),
INGENIC_PIN_GROUP("pwm2", jz4725b_pwm_pwm2),
INGENIC_PIN_GROUP("pwm3", jz4725b_pwm_pwm3),
INGENIC_PIN_GROUP("pwm4", jz4725b_pwm_pwm4),
INGENIC_PIN_GROUP("pwm5", jz4725b_pwm_pwm5),
};
static const char *jz4725b_mmc0_groups[] = { "mmc0-1bit", "mmc0-4bit", };
static const char *jz4725b_mmc1_groups[] = { "mmc1-1bit", "mmc1-4bit", };
static const char *jz4725b_uart_groups[] = { "uart-data", };
static const char *jz4725b_nand_groups[] = {
"nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4",
"nand-cle-ale", "nand-fre-fwe",
};
static const char *jz4725b_pwm0_groups[] = { "pwm0", };
static const char *jz4725b_pwm1_groups[] = { "pwm1", };
static const char *jz4725b_pwm2_groups[] = { "pwm2", };
static const char *jz4725b_pwm3_groups[] = { "pwm3", };
static const char *jz4725b_pwm4_groups[] = { "pwm4", };
static const char *jz4725b_pwm5_groups[] = { "pwm5", };
static const struct function_desc jz4725b_functions[] = {
{ "mmc0", jz4725b_mmc0_groups, ARRAY_SIZE(jz4725b_mmc0_groups), },
{ "mmc1", jz4725b_mmc1_groups, ARRAY_SIZE(jz4725b_mmc1_groups), },
{ "uart", jz4725b_uart_groups, ARRAY_SIZE(jz4725b_uart_groups), },
{ "nand", jz4725b_nand_groups, ARRAY_SIZE(jz4725b_nand_groups), },
{ "pwm0", jz4725b_pwm0_groups, ARRAY_SIZE(jz4725b_pwm0_groups), },
{ "pwm1", jz4725b_pwm1_groups, ARRAY_SIZE(jz4725b_pwm1_groups), },
{ "pwm2", jz4725b_pwm2_groups, ARRAY_SIZE(jz4725b_pwm2_groups), },
{ "pwm3", jz4725b_pwm3_groups, ARRAY_SIZE(jz4725b_pwm3_groups), },
{ "pwm4", jz4725b_pwm4_groups, ARRAY_SIZE(jz4725b_pwm4_groups), },
{ "pwm5", jz4725b_pwm5_groups, ARRAY_SIZE(jz4725b_pwm5_groups), },
};
static const struct ingenic_chip_info jz4725b_chip_info = {
.num_chips = 4,
.groups = jz4725b_groups,
.num_groups = ARRAY_SIZE(jz4725b_groups),
.functions = jz4725b_functions,
.num_functions = ARRAY_SIZE(jz4725b_functions),
.pull_ups = jz4740_pull_ups,
.pull_downs = jz4740_pull_downs,
};
static const u32 jz4770_pull_ups[6] = {
0x3fffffff, 0xfff0030c, 0xffffffff, 0xffff4fff, 0xfffffb7c, 0xffa7f00f,
};
@ -438,6 +542,235 @@ static const struct ingenic_chip_info jz4770_chip_info = {
.pull_downs = jz4770_pull_downs,
};
static u32 gpio_ingenic_read_reg(struct ingenic_gpio_chip *jzgc, u8 reg)
{
unsigned int val;
regmap_read(jzgc->jzpc->map, jzgc->reg_base + reg, &val);
return (u32) val;
}
static void gpio_ingenic_set_bit(struct ingenic_gpio_chip *jzgc,
u8 reg, u8 offset, bool set)
{
if (set)
reg = REG_SET(reg);
else
reg = REG_CLEAR(reg);
regmap_write(jzgc->jzpc->map, jzgc->reg_base + reg, BIT(offset));
}
static inline bool ingenic_gpio_get_value(struct ingenic_gpio_chip *jzgc,
u8 offset)
{
unsigned int val = gpio_ingenic_read_reg(jzgc, GPIO_PIN);
return !!(val & BIT(offset));
}
static void ingenic_gpio_set_value(struct ingenic_gpio_chip *jzgc,
u8 offset, int value)
{
if (jzgc->jzpc->version >= ID_JZ4770)
gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_PAT0, offset, !!value);
else
gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_DATA, offset, !!value);
}
static void irq_set_type(struct ingenic_gpio_chip *jzgc,
u8 offset, unsigned int type)
{
u8 reg1, reg2;
if (jzgc->jzpc->version >= ID_JZ4770) {
reg1 = JZ4770_GPIO_PAT1;
reg2 = JZ4770_GPIO_PAT0;
} else {
reg1 = JZ4740_GPIO_TRIG;
reg2 = JZ4740_GPIO_DIR;
}
switch (type) {
case IRQ_TYPE_EDGE_RISING:
gpio_ingenic_set_bit(jzgc, reg2, offset, true);
gpio_ingenic_set_bit(jzgc, reg1, offset, true);
break;
case IRQ_TYPE_EDGE_FALLING:
gpio_ingenic_set_bit(jzgc, reg2, offset, false);
gpio_ingenic_set_bit(jzgc, reg1, offset, true);
break;
case IRQ_TYPE_LEVEL_HIGH:
gpio_ingenic_set_bit(jzgc, reg2, offset, true);
gpio_ingenic_set_bit(jzgc, reg1, offset, false);
break;
case IRQ_TYPE_LEVEL_LOW:
default:
gpio_ingenic_set_bit(jzgc, reg2, offset, false);
gpio_ingenic_set_bit(jzgc, reg1, offset, false);
break;
}
}
static void ingenic_gpio_irq_mask(struct irq_data *irqd)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
gpio_ingenic_set_bit(jzgc, GPIO_MSK, irqd->hwirq, true);
}
static void ingenic_gpio_irq_unmask(struct irq_data *irqd)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
gpio_ingenic_set_bit(jzgc, GPIO_MSK, irqd->hwirq, false);
}
static void ingenic_gpio_irq_enable(struct irq_data *irqd)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
int irq = irqd->hwirq;
if (jzgc->jzpc->version >= ID_JZ4770)
gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_INT, irq, true);
else
gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, true);
ingenic_gpio_irq_unmask(irqd);
}
static void ingenic_gpio_irq_disable(struct irq_data *irqd)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
int irq = irqd->hwirq;
ingenic_gpio_irq_mask(irqd);
if (jzgc->jzpc->version >= ID_JZ4770)
gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_INT, irq, false);
else
gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, false);
}
static void ingenic_gpio_irq_ack(struct irq_data *irqd)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
int irq = irqd->hwirq;
bool high;
if (irqd_get_trigger_type(irqd) == IRQ_TYPE_EDGE_BOTH) {
/*
* Switch to an interrupt for the opposite edge to the one that
* triggered the interrupt being ACKed.
*/
high = ingenic_gpio_get_value(jzgc, irq);
if (high)
irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_FALLING);
else
irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_RISING);
}
if (jzgc->jzpc->version >= ID_JZ4770)
gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_FLAG, irq, false);
else
gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_DATA, irq, true);
}
static int ingenic_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
switch (type) {
case IRQ_TYPE_EDGE_BOTH:
case IRQ_TYPE_EDGE_RISING:
case IRQ_TYPE_EDGE_FALLING:
irq_set_handler_locked(irqd, handle_edge_irq);
break;
case IRQ_TYPE_LEVEL_HIGH:
case IRQ_TYPE_LEVEL_LOW:
irq_set_handler_locked(irqd, handle_level_irq);
break;
default:
irq_set_handler_locked(irqd, handle_bad_irq);
}
if (type == IRQ_TYPE_EDGE_BOTH) {
/*
* The hardware does not support interrupts on both edges. The
* best we can do is to set up a single-edge interrupt and then
* switch to the opposing edge when ACKing the interrupt.
*/
bool high = ingenic_gpio_get_value(jzgc, irqd->hwirq);
type = high ? IRQ_TYPE_EDGE_FALLING : IRQ_TYPE_EDGE_RISING;
}
irq_set_type(jzgc, irqd->hwirq, type);
return 0;
}
static int ingenic_gpio_irq_set_wake(struct irq_data *irqd, unsigned int on)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
return irq_set_irq_wake(jzgc->irq, on);
}
static void ingenic_gpio_irq_handler(struct irq_desc *desc)
{
struct gpio_chip *gc = irq_desc_get_handler_data(desc);
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
struct irq_chip *irq_chip = irq_data_get_irq_chip(&desc->irq_data);
unsigned long flag, i;
chained_irq_enter(irq_chip, desc);
if (jzgc->jzpc->version >= ID_JZ4770)
flag = gpio_ingenic_read_reg(jzgc, JZ4770_GPIO_FLAG);
else
flag = gpio_ingenic_read_reg(jzgc, JZ4740_GPIO_FLAG);
for_each_set_bit(i, &flag, 32)
generic_handle_irq(irq_linear_revmap(gc->irq.domain, i));
chained_irq_exit(irq_chip, desc);
}
static void ingenic_gpio_set(struct gpio_chip *gc,
unsigned int offset, int value)
{
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
ingenic_gpio_set_value(jzgc, offset, value);
}
static int ingenic_gpio_get(struct gpio_chip *gc, unsigned int offset)
{
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
return (int) ingenic_gpio_get_value(jzgc, offset);
}
static int ingenic_gpio_direction_input(struct gpio_chip *gc,
unsigned int offset)
{
return pinctrl_gpio_direction_input(gc->base + offset);
}
static int ingenic_gpio_direction_output(struct gpio_chip *gc,
unsigned int offset, int value)
{
ingenic_gpio_set(gc, offset, value);
return pinctrl_gpio_direction_output(gc->base + offset);
}
static inline void ingenic_config_pin(struct ingenic_pinctrl *jzpc,
unsigned int pin, u8 reg, bool set)
{
@ -460,6 +793,21 @@ static inline bool ingenic_get_pin_config(struct ingenic_pinctrl *jzpc,
return val & BIT(idx);
}
static int ingenic_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
{
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
struct ingenic_pinctrl *jzpc = jzgc->jzpc;
unsigned int pin = gc->base + offset;
if (jzpc->version >= ID_JZ4770)
return ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PAT1);
if (ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_SELECT))
return true;
return !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_DIR);
}
static const struct pinctrl_ops ingenic_pctlops = {
.get_groups_count = pinctrl_generic_get_group_count,
.get_group_name = pinctrl_generic_get_group_name,
@ -479,7 +827,7 @@ static int ingenic_pinmux_set_pin_fn(struct ingenic_pinctrl *jzpc,
if (jzpc->version >= ID_JZ4770) {
ingenic_config_pin(jzpc, pin, JZ4770_GPIO_INT, false);
ingenic_config_pin(jzpc, pin, JZ4770_GPIO_MSK, false);
ingenic_config_pin(jzpc, pin, GPIO_MSK, false);
ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, func & 0x2);
ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT0, func & 0x1);
} else {
@ -532,7 +880,7 @@ static int ingenic_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
if (jzpc->version >= ID_JZ4770) {
ingenic_config_pin(jzpc, pin, JZ4770_GPIO_INT, false);
ingenic_config_pin(jzpc, pin, JZ4770_GPIO_MSK, true);
ingenic_config_pin(jzpc, pin, GPIO_MSK, true);
ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, input);
} else {
ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, false);
@ -712,12 +1060,95 @@ static const struct regmap_config ingenic_pinctrl_regmap_config = {
static const struct of_device_id ingenic_pinctrl_of_match[] = {
{ .compatible = "ingenic,jz4740-pinctrl", .data = (void *) ID_JZ4740 },
{ .compatible = "ingenic,jz4725b-pinctrl", .data = (void *)ID_JZ4725B },
{ .compatible = "ingenic,jz4770-pinctrl", .data = (void *) ID_JZ4770 },
{ .compatible = "ingenic,jz4780-pinctrl", .data = (void *) ID_JZ4780 },
{},
};
static int ingenic_pinctrl_probe(struct platform_device *pdev)
static const struct of_device_id ingenic_gpio_of_match[] __initconst = {
{ .compatible = "ingenic,jz4740-gpio", },
{ .compatible = "ingenic,jz4770-gpio", },
{ .compatible = "ingenic,jz4780-gpio", },
{},
};
static int __init ingenic_gpio_probe(struct ingenic_pinctrl *jzpc,
struct device_node *node)
{
struct ingenic_gpio_chip *jzgc;
struct device *dev = jzpc->dev;
unsigned int bank;
int err;
err = of_property_read_u32(node, "reg", &bank);
if (err) {
dev_err(dev, "Cannot read \"reg\" property: %i\n", err);
return err;
}
jzgc = devm_kzalloc(dev, sizeof(*jzgc), GFP_KERNEL);
if (!jzgc)
return -ENOMEM;
jzgc->jzpc = jzpc;
jzgc->reg_base = bank * 0x100;
jzgc->gc.label = devm_kasprintf(dev, GFP_KERNEL, "GPIO%c", 'A' + bank);
if (!jzgc->gc.label)
return -ENOMEM;
/* DO NOT EXPAND THIS: FOR BACKWARD GPIO NUMBERSPACE COMPATIBIBILITY
* ONLY: WORK TO TRANSITION CONSUMERS TO USE THE GPIO DESCRIPTOR API IN
* <linux/gpio/consumer.h> INSTEAD.
*/
jzgc->gc.base = bank * 32;
jzgc->gc.ngpio = 32;
jzgc->gc.parent = dev;
jzgc->gc.of_node = node;
jzgc->gc.owner = THIS_MODULE;
jzgc->gc.set = ingenic_gpio_set;
jzgc->gc.get = ingenic_gpio_get;
jzgc->gc.direction_input = ingenic_gpio_direction_input;
jzgc->gc.direction_output = ingenic_gpio_direction_output;
jzgc->gc.get_direction = ingenic_gpio_get_direction;
if (of_property_read_bool(node, "gpio-ranges")) {
jzgc->gc.request = gpiochip_generic_request;
jzgc->gc.free = gpiochip_generic_free;
}
err = devm_gpiochip_add_data(dev, &jzgc->gc, jzgc);
if (err)
return err;
jzgc->irq = irq_of_parse_and_map(node, 0);
if (!jzgc->irq)
return -EINVAL;
jzgc->irq_chip.name = jzgc->gc.label;
jzgc->irq_chip.irq_enable = ingenic_gpio_irq_enable;
jzgc->irq_chip.irq_disable = ingenic_gpio_irq_disable;
jzgc->irq_chip.irq_unmask = ingenic_gpio_irq_unmask;
jzgc->irq_chip.irq_mask = ingenic_gpio_irq_mask;
jzgc->irq_chip.irq_ack = ingenic_gpio_irq_ack;
jzgc->irq_chip.irq_set_type = ingenic_gpio_irq_set_type;
jzgc->irq_chip.irq_set_wake = ingenic_gpio_irq_set_wake;
jzgc->irq_chip.flags = IRQCHIP_MASK_ON_SUSPEND;
err = gpiochip_irqchip_add(&jzgc->gc, &jzgc->irq_chip, 0,
handle_level_irq, IRQ_TYPE_NONE);
if (err)
return err;
gpiochip_set_chained_irqchip(&jzgc->gc, &jzgc->irq_chip,
jzgc->irq, ingenic_gpio_irq_handler);
return 0;
}
static int __init ingenic_pinctrl_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct ingenic_pinctrl *jzpc;
@ -727,6 +1158,7 @@ static int ingenic_pinctrl_probe(struct platform_device *pdev)
const struct of_device_id *of_id = of_match_device(
ingenic_pinctrl_of_match, dev);
const struct ingenic_chip_info *chip_info;
struct device_node *node;
unsigned int i;
int err;
@ -755,6 +1187,8 @@ static int ingenic_pinctrl_probe(struct platform_device *pdev)
if (jzpc->version >= ID_JZ4770)
chip_info = &jz4770_chip_info;
else if (jzpc->version >= ID_JZ4725B)
chip_info = &jz4725b_chip_info;
else
chip_info = &jz4740_chip_info;
jzpc->info = chip_info;
@ -815,11 +1249,11 @@ static int ingenic_pinctrl_probe(struct platform_device *pdev)
dev_set_drvdata(dev, jzpc->map);
if (dev->of_node) {
err = of_platform_populate(dev->of_node, NULL, NULL, dev);
if (err) {
dev_err(dev, "Failed to probe GPIO devices\n");
return err;
for_each_child_of_node(dev->of_node, node) {
if (of_match_node(ingenic_gpio_of_match, node)) {
err = ingenic_gpio_probe(jzpc, node);
if (err)
return err;
}
}
@ -828,6 +1262,7 @@ static int ingenic_pinctrl_probe(struct platform_device *pdev)
static const struct platform_device_id ingenic_pinctrl_ids[] = {
{ "jz4740-pinctrl", ID_JZ4740 },
{ "jz4725b-pinctrl", ID_JZ4725B },
{ "jz4770-pinctrl", ID_JZ4770 },
{ "jz4780-pinctrl", ID_JZ4780 },
{},
@ -837,14 +1272,13 @@ static struct platform_driver ingenic_pinctrl_driver = {
.driver = {
.name = "pinctrl-ingenic",
.of_match_table = of_match_ptr(ingenic_pinctrl_of_match),
.suppress_bind_attrs = true,
},
.probe = ingenic_pinctrl_probe,
.id_table = ingenic_pinctrl_ids,
};
static int __init ingenic_pinctrl_drv_register(void)
{
return platform_driver_register(&ingenic_pinctrl_driver);
return platform_driver_probe(&ingenic_pinctrl_driver,
ingenic_pinctrl_probe);
}
postcore_initcall(ingenic_pinctrl_drv_register);
subsys_initcall(ingenic_pinctrl_drv_register);

View File

@ -80,14 +80,14 @@ static void ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
int ret, i;
if (!pins && !groups) {
dev_err(pctldev->dev, "%s defines neither pins nor groups\n",
np->name);
dev_err(pctldev->dev, "%pOFn defines neither pins nor groups\n",
np);
return;
}
if (pins && groups) {
dev_err(pctldev->dev, "%s defines both pins and groups\n",
np->name);
dev_err(pctldev->dev, "%pOFn defines both pins and groups\n",
np);
return;
}

View File

@ -844,8 +844,11 @@ static int lpc18xx_pconf_get_pin(struct pinctrl_dev *pctldev, unsigned param,
*arg = (reg & LPC18XX_SCU_PIN_EHD_MASK) >> LPC18XX_SCU_PIN_EHD_POS;
switch (*arg) {
case 3: *arg += 5;
/* fall through */
case 2: *arg += 5;
/* fall through */
case 1: *arg += 3;
/* fall through */
case 0: *arg += 4;
}
break;
@ -1060,8 +1063,11 @@ static int lpc18xx_pconf_set_pin(struct pinctrl_dev *pctldev, unsigned param,
switch (param_val) {
case 20: param_val -= 5;
/* fall through */
case 14: param_val -= 5;
/* fall through */
case 8: param_val -= 3;
/* fall through */
case 4: param_val -= 4;
break;
default:

View File

@ -4,7 +4,7 @@
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <linux/spi/mcp23s08.h>

View File

@ -9,7 +9,6 @@
* version 2, as published by the Free Software Foundation.
*/
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/io.h>

View File

@ -27,7 +27,7 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/bitops.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/pinctrl/machine.h>
@ -501,8 +501,8 @@ static int rockchip_dt_node_to_map(struct pinctrl_dev *pctldev,
*/
grp = pinctrl_name_to_group(info, np->name);
if (!grp) {
dev_err(info->dev, "unable to find group for node %s\n",
np->name);
dev_err(info->dev, "unable to find group for node %pOFn\n",
np);
return -EINVAL;
}
@ -2454,7 +2454,7 @@ static int rockchip_pinctrl_parse_groups(struct device_node *np,
int i, j;
int ret;
dev_dbg(info->dev, "group(%d): %s\n", index, np->name);
dev_dbg(info->dev, "group(%d): %pOFn\n", index, np);
/* Initialise group */
grp->name = np->name;
@ -2519,7 +2519,7 @@ static int rockchip_pinctrl_parse_functions(struct device_node *np,
static u32 grp_index;
u32 i = 0;
dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name);
dev_dbg(info->dev, "parse function(%d): %pOFn\n", index, np);
func = &info->functions[index];

View File

@ -1,11 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Combined GPIO and pin controller support for Renesas RZ/A1 (r7s72100) SoC
*
* Copyright (C) 2017 Jacopo Mondi
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
/*
@ -930,8 +927,8 @@ static int rza1_parse_pinmux_node(struct rza1_pinctrl *rza1_pctl,
&npin_configs);
if (ret) {
dev_err(rza1_pctl->dev,
"Unable to parse pin configuration options for %s\n",
np->name);
"Unable to parse pin configuration options for %pOFn\n",
np);
return ret;
}
@ -1226,8 +1223,8 @@ static int rza1_parse_gpiochip(struct rza1_pinctrl *rza1_pctl,
*chip = rza1_gpiochip_template;
chip->base = -1;
chip->label = devm_kasprintf(rza1_pctl->dev, GFP_KERNEL, "%s",
np->name);
chip->label = devm_kasprintf(rza1_pctl->dev, GFP_KERNEL, "%pOFn",
np);
chip->ngpio = of_args.args[2];
chip->of_node = np;
chip->parent = rza1_pctl->dev;
@ -1287,7 +1284,7 @@ static int rza1_gpio_register(struct rza1_pinctrl *rza1_pctl)
ret = rza1_parse_gpiochip(rza1_pctl, child, &gpio_chips[i],
&gpio_ranges[i]);
if (ret)
goto gpiochip_remove;
return ret;
++i;
}
@ -1295,12 +1292,6 @@ static int rza1_gpio_register(struct rza1_pinctrl *rza1_pctl)
dev_info(rza1_pctl->dev, "Registered %u gpio controllers\n", i);
return 0;
gpiochip_remove:
for (; i > 0; i--)
devm_gpiochip_remove(rza1_pctl->dev, &gpio_chips[i - 1]);
return ret;
}
/**

View File

@ -0,0 +1,947 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2014-2018 Renesas Electronics Europe Limited
*
* Phil Edworthy <phil.edworthy@renesas.com>
* Based on a driver originally written by Michel Pollet at Renesas.
*/
#include <dt-bindings/pinctrl/rzn1-pinctrl.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include "core.h"
#include "pinconf.h"
#include "pinctrl-utils.h"
/* Field positions and masks in the pinmux registers */
#define RZN1_L1_PIN_DRIVE_STRENGTH 10
#define RZN1_L1_PIN_DRIVE_STRENGTH_4MA 0
#define RZN1_L1_PIN_DRIVE_STRENGTH_6MA 1
#define RZN1_L1_PIN_DRIVE_STRENGTH_8MA 2
#define RZN1_L1_PIN_DRIVE_STRENGTH_12MA 3
#define RZN1_L1_PIN_PULL 8
#define RZN1_L1_PIN_PULL_NONE 0
#define RZN1_L1_PIN_PULL_UP 1
#define RZN1_L1_PIN_PULL_DOWN 3
#define RZN1_L1_FUNCTION 0
#define RZN1_L1_FUNC_MASK 0xf
#define RZN1_L1_FUNCTION_L2 0xf
/*
* The hardware manual describes two levels of multiplexing, but it's more
* logical to think of the hardware as three levels, with level 3 consisting of
* the multiplexing for Ethernet MDIO signals.
*
* Level 1 functions go from 0 to 9, with level 1 function '15' (0xf) specifying
* that level 2 functions are used instead. Level 2 has a lot more options,
* going from 0 to 61. Level 3 allows selection of MDIO functions which can be
* floating, or one of seven internal peripherals. Unfortunately, there are two
* level 2 functions that can select MDIO, and two MDIO channels so we have four
* sets of level 3 functions.
*
* For this driver, we've compounded the numbers together, so:
* 0 to 9 is level 1
* 10 to 71 is 10 + level 2 number
* 72 to 79 is 72 + MDIO0 source for level 2 MDIO function.
* 80 to 87 is 80 + MDIO0 source for level 2 MDIO_E1 function.
* 88 to 95 is 88 + MDIO1 source for level 2 MDIO function.
* 96 to 103 is 96 + MDIO1 source for level 2 MDIO_E1 function.
* Examples:
* Function 28 corresponds UART0
* Function 73 corresponds to MDIO0 to GMAC0
*
* There are 170 configurable pins (called PL_GPIO in the datasheet).
*/
/*
* Structure detailing the HW registers on the RZ/N1 devices.
* Both the Level 1 mux registers and Level 2 mux registers have the same
* structure. The only difference is that Level 2 has additional MDIO registers
* at the end.
*/
struct rzn1_pinctrl_regs {
u32 conf[170];
u32 pad0[86];
u32 status_protect; /* 0x400 */
/* MDIO mux registers, level2 only */
u32 l2_mdio[2];
};
/**
* struct rzn1_pmx_func - describes rzn1 pinmux functions
* @name: the name of this specific function
* @groups: corresponding pin groups
* @num_groups: the number of groups
*/
struct rzn1_pmx_func {
const char *name;
const char **groups;
unsigned int num_groups;
};
/**
* struct rzn1_pin_group - describes an rzn1 pin group
* @name: the name of this specific pin group
* @func: the name of the function selected by this group
* @npins: the number of pins in this group array, i.e. the number of
* elements in .pins so we can iterate over that array
* @pins: array of pins. Needed due to pinctrl_ops.get_group_pins()
* @pin_ids: array of pin_ids, i.e. the value used to select the mux
*/
struct rzn1_pin_group {
const char *name;
const char *func;
unsigned int npins;
unsigned int *pins;
u8 *pin_ids;
};
struct rzn1_pinctrl {
struct device *dev;
struct clk *clk;
struct pinctrl_dev *pctl;
struct rzn1_pinctrl_regs __iomem *lev1;
struct rzn1_pinctrl_regs __iomem *lev2;
u32 lev1_protect_phys;
u32 lev2_protect_phys;
u32 mdio_func[2];
struct rzn1_pin_group *groups;
unsigned int ngroups;
struct rzn1_pmx_func *functions;
unsigned int nfunctions;
};
#define RZN1_PINS_PROP "pinmux"
#define RZN1_PIN(pin) PINCTRL_PIN(pin, "pl_gpio"#pin)
static const struct pinctrl_pin_desc rzn1_pins[] = {
RZN1_PIN(0), RZN1_PIN(1), RZN1_PIN(2), RZN1_PIN(3), RZN1_PIN(4),
RZN1_PIN(5), RZN1_PIN(6), RZN1_PIN(7), RZN1_PIN(8), RZN1_PIN(9),
RZN1_PIN(10), RZN1_PIN(11), RZN1_PIN(12), RZN1_PIN(13), RZN1_PIN(14),
RZN1_PIN(15), RZN1_PIN(16), RZN1_PIN(17), RZN1_PIN(18), RZN1_PIN(19),
RZN1_PIN(20), RZN1_PIN(21), RZN1_PIN(22), RZN1_PIN(23), RZN1_PIN(24),
RZN1_PIN(25), RZN1_PIN(26), RZN1_PIN(27), RZN1_PIN(28), RZN1_PIN(29),
RZN1_PIN(30), RZN1_PIN(31), RZN1_PIN(32), RZN1_PIN(33), RZN1_PIN(34),
RZN1_PIN(35), RZN1_PIN(36), RZN1_PIN(37), RZN1_PIN(38), RZN1_PIN(39),
RZN1_PIN(40), RZN1_PIN(41), RZN1_PIN(42), RZN1_PIN(43), RZN1_PIN(44),
RZN1_PIN(45), RZN1_PIN(46), RZN1_PIN(47), RZN1_PIN(48), RZN1_PIN(49),
RZN1_PIN(50), RZN1_PIN(51), RZN1_PIN(52), RZN1_PIN(53), RZN1_PIN(54),
RZN1_PIN(55), RZN1_PIN(56), RZN1_PIN(57), RZN1_PIN(58), RZN1_PIN(59),
RZN1_PIN(60), RZN1_PIN(61), RZN1_PIN(62), RZN1_PIN(63), RZN1_PIN(64),
RZN1_PIN(65), RZN1_PIN(66), RZN1_PIN(67), RZN1_PIN(68), RZN1_PIN(69),
RZN1_PIN(70), RZN1_PIN(71), RZN1_PIN(72), RZN1_PIN(73), RZN1_PIN(74),
RZN1_PIN(75), RZN1_PIN(76), RZN1_PIN(77), RZN1_PIN(78), RZN1_PIN(79),
RZN1_PIN(80), RZN1_PIN(81), RZN1_PIN(82), RZN1_PIN(83), RZN1_PIN(84),
RZN1_PIN(85), RZN1_PIN(86), RZN1_PIN(87), RZN1_PIN(88), RZN1_PIN(89),
RZN1_PIN(90), RZN1_PIN(91), RZN1_PIN(92), RZN1_PIN(93), RZN1_PIN(94),
RZN1_PIN(95), RZN1_PIN(96), RZN1_PIN(97), RZN1_PIN(98), RZN1_PIN(99),
RZN1_PIN(100), RZN1_PIN(101), RZN1_PIN(102), RZN1_PIN(103),
RZN1_PIN(104), RZN1_PIN(105), RZN1_PIN(106), RZN1_PIN(107),
RZN1_PIN(108), RZN1_PIN(109), RZN1_PIN(110), RZN1_PIN(111),
RZN1_PIN(112), RZN1_PIN(113), RZN1_PIN(114), RZN1_PIN(115),
RZN1_PIN(116), RZN1_PIN(117), RZN1_PIN(118), RZN1_PIN(119),
RZN1_PIN(120), RZN1_PIN(121), RZN1_PIN(122), RZN1_PIN(123),
RZN1_PIN(124), RZN1_PIN(125), RZN1_PIN(126), RZN1_PIN(127),
RZN1_PIN(128), RZN1_PIN(129), RZN1_PIN(130), RZN1_PIN(131),
RZN1_PIN(132), RZN1_PIN(133), RZN1_PIN(134), RZN1_PIN(135),
RZN1_PIN(136), RZN1_PIN(137), RZN1_PIN(138), RZN1_PIN(139),
RZN1_PIN(140), RZN1_PIN(141), RZN1_PIN(142), RZN1_PIN(143),
RZN1_PIN(144), RZN1_PIN(145), RZN1_PIN(146), RZN1_PIN(147),
RZN1_PIN(148), RZN1_PIN(149), RZN1_PIN(150), RZN1_PIN(151),
RZN1_PIN(152), RZN1_PIN(153), RZN1_PIN(154), RZN1_PIN(155),
RZN1_PIN(156), RZN1_PIN(157), RZN1_PIN(158), RZN1_PIN(159),
RZN1_PIN(160), RZN1_PIN(161), RZN1_PIN(162), RZN1_PIN(163),
RZN1_PIN(164), RZN1_PIN(165), RZN1_PIN(166), RZN1_PIN(167),
RZN1_PIN(168), RZN1_PIN(169),
};
enum {
LOCK_LEVEL1 = 0x1,
LOCK_LEVEL2 = 0x2,
LOCK_ALL = LOCK_LEVEL1 | LOCK_LEVEL2,
};
static void rzn1_hw_set_lock(struct rzn1_pinctrl *ipctl, u8 lock, u8 value)
{
/*
* The pinmux configuration is locked by writing the physical address of
* the status_protect register to itself. It is unlocked by writing the
* address | 1.
*/
if (lock & LOCK_LEVEL1) {
u32 val = ipctl->lev1_protect_phys | !(value & LOCK_LEVEL1);
writel(val, &ipctl->lev1->status_protect);
}
if (lock & LOCK_LEVEL2) {
u32 val = ipctl->lev2_protect_phys | !(value & LOCK_LEVEL2);
writel(val, &ipctl->lev2->status_protect);
}
}
static void rzn1_pinctrl_mdio_select(struct rzn1_pinctrl *ipctl, int mdio,
u32 func)
{
if (ipctl->mdio_func[mdio] >= 0 && ipctl->mdio_func[mdio] != func)
dev_warn(ipctl->dev, "conflicting setting for mdio%d!\n", mdio);
ipctl->mdio_func[mdio] = func;
dev_dbg(ipctl->dev, "setting mdio%d to %u\n", mdio, func);
writel(func, &ipctl->lev2->l2_mdio[mdio]);
}
/*
* Using a composite pin description, set the hardware pinmux registers
* with the corresponding values.
* Make sure to unlock write protection and reset it afterward.
*
* NOTE: There is no protection for potential concurrency, it is assumed these
* calls are serialized already.
*/
static int rzn1_set_hw_pin_func(struct rzn1_pinctrl *ipctl, unsigned int pin,
u32 pin_config, u8 use_locks)
{
u32 l1_cache;
u32 l2_cache;
u32 l1;
u32 l2;
/* Level 3 MDIO multiplexing */
if (pin_config >= RZN1_FUNC_MDIO0_HIGHZ &&
pin_config <= RZN1_FUNC_MDIO1_E1_SWITCH) {
int mdio_channel;
u32 mdio_func;
if (pin_config <= RZN1_FUNC_MDIO1_HIGHZ)
mdio_channel = 0;
else
mdio_channel = 1;
/* Get MDIO func, and convert the func to the level 2 number */
if (pin_config <= RZN1_FUNC_MDIO0_SWITCH) {
mdio_func = pin_config - RZN1_FUNC_MDIO0_HIGHZ;
pin_config = RZN1_FUNC_ETH_MDIO;
} else if (pin_config <= RZN1_FUNC_MDIO0_E1_SWITCH) {
mdio_func = pin_config - RZN1_FUNC_MDIO0_E1_HIGHZ;
pin_config = RZN1_FUNC_ETH_MDIO_E1;
} else if (pin_config <= RZN1_FUNC_MDIO1_SWITCH) {
mdio_func = pin_config - RZN1_FUNC_MDIO1_HIGHZ;
pin_config = RZN1_FUNC_ETH_MDIO;
} else {
mdio_func = pin_config - RZN1_FUNC_MDIO1_E1_HIGHZ;
pin_config = RZN1_FUNC_ETH_MDIO_E1;
}
rzn1_pinctrl_mdio_select(ipctl, mdio_channel, mdio_func);
}
/* Note here, we do not allow anything past the MDIO Mux values */
if (pin >= ARRAY_SIZE(ipctl->lev1->conf) ||
pin_config >= RZN1_FUNC_MDIO0_HIGHZ)
return -EINVAL;
l1 = readl(&ipctl->lev1->conf[pin]);
l1_cache = l1;
l2 = readl(&ipctl->lev2->conf[pin]);
l2_cache = l2;
dev_dbg(ipctl->dev, "setting func for pin %u to %u\n", pin, pin_config);
l1 &= ~(RZN1_L1_FUNC_MASK << RZN1_L1_FUNCTION);
if (pin_config < RZN1_FUNC_L2_OFFSET) {
l1 |= (pin_config << RZN1_L1_FUNCTION);
} else {
l1 |= (RZN1_L1_FUNCTION_L2 << RZN1_L1_FUNCTION);
l2 = pin_config - RZN1_FUNC_L2_OFFSET;
}
/* If either configuration changes, we update both anyway */
if (l1 != l1_cache || l2 != l2_cache) {
writel(l1, &ipctl->lev1->conf[pin]);
writel(l2, &ipctl->lev2->conf[pin]);
}
return 0;
}
static const struct rzn1_pin_group *rzn1_pinctrl_find_group_by_name(
const struct rzn1_pinctrl *ipctl, const char *name)
{
unsigned int i;
for (i = 0; i < ipctl->ngroups; i++) {
if (!strcmp(ipctl->groups[i].name, name))
return &ipctl->groups[i];
}
return NULL;
}
static int rzn1_get_groups_count(struct pinctrl_dev *pctldev)
{
struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
return ipctl->ngroups;
}
static const char *rzn1_get_group_name(struct pinctrl_dev *pctldev,
unsigned int selector)
{
struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
return ipctl->groups[selector].name;
}
static int rzn1_get_group_pins(struct pinctrl_dev *pctldev,
unsigned int selector, const unsigned int **pins,
unsigned int *npins)
{
struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
if (selector >= ipctl->ngroups)
return -EINVAL;
*pins = ipctl->groups[selector].pins;
*npins = ipctl->groups[selector].npins;
return 0;
}
/*
* This function is called for each pinctl 'Function' node.
* Sub-nodes can be used to describe multiple 'Groups' for the 'Function'
* If there aren't any sub-nodes, the 'Group' is essentially the 'Function'.
* Each 'Group' uses pinmux = <...> to detail the pins and data used to select
* the functionality. Each 'Group' has optional pin configurations that apply
* to all pins in the 'Group'.
*/
static int rzn1_dt_node_to_map_one(struct pinctrl_dev *pctldev,
struct device_node *np,
struct pinctrl_map **map,
unsigned int *num_maps)
{
struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
const struct rzn1_pin_group *grp;
unsigned long *configs = NULL;
unsigned int reserved_maps = *num_maps;
unsigned int num_configs = 0;
unsigned int reserve = 1;
int ret;
dev_dbg(ipctl->dev, "processing node %pOF\n", np);
grp = rzn1_pinctrl_find_group_by_name(ipctl, np->name);
if (!grp) {
dev_err(ipctl->dev, "unable to find group for node %pOF\n", np);
return -EINVAL;
}
/* Get the group's pin configuration */
ret = pinconf_generic_parse_dt_config(np, pctldev, &configs,
&num_configs);
if (ret < 0) {
dev_err(ipctl->dev, "%pOF: could not parse property\n", np);
return ret;
}
if (num_configs)
reserve++;
/* Increase the number of maps to cover this group */
ret = pinctrl_utils_reserve_map(pctldev, map, &reserved_maps, num_maps,
reserve);
if (ret < 0)
goto out;
/* Associate the group with the function */
ret = pinctrl_utils_add_map_mux(pctldev, map, &reserved_maps, num_maps,
grp->name, grp->func);
if (ret < 0)
goto out;
if (num_configs) {
/* Associate the group's pin configuration with the group */
ret = pinctrl_utils_add_map_configs(pctldev, map,
&reserved_maps, num_maps, grp->name,
configs, num_configs,
PIN_MAP_TYPE_CONFIGS_GROUP);
if (ret < 0)
goto out;
}
dev_dbg(pctldev->dev, "maps: function %s group %s (%d pins)\n",
grp->func, grp->name, grp->npins);
out:
kfree(configs);
return ret;
}
static int rzn1_dt_node_to_map(struct pinctrl_dev *pctldev,
struct device_node *np,
struct pinctrl_map **map,
unsigned int *num_maps)
{
struct device_node *child;
int ret;
*map = NULL;
*num_maps = 0;
ret = rzn1_dt_node_to_map_one(pctldev, np, map, num_maps);
if (ret < 0)
return ret;
for_each_child_of_node(np, child) {
ret = rzn1_dt_node_to_map_one(pctldev, child, map, num_maps);
if (ret < 0)
return ret;
}
return 0;
}
static const struct pinctrl_ops rzn1_pctrl_ops = {
.get_groups_count = rzn1_get_groups_count,
.get_group_name = rzn1_get_group_name,
.get_group_pins = rzn1_get_group_pins,
.dt_node_to_map = rzn1_dt_node_to_map,
.dt_free_map = pinctrl_utils_free_map,
};
static int rzn1_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
{
struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
return ipctl->nfunctions;
}
static const char *rzn1_pmx_get_func_name(struct pinctrl_dev *pctldev,
unsigned int selector)
{
struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
return ipctl->functions[selector].name;
}
static int rzn1_pmx_get_groups(struct pinctrl_dev *pctldev,
unsigned int selector,
const char * const **groups,
unsigned int * const num_groups)
{
struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
*groups = ipctl->functions[selector].groups;
*num_groups = ipctl->functions[selector].num_groups;
return 0;
}
static int rzn1_set_mux(struct pinctrl_dev *pctldev, unsigned int selector,
unsigned int group)
{
struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
struct rzn1_pin_group *grp = &ipctl->groups[group];
unsigned int i, grp_pins = grp->npins;
dev_dbg(ipctl->dev, "set mux %s(%d) group %s(%d)\n",
ipctl->functions[selector].name, selector, grp->name, group);
rzn1_hw_set_lock(ipctl, LOCK_ALL, LOCK_ALL);
for (i = 0; i < grp_pins; i++)
rzn1_set_hw_pin_func(ipctl, grp->pins[i], grp->pin_ids[i], 0);
rzn1_hw_set_lock(ipctl, LOCK_ALL, 0);
return 0;
}
static const struct pinmux_ops rzn1_pmx_ops = {
.get_functions_count = rzn1_pmx_get_funcs_count,
.get_function_name = rzn1_pmx_get_func_name,
.get_function_groups = rzn1_pmx_get_groups,
.set_mux = rzn1_set_mux,
};
static int rzn1_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *config)
{
struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param = pinconf_to_config_param(*config);
const u32 reg_drive[4] = { 4, 6, 8, 12 };
u32 pull, drive, l1mux;
u32 l1, l2, arg = 0;
if (pin >= ARRAY_SIZE(ipctl->lev1->conf))
return -EINVAL;
l1 = readl(&ipctl->lev1->conf[pin]);
l1mux = l1 & RZN1_L1_FUNC_MASK;
pull = (l1 >> RZN1_L1_PIN_PULL) & 0x3;
drive = (l1 >> RZN1_L1_PIN_DRIVE_STRENGTH) & 0x3;
switch (param) {
case PIN_CONFIG_BIAS_PULL_UP:
if (pull != RZN1_L1_PIN_PULL_UP)
return -EINVAL;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
if (pull != RZN1_L1_PIN_PULL_DOWN)
return -EINVAL;
break;
case PIN_CONFIG_BIAS_DISABLE:
if (pull != RZN1_L1_PIN_PULL_NONE)
return -EINVAL;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
arg = reg_drive[drive];
break;
case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
l2 = readl(&ipctl->lev2->conf[pin]);
if (l1mux == RZN1_L1_FUNCTION_L2) {
if (l2 != 0)
return -EINVAL;
} else if (l1mux != RZN1_FUNC_HIGHZ) {
return -EINVAL;
}
break;
default:
return -ENOTSUPP;
}
*config = pinconf_to_config_packed(param, arg);
return 0;
}
static int rzn1_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned int num_configs)
{
struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param;
unsigned int i;
u32 l1, l1_cache;
u32 drv;
u32 arg;
if (pin >= ARRAY_SIZE(ipctl->lev1->conf))
return -EINVAL;
l1 = readl(&ipctl->lev1->conf[pin]);
l1_cache = l1;
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
switch (param) {
case PIN_CONFIG_BIAS_PULL_UP:
dev_dbg(ipctl->dev, "set pin %d pull up\n", pin);
l1 &= ~(0x3 << RZN1_L1_PIN_PULL);
l1 |= (RZN1_L1_PIN_PULL_UP << RZN1_L1_PIN_PULL);
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
dev_dbg(ipctl->dev, "set pin %d pull down\n", pin);
l1 &= ~(0x3 << RZN1_L1_PIN_PULL);
l1 |= (RZN1_L1_PIN_PULL_DOWN << RZN1_L1_PIN_PULL);
break;
case PIN_CONFIG_BIAS_DISABLE:
dev_dbg(ipctl->dev, "set pin %d bias off\n", pin);
l1 &= ~(0x3 << RZN1_L1_PIN_PULL);
l1 |= (RZN1_L1_PIN_PULL_NONE << RZN1_L1_PIN_PULL);
break;
case PIN_CONFIG_DRIVE_STRENGTH:
dev_dbg(ipctl->dev, "set pin %d drv %umA\n", pin, arg);
switch (arg) {
case 4:
drv = RZN1_L1_PIN_DRIVE_STRENGTH_4MA;
break;
case 6:
drv = RZN1_L1_PIN_DRIVE_STRENGTH_6MA;
break;
case 8:
drv = RZN1_L1_PIN_DRIVE_STRENGTH_8MA;
break;
case 12:
drv = RZN1_L1_PIN_DRIVE_STRENGTH_12MA;
break;
default:
dev_err(ipctl->dev,
"Drive strength %umA not supported\n",
arg);
return -EINVAL;
}
l1 &= ~(0x3 << RZN1_L1_PIN_DRIVE_STRENGTH);
l1 |= (drv << RZN1_L1_PIN_DRIVE_STRENGTH);
break;
case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
dev_dbg(ipctl->dev, "set pin %d High-Z\n", pin);
l1 &= ~RZN1_L1_FUNC_MASK;
l1 |= RZN1_FUNC_HIGHZ;
break;
default:
return -ENOTSUPP;
}
}
if (l1 != l1_cache) {
rzn1_hw_set_lock(ipctl, LOCK_LEVEL1, LOCK_LEVEL1);
writel(l1, &ipctl->lev1->conf[pin]);
rzn1_hw_set_lock(ipctl, LOCK_LEVEL1, 0);
}
return 0;
}
static int rzn1_pinconf_group_get(struct pinctrl_dev *pctldev,
unsigned int selector,
unsigned long *config)
{
struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
struct rzn1_pin_group *grp = &ipctl->groups[selector];
unsigned long old = 0;
unsigned int i;
dev_dbg(ipctl->dev, "group get %s selector:%u\n", grp->name, selector);
for (i = 0; i < grp->npins; i++) {
if (rzn1_pinconf_get(pctldev, grp->pins[i], config))
return -ENOTSUPP;
/* configs do not match between two pins */
if (i && (old != *config))
return -ENOTSUPP;
old = *config;
}
return 0;
}
static int rzn1_pinconf_group_set(struct pinctrl_dev *pctldev,
unsigned int selector,
unsigned long *configs,
unsigned int num_configs)
{
struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
struct rzn1_pin_group *grp = &ipctl->groups[selector];
unsigned int i;
int ret;
dev_dbg(ipctl->dev, "group set %s selector:%u configs:%p/%d\n",
grp->name, selector, configs, num_configs);
for (i = 0; i < grp->npins; i++) {
unsigned int pin = grp->pins[i];
ret = rzn1_pinconf_set(pctldev, pin, configs, num_configs);
if (ret)
return ret;
}
return 0;
}
static const struct pinconf_ops rzn1_pinconf_ops = {
.is_generic = true,
.pin_config_get = rzn1_pinconf_get,
.pin_config_set = rzn1_pinconf_set,
.pin_config_group_get = rzn1_pinconf_group_get,
.pin_config_group_set = rzn1_pinconf_group_set,
.pin_config_config_dbg_show = pinconf_generic_dump_config,
};
static struct pinctrl_desc rzn1_pinctrl_desc = {
.pctlops = &rzn1_pctrl_ops,
.pmxops = &rzn1_pmx_ops,
.confops = &rzn1_pinconf_ops,
.owner = THIS_MODULE,
};
static int rzn1_pinctrl_parse_groups(struct device_node *np,
struct rzn1_pin_group *grp,
struct rzn1_pinctrl *ipctl)
{
const __be32 *list;
unsigned int i;
int size;
dev_dbg(ipctl->dev, "%s: %s\n", __func__, np->name);
/* Initialise group */
grp->name = np->name;
/*
* The binding format is
* pinmux = <PIN_FUNC_ID CONFIG ...>,
* do sanity check and calculate pins number
*/
list = of_get_property(np, RZN1_PINS_PROP, &size);
if (!list) {
dev_err(ipctl->dev,
"no " RZN1_PINS_PROP " property in node %pOF\n", np);
return -EINVAL;
}
if (!size) {
dev_err(ipctl->dev, "Invalid " RZN1_PINS_PROP " in node %pOF\n",
np);
return -EINVAL;
}
grp->npins = size / sizeof(list[0]);
grp->pin_ids = devm_kmalloc_array(ipctl->dev,
grp->npins, sizeof(grp->pin_ids[0]),
GFP_KERNEL);
grp->pins = devm_kmalloc_array(ipctl->dev,
grp->npins, sizeof(grp->pins[0]),
GFP_KERNEL);
if (!grp->pin_ids || !grp->pins)
return -ENOMEM;
for (i = 0; i < grp->npins; i++) {
u32 pin_id = be32_to_cpu(*list++);
grp->pins[i] = pin_id & 0xff;
grp->pin_ids[i] = (pin_id >> 8) & 0x7f;
}
return grp->npins;
}
static int rzn1_pinctrl_count_function_groups(struct device_node *np)
{
struct device_node *child;
int count = 0;
if (of_property_count_u32_elems(np, RZN1_PINS_PROP) > 0)
count++;
for_each_child_of_node(np, child) {
if (of_property_count_u32_elems(child, RZN1_PINS_PROP) > 0)
count++;
}
return count;
}
static int rzn1_pinctrl_parse_functions(struct device_node *np,
struct rzn1_pinctrl *ipctl,
unsigned int index)
{
struct rzn1_pmx_func *func;
struct rzn1_pin_group *grp;
struct device_node *child;
unsigned int i = 0;
int ret;
func = &ipctl->functions[index];
/* Initialise function */
func->name = np->name;
func->num_groups = rzn1_pinctrl_count_function_groups(np);
if (func->num_groups == 0) {
dev_err(ipctl->dev, "no groups defined in %pOF\n", np);
return -EINVAL;
}
dev_dbg(ipctl->dev, "function %s has %d groups\n",
np->name, func->num_groups);
func->groups = devm_kmalloc_array(ipctl->dev,
func->num_groups, sizeof(char *),
GFP_KERNEL);
if (!func->groups)
return -ENOMEM;
if (of_property_count_u32_elems(np, RZN1_PINS_PROP) > 0) {
func->groups[i] = np->name;
grp = &ipctl->groups[ipctl->ngroups];
grp->func = func->name;
ret = rzn1_pinctrl_parse_groups(np, grp, ipctl);
if (ret < 0)
return ret;
i++;
ipctl->ngroups++;
}
for_each_child_of_node(np, child) {
func->groups[i] = child->name;
grp = &ipctl->groups[ipctl->ngroups];
grp->func = func->name;
ret = rzn1_pinctrl_parse_groups(child, grp, ipctl);
if (ret < 0)
return ret;
i++;
ipctl->ngroups++;
}
dev_dbg(ipctl->dev, "function %s parsed %u/%u groups\n",
np->name, i, func->num_groups);
return 0;
}
static int rzn1_pinctrl_probe_dt(struct platform_device *pdev,
struct rzn1_pinctrl *ipctl)
{
struct device_node *np = pdev->dev.of_node;
struct device_node *child;
unsigned int maxgroups = 0;
unsigned int nfuncs = 0;
unsigned int i = 0;
int ret;
nfuncs = of_get_child_count(np);
if (nfuncs <= 0)
return 0;
ipctl->nfunctions = nfuncs;
ipctl->functions = devm_kmalloc_array(&pdev->dev, nfuncs,
sizeof(*ipctl->functions),
GFP_KERNEL);
if (!ipctl->functions)
return -ENOMEM;
ipctl->ngroups = 0;
for_each_child_of_node(np, child)
maxgroups += rzn1_pinctrl_count_function_groups(child);
ipctl->groups = devm_kmalloc_array(&pdev->dev,
maxgroups,
sizeof(*ipctl->groups),
GFP_KERNEL);
if (!ipctl->groups)
return -ENOMEM;
for_each_child_of_node(np, child) {
ret = rzn1_pinctrl_parse_functions(child, ipctl, i++);
if (ret < 0)
return ret;
}
return 0;
}
static int rzn1_pinctrl_probe(struct platform_device *pdev)
{
struct rzn1_pinctrl *ipctl;
struct resource *res;
int ret;
/* Create state holders etc for this driver */
ipctl = devm_kzalloc(&pdev->dev, sizeof(*ipctl), GFP_KERNEL);
if (!ipctl)
return -ENOMEM;
ipctl->mdio_func[0] = -1;
ipctl->mdio_func[1] = -1;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
ipctl->lev1_protect_phys = (u32)res->start + 0x400;
ipctl->lev1 = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(ipctl->lev1))
return PTR_ERR(ipctl->lev1);
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
ipctl->lev2_protect_phys = (u32)res->start + 0x400;
ipctl->lev2 = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(ipctl->lev2))
return PTR_ERR(ipctl->lev2);
ipctl->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(ipctl->clk))
return PTR_ERR(ipctl->clk);
ret = clk_prepare_enable(ipctl->clk);
if (ret)
return ret;
ipctl->dev = &pdev->dev;
rzn1_pinctrl_desc.name = dev_name(&pdev->dev);
rzn1_pinctrl_desc.pins = rzn1_pins;
rzn1_pinctrl_desc.npins = ARRAY_SIZE(rzn1_pins);
ret = rzn1_pinctrl_probe_dt(pdev, ipctl);
if (ret) {
dev_err(&pdev->dev, "fail to probe dt properties\n");
goto err_clk;
}
platform_set_drvdata(pdev, ipctl);
ret = devm_pinctrl_register_and_init(&pdev->dev, &rzn1_pinctrl_desc,
ipctl, &ipctl->pctl);
if (ret) {
dev_err(&pdev->dev, "could not register rzn1 pinctrl driver\n");
goto err_clk;
}
ret = pinctrl_enable(ipctl->pctl);
if (ret)
goto err_clk;
dev_info(&pdev->dev, "probed\n");
return 0;
err_clk:
clk_disable_unprepare(ipctl->clk);
return ret;
}
static int rzn1_pinctrl_remove(struct platform_device *pdev)
{
struct rzn1_pinctrl *ipctl = platform_get_drvdata(pdev);
clk_disable_unprepare(ipctl->clk);
return 0;
}
static const struct of_device_id rzn1_pinctrl_match[] = {
{ .compatible = "renesas,rzn1-pinctrl", },
{}
};
MODULE_DEVICE_TABLE(of, rzn1_pinctrl_match);
static struct platform_driver rzn1_pinctrl_driver = {
.probe = rzn1_pinctrl_probe,
.remove = rzn1_pinctrl_remove,
.driver = {
.name = "rzn1-pinctrl",
.of_match_table = rzn1_pinctrl_match,
},
};
static int __init _pinctrl_drv_register(void)
{
return platform_driver_register(&rzn1_pinctrl_driver);
}
subsys_initcall(_pinctrl_drv_register);
MODULE_AUTHOR("Phil Edworthy <phil.edworthy@renesas.com>");
MODULE_DESCRIPTION("Renesas RZ/N1 pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -1022,14 +1022,14 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
vals[found].reg = pcs->base + offset;
vals[found].val = pinctrl_spec.args[1];
dev_dbg(pcs->dev, "%s index: 0x%x value: 0x%x\n",
pinctrl_spec.np->name, offset, pinctrl_spec.args[1]);
dev_dbg(pcs->dev, "%pOFn index: 0x%x value: 0x%x\n",
pinctrl_spec.np, offset, pinctrl_spec.args[1]);
pin = pcs_get_pin_by_offset(pcs, offset);
if (pin < 0) {
dev_err(pcs->dev,
"could not add functions for %s %ux\n",
np->name, offset);
"could not add functions for %pOFn %ux\n",
np, offset);
break;
}
pins[found++] = pin;
@ -1135,8 +1135,8 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
val = pinctrl_spec.args[1];
mask = pinctrl_spec.args[2];
dev_dbg(pcs->dev, "%s index: 0x%x value: 0x%x mask: 0x%x\n",
pinctrl_spec.np->name, offset, val, mask);
dev_dbg(pcs->dev, "%pOFn index: 0x%x value: 0x%x mask: 0x%x\n",
pinctrl_spec.np, offset, val, mask);
/* Parse pins in each row from LSB */
while (mask) {
@ -1148,8 +1148,8 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
if ((mask & mask_pos) == 0) {
dev_err(pcs->dev,
"Invalid mask for %s at 0x%x\n",
np->name, offset);
"Invalid mask for %pOFn at 0x%x\n",
np, offset);
break;
}
@ -1157,8 +1157,8 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
if (submask != mask_pos) {
dev_warn(pcs->dev,
"Invalid submask 0x%x for %s at 0x%x\n",
submask, np->name, offset);
"Invalid submask 0x%x for %pOFn at 0x%x\n",
submask, np, offset);
continue;
}
@ -1169,8 +1169,8 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
pin = pcs_get_pin_by_offset(pcs, offset);
if (pin < 0) {
dev_err(pcs->dev,
"could not add functions for %s %ux\n",
np->name, offset);
"could not add functions for %pOFn %ux\n",
np, offset);
break;
}
pins[found++] = pin + pin_num_from_lsb;
@ -1254,16 +1254,16 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev,
ret = pcs_parse_bits_in_pinctrl_entry(pcs, np_config, map,
num_maps, pgnames);
if (ret < 0) {
dev_err(pcs->dev, "no pins entries for %s\n",
np_config->name);
dev_err(pcs->dev, "no pins entries for %pOFn\n",
np_config);
goto free_pgnames;
}
} else {
ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map,
num_maps, pgnames);
if (ret < 0) {
dev_err(pcs->dev, "no pins entries for %s\n",
np_config->name);
dev_err(pcs->dev, "no pins entries for %pOFn\n",
np_config);
goto free_pgnames;
}
}

View File

@ -817,8 +817,8 @@ static int st_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
grp = st_pctl_find_group_by_name(info, np->name);
if (!grp) {
dev_err(info->dev, "unable to find group for node %s\n",
np->name);
dev_err(info->dev, "unable to find group for node %pOFn\n",
np);
return -EINVAL;
}
@ -1184,7 +1184,7 @@ static int st_pctl_dt_parse_groups(struct device_node *np,
if (pp->length / sizeof(__be32) >= OF_GPIO_ARGS_MIN) {
npins++;
} else {
pr_warn("Invalid st,pins in %s node\n", np->name);
pr_warn("Invalid st,pins in %pOFn node\n", np);
return -EINVAL;
}
}

View File

@ -114,6 +114,14 @@ config PINCTRL_MSM8998
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm MSM8998 platform.
config PINCTRL_QCS404
tristate "Qualcomm QCS404 pin controller driver"
depends on GPIOLIB && OF
select PINCTRL_MSM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
TLMM block found in the Qualcomm QCS404 platform.
config PINCTRL_QDF2XXX
tristate "Qualcomm Technologies QDF2xxx pin controller driver"
depends on GPIOLIB && ACPI
@ -147,6 +155,15 @@ config PINCTRL_QCOM_SSBI_PMIC
which are using SSBI for communication with SoC. Example PMIC's
devices are pm8058 and pm8921.
config PINCTRL_SDM660
tristate "Qualcomm Technologies Inc SDM660 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 SDM660 platform.
config PINCTRL_SDM845
tristate "Qualcomm Technologies Inc SDM845 pin controller driver"
depends on GPIOLIB && OF

View File

@ -13,10 +13,12 @@ obj-$(CONFIG_PINCTRL_MSM8916) += pinctrl-msm8916.o
obj-$(CONFIG_PINCTRL_MSM8994) += pinctrl-msm8994.o
obj-$(CONFIG_PINCTRL_MSM8996) += pinctrl-msm8996.o
obj-$(CONFIG_PINCTRL_MSM8998) += pinctrl-msm8998.o
obj-$(CONFIG_PINCTRL_QCS404) += pinctrl-qcs404.o
obj-$(CONFIG_PINCTRL_QDF2XXX) += pinctrl-qdf2xxx.o
obj-$(CONFIG_PINCTRL_MDM9615) += pinctrl-mdm9615.o
obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-gpio.o
obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-mpp.o
obj-$(CONFIG_PINCTRL_QCOM_SSBI_PMIC) += pinctrl-ssbi-gpio.o
obj-$(CONFIG_PINCTRL_QCOM_SSBI_PMIC) += pinctrl-ssbi-mpp.o
obj-$(CONFIG_PINCTRL_SDM660) += pinctrl-sdm660.o
obj-$(CONFIG_PINCTRL_SDM845) += pinctrl-sdm845.o

View File

@ -24,7 +24,7 @@
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/reboot.h>
@ -37,6 +37,7 @@
#include "../pinctrl-utils.h"
#define MAX_NR_GPIO 300
#define MAX_NR_TILES 4
#define PS_HOLD_OFFSET 0x820
/**
@ -52,7 +53,7 @@
* @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge
* detection.
* @soc; Reference to soc_data of platform specific data.
* @regs: Base address for the TLMM register map.
* @regs: Base addresses for the TLMM tiles.
*/
struct msm_pinctrl {
struct device *dev;
@ -70,9 +71,27 @@ struct msm_pinctrl {
DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO);
const struct msm_pinctrl_soc_data *soc;
void __iomem *regs;
void __iomem *regs[MAX_NR_TILES];
};
#define MSM_ACCESSOR(name) \
static u32 msm_readl_##name(struct msm_pinctrl *pctrl, \
const struct msm_pingroup *g) \
{ \
return readl(pctrl->regs[g->tile] + g->name##_reg); \
} \
static void msm_writel_##name(u32 val, struct msm_pinctrl *pctrl, \
const struct msm_pingroup *g) \
{ \
writel(val, pctrl->regs[g->tile] + g->name##_reg); \
}
MSM_ACCESSOR(ctl)
MSM_ACCESSOR(io)
MSM_ACCESSOR(intr_cfg)
MSM_ACCESSOR(intr_status)
MSM_ACCESSOR(intr_target)
static int msm_get_groups_count(struct pinctrl_dev *pctldev)
{
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
@ -166,21 +185,37 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
raw_spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->ctl_reg);
val = msm_readl_ctl(pctrl, g);
val &= ~mask;
val |= i << g->mux_bit;
writel(val, pctrl->regs + g->ctl_reg);
msm_writel_ctl(val, pctrl, g);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
return 0;
}
static int msm_pinmux_request_gpio(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset)
{
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
const struct msm_pingroup *g = &pctrl->soc->groups[offset];
/* No funcs? Probably ACPI so can't do anything here */
if (!g->nfuncs)
return 0;
/* For now assume function 0 is GPIO because it always is */
return msm_pinmux_set_mux(pctldev, g->funcs[0], offset);
}
static const struct pinmux_ops msm_pinmux_ops = {
.request = msm_pinmux_request,
.get_functions_count = msm_get_functions_count,
.get_function_name = msm_get_function_name,
.get_function_groups = msm_get_function_groups,
.gpio_request_enable = msm_pinmux_request_gpio,
.set_mux = msm_pinmux_set_mux,
};
@ -244,7 +279,7 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev,
if (ret < 0)
return ret;
val = readl(pctrl->regs + g->ctl_reg);
val = msm_readl_ctl(pctrl, g);
arg = (val >> bit) & mask;
/* Convert register value to pinconf value */
@ -283,7 +318,7 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev,
if (!arg)
return -EINVAL;
val = readl(pctrl->regs + g->io_reg);
val = msm_readl_io(pctrl, g);
arg = !!(val & BIT(g->in_bit));
break;
case PIN_CONFIG_INPUT_ENABLE:
@ -357,12 +392,12 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev,
case PIN_CONFIG_OUTPUT:
/* set output value */
raw_spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->io_reg);
val = msm_readl_io(pctrl, g);
if (arg)
val |= BIT(g->out_bit);
else
val &= ~BIT(g->out_bit);
writel(val, pctrl->regs + g->io_reg);
msm_writel_io(val, pctrl, g);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
/* enable output */
@ -385,10 +420,10 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev,
}
raw_spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->ctl_reg);
val = msm_readl_ctl(pctrl, g);
val &= ~(mask << bit);
val |= arg << bit;
writel(val, pctrl->regs + g->ctl_reg);
msm_writel_ctl(val, pctrl, g);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
}
@ -412,9 +447,9 @@ static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
raw_spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->ctl_reg);
val = msm_readl_ctl(pctrl, g);
val &= ~BIT(g->oe_bit);
writel(val, pctrl->regs + g->ctl_reg);
msm_writel_ctl(val, pctrl, g);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
@ -432,16 +467,16 @@ static int msm_gpio_direction_output(struct gpio_chip *chip, unsigned offset, in
raw_spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->io_reg);
val = msm_readl_io(pctrl, g);
if (value)
val |= BIT(g->out_bit);
else
val &= ~BIT(g->out_bit);
writel(val, pctrl->regs + g->io_reg);
msm_writel_io(val, pctrl, g);
val = readl(pctrl->regs + g->ctl_reg);
val = msm_readl_ctl(pctrl, g);
val |= BIT(g->oe_bit);
writel(val, pctrl->regs + g->ctl_reg);
msm_writel_ctl(val, pctrl, g);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
@ -456,7 +491,7 @@ static int msm_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
g = &pctrl->soc->groups[offset];
val = readl(pctrl->regs + g->ctl_reg);
val = msm_readl_ctl(pctrl, g);
/* 0 = output, 1 = input */
return val & BIT(g->oe_bit) ? 0 : 1;
@ -470,7 +505,7 @@ static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
g = &pctrl->soc->groups[offset];
val = readl(pctrl->regs + g->io_reg);
val = msm_readl_io(pctrl, g);
return !!(val & BIT(g->in_bit));
}
@ -485,12 +520,12 @@ static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
raw_spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->io_reg);
val = msm_readl_io(pctrl, g);
if (value)
val |= BIT(g->out_bit);
else
val &= ~BIT(g->out_bit);
writel(val, pctrl->regs + g->io_reg);
msm_writel_io(val, pctrl, g);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
}
@ -530,8 +565,8 @@ static void msm_gpio_dbg_show_one(struct seq_file *s,
return;
g = &pctrl->soc->groups[offset];
ctl_reg = readl(pctrl->regs + g->ctl_reg);
io_reg = readl(pctrl->regs + g->io_reg);
ctl_reg = msm_readl_ctl(pctrl, g);
io_reg = msm_readl_io(pctrl, g);
is_out = !!(ctl_reg & BIT(g->oe_bit));
func = (ctl_reg >> g->mux_bit) & 7;
@ -606,14 +641,14 @@ static void msm_gpio_update_dual_edge_pos(struct msm_pinctrl *pctrl,
unsigned pol;
do {
val = readl(pctrl->regs + g->io_reg) & BIT(g->in_bit);
val = msm_readl_io(pctrl, g) & BIT(g->in_bit);
pol = readl(pctrl->regs + g->intr_cfg_reg);
pol = msm_readl_intr_cfg(pctrl, g);
pol ^= BIT(g->intr_polarity_bit);
writel(pol, pctrl->regs + g->intr_cfg_reg);
msm_writel_intr_cfg(val, pctrl, g);
val2 = readl(pctrl->regs + g->io_reg) & BIT(g->in_bit);
intstat = readl(pctrl->regs + g->intr_status_reg);
val2 = msm_readl_io(pctrl, g) & BIT(g->in_bit);
intstat = msm_readl_intr_status(pctrl, g);
if (intstat || (val == val2))
return;
} while (loop_limit-- > 0);
@ -633,7 +668,7 @@ static void msm_gpio_irq_mask(struct irq_data *d)
raw_spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->intr_cfg_reg);
val = msm_readl_intr_cfg(pctrl, g);
/*
* There are two bits that control interrupt forwarding to the CPU. The
* RAW_STATUS_EN bit causes the level or edge sensed on the line to be
@ -658,7 +693,7 @@ static void msm_gpio_irq_mask(struct irq_data *d)
val &= ~BIT(g->intr_raw_status_bit);
val &= ~BIT(g->intr_enable_bit);
writel(val, pctrl->regs + g->intr_cfg_reg);
msm_writel_intr_cfg(val, pctrl, g);
clear_bit(d->hwirq, pctrl->enabled_irqs);
@ -677,10 +712,10 @@ static void msm_gpio_irq_unmask(struct irq_data *d)
raw_spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->intr_cfg_reg);
val = msm_readl_intr_cfg(pctrl, g);
val |= BIT(g->intr_raw_status_bit);
val |= BIT(g->intr_enable_bit);
writel(val, pctrl->regs + g->intr_cfg_reg);
msm_writel_intr_cfg(val, pctrl, g);
set_bit(d->hwirq, pctrl->enabled_irqs);
@ -699,12 +734,12 @@ static void msm_gpio_irq_ack(struct irq_data *d)
raw_spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->intr_status_reg);
val = msm_readl_intr_status(pctrl, g);
if (g->intr_ack_high)
val |= BIT(g->intr_status_bit);
else
val &= ~BIT(g->intr_status_bit);
writel(val, pctrl->regs + g->intr_status_reg);
msm_writel_intr_status(val, pctrl, g);
if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
msm_gpio_update_dual_edge_pos(pctrl, g, d);
@ -733,17 +768,17 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
clear_bit(d->hwirq, pctrl->dual_edge_irqs);
/* Route interrupts to application cpu */
val = readl(pctrl->regs + g->intr_target_reg);
val = msm_readl_intr_target(pctrl, g);
val &= ~(7 << g->intr_target_bit);
val |= g->intr_target_kpss_val << g->intr_target_bit;
writel(val, pctrl->regs + g->intr_target_reg);
msm_writel_intr_target(val, pctrl, g);
/* Update configuration for gpio.
* RAW_STATUS_EN is left on for all gpio irqs. Due to the
* internal circuitry of TLMM, toggling the RAW_STATUS
* could cause the INTR_STATUS to be set for EDGE interrupts.
*/
val = readl(pctrl->regs + g->intr_cfg_reg);
val = msm_readl_intr_cfg(pctrl, g);
val |= BIT(g->intr_raw_status_bit);
if (g->intr_detection_width == 2) {
val &= ~(3 << g->intr_detection_bit);
@ -791,7 +826,7 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
} else {
BUG();
}
writel(val, pctrl->regs + g->intr_cfg_reg);
msm_writel_intr_cfg(val, pctrl, g);
if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
msm_gpio_update_dual_edge_pos(pctrl, g, d);
@ -821,6 +856,41 @@ static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
return 0;
}
static int msm_gpio_irq_reqres(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
int ret;
if (!try_module_get(gc->owner))
return -ENODEV;
ret = msm_pinmux_request_gpio(pctrl->pctrl, NULL, d->hwirq);
if (ret)
goto out;
msm_gpio_direction_input(gc, d->hwirq);
if (gpiochip_lock_as_irq(gc, d->hwirq)) {
dev_err(gc->parent,
"unable to lock HW IRQ %lu for IRQ\n",
d->hwirq);
ret = -EINVAL;
goto out;
}
return 0;
out:
module_put(gc->owner);
return ret;
}
static void msm_gpio_irq_relres(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
gpiochip_unlock_as_irq(gc, d->hwirq);
module_put(gc->owner);
}
static void msm_gpio_irq_handler(struct irq_desc *desc)
{
struct gpio_chip *gc = irq_desc_get_handler_data(desc);
@ -840,7 +910,7 @@ static void msm_gpio_irq_handler(struct irq_desc *desc)
*/
for_each_set_bit(i, pctrl->enabled_irqs, pctrl->chip.ngpio) {
g = &pctrl->soc->groups[i];
val = readl(pctrl->regs + g->intr_status_reg);
val = msm_readl_intr_status(pctrl, g);
if (val & BIT(g->intr_status_bit)) {
irq_pin = irq_find_mapping(gc->irq.domain, i);
generic_handle_irq(irq_pin);
@ -919,6 +989,8 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
pctrl->irq_chip.irq_ack = msm_gpio_irq_ack;
pctrl->irq_chip.irq_set_type = msm_gpio_irq_set_type;
pctrl->irq_chip.irq_set_wake = msm_gpio_irq_set_wake;
pctrl->irq_chip.irq_request_resources = msm_gpio_irq_reqres;
pctrl->irq_chip.irq_release_resources = msm_gpio_irq_relres;
ret = gpiochip_add_data(&pctrl->chip, pctrl);
if (ret) {
@ -975,7 +1047,7 @@ static int msm_ps_hold_restart(struct notifier_block *nb, unsigned long action,
{
struct msm_pinctrl *pctrl = container_of(nb, struct msm_pinctrl, restart_nb);
writel(0, pctrl->regs + PS_HOLD_OFFSET);
writel(0, pctrl->regs[0] + PS_HOLD_OFFSET);
mdelay(1000);
return NOTIFY_DONE;
}
@ -1011,6 +1083,7 @@ int msm_pinctrl_probe(struct platform_device *pdev,
struct msm_pinctrl *pctrl;
struct resource *res;
int ret;
int i;
pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
if (!pctrl)
@ -1022,10 +1095,20 @@ int msm_pinctrl_probe(struct platform_device *pdev,
raw_spin_lock_init(&pctrl->lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pctrl->regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(pctrl->regs))
return PTR_ERR(pctrl->regs);
if (soc_data->tiles) {
for (i = 0; i < soc_data->ntiles; i++) {
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
soc_data->tiles[i]);
pctrl->regs[i] = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(pctrl->regs[i]))
return PTR_ERR(pctrl->regs[i]);
}
} else {
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]);
}
msm_pinctrl_setup_pm_reset(pctrl);

View File

@ -76,6 +76,8 @@ struct msm_pingroup {
u32 intr_status_reg;
u32 intr_target_reg;
unsigned int tile:2;
unsigned mux_bit:5;
unsigned pull_bit:5;
@ -117,6 +119,8 @@ struct msm_pinctrl_soc_data {
unsigned ngroups;
unsigned ngpios;
bool pull_no_keeper;
const char *const *tiles;
unsigned int ntiles;
};
int msm_pinctrl_probe(struct platform_device *pdev,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@
* GNU General Public License for more details.
*/
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>

View File

@ -11,7 +11,7 @@
* GNU General Public License for more details.
*/
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
@ -319,6 +319,8 @@ static int pmic_mpp_set_mux(struct pinctrl_dev *pctldev, unsigned function,
pad->function = function;
ret = pmic_mpp_write_mode_ctl(state, pad);
if (ret < 0)
return ret;
val = pad->is_enabled << PMIC_MPP_REG_MASTER_EN_SHIFT;
@ -343,13 +345,12 @@ static int pmic_mpp_config_get(struct pinctrl_dev *pctldev,
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
arg = pad->pullup == PMIC_MPP_PULL_UP_OPEN;
if (pad->pullup != PMIC_MPP_PULL_UP_OPEN)
return -EINVAL;
arg = 1;
break;
case PIN_CONFIG_BIAS_PULL_UP:
switch (pad->pullup) {
case PMIC_MPP_PULL_UP_OPEN:
arg = 0;
break;
case PMIC_MPP_PULL_UP_0P6KOHM:
arg = 600;
break;
@ -364,13 +365,17 @@ static int pmic_mpp_config_get(struct pinctrl_dev *pctldev,
}
break;
case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
arg = !pad->is_enabled;
if (pad->is_enabled)
return -EINVAL;
arg = 1;
break;
case PIN_CONFIG_POWER_SOURCE:
arg = pad->power_source;
break;
case PIN_CONFIG_INPUT_ENABLE:
arg = pad->input_enabled;
if (!pad->input_enabled)
return -EINVAL;
arg = 1;
break;
case PIN_CONFIG_OUTPUT:
arg = pad->out_value;
@ -382,7 +387,9 @@ static int pmic_mpp_config_get(struct pinctrl_dev *pctldev,
arg = pad->amux_input;
break;
case PMIC_MPP_CONF_PAIRED:
arg = pad->paired;
if (!pad->paired)
return -EINVAL;
arg = 1;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
arg = pad->drive_strength;
@ -455,7 +462,7 @@ static int pmic_mpp_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
pad->dtest = arg;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
arg = pad->drive_strength;
pad->drive_strength = arg;
break;
case PMIC_MPP_CONF_AMUX_ROUTE:
if (arg >= PMIC_MPP_AMUX_ROUTE_ABUS4)
@ -502,6 +509,10 @@ static int pmic_mpp_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
if (ret < 0)
return ret;
ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_SINK_CTL, pad->drive_strength);
if (ret < 0)
return ret;
val = pad->is_enabled << PMIC_MPP_REG_MASTER_EN_SHIFT;
return pmic_mpp_write(state, pad, PMIC_MPP_REG_EN_CTL, val);

View File

@ -20,7 +20,7 @@
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/slab.h>
#include <linux/regmap.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
@ -260,22 +260,32 @@ static int pm8xxx_pin_config_get(struct pinctrl_dev *pctldev,
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
arg = pin->bias == PM8XXX_GPIO_BIAS_NP;
if (pin->bias != PM8XXX_GPIO_BIAS_NP)
return -EINVAL;
arg = 1;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
arg = pin->bias == PM8XXX_GPIO_BIAS_PD;
if (pin->bias != PM8XXX_GPIO_BIAS_PD)
return -EINVAL;
arg = 1;
break;
case PIN_CONFIG_BIAS_PULL_UP:
arg = pin->bias <= PM8XXX_GPIO_BIAS_PU_1P5_30;
if (pin->bias > PM8XXX_GPIO_BIAS_PU_1P5_30)
return -EINVAL;
arg = 1;
break;
case PM8XXX_QCOM_PULL_UP_STRENGTH:
arg = pin->pull_up_strength;
break;
case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
arg = pin->disable;
if (!pin->disable)
return -EINVAL;
arg = 1;
break;
case PIN_CONFIG_INPUT_ENABLE:
arg = pin->mode == PM8XXX_GPIO_MODE_INPUT;
if (pin->mode != PM8XXX_GPIO_MODE_INPUT)
return -EINVAL;
arg = 1;
break;
case PIN_CONFIG_OUTPUT:
if (pin->mode & PM8XXX_GPIO_MODE_OUTPUT)
@ -290,10 +300,14 @@ static int pm8xxx_pin_config_get(struct pinctrl_dev *pctldev,
arg = pin->output_strength;
break;
case PIN_CONFIG_DRIVE_PUSH_PULL:
arg = !pin->open_drain;
if (pin->open_drain)
return -EINVAL;
arg = 1;
break;
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
arg = pin->open_drain;
if (!pin->open_drain)
return -EINVAL;
arg = 1;
break;
default:
return -EINVAL;

View File

@ -20,7 +20,7 @@
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/slab.h>
#include <linux/regmap.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>

View File

@ -20,7 +20,7 @@
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/irqdomain.h>
#include <linux/of_device.h>
#include <linux/spinlock.h>

View File

@ -19,7 +19,7 @@
#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/machine.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
/**
* enum pincfg_type - possible pin configuration types supported.

Some files were not shown because too many files have changed in this diff Show More