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 ...
This commit is contained in:
commit
ac7b75966c
|
@ -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>;
|
||||
};
|
||||
};
|
|
@ -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"
|
||||
|
|
|
@ -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>;
|
||||
};
|
|
@ -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.
|
||||
|
|
|
@ -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";
|
||||
};
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -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.
|
||||
|
|
|
@ -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>;
|
||||
};
|
|
@ -43,6 +43,7 @@ available subsections can be seen below.
|
|||
80211/index
|
||||
uio-howto
|
||||
firmware/index
|
||||
pinctl
|
||||
misc_devices
|
||||
|
||||
.. only:: subproject and html
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -29,18 +29,30 @@ &ext {
|
|||
|
||||
&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 @@ nandc: nand-controller@1 {
|
|||
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@1 {
|
|||
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 @@ partition@0x8c00000 {
|
|||
&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;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -55,6 +55,74 @@ rtc_dev: rtc@10003000 {
|
|||
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>;
|
||||
|
|
|
@ -44,6 +44,104 @@ cgu: jz4780-cgu@10000000 {
|
|||
#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>;
|
||||
|
|
|
@ -17,3 +17,16 @@ &ext {
|
|||
&rtc_dev {
|
||||
system-power-controller;
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pins_uart0>;
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
pins_uart0: uart0 {
|
||||
function = "uart0";
|
||||
groups = "uart0-data";
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
|
@ -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 @@ static int jz4740_mmc_probe(struct platform_device* pdev)
|
|||
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,
|
||||
|
|
|
@ -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 @@ static int jz_nand_detect_bank(struct platform_device *pdev,
|
|||
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 @@ static int jz_nand_probe(struct platform_device *pdev)
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */ }
|
||||
|
|
|
@ -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[] = {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
|
@ -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);
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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), \
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
@ -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 = {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 }, \
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(®, 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(®, 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(®, 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(®, 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(®, 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;
|
||||
|
||||
|
|
|
@ -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);
|
|
@ -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);
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
|
@ -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, ®);
|
||||
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 @@ static void mcp23s08_dbg_show(struct seq_file *s, struct gpio_chip *chip)
|
|||
|
||||
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",
|
|
@ -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, ®, &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
|
@ -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));
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
};
|
|
@ -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
|
@ -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 */
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue