1
0
Fork 0

These are the main pinctrl changes for the v3.9 merge window:

- Grabbing of default pinctrl handles from the device core.
   These are the hunks hitting drivers/base. All is ACKed by
   Greg, after a long discussion about different alternatives.
 
 - Some stuff also touches the MFD and ARM SoC trees, this has
   been coordinated and ACKed.
 
 - New drivers for:
 
   - The Tegra 114 sub-SoC
   - Allwinner sunxi
   - New ABx500 driver and sub-SoC drivers for AB8500,
     AB8505, AB9540 and AB8540.
 
 - Make it possible for hogged pins to enter a sleep mode,
   and make it possible for drivers to control that mode.
 
 - Various clean-up, extensions and device tree support to
   various pin controllers.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.10 (GNU/Linux)
 
 iQIcBAABAgAGBQJRHqYQAAoJEEEQszewGV1zsBwQAIDM3MYW6sJcNd+Ekcli8dqv
 2dpzs3c4R9j3Ea0IUS3YRrk8pXeKIw6Ko0ifzFFLPF6s7kuBv1VaNdx7U8wbtoCj
 ZprMmvWTJZvD4zP8WsT9TIgGcCiQQnHbz8jyucGgMUNuwt/S0f5FeQc2mQtZGklT
 yuZ0z9eHQjqkX12ijI+lO5RI+Sduvd/FQgGIbhfoyBEMFwklTq3ePvmH5MUUMzXb
 2uNSvACbnBUkvZlYLGlr5J5w6euqX7oxUnHEf2nBt2L8d0zgP2WC2tonLLwEtzD0
 jcl3NA57eJa42PoQlNL6jZLz0kNWcGRfurstUO7UiFJ0lSxiwjYLGBqB5vfEdjAV
 wg0BokJ1vigrzUUdNPEIh6QFSrXs0I76oAMmHbXxJjnEPwahn5forYpU3G6GmCy4
 ZsTMJgXqrJeolqcDY583M31Lx0lu8/OwMjG6OBnDRCbhzq3bJgF/Nhu9nzmShFN7
 3z+NK0zBzECylV31eygyoU4SUQduYrV2YEav0QNRiZWfi3HBNcEiZGBJxUvv7+cc
 lYox6CPLCZN0Xn9y2Jt3uLNeivdjQLAJRPWnLaFtq0i4EjqpTtQnzw5LLsIqhumc
 9BhhoZ6ktPnp9CK6gQOy+dwJPiigCrqog5oCqLArI0UvRrE7BNkHrjRay8PkMqRC
 Fl4x7eR3fVfENExogGac
 =SQ9W
 -----END PGP SIGNATURE-----

Merge tag 'pinctrl-for-v3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl

Pull pinctrl changes from Linus Walleij:
 "These are the main pinctrl changes for the v3.9 merge window.  The
  most interesting change by far is how the device core grabs pinctrl
  default handles avoiding the need to stick boilerplate into driver
  consumers.

   - Grabbing of default pinctrl handles from the device core.  These
     are the hunks hitting drivers/base.  All is ACKed by Greg, after a
     long discussion about different alternatives.

   - Some stuff also touches the MFD and ARM SoC trees, this has been
     coordinated and ACKed.

   - New drivers for:
     - The Tegra 114 sub-SoC
     - Allwinner sunxi
     - New ABx500 driver and sub-SoC drivers for AB8500, AB8505, AB9540
       and AB8540.

   - Make it possible for hogged pins to enter a sleep mode, and make it
     possible for drivers to control that mode.

   - Various clean-up, extensions and device tree support to various pin
     controllers."

* tag 'pinctrl-for-v3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (68 commits)
  pinctrl: tegra: add clfvs function to Tegra114 support
  pinctrl: generic: rename input schmitt disable
  pinctrl/pinconfig: add debug interface
  pinctrl: samsung: remove duplicated line
  ARM: ux500: use real AB8500 IRQ numbers instead of virtual ones
  ARM: ux500: remove irq_base property from platform_data
  pinctrl/abx500: use direct IRQ defines
  pinctrl/abx500: replace IRQ offsets with table read-in values
  pinctrl/abx500: move IRQ handling to ab8500-core
  pinctrl: exynos5440: remove erroneous __init
  pinctrl/abx500: adjust offset for get_mode()
  pinctrl/abx500: add Device Tree support
  pinctrl/abx500: align GPIO cluster boundaries
  pinctrl/abx500: prevent error path from corrupting returning error
  pinctrl: sunxi: add of_xlate function
  pinctrl/lantiq: fix pin number in ltq_pmx_gpio_request_enable
  pinctrl/lantiq: add functionality to falcon_pinconf_dbg_show
  pinctrl/lantiq: fix pinconfig parameters
  pinctrl/lantiq: one of the boot leds was defined incorrectly
  pinctrl/lantiq: only probe available pad controllers
  ...
wifi-calibration
Linus Torvalds 2013-02-20 09:23:30 -08:00
commit 8a3a11f91d
54 changed files with 9415 additions and 742 deletions

View File

@ -0,0 +1,60 @@
* Allwinner A1X Pin Controller
The pins controlled by sunXi pin controller are organized in banks,
each bank has 32 pins. Each pin has 7 multiplexing functions, with
the first two functions being GPIO in and out. The configuration on
the pins includes drive strength and pull-up.
Required properties:
- compatible: "allwinner,<soc>-pinctrl". Supported SoCs for now are:
sun5i-a13.
- reg: Should contain the register physical address and length for the
pin controller.
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices.
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, drive strength and pullups. If one of these options is
not set, its actual value will be unspecified.
Required subnode-properties:
- allwinner,pins: List of strings containing the pin name.
- allwinner,function: Function to mux the pins listed above to.
Optional subnode-properties:
- allwinner,drive: Integer. Represents the current sent to the pin
0: 10 mA
1: 20 mA
2: 30 mA
3: 40 mA
- allwinner,pull: Integer.
0: No resistor
1: Pull-up resistor
2: Pull-down resistor
Examples:
pinctrl@01c20800 {
compatible = "allwinner,sun5i-a13-pinctrl";
reg = <0x01c20800 0x400>;
#address-cells = <1>;
#size-cells = <0>;
uart1_pins_a: uart1@0 {
allwinner,pins = "PE10", "PE11";
allwinner,function = "uart1";
allwinner,drive = <0>;
allwinner,pull = <0>;
};
uart1_pins_b: uart1@1 {
allwinner,pins = "PG3", "PG4";
allwinner,function = "uart1";
allwinner,drive = <0>;
allwinner,pull = <0>;
};
};

View File

@ -0,0 +1,120 @@
NVIDIA Tegra114 pinmux controller
The Tegra114 pinctrl binding is very similar to the Tegra20 and Tegra30
pinctrl binding, as described in nvidia,tegra20-pinmux.txt and
nvidia,tegra30-pinmux.txt. In fact, this document assumes that binding as
a baseline, and only documents the differences between the two bindings.
Required properties:
- compatible: "nvidia,tegra114-pinmux"
- reg: Should contain the register physical address and length for each of
the pad control and mux registers. The first bank of address must be the
driver strength pad control register address and second bank address must
be pinmux register address.
Tegra114 adds the following optional properties for pin configuration subnodes:
- nvidia,enable-input: Integer. Enable the pin's input path. 0: no, 1: yes.
- nvidia,open-drain: Integer. Enable open drain mode. 0: no, 1: yes.
- nvidia,lock: Integer. Lock the pin configuration against further changes
until reset. 0: no, 1: yes.
- nvidia,io-reset: Integer. Reset the IO path. 0: no, 1: yes.
- nvidia,rcv-sel: Integer. Select VIL/VIH receivers. 0: normal, 1: high.
- nvidia,drive-type: Integer. Valid range 0...3.
As with Tegra20 and Terga30, see the Tegra TRM for complete details regarding
which groups support which functionality.
Valid values for pin and group names are:
per-pin mux groups:
These all support nvidia,function, nvidia,tristate, nvidia,pull,
nvidia,enable-input, nvidia,lock. Some support nvidia,open-drain,
nvidia,io-reset and nvidia,rcv-sel.
ulpi_data0_po1, ulpi_data1_po2, ulpi_data2_po3, ulpi_data3_po4,
ulpi_data4_po5, ulpi_data5_po6, ulpi_data6_po7, ulpi_data7_po0,
ulpi_clk_py0, ulpi_dir_py1, ulpi_nxt_py2, ulpi_stp_py3, dap3_fs_pp0,
dap3_din_pp1, dap3_dout_pp2, dap3_sclk_pp3, pv0, pv1, sdmmc1_clk_pz0,
sdmmc1_cmd_pz1, sdmmc1_dat3_py4, sdmmc1_dat2_py5, sdmmc1_dat1_py6,
sdmmc1_dat0_py7, clk2_out_pw5, clk2_req_pcc5, hdmi_int_pn7, ddc_scl_pv4,
ddc_sda_pv5, uart2_rxd_pc3, uart2_txd_pc2, uart2_rts_n_pj6,
uart2_cts_n_pj5, uart3_txd_pw6, uart3_rxd_pw7, uart3_cts_n_pa1,
uart3_rts_n_pc0, pu0, pu1, pu2, pu3, pu4, pu5, pu6, gen1_i2c_sda_pc5,
gen1_i2c_scl_pc4, dap4_fs_pp4, dap4_din_pp5, dap4_dout_pp6, dap4_sclk_pp7,
clk3_out_pee0, clk3_req_pee1, gmi_wp_n_pc7, gmi_iordy_pi5, gmi_wait_pi7,
gmi_adv_n_pk0, gmi_clk_pk1, gmi_cs0_n_pj0, gmi_cs1_n_pj2, gmi_cs2_n_pk3,
gmi_cs3_n_pk4, gmi_cs4_n_pk2, gmi_cs6_n_pi3, gmi_cs7_n_pi6, gmi_ad0_pg0,
gmi_ad1_pg1, gmi_ad2_pg2, gmi_ad3_pg3, gmi_ad4_pg4, gmi_ad5_pg5,
gmi_ad6_pg6, gmi_ad7_pg7, gmi_ad8_ph0, gmi_ad9_ph1, gmi_ad10_ph2,
gmi_ad11_ph3, gmi_ad12_ph4, gmi_ad13_ph5, gmi_ad14_ph6, gmi_ad15_ph7,
gmi_a16_pj7, gmi_a17_pb0, gmi_a18_pb1, gmi_a19_pk7, gmi_wr_n_pi0,
gmi_oe_n_pi1, gmi_dqs_p_pj3, gmi_rst_n_pi4, gen2_i2c_scl_pt5,
gen2_i2c_sda_pt6, sdmmc4_clk_pcc4, sdmmc4_cmd_pt7, sdmmc4_dat0_paa0,
sdmmc4_dat1_paa1, sdmmc4_dat2_paa2, sdmmc4_dat3_paa3, sdmmc4_dat4_paa4,
sdmmc4_dat5_paa5, sdmmc4_dat6_paa6, sdmmc4_dat7_paa7, cam_mclk_pcc0,
pcc1, pbb0, cam_i2c_scl_pbb1, cam_i2c_sda_pbb2, pbb3, pbb4, pbb5, pbb6,
pbb7, pcc2, pwr_i2c_scl_pz6, pwr_i2c_sda_pz7, kb_row0_pr0, kb_row1_pr1,
kb_row2_pr2, kb_row3_pr3, kb_row4_pr4, kb_row5_pr5, kb_row6_pr6,
kb_row7_pr7, kb_row8_ps0, kb_row9_ps1, kb_row10_ps2, kb_col0_pq0,
kb_col1_pq1, kb_col2_pq2, kb_col3_pq3, kb_col4_pq4, kb_col5_pq5,
kb_col6_pq6, kb_col7_pq7, clk_32k_out_pa0, sys_clk_req_pz5, core_pwr_req,
cpu_pwr_req, pwr_int_n, owr, dap1_fs_pn0, dap1_din_pn1, dap1_dout_pn2,
dap1_sclk_pn3, clk1_req_pee2, clk1_out_pw4, spdif_in_pk6, spdif_out_pk5,
dap2_fs_pa2, dap2_din_pa4, dap2_dout_pa5, dap2_sclk_pa3, dvfs_pwm_px0,
gpio_x1_aud_px1, gpio_x3_aud_px3, dvfs_clk_px2, gpio_x4_aud_px4,
gpio_x5_aud_px5, gpio_x6_aud_px6, gpio_x7_aud_px7, sdmmc3_clk_pa6,
sdmmc3_cmd_pa7, sdmmc3_dat0_pb7, sdmmc3_dat1_pb6, sdmmc3_dat2_pb5,
sdmmc3_dat3_pb4, hdmi_cec_pee3, sdmmc1_wp_n_pv3, sdmmc3_cd_n_pv2,
gpio_w2_aud_pw2, gpio_w3_aud_pw3, usb_vbus_en0_pn4, usb_vbus_en1_pn5,
sdmmc3_clk_lb_in_pee5, sdmmc3_clk_lb_out_pee4, reset_out_n.
drive groups:
These all support nvidia,pull-down-strength, nvidia,pull-up-strength,
nvidia,slew-rate-rising, nvidia,slew-rate-falling. Most but not all
support nvidia,high-speed-mode, nvidia,schmitt, nvidia,low-power-mode
and nvidia,drive-type.
ao1, ao2, at1, at2, at3, at4, at5, cdev1, cdev2, dap1, dap2, dap3, dap4,
dbg, sdio3, spi, uaa, uab, uart2, uart3, sdio1, ddc, gma, gme, gmf, gmg,
gmh, owr, uda.
Example:
pinmux: pinmux {
compatible = "nvidia,tegra114-pinmux";
reg = <0x70000868 0x148 /* Pad control registers */
0x70003000 0x40c>; /* PinMux registers */
};
Example board file extract:
pinctrl {
sdmmc4_default: pinmux {
sdmmc4_clk_pcc4 {
nvidia,pins = "sdmmc4_clk_pcc4",
nvidia,function = "sdmmc4";
nvidia,pull = <0>;
nvidia,tristate = <0>;
};
sdmmc4_dat0_paa0 {
nvidia,pins = "sdmmc4_dat0_paa0",
"sdmmc4_dat1_paa1",
"sdmmc4_dat2_paa2",
"sdmmc4_dat3_paa3",
"sdmmc4_dat4_paa4",
"sdmmc4_dat5_paa5",
"sdmmc4_dat6_paa6",
"sdmmc4_dat7_paa7";
nvidia,function = "sdmmc4";
nvidia,pull = <2>;
nvidia,tristate = <0>;
};
};
};
sdhci@78000400 {
pinctrl-names = "default";
pinctrl-0 = <&sdmmc4_default>;
};

View File

@ -0,0 +1,140 @@
ST Ericsson Nomadik pinmux controller
Required properties:
- compatible: "stericsson,nmk-pinctrl", "stericsson,nmk-pinctrl-db8540",
"stericsson,nmk-pinctrl-stn8815"
- reg: Should contain the register physical address and length of the PRCMU.
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".
ST Ericsson'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 input, output, pull up, pull down...
The name of each subnode is not important; all subnodes should be enumerated
and processed purely based on their content.
Required subnode-properties:
- ste,pins : An array of strings. Each string contains the name of a pin or
group.
Optional subnode-properties:
- ste,function: A string containing the name of the function to mux to the
pin or group.
- ste,config: Handle of pin configuration node (e.g. ste,config = <&slpm_in_wkup_pdis>)
- ste,input : <0/1/2>
0: input with no pull
1: input with pull up,
2: input with pull down,
- ste,output: <0/1/2>
0: output low,
1: output high,
2: output (value is not specified).
- ste,sleep: <0/1>
0: sleep mode disable,
1: sleep mode enable.
- ste,sleep-input: <0/1/2/3>
0: sleep input with no pull,
1: sleep input with pull up,
2: sleep input with pull down.
3: sleep input and keep last input configuration (no pull, pull up or pull down).
- ste,sleep-output: <0/1/2>
0: sleep output low,
1: sleep output high,
2: sleep output (value is not specified).
- ste,sleep-gpio: <0/1>
0: disable sleep gpio mode,
1: enable sleep gpio mode.
- ste,sleep-wakeup: <0/1>
0: wake-up detection enabled,
1: wake-up detection disabled.
- ste,sleep-pull-disable: <0/1>
0: GPIO pull-up or pull-down resistor is enabled, when pin is an input,
1: GPIO pull-up and pull-down resistor are disabled.
Example board file extract:
pinctrl@80157000 {
compatible = "stericsson,nmk-pinctrl";
reg = <0x80157000 0x2000>;
pinctrl-names = "default";
slpm_in_wkup_pdis: slpm_in_wkup_pdis {
ste,sleep = <1>;
ste,sleep-input = <3>;
ste,sleep-wakeup = <1>;
ste,sleep-pull-disable = <0>;
};
slpm_out_hi_wkup_pdis: slpm_out_hi_wkup_pdis {
ste,sleep = <1>;
ste,sleep-output = <1>;
ste,sleep-wakeup = <1>;
ste,sleep-pull-disable = <0>;
};
slpm_out_wkup_pdis: slpm_out_wkup_pdis {
ste,sleep = <1>;
ste,sleep-output = <2>;
ste,sleep-wakeup = <1>;
ste,sleep-pull-disable = <0>;
};
uart0 {
uart0_default_mux: uart0_mux {
u0_default_mux {
ste,function = "u0";
ste,pins = "u0_a_1";
};
};
uart0_default_mode: uart0_default {
uart0_default_cfg1 {
ste,pins = "GPIO0", "GPIO2";
ste,input = <1>;
};
uart0_default_cfg2 {
ste,pins = "GPIO1", "GPIO3";
ste,output = <1>;
};
};
uart0_sleep_mode: uart0_sleep {
uart0_sleep_cfg1 {
ste,pins = "GPIO0", "GPIO2";
ste,config = <&slpm_in_wkup_pdis>;
};
uart0_sleep_cfg2 {
ste,pins = "GPIO1";
ste,config = <&slpm_out_hi_wkup_pdis>;
};
uart0_sleep_cfg3 {
ste,pins = "GPIO3";
ste,config = <&slpm_out_wkup_pdis>;
};
};
};
};
uart@80120000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x80120000 0x1000>;
interrupts = <0 11 0x4>;
pinctrl-names = "default","sleep";
pinctrl-0 = <&uart0_default_mux>, <&uart0_default_mode>;
pinctrl-1 = <&uart0_sleep_mode>;
};

View File

@ -50,6 +50,7 @@ simtek
sirf SiRF Technology, Inc.
snps Synopsys, Inc.
st STMicroelectronics
ste ST-Ericsson
stericsson ST-Ericsson
ti Texas Instruments
via VIA Technologies, Inc.

View File

@ -972,6 +972,18 @@ pinmux core.
Pin control requests from drivers
=================================
When a device driver is about to probe the device core will automatically
attempt to issue pinctrl_get_select_default() on these devices.
This way driver writers do not need to add any of the boilerplate code
of the type found below. However when doing fine-grained state selection
and not using the "default" state, you may have to do some device driver
handling of the pinctrl handles and states.
So if you just want to put the pins for a certain device into the default
state and be done with it, there is nothing you need to do besides
providing the proper mapping table. The device core will take care of
the rest.
Generally it is discouraged to let individual drivers get and enable pin
control. So if possible, handle the pin control in platform code or some other
place where you have access to all the affected struct device * pointers. In
@ -1097,9 +1109,9 @@ situations that can be electrically unpleasant, you will certainly want to
mux in and bias pins in a certain way before the GPIO subsystems starts to
deal with them.
The above can be hidden: using pinctrl hogs, the pin control driver may be
setting up the config and muxing for the pins when it is probing,
nevertheless orthogonal to the GPIO subsystem.
The above can be hidden: using the device core, the pinctrl core may be
setting up the config and muxing for the pins right before the device is
probing, nevertheless orthogonal to the GPIO subsystem.
But there are also situations where it makes sense for the GPIO subsystem
to communicate directly with with the pinctrl subsystem, using the latter

View File

@ -1636,7 +1636,7 @@ config ARCH_NR_GPIO
default 355 if ARCH_U8500
default 264 if MACH_H4700
default 512 if SOC_OMAP5
default 288 if ARCH_VT8500
default 288 if ARCH_VT8500 || ARCH_SUNXI
default 0
help
Maximum number of GPIOs in the system.

View File

@ -170,10 +170,9 @@
gpio-bank = <8>;
};
pinctrl@80157000 {
// This is actually the PRCMU base address
reg = <0x80157000 0x2000>;
compatible = "stericsson,nmk_pinctrl";
pinctrl {
compatible = "stericsson,nmk-pinctrl";
prcm = <&prcmu>;
};
usb@a03e0000 {
@ -190,9 +189,10 @@
interrupts = <0 25 0x4>;
};
prcmu@80157000 {
prcmu: prcmu@80157000 {
compatible = "stericsson,db8500-prcmu";
reg = <0x80157000 0x1000>;
reg-names = "prcmu";
interrupts = <0 47 0x4>;
#address-cells = <1>;
#size-cells = <1>;

View File

@ -16,4 +16,34 @@
memory {
reg = <0x40000000 0x80000000>;
};
soc {
pinctrl@01c20800 {
compatible = "allwinner,sun4i-a10-pinctrl";
reg = <0x01c20800 0x400>;
#address-cells = <1>;
#size-cells = <0>;
uart0_pins_a: uart0@0 {
allwinner,pins = "PB22", "PB23";
allwinner,function = "uart0";
allwinner,drive = <0>;
allwinner,pull = <0>;
};
uart0_pins_b: uart0@1 {
allwinner,pins = "PF2", "PF4";
allwinner,function = "uart0";
allwinner,drive = <0>;
allwinner,pull = <0>;
};
uart1_pins_a: uart1@0 {
allwinner,pins = "PA10", "PA11";
allwinner,function = "uart1";
allwinner,drive = <0>;
allwinner,pull = <0>;
};
};
};
};

View File

@ -24,6 +24,8 @@
soc {
uart1: uart@01c28400 {
pinctrl-names = "default";
pinctrl-0 = <&uart1_pins_b>;
status = "okay";
};
};

View File

@ -17,4 +17,27 @@
memory {
reg = <0x40000000 0x20000000>;
};
soc {
pinctrl@01c20800 {
compatible = "allwinner,sun5i-a13-pinctrl";
reg = <0x01c20800 0x400>;
#address-cells = <1>;
#size-cells = <0>;
uart1_pins_a: uart1@0 {
allwinner,pins = "PE10", "PE11";
allwinner,function = "uart1";
allwinner,drive = <0>;
allwinner,pull = <0>;
};
uart1_pins_b: uart1@1 {
allwinner,pins = "PG3", "PG4";
allwinner,function = "uart1";
allwinner,drive = <0>;
allwinner,pull = <0>;
};
};
};
};

View File

@ -7,3 +7,4 @@ config ARCH_SUNXI
select PINCTRL
select SPARSE_IRQ
select SUNXI_TIMER
select PINCTRL_SUNXI

View File

@ -11,6 +11,7 @@ config UX500_SOC_COMMON
select COMMON_CLK
select PINCTRL
select PINCTRL_NOMADIK
select PINCTRL_ABX500
select PL310_ERRATA_753970 if CACHE_PL310
config UX500_SOC_DB8500
@ -18,6 +19,11 @@ config UX500_SOC_DB8500
select CPU_FREQ_TABLE if CPU_FREQ
select MFD_DB8500_PRCMU
select PINCTRL_DB8500
select PINCTRL_DB8540
select PINCTRL_AB8500
select PINCTRL_AB8505
select PINCTRL_AB9540
select PINCTRL_AB8540
select REGULATOR
select REGULATOR_DB8500_PRCMU

View File

@ -90,26 +90,8 @@ static struct platform_device snowball_gpio_en_3v3_regulator_dev = {
},
};
static struct ab8500_gpio_platform_data ab8500_gpio_pdata = {
static struct abx500_gpio_platform_data ab8500_gpio_pdata = {
.gpio_base = MOP500_AB8500_PIN_GPIO(1),
.irq_base = MOP500_AB8500_VIR_GPIO_IRQ_BASE,
/* config_reg is the initial configuration of ab8500 pins.
* The pins can be configured as GPIO or alt functions based
* on value present in GpioSel1 to GpioSel6 and AlternatFunction
* register. This is the array of 7 configuration settings.
* One has to compile time decide these settings. Below is the
* explanation of these setting
* GpioSel1 = 0x00 => Pins GPIO1 to GPIO8 are not used as GPIO
* GpioSel2 = 0x1E => Pins GPIO10 to GPIO13 are configured as GPIO
* GpioSel3 = 0x80 => Pin GPIO24 is configured as GPIO
* GpioSel4 = 0x01 => Pin GPIo25 is configured as GPIO
* GpioSel5 = 0x7A => Pins GPIO34, GPIO36 to GPIO39 are conf as GPIO
* GpioSel6 = 0x00 => Pins GPIO41 & GPIo42 are not configured as GPIO
* AlternaFunction = 0x00 => If Pins GPIO10 to 13 are not configured
* as GPIO then this register selectes the alternate fucntions
*/
.config_reg = {0x00, 0x1E, 0x80, 0x01,
0x7A, 0x00, 0x00},
};
/* ab8500-codec */

View File

@ -285,7 +285,7 @@ static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("st,nomadik-i2c", 0x80110000, "nmk-i2c.3", NULL),
OF_DEV_AUXDATA("st,nomadik-i2c", 0x8012a000, "nmk-i2c.4", NULL),
/* Requires device name bindings. */
OF_DEV_AUXDATA("stericsson,nmk_pinctrl", U8500_PRCMU_BASE,
OF_DEV_AUXDATA("stericsson,nmk-pinctrl", U8500_PRCMU_BASE,
"pinctrl-db8500", NULL),
/* Requires clock name and DMA bindings. */
OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000,

View File

@ -38,15 +38,7 @@
#define MOP500_STMPE1601_IRQ_END \
MOP500_STMPE1601_IRQ(STMPE_NR_INTERNAL_IRQS)
/* AB8500 virtual gpio IRQ */
#define AB8500_VIR_GPIO_NR_IRQS 16
#define MOP500_AB8500_VIR_GPIO_IRQ_BASE \
MOP500_STMPE1601_IRQ_END
#define MOP500_AB8500_VIR_GPIO_IRQ_END \
(MOP500_AB8500_VIR_GPIO_IRQ_BASE + AB8500_VIR_GPIO_NR_IRQS)
#define MOP500_NR_IRQS MOP500_AB8500_VIR_GPIO_IRQ_END
#define MOP500_NR_IRQS MOP500_STMPE1601_IRQ_END
#define MOP500_IRQ_END MOP500_NR_IRQS

View File

@ -21,6 +21,7 @@ endif
obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
obj-$(CONFIG_REGMAP) += regmap/
obj-$(CONFIG_SOC_BUS) += soc.o
obj-$(CONFIG_PINCTRL) += pinctrl.o
ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG

View File

@ -24,6 +24,7 @@
#include <linux/wait.h>
#include <linux/async.h>
#include <linux/pm_runtime.h>
#include <linux/pinctrl/devinfo.h>
#include "base.h"
#include "power/power.h"
@ -269,6 +270,12 @@ static int really_probe(struct device *dev, struct device_driver *drv)
WARN_ON(!list_empty(&dev->devres_head));
dev->driver = drv;
/* If using pinctrl, bind pins now before probing */
ret = pinctrl_bind_pins(dev);
if (ret)
goto probe_failed;
if (driver_sysfs_add(dev)) {
printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
__func__, dev_name(dev));

View File

@ -0,0 +1,69 @@
/*
* Driver core interface to the pinctrl subsystem.
*
* Copyright (C) 2012 ST-Ericsson SA
* Written on behalf of Linaro for ST-Ericsson
* Based on bits of regulator core, gpio core and clk core
*
* Author: Linus Walleij <linus.walleij@linaro.org>
*
* License terms: GNU General Public License (GPL) version 2
*/
#include <linux/device.h>
#include <linux/pinctrl/devinfo.h>
#include <linux/pinctrl/consumer.h>
#include <linux/slab.h>
/**
* pinctrl_bind_pins() - called by the device core before probe
* @dev: the device that is just about to probe
*/
int pinctrl_bind_pins(struct device *dev)
{
int ret;
dev->pins = devm_kzalloc(dev, sizeof(*(dev->pins)), GFP_KERNEL);
if (!dev->pins)
return -ENOMEM;
dev->pins->p = devm_pinctrl_get(dev);
if (IS_ERR(dev->pins->p)) {
dev_dbg(dev, "no pinctrl handle\n");
ret = PTR_ERR(dev->pins->p);
goto cleanup_alloc;
}
dev->pins->default_state = pinctrl_lookup_state(dev->pins->p,
PINCTRL_STATE_DEFAULT);
if (IS_ERR(dev->pins->default_state)) {
dev_dbg(dev, "no default pinctrl state\n");
ret = 0;
goto cleanup_get;
}
ret = pinctrl_select_state(dev->pins->p, dev->pins->default_state);
if (ret) {
dev_dbg(dev, "failed to activate default pinctrl state\n");
goto cleanup_get;
}
return 0;
/*
* If no pinctrl handle or default state was found for this device,
* let's explicitly free the pin container in the device, there is
* no point in keeping it around.
*/
cleanup_get:
devm_pinctrl_put(dev->pins->p);
cleanup_alloc:
devm_kfree(dev, dev->pins);
dev->pins = NULL;
/* Only return deferrals */
if (ret != -EPROBE_DEFER)
ret = 0;
return ret;
}

View File

@ -657,12 +657,6 @@ config GPIO_JANZ_TTL
This driver provides support for driving the pins in output
mode only. Input mode is not supported.
config GPIO_AB8500
bool "ST-Ericsson AB8500 Mixed Signal Circuit gpio functions"
depends on AB8500_CORE && BROKEN
help
Select this to enable the AB8500 IC GPIO driver
config GPIO_TPS6586X
bool "TPS6586X GPIO"
depends on MFD_TPS6586X

View File

@ -10,7 +10,6 @@ obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o
obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o
obj-$(CONFIG_GPIO_AB8500) += gpio-ab8500.o
obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o
obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o
obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o

View File

@ -1,520 +0,0 @@
/*
* Copyright (C) ST-Ericsson SA 2011
*
* Author: BIBEK BASU <bibek.basu@stericsson.com>
* License terms: GNU General Public License (GPL) version 2
*
* 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/kernel.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/mfd/ab8500.h>
#include <linux/mfd/abx500.h>
#include <linux/mfd/ab8500/gpio.h>
/*
* GPIO registers offset
* Bank: 0x10
*/
#define AB8500_GPIO_SEL1_REG 0x00
#define AB8500_GPIO_SEL2_REG 0x01
#define AB8500_GPIO_SEL3_REG 0x02
#define AB8500_GPIO_SEL4_REG 0x03
#define AB8500_GPIO_SEL5_REG 0x04
#define AB8500_GPIO_SEL6_REG 0x05
#define AB8500_GPIO_DIR1_REG 0x10
#define AB8500_GPIO_DIR2_REG 0x11
#define AB8500_GPIO_DIR3_REG 0x12
#define AB8500_GPIO_DIR4_REG 0x13
#define AB8500_GPIO_DIR5_REG 0x14
#define AB8500_GPIO_DIR6_REG 0x15
#define AB8500_GPIO_OUT1_REG 0x20
#define AB8500_GPIO_OUT2_REG 0x21
#define AB8500_GPIO_OUT3_REG 0x22
#define AB8500_GPIO_OUT4_REG 0x23
#define AB8500_GPIO_OUT5_REG 0x24
#define AB8500_GPIO_OUT6_REG 0x25
#define AB8500_GPIO_PUD1_REG 0x30
#define AB8500_GPIO_PUD2_REG 0x31
#define AB8500_GPIO_PUD3_REG 0x32
#define AB8500_GPIO_PUD4_REG 0x33
#define AB8500_GPIO_PUD5_REG 0x34
#define AB8500_GPIO_PUD6_REG 0x35
#define AB8500_GPIO_IN1_REG 0x40
#define AB8500_GPIO_IN2_REG 0x41
#define AB8500_GPIO_IN3_REG 0x42
#define AB8500_GPIO_IN4_REG 0x43
#define AB8500_GPIO_IN5_REG 0x44
#define AB8500_GPIO_IN6_REG 0x45
#define AB8500_GPIO_ALTFUN_REG 0x45
#define ALTFUN_REG_INDEX 6
#define AB8500_NUM_GPIO 42
#define AB8500_NUM_VIR_GPIO_IRQ 16
enum ab8500_gpio_action {
NONE,
STARTUP,
SHUTDOWN,
MASK,
UNMASK
};
struct ab8500_gpio {
struct gpio_chip chip;
struct ab8500 *parent;
struct device *dev;
struct mutex lock;
u32 irq_base;
enum ab8500_gpio_action irq_action;
u16 rising;
u16 falling;
};
/**
* to_ab8500_gpio() - get the pointer to ab8500_gpio
* @chip: Member of the structure ab8500_gpio
*/
static inline struct ab8500_gpio *to_ab8500_gpio(struct gpio_chip *chip)
{
return container_of(chip, struct ab8500_gpio, chip);
}
static int ab8500_gpio_set_bits(struct gpio_chip *chip, u8 reg,
unsigned offset, int val)
{
struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
u8 pos = offset % 8;
int ret;
reg = reg + (offset / 8);
ret = abx500_mask_and_set_register_interruptible(ab8500_gpio->dev,
AB8500_MISC, reg, 1 << pos, val << pos);
if (ret < 0)
dev_err(ab8500_gpio->dev, "%s write failed\n", __func__);
return ret;
}
/**
* ab8500_gpio_get() - Get the particular GPIO value
* @chip: Gpio device
* @offset: GPIO number to read
*/
static int ab8500_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
u8 mask = 1 << (offset % 8);
u8 reg = AB8500_GPIO_OUT1_REG + (offset / 8);
int ret;
u8 data;
ret = abx500_get_register_interruptible(ab8500_gpio->dev, AB8500_MISC,
reg, &data);
if (ret < 0) {
dev_err(ab8500_gpio->dev, "%s read failed\n", __func__);
return ret;
}
return (data & mask) >> (offset % 8);
}
static void ab8500_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
{
struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
int ret;
/* Write the data */
ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, 1);
if (ret < 0)
dev_err(ab8500_gpio->dev, "%s write failed\n", __func__);
}
static int ab8500_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
int val)
{
int ret;
/* set direction as output */
ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_DIR1_REG, offset, 1);
if (ret < 0)
return ret;
/* disable pull down */
ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_PUD1_REG, offset, 1);
if (ret < 0)
return ret;
/* set the output as 1 or 0 */
return ab8500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, val);
}
static int ab8500_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
/* set the register as input */
return ab8500_gpio_set_bits(chip, AB8500_GPIO_DIR1_REG, offset, 0);
}
static int ab8500_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
/*
* Only some GPIOs are interrupt capable, and they are
* organized in discontiguous clusters:
*
* GPIO6 to GPIO13
* GPIO24 and GPIO25
* GPIO36 to GPIO41
*/
static struct ab8500_gpio_irq_cluster {
int start;
int end;
} clusters[] = {
{.start = 6, .end = 13},
{.start = 24, .end = 25},
{.start = 36, .end = 41},
};
struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
int base = ab8500_gpio->irq_base;
int i;
for (i = 0; i < ARRAY_SIZE(clusters); i++) {
struct ab8500_gpio_irq_cluster *cluster = &clusters[i];
if (offset >= cluster->start && offset <= cluster->end)
return base + offset - cluster->start;
/* Advance by the number of gpios in this cluster */
base += cluster->end - cluster->start + 1;
}
return -EINVAL;
}
static struct gpio_chip ab8500gpio_chip = {
.label = "ab8500_gpio",
.owner = THIS_MODULE,
.direction_input = ab8500_gpio_direction_input,
.get = ab8500_gpio_get,
.direction_output = ab8500_gpio_direction_output,
.set = ab8500_gpio_set,
.to_irq = ab8500_gpio_to_irq,
};
static unsigned int irq_to_rising(unsigned int irq)
{
struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
int offset = irq - ab8500_gpio->irq_base;
int new_irq = offset + AB8500_INT_GPIO6R
+ ab8500_gpio->parent->irq_base;
return new_irq;
}
static unsigned int irq_to_falling(unsigned int irq)
{
struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
int offset = irq - ab8500_gpio->irq_base;
int new_irq = offset + AB8500_INT_GPIO6F
+ ab8500_gpio->parent->irq_base;
return new_irq;
}
static unsigned int rising_to_irq(unsigned int irq, void *dev)
{
struct ab8500_gpio *ab8500_gpio = dev;
int offset = irq - AB8500_INT_GPIO6R
- ab8500_gpio->parent->irq_base ;
int new_irq = offset + ab8500_gpio->irq_base;
return new_irq;
}
static unsigned int falling_to_irq(unsigned int irq, void *dev)
{
struct ab8500_gpio *ab8500_gpio = dev;
int offset = irq - AB8500_INT_GPIO6F
- ab8500_gpio->parent->irq_base ;
int new_irq = offset + ab8500_gpio->irq_base;
return new_irq;
}
/*
* IRQ handler
*/
static irqreturn_t handle_rising(int irq, void *dev)
{
handle_nested_irq(rising_to_irq(irq , dev));
return IRQ_HANDLED;
}
static irqreturn_t handle_falling(int irq, void *dev)
{
handle_nested_irq(falling_to_irq(irq, dev));
return IRQ_HANDLED;
}
static void ab8500_gpio_irq_lock(unsigned int irq)
{
struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
mutex_lock(&ab8500_gpio->lock);
}
static void ab8500_gpio_irq_sync_unlock(unsigned int irq)
{
struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
int offset = irq - ab8500_gpio->irq_base;
bool rising = ab8500_gpio->rising & BIT(offset);
bool falling = ab8500_gpio->falling & BIT(offset);
int ret;
switch (ab8500_gpio->irq_action) {
case STARTUP:
if (rising)
ret = request_threaded_irq(irq_to_rising(irq),
NULL, handle_rising,
IRQF_TRIGGER_RISING,
"ab8500-gpio-r", ab8500_gpio);
if (falling)
ret = request_threaded_irq(irq_to_falling(irq),
NULL, handle_falling,
IRQF_TRIGGER_FALLING,
"ab8500-gpio-f", ab8500_gpio);
break;
case SHUTDOWN:
if (rising)
free_irq(irq_to_rising(irq), ab8500_gpio);
if (falling)
free_irq(irq_to_falling(irq), ab8500_gpio);
break;
case MASK:
if (rising)
disable_irq(irq_to_rising(irq));
if (falling)
disable_irq(irq_to_falling(irq));
break;
case UNMASK:
if (rising)
enable_irq(irq_to_rising(irq));
if (falling)
enable_irq(irq_to_falling(irq));
break;
case NONE:
break;
}
ab8500_gpio->irq_action = NONE;
ab8500_gpio->rising &= ~(BIT(offset));
ab8500_gpio->falling &= ~(BIT(offset));
mutex_unlock(&ab8500_gpio->lock);
}
static void ab8500_gpio_irq_mask(unsigned int irq)
{
struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
ab8500_gpio->irq_action = MASK;
}
static void ab8500_gpio_irq_unmask(unsigned int irq)
{
struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
ab8500_gpio->irq_action = UNMASK;
}
static int ab8500_gpio_irq_set_type(unsigned int irq, unsigned int type)
{
struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
int offset = irq - ab8500_gpio->irq_base;
if (type == IRQ_TYPE_EDGE_BOTH) {
ab8500_gpio->rising = BIT(offset);
ab8500_gpio->falling = BIT(offset);
} else if (type == IRQ_TYPE_EDGE_RISING) {
ab8500_gpio->rising = BIT(offset);
} else {
ab8500_gpio->falling = BIT(offset);
}
return 0;
}
unsigned int ab8500_gpio_irq_startup(unsigned int irq)
{
struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
ab8500_gpio->irq_action = STARTUP;
return 0;
}
void ab8500_gpio_irq_shutdown(unsigned int irq)
{
struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
ab8500_gpio->irq_action = SHUTDOWN;
}
static struct irq_chip ab8500_gpio_irq_chip = {
.name = "ab8500-gpio",
.startup = ab8500_gpio_irq_startup,
.shutdown = ab8500_gpio_irq_shutdown,
.bus_lock = ab8500_gpio_irq_lock,
.bus_sync_unlock = ab8500_gpio_irq_sync_unlock,
.mask = ab8500_gpio_irq_mask,
.unmask = ab8500_gpio_irq_unmask,
.set_type = ab8500_gpio_irq_set_type,
};
static int ab8500_gpio_irq_init(struct ab8500_gpio *ab8500_gpio)
{
u32 base = ab8500_gpio->irq_base;
int irq;
for (irq = base; irq < base + AB8500_NUM_VIR_GPIO_IRQ ; irq++) {
set_irq_chip_data(irq, ab8500_gpio);
set_irq_chip_and_handler(irq, &ab8500_gpio_irq_chip,
handle_simple_irq);
set_irq_nested_thread(irq, 1);
#ifdef CONFIG_ARM
set_irq_flags(irq, IRQF_VALID);
#else
set_irq_noprobe(irq);
#endif
}
return 0;
}
static void ab8500_gpio_irq_remove(struct ab8500_gpio *ab8500_gpio)
{
int base = ab8500_gpio->irq_base;
int irq;
for (irq = base; irq < base + AB8500_NUM_VIR_GPIO_IRQ; irq++) {
#ifdef CONFIG_ARM
set_irq_flags(irq, 0);
#endif
set_irq_chip_and_handler(irq, NULL, NULL);
set_irq_chip_data(irq, NULL);
}
}
static int ab8500_gpio_probe(struct platform_device *pdev)
{
struct ab8500_platform_data *ab8500_pdata =
dev_get_platdata(pdev->dev.parent);
struct ab8500_gpio_platform_data *pdata;
struct ab8500_gpio *ab8500_gpio;
int ret;
int i;
pdata = ab8500_pdata->gpio;
if (!pdata) {
dev_err(&pdev->dev, "gpio platform data missing\n");
return -ENODEV;
}
ab8500_gpio = kzalloc(sizeof(struct ab8500_gpio), GFP_KERNEL);
if (ab8500_gpio == NULL) {
dev_err(&pdev->dev, "failed to allocate memory\n");
return -ENOMEM;
}
ab8500_gpio->dev = &pdev->dev;
ab8500_gpio->parent = dev_get_drvdata(pdev->dev.parent);
ab8500_gpio->chip = ab8500gpio_chip;
ab8500_gpio->chip.ngpio = AB8500_NUM_GPIO;
ab8500_gpio->chip.dev = &pdev->dev;
ab8500_gpio->chip.base = pdata->gpio_base;
ab8500_gpio->irq_base = pdata->irq_base;
/* initialize the lock */
mutex_init(&ab8500_gpio->lock);
/*
* AB8500 core will handle and clear the IRQ
* configre GPIO based on config-reg value.
* These values are for selecting the PINs as
* GPIO or alternate function
*/
for (i = AB8500_GPIO_SEL1_REG; i <= AB8500_GPIO_SEL6_REG; i++) {
ret = abx500_set_register_interruptible(ab8500_gpio->dev,
AB8500_MISC, i,
pdata->config_reg[i]);
if (ret < 0)
goto out_free;
}
ret = abx500_set_register_interruptible(ab8500_gpio->dev, AB8500_MISC,
AB8500_GPIO_ALTFUN_REG,
pdata->config_reg[ALTFUN_REG_INDEX]);
if (ret < 0)
goto out_free;
ret = ab8500_gpio_irq_init(ab8500_gpio);
if (ret)
goto out_free;
ret = gpiochip_add(&ab8500_gpio->chip);
if (ret) {
dev_err(&pdev->dev, "unable to add gpiochip: %d\n",
ret);
goto out_rem_irq;
}
platform_set_drvdata(pdev, ab8500_gpio);
return 0;
out_rem_irq:
ab8500_gpio_irq_remove(ab8500_gpio);
out_free:
mutex_destroy(&ab8500_gpio->lock);
kfree(ab8500_gpio);
return ret;
}
/*
* ab8500_gpio_remove() - remove Ab8500-gpio driver
* @pdev : Platform device registered
*/
static int ab8500_gpio_remove(struct platform_device *pdev)
{
struct ab8500_gpio *ab8500_gpio = platform_get_drvdata(pdev);
int ret;
ret = gpiochip_remove(&ab8500_gpio->chip);
if (ret < 0) {
dev_err(ab8500_gpio->dev, "unable to remove gpiochip: %d\n",
ret);
return ret;
}
platform_set_drvdata(pdev, NULL);
mutex_destroy(&ab8500_gpio->lock);
kfree(ab8500_gpio);
return 0;
}
static struct platform_driver ab8500_gpio_driver = {
.driver = {
.name = "ab8500-gpio",
.owner = THIS_MODULE,
},
.probe = ab8500_gpio_probe,
.remove = ab8500_gpio_remove,
};
static int __init ab8500_gpio_init(void)
{
return platform_driver_register(&ab8500_gpio_driver);
}
arch_initcall(ab8500_gpio_init);
static void __exit ab8500_gpio_exit(void)
{
platform_driver_unregister(&ab8500_gpio_driver);
}
module_exit(ab8500_gpio_exit);
MODULE_AUTHOR("BIBEK BASU <bibek.basu@stericsson.com>");
MODULE_DESCRIPTION("Driver allows to use AB8500 unused pins to be used as GPIO");
MODULE_ALIAS("platform:ab8500-gpio");
MODULE_LICENSE("GPL v2");

