1
0
Fork 0

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

Core:
 
 - The documentation is moved over to RST.
 - We now have agreed bindings for enabling input and output
   buffers without actually enabling input and/or output on a
   pin. We are chiseling out some details of pin control
   electronics.
 
 New drivers:
 
 - ZTE ZX
 - Renesas RZA1
 - MIPS Ingenic JZ47xx: also switch over existing drivers in the
   tree to use this pin controller and consolidate earlier
   spread out code.
 - Microschip MCP23S08: this driver is migrated from the GPIO
   subsystem and totally rewritten to use proper pin control.
   All users are switched over.
 
 New subdrivers:
 
 - Renesas R8A7743 and R8A7745.
 - Allwinner Sunxi A83T R_PIO.
 - Marvell MVEBU Armada CP110 and AP806.
 - Intel Cannon Lake PCH.
 - Qualcomm IPQ8074.
 
 Notable improvements:
 
 - IRQ support on the Marvell MVEBU Armada 37xx.
 - Meson driver supports HDMI CEC, AO, I2S, SPDIF and PWM.
 - Rockchip driver now supports iomux-route switching for
   RK3228, RK3328 and RK3399.
 - Rockchip A10 and A20 are merged into a single driver.
 - STM32 has improved GPIO support.
 - Samsung Exynos drivers are split per ARMv7 and ARMv8.
 - Marvell MVEBU is converted to use regmap for register
   access.
 
 Maintenance:
 
 - Several Renesas SH-PFC refactorings and updates.
 - Serious code size cut for Mediatek MT7623.
 - Misc janitorial and MAINTAINERS fixes.
 -----BEGIN PGP SIGNATURE-----
 
 iQIcBAABAgAGBQJZXeUhAAoJEEEQszewGV1zcl8QAMZ6To2JBQeK0Qi+pik9ZbW7
 CvnIFT7E4X45tstwFNKIgdQ1C/IcfzKpPSUDRUqi2nWJiWcuYgn3wQwQ5qbkGtaG
 vne0KVChgFGkT2SwycUZy11JxuP75U73e27BwAruxHhwWo5PesUOjjkmUtMqdbNQ
 VAwx6KoCBx1VBlb0uscbSSqFyAspdyeAHPEvSj4IpsqRZzT7YFqDm4C+uTnwavPx
 ZLoTji0HCpPIAo4C8JUAvweWbpxMC1IMdfm9jRkZ4rR/gTFQXvK+9ssI6lxSK6a6
 RiCJaAE6wQHKYm4LL0pGbW+aMGWRRRp8MERNmg8NgnWONcfCxYowoOYeYLeqPhAg
 kWkFHlmjpfo/A79V6tmN32vCpeQd34XGCetMpI93TuZ42olniD2Puv6RscVaSP3T
 3mIqydX9BY8iAviyMaLcHQeChaNdhLQi+AVjrn1VQjdkWn0C7uR++JznsyaxaI+S
 cVadl6k8H393R1Qdvh3JdoL0owsntQxWVWCbR6fyAZTHHiLGEyvL1ceO/rbpSRrn
 c8Ghk5s7f3DFltn7yWiV4k3KVhDPb5iK2dYP9uGCgqbigHWqlcB5PanRu1aGSFov
 h/1VFEMagNCXQCrgGcIfmkEiwW3SqUsFaaoMLhlYpNb/ON3ihGgsZYiczWSj8l4L
 yfCOoszuEsVkV1dFNAjA
 =dUFL
 -----END PGP SIGNATURE-----

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

Pull pin control updates from Linus Walleij:
 "This is the big bulk of pin control changes for the v4.13 series:

  Core:
   - The documentation is moved over to RST.
   - We now have agreed bindings for enabling input and output buffers
     without actually enabling input and/or output on a pin. We are
     chiseling out some details of pin control electronics.

  New drivers:
   - ZTE ZX
   - Renesas RZA1
   - MIPS Ingenic JZ47xx: also switch over existing drivers in the tree
     to use this pin controller and consolidate earlier spread out code.
   - Microschip MCP23S08: this driver is migrated from the GPIO
     subsystem and totally rewritten to use proper pin control. All
     users are switched over.

  New subdrivers:
   - Renesas R8A7743 and R8A7745.
   - Allwinner Sunxi A83T R_PIO.
   - Marvell MVEBU Armada CP110 and AP806.
   - Intel Cannon Lake PCH.
   - Qualcomm IPQ8074.

  Notable improvements:
   - IRQ support on the Marvell MVEBU Armada 37xx.
   - Meson driver supports HDMI CEC, AO, I2S, SPDIF and PWM.
   - Rockchip driver now supports iomux-route switching for RK3228,
     RK3328 and RK3399.
   - Rockchip A10 and A20 are merged into a single driver.
   - STM32 has improved GPIO support.
   - Samsung Exynos drivers are split per ARMv7 and ARMv8.
   - Marvell MVEBU is converted to use regmap for register access.

  Maintenance:
   - Several Renesas SH-PFC refactorings and updates.
   - Serious code size cut for Mediatek MT7623.
   - Misc janitorial and MAINTAINERS fixes"

* tag 'pinctrl-v4.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (137 commits)
  pinctrl: samsung: Remove bogus irq_[un]mask from resource management
  pinctrl: rza1: make structures rza1_gpiochip_template and rza1_pinmux_ops static
  pinctrl: rza1: Remove unneeded wrong check for wrong variable
  pinctrl: qcom: Add ipq8074 pinctrl driver
  pinctrl: freescale: imx7d: make of_device_ids const.
  pinctrl: DT: extend the pinmux property to support integers array
  pinctrl: generic: Add output-enable property
  pinctrl: armada-37xx: Fix number of pin in sdio_sb
  pinctrl: armada-37xx: Fix uart2 group selection register mask
  pinctrl: bcm2835: Avoid warning from __irq_do_set_handler
  pinctrl: sh-pfc: r8a7795: Add PWM support
  MAINTAINERS: Add Qualcomm pinctrl drivers section
  arm: dts: dt-bindings: Add Renesas RZ/A1 pinctrl header
  dt-bindings: pinctrl: Add RZ/A1 bindings doc
  pinctrl: Renesas RZ/A1 pin and gpio controller
  pinctrl: sh-pfc: r8a7792: Add SCIF1 and SCIF2 pin groups
  pinctrl.txt: move it to the driver-api book
  pinctrl: ingenic: checking for NULL instead of IS_ERR()
  pinctrl: uniphier: fix WARN_ON() of pingroups dump on LD20
  pinctrl: uniphier: fix WARN_ON() of pingroups dump on LD11
  ...
hifive-unleashed-5.1
Linus Torvalds 2017-07-06 11:38:59 -07:00
commit ac7b75966c
123 changed files with 14135 additions and 8605 deletions

View File

@ -0,0 +1,46 @@
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

@ -20,8 +20,10 @@ Required properties:
"allwinner,sun9i-a80-pinctrl"
"allwinner,sun9i-a80-r-pinctrl"
"allwinner,sun8i-a83t-pinctrl"
"allwinner,sun8i-a83t-r-pinctrl"
"allwinner,sun8i-h3-pinctrl"
"allwinner,sun8i-h3-r-pinctrl"
"allwinner,sun8i-r40-pinctrl"
"allwinner,sun50i-a64-pinctrl"
"allwinner,sun50i-a64-r-pinctrl"
"allwinner,sun50i-h5-pinctrl"

View File

@ -0,0 +1,41 @@
Ingenic jz47xx pin controller
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".
For the jz47xx SoCs, pin control is tightly bound with GPIO ports. All pins may
be used as GPIOs, multiplexed device functions are configured within the
GPIO port configuration registers and it is typical to refer to pins using the
naming scheme "PxN" where x is a character identifying the GPIO port with
which the pin is associated and N is an integer from 0 to 31 identifying the
pin within that GPIO port. For example PA0 is the first pin in GPIO port A, and
PB31 is the last pin in GPIO port B. The jz4740 contains 4 GPIO ports, PA to
PD, for a total of 128 pins. The jz4780 contains 6 GPIO ports, PA to PF, for a
total of 192 pins.
Required properties:
--------------------
- compatible: One of:
- "ingenic,jz4740-pinctrl"
- "ingenic,jz4770-pinctrl"
- "ingenic,jz4780-pinctrl"
- reg: Address range of the pinctrl registers.
GPIO sub-nodes
--------------
The pinctrl node can have optional sub-nodes for the Ingenic GPIO driver;
please refer to ../gpio/ingenic,gpio.txt.
Example:
--------
pinctrl: pin-controller@10010000 {
compatible = "ingenic,jz4740-pinctrl";
reg = <0x10010000 0x400>;
};

View File

@ -204,21 +204,22 @@ each single pin the number of required sub-nodes containing "pin" and
maintain.
For cases like this, the pin controller driver may use the pinmux helper
property, where the pin identifier is packed with mux configuration settings
in a single integer.
property, where the pin identifier is provided with mux configuration settings
in a pinmux group. A pinmux group consists of the pin identifier and mux
settings represented as a single integer or an array of integers.
The pinmux property accepts an array of integers, each of them describing
The pinmux property accepts an array of pinmux groups, each of them describing
a single pin multiplexing configuration.
pincontroller {
state_0_node_a {
pinmux = <PIN_ID_AND_MUX>, <PIN_ID_AND_MUX>, ...;
pinmux = <PINMUX_GROUP>, <PINMUX_GROUP>, ...;
};
};
Each individual pin controller driver bindings documentation shall specify
how those values (pin IDs and pin multiplexing configuration) are defined and
assembled together.
how pin IDs and pin multiplexing configuration are defined and assembled
together in a pinmux group.
== Generic pin configuration node content ==
@ -251,14 +252,20 @@ drive-push-pull - drive actively high and low
drive-open-drain - drive with open drain
drive-open-source - drive with open source
drive-strength - sink or source at most X mA
input-enable - enable input on pin (no effect on output)
input-disable - disable input on pin (no effect on output)
input-enable - enable input on pin (no effect on output, such as
enabling an input buffer)
input-disable - disable input on pin (no effect on output, such as
disabling an input buffer)
input-schmitt-enable - enable schmitt-trigger mode
input-schmitt-disable - disable schmitt-trigger mode
input-debounce - debounce mode with debound time X
power-source - select between different power supplies
low-power-enable - enable low power mode
low-power-disable - disable low power mode
output-disable - disable output on a pin (such as disable an output
buffer)
output-enable - enable output on a pin without actively driving it
(such as enabling an output buffer)
output-low - set the pin to output mode with low level
output-high - set the pin to output mode with high level
slew-rate - set the slew rate
@ -300,7 +307,7 @@ arguments are described below.
- pinmux takes a list of pin IDs and mux settings as required argument. The
specific bindings for the hardware defines:
- How pin IDs and mux settings are defined and assembled together in a single
integer.
integer or an array of integers.
- bias-pull-up, -down and -pin-default take as optional argument on hardware
supporting it the pull strength in Ohm. bias-disable will disable the pull.

View File

@ -0,0 +1,85 @@
* ZTE ZX Pin Controller
The pin controller on ZTE ZX platforms is kinda of hybrid. It consists of
a main controller and an auxiliary one. For example, on ZX296718 SoC, the
main controller is TOP_PMM and the auxiliary one is AON_IOCFG. Both
controllers work together to control pin multiplexing and configuration in
the way illustrated as below.
GMII_RXD3 ---+
|
DVI1_HS ---+----------------------------- GMII_RXD3 (TOP pin)
|
BGPIO16 ---+ ^
| pinconf
^ |
| pinmux |
| |
TOP_PMM (main) AON_IOCFG (aux)
| | |
| pinmux | |
| pinmux v |
v | pinconf
KEY_ROW2 ---+ v
PORT1_LCD_TE ---+ |
| AGPIO10 ---+------ KEY_ROW2 (AON pin)
I2S0_DOUT3 ---+ |
|-----------------------+
PWM_OUT3 ---+
|
VGA_VS1 ---+
For most of pins like GMII_RXD3 in the figure, the pinmux function is
controlled by TOP_PMM block only, and this type of pins are meant by term
'TOP pins'. For pins like KEY_ROW2, the pinmux is controlled by both
TOP_PMM and AON_IOCFG blocks, as the available multiplexing functions for
the pin spread in both controllers. This type of pins are called 'AON pins'.
Though pinmux implementation is quite different, pinconf is same for both
types of pins. Both are controlled by auxiliary controller, i.e. AON_IOCFG
on ZX296718.
Required properties:
- compatible: should be "zte,zx296718-pmm".
- reg: the register physical address and length.
- zte,auxiliary-controller: phandle to the auxiliary pin controller which
implements pinmux for AON pins and pinconf for all pins.
The following pin configuration are supported. Please refer to
pinctrl-bindings.txt in this directory for more details of the common
pinctrl bindings used by client devices.
- bias-pull-up
- bias-pull-down
- drive-strength
- input-enable
- slew-rate
Examples:
iocfg: pin-controller@119000 {
compatible = "zte,zx296718-iocfg";
reg = <0x119000 0x1000>;
};
pmm: pin-controller@1462000 {
compatible = "zte,zx296718-pmm";
reg = <0x1462000 0x1000>;
zte,auxiliary-controller = <&iocfg>;
};
&pmm {
vga_pins: vga {
pins = "KEY_COL1", "KEY_COL2", "KEY_ROW1", "KEY_ROW2";
function = "VGA";
};
};
&vga {
pinctrl-names = "default";
pinctrl-0 = <&vga_pins>;
status = "okay";
};

View File

@ -0,0 +1,172 @@
Qualcomm Technologies, Inc. IPQ8074 TLMM block
This binding describes the Top Level Mode Multiplexer block found in the
IPQ8074 platform.
- compatible:
Usage: required
Value type: <string>
Definition: must be "qcom,ipq8074-pinctrl"
- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: the base address and size of the TLMM register space.
- 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>
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-gpio69
- 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:
atest_char, atest_char0, atest_char1, atest_char2,
atest_char3, audio_rxbclk, audio_rxd, audio_rxfsync,
audio_rxmclk, audio_txbclk, audio_txd, audio_txfsync,
audio_txmclk, blsp0_i2c, blsp0_spi, blsp0_uart, blsp1_i2c,
blsp1_spi, blsp1_uart, blsp2_i2c, blsp2_spi, blsp2_uart,
blsp3_i2c, blsp3_spi, blsp3_spi0, blsp3_spi1, blsp3_spi2,
blsp3_spi3, blsp3_uart, blsp4_i2c0, blsp4_i2c1, blsp4_spi0,
blsp4_spi1, blsp4_uart0, blsp4_uart1, blsp5_i2c, blsp5_spi,
blsp5_uart, burn0, burn1, cri_trng, cri_trng0, cri_trng1,
cxc0, cxc1, dbg_out, gcc_plltest, gcc_tlmm, gpio, ldo_en,
ldo_update, led0, led1, led2, mac0_sa0, mac0_sa1, mac1_sa0,
mac1_sa1, mac1_sa2, mac1_sa3, mac2_sa0, mac2_sa1, mdc,
mdio, pcie0_clk, pcie0_rst, pcie0_wake, pcie1_clk,
pcie1_rst, pcie1_wake, pcm_drx, pcm_dtx, pcm_fsync,
pcm_pclk, pcm_zsi0, pcm_zsi1, prng_rosc, pta1_0, pta1_1,
pta1_2, pta2_0, pta2_1, pta2_2, pwm0, pwm1, pwm2, pwm3,
qdss_cti_trig_in_a0, qdss_cti_trig_in_a1,
qdss_cti_trig_in_b0, qdss_cti_trig_in_b1,
qdss_cti_trig_out_a0, qdss_cti_trig_out_a1,
qdss_cti_trig_out_b0, qdss_cti_trig_out_b1,
qdss_traceclk_a, qdss_traceclk_b, qdss_tracectl_a,
qdss_tracectl_b, qdss_tracedata_a, qdss_tracedata_b,
qpic, rx0, rx1, rx2, sd_card, sd_write, tsens_max, wci2a,
wci2b, wci2c, wci2d
- 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.
- output-low:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
low.
- 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,ipq8074-pinctrl";
reg = <0x1000000 0x300000>;
interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
uart2: uart2-default {
mux {
pins = "gpio23", "gpio24";
function = "blsp4_uart1";
};
rx {
pins = "gpio23";
drive-strength = <4>;
bias-disable;
};
tx {
pins = "gpio24";
drive-strength = <2>;
bias-pull-up;
};
};
};

View File

@ -13,6 +13,8 @@ Required Properties:
- "renesas,pfc-emev2": for EMEV2 (EMMA Mobile EV2) compatible pin-controller.
- "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-r8a7745": for R8A7745 (RZ/G1E) compatible pin-controller.
- "renesas,pfc-r8a7778": for R8A7778 (R-Mobile 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,221 @@
Renesas RZ/A1 combined Pin and GPIO controller
The Renesas SoCs of the RZ/A1 family feature a combined Pin and GPIO controller,
named "Ports" in the hardware reference manual.
Pin multiplexing and GPIO configuration is performed on a per-pin basis
writing configuration values to per-port register sets.
Each "port" features up to 16 pins, each of them configurable for GPIO
function (port mode) or in alternate function mode.
Up to 8 different alternate function modes exist for each single pin.
Pin controller node
-------------------
Required properties:
- compatible
this shall be "renesas,r7s72100-ports".
- reg
address base and length of the memory area where the pin controller
hardware is mapped to.
Example:
Pin controller node for RZ/A1H SoC (r7s72100)
pinctrl: pin-controller@fcfe3000 {
compatible = "renesas,r7s72100-ports";
reg = <0xfcfe3000 0x4230>;
};
Sub-nodes
---------
The child nodes of the pin controller node describe a pin multiplexing
function or a GPIO controller alternatively.
- 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.
A few alternate function require special pin configuration flags to be
supplied along with the alternate function configuration number.
The hardware reference manual specifies when a pin function requires
"software IO driven" mode to be specified. To do so use the generic
properties from the <include/linux/pinctrl/pinconf_generic.h> header file
to instruct the pin controller to perform the desired pin configuration
operation.
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;
};
};
Use the second format when pins part of the same logical group need to have
different generic pin configuration flags applied.
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.
Helper macros to ease assembling the pin index from its position
(port where it sits on and pin number) and alternate function identifier
are provided by the pin controller header file at:
<include/dt-bindings/pinctrl/r7s72100-pinctrl.h>
Integers values in "pinmux" argument list are assembled as:
((PORT * 16 + PIN) | MUX_FUNC << 16)
Optional generic properties:
- input-enable:
enable input bufer for pins requiring software driven IO input
operations.
- output-high:
enable output buffer for pins requiring software driven IO output
operations. output-low can be used alternatively, as line value is
ignored by the driver.
The hardware reference manual specifies when a pin has to be configured to
work in bi-directional mode and when the IO direction has to be specified
by software. Bi-directional pins are managed by the pin controller driver
internally, while software driven IO direction has to be explicitly
selected when multiple options are available.
Example:
A serial communication interface with a TX output pin and an RX input pin.
&pinctrl {
scif2_pins: serial2 {
pinmux = <RZA1_PINMUX(3, 0, 6)>, <RZA1_PINMUX(3, 2, 4)>;
};
};
Pin #0 on port #3 is configured as alternate function #6.
Pin #2 on port #3 is configured as alternate function #4.
Example 2:
I2c master: both SDA and SCL pins need bi-directional operations
&pinctrl {
i2c2_pins: i2c2 {
pinmux = <RZA1_PINMUX(1, 4, 1)>, <RZA1_PINMUX(1, 5, 1)>;
};
};
Pin #4 on port #1 is configured as alternate function #1.
Pin #5 on port #1 is configured as alternate function #1.
Both need to work in bi-directional mode, the driver manages this internally.
Example 3:
Multi-function timer input and output compare pins.
Configure TIOC0A as software driven input and TIOC0B as software driven
output.
&pinctrl {
tioc0_pins: tioc0 {
tioc0_input_pins {
pinumx = <RZA1_PINMUX(4, 0, 2)>;
input-enable;
};
tioc0_output_pins {
pinmux = <RZA1_PINMUX(4, 1, 1)>;
output-enable;
};
};
};
&tioc0 {
...
pinctrl-0 = <&tioc0_pins>;
...
};
Pin #0 on port #4 is configured as alternate function #2 with IO direction
specified by software as input.
Pin #1 on port #4 is configured as alternate function #1 with IO direction
specified by software as output.
- GPIO controller sub-nodes:
Each port of the r7s72100 pin controller hardware is itself a GPIO controller.
Different SoCs have different numbers of available pins per port, but
generally speaking, each of them can be configured in GPIO ("port") mode
on this hardware.
Describe GPIO controllers using sub-nodes with the following properties.
Required properties:
- gpio-controller
empty property as defined by the GPIO bindings documentation.
- #gpio-cells
number of cells required to identify and configure a GPIO.
Shall be 2.
- gpio-ranges
Describes a GPIO controller specifying its specific pin base, the pin
base in the global pin numbering space, and the number of controlled
pins, as defined by the GPIO bindings documentation. Refer to
Documentation/devicetree/bindings/gpio/gpio.txt file for a more detailed
description.
Example:
A GPIO controller node, controlling 16 pins indexed from 0.
The GPIO controller base in the global pin indexing space is pin 48, thus
pins [0 - 15] on this controller map to pins [48 - 63] in the global pin
indexing space.
port3: gpio-3 {
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pinctrl 0 48 16>;
};
A device node willing to use pins controlled by this GPIO controller, shall
refer to it as follows:
led1 {
gpios = <&port3 10 GPIO_ACTIVE_LOW>;
};

View File

@ -43,6 +43,7 @@ available subsections can be seen below.
80211/index
uio-howto
firmware/index
pinctl
misc_devices
.. only:: subproject and html

View File

@ -1515,6 +1515,7 @@ F: arch/arm64/boot/dts/marvell/armada*
F: drivers/cpufreq/mvebu-cpufreq.c
F: drivers/irqchip/irq-armada-370-xp.c
F: drivers/irqchip/irq-mvebu-*
F: drivers/pinctrl/mvebu/
F: drivers/rtc/rtc-armada38x.c
ARM/Marvell Berlin SoC support
@ -1681,7 +1682,6 @@ F: arch/arm/mach-qcom/
F: arch/arm64/boot/dts/qcom/*
F: drivers/i2c/busses/i2c-qup.c
F: drivers/clk/qcom/
F: drivers/pinctrl/qcom/
F: drivers/dma/qcom/
F: drivers/soc/qcom/
F: drivers/spi/spi-qup.c
@ -10267,6 +10267,13 @@ M: Heikki Krogerus <heikki.krogerus@linux.intel.com>
S: Maintained
F: drivers/pinctrl/intel/
PIN CONTROLLER - QUALCOMM
M: Bjorn Andersson <bjorn.andersson@linaro.org>
S: Maintained
L: linux-arm-msm@vger.kernel.org
F: Documentation/devicetree/bindings/pinctrl/qcom,*.txt
F: drivers/pinctrl/qcom/
PIN CONTROLLER - RENESAS
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
M: Geert Uytterhoeven <geert+renesas@glider.be>

View File

@ -112,7 +112,7 @@ CONFIG_GPIO_SX150X=y
CONFIG_GPIO_74X164=y
CONFIG_GPIO_MAX7301=y
CONFIG_GPIO_MC33880=y
CONFIG_GPIO_MCP23S08=y
CONFIG_PINCTRL_MCP23S08=y
CONFIG_SENSORS_DS620=y
CONFIG_SENSORS_MAX6639=y
CONFIG_WATCHDOG=y

View File

@ -105,7 +105,7 @@ CONFIG_SPI=y
CONFIG_SPI_ADI_V3=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_MCP23S08=y
CONFIG_PINCTRL_MCP23S08=y
# CONFIG_HWMON is not set
CONFIG_WATCHDOG=y
CONFIG_BFIN_WDT=y

View File

@ -348,14 +348,14 @@ static struct platform_device bfin_i2s = {
};
#endif
#if IS_ENABLED(CONFIG_GPIO_MCP23S08)
#if IS_ENABLED(CONFIG_PINCTRL_MCP23S08)
#include <linux/spi/mcp23s08.h>
static const struct mcp23s08_platform_data bfin_mcp23s08_sys_gpio_info = {
.chip[0].is_present = true,
.spi_present_mask = BIT(0),
.base = 0x30,
};
static const struct mcp23s08_platform_data bfin_mcp23s08_usr_gpio_info = {
.chip[2].is_present = true,
.spi_present_mask = BIT(2),
.base = 0x38,
};
#endif
@ -423,7 +423,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
.mode = SPI_CPHA | SPI_CPOL,
},
#endif
#if IS_ENABLED(CONFIG_GPIO_MCP23S08)
#if IS_ENABLED(CONFIG_PINCTRL_MCP23S08)
{
.modalias = "mcp23s08",
.platform_data = &bfin_mcp23s08_sys_gpio_info,

View File

@ -1887,7 +1887,7 @@ static struct platform_device i2c_bfin_twi1_device = {
};
#endif
#if IS_ENABLED(CONFIG_GPIO_MCP23S08)
#if IS_ENABLED(CONFIG_PINCTRL_MCP23S08)
#include <linux/spi/mcp23s08.h>
static const struct mcp23s08_platform_data bfin_mcp23s08_soft_switch0 = {
.base = 120,
@ -1929,7 +1929,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info0[] = {
I2C_BOARD_INFO("ssm2602", 0x1b),
},
#endif
#if IS_ENABLED(CONFIG_GPIO_MCP23S08)
#if IS_ENABLED(CONFIG_PINCTRL_MCP23S08)
{
I2C_BOARD_INFO("mcp23017", 0x21),
.platform_data = (void *)&bfin_mcp23s08_soft_switch0

View File

@ -364,6 +364,7 @@ config MACH_INGENIC
select SYS_SUPPORTS_ZBOOT_UART16550
select DMA_NONCOHERENT
select IRQ_MIPS_CPU
select PINCTRL
select GPIOLIB
select COMMON_CLK
select GENERIC_IRQ_CHIP

View File

@ -29,18 +29,30 @@
&uart0 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pins_uart0>;
};
&uart1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pins_uart1>;
};
&uart3 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pins_uart2>;
};
&uart4 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pins_uart4>;
};
&nemc {
@ -61,6 +73,13 @@
ingenic,nemc-tAW = <15>;
ingenic,nemc-tSTRV = <100>;
/*
* Only CLE/ALE are needed for the devices that are connected, rather
* than the full address line set.
*/
pinctrl-names = "default";
pinctrl-0 = <&pins_nemc>;
nand@1 {
reg = <1>;
@ -69,6 +88,9 @@
nand-ecc-mode = "hw";
nand-on-flash-bbt;
pinctrl-names = "default";
pinctrl-0 = <&pins_nemc_cs1>;
partitions {
compatible = "fixed-partitions";
#address-cells = <2>;
@ -106,3 +128,41 @@
&bch {
status = "okay";
};
&pinctrl {
pins_uart0: uart0 {
function = "uart0";
groups = "uart0-data";
bias-disable;
};
pins_uart1: uart1 {
function = "uart1";
groups = "uart1-data";
bias-disable;
};
pins_uart2: uart2 {
function = "uart2";
groups = "uart2-data", "uart2-hwflow";
bias-disable;
};
pins_uart4: uart4 {
function = "uart4";
groups = "uart4-data";
bias-disable;
};
pins_nemc: nemc {
function = "nemc";
groups = "nemc-data", "nemc-cle-ale", "nemc-rd-we", "nemc-frd-fwe";
bias-disable;
};
pins_nemc_cs1: nemc-cs1 {
function = "nemc-cs1";
groups = "nemc-cs1";
bias-disable;
};
};

View File

@ -55,6 +55,74 @@
clock-names = "rtc";
};
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>;
};
gpb: gpio@1 {
compatible = "ingenic,jz4740-gpio";
reg = <1>;
gpio-controller;
gpio-ranges = <&pinctrl 0 32 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <27>;
};
gpc: gpio@2 {
compatible = "ingenic,jz4740-gpio";
reg = <2>;
gpio-controller;
gpio-ranges = <&pinctrl 0 64 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <26>;
};
gpd: gpio@3 {
compatible = "ingenic,jz4740-gpio";
reg = <3>;
gpio-controller;
gpio-ranges = <&pinctrl 0 96 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <25>;
};
};
uart0: serial@10030000 {
compatible = "ingenic,jz4740-uart";
reg = <0x10030000 0x100>;

View File

@ -44,6 +44,104 @@
#clock-cells = <1>;
};
pinctrl: pin-controller@10010000 {
compatible = "ingenic,jz4780-pinctrl";
reg = <0x10010000 0x600>;
#address-cells = <1>;
#size-cells = <0>;
gpa: gpio@0 {
compatible = "ingenic,jz4780-gpio";
reg = <0>;
gpio-controller;
gpio-ranges = <&pinctrl 0 0 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <17>;
};
gpb: gpio@1 {
compatible = "ingenic,jz4780-gpio";
reg = <1>;
gpio-controller;
gpio-ranges = <&pinctrl 0 32 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <16>;
};
gpc: gpio@2 {
compatible = "ingenic,jz4780-gpio";
reg = <2>;
gpio-controller;
gpio-ranges = <&pinctrl 0 64 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <15>;
};
gpd: gpio@3 {
compatible = "ingenic,jz4780-gpio";
reg = <3>;
gpio-controller;
gpio-ranges = <&pinctrl 0 96 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <14>;
};
gpe: gpio@4 {
compatible = "ingenic,jz4780-gpio";
reg = <4>;
gpio-controller;
gpio-ranges = <&pinctrl 0 128 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <13>;
};
gpf: gpio@5 {
compatible = "ingenic,jz4780-gpio";
reg = <5>;
gpio-controller;
gpio-ranges = <&pinctrl 0 160 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <12>;
};
};
uart0: serial@10030000 {
compatible = "ingenic,jz4780-uart";
reg = <0x10030000 0x100>;

View File

@ -17,3 +17,16 @@
&rtc_dev {
system-power-controller;
};
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&pins_uart0>;
};
&pinctrl {
pins_uart0: uart0 {
function = "uart0";
groups = "uart0-data";
bias-disable;
};
};

View File

@ -16,380 +16,9 @@
#ifndef _JZ_GPIO_H
#define _JZ_GPIO_H
#include <linux/types.h>
enum jz_gpio_function {
JZ_GPIO_FUNC_NONE,
JZ_GPIO_FUNC1,
JZ_GPIO_FUNC2,
JZ_GPIO_FUNC3,
};
/*
Usually a driver for a SoC component has to request several gpio pins and
configure them as function pins.
jz_gpio_bulk_request can be used to ease this process.
Usually one would do something like:
static const struct jz_gpio_bulk_request i2c_pins[] = {
JZ_GPIO_BULK_PIN(I2C_SDA),
JZ_GPIO_BULK_PIN(I2C_SCK),
};
inside the probe function:
ret = jz_gpio_bulk_request(i2c_pins, ARRAY_SIZE(i2c_pins));
if (ret) {
...
inside the remove function:
jz_gpio_bulk_free(i2c_pins, ARRAY_SIZE(i2c_pins));
*/
struct jz_gpio_bulk_request {
int gpio;
const char *name;
enum jz_gpio_function function;
};
#define JZ_GPIO_BULK_PIN(pin) { \
.gpio = JZ_GPIO_ ## pin, \
.name = #pin, \
.function = JZ_GPIO_FUNC_ ## pin \
}
int jz_gpio_bulk_request(const struct jz_gpio_bulk_request *request, size_t num);
void jz_gpio_bulk_free(const struct jz_gpio_bulk_request *request, size_t num);
void jz_gpio_bulk_suspend(const struct jz_gpio_bulk_request *request, size_t num);
void jz_gpio_bulk_resume(const struct jz_gpio_bulk_request *request, size_t num);
void jz_gpio_enable_pullup(unsigned gpio);
void jz_gpio_disable_pullup(unsigned gpio);
int jz_gpio_set_function(int gpio, enum jz_gpio_function function);
int jz_gpio_port_direction_input(int port, uint32_t mask);
int jz_gpio_port_direction_output(int port, uint32_t mask);
void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask);
uint32_t jz_gpio_port_get_value(int port, uint32_t mask);
#define JZ_GPIO_PORTA(x) ((x) + 32 * 0)
#define JZ_GPIO_PORTB(x) ((x) + 32 * 1)
#define JZ_GPIO_PORTC(x) ((x) + 32 * 2)
#define JZ_GPIO_PORTD(x) ((x) + 32 * 3)
/* Port A function pins */
#define JZ_GPIO_MEM_DATA0 JZ_GPIO_PORTA(0)
#define JZ_GPIO_MEM_DATA1 JZ_GPIO_PORTA(1)
#define JZ_GPIO_MEM_DATA2 JZ_GPIO_PORTA(2)
#define JZ_GPIO_MEM_DATA3 JZ_GPIO_PORTA(3)
#define JZ_GPIO_MEM_DATA4 JZ_GPIO_PORTA(4)
#define JZ_GPIO_MEM_DATA5 JZ_GPIO_PORTA(5)
#define JZ_GPIO_MEM_DATA6 JZ_GPIO_PORTA(6)
#define JZ_GPIO_MEM_DATA7 JZ_GPIO_PORTA(7)
#define JZ_GPIO_MEM_DATA8 JZ_GPIO_PORTA(8)
#define JZ_GPIO_MEM_DATA9 JZ_GPIO_PORTA(9)
#define JZ_GPIO_MEM_DATA10 JZ_GPIO_PORTA(10)
#define JZ_GPIO_MEM_DATA11 JZ_GPIO_PORTA(11)
#define JZ_GPIO_MEM_DATA12 JZ_GPIO_PORTA(12)
#define JZ_GPIO_MEM_DATA13 JZ_GPIO_PORTA(13)
#define JZ_GPIO_MEM_DATA14 JZ_GPIO_PORTA(14)
#define JZ_GPIO_MEM_DATA15 JZ_GPIO_PORTA(15)
#define JZ_GPIO_MEM_DATA16 JZ_GPIO_PORTA(16)
#define JZ_GPIO_MEM_DATA17 JZ_GPIO_PORTA(17)
#define JZ_GPIO_MEM_DATA18 JZ_GPIO_PORTA(18)
#define JZ_GPIO_MEM_DATA19 JZ_GPIO_PORTA(19)
#define JZ_GPIO_MEM_DATA20 JZ_GPIO_PORTA(20)
#define JZ_GPIO_MEM_DATA21 JZ_GPIO_PORTA(21)
#define JZ_GPIO_MEM_DATA22 JZ_GPIO_PORTA(22)
#define JZ_GPIO_MEM_DATA23 JZ_GPIO_PORTA(23)
#define JZ_GPIO_MEM_DATA24 JZ_GPIO_PORTA(24)
#define JZ_GPIO_MEM_DATA25 JZ_GPIO_PORTA(25)
#define JZ_GPIO_MEM_DATA26 JZ_GPIO_PORTA(26)
#define JZ_GPIO_MEM_DATA27 JZ_GPIO_PORTA(27)
#define JZ_GPIO_MEM_DATA28 JZ_GPIO_PORTA(28)
#define JZ_GPIO_MEM_DATA29 JZ_GPIO_PORTA(29)
#define JZ_GPIO_MEM_DATA30 JZ_GPIO_PORTA(30)
#define JZ_GPIO_MEM_DATA31 JZ_GPIO_PORTA(31)
#define JZ_GPIO_FUNC_MEM_DATA0 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA1 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA2 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA3 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA4 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA5 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA6 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA7 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA8 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA9 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA10 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA11 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA12 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA13 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA14 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA15 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA16 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA17 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA18 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA19 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA20 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA21 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA22 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA23 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA24 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA25 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA26 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA27 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA28 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA29 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA30 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA31 JZ_GPIO_FUNC1
/* Port B function pins */
#define JZ_GPIO_MEM_ADDR0 JZ_GPIO_PORTB(0)
#define JZ_GPIO_MEM_ADDR1 JZ_GPIO_PORTB(1)
#define JZ_GPIO_MEM_ADDR2 JZ_GPIO_PORTB(2)
#define JZ_GPIO_MEM_ADDR3 JZ_GPIO_PORTB(3)
#define JZ_GPIO_MEM_ADDR4 JZ_GPIO_PORTB(4)
#define JZ_GPIO_MEM_ADDR5 JZ_GPIO_PORTB(5)
#define JZ_GPIO_MEM_ADDR6 JZ_GPIO_PORTB(6)
#define JZ_GPIO_MEM_ADDR7 JZ_GPIO_PORTB(7)
#define JZ_GPIO_MEM_ADDR8 JZ_GPIO_PORTB(8)
#define JZ_GPIO_MEM_ADDR9 JZ_GPIO_PORTB(9)
#define JZ_GPIO_MEM_ADDR10 JZ_GPIO_PORTB(10)
#define JZ_GPIO_MEM_ADDR11 JZ_GPIO_PORTB(11)
#define JZ_GPIO_MEM_ADDR12 JZ_GPIO_PORTB(12)
#define JZ_GPIO_MEM_ADDR13 JZ_GPIO_PORTB(13)
#define JZ_GPIO_MEM_ADDR14 JZ_GPIO_PORTB(14)
#define JZ_GPIO_MEM_ADDR15 JZ_GPIO_PORTB(15)
#define JZ_GPIO_MEM_ADDR16 JZ_GPIO_PORTB(16)
#define JZ_GPIO_LCD_CLS JZ_GPIO_PORTB(17)
#define JZ_GPIO_LCD_SPL JZ_GPIO_PORTB(18)
#define JZ_GPIO_MEM_DCS JZ_GPIO_PORTB(19)
#define JZ_GPIO_MEM_RAS JZ_GPIO_PORTB(20)
#define JZ_GPIO_MEM_CAS JZ_GPIO_PORTB(21)
#define JZ_GPIO_MEM_SDWE JZ_GPIO_PORTB(22)
#define JZ_GPIO_MEM_CKE JZ_GPIO_PORTB(23)
#define JZ_GPIO_MEM_CKO JZ_GPIO_PORTB(24)
#define JZ_GPIO_MEM_CS0 JZ_GPIO_PORTB(25)
#define JZ_GPIO_MEM_CS1 JZ_GPIO_PORTB(26)
#define JZ_GPIO_MEM_CS2 JZ_GPIO_PORTB(27)
#define JZ_GPIO_MEM_CS3 JZ_GPIO_PORTB(28)
#define JZ_GPIO_MEM_RD JZ_GPIO_PORTB(29)
#define JZ_GPIO_MEM_WR JZ_GPIO_PORTB(30)
#define JZ_GPIO_MEM_WE0 JZ_GPIO_PORTB(31)
#define JZ_GPIO_FUNC_MEM_ADDR0 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR1 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR2 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR3 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR4 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR5 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR6 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR7 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR8 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR9 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR10 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR11 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR12 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR13 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR14 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR15 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR16 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_CLS JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_SPL JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DCS JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_RAS JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_CAS JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_SDWE JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_CKE JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_CKO JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_CS0 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_CS1 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_CS2 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_CS3 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_RD JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_WR JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_WE0 JZ_GPIO_FUNC1
#define JZ_GPIO_MEM_ADDR21 JZ_GPIO_PORTB(17)
#define JZ_GPIO_MEM_ADDR22 JZ_GPIO_PORTB(18)
#define JZ_GPIO_FUNC_MEM_ADDR21 JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_MEM_ADDR22 JZ_GPIO_FUNC2
/* Port C function pins */
#define JZ_GPIO_LCD_DATA0 JZ_GPIO_PORTC(0)
#define JZ_GPIO_LCD_DATA1 JZ_GPIO_PORTC(1)
#define JZ_GPIO_LCD_DATA2 JZ_GPIO_PORTC(2)
#define JZ_GPIO_LCD_DATA3 JZ_GPIO_PORTC(3)
#define JZ_GPIO_LCD_DATA4 JZ_GPIO_PORTC(4)
#define JZ_GPIO_LCD_DATA5 JZ_GPIO_PORTC(5)
#define JZ_GPIO_LCD_DATA6 JZ_GPIO_PORTC(6)
#define JZ_GPIO_LCD_DATA7 JZ_GPIO_PORTC(7)
#define JZ_GPIO_LCD_DATA8 JZ_GPIO_PORTC(8)
#define JZ_GPIO_LCD_DATA9 JZ_GPIO_PORTC(9)
#define JZ_GPIO_LCD_DATA10 JZ_GPIO_PORTC(10)
#define JZ_GPIO_LCD_DATA11 JZ_GPIO_PORTC(11)
#define JZ_GPIO_LCD_DATA12 JZ_GPIO_PORTC(12)
#define JZ_GPIO_LCD_DATA13 JZ_GPIO_PORTC(13)
#define JZ_GPIO_LCD_DATA14 JZ_GPIO_PORTC(14)
#define JZ_GPIO_LCD_DATA15 JZ_GPIO_PORTC(15)
#define JZ_GPIO_LCD_DATA16 JZ_GPIO_PORTC(16)
#define JZ_GPIO_LCD_DATA17 JZ_GPIO_PORTC(17)
#define JZ_GPIO_LCD_PCLK JZ_GPIO_PORTC(18)
#define JZ_GPIO_LCD_HSYNC JZ_GPIO_PORTC(19)
#define JZ_GPIO_LCD_VSYNC JZ_GPIO_PORTC(20)
#define JZ_GPIO_LCD_DE JZ_GPIO_PORTC(21)
#define JZ_GPIO_LCD_PS JZ_GPIO_PORTC(22)
#define JZ_GPIO_LCD_REV JZ_GPIO_PORTC(23)
#define JZ_GPIO_MEM_WE1 JZ_GPIO_PORTC(24)
#define JZ_GPIO_MEM_WE2 JZ_GPIO_PORTC(25)
#define JZ_GPIO_MEM_WE3 JZ_GPIO_PORTC(26)
#define JZ_GPIO_MEM_WAIT JZ_GPIO_PORTC(27)
#define JZ_GPIO_MEM_FRE JZ_GPIO_PORTC(28)
#define JZ_GPIO_MEM_FWE JZ_GPIO_PORTC(29)
#define JZ_GPIO_FUNC_LCD_DATA0 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA1 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA2 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA3 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA4 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA5 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA6 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA7 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA8 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA9 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA10 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA11 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA12 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA13 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA14 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA15 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA16 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA17 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_PCLK JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_VSYNC JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_HSYNC JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DE JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_PS JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_REV JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_WE1 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_WE2 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_WE3 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_WAIT JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_FRE JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_FWE JZ_GPIO_FUNC1
#define JZ_GPIO_MEM_ADDR19 JZ_GPIO_PORTB(22)
#define JZ_GPIO_MEM_ADDR20 JZ_GPIO_PORTB(23)
#define JZ_GPIO_FUNC_MEM_ADDR19 JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_MEM_ADDR20 JZ_GPIO_FUNC2
/* Port D function pins */
#define JZ_GPIO_CIM_DATA0 JZ_GPIO_PORTD(0)
#define JZ_GPIO_CIM_DATA1 JZ_GPIO_PORTD(1)
#define JZ_GPIO_CIM_DATA2 JZ_GPIO_PORTD(2)
#define JZ_GPIO_CIM_DATA3 JZ_GPIO_PORTD(3)
#define JZ_GPIO_CIM_DATA4 JZ_GPIO_PORTD(4)
#define JZ_GPIO_CIM_DATA5 JZ_GPIO_PORTD(5)
#define JZ_GPIO_CIM_DATA6 JZ_GPIO_PORTD(6)
#define JZ_GPIO_CIM_DATA7 JZ_GPIO_PORTD(7)
#define JZ_GPIO_MSC_CMD JZ_GPIO_PORTD(8)
#define JZ_GPIO_MSC_CLK JZ_GPIO_PORTD(9)
#define JZ_GPIO_MSC_DATA0 JZ_GPIO_PORTD(10)
#define JZ_GPIO_MSC_DATA1 JZ_GPIO_PORTD(11)
#define JZ_GPIO_MSC_DATA2 JZ_GPIO_PORTD(12)
#define JZ_GPIO_MSC_DATA3 JZ_GPIO_PORTD(13)
#define JZ_GPIO_CIM_MCLK JZ_GPIO_PORTD(14)
#define JZ_GPIO_CIM_PCLK JZ_GPIO_PORTD(15)
#define JZ_GPIO_CIM_VSYNC JZ_GPIO_PORTD(16)
#define JZ_GPIO_CIM_HSYNC JZ_GPIO_PORTD(17)
#define JZ_GPIO_SPI_CLK JZ_GPIO_PORTD(18)
#define JZ_GPIO_SPI_CE0 JZ_GPIO_PORTD(19)
#define JZ_GPIO_SPI_DT JZ_GPIO_PORTD(20)
#define JZ_GPIO_SPI_DR JZ_GPIO_PORTD(21)
#define JZ_GPIO_SPI_CE1 JZ_GPIO_PORTD(22)
#define JZ_GPIO_PWM0 JZ_GPIO_PORTD(23)
#define JZ_GPIO_PWM1 JZ_GPIO_PORTD(24)
#define JZ_GPIO_PWM2 JZ_GPIO_PORTD(25)
#define JZ_GPIO_PWM3 JZ_GPIO_PORTD(26)
#define JZ_GPIO_PWM4 JZ_GPIO_PORTD(27)
#define JZ_GPIO_PWM5 JZ_GPIO_PORTD(28)
#define JZ_GPIO_PWM6 JZ_GPIO_PORTD(30)
#define JZ_GPIO_PWM7 JZ_GPIO_PORTD(31)
#define JZ_GPIO_FUNC_CIM_DATA JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_CIM_DATA0 JZ_GPIO_FUNC_CIM_DATA
#define JZ_GPIO_FUNC_CIM_DATA1 JZ_GPIO_FUNC_CIM_DATA
#define JZ_GPIO_FUNC_CIM_DATA2 JZ_GPIO_FUNC_CIM_DATA
#define JZ_GPIO_FUNC_CIM_DATA3 JZ_GPIO_FUNC_CIM_DATA
#define JZ_GPIO_FUNC_CIM_DATA4 JZ_GPIO_FUNC_CIM_DATA
#define JZ_GPIO_FUNC_CIM_DATA5 JZ_GPIO_FUNC_CIM_DATA
#define JZ_GPIO_FUNC_CIM_DATA6 JZ_GPIO_FUNC_CIM_DATA
#define JZ_GPIO_FUNC_CIM_DATA7 JZ_GPIO_FUNC_CIM_DATA
#define JZ_GPIO_FUNC_MSC_CMD JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MSC_CLK JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MSC_DATA JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MSC_DATA0 JZ_GPIO_FUNC_MSC_DATA
#define JZ_GPIO_FUNC_MSC_DATA1 JZ_GPIO_FUNC_MSC_DATA
#define JZ_GPIO_FUNC_MSC_DATA2 JZ_GPIO_FUNC_MSC_DATA
#define JZ_GPIO_FUNC_MSC_DATA3 JZ_GPIO_FUNC_MSC_DATA
#define JZ_GPIO_FUNC_CIM_MCLK JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_CIM_PCLK JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_CIM_VSYNC JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_CIM_HSYNC JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_SPI_CLK JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_SPI_CE0 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_SPI_DT JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_SPI_DR JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_SPI_CE1 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_PWM JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_PWM0 JZ_GPIO_FUNC_PWM
#define JZ_GPIO_FUNC_PWM1 JZ_GPIO_FUNC_PWM
#define JZ_GPIO_FUNC_PWM2 JZ_GPIO_FUNC_PWM
#define JZ_GPIO_FUNC_PWM3 JZ_GPIO_FUNC_PWM
#define JZ_GPIO_FUNC_PWM4 JZ_GPIO_FUNC_PWM
#define JZ_GPIO_FUNC_PWM5 JZ_GPIO_FUNC_PWM
#define JZ_GPIO_FUNC_PWM6 JZ_GPIO_FUNC_PWM
#define JZ_GPIO_FUNC_PWM7 JZ_GPIO_FUNC_PWM
#define JZ_GPIO_MEM_SCLK_RSTN JZ_GPIO_PORTD(18)
#define JZ_GPIO_MEM_BCLK JZ_GPIO_PORTD(19)
#define JZ_GPIO_MEM_SDATO JZ_GPIO_PORTD(20)
#define JZ_GPIO_MEM_SDATI JZ_GPIO_PORTD(21)
#define JZ_GPIO_MEM_SYNC JZ_GPIO_PORTD(22)
#define JZ_GPIO_I2C_SDA JZ_GPIO_PORTD(23)
#define JZ_GPIO_I2C_SCK JZ_GPIO_PORTD(24)
#define JZ_GPIO_UART0_TXD JZ_GPIO_PORTD(25)
#define JZ_GPIO_UART0_RXD JZ_GPIO_PORTD(26)
#define JZ_GPIO_MEM_ADDR17 JZ_GPIO_PORTD(27)
#define JZ_GPIO_MEM_ADDR18 JZ_GPIO_PORTD(28)
#define JZ_GPIO_UART0_CTS JZ_GPIO_PORTD(30)
#define JZ_GPIO_UART0_RTS JZ_GPIO_PORTD(31)
#define JZ_GPIO_FUNC_MEM_SCLK_RSTN JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_MEM_BCLK JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_MEM_SDATO JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_MEM_SDATI JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_MEM_SYNC JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_I2C_SDA JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_I2C_SCK JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_UART0_TXD JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_UART0_RXD JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_MEM_ADDR17 JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_MEM_ADDR18 JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_UART0_CTS JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_UART0_RTS JZ_GPIO_FUNC2
#define JZ_GPIO_UART1_RXD JZ_GPIO_PORTD(30)
#define JZ_GPIO_UART1_TXD JZ_GPIO_PORTD(31)
#define JZ_GPIO_FUNC_UART1_RXD JZ_GPIO_FUNC3
#define JZ_GPIO_FUNC_UART1_TXD JZ_GPIO_FUNC3
#endif

View File

@ -7,8 +7,6 @@
obj-y += prom.o time.o reset.o setup.o \
platform.o timer.o
obj-$(CONFIG_MACH_JZ4740) += gpio.o
CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt
# board specific support

View File

@ -22,6 +22,8 @@
#include <linux/input/matrix_keypad.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_gpio.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/power_supply.h>
#include <linux/power/jz4740-battery.h>
#include <linux/power/gpio-charger.h>
@ -159,7 +161,7 @@ static struct jz_nand_platform_data qi_lb60_nand_pdata = {
static struct gpiod_lookup_table qi_lb60_nand_gpio_table = {
.dev_id = "jz4740-nand.0",
.table = {
GPIO_LOOKUP("Bank C", 30, "busy", 0),
GPIO_LOOKUP("GPIOC", 30, "busy", 0),
{ },
},
};
@ -421,8 +423,8 @@ static struct platform_device qi_lb60_audio_device = {
static struct gpiod_lookup_table qi_lb60_audio_gpio_table = {
.dev_id = "qi-lb60-audio",
.table = {
GPIO_LOOKUP("Bank B", 29, "snd", 0),
GPIO_LOOKUP("Bank D", 4, "amp", 0),
GPIO_LOOKUP("GPIOB", 29, "snd", 0),
GPIO_LOOKUP("GPIOD", 4, "amp", 0),
{ },
},
};
@ -447,13 +449,36 @@ static struct platform_device *jz_platform_devices[] __initdata = {
&qi_lb60_audio_device,
};
static void __init board_gpio_setup(void)
{
/* We only need to enable/disable pullup here for pins used in generic
* drivers. Everything else is done by the drivers themselves. */
jz_gpio_disable_pullup(QI_LB60_GPIO_SD_VCC_EN_N);
jz_gpio_disable_pullup(QI_LB60_GPIO_SD_CD);
}
static unsigned long pin_cfg_bias_disable[] = {
PIN_CONFIG_BIAS_DISABLE,
};
static struct pinctrl_map pin_map[] __initdata = {
/* NAND pin configuration */
PIN_MAP_MUX_GROUP_DEFAULT("jz4740-nand",
"10010000.jz4740-pinctrl", "nand", "nand-cs1"),
/* fbdev pin configuration */
PIN_MAP_MUX_GROUP("jz4740-fb", PINCTRL_STATE_DEFAULT,
"10010000.jz4740-pinctrl", "lcd", "lcd-8bit"),
PIN_MAP_MUX_GROUP("jz4740-fb", PINCTRL_STATE_SLEEP,
"10010000.jz4740-pinctrl", "lcd", "lcd-no-pins"),
/* MMC pin configuration */
PIN_MAP_MUX_GROUP_DEFAULT("jz4740-mmc.0",
"10010000.jz4740-pinctrl", "mmc", "mmc-1bit"),
PIN_MAP_MUX_GROUP_DEFAULT("jz4740-mmc.0",
"10010000.jz4740-pinctrl", "mmc", "mmc-4bit"),
PIN_MAP_CONFIGS_PIN_DEFAULT("jz4740-mmc.0",
"10010000.jz4740-pinctrl", "PD0", pin_cfg_bias_disable),
PIN_MAP_CONFIGS_PIN_DEFAULT("jz4740-mmc.0",
"10010000.jz4740-pinctrl", "PD2", pin_cfg_bias_disable),
/* PWM pin configuration */
PIN_MAP_MUX_GROUP_DEFAULT("jz4740-pwm",
"10010000.jz4740-pinctrl", "pwm4", "pwm4"),
};
static int __init qi_lb60_init_platform_devices(void)
{
@ -469,6 +494,7 @@ static int __init qi_lb60_init_platform_devices(void)
ARRAY_SIZE(qi_lb60_spi_board_info));
pwm_add_table(qi_lb60_pwm_lookup, ARRAY_SIZE(qi_lb60_pwm_lookup));
pinctrl_register_mappings(pin_map, ARRAY_SIZE(pin_map));
return platform_add_devices(jz_platform_devices,
ARRAY_SIZE(jz_platform_devices));
@ -479,8 +505,6 @@ static int __init qi_lb60_board_setup(void)
{
printk(KERN_INFO "Qi Hardware JZ4740 QI LB60 setup\n");
board_gpio_setup();
if (qi_lb60_init_platform_devices())
panic("Failed to initialize platform devices");

View File

@ -1,519 +0,0 @@
/*
* Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
* JZ4740 platform GPIO support
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/gpio/driver.h>
/* FIXME: needed for gpio_request(), try to remove consumer API from driver */
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/irqchip/ingenic.h>
#include <linux/bitops.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <asm/mach-jz4740/base.h>
#include <asm/mach-jz4740/gpio.h>
#define JZ4740_GPIO_BASE_A (32*0)
#define JZ4740_GPIO_BASE_B (32*1)
#define JZ4740_GPIO_BASE_C (32*2)
#define JZ4740_GPIO_BASE_D (32*3)
#define JZ4740_GPIO_NUM_A 32
#define JZ4740_GPIO_NUM_B 32
#define JZ4740_GPIO_NUM_C 31
#define JZ4740_GPIO_NUM_D 32
#define JZ4740_IRQ_GPIO_BASE_A (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_A)
#define JZ4740_IRQ_GPIO_BASE_B (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_B)
#define JZ4740_IRQ_GPIO_BASE_C (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_C)
#define JZ4740_IRQ_GPIO_BASE_D (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_D)
#define JZ_REG_GPIO_PIN 0x00
#define JZ_REG_GPIO_DATA 0x10
#define JZ_REG_GPIO_DATA_SET 0x14
#define JZ_REG_GPIO_DATA_CLEAR 0x18
#define JZ_REG_GPIO_MASK 0x20
#define JZ_REG_GPIO_MASK_SET 0x24
#define JZ_REG_GPIO_MASK_CLEAR 0x28
#define JZ_REG_GPIO_PULL 0x30
#define JZ_REG_GPIO_PULL_SET 0x34
#define JZ_REG_GPIO_PULL_CLEAR 0x38
#define JZ_REG_GPIO_FUNC 0x40
#define JZ_REG_GPIO_FUNC_SET 0x44
#define JZ_REG_GPIO_FUNC_CLEAR 0x48
#define JZ_REG_GPIO_SELECT 0x50
#define JZ_REG_GPIO_SELECT_SET 0x54
#define JZ_REG_GPIO_SELECT_CLEAR 0x58
#define JZ_REG_GPIO_DIRECTION 0x60
#define JZ_REG_GPIO_DIRECTION_SET 0x64
#define JZ_REG_GPIO_DIRECTION_CLEAR 0x68
#define JZ_REG_GPIO_TRIGGER 0x70
#define JZ_REG_GPIO_TRIGGER_SET 0x74
#define JZ_REG_GPIO_TRIGGER_CLEAR 0x78
#define JZ_REG_GPIO_FLAG 0x80
#define JZ_REG_GPIO_FLAG_CLEAR 0x14
#define GPIO_TO_BIT(gpio) BIT(gpio & 0x1f)
#define GPIO_TO_REG(gpio, reg) (gpio_to_jz_gpio_chip(gpio)->base + (reg))
#define CHIP_TO_REG(chip, reg) (gpio_chip_to_jz_gpio_chip(chip)->base + (reg))
struct jz_gpio_chip {
unsigned int irq;
unsigned int irq_base;
uint32_t edge_trigger_both;
void __iomem *base;
struct gpio_chip gpio_chip;
};
static struct jz_gpio_chip jz4740_gpio_chips[];
static inline struct jz_gpio_chip *gpio_to_jz_gpio_chip(unsigned int gpio)
{
return &jz4740_gpio_chips[gpio >> 5];
}
static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *gc)
{
return gpiochip_get_data(gc);
}
static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(struct irq_data *data)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
return gc->private;
}
static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg)
{
writel(GPIO_TO_BIT(gpio), GPIO_TO_REG(gpio, reg));
}
int jz_gpio_set_function(int gpio, enum jz_gpio_function function)
{
if (function == JZ_GPIO_FUNC_NONE) {
jz_gpio_write_bit(gpio, JZ_REG_GPIO_FUNC_CLEAR);
jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_CLEAR);
jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR);
} else {
jz_gpio_write_bit(gpio, JZ_REG_GPIO_FUNC_SET);
jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR);
switch (function) {
case JZ_GPIO_FUNC1:
jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_CLEAR);
break;
case JZ_GPIO_FUNC3:
jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_SET);
case JZ_GPIO_FUNC2: /* Falltrough */
jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_SET);
break;
default:
BUG();
break;
}
}
return 0;
}
EXPORT_SYMBOL_GPL(jz_gpio_set_function);
int jz_gpio_bulk_request(const struct jz_gpio_bulk_request *request, size_t num)
{
size_t i;
int ret;
for (i = 0; i < num; ++i, ++request) {
ret = gpio_request(request->gpio, request->name);
if (ret)
goto err;
jz_gpio_set_function(request->gpio, request->function);
}
return 0;
err:
for (--request; i > 0; --i, --request) {
gpio_free(request->gpio);
jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
}
return ret;
}
EXPORT_SYMBOL_GPL(jz_gpio_bulk_request);
void jz_gpio_bulk_free(const struct jz_gpio_bulk_request *request, size_t num)
{
size_t i;
for (i = 0; i < num; ++i, ++request) {
gpio_free(request->gpio);
jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
}
}
EXPORT_SYMBOL_GPL(jz_gpio_bulk_free);
void jz_gpio_bulk_suspend(const struct jz_gpio_bulk_request *request, size_t num)
{
size_t i;
for (i = 0; i < num; ++i, ++request) {
jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_DIRECTION_CLEAR);
jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_PULL_SET);
}
}
EXPORT_SYMBOL_GPL(jz_gpio_bulk_suspend);
void jz_gpio_bulk_resume(const struct jz_gpio_bulk_request *request, size_t num)
{
size_t i;
for (i = 0; i < num; ++i, ++request)
jz_gpio_set_function(request->gpio, request->function);
}
EXPORT_SYMBOL_GPL(jz_gpio_bulk_resume);
void jz_gpio_enable_pullup(unsigned gpio)
{
jz_gpio_write_bit(gpio, JZ_REG_GPIO_PULL_CLEAR);
}
EXPORT_SYMBOL_GPL(jz_gpio_enable_pullup);
void jz_gpio_disable_pullup(unsigned gpio)
{
jz_gpio_write_bit(gpio, JZ_REG_GPIO_PULL_SET);
}
EXPORT_SYMBOL_GPL(jz_gpio_disable_pullup);
static int jz_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
{
return !!(readl(CHIP_TO_REG(chip, JZ_REG_GPIO_PIN)) & BIT(gpio));
}
static void jz_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
{
uint32_t __iomem *reg = CHIP_TO_REG(chip, JZ_REG_GPIO_DATA_SET);
reg += !value;
writel(BIT(gpio), reg);
}
static int jz_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
int value)
{
writel(BIT(gpio), CHIP_TO_REG(chip, JZ_REG_GPIO_DIRECTION_SET));
jz_gpio_set_value(chip, gpio, value);
return 0;
}
static int jz_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
{
writel(BIT(gpio), CHIP_TO_REG(chip, JZ_REG_GPIO_DIRECTION_CLEAR));
return 0;
}
static int jz_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
{
struct jz_gpio_chip *jz_gpio = gpiochip_get_data(chip);
return jz_gpio->irq_base + gpio;
}
int jz_gpio_port_direction_input(int port, uint32_t mask)
{
writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_CLEAR));
return 0;
}
EXPORT_SYMBOL(jz_gpio_port_direction_input);
int jz_gpio_port_direction_output(int port, uint32_t mask)
{
writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_SET));
return 0;
}
EXPORT_SYMBOL(jz_gpio_port_direction_output);
void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask)
{
writel(~value & mask, GPIO_TO_REG(port, JZ_REG_GPIO_DATA_CLEAR));
writel(value & mask, GPIO_TO_REG(port, JZ_REG_GPIO_DATA_SET));
}
EXPORT_SYMBOL(jz_gpio_port_set_value);
uint32_t jz_gpio_port_get_value(int port, uint32_t mask)
{
uint32_t value = readl(GPIO_TO_REG(port, JZ_REG_GPIO_PIN));
return value & mask;
}
EXPORT_SYMBOL(jz_gpio_port_get_value);
#define IRQ_TO_BIT(irq) BIT((irq - JZ4740_IRQ_GPIO(0)) & 0x1f)
static void jz_gpio_check_trigger_both(struct jz_gpio_chip *chip, unsigned int irq)
{
uint32_t value;
void __iomem *reg;
uint32_t mask = IRQ_TO_BIT(irq);
if (!(chip->edge_trigger_both & mask))
return;
reg = chip->base;
value = readl(chip->base + JZ_REG_GPIO_PIN);
if (value & mask)
reg += JZ_REG_GPIO_DIRECTION_CLEAR;
else
reg += JZ_REG_GPIO_DIRECTION_SET;
writel(mask, reg);
}
static void jz_gpio_irq_demux_handler(struct irq_desc *desc)
{
uint32_t flag;
unsigned int gpio_irq;
struct jz_gpio_chip *chip = irq_desc_get_handler_data(desc);
flag = readl(chip->base + JZ_REG_GPIO_FLAG);
if (!flag)
return;
gpio_irq = chip->irq_base + __fls(flag);
jz_gpio_check_trigger_both(chip, gpio_irq);
generic_handle_irq(gpio_irq);
};
static inline void jz_gpio_set_irq_bit(struct irq_data *data, unsigned int reg)
{
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
writel(IRQ_TO_BIT(data->irq), chip->base + reg);
}
static void jz_gpio_irq_unmask(struct irq_data *data)
{
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
jz_gpio_check_trigger_both(chip, data->irq);
irq_gc_unmask_enable_reg(data);
};
/* TODO: Check if function is gpio */
static unsigned int jz_gpio_irq_startup(struct irq_data *data)
{
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_SET);
jz_gpio_irq_unmask(data);
return 0;
}
static void jz_gpio_irq_shutdown(struct irq_data *data)
{
irq_gc_mask_disable_reg(data);
/* Set direction to input */
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_CLEAR);
}
static int jz_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
{
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
unsigned int irq = data->irq;
if (flow_type == IRQ_TYPE_EDGE_BOTH) {
uint32_t value = readl(chip->base + JZ_REG_GPIO_PIN);
if (value & IRQ_TO_BIT(irq))
flow_type = IRQ_TYPE_EDGE_FALLING;
else
flow_type = IRQ_TYPE_EDGE_RISING;
chip->edge_trigger_both |= IRQ_TO_BIT(irq);
} else {
chip->edge_trigger_both &= ~IRQ_TO_BIT(irq);
}
switch (flow_type) {
case IRQ_TYPE_EDGE_RISING:
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_SET);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_SET);
break;
case IRQ_TYPE_EDGE_FALLING:
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_SET);
break;
case IRQ_TYPE_LEVEL_HIGH:
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_SET);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_CLEAR);
break;
case IRQ_TYPE_LEVEL_LOW:
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_CLEAR);
break;
default:
return -EINVAL;
}
return 0;
}
static int jz_gpio_irq_set_wake(struct irq_data *data, unsigned int on)
{
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
irq_gc_set_wake(data, on);
irq_set_irq_wake(chip->irq, on);
return 0;
}
#define JZ4740_GPIO_CHIP(_bank) { \
.irq_base = JZ4740_IRQ_GPIO_BASE_ ## _bank, \
.gpio_chip = { \
.label = "Bank " # _bank, \
.owner = THIS_MODULE, \
.set = jz_gpio_set_value, \
.get = jz_gpio_get_value, \
.direction_output = jz_gpio_direction_output, \
.direction_input = jz_gpio_direction_input, \
.to_irq = jz_gpio_to_irq, \
.base = JZ4740_GPIO_BASE_ ## _bank, \
.ngpio = JZ4740_GPIO_NUM_ ## _bank, \
}, \
}
static struct jz_gpio_chip jz4740_gpio_chips[] = {
JZ4740_GPIO_CHIP(A),
JZ4740_GPIO_CHIP(B),
JZ4740_GPIO_CHIP(C),
JZ4740_GPIO_CHIP(D),
};
static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
{
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
chip->base = ioremap(JZ4740_GPIO_BASE_ADDR + (id * 0x100), 0x100);
chip->irq = JZ4740_IRQ_INTC_GPIO(id);
irq_set_chained_handler_and_data(chip->irq,
jz_gpio_irq_demux_handler, chip);
gc = irq_alloc_generic_chip(chip->gpio_chip.label, 1, chip->irq_base,
chip->base, handle_level_irq);
gc->wake_enabled = IRQ_MSK(chip->gpio_chip.ngpio);
gc->private = chip;
ct = gc->chip_types;
ct->regs.enable = JZ_REG_GPIO_MASK_CLEAR;
ct->regs.disable = JZ_REG_GPIO_MASK_SET;
ct->regs.ack = JZ_REG_GPIO_FLAG_CLEAR;
ct->chip.name = "GPIO";
ct->chip.irq_mask = irq_gc_mask_disable_reg;
ct->chip.irq_unmask = jz_gpio_irq_unmask;
ct->chip.irq_ack = irq_gc_ack_set_bit;
ct->chip.irq_suspend = ingenic_intc_irq_suspend;
ct->chip.irq_resume = ingenic_intc_irq_resume;
ct->chip.irq_startup = jz_gpio_irq_startup;
ct->chip.irq_shutdown = jz_gpio_irq_shutdown;
ct->chip.irq_set_type = jz_gpio_irq_set_type;
ct->chip.irq_set_wake = jz_gpio_irq_set_wake;
ct->chip.flags = IRQCHIP_SET_TYPE_MASKED;
irq_setup_generic_chip(gc, IRQ_MSK(chip->gpio_chip.ngpio),
IRQ_GC_INIT_NESTED_LOCK, 0, IRQ_NOPROBE | IRQ_LEVEL);
gpiochip_add_data(&chip->gpio_chip, chip);
}
static int __init jz4740_gpio_init(void)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i)
jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i);
printk(KERN_INFO "JZ4740 GPIO initialized\n");
return 0;
}
arch_initcall(jz4740_gpio_init);
#ifdef CONFIG_DEBUG_FS
static inline void gpio_seq_reg(struct seq_file *s, struct jz_gpio_chip *chip,
const char *name, unsigned int reg)
{
seq_printf(s, "\t%s: %08x\n", name, readl(chip->base + reg));
}
static int gpio_regs_show(struct seq_file *s, void *unused)
{
struct jz_gpio_chip *chip = jz4740_gpio_chips;
int i;
for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i, ++chip) {
seq_printf(s, "==GPIO %d==\n", i);
gpio_seq_reg(s, chip, "Pin", JZ_REG_GPIO_PIN);
gpio_seq_reg(s, chip, "Data", JZ_REG_GPIO_DATA);
gpio_seq_reg(s, chip, "Mask", JZ_REG_GPIO_MASK);
gpio_seq_reg(s, chip, "Pull", JZ_REG_GPIO_PULL);
gpio_seq_reg(s, chip, "Func", JZ_REG_GPIO_FUNC);
gpio_seq_reg(s, chip, "Select", JZ_REG_GPIO_SELECT);
gpio_seq_reg(s, chip, "Direction", JZ_REG_GPIO_DIRECTION);
gpio_seq_reg(s, chip, "Trigger", JZ_REG_GPIO_TRIGGER);
gpio_seq_reg(s, chip, "Flag", JZ_REG_GPIO_FLAG);
}
return 0;
}
static int gpio_regs_open(struct inode *inode, struct file *file)
{
return single_open(file, gpio_regs_show, NULL);
}
static const struct file_operations gpio_regs_operations = {
.open = gpio_regs_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int __init gpio_debugfs_init(void)
{
(void) debugfs_create_file("jz_regs_gpio", S_IFREG | S_IRUGO,
NULL, NULL, &gpio_regs_operations);
return 0;
}
subsys_initcall(gpio_debugfs_init);
#endif

View File

@ -242,6 +242,17 @@ 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
@ -1227,23 +1238,6 @@ config GPIO_PISOSR
endmenu
menu "SPI or I2C GPIO expanders"
depends on (SPI_MASTER && !I2C) || I2C
config GPIO_MCP23S08
tristate "Microchip MCP23xxx I/O expander"
depends on OF_GPIO
select GPIOLIB_IRQCHIP
select REGMAP_I2C if I2C
select REGMAP if SPI_MASTER
help
SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017
I/O expanders.
This provides a GPIO interface supporting inputs and outputs.
The I2C versions of the chips can be used as interrupt-controller.
endmenu
menu "USB GPIO expanders"
depends on USB

View File

@ -55,6 +55,7 @@ obj-$(CONFIG_GPIO_GPIO_MM) += gpio-gpio-mm.o
obj-$(CONFIG_GPIO_GRGPIO) += gpio-grgpio.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
@ -77,7 +78,6 @@ obj-$(CONFIG_GPIO_MENZ127) += gpio-menz127.o
obj-$(CONFIG_GPIO_MERRIFIELD) += gpio-merrifield.o
obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o
obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o
obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o
obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o
obj-$(CONFIG_GPIO_MM_LANTIQ) += gpio-mm-lantiq.o
obj-$(CONFIG_GPIO_MOCKUP) += gpio-mockup.o

View File

@ -0,0 +1,394 @@
/*
* 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->irqdomain, 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;
const struct of_device_id *of_id = of_match_device(
ingenic_gpio_of_match, 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_id->data;
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

@ -20,6 +20,7 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/scatterlist.h>
@ -27,7 +28,6 @@
#include <linux/bitops.h>
#include <linux/gpio.h>
#include <asm/mach-jz4740/gpio.h>
#include <asm/cacheflush.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
@ -901,15 +901,6 @@ static const struct mmc_host_ops jz4740_mmc_ops = {
.enable_sdio_irq = jz4740_mmc_enable_sdio_irq,
};
static const struct jz_gpio_bulk_request jz4740_mmc_pins[] = {
JZ_GPIO_BULK_PIN(MSC_CMD),
JZ_GPIO_BULK_PIN(MSC_CLK),
JZ_GPIO_BULK_PIN(MSC_DATA0),
JZ_GPIO_BULK_PIN(MSC_DATA1),
JZ_GPIO_BULK_PIN(MSC_DATA2),
JZ_GPIO_BULK_PIN(MSC_DATA3),
};
static int jz4740_mmc_request_gpio(struct device *dev, int gpio,
const char *name, bool output, int value)
{
@ -973,15 +964,6 @@ static void jz4740_mmc_free_gpios(struct platform_device *pdev)
gpio_free(pdata->gpio_power);
}
static inline size_t jz4740_mmc_num_pins(struct jz4740_mmc_host *host)
{
size_t num_pins = ARRAY_SIZE(jz4740_mmc_pins);
if (host->pdata && host->pdata->data_1bit)
num_pins -= 3;
return num_pins;
}
static int jz4740_mmc_probe(struct platform_device* pdev)
{
int ret;
@ -1022,15 +1004,9 @@ static int jz4740_mmc_probe(struct platform_device* pdev)
goto err_free_host;
}
ret = jz_gpio_bulk_request(jz4740_mmc_pins, jz4740_mmc_num_pins(host));
if (ret) {
dev_err(&pdev->dev, "Failed to request mmc pins: %d\n", ret);
goto err_free_host;
}
ret = jz4740_mmc_request_gpios(mmc, pdev);
if (ret)
goto err_gpio_bulk_free;
goto err_release_dma;
mmc->ops = &jz4740_mmc_ops;
mmc->f_min = JZ_MMC_CLK_RATE / 128;
@ -1086,10 +1062,9 @@ err_free_irq:
free_irq(host->irq, host);
err_free_gpios:
jz4740_mmc_free_gpios(pdev);
err_gpio_bulk_free:
err_release_dma:
if (host->use_dma)
jz4740_mmc_release_dma_channels(host);
jz_gpio_bulk_free(jz4740_mmc_pins, jz4740_mmc_num_pins(host));
err_free_host:
mmc_free_host(mmc);
@ -1109,7 +1084,6 @@ static int jz4740_mmc_remove(struct platform_device *pdev)
free_irq(host->irq, host);
jz4740_mmc_free_gpios(pdev);
jz_gpio_bulk_free(jz4740_mmc_pins, jz4740_mmc_num_pins(host));
if (host->use_dma)
jz4740_mmc_release_dma_channels(host);
@ -1123,20 +1097,12 @@ static int jz4740_mmc_remove(struct platform_device *pdev)
static int jz4740_mmc_suspend(struct device *dev)
{
struct jz4740_mmc_host *host = dev_get_drvdata(dev);
jz_gpio_bulk_suspend(jz4740_mmc_pins, jz4740_mmc_num_pins(host));
return 0;
return pinctrl_pm_select_sleep_state(dev);
}
static int jz4740_mmc_resume(struct device *dev)
{
struct jz4740_mmc_host *host = dev_get_drvdata(dev);
jz_gpio_bulk_resume(jz4740_mmc_pins, jz4740_mmc_num_pins(host));
return 0;
return pinctrl_pm_select_default_state(dev);
}
static SIMPLE_DEV_PM_OPS(jz4740_mmc_pm_ops, jz4740_mmc_suspend,

View File

@ -25,7 +25,6 @@
#include <linux/gpio.h>
#include <asm/mach-jz4740/gpio.h>
#include <asm/mach-jz4740/jz4740_nand.h>
#define JZ_REG_NAND_CTRL 0x50
@ -310,34 +309,20 @@ static int jz_nand_detect_bank(struct platform_device *pdev,
uint8_t *nand_dev_id)
{
int ret;
int gpio;
char gpio_name[9];
char res_name[6];
uint32_t ctrl;
struct nand_chip *chip = &nand->chip;
struct mtd_info *mtd = nand_to_mtd(chip);
/* Request GPIO port. */
gpio = JZ_GPIO_MEM_CS0 + bank - 1;
sprintf(gpio_name, "NAND CS%d", bank);
ret = gpio_request(gpio, gpio_name);
if (ret) {
dev_warn(&pdev->dev,
"Failed to request %s gpio %d: %d\n",
gpio_name, gpio, ret);
goto notfound_gpio;
}
/* Request I/O resource. */
sprintf(res_name, "bank%d", bank);
ret = jz_nand_ioremap_resource(pdev, res_name,
&nand->bank_mem[bank - 1],
&nand->bank_base[bank - 1]);
if (ret)
goto notfound_resource;
return ret;
/* Enable chip in bank. */
jz_gpio_set_function(gpio, JZ_GPIO_FUNC_MEM_CS0);
ctrl = readl(nand->base + JZ_REG_NAND_CTRL);
ctrl |= JZ_NAND_CTRL_ENABLE_CHIP(bank - 1);
writel(ctrl, nand->base + JZ_REG_NAND_CTRL);
@ -377,12 +362,8 @@ notfound_id:
dev_info(&pdev->dev, "No chip found on bank %i\n", bank);
ctrl &= ~(JZ_NAND_CTRL_ENABLE_CHIP(bank - 1));
writel(ctrl, nand->base + JZ_REG_NAND_CTRL);
jz_gpio_set_function(gpio, JZ_GPIO_FUNC_NONE);
jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
nand->bank_base[bank - 1]);
notfound_resource:
gpio_free(gpio);
notfound_gpio:
return ret;
}
@ -503,7 +484,6 @@ err_nand_release:
err_unclaim_banks:
while (chipnr--) {
unsigned char bank = nand->banks[chipnr];
gpio_free(JZ_GPIO_MEM_CS0 + bank - 1);
jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
nand->bank_base[bank - 1]);
}
@ -530,7 +510,6 @@ static int jz_nand_remove(struct platform_device *pdev)
if (bank != 0) {
jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
nand->bank_base[bank - 1]);
gpio_free(JZ_GPIO_MEM_CS0 + bank - 1);
}
}

View File

@ -146,6 +146,20 @@ config PINCTRL_FALCON
depends on SOC_FALCON
depends on PINCTRL_LANTIQ
config PINCTRL_MCP23S08
tristate "Microchip MCP23xxx I/O expander"
depends on SPI_MASTER || I2C
depends on I2C || I2C=n
select GPIOLIB_IRQCHIP
select REGMAP_I2C if I2C
select REGMAP_SPI if SPI_MASTER
select GENERIC_PINCONF
help
SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017
I/O expanders.
This provides a GPIO interface supporting inputs and outputs.
The I2C versions of the chips can be used as interrupt-controller.
config PINCTRL_MESON
bool
depends on OF
@ -174,6 +188,17 @@ config PINCTRL_ROCKCHIP
select GENERIC_IRQ_CHIP
select MFD_SYSCON
config PINCTRL_RZA1
bool "Renesas RZ/A1 gpio and pinctrl driver"
depends on OF
depends on ARCH_R7S72100 || COMPILE_TEST
select GPIOLIB
select GENERIC_PINCTRL_GROUPS
select GENERIC_PINMUX_FUNCTIONS
select GENERIC_PINCONF
help
This selects pinctrl driver for Renesas RZ/A1 platforms.
config PINCTRL_SINGLE
tristate "One-register-per-pin type device tree based pinctrl driver"
depends on OF
@ -296,6 +321,16 @@ config PINCTRL_ZYNQ
help
This selects the pinctrl driver for Xilinx Zynq.
config PINCTRL_INGENIC
bool "Pinctrl driver for the Ingenic JZ47xx SoCs"
default y
depends on OF
depends on MACH_INGENIC || COMPILE_TEST
select GENERIC_PINCONF
select GENERIC_PINCTRL_GROUPS
select GENERIC_PINMUX_FUNCTIONS
select REGMAP_MMIO
source "drivers/pinctrl/aspeed/Kconfig"
source "drivers/pinctrl/bcm/Kconfig"
source "drivers/pinctrl/berlin/Kconfig"
@ -315,6 +350,7 @@ source "drivers/pinctrl/ti/Kconfig"
source "drivers/pinctrl/uniphier/Kconfig"
source "drivers/pinctrl/vt8500/Kconfig"
source "drivers/pinctrl/mediatek/Kconfig"
source "drivers/pinctrl/zte/Kconfig"
config PINCTRL_XWAY
bool

View File

@ -19,12 +19,14 @@ obj-$(CONFIG_PINCTRL_DA850_PUPD) += pinctrl-da850-pupd.o
obj-$(CONFIG_PINCTRL_DIGICOLOR) += pinctrl-digicolor.o
obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o
obj-$(CONFIG_PINCTRL_MAX77620) += pinctrl-max77620.o
obj-$(CONFIG_PINCTRL_MCP23S08) += pinctrl-mcp23s08.o
obj-$(CONFIG_PINCTRL_MESON) += meson/
obj-$(CONFIG_PINCTRL_OXNAS) += pinctrl-oxnas.o
obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o
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_SINGLE) += pinctrl-single.o
obj-$(CONFIG_PINCTRL_SIRF) += sirf/
obj-$(CONFIG_PINCTRL_SX150X) += pinctrl-sx150x.o
@ -39,6 +41,7 @@ obj-$(CONFIG_PINCTRL_LPC18XX) += pinctrl-lpc18xx.o
obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o
obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o
obj-$(CONFIG_PINCTRL_INGENIC) += pinctrl-ingenic.o
obj-$(CONFIG_ARCH_ASPEED) += aspeed/
obj-y += bcm/
@ -58,3 +61,4 @@ obj-y += ti/
obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/
obj-$(CONFIG_ARCH_VT8500) += vt8500/
obj-$(CONFIG_PINCTRL_MTK) += mediatek/
obj-$(CONFIG_PINCTRL_ZX) += zte/

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013 Broadcom Corporation
* Copyright (C) 2013-2017 Broadcom
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@ -10,9 +10,10 @@
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
@ -1444,10 +1445,4 @@ static struct platform_driver bcm281xx_pinctrl_driver = {
.of_match_table = bcm281xx_pinctrl_of_match,
},
};
module_platform_driver_probe(bcm281xx_pinctrl_driver, bcm281xx_pinctrl_probe);
MODULE_AUTHOR("Broadcom Corporation <bcm-kernel-feedback-list@broadcom.com>");
MODULE_AUTHOR("Sherman Yin <syin@broadcom.com>");
MODULE_DESCRIPTION("Broadcom BCM281xx pinctrl driver");
MODULE_LICENSE("GPL v2");
builtin_platform_driver_probe(bcm281xx_pinctrl_driver, bcm281xx_pinctrl_probe);

View File

@ -27,7 +27,7 @@
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/irqdesc.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/of_address.h>
#include <linux/of.h>
#include <linux/of_irq.h>
@ -1048,6 +1048,10 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
for (i = 0; i < BCM2835_NUM_IRQS; i++) {
pc->irq[i] = irq_of_parse_and_map(np, i);
pc->irq_group[i] = i;
if (pc->irq[i] == 0)
continue;
/*
* Use the same handler for all groups: this is necessary
* since we use one gpiochip to cover all lines - the
@ -1075,31 +1079,17 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
return 0;
}
static int bcm2835_pinctrl_remove(struct platform_device *pdev)
{
struct bcm2835_pinctrl *pc = platform_get_drvdata(pdev);
gpiochip_remove(&pc->gpio_chip);
return 0;
}
static const struct of_device_id bcm2835_pinctrl_match[] = {
{ .compatible = "brcm,bcm2835-gpio" },
{}
};
MODULE_DEVICE_TABLE(of, bcm2835_pinctrl_match);
static struct platform_driver bcm2835_pinctrl_driver = {
.probe = bcm2835_pinctrl_probe,
.remove = bcm2835_pinctrl_remove,
.driver = {
.name = MODULE_NAME,
.of_match_table = bcm2835_pinctrl_match,
.suppress_bind_attrs = true,
},
};
module_platform_driver(bcm2835_pinctrl_driver);
MODULE_AUTHOR("Chris Boot, Simon Arlott, Stephen Warren");
MODULE_DESCRIPTION("BCM2835 Pin control driver");
MODULE_LICENSE("GPL");
builtin_platform_driver(bcm2835_pinctrl_driver);

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2014-2015 Broadcom Corporation
/*
* Copyright (C) 2014-2017 Broadcom
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@ -8,6 +9,10 @@
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/*
* Broadcom Cygnus IOMUX driver
*
* This file contains the Cygnus IOMUX driver that supports group based PINMUX
* configuration. Although PINMUX configuration is mainly group based, the
@ -17,7 +22,6 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
@ -1016,7 +1020,3 @@ static int __init cygnus_pinmux_init(void)
return platform_driver_register(&cygnus_pinmux_driver);
}
arch_initcall(cygnus_pinmux_init);
MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>");
MODULE_DESCRIPTION("Broadcom Cygnus IOMUX driver");
MODULE_LICENSE("GPL v2");

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2015 Broadcom Corporation
* Copyright (C) 2014-2017 Broadcom
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@ -9,7 +9,9 @@
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/*
* This file contains the Broadcom Iproc GPIO driver that supports 3
* GPIO controllers on Iproc including the ASIU GPIO controller, the
* chipCommonG GPIO controller, and the always-on GPIO controller. Basic

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 Broadcom Corporation
* Copyright (C) 2014-2017 Broadcom
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@ -9,7 +9,9 @@
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/*
* This file contains the Broadcom Northstar Plus (NSP) GPIO driver that
* supports the chipCommonA GPIO controller. Basic PINCONF such as bias,
* pull up/down, slew and drive strength are also supported in this driver.

View File

@ -170,7 +170,7 @@ const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin)
const struct pin_desc *desc;
desc = pin_desc_get(pctldev, pin);
if (desc == NULL) {
if (!desc) {
dev_err(pctldev->dev, "failed to get pin(%d) name\n",
pin);
return NULL;
@ -214,7 +214,7 @@ static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev,
pindesc = radix_tree_lookup(&pctldev->pin_desc_tree,
pins[i].number);
if (pindesc != NULL) {
if (pindesc) {
radix_tree_delete(&pctldev->pin_desc_tree,
pins[i].number);
if (pindesc->dynamic_name)
@ -230,7 +230,7 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
struct pin_desc *pindesc;
pindesc = pin_desc_get(pctldev, pin->number);
if (pindesc != NULL) {
if (pindesc) {
dev_err(pctldev->dev, "pin %d already registered\n",
pin->number);
return -EINVAL;
@ -248,7 +248,7 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
pindesc->name = pin->name;
} else {
pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", pin->number);
if (pindesc->name == NULL) {
if (!pindesc->name) {
kfree(pindesc);
return -ENOMEM;
}
@ -402,7 +402,7 @@ static int pinctrl_get_device_gpio_range(unsigned gpio,
struct pinctrl_gpio_range *range;
range = pinctrl_match_gpio_range(pctldev, gpio);
if (range != NULL) {
if (range) {
*outdev = pctldev;
*outrange = range;
mutex_unlock(&pinctrldev_list_mutex);
@ -933,7 +933,7 @@ static int add_setting(struct pinctrl *p, struct pinctrl_dev *pctldev,
else
setting->pctldev =
get_pinctrl_dev_from_devname(map->ctrl_dev_name);
if (setting->pctldev == NULL) {
if (!setting->pctldev) {
kfree(setting);
/* Do not defer probing of hogs (circular loop) */
if (!strcmp(map->ctrl_dev_name, map->dev_name))
@ -1024,6 +1024,16 @@ static struct pinctrl *create_pinctrl(struct device *dev,
/* Map must be for this device */
if (strcmp(map->dev_name, devname))
continue;
/*
* If pctldev is not null, we are claiming hog for it,
* that means, setting that is served by pctldev by itself.
*
* Thus we must skip map that is for this device but is served
* by other device.
*/
if (pctldev &&
strcmp(dev_name(pctldev->dev), map->ctrl_dev_name))
continue;
ret = add_setting(p, pctldev, map);
/*
@ -1080,7 +1090,7 @@ struct pinctrl *pinctrl_get(struct device *dev)
* return another pointer to it.
*/
p = find_pinctrl(dev);
if (p != NULL) {
if (p) {
dev_dbg(dev, "obtain a copy of previously claimed pinctrl\n");
kref_get(&p->users);
return p;
@ -1551,7 +1561,7 @@ static int pinctrl_pins_show(struct seq_file *s, void *what)
pin = pctldev->desc->pins[i].number;
desc = pin_desc_get(pctldev, pin);
/* Pin space may be sparse */
if (desc == NULL)
if (!desc)
continue;
seq_printf(s, "pin %d (%s) ", pin, desc->name);
@ -1718,7 +1728,7 @@ static int pinctrl_maps_show(struct seq_file *s, void *what)
break;
}
seq_printf(s, "\n");
seq_putc(s, '\n');
}
mutex_unlock(&pinctrl_maps_mutex);
@ -2131,7 +2141,7 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev)
{
struct pinctrl_gpio_range *range, *n;
if (pctldev == NULL)
if (!pctldev)
return;
mutex_lock(&pctldev->mutex);

View File

@ -2,7 +2,7 @@ config PINCTRL_IMX
bool
select GENERIC_PINCTRL_GROUPS
select GENERIC_PINMUX_FUNCTIONS
select PINCONF
select GENERIC_PINCONF
select REGMAP
config PINCTRL_IMX1_CORE

View File

@ -27,6 +27,7 @@
#include <linux/regmap.h>
#include "../core.h"
#include "../pinconf.h"
#include "../pinmux.h"
#include "pinctrl-imx.h"
@ -196,14 +197,16 @@ static int imx_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
if (info->flags & SHARE_MUX_CONF_REG) {
u32 reg;
reg = readl(ipctl->base + pin_reg->mux_reg);
reg &= ~(0x7 << 20);
reg |= (pin->mux_mode << 20);
reg &= ~info->mux_mask;
reg |= (pin->mux_mode << info->mux_shift);
writel(reg, ipctl->base + pin_reg->mux_reg);
dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n",
pin_reg->mux_reg, reg);
} else {
writel(pin->mux_mode, ipctl->base + pin_reg->mux_reg);
dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n",
pin_reg->mux_reg, pin->mux_mode);
}
dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n",
pin_reg->mux_reg, pin->mux_mode);
/*
* If the select input value begins with 0xff, it's a quirky
@ -287,7 +290,7 @@ static int imx_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
mux_pin:
reg = readl(ipctl->base + pin_reg->mux_reg);
reg &= ~(0x7 << 20);
reg &= ~info->mux_mask;
reg |= imx_pin->config;
writel(reg, ipctl->base + pin_reg->mux_reg);
@ -359,6 +362,62 @@ static const struct pinmux_ops imx_pmx_ops = {
.gpio_set_direction = imx_pmx_gpio_set_direction,
};
/* decode generic config into raw register values */
static u32 imx_pinconf_decode_generic_config(struct imx_pinctrl *ipctl,
unsigned long *configs,
unsigned int num_configs)
{
struct imx_pinctrl_soc_info *info = ipctl->info;
struct imx_cfg_params_decode *decode;
enum pin_config_param param;
u32 raw_config = 0;
u32 param_val;
int i, j;
WARN_ON(num_configs > info->num_decodes);
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
param_val = pinconf_to_config_argument(configs[i]);
decode = info->decodes;
for (j = 0; j < info->num_decodes; j++) {
if (param == decode->param) {
if (decode->invert)
param_val = !param_val;
raw_config |= (param_val << decode->shift)
& decode->mask;
break;
}
decode++;
}
}
if (info->fixup)
info->fixup(configs, num_configs, &raw_config);
return raw_config;
}
static u32 imx_pinconf_parse_generic_config(struct device_node *np,
struct imx_pinctrl *ipctl)
{
struct imx_pinctrl_soc_info *info = ipctl->info;
struct pinctrl_dev *pctl = ipctl->pctl;
unsigned int num_configs;
unsigned long *configs;
int ret;
if (!info->generic_pinconf)
return 0;
ret = pinconf_generic_parse_dt_config(np, pctl, &configs,
&num_configs);
if (ret)
return 0;
return imx_pinconf_decode_generic_config(ipctl, configs, num_configs);
}
static int imx_pinconf_get(struct pinctrl_dev *pctldev,
unsigned pin_id, unsigned long *config)
{
@ -375,7 +434,7 @@ static int imx_pinconf_get(struct pinctrl_dev *pctldev,
*config = readl(ipctl->base + pin_reg->conf_reg);
if (info->flags & SHARE_MUX_CONF_REG)
*config &= 0xffff;
*config &= ~info->mux_mask;
return 0;
}
@ -402,14 +461,16 @@ static int imx_pinconf_set(struct pinctrl_dev *pctldev,
if (info->flags & SHARE_MUX_CONF_REG) {
u32 reg;
reg = readl(ipctl->base + pin_reg->conf_reg);
reg &= ~0xffff;
reg &= info->mux_mask;
reg |= configs[i];
writel(reg, ipctl->base + pin_reg->conf_reg);
dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n",
pin_reg->conf_reg, reg);
} else {
writel(configs[i], ipctl->base + pin_reg->conf_reg);
dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
pin_reg->conf_reg, configs[i]);
}
dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
pin_reg->conf_reg, configs[i]);
} /* for each config */
return 0;
@ -475,9 +536,10 @@ static const struct pinconf_ops imx_pinconf_ops = {
static int imx_pinctrl_parse_groups(struct device_node *np,
struct group_desc *grp,
struct imx_pinctrl_soc_info *info,
struct imx_pinctrl *ipctl,
u32 index)
{
struct imx_pinctrl_soc_info *info = ipctl->info;
int size, pin_size;
const __be32 *list;
int i;
@ -489,25 +551,44 @@ static int imx_pinctrl_parse_groups(struct device_node *np,
pin_size = SHARE_FSL_PIN_SIZE;
else
pin_size = FSL_PIN_SIZE;
if (info->generic_pinconf)
pin_size -= 4;
/* Initialise group */
grp->name = np->name;
/*
* the binding format is fsl,pins = <PIN_FUNC_ID CONFIG ...>,
* do sanity check and calculate pins number
*
* First try legacy 'fsl,pins' property, then fall back to the
* generic 'pins'.
*
* Note: for generic 'pins' case, there's no CONFIG part in
* the binding format.
*/
list = of_get_property(np, "fsl,pins", &size);
if (!list) {
dev_err(info->dev, "no fsl,pins property in node %s\n", np->full_name);
return -EINVAL;
list = of_get_property(np, "pins", &size);
if (!list) {
dev_err(info->dev,
"no fsl,pins and pins property in node %s\n",
np->full_name);
return -EINVAL;
}
}
/* we do not check return since it's safe node passed down */
if (!size || size % pin_size) {
dev_err(info->dev, "Invalid fsl,pins property in node %s\n", np->full_name);
dev_err(info->dev, "Invalid fsl,pins or pins property in node %s\n",
np->full_name);
return -EINVAL;
}
/* first try to parse the generic pin config */
config = imx_pinconf_parse_generic_config(np, ipctl);
grp->num_pins = size / pin_size;
grp->data = devm_kzalloc(info->dev, grp->num_pins *
sizeof(struct imx_pin), GFP_KERNEL);
@ -544,11 +625,18 @@ static int imx_pinctrl_parse_groups(struct device_node *np,
pin->mux_mode = be32_to_cpu(*list++);
pin->input_val = be32_to_cpu(*list++);
/* SION bit is in mux register */
config = be32_to_cpu(*list++);
if (config & IMX_PAD_SION)
pin->mux_mode |= IOMUXC_CONFIG_SION;
pin->config = config & ~IMX_PAD_SION;
if (info->generic_pinconf) {
/* generic pin config decoded */
pin->config = config;
} else {
/* legacy pin config read from devicetree */
config = be32_to_cpu(*list++);
/* SION bit is in mux register */
if (config & IMX_PAD_SION)
pin->mux_mode |= IOMUXC_CONFIG_SION;
pin->config = config & ~IMX_PAD_SION;
}
dev_dbg(info->dev, "%s: 0x%x 0x%08lx", info->pins[pin_id].name,
pin->mux_mode, pin->config);
@ -581,9 +669,10 @@ static int imx_pinctrl_parse_functions(struct device_node *np,
dev_err(info->dev, "no groups defined in %s\n", np->full_name);
return -EINVAL;
}
func->group_names = devm_kzalloc(info->dev,
func->num_group_names *
func->group_names = devm_kcalloc(info->dev, func->num_group_names,
sizeof(char *), GFP_KERNEL);
if (!func->group_names)
return -ENOMEM;
for_each_child_of_node(np, child) {
func->group_names[i] = child->name;
@ -598,7 +687,7 @@ static int imx_pinctrl_parse_functions(struct device_node *np,
info->group_index++, grp);
mutex_unlock(&info->mutex);
imx_pinctrl_parse_groups(child, grp, info, i++);
imx_pinctrl_parse_groups(child, grp, ipctl, i++);
}
return 0;
@ -769,6 +858,10 @@ int imx_pinctrl_probe(struct platform_device *pdev,
imx_pinctrl_desc->confops = &imx_pinconf_ops;
imx_pinctrl_desc->owner = THIS_MODULE;
/* for generic pinconf */
imx_pinctrl_desc->custom_params = info->custom_params;
imx_pinctrl_desc->num_custom_params = info->num_custom_params;
mutex_init(&info->mutex);
ipctl->info = info;

View File

@ -15,6 +15,8 @@
#ifndef __DRIVERS_PINCTRL_IMX_H
#define __DRIVERS_PINCTRL_IMX_H
#include <linux/pinctrl/pinconf-generic.h>
struct platform_device;
/**
@ -44,6 +46,14 @@ struct imx_pin_reg {
s16 conf_reg;
};
/* decode a generic config into raw register value */
struct imx_cfg_params_decode {
enum pin_config_param param;
u32 mask;
u8 shift;
bool invert;
};
struct imx_pinctrl_soc_info {
struct device *dev;
const struct pinctrl_pin_desc *pins;
@ -53,8 +63,27 @@ struct imx_pinctrl_soc_info {
unsigned int flags;
const char *gpr_compatible;
struct mutex mutex;
/* MUX_MODE shift and mask in case SHARE_MUX_CONF_REG */
unsigned int mux_mask;
u8 mux_shift;
/* generic pinconf */
bool generic_pinconf;
const struct pinconf_generic_params *custom_params;
unsigned int num_custom_params;
struct imx_cfg_params_decode *decodes;
unsigned int num_decodes;
void (*fixup)(unsigned long *configs, unsigned int num_configs,
u32 *raw_config);
};
#define IMX_CFG_PARAMS_DECODE(p, m, o) \
{ .param = p, .mask = m, .shift = o, .invert = false, }
#define IMX_CFG_PARAMS_DECODE_INVERT(p, m, o) \
{ .param = p, .mask = m, .shift = o, .invert = true, }
#define SHARE_MUX_CONF_REG 0x1
#define ZERO_OFFSET_VALID 0x2

View File

@ -358,19 +358,19 @@ static const struct pinctrl_pin_desc imx7d_lpsr_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX7D_PAD_GPIO1_IO07),
};
static struct imx_pinctrl_soc_info imx7d_pinctrl_info = {
static const struct imx_pinctrl_soc_info imx7d_pinctrl_info = {
.pins = imx7d_pinctrl_pads,
.npins = ARRAY_SIZE(imx7d_pinctrl_pads),
.gpr_compatible = "fsl,imx7d-iomuxc-gpr",
};
static struct imx_pinctrl_soc_info imx7d_lpsr_pinctrl_info = {
static const struct imx_pinctrl_soc_info imx7d_lpsr_pinctrl_info = {
.pins = imx7d_lpsr_pinctrl_pads,
.npins = ARRAY_SIZE(imx7d_lpsr_pinctrl_pads),
.flags = ZERO_OFFSET_VALID,
};
static struct of_device_id imx7d_pinctrl_of_match[] = {
static const struct of_device_id imx7d_pinctrl_of_match[] = {
{ .compatible = "fsl,imx7d-iomuxc", .data = &imx7d_pinctrl_info, },
{ .compatible = "fsl,imx7d-iomuxc-lpsr", .data = &imx7d_lpsr_pinctrl_info },
{ /* sentinel */ }

View File

@ -299,6 +299,8 @@ static struct imx_pinctrl_soc_info vf610_pinctrl_info = {
.pins = vf610_pinctrl_pads,
.npins = ARRAY_SIZE(vf610_pinctrl_pads),
.flags = SHARE_MUX_CONF_REG | ZERO_OFFSET_VALID,
.mux_mask = 0x700000,
.mux_shift = 20,
};
static const struct of_device_id vf610_pinctrl_of_match[] = {

View File

@ -56,6 +56,14 @@ config PINCTRL_BROXTON
Broxton pinctrl driver provides an interface that allows
configuring of SoC pins and using them as GPIOs.
config PINCTRL_CANNONLAKE
tristate "Intel Cannon Lake PCH pinctrl and GPIO driver"
depends on ACPI
select PINCTRL_INTEL
help
This pinctrl driver provides an interface that allows configuring
of Intel Cannon Lake PCH pins and using them as GPIOs.
config PINCTRL_GEMINILAKE
tristate "Intel Gemini Lake SoC pinctrl and GPIO driver"
depends on ACPI

View File

@ -5,5 +5,6 @@ obj-$(CONFIG_PINCTRL_CHERRYVIEW) += pinctrl-cherryview.o
obj-$(CONFIG_PINCTRL_MERRIFIELD) += pinctrl-merrifield.o
obj-$(CONFIG_PINCTRL_INTEL) += pinctrl-intel.o
obj-$(CONFIG_PINCTRL_BROXTON) += pinctrl-broxton.o
obj-$(CONFIG_PINCTRL_CANNONLAKE) += pinctrl-cannonlake.o
obj-$(CONFIG_PINCTRL_GEMINILAKE) += pinctrl-geminilake.o
obj-$(CONFIG_PINCTRL_SUNRISEPOINT) += pinctrl-sunrisepoint.o

View File

@ -0,0 +1,442 @@
/*
* Intel Cannon Lake PCH pinctrl/GPIO driver
*
* Copyright (C) 2017, Intel Corporation
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#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"
#define CNL_PAD_OWN 0x020
#define CNL_PADCFGLOCK 0x080
#define CNL_HOSTSW_OWN 0x0b0
#define CNL_GPI_IE 0x120
#define CNL_GPP(r, s, e) \
{ \
.reg_num = (r), \
.base = (s), \
.size = ((e) - (s) + 1), \
}
#define CNL_COMMUNITY(b, s, e, g) \
{ \
.barno = (b), \
.padown_offset = CNL_PAD_OWN, \
.padcfglock_offset = CNL_PADCFGLOCK, \
.hostown_offset = CNL_HOSTSW_OWN, \
.ie_offset = CNL_GPI_IE, \
.pin_base = (s), \
.npins = ((e) - (s) + 1), \
.gpps = (g), \
.ngpps = ARRAY_SIZE(g), \
}
/* Cannon Lake-LP */
static const struct pinctrl_pin_desc cnllp_pins[] = {
/* GPP_A */
PINCTRL_PIN(0, "RCINB"),
PINCTRL_PIN(1, "LAD_0"),
PINCTRL_PIN(2, "LAD_1"),
PINCTRL_PIN(3, "LAD_2"),
PINCTRL_PIN(4, "LAD_3"),
PINCTRL_PIN(5, "LFRAMEB"),
PINCTRL_PIN(6, "SERIRQ"),
PINCTRL_PIN(7, "PIRQAB"),
PINCTRL_PIN(8, "CLKRUNB"),
PINCTRL_PIN(9, "CLKOUT_LPC_0"),
PINCTRL_PIN(10, "CLKOUT_LPC_1"),
PINCTRL_PIN(11, "PMEB"),
PINCTRL_PIN(12, "BM_BUSYB"),
PINCTRL_PIN(13, "SUSWARNB_SUSPWRDNACK"),
PINCTRL_PIN(14, "SUS_STATB"),
PINCTRL_PIN(15, "SUSACKB"),
PINCTRL_PIN(16, "SD_1P8_SEL"),
PINCTRL_PIN(17, "SD_PWR_EN_B"),
PINCTRL_PIN(18, "ISH_GP_0"),
PINCTRL_PIN(19, "ISH_GP_1"),
PINCTRL_PIN(20, "ISH_GP_2"),
PINCTRL_PIN(21, "ISH_GP_3"),
PINCTRL_PIN(22, "ISH_GP_4"),
PINCTRL_PIN(23, "ISH_GP_5"),
PINCTRL_PIN(24, "ESPI_CLK_LOOPBK"),
/* GPP_B */
PINCTRL_PIN(25, "CORE_VID_0"),
PINCTRL_PIN(26, "CORE_VID_1"),
PINCTRL_PIN(27, "VRALERTB"),
PINCTRL_PIN(28, "CPU_GP_2"),
PINCTRL_PIN(29, "CPU_GP_3"),
PINCTRL_PIN(30, "SRCCLKREQB_0"),
PINCTRL_PIN(31, "SRCCLKREQB_1"),
PINCTRL_PIN(32, "SRCCLKREQB_2"),
PINCTRL_PIN(33, "SRCCLKREQB_3"),
PINCTRL_PIN(34, "SRCCLKREQB_4"),
PINCTRL_PIN(35, "SRCCLKREQB_5"),
PINCTRL_PIN(36, "EXT_PWR_GATEB"),
PINCTRL_PIN(37, "SLP_S0B"),
PINCTRL_PIN(38, "PLTRSTB"),
PINCTRL_PIN(39, "SPKR"),
PINCTRL_PIN(40, "GSPI0_CS0B"),
PINCTRL_PIN(41, "GSPI0_CLK"),
PINCTRL_PIN(42, "GSPI0_MISO"),
PINCTRL_PIN(43, "GSPI0_MOSI"),
PINCTRL_PIN(44, "GSPI1_CS0B"),
PINCTRL_PIN(45, "GSPI1_CLK"),
PINCTRL_PIN(46, "GSPI1_MISO"),
PINCTRL_PIN(47, "GSPI1_MOSI"),
PINCTRL_PIN(48, "SML1ALERTB"),
PINCTRL_PIN(49, "GSPI0_CLK_LOOPBK"),
PINCTRL_PIN(50, "GSPI1_CLK_LOOPBK"),
/* GPP_G */
PINCTRL_PIN(51, "SD3_CMD"),
PINCTRL_PIN(52, "SD3_D0_SD4_RCLK_P"),
PINCTRL_PIN(53, "SD3_D1_SD4_RCLK_N"),
PINCTRL_PIN(54, "SD3_D2"),
PINCTRL_PIN(55, "SD3_D3"),
PINCTRL_PIN(56, "SD3_CDB"),
PINCTRL_PIN(57, "SD3_CLK"),
PINCTRL_PIN(58, "SD3_WP"),
/* SPI */
PINCTRL_PIN(59, "SPI0_IO_2"),
PINCTRL_PIN(60, "SPI0_IO_3"),
PINCTRL_PIN(61, "SPI0_MOSI_IO_0"),
PINCTRL_PIN(62, "SPI0_MISO_IO_1"),
PINCTRL_PIN(63, "SPI0_TPM_CSB"),
PINCTRL_PIN(64, "SPI0_FLASH_0_CSB"),
PINCTRL_PIN(65, "SPI0_FLASH_1_CSB"),
PINCTRL_PIN(66, "SPI0_CLK"),
PINCTRL_PIN(67, "SPI0_CLK_LOOPBK"),
/* GPP_D */
PINCTRL_PIN(68, "SPI1_CSB"),
PINCTRL_PIN(69, "SPI1_CLK"),
PINCTRL_PIN(70, "SPI1_MISO_IO_1"),
PINCTRL_PIN(71, "SPI1_MOSI_IO_0"),
PINCTRL_PIN(72, "IMGCLKOUT_0"),
PINCTRL_PIN(73, "ISH_I2C0_SDA"),
PINCTRL_PIN(74, "ISH_I2C0_SCL"),
PINCTRL_PIN(75, "ISH_I2C1_SDA"),
PINCTRL_PIN(76, "ISH_I2C1_SCL"),
PINCTRL_PIN(77, "ISH_SPI_CSB"),
PINCTRL_PIN(78, "ISH_SPI_CLK"),
PINCTRL_PIN(79, "ISH_SPI_MISO"),
PINCTRL_PIN(80, "ISH_SPI_MOSI"),
PINCTRL_PIN(81, "ISH_UART0_RXD"),
PINCTRL_PIN(82, "ISH_UART0_TXD"),
PINCTRL_PIN(83, "ISH_UART0_RTSB"),
PINCTRL_PIN(84, "ISH_UART0_CTSB"),
PINCTRL_PIN(85, "DMIC_CLK_1"),
PINCTRL_PIN(86, "DMIC_DATA_1"),
PINCTRL_PIN(87, "DMIC_CLK_0"),
PINCTRL_PIN(88, "DMIC_DATA_0"),
PINCTRL_PIN(89, "SPI1_IO_2"),
PINCTRL_PIN(90, "SPI1_IO_3"),
PINCTRL_PIN(91, "SSP_MCLK"),
PINCTRL_PIN(92, "GSPI2_CLK_LOOPBK"),
/* GPP_F */
PINCTRL_PIN(93, "CNV_GNSS_PA_BLANKING"),
PINCTRL_PIN(94, "CNV_GNSS_FTA"),
PINCTRL_PIN(95, "CNV_GNSS_SYSCK"),
PINCTRL_PIN(96, "EMMC_HIP_MON"),
PINCTRL_PIN(97, "CNV_BRI_DT"),
PINCTRL_PIN(98, "CNV_BRI_RSP"),
PINCTRL_PIN(99, "CNV_RGI_DT"),
PINCTRL_PIN(100, "CNV_RGI_RSP"),
PINCTRL_PIN(101, "CNV_MFUART2_RXD"),
PINCTRL_PIN(102, "CNV_MFUART2_TXD"),
PINCTRL_PIN(103, "GPP_F_10"),
PINCTRL_PIN(104, "EMMC_CMD"),
PINCTRL_PIN(105, "EMMC_DATA_0"),
PINCTRL_PIN(106, "EMMC_DATA_1"),
PINCTRL_PIN(107, "EMMC_DATA_2"),
PINCTRL_PIN(108, "EMMC_DATA_3"),
PINCTRL_PIN(109, "EMMC_DATA_4"),
PINCTRL_PIN(110, "EMMC_DATA_5"),
PINCTRL_PIN(111, "EMMC_DATA_6"),
PINCTRL_PIN(112, "EMMC_DATA_7"),
PINCTRL_PIN(113, "EMMC_RCLK"),
PINCTRL_PIN(114, "EMMC_CLK"),
PINCTRL_PIN(115, "EMMC_RESETB"),
PINCTRL_PIN(116, "A4WP_PRESENT"),
/* GPP_H */
PINCTRL_PIN(117, "SSP2_SCLK"),
PINCTRL_PIN(118, "SSP2_SFRM"),
PINCTRL_PIN(119, "SSP2_TXD"),
PINCTRL_PIN(120, "SSP2_RXD"),
PINCTRL_PIN(121, "I2C2_SDA"),
PINCTRL_PIN(122, "I2C2_SCL"),
PINCTRL_PIN(123, "I2C3_SDA"),
PINCTRL_PIN(124, "I2C3_SCL"),
PINCTRL_PIN(125, "I2C4_SDA"),
PINCTRL_PIN(126, "I2C4_SCL"),
PINCTRL_PIN(127, "I2C5_SDA"),
PINCTRL_PIN(128, "I2C5_SCL"),
PINCTRL_PIN(129, "M2_SKT2_CFG_0"),
PINCTRL_PIN(130, "M2_SKT2_CFG_1"),
PINCTRL_PIN(131, "M2_SKT2_CFG_2"),
PINCTRL_PIN(132, "M2_SKT2_CFG_3"),
PINCTRL_PIN(133, "DDPF_CTRLCLK"),
PINCTRL_PIN(134, "DDPF_CTRLDATA"),
PINCTRL_PIN(135, "CPU_VCCIO_PWR_GATEB"),
PINCTRL_PIN(136, "TIMESYNC_0"),
PINCTRL_PIN(137, "IMGCLKOUT_1"),
PINCTRL_PIN(138, "GPPC_H_21"),
PINCTRL_PIN(139, "GPPC_H_22"),
PINCTRL_PIN(140, "GPPC_H_23"),
/* vGPIO */
PINCTRL_PIN(141, "CNV_BTEN"),
PINCTRL_PIN(142, "CNV_GNEN"),
PINCTRL_PIN(143, "CNV_WFEN"),
PINCTRL_PIN(144, "CNV_WCEN"),
PINCTRL_PIN(145, "CNV_BT_HOST_WAKEB"),
PINCTRL_PIN(146, "CNV_BT_IF_SELECT"),
PINCTRL_PIN(147, "vCNV_BT_UART_TXD"),
PINCTRL_PIN(148, "vCNV_BT_UART_RXD"),
PINCTRL_PIN(149, "vCNV_BT_UART_CTS_B"),
PINCTRL_PIN(150, "vCNV_BT_UART_RTS_B"),
PINCTRL_PIN(151, "vCNV_MFUART1_TXD"),
PINCTRL_PIN(152, "vCNV_MFUART1_RXD"),
PINCTRL_PIN(153, "vCNV_MFUART1_CTS_B"),
PINCTRL_PIN(154, "vCNV_MFUART1_RTS_B"),
PINCTRL_PIN(155, "vCNV_GNSS_UART_TXD"),
PINCTRL_PIN(156, "vCNV_GNSS_UART_RXD"),
PINCTRL_PIN(157, "vCNV_GNSS_UART_CTS_B"),
PINCTRL_PIN(158, "vCNV_GNSS_UART_RTS_B"),
PINCTRL_PIN(159, "vUART0_TXD"),
PINCTRL_PIN(160, "vUART0_RXD"),
PINCTRL_PIN(161, "vUART0_CTS_B"),
PINCTRL_PIN(162, "vUART0_RTS_B"),
PINCTRL_PIN(163, "vISH_UART0_TXD"),
PINCTRL_PIN(164, "vISH_UART0_RXD"),
PINCTRL_PIN(165, "vISH_UART0_CTS_B"),
PINCTRL_PIN(166, "vISH_UART0_RTS_B"),
PINCTRL_PIN(167, "vISH_UART1_TXD"),
PINCTRL_PIN(168, "vISH_UART1_RXD"),
PINCTRL_PIN(169, "vISH_UART1_CTS_B"),
PINCTRL_PIN(170, "vISH_UART1_RTS_B"),
PINCTRL_PIN(171, "vCNV_BT_I2S_BCLK"),
PINCTRL_PIN(172, "vCNV_BT_I2S_WS_SYNC"),
PINCTRL_PIN(173, "vCNV_BT_I2S_SDO"),
PINCTRL_PIN(174, "vCNV_BT_I2S_SDI"),
PINCTRL_PIN(175, "vSSP2_SCLK"),
PINCTRL_PIN(176, "vSSP2_SFRM"),
PINCTRL_PIN(177, "vSSP2_TXD"),
PINCTRL_PIN(178, "vSSP2_RXD"),
PINCTRL_PIN(179, "vCNV_GNSS_HOST_WAKEB"),
PINCTRL_PIN(180, "vSD3_CD_B"),
/* GPP_C */
PINCTRL_PIN(181, "SMBCLK"),
PINCTRL_PIN(182, "SMBDATA"),
PINCTRL_PIN(183, "SMBALERTB"),
PINCTRL_PIN(184, "SML0CLK"),
PINCTRL_PIN(185, "SML0DATA"),
PINCTRL_PIN(186, "SML0ALERTB"),
PINCTRL_PIN(187, "SML1CLK"),
PINCTRL_PIN(188, "SML1DATA"),
PINCTRL_PIN(189, "UART0_RXD"),
PINCTRL_PIN(190, "UART0_TXD"),
PINCTRL_PIN(191, "UART0_RTSB"),
PINCTRL_PIN(192, "UART0_CTSB"),
PINCTRL_PIN(193, "UART1_RXD"),
PINCTRL_PIN(194, "UART1_TXD"),
PINCTRL_PIN(195, "UART1_RTSB"),
PINCTRL_PIN(196, "UART1_CTSB"),
PINCTRL_PIN(197, "I2C0_SDA"),
PINCTRL_PIN(198, "I2C0_SCL"),
PINCTRL_PIN(199, "I2C1_SDA"),
PINCTRL_PIN(200, "I2C1_SCL"),
PINCTRL_PIN(201, "UART2_RXD"),
PINCTRL_PIN(202, "UART2_TXD"),
PINCTRL_PIN(203, "UART2_RTSB"),
PINCTRL_PIN(204, "UART2_CTSB"),
/* GPP_E */
PINCTRL_PIN(205, "SATAXPCIE_0"),
PINCTRL_PIN(206, "SATAXPCIE_1"),
PINCTRL_PIN(207, "SATAXPCIE_2"),
PINCTRL_PIN(208, "CPU_GP_0"),
PINCTRL_PIN(209, "SATA_DEVSLP_0"),
PINCTRL_PIN(210, "SATA_DEVSLP_1"),
PINCTRL_PIN(211, "SATA_DEVSLP_2"),
PINCTRL_PIN(212, "CPU_GP_1"),
PINCTRL_PIN(213, "SATA_LEDB"),
PINCTRL_PIN(214, "USB2_OCB_0"),
PINCTRL_PIN(215, "USB2_OCB_1"),
PINCTRL_PIN(216, "USB2_OCB_2"),
PINCTRL_PIN(217, "USB2_OCB_3"),
PINCTRL_PIN(218, "DDSP_HPD_0"),
PINCTRL_PIN(219, "DDSP_HPD_1"),
PINCTRL_PIN(220, "DDSP_HPD_2"),
PINCTRL_PIN(221, "DDSP_HPD_3"),
PINCTRL_PIN(222, "EDP_HPD"),
PINCTRL_PIN(223, "DDPB_CTRLCLK"),
PINCTRL_PIN(224, "DDPB_CTRLDATA"),
PINCTRL_PIN(225, "DDPC_CTRLCLK"),
PINCTRL_PIN(226, "DDPC_CTRLDATA"),
PINCTRL_PIN(227, "DDPD_CTRLCLK"),
PINCTRL_PIN(228, "DDPD_CTRLDATA"),
/* JTAG */
PINCTRL_PIN(229, "JTAG_TDO"),
PINCTRL_PIN(230, "JTAGX"),
PINCTRL_PIN(231, "PRDYB"),
PINCTRL_PIN(232, "PREQB"),
PINCTRL_PIN(233, "CPU_TRSTB"),
PINCTRL_PIN(234, "JTAG_TDI"),
PINCTRL_PIN(235, "JTAG_TMS"),
PINCTRL_PIN(236, "JTAG_TCK"),
PINCTRL_PIN(237, "ITP_PMODE"),
/* HVCMOS */
PINCTRL_PIN(238, "L_BKLTEN"),
PINCTRL_PIN(239, "L_BKLTCTL"),
PINCTRL_PIN(240, "L_VDDEN"),
PINCTRL_PIN(241, "SYS_PWROK"),
PINCTRL_PIN(242, "SYS_RESETB"),
PINCTRL_PIN(243, "MLK_RSTB"),
};
static const unsigned int cnllp_spi0_pins[] = { 40, 41, 42, 43, 7 };
static const unsigned int cnllp_spi0_modes[] = { 1, 1, 1, 1, 2 };
static const unsigned int cnllp_spi1_pins[] = { 44, 45, 46, 47, 11 };
static const unsigned int cnllp_spi1_modes[] = { 1, 1, 1, 1, 2 };
static const unsigned int cnllp_spi2_pins[] = { 77, 78, 79, 80, 83 };
static const unsigned int cnllp_spi2_modes[] = { 3, 3, 3, 3, 2 };
static const unsigned int cnllp_i2c0_pins[] = { 197, 198 };
static const unsigned int cnllp_i2c1_pins[] = { 199, 200 };
static const unsigned int cnllp_i2c2_pins[] = { 121, 122 };
static const unsigned int cnllp_i2c3_pins[] = { 123, 124 };
static const unsigned int cnllp_i2c4_pins[] = { 125, 126 };
static const unsigned int cnllp_i2c5_pins[] = { 127, 128 };
static const unsigned int cnllp_uart0_pins[] = { 189, 190, 191, 192 };
static const unsigned int cnllp_uart1_pins[] = { 193, 194, 195, 196 };
static const unsigned int cnllp_uart2_pins[] = { 201, 202, 203, 204 };
static const struct intel_pingroup cnllp_groups[] = {
PIN_GROUP("spi0_grp", cnllp_spi0_pins, cnllp_spi0_modes),
PIN_GROUP("spi1_grp", cnllp_spi1_pins, cnllp_spi1_modes),
PIN_GROUP("spi2_grp", cnllp_spi2_pins, cnllp_spi2_modes),
PIN_GROUP("i2c0_grp", cnllp_i2c0_pins, 1),
PIN_GROUP("i2c1_grp", cnllp_i2c1_pins, 1),
PIN_GROUP("i2c2_grp", cnllp_i2c2_pins, 1),
PIN_GROUP("i2c3_grp", cnllp_i2c3_pins, 1),
PIN_GROUP("i2c4_grp", cnllp_i2c4_pins, 1),
PIN_GROUP("i2c5_grp", cnllp_i2c5_pins, 1),
PIN_GROUP("uart0_grp", cnllp_uart0_pins, 1),
PIN_GROUP("uart1_grp", cnllp_uart1_pins, 1),
PIN_GROUP("uart2_grp", cnllp_uart2_pins, 1),
};
static const char * const cnllp_spi0_groups[] = { "spi0_grp" };
static const char * const cnllp_spi1_groups[] = { "spi1_grp" };
static const char * const cnllp_spi2_groups[] = { "spi2_grp" };
static const char * const cnllp_i2c0_groups[] = { "i2c0_grp" };
static const char * const cnllp_i2c1_groups[] = { "i2c1_grp" };
static const char * const cnllp_i2c2_groups[] = { "i2c2_grp" };
static const char * const cnllp_i2c3_groups[] = { "i2c3_grp" };
static const char * const cnllp_i2c4_groups[] = { "i2c4_grp" };
static const char * const cnllp_i2c5_groups[] = { "i2c5_grp" };
static const char * const cnllp_uart0_groups[] = { "uart0_grp" };
static const char * const cnllp_uart1_groups[] = { "uart1_grp" };
static const char * const cnllp_uart2_groups[] = { "uart2_grp" };
static const struct intel_function cnllp_functions[] = {
FUNCTION("spi0", cnllp_spi0_groups),
FUNCTION("spi1", cnllp_spi1_groups),
FUNCTION("spi2", cnllp_spi2_groups),
FUNCTION("i2c0", cnllp_i2c0_groups),
FUNCTION("i2c1", cnllp_i2c1_groups),
FUNCTION("i2c2", cnllp_i2c2_groups),
FUNCTION("i2c3", cnllp_i2c3_groups),
FUNCTION("i2c4", cnllp_i2c4_groups),
FUNCTION("i2c5", cnllp_i2c5_groups),
FUNCTION("uart0", cnllp_uart0_groups),
FUNCTION("uart1", cnllp_uart1_groups),
FUNCTION("uart2", cnllp_uart2_groups),
};
static const struct intel_padgroup cnllp_community0_gpps[] = {
CNL_GPP(0, 0, 24), /* GPP_A */
CNL_GPP(1, 25, 50), /* GPP_B */
CNL_GPP(2, 51, 58), /* GPP_G */
CNL_GPP(3, 59, 67), /* SPI */
};
static const struct intel_padgroup cnllp_community1_gpps[] = {
CNL_GPP(0, 68, 92), /* GPP_D */
CNL_GPP(1, 93, 116), /* GPP_F */
CNL_GPP(2, 117, 140), /* GPP_H */
CNL_GPP(3, 141, 172), /* vGPIO */
CNL_GPP(4, 173, 180), /* vGPIO */
};
static const struct intel_padgroup cnllp_community4_gpps[] = {
CNL_GPP(0, 181, 204), /* GPP_C */
CNL_GPP(1, 205, 228), /* GPP_E */
CNL_GPP(2, 229, 237), /* JTAG */
CNL_GPP(3, 238, 243), /* HVCMOS */
};
static const struct intel_community cnllp_communities[] = {
CNL_COMMUNITY(0, 0, 67, cnllp_community0_gpps),
CNL_COMMUNITY(1, 68, 180, cnllp_community1_gpps),
CNL_COMMUNITY(2, 181, 243, cnllp_community4_gpps),
};
static const struct intel_pinctrl_soc_data cnllp_soc_data = {
.pins = cnllp_pins,
.npins = ARRAY_SIZE(cnllp_pins),
.groups = cnllp_groups,
.ngroups = ARRAY_SIZE(cnllp_groups),
.functions = cnllp_functions,
.nfunctions = ARRAY_SIZE(cnllp_functions),
.communities = cnllp_communities,
.ncommunities = ARRAY_SIZE(cnllp_communities),
};
static const struct acpi_device_id cnl_pinctrl_acpi_match[] = {
{ "INT34BB", (kernel_ulong_t)&cnllp_soc_data },
{ },
};
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);
}
static const struct dev_pm_ops cnl_pinctrl_pm_ops = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
intel_pinctrl_resume)
};
static struct platform_driver cnl_pinctrl_driver = {
.probe = cnl_pinctrl_probe,
.driver = {
.name = "cannonlake-pinctrl",
.acpi_match_table = cnl_pinctrl_acpi_match,
.pm = &cnl_pinctrl_pm_ops,
},
};
module_platform_driver(cnl_pinctrl_driver);
MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
MODULE_DESCRIPTION("Intel Cannon Lake PCH pinctrl/GPIO driver");
MODULE_LICENSE("GPL v2");

View File

@ -117,6 +117,7 @@ struct intel_pinctrl {
};
#define pin_to_padno(c, p) ((p) - (c)->pin_base)
#define padgroup_offset(g, p) ((p) - (g)->base)
static struct intel_community *intel_get_community(struct intel_pinctrl *pctrl,
unsigned pin)
@ -135,6 +136,22 @@ static struct intel_community *intel_get_community(struct intel_pinctrl *pctrl,
return NULL;
}
static const struct intel_padgroup *
intel_community_get_padgroup(const struct intel_community *community,
unsigned pin)
{
int i;
for (i = 0; i < community->ngpps; i++) {
const struct intel_padgroup *padgrp = &community->gpps[i];
if (pin >= padgrp->base && pin < padgrp->base + padgrp->size)
return padgrp;
}
return NULL;
}
static void __iomem *intel_get_padcfg(struct intel_pinctrl *pctrl, unsigned pin,
unsigned reg)
{
@ -158,7 +175,8 @@ static void __iomem *intel_get_padcfg(struct intel_pinctrl *pctrl, unsigned pin,
static bool intel_pad_owned_by_host(struct intel_pinctrl *pctrl, unsigned pin)
{
const struct intel_community *community;
unsigned padno, gpp, offset, group;
const struct intel_padgroup *padgrp;
unsigned gpp, offset, gpp_offset;
void __iomem *padown;
community = intel_get_community(pctrl, pin);
@ -167,19 +185,23 @@ static bool intel_pad_owned_by_host(struct intel_pinctrl *pctrl, unsigned pin)
if (!community->padown_offset)
return true;
padno = pin_to_padno(community, pin);
group = padno / community->gpp_size;
gpp = PADOWN_GPP(padno % community->gpp_size);
offset = community->padown_offset + 0x10 * group + gpp * 4;
padgrp = intel_community_get_padgroup(community, pin);
if (!padgrp)
return false;
gpp_offset = padgroup_offset(padgrp, pin);
gpp = PADOWN_GPP(gpp_offset);
offset = community->padown_offset + padgrp->padown_num * 4 + gpp * 4;
padown = community->regs + offset;
return !(readl(padown) & PADOWN_MASK(padno));
return !(readl(padown) & PADOWN_MASK(gpp_offset));
}
static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned pin)
{
const struct intel_community *community;
unsigned padno, gpp, offset;
const struct intel_padgroup *padgrp;
unsigned offset, gpp_offset;
void __iomem *hostown;
community = intel_get_community(pctrl, pin);
@ -188,18 +210,22 @@ static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned pin)
if (!community->hostown_offset)
return false;
padno = pin_to_padno(community, pin);
gpp = padno / community->gpp_size;
offset = community->hostown_offset + gpp * 4;
padgrp = intel_community_get_padgroup(community, pin);
if (!padgrp)
return true;
gpp_offset = padgroup_offset(padgrp, pin);
offset = community->hostown_offset + padgrp->reg_num * 4;
hostown = community->regs + offset;
return !(readl(hostown) & BIT(padno % community->gpp_size));
return !(readl(hostown) & BIT(gpp_offset));
}
static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned pin)
{
struct intel_community *community;
unsigned padno, gpp, offset;
const struct intel_padgroup *padgrp;
unsigned offset, gpp_offset;
u32 value;
community = intel_get_community(pctrl, pin);
@ -208,22 +234,25 @@ static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned pin)
if (!community->padcfglock_offset)
return false;
padno = pin_to_padno(community, pin);
gpp = padno / community->gpp_size;
padgrp = intel_community_get_padgroup(community, pin);
if (!padgrp)
return true;
gpp_offset = padgroup_offset(padgrp, pin);
/*
* If PADCFGLOCK and PADCFGLOCKTX bits are both clear for this pad,
* the pad is considered unlocked. Any other case means that it is
* either fully or partially locked and we don't touch it.
*/
offset = community->padcfglock_offset + gpp * 8;
offset = community->padcfglock_offset + padgrp->reg_num * 8;
value = readl(community->regs + offset);
if (value & BIT(pin % community->gpp_size))
if (value & BIT(gpp_offset))
return true;
offset = community->padcfglock_offset + 4 + gpp * 8;
offset = community->padcfglock_offset + 4 + padgrp->reg_num * 8;
value = readl(community->regs + offset);
if (value & BIT(pin % community->gpp_size))
if (value & BIT(gpp_offset))
return true;
return false;
@ -369,7 +398,11 @@ static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function,
value = readl(padcfg0);
value &= ~PADCFG0_PMODE_MASK;
value |= grp->mode << PADCFG0_PMODE_SHIFT;
if (grp->modes)
value |= grp->modes[i] << PADCFG0_PMODE_SHIFT;
else
value |= grp->mode << PADCFG0_PMODE_SHIFT;
writel(value, padcfg0);
}
@ -777,18 +810,22 @@ static void intel_gpio_irq_ack(struct irq_data *d)
const struct intel_community *community;
unsigned pin = irqd_to_hwirq(d);
raw_spin_lock(&pctrl->lock);
community = intel_get_community(pctrl, pin);
if (community) {
unsigned padno = pin_to_padno(community, pin);
unsigned gpp_offset = padno % community->gpp_size;
unsigned gpp = padno / community->gpp_size;
const struct intel_padgroup *padgrp;
unsigned gpp, gpp_offset;
padgrp = intel_community_get_padgroup(community, pin);
if (!padgrp)
return;
gpp = padgrp->reg_num;
gpp_offset = padgroup_offset(padgrp, pin);
raw_spin_lock(&pctrl->lock);
writel(BIT(gpp_offset), community->regs + GPI_IS + gpp * 4);
raw_spin_unlock(&pctrl->lock);
}
raw_spin_unlock(&pctrl->lock);
}
static void intel_gpio_irq_enable(struct irq_data *d)
@ -797,27 +834,30 @@ static void intel_gpio_irq_enable(struct irq_data *d)
struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
const struct intel_community *community;
unsigned pin = irqd_to_hwirq(d);
unsigned long flags;
raw_spin_lock_irqsave(&pctrl->lock, flags);
community = intel_get_community(pctrl, pin);
if (community) {
unsigned padno = pin_to_padno(community, pin);
unsigned gpp_size = community->gpp_size;
unsigned gpp_offset = padno % gpp_size;
unsigned gpp = padno / gpp_size;
const struct intel_padgroup *padgrp;
unsigned gpp, gpp_offset;
unsigned long flags;
u32 value;
padgrp = intel_community_get_padgroup(community, pin);
if (!padgrp)
return;
gpp = padgrp->reg_num;
gpp_offset = padgroup_offset(padgrp, pin);
raw_spin_lock_irqsave(&pctrl->lock, flags);
/* Clear interrupt status first to avoid unexpected interrupt */
writel(BIT(gpp_offset), community->regs + GPI_IS + gpp * 4);
value = readl(community->regs + community->ie_offset + gpp * 4);
value |= BIT(gpp_offset);
writel(value, community->regs + community->ie_offset + gpp * 4);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
}
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
}
static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
@ -826,28 +866,33 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
const struct intel_community *community;
unsigned pin = irqd_to_hwirq(d);
unsigned long flags;
raw_spin_lock_irqsave(&pctrl->lock, flags);
community = intel_get_community(pctrl, pin);
if (community) {
unsigned padno = pin_to_padno(community, pin);
unsigned gpp_offset = padno % community->gpp_size;
unsigned gpp = padno / community->gpp_size;
const struct intel_padgroup *padgrp;
unsigned gpp, gpp_offset;
unsigned long flags;
void __iomem *reg;
u32 value;
padgrp = intel_community_get_padgroup(community, pin);
if (!padgrp)
return;
gpp = padgrp->reg_num;
gpp_offset = padgroup_offset(padgrp, pin);
reg = community->regs + community->ie_offset + gpp * 4;
raw_spin_lock_irqsave(&pctrl->lock, flags);
value = readl(reg);
if (mask)
value &= ~BIT(gpp_offset);
else
value |= BIT(gpp_offset);
writel(value, reg);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
}
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
}
static void intel_gpio_irq_mask(struct irq_data *d)
@ -938,23 +983,20 @@ static irqreturn_t intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl,
int gpp;
for (gpp = 0; gpp < community->ngpps; gpp++) {
const struct intel_padgroup *padgrp = &community->gpps[gpp];
unsigned long pending, enabled, gpp_offset;
pending = readl(community->regs + GPI_IS + gpp * 4);
pending = readl(community->regs + GPI_IS + padgrp->reg_num * 4);
enabled = readl(community->regs + community->ie_offset +
gpp * 4);
padgrp->reg_num * 4);
/* Only interrupts that are enabled */
pending &= enabled;
for_each_set_bit(gpp_offset, &pending, community->gpp_size) {
for_each_set_bit(gpp_offset, &pending, padgrp->size) {
unsigned padno, irq;
/*
* The last group in community can have less pins
* than NPADS_IN_GPP.
*/
padno = gpp_offset + gpp * community->gpp_size;
padno = padgrp->base - community->pin_base + gpp_offset;
if (padno >= community->npins)
break;
@ -1045,6 +1087,56 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
return 0;
}
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;
size_t ngpps, i;
if (community->gpps)
ngpps = community->ngpps;
else
ngpps = DIV_ROUND_UP(community->npins, community->gpp_size);
gpps = devm_kcalloc(pctrl->dev, ngpps, sizeof(*gpps), GFP_KERNEL);
if (!gpps)
return -ENOMEM;
for (i = 0; i < ngpps; i++) {
if (community->gpps) {
gpps[i] = community->gpps[i];
} else {
unsigned gpp_size = community->gpp_size;
gpps[i].reg_num = i;
gpps[i].base = community->pin_base + i * gpp_size;
gpps[i].size = min(gpp_size, npins);
npins -= gpps[i].size;
}
if (gpps[i].size > 32)
return -EINVAL;
gpps[i].padown_num = padown_num;
/*
* In older hardware the number of padown registers per
* group is fixed regardless of the group size.
*/
if (community->gpp_num_padown_regs)
padown_num += community->gpp_num_padown_regs;
else
padown_num += DIV_ROUND_UP(gpps[i].size * 4, 32);
}
community->ngpps = ngpps;
community->gpps = gpps;
return 0;
}
static int intel_pinctrl_pm_init(struct intel_pinctrl *pctrl)
{
#ifdef CONFIG_PM_SLEEP
@ -1142,8 +1234,10 @@ int intel_pinctrl_probe(struct platform_device *pdev,
community->regs = regs;
community->pad_regs = regs + padbar;
community->ngpps = DIV_ROUND_UP(community->npins,
community->gpp_size);
ret = intel_pinctrl_add_padgroups(pctrl, community);
if (ret)
return ret;
}
irq = platform_get_irq(pdev, 0);

View File

@ -22,13 +22,16 @@ struct device;
* @name: Name of the groups
* @pins: All pins in this group
* @npins: Number of pins in this groups
* @mode: Native mode in which the group is muxed out @pins
* @mode: Native mode in which the group is muxed out @pins. Used if @modes
* is %NULL.
* @modes: If not %NULL this will hold mode for each pin in @pins
*/
struct intel_pingroup {
const char *name;
const unsigned *pins;
size_t npins;
unsigned short mode;
const unsigned *modes;
};
/**
@ -43,6 +46,23 @@ struct intel_function {
size_t ngroups;
};
/**
* struct intel_padgroup - Hardware pad group information
* @reg_num: GPI_IS register number
* @base: Starting pin of this group
* @size: Size of this group (maximum is 32).
* @padown_num: PAD_OWN register number (assigned by the core driver)
*
* If pad groups of a community are not the same size, use this structure
* to specify them.
*/
struct intel_padgroup {
unsigned reg_num;
unsigned base;
unsigned size;
unsigned padown_num;
};
/**
* struct intel_community - Intel pin community description
* @barno: MMIO BAR number where registers for this community reside
@ -56,13 +76,22 @@ struct intel_function {
* @ie_offset: Register offset of GPI_IE from @regs.
* @pin_base: Starting pin of pins in this community
* @gpp_size: Maximum number of pads in each group, such as PADCFGLOCK,
* HOSTSW_OWN, GPI_IS, GPI_IE, etc.
* HOSTSW_OWN, GPI_IS, GPI_IE, etc. Used when @gpps is %NULL.
* @gpp_num_padown_regs: Number of pad registers each pad group consumes at
* minimum. Use %0 if the number of registers can be
* determined by the size of the group.
* @npins: Number of pins in this community
* @features: Additional features supported by the hardware
* @gpps: Pad groups if the controller has variable size pad groups
* @ngpps: Number of pad groups in this community
* @regs: Community specific common registers (reserved for core driver)
* @pad_regs: Community specific pad registers (reserved for core driver)
* @ngpps: Number of groups (hw groups) in this community (reserved for
* core driver)
*
* Most Intel GPIO host controllers this driver supports each pad group is
* of equal size (except the last one). In that case the driver can just
* fill in @gpp_size field and let the core driver to handle the rest. If
* the controller has pad groups of variable size the client driver can
* pass custom @gpps and @ngpps instead.
*/
struct intel_community {
unsigned barno;
@ -72,23 +101,37 @@ struct intel_community {
unsigned ie_offset;
unsigned pin_base;
unsigned gpp_size;
unsigned gpp_num_padown_regs;
size_t npins;
unsigned features;
const struct intel_padgroup *gpps;
size_t ngpps;
/* Reserved for the core driver */
void __iomem *regs;
void __iomem *pad_regs;
size_t ngpps;
};
/* Additional features supported by the hardware */
#define PINCTRL_FEATURE_DEBOUNCE BIT(0)
#define PINCTRL_FEATURE_1K_PD BIT(1)
#define PIN_GROUP(n, p, m) \
{ \
.name = (n), \
.pins = (p), \
.npins = ARRAY_SIZE((p)), \
.mode = (m), \
/**
* PIN_GROUP - Declare a pin group
* @n: Name of the group
* @p: An array of pins this group consists
* @m: Mode which the pins are put when this group is active. Can be either
* a single integer or an array of integers in which case mode is per
* pin.
*/
#define PIN_GROUP(n, p, m) \
{ \
.name = (n), \
.pins = (p), \
.npins = ARRAY_SIZE((p)), \
.mode = __builtin_choose_expr( \
__builtin_constant_p((m)), (m), 0), \
.modes = __builtin_choose_expr( \
__builtin_constant_p((m)), NULL, (m)), \
}
#define FUNCTION(n, g) \

View File

@ -31,6 +31,7 @@
.hostown_offset = SPT_HOSTSW_OWN, \
.ie_offset = SPT_GPI_IE, \
.gpp_size = 24, \
.gpp_num_padown_regs = 4, \
.pin_base = (s), \
.npins = ((e) - (s) + 1), \
}

View File

@ -11,18 +11,11 @@ config PINCTRL_MTK
# For ARMv7 SoCs
config PINCTRL_MT2701
bool "Mediatek MT2701 pin control"
depends on MACH_MT2701 || COMPILE_TEST
depends on MACH_MT7623 || MACH_MT2701 || COMPILE_TEST
depends on OF
default MACH_MT2701
select PINCTRL_MTK
config PINCTRL_MT7623
bool "Mediatek MT7623 pin control"
depends on MACH_MT7623 || COMPILE_TEST
depends on OF
default MACH_MT7623
select PINCTRL_MTK_COMMON
config PINCTRL_MT8135
bool "Mediatek MT8135 pin control"
depends on MACH_MT8135 || COMPILE_TEST

View File

@ -3,7 +3,6 @@ obj-y += pinctrl-mtk-common.o
# SoC Drivers
obj-$(CONFIG_PINCTRL_MT2701) += pinctrl-mt2701.o
obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o
obj-$(CONFIG_PINCTRL_MT8135) += pinctrl-mt8135.o
obj-$(CONFIG_PINCTRL_MT8127) += pinctrl-mt8127.o
obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o

View File

@ -565,6 +565,7 @@ static int mt2701_pinctrl_probe(struct platform_device *pdev)
static const struct of_device_id mt2701_pctrl_match[] = {
{ .compatible = "mediatek,mt2701-pinctrl", },
{ .compatible = "mediatek,mt7623-pinctrl", },
{}
};
MODULE_DEVICE_TABLE(of, mt2701_pctrl_match);

View File

@ -1,379 +0,0 @@
/*
* Copyright (c) 2016 John Crispin <john@phrozen.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <dt-bindings/pinctrl/mt65xx.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/regmap.h>
#include "pinctrl-mtk-common.h"
#include "pinctrl-mtk-mt7623.h"
static const struct mtk_drv_group_desc mt7623_drv_grp[] = {
/* 0E4E8SR 4/8/12/16 */
MTK_DRV_GRP(4, 16, 1, 2, 4),
/* 0E2E4SR 2/4/6/8 */
MTK_DRV_GRP(2, 8, 1, 2, 2),
/* E8E4E2 2/4/6/8/10/12/14/16 */
MTK_DRV_GRP(2, 16, 0, 2, 2)
};
#define DRV_SEL0 0xf50
#define DRV_SEL1 0xf60
#define DRV_SEL2 0xf70
#define DRV_SEL3 0xf80
#define DRV_SEL4 0xf90
#define DRV_SEL5 0xfa0
#define DRV_SEL6 0xfb0
#define DRV_SEL7 0xfe0
#define DRV_SEL8 0xfd0
#define DRV_SEL9 0xff0
#define DRV_SEL10 0xf00
#define MSDC0_CTRL0 0xcc0
#define MSDC0_CTRL1 0xcd0
#define MSDC0_CTRL2 0xce0
#define MSDC0_CTRL3 0xcf0
#define MSDC0_CTRL4 0xd00
#define MSDC0_CTRL5 0xd10
#define MSDC0_CTRL6 0xd20
#define MSDC1_CTRL0 0xd30
#define MSDC1_CTRL1 0xd40
#define MSDC1_CTRL2 0xd50
#define MSDC1_CTRL3 0xd60
#define MSDC1_CTRL4 0xd70
#define MSDC1_CTRL5 0xd80
#define MSDC1_CTRL6 0xd90
#define IES_EN0 0xb20
#define IES_EN1 0xb30
#define IES_EN2 0xb40
#define SMT_EN0 0xb50
#define SMT_EN1 0xb60
#define SMT_EN2 0xb70
static const struct mtk_pin_drv_grp mt7623_pin_drv[] = {
MTK_PIN_DRV_GRP(0, DRV_SEL0, 0, 1),
MTK_PIN_DRV_GRP(1, DRV_SEL0, 0, 1),
MTK_PIN_DRV_GRP(2, DRV_SEL0, 0, 1),
MTK_PIN_DRV_GRP(3, DRV_SEL0, 0, 1),
MTK_PIN_DRV_GRP(4, DRV_SEL0, 0, 1),
MTK_PIN_DRV_GRP(5, DRV_SEL0, 0, 1),
MTK_PIN_DRV_GRP(6, DRV_SEL0, 0, 1),
MTK_PIN_DRV_GRP(7, DRV_SEL0, 4, 1),
MTK_PIN_DRV_GRP(8, DRV_SEL0, 4, 1),
MTK_PIN_DRV_GRP(9, DRV_SEL0, 4, 1),
MTK_PIN_DRV_GRP(10, DRV_SEL0, 8, 1),
MTK_PIN_DRV_GRP(11, DRV_SEL0, 8, 1),
MTK_PIN_DRV_GRP(12, DRV_SEL0, 8, 1),
MTK_PIN_DRV_GRP(13, DRV_SEL0, 8, 1),
MTK_PIN_DRV_GRP(14, DRV_SEL0, 12, 0),
MTK_PIN_DRV_GRP(15, DRV_SEL0, 12, 0),
MTK_PIN_DRV_GRP(18, DRV_SEL1, 4, 0),
MTK_PIN_DRV_GRP(19, DRV_SEL1, 4, 0),
MTK_PIN_DRV_GRP(20, DRV_SEL1, 4, 0),
MTK_PIN_DRV_GRP(21, DRV_SEL1, 4, 0),
MTK_PIN_DRV_GRP(22, DRV_SEL1, 8, 0),
MTK_PIN_DRV_GRP(23, DRV_SEL1, 8, 0),
MTK_PIN_DRV_GRP(24, DRV_SEL1, 8, 0),
MTK_PIN_DRV_GRP(25, DRV_SEL1, 8, 0),
MTK_PIN_DRV_GRP(26, DRV_SEL1, 8, 0),
MTK_PIN_DRV_GRP(27, DRV_SEL1, 12, 0),
MTK_PIN_DRV_GRP(28, DRV_SEL1, 12, 0),
MTK_PIN_DRV_GRP(29, DRV_SEL1, 12, 0),
MTK_PIN_DRV_GRP(33, DRV_SEL2, 0, 0),
MTK_PIN_DRV_GRP(34, DRV_SEL2, 0, 0),
MTK_PIN_DRV_GRP(35, DRV_SEL2, 0, 0),
MTK_PIN_DRV_GRP(36, DRV_SEL2, 0, 0),
MTK_PIN_DRV_GRP(37, DRV_SEL2, 0, 0),
MTK_PIN_DRV_GRP(39, DRV_SEL2, 8, 1),
MTK_PIN_DRV_GRP(40, DRV_SEL2, 8, 1),
MTK_PIN_DRV_GRP(41, DRV_SEL2, 8, 1),
MTK_PIN_DRV_GRP(42, DRV_SEL2, 8, 1),
MTK_PIN_DRV_GRP(43, DRV_SEL2, 12, 0),
MTK_PIN_DRV_GRP(44, DRV_SEL2, 12, 0),
MTK_PIN_DRV_GRP(45, DRV_SEL2, 12, 0),
MTK_PIN_DRV_GRP(47, DRV_SEL3, 0, 0),
MTK_PIN_DRV_GRP(48, DRV_SEL3, 0, 0),
MTK_PIN_DRV_GRP(49, DRV_SEL3, 4, 0),
MTK_PIN_DRV_GRP(53, DRV_SEL3, 12, 0),
MTK_PIN_DRV_GRP(54, DRV_SEL3, 12, 0),
MTK_PIN_DRV_GRP(55, DRV_SEL3, 12, 0),
MTK_PIN_DRV_GRP(56, DRV_SEL3, 12, 0),
MTK_PIN_DRV_GRP(60, DRV_SEL4, 8, 1),
MTK_PIN_DRV_GRP(61, DRV_SEL4, 8, 1),
MTK_PIN_DRV_GRP(62, DRV_SEL4, 8, 1),
MTK_PIN_DRV_GRP(63, DRV_SEL4, 12, 1),
MTK_PIN_DRV_GRP(64, DRV_SEL4, 12, 1),
MTK_PIN_DRV_GRP(65, DRV_SEL4, 12, 1),
MTK_PIN_DRV_GRP(66, DRV_SEL5, 0, 1),
MTK_PIN_DRV_GRP(67, DRV_SEL5, 0, 1),
MTK_PIN_DRV_GRP(68, DRV_SEL5, 0, 1),
MTK_PIN_DRV_GRP(69, DRV_SEL5, 0, 1),
MTK_PIN_DRV_GRP(70, DRV_SEL5, 0, 1),
MTK_PIN_DRV_GRP(71, DRV_SEL5, 0, 1),
MTK_PIN_DRV_GRP(72, DRV_SEL3, 4, 0),
MTK_PIN_DRV_GRP(73, DRV_SEL3, 4, 0),
MTK_PIN_DRV_GRP(74, DRV_SEL3, 4, 0),
MTK_PIN_DRV_GRP(83, DRV_SEL5, 0, 1),
MTK_PIN_DRV_GRP(84, DRV_SEL5, 0, 1),
MTK_PIN_DRV_GRP(105, MSDC1_CTRL1, 0, 1),
MTK_PIN_DRV_GRP(106, MSDC1_CTRL0, 0, 1),
MTK_PIN_DRV_GRP(107, MSDC1_CTRL2, 0, 1),
MTK_PIN_DRV_GRP(108, MSDC1_CTRL2, 0, 1),
MTK_PIN_DRV_GRP(109, MSDC1_CTRL2, 0, 1),
MTK_PIN_DRV_GRP(110, MSDC1_CTRL2, 0, 1),
MTK_PIN_DRV_GRP(111, MSDC0_CTRL2, 0, 1),
MTK_PIN_DRV_GRP(112, MSDC0_CTRL2, 0, 1),
MTK_PIN_DRV_GRP(113, MSDC0_CTRL2, 0, 1),
MTK_PIN_DRV_GRP(114, MSDC0_CTRL2, 0, 1),
MTK_PIN_DRV_GRP(115, MSDC0_CTRL2, 0, 1),
MTK_PIN_DRV_GRP(116, MSDC0_CTRL1, 0, 1),
MTK_PIN_DRV_GRP(117, MSDC0_CTRL0, 0, 1),
MTK_PIN_DRV_GRP(118, MSDC0_CTRL2, 0, 1),
MTK_PIN_DRV_GRP(119, MSDC0_CTRL2, 0, 1),
MTK_PIN_DRV_GRP(120, MSDC0_CTRL2, 0, 1),
MTK_PIN_DRV_GRP(121, MSDC0_CTRL2, 0, 1),
MTK_PIN_DRV_GRP(126, DRV_SEL3, 4, 0),
MTK_PIN_DRV_GRP(199, DRV_SEL0, 4, 1),
MTK_PIN_DRV_GRP(200, DRV_SEL8, 0, 0),
MTK_PIN_DRV_GRP(201, DRV_SEL8, 0, 0),
MTK_PIN_DRV_GRP(203, DRV_SEL8, 4, 0),
MTK_PIN_DRV_GRP(204, DRV_SEL8, 4, 0),
MTK_PIN_DRV_GRP(205, DRV_SEL8, 4, 0),
MTK_PIN_DRV_GRP(206, DRV_SEL8, 4, 0),
MTK_PIN_DRV_GRP(207, DRV_SEL8, 4, 0),
MTK_PIN_DRV_GRP(208, DRV_SEL8, 8, 0),
MTK_PIN_DRV_GRP(209, DRV_SEL8, 8, 0),
MTK_PIN_DRV_GRP(236, DRV_SEL9, 4, 0),
MTK_PIN_DRV_GRP(237, DRV_SEL9, 4, 0),
MTK_PIN_DRV_GRP(238, DRV_SEL9, 4, 0),
MTK_PIN_DRV_GRP(239, DRV_SEL9, 4, 0),
MTK_PIN_DRV_GRP(240, DRV_SEL9, 4, 0),
MTK_PIN_DRV_GRP(241, DRV_SEL9, 4, 0),
MTK_PIN_DRV_GRP(242, DRV_SEL9, 8, 0),
MTK_PIN_DRV_GRP(243, DRV_SEL9, 8, 0),
MTK_PIN_DRV_GRP(257, MSDC0_CTRL2, 0, 1),
MTK_PIN_DRV_GRP(261, MSDC1_CTRL2, 0, 1),
MTK_PIN_DRV_GRP(262, DRV_SEL10, 8, 0),
MTK_PIN_DRV_GRP(263, DRV_SEL10, 8, 0),
MTK_PIN_DRV_GRP(264, DRV_SEL10, 8, 0),
MTK_PIN_DRV_GRP(265, DRV_SEL10, 8, 0),
MTK_PIN_DRV_GRP(266, DRV_SEL10, 8, 0),
MTK_PIN_DRV_GRP(267, DRV_SEL10, 8, 0),
MTK_PIN_DRV_GRP(268, DRV_SEL10, 8, 0),
MTK_PIN_DRV_GRP(269, DRV_SEL10, 8, 0),
MTK_PIN_DRV_GRP(270, DRV_SEL10, 8, 0),
MTK_PIN_DRV_GRP(271, DRV_SEL10, 8, 0),
MTK_PIN_DRV_GRP(272, DRV_SEL10, 8, 0),
MTK_PIN_DRV_GRP(274, DRV_SEL10, 8, 0),
MTK_PIN_DRV_GRP(275, DRV_SEL10, 8, 0),
MTK_PIN_DRV_GRP(276, DRV_SEL10, 8, 0),
MTK_PIN_DRV_GRP(278, DRV_SEL2, 8, 1),
};
static const struct mtk_pin_spec_pupd_set_samereg mt7623_spec_pupd[] = {
MTK_PIN_PUPD_SPEC_SR(105, MSDC1_CTRL1, 8, 9, 10),
MTK_PIN_PUPD_SPEC_SR(106, MSDC1_CTRL0, 8, 9, 10),
MTK_PIN_PUPD_SPEC_SR(107, MSDC1_CTRL3, 0, 1, 2),
MTK_PIN_PUPD_SPEC_SR(108, MSDC1_CTRL3, 4, 5, 6),
MTK_PIN_PUPD_SPEC_SR(109, MSDC1_CTRL3, 8, 9, 10),
MTK_PIN_PUPD_SPEC_SR(110, MSDC1_CTRL3, 12, 13, 14),
MTK_PIN_PUPD_SPEC_SR(111, MSDC0_CTRL4, 12, 13, 14),
MTK_PIN_PUPD_SPEC_SR(112, MSDC0_CTRL4, 8, 9, 10),
MTK_PIN_PUPD_SPEC_SR(113, MSDC0_CTRL4, 4, 5, 6),
MTK_PIN_PUPD_SPEC_SR(114, MSDC0_CTRL4, 0, 1, 2),
MTK_PIN_PUPD_SPEC_SR(115, MSDC0_CTRL5, 0, 1, 2),
MTK_PIN_PUPD_SPEC_SR(116, MSDC0_CTRL1, 8, 9, 10),
MTK_PIN_PUPD_SPEC_SR(117, MSDC0_CTRL0, 8, 9, 10),
MTK_PIN_PUPD_SPEC_SR(118, MSDC0_CTRL3, 12, 13, 14),
MTK_PIN_PUPD_SPEC_SR(119, MSDC0_CTRL3, 8, 9, 10),
MTK_PIN_PUPD_SPEC_SR(120, MSDC0_CTRL3, 4, 5, 6),
MTK_PIN_PUPD_SPEC_SR(121, MSDC0_CTRL3, 0, 1, 2),
};
static int mt7623_spec_pull_set(struct regmap *regmap, unsigned int pin,
unsigned char align, bool isup, unsigned int r1r0)
{
return mtk_pctrl_spec_pull_set_samereg(regmap, mt7623_spec_pupd,
ARRAY_SIZE(mt7623_spec_pupd), pin, align, isup, r1r0);
}
static const struct mtk_pin_ies_smt_set mt7623_ies_set[] = {
MTK_PIN_IES_SMT_SPEC(0, 6, IES_EN0, 0),
MTK_PIN_IES_SMT_SPEC(7, 9, IES_EN0, 1),
MTK_PIN_IES_SMT_SPEC(10, 13, IES_EN0, 2),
MTK_PIN_IES_SMT_SPEC(14, 15, IES_EN0, 3),
MTK_PIN_IES_SMT_SPEC(18, 21, IES_EN0, 5),
MTK_PIN_IES_SMT_SPEC(22, 26, IES_EN0, 6),
MTK_PIN_IES_SMT_SPEC(27, 29, IES_EN0, 7),
MTK_PIN_IES_SMT_SPEC(33, 37, IES_EN0, 8),
MTK_PIN_IES_SMT_SPEC(39, 42, IES_EN0, 9),
MTK_PIN_IES_SMT_SPEC(43, 45, IES_EN0, 10),
MTK_PIN_IES_SMT_SPEC(47, 48, IES_EN0, 11),
MTK_PIN_IES_SMT_SPEC(49, 49, IES_EN0, 12),
MTK_PIN_IES_SMT_SPEC(53, 56, IES_EN0, 14),
MTK_PIN_IES_SMT_SPEC(60, 62, IES_EN1, 0),
MTK_PIN_IES_SMT_SPEC(63, 65, IES_EN1, 1),
MTK_PIN_IES_SMT_SPEC(66, 71, IES_EN1, 2),
MTK_PIN_IES_SMT_SPEC(72, 74, IES_EN0, 12),
MTK_PIN_IES_SMT_SPEC(75, 76, IES_EN1, 3),
MTK_PIN_IES_SMT_SPEC(83, 84, IES_EN1, 2),
MTK_PIN_IES_SMT_SPEC(105, 121, MSDC1_CTRL1, 4),
MTK_PIN_IES_SMT_SPEC(122, 125, IES_EN1, 7),
MTK_PIN_IES_SMT_SPEC(126, 126, IES_EN0, 12),
MTK_PIN_IES_SMT_SPEC(199, 201, IES_EN0, 1),
MTK_PIN_IES_SMT_SPEC(203, 207, IES_EN2, 2),
MTK_PIN_IES_SMT_SPEC(208, 209, IES_EN2, 3),
MTK_PIN_IES_SMT_SPEC(236, 241, IES_EN2, 6),
MTK_PIN_IES_SMT_SPEC(242, 243, IES_EN2, 7),
MTK_PIN_IES_SMT_SPEC(261, 261, MSDC1_CTRL2, 4),
MTK_PIN_IES_SMT_SPEC(262, 272, IES_EN2, 12),
MTK_PIN_IES_SMT_SPEC(274, 276, IES_EN2, 12),
MTK_PIN_IES_SMT_SPEC(278, 278, IES_EN2, 13),
};
static const struct mtk_pin_ies_smt_set mt7623_smt_set[] = {
MTK_PIN_IES_SMT_SPEC(0, 6, SMT_EN0, 0),
MTK_PIN_IES_SMT_SPEC(7, 9, SMT_EN0, 1),
MTK_PIN_IES_SMT_SPEC(10, 13, SMT_EN0, 2),
MTK_PIN_IES_SMT_SPEC(14, 15, SMT_EN0, 3),
MTK_PIN_IES_SMT_SPEC(18, 21, SMT_EN0, 5),
MTK_PIN_IES_SMT_SPEC(22, 26, SMT_EN0, 6),
MTK_PIN_IES_SMT_SPEC(27, 29, SMT_EN0, 7),
MTK_PIN_IES_SMT_SPEC(33, 37, SMT_EN0, 8),
MTK_PIN_IES_SMT_SPEC(39, 42, SMT_EN0, 9),
MTK_PIN_IES_SMT_SPEC(43, 45, SMT_EN0, 10),
MTK_PIN_IES_SMT_SPEC(47, 48, SMT_EN0, 11),
MTK_PIN_IES_SMT_SPEC(49, 49, SMT_EN0, 12),
MTK_PIN_IES_SMT_SPEC(53, 56, SMT_EN0, 14),
MTK_PIN_IES_SMT_SPEC(60, 62, SMT_EN1, 0),
MTK_PIN_IES_SMT_SPEC(63, 65, SMT_EN1, 1),
MTK_PIN_IES_SMT_SPEC(66, 71, SMT_EN1, 2),
MTK_PIN_IES_SMT_SPEC(72, 74, SMT_EN0, 12),
MTK_PIN_IES_SMT_SPEC(75, 76, SMT_EN1, 3),
MTK_PIN_IES_SMT_SPEC(83, 84, SMT_EN1, 2),
MTK_PIN_IES_SMT_SPEC(105, 106, MSDC1_CTRL1, 11),
MTK_PIN_IES_SMT_SPEC(107, 107, MSDC1_CTRL3, 3),
MTK_PIN_IES_SMT_SPEC(108, 108, MSDC1_CTRL3, 7),
MTK_PIN_IES_SMT_SPEC(109, 109, MSDC1_CTRL3, 11),
MTK_PIN_IES_SMT_SPEC(110, 111, MSDC1_CTRL3, 15),
MTK_PIN_IES_SMT_SPEC(112, 112, MSDC0_CTRL4, 11),
MTK_PIN_IES_SMT_SPEC(113, 113, MSDC0_CTRL4, 7),
MTK_PIN_IES_SMT_SPEC(114, 115, MSDC0_CTRL4, 3),
MTK_PIN_IES_SMT_SPEC(116, 117, MSDC0_CTRL1, 11),
MTK_PIN_IES_SMT_SPEC(118, 118, MSDC0_CTRL3, 15),
MTK_PIN_IES_SMT_SPEC(119, 119, MSDC0_CTRL3, 11),
MTK_PIN_IES_SMT_SPEC(120, 120, MSDC0_CTRL3, 7),
MTK_PIN_IES_SMT_SPEC(121, 121, MSDC0_CTRL3, 3),
MTK_PIN_IES_SMT_SPEC(122, 125, SMT_EN1, 7),
MTK_PIN_IES_SMT_SPEC(126, 126, SMT_EN0, 12),
MTK_PIN_IES_SMT_SPEC(199, 201, SMT_EN0, 1),
MTK_PIN_IES_SMT_SPEC(203, 207, SMT_EN2, 2),
MTK_PIN_IES_SMT_SPEC(208, 209, SMT_EN2, 3),
MTK_PIN_IES_SMT_SPEC(236, 241, SMT_EN2, 6),
MTK_PIN_IES_SMT_SPEC(242, 243, SMT_EN2, 7),
MTK_PIN_IES_SMT_SPEC(261, 261, MSDC1_CTRL6, 3),
MTK_PIN_IES_SMT_SPEC(262, 272, SMT_EN2, 12),
MTK_PIN_IES_SMT_SPEC(274, 276, SMT_EN2, 12),
MTK_PIN_IES_SMT_SPEC(278, 278, SMT_EN2, 13),
};
static int mt7623_ies_smt_set(struct regmap *regmap, unsigned int pin,
unsigned char align, int value, enum pin_config_param arg)
{
if (arg == PIN_CONFIG_INPUT_ENABLE)
return mtk_pconf_spec_set_ies_smt_range(regmap, mt7623_ies_set,
ARRAY_SIZE(mt7623_ies_set), pin, align, value);
else if (arg == PIN_CONFIG_INPUT_SCHMITT_ENABLE)
return mtk_pconf_spec_set_ies_smt_range(regmap, mt7623_smt_set,
ARRAY_SIZE(mt7623_smt_set), pin, align, value);
return -EINVAL;
}
static const struct mtk_pinctrl_devdata mt7623_pinctrl_data = {
.pins = mtk_pins_mt7623,
.npins = ARRAY_SIZE(mtk_pins_mt7623),
.grp_desc = mt7623_drv_grp,
.n_grp_cls = ARRAY_SIZE(mt7623_drv_grp),
.pin_drv_grp = mt7623_pin_drv,
.n_pin_drv_grps = ARRAY_SIZE(mt7623_pin_drv),
.spec_pull_set = mt7623_spec_pull_set,
.spec_ies_smt_set = mt7623_ies_smt_set,
.dir_offset = 0x0000,
.pullen_offset = 0x0150,
.pullsel_offset = 0x0280,
.dout_offset = 0x0500,
.din_offset = 0x0630,
.pinmux_offset = 0x0760,
.type1_start = 280,
.type1_end = 280,
.port_shf = 4,
.port_mask = 0x1f,
.port_align = 4,
.eint_offsets = {
.name = "mt7623_eint",
.stat = 0x000,
.ack = 0x040,
.mask = 0x080,
.mask_set = 0x0c0,
.mask_clr = 0x100,
.sens = 0x140,
.sens_set = 0x180,
.sens_clr = 0x1c0,
.soft = 0x200,
.soft_set = 0x240,
.soft_clr = 0x280,
.pol = 0x300,
.pol_set = 0x340,
.pol_clr = 0x380,
.dom_en = 0x400,
.dbnc_ctrl = 0x500,
.dbnc_set = 0x600,
.dbnc_clr = 0x700,
.port_mask = 6,
.ports = 6,
},
.ap_num = 169,
.db_cnt = 16,
};
static int mt7623_pinctrl_probe(struct platform_device *pdev)
{
return mtk_pctrl_init(pdev, &mt7623_pinctrl_data, NULL);
}
static const struct of_device_id mt7623_pctrl_match[] = {
{ .compatible = "mediatek,mt7623-pinctrl", },
{}
};
MODULE_DEVICE_TABLE(of, mt7623_pctrl_match);
static struct platform_driver mtk_pinctrl_driver = {
.probe = mt7623_pinctrl_probe,
.driver = {
.name = "mediatek-mt7623-pinctrl",
.of_match_table = mt7623_pctrl_match,
},
};
static int __init mtk_pinctrl_init(void)
{
return platform_driver_register(&mtk_pinctrl_driver);
}
arch_initcall(mtk_pinctrl_init);

File diff suppressed because it is too large Load Diff

View File

@ -85,6 +85,7 @@ static const struct pinctrl_pin_desc meson_gxbb_periphs_pins[] = {
MESON_PIN(GPIODV_15, EE_OFF),
MESON_PIN(GPIODV_16, EE_OFF),
MESON_PIN(GPIODV_17, EE_OFF),
MESON_PIN(GPIODV_18, EE_OFF),
MESON_PIN(GPIODV_19, EE_OFF),
MESON_PIN(GPIODV_20, EE_OFF),
MESON_PIN(GPIODV_21, EE_OFF),
@ -137,7 +138,6 @@ static const struct pinctrl_pin_desc meson_gxbb_periphs_pins[] = {
MESON_PIN(GPIOX_19, EE_OFF),
MESON_PIN(GPIOX_20, EE_OFF),
MESON_PIN(GPIOX_21, EE_OFF),
MESON_PIN(GPIOX_22, EE_OFF),
MESON_PIN(GPIOCLK_0, EE_OFF),
MESON_PIN(GPIOCLK_1, EE_OFF),
@ -161,6 +161,11 @@ static const unsigned int nor_q_pins[] = { PIN(BOOT_12, EE_OFF) };
static const unsigned int nor_c_pins[] = { PIN(BOOT_13, EE_OFF) };
static const unsigned int nor_cs_pins[] = { PIN(BOOT_15, EE_OFF) };
static const unsigned int spi_sclk_pins[] = { PIN(GPIOZ_6, EE_OFF) };
static const unsigned int spi_ss0_pins[] = { PIN(GPIOZ_7, EE_OFF) };
static const unsigned int spi_miso_pins[] = { PIN(GPIOZ_12, EE_OFF) };
static const unsigned int spi_mosi_pins[] = { PIN(GPIOZ_13, EE_OFF) };
static const unsigned int sdcard_d0_pins[] = { PIN(CARD_1, EE_OFF) };
static const unsigned int sdcard_d1_pins[] = { PIN(CARD_0, EE_OFF) };
static const unsigned int sdcard_d2_pins[] = { PIN(CARD_5, EE_OFF) };
@ -290,6 +295,9 @@ static const unsigned int i2s_out_ch45_ao_pins[] = { PIN(GPIOAO_13, 0) };
static const unsigned int spdif_out_ao_6_pins[] = { PIN(GPIOAO_6, 0) };
static const unsigned int spdif_out_ao_13_pins[] = { PIN(GPIOAO_13, 0) };
static const unsigned int ao_cec_pins[] = { PIN(GPIOAO_12, 0) };
static const unsigned int ee_cec_pins[] = { PIN(GPIOAO_12, 0) };
static struct meson_pmx_group meson_gxbb_periphs_groups[] = {
GPIO_GROUP(GPIOZ_0, EE_OFF),
GPIO_GROUP(GPIOZ_1, EE_OFF),
@ -462,6 +470,10 @@ static struct meson_pmx_group meson_gxbb_periphs_groups[] = {
GROUP(eth_txd1, 6, 4),
GROUP(eth_txd2, 6, 3),
GROUP(eth_txd3, 6, 2),
GROUP(spi_ss0, 5, 26),
GROUP(spi_sclk, 5, 27),
GROUP(spi_miso, 5, 28),
GROUP(spi_mosi, 5, 29),
/* Bank H */
GROUP(hdmi_hpd, 1, 26),
@ -551,6 +563,8 @@ static struct meson_pmx_group meson_gxbb_aobus_groups[] = {
GROUP(i2s_out_ch45_ao, 1, 1),
GROUP(spdif_out_ao_6, 0, 16),
GROUP(spdif_out_ao_13, 0, 4),
GROUP(ao_cec, 0, 15),
GROUP(ee_cec, 0, 14),
};
static const char * const gpio_periphs_groups[] = {
@ -598,6 +612,10 @@ static const char * const nor_groups[] = {
"nor_d", "nor_q", "nor_c", "nor_cs",
};
static const char * const spi_groups[] = {
"spi_mosi", "spi_miso", "spi_ss0", "spi_sclk",
};
static const char * const sdcard_groups[] = {
"sdcard_d0", "sdcard_d1", "sdcard_d2", "sdcard_d3",
"sdcard_cmd", "sdcard_clk",
@ -739,10 +757,15 @@ static const char * const spdif_out_ao_groups[] = {
"spdif_out_ao_6", "spdif_out_ao_13",
};
static const char * const cec_ao_groups[] = {
"ao_cec", "ee_cec",
};
static struct meson_pmx_func meson_gxbb_periphs_functions[] = {
FUNCTION(gpio_periphs),
FUNCTION(emmc),
FUNCTION(nor),
FUNCTION(spi),
FUNCTION(sdcard),
FUNCTION(sdio),
FUNCTION(nand),
@ -779,23 +802,24 @@ static struct meson_pmx_func meson_gxbb_aobus_functions[] = {
FUNCTION(pwm_ao_b),
FUNCTION(i2s_out_ao),
FUNCTION(spdif_out_ao),
FUNCTION(cec_ao),
};
static struct meson_bank meson_gxbb_periphs_banks[] = {
/* name first last pullen pull dir out in */
BANK("X", PIN(GPIOX_0, EE_OFF), PIN(GPIOX_22, EE_OFF), 4, 0, 4, 0, 12, 0, 13, 0, 14, 0),
BANK("Y", PIN(GPIOY_0, EE_OFF), PIN(GPIOY_16, EE_OFF), 1, 0, 1, 0, 3, 0, 4, 0, 5, 0),
BANK("DV", PIN(GPIODV_0, EE_OFF), PIN(GPIODV_29, EE_OFF), 0, 0, 0, 0, 0, 0, 1, 0, 2, 0),
BANK("H", PIN(GPIOH_0, EE_OFF), PIN(GPIOH_3, EE_OFF), 1, 20, 1, 20, 3, 20, 4, 20, 5, 20),
BANK("Z", PIN(GPIOZ_0, EE_OFF), PIN(GPIOZ_15, EE_OFF), 3, 0, 3, 0, 9, 0, 10, 0, 11, 0),
BANK("CARD", PIN(CARD_0, EE_OFF), PIN(CARD_6, EE_OFF), 2, 20, 2, 20, 6, 20, 7, 20, 8, 20),
BANK("BOOT", PIN(BOOT_0, EE_OFF), PIN(BOOT_17, EE_OFF), 2, 0, 2, 0, 6, 0, 7, 0, 8, 0),
BANK("CLK", PIN(GPIOCLK_0, EE_OFF), PIN(GPIOCLK_3, EE_OFF), 3, 28, 3, 28, 9, 28, 10, 28, 11, 28),
/* name first last irq pullen pull dir out in */
BANK("X", PIN(GPIOX_0, EE_OFF), PIN(GPIOX_22, EE_OFF), 106, 128, 4, 0, 4, 0, 12, 0, 13, 0, 14, 0),
BANK("Y", PIN(GPIOY_0, EE_OFF), PIN(GPIOY_16, EE_OFF), 89, 105, 1, 0, 1, 0, 3, 0, 4, 0, 5, 0),
BANK("DV", PIN(GPIODV_0, EE_OFF), PIN(GPIODV_29, EE_OFF), 59, 88, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0),
BANK("H", PIN(GPIOH_0, EE_OFF), PIN(GPIOH_3, EE_OFF), 30, 33, 1, 20, 1, 20, 3, 20, 4, 20, 5, 20),
BANK("Z", PIN(GPIOZ_0, EE_OFF), PIN(GPIOZ_15, EE_OFF), 14, 29, 3, 0, 3, 0, 9, 0, 10, 0, 11, 0),
BANK("CARD", PIN(CARD_0, EE_OFF), PIN(CARD_6, EE_OFF), 52, 58, 2, 20, 2, 20, 6, 20, 7, 20, 8, 20),
BANK("BOOT", PIN(BOOT_0, EE_OFF), PIN(BOOT_17, EE_OFF), 34, 51, 2, 0, 2, 0, 6, 0, 7, 0, 8, 0),
BANK("CLK", PIN(GPIOCLK_0, EE_OFF), PIN(GPIOCLK_3, EE_OFF), 129, 132, 3, 28, 3, 28, 9, 28, 10, 28, 11, 28),
};
static struct meson_bank meson_gxbb_aobus_banks[] = {
/* name first last pullen pull dir out in */
BANK("AO", PIN(GPIOAO_0, 0), PIN(GPIOAO_13, 0), 0, 0, 0, 16, 0, 0, 0, 16, 1, 0),
/* name first last irq pullen pull dir out in */
BANK("AO", PIN(GPIOAO_0, 0), PIN(GPIOAO_13, 0), 0, 13, 0, 0, 0, 16, 0, 0, 0, 16, 1, 0),
};
struct meson_pinctrl_data meson_gxbb_periphs_pinctrl_data = {

View File

@ -89,6 +89,7 @@ static const struct pinctrl_pin_desc meson_gxl_periphs_pins[] = {
MESON_PIN(GPIODV_15, EE_OFF),
MESON_PIN(GPIODV_16, EE_OFF),
MESON_PIN(GPIODV_17, EE_OFF),
MESON_PIN(GPIODV_18, EE_OFF),
MESON_PIN(GPIODV_19, EE_OFF),
MESON_PIN(GPIODV_20, EE_OFF),
MESON_PIN(GPIODV_21, EE_OFF),
@ -141,6 +142,11 @@ static const unsigned int nor_q_pins[] = { PIN(BOOT_12, EE_OFF) };
static const unsigned int nor_c_pins[] = { PIN(BOOT_13, EE_OFF) };
static const unsigned int nor_cs_pins[] = { PIN(BOOT_15, EE_OFF) };
static const unsigned int spi_mosi_pins[] = { PIN(GPIOX_8, EE_OFF) };
static const unsigned int spi_miso_pins[] = { PIN(GPIOX_9, EE_OFF) };
static const unsigned int spi_ss0_pins[] = { PIN(GPIOX_10, EE_OFF) };
static const unsigned int spi_sclk_pins[] = { PIN(GPIOX_11, EE_OFF) };
static const unsigned int sdcard_d0_pins[] = { PIN(CARD_1, EE_OFF) };
static const unsigned int sdcard_d1_pins[] = { PIN(CARD_0, EE_OFF) };
static const unsigned int sdcard_d2_pins[] = { PIN(CARD_5, EE_OFF) };
@ -234,6 +240,28 @@ static const unsigned int i2s_out_ch67_z_pins[] = { PIN(GPIOZ_7, EE_OFF) };
static const unsigned int spdif_out_h_pins[] = { PIN(GPIOH_4, EE_OFF) };
static const unsigned int eth_link_led_pins[] = { PIN(GPIOZ_14, EE_OFF) };
static const unsigned int eth_act_led_pins[] = { PIN(GPIOZ_15, EE_OFF) };
static const unsigned int tsin_a_d0_pins[] = { PIN(GPIODV_0, EE_OFF) };
static const unsigned int tsin_a_d0_x_pins[] = { PIN(GPIOX_10, EE_OFF) };
static const unsigned int tsin_a_clk_pins[] = { PIN(GPIODV_8, EE_OFF) };
static const unsigned int tsin_a_clk_x_pins[] = { PIN(GPIOX_11, EE_OFF) };
static const unsigned int tsin_a_sop_pins[] = { PIN(GPIODV_9, EE_OFF) };
static const unsigned int tsin_a_sop_x_pins[] = { PIN(GPIOX_8, EE_OFF) };
static const unsigned int tsin_a_d_valid_pins[] = { PIN(GPIODV_10, EE_OFF) };
static const unsigned int tsin_a_d_valid_x_pins[] = { PIN(GPIOX_9, EE_OFF) };
static const unsigned int tsin_a_fail_pins[] = { PIN(GPIODV_11, EE_OFF) };
static const unsigned int tsin_a_dp_pins[] = {
PIN(GPIODV_1, EE_OFF),
PIN(GPIODV_2, EE_OFF),
PIN(GPIODV_3, EE_OFF),
PIN(GPIODV_4, EE_OFF),
PIN(GPIODV_5, EE_OFF),
PIN(GPIODV_6, EE_OFF),
PIN(GPIODV_7, EE_OFF),
};
static const struct pinctrl_pin_desc meson_gxl_aobus_pins[] = {
MESON_PIN(GPIOAO_0, 0),
MESON_PIN(GPIOAO_1, 0),
@ -271,11 +299,14 @@ static const unsigned int pwm_ao_a_8_pins[] = { PIN(GPIOAO_8, 0) };
static const unsigned int pwm_ao_b_pins[] = { PIN(GPIOAO_9, 0) };
static const unsigned int pwm_ao_b_6_pins[] = { PIN(GPIOAO_6, 0) };
static const unsigned int i2s_out_ch23_ao_pins[] = { PIN(GPIOAO_8, EE_OFF) };
static const unsigned int i2s_out_ch45_ao_pins[] = { PIN(GPIOAO_9, EE_OFF) };
static const unsigned int i2s_out_ch23_ao_pins[] = { PIN(GPIOAO_8, 0) };
static const unsigned int i2s_out_ch45_ao_pins[] = { PIN(GPIOAO_9, 0) };
static const unsigned int spdif_out_ao_6_pins[] = { PIN(GPIOAO_6, EE_OFF) };
static const unsigned int spdif_out_ao_9_pins[] = { PIN(GPIOAO_9, EE_OFF) };
static const unsigned int spdif_out_ao_6_pins[] = { PIN(GPIOAO_6, 0) };
static const unsigned int spdif_out_ao_9_pins[] = { PIN(GPIOAO_9, 0) };
static const unsigned int ao_cec_pins[] = { PIN(GPIOAO_8, 0) };
static const unsigned int ee_cec_pins[] = { PIN(GPIOAO_8, 0) };
static struct meson_pmx_group meson_gxl_periphs_groups[] = {
GPIO_GROUP(GPIOZ_0, EE_OFF),
@ -405,6 +436,14 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = {
GROUP(pwm_a, 5, 25),
GROUP(pwm_e, 5, 15),
GROUP(pwm_f_x, 5, 14),
GROUP(spi_mosi, 5, 3),
GROUP(spi_miso, 5, 2),
GROUP(spi_ss0, 5, 1),
GROUP(spi_sclk, 5, 0),
GROUP(tsin_a_sop_x, 6, 3),
GROUP(tsin_a_d_valid_x, 6, 2),
GROUP(tsin_a_d0_x, 6, 1),
GROUP(tsin_a_clk_x, 6, 0),
/* Bank Z */
GROUP(eth_mdio, 4, 23),
@ -425,6 +464,8 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = {
GROUP(i2s_out_ch23_z, 3, 26),
GROUP(i2s_out_ch45_z, 3, 25),
GROUP(i2s_out_ch67_z, 3, 24),
GROUP(eth_link_led, 4, 25),
GROUP(eth_act_led, 4, 24),
/* Bank H */
GROUP(hdmi_hpd, 6, 31),
@ -451,6 +492,12 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = {
GROUP(i2c_sck_c, 1, 10),
GROUP(pwm_b, 2, 11),
GROUP(pwm_d, 2, 12),
GROUP(tsin_a_d0, 2, 4),
GROUP(tsin_a_dp, 2, 3),
GROUP(tsin_a_clk, 2, 2),
GROUP(tsin_a_sop, 2, 1),
GROUP(tsin_a_d_valid, 2, 0),
GROUP(tsin_a_fail, 1, 31),
/* Bank BOOT */
GROUP(emmc_nand_d07, 7, 31),
@ -518,6 +565,8 @@ static struct meson_pmx_group meson_gxl_aobus_groups[] = {
GROUP(i2s_out_ch45_ao, 1, 1),
GROUP(spdif_out_ao_6, 0, 16),
GROUP(spdif_out_ao_9, 0, 4),
GROUP(ao_cec, 0, 15),
GROUP(ee_cec, 0, 14),
};
static const char * const gpio_periphs_groups[] = {
@ -560,6 +609,10 @@ static const char * const nor_groups[] = {
"nor_d", "nor_q", "nor_c", "nor_cs",
};
static const char * const spi_groups[] = {
"spi_mosi", "spi_miso", "spi_ss0", "spi_sclk",
};
static const char * const sdcard_groups[] = {
"sdcard_d0", "sdcard_d1", "sdcard_d2", "sdcard_d3",
"sdcard_cmd", "sdcard_clk",
@ -647,6 +700,16 @@ static const char * const spdif_out_groups[] = {
"spdif_out_h",
};
static const char * const eth_led_groups[] = {
"eth_link_led", "eth_act_led",
};
static const char * const tsin_a_groups[] = {
"tsin_a_clk", "tsin_a_clk_x", "tsin_a_sop", "tsin_a_sop_x",
"tsin_a_d_valid", "tsin_a_d_valid_x", "tsin_a_d0", "tsin_a_d0_x",
"tsin_a_dp", "tsin_a_fail",
};
static const char * const gpio_aobus_groups[] = {
"GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4",
"GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9",
@ -689,10 +752,15 @@ static const char * const spdif_out_ao_groups[] = {
"spdif_out_ao_6", "spdif_out_ao_9",
};
static const char * const cec_ao_groups[] = {
"ao_cec", "ee_cec",
};
static struct meson_pmx_func meson_gxl_periphs_functions[] = {
FUNCTION(gpio_periphs),
FUNCTION(emmc),
FUNCTION(nor),
FUNCTION(spi),
FUNCTION(sdcard),
FUNCTION(sdio),
FUNCTION(nand),
@ -713,6 +781,8 @@ static struct meson_pmx_func meson_gxl_periphs_functions[] = {
FUNCTION(hdmi_i2c),
FUNCTION(i2s_out),
FUNCTION(spdif_out),
FUNCTION(eth_led),
FUNCTION(tsin_a),
};
static struct meson_pmx_func meson_gxl_aobus_functions[] = {
@ -726,22 +796,23 @@ static struct meson_pmx_func meson_gxl_aobus_functions[] = {
FUNCTION(pwm_ao_b),
FUNCTION(i2s_out_ao),
FUNCTION(spdif_out_ao),
FUNCTION(cec_ao),
};
static struct meson_bank meson_gxl_periphs_banks[] = {
/* name first last pullen pull dir out in */
BANK("X", PIN(GPIOX_0, EE_OFF), PIN(GPIOX_18, EE_OFF), 4, 0, 4, 0, 12, 0, 13, 0, 14, 0),
BANK("DV", PIN(GPIODV_0, EE_OFF), PIN(GPIODV_29, EE_OFF), 0, 0, 0, 0, 0, 0, 1, 0, 2, 0),
BANK("H", PIN(GPIOH_0, EE_OFF), PIN(GPIOH_9, EE_OFF), 1, 20, 1, 20, 3, 20, 4, 20, 5, 20),
BANK("Z", PIN(GPIOZ_0, EE_OFF), PIN(GPIOZ_15, EE_OFF), 3, 0, 3, 0, 9, 0, 10, 0, 11, 0),
BANK("CARD", PIN(CARD_0, EE_OFF), PIN(CARD_6, EE_OFF), 2, 20, 2, 20, 6, 20, 7, 20, 8, 20),
BANK("BOOT", PIN(BOOT_0, EE_OFF), PIN(BOOT_15, EE_OFF), 2, 0, 2, 0, 6, 0, 7, 0, 8, 0),
BANK("CLK", PIN(GPIOCLK_0, EE_OFF), PIN(GPIOCLK_1, EE_OFF), 3, 28, 3, 28, 9, 28, 10, 28, 11, 28),
/* name first last irq pullen pull dir out in */
BANK("X", PIN(GPIOX_0, EE_OFF), PIN(GPIOX_18, EE_OFF), 89, 107, 4, 0, 4, 0, 12, 0, 13, 0, 14, 0),
BANK("DV", PIN(GPIODV_0, EE_OFF), PIN(GPIODV_29, EE_OFF), 83, 88, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0),
BANK("H", PIN(GPIOH_0, EE_OFF), PIN(GPIOH_9, EE_OFF), 26, 35, 1, 20, 1, 20, 3, 20, 4, 20, 5, 20),
BANK("Z", PIN(GPIOZ_0, EE_OFF), PIN(GPIOZ_15, EE_OFF), 10, 25, 3, 0, 3, 0, 9, 0, 10, 0, 11, 0),
BANK("CARD", PIN(CARD_0, EE_OFF), PIN(CARD_6, EE_OFF), 52, 58, 2, 20, 2, 20, 6, 20, 7, 20, 8, 20),
BANK("BOOT", PIN(BOOT_0, EE_OFF), PIN(BOOT_15, EE_OFF), 36, 51, 2, 0, 2, 0, 6, 0, 7, 0, 8, 0),
BANK("CLK", PIN(GPIOCLK_0, EE_OFF), PIN(GPIOCLK_1, EE_OFF), 108, 109, 3, 28, 3, 28, 9, 28, 10, 28, 11, 28),
};
static struct meson_bank meson_gxl_aobus_banks[] = {
/* name first last pullen pull dir out in */
BANK("AO", PIN(GPIOAO_0, 0), PIN(GPIOAO_9, 0), 0, 0, 0, 16, 0, 0, 0, 16, 1, 0),
/* name first last irq pullen pull dir out in */
BANK("AO", PIN(GPIOAO_0, 0), PIN(GPIOAO_9, 0), 0, 9, 0, 0, 0, 16, 0, 0, 0, 16, 1, 0),
};
struct meson_pinctrl_data meson_gxl_periphs_pinctrl_data = {

View File

@ -81,6 +81,7 @@ enum meson_reg_type {
* @name: bank name
* @first: first pin of the bank
* @last: last pin of the bank
* @irq: hwirq base number of the bank
* @regs: array of register descriptors
*
* A bank represents a set of pins controlled by a contiguous set of
@ -92,6 +93,8 @@ struct meson_bank {
const char *name;
unsigned int first;
unsigned int last;
int irq_first;
int irq_last;
struct meson_reg_desc regs[NUM_REG];
};
@ -147,12 +150,14 @@ struct meson_pinctrl {
.num_groups = ARRAY_SIZE(fn ## _groups), \
}
#define BANK(n, f, l, per, peb, pr, pb, dr, db, or, ob, ir, ib) \
#define BANK(n, f, l, fi, li, per, peb, pr, pb, dr, db, or, ob, ir, ib) \
{ \
.name = n, \
.first = f, \
.last = l, \
.regs = { \
.name = n, \
.first = f, \
.last = l, \
.irq_first = fi, \
.irq_last = li, \
.regs = { \
[REG_PULLEN] = { per, peb }, \
[REG_PULL] = { pr, pb }, \
[REG_DIR] = { dr, db }, \

View File

@ -205,6 +205,9 @@ static const unsigned int i2c_sck_d0_pins[] = { PIN(GPIOX_17, 0) };
static const unsigned int xtal_32k_out_pins[] = { PIN(GPIOX_10, 0) };
static const unsigned int xtal_24m_out_pins[] = { PIN(GPIOX_11, 0) };
static const unsigned int pwm_e_pins[] = { PIN(GPIOX_10, 0) };
static const unsigned int pwm_b_x_pins[] = { PIN(GPIOX_11, 0) };
/* bank Y */
static const unsigned int uart_tx_c_pins[] = { PIN(GPIOY_0, 0) };
static const unsigned int uart_rx_c_pins[] = { PIN(GPIOY_1, 0) };
@ -219,6 +222,20 @@ static const unsigned int pcm_clk_b_pins[] = { PIN(GPIOY_7, 0) };
static const unsigned int i2c_sda_c0_pins[] = { PIN(GPIOY_0, 0) };
static const unsigned int i2c_sck_c0_pins[] = { PIN(GPIOY_1, 0) };
static const unsigned int pwm_a_y_pins[] = { PIN(GPIOY_16, 0) };
static const unsigned int i2s_out_ch45_pins[] = { PIN(GPIOY_0, 0) };
static const unsigned int i2s_out_ch23_pins[] = { PIN(GPIOY_1, 0) };
static const unsigned int i2s_out_ch01_pins[] = { PIN(GPIOY_4, 0) };
static const unsigned int i2s_in_ch01_pins[] = { PIN(GPIOY_5, 0) };
static const unsigned int i2s_lr_clk_in_pins[] = { PIN(GPIOY_6, 0) };
static const unsigned int i2s_ao_clk_in_pins[] = { PIN(GPIOY_7, 0) };
static const unsigned int i2s_am_clk_pins[] = { PIN(GPIOY_8, 0) };
static const unsigned int i2s_out_ch78_pins[] = { PIN(GPIOY_9, 0) };
static const unsigned int spdif_in_pins[] = { PIN(GPIOY_2, 0) };
static const unsigned int spdif_out_pins[] = { PIN(GPIOY_3, 0) };
/* bank DV */
static const unsigned int dvin_rgb_pins[] = { PIN(GPIODV_0, 0), PIN(GPIODV_1, 0),
PIN(GPIODV_2, 0), PIN(GPIODV_3, 0),
@ -264,6 +281,10 @@ static const unsigned int uart_rts_b1_pins[] = { PIN(GPIODV_27, 0) };
static const unsigned int vga_vs_pins[] = { PIN(GPIODV_24, 0) };
static const unsigned int vga_hs_pins[] = { PIN(GPIODV_25, 0) };
static const unsigned int pwm_c_dv9_pins[] = { PIN(GPIODV_9, 0) };
static const unsigned int pwm_c_dv29_pins[] = { PIN(GPIODV_29, 0) };
static const unsigned int pwm_d_pins[] = { PIN(GPIODV_28, 0) };
/* bank H */
static const unsigned int hdmi_hpd_pins[] = { PIN(GPIOH_0, 0) };
static const unsigned int hdmi_sda_pins[] = { PIN(GPIOH_1, 0) };
@ -312,6 +333,11 @@ static const unsigned int i2c_sck_a1_pins[] = { PIN(GPIOZ_1, 0) };
static const unsigned int i2c_sda_a2_pins[] = { PIN(GPIOZ_0, 0) };
static const unsigned int i2c_sck_a2_pins[] = { PIN(GPIOZ_1, 0) };
static const unsigned int pwm_a_z0_pins[] = { PIN(GPIOZ_0, 0) };
static const unsigned int pwm_a_z7_pins[] = { PIN(GPIOZ_7, 0) };
static const unsigned int pwm_b_z_pins[] = { PIN(GPIOZ_1, 0) };
static const unsigned int pwm_c_z_pins[] = { PIN(GPIOZ_8, 0) };
/* bank BOOT */
static const unsigned int sd_d0_c_pins[] = { PIN(BOOT_0, 0) };
static const unsigned int sd_d1_c_pins[] = { PIN(BOOT_1, 0) };
@ -369,6 +395,7 @@ static const unsigned int uart_cts_ao_a_pins[] = { PIN(GPIOAO_2, AO_OFF) };
static const unsigned int uart_rts_ao_a_pins[] = { PIN(GPIOAO_3, AO_OFF) };
static const unsigned int remote_input_pins[] = { PIN(GPIOAO_7, AO_OFF) };
static const unsigned int remote_output_ao_pins[] = { PIN(GPIOAO_13, AO_OFF) };
static const unsigned int i2c_slave_sck_ao_pins[] = { PIN(GPIOAO_4, AO_OFF) };
static const unsigned int i2c_slave_sda_ao_pins[] = { PIN(GPIOAO_5, AO_OFF) };
@ -382,6 +409,15 @@ static const unsigned int uart_rx_ao_b1_pins[] = { PIN(GPIOAO_5, AO_OFF) };
static const unsigned int i2c_mst_sck_ao_pins[] = { PIN(GPIOAO_4, AO_OFF) };
static const unsigned int i2c_mst_sda_ao_pins[] = { PIN(GPIOAO_5, AO_OFF) };
static const unsigned int pwm_f_ao_pins[] = { PIN(GPIO_TEST_N, AO_OFF) };
static const unsigned int i2s_am_clk_out_ao_pins[] = { PIN(GPIOAO_8, AO_OFF) };
static const unsigned int i2s_ao_clk_out_ao_pins[] = { PIN(GPIOAO_9, AO_OFF) };
static const unsigned int i2s_lr_clk_out_ao_pins[] = { PIN(GPIOAO_10, AO_OFF) };
static const unsigned int i2s_out_ch01_ao_pins[] = { PIN(GPIOAO_11, AO_OFF) };
static const unsigned int hdmi_cec_ao_pins[] = { PIN(GPIOAO_12, AO_OFF) };
static struct meson_pmx_group meson8_cbus_groups[] = {
GPIO_GROUP(GPIOX_0, 0),
GPIO_GROUP(GPIOX_1, 0),
@ -523,6 +559,9 @@ static struct meson_pmx_group meson8_cbus_groups[] = {
GROUP(xtal_32k_out, 3, 22),
GROUP(xtal_24m_out, 3, 23),
GROUP(pwm_e, 9, 19),
GROUP(pwm_b_x, 2, 3),
/* bank Y */
GROUP(uart_tx_c, 1, 19),
GROUP(uart_rx_c, 1, 18),
@ -537,6 +576,20 @@ static struct meson_pmx_group meson8_cbus_groups[] = {
GROUP(i2c_sda_c0, 1, 15),
GROUP(i2c_sck_c0, 1, 14),
GROUP(pwm_a_y, 9, 14),
GROUP(i2s_out_ch45, 1, 10),
GROUP(i2s_out_ch23, 1, 19),
GROUP(i2s_out_ch01, 1, 6),
GROUP(i2s_in_ch01, 1, 5),
GROUP(i2s_lr_clk_in, 1, 4),
GROUP(i2s_ao_clk_in, 1, 2),
GROUP(i2s_am_clk, 1, 0),
GROUP(i2s_out_ch78, 1, 11),
GROUP(spdif_in, 1, 8),
GROUP(spdif_out, 1, 7),
/* bank DV */
GROUP(dvin_rgb, 0, 6),
GROUP(dvin_vs, 0, 9),
@ -571,6 +624,10 @@ static struct meson_pmx_group meson8_cbus_groups[] = {
GROUP(vga_vs, 0, 21),
GROUP(vga_hs, 0, 20),
GROUP(pwm_c_dv9, 3, 24),
GROUP(pwm_c_dv29, 3, 25),
GROUP(pwm_d, 3, 26),
/* bank H */
GROUP(hdmi_hpd, 1, 26),
GROUP(hdmi_sda, 1, 25),
@ -619,6 +676,11 @@ static struct meson_pmx_group meson8_cbus_groups[] = {
GROUP(i2c_sda_a2, 5, 7),
GROUP(i2c_sck_a2, 5, 6),
GROUP(pwm_a_z0, 9, 16),
GROUP(pwm_a_z7, 2, 0),
GROUP(pwm_b_z, 9, 15),
GROUP(pwm_c_z, 2, 1),
/* bank BOOT */
GROUP(sd_d0_c, 6, 29),
GROUP(sd_d1_c, 6, 28),
@ -689,6 +751,7 @@ static struct meson_pmx_group meson8_aobus_groups[] = {
GROUP(uart_rts_ao_a, 0, 9),
GROUP(remote_input, 0, 0),
GROUP(remote_output_ao, 0, 31),
GROUP(i2c_slave_sck_ao, 0, 2),
GROUP(i2c_slave_sda_ao, 0, 1),
@ -701,6 +764,15 @@ static struct meson_pmx_group meson8_aobus_groups[] = {
GROUP(i2c_mst_sck_ao, 0, 6),
GROUP(i2c_mst_sda_ao, 0, 5),
GROUP(pwm_f_ao, 0, 19),
GROUP(i2s_am_clk_out_ao, 0, 30),
GROUP(i2s_ao_clk_out_ao, 0, 29),
GROUP(i2s_lr_clk_out_ao, 0, 28),
GROUP(i2s_out_ch01_ao, 0, 27),
GROUP(hdmi_cec_ao, 0, 17),
};
static const char * const gpio_groups[] = {
@ -828,6 +900,12 @@ static const char * const i2c_b_groups[] = {
"i2c_sda_b", "i2c_sck_b"
};
static const char * const i2s_groups[] = {
"i2s_out_ch45", "i2s_out_ch23_pins", "i2s_out_ch01_pins",
"i2s_in_ch01_pins", "i2s_lr_clk_in_pins", "i2s_ao_clk_in_pins",
"i2s_am_clk_pins", "i2s_out_ch78_pins"
};
static const char * const sd_c_groups[] = {
"sd_d0_c", "sd_d1_c", "sd_d2_c", "sd_d3_c",
"sd_cmd_c", "sd_clk_c"
@ -849,6 +927,26 @@ static const char * const nor_groups[] = {
"nor_d", "nor_q", "nor_c", "nor_cs"
};
static const char * const pwm_a_groups[] = {
"pwm_a_y", "pwm_a_z0", "pwm_a_z7"
};
static const char * const pwm_b_groups[] = {
"pwm_b_x", "pwm_b_z"
};
static const char * const pwm_c_groups[] = {
"pwm_c_dv9", "pwm_c_dv29", "pwm_c_z"
};
static const char * const pwm_d_groups[] = {
"pwm_d"
};
static const char * const pwm_e_groups[] = {
"pwm_e"
};
static const char * const sd_b_groups[] = {
"sd_d1_b", "sd_d0_b", "sd_clk_b", "sd_cmd_b",
"sd_d3_b", "sd_d2_b"
@ -858,12 +956,16 @@ static const char * const sdxc_b_groups[] = {
"sdxc_d13_b", "sdxc_d0_b", "sdxc_clk_b", "sdxc_cmd_b"
};
static const char * const spdif_groups[] = {
"spdif_in", "spdif_out"
};
static const char * const uart_ao_groups[] = {
"uart_tx_ao_a", "uart_rx_ao_a", "uart_cts_ao_a", "uart_rts_ao_a"
};
static const char * const remote_groups[] = {
"remote_input"
"remote_input", "remote_output_ao"
};
static const char * const i2c_slave_ao_groups[] = {
@ -878,6 +980,19 @@ static const char * const i2c_mst_ao_groups[] = {
"i2c_mst_sck_ao", "i2c_mst_sda_ao"
};
static const char * const pwm_f_ao_groups[] = {
"pwm_f_ao"
};
static const char * const i2s_ao_groups[] = {
"i2s_am_clk_out_ao", "i2s_ao_clk_out_ao", "i2s_lr_clk_out_ao",
"i2s_out_ch01_ao"
};
static const char * const hdmi_cec_ao_groups[] = {
"hdmi_cec_ao"
};
static struct meson_pmx_func meson8_cbus_functions[] = {
FUNCTION(gpio),
FUNCTION(sd_a),
@ -905,6 +1020,13 @@ static struct meson_pmx_func meson8_cbus_functions[] = {
FUNCTION(nor),
FUNCTION(sd_b),
FUNCTION(sdxc_b),
FUNCTION(pwm_a),
FUNCTION(pwm_b),
FUNCTION(pwm_c),
FUNCTION(pwm_d),
FUNCTION(pwm_e),
FUNCTION(i2s),
FUNCTION(spdif),
};
static struct meson_pmx_func meson8_aobus_functions[] = {
@ -913,22 +1035,25 @@ static struct meson_pmx_func meson8_aobus_functions[] = {
FUNCTION(i2c_slave_ao),
FUNCTION(uart_ao_b),
FUNCTION(i2c_mst_ao),
FUNCTION(pwm_f_ao),
FUNCTION(i2s_ao),
FUNCTION(hdmi_cec_ao),
};
static struct meson_bank meson8_cbus_banks[] = {
/* name first last pullen pull dir out in */
BANK("X", PIN(GPIOX_0, 0), PIN(GPIOX_21, 0), 4, 0, 4, 0, 0, 0, 1, 0, 2, 0),
BANK("Y", PIN(GPIOY_0, 0), PIN(GPIOY_16, 0), 3, 0, 3, 0, 3, 0, 4, 0, 5, 0),
BANK("DV", PIN(GPIODV_0, 0), PIN(GPIODV_29, 0), 0, 0, 0, 0, 7, 0, 8, 0, 9, 0),
BANK("H", PIN(GPIOH_0, 0), PIN(GPIOH_9, 0), 1, 16, 1, 16, 9, 19, 10, 19, 11, 19),
BANK("Z", PIN(GPIOZ_0, 0), PIN(GPIOZ_14, 0), 1, 0, 1, 0, 3, 17, 4, 17, 5, 17),
BANK("CARD", PIN(CARD_0, 0), PIN(CARD_6, 0), 2, 20, 2, 20, 0, 22, 1, 22, 2, 22),
BANK("BOOT", PIN(BOOT_0, 0), PIN(BOOT_18, 0), 2, 0, 2, 0, 9, 0, 10, 0, 11, 0),
/* name first last irq pullen pull dir out in */
BANK("X", PIN(GPIOX_0, 0), PIN(GPIOX_21, 0), 112, 133, 4, 0, 4, 0, 0, 0, 1, 0, 2, 0),
BANK("Y", PIN(GPIOY_0, 0), PIN(GPIOY_16, 0), 95, 111, 3, 0, 3, 0, 3, 0, 4, 0, 5, 0),
BANK("DV", PIN(GPIODV_0, 0), PIN(GPIODV_29, 0), 65, 94, 0, 0, 0, 0, 7, 0, 8, 0, 9, 0),
BANK("H", PIN(GPIOH_0, 0), PIN(GPIOH_9, 0), 29, 38, 1, 16, 1, 16, 9, 19, 10, 19, 11, 19),
BANK("Z", PIN(GPIOZ_0, 0), PIN(GPIOZ_14, 0), 14, 28, 1, 0, 1, 0, 3, 17, 4, 17, 5, 17),
BANK("CARD", PIN(CARD_0, 0), PIN(CARD_6, 0), 58, 64, 2, 20, 2, 20, 0, 22, 1, 22, 2, 22),
BANK("BOOT", PIN(BOOT_0, 0), PIN(BOOT_18, 0), 39, 57, 2, 0, 2, 0, 9, 0, 10, 0, 11, 0),
};
static struct meson_bank meson8_aobus_banks[] = {
/* name first last pullen pull dir out in */
BANK("AO", PIN(GPIOAO_0, AO_OFF), PIN(GPIO_TEST_N, AO_OFF), 0, 0, 0, 16, 0, 0, 0, 16, 1, 0),
/* name first last irq pullen pull dir out in */
BANK("AO", PIN(GPIOAO_0, AO_OFF), PIN(GPIO_TEST_N, AO_OFF), 0, 13, 0, 0, 0, 16, 0, 0, 0, 16, 1, 0),
};
struct meson_pinctrl_data meson8_cbus_pinctrl_data = {

View File

@ -124,6 +124,12 @@ static const struct pinctrl_pin_desc meson8b_aobus_pins[] = {
MESON_PIN(GPIOAO_11, AO_OFF),
MESON_PIN(GPIOAO_12, AO_OFF),
MESON_PIN(GPIOAO_13, AO_OFF),
/*
* The following 2 pins are not mentionned in the public datasheet
* According to this datasheet, they can't be used with the gpio
* interrupt controller
*/
MESON_PIN(GPIO_BSD_EN, AO_OFF),
MESON_PIN(GPIO_TEST_N, AO_OFF),
};
@ -881,19 +887,25 @@ static struct meson_pmx_func meson8b_aobus_functions[] = {
};
static struct meson_bank meson8b_cbus_banks[] = {
/* name first last pullen pull dir out in */
BANK("X", PIN(GPIOX_0, 0), PIN(GPIOX_21, 0), 4, 0, 4, 0, 0, 0, 1, 0, 2, 0),
BANK("Y", PIN(GPIOY_0, 0), PIN(GPIOY_14, 0), 3, 0, 3, 0, 3, 0, 4, 0, 5, 0),
BANK("DV", PIN(GPIODV_9, 0), PIN(GPIODV_29, 0), 0, 0, 0, 0, 7, 0, 8, 0, 9, 0),
BANK("H", PIN(GPIOH_0, 0), PIN(GPIOH_9, 0), 1, 16, 1, 16, 9, 19, 10, 19, 11, 19),
BANK("CARD", PIN(CARD_0, 0), PIN(CARD_6, 0), 2, 20, 2, 20, 0, 22, 1, 22, 2, 22),
BANK("BOOT", PIN(BOOT_0, 0), PIN(BOOT_18, 0), 2, 0, 2, 0, 9, 0, 10, 0, 11, 0),
BANK("DIF", PIN(DIF_0_P, 0), PIN(DIF_4_N, 0), 5, 8, 5, 8, 12, 12, 13, 12, 14, 12),
/* name first last irq pullen pull dir out in */
BANK("X", PIN(GPIOX_0, 0), PIN(GPIOX_21, 0), 97, 118, 4, 0, 4, 0, 0, 0, 1, 0, 2, 0),
BANK("Y", PIN(GPIOY_0, 0), PIN(GPIOY_14, 0), 80, 96, 3, 0, 3, 0, 3, 0, 4, 0, 5, 0),
BANK("DV", PIN(GPIODV_9, 0), PIN(GPIODV_29, 0), 59, 79, 0, 0, 0, 0, 7, 0, 8, 0, 9, 0),
BANK("H", PIN(GPIOH_0, 0), PIN(GPIOH_9, 0), 14, 23, 1, 16, 1, 16, 9, 19, 10, 19, 11, 19),
BANK("CARD", PIN(CARD_0, 0), PIN(CARD_6, 0), 43, 49, 2, 20, 2, 20, 0, 22, 1, 22, 2, 22),
BANK("BOOT", PIN(BOOT_0, 0), PIN(BOOT_18, 0), 24, 42, 2, 0, 2, 0, 9, 0, 10, 0, 11, 0),
/*
* The following bank is not mentionned in the public datasheet
* There is no information whether it can be used with the gpio
* interrupt controller
*/
BANK("DIF", PIN(DIF_0_P, 0), PIN(DIF_4_N, 0), -1, -1, 5, 8, 5, 8, 12, 12, 13, 12, 14, 12),
};
static struct meson_bank meson8b_aobus_banks[] = {
/* name first last pullen pull dir out in */
BANK("AO", PIN(GPIOAO_0, AO_OFF), PIN(GPIO_TEST_N, AO_OFF), 0, 0, 0, 16, 0, 0, 0, 16, 1, 0),
/* name first last irq pullen pull dir out in */
BANK("AO", PIN(GPIOAO_0, AO_OFF), PIN(GPIO_TEST_N, AO_OFF), 0, 13, 0, 0, 0, 16, 0, 0, 0, 16, 1, 0),
};
struct meson_pinctrl_data meson8b_cbus_pinctrl_data = {

View File

@ -1,5 +1,3 @@
if PLAT_ORION
config PINCTRL_MVEBU
bool
select PINMUX
@ -30,6 +28,14 @@ config PINCTRL_ARMADA_39X
bool
select PINCTRL_MVEBU
config PINCTRL_ARMADA_AP806
bool
select PINCTRL_MVEBU
config PINCTRL_ARMADA_CP110
bool
select PINCTRL_MVEBU
config PINCTRL_ARMADA_XP
bool
select PINCTRL_MVEBU
@ -38,8 +44,6 @@ config PINCTRL_ORION
bool
select PINCTRL_MVEBU
endif
config PINCTRL_ARMADA_37XX
bool
select GENERIC_PINCONF

View File

@ -5,6 +5,8 @@ obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o
obj-$(CONFIG_PINCTRL_ARMADA_375) += pinctrl-armada-375.o
obj-$(CONFIG_PINCTRL_ARMADA_38X) += pinctrl-armada-38x.o
obj-$(CONFIG_PINCTRL_ARMADA_39X) += pinctrl-armada-39x.o
obj-$(CONFIG_PINCTRL_ARMADA_AP806) += pinctrl-armada-ap806.o
obj-$(CONFIG_PINCTRL_ARMADA_CP110) += pinctrl-armada-cp110.o
obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o
obj-$(CONFIG_PINCTRL_ARMADA_37XX) += pinctrl-armada-37xx.o
obj-$(CONFIG_PINCTRL_ORION) += pinctrl-orion.o

View File

@ -13,7 +13,9 @@
#include <linux/gpio/driver.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinctrl.h>
@ -30,6 +32,11 @@
#define OUTPUT_CTL 0x20
#define SELECTION 0x30
#define IRQ_EN 0x0
#define IRQ_POL 0x08
#define IRQ_STATUS 0x10
#define IRQ_WKUP 0x18
#define NB_FUNCS 2
#define GPIO_PER_REG 32
@ -75,9 +82,12 @@ struct armada_37xx_pmx_func {
struct armada_37xx_pinctrl {
struct regmap *regmap;
void __iomem *base;
const struct armada_37xx_pin_data *data;
struct device *dev;
struct gpio_chip gpio_chip;
struct irq_chip irq_chip;
spinlock_t irq_lock;
struct pinctrl_desc pctl;
struct pinctrl_dev *pctl_dev;
struct armada_37xx_pin_group *groups;
@ -147,8 +157,9 @@ static struct armada_37xx_pin_group armada_37xx_nb_groups[] = {
PIN_GRP_GPIO("onewire", 4, 1, BIT(16), "onewire"),
PIN_GRP_GPIO("uart1", 25, 2, BIT(17), "uart"),
PIN_GRP_GPIO("spi_quad", 15, 2, BIT(18), "spi"),
PIN_GRP_EXTRA("uart2", 9, 2, BIT(13) | BIT(14) | BIT(19),
BIT(13) | BIT(14), BIT(19), 18, 2, "gpio", "uart"),
PIN_GRP_EXTRA("uart2", 9, 2, BIT(1) | BIT(13) | BIT(14) | BIT(19),
BIT(1) | BIT(13) | BIT(14), BIT(1) | BIT(19),
18, 2, "gpio", "uart"),
PIN_GRP_GPIO("led0_od", 11, 1, BIT(20), "led"),
PIN_GRP_GPIO("led1_od", 12, 1, BIT(21), "led"),
PIN_GRP_GPIO("led2_od", 13, 1, BIT(22), "led"),
@ -159,8 +170,8 @@ static struct armada_37xx_pin_group armada_37xx_nb_groups[] = {
static struct armada_37xx_pin_group armada_37xx_sb_groups[] = {
PIN_GRP_GPIO("usb32_drvvbus0", 0, 1, BIT(0), "drvbus"),
PIN_GRP_GPIO("usb2_drvvbus1", 1, 1, BIT(1), "drvbus"),
PIN_GRP_GPIO("sdio_sb", 24, 5, BIT(2), "sdio"),
PIN_GRP_EXTRA("rgmii", 6, 14, BIT(3), 0, BIT(3), 23, 1, "mii", "gpio"),
PIN_GRP_GPIO("sdio_sb", 24, 6, BIT(2), "sdio"),
PIN_GRP_EXTRA("rgmii", 6, 12, BIT(3), 0, BIT(3), 23, 1, "mii", "gpio"),
PIN_GRP_GPIO("pcie1", 3, 2, BIT(4), "pcie"),
PIN_GRP_GPIO("ptp", 20, 3, BIT(5), "ptp"),
PIN_GRP("ptp_clk", 21, 1, BIT(6), "ptp", "mii"),
@ -346,6 +357,14 @@ static int armada_37xx_pmx_set(struct pinctrl_dev *pctldev,
return armada_37xx_pmx_set_by_name(pctldev, name, grp);
}
static inline void armada_37xx_irq_update_reg(unsigned int *reg,
struct irq_data *d)
{
int offset = irqd_to_hwirq(d);
armada_37xx_update_reg(reg, offset);
}
static int armada_37xx_gpio_direction_input(struct gpio_chip *chip,
unsigned int offset)
{
@ -468,6 +487,214 @@ static const struct gpio_chip armada_37xx_gpiolib_chip = {
.owner = THIS_MODULE,
};
static void armada_37xx_irq_ack(struct irq_data *d)
{
struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
u32 reg = IRQ_STATUS;
unsigned long flags;
armada_37xx_irq_update_reg(&reg, d);
spin_lock_irqsave(&info->irq_lock, flags);
writel(d->mask, info->base + reg);
spin_unlock_irqrestore(&info->irq_lock, flags);
}
static void armada_37xx_irq_mask(struct irq_data *d)
{
struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
u32 val, reg = IRQ_EN;
unsigned long flags;
armada_37xx_irq_update_reg(&reg, d);
spin_lock_irqsave(&info->irq_lock, flags);
val = readl(info->base + reg);
writel(val & ~d->mask, info->base + reg);
spin_unlock_irqrestore(&info->irq_lock, flags);
}
static void armada_37xx_irq_unmask(struct irq_data *d)
{
struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
u32 val, reg = IRQ_EN;
unsigned long flags;
armada_37xx_irq_update_reg(&reg, d);
spin_lock_irqsave(&info->irq_lock, flags);
val = readl(info->base + reg);
writel(val | d->mask, info->base + reg);
spin_unlock_irqrestore(&info->irq_lock, flags);
}
static int armada_37xx_irq_set_wake(struct irq_data *d, unsigned int on)
{
struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
u32 val, reg = IRQ_WKUP;
unsigned long flags;
armada_37xx_irq_update_reg(&reg, d);
spin_lock_irqsave(&info->irq_lock, flags);
val = readl(info->base + reg);
if (on)
val |= d->mask;
else
val &= ~d->mask;
writel(val, info->base + reg);
spin_unlock_irqrestore(&info->irq_lock, flags);
return 0;
}
static int armada_37xx_irq_set_type(struct irq_data *d, unsigned int type)
{
struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
u32 val, reg = IRQ_POL;
unsigned long flags;
spin_lock_irqsave(&info->irq_lock, flags);
armada_37xx_irq_update_reg(&reg, d);
val = readl(info->base + reg);
switch (type) {
case IRQ_TYPE_EDGE_RISING:
val &= ~d->mask;
break;
case IRQ_TYPE_EDGE_FALLING:
val |= d->mask;
break;
default:
spin_unlock_irqrestore(&info->irq_lock, flags);
return -EINVAL;
}
writel(val, info->base + reg);
spin_unlock_irqrestore(&info->irq_lock, flags);
return 0;
}
static void armada_37xx_irq_handler(struct irq_desc *desc)
{
struct gpio_chip *gc = irq_desc_get_handler_data(desc);
struct irq_chip *chip = irq_desc_get_chip(desc);
struct armada_37xx_pinctrl *info = gpiochip_get_data(gc);
struct irq_domain *d = gc->irqdomain;
int i;
chained_irq_enter(chip, desc);
for (i = 0; i <= d->revmap_size / GPIO_PER_REG; i++) {
u32 status;
unsigned long flags;
spin_lock_irqsave(&info->irq_lock, flags);
status = readl_relaxed(info->base + IRQ_STATUS + 4 * i);
/* Manage only the interrupt that was enabled */
status &= readl_relaxed(info->base + IRQ_EN + 4 * i);
spin_unlock_irqrestore(&info->irq_lock, flags);
while (status) {
u32 hwirq = ffs(status) - 1;
u32 virq = irq_find_mapping(d, hwirq +
i * GPIO_PER_REG);
generic_handle_irq(virq);
/* Update status in case a new IRQ appears */
spin_lock_irqsave(&info->irq_lock, flags);
status = readl_relaxed(info->base +
IRQ_STATUS + 4 * i);
/* Manage only the interrupt that was enabled */
status &= readl_relaxed(info->base + IRQ_EN + 4 * i);
spin_unlock_irqrestore(&info->irq_lock, flags);
}
}
chained_irq_exit(chip, desc);
}
static int armada_37xx_irqchip_register(struct platform_device *pdev,
struct armada_37xx_pinctrl *info)
{
struct device_node *np = info->dev->of_node;
int nrirqs = info->data->nr_pins;
struct gpio_chip *gc = &info->gpio_chip;
struct irq_chip *irqchip = &info->irq_chip;
struct resource res;
int ret = -ENODEV, i, nr_irq_parent;
/* Check if we have at least one gpio-controller child node */
for_each_child_of_node(info->dev->of_node, np) {
if (of_property_read_bool(np, "gpio-controller")) {
ret = 0;
break;
}
};
if (ret)
return ret;
nr_irq_parent = of_irq_count(np);
spin_lock_init(&info->irq_lock);
if (!nr_irq_parent) {
dev_err(&pdev->dev, "Invalid or no IRQ\n");
return 0;
}
if (of_address_to_resource(info->dev->of_node, 1, &res)) {
dev_err(info->dev, "cannot find IO resource\n");
return -ENOENT;
}
info->base = devm_ioremap_resource(info->dev, &res);
if (IS_ERR(info->base))
return PTR_ERR(info->base);
irqchip->irq_ack = armada_37xx_irq_ack;
irqchip->irq_mask = armada_37xx_irq_mask;
irqchip->irq_unmask = armada_37xx_irq_unmask;
irqchip->irq_set_wake = armada_37xx_irq_set_wake;
irqchip->irq_set_type = armada_37xx_irq_set_type;
irqchip->name = info->data->name;
ret = gpiochip_irqchip_add(gc, irqchip, 0,
handle_edge_irq, IRQ_TYPE_NONE);
if (ret) {
dev_info(&pdev->dev, "could not add irqchip\n");
return ret;
}
/*
* Many interrupts are connected to the parent interrupt
* controller. But we do not take advantage of this and use
* the chained irq with all of them.
*/
for (i = 0; i < nrirqs; i++) {
struct irq_data *d = irq_get_irq_data(gc->irq_base + i);
/*
* The mask field is a "precomputed bitmask for
* accessing the chip registers" which was introduced
* for the generic irqchip framework. As we don't use
* this framework, we can reuse this field for our own
* usage.
*/
d->mask = BIT(i % GPIO_PER_REG);
}
for (i = 0; i < nr_irq_parent; i++) {
int irq = irq_of_parse_and_map(np, i);
if (irq < 0)
continue;
gpiochip_set_chained_irqchip(gc, irqchip, irq,
armada_37xx_irq_handler);
}
return 0;
}
static int armada_37xx_gpiochip_register(struct platform_device *pdev,
struct armada_37xx_pinctrl *info)
{
@ -494,6 +721,9 @@ static int armada_37xx_gpiochip_register(struct platform_device *pdev,
gc->label = info->data->name;
ret = devm_gpiochip_add_data(&pdev->dev, gc, info);
if (ret)
return ret;
ret = armada_37xx_irqchip_register(pdev, info);
if (ret)
return ret;

View File

@ -0,0 +1,140 @@
/*
* Marvell Armada ap806 pinctrl driver based on mvebu pinctrl core
*
* Copyright (C) 2017 Marvell
*
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
* Hanna Hawa <hannah@marvell.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-mvebu.h"
static struct mvebu_mpp_mode armada_ap806_mpp_modes[] = {
MPP_MODE(0,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "sdio", "clk"),
MPP_FUNCTION(3, "spi0", "clk")),
MPP_MODE(1,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "sdio", "cmd"),
MPP_FUNCTION(3, "spi0", "miso")),
MPP_MODE(2,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "sdio", "d0"),
MPP_FUNCTION(3, "spi0", "mosi")),
MPP_MODE(3,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "sdio", "d1"),
MPP_FUNCTION(3, "spi0", "cs0n")),
MPP_MODE(4,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "sdio", "d2"),
MPP_FUNCTION(3, "i2c0", "sda")),
MPP_MODE(5,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "sdio", "d3"),
MPP_FUNCTION(3, "i2c0", "sdk")),
MPP_MODE(6,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "sdio", "ds")),
MPP_MODE(7,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "sdio", "d4"),
MPP_FUNCTION(3, "uart1", "rxd")),
MPP_MODE(8,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "sdio", "d5"),
MPP_FUNCTION(3, "uart1", "txd")),
MPP_MODE(9,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "sdio", "d6"),
MPP_FUNCTION(3, "spi0", "cs1n")),
MPP_MODE(10,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "sdio", "d7")),
MPP_MODE(11,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(3, "uart0", "txd")),
MPP_MODE(12,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "sdio", "pw_off"),
MPP_FUNCTION(2, "sdio", "hw_rst")),
MPP_MODE(13,
MPP_FUNCTION(0, "gpio", NULL)),
MPP_MODE(14,
MPP_FUNCTION(0, "gpio", NULL)),
MPP_MODE(15,
MPP_FUNCTION(0, "gpio", NULL)),
MPP_MODE(16,
MPP_FUNCTION(0, "gpio", NULL)),
MPP_MODE(17,
MPP_FUNCTION(0, "gpio", NULL)),
MPP_MODE(18,
MPP_FUNCTION(0, "gpio", NULL)),
MPP_MODE(19,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(3, "uart0", "rxd"),
MPP_FUNCTION(4, "sdio", "pw_off")),
};
static struct mvebu_pinctrl_soc_info armada_ap806_pinctrl_info;
static const struct of_device_id armada_ap806_pinctrl_of_match[] = {
{
.compatible = "marvell,ap806-pinctrl",
},
{ },
};
static const struct mvebu_mpp_ctrl armada_ap806_mpp_controls[] = {
MPP_FUNC_CTRL(0, 19, NULL, mvebu_regmap_mpp_ctrl),
};
static struct pinctrl_gpio_range armada_ap806_mpp_gpio_ranges[] = {
MPP_GPIO_RANGE(0, 0, 0, 20),
};
static int armada_ap806_pinctrl_probe(struct platform_device *pdev)
{
struct mvebu_pinctrl_soc_info *soc = &armada_ap806_pinctrl_info;
const struct of_device_id *match =
of_match_device(armada_ap806_pinctrl_of_match, &pdev->dev);
if (!match || !pdev->dev.parent)
return -ENODEV;
soc->variant = 0; /* no variants for Armada AP806 */
soc->controls = armada_ap806_mpp_controls;
soc->ncontrols = ARRAY_SIZE(armada_ap806_mpp_controls);
soc->gpioranges = armada_ap806_mpp_gpio_ranges;
soc->ngpioranges = ARRAY_SIZE(armada_ap806_mpp_gpio_ranges);
soc->modes = armada_ap806_mpp_modes;
soc->nmodes = armada_ap806_mpp_controls[0].npins;
pdev->dev.platform_data = soc;
return mvebu_pinctrl_simple_regmap_probe(pdev, pdev->dev.parent, 0);
}
static struct platform_driver armada_ap806_pinctrl_driver = {
.driver = {
.name = "armada-ap806-pinctrl",
.of_match_table = of_match_ptr(armada_ap806_pinctrl_of_match),
},
.probe = armada_ap806_pinctrl_probe,
};
builtin_platform_driver(armada_ap806_pinctrl_driver);

View File

@ -0,0 +1,687 @@
/*
* Marvell Armada CP110 pinctrl driver based on mvebu pinctrl core
*
* Copyright (C) 2017 Marvell
*
* Hanna Hawa <hannah@marvell.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h>
#include "pinctrl-mvebu.h"
/*
* Even if the pin controller is the same the MMP available depend on the SoC
* integration.
* - In Armada7K (single CP) almost all the MPPs are available (except the
* MMP 39 to 43)
* - In Armada8K (dual CP) the MPPs are split into 2 parts, MPPs 0-31 from
* CPS, and MPPs 32-62 from CPM, the below flags (V_ARMADA_8K_CPM,
* V_ARMADA_8K_CPS) set which MPP is available to the CPx.
* The x_PLUS enum mean that the MPP available for CPx and for Armada70x0
*/
enum {
V_ARMADA_7K = BIT(0),
V_ARMADA_8K_CPM = BIT(1),
V_ARMADA_8K_CPS = BIT(2),
V_ARMADA_7K_8K_CPM = (V_ARMADA_7K | V_ARMADA_8K_CPM),
V_ARMADA_7K_8K_CPS = (V_ARMADA_7K | V_ARMADA_8K_CPS),
};
static struct mvebu_mpp_mode armada_cp110_mpp_modes[] = {
MPP_MODE(0,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "ale1"),
MPP_FUNCTION(2, "au", "i2smclk"),
MPP_FUNCTION(3, "ge0", "rxd3"),
MPP_FUNCTION(4, "tdm", "pclk"),
MPP_FUNCTION(6, "ptp", "pulse"),
MPP_FUNCTION(7, "mss_i2c", "sda"),
MPP_FUNCTION(8, "uart0", "rxd"),
MPP_FUNCTION(9, "sata0", "present_act"),
MPP_FUNCTION(10, "ge", "mdio")),
MPP_MODE(1,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "ale0"),
MPP_FUNCTION(2, "au", "i2sdo_spdifo"),
MPP_FUNCTION(3, "ge0", "rxd2"),
MPP_FUNCTION(4, "tdm", "drx"),
MPP_FUNCTION(6, "ptp", "clk"),
MPP_FUNCTION(7, "mss_i2c", "sck"),
MPP_FUNCTION(8, "uart0", "txd"),
MPP_FUNCTION(9, "sata1", "present_act"),
MPP_FUNCTION(10, "ge", "mdc")),
MPP_MODE(2,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "ad15"),
MPP_FUNCTION(2, "au", "i2sextclk"),
MPP_FUNCTION(3, "ge0", "rxd1"),
MPP_FUNCTION(4, "tdm", "dtx"),
MPP_FUNCTION(5, "mss_uart", "rxd"),
MPP_FUNCTION(6, "ptp", "pclk_out"),
MPP_FUNCTION(7, "i2c1", "sck"),
MPP_FUNCTION(8, "uart1", "rxd"),
MPP_FUNCTION(9, "sata0", "present_act"),
MPP_FUNCTION(10, "xg", "mdc")),
MPP_MODE(3,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "ad14"),
MPP_FUNCTION(2, "au", "i2slrclk"),
MPP_FUNCTION(3, "ge0", "rxd0"),
MPP_FUNCTION(4, "tdm", "fsync"),
MPP_FUNCTION(5, "mss_uart", "txd"),
MPP_FUNCTION(6, "pcie", "rstoutn"),
MPP_FUNCTION(7, "i2c1", "sda"),
MPP_FUNCTION(8, "uart1", "txd"),
MPP_FUNCTION(9, "sata1", "present_act"),
MPP_FUNCTION(10, "xg", "mdio")),
MPP_MODE(4,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "ad13"),
MPP_FUNCTION(2, "au", "i2sbclk"),
MPP_FUNCTION(3, "ge0", "rxctl"),
MPP_FUNCTION(4, "tdm", "rstn"),
MPP_FUNCTION(5, "mss_uart", "rxd"),
MPP_FUNCTION(6, "uart1", "cts"),
MPP_FUNCTION(7, "pcie0", "clkreq"),
MPP_FUNCTION(8, "uart3", "rxd"),
MPP_FUNCTION(10, "ge", "mdc")),
MPP_MODE(5,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "ad12"),
MPP_FUNCTION(2, "au", "i2sdi"),
MPP_FUNCTION(3, "ge0", "rxclk"),
MPP_FUNCTION(4, "tdm", "intn"),
MPP_FUNCTION(5, "mss_uart", "txd"),
MPP_FUNCTION(6, "uart1", "rts"),
MPP_FUNCTION(7, "pcie1", "clkreq"),
MPP_FUNCTION(8, "uart3", "txd"),
MPP_FUNCTION(10, "ge", "mdio")),
MPP_MODE(6,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "ad11"),
MPP_FUNCTION(3, "ge0", "txd3"),
MPP_FUNCTION(4, "spi0", "csn2"),
MPP_FUNCTION(5, "au", "i2sextclk"),
MPP_FUNCTION(6, "sata1", "present_act"),
MPP_FUNCTION(7, "pcie2", "clkreq"),
MPP_FUNCTION(8, "uart0", "rxd"),
MPP_FUNCTION(9, "ptp", "pulse")),
MPP_MODE(7,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "ad10"),
MPP_FUNCTION(3, "ge0", "txd2"),
MPP_FUNCTION(4, "spi0", "csn1"),
MPP_FUNCTION(5, "spi1", "csn1"),
MPP_FUNCTION(6, "sata0", "present_act"),
MPP_FUNCTION(7, "led", "data"),
MPP_FUNCTION(8, "uart0", "txd"),
MPP_FUNCTION(9, "ptp", "clk")),
MPP_MODE(8,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "ad9"),
MPP_FUNCTION(3, "ge0", "txd1"),
MPP_FUNCTION(4, "spi0", "csn0"),
MPP_FUNCTION(5, "spi1", "csn0"),
MPP_FUNCTION(6, "uart0", "cts"),
MPP_FUNCTION(7, "led", "stb"),
MPP_FUNCTION(8, "uart2", "rxd"),
MPP_FUNCTION(9, "ptp", "pclk_out"),
MPP_FUNCTION(10, "synce1", "clk")),
MPP_MODE(9,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "ad8"),
MPP_FUNCTION(3, "ge0", "txd0"),
MPP_FUNCTION(4, "spi0", "mosi"),
MPP_FUNCTION(5, "spi1", "mosi"),
MPP_FUNCTION(7, "pcie", "rstoutn"),
MPP_FUNCTION(10, "synce2", "clk")),
MPP_MODE(10,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "readyn"),
MPP_FUNCTION(3, "ge0", "txctl"),
MPP_FUNCTION(4, "spi0", "miso"),
MPP_FUNCTION(5, "spi1", "miso"),
MPP_FUNCTION(6, "uart0", "cts"),
MPP_FUNCTION(7, "sata1", "present_act")),
MPP_MODE(11,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "wen1"),
MPP_FUNCTION(3, "ge0", "txclkout"),
MPP_FUNCTION(4, "spi0", "clk"),
MPP_FUNCTION(5, "spi1", "clk"),
MPP_FUNCTION(6, "uart0", "rts"),
MPP_FUNCTION(7, "led", "clk"),
MPP_FUNCTION(8, "uart2", "txd"),
MPP_FUNCTION(9, "sata0", "present_act")),
MPP_MODE(12,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "clk_out"),
MPP_FUNCTION(2, "nf", "rbn1"),
MPP_FUNCTION(3, "spi1", "csn1"),
MPP_FUNCTION(4, "ge0", "rxclk")),
MPP_MODE(13,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "burstn"),
MPP_FUNCTION(2, "nf", "rbn0"),
MPP_FUNCTION(3, "spi1", "miso"),
MPP_FUNCTION(4, "ge0", "rxctl"),
MPP_FUNCTION(8, "mss_spi", "miso")),
MPP_MODE(14,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "bootcsn"),
MPP_FUNCTION(2, "dev", "csn0"),
MPP_FUNCTION(3, "spi1", "csn0"),
MPP_FUNCTION(4, "spi0", "csn3"),
MPP_FUNCTION(5, "au", "i2sextclk"),
MPP_FUNCTION(6, "spi0", "miso"),
MPP_FUNCTION(7, "sata0", "present_act"),
MPP_FUNCTION(8, "mss_spi", "csn")),
MPP_MODE(15,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "ad7"),
MPP_FUNCTION(3, "spi1", "mosi"),
MPP_FUNCTION(6, "spi0", "mosi"),
MPP_FUNCTION(8, "mss_spi", "mosi"),
MPP_FUNCTION(11, "ptp", "pulse_cp2cp")),
MPP_MODE(16,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "ad6"),
MPP_FUNCTION(3, "spi1", "clk"),
MPP_FUNCTION(8, "mss_spi", "clk")),
MPP_MODE(17,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "ad5"),
MPP_FUNCTION(4, "ge0", "txd3")),
MPP_MODE(18,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "ad4"),
MPP_FUNCTION(4, "ge0", "txd2"),
MPP_FUNCTION(11, "ptp", "clk_cp2cp")),
MPP_MODE(19,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "ad3"),
MPP_FUNCTION(4, "ge0", "txd1"),
MPP_FUNCTION(11, "wakeup", "out_cp2cp")),
MPP_MODE(20,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "ad2"),
MPP_FUNCTION(4, "ge0", "txd0")),
MPP_MODE(21,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "ad1"),
MPP_FUNCTION(4, "ge0", "txctl"),
MPP_FUNCTION(11, "sei", "in_cp2cp")),
MPP_MODE(22,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "ad0"),
MPP_FUNCTION(4, "ge0", "txclkout"),
MPP_FUNCTION(11, "wakeup", "in_cp2cp")),
MPP_MODE(23,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "a1"),
MPP_FUNCTION(5, "au", "i2smclk"),
MPP_FUNCTION(11, "link", "rd_in_cp2cp")),
MPP_MODE(24,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "a0"),
MPP_FUNCTION(5, "au", "i2slrclk")),
MPP_MODE(25,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "oen"),
MPP_FUNCTION(5, "au", "i2sdo_spdifo")),
MPP_MODE(26,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "wen0"),
MPP_FUNCTION(5, "au", "i2sbclk")),
MPP_MODE(27,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "csn0"),
MPP_FUNCTION(2, "spi1", "miso"),
MPP_FUNCTION(3, "mss_gpio4", NULL),
MPP_FUNCTION(4, "ge0", "rxd3"),
MPP_FUNCTION(5, "spi0", "csn4"),
MPP_FUNCTION(8, "ge", "mdio"),
MPP_FUNCTION(9, "sata0", "present_act"),
MPP_FUNCTION(10, "uart0", "rts"),
MPP_FUNCTION(11, "rei", "in_cp2cp")),
MPP_MODE(28,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "csn1"),
MPP_FUNCTION(2, "spi1", "csn0"),
MPP_FUNCTION(3, "mss_gpio5", NULL),
MPP_FUNCTION(4, "ge0", "rxd2"),
MPP_FUNCTION(5, "spi0", "csn5"),
MPP_FUNCTION(6, "pcie2", "clkreq"),
MPP_FUNCTION(7, "ptp", "pulse"),
MPP_FUNCTION(8, "ge", "mdc"),
MPP_FUNCTION(9, "sata1", "present_act"),
MPP_FUNCTION(10, "uart0", "cts"),
MPP_FUNCTION(11, "led", "data")),
MPP_MODE(29,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "csn2"),
MPP_FUNCTION(2, "spi1", "mosi"),
MPP_FUNCTION(3, "mss_gpio6", NULL),
MPP_FUNCTION(4, "ge0", "rxd1"),
MPP_FUNCTION(5, "spi0", "csn6"),
MPP_FUNCTION(6, "pcie1", "clkreq"),
MPP_FUNCTION(7, "ptp", "clk"),
MPP_FUNCTION(8, "mss_i2c", "sda"),
MPP_FUNCTION(9, "sata0", "present_act"),
MPP_FUNCTION(10, "uart0", "rxd"),
MPP_FUNCTION(11, "led", "stb")),
MPP_MODE(30,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "csn3"),
MPP_FUNCTION(2, "spi1", "clk"),
MPP_FUNCTION(3, "mss_gpio7", NULL),
MPP_FUNCTION(4, "ge0", "rxd0"),
MPP_FUNCTION(5, "spi0", "csn7"),
MPP_FUNCTION(6, "pcie0", "clkreq"),
MPP_FUNCTION(7, "ptp", "pclk_out"),
MPP_FUNCTION(8, "mss_i2c", "sck"),
MPP_FUNCTION(9, "sata1", "present_act"),
MPP_FUNCTION(10, "uart0", "txd"),
MPP_FUNCTION(11, "led", "clk")),
MPP_MODE(31,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "dev", "a2"),
MPP_FUNCTION(3, "mss_gpio4", NULL),
MPP_FUNCTION(6, "pcie", "rstoutn"),
MPP_FUNCTION(8, "ge", "mdc")),
MPP_MODE(32,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "mii", "col"),
MPP_FUNCTION(2, "mii", "txerr"),
MPP_FUNCTION(3, "mss_spi", "miso"),
MPP_FUNCTION(4, "tdm", "drx"),
MPP_FUNCTION(5, "au", "i2sextclk"),
MPP_FUNCTION(6, "au", "i2sdi"),
MPP_FUNCTION(7, "ge", "mdio"),
MPP_FUNCTION(8, "sdio", "v18_en"),
MPP_FUNCTION(9, "pcie1", "clkreq"),
MPP_FUNCTION(10, "mss_gpio0", NULL)),
MPP_MODE(33,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "mii", "txclk"),
MPP_FUNCTION(2, "sdio", "pwr10"),
MPP_FUNCTION(3, "mss_spi", "csn"),
MPP_FUNCTION(4, "tdm", "fsync"),
MPP_FUNCTION(5, "au", "i2smclk"),
MPP_FUNCTION(6, "sdio", "bus_pwr"),
MPP_FUNCTION(8, "xg", "mdio"),
MPP_FUNCTION(9, "pcie2", "clkreq"),
MPP_FUNCTION(10, "mss_gpio1", NULL)),
MPP_MODE(34,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "mii", "rxerr"),
MPP_FUNCTION(2, "sdio", "pwr11"),
MPP_FUNCTION(3, "mss_spi", "mosi"),
MPP_FUNCTION(4, "tdm", "dtx"),
MPP_FUNCTION(5, "au", "i2slrclk"),
MPP_FUNCTION(6, "sdio", "wr_protect"),
MPP_FUNCTION(7, "ge", "mdc"),
MPP_FUNCTION(9, "pcie0", "clkreq"),
MPP_FUNCTION(10, "mss_gpio2", NULL)),
MPP_MODE(35,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "sata1", "present_act"),
MPP_FUNCTION(2, "i2c1", "sda"),
MPP_FUNCTION(3, "mss_spi", "clk"),
MPP_FUNCTION(4, "tdm", "pclk"),
MPP_FUNCTION(5, "au", "i2sdo_spdifo"),
MPP_FUNCTION(6, "sdio", "card_detect"),
MPP_FUNCTION(7, "xg", "mdio"),
MPP_FUNCTION(8, "ge", "mdio"),
MPP_FUNCTION(9, "pcie", "rstoutn"),
MPP_FUNCTION(10, "mss_gpio3", NULL)),
MPP_MODE(36,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "synce2", "clk"),
MPP_FUNCTION(2, "i2c1", "sck"),
MPP_FUNCTION(3, "ptp", "clk"),
MPP_FUNCTION(4, "synce1", "clk"),
MPP_FUNCTION(5, "au", "i2sbclk"),
MPP_FUNCTION(6, "sata0", "present_act"),
MPP_FUNCTION(7, "xg", "mdc"),
MPP_FUNCTION(8, "ge", "mdc"),
MPP_FUNCTION(9, "pcie2", "clkreq"),
MPP_FUNCTION(10, "mss_gpio5", NULL)),
MPP_MODE(37,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "uart2", "rxd"),
MPP_FUNCTION(2, "i2c0", "sck"),
MPP_FUNCTION(3, "ptp", "pclk_out"),
MPP_FUNCTION(4, "tdm", "intn"),
MPP_FUNCTION(5, "mss_i2c", "sck"),
MPP_FUNCTION(6, "sata1", "present_act"),
MPP_FUNCTION(7, "ge", "mdc"),
MPP_FUNCTION(8, "xg", "mdc"),
MPP_FUNCTION(9, "pcie1", "clkreq"),
MPP_FUNCTION(10, "mss_gpio6", NULL),
MPP_FUNCTION(11, "link", "rd_out_cp2cp")),
MPP_MODE(38,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "uart2", "txd"),
MPP_FUNCTION(2, "i2c0", "sda"),
MPP_FUNCTION(3, "ptp", "pulse"),
MPP_FUNCTION(4, "tdm", "rstn"),
MPP_FUNCTION(5, "mss_i2c", "sda"),
MPP_FUNCTION(6, "sata0", "present_act"),
MPP_FUNCTION(7, "ge", "mdio"),
MPP_FUNCTION(8, "xg", "mdio"),
MPP_FUNCTION(9, "au", "i2sextclk"),
MPP_FUNCTION(10, "mss_gpio7", NULL),
MPP_FUNCTION(11, "ptp", "pulse_cp2cp")),
MPP_MODE(39,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "sdio", "wr_protect"),
MPP_FUNCTION(4, "au", "i2sbclk"),
MPP_FUNCTION(5, "ptp", "clk"),
MPP_FUNCTION(6, "spi0", "csn1"),
MPP_FUNCTION(9, "sata1", "present_act"),
MPP_FUNCTION(10, "mss_gpio0", NULL)),
MPP_MODE(40,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "sdio", "pwr11"),
MPP_FUNCTION(2, "synce1", "clk"),
MPP_FUNCTION(3, "mss_i2c", "sda"),
MPP_FUNCTION(4, "au", "i2sdo_spdifo"),
MPP_FUNCTION(5, "ptp", "pclk_out"),
MPP_FUNCTION(6, "spi0", "clk"),
MPP_FUNCTION(7, "uart1", "txd"),
MPP_FUNCTION(8, "ge", "mdio"),
MPP_FUNCTION(9, "sata0", "present_act"),
MPP_FUNCTION(10, "mss_gpio1", NULL)),
MPP_MODE(41,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "sdio", "pwr10"),
MPP_FUNCTION(2, "sdio", "bus_pwr"),
MPP_FUNCTION(3, "mss_i2c", "sck"),
MPP_FUNCTION(4, "au", "i2slrclk"),
MPP_FUNCTION(5, "ptp", "pulse"),
MPP_FUNCTION(6, "spi0", "mosi"),
MPP_FUNCTION(7, "uart1", "rxd"),
MPP_FUNCTION(8, "ge", "mdc"),
MPP_FUNCTION(9, "sata1", "present_act"),
MPP_FUNCTION(10, "mss_gpio2", NULL),
MPP_FUNCTION(11, "rei", "out_cp2cp")),
MPP_MODE(42,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "sdio", "v18_en"),
MPP_FUNCTION(2, "sdio", "wr_protect"),
MPP_FUNCTION(3, "synce2", "clk"),
MPP_FUNCTION(4, "au", "i2smclk"),
MPP_FUNCTION(5, "mss_uart", "txd"),
MPP_FUNCTION(6, "spi0", "miso"),
MPP_FUNCTION(7, "uart1", "cts"),
MPP_FUNCTION(8, "xg", "mdc"),
MPP_FUNCTION(9, "sata0", "present_act"),
MPP_FUNCTION(10, "mss_gpio4", NULL)),
MPP_MODE(43,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "sdio", "card_detect"),
MPP_FUNCTION(3, "synce1", "clk"),
MPP_FUNCTION(4, "au", "i2sextclk"),
MPP_FUNCTION(5, "mss_uart", "rxd"),
MPP_FUNCTION(6, "spi0", "csn0"),
MPP_FUNCTION(7, "uart1", "rts"),
MPP_FUNCTION(8, "xg", "mdio"),
MPP_FUNCTION(9, "sata1", "present_act"),
MPP_FUNCTION(10, "mss_gpio5", NULL),
MPP_FUNCTION(11, "wakeup", "out_cp2cp")),
MPP_MODE(44,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "ge1", "txd2"),
MPP_FUNCTION(7, "uart0", "rts"),
MPP_FUNCTION(11, "ptp", "clk_cp2cp")),
MPP_MODE(45,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "ge1", "txd3"),
MPP_FUNCTION(7, "uart0", "txd"),
MPP_FUNCTION(9, "pcie", "rstoutn")),
MPP_MODE(46,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "ge1", "txd1"),
MPP_FUNCTION(7, "uart1", "rts")),
MPP_MODE(47,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "ge1", "txd0"),
MPP_FUNCTION(5, "spi1", "clk"),
MPP_FUNCTION(7, "uart1", "txd"),
MPP_FUNCTION(8, "ge", "mdc")),
MPP_MODE(48,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "ge1", "txctl_txen"),
MPP_FUNCTION(5, "spi1", "mosi"),
MPP_FUNCTION(8, "xg", "mdc"),
MPP_FUNCTION(11, "wakeup", "in_cp2cp")),
MPP_MODE(49,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "ge1", "txclkout"),
MPP_FUNCTION(2, "mii", "crs"),
MPP_FUNCTION(5, "spi1", "miso"),
MPP_FUNCTION(7, "uart1", "rxd"),
MPP_FUNCTION(8, "ge", "mdio"),
MPP_FUNCTION(9, "pcie0", "clkreq"),
MPP_FUNCTION(10, "sdio", "v18_en"),
MPP_FUNCTION(11, "sei", "out_cp2cp")),
MPP_MODE(50,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "ge1", "rxclk"),
MPP_FUNCTION(2, "mss_i2c", "sda"),
MPP_FUNCTION(5, "spi1", "csn0"),
MPP_FUNCTION(6, "uart2", "txd"),
MPP_FUNCTION(7, "uart0", "rxd"),
MPP_FUNCTION(8, "xg", "mdio"),
MPP_FUNCTION(10, "sdio", "pwr11")),
MPP_MODE(51,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "ge1", "rxd0"),
MPP_FUNCTION(2, "mss_i2c", "sck"),
MPP_FUNCTION(5, "spi1", "csn1"),
MPP_FUNCTION(6, "uart2", "rxd"),
MPP_FUNCTION(7, "uart0", "cts"),
MPP_FUNCTION(10, "sdio", "pwr10")),
MPP_MODE(52,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "ge1", "rxd1"),
MPP_FUNCTION(2, "synce1", "clk"),
MPP_FUNCTION(4, "synce2", "clk"),
MPP_FUNCTION(5, "spi1", "csn2"),
MPP_FUNCTION(7, "uart1", "cts"),
MPP_FUNCTION(8, "led", "clk"),
MPP_FUNCTION(9, "pcie", "rstoutn"),
MPP_FUNCTION(10, "pcie0", "clkreq")),
MPP_MODE(53,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "ge1", "rxd2"),
MPP_FUNCTION(3, "ptp", "clk"),
MPP_FUNCTION(5, "spi1", "csn3"),
MPP_FUNCTION(7, "uart1", "rxd"),
MPP_FUNCTION(8, "led", "stb"),
MPP_FUNCTION(11, "sdio", "led")),
MPP_MODE(54,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "ge1", "rxd3"),
MPP_FUNCTION(2, "synce2", "clk"),
MPP_FUNCTION(3, "ptp", "pclk_out"),
MPP_FUNCTION(4, "synce1", "clk"),
MPP_FUNCTION(8, "led", "data"),
MPP_FUNCTION(10, "sdio", "hw_rst"),
MPP_FUNCTION(11, "sdio", "wr_protect")),
MPP_MODE(55,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "ge1", "rxctl_rxdv"),
MPP_FUNCTION(3, "ptp", "pulse"),
MPP_FUNCTION(10, "sdio", "led"),
MPP_FUNCTION(11, "sdio", "card_detect")),
MPP_MODE(56,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(4, "tdm", "drx"),
MPP_FUNCTION(5, "au", "i2sdo_spdifo"),
MPP_FUNCTION(6, "spi0", "clk"),
MPP_FUNCTION(7, "uart1", "rxd"),
MPP_FUNCTION(9, "sata1", "present_act"),
MPP_FUNCTION(14, "sdio", "clk")),
MPP_MODE(57,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(2, "mss_i2c", "sda"),
MPP_FUNCTION(3, "ptp", "pclk_out"),
MPP_FUNCTION(4, "tdm", "intn"),
MPP_FUNCTION(5, "au", "i2sbclk"),
MPP_FUNCTION(6, "spi0", "mosi"),
MPP_FUNCTION(7, "uart1", "txd"),
MPP_FUNCTION(9, "sata0", "present_act"),
MPP_FUNCTION(14, "sdio", "cmd")),
MPP_MODE(58,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(2, "mss_i2c", "sck"),
MPP_FUNCTION(3, "ptp", "clk"),
MPP_FUNCTION(4, "tdm", "rstn"),
MPP_FUNCTION(5, "au", "i2sdi"),
MPP_FUNCTION(6, "spi0", "miso"),
MPP_FUNCTION(7, "uart1", "cts"),
MPP_FUNCTION(8, "led", "clk"),
MPP_FUNCTION(14, "sdio", "d0")),
MPP_MODE(59,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "mss_gpio7", NULL),
MPP_FUNCTION(2, "synce2", "clk"),
MPP_FUNCTION(4, "tdm", "fsync"),
MPP_FUNCTION(5, "au", "i2slrclk"),
MPP_FUNCTION(6, "spi0", "csn0"),
MPP_FUNCTION(7, "uart0", "cts"),
MPP_FUNCTION(8, "led", "stb"),
MPP_FUNCTION(9, "uart1", "txd"),
MPP_FUNCTION(14, "sdio", "d1")),
MPP_MODE(60,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "mss_gpio6", NULL),
MPP_FUNCTION(3, "ptp", "pulse"),
MPP_FUNCTION(4, "tdm", "dtx"),
MPP_FUNCTION(5, "au", "i2smclk"),
MPP_FUNCTION(6, "spi0", "csn1"),
MPP_FUNCTION(7, "uart0", "rts"),
MPP_FUNCTION(8, "led", "data"),
MPP_FUNCTION(9, "uart1", "rxd"),
MPP_FUNCTION(14, "sdio", "d2")),
MPP_MODE(61,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "mss_gpio5", NULL),
MPP_FUNCTION(3, "ptp", "clk"),
MPP_FUNCTION(4, "tdm", "pclk"),
MPP_FUNCTION(5, "au", "i2sextclk"),
MPP_FUNCTION(6, "spi0", "csn2"),
MPP_FUNCTION(7, "uart0", "txd"),
MPP_FUNCTION(8, "uart2", "txd"),
MPP_FUNCTION(9, "sata1", "present_act"),
MPP_FUNCTION(10, "ge", "mdio"),
MPP_FUNCTION(14, "sdio", "d3")),
MPP_MODE(62,
MPP_FUNCTION(0, "gpio", NULL),
MPP_FUNCTION(1, "mss_gpio4", NULL),
MPP_FUNCTION(2, "synce1", "clk"),
MPP_FUNCTION(3, "ptp", "pclk_out"),
MPP_FUNCTION(5, "sata1", "present_act"),
MPP_FUNCTION(6, "spi0", "csn3"),
MPP_FUNCTION(7, "uart0", "rxd"),
MPP_FUNCTION(8, "uart2", "rxd"),
MPP_FUNCTION(9, "sata0", "present_act"),
MPP_FUNCTION(10, "ge", "mdc")),
};
static const struct of_device_id armada_cp110_pinctrl_of_match[] = {
{
.compatible = "marvell,armada-7k-pinctrl",
.data = (void *) V_ARMADA_7K,
},
{
.compatible = "marvell,armada-8k-cpm-pinctrl",
.data = (void *) V_ARMADA_8K_CPM,
},
{
.compatible = "marvell,armada-8k-cps-pinctrl",
.data = (void *) V_ARMADA_8K_CPS,
},
{ },
};
static const struct mvebu_mpp_ctrl armada_cp110_mpp_controls[] = {
MPP_FUNC_CTRL(0, 62, NULL, mvebu_regmap_mpp_ctrl),
};
static void mvebu_pinctrl_assign_variant(struct mvebu_mpp_mode *m,
u8 variant)
{
struct mvebu_mpp_ctrl_setting *s;
for (s = m->settings ; s->name ; s++)
s->variant = variant;
}
static int armada_cp110_pinctrl_probe(struct platform_device *pdev)
{
struct mvebu_pinctrl_soc_info *soc;
const struct of_device_id *match =
of_match_device(armada_cp110_pinctrl_of_match, &pdev->dev);
int i;
if (!pdev->dev.parent)
return -ENODEV;
soc = devm_kzalloc(&pdev->dev,
sizeof(struct mvebu_pinctrl_soc_info), GFP_KERNEL);
if (!soc)
return -ENOMEM;
soc->variant = (unsigned long) match->data & 0xff;
soc->controls = armada_cp110_mpp_controls;
soc->ncontrols = ARRAY_SIZE(armada_cp110_mpp_controls);
soc->modes = armada_cp110_mpp_modes;
soc->nmodes = ARRAY_SIZE(armada_cp110_mpp_modes);
for (i = 0; i < ARRAY_SIZE(armada_cp110_mpp_modes); i++) {
struct mvebu_mpp_mode *m = &armada_cp110_mpp_modes[i];
switch (i) {
case 0 ... 31:
mvebu_pinctrl_assign_variant(m, V_ARMADA_7K_8K_CPS);
break;
case 32 ... 38:
mvebu_pinctrl_assign_variant(m, V_ARMADA_7K_8K_CPM);
break;
case 39 ... 43:
mvebu_pinctrl_assign_variant(m, V_ARMADA_8K_CPM);
break;
case 44 ... 62:
mvebu_pinctrl_assign_variant(m, V_ARMADA_7K_8K_CPM);
break;
}
}
pdev->dev.platform_data = soc;
return mvebu_pinctrl_simple_regmap_probe(pdev, pdev->dev.parent, 0);
}
static struct platform_driver armada_cp110_pinctrl_driver = {
.driver = {
.name = "armada-cp110-pinctrl",
.of_match_table = of_match_ptr(armada_cp110_pinctrl_of_match),
},
.probe = armada_cp110_pinctrl_probe,
};
builtin_platform_driver(armada_cp110_pinctrl_driver);

View File

@ -810,21 +810,17 @@ int mvebu_regmap_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data,
}
int mvebu_pinctrl_simple_regmap_probe(struct platform_device *pdev,
struct device *syscon_dev)
struct device *syscon_dev, u32 offset)
{
struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(&pdev->dev);
struct mvebu_mpp_ctrl_data *mpp_data;
struct regmap *regmap;
u32 offset;
int i;
regmap = syscon_node_to_regmap(syscon_dev->of_node);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
if (of_property_read_u32(pdev->dev.of_node, "offset", &offset))
return -EINVAL;
mpp_data = devm_kcalloc(&pdev->dev, soc->ncontrols, sizeof(*mpp_data),
GFP_KERNEL);
if (!mpp_data)

View File

@ -210,6 +210,6 @@ int mvebu_regmap_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,
int mvebu_pinctrl_probe(struct platform_device *pdev);
int mvebu_pinctrl_simple_mmio_probe(struct platform_device *pdev);
int mvebu_pinctrl_simple_regmap_probe(struct platform_device *pdev,
struct device *syscon_dev);
struct device *syscon_dev, u32 offset);
#endif

View File

@ -44,6 +44,7 @@ static const struct pin_config_item conf_items[] = {
PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL, false),
PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_ENABLE, "input schmitt enabled", NULL, false),
PCONFDUMP(PIN_CONFIG_LOW_POWER_MODE, "pin low power", "mode", true),
PCONFDUMP(PIN_CONFIG_OUTPUT_ENABLE, "output enabled", NULL, false),
PCONFDUMP(PIN_CONFIG_OUTPUT, "pin output", "level", true),
PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector", true),
PCONFDUMP(PIN_CONFIG_SLEW_RATE, "slew rate", NULL, true),
@ -172,6 +173,8 @@ static const struct pinconf_generic_params dt_params[] = {
{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
{ "low-power-disable", PIN_CONFIG_LOW_POWER_MODE, 0 },
{ "low-power-enable", PIN_CONFIG_LOW_POWER_MODE, 1 },
{ "output-disable", PIN_CONFIG_OUTPUT_ENABLE, 0 },
{ "output-enable", PIN_CONFIG_OUTPUT_ENABLE, 1 },
{ "output-high", PIN_CONFIG_OUTPUT, 1, },
{ "output-low", PIN_CONFIG_OUTPUT, 0, },
{ "power-source", PIN_CONFIG_POWER_SOURCE, 0 },

View File

@ -87,9 +87,8 @@ int pin_config_group_get(const char *dev_name, const char *pin_group,
ops = pctldev->desc->confops;
if (!ops || !ops->pin_config_group_get) {
dev_dbg(pctldev->dev, "cannot get configuration for pin "
"group, missing group config get function in "
"driver\n");
dev_dbg(pctldev->dev,
"cannot get configuration for pin group, missing group config get function in driver\n");
ret = -ENOTSUPP;
goto unlock;
}
@ -232,7 +231,7 @@ static void pinconf_show_config(struct seq_file *s, struct pinctrl_dev *pctldev,
configs[i]);
else
seq_printf(s, "%08lx", configs[i]);
seq_puts(s, "\n");
seq_putc(s, '\n');
}
}
@ -244,10 +243,10 @@ void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map)
switch (map->type) {
case PIN_MAP_TYPE_CONFIGS_PIN:
seq_printf(s, "pin ");
seq_puts(s, "pin ");
break;
case PIN_MAP_TYPE_CONFIGS_GROUP:
seq_printf(s, "group ");
seq_puts(s, "group ");
break;
default:
break;
@ -319,14 +318,13 @@ static int pinconf_pins_show(struct seq_file *s, void *what)
pin = pctldev->desc->pins[i].number;
desc = pin_desc_get(pctldev, pin);
/* Skip if we cannot search the pin */
if (desc == NULL)
if (!desc)
continue;
seq_printf(s, "pin %d (%s): ", pin, desc->name);
pinconf_dump_pin(pctldev, s, pin);
seq_printf(s, "\n");
seq_putc(s, '\n');
}
mutex_unlock(&pctldev->mutex);
@ -361,8 +359,7 @@ static int pinconf_groups_show(struct seq_file *s, void *what)
seq_printf(s, "%u (%s): ", selector, gname);
pinconf_dump_group(pctldev, s, selector, gname);
seq_printf(s, "\n");
seq_putc(s, '\n');
selector++;
}
@ -397,9 +394,9 @@ static const struct file_operations pinconf_groups_ops = {
struct dbg_cfg {
enum pinctrl_map_type map_type;
char dev_name[MAX_NAME_LEN+1];
char state_name[MAX_NAME_LEN+1];
char pin_name[MAX_NAME_LEN+1];
char dev_name[MAX_NAME_LEN + 1];
char state_name[MAX_NAME_LEN + 1];
char pin_name[MAX_NAME_LEN + 1];
};
/*
@ -485,7 +482,7 @@ static ssize_t pinconf_dbg_config_write(struct file *file,
const struct pinconf_ops *confops = NULL;
struct dbg_cfg *dbg = &pinconf_dbg_conf;
const struct pinctrl_map_configs *configs;
char config[MAX_NAME_LEN+1];
char config[MAX_NAME_LEN + 1];
char buf[128];
char *b = &buf[0];
int buf_size;
@ -526,7 +523,7 @@ static ssize_t pinconf_dbg_config_write(struct file *file,
/* get arg 'device_name' */
token = strsep(&b, " ");
if (token == NULL)
if (!token)
return -EINVAL;
if (strlen(token) >= MAX_NAME_LEN)
return -EINVAL;
@ -534,7 +531,7 @@ static ssize_t pinconf_dbg_config_write(struct file *file,
/* get arg 'state_name' */
token = strsep(&b, " ");
if (token == NULL)
if (!token)
return -EINVAL;
if (strlen(token) >= MAX_NAME_LEN)
return -EINVAL;
@ -542,7 +539,7 @@ static ssize_t pinconf_dbg_config_write(struct file *file,
/* get arg 'pin_name' */
token = strsep(&b, " ");
if (token == NULL)
if (!token)
return -EINVAL;
if (strlen(token) >= MAX_NAME_LEN)
return -EINVAL;
@ -550,7 +547,7 @@ static ssize_t pinconf_dbg_config_write(struct file *file,
/* get new_value of config' */
token = strsep(&b, " ");
if (token == NULL)
if (!token)
return -EINVAL;
if (strlen(token) >= MAX_NAME_LEN)
return -EINVAL;

View File

@ -8,6 +8,10 @@
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* Contact Information: Nehal Shah <Nehal-bakulchandra.Shah@amd.com>
* Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
*
*/
#include <linux/err.h>

View File

@ -0,0 +1,852 @@
/*
* Ingenic SoCs pinctrl driver
*
* Copyright (c) 2017 Paul Cercueil <paul@crapouillou.net>
*
* License terms: GNU General Public License (GPL) version 2
*/
#include <linux/compiler.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/of_device.h>
#include <linux/of_platform.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 <linux/regmap.h>
#include <linux/slab.h>
#include "core.h"
#include "pinconf.h"
#include "pinmux.h"
#define JZ4740_GPIO_DATA 0x10
#define JZ4740_GPIO_PULL_DIS 0x30
#define JZ4740_GPIO_FUNC 0x40
#define JZ4740_GPIO_SELECT 0x50
#define JZ4740_GPIO_DIR 0x60
#define JZ4740_GPIO_TRIG 0x70
#define JZ4740_GPIO_FLAG 0x80
#define JZ4770_GPIO_INT 0x10
#define JZ4770_GPIO_MSK 0x20
#define JZ4770_GPIO_PAT1 0x30
#define JZ4770_GPIO_PAT0 0x40
#define JZ4770_GPIO_FLAG 0x50
#define JZ4770_GPIO_PEN 0x70
#define REG_SET(x) ((x) + 0x4)
#define REG_CLEAR(x) ((x) + 0x8)
#define PINS_PER_GPIO_CHIP 32
enum jz_version {
ID_JZ4740,
ID_JZ4770,
ID_JZ4780,
};
struct ingenic_chip_info {
unsigned int num_chips;
const struct group_desc *groups;
unsigned int num_groups;
const struct function_desc *functions;
unsigned int num_functions;
const u32 *pull_ups, *pull_downs;
};
struct ingenic_pinctrl {
struct device *dev;
struct regmap *map;
struct pinctrl_dev *pctl;
struct pinctrl_pin_desc *pdesc;
enum jz_version version;
const struct ingenic_chip_info *info;
};
static const u32 jz4740_pull_ups[4] = {
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
};
static const u32 jz4740_pull_downs[4] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000,
};
static int jz4740_mmc_1bit_pins[] = { 0x69, 0x68, 0x6a, };
static int jz4740_mmc_4bit_pins[] = { 0x6b, 0x6c, 0x6d, };
static int jz4740_uart0_data_pins[] = { 0x7a, 0x79, };
static int jz4740_uart0_hwflow_pins[] = { 0x7e, 0x7f, };
static int jz4740_uart1_data_pins[] = { 0x7e, 0x7f, };
static int jz4740_lcd_8bit_pins[] = {
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x52, 0x53, 0x54,
};
static int jz4740_lcd_16bit_pins[] = {
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x55,
};
static int jz4740_lcd_18bit_pins[] = { 0x50, 0x51, };
static int jz4740_lcd_18bit_tft_pins[] = { 0x56, 0x57, 0x31, 0x32, };
static int jz4740_nand_cs1_pins[] = { 0x39, };
static int jz4740_nand_cs2_pins[] = { 0x3a, };
static int jz4740_nand_cs3_pins[] = { 0x3b, };
static int jz4740_nand_cs4_pins[] = { 0x3c, };
static int jz4740_pwm_pwm0_pins[] = { 0x77, };
static int jz4740_pwm_pwm1_pins[] = { 0x78, };
static int jz4740_pwm_pwm2_pins[] = { 0x79, };
static int jz4740_pwm_pwm3_pins[] = { 0x7a, };
static int jz4740_pwm_pwm4_pins[] = { 0x7b, };
static int jz4740_pwm_pwm5_pins[] = { 0x7c, };
static int jz4740_pwm_pwm6_pins[] = { 0x7e, };
static int jz4740_pwm_pwm7_pins[] = { 0x7f, };
static int jz4740_mmc_1bit_funcs[] = { 0, 0, 0, };
static int jz4740_mmc_4bit_funcs[] = { 0, 0, 0, };
static int jz4740_uart0_data_funcs[] = { 1, 1, };
static int jz4740_uart0_hwflow_funcs[] = { 1, 1, };
static int jz4740_uart1_data_funcs[] = { 2, 2, };
static int jz4740_lcd_8bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
static int jz4740_lcd_16bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, };
static int jz4740_lcd_18bit_funcs[] = { 0, 0, };
static int jz4740_lcd_18bit_tft_funcs[] = { 0, 0, 0, 0, };
static int jz4740_nand_cs1_funcs[] = { 0, };
static int jz4740_nand_cs2_funcs[] = { 0, };
static int jz4740_nand_cs3_funcs[] = { 0, };
static int jz4740_nand_cs4_funcs[] = { 0, };
static int jz4740_pwm_pwm0_funcs[] = { 0, };
static int jz4740_pwm_pwm1_funcs[] = { 0, };
static int jz4740_pwm_pwm2_funcs[] = { 0, };
static int jz4740_pwm_pwm3_funcs[] = { 0, };
static int jz4740_pwm_pwm4_funcs[] = { 0, };
static int jz4740_pwm_pwm5_funcs[] = { 0, };
static int jz4740_pwm_pwm6_funcs[] = { 0, };
static int jz4740_pwm_pwm7_funcs[] = { 0, };
#define INGENIC_PIN_GROUP(name, id) \
{ \
name, \
id##_pins, \
ARRAY_SIZE(id##_pins), \
id##_funcs, \
}
static const struct group_desc jz4740_groups[] = {
INGENIC_PIN_GROUP("mmc-1bit", jz4740_mmc_1bit),
INGENIC_PIN_GROUP("mmc-4bit", jz4740_mmc_4bit),
INGENIC_PIN_GROUP("uart0-data", jz4740_uart0_data),
INGENIC_PIN_GROUP("uart0-hwflow", jz4740_uart0_hwflow),
INGENIC_PIN_GROUP("uart1-data", jz4740_uart1_data),
INGENIC_PIN_GROUP("lcd-8bit", jz4740_lcd_8bit),
INGENIC_PIN_GROUP("lcd-16bit", jz4740_lcd_16bit),
INGENIC_PIN_GROUP("lcd-18bit", jz4740_lcd_18bit),
INGENIC_PIN_GROUP("lcd-18bit-tft", jz4740_lcd_18bit_tft),
{ "lcd-no-pins", },
INGENIC_PIN_GROUP("nand-cs1", jz4740_nand_cs1),
INGENIC_PIN_GROUP("nand-cs2", jz4740_nand_cs2),
INGENIC_PIN_GROUP("nand-cs3", jz4740_nand_cs3),
INGENIC_PIN_GROUP("nand-cs4", jz4740_nand_cs4),
INGENIC_PIN_GROUP("pwm0", jz4740_pwm_pwm0),
INGENIC_PIN_GROUP("pwm1", jz4740_pwm_pwm1),
INGENIC_PIN_GROUP("pwm2", jz4740_pwm_pwm2),
INGENIC_PIN_GROUP("pwm3", jz4740_pwm_pwm3),
INGENIC_PIN_GROUP("pwm4", jz4740_pwm_pwm4),
INGENIC_PIN_GROUP("pwm5", jz4740_pwm_pwm5),
INGENIC_PIN_GROUP("pwm6", jz4740_pwm_pwm6),
INGENIC_PIN_GROUP("pwm7", jz4740_pwm_pwm7),
};
static const char *jz4740_mmc_groups[] = { "mmc-1bit", "mmc-4bit", };
static const char *jz4740_uart0_groups[] = { "uart0-data", "uart0-hwflow", };
static const char *jz4740_uart1_groups[] = { "uart1-data", };
static const char *jz4740_lcd_groups[] = {
"lcd-8bit", "lcd-16bit", "lcd-18bit", "lcd-18bit-tft", "lcd-no-pins",
};
static const char *jz4740_nand_groups[] = {
"nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4",
};
static const char *jz4740_pwm0_groups[] = { "pwm0", };
static const char *jz4740_pwm1_groups[] = { "pwm1", };
static const char *jz4740_pwm2_groups[] = { "pwm2", };
static const char *jz4740_pwm3_groups[] = { "pwm3", };
static const char *jz4740_pwm4_groups[] = { "pwm4", };
static const char *jz4740_pwm5_groups[] = { "pwm5", };
static const char *jz4740_pwm6_groups[] = { "pwm6", };
static const char *jz4740_pwm7_groups[] = { "pwm7", };
static const struct function_desc jz4740_functions[] = {
{ "mmc", jz4740_mmc_groups, ARRAY_SIZE(jz4740_mmc_groups), },
{ "uart0", jz4740_uart0_groups, ARRAY_SIZE(jz4740_uart0_groups), },
{ "uart1", jz4740_uart1_groups, ARRAY_SIZE(jz4740_uart1_groups), },
{ "lcd", jz4740_lcd_groups, ARRAY_SIZE(jz4740_lcd_groups), },
{ "nand", jz4740_nand_groups, ARRAY_SIZE(jz4740_nand_groups), },
{ "pwm0", jz4740_pwm0_groups, ARRAY_SIZE(jz4740_pwm0_groups), },
{ "pwm1", jz4740_pwm1_groups, ARRAY_SIZE(jz4740_pwm1_groups), },
{ "pwm2", jz4740_pwm2_groups, ARRAY_SIZE(jz4740_pwm2_groups), },
{ "pwm3", jz4740_pwm3_groups, ARRAY_SIZE(jz4740_pwm3_groups), },
{ "pwm4", jz4740_pwm4_groups, ARRAY_SIZE(jz4740_pwm4_groups), },
{ "pwm5", jz4740_pwm5_groups, ARRAY_SIZE(jz4740_pwm5_groups), },
{ "pwm6", jz4740_pwm6_groups, ARRAY_SIZE(jz4740_pwm6_groups), },
{ "pwm7", jz4740_pwm7_groups, ARRAY_SIZE(jz4740_pwm7_groups), },
};
static const struct ingenic_chip_info jz4740_chip_info = {
.num_chips = 4,
.groups = jz4740_groups,
.num_groups = ARRAY_SIZE(jz4740_groups),
.functions = jz4740_functions,
.num_functions = ARRAY_SIZE(jz4740_functions),
.pull_ups = jz4740_pull_ups,
.pull_downs = jz4740_pull_downs,
};
static const u32 jz4770_pull_ups[6] = {
0x3fffffff, 0xfff0030c, 0xffffffff, 0xffff4fff, 0xfffffb7c, 0xffa7f00f,
};
static const u32 jz4770_pull_downs[6] = {
0x00000000, 0x000f0c03, 0x00000000, 0x0000b000, 0x00000483, 0x00580ff0,
};
static int jz4770_uart0_data_pins[] = { 0xa0, 0xa3, };
static int jz4770_uart0_hwflow_pins[] = { 0xa1, 0xa2, };
static int jz4770_uart1_data_pins[] = { 0x7a, 0x7c, };
static int jz4770_uart1_hwflow_pins[] = { 0x7b, 0x7d, };
static int jz4770_uart2_data_pins[] = { 0x66, 0x67, };
static int jz4770_uart2_hwflow_pins[] = { 0x65, 0x64, };
static int jz4770_uart3_data_pins[] = { 0x6c, 0x85, };
static int jz4770_uart3_hwflow_pins[] = { 0x88, 0x89, };
static int jz4770_uart4_data_pins[] = { 0x54, 0x4a, };
static int jz4770_mmc0_8bit_a_pins[] = { 0x04, 0x05, 0x06, 0x07, 0x18, };
static int jz4770_mmc0_4bit_a_pins[] = { 0x15, 0x16, 0x17, };
static int jz4770_mmc0_1bit_a_pins[] = { 0x12, 0x13, 0x14, };
static int jz4770_mmc0_4bit_e_pins[] = { 0x95, 0x96, 0x97, };
static int jz4770_mmc0_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, };
static int jz4770_mmc1_4bit_d_pins[] = { 0x75, 0x76, 0x77, };
static int jz4770_mmc1_1bit_d_pins[] = { 0x78, 0x79, 0x74, };
static int jz4770_mmc1_4bit_e_pins[] = { 0x95, 0x96, 0x97, };
static int jz4770_mmc1_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, };
static int jz4770_nemc_data_pins[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
};
static int jz4770_nemc_cle_ale_pins[] = { 0x20, 0x21, };
static int jz4770_nemc_addr_pins[] = { 0x22, 0x23, 0x24, 0x25, };
static int jz4770_nemc_rd_we_pins[] = { 0x10, 0x11, };
static int jz4770_nemc_frd_fwe_pins[] = { 0x12, 0x13, };
static int jz4770_nemc_cs1_pins[] = { 0x15, };
static int jz4770_nemc_cs2_pins[] = { 0x16, };
static int jz4770_nemc_cs3_pins[] = { 0x17, };
static int jz4770_nemc_cs4_pins[] = { 0x18, };
static int jz4770_nemc_cs5_pins[] = { 0x19, };
static int jz4770_nemc_cs6_pins[] = { 0x1a, };
static int jz4770_i2c0_pins[] = { 0x6e, 0x6f, };
static int jz4770_i2c1_pins[] = { 0x8e, 0x8f, };
static int jz4770_i2c2_pins[] = { 0xb0, 0xb1, };
static int jz4770_i2c3_pins[] = { 0x6a, 0x6b, };
static int jz4770_i2c4_e_pins[] = { 0x8c, 0x8d, };
static int jz4770_i2c4_f_pins[] = { 0xb9, 0xb8, };
static int jz4770_cim_pins[] = {
0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
};
static int jz4770_lcd_32bit_pins[] = {
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x51,
};
static int jz4770_pwm_pwm0_pins[] = { 0x80, };
static int jz4770_pwm_pwm1_pins[] = { 0x81, };
static int jz4770_pwm_pwm2_pins[] = { 0x82, };
static int jz4770_pwm_pwm3_pins[] = { 0x83, };
static int jz4770_pwm_pwm4_pins[] = { 0x84, };
static int jz4770_pwm_pwm5_pins[] = { 0x85, };
static int jz4770_pwm_pwm6_pins[] = { 0x6a, };
static int jz4770_pwm_pwm7_pins[] = { 0x6b, };
static int jz4770_uart0_data_funcs[] = { 0, 0, };
static int jz4770_uart0_hwflow_funcs[] = { 0, 0, };
static int jz4770_uart1_data_funcs[] = { 0, 0, };
static int jz4770_uart1_hwflow_funcs[] = { 0, 0, };
static int jz4770_uart2_data_funcs[] = { 1, 1, };
static int jz4770_uart2_hwflow_funcs[] = { 1, 1, };
static int jz4770_uart3_data_funcs[] = { 0, 1, };
static int jz4770_uart3_hwflow_funcs[] = { 0, 0, };
static int jz4770_uart4_data_funcs[] = { 2, 2, };
static int jz4770_mmc0_8bit_a_funcs[] = { 1, 1, 1, 1, 1, };
static int jz4770_mmc0_4bit_a_funcs[] = { 1, 1, 1, };
static int jz4770_mmc0_1bit_a_funcs[] = { 1, 1, 0, };
static int jz4770_mmc0_4bit_e_funcs[] = { 0, 0, 0, };
static int jz4770_mmc0_1bit_e_funcs[] = { 0, 0, 0, };
static int jz4770_mmc1_4bit_d_funcs[] = { 0, 0, 0, };
static int jz4770_mmc1_1bit_d_funcs[] = { 0, 0, 0, };
static int jz4770_mmc1_4bit_e_funcs[] = { 1, 1, 1, };
static int jz4770_mmc1_1bit_e_funcs[] = { 1, 1, 1, };
static int jz4770_nemc_data_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, };
static int jz4770_nemc_cle_ale_funcs[] = { 0, 0, };
static int jz4770_nemc_addr_funcs[] = { 0, 0, 0, 0, };
static int jz4770_nemc_rd_we_funcs[] = { 0, 0, };
static int jz4770_nemc_frd_fwe_funcs[] = { 0, 0, };
static int jz4770_nemc_cs1_funcs[] = { 0, };
static int jz4770_nemc_cs2_funcs[] = { 0, };
static int jz4770_nemc_cs3_funcs[] = { 0, };
static int jz4770_nemc_cs4_funcs[] = { 0, };
static int jz4770_nemc_cs5_funcs[] = { 0, };
static int jz4770_nemc_cs6_funcs[] = { 0, };
static int jz4770_i2c0_funcs[] = { 0, 0, };
static int jz4770_i2c1_funcs[] = { 0, 0, };
static int jz4770_i2c2_funcs[] = { 2, 2, };
static int jz4770_i2c3_funcs[] = { 1, 1, };
static int jz4770_i2c4_e_funcs[] = { 1, 1, };
static int jz4770_i2c4_f_funcs[] = { 1, 1, };
static int jz4770_cim_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
static int jz4770_lcd_32bit_funcs[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0,
};
static int jz4770_pwm_pwm0_funcs[] = { 0, };
static int jz4770_pwm_pwm1_funcs[] = { 0, };
static int jz4770_pwm_pwm2_funcs[] = { 0, };
static int jz4770_pwm_pwm3_funcs[] = { 0, };
static int jz4770_pwm_pwm4_funcs[] = { 0, };
static int jz4770_pwm_pwm5_funcs[] = { 0, };
static int jz4770_pwm_pwm6_funcs[] = { 0, };
static int jz4770_pwm_pwm7_funcs[] = { 0, };
static const struct group_desc jz4770_groups[] = {
INGENIC_PIN_GROUP("uart0-data", jz4770_uart0_data),
INGENIC_PIN_GROUP("uart0-hwflow", jz4770_uart0_hwflow),
INGENIC_PIN_GROUP("uart1-data", jz4770_uart1_data),
INGENIC_PIN_GROUP("uart1-hwflow", jz4770_uart1_hwflow),
INGENIC_PIN_GROUP("uart2-data", jz4770_uart2_data),
INGENIC_PIN_GROUP("uart2-hwflow", jz4770_uart2_hwflow),
INGENIC_PIN_GROUP("uart3-data", jz4770_uart3_data),
INGENIC_PIN_GROUP("uart3-hwflow", jz4770_uart3_hwflow),
INGENIC_PIN_GROUP("uart4-data", jz4770_uart4_data),
INGENIC_PIN_GROUP("mmc0-8bit-a", jz4770_mmc0_8bit_a),
INGENIC_PIN_GROUP("mmc0-4bit-a", jz4770_mmc0_4bit_a),
INGENIC_PIN_GROUP("mmc0-1bit-a", jz4770_mmc0_1bit_a),
INGENIC_PIN_GROUP("mmc0-4bit-e", jz4770_mmc0_4bit_e),
INGENIC_PIN_GROUP("mmc0-1bit-e", jz4770_mmc0_1bit_e),
INGENIC_PIN_GROUP("mmc1-4bit-d", jz4770_mmc1_4bit_d),
INGENIC_PIN_GROUP("mmc1-1bit-d", jz4770_mmc1_1bit_d),
INGENIC_PIN_GROUP("mmc1-4bit-e", jz4770_mmc1_4bit_e),
INGENIC_PIN_GROUP("mmc1-1bit-e", jz4770_mmc1_1bit_e),
INGENIC_PIN_GROUP("nemc-data", jz4770_nemc_data),
INGENIC_PIN_GROUP("nemc-cle-ale", jz4770_nemc_cle_ale),
INGENIC_PIN_GROUP("nemc-addr", jz4770_nemc_addr),
INGENIC_PIN_GROUP("nemc-rd-we", jz4770_nemc_rd_we),
INGENIC_PIN_GROUP("nemc-frd-fwe", jz4770_nemc_frd_fwe),
INGENIC_PIN_GROUP("nemc-cs1", jz4770_nemc_cs1),
INGENIC_PIN_GROUP("nemc-cs2", jz4770_nemc_cs2),
INGENIC_PIN_GROUP("nemc-cs3", jz4770_nemc_cs3),
INGENIC_PIN_GROUP("nemc-cs4", jz4770_nemc_cs4),
INGENIC_PIN_GROUP("nemc-cs5", jz4770_nemc_cs5),
INGENIC_PIN_GROUP("nemc-cs6", jz4770_nemc_cs6),
INGENIC_PIN_GROUP("i2c0-data", jz4770_i2c0),
INGENIC_PIN_GROUP("i2c1-data", jz4770_i2c1),
INGENIC_PIN_GROUP("i2c2-data", jz4770_i2c2),
INGENIC_PIN_GROUP("i2c3-data", jz4770_i2c3),
INGENIC_PIN_GROUP("i2c4-data-e", jz4770_i2c4_e),
INGENIC_PIN_GROUP("i2c4-data-f", jz4770_i2c4_f),
INGENIC_PIN_GROUP("cim-data", jz4770_cim),
INGENIC_PIN_GROUP("lcd-32bit", jz4770_lcd_32bit),
{ "lcd-no-pins", },
INGENIC_PIN_GROUP("pwm0", jz4770_pwm_pwm0),
INGENIC_PIN_GROUP("pwm1", jz4770_pwm_pwm1),
INGENIC_PIN_GROUP("pwm2", jz4770_pwm_pwm2),
INGENIC_PIN_GROUP("pwm3", jz4770_pwm_pwm3),
INGENIC_PIN_GROUP("pwm4", jz4770_pwm_pwm4),
INGENIC_PIN_GROUP("pwm5", jz4770_pwm_pwm5),
INGENIC_PIN_GROUP("pwm6", jz4770_pwm_pwm6),
INGENIC_PIN_GROUP("pwm7", jz4770_pwm_pwm7),
};
static const char *jz4770_uart0_groups[] = { "uart0-data", "uart0-hwflow", };
static const char *jz4770_uart1_groups[] = { "uart1-data", "uart1-hwflow", };
static const char *jz4770_uart2_groups[] = { "uart2-data", "uart2-hwflow", };
static const char *jz4770_uart3_groups[] = { "uart3-data", "uart3-hwflow", };
static const char *jz4770_uart4_groups[] = { "uart4-data", };
static const char *jz4770_mmc0_groups[] = {
"mmc0-8bit-a", "mmc0-4bit-a", "mmc0-1bit-a",
"mmc0-1bit-e", "mmc0-4bit-e",
};
static const char *jz4770_mmc1_groups[] = {
"mmc1-1bit-d", "mmc1-4bit-d", "mmc1-1bit-e", "mmc1-4bit-e",
};
static const char *jz4770_nemc_groups[] = {
"nemc-data", "nemc-cle-ale", "nemc-addr", "nemc-rd-we", "nemc-frd-fwe",
};
static const char *jz4770_cs1_groups[] = { "nemc-cs1", };
static const char *jz4770_cs6_groups[] = { "nemc-cs6", };
static const char *jz4770_i2c0_groups[] = { "i2c0-data", };
static const char *jz4770_i2c1_groups[] = { "i2c1-data", };
static const char *jz4770_i2c2_groups[] = { "i2c2-data", };
static const char *jz4770_i2c3_groups[] = { "i2c3-data", };
static const char *jz4770_i2c4_groups[] = { "i2c4-data-e", "i2c4-data-f", };
static const char *jz4770_cim_groups[] = { "cim-data", };
static const char *jz4770_lcd_groups[] = { "lcd-32bit", "lcd-no-pins", };
static const char *jz4770_pwm0_groups[] = { "pwm0", };
static const char *jz4770_pwm1_groups[] = { "pwm1", };
static const char *jz4770_pwm2_groups[] = { "pwm2", };
static const char *jz4770_pwm3_groups[] = { "pwm3", };
static const char *jz4770_pwm4_groups[] = { "pwm4", };
static const char *jz4770_pwm5_groups[] = { "pwm5", };
static const char *jz4770_pwm6_groups[] = { "pwm6", };
static const char *jz4770_pwm7_groups[] = { "pwm7", };
static const struct function_desc jz4770_functions[] = {
{ "uart0", jz4770_uart0_groups, ARRAY_SIZE(jz4770_uart0_groups), },
{ "uart1", jz4770_uart1_groups, ARRAY_SIZE(jz4770_uart1_groups), },
{ "uart2", jz4770_uart2_groups, ARRAY_SIZE(jz4770_uart2_groups), },
{ "uart3", jz4770_uart3_groups, ARRAY_SIZE(jz4770_uart3_groups), },
{ "uart4", jz4770_uart4_groups, ARRAY_SIZE(jz4770_uart4_groups), },
{ "mmc0", jz4770_mmc0_groups, ARRAY_SIZE(jz4770_mmc0_groups), },
{ "mmc1", jz4770_mmc1_groups, ARRAY_SIZE(jz4770_mmc1_groups), },
{ "nemc", jz4770_nemc_groups, ARRAY_SIZE(jz4770_nemc_groups), },
{ "nemc-cs1", jz4770_cs1_groups, ARRAY_SIZE(jz4770_cs1_groups), },
{ "nemc-cs6", jz4770_cs6_groups, ARRAY_SIZE(jz4770_cs6_groups), },
{ "i2c0", jz4770_i2c0_groups, ARRAY_SIZE(jz4770_i2c0_groups), },
{ "i2c1", jz4770_i2c1_groups, ARRAY_SIZE(jz4770_i2c1_groups), },
{ "i2c2", jz4770_i2c2_groups, ARRAY_SIZE(jz4770_i2c2_groups), },
{ "i2c3", jz4770_i2c3_groups, ARRAY_SIZE(jz4770_i2c3_groups), },
{ "i2c4", jz4770_i2c4_groups, ARRAY_SIZE(jz4770_i2c4_groups), },
{ "cim", jz4770_cim_groups, ARRAY_SIZE(jz4770_cim_groups), },
{ "lcd", jz4770_lcd_groups, ARRAY_SIZE(jz4770_lcd_groups), },
{ "pwm0", jz4770_pwm0_groups, ARRAY_SIZE(jz4770_pwm0_groups), },
{ "pwm1", jz4770_pwm1_groups, ARRAY_SIZE(jz4770_pwm1_groups), },
{ "pwm2", jz4770_pwm2_groups, ARRAY_SIZE(jz4770_pwm2_groups), },
{ "pwm3", jz4770_pwm3_groups, ARRAY_SIZE(jz4770_pwm3_groups), },
{ "pwm4", jz4770_pwm4_groups, ARRAY_SIZE(jz4770_pwm4_groups), },
{ "pwm5", jz4770_pwm5_groups, ARRAY_SIZE(jz4770_pwm5_groups), },
{ "pwm6", jz4770_pwm6_groups, ARRAY_SIZE(jz4770_pwm6_groups), },
{ "pwm7", jz4770_pwm7_groups, ARRAY_SIZE(jz4770_pwm7_groups), },
};
static const struct ingenic_chip_info jz4770_chip_info = {
.num_chips = 6,
.groups = jz4770_groups,
.num_groups = ARRAY_SIZE(jz4770_groups),
.functions = jz4770_functions,
.num_functions = ARRAY_SIZE(jz4770_functions),
.pull_ups = jz4770_pull_ups,
.pull_downs = jz4770_pull_downs,
};
static inline void ingenic_config_pin(struct ingenic_pinctrl *jzpc,
unsigned int pin, u8 reg, bool set)
{
unsigned int idx = pin % PINS_PER_GPIO_CHIP;
unsigned int offt = pin / PINS_PER_GPIO_CHIP;
regmap_write(jzpc->map, offt * 0x100 +
(set ? REG_SET(reg) : REG_CLEAR(reg)), BIT(idx));
}
static inline bool ingenic_get_pin_config(struct ingenic_pinctrl *jzpc,
unsigned int pin, u8 reg)
{
unsigned int idx = pin % PINS_PER_GPIO_CHIP;
unsigned int offt = pin / PINS_PER_GPIO_CHIP;
unsigned int val;
regmap_read(jzpc->map, offt * 0x100 + reg, &val);
return val & BIT(idx);
}
static struct pinctrl_ops ingenic_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 int ingenic_pinmux_set_pin_fn(struct ingenic_pinctrl *jzpc,
int pin, int func)
{
unsigned int idx = pin % PINS_PER_GPIO_CHIP;
unsigned int offt = pin / PINS_PER_GPIO_CHIP;
dev_dbg(jzpc->dev, "set pin P%c%u to function %u\n",
'A' + offt, idx, func);
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, JZ4770_GPIO_PAT1, func & 0x2);
ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT0, func & 0x1);
} else {
ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, true);
ingenic_config_pin(jzpc, pin, JZ4740_GPIO_TRIG, func & 0x2);
ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func > 0);
}
return 0;
}
static int ingenic_pinmux_set_mux(struct pinctrl_dev *pctldev,
unsigned int selector, unsigned int group)
{
struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
struct function_desc *func;
struct group_desc *grp;
unsigned 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++) {
int *pin_modes = grp->data;
ingenic_pinmux_set_pin_fn(jzpc, grp->pins[i], pin_modes[i]);
}
return 0;
}
static int ingenic_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int pin, bool input)
{
struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
unsigned int idx = pin % PINS_PER_GPIO_CHIP;
unsigned int offt = pin / PINS_PER_GPIO_CHIP;
dev_dbg(pctldev->dev, "set pin P%c%u to %sput\n",
'A' + offt, idx, input ? "in" : "out");
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, JZ4770_GPIO_PAT1, input);
} else {
ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, false);
ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DIR, input);
ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, false);
}
return 0;
}
static struct pinmux_ops ingenic_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 = ingenic_pinmux_set_mux,
.gpio_set_direction = ingenic_pinmux_gpio_set_direction,
};
static int ingenic_pinconf_get(struct pinctrl_dev *pctldev,
unsigned int pin, unsigned long *config)
{
struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param = pinconf_to_config_param(*config);
unsigned int idx = pin % PINS_PER_GPIO_CHIP;
unsigned int offt = pin / PINS_PER_GPIO_CHIP;
bool pull;
if (jzpc->version >= ID_JZ4770)
pull = !ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PEN);
else
pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS);
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
if (pull)
return -EINVAL;
break;
case PIN_CONFIG_BIAS_PULL_UP:
if (!pull || !(jzpc->info->pull_ups[offt] & BIT(idx)))
return -EINVAL;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
if (!pull || !(jzpc->info->pull_downs[offt] & BIT(idx)))
return -EINVAL;
break;
default:
return -ENOTSUPP;
}
*config = pinconf_to_config_packed(param, 1);
return 0;
}
static void ingenic_set_bias(struct ingenic_pinctrl *jzpc,
unsigned int pin, bool enabled)
{
if (jzpc->version >= ID_JZ4770)
ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PEN, !enabled);
else
ingenic_config_pin(jzpc, pin, JZ4740_GPIO_PULL_DIS, !enabled);
}
static int ingenic_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned int num_configs)
{
struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
unsigned int idx = pin % PINS_PER_GPIO_CHIP;
unsigned int offt = pin / PINS_PER_GPIO_CHIP;
unsigned int cfg;
for (cfg = 0; cfg < num_configs; cfg++) {
switch (pinconf_to_config_param(configs[cfg])) {
case PIN_CONFIG_BIAS_DISABLE:
case PIN_CONFIG_BIAS_PULL_UP:
case PIN_CONFIG_BIAS_PULL_DOWN:
continue;
default:
return -ENOTSUPP;
}
}
for (cfg = 0; cfg < num_configs; cfg++) {
switch (pinconf_to_config_param(configs[cfg])) {
case PIN_CONFIG_BIAS_DISABLE:
dev_dbg(jzpc->dev, "disable pull-over for pin P%c%u\n",
'A' + offt, idx);
ingenic_set_bias(jzpc, pin, false);
break;
case PIN_CONFIG_BIAS_PULL_UP:
if (!(jzpc->info->pull_ups[offt] & BIT(idx)))
return -EINVAL;
dev_dbg(jzpc->dev, "set pull-up for pin P%c%u\n",
'A' + offt, idx);
ingenic_set_bias(jzpc, pin, true);
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
if (!(jzpc->info->pull_downs[offt] & BIT(idx)))
return -EINVAL;
dev_dbg(jzpc->dev, "set pull-down for pin P%c%u\n",
'A' + offt, idx);
ingenic_set_bias(jzpc, pin, true);
break;
default:
unreachable();
}
}
return 0;
}
static int ingenic_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 (ingenic_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 ingenic_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 = ingenic_pinconf_set(pctldev,
pins[i], configs, num_configs);
if (ret)
return ret;
}
return 0;
}
static struct pinconf_ops ingenic_confops = {
.is_generic = true,
.pin_config_get = ingenic_pinconf_get,
.pin_config_set = ingenic_pinconf_set,
.pin_config_group_get = ingenic_pinconf_group_get,
.pin_config_group_set = ingenic_pinconf_group_set,
};
static const struct regmap_config ingenic_pinctrl_regmap_config = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
};
static const struct of_device_id ingenic_pinctrl_of_match[] = {
{ .compatible = "ingenic,jz4740-pinctrl", .data = (void *) ID_JZ4740 },
{ .compatible = "ingenic,jz4770-pinctrl", .data = (void *) ID_JZ4770 },
{ .compatible = "ingenic,jz4780-pinctrl", .data = (void *) ID_JZ4780 },
{},
};
int ingenic_pinctrl_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct ingenic_pinctrl *jzpc;
struct pinctrl_desc *pctl_desc;
void __iomem *base;
const struct platform_device_id *id = platform_get_device_id(pdev);
const struct of_device_id *of_id = of_match_device(
ingenic_pinctrl_of_match, dev);
const struct ingenic_chip_info *chip_info;
unsigned int i;
int err;
jzpc = devm_kzalloc(dev, sizeof(*jzpc), GFP_KERNEL);
if (!jzpc)
return -ENOMEM;
base = devm_ioremap_resource(dev,
platform_get_resource(pdev, IORESOURCE_MEM, 0));
if (IS_ERR(base)) {
dev_err(dev, "Failed to ioremap registers\n");
return PTR_ERR(base);
}
jzpc->map = devm_regmap_init_mmio(dev, base,
&ingenic_pinctrl_regmap_config);
if (IS_ERR(jzpc->map)) {
dev_err(dev, "Failed to create regmap\n");
return PTR_ERR(jzpc->map);
}
jzpc->dev = dev;
if (of_id)
jzpc->version = (enum jz_version)of_id->data;
else
jzpc->version = (enum jz_version)id->driver_data;
if (jzpc->version >= ID_JZ4770)
chip_info = &jz4770_chip_info;
else
chip_info = &jz4740_chip_info;
jzpc->info = chip_info;
pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl_desc), GFP_KERNEL);
if (!pctl_desc)
return -ENOMEM;
/* fill in pinctrl_desc structure */
pctl_desc->name = dev_name(dev);
pctl_desc->owner = THIS_MODULE;
pctl_desc->pctlops = &ingenic_pctlops;
pctl_desc->pmxops = &ingenic_pmxops;
pctl_desc->confops = &ingenic_confops;
pctl_desc->npins = chip_info->num_chips * PINS_PER_GPIO_CHIP;
pctl_desc->pins = jzpc->pdesc = devm_kzalloc(&pdev->dev,
sizeof(*jzpc->pdesc) * pctl_desc->npins, GFP_KERNEL);
if (!jzpc->pdesc)
return -ENOMEM;
for (i = 0; i < pctl_desc->npins; i++) {
jzpc->pdesc[i].number = i;
jzpc->pdesc[i].name = kasprintf(GFP_KERNEL, "P%c%d",
'A' + (i / PINS_PER_GPIO_CHIP),
i % PINS_PER_GPIO_CHIP);
}
jzpc->pctl = devm_pinctrl_register(dev, pctl_desc, jzpc);
if (IS_ERR(jzpc->pctl)) {
dev_err(dev, "Failed to register pinctrl\n");
return PTR_ERR(jzpc->pctl);
}
for (i = 0; i < chip_info->num_groups; i++) {
const struct group_desc *group = &chip_info->groups[i];
err = pinctrl_generic_add_group(jzpc->pctl, group->name,
group->pins, group->num_pins, group->data);
if (err) {
dev_err(dev, "Failed to register group %s\n",
group->name);
return err;
}
}
for (i = 0; i < chip_info->num_functions; i++) {
const struct function_desc *func = &chip_info->functions[i];
err = pinmux_generic_add_function(jzpc->pctl, func->name,
func->group_names, func->num_group_names,
func->data);
if (err) {
dev_err(dev, "Failed to register function %s\n",
func->name);
return err;
}
}
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;
}
}
return 0;
}
static const struct platform_device_id ingenic_pinctrl_ids[] = {
{ "jz4740-pinctrl", ID_JZ4740 },
{ "jz4770-pinctrl", ID_JZ4770 },
{ "jz4780-pinctrl", ID_JZ4780 },
{},
};
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);
}
postcore_initcall(ingenic_pinctrl_drv_register);

View File

@ -1,14 +1,4 @@
/*
* MCP23S08 SPI/I2C GPIO gpio expander driver
*
* The inputs and outputs of the mcp23s08, mcp23s17, mcp23008 and mcp23017 are
* supported.
* For the I2C versions of the chips (mcp23008 and mcp23017) generation of
* interrupts is also supported.
* The hardware of the SPI versions of the chips (mcp23s08 and mcp23s17) is
* also capable of generating interrupts, but the linux driver does not
* support that yet.
*/
/* MCP23S08 SPI/I2C GPIO driver */
#include <linux/kernel.h>
#include <linux/device.h>
@ -21,11 +11,13 @@
#include <linux/slab.h>
#include <asm/byteorder.h>
#include <linux/interrupt.h>
#include <linux/of_irq.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
/**
/*
* MCP types supported by driver
*/
#define MCP_TYPE_S08 0
@ -34,6 +26,8 @@
#define MCP_TYPE_017 3
#define MCP_TYPE_S18 4
#define MCP_MAX_DEV_PER_CS 8
/* Registers are all 8 bits wide.
*
* The mcp23s17 has twice as many bits, and can be configured to work
@ -64,19 +58,52 @@ struct mcp23s08 {
bool irq_active_high;
bool reg_shift;
u16 cache[11];
u16 irq_rise;
u16 irq_fall;
int irq;
bool irq_controller;
/* lock protects the cached values */
int cached_gpio;
/* lock protects regmap access with bypass/cache flags */
struct mutex lock;
struct mutex irq_lock;
struct gpio_chip chip;
struct regmap *regmap;
struct device *dev;
struct pinctrl_dev *pctldev;
struct pinctrl_desc pinctrl_desc;
};
static const struct reg_default mcp23x08_defaults[] = {
{.reg = MCP_IODIR, .def = 0xff},
{.reg = MCP_IPOL, .def = 0x00},
{.reg = MCP_GPINTEN, .def = 0x00},
{.reg = MCP_DEFVAL, .def = 0x00},
{.reg = MCP_INTCON, .def = 0x00},
{.reg = MCP_IOCON, .def = 0x00},
{.reg = MCP_GPPU, .def = 0x00},
{.reg = MCP_OLAT, .def = 0x00},
};
static const struct regmap_range mcp23x08_volatile_range = {
.range_min = MCP_INTF,
.range_max = MCP_GPIO,
};
static const struct regmap_access_table mcp23x08_volatile_table = {
.yes_ranges = &mcp23x08_volatile_range,
.n_yes_ranges = 1,
};
static const struct regmap_range mcp23x08_precious_range = {
.range_min = MCP_GPIO,
.range_max = MCP_GPIO,
};
static const struct regmap_access_table mcp23x08_precious_table = {
.yes_ranges = &mcp23x08_precious_range,
.n_yes_ranges = 1,
};
static const struct regmap_config mcp23x08_regmap = {
@ -84,18 +111,203 @@ static const struct regmap_config mcp23x08_regmap = {
.val_bits = 8,
.reg_stride = 1,
.volatile_table = &mcp23x08_volatile_table,
.precious_table = &mcp23x08_precious_table,
.reg_defaults = mcp23x08_defaults,
.num_reg_defaults = ARRAY_SIZE(mcp23x08_defaults),
.cache_type = REGCACHE_FLAT,
.max_register = MCP_OLAT,
};
static const struct reg_default mcp23x16_defaults[] = {
{.reg = MCP_IODIR << 1, .def = 0xffff},
{.reg = MCP_IPOL << 1, .def = 0x0000},
{.reg = MCP_GPINTEN << 1, .def = 0x0000},
{.reg = MCP_DEFVAL << 1, .def = 0x0000},
{.reg = MCP_INTCON << 1, .def = 0x0000},
{.reg = MCP_IOCON << 1, .def = 0x0000},
{.reg = MCP_GPPU << 1, .def = 0x0000},
{.reg = MCP_OLAT << 1, .def = 0x0000},
};
static const struct regmap_range mcp23x16_volatile_range = {
.range_min = MCP_INTF << 1,
.range_max = MCP_GPIO << 1,
};
static const struct regmap_access_table mcp23x16_volatile_table = {
.yes_ranges = &mcp23x16_volatile_range,
.n_yes_ranges = 1,
};
static const struct regmap_range mcp23x16_precious_range = {
.range_min = MCP_GPIO << 1,
.range_max = MCP_GPIO << 1,
};
static const struct regmap_access_table mcp23x16_precious_table = {
.yes_ranges = &mcp23x16_precious_range,
.n_yes_ranges = 1,
};
static const struct regmap_config mcp23x17_regmap = {
.reg_bits = 8,
.val_bits = 16,
.reg_stride = 2,
.max_register = MCP_OLAT << 1,
.volatile_table = &mcp23x16_volatile_table,
.precious_table = &mcp23x16_precious_table,
.reg_defaults = mcp23x16_defaults,
.num_reg_defaults = ARRAY_SIZE(mcp23x16_defaults),
.cache_type = REGCACHE_FLAT,
.val_format_endian = REGMAP_ENDIAN_LITTLE,
};
static int mcp_read(struct mcp23s08 *mcp, unsigned int reg, unsigned int *val)
{
return regmap_read(mcp->regmap, reg << mcp->reg_shift, val);
}
static int mcp_write(struct mcp23s08 *mcp, unsigned int reg, unsigned int val)
{
return regmap_write(mcp->regmap, reg << mcp->reg_shift, val);
}
static int mcp_set_mask(struct mcp23s08 *mcp, unsigned int reg,
unsigned int mask, bool enabled)
{
u16 val = enabled ? 0xffff : 0x0000;
return regmap_update_bits(mcp->regmap, reg << mcp->reg_shift,
mask, val);
}
static int mcp_set_bit(struct mcp23s08 *mcp, unsigned int reg,
unsigned int pin, bool enabled)
{
u16 mask = BIT(pin);
return mcp_set_mask(mcp, reg, mask, enabled);
}
static const struct pinctrl_pin_desc mcp23x08_pins[] = {
PINCTRL_PIN(0, "gpio0"),
PINCTRL_PIN(1, "gpio1"),
PINCTRL_PIN(2, "gpio2"),
PINCTRL_PIN(3, "gpio3"),
PINCTRL_PIN(4, "gpio4"),
PINCTRL_PIN(5, "gpio5"),
PINCTRL_PIN(6, "gpio6"),
PINCTRL_PIN(7, "gpio7"),
};
static const struct pinctrl_pin_desc mcp23x17_pins[] = {
PINCTRL_PIN(0, "gpio0"),
PINCTRL_PIN(1, "gpio1"),
PINCTRL_PIN(2, "gpio2"),
PINCTRL_PIN(3, "gpio3"),
PINCTRL_PIN(4, "gpio4"),
PINCTRL_PIN(5, "gpio5"),
PINCTRL_PIN(6, "gpio6"),
PINCTRL_PIN(7, "gpio7"),
PINCTRL_PIN(8, "gpio8"),
PINCTRL_PIN(9, "gpio9"),
PINCTRL_PIN(10, "gpio10"),
PINCTRL_PIN(11, "gpio11"),
PINCTRL_PIN(12, "gpio12"),
PINCTRL_PIN(13, "gpio13"),
PINCTRL_PIN(14, "gpio14"),
PINCTRL_PIN(15, "gpio15"),
};
static int mcp_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
{
return 0;
}
static const char *mcp_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
unsigned int group)
{
return NULL;
}
static int mcp_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
unsigned int group,
const unsigned int **pins,
unsigned int *num_pins)
{
return -ENOTSUPP;
}
static const struct pinctrl_ops mcp_pinctrl_ops = {
.get_groups_count = mcp_pinctrl_get_groups_count,
.get_group_name = mcp_pinctrl_get_group_name,
.get_group_pins = mcp_pinctrl_get_group_pins,
#ifdef CONFIG_OF
.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
.dt_free_map = pinconf_generic_dt_free_map,
#endif
};
static int mcp_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *config)
{
struct mcp23s08 *mcp = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param = pinconf_to_config_param(*config);
unsigned int data, status;
int ret;
switch (param) {
case PIN_CONFIG_BIAS_PULL_UP:
ret = mcp_read(mcp, MCP_GPPU, &data);
if (ret < 0)
return ret;
status = (data & BIT(pin)) ? 1 : 0;
break;
default:
dev_err(mcp->dev, "Invalid config param %04x\n", param);
return -ENOTSUPP;
}
*config = 0;
return status ? 0 : -EINVAL;
}
static int mcp_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned int num_configs)
{
struct mcp23s08 *mcp = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param;
u32 arg, mask;
u16 val;
int ret = 0;
int i;
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:
val = arg ? 0xFFFF : 0x0000;
mask = BIT(pin);
ret = mcp_set_bit(mcp, MCP_GPPU, pin, arg);
break;
default:
dev_err(mcp->dev, "Invalid config param %04x\n", param);
return -ENOTSUPP;
}
}
return ret;
}
static const struct pinconf_ops mcp_pinconf_ops = {
.pin_config_get = mcp_pinconf_get,
.pin_config_set = mcp_pinconf_set,
.is_generic = true,
};
/*----------------------------------------------------------------------*/
#ifdef CONFIG_SPI_MASTER
@ -158,30 +370,6 @@ static const struct regmap_bus mcp23sxx_spi_regmap = {
#endif /* CONFIG_SPI_MASTER */
static int mcp_read(struct mcp23s08 *mcp, unsigned int reg, unsigned int *val)
{
return regmap_read(mcp->regmap, reg << mcp->reg_shift, val);
}
static int mcp_write(struct mcp23s08 *mcp, unsigned int reg, unsigned int val)
{
return regmap_write(mcp->regmap, reg << mcp->reg_shift, val);
}
static int mcp_update_cache(struct mcp23s08 *mcp)
{
int ret, reg, i;
for (i = 0; i < ARRAY_SIZE(mcp->cache); i++) {
ret = mcp_read(mcp, i, &reg);
if (ret < 0)
return ret;
mcp->cache[i] = reg;
}
return 0;
}
/*----------------------------------------------------------------------*/
/* A given spi_device can represent up to eight mcp23sxx chips
@ -202,9 +390,9 @@ static int mcp23s08_direction_input(struct gpio_chip *chip, unsigned offset)
int status;
mutex_lock(&mcp->lock);
mcp->cache[MCP_IODIR] |= (1 << offset);
status = mcp_write(mcp, MCP_IODIR, mcp->cache[MCP_IODIR]);
status = mcp_set_bit(mcp, MCP_IODIR, offset, true);
mutex_unlock(&mcp->lock);
return status;
}
@ -219,33 +407,27 @@ static int mcp23s08_get(struct gpio_chip *chip, unsigned offset)
ret = mcp_read(mcp, MCP_GPIO, &status);
if (ret < 0)
status = 0;
else {
mcp->cache[MCP_GPIO] = status;
else
status = !!(status & (1 << offset));
}
mcp->cached_gpio = status;
mutex_unlock(&mcp->lock);
return status;
}
static int __mcp23s08_set(struct mcp23s08 *mcp, unsigned mask, int value)
static int __mcp23s08_set(struct mcp23s08 *mcp, unsigned mask, bool value)
{
unsigned olat = mcp->cache[MCP_OLAT];
if (value)
olat |= mask;
else
olat &= ~mask;
mcp->cache[MCP_OLAT] = olat;
return mcp_write(mcp, MCP_OLAT, olat);
return mcp_set_mask(mcp, MCP_OLAT, mask, value);
}
static void mcp23s08_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct mcp23s08 *mcp = gpiochip_get_data(chip);
unsigned mask = 1 << offset;
unsigned mask = BIT(offset);
mutex_lock(&mcp->lock);
__mcp23s08_set(mcp, mask, value);
__mcp23s08_set(mcp, mask, !!value);
mutex_unlock(&mcp->lock);
}
@ -253,14 +435,13 @@ static int
mcp23s08_direction_output(struct gpio_chip *chip, unsigned offset, int value)
{
struct mcp23s08 *mcp = gpiochip_get_data(chip);
unsigned mask = 1 << offset;
unsigned mask = BIT(offset);
int status;
mutex_lock(&mcp->lock);
status = __mcp23s08_set(mcp, mask, value);
if (status == 0) {
mcp->cache[MCP_IODIR] &= ~mask;
status = mcp_write(mcp, MCP_IODIR, mcp->cache[MCP_IODIR]);
status = mcp_set_mask(mcp, MCP_IODIR, mask, false);
}
mutex_unlock(&mcp->lock);
return status;
@ -270,7 +451,7 @@ mcp23s08_direction_output(struct gpio_chip *chip, unsigned offset, int value)
static irqreturn_t mcp23s08_irq(int irq, void *data)
{
struct mcp23s08 *mcp = data;
int intcap, intf, i, gpio, gpio_orig, intcap_mask;
int intcap, intcon, intf, i, gpio, gpio_orig, intcap_mask, defval;
unsigned int child_irq;
bool intf_set, intcap_changed, gpio_bit_changed,
defval_changed, gpio_set;
@ -281,25 +462,31 @@ static irqreturn_t mcp23s08_irq(int irq, void *data)
return IRQ_HANDLED;
}
mcp->cache[MCP_INTF] = intf;
if (mcp_read(mcp, MCP_INTCAP, &intcap) < 0) {
mutex_unlock(&mcp->lock);
return IRQ_HANDLED;
}
mcp->cache[MCP_INTCAP] = intcap;
if (mcp_read(mcp, MCP_INTCON, &intcon) < 0) {
mutex_unlock(&mcp->lock);
return IRQ_HANDLED;
}
if (mcp_read(mcp, MCP_DEFVAL, &defval) < 0) {
mutex_unlock(&mcp->lock);
return IRQ_HANDLED;
}
/* This clears the interrupt(configurable on S18) */
if (mcp_read(mcp, MCP_GPIO, &gpio) < 0) {
mutex_unlock(&mcp->lock);
return IRQ_HANDLED;
}
gpio_orig = mcp->cache[MCP_GPIO];
mcp->cache[MCP_GPIO] = gpio;
gpio_orig = mcp->cached_gpio;
mcp->cached_gpio = gpio;
mutex_unlock(&mcp->lock);
if (mcp->cache[MCP_INTF] == 0) {
if (intf == 0) {
/* There is no interrupt pending */
return IRQ_HANDLED;
}
@ -327,7 +514,7 @@ static irqreturn_t mcp23s08_irq(int irq, void *data)
* to see if the input has changed.
*/
intf_set = BIT(i) & mcp->cache[MCP_INTF];
intf_set = intf & BIT(i);
if (i < 8 && intf_set)
intcap_mask = 0x00FF;
else if (i >= 8 && intf_set)
@ -336,14 +523,14 @@ static irqreturn_t mcp23s08_irq(int irq, void *data)
intcap_mask = 0x00;
intcap_changed = (intcap_mask &
(BIT(i) & mcp->cache[MCP_INTCAP])) !=
(intcap & BIT(i))) !=
(intcap_mask & (BIT(i) & gpio_orig));
gpio_set = BIT(i) & mcp->cache[MCP_GPIO];
gpio_set = BIT(i) & gpio;
gpio_bit_changed = (BIT(i) & gpio_orig) !=
(BIT(i) & mcp->cache[MCP_GPIO]);
defval_changed = (BIT(i) & mcp->cache[MCP_INTCON]) &&
((BIT(i) & mcp->cache[MCP_GPIO]) !=
(BIT(i) & mcp->cache[MCP_DEFVAL]));
(BIT(i) & gpio);
defval_changed = (BIT(i) & intcon) &&
((BIT(i) & gpio) !=
(BIT(i) & defval));
if (((gpio_bit_changed || intcap_changed) &&
(BIT(i) & mcp->irq_rise) && gpio_set) ||
@ -364,7 +551,7 @@ static void mcp23s08_irq_mask(struct irq_data *data)
struct mcp23s08 *mcp = gpiochip_get_data(gc);
unsigned int pos = data->hwirq;
mcp->cache[MCP_GPINTEN] &= ~BIT(pos);
mcp_set_bit(mcp, MCP_GPINTEN, pos, false);
}
static void mcp23s08_irq_unmask(struct irq_data *data)
@ -373,7 +560,7 @@ static void mcp23s08_irq_unmask(struct irq_data *data)
struct mcp23s08 *mcp = gpiochip_get_data(gc);
unsigned int pos = data->hwirq;
mcp->cache[MCP_GPINTEN] |= BIT(pos);
mcp_set_bit(mcp, MCP_GPINTEN, pos, true);
}
static int mcp23s08_irq_set_type(struct irq_data *data, unsigned int type)
@ -384,23 +571,23 @@ static int mcp23s08_irq_set_type(struct irq_data *data, unsigned int type)
int status = 0;
if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
mcp->cache[MCP_INTCON] &= ~BIT(pos);
mcp_set_bit(mcp, MCP_INTCON, pos, false);
mcp->irq_rise |= BIT(pos);
mcp->irq_fall |= BIT(pos);
} else if (type & IRQ_TYPE_EDGE_RISING) {
mcp->cache[MCP_INTCON] &= ~BIT(pos);
mcp_set_bit(mcp, MCP_INTCON, pos, false);
mcp->irq_rise |= BIT(pos);
mcp->irq_fall &= ~BIT(pos);
} else if (type & IRQ_TYPE_EDGE_FALLING) {
mcp->cache[MCP_INTCON] &= ~BIT(pos);
mcp_set_bit(mcp, MCP_INTCON, pos, false);
mcp->irq_rise &= ~BIT(pos);
mcp->irq_fall |= BIT(pos);
} else if (type & IRQ_TYPE_LEVEL_HIGH) {
mcp->cache[MCP_INTCON] |= BIT(pos);
mcp->cache[MCP_DEFVAL] &= ~BIT(pos);
mcp_set_bit(mcp, MCP_INTCON, pos, true);
mcp_set_bit(mcp, MCP_DEFVAL, pos, false);
} else if (type & IRQ_TYPE_LEVEL_LOW) {
mcp->cache[MCP_INTCON] |= BIT(pos);
mcp->cache[MCP_DEFVAL] |= BIT(pos);
mcp_set_bit(mcp, MCP_INTCON, pos, true);
mcp_set_bit(mcp, MCP_DEFVAL, pos, true);
} else
return -EINVAL;
@ -412,7 +599,8 @@ static void mcp23s08_irq_bus_lock(struct irq_data *data)
struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
struct mcp23s08 *mcp = gpiochip_get_data(gc);
mutex_lock(&mcp->irq_lock);
mutex_lock(&mcp->lock);
regcache_cache_only(mcp->regmap, true);
}
static void mcp23s08_irq_bus_unlock(struct irq_data *data)
@ -420,12 +608,10 @@ static void mcp23s08_irq_bus_unlock(struct irq_data *data)
struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
struct mcp23s08 *mcp = gpiochip_get_data(gc);
mutex_lock(&mcp->lock);
mcp_write(mcp, MCP_GPINTEN, mcp->cache[MCP_GPINTEN]);
mcp_write(mcp, MCP_DEFVAL, mcp->cache[MCP_DEFVAL]);
mcp_write(mcp, MCP_INTCON, mcp->cache[MCP_INTCON]);
regcache_cache_only(mcp->regmap, false);
regcache_sync(mcp->regmap);
mutex_unlock(&mcp->lock);
mutex_unlock(&mcp->irq_lock);
}
static struct irq_chip mcp23s08_irq_chip = {
@ -443,8 +629,6 @@ static int mcp23s08_irq_setup(struct mcp23s08 *mcp)
int err;
unsigned long irqflags = IRQF_ONESHOT | IRQF_SHARED;
mutex_init(&mcp->irq_lock);
if (mcp->irq_active_high)
irqflags |= IRQF_TRIGGER_HIGH;
else
@ -483,6 +667,47 @@ static int mcp23s08_irq_setup(struct mcp23s08 *mcp)
#include <linux/seq_file.h>
/*
* This compares the chip's registers with the register
* cache and corrects any incorrectly set register. This
* can be used to fix state for MCP23xxx, that temporary
* lost its power supply.
*/
#define MCP23S08_CONFIG_REGS 8
static int __check_mcp23s08_reg_cache(struct mcp23s08 *mcp)
{
int cached[MCP23S08_CONFIG_REGS];
int err = 0, i;
/* read cached config registers */
for (i = 0; i < MCP23S08_CONFIG_REGS; i++) {
err = mcp_read(mcp, i, &cached[i]);
if (err)
goto out;
}
regcache_cache_bypass(mcp->regmap, true);
for (i = 0; i < MCP23S08_CONFIG_REGS; i++) {
int uncached;
err = mcp_read(mcp, i, &uncached);
if (err)
goto out;
if (uncached != cached[i]) {
dev_err(mcp->dev, "restoring reg 0x%02x from 0x%04x to 0x%04x (power-loss?)\n",
i, uncached, cached[i]);
mcp_write(mcp, i, cached[i]);
}
}
out:
if (err)
dev_err(mcp->dev, "read error: reg=%02x, err=%d", i, err);
regcache_cache_bypass(mcp->regmap, false);
return err;
}
/*
* This shows more info than the generic gpio dump code:
* pullups, deglitching, open drain drive.
@ -493,6 +718,7 @@ static void mcp23s08_dbg_show(struct seq_file *s, struct gpio_chip *chip)
char bank;
int t;
unsigned mask;
int iodir, gpio, gppu;
mcp = gpiochip_get_data(chip);
@ -500,14 +726,30 @@ static void mcp23s08_dbg_show(struct seq_file *s, struct gpio_chip *chip)
bank = '0' + ((mcp->addr >> 1) & 0x7);
mutex_lock(&mcp->lock);
t = mcp_update_cache(mcp);
if (t < 0) {
seq_printf(s, " I/O ERROR %d\n", t);
t = __check_mcp23s08_reg_cache(mcp);
if (t) {
seq_printf(s, " I/O Error\n");
goto done;
}
t = mcp_read(mcp, MCP_IODIR, &iodir);
if (t) {
seq_printf(s, " I/O Error\n");
goto done;
}
t = mcp_read(mcp, MCP_GPIO, &gpio);
if (t) {
seq_printf(s, " I/O Error\n");
goto done;
}
t = mcp_read(mcp, MCP_GPPU, &gppu);
if (t) {
seq_printf(s, " I/O Error\n");
goto done;
}
for (t = 0, mask = 1; t < chip->ngpio; t++, mask <<= 1) {
const char *label;
for (t = 0, mask = BIT(0); t < chip->ngpio; t++, mask <<= 1) {
const char *label;
label = gpiochip_is_requested(chip, t);
if (!label)
@ -515,9 +757,9 @@ static void mcp23s08_dbg_show(struct seq_file *s, struct gpio_chip *chip)
seq_printf(s, " gpio-%-3d P%c.%d (%-12s) %s %s %s",
chip->base + t, bank, t, label,
(mcp->cache[MCP_IODIR] & mask) ? "in " : "out",
(mcp->cache[MCP_GPIO] & mask) ? "hi" : "lo",
(mcp->cache[MCP_GPPU] & mask) ? "up" : " ");
(iodir & mask) ? "in " : "out",
(gpio & mask) ? "hi" : "lo",
(gppu & mask) ? "up" : " ");
/* NOTE: ignoring the irq-related registers */
seq_puts(s, "\n");
}
@ -533,7 +775,7 @@ done:
static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
void *data, unsigned addr, unsigned type,
struct mcp23s08_platform_data *pdata, int cs)
unsigned int base, int cs)
{
int status, ret;
bool mirror = false;
@ -605,7 +847,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
if (IS_ERR(mcp->regmap))
return PTR_ERR(mcp->regmap);
mcp->chip.base = pdata->base;
mcp->chip.base = base;
mcp->chip.can_sleep = true;
mcp->chip.parent = dev;
mcp->chip.owner = THIS_MODULE;
@ -618,13 +860,14 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
if (ret < 0)
goto fail;
mcp->irq_controller = pdata->irq_controller;
mcp->irq_controller =
device_property_read_bool(dev, "interrupt-controller");
if (mcp->irq && mcp->irq_controller) {
mcp->irq_active_high =
of_property_read_bool(mcp->chip.parent->of_node,
device_property_read_bool(dev,
"microchip,irq-active-high");
mirror = pdata->mirror;
mirror = device_property_read_bool(dev, "microchip,irq-mirror");
}
if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror ||
@ -648,32 +891,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
goto fail;
}
/* configure ~100K pullups */
ret = mcp_write(mcp, MCP_GPPU, pdata->chip[cs].pullups);
if (ret < 0)
goto fail;
ret = mcp_update_cache(mcp);
if (ret < 0)
goto fail;
/* disable inverter on input */
if (mcp->cache[MCP_IPOL] != 0) {
mcp->cache[MCP_IPOL] = 0;
ret = mcp_write(mcp, MCP_IPOL, 0);
if (ret < 0)
goto fail;
}
/* disable irqs */
if (mcp->cache[MCP_GPINTEN] != 0) {
mcp->cache[MCP_GPINTEN] = 0;
ret = mcp_write(mcp, MCP_GPINTEN, 0);
if (ret < 0)
goto fail;
}
ret = gpiochip_add_data(&mcp->chip, mcp);
ret = devm_gpiochip_add_data(dev, &mcp->chip, mcp);
if (ret < 0)
goto fail;
@ -682,6 +900,23 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
if (ret)
goto fail;
}
mcp->pinctrl_desc.name = "mcp23xxx-pinctrl";
mcp->pinctrl_desc.pctlops = &mcp_pinctrl_ops;
mcp->pinctrl_desc.confops = &mcp_pinconf_ops;
mcp->pinctrl_desc.npins = mcp->chip.ngpio;
if (mcp->pinctrl_desc.npins == 8)
mcp->pinctrl_desc.pins = mcp23x08_pins;
else if (mcp->pinctrl_desc.npins == 16)
mcp->pinctrl_desc.pins = mcp23x17_pins;
mcp->pinctrl_desc.owner = THIS_MODULE;
mcp->pctldev = devm_pinctrl_register(dev, &mcp->pinctrl_desc, mcp);
if (IS_ERR(mcp->pctldev)) {
ret = PTR_ERR(mcp->pctldev);
goto fail;
}
fail:
if (ret < 0)
dev_dbg(dev, "can't setup chip %d, --> %d\n", addr, ret);
@ -753,59 +988,25 @@ static int mcp230xx_probe(struct i2c_client *client,
struct mcp23s08_platform_data *pdata, local_pdata;
struct mcp23s08 *mcp;
int status;
const struct of_device_id *match;
match = of_match_device(of_match_ptr(mcp23s08_i2c_of_match),
&client->dev);
if (match) {
pdata = dev_get_platdata(&client->dev);
if (!pdata) {
pdata = &local_pdata;
pdata->base = -1;
pdata->chip[0].pullups = 0;
pdata->irq_controller = of_property_read_bool(
client->dev.of_node,
"interrupt-controller");
pdata->mirror = of_property_read_bool(client->dev.of_node,
"microchip,irq-mirror");
client->irq = irq_of_parse_and_map(client->dev.of_node, 0);
} else {
pdata = dev_get_platdata(&client->dev);
if (!pdata) {
pdata = devm_kzalloc(&client->dev,
sizeof(struct mcp23s08_platform_data),
GFP_KERNEL);
if (!pdata)
return -ENOMEM;
pdata->base = -1;
}
}
mcp = kzalloc(sizeof(*mcp), GFP_KERNEL);
mcp = devm_kzalloc(&client->dev, sizeof(*mcp), GFP_KERNEL);
if (!mcp)
return -ENOMEM;
mcp->irq = client->irq;
status = mcp23s08_probe_one(mcp, &client->dev, client, client->addr,
id->driver_data, pdata, 0);
id->driver_data, pdata->base, 0);
if (status)
goto fail;
return status;
i2c_set_clientdata(client, mcp);
return 0;
fail:
kfree(mcp);
return status;
}
static int mcp230xx_remove(struct i2c_client *client)
{
struct mcp23s08 *mcp = i2c_get_clientdata(client);
gpiochip_remove(&mcp->chip);
kfree(mcp);
return 0;
}
@ -822,7 +1023,6 @@ static struct i2c_driver mcp230xx_driver = {
.of_match_table = of_match_ptr(mcp23s08_i2c_of_match),
},
.probe = mcp230xx_probe,
.remove = mcp230xx_remove,
.id_table = mcp230xx_id,
};
@ -856,60 +1056,40 @@ static int mcp23s08_probe(struct spi_device *spi)
int status, type;
unsigned ngpio = 0;
const struct of_device_id *match;
u32 spi_present_mask = 0;
match = of_match_device(of_match_ptr(mcp23s08_spi_of_match), &spi->dev);
if (match) {
if (match)
type = (int)(uintptr_t)match->data;
status = of_property_read_u32(spi->dev.of_node,
"microchip,spi-present-mask", &spi_present_mask);
else
type = spi_get_device_id(spi)->driver_data;
pdata = dev_get_platdata(&spi->dev);
if (!pdata) {
pdata = &local_pdata;
pdata->base = -1;
status = device_property_read_u32(&spi->dev,
"microchip,spi-present-mask", &pdata->spi_present_mask);
if (status) {
status = of_property_read_u32(spi->dev.of_node,
"mcp,spi-present-mask", &spi_present_mask);
status = device_property_read_u32(&spi->dev,
"mcp,spi-present-mask",
&pdata->spi_present_mask);
if (status) {
dev_err(&spi->dev,
"DT has no spi-present-mask\n");
dev_err(&spi->dev, "missing spi-present-mask");
return -ENODEV;
}
}
if ((spi_present_mask <= 0) || (spi_present_mask >= 256)) {
dev_err(&spi->dev, "invalid spi-present-mask\n");
return -ENODEV;
}
}
pdata = &local_pdata;
pdata->base = -1;
for (addr = 0; addr < ARRAY_SIZE(pdata->chip); addr++) {
pdata->chip[addr].pullups = 0;
if (spi_present_mask & (1 << addr))
chips++;
}
pdata->irq_controller = of_property_read_bool(
spi->dev.of_node,
"interrupt-controller");
pdata->mirror = of_property_read_bool(spi->dev.of_node,
"microchip,irq-mirror");
} else {
type = spi_get_device_id(spi)->driver_data;
pdata = dev_get_platdata(&spi->dev);
if (!pdata) {
pdata = devm_kzalloc(&spi->dev,
sizeof(struct mcp23s08_platform_data),
GFP_KERNEL);
pdata->base = -1;
}
if (!pdata->spi_present_mask || pdata->spi_present_mask > 0xff) {
dev_err(&spi->dev, "invalid spi-present-mask");
return -ENODEV;
}
for (addr = 0; addr < ARRAY_SIZE(pdata->chip); addr++) {
if (!pdata->chip[addr].is_present)
continue;
for (addr = 0; addr < MCP_MAX_DEV_PER_CS; addr++) {
if (pdata->spi_present_mask & BIT(addr))
chips++;
if ((type == MCP_TYPE_S08) && (addr > 3)) {
dev_err(&spi->dev,
"mcp23s08 only supports address 0..3\n");
return -EINVAL;
}
spi_present_mask |= 1 << addr;
}
}
if (!chips)
@ -923,19 +1103,17 @@ static int mcp23s08_probe(struct spi_device *spi)
spi_set_drvdata(spi, data);
spi->irq = irq_of_parse_and_map(spi->dev.of_node, 0);
for (addr = 0; addr < ARRAY_SIZE(pdata->chip); addr++) {
if (!(spi_present_mask & (1 << addr)))
for (addr = 0; addr < MCP_MAX_DEV_PER_CS; addr++) {
if (!(pdata->spi_present_mask & BIT(addr)))
continue;
chips--;
data->mcp[addr] = &data->chip[chips];
data->mcp[addr]->irq = spi->irq;
status = mcp23s08_probe_one(data->mcp[addr], &spi->dev, spi,
0x40 | (addr << 1), type, pdata,
addr);
0x40 | (addr << 1), type,
pdata->base, addr);
if (status < 0)
goto fail;
return status;
if (pdata->base != -1)
pdata->base += data->mcp[addr]->chip.ngpio;
@ -943,36 +1121,6 @@ static int mcp23s08_probe(struct spi_device *spi)
}
data->ngpio = ngpio;
/* NOTE: these chips have a relatively sane IRQ framework, with
* per-signal masking and level/edge triggering. It's not yet
* handled here...
*/
return 0;
fail:
for (addr = 0; addr < ARRAY_SIZE(data->mcp); addr++) {
if (!data->mcp[addr])
continue;
gpiochip_remove(&data->mcp[addr]->chip);
}
return status;
}
static int mcp23s08_remove(struct spi_device *spi)
{
struct mcp23s08_driver_data *data = spi_get_drvdata(spi);
unsigned addr;
for (addr = 0; addr < ARRAY_SIZE(data->mcp); addr++) {
if (!data->mcp[addr])
continue;
gpiochip_remove(&data->mcp[addr]->chip);
}
return 0;
}
@ -986,7 +1134,6 @@ MODULE_DEVICE_TABLE(spi, mcp23s08_ids);
static struct spi_driver mcp23s08_driver = {
.probe = mcp23s08_probe,
.remove = mcp23s08_remove,
.id_table = mcp23s08_ids,
.driver = {
.name = "mcp23s08",

View File

@ -143,6 +143,7 @@ struct rockchip_drv {
* @gpio_chip: gpiolib chip
* @grange: gpio range
* @slock: spinlock for the gpio bank
* @route_mask: bits describing the routing pins of per bank
*/
struct rockchip_pin_bank {
void __iomem *reg_base;
@ -165,6 +166,7 @@ struct rockchip_pin_bank {
struct pinctrl_gpio_range grange;
raw_spinlock_t slock;
u32 toggle_edge_mode;
u32 route_mask;
};
#define PIN_BANK(id, pins, label) \
@ -287,6 +289,22 @@ struct rockchip_pin_bank {
.pull_type[3] = pull3, \
}
/**
* struct rockchip_mux_recalced_data: represent a pin iomux data.
* @bank_num: bank number.
* @pin: index at register or used to calc index.
* @func: the min pin.
* @route_offset: the max pin.
* @route_val: the register offset.
*/
struct rockchip_mux_route_data {
u8 bank_num;
u8 pin;
u8 func;
u32 route_offset;
u32 route_val;
};
/**
*/
struct rockchip_pin_ctrl {
@ -299,6 +317,8 @@ struct rockchip_pin_ctrl {
int pmu_mux_offset;
int grf_drv_offset;
int pmu_drv_offset;
struct rockchip_mux_route_data *iomux_routes;
u32 niomux_routes;
void (*pull_calc_reg)(struct rockchip_pin_bank *bank,
int pin_num, struct regmap **regmap,
@ -580,6 +600,280 @@ static void rk3328_recalc_mux(u8 bank_num, int pin, int *reg,
*bit = data->bit;
}
static struct rockchip_mux_route_data rk3228_mux_route_data[] = {
{
/* pwm0-0 */
.bank_num = 0,
.pin = 26,
.func = 1,
.route_offset = 0x50,
.route_val = BIT(16),
}, {
/* pwm0-1 */
.bank_num = 3,
.pin = 21,
.func = 1,
.route_offset = 0x50,
.route_val = BIT(16) | BIT(0),
}, {
/* pwm1-0 */
.bank_num = 0,
.pin = 27,
.func = 1,
.route_offset = 0x50,
.route_val = BIT(16 + 1),
}, {
/* pwm1-1 */
.bank_num = 0,
.pin = 30,
.func = 2,
.route_offset = 0x50,
.route_val = BIT(16 + 1) | BIT(1),
}, {
/* pwm2-0 */
.bank_num = 0,
.pin = 28,
.func = 1,
.route_offset = 0x50,
.route_val = BIT(16 + 2),
}, {
/* pwm2-1 */
.bank_num = 1,
.pin = 12,
.func = 2,
.route_offset = 0x50,
.route_val = BIT(16 + 2) | BIT(2),
}, {
/* pwm3-0 */
.bank_num = 3,
.pin = 26,
.func = 1,
.route_offset = 0x50,
.route_val = BIT(16 + 3),
}, {
/* pwm3-1 */
.bank_num = 1,
.pin = 11,
.func = 2,
.route_offset = 0x50,
.route_val = BIT(16 + 3) | BIT(3),
}, {
/* sdio-0_d0 */
.bank_num = 1,
.pin = 1,
.func = 1,
.route_offset = 0x50,
.route_val = BIT(16 + 4),
}, {
/* sdio-1_d0 */
.bank_num = 3,
.pin = 2,
.func = 1,
.route_offset = 0x50,
.route_val = BIT(16 + 4) | BIT(4),
}, {
/* spi-0_rx */
.bank_num = 0,
.pin = 13,
.func = 2,
.route_offset = 0x50,
.route_val = BIT(16 + 5),
}, {
/* spi-1_rx */
.bank_num = 2,
.pin = 0,
.func = 2,
.route_offset = 0x50,
.route_val = BIT(16 + 5) | BIT(5),
}, {
/* emmc-0_cmd */
.bank_num = 1,
.pin = 22,
.func = 2,
.route_offset = 0x50,
.route_val = BIT(16 + 7),
}, {
/* emmc-1_cmd */
.bank_num = 2,
.pin = 4,
.func = 2,
.route_offset = 0x50,
.route_val = BIT(16 + 7) | BIT(7),
}, {
/* uart2-0_rx */
.bank_num = 1,
.pin = 19,
.func = 2,
.route_offset = 0x50,
.route_val = BIT(16 + 8),
}, {
/* uart2-1_rx */
.bank_num = 1,
.pin = 10,
.func = 2,
.route_offset = 0x50,
.route_val = BIT(16 + 8) | BIT(8),
}, {
/* uart1-0_rx */
.bank_num = 1,
.pin = 10,
.func = 1,
.route_offset = 0x50,
.route_val = BIT(16 + 11),
}, {
/* uart1-1_rx */
.bank_num = 3,
.pin = 13,
.func = 1,
.route_offset = 0x50,
.route_val = BIT(16 + 11) | BIT(11),
},
};
static struct rockchip_mux_route_data rk3328_mux_route_data[] = {
{
/* uart2dbg_rxm0 */
.bank_num = 1,
.pin = 1,
.func = 2,
.route_offset = 0x50,
.route_val = BIT(16) | BIT(16 + 1),
}, {
/* uart2dbg_rxm1 */
.bank_num = 2,
.pin = 1,
.func = 1,
.route_offset = 0x50,
.route_val = BIT(16) | BIT(16 + 1) | BIT(0),
}, {
/* gmac-m1-optimized_rxd0 */
.bank_num = 1,
.pin = 11,
.func = 2,
.route_offset = 0x50,
.route_val = BIT(16 + 2) | BIT(16 + 10) | BIT(2) | BIT(10),
}, {
/* pdm_sdi0m0 */
.bank_num = 2,
.pin = 19,
.func = 2,
.route_offset = 0x50,
.route_val = BIT(16 + 3),
}, {
/* pdm_sdi0m1 */
.bank_num = 1,
.pin = 23,
.func = 3,
.route_offset = 0x50,
.route_val = BIT(16 + 3) | BIT(3),
}, {
/* spi_rxdm2 */
.bank_num = 3,
.pin = 2,
.func = 4,
.route_offset = 0x50,
.route_val = BIT(16 + 4) | BIT(16 + 5) | BIT(5),
}, {
/* i2s2_sdim0 */
.bank_num = 1,
.pin = 24,
.func = 1,
.route_offset = 0x50,
.route_val = BIT(16 + 6),
}, {
/* i2s2_sdim1 */
.bank_num = 3,
.pin = 2,
.func = 6,
.route_offset = 0x50,
.route_val = BIT(16 + 6) | BIT(6),
}, {
/* card_iom1 */
.bank_num = 2,
.pin = 22,
.func = 3,
.route_offset = 0x50,
.route_val = BIT(16 + 7) | BIT(7),
}, {
/* tsp_d5m1 */
.bank_num = 2,
.pin = 16,
.func = 3,
.route_offset = 0x50,
.route_val = BIT(16 + 8) | BIT(8),
}, {
/* cif_data5m1 */
.bank_num = 2,
.pin = 16,
.func = 4,
.route_offset = 0x50,
.route_val = BIT(16 + 9) | BIT(9),
},
};
static struct rockchip_mux_route_data rk3399_mux_route_data[] = {
{
/* uart2dbga_rx */
.bank_num = 4,
.pin = 8,
.func = 2,
.route_offset = 0xe21c,
.route_val = BIT(16 + 10) | BIT(16 + 11),
}, {
/* uart2dbgb_rx */
.bank_num = 4,
.pin = 16,
.func = 2,
.route_offset = 0xe21c,
.route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10),
}, {
/* uart2dbgc_rx */
.bank_num = 4,
.pin = 19,
.func = 1,
.route_offset = 0xe21c,
.route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11),
}, {
/* pcie_clkreqn */
.bank_num = 2,
.pin = 26,
.func = 2,
.route_offset = 0xe21c,
.route_val = BIT(16 + 14),
}, {
/* pcie_clkreqnb */
.bank_num = 4,
.pin = 24,
.func = 1,
.route_offset = 0xe21c,
.route_val = BIT(16 + 14) | BIT(14),
},
};
static bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
int mux, u32 *reg, u32 *value)
{
struct rockchip_pinctrl *info = bank->drvdata;
struct rockchip_pin_ctrl *ctrl = info->ctrl;
struct rockchip_mux_route_data *data;
int i;
for (i = 0; i < ctrl->niomux_routes; i++) {
data = &ctrl->iomux_routes[i];
if ((data->bank_num == bank->bank_num) &&
(data->pin == pin) && (data->func == mux))
break;
}
if (i >= ctrl->niomux_routes)
return false;
*reg = data->route_offset;
*value = data->route_val;
return true;
}
static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
{
struct rockchip_pinctrl *info = bank->drvdata;
@ -678,7 +972,7 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
struct regmap *regmap;
int reg, ret, mask, mux_type;
u8 bit;
u32 data, rmask;
u32 data, rmask, route_reg, route_val;
ret = rockchip_verify_mux(bank, pin, mux);
if (ret < 0)
@ -714,6 +1008,15 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
if (ctrl->iomux_recalc && (mux_type & IOMUX_RECALCED))
ctrl->iomux_recalc(bank->bank_num, pin, &reg, &bit, &mask);
if (bank->route_mask & BIT(pin)) {
if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
&route_val)) {
ret = regmap_write(regmap, route_reg, route_val);
if (ret)
return ret;
}
}
data = (mask << (bit + 16));
rmask = data | (data >> 16);
data |= (mux & mask) << bit;
@ -2549,6 +2852,16 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
bank_pins += 8;
}
/* calculate the per-bank route_mask */
for (j = 0; j < ctrl->niomux_routes; j++) {
int pin = 0;
if (ctrl->iomux_routes[j].bank_num == bank->bank_num) {
pin = ctrl->iomux_routes[j].pin;
bank->route_mask |= BIT(pin);
}
}
}
return ctrl;
@ -2799,6 +3112,8 @@ static struct rockchip_pin_ctrl rk3228_pin_ctrl = {
.label = "RK3228-GPIO",
.type = RK3288,
.grf_mux_offset = 0x0,
.iomux_routes = rk3228_mux_route_data,
.niomux_routes = ARRAY_SIZE(rk3228_mux_route_data),
.pull_calc_reg = rk3228_calc_pull_reg_and_bit,
.drv_calc_reg = rk3228_calc_drv_reg_and_bit,
};
@ -2866,6 +3181,8 @@ static struct rockchip_pin_ctrl rk3328_pin_ctrl = {
.label = "RK3328-GPIO",
.type = RK3288,
.grf_mux_offset = 0x0,
.iomux_routes = rk3328_mux_route_data,
.niomux_routes = ARRAY_SIZE(rk3328_mux_route_data),
.pull_calc_reg = rk3228_calc_pull_reg_and_bit,
.drv_calc_reg = rk3228_calc_drv_reg_and_bit,
.iomux_recalc = rk3328_recalc_mux,
@ -2956,33 +3273,35 @@ static struct rockchip_pin_ctrl rk3399_pin_ctrl = {
.pmu_mux_offset = 0x0,
.grf_drv_offset = 0xe100,
.pmu_drv_offset = 0x80,
.iomux_routes = rk3399_mux_route_data,
.niomux_routes = ARRAY_SIZE(rk3399_mux_route_data),
.pull_calc_reg = rk3399_calc_pull_reg_and_bit,
.drv_calc_reg = rk3399_calc_drv_reg_and_bit,
};
static const struct of_device_id rockchip_pinctrl_dt_match[] = {
{ .compatible = "rockchip,rv1108-pinctrl",
.data = (void *)&rv1108_pin_ctrl },
.data = &rv1108_pin_ctrl },
{ .compatible = "rockchip,rk2928-pinctrl",
.data = (void *)&rk2928_pin_ctrl },
.data = &rk2928_pin_ctrl },
{ .compatible = "rockchip,rk3036-pinctrl",
.data = (void *)&rk3036_pin_ctrl },
.data = &rk3036_pin_ctrl },
{ .compatible = "rockchip,rk3066a-pinctrl",
.data = (void *)&rk3066a_pin_ctrl },
.data = &rk3066a_pin_ctrl },
{ .compatible = "rockchip,rk3066b-pinctrl",
.data = (void *)&rk3066b_pin_ctrl },
.data = &rk3066b_pin_ctrl },
{ .compatible = "rockchip,rk3188-pinctrl",
.data = (void *)&rk3188_pin_ctrl },
.data = &rk3188_pin_ctrl },
{ .compatible = "rockchip,rk3228-pinctrl",
.data = (void *)&rk3228_pin_ctrl },
.data = &rk3228_pin_ctrl },
{ .compatible = "rockchip,rk3288-pinctrl",
.data = (void *)&rk3288_pin_ctrl },
.data = &rk3288_pin_ctrl },
{ .compatible = "rockchip,rk3328-pinctrl",
.data = (void *)&rk3328_pin_ctrl },
.data = &rk3328_pin_ctrl },
{ .compatible = "rockchip,rk3368-pinctrl",
.data = (void *)&rk3368_pin_ctrl },
.data = &rk3368_pin_ctrl },
{ .compatible = "rockchip,rk3399-pinctrl",
.data = (void *)&rk3399_pin_ctrl },
.data = &rk3399_pin_ctrl },
{},
};

File diff suppressed because it is too large Load Diff

View File

@ -1270,8 +1270,6 @@ static void pcs_free_resources(struct pcs_device *pcs)
#endif
}
static const struct of_device_id pcs_of_match[];
static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs)
{
const char *propname = "pinctrl-single,gpio-range";
@ -1637,15 +1635,14 @@ static int pcs_quirk_missing_pinctrl_cells(struct pcs_device *pcs,
static int pcs_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
const struct of_device_id *match;
struct pcs_pdata *pdata;
struct resource *res;
struct pcs_device *pcs;
const struct pcs_soc_data *soc;
int ret;
match = of_match_device(pcs_of_match, &pdev->dev);
if (!match)
soc = of_device_get_match_data(&pdev->dev);
if (WARN_ON(!soc))
return -EINVAL;
pcs = devm_kzalloc(&pdev->dev, sizeof(*pcs), GFP_KERNEL);
@ -1658,7 +1655,6 @@ static int pcs_probe(struct platform_device *pdev)
raw_spin_lock_init(&pcs->lock);
mutex_init(&pcs->mutex);
INIT_LIST_HEAD(&pcs->gpiofuncs);
soc = match->data;
pcs->flags = soc->flags;
memcpy(&pcs->socdata, soc, sizeof(*soc));

View File

@ -1028,7 +1028,7 @@ static const struct ltq_pin_group xrx200_grps[] = {
GRP_MUX("spi_cs5", SPI, xrx200_pins_spi_cs5),
GRP_MUX("spi_cs6", SPI, xrx200_pins_spi_cs6),
GRP_MUX("usif uart_rx", USIF, xrx200_pins_usif_uart_rx),
GRP_MUX("usif uart_rx", USIF, xrx200_pins_usif_uart_tx),
GRP_MUX("usif uart_tx", USIF, xrx200_pins_usif_uart_tx),
GRP_MUX("usif uart_rts", USIF, xrx200_pins_usif_uart_rts),
GRP_MUX("usif uart_cts", USIF, xrx200_pins_usif_uart_cts),
GRP_MUX("usif uart_dtr", USIF, xrx200_pins_usif_uart_dtr),

View File

@ -39,6 +39,16 @@ config PINCTRL_IPQ8064
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm IPQ8064 platform.
config PINCTRL_IPQ8074
tristate "Qualcomm Technologies, Inc. IPQ8074 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. IPQ8074 platform. Select this for
IPQ8074.
config PINCTRL_MSM8660
tristate "Qualcomm 8660 pin controller driver"
depends on GPIOLIB && OF

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,16 @@ config PINCTRL_EXYNOS
bool "Pinctrl driver data for Samsung EXYNOS SoCs other than 5440"
depends on OF && GPIOLIB && (ARCH_EXYNOS || ARCH_S5PV210)
select PINCTRL_SAMSUNG
select PINCTRL_EXYNOS_ARM if ARM && (ARCH_EXYNOS || ARCH_S5PV210)
select PINCTRL_EXYNOS_ARM64 if ARM64 && ARCH_EXYNOS
config PINCTRL_EXYNOS_ARM
bool "ARMv7-specific pinctrl driver data for Exynos (except Exynos5440)" if COMPILE_TEST
depends on PINCTRL_EXYNOS
config PINCTRL_EXYNOS_ARM64
bool "ARMv8-specific pinctrl driver data for Exynos" if COMPILE_TEST
depends on PINCTRL_EXYNOS
config PINCTRL_EXYNOS5440
bool "Samsung EXYNOS5440 SoC pinctrl driver"

View File

@ -2,6 +2,8 @@
obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o
obj-$(CONFIG_PINCTRL_EXYNOS) += pinctrl-exynos.o
obj-$(CONFIG_PINCTRL_EXYNOS_ARM) += pinctrl-exynos-arm.o
obj-$(CONFIG_PINCTRL_EXYNOS_ARM64) += pinctrl-exynos-arm64.o
obj-$(CONFIG_PINCTRL_EXYNOS5440) += pinctrl-exynos5440.o
obj-$(CONFIG_PINCTRL_S3C24XX) += pinctrl-s3c24xx.o
obj-$(CONFIG_PINCTRL_S3C64XX) += pinctrl-s3c64xx.o

View File

@ -0,0 +1,815 @@
/*
* Exynos specific support for Samsung pinctrl/gpiolib driver with eint support.
*
* Copyright (c) 2012 Samsung Electronics Co., Ltd.
* http://www.samsung.com
* Copyright (c) 2012 Linaro Ltd
* http://www.linaro.org
*
* Author: Thomas Abraham <thomas.ab@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This file contains the Samsung Exynos specific information required by the
* the Samsung pinctrl/gpiolib driver. It also includes the implementation of
* external gpio and wakeup interrupt support.
*/
#include <linux/device.h>
#include <linux/of_address.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/soc/samsung/exynos-regs-pmu.h>
#include "pinctrl-samsung.h"
#include "pinctrl-exynos.h"
static const struct samsung_pin_bank_type bank_type_off = {
.fld_width = { 4, 1, 2, 2, 2, 2, },
.reg_offset = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, },
};
static const struct samsung_pin_bank_type bank_type_alive = {
.fld_width = { 4, 1, 2, 2, },
.reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
};
/* Retention control for S5PV210 are located at the end of clock controller */
#define S5P_OTHERS 0xE000
#define S5P_OTHERS_RET_IO (1 << 31)
#define S5P_OTHERS_RET_CF (1 << 30)
#define S5P_OTHERS_RET_MMC (1 << 29)
#define S5P_OTHERS_RET_UART (1 << 28)
static void s5pv210_retention_disable(struct samsung_pinctrl_drv_data *drvdata)
{
void __iomem *clk_base = (void __iomem *)drvdata->retention_ctrl->priv;
u32 tmp;
tmp = __raw_readl(clk_base + S5P_OTHERS);
tmp |= (S5P_OTHERS_RET_IO | S5P_OTHERS_RET_CF | S5P_OTHERS_RET_MMC |
S5P_OTHERS_RET_UART);
__raw_writel(tmp, clk_base + S5P_OTHERS);
}
static struct samsung_retention_ctrl *
s5pv210_retention_init(struct samsung_pinctrl_drv_data *drvdata,
const struct samsung_retention_data *data)
{
struct samsung_retention_ctrl *ctrl;
struct device_node *np;
void __iomem *clk_base;
ctrl = devm_kzalloc(drvdata->dev, sizeof(*ctrl), GFP_KERNEL);
if (!ctrl)
return ERR_PTR(-ENOMEM);
np = of_find_compatible_node(NULL, NULL, "samsung,s5pv210-clock");
if (!np) {
pr_err("%s: failed to find clock controller DT node\n",
__func__);
return ERR_PTR(-ENODEV);
}
clk_base = of_iomap(np, 0);
if (!clk_base) {
pr_err("%s: failed to map clock registers\n", __func__);
return ERR_PTR(-EINVAL);
}
ctrl->priv = (void __force *)clk_base;
ctrl->disable = s5pv210_retention_disable;
return ctrl;
}
static const struct samsung_retention_data s5pv210_retention_data __initconst = {
.init = s5pv210_retention_init,
};
/* pin banks of s5pv210 pin-controller */
static const struct samsung_pin_bank_data s5pv210_pin_bank[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08),
EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c),
EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10),
EXYNOS_PIN_BANK_EINTG(4, 0x0a0, "gpd0", 0x14),
EXYNOS_PIN_BANK_EINTG(6, 0x0c0, "gpd1", 0x18),
EXYNOS_PIN_BANK_EINTG(8, 0x0e0, "gpe0", 0x1c),
EXYNOS_PIN_BANK_EINTG(5, 0x100, "gpe1", 0x20),
EXYNOS_PIN_BANK_EINTG(8, 0x120, "gpf0", 0x24),
EXYNOS_PIN_BANK_EINTG(8, 0x140, "gpf1", 0x28),
EXYNOS_PIN_BANK_EINTG(8, 0x160, "gpf2", 0x2c),
EXYNOS_PIN_BANK_EINTG(6, 0x180, "gpf3", 0x30),
EXYNOS_PIN_BANK_EINTG(7, 0x1a0, "gpg0", 0x34),
EXYNOS_PIN_BANK_EINTG(7, 0x1c0, "gpg1", 0x38),
EXYNOS_PIN_BANK_EINTG(7, 0x1e0, "gpg2", 0x3c),
EXYNOS_PIN_BANK_EINTG(7, 0x200, "gpg3", 0x40),
EXYNOS_PIN_BANK_EINTN(7, 0x220, "gpi"),
EXYNOS_PIN_BANK_EINTG(8, 0x240, "gpj0", 0x44),
EXYNOS_PIN_BANK_EINTG(6, 0x260, "gpj1", 0x48),
EXYNOS_PIN_BANK_EINTG(8, 0x280, "gpj2", 0x4c),
EXYNOS_PIN_BANK_EINTG(8, 0x2a0, "gpj3", 0x50),
EXYNOS_PIN_BANK_EINTG(5, 0x2c0, "gpj4", 0x54),
EXYNOS_PIN_BANK_EINTN(8, 0x2e0, "mp01"),
EXYNOS_PIN_BANK_EINTN(4, 0x300, "mp02"),
EXYNOS_PIN_BANK_EINTN(8, 0x320, "mp03"),
EXYNOS_PIN_BANK_EINTN(8, 0x340, "mp04"),
EXYNOS_PIN_BANK_EINTN(8, 0x360, "mp05"),
EXYNOS_PIN_BANK_EINTN(8, 0x380, "mp06"),
EXYNOS_PIN_BANK_EINTN(8, 0x3a0, "mp07"),
EXYNOS_PIN_BANK_EINTW(8, 0xc00, "gph0", 0x00),
EXYNOS_PIN_BANK_EINTW(8, 0xc20, "gph1", 0x04),
EXYNOS_PIN_BANK_EINTW(8, 0xc40, "gph2", 0x08),
EXYNOS_PIN_BANK_EINTW(8, 0xc60, "gph3", 0x0c),
};
const struct samsung_pin_ctrl s5pv210_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 data */
.pin_banks = s5pv210_pin_bank,
.nr_banks = ARRAY_SIZE(s5pv210_pin_bank),
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &s5pv210_retention_data,
},
};
/* Pad retention control code for accessing PMU regmap */
static atomic_t exynos_shared_retention_refcnt;
/* pin banks of exynos3250 pin-controller 0 */
static const struct samsung_pin_bank_data exynos3250_pin_banks0[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08),
EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c),
EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10),
EXYNOS_PIN_BANK_EINTG(4, 0x0a0, "gpd0", 0x14),
EXYNOS_PIN_BANK_EINTG(4, 0x0c0, "gpd1", 0x18),
};
/* pin banks of exynos3250 pin-controller 1 */
static const struct samsung_pin_bank_data exynos3250_pin_banks1[] __initconst = {
EXYNOS_PIN_BANK_EINTN(8, 0x120, "gpe0"),
EXYNOS_PIN_BANK_EINTN(8, 0x140, "gpe1"),
EXYNOS_PIN_BANK_EINTN(3, 0x180, "gpe2"),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpk0", 0x08),
EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c),
EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10),
EXYNOS_PIN_BANK_EINTG(4, 0x0c0, "gpl0", 0x18),
EXYNOS_PIN_BANK_EINTG(8, 0x260, "gpm0", 0x24),
EXYNOS_PIN_BANK_EINTG(7, 0x280, "gpm1", 0x28),
EXYNOS_PIN_BANK_EINTG(5, 0x2a0, "gpm2", 0x2c),
EXYNOS_PIN_BANK_EINTG(8, 0x2c0, "gpm3", 0x30),
EXYNOS_PIN_BANK_EINTG(8, 0x2e0, "gpm4", 0x34),
EXYNOS_PIN_BANK_EINTW(8, 0xc00, "gpx0", 0x00),
EXYNOS_PIN_BANK_EINTW(8, 0xc20, "gpx1", 0x04),
EXYNOS_PIN_BANK_EINTW(8, 0xc40, "gpx2", 0x08),
EXYNOS_PIN_BANK_EINTW(8, 0xc60, "gpx3", 0x0c),
};
/*
* PMU pad retention groups for Exynos3250 doesn't match pin banks, so handle
* them all together
*/
static const u32 exynos3250_retention_regs[] = {
S5P_PAD_RET_MAUDIO_OPTION,
S5P_PAD_RET_GPIO_OPTION,
S5P_PAD_RET_UART_OPTION,
S5P_PAD_RET_MMCA_OPTION,
S5P_PAD_RET_MMCB_OPTION,
S5P_PAD_RET_EBIA_OPTION,
S5P_PAD_RET_EBIB_OPTION,
S5P_PAD_RET_MMC2_OPTION,
S5P_PAD_RET_SPI_OPTION,
};
static const struct samsung_retention_data exynos3250_retention_data __initconst = {
.regs = exynos3250_retention_regs,
.nr_regs = ARRAY_SIZE(exynos3250_retention_regs),
.value = EXYNOS_WAKEUP_FROM_LOWPWR,
.refcnt = &exynos_shared_retention_refcnt,
.init = exynos_retention_init,
};
/*
* Samsung pinctrl driver data for Exynos3250 SoC. Exynos3250 SoC includes
* two gpio/pin-mux/pinconfig controllers.
*/
const struct samsung_pin_ctrl exynos3250_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 data */
.pin_banks = exynos3250_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos3250_pin_banks0),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos3250_retention_data,
}, {
/* pin-controller instance 1 data */
.pin_banks = exynos3250_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos3250_pin_banks1),
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos3250_retention_data,
},
};
/* pin banks of exynos4210 pin-controller 0 */
static const struct samsung_pin_bank_data exynos4210_pin_banks0[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08),
EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c),
EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10),
EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpd0", 0x14),
EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpd1", 0x18),
EXYNOS_PIN_BANK_EINTG(5, 0x0E0, "gpe0", 0x1c),
EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpe1", 0x20),
EXYNOS_PIN_BANK_EINTG(6, 0x120, "gpe2", 0x24),
EXYNOS_PIN_BANK_EINTG(8, 0x140, "gpe3", 0x28),
EXYNOS_PIN_BANK_EINTG(8, 0x160, "gpe4", 0x2c),
EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpf0", 0x30),
EXYNOS_PIN_BANK_EINTG(8, 0x1A0, "gpf1", 0x34),
EXYNOS_PIN_BANK_EINTG(8, 0x1C0, "gpf2", 0x38),
EXYNOS_PIN_BANK_EINTG(6, 0x1E0, "gpf3", 0x3c),
};
/* pin banks of exynos4210 pin-controller 1 */
static const struct samsung_pin_bank_data exynos4210_pin_banks1[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpj0", 0x00),
EXYNOS_PIN_BANK_EINTG(5, 0x020, "gpj1", 0x04),
EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08),
EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c),
EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10),
EXYNOS_PIN_BANK_EINTG(7, 0x0A0, "gpk3", 0x14),
EXYNOS_PIN_BANK_EINTG(8, 0x0C0, "gpl0", 0x18),
EXYNOS_PIN_BANK_EINTG(3, 0x0E0, "gpl1", 0x1c),
EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpl2", 0x20),
EXYNOS_PIN_BANK_EINTN(6, 0x120, "gpy0"),
EXYNOS_PIN_BANK_EINTN(4, 0x140, "gpy1"),
EXYNOS_PIN_BANK_EINTN(6, 0x160, "gpy2"),
EXYNOS_PIN_BANK_EINTN(8, 0x180, "gpy3"),
EXYNOS_PIN_BANK_EINTN(8, 0x1A0, "gpy4"),
EXYNOS_PIN_BANK_EINTN(8, 0x1C0, "gpy5"),
EXYNOS_PIN_BANK_EINTN(8, 0x1E0, "gpy6"),
EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08),
EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c),
};
/* pin banks of exynos4210 pin-controller 2 */
static const struct samsung_pin_bank_data exynos4210_pin_banks2[] __initconst = {
EXYNOS_PIN_BANK_EINTN(7, 0x000, "gpz"),
};
/* PMU pad retention groups registers for Exynos4 (without audio) */
static const u32 exynos4_retention_regs[] = {
S5P_PAD_RET_GPIO_OPTION,
S5P_PAD_RET_UART_OPTION,
S5P_PAD_RET_MMCA_OPTION,
S5P_PAD_RET_MMCB_OPTION,
S5P_PAD_RET_EBIA_OPTION,
S5P_PAD_RET_EBIB_OPTION,
};
static const struct samsung_retention_data exynos4_retention_data __initconst = {
.regs = exynos4_retention_regs,
.nr_regs = ARRAY_SIZE(exynos4_retention_regs),
.value = EXYNOS_WAKEUP_FROM_LOWPWR,
.refcnt = &exynos_shared_retention_refcnt,
.init = exynos_retention_init,
};
/* PMU retention control for audio pins can be tied to audio pin bank */
static const u32 exynos4_audio_retention_regs[] = {
S5P_PAD_RET_MAUDIO_OPTION,
};
static const struct samsung_retention_data exynos4_audio_retention_data __initconst = {
.regs = exynos4_audio_retention_regs,
.nr_regs = ARRAY_SIZE(exynos4_audio_retention_regs),
.value = EXYNOS_WAKEUP_FROM_LOWPWR,
.init = exynos_retention_init,
};
/*
* Samsung pinctrl driver data for Exynos4210 SoC. Exynos4210 SoC includes
* three gpio/pin-mux/pinconfig controllers.
*/
const struct samsung_pin_ctrl exynos4210_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 data */
.pin_banks = exynos4210_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos4210_pin_banks0),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos4_retention_data,
}, {
/* pin-controller instance 1 data */
.pin_banks = exynos4210_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos4210_pin_banks1),
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos4_retention_data,
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos4210_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos4210_pin_banks2),
.retention_data = &exynos4_audio_retention_data,
},
};
/* pin banks of exynos4x12 pin-controller 0 */
static const struct samsung_pin_bank_data exynos4x12_pin_banks0[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08),
EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c),
EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10),
EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpd0", 0x14),
EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpd1", 0x18),
EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpf0", 0x30),
EXYNOS_PIN_BANK_EINTG(8, 0x1A0, "gpf1", 0x34),
EXYNOS_PIN_BANK_EINTG(8, 0x1C0, "gpf2", 0x38),
EXYNOS_PIN_BANK_EINTG(6, 0x1E0, "gpf3", 0x3c),
EXYNOS_PIN_BANK_EINTG(8, 0x240, "gpj0", 0x40),
EXYNOS_PIN_BANK_EINTG(5, 0x260, "gpj1", 0x44),
};
/* pin banks of exynos4x12 pin-controller 1 */
static const struct samsung_pin_bank_data exynos4x12_pin_banks1[] __initconst = {
EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08),
EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c),
EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10),
EXYNOS_PIN_BANK_EINTG(7, 0x0A0, "gpk3", 0x14),
EXYNOS_PIN_BANK_EINTG(7, 0x0C0, "gpl0", 0x18),
EXYNOS_PIN_BANK_EINTG(2, 0x0E0, "gpl1", 0x1c),
EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpl2", 0x20),
EXYNOS_PIN_BANK_EINTG(8, 0x260, "gpm0", 0x24),
EXYNOS_PIN_BANK_EINTG(7, 0x280, "gpm1", 0x28),
EXYNOS_PIN_BANK_EINTG(5, 0x2A0, "gpm2", 0x2c),
EXYNOS_PIN_BANK_EINTG(8, 0x2C0, "gpm3", 0x30),
EXYNOS_PIN_BANK_EINTG(8, 0x2E0, "gpm4", 0x34),
EXYNOS_PIN_BANK_EINTN(6, 0x120, "gpy0"),
EXYNOS_PIN_BANK_EINTN(4, 0x140, "gpy1"),
EXYNOS_PIN_BANK_EINTN(6, 0x160, "gpy2"),
EXYNOS_PIN_BANK_EINTN(8, 0x180, "gpy3"),
EXYNOS_PIN_BANK_EINTN(8, 0x1A0, "gpy4"),
EXYNOS_PIN_BANK_EINTN(8, 0x1C0, "gpy5"),
EXYNOS_PIN_BANK_EINTN(8, 0x1E0, "gpy6"),
EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08),
EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c),
};
/* pin banks of exynos4x12 pin-controller 2 */
static const struct samsung_pin_bank_data exynos4x12_pin_banks2[] __initconst = {
EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00),
};
/* pin banks of exynos4x12 pin-controller 3 */
static const struct samsung_pin_bank_data exynos4x12_pin_banks3[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00),
EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpv2", 0x08),
EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpv3", 0x0c),
EXYNOS_PIN_BANK_EINTG(2, 0x080, "gpv4", 0x10),
};
/*
* Samsung pinctrl driver data for Exynos4x12 SoC. Exynos4x12 SoC includes
* four gpio/pin-mux/pinconfig controllers.
*/
const struct samsung_pin_ctrl exynos4x12_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 data */
.pin_banks = exynos4x12_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos4x12_pin_banks0),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos4_retention_data,
}, {
/* pin-controller instance 1 data */
.pin_banks = exynos4x12_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos4x12_pin_banks1),
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos4_retention_data,
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos4x12_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos4x12_pin_banks2),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos4_audio_retention_data,
}, {
/* pin-controller instance 3 data */
.pin_banks = exynos4x12_pin_banks3,
.nr_banks = ARRAY_SIZE(exynos4x12_pin_banks3),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
},
};
/* pin banks of exynos5250 pin-controller 0 */
static const struct samsung_pin_bank_data exynos5250_pin_banks0[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08),
EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpb0", 0x0c),
EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpb1", 0x10),
EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpb2", 0x14),
EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpb3", 0x18),
EXYNOS_PIN_BANK_EINTG(7, 0x0E0, "gpc0", 0x1c),
EXYNOS_PIN_BANK_EINTG(4, 0x100, "gpc1", 0x20),
EXYNOS_PIN_BANK_EINTG(7, 0x120, "gpc2", 0x24),
EXYNOS_PIN_BANK_EINTG(7, 0x140, "gpc3", 0x28),
EXYNOS_PIN_BANK_EINTG(4, 0x160, "gpd0", 0x2c),
EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpd1", 0x30),
EXYNOS_PIN_BANK_EINTG(7, 0x2E0, "gpc4", 0x34),
EXYNOS_PIN_BANK_EINTN(6, 0x1A0, "gpy0"),
EXYNOS_PIN_BANK_EINTN(4, 0x1C0, "gpy1"),
EXYNOS_PIN_BANK_EINTN(6, 0x1E0, "gpy2"),
EXYNOS_PIN_BANK_EINTN(8, 0x200, "gpy3"),
EXYNOS_PIN_BANK_EINTN(8, 0x220, "gpy4"),
EXYNOS_PIN_BANK_EINTN(8, 0x240, "gpy5"),
EXYNOS_PIN_BANK_EINTN(8, 0x260, "gpy6"),
EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08),
EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c),
};
/* pin banks of exynos5250 pin-controller 1 */
static const struct samsung_pin_bank_data exynos5250_pin_banks1[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpe0", 0x00),
EXYNOS_PIN_BANK_EINTG(2, 0x020, "gpe1", 0x04),
EXYNOS_PIN_BANK_EINTG(4, 0x040, "gpf0", 0x08),
EXYNOS_PIN_BANK_EINTG(4, 0x060, "gpf1", 0x0c),
EXYNOS_PIN_BANK_EINTG(8, 0x080, "gpg0", 0x10),
EXYNOS_PIN_BANK_EINTG(8, 0x0A0, "gpg1", 0x14),
EXYNOS_PIN_BANK_EINTG(2, 0x0C0, "gpg2", 0x18),
EXYNOS_PIN_BANK_EINTG(4, 0x0E0, "gph0", 0x1c),
EXYNOS_PIN_BANK_EINTG(8, 0x100, "gph1", 0x20),
};
/* pin banks of exynos5250 pin-controller 2 */
static const struct samsung_pin_bank_data exynos5250_pin_banks2[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00),
EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpv2", 0x08),
EXYNOS_PIN_BANK_EINTG(8, 0x080, "gpv3", 0x0c),
EXYNOS_PIN_BANK_EINTG(2, 0x0C0, "gpv4", 0x10),
};
/* pin banks of exynos5250 pin-controller 3 */
static const struct samsung_pin_bank_data exynos5250_pin_banks3[] __initconst = {
EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00),
};
/*
* Samsung pinctrl driver data for Exynos5250 SoC. Exynos5250 SoC includes
* four gpio/pin-mux/pinconfig controllers.
*/
const struct samsung_pin_ctrl exynos5250_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 data */
.pin_banks = exynos5250_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos5250_pin_banks0),
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos4_retention_data,
}, {
/* pin-controller instance 1 data */
.pin_banks = exynos5250_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos5250_pin_banks1),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos4_retention_data,
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos5250_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos5250_pin_banks2),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 3 data */
.pin_banks = exynos5250_pin_banks3,
.nr_banks = ARRAY_SIZE(exynos5250_pin_banks3),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos4_audio_retention_data,
},
};
/* pin banks of exynos5260 pin-controller 0 */
static const struct samsung_pin_bank_data exynos5260_pin_banks0[] __initconst = {
EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTG(7, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08),
EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpb0", 0x0c),
EXYNOS_PIN_BANK_EINTG(4, 0x080, "gpb1", 0x10),
EXYNOS_PIN_BANK_EINTG(5, 0x0a0, "gpb2", 0x14),
EXYNOS_PIN_BANK_EINTG(8, 0x0c0, "gpb3", 0x18),
EXYNOS_PIN_BANK_EINTG(8, 0x0e0, "gpb4", 0x1c),
EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpb5", 0x20),
EXYNOS_PIN_BANK_EINTG(8, 0x120, "gpd0", 0x24),
EXYNOS_PIN_BANK_EINTG(7, 0x140, "gpd1", 0x28),
EXYNOS_PIN_BANK_EINTG(5, 0x160, "gpd2", 0x2c),
EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpe0", 0x30),
EXYNOS_PIN_BANK_EINTG(5, 0x1a0, "gpe1", 0x34),
EXYNOS_PIN_BANK_EINTG(4, 0x1c0, "gpf0", 0x38),
EXYNOS_PIN_BANK_EINTG(8, 0x1e0, "gpf1", 0x3c),
EXYNOS_PIN_BANK_EINTG(2, 0x200, "gpk0", 0x40),
EXYNOS_PIN_BANK_EINTW(8, 0xc00, "gpx0", 0x00),
EXYNOS_PIN_BANK_EINTW(8, 0xc20, "gpx1", 0x04),
EXYNOS_PIN_BANK_EINTW(8, 0xc40, "gpx2", 0x08),
EXYNOS_PIN_BANK_EINTW(8, 0xc60, "gpx3", 0x0c),
};
/* pin banks of exynos5260 pin-controller 1 */
static const struct samsung_pin_bank_data exynos5260_pin_banks1[] __initconst = {
EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpc0", 0x00),
EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpc1", 0x04),
EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpc2", 0x08),
EXYNOS_PIN_BANK_EINTG(4, 0x060, "gpc3", 0x0c),
EXYNOS_PIN_BANK_EINTG(4, 0x080, "gpc4", 0x10),
};
/* pin banks of exynos5260 pin-controller 2 */
static const struct samsung_pin_bank_data exynos5260_pin_banks2[] __initconst = {
EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz0", 0x00),
EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04),
};
/*
* Samsung pinctrl driver data for Exynos5260 SoC. Exynos5260 SoC includes
* three gpio/pin-mux/pinconfig controllers.
*/
const struct samsung_pin_ctrl exynos5260_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 data */
.pin_banks = exynos5260_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos5260_pin_banks0),
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
}, {
/* pin-controller instance 1 data */
.pin_banks = exynos5260_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos5260_pin_banks1),
.eint_gpio_init = exynos_eint_gpio_init,
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos5260_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos5260_pin_banks2),
.eint_gpio_init = exynos_eint_gpio_init,
},
};
/* pin banks of exynos5410 pin-controller 0 */
static const struct samsung_pin_bank_data exynos5410_pin_banks0[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08),
EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpb0", 0x0c),
EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpb1", 0x10),
EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpb2", 0x14),
EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpb3", 0x18),
EXYNOS_PIN_BANK_EINTG(7, 0x0E0, "gpc0", 0x1c),
EXYNOS_PIN_BANK_EINTG(4, 0x100, "gpc3", 0x20),
EXYNOS_PIN_BANK_EINTG(7, 0x120, "gpc1", 0x24),
EXYNOS_PIN_BANK_EINTG(7, 0x140, "gpc2", 0x28),
EXYNOS_PIN_BANK_EINTN(2, 0x160, "gpm5"),
EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpd1", 0x2c),
EXYNOS_PIN_BANK_EINTG(8, 0x1A0, "gpe0", 0x30),
EXYNOS_PIN_BANK_EINTG(2, 0x1C0, "gpe1", 0x34),
EXYNOS_PIN_BANK_EINTG(6, 0x1E0, "gpf0", 0x38),
EXYNOS_PIN_BANK_EINTG(8, 0x200, "gpf1", 0x3c),
EXYNOS_PIN_BANK_EINTG(8, 0x220, "gpg0", 0x40),
EXYNOS_PIN_BANK_EINTG(8, 0x240, "gpg1", 0x44),
EXYNOS_PIN_BANK_EINTG(2, 0x260, "gpg2", 0x48),
EXYNOS_PIN_BANK_EINTG(4, 0x280, "gph0", 0x4c),
EXYNOS_PIN_BANK_EINTG(8, 0x2A0, "gph1", 0x50),
EXYNOS_PIN_BANK_EINTN(8, 0x2C0, "gpm7"),
EXYNOS_PIN_BANK_EINTN(6, 0x2E0, "gpy0"),
EXYNOS_PIN_BANK_EINTN(4, 0x300, "gpy1"),
EXYNOS_PIN_BANK_EINTN(6, 0x320, "gpy2"),
EXYNOS_PIN_BANK_EINTN(8, 0x340, "gpy3"),
EXYNOS_PIN_BANK_EINTN(8, 0x360, "gpy4"),
EXYNOS_PIN_BANK_EINTN(8, 0x380, "gpy5"),
EXYNOS_PIN_BANK_EINTN(8, 0x3A0, "gpy6"),
EXYNOS_PIN_BANK_EINTN(8, 0x3C0, "gpy7"),
EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08),
EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c),
};
/* pin banks of exynos5410 pin-controller 1 */
static const struct samsung_pin_bank_data exynos5410_pin_banks1[] __initconst = {
EXYNOS_PIN_BANK_EINTG(5, 0x000, "gpj0", 0x00),
EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpj1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpj2", 0x08),
EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpj3", 0x0c),
EXYNOS_PIN_BANK_EINTG(2, 0x080, "gpj4", 0x10),
EXYNOS_PIN_BANK_EINTG(8, 0x0A0, "gpk0", 0x14),
EXYNOS_PIN_BANK_EINTG(8, 0x0C0, "gpk1", 0x18),
EXYNOS_PIN_BANK_EINTG(8, 0x0E0, "gpk2", 0x1c),
EXYNOS_PIN_BANK_EINTG(7, 0x100, "gpk3", 0x20),
};
/* pin banks of exynos5410 pin-controller 2 */
static const struct samsung_pin_bank_data exynos5410_pin_banks2[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00),
EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpv2", 0x08),
EXYNOS_PIN_BANK_EINTG(8, 0x080, "gpv3", 0x0c),
EXYNOS_PIN_BANK_EINTG(2, 0x0C0, "gpv4", 0x10),
};
/* pin banks of exynos5410 pin-controller 3 */
static const struct samsung_pin_bank_data exynos5410_pin_banks3[] __initconst = {
EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00),
};
/*
* Samsung pinctrl driver data for Exynos5410 SoC. Exynos5410 SoC includes
* four gpio/pin-mux/pinconfig controllers.
*/
const struct samsung_pin_ctrl exynos5410_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 data */
.pin_banks = exynos5410_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos5410_pin_banks0),
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 1 data */
.pin_banks = exynos5410_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos5410_pin_banks1),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos5410_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos5410_pin_banks2),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 3 data */
.pin_banks = exynos5410_pin_banks3,
.nr_banks = ARRAY_SIZE(exynos5410_pin_banks3),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
},
};
/* pin banks of exynos5420 pin-controller 0 */
static const struct samsung_pin_bank_data exynos5420_pin_banks0[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpy7", 0x00),
EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08),
EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c),
};
/* pin banks of exynos5420 pin-controller 1 */
static const struct samsung_pin_bank_data exynos5420_pin_banks1[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpc0", 0x00),
EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpc1", 0x04),
EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpc2", 0x08),
EXYNOS_PIN_BANK_EINTG(4, 0x060, "gpc3", 0x0c),
EXYNOS_PIN_BANK_EINTG(2, 0x080, "gpc4", 0x10),
EXYNOS_PIN_BANK_EINTG(8, 0x0A0, "gpd1", 0x14),
EXYNOS_PIN_BANK_EINTN(6, 0x0C0, "gpy0"),
EXYNOS_PIN_BANK_EINTN(4, 0x0E0, "gpy1"),
EXYNOS_PIN_BANK_EINTN(6, 0x100, "gpy2"),
EXYNOS_PIN_BANK_EINTN(8, 0x120, "gpy3"),
EXYNOS_PIN_BANK_EINTN(8, 0x140, "gpy4"),
EXYNOS_PIN_BANK_EINTN(8, 0x160, "gpy5"),
EXYNOS_PIN_BANK_EINTN(8, 0x180, "gpy6"),
};
/* pin banks of exynos5420 pin-controller 2 */
static const struct samsung_pin_bank_data exynos5420_pin_banks2[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpe0", 0x00),
EXYNOS_PIN_BANK_EINTG(2, 0x020, "gpe1", 0x04),
EXYNOS_PIN_BANK_EINTG(6, 0x040, "gpf0", 0x08),
EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpf1", 0x0c),
EXYNOS_PIN_BANK_EINTG(8, 0x080, "gpg0", 0x10),
EXYNOS_PIN_BANK_EINTG(8, 0x0A0, "gpg1", 0x14),
EXYNOS_PIN_BANK_EINTG(2, 0x0C0, "gpg2", 0x18),
EXYNOS_PIN_BANK_EINTG(4, 0x0E0, "gpj4", 0x1c),
};
/* pin banks of exynos5420 pin-controller 3 */
static const struct samsung_pin_bank_data exynos5420_pin_banks3[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08),
EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpb0", 0x0c),
EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpb1", 0x10),
EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpb2", 0x14),
EXYNOS_PIN_BANK_EINTG(8, 0x0C0, "gpb3", 0x18),
EXYNOS_PIN_BANK_EINTG(2, 0x0E0, "gpb4", 0x1c),
EXYNOS_PIN_BANK_EINTG(8, 0x100, "gph0", 0x20),
};
/* pin banks of exynos5420 pin-controller 4 */
static const struct samsung_pin_bank_data exynos5420_pin_banks4[] __initconst = {
EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00),
};
/* PMU pad retention groups registers for Exynos5420 (without audio) */
static const u32 exynos5420_retention_regs[] = {
EXYNOS_PAD_RET_DRAM_OPTION,
EXYNOS_PAD_RET_JTAG_OPTION,
EXYNOS5420_PAD_RET_GPIO_OPTION,
EXYNOS5420_PAD_RET_UART_OPTION,
EXYNOS5420_PAD_RET_MMCA_OPTION,
EXYNOS5420_PAD_RET_MMCB_OPTION,
EXYNOS5420_PAD_RET_MMCC_OPTION,
EXYNOS5420_PAD_RET_HSI_OPTION,
EXYNOS_PAD_RET_EBIA_OPTION,
EXYNOS_PAD_RET_EBIB_OPTION,
EXYNOS5420_PAD_RET_SPI_OPTION,
EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION,
};
static const struct samsung_retention_data exynos5420_retention_data __initconst = {
.regs = exynos5420_retention_regs,
.nr_regs = ARRAY_SIZE(exynos5420_retention_regs),
.value = EXYNOS_WAKEUP_FROM_LOWPWR,
.refcnt = &exynos_shared_retention_refcnt,
.init = exynos_retention_init,
};
/*
* Samsung pinctrl driver data for Exynos5420 SoC. Exynos5420 SoC includes
* four gpio/pin-mux/pinconfig controllers.
*/
const struct samsung_pin_ctrl exynos5420_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 data */
.pin_banks = exynos5420_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks0),
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.retention_data = &exynos5420_retention_data,
}, {
/* pin-controller instance 1 data */
.pin_banks = exynos5420_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks1),
.eint_gpio_init = exynos_eint_gpio_init,
.retention_data = &exynos5420_retention_data,
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos5420_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks2),
.eint_gpio_init = exynos_eint_gpio_init,
.retention_data = &exynos5420_retention_data,
}, {
/* pin-controller instance 3 data */
.pin_banks = exynos5420_pin_banks3,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks3),
.eint_gpio_init = exynos_eint_gpio_init,
.retention_data = &exynos5420_retention_data,
}, {
/* pin-controller instance 4 data */
.pin_banks = exynos5420_pin_banks4,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks4),
.eint_gpio_init = exynos_eint_gpio_init,
.retention_data = &exynos4_audio_retention_data,
},
};

View File

@ -0,0 +1,399 @@
/*
* Exynos ARMv8 specific support for Samsung pinctrl/gpiolib driver
* with eint support.
*
* Copyright (c) 2012 Samsung Electronics Co., Ltd.
* http://www.samsung.com
* Copyright (c) 2012 Linaro Ltd
* http://www.linaro.org
* Copyright (c) 2017 Krzysztof Kozlowski <krzk@kernel.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This file contains the Samsung Exynos specific information required by the
* the Samsung pinctrl/gpiolib driver. It also includes the implementation of
* external gpio and wakeup interrupt support.
*/
#include <linux/slab.h>
#include <linux/soc/samsung/exynos-regs-pmu.h>
#include "pinctrl-samsung.h"
#include "pinctrl-exynos.h"
static const struct samsung_pin_bank_type bank_type_off = {
.fld_width = { 4, 1, 2, 2, 2, 2, },
.reg_offset = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, },
};
static const struct samsung_pin_bank_type bank_type_alive = {
.fld_width = { 4, 1, 2, 2, },
.reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
};
/* Exynos5433 has the 4bit widths for PINCFG_TYPE_DRV bitfields. */
static const struct samsung_pin_bank_type exynos5433_bank_type_off = {
.fld_width = { 4, 1, 2, 4, 2, 2, },
.reg_offset = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, },
};
static const struct samsung_pin_bank_type exynos5433_bank_type_alive = {
.fld_width = { 4, 1, 2, 4, },
.reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
};
/* Pad retention control code for accessing PMU regmap */
static atomic_t exynos_shared_retention_refcnt;
/* pin banks of exynos5433 pin-controller - ALIVE */
static const struct samsung_pin_bank_data exynos5433_pin_banks0[] __initconst = {
EXYNOS5433_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00),
EXYNOS5433_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04),
EXYNOS5433_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08),
EXYNOS5433_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c),
EXYNOS5433_PIN_BANK_EINTW_EXT(8, 0x020, "gpf1", 0x1004, 1),
EXYNOS5433_PIN_BANK_EINTW_EXT(4, 0x040, "gpf2", 0x1008, 1),
EXYNOS5433_PIN_BANK_EINTW_EXT(4, 0x060, "gpf3", 0x100c, 1),
EXYNOS5433_PIN_BANK_EINTW_EXT(8, 0x080, "gpf4", 0x1010, 1),
EXYNOS5433_PIN_BANK_EINTW_EXT(8, 0x0a0, "gpf5", 0x1014, 1),
};
/* pin banks of exynos5433 pin-controller - AUD */
static const struct samsung_pin_bank_data exynos5433_pin_banks1[] __initconst = {
EXYNOS5433_PIN_BANK_EINTG(7, 0x000, "gpz0", 0x00),
EXYNOS5433_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04),
};
/* pin banks of exynos5433 pin-controller - CPIF */
static const struct samsung_pin_bank_data exynos5433_pin_banks2[] __initconst = {
EXYNOS5433_PIN_BANK_EINTG(2, 0x000, "gpv6", 0x00),
};
/* pin banks of exynos5433 pin-controller - eSE */
static const struct samsung_pin_bank_data exynos5433_pin_banks3[] __initconst = {
EXYNOS5433_PIN_BANK_EINTG(3, 0x000, "gpj2", 0x00),
};
/* pin banks of exynos5433 pin-controller - FINGER */
static const struct samsung_pin_bank_data exynos5433_pin_banks4[] __initconst = {
EXYNOS5433_PIN_BANK_EINTG(4, 0x000, "gpd5", 0x00),
};
/* pin banks of exynos5433 pin-controller - FSYS */
static const struct samsung_pin_bank_data exynos5433_pin_banks5[] __initconst = {
EXYNOS5433_PIN_BANK_EINTG(6, 0x000, "gph1", 0x00),
EXYNOS5433_PIN_BANK_EINTG(7, 0x020, "gpr4", 0x04),
EXYNOS5433_PIN_BANK_EINTG(5, 0x040, "gpr0", 0x08),
EXYNOS5433_PIN_BANK_EINTG(8, 0x060, "gpr1", 0x0c),
EXYNOS5433_PIN_BANK_EINTG(2, 0x080, "gpr2", 0x10),
EXYNOS5433_PIN_BANK_EINTG(8, 0x0a0, "gpr3", 0x14),
};
/* pin banks of exynos5433 pin-controller - IMEM */
static const struct samsung_pin_bank_data exynos5433_pin_banks6[] __initconst = {
EXYNOS5433_PIN_BANK_EINTG(8, 0x000, "gpf0", 0x00),
};
/* pin banks of exynos5433 pin-controller - NFC */
static const struct samsung_pin_bank_data exynos5433_pin_banks7[] __initconst = {
EXYNOS5433_PIN_BANK_EINTG(3, 0x000, "gpj0", 0x00),
};
/* pin banks of exynos5433 pin-controller - PERIC */
static const struct samsung_pin_bank_data exynos5433_pin_banks8[] __initconst = {
EXYNOS5433_PIN_BANK_EINTG(6, 0x000, "gpv7", 0x00),
EXYNOS5433_PIN_BANK_EINTG(5, 0x020, "gpb0", 0x04),
EXYNOS5433_PIN_BANK_EINTG(8, 0x040, "gpc0", 0x08),
EXYNOS5433_PIN_BANK_EINTG(2, 0x060, "gpc1", 0x0c),
EXYNOS5433_PIN_BANK_EINTG(6, 0x080, "gpc2", 0x10),
EXYNOS5433_PIN_BANK_EINTG(8, 0x0a0, "gpc3", 0x14),
EXYNOS5433_PIN_BANK_EINTG(2, 0x0c0, "gpg0", 0x18),
EXYNOS5433_PIN_BANK_EINTG(4, 0x0e0, "gpd0", 0x1c),
EXYNOS5433_PIN_BANK_EINTG(6, 0x100, "gpd1", 0x20),
EXYNOS5433_PIN_BANK_EINTG(8, 0x120, "gpd2", 0x24),
EXYNOS5433_PIN_BANK_EINTG(5, 0x140, "gpd4", 0x28),
EXYNOS5433_PIN_BANK_EINTG(2, 0x160, "gpd8", 0x2c),
EXYNOS5433_PIN_BANK_EINTG(7, 0x180, "gpd6", 0x30),
EXYNOS5433_PIN_BANK_EINTG(3, 0x1a0, "gpd7", 0x34),
EXYNOS5433_PIN_BANK_EINTG(5, 0x1c0, "gpg1", 0x38),
EXYNOS5433_PIN_BANK_EINTG(2, 0x1e0, "gpg2", 0x3c),
EXYNOS5433_PIN_BANK_EINTG(8, 0x200, "gpg3", 0x40),
};
/* pin banks of exynos5433 pin-controller - TOUCH */
static const struct samsung_pin_bank_data exynos5433_pin_banks9[] __initconst = {
EXYNOS5433_PIN_BANK_EINTG(3, 0x000, "gpj1", 0x00),
};
/* PMU pin retention groups registers for Exynos5433 (without audio & fsys) */
static const u32 exynos5433_retention_regs[] = {
EXYNOS5433_PAD_RETENTION_TOP_OPTION,
EXYNOS5433_PAD_RETENTION_UART_OPTION,
EXYNOS5433_PAD_RETENTION_EBIA_OPTION,
EXYNOS5433_PAD_RETENTION_EBIB_OPTION,
EXYNOS5433_PAD_RETENTION_SPI_OPTION,
EXYNOS5433_PAD_RETENTION_MIF_OPTION,
EXYNOS5433_PAD_RETENTION_USBXTI_OPTION,
EXYNOS5433_PAD_RETENTION_BOOTLDO_OPTION,
EXYNOS5433_PAD_RETENTION_UFS_OPTION,
EXYNOS5433_PAD_RETENTION_FSYSGENIO_OPTION,
};
static const struct samsung_retention_data exynos5433_retention_data __initconst = {
.regs = exynos5433_retention_regs,
.nr_regs = ARRAY_SIZE(exynos5433_retention_regs),
.value = EXYNOS_WAKEUP_FROM_LOWPWR,
.refcnt = &exynos_shared_retention_refcnt,
.init = exynos_retention_init,
};
/* PMU retention control for audio pins can be tied to audio pin bank */
static const u32 exynos5433_audio_retention_regs[] = {
EXYNOS5433_PAD_RETENTION_AUD_OPTION,
};
static const struct samsung_retention_data exynos5433_audio_retention_data __initconst = {
.regs = exynos5433_audio_retention_regs,
.nr_regs = ARRAY_SIZE(exynos5433_audio_retention_regs),
.value = EXYNOS_WAKEUP_FROM_LOWPWR,
.init = exynos_retention_init,
};
/* PMU retention control for mmc pins can be tied to fsys pin bank */
static const u32 exynos5433_fsys_retention_regs[] = {
EXYNOS5433_PAD_RETENTION_MMC0_OPTION,
EXYNOS5433_PAD_RETENTION_MMC1_OPTION,
EXYNOS5433_PAD_RETENTION_MMC2_OPTION,
};
static const struct samsung_retention_data exynos5433_fsys_retention_data __initconst = {
.regs = exynos5433_fsys_retention_regs,
.nr_regs = ARRAY_SIZE(exynos5433_fsys_retention_regs),
.value = EXYNOS_WAKEUP_FROM_LOWPWR,
.init = exynos_retention_init,
};
/*
* Samsung pinctrl driver data for Exynos5433 SoC. Exynos5433 SoC includes
* ten gpio/pin-mux/pinconfig controllers.
*/
const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 data */
.pin_banks = exynos5433_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks0),
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.nr_ext_resources = 1,
.retention_data = &exynos5433_retention_data,
}, {
/* pin-controller instance 1 data */
.pin_banks = exynos5433_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks1),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos5433_audio_retention_data,
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos5433_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks2),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos5433_retention_data,
}, {
/* pin-controller instance 3 data */
.pin_banks = exynos5433_pin_banks3,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks3),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos5433_retention_data,
}, {
/* pin-controller instance 4 data */
.pin_banks = exynos5433_pin_banks4,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks4),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos5433_retention_data,
}, {
/* pin-controller instance 5 data */
.pin_banks = exynos5433_pin_banks5,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks5),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos5433_fsys_retention_data,
}, {
/* pin-controller instance 6 data */
.pin_banks = exynos5433_pin_banks6,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks6),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos5433_retention_data,
}, {
/* pin-controller instance 7 data */
.pin_banks = exynos5433_pin_banks7,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks7),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos5433_retention_data,
}, {
/* pin-controller instance 8 data */
.pin_banks = exynos5433_pin_banks8,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks8),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos5433_retention_data,
}, {
/* pin-controller instance 9 data */
.pin_banks = exynos5433_pin_banks9,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks9),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos5433_retention_data,
},
};
/* pin banks of exynos7 pin-controller - ALIVE */
static const struct samsung_pin_bank_data exynos7_pin_banks0[] __initconst = {
EXYNOS_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08),
EXYNOS_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c),
};
/* pin banks of exynos7 pin-controller - BUS0 */
static const struct samsung_pin_bank_data exynos7_pin_banks1[] __initconst = {
EXYNOS_PIN_BANK_EINTG(5, 0x000, "gpb0", 0x00),
EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpc0", 0x04),
EXYNOS_PIN_BANK_EINTG(2, 0x040, "gpc1", 0x08),
EXYNOS_PIN_BANK_EINTG(6, 0x060, "gpc2", 0x0c),
EXYNOS_PIN_BANK_EINTG(8, 0x080, "gpc3", 0x10),
EXYNOS_PIN_BANK_EINTG(4, 0x0a0, "gpd0", 0x14),
EXYNOS_PIN_BANK_EINTG(6, 0x0c0, "gpd1", 0x18),
EXYNOS_PIN_BANK_EINTG(8, 0x0e0, "gpd2", 0x1c),
EXYNOS_PIN_BANK_EINTG(5, 0x100, "gpd4", 0x20),
EXYNOS_PIN_BANK_EINTG(4, 0x120, "gpd5", 0x24),
EXYNOS_PIN_BANK_EINTG(6, 0x140, "gpd6", 0x28),
EXYNOS_PIN_BANK_EINTG(3, 0x160, "gpd7", 0x2c),
EXYNOS_PIN_BANK_EINTG(2, 0x180, "gpd8", 0x30),
EXYNOS_PIN_BANK_EINTG(2, 0x1a0, "gpg0", 0x34),
EXYNOS_PIN_BANK_EINTG(4, 0x1c0, "gpg3", 0x38),
};
/* pin banks of exynos7 pin-controller - NFC */
static const struct samsung_pin_bank_data exynos7_pin_banks2[] __initconst = {
EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj0", 0x00),
};
/* pin banks of exynos7 pin-controller - TOUCH */
static const struct samsung_pin_bank_data exynos7_pin_banks3[] __initconst = {
EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj1", 0x00),
};
/* pin banks of exynos7 pin-controller - FF */
static const struct samsung_pin_bank_data exynos7_pin_banks4[] __initconst = {
EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpg4", 0x00),
};
/* pin banks of exynos7 pin-controller - ESE */
static const struct samsung_pin_bank_data exynos7_pin_banks5[] __initconst = {
EXYNOS_PIN_BANK_EINTG(5, 0x000, "gpv7", 0x00),
};
/* pin banks of exynos7 pin-controller - FSYS0 */
static const struct samsung_pin_bank_data exynos7_pin_banks6[] __initconst = {
EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpr4", 0x00),
};
/* pin banks of exynos7 pin-controller - FSYS1 */
static const struct samsung_pin_bank_data exynos7_pin_banks7[] __initconst = {
EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpr0", 0x00),
EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpr1", 0x04),
EXYNOS_PIN_BANK_EINTG(5, 0x040, "gpr2", 0x08),
EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpr3", 0x0c),
};
/* pin banks of exynos7 pin-controller - BUS1 */
static const struct samsung_pin_bank_data exynos7_pin_banks8[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpf0", 0x00),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpf1", 0x04),
EXYNOS_PIN_BANK_EINTG(4, 0x060, "gpf2", 0x08),
EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpf3", 0x0c),
EXYNOS_PIN_BANK_EINTG(8, 0x0a0, "gpf4", 0x10),
EXYNOS_PIN_BANK_EINTG(8, 0x0c0, "gpf5", 0x14),
EXYNOS_PIN_BANK_EINTG(5, 0x0e0, "gpg1", 0x18),
EXYNOS_PIN_BANK_EINTG(5, 0x100, "gpg2", 0x1c),
EXYNOS_PIN_BANK_EINTG(6, 0x120, "gph1", 0x20),
EXYNOS_PIN_BANK_EINTG(3, 0x140, "gpv6", 0x24),
};
static const struct samsung_pin_bank_data exynos7_pin_banks9[] __initconst = {
EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz0", 0x00),
EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04),
};
const struct samsung_pin_ctrl exynos7_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 Alive data */
.pin_banks = exynos7_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos7_pin_banks0),
.eint_wkup_init = exynos_eint_wkup_init,
}, {
/* pin-controller instance 1 BUS0 data */
.pin_banks = exynos7_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos7_pin_banks1),
.eint_gpio_init = exynos_eint_gpio_init,
}, {
/* pin-controller instance 2 NFC data */
.pin_banks = exynos7_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos7_pin_banks2),
.eint_gpio_init = exynos_eint_gpio_init,
}, {
/* pin-controller instance 3 TOUCH data */
.pin_banks = exynos7_pin_banks3,
.nr_banks = ARRAY_SIZE(exynos7_pin_banks3),
.eint_gpio_init = exynos_eint_gpio_init,
}, {
/* pin-controller instance 4 FF data */
.pin_banks = exynos7_pin_banks4,
.nr_banks = ARRAY_SIZE(exynos7_pin_banks4),
.eint_gpio_init = exynos_eint_gpio_init,
}, {
/* pin-controller instance 5 ESE data */
.pin_banks = exynos7_pin_banks5,
.nr_banks = ARRAY_SIZE(exynos7_pin_banks5),
.eint_gpio_init = exynos_eint_gpio_init,
}, {
/* pin-controller instance 6 FSYS0 data */
.pin_banks = exynos7_pin_banks6,
.nr_banks = ARRAY_SIZE(exynos7_pin_banks6),
.eint_gpio_init = exynos_eint_gpio_init,
}, {
/* pin-controller instance 7 FSYS1 data */
.pin_banks = exynos7_pin_banks7,
.nr_banks = ARRAY_SIZE(exynos7_pin_banks7),
.eint_gpio_init = exynos_eint_gpio_init,
}, {
/* pin-controller instance 8 BUS1 data */
.pin_banks = exynos7_pin_banks8,
.nr_banks = ARRAY_SIZE(exynos7_pin_banks8),
.eint_gpio_init = exynos_eint_gpio_init,
}, {
/* pin-controller instance 9 AUD data */
.pin_banks = exynos7_pin_banks9,
.nr_banks = ARRAY_SIZE(exynos7_pin_banks9),
.eint_gpio_init = exynos_eint_gpio_init,
},
};

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,9 @@
* (at your option) any later version.
*/
#ifndef __PINCTRL_SAMSUNG_EXYNOS_H
#define __PINCTRL_SAMSUNG_EXYNOS_H
/* External GPIO and wakeup interrupt related definitions */
#define EXYNOS_GPIO_ECON_OFFSET 0x700
#define EXYNOS_GPIO_EFLTCON_OFFSET 0x800
@ -131,3 +134,13 @@ struct exynos_muxed_weint_data {
unsigned int nr_banks;
struct samsung_pin_bank *banks[];
};
int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d);
int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d);
void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata);
void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata);
struct samsung_retention_ctrl *
exynos_retention_init(struct samsung_pinctrl_drv_data *drvdata,
const struct samsung_retention_data *data);
#endif /* __PINCTRL_SAMSUNG_EXYNOS_H */

View File

@ -1,6 +1,8 @@
/*
* pin-controller/pin-mux/pin-config/gpio-driver for Samsung's EXYNOS5440 SoC.
*
* Author: Thomas Abraham <thomas.ab@samsung.com>
*
* Copyright (c) 2012 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
@ -10,7 +12,7 @@
* (at your option) any later version.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/slab.h>
@ -991,7 +993,6 @@ static const struct of_device_id exynos5440_pinctrl_dt_match[] = {
{ .compatible = "samsung,exynos5440-pinctrl" },
{},
};
MODULE_DEVICE_TABLE(of, exynos5440_pinctrl_dt_match);
static struct platform_driver exynos5440_pinctrl_driver = {
.probe = exynos5440_pinctrl_probe,
@ -1007,13 +1008,3 @@ static int __init exynos5440_pinctrl_drv_register(void)
return platform_driver_register(&exynos5440_pinctrl_driver);
}
postcore_initcall(exynos5440_pinctrl_drv_register);
static void __exit exynos5440_pinctrl_drv_unregister(void)
{
platform_driver_unregister(&exynos5440_pinctrl_driver);
}
module_exit(exynos5440_pinctrl_drv_unregister);
MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");
MODULE_DESCRIPTION("Samsung EXYNOS5440 SoC pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -13,7 +13,7 @@
* external gpio and wakeup interrupt support.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>

View File

@ -15,7 +15,7 @@
* external gpio and wakeup interrupt support.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>

View File

@ -20,7 +20,7 @@
* and wakeup interrupts can be hooked to.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/slab.h>
@ -1183,27 +1183,29 @@ static int __maybe_unused samsung_pinctrl_resume(struct device *dev)
}
static const struct of_device_id samsung_pinctrl_dt_match[] = {
#ifdef CONFIG_PINCTRL_EXYNOS
#ifdef CONFIG_PINCTRL_EXYNOS_ARM
{ .compatible = "samsung,exynos3250-pinctrl",
.data = (void *)exynos3250_pin_ctrl },
.data = exynos3250_pin_ctrl },
{ .compatible = "samsung,exynos4210-pinctrl",
.data = (void *)exynos4210_pin_ctrl },
.data = exynos4210_pin_ctrl },
{ .compatible = "samsung,exynos4x12-pinctrl",
.data = (void *)exynos4x12_pin_ctrl },
.data = exynos4x12_pin_ctrl },
{ .compatible = "samsung,exynos5250-pinctrl",
.data = (void *)exynos5250_pin_ctrl },
.data = exynos5250_pin_ctrl },
{ .compatible = "samsung,exynos5260-pinctrl",
.data = (void *)exynos5260_pin_ctrl },
.data = exynos5260_pin_ctrl },
{ .compatible = "samsung,exynos5410-pinctrl",
.data = (void *)exynos5410_pin_ctrl },
.data = exynos5410_pin_ctrl },
{ .compatible = "samsung,exynos5420-pinctrl",
.data = (void *)exynos5420_pin_ctrl },
{ .compatible = "samsung,exynos5433-pinctrl",
.data = (void *)exynos5433_pin_ctrl },
.data = exynos5420_pin_ctrl },
{ .compatible = "samsung,s5pv210-pinctrl",
.data = (void *)s5pv210_pin_ctrl },
.data = s5pv210_pin_ctrl },
#endif
#ifdef CONFIG_PINCTRL_EXYNOS_ARM64
{ .compatible = "samsung,exynos5433-pinctrl",
.data = exynos5433_pin_ctrl },
{ .compatible = "samsung,exynos7-pinctrl",
.data = (void *)exynos7_pin_ctrl },
.data = exynos7_pin_ctrl },
#endif
#ifdef CONFIG_PINCTRL_S3C64XX
{ .compatible = "samsung,s3c64xx-pinctrl",
@ -1221,7 +1223,6 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
#endif
{},
};
MODULE_DEVICE_TABLE(of, samsung_pinctrl_dt_match);
static const struct dev_pm_ops samsung_pinctrl_pm_ops = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(samsung_pinctrl_suspend,
@ -1243,13 +1244,3 @@ static int __init samsung_pinctrl_drv_register(void)
return platform_driver_register(&samsung_pinctrl_driver);
}
postcore_initcall(samsung_pinctrl_drv_register);
static void __exit samsung_pinctrl_drv_unregister(void)
{
platform_driver_unregister(&samsung_pinctrl_driver);
}
module_exit(samsung_pinctrl_drv_unregister);
MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");
MODULE_DESCRIPTION("Samsung pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -34,6 +34,16 @@ config PINCTRL_PFC_R8A7740
depends on ARCH_R8A7740
select PINCTRL_SH_PFC_GPIO
config PINCTRL_PFC_R8A7743
def_bool y
depends on ARCH_R8A7743
select PINCTRL_SH_PFC
config PINCTRL_PFC_R8A7745
def_bool y
depends on ARCH_R8A7745
select PINCTRL_SH_PFC
config PINCTRL_PFC_R8A7778
def_bool y
depends on ARCH_R8A7778

View File

@ -3,6 +3,8 @@ obj-$(CONFIG_PINCTRL_SH_PFC_GPIO) += gpio.o
obj-$(CONFIG_PINCTRL_PFC_EMEV2) += pfc-emev2.o
obj-$(CONFIG_PINCTRL_PFC_R8A73A4) += pfc-r8a73a4.o
obj-$(CONFIG_PINCTRL_PFC_R8A7740) += pfc-r8a7740.o
obj-$(CONFIG_PINCTRL_PFC_R8A7743) += pfc-r8a7791.o
obj-$(CONFIG_PINCTRL_PFC_R8A7745) += pfc-r8a7794.o
obj-$(CONFIG_PINCTRL_PFC_R8A7778) += pfc-r8a7778.o
obj-$(CONFIG_PINCTRL_PFC_R8A7779) += pfc-r8a7779.o
obj-$(CONFIG_PINCTRL_PFC_R8A7790) += pfc-r8a7790.o

View File

@ -485,6 +485,18 @@ static const struct of_device_id sh_pfc_of_table[] = {
.data = &r8a7740_pinmux_info,
},
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A7743
{
.compatible = "renesas,pfc-r8a7743",
.data = &r8a7743_pinmux_info,
},
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A7745
{
.compatible = "renesas,pfc-r8a7745",
.data = &r8a7745_pinmux_info,
},
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A7778
{
.compatible = "renesas,pfc-r8a7778",

File diff suppressed because it is too large Load Diff

View File

@ -1137,6 +1137,43 @@ static const unsigned int scif0_ctrl_pins[] = {
static const unsigned int scif0_ctrl_mux[] = {
RTS0_N_MARK, CTS0_N_MARK,
};
/* - SCIF1 ------------------------------------------------------------------ */
static const unsigned int scif1_data_pins[] = {
/* RX, TX */
RCAR_GP_PIN(10, 19), RCAR_GP_PIN(10, 18),
};
static const unsigned int scif1_data_mux[] = {
RX1_MARK, TX1_MARK,
};
static const unsigned int scif1_clk_pins[] = {
/* SCK */
RCAR_GP_PIN(10, 15),
};
static const unsigned int scif1_clk_mux[] = {
SCK1_MARK,
};
static const unsigned int scif1_ctrl_pins[] = {
/* RTS, CTS */
RCAR_GP_PIN(10, 17), RCAR_GP_PIN(10, 16),
};
static const unsigned int scif1_ctrl_mux[] = {
RTS1_N_MARK, CTS1_N_MARK,
};
/* - SCIF2 ------------------------------------------------------------------ */
static const unsigned int scif2_data_pins[] = {
/* RX, TX */
RCAR_GP_PIN(10, 22), RCAR_GP_PIN(10, 21),
};
static const unsigned int scif2_data_mux[] = {
RX2_MARK, TX2_MARK,
};
static const unsigned int scif2_clk_pins[] = {
/* SCK */
RCAR_GP_PIN(10, 20),
};
static const unsigned int scif2_clk_mux[] = {
SCK2_MARK,
};
/* - SCIF3 ------------------------------------------------------------------ */
static const unsigned int scif3_data_pins[] = {
/* RX, TX */
@ -1680,6 +1717,11 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(scif0_data),
SH_PFC_PIN_GROUP(scif0_clk),
SH_PFC_PIN_GROUP(scif0_ctrl),
SH_PFC_PIN_GROUP(scif1_data),
SH_PFC_PIN_GROUP(scif1_clk),
SH_PFC_PIN_GROUP(scif1_ctrl),
SH_PFC_PIN_GROUP(scif2_data),
SH_PFC_PIN_GROUP(scif2_clk),
SH_PFC_PIN_GROUP(scif3_data),
SH_PFC_PIN_GROUP(scif3_clk),
SH_PFC_PIN_GROUP(sdhi0_data1),
@ -1826,6 +1868,17 @@ static const char * const scif0_groups[] = {
"scif0_ctrl",
};
static const char * const scif1_groups[] = {
"scif1_data",
"scif1_clk",
"scif1_ctrl",
};
static const char * const scif2_groups[] = {
"scif2_data",
"scif2_clk",
};
static const char * const scif3_groups[] = {
"scif3_data",
"scif3_clk",
@ -1924,6 +1977,8 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(msiof1),
SH_PFC_FUNCTION(qspi),
SH_PFC_FUNCTION(scif0),
SH_PFC_FUNCTION(scif1),
SH_PFC_FUNCTION(scif2),
SH_PFC_FUNCTION(scif3),
SH_PFC_FUNCTION(sdhi0),
SH_PFC_FUNCTION(vin0),

File diff suppressed because it is too large Load Diff

View File

@ -192,8 +192,8 @@
#define GPSR6_9 F_(SSI_WS4, IP14_27_24)
#define GPSR6_8 F_(SSI_SCK4, IP14_23_20)
#define GPSR6_7 F_(SSI_SDATA3, IP14_19_16)
#define GPSR6_6 F_(SSI_WS34, IP14_15_12)
#define GPSR6_5 F_(SSI_SCK34, IP14_11_8)
#define GPSR6_6 F_(SSI_WS349, IP14_15_12)
#define GPSR6_5 F_(SSI_SCK349, IP14_11_8)
#define GPSR6_4 F_(SSI_SDATA2_A, IP14_7_4)
#define GPSR6_3 F_(SSI_SDATA1_A, IP14_3_0)
#define GPSR6_2 F_(SSI_SDATA0, IP13_31_28)
@ -328,8 +328,8 @@
#define IP13_31_28 FM(SSI_SDATA0) F_(0, 0) FM(MSIOF1_SS2_F) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP14_3_0 FM(SSI_SDATA1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP14_7_4 FM(SSI_SDATA2_A) F_(0, 0) F_(0, 0) F_(0, 0) FM(SSI_SCK1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP14_11_8 FM(SSI_SCK34) F_(0, 0) FM(MSIOF1_SS1_A) F_(0, 0) F_(0, 0) F_(0, 0) FM(STP_OPWM_0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP14_15_12 FM(SSI_WS34) FM(HCTS2_N_A) FM(MSIOF1_SS2_A) F_(0, 0) F_(0, 0) F_(0, 0) FM(STP_IVCXO27_0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP14_11_8 FM(SSI_SCK349) F_(0, 0) FM(MSIOF1_SS1_A) F_(0, 0) F_(0, 0) F_(0, 0) FM(STP_OPWM_0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP14_15_12 FM(SSI_WS349) FM(HCTS2_N_A) FM(MSIOF1_SS2_A) F_(0, 0) F_(0, 0) F_(0, 0) FM(STP_IVCXO27_0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP14_19_16 FM(SSI_SDATA3) FM(HRTS2_N_A) FM(MSIOF1_TXD_A) F_(0, 0) F_(0, 0) FM(TS_SCK0_A) FM(STP_ISCLK_0_A) FM(RIF0_D1_A) FM(RIF2_D0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP14_23_20 FM(SSI_SCK4) FM(HRX2_A) FM(MSIOF1_SCK_A) F_(0, 0) F_(0, 0) FM(TS_SDAT0_A) FM(STP_ISD_0_A) FM(RIF0_CLK_A) FM(RIF2_CLK_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP14_27_24 FM(SSI_WS4) FM(HTX2_A) FM(MSIOF1_SYNC_A) F_(0, 0) F_(0, 0) FM(TS_SDEN0_A) FM(STP_ISEN_0_A) FM(RIF0_SYNC_A) FM(RIF2_SYNC_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
@ -1256,11 +1256,11 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_MSEL(IP14_7_4, SSI_SDATA2_A, SEL_SSI_0),
PINMUX_IPSR_MSEL(IP14_7_4, SSI_SCK1_B, SEL_SSI_1),
PINMUX_IPSR_GPSR(IP14_11_8, SSI_SCK34),
PINMUX_IPSR_GPSR(IP14_11_8, SSI_SCK349),
PINMUX_IPSR_MSEL(IP14_11_8, MSIOF1_SS1_A, SEL_MSIOF1_0),
PINMUX_IPSR_MSEL(IP14_11_8, STP_OPWM_0_A, SEL_SSP1_0_0),
PINMUX_IPSR_GPSR(IP14_15_12, SSI_WS34),
PINMUX_IPSR_GPSR(IP14_15_12, SSI_WS349),
PINMUX_IPSR_MSEL(IP14_15_12, HCTS2_N_A, SEL_HSCIF2_0),
PINMUX_IPSR_MSEL(IP14_15_12, MSIOF1_SS2_A, SEL_MSIOF1_0),
PINMUX_IPSR_MSEL(IP14_15_12, STP_IVCXO27_0_A, SEL_SSP1_0_0),
@ -3650,12 +3650,12 @@ static const unsigned int ssi3_data_pins[] = {
static const unsigned int ssi3_data_mux[] = {
SSI_SDATA3_MARK,
};
static const unsigned int ssi34_ctrl_pins[] = {
static const unsigned int ssi349_ctrl_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(6, 5), RCAR_GP_PIN(6, 6),
};
static const unsigned int ssi34_ctrl_mux[] = {
SSI_SCK34_MARK, SSI_WS34_MARK,
static const unsigned int ssi349_ctrl_mux[] = {
SSI_SCK349_MARK, SSI_WS349_MARK,
};
static const unsigned int ssi4_data_pins[] = {
/* SDATA */
@ -4063,7 +4063,7 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(ssi2_ctrl_a),
SH_PFC_PIN_GROUP(ssi2_ctrl_b),
SH_PFC_PIN_GROUP(ssi3_data),
SH_PFC_PIN_GROUP(ssi34_ctrl),
SH_PFC_PIN_GROUP(ssi349_ctrl),
SH_PFC_PIN_GROUP(ssi4_data),
SH_PFC_PIN_GROUP(ssi4_ctrl),
SH_PFC_PIN_GROUP(ssi5_data),
@ -4509,7 +4509,7 @@ static const char * const ssi_groups[] = {
"ssi2_ctrl_a",
"ssi2_ctrl_b",
"ssi3_data",
"ssi34_ctrl",
"ssi349_ctrl",
"ssi4_data",
"ssi4_ctrl",
"ssi5_data",
@ -5356,8 +5356,8 @@ static const struct pinmux_drive_reg pinmux_drive_regs[] = {
{ RCAR_GP_PIN(6, 2), 24, 3 }, /* SSI_SDATA0 */
{ RCAR_GP_PIN(6, 3), 20, 3 }, /* SSI_SDATA1 */
{ RCAR_GP_PIN(6, 4), 16, 3 }, /* SSI_SDATA2 */
{ RCAR_GP_PIN(6, 5), 12, 3 }, /* SSI_SCK34 */
{ RCAR_GP_PIN(6, 6), 8, 3 }, /* SSI_WS34 */
{ RCAR_GP_PIN(6, 5), 12, 3 }, /* SSI_SCK349 */
{ RCAR_GP_PIN(6, 6), 8, 3 }, /* SSI_WS349 */
{ RCAR_GP_PIN(6, 7), 4, 3 }, /* SSI_SDATA3 */
{ RCAR_GP_PIN(6, 8), 0, 3 }, /* SSI_SCK4 */
} },
@ -5604,8 +5604,8 @@ static const struct sh_pfc_bias_info bias_info[] = {
{ RCAR_GP_PIN(6, 9), PU5, 16 }, /* SSI_WS4 */
{ RCAR_GP_PIN(6, 8), PU5, 15 }, /* SSI_SCK4 */
{ RCAR_GP_PIN(6, 7), PU5, 14 }, /* SSI_SDATA3 */
{ RCAR_GP_PIN(6, 6), PU5, 13 }, /* SSI_WS34 */
{ RCAR_GP_PIN(6, 5), PU5, 12 }, /* SSI_SCK34 */
{ RCAR_GP_PIN(6, 6), PU5, 13 }, /* SSI_WS349 */
{ RCAR_GP_PIN(6, 5), PU5, 12 }, /* SSI_SCK349 */
{ RCAR_GP_PIN(6, 4), PU5, 11 }, /* SSI_SDATA2_A */
{ RCAR_GP_PIN(6, 3), PU5, 10 }, /* SSI_SDATA1_A */
{ RCAR_GP_PIN(6, 2), PU5, 9 }, /* SSI_SDATA0 */

View File

@ -193,8 +193,8 @@
#define GPSR6_9 F_(SSI_WS4, IP15_27_24)
#define GPSR6_8 F_(SSI_SCK4, IP15_23_20)
#define GPSR6_7 F_(SSI_SDATA3, IP15_19_16)
#define GPSR6_6 F_(SSI_WS34, IP15_15_12)
#define GPSR6_5 F_(SSI_SCK34, IP15_11_8)
#define GPSR6_6 F_(SSI_WS349, IP15_15_12)
#define GPSR6_5 F_(SSI_SCK349, IP15_11_8)
#define GPSR6_4 F_(SSI_SDATA2_A, IP15_7_4)
#define GPSR6_3 F_(SSI_SDATA1_A, IP15_3_0)
#define GPSR6_2 F_(SSI_SDATA0, IP14_31_28)
@ -339,8 +339,8 @@
#define IP14_31_28 FM(SSI_SDATA0) F_(0, 0) FM(MSIOF1_SS2_F) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP15_3_0 FM(SSI_SDATA1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP15_7_4 FM(SSI_SDATA2_A) F_(0, 0) F_(0, 0) F_(0, 0) FM(SSI_SCK1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP15_11_8 FM(SSI_SCK34) F_(0, 0) FM(MSIOF1_SS1_A) F_(0, 0) F_(0, 0) F_(0, 0) FM(STP_OPWM_0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP15_15_12 FM(SSI_WS34) FM(HCTS2_N_A) FM(MSIOF1_SS2_A) F_(0, 0) F_(0, 0) F_(0, 0) FM(STP_IVCXO27_0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP15_11_8 FM(SSI_SCK349) F_(0, 0) FM(MSIOF1_SS1_A) F_(0, 0) F_(0, 0) F_(0, 0) FM(STP_OPWM_0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP15_15_12 FM(SSI_WS349) FM(HCTS2_N_A) FM(MSIOF1_SS2_A) F_(0, 0) F_(0, 0) F_(0, 0) FM(STP_IVCXO27_0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP15_19_16 FM(SSI_SDATA3) FM(HRTS2_N_A) FM(MSIOF1_TXD_A) F_(0, 0) F_(0, 0) FM(TS_SCK0_A) FM(STP_ISCLK_0_A) FM(RIF0_D1_A) FM(RIF2_D0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP15_23_20 FM(SSI_SCK4) FM(HRX2_A) FM(MSIOF1_SCK_A) F_(0, 0) F_(0, 0) FM(TS_SDAT0_A) FM(STP_ISD_0_A) FM(RIF0_CLK_A) FM(RIF2_CLK_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP15_27_24 FM(SSI_WS4) FM(HTX2_A) FM(MSIOF1_SYNC_A) F_(0, 0) F_(0, 0) FM(TS_SDEN0_A) FM(STP_ISEN_0_A) FM(RIF0_SYNC_A) FM(RIF2_SYNC_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
@ -1315,11 +1315,11 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_MSEL(IP15_7_4, SSI_SDATA2_A, SEL_SSI_0),
PINMUX_IPSR_MSEL(IP15_7_4, SSI_SCK1_B, SEL_SSI_1),
PINMUX_IPSR_GPSR(IP15_11_8, SSI_SCK34),
PINMUX_IPSR_GPSR(IP15_11_8, SSI_SCK349),
PINMUX_IPSR_MSEL(IP15_11_8, MSIOF1_SS1_A, SEL_MSIOF1_0),
PINMUX_IPSR_MSEL(IP15_11_8, STP_OPWM_0_A, SEL_SSP1_0_0),
PINMUX_IPSR_GPSR(IP15_15_12, SSI_WS34),
PINMUX_IPSR_GPSR(IP15_15_12, SSI_WS349),
PINMUX_IPSR_MSEL(IP15_15_12, HCTS2_N_A, SEL_HSCIF2_0),
PINMUX_IPSR_MSEL(IP15_15_12, MSIOF1_SS2_A, SEL_MSIOF1_0),
PINMUX_IPSR_MSEL(IP15_15_12, STP_IVCXO27_0_A, SEL_SSP1_0_0),
@ -1576,6 +1576,273 @@ static const struct sh_pfc_pin pinmux_pins[] = {
SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('T'), 30, ASEBRK, CFG_FLAGS),
};
/* - EtherAVB --------------------------------------------------------------- */
static const unsigned int avb_link_pins[] = {
/* AVB_LINK */
RCAR_GP_PIN(2, 12),
};
static const unsigned int avb_link_mux[] = {
AVB_LINK_MARK,
};
static const unsigned int avb_magic_pins[] = {
/* AVB_MAGIC_ */
RCAR_GP_PIN(2, 10),
};
static const unsigned int avb_magic_mux[] = {
AVB_MAGIC_MARK,
};
static const unsigned int avb_phy_int_pins[] = {
/* AVB_PHY_INT */
RCAR_GP_PIN(2, 11),
};
static const unsigned int avb_phy_int_mux[] = {
AVB_PHY_INT_MARK,
};
static const unsigned int avb_mdc_pins[] = {
/* AVB_MDC, AVB_MDIO */
RCAR_GP_PIN(2, 9), PIN_NUMBER('A', 9),
};
static const unsigned int avb_mdc_mux[] = {
AVB_MDC_MARK, AVB_MDIO_MARK,
};
static const unsigned int avb_mii_pins[] = {
/*
* AVB_TX_CTL, AVB_TXC, AVB_TD0,
* AVB_TD1, AVB_TD2, AVB_TD3,
* AVB_RX_CTL, AVB_RXC, AVB_RD0,
* AVB_RD1, AVB_RD2, AVB_RD3,
* AVB_TXCREFCLK
*/
PIN_NUMBER('A', 8), PIN_NUMBER('A', 19), PIN_NUMBER('A', 18),
PIN_NUMBER('B', 18), PIN_NUMBER('A', 17), PIN_NUMBER('B', 17),
PIN_NUMBER('A', 16), PIN_NUMBER('B', 19), PIN_NUMBER('A', 13),
PIN_NUMBER('B', 13), PIN_NUMBER('A', 14), PIN_NUMBER('B', 14),
PIN_NUMBER('A', 12),
};
static const unsigned int avb_mii_mux[] = {
AVB_TX_CTL_MARK, AVB_TXC_MARK, AVB_TD0_MARK,
AVB_TD1_MARK, AVB_TD2_MARK, AVB_TD3_MARK,
AVB_RX_CTL_MARK, AVB_RXC_MARK, AVB_RD0_MARK,
AVB_RD1_MARK, AVB_RD2_MARK, AVB_RD3_MARK,
AVB_TXCREFCLK_MARK,
};
static const unsigned int avb_avtp_pps_pins[] = {
/* AVB_AVTP_PPS */
RCAR_GP_PIN(2, 6),
};
static const unsigned int avb_avtp_pps_mux[] = {
AVB_AVTP_PPS_MARK,
};
static const unsigned int avb_avtp_match_a_pins[] = {
/* AVB_AVTP_MATCH_A */
RCAR_GP_PIN(2, 13),
};
static const unsigned int avb_avtp_match_a_mux[] = {
AVB_AVTP_MATCH_A_MARK,
};
static const unsigned int avb_avtp_capture_a_pins[] = {
/* AVB_AVTP_CAPTURE_A */
RCAR_GP_PIN(2, 14),
};
static const unsigned int avb_avtp_capture_a_mux[] = {
AVB_AVTP_CAPTURE_A_MARK,
};
static const unsigned int avb_avtp_match_b_pins[] = {
/* AVB_AVTP_MATCH_B */
RCAR_GP_PIN(1, 8),
};
static const unsigned int avb_avtp_match_b_mux[] = {
AVB_AVTP_MATCH_B_MARK,
};
static const unsigned int avb_avtp_capture_b_pins[] = {
/* AVB_AVTP_CAPTURE_B */
RCAR_GP_PIN(1, 11),
};
static const unsigned int avb_avtp_capture_b_mux[] = {
AVB_AVTP_CAPTURE_B_MARK,
};
/* - DU --------------------------------------------------------------------- */
static const unsigned int du_rgb666_pins[] = {
/* R[7:2], G[7:2], B[7:2] */
RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 14), RCAR_GP_PIN(0, 13),
RCAR_GP_PIN(0, 12), RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 10),
RCAR_GP_PIN(1, 15), RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 13),
RCAR_GP_PIN(1, 12), RCAR_GP_PIN(1, 19), RCAR_GP_PIN(1, 18),
RCAR_GP_PIN(1, 7), RCAR_GP_PIN(1, 6), RCAR_GP_PIN(1, 5),
RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 3), RCAR_GP_PIN(1, 2),
};
static const unsigned int du_rgb666_mux[] = {
DU_DR7_MARK, DU_DR6_MARK, DU_DR5_MARK, DU_DR4_MARK,
DU_DR3_MARK, DU_DR2_MARK,
DU_DG7_MARK, DU_DG6_MARK, DU_DG5_MARK, DU_DG4_MARK,
DU_DG3_MARK, DU_DG2_MARK,
DU_DB7_MARK, DU_DB6_MARK, DU_DB5_MARK, DU_DB4_MARK,
DU_DB3_MARK, DU_DB2_MARK,
};
static const unsigned int du_rgb888_pins[] = {
/* R[7:0], G[7:0], B[7:0] */
RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 14), RCAR_GP_PIN(0, 13),
RCAR_GP_PIN(0, 12), RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 10),
RCAR_GP_PIN(0, 9), RCAR_GP_PIN(0, 8),
RCAR_GP_PIN(1, 15), RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 13),
RCAR_GP_PIN(1, 12), RCAR_GP_PIN(1, 19), RCAR_GP_PIN(1, 18),
RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 16),
RCAR_GP_PIN(1, 7), RCAR_GP_PIN(1, 6), RCAR_GP_PIN(1, 5),
RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 3), RCAR_GP_PIN(1, 2),
RCAR_GP_PIN(1, 1), RCAR_GP_PIN(1, 0),
};
static const unsigned int du_rgb888_mux[] = {
DU_DR7_MARK, DU_DR6_MARK, DU_DR5_MARK, DU_DR4_MARK,
DU_DR3_MARK, DU_DR2_MARK, DU_DR1_MARK, DU_DR0_MARK,
DU_DG7_MARK, DU_DG6_MARK, DU_DG5_MARK, DU_DG4_MARK,
DU_DG3_MARK, DU_DG2_MARK, DU_DG1_MARK, DU_DG0_MARK,
DU_DB7_MARK, DU_DB6_MARK, DU_DB5_MARK, DU_DB4_MARK,
DU_DB3_MARK, DU_DB2_MARK, DU_DB1_MARK, DU_DB0_MARK,
};
static const unsigned int du_clk_out_0_pins[] = {
/* CLKOUT */
RCAR_GP_PIN(1, 27),
};
static const unsigned int du_clk_out_0_mux[] = {
DU_DOTCLKOUT0_MARK
};
static const unsigned int du_clk_out_1_pins[] = {
/* CLKOUT */
RCAR_GP_PIN(2, 3),
};
static const unsigned int du_clk_out_1_mux[] = {
DU_DOTCLKOUT1_MARK
};
static const unsigned int du_sync_pins[] = {
/* EXVSYNC/VSYNC, EXHSYNC/HSYNC */
RCAR_GP_PIN(2, 5), RCAR_GP_PIN(2, 4),
};
static const unsigned int du_sync_mux[] = {
DU_EXVSYNC_DU_VSYNC_MARK, DU_EXHSYNC_DU_HSYNC_MARK
};
static const unsigned int du_oddf_pins[] = {
/* EXDISP/EXODDF/EXCDE */
RCAR_GP_PIN(2, 2),
};
static const unsigned int du_oddf_mux[] = {
DU_EXODDF_DU_ODDF_DISP_CDE_MARK,
};
static const unsigned int du_cde_pins[] = {
/* CDE */
RCAR_GP_PIN(2, 0),
};
static const unsigned int du_cde_mux[] = {
DU_CDE_MARK,
};
static const unsigned int du_disp_pins[] = {
/* DISP */
RCAR_GP_PIN(2, 1),
};
static const unsigned int du_disp_mux[] = {
DU_DISP_MARK,
};
/* - PWM0 --------------------------------------------------------------------*/
static const unsigned int pwm0_pins[] = {
/* PWM */
RCAR_GP_PIN(2, 6),
};
static const unsigned int pwm0_mux[] = {
PWM0_MARK,
};
/* - PWM1 --------------------------------------------------------------------*/
static const unsigned int pwm1_a_pins[] = {
/* PWM */
RCAR_GP_PIN(2, 7),
};
static const unsigned int pwm1_a_mux[] = {
PWM1_A_MARK,
};
static const unsigned int pwm1_b_pins[] = {
/* PWM */
RCAR_GP_PIN(1, 8),
};
static const unsigned int pwm1_b_mux[] = {
PWM1_B_MARK,
};
/* - PWM2 --------------------------------------------------------------------*/
static const unsigned int pwm2_a_pins[] = {
/* PWM */
RCAR_GP_PIN(2, 8),
};
static const unsigned int pwm2_a_mux[] = {
PWM2_A_MARK,
};
static const unsigned int pwm2_b_pins[] = {
/* PWM */
RCAR_GP_PIN(1, 11),
};
static const unsigned int pwm2_b_mux[] = {
PWM2_B_MARK,
};
/* - PWM3 --------------------------------------------------------------------*/
static const unsigned int pwm3_a_pins[] = {
/* PWM */
RCAR_GP_PIN(1, 0),
};
static const unsigned int pwm3_a_mux[] = {
PWM3_A_MARK,
};
static const unsigned int pwm3_b_pins[] = {
/* PWM */
RCAR_GP_PIN(2, 2),
};
static const unsigned int pwm3_b_mux[] = {
PWM3_B_MARK,
};
/* - PWM4 --------------------------------------------------------------------*/
static const unsigned int pwm4_a_pins[] = {
/* PWM */
RCAR_GP_PIN(1, 1),
};
static const unsigned int pwm4_a_mux[] = {
PWM4_A_MARK,
};
static const unsigned int pwm4_b_pins[] = {
/* PWM */
RCAR_GP_PIN(2, 3),
};
static const unsigned int pwm4_b_mux[] = {
PWM4_B_MARK,
};
/* - PWM5 --------------------------------------------------------------------*/
static const unsigned int pwm5_a_pins[] = {
/* PWM */
RCAR_GP_PIN(1, 2),
};
static const unsigned int pwm5_a_mux[] = {
PWM5_A_MARK,
};
static const unsigned int pwm5_b_pins[] = {
/* PWM */
RCAR_GP_PIN(2, 4),
};
static const unsigned int pwm5_b_mux[] = {
PWM5_B_MARK,
};
/* - PWM6 --------------------------------------------------------------------*/
static const unsigned int pwm6_a_pins[] = {
/* PWM */
RCAR_GP_PIN(1, 3),
};
static const unsigned int pwm6_a_mux[] = {
PWM6_A_MARK,
};
static const unsigned int pwm6_b_pins[] = {
/* PWM */
RCAR_GP_PIN(2, 5),
};
static const unsigned int pwm6_b_mux[] = {
PWM6_B_MARK,
};
/* - SCIF0 ------------------------------------------------------------------ */
static const unsigned int scif0_data_pins[] = {
/* RX, TX */
@ -1790,6 +2057,37 @@ static const unsigned int scif_clk_b_mux[] = {
};
static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(avb_link),
SH_PFC_PIN_GROUP(avb_magic),
SH_PFC_PIN_GROUP(avb_phy_int),
SH_PFC_PIN_GROUP(avb_mdc),
SH_PFC_PIN_GROUP(avb_mii),
SH_PFC_PIN_GROUP(avb_avtp_pps),
SH_PFC_PIN_GROUP(avb_avtp_match_a),
SH_PFC_PIN_GROUP(avb_avtp_capture_a),
SH_PFC_PIN_GROUP(avb_avtp_match_b),
SH_PFC_PIN_GROUP(avb_avtp_capture_b),
SH_PFC_PIN_GROUP(du_rgb666),
SH_PFC_PIN_GROUP(du_rgb888),
SH_PFC_PIN_GROUP(du_clk_out_0),
SH_PFC_PIN_GROUP(du_clk_out_1),
SH_PFC_PIN_GROUP(du_sync),
SH_PFC_PIN_GROUP(du_oddf),
SH_PFC_PIN_GROUP(du_cde),
SH_PFC_PIN_GROUP(du_disp),
SH_PFC_PIN_GROUP(pwm0),
SH_PFC_PIN_GROUP(pwm1_a),
SH_PFC_PIN_GROUP(pwm1_b),
SH_PFC_PIN_GROUP(pwm2_a),
SH_PFC_PIN_GROUP(pwm2_b),
SH_PFC_PIN_GROUP(pwm3_a),
SH_PFC_PIN_GROUP(pwm3_b),
SH_PFC_PIN_GROUP(pwm4_a),
SH_PFC_PIN_GROUP(pwm4_b),
SH_PFC_PIN_GROUP(pwm5_a),
SH_PFC_PIN_GROUP(pwm5_b),
SH_PFC_PIN_GROUP(pwm6_a),
SH_PFC_PIN_GROUP(pwm6_b),
SH_PFC_PIN_GROUP(scif0_data),
SH_PFC_PIN_GROUP(scif0_clk),
SH_PFC_PIN_GROUP(scif0_ctrl),
@ -1821,6 +2119,64 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(scif_clk_b),
};
static const char * const avb_groups[] = {
"avb_link",
"avb_magic",
"avb_phy_int",
"avb_mdc",
"avb_mii",
"avb_avtp_pps",
"avb_avtp_match_a",
"avb_avtp_capture_a",
"avb_avtp_match_b",
"avb_avtp_capture_b",
};
static const char * const du_groups[] = {
"du_rgb666",
"du_rgb888",
"du_clk_out_0",
"du_clk_out_1",
"du_sync",
"du_oddf",
"du_cde",
"du_disp",
};
static const char * const pwm0_groups[] = {
"pwm0",
};
static const char * const pwm1_groups[] = {
"pwm1_a",
"pwm1_b",
};
static const char * const pwm2_groups[] = {
"pwm2_a",
"pwm2_b",
};
static const char * const pwm3_groups[] = {
"pwm3_a",
"pwm3_b",
};
static const char * const pwm4_groups[] = {
"pwm4_a",
"pwm4_b",
};
static const char * const pwm5_groups[] = {
"pwm5_a",
"pwm5_b",
};
static const char * const pwm6_groups[] = {
"pwm6_a",
"pwm6_b",
};
static const char * const scif0_groups[] = {
"scif0_data",
"scif0_clk",
@ -1872,6 +2228,15 @@ static const char * const scif_clk_groups[] = {
};
static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(avb),
SH_PFC_FUNCTION(du),
SH_PFC_FUNCTION(pwm0),
SH_PFC_FUNCTION(pwm1),
SH_PFC_FUNCTION(pwm2),
SH_PFC_FUNCTION(pwm3),
SH_PFC_FUNCTION(pwm4),
SH_PFC_FUNCTION(pwm5),
SH_PFC_FUNCTION(pwm6),
SH_PFC_FUNCTION(scif0),
SH_PFC_FUNCTION(scif1),
SH_PFC_FUNCTION(scif2),
@ -2653,8 +3018,8 @@ static const struct pinmux_drive_reg pinmux_drive_regs[] = {
{ RCAR_GP_PIN(6, 2), 24, 3 }, /* SSI_SDATA0 */
{ RCAR_GP_PIN(6, 3), 20, 3 }, /* SSI_SDATA1 */
{ RCAR_GP_PIN(6, 4), 16, 3 }, /* SSI_SDATA2 */
{ RCAR_GP_PIN(6, 5), 12, 3 }, /* SSI_SCK34 */
{ RCAR_GP_PIN(6, 6), 8, 3 }, /* SSI_WS34 */
{ RCAR_GP_PIN(6, 5), 12, 3 }, /* SSI_SCK349 */
{ RCAR_GP_PIN(6, 6), 8, 3 }, /* SSI_WS349 */
{ RCAR_GP_PIN(6, 7), 4, 3 }, /* SSI_SDATA3 */
{ RCAR_GP_PIN(6, 8), 0, 3 }, /* SSI_SCK4 */
} },
@ -2900,8 +3265,8 @@ static const struct sh_pfc_bias_info bias_info[] = {
{ RCAR_GP_PIN(6, 9), PU5, 16 }, /* SSI_WS4 */
{ RCAR_GP_PIN(6, 8), PU5, 15 }, /* SSI_SCK4 */
{ RCAR_GP_PIN(6, 7), PU5, 14 }, /* SSI_SDATA3 */
{ RCAR_GP_PIN(6, 6), PU5, 13 }, /* SSI_WS34 */
{ RCAR_GP_PIN(6, 5), PU5, 12 }, /* SSI_SCK34 */
{ RCAR_GP_PIN(6, 6), PU5, 13 }, /* SSI_WS349 */
{ RCAR_GP_PIN(6, 5), PU5, 12 }, /* SSI_SCK349 */
{ RCAR_GP_PIN(6, 4), PU5, 11 }, /* SSI_SDATA2_A */
{ RCAR_GP_PIN(6, 3), PU5, 10 }, /* SSI_SDATA1_A */
{ RCAR_GP_PIN(6, 2), PU5, 9 }, /* SSI_SDATA0 */

View File

@ -199,13 +199,13 @@
#define GPSR6_9 F_(SSI_WS4, IP15_27_24)
#define GPSR6_8 F_(SSI_SCK4, IP15_23_20)
#define GPSR6_7 F_(SSI_SDATA3, IP15_19_16)
#define GPSR6_6 F_(SSI_WS34, IP15_15_12)
#define GPSR6_5 F_(SSI_SCK34, IP15_11_8)
#define GPSR6_6 F_(SSI_WS349, IP15_15_12)
#define GPSR6_5 F_(SSI_SCK349, IP15_11_8)
#define GPSR6_4 F_(SSI_SDATA2_A, IP15_7_4)
#define GPSR6_3 F_(SSI_SDATA1_A, IP15_3_0)
#define GPSR6_2 F_(SSI_SDATA0, IP14_31_28)
#define GPSR6_1 F_(SSI_WS0129, IP14_27_24)
#define GPSR6_0 F_(SSI_SCK0129, IP14_23_20)
#define GPSR6_1 F_(SSI_WS01239, IP14_27_24)
#define GPSR6_0 F_(SSI_SCK01239, IP14_23_20)
/* GPSR7 */
#define GPSR7_3 FM(GP7_03)
@ -338,15 +338,15 @@
#define IP14_11_8 FM(MLB_CLK) F_(0, 0) FM(MSIOF1_SCK_F) F_(0, 0) FM(SCL1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP14_15_12 FM(MLB_SIG) FM(RX1_B) FM(MSIOF1_SYNC_F) F_(0, 0) FM(SDA1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP14_19_16 FM(MLB_DAT) FM(TX1_B) FM(MSIOF1_RXD_F) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP14_23_20 FM(SSI_SCK0129) F_(0, 0) FM(MSIOF1_TXD_F) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP14_27_24 FM(SSI_WS0129) F_(0, 0) FM(MSIOF1_SS1_F) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP14_23_20 FM(SSI_SCK01239) F_(0, 0) FM(MSIOF1_TXD_F) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP14_27_24 FM(SSI_WS01239) F_(0, 0) FM(MSIOF1_SS1_F) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
/* IPSRx */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 */ /* 7 */ /* 8 */ /* 9 */ /* A */ /* B */ /* C - F */
#define IP14_31_28 FM(SSI_SDATA0) F_(0, 0) FM(MSIOF1_SS2_F) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP15_3_0 FM(SSI_SDATA1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP15_7_4 FM(SSI_SDATA2_A) F_(0, 0) F_(0, 0) F_(0, 0) FM(SSI_SCK1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP15_11_8 FM(SSI_SCK34) F_(0, 0) FM(MSIOF1_SS1_A) F_(0, 0) F_(0, 0) F_(0, 0) FM(STP_OPWM_0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP15_15_12 FM(SSI_WS34) FM(HCTS2_N_A) FM(MSIOF1_SS2_A) F_(0, 0) F_(0, 0) F_(0, 0) FM(STP_IVCXO27_0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP15_11_8 FM(SSI_SCK349) F_(0, 0) FM(MSIOF1_SS1_A) F_(0, 0) F_(0, 0) F_(0, 0) FM(STP_OPWM_0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP15_15_12 FM(SSI_WS349) FM(HCTS2_N_A) FM(MSIOF1_SS2_A) F_(0, 0) F_(0, 0) F_(0, 0) FM(STP_IVCXO27_0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP15_19_16 FM(SSI_SDATA3) FM(HRTS2_N_A) FM(MSIOF1_TXD_A) F_(0, 0) F_(0, 0) FM(TS_SCK0_A) FM(STP_ISCLK_0_A) FM(RIF0_D1_A) FM(RIF2_D0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP15_23_20 FM(SSI_SCK4) FM(HRX2_A) FM(MSIOF1_SCK_A) F_(0, 0) F_(0, 0) FM(TS_SDAT0_A) FM(STP_ISD_0_A) FM(RIF0_CLK_A) FM(RIF2_CLK_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
#define IP15_27_24 FM(SSI_WS4) FM(HTX2_A) FM(MSIOF1_SYNC_A) F_(0, 0) F_(0, 0) FM(TS_SDEN0_A) FM(STP_ISEN_0_A) FM(RIF0_SYNC_A) FM(RIF2_SYNC_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
@ -1304,10 +1304,10 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_MSEL(IP14_19_16, TX1_B, SEL_SCIF1_1),
PINMUX_IPSR_MSEL(IP14_19_16, MSIOF1_RXD_F, SEL_MSIOF1_5),
PINMUX_IPSR_GPSR(IP14_23_20, SSI_SCK0129),
PINMUX_IPSR_GPSR(IP14_23_20, SSI_SCK01239),
PINMUX_IPSR_MSEL(IP14_23_20, MSIOF1_TXD_F, SEL_MSIOF1_5),
PINMUX_IPSR_GPSR(IP14_27_24, SSI_WS0129),
PINMUX_IPSR_GPSR(IP14_27_24, SSI_WS01239),
PINMUX_IPSR_MSEL(IP14_27_24, MSIOF1_SS1_F, SEL_MSIOF1_5),
PINMUX_IPSR_GPSR(IP14_31_28, SSI_SDATA0),
@ -1319,11 +1319,11 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_MSEL(IP15_7_4, SSI_SDATA2_A, SEL_SSI_0),
PINMUX_IPSR_MSEL(IP15_7_4, SSI_SCK1_B, SEL_SSI_1),
PINMUX_IPSR_GPSR(IP15_11_8, SSI_SCK34),
PINMUX_IPSR_GPSR(IP15_11_8, SSI_SCK349),
PINMUX_IPSR_MSEL(IP15_11_8, MSIOF1_SS1_A, SEL_MSIOF1_0),
PINMUX_IPSR_MSEL(IP15_11_8, STP_OPWM_0_A, SEL_SSP1_0_0),
PINMUX_IPSR_GPSR(IP15_15_12, SSI_WS34),
PINMUX_IPSR_GPSR(IP15_15_12, SSI_WS349),
PINMUX_IPSR_MSEL(IP15_15_12, HCTS2_N_A, SEL_HSCIF2_0),
PINMUX_IPSR_MSEL(IP15_15_12, MSIOF1_SS2_A, SEL_MSIOF1_0),
PINMUX_IPSR_MSEL(IP15_15_12, STP_IVCXO27_0_A, SEL_SSP1_0_0),
@ -1582,6 +1582,128 @@ static const struct sh_pfc_pin pinmux_pins[] = {
SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('T'), 30, ASEBRK, CFG_FLAGS),
};
/* - AUDIO CLOCK ------------------------------------------------------------ */
static const unsigned int audio_clk_a_a_pins[] = {
/* CLK A */
RCAR_GP_PIN(6, 22),
};
static const unsigned int audio_clk_a_a_mux[] = {
AUDIO_CLKA_A_MARK,
};
static const unsigned int audio_clk_a_b_pins[] = {
/* CLK A */
RCAR_GP_PIN(5, 4),
};
static const unsigned int audio_clk_a_b_mux[] = {
AUDIO_CLKA_B_MARK,
};
static const unsigned int audio_clk_a_c_pins[] = {
/* CLK A */
RCAR_GP_PIN(5, 19),
};
static const unsigned int audio_clk_a_c_mux[] = {
AUDIO_CLKA_C_MARK,
};
static const unsigned int audio_clk_b_a_pins[] = {
/* CLK B */
RCAR_GP_PIN(5, 12),
};
static const unsigned int audio_clk_b_a_mux[] = {
AUDIO_CLKB_A_MARK,
};
static const unsigned int audio_clk_b_b_pins[] = {
/* CLK B */
RCAR_GP_PIN(6, 23),
};
static const unsigned int audio_clk_b_b_mux[] = {
AUDIO_CLKB_B_MARK,
};
static const unsigned int audio_clk_c_a_pins[] = {
/* CLK C */
RCAR_GP_PIN(5, 21),
};
static const unsigned int audio_clk_c_a_mux[] = {
AUDIO_CLKC_A_MARK,
};
static const unsigned int audio_clk_c_b_pins[] = {
/* CLK C */
RCAR_GP_PIN(5, 0),
};
static const unsigned int audio_clk_c_b_mux[] = {
AUDIO_CLKC_B_MARK,
};
static const unsigned int audio_clkout_a_pins[] = {
/* CLKOUT */
RCAR_GP_PIN(5, 18),
};
static const unsigned int audio_clkout_a_mux[] = {
AUDIO_CLKOUT_A_MARK,
};
static const unsigned int audio_clkout_b_pins[] = {
/* CLKOUT */
RCAR_GP_PIN(6, 28),
};
static const unsigned int audio_clkout_b_mux[] = {
AUDIO_CLKOUT_B_MARK,
};
static const unsigned int audio_clkout_c_pins[] = {
/* CLKOUT */
RCAR_GP_PIN(5, 3),
};
static const unsigned int audio_clkout_c_mux[] = {
AUDIO_CLKOUT_C_MARK,
};
static const unsigned int audio_clkout_d_pins[] = {
/* CLKOUT */
RCAR_GP_PIN(5, 21),
};
static const unsigned int audio_clkout_d_mux[] = {
AUDIO_CLKOUT_D_MARK,
};
static const unsigned int audio_clkout1_a_pins[] = {
/* CLKOUT1 */
RCAR_GP_PIN(5, 15),
};
static const unsigned int audio_clkout1_a_mux[] = {
AUDIO_CLKOUT1_A_MARK,
};
static const unsigned int audio_clkout1_b_pins[] = {
/* CLKOUT1 */
RCAR_GP_PIN(6, 29),
};
static const unsigned int audio_clkout1_b_mux[] = {
AUDIO_CLKOUT1_B_MARK,
};
static const unsigned int audio_clkout2_a_pins[] = {
/* CLKOUT2 */
RCAR_GP_PIN(5, 16),
};
static const unsigned int audio_clkout2_a_mux[] = {
AUDIO_CLKOUT2_A_MARK,
};
static const unsigned int audio_clkout2_b_pins[] = {
/* CLKOUT2 */
RCAR_GP_PIN(6, 30),
};
static const unsigned int audio_clkout2_b_mux[] = {
AUDIO_CLKOUT2_B_MARK,
};
static const unsigned int audio_clkout3_a_pins[] = {
/* CLKOUT3 */
RCAR_GP_PIN(5, 19),
};
static const unsigned int audio_clkout3_a_mux[] = {
AUDIO_CLKOUT3_A_MARK,
};
static const unsigned int audio_clkout3_b_pins[] = {
/* CLKOUT3 */
RCAR_GP_PIN(6, 31),
};
static const unsigned int audio_clkout3_b_mux[] = {
AUDIO_CLKOUT3_B_MARK,
};
/* - EtherAVB --------------------------------------------------------------- */
static const unsigned int avb_link_pins[] = {
/* AVB_LINK */
@ -1605,11 +1727,33 @@ static const unsigned int avb_phy_int_mux[] = {
AVB_PHY_INT_MARK,
};
static const unsigned int avb_mdc_pins[] = {
/* AVB_MDC */
RCAR_GP_PIN(2, 9),
/* AVB_MDC, AVB_MDIO */
RCAR_GP_PIN(2, 9), PIN_NUMBER('A', 9),
};
static const unsigned int avb_mdc_mux[] = {
AVB_MDC_MARK,
AVB_MDC_MARK, AVB_MDIO_MARK,
};
static const unsigned int avb_mii_pins[] = {
/*
* AVB_TX_CTL, AVB_TXC, AVB_TD0,
* AVB_TD1, AVB_TD2, AVB_TD3,
* AVB_RX_CTL, AVB_RXC, AVB_RD0,
* AVB_RD1, AVB_RD2, AVB_RD3,
* AVB_TXCREFCLK
*/
PIN_NUMBER('A', 8), PIN_NUMBER('A', 19), PIN_NUMBER('A', 18),
PIN_NUMBER('B', 18), PIN_NUMBER('A', 17), PIN_NUMBER('B', 17),
PIN_NUMBER('A', 16), PIN_NUMBER('B', 19), PIN_NUMBER('A', 13),
PIN_NUMBER('B', 13), PIN_NUMBER('A', 14), PIN_NUMBER('B', 14),
PIN_NUMBER('A', 12),
};
static const unsigned int avb_mii_mux[] = {
AVB_TX_CTL_MARK, AVB_TXC_MARK, AVB_TD0_MARK,
AVB_TD1_MARK, AVB_TD2_MARK, AVB_TD3_MARK,
AVB_RX_CTL_MARK, AVB_RXC_MARK, AVB_RD0_MARK,
AVB_RD1_MARK, AVB_RD2_MARK, AVB_RD3_MARK,
AVB_TXCREFCLK_MARK,
};
static const unsigned int avb_avtp_pps_pins[] = {
/* AVB_AVTP_PPS */
@ -2955,6 +3099,105 @@ static const unsigned int msiof3_rxd_e_mux[] = {
MSIOF3_RXD_E_MARK,
};
/* - PWM0 --------------------------------------------------------------------*/
static const unsigned int pwm0_pins[] = {
/* PWM */
RCAR_GP_PIN(2, 6),
};
static const unsigned int pwm0_mux[] = {
PWM0_MARK,
};
/* - PWM1 --------------------------------------------------------------------*/
static const unsigned int pwm1_a_pins[] = {
/* PWM */
RCAR_GP_PIN(2, 7),
};
static const unsigned int pwm1_a_mux[] = {
PWM1_A_MARK,
};
static const unsigned int pwm1_b_pins[] = {
/* PWM */
RCAR_GP_PIN(1, 8),
};
static const unsigned int pwm1_b_mux[] = {
PWM1_B_MARK,
};
/* - PWM2 --------------------------------------------------------------------*/
static const unsigned int pwm2_a_pins[] = {
/* PWM */
RCAR_GP_PIN(2, 8),
};
static const unsigned int pwm2_a_mux[] = {
PWM2_A_MARK,
};
static const unsigned int pwm2_b_pins[] = {
/* PWM */
RCAR_GP_PIN(1, 11),
};
static const unsigned int pwm2_b_mux[] = {
PWM2_B_MARK,
};
/* - PWM3 --------------------------------------------------------------------*/
static const unsigned int pwm3_a_pins[] = {
/* PWM */
RCAR_GP_PIN(1, 0),
};
static const unsigned int pwm3_a_mux[] = {
PWM3_A_MARK,
};
static const unsigned int pwm3_b_pins[] = {
/* PWM */
RCAR_GP_PIN(2, 2),
};
static const unsigned int pwm3_b_mux[] = {
PWM3_B_MARK,
};
/* - PWM4 --------------------------------------------------------------------*/
static const unsigned int pwm4_a_pins[] = {
/* PWM */
RCAR_GP_PIN(1, 1),
};
static const unsigned int pwm4_a_mux[] = {
PWM4_A_MARK,
};
static const unsigned int pwm4_b_pins[] = {
/* PWM */
RCAR_GP_PIN(2, 3),
};
static const unsigned int pwm4_b_mux[] = {
PWM4_B_MARK,
};
/* - PWM5 --------------------------------------------------------------------*/
static const unsigned int pwm5_a_pins[] = {
/* PWM */
RCAR_GP_PIN(1, 2),
};
static const unsigned int pwm5_a_mux[] = {
PWM5_A_MARK,
};
static const unsigned int pwm5_b_pins[] = {
/* PWM */
RCAR_GP_PIN(2, 4),
};
static const unsigned int pwm5_b_mux[] = {
PWM5_B_MARK,
};
/* - PWM6 --------------------------------------------------------------------*/
static const unsigned int pwm6_a_pins[] = {
/* PWM */
RCAR_GP_PIN(1, 3),
};
static const unsigned int pwm6_a_mux[] = {
PWM6_A_MARK,
};
static const unsigned int pwm6_b_pins[] = {
/* PWM */
RCAR_GP_PIN(2, 5),
};
static const unsigned int pwm6_b_mux[] = {
PWM6_B_MARK,
};
/* - SCIF0 ------------------------------------------------------------------ */
static const unsigned int scif0_data_pins[] = {
/* RX, TX */
@ -3376,11 +3619,206 @@ static const unsigned int sdhi3_ds_mux[] = {
SD3_DS_MARK,
};
/* - SSI -------------------------------------------------------------------- */
static const unsigned int ssi0_data_pins[] = {
/* SDATA */
RCAR_GP_PIN(6, 2),
};
static const unsigned int ssi0_data_mux[] = {
SSI_SDATA0_MARK,
};
static const unsigned int ssi01239_ctrl_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(6, 0), RCAR_GP_PIN(6, 1),
};
static const unsigned int ssi01239_ctrl_mux[] = {
SSI_SCK01239_MARK, SSI_WS01239_MARK,
};
static const unsigned int ssi1_data_a_pins[] = {
/* SDATA */
RCAR_GP_PIN(6, 3),
};
static const unsigned int ssi1_data_a_mux[] = {
SSI_SDATA1_A_MARK,
};
static const unsigned int ssi1_data_b_pins[] = {
/* SDATA */
RCAR_GP_PIN(5, 12),
};
static const unsigned int ssi1_data_b_mux[] = {
SSI_SDATA1_B_MARK,
};
static const unsigned int ssi1_ctrl_a_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(6, 26), RCAR_GP_PIN(6, 27),
};
static const unsigned int ssi1_ctrl_a_mux[] = {
SSI_SCK1_A_MARK, SSI_WS1_A_MARK,
};
static const unsigned int ssi1_ctrl_b_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(6, 4), RCAR_GP_PIN(6, 21),
};
static const unsigned int ssi1_ctrl_b_mux[] = {
SSI_SCK1_B_MARK, SSI_WS1_B_MARK,
};
static const unsigned int ssi2_data_a_pins[] = {
/* SDATA */
RCAR_GP_PIN(6, 4),
};
static const unsigned int ssi2_data_a_mux[] = {
SSI_SDATA2_A_MARK,
};
static const unsigned int ssi2_data_b_pins[] = {
/* SDATA */
RCAR_GP_PIN(5, 13),
};
static const unsigned int ssi2_data_b_mux[] = {
SSI_SDATA2_B_MARK,
};
static const unsigned int ssi2_ctrl_a_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(5, 19), RCAR_GP_PIN(5, 21),
};
static const unsigned int ssi2_ctrl_a_mux[] = {
SSI_SCK2_A_MARK, SSI_WS2_A_MARK,
};
static const unsigned int ssi2_ctrl_b_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(6, 28), RCAR_GP_PIN(6, 29),
};
static const unsigned int ssi2_ctrl_b_mux[] = {
SSI_SCK2_B_MARK, SSI_WS2_B_MARK,
};
static const unsigned int ssi3_data_pins[] = {
/* SDATA */
RCAR_GP_PIN(6, 7),
};
static const unsigned int ssi3_data_mux[] = {
SSI_SDATA3_MARK,
};
static const unsigned int ssi349_ctrl_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(6, 5), RCAR_GP_PIN(6, 6),
};
static const unsigned int ssi349_ctrl_mux[] = {
SSI_SCK349_MARK, SSI_WS349_MARK,
};
static const unsigned int ssi4_data_pins[] = {
/* SDATA */
RCAR_GP_PIN(6, 10),
};
static const unsigned int ssi4_data_mux[] = {
SSI_SDATA4_MARK,
};
static const unsigned int ssi4_ctrl_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(6, 8), RCAR_GP_PIN(6, 9),
};
static const unsigned int ssi4_ctrl_mux[] = {
SSI_SCK4_MARK, SSI_WS4_MARK,
};
static const unsigned int ssi5_data_pins[] = {
/* SDATA */
RCAR_GP_PIN(6, 13),
};
static const unsigned int ssi5_data_mux[] = {
SSI_SDATA5_MARK,
};
static const unsigned int ssi5_ctrl_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(6, 11), RCAR_GP_PIN(6, 12),
};
static const unsigned int ssi5_ctrl_mux[] = {
SSI_SCK5_MARK, SSI_WS5_MARK,
};
static const unsigned int ssi6_data_pins[] = {
/* SDATA */
RCAR_GP_PIN(6, 16),
};
static const unsigned int ssi6_data_mux[] = {
SSI_SDATA6_MARK,
};
static const unsigned int ssi6_ctrl_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(6, 14), RCAR_GP_PIN(6, 15),
};
static const unsigned int ssi6_ctrl_mux[] = {
SSI_SCK6_MARK, SSI_WS6_MARK,
};
static const unsigned int ssi7_data_pins[] = {
/* SDATA */
RCAR_GP_PIN(6, 19),
};
static const unsigned int ssi7_data_mux[] = {
SSI_SDATA7_MARK,
};
static const unsigned int ssi78_ctrl_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(6, 17), RCAR_GP_PIN(6, 18),
};
static const unsigned int ssi78_ctrl_mux[] = {
SSI_SCK78_MARK, SSI_WS78_MARK,
};
static const unsigned int ssi8_data_pins[] = {
/* SDATA */
RCAR_GP_PIN(6, 20),
};
static const unsigned int ssi8_data_mux[] = {
SSI_SDATA8_MARK,
};
static const unsigned int ssi9_data_a_pins[] = {
/* SDATA */
RCAR_GP_PIN(6, 21),
};
static const unsigned int ssi9_data_a_mux[] = {
SSI_SDATA9_A_MARK,
};
static const unsigned int ssi9_data_b_pins[] = {
/* SDATA */
RCAR_GP_PIN(5, 14),
};
static const unsigned int ssi9_data_b_mux[] = {
SSI_SDATA9_B_MARK,
};
static const unsigned int ssi9_ctrl_a_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(5, 15), RCAR_GP_PIN(5, 16),
};
static const unsigned int ssi9_ctrl_a_mux[] = {
SSI_SCK9_A_MARK, SSI_WS9_A_MARK,
};
static const unsigned int ssi9_ctrl_b_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(6, 30), RCAR_GP_PIN(6, 31),
};
static const unsigned int ssi9_ctrl_b_mux[] = {
SSI_SCK9_B_MARK, SSI_WS9_B_MARK,
};
static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(audio_clk_a_a),
SH_PFC_PIN_GROUP(audio_clk_a_b),
SH_PFC_PIN_GROUP(audio_clk_a_c),
SH_PFC_PIN_GROUP(audio_clk_b_a),
SH_PFC_PIN_GROUP(audio_clk_b_b),
SH_PFC_PIN_GROUP(audio_clk_c_a),
SH_PFC_PIN_GROUP(audio_clk_c_b),
SH_PFC_PIN_GROUP(audio_clkout_a),
SH_PFC_PIN_GROUP(audio_clkout_b),
SH_PFC_PIN_GROUP(audio_clkout_c),
SH_PFC_PIN_GROUP(audio_clkout_d),
SH_PFC_PIN_GROUP(audio_clkout1_a),
SH_PFC_PIN_GROUP(audio_clkout1_b),
SH_PFC_PIN_GROUP(audio_clkout2_a),
SH_PFC_PIN_GROUP(audio_clkout2_b),
SH_PFC_PIN_GROUP(audio_clkout3_a),
SH_PFC_PIN_GROUP(audio_clkout3_b),
SH_PFC_PIN_GROUP(avb_link),
SH_PFC_PIN_GROUP(avb_magic),
SH_PFC_PIN_GROUP(avb_phy_int),
SH_PFC_PIN_GROUP(avb_mdc),
SH_PFC_PIN_GROUP(avb_mii),
SH_PFC_PIN_GROUP(avb_avtp_pps),
SH_PFC_PIN_GROUP(avb_avtp_match_a),
SH_PFC_PIN_GROUP(avb_avtp_capture_a),
@ -3565,6 +4003,19 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(msiof3_ss2_e),
SH_PFC_PIN_GROUP(msiof3_txd_e),
SH_PFC_PIN_GROUP(msiof3_rxd_e),
SH_PFC_PIN_GROUP(pwm0),
SH_PFC_PIN_GROUP(pwm1_a),
SH_PFC_PIN_GROUP(pwm1_b),
SH_PFC_PIN_GROUP(pwm2_a),
SH_PFC_PIN_GROUP(pwm2_b),
SH_PFC_PIN_GROUP(pwm3_a),
SH_PFC_PIN_GROUP(pwm3_b),
SH_PFC_PIN_GROUP(pwm4_a),
SH_PFC_PIN_GROUP(pwm4_b),
SH_PFC_PIN_GROUP(pwm5_a),
SH_PFC_PIN_GROUP(pwm5_b),
SH_PFC_PIN_GROUP(pwm6_a),
SH_PFC_PIN_GROUP(pwm6_b),
SH_PFC_PIN_GROUP(scif0_data),
SH_PFC_PIN_GROUP(scif0_clk),
SH_PFC_PIN_GROUP(scif0_ctrl),
@ -3620,6 +4071,51 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(sdhi3_cd),
SH_PFC_PIN_GROUP(sdhi3_wp),
SH_PFC_PIN_GROUP(sdhi3_ds),
SH_PFC_PIN_GROUP(ssi0_data),
SH_PFC_PIN_GROUP(ssi01239_ctrl),
SH_PFC_PIN_GROUP(ssi1_data_a),
SH_PFC_PIN_GROUP(ssi1_data_b),
SH_PFC_PIN_GROUP(ssi1_ctrl_a),
SH_PFC_PIN_GROUP(ssi1_ctrl_b),
SH_PFC_PIN_GROUP(ssi2_data_a),
SH_PFC_PIN_GROUP(ssi2_data_b),
SH_PFC_PIN_GROUP(ssi2_ctrl_a),
SH_PFC_PIN_GROUP(ssi2_ctrl_b),
SH_PFC_PIN_GROUP(ssi3_data),
SH_PFC_PIN_GROUP(ssi349_ctrl),
SH_PFC_PIN_GROUP(ssi4_data),
SH_PFC_PIN_GROUP(ssi4_ctrl),
SH_PFC_PIN_GROUP(ssi5_data),
SH_PFC_PIN_GROUP(ssi5_ctrl),
SH_PFC_PIN_GROUP(ssi6_data),
SH_PFC_PIN_GROUP(ssi6_ctrl),
SH_PFC_PIN_GROUP(ssi7_data),
SH_PFC_PIN_GROUP(ssi78_ctrl),
SH_PFC_PIN_GROUP(ssi8_data),
SH_PFC_PIN_GROUP(ssi9_data_a),
SH_PFC_PIN_GROUP(ssi9_data_b),
SH_PFC_PIN_GROUP(ssi9_ctrl_a),
SH_PFC_PIN_GROUP(ssi9_ctrl_b),
};
static const char * const audio_clk_groups[] = {
"audio_clk_a_a",
"audio_clk_a_b",
"audio_clk_a_c",
"audio_clk_b_a",
"audio_clk_b_b",
"audio_clk_c_a",
"audio_clk_c_b",
"audio_clkout_a",
"audio_clkout_b",
"audio_clkout_c",
"audio_clkout_d",
"audio_clkout1_a",
"audio_clkout1_b",
"audio_clkout2_a",
"audio_clkout2_b",
"audio_clkout3_a",
"audio_clkout3_b",
};
static const char * const avb_groups[] = {
@ -3627,6 +4123,7 @@ static const char * const avb_groups[] = {
"avb_magic",
"avb_phy_int",
"avb_mdc",
"avb_mii",
"avb_avtp_pps",
"avb_avtp_match_a",
"avb_avtp_capture_a",
@ -3879,6 +4376,40 @@ static const char * const msiof3_groups[] = {
"msiof3_rxd_e",
};
static const char * const pwm0_groups[] = {
"pwm0",
};
static const char * const pwm1_groups[] = {
"pwm1_a",
"pwm1_b",
};
static const char * const pwm2_groups[] = {
"pwm2_a",
"pwm2_b",
};
static const char * const pwm3_groups[] = {
"pwm3_a",
"pwm3_b",
};
static const char * const pwm4_groups[] = {
"pwm4_a",
"pwm4_b",
};
static const char * const pwm5_groups[] = {
"pwm5_a",
"pwm5_b",
};
static const char * const pwm6_groups[] = {
"pwm6_a",
"pwm6_b",
};
static const char * const scif0_groups[] = {
"scif0_data",
"scif0_clk",
@ -3967,7 +4498,36 @@ static const char * const sdhi3_groups[] = {
"sdhi3_ds",
};
static const char * const ssi_groups[] = {
"ssi0_data",
"ssi01239_ctrl",
"ssi1_data_a",
"ssi1_data_b",
"ssi1_ctrl_a",
"ssi1_ctrl_b",
"ssi2_data_a",
"ssi2_data_b",
"ssi2_ctrl_a",
"ssi2_ctrl_b",
"ssi3_data",
"ssi349_ctrl",
"ssi4_data",
"ssi4_ctrl",
"ssi5_data",
"ssi5_ctrl",
"ssi6_data",
"ssi6_ctrl",
"ssi7_data",
"ssi78_ctrl",
"ssi8_data",
"ssi9_data_a",
"ssi9_data_b",
"ssi9_ctrl_a",
"ssi9_ctrl_b",
};
static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(audio_clk),
SH_PFC_FUNCTION(avb),
SH_PFC_FUNCTION(can0),
SH_PFC_FUNCTION(can1),
@ -3991,6 +4551,13 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(msiof1),
SH_PFC_FUNCTION(msiof2),
SH_PFC_FUNCTION(msiof3),
SH_PFC_FUNCTION(pwm0),
SH_PFC_FUNCTION(pwm1),
SH_PFC_FUNCTION(pwm2),
SH_PFC_FUNCTION(pwm3),
SH_PFC_FUNCTION(pwm4),
SH_PFC_FUNCTION(pwm5),
SH_PFC_FUNCTION(pwm6),
SH_PFC_FUNCTION(scif0),
SH_PFC_FUNCTION(scif1),
SH_PFC_FUNCTION(scif2),
@ -4002,6 +4569,7 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(sdhi1),
SH_PFC_FUNCTION(sdhi2),
SH_PFC_FUNCTION(sdhi3),
SH_PFC_FUNCTION(ssi),
};
static const struct pinmux_cfg_reg pinmux_config_regs[] = {
@ -4775,8 +5343,8 @@ static const struct pinmux_drive_reg pinmux_drive_regs[] = {
{ RCAR_GP_PIN(6, 2), 24, 3 }, /* SSI_SDATA0 */
{ RCAR_GP_PIN(6, 3), 20, 3 }, /* SSI_SDATA1 */
{ RCAR_GP_PIN(6, 4), 16, 3 }, /* SSI_SDATA2 */
{ RCAR_GP_PIN(6, 5), 12, 3 }, /* SSI_SCK34 */
{ RCAR_GP_PIN(6, 6), 8, 3 }, /* SSI_WS34 */
{ RCAR_GP_PIN(6, 5), 12, 3 }, /* SSI_SCK349 */
{ RCAR_GP_PIN(6, 6), 8, 3 }, /* SSI_WS349 */
{ RCAR_GP_PIN(6, 7), 4, 3 }, /* SSI_SDATA3 */
{ RCAR_GP_PIN(6, 8), 0, 3 }, /* SSI_SCK4 */
} },
@ -5022,8 +5590,8 @@ static const struct sh_pfc_bias_info bias_info[] = {
{ RCAR_GP_PIN(6, 9), PU5, 16 }, /* SSI_WS4 */
{ RCAR_GP_PIN(6, 8), PU5, 15 }, /* SSI_SCK4 */
{ RCAR_GP_PIN(6, 7), PU5, 14 }, /* SSI_SDATA3 */
{ RCAR_GP_PIN(6, 6), PU5, 13 }, /* SSI_WS34 */
{ RCAR_GP_PIN(6, 5), PU5, 12 }, /* SSI_SCK34 */
{ RCAR_GP_PIN(6, 6), PU5, 13 }, /* SSI_WS349 */
{ RCAR_GP_PIN(6, 5), PU5, 12 }, /* SSI_SCK349 */
{ RCAR_GP_PIN(6, 4), PU5, 11 }, /* SSI_SDATA2_A */
{ RCAR_GP_PIN(6, 3), PU5, 10 }, /* SSI_SDATA1_A */
{ RCAR_GP_PIN(6, 2), PU5, 9 }, /* SSI_SDATA0 */

View File

@ -259,6 +259,8 @@ struct sh_pfc_soc_info {
extern const struct sh_pfc_soc_info emev2_pinmux_info;
extern const struct sh_pfc_soc_info r8a73a4_pinmux_info;
extern const struct sh_pfc_soc_info r8a7740_pinmux_info;
extern const struct sh_pfc_soc_info r8a7743_pinmux_info;
extern const struct sh_pfc_soc_info r8a7745_pinmux_info;
extern const struct sh_pfc_soc_info r8a7778_pinmux_info;
extern const struct sh_pfc_soc_info r8a7779_pinmux_info;
extern const struct sh_pfc_soc_info r8a7790_pinmux_info;

View File

@ -209,6 +209,24 @@ static int stm32_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
return irq_create_fwspec_mapping(&fwspec);
}
static int stm32_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
{
struct stm32_gpio_bank *bank = gpiochip_get_data(chip);
int pin = stm32_gpio_pin(offset);
int ret;
u32 mode, alt;
stm32_pmx_get_mode(bank, pin, &mode, &alt);
if ((alt == 0) && (mode == 0))
ret = 1;
else if ((alt == 0) && (mode == 1))
ret = 0;
else
ret = -EINVAL;
return ret;
}
static const struct gpio_chip stm32_gpio_template = {
.request = stm32_gpio_request,
.free = stm32_gpio_free,
@ -217,14 +235,44 @@ static const struct gpio_chip stm32_gpio_template = {
.direction_input = stm32_gpio_direction_input,
.direction_output = stm32_gpio_direction_output,
.to_irq = stm32_gpio_to_irq,
.get_direction = stm32_gpio_get_direction,
};
static int stm32_gpio_irq_request_resources(struct irq_data *irq_data)
{
struct stm32_gpio_bank *bank = irq_data->domain->host_data;
struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent);
int ret;
ret = stm32_gpio_direction_input(&bank->gpio_chip, irq_data->hwirq);
if (ret)
return ret;
ret = gpiochip_lock_as_irq(&bank->gpio_chip, irq_data->hwirq);
if (ret) {
dev_err(pctl->dev, "unable to lock HW IRQ %lu for IRQ\n",
irq_data->hwirq);
return ret;
}
return 0;
}
static void stm32_gpio_irq_release_resources(struct irq_data *irq_data)
{
struct stm32_gpio_bank *bank = irq_data->domain->host_data;
gpiochip_unlock_as_irq(&bank->gpio_chip, irq_data->hwirq);
}
static struct irq_chip stm32_gpio_irq_chip = {
.name = "stm32gpio",
.irq_eoi = irq_chip_eoi_parent,
.irq_mask = irq_chip_mask_parent,
.irq_unmask = irq_chip_unmask_parent,
.irq_set_type = irq_chip_set_type_parent,
.irq_request_resources = stm32_gpio_irq_request_resources,
.irq_release_resources = stm32_gpio_irq_release_resources,
};
static int stm32_gpio_domain_translate(struct irq_domain *d,
@ -248,15 +296,6 @@ static void stm32_gpio_domain_activate(struct irq_domain *d,
struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent);
regmap_field_write(pctl->irqmux[irq_data->hwirq], bank->bank_nr);
gpiochip_lock_as_irq(&bank->gpio_chip, irq_data->hwirq);
}
static void stm32_gpio_domain_deactivate(struct irq_domain *d,
struct irq_data *irq_data)
{
struct stm32_gpio_bank *bank = d->host_data;
gpiochip_unlock_as_irq(&bank->gpio_chip, irq_data->hwirq);
}
static int stm32_gpio_domain_alloc(struct irq_domain *d,
@ -285,7 +324,6 @@ static const struct irq_domain_ops stm32_gpio_domain_ops = {
.alloc = stm32_gpio_domain_alloc,
.free = irq_domain_free_irqs_common,
.activate = stm32_gpio_domain_activate,
.deactivate = stm32_gpio_domain_deactivate,
};
/* Pinctrl functions */
@ -411,11 +449,6 @@ static int stm32_pctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
pin = STM32_GET_PIN_NO(pinfunc);
func = STM32_GET_PIN_FUNC(pinfunc);
if (pin >= pctl->match_data->npins) {
dev_err(pctl->dev, "invalid pin number.\n");
return -EINVAL;
}
if (!stm32_pctrl_is_function_valid(pctl, pin, func)) {
dev_err(pctl->dev, "invalid function.\n");
return -EINVAL;
@ -558,8 +591,8 @@ static void stm32_pmx_set_mode(struct stm32_gpio_bank *bank,
clk_disable(bank->clk);
}
static void stm32_pmx_get_mode(struct stm32_gpio_bank *bank,
int pin, u32 *mode, u32 *alt)
void stm32_pmx_get_mode(struct stm32_gpio_bank *bank, int pin, u32 *mode,
u32 *alt)
{
u32 val;
int alt_shift = (pin % 8) * 4;

View File

@ -45,7 +45,10 @@ struct stm32_pinctrl_match_data {
const unsigned int npins;
};
int stm32_pctl_probe(struct platform_device *pdev);
struct stm32_gpio_bank;
int stm32_pctl_probe(struct platform_device *pdev);
void stm32_pmx_get_mode(struct stm32_gpio_bank *bank,
int pin, u32 *mode, u32 *alt);
#endif /* __PINCTRL_STM32_H */

View File

@ -7,7 +7,7 @@ config PINCTRL_SUNXI
select GPIOLIB
config PINCTRL_SUN4I_A10
def_bool MACH_SUN4I
def_bool MACH_SUN4I || MACH_SUN7I
select PINCTRL_SUNXI
config PINCTRL_SUN5I
@ -23,10 +23,6 @@ config PINCTRL_SUN6I_A31_R
depends on RESET_CONTROLLER
select PINCTRL_SUNXI
config PINCTRL_SUN7I_A20
def_bool MACH_SUN7I
select PINCTRL_SUNXI
config PINCTRL_SUN8I_A23
def_bool MACH_SUN8I
select PINCTRL_SUNXI
@ -39,6 +35,10 @@ config PINCTRL_SUN8I_A83T
def_bool MACH_SUN8I
select PINCTRL_SUNXI
config PINCTRL_SUN8I_A83T_R
def_bool MACH_SUN8I
select PINCTRL_SUNXI
config PINCTRL_SUN8I_A23_R
def_bool MACH_SUN8I
depends on RESET_CONTROLLER

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