mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-10 07:00:48 +00:00
This is the bulk pin control changes for the v3.17 merge
development cycle: - Get rid of the .disable() callback from the driver callback vtable. This callback was abused and counterintuitive since a pin or group of pins can be said to always be in some setting, and never really disabled. We now only enable a certain muxing, and move between some certain muxings, we never "disable" a mux setting. - Some janitorial moving the MSM, Samsung and Nomadik and drivers to their own subdirectories for a clearer view in the subsystem. This will continue. - Kill off the use of the return value from gpiochip_remove(), this will be done in parallel in the GPIO subsystem and hopefully not trigger too many unchecked return value warnings before we get rid of this altogether. - A huge set of changes and improvements to the Allwinner sunxi drivers especially for their latest A23 and A31 SoCs, and some ground work for the new sun8i platform family. - A large set of Rockchip driver improvements adding support for the RK3288 SoC. - Advances in migration of older Freescale platforms to pin control, especially i.MX1. - Samsung and Exynos improvements. - Support for the Qualcomm MSM8960 SoC. - Use the gpiolib irqchip helpers for the ST SPEAr and Intel Baytrail drivers. - A bunch of nice janitorial work done with cppcheck. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJT41HwAAoJEEEQszewGV1zVN0QAMJOJcsjYyHG+b/y0upJ5n1c tyPelyxKrpGUUTvTsO5LiqvoIfa2E/DrwXupRAC4zAXvb+x3TUGkiluK4Yxl5e56 AqjePnSydqqHiRZOK4Q06W7VwGUoxLltDmDPTcra+DAaijIeKUPMQE1MvcPxisMe IR7PZN58JYCG3ZV5yjwfBBxcRAm8KiiwHvQdBywPIGGvvmpy1X+U96U869nQgUH2 70lpJVPx75bhyAFk99bE9nAnroZeRR7mvijjf26ssyAFNqeJ0K7Xlom+NtpHdiw0 lsDKdBiAWVbZON/7Pc24gpHzhBoIYdA/6LxPA8Xz4QVFRmfxmNkZhuXZnZ7Dbuj2 xv9HtnjExqjZcfeNyUlO0iQDEQIUN/oPkaBS2G8DNZ/bmQqC8EzkIFh6F72KO1s2 7FU214LcuBYuAa3HvNLmgtjSkgou8tTMj58rnZ1XDr2mI9tzlrwI3i6ZrJZWKDur NIoRAcUZkFiMpXxqLbk4UXzDvuJgrzaFiQ2PkxTXAlC2DjXz+gXPzPIOSD5LTaHE k3WvZfuGK2iPoKeDHaLx2qEl9PoD5hz1JH3o+bgOKkRZG2gEJWd02JwhuPyRPLfc TeBgmdYS2t2MBS21VsqoObw8336oCHJu7tDAxTkAalLsZy9MV2WqThhZoYggZ/Rq yMqCr8vfd2pRVtwYe7Wc =t1pR -----END PGP SIGNATURE----- Merge tag 'pinctrl-v3.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl Pull pinctrl updates from Linus Walleij: "This is the bulk pin control changes for the v3.17 merge development cycle: - get rid of the .disable() callback from the driver callback vtable. This callback was abused and counterintuitive since a pin or group of pins can be said to always be in some setting, and never really disabled. We now only enable a certain muxing, and move between some certain muxings, we never "disable" a mux setting - some janitorial moving the MSM, Samsung and Nomadik and drivers to their own subdirectories for a clearer view in the subsystem. This will continue - kill off the use of the return value from gpiochip_remove(), this will be done in parallel in the GPIO subsystem and hopefully not trigger too many unchecked return value warnings before we get rid of this altogether - a huge set of changes and improvements to the Allwinner sunxi drivers especially for their latest A23 and A31 SoCs, and some ground work for the new sun8i platform family - a large set of Rockchip driver improvements adding support for the RK3288 SoC - advances in migration of older Freescale platforms to pin control, especially i.MX1 - Samsung and Exynos improvements - support for the Qualcomm MSM8960 SoC - use the gpiolib irqchip helpers for the ST SPEAr and Intel Baytrail drivers - a bunch of nice janitorial work done with cppcheck" * tag 'pinctrl-v3.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (61 commits) pinctrl: baytrail: Convert to use gpiolib irqchip pinctrl: sunxi: number gpio ranges starting from 0 pinctrl: sunxi: use gpiolib API to mark a GPIO used as an IRQ pinctrl: rockchip: add drive-strength control for rk3288 pinctrl: rockchip: add separate type for rk3288 pinctrl: rockchip: set is_generic in pinconf_ops pinctrl: msm: drop negativity check on unsigned value pinctrl: remove all usage of gpio_remove ret val in driver/pinctl pinctrl: qcom: Make muxing of gpio function explicit pinctrl: nomadik: move all Nomadik drivers to subdir pinctrl: samsung: Group all drivers in a sub-dir sh-pfc: sh73a0: Introduce the use of devm_regulator_register sh-pfc: Add renesas,pfc-r8a7791 to binding documentation pinctrl: msm: move all qualcomm drivers to subdir pinctrl: msm: Add msm8960 definitions pinctrl: samsung: Allow pin value to be initialized using pinfunc pinctrl: samsung: Allow grouping multiple pinmux/pinconf nodes pinctrl: exynos: Consolidate irq_chips of GPIO and WKUP EINTs pinctrl: samsung: Handle GPIO request and free using pinctrl helpers pinctrl: samsung: Decouple direction setting from pinctrl ...
This commit is contained in:
commit
e0b8b78651
@ -13,6 +13,8 @@ Required properties:
|
||||
"allwinner,sun6i-a31-pinctrl"
|
||||
"allwinner,sun6i-a31-r-pinctrl"
|
||||
"allwinner,sun7i-a20-pinctrl"
|
||||
"allwinner,sun8i-a23-pinctrl"
|
||||
"allwinner,sun8i-a23-r-pinctrl"
|
||||
- reg: Should contain the register physical address and length for the
|
||||
pin controller.
|
||||
|
||||
|
@ -46,7 +46,7 @@ Valid values for pins are:
|
||||
gpio0-gpio89
|
||||
|
||||
Valid values for function are:
|
||||
cam_mclk, codec_mic_i2s, codec_spkr_i2s, gsbi1, gsbi2, gsbi3, gsbi4,
|
||||
cam_mclk, codec_mic_i2s, codec_spkr_i2s, gpio, gsbi1, gsbi2, gsbi3, gsbi4,
|
||||
gsbi4_cam_i2c, gsbi5, gsbi5_spi_cs1, gsbi5_spi_cs2, gsbi5_spi_cs3, gsbi6,
|
||||
gsbi6_spi_cs1, gsbi6_spi_cs2, gsbi6_spi_cs3, gsbi7, gsbi7_spi_cs1,
|
||||
gsbi7_spi_cs2, gsbi7_spi_cs3, gsbi_cam_i2c, hdmi, mi2s, riva_bt, riva_fm,
|
||||
|
@ -51,7 +51,7 @@ Valid values for qcom,pins are:
|
||||
|
||||
|
||||
Valid values for function are:
|
||||
mdio, mi2s, pdm, ssbi, spmi, audio_pcm, gsbi1, gsbi2, gsbi4, gsbi5,
|
||||
mdio, mi2s, pdm, ssbi, spmi, audio_pcm, gpio, gsbi1, gsbi2, gsbi4, gsbi5,
|
||||
gsbi5_spi_cs1, gsbi5_spi_cs2, gsbi5_spi_cs3, gsbi6, gsbi7, nss_spi, sdc1,
|
||||
spdif, nand, tsif1, tsif2, usb_fs_n, usb_fs, usb2_hsic, rgmii2, sata,
|
||||
pcie1_rst, pcie1_prsnt, pcie1_pwren_n, pcie1_pwren, pcie1_pwrflt,
|
||||
|
@ -0,0 +1,181 @@
|
||||
Qualcomm MSM8960 TLMM block
|
||||
|
||||
This binding describes the Top Level Mode Multiplexer block found in the
|
||||
MSM8960 platform.
|
||||
|
||||
- compatible:
|
||||
Usage: required
|
||||
Value type: <string>
|
||||
Definition: must be "qcom,msm8960-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 abitrary 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-gpio151,
|
||||
sdc1_clk,
|
||||
sdc1_cmd,
|
||||
sdc1_data
|
||||
sdc3_clk,
|
||||
sdc3_cmd,
|
||||
sdc3_data
|
||||
|
||||
- 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:
|
||||
audio_pcm, bt, cam_mclk0, cam_mclk1, cam_mclk2,
|
||||
codec_mic_i2s, codec_spkr_i2s, ext_gps, fm, gps_blanking,
|
||||
gps_pps_in, gps_pps_out, gp_clk_0a, gp_clk_0b, gp_clk_1a,
|
||||
gp_clk_1b, gp_clk_2a, gp_clk_2b, gp_mn, gp_pdm_0a,
|
||||
gp_pdm_0b, gp_pdm_1a, gp_pdm_1b, gp_pdm_2a, gp_pdm_2b, gpio,
|
||||
gsbi1, gsbi1_spi_cs1_n, gsbi1_spi_cs2a_n, gsbi1_spi_cs2b_n,
|
||||
gsbi1_spi_cs3_n, gsbi2, gsbi2_spi_cs1_n, gsbi2_spi_cs2_n,
|
||||
gsbi2_spi_cs3_n, gsbi3, gsbi4, gsbi4_3d_cam_i2c_l,
|
||||
gsbi4_3d_cam_i2c_r, gsbi5, gsbi5_3d_cam_i2c_l,
|
||||
gsbi5_3d_cam_i2c_r, gsbi6, gsbi7, gsbi8, gsbi9, gsbi10,
|
||||
gsbi11, gsbi11_spi_cs1a_n, gsbi11_spi_cs1b_n,
|
||||
gsbi11_spi_cs2a_n, gsbi11_spi_cs2b_n, gsbi11_spi_cs3_n,
|
||||
gsbi12, hdmi_cec, hdmi_ddc_clock, hdmi_ddc_data,
|
||||
hdmi_hot_plug_detect, hsic, mdp_vsync, mi2s, mic_i2s,
|
||||
pmb_clk, pmb_ext_ctrl, ps_hold, rpm_wdog, sdc2, sdc4, sdc5,
|
||||
slimbus1, slimbus2, spkr_i2s, ssbi1, ssbi2, ssbi_ext_gps,
|
||||
ssbi_pmic2, ssbi_qpa1, ssbi_ts, tsif1, tsif2, ts_eoc,
|
||||
usb_fs1, usb_fs1_oe, usb_fs1_oe_n, usb_fs2, usb_fs2_oe,
|
||||
usb_fs2_oe_n, vfe_camif_timer1_a, vfe_camif_timer1_b,
|
||||
vfe_camif_timer2, vfe_camif_timer3_a, vfe_camif_timer3_b,
|
||||
vfe_camif_timer4_a, vfe_camif_timer4_b, vfe_camif_timer4_c,
|
||||
vfe_camif_timer5_a, vfe_camif_timer5_b, vfe_camif_timer6_a,
|
||||
vfe_camif_timer6_b, vfe_camif_timer6_c, vfe_camif_timer7_a,
|
||||
vfe_camif_timer7_b, vfe_camif_timer7_c, wlan
|
||||
|
||||
- bias-disable:
|
||||
Usage: optional
|
||||
Value type: <none>
|
||||
Definition: The specified pins should be configued as no pull.
|
||||
|
||||
- bias-pull-down:
|
||||
Usage: optional
|
||||
Value type: <none>
|
||||
Definition: The specified pins should be configued as pull down.
|
||||
|
||||
- bias-pull-up:
|
||||
Usage: optional
|
||||
Value type: <none>
|
||||
Definition: The specified pins should be configued as pull up.
|
||||
|
||||
- output-high:
|
||||
Usage: optional
|
||||
Value type: <none>
|
||||
Definition: The specified pins are configured in output mode, driven
|
||||
high.
|
||||
Not valid for sdc pins.
|
||||
|
||||
- output-low:
|
||||
Usage: optional
|
||||
Value type: <none>
|
||||
Definition: The specified pins are configured in output mode, driven
|
||||
low.
|
||||
Not valid for sdc pins.
|
||||
|
||||
- drive-strength:
|
||||
Usage: optional
|
||||
Value type: <u32>
|
||||
Definition: Selects the drive strength for the specified pins, in mA.
|
||||
Valid values are: 2, 4, 6, 8, 10, 12, 14 and 16
|
||||
|
||||
Example:
|
||||
|
||||
msmgpio: pinctrl@800000 {
|
||||
compatible = "qcom,msm8960-pinctrl";
|
||||
reg = <0x800000 0x4000>;
|
||||
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
interrupts = <0 16 0x4>;
|
||||
|
||||
gsbi8_uart: gsbi8-uart {
|
||||
mux {
|
||||
pins = "gpio34", "gpio35";
|
||||
function = "gsbi8";
|
||||
};
|
||||
|
||||
tx {
|
||||
pins = "gpio34";
|
||||
drive-strength = <4>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
rx {
|
||||
pins = "gpio35";
|
||||
drive-strength = <2>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
};
|
@ -70,7 +70,7 @@ Valid values for function are:
|
||||
cam_mckl0, cam_mclk1, cam_mclk2, cam_mclk3, mdp_vsync, hdmi_cec, hdmi_ddc,
|
||||
hdmi_hpd, edp_hpd, gp_pdm0, gp_pdm1, gp_pdm2, gp_pdm3, gp0_clk, gp1_clk,
|
||||
gp_mn, tsif1, tsif2, hsic, grfc, audio_ref_clk, qua_mi2s, pri_mi2s, spkr_mi2s,
|
||||
ter_mi2s, sec_mi2s, bt, fm, wlan, slimbus
|
||||
ter_mi2s, sec_mi2s, bt, fm, wlan, slimbus, gpio
|
||||
|
||||
(Note that this is not yet the complete list of functions)
|
||||
|
||||
|
@ -15,6 +15,7 @@ Required Properties:
|
||||
- "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.
|
||||
- "renesas,pfc-r8a7791": for R8A7791 (R-Car M2) compatible pin-controller.
|
||||
- "renesas,pfc-sh7372": for SH7372 (SH-Mobile AP4) compatible pin-controller.
|
||||
- "renesas,pfc-sh73a0": for SH73A0 (SH-Mobile AG5) compatible pin-controller.
|
||||
|
||||
|
@ -21,6 +21,7 @@ defined as gpio sub-nodes of the pinmux controller.
|
||||
Required properties for iomux controller:
|
||||
- compatible: one of "rockchip,rk2928-pinctrl", "rockchip,rk3066a-pinctrl"
|
||||
"rockchip,rk3066b-pinctrl", "rockchip,rk3188-pinctrl"
|
||||
"rockchip,rk3288-pinctrl"
|
||||
- rockchip,grf: phandle referencing a syscon providing the
|
||||
"general register files"
|
||||
|
||||
@ -36,7 +37,7 @@ Deprecated properties for iomux controller:
|
||||
Use rockchip,grf and rockchip,pmu described above instead.
|
||||
|
||||
Required properties for gpio sub nodes:
|
||||
- compatible: "rockchip,gpio-bank", "rockchip,rk3188-gpio-bank0"
|
||||
- compatible: "rockchip,gpio-bank"
|
||||
- reg: register of the gpio bank (different than the iomux registerset)
|
||||
- interrupts: base interrupt of the gpio bank in the interrupt controller
|
||||
- clocks: clock that drives this bank
|
||||
@ -50,6 +51,7 @@ Required properties for gpio sub nodes:
|
||||
bindings/interrupt-controller/interrupts.txt
|
||||
|
||||
Deprecated properties for gpio sub nodes:
|
||||
- compatible: "rockchip,rk3188-gpio-bank0"
|
||||
- reg: second element: separate pull register for rk3188 bank0, use
|
||||
rockchip,pmu described above instead
|
||||
|
||||
|
@ -44,7 +44,11 @@ Required Properties:
|
||||
- Pin mux/config groups as child nodes: The pin mux (selecting pin function
|
||||
mode) and pin config (pull up/down, driver strength) settings are represented
|
||||
as child nodes of the pin-controller node. There should be atleast one
|
||||
child node and there is no limit on the count of these child nodes.
|
||||
child node and there is no limit on the count of these child nodes. It is
|
||||
also possible for a child node to consist of several further child nodes
|
||||
to allow grouping multiple pinctrl groups into one. The format of second
|
||||
level child nodes is exactly the same as for first level ones and is
|
||||
described below.
|
||||
|
||||
The child node should contain a list of pin(s) on which a particular pin
|
||||
function selection or pin configuration (or both) have to applied. This
|
||||
@ -71,6 +75,7 @@ Required Properties:
|
||||
"samsung,pins" property of the child node. The following pin configuration
|
||||
properties are supported.
|
||||
|
||||
- samsung,pin-val: Initial value of pin output buffer.
|
||||
- samsung,pin-pud: Pull up/down configuration.
|
||||
- samsung,pin-drv: Drive strength configuration.
|
||||
- samsung,pin-pud-pdn: Pull up/down configuration in power down mode.
|
||||
@ -249,6 +254,23 @@ Example 1: A pin-controller node with pin groups.
|
||||
samsung,pin-pud = <3>;
|
||||
samsung,pin-drv = <0>;
|
||||
};
|
||||
|
||||
sd4_bus8: sd4-bus-width8 {
|
||||
part-1 {
|
||||
samsung,pins = "gpk0-3", "gpk0-4",
|
||||
"gpk0-5", "gpk0-6";
|
||||
samsung,pin-function = <3>;
|
||||
samsung,pin-pud = <3>;
|
||||
samsung,pin-drv = <3>;
|
||||
};
|
||||
part-2 {
|
||||
samsung,pins = "gpk1-3", "gpk1-4",
|
||||
"gpk1-5", "gpk1-6";
|
||||
samsung,pin-function = <4>;
|
||||
samsung,pin-pud = <4>;
|
||||
samsung,pin-drv = <3>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
Example 2: A pin-controller node with external wakeup interrupt controller node.
|
||||
|
@ -101,14 +101,6 @@
|
||||
#define MX27_PAD_CONTRAST__GPIO1_30 0x1e 0x032
|
||||
#define MX27_PAD_OE_ACD__OE_ACD 0x1f 0x004
|
||||
#define MX27_PAD_OE_ACD__GPIO1_31 0x1f 0x032
|
||||
#define MX27_PAD_UNUSED0__UNUSED0 0x20 0x004
|
||||
#define MX27_PAD_UNUSED0__GPIO2_0 0x20 0x032
|
||||
#define MX27_PAD_UNUSED1__UNUSED1 0x21 0x004
|
||||
#define MX27_PAD_UNUSED1__GPIO2_1 0x21 0x032
|
||||
#define MX27_PAD_UNUSED2__UNUSED2 0x22 0x004
|
||||
#define MX27_PAD_UNUSED2__GPIO2_2 0x22 0x032
|
||||
#define MX27_PAD_UNUSED3__UNUSED3 0x23 0x004
|
||||
#define MX27_PAD_UNUSED3__GPIO2_3 0x23 0x032
|
||||
#define MX27_PAD_SD2_D0__SD2_D0 0x24 0x004
|
||||
#define MX27_PAD_SD2_D0__MSHC_DATA0 0x24 0x005
|
||||
#define MX27_PAD_SD2_D0__GPIO2_4 0x24 0x032
|
||||
@ -183,16 +175,6 @@
|
||||
#define MX27_PAD_USBH1_RXDP__USBH1_RXDP 0x3f 0x004
|
||||
#define MX27_PAD_USBH1_RXDP__UART4_RXD 0x3f 0x001
|
||||
#define MX27_PAD_USBH1_RXDP__GPIO2_31 0x3f 0x032
|
||||
#define MX27_PAD_UNUSED4__UNUSED4 0x40 0x004
|
||||
#define MX27_PAD_UNUSED4__GPIO3_0 0x40 0x032
|
||||
#define MX27_PAD_UNUSED5__UNUSED5 0x41 0x004
|
||||
#define MX27_PAD_UNUSED5__GPIO3_1 0x41 0x032
|
||||
#define MX27_PAD_UNUSED6__UNUSED6 0x42 0x004
|
||||
#define MX27_PAD_UNUSED6__GPIO3_2 0x42 0x032
|
||||
#define MX27_PAD_UNUSED7__UNUSED7 0x43 0x004
|
||||
#define MX27_PAD_UNUSED7__GPIO3_3 0x43 0x032
|
||||
#define MX27_PAD_UNUSED8__UNUSED8 0x44 0x004
|
||||
#define MX27_PAD_UNUSED8__GPIO3_4 0x44 0x032
|
||||
#define MX27_PAD_I2C2_SDA__I2C2_SDA 0x45 0x004
|
||||
#define MX27_PAD_I2C2_SDA__GPIO3_5 0x45 0x032
|
||||
#define MX27_PAD_I2C2_SCL__I2C2_SCL 0x46 0x004
|
||||
@ -422,18 +404,6 @@
|
||||
#define MX27_PAD_USBOTG_CLK__GPIO5_24 0x98 0x032
|
||||
#define MX27_PAD_USBOTG_DATA7__USBOTG_DATA7 0x99 0x004
|
||||
#define MX27_PAD_USBOTG_DATA7__GPIO5_25 0x99 0x032
|
||||
#define MX27_PAD_UNUSED9__UNUSED9 0x9a 0x004
|
||||
#define MX27_PAD_UNUSED9__GPIO5_26 0x9a 0x032
|
||||
#define MX27_PAD_UNUSED10__UNUSED10 0x9b 0x004
|
||||
#define MX27_PAD_UNUSED10__GPIO5_27 0x9b 0x032
|
||||
#define MX27_PAD_UNUSED11__UNUSED11 0x9c 0x004
|
||||
#define MX27_PAD_UNUSED11__GPIO5_28 0x9c 0x032
|
||||
#define MX27_PAD_UNUSED12__UNUSED12 0x9d 0x004
|
||||
#define MX27_PAD_UNUSED12__GPIO5_29 0x9d 0x032
|
||||
#define MX27_PAD_UNUSED13__UNUSED13 0x9e 0x004
|
||||
#define MX27_PAD_UNUSED13__GPIO5_30 0x9e 0x032
|
||||
#define MX27_PAD_UNUSED14__UNUSED14 0x9f 0x004
|
||||
#define MX27_PAD_UNUSED14__GPIO5_31 0x9f 0x032
|
||||
#define MX27_PAD_NFRB__NFRB 0xa0 0x000
|
||||
#define MX27_PAD_NFRB__ETMTRACEPKT3 0xa0 0x005
|
||||
#define MX27_PAD_NFRB__GPIO6_0 0xa0 0x032
|
||||
@ -506,21 +476,5 @@
|
||||
#define MX27_PAD_ATA_DATA15__ETMTRACEPKT4 0xb7 0x005
|
||||
#define MX27_PAD_ATA_DATA15__FEC_TX_EN 0xb7 0x006
|
||||
#define MX27_PAD_ATA_DATA15__GPIO6_23 0xb7 0x032
|
||||
#define MX27_PAD_UNUSED15__UNUSED15 0xb8 0x004
|
||||
#define MX27_PAD_UNUSED15__GPIO6_24 0xb8 0x032
|
||||
#define MX27_PAD_UNUSED16__UNUSED16 0xb9 0x004
|
||||
#define MX27_PAD_UNUSED16__GPIO6_25 0xb9 0x032
|
||||
#define MX27_PAD_UNUSED17__UNUSED17 0xba 0x004
|
||||
#define MX27_PAD_UNUSED17__GPIO6_26 0xba 0x032
|
||||
#define MX27_PAD_UNUSED18__UNUSED18 0xbb 0x004
|
||||
#define MX27_PAD_UNUSED18__GPIO6_27 0xbb 0x032
|
||||
#define MX27_PAD_UNUSED19__UNUSED19 0xbc 0x004
|
||||
#define MX27_PAD_UNUSED19__GPIO6_28 0xbc 0x032
|
||||
#define MX27_PAD_UNUSED20__UNUSED20 0xbd 0x004
|
||||
#define MX27_PAD_UNUSED20__GPIO6_29 0xbd 0x032
|
||||
#define MX27_PAD_UNUSED21__UNUSED21 0xbe 0x004
|
||||
#define MX27_PAD_UNUSED21__GPIO6_30 0xbe 0x032
|
||||
#define MX27_PAD_UNUSED22__UNUSED22 0xbf 0x004
|
||||
#define MX27_PAD_UNUSED22__GPIO6_31 0xbf 0x032
|
||||
|
||||
#endif /* __DTS_IMX27_PINFUNC_H */
|
||||
|
@ -4,7 +4,6 @@ menuconfig ARCH_SUNXI
|
||||
select CLKSRC_MMIO
|
||||
select GENERIC_IRQ_CHIP
|
||||
select PINCTRL
|
||||
select PINCTRL_SUNXI
|
||||
select SUN4I_TIMER
|
||||
|
||||
if ARCH_SUNXI
|
||||
|
@ -11,10 +11,10 @@ menu "Pin controllers"
|
||||
depends on PINCTRL
|
||||
|
||||
config PINMUX
|
||||
bool "Support pin multiplexing controllers"
|
||||
bool "Support pin multiplexing controllers" if COMPILE_TEST
|
||||
|
||||
config PINCONF
|
||||
bool "Support pin configuration controllers"
|
||||
bool "Support pin configuration controllers" if COMPILE_TEST
|
||||
|
||||
config GENERIC_PINCONF
|
||||
bool
|
||||
@ -26,29 +26,6 @@ config DEBUG_PINCTRL
|
||||
help
|
||||
Say Y here to add some extra checks and diagnostics to PINCTRL calls.
|
||||
|
||||
config PINCTRL_ABX500
|
||||
bool "ST-Ericsson ABx500 family Mixed Signal Circuit gpio functions"
|
||||
depends on AB8500_CORE
|
||||
select GENERIC_PINCONF
|
||||
help
|
||||
Select this to enable the ABx500 family IC GPIO driver
|
||||
|
||||
config PINCTRL_AB8500
|
||||
bool "AB8500 pin controller driver"
|
||||
depends on PINCTRL_ABX500 && ARCH_U8500
|
||||
|
||||
config PINCTRL_AB8540
|
||||
bool "AB8540 pin controller driver"
|
||||
depends on PINCTRL_ABX500 && ARCH_U8500
|
||||
|
||||
config PINCTRL_AB9540
|
||||
bool "AB9540 pin controller driver"
|
||||
depends on PINCTRL_ABX500 && ARCH_U8500
|
||||
|
||||
config PINCTRL_AB8505
|
||||
bool "AB8505 pin controller driver"
|
||||
depends on PINCTRL_ABX500 && ARCH_U8500
|
||||
|
||||
config PINCTRL_ADI2
|
||||
bool "ADI pin controller driver"
|
||||
depends on BLACKFIN
|
||||
@ -93,7 +70,7 @@ config PINCTRL_AT91
|
||||
config PINCTRL_BAYTRAIL
|
||||
bool "Intel Baytrail GPIO pin control"
|
||||
depends on GPIOLIB && ACPI && X86
|
||||
select IRQ_DOMAIN
|
||||
select GPIOLIB_IRQCHIP
|
||||
help
|
||||
driver for memory mapped GPIO functionality on Intel Baytrail
|
||||
platforms. Supports 3 banks with 102, 28 and 44 gpios.
|
||||
@ -130,6 +107,13 @@ config PINCTRL_IMX1_CORE
|
||||
select PINMUX
|
||||
select PINCONF
|
||||
|
||||
config PINCTRL_IMX1
|
||||
bool "IMX1 pinctrl driver"
|
||||
depends on SOC_IMX1
|
||||
select PINCTRL_IMX1_CORE
|
||||
help
|
||||
Say Y here to enable the imx1 pinctrl driver
|
||||
|
||||
config PINCTRL_IMX27
|
||||
bool "IMX27 pinctrl driver"
|
||||
depends on SOC_IMX27
|
||||
@ -226,58 +210,6 @@ config PINCTRL_IMX28
|
||||
bool
|
||||
select PINCTRL_MXS
|
||||
|
||||
config PINCTRL_MSM
|
||||
bool
|
||||
select PINMUX
|
||||
select PINCONF
|
||||
select GENERIC_PINCONF
|
||||
select GPIOLIB_IRQCHIP
|
||||
|
||||
config PINCTRL_APQ8064
|
||||
tristate "Qualcomm APQ8064 pin controller driver"
|
||||
depends on GPIOLIB && OF
|
||||
select PINCTRL_MSM
|
||||
help
|
||||
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
|
||||
Qualcomm TLMM block found in the Qualcomm APQ8064 platform.
|
||||
|
||||
config PINCTRL_IPQ8064
|
||||
tristate "Qualcomm IPQ8064 pin controller driver"
|
||||
depends on GPIOLIB && OF
|
||||
select PINCTRL_MSM
|
||||
help
|
||||
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
|
||||
Qualcomm TLMM block found in the Qualcomm IPQ8064 platform.
|
||||
|
||||
config PINCTRL_MSM8X74
|
||||
tristate "Qualcomm 8x74 pin controller driver"
|
||||
depends on GPIOLIB && OF && (ARCH_QCOM || COMPILE_TEST)
|
||||
select PINCTRL_MSM
|
||||
help
|
||||
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
|
||||
Qualcomm TLMM block found in the Qualcomm 8974 platform.
|
||||
|
||||
config PINCTRL_NOMADIK
|
||||
bool "Nomadik pin controller driver"
|
||||
depends on ARCH_U8500 || ARCH_NOMADIK
|
||||
select PINMUX
|
||||
select PINCONF
|
||||
select GPIOLIB
|
||||
select OF_GPIO
|
||||
select GPIOLIB_IRQCHIP
|
||||
|
||||
config PINCTRL_STN8815
|
||||
bool "STN8815 pin controller driver"
|
||||
depends on PINCTRL_NOMADIK && ARCH_NOMADIK
|
||||
|
||||
config PINCTRL_DB8500
|
||||
bool "DB8500 pin controller driver"
|
||||
depends on PINCTRL_NOMADIK && ARCH_U8500
|
||||
|
||||
config PINCTRL_DB8540
|
||||
bool "DB8540 pin controller driver"
|
||||
depends on PINCTRL_NOMADIK && ARCH_U8500
|
||||
|
||||
config PINCTRL_ROCKCHIP
|
||||
bool
|
||||
select PINMUX
|
||||
@ -356,22 +288,6 @@ config PINCTRL_COH901
|
||||
COH 901 335 and COH 901 571/3. They contain 3, 5 or 7
|
||||
ports of 8 GPIO pins each.
|
||||
|
||||
config PINCTRL_SAMSUNG
|
||||
bool
|
||||
select PINMUX
|
||||
select PINCONF
|
||||
|
||||
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
|
||||
|
||||
config PINCTRL_EXYNOS5440
|
||||
bool "Samsung EXYNOS5440 SoC pinctrl driver"
|
||||
depends on SOC_EXYNOS5440
|
||||
select PINMUX
|
||||
select PINCONF
|
||||
|
||||
config PINCTRL_PALMAS
|
||||
bool "Pinctrl driver for the PALMAS Series MFD devices"
|
||||
depends on OF && MFD_PALMAS
|
||||
@ -383,18 +299,11 @@ config PINCTRL_PALMAS
|
||||
open drain configuration for the Palmas series devices like
|
||||
TPS65913, TPS80036 etc.
|
||||
|
||||
config PINCTRL_S3C24XX
|
||||
bool "Samsung S3C24XX SoC pinctrl driver"
|
||||
depends on ARCH_S3C24XX
|
||||
select PINCTRL_SAMSUNG
|
||||
|
||||
config PINCTRL_S3C64XX
|
||||
bool "Samsung S3C64XX SoC pinctrl driver"
|
||||
depends on ARCH_S3C64XX
|
||||
select PINCTRL_SAMSUNG
|
||||
|
||||
source "drivers/pinctrl/berlin/Kconfig"
|
||||
source "drivers/pinctrl/mvebu/Kconfig"
|
||||
source "drivers/pinctrl/nomadik/Kconfig"
|
||||
source "drivers/pinctrl/qcom/Kconfig"
|
||||
source "drivers/pinctrl/samsung/Kconfig"
|
||||
source "drivers/pinctrl/sh-pfc/Kconfig"
|
||||
source "drivers/pinctrl/spear/Kconfig"
|
||||
source "drivers/pinctrl/sunxi/Kconfig"
|
||||
|
@ -9,11 +9,6 @@ ifeq ($(CONFIG_OF),y)
|
||||
obj-$(CONFIG_PINCTRL) += devicetree.o
|
||||
endif
|
||||
obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o
|
||||
obj-$(CONFIG_PINCTRL_ABX500) += pinctrl-abx500.o
|
||||
obj-$(CONFIG_PINCTRL_AB8500) += pinctrl-ab8500.o
|
||||
obj-$(CONFIG_PINCTRL_AB8540) += pinctrl-ab8540.o
|
||||
obj-$(CONFIG_PINCTRL_AB9540) += pinctrl-ab9540.o
|
||||
obj-$(CONFIG_PINCTRL_AB8505) += pinctrl-ab8505.o
|
||||
obj-$(CONFIG_PINCTRL_ADI2) += pinctrl-adi2.o
|
||||
obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o
|
||||
obj-$(CONFIG_PINCTRL_BF54x) += pinctrl-adi2-bf54x.o
|
||||
@ -24,6 +19,7 @@ obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o
|
||||
obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o
|
||||
obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o
|
||||
obj-$(CONFIG_PINCTRL_IMX1_CORE) += pinctrl-imx1-core.o
|
||||
obj-$(CONFIG_PINCTRL_IMX1) += pinctrl-imx1.o
|
||||
obj-$(CONFIG_PINCTRL_IMX27) += pinctrl-imx27.o
|
||||
obj-$(CONFIG_PINCTRL_IMX35) += pinctrl-imx35.o
|
||||
obj-$(CONFIG_PINCTRL_IMX50) += pinctrl-imx50.o
|
||||
@ -38,14 +34,6 @@ obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o
|
||||
obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o
|
||||
obj-$(CONFIG_PINCTRL_IMX25) += pinctrl-imx25.o
|
||||
obj-$(CONFIG_PINCTRL_IMX28) += pinctrl-imx28.o
|
||||
obj-$(CONFIG_PINCTRL_MSM) += pinctrl-msm.o
|
||||
obj-$(CONFIG_PINCTRL_APQ8064) += pinctrl-apq8064.o
|
||||
obj-$(CONFIG_PINCTRL_IPQ8064) += pinctrl-ipq8064.o
|
||||
obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o
|
||||
obj-$(CONFIG_PINCTRL_NOMADIK) += pinctrl-nomadik.o
|
||||
obj-$(CONFIG_PINCTRL_STN8815) += pinctrl-nomadik-stn8815.o
|
||||
obj-$(CONFIG_PINCTRL_DB8500) += pinctrl-nomadik-db8500.o
|
||||
obj-$(CONFIG_PINCTRL_DB8540) += pinctrl-nomadik-db8540.o
|
||||
obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o
|
||||
obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
|
||||
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
|
||||
@ -59,11 +47,6 @@ obj-$(CONFIG_PINCTRL_TZ1090) += pinctrl-tz1090.o
|
||||
obj-$(CONFIG_PINCTRL_TZ1090_PDC) += pinctrl-tz1090-pdc.o
|
||||
obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o
|
||||
obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o
|
||||
obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o
|
||||
obj-$(CONFIG_PINCTRL_EXYNOS) += pinctrl-exynos.o
|
||||
obj-$(CONFIG_PINCTRL_EXYNOS5440) += pinctrl-exynos5440.o
|
||||
obj-$(CONFIG_PINCTRL_S3C24XX) += pinctrl-s3c24xx.o
|
||||
obj-$(CONFIG_PINCTRL_S3C64XX) += pinctrl-s3c64xx.o
|
||||
obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o
|
||||
obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o
|
||||
obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o
|
||||
@ -72,8 +55,11 @@ obj-$(CONFIG_PINCTRL_VF610) += pinctrl-vf610.o
|
||||
|
||||
obj-$(CONFIG_ARCH_BERLIN) += berlin/
|
||||
obj-$(CONFIG_PLAT_ORION) += mvebu/
|
||||
obj-y += nomadik/
|
||||
obj-$(CONFIG_ARCH_QCOM) += qcom/
|
||||
obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
|
||||
obj-$(CONFIG_ARCH_SHMOBILE) += sh-pfc/
|
||||
obj-$(CONFIG_SUPERH) += sh-pfc/
|
||||
obj-$(CONFIG_PLAT_SPEAR) += spear/
|
||||
obj-$(CONFIG_ARCH_VT8500) += vt8500/
|
||||
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
|
||||
obj-$(CONFIG_ARCH_VT8500) += vt8500/
|
||||
|
@ -992,29 +992,15 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
|
||||
|
||||
if (p->state) {
|
||||
/*
|
||||
* The set of groups with a mux configuration in the old state
|
||||
* may not be identical to the set of groups with a mux setting
|
||||
* in the new state. While this might be unusual, it's entirely
|
||||
* possible for the "user"-supplied mapping table to be written
|
||||
* that way. For each group that was configured in the old state
|
||||
* but not in the new state, this code puts that group into a
|
||||
* safe/disabled state.
|
||||
* For each pinmux setting in the old state, forget SW's record
|
||||
* of mux owner for that pingroup. Any pingroups which are
|
||||
* still owned by the new state will be re-acquired by the call
|
||||
* to pinmux_enable_setting() in the loop below.
|
||||
*/
|
||||
list_for_each_entry(setting, &p->state->settings, node) {
|
||||
bool found = false;
|
||||
if (setting->type != PIN_MAP_TYPE_MUX_GROUP)
|
||||
continue;
|
||||
list_for_each_entry(setting2, &state->settings, node) {
|
||||
if (setting2->type != PIN_MAP_TYPE_MUX_GROUP)
|
||||
continue;
|
||||
if (setting2->data.mux.group ==
|
||||
setting->data.mux.group) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
pinmux_disable_setting(setting);
|
||||
pinmux_disable_setting(setting);
|
||||
}
|
||||
}
|
||||
|
||||
|
51
drivers/pinctrl/nomadik/Kconfig
Normal file
51
drivers/pinctrl/nomadik/Kconfig
Normal file
@ -0,0 +1,51 @@
|
||||
if ARCH_U8500
|
||||
|
||||
config PINCTRL_ABX500
|
||||
bool "ST-Ericsson ABx500 family Mixed Signal Circuit gpio functions"
|
||||
depends on AB8500_CORE
|
||||
select GENERIC_PINCONF
|
||||
help
|
||||
Select this to enable the ABx500 family IC GPIO driver
|
||||
|
||||
config PINCTRL_AB8500
|
||||
bool "AB8500 pin controller driver"
|
||||
depends on PINCTRL_ABX500 && ARCH_U8500
|
||||
|
||||
config PINCTRL_AB8540
|
||||
bool "AB8540 pin controller driver"
|
||||
depends on PINCTRL_ABX500 && ARCH_U8500
|
||||
|
||||
config PINCTRL_AB9540
|
||||
bool "AB9540 pin controller driver"
|
||||
depends on PINCTRL_ABX500 && ARCH_U8500
|
||||
|
||||
config PINCTRL_AB8505
|
||||
bool "AB8505 pin controller driver"
|
||||
depends on PINCTRL_ABX500 && ARCH_U8500
|
||||
|
||||
endif
|
||||
|
||||
if (ARCH_U8500 || ARCH_NOMADIK)
|
||||
|
||||
config PINCTRL_NOMADIK
|
||||
bool "Nomadik pin controller driver"
|
||||
depends on ARCH_U8500 || ARCH_NOMADIK
|
||||
select PINMUX
|
||||
select PINCONF
|
||||
select GPIOLIB
|
||||
select OF_GPIO
|
||||
select GPIOLIB_IRQCHIP
|
||||
|
||||
config PINCTRL_STN8815
|
||||
bool "STN8815 pin controller driver"
|
||||
depends on PINCTRL_NOMADIK && ARCH_NOMADIK
|
||||
|
||||
config PINCTRL_DB8500
|
||||
bool "DB8500 pin controller driver"
|
||||
depends on PINCTRL_NOMADIK && ARCH_U8500
|
||||
|
||||
config PINCTRL_DB8540
|
||||
bool "DB8540 pin controller driver"
|
||||
depends on PINCTRL_NOMADIK && ARCH_U8500
|
||||
|
||||
endif
|
10
drivers/pinctrl/nomadik/Makefile
Normal file
10
drivers/pinctrl/nomadik/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
# Nomadik family pin control drivers
|
||||
obj-$(CONFIG_PINCTRL_ABX500) += pinctrl-abx500.o
|
||||
obj-$(CONFIG_PINCTRL_AB8500) += pinctrl-ab8500.o
|
||||
obj-$(CONFIG_PINCTRL_AB8540) += pinctrl-ab8540.o
|
||||
obj-$(CONFIG_PINCTRL_AB9540) += pinctrl-ab9540.o
|
||||
obj-$(CONFIG_PINCTRL_AB8505) += pinctrl-ab8505.o
|
||||
obj-$(CONFIG_PINCTRL_NOMADIK) += pinctrl-nomadik.o
|
||||
obj-$(CONFIG_PINCTRL_STN8815) += pinctrl-nomadik-stn8815.o
|
||||
obj-$(CONFIG_PINCTRL_DB8500) += pinctrl-nomadik-db8500.o
|
||||
obj-$(CONFIG_PINCTRL_DB8540) += pinctrl-nomadik-db8540.o
|
@ -32,8 +32,8 @@
|
||||
#include <linux/pinctrl/machine.h>
|
||||
|
||||
#include "pinctrl-abx500.h"
|
||||
#include "core.h"
|
||||
#include "pinconf.h"
|
||||
#include "../core.h"
|
||||
#include "../pinconf.h"
|
||||
|
||||
/*
|
||||
* The AB9540 and AB8540 GPIO support are extended versions
|
||||
@ -737,20 +737,6 @@ static int abx500_pmx_enable(struct pinctrl_dev *pctldev, unsigned function,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void abx500_pmx_disable(struct pinctrl_dev *pctldev,
|
||||
unsigned function, unsigned group)
|
||||
{
|
||||
struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct abx500_pingroup *g;
|
||||
|
||||
g = &pct->soc->groups[group];
|
||||
if (g->altsetting < 0)
|
||||
return;
|
||||
|
||||
/* FIXME: poke out the mux, set the pin to some default state? */
|
||||
dev_dbg(pct->dev, "disable group %s, %u pins\n", g->name, g->npins);
|
||||
}
|
||||
|
||||
static int abx500_gpio_request_enable(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
unsigned offset)
|
||||
@ -799,7 +785,6 @@ static const struct pinmux_ops abx500_pinmux_ops = {
|
||||
.get_function_name = abx500_pmx_get_func_name,
|
||||
.get_function_groups = abx500_pmx_get_func_groups,
|
||||
.enable = abx500_pmx_enable,
|
||||
.disable = abx500_pmx_disable,
|
||||
.gpio_request_enable = abx500_gpio_request_enable,
|
||||
.gpio_disable_free = abx500_gpio_disable_free,
|
||||
};
|
@ -31,7 +31,7 @@
|
||||
/* Since we request GPIOs from ourself */
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include "pinctrl-nomadik.h"
|
||||
#include "core.h"
|
||||
#include "../core.h"
|
||||
|
||||
/*
|
||||
* The GPIO module in the Nomadik family of Systems-on-Chip is an
|
||||
@ -1765,21 +1765,6 @@ out_glitch:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void nmk_pmx_disable(struct pinctrl_dev *pctldev,
|
||||
unsigned function, unsigned group)
|
||||
{
|
||||
struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct nmk_pingroup *g;
|
||||
|
||||
g = &npct->soc->groups[group];
|
||||
|
||||
if (g->altsetting < 0)
|
||||
return;
|
||||
|
||||
/* Poke out the mux, set the pin to some default state? */
|
||||
dev_dbg(npct->dev, "disable group %s, %u pins\n", g->name, g->npins);
|
||||
}
|
||||
|
||||
static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
unsigned offset)
|
||||
@ -1826,7 +1811,6 @@ static const struct pinmux_ops nmk_pinmux_ops = {
|
||||
.get_function_name = nmk_pmx_get_func_name,
|
||||
.get_function_groups = nmk_pmx_get_func_groups,
|
||||
.enable = nmk_pmx_enable,
|
||||
.disable = nmk_pmx_disable,
|
||||
.gpio_request_enable = nmk_gpio_request_enable,
|
||||
.gpio_disable_free = nmk_gpio_disable_free,
|
||||
};
|
@ -401,7 +401,7 @@ static int adi_gpio_irq_type(struct irq_data *d, unsigned int type)
|
||||
|
||||
if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
|
||||
IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
|
||||
snprintf(buf, 16, "gpio-irq%d", irq);
|
||||
snprintf(buf, 16, "gpio-irq%u", irq);
|
||||
port_setup(port, d->hwirq, true);
|
||||
} else
|
||||
goto out;
|
||||
@ -652,35 +652,6 @@ static int adi_pinmux_enable(struct pinctrl_dev *pctldev, unsigned func_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void adi_pinmux_disable(struct pinctrl_dev *pctldev, unsigned func_id,
|
||||
unsigned group_id)
|
||||
{
|
||||
struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct gpio_port *port;
|
||||
struct pinctrl_gpio_range *range;
|
||||
unsigned long flags;
|
||||
unsigned short *mux, pin;
|
||||
|
||||
mux = (unsigned short *)pinctrl->soc->groups[group_id].mux;
|
||||
|
||||
while (*mux) {
|
||||
pin = P_IDENT(*mux);
|
||||
|
||||
range = pinctrl_find_gpio_range_from_pin(pctldev, pin);
|
||||
if (range == NULL) /* should not happen */
|
||||
return;
|
||||
|
||||
port = container_of(range->gc, struct gpio_port, chip);
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
|
||||
port_setup(port, pin_to_offset(range, pin), true);
|
||||
mux++;
|
||||
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
static int adi_pinmux_get_funcs_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
|
||||
@ -728,7 +699,6 @@ static int adi_pinmux_request_gpio(struct pinctrl_dev *pctldev,
|
||||
|
||||
static struct pinmux_ops adi_pinmux_ops = {
|
||||
.enable = adi_pinmux_enable,
|
||||
.disable = adi_pinmux_disable,
|
||||
.get_functions_count = adi_pinmux_get_funcs_count,
|
||||
.get_function_name = adi_pinmux_get_func_name,
|
||||
.get_function_groups = adi_pinmux_get_groups,
|
||||
@ -979,7 +949,7 @@ static int adi_gpio_probe(struct platform_device *pdev)
|
||||
struct gpio_port *port;
|
||||
char pinctrl_devname[DEVNAME_SIZE];
|
||||
static int gpio;
|
||||
int ret = 0, ret1;
|
||||
int ret = 0;
|
||||
|
||||
pdata = dev->platform_data;
|
||||
if (!pdata)
|
||||
@ -1057,7 +1027,7 @@ static int adi_gpio_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
|
||||
out_remove_gpiochip:
|
||||
ret1 = gpiochip_remove(&port->chip);
|
||||
gpiochip_remove(&port->chip);
|
||||
out_remove_domain:
|
||||
if (port->pint)
|
||||
irq_domain_remove(port->domain);
|
||||
@ -1068,12 +1038,11 @@ out_remove_domain:
|
||||
static int adi_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct gpio_port *port = platform_get_drvdata(pdev);
|
||||
int ret;
|
||||
u8 offset;
|
||||
|
||||
list_del(&port->node);
|
||||
gpiochip_remove_pin_ranges(&port->chip);
|
||||
ret = gpiochip_remove(&port->chip);
|
||||
gpiochip_remove(&port->chip);
|
||||
if (port->pint) {
|
||||
for (offset = 0; offset < port->width; offset++)
|
||||
irq_dispose_mapping(irq_find_mapping(port->domain,
|
||||
@ -1081,7 +1050,7 @@ static int adi_gpio_remove(struct platform_device *pdev)
|
||||
irq_domain_remove(port->domain);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adi_pinctrl_probe(struct platform_device *pdev)
|
||||
|
@ -565,7 +565,6 @@ static int as3722_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct as3722_pctrl_info *as_pci;
|
||||
int ret;
|
||||
int tret;
|
||||
|
||||
as_pci = devm_kzalloc(&pdev->dev, sizeof(*as_pci), GFP_KERNEL);
|
||||
if (!as_pci)
|
||||
@ -611,10 +610,7 @@ static int as3722_pinctrl_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
|
||||
fail_range_add:
|
||||
tret = gpiochip_remove(&as_pci->gpio_chip);
|
||||
if (tret < 0)
|
||||
dev_warn(&pdev->dev, "Couldn't remove gpio chip, %d\n", tret);
|
||||
|
||||
gpiochip_remove(&as_pci->gpio_chip);
|
||||
fail_chip_add:
|
||||
pinctrl_unregister(as_pci->pctl);
|
||||
return ret;
|
||||
@ -623,11 +619,8 @@ fail_chip_add:
|
||||
static int as3722_pinctrl_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct as3722_pctrl_info *as_pci = platform_get_drvdata(pdev);
|
||||
int ret;
|
||||
|
||||
ret = gpiochip_remove(&as_pci->gpio_chip);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
gpiochip_remove(&as_pci->gpio_chip);
|
||||
pinctrl_unregister(as_pci->pctl);
|
||||
return 0;
|
||||
}
|
||||
|
@ -611,26 +611,6 @@ static int at91_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void at91_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
unsigned group)
|
||||
{
|
||||
struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct at91_pmx_pin *pins_conf = info->groups[group].pins_conf;
|
||||
const struct at91_pmx_pin *pin;
|
||||
uint32_t npins = info->groups[group].npins;
|
||||
int i;
|
||||
unsigned mask;
|
||||
void __iomem *pio;
|
||||
|
||||
for (i = 0; i < npins; i++) {
|
||||
pin = &pins_conf[i];
|
||||
at91_pin_dbg(info->dev, pin);
|
||||
pio = pin_to_controller(info, pin->bank);
|
||||
mask = pin_to_mask(pin->pin);
|
||||
at91_mux_gpio_enable(pio, mask, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static int at91_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
|
||||
@ -705,7 +685,6 @@ static const struct pinmux_ops at91_pmx_ops = {
|
||||
.get_function_name = at91_pmx_get_func_name,
|
||||
.get_function_groups = at91_pmx_get_groups,
|
||||
.enable = at91_pmx_enable,
|
||||
.disable = at91_pmx_disable,
|
||||
.gpio_request_enable = at91_gpio_request_enable,
|
||||
.gpio_disable_free = at91_gpio_disable_free,
|
||||
};
|
||||
@ -793,9 +772,9 @@ static void at91_pinconf_dbg_show(struct pinctrl_dev *pctldev,
|
||||
struct seq_file *s, unsigned pin_id)
|
||||
{
|
||||
unsigned long config;
|
||||
int ret, val, num_conf = 0;
|
||||
int val, num_conf = 0;
|
||||
|
||||
ret = at91_pinconf_get(pctldev, pin_id, &config);
|
||||
at91_pinconf_get(pctldev, pin_id, &config);
|
||||
|
||||
DBG_SHOW_FLAG(MULTI_DRIVE);
|
||||
DBG_SHOW_FLAG(PULL_UP);
|
||||
@ -945,7 +924,7 @@ static int at91_pinctrl_parse_functions(struct device_node *np,
|
||||
/* Initialise function */
|
||||
func->name = np->name;
|
||||
func->ngroups = of_get_child_count(np);
|
||||
if (func->ngroups <= 0) {
|
||||
if (func->ngroups == 0) {
|
||||
dev_err(info->dev, "no groups defined\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -25,9 +25,7 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/seq_file.h>
|
||||
@ -44,6 +42,7 @@
|
||||
|
||||
/* BYT_CONF0_REG register bits */
|
||||
#define BYT_IODEN BIT(31)
|
||||
#define BYT_DIRECT_IRQ_EN BIT(27)
|
||||
#define BYT_TRIG_NEG BIT(26)
|
||||
#define BYT_TRIG_POS BIT(25)
|
||||
#define BYT_TRIG_LVL BIT(24)
|
||||
@ -137,7 +136,6 @@ static struct pinctrl_gpio_range byt_ranges[] = {
|
||||
|
||||
struct byt_gpio {
|
||||
struct gpio_chip chip;
|
||||
struct irq_domain *domain;
|
||||
struct platform_device *pdev;
|
||||
spinlock_t lock;
|
||||
void __iomem *reg_base;
|
||||
@ -217,7 +215,7 @@ static void byt_gpio_free(struct gpio_chip *chip, unsigned offset)
|
||||
|
||||
static int byt_irq_type(struct irq_data *d, unsigned type)
|
||||
{
|
||||
struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
|
||||
struct byt_gpio *vg = to_byt_gpio(irq_data_get_irq_chip_data(d));
|
||||
u32 offset = irqd_to_hwirq(d);
|
||||
u32 value;
|
||||
unsigned long flags;
|
||||
@ -303,12 +301,22 @@ static int byt_gpio_direction_output(struct gpio_chip *chip,
|
||||
unsigned gpio, int value)
|
||||
{
|
||||
struct byt_gpio *vg = to_byt_gpio(chip);
|
||||
void __iomem *conf_reg = byt_gpio_reg(chip, gpio, BYT_CONF0_REG);
|
||||
void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG);
|
||||
unsigned long flags;
|
||||
u32 reg_val;
|
||||
|
||||
spin_lock_irqsave(&vg->lock, flags);
|
||||
|
||||
/*
|
||||
* Before making any direction modifications, do a check if gpio
|
||||
* is set for direct IRQ. On baytrail, setting GPIO to output does
|
||||
* not make sense, so let's at least warn the caller before they shoot
|
||||
* themselves in the foot.
|
||||
*/
|
||||
WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN,
|
||||
"Potential Error: Setting GPIO with direct_irq_en to output");
|
||||
|
||||
reg_val = readl(reg) | BYT_DIR_MASK;
|
||||
reg_val &= ~BYT_OUTPUT_EN;
|
||||
|
||||
@ -393,16 +401,10 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
|
||||
spin_unlock_irqrestore(&vg->lock, flags);
|
||||
}
|
||||
|
||||
static int byt_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct byt_gpio *vg = to_byt_gpio(chip);
|
||||
return irq_create_mapping(vg->domain, offset);
|
||||
}
|
||||
|
||||
static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
|
||||
{
|
||||
struct irq_data *data = irq_desc_get_irq_data(desc);
|
||||
struct byt_gpio *vg = irq_data_get_irq_handler_data(data);
|
||||
struct byt_gpio *vg = to_byt_gpio(irq_desc_get_handler_data(desc));
|
||||
struct irq_chip *chip = irq_data_get_irq_chip(data);
|
||||
u32 base, pin, mask;
|
||||
void __iomem *reg;
|
||||
@ -421,7 +423,7 @@ static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
|
||||
/* Clear before handling so we can't lose an edge */
|
||||
writel(mask, reg);
|
||||
|
||||
virq = irq_find_mapping(vg->domain, base + pin);
|
||||
virq = irq_find_mapping(vg->chip.irqdomain, base + pin);
|
||||
generic_handle_irq(virq);
|
||||
|
||||
/* In case bios or user sets triggering incorretly a pin
|
||||
@ -454,33 +456,11 @@ static void byt_irq_mask(struct irq_data *d)
|
||||
{
|
||||
}
|
||||
|
||||
static int byt_irq_reqres(struct irq_data *d)
|
||||
{
|
||||
struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
|
||||
|
||||
if (gpio_lock_as_irq(&vg->chip, irqd_to_hwirq(d))) {
|
||||
dev_err(vg->chip.dev,
|
||||
"unable to lock HW IRQ %lu for IRQ\n",
|
||||
irqd_to_hwirq(d));
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void byt_irq_relres(struct irq_data *d)
|
||||
{
|
||||
struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
|
||||
|
||||
gpio_unlock_as_irq(&vg->chip, irqd_to_hwirq(d));
|
||||
}
|
||||
|
||||
static struct irq_chip byt_irqchip = {
|
||||
.name = "BYT-GPIO",
|
||||
.irq_mask = byt_irq_mask,
|
||||
.irq_unmask = byt_irq_unmask,
|
||||
.irq_set_type = byt_irq_type,
|
||||
.irq_request_resources = byt_irq_reqres,
|
||||
.irq_release_resources = byt_irq_relres,
|
||||
};
|
||||
|
||||
static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
|
||||
@ -501,23 +481,6 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
|
||||
}
|
||||
}
|
||||
|
||||
static int byt_gpio_irq_map(struct irq_domain *d, unsigned int virq,
|
||||
irq_hw_number_t hw)
|
||||
{
|
||||
struct byt_gpio *vg = d->host_data;
|
||||
|
||||
irq_set_chip_and_handler_name(virq, &byt_irqchip, handle_simple_irq,
|
||||
"demux");
|
||||
irq_set_chip_data(virq, vg);
|
||||
irq_set_irq_type(virq, IRQ_TYPE_NONE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops byt_gpio_irq_ops = {
|
||||
.map = byt_gpio_irq_map,
|
||||
};
|
||||
|
||||
static int byt_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct byt_gpio *vg;
|
||||
@ -527,7 +490,6 @@ static int byt_gpio_probe(struct platform_device *pdev)
|
||||
struct acpi_device *acpi_dev;
|
||||
struct pinctrl_gpio_range *range;
|
||||
acpi_handle handle = ACPI_HANDLE(dev);
|
||||
unsigned hwirq;
|
||||
int ret;
|
||||
|
||||
if (acpi_bus_get_device(handle, &acpi_dev))
|
||||
@ -574,29 +536,29 @@ static int byt_gpio_probe(struct platform_device *pdev)
|
||||
gc->can_sleep = false;
|
||||
gc->dev = dev;
|
||||
|
||||
/* set up interrupts */
|
||||
irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (irq_rc && irq_rc->start) {
|
||||
hwirq = irq_rc->start;
|
||||
gc->to_irq = byt_gpio_to_irq;
|
||||
|
||||
vg->domain = irq_domain_add_linear(NULL, gc->ngpio,
|
||||
&byt_gpio_irq_ops, vg);
|
||||
if (!vg->domain)
|
||||
return -ENXIO;
|
||||
|
||||
byt_gpio_irq_init_hw(vg);
|
||||
|
||||
irq_set_handler_data(hwirq, vg);
|
||||
irq_set_chained_handler(hwirq, byt_gpio_irq_handler);
|
||||
}
|
||||
|
||||
ret = gpiochip_add(gc);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed adding byt-gpio chip\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* set up interrupts */
|
||||
irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (irq_rc && irq_rc->start) {
|
||||
byt_gpio_irq_init_hw(vg);
|
||||
ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0,
|
||||
handle_simple_irq, IRQ_TYPE_NONE);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to add irqchip\n");
|
||||
gpiochip_remove(gc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gpiochip_set_chained_irqchip(gc, &byt_irqchip,
|
||||
(unsigned)irq_rc->start,
|
||||
byt_gpio_irq_handler);
|
||||
}
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
return 0;
|
||||
@ -627,12 +589,9 @@ MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match);
|
||||
static int byt_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct byt_gpio *vg = platform_get_drvdata(pdev);
|
||||
int err;
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
err = gpiochip_remove(&vg->chip);
|
||||
if (err)
|
||||
dev_warn(&pdev->dev, "failed to remove gpio_chip.\n");
|
||||
gpiochip_remove(&vg->chip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1396,7 +1396,7 @@ static struct pinctrl_desc bcm281xx_pinctrl_desc = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
int __init bcm281xx_pinctrl_probe(struct platform_device *pdev)
|
||||
static int __init bcm281xx_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct bcm281xx_pinctrl_data *pdata = &bcm281xx_pinctrl;
|
||||
struct resource *res;
|
||||
|
@ -841,16 +841,6 @@ static int bcm2835_pmx_enable(struct pinctrl_dev *pctldev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bcm2835_pmx_disable(struct pinctrl_dev *pctldev,
|
||||
unsigned func_selector,
|
||||
unsigned group_selector)
|
||||
{
|
||||
struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
/* disable by setting to GPIO_IN */
|
||||
bcm2835_pinctrl_fsel_set(pc, group_selector, BCM2835_FSEL_GPIO_IN);
|
||||
}
|
||||
|
||||
static void bcm2835_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
unsigned offset)
|
||||
@ -880,7 +870,6 @@ static const struct pinmux_ops bcm2835_pmx_ops = {
|
||||
.get_function_name = bcm2835_pmx_get_function_name,
|
||||
.get_function_groups = bcm2835_pmx_get_function_groups,
|
||||
.enable = bcm2835_pmx_enable,
|
||||
.disable = bcm2835_pmx_disable,
|
||||
.gpio_disable_free = bcm2835_pmx_gpio_disable_free,
|
||||
.gpio_set_direction = bcm2835_pmx_gpio_set_direction,
|
||||
};
|
||||
|
@ -756,8 +756,7 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
|
||||
|
||||
err_no_range:
|
||||
err_no_irqchip:
|
||||
if (gpiochip_remove(&gpio->chip))
|
||||
dev_err(&pdev->dev, "failed to remove gpio chip\n");
|
||||
gpiochip_remove(&gpio->chip);
|
||||
err_no_chip:
|
||||
clk_disable_unprepare(gpio->clk);
|
||||
dev_err(&pdev->dev, "module ERROR:%d\n", err);
|
||||
@ -767,16 +766,11 @@ err_no_chip:
|
||||
static int __exit u300_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct u300_gpio *gpio = platform_get_drvdata(pdev);
|
||||
int err;
|
||||
|
||||
/* Turn off the GPIO block */
|
||||
writel(0x00000000U, gpio->base + U300_GPIO_CR);
|
||||
|
||||
err = gpiochip_remove(&gpio->chip);
|
||||
if (err < 0) {
|
||||
dev_err(gpio->dev, "unable to remove gpiochip: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
gpiochip_remove(&gpio->chip);
|
||||
clk_disable_unprepare(gpio->clk);
|
||||
return 0;
|
||||
}
|
||||
|
@ -515,7 +515,7 @@ static int imx_pinctrl_parse_functions(struct device_node *np,
|
||||
/* Initialise function */
|
||||
func->name = np->name;
|
||||
func->num_groups = of_get_child_count(np);
|
||||
if (func->num_groups <= 0) {
|
||||
if (func->num_groups == 0) {
|
||||
dev_err(info->dev, "no groups defined in %s\n", np->full_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -526,7 +526,7 @@ static int imx1_pinctrl_parse_functions(struct device_node *np,
|
||||
/* Initialise function */
|
||||
func->name = np->name;
|
||||
func->num_groups = of_get_child_count(np);
|
||||
if (func->num_groups <= 0)
|
||||
if (func->num_groups == 0)
|
||||
return -EINVAL;
|
||||
|
||||
func->groups = devm_kzalloc(info->dev,
|
||||
|
279
drivers/pinctrl/pinctrl-imx1.c
Normal file
279
drivers/pinctrl/pinctrl-imx1.c
Normal file
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* i.MX1 pinctrl driver based on imx pinmux core
|
||||
*
|
||||
* Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
|
||||
*
|
||||
* 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/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
|
||||
#include "pinctrl-imx1.h"
|
||||
|
||||
#define PAD_ID(port, pin) ((port) * 32 + (pin))
|
||||
#define PA 0
|
||||
#define PB 1
|
||||
#define PC 2
|
||||
#define PD 3
|
||||
|
||||
enum imx1_pads {
|
||||
MX1_PAD_A24 = PAD_ID(PA, 0),
|
||||
MX1_PAD_TIN = PAD_ID(PA, 1),
|
||||
MX1_PAD_PWMO = PAD_ID(PA, 2),
|
||||
MX1_PAD_CSI_MCLK = PAD_ID(PA, 3),
|
||||
MX1_PAD_CSI_D0 = PAD_ID(PA, 4),
|
||||
MX1_PAD_CSI_D1 = PAD_ID(PA, 5),
|
||||
MX1_PAD_CSI_D2 = PAD_ID(PA, 6),
|
||||
MX1_PAD_CSI_D3 = PAD_ID(PA, 7),
|
||||
MX1_PAD_CSI_D4 = PAD_ID(PA, 8),
|
||||
MX1_PAD_CSI_D5 = PAD_ID(PA, 9),
|
||||
MX1_PAD_CSI_D6 = PAD_ID(PA, 10),
|
||||
MX1_PAD_CSI_D7 = PAD_ID(PA, 11),
|
||||
MX1_PAD_CSI_VSYNC = PAD_ID(PA, 12),
|
||||
MX1_PAD_CSI_HSYNC = PAD_ID(PA, 13),
|
||||
MX1_PAD_CSI_PIXCLK = PAD_ID(PA, 14),
|
||||
MX1_PAD_I2C_SDA = PAD_ID(PA, 15),
|
||||
MX1_PAD_I2C_SCL = PAD_ID(PA, 16),
|
||||
MX1_PAD_DTACK = PAD_ID(PA, 17),
|
||||
MX1_PAD_BCLK = PAD_ID(PA, 18),
|
||||
MX1_PAD_LBA = PAD_ID(PA, 19),
|
||||
MX1_PAD_ECB = PAD_ID(PA, 20),
|
||||
MX1_PAD_A0 = PAD_ID(PA, 21),
|
||||
MX1_PAD_CS4 = PAD_ID(PA, 22),
|
||||
MX1_PAD_CS5 = PAD_ID(PA, 23),
|
||||
MX1_PAD_A16 = PAD_ID(PA, 24),
|
||||
MX1_PAD_A17 = PAD_ID(PA, 25),
|
||||
MX1_PAD_A18 = PAD_ID(PA, 26),
|
||||
MX1_PAD_A19 = PAD_ID(PA, 27),
|
||||
MX1_PAD_A20 = PAD_ID(PA, 28),
|
||||
MX1_PAD_A21 = PAD_ID(PA, 29),
|
||||
MX1_PAD_A22 = PAD_ID(PA, 30),
|
||||
MX1_PAD_A23 = PAD_ID(PA, 31),
|
||||
MX1_PAD_SD_DAT0 = PAD_ID(PB, 8),
|
||||
MX1_PAD_SD_DAT1 = PAD_ID(PB, 9),
|
||||
MX1_PAD_SD_DAT2 = PAD_ID(PB, 10),
|
||||
MX1_PAD_SD_DAT3 = PAD_ID(PB, 11),
|
||||
MX1_PAD_SD_SCLK = PAD_ID(PB, 12),
|
||||
MX1_PAD_SD_CMD = PAD_ID(PB, 13),
|
||||
MX1_PAD_SIM_SVEN = PAD_ID(PB, 14),
|
||||
MX1_PAD_SIM_PD = PAD_ID(PB, 15),
|
||||
MX1_PAD_SIM_TX = PAD_ID(PB, 16),
|
||||
MX1_PAD_SIM_RX = PAD_ID(PB, 17),
|
||||
MX1_PAD_SIM_RST = PAD_ID(PB, 18),
|
||||
MX1_PAD_SIM_CLK = PAD_ID(PB, 19),
|
||||
MX1_PAD_USBD_AFE = PAD_ID(PB, 20),
|
||||
MX1_PAD_USBD_OE = PAD_ID(PB, 21),
|
||||
MX1_PAD_USBD_RCV = PAD_ID(PB, 22),
|
||||
MX1_PAD_USBD_SUSPND = PAD_ID(PB, 23),
|
||||
MX1_PAD_USBD_VP = PAD_ID(PB, 24),
|
||||
MX1_PAD_USBD_VM = PAD_ID(PB, 25),
|
||||
MX1_PAD_USBD_VPO = PAD_ID(PB, 26),
|
||||
MX1_PAD_USBD_VMO = PAD_ID(PB, 27),
|
||||
MX1_PAD_UART2_CTS = PAD_ID(PB, 28),
|
||||
MX1_PAD_UART2_RTS = PAD_ID(PB, 29),
|
||||
MX1_PAD_UART2_TXD = PAD_ID(PB, 30),
|
||||
MX1_PAD_UART2_RXD = PAD_ID(PB, 31),
|
||||
MX1_PAD_SSI_RXFS = PAD_ID(PC, 3),
|
||||
MX1_PAD_SSI_RXCLK = PAD_ID(PC, 4),
|
||||
MX1_PAD_SSI_RXDAT = PAD_ID(PC, 5),
|
||||
MX1_PAD_SSI_TXDAT = PAD_ID(PC, 6),
|
||||
MX1_PAD_SSI_TXFS = PAD_ID(PC, 7),
|
||||
MX1_PAD_SSI_TXCLK = PAD_ID(PC, 8),
|
||||
MX1_PAD_UART1_CTS = PAD_ID(PC, 9),
|
||||
MX1_PAD_UART1_RTS = PAD_ID(PC, 10),
|
||||
MX1_PAD_UART1_TXD = PAD_ID(PC, 11),
|
||||
MX1_PAD_UART1_RXD = PAD_ID(PC, 12),
|
||||
MX1_PAD_SPI1_RDY = PAD_ID(PC, 13),
|
||||
MX1_PAD_SPI1_SCLK = PAD_ID(PC, 14),
|
||||
MX1_PAD_SPI1_SS = PAD_ID(PC, 15),
|
||||
MX1_PAD_SPI1_MISO = PAD_ID(PC, 16),
|
||||
MX1_PAD_SPI1_MOSI = PAD_ID(PC, 17),
|
||||
MX1_PAD_BT13 = PAD_ID(PC, 19),
|
||||
MX1_PAD_BT12 = PAD_ID(PC, 20),
|
||||
MX1_PAD_BT11 = PAD_ID(PC, 21),
|
||||
MX1_PAD_BT10 = PAD_ID(PC, 22),
|
||||
MX1_PAD_BT9 = PAD_ID(PC, 23),
|
||||
MX1_PAD_BT8 = PAD_ID(PC, 24),
|
||||
MX1_PAD_BT7 = PAD_ID(PC, 25),
|
||||
MX1_PAD_BT6 = PAD_ID(PC, 26),
|
||||
MX1_PAD_BT5 = PAD_ID(PC, 27),
|
||||
MX1_PAD_BT4 = PAD_ID(PC, 28),
|
||||
MX1_PAD_BT3 = PAD_ID(PC, 29),
|
||||
MX1_PAD_BT2 = PAD_ID(PC, 30),
|
||||
MX1_PAD_BT1 = PAD_ID(PC, 31),
|
||||
MX1_PAD_LSCLK = PAD_ID(PD, 6),
|
||||
MX1_PAD_REV = PAD_ID(PD, 7),
|
||||
MX1_PAD_CLS = PAD_ID(PD, 8),
|
||||
MX1_PAD_PS = PAD_ID(PD, 9),
|
||||
MX1_PAD_SPL_SPR = PAD_ID(PD, 10),
|
||||
MX1_PAD_CONTRAST = PAD_ID(PD, 11),
|
||||
MX1_PAD_ACD_OE = PAD_ID(PD, 12),
|
||||
MX1_PAD_LP_HSYNC = PAD_ID(PD, 13),
|
||||
MX1_PAD_FLM_VSYNC = PAD_ID(PD, 14),
|
||||
MX1_PAD_LD0 = PAD_ID(PD, 15),
|
||||
MX1_PAD_LD1 = PAD_ID(PD, 16),
|
||||
MX1_PAD_LD2 = PAD_ID(PD, 17),
|
||||
MX1_PAD_LD3 = PAD_ID(PD, 18),
|
||||
MX1_PAD_LD4 = PAD_ID(PD, 19),
|
||||
MX1_PAD_LD5 = PAD_ID(PD, 20),
|
||||
MX1_PAD_LD6 = PAD_ID(PD, 21),
|
||||
MX1_PAD_LD7 = PAD_ID(PD, 22),
|
||||
MX1_PAD_LD8 = PAD_ID(PD, 23),
|
||||
MX1_PAD_LD9 = PAD_ID(PD, 24),
|
||||
MX1_PAD_LD10 = PAD_ID(PD, 25),
|
||||
MX1_PAD_LD11 = PAD_ID(PD, 26),
|
||||
MX1_PAD_LD12 = PAD_ID(PD, 27),
|
||||
MX1_PAD_LD13 = PAD_ID(PD, 28),
|
||||
MX1_PAD_LD14 = PAD_ID(PD, 29),
|
||||
MX1_PAD_LD15 = PAD_ID(PD, 30),
|
||||
MX1_PAD_TMR2OUT = PAD_ID(PD, 31),
|
||||
};
|
||||
|
||||
/* Pad names for the pinmux subsystem */
|
||||
static const struct pinctrl_pin_desc imx1_pinctrl_pads[] = {
|
||||
IMX_PINCTRL_PIN(MX1_PAD_A24),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_TIN),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_PWMO),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_CSI_MCLK),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_CSI_D0),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_CSI_D1),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_CSI_D2),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_CSI_D3),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_CSI_D4),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_CSI_D5),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_CSI_D6),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_CSI_D7),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_CSI_VSYNC),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_CSI_HSYNC),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_CSI_PIXCLK),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_I2C_SDA),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_I2C_SCL),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_DTACK),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_BCLK),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_LBA),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_ECB),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_A0),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_CS4),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_CS5),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_A16),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_A17),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_A18),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_A19),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_A20),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_A21),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_A22),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_A23),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SD_DAT0),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SD_DAT1),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SD_DAT2),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SD_DAT3),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SD_SCLK),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SD_CMD),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SIM_SVEN),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SIM_PD),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SIM_TX),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SIM_RX),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SIM_CLK),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_USBD_AFE),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_USBD_OE),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_USBD_RCV),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_USBD_SUSPND),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_USBD_VP),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_USBD_VM),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_USBD_VPO),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_USBD_VMO),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_UART2_CTS),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_UART2_RTS),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_UART2_TXD),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_UART2_RXD),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SSI_RXFS),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SSI_RXCLK),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SSI_RXDAT),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SSI_TXDAT),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SSI_TXFS),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SSI_TXCLK),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_UART1_CTS),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_UART1_RTS),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_UART1_TXD),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_UART1_RXD),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SPI1_RDY),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SPI1_SCLK),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SPI1_SS),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SPI1_MISO),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SPI1_MOSI),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_BT13),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_BT12),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_BT11),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_BT10),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_BT9),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_BT8),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_BT7),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_BT6),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_BT5),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_BT4),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_BT3),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_BT2),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_BT1),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_LSCLK),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_REV),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_CLS),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_PS),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_SPL_SPR),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_CONTRAST),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_ACD_OE),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_LP_HSYNC),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_FLM_VSYNC),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_LD0),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_LD1),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_LD2),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_LD3),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_LD4),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_LD5),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_LD6),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_LD7),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_LD8),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_LD9),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_LD10),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_LD11),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_LD12),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_LD13),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_LD14),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_LD15),
|
||||
IMX_PINCTRL_PIN(MX1_PAD_TMR2OUT),
|
||||
};
|
||||
|
||||
static struct imx1_pinctrl_soc_info imx1_pinctrl_info = {
|
||||
.pins = imx1_pinctrl_pads,
|
||||
.npins = ARRAY_SIZE(imx1_pinctrl_pads),
|
||||
};
|
||||
|
||||
static int __init imx1_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
return imx1_pinctrl_core_probe(pdev, &imx1_pinctrl_info);
|
||||
}
|
||||
|
||||
static const struct of_device_id imx1_pinctrl_of_match[] = {
|
||||
{ .compatible = "fsl,imx1-iomuxc", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, imx1_pinctrl_of_match);
|
||||
|
||||
static struct platform_driver imx1_pinctrl_driver = {
|
||||
.driver = {
|
||||
.name = "imx1-pinctrl",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = imx1_pinctrl_of_match,
|
||||
},
|
||||
.remove = imx1_pinctrl_core_remove,
|
||||
};
|
||||
module_platform_driver_probe(imx1_pinctrl_driver, imx1_pinctrl_probe);
|
||||
|
||||
MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
|
||||
MODULE_DESCRIPTION("Freescale i.MX1 pinctrl driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -63,10 +63,6 @@ enum imx27_pads {
|
||||
MX27_PAD_CONTRAST = PAD_ID(PA, 30),
|
||||
MX27_PAD_OE_ACD = PAD_ID(PA, 31),
|
||||
|
||||
MX27_PAD_UNUSED0 = PAD_ID(PB, 0),
|
||||
MX27_PAD_UNUSED1 = PAD_ID(PB, 1),
|
||||
MX27_PAD_UNUSED2 = PAD_ID(PB, 2),
|
||||
MX27_PAD_UNUSED3 = PAD_ID(PB, 3),
|
||||
MX27_PAD_SD2_D0 = PAD_ID(PB, 4),
|
||||
MX27_PAD_SD2_D1 = PAD_ID(PB, 5),
|
||||
MX27_PAD_SD2_D2 = PAD_ID(PB, 6),
|
||||
@ -96,11 +92,6 @@ enum imx27_pads {
|
||||
MX27_PAD_USBH1_RXDM = PAD_ID(PB, 30),
|
||||
MX27_PAD_USBH1_RXDP = PAD_ID(PB, 31),
|
||||
|
||||
MX27_PAD_UNUSED4 = PAD_ID(PC, 0),
|
||||
MX27_PAD_UNUSED5 = PAD_ID(PC, 1),
|
||||
MX27_PAD_UNUSED6 = PAD_ID(PC, 2),
|
||||
MX27_PAD_UNUSED7 = PAD_ID(PC, 3),
|
||||
MX27_PAD_UNUSED8 = PAD_ID(PC, 4),
|
||||
MX27_PAD_I2C2_SDA = PAD_ID(PC, 5),
|
||||
MX27_PAD_I2C2_SCL = PAD_ID(PC, 6),
|
||||
MX27_PAD_USBOTG_DATA5 = PAD_ID(PC, 7),
|
||||
@ -188,12 +179,6 @@ enum imx27_pads {
|
||||
MX27_PAD_SD1_CLK = PAD_ID(PE, 23),
|
||||
MX27_PAD_USBOTG_CLK = PAD_ID(PE, 24),
|
||||
MX27_PAD_USBOTG_DATA7 = PAD_ID(PE, 25),
|
||||
MX27_PAD_UNUSED9 = PAD_ID(PE, 26),
|
||||
MX27_PAD_UNUSED10 = PAD_ID(PE, 27),
|
||||
MX27_PAD_UNUSED11 = PAD_ID(PE, 28),
|
||||
MX27_PAD_UNUSED12 = PAD_ID(PE, 29),
|
||||
MX27_PAD_UNUSED13 = PAD_ID(PE, 30),
|
||||
MX27_PAD_UNUSED14 = PAD_ID(PE, 31),
|
||||
|
||||
MX27_PAD_NFRB = PAD_ID(PF, 0),
|
||||
MX27_PAD_NFCLE = PAD_ID(PF, 1),
|
||||
@ -219,14 +204,6 @@ enum imx27_pads {
|
||||
MX27_PAD_CS4_B = PAD_ID(PF, 21),
|
||||
MX27_PAD_CS5_B = PAD_ID(PF, 22),
|
||||
MX27_PAD_ATA_DATA15 = PAD_ID(PF, 23),
|
||||
MX27_PAD_UNUSED15 = PAD_ID(PF, 24),
|
||||
MX27_PAD_UNUSED16 = PAD_ID(PF, 25),
|
||||
MX27_PAD_UNUSED17 = PAD_ID(PF, 26),
|
||||
MX27_PAD_UNUSED18 = PAD_ID(PF, 27),
|
||||
MX27_PAD_UNUSED19 = PAD_ID(PF, 28),
|
||||
MX27_PAD_UNUSED20 = PAD_ID(PF, 29),
|
||||
MX27_PAD_UNUSED21 = PAD_ID(PF, 30),
|
||||
MX27_PAD_UNUSED22 = PAD_ID(PF, 31),
|
||||
};
|
||||
|
||||
/* Pad names for the pinmux subsystem */
|
||||
@ -264,10 +241,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = {
|
||||
IMX_PINCTRL_PIN(MX27_PAD_CONTRAST),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_OE_ACD),
|
||||
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED0),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED1),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED2),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED3),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_SD2_D0),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_SD2_D1),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_SD2_D2),
|
||||
@ -297,11 +270,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = {
|
||||
IMX_PINCTRL_PIN(MX27_PAD_USBH1_RXDM),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_USBH1_RXDP),
|
||||
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED4),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED5),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED6),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED7),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED8),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_I2C2_SDA),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_I2C2_SCL),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_USBOTG_DATA5),
|
||||
@ -389,12 +357,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = {
|
||||
IMX_PINCTRL_PIN(MX27_PAD_SD1_CLK),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_USBOTG_CLK),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_USBOTG_DATA7),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED9),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED10),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED11),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED12),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED13),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED14),
|
||||
|
||||
IMX_PINCTRL_PIN(MX27_PAD_NFRB),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_NFCLE),
|
||||
@ -420,14 +382,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = {
|
||||
IMX_PINCTRL_PIN(MX27_PAD_CS4_B),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_CS5_B),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_ATA_DATA15),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED15),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED16),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED17),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED18),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED19),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED20),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED21),
|
||||
IMX_PINCTRL_PIN(MX27_PAD_UNUSED22),
|
||||
};
|
||||
|
||||
static struct imx1_pinctrl_soc_info imx27_pinctrl_info = {
|
||||
@ -440,12 +394,6 @@ static struct of_device_id imx27_pinctrl_of_match[] = {
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
struct imx27_pinctrl_private {
|
||||
int num_gpio_childs;
|
||||
struct platform_device **gpio_dev;
|
||||
struct mxc_gpio_platform_data *gpio_pdata;
|
||||
};
|
||||
|
||||
static int imx27_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
return imx1_pinctrl_core_probe(pdev, &imx27_pinctrl_info);
|
||||
|
@ -62,11 +62,26 @@ enum rockchip_pinctrl_type {
|
||||
RK2928,
|
||||
RK3066B,
|
||||
RK3188,
|
||||
RK3288,
|
||||
};
|
||||
|
||||
enum rockchip_pin_bank_type {
|
||||
COMMON_BANK,
|
||||
RK3188_BANK0,
|
||||
/**
|
||||
* Encode variants of iomux registers into a type variable
|
||||
*/
|
||||
#define IOMUX_GPIO_ONLY BIT(0)
|
||||
#define IOMUX_WIDTH_4BIT BIT(1)
|
||||
#define IOMUX_SOURCE_PMU BIT(2)
|
||||
#define IOMUX_UNROUTED BIT(3)
|
||||
|
||||
/**
|
||||
* @type: iomux variant using IOMUX_* constants
|
||||
* @offset: if initialized to -1 it will be autocalculated, by specifying
|
||||
* an initial offset value the relevant source offset can be reset
|
||||
* to a new value for autocalculating the following iomux registers.
|
||||
*/
|
||||
struct rockchip_iomux {
|
||||
int type;
|
||||
int offset;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -78,6 +93,7 @@ enum rockchip_pin_bank_type {
|
||||
* @nr_pins: number of pins in this bank
|
||||
* @name: name of the bank
|
||||
* @bank_num: number of the bank, to account for holes
|
||||
* @iomux: array describing the 4 iomux sources of the bank
|
||||
* @valid: are all necessary informations present
|
||||
* @of_node: dt node of this bank
|
||||
* @drvdata: common pinctrl basedata
|
||||
@ -95,7 +111,7 @@ struct rockchip_pin_bank {
|
||||
u8 nr_pins;
|
||||
char *name;
|
||||
u8 bank_num;
|
||||
enum rockchip_pin_bank_type bank_type;
|
||||
struct rockchip_iomux iomux[4];
|
||||
bool valid;
|
||||
struct device_node *of_node;
|
||||
struct rockchip_pinctrl *drvdata;
|
||||
@ -111,6 +127,25 @@ struct rockchip_pin_bank {
|
||||
.bank_num = id, \
|
||||
.nr_pins = pins, \
|
||||
.name = label, \
|
||||
.iomux = { \
|
||||
{ .offset = -1 }, \
|
||||
{ .offset = -1 }, \
|
||||
{ .offset = -1 }, \
|
||||
{ .offset = -1 }, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \
|
||||
{ \
|
||||
.bank_num = id, \
|
||||
.nr_pins = pins, \
|
||||
.name = label, \
|
||||
.iomux = { \
|
||||
{ .type = iom0, .offset = -1 }, \
|
||||
{ .type = iom1, .offset = -1 }, \
|
||||
{ .type = iom2, .offset = -1 }, \
|
||||
{ .type = iom3, .offset = -1 }, \
|
||||
}, \
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,7 +156,8 @@ struct rockchip_pin_ctrl {
|
||||
u32 nr_pins;
|
||||
char *label;
|
||||
enum rockchip_pinctrl_type type;
|
||||
int mux_offset;
|
||||
int grf_mux_offset;
|
||||
int pmu_mux_offset;
|
||||
void (*pull_calc_reg)(struct rockchip_pin_bank *bank,
|
||||
int pin_num, struct regmap **regmap,
|
||||
int *reg, u8 *bit);
|
||||
@ -343,24 +379,42 @@ static const struct pinctrl_ops rockchip_pctrl_ops = {
|
||||
static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
|
||||
{
|
||||
struct rockchip_pinctrl *info = bank->drvdata;
|
||||
int iomux_num = (pin / 8);
|
||||
struct regmap *regmap;
|
||||
unsigned int val;
|
||||
int reg, ret;
|
||||
int reg, ret, mask;
|
||||
u8 bit;
|
||||
|
||||
if (bank->bank_type == RK3188_BANK0 && pin < 16)
|
||||
if (iomux_num > 3)
|
||||
return -EINVAL;
|
||||
|
||||
if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
|
||||
dev_err(info->dev, "pin %d is unrouted\n", pin);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
|
||||
return RK_FUNC_GPIO;
|
||||
|
||||
/* get basic quadrupel of mux registers and the correct reg inside */
|
||||
reg = info->ctrl->mux_offset;
|
||||
reg += bank->bank_num * 0x10;
|
||||
reg += (pin / 8) * 4;
|
||||
bit = (pin % 8) * 2;
|
||||
regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
|
||||
? info->regmap_pmu : info->regmap_base;
|
||||
|
||||
ret = regmap_read(info->regmap_base, reg, &val);
|
||||
/* get basic quadrupel of mux registers and the correct reg inside */
|
||||
mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3;
|
||||
reg = bank->iomux[iomux_num].offset;
|
||||
if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) {
|
||||
if ((pin % 8) >= 4)
|
||||
reg += 0x4;
|
||||
bit = (pin % 4) * 4;
|
||||
} else {
|
||||
bit = (pin % 8) * 2;
|
||||
}
|
||||
|
||||
ret = regmap_read(regmap, reg, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ((val >> bit) & 3);
|
||||
return ((val >> bit) & mask);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -379,16 +433,22 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
|
||||
static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
|
||||
{
|
||||
struct rockchip_pinctrl *info = bank->drvdata;
|
||||
int reg, ret;
|
||||
int iomux_num = (pin / 8);
|
||||
struct regmap *regmap;
|
||||
int reg, ret, mask;
|
||||
unsigned long flags;
|
||||
u8 bit;
|
||||
u32 data;
|
||||
|
||||
/*
|
||||
* The first 16 pins of rk3188_bank0 are always gpios and do not have
|
||||
* a mux register at all.
|
||||
*/
|
||||
if (bank->bank_type == RK3188_BANK0 && pin < 16) {
|
||||
if (iomux_num > 3)
|
||||
return -EINVAL;
|
||||
|
||||
if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
|
||||
dev_err(info->dev, "pin %d is unrouted\n", pin);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) {
|
||||
if (mux != RK_FUNC_GPIO) {
|
||||
dev_err(info->dev,
|
||||
"pin %d only supports a gpio mux\n", pin);
|
||||
@ -401,17 +461,25 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
|
||||
dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n",
|
||||
bank->bank_num, pin, mux);
|
||||
|
||||
regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
|
||||
? info->regmap_pmu : info->regmap_base;
|
||||
|
||||
/* get basic quadrupel of mux registers and the correct reg inside */
|
||||
reg = info->ctrl->mux_offset;
|
||||
reg += bank->bank_num * 0x10;
|
||||
reg += (pin / 8) * 4;
|
||||
bit = (pin % 8) * 2;
|
||||
mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3;
|
||||
reg = bank->iomux[iomux_num].offset;
|
||||
if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) {
|
||||
if ((pin % 8) >= 4)
|
||||
reg += 0x4;
|
||||
bit = (pin % 4) * 4;
|
||||
} else {
|
||||
bit = (pin % 8) * 2;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&bank->slock, flags);
|
||||
|
||||
data = (3 << (bit + 16));
|
||||
data |= (mux & 3) << bit;
|
||||
ret = regmap_write(info->regmap_base, reg, data);
|
||||
data = (mask << (bit + 16));
|
||||
data |= (mux & mask) << bit;
|
||||
ret = regmap_write(regmap, reg, data);
|
||||
|
||||
spin_unlock_irqrestore(&bank->slock, flags);
|
||||
|
||||
@ -449,7 +517,7 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
|
||||
struct rockchip_pinctrl *info = bank->drvdata;
|
||||
|
||||
/* The first 12 pins of the first bank are located elsewhere */
|
||||
if (bank->bank_type == RK3188_BANK0 && pin_num < 12) {
|
||||
if (bank->bank_num == 0 && pin_num < 12) {
|
||||
*regmap = info->regmap_pmu ? info->regmap_pmu
|
||||
: bank->regmap_pull;
|
||||
*reg = info->regmap_pmu ? RK3188_PULL_PMU_OFFSET : 0;
|
||||
@ -476,6 +544,127 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
|
||||
}
|
||||
}
|
||||
|
||||
#define RK3288_PULL_OFFSET 0x140
|
||||
static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
|
||||
int pin_num, struct regmap **regmap,
|
||||
int *reg, u8 *bit)
|
||||
{
|
||||
struct rockchip_pinctrl *info = bank->drvdata;
|
||||
|
||||
/* The first 24 pins of the first bank are located in PMU */
|
||||
if (bank->bank_num == 0) {
|
||||
*regmap = info->regmap_pmu;
|
||||
*reg = RK3188_PULL_PMU_OFFSET;
|
||||
|
||||
*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
|
||||
*bit = pin_num % RK3188_PULL_PINS_PER_REG;
|
||||
*bit *= RK3188_PULL_BITS_PER_PIN;
|
||||
} else {
|
||||
*regmap = info->regmap_base;
|
||||
*reg = RK3288_PULL_OFFSET;
|
||||
|
||||
/* correct the offset, as we're starting with the 2nd bank */
|
||||
*reg -= 0x10;
|
||||
*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
|
||||
*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
|
||||
|
||||
*bit = (pin_num % RK3188_PULL_PINS_PER_REG);
|
||||
*bit *= RK3188_PULL_BITS_PER_PIN;
|
||||
}
|
||||
}
|
||||
|
||||
#define RK3288_DRV_PMU_OFFSET 0x70
|
||||
#define RK3288_DRV_GRF_OFFSET 0x1c0
|
||||
#define RK3288_DRV_BITS_PER_PIN 2
|
||||
#define RK3288_DRV_PINS_PER_REG 8
|
||||
#define RK3288_DRV_BANK_STRIDE 16
|
||||
static int rk3288_drv_list[] = { 2, 4, 8, 12 };
|
||||
|
||||
static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
|
||||
int pin_num, struct regmap **regmap,
|
||||
int *reg, u8 *bit)
|
||||
{
|
||||
struct rockchip_pinctrl *info = bank->drvdata;
|
||||
|
||||
/* The first 24 pins of the first bank are located in PMU */
|
||||
if (bank->bank_num == 0) {
|
||||
*regmap = info->regmap_pmu;
|
||||
*reg = RK3288_DRV_PMU_OFFSET;
|
||||
|
||||
*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
|
||||
*bit = pin_num % RK3288_DRV_PINS_PER_REG;
|
||||
*bit *= RK3288_DRV_BITS_PER_PIN;
|
||||
} else {
|
||||
*regmap = info->regmap_base;
|
||||
*reg = RK3288_DRV_GRF_OFFSET;
|
||||
|
||||
/* correct the offset, as we're starting with the 2nd bank */
|
||||
*reg -= 0x10;
|
||||
*reg += bank->bank_num * RK3288_DRV_BANK_STRIDE;
|
||||
*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
|
||||
|
||||
*bit = (pin_num % RK3288_DRV_PINS_PER_REG);
|
||||
*bit *= RK3288_DRV_BITS_PER_PIN;
|
||||
}
|
||||
}
|
||||
|
||||
static int rk3288_get_drive(struct rockchip_pin_bank *bank, int pin_num)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
int reg, ret;
|
||||
u32 data;
|
||||
u8 bit;
|
||||
|
||||
rk3288_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit);
|
||||
|
||||
ret = regmap_read(regmap, reg, &data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
data >>= bit;
|
||||
data &= (1 << RK3288_DRV_BITS_PER_PIN) - 1;
|
||||
|
||||
return rk3288_drv_list[data];
|
||||
}
|
||||
|
||||
static int rk3288_set_drive(struct rockchip_pin_bank *bank, int pin_num,
|
||||
int strength)
|
||||
{
|
||||
struct rockchip_pinctrl *info = bank->drvdata;
|
||||
struct regmap *regmap;
|
||||
unsigned long flags;
|
||||
int reg, ret, i;
|
||||
u32 data;
|
||||
u8 bit;
|
||||
|
||||
rk3288_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit);
|
||||
|
||||
ret = -EINVAL;
|
||||
for (i = 0; i < ARRAY_SIZE(rk3288_drv_list); i++) {
|
||||
if (rk3288_drv_list[i] == strength) {
|
||||
ret = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(info->dev, "unsupported driver strength %d\n",
|
||||
strength);
|
||||
return ret;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&bank->slock, flags);
|
||||
|
||||
/* enable the write to the equivalent lower bits */
|
||||
data = ((1 << RK3288_DRV_BITS_PER_PIN) - 1) << (bit + 16);
|
||||
data |= (ret << bit);
|
||||
|
||||
ret = regmap_write(regmap, reg, data);
|
||||
spin_unlock_irqrestore(&bank->slock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
|
||||
{
|
||||
struct rockchip_pinctrl *info = bank->drvdata;
|
||||
@ -501,6 +690,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
|
||||
? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT
|
||||
: PIN_CONFIG_BIAS_DISABLE;
|
||||
case RK3188:
|
||||
case RK3288:
|
||||
data >>= bit;
|
||||
data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1;
|
||||
|
||||
@ -555,6 +745,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
|
||||
spin_unlock_irqrestore(&bank->slock, flags);
|
||||
break;
|
||||
case RK3188:
|
||||
case RK3288:
|
||||
spin_lock_irqsave(&bank->slock, flags);
|
||||
|
||||
/* enable the write to the equivalent lower bits */
|
||||
@ -657,23 +848,6 @@ static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rockchip_pmx_disable(struct pinctrl_dev *pctldev,
|
||||
unsigned selector, unsigned group)
|
||||
{
|
||||
struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
|
||||
const unsigned int *pins = info->groups[group].pins;
|
||||
struct rockchip_pin_bank *bank;
|
||||
int cnt;
|
||||
|
||||
dev_dbg(info->dev, "disable function %s group %s\n",
|
||||
info->functions[selector].name, info->groups[group].name);
|
||||
|
||||
for (cnt = 0; cnt < info->groups[group].npins; cnt++) {
|
||||
bank = pin_to_bank(info, pins[cnt]);
|
||||
rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The calls to gpio_direction_output() and gpio_direction_input()
|
||||
* leads to this function call (via the pinctrl_gpio_direction_{input|output}()
|
||||
@ -716,7 +890,6 @@ static const struct pinmux_ops rockchip_pmx_ops = {
|
||||
.get_function_name = rockchip_pmx_get_func_name,
|
||||
.get_function_groups = rockchip_pmx_get_groups,
|
||||
.enable = rockchip_pmx_enable,
|
||||
.disable = rockchip_pmx_disable,
|
||||
.gpio_set_direction = rockchip_pmx_gpio_set_direction,
|
||||
};
|
||||
|
||||
@ -734,6 +907,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
|
||||
case RK3066B:
|
||||
return pull ? false : true;
|
||||
case RK3188:
|
||||
case RK3288:
|
||||
return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT);
|
||||
}
|
||||
|
||||
@ -788,6 +962,15 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
|
||||
if (rc)
|
||||
return rc;
|
||||
break;
|
||||
case PIN_CONFIG_DRIVE_STRENGTH:
|
||||
/* rk3288 is the first with per-pin drive-strength */
|
||||
if (info->ctrl->type != RK3288)
|
||||
return -ENOTSUPP;
|
||||
|
||||
rc = rk3288_set_drive(bank, pin - bank->pin_base, arg);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUPP;
|
||||
break;
|
||||
@ -837,6 +1020,17 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
|
||||
|
||||
arg = rc ? 1 : 0;
|
||||
break;
|
||||
case PIN_CONFIG_DRIVE_STRENGTH:
|
||||
/* rk3288 is the first with per-pin drive-strength */
|
||||
if (info->ctrl->type != RK3288)
|
||||
return -ENOTSUPP;
|
||||
|
||||
rc = rk3288_get_drive(bank, pin - bank->pin_base);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
arg = rc;
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUPP;
|
||||
break;
|
||||
@ -850,6 +1044,7 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
|
||||
static const struct pinconf_ops rockchip_pinconf_ops = {
|
||||
.pin_config_get = rockchip_pinconf_get,
|
||||
.pin_config_set = rockchip_pinconf_set,
|
||||
.is_generic = true,
|
||||
};
|
||||
|
||||
static const struct of_device_id rockchip_bank_match[] = {
|
||||
@ -1414,10 +1609,7 @@ fail:
|
||||
for (--i, --bank; i >= 0; --i, --bank) {
|
||||
if (!bank->valid)
|
||||
continue;
|
||||
|
||||
if (gpiochip_remove(&bank->gpio_chip))
|
||||
dev_err(&pdev->dev, "gpio chip %s remove failed\n",
|
||||
bank->gpio_chip.label);
|
||||
gpiochip_remove(&bank->gpio_chip);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1427,20 +1619,15 @@ static int rockchip_gpiolib_unregister(struct platform_device *pdev,
|
||||
{
|
||||
struct rockchip_pin_ctrl *ctrl = info->ctrl;
|
||||
struct rockchip_pin_bank *bank = ctrl->pin_banks;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank) {
|
||||
for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
|
||||
if (!bank->valid)
|
||||
continue;
|
||||
|
||||
ret = gpiochip_remove(&bank->gpio_chip);
|
||||
gpiochip_remove(&bank->gpio_chip);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
dev_err(&pdev->dev, "gpio chip remove failed\n");
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
|
||||
@ -1466,8 +1653,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
|
||||
"rockchip,rk3188-gpio-bank0")) {
|
||||
struct device_node *node;
|
||||
|
||||
bank->bank_type = RK3188_BANK0;
|
||||
|
||||
node = of_parse_phandle(bank->of_node->parent,
|
||||
"rockchip,pmu", 0);
|
||||
if (!node) {
|
||||
@ -1487,9 +1672,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
|
||||
base,
|
||||
&rockchip_regmap_config);
|
||||
}
|
||||
|
||||
} else {
|
||||
bank->bank_type = COMMON_BANK;
|
||||
}
|
||||
|
||||
bank->irq = irq_of_parse_and_map(bank->of_node, 0);
|
||||
@ -1513,7 +1695,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
|
||||
struct device_node *np;
|
||||
struct rockchip_pin_ctrl *ctrl;
|
||||
struct rockchip_pin_bank *bank;
|
||||
int i;
|
||||
int grf_offs, pmu_offs, i, j;
|
||||
|
||||
match = of_match_node(rockchip_pinctrl_dt_match, node);
|
||||
ctrl = (struct rockchip_pin_ctrl *)match->data;
|
||||
@ -1535,12 +1717,51 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
|
||||
}
|
||||
}
|
||||
|
||||
grf_offs = ctrl->grf_mux_offset;
|
||||
pmu_offs = ctrl->pmu_mux_offset;
|
||||
bank = ctrl->pin_banks;
|
||||
for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
|
||||
int bank_pins = 0;
|
||||
|
||||
spin_lock_init(&bank->slock);
|
||||
bank->drvdata = d;
|
||||
bank->pin_base = ctrl->nr_pins;
|
||||
ctrl->nr_pins += bank->nr_pins;
|
||||
|
||||
/* calculate iomux offsets */
|
||||
for (j = 0; j < 4; j++) {
|
||||
struct rockchip_iomux *iom = &bank->iomux[j];
|
||||
int inc;
|
||||
|
||||
if (bank_pins >= bank->nr_pins)
|
||||
break;
|
||||
|
||||
/* preset offset value, set new start value */
|
||||
if (iom->offset >= 0) {
|
||||
if (iom->type & IOMUX_SOURCE_PMU)
|
||||
pmu_offs = iom->offset;
|
||||
else
|
||||
grf_offs = iom->offset;
|
||||
} else { /* set current offset */
|
||||
iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
|
||||
pmu_offs : grf_offs;
|
||||
}
|
||||
|
||||
dev_dbg(d->dev, "bank %d, iomux %d has offset 0x%x\n",
|
||||
i, j, iom->offset);
|
||||
|
||||
/*
|
||||
* Increase offset according to iomux width.
|
||||
* 4bit iomux'es are spread over two registers.
|
||||
*/
|
||||
inc = (iom->type & IOMUX_WIDTH_4BIT) ? 8 : 4;
|
||||
if (iom->type & IOMUX_SOURCE_PMU)
|
||||
pmu_offs += inc;
|
||||
else
|
||||
grf_offs += inc;
|
||||
|
||||
bank_pins += 8;
|
||||
}
|
||||
}
|
||||
|
||||
return ctrl;
|
||||
@ -1644,7 +1865,7 @@ static struct rockchip_pin_ctrl rk2928_pin_ctrl = {
|
||||
.nr_banks = ARRAY_SIZE(rk2928_pin_banks),
|
||||
.label = "RK2928-GPIO",
|
||||
.type = RK2928,
|
||||
.mux_offset = 0xa8,
|
||||
.grf_mux_offset = 0xa8,
|
||||
.pull_calc_reg = rk2928_calc_pull_reg_and_bit,
|
||||
};
|
||||
|
||||
@ -1662,7 +1883,7 @@ static struct rockchip_pin_ctrl rk3066a_pin_ctrl = {
|
||||
.nr_banks = ARRAY_SIZE(rk3066a_pin_banks),
|
||||
.label = "RK3066a-GPIO",
|
||||
.type = RK2928,
|
||||
.mux_offset = 0xa8,
|
||||
.grf_mux_offset = 0xa8,
|
||||
.pull_calc_reg = rk2928_calc_pull_reg_and_bit,
|
||||
};
|
||||
|
||||
@ -1678,11 +1899,11 @@ static struct rockchip_pin_ctrl rk3066b_pin_ctrl = {
|
||||
.nr_banks = ARRAY_SIZE(rk3066b_pin_banks),
|
||||
.label = "RK3066b-GPIO",
|
||||
.type = RK3066B,
|
||||
.mux_offset = 0x60,
|
||||
.grf_mux_offset = 0x60,
|
||||
};
|
||||
|
||||
static struct rockchip_pin_bank rk3188_pin_banks[] = {
|
||||
PIN_BANK(0, 32, "gpio0"),
|
||||
PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0),
|
||||
PIN_BANK(1, 32, "gpio1"),
|
||||
PIN_BANK(2, 32, "gpio2"),
|
||||
PIN_BANK(3, 32, "gpio3"),
|
||||
@ -1693,10 +1914,52 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
|
||||
.nr_banks = ARRAY_SIZE(rk3188_pin_banks),
|
||||
.label = "RK3188-GPIO",
|
||||
.type = RK3188,
|
||||
.mux_offset = 0x60,
|
||||
.grf_mux_offset = 0x60,
|
||||
.pull_calc_reg = rk3188_calc_pull_reg_and_bit,
|
||||
};
|
||||
|
||||
static struct rockchip_pin_bank rk3288_pin_banks[] = {
|
||||
PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU,
|
||||
IOMUX_SOURCE_PMU,
|
||||
IOMUX_SOURCE_PMU,
|
||||
IOMUX_UNROUTED
|
||||
),
|
||||
PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED,
|
||||
IOMUX_UNROUTED,
|
||||
IOMUX_UNROUTED,
|
||||
0
|
||||
),
|
||||
PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED),
|
||||
PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT),
|
||||
PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
|
||||
IOMUX_WIDTH_4BIT,
|
||||
0,
|
||||
0
|
||||
),
|
||||
PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED,
|
||||
0,
|
||||
0,
|
||||
IOMUX_UNROUTED
|
||||
),
|
||||
PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED),
|
||||
PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0,
|
||||
0,
|
||||
IOMUX_WIDTH_4BIT,
|
||||
IOMUX_UNROUTED
|
||||
),
|
||||
PIN_BANK(8, 16, "gpio8"),
|
||||
};
|
||||
|
||||
static struct rockchip_pin_ctrl rk3288_pin_ctrl = {
|
||||
.pin_banks = rk3288_pin_banks,
|
||||
.nr_banks = ARRAY_SIZE(rk3288_pin_banks),
|
||||
.label = "RK3288-GPIO",
|
||||
.type = RK3288,
|
||||
.grf_mux_offset = 0x0,
|
||||
.pmu_mux_offset = 0x84,
|
||||
.pull_calc_reg = rk3288_calc_pull_reg_and_bit,
|
||||
};
|
||||
|
||||
static const struct of_device_id rockchip_pinctrl_dt_match[] = {
|
||||
{ .compatible = "rockchip,rk2928-pinctrl",
|
||||
.data = (void *)&rk2928_pin_ctrl },
|
||||
@ -1706,6 +1969,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = {
|
||||
.data = (void *)&rk3066b_pin_ctrl },
|
||||
{ .compatible = "rockchip,rk3188-pinctrl",
|
||||
.data = (void *)&rk3188_pin_ctrl },
|
||||
{ .compatible = "rockchip,rk3288-pinctrl",
|
||||
.data = (void *)&rk3288_pin_ctrl },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match);
|
||||
|
@ -488,61 +488,6 @@ static int pcs_enable(struct pinctrl_dev *pctldev, unsigned fselector,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector,
|
||||
unsigned group)
|
||||
{
|
||||
struct pcs_device *pcs;
|
||||
struct pcs_function *func;
|
||||
int i;
|
||||
|
||||
pcs = pinctrl_dev_get_drvdata(pctldev);
|
||||
/* If function mask is null, needn't disable it. */
|
||||
if (!pcs->fmask)
|
||||
return;
|
||||
|
||||
func = radix_tree_lookup(&pcs->ftree, fselector);
|
||||
if (!func) {
|
||||
dev_err(pcs->dev, "%s could not find function%i\n",
|
||||
__func__, fselector);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ignore disable if function-off is not specified. Some hardware
|
||||
* does not have clearly defined disable function. For pin specific
|
||||
* off modes, you can use alternate named states as described in
|
||||
* pinctrl-bindings.txt.
|
||||
*/
|
||||
if (pcs->foff == PCS_OFF_DISABLED) {
|
||||
dev_dbg(pcs->dev, "ignoring disable for %s function%i\n",
|
||||
func->name, fselector);
|
||||
return;
|
||||
}
|
||||
|
||||
dev_dbg(pcs->dev, "disabling function%i %s\n",
|
||||
fselector, func->name);
|
||||
|
||||
for (i = 0; i < func->nvals; i++) {
|
||||
struct pcs_func_vals *vals;
|
||||
unsigned long flags;
|
||||
unsigned val, mask;
|
||||
|
||||
vals = &func->vals[i];
|
||||
raw_spin_lock_irqsave(&pcs->lock, flags);
|
||||
val = pcs->read(vals->reg);
|
||||
|
||||
if (pcs->bits_per_mux)
|
||||
mask = vals->mask;
|
||||
else
|
||||
mask = pcs->fmask;
|
||||
|
||||
val &= ~mask;
|
||||
val |= pcs->foff << pcs->fshift;
|
||||
pcs->write(val, vals->reg);
|
||||
raw_spin_unlock_irqrestore(&pcs->lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
static int pcs_request_gpio(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range, unsigned pin)
|
||||
{
|
||||
@ -575,7 +520,6 @@ static const struct pinmux_ops pcs_pinmux_ops = {
|
||||
.get_function_name = pcs_get_function_name,
|
||||
.get_function_groups = pcs_get_function_groups,
|
||||
.enable = pcs_enable,
|
||||
.disable = pcs_disable,
|
||||
.gpio_request_enable = pcs_request_gpio,
|
||||
};
|
||||
|
||||
@ -836,7 +780,7 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset,
|
||||
|
||||
pin = &pcs->pins.pa[i];
|
||||
pn = &pcs->names[i];
|
||||
sprintf(pn->name, "%lx.%d",
|
||||
sprintf(pn->name, "%lx.%u",
|
||||
(unsigned long)pcs->res->start + offset, pin_pos);
|
||||
pin->name = pn->name;
|
||||
pin->number = i;
|
||||
@ -1739,11 +1683,10 @@ static void pcs_irq_chain_handler(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
struct pcs_soc_data *pcs_soc = irq_desc_get_handler_data(desc);
|
||||
struct irq_chip *chip;
|
||||
int res;
|
||||
|
||||
chip = irq_get_chip(irq);
|
||||
chained_irq_enter(chip, desc);
|
||||
res = pcs_irq_handle(pcs_soc);
|
||||
pcs_irq_handle(pcs_soc);
|
||||
/* REVISIT: export and add handle_bad_irq(irq, desc)? */
|
||||
chained_irq_exit(chip, desc);
|
||||
|
||||
|
@ -930,11 +930,6 @@ static int st_pmx_enable(struct pinctrl_dev *pctldev, unsigned fselector,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void st_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
unsigned group)
|
||||
{
|
||||
}
|
||||
|
||||
static int st_pmx_set_gpio_direction(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range, unsigned gpio,
|
||||
bool input)
|
||||
@ -957,7 +952,6 @@ static struct pinmux_ops st_pmxops = {
|
||||
.get_function_name = st_pmx_get_fname,
|
||||
.get_function_groups = st_pmx_get_groups,
|
||||
.enable = st_pmx_enable,
|
||||
.disable = st_pmx_disable,
|
||||
.gpio_set_direction = st_pmx_set_gpio_direction,
|
||||
};
|
||||
|
||||
@ -1178,9 +1172,7 @@ static int st_pctl_dt_parse_groups(struct device_node *np,
|
||||
const __be32 *list;
|
||||
struct property *pp;
|
||||
struct st_pinconf *conf;
|
||||
phandle phandle;
|
||||
struct device_node *pins;
|
||||
u32 pin;
|
||||
int i = 0, npins = 0, nr_props;
|
||||
|
||||
pins = of_get_child_by_name(np, "st,pins");
|
||||
@ -1218,8 +1210,8 @@ static int st_pctl_dt_parse_groups(struct device_node *np,
|
||||
conf = &grp->pin_conf[i];
|
||||
|
||||
/* bank & offset */
|
||||
phandle = be32_to_cpup(list++);
|
||||
pin = be32_to_cpup(list++);
|
||||
be32_to_cpup(list++);
|
||||
be32_to_cpup(list++);
|
||||
conf->pin = of_get_named_gpio(pins, pp->name, 0);
|
||||
conf->name = pp->name;
|
||||
grp->pins[i] = conf->pin;
|
||||
@ -1256,7 +1248,7 @@ static int st_pctl_parse_functions(struct device_node *np,
|
||||
func = &info->functions[index];
|
||||
func->name = np->name;
|
||||
func->ngroups = of_get_child_count(np);
|
||||
if (func->ngroups <= 0) {
|
||||
if (func->ngroups == 0) {
|
||||
dev_err(info->dev, "No groups defined\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -1454,6 +1446,7 @@ static struct irq_chip st_gpio_irqchip = {
|
||||
.irq_mask = st_gpio_irq_mask,
|
||||
.irq_unmask = st_gpio_irq_unmask,
|
||||
.irq_set_type = st_gpio_irq_set_type,
|
||||
.flags = IRQCHIP_SKIP_SET_WAKE,
|
||||
};
|
||||
|
||||
static int st_gpiolib_register_bank(struct st_pinctrl *info,
|
||||
|
@ -738,22 +738,6 @@ static int tb10x_pctl_enable(struct pinctrl_dev *pctl,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tb10x_pctl_disable(struct pinctrl_dev *pctl,
|
||||
unsigned func_selector, unsigned group_selector)
|
||||
{
|
||||
struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
|
||||
const struct tb10x_pinfuncgrp *grp = &state->pingroups[group_selector];
|
||||
|
||||
if (grp->port < 0)
|
||||
return;
|
||||
|
||||
mutex_lock(&state->mutex);
|
||||
|
||||
state->ports[grp->port].count--;
|
||||
|
||||
mutex_unlock(&state->mutex);
|
||||
}
|
||||
|
||||
static struct pinmux_ops tb10x_pinmux_ops = {
|
||||
.get_functions_count = tb10x_get_functions_count,
|
||||
.get_function_name = tb10x_get_function_name,
|
||||
@ -761,7 +745,6 @@ static struct pinmux_ops tb10x_pinmux_ops = {
|
||||
.gpio_request_enable = tb10x_gpio_request_enable,
|
||||
.gpio_disable_free = tb10x_gpio_disable_free,
|
||||
.enable = tb10x_pctl_enable,
|
||||
.disable = tb10x_pctl_disable,
|
||||
};
|
||||
|
||||
static struct pinctrl_desc tb10x_pindesc = {
|
||||
|
@ -290,24 +290,11 @@ static int tegra_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tegra_pinctrl_disable(struct pinctrl_dev *pctldev,
|
||||
unsigned function, unsigned group)
|
||||
{
|
||||
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct tegra_pingroup *g;
|
||||
|
||||
g = &pmx->soc->groups[group];
|
||||
|
||||
if (WARN_ON(g->mux_reg < 0))
|
||||
return;
|
||||
}
|
||||
|
||||
static const struct pinmux_ops tegra_pinmux_ops = {
|
||||
.get_functions_count = tegra_pinctrl_get_funcs_count,
|
||||
.get_function_name = tegra_pinctrl_get_func_name,
|
||||
.get_function_groups = tegra_pinctrl_get_func_groups,
|
||||
.enable = tegra_pinctrl_enable,
|
||||
.disable = tegra_pinctrl_disable,
|
||||
};
|
||||
|
||||
static int tegra_pinconf_reg(struct tegra_pmx *pmx,
|
||||
|
@ -574,33 +574,6 @@ static int tz1090_pdc_pinctrl_enable(struct pinctrl_dev *pctldev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tz1090_pdc_pinctrl_disable(struct pinctrl_dev *pctldev,
|
||||
unsigned int function,
|
||||
unsigned int group)
|
||||
{
|
||||
struct tz1090_pdc_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct tz1090_pdc_pingroup *grp = &tz1090_pdc_groups[group];
|
||||
|
||||
dev_dbg(pctldev->dev, "%s(func=%u (%s), group=%u (%s))\n",
|
||||
__func__,
|
||||
function, tz1090_pdc_functions[function].name,
|
||||
group, tz1090_pdc_groups[group].name);
|
||||
|
||||
/* is it even a mux? */
|
||||
if (grp->drv)
|
||||
return;
|
||||
|
||||
/* does this group even control the function? */
|
||||
if (function != grp->func)
|
||||
return;
|
||||
|
||||
/* record the pin being unmuxed and update mux bit */
|
||||
spin_lock(&pmx->lock);
|
||||
pmx->mux_en &= ~BIT(grp->pins[0]);
|
||||
tz1090_pdc_pinctrl_mux(pmx, grp);
|
||||
spin_unlock(&pmx->lock);
|
||||
}
|
||||
|
||||
static const struct tz1090_pdc_pingroup *find_mux_group(
|
||||
struct tz1090_pdc_pmx *pmx,
|
||||
unsigned int pin)
|
||||
@ -662,7 +635,6 @@ static struct pinmux_ops tz1090_pdc_pinmux_ops = {
|
||||
.get_function_name = tz1090_pdc_pinctrl_get_func_name,
|
||||
.get_function_groups = tz1090_pdc_pinctrl_get_func_groups,
|
||||
.enable = tz1090_pdc_pinctrl_enable,
|
||||
.disable = tz1090_pdc_pinctrl_disable,
|
||||
.gpio_request_enable = tz1090_pdc_pinctrl_gpio_request_enable,
|
||||
.gpio_disable_free = tz1090_pdc_pinctrl_gpio_disable_free,
|
||||
};
|
||||
|
@ -1478,63 +1478,6 @@ mux_pins:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* tz1090_pinctrl_disable() - Disable a function on a pin group.
|
||||
* @pctldev: Pin control data
|
||||
* @function: Function index to disable
|
||||
* @group: Group index to disable
|
||||
*
|
||||
* Disable a particular function on a group of pins. The per GPIO pin pseudo pin
|
||||
* groups can be used (in which case the pin will be taken out of peripheral
|
||||
* mode. Some convenience pin groups can also be used in which case the effect
|
||||
* is the same as enabling the function on each individual pin in the group.
|
||||
*/
|
||||
static void tz1090_pinctrl_disable(struct pinctrl_dev *pctldev,
|
||||
unsigned int function, unsigned int group)
|
||||
{
|
||||
struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct tz1090_pingroup *grp;
|
||||
unsigned int pin_num, mux_group, i, npins;
|
||||
const unsigned int *pins;
|
||||
|
||||
/* group of pins? */
|
||||
if (group < ARRAY_SIZE(tz1090_groups)) {
|
||||
grp = &tz1090_groups[group];
|
||||
npins = grp->npins;
|
||||
pins = grp->pins;
|
||||
/*
|
||||
* All pins in the group must belong to the same mux group,
|
||||
* which allows us to just use the mux group of the first pin.
|
||||
* By explicitly listing permitted pingroups for each function
|
||||
* the pinmux core should ensure this is always the case.
|
||||
*/
|
||||
} else {
|
||||
pin_num = group - ARRAY_SIZE(tz1090_groups);
|
||||
npins = 1;
|
||||
pins = &pin_num;
|
||||
}
|
||||
mux_group = tz1090_mux_pins[*pins];
|
||||
|
||||
/* no mux group, but can still be individually muxed to peripheral */
|
||||
if (mux_group >= TZ1090_MUX_GROUP_MAX) {
|
||||
if (function == TZ1090_MUX_PERIP)
|
||||
goto unmux_pins;
|
||||
return;
|
||||
}
|
||||
|
||||
/* mux group already set to a different function? */
|
||||
grp = &tz1090_mux_groups[mux_group];
|
||||
dev_dbg(pctldev->dev, "%s: unmuxing %u pin(s) in '%s' from '%s'\n",
|
||||
__func__, npins, grp->name, tz1090_functions[function].name);
|
||||
|
||||
/* subtract pins from ref count and unmux individually */
|
||||
WARN_ON(grp->func_count < npins);
|
||||
grp->func_count -= npins;
|
||||
unmux_pins:
|
||||
for (i = 0; i < npins; ++i)
|
||||
tz1090_pinctrl_perip_select(pmx, pins[i], false);
|
||||
}
|
||||
|
||||
/**
|
||||
* tz1090_pinctrl_gpio_request_enable() - Put pin in GPIO mode.
|
||||
* @pctldev: Pin control data
|
||||
@ -1575,7 +1518,6 @@ static struct pinmux_ops tz1090_pinmux_ops = {
|
||||
.get_function_name = tz1090_pinctrl_get_func_name,
|
||||
.get_function_groups = tz1090_pinctrl_get_func_groups,
|
||||
.enable = tz1090_pinctrl_enable,
|
||||
.disable = tz1090_pinctrl_disable,
|
||||
.gpio_request_enable = tz1090_pinctrl_gpio_request_enable,
|
||||
.gpio_disable_free = tz1090_pinctrl_gpio_disable_free,
|
||||
};
|
||||
|
@ -970,19 +970,6 @@ static int u300_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void u300_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
unsigned group)
|
||||
{
|
||||
struct u300_pmx *upmx;
|
||||
|
||||
/* There is nothing to do with the power pins */
|
||||
if (selector == 0)
|
||||
return;
|
||||
|
||||
upmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
u300_pmx_endisable(upmx, selector, false);
|
||||
}
|
||||
|
||||
static int u300_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
return ARRAY_SIZE(u300_pmx_functions);
|
||||
@ -1008,7 +995,6 @@ static const struct pinmux_ops u300_pmx_ops = {
|
||||
.get_function_name = u300_pmx_get_func_name,
|
||||
.get_function_groups = u300_pmx_get_groups,
|
||||
.enable = u300_pmx_enable,
|
||||
.disable = u300_pmx_disable,
|
||||
};
|
||||
|
||||
static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
|
||||
|
@ -471,7 +471,6 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
|
||||
{
|
||||
struct pinctrl_dev *pctldev = setting->pctldev;
|
||||
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
|
||||
const struct pinmux_ops *ops = pctldev->desc->pmxops;
|
||||
int ret = 0;
|
||||
const unsigned *pins = NULL;
|
||||
unsigned num_pins = 0;
|
||||
@ -518,9 +517,6 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
|
||||
pins[i], desc->name, gname);
|
||||
}
|
||||
}
|
||||
|
||||
if (ops->disable)
|
||||
ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
42
drivers/pinctrl/qcom/Kconfig
Normal file
42
drivers/pinctrl/qcom/Kconfig
Normal file
@ -0,0 +1,42 @@
|
||||
if (ARCH_QCOM || COMPILE_TEST)
|
||||
|
||||
config PINCTRL_MSM
|
||||
bool
|
||||
select PINMUX
|
||||
select PINCONF
|
||||
select GENERIC_PINCONF
|
||||
select GPIOLIB_IRQCHIP
|
||||
|
||||
config PINCTRL_APQ8064
|
||||
tristate "Qualcomm APQ8064 pin controller driver"
|
||||
depends on GPIOLIB && OF
|
||||
select PINCTRL_MSM
|
||||
help
|
||||
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
|
||||
Qualcomm TLMM block found in the Qualcomm APQ8064 platform.
|
||||
|
||||
config PINCTRL_IPQ8064
|
||||
tristate "Qualcomm IPQ8064 pin controller driver"
|
||||
depends on GPIOLIB && OF
|
||||
select PINCTRL_MSM
|
||||
help
|
||||
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
|
||||
Qualcomm TLMM block found in the Qualcomm IPQ8064 platform.
|
||||
|
||||
config PINCTRL_MSM8960
|
||||
tristate "Qualcomm 8960 pin controller driver"
|
||||
depends on GPIOLIB && OF
|
||||
select PINCTRL_MSM
|
||||
help
|
||||
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
|
||||
Qualcomm TLMM block found in the Qualcomm 8960 platform.
|
||||
|
||||
config PINCTRL_MSM8X74
|
||||
tristate "Qualcomm 8x74 pin controller driver"
|
||||
depends on GPIOLIB && OF
|
||||
select PINCTRL_MSM
|
||||
help
|
||||
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
|
||||
Qualcomm TLMM block found in the Qualcomm 8974 platform.
|
||||
|
||||
endif
|
6
drivers/pinctrl/qcom/Makefile
Normal file
6
drivers/pinctrl/qcom/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# Qualcomm pin control drivers
|
||||
obj-$(CONFIG_PINCTRL_MSM) += pinctrl-msm.o
|
||||
obj-$(CONFIG_PINCTRL_APQ8064) += pinctrl-apq8064.o
|
||||
obj-$(CONFIG_PINCTRL_IPQ8064) += pinctrl-ipq8064.o
|
||||
obj-$(CONFIG_PINCTRL_MSM8960) += pinctrl-msm8960.o
|
||||
obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o
|
@ -230,7 +230,7 @@ static const unsigned int sdc3_data_pins[] = { 95 };
|
||||
.pins = gpio##id##_pins, \
|
||||
.npins = ARRAY_SIZE(gpio##id##_pins), \
|
||||
.funcs = (int[]){ \
|
||||
APQ_MUX_NA, /* gpio mode */ \
|
||||
APQ_MUX_gpio, \
|
||||
APQ_MUX_##f1, \
|
||||
APQ_MUX_##f2, \
|
||||
APQ_MUX_##f3, \
|
||||
@ -293,6 +293,7 @@ enum apq8064_functions {
|
||||
APQ_MUX_cam_mclk,
|
||||
APQ_MUX_codec_mic_i2s,
|
||||
APQ_MUX_codec_spkr_i2s,
|
||||
APQ_MUX_gpio,
|
||||
APQ_MUX_gsbi1,
|
||||
APQ_MUX_gsbi2,
|
||||
APQ_MUX_gsbi3,
|
||||
@ -335,6 +336,21 @@ static const char * const codec_mic_i2s_groups[] = {
|
||||
static const char * const codec_spkr_i2s_groups[] = {
|
||||
"gpio39", "gpio40", "gpio41", "gpio42"
|
||||
};
|
||||
static const char * const gpio_groups[] = {
|
||||
"gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
|
||||
"gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
|
||||
"gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
|
||||
"gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
|
||||
"gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
|
||||
"gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
|
||||
"gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
|
||||
"gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
|
||||
"gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
|
||||
"gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
|
||||
"gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
|
||||
"gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84",
|
||||
"gpio85", "gpio86", "gpio87", "gpio88", "gpio89"
|
||||
};
|
||||
static const char * const gsbi1_groups[] = {
|
||||
"gpio18", "gpio19", "gpio20", "gpio21"
|
||||
};
|
||||
@ -430,6 +446,7 @@ static const struct msm_function apq8064_functions[] = {
|
||||
FUNCTION(cam_mclk),
|
||||
FUNCTION(codec_mic_i2s),
|
||||
FUNCTION(codec_spkr_i2s),
|
||||
FUNCTION(gpio),
|
||||
FUNCTION(gsbi1),
|
||||
FUNCTION(gsbi2),
|
||||
FUNCTION(gsbi3),
|
@ -183,7 +183,7 @@ static const unsigned int sdc3_data_pins[] = { 71 };
|
||||
.pins = gpio##id##_pins, \
|
||||
.npins = ARRAY_SIZE(gpio##id##_pins), \
|
||||
.funcs = (int[]){ \
|
||||
IPQ_MUX_NA, /* gpio mode */ \
|
||||
IPQ_MUX_gpio, \
|
||||
IPQ_MUX_##f1, \
|
||||
IPQ_MUX_##f2, \
|
||||
IPQ_MUX_##f3, \
|
||||
@ -243,6 +243,7 @@ static const unsigned int sdc3_data_pins[] = { 71 };
|
||||
}
|
||||
|
||||
enum ipq8064_functions {
|
||||
IPQ_MUX_gpio,
|
||||
IPQ_MUX_mdio,
|
||||
IPQ_MUX_mi2s,
|
||||
IPQ_MUX_pdm,
|
||||
@ -291,6 +292,19 @@ enum ipq8064_functions {
|
||||
IPQ_MUX_NA,
|
||||
};
|
||||
|
||||
static const char * const gpio_groups[] = {
|
||||
"gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
|
||||
"gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
|
||||
"gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
|
||||
"gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
|
||||
"gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
|
||||
"gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
|
||||
"gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
|
||||
"gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
|
||||
"gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
|
||||
"gpio64", "gpio65", "gpio66", "gpio67", "gpio68"
|
||||
};
|
||||
|
||||
static const char * const mdio_groups[] = {
|
||||
"gpio0", "gpio1", "gpio10", "gpio11",
|
||||
};
|
||||
@ -481,6 +495,7 @@ static const char * const ps_hold_groups[] = {
|
||||
};
|
||||
|
||||
static const struct msm_function ipq8064_functions[] = {
|
||||
FUNCTION(gpio),
|
||||
FUNCTION(mdio),
|
||||
FUNCTION(ssbi),
|
||||
FUNCTION(spmi),
|
@ -27,10 +27,10 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "pinconf.h"
|
||||
#include "../core.h"
|
||||
#include "../pinconf.h"
|
||||
#include "pinctrl-msm.h"
|
||||
#include "pinctrl-utils.h"
|
||||
#include "../pinctrl-utils.h"
|
||||
|
||||
#define MAX_NR_GPIO 300
|
||||
|
||||
@ -142,9 +142,6 @@ static int msm_pinmux_enable(struct pinctrl_dev *pctldev,
|
||||
|
||||
g = &pctrl->soc->groups[group];
|
||||
|
||||
if (WARN_ON(g->mux_bit < 0))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < g->nfuncs; i++) {
|
||||
if (g->funcs[i] == function)
|
||||
break;
|
||||
@ -165,36 +162,11 @@ static int msm_pinmux_enable(struct pinctrl_dev *pctldev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void msm_pinmux_disable(struct pinctrl_dev *pctldev,
|
||||
unsigned function,
|
||||
unsigned group)
|
||||
{
|
||||
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct msm_pingroup *g;
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
g = &pctrl->soc->groups[group];
|
||||
|
||||
if (WARN_ON(g->mux_bit < 0))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&pctrl->lock, flags);
|
||||
|
||||
/* Clear the mux bits to select gpio mode */
|
||||
val = readl(pctrl->regs + g->ctl_reg);
|
||||
val &= ~(0x7 << g->mux_bit);
|
||||
writel(val, pctrl->regs + g->ctl_reg);
|
||||
|
||||
spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||
}
|
||||
|
||||
static const struct pinmux_ops msm_pinmux_ops = {
|
||||
.get_functions_count = msm_get_functions_count,
|
||||
.get_function_name = msm_get_function_name,
|
||||
.get_function_groups = msm_get_function_groups,
|
||||
.enable = msm_pinmux_enable,
|
||||
.disable = msm_pinmux_disable,
|
||||
};
|
||||
|
||||
static int msm_config_reg(struct msm_pinctrl *pctrl,
|
||||
@ -206,6 +178,7 @@ static int msm_config_reg(struct msm_pinctrl *pctrl,
|
||||
switch (param) {
|
||||
case PIN_CONFIG_BIAS_DISABLE:
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
case PIN_CONFIG_BIAS_BUS_HOLD:
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
*bit = g->pull_bit;
|
||||
*mask = 3;
|
||||
@ -243,6 +216,7 @@ static int msm_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
|
||||
|
||||
#define MSM_NO_PULL 0
|
||||
#define MSM_PULL_DOWN 1
|
||||
#define MSM_KEEPER 2
|
||||
#define MSM_PULL_UP 3
|
||||
|
||||
static unsigned msm_regval_to_drive(u32 val)
|
||||
@ -280,6 +254,9 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev,
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
arg = arg == MSM_PULL_DOWN;
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_BUS_HOLD:
|
||||
arg = arg == MSM_KEEPER;
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
arg = arg == MSM_PULL_UP;
|
||||
break;
|
||||
@ -339,6 +316,9 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev,
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
arg = MSM_PULL_DOWN;
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_BUS_HOLD:
|
||||
arg = MSM_KEEPER;
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
arg = MSM_PULL_UP;
|
||||
break;
|
1282
drivers/pinctrl/qcom/pinctrl-msm8960.c
Normal file
1282
drivers/pinctrl/qcom/pinctrl-msm8960.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -342,7 +342,7 @@ static const unsigned int sdc2_data_pins[] = { 151 };
|
||||
.pins = gpio##id##_pins, \
|
||||
.npins = ARRAY_SIZE(gpio##id##_pins), \
|
||||
.funcs = (int[]){ \
|
||||
MSM_MUX_NA, /* gpio mode */ \
|
||||
MSM_MUX_gpio, \
|
||||
MSM_MUX_##f1, \
|
||||
MSM_MUX_##f2, \
|
||||
MSM_MUX_##f3, \
|
||||
@ -402,6 +402,7 @@ static const unsigned int sdc2_data_pins[] = { 151 };
|
||||
* the pingroup table below.
|
||||
*/
|
||||
enum msm8x74_functions {
|
||||
MSM_MUX_gpio,
|
||||
MSM_MUX_cci_i2c0,
|
||||
MSM_MUX_cci_i2c1,
|
||||
MSM_MUX_blsp_i2c1,
|
||||
@ -509,6 +510,31 @@ enum msm8x74_functions {
|
||||
MSM_MUX_NA,
|
||||
};
|
||||
|
||||
static const char * const gpio_groups[] = {
|
||||
"gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
|
||||
"gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
|
||||
"gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
|
||||
"gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
|
||||
"gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
|
||||
"gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
|
||||
"gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
|
||||
"gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
|
||||
"gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
|
||||
"gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
|
||||
"gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
|
||||
"gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84",
|
||||
"gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91",
|
||||
"gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98",
|
||||
"gpio99", "gpio100", "gpio101", "gpio102", "gpio103", "gpio104",
|
||||
"gpio105", "gpio106", "gpio107", "gpio108", "gpio109", "gpio110",
|
||||
"gpio111", "gpio112", "gpio113", "gpio114", "gpio115", "gpio116",
|
||||
"gpio117", "gpio118", "gpio119", "gpio120", "gpio121", "gpio122",
|
||||
"gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128",
|
||||
"gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134",
|
||||
"gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140",
|
||||
"gpio141", "gpio142", "gpio143", "gpio144", "gpio145"
|
||||
};
|
||||
|
||||
static const char * const blsp_uart1_groups[] = {
|
||||
"gpio0", "gpio1", "gpio2", "gpio3"
|
||||
};
|
||||
@ -728,6 +754,7 @@ static const char * const wlan_groups[] = {
|
||||
static const char * const slimbus_groups[] = { "gpio70", "gpio71" };
|
||||
|
||||
static const struct msm_function msm8x74_functions[] = {
|
||||
FUNCTION(gpio),
|
||||
FUNCTION(cci_i2c0),
|
||||
FUNCTION(cci_i2c1),
|
||||
FUNCTION(uim1),
|
28
drivers/pinctrl/samsung/Kconfig
Normal file
28
drivers/pinctrl/samsung/Kconfig
Normal file
@ -0,0 +1,28 @@
|
||||
#
|
||||
# Samsung Pin control drivers
|
||||
#
|
||||
config PINCTRL_SAMSUNG
|
||||
bool
|
||||
select PINMUX
|
||||
select PINCONF
|
||||
|
||||
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
|
||||
|
||||
config PINCTRL_EXYNOS5440
|
||||
bool "Samsung EXYNOS5440 SoC pinctrl driver"
|
||||
depends on SOC_EXYNOS5440
|
||||
select PINMUX
|
||||
select PINCONF
|
||||
|
||||
config PINCTRL_S3C24XX
|
||||
bool "Samsung S3C24XX SoC pinctrl driver"
|
||||
depends on ARCH_S3C24XX
|
||||
select PINCTRL_SAMSUNG
|
||||
|
||||
config PINCTRL_S3C64XX
|
||||
bool "Samsung S3C64XX SoC pinctrl driver"
|
||||
depends on ARCH_S3C64XX
|
||||
select PINCTRL_SAMSUNG
|
7
drivers/pinctrl/samsung/Makefile
Normal file
7
drivers/pinctrl/samsung/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# Samsung pin control drivers
|
||||
|
||||
obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o
|
||||
obj-$(CONFIG_PINCTRL_EXYNOS) += pinctrl-exynos.o
|
||||
obj-$(CONFIG_PINCTRL_EXYNOS5440) += pinctrl-exynos5440.o
|
||||
obj-$(CONFIG_PINCTRL_S3C24XX) += pinctrl-s3c24xx.o
|
||||
obj-$(CONFIG_PINCTRL_S3C64XX) += pinctrl-s3c64xx.o
|
@ -33,6 +33,18 @@
|
||||
#include "pinctrl-samsung.h"
|
||||
#include "pinctrl-exynos.h"
|
||||
|
||||
struct exynos_irq_chip {
|
||||
struct irq_chip chip;
|
||||
|
||||
u32 eint_con;
|
||||
u32 eint_mask;
|
||||
u32 eint_pend;
|
||||
};
|
||||
|
||||
static inline struct exynos_irq_chip *to_exynos_irq_chip(struct irq_chip *chip)
|
||||
{
|
||||
return container_of(chip, struct exynos_irq_chip, chip);
|
||||
}
|
||||
|
||||
static struct samsung_pin_bank_type bank_type_off = {
|
||||
.fld_width = { 4, 1, 2, 2, 2, 2, },
|
||||
@ -50,11 +62,13 @@ static const struct of_device_id exynos_wkup_irq_ids[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static void exynos_gpio_irq_mask(struct irq_data *irqd)
|
||||
static void exynos_irq_mask(struct irq_data *irqd)
|
||||
{
|
||||
struct irq_chip *chip = irq_data_get_irq_chip(irqd);
|
||||
struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
|
||||
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
|
||||
struct samsung_pinctrl_drv_data *d = bank->drvdata;
|
||||
unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
|
||||
unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
|
||||
unsigned long mask;
|
||||
unsigned long flags;
|
||||
|
||||
@ -67,20 +81,24 @@ static void exynos_gpio_irq_mask(struct irq_data *irqd)
|
||||
spin_unlock_irqrestore(&bank->slock, flags);
|
||||
}
|
||||
|
||||
static void exynos_gpio_irq_ack(struct irq_data *irqd)
|
||||
static void exynos_irq_ack(struct irq_data *irqd)
|
||||
{
|
||||
struct irq_chip *chip = irq_data_get_irq_chip(irqd);
|
||||
struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
|
||||
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
|
||||
struct samsung_pinctrl_drv_data *d = bank->drvdata;
|
||||
unsigned long reg_pend = d->ctrl->geint_pend + bank->eint_offset;
|
||||
unsigned long reg_pend = our_chip->eint_pend + bank->eint_offset;
|
||||
|
||||
writel(1 << irqd->hwirq, d->virt_base + reg_pend);
|
||||
}
|
||||
|
||||
static void exynos_gpio_irq_unmask(struct irq_data *irqd)
|
||||
static void exynos_irq_unmask(struct irq_data *irqd)
|
||||
{
|
||||
struct irq_chip *chip = irq_data_get_irq_chip(irqd);
|
||||
struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
|
||||
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
|
||||
struct samsung_pinctrl_drv_data *d = bank->drvdata;
|
||||
unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
|
||||
unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
|
||||
unsigned long mask;
|
||||
unsigned long flags;
|
||||
|
||||
@ -93,7 +111,7 @@ static void exynos_gpio_irq_unmask(struct irq_data *irqd)
|
||||
* masked.
|
||||
*/
|
||||
if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK)
|
||||
exynos_gpio_irq_ack(irqd);
|
||||
exynos_irq_ack(irqd);
|
||||
|
||||
spin_lock_irqsave(&bank->slock, flags);
|
||||
|
||||
@ -104,16 +122,17 @@ static void exynos_gpio_irq_unmask(struct irq_data *irqd)
|
||||
spin_unlock_irqrestore(&bank->slock, flags);
|
||||
}
|
||||
|
||||
static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
|
||||
static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
|
||||
{
|
||||
struct irq_chip *chip = irq_data_get_irq_chip(irqd);
|
||||
struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
|
||||
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
|
||||
struct samsung_pin_bank_type *bank_type = bank->type;
|
||||
struct samsung_pinctrl_drv_data *d = bank->drvdata;
|
||||
struct samsung_pin_ctrl *ctrl = d->ctrl;
|
||||
unsigned int pin = irqd->hwirq;
|
||||
unsigned int shift = EXYNOS_EINT_CON_LEN * pin;
|
||||
unsigned int con, trig_type;
|
||||
unsigned long reg_con = ctrl->geint_con + bank->eint_offset;
|
||||
unsigned long reg_con = our_chip->eint_con + bank->eint_offset;
|
||||
unsigned long flags;
|
||||
unsigned int mask;
|
||||
|
||||
@ -167,12 +186,17 @@ static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
|
||||
/*
|
||||
* irq_chip for gpio interrupts.
|
||||
*/
|
||||
static struct irq_chip exynos_gpio_irq_chip = {
|
||||
.name = "exynos_gpio_irq_chip",
|
||||
.irq_unmask = exynos_gpio_irq_unmask,
|
||||
.irq_mask = exynos_gpio_irq_mask,
|
||||
.irq_ack = exynos_gpio_irq_ack,
|
||||
.irq_set_type = exynos_gpio_irq_set_type,
|
||||
static struct exynos_irq_chip exynos_gpio_irq_chip = {
|
||||
.chip = {
|
||||
.name = "exynos_gpio_irq_chip",
|
||||
.irq_unmask = exynos_irq_unmask,
|
||||
.irq_mask = exynos_irq_mask,
|
||||
.irq_ack = exynos_irq_ack,
|
||||
.irq_set_type = exynos_irq_set_type,
|
||||
},
|
||||
.eint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.eint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.eint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
};
|
||||
|
||||
static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq,
|
||||
@ -181,7 +205,7 @@ static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq,
|
||||
struct samsung_pin_bank *b = h->host_data;
|
||||
|
||||
irq_set_chip_data(virq, b);
|
||||
irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip,
|
||||
irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip.chip,
|
||||
handle_level_irq);
|
||||
set_irq_flags(virq, IRQF_VALID);
|
||||
return 0;
|
||||
@ -202,7 +226,7 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
|
||||
struct samsung_pin_bank *bank = ctrl->pin_banks;
|
||||
unsigned int svc, group, pin, virq;
|
||||
|
||||
svc = readl(d->virt_base + ctrl->svc);
|
||||
svc = readl(d->virt_base + EXYNOS_SVC_OFFSET);
|
||||
group = EXYNOS_SVC_GROUP(svc);
|
||||
pin = svc & EXYNOS_SVC_NUM_MASK;
|
||||
|
||||
@ -279,119 +303,6 @@ err_domains:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void exynos_wkup_irq_mask(struct irq_data *irqd)
|
||||
{
|
||||
struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
|
||||
struct samsung_pinctrl_drv_data *d = b->drvdata;
|
||||
unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
|
||||
unsigned long mask;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&b->slock, flags);
|
||||
|
||||
mask = readl(d->virt_base + reg_mask);
|
||||
mask |= 1 << irqd->hwirq;
|
||||
writel(mask, d->virt_base + reg_mask);
|
||||
|
||||
spin_unlock_irqrestore(&b->slock, flags);
|
||||
}
|
||||
|
||||
static void exynos_wkup_irq_ack(struct irq_data *irqd)
|
||||
{
|
||||
struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
|
||||
struct samsung_pinctrl_drv_data *d = b->drvdata;
|
||||
unsigned long pend = d->ctrl->weint_pend + b->eint_offset;
|
||||
|
||||
writel(1 << irqd->hwirq, d->virt_base + pend);
|
||||
}
|
||||
|
||||
static void exynos_wkup_irq_unmask(struct irq_data *irqd)
|
||||
{
|
||||
struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
|
||||
struct samsung_pinctrl_drv_data *d = b->drvdata;
|
||||
unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
|
||||
unsigned long mask;
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* Ack level interrupts right before unmask
|
||||
*
|
||||
* If we don't do this we'll get a double-interrupt. Level triggered
|
||||
* interrupts must not fire an interrupt if the level is not
|
||||
* _currently_ active, even if it was active while the interrupt was
|
||||
* masked.
|
||||
*/
|
||||
if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK)
|
||||
exynos_wkup_irq_ack(irqd);
|
||||
|
||||
spin_lock_irqsave(&b->slock, flags);
|
||||
|
||||
mask = readl(d->virt_base + reg_mask);
|
||||
mask &= ~(1 << irqd->hwirq);
|
||||
writel(mask, d->virt_base + reg_mask);
|
||||
|
||||
spin_unlock_irqrestore(&b->slock, flags);
|
||||
}
|
||||
|
||||
static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
|
||||
{
|
||||
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
|
||||
struct samsung_pin_bank_type *bank_type = bank->type;
|
||||
struct samsung_pinctrl_drv_data *d = bank->drvdata;
|
||||
unsigned int pin = irqd->hwirq;
|
||||
unsigned long reg_con = d->ctrl->weint_con + bank->eint_offset;
|
||||
unsigned long shift = EXYNOS_EINT_CON_LEN * pin;
|
||||
unsigned long con, trig_type;
|
||||
unsigned long flags;
|
||||
unsigned int mask;
|
||||
|
||||
switch (type) {
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
trig_type = EXYNOS_EINT_EDGE_RISING;
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
trig_type = EXYNOS_EINT_EDGE_FALLING;
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
trig_type = EXYNOS_EINT_EDGE_BOTH;
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
trig_type = EXYNOS_EINT_LEVEL_HIGH;
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
trig_type = EXYNOS_EINT_LEVEL_LOW;
|
||||
break;
|
||||
default:
|
||||
pr_err("unsupported external interrupt type\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (type & IRQ_TYPE_EDGE_BOTH)
|
||||
__irq_set_handler_locked(irqd->irq, handle_edge_irq);
|
||||
else
|
||||
__irq_set_handler_locked(irqd->irq, handle_level_irq);
|
||||
|
||||
con = readl(d->virt_base + reg_con);
|
||||
con &= ~(EXYNOS_EINT_CON_MASK << shift);
|
||||
con |= trig_type << shift;
|
||||
writel(con, d->virt_base + reg_con);
|
||||
|
||||
reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC];
|
||||
shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC];
|
||||
mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
|
||||
|
||||
spin_lock_irqsave(&bank->slock, flags);
|
||||
|
||||
con = readl(d->virt_base + reg_con);
|
||||
con &= ~(mask << shift);
|
||||
con |= EXYNOS_EINT_FUNC << shift;
|
||||
writel(con, d->virt_base + reg_con);
|
||||
|
||||
spin_unlock_irqrestore(&bank->slock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 exynos_eint_wake_mask = 0xffffffff;
|
||||
|
||||
u32 exynos_get_eint_wake_mask(void)
|
||||
@ -417,13 +328,18 @@ static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on)
|
||||
/*
|
||||
* irq_chip for wakeup interrupts
|
||||
*/
|
||||
static struct irq_chip exynos_wkup_irq_chip = {
|
||||
.name = "exynos_wkup_irq_chip",
|
||||
.irq_unmask = exynos_wkup_irq_unmask,
|
||||
.irq_mask = exynos_wkup_irq_mask,
|
||||
.irq_ack = exynos_wkup_irq_ack,
|
||||
.irq_set_type = exynos_wkup_irq_set_type,
|
||||
.irq_set_wake = exynos_wkup_irq_set_wake,
|
||||
static struct exynos_irq_chip exynos_wkup_irq_chip = {
|
||||
.chip = {
|
||||
.name = "exynos_wkup_irq_chip",
|
||||
.irq_unmask = exynos_irq_unmask,
|
||||
.irq_mask = exynos_irq_mask,
|
||||
.irq_ack = exynos_irq_ack,
|
||||
.irq_set_type = exynos_irq_set_type,
|
||||
.irq_set_wake = exynos_wkup_irq_set_wake,
|
||||
},
|
||||
.eint_con = EXYNOS_WKUP_ECON_OFFSET,
|
||||
.eint_mask = EXYNOS_WKUP_EMASK_OFFSET,
|
||||
.eint_pend = EXYNOS_WKUP_EPEND_OFFSET,
|
||||
};
|
||||
|
||||
/* interrupt handler for wakeup interrupts 0..15 */
|
||||
@ -464,7 +380,6 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
|
||||
struct irq_chip *chip = irq_get_chip(irq);
|
||||
struct exynos_muxed_weint_data *eintd = irq_get_handler_data(irq);
|
||||
struct samsung_pinctrl_drv_data *d = eintd->banks[0]->drvdata;
|
||||
struct samsung_pin_ctrl *ctrl = d->ctrl;
|
||||
unsigned long pend;
|
||||
unsigned long mask;
|
||||
int i;
|
||||
@ -473,8 +388,10 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
|
||||
|
||||
for (i = 0; i < eintd->nr_banks; ++i) {
|
||||
struct samsung_pin_bank *b = eintd->banks[i];
|
||||
pend = readl(d->virt_base + ctrl->weint_pend + b->eint_offset);
|
||||
mask = readl(d->virt_base + ctrl->weint_mask + b->eint_offset);
|
||||
pend = readl(d->virt_base + EXYNOS_WKUP_EPEND_OFFSET
|
||||
+ b->eint_offset);
|
||||
mask = readl(d->virt_base + EXYNOS_WKUP_EMASK_OFFSET
|
||||
+ b->eint_offset);
|
||||
exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
|
||||
}
|
||||
|
||||
@ -484,7 +401,8 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
|
||||
static int exynos_wkup_irq_map(struct irq_domain *h, unsigned int virq,
|
||||
irq_hw_number_t hw)
|
||||
{
|
||||
irq_set_chip_and_handler(virq, &exynos_wkup_irq_chip, handle_level_irq);
|
||||
irq_set_chip_and_handler(virq, &exynos_wkup_irq_chip.chip,
|
||||
handle_level_irq);
|
||||
irq_set_chip_data(virq, h->host_data);
|
||||
set_irq_flags(virq, IRQF_VALID);
|
||||
return 0;
|
||||
@ -703,13 +621,6 @@ struct samsung_pin_ctrl s5pv210_pin_ctrl[] = {
|
||||
/* pin-controller instance 0 data */
|
||||
.pin_banks = s5pv210_pin_bank,
|
||||
.nr_banks = ARRAY_SIZE(s5pv210_pin_bank),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.weint_con = EXYNOS_WKUP_ECON_OFFSET,
|
||||
.weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
|
||||
.weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.eint_wkup_init = exynos_eint_wkup_init,
|
||||
.suspend = exynos_pinctrl_suspend,
|
||||
@ -758,10 +669,6 @@ struct samsung_pin_ctrl exynos3250_pin_ctrl[] = {
|
||||
/* pin-controller instance 0 data */
|
||||
.pin_banks = exynos3250_pin_banks0,
|
||||
.nr_banks = ARRAY_SIZE(exynos3250_pin_banks0),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.suspend = exynos_pinctrl_suspend,
|
||||
.resume = exynos_pinctrl_resume,
|
||||
@ -770,13 +677,6 @@ struct samsung_pin_ctrl exynos3250_pin_ctrl[] = {
|
||||
/* pin-controller instance 1 data */
|
||||
.pin_banks = exynos3250_pin_banks1,
|
||||
.nr_banks = ARRAY_SIZE(exynos3250_pin_banks1),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.weint_con = EXYNOS_WKUP_ECON_OFFSET,
|
||||
.weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
|
||||
.weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.eint_wkup_init = exynos_eint_wkup_init,
|
||||
.suspend = exynos_pinctrl_suspend,
|
||||
@ -843,10 +743,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
|
||||
/* pin-controller instance 0 data */
|
||||
.pin_banks = exynos4210_pin_banks0,
|
||||
.nr_banks = ARRAY_SIZE(exynos4210_pin_banks0),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.suspend = exynos_pinctrl_suspend,
|
||||
.resume = exynos_pinctrl_resume,
|
||||
@ -855,13 +751,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
|
||||
/* pin-controller instance 1 data */
|
||||
.pin_banks = exynos4210_pin_banks1,
|
||||
.nr_banks = ARRAY_SIZE(exynos4210_pin_banks1),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.weint_con = EXYNOS_WKUP_ECON_OFFSET,
|
||||
.weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
|
||||
.weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.eint_wkup_init = exynos_eint_wkup_init,
|
||||
.suspend = exynos_pinctrl_suspend,
|
||||
@ -942,10 +831,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
|
||||
/* pin-controller instance 0 data */
|
||||
.pin_banks = exynos4x12_pin_banks0,
|
||||
.nr_banks = ARRAY_SIZE(exynos4x12_pin_banks0),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.suspend = exynos_pinctrl_suspend,
|
||||
.resume = exynos_pinctrl_resume,
|
||||
@ -954,13 +839,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
|
||||
/* pin-controller instance 1 data */
|
||||
.pin_banks = exynos4x12_pin_banks1,
|
||||
.nr_banks = ARRAY_SIZE(exynos4x12_pin_banks1),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.weint_con = EXYNOS_WKUP_ECON_OFFSET,
|
||||
.weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
|
||||
.weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.eint_wkup_init = exynos_eint_wkup_init,
|
||||
.suspend = exynos_pinctrl_suspend,
|
||||
@ -970,10 +848,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
|
||||
/* pin-controller instance 2 data */
|
||||
.pin_banks = exynos4x12_pin_banks2,
|
||||
.nr_banks = ARRAY_SIZE(exynos4x12_pin_banks2),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.suspend = exynos_pinctrl_suspend,
|
||||
.resume = exynos_pinctrl_resume,
|
||||
@ -982,10 +856,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
|
||||
/* pin-controller instance 3 data */
|
||||
.pin_banks = exynos4x12_pin_banks3,
|
||||
.nr_banks = ARRAY_SIZE(exynos4x12_pin_banks3),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.suspend = exynos_pinctrl_suspend,
|
||||
.resume = exynos_pinctrl_resume,
|
||||
@ -1058,13 +928,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
|
||||
/* pin-controller instance 0 data */
|
||||
.pin_banks = exynos5250_pin_banks0,
|
||||
.nr_banks = ARRAY_SIZE(exynos5250_pin_banks0),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.weint_con = EXYNOS_WKUP_ECON_OFFSET,
|
||||
.weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
|
||||
.weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.eint_wkup_init = exynos_eint_wkup_init,
|
||||
.suspend = exynos_pinctrl_suspend,
|
||||
@ -1074,10 +937,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
|
||||
/* pin-controller instance 1 data */
|
||||
.pin_banks = exynos5250_pin_banks1,
|
||||
.nr_banks = ARRAY_SIZE(exynos5250_pin_banks1),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.suspend = exynos_pinctrl_suspend,
|
||||
.resume = exynos_pinctrl_resume,
|
||||
@ -1086,10 +945,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
|
||||
/* pin-controller instance 2 data */
|
||||
.pin_banks = exynos5250_pin_banks2,
|
||||
.nr_banks = ARRAY_SIZE(exynos5250_pin_banks2),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.suspend = exynos_pinctrl_suspend,
|
||||
.resume = exynos_pinctrl_resume,
|
||||
@ -1098,10 +953,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
|
||||
/* pin-controller instance 3 data */
|
||||
.pin_banks = exynos5250_pin_banks3,
|
||||
.nr_banks = ARRAY_SIZE(exynos5250_pin_banks3),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.suspend = exynos_pinctrl_suspend,
|
||||
.resume = exynos_pinctrl_resume,
|
||||
@ -1158,13 +1009,6 @@ struct samsung_pin_ctrl exynos5260_pin_ctrl[] = {
|
||||
/* pin-controller instance 0 data */
|
||||
.pin_banks = exynos5260_pin_banks0,
|
||||
.nr_banks = ARRAY_SIZE(exynos5260_pin_banks0),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.weint_con = EXYNOS_WKUP_ECON_OFFSET,
|
||||
.weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
|
||||
.weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.eint_wkup_init = exynos_eint_wkup_init,
|
||||
.label = "exynos5260-gpio-ctrl0",
|
||||
@ -1172,20 +1016,12 @@ struct samsung_pin_ctrl exynos5260_pin_ctrl[] = {
|
||||
/* pin-controller instance 1 data */
|
||||
.pin_banks = exynos5260_pin_banks1,
|
||||
.nr_banks = ARRAY_SIZE(exynos5260_pin_banks1),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.label = "exynos5260-gpio-ctrl1",
|
||||
}, {
|
||||
/* pin-controller instance 2 data */
|
||||
.pin_banks = exynos5260_pin_banks2,
|
||||
.nr_banks = ARRAY_SIZE(exynos5260_pin_banks2),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.label = "exynos5260-gpio-ctrl2",
|
||||
},
|
||||
@ -1256,13 +1092,6 @@ struct samsung_pin_ctrl exynos5420_pin_ctrl[] = {
|
||||
/* pin-controller instance 0 data */
|
||||
.pin_banks = exynos5420_pin_banks0,
|
||||
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks0),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.weint_con = EXYNOS_WKUP_ECON_OFFSET,
|
||||
.weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
|
||||
.weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.eint_wkup_init = exynos_eint_wkup_init,
|
||||
.label = "exynos5420-gpio-ctrl0",
|
||||
@ -1270,40 +1099,24 @@ struct samsung_pin_ctrl exynos5420_pin_ctrl[] = {
|
||||
/* pin-controller instance 1 data */
|
||||
.pin_banks = exynos5420_pin_banks1,
|
||||
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks1),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.label = "exynos5420-gpio-ctrl1",
|
||||
}, {
|
||||
/* pin-controller instance 2 data */
|
||||
.pin_banks = exynos5420_pin_banks2,
|
||||
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks2),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.label = "exynos5420-gpio-ctrl2",
|
||||
}, {
|
||||
/* pin-controller instance 3 data */
|
||||
.pin_banks = exynos5420_pin_banks3,
|
||||
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks3),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.label = "exynos5420-gpio-ctrl3",
|
||||
}, {
|
||||
/* pin-controller instance 4 data */
|
||||
.pin_banks = exynos5420_pin_banks4,
|
||||
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks4),
|
||||
.geint_con = EXYNOS_GPIO_ECON_OFFSET,
|
||||
.geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
|
||||
.geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
|
||||
.svc = EXYNOS_SVC_OFFSET,
|
||||
.eint_gpio_init = exynos_eint_gpio_init,
|
||||
.label = "exynos5420-gpio-ctrl4",
|
||||
},
|
@ -23,7 +23,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include "core.h"
|
||||
#include "../core.h"
|
||||
|
||||
/* EXYNOS5440 GPIO and Pinctrl register offsets */
|
||||
#define GPIO_MUX 0x00
|
||||
@ -371,13 +371,6 @@ static int exynos5440_pinmux_enable(struct pinctrl_dev *pctldev, unsigned select
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* disable a specified pinmux by writing to registers */
|
||||
static void exynos5440_pinmux_disable(struct pinctrl_dev *pctldev,
|
||||
unsigned selector, unsigned group)
|
||||
{
|
||||
exynos5440_pinmux_setup(pctldev, selector, group, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* The calls to gpio_direction_output() and gpio_direction_input()
|
||||
* leads to this function call (via the pinctrl_gpio_direction_{input|output}()
|
||||
@ -395,7 +388,6 @@ static const struct pinmux_ops exynos5440_pinmux_ops = {
|
||||
.get_function_name = exynos5440_pinmux_get_fname,
|
||||
.get_function_groups = exynos5440_pinmux_get_groups,
|
||||
.enable = exynos5440_pinmux_enable,
|
||||
.disable = exynos5440_pinmux_disable,
|
||||
.gpio_set_direction = exynos5440_pinmux_gpio_set_direction,
|
||||
};
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "../core.h"
|
||||
#include "pinctrl-samsung.h"
|
||||
|
||||
#define GROUP_SUFFIX "-grp"
|
||||
@ -40,13 +40,14 @@
|
||||
|
||||
/* list of all possible config options supported */
|
||||
static struct pin_config {
|
||||
char *prop_cfg;
|
||||
unsigned int cfg_type;
|
||||
} pcfgs[] = {
|
||||
const char *property;
|
||||
enum pincfg_type param;
|
||||
} cfg_params[] = {
|
||||
{ "samsung,pin-pud", PINCFG_TYPE_PUD },
|
||||
{ "samsung,pin-drv", PINCFG_TYPE_DRV },
|
||||
{ "samsung,pin-con-pdn", PINCFG_TYPE_CON_PDN },
|
||||
{ "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN },
|
||||
{ "samsung,pin-val", PINCFG_TYPE_DAT },
|
||||
};
|
||||
|
||||
/* Global list of devices (struct samsung_pinctrl_drv_data) */
|
||||
@ -59,165 +60,244 @@ static inline struct samsung_pin_bank *gc_to_pin_bank(struct gpio_chip *gc)
|
||||
return container_of(gc, struct samsung_pin_bank, gpio_chip);
|
||||
}
|
||||
|
||||
/* check if the selector is a valid pin group selector */
|
||||
static int samsung_get_group_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
struct samsung_pinctrl_drv_data *drvdata;
|
||||
struct samsung_pinctrl_drv_data *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
drvdata = pinctrl_dev_get_drvdata(pctldev);
|
||||
return drvdata->nr_groups;
|
||||
return pmx->nr_groups;
|
||||
}
|
||||
|
||||
/* return the name of the group selected by the group selector */
|
||||
static const char *samsung_get_group_name(struct pinctrl_dev *pctldev,
|
||||
unsigned selector)
|
||||
unsigned group)
|
||||
{
|
||||
struct samsung_pinctrl_drv_data *drvdata;
|
||||
struct samsung_pinctrl_drv_data *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
drvdata = pinctrl_dev_get_drvdata(pctldev);
|
||||
return drvdata->pin_groups[selector].name;
|
||||
return pmx->pin_groups[group].name;
|
||||
}
|
||||
|
||||
/* return the pin numbers associated with the specified group */
|
||||
static int samsung_get_group_pins(struct pinctrl_dev *pctldev,
|
||||
unsigned selector, const unsigned **pins, unsigned *num_pins)
|
||||
unsigned group,
|
||||
const unsigned **pins,
|
||||
unsigned *num_pins)
|
||||
{
|
||||
struct samsung_pinctrl_drv_data *drvdata;
|
||||
struct samsung_pinctrl_drv_data *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
*pins = pmx->pin_groups[group].pins;
|
||||
*num_pins = pmx->pin_groups[group].num_pins;
|
||||
|
||||
drvdata = pinctrl_dev_get_drvdata(pctldev);
|
||||
*pins = drvdata->pin_groups[selector].pins;
|
||||
*num_pins = drvdata->pin_groups[selector].num_pins;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* create pinctrl_map entries by parsing device tree nodes */
|
||||
static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev,
|
||||
struct device_node *np, struct pinctrl_map **maps,
|
||||
unsigned *nmaps)
|
||||
static int reserve_map(struct device *dev, struct pinctrl_map **map,
|
||||
unsigned *reserved_maps, unsigned *num_maps,
|
||||
unsigned reserve)
|
||||
{
|
||||
struct device *dev = pctldev->dev;
|
||||
struct pinctrl_map *map;
|
||||
unsigned long *cfg = NULL;
|
||||
char *gname, *fname;
|
||||
int cfg_cnt = 0, map_cnt = 0, idx = 0;
|
||||
unsigned old_num = *reserved_maps;
|
||||
unsigned new_num = *num_maps + reserve;
|
||||
struct pinctrl_map *new_map;
|
||||
|
||||
/* count the number of config options specfied in the node */
|
||||
for (idx = 0; idx < ARRAY_SIZE(pcfgs); idx++) {
|
||||
if (of_find_property(np, pcfgs[idx].prop_cfg, NULL))
|
||||
cfg_cnt++;
|
||||
}
|
||||
if (old_num >= new_num)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Find out the number of map entries to create. All the config options
|
||||
* can be accomadated into a single config map entry.
|
||||
*/
|
||||
if (cfg_cnt)
|
||||
map_cnt = 1;
|
||||
if (of_find_property(np, "samsung,pin-function", NULL))
|
||||
map_cnt++;
|
||||
if (!map_cnt) {
|
||||
dev_err(dev, "node %s does not have either config or function "
|
||||
"configurations\n", np->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Allocate memory for pin-map entries */
|
||||
map = kzalloc(sizeof(*map) * map_cnt, GFP_KERNEL);
|
||||
if (!map) {
|
||||
dev_err(dev, "could not alloc memory for pin-maps\n");
|
||||
new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL);
|
||||
if (!new_map) {
|
||||
dev_err(dev, "krealloc(map) failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
*nmaps = 0;
|
||||
|
||||
/*
|
||||
* Allocate memory for pin group name. The pin group name is derived
|
||||
* from the node name from which these map entries are be created.
|
||||
*/
|
||||
gname = kzalloc(strlen(np->name) + GSUFFIX_LEN, GFP_KERNEL);
|
||||
if (!gname) {
|
||||
dev_err(dev, "failed to alloc memory for group name\n");
|
||||
goto free_map;
|
||||
}
|
||||
sprintf(gname, "%s%s", np->name, GROUP_SUFFIX);
|
||||
memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));
|
||||
|
||||
/*
|
||||
* don't have config options? then skip over to creating function
|
||||
* map entries.
|
||||
*/
|
||||
if (!cfg_cnt)
|
||||
goto skip_cfgs;
|
||||
*map = new_map;
|
||||
*reserved_maps = new_num;
|
||||
|
||||
/* Allocate memory for config entries */
|
||||
cfg = kzalloc(sizeof(*cfg) * cfg_cnt, GFP_KERNEL);
|
||||
if (!cfg) {
|
||||
dev_err(dev, "failed to alloc memory for configs\n");
|
||||
goto free_gname;
|
||||
}
|
||||
|
||||
/* Prepare a list of config settings */
|
||||
for (idx = 0, cfg_cnt = 0; idx < ARRAY_SIZE(pcfgs); idx++) {
|
||||
u32 value;
|
||||
if (!of_property_read_u32(np, pcfgs[idx].prop_cfg, &value))
|
||||
cfg[cfg_cnt++] =
|
||||
PINCFG_PACK(pcfgs[idx].cfg_type, value);
|
||||
}
|
||||
|
||||
/* create the config map entry */
|
||||
map[*nmaps].data.configs.group_or_pin = gname;
|
||||
map[*nmaps].data.configs.configs = cfg;
|
||||
map[*nmaps].data.configs.num_configs = cfg_cnt;
|
||||
map[*nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
|
||||
*nmaps += 1;
|
||||
|
||||
skip_cfgs:
|
||||
/* create the function map entry */
|
||||
if (of_find_property(np, "samsung,pin-function", NULL)) {
|
||||
fname = kzalloc(strlen(np->name) + FSUFFIX_LEN, GFP_KERNEL);
|
||||
if (!fname) {
|
||||
dev_err(dev, "failed to alloc memory for func name\n");
|
||||
goto free_cfg;
|
||||
}
|
||||
sprintf(fname, "%s%s", np->name, FUNCTION_SUFFIX);
|
||||
|
||||
map[*nmaps].data.mux.group = gname;
|
||||
map[*nmaps].data.mux.function = fname;
|
||||
map[*nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
|
||||
*nmaps += 1;
|
||||
}
|
||||
|
||||
*maps = map;
|
||||
return 0;
|
||||
|
||||
free_cfg:
|
||||
kfree(cfg);
|
||||
free_gname:
|
||||
kfree(gname);
|
||||
free_map:
|
||||
kfree(map);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* free the memory allocated to hold the pin-map table */
|
||||
static void samsung_dt_free_map(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_map *map, unsigned num_maps)
|
||||
static int add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps,
|
||||
unsigned *num_maps, const char *group,
|
||||
const char *function)
|
||||
{
|
||||
int idx;
|
||||
if (WARN_ON(*num_maps == *reserved_maps))
|
||||
return -ENOSPC;
|
||||
|
||||
for (idx = 0; idx < num_maps; idx++) {
|
||||
if (map[idx].type == PIN_MAP_TYPE_MUX_GROUP) {
|
||||
kfree(map[idx].data.mux.function);
|
||||
if (!idx)
|
||||
kfree(map[idx].data.mux.group);
|
||||
} else if (map->type == PIN_MAP_TYPE_CONFIGS_GROUP) {
|
||||
kfree(map[idx].data.configs.configs);
|
||||
if (!idx)
|
||||
kfree(map[idx].data.configs.group_or_pin);
|
||||
}
|
||||
};
|
||||
(*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
|
||||
(*map)[*num_maps].data.mux.group = group;
|
||||
(*map)[*num_maps].data.mux.function = function;
|
||||
(*num_maps)++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_map_configs(struct device *dev, struct pinctrl_map **map,
|
||||
unsigned *reserved_maps, unsigned *num_maps,
|
||||
const char *group, unsigned long *configs,
|
||||
unsigned num_configs)
|
||||
{
|
||||
unsigned long *dup_configs;
|
||||
|
||||
if (WARN_ON(*num_maps == *reserved_maps))
|
||||
return -ENOSPC;
|
||||
|
||||
dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs),
|
||||
GFP_KERNEL);
|
||||
if (!dup_configs) {
|
||||
dev_err(dev, "kmemdup(configs) failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
(*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
|
||||
(*map)[*num_maps].data.configs.group_or_pin = group;
|
||||
(*map)[*num_maps].data.configs.configs = dup_configs;
|
||||
(*map)[*num_maps].data.configs.num_configs = num_configs;
|
||||
(*num_maps)++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_config(struct device *dev, unsigned long **configs,
|
||||
unsigned *num_configs, unsigned long config)
|
||||
{
|
||||
unsigned old_num = *num_configs;
|
||||
unsigned new_num = old_num + 1;
|
||||
unsigned long *new_configs;
|
||||
|
||||
new_configs = krealloc(*configs, sizeof(*new_configs) * new_num,
|
||||
GFP_KERNEL);
|
||||
if (!new_configs) {
|
||||
dev_err(dev, "krealloc(configs) failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
new_configs[old_num] = config;
|
||||
|
||||
*configs = new_configs;
|
||||
*num_configs = new_num;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void samsung_dt_free_map(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_map *map,
|
||||
unsigned num_maps)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_maps; i++)
|
||||
if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
|
||||
kfree(map[i].data.configs.configs);
|
||||
|
||||
kfree(map);
|
||||
}
|
||||
|
||||
static int samsung_dt_subnode_to_map(struct samsung_pinctrl_drv_data *drvdata,
|
||||
struct device *dev,
|
||||
struct device_node *np,
|
||||
struct pinctrl_map **map,
|
||||
unsigned *reserved_maps,
|
||||
unsigned *num_maps)
|
||||
{
|
||||
int ret, i;
|
||||
u32 val;
|
||||
unsigned long config;
|
||||
unsigned long *configs = NULL;
|
||||
unsigned num_configs = 0;
|
||||
unsigned reserve;
|
||||
struct property *prop;
|
||||
const char *group;
|
||||
bool has_func = false;
|
||||
|
||||
ret = of_property_read_u32(np, "samsung,pin-function", &val);
|
||||
if (!ret)
|
||||
has_func = true;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
|
||||
ret = of_property_read_u32(np, cfg_params[i].property, &val);
|
||||
if (!ret) {
|
||||
config = PINCFG_PACK(cfg_params[i].param, val);
|
||||
ret = add_config(dev, &configs, &num_configs, config);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
/* EINVAL=missing, which is fine since it's optional */
|
||||
} else if (ret != -EINVAL) {
|
||||
dev_err(dev, "could not parse property %s\n",
|
||||
cfg_params[i].property);
|
||||
}
|
||||
}
|
||||
|
||||
reserve = 0;
|
||||
if (has_func)
|
||||
reserve++;
|
||||
if (num_configs)
|
||||
reserve++;
|
||||
ret = of_property_count_strings(np, "samsung,pins");
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "could not parse property samsung,pins\n");
|
||||
goto exit;
|
||||
}
|
||||
reserve *= ret;
|
||||
|
||||
ret = reserve_map(dev, map, reserved_maps, num_maps, reserve);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
of_property_for_each_string(np, "samsung,pins", prop, group) {
|
||||
if (has_func) {
|
||||
ret = add_map_mux(map, reserved_maps,
|
||||
num_maps, group, np->full_name);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (num_configs) {
|
||||
ret = add_map_configs(dev, map, reserved_maps,
|
||||
num_maps, group, configs,
|
||||
num_configs);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
kfree(configs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev,
|
||||
struct device_node *np_config,
|
||||
struct pinctrl_map **map,
|
||||
unsigned *num_maps)
|
||||
{
|
||||
struct samsung_pinctrl_drv_data *drvdata;
|
||||
unsigned reserved_maps;
|
||||
struct device_node *np;
|
||||
int ret;
|
||||
|
||||
drvdata = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
reserved_maps = 0;
|
||||
*map = NULL;
|
||||
*num_maps = 0;
|
||||
|
||||
if (!of_get_child_count(np_config))
|
||||
return samsung_dt_subnode_to_map(drvdata, pctldev->dev,
|
||||
np_config, map,
|
||||
&reserved_maps,
|
||||
num_maps);
|
||||
|
||||
for_each_child_of_node(np_config, np) {
|
||||
ret = samsung_dt_subnode_to_map(drvdata, pctldev->dev, np, map,
|
||||
&reserved_maps, num_maps);
|
||||
if (ret < 0) {
|
||||
samsung_dt_free_map(pctldev, *map, *num_maps);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* list of pinctrl callbacks for the pinctrl core */
|
||||
static const struct pinctrl_ops samsung_pctrl_ops = {
|
||||
.get_groups_count = samsung_get_group_count,
|
||||
@ -286,83 +366,21 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
unsigned group, bool enable)
|
||||
{
|
||||
struct samsung_pinctrl_drv_data *drvdata;
|
||||
const unsigned int *pins;
|
||||
struct samsung_pin_bank *bank;
|
||||
void __iomem *reg;
|
||||
u32 mask, shift, data, pin_offset, cnt;
|
||||
unsigned long flags;
|
||||
|
||||
drvdata = pinctrl_dev_get_drvdata(pctldev);
|
||||
pins = drvdata->pin_groups[group].pins;
|
||||
|
||||
/*
|
||||
* for each pin in the pin group selected, program the correspoding pin
|
||||
* pin function number in the config register.
|
||||
*/
|
||||
for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) {
|
||||
struct samsung_pin_bank_type *type;
|
||||
|
||||
pin_to_reg_bank(drvdata, pins[cnt] - drvdata->ctrl->base,
|
||||
®, &pin_offset, &bank);
|
||||
type = bank->type;
|
||||
mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1;
|
||||
shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC];
|
||||
if (shift >= 32) {
|
||||
/* Some banks have two config registers */
|
||||
shift -= 32;
|
||||
reg += 4;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&bank->slock, flags);
|
||||
|
||||
data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]);
|
||||
data &= ~(mask << shift);
|
||||
if (enable)
|
||||
data |= drvdata->pin_groups[group].func << shift;
|
||||
writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]);
|
||||
|
||||
spin_unlock_irqrestore(&bank->slock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/* enable a specified pinmux by writing to registers */
|
||||
static int samsung_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
unsigned group)
|
||||
{
|
||||
samsung_pinmux_setup(pctldev, selector, group, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* disable a specified pinmux by writing to registers */
|
||||
static void samsung_pinmux_disable(struct pinctrl_dev *pctldev,
|
||||
unsigned selector, unsigned group)
|
||||
{
|
||||
samsung_pinmux_setup(pctldev, selector, group, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* The calls to gpio_direction_output() and gpio_direction_input()
|
||||
* leads to this function call (via the pinctrl_gpio_direction_{input|output}()
|
||||
* function called from the gpiolib interface).
|
||||
*/
|
||||
static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range, unsigned offset, bool input)
|
||||
{
|
||||
struct samsung_pin_bank_type *type;
|
||||
struct samsung_pin_bank *bank;
|
||||
struct samsung_pinctrl_drv_data *drvdata;
|
||||
void __iomem *reg;
|
||||
u32 data, pin_offset, mask, shift;
|
||||
u32 mask, shift, data, pin_offset;
|
||||
unsigned long flags;
|
||||
const struct samsung_pmx_func *func;
|
||||
const struct samsung_pin_group *grp;
|
||||
|
||||
bank = gc_to_pin_bank(range->gc);
|
||||
type = bank->type;
|
||||
drvdata = pinctrl_dev_get_drvdata(pctldev);
|
||||
func = &drvdata->pmx_functions[selector];
|
||||
grp = &drvdata->pin_groups[group];
|
||||
|
||||
pin_offset = offset - bank->pin_base;
|
||||
reg = drvdata->virt_base + bank->pctl_offset +
|
||||
type->reg_offset[PINCFG_TYPE_FUNC];
|
||||
|
||||
pin_to_reg_bank(drvdata, grp->pins[0] - drvdata->ctrl->base,
|
||||
®, &pin_offset, &bank);
|
||||
type = bank->type;
|
||||
mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1;
|
||||
shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC];
|
||||
if (shift >= 32) {
|
||||
@ -373,14 +391,20 @@ static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
|
||||
|
||||
spin_lock_irqsave(&bank->slock, flags);
|
||||
|
||||
data = readl(reg);
|
||||
data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]);
|
||||
data &= ~(mask << shift);
|
||||
if (!input)
|
||||
data |= FUNC_OUTPUT << shift;
|
||||
writel(data, reg);
|
||||
if (enable)
|
||||
data |= func->val << shift;
|
||||
writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]);
|
||||
|
||||
spin_unlock_irqrestore(&bank->slock, flags);
|
||||
}
|
||||
|
||||
/* enable a specified pinmux by writing to registers */
|
||||
static int samsung_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
unsigned group)
|
||||
{
|
||||
samsung_pinmux_setup(pctldev, selector, group, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -390,8 +414,6 @@ static const struct pinmux_ops samsung_pinmux_ops = {
|
||||
.get_function_name = samsung_pinmux_get_fname,
|
||||
.get_function_groups = samsung_pinmux_get_groups,
|
||||
.enable = samsung_pinmux_enable,
|
||||
.disable = samsung_pinmux_disable,
|
||||
.gpio_set_direction = samsung_pinmux_gpio_set_direction,
|
||||
};
|
||||
|
||||
/* set or get the pin config settings for a specified pin */
|
||||
@ -540,25 +562,59 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
|
||||
}
|
||||
|
||||
/*
|
||||
* gpiolib gpio_direction_input callback function. The setting of the pin
|
||||
* mux function as 'gpio input' will be handled by the pinctrl susbsystem
|
||||
* interface.
|
||||
* The calls to gpio_direction_output() and gpio_direction_input()
|
||||
* leads to this function call.
|
||||
*/
|
||||
static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
|
||||
static int samsung_gpio_set_direction(struct gpio_chip *gc,
|
||||
unsigned offset, bool input)
|
||||
{
|
||||
return pinctrl_gpio_direction_input(gc->base + offset);
|
||||
struct samsung_pin_bank_type *type;
|
||||
struct samsung_pin_bank *bank;
|
||||
struct samsung_pinctrl_drv_data *drvdata;
|
||||
void __iomem *reg;
|
||||
u32 data, mask, shift;
|
||||
unsigned long flags;
|
||||
|
||||
bank = gc_to_pin_bank(gc);
|
||||
type = bank->type;
|
||||
drvdata = bank->drvdata;
|
||||
|
||||
reg = drvdata->virt_base + bank->pctl_offset +
|
||||
type->reg_offset[PINCFG_TYPE_FUNC];
|
||||
|
||||
mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1;
|
||||
shift = offset * type->fld_width[PINCFG_TYPE_FUNC];
|
||||
if (shift >= 32) {
|
||||
/* Some banks have two config registers */
|
||||
shift -= 32;
|
||||
reg += 4;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&bank->slock, flags);
|
||||
|
||||
data = readl(reg);
|
||||
data &= ~(mask << shift);
|
||||
if (!input)
|
||||
data |= FUNC_OUTPUT << shift;
|
||||
writel(data, reg);
|
||||
|
||||
spin_unlock_irqrestore(&bank->slock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* gpiolib gpio_direction_output callback function. The setting of the pin
|
||||
* mux function as 'gpio output' will be handled by the pinctrl susbsystem
|
||||
* interface.
|
||||
*/
|
||||
/* gpiolib gpio_direction_input callback function. */
|
||||
static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
|
||||
{
|
||||
return samsung_gpio_set_direction(gc, offset, true);
|
||||
}
|
||||
|
||||
/* gpiolib gpio_direction_output callback function. */
|
||||
static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
|
||||
int value)
|
||||
{
|
||||
samsung_gpio_set(gc, offset, value);
|
||||
return pinctrl_gpio_direction_output(gc->base + offset);
|
||||
return samsung_gpio_set_direction(gc, offset, false);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -578,87 +634,115 @@ static int samsung_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
|
||||
return (virq) ? : -ENXIO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the pin names listed in the 'samsung,pins' property and convert it
|
||||
* into a list of gpio numbers are create a pin group from it.
|
||||
*/
|
||||
static int samsung_pinctrl_parse_dt_pins(struct platform_device *pdev,
|
||||
struct device_node *cfg_np,
|
||||
struct pinctrl_desc *pctl,
|
||||
unsigned int **pin_list,
|
||||
unsigned int *npins)
|
||||
static struct samsung_pin_group *samsung_pinctrl_create_groups(
|
||||
struct device *dev,
|
||||
struct samsung_pinctrl_drv_data *drvdata,
|
||||
unsigned int *cnt)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct property *prop;
|
||||
struct pinctrl_pin_desc const *pdesc = pctl->pins;
|
||||
unsigned int idx = 0, cnt;
|
||||
const char *pin_name;
|
||||
|
||||
*npins = of_property_count_strings(cfg_np, "samsung,pins");
|
||||
if (IS_ERR_VALUE(*npins)) {
|
||||
dev_err(dev, "invalid pin list in %s node", cfg_np->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*pin_list = devm_kzalloc(dev, *npins * sizeof(**pin_list), GFP_KERNEL);
|
||||
if (!*pin_list) {
|
||||
dev_err(dev, "failed to allocate memory for pin list\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
of_property_for_each_string(cfg_np, "samsung,pins", prop, pin_name) {
|
||||
for (cnt = 0; cnt < pctl->npins; cnt++) {
|
||||
if (pdesc[cnt].name) {
|
||||
if (!strcmp(pin_name, pdesc[cnt].name)) {
|
||||
(*pin_list)[idx++] = pdesc[cnt].number;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cnt == pctl->npins) {
|
||||
dev_err(dev, "pin %s not valid in %s node\n",
|
||||
pin_name, cfg_np->name);
|
||||
devm_kfree(dev, *pin_list);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the information about all the available pin groups and pin functions
|
||||
* from device node of the pin-controller. A pin group is formed with all
|
||||
* the pins listed in the "samsung,pins" property.
|
||||
*/
|
||||
static int samsung_pinctrl_parse_dt(struct platform_device *pdev,
|
||||
struct samsung_pinctrl_drv_data *drvdata)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *dev_np = dev->of_node;
|
||||
struct device_node *cfg_np;
|
||||
struct pinctrl_desc *ctrldesc = &drvdata->pctl;
|
||||
struct samsung_pin_group *groups, *grp;
|
||||
struct samsung_pmx_func *functions, *func;
|
||||
unsigned *pin_list;
|
||||
unsigned int npins, grp_cnt, func_idx = 0;
|
||||
char *gname, *fname;
|
||||
int ret;
|
||||
const struct pinctrl_pin_desc *pdesc;
|
||||
int i;
|
||||
|
||||
grp_cnt = of_get_child_count(dev_np);
|
||||
if (!grp_cnt)
|
||||
return -EINVAL;
|
||||
|
||||
groups = devm_kzalloc(dev, grp_cnt * sizeof(*groups), GFP_KERNEL);
|
||||
if (!groups) {
|
||||
dev_err(dev, "failed allocate memory for ping group list\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
groups = devm_kzalloc(dev, ctrldesc->npins * sizeof(*groups),
|
||||
GFP_KERNEL);
|
||||
if (!groups)
|
||||
return ERR_PTR(-EINVAL);
|
||||
grp = groups;
|
||||
|
||||
functions = devm_kzalloc(dev, grp_cnt * sizeof(*functions), GFP_KERNEL);
|
||||
pdesc = ctrldesc->pins;
|
||||
for (i = 0; i < ctrldesc->npins; ++i, ++pdesc, ++grp) {
|
||||
grp->name = pdesc->name;
|
||||
grp->pins = &pdesc->number;
|
||||
grp->num_pins = 1;
|
||||
}
|
||||
|
||||
*cnt = ctrldesc->npins;
|
||||
return groups;
|
||||
}
|
||||
|
||||
static int samsung_pinctrl_create_function(struct device *dev,
|
||||
struct samsung_pinctrl_drv_data *drvdata,
|
||||
struct device_node *func_np,
|
||||
struct samsung_pmx_func *func)
|
||||
{
|
||||
int npins;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (of_property_read_u32(func_np, "samsung,pin-function", &func->val))
|
||||
return 0;
|
||||
|
||||
npins = of_property_count_strings(func_np, "samsung,pins");
|
||||
if (npins < 1) {
|
||||
dev_err(dev, "invalid pin list in %s node", func_np->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
func->name = func_np->full_name;
|
||||
|
||||
func->groups = devm_kzalloc(dev, npins * sizeof(char *), GFP_KERNEL);
|
||||
if (!func->groups)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < npins; ++i) {
|
||||
const char *gname;
|
||||
|
||||
ret = of_property_read_string_index(func_np, "samsung,pins",
|
||||
i, &gname);
|
||||
if (ret) {
|
||||
dev_err(dev,
|
||||
"failed to read pin name %d from %s node\n",
|
||||
i, func_np->name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
func->groups[i] = gname;
|
||||
}
|
||||
|
||||
func->num_groups = npins;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct samsung_pmx_func *samsung_pinctrl_create_functions(
|
||||
struct device *dev,
|
||||
struct samsung_pinctrl_drv_data *drvdata,
|
||||
unsigned int *cnt)
|
||||
{
|
||||
struct samsung_pmx_func *functions, *func;
|
||||
struct device_node *dev_np = dev->of_node;
|
||||
struct device_node *cfg_np;
|
||||
unsigned int func_cnt = 0;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Iterate over all the child nodes of the pin controller node
|
||||
* and create pin groups and pin function lists.
|
||||
*/
|
||||
for_each_child_of_node(dev_np, cfg_np) {
|
||||
struct device_node *func_np;
|
||||
|
||||
if (!of_get_child_count(cfg_np)) {
|
||||
if (!of_find_property(cfg_np,
|
||||
"samsung,pin-function", NULL))
|
||||
continue;
|
||||
++func_cnt;
|
||||
continue;
|
||||
}
|
||||
|
||||
for_each_child_of_node(cfg_np, func_np) {
|
||||
if (!of_find_property(func_np,
|
||||
"samsung,pin-function", NULL))
|
||||
continue;
|
||||
++func_cnt;
|
||||
}
|
||||
}
|
||||
|
||||
functions = devm_kzalloc(dev, func_cnt * sizeof(*functions),
|
||||
GFP_KERNEL);
|
||||
if (!functions) {
|
||||
dev_err(dev, "failed to allocate memory for function list\n");
|
||||
return -EINVAL;
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
func = functions;
|
||||
|
||||
@ -666,61 +750,68 @@ static int samsung_pinctrl_parse_dt(struct platform_device *pdev,
|
||||
* Iterate over all the child nodes of the pin controller node
|
||||
* and create pin groups and pin function lists.
|
||||
*/
|
||||
func_cnt = 0;
|
||||
for_each_child_of_node(dev_np, cfg_np) {
|
||||
u32 function;
|
||||
if (!of_find_property(cfg_np, "samsung,pins", NULL))
|
||||
struct device_node *func_np;
|
||||
|
||||
if (!of_get_child_count(cfg_np)) {
|
||||
ret = samsung_pinctrl_create_function(dev, drvdata,
|
||||
cfg_np, func);
|
||||
if (ret < 0)
|
||||
return ERR_PTR(ret);
|
||||
if (ret > 0) {
|
||||
++func;
|
||||
++func_cnt;
|
||||
}
|
||||
continue;
|
||||
|
||||
ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np,
|
||||
&drvdata->pctl, &pin_list, &npins);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* derive pin group name from the node name */
|
||||
gname = devm_kzalloc(dev, strlen(cfg_np->name) + GSUFFIX_LEN,
|
||||
GFP_KERNEL);
|
||||
if (!gname) {
|
||||
dev_err(dev, "failed to alloc memory for group name\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
sprintf(gname, "%s%s", cfg_np->name, GROUP_SUFFIX);
|
||||
|
||||
grp->name = gname;
|
||||
grp->pins = pin_list;
|
||||
grp->num_pins = npins;
|
||||
of_property_read_u32(cfg_np, "samsung,pin-function", &function);
|
||||
grp->func = function;
|
||||
grp++;
|
||||
|
||||
if (!of_find_property(cfg_np, "samsung,pin-function", NULL))
|
||||
continue;
|
||||
|
||||
/* derive function name from the node name */
|
||||
fname = devm_kzalloc(dev, strlen(cfg_np->name) + FSUFFIX_LEN,
|
||||
GFP_KERNEL);
|
||||
if (!fname) {
|
||||
dev_err(dev, "failed to alloc memory for func name\n");
|
||||
return -ENOMEM;
|
||||
for_each_child_of_node(cfg_np, func_np) {
|
||||
ret = samsung_pinctrl_create_function(dev, drvdata,
|
||||
func_np, func);
|
||||
if (ret < 0)
|
||||
return ERR_PTR(ret);
|
||||
if (ret > 0) {
|
||||
++func;
|
||||
++func_cnt;
|
||||
}
|
||||
}
|
||||
sprintf(fname, "%s%s", cfg_np->name, FUNCTION_SUFFIX);
|
||||
}
|
||||
|
||||
func->name = fname;
|
||||
func->groups = devm_kzalloc(dev, sizeof(char *), GFP_KERNEL);
|
||||
if (!func->groups) {
|
||||
dev_err(dev, "failed to alloc memory for group list "
|
||||
"in pin function");
|
||||
return -ENOMEM;
|
||||
}
|
||||
func->groups[0] = gname;
|
||||
func->num_groups = 1;
|
||||
func++;
|
||||
func_idx++;
|
||||
*cnt = func_cnt;
|
||||
return functions;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the information about all the available pin groups and pin functions
|
||||
* from device node of the pin-controller. A pin group is formed with all
|
||||
* the pins listed in the "samsung,pins" property.
|
||||
*/
|
||||
|
||||
static int samsung_pinctrl_parse_dt(struct platform_device *pdev,
|
||||
struct samsung_pinctrl_drv_data *drvdata)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct samsung_pin_group *groups;
|
||||
struct samsung_pmx_func *functions;
|
||||
unsigned int grp_cnt = 0, func_cnt = 0;
|
||||
|
||||
groups = samsung_pinctrl_create_groups(dev, drvdata, &grp_cnt);
|
||||
if (IS_ERR(groups)) {
|
||||
dev_err(dev, "failed to parse pin groups\n");
|
||||
return PTR_ERR(groups);
|
||||
}
|
||||
|
||||
functions = samsung_pinctrl_create_functions(dev, drvdata, &func_cnt);
|
||||
if (IS_ERR(functions)) {
|
||||
dev_err(dev, "failed to parse pin functions\n");
|
||||
return PTR_ERR(groups);
|
||||
}
|
||||
|
||||
drvdata->pin_groups = groups;
|
||||
drvdata->nr_groups = grp_cnt;
|
||||
drvdata->pmx_functions = functions;
|
||||
drvdata->nr_functions = func_idx;
|
||||
drvdata->nr_functions = func_cnt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -790,7 +881,8 @@ static int samsung_pinctrl_register(struct platform_device *pdev,
|
||||
pin_bank = &drvdata->ctrl->pin_banks[bank];
|
||||
pin_bank->grange.name = pin_bank->name;
|
||||
pin_bank->grange.id = bank;
|
||||
pin_bank->grange.pin_base = pin_bank->pin_base;
|
||||
pin_bank->grange.pin_base = drvdata->ctrl->base
|
||||
+ pin_bank->pin_base;
|
||||
pin_bank->grange.base = pin_bank->gpio_chip.base;
|
||||
pin_bank->grange.npins = pin_bank->gpio_chip.ngpio;
|
||||
pin_bank->grange.gc = &pin_bank->gpio_chip;
|
||||
@ -800,7 +892,19 @@ static int samsung_pinctrl_register(struct platform_device *pdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int samsung_gpio_request(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
return pinctrl_request_gpio(chip->base + offset);
|
||||
}
|
||||
|
||||
static void samsung_gpio_free(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
pinctrl_free_gpio(chip->base + offset);
|
||||
}
|
||||
|
||||
static const struct gpio_chip samsung_gpiolib_chip = {
|
||||
.request = samsung_gpio_request,
|
||||
.free = samsung_gpio_free,
|
||||
.set = samsung_gpio_set,
|
||||
.get = samsung_gpio_get,
|
||||
.direction_input = samsung_gpio_direction_input,
|
@ -156,13 +156,6 @@ struct samsung_pin_bank {
|
||||
* @nr_banks: number of pin banks.
|
||||
* @base: starting system wide pin number.
|
||||
* @nr_pins: number of pins supported by the controller.
|
||||
* @geint_con: offset of the ext-gpio controller registers.
|
||||
* @geint_mask: offset of the ext-gpio interrupt mask registers.
|
||||
* @geint_pend: offset of the ext-gpio interrupt pending registers.
|
||||
* @weint_con: offset of the ext-wakeup controller registers.
|
||||
* @weint_mask: offset of the ext-wakeup interrupt mask registers.
|
||||
* @weint_pend: offset of the ext-wakeup interrupt pending registers.
|
||||
* @svc: offset of the interrupt service register.
|
||||
* @eint_gpio_init: platform specific callback to setup the external gpio
|
||||
* interrupts for the controller.
|
||||
* @eint_wkup_init: platform specific callback to setup the external wakeup
|
||||
@ -176,16 +169,6 @@ struct samsung_pin_ctrl {
|
||||
u32 base;
|
||||
u32 nr_pins;
|
||||
|
||||
u32 geint_con;
|
||||
u32 geint_mask;
|
||||
u32 geint_pend;
|
||||
|
||||
u32 weint_con;
|
||||
u32 weint_mask;
|
||||
u32 weint_pend;
|
||||
|
||||
u32 svc;
|
||||
|
||||
int (*eint_gpio_init)(struct samsung_pinctrl_drv_data *);
|
||||
int (*eint_wkup_init)(struct samsung_pinctrl_drv_data *);
|
||||
void (*suspend)(struct samsung_pinctrl_drv_data *);
|
||||
@ -248,6 +231,7 @@ struct samsung_pmx_func {
|
||||
const char *name;
|
||||
const char **groups;
|
||||
u8 num_groups;
|
||||
u32 val;
|
||||
};
|
||||
|
||||
/* list of all exported SoC specific data */
|
@ -409,11 +409,8 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
|
||||
|
||||
int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc)
|
||||
{
|
||||
int err;
|
||||
int ret;
|
||||
gpiochip_remove(&pfc->gpio->gpio_chip);
|
||||
gpiochip_remove(&pfc->func->gpio_chip);
|
||||
|
||||
ret = gpiochip_remove(&pfc->gpio->gpio_chip);
|
||||
err = gpiochip_remove(&pfc->func->gpio_chip);
|
||||
|
||||
return ret < 0 ? ret : err;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1726,6 +1726,133 @@ static const unsigned int audio_clkout_mux[] = {
|
||||
AUDIO_CLKOUT_MARK,
|
||||
};
|
||||
|
||||
/* - CAN -------------------------------------------------------------------- */
|
||||
|
||||
static const unsigned int can0_data_pins[] = {
|
||||
/* TX, RX */
|
||||
RCAR_GP_PIN(3, 26), RCAR_GP_PIN(3, 29),
|
||||
};
|
||||
|
||||
static const unsigned int can0_data_mux[] = {
|
||||
CAN0_TX_MARK, CAN0_RX_MARK,
|
||||
};
|
||||
|
||||
static const unsigned int can0_data_b_pins[] = {
|
||||
/* TX, RX */
|
||||
RCAR_GP_PIN(7, 4), RCAR_GP_PIN(7, 3),
|
||||
};
|
||||
|
||||
static const unsigned int can0_data_b_mux[] = {
|
||||
CAN0_TX_B_MARK, CAN0_RX_B_MARK,
|
||||
};
|
||||
|
||||
static const unsigned int can0_data_c_pins[] = {
|
||||
/* TX, RX */
|
||||
RCAR_GP_PIN(5, 17), RCAR_GP_PIN(5, 18),
|
||||
};
|
||||
|
||||
static const unsigned int can0_data_c_mux[] = {
|
||||
CAN0_TX_C_MARK, CAN0_RX_C_MARK,
|
||||
};
|
||||
|
||||
static const unsigned int can0_data_d_pins[] = {
|
||||
/* TX, RX */
|
||||
RCAR_GP_PIN(2, 26), RCAR_GP_PIN(2, 27),
|
||||
};
|
||||
|
||||
static const unsigned int can0_data_d_mux[] = {
|
||||
CAN0_TX_D_MARK, CAN0_RX_D_MARK,
|
||||
};
|
||||
|
||||
static const unsigned int can0_data_e_pins[] = {
|
||||
/* TX, RX */
|
||||
RCAR_GP_PIN(4, 18), RCAR_GP_PIN(4, 28),
|
||||
};
|
||||
|
||||
static const unsigned int can0_data_e_mux[] = {
|
||||
CAN0_TX_E_MARK, CAN0_RX_E_MARK,
|
||||
};
|
||||
|
||||
static const unsigned int can0_data_f_pins[] = {
|
||||
/* TX, RX */
|
||||
RCAR_GP_PIN(6, 7), RCAR_GP_PIN(6, 6),
|
||||
};
|
||||
|
||||
static const unsigned int can0_data_f_mux[] = {
|
||||
CAN0_TX_F_MARK, CAN0_RX_F_MARK,
|
||||
};
|
||||
|
||||
static const unsigned int can1_data_pins[] = {
|
||||
/* TX, RX */
|
||||
RCAR_GP_PIN(3, 21), RCAR_GP_PIN(3, 20),
|
||||
};
|
||||
|
||||
static const unsigned int can1_data_mux[] = {
|
||||
CAN1_TX_MARK, CAN1_RX_MARK,
|
||||
};
|
||||
|
||||
static const unsigned int can1_data_b_pins[] = {
|
||||
/* TX, RX */
|
||||
RCAR_GP_PIN(7, 8), RCAR_GP_PIN(7, 9),
|
||||
};
|
||||
|
||||
static const unsigned int can1_data_b_mux[] = {
|
||||
CAN1_TX_B_MARK, CAN1_RX_B_MARK,
|
||||
};
|
||||
|
||||
static const unsigned int can1_data_c_pins[] = {
|
||||
/* TX, RX */
|
||||
RCAR_GP_PIN(5, 20), RCAR_GP_PIN(5, 19),
|
||||
};
|
||||
|
||||
static const unsigned int can1_data_c_mux[] = {
|
||||
CAN1_TX_C_MARK, CAN1_RX_C_MARK,
|
||||
};
|
||||
|
||||
static const unsigned int can1_data_d_pins[] = {
|
||||
/* TX, RX */
|
||||
RCAR_GP_PIN(4, 29), RCAR_GP_PIN(4, 31),
|
||||
};
|
||||
|
||||
static const unsigned int can1_data_d_mux[] = {
|
||||
CAN1_TX_D_MARK, CAN1_RX_D_MARK,
|
||||
};
|
||||
|
||||
static const unsigned int can_clk_pins[] = {
|
||||
/* CLK */
|
||||
RCAR_GP_PIN(7, 2),
|
||||
};
|
||||
|
||||
static const unsigned int can_clk_mux[] = {
|
||||
CAN_CLK_MARK,
|
||||
};
|
||||
|
||||
static const unsigned int can_clk_b_pins[] = {
|
||||
/* CLK */
|
||||
RCAR_GP_PIN(5, 21),
|
||||
};
|
||||
|
||||
static const unsigned int can_clk_b_mux[] = {
|
||||
CAN_CLK_B_MARK,
|
||||
};
|
||||
|
||||
static const unsigned int can_clk_c_pins[] = {
|
||||
/* CLK */
|
||||
RCAR_GP_PIN(4, 30),
|
||||
};
|
||||
|
||||
static const unsigned int can_clk_c_mux[] = {
|
||||
CAN_CLK_C_MARK,
|
||||
};
|
||||
|
||||
static const unsigned int can_clk_d_pins[] = {
|
||||
/* CLK */
|
||||
RCAR_GP_PIN(7, 19),
|
||||
};
|
||||
|
||||
static const unsigned int can_clk_d_mux[] = {
|
||||
CAN_CLK_D_MARK,
|
||||
};
|
||||
|
||||
/* - DU --------------------------------------------------------------------- */
|
||||
static const unsigned int du_rgb666_pins[] = {
|
||||
@ -1867,6 +1994,192 @@ static const unsigned int eth_rmii_mux[] = {
|
||||
ETH_RXD0_MARK, ETH_RXD1_MARK, ETH_RX_ER_MARK, ETH_CRS_DV_MARK,
|
||||
ETH_TXD0_MARK, ETH_TXD1_MARK, ETH_TX_EN_MARK, ETH_REFCLK_MARK,
|
||||
};
|
||||
|
||||
/* - HSCIF0 ----------------------------------------------------------------- */
|
||||
static const unsigned int hscif0_data_pins[] = {
|
||||
/* RX, TX */
|
||||
RCAR_GP_PIN(7, 3), RCAR_GP_PIN(7, 4),
|
||||
};
|
||||
static const unsigned int hscif0_data_mux[] = {
|
||||
HRX0_MARK, HTX0_MARK,
|
||||
};
|
||||
static const unsigned int hscif0_clk_pins[] = {
|
||||
/* SCK */
|
||||
RCAR_GP_PIN(7, 2),
|
||||
};
|
||||
static const unsigned int hscif0_clk_mux[] = {
|
||||
HSCK0_MARK,
|
||||
};
|
||||
static const unsigned int hscif0_ctrl_pins[] = {
|
||||
/* RTS, CTS */
|
||||
RCAR_GP_PIN(7, 1), RCAR_GP_PIN(7, 0),
|
||||
};
|
||||
static const unsigned int hscif0_ctrl_mux[] = {
|
||||
HRTS0_N_MARK, HCTS0_N_MARK,
|
||||
};
|
||||
static const unsigned int hscif0_data_b_pins[] = {
|
||||
/* RX, TX */
|
||||
RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 15),
|
||||
};
|
||||
static const unsigned int hscif0_data_b_mux[] = {
|
||||
HRX0_B_MARK, HTX0_B_MARK,
|
||||
};
|
||||
static const unsigned int hscif0_ctrl_b_pins[] = {
|
||||
/* RTS, CTS */
|
||||
RCAR_GP_PIN(3, 14), RCAR_GP_PIN(3, 13),
|
||||
};
|
||||
static const unsigned int hscif0_ctrl_b_mux[] = {
|
||||
HRTS0_N_B_MARK, HCTS0_N_B_MARK,
|
||||
};
|
||||
static const unsigned int hscif0_data_c_pins[] = {
|
||||
/* RX, TX */
|
||||
RCAR_GP_PIN(2, 0), RCAR_GP_PIN(2, 1),
|
||||
};
|
||||
static const unsigned int hscif0_data_c_mux[] = {
|
||||
HRX0_C_MARK, HTX0_C_MARK,
|
||||
};
|
||||
static const unsigned int hscif0_clk_c_pins[] = {
|
||||
/* SCK */
|
||||
RCAR_GP_PIN(5, 31),
|
||||
};
|
||||
static const unsigned int hscif0_clk_c_mux[] = {
|
||||
HSCK0_C_MARK,
|
||||
};
|
||||
/* - HSCIF1 ----------------------------------------------------------------- */
|
||||
static const unsigned int hscif1_data_pins[] = {
|
||||
/* RX, TX */
|
||||
RCAR_GP_PIN(7, 5), RCAR_GP_PIN(7, 6),
|
||||
};
|
||||
static const unsigned int hscif1_data_mux[] = {
|
||||
HRX1_MARK, HTX1_MARK,
|
||||
};
|
||||
static const unsigned int hscif1_clk_pins[] = {
|
||||
/* SCK */
|
||||
RCAR_GP_PIN(7, 7),
|
||||
};
|
||||
static const unsigned int hscif1_clk_mux[] = {
|
||||
HSCK1_MARK,
|
||||
};
|
||||
static const unsigned int hscif1_ctrl_pins[] = {
|
||||
/* RTS, CTS */
|
||||
RCAR_GP_PIN(7, 9), RCAR_GP_PIN(7, 8),
|
||||
};
|
||||
static const unsigned int hscif1_ctrl_mux[] = {
|
||||
HRTS1_N_MARK, HCTS1_N_MARK,
|
||||
};
|
||||
static const unsigned int hscif1_data_b_pins[] = {
|
||||
/* RX, TX */
|
||||
RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 18),
|
||||
};
|
||||
static const unsigned int hscif1_data_b_mux[] = {
|
||||
HRX1_B_MARK, HTX1_B_MARK,
|
||||
};
|
||||
static const unsigned int hscif1_data_c_pins[] = {
|
||||
/* RX, TX */
|
||||
RCAR_GP_PIN(7, 14), RCAR_GP_PIN(7, 15),
|
||||
};
|
||||
static const unsigned int hscif1_data_c_mux[] = {
|
||||
HRX1_C_MARK, HTX1_C_MARK,
|
||||
};
|
||||
static const unsigned int hscif1_clk_c_pins[] = {
|
||||
/* SCK */
|
||||
RCAR_GP_PIN(7, 16),
|
||||
};
|
||||
static const unsigned int hscif1_clk_c_mux[] = {
|
||||
HSCK1_C_MARK,
|
||||
};
|
||||
static const unsigned int hscif1_ctrl_c_pins[] = {
|
||||
/* RTS, CTS */
|
||||
RCAR_GP_PIN(7, 18), RCAR_GP_PIN(7, 17),
|
||||
};
|
||||
static const unsigned int hscif1_ctrl_c_mux[] = {
|
||||
HRTS1_N_C_MARK, HCTS1_N_C_MARK,
|
||||
};
|
||||
static const unsigned int hscif1_data_d_pins[] = {
|
||||
/* RX, TX */
|
||||
RCAR_GP_PIN(4, 28), RCAR_GP_PIN(4, 18),
|
||||
};
|
||||
static const unsigned int hscif1_data_d_mux[] = {
|
||||
HRX1_D_MARK, HTX1_D_MARK,
|
||||
};
|
||||
static const unsigned int hscif1_data_e_pins[] = {
|
||||
/* RX, TX */
|
||||
RCAR_GP_PIN(7, 14), RCAR_GP_PIN(7, 15),
|
||||
};
|
||||
static const unsigned int hscif1_data_e_mux[] = {
|
||||
HRX1_C_MARK, HTX1_C_MARK,
|
||||
};
|
||||
static const unsigned int hscif1_clk_e_pins[] = {
|
||||
/* SCK */
|
||||
RCAR_GP_PIN(2, 6),
|
||||
};
|
||||
static const unsigned int hscif1_clk_e_mux[] = {
|
||||
HSCK1_E_MARK,
|
||||
};
|
||||
static const unsigned int hscif1_ctrl_e_pins[] = {
|
||||
/* RTS, CTS */
|
||||
RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 7),
|
||||
};
|
||||
static const unsigned int hscif1_ctrl_e_mux[] = {
|
||||
HRTS1_N_E_MARK, HCTS1_N_E_MARK,
|
||||
};
|
||||
/* - HSCIF2 ----------------------------------------------------------------- */
|
||||
static const unsigned int hscif2_data_pins[] = {
|
||||
/* RX, TX */
|
||||
RCAR_GP_PIN(4, 16), RCAR_GP_PIN(4, 17),
|
||||
};
|
||||
static const unsigned int hscif2_data_mux[] = {
|
||||
HRX2_MARK, HTX2_MARK,
|
||||
};
|
||||
static const unsigned int hscif2_clk_pins[] = {
|
||||
/* SCK */
|
||||
RCAR_GP_PIN(4, 15),
|
||||
};
|
||||
static const unsigned int hscif2_clk_mux[] = {
|
||||
HSCK2_MARK,
|
||||
};
|
||||
static const unsigned int hscif2_ctrl_pins[] = {
|
||||
/* RTS, CTS */
|
||||
RCAR_GP_PIN(4, 14), RCAR_GP_PIN(4, 13),
|
||||
};
|
||||
static const unsigned int hscif2_ctrl_mux[] = {
|
||||
HRTS2_N_MARK, HCTS2_N_MARK,
|
||||
};
|
||||
static const unsigned int hscif2_data_b_pins[] = {
|
||||
/* RX, TX */
|
||||
RCAR_GP_PIN(1, 20), RCAR_GP_PIN(1, 22),
|
||||
};
|
||||
static const unsigned int hscif2_data_b_mux[] = {
|
||||
HRX2_B_MARK, HTX2_B_MARK,
|
||||
};
|
||||
static const unsigned int hscif2_ctrl_b_pins[] = {
|
||||
/* RTS, CTS */
|
||||
RCAR_GP_PIN(1, 23), RCAR_GP_PIN(1, 21),
|
||||
};
|
||||
static const unsigned int hscif2_ctrl_b_mux[] = {
|
||||
HRTS2_N_B_MARK, HCTS2_N_B_MARK,
|
||||
};
|
||||
static const unsigned int hscif2_data_c_pins[] = {
|
||||
/* RX, TX */
|
||||
RCAR_GP_PIN(2, 0), RCAR_GP_PIN(2, 1),
|
||||
};
|
||||
static const unsigned int hscif2_data_c_mux[] = {
|
||||
HRX2_C_MARK, HTX2_C_MARK,
|
||||
};
|
||||
static const unsigned int hscif2_clk_c_pins[] = {
|
||||
/* SCK */
|
||||
RCAR_GP_PIN(5, 31),
|
||||
};
|
||||
static const unsigned int hscif2_clk_c_mux[] = {
|
||||
HSCK2_C_MARK,
|
||||
};
|
||||
static const unsigned int hscif2_data_d_pins[] = {
|
||||
/* RX, TX */
|
||||
RCAR_GP_PIN(1, 20), RCAR_GP_PIN(5, 31),
|
||||
};
|
||||
static const unsigned int hscif2_data_d_mux[] = {
|
||||
HRX2_B_MARK, HTX2_D_MARK,
|
||||
};
|
||||
/* - I2C0 ------------------------------------------------------------------- */
|
||||
static const unsigned int i2c0_pins[] = {
|
||||
/* SCL, SDA */
|
||||
@ -3869,6 +4182,20 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
|
||||
SH_PFC_PIN_GROUP(audio_clk_b_b),
|
||||
SH_PFC_PIN_GROUP(audio_clk_c),
|
||||
SH_PFC_PIN_GROUP(audio_clkout),
|
||||
SH_PFC_PIN_GROUP(can0_data),
|
||||
SH_PFC_PIN_GROUP(can0_data_b),
|
||||
SH_PFC_PIN_GROUP(can0_data_c),
|
||||
SH_PFC_PIN_GROUP(can0_data_d),
|
||||
SH_PFC_PIN_GROUP(can0_data_e),
|
||||
SH_PFC_PIN_GROUP(can0_data_f),
|
||||
SH_PFC_PIN_GROUP(can1_data),
|
||||
SH_PFC_PIN_GROUP(can1_data_b),
|
||||
SH_PFC_PIN_GROUP(can1_data_c),
|
||||
SH_PFC_PIN_GROUP(can1_data_d),
|
||||
SH_PFC_PIN_GROUP(can_clk),
|
||||
SH_PFC_PIN_GROUP(can_clk_b),
|
||||
SH_PFC_PIN_GROUP(can_clk_c),
|
||||
SH_PFC_PIN_GROUP(can_clk_d),
|
||||
SH_PFC_PIN_GROUP(du_rgb666),
|
||||
SH_PFC_PIN_GROUP(du_rgb888),
|
||||
SH_PFC_PIN_GROUP(du_clk_out_0),
|
||||
@ -3885,6 +4212,32 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
|
||||
SH_PFC_PIN_GROUP(eth_magic),
|
||||
SH_PFC_PIN_GROUP(eth_mdio),
|
||||
SH_PFC_PIN_GROUP(eth_rmii),
|
||||
SH_PFC_PIN_GROUP(hscif0_data),
|
||||
SH_PFC_PIN_GROUP(hscif0_clk),
|
||||
SH_PFC_PIN_GROUP(hscif0_ctrl),
|
||||
SH_PFC_PIN_GROUP(hscif0_data_b),
|
||||
SH_PFC_PIN_GROUP(hscif0_ctrl_b),
|
||||
SH_PFC_PIN_GROUP(hscif0_data_c),
|
||||
SH_PFC_PIN_GROUP(hscif0_clk_c),
|
||||
SH_PFC_PIN_GROUP(hscif1_data),
|
||||
SH_PFC_PIN_GROUP(hscif1_clk),
|
||||
SH_PFC_PIN_GROUP(hscif1_ctrl),
|
||||
SH_PFC_PIN_GROUP(hscif1_data_b),
|
||||
SH_PFC_PIN_GROUP(hscif1_data_c),
|
||||
SH_PFC_PIN_GROUP(hscif1_clk_c),
|
||||
SH_PFC_PIN_GROUP(hscif1_ctrl_c),
|
||||
SH_PFC_PIN_GROUP(hscif1_data_d),
|
||||
SH_PFC_PIN_GROUP(hscif1_data_e),
|
||||
SH_PFC_PIN_GROUP(hscif1_clk_e),
|
||||
SH_PFC_PIN_GROUP(hscif1_ctrl_e),
|
||||
SH_PFC_PIN_GROUP(hscif2_data),
|
||||
SH_PFC_PIN_GROUP(hscif2_clk),
|
||||
SH_PFC_PIN_GROUP(hscif2_ctrl),
|
||||
SH_PFC_PIN_GROUP(hscif2_data_b),
|
||||
SH_PFC_PIN_GROUP(hscif2_ctrl_b),
|
||||
SH_PFC_PIN_GROUP(hscif2_data_c),
|
||||
SH_PFC_PIN_GROUP(hscif2_clk_c),
|
||||
SH_PFC_PIN_GROUP(hscif2_data_d),
|
||||
SH_PFC_PIN_GROUP(i2c0),
|
||||
SH_PFC_PIN_GROUP(i2c0_b),
|
||||
SH_PFC_PIN_GROUP(i2c0_c),
|
||||
@ -4155,6 +4508,30 @@ static const char * const audio_clk_groups[] = {
|
||||
"audio_clkout",
|
||||
};
|
||||
|
||||
static const char * const can0_groups[] = {
|
||||
"can0_data_a",
|
||||
"can0_data_b",
|
||||
"can0_data_c",
|
||||
"can0_data_d",
|
||||
"can0_data_e",
|
||||
"can0_data_f",
|
||||
"can_clk_a",
|
||||
"can_clk_b",
|
||||
"can_clk_c",
|
||||
"can_clk_d",
|
||||
};
|
||||
|
||||
static const char * const can1_groups[] = {
|
||||
"can1_data_a",
|
||||
"can1_data_b",
|
||||
"can1_data_c",
|
||||
"can1_data_d",
|
||||
"can_clk_a",
|
||||
"can_clk_b",
|
||||
"can_clk_c",
|
||||
"can_clk_d",
|
||||
};
|
||||
|
||||
static const char * const du_groups[] = {
|
||||
"du_rgb666",
|
||||
"du_rgb888",
|
||||
@ -4183,6 +4560,41 @@ static const char * const eth_groups[] = {
|
||||
"eth_rmii",
|
||||
};
|
||||
|
||||
static const char * const hscif0_groups[] = {
|
||||
"hscif0_data",
|
||||
"hscif0_clk",
|
||||
"hscif0_ctrl",
|
||||
"hscif0_data_b",
|
||||
"hscif0_ctrl_b",
|
||||
"hscif0_data_c",
|
||||
"hscif0_clk_c",
|
||||
};
|
||||
|
||||
static const char * const hscif1_groups[] = {
|
||||
"hscif1_data",
|
||||
"hscif1_clk",
|
||||
"hscif1_ctrl",
|
||||
"hscif1_data_b",
|
||||
"hscif1_data_c",
|
||||
"hscif1_clk_c",
|
||||
"hscif1_ctrl_c",
|
||||
"hscif1_data_d",
|
||||
"hscif1_data_e",
|
||||
"hscif1_clk_e",
|
||||
"hscif1_ctrl_e",
|
||||
};
|
||||
|
||||
static const char * const hscif2_groups[] = {
|
||||
"hscif2_data",
|
||||
"hscif2_clk",
|
||||
"hscif2_ctrl",
|
||||
"hscif2_data_b",
|
||||
"hscif2_ctrl_b",
|
||||
"hscif2_data_c",
|
||||
"hscif2_clk_c",
|
||||
"hscif2_data_d",
|
||||
};
|
||||
|
||||
static const char * const i2c0_groups[] = {
|
||||
"i2c0",
|
||||
"i2c0_b",
|
||||
@ -4543,10 +4955,15 @@ static const char * const vin2_groups[] = {
|
||||
|
||||
static const struct sh_pfc_function pinmux_functions[] = {
|
||||
SH_PFC_FUNCTION(audio_clk),
|
||||
SH_PFC_FUNCTION(can0),
|
||||
SH_PFC_FUNCTION(can1),
|
||||
SH_PFC_FUNCTION(du),
|
||||
SH_PFC_FUNCTION(du0),
|
||||
SH_PFC_FUNCTION(du1),
|
||||
SH_PFC_FUNCTION(eth),
|
||||
SH_PFC_FUNCTION(hscif0),
|
||||
SH_PFC_FUNCTION(hscif1),
|
||||
SH_PFC_FUNCTION(hscif2),
|
||||
SH_PFC_FUNCTION(i2c0),
|
||||
SH_PFC_FUNCTION(i2c1),
|
||||
SH_PFC_FUNCTION(i2c2),
|
||||
|
@ -3842,7 +3842,8 @@ static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc)
|
||||
cfg.init_data = &sh73a0_vccq_mc0_init_data;
|
||||
cfg.driver_data = pfc;
|
||||
|
||||
data->vccq_mc0 = regulator_register(&sh73a0_vccq_mc0_desc, &cfg);
|
||||
data->vccq_mc0 = devm_regulator_register(pfc->dev,
|
||||
&sh73a0_vccq_mc0_desc, &cfg);
|
||||
if (IS_ERR(data->vccq_mc0)) {
|
||||
ret = PTR_ERR(data->vccq_mc0);
|
||||
dev_err(pfc->dev, "Failed to register VCCQ MC0 regulator: %d\n",
|
||||
@ -3855,16 +3856,8 @@ static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sh73a0_pinmux_soc_exit(struct sh_pfc *pfc)
|
||||
{
|
||||
struct sh73a0_pinmux_data *data = pfc->soc_data;
|
||||
|
||||
regulator_unregister(data->vccq_mc0);
|
||||
}
|
||||
|
||||
static const struct sh_pfc_soc_operations sh73a0_pinmux_ops = {
|
||||
.init = sh73a0_pinmux_soc_init,
|
||||
.exit = sh73a0_pinmux_soc_exit,
|
||||
.get_bias = sh73a0_pinmux_get_bias,
|
||||
.set_bias = sh73a0_pinmux_set_bias,
|
||||
};
|
||||
|
@ -345,27 +345,6 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sh_pfc_func_disable(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
unsigned group)
|
||||
{
|
||||
struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct sh_pfc *pfc = pmx->pfc;
|
||||
const struct sh_pfc_pin_group *grp = &pfc->info->groups[group];
|
||||
unsigned long flags;
|
||||
unsigned int i;
|
||||
|
||||
spin_lock_irqsave(&pfc->lock, flags);
|
||||
|
||||
for (i = 0; i < grp->nr_pins; ++i) {
|
||||
int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]);
|
||||
struct sh_pfc_pin_config *cfg = &pmx->configs[idx];
|
||||
|
||||
cfg->type = PINMUX_TYPE_NONE;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&pfc->lock, flags);
|
||||
}
|
||||
|
||||
static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
unsigned offset)
|
||||
@ -464,7 +443,6 @@ static const struct pinmux_ops sh_pfc_pinmux_ops = {
|
||||
.get_function_name = sh_pfc_get_function_name,
|
||||
.get_function_groups = sh_pfc_get_function_groups,
|
||||
.enable = sh_pfc_func_enable,
|
||||
.disable = sh_pfc_func_disable,
|
||||
.gpio_request_enable = sh_pfc_gpio_request_enable,
|
||||
.gpio_disable_free = sh_pfc_gpio_disable_free,
|
||||
.gpio_set_direction = sh_pfc_gpio_set_direction,
|
||||
|
@ -186,15 +186,6 @@ static int sirfsoc_pinmux_enable(struct pinctrl_dev *pmxdev, unsigned selector,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sirfsoc_pinmux_disable(struct pinctrl_dev *pmxdev, unsigned selector,
|
||||
unsigned group)
|
||||
{
|
||||
struct sirfsoc_pmx *spmx;
|
||||
|
||||
spmx = pinctrl_dev_get_drvdata(pmxdev);
|
||||
sirfsoc_pinmux_endisable(spmx, selector, false);
|
||||
}
|
||||
|
||||
static int sirfsoc_pinmux_get_funcs_count(struct pinctrl_dev *pmxdev)
|
||||
{
|
||||
return sirfsoc_pmxfunc_cnt;
|
||||
@ -240,7 +231,6 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev,
|
||||
|
||||
static struct pinmux_ops sirfsoc_pinmux_ops = {
|
||||
.enable = sirfsoc_pinmux_enable,
|
||||
.disable = sirfsoc_pinmux_disable,
|
||||
.get_functions_count = sirfsoc_pinmux_get_funcs_count,
|
||||
.get_function_name = sirfsoc_pinmux_get_func_name,
|
||||
.get_function_groups = sirfsoc_pinmux_get_groups,
|
||||
|
@ -48,6 +48,7 @@ config PINCTRL_SPEAR1340
|
||||
config PINCTRL_SPEAR_PLGPIO
|
||||
bool "SPEAr SoC PLGPIO Controller"
|
||||
depends on GPIOLIB && PINCTRL_SPEAR
|
||||
select GPIOLIB_IRQCHIP
|
||||
help
|
||||
Say yes here to support PLGPIO controller on ST Microelectronics SPEAr
|
||||
SoCs.
|
||||
|
@ -11,12 +11,11 @@
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/irqchip/chained_irq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm.h>
|
||||
@ -54,7 +53,6 @@ struct plgpio_regs {
|
||||
*
|
||||
* lock: lock for guarding gpio registers
|
||||
* base: base address of plgpio block
|
||||
* irq_base: irq number of plgpio0
|
||||
* chip: gpio framework specific chip information structure
|
||||
* p2o: function ptr for pin to offset conversion. This is required only for
|
||||
* machines where mapping b/w pin and offset is not 1-to-1.
|
||||
@ -68,8 +66,6 @@ struct plgpio {
|
||||
spinlock_t lock;
|
||||
void __iomem *base;
|
||||
struct clk *clk;
|
||||
unsigned irq_base;
|
||||
struct irq_domain *irq_domain;
|
||||
struct gpio_chip chip;
|
||||
int (*p2o)(int pin); /* pin_to_offset */
|
||||
int (*o2p)(int offset); /* offset_to_pin */
|
||||
@ -280,21 +276,12 @@ disable_clk:
|
||||
pinctrl_free_gpio(gpio);
|
||||
}
|
||||
|
||||
static int plgpio_to_irq(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
|
||||
|
||||
if (IS_ERR_VALUE(plgpio->irq_base))
|
||||
return -EINVAL;
|
||||
|
||||
return irq_find_mapping(plgpio->irq_domain, offset);
|
||||
}
|
||||
|
||||
/* PLGPIO IRQ */
|
||||
static void plgpio_irq_disable(struct irq_data *d)
|
||||
{
|
||||
struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
|
||||
int offset = d->irq - plgpio->irq_base;
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
|
||||
int offset = d->hwirq;
|
||||
unsigned long flags;
|
||||
|
||||
/* get correct offset for "offset" pin */
|
||||
@ -311,8 +298,9 @@ static void plgpio_irq_disable(struct irq_data *d)
|
||||
|
||||
static void plgpio_irq_enable(struct irq_data *d)
|
||||
{
|
||||
struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
|
||||
int offset = d->irq - plgpio->irq_base;
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
|
||||
int offset = d->hwirq;
|
||||
unsigned long flags;
|
||||
|
||||
/* get correct offset for "offset" pin */
|
||||
@ -329,8 +317,9 @@ static void plgpio_irq_enable(struct irq_data *d)
|
||||
|
||||
static int plgpio_irq_set_type(struct irq_data *d, unsigned trigger)
|
||||
{
|
||||
struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
|
||||
int offset = d->irq - plgpio->irq_base;
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
|
||||
int offset = d->hwirq;
|
||||
void __iomem *reg_off;
|
||||
unsigned int supported_type = 0, val;
|
||||
|
||||
@ -369,7 +358,8 @@ static struct irq_chip plgpio_irqchip = {
|
||||
|
||||
static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc)
|
||||
{
|
||||
struct plgpio *plgpio = irq_get_handler_data(irq);
|
||||
struct gpio_chip *gc = irq_desc_get_handler_data(desc);
|
||||
struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
|
||||
struct irq_chip *irqchip = irq_desc_get_chip(desc);
|
||||
int regs_count, count, pin, offset, i = 0;
|
||||
unsigned long pending;
|
||||
@ -410,7 +400,8 @@ static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc)
|
||||
|
||||
/* get correct irq line number */
|
||||
pin = i * MAX_GPIO_PER_REG + pin;
|
||||
generic_handle_irq(plgpio_to_irq(&plgpio->chip, pin));
|
||||
generic_handle_irq(
|
||||
irq_find_mapping(gc->irqdomain, pin));
|
||||
}
|
||||
}
|
||||
chained_irq_exit(irqchip, desc);
|
||||
@ -523,10 +514,9 @@ end:
|
||||
}
|
||||
static int plgpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct plgpio *plgpio;
|
||||
struct resource *res;
|
||||
int ret, irq, i;
|
||||
int ret, irq;
|
||||
|
||||
plgpio = devm_kzalloc(&pdev->dev, sizeof(*plgpio), GFP_KERNEL);
|
||||
if (!plgpio) {
|
||||
@ -563,7 +553,6 @@ static int plgpio_probe(struct platform_device *pdev)
|
||||
platform_set_drvdata(pdev, plgpio);
|
||||
spin_lock_init(&plgpio->lock);
|
||||
|
||||
plgpio->irq_base = -1;
|
||||
plgpio->chip.base = -1;
|
||||
plgpio->chip.request = plgpio_request;
|
||||
plgpio->chip.free = plgpio_free;
|
||||
@ -571,10 +560,10 @@ static int plgpio_probe(struct platform_device *pdev)
|
||||
plgpio->chip.direction_output = plgpio_direction_output;
|
||||
plgpio->chip.get = plgpio_get_value;
|
||||
plgpio->chip.set = plgpio_set_value;
|
||||
plgpio->chip.to_irq = plgpio_to_irq;
|
||||
plgpio->chip.label = dev_name(&pdev->dev);
|
||||
plgpio->chip.dev = &pdev->dev;
|
||||
plgpio->chip.owner = THIS_MODULE;
|
||||
plgpio->chip.of_node = pdev->dev.of_node;
|
||||
|
||||
if (!IS_ERR(plgpio->clk)) {
|
||||
ret = clk_prepare(plgpio->clk);
|
||||
@ -592,43 +581,32 @@ static int plgpio_probe(struct platform_device *pdev)
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_info(&pdev->dev, "irqs not supported\n");
|
||||
dev_info(&pdev->dev, "PLGPIO registered without IRQs\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
plgpio->irq_base = irq_alloc_descs(-1, 0, plgpio->chip.ngpio, 0);
|
||||
if (IS_ERR_VALUE(plgpio->irq_base)) {
|
||||
/* we would not support irq for gpio */
|
||||
dev_warn(&pdev->dev, "couldn't allocate irq base\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
plgpio->irq_domain = irq_domain_add_legacy(np, plgpio->chip.ngpio,
|
||||
plgpio->irq_base, 0, &irq_domain_simple_ops, NULL);
|
||||
if (WARN_ON(!plgpio->irq_domain)) {
|
||||
dev_err(&pdev->dev, "irq domain init failed\n");
|
||||
irq_free_descs(plgpio->irq_base, plgpio->chip.ngpio);
|
||||
ret = -ENXIO;
|
||||
ret = gpiochip_irqchip_add(&plgpio->chip,
|
||||
&plgpio_irqchip,
|
||||
0,
|
||||
handle_simple_irq,
|
||||
IRQ_TYPE_NONE);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to add irqchip to gpiochip\n");
|
||||
goto remove_gpiochip;
|
||||
}
|
||||
|
||||
irq_set_chained_handler(irq, plgpio_irq_handler);
|
||||
for (i = 0; i < plgpio->chip.ngpio; i++) {
|
||||
irq_set_chip_and_handler(i + plgpio->irq_base, &plgpio_irqchip,
|
||||
handle_simple_irq);
|
||||
set_irq_flags(i + plgpio->irq_base, IRQF_VALID);
|
||||
irq_set_chip_data(i + plgpio->irq_base, plgpio);
|
||||
}
|
||||
gpiochip_set_chained_irqchip(&plgpio->chip,
|
||||
&plgpio_irqchip,
|
||||
irq,
|
||||
plgpio_irq_handler);
|
||||
|
||||
irq_set_handler_data(irq, plgpio);
|
||||
dev_info(&pdev->dev, "PLGPIO registered with IRQs\n");
|
||||
|
||||
return 0;
|
||||
|
||||
remove_gpiochip:
|
||||
dev_info(&pdev->dev, "Remove gpiochip\n");
|
||||
if (gpiochip_remove(&plgpio->chip))
|
||||
dev_err(&pdev->dev, "unable to remove gpiochip\n");
|
||||
gpiochip_remove(&plgpio->chip);
|
||||
unprepare_clk:
|
||||
if (!IS_ERR(plgpio->clk))
|
||||
clk_unprepare(plgpio->clk);
|
||||
|
@ -274,12 +274,6 @@ static int spear_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
|
||||
return spear_pinctrl_endisable(pctldev, function, group, true);
|
||||
}
|
||||
|
||||
static void spear_pinctrl_disable(struct pinctrl_dev *pctldev,
|
||||
unsigned function, unsigned group)
|
||||
{
|
||||
spear_pinctrl_endisable(pctldev, function, group, false);
|
||||
}
|
||||
|
||||
/* gpio with pinmux */
|
||||
static struct spear_gpio_pingroup *get_gpio_pingroup(struct spear_pmx *pmx,
|
||||
unsigned pin)
|
||||
@ -345,7 +339,6 @@ static const struct pinmux_ops spear_pinmux_ops = {
|
||||
.get_function_name = spear_pinctrl_get_func_name,
|
||||
.get_function_groups = spear_pinctrl_get_func_groups,
|
||||
.enable = spear_pinctrl_enable,
|
||||
.disable = spear_pinctrl_disable,
|
||||
.gpio_request_enable = gpio_request_enable,
|
||||
.gpio_disable_free = gpio_disable_free,
|
||||
};
|
||||
|
@ -1,36 +1,42 @@
|
||||
if ARCH_SUNXI
|
||||
|
||||
config PINCTRL_SUNXI
|
||||
bool
|
||||
|
||||
config PINCTRL_SUNXI_COMMON
|
||||
bool
|
||||
select PINMUX
|
||||
select GENERIC_PINCONF
|
||||
|
||||
config PINCTRL_SUN4I_A10
|
||||
def_bool PINCTRL_SUNXI || MACH_SUN4I
|
||||
def_bool MACH_SUN4I
|
||||
select PINCTRL_SUNXI_COMMON
|
||||
|
||||
config PINCTRL_SUN5I_A10S
|
||||
def_bool PINCTRL_SUNXI || MACH_SUN5I
|
||||
def_bool MACH_SUN5I
|
||||
select PINCTRL_SUNXI_COMMON
|
||||
|
||||
config PINCTRL_SUN5I_A13
|
||||
def_bool PINCTRL_SUNXI || MACH_SUN5I
|
||||
def_bool MACH_SUN5I
|
||||
select PINCTRL_SUNXI_COMMON
|
||||
|
||||
config PINCTRL_SUN6I_A31
|
||||
def_bool PINCTRL_SUNXI || MACH_SUN6I
|
||||
def_bool MACH_SUN6I
|
||||
select PINCTRL_SUNXI_COMMON
|
||||
|
||||
config PINCTRL_SUN6I_A31_R
|
||||
def_bool PINCTRL_SUNXI || MACH_SUN6I
|
||||
def_bool MACH_SUN6I
|
||||
depends on RESET_CONTROLLER
|
||||
select PINCTRL_SUNXI_COMMON
|
||||
|
||||
config PINCTRL_SUN7I_A20
|
||||
def_bool PINCTRL_SUNXI || MACH_SUN7I
|
||||
def_bool MACH_SUN7I
|
||||
select PINCTRL_SUNXI_COMMON
|
||||
|
||||
config PINCTRL_SUN8I_A23
|
||||
def_bool MACH_SUN8I
|
||||
select PINCTRL_SUNXI_COMMON
|
||||
|
||||
config PINCTRL_SUN8I_A23_R
|
||||
def_bool MACH_SUN8I
|
||||
depends on RESET_CONTROLLER
|
||||
select PINCTRL_SUNXI_COMMON
|
||||
|
||||
endif
|
||||
|
@ -8,3 +8,5 @@ obj-$(CONFIG_PINCTRL_SUN5I_A13) += pinctrl-sun5i-a13.o
|
||||
obj-$(CONFIG_PINCTRL_SUN6I_A31) += pinctrl-sun6i-a31.o
|
||||
obj-$(CONFIG_PINCTRL_SUN6I_A31_R) += pinctrl-sun6i-a31-r.o
|
||||
obj-$(CONFIG_PINCTRL_SUN7I_A20) += pinctrl-sun7i-a20.o
|
||||
obj-$(CONFIG_PINCTRL_SUN8I_A23) += pinctrl-sun8i-a23.o
|
||||
obj-$(CONFIG_PINCTRL_SUN8I_A23_R) += pinctrl-sun8i-a23-r.o
|
||||
|
@ -1010,6 +1010,7 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
|
||||
static const struct sunxi_pinctrl_desc sun4i_a10_pinctrl_data = {
|
||||
.pins = sun4i_a10_pins,
|
||||
.npins = ARRAY_SIZE(sun4i_a10_pins),
|
||||
.irq_banks = 1,
|
||||
};
|
||||
|
||||
static int sun4i_a10_pinctrl_probe(struct platform_device *pdev)
|
||||
|
@ -661,6 +661,7 @@ static const struct sunxi_desc_pin sun5i_a10s_pins[] = {
|
||||
static const struct sunxi_pinctrl_desc sun5i_a10s_pinctrl_data = {
|
||||
.pins = sun5i_a10s_pins,
|
||||
.npins = ARRAY_SIZE(sun5i_a10s_pins),
|
||||
.irq_banks = 1,
|
||||
};
|
||||
|
||||
static int sun5i_a10s_pinctrl_probe(struct platform_device *pdev)
|
||||
|
@ -330,15 +330,12 @@ static const struct sunxi_desc_pin sun5i_a13_pins[] = {
|
||||
/* Hole */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION_IRQ(0x6, 0)), /* EINT0 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION_IRQ(0x6, 1)), /* EINT1 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION_IRQ(0x6, 2)), /* EINT2 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
@ -382,6 +379,7 @@ static const struct sunxi_desc_pin sun5i_a13_pins[] = {
|
||||
static const struct sunxi_pinctrl_desc sun5i_a13_pinctrl_data = {
|
||||
.pins = sun5i_a13_pins,
|
||||
.npins = ARRAY_SIZE(sun5i_a13_pins),
|
||||
.irq_banks = 1,
|
||||
};
|
||||
|
||||
static int sun5i_a13_pinctrl_probe(struct platform_device *pdev)
|
||||
|
@ -93,6 +93,7 @@ static const struct sunxi_pinctrl_desc sun6i_a31_r_pinctrl_data = {
|
||||
.pins = sun6i_a31_r_pins,
|
||||
.npins = ARRAY_SIZE(sun6i_a31_r_pins),
|
||||
.pin_base = PL_BASE,
|
||||
.irq_banks = 2,
|
||||
};
|
||||
|
||||
static int sun6i_a31_r_pinctrl_probe(struct platform_device *pdev)
|
||||
|
@ -24,208 +24,244 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* TXD0 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D0 */
|
||||
SUNXI_FUNCTION(0x4, "uart1")), /* DTR */
|
||||
SUNXI_FUNCTION(0x4, "uart1"), /* DTR */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)), /* PA_EINT0 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 1),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* TXD1 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D1 */
|
||||
SUNXI_FUNCTION(0x4, "uart1")), /* DSR */
|
||||
SUNXI_FUNCTION(0x4, "uart1"), /* DSR */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)), /* PA_EINT1 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 2),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* TXD2 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D2 */
|
||||
SUNXI_FUNCTION(0x4, "uart1")), /* DCD */
|
||||
SUNXI_FUNCTION(0x4, "uart1"), /* DCD */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)), /* PA_EINT2 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 3),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* TXD3 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D3 */
|
||||
SUNXI_FUNCTION(0x4, "uart1")), /* RING */
|
||||
SUNXI_FUNCTION(0x4, "uart1"), /* RING */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)), /* PA_EINT3 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 4),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* TXD4 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D4 */
|
||||
SUNXI_FUNCTION(0x4, "uart1")), /* TX */
|
||||
SUNXI_FUNCTION(0x4, "uart1"), /* TX */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)), /* PA_EINT4 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 5),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* TXD5 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D5 */
|
||||
SUNXI_FUNCTION(0x4, "uart1")), /* RX */
|
||||
SUNXI_FUNCTION(0x4, "uart1"), /* RX */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)), /* PA_EINT5 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 6),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* TXD6 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D6 */
|
||||
SUNXI_FUNCTION(0x4, "uart1")), /* RTS */
|
||||
SUNXI_FUNCTION(0x4, "uart1"), /* RTS */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)), /* PA_EINT6 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 7),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* TXD7 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D7 */
|
||||
SUNXI_FUNCTION(0x4, "uart1")), /* CTS */
|
||||
SUNXI_FUNCTION(0x4, "uart1"), /* CTS */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)), /* PA_EINT7 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 8),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* TXCLK */
|
||||
SUNXI_FUNCTION(0x3, "lcd1")), /* D8 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D8 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)), /* PA_EINT8 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 9),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* TXEN */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D9 */
|
||||
SUNXI_FUNCTION(0x4, "mmc3"), /* CMD */
|
||||
SUNXI_FUNCTION(0x5, "mmc2")), /* CMD */
|
||||
SUNXI_FUNCTION(0x5, "mmc2"), /* CMD */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)), /* PA_EINT9 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 10),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* GTXCLK */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D10 */
|
||||
SUNXI_FUNCTION(0x4, "mmc3"), /* CLK */
|
||||
SUNXI_FUNCTION(0x5, "mmc2")), /* CLK */
|
||||
SUNXI_FUNCTION(0x5, "mmc2"), /* CLK */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 10)), /* PA_EINT10 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 11),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* RXD0 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D11 */
|
||||
SUNXI_FUNCTION(0x4, "mmc3"), /* D0 */
|
||||
SUNXI_FUNCTION(0x5, "mmc2")), /* D0 */
|
||||
SUNXI_FUNCTION(0x5, "mmc2"), /* D0 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 11)), /* PA_EINT11 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 12),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* RXD1 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D12 */
|
||||
SUNXI_FUNCTION(0x4, "mmc3"), /* D1 */
|
||||
SUNXI_FUNCTION(0x5, "mmc2")), /* D1 */
|
||||
SUNXI_FUNCTION(0x5, "mmc2"), /* D1 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 12)), /* PA_EINT12 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 13),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* RXD2 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D13 */
|
||||
SUNXI_FUNCTION(0x4, "mmc3"), /* D2 */
|
||||
SUNXI_FUNCTION(0x5, "mmc2")), /* D2 */
|
||||
SUNXI_FUNCTION(0x5, "mmc2"), /* D2 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 13)), /* PA_EINT13 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 14),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* RXD3 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D14 */
|
||||
SUNXI_FUNCTION(0x4, "mmc3"), /* D3 */
|
||||
SUNXI_FUNCTION(0x5, "mmc2")), /* D3 */
|
||||
SUNXI_FUNCTION(0x5, "mmc2"), /* D3 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 14)), /* PA_EINT14 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 15),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* RXD4 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1")), /* D15 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D15 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 15)), /* PA_EINT15 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 16),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* RXD5 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1")), /* D16 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D16 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 16)), /* PA_EINT16 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 17),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* RXD6 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1")), /* D17 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D17 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 17)), /* PA_EINT17 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 18),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* RXD7 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1")), /* D18 */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D18 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 18)), /* PA_EINT18 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 19),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* RXDV */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D19 */
|
||||
SUNXI_FUNCTION(0x4, "pwm3")), /* Positive */
|
||||
SUNXI_FUNCTION(0x4, "pwm3"), /* Positive */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 19)), /* PA_EINT19 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 20),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* RXCLK */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D20 */
|
||||
SUNXI_FUNCTION(0x4, "pwm3")), /* Negative */
|
||||
SUNXI_FUNCTION(0x4, "pwm3"), /* Negative */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 20)), /* PA_EINT20 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 21),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* TXERR */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D21 */
|
||||
SUNXI_FUNCTION(0x4, "spi3")), /* CS0 */
|
||||
SUNXI_FUNCTION(0x4, "spi3"), /* CS0 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 21)), /* PA_EINT21 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 22),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* RXERR */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D22 */
|
||||
SUNXI_FUNCTION(0x4, "spi3")), /* CLK */
|
||||
SUNXI_FUNCTION(0x4, "spi3"), /* CLK */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 22)), /* PA_EINT22 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 23),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* COL */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* D23 */
|
||||
SUNXI_FUNCTION(0x4, "spi3")), /* MOSI */
|
||||
SUNXI_FUNCTION(0x4, "spi3"), /* MOSI */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 23)), /* PA_EINT23 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 24),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* CRS */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* CLK */
|
||||
SUNXI_FUNCTION(0x4, "spi3")), /* MISO */
|
||||
SUNXI_FUNCTION(0x4, "spi3"), /* MISO */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 24)), /* PA_EINT24 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 25),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* CLKIN */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* DE */
|
||||
SUNXI_FUNCTION(0x4, "spi3")), /* CS1 */
|
||||
SUNXI_FUNCTION(0x4, "spi3"), /* CS1 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 25)), /* PA_EINT25 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 26),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* MDC */
|
||||
SUNXI_FUNCTION(0x3, "lcd1")), /* HSYNC */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* HSYNC */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 26)), /* PA_EINT26 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 27),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "gmac"), /* MDIO */
|
||||
SUNXI_FUNCTION(0x3, "lcd1")), /* VSYNC */
|
||||
SUNXI_FUNCTION(0x3, "lcd1"), /* VSYNC */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 27)), /* PA_EINT27 */
|
||||
/* Hole */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2s0"), /* MCLK */
|
||||
SUNXI_FUNCTION(0x3, "uart3"), /* CTS */
|
||||
SUNXI_FUNCTION(0x4, "csi")), /* MCLK1 */
|
||||
SUNXI_FUNCTION(0x4, "csi"), /* MCLK1 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 0)), /* PB_EINT0 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2s0")), /* BCLK */
|
||||
SUNXI_FUNCTION(0x2, "i2s0"), /* BCLK */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 1)), /* PB_EINT1 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2s0")), /* LRCK */
|
||||
SUNXI_FUNCTION(0x2, "i2s0"), /* LRCK */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 2)), /* PB_EINT2 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2s0")), /* DO0 */
|
||||
SUNXI_FUNCTION(0x2, "i2s0"), /* DO0 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 3)), /* PB_EINT3 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2s0"), /* DO1 */
|
||||
SUNXI_FUNCTION(0x3, "uart3")), /* RTS */
|
||||
SUNXI_FUNCTION(0x3, "uart3"), /* RTS */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 4)), /* PB_EINT4 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2s0"), /* DO2 */
|
||||
SUNXI_FUNCTION(0x3, "uart3"), /* TX */
|
||||
SUNXI_FUNCTION(0x4, "i2c3")), /* SCK */
|
||||
SUNXI_FUNCTION(0x4, "i2c3"), /* SCK */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 5)), /* PB_EINT5 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2s0"), /* DO3 */
|
||||
SUNXI_FUNCTION(0x3, "uart3"), /* RX */
|
||||
SUNXI_FUNCTION(0x4, "i2c3")), /* SDA */
|
||||
SUNXI_FUNCTION(0x4, "i2c3"), /* SDA */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 6)), /* PB_EINT6 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x3, "i2s0")), /* DI */
|
||||
SUNXI_FUNCTION(0x3, "i2s0"), /* DI */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 7)), /* PB_EINT7 */
|
||||
/* Hole */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
@ -510,86 +546,103 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi"), /* PCLK */
|
||||
SUNXI_FUNCTION(0x3, "ts")), /* CLK */
|
||||
SUNXI_FUNCTION(0x3, "ts"), /* CLK */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 0)), /* PE_EINT0 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi"), /* MCLK */
|
||||
SUNXI_FUNCTION(0x3, "ts")), /* ERR */
|
||||
SUNXI_FUNCTION(0x3, "ts"), /* ERR */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 1)), /* PE_EINT1 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi"), /* HSYNC */
|
||||
SUNXI_FUNCTION(0x3, "ts")), /* SYNC */
|
||||
SUNXI_FUNCTION(0x3, "ts"), /* SYNC */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 2)), /* PE_EINT2 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi"), /* VSYNC */
|
||||
SUNXI_FUNCTION(0x3, "ts")), /* DVLD */
|
||||
SUNXI_FUNCTION(0x3, "ts"), /* DVLD */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 3)), /* PE_EINT3 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi"), /* D0 */
|
||||
SUNXI_FUNCTION(0x3, "uart5")), /* TX */
|
||||
SUNXI_FUNCTION(0x3, "uart5"), /* TX */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 4)), /* PE_EINT4 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi"), /* D1 */
|
||||
SUNXI_FUNCTION(0x3, "uart5")), /* RX */
|
||||
SUNXI_FUNCTION(0x3, "uart5"), /* RX */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 5)), /* PE_EINT5 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi"), /* D2 */
|
||||
SUNXI_FUNCTION(0x3, "uart5")), /* RTS */
|
||||
SUNXI_FUNCTION(0x3, "uart5"), /* RTS */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 6)), /* PE_EINT6 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi"), /* D3 */
|
||||
SUNXI_FUNCTION(0x3, "uart5")), /* CTS */
|
||||
SUNXI_FUNCTION(0x3, "uart5"), /* CTS */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 7)), /* PE_EINT7 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi"), /* D4 */
|
||||
SUNXI_FUNCTION(0x3, "ts")), /* D0 */
|
||||
SUNXI_FUNCTION(0x3, "ts"), /* D0 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 8)), /* PE_EINT8 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi"), /* D5 */
|
||||
SUNXI_FUNCTION(0x3, "ts")), /* D1 */
|
||||
SUNXI_FUNCTION(0x3, "ts"), /* D1 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 9)), /* PE_EINT9 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi"), /* D6 */
|
||||
SUNXI_FUNCTION(0x3, "ts")), /* D2 */
|
||||
SUNXI_FUNCTION(0x3, "ts"), /* D2 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 10)), /* PE_EINT10 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi"), /* D7 */
|
||||
SUNXI_FUNCTION(0x3, "ts")), /* D3 */
|
||||
SUNXI_FUNCTION(0x3, "ts"), /* D3 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 11)), /* PE_EINT11 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi"), /* D8 */
|
||||
SUNXI_FUNCTION(0x3, "ts")), /* D4 */
|
||||
SUNXI_FUNCTION(0x3, "ts"), /* D4 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 12)), /* PE_EINT12 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi"), /* D9 */
|
||||
SUNXI_FUNCTION(0x3, "ts")), /* D5 */
|
||||
SUNXI_FUNCTION(0x3, "ts"), /* D5 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 13)), /* PE_EINT13 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi"), /* D10 */
|
||||
SUNXI_FUNCTION(0x3, "ts")), /* D6 */
|
||||
SUNXI_FUNCTION(0x3, "ts"), /* D6 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 14)), /* PE_EINT14 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi"), /* D11 */
|
||||
SUNXI_FUNCTION(0x3, "ts")), /* D7 */
|
||||
SUNXI_FUNCTION(0x3, "ts"), /* D7 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 15)), /* PE_EINT15 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 16),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi")), /* MIPI CSI MCLK */
|
||||
SUNXI_FUNCTION(0x2, "csi"), /* MIPI CSI MCLK */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 16)), /* PE_EINT16 */
|
||||
/* Hole */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
@ -625,86 +678,105 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "mmc1")), /* CLK */
|
||||
SUNXI_FUNCTION(0x2, "mmc1"), /* CLK */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 0)), /* PG_EINT0 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "mmc1")), /* CMD */
|
||||
SUNXI_FUNCTION(0x2, "mmc1"), /* CMD */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 1)), /* PG_EINT1 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "mmc1")), /* D0 */
|
||||
SUNXI_FUNCTION(0x2, "mmc1"), /* D0 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 2)), /* PG_EINT2 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "mmc1")), /* D1 */
|
||||
SUNXI_FUNCTION(0x2, "mmc1"), /* D1 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 3)), /* PG_EINT3 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "mmc1")), /* D2 */
|
||||
SUNXI_FUNCTION(0x2, "mmc1"), /* D2 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 4)), /* PG_EINT4 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "mmc1")), /* D3 */
|
||||
SUNXI_FUNCTION(0x2, "mmc1"), /* D3 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 5)), /* PG_EINT5 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "uart2")), /* TX */
|
||||
SUNXI_FUNCTION(0x2, "uart2"), /* TX */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 6)), /* PG_EINT6 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "uart2")), /* RX */
|
||||
SUNXI_FUNCTION(0x2, "uart2"), /* RX */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 7)), /* PG_EINT7 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "uart2")), /* RTS */
|
||||
SUNXI_FUNCTION(0x2, "uart2"), /* RTS */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 8)), /* PG_EINT8 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "uart2")), /* CTS */
|
||||
SUNXI_FUNCTION(0x2, "uart2"), /* CTS */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 9)), /* PG_EINT9 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2c3"), /* SCK */
|
||||
SUNXI_FUNCTION(0x3, "usb")), /* DP3 */
|
||||
SUNXI_FUNCTION(0x3, "usb"), /* DP3 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 10)), /* PG_EINT10 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2c3"), /* SDA */
|
||||
SUNXI_FUNCTION(0x3, "usb")), /* DM3 */
|
||||
SUNXI_FUNCTION(0x3, "usb"), /* DM3 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 11)), /* PG_EINT11 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "spi1"), /* CS1 */
|
||||
SUNXI_FUNCTION(0x3, "i2s1")), /* MCLK */
|
||||
SUNXI_FUNCTION(0x3, "i2s1"), /* MCLK */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 12)), /* PG_EINT12 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "spi1"), /* CS0 */
|
||||
SUNXI_FUNCTION(0x3, "i2s1")), /* BCLK */
|
||||
SUNXI_FUNCTION(0x3, "i2s1"), /* BCLK */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 13)), /* PG_EINT13 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 14),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "spi1"), /* CLK */
|
||||
SUNXI_FUNCTION(0x3, "i2s1")), /* LRCK */
|
||||
SUNXI_FUNCTION(0x3, "i2s1"), /* LRCK */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 14)), /* PG_EINT14 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 15),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "spi1"), /* MOSI */
|
||||
SUNXI_FUNCTION(0x3, "i2s1")), /* DIN */
|
||||
SUNXI_FUNCTION(0x3, "i2s1"), /* DIN */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 15)), /* PG_EINT15 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 16),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "spi1"), /* MISO */
|
||||
SUNXI_FUNCTION(0x3, "i2s1")), /* DOUT */
|
||||
SUNXI_FUNCTION(0x3, "i2s1"), /* DOUT */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 16)), /* PG_EINT16 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 17),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "uart4")), /* TX */
|
||||
SUNXI_FUNCTION(0x2, "uart4"), /* TX */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 17)), /* PG_EINT17 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 18),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "uart4")), /* RX */
|
||||
SUNXI_FUNCTION(0x2, "uart4"), /* RX */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 18)), /* PG_EINT18 */
|
||||
/* Hole */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
@ -836,6 +908,7 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
|
||||
static const struct sunxi_pinctrl_desc sun6i_a31_pinctrl_data = {
|
||||
.pins = sun6i_a31_pins,
|
||||
.npins = ARRAY_SIZE(sun6i_a31_pins),
|
||||
.irq_banks = 4,
|
||||
};
|
||||
|
||||
static int sun6i_a31_pinctrl_probe(struct platform_device *pdev)
|
||||
|
@ -1036,6 +1036,7 @@ static const struct sunxi_desc_pin sun7i_a20_pins[] = {
|
||||
static const struct sunxi_pinctrl_desc sun7i_a20_pinctrl_data = {
|
||||
.pins = sun7i_a20_pins,
|
||||
.npins = ARRAY_SIZE(sun7i_a20_pins),
|
||||
.irq_banks = 1,
|
||||
};
|
||||
|
||||
static int sun7i_a20_pinctrl_probe(struct platform_device *pdev)
|
||||
|
142
drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c
Normal file
142
drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Allwinner A23 SoCs special pins pinctrl driver.
|
||||
*
|
||||
* Copyright (C) 2014 Chen-Yu Tsai
|
||||
* Chen-Yu Tsai <wens@csie.org>
|
||||
*
|
||||
* Copyright (C) 2014 Boris Brezillon
|
||||
* Boris Brezillon <boris.brezillon@free-electrons.com>
|
||||
*
|
||||
* Copyright (C) 2014 Maxime Ripard
|
||||
* Maxime Ripard <maxime.ripard@free-electrons.com>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/reset.h>
|
||||
|
||||
#include "pinctrl-sunxi.h"
|
||||
|
||||
static const struct sunxi_desc_pin sun8i_a23_r_pins[] = {
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 0),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "s_rsb"), /* SCK */
|
||||
SUNXI_FUNCTION(0x3, "s_twi"), /* SCK */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 0)), /* PL_EINT0 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 1),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "s_rsb"), /* SDA */
|
||||
SUNXI_FUNCTION(0x3, "s_twi"), /* SDA */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 1)), /* PL_EINT1 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 2),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "s_uart"), /* TX */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 2)), /* PL_EINT2 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 3),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "s_uart"), /* RX */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 3)), /* PL_EINT3 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 4),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x3, "s_jtag"), /* MS */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 4)), /* PL_EINT4 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 5),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x3, "s_jtag"), /* CK */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 5)), /* PL_EINT5 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 6),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x3, "s_jtag"), /* DO */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 6)), /* PL_EINT6 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 7),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x3, "s_jtag"), /* DI */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 7)), /* PL_EINT7 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 8),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "s_twi"), /* SCK */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 8)), /* PL_EINT8 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 9),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "s_twi"), /* SDA */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 9)), /* PL_EINT9 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 10),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "s_pwm"),
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 10)), /* PL_EINT10 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 11),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 11)), /* PL_EINT11 */
|
||||
};
|
||||
|
||||
static const struct sunxi_pinctrl_desc sun8i_a23_r_pinctrl_data = {
|
||||
.pins = sun8i_a23_r_pins,
|
||||
.npins = ARRAY_SIZE(sun8i_a23_r_pins),
|
||||
.pin_base = PL_BASE,
|
||||
.irq_banks = 1,
|
||||
};
|
||||
|
||||
static int sun8i_a23_r_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct reset_control *rstc;
|
||||
int ret;
|
||||
|
||||
rstc = devm_reset_control_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(rstc)) {
|
||||
dev_err(&pdev->dev, "Reset controller missing\n");
|
||||
return PTR_ERR(rstc);
|
||||
}
|
||||
|
||||
ret = reset_control_deassert(rstc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = sunxi_pinctrl_init(pdev,
|
||||
&sun8i_a23_r_pinctrl_data);
|
||||
|
||||
if (ret)
|
||||
reset_control_assert(rstc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct of_device_id sun8i_a23_r_pinctrl_match[] = {
|
||||
{ .compatible = "allwinner,sun8i-a23-r-pinctrl", },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sun8i_a23_r_pinctrl_match);
|
||||
|
||||
static struct platform_driver sun8i_a23_r_pinctrl_driver = {
|
||||
.probe = sun8i_a23_r_pinctrl_probe,
|
||||
.driver = {
|
||||
.name = "sun8i-a23-r-pinctrl",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = sun8i_a23_r_pinctrl_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(sun8i_a23_r_pinctrl_driver);
|
||||
|
||||
MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
|
||||
MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com");
|
||||
MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
|
||||
MODULE_DESCRIPTION("Allwinner A23 R_PIO pinctrl driver");
|
||||
MODULE_LICENSE("GPL");
|
593
drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c
Normal file
593
drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c
Normal file
@ -0,0 +1,593 @@
|
||||
/*
|
||||
* Allwinner A23 SoCs pinctrl driver.
|
||||
*
|
||||
* Copyright (C) 2014 Chen-Yu Tsai
|
||||
*
|
||||
* Chen-Yu Tsai <wens@csie.org>
|
||||
*
|
||||
* Copyright (C) 2014 Maxime Ripard
|
||||
*
|
||||
* Maxime Ripard <maxime.ripard@free-electrons.com>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
|
||||
#include "pinctrl-sunxi.h"
|
||||
|
||||
static const struct sunxi_desc_pin sun8i_a23_pins[] = {
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 0),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "spi1"), /* CS */
|
||||
SUNXI_FUNCTION(0x3, "jtag"), /* MS0 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 0)), /* PA_EINT0 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 1),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "spi1"), /* CLK */
|
||||
SUNXI_FUNCTION(0x3, "jtag"), /* CKO */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 1)), /* PA_EINT1 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 2),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "spi1"), /* MOSI */
|
||||
SUNXI_FUNCTION(0x3, "jtag"), /* DOO */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 2)), /* PA_EINT2 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 3),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "spi1"), /* MISO */
|
||||
SUNXI_FUNCTION(0x3, "jtag"), /* DIO */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 3)), /* PA_EINT3 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 4),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "uart4"), /* TX */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 4)), /* PA_EINT4 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 5),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "uart4"), /* RX */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 5)), /* PA_EINT5 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 6),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "uart4"), /* RTS */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 6)), /* PA_EINT6 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 7),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "uart4"), /* CTS */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 7)), /* PA_EINT7 */
|
||||
/* Hole */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "uart2"), /* TX */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 0)), /* PB_EINT0 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "uart2"), /* RX */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 1)), /* PB_EINT1 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "uart2"), /* RTS */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 2)), /* PB_EINT2 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "uart2"), /* CTS */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 3)), /* PB_EINT3 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2s0"), /* SYNC */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 4)), /* PB_EINT4 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2s0"), /* DOUT */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 5)), /* PB_EINT5 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2s0"), /* DIN */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 6)), /* PB_EINT6 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x3, "i2s0"), /* DI */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 7)), /* PB_EINT7 */
|
||||
/* Hole */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "nand0"), /* WE */
|
||||
SUNXI_FUNCTION(0x3, "spi0")), /* MOSI */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "nand0"), /* ALE */
|
||||
SUNXI_FUNCTION(0x3, "spi0")), /* MISO */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "nand0"), /* CLE */
|
||||
SUNXI_FUNCTION(0x3, "spi0")), /* CLK */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "nand0"), /* CE1 */
|
||||
SUNXI_FUNCTION(0x3, "spi0")), /* CS */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "nand0")), /* CE0 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "nand0"), /* RE */
|
||||
SUNXI_FUNCTION(0x3, "mmc2")), /* CLK */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "nand0"), /* RB0 */
|
||||
SUNXI_FUNCTION(0x3, "mmc2")), /* CMD */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "nand0")), /* RB1 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 8),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "nand0"), /* DQ0 */
|
||||
SUNXI_FUNCTION(0x3, "mmc2")), /* D0 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 9),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "nand0"), /* DQ1 */
|
||||
SUNXI_FUNCTION(0x3, "mmc2")), /* D1 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 10),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "nand0"), /* DQ2 */
|
||||
SUNXI_FUNCTION(0x3, "mmc2")), /* D2 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 11),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "nand0"), /* DQ3 */
|
||||
SUNXI_FUNCTION(0x3, "mmc2")), /* D3 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 12),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "nand0"), /* DQ4 */
|
||||
SUNXI_FUNCTION(0x3, "mmc2")), /* D4 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 13),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "nand0"), /* DQ5 */
|
||||
SUNXI_FUNCTION(0x3, "mmc2")), /* D5 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "nand"), /* DQ6 */
|
||||
SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "nand"), /* DQ7 */
|
||||
SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "nand"), /* DQS */
|
||||
SUNXI_FUNCTION(0x3, "mmc2")), /* RST */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 17),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "nand0")), /* CE2 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 18),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "nand0")), /* CE3 */
|
||||
/* Hole */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 0),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0")), /* D0 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 1),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0")), /* D1 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D2 */
|
||||
SUNXI_FUNCTION(0x3, "mmc1")), /* CLK */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 3),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D3 */
|
||||
SUNXI_FUNCTION(0x3, "mmc1")), /* CMD */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 4),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D4 */
|
||||
SUNXI_FUNCTION(0x3, "mmc1")), /* D0 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 5),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D5 */
|
||||
SUNXI_FUNCTION(0x3, "mmc1")), /* D1 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 6),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D6 */
|
||||
SUNXI_FUNCTION(0x3, "mmc1")), /* D2 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 7),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D7 */
|
||||
SUNXI_FUNCTION(0x3, "mmc1")), /* D3 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 8),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D8 */
|
||||
SUNXI_FUNCTION(0x3, "uart3")), /* TX */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 9),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D9 */
|
||||
SUNXI_FUNCTION(0x3, "uart3")), /* RX */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 10),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D10 */
|
||||
SUNXI_FUNCTION(0x3, "uart1")), /* TX */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 11),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D11 */
|
||||
SUNXI_FUNCTION(0x3, "uart1")), /* RX */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 12),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D12 */
|
||||
SUNXI_FUNCTION(0x3, "uart1")), /* RTS */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 13),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D13 */
|
||||
SUNXI_FUNCTION(0x3, "uart1")), /* CTS */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 14),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D14 */
|
||||
SUNXI_FUNCTION(0x3, "i2s1")), /* SYNC */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 15),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D15 */
|
||||
SUNXI_FUNCTION(0x3, "i2s1")), /* CLK */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 16),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D16 */
|
||||
SUNXI_FUNCTION(0x3, "i2s1")), /* DOUT */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 17),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D17 */
|
||||
SUNXI_FUNCTION(0x3, "i2s1")), /* DIN */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 18),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D18 */
|
||||
SUNXI_FUNCTION(0x3, "lvds0")), /* VN0 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 19),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D19 */
|
||||
SUNXI_FUNCTION(0x3, "lvds0")), /* VP0 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 20),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D20 */
|
||||
SUNXI_FUNCTION(0x3, "lvds0")), /* VP1 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 21),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D21 */
|
||||
SUNXI_FUNCTION(0x3, "lvds0")), /* VN1 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 22),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D22 */
|
||||
SUNXI_FUNCTION(0x3, "lvds0")), /* VP2 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 23),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* D23 */
|
||||
SUNXI_FUNCTION(0x3, "lvds0")), /* VN2 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 24),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* CLK */
|
||||
SUNXI_FUNCTION(0x3, "lvds0")), /* VPC */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 25),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* DE */
|
||||
SUNXI_FUNCTION(0x3, "lvds0")), /* VNC */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 26),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* HSYNC */
|
||||
SUNXI_FUNCTION(0x3, "lvds0")), /* VP3 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 27),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "lcd0"), /* VSYNC */
|
||||
SUNXI_FUNCTION(0x3, "lvds0")), /* VN3 */
|
||||
/* Hole */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 0),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi")), /* PCLK */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi")), /* MCLK */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi")), /* HSYNC */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi")), /* VSYNC */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi")), /* D0 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi")), /* D1 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi")), /* D2 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi")), /* D3 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi")), /* D4 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi")), /* D5 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi")), /* D6 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi")), /* D7 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi"), /* SCK */
|
||||
SUNXI_FUNCTION(0x3, "i2c2")), /* SCK */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "csi"), /* SDA */
|
||||
SUNXI_FUNCTION(0x3, "i2c2")), /* SDA */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out")),
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out")),
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 16),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out")),
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 17),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out")),
|
||||
/* Hole */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "mmc0"), /* D1 */
|
||||
SUNXI_FUNCTION(0x3, "jtag")), /* MS1 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "mmc0"), /* D0 */
|
||||
SUNXI_FUNCTION(0x3, "jtag")), /* DI1 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "mmc0"), /* CLK */
|
||||
SUNXI_FUNCTION(0x3, "uart0")), /* TX */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "mmc0"), /* CMD */
|
||||
SUNXI_FUNCTION(0x3, "jtag")), /* DO1 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "mmc0"), /* D3 */
|
||||
SUNXI_FUNCTION(0x3, "uart0")), /* RX */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "mmc0"), /* D2 */
|
||||
SUNXI_FUNCTION(0x3, "jtag")), /* CK1 */
|
||||
/* Hole */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "mmc1"), /* CLK */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 0)), /* PG_EINT0 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "mmc1"), /* CMD */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 1)), /* PG_EINT1 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "mmc1"), /* D0 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 2)), /* PG_EINT2 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "mmc1"), /* D1 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 3)), /* PG_EINT3 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "mmc1"), /* D2 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 4)), /* PG_EINT4 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "mmc1"), /* D3 */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 5)), /* PG_EINT5 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "uart1"), /* TX */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 6)), /* PG_EINT6 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "uart1"), /* RX */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 7)), /* PG_EINT7 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "uart2"), /* RTS */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 8)), /* PG_EINT8 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "uart2"), /* CTS */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 9)), /* PG_EINT9 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2s1"), /* SYNC */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 10)), /* PG_EINT10 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2s1"), /* CLK */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 11)), /* PG_EINT11 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2s1"), /* DOUT */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 12)), /* PG_EINT12 */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2s1"), /* DIN */
|
||||
SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 13)), /* PG_EINT13 */
|
||||
/* Hole */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "pwm0")),
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 1),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "pwm1")),
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 2),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2c0")), /* SCK */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 3),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2c0")), /* SDA */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 4),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2c1")), /* SCK */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 5),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "i2c1")), /* SDA */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 6),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "spi0"), /* CS */
|
||||
SUNXI_FUNCTION(0x3, "uart3")), /* TX */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 7),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "spi0"), /* CLK */
|
||||
SUNXI_FUNCTION(0x3, "uart3")), /* RX */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 8),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "spi0"), /* DOUT */
|
||||
SUNXI_FUNCTION(0x3, "uart3")), /* RTS */
|
||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9),
|
||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||
SUNXI_FUNCTION(0x2, "spi0"), /* DIN */
|
||||
SUNXI_FUNCTION(0x3, "uart3")), /* CTS */
|
||||
};
|
||||
|
||||
static const struct sunxi_pinctrl_desc sun8i_a23_pinctrl_data = {
|
||||
.pins = sun8i_a23_pins,
|
||||
.npins = ARRAY_SIZE(sun8i_a23_pins),
|
||||
.irq_banks = 3,
|
||||
};
|
||||
|
||||
static int sun8i_a23_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
return sunxi_pinctrl_init(pdev,
|
||||
&sun8i_a23_pinctrl_data);
|
||||
}
|
||||
|
||||
static struct of_device_id sun8i_a23_pinctrl_match[] = {
|
||||
{ .compatible = "allwinner,sun8i-a23-pinctrl", },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sun8i_a23_pinctrl_match);
|
||||
|
||||
static struct platform_driver sun8i_a23_pinctrl_driver = {
|
||||
.probe = sun8i_a23_pinctrl_probe,
|
||||
.driver = {
|
||||
.name = "sun8i-a23-pinctrl",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = sun8i_a23_pinctrl_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(sun8i_a23_pinctrl_driver);
|
||||
|
||||
MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
|
||||
MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
|
||||
MODULE_DESCRIPTION("Allwinner A23 pinctrl driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -31,6 +31,9 @@
|
||||
#include "../core.h"
|
||||
#include "pinctrl-sunxi.h"
|
||||
|
||||
static struct irq_chip sunxi_pinctrl_edge_irq_chip;
|
||||
static struct irq_chip sunxi_pinctrl_level_irq_chip;
|
||||
|
||||
static struct sunxi_pinctrl_group *
|
||||
sunxi_pinctrl_find_group_by_name(struct sunxi_pinctrl *pctl, const char *group)
|
||||
{
|
||||
@ -508,7 +511,7 @@ static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc,
|
||||
base = PINS_PER_BANK * gpiospec->args[0];
|
||||
pin = base + gpiospec->args[1];
|
||||
|
||||
if (pin > (gc->base + gc->ngpio))
|
||||
if (pin > gc->ngpio)
|
||||
return -EINVAL;
|
||||
|
||||
if (flags)
|
||||
@ -521,25 +524,61 @@ static int sunxi_pinctrl_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
|
||||
struct sunxi_desc_function *desc;
|
||||
unsigned pinnum = pctl->desc->pin_base + offset;
|
||||
unsigned irqnum;
|
||||
|
||||
if (offset >= chip->ngpio)
|
||||
return -ENXIO;
|
||||
|
||||
desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, offset, "irq");
|
||||
desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, pinnum, "irq");
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n",
|
||||
chip->label, offset + chip->base, desc->irqnum);
|
||||
irqnum = desc->irqbank * IRQ_PER_BANK + desc->irqnum;
|
||||
|
||||
return irq_find_mapping(pctl->domain, desc->irqnum);
|
||||
dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n",
|
||||
chip->label, offset + chip->base, irqnum);
|
||||
|
||||
return irq_find_mapping(pctl->domain, irqnum);
|
||||
}
|
||||
|
||||
|
||||
static int sunxi_pinctrl_irq_set_type(struct irq_data *d,
|
||||
unsigned int type)
|
||||
static int sunxi_pinctrl_irq_request_resources(struct irq_data *d)
|
||||
{
|
||||
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
|
||||
struct sunxi_desc_function *func;
|
||||
int ret;
|
||||
|
||||
func = sunxi_pinctrl_desc_find_function_by_pin(pctl,
|
||||
pctl->irq_array[d->hwirq], "irq");
|
||||
if (!func)
|
||||
return -EINVAL;
|
||||
|
||||
ret = gpio_lock_as_irq(pctl->chip,
|
||||
pctl->irq_array[d->hwirq] - pctl->desc->pin_base);
|
||||
if (ret) {
|
||||
dev_err(pctl->dev, "unable to lock HW IRQ %lu for IRQ\n",
|
||||
irqd_to_hwirq(d));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Change muxing to INT mode */
|
||||
sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sunxi_pinctrl_irq_release_resources(struct irq_data *d)
|
||||
{
|
||||
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
|
||||
|
||||
gpio_unlock_as_irq(pctl->chip,
|
||||
pctl->irq_array[d->hwirq] - pctl->desc->pin_base);
|
||||
}
|
||||
|
||||
static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type)
|
||||
{
|
||||
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
|
||||
struct irq_desc *desc = container_of(d, struct irq_desc, irq_data);
|
||||
u32 reg = sunxi_irq_cfg_reg(d->hwirq);
|
||||
u8 index = sunxi_irq_cfg_offset(d->hwirq);
|
||||
unsigned long flags;
|
||||
@ -566,6 +605,14 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (type & IRQ_TYPE_LEVEL_MASK) {
|
||||
d->chip = &sunxi_pinctrl_level_irq_chip;
|
||||
desc->handle_irq = handle_fasteoi_irq;
|
||||
} else {
|
||||
d->chip = &sunxi_pinctrl_edge_irq_chip;
|
||||
desc->handle_irq = handle_edge_irq;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&pctl->lock, flags);
|
||||
|
||||
regval = readl(pctl->membase + reg);
|
||||
@ -577,26 +624,14 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sunxi_pinctrl_irq_mask_ack(struct irq_data *d)
|
||||
static void sunxi_pinctrl_irq_ack(struct irq_data *d)
|
||||
{
|
||||
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
|
||||
u32 ctrl_reg = sunxi_irq_ctrl_reg(d->hwirq);
|
||||
u8 ctrl_idx = sunxi_irq_ctrl_offset(d->hwirq);
|
||||
u32 status_reg = sunxi_irq_status_reg(d->hwirq);
|
||||
u8 status_idx = sunxi_irq_status_offset(d->hwirq);
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
spin_lock_irqsave(&pctl->lock, flags);
|
||||
|
||||
/* Mask the IRQ */
|
||||
val = readl(pctl->membase + ctrl_reg);
|
||||
writel(val & ~(1 << ctrl_idx), pctl->membase + ctrl_reg);
|
||||
|
||||
/* Clear the IRQ */
|
||||
writel(1 << status_idx, pctl->membase + status_reg);
|
||||
|
||||
spin_unlock_irqrestore(&pctl->lock, flags);
|
||||
}
|
||||
|
||||
static void sunxi_pinctrl_irq_mask(struct irq_data *d)
|
||||
@ -619,19 +654,11 @@ static void sunxi_pinctrl_irq_mask(struct irq_data *d)
|
||||
static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
|
||||
struct sunxi_desc_function *func;
|
||||
u32 reg = sunxi_irq_ctrl_reg(d->hwirq);
|
||||
u8 idx = sunxi_irq_ctrl_offset(d->hwirq);
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
func = sunxi_pinctrl_desc_find_function_by_pin(pctl,
|
||||
pctl->irq_array[d->hwirq],
|
||||
"irq");
|
||||
|
||||
/* Change muxing to INT mode */
|
||||
sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval);
|
||||
|
||||
spin_lock_irqsave(&pctl->lock, flags);
|
||||
|
||||
/* Unmask the IRQ */
|
||||
@ -641,28 +668,60 @@ static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
|
||||
spin_unlock_irqrestore(&pctl->lock, flags);
|
||||
}
|
||||
|
||||
static struct irq_chip sunxi_pinctrl_irq_chip = {
|
||||
static void sunxi_pinctrl_irq_ack_unmask(struct irq_data *d)
|
||||
{
|
||||
sunxi_pinctrl_irq_ack(d);
|
||||
sunxi_pinctrl_irq_unmask(d);
|
||||
}
|
||||
|
||||
static struct irq_chip sunxi_pinctrl_edge_irq_chip = {
|
||||
.irq_ack = sunxi_pinctrl_irq_ack,
|
||||
.irq_mask = sunxi_pinctrl_irq_mask,
|
||||
.irq_mask_ack = sunxi_pinctrl_irq_mask_ack,
|
||||
.irq_unmask = sunxi_pinctrl_irq_unmask,
|
||||
.irq_request_resources = sunxi_pinctrl_irq_request_resources,
|
||||
.irq_release_resources = sunxi_pinctrl_irq_release_resources,
|
||||
.irq_set_type = sunxi_pinctrl_irq_set_type,
|
||||
.flags = IRQCHIP_SKIP_SET_WAKE,
|
||||
};
|
||||
|
||||
static struct irq_chip sunxi_pinctrl_level_irq_chip = {
|
||||
.irq_eoi = sunxi_pinctrl_irq_ack,
|
||||
.irq_mask = sunxi_pinctrl_irq_mask,
|
||||
.irq_unmask = sunxi_pinctrl_irq_unmask,
|
||||
/* Define irq_enable / disable to avoid spurious irqs for drivers
|
||||
* using these to suppress irqs while they clear the irq source */
|
||||
.irq_enable = sunxi_pinctrl_irq_ack_unmask,
|
||||
.irq_disable = sunxi_pinctrl_irq_mask,
|
||||
.irq_request_resources = sunxi_pinctrl_irq_request_resources,
|
||||
.irq_release_resources = sunxi_pinctrl_irq_release_resources,
|
||||
.irq_set_type = sunxi_pinctrl_irq_set_type,
|
||||
.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_EOI_THREADED |
|
||||
IRQCHIP_EOI_IF_HANDLED,
|
||||
};
|
||||
|
||||
static void sunxi_pinctrl_irq_handler(unsigned irq, struct irq_desc *desc)
|
||||
{
|
||||
struct irq_chip *chip = irq_get_chip(irq);
|
||||
struct sunxi_pinctrl *pctl = irq_get_handler_data(irq);
|
||||
const unsigned long reg = readl(pctl->membase + IRQ_STATUS_REG);
|
||||
unsigned long bank, reg, val;
|
||||
|
||||
/* Clear all interrupts */
|
||||
writel(reg, pctl->membase + IRQ_STATUS_REG);
|
||||
for (bank = 0; bank < pctl->desc->irq_banks; bank++)
|
||||
if (irq == pctl->irq[bank])
|
||||
break;
|
||||
|
||||
if (reg) {
|
||||
if (bank == pctl->desc->irq_banks)
|
||||
return;
|
||||
|
||||
reg = sunxi_irq_status_reg_from_bank(bank);
|
||||
val = readl(pctl->membase + reg);
|
||||
|
||||
if (val) {
|
||||
int irqoffset;
|
||||
|
||||
chained_irq_enter(chip, desc);
|
||||
for_each_set_bit(irqoffset, ®, SUNXI_IRQ_NUMBER) {
|
||||
int pin_irq = irq_find_mapping(pctl->domain, irqoffset);
|
||||
for_each_set_bit(irqoffset, &val, IRQ_PER_BANK) {
|
||||
int pin_irq = irq_find_mapping(pctl->domain,
|
||||
bank * IRQ_PER_BANK + irqoffset);
|
||||
generic_handle_irq(pin_irq);
|
||||
}
|
||||
chained_irq_exit(chip, desc);
|
||||
@ -730,8 +789,11 @@ static int sunxi_pinctrl_build_state(struct platform_device *pdev)
|
||||
|
||||
while (func->name) {
|
||||
/* Create interrupt mapping while we're at it */
|
||||
if (!strcmp(func->name, "irq"))
|
||||
pctl->irq_array[func->irqnum] = pin->pin.number;
|
||||
if (!strcmp(func->name, "irq")) {
|
||||
int irqnum = func->irqnum + func->irqbank * IRQ_PER_BANK;
|
||||
pctl->irq_array[irqnum] = pin->pin.number;
|
||||
}
|
||||
|
||||
sunxi_pinctrl_add_function(pctl, func->name);
|
||||
func++;
|
||||
}
|
||||
@ -801,6 +863,13 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
|
||||
pctl->dev = &pdev->dev;
|
||||
pctl->desc = desc;
|
||||
|
||||
pctl->irq_array = devm_kcalloc(&pdev->dev,
|
||||
IRQ_PER_BANK * pctl->desc->irq_banks,
|
||||
sizeof(*pctl->irq_array),
|
||||
GFP_KERNEL);
|
||||
if (!pctl->irq_array)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = sunxi_pinctrl_build_state(pdev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "dt probe failed: %d\n", ret);
|
||||
@ -869,7 +938,7 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
|
||||
const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
|
||||
|
||||
ret = gpiochip_add_pin_range(pctl->chip, dev_name(&pdev->dev),
|
||||
pin->pin.number,
|
||||
pin->pin.number - pctl->desc->pin_base,
|
||||
pin->pin.number, 1);
|
||||
if (ret)
|
||||
goto gpiochip_error;
|
||||
@ -885,30 +954,51 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
|
||||
if (ret)
|
||||
goto gpiochip_error;
|
||||
|
||||
pctl->irq = irq_of_parse_and_map(node, 0);
|
||||
pctl->irq = devm_kcalloc(&pdev->dev,
|
||||
pctl->desc->irq_banks,
|
||||
sizeof(*pctl->irq),
|
||||
GFP_KERNEL);
|
||||
if (!pctl->irq) {
|
||||
ret = -EINVAL;
|
||||
ret = -ENOMEM;
|
||||
goto clk_error;
|
||||
}
|
||||
|
||||
pctl->domain = irq_domain_add_linear(node, SUNXI_IRQ_NUMBER,
|
||||
&irq_domain_simple_ops, NULL);
|
||||
for (i = 0; i < pctl->desc->irq_banks; i++) {
|
||||
pctl->irq[i] = platform_get_irq(pdev, i);
|
||||
if (pctl->irq[i] < 0) {
|
||||
ret = pctl->irq[i];
|
||||
goto clk_error;
|
||||
}
|
||||
}
|
||||
|
||||
pctl->domain = irq_domain_add_linear(node,
|
||||
pctl->desc->irq_banks * IRQ_PER_BANK,
|
||||
&irq_domain_simple_ops,
|
||||
NULL);
|
||||
if (!pctl->domain) {
|
||||
dev_err(&pdev->dev, "Couldn't register IRQ domain\n");
|
||||
ret = -ENOMEM;
|
||||
goto clk_error;
|
||||
}
|
||||
|
||||
for (i = 0; i < SUNXI_IRQ_NUMBER; i++) {
|
||||
for (i = 0; i < (pctl->desc->irq_banks * IRQ_PER_BANK); i++) {
|
||||
int irqno = irq_create_mapping(pctl->domain, i);
|
||||
|
||||
irq_set_chip_and_handler(irqno, &sunxi_pinctrl_irq_chip,
|
||||
handle_simple_irq);
|
||||
irq_set_chip_and_handler(irqno, &sunxi_pinctrl_edge_irq_chip,
|
||||
handle_edge_irq);
|
||||
irq_set_chip_data(irqno, pctl);
|
||||
};
|
||||
|
||||
irq_set_chained_handler(pctl->irq, sunxi_pinctrl_irq_handler);
|
||||
irq_set_handler_data(pctl->irq, pctl);
|
||||
for (i = 0; i < pctl->desc->irq_banks; i++) {
|
||||
/* Mask and clear all IRQs before registering a handler */
|
||||
writel(0, pctl->membase + sunxi_irq_ctrl_reg_from_bank(i));
|
||||
writel(0xffffffff,
|
||||
pctl->membase + sunxi_irq_status_reg_from_bank(i));
|
||||
|
||||
irq_set_chained_handler(pctl->irq[i],
|
||||
sunxi_pinctrl_irq_handler);
|
||||
irq_set_handler_data(pctl->irq[i], pctl);
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "initialized sunXi PIO driver\n");
|
||||
|
||||
@ -917,8 +1007,7 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
|
||||
clk_error:
|
||||
clk_disable_unprepare(clk);
|
||||
gpiochip_error:
|
||||
if (gpiochip_remove(pctl->chip))
|
||||
dev_err(&pdev->dev, "failed to remove gpio chip\n");
|
||||
gpiochip_remove(pctl->chip);
|
||||
pinctrl_error:
|
||||
pinctrl_unregister(pctl->pctl_dev);
|
||||
return ret;
|
||||
|
@ -53,7 +53,7 @@
|
||||
#define PULL_PINS_BITS 2
|
||||
#define PULL_PINS_MASK 0x03
|
||||
|
||||
#define SUNXI_IRQ_NUMBER 32
|
||||
#define IRQ_PER_BANK 32
|
||||
|
||||
#define IRQ_CFG_REG 0x200
|
||||
#define IRQ_CFG_IRQ_PER_REG 8
|
||||
@ -68,6 +68,8 @@
|
||||
#define IRQ_STATUS_IRQ_BITS 1
|
||||
#define IRQ_STATUS_IRQ_MASK ((1 << IRQ_STATUS_IRQ_BITS) - 1)
|
||||
|
||||
#define IRQ_MEM_SIZE 0x20
|
||||
|
||||
#define IRQ_EDGE_RISING 0x00
|
||||
#define IRQ_EDGE_FALLING 0x01
|
||||
#define IRQ_LEVEL_HIGH 0x02
|
||||
@ -77,6 +79,7 @@
|
||||
struct sunxi_desc_function {
|
||||
const char *name;
|
||||
u8 muxval;
|
||||
u8 irqbank;
|
||||
u8 irqnum;
|
||||
};
|
||||
|
||||
@ -89,6 +92,7 @@ struct sunxi_pinctrl_desc {
|
||||
const struct sunxi_desc_pin *pins;
|
||||
int npins;
|
||||
unsigned pin_base;
|
||||
unsigned irq_banks;
|
||||
};
|
||||
|
||||
struct sunxi_pinctrl_function {
|
||||
@ -113,8 +117,8 @@ struct sunxi_pinctrl {
|
||||
unsigned nfunctions;
|
||||
struct sunxi_pinctrl_group *groups;
|
||||
unsigned ngroups;
|
||||
int irq;
|
||||
int irq_array[SUNXI_IRQ_NUMBER];
|
||||
int *irq;
|
||||
unsigned *irq_array;
|
||||
spinlock_t lock;
|
||||
struct pinctrl_dev *pctl_dev;
|
||||
};
|
||||
@ -139,6 +143,14 @@ struct sunxi_pinctrl {
|
||||
.irqnum = _irq, \
|
||||
}
|
||||
|
||||
#define SUNXI_FUNCTION_IRQ_BANK(_val, _bank, _irq) \
|
||||
{ \
|
||||
.name = "irq", \
|
||||
.muxval = _val, \
|
||||
.irqbank = _bank, \
|
||||
.irqnum = _irq, \
|
||||
}
|
||||
|
||||
/*
|
||||
* The sunXi PIO registers are organized as is:
|
||||
* 0x00 - 0x0c Muxing values.
|
||||
@ -218,8 +230,10 @@ static inline u32 sunxi_pull_offset(u16 pin)
|
||||
|
||||
static inline u32 sunxi_irq_cfg_reg(u16 irq)
|
||||
{
|
||||
u8 reg = irq / IRQ_CFG_IRQ_PER_REG * 0x04;
|
||||
return reg + IRQ_CFG_REG;
|
||||
u8 bank = irq / IRQ_PER_BANK;
|
||||
u8 reg = (irq % IRQ_PER_BANK) / IRQ_CFG_IRQ_PER_REG * 0x04;
|
||||
|
||||
return IRQ_CFG_REG + bank * IRQ_MEM_SIZE + reg;
|
||||
}
|
||||
|
||||
static inline u32 sunxi_irq_cfg_offset(u16 irq)
|
||||
@ -228,10 +242,16 @@ static inline u32 sunxi_irq_cfg_offset(u16 irq)
|
||||
return irq_num * IRQ_CFG_IRQ_BITS;
|
||||
}
|
||||
|
||||
static inline u32 sunxi_irq_ctrl_reg_from_bank(u8 bank)
|
||||
{
|
||||
return IRQ_CTRL_REG + bank * IRQ_MEM_SIZE;
|
||||
}
|
||||
|
||||
static inline u32 sunxi_irq_ctrl_reg(u16 irq)
|
||||
{
|
||||
u8 reg = irq / IRQ_CTRL_IRQ_PER_REG * 0x04;
|
||||
return reg + IRQ_CTRL_REG;
|
||||
u8 bank = irq / IRQ_PER_BANK;
|
||||
|
||||
return sunxi_irq_ctrl_reg_from_bank(bank);
|
||||
}
|
||||
|
||||
static inline u32 sunxi_irq_ctrl_offset(u16 irq)
|
||||
@ -240,10 +260,16 @@ static inline u32 sunxi_irq_ctrl_offset(u16 irq)
|
||||
return irq_num * IRQ_CTRL_IRQ_BITS;
|
||||
}
|
||||
|
||||
static inline u32 sunxi_irq_status_reg_from_bank(u8 bank)
|
||||
{
|
||||
return IRQ_STATUS_REG + bank * IRQ_MEM_SIZE;
|
||||
}
|
||||
|
||||
static inline u32 sunxi_irq_status_reg(u16 irq)
|
||||
{
|
||||
u8 reg = irq / IRQ_STATUS_IRQ_PER_REG * 0x04;
|
||||
return reg + IRQ_STATUS_REG;
|
||||
u8 bank = irq / IRQ_PER_BANK;
|
||||
|
||||
return sunxi_irq_status_reg_from_bank(bank);
|
||||
}
|
||||
|
||||
static inline u32 sunxi_irq_status_offset(u16 irq)
|
||||
|
@ -141,17 +141,6 @@ static int wmt_pmx_enable(struct pinctrl_dev *pctldev,
|
||||
return wmt_set_pinmux(data, func_selector, pinnum);
|
||||
}
|
||||
|
||||
static void wmt_pmx_disable(struct pinctrl_dev *pctldev,
|
||||
unsigned func_selector,
|
||||
unsigned group_selector)
|
||||
{
|
||||
struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev);
|
||||
u32 pinnum = data->pins[group_selector].number;
|
||||
|
||||
/* disable by setting GPIO_IN */
|
||||
wmt_set_pinmux(data, WMT_FSEL_GPIO_IN, pinnum);
|
||||
}
|
||||
|
||||
static void wmt_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
unsigned offset)
|
||||
@ -180,7 +169,6 @@ static struct pinmux_ops wmt_pinmux_ops = {
|
||||
.get_function_name = wmt_pmx_get_function_name,
|
||||
.get_function_groups = wmt_pmx_get_function_groups,
|
||||
.enable = wmt_pmx_enable,
|
||||
.disable = wmt_pmx_disable,
|
||||
.gpio_disable_free = wmt_pmx_gpio_disable_free,
|
||||
.gpio_set_direction = wmt_pmx_gpio_set_direction,
|
||||
};
|
||||
@ -627,8 +615,7 @@ int wmt_pinctrl_probe(struct platform_device *pdev,
|
||||
return 0;
|
||||
|
||||
fail_range:
|
||||
if (gpiochip_remove(&data->gpio_chip))
|
||||
dev_err(&pdev->dev, "failed to remove gpio chip\n");
|
||||
gpiochip_remove(&data->gpio_chip);
|
||||
fail_gpio:
|
||||
pinctrl_unregister(data->pctl_dev);
|
||||
return err;
|
||||
@ -637,12 +624,8 @@ fail_gpio:
|
||||
int wmt_pinctrl_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct wmt_pinctrl_data *data = platform_get_drvdata(pdev);
|
||||
int err;
|
||||
|
||||
err = gpiochip_remove(&data->gpio_chip);
|
||||
if (err)
|
||||
dev_err(&pdev->dev, "failed to remove gpio chip\n");
|
||||
|
||||
gpiochip_remove(&data->gpio_chip);
|
||||
pinctrl_unregister(data->pctl_dev);
|
||||
|
||||
return 0;
|
||||
|
@ -70,8 +70,6 @@ struct pinmux_ops {
|
||||
unsigned * const num_groups);
|
||||
int (*enable) (struct pinctrl_dev *pctldev, unsigned func_selector,
|
||||
unsigned group_selector);
|
||||
void (*disable) (struct pinctrl_dev *pctldev, unsigned func_selector,
|
||||
unsigned group_selector);
|
||||
int (*gpio_request_enable) (struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
unsigned offset);
|
||||
|
Loading…
x
Reference in New Issue
Block a user