This is the bulk of pin control changes for the v4.1 development

cycle:
 
 New drivers:
   - Intel Sunrisepoint
   - AMD KERNCZ GPIO
   - Broadcom Cygnus IOMUX
 
 New subdrivers:
   - Marvell MVEBU Armada 39x SoCs
   - Samsung Exynos 5433
   - nVidia Tegra 210
   - Mediatek MT8135
   - Mediatek MT8173
   - AMLogic Meson8b
   - Qualcomm PM8916
 
 On top of this cleanups and development history for the above
 drivers as issues were fixed after merging.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJVLSiSAAoJEEEQszewGV1z/nMP/jXyxCb8THuAyCFkJoY+Hgzz
 dj3eMt+TPPyqt6lG3WODq/lQFxEdE28TqHYf2eGVdpriCpuyecFxyf9MPzY3P60E
 v6XfzIeUOIGovw781qsg9TxJAZ0C+DLmNgpS8kWhnK7Igs3EJrRcz5Zz00F32olv
 1dojVIQF6Nsn3M2Cc6bzF2wkJre3tLsUT7KXGZw4e3yA0K1XMZI3jYYXZ25GgLW0
 CpZ1vKdKgwuBsgV5waJ8XZuFMqo3FRhjcD/f8ubk5hhMK6Wx6gszBcrLKVlkbz+2
 XJzhn5tZSupSKmBtl0gCzP7pgVc0JeV8P12hHv6imT82rCU0YGBidNX2s3GrscnF
 Nfwpw/BsaOXcu9CttI5LndvDlvCH2hUAal6i4IghiL5sRzlcW4jUoWHkIa8e6dHe
 e/zjJSo7tXrWio30Dl6++qklcDimP3sbaaFseENhLUSl7hDGJ09Tx8yxEOFN3PX6
 29i7ZC+ifZFzS30E3E+MOlFrxp3MB7j/z/ig3HL7XYr/TTiCKMNbKJNOlmGEfiTV
 VI3GvTAJgt/1U+AOJI7a5xrxivaGL5GWXuoonQHY1gPrvjqkL54w4j+XBpj4tXIV
 LBh6AS6G6AJDUOEU00EroCxOt1FPMW24zQvTKP18sgXsKWqHTIKT9B5RZbDXM9D7
 pLfOIy0H1RWdQGvGgK7X
 =MGqe
 -----END PGP SIGNATURE-----

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

Pull pincontrol updates from Linus Walleij:
 "This is the bulk of pin control changes for the v4.1 development
  cycle.  Nothing really exciting this time: we basically added a few
  new drivers and subdrivers and stabilized them in linux-next.  Some
  cleanups too.  With sunrisepoint Intel has a real fine fully featured
  pin control driver for contemporary hardware, and the AMD driver is
  also for large deployments.  Most of the others are ARM devices.

  New drivers:
    - Intel Sunrisepoint
    - AMD KERNCZ GPIO
    - Broadcom Cygnus IOMUX

  New subdrivers:
    - Marvell MVEBU Armada 39x SoCs
    - Samsung Exynos 5433
    - nVidia Tegra 210
    - Mediatek MT8135
    - Mediatek MT8173
    - AMLogic Meson8b
    - Qualcomm PM8916

  On top of this cleanups and development history for the above drivers
  as issues were fixed after merging"

* tag 'pinctrl-v4.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (71 commits)
  pinctrl: sirf: move sgpio lock into state container
  pinctrl: Add support for PM8916 GPIO's and MPP's
  pinctrl: bcm2835: Fix support for threaded level triggered IRQs
  sh-pfc: r8a7790: add EtherAVB pin groups
  pinctrl: Document "function" + "pins" pinmux binding
  pinctrl: intel: Add Intel Sunrisepoint pin controller and GPIO support
  pinctrl: fsl: imx: Check for 0 config register
  pinctrl: Add support for Meson8b
  documentation: Extend pinctrl docs for Meson8b
  pinctrl: Cleanup Meson8 driver
  Fix inconsistent spinlock of AMD GPIO driver which can be recognized by static analysis tool smatch. Declare constant Variables with Sparse's suggestion.
  pinctrl: at91: convert __raw to endian agnostic IO
  pinctrl: constify of_device_id array
  pinctrl: pinconf-generic: add dt node names to error messages
  pinctrl: pinconf-generic: scan also referenced phandle node
  pinctrl: mvebu: add suspend/resume support to Armada XP pinctrl driver
  pinctrl: st: Display pin's function when printing pinctrl debug information
  pinctrl: st: Show correct pin direction also in GPIO mode
  pinctrl: st: Supply a GPIO get_direction() call-back
  pinctrl: st: Move st_get_pio_control() further up the source file
  ...
This commit is contained in:
Linus Torvalds 2015-04-14 17:58:15 -07:00
Родитель b240452a0f 1dfe0d159d
Коммит 07e492eb89
96 изменённых файлов: 15302 добавлений и 936 удалений

Просмотреть файл

@ -0,0 +1,98 @@
Broadcom Cygnus GPIO/PINCONF Controller
Required properties:
- compatible:
Must be "brcm,cygnus-ccm-gpio", "brcm,cygnus-asiu-gpio", or
"brcm,cygnus-crmu-gpio"
- reg:
Define the base and range of the I/O address space that contains the Cygnus
GPIO/PINCONF controller registers
- #gpio-cells:
Must be two. The first cell is the GPIO pin number (within the
controller's pin space) and the second cell is used for the following:
bit[0]: polarity (0 for active high and 1 for active low)
- gpio-controller:
Specifies that the node is a GPIO controller
Optional properties:
- interrupts:
Interrupt ID
- interrupt-controller:
Specifies that the node is an interrupt controller
- pinmux:
Specifies the phandle to the IOMUX device, where pins can be individually
muxed to GPIO
Supported generic PINCONF properties in child nodes:
- pins:
The list of pins (within the controller's own pin space) that properties
in the node apply to. Pin names are "gpio-<pin>"
- bias-disable:
Disable pin bias
- bias-pull-up:
Enable internal pull up resistor
- bias-pull-down:
Enable internal pull down resistor
- drive-strength:
Valid drive strength values include 2, 4, 6, 8, 10, 12, 14, 16 (mA)
Example:
gpio_ccm: gpio@1800a000 {
compatible = "brcm,cygnus-ccm-gpio";
reg = <0x1800a000 0x50>,
<0x0301d164 0x20>;
#gpio-cells = <2>;
gpio-controller;
interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
touch_pins: touch_pins {
pwr: pwr {
pins = "gpio-0";
drive-strength = <16>;
};
event: event {
pins = "gpio-1";
bias-pull-up;
};
};
};
gpio_asiu: gpio@180a5000 {
compatible = "brcm,cygnus-asiu-gpio";
reg = <0x180a5000 0x668>;
#gpio-cells = <2>;
gpio-controller;
interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
};
/*
* Touchscreen that uses the CCM GPIO 0 and 1
*/
tsc {
...
...
gpio-pwr = <&gpio_ccm 0 0>;
gpio-event = <&gpio_ccm 1 0>;
};
/* Bluetooth that uses the ASIU GPIO 5, with polarity inverted */
bluetooth {
...
...
bcm,rfkill-bank-sel = <&gpio_asiu 5 1>
}

Просмотреть файл

@ -0,0 +1,132 @@
Broadcom Cygnus IOMUX Controller
The Cygnus IOMUX controller supports group based mux configuration. In
addition, certain pins can be muxed to GPIO function individually.
Required properties:
- compatible:
Must be "brcm,cygnus-pinmux"
- reg:
Define the base and range of the I/O address space that contains the Cygnus
IOMUX registers
Properties in subnodes:
- function:
The mux function to select
- groups:
The list of groups to select with a given function
For more details, refer to
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
For example:
pinmux: pinmux@0x0301d0c8 {
compatible = "brcm,cygnus-pinmux";
reg = <0x0301d0c8 0x1b0>;
pinctrl-names = "default";
pinctrl-0 = <&i2s0_default>;
i2s0_default: i2s0_default {
mux {
function = "i2s0";
groups = "i2s0_0_grp", "i2s0_1_grp";
};
};
};
List of supported functions and groups in Cygnus:
"i2s0": "i2s0_0_grp", "i2s0_1_grp"
"i2s1": "i2s1_0_grp", "i2s1_1_grp"
"i2s2": "i2s2_0_grp", "i2s2_1_grp", "i2s2_2_grp", "i2s2_3_grp", "i2s2_4_grp"
"spdif": "spdif_grp"
"pwm0": "pwm0_grp"
"pwm1": "pwm1_grp"
"pwm2": "pwm2_grp"
"pwm3": "pwm3_grp"
"pwm4": "pwm4_grp"
"pwm5": "pwm5_grp"
"key": "key0_grp", "key1_grp", "key2_grp", "key3_grp", "key4_grp", "key5_grp",
"key6_grp", "key7_grp", "key8_grp", "key9_grp", "key10_grp", "key11_grp",
"key12_grp", "key13_grp", "key14_grp", "key15_grp"
"audio_dte": "audio_dte0_grp", "audio_dte1_grp", "audio_dte2_grp", "audio_dte3_grp"
"smart_card0": "smart_card0_grp", "smart_card0_fcb_grp"
"smart_card1": "smart_card1_grp", "smart_card1_fcb_grp"
"spi0": "spi0_grp"
"spi1": "spi1_grp"
"spi2": "spi2_grp"
"spi3": "spi3_grp"
"spi4": "spi4_0_grp", "spi4_1_grp"
"spi5": "spi5_grp"
"sw_led0": "sw_led0_0_grp", "sw_led0_1_grp"
"sw_led1": "sw_led1_grp"
"sw_led2": "sw_led2_0_grp", "sw_led2_1_grp"
"d1w": "d1w_grp"
"lcd": "lcd_grp"
"sram": "sram_0_grp", "sram_1_grp"
"uart0": "uart0_grp"
"uart1": "uart1_grp", "uart1_dte_grp"
"uart2": "uart2_grp"
"uart3": "uart3_grp"
"uart4": "uart4_grp"
"qspi": "qspi_0_grp", "qspi_1_grp"
"nand": "nand_grp"
"sdio0": "sdio0_grp", "sdio0_cd_grp", "sdio0_mmc_grp"
"sdio1": "sdio1_data_0_grp", "sdio1_data_1_grp", "sdio1_cd_grp",
"sdio1_led_grp", "sdio1_mmc_grp"
"can0": "can0_grp"
"can1": "can1_grp"
"cam": "cam_led_grp", "cam_0_grp", "cam_1_grp"
"bsc1": "bsc1_grp"
"pcie_clkreq": "pcie_clkreq_grp"
"usb0_oc": "usb0_oc_grp"
"usb1_oc": "usb1_oc_grp"
"usb2_oc": "usb2_oc_grp"

Просмотреть файл

@ -0,0 +1,78 @@
* Marvell Armada 39x SoC pinctrl driver for mpp
Please refer to marvell,mvebu-pinctrl.txt in this directory for common binding
part and usage.
Required properties:
- compatible: "marvell,88f6920-pinctrl", "marvell,88f6928-pinctrl"
depending on the specific variant of the SoC being used.
- reg: register specifier of MPP registers
Available mpp pins/groups and functions:
Note: brackets (x) are not part of the mpp name for marvell,function and given
only for more detailed description in this document.
name pins functions
================================================================================
mpp0 0 gpio, ua0(rxd)
mpp1 1 gpio, ua0(txd)
mpp2 2 gpio, i2c0(sck)
mpp3 3 gpio, i2c0(sda)
mpp4 4 gpio, ua1(txd), ua0(rts), smi(mdc)
mpp5 5 gpio, ua1(rxd), ua0(cts), smi(mdio)
mpp6 6 gpio, dev(cs3), xsmi(mdio)
mpp7 7 gpio, dev(ad9), xsmi(mdc)
mpp8 8 gpio, dev(ad10), ptp(trig)
mpp9 9 gpio, dev(ad11), ptp(clk)
mpp10 10 gpio, dev(ad12), ptp(event)
mpp11 11 gpio, dev(ad13), led(clk)
mpp12 12 gpio, pcie0(rstout), dev(ad14), led(stb)
mpp13 13 gpio, dev(ad15), led(data)
mpp14 14 gpio, m(vtt), dev(wen1), ua1(txd)
mpp15 15 gpio, pcie0(rstout), spi0(mosi), i2c1(sck)
mpp16 16 gpio, m(decc), spi0(miso), i2c1(sda)
mpp17 17 gpio, ua1(rxd), spi0(sck), smi(mdio)
mpp18 18 gpio, ua1(txd), spi0(cs0), i2c2(sck)
mpp19 19 gpio, sata1(present) [1], ua0(cts), ua1(rxd), i2c2(sda)
mpp20 20 gpio, sata0(present) [1], ua0(rts), ua1(txd), smi(mdc)
mpp21 21 gpio, spi0(cs1), sata0(present) [1], sd(cmd), dev(bootcs), ge(rxd0)
mpp22 22 gpio, spi0(mosi), dev(ad0)
mpp23 23 gpio, spi0(sck), dev(ad2)
mpp24 24 gpio, spi0(miso), ua0(cts), ua1(rxd), sd(d4), dev(readyn)
mpp25 25 gpio, spi0(cs0), ua0(rts), ua1(txd), sd(d5), dev(cs0)
mpp26 26 gpio, spi0(cs2), i2c1(sck), sd(d6), dev(cs1)
mpp27 27 gpio, spi0(cs3), i2c1(sda), sd(d7), dev(cs2), ge(txclkout)
mpp28 28 gpio, sd(clk), dev(ad5), ge(txd0)
mpp29 29 gpio, dev(ale0), ge(txd1)
mpp30 30 gpio, dev(oen), ge(txd2)
mpp31 31 gpio, dev(ale1), ge(txd3)
mpp32 32 gpio, dev(wen0), ge(txctl)
mpp33 33 gpio, m(decc), dev(ad3)
mpp34 34 gpio, dev(ad1)
mpp35 35 gpio, ref(clk), dev(a1)
mpp36 36 gpio, dev(a0)
mpp37 37 gpio, sd(d3), dev(ad8), ge(rxclk)
mpp38 38 gpio, ref(clk), sd(d0), dev(ad4), ge(rxd1)
mpp39 39 gpio, i2c1(sck), ua0(cts), sd(d1), dev(a2), ge(rxd2)
mpp40 40 gpio, i2c1(sda), ua0(rts), sd(d2), dev(ad6), ge(rxd3)
mpp41 41 gpio, ua1(rxd), ua0(cts), spi1(cs3), dev(burstn), nd(rbn0), ge(rxctl)
mpp42 42 gpio, ua1(txd), ua0(rts), dev(ad7)
mpp43 43 gpio, pcie0(clkreq), m(vtt), m(decc), spi1(cs2), dev(clkout), nd(rbn1)
mpp44 44 gpio, sata0(present) [1], sata1(present) [1], led(clk)
mpp45 45 gpio, ref(clk), pcie0(rstout), ua1(rxd)
mpp46 46 gpio, ref(clk), pcie0(rstout), ua1(txd), led(stb)
mpp47 47 gpio, sata0(present) [1], sata1(present) [1], led(data)
mpp48 48 gpio, sata0(present) [1], m(vtt), tdm(pclk) [1], audio(mclk) [1], sd(d4), pcie0(clkreq), ua1(txd)
mpp49 49 gpio, tdm(fsync) [1], audio(lrclk) [1], sd(d5), ua2(rxd)
mpp50 50 gpio, pcie0(rstout), tdm(drx) [1], audio(extclk) [1], sd(cmd), ua2(rxd)
mpp51 51 gpio, tdm(dtx) [1], audio(sdo) [1], m(decc), ua2(txd)
mpp52 52 gpio, pcie0(rstout), tdm(intn) [1], audio(sdi) [1], sd(d6), i2c3(sck)
mpp53 53 gpio, sata1(present) [1], sata0(present) [1], tdm(rstn) [1], audio(bclk) [1], sd(d7), i2c3(sda)
mpp54 54 gpio, sata0(present) [1], sata1(present) [1], pcie0(rstout), sd(d3), ua3(txd)
mpp55 55 gpio, ua1(cts), spi1(cs1), sd(d0), ua1(rxd), ua3(rxd)
mpp56 56 gpio, ua1(rts), m(decc), spi1(mosi), ua1(txd)
mpp57 57 gpio, spi1(sck), sd(clk), ua1(txd)
mpp58 58 gpio, i2c1(sck), pcie2(clkreq), spi1(miso), sd(d1), ua1(rxd)
mpp59 59 gpio, pcie0(rstout), i2c1(sda), spi1(cs0), sd(d2)
[1]: only available on 88F6928

Просмотреть файл

@ -1,7 +1,7 @@
== Amlogic Meson pinmux controller ==
Required properties for the root node:
- compatible: "amlogic,meson8-pinctrl"
- compatible: "amlogic,meson8-pinctrl" or "amlogic,meson8b-pinctrl"
- reg: address and size of registers controlling irq functionality
=== GPIO sub-nodes ===

Просмотреть файл

@ -0,0 +1,166 @@
NVIDIA Tegra210 pinmux controller
Required properties:
- compatible: "nvidia,tegra210-pinmux"
- reg: Should contain a list of base address and size pairs for:
- first entry: The APB_MISC_GP_*_PADCTRL registers (pad control)
- second entry: The PINMUX_AUX_* registers (pinmux)
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".
Tegra's pin configuration nodes act as a container for an arbitrary number of
subnodes. Each of these subnodes represents some desired configuration for a
pin, a group, or a list of pins or groups. This configuration can include the
mux function to select on those pin(s)/group(s), and various pin configuration
parameters, such as pull-up, tristate, drive strength, etc.
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 or tristate parameter. For this
reason, even seemingly boolean values are actually tristates in this binding:
unspecified, off, or on. Unspecified is represented as an absent property,
and off/on are represented as integer values 0 and 1.
See the TRM to determine which properties and values apply to each pin/group.
Macro values for property values are defined in
include/dt-binding/pinctrl/pinctrl-tegra.h.
Required subnode-properties:
- nvidia,pins : An array of strings. Each string contains the name of a pin or
group. Valid values for these names are listed below.
Optional subnode-properties:
- nvidia,function: A string containing the name of the function to mux to the
pin or group.
- nvidia,pull: Integer, representing the pull-down/up to apply to the pin.
0: none, 1: down, 2: up.
- nvidia,tristate: Integer.
0: drive, 1: tristate.
- nvidia,enable-input: Integer. Enable the pin's input path.
enable :TEGRA_PIN_ENABLE0 and
disable or output only: TEGRA_PIN_DISABLE.
- nvidia,open-drain: Integer.
enable: TEGRA_PIN_ENABLE.
disable: TEGRA_PIN_DISABLE.
- nvidia,lock: Integer. Lock the pin configuration against further changes
until reset.
enable: TEGRA_PIN_ENABLE.
disable: TEGRA_PIN_DISABLE.
- nvidia,io-hv: Integer. Select high-voltage receivers.
normal: TEGRA_PIN_DISABLE
high: TEGRA_PIN_ENABLE
- nvidia,high-speed-mode: Integer. Enable high speed mode the pins.
normal: TEGRA_PIN_DISABLE
high: TEGRA_PIN_ENABLE
- nvidia,schmitt: Integer. Enables Schmitt Trigger on the input.
normal: TEGRA_PIN_DISABLE
high: TEGRA_PIN_ENABLE
- nvidia,drive-type: Integer. Valid range 0...3.
- nvidia,pull-down-strength: Integer. Controls drive strength. 0 is weakest.
The range of valid values depends on the pingroup. See "CAL_DRVDN" in the
Tegra TRM.
- nvidia,pull-up-strength: Integer. Controls drive strength. 0 is weakest.
The range of valid values depends on the pingroup. See "CAL_DRVUP" in the
Tegra TRM.
- nvidia,slew-rate-rising: Integer. Controls rising signal slew rate. 0 is
fastest. The range of valid values depends on the pingroup. See
"DRVDN_SLWR" in the Tegra TRM.
- nvidia,slew-rate-falling: Integer. Controls falling signal slew rate. 0 is
fastest. The range of valid values depends on the pingroup. See
"DRVUP_SLWF" in the Tegra TRM.
Valid values for pin and group names (nvidia,pin) are:
Mux groups:
These correspond to Tegra PINMUX_AUX_* (pinmux) registers. Any property
that exists in those registers may be set for the following pin names.
In Tegra210, many pins also have a dedicated APB_MISC_GP_*_PADCTRL
register. Where that is true, and property that exists in that register
may also be set on the following pin names.
als_prox_int_px3, ap_ready_pv5, ap_wake_bt_ph3, ap_wake_nfc_ph7,
aud_mclk_pbb0, batt_bcl, bt_rst_ph4, bt_wake_ap_ph5, button_home_py1,
button_power_on_px5, button_slide_sw_py0, button_vol_down_px7,
button_vol_up_px6, cam1_mclk_ps0, cam1_pwdn_ps7, cam1_strobe_pt1,
cam2_mclk_ps1, cam2_pwdn_pt0, cam_af_en_ps5, cam_flash_en_ps6,
cam_i2c_scl_ps2, cam_i2c_sda_ps3, cam_rst_ps4cam_rst_ps4, clk_32k_in,
clk_32k_out_py5, clk_req, core_pwr_req, cpu_pwr_req, dap1_din_pb1,
dap1_dout_pb2, dap1_fs_pb0, dap1_sclk_pb3, dap2_din_paa2, dap2_dout_paa3,
dap2_fs_paa0, dap2_sclk_paa1, dap4_din_pj5, dap4_dout_pj6, dap4_fs_pj4,
dap4_sclk_pj7, dmic1_clk_pe0, dmic1_dat_pe1, dmic2_clk_pe2, dmic2_dat_pe3,
dmic3_clk_pe4, dmic3_dat_pe5, dp_hpd0_pcc6, dvfs_clk_pbb2, dvfs_pwm_pbb1,
gen1_i2c_scl_pj1, gen1_i2c_sda_pj0, gen2_i2c_scl_pj2, gen2_i2c_sda_pj3,
gen3_i2c_scl_pf0, gen3_i2c_sda_pf1, gpio_x1_aud_pbb3, gpio_x3_aud_pbb4,
gps_en_pi2, gps_rst_pi3, hdmi_cec_pcc0, hdmi_int_dp_hpd_pcc1, jtag_rtck,
lcd_bl_en_pv1, lcd_bl_pwm_pv0, lcd_gpio1_pv3, lcd_gpio2_pv4, lcd_rst_pv2,
lcd_te_py2, modem_wake_ap_px0, motion_int_px2, nfc_en_pi0, nfc_int_pi1,
pa6, pcc7, pe6, pe7, pex_l0_clkreq_n_pa1, pex_l0_rst_n_pa0,
pex_l1_clkreq_n_pa4, pex_l1_rst_n_pa3, pex_wake_n_pa2, ph6, pk0, pk1, pk2,
pk3, pk4, pk5, pk6, pk7, pl0, pl1, pwr_i2c_scl_py3, pwr_i2c_sda_py4,
pwr_int_n, pz0, pz1, pz2, pz3, pz4, pz5, qspi_cs_n_pee1, qspi_io0_pee2,
qspi_io1_pee3, qspi_io2_pee4, qspi_io3_pee5, qspi_sck_pee0,
sata_led_active_pa5, sdmmc1_clk_pm0, sdmmc1_cmd_pm1, sdmmc1_dat0_pm5,
sdmmc1_dat1_pm4, sdmmc1_dat2_pm3, sdmmc1_dat3_pm2, sdmmc3_clk_pp0,
sdmmc3_cmd_pp1, sdmmc3_dat0_pp5, sdmmc3_dat1_pp4, sdmmc3_dat2_pp3,
sdmmc3_dat3_pp2, shutdown, spdif_in_pcc3, spdif_out_pcc2, spi1_cs0_pc3,
spi1_cs1_pc4, spi1_miso_pc1, spi1_mosi_pc0, spi1_sck_pc2, spi2_cs0_pb7,
spi2_cs1_pdd0, spi2_miso_pb5, spi2_mosi_pb4, spi2_sck_pb6, spi4_cs0_pc6,
spi4_miso_pd0, spi4_mosi_pc7, spi4_sck_pc5, temp_alert_px4, touch_clk_pv7,
touch_int_px1, touch_rst_pv6, uart1_cts_pu3, uart1_rts_pu2, uart1_rx_pu1,
uart1_tx_pu0, uart2_cts_pg3, uart2_rts_pg2, uart2_rx_pg1, uart2_tx_pg0,
uart3_cts_pd4, uart3_rts_pd3, uart3_rx_pd2, uart3_tx_pd1, uart4_cts_pi7,
uart4_rts_pi6, uart4_rx_pi5, uart4_tx_pi4, usb_vbus_en0_pcc4,
usb_vbus_en1_pcc5, wifi_en_ph0, wifi_rst_ph1, wifi_wake_ap_ph2
Drive groups:
These correspond to the Tegra APB_MISC_GP_*_PADCTRL (pad control)
registers. Note that where one of these registers controls a single pin
for which a PINMUX_AUX_* exists, see the list above for the pin name to
use when configuring the pinmux.
pa6, pcc7, pe6, pe7, ph6, pk0, pk1, pk2, pk3, pk4, pk5, pk6, pk7, pl0, pl1,
pz0, pz1, pz2, pz3, pz4, pz5, sdmmc1, sdmmc2, sdmmc3, sdmmc4
Valid values for nvidia,functions are:
aud, bcl, blink, ccla, cec, cldvfs, clk, core, cpu, displaya, displayb,
dmic1, dmic2, dmic3, dp, dtv, extperiph3, i2c1, i2c2, i2c3, i2cpmu, i2cvi,
i2s1, i2s2, i2s3, i2s4a, i2s4b, i2s5a, i2s5b, iqc0, iqc1, jtag, pe, pe0,
pe1, pmi, pwm0, pwm1, pwm2, pwm3, qspi, rsvd0, rsvd1, rsvd2, rsvd3, sata,
sdmmc1, sdmmc3, shutdown, soc, sor0, sor1, spdif, spi1, spi2, spi3, spi4,
sys, touch, uart, uarta, uartb, uartc, uartd, usb, vgp1, vgp2, vgp3, vgp4,
vgp5, vgp6, vimclk, vimclk2
Example:
pinmux: pinmux@70000800 {
compatible = "nvidia,tegra210-pinmux";
reg = <0x0 0x700008d4 0x0 0x2a8>, /* Pad control registers */
<0x0 0x70003000 0x0 0x1000>; /* Mux registers */
pinctrl-names = "boot";
pinctrl-0 = <&state_boot>;
state_boot: pinmux {
gen1_i2c_scl_pj1 {
nvidia,pins = "gen1_i2c_scl_pj1",
nvidia,function = "i2c1";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,io-hv = <TEGRA_PIN_ENABLE>;
};
};
};
};

Просмотреть файл

@ -38,7 +38,7 @@ property exists to define the pin configuration. Each state may also be
assigned a name. When names are used, another property exists to map from
those names to the integer IDs.
Each client device's own binding determines the set of states the must be
Each client device's own binding determines the set of states that must be
defined in its device tree node, and whether to define the set of state
IDs that must be provided, or whether to define the set of state names that
must be provided.
@ -133,16 +133,27 @@ pin multiplexing nodes:
function - the mux function to select
groups - the list of groups to select with this function
(either this or "pins" must be specified)
pins - the list of pins to select with this function (either
this or "groups" must be specified)
Example:
state_0_node_a {
function = "uart0";
groups = "u0rxtx", "u0rtscts";
uart0 {
function = "uart0";
groups = "u0rxtx", "u0rtscts";
};
};
state_1_node_a {
function = "spi0";
groups = "spi0pins";
spi0 {
function = "spi0";
groups = "spi0pins";
};
};
state_2_node_a {
function = "i2c0";
pins = "mfio29", "mfio30";
};
== Generic pin configuration node content ==
@ -188,16 +199,22 @@ slew-rate - set the slew rate
For example:
state_0_node_a {
pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */
bias-pull-up;
cts_rxd {
pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */
bias-pull-up;
};
};
state_1_node_a {
pins = "GPIO1_AJ3", "GPIO3_AH3"; /* RTS+TXD */
output-high;
rts_txd {
pins = "GPIO1_AJ3", "GPIO3_AH3"; /* RTS+TXD */
output-high;
};
};
state_2_node_a {
group = "foo-group";
bias-pull-up;
foo {
group = "foo-group";
bias-pull-up;
};
};
Some of the generic properties take arguments. For those that do, the

Просмотреть файл

@ -0,0 +1,145 @@
* Mediatek MT65XX Pin Controller
The Mediatek's Pin controller is used to control SoC pins.
Required properties:
- compatible: value should be either of the following.
(a) "mediatek,mt8135-pinctrl", compatible with mt8135 pinctrl.
- mediatek,pctl-regmap: Should be a phandle of the syscfg node.
- pins-are-numbered: Specify the subnodes are using numbered pinmux to
specify pins.
- gpio-controller : Marks the device node as a gpio controller.
- #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
binding is used, the amount of cells must be specified as 2. See the below
mentioned gpio binding representation for description of particular cells.
Eg: <&pio 6 0>
<[phandle of the gpio controller node]
[line number within the gpio controller]
[flags]>
Values for gpio specifier:
- Line number: is a value between 0 to 202.
- Flags: bit field of flags, as defined in <dt-bindings/gpio/gpio.h>.
Only the following flags are supported:
0 - GPIO_ACTIVE_HIGH
1 - GPIO_ACTIVE_LOW
- reg: physicall address base for EINT registers
- interrupt-controller: Marks the device node as an interrupt controller
- #interrupt-cells: Should be two.
- interrupts : The interrupt outputs from the controller.
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices.
Subnode format
A pinctrl node should contain at least one subnodes representing the
pinctrl groups available on the machine. Each subnode will list the
pins it needs, and how they should be configured, with regard to muxer
configuration, pullups, drive strength, input enable/disable and input schmitt.
node {
pinmux = <PIN_NUMBER_PINMUX>;
GENERIC_PINCONFIG;
};
Required properties:
- pinmux: integer array, represents gpio pin number and mux setting.
Supported pin number and mux varies for different SoCs, and are defined
as macros in boot/dts/<soc>-pinfunc.h directly.
Optional properties:
- GENERIC_PINCONFIG: is the generic pinconfig options to use, bias-disable,
bias-pull-down, bias-pull-up, input-enable, input-disable, output-low, output-high,
input-schmitt-enable, input-schmitt-disable and drive-strength are valid.
Some special pins have extra pull up strength, there are R0 and R1 pull-up
resistors available, but for user, it's only need to set R1R0 as 00, 01, 10 or 11.
So when config bias-pull-up, it support arguments for those special pins.
Some macros have been defined for this usage, such as MTK_PUPD_SET_R1R0_00.
See dt-bindings/pinctrl/mt65xx.h.
When config drive-strength, it can support some arguments, such as
MTK_DRIVE_4mA, MTK_DRIVE_6mA, etc. See dt-bindings/pinctrl/mt65xx.h.
Examples:
#include "mt8135-pinfunc.h"
...
{
syscfg_pctl_a: syscfg_pctl_a@10005000 {
compatible = "mediatek,mt8135-pctl-a-syscfg", "syscon";
reg = <0 0x10005000 0 0x1000>;
};
syscfg_pctl_b: syscfg_pctl_b@1020C020 {
compatible = "mediatek,mt8135-pctl-b-syscfg", "syscon";
reg = <0 0x1020C020 0 0x1000>;
};
pinctrl@01c20800 {
compatible = "mediatek,mt8135-pinctrl";
reg = <0 0x1000B000 0 0x1000>;
mediatek,pctl-regmap = <&syscfg_pctl_a &syscfg_pctl_b>;
pins-are-numbered;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
i2c0_pins_a: i2c0@0 {
pins1 {
pinmux = <MT8135_PIN_100_SDA0__FUNC_SDA0>,
<MT8135_PIN_101_SCL0__FUNC_SCL0>;
bias-disable;
};
};
i2c1_pins_a: i2c1@0 {
pins {
pinmux = <MT8135_PIN_195_SDA1__FUNC_SDA1>,
<MT8135_PIN_196_SCL1__FUNC_SCL1>;
bias-pull-up = <55>;
};
};
i2c2_pins_a: i2c2@0 {
pins1 {
pinmux = <MT8135_PIN_193_SDA2__FUNC_SDA2>;
bias-pull-down;
};
pins2 {
pinmux = <MT8135_PIN_49_WATCHDOG__FUNC_GPIO49>;
bias-pull-up;
};
};
i2c3_pins_a: i2c3@0 {
pins1 {
pinmux = <MT8135_PIN_40_DAC_CLK__FUNC_GPIO40>,
<MT8135_PIN_41_DAC_WS__FUNC_GPIO41>;
bias-pull-up = <55>;
};
pins2 {
pinmux = <MT8135_PIN_35_SCL3__FUNC_SCL3>,
<MT8135_PIN_36_SDA3__FUNC_SDA3>;
output-low;
bias-pull-up = <55>;
};
pins3 {
pinmux = <MT8135_PIN_57_JTCK__FUNC_GPIO57>,
<MT8135_PIN_60_JTDI__FUNC_JTDI>;
drive-strength = <32>;
};
};
...
}
};

Просмотреть файл

@ -10,6 +10,7 @@ PMIC's from Qualcomm.
"qcom,pm8018-gpio"
"qcom,pm8038-gpio"
"qcom,pm8058-gpio"
"qcom,pm8916-gpio"
"qcom,pm8917-gpio"
"qcom,pm8921-gpio"
"qcom,pm8941-gpio"
@ -74,6 +75,7 @@ to specify in a pin configuration subnode:
gpio1-gpio6 for pm8018
gpio1-gpio12 for pm8038
gpio1-gpio40 for pm8058
gpio1-gpio4 for pm8916
gpio1-gpio38 for pm8917
gpio1-gpio44 for pm8921
gpio1-gpio36 for pm8941

Просмотреть файл

@ -8,6 +8,7 @@ of PMIC's from Qualcomm.
Value type: <string>
Definition: Should contain one of:
"qcom,pm8841-mpp",
"qcom,pm8916-mpp",
"qcom,pm8941-mpp",
"qcom,pma8084-mpp",
@ -67,6 +68,7 @@ to specify in a pin configuration subnode:
Definition: List of MPP pins affected by the properties specified in
this subnode. Valid pins are:
mpp1-mpp4 for pm8841
mpp1-mpp4 for pm8916
mpp1-mpp8 for pm8941
mpp1-mpp4 for pma8084

Просмотреть файл

@ -72,7 +72,6 @@ static struct pinctrl_desc foo_desc = {
.name = "foo",
.pins = foo_pins,
.npins = ARRAY_SIZE(foo_pins),
.maxpin = 63,
.owner = THIS_MODULE,
};
@ -164,8 +163,8 @@ static const char *foo_get_group_name(struct pinctrl_dev *pctldev,
}
static int foo_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
unsigned ** const pins,
unsigned * const num_pins)
const unsigned **pins,
unsigned *num_pins)
{
*pins = (unsigned *) foo_groups[selector].pins;
*num_pins = foo_groups[selector].num_pins;
@ -570,9 +569,8 @@ is possible to perform the requested mux setting, poke the hardware so that
this happens.
Pinmux drivers are required to supply a few callback functions, some are
optional. Usually the enable() and disable() functions are implemented,
writing values into some certain registers to activate a certain mux setting
for a certain pin.
optional. Usually the set_mux() function is implemented, writing values into
some certain registers to activate a certain mux setting for a certain pin.
A simple driver for the above example will work by setting bits 0, 1, 2, 3 or 4
into some register named MUX to select a certain function with a certain
@ -683,12 +681,12 @@ static const struct foo_pmx_func foo_functions[] = {
},
};
int foo_get_functions_count(struct pinctrl_dev *pctldev)
static int foo_get_functions_count(struct pinctrl_dev *pctldev)
{
return ARRAY_SIZE(foo_functions);
}
const char *foo_get_fname(struct pinctrl_dev *pctldev, unsigned selector)
static const char *foo_get_fname(struct pinctrl_dev *pctldev, unsigned selector)
{
return foo_functions[selector].name;
}
@ -702,7 +700,7 @@ static int foo_get_groups(struct pinctrl_dev *pctldev, unsigned selector,
return 0;
}
int foo_set_mux(struct pinctrl_dev *pctldev, unsigned selector,
static int foo_set_mux(struct pinctrl_dev *pctldev, unsigned selector,
unsigned group)
{
u8 regbit = (1 << selector + group);
@ -711,7 +709,7 @@ int foo_set_mux(struct pinctrl_dev *pctldev, unsigned selector,
return 0;
}
struct pinmux_ops foo_pmxops = {
static struct pinmux_ops foo_pmxops = {
.get_functions_count = foo_get_functions_count,
.get_function_name = foo_get_fname,
.get_function_groups = foo_get_groups,
@ -1266,7 +1264,7 @@ The semantics of the pinctrl APIs are:
Usually the pin control core handled the get/put pair and call out to the
device drivers bookkeeping operations, like checking available functions and
the associated pins, whereas the enable/disable pass on to the pin controller
the associated pins, whereas select_state pass on to the pin controller
driver which takes care of activating and/or deactivating the mux setting by
quickly poking some registers.
@ -1363,8 +1361,9 @@ function, but with different named in the mapping as described under
"Advanced mapping" above. So that for an SPI device, we have two states named
"pos-A" and "pos-B".
This snippet first muxes the function in the pins defined by group A, enables
it, disables and releases it, and muxes it in on the pins defined by group B:
This snippet first initializes a state object for both groups (in foo_probe()),
then muxes the function in the pins defined by group A, and finally muxes it in
on the pins defined by group B:
#include <linux/pinctrl/consumer.h>

Просмотреть файл

@ -67,23 +67,20 @@ config PINCTRL_AT91
help
Say Y here to enable the at91 pinctrl driver
config PINCTRL_BCM2835
bool
select PINMUX
select PINCONF
config PINCTRL_BCM281XX
bool "Broadcom BCM281xx pinctrl driver"
depends on OF && (ARCH_BCM_MOBILE || COMPILE_TEST)
select PINMUX
config PINCTRL_AMD
bool "AMD GPIO pin control"
depends on GPIOLIB
select GPIOLIB_IRQCHIP
select PINCONF
select GENERIC_PINCONF
select REGMAP_MMIO
help
Say Y here to support Broadcom BCM281xx pinctrl driver, which is used
for the BCM281xx SoC family, including BCM11130, BCM11140, BCM11351,
BCM28145, and BCM28155 SoCs. This driver requires the pinctrl
framework. GPIO is provided by a separate GPIO driver.
driver for memory mapped GPIO functionality on AMD platforms
(x86 or arm).Most pins are usually muxed to some other
functionality by firmware,so only a small amount is available
for gpio use.
Requires ACPI/FDT device enumeration code to set up a platform
device.
config PINCTRL_LANTIQ
bool
@ -154,6 +151,10 @@ config PINCTRL_TEGRA124
bool
select PINCTRL_TEGRA
config PINCTRL_TEGRA210
bool
select PINCTRL_TEGRA
config PINCTRL_TEGRA_XUSB
def_bool y if ARCH_TEGRA
select GENERIC_PHY
@ -207,6 +208,7 @@ config PINCTRL_ZYNQ
help
This selectes the pinctrl driver for Xilinx Zynq.
source "drivers/pinctrl/bcm/Kconfig"
source "drivers/pinctrl/berlin/Kconfig"
source "drivers/pinctrl/freescale/Kconfig"
source "drivers/pinctrl/intel/Kconfig"
@ -218,6 +220,7 @@ source "drivers/pinctrl/sh-pfc/Kconfig"
source "drivers/pinctrl/spear/Kconfig"
source "drivers/pinctrl/sunxi/Kconfig"
source "drivers/pinctrl/vt8500/Kconfig"
source "drivers/pinctrl/mediatek/Kconfig"
config PINCTRL_XWAY
bool

Просмотреть файл

@ -14,8 +14,7 @@ obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o
obj-$(CONFIG_PINCTRL_BF54x) += pinctrl-adi2-bf54x.o
obj-$(CONFIG_PINCTRL_BF60x) += pinctrl-adi2-bf60x.o
obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o
obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o
obj-$(CONFIG_PINCTRL_AMD) += pinctrl-amd.o
obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o
obj-$(CONFIG_PINCTRL_MESON) += meson/
obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o
@ -27,6 +26,7 @@ obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o
obj-$(CONFIG_PINCTRL_TEGRA114) += pinctrl-tegra114.o
obj-$(CONFIG_PINCTRL_TEGRA124) += pinctrl-tegra124.o
obj-$(CONFIG_PINCTRL_TEGRA210) += pinctrl-tegra210.o
obj-$(CONFIG_PINCTRL_TEGRA_XUSB) += pinctrl-tegra-xusb.o
obj-$(CONFIG_PINCTRL_TZ1090) += pinctrl-tz1090.o
obj-$(CONFIG_PINCTRL_TZ1090_PDC) += pinctrl-tz1090-pdc.o
@ -38,6 +38,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o
obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o
obj-$(CONFIG_ARCH_BCM) += bcm/
obj-$(CONFIG_ARCH_BERLIN) += berlin/
obj-y += freescale/
obj-$(CONFIG_X86) += intel/
@ -49,3 +50,4 @@ obj-$(CONFIG_PINCTRL_SH_PFC) += sh-pfc/
obj-$(CONFIG_PLAT_SPEAR) += spear/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_ARCH_VT8500) += vt8500/
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/

Просмотреть файл

@ -0,0 +1,56 @@
#
# Broadcom pinctrl drivers
#
config PINCTRL_BCM281XX
bool "Broadcom BCM281xx pinctrl driver"
depends on OF && (ARCH_BCM_MOBILE || COMPILE_TEST)
select PINMUX
select PINCONF
select GENERIC_PINCONF
select REGMAP_MMIO
help
Say Y here to support Broadcom BCM281xx pinctrl driver, which is used
for the BCM281xx SoC family, including BCM11130, BCM11140, BCM11351,
BCM28145, and BCM28155 SoCs. This driver requires the pinctrl
framework. GPIO is provided by a separate GPIO driver.
config PINCTRL_BCM2835
bool
select PINMUX
select PINCONF
config PINCTRL_CYGNUS_GPIO
bool "Broadcom Cygnus GPIO (with PINCONF) driver"
depends on OF_GPIO && ARCH_BCM_CYGNUS
select GPIOLIB_IRQCHIP
select PINCONF
select GENERIC_PINCONF
default ARCH_BCM_CYGNUS
help
Say yes here to enable the Broadcom Cygnus GPIO driver.
The Broadcom Cygnus SoC has 3 GPIO controllers including the ASIU
GPIO controller (ASIU), the chipCommonG GPIO controller (CCM), and
the always-ON GPIO controller (CRMU/AON). All 3 GPIO controllers are
supported by this driver.
All 3 Cygnus GPIO controllers support basic PINCONF functions such
as bias pull up, pull down, and drive strength configurations, when
these pins are muxed to GPIO.
Pins from the ASIU GPIO can be individually muxed to GPIO function,
through interaction with the Cygnus IOMUX controller.
config PINCTRL_CYGNUS_MUX
bool "Broadcom Cygnus IOMUX driver"
depends on (ARCH_BCM_CYGNUS || COMPILE_TEST)
select PINMUX
select GENERIC_PINCONF
default ARCH_BCM_CYGNUS
help
Say yes here to enable the Broadcom Cygnus IOMUX driver.
The Broadcom Cygnus IOMUX driver supports group based IOMUX
configuration, with the exception that certain individual pins
can be overrided to GPIO function

Просмотреть файл

@ -0,0 +1,6 @@
# Broadcom pinctrl support
obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o
obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o
obj-$(CONFIG_PINCTRL_CYGNUS_GPIO) += pinctrl-cygnus-gpio.o
obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o

Просмотреть файл

@ -21,8 +21,8 @@
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include "core.h"
#include "pinctrl-utils.h"
#include "../core.h"
#include "../pinctrl-utils.h"
/* BCM281XX Pin Control Registers Definitions */

Просмотреть файл

@ -403,15 +403,7 @@ static irqreturn_t bcm2835_gpio_irq_handler(int irq, void *dev_id)
gpio = (32 * bank) + offset;
type = pc->irq_type[gpio];
/* ack edge triggered IRQs immediately */
if (!(type & IRQ_TYPE_LEVEL_MASK))
bcm2835_gpio_set_bit(pc, GPEDS0, gpio);
generic_handle_irq(irq_linear_revmap(pc->irq_domain, gpio));
/* ack level triggered IRQ after handling them */
if (type & IRQ_TYPE_LEVEL_MASK)
bcm2835_gpio_set_bit(pc, GPEDS0, gpio);
}
return events ? IRQ_HANDLED : IRQ_NONE;
}
@ -591,16 +583,32 @@ static int bcm2835_gpio_irq_set_type(struct irq_data *data, unsigned int type)
else
ret = __bcm2835_gpio_irq_set_type_disabled(pc, gpio, type);
if (type & IRQ_TYPE_EDGE_BOTH)
__irq_set_handler_locked(data->irq, handle_edge_irq);
else
__irq_set_handler_locked(data->irq, handle_level_irq);
spin_unlock_irqrestore(&pc->irq_lock[bank], flags);
return ret;
}
static void bcm2835_gpio_irq_ack(struct irq_data *data)
{
struct bcm2835_pinctrl *pc = irq_data_get_irq_chip_data(data);
unsigned gpio = irqd_to_hwirq(data);
bcm2835_gpio_set_bit(pc, GPEDS0, gpio);
}
static struct irq_chip bcm2835_gpio_irq_chip = {
.name = MODULE_NAME,
.irq_enable = bcm2835_gpio_irq_enable,
.irq_disable = bcm2835_gpio_irq_disable,
.irq_set_type = bcm2835_gpio_irq_set_type,
.irq_ack = bcm2835_gpio_irq_ack,
.irq_mask = bcm2835_gpio_irq_disable,
.irq_unmask = bcm2835_gpio_irq_enable,
};
static int bcm2835_pctl_get_groups_count(struct pinctrl_dev *pctldev)
@ -977,7 +985,7 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
int irq = irq_create_mapping(pc->irq_domain, i);
irq_set_lockdep_class(irq, &gpio_lock_class);
irq_set_chip_and_handler(irq, &bcm2835_gpio_irq_chip,
handle_simple_irq);
handle_level_irq);
irq_set_chip_data(irq, pc);
set_irq_flags(irq, IRQF_VALID);
}
@ -1051,7 +1059,7 @@ static int bcm2835_pinctrl_remove(struct platform_device *pdev)
return 0;
}
static struct of_device_id bcm2835_pinctrl_match[] = {
static const struct of_device_id bcm2835_pinctrl_match[] = {
{ .compatible = "brcm,bcm2835-gpio" },
{}
};

Просмотреть файл

@ -0,0 +1,907 @@
/*
* Copyright (C) 2014-2015 Broadcom Corporation
*
* 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 version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This file contains the Broadcom Cygnus GPIO driver that supports 3
* GPIO controllers on Cygnus including the ASIU GPIO controller, the
* chipCommonG GPIO controller, and the always-on GPIO controller. Basic
* PINCONF such as bias pull up/down, and drive strength are also supported
* in this driver.
*
* Pins from the ASIU GPIO can be individually muxed to GPIO function,
* through the interaction with the Cygnus IOMUX controller
*/
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/ioport.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include "../pinctrl-utils.h"
#define CYGNUS_GPIO_DATA_IN_OFFSET 0x00
#define CYGNUS_GPIO_DATA_OUT_OFFSET 0x04
#define CYGNUS_GPIO_OUT_EN_OFFSET 0x08
#define CYGNUS_GPIO_IN_TYPE_OFFSET 0x0c
#define CYGNUS_GPIO_INT_DE_OFFSET 0x10
#define CYGNUS_GPIO_INT_EDGE_OFFSET 0x14
#define CYGNUS_GPIO_INT_MSK_OFFSET 0x18
#define CYGNUS_GPIO_INT_STAT_OFFSET 0x1c
#define CYGNUS_GPIO_INT_MSTAT_OFFSET 0x20
#define CYGNUS_GPIO_INT_CLR_OFFSET 0x24
#define CYGNUS_GPIO_PAD_RES_OFFSET 0x34
#define CYGNUS_GPIO_RES_EN_OFFSET 0x38
/* drive strength control for ASIU GPIO */
#define CYGNUS_GPIO_ASIU_DRV0_CTRL_OFFSET 0x58
/* drive strength control for CCM/CRMU (AON) GPIO */
#define CYGNUS_GPIO_DRV0_CTRL_OFFSET 0x00
#define GPIO_BANK_SIZE 0x200
#define NGPIOS_PER_BANK 32
#define GPIO_BANK(pin) ((pin) / NGPIOS_PER_BANK)
#define CYGNUS_GPIO_REG(pin, reg) (GPIO_BANK(pin) * GPIO_BANK_SIZE + (reg))
#define CYGNUS_GPIO_SHIFT(pin) ((pin) % NGPIOS_PER_BANK)
#define GPIO_DRV_STRENGTH_BIT_SHIFT 20
#define GPIO_DRV_STRENGTH_BITS 3
#define GPIO_DRV_STRENGTH_BIT_MASK ((1 << GPIO_DRV_STRENGTH_BITS) - 1)
/*
* Cygnus GPIO core
*
* @dev: pointer to device
* @base: I/O register base for Cygnus GPIO controller
* @io_ctrl: I/O register base for certain type of Cygnus GPIO controller that
* has the PINCONF support implemented outside of the GPIO block
* @lock: lock to protect access to I/O registers
* @gc: GPIO chip
* @num_banks: number of GPIO banks, each bank supports up to 32 GPIOs
* @pinmux_is_supported: flag to indicate this GPIO controller contains pins
* that can be individually muxed to GPIO
* @pctl: pointer to pinctrl_dev
* @pctldesc: pinctrl descriptor
*/
struct cygnus_gpio {
struct device *dev;
void __iomem *base;
void __iomem *io_ctrl;
spinlock_t lock;
struct gpio_chip gc;
unsigned num_banks;
bool pinmux_is_supported;
struct pinctrl_dev *pctl;
struct pinctrl_desc pctldesc;
};
static inline struct cygnus_gpio *to_cygnus_gpio(struct gpio_chip *gc)
{
return container_of(gc, struct cygnus_gpio, gc);
}
/*
* Mapping from PINCONF pins to GPIO pins is 1-to-1
*/
static inline unsigned cygnus_pin_to_gpio(unsigned pin)
{
return pin;
}
/**
* cygnus_set_bit - set or clear one bit (corresponding to the GPIO pin) in a
* Cygnus GPIO register
*
* @cygnus_gpio: Cygnus GPIO device
* @reg: register offset
* @gpio: GPIO pin
* @set: set or clear
*/
static inline void cygnus_set_bit(struct cygnus_gpio *chip, unsigned int reg,
unsigned gpio, bool set)
{
unsigned int offset = CYGNUS_GPIO_REG(gpio, reg);
unsigned int shift = CYGNUS_GPIO_SHIFT(gpio);
u32 val;
val = readl(chip->base + offset);
if (set)
val |= BIT(shift);
else
val &= ~BIT(shift);
writel(val, chip->base + offset);
}
static inline bool cygnus_get_bit(struct cygnus_gpio *chip, unsigned int reg,
unsigned gpio)
{
unsigned int offset = CYGNUS_GPIO_REG(gpio, reg);
unsigned int shift = CYGNUS_GPIO_SHIFT(gpio);
return !!(readl(chip->base + offset) & BIT(shift));
}
static void cygnus_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
struct gpio_chip *gc = irq_desc_get_handler_data(desc);
struct cygnus_gpio *chip = to_cygnus_gpio(gc);
struct irq_chip *irq_chip = irq_desc_get_chip(desc);
int i, bit;
chained_irq_enter(irq_chip, desc);
/* go through the entire GPIO banks and handle all interrupts */
for (i = 0; i < chip->num_banks; i++) {
unsigned long val = readl(chip->base + (i * GPIO_BANK_SIZE) +
CYGNUS_GPIO_INT_MSTAT_OFFSET);
for_each_set_bit(bit, &val, NGPIOS_PER_BANK) {
unsigned pin = NGPIOS_PER_BANK * i + bit;
int child_irq = irq_find_mapping(gc->irqdomain, pin);
/*
* Clear the interrupt before invoking the
* handler, so we do not leave any window
*/
writel(BIT(bit), chip->base + (i * GPIO_BANK_SIZE) +
CYGNUS_GPIO_INT_CLR_OFFSET);
generic_handle_irq(child_irq);
}
}
chained_irq_exit(irq_chip, desc);
}
static void cygnus_gpio_irq_ack(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct cygnus_gpio *chip = to_cygnus_gpio(gc);
unsigned gpio = d->hwirq;
unsigned int offset = CYGNUS_GPIO_REG(gpio,
CYGNUS_GPIO_INT_CLR_OFFSET);
unsigned int shift = CYGNUS_GPIO_SHIFT(gpio);
u32 val = BIT(shift);
writel(val, chip->base + offset);
}
/**
* cygnus_gpio_irq_set_mask - mask/unmask a GPIO interrupt
*
* @d: IRQ chip data
* @unmask: mask/unmask GPIO interrupt
*/
static void cygnus_gpio_irq_set_mask(struct irq_data *d, bool unmask)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct cygnus_gpio *chip = to_cygnus_gpio(gc);
unsigned gpio = d->hwirq;
cygnus_set_bit(chip, CYGNUS_GPIO_INT_MSK_OFFSET, gpio, unmask);
}
static void cygnus_gpio_irq_mask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct cygnus_gpio *chip = to_cygnus_gpio(gc);
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
cygnus_gpio_irq_set_mask(d, false);
spin_unlock_irqrestore(&chip->lock, flags);
}
static void cygnus_gpio_irq_unmask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct cygnus_gpio *chip = to_cygnus_gpio(gc);
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
cygnus_gpio_irq_set_mask(d, true);
spin_unlock_irqrestore(&chip->lock, flags);
}
static int cygnus_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct cygnus_gpio *chip = to_cygnus_gpio(gc);
unsigned gpio = d->hwirq;
bool level_triggered = false;
bool dual_edge = false;
bool rising_or_high = false;
unsigned long flags;
switch (type & IRQ_TYPE_SENSE_MASK) {
case IRQ_TYPE_EDGE_RISING:
rising_or_high = true;
break;
case IRQ_TYPE_EDGE_FALLING:
break;
case IRQ_TYPE_EDGE_BOTH:
dual_edge = true;
break;
case IRQ_TYPE_LEVEL_HIGH:
level_triggered = true;
rising_or_high = true;
break;
case IRQ_TYPE_LEVEL_LOW:
level_triggered = true;
break;
default:
dev_err(chip->dev, "invalid GPIO IRQ type 0x%x\n",
type);
return -EINVAL;
}
spin_lock_irqsave(&chip->lock, flags);
cygnus_set_bit(chip, CYGNUS_GPIO_IN_TYPE_OFFSET, gpio,
level_triggered);
cygnus_set_bit(chip, CYGNUS_GPIO_INT_DE_OFFSET, gpio, dual_edge);
cygnus_set_bit(chip, CYGNUS_GPIO_INT_EDGE_OFFSET, gpio,
rising_or_high);
spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev,
"gpio:%u level_triggered:%d dual_edge:%d rising_or_high:%d\n",
gpio, level_triggered, dual_edge, rising_or_high);
return 0;
}
static struct irq_chip cygnus_gpio_irq_chip = {
.name = "bcm-cygnus-gpio",
.irq_ack = cygnus_gpio_irq_ack,
.irq_mask = cygnus_gpio_irq_mask,
.irq_unmask = cygnus_gpio_irq_unmask,
.irq_set_type = cygnus_gpio_irq_set_type,
};
/*
* Request the Cygnus IOMUX pinmux controller to mux individual pins to GPIO
*/
static int cygnus_gpio_request(struct gpio_chip *gc, unsigned offset)
{
struct cygnus_gpio *chip = to_cygnus_gpio(gc);
unsigned gpio = gc->base + offset;
/* not all Cygnus GPIO pins can be muxed individually */
if (!chip->pinmux_is_supported)
return 0;
return pinctrl_request_gpio(gpio);
}
static void cygnus_gpio_free(struct gpio_chip *gc, unsigned offset)
{
struct cygnus_gpio *chip = to_cygnus_gpio(gc);
unsigned gpio = gc->base + offset;
if (!chip->pinmux_is_supported)
return;
pinctrl_free_gpio(gpio);
}
static int cygnus_gpio_direction_input(struct gpio_chip *gc, unsigned gpio)
{
struct cygnus_gpio *chip = to_cygnus_gpio(gc);
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
cygnus_set_bit(chip, CYGNUS_GPIO_OUT_EN_OFFSET, gpio, false);
spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set input\n", gpio);
return 0;
}
static int cygnus_gpio_direction_output(struct gpio_chip *gc, unsigned gpio,
int val)
{
struct cygnus_gpio *chip = to_cygnus_gpio(gc);
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
cygnus_set_bit(chip, CYGNUS_GPIO_OUT_EN_OFFSET, gpio, true);
cygnus_set_bit(chip, CYGNUS_GPIO_DATA_OUT_OFFSET, gpio, !!(val));
spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set output, value:%d\n", gpio, val);
return 0;
}
static void cygnus_gpio_set(struct gpio_chip *gc, unsigned gpio, int val)
{
struct cygnus_gpio *chip = to_cygnus_gpio(gc);
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
cygnus_set_bit(chip, CYGNUS_GPIO_DATA_OUT_OFFSET, gpio, !!(val));
spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set, value:%d\n", gpio, val);
}
static int cygnus_gpio_get(struct gpio_chip *gc, unsigned gpio)
{
struct cygnus_gpio *chip = to_cygnus_gpio(gc);
unsigned int offset = CYGNUS_GPIO_REG(gpio,
CYGNUS_GPIO_DATA_IN_OFFSET);
unsigned int shift = CYGNUS_GPIO_SHIFT(gpio);
return !!(readl(chip->base + offset) & BIT(shift));
}
static int cygnus_get_groups_count(struct pinctrl_dev *pctldev)
{
return 1;
}
/*
* Only one group: "gpio_grp", since this local pinctrl device only performs
* GPIO specific PINCONF configurations
*/
static const char *cygnus_get_group_name(struct pinctrl_dev *pctldev,
unsigned selector)
{
return "gpio_grp";
}
static const struct pinctrl_ops cygnus_pctrl_ops = {
.get_groups_count = cygnus_get_groups_count,
.get_group_name = cygnus_get_group_name,
.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
.dt_free_map = pinctrl_utils_dt_free_map,
};
static int cygnus_gpio_set_pull(struct cygnus_gpio *chip, unsigned gpio,
bool disable, bool pull_up)
{
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
if (disable) {
cygnus_set_bit(chip, CYGNUS_GPIO_RES_EN_OFFSET, gpio, false);
} else {
cygnus_set_bit(chip, CYGNUS_GPIO_PAD_RES_OFFSET, gpio,
pull_up);
cygnus_set_bit(chip, CYGNUS_GPIO_RES_EN_OFFSET, gpio, true);
}
spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set pullup:%d\n", gpio, pull_up);
return 0;
}
static void cygnus_gpio_get_pull(struct cygnus_gpio *chip, unsigned gpio,
bool *disable, bool *pull_up)
{
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
*disable = !cygnus_get_bit(chip, CYGNUS_GPIO_RES_EN_OFFSET, gpio);
*pull_up = cygnus_get_bit(chip, CYGNUS_GPIO_PAD_RES_OFFSET, gpio);
spin_unlock_irqrestore(&chip->lock, flags);
}
static int cygnus_gpio_set_strength(struct cygnus_gpio *chip, unsigned gpio,
unsigned strength)
{
void __iomem *base;
unsigned int i, offset, shift;
u32 val;
unsigned long flags;
/* make sure drive strength is supported */
if (strength < 2 || strength > 16 || (strength % 2))
return -ENOTSUPP;
if (chip->io_ctrl) {
base = chip->io_ctrl;
offset = CYGNUS_GPIO_DRV0_CTRL_OFFSET;
} else {
base = chip->base;
offset = CYGNUS_GPIO_REG(gpio,
CYGNUS_GPIO_ASIU_DRV0_CTRL_OFFSET);
}
shift = CYGNUS_GPIO_SHIFT(gpio);
dev_dbg(chip->dev, "gpio:%u set drive strength:%d mA\n", gpio,
strength);
spin_lock_irqsave(&chip->lock, flags);
strength = (strength / 2) - 1;
for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) {
val = readl(base + offset);
val &= ~BIT(shift);
val |= ((strength >> i) & 0x1) << shift;
writel(val, base + offset);
offset += 4;
}
spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
static int cygnus_gpio_get_strength(struct cygnus_gpio *chip, unsigned gpio,
u16 *strength)
{
void __iomem *base;
unsigned int i, offset, shift;
u32 val;
unsigned long flags;
if (chip->io_ctrl) {
base = chip->io_ctrl;
offset = CYGNUS_GPIO_DRV0_CTRL_OFFSET;
} else {
base = chip->base;
offset = CYGNUS_GPIO_REG(gpio,
CYGNUS_GPIO_ASIU_DRV0_CTRL_OFFSET);
}
shift = CYGNUS_GPIO_SHIFT(gpio);
spin_lock_irqsave(&chip->lock, flags);
*strength = 0;
for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) {
val = readl(base + offset) & BIT(shift);
val >>= shift;
*strength += (val << i);
offset += 4;
}
/* convert to mA */
*strength = (*strength + 1) * 2;
spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
static int cygnus_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long *config)
{
struct cygnus_gpio *chip = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param = pinconf_to_config_param(*config);
unsigned gpio = cygnus_pin_to_gpio(pin);
u16 arg;
bool disable, pull_up;
int ret;
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
cygnus_gpio_get_pull(chip, gpio, &disable, &pull_up);
if (disable)
return 0;
else
return -EINVAL;
case PIN_CONFIG_BIAS_PULL_UP:
cygnus_gpio_get_pull(chip, gpio, &disable, &pull_up);
if (!disable && pull_up)
return 0;
else
return -EINVAL;
case PIN_CONFIG_BIAS_PULL_DOWN:
cygnus_gpio_get_pull(chip, gpio, &disable, &pull_up);
if (!disable && !pull_up)
return 0;
else
return -EINVAL;
case PIN_CONFIG_DRIVE_STRENGTH:
ret = cygnus_gpio_get_strength(chip, gpio, &arg);
if (ret)
return ret;
else
*config = pinconf_to_config_packed(param, arg);
return 0;
default:
return -ENOTSUPP;
}
return -ENOTSUPP;
}
static int cygnus_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long *configs, unsigned num_configs)
{
struct cygnus_gpio *chip = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param;
u16 arg;
unsigned i, gpio = cygnus_pin_to_gpio(pin);
int ret = -ENOTSUPP;
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
ret = cygnus_gpio_set_pull(chip, gpio, true, false);
if (ret < 0)
goto out;
break;
case PIN_CONFIG_BIAS_PULL_UP:
ret = cygnus_gpio_set_pull(chip, gpio, false, true);
if (ret < 0)
goto out;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
ret = cygnus_gpio_set_pull(chip, gpio, false, false);
if (ret < 0)
goto out;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
ret = cygnus_gpio_set_strength(chip, gpio, arg);
if (ret < 0)
goto out;
break;
default:
dev_err(chip->dev, "invalid configuration\n");
return -ENOTSUPP;
}
} /* for each config */
out:
return ret;
}
static const struct pinconf_ops cygnus_pconf_ops = {
.is_generic = true,
.pin_config_get = cygnus_pin_config_get,
.pin_config_set = cygnus_pin_config_set,
};
/*
* Map a GPIO in the local gpio_chip pin space to a pin in the Cygnus IOMUX
* pinctrl pin space
*/
struct cygnus_gpio_pin_range {
unsigned offset;
unsigned pin_base;
unsigned num_pins;
};
#define CYGNUS_PINRANGE(o, p, n) { .offset = o, .pin_base = p, .num_pins = n }
/*
* Pin mapping table for mapping local GPIO pins to Cygnus IOMUX pinctrl pins
*/
static const struct cygnus_gpio_pin_range cygnus_gpio_pintable[] = {
CYGNUS_PINRANGE(0, 42, 1),
CYGNUS_PINRANGE(1, 44, 3),
CYGNUS_PINRANGE(4, 48, 1),
CYGNUS_PINRANGE(5, 50, 3),
CYGNUS_PINRANGE(8, 126, 1),
CYGNUS_PINRANGE(9, 155, 1),
CYGNUS_PINRANGE(10, 152, 1),
CYGNUS_PINRANGE(11, 154, 1),
CYGNUS_PINRANGE(12, 153, 1),
CYGNUS_PINRANGE(13, 127, 3),
CYGNUS_PINRANGE(16, 140, 1),
CYGNUS_PINRANGE(17, 145, 7),
CYGNUS_PINRANGE(24, 130, 10),
CYGNUS_PINRANGE(34, 141, 4),
CYGNUS_PINRANGE(38, 54, 1),
CYGNUS_PINRANGE(39, 56, 3),
CYGNUS_PINRANGE(42, 60, 3),
CYGNUS_PINRANGE(45, 64, 3),
CYGNUS_PINRANGE(48, 68, 2),
CYGNUS_PINRANGE(50, 84, 6),
CYGNUS_PINRANGE(56, 94, 6),
CYGNUS_PINRANGE(62, 72, 1),
CYGNUS_PINRANGE(63, 70, 1),
CYGNUS_PINRANGE(64, 80, 1),
CYGNUS_PINRANGE(65, 74, 3),
CYGNUS_PINRANGE(68, 78, 1),
CYGNUS_PINRANGE(69, 82, 1),
CYGNUS_PINRANGE(70, 156, 17),
CYGNUS_PINRANGE(87, 104, 12),
CYGNUS_PINRANGE(99, 102, 2),
CYGNUS_PINRANGE(101, 90, 4),
CYGNUS_PINRANGE(105, 116, 10),
CYGNUS_PINRANGE(123, 11, 1),
CYGNUS_PINRANGE(124, 38, 4),
CYGNUS_PINRANGE(128, 43, 1),
CYGNUS_PINRANGE(129, 47, 1),
CYGNUS_PINRANGE(130, 49, 1),
CYGNUS_PINRANGE(131, 53, 1),
CYGNUS_PINRANGE(132, 55, 1),
CYGNUS_PINRANGE(133, 59, 1),
CYGNUS_PINRANGE(134, 63, 1),
CYGNUS_PINRANGE(135, 67, 1),
CYGNUS_PINRANGE(136, 71, 1),
CYGNUS_PINRANGE(137, 73, 1),
CYGNUS_PINRANGE(138, 77, 1),
CYGNUS_PINRANGE(139, 79, 1),
CYGNUS_PINRANGE(140, 81, 1),
CYGNUS_PINRANGE(141, 83, 1),
CYGNUS_PINRANGE(142, 10, 1)
};
/*
* The Cygnus IOMUX controller mainly supports group based mux configuration,
* but certain pins can be muxed to GPIO individually. Only the ASIU GPIO
* controller can support this, so it's an optional configuration
*
* Return -ENODEV means no support and that's fine
*/
static int cygnus_gpio_pinmux_add_range(struct cygnus_gpio *chip)
{
struct device_node *node = chip->dev->of_node;
struct device_node *pinmux_node;
struct platform_device *pinmux_pdev;
struct gpio_chip *gc = &chip->gc;
int i, ret = 0;
/* parse DT to find the phandle to the pinmux controller */
pinmux_node = of_parse_phandle(node, "pinmux", 0);
if (!pinmux_node)
return -ENODEV;
pinmux_pdev = of_find_device_by_node(pinmux_node);
/* no longer need the pinmux node */
of_node_put(pinmux_node);
if (!pinmux_pdev) {
dev_err(chip->dev, "failed to get pinmux device\n");
return -EINVAL;
}
/* now need to create the mapping between local GPIO and PINMUX pins */
for (i = 0; i < ARRAY_SIZE(cygnus_gpio_pintable); i++) {
ret = gpiochip_add_pin_range(gc, dev_name(&pinmux_pdev->dev),
cygnus_gpio_pintable[i].offset,
cygnus_gpio_pintable[i].pin_base,
cygnus_gpio_pintable[i].num_pins);
if (ret) {
dev_err(chip->dev, "unable to add GPIO pin range\n");
goto err_put_device;
}
}
chip->pinmux_is_supported = true;
/* no need for pinmux_pdev device reference anymore */
put_device(&pinmux_pdev->dev);
return 0;
err_put_device:
put_device(&pinmux_pdev->dev);
gpiochip_remove_pin_ranges(gc);
return ret;
}
/*
* Cygnus GPIO controller supports some PINCONF related configurations such as
* pull up, pull down, and drive strength, when the pin is configured to GPIO
*
* Here a local pinctrl device is created with simple 1-to-1 pin mapping to the
* local GPIO pins
*/
static int cygnus_gpio_register_pinconf(struct cygnus_gpio *chip)
{
struct pinctrl_desc *pctldesc = &chip->pctldesc;
struct pinctrl_pin_desc *pins;
struct gpio_chip *gc = &chip->gc;
int i;
pins = devm_kcalloc(chip->dev, gc->ngpio, sizeof(*pins), GFP_KERNEL);
if (!pins)
return -ENOMEM;
for (i = 0; i < gc->ngpio; i++) {
pins[i].number = i;
pins[i].name = devm_kasprintf(chip->dev, GFP_KERNEL,
"gpio-%d", i);
if (!pins[i].name)
return -ENOMEM;
}
pctldesc->name = dev_name(chip->dev);
pctldesc->pctlops = &cygnus_pctrl_ops;
pctldesc->pins = pins;
pctldesc->npins = gc->ngpio;
pctldesc->confops = &cygnus_pconf_ops;
chip->pctl = pinctrl_register(pctldesc, chip->dev, chip);
if (!chip->pctl) {
dev_err(chip->dev, "unable to register pinctrl device\n");
return -EINVAL;
}
return 0;
}
static void cygnus_gpio_unregister_pinconf(struct cygnus_gpio *chip)
{
if (chip->pctl)
pinctrl_unregister(chip->pctl);
}
struct cygnus_gpio_data {
unsigned num_gpios;
};
static const struct cygnus_gpio_data cygnus_cmm_gpio_data = {
.num_gpios = 24,
};
static const struct cygnus_gpio_data cygnus_asiu_gpio_data = {
.num_gpios = 146,
};
static const struct cygnus_gpio_data cygnus_crmu_gpio_data = {
.num_gpios = 6,
};
static const struct of_device_id cygnus_gpio_of_match[] = {
{
.compatible = "brcm,cygnus-ccm-gpio",
.data = &cygnus_cmm_gpio_data,
},
{
.compatible = "brcm,cygnus-asiu-gpio",
.data = &cygnus_asiu_gpio_data,
},
{
.compatible = "brcm,cygnus-crmu-gpio",
.data = &cygnus_crmu_gpio_data,
}
};
static int cygnus_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct resource *res;
struct cygnus_gpio *chip;
struct gpio_chip *gc;
u32 ngpios;
int irq, ret;
const struct of_device_id *match;
const struct cygnus_gpio_data *gpio_data;
match = of_match_device(cygnus_gpio_of_match, dev);
if (!match)
return -ENODEV;
gpio_data = match->data;
ngpios = gpio_data->num_gpios;
chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;
chip->dev = dev;
platform_set_drvdata(pdev, chip);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
chip->base = devm_ioremap_resource(dev, res);
if (IS_ERR(chip->base)) {
dev_err(dev, "unable to map I/O memory\n");
return PTR_ERR(chip->base);
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (res) {
chip->io_ctrl = devm_ioremap_resource(dev, res);
if (IS_ERR(chip->io_ctrl)) {
dev_err(dev, "unable to map I/O memory\n");
return PTR_ERR(chip->io_ctrl);
}
}
spin_lock_init(&chip->lock);
gc = &chip->gc;
gc->base = -1;
gc->ngpio = ngpios;
chip->num_banks = (ngpios + NGPIOS_PER_BANK - 1) / NGPIOS_PER_BANK;
gc->label = dev_name(dev);
gc->dev = dev;
gc->of_node = dev->of_node;
gc->request = cygnus_gpio_request;
gc->free = cygnus_gpio_free;
gc->direction_input = cygnus_gpio_direction_input;
gc->direction_output = cygnus_gpio_direction_output;
gc->set = cygnus_gpio_set;
gc->get = cygnus_gpio_get;
ret = gpiochip_add(gc);
if (ret < 0) {
dev_err(dev, "unable to add GPIO chip\n");
return ret;
}
ret = cygnus_gpio_pinmux_add_range(chip);
if (ret && ret != -ENODEV) {
dev_err(dev, "unable to add GPIO pin range\n");
goto err_rm_gpiochip;
}
ret = cygnus_gpio_register_pinconf(chip);
if (ret) {
dev_err(dev, "unable to register pinconf\n");
goto err_rm_gpiochip;
}
/* optional GPIO interrupt support */
irq = platform_get_irq(pdev, 0);
if (irq) {
ret = gpiochip_irqchip_add(gc, &cygnus_gpio_irq_chip, 0,
handle_simple_irq, IRQ_TYPE_NONE);
if (ret) {
dev_err(dev, "no GPIO irqchip\n");
goto err_unregister_pinconf;
}
gpiochip_set_chained_irqchip(gc, &cygnus_gpio_irq_chip, irq,
cygnus_gpio_irq_handler);
}
return 0;
err_unregister_pinconf:
cygnus_gpio_unregister_pinconf(chip);
err_rm_gpiochip:
gpiochip_remove(gc);
return ret;
}
static struct platform_driver cygnus_gpio_driver = {
.driver = {
.name = "cygnus-gpio",
.of_match_table = cygnus_gpio_of_match,
},
.probe = cygnus_gpio_probe,
};
static int __init cygnus_gpio_init(void)
{
return platform_driver_probe(&cygnus_gpio_driver, cygnus_gpio_probe);
}
arch_initcall_sync(cygnus_gpio_init);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -542,10 +542,13 @@ static int imx_pinctrl_parse_groups(struct device_node *np,
struct imx_pin_reg *pin_reg;
struct imx_pin *pin = &grp->pins[i];
if (info->flags & SHARE_MUX_CONF_REG)
if (info->flags & SHARE_MUX_CONF_REG) {
conf_reg = mux_reg;
else
} else {
conf_reg = be32_to_cpu(*list++);
if (!conf_reg)
conf_reg = -1;
}
pin_id = mux_reg ? mux_reg / 4 : conf_reg / 4;
pin_reg = &info->pin_regs[pin_id];
@ -645,7 +648,7 @@ int imx_pinctrl_probe(struct platform_device *pdev,
{
struct imx_pinctrl *ipctl;
struct resource *res;
int ret;
int ret, i;
if (!info || !info->pins || !info->npins) {
dev_err(&pdev->dev, "wrong pinctrl info\n");
@ -662,7 +665,11 @@ int imx_pinctrl_probe(struct platform_device *pdev,
info->npins, GFP_KERNEL);
if (!info->pin_regs)
return -ENOMEM;
memset(info->pin_regs, 0xff, sizeof(*info->pin_regs) * info->npins);
for (i = 0; i < info->npins; i++) {
info->pin_regs[i].mux_reg = -1;
info->pin_regs[i].conf_reg = -1;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
ipctl->base = devm_ioremap_resource(&pdev->dev, res);

Просмотреть файл

@ -302,7 +302,7 @@ static struct imx_pinctrl_soc_info vf610_pinctrl_info = {
.flags = SHARE_MUX_CONF_REG,
};
static struct of_device_id vf610_pinctrl_of_match[] = {
static const struct of_device_id vf610_pinctrl_of_match[] = {
{ .compatible = "fsl,vf610-iomuxc", },
{ /* sentinel */ }
};

Просмотреть файл

@ -25,3 +25,20 @@ config PINCTRL_CHERRYVIEW
help
Cherryview/Braswell pinctrl driver provides an interface that
allows configuring of SoC pins and using them as GPIOs.
config PINCTRL_INTEL
tristate
select PINMUX
select PINCONF
select GENERIC_PINCONF
select GPIOLIB
select GPIOLIB_IRQCHIP
config PINCTRL_SUNRISEPOINT
tristate "Intel Sunrisepoint pinctrl and GPIO driver"
depends on ACPI
select PINCTRL_INTEL
help
Sunrisepoint is the PCH of Intel Skylake. This pinctrl driver
provides an interface that allows configuring of PCH pins and
using them as GPIOs.

Просмотреть файл

@ -2,3 +2,5 @@
obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o
obj-$(CONFIG_PINCTRL_CHERRYVIEW) += pinctrl-cherryview.o
obj-$(CONFIG_PINCTRL_INTEL) += pinctrl-intel.o
obj-$(CONFIG_PINCTRL_SUNRISEPOINT) += pinctrl-sunrisepoint.o

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,128 @@
/*
* Core pinctrl/GPIO driver for Intel GPIO controllers
*
* Copyright (C) 2015, Intel Corporation
* Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
* Mika Westerberg <mika.westerberg@linux.intel.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef PINCTRL_INTEL_H
#define PINCTRL_INTEL_H
struct pinctrl_pin_desc;
struct platform_device;
struct device;
/**
* struct intel_pingroup - Description about group of pins
* @name: Name of the groups
* @pins: All pins in this group
* @npins: Number of pins in this groups
* @mode: Native mode in which the group is muxed out @pins
*/
struct intel_pingroup {
const char *name;
const unsigned *pins;
size_t npins;
unsigned short mode;
};
/**
* struct intel_function - Description about a function
* @name: Name of the function
* @groups: An array of groups for this function
* @ngroups: Number of groups in @groups
*/
struct intel_function {
const char *name;
const char * const *groups;
size_t ngroups;
};
/**
* struct intel_community - Intel pin community description
* @barno: MMIO BAR number where registers for this community reside
* @padown_offset: Register offset of PAD_OWN register from @regs. If %0
* then there is no support for owner.
* @padcfglock_offset: Register offset of PADCFGLOCK from @regs. If %0 then
* locking is not supported.
* @hostown_offset: Register offset of HOSTSW_OWN from @regs. If %0 then it
* is assumed that the host owns the pin (rather than
* ACPI).
* @ie_offset: Register offset of GPI_IE from @regs.
* @pin_base: Starting pin of pins in this community
* @npins: Number of pins in this community
* @regs: Community specific common registers (reserved for core driver)
* @pad_regs: Community specific pad registers (reserved for core driver)
* @ngpps: Number of groups (hw groups) in this community (reserved for
* core driver)
*/
struct intel_community {
unsigned barno;
unsigned padown_offset;
unsigned padcfglock_offset;
unsigned hostown_offset;
unsigned ie_offset;
unsigned pin_base;
size_t npins;
void __iomem *regs;
void __iomem *pad_regs;
size_t ngpps;
};
#define PIN_GROUP(n, p, m) \
{ \
.name = (n), \
.pins = (p), \
.npins = ARRAY_SIZE((p)), \
.mode = (m), \
}
#define FUNCTION(n, g) \
{ \
.name = (n), \
.groups = (g), \
.ngroups = ARRAY_SIZE((g)), \
}
/**
* struct intel_pinctrl_soc_data - Intel pin controller per-SoC configuration
* @uid: ACPI _UID for the probe driver use if needed
* @pins: Array if pins this pinctrl controls
* @npins: Number of pins in the array
* @groups: Array of pin groups
* @ngroups: Number of groups in the array
* @functions: Array of functions
* @nfunctions: Number of functions in the array
* @communities: Array of communities this pinctrl handles
* @ncommunities: Number of communities in the array
*
* The @communities is used as a template by the core driver. It will make
* copy of all communities and fill in rest of the information.
*/
struct intel_pinctrl_soc_data {
const char *uid;
const struct pinctrl_pin_desc *pins;
size_t npins;
const struct intel_pingroup *groups;
size_t ngroups;
const struct intel_function *functions;
size_t nfunctions;
const struct intel_community *communities;
size_t ncommunities;
};
int intel_pinctrl_probe(struct platform_device *pdev,
const struct intel_pinctrl_soc_data *soc_data);
int intel_pinctrl_remove(struct platform_device *pdev);
#ifdef CONFIG_PM_SLEEP
int intel_pinctrl_suspend(struct device *dev);
int intel_pinctrl_resume(struct device *dev);
#endif
#endif /* PINCTRL_INTEL_H */

Просмотреть файл

@ -0,0 +1,336 @@
/*
* Intel Sunrisepoint PCH pinctrl/GPIO driver
*
* Copyright (C) 2015, Intel Corporation
* Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
* Mika Westerberg <mika.westerberg@linux.intel.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-intel.h"
#define SPT_PAD_OWN 0x020
#define SPT_PADCFGLOCK 0x0a0
#define SPT_HOSTSW_OWN 0x0d0
#define SPT_GPI_IE 0x120
#define SPT_COMMUNITY(b, s, e) \
{ \
.barno = (b), \
.padown_offset = SPT_PAD_OWN, \
.padcfglock_offset = SPT_PADCFGLOCK, \
.hostown_offset = SPT_HOSTSW_OWN, \
.ie_offset = SPT_GPI_IE, \
.pin_base = (s), \
.npins = ((e) - (s) + 1), \
}
/* Sunrisepoint-LP */
static const struct pinctrl_pin_desc sptlp_pins[] = {
/* GPP_A */
PINCTRL_PIN(0, "RCINB"),
PINCTRL_PIN(1, "LAD_0"),
PINCTRL_PIN(2, "LAD_1"),
PINCTRL_PIN(3, "LAD_2"),
PINCTRL_PIN(4, "LAD_3"),
PINCTRL_PIN(5, "LFRAMEB"),
PINCTRL_PIN(6, "SERIQ"),
PINCTRL_PIN(7, "PIRQAB"),
PINCTRL_PIN(8, "CLKRUNB"),
PINCTRL_PIN(9, "CLKOUT_LPC_0"),
PINCTRL_PIN(10, "CLKOUT_LPC_1"),
PINCTRL_PIN(11, "PMEB"),
PINCTRL_PIN(12, "BM_BUSYB"),
PINCTRL_PIN(13, "SUSWARNB_SUS_PWRDNACK"),
PINCTRL_PIN(14, "SUS_STATB"),
PINCTRL_PIN(15, "SUSACKB"),
PINCTRL_PIN(16, "SD_1P8_SEL"),
PINCTRL_PIN(17, "SD_PWR_EN_B"),
PINCTRL_PIN(18, "ISH_GP_0"),
PINCTRL_PIN(19, "ISH_GP_1"),
PINCTRL_PIN(20, "ISH_GP_2"),
PINCTRL_PIN(21, "ISH_GP_3"),
PINCTRL_PIN(22, "ISH_GP_4"),
PINCTRL_PIN(23, "ISH_GP_5"),
/* GPP_B */
PINCTRL_PIN(24, "CORE_VID_0"),
PINCTRL_PIN(25, "CORE_VID_1"),
PINCTRL_PIN(26, "VRALERTB"),
PINCTRL_PIN(27, "CPU_GP_2"),
PINCTRL_PIN(28, "CPU_GP_3"),
PINCTRL_PIN(29, "SRCCLKREQB_0"),
PINCTRL_PIN(30, "SRCCLKREQB_1"),
PINCTRL_PIN(31, "SRCCLKREQB_2"),
PINCTRL_PIN(32, "SRCCLKREQB_3"),
PINCTRL_PIN(33, "SRCCLKREQB_4"),
PINCTRL_PIN(34, "SRCCLKREQB_5"),
PINCTRL_PIN(35, "EXT_PWR_GATEB"),
PINCTRL_PIN(36, "SLP_S0B"),
PINCTRL_PIN(37, "PLTRSTB"),
PINCTRL_PIN(38, "SPKR"),
PINCTRL_PIN(39, "GSPI0_CSB"),
PINCTRL_PIN(40, "GSPI0_CLK"),
PINCTRL_PIN(41, "GSPI0_MISO"),
PINCTRL_PIN(42, "GSPI0_MOSI"),
PINCTRL_PIN(43, "GSPI1_CSB"),
PINCTRL_PIN(44, "GSPI1_CLK"),
PINCTRL_PIN(45, "GSPI1_MISO"),
PINCTRL_PIN(46, "GSPI1_MOSI"),
PINCTRL_PIN(47, "SML1ALERTB"),
/* GPP_C */
PINCTRL_PIN(48, "SMBCLK"),
PINCTRL_PIN(49, "SMBDATA"),
PINCTRL_PIN(50, "SMBALERTB"),
PINCTRL_PIN(51, "SML0CLK"),
PINCTRL_PIN(52, "SML0DATA"),
PINCTRL_PIN(53, "SML0ALERTB"),
PINCTRL_PIN(54, "SML1CLK"),
PINCTRL_PIN(55, "SML1DATA"),
PINCTRL_PIN(56, "UART0_RXD"),
PINCTRL_PIN(57, "UART0_TXD"),
PINCTRL_PIN(58, "UART0_RTSB"),
PINCTRL_PIN(59, "UART0_CTSB"),
PINCTRL_PIN(60, "UART1_RXD"),
PINCTRL_PIN(61, "UART1_TXD"),
PINCTRL_PIN(62, "UART1_RTSB"),
PINCTRL_PIN(63, "UART1_CTSB"),
PINCTRL_PIN(64, "I2C0_SDA"),
PINCTRL_PIN(65, "I2C0_SCL"),
PINCTRL_PIN(66, "I2C1_SDA"),
PINCTRL_PIN(67, "I2C1_SCL"),
PINCTRL_PIN(68, "UART2_RXD"),
PINCTRL_PIN(69, "UART2_TXD"),
PINCTRL_PIN(70, "UART2_RTSB"),
PINCTRL_PIN(71, "UART2_CTSB"),
/* GPP_D */
PINCTRL_PIN(72, "SPI1_CSB"),
PINCTRL_PIN(73, "SPI1_CLK"),
PINCTRL_PIN(74, "SPI1_MISO_IO_1"),
PINCTRL_PIN(75, "SPI1_MOSI_IO_0"),
PINCTRL_PIN(76, "FLASHTRIG"),
PINCTRL_PIN(77, "ISH_I2C0_SDA"),
PINCTRL_PIN(78, "ISH_I2C0_SCL"),
PINCTRL_PIN(79, "ISH_I2C1_SDA"),
PINCTRL_PIN(80, "ISH_I2C1_SCL"),
PINCTRL_PIN(81, "ISH_SPI_CSB"),
PINCTRL_PIN(82, "ISH_SPI_CLK"),
PINCTRL_PIN(83, "ISH_SPI_MISO"),
PINCTRL_PIN(84, "ISH_SPI_MOSI"),
PINCTRL_PIN(85, "ISH_UART0_RXD"),
PINCTRL_PIN(86, "ISH_UART0_TXD"),
PINCTRL_PIN(87, "ISH_UART0_RTSB"),
PINCTRL_PIN(88, "ISH_UART0_CTSB"),
PINCTRL_PIN(89, "DMIC_CLK_1"),
PINCTRL_PIN(90, "DMIC_DATA_1"),
PINCTRL_PIN(91, "DMIC_CLK_0"),
PINCTRL_PIN(92, "DMIC_DATA_0"),
PINCTRL_PIN(93, "SPI1_IO_2"),
PINCTRL_PIN(94, "SPI1_IO_3"),
PINCTRL_PIN(95, "SSP_MCLK"),
/* GPP_E */
PINCTRL_PIN(96, "SATAXPCIE_0"),
PINCTRL_PIN(97, "SATAXPCIE_1"),
PINCTRL_PIN(98, "SATAXPCIE_2"),
PINCTRL_PIN(99, "CPU_GP_0"),
PINCTRL_PIN(100, "SATA_DEVSLP_0"),
PINCTRL_PIN(101, "SATA_DEVSLP_1"),
PINCTRL_PIN(102, "SATA_DEVSLP_2"),
PINCTRL_PIN(103, "CPU_GP_1"),
PINCTRL_PIN(104, "SATA_LEDB"),
PINCTRL_PIN(105, "USB2_OCB_0"),
PINCTRL_PIN(106, "USB2_OCB_1"),
PINCTRL_PIN(107, "USB2_OCB_2"),
PINCTRL_PIN(108, "USB2_OCB_3"),
PINCTRL_PIN(109, "DDSP_HPD_0"),
PINCTRL_PIN(110, "DDSP_HPD_1"),
PINCTRL_PIN(111, "DDSP_HPD_2"),
PINCTRL_PIN(112, "DDSP_HPD_3"),
PINCTRL_PIN(113, "EDP_HPD"),
PINCTRL_PIN(114, "DDPB_CTRLCLK"),
PINCTRL_PIN(115, "DDPB_CTRLDATA"),
PINCTRL_PIN(116, "DDPC_CTRLCLK"),
PINCTRL_PIN(117, "DDPC_CTRLDATA"),
PINCTRL_PIN(118, "DDPD_CTRLCLK"),
PINCTRL_PIN(119, "DDPD_CTRLDATA"),
/* GPP_F */
PINCTRL_PIN(120, "SSP2_SCLK"),
PINCTRL_PIN(121, "SSP2_SFRM"),
PINCTRL_PIN(122, "SSP2_TXD"),
PINCTRL_PIN(123, "SSP2_RXD"),
PINCTRL_PIN(124, "I2C2_SDA"),
PINCTRL_PIN(125, "I2C2_SCL"),
PINCTRL_PIN(126, "I2C3_SDA"),
PINCTRL_PIN(127, "I2C3_SCL"),
PINCTRL_PIN(128, "I2C4_SDA"),
PINCTRL_PIN(129, "I2C4_SCL"),
PINCTRL_PIN(130, "I2C5_SDA"),
PINCTRL_PIN(131, "I2C5_SCL"),
PINCTRL_PIN(132, "EMMC_CMD"),
PINCTRL_PIN(133, "EMMC_DATA_0"),
PINCTRL_PIN(134, "EMMC_DATA_1"),
PINCTRL_PIN(135, "EMMC_DATA_2"),
PINCTRL_PIN(136, "EMMC_DATA_3"),
PINCTRL_PIN(137, "EMMC_DATA_4"),
PINCTRL_PIN(138, "EMMC_DATA_5"),
PINCTRL_PIN(139, "EMMC_DATA_6"),
PINCTRL_PIN(140, "EMMC_DATA_7"),
PINCTRL_PIN(141, "EMMC_RCLK"),
PINCTRL_PIN(142, "EMMC_CLK"),
PINCTRL_PIN(143, "GPP_F_23"),
/* GPP_G */
PINCTRL_PIN(144, "SD_CMD"),
PINCTRL_PIN(145, "SD_DATA_0"),
PINCTRL_PIN(146, "SD_DATA_1"),
PINCTRL_PIN(147, "SD_DATA_2"),
PINCTRL_PIN(148, "SD_DATA_3"),
PINCTRL_PIN(149, "SD_CDB"),
PINCTRL_PIN(150, "SD_CLK"),
PINCTRL_PIN(151, "SD_WP"),
};
static const unsigned sptlp_spi0_pins[] = { 39, 40, 41, 42 };
static const unsigned sptlp_spi1_pins[] = { 43, 44, 45, 46 };
static const unsigned sptlp_uart0_pins[] = { 56, 57, 58, 59 };
static const unsigned sptlp_uart1_pins[] = { 60, 61, 62, 63 };
static const unsigned sptlp_uart2_pins[] = { 68, 69, 71, 71 };
static const unsigned sptlp_i2c0_pins[] = { 64, 65 };
static const unsigned sptlp_i2c1_pins[] = { 66, 67 };
static const unsigned sptlp_i2c2_pins[] = { 124, 125 };
static const unsigned sptlp_i2c3_pins[] = { 126, 127 };
static const unsigned sptlp_i2c4_pins[] = { 128, 129 };
static const unsigned sptlp_i2c4b_pins[] = { 85, 86 };
static const unsigned sptlp_i2c5_pins[] = { 130, 131 };
static const unsigned sptlp_ssp2_pins[] = { 120, 121, 122, 123 };
static const unsigned sptlp_emmc_pins[] = {
132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
};
static const unsigned sptlp_sd_pins[] = {
144, 145, 146, 147, 148, 149, 150, 151,
};
static const struct intel_pingroup sptlp_groups[] = {
PIN_GROUP("spi0_grp", sptlp_spi0_pins, 1),
PIN_GROUP("spi1_grp", sptlp_spi1_pins, 1),
PIN_GROUP("uart0_grp", sptlp_uart0_pins, 1),
PIN_GROUP("uart1_grp", sptlp_uart1_pins, 1),
PIN_GROUP("uart2_grp", sptlp_uart2_pins, 1),
PIN_GROUP("i2c0_grp", sptlp_i2c0_pins, 1),
PIN_GROUP("i2c1_grp", sptlp_i2c1_pins, 1),
PIN_GROUP("i2c2_grp", sptlp_i2c2_pins, 1),
PIN_GROUP("i2c3_grp", sptlp_i2c3_pins, 1),
PIN_GROUP("i2c4_grp", sptlp_i2c4_pins, 1),
PIN_GROUP("i2c4b_grp", sptlp_i2c4b_pins, 3),
PIN_GROUP("i2c5_grp", sptlp_i2c5_pins, 1),
PIN_GROUP("ssp2_grp", sptlp_ssp2_pins, 1),
PIN_GROUP("emmc_grp", sptlp_emmc_pins, 1),
PIN_GROUP("sd_grp", sptlp_sd_pins, 1),
};
static const char * const sptlp_spi0_groups[] = { "spi0_grp" };
static const char * const sptlp_spi1_groups[] = { "spi0_grp" };
static const char * const sptlp_uart0_groups[] = { "uart0_grp" };
static const char * const sptlp_uart1_groups[] = { "uart1_grp" };
static const char * const sptlp_uart2_groups[] = { "uart2_grp" };
static const char * const sptlp_i2c0_groups[] = { "i2c0_grp" };
static const char * const sptlp_i2c1_groups[] = { "i2c1_grp" };
static const char * const sptlp_i2c2_groups[] = { "i2c2_grp" };
static const char * const sptlp_i2c3_groups[] = { "i2c3_grp" };
static const char * const sptlp_i2c4_groups[] = { "i2c4_grp", "i2c4b_grp" };
static const char * const sptlp_i2c5_groups[] = { "i2c5_grp" };
static const char * const sptlp_ssp2_groups[] = { "ssp2_grp" };
static const char * const sptlp_emmc_groups[] = { "emmc_grp" };
static const char * const sptlp_sd_groups[] = { "sd_grp" };
static const struct intel_function sptlp_functions[] = {
FUNCTION("spi0", sptlp_spi0_groups),
FUNCTION("spi1", sptlp_spi1_groups),
FUNCTION("uart0", sptlp_uart0_groups),
FUNCTION("uart1", sptlp_uart1_groups),
FUNCTION("uart2", sptlp_uart2_groups),
FUNCTION("i2c0", sptlp_i2c0_groups),
FUNCTION("i2c1", sptlp_i2c1_groups),
FUNCTION("i2c2", sptlp_i2c2_groups),
FUNCTION("i2c3", sptlp_i2c3_groups),
FUNCTION("i2c4", sptlp_i2c4_groups),
FUNCTION("i2c5", sptlp_i2c5_groups),
FUNCTION("ssp2", sptlp_ssp2_groups),
FUNCTION("emmc", sptlp_emmc_groups),
FUNCTION("sd", sptlp_sd_groups),
};
static const struct intel_community sptlp_communities[] = {
SPT_COMMUNITY(0, 0, 47),
SPT_COMMUNITY(1, 48, 119),
SPT_COMMUNITY(2, 120, 151),
};
static const struct intel_pinctrl_soc_data sptlp_soc_data = {
.pins = sptlp_pins,
.npins = ARRAY_SIZE(sptlp_pins),
.groups = sptlp_groups,
.ngroups = ARRAY_SIZE(sptlp_groups),
.functions = sptlp_functions,
.nfunctions = ARRAY_SIZE(sptlp_functions),
.communities = sptlp_communities,
.ncommunities = ARRAY_SIZE(sptlp_communities),
};
static const struct acpi_device_id spt_pinctrl_acpi_match[] = {
{ "INT344B", (kernel_ulong_t)&sptlp_soc_data },
{ }
};
MODULE_DEVICE_TABLE(acpi, spt_pinctrl_acpi_match);
static int spt_pinctrl_probe(struct platform_device *pdev)
{
const struct intel_pinctrl_soc_data *soc_data;
const struct acpi_device_id *id;
id = acpi_match_device(spt_pinctrl_acpi_match, &pdev->dev);
if (!id || !id->driver_data)
return -ENODEV;
soc_data = (const struct intel_pinctrl_soc_data *)id->driver_data;
return intel_pinctrl_probe(pdev, soc_data);
}
static const struct dev_pm_ops spt_pinctrl_pm_ops = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
intel_pinctrl_resume)
};
static struct platform_driver spt_pinctrl_driver = {
.probe = spt_pinctrl_probe,
.remove = intel_pinctrl_remove,
.driver = {
.name = "sunrisepoint-pinctrl",
.acpi_match_table = spt_pinctrl_acpi_match,
.pm = &spt_pinctrl_pm_ops,
},
};
static int __init spt_pinctrl_init(void)
{
return platform_driver_register(&spt_pinctrl_driver);
}
subsys_initcall(spt_pinctrl_init);
static void __exit spt_pinctrl_exit(void)
{
platform_driver_unregister(&spt_pinctrl_driver);
}
module_exit(spt_pinctrl_exit);
MODULE_AUTHOR("Mathias Nyman <mathias.nyman@linux.intel.com>");
MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
MODULE_DESCRIPTION("Intel Sunrisepoint PCH pinctrl/GPIO driver");
MODULE_LICENSE("GPL v2");

Просмотреть файл

@ -0,0 +1,23 @@
if ARCH_MEDIATEK || COMPILE_TEST
config PINCTRL_MTK_COMMON
bool
select PINMUX
select GENERIC_PINCONF
select GPIOLIB
select OF_GPIO
# For ARMv7 SoCs
config PINCTRL_MT8135
bool "Mediatek MT8135 pin control" if COMPILE_TEST && !MACH_MT8135
default MACH_MT8135
select PINCTRL_MTK_COMMON
# For ARMv8 SoCs
config PINCTRL_MT8173
bool "Mediatek MT8173 pin control"
depends on ARM64 || COMPILE_TEST
default ARM64 && ARCH_MEDIATEK
select PINCTRL_MTK_COMMON
endif

Просмотреть файл

@ -0,0 +1,6 @@
# Core
obj-$(CONFIG_PINCTRL_MTK_COMMON) += pinctrl-mtk-common.o
# SoC Drivers
obj-$(CONFIG_PINCTRL_MT8135) += pinctrl-mt8135.o
obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o

Просмотреть файл

@ -0,0 +1,376 @@
/*
* Copyright (c) 2014 MediaTek Inc.
* Author: Hongzhou.Yang <hongzhou.yang@mediatek.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/regmap.h>
#include <dt-bindings/pinctrl/mt65xx.h>
#include "pinctrl-mtk-common.h"
#include "pinctrl-mtk-mt8135.h"
#define DRV_BASE1 0x500
#define DRV_BASE2 0x510
#define PUPD_BASE1 0x400
#define PUPD_BASE2 0x450
#define R0_BASE1 0x4d0
#define R1_BASE1 0x200
#define R1_BASE2 0x250
struct mtk_spec_pull_set {
unsigned int pin;
unsigned int pupd_offset;
unsigned char pupd_bit;
unsigned int r0_offset;
unsigned char r0_bit;
unsigned int r1_offset;
unsigned char r1_bit;
};
#define SPEC_PULL(_pin, _pupd_offset, _pupd_bit, _r0_offset, \
_r0_bit, _r1_offset, _r1_bit) \
{ \
.pin = _pin, \
.pupd_offset = _pupd_offset, \
.pupd_bit = _pupd_bit, \
.r0_offset = _r0_offset, \
.r0_bit = _r0_bit, \
.r1_offset = _r1_offset, \
.r1_bit = _r1_bit, \
}
static const struct mtk_drv_group_desc mt8135_drv_grp[] = {
/* E8E4E2 2/4/6/8/10/12/14/16 */
MTK_DRV_GRP(2, 16, 0, 2, 2),
/* E8E4 4/8/12/16 */
MTK_DRV_GRP(4, 16, 1, 2, 4),
/* E4E2 2/4/6/8 */
MTK_DRV_GRP(2, 8, 0, 1, 2),
/* E16E8E4 4/8/12/16/20/24/28/32 */
MTK_DRV_GRP(4, 32, 0, 2, 4)
};
static const struct mtk_pin_drv_grp mt8135_pin_drv[] = {
MTK_PIN_DRV_GRP(0, DRV_BASE1, 0, 0),
MTK_PIN_DRV_GRP(1, DRV_BASE1, 0, 0),
MTK_PIN_DRV_GRP(2, DRV_BASE1, 0, 0),
MTK_PIN_DRV_GRP(3, DRV_BASE1, 0, 0),
MTK_PIN_DRV_GRP(4, DRV_BASE1, 4, 0),
MTK_PIN_DRV_GRP(5, DRV_BASE1, 8, 0),
MTK_PIN_DRV_GRP(6, DRV_BASE1, 0, 0),
MTK_PIN_DRV_GRP(7, DRV_BASE1, 0, 0),
MTK_PIN_DRV_GRP(8, DRV_BASE1, 0, 0),
MTK_PIN_DRV_GRP(9, DRV_BASE1, 0, 0),
MTK_PIN_DRV_GRP(10, DRV_BASE1, 12, 1),
MTK_PIN_DRV_GRP(11, DRV_BASE1, 12, 1),
MTK_PIN_DRV_GRP(12, DRV_BASE1, 12, 1),
MTK_PIN_DRV_GRP(13, DRV_BASE1, 12, 1),
MTK_PIN_DRV_GRP(14, DRV_BASE1, 12, 1),
MTK_PIN_DRV_GRP(15, DRV_BASE1, 12, 1),
MTK_PIN_DRV_GRP(16, DRV_BASE1, 12, 1),
MTK_PIN_DRV_GRP(17, DRV_BASE1, 16, 1),
MTK_PIN_DRV_GRP(18, DRV_BASE1, 16, 1),
MTK_PIN_DRV_GRP(19, DRV_BASE1, 16, 1),
MTK_PIN_DRV_GRP(20, DRV_BASE1, 16, 1),
MTK_PIN_DRV_GRP(21, DRV_BASE1, 16, 1),
MTK_PIN_DRV_GRP(22, DRV_BASE1, 16, 1),
MTK_PIN_DRV_GRP(23, DRV_BASE1, 16, 1),
MTK_PIN_DRV_GRP(24, DRV_BASE1, 16, 1),
MTK_PIN_DRV_GRP(33, DRV_BASE1, 24, 1),
MTK_PIN_DRV_GRP(34, DRV_BASE2, 12, 2),
MTK_PIN_DRV_GRP(37, DRV_BASE2, 20, 1),
MTK_PIN_DRV_GRP(38, DRV_BASE2, 20, 1),
MTK_PIN_DRV_GRP(39, DRV_BASE2, 20, 1),
MTK_PIN_DRV_GRP(40, DRV_BASE2, 24, 1),
MTK_PIN_DRV_GRP(41, DRV_BASE2, 24, 1),
MTK_PIN_DRV_GRP(42, DRV_BASE2, 24, 1),
MTK_PIN_DRV_GRP(43, DRV_BASE2, 28, 1),
MTK_PIN_DRV_GRP(44, DRV_BASE2, 28, 1),
MTK_PIN_DRV_GRP(45, DRV_BASE2, 28, 1),
MTK_PIN_DRV_GRP(46, DRV_BASE2, 28, 1),
MTK_PIN_DRV_GRP(47, DRV_BASE2, 28, 1),
MTK_PIN_DRV_GRP(49, DRV_BASE2+0x10, 0, 1),
MTK_PIN_DRV_GRP(50, DRV_BASE2+0x10, 4, 1),
MTK_PIN_DRV_GRP(51, DRV_BASE2+0x10, 8, 1),
MTK_PIN_DRV_GRP(52, DRV_BASE2+0x10, 12, 2),
MTK_PIN_DRV_GRP(53, DRV_BASE2+0x10, 16, 1),
MTK_PIN_DRV_GRP(54, DRV_BASE2+0x10, 20, 1),
MTK_PIN_DRV_GRP(55, DRV_BASE2+0x10, 24, 1),
MTK_PIN_DRV_GRP(56, DRV_BASE2+0x10, 28, 1),
MTK_PIN_DRV_GRP(57, DRV_BASE2+0x20, 0, 1),
MTK_PIN_DRV_GRP(58, DRV_BASE2+0x20, 0, 1),
MTK_PIN_DRV_GRP(59, DRV_BASE2+0x20, 0, 1),
MTK_PIN_DRV_GRP(60, DRV_BASE2+0x20, 0, 1),
MTK_PIN_DRV_GRP(61, DRV_BASE2+0x20, 0, 1),
MTK_PIN_DRV_GRP(62, DRV_BASE2+0x20, 0, 1),
MTK_PIN_DRV_GRP(63, DRV_BASE2+0x20, 4, 1),
MTK_PIN_DRV_GRP(64, DRV_BASE2+0x20, 8, 1),
MTK_PIN_DRV_GRP(65, DRV_BASE2+0x20, 12, 1),
MTK_PIN_DRV_GRP(66, DRV_BASE2+0x20, 16, 1),
MTK_PIN_DRV_GRP(67, DRV_BASE2+0x20, 20, 1),
MTK_PIN_DRV_GRP(68, DRV_BASE2+0x20, 24, 1),
MTK_PIN_DRV_GRP(69, DRV_BASE2+0x20, 28, 1),
MTK_PIN_DRV_GRP(70, DRV_BASE2+0x30, 0, 1),
MTK_PIN_DRV_GRP(71, DRV_BASE2+0x30, 4, 1),
MTK_PIN_DRV_GRP(72, DRV_BASE2+0x30, 8, 1),
MTK_PIN_DRV_GRP(73, DRV_BASE2+0x30, 12, 1),
MTK_PIN_DRV_GRP(74, DRV_BASE2+0x30, 16, 1),
MTK_PIN_DRV_GRP(75, DRV_BASE2+0x30, 20, 1),
MTK_PIN_DRV_GRP(76, DRV_BASE2+0x30, 24, 1),
MTK_PIN_DRV_GRP(77, DRV_BASE2+0x30, 28, 3),
MTK_PIN_DRV_GRP(78, DRV_BASE2+0x30, 28, 3),
MTK_PIN_DRV_GRP(79, DRV_BASE2+0x40, 0, 3),
MTK_PIN_DRV_GRP(80, DRV_BASE2+0x40, 4, 3),
MTK_PIN_DRV_GRP(81, DRV_BASE2+0x30, 28, 3),
MTK_PIN_DRV_GRP(82, DRV_BASE2+0x30, 28, 3),
MTK_PIN_DRV_GRP(83, DRV_BASE2+0x40, 8, 3),
MTK_PIN_DRV_GRP(84, DRV_BASE2+0x40, 8, 3),
MTK_PIN_DRV_GRP(85, DRV_BASE2+0x40, 12, 3),
MTK_PIN_DRV_GRP(86, DRV_BASE2+0x40, 16, 3),
MTK_PIN_DRV_GRP(87, DRV_BASE2+0x40, 8, 3),
MTK_PIN_DRV_GRP(88, DRV_BASE2+0x40, 8, 3),
MTK_PIN_DRV_GRP(89, DRV_BASE2+0x50, 12, 0),
MTK_PIN_DRV_GRP(90, DRV_BASE2+0x50, 12, 0),
MTK_PIN_DRV_GRP(91, DRV_BASE2+0x50, 12, 0),
MTK_PIN_DRV_GRP(92, DRV_BASE2+0x50, 12, 0),
MTK_PIN_DRV_GRP(93, DRV_BASE2+0x50, 12, 0),
MTK_PIN_DRV_GRP(94, DRV_BASE2+0x50, 12, 0),
MTK_PIN_DRV_GRP(95, DRV_BASE2+0x50, 12, 0),
MTK_PIN_DRV_GRP(96, DRV_BASE1+0xb0, 28, 0),
MTK_PIN_DRV_GRP(97, DRV_BASE2+0x50, 12, 0),
MTK_PIN_DRV_GRP(98, DRV_BASE2+0x50, 16, 0),
MTK_PIN_DRV_GRP(99, DRV_BASE2+0x50, 20, 1),
MTK_PIN_DRV_GRP(102, DRV_BASE2+0x50, 24, 1),
MTK_PIN_DRV_GRP(103, DRV_BASE2+0x50, 28, 1),
MTK_PIN_DRV_GRP(104, DRV_BASE2+0x60, 0, 1),
MTK_PIN_DRV_GRP(105, DRV_BASE2+0x60, 4, 1),
MTK_PIN_DRV_GRP(106, DRV_BASE2+0x60, 4, 1),
MTK_PIN_DRV_GRP(107, DRV_BASE2+0x60, 4, 1),
MTK_PIN_DRV_GRP(108, DRV_BASE2+0x60, 4, 1),
MTK_PIN_DRV_GRP(109, DRV_BASE2+0x60, 8, 2),
MTK_PIN_DRV_GRP(110, DRV_BASE2+0x60, 12, 2),
MTK_PIN_DRV_GRP(111, DRV_BASE2+0x60, 16, 2),
MTK_PIN_DRV_GRP(112, DRV_BASE2+0x60, 20, 2),
MTK_PIN_DRV_GRP(113, DRV_BASE2+0x60, 24, 2),
MTK_PIN_DRV_GRP(114, DRV_BASE2+0x60, 28, 2),
MTK_PIN_DRV_GRP(115, DRV_BASE2+0x70, 0, 2),
MTK_PIN_DRV_GRP(116, DRV_BASE2+0x70, 4, 2),
MTK_PIN_DRV_GRP(117, DRV_BASE2+0x70, 8, 2),
MTK_PIN_DRV_GRP(118, DRV_BASE2+0x70, 12, 2),
MTK_PIN_DRV_GRP(119, DRV_BASE2+0x70, 16, 2),
MTK_PIN_DRV_GRP(120, DRV_BASE2+0x70, 20, 2),
MTK_PIN_DRV_GRP(181, DRV_BASE1+0xa0, 12, 1),
MTK_PIN_DRV_GRP(182, DRV_BASE1+0xa0, 16, 1),
MTK_PIN_DRV_GRP(183, DRV_BASE1+0xa0, 20, 1),
MTK_PIN_DRV_GRP(184, DRV_BASE1+0xa0, 24, 1),
MTK_PIN_DRV_GRP(185, DRV_BASE1+0xa0, 28, 1),
MTK_PIN_DRV_GRP(186, DRV_BASE1+0xb0, 0, 2),
MTK_PIN_DRV_GRP(187, DRV_BASE1+0xb0, 0, 2),
MTK_PIN_DRV_GRP(188, DRV_BASE1+0xb0, 0, 2),
MTK_PIN_DRV_GRP(189, DRV_BASE1+0xb0, 0, 2),
MTK_PIN_DRV_GRP(190, DRV_BASE1+0xb0, 4, 1),
MTK_PIN_DRV_GRP(191, DRV_BASE1+0xb0, 8, 1),
MTK_PIN_DRV_GRP(192, DRV_BASE1+0xb0, 12, 1),
MTK_PIN_DRV_GRP(197, DRV_BASE1+0xb0, 16, 0),
MTK_PIN_DRV_GRP(198, DRV_BASE1+0xb0, 16, 0),
MTK_PIN_DRV_GRP(199, DRV_BASE1+0xb0, 20, 0),
MTK_PIN_DRV_GRP(200, DRV_BASE1+0xb0, 24, 0),
MTK_PIN_DRV_GRP(201, DRV_BASE1+0xb0, 16, 0),
MTK_PIN_DRV_GRP(202, DRV_BASE1+0xb0, 16, 0)
};
static const struct mtk_spec_pull_set spec_pupd[] = {
SPEC_PULL(0, PUPD_BASE1, 0, R0_BASE1, 9, R1_BASE1, 0),
SPEC_PULL(1, PUPD_BASE1, 1, R0_BASE1, 8, R1_BASE1, 1),
SPEC_PULL(2, PUPD_BASE1, 2, R0_BASE1, 7, R1_BASE1, 2),
SPEC_PULL(3, PUPD_BASE1, 3, R0_BASE1, 6, R1_BASE1, 3),
SPEC_PULL(4, PUPD_BASE1, 4, R0_BASE1, 1, R1_BASE1, 4),
SPEC_PULL(5, PUPD_BASE1, 5, R0_BASE1, 0, R1_BASE1, 5),
SPEC_PULL(6, PUPD_BASE1, 6, R0_BASE1, 5, R1_BASE1, 6),
SPEC_PULL(7, PUPD_BASE1, 7, R0_BASE1, 4, R1_BASE1, 7),
SPEC_PULL(8, PUPD_BASE1, 8, R0_BASE1, 3, R1_BASE1, 8),
SPEC_PULL(9, PUPD_BASE1, 9, R0_BASE1, 2, R1_BASE1, 9),
SPEC_PULL(89, PUPD_BASE2, 9, R0_BASE1, 18, R1_BASE2, 9),
SPEC_PULL(90, PUPD_BASE2, 10, R0_BASE1, 19, R1_BASE2, 10),
SPEC_PULL(91, PUPD_BASE2, 11, R0_BASE1, 23, R1_BASE2, 11),
SPEC_PULL(92, PUPD_BASE2, 12, R0_BASE1, 24, R1_BASE2, 12),
SPEC_PULL(93, PUPD_BASE2, 13, R0_BASE1, 25, R1_BASE2, 13),
SPEC_PULL(94, PUPD_BASE2, 14, R0_BASE1, 22, R1_BASE2, 14),
SPEC_PULL(95, PUPD_BASE2, 15, R0_BASE1, 20, R1_BASE2, 15),
SPEC_PULL(96, PUPD_BASE2+0x10, 0, R0_BASE1, 16, R1_BASE2+0x10, 0),
SPEC_PULL(97, PUPD_BASE2+0x10, 1, R0_BASE1, 21, R1_BASE2+0x10, 1),
SPEC_PULL(98, PUPD_BASE2+0x10, 2, R0_BASE1, 17, R1_BASE2+0x10, 2),
SPEC_PULL(197, PUPD_BASE1+0xc0, 5, R0_BASE1, 13, R1_BASE2+0xc0, 5),
SPEC_PULL(198, PUPD_BASE2+0xc0, 6, R0_BASE1, 14, R1_BASE2+0xc0, 6),
SPEC_PULL(199, PUPD_BASE2+0xc0, 7, R0_BASE1, 11, R1_BASE2+0xc0, 7),
SPEC_PULL(200, PUPD_BASE2+0xc0, 8, R0_BASE1, 10, R1_BASE2+0xc0, 8),
SPEC_PULL(201, PUPD_BASE2+0xc0, 9, R0_BASE1, 13, R1_BASE2+0xc0, 9),
SPEC_PULL(202, PUPD_BASE2+0xc0, 10, R0_BASE1, 12, R1_BASE2+0xc0, 10)
};
static int spec_pull_set(struct regmap *regmap, unsigned int pin,
unsigned char align, bool isup, unsigned int r1r0)
{
unsigned int i;
unsigned int reg_pupd, reg_set_r0, reg_set_r1;
unsigned int reg_rst_r0, reg_rst_r1;
bool find = false;
for (i = 0; i < ARRAY_SIZE(spec_pupd); i++) {
if (pin == spec_pupd[i].pin) {
find = true;
break;
}
}
if (!find)
return -EINVAL;
if (isup)
reg_pupd = spec_pupd[i].pupd_offset + align;
else
reg_pupd = spec_pupd[i].pupd_offset + (align << 1);
regmap_write(regmap, reg_pupd, spec_pupd[i].pupd_bit);
reg_set_r0 = spec_pupd[i].r0_offset + align;
reg_rst_r0 = spec_pupd[i].r0_offset + (align << 1);
reg_set_r1 = spec_pupd[i].r1_offset + align;
reg_rst_r1 = spec_pupd[i].r1_offset + (align << 1);
switch (r1r0) {
case MTK_PUPD_SET_R1R0_00:
regmap_write(regmap, reg_rst_r0, spec_pupd[i].r0_bit);
regmap_write(regmap, reg_rst_r1, spec_pupd[i].r1_bit);
break;
case MTK_PUPD_SET_R1R0_01:
regmap_write(regmap, reg_set_r0, spec_pupd[i].r0_bit);
regmap_write(regmap, reg_rst_r1, spec_pupd[i].r1_bit);
break;
case MTK_PUPD_SET_R1R0_10:
regmap_write(regmap, reg_rst_r0, spec_pupd[i].r0_bit);
regmap_write(regmap, reg_set_r1, spec_pupd[i].r1_bit);
break;
case MTK_PUPD_SET_R1R0_11:
regmap_write(regmap, reg_set_r0, spec_pupd[i].r0_bit);
regmap_write(regmap, reg_set_r1, spec_pupd[i].r1_bit);
break;
default:
return -EINVAL;
}
return 0;
}
static const struct mtk_pinctrl_devdata mt8135_pinctrl_data = {
.pins = mtk_pins_mt8135,
.npins = ARRAY_SIZE(mtk_pins_mt8135),
.grp_desc = mt8135_drv_grp,
.n_grp_cls = ARRAY_SIZE(mt8135_drv_grp),
.pin_drv_grp = mt8135_pin_drv,
.n_pin_drv_grps = ARRAY_SIZE(mt8135_pin_drv),
.spec_pull_set = spec_pull_set,
.dir_offset = 0x0000,
.ies_offset = 0x0100,
.pullen_offset = 0x0200,
.smt_offset = 0x0300,
.pullsel_offset = 0x0400,
.invser_offset = 0x0600,
.dout_offset = 0x0800,
.din_offset = 0x0A00,
.pinmux_offset = 0x0C00,
.type1_start = 34,
.type1_end = 149,
.port_shf = 4,
.port_mask = 0xf,
.port_align = 4,
.chip_type = MTK_CHIP_TYPE_BASE,
.eint_offsets = {
.name = "mt8135_eint",
.stat = 0x000,
.ack = 0x040,
.mask = 0x080,
.mask_set = 0x0c0,
.mask_clr = 0x100,
.sens = 0x140,
.sens_set = 0x180,
.sens_clr = 0x1c0,
.soft = 0x200,
.soft_set = 0x240,
.soft_clr = 0x280,
.pol = 0x300,
.pol_set = 0x340,
.pol_clr = 0x380,
.dom_en = 0x400,
.dbnc_ctrl = 0x500,
.dbnc_set = 0x600,
.dbnc_clr = 0x700,
.port_mask = 7,
.ports = 6,
},
.ap_num = 192,
.db_cnt = 16,
};
static int mt8135_pinctrl_probe(struct platform_device *pdev)
{
return mtk_pctrl_init(pdev, &mt8135_pinctrl_data);
}
static const struct of_device_id mt8135_pctrl_match[] = {
{
.compatible = "mediatek,mt8135-pinctrl",
},
{ }
};
MODULE_DEVICE_TABLE(of, mt8135_pctrl_match);
static struct platform_driver mtk_pinctrl_driver = {
.probe = mt8135_pinctrl_probe,
.driver = {
.name = "mediatek-mt8135-pinctrl",
.owner = THIS_MODULE,
.of_match_table = mt8135_pctrl_match,
},
};
static int __init mtk_pinctrl_init(void)
{
return platform_driver_register(&mtk_pinctrl_driver);
}
module_init(mtk_pinctrl_init);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MediaTek Pinctrl Driver");
MODULE_AUTHOR("Hongzhou Yang <hongzhou.yang@mediatek.com>");

Просмотреть файл

@ -0,0 +1,455 @@
/*
* Copyright (c) 2014-2015 MediaTek Inc.
* Author: Hongzhou.Yang <hongzhou.yang@mediatek.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/regmap.h>
#include <dt-bindings/pinctrl/mt65xx.h>
#include "pinctrl-mtk-common.h"
#include "pinctrl-mtk-mt8173.h"
#define DRV_BASE 0xb00
/**
* struct mtk_pin_ies_smt_set - For special pins' ies and smt setting.
* @start: The start pin number of those special pins.
* @end: The end pin number of those special pins.
* @offset: The offset of special setting register.
* @bit: The bit of special setting register.
*/
struct mtk_pin_ies_smt_set {
unsigned int start;
unsigned int end;
unsigned int offset;
unsigned char bit;
};
#define MTK_PIN_IES_SMT_SET(_start, _end, _offset, _bit) \
{ \
.start = _start, \
.end = _end, \
.bit = _bit, \
.offset = _offset, \
}
/**
* struct mtk_pin_spec_pupd_set - For special pins' pull up/down setting.
* @pin: The pin number.
* @offset: The offset of special pull up/down setting register.
* @pupd_bit: The pull up/down bit in this register.
* @r0_bit: The r0 bit of pull resistor.
* @r1_bit: The r1 bit of pull resistor.
*/
struct mtk_pin_spec_pupd_set {
unsigned int pin;
unsigned int offset;
unsigned char pupd_bit;
unsigned char r1_bit;
unsigned char r0_bit;
};
#define MTK_PIN_PUPD_SPEC(_pin, _offset, _pupd, _r1, _r0) \
{ \
.pin = _pin, \
.offset = _offset, \
.pupd_bit = _pupd, \
.r1_bit = _r1, \
.r0_bit = _r0, \
}
static const struct mtk_pin_spec_pupd_set mt8173_spec_pupd[] = {
MTK_PIN_PUPD_SPEC(119, 0xe00, 2, 1, 0), /* KROW0 */
MTK_PIN_PUPD_SPEC(120, 0xe00, 6, 5, 4), /* KROW1 */
MTK_PIN_PUPD_SPEC(121, 0xe00, 10, 9, 8), /* KROW2 */
MTK_PIN_PUPD_SPEC(122, 0xe10, 2, 1, 0), /* KCOL0 */
MTK_PIN_PUPD_SPEC(123, 0xe10, 6, 5, 4), /* KCOL1 */
MTK_PIN_PUPD_SPEC(124, 0xe10, 10, 9, 8), /* KCOL2 */
MTK_PIN_PUPD_SPEC(67, 0xd10, 2, 1, 0), /* ms0 DS */
MTK_PIN_PUPD_SPEC(68, 0xd00, 2, 1, 0), /* ms0 RST */
MTK_PIN_PUPD_SPEC(66, 0xc10, 2, 1, 0), /* ms0 cmd */
MTK_PIN_PUPD_SPEC(65, 0xc00, 2, 1, 0), /* ms0 clk */
MTK_PIN_PUPD_SPEC(57, 0xc20, 2, 1, 0), /* ms0 data0 */
MTK_PIN_PUPD_SPEC(58, 0xc20, 2, 1, 0), /* ms0 data1 */
MTK_PIN_PUPD_SPEC(59, 0xc20, 2, 1, 0), /* ms0 data2 */
MTK_PIN_PUPD_SPEC(60, 0xc20, 2, 1, 0), /* ms0 data3 */
MTK_PIN_PUPD_SPEC(61, 0xc20, 2, 1, 0), /* ms0 data4 */
MTK_PIN_PUPD_SPEC(62, 0xc20, 2, 1, 0), /* ms0 data5 */
MTK_PIN_PUPD_SPEC(63, 0xc20, 2, 1, 0), /* ms0 data6 */
MTK_PIN_PUPD_SPEC(64, 0xc20, 2, 1, 0), /* ms0 data7 */
MTK_PIN_PUPD_SPEC(78, 0xc50, 2, 1, 0), /* ms1 cmd */
MTK_PIN_PUPD_SPEC(73, 0xd20, 2, 1, 0), /* ms1 dat0 */
MTK_PIN_PUPD_SPEC(74, 0xd20, 6, 5, 4), /* ms1 dat1 */
MTK_PIN_PUPD_SPEC(75, 0xd20, 10, 9, 8), /* ms1 dat2 */
MTK_PIN_PUPD_SPEC(76, 0xd20, 14, 13, 12), /* ms1 dat3 */
MTK_PIN_PUPD_SPEC(77, 0xc40, 2, 1, 0), /* ms1 clk */
MTK_PIN_PUPD_SPEC(100, 0xd40, 2, 1, 0), /* ms2 dat0 */
MTK_PIN_PUPD_SPEC(101, 0xd40, 6, 5, 4), /* ms2 dat1 */
MTK_PIN_PUPD_SPEC(102, 0xd40, 10, 9, 8), /* ms2 dat2 */
MTK_PIN_PUPD_SPEC(103, 0xd40, 14, 13, 12), /* ms2 dat3 */
MTK_PIN_PUPD_SPEC(104, 0xc80, 2, 1, 0), /* ms2 clk */
MTK_PIN_PUPD_SPEC(105, 0xc90, 2, 1, 0), /* ms2 cmd */
MTK_PIN_PUPD_SPEC(22, 0xd60, 2, 1, 0), /* ms3 dat0 */
MTK_PIN_PUPD_SPEC(23, 0xd60, 6, 5, 4), /* ms3 dat1 */
MTK_PIN_PUPD_SPEC(24, 0xd60, 10, 9, 8), /* ms3 dat2 */
MTK_PIN_PUPD_SPEC(25, 0xd60, 14, 13, 12), /* ms3 dat3 */
MTK_PIN_PUPD_SPEC(26, 0xcc0, 2, 1, 0), /* ms3 clk */
MTK_PIN_PUPD_SPEC(27, 0xcd0, 2, 1, 0) /* ms3 cmd */
};
static int spec_pull_set(struct regmap *regmap, unsigned int pin,
unsigned char align, bool isup, unsigned int r1r0)
{
unsigned int i;
unsigned int reg_pupd, reg_set, reg_rst;
unsigned int bit_pupd, bit_r0, bit_r1;
const struct mtk_pin_spec_pupd_set *spec_pupd_pin;
bool find = false;
for (i = 0; i < ARRAY_SIZE(mt8173_spec_pupd); i++) {
if (pin == mt8173_spec_pupd[i].pin) {
find = true;
break;
}
}
if (!find)
return -EINVAL;
spec_pupd_pin = mt8173_spec_pupd + i;
reg_set = spec_pupd_pin->offset + align;
reg_rst = spec_pupd_pin->offset + (align << 1);
if (isup)
reg_pupd = reg_rst;
else
reg_pupd = reg_set;
bit_pupd = BIT(spec_pupd_pin->pupd_bit);
regmap_write(regmap, reg_pupd, bit_pupd);
bit_r0 = BIT(spec_pupd_pin->r0_bit);
bit_r1 = BIT(spec_pupd_pin->r1_bit);
switch (r1r0) {
case MTK_PUPD_SET_R1R0_00:
regmap_write(regmap, reg_rst, bit_r0);
regmap_write(regmap, reg_rst, bit_r1);
break;
case MTK_PUPD_SET_R1R0_01:
regmap_write(regmap, reg_set, bit_r0);
regmap_write(regmap, reg_rst, bit_r1);
break;
case MTK_PUPD_SET_R1R0_10:
regmap_write(regmap, reg_rst, bit_r0);
regmap_write(regmap, reg_set, bit_r1);
break;
case MTK_PUPD_SET_R1R0_11:
regmap_write(regmap, reg_set, bit_r0);
regmap_write(regmap, reg_set, bit_r1);
break;
default:
return -EINVAL;
}
return 0;
}
static const struct mtk_pin_ies_smt_set mt8173_ies_smt_set[] = {
MTK_PIN_IES_SMT_SET(0, 4, 0x930, 1),
MTK_PIN_IES_SMT_SET(5, 9, 0x930, 2),
MTK_PIN_IES_SMT_SET(10, 13, 0x930, 10),
MTK_PIN_IES_SMT_SET(14, 15, 0x940, 10),
MTK_PIN_IES_SMT_SET(16, 16, 0x930, 0),
MTK_PIN_IES_SMT_SET(17, 17, 0x950, 2),
MTK_PIN_IES_SMT_SET(18, 21, 0x940, 3),
MTK_PIN_IES_SMT_SET(29, 32, 0x930, 3),
MTK_PIN_IES_SMT_SET(33, 33, 0x930, 4),
MTK_PIN_IES_SMT_SET(34, 36, 0x930, 5),
MTK_PIN_IES_SMT_SET(37, 38, 0x930, 6),
MTK_PIN_IES_SMT_SET(39, 39, 0x930, 7),
MTK_PIN_IES_SMT_SET(40, 41, 0x930, 9),
MTK_PIN_IES_SMT_SET(42, 42, 0x940, 0),
MTK_PIN_IES_SMT_SET(43, 44, 0x930, 11),
MTK_PIN_IES_SMT_SET(45, 46, 0x930, 12),
MTK_PIN_IES_SMT_SET(57, 64, 0xc20, 13),
MTK_PIN_IES_SMT_SET(65, 65, 0xc10, 13),
MTK_PIN_IES_SMT_SET(66, 66, 0xc00, 13),
MTK_PIN_IES_SMT_SET(67, 67, 0xd10, 13),
MTK_PIN_IES_SMT_SET(68, 68, 0xd00, 13),
MTK_PIN_IES_SMT_SET(69, 72, 0x940, 14),
MTK_PIN_IES_SMT_SET(73, 76, 0xc60, 13),
MTK_PIN_IES_SMT_SET(77, 77, 0xc40, 13),
MTK_PIN_IES_SMT_SET(78, 78, 0xc50, 13),
MTK_PIN_IES_SMT_SET(79, 82, 0x940, 15),
MTK_PIN_IES_SMT_SET(83, 83, 0x950, 0),
MTK_PIN_IES_SMT_SET(84, 85, 0x950, 1),
MTK_PIN_IES_SMT_SET(86, 91, 0x950, 2),
MTK_PIN_IES_SMT_SET(92, 92, 0x930, 13),
MTK_PIN_IES_SMT_SET(93, 95, 0x930, 14),
MTK_PIN_IES_SMT_SET(96, 99, 0x930, 15),
MTK_PIN_IES_SMT_SET(100, 103, 0xca0, 13),
MTK_PIN_IES_SMT_SET(104, 104, 0xc80, 13),
MTK_PIN_IES_SMT_SET(105, 105, 0xc90, 13),
MTK_PIN_IES_SMT_SET(106, 107, 0x940, 4),
MTK_PIN_IES_SMT_SET(108, 112, 0x940, 1),
MTK_PIN_IES_SMT_SET(113, 116, 0x940, 2),
MTK_PIN_IES_SMT_SET(117, 118, 0x940, 5),
MTK_PIN_IES_SMT_SET(119, 124, 0x940, 6),
MTK_PIN_IES_SMT_SET(125, 126, 0x940, 7),
MTK_PIN_IES_SMT_SET(127, 127, 0x940, 0),
MTK_PIN_IES_SMT_SET(128, 128, 0x950, 8),
MTK_PIN_IES_SMT_SET(129, 130, 0x950, 9),
MTK_PIN_IES_SMT_SET(131, 132, 0x950, 8),
MTK_PIN_IES_SMT_SET(133, 134, 0x910, 8)
};
static int spec_ies_smt_set(struct regmap *regmap, unsigned int pin,
unsigned char align, int value)
{
unsigned int i, reg_addr, bit;
bool find = false;
for (i = 0; i < ARRAY_SIZE(mt8173_ies_smt_set); i++) {
if (pin >= mt8173_ies_smt_set[i].start &&
pin <= mt8173_ies_smt_set[i].end) {
find = true;
break;
}
}
if (!find)
return -EINVAL;
if (value)
reg_addr = mt8173_ies_smt_set[i].offset + align;
else
reg_addr = mt8173_ies_smt_set[i].offset + (align << 1);
bit = BIT(mt8173_ies_smt_set[i].bit);
regmap_write(regmap, reg_addr, bit);
return 0;
}
static const struct mtk_drv_group_desc mt8173_drv_grp[] = {
/* 0E4E8SR 4/8/12/16 */
MTK_DRV_GRP(4, 16, 1, 2, 4),
/* 0E2E4SR 2/4/6/8 */
MTK_DRV_GRP(2, 8, 1, 2, 2),
/* E8E4E2 2/4/6/8/10/12/14/16 */
MTK_DRV_GRP(2, 16, 0, 2, 2)
};
static const struct mtk_pin_drv_grp mt8173_pin_drv[] = {
MTK_PIN_DRV_GRP(0, DRV_BASE+0x20, 12, 0),
MTK_PIN_DRV_GRP(1, DRV_BASE+0x20, 12, 0),
MTK_PIN_DRV_GRP(2, DRV_BASE+0x20, 12, 0),
MTK_PIN_DRV_GRP(3, DRV_BASE+0x20, 12, 0),
MTK_PIN_DRV_GRP(4, DRV_BASE+0x20, 12, 0),
MTK_PIN_DRV_GRP(5, DRV_BASE+0x30, 0, 0),
MTK_PIN_DRV_GRP(6, DRV_BASE+0x30, 0, 0),
MTK_PIN_DRV_GRP(7, DRV_BASE+0x30, 0, 0),
MTK_PIN_DRV_GRP(8, DRV_BASE+0x30, 0, 0),
MTK_PIN_DRV_GRP(9, DRV_BASE+0x30, 0, 0),
MTK_PIN_DRV_GRP(10, DRV_BASE+0x30, 4, 1),
MTK_PIN_DRV_GRP(11, DRV_BASE+0x30, 4, 1),
MTK_PIN_DRV_GRP(12, DRV_BASE+0x30, 4, 1),
MTK_PIN_DRV_GRP(13, DRV_BASE+0x30, 4, 1),
MTK_PIN_DRV_GRP(14, DRV_BASE+0x40, 8, 1),
MTK_PIN_DRV_GRP(15, DRV_BASE+0x40, 8, 1),
MTK_PIN_DRV_GRP(16, DRV_BASE, 8, 1),
MTK_PIN_DRV_GRP(17, 0xce0, 8, 2),
MTK_PIN_DRV_GRP(22, 0xce0, 8, 2),
MTK_PIN_DRV_GRP(23, 0xce0, 8, 2),
MTK_PIN_DRV_GRP(24, 0xce0, 8, 2),
MTK_PIN_DRV_GRP(25, 0xce0, 8, 2),
MTK_PIN_DRV_GRP(26, 0xcc0, 8, 2),
MTK_PIN_DRV_GRP(27, 0xcd0, 8, 2),
MTK_PIN_DRV_GRP(28, 0xd70, 8, 2),
MTK_PIN_DRV_GRP(29, DRV_BASE+0x80, 12, 1),
MTK_PIN_DRV_GRP(30, DRV_BASE+0x80, 12, 1),
MTK_PIN_DRV_GRP(31, DRV_BASE+0x80, 12, 1),
MTK_PIN_DRV_GRP(32, DRV_BASE+0x80, 12, 1),
MTK_PIN_DRV_GRP(33, DRV_BASE+0x10, 12, 1),
MTK_PIN_DRV_GRP(34, DRV_BASE+0x10, 8, 1),
MTK_PIN_DRV_GRP(35, DRV_BASE+0x10, 8, 1),
MTK_PIN_DRV_GRP(36, DRV_BASE+0x10, 8, 1),
MTK_PIN_DRV_GRP(37, DRV_BASE+0x10, 4, 1),
MTK_PIN_DRV_GRP(38, DRV_BASE+0x10, 4, 1),
MTK_PIN_DRV_GRP(39, DRV_BASE+0x20, 0, 0),
MTK_PIN_DRV_GRP(40, DRV_BASE+0x20, 8, 0),
MTK_PIN_DRV_GRP(41, DRV_BASE+0x20, 8, 0),
MTK_PIN_DRV_GRP(42, DRV_BASE+0x50, 8, 1),
MTK_PIN_DRV_GRP(57, 0xc20, 8, 2),
MTK_PIN_DRV_GRP(58, 0xc20, 8, 2),
MTK_PIN_DRV_GRP(59, 0xc20, 8, 2),
MTK_PIN_DRV_GRP(60, 0xc20, 8, 2),
MTK_PIN_DRV_GRP(61, 0xc20, 8, 2),
MTK_PIN_DRV_GRP(62, 0xc20, 8, 2),
MTK_PIN_DRV_GRP(63, 0xc20, 8, 2),
MTK_PIN_DRV_GRP(64, 0xc20, 8, 2),
MTK_PIN_DRV_GRP(65, 0xc00, 8, 2),
MTK_PIN_DRV_GRP(66, 0xc10, 8, 2),
MTK_PIN_DRV_GRP(67, 0xd10, 8, 2),
MTK_PIN_DRV_GRP(68, 0xd00, 8, 2),
MTK_PIN_DRV_GRP(69, DRV_BASE+0x80, 0, 1),
MTK_PIN_DRV_GRP(70, DRV_BASE+0x80, 0, 1),
MTK_PIN_DRV_GRP(71, DRV_BASE+0x80, 0, 1),
MTK_PIN_DRV_GRP(72, DRV_BASE+0x80, 0, 1),
MTK_PIN_DRV_GRP(73, 0xc60, 8, 2),
MTK_PIN_DRV_GRP(74, 0xc60, 8, 2),
MTK_PIN_DRV_GRP(75, 0xc60, 8, 2),
MTK_PIN_DRV_GRP(76, 0xc60, 8, 2),
MTK_PIN_DRV_GRP(77, 0xc40, 8, 2),
MTK_PIN_DRV_GRP(78, 0xc50, 8, 2),
MTK_PIN_DRV_GRP(79, DRV_BASE+0x70, 12, 1),
MTK_PIN_DRV_GRP(80, DRV_BASE+0x70, 12, 1),
MTK_PIN_DRV_GRP(81, DRV_BASE+0x70, 12, 1),
MTK_PIN_DRV_GRP(82, DRV_BASE+0x70, 12, 1),
MTK_PIN_DRV_GRP(83, DRV_BASE, 4, 1),
MTK_PIN_DRV_GRP(84, DRV_BASE, 0, 1),
MTK_PIN_DRV_GRP(85, DRV_BASE, 0, 1),
MTK_PIN_DRV_GRP(85, DRV_BASE+0x60, 8, 1),
MTK_PIN_DRV_GRP(86, DRV_BASE+0x60, 8, 1),
MTK_PIN_DRV_GRP(87, DRV_BASE+0x60, 8, 1),
MTK_PIN_DRV_GRP(88, DRV_BASE+0x60, 8, 1),
MTK_PIN_DRV_GRP(89, DRV_BASE+0x60, 8, 1),
MTK_PIN_DRV_GRP(90, DRV_BASE+0x60, 8, 1),
MTK_PIN_DRV_GRP(91, DRV_BASE+0x60, 8, 1),
MTK_PIN_DRV_GRP(92, DRV_BASE+0x60, 4, 0),
MTK_PIN_DRV_GRP(93, DRV_BASE+0x60, 0, 0),
MTK_PIN_DRV_GRP(94, DRV_BASE+0x60, 0, 0),
MTK_PIN_DRV_GRP(95, DRV_BASE+0x60, 0, 0),
MTK_PIN_DRV_GRP(96, DRV_BASE+0x80, 8, 1),
MTK_PIN_DRV_GRP(97, DRV_BASE+0x80, 8, 1),
MTK_PIN_DRV_GRP(98, DRV_BASE+0x80, 8, 1),
MTK_PIN_DRV_GRP(99, DRV_BASE+0x80, 8, 1),
MTK_PIN_DRV_GRP(100, 0xca0, 8, 2),
MTK_PIN_DRV_GRP(101, 0xca0, 8, 2),
MTK_PIN_DRV_GRP(102, 0xca0, 8, 2),
MTK_PIN_DRV_GRP(103, 0xca0, 8, 2),
MTK_PIN_DRV_GRP(104, 0xc80, 8, 2),
MTK_PIN_DRV_GRP(105, 0xc90, 8, 2),
MTK_PIN_DRV_GRP(108, DRV_BASE+0x50, 0, 1),
MTK_PIN_DRV_GRP(109, DRV_BASE+0x50, 0, 1),
MTK_PIN_DRV_GRP(110, DRV_BASE+0x50, 0, 1),
MTK_PIN_DRV_GRP(111, DRV_BASE+0x50, 0, 1),
MTK_PIN_DRV_GRP(112, DRV_BASE+0x50, 0, 1),
MTK_PIN_DRV_GRP(113, DRV_BASE+0x80, 4, 1),
MTK_PIN_DRV_GRP(114, DRV_BASE+0x80, 4, 1),
MTK_PIN_DRV_GRP(115, DRV_BASE+0x80, 4, 1),
MTK_PIN_DRV_GRP(116, DRV_BASE+0x80, 4, 1),
MTK_PIN_DRV_GRP(117, DRV_BASE+0x90, 0, 1),
MTK_PIN_DRV_GRP(118, DRV_BASE+0x90, 0, 1),
MTK_PIN_DRV_GRP(119, DRV_BASE+0x50, 4, 1),
MTK_PIN_DRV_GRP(120, DRV_BASE+0x50, 4, 1),
MTK_PIN_DRV_GRP(121, DRV_BASE+0x50, 4, 1),
MTK_PIN_DRV_GRP(122, DRV_BASE+0x50, 4, 1),
MTK_PIN_DRV_GRP(123, DRV_BASE+0x50, 4, 1),
MTK_PIN_DRV_GRP(124, DRV_BASE+0x50, 4, 1),
MTK_PIN_DRV_GRP(125, DRV_BASE+0x30, 12, 1),
MTK_PIN_DRV_GRP(126, DRV_BASE+0x30, 12, 1),
MTK_PIN_DRV_GRP(127, DRV_BASE+0x50, 8, 1),
MTK_PIN_DRV_GRP(128, DRV_BASE+0x40, 0, 1),
MTK_PIN_DRV_GRP(129, DRV_BASE+0x40, 0, 1),
MTK_PIN_DRV_GRP(130, DRV_BASE+0x40, 0, 1),
MTK_PIN_DRV_GRP(131, DRV_BASE+0x40, 0, 1),
MTK_PIN_DRV_GRP(132, DRV_BASE+0x40, 0, 1)
};
static const struct mtk_pinctrl_devdata mt8173_pinctrl_data = {
.pins = mtk_pins_mt8173,
.npins = ARRAY_SIZE(mtk_pins_mt8173),
.grp_desc = mt8173_drv_grp,
.n_grp_cls = ARRAY_SIZE(mt8173_drv_grp),
.pin_drv_grp = mt8173_pin_drv,
.n_pin_drv_grps = ARRAY_SIZE(mt8173_pin_drv),
.spec_pull_set = spec_pull_set,
.spec_ies_smt_set = spec_ies_smt_set,
.dir_offset = 0x0000,
.pullen_offset = 0x0100,
.pullsel_offset = 0x0200,
.dout_offset = 0x0400,
.din_offset = 0x0500,
.pinmux_offset = 0x0600,
.type1_start = 135,
.type1_end = 135,
.port_shf = 4,
.port_mask = 0xf,
.port_align = 4,
.eint_offsets = {
.name = "mt8173_eint",
.stat = 0x000,
.ack = 0x040,
.mask = 0x080,
.mask_set = 0x0c0,
.mask_clr = 0x100,
.sens = 0x140,
.sens_set = 0x180,
.sens_clr = 0x1c0,
.soft = 0x200,
.soft_set = 0x240,
.soft_clr = 0x280,
.pol = 0x300,
.pol_set = 0x340,
.pol_clr = 0x380,
.dom_en = 0x400,
.dbnc_ctrl = 0x500,
.dbnc_set = 0x600,
.dbnc_clr = 0x700,
.port_mask = 7,
.ports = 6,
},
.ap_num = 224,
.db_cnt = 16,
};
static int mt8173_pinctrl_probe(struct platform_device *pdev)
{
return mtk_pctrl_init(pdev, &mt8173_pinctrl_data);
}
static const struct of_device_id mt8173_pctrl_match[] = {
{
.compatible = "mediatek,mt8173-pinctrl",
},
{ }
};
MODULE_DEVICE_TABLE(of, mt8173_pctrl_match);
static struct platform_driver mtk_pinctrl_driver = {
.probe = mt8173_pinctrl_probe,
.driver = {
.name = "mediatek-mt8173-pinctrl",
.of_match_table = mt8173_pctrl_match,
},
};
static int __init mtk_pinctrl_init(void)
{
return platform_driver_register(&mtk_pinctrl_driver);
}
module_init(mtk_pinctrl_init);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("MediaTek Pinctrl Driver");
MODULE_AUTHOR("Hongzhou Yang <hongzhou.yang@mediatek.com>");

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,229 @@
/*
* Copyright (c) 2014 MediaTek Inc.
* Author: Hongzhou.Yang <hongzhou.yang@mediatek.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __PINCTRL_MTK_COMMON_H
#define __PINCTRL_MTK_COMMON_H
#include <linux/pinctrl/pinctrl.h>
#include <linux/regmap.h>
#define NO_EINT_SUPPORT 255
#define MTK_CHIP_TYPE_BASE 0
#define MTK_CHIP_TYPE_PMIC 1
#define MT_EDGE_SENSITIVE 0
#define MT_LEVEL_SENSITIVE 1
#define EINT_DBNC_SET_DBNC_BITS 4
#define EINT_DBNC_RST_BIT (0x1 << 1)
#define EINT_DBNC_SET_EN (0x1 << 0)
struct mtk_desc_function {
const char *name;
unsigned char muxval;
};
struct mtk_desc_eint {
unsigned char eintmux;
unsigned char eintnum;
};
struct mtk_desc_pin {
struct pinctrl_pin_desc pin;
const char *chip;
const struct mtk_desc_eint eint;
const struct mtk_desc_function *functions;
};
#define MTK_PIN(_pin, _pad, _chip, _eint, ...) \
{ \
.pin = _pin, \
.chip = _chip, \
.eint = _eint, \
.functions = (struct mtk_desc_function[]){ \
__VA_ARGS__, { } }, \
}
#define MTK_EINT_FUNCTION(_eintmux, _eintnum) \
{ \
.eintmux = _eintmux, \
.eintnum = _eintnum, \
}
#define MTK_FUNCTION(_val, _name) \
{ \
.muxval = _val, \
.name = _name, \
}
#define SET_ADDR(x, y) (x + (y->devdata->port_align))
#define CLR_ADDR(x, y) (x + (y->devdata->port_align << 1))
struct mtk_pinctrl_group {
const char *name;
unsigned long config;
unsigned pin;
};
/**
* struct mtk_drv_group_desc - Provide driving group data.
* @max_drv: The maximum current of this group.
* @min_drv: The minimum current of this group.
* @low_bit: The lowest bit of this group.
* @high_bit: The highest bit of this group.
* @step: The step current of this group.
*/
struct mtk_drv_group_desc {
unsigned char min_drv;
unsigned char max_drv;
unsigned char low_bit;
unsigned char high_bit;
unsigned char step;
};
#define MTK_DRV_GRP(_min, _max, _low, _high, _step) \
{ \
.min_drv = _min, \
.max_drv = _max, \
.low_bit = _low, \
.high_bit = _high, \
.step = _step, \
}
/**
* struct mtk_pin_drv_grp - Provide each pin driving info.
* @pin: The pin number.
* @offset: The offset of driving register for this pin.
* @bit: The bit of driving register for this pin.
* @grp: The group for this pin belongs to.
*/
struct mtk_pin_drv_grp {
unsigned int pin;
unsigned int offset;
unsigned char bit;
unsigned char grp;
};
#define MTK_PIN_DRV_GRP(_pin, _offset, _bit, _grp) \
{ \
.pin = _pin, \
.offset = _offset, \
.bit = _bit, \
.grp = _grp, \
}
struct mtk_eint_offsets {
const char *name;
unsigned int stat;
unsigned int ack;
unsigned int mask;
unsigned int mask_set;
unsigned int mask_clr;
unsigned int sens;
unsigned int sens_set;
unsigned int sens_clr;
unsigned int soft;
unsigned int soft_set;
unsigned int soft_clr;
unsigned int pol;
unsigned int pol_set;
unsigned int pol_clr;
unsigned int dom_en;
unsigned int dbnc_ctrl;
unsigned int dbnc_set;
unsigned int dbnc_clr;
u8 port_mask;
u8 ports;
};
/**
* struct mtk_pinctrl_devdata - Provide HW GPIO related data.
* @pins: An array describing all pins the pin controller affects.
* @npins: The number of entries in @pins.
*
* @grp_desc: The driving group info.
* @pin_drv_grp: The driving group for all pins.
* @spec_pull_set: Each SoC may have special pins for pull up/down setting,
* these pins' pull setting are very different, they have separate pull
* up/down bit, R0 and R1 resistor bit, so they need special pull setting.
* If special setting is success, this should return 0, otherwise it should
* return non-zero value.
* @spec_ies_smt_set: Some pins are irregular, their input enable and smt
* control register are discontinuous, but they are mapping together. That
* means when user set smt, input enable is set at the same time. So they
* also need special control. If special control is success, this should
* return 0, otherwise return non-zero value.
*
* @dir_offset: The direction register offset.
* @pullen_offset: The pull-up/pull-down enable register offset.
* @pinmux_offset: The pinmux register offset.
*
* @type1_start: Some chips have two base addresses for pull select register,
* that means some pins use the first address and others use the second. This
* member record the start of pin number to use the second address.
* @type1_end: The end of pin number to use the second address.
*
* @port_shf: The shift between two registers.
* @port_mask: The mask of register.
* @port_align: Provide clear register and set register step.
*/
struct mtk_pinctrl_devdata {
const struct mtk_desc_pin *pins;
unsigned int npins;
const struct mtk_drv_group_desc *grp_desc;
unsigned int n_grp_cls;
const struct mtk_pin_drv_grp *pin_drv_grp;
unsigned int n_pin_drv_grps;
int (*spec_pull_set)(struct regmap *reg, unsigned int pin,
unsigned char align, bool isup, unsigned int arg);
int (*spec_ies_smt_set)(struct regmap *reg, unsigned int pin,
unsigned char align, int value);
unsigned int dir_offset;
unsigned int ies_offset;
unsigned int smt_offset;
unsigned int pullen_offset;
unsigned int pullsel_offset;
unsigned int drv_offset;
unsigned int invser_offset;
unsigned int dout_offset;
unsigned int din_offset;
unsigned int pinmux_offset;
unsigned short type1_start;
unsigned short type1_end;
unsigned char port_shf;
unsigned char port_mask;
unsigned char port_align;
unsigned char chip_type;
struct mtk_eint_offsets eint_offsets;
unsigned int ap_num;
unsigned int db_cnt;
};
struct mtk_pinctrl {
struct regmap *regmap1;
struct regmap *regmap2;
struct device *dev;
struct gpio_chip *chip;
struct mtk_pinctrl_group *groups;
unsigned ngroups;
const char **grp_names;
struct pinctrl_dev *pctl_dev;
const struct mtk_pinctrl_devdata *devdata;
void __iomem *eint_reg_base;
struct irq_domain *domain;
int *eint_dual_edges;
};
int mtk_pctrl_init(struct platform_device *pdev,
const struct mtk_pinctrl_devdata *data);
#endif /* __PINCTRL_MTK_COMMON_H */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,2 +1,2 @@
obj-y += pinctrl-meson8.o
obj-y += pinctrl-meson8.o pinctrl-meson8b.o
obj-y += pinctrl-meson.o

Просмотреть файл

@ -13,8 +13,9 @@
/*
* The available pins are organized in banks (A,B,C,D,E,X,Y,Z,AO,
* BOOT,CARD for meson6 and X,Y,DV,H,Z,AO,BOOT,CARD for meson8) and
* each bank has a variable number of pins.
* BOOT,CARD for meson6, X,Y,DV,H,Z,AO,BOOT,CARD for meson8 and
* X,Y,DV,H,AO,BOOT,CARD,DIF for meson8b) and each bank has a
* variable number of pins.
*
* The AO bank is special because it belongs to the Always-On power
* domain which can't be powered off; the bank also uses a set of
@ -544,6 +545,10 @@ static const struct of_device_id meson_pinctrl_dt_match[] = {
.compatible = "amlogic,meson8-pinctrl",
.data = &meson8_pinctrl_data,
},
{
.compatible = "amlogic,meson8b-pinctrl",
.data = &meson8b_pinctrl_data,
},
{ },
};
MODULE_DEVICE_TABLE(of, meson_pinctrl_dt_match);

Просмотреть файл

@ -155,6 +155,8 @@ struct meson_pinctrl {
struct meson_domain *domains;
};
#define PIN(x, b) (b + x)
#define GROUP(grp, r, b) \
{ \
.name = #grp, \
@ -165,10 +167,10 @@ struct meson_pinctrl {
.domain = 0, \
}
#define GPIO_GROUP(gpio) \
#define GPIO_GROUP(gpio, b) \
{ \
.name = #gpio, \
.pins = (const unsigned int[]){ PIN_ ## gpio}, \
.pins = (const unsigned int[]){ PIN(gpio, b) }, \
.num_pins = 1, \
.is_gpio = true, \
}
@ -204,6 +206,7 @@ struct meson_pinctrl {
}, \
}
#define MESON_PIN(x) PINCTRL_PIN(PIN_ ## x, #x)
#define MESON_PIN(x, b) PINCTRL_PIN(PIN(x, b), #x)
extern struct meson_pinctrl_data meson8_pinctrl_data;
extern struct meson_pinctrl_data meson8b_pinctrl_data;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,899 @@
/*
* Pin controller and GPIO driver for Amlogic Meson8b.
*
* Copyright (C) 2015 Endless Mobile, Inc.
* Author: Carlo Caione <carlo@endlessm.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <dt-bindings/gpio/meson8b-gpio.h>
#include "pinctrl-meson.h"
#define AO_OFF 130
static const struct pinctrl_pin_desc meson8b_pins[] = {
MESON_PIN(GPIOX_0, 0),
MESON_PIN(GPIOX_1, 0),
MESON_PIN(GPIOX_2, 0),
MESON_PIN(GPIOX_3, 0),
MESON_PIN(GPIOX_4, 0),
MESON_PIN(GPIOX_5, 0),
MESON_PIN(GPIOX_6, 0),
MESON_PIN(GPIOX_7, 0),
MESON_PIN(GPIOX_8, 0),
MESON_PIN(GPIOX_9, 0),
MESON_PIN(GPIOX_10, 0),
MESON_PIN(GPIOX_11, 0),
MESON_PIN(GPIOX_16, 0),
MESON_PIN(GPIOX_17, 0),
MESON_PIN(GPIOX_18, 0),
MESON_PIN(GPIOX_19, 0),
MESON_PIN(GPIOX_20, 0),
MESON_PIN(GPIOX_21, 0),
MESON_PIN(GPIOY_0, 0),
MESON_PIN(GPIOY_1, 0),
MESON_PIN(GPIOY_3, 0),
MESON_PIN(GPIOY_6, 0),
MESON_PIN(GPIOY_7, 0),
MESON_PIN(GPIOY_8, 0),
MESON_PIN(GPIOY_9, 0),
MESON_PIN(GPIOY_10, 0),
MESON_PIN(GPIOY_11, 0),
MESON_PIN(GPIOY_12, 0),
MESON_PIN(GPIOY_13, 0),
MESON_PIN(GPIOY_14, 0),
MESON_PIN(GPIODV_9, 0),
MESON_PIN(GPIODV_24, 0),
MESON_PIN(GPIODV_25, 0),
MESON_PIN(GPIODV_26, 0),
MESON_PIN(GPIODV_27, 0),
MESON_PIN(GPIODV_28, 0),
MESON_PIN(GPIODV_29, 0),
MESON_PIN(GPIOH_0, 0),
MESON_PIN(GPIOH_1, 0),
MESON_PIN(GPIOH_2, 0),
MESON_PIN(GPIOH_3, 0),
MESON_PIN(GPIOH_4, 0),
MESON_PIN(GPIOH_5, 0),
MESON_PIN(GPIOH_6, 0),
MESON_PIN(GPIOH_7, 0),
MESON_PIN(GPIOH_8, 0),
MESON_PIN(GPIOH_9, 0),
MESON_PIN(CARD_0, 0),
MESON_PIN(CARD_1, 0),
MESON_PIN(CARD_2, 0),
MESON_PIN(CARD_3, 0),
MESON_PIN(CARD_4, 0),
MESON_PIN(CARD_5, 0),
MESON_PIN(CARD_6, 0),
MESON_PIN(BOOT_0, 0),
MESON_PIN(BOOT_1, 0),
MESON_PIN(BOOT_2, 0),
MESON_PIN(BOOT_3, 0),
MESON_PIN(BOOT_4, 0),
MESON_PIN(BOOT_5, 0),
MESON_PIN(BOOT_6, 0),
MESON_PIN(BOOT_7, 0),
MESON_PIN(BOOT_8, 0),
MESON_PIN(BOOT_9, 0),
MESON_PIN(BOOT_10, 0),
MESON_PIN(BOOT_11, 0),
MESON_PIN(BOOT_12, 0),
MESON_PIN(BOOT_13, 0),
MESON_PIN(BOOT_14, 0),
MESON_PIN(BOOT_15, 0),
MESON_PIN(BOOT_16, 0),
MESON_PIN(BOOT_17, 0),
MESON_PIN(BOOT_18, 0),
MESON_PIN(DIF_0_P, 0),
MESON_PIN(DIF_0_N, 0),
MESON_PIN(DIF_1_P, 0),
MESON_PIN(DIF_1_N, 0),
MESON_PIN(DIF_2_P, 0),
MESON_PIN(DIF_2_N, 0),
MESON_PIN(DIF_3_P, 0),
MESON_PIN(DIF_3_N, 0),
MESON_PIN(DIF_4_P, 0),
MESON_PIN(DIF_4_N, 0),
MESON_PIN(GPIOAO_0, AO_OFF),
MESON_PIN(GPIOAO_1, AO_OFF),
MESON_PIN(GPIOAO_2, AO_OFF),
MESON_PIN(GPIOAO_3, AO_OFF),
MESON_PIN(GPIOAO_4, AO_OFF),
MESON_PIN(GPIOAO_5, AO_OFF),
MESON_PIN(GPIOAO_6, AO_OFF),
MESON_PIN(GPIOAO_7, AO_OFF),
MESON_PIN(GPIOAO_8, AO_OFF),
MESON_PIN(GPIOAO_9, AO_OFF),
MESON_PIN(GPIOAO_10, AO_OFF),
MESON_PIN(GPIOAO_11, AO_OFF),
MESON_PIN(GPIOAO_12, AO_OFF),
MESON_PIN(GPIOAO_13, AO_OFF),
MESON_PIN(GPIO_BSD_EN, AO_OFF),
MESON_PIN(GPIO_TEST_N, AO_OFF),
};
/* bank X */
static const unsigned int sd_d0_a_pins[] = { PIN(GPIOX_0, 0) };
static const unsigned int sd_d1_a_pins[] = { PIN(GPIOX_1, 0) };
static const unsigned int sd_d2_a_pins[] = { PIN(GPIOX_2, 0) };
static const unsigned int sd_d3_a_pins[] = { PIN(GPIOX_3, 0) };
static const unsigned int sdxc_d0_0_a_pins[] = { PIN(GPIOX_4, 0) };
static const unsigned int sdxc_d47_a_pins[] = { PIN(GPIOX_4, 0), PIN(GPIOX_5, 0),
PIN(GPIOX_6, 0), PIN(GPIOX_7, 0) };
static const unsigned int sdxc_d13_0_a_pins[] = { PIN(GPIOX_5, 0), PIN(GPIOX_6, 0),
PIN(GPIOX_7, 0) };
static const unsigned int sd_clk_a_pins[] = { PIN(GPIOX_8, 0) };
static const unsigned int sd_cmd_a_pins[] = { PIN(GPIOX_9, 0) };
static const unsigned int xtal_32k_out_pins[] = { PIN(GPIOX_10, 0) };
static const unsigned int xtal_24m_out_pins[] = { PIN(GPIOX_11, 0) };
static const unsigned int uart_tx_b0_pins[] = { PIN(GPIOX_16, 0) };
static const unsigned int uart_rx_b0_pins[] = { PIN(GPIOX_17, 0) };
static const unsigned int uart_cts_b0_pins[] = { PIN(GPIOX_18, 0) };
static const unsigned int uart_rts_b0_pins[] = { PIN(GPIOX_19, 0) };
static const unsigned int sdxc_d0_1_a_pins[] = { PIN(GPIOX_0, 0) };
static const unsigned int sdxc_d13_1_a_pins[] = { PIN(GPIOX_1, 0), PIN(GPIOX_2, 0),
PIN(GPIOX_3, 0) };
static const unsigned int pcm_out_a_pins[] = { PIN(GPIOX_4, 0) };
static const unsigned int pcm_in_a_pins[] = { PIN(GPIOX_5, 0) };
static const unsigned int pcm_fs_a_pins[] = { PIN(GPIOX_6, 0) };
static const unsigned int pcm_clk_a_pins[] = { PIN(GPIOX_7, 0) };
static const unsigned int sdxc_clk_a_pins[] = { PIN(GPIOX_8, 0) };
static const unsigned int sdxc_cmd_a_pins[] = { PIN(GPIOX_9, 0) };
static const unsigned int pwm_vs_0_pins[] = { PIN(GPIOX_10, 0) };
static const unsigned int pwm_e_pins[] = { PIN(GPIOX_10, 0) };
static const unsigned int pwm_vs_1_pins[] = { PIN(GPIOX_11, 0) };
static const unsigned int uart_tx_a_pins[] = { PIN(GPIOX_4, 0) };
static const unsigned int uart_rx_a_pins[] = { PIN(GPIOX_5, 0) };
static const unsigned int uart_cts_a_pins[] = { PIN(GPIOX_6, 0) };
static const unsigned int uart_rts_a_pins[] = { PIN(GPIOX_7, 0) };
static const unsigned int uart_tx_b1_pins[] = { PIN(GPIOX_8, 0) };
static const unsigned int uart_rx_b1_pins[] = { PIN(GPIOX_9, 0) };
static const unsigned int uart_cts_b1_pins[] = { PIN(GPIOX_10, 0) };
static const unsigned int uart_rts_b1_pins[] = { PIN(GPIOX_20, 0) };
static const unsigned int iso7816_0_clk_pins[] = { PIN(GPIOX_6, 0) };
static const unsigned int iso7816_0_data_pins[] = { PIN(GPIOX_7, 0) };
static const unsigned int spi_sclk_0_pins[] = { PIN(GPIOX_8, 0) };
static const unsigned int spi_miso_0_pins[] = { PIN(GPIOX_9, 0) };
static const unsigned int spi_mosi_0_pins[] = { PIN(GPIOX_10, 0) };
static const unsigned int iso7816_det_pins[] = { PIN(GPIOX_16, 0) };
static const unsigned int iso7816_reset_pins[] = { PIN(GPIOX_17, 0) };
static const unsigned int iso7816_1_clk_pins[] = { PIN(GPIOX_18, 0) };
static const unsigned int iso7816_1_data_pins[] = { PIN(GPIOX_19, 0) };
static const unsigned int spi_ss0_0_pins[] = { PIN(GPIOX_20, 0) };
static const unsigned int tsin_clk_b_pins[] = { PIN(GPIOX_8, 0) };
static const unsigned int tsin_sop_b_pins[] = { PIN(GPIOX_9, 0) };
static const unsigned int tsin_d0_b_pins[] = { PIN(GPIOX_10, 0) };
static const unsigned int pwm_b_pins[] = { PIN(GPIOX_11, 0) };
static const unsigned int i2c_sda_d0_pins[] = { PIN(GPIOX_16, 0) };
static const unsigned int i2c_sck_d0_pins[] = { PIN(GPIOX_17, 0) };
static const unsigned int tsin_d_valid_b_pins[] = { PIN(GPIOX_20, 0) };
/* bank Y */
static const unsigned int tsin_d_valid_a_pins[] = { PIN(GPIOY_0, 0) };
static const unsigned int tsin_sop_a_pins[] = { PIN(GPIOY_1, 0) };
static const unsigned int tsin_d17_a_pins[] = { PIN(GPIOY_6, 0), PIN(GPIOY_7, 0),
PIN(GPIOY_10, 0), PIN(GPIOY_11, 0),
PIN(GPIOY_12, 0), PIN(GPIOY_13, 0),
PIN(GPIOY_14, 0) };
static const unsigned int tsin_clk_a_pins[] = { PIN(GPIOY_8, 0) };
static const unsigned int tsin_d0_a_pins[] = { PIN(GPIOY_9, 0) };
static const unsigned int spdif_out_0_pins[] = { PIN(GPIOY_3, 0) };
static const unsigned int xtal_24m_pins[] = { PIN(GPIOY_3, 0) };
static const unsigned int iso7816_2_clk_pins[] = { PIN(GPIOY_13, 0) };
static const unsigned int iso7816_2_data_pins[] = { PIN(GPIOY_14, 0) };
/* bank DV */
static const unsigned int pwm_d_pins[] = { PIN(GPIODV_28, 0) };
static const unsigned int pwm_c0_pins[] = { PIN(GPIODV_29, 0) };
static const unsigned int pwm_vs_2_pins[] = { PIN(GPIODV_9, 0) };
static const unsigned int pwm_vs_3_pins[] = { PIN(GPIODV_28, 0) };
static const unsigned int pwm_vs_4_pins[] = { PIN(GPIODV_29, 0) };
static const unsigned int xtal24_out_pins[] = { PIN(GPIODV_29, 0) };
static const unsigned int uart_tx_c_pins[] = { PIN(GPIODV_24, 0) };
static const unsigned int uart_rx_c_pins[] = { PIN(GPIODV_25, 0) };
static const unsigned int uart_cts_c_pins[] = { PIN(GPIODV_26, 0) };
static const unsigned int uart_rts_c_pins[] = { PIN(GPIODV_27, 0) };
static const unsigned int pwm_c1_pins[] = { PIN(GPIODV_9, 0) };
static const unsigned int i2c_sda_a_pins[] = { PIN(GPIODV_24, 0) };
static const unsigned int i2c_sck_a_pins[] = { PIN(GPIODV_25, 0) };
static const unsigned int i2c_sda_b0_pins[] = { PIN(GPIODV_26, 0) };
static const unsigned int i2c_sck_b0_pins[] = { PIN(GPIODV_27, 0) };
static const unsigned int i2c_sda_c0_pins[] = { PIN(GPIODV_28, 0) };
static const unsigned int i2c_sck_c0_pins[] = { PIN(GPIODV_29, 0) };
/* bank H */
static const unsigned int hdmi_hpd_pins[] = { PIN(GPIOH_0, 0) };
static const unsigned int hdmi_sda_pins[] = { PIN(GPIOH_1, 0) };
static const unsigned int hdmi_scl_pins[] = { PIN(GPIOH_2, 0) };
static const unsigned int hdmi_cec_0_pins[] = { PIN(GPIOH_3, 0) };
static const unsigned int eth_txd1_0_pins[] = { PIN(GPIOH_5, 0) };
static const unsigned int eth_txd0_0_pins[] = { PIN(GPIOH_6, 0) };
static const unsigned int clk_24m_out_pins[] = { PIN(GPIOH_9, 0) };
static const unsigned int spi_ss1_pins[] = { PIN(GPIOH_0, 0) };
static const unsigned int spi_ss2_pins[] = { PIN(GPIOH_1, 0) };
static const unsigned int spi_ss0_1_pins[] = { PIN(GPIOH_3, 0) };
static const unsigned int spi_miso_1_pins[] = { PIN(GPIOH_4, 0) };
static const unsigned int spi_mosi_1_pins[] = { PIN(GPIOH_5, 0) };
static const unsigned int spi_sclk_1_pins[] = { PIN(GPIOH_6, 0) };
static const unsigned int eth_txd3_pins[] = { PIN(GPIOH_7, 0) };
static const unsigned int eth_txd2_pins[] = { PIN(GPIOH_8, 0) };
static const unsigned int eth_tx_clk_pins[] = { PIN(GPIOH_9, 0) };
static const unsigned int i2c_sda_b1_pins[] = { PIN(GPIOH_3, 0) };
static const unsigned int i2c_sck_b1_pins[] = { PIN(GPIOH_4, 0) };
static const unsigned int i2c_sda_c1_pins[] = { PIN(GPIOH_5, 0) };
static const unsigned int i2c_sck_c1_pins[] = { PIN(GPIOH_6, 0) };
static const unsigned int i2c_sda_d1_pins[] = { PIN(GPIOH_7, 0) };
static const unsigned int i2c_sck_d1_pins[] = { PIN(GPIOH_8, 0) };
/* bank BOOT */
static const unsigned int nand_io_pins[] = { PIN(BOOT_0, 0), PIN(BOOT_1, 0),
PIN(BOOT_2, 0), PIN(BOOT_3, 0),
PIN(BOOT_4, 0), PIN(BOOT_5, 0),
PIN(BOOT_6, 0), PIN(BOOT_7, 0) };
static const unsigned int nand_io_ce0_pins[] = { PIN(BOOT_8, 0) };
static const unsigned int nand_io_ce1_pins[] = { PIN(BOOT_9, 0) };
static const unsigned int nand_io_rb0_pins[] = { PIN(BOOT_10, 0) };
static const unsigned int nand_ale_pins[] = { PIN(BOOT_11, 0) };
static const unsigned int nand_cle_pins[] = { PIN(BOOT_12, 0) };
static const unsigned int nand_wen_clk_pins[] = { PIN(BOOT_13, 0) };
static const unsigned int nand_ren_clk_pins[] = { PIN(BOOT_14, 0) };
static const unsigned int nand_dqs_0_pins[] = { PIN(BOOT_15, 0) };
static const unsigned int nand_dqs_1_pins[] = { PIN(BOOT_18, 0) };
static const unsigned int sdxc_d0_c_pins[] = { PIN(BOOT_0, 0)};
static const unsigned int sdxc_d13_c_pins[] = { PIN(BOOT_1, 0), PIN(BOOT_2, 0),
PIN(BOOT_3, 0) };
static const unsigned int sdxc_d47_c_pins[] = { PIN(BOOT_4, 0), PIN(BOOT_5, 0),
PIN(BOOT_6, 0), PIN(BOOT_7, 0) };
static const unsigned int sdxc_clk_c_pins[] = { PIN(BOOT_8, 0) };
static const unsigned int sdxc_cmd_c_pins[] = { PIN(BOOT_10, 0) };
static const unsigned int nor_d_pins[] = { PIN(BOOT_11, 0) };
static const unsigned int nor_q_pins[] = { PIN(BOOT_12, 0) };
static const unsigned int nor_c_pins[] = { PIN(BOOT_13, 0) };
static const unsigned int nor_cs_pins[] = { PIN(BOOT_18, 0) };
static const unsigned int sd_d0_c_pins[] = { PIN(BOOT_0, 0) };
static const unsigned int sd_d1_c_pins[] = { PIN(BOOT_1, 0) };
static const unsigned int sd_d2_c_pins[] = { PIN(BOOT_2, 0) };
static const unsigned int sd_d3_c_pins[] = { PIN(BOOT_3, 0) };
static const unsigned int sd_cmd_c_pins[] = { PIN(BOOT_8, 0) };
static const unsigned int sd_clk_c_pins[] = { PIN(BOOT_10, 0) };
/* bank CARD */
static const unsigned int sd_d1_b_pins[] = { PIN(CARD_0, 0) };
static const unsigned int sd_d0_b_pins[] = { PIN(CARD_1, 0) };
static const unsigned int sd_clk_b_pins[] = { PIN(CARD_2, 0) };
static const unsigned int sd_cmd_b_pins[] = { PIN(CARD_3, 0) };
static const unsigned int sd_d3_b_pins[] = { PIN(CARD_4, 0) };
static const unsigned int sd_d2_b_pins[] = { PIN(CARD_5, 0) };
static const unsigned int sdxc_d13_b_pins[] = { PIN(CARD_0, 0), PIN(CARD_4, 0),
PIN(CARD_5, 0) };
static const unsigned int sdxc_d0_b_pins[] = { PIN(CARD_1, 0) };
static const unsigned int sdxc_clk_b_pins[] = { PIN(CARD_2, 0) };
static const unsigned int sdxc_cmd_b_pins[] = { PIN(CARD_3, 0) };
/* bank AO */
static const unsigned int uart_tx_ao_a_pins[] = { PIN(GPIOAO_0, AO_OFF) };
static const unsigned int uart_rx_ao_a_pins[] = { PIN(GPIOAO_1, AO_OFF) };
static const unsigned int uart_cts_ao_a_pins[] = { PIN(GPIOAO_2, AO_OFF) };
static const unsigned int uart_rts_ao_a_pins[] = { PIN(GPIOAO_3, AO_OFF) };
static const unsigned int i2c_mst_sck_ao_pins[] = { PIN(GPIOAO_4, AO_OFF) };
static const unsigned int i2c_mst_sda_ao_pins[] = { PIN(GPIOAO_5, AO_OFF) };
static const unsigned int clk_32k_in_out_pins[] = { PIN(GPIOAO_6, AO_OFF) };
static const unsigned int remote_input_pins[] = { PIN(GPIOAO_7, AO_OFF) };
static const unsigned int hdmi_cec_1_pins[] = { PIN(GPIOAO_12, AO_OFF) };
static const unsigned int ir_blaster_pins[] = { PIN(GPIOAO_13, AO_OFF) };
static const unsigned int pwm_c2_pins[] = { PIN(GPIOAO_3, AO_OFF) };
static const unsigned int i2c_sck_ao_pins[] = { PIN(GPIOAO_4, AO_OFF) };
static const unsigned int i2c_sda_ao_pins[] = { PIN(GPIOAO_5, AO_OFF) };
static const unsigned int ir_remote_out_pins[] = { PIN(GPIOAO_7, AO_OFF) };
static const unsigned int i2s_am_clk_out_pins[] = { PIN(GPIOAO_8, AO_OFF) };
static const unsigned int i2s_ao_clk_out_pins[] = { PIN(GPIOAO_9, AO_OFF) };
static const unsigned int i2s_lr_clk_out_pins[] = { PIN(GPIOAO_10, AO_OFF) };
static const unsigned int i2s_out_01_pins[] = { PIN(GPIOAO_11, AO_OFF) };
static const unsigned int uart_tx_ao_b0_pins[] = { PIN(GPIOAO_0, AO_OFF) };
static const unsigned int uart_rx_ao_b0_pins[] = { PIN(GPIOAO_1, AO_OFF) };
static const unsigned int uart_cts_ao_b_pins[] = { PIN(GPIOAO_2, AO_OFF) };
static const unsigned int uart_rts_ao_b_pins[] = { PIN(GPIOAO_3, AO_OFF) };
static const unsigned int uart_tx_ao_b1_pins[] = { PIN(GPIOAO_4, AO_OFF) };
static const unsigned int uart_rx_ao_b1_pins[] = { PIN(GPIOAO_5, AO_OFF) };
static const unsigned int spdif_out_1_pins[] = { PIN(GPIOAO_6, AO_OFF) };
static const unsigned int i2s_in_ch01_pins[] = { PIN(GPIOAO_6, AO_OFF) };
static const unsigned int i2s_ao_clk_in_pins[] = { PIN(GPIOAO_9, AO_OFF) };
static const unsigned int i2s_lr_clk_in_pins[] = { PIN(GPIOAO_10, AO_OFF) };
/* bank DIF */
static const unsigned int eth_rxd1_pins[] = { PIN(DIF_0_P, 0) };
static const unsigned int eth_rxd0_pins[] = { PIN(DIF_0_N, 0) };
static const unsigned int eth_rx_dv_pins[] = { PIN(DIF_1_P, 0) };
static const unsigned int eth_rx_clk_pins[] = { PIN(DIF_1_N, 0) };
static const unsigned int eth_txd0_1_pins[] = { PIN(DIF_2_P, 0) };
static const unsigned int eth_txd1_1_pins[] = { PIN(DIF_2_N, 0) };
static const unsigned int eth_tx_en_pins[] = { PIN(DIF_3_P, 0) };
static const unsigned int eth_ref_clk_pins[] = { PIN(DIF_3_N, 0) };
static const unsigned int eth_mdc_pins[] = { PIN(DIF_4_P, 0) };
static const unsigned int eth_mdio_en_pins[] = { PIN(DIF_4_N, 0) };
static struct meson_pmx_group meson8b_groups[] = {
GPIO_GROUP(GPIOX_0, 0),
GPIO_GROUP(GPIOX_1, 0),
GPIO_GROUP(GPIOX_2, 0),
GPIO_GROUP(GPIOX_3, 0),
GPIO_GROUP(GPIOX_4, 0),
GPIO_GROUP(GPIOX_5, 0),
GPIO_GROUP(GPIOX_6, 0),
GPIO_GROUP(GPIOX_7, 0),
GPIO_GROUP(GPIOX_8, 0),
GPIO_GROUP(GPIOX_9, 0),
GPIO_GROUP(GPIOX_10, 0),
GPIO_GROUP(GPIOX_11, 0),
GPIO_GROUP(GPIOX_16, 0),
GPIO_GROUP(GPIOX_17, 0),
GPIO_GROUP(GPIOX_18, 0),
GPIO_GROUP(GPIOX_19, 0),
GPIO_GROUP(GPIOX_20, 0),
GPIO_GROUP(GPIOX_21, 0),
GPIO_GROUP(GPIOY_0, 0),
GPIO_GROUP(GPIOY_1, 0),
GPIO_GROUP(GPIOY_3, 0),
GPIO_GROUP(GPIOY_6, 0),
GPIO_GROUP(GPIOY_7, 0),
GPIO_GROUP(GPIOY_8, 0),
GPIO_GROUP(GPIOY_9, 0),
GPIO_GROUP(GPIOY_10, 0),
GPIO_GROUP(GPIOY_11, 0),
GPIO_GROUP(GPIOY_12, 0),
GPIO_GROUP(GPIOY_13, 0),
GPIO_GROUP(GPIOY_14, 0),
GPIO_GROUP(GPIODV_9, 0),
GPIO_GROUP(GPIODV_24, 0),
GPIO_GROUP(GPIODV_25, 0),
GPIO_GROUP(GPIODV_26, 0),
GPIO_GROUP(GPIODV_27, 0),
GPIO_GROUP(GPIODV_28, 0),
GPIO_GROUP(GPIODV_29, 0),
GPIO_GROUP(GPIOH_0, 0),
GPIO_GROUP(GPIOH_1, 0),
GPIO_GROUP(GPIOH_2, 0),
GPIO_GROUP(GPIOH_3, 0),
GPIO_GROUP(GPIOH_4, 0),
GPIO_GROUP(GPIOH_5, 0),
GPIO_GROUP(GPIOH_6, 0),
GPIO_GROUP(GPIOH_7, 0),
GPIO_GROUP(GPIOH_8, 0),
GPIO_GROUP(GPIOH_9, 0),
GPIO_GROUP(DIF_0_P, 0),
GPIO_GROUP(DIF_0_N, 0),
GPIO_GROUP(DIF_1_P, 0),
GPIO_GROUP(DIF_1_N, 0),
GPIO_GROUP(DIF_2_P, 0),
GPIO_GROUP(DIF_2_N, 0),
GPIO_GROUP(DIF_3_P, 0),
GPIO_GROUP(DIF_3_N, 0),
GPIO_GROUP(DIF_4_P, 0),
GPIO_GROUP(DIF_4_N, 0),
GPIO_GROUP(GPIOAO_0, AO_OFF),
GPIO_GROUP(GPIOAO_1, AO_OFF),
GPIO_GROUP(GPIOAO_2, AO_OFF),
GPIO_GROUP(GPIOAO_3, AO_OFF),
GPIO_GROUP(GPIOAO_4, AO_OFF),
GPIO_GROUP(GPIOAO_5, AO_OFF),
GPIO_GROUP(GPIOAO_6, AO_OFF),
GPIO_GROUP(GPIOAO_7, AO_OFF),
GPIO_GROUP(GPIOAO_8, AO_OFF),
GPIO_GROUP(GPIOAO_9, AO_OFF),
GPIO_GROUP(GPIOAO_10, AO_OFF),
GPIO_GROUP(GPIOAO_11, AO_OFF),
GPIO_GROUP(GPIOAO_12, AO_OFF),
GPIO_GROUP(GPIOAO_13, AO_OFF),
GPIO_GROUP(GPIO_BSD_EN, AO_OFF),
GPIO_GROUP(GPIO_TEST_N, AO_OFF),
/* bank X */
GROUP(sd_d0_a, 8, 5),
GROUP(sd_d1_a, 8, 4),
GROUP(sd_d2_a, 8, 3),
GROUP(sd_d3_a, 8, 2),
GROUP(sdxc_d0_0_a, 5, 29),
GROUP(sdxc_d47_a, 5, 12),
GROUP(sdxc_d13_0_a, 5, 28),
GROUP(sd_clk_a, 8, 1),
GROUP(sd_cmd_a, 8, 0),
GROUP(xtal_32k_out, 3, 22),
GROUP(xtal_24m_out, 3, 20),
GROUP(uart_tx_b0, 4, 9),
GROUP(uart_rx_b0, 4, 8),
GROUP(uart_cts_b0, 4, 7),
GROUP(uart_rts_b0, 4, 6),
GROUP(sdxc_d0_1_a, 5, 14),
GROUP(sdxc_d13_1_a, 5, 13),
GROUP(pcm_out_a, 3, 30),
GROUP(pcm_in_a, 3, 29),
GROUP(pcm_fs_a, 3, 28),
GROUP(pcm_clk_a, 3, 27),
GROUP(sdxc_clk_a, 5, 11),
GROUP(sdxc_cmd_a, 5, 10),
GROUP(pwm_vs_0, 7, 31),
GROUP(pwm_e, 9, 19),
GROUP(pwm_vs_1, 7, 30),
GROUP(uart_tx_a, 4, 17),
GROUP(uart_rx_a, 4, 16),
GROUP(uart_cts_a, 4, 15),
GROUP(uart_rts_a, 4, 14),
GROUP(uart_tx_b1, 6, 19),
GROUP(uart_rx_b1, 6, 18),
GROUP(uart_cts_b1, 6, 17),
GROUP(uart_rts_b1, 6, 16),
GROUP(iso7816_0_clk, 5, 9),
GROUP(iso7816_0_data, 5, 8),
GROUP(spi_sclk_0, 4, 22),
GROUP(spi_miso_0, 4, 24),
GROUP(spi_mosi_0, 4, 23),
GROUP(iso7816_det, 4, 21),
GROUP(iso7816_reset, 4, 20),
GROUP(iso7816_1_clk, 4, 19),
GROUP(iso7816_1_data, 4, 18),
GROUP(spi_ss0_0, 4, 25),
GROUP(tsin_clk_b, 3, 6),
GROUP(tsin_sop_b, 3, 7),
GROUP(tsin_d0_b, 3, 8),
GROUP(pwm_b, 2, 3),
GROUP(i2c_sda_d0, 4, 5),
GROUP(i2c_sck_d0, 4, 4),
GROUP(tsin_d_valid_b, 3, 9),
/* bank Y */
GROUP(tsin_d_valid_a, 3, 2),
GROUP(tsin_sop_a, 3, 1),
GROUP(tsin_d17_a, 3, 5),
GROUP(tsin_clk_a, 3, 0),
GROUP(tsin_d0_a, 3, 4),
GROUP(spdif_out_0, 1, 7),
GROUP(xtal_24m, 3, 18),
GROUP(iso7816_2_clk, 5, 7),
GROUP(iso7816_2_data, 5, 6),
/* bank DV */
GROUP(pwm_d, 3, 26),
GROUP(pwm_c0, 3, 25),
GROUP(pwm_vs_2, 7, 28),
GROUP(pwm_vs_3, 7, 27),
GROUP(pwm_vs_4, 7, 26),
GROUP(xtal24_out, 7, 25),
GROUP(uart_tx_c, 6, 23),
GROUP(uart_rx_c, 6, 22),
GROUP(uart_cts_c, 6, 21),
GROUP(uart_rts_c, 6, 20),
GROUP(pwm_c1, 3, 24),
GROUP(i2c_sda_a, 9, 31),
GROUP(i2c_sck_a, 9, 30),
GROUP(i2c_sda_b0, 9, 29),
GROUP(i2c_sck_b0, 9, 28),
GROUP(i2c_sda_c0, 9, 27),
GROUP(i2c_sck_c0, 9, 26),
/* bank H */
GROUP(hdmi_hpd, 1, 26),
GROUP(hdmi_sda, 1, 25),
GROUP(hdmi_scl, 1, 24),
GROUP(hdmi_cec_0, 1, 23),
GROUP(eth_txd1_0, 7, 21),
GROUP(eth_txd0_0, 7, 20),
GROUP(clk_24m_out, 4, 1),
GROUP(spi_ss1, 8, 11),
GROUP(spi_ss2, 8, 12),
GROUP(spi_ss0_1, 9, 13),
GROUP(spi_miso_1, 9, 12),
GROUP(spi_mosi_1, 9, 11),
GROUP(spi_sclk_1, 9, 10),
GROUP(eth_txd3, 6, 13),
GROUP(eth_txd2, 6, 12),
GROUP(eth_tx_clk, 6, 11),
GROUP(i2c_sda_b1, 5, 27),
GROUP(i2c_sck_b1, 5, 26),
GROUP(i2c_sda_c1, 5, 25),
GROUP(i2c_sck_c1, 5, 24),
GROUP(i2c_sda_d1, 4, 3),
GROUP(i2c_sck_d1, 4, 2),
/* bank BOOT */
GROUP(nand_io, 2, 26),
GROUP(nand_io_ce0, 2, 25),
GROUP(nand_io_ce1, 2, 24),
GROUP(nand_io_rb0, 2, 17),
GROUP(nand_ale, 2, 21),
GROUP(nand_cle, 2, 20),
GROUP(nand_wen_clk, 2, 19),
GROUP(nand_ren_clk, 2, 18),
GROUP(nand_dqs_0, 2, 27),
GROUP(nand_dqs_1, 2, 28),
GROUP(sdxc_d0_c, 4, 30),
GROUP(sdxc_d13_c, 4, 29),
GROUP(sdxc_d47_c, 4, 28),
GROUP(sdxc_clk_c, 7, 19),
GROUP(sdxc_cmd_c, 7, 18),
GROUP(nor_d, 5, 1),
GROUP(nor_q, 5, 3),
GROUP(nor_c, 5, 2),
GROUP(nor_cs, 5, 0),
GROUP(sd_d0_c, 6, 29),
GROUP(sd_d1_c, 6, 28),
GROUP(sd_d2_c, 6, 27),
GROUP(sd_d3_c, 6, 26),
GROUP(sd_cmd_c, 6, 30),
GROUP(sd_clk_c, 6, 31),
/* bank CARD */
GROUP(sd_d1_b, 2, 14),
GROUP(sd_d0_b, 2, 15),
GROUP(sd_clk_b, 2, 11),
GROUP(sd_cmd_b, 2, 10),
GROUP(sd_d3_b, 2, 12),
GROUP(sd_d2_b, 2, 13),
GROUP(sdxc_d13_b, 2, 6),
GROUP(sdxc_d0_b, 2, 7),
GROUP(sdxc_clk_b, 2, 5),
GROUP(sdxc_cmd_b, 2, 4),
/* bank AO */
GROUP(uart_tx_ao_a, 0, 12),
GROUP(uart_rx_ao_a, 0, 11),
GROUP(uart_cts_ao_a, 0, 10),
GROUP(uart_rts_ao_a, 0, 9),
GROUP(i2c_mst_sck_ao, 0, 6),
GROUP(i2c_mst_sda_ao, 0, 5),
GROUP(clk_32k_in_out, 0, 18),
GROUP(remote_input, 0, 0),
GROUP(hdmi_cec_1, 0, 17),
GROUP(ir_blaster, 0, 31),
GROUP(pwm_c2, 0, 22),
GROUP(i2c_sck_ao, 0, 2),
GROUP(i2c_sda_ao, 0, 1),
GROUP(ir_remote_out, 0, 21),
GROUP(i2s_am_clk_out, 0, 30),
GROUP(i2s_ao_clk_out, 0, 29),
GROUP(i2s_lr_clk_out, 0, 28),
GROUP(i2s_out_01, 0, 27),
GROUP(uart_tx_ao_b0, 0, 26),
GROUP(uart_rx_ao_b0, 0, 25),
GROUP(uart_cts_ao_b, 0, 8),
GROUP(uart_rts_ao_b, 0, 7),
GROUP(uart_tx_ao_b1, 0, 24),
GROUP(uart_rx_ao_b1, 0, 23),
GROUP(spdif_out_1, 0, 16),
GROUP(i2s_in_ch01, 0, 13),
GROUP(i2s_ao_clk_in, 0, 15),
GROUP(i2s_lr_clk_in, 0, 14),
/* bank DIF */
GROUP(eth_rxd1, 6, 0),
GROUP(eth_rxd0, 6, 1),
GROUP(eth_rx_dv, 6, 2),
GROUP(eth_rx_clk, 6, 3),
GROUP(eth_txd0_1, 6, 4),
GROUP(eth_txd1_1, 6, 5),
GROUP(eth_tx_en, 6, 0),
GROUP(eth_ref_clk, 6, 8),
GROUP(eth_mdc, 6, 9),
GROUP(eth_mdio_en, 6, 10),
};
static const char * const gpio_groups[] = {
"GPIOX_0", "GPIOX_1", "GPIOX_2", "GPIOX_3", "GPIOX_4",
"GPIOX_5", "GPIOX_6", "GPIOX_7", "GPIOX_8", "GPIOX_9",
"GPIOX_10", "GPIOX_11", "GPIOX_16", "GPIOX_17", "GPIOX_18",
"GPIOX_19", "GPIOX_20", "GPIOX_21",
"GPIOY_0", "GPIOY_1", "GPIOY_3", "GPIOY_6", "GPIOY_7",
"GPIOY_8", "GPIOY_9", "GPIOY_10", "GPIOY_11", "GPIOY_12",
"GPIOY_13", "GPIOY_14",
"GPIODV_9", "GPIODV_24", "GPIODV_25", "GPIODV_26",
"GPIODV_27", "GPIODV_28", "GPIODV_29",
"GPIOH_0", "GPIOH_1", "GPIOH_2", "GPIOH_3", "GPIOH_4",
"GPIOH_5", "GPIOH_6", "GPIOH_7", "GPIOH_8", "GPIOH_9",
"CARD_0", "CARD_1", "CARD_2", "CARD_3", "CARD_4",
"CARD_5", "CARD_6",
"BOOT_0", "BOOT_1", "BOOT_2", "BOOT_3", "BOOT_4",
"BOOT_5", "BOOT_6", "BOOT_7", "BOOT_8", "BOOT_9",
"BOOT_10", "BOOT_11", "BOOT_12", "BOOT_13", "BOOT_14",
"BOOT_15", "BOOT_16", "BOOT_17", "BOOT_18",
"GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3",
"GPIOAO_4", "GPIOAO_5", "GPIOAO_6", "GPIOAO_7",
"GPIOAO_8", "GPIOAO_9", "GPIOAO_10", "GPIOAO_11",
"GPIOAO_12", "GPIOAO_13", "GPIO_BSD_EN", "GPIO_TEST_N",
"DIF_0_P", "DIF_0_N", "DIF_1_P", "DIF_1_N",
"DIF_2_P", "DIF_2_N", "DIF_3_P", "DIF_3_N",
"DIF_4_P", "DIF_4_N"
};
static const char * const sd_a_groups[] = {
"sd_d0_a", "sd_d1_a", "sd_d2_a", "sd_d3_a", "sd_clk_a",
"sd_cmd_a"
};
static const char * const sdxc_a_groups[] = {
"sdxc_d0_0_a", "sdxc_d13_0_a", "sdxc_d47_a", "sdxc_clk_a",
"sdxc_cmd_a", "sdxc_d0_1_a", "sdxc_d0_13_1_a"
};
static const char * const pcm_a_groups[] = {
"pcm_out_a", "pcm_in_a", "pcm_fs_a", "pcm_clk_a"
};
static const char * const uart_a_groups[] = {
"uart_tx_a", "uart_rx_a", "uart_cts_a", "uart_rts_a"
};
static const char * const uart_b_groups[] = {
"uart_tx_b0", "uart_rx_b0", "uart_cts_b0", "uart_rts_b0",
"uart_tx_b1", "uart_rx_b1", "uart_cts_b1", "uart_rts_b1"
};
static const char * const iso7816_groups[] = {
"iso7816_det", "iso7816_reset", "iso7816_0_clk", "iso7816_0_data",
"iso7816_1_clk", "iso7816_1_data", "iso7816_2_clk", "iso7816_2_data"
};
static const char * const i2c_d_groups[] = {
"i2c_sda_d0", "i2c_sck_d0", "i2c_sda_d1", "i2c_sck_d1"
};
static const char * const xtal_groups[] = {
"xtal_32k_out", "xtal_24m_out", "xtal_24m", "xtal24_out"
};
static const char * const uart_c_groups[] = {
"uart_tx_c", "uart_rx_c", "uart_cts_c", "uart_rts_c"
};
static const char * const i2c_c_groups[] = {
"i2c_sda_c0", "i2c_sck_c0", "i2c_sda_c1", "i2c_sck_c1"
};
static const char * const hdmi_groups[] = {
"hdmi_hpd", "hdmi_sda", "hdmi_scl", "hdmi_cec_0",
"hdmi_cec_1"
};
static const char * const spi_groups[] = {
"spi_ss0_0", "spi_miso_0", "spi_mosi_0", "spi_sclk_0",
"spi_ss0_1", "spi_ss1", "spi_sclk_1", "spi_mosi_1",
"spi_miso_1", "spi_ss2"
};
static const char * const ethernet_groups[] = {
"eth_tx_clk", "eth_tx_en", "eth_txd1_0", "eth_txd1_1",
"eth_txd0_0", "eth_txd0_1", "eth_rx_clk", "eth_rx_dv",
"eth_rxd1", "eth_rxd0", "eth_mdio_en", "eth_mdc", "eth_ref_clk",
"eth_txd2", "eth_txd3"
};
static const char * const i2c_a_groups[] = {
"i2c_sda_a", "i2c_sck_a",
};
static const char * const i2c_b_groups[] = {
"i2c_sda_b0", "i2c_sck_b0", "i2c_sda_b1", "i2c_sck_b1"
};
static const char * const sd_c_groups[] = {
"sd_d0_c", "sd_d1_c", "sd_d2_c", "sd_d3_c",
"sd_cmd_c", "sd_clk_c"
};
static const char * const sdxc_c_groups[] = {
"sdxc_d0_c", "sdxc_d13_c", "sdxc_d47_c", "sdxc_cmd_c",
"sdxc_clk_c"
};
static const char * const nand_groups[] = {
"nand_io", "nand_io_ce0", "nand_io_ce1",
"nand_io_rb0", "nand_ale", "nand_cle",
"nand_wen_clk", "nand_ren_clk", "nand_dqs0",
"nand_dqs1"
};
static const char * const nor_groups[] = {
"nor_d", "nor_q", "nor_c", "nor_cs"
};
static const char * const sd_b_groups[] = {
"sd_d1_b", "sd_d0_b", "sd_clk_b", "sd_cmd_b",
"sd_d3_b", "sd_d2_b"
};
static const char * const sdxc_b_groups[] = {
"sdxc_d13_b", "sdxc_d0_b", "sdxc_clk_b", "sdxc_cmd_b"
};
static const char * const uart_ao_groups[] = {
"uart_tx_ao_a", "uart_rx_ao_a", "uart_cts_ao_a", "uart_rts_ao_a"
};
static const char * const remote_groups[] = {
"remote_input", "ir_blaster", "ir_remote_out"
};
static const char * const i2c_slave_ao_groups[] = {
"i2c_sck_ao", "i2c_sda_ao"
};
static const char * const uart_ao_b_groups[] = {
"uart_tx_ao_b0", "uart_rx_ao_b0", "uart_tx_ao_b1", "uart_rx_ao_b1",
"uart_cts_ao_b", "uart_rts_ao_b"
};
static const char * const i2c_mst_ao_groups[] = {
"i2c_mst_sck_ao", "i2c_mst_sda_ao"
};
static const char * const clk_groups[] = {
"clk_24m_out", "clk_32k_in_out"
};
static const char * const spdif_groups[] = {
"spdif_out_1", "spdif_out_0"
};
static const char * const i2s_groups[] = {
"i2s_am_clk_out", "i2s_ao_clk_out", "i2s_lr_clk_out",
"i2s_out_01", "i2s_in_ch01", "i2s_ao_clk_in",
"i2s_lr_clk_in"
};
static const char * const pwm_b_groups[] = {
"pwm_b"
};
static const char * const pwm_c_groups[] = {
"pwm_c0", "pwm_c1", "pwm_c2"
};
static const char * const pwm_d_groups[] = {
"pwm_d"
};
static const char * const pwm_e_groups[] = {
"pwm_e"
};
static const char * const pwm_vs_groups[] = {
"pwm_vs_0", "pwm_vs_1", "pwm_vs_2",
"pwm_vs_3", "pwm_vs_4"
};
static const char * const tsin_a_groups[] = {
"tsin_d0_a", "tsin_d17_a", "tsin_clk_a", "tsin_sop_a",
"tsin_d_valid_a"
};
static const char * const tsin_b_groups[] = {
"tsin_d0_b", "tsin_clk_b", "tsin_sop_b", "tsin_d_valid_b"
};
static struct meson_pmx_func meson8b_functions[] = {
FUNCTION(gpio),
FUNCTION(sd_a),
FUNCTION(sdxc_a),
FUNCTION(pcm_a),
FUNCTION(uart_a),
FUNCTION(uart_b),
FUNCTION(iso7816),
FUNCTION(i2c_d),
FUNCTION(xtal),
FUNCTION(uart_c),
FUNCTION(i2c_c),
FUNCTION(hdmi),
FUNCTION(spi),
FUNCTION(ethernet),
FUNCTION(i2c_a),
FUNCTION(i2c_b),
FUNCTION(sd_c),
FUNCTION(sdxc_c),
FUNCTION(nand),
FUNCTION(nor),
FUNCTION(sd_b),
FUNCTION(sdxc_b),
FUNCTION(uart_ao),
FUNCTION(remote),
FUNCTION(i2c_slave_ao),
FUNCTION(uart_ao_b),
FUNCTION(i2c_mst_ao),
FUNCTION(clk),
FUNCTION(spdif),
FUNCTION(i2s),
FUNCTION(pwm_b),
FUNCTION(pwm_c),
FUNCTION(pwm_d),
FUNCTION(pwm_e),
FUNCTION(pwm_vs),
FUNCTION(tsin_a),
FUNCTION(tsin_b),
};
static struct meson_bank meson8b_banks[] = {
/* name first last pullen pull dir out in */
BANK("X", PIN(GPIOX_0, 0), PIN(GPIOX_21, 0), 4, 0, 4, 0, 0, 0, 1, 0, 2, 0),
BANK("Y", PIN(GPIOY_0, 0), PIN(GPIOY_14, 0), 3, 0, 3, 0, 3, 0, 4, 0, 5, 0),
BANK("DV", PIN(GPIODV_9, 0), PIN(GPIODV_29, 0), 0, 0, 0, 0, 7, 0, 8, 0, 9, 0),
BANK("H", PIN(GPIOH_0, 0), PIN(GPIOH_9, 0), 1, 16, 1, 16, 9, 19, 10, 19, 11, 19),
BANK("CARD", PIN(CARD_0, 0), PIN(CARD_6, 0), 2, 20, 2, 20, 0, 22, 1, 22, 2, 22),
BANK("BOOT", PIN(BOOT_0, 0), PIN(BOOT_18, 0), 2, 0, 2, 0, 9, 0, 10, 0, 11, 0),
BANK("DIF", PIN(DIF_0_P, 0), PIN(DIF_4_N, 0), 5, 8, 5, 8, 12, 12, 13, 12, 14, 12),
};
static struct meson_bank meson8b_ao_banks[] = {
/* name first last pullen pull dir out in */
BANK("AO", PIN(GPIOAO_0, AO_OFF), PIN(GPIO_TEST_N, AO_OFF), 0, 0, 0, 16, 0, 0, 0, 16, 1, 0),
};
static struct meson_domain_data meson8b_domain_data[] = {
{
.name = "banks",
.banks = meson8b_banks,
.num_banks = ARRAY_SIZE(meson8b_banks),
.pin_base = 0,
.num_pins = 83,
},
{
.name = "ao-bank",
.banks = meson8b_ao_banks,
.num_banks = ARRAY_SIZE(meson8b_ao_banks),
.pin_base = 83,
.num_pins = 16,
},
};
struct meson_pinctrl_data meson8b_pinctrl_data = {
.pins = meson8b_pins,
.groups = meson8b_groups,
.funcs = meson8b_functions,
.domain_data = meson8b_domain_data,
.num_pins = ARRAY_SIZE(meson8b_pins),
.num_groups = ARRAY_SIZE(meson8b_groups),
.num_funcs = ARRAY_SIZE(meson8b_functions),
.num_domains = ARRAY_SIZE(meson8b_domain_data),
};

Просмотреть файл

@ -26,6 +26,10 @@ config PINCTRL_ARMADA_38X
bool
select PINCTRL_MVEBU
config PINCTRL_ARMADA_39X
bool
select PINCTRL_MVEBU
config PINCTRL_ARMADA_XP
bool
select PINCTRL_MVEBU

Просмотреть файл

@ -4,5 +4,6 @@ obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o
obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o
obj-$(CONFIG_PINCTRL_ARMADA_375) += pinctrl-armada-375.o
obj-$(CONFIG_PINCTRL_ARMADA_38X) += pinctrl-armada-38x.o
obj-$(CONFIG_PINCTRL_ARMADA_39X) += pinctrl-armada-39x.o
obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o
obj-$(CONFIG_PINCTRL_ORION) += pinctrl-orion.o

Просмотреть файл

@ -379,7 +379,7 @@ static struct mvebu_mpp_mode mv88f6710_mpp_modes[] = {
static struct mvebu_pinctrl_soc_info armada_370_pinctrl_info;
static struct of_device_id armada_370_pinctrl_of_match[] = {
static const struct of_device_id armada_370_pinctrl_of_match[] = {
{ .compatible = "marvell,mv88f6710-pinctrl" },
{ },
};

Просмотреть файл

@ -399,7 +399,7 @@ static struct mvebu_mpp_mode mv88f6720_mpp_modes[] = {
static struct mvebu_pinctrl_soc_info armada_375_pinctrl_info;
static struct of_device_id armada_375_pinctrl_of_match[] = {
static const struct of_device_id armada_375_pinctrl_of_match[] = {
{ .compatible = "marvell,mv88f6720-pinctrl" },
{ },
};

Просмотреть файл

@ -389,7 +389,7 @@ static struct mvebu_mpp_mode armada_38x_mpp_modes[] = {
static struct mvebu_pinctrl_soc_info armada_38x_pinctrl_info;
static struct of_device_id armada_38x_pinctrl_of_match[] = {
static const struct of_device_id armada_38x_pinctrl_of_match[] = {
{
.compatible = "marvell,mv88f6810-pinctrl",
.data = (void *) V_88F6810,

Просмотреть файл

@ -0,0 +1,432 @@
/*
* Marvell Armada 39x pinctrl driver based on mvebu pinctrl core
*
* Copyright (C) 2015 Marvell
*
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-mvebu.h"
static void __iomem *mpp_base;
static int armada_39x_mpp_ctrl_get(unsigned pid, unsigned long *config)
{
return default_mpp_ctrl_get(mpp_base, pid, config);
}
static int armada_39x_mpp_ctrl_set(unsigned pid, unsigned long config)
{
return default_mpp_ctrl_set(mpp_base, pid, config);
}
enum {
V_88F6920 = BIT(0),
V_88F6928 = BIT(1),
V_88F6920_PLUS = (V_88F6920 | V_88F6928),
};
static struct mvebu_mpp_mode armada_39x_mpp_modes[] = {
MPP_MODE(0,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "ua0", "rxd", V_88F6920_PLUS)),
MPP_MODE(1,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "ua0", "txd", V_88F6920_PLUS)),
MPP_MODE(2,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "i2c0", "sck", V_88F6920_PLUS)),
MPP_MODE(3,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "i2c0", "sda", V_88F6920_PLUS)),
MPP_MODE(4,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(2, "ua1", "txd", V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "ua0", "rts", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "smi", "mdc", V_88F6920_PLUS)),
MPP_MODE(5,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(2, "ua1", "rxd", V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "ua0", "cts", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "smi", "mdio", V_88F6920_PLUS)),
MPP_MODE(6,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "cs3", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "xsmi", "mdio", V_88F6920_PLUS)),
MPP_MODE(7,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad9", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "xsmi", "mdc", V_88F6920_PLUS)),
MPP_MODE(8,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad10", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "ptp", "trig", V_88F6920_PLUS)),
MPP_MODE(9,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad11", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "ptp", "clk", V_88F6920_PLUS)),
MPP_MODE(10,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad12", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "ptp", "event", V_88F6920_PLUS)),
MPP_MODE(11,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad13", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "led", "clk", V_88F6920_PLUS)),
MPP_MODE(12,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(2, "pcie0", "rstout", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad14", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "led", "stb", V_88F6920_PLUS)),
MPP_MODE(13,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad15", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "led", "data", V_88F6920_PLUS)),
MPP_MODE(14,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "m", "vtt", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "wen1", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "ua1", "txd", V_88F6920_PLUS)),
MPP_MODE(15,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "pcie0", "rstout", V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "spi0", "mosi", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "i2c1", "sck", V_88F6920_PLUS)),
MPP_MODE(16,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "m", "decc", V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "spi0", "miso", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "i2c1", "sda", V_88F6920_PLUS)),
MPP_MODE(17,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "ua1", "rxd", V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "spi0", "sck", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "smi", "mdio", V_88F6920_PLUS)),
MPP_MODE(18,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "ua1", "txd", V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "spi0", "cs0", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "i2c2", "sck", V_88F6920_PLUS)),
MPP_MODE(19,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "sata1", "present", V_88F6928),
MPP_VAR_FUNCTION(5, "ua0", "cts", V_88F6920_PLUS),
MPP_VAR_FUNCTION(6, "ua1", "rxd", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "i2c2", "sda", V_88F6920_PLUS)),
MPP_MODE(20,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "sata0", "present", V_88F6928),
MPP_VAR_FUNCTION(5, "ua0", "rts", V_88F6920_PLUS),
MPP_VAR_FUNCTION(6, "ua1", "txd", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "smi", "mdc", V_88F6920_PLUS)),
MPP_MODE(21,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "spi0", "cs1", V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "sata0", "present", V_88F6928),
MPP_VAR_FUNCTION(4, "sd", "cmd", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "bootcs", V_88F6920_PLUS),
MPP_VAR_FUNCTION(8, "ge", "rxd0", V_88F6920_PLUS)),
MPP_MODE(22,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "spi0", "mosi", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad0", V_88F6920_PLUS)),
MPP_MODE(23,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "spi0", "sck", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad2", V_88F6920_PLUS)),
MPP_MODE(24,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "spi0", "miso", V_88F6920_PLUS),
MPP_VAR_FUNCTION(2, "ua0", "cts", V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "ua1", "rxd", V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "sd", "d4", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "readyn", V_88F6920_PLUS)),
MPP_MODE(25,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "spi0", "cs0", V_88F6920_PLUS),
MPP_VAR_FUNCTION(2, "ua0", "rts", V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "ua1", "txd", V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "sd", "d5", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "cs0", V_88F6920_PLUS)),
MPP_MODE(26,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "spi0", "cs2", V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "i2c1", "sck", V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "sd", "d6", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "cs1", V_88F6920_PLUS)),
MPP_MODE(27,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "spi0", "cs3", V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "i2c1", "sda", V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "sd", "d7", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "cs2", V_88F6920_PLUS),
MPP_VAR_FUNCTION(8, "ge", "txclkout", V_88F6920_PLUS)),
MPP_MODE(28,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "sd", "clk", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad5", V_88F6920_PLUS),
MPP_VAR_FUNCTION(8, "ge", "txd0", V_88F6920_PLUS)),
MPP_MODE(29,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ale0", V_88F6920_PLUS),
MPP_VAR_FUNCTION(8, "ge", "txd1", V_88F6920_PLUS)),
MPP_MODE(30,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "oen", V_88F6920_PLUS),
MPP_VAR_FUNCTION(8, "ge", "txd2", V_88F6920_PLUS)),
MPP_MODE(31,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ale1", V_88F6920_PLUS),
MPP_VAR_FUNCTION(8, "ge", "txd3", V_88F6920_PLUS)),
MPP_MODE(32,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "wen0", V_88F6920_PLUS),
MPP_VAR_FUNCTION(8, "ge", "txctl", V_88F6920_PLUS)),
MPP_MODE(33,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "m", "decc", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad3", V_88F6920_PLUS)),
MPP_MODE(34,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad1", V_88F6920_PLUS)),
MPP_MODE(35,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "ref", "clk", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "a1", V_88F6920_PLUS)),
MPP_MODE(36,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "a0", V_88F6920_PLUS)),
MPP_MODE(37,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "sd", "d3", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad8", V_88F6920_PLUS),
MPP_VAR_FUNCTION(8, "ge", "rxclk", V_88F6920_PLUS)),
MPP_MODE(38,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "ref", "clk", V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "sd", "d0", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad4", V_88F6920_PLUS),
MPP_VAR_FUNCTION(8, "ge", "rxd1", V_88F6920_PLUS)),
MPP_MODE(39,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "i2c1", "sck", V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "ua0", "cts", V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "sd", "d1", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "a2", V_88F6920_PLUS),
MPP_VAR_FUNCTION(8, "ge", "rxd2", V_88F6920_PLUS)),
MPP_MODE(40,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "i2c1", "sda", V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "ua0", "rts", V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "sd", "d2", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad6", V_88F6920_PLUS),
MPP_VAR_FUNCTION(8, "ge", "rxd3", V_88F6920_PLUS)),
MPP_MODE(41,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "ua1", "rxd", V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "ua0", "cts", V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "spi1", "cs3", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "burstn", V_88F6920_PLUS),
MPP_VAR_FUNCTION(6, "nd", "rbn0", V_88F6920_PLUS),
MPP_VAR_FUNCTION(8, "ge", "rxctl", V_88F6920_PLUS)),
MPP_MODE(42,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "ua1", "txd", V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "ua0", "rts", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "ad7", V_88F6920_PLUS)),
MPP_MODE(43,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "pcie0", "clkreq", V_88F6920_PLUS),
MPP_VAR_FUNCTION(2, "m", "vtt", V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "m", "decc", V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "spi1", "cs2", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "dev", "clkout", V_88F6920_PLUS),
MPP_VAR_FUNCTION(6, "nd", "rbn1", V_88F6920_PLUS)),
MPP_MODE(44,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "sata0", "present", V_88F6928),
MPP_VAR_FUNCTION(2, "sata1", "present", V_88F6928),
MPP_VAR_FUNCTION(7, "led", "clk", V_88F6920_PLUS)),
MPP_MODE(45,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "ref", "clk", V_88F6920_PLUS),
MPP_VAR_FUNCTION(2, "pcie0", "rstout", V_88F6920_PLUS),
MPP_VAR_FUNCTION(6, "ua1", "rxd", V_88F6920_PLUS)),
MPP_MODE(46,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "ref", "clk", V_88F6920_PLUS),
MPP_VAR_FUNCTION(2, "pcie0", "rstout", V_88F6920_PLUS),
MPP_VAR_FUNCTION(6, "ua1", "txd", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "led", "stb", V_88F6920_PLUS)),
MPP_MODE(47,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "sata0", "present", V_88F6928),
MPP_VAR_FUNCTION(2, "sata1", "present", V_88F6928),
MPP_VAR_FUNCTION(7, "led", "data", V_88F6920_PLUS)),
MPP_MODE(48,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "sata0", "present", V_88F6928),
MPP_VAR_FUNCTION(2, "m", "vtt", V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "tdm", "pclk", V_88F6928),
MPP_VAR_FUNCTION(4, "audio", "mclk", V_88F6928),
MPP_VAR_FUNCTION(5, "sd", "d4", V_88F6920_PLUS),
MPP_VAR_FUNCTION(6, "pcie0", "clkreq", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "ua1", "txd", V_88F6920_PLUS)),
MPP_MODE(49,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "tdm", "fsync", V_88F6928),
MPP_VAR_FUNCTION(4, "audio", "lrclk", V_88F6928),
MPP_VAR_FUNCTION(5, "sd", "d5", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "ua2", "rxd", V_88F6920_PLUS)),
MPP_MODE(50,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "pcie0", "rstout", V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "tdm", "drx", V_88F6928),
MPP_VAR_FUNCTION(4, "audio", "extclk", V_88F6928),
MPP_VAR_FUNCTION(5, "sd", "cmd", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "ua2", "rxd", V_88F6920_PLUS)),
MPP_MODE(51,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "tdm", "dtx", V_88F6928),
MPP_VAR_FUNCTION(4, "audio", "sdo", V_88F6928),
MPP_VAR_FUNCTION(5, "m", "decc", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "ua2", "txd", V_88F6920_PLUS)),
MPP_MODE(52,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "pcie0", "rstout", V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "tdm", "intn", V_88F6928),
MPP_VAR_FUNCTION(4, "audio", "sdi", V_88F6928),
MPP_VAR_FUNCTION(5, "sd", "d6", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "i2c3", "sck", V_88F6920_PLUS)),
MPP_MODE(53,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "sata1", "present", V_88F6928),
MPP_VAR_FUNCTION(2, "sata0", "present", V_88F6928),
MPP_VAR_FUNCTION(3, "tdm", "rstn", V_88F6928),
MPP_VAR_FUNCTION(4, "audio", "bclk", V_88F6928),
MPP_VAR_FUNCTION(5, "sd", "d7", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "i2c3", "sda", V_88F6920_PLUS)),
MPP_MODE(54,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "sata0", "present", V_88F6928),
MPP_VAR_FUNCTION(2, "sata1", "present", V_88F6928),
MPP_VAR_FUNCTION(3, "pcie0", "rstout", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "sd", "d3", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "ua3", "txd", V_88F6920_PLUS)),
MPP_MODE(55,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "ua1", "cts", V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "spi1", "cs1", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "sd", "d0", V_88F6920_PLUS),
MPP_VAR_FUNCTION(6, "ua1", "rxd", V_88F6920_PLUS),
MPP_VAR_FUNCTION(7, "ua3", "rxd", V_88F6920_PLUS)),
MPP_MODE(56,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "ua1", "rts", V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "m", "decc", V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "spi1", "mosi", V_88F6920_PLUS),
MPP_VAR_FUNCTION(6, "ua1", "txd", V_88F6920_PLUS)),
MPP_MODE(57,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "spi1", "sck", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "sd", "clk", V_88F6920_PLUS),
MPP_VAR_FUNCTION(6, "ua1", "txd", V_88F6920_PLUS)),
MPP_MODE(58,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(2, "i2c1", "sck", V_88F6920_PLUS),
MPP_VAR_FUNCTION(3, "pcie2", "clkreq", V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "spi1", "miso", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "sd", "d1", V_88F6920_PLUS),
MPP_VAR_FUNCTION(6, "ua1", "rxd", V_88F6920_PLUS)),
MPP_MODE(59,
MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS),
MPP_VAR_FUNCTION(1, "pcie0", "rstout", V_88F6920_PLUS),
MPP_VAR_FUNCTION(2, "i2c1", "sda", V_88F6920_PLUS),
MPP_VAR_FUNCTION(4, "spi1", "cs0", V_88F6920_PLUS),
MPP_VAR_FUNCTION(5, "sd", "d2", V_88F6920_PLUS)),
};
static struct mvebu_pinctrl_soc_info armada_39x_pinctrl_info;
static const struct of_device_id armada_39x_pinctrl_of_match[] = {
{
.compatible = "marvell,mv88f6920-pinctrl",
.data = (void *) V_88F6920,
},
{
.compatible = "marvell,mv88f6928-pinctrl",
.data = (void *) V_88F6928,
},
{ },
};
static struct mvebu_mpp_ctrl armada_39x_mpp_controls[] = {
MPP_FUNC_CTRL(0, 59, NULL, armada_39x_mpp_ctrl),
};
static struct pinctrl_gpio_range armada_39x_mpp_gpio_ranges[] = {
MPP_GPIO_RANGE(0, 0, 0, 32),
MPP_GPIO_RANGE(1, 32, 32, 27),
};
static int armada_39x_pinctrl_probe(struct platform_device *pdev)
{
struct mvebu_pinctrl_soc_info *soc = &armada_39x_pinctrl_info;
const struct of_device_id *match =
of_match_device(armada_39x_pinctrl_of_match, &pdev->dev);
struct resource *res;
if (!match)
return -ENODEV;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mpp_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(mpp_base))
return PTR_ERR(mpp_base);
soc->variant = (unsigned) match->data & 0xff;
soc->controls = armada_39x_mpp_controls;
soc->ncontrols = ARRAY_SIZE(armada_39x_mpp_controls);
soc->gpioranges = armada_39x_mpp_gpio_ranges;
soc->ngpioranges = ARRAY_SIZE(armada_39x_mpp_gpio_ranges);
soc->modes = armada_39x_mpp_modes;
soc->nmodes = armada_39x_mpp_controls[0].npins;
pdev->dev.platform_data = soc;
return mvebu_pinctrl_probe(pdev);
}
static int armada_39x_pinctrl_remove(struct platform_device *pdev)
{
return mvebu_pinctrl_remove(pdev);
}
static struct platform_driver armada_39x_pinctrl_driver = {
.driver = {
.name = "armada-39x-pinctrl",
.of_match_table = of_match_ptr(armada_39x_pinctrl_of_match),
},
.probe = armada_39x_pinctrl_probe,
.remove = armada_39x_pinctrl_remove,
};
module_platform_driver(armada_39x_pinctrl_driver);
MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
MODULE_DESCRIPTION("Marvell Armada 39x pinctrl driver");
MODULE_LICENSE("GPL v2");

Просмотреть файл

@ -34,6 +34,7 @@
#include "pinctrl-mvebu.h"
static void __iomem *mpp_base;
static u32 *mpp_saved_regs;
static int armada_xp_mpp_ctrl_get(unsigned pid, unsigned long *config)
{
@ -361,7 +362,7 @@ static struct mvebu_mpp_mode armada_xp_mpp_modes[] = {
static struct mvebu_pinctrl_soc_info armada_xp_pinctrl_info;
static struct of_device_id armada_xp_pinctrl_of_match[] = {
static const struct of_device_id armada_xp_pinctrl_of_match[] = {
{
.compatible = "marvell,mv78230-pinctrl",
.data = (void *) V_MV78230,
@ -406,12 +407,42 @@ static struct pinctrl_gpio_range mv78460_mpp_gpio_ranges[] = {
MPP_GPIO_RANGE(2, 64, 64, 3),
};
static int armada_xp_pinctrl_suspend(struct platform_device *pdev,
pm_message_t state)
{
struct mvebu_pinctrl_soc_info *soc =
platform_get_drvdata(pdev);
int i, nregs;
nregs = DIV_ROUND_UP(soc->nmodes, MVEBU_MPPS_PER_REG);
for (i = 0; i < nregs; i++)
mpp_saved_regs[i] = readl(mpp_base + i * 4);
return 0;
}
static int armada_xp_pinctrl_resume(struct platform_device *pdev)
{
struct mvebu_pinctrl_soc_info *soc =
platform_get_drvdata(pdev);
int i, nregs;
nregs = DIV_ROUND_UP(soc->nmodes, MVEBU_MPPS_PER_REG);
for (i = 0; i < nregs; i++)
writel(mpp_saved_regs[i], mpp_base + i * 4);
return 0;
}
static int armada_xp_pinctrl_probe(struct platform_device *pdev)
{
struct mvebu_pinctrl_soc_info *soc = &armada_xp_pinctrl_info;
const struct of_device_id *match =
of_match_device(armada_xp_pinctrl_of_match, &pdev->dev);
struct resource *res;
int nregs;
if (!match)
return -ENODEV;
@ -459,6 +490,13 @@ static int armada_xp_pinctrl_probe(struct platform_device *pdev)
break;
}
nregs = DIV_ROUND_UP(soc->nmodes, MVEBU_MPPS_PER_REG);
mpp_saved_regs = devm_kmalloc(&pdev->dev, nregs * sizeof(u32),
GFP_KERNEL);
if (!mpp_saved_regs)
return -ENOMEM;
pdev->dev.platform_data = soc;
return mvebu_pinctrl_probe(pdev);
@ -476,6 +514,8 @@ static struct platform_driver armada_xp_pinctrl_driver = {
},
.probe = armada_xp_pinctrl_probe,
.remove = armada_xp_pinctrl_remove,
.suspend = armada_xp_pinctrl_suspend,
.resume = armada_xp_pinctrl_resume,
};
module_platform_driver(armada_xp_pinctrl_driver);

Просмотреть файл

@ -456,7 +456,7 @@ static struct mvebu_pinctrl_soc_info mv98dx4122_info = {
.ngpioranges = ARRAY_SIZE(mv88f628x_gpio_ranges),
};
static struct of_device_id kirkwood_pinctrl_of_match[] = {
static const struct of_device_id kirkwood_pinctrl_of_match[] = {
{ .compatible = "marvell,88f6180-pinctrl", .data = &mv88f6180_info },
{ .compatible = "marvell,88f6190-pinctrl", .data = &mv88f6190_info },
{ .compatible = "marvell,88f6192-pinctrl", .data = &mv88f6192_info },

Просмотреть файл

@ -211,7 +211,7 @@ static struct mvebu_pinctrl_soc_info mv88f5281_info = {
* There are multiple variants of the Orion SoCs, but in terms of pin
* muxing, they are identical.
*/
static struct of_device_id orion_pinctrl_of_match[] = {
static const struct of_device_id orion_pinctrl_of_match[] = {
{ .compatible = "marvell,88f5181l-pinctrl", .data = &mv88f5181l_info },
{ .compatible = "marvell,88f5182-pinctrl", .data = &mv88f5182_info },
{ .compatible = "marvell,88f5281-pinctrl", .data = &mv88f5281_info },

Просмотреть файл

@ -283,23 +283,40 @@ int pinconf_generic_dt_subnode_to_map(struct pinctrl_dev *pctldev,
struct device *dev = pctldev->dev;
unsigned long *configs = NULL;
unsigned num_configs = 0;
unsigned reserve;
unsigned reserve, strings_count;
struct property *prop;
const char *group;
const char *subnode_target_type = "pins";
ret = of_property_count_strings(np, "pins");
if (ret < 0) {
ret = of_property_count_strings(np, "groups");
if (ret < 0)
/* skip this node; may contain config child nodes */
return 0;
if (type == PIN_MAP_TYPE_INVALID)
type = PIN_MAP_TYPE_CONFIGS_GROUP;
subnode_target_type = "groups";
} else {
if (type == PIN_MAP_TYPE_INVALID)
type = PIN_MAP_TYPE_CONFIGS_PIN;
}
strings_count = ret;
ret = of_property_read_string(np, "function", &function);
if (ret < 0) {
/* EINVAL=missing, which is fine since it's optional */
if (ret != -EINVAL)
dev_err(dev, "could not parse property function\n");
dev_err(dev, "%s: could not parse property function\n",
of_node_full_name(np));
function = NULL;
}
ret = pinconf_generic_parse_dt_config(np, pctldev, &configs,
&num_configs);
if (ret < 0) {
dev_err(dev, "could not parse node property\n");
dev_err(dev, "%s: could not parse node property\n",
of_node_full_name(np));
return ret;
}
@ -309,21 +326,7 @@ int pinconf_generic_dt_subnode_to_map(struct pinctrl_dev *pctldev,
if (num_configs)
reserve++;
ret = of_property_count_strings(np, "pins");
if (ret < 0) {
ret = of_property_count_strings(np, "groups");
if (ret < 0) {
dev_err(dev, "could not parse property pins/groups\n");
goto exit;
}
if (type == PIN_MAP_TYPE_INVALID)
type = PIN_MAP_TYPE_CONFIGS_GROUP;
subnode_target_type = "groups";
} else {
if (type == PIN_MAP_TYPE_INVALID)
type = PIN_MAP_TYPE_CONFIGS_PIN;
}
reserve *= ret;
reserve *= strings_count;
ret = pinctrl_utils_reserve_map(pctldev, map, reserved_maps,
num_maps, reserve);
@ -367,15 +370,22 @@ int pinconf_generic_dt_node_to_map(struct pinctrl_dev *pctldev,
*map = NULL;
*num_maps = 0;
ret = pinconf_generic_dt_subnode_to_map(pctldev, np_config, map,
&reserved_maps, num_maps, type);
if (ret < 0)
goto exit;
for_each_child_of_node(np_config, np) {
ret = pinconf_generic_dt_subnode_to_map(pctldev, np, map,
&reserved_maps, num_maps, type);
if (ret < 0) {
pinctrl_utils_dt_free_map(pctldev, *map, *num_maps);
return ret;
}
if (ret < 0)
goto exit;
}
return 0;
exit:
pinctrl_utils_dt_free_map(pctldev, *map, *num_maps);
return ret;
}
EXPORT_SYMBOL_GPL(pinconf_generic_dt_node_to_map);

Просмотреть файл

@ -0,0 +1,869 @@
/*
* GPIO driver for AMD
*
* Copyright (c) 2014,2015 AMD Corporation.
* Authors: Ken Xue <Ken.Xue@amd.com>
* Wu, Jeff <Jeff.Wu@amd.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*/
#include <linux/err.h>
#include <linux/bug.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/compiler.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/log2.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/acpi.h>
#include <linux/seq_file.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/bitops.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include "pinctrl-utils.h"
#include "pinctrl-amd.h"
static inline struct amd_gpio *to_amd_gpio(struct gpio_chip *gc)
{
return container_of(gc, struct amd_gpio, gc);
}
static int amd_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
{
unsigned long flags;
u32 pin_reg;
struct amd_gpio *gpio_dev = to_amd_gpio(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + offset * 4);
/*
* Suppose BIOS or Bootloader sets specific debounce for the
* GPIO. if not, set debounce to be 2.75ms and remove glitch.
*/
if ((pin_reg & DB_TMR_OUT_MASK) == 0) {
pin_reg |= 0xf;
pin_reg |= BIT(DB_TMR_OUT_UNIT_OFF);
pin_reg |= DB_TYPE_REMOVE_GLITCH << DB_CNTRL_OFF;
pin_reg &= ~BIT(DB_TMR_LARGE_OFF);
}
pin_reg &= ~BIT(OUTPUT_ENABLE_OFF);
writel(pin_reg, gpio_dev->base + offset * 4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
return 0;
}
static int amd_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
int value)
{
u32 pin_reg;
unsigned long flags;
struct amd_gpio *gpio_dev = to_amd_gpio(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + offset * 4);
pin_reg |= BIT(OUTPUT_ENABLE_OFF);
if (value)
pin_reg |= BIT(OUTPUT_VALUE_OFF);
else
pin_reg &= ~BIT(OUTPUT_VALUE_OFF);
writel(pin_reg, gpio_dev->base + offset * 4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
return 0;
}
static int amd_gpio_get_value(struct gpio_chip *gc, unsigned offset)
{
u32 pin_reg;
unsigned long flags;
struct amd_gpio *gpio_dev = to_amd_gpio(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + offset * 4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
return !!(pin_reg & BIT(PIN_STS_OFF));
}
static void amd_gpio_set_value(struct gpio_chip *gc, unsigned offset, int value)
{
u32 pin_reg;
unsigned long flags;
struct amd_gpio *gpio_dev = to_amd_gpio(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + offset * 4);
if (value)
pin_reg |= BIT(OUTPUT_VALUE_OFF);
else
pin_reg &= ~BIT(OUTPUT_VALUE_OFF);
writel(pin_reg, gpio_dev->base + offset * 4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
static int amd_gpio_set_debounce(struct gpio_chip *gc, unsigned offset,
unsigned debounce)
{
u32 time;
u32 pin_reg;
int ret = 0;
unsigned long flags;
struct amd_gpio *gpio_dev = to_amd_gpio(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + offset * 4);
if (debounce) {
pin_reg |= DB_TYPE_REMOVE_GLITCH << DB_CNTRL_OFF;
pin_reg &= ~DB_TMR_OUT_MASK;
/*
Debounce Debounce Timer Max
TmrLarge TmrOutUnit Unit Debounce
Time
0 0 61 usec (2 RtcClk) 976 usec
0 1 244 usec (8 RtcClk) 3.9 msec
1 0 15.6 msec (512 RtcClk) 250 msec
1 1 62.5 msec (2048 RtcClk) 1 sec
*/
if (debounce < 61) {
pin_reg |= 1;
pin_reg &= ~BIT(DB_TMR_OUT_UNIT_OFF);
pin_reg &= ~BIT(DB_TMR_LARGE_OFF);
} else if (debounce < 976) {
time = debounce / 61;
pin_reg |= time & DB_TMR_OUT_MASK;
pin_reg &= ~BIT(DB_TMR_OUT_UNIT_OFF);
pin_reg &= ~BIT(DB_TMR_LARGE_OFF);
} else if (debounce < 3900) {
time = debounce / 244;
pin_reg |= time & DB_TMR_OUT_MASK;
pin_reg |= BIT(DB_TMR_OUT_UNIT_OFF);
pin_reg &= ~BIT(DB_TMR_LARGE_OFF);
} else if (debounce < 250000) {
time = debounce / 15600;
pin_reg |= time & DB_TMR_OUT_MASK;
pin_reg &= ~BIT(DB_TMR_OUT_UNIT_OFF);
pin_reg |= BIT(DB_TMR_LARGE_OFF);
} else if (debounce < 1000000) {
time = debounce / 62500;
pin_reg |= time & DB_TMR_OUT_MASK;
pin_reg |= BIT(DB_TMR_OUT_UNIT_OFF);
pin_reg |= BIT(DB_TMR_LARGE_OFF);
} else {
pin_reg &= ~DB_CNTRl_MASK;
ret = -EINVAL;
}
} else {
pin_reg &= ~BIT(DB_TMR_OUT_UNIT_OFF);
pin_reg &= ~BIT(DB_TMR_LARGE_OFF);
pin_reg &= ~DB_TMR_OUT_MASK;
pin_reg &= ~DB_CNTRl_MASK;
}
writel(pin_reg, gpio_dev->base + offset * 4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
return ret;
}
#ifdef CONFIG_DEBUG_FS
static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc)
{
u32 pin_reg;
unsigned long flags;
unsigned int bank, i, pin_num;
struct amd_gpio *gpio_dev = to_amd_gpio(gc);
char *level_trig;
char *active_level;
char *interrupt_enable;
char *interrupt_mask;
char *wake_cntrl0;
char *wake_cntrl1;
char *wake_cntrl2;
char *pin_sts;
char *pull_up_sel;
char *pull_up_enable;
char *pull_down_enable;
char *output_value;
char *output_enable;
for (bank = 0; bank < AMD_GPIO_TOTAL_BANKS; bank++) {
seq_printf(s, "GPIO bank%d\t", bank);
switch (bank) {
case 0:
i = 0;
pin_num = AMD_GPIO_PINS_BANK0;
break;
case 1:
i = 64;
pin_num = AMD_GPIO_PINS_BANK1 + i;
break;
case 2:
i = 128;
pin_num = AMD_GPIO_PINS_BANK2 + i;
break;
}
for (; i < pin_num; i++) {
seq_printf(s, "pin%d\t", i);
spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + i * 4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
if (pin_reg & BIT(INTERRUPT_ENABLE_OFF)) {
interrupt_enable = "interrupt is enabled|";
if (!(pin_reg & BIT(ACTIVE_LEVEL_OFF))
&& !(pin_reg & BIT(ACTIVE_LEVEL_OFF+1)))
active_level = "Active low|";
else if (pin_reg & BIT(ACTIVE_LEVEL_OFF)
&& !(pin_reg & BIT(ACTIVE_LEVEL_OFF+1)))
active_level = "Active high|";
else if (!(pin_reg & BIT(ACTIVE_LEVEL_OFF))
&& pin_reg & BIT(ACTIVE_LEVEL_OFF+1))
active_level = "Active on both|";
else
active_level = "Unknow Active level|";
if (pin_reg & BIT(LEVEL_TRIG_OFF))
level_trig = "Level trigger|";
else
level_trig = "Edge trigger|";
} else {
interrupt_enable =
"interrupt is disabled|";
active_level = " ";
level_trig = " ";
}
if (pin_reg & BIT(INTERRUPT_MASK_OFF))
interrupt_mask =
"interrupt is unmasked|";
else
interrupt_mask =
"interrupt is masked|";
if (pin_reg & BIT(WAKE_CNTRL_OFF))
wake_cntrl0 = "enable wakeup in S0i3 state|";
else
wake_cntrl0 = "disable wakeup in S0i3 state|";
if (pin_reg & BIT(WAKE_CNTRL_OFF))
wake_cntrl1 = "enable wakeup in S3 state|";
else
wake_cntrl1 = "disable wakeup in S3 state|";
if (pin_reg & BIT(WAKE_CNTRL_OFF))
wake_cntrl2 = "enable wakeup in S4/S5 state|";
else
wake_cntrl2 = "disable wakeup in S4/S5 state|";
if (pin_reg & BIT(PULL_UP_ENABLE_OFF)) {
pull_up_enable = "pull-up is enabled|";
if (pin_reg & BIT(PULL_UP_SEL_OFF))
pull_up_sel = "8k pull-up|";
else
pull_up_sel = "4k pull-up|";
} else {
pull_up_enable = "pull-up is disabled|";
pull_up_sel = " ";
}
if (pin_reg & BIT(PULL_DOWN_ENABLE_OFF))
pull_down_enable = "pull-down is enabled|";
else
pull_down_enable = "Pull-down is disabled|";
if (pin_reg & BIT(OUTPUT_ENABLE_OFF)) {
pin_sts = " ";
output_enable = "output is enabled|";
if (pin_reg & BIT(OUTPUT_VALUE_OFF))
output_value = "output is high|";
else
output_value = "output is low|";
} else {
output_enable = "output is disabled|";
output_value = " ";
if (pin_reg & BIT(PIN_STS_OFF))
pin_sts = "input is high|";
else
pin_sts = "input is low|";
}
seq_printf(s, "%s %s %s %s %s %s\n"
" %s %s %s %s %s %s %s 0x%x\n",
level_trig, active_level, interrupt_enable,
interrupt_mask, wake_cntrl0, wake_cntrl1,
wake_cntrl2, pin_sts, pull_up_sel,
pull_up_enable, pull_down_enable,
output_value, output_enable, pin_reg);
}
}
}
#else
#define amd_gpio_dbg_show NULL
#endif
static void amd_gpio_irq_enable(struct irq_data *d)
{
u32 pin_reg;
unsigned long flags;
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = to_amd_gpio(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
/*
Suppose BIOS or Bootloader sets specific debounce for the
GPIO. if not, set debounce to be 2.75ms.
*/
if ((pin_reg & DB_TMR_OUT_MASK) == 0) {
pin_reg |= 0xf;
pin_reg |= BIT(DB_TMR_OUT_UNIT_OFF);
pin_reg &= ~BIT(DB_TMR_LARGE_OFF);
}
pin_reg |= BIT(INTERRUPT_ENABLE_OFF);
pin_reg |= BIT(INTERRUPT_MASK_OFF);
writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
static void amd_gpio_irq_disable(struct irq_data *d)
{
u32 pin_reg;
unsigned long flags;
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = to_amd_gpio(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
pin_reg &= ~BIT(INTERRUPT_ENABLE_OFF);
pin_reg &= ~BIT(INTERRUPT_MASK_OFF);
writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
static void amd_gpio_irq_mask(struct irq_data *d)
{
u32 pin_reg;
unsigned long flags;
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = to_amd_gpio(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
pin_reg &= ~BIT(INTERRUPT_MASK_OFF);
writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
static void amd_gpio_irq_unmask(struct irq_data *d)
{
u32 pin_reg;
unsigned long flags;
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = to_amd_gpio(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
pin_reg |= BIT(INTERRUPT_MASK_OFF);
writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
static void amd_gpio_irq_eoi(struct irq_data *d)
{
u32 reg;
unsigned long flags;
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = to_amd_gpio(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
reg |= EOI_MASK;
writel(reg, gpio_dev->base + WAKE_INT_MASTER_REG);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{
int ret = 0;
u32 pin_reg;
unsigned long flags;
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = to_amd_gpio(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
switch (type & IRQ_TYPE_SENSE_MASK) {
case IRQ_TYPE_EDGE_RISING:
pin_reg &= ~BIT(LEVEL_TRIG_OFF);
pin_reg &= ~(ACTIVE_LEVEL_MASK << ACTIVE_LEVEL_OFF);
pin_reg |= ACTIVE_HIGH << ACTIVE_LEVEL_OFF;
pin_reg |= DB_TYPE_REMOVE_GLITCH << DB_CNTRL_OFF;
__irq_set_handler_locked(d->irq, handle_edge_irq);
break;
case IRQ_TYPE_EDGE_FALLING:
pin_reg &= ~BIT(LEVEL_TRIG_OFF);
pin_reg &= ~(ACTIVE_LEVEL_MASK << ACTIVE_LEVEL_OFF);
pin_reg |= ACTIVE_LOW << ACTIVE_LEVEL_OFF;
pin_reg |= DB_TYPE_REMOVE_GLITCH << DB_CNTRL_OFF;
__irq_set_handler_locked(d->irq, handle_edge_irq);
break;
case IRQ_TYPE_EDGE_BOTH:
pin_reg &= ~BIT(LEVEL_TRIG_OFF);
pin_reg &= ~(ACTIVE_LEVEL_MASK << ACTIVE_LEVEL_OFF);
pin_reg |= BOTH_EADGE << ACTIVE_LEVEL_OFF;
pin_reg |= DB_TYPE_REMOVE_GLITCH << DB_CNTRL_OFF;
__irq_set_handler_locked(d->irq, handle_edge_irq);
break;
case IRQ_TYPE_LEVEL_HIGH:
pin_reg |= LEVEL_TRIGGER << LEVEL_TRIG_OFF;
pin_reg &= ~(ACTIVE_LEVEL_MASK << ACTIVE_LEVEL_OFF);
pin_reg |= ACTIVE_HIGH << ACTIVE_LEVEL_OFF;
pin_reg &= ~(DB_CNTRl_MASK << DB_CNTRL_OFF);
pin_reg |= DB_TYPE_PRESERVE_LOW_GLITCH << DB_CNTRL_OFF;
__irq_set_handler_locked(d->irq, handle_level_irq);
break;
case IRQ_TYPE_LEVEL_LOW:
pin_reg |= LEVEL_TRIGGER << LEVEL_TRIG_OFF;
pin_reg &= ~(ACTIVE_LEVEL_MASK << ACTIVE_LEVEL_OFF);
pin_reg |= ACTIVE_LOW << ACTIVE_LEVEL_OFF;
pin_reg &= ~(DB_CNTRl_MASK << DB_CNTRL_OFF);
pin_reg |= DB_TYPE_PRESERVE_HIGH_GLITCH << DB_CNTRL_OFF;
__irq_set_handler_locked(d->irq, handle_level_irq);
break;
case IRQ_TYPE_NONE:
break;
default:
dev_err(&gpio_dev->pdev->dev, "Invalid type value\n");
ret = -EINVAL;
}
pin_reg |= CLR_INTR_STAT << INTERRUPT_STS_OFF;
writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
return ret;
}
static void amd_irq_ack(struct irq_data *d)
{
/*
* based on HW design,there is no need to ack HW
* before handle current irq. But this routine is
* necessary for handle_edge_irq
*/
}
static struct irq_chip amd_gpio_irqchip = {
.name = "amd_gpio",
.irq_ack = amd_irq_ack,
.irq_enable = amd_gpio_irq_enable,
.irq_disable = amd_gpio_irq_disable,
.irq_mask = amd_gpio_irq_mask,
.irq_unmask = amd_gpio_irq_unmask,
.irq_eoi = amd_gpio_irq_eoi,
.irq_set_type = amd_gpio_irq_set_type,
};
static void amd_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
u32 i;
u32 off;
u32 reg;
u32 pin_reg;
u64 reg64;
int handled = 0;
unsigned long flags;
struct irq_chip *chip = irq_get_chip(irq);
struct gpio_chip *gc = irq_desc_get_handler_data(desc);
struct amd_gpio *gpio_dev = to_amd_gpio(gc);
chained_irq_enter(chip, desc);
/*enable GPIO interrupt again*/
spin_lock_irqsave(&gpio_dev->lock, flags);
reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
reg64 = reg;
reg64 = reg64 << 32;
reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
reg64 |= reg;
spin_unlock_irqrestore(&gpio_dev->lock, flags);
/*
* first 46 bits indicates interrupt status.
* one bit represents four interrupt sources.
*/
for (off = 0; off < 46 ; off++) {
if (reg64 & BIT(off)) {
for (i = 0; i < 4; i++) {
pin_reg = readl(gpio_dev->base +
(off * 4 + i) * 4);
if ((pin_reg & BIT(INTERRUPT_STS_OFF)) ||
(pin_reg & BIT(WAKE_STS_OFF))) {
irq = irq_find_mapping(gc->irqdomain,
off * 4 + i);
generic_handle_irq(irq);
writel(pin_reg,
gpio_dev->base
+ (off * 4 + i) * 4);
handled++;
}
}
}
}
if (handled == 0)
handle_bad_irq(irq, desc);
spin_lock_irqsave(&gpio_dev->lock, flags);
reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
reg |= EOI_MASK;
writel(reg, gpio_dev->base + WAKE_INT_MASTER_REG);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
chained_irq_exit(chip, desc);
}
static int amd_get_groups_count(struct pinctrl_dev *pctldev)
{
struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev);
return gpio_dev->ngroups;
}
static const char *amd_get_group_name(struct pinctrl_dev *pctldev,
unsigned group)
{
struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev);
return gpio_dev->groups[group].name;
}
static int amd_get_group_pins(struct pinctrl_dev *pctldev,
unsigned group,
const unsigned **pins,
unsigned *num_pins)
{
struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev);
*pins = gpio_dev->groups[group].pins;
*num_pins = gpio_dev->groups[group].npins;
return 0;
}
static const struct pinctrl_ops amd_pinctrl_ops = {
.get_groups_count = amd_get_groups_count,
.get_group_name = amd_get_group_name,
.get_group_pins = amd_get_group_pins,
#ifdef CONFIG_OF
.dt_node_to_map = pinconf_generic_dt_node_to_map_group,
.dt_free_map = pinctrl_utils_dt_free_map,
#endif
};
static int amd_pinconf_get(struct pinctrl_dev *pctldev,
unsigned int pin,
unsigned long *config)
{
u32 pin_reg;
unsigned arg;
unsigned long flags;
struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param = pinconf_to_config_param(*config);
spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + pin*4);
spin_unlock_irqrestore(&gpio_dev->lock, flags);
switch (param) {
case PIN_CONFIG_INPUT_DEBOUNCE:
arg = pin_reg & DB_TMR_OUT_MASK;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
arg = (pin_reg >> PULL_DOWN_ENABLE_OFF) & BIT(0);
break;
case PIN_CONFIG_BIAS_PULL_UP:
arg = (pin_reg >> PULL_UP_SEL_OFF) & (BIT(0) | BIT(1));
break;
case PIN_CONFIG_DRIVE_STRENGTH:
arg = (pin_reg >> DRV_STRENGTH_SEL_OFF) & DRV_STRENGTH_SEL_MASK;
break;
default:
dev_err(&gpio_dev->pdev->dev, "Invalid config param %04x\n",
param);
return -ENOTSUPP;
}
*config = pinconf_to_config_packed(param, arg);
return 0;
}
static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned num_configs)
{
int i;
u32 arg;
int ret = 0;
u32 pin_reg;
unsigned long flags;
enum pin_config_param param;
struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev);
spin_lock_irqsave(&gpio_dev->lock, flags);
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
pin_reg = readl(gpio_dev->base + pin*4);
switch (param) {
case PIN_CONFIG_INPUT_DEBOUNCE:
pin_reg &= ~DB_TMR_OUT_MASK;
pin_reg |= arg & DB_TMR_OUT_MASK;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
pin_reg &= ~BIT(PULL_DOWN_ENABLE_OFF);
pin_reg |= (arg & BIT(0)) << PULL_DOWN_ENABLE_OFF;
break;
case PIN_CONFIG_BIAS_PULL_UP:
pin_reg &= ~BIT(PULL_UP_SEL_OFF);
pin_reg |= (arg & BIT(0)) << PULL_UP_SEL_OFF;
pin_reg &= ~BIT(PULL_UP_ENABLE_OFF);
pin_reg |= ((arg>>1) & BIT(0)) << PULL_UP_ENABLE_OFF;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
pin_reg &= ~(DRV_STRENGTH_SEL_MASK
<< DRV_STRENGTH_SEL_OFF);
pin_reg |= (arg & DRV_STRENGTH_SEL_MASK)
<< DRV_STRENGTH_SEL_OFF;
break;
default:
dev_err(&gpio_dev->pdev->dev,
"Invalid config param %04x\n", param);
ret = -ENOTSUPP;
}
writel(pin_reg, gpio_dev->base + pin*4);
}
spin_unlock_irqrestore(&gpio_dev->lock, flags);
return ret;
}
static int amd_pinconf_group_get(struct pinctrl_dev *pctldev,
unsigned int group,
unsigned long *config)
{
const unsigned *pins;
unsigned npins;
int ret;
ret = amd_get_group_pins(pctldev, group, &pins, &npins);
if (ret)
return ret;
if (amd_pinconf_get(pctldev, pins[0], config))
return -ENOTSUPP;
return 0;
}
static int amd_pinconf_group_set(struct pinctrl_dev *pctldev,
unsigned group, unsigned long *configs,
unsigned num_configs)
{
const unsigned *pins;
unsigned npins;
int i, ret;
ret = amd_get_group_pins(pctldev, group, &pins, &npins);
if (ret)
return ret;
for (i = 0; i < npins; i++) {
if (amd_pinconf_set(pctldev, pins[i], configs, num_configs))
return -ENOTSUPP;
}
return 0;
}
static const struct pinconf_ops amd_pinconf_ops = {
.pin_config_get = amd_pinconf_get,
.pin_config_set = amd_pinconf_set,
.pin_config_group_get = amd_pinconf_group_get,
.pin_config_group_set = amd_pinconf_group_set,
};
static struct pinctrl_desc amd_pinctrl_desc = {
.pins = kerncz_pins,
.npins = ARRAY_SIZE(kerncz_pins),
.pctlops = &amd_pinctrl_ops,
.confops = &amd_pinconf_ops,
.owner = THIS_MODULE,
};
static int amd_gpio_probe(struct platform_device *pdev)
{
int ret = 0;
int irq_base;
struct resource *res;
struct amd_gpio *gpio_dev;
gpio_dev = devm_kzalloc(&pdev->dev,
sizeof(struct amd_gpio), GFP_KERNEL);
if (!gpio_dev)
return -ENOMEM;
spin_lock_init(&gpio_dev->lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "Failed to get gpio io resource.\n");
return -EINVAL;
}
gpio_dev->base = devm_ioremap_nocache(&pdev->dev, res->start,
resource_size(res));
if (IS_ERR(gpio_dev->base))
return PTR_ERR(gpio_dev->base);
irq_base = platform_get_irq(pdev, 0);
if (irq_base < 0) {
dev_err(&pdev->dev, "Failed to get gpio IRQ.\n");
return -EINVAL;
}
gpio_dev->pdev = pdev;
gpio_dev->gc.direction_input = amd_gpio_direction_input;
gpio_dev->gc.direction_output = amd_gpio_direction_output;
gpio_dev->gc.get = amd_gpio_get_value;
gpio_dev->gc.set = amd_gpio_set_value;
gpio_dev->gc.set_debounce = amd_gpio_set_debounce;
gpio_dev->gc.dbg_show = amd_gpio_dbg_show;
gpio_dev->gc.base = 0;
gpio_dev->gc.label = pdev->name;
gpio_dev->gc.owner = THIS_MODULE;
gpio_dev->gc.dev = &pdev->dev;
gpio_dev->gc.ngpio = TOTAL_NUMBER_OF_PINS;
#if defined(CONFIG_OF_GPIO)
gpio_dev->gc.of_node = pdev->dev.of_node;
#endif
gpio_dev->groups = kerncz_groups;
gpio_dev->ngroups = ARRAY_SIZE(kerncz_groups);
amd_pinctrl_desc.name = dev_name(&pdev->dev);
gpio_dev->pctrl = pinctrl_register(&amd_pinctrl_desc,
&pdev->dev, gpio_dev);
if (!gpio_dev->pctrl) {
dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
return -ENODEV;
}
ret = gpiochip_add(&gpio_dev->gc);
if (ret)
goto out1;
ret = gpiochip_add_pin_range(&gpio_dev->gc, dev_name(&pdev->dev),
0, 0, TOTAL_NUMBER_OF_PINS);
if (ret) {
dev_err(&pdev->dev, "Failed to add pin range\n");
goto out2;
}
ret = gpiochip_irqchip_add(&gpio_dev->gc,
&amd_gpio_irqchip,
0,
handle_simple_irq,
IRQ_TYPE_NONE);
if (ret) {
dev_err(&pdev->dev, "could not add irqchip\n");
ret = -ENODEV;
goto out2;
}
gpiochip_set_chained_irqchip(&gpio_dev->gc,
&amd_gpio_irqchip,
irq_base,
amd_gpio_irq_handler);
platform_set_drvdata(pdev, gpio_dev);
dev_dbg(&pdev->dev, "amd gpio driver loaded\n");
return ret;
out2:
gpiochip_remove(&gpio_dev->gc);
out1:
pinctrl_unregister(gpio_dev->pctrl);
return ret;
}
static int amd_gpio_remove(struct platform_device *pdev)
{
struct amd_gpio *gpio_dev;
gpio_dev = platform_get_drvdata(pdev);
gpiochip_remove(&gpio_dev->gc);
pinctrl_unregister(gpio_dev->pctrl);
return 0;
}
static const struct acpi_device_id amd_gpio_acpi_match[] = {
{ "AMD0030", 0 },
{ },
};
MODULE_DEVICE_TABLE(acpi, amd_gpio_acpi_match);
static struct platform_driver amd_gpio_driver = {
.driver = {
.name = "amd_gpio",
.owner = THIS_MODULE,
.acpi_match_table = ACPI_PTR(amd_gpio_acpi_match),
},
.probe = amd_gpio_probe,
.remove = amd_gpio_remove,
};
module_platform_driver(amd_gpio_driver);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Ken Xue <Ken.Xue@amd.com>, Jeff Wu <Jeff.Wu@amd.com>");
MODULE_DESCRIPTION("AMD GPIO pinctrl driver");

Просмотреть файл

@ -0,0 +1,261 @@
/*
* GPIO driver for AMD
*
* Copyright (c) 2014,2015 Ken Xue <Ken.Xue@amd.com>
* Jeff Wu <Jeff.Wu@amd.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
*/
#ifndef _PINCTRL_AMD_H
#define _PINCTRL_AMD_H
#define TOTAL_NUMBER_OF_PINS 192
#define AMD_GPIO_PINS_PER_BANK 64
#define AMD_GPIO_TOTAL_BANKS 3
#define AMD_GPIO_PINS_BANK0 63
#define AMD_GPIO_PINS_BANK1 64
#define AMD_GPIO_PINS_BANK2 56
#define WAKE_INT_MASTER_REG 0xfc
#define EOI_MASK (1 << 29)
#define WAKE_INT_STATUS_REG0 0x2f8
#define WAKE_INT_STATUS_REG1 0x2fc
#define DB_TMR_OUT_OFF 0
#define DB_TMR_OUT_UNIT_OFF 4
#define DB_CNTRL_OFF 5
#define DB_TMR_LARGE_OFF 7
#define LEVEL_TRIG_OFF 8
#define ACTIVE_LEVEL_OFF 9
#define INTERRUPT_ENABLE_OFF 11
#define INTERRUPT_MASK_OFF 12
#define WAKE_CNTRL_OFF 13
#define PIN_STS_OFF 16
#define DRV_STRENGTH_SEL_OFF 17
#define PULL_UP_SEL_OFF 19
#define PULL_UP_ENABLE_OFF 20
#define PULL_DOWN_ENABLE_OFF 21
#define OUTPUT_VALUE_OFF 22
#define OUTPUT_ENABLE_OFF 23
#define SW_CNTRL_IN_OFF 24
#define SW_CNTRL_EN_OFF 25
#define INTERRUPT_STS_OFF 28
#define WAKE_STS_OFF 29
#define DB_TMR_OUT_MASK 0xFUL
#define DB_CNTRl_MASK 0x3UL
#define ACTIVE_LEVEL_MASK 0x3UL
#define DRV_STRENGTH_SEL_MASK 0x3UL
#define DB_TYPE_NO_DEBOUNCE 0x0UL
#define DB_TYPE_PRESERVE_LOW_GLITCH 0x1UL
#define DB_TYPE_PRESERVE_HIGH_GLITCH 0x2UL
#define DB_TYPE_REMOVE_GLITCH 0x3UL
#define EDGE_TRAGGER 0x0UL
#define LEVEL_TRIGGER 0x1UL
#define ACTIVE_HIGH 0x0UL
#define ACTIVE_LOW 0x1UL
#define BOTH_EADGE 0x2UL
#define ENABLE_INTERRUPT 0x1UL
#define DISABLE_INTERRUPT 0x0UL
#define ENABLE_INTERRUPT_MASK 0x0UL
#define DISABLE_INTERRUPT_MASK 0x1UL
#define CLR_INTR_STAT 0x1UL
struct amd_pingroup {
const char *name;
const unsigned *pins;
unsigned npins;
};
struct amd_function {
const char *name;
const char * const *groups;
unsigned ngroups;
};
struct amd_gpio {
spinlock_t lock;
void __iomem *base;
const struct amd_pingroup *groups;
u32 ngroups;
struct pinctrl_dev *pctrl;
struct gpio_chip gc;
struct resource *res;
struct platform_device *pdev;
};
/* KERNCZ configuration*/
static const struct pinctrl_pin_desc kerncz_pins[] = {
PINCTRL_PIN(0, "GPIO_0"),
PINCTRL_PIN(1, "GPIO_1"),
PINCTRL_PIN(2, "GPIO_2"),
PINCTRL_PIN(3, "GPIO_3"),
PINCTRL_PIN(4, "GPIO_4"),
PINCTRL_PIN(5, "GPIO_5"),
PINCTRL_PIN(6, "GPIO_6"),
PINCTRL_PIN(7, "GPIO_7"),
PINCTRL_PIN(8, "GPIO_8"),
PINCTRL_PIN(9, "GPIO_9"),
PINCTRL_PIN(10, "GPIO_10"),
PINCTRL_PIN(11, "GPIO_11"),
PINCTRL_PIN(12, "GPIO_12"),
PINCTRL_PIN(13, "GPIO_13"),
PINCTRL_PIN(14, "GPIO_14"),
PINCTRL_PIN(15, "GPIO_15"),
PINCTRL_PIN(16, "GPIO_16"),
PINCTRL_PIN(17, "GPIO_17"),
PINCTRL_PIN(18, "GPIO_18"),
PINCTRL_PIN(19, "GPIO_19"),
PINCTRL_PIN(20, "GPIO_20"),
PINCTRL_PIN(23, "GPIO_23"),
PINCTRL_PIN(24, "GPIO_24"),
PINCTRL_PIN(25, "GPIO_25"),
PINCTRL_PIN(26, "GPIO_26"),
PINCTRL_PIN(39, "GPIO_39"),
PINCTRL_PIN(40, "GPIO_40"),
PINCTRL_PIN(43, "GPIO_42"),
PINCTRL_PIN(46, "GPIO_46"),
PINCTRL_PIN(47, "GPIO_47"),
PINCTRL_PIN(48, "GPIO_48"),
PINCTRL_PIN(49, "GPIO_49"),
PINCTRL_PIN(50, "GPIO_50"),
PINCTRL_PIN(51, "GPIO_51"),
PINCTRL_PIN(52, "GPIO_52"),
PINCTRL_PIN(53, "GPIO_53"),
PINCTRL_PIN(54, "GPIO_54"),
PINCTRL_PIN(55, "GPIO_55"),
PINCTRL_PIN(56, "GPIO_56"),
PINCTRL_PIN(57, "GPIO_57"),
PINCTRL_PIN(58, "GPIO_58"),
PINCTRL_PIN(59, "GPIO_59"),
PINCTRL_PIN(60, "GPIO_60"),
PINCTRL_PIN(61, "GPIO_61"),
PINCTRL_PIN(62, "GPIO_62"),
PINCTRL_PIN(64, "GPIO_64"),
PINCTRL_PIN(65, "GPIO_65"),
PINCTRL_PIN(66, "GPIO_66"),
PINCTRL_PIN(68, "GPIO_68"),
PINCTRL_PIN(69, "GPIO_69"),
PINCTRL_PIN(70, "GPIO_70"),
PINCTRL_PIN(71, "GPIO_71"),
PINCTRL_PIN(72, "GPIO_72"),
PINCTRL_PIN(74, "GPIO_74"),
PINCTRL_PIN(75, "GPIO_75"),
PINCTRL_PIN(76, "GPIO_76"),
PINCTRL_PIN(84, "GPIO_84"),
PINCTRL_PIN(85, "GPIO_85"),
PINCTRL_PIN(86, "GPIO_86"),
PINCTRL_PIN(87, "GPIO_87"),
PINCTRL_PIN(88, "GPIO_88"),
PINCTRL_PIN(89, "GPIO_89"),
PINCTRL_PIN(90, "GPIO_90"),
PINCTRL_PIN(91, "GPIO_91"),
PINCTRL_PIN(92, "GPIO_92"),
PINCTRL_PIN(93, "GPIO_93"),
PINCTRL_PIN(95, "GPIO_95"),
PINCTRL_PIN(96, "GPIO_96"),
PINCTRL_PIN(97, "GPIO_97"),
PINCTRL_PIN(98, "GPIO_98"),
PINCTRL_PIN(99, "GPIO_99"),
PINCTRL_PIN(100, "GPIO_100"),
PINCTRL_PIN(101, "GPIO_101"),
PINCTRL_PIN(102, "GPIO_102"),
PINCTRL_PIN(113, "GPIO_113"),
PINCTRL_PIN(114, "GPIO_114"),
PINCTRL_PIN(115, "GPIO_115"),
PINCTRL_PIN(116, "GPIO_116"),
PINCTRL_PIN(117, "GPIO_117"),
PINCTRL_PIN(118, "GPIO_118"),
PINCTRL_PIN(119, "GPIO_119"),
PINCTRL_PIN(120, "GPIO_120"),
PINCTRL_PIN(121, "GPIO_121"),
PINCTRL_PIN(122, "GPIO_122"),
PINCTRL_PIN(126, "GPIO_126"),
PINCTRL_PIN(129, "GPIO_129"),
PINCTRL_PIN(130, "GPIO_130"),
PINCTRL_PIN(131, "GPIO_131"),
PINCTRL_PIN(132, "GPIO_132"),
PINCTRL_PIN(133, "GPIO_133"),
PINCTRL_PIN(135, "GPIO_135"),
PINCTRL_PIN(136, "GPIO_136"),
PINCTRL_PIN(137, "GPIO_137"),
PINCTRL_PIN(138, "GPIO_138"),
PINCTRL_PIN(139, "GPIO_139"),
PINCTRL_PIN(140, "GPIO_140"),
PINCTRL_PIN(141, "GPIO_141"),
PINCTRL_PIN(142, "GPIO_142"),
PINCTRL_PIN(143, "GPIO_143"),
PINCTRL_PIN(144, "GPIO_144"),
PINCTRL_PIN(145, "GPIO_145"),
PINCTRL_PIN(146, "GPIO_146"),
PINCTRL_PIN(147, "GPIO_147"),
PINCTRL_PIN(148, "GPIO_148"),
PINCTRL_PIN(166, "GPIO_166"),
PINCTRL_PIN(167, "GPIO_167"),
PINCTRL_PIN(168, "GPIO_168"),
PINCTRL_PIN(169, "GPIO_169"),
PINCTRL_PIN(170, "GPIO_170"),
PINCTRL_PIN(171, "GPIO_171"),
PINCTRL_PIN(172, "GPIO_172"),
PINCTRL_PIN(173, "GPIO_173"),
PINCTRL_PIN(174, "GPIO_174"),
PINCTRL_PIN(175, "GPIO_175"),
PINCTRL_PIN(176, "GPIO_176"),
PINCTRL_PIN(177, "GPIO_177"),
};
static const unsigned i2c0_pins[] = {145, 146};
static const unsigned i2c1_pins[] = {147, 148};
static const unsigned i2c2_pins[] = {113, 114};
static const unsigned i2c3_pins[] = {19, 20};
static const unsigned uart0_pins[] = {135, 136, 137, 138, 139};
static const unsigned uart1_pins[] = {140, 141, 142, 143, 144};
static const struct amd_pingroup kerncz_groups[] = {
{
.name = "i2c0",
.pins = i2c0_pins,
.npins = 2,
},
{
.name = "i2c1",
.pins = i2c1_pins,
.npins = 2,
},
{
.name = "i2c2",
.pins = i2c2_pins,
.npins = 2,
},
{
.name = "i2c3",
.pins = i2c3_pins,
.npins = 2,
},
{
.name = "uart0",
.pins = uart0_pins,
.npins = 9,
},
{
.name = "uart1",
.pins = uart1_pins,
.npins = 5,
},
};
#endif

Просмотреть файл

@ -625,7 +625,7 @@ static int as3722_pinctrl_remove(struct platform_device *pdev)
return 0;
}
static struct of_device_id as3722_pinctrl_of_match[] = {
static const struct of_device_id as3722_pinctrl_of_match[] = {
{ .compatible = "ams,as3722-pinctrl", },
{ },
};

Просмотреть файл

@ -451,18 +451,18 @@ static enum at91_mux at91_mux_get_periph(void __iomem *pio, unsigned mask)
static bool at91_mux_get_deglitch(void __iomem *pio, unsigned pin)
{
return (__raw_readl(pio + PIO_IFSR) >> pin) & 0x1;
return (readl_relaxed(pio + PIO_IFSR) >> pin) & 0x1;
}
static void at91_mux_set_deglitch(void __iomem *pio, unsigned mask, bool is_on)
{
__raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR));
writel_relaxed(mask, pio + (is_on ? PIO_IFER : PIO_IFDR));
}
static bool at91_mux_pio3_get_deglitch(void __iomem *pio, unsigned pin)
{
if ((__raw_readl(pio + PIO_IFSR) >> pin) & 0x1)
return !((__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1);
if ((readl_relaxed(pio + PIO_IFSR) >> pin) & 0x1)
return !((readl_relaxed(pio + PIO_IFSCSR) >> pin) & 0x1);
return false;
}
@ -470,55 +470,55 @@ static bool at91_mux_pio3_get_deglitch(void __iomem *pio, unsigned pin)
static void at91_mux_pio3_set_deglitch(void __iomem *pio, unsigned mask, bool is_on)
{
if (is_on)
__raw_writel(mask, pio + PIO_IFSCDR);
writel_relaxed(mask, pio + PIO_IFSCDR);
at91_mux_set_deglitch(pio, mask, is_on);
}
static bool at91_mux_pio3_get_debounce(void __iomem *pio, unsigned pin, u32 *div)
{
*div = __raw_readl(pio + PIO_SCDR);
*div = readl_relaxed(pio + PIO_SCDR);
return ((__raw_readl(pio + PIO_IFSR) >> pin) & 0x1) &&
((__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1);
return ((readl_relaxed(pio + PIO_IFSR) >> pin) & 0x1) &&
((readl_relaxed(pio + PIO_IFSCSR) >> pin) & 0x1);
}
static void at91_mux_pio3_set_debounce(void __iomem *pio, unsigned mask,
bool is_on, u32 div)
{
if (is_on) {
__raw_writel(mask, pio + PIO_IFSCER);
__raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR);
__raw_writel(mask, pio + PIO_IFER);
writel_relaxed(mask, pio + PIO_IFSCER);
writel_relaxed(div & PIO_SCDR_DIV, pio + PIO_SCDR);
writel_relaxed(mask, pio + PIO_IFER);
} else
__raw_writel(mask, pio + PIO_IFSCDR);
writel_relaxed(mask, pio + PIO_IFSCDR);
}
static bool at91_mux_pio3_get_pulldown(void __iomem *pio, unsigned pin)
{
return !((__raw_readl(pio + PIO_PPDSR) >> pin) & 0x1);
return !((readl_relaxed(pio + PIO_PPDSR) >> pin) & 0x1);
}
static void at91_mux_pio3_set_pulldown(void __iomem *pio, unsigned mask, bool is_on)
{
if (is_on)
__raw_writel(mask, pio + PIO_PUDR);
writel_relaxed(mask, pio + PIO_PUDR);
__raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR));
writel_relaxed(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR));
}
static void at91_mux_pio3_disable_schmitt_trig(void __iomem *pio, unsigned mask)
{
__raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT);
writel_relaxed(readl_relaxed(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT);
}
static bool at91_mux_pio3_get_schmitt_trig(void __iomem *pio, unsigned pin)
{
return (__raw_readl(pio + PIO_SCHMITT) >> pin) & 0x1;
return (readl_relaxed(pio + PIO_SCHMITT) >> pin) & 0x1;
}
static inline u32 read_drive_strength(void __iomem *reg, unsigned pin)
{
unsigned tmp = __raw_readl(reg);
unsigned tmp = readl_relaxed(reg);
tmp = tmp >> two_bit_pin_value_shift_amount(pin);
@ -554,13 +554,13 @@ static unsigned at91_mux_sam9x5_get_drivestrength(void __iomem *pio,
static void set_drive_strength(void __iomem *reg, unsigned pin, u32 strength)
{
unsigned tmp = __raw_readl(reg);
unsigned tmp = readl_relaxed(reg);
unsigned shift = two_bit_pin_value_shift_amount(pin);
tmp &= ~(DRIVE_STRENGTH_MASK << shift);
tmp |= strength << shift;
__raw_writel(tmp, reg);
writel_relaxed(tmp, reg);
}
static void at91_mux_sama5d3_set_drivestrength(void __iomem *pio, unsigned pin,
@ -1114,7 +1114,7 @@ static int at91_pinctrl_parse_functions(struct device_node *np,
return 0;
}
static struct of_device_id at91_pinctrl_of_match[] = {
static const struct of_device_id at91_pinctrl_of_match[] = {
{ .compatible = "atmel,sama5d3-pinctrl", .data = &sama5d3_ops },
{ .compatible = "atmel,at91sam9x5-pinctrl", .data = &at91sam9x5_ops },
{ .compatible = "atmel,at91rm9200-pinctrl", .data = &at91rm9200_ops },
@ -1240,8 +1240,7 @@ static int at91_pinctrl_probe(struct platform_device *pdev)
if (!info->pctl) {
dev_err(&pdev->dev, "could not register AT91 pinctrl driver\n");
ret = -EINVAL;
goto err;
return -EINVAL;
}
/* We will handle a range of GPIO pins */
@ -1252,9 +1251,6 @@ static int at91_pinctrl_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "initialized AT91 pinctrl driver\n");
return 0;
err:
return ret;
}
static int at91_pinctrl_remove(struct platform_device *pdev)
@ -1535,9 +1531,9 @@ void at91_pinctrl_gpio_suspend(void)
pio = gpio_chips[i]->regbase;
backups[i] = __raw_readl(pio + PIO_IMR);
__raw_writel(backups[i], pio + PIO_IDR);
__raw_writel(wakeups[i], pio + PIO_IER);
backups[i] = readl_relaxed(pio + PIO_IMR);
writel_relaxed(backups[i], pio + PIO_IDR);
writel_relaxed(wakeups[i], pio + PIO_IER);
if (!wakeups[i])
clk_disable_unprepare(gpio_chips[i]->clock);
@ -1562,8 +1558,8 @@ void at91_pinctrl_gpio_resume(void)
if (!wakeups[i])
clk_prepare_enable(gpio_chips[i]->clock);
__raw_writel(wakeups[i], pio + PIO_IDR);
__raw_writel(backups[i], pio + PIO_IER);
writel_relaxed(wakeups[i], pio + PIO_IDR);
writel_relaxed(backups[i], pio + PIO_IER);
}
}
@ -1694,7 +1690,7 @@ static struct gpio_chip at91_gpio_template = {
.ngpio = MAX_NB_GPIO_PER_BANK,
};
static struct of_device_id at91_gpio_of_match[] = {
static const struct of_device_id at91_gpio_of_match[] = {
{ .compatible = "atmel,at91sam9x5-gpio", .data = &at91sam9x5_ops, },
{ .compatible = "atmel,at91rm9200-gpio", .data = &at91rm9200_ops },
{ /* sentinel */ }

Просмотреть файл

@ -193,4 +193,4 @@ enum ltq_pin {
extern int ltq_pinctrl_register(struct platform_device *pdev,
struct ltq_pinmux_info *info);
extern int ltq_pinctrl_unregister(struct platform_device *pdev);
#endif /* __PINCTRL_PXA3XX_H */
#endif /* __PINCTRL_LANTIQ_H */

Просмотреть файл

@ -987,7 +987,7 @@ static struct palmas_pinctrl_data tps80036_pinctrl_data = {
.num_pin_groups = ARRAY_SIZE(tps80036_pingroups),
};
static struct of_device_id palmas_pinctrl_of_match[] = {
static const struct of_device_id palmas_pinctrl_of_match[] = {
{ .compatible = "ti,palmas-pinctrl", .data = &tps65913_pinctrl_data},
{ .compatible = "ti,tps65913-pinctrl", .data = &tps65913_pinctrl_data},
{ .compatible = "ti,tps80036-pinctrl", .data = &tps80036_pinctrl_data},

Просмотреть файл

@ -1501,7 +1501,7 @@ static void pcs_free_resources(struct pcs_device *pcs)
} \
} while (0);
static struct of_device_id pcs_of_match[];
static const struct of_device_id pcs_of_match[];
static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs)
{
@ -2000,7 +2000,7 @@ static const struct pcs_soc_data pinconf_single = {
.flags = PCS_FEAT_PINCONF,
};
static struct of_device_id pcs_of_match[] = {
static const struct of_device_id pcs_of_match[] = {
{ .compatible = "ti,omap3-padconf", .data = &pinctrl_single_omap_wkup },
{ .compatible = "ti,omap4-padconf", .data = &pinctrl_single_omap_wkup },
{ .compatible = "ti,omap5-padconf", .data = &pinctrl_single_omap_wkup },

Просмотреть файл

@ -206,6 +206,8 @@
#define gpio_chip_to_bank(chip) \
container_of(chip, struct st_gpio_bank, gpio_chip)
#define pc_to_bank(pc) \
container_of(pc, struct st_gpio_bank, pc)
enum st_retime_style {
st_retime_style_none,
@ -398,6 +400,16 @@ static const struct st_pctl_data stih407_flashdata = {
.rt = 100,
};
static struct st_pio_control *st_get_pio_control(
struct pinctrl_dev *pctldev, int pin)
{
struct pinctrl_gpio_range *range =
pinctrl_find_gpio_range_from_pin(pctldev, pin);
struct st_gpio_bank *bank = gpio_range_to_bank(range);
return &bank->pc;
}
/* Low level functions.. */
static inline int st_gpio_bank(int gpio)
{
@ -460,6 +472,20 @@ static void st_pctl_set_function(struct st_pio_control *pc,
regmap_field_write(alt, val);
}
static unsigned int st_pctl_get_pin_function(struct st_pio_control *pc, int pin)
{
struct regmap_field *alt = pc->alt;
unsigned int val;
int offset = pin * 4;
if (!alt)
return 0;
regmap_field_read(alt, &val);
return (val >> offset) & 0xf;
}
static unsigned long st_pinconf_delay_to_bit(unsigned int delay,
const struct st_pctl_data *data, unsigned long config)
{
@ -757,6 +783,35 @@ static int st_gpio_direction_output(struct gpio_chip *chip,
return 0;
}
static int st_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
{
struct st_gpio_bank *bank = gpio_chip_to_bank(chip);
struct st_pio_control pc = bank->pc;
unsigned long config;
unsigned int direction = 0;
unsigned int function;
unsigned int value;
int i = 0;
/* Alternate function direction is handled by Pinctrl */
function = st_pctl_get_pin_function(&pc, offset);
if (function) {
st_pinconf_get_direction(&pc, offset, &config);
return !ST_PINCONF_UNPACK_OE(config);
}
/*
* GPIO direction is handled differently
* - See st_gpio_direction() above for an explanation
*/
for (i = 0; i <= 2; i++) {
value = readl(bank->base + REG_PIO_PC(i));
direction |= ((value >> offset) & 0x1) << i;
}
return (direction == ST_GPIO_DIRECTION_IN);
}
static int st_gpio_xlate(struct gpio_chip *gc,
const struct of_phandle_args *gpiospec, u32 *flags)
{
@ -904,16 +959,6 @@ static int st_pmx_get_groups(struct pinctrl_dev *pctldev,
return 0;
}
static struct st_pio_control *st_get_pio_control(
struct pinctrl_dev *pctldev, int pin)
{
struct pinctrl_gpio_range *range =
pinctrl_find_gpio_range_from_pin(pctldev, pin);
struct st_gpio_bank *bank = gpio_range_to_bank(range);
return &bank->pc;
}
static int st_pmx_set_mux(struct pinctrl_dev *pctldev, unsigned fselector,
unsigned group)
{
@ -1011,17 +1056,30 @@ static int st_pinconf_get(struct pinctrl_dev *pctldev,
static void st_pinconf_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s, unsigned pin_id)
{
struct st_pio_control *pc;
unsigned long config;
unsigned int function;
int offset = st_gpio_pin(pin_id);
char f[16];
mutex_unlock(&pctldev->mutex);
pc = st_get_pio_control(pctldev, pin_id);
st_pinconf_get(pctldev, pin_id, &config);
mutex_lock(&pctldev->mutex);
seq_printf(s, "[OE:%ld,PU:%ld,OD:%ld]\n"
function = st_pctl_get_pin_function(pc, offset);
if (function)
snprintf(f, 10, "Alt Fn %d", function);
else
snprintf(f, 5, "GPIO");
seq_printf(s, "[OE:%d,PU:%ld,OD:%ld]\t%s\n"
"\t\t[retime:%ld,invclk:%ld,clknotdat:%ld,"
"de:%ld,rt-clk:%ld,rt-delay:%ld]",
ST_PINCONF_UNPACK_OE(config),
!st_gpio_get_direction(&pc_to_bank(pc)->gpio_chip, offset),
ST_PINCONF_UNPACK_PU(config),
ST_PINCONF_UNPACK_OD(config),
f,
ST_PINCONF_UNPACK_RT(config),
ST_PINCONF_UNPACK_RT_INVERTCLK(config),
ST_PINCONF_UNPACK_RT_CLKNOTDATA(config),
@ -1438,6 +1496,7 @@ static struct gpio_chip st_gpio_template = {
.set = st_gpio_set,
.direction_input = st_gpio_direction_input,
.direction_output = st_gpio_direction_output,
.get_direction = st_gpio_get_direction,
.ngpio = ST_GPIO_PINS_PER_BANK,
.of_gpio_n_cells = 1,
.of_xlate = st_gpio_xlate,
@ -1531,7 +1590,7 @@ static int st_gpiolib_register_bank(struct st_pinctrl *info,
return 0;
}
static struct of_device_id st_pctl_of_match[] = {
static const struct of_device_id st_pctl_of_match[] = {
{ .compatible = "st,stih415-sbc-pinctrl", .data = &stih415_sbc_data },
{ .compatible = "st,stih415-rear-pinctrl", .data = &stih415_rear_data },
{ .compatible = "st,stih415-left-pinctrl", .data = &stih415_left_data },

Просмотреть файл

@ -103,6 +103,7 @@ static const struct cfg_param {
{"nvidia,lock", TEGRA_PINCONF_PARAM_LOCK},
{"nvidia,io-reset", TEGRA_PINCONF_PARAM_IORESET},
{"nvidia,rcv-sel", TEGRA_PINCONF_PARAM_RCV_SEL},
{"nvidia,io-hv", TEGRA_PINCONF_PARAM_RCV_SEL},
{"nvidia,high-speed-mode", TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE},
{"nvidia,schmitt", TEGRA_PINCONF_PARAM_SCHMITT},
{"nvidia,low-power-mode", TEGRA_PINCONF_PARAM_LOW_POWER_MODE},
@ -348,14 +349,24 @@ static int tegra_pinconf_reg(struct tegra_pmx *pmx,
*width = 1;
break;
case TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE:
*bank = g->drv_bank;
*reg = g->drv_reg;
if (pmx->soc->hsm_in_mux) {
*bank = g->mux_bank;
*reg = g->mux_reg;
} else {
*bank = g->drv_bank;
*reg = g->drv_reg;
}
*bit = g->hsm_bit;
*width = 1;
break;
case TEGRA_PINCONF_PARAM_SCHMITT:
*bank = g->drv_bank;
*reg = g->drv_reg;
if (pmx->soc->schmitt_in_mux) {
*bank = g->mux_bank;
*reg = g->mux_reg;
} else {
*bank = g->drv_bank;
*reg = g->drv_reg;
}
*bit = g->schmitt_bit;
*width = 1;
break;
@ -390,8 +401,13 @@ static int tegra_pinconf_reg(struct tegra_pmx *pmx,
*width = g->slwr_width;
break;
case TEGRA_PINCONF_PARAM_DRIVE_TYPE:
*bank = g->drv_bank;
*reg = g->drv_reg;
if (pmx->soc->drvtype_in_mux) {
*bank = g->mux_bank;
*reg = g->mux_reg;
} else {
*bank = g->drv_bank;
*reg = g->drv_reg;
}
*bit = g->drvtype_bit;
*width = 2;
break;

Просмотреть файл

@ -139,26 +139,26 @@ struct tegra_pingroup {
u32 pupd_bank:2;
u32 tri_bank:2;
u32 drv_bank:2;
u32 mux_bit:6;
u32 pupd_bit:6;
u32 tri_bit:6;
u32 einput_bit:6;
u32 odrain_bit:6;
u32 lock_bit:6;
u32 ioreset_bit:6;
u32 rcv_sel_bit:6;
u32 hsm_bit:6;
u32 schmitt_bit:6;
u32 lpmd_bit:6;
u32 drvdn_bit:6;
u32 drvup_bit:6;
u32 slwr_bit:6;
u32 slwf_bit:6;
u32 drvtype_bit:6;
u32 drvdn_width:6;
u32 drvup_width:6;
u32 slwr_width:6;
u32 slwf_width:6;
s32 mux_bit:6;
s32 pupd_bit:6;
s32 tri_bit:6;
s32 einput_bit:6;
s32 odrain_bit:6;
s32 lock_bit:6;
s32 ioreset_bit:6;
s32 rcv_sel_bit:6;
s32 hsm_bit:6;
s32 schmitt_bit:6;
s32 lpmd_bit:6;
s32 drvdn_bit:6;
s32 drvup_bit:6;
s32 slwr_bit:6;
s32 slwf_bit:6;
s32 drvtype_bit:6;
s32 drvdn_width:6;
s32 drvup_width:6;
s32 slwr_width:6;
s32 slwf_width:6;
};
/**
@ -182,6 +182,9 @@ struct tegra_pinctrl_soc_data {
unsigned nfunctions;
const struct tegra_pingroup *groups;
unsigned ngroups;
bool hsm_in_mux;
bool schmitt_in_mux;
bool drvtype_in_mux;
};
int tegra_pinctrl_probe(struct platform_device *pdev,

Просмотреть файл

@ -1547,6 +1547,7 @@ static struct tegra_function tegra114_functions[] = {
#define DRV_PINGROUP_REG_A 0x868 /* bank 0 */
#define PINGROUP_REG_A 0x3000 /* bank 1 */
#define DRV_PINGROUP_REG(r) ((r) - DRV_PINGROUP_REG_A)
#define PINGROUP_REG(r) ((r) - PINGROUP_REG_A)
#define PINGROUP_BIT_Y(b) (b)
@ -1572,20 +1573,17 @@ static struct tegra_function tegra114_functions[] = {
.tri_reg = PINGROUP_REG(r), \
.tri_bank = 1, \
.tri_bit = 4, \
.einput_bit = PINGROUP_BIT_Y(5), \
.einput_bit = 5, \
.odrain_bit = PINGROUP_BIT_##od(6), \
.lock_bit = PINGROUP_BIT_Y(7), \
.lock_bit = 7, \
.ioreset_bit = PINGROUP_BIT_##ior(8), \
.rcv_sel_bit = PINGROUP_BIT_##rcv_sel(9), \
.drv_reg = -1, \
}
#define DRV_PINGROUP_REG(r) ((r) - DRV_PINGROUP_REG_A)
#define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b, \
drvdn_b, drvdn_w, drvup_b, drvup_w, \
slwr_b, slwr_w, slwf_b, slwf_w, \
drvtype) \
#define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b, drvdn_b, \
drvdn_w, drvup_b, drvup_w, slwr_b, slwr_w, \
slwf_b, slwf_w, drvtype) \
{ \
.name = "drive_" #pg_name, \
.pins = drive_##pg_name##_pins, \
@ -1843,6 +1841,9 @@ static const struct tegra_pinctrl_soc_data tegra114_pinctrl = {
.nfunctions = ARRAY_SIZE(tegra114_functions),
.groups = tegra114_groups,
.ngroups = ARRAY_SIZE(tegra114_groups),
.hsm_in_mux = false,
.schmitt_in_mux = false,
.drvtype_in_mux = false,
};
static int tegra114_pinctrl_probe(struct platform_device *pdev)

Просмотреть файл

@ -1536,6 +1536,7 @@ enum tegra_mux {
TEGRA_MUX_CLK,
TEGRA_MUX_CLK12,
TEGRA_MUX_CPU,
TEGRA_MUX_CSI,
TEGRA_MUX_DAP,
TEGRA_MUX_DAP1,
TEGRA_MUX_DAP2,
@ -1544,6 +1545,7 @@ enum tegra_mux {
TEGRA_MUX_DISPLAYA_ALT,
TEGRA_MUX_DISPLAYB,
TEGRA_MUX_DP,
TEGRA_MUX_DSI_B,
TEGRA_MUX_DTV,
TEGRA_MUX_EXTPERIPH1,
TEGRA_MUX_EXTPERIPH2,
@ -1613,8 +1615,6 @@ enum tegra_mux {
TEGRA_MUX_VI_ALT3,
TEGRA_MUX_VIMCLK2,
TEGRA_MUX_VIMCLK2_ALT,
TEGRA_MUX_CSI,
TEGRA_MUX_DSI_B,
};
#define FUNCTION(fname) \
@ -1630,6 +1630,7 @@ static struct tegra_function tegra124_functions[] = {
FUNCTION(clk),
FUNCTION(clk12),
FUNCTION(cpu),
FUNCTION(csi),
FUNCTION(dap),
FUNCTION(dap1),
FUNCTION(dap2),
@ -1638,6 +1639,7 @@ static struct tegra_function tegra124_functions[] = {
FUNCTION(displaya_alt),
FUNCTION(displayb),
FUNCTION(dp),
FUNCTION(dsi_b),
FUNCTION(dtv),
FUNCTION(extperiph1),
FUNCTION(extperiph2),
@ -1707,15 +1709,15 @@ static struct tegra_function tegra124_functions[] = {
FUNCTION(vi_alt3),
FUNCTION(vimclk2),
FUNCTION(vimclk2_alt),
FUNCTION(csi),
FUNCTION(dsi_b),
};
#define DRV_PINGROUP_REG_A 0x868 /* bank 0 */
#define PINGROUP_REG_A 0x3000 /* bank 1 */
#define MIPI_PAD_CTRL_PINGROUP_REG_A 0x820 /* bank 2 */
#define DRV_PINGROUP_REG(r) ((r) - DRV_PINGROUP_REG_A)
#define PINGROUP_REG(r) ((r) - PINGROUP_REG_A)
#define MIPI_PAD_CTRL_PINGROUP_REG_Y(r) ((r) - MIPI_PAD_CTRL_PINGROUP_REG_A)
#define PINGROUP_BIT_Y(b) (b)
#define PINGROUP_BIT_N(b) (-1)
@ -1740,20 +1742,17 @@ static struct tegra_function tegra124_functions[] = {
.tri_reg = PINGROUP_REG(r), \
.tri_bank = 1, \
.tri_bit = 4, \
.einput_bit = PINGROUP_BIT_Y(5), \
.einput_bit = 5, \
.odrain_bit = PINGROUP_BIT_##od(6), \
.lock_bit = PINGROUP_BIT_Y(7), \
.lock_bit = 7, \
.ioreset_bit = PINGROUP_BIT_##ior(8), \
.rcv_sel_bit = PINGROUP_BIT_##rcv_sel(9), \
.drv_reg = -1, \
}
#define DRV_PINGROUP_REG(r) ((r) - DRV_PINGROUP_REG_A)
#define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b, \
drvdn_b, drvdn_w, drvup_b, drvup_w, \
slwr_b, slwr_w, slwf_b, slwf_w, \
drvtype) \
#define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b, drvdn_b, \
drvdn_w, drvup_b, drvup_w, slwr_b, slwr_w, \
slwf_b, slwf_w, drvtype) \
{ \
.name = "drive_" #pg_name, \
.pins = drive_##pg_name##_pins, \
@ -1782,8 +1781,6 @@ static struct tegra_function tegra124_functions[] = {
.drvtype_bit = PINGROUP_BIT_##drvtype(6), \
}
#define MIPI_PAD_CTRL_PINGROUP_REG_Y(r) ((r) - MIPI_PAD_CTRL_PINGROUP_REG_A)
#define MIPI_PAD_CTRL_PINGROUP(pg_name, r, b, f0, f1) \
{ \
.name = "mipi_pad_ctrl_" #pg_name, \
@ -2044,8 +2041,8 @@ static const struct tegra_pingroup tegra124_groups[] = {
DRV_PINGROUP(sdio4, 0x9c4, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2, N),
DRV_PINGROUP(ao4, 0x9c8, 2, 3, 4, 12, 7, 20, 7, 28, 2, 30, 2, Y),
/* pg_name, r b f0, f1 */
MIPI_PAD_CTRL_PINGROUP(dsi_b, 0x820, 1, CSI, DSI_B)
/* pg_name, r, b, f0, f1 */
MIPI_PAD_CTRL_PINGROUP(dsi_b, 0x820, 1, CSI, DSI_B),
};
static const struct tegra_pinctrl_soc_data tegra124_pinctrl = {
@ -2056,6 +2053,9 @@ static const struct tegra_pinctrl_soc_data tegra124_pinctrl = {
.nfunctions = ARRAY_SIZE(tegra124_functions),
.groups = tegra124_groups,
.ngroups = ARRAY_SIZE(tegra124_groups),
.hsm_in_mux = false,
.schmitt_in_mux = false,
.drvtype_in_mux = false,
};
static int tegra124_pinctrl_probe(struct platform_device *pdev)

Просмотреть файл

@ -2221,6 +2221,9 @@ static const struct tegra_pinctrl_soc_data tegra20_pinctrl = {
.nfunctions = ARRAY_SIZE(tegra20_functions),
.groups = tegra20_groups,
.ngroups = ARRAY_SIZE(tegra20_groups),
.hsm_in_mux = false,
.schmitt_in_mux = false,
.drvtype_in_mux = false,
};
static int tegra20_pinctrl_probe(struct platform_device *pdev)

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -2108,70 +2108,69 @@ static struct tegra_function tegra30_functions[] = {
#define DRV_PINGROUP_REG_A 0x868 /* bank 0 */
#define PINGROUP_REG_A 0x3000 /* bank 1 */
#define DRV_PINGROUP_REG(r) ((r) - DRV_PINGROUP_REG_A)
#define PINGROUP_REG(r) ((r) - PINGROUP_REG_A)
#define PINGROUP_BIT_Y(b) (b)
#define PINGROUP_BIT_N(b) (-1)
#define PINGROUP(pg_name, f0, f1, f2, f3, r, od, ior) \
{ \
.name = #pg_name, \
.pins = pg_name##_pins, \
.npins = ARRAY_SIZE(pg_name##_pins), \
.funcs = { \
TEGRA_MUX_##f0, \
TEGRA_MUX_##f1, \
TEGRA_MUX_##f2, \
TEGRA_MUX_##f3, \
}, \
.mux_reg = PINGROUP_REG(r), \
.mux_bank = 1, \
.mux_bit = 0, \
.pupd_reg = PINGROUP_REG(r), \
.pupd_bank = 1, \
.pupd_bit = 2, \
.tri_reg = PINGROUP_REG(r), \
.tri_bank = 1, \
.tri_bit = 4, \
.einput_bit = PINGROUP_BIT_Y(5), \
.odrain_bit = PINGROUP_BIT_##od(6), \
.lock_bit = PINGROUP_BIT_Y(7), \
.ioreset_bit = PINGROUP_BIT_##ior(8), \
.rcv_sel_bit = -1, \
.drv_reg = -1, \
#define PINGROUP(pg_name, f0, f1, f2, f3, r, od, ior) \
{ \
.name = #pg_name, \
.pins = pg_name##_pins, \
.npins = ARRAY_SIZE(pg_name##_pins), \
.funcs = { \
TEGRA_MUX_##f0, \
TEGRA_MUX_##f1, \
TEGRA_MUX_##f2, \
TEGRA_MUX_##f3, \
}, \
.mux_reg = PINGROUP_REG(r), \
.mux_bank = 1, \
.mux_bit = 0, \
.pupd_reg = PINGROUP_REG(r), \
.pupd_bank = 1, \
.pupd_bit = 2, \
.tri_reg = PINGROUP_REG(r), \
.tri_bank = 1, \
.tri_bit = 4, \
.einput_bit = 5, \
.odrain_bit = PINGROUP_BIT_##od(6), \
.lock_bit = 7, \
.ioreset_bit = PINGROUP_BIT_##ior(8), \
.rcv_sel_bit = -1, \
.drv_reg = -1, \
}
#define DRV_PINGROUP_REG(r) ((r) - DRV_PINGROUP_REG_A)
#define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b, \
drvdn_b, drvdn_w, drvup_b, drvup_w, \
slwr_b, slwr_w, slwf_b, slwf_w) \
{ \
.name = "drive_" #pg_name, \
.pins = drive_##pg_name##_pins, \
.npins = ARRAY_SIZE(drive_##pg_name##_pins), \
.mux_reg = -1, \
.pupd_reg = -1, \
.tri_reg = -1, \
.einput_bit = -1, \
.odrain_bit = -1, \
.lock_bit = -1, \
.ioreset_bit = -1, \
.rcv_sel_bit = -1, \
.drv_reg = DRV_PINGROUP_REG(r), \
.drv_bank = 0, \
.hsm_bit = hsm_b, \
.schmitt_bit = schmitt_b, \
.lpmd_bit = lpmd_b, \
.drvdn_bit = drvdn_b, \
.drvdn_width = drvdn_w, \
.drvup_bit = drvup_b, \
.drvup_width = drvup_w, \
.slwr_bit = slwr_b, \
.slwr_width = slwr_w, \
.slwf_bit = slwf_b, \
.slwf_width = slwf_w, \
.drvtype_bit = -1, \
#define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b, drvdn_b, \
drvdn_w, drvup_b, drvup_w, slwr_b, slwr_w, \
slwf_b, slwf_w) \
{ \
.name = "drive_" #pg_name, \
.pins = drive_##pg_name##_pins, \
.npins = ARRAY_SIZE(drive_##pg_name##_pins), \
.mux_reg = -1, \
.pupd_reg = -1, \
.tri_reg = -1, \
.einput_bit = -1, \
.odrain_bit = -1, \
.lock_bit = -1, \
.ioreset_bit = -1, \
.rcv_sel_bit = -1, \
.drv_reg = DRV_PINGROUP_REG(r), \
.drv_bank = 0, \
.hsm_bit = hsm_b, \
.schmitt_bit = schmitt_b, \
.lpmd_bit = lpmd_b, \
.drvdn_bit = drvdn_b, \
.drvdn_width = drvdn_w, \
.drvup_bit = drvup_b, \
.drvup_width = drvup_w, \
.slwr_bit = slwr_b, \
.slwr_width = slwr_w, \
.slwf_bit = slwf_b, \
.slwf_width = slwf_w, \
.drvtype_bit = -1, \
}
static const struct tegra_pingroup tegra30_groups[] = {
@ -2477,6 +2476,9 @@ static const struct tegra_pinctrl_soc_data tegra30_pinctrl = {
.nfunctions = ARRAY_SIZE(tegra30_functions),
.groups = tegra30_groups,
.ngroups = ARRAY_SIZE(tegra30_groups),
.hsm_in_mux = false,
.schmitt_in_mux = false,
.drvtype_in_mux = false,
};
static int tegra30_pinctrl_probe(struct platform_device *pdev)

Просмотреть файл

@ -969,7 +969,7 @@ static int tz1090_pdc_pinctrl_remove(struct platform_device *pdev)
return 0;
}
static struct of_device_id tz1090_pdc_pinctrl_of_match[] = {
static const struct of_device_id tz1090_pdc_pinctrl_of_match[] = {
{ .compatible = "img,tz1090-pdc-pinctrl", },
{ },
};

Просмотреть файл

@ -1984,7 +1984,7 @@ static int tz1090_pinctrl_remove(struct platform_device *pdev)
return 0;
}
static struct of_device_id tz1090_pinctrl_of_match[] = {
static const struct of_device_id tz1090_pinctrl_of_match[] = {
{ .compatible = "img,tz1090-pinctrl", },
{ },
};

Просмотреть файл

@ -193,11 +193,11 @@ static int msm_config_reg(struct msm_pinctrl *pctrl,
*mask = 7;
break;
case PIN_CONFIG_OUTPUT:
case PIN_CONFIG_INPUT_ENABLE:
*bit = g->oe_bit;
*mask = 1;
break;
default:
dev_err(pctrl->dev, "Invalid config param %04x\n", param);
return -ENOTSUPP;
}
@ -261,10 +261,14 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev,
val = readl(pctrl->regs + g->io_reg);
arg = !!(val & BIT(g->in_bit));
break;
case PIN_CONFIG_INPUT_ENABLE:
/* Pin is output */
if (arg)
return -EINVAL;
arg = 1;
break;
default:
dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
param);
return -EINVAL;
return -ENOTSUPP;
}
*config = pinconf_to_config_packed(param, arg);
@ -333,6 +337,10 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev,
/* enable output */
arg = 1;
break;
case PIN_CONFIG_INPUT_ENABLE:
/* disable output */
arg = 0;
break;
default:
dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
param);
@ -357,6 +365,7 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev,
}
static const struct pinconf_ops msm_pinconf_ops = {
.is_generic = true,
.pin_config_group_get = msm_config_group_get,
.pin_config_group_set = msm_config_group_set,
};

Просмотреть файл

@ -810,6 +810,7 @@ static int pmic_gpio_remove(struct platform_device *pdev)
}
static const struct of_device_id pmic_gpio_of_match[] = {
{ .compatible = "qcom,pm8916-gpio" }, /* 4 GPIO's */
{ .compatible = "qcom,pm8941-gpio" }, /* 36 GPIO's */
{ .compatible = "qcom,pma8084-gpio" }, /* 22 GPIO's */
{ },

Просмотреть файл

@ -925,6 +925,7 @@ static int pmic_mpp_remove(struct platform_device *pdev)
static const struct of_device_id pmic_mpp_of_match[] = {
{ .compatible = "qcom,pm8841-mpp" }, /* 4 MPP's */
{ .compatible = "qcom,pm8916-mpp" }, /* 4 MPP's */
{ .compatible = "qcom,pm8941-mpp" }, /* 8 MPP's */
{ .compatible = "qcom,pma8084-mpp" }, /* 8 MPP's */
{ },

Просмотреть файл

@ -1240,6 +1240,159 @@ const struct samsung_pin_ctrl exynos5420_pin_ctrl[] __initconst = {
},
};
/* pin banks of exynos5433 pin-controller - ALIVE */
static const struct samsung_pin_bank_data exynos5433_pin_banks0[] = {
EXYNOS_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08),
EXYNOS_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c),
};
/* pin banks of exynos5433 pin-controller - AUD */
static const struct samsung_pin_bank_data exynos5433_pin_banks1[] = {
EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz0", 0x00),
EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04),
};
/* pin banks of exynos5433 pin-controller - CPIF */
static const struct samsung_pin_bank_data exynos5433_pin_banks2[] = {
EXYNOS_PIN_BANK_EINTG(2, 0x000, "gpv6", 0x00),
};
/* pin banks of exynos5433 pin-controller - eSE */
static const struct samsung_pin_bank_data exynos5433_pin_banks3[] = {
EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj2", 0x00),
};
/* pin banks of exynos5433 pin-controller - FINGER */
static const struct samsung_pin_bank_data exynos5433_pin_banks4[] = {
EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpd5", 0x00),
};
/* pin banks of exynos5433 pin-controller - FSYS */
static const struct samsung_pin_bank_data exynos5433_pin_banks5[] = {
EXYNOS_PIN_BANK_EINTG(6, 0x000, "gph1", 0x00),
EXYNOS_PIN_BANK_EINTG(7, 0x020, "gpr4", 0x04),
EXYNOS_PIN_BANK_EINTG(5, 0x040, "gpr0", 0x08),
EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpr1", 0x0c),
EXYNOS_PIN_BANK_EINTG(2, 0x080, "gpr2", 0x10),
EXYNOS_PIN_BANK_EINTG(8, 0x0a0, "gpr3", 0x14),
};
/* pin banks of exynos5433 pin-controller - IMEM */
static const struct samsung_pin_bank_data exynos5433_pin_banks6[] = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpf0", 0x00),
};
/* pin banks of exynos5433 pin-controller - NFC */
static const struct samsung_pin_bank_data exynos5433_pin_banks7[] = {
EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj0", 0x00),
};
/* pin banks of exynos5433 pin-controller - PERIC */
static const struct samsung_pin_bank_data exynos5433_pin_banks8[] = {
EXYNOS_PIN_BANK_EINTG(6, 0x000, "gpv7", 0x00),
EXYNOS_PIN_BANK_EINTG(5, 0x020, "gpb0", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpc0", 0x08),
EXYNOS_PIN_BANK_EINTG(2, 0x060, "gpc1", 0x0c),
EXYNOS_PIN_BANK_EINTG(6, 0x080, "gpc2", 0x10),
EXYNOS_PIN_BANK_EINTG(8, 0x0a0, "gpc3", 0x14),
EXYNOS_PIN_BANK_EINTG(2, 0x0c0, "gpg0", 0x18),
EXYNOS_PIN_BANK_EINTG(4, 0x0e0, "gpd0", 0x1c),
EXYNOS_PIN_BANK_EINTG(6, 0x100, "gpd1", 0x20),
EXYNOS_PIN_BANK_EINTG(8, 0x120, "gpd2", 0x24),
EXYNOS_PIN_BANK_EINTG(5, 0x140, "gpd4", 0x28),
EXYNOS_PIN_BANK_EINTG(2, 0x160, "gpd8", 0x2c),
EXYNOS_PIN_BANK_EINTG(7, 0x180, "gpd6", 0x30),
EXYNOS_PIN_BANK_EINTG(3, 0x1a0, "gpd7", 0x34),
EXYNOS_PIN_BANK_EINTG(5, 0x1c0, "gpg1", 0x38),
EXYNOS_PIN_BANK_EINTG(2, 0x1e0, "gpg2", 0x3c),
EXYNOS_PIN_BANK_EINTG(8, 0x200, "gpg3", 0x40),
};
/* pin banks of exynos5433 pin-controller - TOUCH */
static const struct samsung_pin_bank_data exynos5433_pin_banks9[] = {
EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj1", 0x00),
};
/*
* Samsung pinctrl driver data for Exynos5433 SoC. Exynos5433 SoC includes
* ten gpio/pin-mux/pinconfig controllers.
*/
const struct samsung_pin_ctrl exynos5433_pin_ctrl[] = {
{
/* pin-controller instance 0 data */
.pin_banks = exynos5433_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks0),
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 1 data */
.pin_banks = exynos5433_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks1),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos5433_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks2),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 3 data */
.pin_banks = exynos5433_pin_banks3,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks3),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 4 data */
.pin_banks = exynos5433_pin_banks4,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks4),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 5 data */
.pin_banks = exynos5433_pin_banks5,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks5),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 6 data */
.pin_banks = exynos5433_pin_banks6,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks6),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 7 data */
.pin_banks = exynos5433_pin_banks7,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks7),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 8 data */
.pin_banks = exynos5433_pin_banks8,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks8),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 9 data */
.pin_banks = exynos5433_pin_banks9,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks9),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
},
};
/* pin banks of exynos7 pin-controller - ALIVE */
static const struct samsung_pin_bank_data exynos7_pin_banks0[] __initconst = {
EXYNOS_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00),
@ -1324,7 +1477,6 @@ const struct samsung_pin_ctrl exynos7_pin_ctrl[] __initconst = {
/* pin-controller instance 0 Alive data */
.pin_banks = exynos7_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos7_pin_banks0),
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
}, {
/* pin-controller instance 1 BUS0 data */

Просмотреть файл

@ -1239,6 +1239,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
.data = (void *)exynos5260_pin_ctrl },
{ .compatible = "samsung,exynos5420-pinctrl",
.data = (void *)exynos5420_pin_ctrl },
{ .compatible = "samsung,exynos5433-pinctrl",
.data = (void *)exynos5433_pin_ctrl },
{ .compatible = "samsung,s5pv210-pinctrl",
.data = (void *)s5pv210_pin_ctrl },
{ .compatible = "samsung,exynos7-pinctrl",

Просмотреть файл

@ -271,6 +271,7 @@ extern const struct samsung_pin_ctrl exynos4415_pin_ctrl[];
extern const struct samsung_pin_ctrl exynos5250_pin_ctrl[];
extern const struct samsung_pin_ctrl exynos5260_pin_ctrl[];
extern const struct samsung_pin_ctrl exynos5420_pin_ctrl[];
extern const struct samsung_pin_ctrl exynos5433_pin_ctrl[];
extern const struct samsung_pin_ctrl exynos7_pin_ctrl[];
extern const struct samsung_pin_ctrl s3c64xx_pin_ctrl[];
extern const struct samsung_pin_ctrl s3c2412_pin_ctrl[];

Просмотреть файл

@ -92,10 +92,10 @@ static int sh_pfc_map_resources(struct sh_pfc *pfc,
return 0;
}
static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc,
unsigned long address)
static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc, u32 reg)
{
struct sh_pfc_window *window;
phys_addr_t address = reg;
unsigned int i;
/* scan through physical windows and convert address */
@ -144,8 +144,7 @@ static int sh_pfc_enum_in_range(u16 enum_id, const struct pinmux_range *r)
return 1;
}
unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg,
unsigned long reg_width)
u32 sh_pfc_read_raw_reg(void __iomem *mapped_reg, unsigned int reg_width)
{
switch (reg_width) {
case 8:
@ -160,8 +159,8 @@ unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg,
return 0;
}
void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned long reg_width,
unsigned long data)
void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned int reg_width,
u32 data)
{
switch (reg_width) {
case 8:
@ -180,10 +179,9 @@ void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned long reg_width,
static void sh_pfc_config_reg_helper(struct sh_pfc *pfc,
const struct pinmux_cfg_reg *crp,
unsigned long in_pos,
void __iomem **mapped_regp,
unsigned long *maskp,
unsigned long *posp)
unsigned int in_pos,
void __iomem **mapped_regp, u32 *maskp,
unsigned int *posp)
{
unsigned int k;
@ -202,15 +200,16 @@ static void sh_pfc_config_reg_helper(struct sh_pfc *pfc,
static void sh_pfc_write_config_reg(struct sh_pfc *pfc,
const struct pinmux_cfg_reg *crp,
unsigned long field, unsigned long value)
unsigned int field, u32 value)
{
void __iomem *mapped_reg;
unsigned long mask, pos, data;
unsigned int pos;
u32 mask, data;
sh_pfc_config_reg_helper(pfc, crp, field, &mapped_reg, &mask, &pos);
dev_dbg(pfc->dev, "write_reg addr = %lx, value = %ld, field = %ld, "
"r_width = %ld, f_width = %ld\n",
dev_dbg(pfc->dev, "write_reg addr = %x, value = 0x%x, field = %u, "
"r_width = %u, f_width = %u\n",
crp->reg, value, field, crp->reg_width, crp->field_width);
mask = ~(mask << pos);
@ -229,26 +228,28 @@ static void sh_pfc_write_config_reg(struct sh_pfc *pfc,
}
static int sh_pfc_get_config_reg(struct sh_pfc *pfc, u16 enum_id,
const struct pinmux_cfg_reg **crp, int *fieldp,
int *valuep)
const struct pinmux_cfg_reg **crp,
unsigned int *fieldp, u32 *valuep)
{
const struct pinmux_cfg_reg *config_reg;
unsigned long r_width, f_width, curr_width, ncomb;
unsigned int k, m, n, pos, bit_pos;
unsigned int k = 0;
k = 0;
while (1) {
config_reg = pfc->info->cfg_regs + k;
r_width = config_reg->reg_width;
f_width = config_reg->field_width;
const struct pinmux_cfg_reg *config_reg =
pfc->info->cfg_regs + k;
unsigned int r_width = config_reg->reg_width;
unsigned int f_width = config_reg->field_width;
unsigned int curr_width;
unsigned int bit_pos;
unsigned int pos = 0;
unsigned int m = 0;
if (!r_width)
break;
pos = 0;
m = 0;
for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) {
u32 ncomb;
u32 n;
if (f_width)
curr_width = f_width;
else
@ -297,11 +298,8 @@ static int sh_pfc_mark_to_enum(struct sh_pfc *pfc, u16 mark, int pos,
int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type)
{
const struct pinmux_cfg_reg *cr = NULL;
u16 enum_id;
const struct pinmux_range *range;
int in_range, pos, field, value;
int ret;
int pos = 0;
switch (pinmux_type) {
case PINMUX_TYPE_GPIO:
@ -321,13 +319,15 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type)
return -EINVAL;
}
pos = 0;
enum_id = 0;
field = 0;
value = 0;
/* Iterate over all the configuration fields we need to update. */
while (1) {
const struct pinmux_cfg_reg *cr;
unsigned int field;
u16 enum_id;
u32 value;
int in_range;
int ret;
pos = sh_pfc_mark_to_enum(pfc, mark, pos, &enum_id);
if (pos < 0)
return pos;
@ -579,9 +579,6 @@ static int sh_pfc_remove(struct platform_device *pdev)
}
static const struct platform_device_id sh_pfc_id_table[] = {
#ifdef CONFIG_PINCTRL_PFC_EMEV2
{ "pfc-emev2", (kernel_ulong_t)&emev2_pinmux_info },
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A73A4
{ "pfc-r8a73a4", (kernel_ulong_t)&r8a73a4_pinmux_info },
#endif
@ -594,12 +591,6 @@ static const struct platform_device_id sh_pfc_id_table[] = {
#ifdef CONFIG_PINCTRL_PFC_R8A7779
{ "pfc-r8a7779", (kernel_ulong_t)&r8a7779_pinmux_info },
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A7790
{ "pfc-r8a7790", (kernel_ulong_t)&r8a7790_pinmux_info },
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A7791
{ "pfc-r8a7791", (kernel_ulong_t)&r8a7791_pinmux_info },
#endif
#ifdef CONFIG_PINCTRL_PFC_SH7203
{ "pfc-sh7203", (kernel_ulong_t)&sh7203_pinmux_info },
#endif

Просмотреть файл

@ -57,10 +57,9 @@ int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc);
int sh_pfc_register_pinctrl(struct sh_pfc *pfc);
int sh_pfc_unregister_pinctrl(struct sh_pfc *pfc);
unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg,
unsigned long reg_width);
void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned long reg_width,
unsigned long data);
u32 sh_pfc_read_raw_reg(void __iomem *mapped_reg, unsigned int reg_width);
void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned int reg_width,
u32 data);
int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin);
int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type);

Просмотреть файл

@ -21,7 +21,7 @@
struct sh_pfc_gpio_data_reg {
const struct pinmux_data_reg *info;
unsigned long shadow;
u32 shadow;
};
struct sh_pfc_gpio_pin {
@ -59,19 +59,20 @@ static void gpio_get_data_reg(struct sh_pfc_chip *chip, unsigned int offset,
*bit = gpio_pin->dbit;
}
static unsigned long gpio_read_data_reg(struct sh_pfc_chip *chip,
const struct pinmux_data_reg *dreg)
static u32 gpio_read_data_reg(struct sh_pfc_chip *chip,
const struct pinmux_data_reg *dreg)
{
void __iomem *mem = dreg->reg - chip->mem->phys + chip->mem->virt;
phys_addr_t address = dreg->reg;
void __iomem *mem = address - chip->mem->phys + chip->mem->virt;
return sh_pfc_read_raw_reg(mem, dreg->reg_width);
}
static void gpio_write_data_reg(struct sh_pfc_chip *chip,
const struct pinmux_data_reg *dreg,
unsigned long value)
const struct pinmux_data_reg *dreg, u32 value)
{
void __iomem *mem = dreg->reg - chip->mem->phys + chip->mem->virt;
phys_addr_t address = dreg->reg;
void __iomem *mem = address - chip->mem->phys + chip->mem->virt;
sh_pfc_write_raw_reg(mem, dreg->reg_width, value);
}
@ -85,7 +86,7 @@ static void gpio_setup_data_reg(struct sh_pfc_chip *chip, unsigned idx)
unsigned int bit;
unsigned int i;
for (i = 0, dreg = pfc->info->data_regs; dreg->reg; ++i, ++dreg) {
for (i = 0, dreg = pfc->info->data_regs; dreg->reg_width; ++i, ++dreg) {
for (bit = 0; bit < dreg->reg_width; bit++) {
if (dreg->enum_ids[bit] == pin->enum_id) {
gpio_pin->dreg = i;
@ -154,17 +155,17 @@ static void gpio_pin_set_value(struct sh_pfc_chip *chip, unsigned offset,
int value)
{
struct sh_pfc_gpio_data_reg *reg;
unsigned long pos;
unsigned int bit;
unsigned int pos;
gpio_get_data_reg(chip, offset, &reg, &bit);
pos = reg->info->reg_width - (bit + 1);
if (value)
set_bit(pos, &reg->shadow);
reg->shadow |= BIT(pos);
else
clear_bit(pos, &reg->shadow);
reg->shadow &= ~BIT(pos);
gpio_write_data_reg(chip, reg->info, reg->shadow);
}
@ -186,8 +187,8 @@ static int gpio_pin_get(struct gpio_chip *gc, unsigned offset)
{
struct sh_pfc_chip *chip = gpio_to_pfc_chip(gc);
struct sh_pfc_gpio_data_reg *reg;
unsigned long pos;
unsigned int bit;
unsigned int pos;
gpio_get_data_reg(chip, offset, &reg, &bit);
@ -341,6 +342,7 @@ sh_pfc_add_gpiochip(struct sh_pfc *pfc, int(*setup)(struct sh_pfc_chip *),
int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
{
struct sh_pfc_chip *chip;
phys_addr_t address;
unsigned int i;
int ret;
@ -352,11 +354,12 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
* that covers the data registers. In that case don't try to handle
* GPIOs.
*/
address = pfc->info->data_regs[0].reg;
for (i = 0; i < pfc->num_windows; ++i) {
struct sh_pfc_window *window = &pfc->windows[i];
if (pfc->info->data_regs[0].reg >= window->phys &&
pfc->info->data_regs[0].reg < window->phys + window->size)
if (address >= window->phys &&
address < window->phys + window->size)
break;
}

Просмотреть файл

@ -1799,6 +1799,81 @@ static const unsigned int audio_clkout_d_pins[] = {
static const unsigned int audio_clkout_d_mux[] = {
AUDIO_CLKOUT_D_MARK,
};
/* - AVB -------------------------------------------------------------------- */
static const unsigned int avb_link_pins[] = {
RCAR_GP_PIN(3, 11),
};
static const unsigned int avb_link_mux[] = {
AVB_LINK_MARK,
};
static const unsigned int avb_magic_pins[] = {
RCAR_GP_PIN(2, 14),
};
static const unsigned int avb_magic_mux[] = {
AVB_MAGIC_MARK,
};
static const unsigned int avb_phy_int_pins[] = {
RCAR_GP_PIN(2, 15),
};
static const unsigned int avb_phy_int_mux[] = {
AVB_PHY_INT_MARK,
};
static const unsigned int avb_mdio_pins[] = {
RCAR_GP_PIN(2, 11), RCAR_GP_PIN(2, 12),
};
static const unsigned int avb_mdio_mux[] = {
AVB_MDC_MARK, AVB_MDIO_MARK,
};
static const unsigned int avb_mii_pins[] = {
RCAR_GP_PIN(0, 8), RCAR_GP_PIN(0, 9), RCAR_GP_PIN(0, 10),
RCAR_GP_PIN(0, 11),
RCAR_GP_PIN(3, 13), RCAR_GP_PIN(2, 0), RCAR_GP_PIN(2, 1),
RCAR_GP_PIN(2, 2),
RCAR_GP_PIN(2, 7), RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
RCAR_GP_PIN(2, 10), RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 10),
RCAR_GP_PIN(3, 12),
};
static const unsigned int avb_mii_mux[] = {
AVB_TXD0_MARK, AVB_TXD1_MARK, AVB_TXD2_MARK,
AVB_TXD3_MARK,
AVB_RXD0_MARK, AVB_RXD1_MARK, AVB_RXD2_MARK,
AVB_RXD3_MARK,
AVB_RX_ER_MARK, AVB_RX_CLK_MARK, AVB_RX_DV_MARK,
AVB_CRS_MARK, AVB_TX_EN_MARK, AVB_TX_CLK_MARK,
AVB_COL_MARK,
};
static const unsigned int avb_gmii_pins[] = {
RCAR_GP_PIN(0, 8), RCAR_GP_PIN(0, 9), RCAR_GP_PIN(0, 10),
RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 12), RCAR_GP_PIN(0, 13),
RCAR_GP_PIN(0, 14), RCAR_GP_PIN(0, 15),
RCAR_GP_PIN(3, 13), RCAR_GP_PIN(2, 0), RCAR_GP_PIN(2, 1),
RCAR_GP_PIN(2, 2), RCAR_GP_PIN(2, 3), RCAR_GP_PIN(2, 4),
RCAR_GP_PIN(2, 5), RCAR_GP_PIN(2, 6),
RCAR_GP_PIN(2, 7), RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 13), RCAR_GP_PIN(2, 16),
RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9), RCAR_GP_PIN(3, 10),
RCAR_GP_PIN(3, 12),
};
static const unsigned int avb_gmii_mux[] = {
AVB_TXD0_MARK, AVB_TXD1_MARK, AVB_TXD2_MARK,
AVB_TXD3_MARK, AVB_TXD4_MARK, AVB_TXD5_MARK,
AVB_TXD6_MARK, AVB_TXD7_MARK,
AVB_RXD0_MARK, AVB_RXD1_MARK, AVB_RXD2_MARK,
AVB_RXD3_MARK, AVB_RXD4_MARK, AVB_RXD5_MARK,
AVB_RXD6_MARK, AVB_RXD7_MARK,
AVB_RX_ER_MARK, AVB_RX_CLK_MARK, AVB_RX_DV_MARK,
AVB_CRS_MARK, AVB_GTX_CLK_MARK, AVB_GTXREFCLK_MARK,
AVB_TX_EN_MARK, AVB_TX_ER_MARK, AVB_TX_CLK_MARK,
AVB_COL_MARK,
};
/* - DU RGB ----------------------------------------------------------------- */
static const unsigned int du_rgb666_pins[] = {
/* R[7:2], G[7:2], B[7:2] */
@ -3823,6 +3898,12 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(audio_clkout_b),
SH_PFC_PIN_GROUP(audio_clkout_c),
SH_PFC_PIN_GROUP(audio_clkout_d),
SH_PFC_PIN_GROUP(avb_link),
SH_PFC_PIN_GROUP(avb_magic),
SH_PFC_PIN_GROUP(avb_phy_int),
SH_PFC_PIN_GROUP(avb_mdio),
SH_PFC_PIN_GROUP(avb_mii),
SH_PFC_PIN_GROUP(avb_gmii),
SH_PFC_PIN_GROUP(du_rgb666),
SH_PFC_PIN_GROUP(du_rgb888),
SH_PFC_PIN_GROUP(du_clk_out_0),
@ -4101,6 +4182,15 @@ static const char * const audio_clk_groups[] = {
"audio_clkout_d",
};
static const char * const avb_groups[] = {
"avb_link",
"avb_magic",
"avb_phy_int",
"avb_mdio",
"avb_mii",
"avb_gmii",
};
static const char * const du_groups[] = {
"du_rgb666",
"du_rgb888",
@ -4507,6 +4597,7 @@ static const char * const vin3_groups[] = {
static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(audio_clk),
SH_PFC_FUNCTION(avb),
SH_PFC_FUNCTION(du),
SH_PFC_FUNCTION(du0),
SH_PFC_FUNCTION(du1),

Просмотреть файл

@ -69,9 +69,10 @@ struct pinmux_func {
};
struct pinmux_cfg_reg {
unsigned long reg, reg_width, field_width;
u32 reg;
u8 reg_width, field_width;
const u16 *enum_ids;
const unsigned long *var_field_width;
const u8 *var_field_width;
};
#define PINMUX_CFG_REG(name, r, r_width, f_width) \
@ -80,12 +81,13 @@ struct pinmux_cfg_reg {
#define PINMUX_CFG_REG_VAR(name, r, r_width, var_fw0, var_fwn...) \
.reg = r, .reg_width = r_width, \
.var_field_width = (const unsigned long [r_width]) \
.var_field_width = (const u8 [r_width]) \
{ var_fw0, var_fwn, 0 }, \
.enum_ids = (const u16 [])
struct pinmux_data_reg {
unsigned long reg, reg_width;
u32 reg;
u8 reg_width;
const u16 *enum_ids;
};
@ -148,7 +150,7 @@ struct sh_pfc_soc_info {
const struct pinmux_irq *gpio_irq;
unsigned int gpio_irq_size;
unsigned long unlock_reg;
u32 unlock_reg;
};
/* -----------------------------------------------------------------------------
@ -302,20 +304,21 @@ struct sh_pfc_soc_info {
/*
* PORTnCR macro
*/
#define _PCRH(in, in_pd, in_pu, out) \
0, (out), (in), 0, \
0, 0, 0, 0, \
0, 0, (in_pd), 0, \
0, 0, (in_pu), 0
#define PORTCR(nr, reg) \
{ \
PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
_PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT), \
PORT##nr##_FN0, PORT##nr##_FN1, \
PORT##nr##_FN2, PORT##nr##_FN3, \
PORT##nr##_FN4, PORT##nr##_FN5, \
PORT##nr##_FN6, PORT##nr##_FN7 } \
PINMUX_CFG_REG_VAR("PORT" nr "CR", reg, 8, 2, 2, 1, 3) {\
/* PULMD[1:0], handled by .set_bias() */ \
0, 0, 0, 0, \
/* IE and OE */ \
0, PORT##nr##_OUT, PORT##nr##_IN, 0, \
/* SEC, not supported */ \
0, 0, \
/* PTMD[2:0] */ \
PORT##nr##_FN0, PORT##nr##_FN1, \
PORT##nr##_FN2, PORT##nr##_FN3, \
PORT##nr##_FN4, PORT##nr##_FN5, \
PORT##nr##_FN6, PORT##nr##_FN7 \
} \
}
#endif /* __SH_PFC_H */

Просмотреть файл

@ -39,10 +39,9 @@ struct sirfsoc_gpio_bank {
struct sirfsoc_gpio_chip {
struct of_mm_gpio_chip chip;
struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS];
spinlock_t lock;
};
static DEFINE_SPINLOCK(sgpio_lock);
static struct sirfsoc_pin_group *sirfsoc_pin_groups;
static int sirfsoc_pingrp_cnt;
@ -427,13 +426,13 @@ static void sirfsoc_gpio_irq_ack(struct irq_data *d)
offset = SIRFSOC_GPIO_CTRL(bank->id, idx);
spin_lock_irqsave(&sgpio_lock, flags);
spin_lock_irqsave(&sgpio->lock, flags);
val = readl(sgpio->chip.regs + offset);
writel(val, sgpio->chip.regs + offset);
spin_unlock_irqrestore(&sgpio_lock, flags);
spin_unlock_irqrestore(&sgpio->lock, flags);
}
static void __sirfsoc_gpio_irq_mask(struct sirfsoc_gpio_chip *sgpio,
@ -445,14 +444,14 @@ static void __sirfsoc_gpio_irq_mask(struct sirfsoc_gpio_chip *sgpio,
offset = SIRFSOC_GPIO_CTRL(bank->id, idx);
spin_lock_irqsave(&sgpio_lock, flags);
spin_lock_irqsave(&sgpio->lock, flags);
val = readl(sgpio->chip.regs + offset);
val &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK;
val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK;
writel(val, sgpio->chip.regs + offset);
spin_unlock_irqrestore(&sgpio_lock, flags);
spin_unlock_irqrestore(&sgpio->lock, flags);
}
static void sirfsoc_gpio_irq_mask(struct irq_data *d)
@ -475,14 +474,14 @@ static void sirfsoc_gpio_irq_unmask(struct irq_data *d)
offset = SIRFSOC_GPIO_CTRL(bank->id, idx);
spin_lock_irqsave(&sgpio_lock, flags);
spin_lock_irqsave(&sgpio->lock, flags);
val = readl(sgpio->chip.regs + offset);
val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK;
val |= SIRFSOC_GPIO_CTL_INTR_EN_MASK;
writel(val, sgpio->chip.regs + offset);
spin_unlock_irqrestore(&sgpio_lock, flags);
spin_unlock_irqrestore(&sgpio->lock, flags);
}
static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type)
@ -496,7 +495,7 @@ static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type)
offset = SIRFSOC_GPIO_CTRL(bank->id, idx);
spin_lock_irqsave(&sgpio_lock, flags);
spin_lock_irqsave(&sgpio->lock, flags);
val = readl(sgpio->chip.regs + offset);
val &= ~(SIRFSOC_GPIO_CTL_INTR_STS_MASK | SIRFSOC_GPIO_CTL_OUT_EN_MASK);
@ -533,7 +532,7 @@ static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type)
writel(val, sgpio->chip.regs + offset);
spin_unlock_irqrestore(&sgpio_lock, flags);
spin_unlock_irqrestore(&sgpio->lock, flags);
return 0;
}
@ -568,7 +567,7 @@ static void sirfsoc_gpio_handle_irq(unsigned int irq, struct irq_desc *desc)
status = readl(sgpio->chip.regs + SIRFSOC_GPIO_INT_STATUS(bank->id));
if (!status) {
printk(KERN_WARNING
"%s: gpio id %d status %#x no interrupt is flaged\n",
"%s: gpio id %d status %#x no interrupt is flagged\n",
__func__, bank->id, status);
handle_bad_irq(irq, desc);
return;
@ -697,11 +696,11 @@ static int sirfsoc_gpio_direction_output(struct gpio_chip *chip,
offset = SIRFSOC_GPIO_CTRL(bank->id, idx);
spin_lock_irqsave(&sgpio_lock, flags);
spin_lock_irqsave(&sgpio->lock, flags);
sirfsoc_gpio_set_output(sgpio, bank, offset, value);
spin_unlock_irqrestore(&sgpio_lock, flags);
spin_unlock_irqrestore(&sgpio->lock, flags);
return 0;
}
@ -793,6 +792,7 @@ static int sirfsoc_gpio_probe(struct device_node *np)
sgpio = devm_kzalloc(&pdev->dev, sizeof(*sgpio), GFP_KERNEL);
if (!sgpio)
return -ENOMEM;
spin_lock_init(&sgpio->lock);
regs = of_iomap(np, 0);
if (!regs)

Просмотреть файл

@ -1020,7 +1020,7 @@ static int sun4i_a10_pinctrl_probe(struct platform_device *pdev)
&sun4i_a10_pinctrl_data);
}
static struct of_device_id sun4i_a10_pinctrl_match[] = {
static const struct of_device_id sun4i_a10_pinctrl_match[] = {
{ .compatible = "allwinner,sun4i-a10-pinctrl", },
{}
};

Просмотреть файл

@ -670,7 +670,7 @@ static int sun5i_a10s_pinctrl_probe(struct platform_device *pdev)
&sun5i_a10s_pinctrl_data);
}
static struct of_device_id sun5i_a10s_pinctrl_match[] = {
static const struct of_device_id sun5i_a10s_pinctrl_match[] = {
{ .compatible = "allwinner,sun5i-a10s-pinctrl", },
{}
};

Просмотреть файл

@ -388,7 +388,7 @@ static int sun5i_a13_pinctrl_probe(struct platform_device *pdev)
&sun5i_a13_pinctrl_data);
}
static struct of_device_id sun5i_a13_pinctrl_match[] = {
static const struct of_device_id sun5i_a13_pinctrl_match[] = {
{ .compatible = "allwinner,sun5i-a13-pinctrl", },
{}
};

Просмотреть файл

@ -120,7 +120,7 @@ static int sun6i_a31_r_pinctrl_probe(struct platform_device *pdev)
return ret;
}
static struct of_device_id sun6i_a31_r_pinctrl_match[] = {
static const struct of_device_id sun6i_a31_r_pinctrl_match[] = {
{ .compatible = "allwinner,sun6i-a31-r-pinctrl", },
{}
};

Просмотреть файл

@ -922,7 +922,7 @@ static int sun6i_a31_pinctrl_probe(struct platform_device *pdev)
&sun6i_a31_pinctrl_data);
}
static struct of_device_id sun6i_a31_pinctrl_match[] = {
static const struct of_device_id sun6i_a31_pinctrl_match[] = {
{ .compatible = "allwinner,sun6i-a31-pinctrl", },
{}
};

Просмотреть файл

@ -794,7 +794,7 @@ static int sun6i_a31s_pinctrl_probe(struct platform_device *pdev)
&sun6i_a31s_pinctrl_data);
}
static struct of_device_id sun6i_a31s_pinctrl_match[] = {
static const struct of_device_id sun6i_a31s_pinctrl_match[] = {
{ .compatible = "allwinner,sun6i-a31s-pinctrl", },
{}
};

Просмотреть файл

@ -1045,7 +1045,7 @@ static int sun7i_a20_pinctrl_probe(struct platform_device *pdev)
&sun7i_a20_pinctrl_data);
}
static struct of_device_id sun7i_a20_pinctrl_match[] = {
static const struct of_device_id sun7i_a20_pinctrl_match[] = {
{ .compatible = "allwinner,sun7i-a20-pinctrl", },
{}
};

Просмотреть файл

@ -119,7 +119,7 @@ static int sun8i_a23_r_pinctrl_probe(struct platform_device *pdev)
return ret;
}
static struct of_device_id sun8i_a23_r_pinctrl_match[] = {
static const struct of_device_id sun8i_a23_r_pinctrl_match[] = {
{ .compatible = "allwinner,sun8i-a23-r-pinctrl", },
{}
};

Просмотреть файл

@ -571,7 +571,7 @@ static int sun8i_a23_pinctrl_probe(struct platform_device *pdev)
&sun8i_a23_pinctrl_data);
}
static struct of_device_id sun8i_a23_pinctrl_match[] = {
static const struct of_device_id sun8i_a23_pinctrl_match[] = {
{ .compatible = "allwinner,sun8i-a23-pinctrl", },
{}
};

Просмотреть файл

@ -729,7 +729,7 @@ static int sun9i_a80_pinctrl_probe(struct platform_device *pdev)
&sun9i_a80_pinctrl_data);
}
static struct of_device_id sun9i_a80_pinctrl_match[] = {
static const struct of_device_id sun9i_a80_pinctrl_match[] = {
{ .compatible = "allwinner,sun9i-a80-pinctrl", },
{}
};

Просмотреть файл

@ -478,7 +478,7 @@ static int vt8500_pinctrl_remove(struct platform_device *pdev)
return wmt_pinctrl_remove(pdev);
}
static struct of_device_id wmt_pinctrl_of_match[] = {
static const struct of_device_id wmt_pinctrl_of_match[] = {
{ .compatible = "via,vt8500-pinctrl" },
{ /* sentinel */ },
};

Просмотреть файл

@ -509,7 +509,7 @@ static int wm8505_pinctrl_remove(struct platform_device *pdev)
return wmt_pinctrl_remove(pdev);
}
static struct of_device_id wmt_pinctrl_of_match[] = {
static const struct of_device_id wmt_pinctrl_of_match[] = {
{ .compatible = "wm,wm8505-pinctrl" },
{ /* sentinel */ },
};

Просмотреть файл

@ -347,7 +347,7 @@ static int wm8650_pinctrl_remove(struct platform_device *pdev)
return wmt_pinctrl_remove(pdev);
}
static struct of_device_id wmt_pinctrl_of_match[] = {
static const struct of_device_id wmt_pinctrl_of_match[] = {
{ .compatible = "wm,wm8650-pinctrl" },
{ /* sentinel */ },
};

Просмотреть файл

@ -386,7 +386,7 @@ static int wm8750_pinctrl_remove(struct platform_device *pdev)
return wmt_pinctrl_remove(pdev);
}
static struct of_device_id wmt_pinctrl_of_match[] = {
static const struct of_device_id wmt_pinctrl_of_match[] = {
{ .compatible = "wm,wm8750-pinctrl" },
{ /* sentinel */ },
};

Просмотреть файл

@ -365,7 +365,7 @@ static int wm8850_pinctrl_remove(struct platform_device *pdev)
return wmt_pinctrl_remove(pdev);
}
static struct of_device_id wmt_pinctrl_of_match[] = {
static const struct of_device_id wmt_pinctrl_of_match[] = {
{ .compatible = "wm,wm8850-pinctrl" },
{ /* sentinel */ },
};

Просмотреть файл

@ -0,0 +1,32 @@
/*
* GPIO definitions for Amlogic Meson8b SoCs
*
* Copyright (C) 2015 Endless Mobile, Inc.
* Author: Carlo Caione <carlo@endlessm.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _DT_BINDINGS_MESON8B_GPIO_H
#define _DT_BINDINGS_MESON8B_GPIO_H
#include <dt-bindings/gpio/meson8-gpio.h>
/* GPIO Bank DIF */
#define DIF_0_P 120
#define DIF_0_N 121
#define DIF_1_P 122
#define DIF_1_N 123
#define DIF_2_P 124
#define DIF_2_N 125
#define DIF_3_P 126
#define DIF_3_N 127
#define DIF_4_P 128
#define DIF_4_N 129
#endif /* _DT_BINDINGS_MESON8B_GPIO_H */

Просмотреть файл

@ -0,0 +1,40 @@
/*
* Copyright (c) 2014 MediaTek Inc.
* Author: Hongzhou.Yang <hongzhou.yang@mediatek.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _DT_BINDINGS_PINCTRL_MT65XX_H
#define _DT_BINDINGS_PINCTRL_MT65XX_H
#define MTK_PIN_NO(x) ((x) << 8)
#define MTK_GET_PIN_NO(x) ((x) >> 8)
#define MTK_GET_PIN_FUNC(x) ((x) & 0xf)
#define MTK_PUPD_SET_R1R0_00 100
#define MTK_PUPD_SET_R1R0_01 101
#define MTK_PUPD_SET_R1R0_10 102
#define MTK_PUPD_SET_R1R0_11 103
#define MTK_DRIVE_2mA 2
#define MTK_DRIVE_4mA 4
#define MTK_DRIVE_6mA 6
#define MTK_DRIVE_8mA 8
#define MTK_DRIVE_10mA 10
#define MTK_DRIVE_12mA 12
#define MTK_DRIVE_14mA 14
#define MTK_DRIVE_16mA 16
#define MTK_DRIVE_20mA 20
#define MTK_DRIVE_24mA 24
#define MTK_DRIVE_28mA 28
#define MTK_DRIVE_32mA 32
#endif /* _DT_BINDINGS_PINCTRL_MT65XX_H */

Просмотреть файл

@ -48,6 +48,14 @@
#define PM8058_GPIO_L5 6
#define PM8058_GPIO_L2 7
/*
* Note: PM8916 GPIO1 and GPIO2 are supporting
* only L2(1.15V) and L5(1.8V) options
*/
#define PM8916_GPIO_VPH 0
#define PM8916_GPIO_L2 2
#define PM8916_GPIO_L5 3
#define PM8917_GPIO_VPH 0
#define PM8917_GPIO_S4 2
#define PM8917_GPIO_L15 3
@ -115,6 +123,13 @@
#define PM8058_GPIO39_MP3_CLK PMIC_GPIO_FUNC_FUNC1
#define PM8058_GPIO40_EXT_BB_EN PMIC_GPIO_FUNC_FUNC1
#define PM8916_GPIO1_BAT_ALRM_OUT PMIC_GPIO_FUNC_FUNC1
#define PM8916_GPIO1_KEYP_DRV PMIC_GPIO_FUNC_FUNC2
#define PM8916_GPIO2_DIV_CLK PMIC_GPIO_FUNC_FUNC1
#define PM8916_GPIO2_SLEEP_CLK PMIC_GPIO_FUNC_FUNC2
#define PM8916_GPIO3_KEYP_DRV PMIC_GPIO_FUNC_FUNC1
#define PM8916_GPIO4_KEYP_DRV PMIC_GPIO_FUNC_FUNC2
#define PM8917_GPIO9_18_KEYP_DRV PMIC_GPIO_FUNC_FUNC1
#define PM8917_GPIO20_BAT_ALRM_OUT PMIC_GPIO_FUNC_FUNC1
#define PM8917_GPIO21_23_UART_TX PMIC_GPIO_FUNC_FUNC2

Просмотреть файл

@ -10,6 +10,10 @@
#define PM8841_MPP_VPH 0
#define PM8841_MPP_S3 2
#define PM8916_MPP_VPH 0
#define PM8916_MPP_L2 2
#define PM8916_MPP_L5 3
#define PM8941_MPP_VPH 0
#define PM8941_MPP_L1 1
#define PM8941_MPP_S3 2