View File

@ -250,7 +250,7 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
* on the same GPIO chip.
*/
ret = gpiochip_add_pin_range(chip,
pinctrl_dev_get_name(pctldev),
pinctrl_dev_get_devname(pctldev),
0, /* offset in gpiochip */
pinspec.args[0],
pinspec.args[1]);

View File

@ -26,6 +26,29 @@ config DEBUG_PINCTRL
help
Say Y here to add some extra checks and diagnostics to PINCTRL calls.
config PINCTRL_ABX500
bool "ST-Ericsson ABx500 family Mixed Signal Circuit gpio functions"
depends on AB8500_CORE
select GENERIC_PINCONF
help
Select this to enable the ABx500 family IC GPIO driver
config PINCTRL_AB8500
bool "AB8500 pin controller driver"
depends on PINCTRL_ABX500 && ARCH_U8500
config PINCTRL_AB8540
bool "AB8540 pin controller driver"
depends on PINCTRL_ABX500 && ARCH_U8500
config PINCTRL_AB9540
bool "AB9540 pin controller driver"
depends on PINCTRL_ABX500 && ARCH_U8500
config PINCTRL_AB8505
bool "AB8505 pin controller driver"
depends on PINCTRL_ABX500 && ARCH_U8500
config PINCTRL_AT91
bool "AT91 pinctrl driver"
depends on OF
@ -151,6 +174,11 @@ config PINCTRL_SIRF
depends on ARCH_SIRF
select PINMUX
config PINCTRL_SUNXI
bool
select PINMUX
select GENERIC_PINCONF
config PINCTRL_TEGRA
bool
select PINMUX
@ -164,6 +192,10 @@ config PINCTRL_TEGRA30
bool
select PINCTRL_TEGRA
config PINCTRL_TEGRA114
bool
select PINCTRL_TEGRA
config PINCTRL_U300
bool "U300 pin controller driver"
depends on ARCH_U300

View File

@ -9,6 +9,11 @@ ifeq ($(CONFIG_OF),y)
obj-$(CONFIG_PINCTRL) += devicetree.o
endif
obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o
obj-$(CONFIG_PINCTRL_ABX500) += pinctrl-abx500.o
obj-$(CONFIG_PINCTRL_AB8500) += pinctrl-ab8500.o
obj-$(CONFIG_PINCTRL_AB8540) += pinctrl-ab8540.o
obj-$(CONFIG_PINCTRL_AB9540) += pinctrl-ab9540.o
obj-$(CONFIG_PINCTRL_AB8505) += pinctrl-ab8505.o
obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o
obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o
@ -30,9 +35,11 @@ obj-$(CONFIG_PINCTRL_PXA168) += pinctrl-pxa168.o
obj-$(CONFIG_PINCTRL_PXA910) += pinctrl-pxa910.o
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
obj-$(CONFIG_PINCTRL_SIRF) += pinctrl-sirf.o
obj-$(CONFIG_PINCTRL_SUNXI) += pinctrl-sunxi.o
obj-$(CONFIG_PINCTRL_TEGRA) += pinctrl-tegra.o
obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o
obj-$(CONFIG_PINCTRL_TEGRA114) += pinctrl-tegra114.o
obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o
obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o
obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o

View File

@ -14,6 +14,7 @@
#define pr_fmt(fmt) "pinctrl core: " fmt
#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/export.h>
#include <linux/init.h>
#include <linux/device.h>
@ -31,17 +32,6 @@
#include "pinmux.h"
#include "pinconf.h"
/**
* struct pinctrl_maps - a list item containing part of the mapping table
* @node: mapping table list node
* @maps: array of mapping table entries
* @num_maps: the number of entries in @maps
*/
struct pinctrl_maps {
struct list_head node;
struct pinctrl_map const *maps;
unsigned num_maps;
};
static bool pinctrl_dummy_state;
@ -55,13 +45,8 @@ LIST_HEAD(pinctrldev_list);
static LIST_HEAD(pinctrl_list);
/* List of pinctrl maps (struct pinctrl_maps) */
static LIST_HEAD(pinctrl_maps);
LIST_HEAD(pinctrl_maps);
#define for_each_maps(_maps_node_, _i_, _map_) \
list_for_each_entry(_maps_node_, &pinctrl_maps, node) \
for (_i_ = 0, _map_ = &_maps_node_->maps[_i_]; \
_i_ < _maps_node_->num_maps; \
_i_++, _map_ = &_maps_node_->maps[_i_])
/**
* pinctrl_provide_dummies() - indicate if pinctrl provides dummy state support
@ -83,6 +68,12 @@ const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev)
}
EXPORT_SYMBOL_GPL(pinctrl_dev_get_name);
const char *pinctrl_dev_get_devname(struct pinctrl_dev *pctldev)
{
return dev_name(pctldev->dev);
}
EXPORT_SYMBOL_GPL(pinctrl_dev_get_devname);
void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev)
{
return pctldev->driver_data;
@ -609,13 +600,16 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map)
setting->pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name);
if (setting->pctldev == NULL) {
dev_info(p->dev, "unknown pinctrl device %s in map entry, deferring probe",
map->ctrl_dev_name);
kfree(setting);
/* Do not defer probing of hogs (circular loop) */
if (!strcmp(map->ctrl_dev_name, map->dev_name))
return -ENODEV;
/*
* OK let us guess that the driver is not there yet, and
* let's defer obtaining this pinctrl handle to later...
*/
dev_info(p->dev, "unknown pinctrl device %s in map entry, deferring probe",
map->ctrl_dev_name);
return -EPROBE_DEFER;
}
@ -694,11 +688,31 @@ static struct pinctrl *create_pinctrl(struct device *dev)
continue;
ret = add_setting(p, map);
if (ret < 0) {
/*
* At this point the adding of a setting may:
*
* - Defer, if the pinctrl device is not yet available
* - Fail, if the pinctrl device is not yet available,
* AND the setting is a hog. We cannot defer that, since
* the hog will kick in immediately after the device
* is registered.
*
* If the error returned was not -EPROBE_DEFER then we
* accumulate the errors to see if we end up with
* an -EPROBE_DEFER later, as that is the worst case.
*/
if (ret == -EPROBE_DEFER) {
pinctrl_put_locked(p, false);
return ERR_PTR(ret);
}
}
if (ret < 0) {
/* If some other error than deferral occured, return here */
pinctrl_put_locked(p, false);
return ERR_PTR(ret);
}
kref_init(&p->users);
/* Add the pinctrl handle to the global list */
list_add_tail(&p->node, &pinctrl_list);
@ -713,9 +727,17 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev)
if (WARN_ON(!dev))
return ERR_PTR(-EINVAL);
/*
* See if somebody else (such as the device core) has already
* obtained a handle to the pinctrl for this device. In that case,
* return another pointer to it.
*/
p = find_pinctrl(dev);
if (p != NULL)
return ERR_PTR(-EBUSY);
if (p != NULL) {
dev_dbg(dev, "obtain a copy of previously claimed pinctrl\n");
kref_get(&p->users);
return p;
}
return create_pinctrl(dev);
}
@ -771,13 +793,24 @@ static void pinctrl_put_locked(struct pinctrl *p, bool inlist)
}
/**
* pinctrl_put() - release a previously claimed pinctrl handle
* pinctrl_release() - release the pinctrl handle
* @kref: the kref in the pinctrl being released
*/
static void pinctrl_release(struct kref *kref)
{
struct pinctrl *p = container_of(kref, struct pinctrl, users);
pinctrl_put_locked(p, true);
}
/**
* pinctrl_put() - decrease use count on a previously claimed pinctrl handle
* @p: the pinctrl handle to release
*/
void pinctrl_put(struct pinctrl *p)
{
mutex_lock(&pinctrl_mutex);
pinctrl_put_locked(p, true);
kref_put(&p->users, pinctrl_release);
mutex_unlock(&pinctrl_mutex);
}
EXPORT_SYMBOL_GPL(pinctrl_put);
@ -1055,6 +1088,30 @@ void pinctrl_unregister_map(struct pinctrl_map const *map)
}
}
/**
* pinctrl_force_sleep() - turn a given controller device into sleep state
* @pctldev: pin controller device
*/
int pinctrl_force_sleep(struct pinctrl_dev *pctldev)
{
if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_sleep))
return pinctrl_select_state(pctldev->p, pctldev->hog_sleep);
return 0;
}
EXPORT_SYMBOL_GPL(pinctrl_force_sleep);
/**
* pinctrl_force_default() - turn a given controller device into default state
* @pctldev: pin controller device
*/
int pinctrl_force_default(struct pinctrl_dev *pctldev)
{
if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_default))
return pinctrl_select_state(pctldev->p, pctldev->hog_default);
return 0;
}
EXPORT_SYMBOL_GPL(pinctrl_force_default);
#ifdef CONFIG_DEBUG_FS
static int pinctrl_pins_show(struct seq_file *s, void *what)
@ -1500,16 +1557,23 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
pctldev->p = pinctrl_get_locked(pctldev->dev);
if (!IS_ERR(pctldev->p)) {
struct pinctrl_state *s =
pctldev->hog_default =
pinctrl_lookup_state_locked(pctldev->p,
PINCTRL_STATE_DEFAULT);
if (IS_ERR(s)) {
if (IS_ERR(pctldev->hog_default)) {
dev_dbg(dev, "failed to lookup the default state\n");
} else {
if (pinctrl_select_state_locked(pctldev->p, s))
if (pinctrl_select_state_locked(pctldev->p,
pctldev->hog_default))
dev_err(dev,
"failed to select default state\n");
}
pctldev->hog_sleep =
pinctrl_lookup_state_locked(pctldev->p,
PINCTRL_STATE_SLEEP);
if (IS_ERR(pctldev->hog_sleep))
dev_dbg(dev, "failed to lookup the sleep state\n");
}
mutex_unlock(&pinctrl_mutex);

View File

@ -9,6 +9,7 @@
* License terms: GNU General Public License (GPL) version 2
*/
#include <linux/kref.h>
#include <linux/mutex.h>
#include <linux/radix-tree.h>
#include <linux/pinctrl/pinconf.h>
@ -30,6 +31,8 @@ struct pinctrl_gpio_range;
* @driver_data: driver data for drivers registering to the pin controller
* subsystem
* @p: result of pinctrl_get() for this device
* @hog_default: default state for pins hogged by this device
* @hog_sleep: sleep state for pins hogged by this device
* @device_root: debugfs root for this device
*/
struct pinctrl_dev {
@ -41,6 +44,8 @@ struct pinctrl_dev {
struct module *owner;
void *driver_data;
struct pinctrl *p;
struct pinctrl_state *hog_default;
struct pinctrl_state *hog_sleep;
#ifdef CONFIG_DEBUG_FS
struct dentry *device_root;
#endif
@ -54,6 +59,7 @@ struct pinctrl_dev {
* @state: the current state
* @dt_maps: the mapping table chunks dynamically parsed from device tree for
* this device, if any
* @users: reference count
*/
struct pinctrl {
struct list_head node;
@ -61,6 +67,7 @@ struct pinctrl {
struct list_head states;
struct pinctrl_state *state;
struct list_head dt_maps;
struct kref users;
};
/**
@ -148,6 +155,18 @@ struct pin_desc {
#endif
};
/**
* struct pinctrl_maps - a list item containing part of the mapping table
* @node: mapping table list node
* @maps: array of mapping table entries
* @num_maps: the number of entries in @maps
*/
struct pinctrl_maps {
struct list_head node;
struct pinctrl_map const *maps;
unsigned num_maps;
};
struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name);
int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name);
const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin);
@ -164,5 +183,15 @@ int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps,
bool dup, bool locked);
void pinctrl_unregister_map(struct pinctrl_map const *map);
extern int pinctrl_force_sleep(struct pinctrl_dev *pctldev);
extern int pinctrl_force_default(struct pinctrl_dev *pctldev);
extern struct mutex pinctrl_mutex;
extern struct list_head pinctrldev_list;
extern struct list_head pinctrl_maps;
#define for_each_maps(_maps_node_, _i_, _map_) \
list_for_each_entry(_maps_node_, &pinctrl_maps, node) \
for (_i_ = 0, _map_ = &_maps_node_->maps[_i_]; \
_i_ < _maps_node_->num_maps; \
_i_++, _map_ = &_maps_node_->maps[_i_])

View File

@ -141,6 +141,11 @@ static int dt_to_map_one_config(struct pinctrl *p, const char *statename,
pctldev = find_pinctrl_by_of_node(np_pctldev);
if (pctldev)
break;
/* Do not defer probing of hogs (circular loop) */
if (np_pctldev == p->dev->of_node) {
of_node_put(np_pctldev);
return -ENODEV;
}
}
of_node_put(np_pctldev);

View File

@ -41,11 +41,13 @@ struct pin_config_item conf_items[] = {
PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL),
PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL),
PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL),
PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_DISABLE, "input schmitt disabled", NULL),
PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_ENABLE, "input schmitt enabled", NULL),
PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL),
PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "time units"),
PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector"),
PCONFDUMP(PIN_CONFIG_SLEW_RATE, "slew rate", NULL),
PCONFDUMP(PIN_CONFIG_LOW_POWER_MODE, "pin low power", "mode"),
PCONFDUMP(PIN_CONFIG_OUTPUT, "pin output", "level"),
};
void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev,

View File

@ -574,6 +574,207 @@ static const struct file_operations pinconf_groups_ops = {
.release = single_release,
};
/* 32bit read/write ressources */
#define MAX_NAME_LEN 16
char dbg_pinname[MAX_NAME_LEN]; /* shared: name of the state of the pin*/
char dbg_state_name[MAX_NAME_LEN]; /* shared: state of the pin*/
static u32 dbg_config; /* shared: config to be read/set for the pin & state*/
static int pinconf_dbg_pinname_print(struct seq_file *s, void *d)
{
if (strlen(dbg_pinname))
seq_printf(s, "%s\n", dbg_pinname);
else
seq_printf(s, "No pin name set\n");
return 0;
}
static int pinconf_dbg_pinname_open(struct inode *inode, struct file *file)
{
return single_open(file, pinconf_dbg_pinname_print, inode->i_private);
}
static int pinconf_dbg_pinname_write(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos)
{
int err;
if (count > MAX_NAME_LEN)
return -EINVAL;
err = sscanf(user_buf, "%15s", dbg_pinname);
if (err != 1)
return -EINVAL;
return count;
}
static const struct file_operations pinconf_dbg_pinname_fops = {
.open = pinconf_dbg_pinname_open,
.write = pinconf_dbg_pinname_write,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.owner = THIS_MODULE,
};
static int pinconf_dbg_state_print(struct seq_file *s, void *d)
{
if (strlen(dbg_state_name))
seq_printf(s, "%s\n", dbg_pinname);
else
seq_printf(s, "No pin state set\n");
return 0;
}
static int pinconf_dbg_state_open(struct inode *inode, struct file *file)
{
return single_open(file, pinconf_dbg_state_print, inode->i_private);
}
static int pinconf_dbg_state_write(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos)
{
int err;
if (count > MAX_NAME_LEN)
return -EINVAL;
err = sscanf(user_buf, "%15s", dbg_state_name);
if (err != 1)
return -EINVAL;
return count;
}
static const struct file_operations pinconf_dbg_pinstate_fops = {
.open = pinconf_dbg_state_open,
.write = pinconf_dbg_state_write,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.owner = THIS_MODULE,
};
/**
* pinconf_dbg_config_print() - display the pinctrl config from the pinctrl
* map, of a pin/state pair based on pinname and state that have been
* selected with the debugfs entries pinconf-name and pinconf-state
* @s: contains the 32bits config to be written
* @d: not used
*/
static int pinconf_dbg_config_print(struct seq_file *s, void *d)
{
struct pinctrl_maps *maps_node;
struct pinctrl_map const *map;
struct pinctrl_dev *pctldev = NULL;
struct pinconf_ops *confops = NULL;
int i, j;
bool found = false;
mutex_lock(&pinctrl_mutex);
/* Parse the pinctrl map and look for the elected pin/state */
for_each_maps(maps_node, i, map) {
if (map->type != PIN_MAP_TYPE_CONFIGS_PIN)
continue;
if (strncmp(map->name, dbg_state_name, MAX_NAME_LEN) > 0)
continue;
for (j = 0; j < map->data.configs.num_configs; j++) {
if (0 == strncmp(map->data.configs.group_or_pin,
dbg_pinname, MAX_NAME_LEN)) {
/* We found the right pin / state, read the
* config and store the pctldev */
dbg_config = map->data.configs.configs[j];
pctldev = get_pinctrl_dev_from_devname
(map->ctrl_dev_name);
found = true;
break;
}
}
}
mutex_unlock(&pinctrl_mutex);
if (found) {
seq_printf(s, "Config of %s in state %s: 0x%08X\n", dbg_pinname,
dbg_state_name, dbg_config);
if (pctldev)
confops = pctldev->desc->confops;
if (confops && confops->pin_config_config_dbg_show)
confops->pin_config_config_dbg_show(pctldev,
s, dbg_config);
} else {
seq_printf(s, "No pin found for defined name/state\n");
}
return 0;
}
static int pinconf_dbg_config_open(struct inode *inode, struct file *file)
{
return single_open(file, pinconf_dbg_config_print, inode->i_private);
}
/**
* pinconf_dbg_config_write() - overwrite the pinctrl config in thepinctrl
* map, of a pin/state pair based on pinname and state that have been
* selected with the debugfs entries pinconf-name and pinconf-state
*/
static int pinconf_dbg_config_write(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos)
{
int err;
unsigned long config;
struct pinctrl_maps *maps_node;
struct pinctrl_map const *map;
int i, j;
err = kstrtoul_from_user(user_buf, count, 0, &config);
if (err)
return err;
dbg_config = config;
mutex_lock(&pinctrl_mutex);
/* Parse the pinctrl map and look for the selected pin/state */
for_each_maps(maps_node, i, map) {
if (map->type != PIN_MAP_TYPE_CONFIGS_PIN)
continue;
if (strncmp(map->name, dbg_state_name, MAX_NAME_LEN) > 0)
continue;
/* we found the right pin / state, so overwrite config */
for (j = 0; j < map->data.configs.num_configs; j++) {
if (strncmp(map->data.configs.group_or_pin, dbg_pinname,
MAX_NAME_LEN) == 0)
map->data.configs.configs[j] = dbg_config;
}
}
mutex_unlock(&pinctrl_mutex);
return count;
}
static const struct file_operations pinconf_dbg_pinconfig_fops = {
.open = pinconf_dbg_config_open,
.write = pinconf_dbg_config_write,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.owner = THIS_MODULE,
};
void pinconf_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev)
{
@ -581,6 +782,12 @@ void pinconf_init_device_debugfs(struct dentry *devroot,
devroot, pctldev, &pinconf_pins_ops);
debugfs_create_file("pinconf-groups", S_IFREG | S_IRUGO,
devroot, pctldev, &pinconf_groups_ops);
debugfs_create_file("pinconf-name", (S_IRUGO | S_IWUSR | S_IWGRP),
devroot, pctldev, &pinconf_dbg_pinname_fops);
debugfs_create_file("pinconf-state", (S_IRUGO | S_IWUSR | S_IWGRP),
devroot, pctldev, &pinconf_dbg_pinstate_fops);
debugfs_create_file("pinconf-config", (S_IRUGO | S_IWUSR | S_IWGRP),
devroot, pctldev, &pinconf_dbg_pinconfig_fops);
}
#endif

View File

@ -0,0 +1,484 @@
/*
* Copyright (C) ST-Ericsson SA 2012
*
* Author: Patrice Chotard <patrice.chotard@stericsson.com> for ST-Ericsson.
*
* 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/kernel.h>
#include <linux/gpio.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/mfd/abx500/ab8500.h>
#include "pinctrl-abx500.h"
/* All the pins that can be used for GPIO and some other functions */
#define ABX500_GPIO(offset) (offset)
#define AB8500_PIN_T10 ABX500_GPIO(1)
#define AB8500_PIN_T9 ABX500_GPIO(2)
#define AB8500_PIN_U9 ABX500_GPIO(3)
#define AB8500_PIN_W2 ABX500_GPIO(4)
/* hole */
#define AB8500_PIN_Y18 ABX500_GPIO(6)
#define AB8500_PIN_AA20 ABX500_GPIO(7)
#define AB8500_PIN_W18 ABX500_GPIO(8)
#define AB8500_PIN_AA19 ABX500_GPIO(9)
#define AB8500_PIN_U17 ABX500_GPIO(10)
#define AB8500_PIN_AA18 ABX500_GPIO(11)
#define AB8500_PIN_U16 ABX500_GPIO(12)
#define AB8500_PIN_W17 ABX500_GPIO(13)
#define AB8500_PIN_F14 ABX500_GPIO(14)
#define AB8500_PIN_B17 ABX500_GPIO(15)
#define AB8500_PIN_F15 ABX500_GPIO(16)
#define AB8500_PIN_P5 ABX500_GPIO(17)
#define AB8500_PIN_R5 ABX500_GPIO(18)
#define AB8500_PIN_U5 ABX500_GPIO(19)
#define AB8500_PIN_T5 ABX500_GPIO(20)
#define AB8500_PIN_H19 ABX500_GPIO(21)
#define AB8500_PIN_G20 ABX500_GPIO(22)
#define AB8500_PIN_G19 ABX500_GPIO(23)
#define AB8500_PIN_T14 ABX500_GPIO(24)
#define AB8500_PIN_R16 ABX500_GPIO(25)
#define AB8500_PIN_M16 ABX500_GPIO(26)
#define AB8500_PIN_J6 ABX500_GPIO(27)
#define AB8500_PIN_K6 ABX500_GPIO(28)
#define AB8500_PIN_G6 ABX500_GPIO(29)
#define AB8500_PIN_H6 ABX500_GPIO(30)
#define AB8500_PIN_F5 ABX500_GPIO(31)
#define AB8500_PIN_G5 ABX500_GPIO(32)
/* hole */
#define AB8500_PIN_R17 ABX500_GPIO(34)
#define AB8500_PIN_W15 ABX500_GPIO(35)
#define AB8500_PIN_A17 ABX500_GPIO(36)
#define AB8500_PIN_E15 ABX500_GPIO(37)
#define AB8500_PIN_C17 ABX500_GPIO(38)
#define AB8500_PIN_E16 ABX500_GPIO(39)
#define AB8500_PIN_T19 ABX500_GPIO(40)
#define AB8500_PIN_U19 ABX500_GPIO(41)
#define AB8500_PIN_U2 ABX500_GPIO(42)
/* indicates the highest GPIO number */
#define AB8500_GPIO_MAX_NUMBER 42
/*
* The names of the pins are denoted by GPIO number and ball name, even
* though they can be used for other things than GPIO, this is the first
* column in the table of the data sheet and often used on schematics and
* such.
*/
static const struct pinctrl_pin_desc ab8500_pins[] = {
PINCTRL_PIN(AB8500_PIN_T10, "GPIO1_T10"),
PINCTRL_PIN(AB8500_PIN_T9, "GPIO2_T9"),
PINCTRL_PIN(AB8500_PIN_U9, "GPIO3_U9"),
PINCTRL_PIN(AB8500_PIN_W2, "GPIO4_W2"),
/* hole */
PINCTRL_PIN(AB8500_PIN_Y18, "GPIO6_Y18"),
PINCTRL_PIN(AB8500_PIN_AA20, "GPIO7_AA20"),
PINCTRL_PIN(AB8500_PIN_W18, "GPIO8_W18"),
PINCTRL_PIN(AB8500_PIN_AA19, "GPIO9_AA19"),
PINCTRL_PIN(AB8500_PIN_U17, "GPIO10_U17"),
PINCTRL_PIN(AB8500_PIN_AA18, "GPIO11_AA18"),
PINCTRL_PIN(AB8500_PIN_U16, "GPIO12_U16"),
PINCTRL_PIN(AB8500_PIN_W17, "GPIO13_W17"),
PINCTRL_PIN(AB8500_PIN_F14, "GPIO14_F14"),
PINCTRL_PIN(AB8500_PIN_B17, "GPIO15_B17"),
PINCTRL_PIN(AB8500_PIN_F15, "GPIO16_F15"),
PINCTRL_PIN(AB8500_PIN_P5, "GPIO17_P5"),
PINCTRL_PIN(AB8500_PIN_R5, "GPIO18_R5"),
PINCTRL_PIN(AB8500_PIN_U5, "GPIO19_U5"),
PINCTRL_PIN(AB8500_PIN_T5, "GPIO20_T5"),
PINCTRL_PIN(AB8500_PIN_H19, "GPIO21_H19"),
PINCTRL_PIN(AB8500_PIN_G20, "GPIO22_G20"),
PINCTRL_PIN(AB8500_PIN_G19, "GPIO23_G19"),
PINCTRL_PIN(AB8500_PIN_T14, "GPIO24_T14"),
PINCTRL_PIN(AB8500_PIN_R16, "GPIO25_R16"),
PINCTRL_PIN(AB8500_PIN_M16, "GPIO26_M16"),
PINCTRL_PIN(AB8500_PIN_J6, "GPIO27_J6"),
PINCTRL_PIN(AB8500_PIN_K6, "GPIO28_K6"),
PINCTRL_PIN(AB8500_PIN_G6, "GPIO29_G6"),
PINCTRL_PIN(AB8500_PIN_H6, "GPIO30_H6"),
PINCTRL_PIN(AB8500_PIN_F5, "GPIO31_F5"),
PINCTRL_PIN(AB8500_PIN_G5, "GPIO32_G5"),
/* hole */
PINCTRL_PIN(AB8500_PIN_R17, "GPIO34_R17"),
PINCTRL_PIN(AB8500_PIN_W15, "GPIO35_W15"),
PINCTRL_PIN(AB8500_PIN_A17, "GPIO36_A17"),
PINCTRL_PIN(AB8500_PIN_E15, "GPIO37_E15"),
PINCTRL_PIN(AB8500_PIN_C17, "GPIO38_C17"),
PINCTRL_PIN(AB8500_PIN_E16, "GPIO39_E16"),
PINCTRL_PIN(AB8500_PIN_T19, "GPIO40_T19"),
PINCTRL_PIN(AB8500_PIN_U19, "GPIO41_U19"),
PINCTRL_PIN(AB8500_PIN_U2, "GPIO42_U2"),
};
/*
* Maps local GPIO offsets to local pin numbers
*/
static const struct abx500_pinrange ab8500_pinranges[] = {
ABX500_PINRANGE(1, 4, ABX500_ALT_A),
ABX500_PINRANGE(6, 4, ABX500_ALT_A),
ABX500_PINRANGE(10, 4, ABX500_DEFAULT),
ABX500_PINRANGE(14, 12, ABX500_ALT_A),
ABX500_PINRANGE(26, 1, ABX500_DEFAULT),
ABX500_PINRANGE(27, 6, ABX500_ALT_A),
ABX500_PINRANGE(34, 1, ABX500_ALT_A),
ABX500_PINRANGE(35, 1, ABX500_DEFAULT),
ABX500_PINRANGE(36, 7, ABX500_ALT_A),
};
/*
* Read the pin group names like this:
* sysclkreq2_d_1 = first groups of pins for sysclkreq2 on default function
*
* The groups are arranged as sets per altfunction column, so we can
* mux in one group at a time by selecting the same altfunction for them
* all. When functions require pins on different altfunctions, you need
* to combine several groups.
*/
/* default column */
static const unsigned sysclkreq2_d_1_pins[] = { AB8500_PIN_T10 };
static const unsigned sysclkreq3_d_1_pins[] = { AB8500_PIN_T9 };
static const unsigned sysclkreq4_d_1_pins[] = { AB8500_PIN_U9 };
static const unsigned sysclkreq6_d_1_pins[] = { AB8500_PIN_W2 };
static const unsigned ycbcr0123_d_1_pins[] = { AB8500_PIN_Y18, AB8500_PIN_AA20,
AB8500_PIN_W18, AB8500_PIN_AA19};
static const unsigned gpio10_d_1_pins[] = { AB8500_PIN_U17 };
static const unsigned gpio11_d_1_pins[] = { AB8500_PIN_AA18 };
static const unsigned gpio12_d_1_pins[] = { AB8500_PIN_U16 };
static const unsigned gpio13_d_1_pins[] = { AB8500_PIN_W17 };
static const unsigned pwmout1_d_1_pins[] = { AB8500_PIN_F14 };
static const unsigned pwmout2_d_1_pins[] = { AB8500_PIN_B17 };
static const unsigned pwmout3_d_1_pins[] = { AB8500_PIN_F15 };
/* audio data interface 1*/
static const unsigned adi1_d_1_pins[] = { AB8500_PIN_P5, AB8500_PIN_R5,
AB8500_PIN_U5, AB8500_PIN_T5 };
/* USBUICC */
static const unsigned usbuicc_d_1_pins[] = { AB8500_PIN_H19, AB8500_PIN_G20,
AB8500_PIN_G19 };
static const unsigned sysclkreq7_d_1_pins[] = { AB8500_PIN_T14 };
static const unsigned sysclkreq8_d_1_pins[] = { AB8500_PIN_R16 };
static const unsigned gpio26_d_1_pins[] = { AB8500_PIN_M16 };
/* Digital microphone 1 and 2 */
static const unsigned dmic12_d_1_pins[] = { AB8500_PIN_J6, AB8500_PIN_K6 };
/* Digital microphone 3 and 4 */
static const unsigned dmic34_d_1_pins[] = { AB8500_PIN_G6, AB8500_PIN_H6 };
/* Digital microphone 5 and 6 */
static const unsigned dmic56_d_1_pins[] = { AB8500_PIN_F5, AB8500_PIN_G5 };
static const unsigned extcpena_d_1_pins[] = { AB8500_PIN_R17 };
static const unsigned gpio35_d_1_pins[] = { AB8500_PIN_W15 };
/* APE SPI */
static const unsigned apespi_d_1_pins[] = { AB8500_PIN_A17, AB8500_PIN_E15,
AB8500_PIN_C17, AB8500_PIN_E16};
/* modem SDA/SCL */
static const unsigned modsclsda_d_1_pins[] = { AB8500_PIN_T19, AB8500_PIN_U19 };
static const unsigned sysclkreq5_d_1_pins[] = { AB8500_PIN_U2 };
/* Altfunction A column */
static const unsigned gpio1_a_1_pins[] = { AB8500_PIN_T10 };
static const unsigned gpio2_a_1_pins[] = { AB8500_PIN_T9 };
static const unsigned gpio3_a_1_pins[] = { AB8500_PIN_U9 };
static const unsigned gpio4_a_1_pins[] = { AB8500_PIN_W2 };
static const unsigned gpio6_a_1_pins[] = { AB8500_PIN_Y18 };
static const unsigned gpio7_a_1_pins[] = { AB8500_PIN_AA20 };
static const unsigned gpio8_a_1_pins[] = { AB8500_PIN_W18 };
static const unsigned gpio9_a_1_pins[] = { AB8500_PIN_AA19 };
/* YCbCr4 YCbCr5 YCbCr6 YCbCr7*/
static const unsigned ycbcr4567_a_1_pins[] = { AB8500_PIN_U17, AB8500_PIN_AA18,
AB8500_PIN_U16, AB8500_PIN_W17};
static const unsigned gpio14_a_1_pins[] = { AB8500_PIN_F14 };
static const unsigned gpio15_a_1_pins[] = { AB8500_PIN_B17 };
static const unsigned gpio16_a_1_pins[] = { AB8500_PIN_F15 };
static const unsigned gpio17_a_1_pins[] = { AB8500_PIN_P5 };
static const unsigned gpio18_a_1_pins[] = { AB8500_PIN_R5 };
static const unsigned gpio19_a_1_pins[] = { AB8500_PIN_U5 };
static const unsigned gpio20_a_1_pins[] = { AB8500_PIN_T5 };
static const unsigned gpio21_a_1_pins[] = { AB8500_PIN_H19 };
static const unsigned gpio22_a_1_pins[] = { AB8500_PIN_G20 };
static const unsigned gpio23_a_1_pins[] = { AB8500_PIN_G19 };
static const unsigned gpio24_a_1_pins[] = { AB8500_PIN_T14 };
static const unsigned gpio25_a_1_pins[] = { AB8500_PIN_R16 };
static const unsigned gpio27_a_1_pins[] = { AB8500_PIN_J6 };
static const unsigned gpio28_a_1_pins[] = { AB8500_PIN_K6 };
static const unsigned gpio29_a_1_pins[] = { AB8500_PIN_G6 };
static const unsigned gpio30_a_1_pins[] = { AB8500_PIN_H6 };
static const unsigned gpio31_a_1_pins[] = { AB8500_PIN_F5 };
static const unsigned gpio32_a_1_pins[] = { AB8500_PIN_G5 };
static const unsigned gpio34_a_1_pins[] = { AB8500_PIN_R17 };
static const unsigned gpio36_a_1_pins[] = { AB8500_PIN_A17 };
static const unsigned gpio37_a_1_pins[] = { AB8500_PIN_E15 };
static const unsigned gpio38_a_1_pins[] = { AB8500_PIN_C17 };
static const unsigned gpio39_a_1_pins[] = { AB8500_PIN_E16 };
static const unsigned gpio40_a_1_pins[] = { AB8500_PIN_T19 };
static const unsigned gpio41_a_1_pins[] = { AB8500_PIN_U19 };
static const unsigned gpio42_a_1_pins[] = { AB8500_PIN_U2 };
/* Altfunction B colum */
static const unsigned hiqclkena_b_1_pins[] = { AB8500_PIN_U17 };
static const unsigned usbuiccpd_b_1_pins[] = { AB8500_PIN_AA18 };
static const unsigned i2ctrig1_b_1_pins[] = { AB8500_PIN_U16 };
static const unsigned i2ctrig2_b_1_pins[] = { AB8500_PIN_W17 };
/* Altfunction C column */
static const unsigned usbvdat_c_1_pins[] = { AB8500_PIN_W17 };
#define AB8500_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins, \
.npins = ARRAY_SIZE(a##_pins), .altsetting = b }
static const struct abx500_pingroup ab8500_groups[] = {
/* default column */
AB8500_PIN_GROUP(sysclkreq2_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(sysclkreq3_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(sysclkreq4_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(sysclkreq6_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(ycbcr0123_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(gpio10_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(gpio11_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(gpio12_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(gpio13_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(pwmout1_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(pwmout2_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(pwmout3_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(adi1_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(usbuicc_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(sysclkreq7_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(sysclkreq8_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(gpio26_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(dmic12_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(dmic34_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(dmic56_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(extcpena_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(gpio35_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(apespi_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(modsclsda_d_1, ABX500_DEFAULT),
AB8500_PIN_GROUP(sysclkreq5_d_1, ABX500_DEFAULT),
/* Altfunction A column */
AB8500_PIN_GROUP(gpio1_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio2_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio3_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio4_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio6_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio7_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio8_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio9_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(ycbcr4567_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio14_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio15_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio16_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio17_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio18_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio19_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio20_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio21_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio22_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio23_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio24_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio25_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio27_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio28_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio29_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio30_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio31_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio32_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio34_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio36_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio37_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio38_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio39_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio40_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio41_a_1, ABX500_ALT_A),
AB8500_PIN_GROUP(gpio42_a_1, ABX500_ALT_A),
/* Altfunction B column */
AB8500_PIN_GROUP(hiqclkena_b_1, ABX500_ALT_B),
AB8500_PIN_GROUP(usbuiccpd_b_1, ABX500_ALT_B),
AB8500_PIN_GROUP(i2ctrig1_b_1, ABX500_ALT_B),
AB8500_PIN_GROUP(i2ctrig2_b_1, ABX500_ALT_B),
/* Altfunction C column */
AB8500_PIN_GROUP(usbvdat_c_1, ABX500_ALT_C),
};
/* We use this macro to define the groups applicable to a function */
#define AB8500_FUNC_GROUPS(a, b...) \
static const char * const a##_groups[] = { b };
AB8500_FUNC_GROUPS(sysclkreq, "sysclkreq2_d_1", "sysclkreq3_d_1",
"sysclkreq4_d_1", "sysclkreq5_d_1", "sysclkreq6_d_1",
"sysclkreq7_d_1", "sysclkreq8_d_1");
AB8500_FUNC_GROUPS(ycbcr, "ycbcr0123_d_1", "ycbcr4567_a_1");
AB8500_FUNC_GROUPS(gpio, "gpio1_a_1", "gpio2_a_1", "gpio3_a_1", "gpio4_a_1",
"gpio6_a_1", "gpio7_a_1", "gpio8_a_1", "gpio9_a_1",
"gpio10_d_1", "gpio11_d_1", "gpio12_d_1", "gpio13_d_1",
"gpio14_a_1", "gpio15_a_1", "gpio16_a_1", "gpio17_a_1",
"gpio18_a_1", "gpio19_a_1", "gpio20_a_1", "gpio21_a_1",
"gpio22_a_1", "gpio23_a_1", "gpio24_a_1", "gpio25_a_1",
"gpio26_d_1", "gpio27_a_1", "gpio28_a_1", "gpio29_a_1",
"gpio30_a_1", "gpio31_a_1", "gpio32_a_1", "gpio34_a_1",
"gpio35_d_1", "gpio36_a_1", "gpio37_a_1", "gpio38_a_1",
"gpio39_a_1", "gpio40_a_1", "gpio41_a_1", "gpio42_a_1");
AB8500_FUNC_GROUPS(pwmout, "pwmout1_d_1", "pwmout2_d_1", "pwmout3_d_1");
AB8500_FUNC_GROUPS(adi1, "adi1_d_1");
AB8500_FUNC_GROUPS(usbuicc, "usbuicc_d_1", "usbuiccpd_b_1");
AB8500_FUNC_GROUPS(dmic, "dmic12_d_1", "dmic34_d_1", "dmic56_d_1");
AB8500_FUNC_GROUPS(extcpena, "extcpena_d_1");
AB8500_FUNC_GROUPS(apespi, "apespi_d_1");
AB8500_FUNC_GROUPS(modsclsda, "modsclsda_d_1");
AB8500_FUNC_GROUPS(hiqclkena, "hiqclkena_b_1");
AB8500_FUNC_GROUPS(i2ctrig, "i2ctrig1_b_1", "i2ctrig2_b_1");
AB8500_FUNC_GROUPS(usbvdat, "usbvdat_c_1");
#define FUNCTION(fname) \
{ \
.name = #fname, \
.groups = fname##_groups, \
.ngroups = ARRAY_SIZE(fname##_groups), \
}
static const struct abx500_function ab8500_functions[] = {
FUNCTION(sysclkreq),
FUNCTION(ycbcr),
FUNCTION(gpio),
FUNCTION(pwmout),
FUNCTION(adi1),
FUNCTION(usbuicc),
FUNCTION(dmic),
FUNCTION(extcpena),
FUNCTION(apespi),
FUNCTION(modsclsda),
FUNCTION(hiqclkena),
FUNCTION(i2ctrig),
FUNCTION(usbvdat),
};
/*
* this table translates what's is in the AB8500 specification regarding the
* balls alternate functions (as for DB, default, ALT_A, ALT_B and ALT_C).
* ALTERNATE_FUNCTIONS(GPIO_NUMBER, GPIOSEL bit, ALTERNATFUNC bit1,
* ALTERNATEFUNC bit2, ALTA val, ALTB val, ALTC val),
*
* example :
*
* ALTERNATE_FUNCTIONS(13, 4, 3, 4, 0, 1 ,2),
* means that pin AB8500_PIN_W17 (pin 13) supports 4 mux (default/ALT_A,
* ALT_B and ALT_C), so GPIOSEL and ALTERNATFUNC registers are used to
* select the mux. ALTA, ALTB and ALTC val indicates values to write in
* ALTERNATFUNC register. We need to specifies these values as SOC
* designers didn't apply the same logic on how to select mux in the
* ABx500 family.
*
* As this pins supports at least ALT_B mux, default mux is
* selected by writing 1 in GPIOSEL bit :
*
* | GPIOSEL bit=4 | alternatfunc bit2=4 | alternatfunc bit1=3
* default | 1 | 0 | 0
* alt_A | 0 | 0 | 0
* alt_B | 0 | 0 | 1
* alt_C | 0 | 1 | 0
*
* ALTERNATE_FUNCTIONS(8, 7, UNUSED, UNUSED),
* means that pin AB8500_PIN_W18 (pin 8) supports 2 mux, so only GPIOSEL
* register is used to select the mux. As this pins doesn't support at
* least ALT_B mux, default mux is by writing 0 in GPIOSEL bit :
*
* | GPIOSEL bit=7 | alternatfunc bit2= | alternatfunc bit1=
* default | 0 | 0 | 0
* alt_A | 1 | 0 | 0
*/
struct alternate_functions ab8500_alternate_functions[AB8500_GPIO_MAX_NUMBER + 1] = {
ALTERNATE_FUNCTIONS(0, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO0 */
ALTERNATE_FUNCTIONS(1, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO1, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(2, 1, UNUSED, UNUSED, 0, 0, 0), /* GPIO2, altA controlled by bit 1 */
ALTERNATE_FUNCTIONS(3, 2, UNUSED, UNUSED, 0, 0, 0), /* GPIO3, altA controlled by bit 2*/
ALTERNATE_FUNCTIONS(4, 3, UNUSED, UNUSED, 0, 0, 0), /* GPIO4, altA controlled by bit 3*/
/* bit 4 reserved */
ALTERNATE_FUNCTIONS(5, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO5 */
ALTERNATE_FUNCTIONS(6, 5, UNUSED, UNUSED, 0, 0, 0), /* GPIO6, altA controlled by bit 5*/
ALTERNATE_FUNCTIONS(7, 6, UNUSED, UNUSED, 0, 0, 0), /* GPIO7, altA controlled by bit 6*/
ALTERNATE_FUNCTIONS(8, 7, UNUSED, UNUSED, 0, 0, 0), /* GPIO8, altA controlled by bit 7*/
ALTERNATE_FUNCTIONS(9, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO9, altA controlled by bit 0*/
ALTERNATE_FUNCTIONS(10, 1, 0, UNUSED, 0, 1, 0), /* GPIO10, altA and altB controlled by bit 0 */
ALTERNATE_FUNCTIONS(11, 2, 1, UNUSED, 0, 1, 0), /* GPIO11, altA and altB controlled by bit 1 */
ALTERNATE_FUNCTIONS(12, 3, 2, UNUSED, 0, 1, 0), /* GPIO12, altA and altB controlled by bit 2 */
ALTERNATE_FUNCTIONS(13, 4, 3, 4, 0, 1, 2), /* GPIO13, altA altB and altC controlled by bit 3 and 4 */
ALTERNATE_FUNCTIONS(14, 5, UNUSED, UNUSED, 0, 0, 0), /* GPIO14, altA controlled by bit 5 */
ALTERNATE_FUNCTIONS(15, 6, UNUSED, UNUSED, 0, 0, 0), /* GPIO15, altA controlled by bit 6 */
ALTERNATE_FUNCTIONS(16, 7, UNUSED, UNUSED, 0, 0, 0), /* GPIO16, altA controlled by bit 7 */
/*
* pins 17 to 20 are special case, only bit 0 is used to select
* alternate function for these 4 pins.
* bits 1 to 3 are reserved
*/
ALTERNATE_FUNCTIONS(17, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO17, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(18, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO18, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(19, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO19, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(20, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO20, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(21, 4, UNUSED, UNUSED, 0, 0, 0), /* GPIO21, altA controlled by bit 4 */
ALTERNATE_FUNCTIONS(22, 5, UNUSED, UNUSED, 0, 0, 0), /* GPIO22, altA controlled by bit 5 */
ALTERNATE_FUNCTIONS(23, 6, UNUSED, UNUSED, 0, 0, 0), /* GPIO23, altA controlled by bit 6 */
ALTERNATE_FUNCTIONS(24, 7, UNUSED, UNUSED, 0, 0, 0), /* GPIO24, altA controlled by bit 7 */
ALTERNATE_FUNCTIONS(25, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO25, altA controlled by bit 0 */
/* pin 26 special case, no alternate function, bit 1 reserved */
ALTERNATE_FUNCTIONS(26, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* GPIO26 */
ALTERNATE_FUNCTIONS(27, 2, UNUSED, UNUSED, 0, 0, 0), /* GPIO27, altA controlled by bit 2 */
ALTERNATE_FUNCTIONS(28, 3, UNUSED, UNUSED, 0, 0, 0), /* GPIO28, altA controlled by bit 3 */
ALTERNATE_FUNCTIONS(29, 4, UNUSED, UNUSED, 0, 0, 0), /* GPIO29, altA controlled by bit 4 */
ALTERNATE_FUNCTIONS(30, 5, UNUSED, UNUSED, 0, 0, 0), /* GPIO30, altA controlled by bit 5 */
ALTERNATE_FUNCTIONS(31, 6, UNUSED, UNUSED, 0, 0, 0), /* GPIO31, altA controlled by bit 6 */
ALTERNATE_FUNCTIONS(32, 7, UNUSED, UNUSED, 0, 0, 0), /* GPIO32, altA controlled by bit 7 */
ALTERNATE_FUNCTIONS(33, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO33 */
ALTERNATE_FUNCTIONS(34, 1, UNUSED, UNUSED, 0, 0, 0), /* GPIO34, altA controlled by bit 1 */
/* pin 35 special case, no alternate function, bit 2 reserved */
ALTERNATE_FUNCTIONS(35, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* GPIO35 */
ALTERNATE_FUNCTIONS(36, 3, UNUSED, UNUSED, 0, 0, 0), /* GPIO36, altA controlled by bit 3 */
ALTERNATE_FUNCTIONS(37, 4, UNUSED, UNUSED, 0, 0, 0), /* GPIO37, altA controlled by bit 4 */
ALTERNATE_FUNCTIONS(38, 5, UNUSED, UNUSED, 0, 0, 0), /* GPIO38, altA controlled by bit 5 */
ALTERNATE_FUNCTIONS(39, 6, UNUSED, UNUSED, 0, 0, 0), /* GPIO39, altA controlled by bit 6 */
ALTERNATE_FUNCTIONS(40, 7, UNUSED, UNUSED, 0, 0, 0), /* GPIO40, altA controlled by bit 7 */
ALTERNATE_FUNCTIONS(41, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO41, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(42, 1, UNUSED, UNUSED, 0, 0, 0), /* GPIO42, altA controlled by bit 1 */
};
/*
* Only some GPIOs are interrupt capable, and they are
* organized in discontiguous clusters:
*
* GPIO6 to GPIO13
* GPIO24 and GPIO25
* GPIO36 to GPIO41
*/
struct abx500_gpio_irq_cluster ab8500_gpio_irq_cluster[] = {
GPIO_IRQ_CLUSTER(6, 13, AB8500_INT_GPIO6R),
GPIO_IRQ_CLUSTER(24, 25, AB8500_INT_GPIO24R),
GPIO_IRQ_CLUSTER(36, 41, AB8500_INT_GPIO36R),
};
static struct abx500_pinctrl_soc_data ab8500_soc = {
.gpio_ranges = ab8500_pinranges,
.gpio_num_ranges = ARRAY_SIZE(ab8500_pinranges),
.pins = ab8500_pins,
.npins = ARRAY_SIZE(ab8500_pins),
.functions = ab8500_functions,
.nfunctions = ARRAY_SIZE(ab8500_functions),
.groups = ab8500_groups,
.ngroups = ARRAY_SIZE(ab8500_groups),
.alternate_functions = ab8500_alternate_functions,
.gpio_irq_cluster = ab8500_gpio_irq_cluster,
.ngpio_irq_cluster = ARRAY_SIZE(ab8500_gpio_irq_cluster),
.irq_gpio_rising_offset = AB8500_INT_GPIO6R,
.irq_gpio_falling_offset = AB8500_INT_GPIO6F,
.irq_gpio_factor = 1,
};
void abx500_pinctrl_ab8500_init(struct abx500_pinctrl_soc_data **soc)
{
*soc = &ab8500_soc;
}

View File

@ -0,0 +1,380 @@
/*
* Copyright (C) ST-Ericsson SA 2012
*
* Author: Patrice Chotard <patrice.chotard@stericsson.com> for ST-Ericsson.
*
* 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/kernel.h>
#include <linux/gpio.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/mfd/abx500/ab8500.h>
#include "pinctrl-abx500.h"
/* All the pins that can be used for GPIO and some other functions */
#define ABX500_GPIO(offset) (offset)
#define AB8505_PIN_N4 ABX500_GPIO(1)
#define AB8505_PIN_R5 ABX500_GPIO(2)
#define AB8505_PIN_P5 ABX500_GPIO(3)
/* hole */
#define AB8505_PIN_B16 ABX500_GPIO(10)
#define AB8505_PIN_B17 ABX500_GPIO(11)
/* hole */
#define AB8505_PIN_D17 ABX500_GPIO(13)
#define AB8505_PIN_C16 ABX500_GPIO(14)
/* hole */
#define AB8505_PIN_P2 ABX500_GPIO(17)
#define AB8505_PIN_N3 ABX500_GPIO(18)
#define AB8505_PIN_T1 ABX500_GPIO(19)
#define AB8505_PIN_P3 ABX500_GPIO(20)
/* hole */
#define AB8505_PIN_H14 ABX500_GPIO(34)
/* hole */
#define AB8505_PIN_J15 ABX500_GPIO(40)
#define AB8505_PIN_J14 ABX500_GPIO(41)
/* hole */
#define AB8505_PIN_L4 ABX500_GPIO(50)
/* hole */
#define AB8505_PIN_D16 ABX500_GPIO(52)
#define AB8505_PIN_D15 ABX500_GPIO(53)
/* indicates the higher GPIO number */
#define AB8505_GPIO_MAX_NUMBER 53
/*
* The names of the pins are denoted by GPIO number and ball name, even
* though they can be used for other things than GPIO, this is the first
* column in the table of the data sheet and often used on schematics and
* such.
*/
static const struct pinctrl_pin_desc ab8505_pins[] = {
PINCTRL_PIN(AB8505_PIN_N4, "GPIO1_N4"),
PINCTRL_PIN(AB8505_PIN_R5, "GPIO2_R5"),
PINCTRL_PIN(AB8505_PIN_P5, "GPIO3_P5"),
/* hole */
PINCTRL_PIN(AB8505_PIN_B16, "GPIO10_B16"),
PINCTRL_PIN(AB8505_PIN_B17, "GPIO11_B17"),
/* hole */
PINCTRL_PIN(AB8505_PIN_D17, "GPIO13_D17"),
PINCTRL_PIN(AB8505_PIN_C16, "GPIO14_C16"),
/* hole */
PINCTRL_PIN(AB8505_PIN_P2, "GPIO17_P2"),
PINCTRL_PIN(AB8505_PIN_N3, "GPIO18_N3"),
PINCTRL_PIN(AB8505_PIN_T1, "GPIO19_T1"),
PINCTRL_PIN(AB8505_PIN_P3, "GPIO20_P3"),
/* hole */
PINCTRL_PIN(AB8505_PIN_H14, "GPIO34_H14"),
/* hole */
PINCTRL_PIN(AB8505_PIN_J15, "GPIO40_J15"),
PINCTRL_PIN(AB8505_PIN_J14, "GPIO41_J14"),
/* hole */
PINCTRL_PIN(AB8505_PIN_L4, "GPIO50_L4"),
/* hole */
PINCTRL_PIN(AB8505_PIN_D16, "GPIO52_D16"),
PINCTRL_PIN(AB8505_PIN_D15, "GPIO53_D15"),
};
/*
* Maps local GPIO offsets to local pin numbers
*/
static const struct abx500_pinrange ab8505_pinranges[] = {
ABX500_PINRANGE(1, 3, ABX500_ALT_A),
ABX500_PINRANGE(10, 2, ABX500_DEFAULT),
ABX500_PINRANGE(13, 1, ABX500_DEFAULT),
ABX500_PINRANGE(14, 1, ABX500_ALT_A),
ABX500_PINRANGE(17, 4, ABX500_ALT_A),
ABX500_PINRANGE(34, 1, ABX500_ALT_A),
ABX500_PINRANGE(40, 2, ABX500_ALT_A),
ABX500_PINRANGE(50, 1, ABX500_DEFAULT),
ABX500_PINRANGE(52, 2, ABX500_ALT_A),
};
/*
* Read the pin group names like this:
* sysclkreq2_d_1 = first groups of pins for sysclkreq2 on default function
*
* The groups are arranged as sets per altfunction column, so we can
* mux in one group at a time by selecting the same altfunction for them
* all. When functions require pins on different altfunctions, you need
* to combine several groups.
*/
/* default column */
static const unsigned sysclkreq2_d_1_pins[] = { AB8505_PIN_N4 };
static const unsigned sysclkreq3_d_1_pins[] = { AB8505_PIN_R5 };
static const unsigned sysclkreq4_d_1_pins[] = { AB8505_PIN_P5 };
static const unsigned gpio10_d_1_pins[] = { AB8505_PIN_B16 };
static const unsigned gpio11_d_1_pins[] = { AB8505_PIN_B17 };
static const unsigned gpio13_d_1_pins[] = { AB8505_PIN_D17 };
static const unsigned pwmout1_d_1_pins[] = { AB8505_PIN_C16 };
/* audio data interface 2*/
static const unsigned adi2_d_1_pins[] = { AB8505_PIN_P2, AB8505_PIN_N3,
AB8505_PIN_T1, AB8505_PIN_P3 };
static const unsigned extcpena_d_1_pins[] = { AB8505_PIN_H14 };
/* modem SDA/SCL */
static const unsigned modsclsda_d_1_pins[] = { AB8505_PIN_J15, AB8505_PIN_J14 };
static const unsigned gpio50_d_1_pins[] = { AB8505_PIN_L4 };
static const unsigned resethw_d_1_pins[] = { AB8505_PIN_D16 };
static const unsigned service_d_1_pins[] = { AB8505_PIN_D15 };
/* Altfunction A column */
static const unsigned gpio1_a_1_pins[] = { AB8505_PIN_N4 };
static const unsigned gpio2_a_1_pins[] = { AB8505_PIN_R5 };
static const unsigned gpio3_a_1_pins[] = { AB8505_PIN_P5 };
static const unsigned hiqclkena_a_1_pins[] = { AB8505_PIN_B16 };
static const unsigned pdmclk_a_1_pins[] = { AB8505_PIN_B17 };
static const unsigned uarttxdata_a_1_pins[] = { AB8505_PIN_D17 };
static const unsigned gpio14_a_1_pins[] = { AB8505_PIN_C16 };
static const unsigned gpio17_a_1_pins[] = { AB8505_PIN_P2 };
static const unsigned gpio18_a_1_pins[] = { AB8505_PIN_N3 };
static const unsigned gpio19_a_1_pins[] = { AB8505_PIN_T1 };
static const unsigned gpio20_a_1_pins[] = { AB8505_PIN_P3 };
static const unsigned gpio34_a_1_pins[] = { AB8505_PIN_H14 };
static const unsigned gpio40_a_1_pins[] = { AB8505_PIN_J15 };
static const unsigned gpio41_a_1_pins[] = { AB8505_PIN_J14 };
static const unsigned uartrxdata_a_1_pins[] = { AB8505_PIN_J14 };
static const unsigned gpio50_a_1_pins[] = { AB8505_PIN_L4 };
static const unsigned gpio52_a_1_pins[] = { AB8505_PIN_D16 };
static const unsigned gpio53_a_1_pins[] = { AB8505_PIN_D15 };
/* Altfunction B colum */
static const unsigned pdmdata_b_1_pins[] = { AB8505_PIN_B16 };
static const unsigned extvibrapwm1_b_1_pins[] = { AB8505_PIN_D17 };
static const unsigned extvibrapwm2_b_1_pins[] = { AB8505_PIN_L4 };
/* Altfunction C column */
static const unsigned usbvdat_c_1_pins[] = { AB8505_PIN_D17 };
#define AB8505_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins, \
.npins = ARRAY_SIZE(a##_pins), .altsetting = b }
static const struct abx500_pingroup ab8505_groups[] = {
AB8505_PIN_GROUP(sysclkreq2_d_1, ABX500_DEFAULT),
AB8505_PIN_GROUP(sysclkreq3_d_1, ABX500_DEFAULT),
AB8505_PIN_GROUP(sysclkreq4_d_1, ABX500_DEFAULT),
AB8505_PIN_GROUP(gpio10_d_1, ABX500_DEFAULT),
AB8505_PIN_GROUP(gpio11_d_1, ABX500_DEFAULT),
AB8505_PIN_GROUP(gpio13_d_1, ABX500_DEFAULT),
AB8505_PIN_GROUP(pwmout1_d_1, ABX500_DEFAULT),
AB8505_PIN_GROUP(adi2_d_1, ABX500_DEFAULT),
AB8505_PIN_GROUP(extcpena_d_1, ABX500_DEFAULT),
AB8505_PIN_GROUP(modsclsda_d_1, ABX500_DEFAULT),
AB8505_PIN_GROUP(gpio50_d_1, ABX500_DEFAULT),
AB8505_PIN_GROUP(resethw_d_1, ABX500_DEFAULT),
AB8505_PIN_GROUP(service_d_1, ABX500_DEFAULT),
AB8505_PIN_GROUP(gpio1_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(gpio2_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(gpio3_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(hiqclkena_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(pdmclk_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(uarttxdata_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(gpio14_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(gpio17_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(gpio18_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(gpio19_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(gpio20_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(gpio34_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(gpio40_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(gpio41_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(uartrxdata_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(gpio52_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(gpio53_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(pdmdata_b_1, ABX500_ALT_B),
AB8505_PIN_GROUP(extvibrapwm1_b_1, ABX500_ALT_B),
AB8505_PIN_GROUP(extvibrapwm2_b_1, ABX500_ALT_B),
AB8505_PIN_GROUP(usbvdat_c_1, ABX500_ALT_C),
};
/* We use this macro to define the groups applicable to a function */
#define AB8505_FUNC_GROUPS(a, b...) \
static const char * const a##_groups[] = { b };
AB8505_FUNC_GROUPS(sysclkreq, "sysclkreq2_d_1", "sysclkreq3_d_1",
"sysclkreq4_d_1");
AB8505_FUNC_GROUPS(gpio, "gpio1_a_1", "gpio2_a_1", "gpio3_a_1",
"gpio10_d_1", "gpio11_d_1", "gpio13_d_1", "gpio14_a_1",
"gpio17_a_1", "gpio18_a_1", "gpio19_a_1", "gpio20_a_1",
"gpio34_a_1", "gpio40_a_1", "gpio41_a_1", "gpio50_d_1",
"gpio52_a_1", "gpio53_a_1");
AB8505_FUNC_GROUPS(pwmout, "pwmout1_d_1");
AB8505_FUNC_GROUPS(adi2, "adi2_d_1");
AB8505_FUNC_GROUPS(extcpena, "extcpena_d_1");
AB8505_FUNC_GROUPS(modsclsda, "modsclsda_d_1");
AB8505_FUNC_GROUPS(resethw, "resethw_d_1");
AB8505_FUNC_GROUPS(service, "service_d_1");
AB8505_FUNC_GROUPS(hiqclkena, "hiqclkena_a_1");
AB8505_FUNC_GROUPS(pdm, "pdmclk_a_1", "pdmdata_b_1");
AB8505_FUNC_GROUPS(uartdata, "uarttxdata_a_1", "uartrxdata_a_1");
AB8505_FUNC_GROUPS(extvibra, "extvibrapwm1_b_1", "extvibrapwm2_b_1");
AB8505_FUNC_GROUPS(usbvdat, "usbvdat_c_1");
#define FUNCTION(fname) \
{ \
.name = #fname, \
.groups = fname##_groups, \
.ngroups = ARRAY_SIZE(fname##_groups), \
}
static const struct abx500_function ab8505_functions[] = {
FUNCTION(sysclkreq),
FUNCTION(gpio),
FUNCTION(pwmout),
FUNCTION(adi2),
FUNCTION(extcpena),
FUNCTION(modsclsda),
FUNCTION(resethw),
FUNCTION(service),
FUNCTION(hiqclkena),
FUNCTION(pdm),
FUNCTION(uartdata),
FUNCTION(extvibra),
FUNCTION(extvibra),
FUNCTION(usbvdat),
};
/*
* this table translates what's is in the AB8505 specification regarding the
* balls alternate functions (as for DB, default, ALT_A, ALT_B and ALT_C).
* ALTERNATE_FUNCTIONS(GPIO_NUMBER, GPIOSEL bit, ALTERNATFUNC bit1,
* ALTERNATEFUNC bit2, ALTA val, ALTB val, ALTC val),
*
* example :
*
* ALTERNATE_FUNCTIONS(13, 4, 3, 4, 1, 0, 2),
* means that pin AB8505_PIN_D18 (pin 13) supports 4 mux (default/ALT_A,
* ALT_B and ALT_C), so GPIOSEL and ALTERNATFUNC registers are used to
* select the mux. ALTA, ALTB and ALTC val indicates values to write in
* ALTERNATFUNC register. We need to specifies these values as SOC
* designers didn't apply the same logic on how to select mux in the
* ABx500 family.
*
* As this pins supports at least ALT_B mux, default mux is
* selected by writing 1 in GPIOSEL bit :
*
* | GPIOSEL bit=4 | alternatfunc bit2=4 | alternatfunc bit1=3
* default | 1 | 0 | 0
* alt_A | 0 | 0 | 1
* alt_B | 0 | 0 | 0
* alt_C | 0 | 1 | 0
*
* ALTERNATE_FUNCTIONS(1, 0, UNUSED, UNUSED),
* means that pin AB9540_PIN_R4 (pin 1) supports 2 mux, so only GPIOSEL
* register is used to select the mux. As this pins doesn't support at
* least ALT_B mux, default mux is by writing 0 in GPIOSEL bit :
*
* | GPIOSEL bit=0 | alternatfunc bit2= | alternatfunc bit1=
* default | 0 | 0 | 0
* alt_A | 1 | 0 | 0
*/
struct alternate_functions ab8505_alternate_functions[AB8505_GPIO_MAX_NUMBER + 1] = {
ALTERNATE_FUNCTIONS(0, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO0 */
ALTERNATE_FUNCTIONS(1, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO1, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(2, 1, UNUSED, UNUSED, 0, 0, 0), /* GPIO2, altA controlled by bit 1 */
ALTERNATE_FUNCTIONS(3, 2, UNUSED, UNUSED, 0, 0, 0), /* GPIO3, altA controlled by bit 2*/
ALTERNATE_FUNCTIONS(4, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO4, bit 3 reserved */
ALTERNATE_FUNCTIONS(5, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO5, bit 4 reserved */
ALTERNATE_FUNCTIONS(6, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO6, bit 5 reserved */
ALTERNATE_FUNCTIONS(7, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO7, bit 6 reserved */
ALTERNATE_FUNCTIONS(8, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO8, bit 7 reserved */
ALTERNATE_FUNCTIONS(9, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO9, bit 0 reserved */
ALTERNATE_FUNCTIONS(10, 1, 0, UNUSED, 1, 0, 0), /* GPIO10, altA and altB controlled by bit 0 */
ALTERNATE_FUNCTIONS(11, 2, UNUSED, UNUSED, 0, 0, 0), /* GPIO11, altA controlled by bit 2 */
ALTERNATE_FUNCTIONS(12, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO12, bit3 reseved */
ALTERNATE_FUNCTIONS(13, 4, 3, 4, 1, 0, 2), /* GPIO13, altA altB and altC controlled by bit 3 and 4 */
ALTERNATE_FUNCTIONS(14, 5, UNUSED, UNUSED, 0, 0, 0), /* GPIO14, altA controlled by bit 5 */
ALTERNATE_FUNCTIONS(15, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO15, bit 6 reserved */
ALTERNATE_FUNCTIONS(16, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO15, bit 7 reserved */
/*
* pins 17 to 20 are special case, only bit 0 is used to select
* alternate function for these 4 pins.
* bits 1 to 3 are reserved
*/
ALTERNATE_FUNCTIONS(17, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO17, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(18, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO18, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(19, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO19, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(20, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO20, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(21, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO21, bit 4 reserved */
ALTERNATE_FUNCTIONS(22, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO22, bit 5 reserved */
ALTERNATE_FUNCTIONS(23, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO23, bit 6 reserved */
ALTERNATE_FUNCTIONS(24, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO24, bit 7 reserved */
ALTERNATE_FUNCTIONS(25, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO25, bit 0 reserved */
ALTERNATE_FUNCTIONS(26, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO26, bit 1 reserved */
ALTERNATE_FUNCTIONS(27, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO27, bit 2 reserved */
ALTERNATE_FUNCTIONS(28, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO28, bit 3 reserved */
ALTERNATE_FUNCTIONS(29, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO29, bit 4 reserved */
ALTERNATE_FUNCTIONS(30, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO30, bit 5 reserved */
ALTERNATE_FUNCTIONS(31, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO31, bit 6 reserved */
ALTERNATE_FUNCTIONS(32, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO32, bit 7 reserved */
ALTERNATE_FUNCTIONS(33, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO33, bit 0 reserved */
ALTERNATE_FUNCTIONS(34, 1, UNUSED, UNUSED, 0, 0, 0), /* GPIO34, altA controlled by bit 1 */
ALTERNATE_FUNCTIONS(35, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO35, bit 2 reserved */
ALTERNATE_FUNCTIONS(36, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO36, bit 2 reserved */
ALTERNATE_FUNCTIONS(37, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO37, bit 2 reserved */
ALTERNATE_FUNCTIONS(38, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO38, bit 2 reserved */
ALTERNATE_FUNCTIONS(39, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO39, bit 2 reserved */
ALTERNATE_FUNCTIONS(40, 7, UNUSED, UNUSED, 0, 0, 0), /* GPIO40, altA controlled by bit 7*/
ALTERNATE_FUNCTIONS(41, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO41, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(42, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO42, bit 1 reserved */
ALTERNATE_FUNCTIONS(43, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO43, bit 2 reserved */
ALTERNATE_FUNCTIONS(44, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO44, bit 3 reserved */
ALTERNATE_FUNCTIONS(45, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO45, bit 4 reserved */
ALTERNATE_FUNCTIONS(46, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO46, bit 5 reserved */
ALTERNATE_FUNCTIONS(47, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO47, bit 6 reserved */
ALTERNATE_FUNCTIONS(48, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO48, bit 7 reserved */
ALTERNATE_FUNCTIONS(49, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO49, bit 0 reserved */
ALTERNATE_FUNCTIONS(50, 1, 2, UNUSED, 1, 0, 0), /* GPIO50, altA controlled by bit 1 */
ALTERNATE_FUNCTIONS(51, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO49, bit 0 reserved */
ALTERNATE_FUNCTIONS(52, 3, UNUSED, UNUSED, 0, 0, 0), /* GPIO52, altA controlled by bit 3 */
ALTERNATE_FUNCTIONS(53, 4, UNUSED, UNUSED, 0, 0, 0), /* GPIO53, altA controlled by bit 4 */
};
/*
* For AB8505 Only some GPIOs are interrupt capable, and they are
* organized in discontiguous clusters:
*
* GPIO10 to GPIO11
* GPIO13
* GPIO40 and GPIO41
* GPIO50
* GPIO52 to GPIO53
*/
struct abx500_gpio_irq_cluster ab8505_gpio_irq_cluster[] = {
GPIO_IRQ_CLUSTER(10, 11, AB8500_INT_GPIO10R),
GPIO_IRQ_CLUSTER(13, 13, AB8500_INT_GPIO13R),
GPIO_IRQ_CLUSTER(40, 41, AB8500_INT_GPIO40R),
GPIO_IRQ_CLUSTER(50, 50, AB9540_INT_GPIO50R),
GPIO_IRQ_CLUSTER(52, 53, AB9540_INT_GPIO52R),
};
static struct abx500_pinctrl_soc_data ab8505_soc = {
.gpio_ranges = ab8505_pinranges,
.gpio_num_ranges = ARRAY_SIZE(ab8505_pinranges),
.pins = ab8505_pins,
.npins = ARRAY_SIZE(ab8505_pins),
.functions = ab8505_functions,
.nfunctions = ARRAY_SIZE(ab8505_functions),
.groups = ab8505_groups,
.ngroups = ARRAY_SIZE(ab8505_groups),
.alternate_functions = ab8505_alternate_functions,
.gpio_irq_cluster = ab8505_gpio_irq_cluster,
.ngpio_irq_cluster = ARRAY_SIZE(ab8505_gpio_irq_cluster),
.irq_gpio_rising_offset = AB8500_INT_GPIO6R,
.irq_gpio_falling_offset = AB8500_INT_GPIO6F,
.irq_gpio_factor = 1,
};
void
abx500_pinctrl_ab8505_init(struct abx500_pinctrl_soc_data **soc)
{
*soc = &ab8505_soc;
}

View File

@ -0,0 +1,407 @@
/*
* Copyright (C) ST-Ericsson SA 2012
*
* Author: Patrice Chotard <patrice.chotard@stericsson.com> for ST-Ericsson.
*
* 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/kernel.h>
#include <linux/gpio.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/mfd/abx500/ab8500.h>
#include "pinctrl-abx500.h"
/* All the pins that can be used for GPIO and some other functions */
#define ABX500_GPIO(offset) (offset)
#define AB8540_PIN_J16 ABX500_GPIO(1)
#define AB8540_PIN_D17 ABX500_GPIO(2)
#define AB8540_PIN_C12 ABX500_GPIO(3)
#define AB8540_PIN_G12 ABX500_GPIO(4)
/* hole */
#define AB8540_PIN_D16 ABX500_GPIO(14)
#define AB8540_PIN_F15 ABX500_GPIO(15)
#define AB8540_PIN_J8 ABX500_GPIO(16)
#define AB8540_PIN_K16 ABX500_GPIO(17)
#define AB8540_PIN_G15 ABX500_GPIO(18)
#define AB8540_PIN_F17 ABX500_GPIO(19)
#define AB8540_PIN_E17 ABX500_GPIO(20)
/* hole */
#define AB8540_PIN_AA16 ABX500_GPIO(27)
#define AB8540_PIN_W18 ABX500_GPIO(28)
#define AB8540_PIN_Y15 ABX500_GPIO(29)
#define AB8540_PIN_W16 ABX500_GPIO(30)
#define AB8540_PIN_V15 ABX500_GPIO(31)
#define AB8540_PIN_W17 ABX500_GPIO(32)
/* hole */
#define AB8540_PIN_D12 ABX500_GPIO(42)
#define AB8540_PIN_P4 ABX500_GPIO(43)
#define AB8540_PIN_AB1 ABX500_GPIO(44)
#define AB8540_PIN_K7 ABX500_GPIO(45)
#define AB8540_PIN_L7 ABX500_GPIO(46)
#define AB8540_PIN_G10 ABX500_GPIO(47)
#define AB8540_PIN_K12 ABX500_GPIO(48)
/* hole */
#define AB8540_PIN_N8 ABX500_GPIO(51)
#define AB8540_PIN_P12 ABX500_GPIO(52)
#define AB8540_PIN_K8 ABX500_GPIO(53)
#define AB8540_PIN_J11 ABX500_GPIO(54)
#define AB8540_PIN_AC2 ABX500_GPIO(55)
#define AB8540_PIN_AB2 ABX500_GPIO(56)
/* indicates the highest GPIO number */
#define AB8540_GPIO_MAX_NUMBER 56
/*
* The names of the pins are denoted by GPIO number and ball name, even
* though they can be used for other things than GPIO, this is the first
* column in the table of the data sheet and often used on schematics and
* such.
*/
static const struct pinctrl_pin_desc ab8540_pins[] = {
PINCTRL_PIN(AB8540_PIN_J16, "GPIO1_J16"),
PINCTRL_PIN(AB8540_PIN_D17, "GPIO2_D17"),
PINCTRL_PIN(AB8540_PIN_C12, "GPIO3_C12"),
PINCTRL_PIN(AB8540_PIN_G12, "GPIO4_G12"),
/* hole */
PINCTRL_PIN(AB8540_PIN_D16, "GPIO14_D16"),
PINCTRL_PIN(AB8540_PIN_F15, "GPIO15_F15"),
PINCTRL_PIN(AB8540_PIN_J8, "GPIO16_J8"),
PINCTRL_PIN(AB8540_PIN_K16, "GPIO17_K16"),
PINCTRL_PIN(AB8540_PIN_G15, "GPIO18_G15"),
PINCTRL_PIN(AB8540_PIN_F17, "GPIO19_F17"),
PINCTRL_PIN(AB8540_PIN_E17, "GPIO20_E17"),
/* hole */
PINCTRL_PIN(AB8540_PIN_AA16, "GPIO27_AA16"),
PINCTRL_PIN(AB8540_PIN_W18, "GPIO28_W18"),
PINCTRL_PIN(AB8540_PIN_Y15, "GPIO29_Y15"),
PINCTRL_PIN(AB8540_PIN_W16, "GPIO30_W16"),
PINCTRL_PIN(AB8540_PIN_V15, "GPIO31_V15"),
PINCTRL_PIN(AB8540_PIN_W17, "GPIO32_W17"),
/* hole */
PINCTRL_PIN(AB8540_PIN_D12, "GPIO42_D12"),
PINCTRL_PIN(AB8540_PIN_P4, "GPIO43_P4"),
PINCTRL_PIN(AB8540_PIN_AB1, "GPIO44_AB1"),
PINCTRL_PIN(AB8540_PIN_K7, "GPIO45_K7"),
PINCTRL_PIN(AB8540_PIN_L7, "GPIO46_L7"),
PINCTRL_PIN(AB8540_PIN_G10, "GPIO47_G10"),
PINCTRL_PIN(AB8540_PIN_K12, "GPIO48_K12"),
/* hole */
PINCTRL_PIN(AB8540_PIN_N8, "GPIO51_N8"),
PINCTRL_PIN(AB8540_PIN_P12, "GPIO52_P12"),
PINCTRL_PIN(AB8540_PIN_K8, "GPIO53_K8"),
PINCTRL_PIN(AB8540_PIN_J11, "GPIO54_J11"),
PINCTRL_PIN(AB8540_PIN_AC2, "GPIO55_AC2"),
PINCTRL_PIN(AB8540_PIN_AB2, "GPIO56_AB2"),
};
/*
* Maps local GPIO offsets to local pin numbers
*/
static const struct abx500_pinrange ab8540_pinranges[] = {
ABX500_PINRANGE(1, 4, ABX500_ALT_A),
ABX500_PINRANGE(14, 7, ABX500_ALT_A),
ABX500_PINRANGE(27, 6, ABX500_ALT_A),
ABX500_PINRANGE(42, 7, ABX500_ALT_A),
ABX500_PINRANGE(51, 6, ABX500_ALT_A),
};
/*
* Read the pin group names like this:
* sysclkreq2_d_1 = first groups of pins for sysclkreq2 on default function
*
* The groups are arranged as sets per altfunction column, so we can
* mux in one group at a time by selecting the same altfunction for them
* all. When functions require pins on different altfunctions, you need
* to combine several groups.
*/
/* default column */
static const unsigned sysclkreq2_d_1_pins[] = { AB8540_PIN_J16 };
static const unsigned sysclkreq3_d_1_pins[] = { AB8540_PIN_D17 };
static const unsigned sysclkreq4_d_1_pins[] = { AB8540_PIN_C12 };
static const unsigned sysclkreq6_d_1_pins[] = { AB8540_PIN_G12 };
static const unsigned pwmout1_d_1_pins[] = { AB8540_PIN_D16 };
static const unsigned pwmout2_d_1_pins[] = { AB8540_PIN_F15 };
static const unsigned pwmout3_d_1_pins[] = { AB8540_PIN_J8 };
/* audio data interface 1*/
static const unsigned adi1_d_1_pins[] = { AB8540_PIN_K16, AB8540_PIN_G15,
AB8540_PIN_F17, AB8540_PIN_E17 };
/* Digital microphone 1 and 2 */
static const unsigned dmic12_d_1_pins[] = { AB8540_PIN_AA16, AB8540_PIN_W18 };
/* Digital microphone 3 and 4 */
static const unsigned dmic34_d_1_pins[] = { AB8540_PIN_Y15, AB8540_PIN_W16 };
/* Digital microphone 5 and 6 */
static const unsigned dmic56_d_1_pins[] = { AB8540_PIN_V15, AB8540_PIN_W17 };
static const unsigned sysclkreq5_d_1_pins[] = { AB8540_PIN_D12 };
static const unsigned batremn_d_1_pins[] = { AB8540_PIN_P4 };
static const unsigned service_d_1_pins[] = { AB8540_PIN_AB1 };
static const unsigned pwrctrl0_d_1_pins[] = { AB8540_PIN_K7 };
static const unsigned pwrctrl1_d_1_pins[] = { AB8540_PIN_L7 };
static const unsigned pwmextvibra1_d_1_pins[] = { AB8540_PIN_G10 };
static const unsigned pwmextvibra2_d_1_pins[] = { AB8540_PIN_K12 };
static const unsigned gpio1_vbat_d_1_pins[] = { AB8540_PIN_N8 };
static const unsigned gpio2_vbat_d_1_pins[] = { AB8540_PIN_P12 };
static const unsigned gpio3_vbat_d_1_pins[] = { AB8540_PIN_K8 };
static const unsigned gpio4_vbat_d_1_pins[] = { AB8540_PIN_J11 };
static const unsigned pdmclkdat_d_1_pins[] = { AB8540_PIN_AC2, AB8540_PIN_AB2 };
/* Altfunction A column */
static const unsigned gpio1_a_1_pins[] = { AB8540_PIN_J16 };
static const unsigned gpio2_a_1_pins[] = { AB8540_PIN_D17 };
static const unsigned gpio3_a_1_pins[] = { AB8540_PIN_C12 };
static const unsigned gpio4_a_1_pins[] = { AB8540_PIN_G12 };
static const unsigned gpio14_a_1_pins[] = { AB8540_PIN_D16 };
static const unsigned gpio15_a_1_pins[] = { AB8540_PIN_F15 };
static const unsigned gpio16_a_1_pins[] = { AB8540_PIN_J8 };
static const unsigned gpio17_a_1_pins[] = { AB8540_PIN_K16 };
static const unsigned gpio18_a_1_pins[] = { AB8540_PIN_G15 };
static const unsigned gpio19_a_1_pins[] = { AB8540_PIN_F17 };
static const unsigned gpio20_a_1_pins[] = { AB8540_PIN_E17 };
static const unsigned gpio27_a_1_pins[] = { AB8540_PIN_AA16 };
static const unsigned gpio28_a_1_pins[] = { AB8540_PIN_W18 };
static const unsigned gpio29_a_1_pins[] = { AB8540_PIN_Y15 };
static const unsigned gpio30_a_1_pins[] = { AB8540_PIN_W16 };
static const unsigned gpio31_a_1_pins[] = { AB8540_PIN_V15 };
static const unsigned gpio32_a_1_pins[] = { AB8540_PIN_W17 };
static const unsigned gpio42_a_1_pins[] = { AB8540_PIN_D12 };
static const unsigned gpio43_a_1_pins[] = { AB8540_PIN_P4 };
static const unsigned gpio44_a_1_pins[] = { AB8540_PIN_AB1 };
static const unsigned gpio45_a_1_pins[] = { AB8540_PIN_K7 };
static const unsigned gpio46_a_1_pins[] = { AB8540_PIN_L7 };
static const unsigned gpio47_a_1_pins[] = { AB8540_PIN_G10 };
static const unsigned gpio48_a_1_pins[] = { AB8540_PIN_K12 };
static const unsigned gpio51_a_1_pins[] = { AB8540_PIN_N8 };
static const unsigned gpio52_a_1_pins[] = { AB8540_PIN_P12 };
static const unsigned gpio53_a_1_pins[] = { AB8540_PIN_K8 };
static const unsigned gpio54_a_1_pins[] = { AB8540_PIN_J11 };
static const unsigned gpio55_a_1_pins[] = { AB8540_PIN_AC2 };
static const unsigned gpio56_a_1_pins[] = { AB8540_PIN_AB2 };
#define AB8540_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins, \
.npins = ARRAY_SIZE(a##_pins), .altsetting = b }
static const struct abx500_pingroup ab8540_groups[] = {
/* default column */
AB8540_PIN_GROUP(sysclkreq2_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(sysclkreq3_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(sysclkreq4_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(sysclkreq6_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(pwmout1_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(pwmout2_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(pwmout3_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(adi1_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(dmic12_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(dmic34_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(dmic56_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(sysclkreq5_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(batremn_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(service_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(pwrctrl0_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(pwrctrl1_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(pwmextvibra1_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(pwmextvibra2_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(gpio1_vbat_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(gpio2_vbat_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(gpio3_vbat_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(gpio4_vbat_d_1, ABX500_DEFAULT),
AB8540_PIN_GROUP(pdmclkdat_d_1, ABX500_DEFAULT),
/* Altfunction A column */
AB8540_PIN_GROUP(gpio1_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio2_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio3_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio4_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio14_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio15_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio16_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio17_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio18_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio19_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio20_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio27_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio28_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio29_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio30_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio31_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio32_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio42_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio43_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio44_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio45_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio46_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio47_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio48_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio51_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio52_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio53_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio54_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio55_a_1, ABX500_ALT_A),
AB8540_PIN_GROUP(gpio56_a_1, ABX500_ALT_A),
};
/* We use this macro to define the groups applicable to a function */
#define AB8540_FUNC_GROUPS(a, b...) \
static const char * const a##_groups[] = { b };
AB8540_FUNC_GROUPS(sysclkreq, "sysclkreq2_d_1", "sysclkreq3_d_1",
"sysclkreq4_d_1", "sysclkreq5_d_1", "sysclkreq6_d_1");
AB8540_FUNC_GROUPS(gpio, "gpio1_a_1", "gpio2_a_1", "gpio3_a_1", "gpio4_a_1",
"gpio14_a_1", "gpio15_a_1", "gpio16_a_1", "gpio17_a_1",
"gpio18_a_1", "gpio19_a_1", "gpio20_a_1", "gpio27_a_1",
"gpio28_a_1", "gpio29_a_1", "gpio30_a_1", "gpio31_a_1",
"gpio32_a_1", "gpio42_a_1", "gpio43_a_1", "gpio44_a_1",
"gpio45_a_1", "gpio46_a_1", "gpio47_a_1", "gpio48_a_1",
"gpio51_a_1", "gpio52_a_1", "gpio53_a_1", "gpio54_a_1",
"gpio55_a_1", "gpio56_a_1");
AB8540_FUNC_GROUPS(pwmout, "pwmout1_d_1", "pwmout2_d_1", "pwmout3_d_1");
AB8540_FUNC_GROUPS(adi1, "adi1_d_1");
AB8540_FUNC_GROUPS(dmic, "dmic12_d_1", "dmic34_d_1", "dmic56_d_1");
AB8540_FUNC_GROUPS(batremn, "batremn_d_1");
AB8540_FUNC_GROUPS(service, "service_d_1");
AB8540_FUNC_GROUPS(pwrctrl, "pwrctrl0_d_1", "pwrctrl1_d_1");
AB8540_FUNC_GROUPS(pwmextvibra, "pwmextvibra1_d_1", "pwmextvibra2_d_1");
AB8540_FUNC_GROUPS(gpio_vbat, "gpio1_vbat_d_1", "gpio2_vbat_d_1",
"gpio3_vbat_d_1", "gpio4_vbat_d_1");
AB8540_FUNC_GROUPS(pdm, "pdmclkdat_d_1");
#define FUNCTION(fname) \
{ \
.name = #fname, \
.groups = fname##_groups, \
.ngroups = ARRAY_SIZE(fname##_groups), \
}
static const struct abx500_function ab8540_functions[] = {
FUNCTION(sysclkreq),
FUNCTION(gpio),
FUNCTION(pwmout),
FUNCTION(adi1),
FUNCTION(dmic),
FUNCTION(batremn),
FUNCTION(service),
FUNCTION(pwrctrl),
FUNCTION(pwmextvibra),
FUNCTION(gpio_vbat),
FUNCTION(pdm),
};
/*
* this table translates what's is in the AB8540 specification regarding the
* balls alternate functions (as for DB, default, ALT_A, ALT_B and ALT_C).
* ALTERNATE_FUNCTIONS(GPIO_NUMBER, GPIOSEL bit, ALTERNATFUNC bit1,
* ALTERNATEFUNC bit2, ALTA val, ALTB val, ALTC val),
* AB8540 only supports DEFAULT and ALTA functions, so ALTERNATFUNC
* registers is not used
*
*/
struct alternate_functions ab8540_alternate_functions[AB8540_GPIO_MAX_NUMBER + 1] = {
/* GPIOSEL1 - bit 4-7 reserved */
ALTERNATE_FUNCTIONS(0, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO0 */
ALTERNATE_FUNCTIONS(1, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO1, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(2, 1, UNUSED, UNUSED, 0, 0, 0), /* GPIO2, altA controlled by bit 1 */
ALTERNATE_FUNCTIONS(3, 2, UNUSED, UNUSED, 0, 0, 0), /* GPIO3, altA controlled by bit 2*/
ALTERNATE_FUNCTIONS(4, 3, UNUSED, UNUSED, 0, 0, 0), /* GPIO4, altA controlled by bit 3*/
ALTERNATE_FUNCTIONS(5, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO5 */
ALTERNATE_FUNCTIONS(6, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO6 */
ALTERNATE_FUNCTIONS(7, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO7 */
ALTERNATE_FUNCTIONS(8, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO8 */
/* GPIOSEL2 - bit 0-4 reserved */
ALTERNATE_FUNCTIONS(9, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO9 */
ALTERNATE_FUNCTIONS(10, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO10 */
ALTERNATE_FUNCTIONS(11, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO11 */
ALTERNATE_FUNCTIONS(12, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO12 */
ALTERNATE_FUNCTIONS(13, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO13 */
ALTERNATE_FUNCTIONS(14, 5, UNUSED, UNUSED, 0, 0, 0), /* GPIO14, altA controlled by bit 5 */
ALTERNATE_FUNCTIONS(15, 6, UNUSED, UNUSED, 0, 0, 0), /* GPIO15, altA controlled by bit 6 */
ALTERNATE_FUNCTIONS(16, 7, UNUSED, UNUSED, 0, 0, 0), /* GPIO16, altA controlled by bit 7 */
/* GPIOSEL3 - bit 4-7 reserved */
ALTERNATE_FUNCTIONS(17, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO17, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(18, 1, UNUSED, UNUSED, 0, 0, 0), /* GPIO18, altA controlled by bit 1 */
ALTERNATE_FUNCTIONS(19, 2, UNUSED, UNUSED, 0, 0, 0), /* GPIO19, altA controlled by bit 2 */
ALTERNATE_FUNCTIONS(20, 3, UNUSED, UNUSED, 0, 0, 0), /* GPIO20, altA controlled by bit 3 */
ALTERNATE_FUNCTIONS(21, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO21 */
ALTERNATE_FUNCTIONS(22, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO22 */
ALTERNATE_FUNCTIONS(23, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO23 */
ALTERNATE_FUNCTIONS(24, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO24 */
/* GPIOSEL4 - bit 0-1 reserved */
ALTERNATE_FUNCTIONS(25, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO25 */
ALTERNATE_FUNCTIONS(26, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO26 */
ALTERNATE_FUNCTIONS(27, 2, UNUSED, UNUSED, 0, 0, 0), /* GPIO27, altA controlled by bit 2 */
ALTERNATE_FUNCTIONS(28, 3, UNUSED, UNUSED, 0, 0, 0), /* GPIO28, altA controlled by bit 3 */
ALTERNATE_FUNCTIONS(29, 4, UNUSED, UNUSED, 0, 0, 0), /* GPIO29, altA controlled by bit 4 */
ALTERNATE_FUNCTIONS(30, 5, UNUSED, UNUSED, 0, 0, 0), /* GPIO30, altA controlled by bit 5 */
ALTERNATE_FUNCTIONS(31, 6, UNUSED, UNUSED, 0, 0, 0), /* GPIO31, altA controlled by bit 6 */
ALTERNATE_FUNCTIONS(32, 7, UNUSED, UNUSED, 0, 0, 0), /* GPIO32, altA controlled by bit 7 */
/* GPIOSEL5 - bit 0-7 reserved */
ALTERNATE_FUNCTIONS(33, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO33 */
ALTERNATE_FUNCTIONS(34, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO34 */
ALTERNATE_FUNCTIONS(35, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO35 */
ALTERNATE_FUNCTIONS(36, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO36 */
ALTERNATE_FUNCTIONS(37, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO37 */
ALTERNATE_FUNCTIONS(38, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO38 */
ALTERNATE_FUNCTIONS(39, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO39 */
ALTERNATE_FUNCTIONS(40, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO40 */
/* GPIOSEL6 - bit 0 reserved */
ALTERNATE_FUNCTIONS(41, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO41 */
ALTERNATE_FUNCTIONS(42, 1, UNUSED, UNUSED, 0, 0, 0), /* GPIO42, altA controlled by bit 1 */
ALTERNATE_FUNCTIONS(43, 2, UNUSED, UNUSED, 0, 0, 0), /* GPIO43, altA controlled by bit 2 */
ALTERNATE_FUNCTIONS(44, 3, UNUSED, UNUSED, 0, 0, 0), /* GPIO44, altA controlled by bit 3 */
ALTERNATE_FUNCTIONS(45, 4, UNUSED, UNUSED, 0, 0, 0), /* GPIO45, altA controlled by bit 4 */
ALTERNATE_FUNCTIONS(46, 5, UNUSED, UNUSED, 0, 0, 0), /* GPIO46, altA controlled by bit 5 */
ALTERNATE_FUNCTIONS(47, 6, UNUSED, UNUSED, 0, 0, 0), /* GPIO47, altA controlled by bit 6 */
ALTERNATE_FUNCTIONS(48, 7, UNUSED, UNUSED, 0, 0, 0), /* GPIO48, altA controlled by bit 7 */
/* GPIOSEL7 - bit 0-1 reserved */
ALTERNATE_FUNCTIONS(49, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO49 */
ALTERNATE_FUNCTIONS(50, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO50 */
ALTERNATE_FUNCTIONS(51, 2, UNUSED, UNUSED, 0, 0, 0), /* GPIO51, altA controlled by bit 2 */
ALTERNATE_FUNCTIONS(52, 3, UNUSED, UNUSED, 0, 0, 0), /* GPIO52, altA controlled by bit 3 */
ALTERNATE_FUNCTIONS(53, 4, UNUSED, UNUSED, 0, 0, 0), /* GPIO53, altA controlled by bit 4 */
ALTERNATE_FUNCTIONS(54, 5, UNUSED, UNUSED, 0, 0, 0), /* GPIO54, altA controlled by bit 5 */
ALTERNATE_FUNCTIONS(55, 6, UNUSED, UNUSED, 0, 0, 0), /* GPIO55, altA controlled by bit 6 */
ALTERNATE_FUNCTIONS(56, 7, UNUSED, UNUSED, 0, 0, 0), /* GPIO56, altA controlled by bit 7 */
};
static struct pullud ab8540_pullud = {
.first_pin = 51, /* GPIO1_VBAT */
.last_pin = 54, /* GPIO4_VBAT */
};
/*
* For AB8540 Only some GPIOs are interrupt capable:
* GPIO43 to GPIO44
* GPIO51 to GPIO54
*/
struct abx500_gpio_irq_cluster ab8540_gpio_irq_cluster[] = {
GPIO_IRQ_CLUSTER(43, 43, AB8540_INT_GPIO43F),
GPIO_IRQ_CLUSTER(44, 44, AB8540_INT_GPIO44F),
GPIO_IRQ_CLUSTER(51, 54, AB9540_INT_GPIO51R),
};
static struct abx500_pinctrl_soc_data ab8540_soc = {
.gpio_ranges = ab8540_pinranges,
.gpio_num_ranges = ARRAY_SIZE(ab8540_pinranges),
.pins = ab8540_pins,
.npins = ARRAY_SIZE(ab8540_pins),
.functions = ab8540_functions,
.nfunctions = ARRAY_SIZE(ab8540_functions),
.groups = ab8540_groups,
.ngroups = ARRAY_SIZE(ab8540_groups),
.alternate_functions = ab8540_alternate_functions,
.pullud = &ab8540_pullud,
.gpio_irq_cluster = ab8540_gpio_irq_cluster,
.ngpio_irq_cluster = ARRAY_SIZE(ab8540_gpio_irq_cluster),
.irq_gpio_rising_offset = AB8540_INT_GPIO43R,
.irq_gpio_falling_offset = AB8540_INT_GPIO43F,
.irq_gpio_factor = 2,
};
void
abx500_pinctrl_ab8540_init(struct abx500_pinctrl_soc_data **soc)
{
*soc = &ab8540_soc;
}

View File

@ -0,0 +1,485 @@
/*
* Copyright (C) ST-Ericsson SA 2012
*
* Author: Patrice Chotard <patrice.chotard@stericsson.com> for ST-Ericsson.
*
* 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/kernel.h>
#include <linux/gpio.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/mfd/abx500/ab8500.h>
#include "pinctrl-abx500.h"
/* All the pins that can be used for GPIO and some other functions */
#define ABX500_GPIO(offset) (offset)
#define AB9540_PIN_R4 ABX500_GPIO(1)
#define AB9540_PIN_V3 ABX500_GPIO(2)
#define AB9540_PIN_T4 ABX500_GPIO(3)
#define AB9540_PIN_T5 ABX500_GPIO(4)
/* hole */
#define AB9540_PIN_B18 ABX500_GPIO(10)
#define AB9540_PIN_C18 ABX500_GPIO(11)
/* hole */
#define AB9540_PIN_D18 ABX500_GPIO(13)
#define AB9540_PIN_B19 ABX500_GPIO(14)
#define AB9540_PIN_C19 ABX500_GPIO(15)
#define AB9540_PIN_D19 ABX500_GPIO(16)
#define AB9540_PIN_R3 ABX500_GPIO(17)
#define AB9540_PIN_T2 ABX500_GPIO(18)
#define AB9540_PIN_U2 ABX500_GPIO(19)
#define AB9540_PIN_V2 ABX500_GPIO(20)
#define AB9540_PIN_N17 ABX500_GPIO(21)
#define AB9540_PIN_N16 ABX500_GPIO(22)
#define AB9540_PIN_M19 ABX500_GPIO(23)
#define AB9540_PIN_T3 ABX500_GPIO(24)
#define AB9540_PIN_W2 ABX500_GPIO(25)
/* hole */
#define AB9540_PIN_H4 ABX500_GPIO(27)
#define AB9540_PIN_F1 ABX500_GPIO(28)
#define AB9540_PIN_F4 ABX500_GPIO(29)
#define AB9540_PIN_F2 ABX500_GPIO(30)
#define AB9540_PIN_E4 ABX500_GPIO(31)
#define AB9540_PIN_F3 ABX500_GPIO(32)
/* hole */
#define AB9540_PIN_J13 ABX500_GPIO(34)
/* hole */
#define AB9540_PIN_L17 ABX500_GPIO(40)
#define AB9540_PIN_L16 ABX500_GPIO(41)
#define AB9540_PIN_W3 ABX500_GPIO(42)
#define AB9540_PIN_N4 ABX500_GPIO(50)
#define AB9540_PIN_G12 ABX500_GPIO(51)
#define AB9540_PIN_E17 ABX500_GPIO(52)
#define AB9540_PIN_D11 ABX500_GPIO(53)
#define AB9540_PIN_M18 ABX500_GPIO(54)
/* indicates the highest GPIO number */
#define AB9540_GPIO_MAX_NUMBER 54
/*
* The names of the pins are denoted by GPIO number and ball name, even
* though they can be used for other things than GPIO, this is the first
* column in the table of the data sheet and often used on schematics and
* such.
*/
static const struct pinctrl_pin_desc ab9540_pins[] = {
PINCTRL_PIN(AB9540_PIN_R4, "GPIO1_R4"),
PINCTRL_PIN(AB9540_PIN_V3, "GPIO2_V3"),
PINCTRL_PIN(AB9540_PIN_T4, "GPIO3_T4"),
PINCTRL_PIN(AB9540_PIN_T5, "GPIO4_T5"),
/* hole */
PINCTRL_PIN(AB9540_PIN_B18, "GPIO10_B18"),
PINCTRL_PIN(AB9540_PIN_C18, "GPIO11_C18"),
/* hole */
PINCTRL_PIN(AB9540_PIN_D18, "GPIO13_D18"),
PINCTRL_PIN(AB9540_PIN_B19, "GPIO14_B19"),
PINCTRL_PIN(AB9540_PIN_C19, "GPIO15_C19"),
PINCTRL_PIN(AB9540_PIN_D19, "GPIO16_D19"),
PINCTRL_PIN(AB9540_PIN_R3, "GPIO17_R3"),
PINCTRL_PIN(AB9540_PIN_T2, "GPIO18_T2"),
PINCTRL_PIN(AB9540_PIN_U2, "GPIO19_U2"),
PINCTRL_PIN(AB9540_PIN_V2, "GPIO20_V2"),
PINCTRL_PIN(AB9540_PIN_N17, "GPIO21_N17"),
PINCTRL_PIN(AB9540_PIN_N16, "GPIO22_N16"),
PINCTRL_PIN(AB9540_PIN_M19, "GPIO23_M19"),
PINCTRL_PIN(AB9540_PIN_T3, "GPIO24_T3"),
PINCTRL_PIN(AB9540_PIN_W2, "GPIO25_W2"),
/* hole */
PINCTRL_PIN(AB9540_PIN_H4, "GPIO27_H4"),
PINCTRL_PIN(AB9540_PIN_F1, "GPIO28_F1"),
PINCTRL_PIN(AB9540_PIN_F4, "GPIO29_F4"),
PINCTRL_PIN(AB9540_PIN_F2, "GPIO30_F2"),
PINCTRL_PIN(AB9540_PIN_E4, "GPIO31_E4"),
PINCTRL_PIN(AB9540_PIN_F3, "GPIO32_F3"),
/* hole */
PINCTRL_PIN(AB9540_PIN_J13, "GPIO34_J13"),
/* hole */
PINCTRL_PIN(AB9540_PIN_L17, "GPIO40_L17"),
PINCTRL_PIN(AB9540_PIN_L16, "GPIO41_L16"),
PINCTRL_PIN(AB9540_PIN_W3, "GPIO42_W3"),
PINCTRL_PIN(AB9540_PIN_N4, "GPIO50_N4"),
PINCTRL_PIN(AB9540_PIN_G12, "GPIO51_G12"),
PINCTRL_PIN(AB9540_PIN_E17, "GPIO52_E17"),
PINCTRL_PIN(AB9540_PIN_D11, "GPIO53_D11"),
PINCTRL_PIN(AB9540_PIN_M18, "GPIO60_M18"),
};
/*
* Maps local GPIO offsets to local pin numbers
*/
static const struct abx500_pinrange ab9540_pinranges[] = {
ABX500_PINRANGE(1, 4, ABX500_ALT_A),
ABX500_PINRANGE(10, 2, ABX500_DEFAULT),
ABX500_PINRANGE(13, 1, ABX500_DEFAULT),
ABX500_PINRANGE(14, 12, ABX500_ALT_A),
ABX500_PINRANGE(27, 6, ABX500_ALT_A),
ABX500_PINRANGE(34, 1, ABX500_ALT_A),
ABX500_PINRANGE(40, 3, ABX500_ALT_A),
ABX500_PINRANGE(50, 1, ABX500_DEFAULT),
ABX500_PINRANGE(51, 3, ABX500_ALT_A),
ABX500_PINRANGE(54, 1, ABX500_DEFAULT),
};
/*
* Read the pin group names like this:
* sysclkreq2_d_1 = first groups of pins for sysclkreq2 on default function
*
* The groups are arranged as sets per altfunction column, so we can
* mux in one group at a time by selecting the same altfunction for them
* all. When functions require pins on different altfunctions, you need
* to combine several groups.
*/
/* default column */
static const unsigned sysclkreq2_d_1_pins[] = { AB9540_PIN_R4 };
static const unsigned sysclkreq3_d_1_pins[] = { AB9540_PIN_V3 };
static const unsigned sysclkreq4_d_1_pins[] = { AB9540_PIN_T4 };
static const unsigned sysclkreq6_d_1_pins[] = { AB9540_PIN_T5 };
static const unsigned gpio10_d_1_pins[] = { AB9540_PIN_B18 };
static const unsigned gpio11_d_1_pins[] = { AB9540_PIN_C18 };
static const unsigned gpio13_d_1_pins[] = { AB9540_PIN_D18 };
static const unsigned pwmout1_d_1_pins[] = { AB9540_PIN_B19 };
static const unsigned pwmout2_d_1_pins[] = { AB9540_PIN_C19 };
static const unsigned pwmout3_d_1_pins[] = { AB9540_PIN_D19 };
/* audio data interface 1*/
static const unsigned adi1_d_1_pins[] = { AB9540_PIN_R3, AB9540_PIN_T2,
AB9540_PIN_U2, AB9540_PIN_V2 };
/* USBUICC */
static const unsigned usbuicc_d_1_pins[] = { AB9540_PIN_N17, AB9540_PIN_N16,
AB9540_PIN_M19 };
static const unsigned sysclkreq7_d_1_pins[] = { AB9540_PIN_T3 };
static const unsigned sysclkreq8_d_1_pins[] = { AB9540_PIN_W2 };
/* Digital microphone 1 and 2 */
static const unsigned dmic12_d_1_pins[] = { AB9540_PIN_H4, AB9540_PIN_F1 };
/* Digital microphone 3 and 4 */
static const unsigned dmic34_d_1_pins[] = { AB9540_PIN_F4, AB9540_PIN_F2 };
/* Digital microphone 5 and 6 */
static const unsigned dmic56_d_1_pins[] = { AB9540_PIN_E4, AB9540_PIN_F3 };
static const unsigned extcpena_d_1_pins[] = { AB9540_PIN_J13 };
/* modem SDA/SCL */
static const unsigned modsclsda_d_1_pins[] = { AB9540_PIN_L17, AB9540_PIN_L16 };
static const unsigned sysclkreq5_d_1_pins[] = { AB9540_PIN_W3 };
static const unsigned gpio50_d_1_pins[] = { AB9540_PIN_N4 };
static const unsigned batremn_d_1_pins[] = { AB9540_PIN_G12 };
static const unsigned resethw_d_1_pins[] = { AB9540_PIN_E17 };
static const unsigned service_d_1_pins[] = { AB9540_PIN_D11 };
static const unsigned gpio60_d_1_pins[] = { AB9540_PIN_M18 };
/* Altfunction A column */
static const unsigned gpio1_a_1_pins[] = { AB9540_PIN_R4 };
static const unsigned gpio2_a_1_pins[] = { AB9540_PIN_V3 };
static const unsigned gpio3_a_1_pins[] = { AB9540_PIN_T4 };
static const unsigned gpio4_a_1_pins[] = { AB9540_PIN_T5 };
static const unsigned hiqclkena_a_1_pins[] = { AB9540_PIN_B18 };
static const unsigned pdmclk_a_1_pins[] = { AB9540_PIN_C18 };
static const unsigned uartdata_a_1_pins[] = { AB9540_PIN_D18, AB9540_PIN_N4 };
static const unsigned gpio14_a_1_pins[] = { AB9540_PIN_B19 };
static const unsigned gpio15_a_1_pins[] = { AB9540_PIN_C19 };
static const unsigned gpio16_a_1_pins[] = { AB9540_PIN_D19 };
static const unsigned gpio17_a_1_pins[] = { AB9540_PIN_R3 };
static const unsigned gpio18_a_1_pins[] = { AB9540_PIN_T2 };
static const unsigned gpio19_a_1_pins[] = { AB9540_PIN_U2 };
static const unsigned gpio20_a_1_pins[] = { AB9540_PIN_V2 };
static const unsigned gpio21_a_1_pins[] = { AB9540_PIN_N17 };
static const unsigned gpio22_a_1_pins[] = { AB9540_PIN_N16 };
static const unsigned gpio23_a_1_pins[] = { AB9540_PIN_M19 };
static const unsigned gpio24_a_1_pins[] = { AB9540_PIN_T3 };
static const unsigned gpio25_a_1_pins[] = { AB9540_PIN_W2 };
static const unsigned gpio27_a_1_pins[] = { AB9540_PIN_H4 };
static const unsigned gpio28_a_1_pins[] = { AB9540_PIN_F1 };
static const unsigned gpio29_a_1_pins[] = { AB9540_PIN_F4 };
static const unsigned gpio30_a_1_pins[] = { AB9540_PIN_F2 };
static const unsigned gpio31_a_1_pins[] = { AB9540_PIN_E4 };
static const unsigned gpio32_a_1_pins[] = { AB9540_PIN_F3 };
static const unsigned gpio34_a_1_pins[] = { AB9540_PIN_J13 };
static const unsigned gpio40_a_1_pins[] = { AB9540_PIN_L17 };
static const unsigned gpio41_a_1_pins[] = { AB9540_PIN_L16 };
static const unsigned gpio42_a_1_pins[] = { AB9540_PIN_W3 };
static const unsigned gpio51_a_1_pins[] = { AB9540_PIN_G12 };
static const unsigned gpio52_a_1_pins[] = { AB9540_PIN_E17 };
static const unsigned gpio53_a_1_pins[] = { AB9540_PIN_D11 };
static const unsigned usbuiccpd_a_1_pins[] = { AB9540_PIN_M18 };
/* Altfunction B colum */
static const unsigned pdmdata_b_1_pins[] = { AB9540_PIN_B18 };
static const unsigned pwmextvibra1_b_1_pins[] = { AB9540_PIN_D18 };
static const unsigned pwmextvibra2_b_1_pins[] = { AB9540_PIN_N4 };
/* Altfunction C column */
static const unsigned usbvdat_c_1_pins[] = { AB9540_PIN_D18 };
#define AB9540_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins, \
.npins = ARRAY_SIZE(a##_pins), .altsetting = b }
static const struct abx500_pingroup ab9540_groups[] = {
/* default column */
AB9540_PIN_GROUP(sysclkreq2_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(sysclkreq3_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(sysclkreq4_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(sysclkreq6_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(gpio10_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(gpio11_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(gpio13_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(pwmout1_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(pwmout2_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(pwmout3_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(adi1_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(usbuicc_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(sysclkreq7_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(sysclkreq8_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(dmic12_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(dmic34_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(dmic56_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(extcpena_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(modsclsda_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(sysclkreq5_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(gpio50_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(batremn_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(resethw_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(service_d_1, ABX500_DEFAULT),
AB9540_PIN_GROUP(gpio60_d_1, ABX500_DEFAULT),
/* Altfunction A column */
AB9540_PIN_GROUP(gpio1_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio2_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio3_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio4_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(hiqclkena_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(pdmclk_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(uartdata_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio14_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio15_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio16_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio17_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio18_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio19_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio20_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio21_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio22_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio23_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio24_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio25_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio27_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio28_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio29_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio30_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio31_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio32_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio34_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio40_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio41_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio42_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio51_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio52_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(gpio53_a_1, ABX500_ALT_A),
AB9540_PIN_GROUP(usbuiccpd_a_1, ABX500_ALT_A),
/* Altfunction B column */
AB9540_PIN_GROUP(pdmdata_b_1, ABX500_ALT_B),
AB9540_PIN_GROUP(pwmextvibra1_b_1, ABX500_ALT_B),
AB9540_PIN_GROUP(pwmextvibra2_b_1, ABX500_ALT_B),
/* Altfunction C column */
AB9540_PIN_GROUP(usbvdat_c_1, ABX500_ALT_C),
};
/* We use this macro to define the groups applicable to a function */
#define AB9540_FUNC_GROUPS(a, b...) \
static const char * const a##_groups[] = { b };
AB9540_FUNC_GROUPS(sysclkreq, "sysclkreq2_d_1", "sysclkreq3_d_1",
"sysclkreq4_d_1", "sysclkreq5_d_1", "sysclkreq6_d_1",
"sysclkreq7_d_1", "sysclkreq8_d_1");
AB9540_FUNC_GROUPS(gpio, "gpio1_a_1", "gpio2_a_1", "gpio3_a_1", "gpio4_a_1",
"gpio10_d_1", "gpio11_d_1", "gpio13_d_1", "gpio14_a_1",
"gpio15_a_1", "gpio16_a_1", "gpio17_a_1", "gpio18_a_1",
"gpio19_a_1", "gpio20_a_1", "gpio21_a_1", "gpio22_a_1",
"gpio23_a_1", "gpio24_a_1", "gpio25_a_1", "gpio27_a_1",
"gpio28_a_1", "gpio29_a_1", "gpio30_a_1", "gpio31_a_1",
"gpio32_a_1", "gpio34_a_1", "gpio40_a_1", "gpio41_a_1",
"gpio42_a_1", "gpio50_d_1", "gpio51_a_1", "gpio52_a_1",
"gpio53_a_1", "gpio60_d_1");
AB9540_FUNC_GROUPS(pwmout, "pwmout1_d_1", "pwmout2_d_1", "pwmout3_d_1");
AB9540_FUNC_GROUPS(adi1, "adi1_d_1");
AB9540_FUNC_GROUPS(usbuicc, "usbuicc_d_1", "usbuiccpd_a_1");
AB9540_FUNC_GROUPS(dmic, "dmic12_d_1", "dmic34_d_1", "dmic56_d_1");
AB9540_FUNC_GROUPS(extcpena, "extcpena_d_1");
AB9540_FUNC_GROUPS(modsclsda, "modsclsda_d_1");
AB9540_FUNC_GROUPS(batremn, "batremn_d_1");
AB9540_FUNC_GROUPS(resethw, "resethw_d_1");
AB9540_FUNC_GROUPS(service, "service_d_1");
AB9540_FUNC_GROUPS(hiqclkena, "hiqclkena_a_1");
AB9540_FUNC_GROUPS(pdm, "pdmdata_b_1", "pdmclk_a_1");
AB9540_FUNC_GROUPS(uartdata, "uartdata_a_1");
AB9540_FUNC_GROUPS(pwmextvibra, "pwmextvibra1_b_1", "pwmextvibra2_b_1");
AB9540_FUNC_GROUPS(usbvdat, "usbvdat_c_1");
#define FUNCTION(fname) \
{ \
.name = #fname, \
.groups = fname##_groups, \
.ngroups = ARRAY_SIZE(fname##_groups), \
}
static const struct abx500_function ab9540_functions[] = {
FUNCTION(sysclkreq),
FUNCTION(gpio),
FUNCTION(pwmout),
FUNCTION(adi1),
FUNCTION(usbuicc),
FUNCTION(dmic),
FUNCTION(extcpena),
FUNCTION(modsclsda),
FUNCTION(batremn),
FUNCTION(resethw),
FUNCTION(service),
FUNCTION(hiqclkena),
FUNCTION(pdm),
FUNCTION(uartdata),
FUNCTION(pwmextvibra),
FUNCTION(usbvdat),
};
/*
* this table translates what's is in the AB9540 specification regarding the
* balls alternate functions (as for DB, default, ALT_A, ALT_B and ALT_C).
* ALTERNATE_FUNCTIONS(GPIO_NUMBER, GPIOSEL bit, ALTERNATFUNC bit1,
* ALTERNATEFUNC bit2, ALTA val, ALTB val, ALTC val),
*
* example :
*
* ALTERNATE_FUNCTIONS(13, 4, 3, 4, 1, 0, 2),
* means that pin AB9540_PIN_D18 (pin 13) supports 4 mux (default/ALT_A,
* ALT_B and ALT_C), so GPIOSEL and ALTERNATFUNC registers are used to
* select the mux. ALTA, ALTB and ALTC val indicates values to write in
* ALTERNATFUNC register. We need to specifies these values as SOC
* designers didn't apply the same logic on how to select mux in the
* ABx500 family.
*
* As this pins supports at least ALT_B mux, default mux is
* selected by writing 1 in GPIOSEL bit :
*
* | GPIOSEL bit=4 | alternatfunc bit2=4 | alternatfunc bit1=3
* default | 1 | 0 | 0
* alt_A | 0 | 0 | 1
* alt_B | 0 | 0 | 0
* alt_C | 0 | 1 | 0
*
* ALTERNATE_FUNCTIONS(1, 0, UNUSED, UNUSED),
* means that pin AB9540_PIN_R4 (pin 1) supports 2 mux, so only GPIOSEL
* register is used to select the mux. As this pins doesn't support at
* least ALT_B mux, default mux is by writing 0 in GPIOSEL bit :
*
* | GPIOSEL bit=0 | alternatfunc bit2= | alternatfunc bit1=
* default | 0 | 0 | 0
* alt_A | 1 | 0 | 0
*/
struct alternate_functions ab9540alternate_functions[AB9540_GPIO_MAX_NUMBER + 1] = {
/* GPIOSEL1 - bits 4-7 are reserved */
ALTERNATE_FUNCTIONS(0, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO0 */
ALTERNATE_FUNCTIONS(1, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO1, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(2, 1, UNUSED, UNUSED, 0, 0, 0), /* GPIO2, altA controlled by bit 1 */
ALTERNATE_FUNCTIONS(3, 2, UNUSED, UNUSED, 0, 0, 0), /* GPIO3, altA controlled by bit 2*/
ALTERNATE_FUNCTIONS(4, 3, UNUSED, UNUSED, 0, 0, 0), /* GPIO4, altA controlled by bit 3*/
ALTERNATE_FUNCTIONS(5, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO5 */
ALTERNATE_FUNCTIONS(6, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO6 */
ALTERNATE_FUNCTIONS(7, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO7 */
ALTERNATE_FUNCTIONS(8, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO8 */
/* GPIOSEL2 - bits 0 and 3 are reserved */
ALTERNATE_FUNCTIONS(9, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO9 */
ALTERNATE_FUNCTIONS(10, 1, 0, UNUSED, 1, 0, 0), /* GPIO10, altA and altB controlled by bit 0 */
ALTERNATE_FUNCTIONS(11, 2, UNUSED, UNUSED, 0, 0, 0), /* GPIO11, altA controlled by bit 1 */
ALTERNATE_FUNCTIONS(12, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO12 */
ALTERNATE_FUNCTIONS(13, 4, 3, 4, 1, 0, 2), /* GPIO13, altA altB and altC controlled by bit 3 and 4 */
ALTERNATE_FUNCTIONS(14, 5, UNUSED, UNUSED, 0, 0, 0), /* GPIO14, altA controlled by bit 5 */
ALTERNATE_FUNCTIONS(15, 6, UNUSED, UNUSED, 0, 0, 0), /* GPIO15, altA controlled by bit 6 */
ALTERNATE_FUNCTIONS(16, 7, UNUSED, UNUSED, 0, 0, 0), /* GPIO16, altA controlled by bit 7 */
/* GPIOSEL3 - bit 1-3 reserved
* pins 17 to 20 are special case, only bit 0 is used to select
* alternate function for these 4 pins.
* bits 1 to 3 are reserved
*/
ALTERNATE_FUNCTIONS(17, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO17, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(18, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO18, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(19, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO19, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(20, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO20, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(21, 4, UNUSED, UNUSED, 0, 0, 0), /* GPIO21, altA controlled by bit 4 */
ALTERNATE_FUNCTIONS(22, 5, UNUSED, UNUSED, 0, 0, 0), /* GPIO22, altA controlled by bit 5 */
ALTERNATE_FUNCTIONS(23, 6, UNUSED, UNUSED, 0, 0, 0), /* GPIO23, altA controlled by bit 6 */
ALTERNATE_FUNCTIONS(24, 7, UNUSED, UNUSED, 0, 0, 0), /* GPIO24, altA controlled by bit 7 */
/* GPIOSEL4 - bit 1 reserved */
ALTERNATE_FUNCTIONS(25, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO25, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(26, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO26 */
ALTERNATE_FUNCTIONS(27, 2, UNUSED, UNUSED, 0, 0, 0), /* GPIO27, altA controlled by bit 2 */
ALTERNATE_FUNCTIONS(28, 3, UNUSED, UNUSED, 0, 0, 0), /* GPIO28, altA controlled by bit 3 */
ALTERNATE_FUNCTIONS(29, 4, UNUSED, UNUSED, 0, 0, 0), /* GPIO29, altA controlled by bit 4 */
ALTERNATE_FUNCTIONS(30, 5, UNUSED, UNUSED, 0, 0, 0), /* GPIO30, altA controlled by bit 5 */
ALTERNATE_FUNCTIONS(31, 6, UNUSED, UNUSED, 0, 0, 0), /* GPIO31, altA controlled by bit 6 */
ALTERNATE_FUNCTIONS(32, 7, UNUSED, UNUSED, 0, 0, 0), /* GPIO32, altA controlled by bit 7 */
/* GPIOSEL5 - bit 0, 2-6 are reserved */
ALTERNATE_FUNCTIONS(33, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO33 */
ALTERNATE_FUNCTIONS(34, 1, UNUSED, UNUSED, 0, 0, 0), /* GPIO34, altA controlled by bit 1 */
ALTERNATE_FUNCTIONS(35, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO35 */
ALTERNATE_FUNCTIONS(36, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO36 */
ALTERNATE_FUNCTIONS(37, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO37 */
ALTERNATE_FUNCTIONS(38, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO38 */
ALTERNATE_FUNCTIONS(39, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO39 */
ALTERNATE_FUNCTIONS(40, 7, UNUSED, UNUSED, 0, 0, 0), /* GPIO40, altA controlled by bit 7 */
/* GPIOSEL6 - bit 2-7 are reserved */
ALTERNATE_FUNCTIONS(41, 0, UNUSED, UNUSED, 0, 0, 0), /* GPIO41, altA controlled by bit 0 */
ALTERNATE_FUNCTIONS(42, 1, UNUSED, UNUSED, 0, 0, 0), /* GPIO42, altA controlled by bit 1 */
ALTERNATE_FUNCTIONS(43, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO43 */
ALTERNATE_FUNCTIONS(44, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO44 */
ALTERNATE_FUNCTIONS(45, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO45 */
ALTERNATE_FUNCTIONS(46, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO46 */
ALTERNATE_FUNCTIONS(47, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO47 */
ALTERNATE_FUNCTIONS(48, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO48 */
/*
* GPIOSEL7 - bit 0 and 6-7 are reserved
* special case with GPIO60, wich is located at offset 5 of gpiosel7
* don't know why it has been called GPIO60 in AB9540 datasheet,
* GPIO54 would be logical..., so at SOC point of view we consider
* GPIO60 = GPIO54
*/
ALTERNATE_FUNCTIONS(49, 0, UNUSED, UNUSED, 0, 0, 0), /* no GPIO49 */
ALTERNATE_FUNCTIONS(50, 1, 2, UNUSED, 1, 0, 0), /* GPIO50, altA and altB controlled by bit 1 */
ALTERNATE_FUNCTIONS(51, 2, UNUSED, UNUSED, 0, 0, 0), /* GPIO51, altA controlled by bit 2 */
ALTERNATE_FUNCTIONS(52, 3, UNUSED, UNUSED, 0, 0, 0), /* GPIO52, altA controlled by bit 3 */
ALTERNATE_FUNCTIONS(53, 4, UNUSED, UNUSED, 0, 0, 0), /* GPIO53, altA controlled by bit 4 */
ALTERNATE_FUNCTIONS(54, 5, UNUSED, UNUSED, 0, 0, 0), /* GPIO54 = GPIO60, altA controlled by bit 5 */
};
struct abx500_gpio_irq_cluster ab9540_gpio_irq_cluster[] = {
GPIO_IRQ_CLUSTER(10, 13, AB8500_INT_GPIO10R),
GPIO_IRQ_CLUSTER(24, 25, AB8500_INT_GPIO24R),
GPIO_IRQ_CLUSTER(40, 41, AB8500_INT_GPIO40R),
GPIO_IRQ_CLUSTER(50, 54, AB9540_INT_GPIO50R),
};
static struct abx500_pinctrl_soc_data ab9540_soc = {
.gpio_ranges = ab9540_pinranges,
.gpio_num_ranges = ARRAY_SIZE(ab9540_pinranges),
.pins = ab9540_pins,
.npins = ARRAY_SIZE(ab9540_pins),
.functions = ab9540_functions,
.nfunctions = ARRAY_SIZE(ab9540_functions),
.groups = ab9540_groups,
.ngroups = ARRAY_SIZE(ab9540_groups),
.alternate_functions = ab9540alternate_functions,
.gpio_irq_cluster = ab9540_gpio_irq_cluster,
.ngpio_irq_cluster = ARRAY_SIZE(ab9540_gpio_irq_cluster),
.irq_gpio_rising_offset = AB8500_INT_GPIO6R,
.irq_gpio_falling_offset = AB8500_INT_GPIO6F,
.irq_gpio_factor = 1,
};
void
abx500_pinctrl_ab9540_init(struct abx500_pinctrl_soc_data **soc)
{
*soc = &ab9540_soc;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,234 @@
#ifndef PINCTRL_PINCTRL_ABx5O0_H
#define PINCTRL_PINCTRL_ABx500_H
/* Package definitions */
#define PINCTRL_AB8500 0
#define PINCTRL_AB8540 1
#define PINCTRL_AB9540 2
#define PINCTRL_AB8505 3
/* pins alternate function */
enum abx500_pin_func {
ABX500_DEFAULT,
ABX500_ALT_A,
ABX500_ALT_B,
ABX500_ALT_C,
};
/**
* struct abx500_function - ABx500 pinctrl mux function
* @name: The name of the function, exported to pinctrl core.
* @groups: An array of pin groups that may select this function.
* @ngroups: The number of entries in @groups.
*/
struct abx500_function {
const char *name;
const char * const *groups;
unsigned ngroups;
};
/**
* struct abx500_pingroup - describes a ABx500 pin group
* @name: the name of this specific pin group
* @pins: an array of discrete physical pins used in this group, taken
* from the driver-local pin enumeration space
* @num_pins: the number of pins in this group array, i.e. the number of
* elements in .pins so we can iterate over that array
* @altsetting: the altsetting to apply to all pins in this group to
* configure them to be used by a function
*/
struct abx500_pingroup {
const char *name;
const unsigned int *pins;
const unsigned npins;
int altsetting;
};
#define ALTERNATE_FUNCTIONS(pin, sel_bit, alt1, alt2, alta, altb, altc) \
{ \
.pin_number = pin, \
.gpiosel_bit = sel_bit, \
.alt_bit1 = alt1, \
.alt_bit2 = alt2, \
.alta_val = alta, \
.altb_val = altb, \
.altc_val = altc, \
}
#define UNUSED -1
/**
* struct alternate_functions
* @pin_number: The pin number
* @gpiosel_bit: Control bit in GPIOSEL register,
* @alt_bit1: First AlternateFunction bit used to select the
* alternate function
* @alt_bit2: Second AlternateFunction bit used to select the
* alternate function
*
* these 3 following fields are necessary due to none
* coherency on how to select the altA, altB and altC
* function between the ABx500 SOC family when using
* alternatfunc register.
* @alta_val: value to write in alternatfunc to select altA function
* @altb_val: value to write in alternatfunc to select altB function
* @altc_val: value to write in alternatfunc to select altC function
*/
struct alternate_functions {
unsigned pin_number;
s8 gpiosel_bit;
s8 alt_bit1;
s8 alt_bit2;
u8 alta_val;
u8 altb_val;
u8 altc_val;
};
/**
* struct pullud - specific pull up/down feature
* @first_pin: The pin number of the first pins which support
* specific pull up/down
* @last_pin: The pin number of the last pins
*/
struct pullud {
unsigned first_pin;
unsigned last_pin;
};
#define GPIO_IRQ_CLUSTER(a, b, c) \
{ \
.start = a, \
.end = b, \
.to_irq = c, \
}
/**
* struct abx500_gpio_irq_cluster - indicates GPIOs which are interrupt
* capable
* @start: The pin number of the first pin interrupt capable
* @end: The pin number of the last pin interrupt capable
* @to_irq: The ABx500 GPIO's associated IRQs are clustered
* together throughout the interrupt numbers at irregular
* intervals. To solve this quandary, we will place the
* read-in values into the cluster information table
*/
struct abx500_gpio_irq_cluster {
int start;
int end;
int to_irq;
};
/**
* struct abx500_pinrange - map pin numbers to GPIO offsets
* @offset: offset into the GPIO local numberspace, incidentally
* identical to the offset into the local pin numberspace
* @npins: number of pins to map from both offsets
* @altfunc: altfunc setting to be used to enable GPIO on a pin in
* this range (may vary)
*/
struct abx500_pinrange {
unsigned int offset;
unsigned int npins;
int altfunc;
};
#define ABX500_PINRANGE(a, b, c) { .offset = a, .npins = b, .altfunc = c }
/**
* struct abx500_pinctrl_soc_data - ABx500 pin controller per-SoC configuration
* @gpio_ranges: An array of GPIO ranges for this SoC
* @gpio_num_ranges: The number of GPIO ranges for this SoC
* @pins: An array describing all pins the pin controller affects.
* All pins which are also GPIOs must be listed first within the
* array, and be numbered identically to the GPIO controller's
* numbering.
* @npins: The number of entries in @pins.
* @functions: The functions supported on this SoC.
* @nfunction: The number of entries in @functions.
* @groups: An array describing all pin groups the pin SoC supports.
* @ngroups: The number of entries in @groups.
* @alternate_functions: array describing pins which supports alternate and
* how to set it.
* @pullud: array describing pins which supports pull up/down
* specific registers.
* @gpio_irq_cluster: An array of GPIO interrupt capable for this SoC
* @ngpio_irq_cluster: The number of GPIO inetrrupt capable for this SoC
* @irq_gpio_rising_offset: Interrupt offset used as base to compute specific
* setting strategy of the rising interrupt line
* @irq_gpio_falling_offset: Interrupt offset used as base to compute specific
* setting strategy of the falling interrupt line
* @irq_gpio_factor: Factor used to compute specific setting strategy of
* the interrupt line
*/
struct abx500_pinctrl_soc_data {
const struct abx500_pinrange *gpio_ranges;
unsigned gpio_num_ranges;
const struct pinctrl_pin_desc *pins;
unsigned npins;
const struct abx500_function *functions;
unsigned nfunctions;
const struct abx500_pingroup *groups;
unsigned ngroups;
struct alternate_functions *alternate_functions;
struct pullud *pullud;
struct abx500_gpio_irq_cluster *gpio_irq_cluster;
unsigned ngpio_irq_cluster;
int irq_gpio_rising_offset;
int irq_gpio_falling_offset;
int irq_gpio_factor;
};
#ifdef CONFIG_PINCTRL_AB8500
void abx500_pinctrl_ab8500_init(struct abx500_pinctrl_soc_data **soc);
#else
static inline void
abx500_pinctrl_ab8500_init(struct abx500_pinctrl_soc_data **soc)
{
}
#endif
#ifdef CONFIG_PINCTRL_AB8540
void abx500_pinctrl_ab8540_init(struct abx500_pinctrl_soc_data **soc);
#else
static inline void
abx500_pinctrl_ab8540_init(struct abx500_pinctrl_soc_data **soc)
{
}
#endif
#ifdef CONFIG_PINCTRL_AB9540
void abx500_pinctrl_ab9540_init(struct abx500_pinctrl_soc_data **soc);
#else
static inline void
abx500_pinctrl_ab9540_init(struct abx500_pinctrl_soc_data **soc)
{
}
#endif
#ifdef CONFIG_PINCTRL_AB8505
void abx500_pinctrl_ab8505_init(struct abx500_pinctrl_soc_data **soc);
#else
static inline void
abx500_pinctrl_ab8505_init(struct abx500_pinctrl_soc_data **soc)
{
}
#endif
#endif /* PINCTRL_PINCTRL_ABx500_H */

View File

@ -170,7 +170,7 @@ static const unsigned pins_ntr[] = {GPIO4};
static const unsigned pins_ntr8k[] = {GPIO5};
static const unsigned pins_hrst[] = {GPIO6};
static const unsigned pins_mdio[] = {GPIO7, GPIO8};
static const unsigned pins_bled[] = {GPIO7, GPIO10, GPIO11,
static const unsigned pins_bled[] = {GPIO9, GPIO10, GPIO11,
GPIO12, GPIO13, GPIO14};
static const unsigned pins_asc0[] = {GPIO32, GPIO33};
static const unsigned pins_spi[] = {GPIO34, GPIO35, GPIO36};
@ -315,6 +315,37 @@ static int falcon_pinconf_set(struct pinctrl_dev *pctrldev,
static void falcon_pinconf_dbg_show(struct pinctrl_dev *pctrldev,
struct seq_file *s, unsigned offset)
{
unsigned long config;
struct pin_desc *desc;
struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
int port = PORT(offset);
seq_printf(s, " (port %d) mux %d -- ", port,
pad_r32(info->membase[port], LTQ_PADC_MUX(PORT_PIN(offset))));
config = LTQ_PINCONF_PACK(LTQ_PINCONF_PARAM_PULL, 0);
if (!falcon_pinconf_get(pctrldev, offset, &config))
seq_printf(s, "pull %d ",
(int)LTQ_PINCONF_UNPACK_ARG(config));
config = LTQ_PINCONF_PACK(LTQ_PINCONF_PARAM_DRIVE_CURRENT, 0);
if (!falcon_pinconf_get(pctrldev, offset, &config))
seq_printf(s, "drive-current %d ",
(int)LTQ_PINCONF_UNPACK_ARG(config));
config = LTQ_PINCONF_PACK(LTQ_PINCONF_PARAM_SLEW_RATE, 0);
if (!falcon_pinconf_get(pctrldev, offset, &config))
seq_printf(s, "slew-rate %d ",
(int)LTQ_PINCONF_UNPACK_ARG(config));
desc = pin_desc_get(pctrldev, offset);
if (desc) {
if (desc->gpio_owner)
seq_printf(s, " owner: %s", desc->gpio_owner);
} else {
seq_printf(s, " not registered");
}
}
static void falcon_pinconf_group_dbg_show(struct pinctrl_dev *pctrldev,
@ -360,6 +391,8 @@ static const struct ltq_cfg_param falcon_cfg_params[] = {
static struct ltq_pinmux_info falcon_info = {
.desc = &falcon_pctrl_desc,
.apply_mux = falcon_mux_apply,
.params = falcon_cfg_params,
.num_params = ARRAY_SIZE(falcon_cfg_params),
};
@ -398,6 +431,9 @@ static int pinctrl_falcon_probe(struct platform_device *pdev)
u32 avail;
int pins;
if (!of_device_is_available(np))
continue;
if (!ppdev) {
dev_err(&pdev->dev, "failed to find pad pdev\n");
continue;

View File

@ -64,11 +64,13 @@ static void ltq_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
seq_printf(s, " %s", dev_name(pctldev->dev));
}
static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
static void ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
struct device_node *np,
struct pinctrl_map **map)
{
struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
struct property *pins = of_find_property(np, "lantiq,pins", NULL);
struct property *groups = of_find_property(np, "lantiq,groups", NULL);
unsigned long configs[3];
unsigned num_configs = 0;
struct property *prop;
@ -76,8 +78,20 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
const char *function;
int ret, i;
if (!pins && !groups) {
dev_err(pctldev->dev, "%s defines neither pins nor groups\n",
np->name);
return;
}
if (pins && groups) {
dev_err(pctldev->dev, "%s defines both pins and groups\n",
np->name);
return;
}
ret = of_property_read_string(np, "lantiq,function", &function);
if (!ret) {
if (groups && !ret) {
of_property_for_each_string(np, "lantiq,groups", prop, group) {
(*map)->type = PIN_MAP_TYPE_MUX_GROUP;
(*map)->name = function;
@ -85,11 +99,6 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
(*map)->data.mux.function = function;
(*map)++;
}
if (of_find_property(np, "lantiq,pins", NULL))
dev_err(pctldev->dev,
"%s mixes pins and groups settings\n",
np->name);
return 0;
}
for (i = 0; i < info->num_params; i++) {
@ -103,7 +112,7 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
}
if (!num_configs)
return -EINVAL;
return;
of_property_for_each_string(np, "lantiq,pins", prop, pin) {
(*map)->data.configs.configs = kmemdup(configs,
@ -115,7 +124,16 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
(*map)->data.configs.num_configs = num_configs;
(*map)++;
}
return 0;
of_property_for_each_string(np, "lantiq,groups", prop, group) {
(*map)->data.configs.configs = kmemdup(configs,
num_configs * sizeof(unsigned long),
GFP_KERNEL);
(*map)->type = PIN_MAP_TYPE_CONFIGS_GROUP;
(*map)->name = group;
(*map)->data.configs.group_or_pin = group;
(*map)->data.configs.num_configs = num_configs;
(*map)++;
}
}
static int ltq_pinctrl_dt_subnode_size(struct device_node *np)
@ -135,23 +153,19 @@ static int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
{
struct pinctrl_map *tmp;
struct device_node *np;
int ret;
int max_maps = 0;
*num_maps = 0;
for_each_child_of_node(np_config, np)
*num_maps += ltq_pinctrl_dt_subnode_size(np);
*map = kzalloc(*num_maps * sizeof(struct pinctrl_map), GFP_KERNEL);
max_maps += ltq_pinctrl_dt_subnode_size(np);
*map = kzalloc(max_maps * sizeof(struct pinctrl_map) * 2, GFP_KERNEL);
if (!*map)
return -ENOMEM;
tmp = *map;
for_each_child_of_node(np_config, np) {
ret = ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
if (ret < 0) {
ltq_pinctrl_dt_free_map(pctldev, *map, *num_maps);
return ret;
}
}
for_each_child_of_node(np_config, np)
ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
*num_maps = ((int)(tmp - *map));
return 0;
}
@ -280,7 +294,7 @@ static int ltq_pmx_gpio_request_enable(struct pinctrl_dev *pctrldev,
unsigned pin)
{
struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
int mfp = match_mfp(info, pin + (range->id * 32));
int mfp = match_mfp(info, pin);
int pin_func;
if (mfp < 0) {

View File

@ -34,6 +34,7 @@ enum ltq_pinconf_param {
LTQ_PINCONF_PARAM_OPEN_DRAIN,
LTQ_PINCONF_PARAM_DRIVE_CURRENT,
LTQ_PINCONF_PARAM_SLEW_RATE,
LTQ_PINCONF_PARAM_OUTPUT,
};
struct ltq_cfg_param {

View File

@ -25,6 +25,8 @@
#include <linux/irqdomain.h>
#include <linux/slab.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
@ -32,8 +34,8 @@
#include <linux/pinctrl/consumer.h>
#include <linux/platform_data/pinctrl-nomadik.h>
#include <asm/mach/irq.h>
#include <mach/irqs.h>
#include "pinctrl-nomadik.h"
#include "core.h"
/*
* The GPIO module in the Nomadik family of Systems-on-Chip is an
@ -216,7 +218,7 @@ nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset)
u32 falling = nmk_chip->fimsc & BIT(offset);
u32 rising = nmk_chip->rimsc & BIT(offset);
int gpio = nmk_chip->chip.base + offset;
int irq = NOMADIK_GPIO_TO_IRQ(gpio);
int irq = irq_find_mapping(nmk_chip->domain, offset);
struct irq_data *d = irq_get_irq_data(irq);
if (!rising && !falling)
@ -1341,8 +1343,7 @@ static int nmk_gpio_probe(struct platform_device *dev)
if (of_property_read_u32(np, "gpio-bank", &dev->id)) {
dev_err(&dev->dev, "gpio-bank property not found\n");
ret = -EINVAL;
goto out;
return -EINVAL;
}
pdata->first_gpio = dev->id * NMK_GPIO_PER_CHIP;
@ -1350,41 +1351,29 @@ static int nmk_gpio_probe(struct platform_device *dev)
}
res = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!res) {
ret = -ENOENT;
goto out;
}
if (!res)
return -ENOENT;
irq = platform_get_irq(dev, 0);
if (irq < 0) {
ret = irq;
goto out;
}
if (irq < 0)
return irq;
secondary_irq = platform_get_irq(dev, 1);
if (secondary_irq >= 0 && !pdata->get_secondary_status) {
ret = -EINVAL;
goto out;
}
if (secondary_irq >= 0 && !pdata->get_secondary_status)
return -EINVAL;
base = devm_request_and_ioremap(&dev->dev, res);
if (!base) {
ret = -ENOMEM;
goto out;
}
if (!base)
return -ENOMEM;
clk = devm_clk_get(&dev->dev, NULL);
if (IS_ERR(clk)) {
ret = PTR_ERR(clk);
goto out;
}
if (IS_ERR(clk))
return PTR_ERR(clk);
clk_prepare(clk);
nmk_chip = devm_kzalloc(&dev->dev, sizeof(*nmk_chip), GFP_KERNEL);
if (!nmk_chip) {
ret = -ENOMEM;
goto out;
}
if (!nmk_chip)
return -ENOMEM;
/*
* The virt address in nmk_chip->addr is in the nomadik register space,
@ -1418,7 +1407,7 @@ static int nmk_gpio_probe(struct platform_device *dev)
ret = gpiochip_add(&nmk_chip->chip);
if (ret)
goto out;
return ret;
BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips));
@ -1427,14 +1416,15 @@ static int nmk_gpio_probe(struct platform_device *dev)
platform_set_drvdata(dev, nmk_chip);
if (!np)
irq_start = NOMADIK_GPIO_TO_IRQ(pdata->first_gpio);
irq_start = pdata->first_irq;
nmk_chip->domain = irq_domain_add_simple(np,
NMK_GPIO_PER_CHIP, irq_start,
&nmk_gpio_irq_simple_ops, nmk_chip);
if (!nmk_chip->domain) {
dev_err(&dev->dev, "failed to create irqdomain\n");
ret = -ENOSYS;
goto out;
/* Just do this, no matter if it fails */
ret = gpiochip_remove(&nmk_chip->chip);
return -ENOSYS;
}
nmk_gpio_init_irq(nmk_chip);
@ -1442,12 +1432,6 @@ static int nmk_gpio_probe(struct platform_device *dev)
dev_info(&dev->dev, "at address %p\n", nmk_chip->addr);
return 0;
out:
dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret,
pdata->first_gpio, pdata->first_gpio+31);
return ret;
}
static int nmk_get_groups_cnt(struct pinctrl_dev *pctldev)
@ -1508,11 +1492,285 @@ static void nmk_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
nmk_gpio_dbg_show_one(s, pctldev, chip, offset - chip->base, offset);
}
static void nmk_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
struct pinctrl_map *map, unsigned num_maps)
{
int i;
for (i = 0; i < num_maps; i++)
if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN)
kfree(map[i].data.configs.configs);
kfree(map);
}
static int nmk_dt_reserve_map(struct pinctrl_map **map, unsigned *reserved_maps,
unsigned *num_maps, unsigned reserve)
{
unsigned old_num = *reserved_maps;
unsigned new_num = *num_maps + reserve;
struct pinctrl_map *new_map;
if (old_num >= new_num)
return 0;
new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL);
if (!new_map)
return -ENOMEM;
memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));
*map = new_map;
*reserved_maps = new_num;
return 0;
}
static int nmk_dt_add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps,
unsigned *num_maps, const char *group,
const char *function)
{
if (*num_maps == *reserved_maps)
return -ENOSPC;
(*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
(*map)[*num_maps].data.mux.group = group;
(*map)[*num_maps].data.mux.function = function;
(*num_maps)++;
return 0;
}
static int nmk_dt_add_map_configs(struct pinctrl_map **map,
unsigned *reserved_maps,
unsigned *num_maps, const char *group,
unsigned long *configs, unsigned num_configs)
{
unsigned long *dup_configs;
if (*num_maps == *reserved_maps)
return -ENOSPC;
dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs),
GFP_KERNEL);
if (!dup_configs)
return -ENOMEM;
(*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_PIN;
(*map)[*num_maps].data.configs.group_or_pin = group;
(*map)[*num_maps].data.configs.configs = dup_configs;
(*map)[*num_maps].data.configs.num_configs = num_configs;
(*num_maps)++;
return 0;
}
#define NMK_CONFIG_PIN(x,y) { .property = x, .config = y, }
#define NMK_CONFIG_PIN_ARRAY(x,y) { .property = x, .choice = y, \
.size = ARRAY_SIZE(y), }
static const unsigned long nmk_pin_input_modes[] = {
PIN_INPUT_NOPULL,
PIN_INPUT_PULLUP,
PIN_INPUT_PULLDOWN,
};
static const unsigned long nmk_pin_output_modes[] = {
PIN_OUTPUT_LOW,
PIN_OUTPUT_HIGH,
PIN_DIR_OUTPUT,
};
static const unsigned long nmk_pin_sleep_modes[] = {
PIN_SLEEPMODE_DISABLED,
PIN_SLEEPMODE_ENABLED,
};
static const unsigned long nmk_pin_sleep_input_modes[] = {
PIN_SLPM_INPUT_NOPULL,
PIN_SLPM_INPUT_PULLUP,
PIN_SLPM_INPUT_PULLDOWN,
PIN_SLPM_DIR_INPUT,
};
static const unsigned long nmk_pin_sleep_output_modes[] = {
PIN_SLPM_OUTPUT_LOW,
PIN_SLPM_OUTPUT_HIGH,
PIN_SLPM_DIR_OUTPUT,
};
static const unsigned long nmk_pin_sleep_wakeup_modes[] = {
PIN_SLPM_WAKEUP_DISABLE,
PIN_SLPM_WAKEUP_ENABLE,
};
static const unsigned long nmk_pin_gpio_modes[] = {
PIN_GPIOMODE_DISABLED,
PIN_GPIOMODE_ENABLED,
};
static const unsigned long nmk_pin_sleep_pdis_modes[] = {
PIN_SLPM_PDIS_DISABLED,
PIN_SLPM_PDIS_ENABLED,
};
struct nmk_cfg_param {
const char *property;
unsigned long config;
const unsigned long *choice;
int size;
};
static const struct nmk_cfg_param nmk_cfg_params[] = {
NMK_CONFIG_PIN_ARRAY("ste,input", nmk_pin_input_modes),
NMK_CONFIG_PIN_ARRAY("ste,output", nmk_pin_output_modes),
NMK_CONFIG_PIN_ARRAY("ste,sleep", nmk_pin_sleep_modes),
NMK_CONFIG_PIN_ARRAY("ste,sleep-input", nmk_pin_sleep_input_modes),
NMK_CONFIG_PIN_ARRAY("ste,sleep-output", nmk_pin_sleep_output_modes),
NMK_CONFIG_PIN_ARRAY("ste,sleep-wakeup", nmk_pin_sleep_wakeup_modes),
NMK_CONFIG_PIN_ARRAY("ste,gpio", nmk_pin_gpio_modes),
NMK_CONFIG_PIN_ARRAY("ste,sleep-pull-disable", nmk_pin_sleep_pdis_modes),
};
static int nmk_dt_pin_config(int index, int val, unsigned long *config)
{
int ret = 0;
if (nmk_cfg_params[index].choice == NULL)
*config = nmk_cfg_params[index].config;
else {
/* test if out of range */
if (val < nmk_cfg_params[index].size) {
*config = nmk_cfg_params[index].config |
nmk_cfg_params[index].choice[val];
}
}
return ret;
}
static const char *nmk_find_pin_name(struct pinctrl_dev *pctldev, const char *pin_name)
{
int i, pin_number;
struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
if (sscanf((char *)pin_name, "GPIO%d", &pin_number) == 1)
for (i = 0; i < npct->soc->npins; i++)
if (npct->soc->pins[i].number == pin_number)
return npct->soc->pins[i].name;
return NULL;
}
static bool nmk_pinctrl_dt_get_config(struct device_node *np,
unsigned long *configs)
{
bool has_config = 0;
unsigned long cfg = 0;
int i, val, ret;
for (i = 0; i < ARRAY_SIZE(nmk_cfg_params); i++) {
ret = of_property_read_u32(np,
nmk_cfg_params[i].property, &val);
if (ret != -EINVAL) {
if (nmk_dt_pin_config(i, val, &cfg) == 0) {
*configs |= cfg;
has_config = 1;
}
}
}
return has_config;
}
int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
struct device_node *np,
struct pinctrl_map **map,
unsigned *reserved_maps,
unsigned *num_maps)
{
int ret;
const char *function = NULL;
unsigned long configs = 0;
bool has_config = 0;
unsigned reserve = 0;
struct property *prop;
const char *group, *gpio_name;
struct device_node *np_config;
ret = of_property_read_string(np, "ste,function", &function);
if (ret >= 0)
reserve = 1;
has_config = nmk_pinctrl_dt_get_config(np, &configs);
np_config = of_parse_phandle(np, "ste,config", 0);
if (np_config)
has_config |= nmk_pinctrl_dt_get_config(np_config, &configs);
ret = of_property_count_strings(np, "ste,pins");
if (ret < 0)
goto exit;
if (has_config)
reserve++;
reserve *= ret;
ret = nmk_dt_reserve_map(map, reserved_maps, num_maps, reserve);
if (ret < 0)
goto exit;
of_property_for_each_string(np, "ste,pins", prop, group) {
if (function) {
ret = nmk_dt_add_map_mux(map, reserved_maps, num_maps,
group, function);
if (ret < 0)
goto exit;
}
if (has_config) {
gpio_name = nmk_find_pin_name(pctldev, group);
ret = nmk_dt_add_map_configs(map, reserved_maps, num_maps,
gpio_name, &configs, 1);
if (ret < 0)
goto exit;
}
}
exit:
return ret;
}
int nmk_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
struct device_node *np_config,
struct pinctrl_map **map, unsigned *num_maps)
{
unsigned reserved_maps;
struct device_node *np;
int ret;
reserved_maps = 0;
*map = NULL;
*num_maps = 0;
for_each_child_of_node(np_config, np) {
ret = nmk_pinctrl_dt_subnode_to_map(pctldev, np, map,
&reserved_maps, num_maps);
if (ret < 0) {
nmk_pinctrl_dt_free_map(pctldev, *map, *num_maps);
return ret;
}
}
return 0;
}
static struct pinctrl_ops nmk_pinctrl_ops = {
.get_groups_count = nmk_get_groups_cnt,
.get_group_name = nmk_get_group_name,
.get_group_pins = nmk_get_group_pins,
.pin_dbg_show = nmk_pin_dbg_show,
.dt_node_to_map = nmk_pinctrl_dt_node_to_map,
.dt_free_map = nmk_pinctrl_dt_free_map,
};
static int nmk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
@ -1846,16 +2104,39 @@ static struct pinctrl_desc nmk_pinctrl_desc = {
static const struct of_device_id nmk_pinctrl_match[] = {
{
.compatible = "stericsson,nmk_pinctrl",
.compatible = "stericsson,nmk-pinctrl",
.data = (void *)PINCTRL_NMK_DB8500,
},
{},
};
static int nmk_pinctrl_suspend(struct platform_device *pdev, pm_message_t state)
{
struct nmk_pinctrl *npct;
npct = platform_get_drvdata(pdev);
if (!npct)
return -EINVAL;
return pinctrl_force_sleep(npct->pctl);
}
static int nmk_pinctrl_resume(struct platform_device *pdev)
{
struct nmk_pinctrl *npct;
npct = platform_get_drvdata(pdev);
if (!npct)
return -EINVAL;
return pinctrl_force_default(npct->pctl);
}
static int nmk_pinctrl_probe(struct platform_device *pdev)
{
const struct platform_device_id *platid = platform_get_device_id(pdev);
struct device_node *np = pdev->dev.of_node;
struct device_node *prcm_np;
struct nmk_pinctrl *npct;
struct resource *res;
unsigned int version = 0;
@ -1884,21 +2165,26 @@ static int nmk_pinctrl_probe(struct platform_device *pdev)
if (version == PINCTRL_NMK_DB8540)
nmk_pinctrl_db8540_init(&npct->soc);
if (np) {
prcm_np = of_parse_phandle(np, "prcm", 0);
if (prcm_np)
npct->prcm_base = of_iomap(prcm_np, 0);
}
/* Allow platform passed information to over-write DT. */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res) {
if (res)
npct->prcm_base = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
if (!npct->prcm_base) {
dev_err(&pdev->dev,
"failed to ioremap PRCM registers\n");
return -ENOMEM;
if (!npct->prcm_base) {
if (version == PINCTRL_NMK_STN8815) {
dev_info(&pdev->dev,
"No PRCM base, "
"assuming no ALT-Cx control is available\n");
} else {
dev_err(&pdev->dev, "missing PRCM base address\n");
return -EINVAL;
}
} else if (version == PINCTRL_NMK_STN8815) {
dev_info(&pdev->dev,
"No PRCM base, assume no ALT-Cx control is available\n");
} else {
dev_err(&pdev->dev, "missing PRCM base address\n");
return -EINVAL;
}
/*
@ -1963,6 +2249,10 @@ static struct platform_driver nmk_pinctrl_driver = {
},
.probe = nmk_pinctrl_probe,
.id_table = nmk_pinctrl_id,
#ifdef CONFIG_PM
.suspend = nmk_pinctrl_suspend,
.resume = nmk_pinctrl_resume,
#endif
};
static int __init nmk_gpio_init(void)

View File

@ -716,7 +716,6 @@ static int samsung_pinctrl_register(struct platform_device *pdev,
}
ctrldesc->pins = pindesc;
ctrldesc->npins = drvdata->ctrl->nr_pins;
ctrldesc->npins = drvdata->ctrl->nr_pins;
/* dynamically populate the pin number and pin name for pindesc */
for (pin = 0, pdesc = pindesc; pin < ctrldesc->npins; pin++, pdesc++)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,478 @@
/*
* Allwinner A1X SoCs pinctrl driver.
*
* Copyright (C) 2012 Maxime Ripard
*
* Maxime Ripard <maxime.ripard@free-electrons.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __PINCTRL_SUNXI_H
#define __PINCTRL_SUNXI_H
#include <linux/kernel.h>
#define PA_BASE 0
#define PB_BASE 32
#define PC_BASE 64
#define PD_BASE 96
#define PE_BASE 128
#define PF_BASE 160
#define PG_BASE 192
#define PH_BASE 224
#define PI_BASE 256
#define SUNXI_PINCTRL_PIN_PA0 PINCTRL_PIN(PA_BASE + 0, "PA0")
#define SUNXI_PINCTRL_PIN_PA1 PINCTRL_PIN(PA_BASE + 1, "PA1")
#define SUNXI_PINCTRL_PIN_PA2 PINCTRL_PIN(PA_BASE + 2, "PA2")
#define SUNXI_PINCTRL_PIN_PA3 PINCTRL_PIN(PA_BASE + 3, "PA3")
#define SUNXI_PINCTRL_PIN_PA4 PINCTRL_PIN(PA_BASE + 4, "PA4")
#define SUNXI_PINCTRL_PIN_PA5 PINCTRL_PIN(PA_BASE + 5, "PA5")
#define SUNXI_PINCTRL_PIN_PA6 PINCTRL_PIN(PA_BASE + 6, "PA6")
#define SUNXI_PINCTRL_PIN_PA7 PINCTRL_PIN(PA_BASE + 7, "PA7")
#define SUNXI_PINCTRL_PIN_PA8 PINCTRL_PIN(PA_BASE + 8, "PA8")
#define SUNXI_PINCTRL_PIN_PA9 PINCTRL_PIN(PA_BASE + 9, "PA9")
#define SUNXI_PINCTRL_PIN_PA10 PINCTRL_PIN(PA_BASE + 10, "PA10")
#define SUNXI_PINCTRL_PIN_PA11 PINCTRL_PIN(PA_BASE + 11, "PA11")
#define SUNXI_PINCTRL_PIN_PA12 PINCTRL_PIN(PA_BASE + 12, "PA12")
#define SUNXI_PINCTRL_PIN_PA13 PINCTRL_PIN(PA_BASE + 13, "PA13")
#define SUNXI_PINCTRL_PIN_PA14 PINCTRL_PIN(PA_BASE + 14, "PA14")
#define SUNXI_PINCTRL_PIN_PA15 PINCTRL_PIN(PA_BASE + 15, "PA15")
#define SUNXI_PINCTRL_PIN_PA16 PINCTRL_PIN(PA_BASE + 16, "PA16")
#define SUNXI_PINCTRL_PIN_PA17 PINCTRL_PIN(PA_BASE + 17, "PA17")
#define SUNXI_PINCTRL_PIN_PA18 PINCTRL_PIN(PA_BASE + 18, "PA18")
#define SUNXI_PINCTRL_PIN_PA19 PINCTRL_PIN(PA_BASE + 19, "PA19")
#define SUNXI_PINCTRL_PIN_PA20 PINCTRL_PIN(PA_BASE + 20, "PA20")
#define SUNXI_PINCTRL_PIN_PA21 PINCTRL_PIN(PA_BASE + 21, "PA21")
#define SUNXI_PINCTRL_PIN_PA22 PINCTRL_PIN(PA_BASE + 22, "PA22")
#define SUNXI_PINCTRL_PIN_PA23 PINCTRL_PIN(PA_BASE + 23, "PA23")
#define SUNXI_PINCTRL_PIN_PA24 PINCTRL_PIN(PA_BASE + 24, "PA24")
#define SUNXI_PINCTRL_PIN_PA25 PINCTRL_PIN(PA_BASE + 25, "PA25")
#define SUNXI_PINCTRL_PIN_PA26 PINCTRL_PIN(PA_BASE + 26, "PA26")
#define SUNXI_PINCTRL_PIN_PA27 PINCTRL_PIN(PA_BASE + 27, "PA27")
#define SUNXI_PINCTRL_PIN_PA28 PINCTRL_PIN(PA_BASE + 28, "PA28")
#define SUNXI_PINCTRL_PIN_PA29 PINCTRL_PIN(PA_BASE + 29, "PA29")
#define SUNXI_PINCTRL_PIN_PA30 PINCTRL_PIN(PA_BASE + 30, "PA30")
#define SUNXI_PINCTRL_PIN_PA31 PINCTRL_PIN(PA_BASE + 31, "PA31")
#define SUNXI_PINCTRL_PIN_PB0 PINCTRL_PIN(PB_BASE + 0, "PB0")
#define SUNXI_PINCTRL_PIN_PB1 PINCTRL_PIN(PB_BASE + 1, "PB1")
#define SUNXI_PINCTRL_PIN_PB2 PINCTRL_PIN(PB_BASE + 2, "PB2")
#define SUNXI_PINCTRL_PIN_PB3 PINCTRL_PIN(PB_BASE + 3, "PB3")
#define SUNXI_PINCTRL_PIN_PB4 PINCTRL_PIN(PB_BASE + 4, "PB4")
#define SUNXI_PINCTRL_PIN_PB5 PINCTRL_PIN(PB_BASE + 5, "PB5")
#define SUNXI_PINCTRL_PIN_PB6 PINCTRL_PIN(PB_BASE + 6, "PB6")
#define SUNXI_PINCTRL_PIN_PB7 PINCTRL_PIN(PB_BASE + 7, "PB7")
#define SUNXI_PINCTRL_PIN_PB8 PINCTRL_PIN(PB_BASE + 8, "PB8")
#define SUNXI_PINCTRL_PIN_PB9 PINCTRL_PIN(PB_BASE + 9, "PB9")
#define SUNXI_PINCTRL_PIN_PB10 PINCTRL_PIN(PB_BASE + 10, "PB10")
#define SUNXI_PINCTRL_PIN_PB11 PINCTRL_PIN(PB_BASE + 11, "PB11")
#define SUNXI_PINCTRL_PIN_PB12 PINCTRL_PIN(PB_BASE + 12, "PB12")
#define SUNXI_PINCTRL_PIN_PB13 PINCTRL_PIN(PB_BASE + 13, "PB13")
#define SUNXI_PINCTRL_PIN_PB14 PINCTRL_PIN(PB_BASE + 14, "PB14")
#define SUNXI_PINCTRL_PIN_PB15 PINCTRL_PIN(PB_BASE + 15, "PB15")
#define SUNXI_PINCTRL_PIN_PB16 PINCTRL_PIN(PB_BASE + 16, "PB16")
#define SUNXI_PINCTRL_PIN_PB17 PINCTRL_PIN(PB_BASE + 17, "PB17")
#define SUNXI_PINCTRL_PIN_PB18 PINCTRL_PIN(PB_BASE + 18, "PB18")
#define SUNXI_PINCTRL_PIN_PB19 PINCTRL_PIN(PB_BASE + 19, "PB19")
#define SUNXI_PINCTRL_PIN_PB20 PINCTRL_PIN(PB_BASE + 20, "PB20")
#define SUNXI_PINCTRL_PIN_PB21 PINCTRL_PIN(PB_BASE + 21, "PB21")
#define SUNXI_PINCTRL_PIN_PB22 PINCTRL_PIN(PB_BASE + 22, "PB22")
#define SUNXI_PINCTRL_PIN_PB23 PINCTRL_PIN(PB_BASE + 23, "PB23")
#define SUNXI_PINCTRL_PIN_PB24 PINCTRL_PIN(PB_BASE + 24, "PB24")
#define SUNXI_PINCTRL_PIN_PB25 PINCTRL_PIN(PB_BASE + 25, "PB25")
#define SUNXI_PINCTRL_PIN_PB26 PINCTRL_PIN(PB_BASE + 26, "PB26")
#define SUNXI_PINCTRL_PIN_PB27 PINCTRL_PIN(PB_BASE + 27, "PB27")
#define SUNXI_PINCTRL_PIN_PB28 PINCTRL_PIN(PB_BASE + 28, "PB28")
#define SUNXI_PINCTRL_PIN_PB29 PINCTRL_PIN(PB_BASE + 29, "PB29")
#define SUNXI_PINCTRL_PIN_PB30 PINCTRL_PIN(PB_BASE + 30, "PB30")
#define SUNXI_PINCTRL_PIN_PB31 PINCTRL_PIN(PB_BASE + 31, "PB31")
#define SUNXI_PINCTRL_PIN_PC0 PINCTRL_PIN(PC_BASE + 0, "PC0")
#define SUNXI_PINCTRL_PIN_PC1 PINCTRL_PIN(PC_BASE + 1, "PC1")
#define SUNXI_PINCTRL_PIN_PC2 PINCTRL_PIN(PC_BASE + 2, "PC2")
#define SUNXI_PINCTRL_PIN_PC3 PINCTRL_PIN(PC_BASE + 3, "PC3")
#define SUNXI_PINCTRL_PIN_PC4 PINCTRL_PIN(PC_BASE + 4, "PC4")
#define SUNXI_PINCTRL_PIN_PC5 PINCTRL_PIN(PC_BASE + 5, "PC5")
#define SUNXI_PINCTRL_PIN_PC6 PINCTRL_PIN(PC_BASE + 6, "PC6")
#define SUNXI_PINCTRL_PIN_PC7 PINCTRL_PIN(PC_BASE + 7, "PC7")
#define SUNXI_PINCTRL_PIN_PC8 PINCTRL_PIN(PC_BASE + 8, "PC8")
#define SUNXI_PINCTRL_PIN_PC9 PINCTRL_PIN(PC_BASE + 9, "PC9")
#define SUNXI_PINCTRL_PIN_PC10 PINCTRL_PIN(PC_BASE + 10, "PC10")
#define SUNXI_PINCTRL_PIN_PC11 PINCTRL_PIN(PC_BASE + 11, "PC11")
#define SUNXI_PINCTRL_PIN_PC12 PINCTRL_PIN(PC_BASE + 12, "PC12")
#define SUNXI_PINCTRL_PIN_PC13 PINCTRL_PIN(PC_BASE + 13, "PC13")
#define SUNXI_PINCTRL_PIN_PC14 PINCTRL_PIN(PC_BASE + 14, "PC14")
#define SUNXI_PINCTRL_PIN_PC15 PINCTRL_PIN(PC_BASE + 15, "PC15")
#define SUNXI_PINCTRL_PIN_PC16 PINCTRL_PIN(PC_BASE + 16, "PC16")
#define SUNXI_PINCTRL_PIN_PC17 PINCTRL_PIN(PC_BASE + 17, "PC17")
#define SUNXI_PINCTRL_PIN_PC18 PINCTRL_PIN(PC_BASE + 18, "PC18")
#define SUNXI_PINCTRL_PIN_PC19 PINCTRL_PIN(PC_BASE + 19, "PC19")
#define SUNXI_PINCTRL_PIN_PC20 PINCTRL_PIN(PC_BASE + 20, "PC20")
#define SUNXI_PINCTRL_PIN_PC21 PINCTRL_PIN(PC_BASE + 21, "PC21")
#define SUNXI_PINCTRL_PIN_PC22 PINCTRL_PIN(PC_BASE + 22, "PC22")
#define SUNXI_PINCTRL_PIN_PC23 PINCTRL_PIN(PC_BASE + 23, "PC23")
#define SUNXI_PINCTRL_PIN_PC24 PINCTRL_PIN(PC_BASE + 24, "PC24")
#define SUNXI_PINCTRL_PIN_PC25 PINCTRL_PIN(PC_BASE + 25, "PC25")
#define SUNXI_PINCTRL_PIN_PC26 PINCTRL_PIN(PC_BASE + 26, "PC26")
#define SUNXI_PINCTRL_PIN_PC27 PINCTRL_PIN(PC_BASE + 27, "PC27")
#define SUNXI_PINCTRL_PIN_PC28 PINCTRL_PIN(PC_BASE + 28, "PC28")
#define SUNXI_PINCTRL_PIN_PC29 PINCTRL_PIN(PC_BASE + 29, "PC29")
#define SUNXI_PINCTRL_PIN_PC30 PINCTRL_PIN(PC_BASE + 30, "PC30")
#define SUNXI_PINCTRL_PIN_PC31 PINCTRL_PIN(PC_BASE + 31, "PC31")
#define SUNXI_PINCTRL_PIN_PD0 PINCTRL_PIN(PD_BASE + 0, "PD0")
#define SUNXI_PINCTRL_PIN_PD1 PINCTRL_PIN(PD_BASE + 1, "PD1")
#define SUNXI_PINCTRL_PIN_PD2 PINCTRL_PIN(PD_BASE + 2, "PD2")
#define SUNXI_PINCTRL_PIN_PD3 PINCTRL_PIN(PD_BASE + 3, "PD3")
#define SUNXI_PINCTRL_PIN_PD4 PINCTRL_PIN(PD_BASE + 4, "PD4")
#define SUNXI_PINCTRL_PIN_PD5 PINCTRL_PIN(PD_BASE + 5, "PD5")
#define SUNXI_PINCTRL_PIN_PD6 PINCTRL_PIN(PD_BASE + 6, "PD6")
#define SUNXI_PINCTRL_PIN_PD7 PINCTRL_PIN(PD_BASE + 7, "PD7")
#define SUNXI_PINCTRL_PIN_PD8 PINCTRL_PIN(PD_BASE + 8, "PD8")
#define SUNXI_PINCTRL_PIN_PD9 PINCTRL_PIN(PD_BASE + 9, "PD9")
#define SUNXI_PINCTRL_PIN_PD10 PINCTRL_PIN(PD_BASE + 10, "PD10")
#define SUNXI_PINCTRL_PIN_PD11 PINCTRL_PIN(PD_BASE + 11, "PD11")
#define SUNXI_PINCTRL_PIN_PD12 PINCTRL_PIN(PD_BASE + 12, "PD12")
#define SUNXI_PINCTRL_PIN_PD13 PINCTRL_PIN(PD_BASE + 13, "PD13")
#define SUNXI_PINCTRL_PIN_PD14 PINCTRL_PIN(PD_BASE + 14, "PD14")
#define SUNXI_PINCTRL_PIN_PD15 PINCTRL_PIN(PD_BASE + 15, "PD15")
#define SUNXI_PINCTRL_PIN_PD16 PINCTRL_PIN(PD_BASE + 16, "PD16")
#define SUNXI_PINCTRL_PIN_PD17 PINCTRL_PIN(PD_BASE + 17, "PD17")
#define SUNXI_PINCTRL_PIN_PD18 PINCTRL_PIN(PD_BASE + 18, "PD18")
#define SUNXI_PINCTRL_PIN_PD19 PINCTRL_PIN(PD_BASE + 19, "PD19")
#define SUNXI_PINCTRL_PIN_PD20 PINCTRL_PIN(PD_BASE + 20, "PD20")
#define SUNXI_PINCTRL_PIN_PD21 PINCTRL_PIN(PD_BASE + 21, "PD21")
#define SUNXI_PINCTRL_PIN_PD22 PINCTRL_PIN(PD_BASE + 22, "PD22")
#define SUNXI_PINCTRL_PIN_PD23 PINCTRL_PIN(PD_BASE + 23, "PD23")
#define SUNXI_PINCTRL_PIN_PD24 PINCTRL_PIN(PD_BASE + 24, "PD24")
#define SUNXI_PINCTRL_PIN_PD25 PINCTRL_PIN(PD_BASE + 25, "PD25")
#define SUNXI_PINCTRL_PIN_PD26 PINCTRL_PIN(PD_BASE + 26, "PD26")
#define SUNXI_PINCTRL_PIN_PD27 PINCTRL_PIN(PD_BASE + 27, "PD27")
#define SUNXI_PINCTRL_PIN_PD28 PINCTRL_PIN(PD_BASE + 28, "PD28")
#define SUNXI_PINCTRL_PIN_PD29 PINCTRL_PIN(PD_BASE + 29, "PD29")
#define SUNXI_PINCTRL_PIN_PD30 PINCTRL_PIN(PD_BASE + 30, "PD30")
#define SUNXI_PINCTRL_PIN_PD31 PINCTRL_PIN(PD_BASE + 31, "PD31")
#define SUNXI_PINCTRL_PIN_PE0 PINCTRL_PIN(PE_BASE + 0, "PE0")
#define SUNXI_PINCTRL_PIN_PE1 PINCTRL_PIN(PE_BASE + 1, "PE1")
#define SUNXI_PINCTRL_PIN_PE2 PINCTRL_PIN(PE_BASE + 2, "PE2")
#define SUNXI_PINCTRL_PIN_PE3 PINCTRL_PIN(PE_BASE + 3, "PE3")
#define SUNXI_PINCTRL_PIN_PE4 PINCTRL_PIN(PE_BASE + 4, "PE4")
#define SUNXI_PINCTRL_PIN_PE5 PINCTRL_PIN(PE_BASE + 5, "PE5")
#define SUNXI_PINCTRL_PIN_PE6 PINCTRL_PIN(PE_BASE + 6, "PE6")
#define SUNXI_PINCTRL_PIN_PE7 PINCTRL_PIN(PE_BASE + 7, "PE7")
#define SUNXI_PINCTRL_PIN_PE8 PINCTRL_PIN(PE_BASE + 8, "PE8")
#define SUNXI_PINCTRL_PIN_PE9 PINCTRL_PIN(PE_BASE + 9, "PE9")
#define SUNXI_PINCTRL_PIN_PE10 PINCTRL_PIN(PE_BASE + 10, "PE10")
#define SUNXI_PINCTRL_PIN_PE11 PINCTRL_PIN(PE_BASE + 11, "PE11")
#define SUNXI_PINCTRL_PIN_PE12 PINCTRL_PIN(PE_BASE + 12, "PE12")
#define SUNXI_PINCTRL_PIN_PE13 PINCTRL_PIN(PE_BASE + 13, "PE13")
#define SUNXI_PINCTRL_PIN_PE14 PINCTRL_PIN(PE_BASE + 14, "PE14")
#define SUNXI_PINCTRL_PIN_PE15 PINCTRL_PIN(PE_BASE + 15, "PE15")
#define SUNXI_PINCTRL_PIN_PE16 PINCTRL_PIN(PE_BASE + 16, "PE16")
#define SUNXI_PINCTRL_PIN_PE17 PINCTRL_PIN(PE_BASE + 17, "PE17")
#define SUNXI_PINCTRL_PIN_PE18 PINCTRL_PIN(PE_BASE + 18, "PE18")
#define SUNXI_PINCTRL_PIN_PE19 PINCTRL_PIN(PE_BASE + 19, "PE19")
#define SUNXI_PINCTRL_PIN_PE20 PINCTRL_PIN(PE_BASE + 20, "PE20")
#define SUNXI_PINCTRL_PIN_PE21 PINCTRL_PIN(PE_BASE + 21, "PE21")
#define SUNXI_PINCTRL_PIN_PE22 PINCTRL_PIN(PE_BASE + 22, "PE22")
#define SUNXI_PINCTRL_PIN_PE23 PINCTRL_PIN(PE_BASE + 23, "PE23")
#define SUNXI_PINCTRL_PIN_PE24 PINCTRL_PIN(PE_BASE + 24, "PE24")
#define SUNXI_PINCTRL_PIN_PE25 PINCTRL_PIN(PE_BASE + 25, "PE25")
#define SUNXI_PINCTRL_PIN_PE26 PINCTRL_PIN(PE_BASE + 26, "PE26")
#define SUNXI_PINCTRL_PIN_PE27 PINCTRL_PIN(PE_BASE + 27, "PE27")
#define SUNXI_PINCTRL_PIN_PE28 PINCTRL_PIN(PE_BASE + 28, "PE28")
#define SUNXI_PINCTRL_PIN_PE29 PINCTRL_PIN(PE_BASE + 29, "PE29")
#define SUNXI_PINCTRL_PIN_PE30 PINCTRL_PIN(PE_BASE + 30, "PE30")
#define SUNXI_PINCTRL_PIN_PE31 PINCTRL_PIN(PE_BASE + 31, "PE31")
#define SUNXI_PINCTRL_PIN_PF0 PINCTRL_PIN(PF_BASE + 0, "PF0")
#define SUNXI_PINCTRL_PIN_PF1 PINCTRL_PIN(PF_BASE + 1, "PF1")
#define SUNXI_PINCTRL_PIN_PF2 PINCTRL_PIN(PF_BASE + 2, "PF2")
#define SUNXI_PINCTRL_PIN_PF3 PINCTRL_PIN(PF_BASE + 3, "PF3")
#define SUNXI_PINCTRL_PIN_PF4 PINCTRL_PIN(PF_BASE + 4, "PF4")
#define SUNXI_PINCTRL_PIN_PF5 PINCTRL_PIN(PF_BASE + 5, "PF5")
#define SUNXI_PINCTRL_PIN_PF6 PINCTRL_PIN(PF_BASE + 6, "PF6")
#define SUNXI_PINCTRL_PIN_PF7 PINCTRL_PIN(PF_BASE + 7, "PF7")
#define SUNXI_PINCTRL_PIN_PF8 PINCTRL_PIN(PF_BASE + 8, "PF8")
#define SUNXI_PINCTRL_PIN_PF9 PINCTRL_PIN(PF_BASE + 9, "PF9")
#define SUNXI_PINCTRL_PIN_PF10 PINCTRL_PIN(PF_BASE + 10, "PF10")
#define SUNXI_PINCTRL_PIN_PF11 PINCTRL_PIN(PF_BASE + 11, "PF11")
#define SUNXI_PINCTRL_PIN_PF12 PINCTRL_PIN(PF_BASE + 12, "PF12")
#define SUNXI_PINCTRL_PIN_PF13 PINCTRL_PIN(PF_BASE + 13, "PF13")
#define SUNXI_PINCTRL_PIN_PF14 PINCTRL_PIN(PF_BASE + 14, "PF14")
#define SUNXI_PINCTRL_PIN_PF15 PINCTRL_PIN(PF_BASE + 15, "PF15")
#define SUNXI_PINCTRL_PIN_PF16 PINCTRL_PIN(PF_BASE + 16, "PF16")
#define SUNXI_PINCTRL_PIN_PF17 PINCTRL_PIN(PF_BASE + 17, "PF17")
#define SUNXI_PINCTRL_PIN_PF18 PINCTRL_PIN(PF_BASE + 18, "PF18")
#define SUNXI_PINCTRL_PIN_PF19 PINCTRL_PIN(PF_BASE + 19, "PF19")
#define SUNXI_PINCTRL_PIN_PF20 PINCTRL_PIN(PF_BASE + 20, "PF20")
#define SUNXI_PINCTRL_PIN_PF21 PINCTRL_PIN(PF_BASE + 21, "PF21")
#define SUNXI_PINCTRL_PIN_PF22 PINCTRL_PIN(PF_BASE + 22, "PF22")
#define SUNXI_PINCTRL_PIN_PF23 PINCTRL_PIN(PF_BASE + 23, "PF23")
#define SUNXI_PINCTRL_PIN_PF24 PINCTRL_PIN(PF_BASE + 24, "PF24")
#define SUNXI_PINCTRL_PIN_PF25 PINCTRL_PIN(PF_BASE + 25, "PF25")
#define SUNXI_PINCTRL_PIN_PF26 PINCTRL_PIN(PF_BASE + 26, "PF26")
#define SUNXI_PINCTRL_PIN_PF27 PINCTRL_PIN(PF_BASE + 27, "PF27")
#define SUNXI_PINCTRL_PIN_PF28 PINCTRL_PIN(PF_BASE + 28, "PF28")
#define SUNXI_PINCTRL_PIN_PF29 PINCTRL_PIN(PF_BASE + 29, "PF29")
#define SUNXI_PINCTRL_PIN_PF30 PINCTRL_PIN(PF_BASE + 30, "PF30")
#define SUNXI_PINCTRL_PIN_PF31 PINCTRL_PIN(PF_BASE + 31, "PF31")
#define SUNXI_PINCTRL_PIN_PG0 PINCTRL_PIN(PG_BASE + 0, "PG0")
#define SUNXI_PINCTRL_PIN_PG1 PINCTRL_PIN(PG_BASE + 1, "PG1")
#define SUNXI_PINCTRL_PIN_PG2 PINCTRL_PIN(PG_BASE + 2, "PG2")
#define SUNXI_PINCTRL_PIN_PG3 PINCTRL_PIN(PG_BASE + 3, "PG3")
#define SUNXI_PINCTRL_PIN_PG4 PINCTRL_PIN(PG_BASE + 4, "PG4")
#define SUNXI_PINCTRL_PIN_PG5 PINCTRL_PIN(PG_BASE + 5, "PG5")
#define SUNXI_PINCTRL_PIN_PG6 PINCTRL_PIN(PG_BASE + 6, "PG6")
#define SUNXI_PINCTRL_PIN_PG7 PINCTRL_PIN(PG_BASE + 7, "PG7")
#define SUNXI_PINCTRL_PIN_PG8 PINCTRL_PIN(PG_BASE + 8, "PG8")
#define SUNXI_PINCTRL_PIN_PG9 PINCTRL_PIN(PG_BASE + 9, "PG9")
#define SUNXI_PINCTRL_PIN_PG10 PINCTRL_PIN(PG_BASE + 10, "PG10")
#define SUNXI_PINCTRL_PIN_PG11 PINCTRL_PIN(PG_BASE + 11, "PG11")
#define SUNXI_PINCTRL_PIN_PG12 PINCTRL_PIN(PG_BASE + 12, "PG12")
#define SUNXI_PINCTRL_PIN_PG13 PINCTRL_PIN(PG_BASE + 13, "PG13")
#define SUNXI_PINCTRL_PIN_PG14 PINCTRL_PIN(PG_BASE + 14, "PG14")
#define SUNXI_PINCTRL_PIN_PG15 PINCTRL_PIN(PG_BASE + 15, "PG15")
#define SUNXI_PINCTRL_PIN_PG16 PINCTRL_PIN(PG_BASE + 16, "PG16")
#define SUNXI_PINCTRL_PIN_PG17 PINCTRL_PIN(PG_BASE + 17, "PG17")
#define SUNXI_PINCTRL_PIN_PG18 PINCTRL_PIN(PG_BASE + 18, "PG18")
#define SUNXI_PINCTRL_PIN_PG19 PINCTRL_PIN(PG_BASE + 19, "PG19")
#define SUNXI_PINCTRL_PIN_PG20 PINCTRL_PIN(PG_BASE + 20, "PG20")
#define SUNXI_PINCTRL_PIN_PG21 PINCTRL_PIN(PG_BASE + 21, "PG21")
#define SUNXI_PINCTRL_PIN_PG22 PINCTRL_PIN(PG_BASE + 22, "PG22")
#define SUNXI_PINCTRL_PIN_PG23 PINCTRL_PIN(PG_BASE + 23, "PG23")
#define SUNXI_PINCTRL_PIN_PG24 PINCTRL_PIN(PG_BASE + 24, "PG24")
#define SUNXI_PINCTRL_PIN_PG25 PINCTRL_PIN(PG_BASE + 25, "PG25")
#define SUNXI_PINCTRL_PIN_PG26 PINCTRL_PIN(PG_BASE + 26, "PG26")
#define SUNXI_PINCTRL_PIN_PG27 PINCTRL_PIN(PG_BASE + 27, "PG27")
#define SUNXI_PINCTRL_PIN_PG28 PINCTRL_PIN(PG_BASE + 28, "PG28")
#define SUNXI_PINCTRL_PIN_PG29 PINCTRL_PIN(PG_BASE + 29, "PG29")
#define SUNXI_PINCTRL_PIN_PG30 PINCTRL_PIN(PG_BASE + 30, "PG30")
#define SUNXI_PINCTRL_PIN_PG31 PINCTRL_PIN(PG_BASE + 31, "PG31")
#define SUNXI_PINCTRL_PIN_PH0 PINCTRL_PIN(PH_BASE + 0, "PH0")
#define SUNXI_PINCTRL_PIN_PH1 PINCTRL_PIN(PH_BASE + 1, "PH1")
#define SUNXI_PINCTRL_PIN_PH2 PINCTRL_PIN(PH_BASE + 2, "PH2")
#define SUNXI_PINCTRL_PIN_PH3 PINCTRL_PIN(PH_BASE + 3, "PH3")
#define SUNXI_PINCTRL_PIN_PH4 PINCTRL_PIN(PH_BASE + 4, "PH4")
#define SUNXI_PINCTRL_PIN_PH5 PINCTRL_PIN(PH_BASE + 5, "PH5")
#define SUNXI_PINCTRL_PIN_PH6 PINCTRL_PIN(PH_BASE + 6, "PH6")
#define SUNXI_PINCTRL_PIN_PH7 PINCTRL_PIN(PH_BASE + 7, "PH7")
#define SUNXI_PINCTRL_PIN_PH8 PINCTRL_PIN(PH_BASE + 8, "PH8")
#define SUNXI_PINCTRL_PIN_PH9 PINCTRL_PIN(PH_BASE + 9, "PH9")
#define SUNXI_PINCTRL_PIN_PH10 PINCTRL_PIN(PH_BASE + 10, "PH10")
#define SUNXI_PINCTRL_PIN_PH11 PINCTRL_PIN(PH_BASE + 11, "PH11")
#define SUNXI_PINCTRL_PIN_PH12 PINCTRL_PIN(PH_BASE + 12, "PH12")
#define SUNXI_PINCTRL_PIN_PH13 PINCTRL_PIN(PH_BASE + 13, "PH13")
#define SUNXI_PINCTRL_PIN_PH14 PINCTRL_PIN(PH_BASE + 14, "PH14")
#define SUNXI_PINCTRL_PIN_PH15 PINCTRL_PIN(PH_BASE + 15, "PH15")
#define SUNXI_PINCTRL_PIN_PH16 PINCTRL_PIN(PH_BASE + 16, "PH16")
#define SUNXI_PINCTRL_PIN_PH17 PINCTRL_PIN(PH_BASE + 17, "PH17")
#define SUNXI_PINCTRL_PIN_PH18 PINCTRL_PIN(PH_BASE + 18, "PH18")
#define SUNXI_PINCTRL_PIN_PH19 PINCTRL_PIN(PH_BASE + 19, "PH19")
#define SUNXI_PINCTRL_PIN_PH20 PINCTRL_PIN(PH_BASE + 20, "PH20")
#define SUNXI_PINCTRL_PIN_PH21 PINCTRL_PIN(PH_BASE + 21, "PH21")
#define SUNXI_PINCTRL_PIN_PH22 PINCTRL_PIN(PH_BASE + 22, "PH22")
#define SUNXI_PINCTRL_PIN_PH23 PINCTRL_PIN(PH_BASE + 23, "PH23")
#define SUNXI_PINCTRL_PIN_PH24 PINCTRL_PIN(PH_BASE + 24, "PH24")
#define SUNXI_PINCTRL_PIN_PH25 PINCTRL_PIN(PH_BASE + 25, "PH25")
#define SUNXI_PINCTRL_PIN_PH26 PINCTRL_PIN(PH_BASE + 26, "PH26")
#define SUNXI_PINCTRL_PIN_PH27 PINCTRL_PIN(PH_BASE + 27, "PH27")
#define SUNXI_PINCTRL_PIN_PH28 PINCTRL_PIN(PH_BASE + 28, "PH28")
#define SUNXI_PINCTRL_PIN_PH29 PINCTRL_PIN(PH_BASE + 29, "PH29")
#define SUNXI_PINCTRL_PIN_PH30 PINCTRL_PIN(PH_BASE + 30, "PH30")
#define SUNXI_PINCTRL_PIN_PH31 PINCTRL_PIN(PH_BASE + 31, "PH31")
#define SUNXI_PINCTRL_PIN_PI0 PINCTRL_PIN(PI_BASE + 0, "PI0")
#define SUNXI_PINCTRL_PIN_PI1 PINCTRL_PIN(PI_BASE + 1, "PI1")
#define SUNXI_PINCTRL_PIN_PI2 PINCTRL_PIN(PI_BASE + 2, "PI2")
#define SUNXI_PINCTRL_PIN_PI3 PINCTRL_PIN(PI_BASE + 3, "PI3")
#define SUNXI_PINCTRL_PIN_PI4 PINCTRL_PIN(PI_BASE + 4, "PI4")
#define SUNXI_PINCTRL_PIN_PI5 PINCTRL_PIN(PI_BASE + 5, "PI5")
#define SUNXI_PINCTRL_PIN_PI6 PINCTRL_PIN(PI_BASE + 6, "PI6")
#define SUNXI_PINCTRL_PIN_PI7 PINCTRL_PIN(PI_BASE + 7, "PI7")
#define SUNXI_PINCTRL_PIN_PI8 PINCTRL_PIN(PI_BASE + 8, "PI8")
#define SUNXI_PINCTRL_PIN_PI9 PINCTRL_PIN(PI_BASE + 9, "PI9")
#define SUNXI_PINCTRL_PIN_PI10 PINCTRL_PIN(PI_BASE + 10, "PI10")
#define SUNXI_PINCTRL_PIN_PI11 PINCTRL_PIN(PI_BASE + 11, "PI11")
#define SUNXI_PINCTRL_PIN_PI12 PINCTRL_PIN(PI_BASE + 12, "PI12")
#define SUNXI_PINCTRL_PIN_PI13 PINCTRL_PIN(PI_BASE + 13, "PI13")
#define SUNXI_PINCTRL_PIN_PI14 PINCTRL_PIN(PI_BASE + 14, "PI14")
#define SUNXI_PINCTRL_PIN_PI15 PINCTRL_PIN(PI_BASE + 15, "PI15")
#define SUNXI_PINCTRL_PIN_PI16 PINCTRL_PIN(PI_BASE + 16, "PI16")
#define SUNXI_PINCTRL_PIN_PI17 PINCTRL_PIN(PI_BASE + 17, "PI17")
#define SUNXI_PINCTRL_PIN_PI18 PINCTRL_PIN(PI_BASE + 18, "PI18")
#define SUNXI_PINCTRL_PIN_PI19 PINCTRL_PIN(PI_BASE + 19, "PI19")
#define SUNXI_PINCTRL_PIN_PI20 PINCTRL_PIN(PI_BASE + 20, "PI20")
#define SUNXI_PINCTRL_PIN_PI21 PINCTRL_PIN(PI_BASE + 21, "PI21")
#define SUNXI_PINCTRL_PIN_PI22 PINCTRL_PIN(PI_BASE + 22, "PI22")
#define SUNXI_PINCTRL_PIN_PI23 PINCTRL_PIN(PI_BASE + 23, "PI23")
#define SUNXI_PINCTRL_PIN_PI24 PINCTRL_PIN(PI_BASE + 24, "PI24")
#define SUNXI_PINCTRL_PIN_PI25 PINCTRL_PIN(PI_BASE + 25, "PI25")
#define SUNXI_PINCTRL_PIN_PI26 PINCTRL_PIN(PI_BASE + 26, "PI26")
#define SUNXI_PINCTRL_PIN_PI27 PINCTRL_PIN(PI_BASE + 27, "PI27")
#define SUNXI_PINCTRL_PIN_PI28 PINCTRL_PIN(PI_BASE + 28, "PI28")
#define SUNXI_PINCTRL_PIN_PI29 PINCTRL_PIN(PI_BASE + 29, "PI29")
#define SUNXI_PINCTRL_PIN_PI30 PINCTRL_PIN(PI_BASE + 30, "PI30")
#define SUNXI_PINCTRL_PIN_PI31 PINCTRL_PIN(PI_BASE + 31, "PI31")
#define SUNXI_PIN_NAME_MAX_LEN 5
#define BANK_MEM_SIZE 0x24
#define MUX_REGS_OFFSET 0x0
#define DATA_REGS_OFFSET 0x10
#define DLEVEL_REGS_OFFSET 0x14
#define PULL_REGS_OFFSET 0x1c
#define PINS_PER_BANK 32
#define MUX_PINS_PER_REG 8
#define MUX_PINS_BITS 4
#define MUX_PINS_MASK 0x0f
#define DATA_PINS_PER_REG 32
#define DATA_PINS_BITS 1
#define DATA_PINS_MASK 0x01
#define DLEVEL_PINS_PER_REG 16
#define DLEVEL_PINS_BITS 2
#define DLEVEL_PINS_MASK 0x03
#define PULL_PINS_PER_REG 16
#define PULL_PINS_BITS 2
#define PULL_PINS_MASK 0x03
struct sunxi_desc_function {
const char *name;
u8 muxval;
};
struct sunxi_desc_pin {
struct pinctrl_pin_desc pin;
struct sunxi_desc_function *functions;
};
struct sunxi_pinctrl_desc {
const struct sunxi_desc_pin *pins;
int npins;
struct pinctrl_gpio_range *ranges;
int nranges;
};
struct sunxi_pinctrl_function {
const char *name;
const char **groups;
unsigned ngroups;
};
struct sunxi_pinctrl_group {
const char *name;
unsigned long config;
unsigned pin;
};
struct sunxi_pinctrl {
void __iomem *membase;
struct gpio_chip *chip;
struct sunxi_pinctrl_desc *desc;
struct device *dev;
struct sunxi_pinctrl_function *functions;
unsigned nfunctions;
struct sunxi_pinctrl_group *groups;
unsigned ngroups;
struct pinctrl_dev *pctl_dev;
};
#define SUNXI_PIN(_pin, ...) \
{ \
.pin = _pin, \
.functions = (struct sunxi_desc_function[]){ \
__VA_ARGS__, { } }, \
}
#define SUNXI_FUNCTION(_val, _name) \
{ \
.name = _name, \
.muxval = _val, \
}
/*
* The sunXi PIO registers are organized as is:
* 0x00 - 0x0c Muxing values.
* 8 pins per register, each pin having a 4bits value
* 0x10 Pin values
* 32 bits per register, each pin corresponding to one bit
* 0x14 - 0x18 Drive level
* 16 pins per register, each pin having a 2bits value
* 0x1c - 0x20 Pull-Up values
* 16 pins per register, each pin having a 2bits value
*
* This is for the first bank. Each bank will have the same layout,
* with an offset being a multiple of 0x24.
*
* The following functions calculate from the pin number the register
* and the bit offset that we should access.
*/
static inline u32 sunxi_mux_reg(u16 pin)
{
u8 bank = pin / PINS_PER_BANK;
u32 offset = bank * BANK_MEM_SIZE;
offset += MUX_REGS_OFFSET;
offset += pin % PINS_PER_BANK / MUX_PINS_PER_REG * 0x04;
return round_down(offset, 4);
}
static inline u32 sunxi_mux_offset(u16 pin)
{
u32 pin_num = pin % MUX_PINS_PER_REG;
return pin_num * MUX_PINS_BITS;
}
static inline u32 sunxi_data_reg(u16 pin)
{
u8 bank = pin / PINS_PER_BANK;
u32 offset = bank * BANK_MEM_SIZE;
offset += DATA_REGS_OFFSET;
offset += pin % PINS_PER_BANK / DATA_PINS_PER_REG * 0x04;
return round_down(offset, 4);
}
static inline u32 sunxi_data_offset(u16 pin)
{
u32 pin_num = pin % DATA_PINS_PER_REG;
return pin_num * DATA_PINS_BITS;
}
static inline u32 sunxi_dlevel_reg(u16 pin)
{
u8 bank = pin / PINS_PER_BANK;
u32 offset = bank * BANK_MEM_SIZE;
offset += DLEVEL_REGS_OFFSET;
offset += pin % PINS_PER_BANK / DLEVEL_PINS_PER_REG * 0x04;
return round_down(offset, 4);
}
static inline u32 sunxi_dlevel_offset(u16 pin)
{
u32 pin_num = pin % DLEVEL_PINS_PER_REG;
return pin_num * DLEVEL_PINS_BITS;
}
static inline u32 sunxi_pull_reg(u16 pin)
{
u8 bank = pin / PINS_PER_BANK;
u32 offset = bank * BANK_MEM_SIZE;
offset += PULL_REGS_OFFSET;
offset += pin % PINS_PER_BANK / PULL_PINS_PER_REG * 0x04;
return round_down(offset, 4);
}
static inline u32 sunxi_pull_offset(u16 pin)
{
u32 pin_num = pin % PULL_PINS_PER_REG;
return pin_num * PULL_PINS_BITS;
}
#endif /* __PINCTRL_SUNXI_H */

View File

@ -201,6 +201,7 @@ static const struct cfg_param {
{"nvidia,open-drain", TEGRA_PINCONF_PARAM_OPEN_DRAIN},
{"nvidia,lock", TEGRA_PINCONF_PARAM_LOCK},
{"nvidia,io-reset", TEGRA_PINCONF_PARAM_IORESET},
{"nvidia,rcv-sel", 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},
@ -208,6 +209,7 @@ static const struct cfg_param {
{"nvidia,pull-up-strength", TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH},
{"nvidia,slew-rate-falling", TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING},
{"nvidia,slew-rate-rising", TEGRA_PINCONF_PARAM_SLEW_RATE_RISING},
{"nvidia,drive-type", TEGRA_PINCONF_PARAM_DRIVE_TYPE},
};
static int tegra_pinctrl_dt_subnode_to_map(struct device *dev,
@ -450,6 +452,12 @@ static int tegra_pinconf_reg(struct tegra_pmx *pmx,
*bit = g->ioreset_bit;
*width = 1;
break;
case TEGRA_PINCONF_PARAM_RCV_SEL:
*bank = g->rcv_sel_bank;
*reg = g->rcv_sel_reg;
*bit = g->rcv_sel_bit;
*width = 1;
break;
case TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE:
*bank = g->drv_bank;
*reg = g->drv_reg;
@ -492,6 +500,12 @@ static int tegra_pinconf_reg(struct tegra_pmx *pmx,
*bit = g->slwr_bit;
*width = g->slwr_width;
break;
case TEGRA_PINCONF_PARAM_DRIVE_TYPE:
*bank = g->drvtype_bank;
*reg = g->drvtype_reg;
*bit = g->drvtype_bit;
*width = 2;
break;
default:
dev_err(pmx->dev, "Invalid config param %04x\n", param);
return -ENOTSUPP;

View File

@ -30,6 +30,8 @@ enum tegra_pinconf_param {
/* argument: Boolean */
TEGRA_PINCONF_PARAM_IORESET,
/* argument: Boolean */
TEGRA_PINCONF_PARAM_RCV_SEL,
/* argument: Boolean */
TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE,
/* argument: Boolean */
TEGRA_PINCONF_PARAM_SCHMITT,
@ -43,6 +45,8 @@ enum tegra_pinconf_param {
TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING,
/* argument: Integer, range is HW-dependant */
TEGRA_PINCONF_PARAM_SLEW_RATE_RISING,
/* argument: Integer, range is HW-dependant */
TEGRA_PINCONF_PARAM_DRIVE_TYPE,
};
enum tegra_pinconf_pull {
@ -95,6 +99,9 @@ struct tegra_function {
* @ioreset_reg: IO reset register offset. -1 if unsupported.
* @ioreset_bank: IO reset register bank. 0 if unsupported.
* @ioreset_bit: IO reset register bit. 0 if unsupported.
* @rcv_sel_reg: Receiver select offset. -1 if unsupported.
* @rcv_sel_bank: Receiver select bank. 0 if unsupported.
* @rcv_sel_bit: Receiver select bit. 0 if unsupported.
* @drv_reg: Drive fields register offset. -1 if unsupported.
* This register contains the hsm, schmitt, lpmd, drvdn,
* drvup, slwr, and slwf parameters.
@ -110,6 +117,9 @@ struct tegra_function {
* @slwr_width: Slew Rising field width. 0 if unsupported.
* @slwf_bit: Slew Falling register bit. 0 if unsupported.
* @slwf_width: Slew Falling field width. 0 if unsupported.
* @drvtype_reg: Drive type fields register offset. -1 if unsupported.
* @drvtype_bank: Drive type fields register bank. 0 if unsupported.
* @drvtype_bit: Drive type register bit. 0 if unsupported.
*
* A representation of a group of pins (possibly just one pin) in the Tegra
* pin controller. Each group allows some parameter or parameters to be
@ -131,15 +141,19 @@ struct tegra_pingroup {
s16 odrain_reg;
s16 lock_reg;
s16 ioreset_reg;
s16 rcv_sel_reg;
s16 drv_reg;
s16 drvtype_reg;
u32 mux_bank:2;
u32 pupd_bank:2;
u32 tri_bank:2;
u32 einput_bank:2;
u32 odrain_bank:2;
u32 ioreset_bank:2;
u32 rcv_sel_bank:2;
u32 lock_bank:2;
u32 drv_bank:2;
u32 drvtype_bank:2;
u32 mux_bit:5;
u32 pupd_bit:5;
u32 tri_bit:5;
@ -147,6 +161,7 @@ struct tegra_pingroup {
u32 odrain_bit:5;
u32 lock_bit:5;
u32 ioreset_bit:5;
u32 rcv_sel_bit:5;
u32 hsm_bit:5;
u32 schmitt_bit:5;
u32 lpmd_bit:5;
@ -154,6 +169,7 @@ struct tegra_pingroup {
u32 drvup_bit:5;
u32 slwr_bit:5;
u32 slwf_bit:5;
u32 drvtype_bit:5;
u32 drvdn_width:6;
u32 drvup_width:6;
u32 slwr_width:6;

File diff suppressed because it is too large Load Diff

View File

@ -2624,7 +2624,9 @@ static const struct tegra_function tegra20_functions[] = {
.odrain_reg = -1, \
.lock_reg = -1, \
.ioreset_reg = -1, \
.rcv_sel_reg = -1, \
.drv_reg = -1, \
.drvtype_reg = -1, \
}
/* Pin groups with only pull up and pull down control */
@ -2642,7 +2644,9 @@ static const struct tegra_function tegra20_functions[] = {
.odrain_reg = -1, \
.lock_reg = -1, \
.ioreset_reg = -1, \
.rcv_sel_reg = -1, \
.drv_reg = -1, \
.drvtype_reg = -1, \
}
/* Pin groups for drive strength registers (configurable version) */
@ -2660,6 +2664,7 @@ static const struct tegra_function tegra20_functions[] = {
.odrain_reg = -1, \
.lock_reg = -1, \
.ioreset_reg = -1, \
.rcv_sel_reg = -1, \
.drv_reg = ((r) - PINGROUP_REG_A), \
.drv_bank = 3, \
.hsm_bit = hsm_b, \
@ -2673,6 +2678,7 @@ static const struct tegra_function tegra20_functions[] = {
.slwr_width = slwr_w, \
.slwf_bit = slwf_b, \
.slwf_width = slwf_w, \
.drvtype_reg = -1, \
}
/* Pin groups for drive strength registers (simple version) */

View File

@ -3384,7 +3384,9 @@ static const struct tegra_function tegra30_functions[] = {
.ioreset_reg = PINGROUP_REG_##ior(r), \
.ioreset_bank = 1, \
.ioreset_bit = 8, \
.rcv_sel_reg = -1, \
.drv_reg = -1, \
.drvtype_reg = -1, \
}
#define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b, \
@ -3401,6 +3403,7 @@ static const struct tegra_function tegra30_functions[] = {
.odrain_reg = -1, \
.lock_reg = -1, \
.ioreset_reg = -1, \
.rcv_sel_reg = -1, \
.drv_reg = ((r) - DRV_PINGROUP_REG_A), \
.drv_bank = 0, \
.hsm_bit = hsm_b, \
@ -3414,6 +3417,7 @@ static const struct tegra_function tegra30_functions[] = {
.slwr_width = slwr_w, \
.slwf_bit = slwf_b, \
.slwf_width = slwf_w, \
.drvtype_reg = -1, \
}
static const struct tegra_pingroup tegra30_groups[] = {

View File

@ -441,17 +441,17 @@ static int xway_pinconf_get(struct pinctrl_dev *pctldev,
if (port == PORT3)
reg = GPIO3_OD;
else
reg = GPIO_OD(port);
reg = GPIO_OD(pin);
*config = LTQ_PINCONF_PACK(param,
!!gpio_getbit(info->membase[0], reg, PORT_PIN(port)));
!gpio_getbit(info->membase[0], reg, PORT_PIN(pin)));
break;
case LTQ_PINCONF_PARAM_PULL:
if (port == PORT3)
reg = GPIO3_PUDEN;
else
reg = GPIO_PUDEN(port);
if (!gpio_getbit(info->membase[0], reg, PORT_PIN(port))) {
reg = GPIO_PUDEN(pin);
if (!gpio_getbit(info->membase[0], reg, PORT_PIN(pin))) {
*config = LTQ_PINCONF_PACK(param, 0);
break;
}
@ -459,13 +459,18 @@ static int xway_pinconf_get(struct pinctrl_dev *pctldev,
if (port == PORT3)
reg = GPIO3_PUDSEL;
else
reg = GPIO_PUDSEL(port);
if (!gpio_getbit(info->membase[0], reg, PORT_PIN(port)))
reg = GPIO_PUDSEL(pin);
if (!gpio_getbit(info->membase[0], reg, PORT_PIN(pin)))
*config = LTQ_PINCONF_PACK(param, 2);
else
*config = LTQ_PINCONF_PACK(param, 1);
break;
case LTQ_PINCONF_PARAM_OUTPUT:
reg = GPIO_DIR(pin);
*config = LTQ_PINCONF_PACK(param,
gpio_getbit(info->membase[0], reg, PORT_PIN(pin)));
break;
default:
dev_err(pctldev->dev, "Invalid config param %04x\n", param);
return -ENOTSUPP;
@ -488,33 +493,44 @@ static int xway_pinconf_set(struct pinctrl_dev *pctldev,
if (port == PORT3)
reg = GPIO3_OD;
else
reg = GPIO_OD(port);
gpio_setbit(info->membase[0], reg, PORT_PIN(port));
reg = GPIO_OD(pin);
if (arg == 0)
gpio_setbit(info->membase[0], reg, PORT_PIN(pin));
else
gpio_clearbit(info->membase[0], reg, PORT_PIN(pin));
break;
case LTQ_PINCONF_PARAM_PULL:
if (port == PORT3)
reg = GPIO3_PUDEN;
else
reg = GPIO_PUDEN(port);
reg = GPIO_PUDEN(pin);
if (arg == 0) {
gpio_clearbit(info->membase[0], reg, PORT_PIN(port));
gpio_clearbit(info->membase[0], reg, PORT_PIN(pin));
break;
}
gpio_setbit(info->membase[0], reg, PORT_PIN(port));
gpio_setbit(info->membase[0], reg, PORT_PIN(pin));
if (port == PORT3)
reg = GPIO3_PUDSEL;
else
reg = GPIO_PUDSEL(port);
reg = GPIO_PUDSEL(pin);
if (arg == 1)
gpio_clearbit(info->membase[0], reg, PORT_PIN(port));
gpio_clearbit(info->membase[0], reg, PORT_PIN(pin));
else if (arg == 2)
gpio_setbit(info->membase[0], reg, PORT_PIN(port));
gpio_setbit(info->membase[0], reg, PORT_PIN(pin));
else
dev_err(pctldev->dev, "Invalid pull value %d\n", arg);
break;
case LTQ_PINCONF_PARAM_OUTPUT:
reg = GPIO_DIR(pin);
if (arg == 0)
gpio_clearbit(info->membase[0], reg, PORT_PIN(pin));
else
gpio_setbit(info->membase[0], reg, PORT_PIN(pin));
break;
default:
dev_err(pctldev->dev, "Invalid config param %04x\n", param);
return -ENOTSUPP;
@ -522,9 +538,24 @@ static int xway_pinconf_set(struct pinctrl_dev *pctldev,
return 0;
}
int xway_pinconf_group_set(struct pinctrl_dev *pctldev,
unsigned selector,
unsigned long config)
{
struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
int i, ret = 0;
for (i = 0; i < info->grps[selector].npins && !ret; i++)
ret = xway_pinconf_set(pctldev,
info->grps[selector].pins[i], config);
return ret;
}
static struct pinconf_ops xway_pinconf_ops = {
.pin_config_get = xway_pinconf_get,
.pin_config_set = xway_pinconf_set,
.pin_config_group_set = xway_pinconf_group_set,
};
static struct pinctrl_desc xway_pctrl_desc = {
@ -558,6 +589,7 @@ static inline int xway_mux_apply(struct pinctrl_dev *pctrldev,
static const struct ltq_cfg_param xway_cfg_params[] = {
{"lantiq,pull", LTQ_PINCONF_PARAM_PULL},
{"lantiq,open-drain", LTQ_PINCONF_PARAM_OPEN_DRAIN},
{"lantiq,output", LTQ_PINCONF_PARAM_OUTPUT},
};
static struct ltq_pinmux_info xway_info = {

View File

@ -21,6 +21,7 @@
#include <linux/compiler.h>
#include <linux/types.h>
#include <linux/mutex.h>
#include <linux/pinctrl/devinfo.h>
#include <linux/pm.h>
#include <linux/atomic.h>
#include <linux/ratelimit.h>
@ -620,6 +621,8 @@ struct acpi_dev_node {
* @pm_domain: Provide callbacks that are executed during system suspend,
* hibernation, system resume and during runtime PM transitions
* along with subsystem-level and driver-level callbacks.
* @pins: For device pin management.
* See Documentation/pinctrl.txt for details.
* @numa_node: NUMA node this device is close to.
* @dma_mask: Dma mask (if dma'ble device).
* @coherent_dma_mask: Like dma_mask, but for alloc_coherent mapping as not all
@ -672,6 +675,10 @@ struct device {
struct dev_pm_info power;
struct dev_pm_domain *pm_domain;
#ifdef CONFIG_PINCTRL
struct dev_pin_info *pins;
#endif
#ifdef CONFIG_NUMA
int numa_node; /* NUMA node this device is close to */
#endif

View File

@ -14,10 +14,20 @@
* registers.
*/
struct ab8500_gpio_platform_data {
struct abx500_gpio_platform_data {
int gpio_base;
u32 irq_base;
u8 config_reg[8];
};
enum abx500_gpio_pull_updown {
ABX500_GPIO_PULL_DOWN = 0x0,
ABX500_GPIO_PULL_NONE = 0x1,
ABX500_GPIO_PULL_UP = 0x3,
};
enum abx500_gpio_vinsel {
ABX500_GPIO_VINSEL_VBAT = 0x0,
ABX500_GPIO_VINSEL_VIN_1V8 = 0x1,
ABX500_GPIO_VINSEL_VDD_BIF = 0x2,
};
#endif /* _AB8500_GPIO_H */

View File

@ -24,7 +24,7 @@ enum ab8500_version {
AB8500_VERSION_AB8500 = 0x0,
AB8500_VERSION_AB8505 = 0x1,
AB8500_VERSION_AB9540 = 0x2,
AB8500_VERSION_AB8540 = 0x3,
AB8500_VERSION_AB8540 = 0x4,
AB8500_VERSION_UNDEFINED,
};
@ -32,6 +32,7 @@ enum ab8500_version {
#define AB8500_CUTEARLY 0x00
#define AB8500_CUT1P0 0x10
#define AB8500_CUT1P1 0x11
#define AB8500_CUT1P2 0x12 /* Only valid for AB8540 */
#define AB8500_CUT2P0 0x20
#define AB8500_CUT3P0 0x30
#define AB8500_CUT3P3 0x33
@ -39,6 +40,7 @@ enum ab8500_version {
/*
* AB8500 bank addresses
*/
#define AB8500_M_FSM_RANK 0x0
#define AB8500_SYS_CTRL1_BLOCK 0x1
#define AB8500_SYS_CTRL2_BLOCK 0x2
#define AB8500_REGU_CTRL1 0x3
@ -58,6 +60,7 @@ enum ab8500_version {
#define AB8500_DEVELOPMENT 0x11
#define AB8500_DEBUG 0x12
#define AB8500_PROD_TEST 0x13
#define AB8500_STE_TEST 0x14
#define AB8500_OTP_EMUL 0x15
/*
@ -65,11 +68,11 @@ enum ab8500_version {
* Values used to index into array ab8500_irq_regoffset[] defined in
* drivers/mdf/ab8500-core.c
*/
/* Definitions for AB8500 and AB9540 */
/* Definitions for AB8500, AB9540 and AB8540 */
/* ab8500_irq_regoffset[0] -> IT[Source|Latch|Mask]1 */
#define AB8500_INT_MAIN_EXT_CH_NOT_OK 0 /* not 8505/9540 */
#define AB8500_INT_UN_PLUG_TV_DET 1 /* not 8505/9540 */
#define AB8500_INT_PLUG_TV_DET 2 /* not 8505/9540 */
#define AB8500_INT_UN_PLUG_TV_DET 1 /* not 8505/9540/8540 */
#define AB8500_INT_PLUG_TV_DET 2 /* not 8505/9540/8540 */
#define AB8500_INT_TEMP_WARM 3
#define AB8500_INT_PON_KEY2DB_F 4
#define AB8500_INT_PON_KEY2DB_R 5
@ -77,18 +80,19 @@ enum ab8500_version {
#define AB8500_INT_PON_KEY1DB_R 7
/* ab8500_irq_regoffset[1] -> IT[Source|Latch|Mask]2 */
#define AB8500_INT_BATT_OVV 8
#define AB8500_INT_MAIN_CH_UNPLUG_DET 10 /* not 8505 */
#define AB8500_INT_MAIN_CH_PLUG_DET 11 /* not 8505 */
#define AB8500_INT_MAIN_CH_UNPLUG_DET 10 /* not 8505/8540 */
#define AB8500_INT_MAIN_CH_PLUG_DET 11 /* not 8505/8540 */
#define AB8500_INT_VBUS_DET_F 14
#define AB8500_INT_VBUS_DET_R 15
/* ab8500_irq_regoffset[2] -> IT[Source|Latch|Mask]3 */
#define AB8500_INT_VBUS_CH_DROP_END 16
#define AB8500_INT_RTC_60S 17
#define AB8500_INT_RTC_ALARM 18
#define AB8540_INT_BIF_INT 19
#define AB8500_INT_BAT_CTRL_INDB 20
#define AB8500_INT_CH_WD_EXP 21
#define AB8500_INT_VBUS_OVV 22
#define AB8500_INT_MAIN_CH_DROP_END 23 /* not 8505/9540 */
#define AB8500_INT_MAIN_CH_DROP_END 23 /* not 8505/9540/8540 */
/* ab8500_irq_regoffset[3] -> IT[Source|Latch|Mask]4 */
#define AB8500_INT_CCN_CONV_ACC 24
#define AB8500_INT_INT_AUD 25
@ -99,7 +103,7 @@ enum ab8500_version {
#define AB8500_INT_BUP_CHG_NOT_OK 30
#define AB8500_INT_BUP_CHG_OK 31
/* ab8500_irq_regoffset[4] -> IT[Source|Latch|Mask]5 */
#define AB8500_INT_GP_HW_ADC_CONV_END 32 /* not 8505 */
#define AB8500_INT_GP_HW_ADC_CONV_END 32 /* not 8505/8540 */
#define AB8500_INT_ACC_DETECT_1DB_F 33
#define AB8500_INT_ACC_DETECT_1DB_R 34
#define AB8500_INT_ACC_DETECT_22DB_F 35
@ -108,23 +112,23 @@ enum ab8500_version {
#define AB8500_INT_ACC_DETECT_21DB_R 38
#define AB8500_INT_GP_SW_ADC_CONV_END 39
/* ab8500_irq_regoffset[5] -> IT[Source|Latch|Mask]7 */
#define AB8500_INT_GPIO6R 40 /* not 8505/9540 */
#define AB8500_INT_GPIO7R 41 /* not 8505/9540 */
#define AB8500_INT_GPIO8R 42 /* not 8505/9540 */
#define AB8500_INT_GPIO9R 43 /* not 8505/9540 */
#define AB8500_INT_GPIO10R 44
#define AB8500_INT_GPIO11R 45
#define AB8500_INT_GPIO12R 46 /* not 8505 */
#define AB8500_INT_GPIO13R 47
#define AB8500_INT_GPIO6R 40 /* not 8505/9540/8540 */
#define AB8500_INT_GPIO7R 41 /* not 8505/9540/8540 */
#define AB8500_INT_GPIO8R 42 /* not 8505/9540/8540 */
#define AB8500_INT_GPIO9R 43 /* not 8505/9540/8540 */
#define AB8500_INT_GPIO10R 44 /* not 8540 */
#define AB8500_INT_GPIO11R 45 /* not 8540 */
#define AB8500_INT_GPIO12R 46 /* not 8505/8540 */
#define AB8500_INT_GPIO13R 47 /* not 8540 */
/* ab8500_irq_regoffset[6] -> IT[Source|Latch|Mask]8 */
#define AB8500_INT_GPIO24R 48 /* not 8505 */
#define AB8500_INT_GPIO25R 49 /* not 8505 */
#define AB8500_INT_GPIO36R 50 /* not 8505/9540 */
#define AB8500_INT_GPIO37R 51 /* not 8505/9540 */
#define AB8500_INT_GPIO38R 52 /* not 8505/9540 */
#define AB8500_INT_GPIO39R 53 /* not 8505/9540 */
#define AB8500_INT_GPIO40R 54
#define AB8500_INT_GPIO41R 55
#define AB8500_INT_GPIO24R 48 /* not 8505/8540 */
#define AB8500_INT_GPIO25R 49 /* not 8505/8540 */
#define AB8500_INT_GPIO36R 50 /* not 8505/9540/8540 */
#define AB8500_INT_GPIO37R 51 /* not 8505/9540/8540 */
#define AB8500_INT_GPIO38R 52 /* not 8505/9540/8540 */
#define AB8500_INT_GPIO39R 53 /* not 8505/9540/8540 */
#define AB8500_INT_GPIO40R 54 /* not 8540 */
#define AB8500_INT_GPIO41R 55 /* not 8540 */
/* ab8500_irq_regoffset[7] -> IT[Source|Latch|Mask]9 */
#define AB8500_INT_GPIO6F 56 /* not 8505/9540 */
#define AB8500_INT_GPIO7F 57 /* not 8505/9540 */
@ -135,14 +139,14 @@ enum ab8500_version {
#define AB8500_INT_GPIO12F 62 /* not 8505 */
#define AB8500_INT_GPIO13F 63
/* ab8500_irq_regoffset[8] -> IT[Source|Latch|Mask]10 */
#define AB8500_INT_GPIO24F 64 /* not 8505 */
#define AB8500_INT_GPIO25F 65 /* not 8505 */
#define AB8500_INT_GPIO36F 66 /* not 8505/9540 */
#define AB8500_INT_GPIO37F 67 /* not 8505/9540 */
#define AB8500_INT_GPIO38F 68 /* not 8505/9540 */
#define AB8500_INT_GPIO39F 69 /* not 8505/9540 */
#define AB8500_INT_GPIO40F 70
#define AB8500_INT_GPIO41F 71
#define AB8500_INT_GPIO24F 64 /* not 8505/8540 */
#define AB8500_INT_GPIO25F 65 /* not 8505/8540 */
#define AB8500_INT_GPIO36F 66 /* not 8505/9540/8540 */
#define AB8500_INT_GPIO37F 67 /* not 8505/9540/8540 */
#define AB8500_INT_GPIO38F 68 /* not 8505/9540/8540 */
#define AB8500_INT_GPIO39F 69 /* not 8505/9540/8540 */
#define AB8500_INT_GPIO40F 70 /* not 8540 */
#define AB8500_INT_GPIO41F 71 /* not 8540 */
/* ab8500_irq_regoffset[9] -> IT[Source|Latch|Mask]12 */
#define AB8500_INT_ADP_SOURCE_ERROR 72
#define AB8500_INT_ADP_SINK_ERROR 73
@ -160,42 +164,44 @@ enum ab8500_version {
#define AB8500_INT_SRP_DETECT 88
#define AB8500_INT_USB_CHARGER_NOT_OKR 89
#define AB8500_INT_ID_WAKEUP_R 90
#define AB8500_INT_ID_DET_PLUGR 91 /* 8505/9540 cut2.0 */
#define AB8500_INT_ID_DET_R1R 92
#define AB8500_INT_ID_DET_R2R 93
#define AB8500_INT_ID_DET_R3R 94
#define AB8500_INT_ID_DET_R4R 95
/* ab8500_irq_regoffset[12] -> IT[Source|Latch|Mask]21 */
#define AB8500_INT_ID_WAKEUP_F 96
#define AB8500_INT_ID_DET_R1F 98
#define AB8500_INT_ID_DET_R2F 99
#define AB8500_INT_ID_DET_R3F 100
#define AB8500_INT_ID_DET_R4F 101
#define AB8500_INT_CHAUTORESTARTAFTSEC 102
#define AB8500_INT_ID_WAKEUP_F 96 /* not 8505/9540 */
#define AB8500_INT_ID_DET_PLUGF 97 /* 8505/9540 cut2.0 */
#define AB8500_INT_ID_DET_R1F 98 /* not 8505/9540 */
#define AB8500_INT_ID_DET_R2F 99 /* not 8505/9540 */
#define AB8500_INT_ID_DET_R3F 100 /* not 8505/9540 */
#define AB8500_INT_ID_DET_R4F 101 /* not 8505/9540 */
#define AB8500_INT_CHAUTORESTARTAFTSEC 102 /* not 8505/9540 */
#define AB8500_INT_CHSTOPBYSEC 103
/* ab8500_irq_regoffset[13] -> IT[Source|Latch|Mask]22 */
#define AB8500_INT_USB_CH_TH_PROT_F 104
#define AB8500_INT_USB_CH_TH_PROT_R 105
#define AB8500_INT_USB_CH_TH_PROT_R 105
#define AB8500_INT_MAIN_CH_TH_PROT_F 106 /* not 8505/9540 */
#define AB8500_INT_MAIN_CH_TH_PROT_R 107 /* not 8505/9540 */
#define AB8500_INT_CHCURLIMNOHSCHIRP 109
#define AB8500_INT_CHCURLIMHSCHIRP 110
#define AB8500_INT_XTAL32K_KO 111
/* Definitions for AB9540 */
/* Definitions for AB9540 / AB8505 */
/* ab8500_irq_regoffset[14] -> IT[Source|Latch|Mask]13 */
#define AB9540_INT_GPIO50R 113
#define AB9540_INT_GPIO51R 114 /* not 8505 */
#define AB9540_INT_GPIO52R 115
#define AB9540_INT_GPIO53R 116
#define AB9540_INT_GPIO54R 117 /* not 8505 */
#define AB9540_INT_GPIO50R 113 /* not 8540 */
#define AB9540_INT_GPIO51R 114 /* not 8505/8540 */
#define AB9540_INT_GPIO52R 115 /* not 8540 */
#define AB9540_INT_GPIO53R 116 /* not 8540 */
#define AB9540_INT_GPIO54R 117 /* not 8505/8540 */
#define AB9540_INT_IEXT_CH_RF_BFN_R 118
#define AB9540_INT_IEXT_CH_RF_BFN_F 119
/* ab8500_irq_regoffset[15] -> IT[Source|Latch|Mask]14 */
#define AB9540_INT_GPIO50F 121
#define AB9540_INT_GPIO51F 122 /* not 8505 */
#define AB9540_INT_GPIO52F 123
#define AB9540_INT_GPIO53F 124
#define AB9540_INT_GPIO54F 125 /* not 8505 */
#define AB9540_INT_GPIO50F 121 /* not 8540 */
#define AB9540_INT_GPIO51F 122 /* not 8505/8540 */
#define AB9540_INT_GPIO52F 123 /* not 8540 */
#define AB9540_INT_GPIO53F 124 /* not 8540 */
#define AB9540_INT_GPIO54F 125 /* not 8505/8540 */
#define AB9540_INT_IEXT_CH_RF_BFN_F 126
/* ab8500_irq_regoffset[16] -> IT[Source|Latch|Mask]25 */
#define AB8505_INT_KEYSTUCK 128
#define AB8505_INT_IKR 129
@ -204,6 +210,87 @@ enum ab8500_version {
#define AB8505_INT_KEYDEGLITCH 132
#define AB8505_INT_MODPWRSTATUSF 134
#define AB8505_INT_MODPWRSTATUSR 135
/* ab8500_irq_regoffset[17] -> IT[Source|Latch|Mask]6 */
#define AB8500_INT_HOOK_DET_NEG_F 138
#define AB8500_INT_HOOK_DET_NEG_R 139
#define AB8500_INT_HOOK_DET_POS_F 140
#define AB8500_INT_HOOK_DET_POS_R 141
#define AB8500_INT_PLUG_DET_COMP_F 142
#define AB8500_INT_PLUG_DET_COMP_R 143
/* ab8500_irq_regoffset[18] -> IT[Source|Latch|Mask]23 */
#define AB8505_INT_COLL 144
#define AB8505_INT_RESERR 145
#define AB8505_INT_FRAERR 146
#define AB8505_INT_COMERR 147
#define AB8505_INT_SPDSET 148
#define AB8505_INT_DSENT 149
#define AB8505_INT_DREC 150
#define AB8505_INT_ACC_INT 151
/* ab8500_irq_regoffset[19] -> IT[Source|Latch|Mask]24 */
#define AB8505_INT_NOPINT 152
/* ab8540_irq_regoffset[20] -> IT[Source|Latch|Mask]26 */
#define AB8540_INT_IDPLUGDETCOMPF 160
#define AB8540_INT_IDPLUGDETCOMPR 161
#define AB8540_INT_FMDETCOMPLOF 162
#define AB8540_INT_FMDETCOMPLOR 163
#define AB8540_INT_FMDETCOMPHIF 164
#define AB8540_INT_FMDETCOMPHIR 165
#define AB8540_INT_ID5VDETCOMPF 166
#define AB8540_INT_ID5VDETCOMPR 167
/* ab8540_irq_regoffset[21] -> IT[Source|Latch|Mask]27 */
#define AB8540_INT_GPIO43F 168
#define AB8540_INT_GPIO43R 169
#define AB8540_INT_GPIO44F 170
#define AB8540_INT_GPIO44R 171
#define AB8540_INT_KEYPOSDETCOMPF 172
#define AB8540_INT_KEYPOSDETCOMPR 173
#define AB8540_INT_KEYNEGDETCOMPF 174
#define AB8540_INT_KEYNEGDETCOMPR 175
/* ab8540_irq_regoffset[22] -> IT[Source|Latch|Mask]28 */
#define AB8540_INT_GPIO1VBATF 176
#define AB8540_INT_GPIO1VBATR 177
#define AB8540_INT_GPIO2VBATF 178
#define AB8540_INT_GPIO2VBATR 179
#define AB8540_INT_GPIO3VBATF 180
#define AB8540_INT_GPIO3VBATR 181
#define AB8540_INT_GPIO4VBATF 182
#define AB8540_INT_GPIO4VBATR 183
/* ab8540_irq_regoffset[23] -> IT[Source|Latch|Mask]29 */
#define AB8540_INT_SYSCLKREQ2F 184
#define AB8540_INT_SYSCLKREQ2R 185
#define AB8540_INT_SYSCLKREQ3F 186
#define AB8540_INT_SYSCLKREQ3R 187
#define AB8540_INT_SYSCLKREQ4F 188
#define AB8540_INT_SYSCLKREQ4R 189
#define AB8540_INT_SYSCLKREQ5F 190
#define AB8540_INT_SYSCLKREQ5R 191
/* ab8540_irq_regoffset[24] -> IT[Source|Latch|Mask]30 */
#define AB8540_INT_PWMOUT1F 192
#define AB8540_INT_PWMOUT1R 193
#define AB8540_INT_PWMCTRL0F 194
#define AB8540_INT_PWMCTRL0R 195
#define AB8540_INT_PWMCTRL1F 196
#define AB8540_INT_PWMCTRL1R 197
#define AB8540_INT_SYSCLKREQ6F 198
#define AB8540_INT_SYSCLKREQ6R 199
/* ab8540_irq_regoffset[25] -> IT[Source|Latch|Mask]31 */
#define AB8540_INT_PWMEXTVIBRA1F 200
#define AB8540_INT_PWMEXTVIBRA1R 201
#define AB8540_INT_PWMEXTVIBRA2F 202
#define AB8540_INT_PWMEXTVIBRA2R 203
#define AB8540_INT_PWMOUT2F 204
#define AB8540_INT_PWMOUT2R 205
#define AB8540_INT_PWMOUT3F 206
#define AB8540_INT_PWMOUT3R 207
/* ab8540_irq_regoffset[26] -> IT[Source|Latch|Mask]32 */
#define AB8540_INT_ADDATA2F 208
#define AB8540_INT_ADDATA2R 209
#define AB8540_INT_DADATA2F 210
#define AB8540_INT_DADATA2R 211
#define AB8540_INT_FSYNC2F 212
#define AB8540_INT_FSYNC2R 213
#define AB8540_INT_BITCLK2F 214
#define AB8540_INT_BITCLK2R 215
/*
* AB8500_AB9540_NR_IRQS is used when configuring the IRQ numbers for the
@ -213,13 +300,24 @@ enum ab8500_version {
* which is larger.
*/
#define AB8500_NR_IRQS 112
#define AB8505_NR_IRQS 136
#define AB9540_NR_IRQS 136
#define AB8505_NR_IRQS 153
#define AB9540_NR_IRQS 153
#define AB8540_NR_IRQS 216
/* This is set to the roof of any AB8500 chip variant IRQ counts */
#define AB8500_MAX_NR_IRQS AB9540_NR_IRQS
#define AB8500_MAX_NR_IRQS AB8540_NR_IRQS
#define AB8500_NUM_IRQ_REGS 14
#define AB9540_NUM_IRQ_REGS 17
#define AB9540_NUM_IRQ_REGS 20
#define AB8540_NUM_IRQ_REGS 27
/* Turn On Status Event */
#define AB8500_POR_ON_VBAT 0x01
#define AB8500_POW_KEY_1_ON 0x02
#define AB8500_POW_KEY_2_ON 0x04
#define AB8500_RTC_ALARM 0x08
#define AB8500_MAIN_CH_DET 0x10
#define AB8500_VBUS_DET 0x20
#define AB8500_USB_ID_DET 0x40
/**
* struct ab8500 - ab8500 internal structure
@ -287,7 +385,7 @@ struct ab8500_platform_data {
struct ab8500_regulator_reg_init *regulator_reg_init;
int num_regulator;
struct regulator_init_data *regulator;
struct ab8500_gpio_platform_data *gpio;
struct abx500_gpio_platform_data *gpio;
struct ab8500_codec_platform_data *codec;
};
@ -335,10 +433,79 @@ static inline int is_ab8500_2p0_or_earlier(struct ab8500 *ab)
return (is_ab8500(ab) && (ab->chip_id <= AB8500_CUT2P0));
}
static inline int is_ab8500_3p3_or_earlier(struct ab8500 *ab)
{
return (is_ab8500(ab) && (ab->chip_id <= AB8500_CUT3P3));
}
/* exclude also ab8505, ab9540... */
static inline int is_ab8500_2p0(struct ab8500 *ab)
{
return (is_ab8500(ab) && (ab->chip_id == AB8500_CUT2P0));
}
static inline int is_ab8505_1p0_or_earlier(struct ab8500 *ab)
{
return (is_ab8505(ab) && (ab->chip_id <= AB8500_CUT1P0));
}
static inline int is_ab8505_2p0(struct ab8500 *ab)
{
return (is_ab8505(ab) && (ab->chip_id == AB8500_CUT2P0));
}
static inline int is_ab9540_1p0_or_earlier(struct ab8500 *ab)
{
return (is_ab9540(ab) && (ab->chip_id <= AB8500_CUT1P0));
}
static inline int is_ab9540_2p0(struct ab8500 *ab)
{
return (is_ab9540(ab) && (ab->chip_id == AB8500_CUT2P0));
}
/*
* Be careful, the marketing name for this chip is 2.1
* but the value read from the chip is 3.0 (0x30)
*/
static inline int is_ab9540_3p0(struct ab8500 *ab)
{
return (is_ab9540(ab) && (ab->chip_id == AB8500_CUT3P0));
}
static inline int is_ab8540_1p0_or_earlier(struct ab8500 *ab)
{
return is_ab8540(ab) && (ab->chip_id <= AB8500_CUT1P0);
}
static inline int is_ab8540_1p1_or_earlier(struct ab8500 *ab)
{
return is_ab8540(ab) && (ab->chip_id <= AB8500_CUT1P1);
}
static inline int is_ab8540_1p2_or_earlier(struct ab8500 *ab)
{
return is_ab8540(ab) && (ab->chip_id <= AB8500_CUT1P2);
}
static inline int is_ab8540_2p0_or_earlier(struct ab8500 *ab)
{
return is_ab8540(ab) && (ab->chip_id <= AB8500_CUT2P0);
}
static inline int is_ab8540_2p0(struct ab8500 *ab)
{
return is_ab8540(ab) && (ab->chip_id == AB8500_CUT2P0);
}
static inline int is_ab8505_2p0_earlier(struct ab8500 *ab)
{
return (is_ab8505(ab) && (ab->chip_id < AB8500_CUT2P0));
}
static inline int is_ab9540_2p0_or_earlier(struct ab8500 *ab)
{
return (is_ab9540(ab) && (ab->chip_id < AB8500_CUT2P0));
}
#endif /* MFD_AB8500_H */

View File

@ -0,0 +1,45 @@
/*
* Per-device information from the pin control system.
* This is the stuff that get included into the device
* core.
*
* Copyright (C) 2012 ST-Ericsson SA
* Written on behalf of Linaro for ST-Ericsson
* This interface is used in the core to keep track of pins.
*
* Author: Linus Walleij <linus.walleij@linaro.org>
*
* License terms: GNU General Public License (GPL) version 2
*/
#ifndef PINCTRL_DEVINFO_H
#define PINCTRL_DEVINFO_H
#ifdef CONFIG_PINCTRL
/* The device core acts as a consumer toward pinctrl */
#include <linux/pinctrl/consumer.h>
/**
* struct dev_pin_info - pin state container for devices
* @p: pinctrl handle for the containing device
* @default_state: the default state for the handle, if found
*/
struct dev_pin_info {
struct pinctrl *p;
struct pinctrl_state *default_state;
};
extern int pinctrl_bind_pins(struct device *dev);
#else
/* Stubs if we're not using pinctrl */
static inline int pinctrl_bind_pins(struct device *dev)
{
return 0;
}
#endif /* CONFIG_PINCTRL */
#endif /* PINCTRL_DEVINFO_H */

View File

@ -46,7 +46,11 @@
* @PIN_CONFIG_DRIVE_OPEN_SOURCE: the pin will be driven with open source
* (open emitter). Sending this config will enabale open drain mode, the
* argument is ignored.
* @PIN_CONFIG_INPUT_SCHMITT_DISABLE: disable schmitt-trigger mode on the pin.
* @PIN_CONFIG_DRIVE_STRENGTH: the pin will output the current passed as
* argument. The argument is in mA.
* @PIN_CONFIG_INPUT_SCHMITT_ENABLE: control schmitt-trigger mode on the pin.
* If the argument != 0, schmitt-trigger mode is enabled. If it's 0,
* schmitt-trigger mode is disabled.
* @PIN_CONFIG_INPUT_SCHMITT: this will configure an input pin to run in
* schmitt-trigger mode. If the schmitt-trigger has adjustable hysteresis,
* the threshold value is given on a custom format as argument when
@ -58,10 +62,15 @@
* @PIN_CONFIG_POWER_SOURCE: if the pin can select between different power
* supplies, the argument to this parameter (on a custom format) tells
* the driver which alternative power source to use.
* @PIN_CONFIG_SLEW_RATE: if the pin can select slew rate, the argument to
* this parameter (on a custom format) tells the driver which alternative
* slew rate to use.
* @PIN_CONFIG_LOW_POWER_MODE: this will configure the pin for low power
* operation, if several modes of operation are supported these can be
* passed in the argument on a custom form, else just use argument 1
* to indicate low power mode, argument 0 turns low power mode off.
* @PIN_CONFIG_OUTPUT: this will configure the pin in output, use argument
* 1 to indicate high level, argument 0 to indicate low level.
* @PIN_CONFIG_END: this is the last enumerator for pin configurations, if
* you need to pass in custom configurations to the pin controller, use
* PIN_CONFIG_END+1 as the base offset.
@ -74,11 +83,14 @@ enum pin_config_param {
PIN_CONFIG_DRIVE_PUSH_PULL,
PIN_CONFIG_DRIVE_OPEN_DRAIN,
PIN_CONFIG_DRIVE_OPEN_SOURCE,
PIN_CONFIG_INPUT_SCHMITT_DISABLE,
PIN_CONFIG_DRIVE_STRENGTH,
PIN_CONFIG_INPUT_SCHMITT_ENABLE,
PIN_CONFIG_INPUT_SCHMITT,
PIN_CONFIG_INPUT_DEBOUNCE,
PIN_CONFIG_POWER_SOURCE,
PIN_CONFIG_SLEW_RATE,
PIN_CONFIG_LOW_POWER_MODE,
PIN_CONFIG_OUTPUT,
PIN_CONFIG_END = 0x7FFF,
};

View File

@ -154,6 +154,7 @@ struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
#endif /* CONFIG_OF */
extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev);
extern const char *pinctrl_dev_get_devname(struct pinctrl_dev *pctldev);
extern void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev);
#else