Pin control changes for the v3.19 series:

- Force conversion of the ux500 pin control device trees
   and parsers to use the generic pin control bindings.
 - New driver and device tree bindings for the Qualcomm
   PMIC MPP pin controller and GPIO.
 - Some ACPI infrastructure for pin controllers.
 - New driver for the Intel CherryView/Braswell pin controller,
   the first Intel pin controller to fully take advantage of
   the pin control subsystem.
 - Support the Freescale i.MX VF610 variant.
 - Support the sunxi A80 variant.
 - Support the Samsung Exynos 4415 and Exynos 7 variants.
 - Split out Intel pin controllers to their own subdirectory.
 - A large slew of rockchip pin control updates, including
   suspend/resume support.
 - A large slew of Samsung Exynos pin controller updates.
 - Various minor updates and fixes.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJUhrHUAAoJEEEQszewGV1zPZsQAMzWjGKcZhyBDWyTsHM/E9nN
 csRIcVdXs+OggH0nr2YNm2AAh+nRlp4DAQCB7S83SLfKFHF4oWT8SlornEl7WKdN
 zcVUbV29LtHkotjtVoGQZmjuJx+uvHlWJt7moTKJsAMTeNyXv25jEp0LGETji24A
 xsIQ+Bp+G9IYZqK1dlJFPva1YMjjt9sBhJqKnOhh5Z+wjj3YdT7z5LW1x001GPju
 kwKumgxOL7qKjvyaI7n2z+9VhGu9zAvoxK2gLOgjgtFQODASLS/gk2oCuRi/fIpn
 RqE+YyfrNSeMKpOjZOXc/R0SRtOkhyvMBYbgQrAX04nio4pbT6x2XgclAe6v7O5Q
 T3GmOR2JZblwrzEPRs5mGBC9p7fd488ToHAPg5ojNH5F70hDkC8wSYYJZmaL+ORw
 umyxRlRjIbQ4vs6cZMlz/NksqpQyqCTMuBRLllo/jsSQlk0Vo3Gdci5J/T10lKd2
 ciX6AxlRKaRyRo+W6/i01xcX7SzzmNZoOCMXWSjsPv7Th+Gm7vIKyVeNOUkiqUXH
 1fVjw/M0AhIttVRbx1qTPsqFaDI/WPPk9EUvVm3W7DFuf0/w9B0HkZe6KpXdp33K
 GV6gEMvmTObvUpwYrYEi7hhKVl+cJ902ZMR/LSmK0QdADhI98pjsokDrigl+Jy93
 U1OepT70fw4mgJnqnevZ
 =sxpe
 -----END PGP SIGNATURE-----

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

Pull pin control changes from Linus Walleij:
 "Here is a stash of pin control changes I have collected for the v3.19
  series.  Mainly new hardware support, with Intels new embedded SoC as
  the especially interesting thing standing out, fully using the
  subsystem.

   - Force conversion of the ux500 pin control device trees and parsers
     to use the generic pin control bindings.
   - New driver and device tree bindings for the Qualcomm PMIC MPP pin
     controller and GPIO.
   - Some ACPI infrastructure for pin controllers.
   - New driver for the Intel CherryView/Braswell pin controller, the
     first Intel pin controller to fully take advantage of the pin
     control subsystem.
   - Support the Freescale i.MX VF610 variant.
   - Support the sunxi A80 variant.
   - Support the Samsung Exynos 4415 and Exynos 7 variants.
   - Split out Intel pin controllers to their own subdirectory.
   - A large slew of rockchip pin control updates, including
     suspend/resume support.
   - A large slew of Samsung Exynos pin controller updates.
   - Various minor updates and fixes"

* tag 'pinctrl-v3.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (49 commits)
  pinctrl: at91: enhance (debugfs) at91_gpio_dbg_show
  pinctrl: meson: add device tree bindings documentation
  gpio: tz1090: Fix error handling of irq_of_parse_and_map
  pinctrl: tz1090-pinctrl.txt: Fix typo in binding
  pinctrl: pinconf-generic: Declare dt_params/conf_items const
  pinctrl: exynos: Add support for Exynos4415
  pinctrl: exynos: Add initial driver data for Exynos7
  pinctrl: exynos: Add irq_chip instance for Exynos7 wakeup interrupts
  pinctrl: exynos: Consolidate irq domain callbacks
  pinctrl: exynos: Generalize the eint16_31 demux code
  pinctrl: samsung: Separate per-bank init and runtime data
  pinctrl: samsung: Constify samsung_pin_ctrl struct
  pinctrl: samsung: Constify samsung_pin_bank_type struct
  pinctrl: samsung: Drop unused label field in samsung_pin_ctrl struct
  pinctrl: samsung: Make samsung_pinctrl_get_soc_data use ERR_PTR()
  pinctrl: Add Intel Cherryview/Braswell pin controller support
  gpio / ACPI: Add knowledge about pin controllers to acpi_get_gpiod()
  pinctrl: Fix path error in documentation
  pinctrl: rockchip: save and restore gpio6_c6 pinmux in suspend/resume
  pinctrl: rockchip: add suspend/resume functions
  ...
This commit is contained in:
Linus Torvalds 2014-12-11 10:43:14 -08:00
commit c1b30e4d94
56 changed files with 6160 additions and 819 deletions

View file

@ -67,7 +67,7 @@ Valid values for pin and group names are:
They also all support the some form of muxing. Any pins which are contained
in one of the mux groups (see below) can be muxed only to the functions
supported by the mux group. All other pins can be muxed to the "perip"
function which which enables them with their intended peripheral.
function which enables them with their intended peripheral.
Different pins in the same mux group cannot be muxed to different functions,
however it is possible to mux only a subset of the pins in a mux group to a

View file

@ -0,0 +1,96 @@
== Amlogic Meson pinmux controller ==
Required properties for the root node:
- compatible: "amlogic,meson8-pinctrl"
- reg: address and size of registers controlling irq functionality
=== GPIO sub-nodes ===
The 2 power domains of the controller (regular and always-on) are
represented as sub-nodes and each of them acts as a GPIO controller.
Required properties for sub-nodes are:
- reg: should contain address and size for mux, pull-enable, pull and
gpio register sets
- reg-names: an array of strings describing the "reg" entries. Must
contain "mux", "pull" and "gpio". "pull-enable" is optional and
when it is missing the "pull" registers are used instead
- gpio-controller: identifies the node as a gpio controller
- #gpio-cells: must be 2
Valid sub-node names are:
- "banks" for the regular domain
- "ao-bank" for the always-on domain
=== Other sub-nodes ===
Child nodes without the "gpio-controller" represent some desired
configuration for a pin or a group. Those nodes can be pinmux nodes or
configuration nodes.
Required properties for pinmux nodes are:
- groups: a list of pinmux groups. The list of all available groups
depends on the SoC and can be found in driver sources.
- function: the name of a function to activate for the specified set
of groups. The list of all available functions depends on the SoC
and can be found in driver sources.
Required properties for configuration nodes:
- pins: a list of pin names
Configuration nodes support the generic properties "bias-disable",
"bias-pull-up" and "bias-pull-down", described in file
pinctrl-bindings.txt
=== Example ===
pinctrl: pinctrl@c1109880 {
compatible = "amlogic,meson8-pinctrl";
reg = <0xc1109880 0x10>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
gpio: banks@c11080b0 {
reg = <0xc11080b0 0x28>,
<0xc11080e8 0x18>,
<0xc1108120 0x18>,
<0xc1108030 0x30>;
reg-names = "mux", "pull", "pull-enable", "gpio";
gpio-controller;
#gpio-cells = <2>;
};
gpio_ao: ao-bank@c1108030 {
reg = <0xc8100014 0x4>,
<0xc810002c 0x4>,
<0xc8100024 0x8>;
reg-names = "mux", "pull", "gpio";
gpio-controller;
#gpio-cells = <2>;
};
nand {
mux {
groups = "nand_io", "nand_io_ce0", "nand_io_ce1",
"nand_io_rb0", "nand_ale", "nand_cle",
"nand_wen_clk", "nand_ren_clk", "nand_dqs",
"nand_ce2", "nand_ce3";
function = "nand";
};
};
uart_ao_a {
mux {
groups = "uart_tx_ao_a", "uart_rx_ao_a",
"uart_cts_ao_a", "uart_rts_ao_a";
function = "uart_ao";
};
conf {
pins = "GPIOAO_0", "GPIOAO_1",
"GPIOAO_2", "GPIOAO_3";
bias-disable;
};
};
};

View file

@ -216,4 +216,4 @@ arguments are described below.
or 0 to disable debouncing
More in-depth documentation on these parameters can be found in
<include/linux/pinctrl/pinconfig-generic.h>
<include/linux/pinctrl/pinconf-generic.h>

View file

@ -0,0 +1,215 @@
Qualcomm PMIC GPIO block
This binding describes the GPIO block(s) found in the 8xxx series of
PMIC's from Qualcomm.
- compatible:
Usage: required
Value type: <string>
Definition: must be one of:
"qcom,pm8018-gpio"
"qcom,pm8038-gpio"
"qcom,pm8058-gpio"
"qcom,pm8917-gpio"
"qcom,pm8921-gpio"
"qcom,pm8941-gpio"
"qcom,pma8084-gpio"
- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: Register base of the GPIO block and length.
- interrupts:
Usage: required
Value type: <prop-encoded-array>
Definition: Must contain an array of encoded interrupt specifiers for
each available GPIO
- gpio-controller:
Usage: required
Value type: <none>
Definition: Mark the device node as a GPIO controller
- #gpio-cells:
Usage: required
Value type: <u32>
Definition: Must be 2;
the first cell will be used to define gpio number and the
second denotes the flags for this gpio
Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
a general description of GPIO and interrupt bindings.
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices, including the meaning of the
phrase "pin configuration node".
The pin configuration nodes act as a container for an arbitrary number of
subnodes. Each of these subnodes represents some desired configuration for a
pin or a list of pins. This configuration can include the
mux function to select on those pin(s), and various pin configuration
parameters, as listed below.
SUBNODES:
The name of each subnode is not important; all subnodes should be enumerated
and processed purely based on their content.
Each subnode only affects those parameters that are explicitly listed. In
other words, a subnode that lists a mux function but no pin configuration
parameters implies no information about any pin configuration parameters.
Similarly, a pin subnode that describes a pullup parameter implies no
information about e.g. the mux function.
The following generic properties as defined in pinctrl-bindings.txt are valid
to specify in a pin configuration subnode:
- pins:
Usage: required
Value type: <string-array>
Definition: List of gpio pins affected by the properties specified in
this subnode. Valid pins are:
gpio1-gpio6 for pm8018
gpio1-gpio12 for pm8038
gpio1-gpio40 for pm8058
gpio1-gpio38 for pm8917
gpio1-gpio44 for pm8921
gpio1-gpio36 for pm8941
gpio1-gpio22 for pma8084
- function:
Usage: required
Value type: <string>
Definition: Specify the alternative function to be configured for the
specified pins. Valid values are:
"normal",
"paired",
"func1",
"func2",
"dtest1",
"dtest2",
"dtest3",
"dtest4"
- bias-disable:
Usage: optional
Value type: <none>
Definition: The specified pins should be configured as no pull.
- bias-pull-down:
Usage: optional
Value type: <none>
Definition: The specified pins should be configured as pull down.
- bias-pull-up:
Usage: optional
Value type: <empty>
Definition: The specified pins should be configured as pull up.
- qcom,pull-up-strength:
Usage: optional
Value type: <u32>
Definition: Specifies the strength to use for pull up, if selected.
Valid values are; as defined in
<dt-bindings/pinctrl/qcom,pmic-gpio.h>:
1: 30uA (PMIC_GPIO_PULL_UP_30)
2: 1.5uA (PMIC_GPIO_PULL_UP_1P5)
3: 31.5uA (PMIC_GPIO_PULL_UP_31P5)
4: 1.5uA + 30uA boost (PMIC_GPIO_PULL_UP_1P5_30)
If this property is ommited 30uA strength will be used if
pull up is selected
- bias-high-impedance:
Usage: optional
Value type: <none>
Definition: The specified pins will put in high-Z mode and disabled.
- input-enable:
Usage: optional
Value type: <none>
Definition: The specified pins are put in input mode.
- output-high:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
high.
- output-low:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
low.
- power-source:
Usage: optional
Value type: <u32>
Definition: Selects the power source for the specified pins. Valid
power sources are defined per chip in
<dt-bindings/pinctrl/qcom,pmic-gpio.h>
- qcom,drive-strength:
Usage: optional
Value type: <u32>
Definition: Selects the drive strength for the specified pins. Value
drive strengths are:
0: no (PMIC_GPIO_STRENGTH_NO)
1: high (PMIC_GPIO_STRENGTH_HIGH) 0.9mA @ 1.8V - 1.9mA @ 2.6V
2: medium (PMIC_GPIO_STRENGTH_MED) 0.6mA @ 1.8V - 1.25mA @ 2.6V
3: low (PMIC_GPIO_STRENGTH_LOW) 0.15mA @ 1.8V - 0.3mA @ 2.6V
as defined in <dt-bindings/pinctrl/qcom,pmic-gpio.h>
- drive-push-pull:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in push-pull mode.
- drive-open-drain:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in open-drain mode.
- drive-open-source:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in open-source mode.
Example:
pm8921_gpio: gpio@150 {
compatible = "qcom,pm8921-gpio";
reg = <0x150 0x160>;
interrupts = <192 1>, <193 1>, <194 1>,
<195 1>, <196 1>, <197 1>,
<198 1>, <199 1>, <200 1>,
<201 1>, <202 1>, <203 1>,
<204 1>, <205 1>, <206 1>,
<207 1>, <208 1>, <209 1>,
<210 1>, <211 1>, <212 1>,
<213 1>, <214 1>, <215 1>,
<216 1>, <217 1>, <218 1>,
<219 1>, <220 1>, <221 1>,
<222 1>, <223 1>, <224 1>,
<225 1>, <226 1>, <227 1>,
<228 1>, <229 1>, <230 1>,
<231 1>, <232 1>, <233 1>,
<234 1>, <235 1>;
gpio-controller;
#gpio-cells = <2>;
pm8921_gpio_keys: gpio-keys {
volume-keys {
pins = "gpio20", "gpio21";
function = "normal";
input-enable;
bias-pull-up;
drive-push-pull;
qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>;
power-source = <PM8921_GPIO_S4>;
};
};
};

View file

@ -0,0 +1,162 @@
Qualcomm PMIC Multi-Purpose Pin (MPP) block
This binding describes the MPP block(s) found in the 8xxx series
of PMIC's from Qualcomm.
- compatible:
Usage: required
Value type: <string>
Definition: Should contain one of:
"qcom,pm8841-mpp",
"qcom,pm8941-mpp",
"qcom,pma8084-mpp",
- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: Register base of the MPP block and length.
- interrupts:
Usage: required
Value type: <prop-encoded-array>
Definition: Must contain an array of encoded interrupt specifiers for
each available MPP
- gpio-controller:
Usage: required
Value type: <none>
Definition: Mark the device node as a GPIO controller
- #gpio-cells:
Usage: required
Value type: <u32>
Definition: Must be 2;
the first cell will be used to define MPP number and the
second denotes the flags for this MPP
Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
a general description of GPIO and interrupt bindings.
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices, including the meaning of the
phrase "pin configuration node".
The pin configuration nodes act as a container for an arbitrary number of
subnodes. Each of these subnodes represents some desired configuration for a
pin or a list of pins. This configuration can include the
mux function to select on those pin(s), and various pin configuration
parameters, as listed below.
SUBNODES:
The name of each subnode is not important; all subnodes should be enumerated
and processed purely based on their content.
Each subnode only affects those parameters that are explicitly listed. In
other words, a subnode that lists a mux function but no pin configuration
parameters implies no information about any pin configuration parameters.
Similarly, a pin subnode that describes a pullup parameter implies no
information about e.g. the mux function.
The following generic properties as defined in pinctrl-bindings.txt are valid
to specify in a pin configuration subnode:
- pins:
Usage: required
Value type: <string-array>
Definition: List of MPP pins affected by the properties specified in
this subnode. Valid pins are:
mpp1-mpp4 for pm8841
mpp1-mpp8 for pm8941
mpp1-mpp4 for pma8084
- function:
Usage: required
Value type: <string>
Definition: Specify the alternative function to be configured for the
specified pins. Valid values are:
"normal",
"paired",
"dtest1",
"dtest2",
"dtest3",
"dtest4"
- bias-disable:
Usage: optional
Value type: <none>
Definition: The specified pins should be configured as no pull.
- bias-pull-up:
Usage: optional
Value type: <u32>
Definition: The specified pins should be configured as pull up.
Valid values are 600, 10000 and 30000 in bidirectional mode
only, i.e. when operating in qcom,analog-mode and input and
outputs are enabled. The hardware ignores the configuration
when operating in other modes.
- bias-high-impedance:
Usage: optional
Value type: <none>
Definition: The specified pins will put in high-Z mode and disabled.
- input-enable:
Usage: optional
Value type: <none>
Definition: The specified pins are put in input mode, i.e. their input
buffer is enabled
- output-high:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
high.
- output-low:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
low.
- power-source:
Usage: optional
Value type: <u32>
Definition: Selects the power source for the specified pins. Valid power
sources are defined in <dt-bindings/pinctrl/qcom,pmic-mpp.h>
- qcom,analog-mode:
Usage: optional
Value type: <none>
Definition: Selects Analog mode of operation: combined with input-enable
and/or output-high, output-low MPP could operate as
Bidirectional Logic, Analog Input, Analog Output.
- qcom,amux-route:
Usage: optional
Value type: <u32>
Definition: Selects the source for analog input. Valid values are
defined in <dt-bindings/pinctrl/qcom,pmic-mpp.h>
PMIC_MPP_AMUX_ROUTE_CH5, PMIC_MPP_AMUX_ROUTE_CH6...
Example:
mpps@a000 {
compatible = "qcom,pm8841-mpp";
reg = <0xa000>;
gpio-controller;
#gpio-cells = <2>;
interrupts = <4 0xa0 0 0>, <4 0xa1 0 0>, <4 0xa2 0 0>, <4 0xa3 0 0>;
pinctrl-names = "default";
pinctrl-0 = <&pm8841_default>;
pm8841_default: default {
gpio {
pins = "mpp1", "mpp2", "mpp3", "mpp4";
function = "normal";
input-enable;
power-source = <PM8841_MPP_S3>;
};
};
};

View file

@ -18,6 +18,7 @@ Required Properties:
- "samsung,exynos5250-pinctrl": for Exynos5250 compatible pin-controller.
- "samsung,exynos5260-pinctrl": for Exynos5260 compatible pin-controller.
- "samsung,exynos5420-pinctrl": for Exynos5420 compatible pin-controller.
- "samsung,exynos7-pinctrl": for Exynos7 compatible pin-controller.
- reg: Base address of the pin controller hardware module and length of
the address space it occupies.
@ -136,6 +137,8 @@ B. External Wakeup Interrupts: For supporting external wakeup interrupts, a
found on Samsung S3C64xx SoCs,
- samsung,exynos4210-wakeup-eint: represents wakeup interrupt controller
found on Samsung Exynos4210 and S5PC110/S5PV210 SoCs.
- samsung,exynos7-wakeup-eint: represents wakeup interrupt controller
found on Samsung Exynos7 SoC.
- interrupt-parent: phandle of the interrupt parent to which the external
wakeup interrupts are forwarded to.
- interrupts: interrupt used by multiplexed wakeup interrupts.

View file

@ -8,42 +8,8 @@ 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.
- generic pin configuration option to use. Example :
default_cfg {
ste,pins = "GPIO1";
bias-disable;
};
- ste,config: Handle of pin configuration node containing the generic
pinconfig options to use, as described in pinctrl-bindings.txt in
this directory. Example :
pcfg_bias_disable: pcfg_bias_disable {
bias-disable;
};
default_cfg {
ste,pins = "GPIO1";
ste.config = <&pcfg_bias_disable>;
};
ST Ericsson's pin configuration nodes use the generic pin multiplexing
and pin configuration bindings, see pinctrl-bindings.txt
Example board file extract:
@ -54,11 +20,11 @@ Example board file extract:
sysclkreq2 {
sysclkreq2_default_mode: sysclkreq2_default {
default_mux {
ste,function = "sysclkreq";
ste,pins = "sysclkreq2_d_1";
function = "sysclkreq";
groups = "sysclkreq2_d_1";
};
default_cfg {
ste,pins = "GPIO1";
pins = "GPIO1";
bias-disable;
};
};
@ -66,11 +32,11 @@ Example board file extract:
sysclkreq3 {
sysclkreq3_default_mode: sysclkreq3_default {
default_mux {
ste,function = "sysclkreq";
ste,pins = "sysclkreq3_d_1";
function = "sysclkreq";
groups = "sysclkreq3_d_1";
};
default_cfg {
ste,pins = "GPIO2";
pins = "GPIO2";
output-low;
};
};
@ -78,11 +44,11 @@ Example board file extract:
gpio3 {
gpio3_default_mode: gpio3_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio3_a_1";
function = "gpio";
groups = "gpio3_a_1";
};
default_cfg {
ste,pins = "GPIO3";
pins = "GPIO3";
output-low;
};
};
@ -90,11 +56,11 @@ Example board file extract:
sysclkreq6 {
sysclkreq6_default_mode: sysclkreq6_default {
default_mux {
ste,function = "sysclkreq";
ste,pins = "sysclkreq6_d_1";
function = "sysclkreq";
groups = "sysclkreq6_d_1";
};
default_cfg {
ste,pins = "GPIO4";
pins = "GPIO4";
bias-disable;
};
};
@ -102,11 +68,11 @@ Example board file extract:
pwmout1 {
pwmout1_default_mode: pwmout1_default {
default_mux {
ste,function = "pwmout";
ste,pins = "pwmout1_d_1";
function = "pwmout";
groups = "pwmout1_d_1";
};
default_cfg {
ste,pins = "GPIO14";
pins = "GPIO14";
output-low;
};
};
@ -114,11 +80,11 @@ Example board file extract:
pwmout2 {
pwmout2_default_mode: pwmout2_default {
pwmout2_default_mux {
ste,function = "pwmout";
ste,pins = "pwmout2_d_1";
function = "pwmout";
groups = "pwmout2_d_1";
};
pwmout2_default_cfg {
ste,pins = "GPIO15";
pins = "GPIO15";
output-low;
};
};
@ -126,11 +92,11 @@ Example board file extract:
pwmout3 {
pwmout3_default_mode: pwmout3_default {
pwmout3_default_mux {
ste,function = "pwmout";
ste,pins = "pwmout3_d_1";
function = "pwmout";
groups = "pwmout3_d_1";
};
pwmout3_default_cfg {
ste,pins = "GPIO16";
pins = "GPIO16";
output-low;
};
};
@ -139,15 +105,15 @@ Example board file extract:
adi1_default_mode: adi1_default {
adi1_default_mux {
ste,function = "adi1";
ste,pins = "adi1_d_1";
function = "adi1";
groups = "adi1_d_1";
};
adi1_default_cfg1 {
ste,pins = "GPIO17","GPIO19","GPIO20";
pins = "GPIO17","GPIO19","GPIO20";
bias-disable;
};
adi1_default_cfg2 {
ste,pins = "GPIO18";
pins = "GPIO18";
output-low;
};
};
@ -155,15 +121,15 @@ Example board file extract:
dmic12 {
dmic12_default_mode: dmic12_default {
dmic12_default_mux {
ste,function = "dmic";
ste,pins = "dmic12_d_1";
function = "dmic";
groups = "dmic12_d_1";
};
dmic12_default_cfg1 {
ste,pins = "GPIO27";
pins = "GPIO27";
output-low;
};
dmic12_default_cfg2 {
ste,pins = "GPIO28";
pins = "GPIO28";
bias-disable;
};
};
@ -171,15 +137,15 @@ Example board file extract:
dmic34 {
dmic34_default_mode: dmic34_default {
dmic34_default_mux {
ste,function = "dmic";
ste,pins = "dmic34_d_1";
function = "dmic";
groups = "dmic34_d_1";
};
dmic34_default_cfg1 {
ste,pins = "GPIO29";
pins = "GPIO29";
output-low;
};
dmic34_default_cfg2 {
ste,pins = "GPIO30";
pins = "GPIO30";
bias-disable;{
};
@ -188,15 +154,15 @@ Example board file extract:
dmic56 {
dmic56_default_mode: dmic56_default {
dmic56_default_mux {
ste,function = "dmic";
ste,pins = "dmic56_d_1";
function = "dmic";
groups = "dmic56_d_1";
};
dmic56_default_cfg1 {
ste,pins = "GPIO31";
pins = "GPIO31";
output-low;
};
dmic56_default_cfg2 {
ste,pins = "GPIO32";
pins = "GPIO32";
bias-disable;
};
};
@ -204,11 +170,11 @@ Example board file extract:
sysclkreq5 {
sysclkreq5_default_mode: sysclkreq5_default {
sysclkreq5_default_mux {
ste,function = "sysclkreq";
ste,pins = "sysclkreq5_d_1";
function = "sysclkreq";
groups = "sysclkreq5_d_1";
};
sysclkreq5_default_cfg {
ste,pins = "GPIO42";
pins = "GPIO42";
output-low;
};
};
@ -216,11 +182,11 @@ Example board file extract:
batremn {
batremn_default_mode: batremn_default {
batremn_default_mux {
ste,function = "batremn";
ste,pins = "batremn_d_1";
function = "batremn";
groups = "batremn_d_1";
};
batremn_default_cfg {
ste,pins = "GPIO43";
pins = "GPIO43";
bias-disable;
};
};
@ -228,11 +194,11 @@ Example board file extract:
service {
service_default_mode: service_default {
service_default_mux {
ste,function = "service";
ste,pins = "service_d_1";
function = "service";
groups = "service_d_1";
};
service_default_cfg {
ste,pins = "GPIO44";
pins = "GPIO44";
bias-disable;
};
};
@ -240,13 +206,13 @@ Example board file extract:
pwrctrl0 {
pwrctrl0_default_mux: pwrctrl0_mux {
pwrctrl0_default_mux {
ste,function = "pwrctrl";
ste,pins = "pwrctrl0_d_1";
function = "pwrctrl";
groups = "pwrctrl0_d_1";
};
};
pwrctrl0_default_mode: pwrctrl0_default {
pwrctrl0_default_cfg {
ste,pins = "GPIO45";
pins = "GPIO45";
bias-disable;
};
};
@ -254,13 +220,13 @@ Example board file extract:
pwrctrl1 {
pwrctrl1_default_mux: pwrctrl1_mux {
pwrctrl1_default_mux {
ste,function = "pwrctrl";
ste,pins = "pwrctrl1_d_1";
function = "pwrctrl";
groups = "pwrctrl1_d_1";
};
};
pwrctrl1_default_mode: pwrctrl1_default {
pwrctrl1_default_cfg {
ste,pins = "GPIO46";
pins = "GPIO46";
bias-disable;
};
};
@ -268,11 +234,11 @@ Example board file extract:
pwmextvibra1 {
pwmextvibra1_default_mode: pwmextvibra1_default {
pwmextvibra1_default_mux {
ste,function = "pwmextvibra";
ste,pins = "pwmextvibra1_d_1";
function = "pwmextvibra";
groups = "pwmextvibra1_d_1";
};
pwmextvibra1_default_cfg {
ste,pins = "GPIO47";
pins = "GPIO47";
bias-disable;
};
};
@ -280,11 +246,11 @@ Example board file extract:
pwmextvibra2 {
pwmextvibra2_default_mode: pwmextvibra2_default {
pwmextvibra2_default_mux {
ste,function = "pwmextvibra";
ste,pins = "pwmextvibra2_d_1";
function = "pwmextvibra";
groups = "pwmextvibra2_d_1";
};
pwmextvibra1_default_cfg {
ste,pins = "GPIO48";
pins = "GPIO48";
bias-disable;
};
};
@ -292,11 +258,11 @@ Example board file extract:
gpio51 {
gpio51_default_mode: gpio51_default {
gpio51_default_mux {
ste,function = "gpio";
ste,pins = "gpio51_a_1";
function = "gpio";
groups = "gpio51_a_1";
};
gpio51_default_cfg {
ste,pins = "GPIO51";
pins = "GPIO51";
output-low;
};
};
@ -304,11 +270,11 @@ Example board file extract:
gpio52 {
gpio52_default_mode: gpio52_default {
gpio52_default_mux {
ste,function = "gpio";
ste,pins = "gpio52_a_1";
function = "gpio";
groups = "gpio52_a_1";
};
gpio52_default_cfg {
ste,pins = "GPIO52";
pins = "GPIO52";
bias-pull-down;
};
};
@ -316,11 +282,11 @@ Example board file extract:
gpio53 {
gpio53_default_mode: gpio53_default {
gpio53_default_mux {
ste,function = "gpio";
ste,pins = "gpio53_a_1";
function = "gpio";
groups = "gpio53_a_1";
};
gpio53_default_cfg {
ste,pins = "GPIO53";
pins = "GPIO53";
bias-pull-down;
};
};
@ -328,11 +294,11 @@ Example board file extract:
gpio54 {
gpio54_default_mode: gpio54_default {
gpio54_default_mux {
ste,function = "gpio";
ste,pins = "gpio54_a_1";
function = "gpio";
groups = "gpio54_a_1";
};
gpio54_default_cfg {
ste,pins = "GPIO54";
pins = "GPIO54";
output-low;
};
};
@ -340,11 +306,11 @@ Example board file extract:
pdmclkdat {
pdmclkdat_default_mode: pdmclkdat_default {
pdmclkdat_default_mux {
ste,function = "pdm";
ste,pins = "pdmclkdat_d_1";
function = "pdm";
groups = "pdmclkdat_d_1";
};
pdmclkdat_default_cfg {
ste,pins = "GPIO55", "GPIO56";
pins = "GPIO55", "GPIO56";
bias-disable;
};
};

View file

@ -7285,7 +7285,13 @@ PIN CONTROLLER - ATMEL AT91
M: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: drivers/pinctrl/pinctrl-at91.c
F: drivers/pinctrl/pinctrl-at91.*
PIN CONTROLLER - INTEL
M: Mika Westerberg <mika.westerberg@linux.intel.com>
M: Heikki Krogerus <heikki.krogerus@linux.intel.com>
S: Maintained
F: drivers/pinctrl/intel/
PIN CONTROLLER - RENESAS
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

View file

@ -16,31 +16,31 @@
uart0 {
uart0_default_mux: uart0_mux {
default_mux {
ste,function = "u0";
ste,pins = "u0_a_1";
function = "u0";
groups = "u0_a_1";
};
};
uart0_default_mode: uart0_default {
default_cfg1 {
ste,pins = "GPIO0", "GPIO2";
pins = "GPIO0", "GPIO2";
ste,config = <&in_pu>;
};
default_cfg2 {
ste,pins = "GPIO1", "GPIO3";
pins = "GPIO1", "GPIO3";
ste,config = <&out_hi>;
};
};
uart0_sleep_mode: uart0_sleep {
sleep_cfg1 {
ste,pins = "GPIO0", "GPIO2";
pins = "GPIO0", "GPIO2";
ste,config = <&slpm_in_pu>;
};
sleep_cfg2 {
ste,pins = "GPIO1", "GPIO3";
pins = "GPIO1", "GPIO3";
ste,config = <&slpm_out_hi>;
};
};
@ -49,29 +49,29 @@
uart2 {
uart2_default_mode: uart2_default {
default_mux {
ste,function = "u2";
ste,pins = "u2txrx_a_1";
function = "u2";
groups = "u2txrx_a_1";
};
default_cfg1 {
ste,pins = "GPIO120";
pins = "GPIO120";
ste,config = <&in_pu>;
};
default_cfg2 {
ste,pins = "GPIO121";
pins = "GPIO121";
ste,config = <&out_hi>;
};
};
uart2_sleep_mode: uart2_sleep {
sleep_cfg1 {
ste,pins = "GPIO120";
pins = "GPIO120";
ste,config = <&slpm_in_pu>;
};
sleep_cfg2 {
ste,pins = "GPIO121";
pins = "GPIO121";
ste,config = <&slpm_out_hi>;
};
};
@ -80,21 +80,21 @@
i2c0 {
i2c0_default_mux: i2c_mux {
default_mux {
ste,function = "i2c0";
ste,pins = "i2c0_a_1";
function = "i2c0";
groups = "i2c0_a_1";
};
};
i2c0_default_mode: i2c_default {
default_cfg1 {
ste,pins = "GPIO147", "GPIO148";
pins = "GPIO147", "GPIO148";
ste,config = <&in_pu>;
};
};
i2c0_sleep_mode: i2c_sleep {
sleep_cfg1 {
ste,pins = "GPIO147", "GPIO148";
pins = "GPIO147", "GPIO148";
ste,config = <&slpm_in_pu>;
};
};
@ -103,21 +103,21 @@
i2c1 {
i2c1_default_mux: i2c_mux {
default_mux {
ste,function = "i2c1";
ste,pins = "i2c1_b_2";
function = "i2c1";
groups = "i2c1_b_2";
};
};
i2c1_default_mode: i2c_default {
default_cfg1 {
ste,pins = "GPIO16", "GPIO17";
pins = "GPIO16", "GPIO17";
ste,config = <&in_pu>;
};
};
i2c1_sleep_mode: i2c_sleep {
sleep_cfg1 {
ste,pins = "GPIO16", "GPIO17";
pins = "GPIO16", "GPIO17";
ste,config = <&slpm_in_pu>;
};
};
@ -126,21 +126,21 @@
i2c2 {
i2c2_default_mux: i2c_mux {
default_mux {
ste,function = "i2c2";
ste,pins = "i2c2_b_2";
function = "i2c2";
groups = "i2c2_b_2";
};
};
i2c2_default_mode: i2c_default {
default_cfg1 {
ste,pins = "GPIO10", "GPIO11";
pins = "GPIO10", "GPIO11";
ste,config = <&in_pu>;
};
};
i2c2_sleep_mode: i2c_sleep {
sleep_cfg1 {
ste,pins = "GPIO11", "GPIO11";
pins = "GPIO11", "GPIO11";
ste,config = <&slpm_in_pu>;
};
};
@ -149,21 +149,21 @@
i2c4 {
i2c4_default_mux: i2c_mux {
default_mux {
ste,function = "i2c4";
ste,pins = "i2c4_b_2";
function = "i2c4";
groups = "i2c4_b_2";
};
};
i2c4_default_mode: i2c_default {
default_cfg1 {
ste,pins = "GPIO122", "GPIO123";
pins = "GPIO122", "GPIO123";
ste,config = <&in_pu>;
};
};
i2c4_sleep_mode: i2c_sleep {
sleep_cfg1 {
ste,pins = "GPIO122", "GPIO123";
pins = "GPIO122", "GPIO123";
ste,config = <&slpm_in_pu>;
};
};
@ -172,21 +172,21 @@
i2c5 {
i2c5_default_mux: i2c_mux {
default_mux {
ste,function = "i2c5";
ste,pins = "i2c5_c_2";
function = "i2c5";
groups = "i2c5_c_2";
};
};
i2c5_default_mode: i2c_default {
default_cfg1 {
ste,pins = "GPIO118", "GPIO119";
pins = "GPIO118", "GPIO119";
ste,config = <&in_pu>;
};
};
i2c5_sleep_mode: i2c_sleep {
sleep_cfg1 {
ste,pins = "GPIO118", "GPIO119";
pins = "GPIO118", "GPIO119";
ste,config = <&slpm_in_pu>;
};
};

View file

@ -47,11 +47,11 @@
gpio2 {
gpio2_default_mode: gpio2_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio2_a_1";
function = "gpio";
groups = "gpio2_a_1";
};
default_cfg {
ste,pins = "GPIO2_T9";
pins = "GPIO2_T9";
input-enable;
bias-pull-down;
};
@ -60,11 +60,11 @@
gpio4 {
gpio4_default_mode: gpio4_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio4_a_1";
function = "gpio";
groups = "gpio4_a_1";
};
default_cfg {
ste,pins = "GPIO4_W2";
pins = "GPIO4_W2";
input-enable;
bias-pull-down;
};
@ -73,11 +73,11 @@
gpio10 {
gpio10_default_mode: gpio10_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio10_d_1";
function = "gpio";
groups = "gpio10_d_1";
};
default_cfg {
ste,pins = "GPIO10_U17";
pins = "GPIO10_U17";
input-enable;
bias-pull-down;
};
@ -86,11 +86,11 @@
gpio11 {
gpio11_default_mode: gpio11_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio11_d_1";
function = "gpio";
groups = "gpio11_d_1";
};
default_cfg {
ste,pins = "GPIO11_AA18";
pins = "GPIO11_AA18";
input-enable;
bias-pull-down;
};
@ -99,11 +99,11 @@
gpio12 {
gpio12_default_mode: gpio12_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio12_d_1";
function = "gpio";
groups = "gpio12_d_1";
};
default_cfg {
ste,pins = "GPIO12_U16";
pins = "GPIO12_U16";
input-enable;
bias-pull-down;
};
@ -112,11 +112,11 @@
gpio13 {
gpio13_default_mode: gpio13_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio13_d_1";
function = "gpio";
groups = "gpio13_d_1";
};
default_cfg {
ste,pins = "GPIO13_W17";
pins = "GPIO13_W17";
input-enable;
bias-pull-down;
};
@ -125,11 +125,11 @@
gpio16 {
gpio16_default_mode: gpio16_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio16_a_1";
function = "gpio";
groups = "gpio16_a_1";
};
default_cfg {
ste,pins = "GPIO16_F15";
pins = "GPIO16_F15";
input-enable;
bias-pull-down;
};
@ -138,11 +138,11 @@
gpio24 {
gpio24_default_mode: gpio24_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio24_a_1";
function = "gpio";
groups = "gpio24_a_1";
};
default_cfg {
ste,pins = "GPIO24_T14";
pins = "GPIO24_T14";
input-enable;
bias-pull-down;
};
@ -151,11 +151,11 @@
gpio25 {
gpio25_default_mode: gpio25_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio25_a_1";
function = "gpio";
groups = "gpio25_a_1";
};
default_cfg {
ste,pins = "GPIO25_R16";
pins = "GPIO25_R16";
input-enable;
bias-pull-down;
};
@ -164,11 +164,11 @@
gpio36 {
gpio36_default_mode: gpio36_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio36_a_1";
function = "gpio";
groups = "gpio36_a_1";
};
default_cfg {
ste,pins = "GPIO36_A17";
pins = "GPIO36_A17";
input-enable;
bias-pull-down;
};
@ -177,11 +177,11 @@
gpio37 {
gpio37_default_mode: gpio37_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio37_a_1";
function = "gpio";
groups = "gpio37_a_1";
};
default_cfg {
ste,pins = "GPIO37_E15";
pins = "GPIO37_E15";
input-enable;
bias-pull-down;
};
@ -190,11 +190,11 @@
gpio38 {
gpio38_default_mode: gpio38_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio38_a_1";
function = "gpio";
groups = "gpio38_a_1";
};
default_cfg {
ste,pins = "GPIO38_C17";
pins = "GPIO38_C17";
input-enable;
bias-pull-down;
};
@ -203,11 +203,11 @@
gpio39 {
gpio39_default_mode: gpio39_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio39_a_1";
function = "gpio";
groups = "gpio39_a_1";
};
default_cfg {
ste,pins = "GPIO39_E16";
pins = "GPIO39_E16";
input-enable;
bias-pull-down;
};
@ -216,11 +216,11 @@
gpio42 {
gpio42_default_mode: gpio42_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio42_a_1";
function = "gpio";
groups = "gpio42_a_1";
};
default_cfg {
ste,pins = "GPIO42_U2";
pins = "GPIO42_U2";
input-enable;
bias-pull-down;
};
@ -232,11 +232,11 @@
gpio26 {
gpio26_default_mode: gpio26_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio26_d_1";
function = "gpio";
groups = "gpio26_d_1";
};
default_cfg {
ste,pins = "GPIO26_M16";
pins = "GPIO26_M16";
output-low;
};
};
@ -244,11 +244,11 @@
gpio35 {
gpio35_default_mode: gpio35_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio35_d_1";
function = "gpio";
groups = "gpio35_d_1";
};
default_cfg {
ste,pins = "GPIO35_W15";
pins = "GPIO35_W15";
output-low;
};
};
@ -260,11 +260,11 @@
ycbcr {
ycbcr_default_mode: ycbcr_default {
default_mux {
ste,function = "ycbcr";
ste,pins = "ycbcr0123_d_1";
function = "ycbcr";
groups = "ycbcr0123_d_1";
};
default_cfg {
ste,pins = "GPIO6_Y18",
pins = "GPIO6_Y18",
"GPIO7_AA20",
"GPIO8_W18",
"GPIO9_AA19";
@ -277,11 +277,11 @@
pwm {
pwm_default_mode: pwm_default {
default_mux {
ste,function = "pwmout";
ste,pins = "pwmout1_d_1", "pwmout2_d_1";
function = "pwmout";
groups = "pwmout1_d_1", "pwmout2_d_1";
};
default_cfg {
ste,pins = "GPIO14_F14",
pins = "GPIO14_F14",
"GPIO15_B17";
input-enable;
bias-pull-down;
@ -292,11 +292,11 @@
adi1 {
adi1_default_mode: adi1_default {
default_mux {
ste,function = "adi1";
ste,pins = "adi1_d_1";
function = "adi1";
groups = "adi1_d_1";
};
default_cfg {
ste,pins = "GPIO17_P5",
pins = "GPIO17_P5",
"GPIO18_R5",
"GPIO19_U5",
"GPIO20_T5";
@ -309,11 +309,11 @@
usbuicc {
usbuicc_default_mode: usbuicc_default {
default_mux {
ste,function = "usbuicc";
ste,pins = "usbuicc_d_1";
function = "usbuicc";
groups = "usbuicc_d_1";
};
default_cfg {
ste,pins = "GPIO21_H19",
pins = "GPIO21_H19",
"GPIO22_G20",
"GPIO23_G19";
input-enable;
@ -325,13 +325,13 @@
dmic {
dmic_default_mode: dmic_default {
default_mux {
ste,function = "dmic";
ste,pins = "dmic12_d_1",
function = "dmic";
groups = "dmic12_d_1",
"dmic34_d_1",
"dmic56_d_1";
};
default_cfg {
ste,pins = "GPIO27_J6",
pins = "GPIO27_J6",
"GPIO28_K6",
"GPIO29_G6",
"GPIO30_H6",
@ -345,11 +345,11 @@
extcpena {
extcpena_default_mode: extcpena_default {
default_mux {
ste,function = "extcpena";
ste,pins = "extcpena_d_1";
function = "extcpena";
groups = "extcpena_d_1";
};
default_cfg {
ste,pins = "GPIO34_R17";
pins = "GPIO34_R17";
input-enable;
bias-pull-down;
};
@ -359,11 +359,11 @@
modsclsda {
modsclsda_default_mode: modsclsda_default {
default_mux {
ste,function = "modsclsda";
ste,pins = "modsclsda_d_1";
function = "modsclsda";
groups = "modsclsda_d_1";
};
default_cfg {
ste,pins = "GPIO40_T19",
pins = "GPIO40_T19",
"GPIO41_U19";
input-enable;
bias-pull-down;
@ -376,22 +376,22 @@
sysclkreq2 {
sysclkreq2_default_mode: sysclkreq2_default {
default_mux {
ste,function = "sysclkreq";
ste,pins = "sysclkreq2_d_1";
function = "sysclkreq";
groups = "sysclkreq2_d_1";
};
default_cfg {
ste,pins = "GPIO1_T10";
pins = "GPIO1_T10";
input-enable;
bias-disable;
};
};
sysclkreq2_sleep_mode: sysclkreq2_sleep {
default_mux {
ste,function = "gpio";
ste,pins = "gpio1_a_1";
function = "gpio";
groups = "gpio1_a_1";
};
default_cfg {
ste,pins = "GPIO1_T10";
pins = "GPIO1_T10";
input-enable;
bias-pull-down;
};
@ -400,22 +400,22 @@
sysclkreq4 {
sysclkreq4_default_mode: sysclkreq4_default {
default_mux {
ste,function = "sysclkreq";
ste,pins = "sysclkreq4_d_1";
function = "sysclkreq";
groups = "sysclkreq4_d_1";
};
default_cfg {
ste,pins = "GPIO3_U9";
pins = "GPIO3_U9";
input-enable;
bias-disable;
};
};
sysclkreq4_sleep_mode: sysclkreq4_sleep {
default_mux {
ste,function = "gpio";
ste,pins = "gpio3_a_1";
function = "gpio";
groups = "gpio3_a_1";
};
default_cfg {
ste,pins = "GPIO3_U9";
pins = "GPIO3_U9";
input-enable;
bias-pull-down;
};

View file

@ -35,11 +35,11 @@
gpio2 {
gpio2_default_mode: gpio2_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio2_a_1";
function = "gpio";
groups = "gpio2_a_1";
};
default_cfg {
ste,pins = "GPIO2_R5";
pins = "GPIO2_R5";
input-enable;
bias-pull-down;
};
@ -48,11 +48,11 @@
gpio10 {
gpio10_default_mode: gpio10_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio10_d_1";
function = "gpio";
groups = "gpio10_d_1";
};
default_cfg {
ste,pins = "GPIO10_B16";
pins = "GPIO10_B16";
input-enable;
bias-pull-down;
};
@ -61,11 +61,11 @@
gpio11 {
gpio11_default_mode: gpio11_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio11_d_1";
function = "gpio";
groups = "gpio11_d_1";
};
default_cfg {
ste,pins = "GPIO11_B17";
pins = "GPIO11_B17";
input-enable;
bias-pull-down;
};
@ -74,11 +74,11 @@
gpio13 {
gpio13_default_mode: gpio13_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio13_d_1";
function = "gpio";
groups = "gpio13_d_1";
};
default_cfg {
ste,pins = "GPIO13_D17";
pins = "GPIO13_D17";
input-enable;
bias-disable;
};
@ -87,11 +87,11 @@
gpio34 {
gpio34_default_mode: gpio34_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio34_a_1";
function = "gpio";
groups = "gpio34_a_1";
};
default_cfg {
ste,pins = "GPIO34_H14";
pins = "GPIO34_H14";
input-enable;
bias-pull-down;
};
@ -100,11 +100,11 @@
gpio50 {
gpio50_default_mode: gpio50_default {
default_mux {
ste,function = "gpio";
ste,pins = "gpio50_d_1";
function = "gpio";
groups = "gpio50_d_1";
};
default_cfg {
ste,pins = "GPIO50_L4";
pins = "GPIO50_L4";
input-enable;
bias-disable;
};
@ -114,11 +114,11 @@
pwm {
pwm_default_mode: pwm_default {
default_mux {
ste,function = "pwmout";
ste,pins = "pwmout1_d_1";
function = "pwmout";
groups = "pwmout1_d_1";
};
default_cfg {
ste,pins = "GPIO14_C16";
pins = "GPIO14_C16";
input-enable;
bias-pull-down;
};
@ -128,11 +128,11 @@
adi2 {
adi2_default_mode: adi2_default {
default_mux {
ste,function = "adi2";
ste,pins = "adi2_d_1";
function = "adi2";
groups = "adi2_d_1";
};
default_cfg {
ste,pins = "GPIO17_P2",
pins = "GPIO17_P2",
"GPIO18_N3",
"GPIO19_T1",
"GPIO20_P3";
@ -145,11 +145,11 @@
modsclsda {
modsclsda_default_mode: modsclsda_default {
default_mux {
ste,function = "modsclsda";
ste,pins = "modsclsda_d_1";
function = "modsclsda";
groups = "modsclsda_d_1";
};
default_cfg {
ste,pins = "GPIO40_J15",
pins = "GPIO40_J15",
"GPIO41_J14";
input-enable;
bias-pull-down;
@ -159,11 +159,11 @@
resethw {
resethw_default_mode: resethw_default {
default_mux {
ste,function = "resethw";
ste,pins = "resethw_d_1";
function = "resethw";
groups = "resethw_d_1";
};
default_cfg {
ste,pins = "GPIO52_D16";
pins = "GPIO52_D16";
input-enable;
bias-pull-down;
};
@ -172,11 +172,11 @@
service {
service_default_mode: service_default {
default_mux {
ste,function = "service";
ste,pins = "service_d_1";
function = "service";
groups = "service_d_1";
};
default_cfg {
ste,pins = "GPIO53_D15";
pins = "GPIO53_D15";
input-enable;
bias-pull-down;
};
@ -188,22 +188,22 @@
sysclkreq2 {
sysclkreq2_default_mode: sysclkreq2_default {
default_mux {
ste,function = "sysclkreq";
ste,pins = "sysclkreq2_d_1";
function = "sysclkreq";
groups = "sysclkreq2_d_1";
};
default_cfg {
ste,pins = "GPIO1_N4";
pins = "GPIO1_N4";
input-enable;
bias-disable;
};
};
sysclkreq2_sleep_mode: sysclkreq2_sleep {
default_mux {
ste,function = "gpio";
ste,pins = "gpio1_a_1";
function = "gpio";
groups = "gpio1_a_1";
};
default_cfg {
ste,pins = "GPIO1_N4";
pins = "GPIO1_N4";
input-enable;
bias-pull-down;
};
@ -212,22 +212,22 @@
sysclkreq4 {
sysclkreq4_default_mode: sysclkreq4_default {
default_mux {
ste,function = "sysclkreq";
ste,pins = "sysclkreq4_d_1";
function = "sysclkreq";
groups = "sysclkreq4_d_1";
};
default_cfg {
ste,pins = "GPIO3_P5";
pins = "GPIO3_P5";
input-enable;
bias-disable;
};
};
sysclkreq4_sleep_mode: sysclkreq4_sleep {
default_mux {
ste,function = "gpio";
ste,pins = "gpio3_a_1";
function = "gpio";
groups = "gpio3_a_1";
};
default_cfg {
ste,pins = "GPIO3_P5";
pins = "GPIO3_P5";
input-enable;
bias-pull-down;
};

View file

@ -18,33 +18,33 @@
uart0 {
uart0_default_mode: uart0_default {
default_mux {
ste,function = "u0";
ste,pins = "u0_a_1";
function = "u0";
groups = "u0_a_1";
};
default_cfg1 {
ste,pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */
pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */
ste,config = <&in_pu>;
};
default_cfg2 {
ste,pins = "GPIO1_AJ3", "GPIO3_AH3"; /* RTS+TXD */
pins = "GPIO1_AJ3", "GPIO3_AH3"; /* RTS+TXD */
ste,config = <&out_hi>;
};
};
uart0_sleep_mode: uart0_sleep {
sleep_cfg1 {
ste,pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */
pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */
ste,config = <&slpm_in_wkup_pdis>;
};
sleep_cfg2 {
ste,pins = "GPIO1_AJ3"; /* RTS */
pins = "GPIO1_AJ3"; /* RTS */
ste,config = <&slpm_out_hi_wkup_pdis>;
};
sleep_cfg3 {
ste,pins = "GPIO3_AH3"; /* TXD */
pins = "GPIO3_AH3"; /* TXD */
ste,config = <&slpm_out_wkup_pdis>;
};
};
@ -53,28 +53,28 @@
uart1 {
uart1_default_mode: uart1_default {
default_mux {
ste,function = "u1";
ste,pins = "u1rxtx_a_1";
function = "u1";
groups = "u1rxtx_a_1";
};
default_cfg1 {
ste,pins = "GPIO4_AH6"; /* RXD */
pins = "GPIO4_AH6"; /* RXD */
ste,config = <&in_pu>;
};
default_cfg2 {
ste,pins = "GPIO5_AG6"; /* TXD */
pins = "GPIO5_AG6"; /* TXD */
ste,config = <&out_hi>;
};
};
uart1_sleep_mode: uart1_sleep {
sleep_cfg1 {
ste,pins = "GPIO4_AH6"; /* RXD */
pins = "GPIO4_AH6"; /* RXD */
ste,config = <&slpm_in_wkup_pdis>;
};
sleep_cfg2 {
ste,pins = "GPIO5_AG6"; /* TXD */
pins = "GPIO5_AG6"; /* TXD */
ste,config = <&slpm_out_wkup_pdis>;
};
};
@ -83,28 +83,28 @@
uart2 {
uart2_default_mode: uart2_default {
default_mux {
ste,function = "u2";
ste,pins = "u2rxtx_c_1";
function = "u2";
groups = "u2rxtx_c_1";
};
default_cfg1 {
ste,pins = "GPIO29_W2"; /* RXD */
pins = "GPIO29_W2"; /* RXD */
ste,config = <&in_pu>;
};
default_cfg2 {
ste,pins = "GPIO30_W3"; /* TXD */
pins = "GPIO30_W3"; /* TXD */
ste,config = <&out_hi>;
};
};
uart2_sleep_mode: uart2_sleep {
sleep_cfg1 {
ste,pins = "GPIO29_W2"; /* RXD */
pins = "GPIO29_W2"; /* RXD */
ste,config = <&in_wkup_pdis>;
};
sleep_cfg2 {
ste,pins = "GPIO30_W3"; /* TXD */
pins = "GPIO30_W3"; /* TXD */
ste,config = <&out_wkup_pdis>;
};
};
@ -114,18 +114,18 @@
i2c0 {
i2c0_default_mode: i2c_default {
default_mux {
ste,function = "i2c0";
ste,pins = "i2c0_a_1";
function = "i2c0";
groups = "i2c0_a_1";
};
default_cfg1 {
ste,pins = "GPIO147_C15", "GPIO148_B16"; /* SDA/SCL */
pins = "GPIO147_C15", "GPIO148_B16"; /* SDA/SCL */
ste,config = <&in_pu>;
};
};
i2c0_sleep_mode: i2c_sleep {
sleep_cfg1 {
ste,pins = "GPIO147_C15", "GPIO148_B16"; /* SDA/SCL */
pins = "GPIO147_C15", "GPIO148_B16"; /* SDA/SCL */
ste,config = <&slpm_in_wkup_pdis>;
};
};
@ -134,18 +134,18 @@
i2c1 {
i2c1_default_mode: i2c_default {
default_mux {
ste,function = "i2c1";
ste,pins = "i2c1_b_2";
function = "i2c1";
groups = "i2c1_b_2";
};
default_cfg1 {
ste,pins = "GPIO16_AD3", "GPIO17_AD4"; /* SDA/SCL */
pins = "GPIO16_AD3", "GPIO17_AD4"; /* SDA/SCL */
ste,config = <&in_pu>;
};
};
i2c1_sleep_mode: i2c_sleep {
sleep_cfg1 {
ste,pins = "GPIO16_AD3", "GPIO17_AD4"; /* SDA/SCL */
pins = "GPIO16_AD3", "GPIO17_AD4"; /* SDA/SCL */
ste,config = <&slpm_in_wkup_pdis>;
};
};
@ -154,18 +154,18 @@
i2c2 {
i2c2_default_mode: i2c_default {
default_mux {
ste,function = "i2c2";
ste,pins = "i2c2_b_2";
function = "i2c2";
groups = "i2c2_b_2";
};
default_cfg1 {
ste,pins = "GPIO10_AF5", "GPIO11_AG4"; /* SDA/SCL */
pins = "GPIO10_AF5", "GPIO11_AG4"; /* SDA/SCL */
ste,config = <&in_pu>;
};
};
i2c2_sleep_mode: i2c_sleep {
sleep_cfg1 {
ste,pins = "GPIO10_AF5", "GPIO11_AG4"; /* SDA/SCL */
pins = "GPIO10_AF5", "GPIO11_AG4"; /* SDA/SCL */
ste,config = <&slpm_in_wkup_pdis>;
};
};
@ -174,18 +174,18 @@
i2c3 {
i2c3_default_mode: i2c_default {
default_mux {
ste,function = "i2c3";
ste,pins = "i2c3_c_2";
function = "i2c3";
groups = "i2c3_c_2";
};
default_cfg1 {
ste,pins = "GPIO229_AG7", "GPIO230_AF7"; /* SDA/SCL */
pins = "GPIO229_AG7", "GPIO230_AF7"; /* SDA/SCL */
ste,config = <&in_pu>;
};
};
i2c3_sleep_mode: i2c_sleep {
sleep_cfg1 {
ste,pins = "GPIO229_AG7", "GPIO230_AF7"; /* SDA/SCL */
pins = "GPIO229_AG7", "GPIO230_AF7"; /* SDA/SCL */
ste,config = <&slpm_in_wkup_pdis>;
};
};
@ -198,18 +198,18 @@
i2c4 {
i2c4_default_mode: i2c_default {
default_mux {
ste,function = "i2c4";
ste,pins = "i2c4_b_1";
function = "i2c4";
groups = "i2c4_b_1";
};
default_cfg1 {
ste,pins = "GPIO4_AH6", "GPIO5_AG6"; /* SDA/SCL */
pins = "GPIO4_AH6", "GPIO5_AG6"; /* SDA/SCL */
ste,config = <&in_pu>;
};
};
i2c4_sleep_mode: i2c_sleep {
sleep_cfg1 {
ste,pins = "GPIO4_AH6", "GPIO5_AG6"; /* SDA/SCL */
pins = "GPIO4_AH6", "GPIO5_AG6"; /* SDA/SCL */
ste,config = <&slpm_in_wkup_pdis>;
};
};
@ -219,19 +219,19 @@
spi2 {
spi2_default_mode: spi_default {
default_mux {
ste,function = "spi2";
ste,pins = "spi2_oc1_2";
function = "spi2";
groups = "spi2_oc1_2";
};
default_cfg1 {
ste,pins = "GPIO216_AG12"; /* FRM */
pins = "GPIO216_AG12"; /* FRM */
ste,config = <&gpio_out_hi>;
};
default_cfg2 {
ste,pins = "GPIO218_AH11"; /* RXD */
pins = "GPIO218_AH11"; /* RXD */
ste,config = <&in_pd>;
};
default_cfg3 {
ste,pins =
pins =
"GPIO215_AH13", /* TXD */
"GPIO217_AH12"; /* CLK */
ste,config = <&out_lo>;
@ -245,32 +245,32 @@
* as we do not state any muxing.
*/
idle_cfg1 {
ste,pins = "GPIO218_AH11"; /* RXD */
pins = "GPIO218_AH11"; /* RXD */
ste,config = <&slpm_in_pdis>;
};
idle_cfg2 {
ste,pins = "GPIO215_AH13"; /* TXD */
pins = "GPIO215_AH13"; /* TXD */
ste,config = <&slpm_out_lo_pdis>;
};
idle_cfg3 {
ste,pins = "GPIO217_AH12"; /* CLK */
pins = "GPIO217_AH12"; /* CLK */
ste,config = <&slpm_pdis>;
};
};
spi2_sleep_mode: spi_sleep {
sleep_cfg1 {
ste,pins =
pins =
"GPIO216_AG12", /* FRM */
"GPIO218_AH11"; /* RXD */
ste,config = <&slpm_in_wkup_pdis>;
};
sleep_cfg2 {
ste,pins = "GPIO215_AH13"; /* TXD */
pins = "GPIO215_AH13"; /* TXD */
ste,config = <&slpm_out_lo_wkup_pdis>;
};
sleep_cfg3 {
ste,pins = "GPIO217_AH12"; /* CLK */
pins = "GPIO217_AH12"; /* CLK */
ste,config = <&slpm_wkup_pdis>;
};
};
@ -281,26 +281,26 @@
/* This is the external SD card slot, 4 bits wide */
sdi0_default_mode: sdi0_default {
default_mux {
ste,function = "mc0";
ste,pins = "mc0_a_1";
function = "mc0";
groups = "mc0_a_1";
};
default_cfg1 {
ste,pins =
pins =
"GPIO18_AC2", /* CMDDIR */
"GPIO19_AC1", /* DAT0DIR */
"GPIO20_AB4"; /* DAT2DIR */
ste,config = <&out_hi>;
};
default_cfg2 {
ste,pins = "GPIO22_AA3"; /* FBCLK */
pins = "GPIO22_AA3"; /* FBCLK */
ste,config = <&in_nopull>;
};
default_cfg3 {
ste,pins = "GPIO23_AA4"; /* CLK */
pins = "GPIO23_AA4"; /* CLK */
ste,config = <&out_lo>;
};
default_cfg4 {
ste,pins =
pins =
"GPIO24_AB2", /* CMD */
"GPIO25_Y4", /* DAT0 */
"GPIO26_Y2", /* DAT1 */
@ -312,14 +312,14 @@
sdi0_sleep_mode: sdi0_sleep {
sleep_cfg1 {
ste,pins =
pins =
"GPIO18_AC2", /* CMDDIR */
"GPIO19_AC1", /* DAT0DIR */
"GPIO20_AB4"; /* DAT2DIR */
ste,config = <&slpm_out_hi_wkup_pdis>;
};
sleep_cfg2 {
ste,pins =
pins =
"GPIO22_AA3", /* FBCLK */
"GPIO24_AB2", /* CMD */
"GPIO25_Y4", /* DAT0 */
@ -329,7 +329,7 @@
ste,config = <&slpm_in_wkup_pdis>;
};
sleep_cfg3 {
ste,pins = "GPIO23_AA4"; /* CLK */
pins = "GPIO23_AA4"; /* CLK */
ste,config = <&slpm_out_lo_wkup_pdis>;
};
};
@ -339,19 +339,19 @@
/* This is the WLAN SDIO 4 bits wide */
sdi1_default_mode: sdi1_default {
default_mux {
ste,function = "mc1";
ste,pins = "mc1_a_1";
function = "mc1";
groups = "mc1_a_1";
};
default_cfg1 {
ste,pins = "GPIO208_AH16"; /* CLK */
pins = "GPIO208_AH16"; /* CLK */
ste,config = <&out_lo>;
};
default_cfg2 {
ste,pins = "GPIO209_AG15"; /* FBCLK */
pins = "GPIO209_AG15"; /* FBCLK */
ste,config = <&in_nopull>;
};
default_cfg3 {
ste,pins =
pins =
"GPIO210_AJ15", /* CMD */
"GPIO211_AG14", /* DAT0 */
"GPIO212_AF13", /* DAT1 */
@ -363,11 +363,11 @@
sdi1_sleep_mode: sdi1_sleep {
sleep_cfg1 {
ste,pins = "GPIO208_AH16"; /* CLK */
pins = "GPIO208_AH16"; /* CLK */
ste,config = <&slpm_out_lo_wkup_pdis>;
};
sleep_cfg2 {
ste,pins =
pins =
"GPIO209_AG15", /* FBCLK */
"GPIO210_AJ15", /* CMD */
"GPIO211_AG14", /* DAT0 */
@ -383,19 +383,19 @@
/* This is the eMMC 8 bits wide, usually PoP eMMC */
sdi2_default_mode: sdi2_default {
default_mux {
ste,function = "mc2";
ste,pins = "mc2_a_1";
function = "mc2";
groups = "mc2_a_1";
};
default_cfg1 {
ste,pins = "GPIO128_A5"; /* CLK */
pins = "GPIO128_A5"; /* CLK */
ste,config = <&out_lo>;
};
default_cfg2 {
ste,pins = "GPIO130_C8"; /* FBCLK */
pins = "GPIO130_C8"; /* FBCLK */
ste,config = <&in_nopull>;
};
default_cfg3 {
ste,pins =
pins =
"GPIO129_B4", /* CMD */
"GPIO131_A12", /* DAT0 */
"GPIO132_C10", /* DAT1 */
@ -411,17 +411,17 @@
sdi2_sleep_mode: sdi2_sleep {
sleep_cfg1 {
ste,pins = "GPIO128_A5"; /* CLK */
pins = "GPIO128_A5"; /* CLK */
ste,config = <&out_lo_wkup_pdis>;
};
sleep_cfg2 {
ste,pins =
pins =
"GPIO130_C8", /* FBCLK */
"GPIO129_B4"; /* CMD */
ste,config = <&in_wkup_pdis_en>;
};
sleep_cfg3 {
ste,pins =
pins =
"GPIO131_A12", /* DAT0 */
"GPIO132_C10", /* DAT1 */
"GPIO133_B10", /* DAT2 */
@ -439,19 +439,19 @@
/* This is the eMMC 8 bits wide, usually PCB-mounted eMMC */
sdi4_default_mode: sdi4_default {
default_mux {
ste,function = "mc4";
ste,pins = "mc4_a_1";
function = "mc4";
groups = "mc4_a_1";
};
default_cfg1 {
ste,pins = "GPIO203_AE23"; /* CLK */
pins = "GPIO203_AE23"; /* CLK */
ste,config = <&out_lo>;
};
default_cfg2 {
ste,pins = "GPIO202_AF25"; /* FBCLK */
pins = "GPIO202_AF25"; /* FBCLK */
ste,config = <&in_nopull>;
};
default_cfg3 {
ste,pins =
pins =
"GPIO201_AF24", /* CMD */
"GPIO200_AH26", /* DAT0 */
"GPIO199_AH23", /* DAT1 */
@ -467,11 +467,11 @@
sdi4_sleep_mode: sdi4_sleep {
sleep_cfg1 {
ste,pins = "GPIO203_AE23"; /* CLK */
pins = "GPIO203_AE23"; /* CLK */
ste,config = <&out_lo_wkup_pdis>;
};
sleep_cfg2 {
ste,pins =
pins =
"GPIO202_AF25", /* FBCLK */
"GPIO201_AF24", /* CMD */
"GPIO200_AH26", /* DAT0 */
@ -494,11 +494,11 @@
msp0 {
msp0_default_mode: msp0_default {
default_msp0_mux {
ste,function = "msp0";
ste,pins = "msp0txrx_a_1", "msp0tfstck_a_1";
function = "msp0";
groups = "msp0txrx_a_1", "msp0tfstck_a_1";
};
default_msp0_cfg {
ste,pins =
pins =
"GPIO12_AC4", /* TXD */
"GPIO15_AC3", /* RXD */
"GPIO13_AF3", /* TFS */
@ -511,15 +511,15 @@
msp1 {
msp1_default_mode: msp1_default {
default_mux {
ste,function = "msp1";
ste,pins = "msp1txrx_a_1", "msp1_a_1";
function = "msp1";
groups = "msp1txrx_a_1", "msp1_a_1";
};
default_cfg1 {
ste,pins = "GPIO33_AF2";
pins = "GPIO33_AF2";
ste,config = <&out_lo>;
};
default_cfg2 {
ste,pins =
pins =
"GPIO34_AE1",
"GPIO35_AE2",
"GPIO36_AG2";
@ -533,18 +533,18 @@
msp2_default_mode: msp2_default {
/* MSP2 usually used for HDMI audio */
default_mux {
ste,function = "msp2";
ste,pins = "msp2_a_1";
function = "msp2";
groups = "msp2_a_1";
};
default_cfg1 {
ste,pins =
pins =
"GPIO193_AH27", /* TXD */
"GPIO194_AF27", /* TCK */
"GPIO195_AG28"; /* TFS */
ste,config = <&in_pd>;
};
default_cfg2 {
ste,pins = "GPIO196_AG26"; /* RXD */
pins = "GPIO196_AG26"; /* RXD */
ste,config = <&out_lo>;
};
};
@ -554,11 +554,11 @@
musb {
musb_default_mode: musb_default {
default_mux {
ste,function = "usb";
ste,pins = "usb_a_1";
function = "usb";
groups = "usb_a_1";
};
default_cfg1 {
ste,pins =
pins =
"GPIO256_AF28", /* NXT */
"GPIO258_AD29", /* XCLK */
"GPIO259_AC29", /* DIR */
@ -573,25 +573,25 @@
ste,config = <&in_nopull>;
};
default_cfg2 {
ste,pins = "GPIO257_AE29"; /* STP */
pins = "GPIO257_AE29"; /* STP */
ste,config = <&out_hi>;
};
};
musb_sleep_mode: musb_sleep {
sleep_cfg1 {
ste,pins =
pins =
"GPIO256_AF28", /* NXT */
"GPIO258_AD29", /* XCLK */
"GPIO259_AC29"; /* DIR */
ste,config = <&slpm_wkup_pdis_en>;
};
sleep_cfg2 {
ste,pins = "GPIO257_AE29"; /* STP */
pins = "GPIO257_AE29"; /* STP */
ste,config = <&slpm_out_hi_wkup_pdis>;
};
sleep_cfg3 {
ste,pins =
pins =
"GPIO260_AD28", /* DAT7 */
"GPIO261_AD26", /* DAT6 */
"GPIO262_AE26", /* DAT5 */
@ -609,8 +609,8 @@
lcd_default_mode: lcd_default {
default_mux {
/* Mux in VSI0 and all the data lines */
ste,function = "lcd";
ste,pins =
function = "lcd";
groups =
"lcdvsi0_a_1", /* VSI0 for LCD */
"lcd_d0_d7_a_1", /* Data lines */
"lcd_d8_d11_a_1", /* TV-out */
@ -618,7 +618,7 @@
"lcdvsi1_a_1"; /* VSI1 for HDMI */
};
default_cfg1 {
ste,pins =
pins =
"GPIO68_E1", /* VSI0 */
"GPIO69_E2"; /* VSI1 */
ste,config = <&in_pu>;
@ -626,7 +626,7 @@
};
lcd_sleep_mode: lcd_sleep {
sleep_cfg1 {
ste,pins = "GPIO69_E2"; /* VSI1 */
pins = "GPIO69_E2"; /* VSI1 */
ste,config = <&slpm_in_wkup_pdis>;
};
};
@ -636,11 +636,11 @@
/* SKE keys on position 2 in an 8x8 matrix */
ske_kpa2_default_mode: ske_kpa2_default {
default_mux {
ste,function = "kp";
ste,pins = "kp_a_2";
function = "kp";
groups = "kp_a_2";
};
default_cfg1 {
ste,pins =
pins =
"GPIO153_B17", /* I7 */
"GPIO154_C16", /* I6 */
"GPIO155_C19", /* I5 */
@ -652,7 +652,7 @@
ste,config = <&in_pd>;
};
default_cfg2 {
ste,pins =
pins =
"GPIO157_A18", /* O7 */
"GPIO158_C18", /* O6 */
"GPIO159_B19", /* O5 */
@ -666,7 +666,7 @@
};
ske_kpa2_sleep_mode: ske_kpa2_sleep {
sleep_cfg1 {
ste,pins =
pins =
"GPIO153_B17", /* I7 */
"GPIO154_C16", /* I6 */
"GPIO155_C19", /* I5 */
@ -678,7 +678,7 @@
ste,config = <&slpm_in_pu_wkup_pdis_en>;
};
sleep_cfg2 {
ste,pins =
pins =
"GPIO157_A18", /* O7 */
"GPIO158_C18", /* O6 */
"GPIO159_B19", /* O5 */
@ -696,11 +696,11 @@
*/
ske_kpaoc1_default_mode: ske_kpaoc1_default {
default_mux {
ste,function = "kp";
ste,pins = "kp_a_1", "kp_oc1_1";
function = "kp";
groups = "kp_a_1", "kp_oc1_1";
};
default_cfg1 {
ste,pins =
pins =
"GPIO91_B6", /* KP_O0 */
"GPIO90_A3", /* KP_O1 */
"GPIO87_B3", /* KP_O2 */
@ -710,7 +710,7 @@
ste,config = <&out_lo>;
};
default_cfg2 {
ste,pins =
pins =
"GPIO93_B7", /* KP_I0 */
"GPIO92_D6", /* KP_I1 */
"GPIO89_E6", /* KP_I2 */
@ -729,13 +729,13 @@
* These are plain GPIO pins used by WLAN
*/
default_cfg1 {
ste,pins =
pins =
"GPIO226_AF8", /* WLAN_PMU_EN */
"GPIO85_D5"; /* WLAN_ENA */
ste,config = <&gpio_out_lo>;
};
default_cfg2 {
ste,pins = "GPIO4_AH6"; /* WLAN_IRQ on UART1 */
pins = "GPIO4_AH6"; /* WLAN_IRQ on UART1 */
ste,config = <&gpio_in_pu>;
};
};

View file

@ -103,7 +103,7 @@
prox {
prox_stuib_mode: prox_stuib {
stuib_cfg {
ste,pins = "GPIO217_AH12";
pins = "GPIO217_AH12";
ste,config = <&gpio_in_pu>;
};
};
@ -111,7 +111,7 @@
hall {
hall_stuib_mode: stuib_tvk {
stuib_cfg {
ste,pins = "GPIO145_C13";
pins = "GPIO145_C13";
ste,config = <&gpio_in_pu>;
};
};

View file

@ -130,7 +130,7 @@
tc35893 {
tc35893_tvk_mode: tc35893_tvk {
tvk_cfg {
ste,pins = "GPIO218_AH11";
pins = "GPIO218_AH11";
ste,config = <&gpio_in_pu>;
};
};
@ -138,7 +138,7 @@
prox {
prox_tvk_mode: prox_tvk {
tvk_cfg {
ste,pins = "GPIO217_AH12";
pins = "GPIO217_AH12";
ste,config = <&gpio_in_pu>;
};
};
@ -146,7 +146,7 @@
hall {
hall_tvk_mode: hall_tvk {
tvk_cfg {
ste,pins = "GPIO145_C13";
pins = "GPIO145_C13";
ste,config = <&gpio_in_pu>;
};
};
@ -155,7 +155,7 @@
accel_tvk_mode: accel_tvk {
/* Accelerometer interrupt lines 1 & 2 */
tvk_cfg {
ste,pins = "GPIO82_C1", "GPIO83_D3";
pins = "GPIO82_C1", "GPIO83_D3";
ste,config = <&gpio_in_pu>;
};
};
@ -164,11 +164,11 @@
magneto_tvk_mode: magneto_tvk {
/* Magnetometer uses GPIO 31 and 32, pull these up/down respectively */
tvk_cfg1 {
ste,pins = "GPIO31_V3";
pins = "GPIO31_V3";
ste,config = <&gpio_in_pu>;
};
tvk_cfg2 {
ste,pins = "GPIO32_V2";
pins = "GPIO32_V2";
ste,config = <&gpio_in_pd>;
};
};

View file

@ -79,11 +79,11 @@
ssp0 {
ssp0_hrefprev60_mode: ssp0_hrefprev60_default {
hrefprev60_mux {
ste,function = "ssp0";
ste,pins = "ssp0_a_1";
function = "ssp0";
groups = "ssp0_a_1";
};
hrefprev60_cfg1 {
ste,pins = "GPIO145_C13"; /* RXD */
pins = "GPIO145_C13"; /* RXD */
ste,config = <&in_pd>;
};
@ -93,11 +93,11 @@
/* This additional pin needed on early MOP500 and HREFs previous to v60 */
sdi0_default_mode: sdi0_default {
hrefprev60_mux {
ste,function = "mc0";
ste,pins = "mc0dat31dir_a_1";
function = "mc0";
groups = "mc0dat31dir_a_1";
};
hrefprev60_cfg1 {
ste,pins = "GPIO21_AB3"; /* DAT31DIR */
pins = "GPIO21_AB3"; /* DAT31DIR */
ste,config = <&out_hi>;
};
@ -106,7 +106,7 @@
tc35892 {
tc35892_hrefprev60_mode: tc35892_hrefprev60 {
hrefprev60_cfg {
ste,pins = "GPIO217_AH12";
pins = "GPIO217_AH12";
ste,config = <&gpio_in_pu>;
};
};
@ -114,11 +114,11 @@
ipgpio {
ipgpio_hrefprev60_mode: ipgpio_hrefprev60 {
hrefprev60_mux {
ste,function = "ipgpio";
ste,pins = "ipgpio0_c_1", "ipgpio1_c_1";
function = "ipgpio";
groups = "ipgpio0_c_1", "ipgpio1_c_1";
};
hrefprev60_cfg1 {
ste,pins = "GPIO6_AF6", "GPIO7_AG5";
pins = "GPIO6_AF6", "GPIO7_AG5";
ste,config = <&in_pu>;
};
};

View file

@ -49,7 +49,7 @@
/* SD card detect GPIO pin, extend default state */
sdi0_default_mode: sdi0_default {
default_hrefv60_cfg1 {
ste,pins = "GPIO95_E8";
pins = "GPIO95_E8";
ste,config = <&gpio_in_pu>;
};
};
@ -64,19 +64,19 @@
*/
ipgpio_hrefv60_mode: ipgpio_hrefv60 {
hrefv60_mux {
ste,function = "ipgpio";
ste,pins = "ipgpio0_c_1", "ipgpio1_c_1", "ipgpio4_c_1";
function = "ipgpio";
groups = "ipgpio0_c_1", "ipgpio1_c_1", "ipgpio4_c_1";
};
hrefv60_cfg1 {
ste,pins = "GPIO6_AF6", "GPIO7_AG5";
pins = "GPIO6_AF6", "GPIO7_AG5";
ste,config = <&in_pu>;
};
hrefv60_cfg2 {
ste,pins = "GPIO21_AB3";
pins = "GPIO21_AB3";
ste,config = <&gpio_out_lo>;
};
hrefv60_cfg3 {
ste,pins = "GPIO64_F3";
pins = "GPIO64_F3";
ste,config = <&out_lo>;
};
};
@ -89,7 +89,7 @@
*/
etm_hrefv60_mode: etm_hrefv60 {
hrefv60_cfg1 {
ste,pins =
pins =
"GPIO70_G5",
"GPIO71_G4",
"GPIO72_H4",
@ -103,11 +103,11 @@
nahj_hrefv60_mode: nahj_hrefv60 {
/* NAHJ CTRL on GPIO76 to low, CTRL_INV on GPIO216 to high */
hrefv60_cfg1 {
ste,pins = "GPIO76_J2";
pins = "GPIO76_J2";
ste,config = <&gpio_out_lo>;
};
hrefv60_cfg2 {
ste,pins = "GPIO216_AG12";
pins = "GPIO216_AG12";
ste,config = <&gpio_out_hi>;
};
};
@ -116,13 +116,13 @@
nfc_hrefv60_mode: nfc_hrefv60 {
/* NFC ENA and RESET to low, pulldown IRQ line */
hrefv60_cfg1 {
ste,pins =
pins =
"GPIO77_H1", /* NFC_ENA */
"GPIO142_C11"; /* NFC_RESET */
ste,config = <&gpio_out_lo>;
};
hrefv60_cfg2 {
ste,pins = "GPIO144_B13"; /* NFC_IRQ */
pins = "GPIO144_B13"; /* NFC_IRQ */
ste,config = <&gpio_in_pd>;
};
};
@ -130,11 +130,11 @@
force {
force_hrefv60_mode: force_hrefv60 {
hrefv60_cfg1 {
ste,pins = "GPIO91_B6"; /* FORCE_SENSING_INT */
pins = "GPIO91_B6"; /* FORCE_SENSING_INT */
ste,config = <&gpio_in_pu>;
};
hrefv60_cfg2 {
ste,pins =
pins =
"GPIO92_D6", /* FORCE_SENSING_RST */
"GPIO97_D9"; /* FORCE_SENSING_WU */
ste,config = <&gpio_out_lo>;
@ -144,7 +144,7 @@
dipro {
dipro_hrefv60_mode: dipro_hrefv60 {
hrefv60_cfg1 {
ste,pins = "GPIO139_C9"; /* DIPRO_INT */
pins = "GPIO139_C9"; /* DIPRO_INT */
ste,config = <&gpio_in_pu>;
};
};
@ -153,7 +153,7 @@
vaudio_hf_hrefv60_mode: vaudio_hf_hrefv60 {
/* Audio Amplifier HF enable GPIO */
hrefv60_cfg1 {
ste,pins = "GPIO149_B14"; /* VAUDIO_HF_EN, enable MAX8968 */
pins = "GPIO149_B14"; /* VAUDIO_HF_EN, enable MAX8968 */
ste,config = <&gpio_out_hi>;
};
};
@ -165,7 +165,7 @@
* pull low to reset state
*/
hrefv60_cfg1 {
ste,pins = "GPIO171_D23"; /* GBF_ENA_RESET */
pins = "GPIO171_D23"; /* GBF_ENA_RESET */
ste,config = <&gpio_out_lo>;
};
};
@ -174,7 +174,7 @@
hdtv_hrefv60_mode: hdtv_hrefv60 {
/* MSP : HDTV INTERFACE GPIO line */
hrefv60_cfg1 {
ste,pins = "GPIO192_AJ27";
pins = "GPIO192_AJ27";
ste,config = <&gpio_in_pd>;
};
};
@ -187,11 +187,11 @@
* reset signals low.
*/
hrefv60_cfg1 {
ste,pins = "GPIO143_D12", "GPIO146_D13";
pins = "GPIO143_D12", "GPIO146_D13";
ste,config = <&gpio_out_lo>;
};
hrefv60_cfg2 {
ste,pins = "GPIO67_G2";
pins = "GPIO67_G2";
ste,config = <&gpio_in_pu>;
};
};
@ -204,11 +204,11 @@
* Drive DISP1 reset high (not reset), driver DISP2 reset low (reset)
*/
hrefv60_cfg1 {
ste,pins ="GPIO65_F1";
pins ="GPIO65_F1";
ste,config = <&gpio_out_hi>;
};
hrefv60_cfg2 {
ste,pins ="GPIO66_G3";
pins ="GPIO66_G3";
ste,config = <&gpio_out_lo>;
};
};

View file

@ -30,12 +30,12 @@
cd_default_mode: cd_default {
cd_default_cfg1 {
/* CD input GPIO */
ste,pins = "GPIO111_H21";
pins = "GPIO111_H21";
ste,input = <0>;
};
cd_default_cfg2 {
/* CD GPIO biasing */
ste,pins = "GPIO112_J21";
pins = "GPIO112_J21";
ste,output = <0>;
};
};
@ -43,7 +43,7 @@
gpioi2c {
gpioi2c_default_mode: gpioi2c_default {
gpioi2c_default_cfg {
ste,pins = "GPIO73_C21", "GPIO74_C20";
pins = "GPIO73_C21", "GPIO74_C20";
ste,input = <0>;
};
};
@ -51,7 +51,7 @@
user-led {
user_led_default_mode: user_led_default {
user_led_default_cfg {
ste,pins = "GPIO2_C5";
pins = "GPIO2_C5";
ste,output = <1>;
};
};
@ -59,7 +59,7 @@
user-button {
user_button_default_mode: user_button_default {
user_button_default_cfg {
ste,pins = "GPIO3_A4";
pins = "GPIO3_A4";
ste,input = <0>;
};
};

View file

@ -100,41 +100,41 @@
uart0 {
uart0_default_mux: uart0_mux {
u0_default_mux {
ste,function = "u0";
ste,pins = "u0_a_1";
function = "u0";
groups = "u0_a_1";
};
};
};
uart1 {
uart1_default_mux: uart1_mux {
u1_default_mux {
ste,function = "u1";
ste,pins = "u1_a_1";
function = "u1";
groups = "u1_a_1";
};
};
};
mmcsd {
mmcsd_default_mux: mmcsd_mux {
mmcsd_default_mux {
ste,function = "mmcsd";
ste,pins = "mmcsd_a_1", "mmcsd_b_1";
function = "mmcsd";
groups = "mmcsd_a_1", "mmcsd_b_1";
};
};
mmcsd_default_mode: mmcsd_default {
mmcsd_default_cfg1 {
/* MCCLK */
ste,pins = "GPIO8_B10";
pins = "GPIO8_B10";
ste,output = <0>;
};
mmcsd_default_cfg2 {
/* MCCMDDIR, MCDAT0DIR, MCDAT31DIR, MCDATDIR2 */
ste,pins = "GPIO10_C11", "GPIO15_A12",
pins = "GPIO10_C11", "GPIO15_A12",
"GPIO16_C13", "GPIO23_D15";
ste,output = <1>;
};
mmcsd_default_cfg3 {
/* MCCMD, MCDAT3-0, MCMSFBCLK */
ste,pins = "GPIO9_A10", "GPIO11_B11",
pins = "GPIO9_A10", "GPIO11_B11",
"GPIO12_A11", "GPIO13_C12",
"GPIO14_B12", "GPIO24_C15";
ste,input = <1>;
@ -144,13 +144,13 @@
i2c0 {
i2c0_default_mux: i2c0_mux {
i2c0_default_mux {
ste,function = "i2c0";
ste,pins = "i2c0_a_1";
function = "i2c0";
groups = "i2c0_a_1";
};
};
i2c0_default_mode: i2c0_default {
i2c0_default_cfg {
ste,pins = "GPIO62_D3", "GPIO63_D2";
pins = "GPIO62_D3", "GPIO63_D2";
ste,input = <0>;
};
};
@ -158,13 +158,13 @@
i2c1 {
i2c1_default_mux: i2c1_mux {
i2c1_default_mux {
ste,function = "i2c1";
ste,pins = "i2c1_a_1";
function = "i2c1";
groups = "i2c1_a_1";
};
};
i2c1_default_mode: i2c1_default {
i2c1_default_cfg {
ste,pins = "GPIO53_L4", "GPIO54_L3";
pins = "GPIO53_L4", "GPIO54_L3";
ste,input = <0>;
};
};

View file

@ -404,17 +404,17 @@
*/
eth_snowball_mode: eth_snowball {
snowball_mux {
ste,function = "sm";
ste,pins = "sm_b_1";
function = "sm";
groups = "sm_b_1";
};
/* LAN IRQ pin */
snowball_cfg1 {
ste,pins = "GPIO140_B11";
pins = "GPIO140_B11";
ste,config = <&in_nopull>;
};
/* LAN reset pin */
snowball_cfg2 {
ste,pins = "GPIO141_C12";
pins = "GPIO141_C12";
ste,config = <&gpio_out_hi>;
};
@ -423,11 +423,11 @@
sdi0 {
sdi0_default_mode: sdi0_default {
snowball_mux {
ste,function = "mc0";
ste,pins = "mc0dat31dir_a_1";
function = "mc0";
groups = "mc0dat31dir_a_1";
};
snowball_cfg1 {
ste,pins = "GPIO21_AB3"; /* DAT31DIR */
pins = "GPIO21_AB3"; /* DAT31DIR */
ste,config = <&out_hi>;
};
@ -436,19 +436,19 @@
ssp0 {
ssp0_snowball_mode: ssp0_snowball_default {
snowball_mux {
ste,function = "ssp0";
ste,pins = "ssp0_a_1";
function = "ssp0";
groups = "ssp0_a_1";
};
snowball_cfg1 {
ste,pins = "GPIO144_B13"; /* FRM */
pins = "GPIO144_B13"; /* FRM */
ste,config = <&gpio_out_hi>;
};
snowball_cfg2 {
ste,pins = "GPIO145_C13"; /* RXD */
pins = "GPIO145_C13"; /* RXD */
ste,config = <&in_pd>;
};
snowball_cfg3 {
ste,pins =
pins =
"GPIO146_D13", /* TXD */
"GPIO143_D12"; /* CLK */
ste,config = <&out_lo>;
@ -459,7 +459,7 @@
gpio_led {
gpioled_snowball_mode: gpioled_default {
snowball_cfg1 {
ste,pins = "GPIO142_C11";
pins = "GPIO142_C11";
ste,config = <&gpio_out_hi>;
};
@ -469,7 +469,7 @@
accel_snowball_mode: accel_snowball {
/* Accelerometer lines */
snowball_cfg1 {
ste,pins =
pins =
"GPIO163_C20", /* ACCEL_IRQ1 */
"GPIO164_B21"; /* ACCEL_IRQ2 */
ste,config = <&gpio_in_pu>;
@ -479,7 +479,7 @@
magnetometer {
magneto_snowball_mode: magneto_snowball {
snowball_cfg1 {
ste,pins = "GPIO165_C21"; /* MAG_DRDY */
pins = "GPIO165_C21"; /* MAG_DRDY */
ste,config = <&gpio_in_pu>;
};
};
@ -491,7 +491,7 @@
* pull low to reset state
*/
snowball_cfg1 {
ste,pins = "GPIO171_D23"; /* GBF_ENA_RESET */
pins = "GPIO171_D23"; /* GBF_ENA_RESET */
ste,config = <&gpio_out_lo>;
};
};
@ -503,13 +503,13 @@
* These are plain GPIO pins used by WLAN
*/
snowball_cfg1 {
ste,pins =
pins =
"GPIO161_D21", /* WLAN_PMU_EN */
"GPIO215_AH13"; /* WLAN_ENA */
ste,config = <&gpio_out_lo>;
};
snowball_cfg2 {
ste,pins = "GPIO216_AG12"; /* WLAN_IRQ */
pins = "GPIO216_AG12"; /* WLAN_IRQ */
ste,config = <&gpio_in_pu>;
};
};

View file

@ -446,7 +446,7 @@ static int tz1090_gpio_bank_probe(struct tz1090_gpio_bank_info *info)
bank->irq = irq_of_parse_and_map(np, 0);
/* The interrupt is optional (it may be used by another core on chip) */
if (bank->irq < 0) {
if (!bank->irq) {
dev_info(dev, "IRQ not provided for bank %u, IRQs disabled\n",
info->index);
return 0;

View file

@ -11,12 +11,14 @@
*/
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h>
#include <linux/export.h>
#include <linux/acpi.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/pinctrl/pinctrl.h>
#include "gpiolib.h"
@ -55,6 +57,58 @@ static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
return ACPI_HANDLE(gc->dev) == data;
}
#ifdef CONFIG_PINCTRL
/**
* acpi_gpiochip_pin_to_gpio_offset() - translates ACPI GPIO to Linux GPIO
* @chip: GPIO chip
* @pin: ACPI GPIO pin number from GpioIo/GpioInt resource
*
* Function takes ACPI GpioIo/GpioInt pin number as a parameter and
* translates it to a corresponding offset suitable to be passed to a
* GPIO controller driver.
*
* Typically the returned offset is same as @pin, but if the GPIO
* controller uses pin controller and the mapping is not contigous the
* offset might be different.
*/
static int acpi_gpiochip_pin_to_gpio_offset(struct gpio_chip *chip, int pin)
{
struct gpio_pin_range *pin_range;
/* If there are no ranges in this chip, use 1:1 mapping */
if (list_empty(&chip->pin_ranges))
return pin;
list_for_each_entry(pin_range, &chip->pin_ranges, node) {
const struct pinctrl_gpio_range *range = &pin_range->range;
int i;
if (range->pins) {
for (i = 0; i < range->npins; i++) {
if (range->pins[i] == pin)
return range->base + i - chip->base;
}
} else {
if (pin >= range->pin_base &&
pin < range->pin_base + range->npins) {
unsigned gpio_base;
gpio_base = range->base - chip->base;
return gpio_base + pin - range->pin_base;
}
}
}
return -EINVAL;
}
#else
static inline int acpi_gpiochip_pin_to_gpio_offset(struct gpio_chip *chip,
int pin)
{
return pin;
}
#endif
/**
* acpi_get_gpiod() - Translate ACPI GPIO pin to GPIO descriptor usable with GPIO API
* @path: ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1")
@ -69,6 +123,7 @@ static struct gpio_desc *acpi_get_gpiod(char *path, int pin)
struct gpio_chip *chip;
acpi_handle handle;
acpi_status status;
int offset;
status = acpi_get_handle(NULL, path, &handle);
if (ACPI_FAILURE(status))
@ -78,10 +133,11 @@ static struct gpio_desc *acpi_get_gpiod(char *path, int pin)
if (!chip)
return ERR_PTR(-ENODEV);
if (pin < 0 || pin > chip->ngpio)
return ERR_PTR(-EINVAL);
offset = acpi_gpiochip_pin_to_gpio_offset(chip, pin);
if (offset < 0)
return ERR_PTR(offset);
return gpiochip_get_desc(chip, pin);
return gpiochip_get_desc(chip, offset);
}
static irqreturn_t acpi_gpio_irq_handler(int irq, void *data)

View file

@ -67,18 +67,6 @@ config PINCTRL_AT91
help
Say Y here to enable the at91 pinctrl driver
config PINCTRL_BAYTRAIL
bool "Intel Baytrail GPIO pin control"
depends on GPIOLIB && ACPI && X86
select GPIOLIB_IRQCHIP
help
driver for memory mapped GPIO functionality on Intel Baytrail
platforms. Supports 3 banks with 102, 28 and 44 gpios.
Most pins are usually muxed to some other functionality by firmware,
so only a small amount is available for gpio use.
Requires ACPI device enumeration code to set up a platform device.
config PINCTRL_BCM2835
bool
select PINMUX
@ -205,6 +193,7 @@ config PINCTRL_PALMAS
source "drivers/pinctrl/berlin/Kconfig"
source "drivers/pinctrl/freescale/Kconfig"
source "drivers/pinctrl/intel/Kconfig"
source "drivers/pinctrl/mvebu/Kconfig"
source "drivers/pinctrl/nomadik/Kconfig"
source "drivers/pinctrl/qcom/Kconfig"

View file

@ -15,7 +15,6 @@ obj-$(CONFIG_PINCTRL_BF54x) += pinctrl-adi2-bf54x.o
obj-$(CONFIG_PINCTRL_BF60x) += pinctrl-adi2-bf60x.o
obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o
obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o
obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o
obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o
obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o
@ -39,6 +38,7 @@ obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
obj-$(CONFIG_ARCH_BERLIN) += berlin/
obj-y += freescale/
obj-$(CONFIG_X86) += intel/
obj-$(CONFIG_PLAT_ORION) += mvebu/
obj-y += nomadik/
obj-$(CONFIG_ARCH_QCOM) += qcom/

View file

@ -294,11 +294,83 @@ static int imx_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector,
return 0;
}
static int imx_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, unsigned offset)
{
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
const struct imx_pinctrl_soc_info *info = ipctl->info;
const struct imx_pin_reg *pin_reg;
struct imx_pin_group *grp;
struct imx_pin *imx_pin;
unsigned int pin, group;
u32 reg;
/* Currently implementation only for shared mux/conf register */
if (!(info->flags & SHARE_MUX_CONF_REG))
return -EINVAL;
pin_reg = &info->pin_regs[offset];
if (pin_reg->mux_reg == -1)
return -EINVAL;
/* Find the pinctrl config with GPIO mux mode for the requested pin */
for (group = 0; group < info->ngroups; group++) {
grp = &info->groups[group];
for (pin = 0; pin < grp->npins; pin++) {
imx_pin = &grp->pins[pin];
if (imx_pin->pin == offset && !imx_pin->mux_mode)
goto mux_pin;
}
}
return -EINVAL;
mux_pin:
reg = readl(ipctl->base + pin_reg->mux_reg);
reg &= ~(0x7 << 20);
reg |= imx_pin->config;
writel(reg, ipctl->base + pin_reg->mux_reg);
return 0;
}
static int imx_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, unsigned offset, bool input)
{
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
const struct imx_pinctrl_soc_info *info = ipctl->info;
const struct imx_pin_reg *pin_reg;
u32 reg;
/*
* Only Vybrid has the input/output buffer enable flags (IBE/OBE)
* They are part of the shared mux/conf register.
*/
if (!(info->flags & SHARE_MUX_CONF_REG))
return -EINVAL;
pin_reg = &info->pin_regs[offset];
if (pin_reg->mux_reg == -1)
return -EINVAL;
/* IBE always enabled allows us to read the value "on the wire" */
reg = readl(ipctl->base + pin_reg->mux_reg);
if (input)
reg &= ~0x2;
else
reg |= 0x2;
writel(reg, ipctl->base + pin_reg->mux_reg);
return 0;
}
static const struct pinmux_ops imx_pmx_ops = {
.get_functions_count = imx_pmx_get_funcs_count,
.get_function_name = imx_pmx_get_func_name,
.get_function_groups = imx_pmx_get_groups,
.set_mux = imx_pmx_set,
.gpio_request_enable = imx_pmx_gpio_request_enable,
.gpio_set_direction = imx_pmx_gpio_set_direction,
};
static int imx_pinconf_get(struct pinctrl_dev *pctldev,

View file

@ -445,6 +445,31 @@ static int mxs_pinctrl_probe_dt(struct platform_device *pdev,
if (of_property_read_u32(child, "reg", &val))
continue;
if (strcmp(fn, child->name)) {
struct device_node *child2;
/*
* This reference is dropped by
* of_get_next_child(np, * child)
*/
of_node_get(child);
/*
* The logic parsing the functions from dt currently
* doesn't handle if functions with the same name are
* not grouped together. Only the first contiguous
* cluster is usable for each function name. This is a
* bug that is not trivial to fix, but at least warn
* about it.
*/
for (child2 = of_get_next_child(np, child);
child2 != NULL;
child2 = of_get_next_child(np, child2)) {
if (!strcmp(child2->name, fn))
dev_warn(&pdev->dev,
"function nodes must be grouped by name (failed for: %s)",
fn);
}
f = &soc->functions[idxf++];
f->name = fn = child->name;
}

View file

@ -0,0 +1,27 @@
#
# Intel pin control drivers
#
config PINCTRL_BAYTRAIL
bool "Intel Baytrail GPIO pin control"
depends on GPIOLIB && ACPI
select GPIOLIB_IRQCHIP
help
driver for memory mapped GPIO functionality on Intel Baytrail
platforms. Supports 3 banks with 102, 28 and 44 gpios.
Most pins are usually muxed to some other functionality by firmware,
so only a small amount is available for gpio use.
Requires ACPI device enumeration code to set up a platform device.
config PINCTRL_CHERRYVIEW
tristate "Intel Cherryview/Braswell pinctrl and GPIO driver"
depends on ACPI
select PINMUX
select PINCONF
select GENERIC_PINCONF
select GPIOLIB
select GPIOLIB_IRQCHIP
help
Cherryview/Braswell pinctrl driver provides an interface that
allows configuring of SoC pins and using them as GPIOs.

View file

@ -0,0 +1,4 @@
# Intel pin control drivers
obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o
obj-$(CONFIG_PINCTRL_CHERRYVIEW) += pinctrl-cherryview.o

View file

@ -616,5 +616,10 @@ static int __init byt_gpio_init(void)
{
return platform_driver_register(&byt_gpio_driver);
}
subsys_initcall(byt_gpio_init);
static void __exit byt_gpio_exit(void)
{
platform_driver_unregister(&byt_gpio_driver);
}
module_exit(byt_gpio_exit);

File diff suppressed because it is too large Load diff

View file

@ -891,14 +891,13 @@ static int abx500_dt_subnode_to_map(struct pinctrl_dev *pctldev,
const char *function = NULL;
unsigned long *configs;
unsigned int nconfigs = 0;
bool has_config = 0;
struct property *prop;
const char *group, *gpio_name;
struct device_node *np_config;
ret = of_property_read_string(np, "ste,function", &function);
ret = of_property_read_string(np, "function", &function);
if (ret >= 0) {
ret = of_property_count_strings(np, "ste,pins");
const char *group;
ret = of_property_count_strings(np, "groups");
if (ret < 0)
goto exit;
@ -907,7 +906,7 @@ static int abx500_dt_subnode_to_map(struct pinctrl_dev *pctldev,
if (ret < 0)
goto exit;
of_property_for_each_string(np, "ste,pins", prop, group) {
of_property_for_each_string(np, "groups", prop, group) {
ret = abx500_dt_add_map_mux(map, reserved_maps,
num_maps, group, function);
if (ret < 0)
@ -916,18 +915,11 @@ static int abx500_dt_subnode_to_map(struct pinctrl_dev *pctldev,
}
ret = pinconf_generic_parse_dt_config(np, &configs, &nconfigs);
if (nconfigs)
has_config = 1;
np_config = of_parse_phandle(np, "ste,config", 0);
if (np_config) {
ret = pinconf_generic_parse_dt_config(np_config, &configs,
&nconfigs);
if (ret)
goto exit;
has_config |= nconfigs;
}
if (has_config) {
ret = of_property_count_strings(np, "ste,pins");
if (nconfigs) {
const char *gpio_name;
const char *pin;
ret = of_property_count_strings(np, "pins");
if (ret < 0)
goto exit;
@ -937,8 +929,8 @@ static int abx500_dt_subnode_to_map(struct pinctrl_dev *pctldev,
if (ret < 0)
goto exit;
of_property_for_each_string(np, "ste,pins", prop, group) {
gpio_name = abx500_find_pin_name(pctldev, group);
of_property_for_each_string(np, "pins", prop, pin) {
gpio_name = abx500_find_pin_name(pctldev, pin);
ret = abx500_dt_add_map_configs(map, reserved_maps,
num_maps, gpio_name, configs, 1);
@ -1112,6 +1104,7 @@ out:
static const struct pinconf_ops abx500_pinconf_ops = {
.pin_config_get = abx500_pin_config_get,
.pin_config_set = abx500_pin_config_set,
.is_generic = true,
};
static struct pinctrl_desc abx500_pinctrl_desc = {

View file

@ -291,6 +291,7 @@ static const unsigned u0_a_1_pins[] = { STN8815_PIN_B4, STN8815_PIN_D5,
static const unsigned mmcsd_a_1_pins[] = { STN8815_PIN_B10, STN8815_PIN_A10,
STN8815_PIN_C11, STN8815_PIN_B11, STN8815_PIN_A11, STN8815_PIN_C12,
STN8815_PIN_B12, STN8815_PIN_A12, STN8815_PIN_C13, STN8815_PIN_C15 };
static const unsigned mmcsd_b_1_pins[] = { STN8815_PIN_D15 };
static const unsigned u1_a_1_pins[] = { STN8815_PIN_M2, STN8815_PIN_L1,
STN8815_PIN_F3, STN8815_PIN_F2 };
static const unsigned i2c1_a_1_pins[] = { STN8815_PIN_L4, STN8815_PIN_L3 };
@ -305,6 +306,7 @@ static const unsigned i2cusb_b_1_pins[] = { STN8815_PIN_C21, STN8815_PIN_C20 };
static const struct nmk_pingroup nmk_stn8815_groups[] = {
STN8815_PIN_GROUP(u0_a_1, NMK_GPIO_ALT_A),
STN8815_PIN_GROUP(mmcsd_a_1, NMK_GPIO_ALT_A),
STN8815_PIN_GROUP(mmcsd_b_1, NMK_GPIO_ALT_B),
STN8815_PIN_GROUP(u1_a_1, NMK_GPIO_ALT_A),
STN8815_PIN_GROUP(i2c1_a_1, NMK_GPIO_ALT_A),
STN8815_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A),
@ -317,7 +319,7 @@ static const struct nmk_pingroup nmk_stn8815_groups[] = {
static const char * const a##_groups[] = { b };
STN8815_FUNC_GROUPS(u0, "u0_a_1");
STN8815_FUNC_GROUPS(mmcsd, "mmcsd_a_1");
STN8815_FUNC_GROUPS(mmcsd, "mmcsd_a_1", "mmcsd_b_1");
STN8815_FUNC_GROUPS(u1, "u1_a_1", "u1_b_1");
STN8815_FUNC_GROUPS(i2c1, "i2c1_a_1");
STN8815_FUNC_GROUPS(i2c0, "i2c0_a_1");

View file

@ -1520,12 +1520,13 @@ static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
unsigned long configs = 0;
bool has_config = 0;
struct property *prop;
const char *group, *gpio_name;
struct device_node *np_config;
ret = of_property_read_string(np, "ste,function", &function);
ret = of_property_read_string(np, "function", &function);
if (ret >= 0) {
ret = of_property_count_strings(np, "ste,pins");
const char *group;
ret = of_property_count_strings(np, "groups");
if (ret < 0)
goto exit;
@ -1535,7 +1536,7 @@ static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
if (ret < 0)
goto exit;
of_property_for_each_string(np, "ste,pins", prop, group) {
of_property_for_each_string(np, "groups", prop, group) {
ret = nmk_dt_add_map_mux(map, reserved_maps, num_maps,
group, function);
if (ret < 0)
@ -1548,7 +1549,10 @@ static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
if (np_config)
has_config |= nmk_pinctrl_dt_get_config(np_config, &configs);
if (has_config) {
ret = of_property_count_strings(np, "ste,pins");
const char *gpio_name;
const char *pin;
ret = of_property_count_strings(np, "pins");
if (ret < 0)
goto exit;
ret = pinctrl_utils_reserve_map(pctldev, map,
@ -1557,8 +1561,8 @@ static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
if (ret < 0)
goto exit;
of_property_for_each_string(np, "ste,pins", prop, group) {
gpio_name = nmk_find_pin_name(pctldev, group);
of_property_for_each_string(np, "pins", prop, pin) {
gpio_name = nmk_find_pin_name(pctldev, pin);
ret = nmk_dt_add_map_configs(map, reserved_maps,
num_maps,

View file

@ -32,30 +32,32 @@ struct pin_config_item {
const enum pin_config_param param;
const char * const display;
const char * const format;
bool has_arg;
};
#define PCONFDUMP(a, b, c) { .param = a, .display = b, .format = c }
#define PCONFDUMP(a, b, c, d) { .param = a, .display = b, .format = c, \
.has_arg = d }
static struct pin_config_item conf_items[] = {
PCONFDUMP(PIN_CONFIG_BIAS_DISABLE, "input bias disabled", NULL),
PCONFDUMP(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, "input bias high impedance", NULL),
PCONFDUMP(PIN_CONFIG_BIAS_BUS_HOLD, "input bias bus hold", NULL),
PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL),
PCONFDUMP(PIN_CONFIG_BIAS_PULL_DOWN, "input bias pull down", NULL),
static const struct pin_config_item conf_items[] = {
PCONFDUMP(PIN_CONFIG_BIAS_DISABLE, "input bias disabled", NULL, false),
PCONFDUMP(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, "input bias high impedance", NULL, false),
PCONFDUMP(PIN_CONFIG_BIAS_BUS_HOLD, "input bias bus hold", NULL, false),
PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL, false),
PCONFDUMP(PIN_CONFIG_BIAS_PULL_DOWN, "input bias pull down", NULL, false),
PCONFDUMP(PIN_CONFIG_BIAS_PULL_PIN_DEFAULT,
"input bias pull to pin specific state", NULL),
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_DRIVE_STRENGTH, "output drive strength", "mA"),
PCONFDUMP(PIN_CONFIG_INPUT_ENABLE, "input enabled", 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", "usec"),
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"),
"input bias pull to pin specific state", NULL, false),
PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL, false),
PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL, false),
PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL, false),
PCONFDUMP(PIN_CONFIG_DRIVE_STRENGTH, "output drive strength", "mA", true),
PCONFDUMP(PIN_CONFIG_INPUT_ENABLE, "input enabled", NULL, false),
PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_ENABLE, "input schmitt enabled", NULL, false),
PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL, false),
PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "usec", true),
PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector", true),
PCONFDUMP(PIN_CONFIG_SLEW_RATE, "slew rate", NULL, true),
PCONFDUMP(PIN_CONFIG_LOW_POWER_MODE, "pin low power", "mode", true),
PCONFDUMP(PIN_CONFIG_OUTPUT, "pin output", "level", true),
};
void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev,
@ -85,11 +87,14 @@ void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev,
seq_puts(s, " ");
seq_puts(s, conf_items[i].display);
/* Print unit if available */
if (conf_items[i].format &&
pinconf_to_config_argument(config) != 0)
seq_printf(s, " (%u %s)",
pinconf_to_config_argument(config),
conf_items[i].format);
if (conf_items[i].has_arg) {
seq_printf(s, " (%u",
pinconf_to_config_argument(config));
if (conf_items[i].format)
seq_printf(s, " %s)", conf_items[i].format);
else
seq_puts(s, ")");
}
}
}
@ -121,10 +126,14 @@ void pinconf_generic_dump_group(struct pinctrl_dev *pctldev,
seq_puts(s, " ");
seq_puts(s, conf_items[i].display);
/* Print unit if available */
if (conf_items[i].format && config != 0)
seq_printf(s, " (%u %s)",
pinconf_to_config_argument(config),
conf_items[i].format);
if (conf_items[i].has_arg) {
seq_printf(s, " (%u",
pinconf_to_config_argument(config));
if (conf_items[i].format)
seq_printf(s, " %s)", conf_items[i].format);
else
seq_puts(s, ")");
}
}
}
@ -150,7 +159,7 @@ struct pinconf_generic_dt_params {
u32 default_value;
};
static struct pinconf_generic_dt_params dt_params[] = {
static const struct pinconf_generic_dt_params dt_params[] = {
{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
{ "bias-high-impedance", PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0 },
{ "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 },
@ -200,7 +209,7 @@ int pinconf_generic_parse_dt_config(struct device_node *np,
return -ENOMEM;
for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
struct pinconf_generic_dt_params *par = &dt_params[i];
const struct pinconf_generic_dt_params *par = &dt_params[i];
ret = of_property_read_u32(np, par->property, &val);
/* property not found */

View file

@ -25,9 +25,7 @@
/* Since we request GPIOs from ourself */
#include <linux/pinctrl/consumer.h>
#include <mach/hardware.h>
#include <mach/at91_pio.h>
#include "pinctrl-at91.h"
#include "core.h"
#define MAX_GPIO_BANKS 5
@ -1344,7 +1342,6 @@ static void at91_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
for (i = 0; i < chip->ngpio; i++) {
unsigned mask = pin_to_mask(i);
const char *gpio_label;
u32 pdsr;
gpio_label = gpiochip_is_requested(chip, i);
if (!gpio_label)
@ -1353,11 +1350,13 @@ static void at91_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
seq_printf(s, "[%s] GPIO%s%d: ",
gpio_label, chip->label, i);
if (mode == AT91_MUX_GPIO) {
pdsr = readl_relaxed(pio + PIO_PDSR);
seq_printf(s, "[gpio] %s\n",
pdsr & mask ?
"set" : "clear");
seq_printf(s, "[gpio] ");
seq_printf(s, "%s ",
readl_relaxed(pio + PIO_OSR) & mask ?
"output" : "input");
seq_printf(s, "%s\n",
readl_relaxed(pio + PIO_PDSR) & mask ?
"set" : "clear");
} else {
seq_printf(s, "[periph %c]\n",
mode + 'A' - 1);

View file

@ -0,0 +1,72 @@
/*
* Copyright (C) 2005 Ivan Kokshaysky
* Copyright (C) SAN People
*
* Parallel I/O Controller (PIO) - System peripherals registers.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef __PINCTRL_AT91_H
#define __PINCTRL_AT91_H
#define PIO_PER 0x00 /* Enable Register */
#define PIO_PDR 0x04 /* Disable Register */
#define PIO_PSR 0x08 /* Status Register */
#define PIO_OER 0x10 /* Output Enable Register */
#define PIO_ODR 0x14 /* Output Disable Register */
#define PIO_OSR 0x18 /* Output Status Register */
#define PIO_IFER 0x20 /* Glitch Input Filter Enable */
#define PIO_IFDR 0x24 /* Glitch Input Filter Disable */
#define PIO_IFSR 0x28 /* Glitch Input Filter Status */
#define PIO_SODR 0x30 /* Set Output Data Register */
#define PIO_CODR 0x34 /* Clear Output Data Register */
#define PIO_ODSR 0x38 /* Output Data Status Register */
#define PIO_PDSR 0x3c /* Pin Data Status Register */
#define PIO_IER 0x40 /* Interrupt Enable Register */
#define PIO_IDR 0x44 /* Interrupt Disable Register */
#define PIO_IMR 0x48 /* Interrupt Mask Register */
#define PIO_ISR 0x4c /* Interrupt Status Register */
#define PIO_MDER 0x50 /* Multi-driver Enable Register */
#define PIO_MDDR 0x54 /* Multi-driver Disable Register */
#define PIO_MDSR 0x58 /* Multi-driver Status Register */
#define PIO_PUDR 0x60 /* Pull-up Disable Register */
#define PIO_PUER 0x64 /* Pull-up Enable Register */
#define PIO_PUSR 0x68 /* Pull-up Status Register */
#define PIO_ASR 0x70 /* Peripheral A Select Register */
#define PIO_ABCDSR1 0x70 /* Peripheral ABCD Select Register 1 [some sam9 only] */
#define PIO_BSR 0x74 /* Peripheral B Select Register */
#define PIO_ABCDSR2 0x74 /* Peripheral ABCD Select Register 2 [some sam9 only] */
#define PIO_ABSR 0x78 /* AB Status Register */
#define PIO_IFSCDR 0x80 /* Input Filter Slow Clock Disable Register */
#define PIO_IFSCER 0x84 /* Input Filter Slow Clock Enable Register */
#define PIO_IFSCSR 0x88 /* Input Filter Slow Clock Status Register */
#define PIO_SCDR 0x8c /* Slow Clock Divider Debouncing Register */
#define PIO_SCDR_DIV (0x3fff << 0) /* Slow Clock Divider Mask */
#define PIO_PPDDR 0x90 /* Pad Pull-down Disable Register */
#define PIO_PPDER 0x94 /* Pad Pull-down Enable Register */
#define PIO_PPDSR 0x98 /* Pad Pull-down Status Register */
#define PIO_OWER 0xa0 /* Output Write Enable Register */
#define PIO_OWDR 0xa4 /* Output Write Disable Register */
#define PIO_OWSR 0xa8 /* Output Write Status Register */
#define PIO_AIMER 0xb0 /* Additional Interrupt Modes Enable Register */
#define PIO_AIMDR 0xb4 /* Additional Interrupt Modes Disable Register */
#define PIO_AIMMR 0xb8 /* Additional Interrupt Modes Mask Register */
#define PIO_ESR 0xc0 /* Edge Select Register */
#define PIO_LSR 0xc4 /* Level Select Register */
#define PIO_ELSR 0xc8 /* Edge/Level Status Register */
#define PIO_FELLSR 0xd0 /* Falling Edge/Low Level Select Register */
#define PIO_REHLSR 0xd4 /* Rising Edge/ High Level Select Register */
#define PIO_FRLHSR 0xd8 /* Fall/Rise - Low/High Status Register */
#define PIO_SCHMITT 0x100 /* Schmitt Trigger Register */
#define SAMA5D3_PIO_DRIVER1 0x118 /*PIO Driver 1 register offset*/
#define SAMA5D3_PIO_DRIVER2 0x11C /*PIO Driver 2 register offset*/
#define AT91SAM9X5_PIO_DRIVER1 0x114 /*PIO Driver 1 register offset*/
#define AT91SAM9X5_PIO_DRIVER2 0x118 /*PIO Driver 2 register offset*/
#endif

View file

@ -1404,11 +1404,6 @@ static int __init bcm281xx_pinctrl_probe(struct platform_device *pdev)
/* So far We can assume there is only 1 bank of registers */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "Missing MEM resource\n");
return -ENODEV;
}
pdata->reg_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(pdata->reg_base)) {
dev_err(&pdev->dev, "Failed to ioremap MEM resource\n");

View file

@ -856,27 +856,22 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
* leads to this function call (via the pinctrl_gpio_direction_{input|output}()
* function called from the gpiolib interface).
*/
static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset, bool input)
static int _rockchip_pmx_gpio_set_direction(struct gpio_chip *chip,
int pin, bool input)
{
struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
struct rockchip_pin_bank *bank;
struct gpio_chip *chip;
int pin, ret;
int ret;
unsigned long flags;
u32 data;
chip = range->gc;
bank = gc_to_pin_bank(chip);
pin = offset - chip->base;
dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n",
offset, range->name, pin, input ? "input" : "output");
ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO);
if (ret < 0)
return ret;
spin_lock_irqsave(&bank->slock, flags);
data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
/* set bit to 1 for output, 0 for input */
if (!input)
@ -885,9 +880,28 @@ static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
data &= ~BIT(pin);
writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
spin_unlock_irqrestore(&bank->slock, flags);
return 0;
}
static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset, bool input)
{
struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
struct gpio_chip *chip;
int pin;
chip = range->gc;
pin = offset - chip->base;
dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n",
offset, range->name, pin, input ? "input" : "output");
return _rockchip_pmx_gpio_set_direction(chip, offset - chip->base,
input);
}
static const struct pinmux_ops rockchip_pmx_ops = {
.get_functions_count = rockchip_pmx_get_funcs_count,
.get_function_name = rockchip_pmx_get_func_name,
@ -917,8 +931,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
return false;
}
static int rockchip_gpio_direction_output(struct gpio_chip *gc,
unsigned offset, int value);
static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value);
static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset);
/* set the pin config settings for a specified pin */
@ -959,9 +972,10 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
return rc;
break;
case PIN_CONFIG_OUTPUT:
rc = rockchip_gpio_direction_output(&bank->gpio_chip,
pin - bank->pin_base,
arg);
rockchip_gpio_set(&bank->gpio_chip,
pin - bank->pin_base, arg);
rc = _rockchip_pmx_gpio_set_direction(&bank->gpio_chip,
pin - bank->pin_base, false);
if (rc)
return rc;
break;
@ -1253,6 +1267,10 @@ static int rockchip_pinctrl_register(struct platform_device *pdev,
}
}
ret = rockchip_pinctrl_parse_dt(pdev, info);
if (ret)
return ret;
info->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, info);
if (!info->pctl_dev) {
dev_err(&pdev->dev, "could not register pinctrl driver\n");
@ -1270,12 +1288,6 @@ static int rockchip_pinctrl_register(struct platform_device *pdev,
pinctrl_add_gpio_range(info->pctl_dev, &pin_bank->grange);
}
ret = rockchip_pinctrl_parse_dt(pdev, info);
if (ret) {
pinctrl_unregister(info->pctl_dev);
return ret;
}
return 0;
}
@ -1387,6 +1399,7 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc)
u32 polarity = 0, data = 0;
u32 pend;
bool edge_changed = false;
unsigned long flags;
dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name);
@ -1432,10 +1445,14 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc)
if (bank->toggle_edge_mode && edge_changed) {
/* Interrupt params should only be set with ints disabled */
spin_lock_irqsave(&bank->slock, flags);
data = readl_relaxed(bank->reg_base + GPIO_INTEN);
writel_relaxed(0, bank->reg_base + GPIO_INTEN);
writel(polarity, bank->reg_base + GPIO_INT_POLARITY);
writel(data, bank->reg_base + GPIO_INTEN);
spin_unlock_irqrestore(&bank->slock, flags);
}
chained_irq_exit(chip, desc);
@ -1449,6 +1466,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
u32 polarity;
u32 level;
u32 data;
unsigned long flags;
int ret;
/* make sure the pin is configured as gpio input */
@ -1456,15 +1474,20 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
if (ret < 0)
return ret;
spin_lock_irqsave(&bank->slock, flags);
data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
data &= ~mask;
writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
spin_unlock_irqrestore(&bank->slock, flags);
if (type & IRQ_TYPE_EDGE_BOTH)
__irq_set_handler_locked(d->irq, handle_edge_irq);
else
__irq_set_handler_locked(d->irq, handle_level_irq);
spin_lock_irqsave(&bank->slock, flags);
irq_gc_lock(gc);
level = readl_relaxed(gc->reg_base + GPIO_INTTYPE_LEVEL);
@ -1507,6 +1530,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
break;
default:
irq_gc_unlock(gc);
spin_unlock_irqrestore(&bank->slock, flags);
return -EINVAL;
}
@ -1514,6 +1538,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
writel_relaxed(polarity, gc->reg_base + GPIO_INT_POLARITY);
irq_gc_unlock(gc);
spin_unlock_irqrestore(&bank->slock, flags);
return 0;
}
@ -1563,6 +1588,7 @@ static int rockchip_interrupts_register(struct platform_device *pdev,
gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake;
gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type;
gc->wake_enabled = IRQ_MSK(bank->nr_pins);
irq_set_handler_data(bank->irq, bank);
irq_set_chained_handler(bank->irq, rockchip_irq_demux);
@ -1770,6 +1796,51 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
return ctrl;
}
#define RK3288_GRF_GPIO6C_IOMUX 0x64
#define GPIO6C6_SEL_WRITE_ENABLE BIT(28)
static u32 rk3288_grf_gpio6c_iomux;
static int __maybe_unused rockchip_pinctrl_suspend(struct device *dev)
{
struct rockchip_pinctrl *info = dev_get_drvdata(dev);
int ret = pinctrl_force_sleep(info->pctl_dev);
if (ret)
return ret;
/*
* RK3288 GPIO6_C6 mux would be modified by Maskrom when resume, so save
* the setting here, and restore it at resume.
*/
if (info->ctrl->type == RK3288) {
ret = regmap_read(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX,
&rk3288_grf_gpio6c_iomux);
if (ret) {
pinctrl_force_default(info->pctl_dev);
return ret;
}
}
return 0;
}
static int __maybe_unused rockchip_pinctrl_resume(struct device *dev)
{
struct rockchip_pinctrl *info = dev_get_drvdata(dev);
int ret = regmap_write(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX,
rk3288_grf_gpio6c_iomux |
GPIO6C6_SEL_WRITE_ENABLE);
if (ret)
return ret;
return pinctrl_force_default(info->pctl_dev);
}
static SIMPLE_DEV_PM_OPS(rockchip_pinctrl_dev_pm_ops, rockchip_pinctrl_suspend,
rockchip_pinctrl_resume);
static int rockchip_pinctrl_probe(struct platform_device *pdev)
{
struct rockchip_pinctrl *info;
@ -1983,6 +2054,7 @@ static struct platform_driver rockchip_pinctrl_driver = {
.driver = {
.name = "rockchip-pinctrl",
.owner = THIS_MODULE,
.pm = &rockchip_pinctrl_dev_pm_ops,
.of_match_table = rockchip_pinctrl_dt_match,
},
};

View file

@ -1512,7 +1512,7 @@ static int st_gpiolib_register_bank(struct st_pinctrl *info,
gpio_irq, st_gpio_irq_handler);
}
if (info->irqmux_base > 0 || gpio_irq > 0) {
if (info->irqmux_base || gpio_irq > 0) {
err = gpiochip_irqchip_add(&bank->gpio_chip, &st_gpio_irqchip,
0, handle_simple_irq,
IRQ_TYPE_LEVEL_LOW);

View file

@ -759,7 +759,7 @@ static struct pinctrl_desc tb10x_pindesc = {
static int tb10x_pinctrl_probe(struct platform_device *pdev)
{
int ret = -EINVAL;
struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct resource *mem;
struct device *dev = &pdev->dev;
struct device_node *of_node = dev->of_node;
struct device_node *child;
@ -771,11 +771,6 @@ static int tb10x_pinctrl_probe(struct platform_device *pdev)
return -EINVAL;
}
if (!mem) {
dev_err(dev, "No memory resource defined.\n");
return -EINVAL;
}
state = devm_kzalloc(dev, sizeof(struct tb10x_pinctrl) +
of_get_child_count(of_node)
* sizeof(struct tb10x_of_pinfunc),
@ -787,6 +782,7 @@ static int tb10x_pinctrl_probe(struct platform_device *pdev)
state->pinfuncs = (struct tb10x_of_pinfunc *)(state + 1);
mutex_init(&state->mutex);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
state->base = devm_ioremap_resource(dev, mem);
if (IS_ERR(state->base)) {
ret = PTR_ERR(state->base);

View file

@ -20,6 +20,7 @@
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
@ -171,7 +172,7 @@ static int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl,
if (err == -EINVAL)
continue;
return err;
goto out;
}
config = TEGRA_XUSB_PADCTL_PACK(properties[i].param, value);
@ -179,7 +180,7 @@ static int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl,
err = pinctrl_utils_add_config(padctl->pinctrl, &configs,
&num_configs, config);
if (err < 0)
return err;
goto out;
}
if (function)
@ -190,14 +191,14 @@ static int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl,
err = of_property_count_strings(np, "nvidia,lanes");
if (err < 0)
return err;
goto out;
reserve *= err;
err = pinctrl_utils_reserve_map(padctl->pinctrl, maps, reserved_maps,
num_maps, reserve);
if (err < 0)
return err;
goto out;
of_property_for_each_string(np, "nvidia,lanes", prop, group) {
if (function) {
@ -205,7 +206,7 @@ static int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl,
reserved_maps, num_maps, group,
function);
if (err < 0)
return err;
goto out;
}
if (num_configs) {
@ -214,11 +215,15 @@ static int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl,
configs, num_configs,
PIN_MAP_TYPE_CONFIGS_GROUP);
if (err < 0)
return err;
goto out;
}
}
return 0;
err = 0;
out:
kfree(configs);
return err;
}
static int tegra_xusb_padctl_dt_node_to_map(struct pinctrl_dev *pinctrl,

View file

@ -47,4 +47,17 @@ config PINCTRL_MSM8X74
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm 8974 platform.
config PINCTRL_QCOM_SPMI_PMIC
tristate "Qualcomm SPMI PMIC pin controller driver"
depends on GPIOLIB && OF && SPMI
select REGMAP_SPMI
select PINMUX
select PINCONF
select GENERIC_PINCONF
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm GPIO and MPP blocks found in the Qualcomm PMIC's chips,
which are using SPMI for communication with SoC. Example PMIC's
devices are pm8841, pm8941 and pma8084.
endif

View file

@ -5,3 +5,5 @@ obj-$(CONFIG_PINCTRL_APQ8084) += pinctrl-apq8084.o
obj-$(CONFIG_PINCTRL_IPQ8064) += pinctrl-ipq8064.o
obj-$(CONFIG_PINCTRL_MSM8960) += pinctrl-msm8960.o
obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o
obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-gpio.o
obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-mpp.o

View file

@ -0,0 +1,933 @@
/*
* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
#include "../core.h"
#include "../pinctrl-utils.h"
#define PMIC_GPIO_ADDRESS_RANGE 0x100
/* type and subtype registers base address offsets */
#define PMIC_GPIO_REG_TYPE 0x4
#define PMIC_GPIO_REG_SUBTYPE 0x5
/* GPIO peripheral type and subtype out_values */
#define PMIC_GPIO_TYPE 0x10
#define PMIC_GPIO_SUBTYPE_GPIO_4CH 0x1
#define PMIC_GPIO_SUBTYPE_GPIOC_4CH 0x5
#define PMIC_GPIO_SUBTYPE_GPIO_8CH 0x9
#define PMIC_GPIO_SUBTYPE_GPIOC_8CH 0xd
#define PMIC_MPP_REG_RT_STS 0x10
#define PMIC_MPP_REG_RT_STS_VAL_MASK 0x1
/* control register base address offsets */
#define PMIC_GPIO_REG_MODE_CTL 0x40
#define PMIC_GPIO_REG_DIG_VIN_CTL 0x41
#define PMIC_GPIO_REG_DIG_PULL_CTL 0x42
#define PMIC_GPIO_REG_DIG_OUT_CTL 0x45
#define PMIC_GPIO_REG_EN_CTL 0x46
/* PMIC_GPIO_REG_MODE_CTL */
#define PMIC_GPIO_REG_MODE_VALUE_SHIFT 0x1
#define PMIC_GPIO_REG_MODE_FUNCTION_SHIFT 1
#define PMIC_GPIO_REG_MODE_FUNCTION_MASK 0x7
#define PMIC_GPIO_REG_MODE_DIR_SHIFT 4
#define PMIC_GPIO_REG_MODE_DIR_MASK 0x7
/* PMIC_GPIO_REG_DIG_VIN_CTL */
#define PMIC_GPIO_REG_VIN_SHIFT 0
#define PMIC_GPIO_REG_VIN_MASK 0x7
/* PMIC_GPIO_REG_DIG_PULL_CTL */
#define PMIC_GPIO_REG_PULL_SHIFT 0
#define PMIC_GPIO_REG_PULL_MASK 0x7
#define PMIC_GPIO_PULL_DOWN 4
#define PMIC_GPIO_PULL_DISABLE 5
/* PMIC_GPIO_REG_DIG_OUT_CTL */
#define PMIC_GPIO_REG_OUT_STRENGTH_SHIFT 0
#define PMIC_GPIO_REG_OUT_STRENGTH_MASK 0x3
#define PMIC_GPIO_REG_OUT_TYPE_SHIFT 4
#define PMIC_GPIO_REG_OUT_TYPE_MASK 0x3
/*
* Output type - indicates pin should be configured as push-pull,
* open drain or open source.
*/
#define PMIC_GPIO_OUT_BUF_CMOS 0
#define PMIC_GPIO_OUT_BUF_OPEN_DRAIN_NMOS 1
#define PMIC_GPIO_OUT_BUF_OPEN_DRAIN_PMOS 2
/* PMIC_GPIO_REG_EN_CTL */
#define PMIC_GPIO_REG_MASTER_EN_SHIFT 7
#define PMIC_GPIO_PHYSICAL_OFFSET 1
/* Qualcomm specific pin configurations */
#define PMIC_GPIO_CONF_PULL_UP (PIN_CONFIG_END + 1)
#define PMIC_GPIO_CONF_STRENGTH (PIN_CONFIG_END + 2)
/**
* struct pmic_gpio_pad - keep current GPIO settings
* @base: Address base in SPMI device.
* @irq: IRQ number which this GPIO generate.
* @is_enabled: Set to false when GPIO should be put in high Z state.
* @out_value: Cached pin output value
* @have_buffer: Set to true if GPIO output could be configured in push-pull,
* open-drain or open-source mode.
* @output_enabled: Set to true if GPIO output logic is enabled.
* @input_enabled: Set to true if GPIO input buffer logic is enabled.
* @num_sources: Number of power-sources supported by this GPIO.
* @power_source: Current power-source used.
* @buffer_type: Push-pull, open-drain or open-source.
* @pullup: Constant current which flow trough GPIO output buffer.
* @strength: No, Low, Medium, High
* @function: See pmic_gpio_functions[]
*/
struct pmic_gpio_pad {
u16 base;
int irq;
bool is_enabled;
bool out_value;
bool have_buffer;
bool output_enabled;
bool input_enabled;
unsigned int num_sources;
unsigned int power_source;
unsigned int buffer_type;
unsigned int pullup;
unsigned int strength;
unsigned int function;
};
struct pmic_gpio_state {
struct device *dev;
struct regmap *map;
struct pinctrl_dev *ctrl;
struct gpio_chip chip;
};
struct pmic_gpio_bindings {
const char *property;
unsigned param;
};
static struct pmic_gpio_bindings pmic_gpio_bindings[] = {
{"qcom,pull-up-strength", PMIC_GPIO_CONF_PULL_UP},
{"qcom,drive-strength", PMIC_GPIO_CONF_STRENGTH},
};
static const char *const pmic_gpio_groups[] = {
"gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", "gpio8",
"gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", "gpio15",
"gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", "gpio22",
"gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", "gpio29",
"gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35", "gpio36",
};
static const char *const pmic_gpio_functions[] = {
PMIC_GPIO_FUNC_NORMAL, PMIC_GPIO_FUNC_PAIRED,
PMIC_GPIO_FUNC_FUNC1, PMIC_GPIO_FUNC_FUNC2,
PMIC_GPIO_FUNC_DTEST1, PMIC_GPIO_FUNC_DTEST2,
PMIC_GPIO_FUNC_DTEST3, PMIC_GPIO_FUNC_DTEST4,
};
static inline struct pmic_gpio_state *to_gpio_state(struct gpio_chip *chip)
{
return container_of(chip, struct pmic_gpio_state, chip);
};
static int pmic_gpio_read(struct pmic_gpio_state *state,
struct pmic_gpio_pad *pad, unsigned int addr)
{
unsigned int val;
int ret;
ret = regmap_read(state->map, pad->base + addr, &val);
if (ret < 0)
dev_err(state->dev, "read 0x%x failed\n", addr);
else
ret = val;
return ret;
}
static int pmic_gpio_write(struct pmic_gpio_state *state,
struct pmic_gpio_pad *pad, unsigned int addr,
unsigned int val)
{
int ret;
ret = regmap_write(state->map, pad->base + addr, val);
if (ret < 0)
dev_err(state->dev, "write 0x%x failed\n", addr);
return ret;
}
static int pmic_gpio_get_groups_count(struct pinctrl_dev *pctldev)
{
/* Every PIN is a group */
return pctldev->desc->npins;
}
static const char *pmic_gpio_get_group_name(struct pinctrl_dev *pctldev,
unsigned pin)
{
return pctldev->desc->pins[pin].name;
}
static int pmic_gpio_get_group_pins(struct pinctrl_dev *pctldev, unsigned pin,
const unsigned **pins, unsigned *num_pins)
{
*pins = &pctldev->desc->pins[pin].number;
*num_pins = 1;
return 0;
}
static int pmic_gpio_parse_dt_config(struct device_node *np,
struct pinctrl_dev *pctldev,
unsigned long **configs,
unsigned int *nconfs)
{
struct pmic_gpio_bindings *par;
unsigned long cfg;
int ret, i;
u32 val;
for (i = 0; i < ARRAY_SIZE(pmic_gpio_bindings); i++) {
par = &pmic_gpio_bindings[i];
ret = of_property_read_u32(np, par->property, &val);
/* property not found */
if (ret == -EINVAL)
continue;
/* use zero as default value */
if (ret)
val = 0;
dev_dbg(pctldev->dev, "found %s with value %u\n",
par->property, val);
cfg = pinconf_to_config_packed(par->param, val);
ret = pinctrl_utils_add_config(pctldev, configs, nconfs, cfg);
if (ret)
return ret;
}
return 0;
}
static int pmic_gpio_dt_subnode_to_map(struct pinctrl_dev *pctldev,
struct device_node *np,
struct pinctrl_map **map,
unsigned *reserv, unsigned *nmaps,
enum pinctrl_map_type type)
{
unsigned long *configs = NULL;
unsigned nconfs = 0;
struct property *prop;
const char *group;
int ret;
ret = pmic_gpio_parse_dt_config(np, pctldev, &configs, &nconfs);
if (ret < 0)
return ret;
if (!nconfs)
return 0;
ret = of_property_count_strings(np, "pins");
if (ret < 0)
goto exit;
ret = pinctrl_utils_reserve_map(pctldev, map, reserv, nmaps, ret);
if (ret < 0)
goto exit;
of_property_for_each_string(np, "pins", prop, group) {
ret = pinctrl_utils_add_map_configs(pctldev, map,
reserv, nmaps, group,
configs, nconfs, type);
if (ret < 0)
break;
}
exit:
kfree(configs);
return ret;
}
static int pmic_gpio_dt_node_to_map(struct pinctrl_dev *pctldev,
struct device_node *np_config,
struct pinctrl_map **map, unsigned *nmaps)
{
enum pinctrl_map_type type;
struct device_node *np;
unsigned reserv;
int ret;
ret = 0;
*map = NULL;
*nmaps = 0;
reserv = 0;
type = PIN_MAP_TYPE_CONFIGS_GROUP;
for_each_child_of_node(np_config, np) {
ret = pinconf_generic_dt_subnode_to_map(pctldev, np, map,
&reserv, nmaps, type);
if (ret)
break;
ret = pmic_gpio_dt_subnode_to_map(pctldev, np, map, &reserv,
nmaps, type);
if (ret)
break;
}
if (ret < 0)
pinctrl_utils_dt_free_map(pctldev, *map, *nmaps);
return ret;
}
static const struct pinctrl_ops pmic_gpio_pinctrl_ops = {
.get_groups_count = pmic_gpio_get_groups_count,
.get_group_name = pmic_gpio_get_group_name,
.get_group_pins = pmic_gpio_get_group_pins,
.dt_node_to_map = pmic_gpio_dt_node_to_map,
.dt_free_map = pinctrl_utils_dt_free_map,
};
static int pmic_gpio_get_functions_count(struct pinctrl_dev *pctldev)
{
return ARRAY_SIZE(pmic_gpio_functions);
}
static const char *pmic_gpio_get_function_name(struct pinctrl_dev *pctldev,
unsigned function)
{
return pmic_gpio_functions[function];
}
static int pmic_gpio_get_function_groups(struct pinctrl_dev *pctldev,
unsigned function,
const char *const **groups,
unsigned *const num_qgroups)
{
*groups = pmic_gpio_groups;
*num_qgroups = pctldev->desc->npins;
return 0;
}
static int pmic_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned function,
unsigned pin)
{
struct pmic_gpio_state *state = pinctrl_dev_get_drvdata(pctldev);
struct pmic_gpio_pad *pad;
unsigned int val;
int ret;
pad = pctldev->desc->pins[pin].drv_data;
pad->function = function;
val = 0;
if (pad->output_enabled) {
if (pad->input_enabled)
val = 2;
else
val = 1;
}
val |= pad->function << PMIC_GPIO_REG_MODE_FUNCTION_SHIFT;
val |= pad->out_value & PMIC_GPIO_REG_MODE_VALUE_SHIFT;
ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_MODE_CTL, val);
if (ret < 0)
return ret;
val = pad->is_enabled << PMIC_GPIO_REG_MASTER_EN_SHIFT;
return pmic_gpio_write(state, pad, PMIC_GPIO_REG_EN_CTL, val);
}
static const struct pinmux_ops pmic_gpio_pinmux_ops = {
.get_functions_count = pmic_gpio_get_functions_count,
.get_function_name = pmic_gpio_get_function_name,
.get_function_groups = pmic_gpio_get_function_groups,
.set_mux = pmic_gpio_set_mux,
};
static int pmic_gpio_config_get(struct pinctrl_dev *pctldev,
unsigned int pin, unsigned long *config)
{
unsigned param = pinconf_to_config_param(*config);
struct pmic_gpio_pad *pad;
unsigned arg;
pad = pctldev->desc->pins[pin].drv_data;
switch (param) {
case PIN_CONFIG_DRIVE_PUSH_PULL:
arg = pad->buffer_type == PMIC_GPIO_OUT_BUF_CMOS;
break;
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
arg = pad->buffer_type == PMIC_GPIO_OUT_BUF_OPEN_DRAIN_NMOS;
break;
case PIN_CONFIG_DRIVE_OPEN_SOURCE:
arg = pad->buffer_type == PMIC_GPIO_OUT_BUF_OPEN_DRAIN_PMOS;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
arg = pad->pullup == PMIC_GPIO_PULL_DOWN;
break;
case PIN_CONFIG_BIAS_DISABLE:
arg = pad->pullup = PMIC_GPIO_PULL_DISABLE;
break;
case PIN_CONFIG_BIAS_PULL_UP:
arg = pad->pullup == PMIC_GPIO_PULL_UP_30;
break;
case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
arg = !pad->is_enabled;
break;
case PIN_CONFIG_POWER_SOURCE:
arg = pad->power_source;
break;
case PIN_CONFIG_INPUT_ENABLE:
arg = pad->input_enabled;
break;
case PIN_CONFIG_OUTPUT:
arg = pad->out_value;
break;
case PMIC_GPIO_CONF_PULL_UP:
arg = pad->pullup;
break;
case PMIC_GPIO_CONF_STRENGTH:
arg = pad->strength;
break;
default:
return -EINVAL;
}
*config = pinconf_to_config_packed(param, arg);
return 0;
}
static int pmic_gpio_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned nconfs)
{
struct pmic_gpio_state *state = pinctrl_dev_get_drvdata(pctldev);
struct pmic_gpio_pad *pad;
unsigned param, arg;
unsigned int val;
int i, ret;
pad = pctldev->desc->pins[pin].drv_data;
for (i = 0; i < nconfs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
switch (param) {
case PIN_CONFIG_DRIVE_PUSH_PULL:
pad->buffer_type = PMIC_GPIO_OUT_BUF_CMOS;
break;
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
if (!pad->have_buffer)
return -EINVAL;
pad->buffer_type = PMIC_GPIO_OUT_BUF_OPEN_DRAIN_NMOS;
break;
case PIN_CONFIG_DRIVE_OPEN_SOURCE:
if (!pad->have_buffer)
return -EINVAL;
pad->buffer_type = PMIC_GPIO_OUT_BUF_OPEN_DRAIN_PMOS;
break;
case PIN_CONFIG_BIAS_DISABLE:
pad->pullup = PMIC_GPIO_PULL_DISABLE;
break;
case PIN_CONFIG_BIAS_PULL_UP:
pad->pullup = PMIC_GPIO_PULL_UP_30;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
if (arg)
pad->pullup = PMIC_GPIO_PULL_DOWN;
else
pad->pullup = PMIC_GPIO_PULL_DISABLE;
break;
case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
pad->is_enabled = false;
break;
case PIN_CONFIG_POWER_SOURCE:
if (arg > pad->num_sources)
return -EINVAL;
pad->power_source = arg;
break;
case PIN_CONFIG_INPUT_ENABLE:
pad->input_enabled = arg ? true : false;
break;
case PIN_CONFIG_OUTPUT:
pad->output_enabled = true;
pad->out_value = arg;
break;
case PMIC_GPIO_CONF_PULL_UP:
if (arg > PMIC_GPIO_PULL_UP_1P5_30)
return -EINVAL;
pad->pullup = arg;
break;
case PMIC_GPIO_CONF_STRENGTH:
if (arg > PMIC_GPIO_STRENGTH_LOW)
return -EINVAL;
pad->strength = arg;
break;
default:
return -EINVAL;
}
}
val = pad->power_source << PMIC_GPIO_REG_VIN_SHIFT;
ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_DIG_VIN_CTL, val);
if (ret < 0)
return ret;
val = pad->pullup << PMIC_GPIO_REG_PULL_SHIFT;
ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_DIG_PULL_CTL, val);
if (ret < 0)
return ret;
val = pad->buffer_type << PMIC_GPIO_REG_OUT_TYPE_SHIFT;
val = pad->strength << PMIC_GPIO_REG_OUT_STRENGTH_SHIFT;
ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_DIG_OUT_CTL, val);
if (ret < 0)
return ret;
val = 0;
if (pad->output_enabled) {
if (pad->input_enabled)
val = 2;
else
val = 1;
}
val = val << PMIC_GPIO_REG_MODE_DIR_SHIFT;
val |= pad->function << PMIC_GPIO_REG_MODE_FUNCTION_SHIFT;
val |= pad->out_value & PMIC_GPIO_REG_MODE_VALUE_SHIFT;
return pmic_gpio_write(state, pad, PMIC_GPIO_REG_MODE_CTL, val);
}
static void pmic_gpio_config_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s, unsigned pin)
{
struct pmic_gpio_state *state = pinctrl_dev_get_drvdata(pctldev);
struct pmic_gpio_pad *pad;
int ret, val;
static const char *const biases[] = {
"pull-up 30uA", "pull-up 1.5uA", "pull-up 31.5uA",
"pull-up 1.5uA + 30uA boost", "pull-down 10uA", "no pull"
};
static const char *const buffer_types[] = {
"push-pull", "open-drain", "open-source"
};
static const char *const strengths[] = {
"no", "high", "medium", "low"
};
pad = pctldev->desc->pins[pin].drv_data;
seq_printf(s, " gpio%-2d:", pin + PMIC_GPIO_PHYSICAL_OFFSET);
val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_EN_CTL);
if (val < 0 || !(val >> PMIC_GPIO_REG_MASTER_EN_SHIFT)) {
seq_puts(s, " ---");
} else {
if (!pad->input_enabled) {
ret = pmic_gpio_read(state, pad, PMIC_MPP_REG_RT_STS);
if (!ret) {
ret &= PMIC_MPP_REG_RT_STS_VAL_MASK;
pad->out_value = ret;
}
}
seq_printf(s, " %-4s", pad->output_enabled ? "out" : "in");
seq_printf(s, " %-7s", pmic_gpio_functions[pad->function]);
seq_printf(s, " vin-%d", pad->power_source);
seq_printf(s, " %-27s", biases[pad->pullup]);
seq_printf(s, " %-10s", buffer_types[pad->buffer_type]);
seq_printf(s, " %-4s", pad->out_value ? "high" : "low");
seq_printf(s, " %-7s", strengths[pad->strength]);
}
}
static const struct pinconf_ops pmic_gpio_pinconf_ops = {
.pin_config_group_get = pmic_gpio_config_get,
.pin_config_group_set = pmic_gpio_config_set,
.pin_config_group_dbg_show = pmic_gpio_config_dbg_show,
};
static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned pin)
{
struct pmic_gpio_state *state = to_gpio_state(chip);
unsigned long config;
config = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 1);
return pmic_gpio_config_set(state->ctrl, pin, &config, 1);
}
static int pmic_gpio_direction_output(struct gpio_chip *chip,
unsigned pin, int val)
{
struct pmic_gpio_state *state = to_gpio_state(chip);
unsigned long config;
config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, val);
return pmic_gpio_config_set(state->ctrl, pin, &config, 1);
}
static int pmic_gpio_get(struct gpio_chip *chip, unsigned pin)
{
struct pmic_gpio_state *state = to_gpio_state(chip);
struct pmic_gpio_pad *pad;
int ret;
pad = state->ctrl->desc->pins[pin].drv_data;
if (!pad->is_enabled)
return -EINVAL;
if (pad->input_enabled) {
ret = pmic_gpio_read(state, pad, PMIC_MPP_REG_RT_STS);
if (ret < 0)
return ret;
pad->out_value = ret & PMIC_MPP_REG_RT_STS_VAL_MASK;
}
return pad->out_value;
}
static void pmic_gpio_set(struct gpio_chip *chip, unsigned pin, int value)
{
struct pmic_gpio_state *state = to_gpio_state(chip);
unsigned long config;
config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, value);
pmic_gpio_config_set(state->ctrl, pin, &config, 1);
}
static int pmic_gpio_request(struct gpio_chip *chip, unsigned base)
{
return pinctrl_request_gpio(chip->base + base);
}
static void pmic_gpio_free(struct gpio_chip *chip, unsigned base)
{
pinctrl_free_gpio(chip->base + base);
}
static int pmic_gpio_of_xlate(struct gpio_chip *chip,
const struct of_phandle_args *gpio_desc,
u32 *flags)
{
if (chip->of_gpio_n_cells < 2)
return -EINVAL;
if (flags)
*flags = gpio_desc->args[1];
return gpio_desc->args[0] - PMIC_GPIO_PHYSICAL_OFFSET;
}
static int pmic_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
{
struct pmic_gpio_state *state = to_gpio_state(chip);
struct pmic_gpio_pad *pad;
pad = state->ctrl->desc->pins[pin].drv_data;
return pad->irq;
}
static void pmic_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
{
struct pmic_gpio_state *state = to_gpio_state(chip);
unsigned i;
for (i = 0; i < chip->ngpio; i++) {
pmic_gpio_config_dbg_show(state->ctrl, s, i);
seq_puts(s, "\n");
}
}
static const struct gpio_chip pmic_gpio_gpio_template = {
.direction_input = pmic_gpio_direction_input,
.direction_output = pmic_gpio_direction_output,
.get = pmic_gpio_get,
.set = pmic_gpio_set,
.request = pmic_gpio_request,
.free = pmic_gpio_free,
.of_xlate = pmic_gpio_of_xlate,
.to_irq = pmic_gpio_to_irq,
.dbg_show = pmic_gpio_dbg_show,
};
static int pmic_gpio_populate(struct pmic_gpio_state *state,
struct pmic_gpio_pad *pad)
{
int type, subtype, val, dir;
type = pmic_gpio_read(state, pad, PMIC_GPIO_REG_TYPE);
if (type < 0)
return type;
if (type != PMIC_GPIO_TYPE) {
dev_err(state->dev, "incorrect block type 0x%x at 0x%x\n",
type, pad->base);
return -ENODEV;
}
subtype = pmic_gpio_read(state, pad, PMIC_GPIO_REG_SUBTYPE);
if (subtype < 0)
return subtype;
switch (subtype) {
case PMIC_GPIO_SUBTYPE_GPIO_4CH:
pad->have_buffer = true;
case PMIC_GPIO_SUBTYPE_GPIOC_4CH:
pad->num_sources = 4;
break;
case PMIC_GPIO_SUBTYPE_GPIO_8CH:
pad->have_buffer = true;
case PMIC_GPIO_SUBTYPE_GPIOC_8CH:
pad->num_sources = 8;
break;
default:
dev_err(state->dev, "unknown GPIO type 0x%x\n", subtype);
return -ENODEV;
}
val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_MODE_CTL);
if (val < 0)
return val;
pad->out_value = val & PMIC_GPIO_REG_MODE_VALUE_SHIFT;
dir = val >> PMIC_GPIO_REG_MODE_DIR_SHIFT;
dir &= PMIC_GPIO_REG_MODE_DIR_MASK;
switch (dir) {
case 0:
pad->input_enabled = true;
pad->output_enabled = false;
break;
case 1:
pad->input_enabled = false;
pad->output_enabled = true;
break;
case 2:
pad->input_enabled = true;
pad->output_enabled = true;
break;
default:
dev_err(state->dev, "unknown GPIO direction\n");
return -ENODEV;
}
pad->function = val >> PMIC_GPIO_REG_MODE_FUNCTION_SHIFT;
pad->function &= PMIC_GPIO_REG_MODE_FUNCTION_MASK;
val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_DIG_VIN_CTL);
if (val < 0)
return val;
pad->power_source = val >> PMIC_GPIO_REG_VIN_SHIFT;
pad->power_source &= PMIC_GPIO_REG_VIN_MASK;
val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_DIG_PULL_CTL);
if (val < 0)
return val;
pad->pullup = val >> PMIC_GPIO_REG_PULL_SHIFT;
pad->pullup &= PMIC_GPIO_REG_PULL_MASK;
val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_DIG_OUT_CTL);
if (val < 0)
return val;
pad->strength = val >> PMIC_GPIO_REG_OUT_STRENGTH_SHIFT;
pad->strength &= PMIC_GPIO_REG_OUT_STRENGTH_MASK;
pad->buffer_type = val >> PMIC_GPIO_REG_OUT_TYPE_SHIFT;
pad->buffer_type &= PMIC_GPIO_REG_OUT_TYPE_MASK;
/* Pin could be disabled with PIN_CONFIG_BIAS_HIGH_IMPEDANCE */
pad->is_enabled = true;
return 0;
}
static int pmic_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct pinctrl_pin_desc *pindesc;
struct pinctrl_desc *pctrldesc;
struct pmic_gpio_pad *pad, *pads;
struct pmic_gpio_state *state;
int ret, npins, i;
u32 res[2];
ret = of_property_read_u32_array(dev->of_node, "reg", res, 2);
if (ret < 0) {
dev_err(dev, "missing base address and/or range");
return ret;
}
npins = res[1] / PMIC_GPIO_ADDRESS_RANGE;
if (!npins)
return -EINVAL;
BUG_ON(npins > ARRAY_SIZE(pmic_gpio_groups));
state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
if (!state)
return -ENOMEM;
platform_set_drvdata(pdev, state);
state->dev = &pdev->dev;
state->map = dev_get_regmap(dev->parent, NULL);
pindesc = devm_kcalloc(dev, npins, sizeof(*pindesc), GFP_KERNEL);
if (!pindesc)
return -ENOMEM;
pads = devm_kcalloc(dev, npins, sizeof(*pads), GFP_KERNEL);
if (!pads)
return -ENOMEM;
pctrldesc = devm_kzalloc(dev, sizeof(*pctrldesc), GFP_KERNEL);
if (!pctrldesc)
return -ENOMEM;
pctrldesc->pctlops = &pmic_gpio_pinctrl_ops;
pctrldesc->pmxops = &pmic_gpio_pinmux_ops;
pctrldesc->confops = &pmic_gpio_pinconf_ops;
pctrldesc->owner = THIS_MODULE;
pctrldesc->name = dev_name(dev);
pctrldesc->pins = pindesc;
pctrldesc->npins = npins;
for (i = 0; i < npins; i++, pindesc++) {
pad = &pads[i];
pindesc->drv_data = pad;
pindesc->number = i;
pindesc->name = pmic_gpio_groups[i];
pad->irq = platform_get_irq(pdev, i);
if (pad->irq < 0)
return pad->irq;
pad->base = res[0] + i * PMIC_GPIO_ADDRESS_RANGE;
ret = pmic_gpio_populate(state, pad);
if (ret < 0)
return ret;
}
state->chip = pmic_gpio_gpio_template;
state->chip.dev = dev;
state->chip.base = -1;
state->chip.ngpio = npins;
state->chip.label = dev_name(dev);
state->chip.of_gpio_n_cells = 2;
state->chip.can_sleep = false;
state->ctrl = pinctrl_register(pctrldesc, dev, state);
if (!state->ctrl)
return -ENODEV;
ret = gpiochip_add(&state->chip);
if (ret) {
dev_err(state->dev, "can't add gpio chip\n");
goto err_chip;
}
ret = gpiochip_add_pin_range(&state->chip, dev_name(dev), 0, 0, npins);
if (ret) {
dev_err(dev, "failed to add pin range\n");
goto err_range;
}
return 0;
err_range:
gpiochip_remove(&state->chip);
err_chip:
pinctrl_unregister(state->ctrl);
return ret;
}
static int pmic_gpio_remove(struct platform_device *pdev)
{
struct pmic_gpio_state *state = platform_get_drvdata(pdev);
gpiochip_remove(&state->chip);
pinctrl_unregister(state->ctrl);
return 0;
}
static const struct of_device_id pmic_gpio_of_match[] = {
{ .compatible = "qcom,pm8941-gpio" }, /* 36 GPIO's */
{ .compatible = "qcom,pma8084-gpio" }, /* 22 GPIO's */
{ },
};
MODULE_DEVICE_TABLE(of, pmic_gpio_of_match);
static struct platform_driver pmic_gpio_driver = {
.driver = {
.name = "qcom-spmi-gpio",
.of_match_table = pmic_gpio_of_match,
},
.probe = pmic_gpio_probe,
.remove = pmic_gpio_remove,
};
module_platform_driver(pmic_gpio_driver);
MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>");
MODULE_DESCRIPTION("Qualcomm SPMI PMIC GPIO pin control driver");
MODULE_ALIAS("platform:qcom-spmi-gpio");
MODULE_LICENSE("GPL v2");

View file

@ -0,0 +1,949 @@
/*
* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <dt-bindings/pinctrl/qcom,pmic-mpp.h>
#include "../core.h"
#include "../pinctrl-utils.h"
#define PMIC_MPP_ADDRESS_RANGE 0x100
/*
* Pull Up Values - it indicates whether a pull-up should be
* applied for bidirectional mode only. The hardware ignores the
* configuration when operating in other modes.
*/
#define PMIC_MPP_PULL_UP_0P6KOHM 0
#define PMIC_MPP_PULL_UP_10KOHM 1
#define PMIC_MPP_PULL_UP_30KOHM 2
#define PMIC_MPP_PULL_UP_OPEN 3
/* type registers base address bases */
#define PMIC_MPP_REG_TYPE 0x4
#define PMIC_MPP_REG_SUBTYPE 0x5
/* mpp peripheral type and subtype values */
#define PMIC_MPP_TYPE 0x11
#define PMIC_MPP_SUBTYPE_4CH_NO_ANA_OUT 0x3
#define PMIC_MPP_SUBTYPE_ULT_4CH_NO_ANA_OUT 0x4
#define PMIC_MPP_SUBTYPE_4CH_NO_SINK 0x5
#define PMIC_MPP_SUBTYPE_ULT_4CH_NO_SINK 0x6
#define PMIC_MPP_SUBTYPE_4CH_FULL_FUNC 0x7
#define PMIC_MPP_SUBTYPE_8CH_FULL_FUNC 0xf
#define PMIC_MPP_REG_RT_STS 0x10
#define PMIC_MPP_REG_RT_STS_VAL_MASK 0x1
/* control register base address bases */
#define PMIC_MPP_REG_MODE_CTL 0x40
#define PMIC_MPP_REG_DIG_VIN_CTL 0x41
#define PMIC_MPP_REG_DIG_PULL_CTL 0x42
#define PMIC_MPP_REG_DIG_IN_CTL 0x43
#define PMIC_MPP_REG_EN_CTL 0x46
#define PMIC_MPP_REG_AIN_CTL 0x4a
/* PMIC_MPP_REG_MODE_CTL */
#define PMIC_MPP_REG_MODE_VALUE_MASK 0x1
#define PMIC_MPP_REG_MODE_FUNCTION_SHIFT 1
#define PMIC_MPP_REG_MODE_FUNCTION_MASK 0x7
#define PMIC_MPP_REG_MODE_DIR_SHIFT 4
#define PMIC_MPP_REG_MODE_DIR_MASK 0x7
/* PMIC_MPP_REG_DIG_VIN_CTL */
#define PMIC_MPP_REG_VIN_SHIFT 0
#define PMIC_MPP_REG_VIN_MASK 0x7
/* PMIC_MPP_REG_DIG_PULL_CTL */
#define PMIC_MPP_REG_PULL_SHIFT 0
#define PMIC_MPP_REG_PULL_MASK 0x7
/* PMIC_MPP_REG_EN_CTL */
#define PMIC_MPP_REG_MASTER_EN_SHIFT 7
/* PMIC_MPP_REG_AIN_CTL */
#define PMIC_MPP_REG_AIN_ROUTE_SHIFT 0
#define PMIC_MPP_REG_AIN_ROUTE_MASK 0x7
#define PMIC_MPP_PHYSICAL_OFFSET 1
/* Qualcomm specific pin configurations */
#define PMIC_MPP_CONF_AMUX_ROUTE (PIN_CONFIG_END + 1)
#define PMIC_MPP_CONF_ANALOG_MODE (PIN_CONFIG_END + 2)
/**
* struct pmic_mpp_pad - keep current MPP settings
* @base: Address base in SPMI device.
* @irq: IRQ number which this MPP generate.
* @is_enabled: Set to false when MPP should be put in high Z state.
* @out_value: Cached pin output value.
* @output_enabled: Set to true if MPP output logic is enabled.
* @input_enabled: Set to true if MPP input buffer logic is enabled.
* @analog_mode: Set to true when MPP should operate in Analog Input, Analog
* Output or Bidirectional Analog mode.
* @num_sources: Number of power-sources supported by this MPP.
* @power_source: Current power-source used.
* @amux_input: Set the source for analog input.
* @pullup: Pullup resistor value. Valid in Bidirectional mode only.
* @function: See pmic_mpp_functions[].
*/
struct pmic_mpp_pad {
u16 base;
int irq;
bool is_enabled;
bool out_value;
bool output_enabled;
bool input_enabled;
bool analog_mode;
unsigned int num_sources;
unsigned int power_source;
unsigned int amux_input;
unsigned int pullup;
unsigned int function;
};
struct pmic_mpp_state {
struct device *dev;
struct regmap *map;
struct pinctrl_dev *ctrl;
struct gpio_chip chip;
};
struct pmic_mpp_bindings {
const char *property;
unsigned param;
};
static struct pmic_mpp_bindings pmic_mpp_bindings[] = {
{"qcom,amux-route", PMIC_MPP_CONF_AMUX_ROUTE},
{"qcom,analog-mode", PMIC_MPP_CONF_ANALOG_MODE},
};
static const char *const pmic_mpp_groups[] = {
"mpp1", "mpp2", "mpp3", "mpp4", "mpp5", "mpp6", "mpp7", "mpp8",
};
static const char *const pmic_mpp_functions[] = {
PMIC_MPP_FUNC_NORMAL, PMIC_MPP_FUNC_PAIRED,
"reserved1", "reserved2",
PMIC_MPP_FUNC_DTEST1, PMIC_MPP_FUNC_DTEST2,
PMIC_MPP_FUNC_DTEST3, PMIC_MPP_FUNC_DTEST4,
};
static inline struct pmic_mpp_state *to_mpp_state(struct gpio_chip *chip)
{
return container_of(chip, struct pmic_mpp_state, chip);
};
static int pmic_mpp_read(struct pmic_mpp_state *state,
struct pmic_mpp_pad *pad, unsigned int addr)
{
unsigned int val;
int ret;
ret = regmap_read(state->map, pad->base + addr, &val);
if (ret < 0)
dev_err(state->dev, "read 0x%x failed\n", addr);
else
ret = val;
return ret;
}
static int pmic_mpp_write(struct pmic_mpp_state *state,
struct pmic_mpp_pad *pad, unsigned int addr,
unsigned int val)
{
int ret;
ret = regmap_write(state->map, pad->base + addr, val);
if (ret < 0)
dev_err(state->dev, "write 0x%x failed\n", addr);
return ret;
}
static int pmic_mpp_get_groups_count(struct pinctrl_dev *pctldev)
{
/* Every PIN is a group */
return pctldev->desc->npins;
}
static const char *pmic_mpp_get_group_name(struct pinctrl_dev *pctldev,
unsigned pin)
{
return pctldev->desc->pins[pin].name;
}
static int pmic_mpp_get_group_pins(struct pinctrl_dev *pctldev,
unsigned pin,
const unsigned **pins, unsigned *num_pins)
{
*pins = &pctldev->desc->pins[pin].number;
*num_pins = 1;
return 0;
}
static int pmic_mpp_parse_dt_config(struct device_node *np,
struct pinctrl_dev *pctldev,
unsigned long **configs,
unsigned int *nconfs)
{
struct pmic_mpp_bindings *par;
unsigned long cfg;
int ret, i;
u32 val;
for (i = 0; i < ARRAY_SIZE(pmic_mpp_bindings); i++) {
par = &pmic_mpp_bindings[i];
ret = of_property_read_u32(np, par->property, &val);
/* property not found */
if (ret == -EINVAL)
continue;
/* use zero as default value, when no value is specified */
if (ret)
val = 0;
dev_dbg(pctldev->dev, "found %s with value %u\n",
par->property, val);
cfg = pinconf_to_config_packed(par->param, val);
ret = pinctrl_utils_add_config(pctldev, configs, nconfs, cfg);
if (ret)
return ret;
}
return 0;
}
static int pmic_mpp_dt_subnode_to_map(struct pinctrl_dev *pctldev,
struct device_node *np,
struct pinctrl_map **map,
unsigned *reserv, unsigned *nmaps,
enum pinctrl_map_type type)
{
unsigned long *configs = NULL;
unsigned nconfs = 0;
struct property *prop;
const char *group;
int ret;
ret = pmic_mpp_parse_dt_config(np, pctldev, &configs, &nconfs);
if (ret < 0)
return ret;
if (!nconfs)
return 0;
ret = of_property_count_strings(np, "pins");
if (ret < 0)
goto exit;
ret = pinctrl_utils_reserve_map(pctldev, map, reserv, nmaps, ret);
if (ret < 0)
goto exit;
of_property_for_each_string(np, "pins", prop, group) {
ret = pinctrl_utils_add_map_configs(pctldev, map,
reserv, nmaps, group,
configs, nconfs, type);
if (ret < 0)
break;
}
exit:
kfree(configs);
return ret;
}
static int pmic_mpp_dt_node_to_map(struct pinctrl_dev *pctldev,
struct device_node *np_config,
struct pinctrl_map **map, unsigned *nmaps)
{
struct device_node *np;
enum pinctrl_map_type type;
unsigned reserv;
int ret;
ret = 0;
*map = NULL;
*nmaps = 0;
reserv = 0;
type = PIN_MAP_TYPE_CONFIGS_GROUP;
for_each_child_of_node(np_config, np) {
ret = pinconf_generic_dt_subnode_to_map(pctldev, np, map,
&reserv, nmaps, type);
if (ret)
break;
ret = pmic_mpp_dt_subnode_to_map(pctldev, np, map, &reserv,
nmaps, type);
if (ret)
break;
}
if (ret < 0)
pinctrl_utils_dt_free_map(pctldev, *map, *nmaps);
return ret;
}
static const struct pinctrl_ops pmic_mpp_pinctrl_ops = {
.get_groups_count = pmic_mpp_get_groups_count,
.get_group_name = pmic_mpp_get_group_name,
.get_group_pins = pmic_mpp_get_group_pins,
.dt_node_to_map = pmic_mpp_dt_node_to_map,
.dt_free_map = pinctrl_utils_dt_free_map,
};
static int pmic_mpp_get_functions_count(struct pinctrl_dev *pctldev)
{
return ARRAY_SIZE(pmic_mpp_functions);
}
static const char *pmic_mpp_get_function_name(struct pinctrl_dev *pctldev,
unsigned function)
{
return pmic_mpp_functions[function];
}
static int pmic_mpp_get_function_groups(struct pinctrl_dev *pctldev,
unsigned function,
const char *const **groups,
unsigned *const num_qgroups)
{
*groups = pmic_mpp_groups;
*num_qgroups = pctldev->desc->npins;
return 0;
}
static int pmic_mpp_set_mux(struct pinctrl_dev *pctldev, unsigned function,
unsigned pin)
{
struct pmic_mpp_state *state = pinctrl_dev_get_drvdata(pctldev);
struct pmic_mpp_pad *pad;
unsigned int val;
int ret;
pad = pctldev->desc->pins[pin].drv_data;
pad->function = function;
if (!pad->analog_mode) {
val = 0; /* just digital input */
if (pad->output_enabled) {
if (pad->input_enabled)
val = 2; /* digital input and output */
else
val = 1; /* just digital output */
}
} else {
val = 4; /* just analog input */
if (pad->output_enabled) {
if (pad->input_enabled)
val = 3; /* analog input and output */
else
val = 5; /* just analog output */
}
}
val |= pad->function << PMIC_MPP_REG_MODE_FUNCTION_SHIFT;
val |= pad->out_value & PMIC_MPP_REG_MODE_VALUE_MASK;
ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_MODE_CTL, val);
if (ret < 0)
return ret;
val = pad->is_enabled << PMIC_MPP_REG_MASTER_EN_SHIFT;
return pmic_mpp_write(state, pad, PMIC_MPP_REG_EN_CTL, val);
}
static const struct pinmux_ops pmic_mpp_pinmux_ops = {
.get_functions_count = pmic_mpp_get_functions_count,
.get_function_name = pmic_mpp_get_function_name,
.get_function_groups = pmic_mpp_get_function_groups,
.set_mux = pmic_mpp_set_mux,
};
static int pmic_mpp_config_get(struct pinctrl_dev *pctldev,
unsigned int pin, unsigned long *config)
{
unsigned param = pinconf_to_config_param(*config);
struct pmic_mpp_pad *pad;
unsigned arg = 0;
pad = pctldev->desc->pins[pin].drv_data;
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
arg = pad->pullup == PMIC_MPP_PULL_UP_OPEN;
break;
case PIN_CONFIG_BIAS_PULL_UP:
switch (pad->pullup) {
case PMIC_MPP_PULL_UP_OPEN:
arg = 0;
break;
case PMIC_MPP_PULL_UP_0P6KOHM:
arg = 600;
break;
case PMIC_MPP_PULL_UP_10KOHM:
arg = 10000;
break;
case PMIC_MPP_PULL_UP_30KOHM:
arg = 30000;
break;
default:
return -EINVAL;
}
break;
case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
arg = !pad->is_enabled;
break;
case PIN_CONFIG_POWER_SOURCE:
arg = pad->power_source;
break;
case PIN_CONFIG_INPUT_ENABLE:
arg = pad->input_enabled;
break;
case PIN_CONFIG_OUTPUT:
arg = pad->out_value;
break;
case PMIC_MPP_CONF_AMUX_ROUTE:
arg = pad->amux_input;
break;
case PMIC_MPP_CONF_ANALOG_MODE:
arg = pad->analog_mode;
break;
default:
return -EINVAL;
}
/* Convert register value to pinconf value */
*config = pinconf_to_config_packed(param, arg);
return 0;
}
static int pmic_mpp_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned nconfs)
{
struct pmic_mpp_state *state = pinctrl_dev_get_drvdata(pctldev);
struct pmic_mpp_pad *pad;
unsigned param, arg;
unsigned int val;
int i, ret;
pad = pctldev->desc->pins[pin].drv_data;
for (i = 0; i < nconfs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
pad->pullup = PMIC_MPP_PULL_UP_OPEN;
break;
case PIN_CONFIG_BIAS_PULL_UP:
switch (arg) {
case 600:
pad->pullup = PMIC_MPP_PULL_UP_0P6KOHM;
break;
case 10000:
pad->pullup = PMIC_MPP_PULL_UP_10KOHM;
break;
case 30000:
pad->pullup = PMIC_MPP_PULL_UP_30KOHM;
break;
default:
return -EINVAL;
}
break;
case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
pad->is_enabled = false;
break;
case PIN_CONFIG_POWER_SOURCE:
if (arg >= pad->num_sources)
return -EINVAL;
pad->power_source = arg;
break;
case PIN_CONFIG_INPUT_ENABLE:
pad->input_enabled = arg ? true : false;
break;
case PIN_CONFIG_OUTPUT:
pad->output_enabled = true;
pad->out_value = arg;
break;
case PMIC_MPP_CONF_AMUX_ROUTE:
if (arg >= PMIC_MPP_AMUX_ROUTE_ABUS4)
return -EINVAL;
pad->amux_input = arg;
break;
case PMIC_MPP_CONF_ANALOG_MODE:
pad->analog_mode = true;
break;
default:
return -EINVAL;
}
}
val = pad->power_source << PMIC_MPP_REG_VIN_SHIFT;
ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_DIG_VIN_CTL, val);
if (ret < 0)
return ret;
val = pad->pullup << PMIC_MPP_REG_PULL_SHIFT;
ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_DIG_PULL_CTL, val);
if (ret < 0)
return ret;
val = pad->amux_input & PMIC_MPP_REG_AIN_ROUTE_MASK;
ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_AIN_CTL, val);
if (ret < 0)
return ret;
if (!pad->analog_mode) {
val = 0; /* just digital input */
if (pad->output_enabled) {
if (pad->input_enabled)
val = 2; /* digital input and output */
else
val = 1; /* just digital output */
}
} else {
val = 4; /* just analog input */
if (pad->output_enabled) {
if (pad->input_enabled)
val = 3; /* analog input and output */
else
val = 5; /* just analog output */
}
}
val = val << PMIC_MPP_REG_MODE_DIR_SHIFT;
val |= pad->function << PMIC_MPP_REG_MODE_FUNCTION_SHIFT;
val |= pad->out_value & PMIC_MPP_REG_MODE_VALUE_MASK;
return pmic_mpp_write(state, pad, PMIC_MPP_REG_MODE_CTL, val);
}
static void pmic_mpp_config_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s, unsigned pin)
{
struct pmic_mpp_state *state = pinctrl_dev_get_drvdata(pctldev);
struct pmic_mpp_pad *pad;
int ret, val;
static const char *const biases[] = {
"0.6kOhm", "10kOhm", "30kOhm", "Disabled"
};
pad = pctldev->desc->pins[pin].drv_data;
seq_printf(s, " mpp%-2d:", pin + PMIC_MPP_PHYSICAL_OFFSET);
val = pmic_mpp_read(state, pad, PMIC_MPP_REG_EN_CTL);
if (val < 0 || !(val >> PMIC_MPP_REG_MASTER_EN_SHIFT)) {
seq_puts(s, " ---");
} else {
if (pad->input_enabled) {
ret = pmic_mpp_read(state, pad, PMIC_MPP_REG_RT_STS);
if (!ret) {
ret &= PMIC_MPP_REG_RT_STS_VAL_MASK;
pad->out_value = ret;
}
}
seq_printf(s, " %-4s", pad->output_enabled ? "out" : "in");
seq_printf(s, " %-4s", pad->analog_mode ? "ana" : "dig");
seq_printf(s, " %-7s", pmic_mpp_functions[pad->function]);
seq_printf(s, " vin-%d", pad->power_source);
seq_printf(s, " %-8s", biases[pad->pullup]);
seq_printf(s, " %-4s", pad->out_value ? "high" : "low");
}
}
static const struct pinconf_ops pmic_mpp_pinconf_ops = {
.pin_config_group_get = pmic_mpp_config_get,
.pin_config_group_set = pmic_mpp_config_set,
.pin_config_group_dbg_show = pmic_mpp_config_dbg_show,
};
static int pmic_mpp_direction_input(struct gpio_chip *chip, unsigned pin)
{
struct pmic_mpp_state *state = to_mpp_state(chip);
unsigned long config;
config = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 1);
return pmic_mpp_config_set(state->ctrl, pin, &config, 1);
}
static int pmic_mpp_direction_output(struct gpio_chip *chip,
unsigned pin, int val)
{
struct pmic_mpp_state *state = to_mpp_state(chip);
unsigned long config;
config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, val);
return pmic_mpp_config_set(state->ctrl, pin, &config, 1);
}
static int pmic_mpp_get(struct gpio_chip *chip, unsigned pin)
{
struct pmic_mpp_state *state = to_mpp_state(chip);
struct pmic_mpp_pad *pad;
int ret;
pad = state->ctrl->desc->pins[pin].drv_data;
if (pad->input_enabled) {
ret = pmic_mpp_read(state, pad, PMIC_MPP_REG_RT_STS);
if (ret < 0)
return ret;
pad->out_value = ret & PMIC_MPP_REG_RT_STS_VAL_MASK;
}
return pad->out_value;
}
static void pmic_mpp_set(struct gpio_chip *chip, unsigned pin, int value)
{
struct pmic_mpp_state *state = to_mpp_state(chip);
unsigned long config;
config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, value);
pmic_mpp_config_set(state->ctrl, pin, &config, 1);
}
static int pmic_mpp_request(struct gpio_chip *chip, unsigned base)
{
return pinctrl_request_gpio(chip->base + base);
}
static void pmic_mpp_free(struct gpio_chip *chip, unsigned base)
{
pinctrl_free_gpio(chip->base + base);
}
static int pmic_mpp_of_xlate(struct gpio_chip *chip,
const struct of_phandle_args *gpio_desc,
u32 *flags)
{
if (chip->of_gpio_n_cells < 2)
return -EINVAL;
if (flags)
*flags = gpio_desc->args[1];
return gpio_desc->args[0] - PMIC_MPP_PHYSICAL_OFFSET;
}
static int pmic_mpp_to_irq(struct gpio_chip *chip, unsigned pin)
{
struct pmic_mpp_state *state = to_mpp_state(chip);
struct pmic_mpp_pad *pad;
pad = state->ctrl->desc->pins[pin].drv_data;
return pad->irq;
}
static void pmic_mpp_dbg_show(struct seq_file *s, struct gpio_chip *chip)
{
struct pmic_mpp_state *state = to_mpp_state(chip);
unsigned i;
for (i = 0; i < chip->ngpio; i++) {
pmic_mpp_config_dbg_show(state->ctrl, s, i);
seq_puts(s, "\n");
}
}
static const struct gpio_chip pmic_mpp_gpio_template = {
.direction_input = pmic_mpp_direction_input,
.direction_output = pmic_mpp_direction_output,
.get = pmic_mpp_get,
.set = pmic_mpp_set,
.request = pmic_mpp_request,
.free = pmic_mpp_free,
.of_xlate = pmic_mpp_of_xlate,
.to_irq = pmic_mpp_to_irq,
.dbg_show = pmic_mpp_dbg_show,
};
static int pmic_mpp_populate(struct pmic_mpp_state *state,
struct pmic_mpp_pad *pad)
{
int type, subtype, val, dir;
type = pmic_mpp_read(state, pad, PMIC_MPP_REG_TYPE);
if (type < 0)
return type;
if (type != PMIC_MPP_TYPE) {
dev_err(state->dev, "incorrect block type 0x%x at 0x%x\n",
type, pad->base);
return -ENODEV;
}
subtype = pmic_mpp_read(state, pad, PMIC_MPP_REG_SUBTYPE);
if (subtype < 0)
return subtype;
switch (subtype) {
case PMIC_MPP_SUBTYPE_4CH_NO_ANA_OUT:
case PMIC_MPP_SUBTYPE_ULT_4CH_NO_ANA_OUT:
case PMIC_MPP_SUBTYPE_4CH_NO_SINK:
case PMIC_MPP_SUBTYPE_ULT_4CH_NO_SINK:
case PMIC_MPP_SUBTYPE_4CH_FULL_FUNC:
pad->num_sources = 4;
break;
case PMIC_MPP_SUBTYPE_8CH_FULL_FUNC:
pad->num_sources = 8;
break;
default:
dev_err(state->dev, "unknown MPP type 0x%x at 0x%x\n",
subtype, pad->base);
return -ENODEV;
}
val = pmic_mpp_read(state, pad, PMIC_MPP_REG_MODE_CTL);
if (val < 0)
return val;
pad->out_value = val & PMIC_MPP_REG_MODE_VALUE_MASK;
dir = val >> PMIC_MPP_REG_MODE_DIR_SHIFT;
dir &= PMIC_MPP_REG_MODE_DIR_MASK;
switch (dir) {
case 0:
pad->input_enabled = true;
pad->output_enabled = false;
pad->analog_mode = false;
break;
case 1:
pad->input_enabled = false;
pad->output_enabled = true;
pad->analog_mode = false;
break;
case 2:
pad->input_enabled = true;
pad->output_enabled = true;
pad->analog_mode = false;
break;
case 3:
pad->input_enabled = true;
pad->output_enabled = true;
pad->analog_mode = true;
break;
case 4:
pad->input_enabled = true;
pad->output_enabled = false;
pad->analog_mode = true;
break;
case 5:
pad->input_enabled = false;
pad->output_enabled = true;
pad->analog_mode = true;
break;
default:
dev_err(state->dev, "unknown MPP direction\n");
return -ENODEV;
}
pad->function = val >> PMIC_MPP_REG_MODE_FUNCTION_SHIFT;
pad->function &= PMIC_MPP_REG_MODE_FUNCTION_MASK;
val = pmic_mpp_read(state, pad, PMIC_MPP_REG_DIG_VIN_CTL);
if (val < 0)
return val;
pad->power_source = val >> PMIC_MPP_REG_VIN_SHIFT;
pad->power_source &= PMIC_MPP_REG_VIN_MASK;
val = pmic_mpp_read(state, pad, PMIC_MPP_REG_DIG_PULL_CTL);
if (val < 0)
return val;
pad->pullup = val >> PMIC_MPP_REG_PULL_SHIFT;
pad->pullup &= PMIC_MPP_REG_PULL_MASK;
val = pmic_mpp_read(state, pad, PMIC_MPP_REG_AIN_CTL);
if (val < 0)
return val;
pad->amux_input = val >> PMIC_MPP_REG_AIN_ROUTE_SHIFT;
pad->amux_input &= PMIC_MPP_REG_AIN_ROUTE_MASK;
/* Pin could be disabled with PIN_CONFIG_BIAS_HIGH_IMPEDANCE */
pad->is_enabled = true;
return 0;
}
static int pmic_mpp_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct pinctrl_pin_desc *pindesc;
struct pinctrl_desc *pctrldesc;
struct pmic_mpp_pad *pad, *pads;
struct pmic_mpp_state *state;
int ret, npins, i;
u32 res[2];
ret = of_property_read_u32_array(dev->of_node, "reg", res, 2);
if (ret < 0) {
dev_err(dev, "missing base address and/or range");
return ret;
}
npins = res[1] / PMIC_MPP_ADDRESS_RANGE;
if (!npins)
return -EINVAL;
BUG_ON(npins > ARRAY_SIZE(pmic_mpp_groups));
state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
if (!state)
return -ENOMEM;
platform_set_drvdata(pdev, state);
state->dev = &pdev->dev;
state->map = dev_get_regmap(dev->parent, NULL);
pindesc = devm_kcalloc(dev, npins, sizeof(*pindesc), GFP_KERNEL);
if (!pindesc)
return -ENOMEM;
pads = devm_kcalloc(dev, npins, sizeof(*pads), GFP_KERNEL);
if (!pads)
return -ENOMEM;
pctrldesc = devm_kzalloc(dev, sizeof(*pctrldesc), GFP_KERNEL);
if (!pctrldesc)
return -ENOMEM;
pctrldesc->pctlops = &pmic_mpp_pinctrl_ops;
pctrldesc->pmxops = &pmic_mpp_pinmux_ops;
pctrldesc->confops = &pmic_mpp_pinconf_ops;
pctrldesc->owner = THIS_MODULE;
pctrldesc->name = dev_name(dev);
pctrldesc->pins = pindesc;
pctrldesc->npins = npins;
for (i = 0; i < npins; i++, pindesc++) {
pad = &pads[i];
pindesc->drv_data = pad;
pindesc->number = i;
pindesc->name = pmic_mpp_groups[i];
pad->irq = platform_get_irq(pdev, i);
if (pad->irq < 0)
return pad->irq;
pad->base = res[0] + i * PMIC_MPP_ADDRESS_RANGE;
ret = pmic_mpp_populate(state, pad);
if (ret < 0)
return ret;
}
state->chip = pmic_mpp_gpio_template;
state->chip.dev = dev;
state->chip.base = -1;
state->chip.ngpio = npins;
state->chip.label = dev_name(dev);
state->chip.of_gpio_n_cells = 2;
state->chip.can_sleep = false;
state->ctrl = pinctrl_register(pctrldesc, dev, state);
if (!state->ctrl)
return -ENODEV;
ret = gpiochip_add(&state->chip);
if (ret) {
dev_err(state->dev, "can't add gpio chip\n");
goto err_chip;
}
ret = gpiochip_add_pin_range(&state->chip, dev_name(dev), 0, 0, npins);
if (ret) {
dev_err(dev, "failed to add pin range\n");
goto err_range;
}
return 0;
err_range:
gpiochip_remove(&state->chip);
err_chip:
pinctrl_unregister(state->ctrl);
return ret;
}
static int pmic_mpp_remove(struct platform_device *pdev)
{
struct pmic_mpp_state *state = platform_get_drvdata(pdev);
gpiochip_remove(&state->chip);
pinctrl_unregister(state->ctrl);
return 0;
}
static const struct of_device_id pmic_mpp_of_match[] = {
{ .compatible = "qcom,pm8841-mpp" }, /* 4 MPP's */
{ .compatible = "qcom,pm8941-mpp" }, /* 8 MPP's */
{ .compatible = "qcom,pma8084-mpp" }, /* 8 MPP's */
{ },
};
MODULE_DEVICE_TABLE(of, pmic_mpp_of_match);
static struct platform_driver pmic_mpp_driver = {
.driver = {
.name = "qcom-spmi-mpp",
.of_match_table = pmic_mpp_of_match,
},
.probe = pmic_mpp_probe,
.remove = pmic_mpp_remove,
};
module_platform_driver(pmic_mpp_driver);
MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>");
MODULE_DESCRIPTION("Qualcomm SPMI PMIC MPP pin control driver");
MODULE_ALIAS("platform:qcom-spmi-mpp");
MODULE_LICENSE("GPL v2");

View file

@ -46,22 +46,16 @@ static inline struct exynos_irq_chip *to_exynos_irq_chip(struct irq_chip *chip)
return container_of(chip, struct exynos_irq_chip, chip);
}
static struct samsung_pin_bank_type bank_type_off = {
static const struct samsung_pin_bank_type bank_type_off = {
.fld_width = { 4, 1, 2, 2, 2, 2, },
.reg_offset = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, },
};
static struct samsung_pin_bank_type bank_type_alive = {
static const struct samsung_pin_bank_type bank_type_alive = {
.fld_width = { 4, 1, 2, 2, },
.reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
};
/* list of external wakeup controllers supported */
static const struct of_device_id exynos_wkup_irq_ids[] = {
{ .compatible = "samsung,exynos4210-wakeup-eint", },
{ }
};
static void exynos_irq_mask(struct irq_data *irqd)
{
struct irq_chip *chip = irq_data_get_irq_chip(irqd);
@ -171,7 +165,7 @@ static int exynos_irq_request_resources(struct irq_data *irqd)
struct irq_chip *chip = irq_data_get_irq_chip(irqd);
struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pin_bank_type *bank_type = bank->type;
const struct samsung_pin_bank_type *bank_type = bank->type;
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq;
unsigned long reg_con = our_chip->eint_con + bank->eint_offset;
@ -210,7 +204,7 @@ static void exynos_irq_release_resources(struct irq_data *irqd)
struct irq_chip *chip = irq_data_get_irq_chip(irqd);
struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pin_bank_type *bank_type = bank->type;
const struct samsung_pin_bank_type *bank_type = bank->type;
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq;
unsigned long reg_con = our_chip->eint_con + bank->eint_offset;
@ -254,31 +248,30 @@ static struct exynos_irq_chip exynos_gpio_irq_chip = {
.eint_pend = EXYNOS_GPIO_EPEND_OFFSET,
};
static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq,
static int exynos_eint_irq_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct samsung_pin_bank *b = h->host_data;
irq_set_chip_data(virq, b);
irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip.chip,
irq_set_chip_and_handler(virq, &b->irq_chip->chip,
handle_level_irq);
set_irq_flags(virq, IRQF_VALID);
return 0;
}
/*
* irq domain callbacks for external gpio interrupt controller.
* irq domain callbacks for external gpio and wakeup interrupt controllers.
*/
static const struct irq_domain_ops exynos_gpio_irqd_ops = {
.map = exynos_gpio_irq_map,
static const struct irq_domain_ops exynos_eint_irqd_ops = {
.map = exynos_eint_irq_map,
.xlate = irq_domain_xlate_twocell,
};
static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
{
struct samsung_pinctrl_drv_data *d = data;
struct samsung_pin_ctrl *ctrl = d->ctrl;
struct samsung_pin_bank *bank = ctrl->pin_banks;
struct samsung_pin_bank *bank = d->pin_banks;
unsigned int svc, group, pin, virq;
svc = readl(d->virt_base + EXYNOS_SVC_OFFSET);
@ -325,12 +318,12 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
return -ENXIO;
}
bank = d->ctrl->pin_banks;
for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
bank = d->pin_banks;
for (i = 0; i < d->nr_banks; ++i, ++bank) {
if (bank->eint_type != EINT_TYPE_GPIO)
continue;
bank->irq_domain = irq_domain_add_linear(bank->of_node,
bank->nr_pins, &exynos_gpio_irqd_ops, bank);
bank->nr_pins, &exynos_eint_irqd_ops, bank);
if (!bank->irq_domain) {
dev_err(dev, "gpio irq domain add failed\n");
ret = -ENXIO;
@ -344,6 +337,8 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
ret = -ENOMEM;
goto err_domains;
}
bank->irq_chip = &exynos_gpio_irq_chip;
}
return 0;
@ -383,9 +378,9 @@ static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on)
/*
* irq_chip for wakeup interrupts
*/
static struct exynos_irq_chip exynos_wkup_irq_chip = {
static struct exynos_irq_chip exynos4210_wkup_irq_chip __initdata = {
.chip = {
.name = "exynos_wkup_irq_chip",
.name = "exynos4210_wkup_irq_chip",
.irq_unmask = exynos_irq_unmask,
.irq_mask = exynos_irq_mask,
.irq_ack = exynos_irq_ack,
@ -399,6 +394,31 @@ static struct exynos_irq_chip exynos_wkup_irq_chip = {
.eint_pend = EXYNOS_WKUP_EPEND_OFFSET,
};
static struct exynos_irq_chip exynos7_wkup_irq_chip __initdata = {
.chip = {
.name = "exynos7_wkup_irq_chip",
.irq_unmask = exynos_irq_unmask,
.irq_mask = exynos_irq_mask,
.irq_ack = exynos_irq_ack,
.irq_set_type = exynos_irq_set_type,
.irq_set_wake = exynos_wkup_irq_set_wake,
.irq_request_resources = exynos_irq_request_resources,
.irq_release_resources = exynos_irq_release_resources,
},
.eint_con = EXYNOS7_WKUP_ECON_OFFSET,
.eint_mask = EXYNOS7_WKUP_EMASK_OFFSET,
.eint_pend = EXYNOS7_WKUP_EPEND_OFFSET,
};
/* list of external wakeup controllers supported */
static const struct of_device_id exynos_wkup_irq_ids[] = {
{ .compatible = "samsung,exynos4210-wakeup-eint",
.data = &exynos4210_wkup_irq_chip },
{ .compatible = "samsung,exynos7-wakeup-eint",
.data = &exynos7_wkup_irq_chip },
{ }
};
/* interrupt handler for wakeup interrupts 0..15 */
static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
{
@ -445,9 +465,9 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
for (i = 0; i < eintd->nr_banks; ++i) {
struct samsung_pin_bank *b = eintd->banks[i];
pend = readl(d->virt_base + EXYNOS_WKUP_EPEND_OFFSET
pend = readl(d->virt_base + b->irq_chip->eint_pend
+ b->eint_offset);
mask = readl(d->virt_base + EXYNOS_WKUP_EMASK_OFFSET
mask = readl(d->virt_base + b->irq_chip->eint_mask
+ b->eint_offset);
exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
}
@ -455,24 +475,6 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
chained_irq_exit(chip, desc);
}
static int exynos_wkup_irq_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
irq_set_chip_and_handler(virq, &exynos_wkup_irq_chip.chip,
handle_level_irq);
irq_set_chip_data(virq, h->host_data);
set_irq_flags(virq, IRQF_VALID);
return 0;
}
/*
* irq domain callbacks for external wakeup interrupt controller.
*/
static const struct irq_domain_ops exynos_wkup_irqd_ops = {
.map = exynos_wkup_irq_map,
.xlate = irq_domain_xlate_twocell,
};
/*
* exynos_eint_wkup_init() - setup handling of external wakeup interrupts.
* @d: driver data of samsung pinctrl driver.
@ -485,12 +487,18 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
struct samsung_pin_bank *bank;
struct exynos_weint_data *weint_data;
struct exynos_muxed_weint_data *muxed_data;
struct exynos_irq_chip *irq_chip;
unsigned int muxed_banks = 0;
unsigned int i;
int idx, irq;
for_each_child_of_node(dev->of_node, np) {
if (of_match_node(exynos_wkup_irq_ids, np)) {
const struct of_device_id *match;
match = of_match_node(exynos_wkup_irq_ids, np);
if (match) {
irq_chip = kmemdup(match->data,
sizeof(*irq_chip), GFP_KERNEL);
wkup_np = np;
break;
}
@ -498,18 +506,20 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
if (!wkup_np)
return -ENODEV;
bank = d->ctrl->pin_banks;
for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
bank = d->pin_banks;
for (i = 0; i < d->nr_banks; ++i, ++bank) {
if (bank->eint_type != EINT_TYPE_WKUP)
continue;
bank->irq_domain = irq_domain_add_linear(bank->of_node,
bank->nr_pins, &exynos_wkup_irqd_ops, bank);
bank->nr_pins, &exynos_eint_irqd_ops, bank);
if (!bank->irq_domain) {
dev_err(dev, "wkup irq domain add failed\n");
return -ENXIO;
}
bank->irq_chip = irq_chip;
if (!of_find_property(bank->of_node, "interrupts", NULL)) {
bank->eint_type = EINT_TYPE_WKUP_MUX;
++muxed_banks;
@ -556,9 +566,9 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
irq_set_chained_handler(irq, exynos_irq_demux_eint16_31);
irq_set_handler_data(irq, muxed_data);
bank = d->ctrl->pin_banks;
bank = d->pin_banks;
idx = 0;
for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
for (i = 0; i < d->nr_banks; ++i, ++bank) {
if (bank->eint_type != EINT_TYPE_WKUP_MUX)
continue;
@ -590,11 +600,10 @@ static void exynos_pinctrl_suspend_bank(
static void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata)
{
struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
struct samsung_pin_bank *bank = ctrl->pin_banks;
struct samsung_pin_bank *bank = drvdata->pin_banks;
int i;
for (i = 0; i < ctrl->nr_banks; ++i, ++bank)
for (i = 0; i < drvdata->nr_banks; ++i, ++bank)
if (bank->eint_type == EINT_TYPE_GPIO)
exynos_pinctrl_suspend_bank(drvdata, bank);
}
@ -626,17 +635,16 @@ static void exynos_pinctrl_resume_bank(
static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
{
struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
struct samsung_pin_bank *bank = ctrl->pin_banks;
struct samsung_pin_bank *bank = drvdata->pin_banks;
int i;
for (i = 0; i < ctrl->nr_banks; ++i, ++bank)
for (i = 0; i < drvdata->nr_banks; ++i, ++bank)
if (bank->eint_type == EINT_TYPE_GPIO)
exynos_pinctrl_resume_bank(drvdata, bank);
}
/* pin banks of s5pv210 pin-controller */
static struct samsung_pin_bank s5pv210_pin_bank[] = {
static const struct samsung_pin_bank_data s5pv210_pin_bank[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08),
@ -673,7 +681,7 @@ static struct samsung_pin_bank s5pv210_pin_bank[] = {
EXYNOS_PIN_BANK_EINTW(8, 0xc60, "gph3", 0x0c),
};
struct samsung_pin_ctrl s5pv210_pin_ctrl[] = {
const struct samsung_pin_ctrl s5pv210_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 data */
.pin_banks = s5pv210_pin_bank,
@ -682,12 +690,11 @@ struct samsung_pin_ctrl s5pv210_pin_ctrl[] = {
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.label = "s5pv210-gpio-ctrl0",
},
};
/* pin banks of exynos3250 pin-controller 0 */
static struct samsung_pin_bank exynos3250_pin_banks0[] = {
static const struct samsung_pin_bank_data exynos3250_pin_banks0[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08),
@ -698,7 +705,7 @@ static struct samsung_pin_bank exynos3250_pin_banks0[] = {
};
/* pin banks of exynos3250 pin-controller 1 */
static struct samsung_pin_bank exynos3250_pin_banks1[] = {
static const struct samsung_pin_bank_data exynos3250_pin_banks1[] __initconst = {
EXYNOS_PIN_BANK_EINTN(8, 0x120, "gpe0"),
EXYNOS_PIN_BANK_EINTN(8, 0x140, "gpe1"),
EXYNOS_PIN_BANK_EINTN(3, 0x180, "gpe2"),
@ -721,7 +728,7 @@ static struct samsung_pin_bank exynos3250_pin_banks1[] = {
* Samsung pinctrl driver data for Exynos3250 SoC. Exynos3250 SoC includes
* two gpio/pin-mux/pinconfig controllers.
*/
struct samsung_pin_ctrl exynos3250_pin_ctrl[] = {
const struct samsung_pin_ctrl exynos3250_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 data */
.pin_banks = exynos3250_pin_banks0,
@ -729,7 +736,6 @@ struct samsung_pin_ctrl exynos3250_pin_ctrl[] = {
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.label = "exynos3250-gpio-ctrl0",
}, {
/* pin-controller instance 1 data */
.pin_banks = exynos3250_pin_banks1,
@ -738,12 +744,11 @@ struct samsung_pin_ctrl exynos3250_pin_ctrl[] = {
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.label = "exynos3250-gpio-ctrl1",
},
};
/* pin banks of exynos4210 pin-controller 0 */
static struct samsung_pin_bank exynos4210_pin_banks0[] = {
static const struct samsung_pin_bank_data exynos4210_pin_banks0[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08),
@ -763,7 +768,7 @@ static struct samsung_pin_bank exynos4210_pin_banks0[] = {
};
/* pin banks of exynos4210 pin-controller 1 */
static struct samsung_pin_bank exynos4210_pin_banks1[] = {
static const struct samsung_pin_bank_data exynos4210_pin_banks1[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpj0", 0x00),
EXYNOS_PIN_BANK_EINTG(5, 0x020, "gpj1", 0x04),
EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08),
@ -787,7 +792,7 @@ static struct samsung_pin_bank exynos4210_pin_banks1[] = {
};
/* pin banks of exynos4210 pin-controller 2 */
static struct samsung_pin_bank exynos4210_pin_banks2[] = {
static const struct samsung_pin_bank_data exynos4210_pin_banks2[] __initconst = {
EXYNOS_PIN_BANK_EINTN(7, 0x000, "gpz"),
};
@ -795,7 +800,7 @@ static struct samsung_pin_bank exynos4210_pin_banks2[] = {
* Samsung pinctrl driver data for Exynos4210 SoC. Exynos4210 SoC includes
* three gpio/pin-mux/pinconfig controllers.
*/
struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
const struct samsung_pin_ctrl exynos4210_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 data */
.pin_banks = exynos4210_pin_banks0,
@ -803,7 +808,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.label = "exynos4210-gpio-ctrl0",
}, {
/* pin-controller instance 1 data */
.pin_banks = exynos4210_pin_banks1,
@ -812,17 +816,15 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.label = "exynos4210-gpio-ctrl1",
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos4210_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos4210_pin_banks2),
.label = "exynos4210-gpio-ctrl2",
},
};
/* pin banks of exynos4x12 pin-controller 0 */
static struct samsung_pin_bank exynos4x12_pin_banks0[] = {
static const struct samsung_pin_bank_data exynos4x12_pin_banks0[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08),
@ -839,7 +841,7 @@ static struct samsung_pin_bank exynos4x12_pin_banks0[] = {
};
/* pin banks of exynos4x12 pin-controller 1 */
static struct samsung_pin_bank exynos4x12_pin_banks1[] = {
static const struct samsung_pin_bank_data exynos4x12_pin_banks1[] __initconst = {
EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08),
EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c),
EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10),
@ -866,12 +868,12 @@ static struct samsung_pin_bank exynos4x12_pin_banks1[] = {
};
/* pin banks of exynos4x12 pin-controller 2 */
static struct samsung_pin_bank exynos4x12_pin_banks2[] = {
static const struct samsung_pin_bank_data exynos4x12_pin_banks2[] __initconst = {
EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00),
};
/* pin banks of exynos4x12 pin-controller 3 */
static struct samsung_pin_bank exynos4x12_pin_banks3[] = {
static const struct samsung_pin_bank_data exynos4x12_pin_banks3[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00),
EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpv2", 0x08),
@ -883,7 +885,7 @@ static struct samsung_pin_bank exynos4x12_pin_banks3[] = {
* Samsung pinctrl driver data for Exynos4x12 SoC. Exynos4x12 SoC includes
* four gpio/pin-mux/pinconfig controllers.
*/
struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
const struct samsung_pin_ctrl exynos4x12_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 data */
.pin_banks = exynos4x12_pin_banks0,
@ -891,7 +893,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.label = "exynos4x12-gpio-ctrl0",
}, {
/* pin-controller instance 1 data */
.pin_banks = exynos4x12_pin_banks1,
@ -900,7 +901,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.label = "exynos4x12-gpio-ctrl1",
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos4x12_pin_banks2,
@ -908,7 +908,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.label = "exynos4x12-gpio-ctrl2",
}, {
/* pin-controller instance 3 data */
.pin_banks = exynos4x12_pin_banks3,
@ -916,12 +915,86 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.label = "exynos4x12-gpio-ctrl3",
},
};
/* pin banks of exynos4415 pin-controller 0 */
static const struct samsung_pin_bank_data exynos4415_pin_banks0[] = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08),
EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c),
EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10),
EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpd0", 0x14),
EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpd1", 0x18),
EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpf0", 0x30),
EXYNOS_PIN_BANK_EINTG(8, 0x1A0, "gpf1", 0x34),
EXYNOS_PIN_BANK_EINTG(1, 0x1C0, "gpf2", 0x38),
};
/* pin banks of exynos4415 pin-controller 1 */
static const struct samsung_pin_bank_data exynos4415_pin_banks1[] = {
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpk0", 0x08),
EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c),
EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10),
EXYNOS_PIN_BANK_EINTG(7, 0x0A0, "gpk3", 0x14),
EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpl0", 0x18),
EXYNOS_PIN_BANK_EINTN(6, 0x120, "mp00"),
EXYNOS_PIN_BANK_EINTN(4, 0x140, "mp01"),
EXYNOS_PIN_BANK_EINTN(6, 0x160, "mp02"),
EXYNOS_PIN_BANK_EINTN(8, 0x180, "mp03"),
EXYNOS_PIN_BANK_EINTN(8, 0x1A0, "mp04"),
EXYNOS_PIN_BANK_EINTN(8, 0x1C0, "mp05"),
EXYNOS_PIN_BANK_EINTN(8, 0x1E0, "mp06"),
EXYNOS_PIN_BANK_EINTG(8, 0x260, "gpm0", 0x24),
EXYNOS_PIN_BANK_EINTG(7, 0x280, "gpm1", 0x28),
EXYNOS_PIN_BANK_EINTG(5, 0x2A0, "gpm2", 0x2c),
EXYNOS_PIN_BANK_EINTG(8, 0x2C0, "gpm3", 0x30),
EXYNOS_PIN_BANK_EINTG(8, 0x2E0, "gpm4", 0x34),
EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08),
EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c),
};
/* pin banks of exynos4415 pin-controller 2 */
static const struct samsung_pin_bank_data exynos4415_pin_banks2[] = {
EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00),
EXYNOS_PIN_BANK_EINTN(2, 0x000, "etc1"),
};
/*
* Samsung pinctrl driver data for Exynos4415 SoC. Exynos4415 SoC includes
* three gpio/pin-mux/pinconfig controllers.
*/
const struct samsung_pin_ctrl exynos4415_pin_ctrl[] = {
{
/* pin-controller instance 0 data */
.pin_banks = exynos4415_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos4415_pin_banks0),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 1 data */
.pin_banks = exynos4415_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos4415_pin_banks1),
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos4415_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos4415_pin_banks2),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
},
};
/* pin banks of exynos5250 pin-controller 0 */
static struct samsung_pin_bank exynos5250_pin_banks0[] = {
static const struct samsung_pin_bank_data exynos5250_pin_banks0[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08),
@ -950,7 +1023,7 @@ static struct samsung_pin_bank exynos5250_pin_banks0[] = {
};
/* pin banks of exynos5250 pin-controller 1 */
static struct samsung_pin_bank exynos5250_pin_banks1[] = {
static const struct samsung_pin_bank_data exynos5250_pin_banks1[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpe0", 0x00),
EXYNOS_PIN_BANK_EINTG(2, 0x020, "gpe1", 0x04),
EXYNOS_PIN_BANK_EINTG(4, 0x040, "gpf0", 0x08),
@ -963,7 +1036,7 @@ static struct samsung_pin_bank exynos5250_pin_banks1[] = {
};
/* pin banks of exynos5250 pin-controller 2 */
static struct samsung_pin_bank exynos5250_pin_banks2[] = {
static const struct samsung_pin_bank_data exynos5250_pin_banks2[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00),
EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpv2", 0x08),
@ -972,7 +1045,7 @@ static struct samsung_pin_bank exynos5250_pin_banks2[] = {
};
/* pin banks of exynos5250 pin-controller 3 */
static struct samsung_pin_bank exynos5250_pin_banks3[] = {
static const struct samsung_pin_bank_data exynos5250_pin_banks3[] __initconst = {
EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00),
};
@ -980,7 +1053,7 @@ static struct samsung_pin_bank exynos5250_pin_banks3[] = {
* Samsung pinctrl driver data for Exynos5250 SoC. Exynos5250 SoC includes
* four gpio/pin-mux/pinconfig controllers.
*/
struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
const struct samsung_pin_ctrl exynos5250_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 data */
.pin_banks = exynos5250_pin_banks0,
@ -989,7 +1062,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.label = "exynos5250-gpio-ctrl0",
}, {
/* pin-controller instance 1 data */
.pin_banks = exynos5250_pin_banks1,
@ -997,7 +1069,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.label = "exynos5250-gpio-ctrl1",
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos5250_pin_banks2,
@ -1005,7 +1076,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.label = "exynos5250-gpio-ctrl2",
}, {
/* pin-controller instance 3 data */
.pin_banks = exynos5250_pin_banks3,
@ -1013,12 +1083,11 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.label = "exynos5250-gpio-ctrl3",
},
};
/* pin banks of exynos5260 pin-controller 0 */
static struct samsung_pin_bank exynos5260_pin_banks0[] = {
static const struct samsung_pin_bank_data exynos5260_pin_banks0[] __initconst = {
EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTG(7, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08),
@ -1043,7 +1112,7 @@ static struct samsung_pin_bank exynos5260_pin_banks0[] = {
};
/* pin banks of exynos5260 pin-controller 1 */
static struct samsung_pin_bank exynos5260_pin_banks1[] = {
static const struct samsung_pin_bank_data exynos5260_pin_banks1[] __initconst = {
EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpc0", 0x00),
EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpc1", 0x04),
EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpc2", 0x08),
@ -1052,7 +1121,7 @@ static struct samsung_pin_bank exynos5260_pin_banks1[] = {
};
/* pin banks of exynos5260 pin-controller 2 */
static struct samsung_pin_bank exynos5260_pin_banks2[] = {
static const struct samsung_pin_bank_data exynos5260_pin_banks2[] __initconst = {
EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz0", 0x00),
EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04),
};
@ -1061,31 +1130,28 @@ static struct samsung_pin_bank exynos5260_pin_banks2[] = {
* Samsung pinctrl driver data for Exynos5260 SoC. Exynos5260 SoC includes
* three gpio/pin-mux/pinconfig controllers.
*/
struct samsung_pin_ctrl exynos5260_pin_ctrl[] = {
const struct samsung_pin_ctrl exynos5260_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 data */
.pin_banks = exynos5260_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos5260_pin_banks0),
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.label = "exynos5260-gpio-ctrl0",
}, {
/* pin-controller instance 1 data */
.pin_banks = exynos5260_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos5260_pin_banks1),
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5260-gpio-ctrl1",
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos5260_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos5260_pin_banks2),
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5260-gpio-ctrl2",
},
};
/* pin banks of exynos5420 pin-controller 0 */
static struct samsung_pin_bank exynos5420_pin_banks0[] = {
static const struct samsung_pin_bank_data exynos5420_pin_banks0[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpy7", 0x00),
EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
@ -1094,7 +1160,7 @@ static struct samsung_pin_bank exynos5420_pin_banks0[] = {
};
/* pin banks of exynos5420 pin-controller 1 */
static struct samsung_pin_bank exynos5420_pin_banks1[] = {
static const struct samsung_pin_bank_data exynos5420_pin_banks1[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpc0", 0x00),
EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpc1", 0x04),
EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpc2", 0x08),
@ -1111,7 +1177,7 @@ static struct samsung_pin_bank exynos5420_pin_banks1[] = {
};
/* pin banks of exynos5420 pin-controller 2 */
static struct samsung_pin_bank exynos5420_pin_banks2[] = {
static const struct samsung_pin_bank_data exynos5420_pin_banks2[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpe0", 0x00),
EXYNOS_PIN_BANK_EINTG(2, 0x020, "gpe1", 0x04),
EXYNOS_PIN_BANK_EINTG(6, 0x040, "gpf0", 0x08),
@ -1123,7 +1189,7 @@ static struct samsung_pin_bank exynos5420_pin_banks2[] = {
};
/* pin banks of exynos5420 pin-controller 3 */
static struct samsung_pin_bank exynos5420_pin_banks3[] = {
static const struct samsung_pin_bank_data exynos5420_pin_banks3[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08),
@ -1136,7 +1202,7 @@ static struct samsung_pin_bank exynos5420_pin_banks3[] = {
};
/* pin banks of exynos5420 pin-controller 4 */
static struct samsung_pin_bank exynos5420_pin_banks4[] = {
static const struct samsung_pin_bank_data exynos5420_pin_banks4[] __initconst = {
EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00),
};
@ -1144,37 +1210,137 @@ static struct samsung_pin_bank exynos5420_pin_banks4[] = {
* Samsung pinctrl driver data for Exynos5420 SoC. Exynos5420 SoC includes
* four gpio/pin-mux/pinconfig controllers.
*/
struct samsung_pin_ctrl exynos5420_pin_ctrl[] = {
const struct samsung_pin_ctrl exynos5420_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 data */
.pin_banks = exynos5420_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks0),
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.label = "exynos5420-gpio-ctrl0",
}, {
/* pin-controller instance 1 data */
.pin_banks = exynos5420_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks1),
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5420-gpio-ctrl1",
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos5420_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks2),
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5420-gpio-ctrl2",
}, {
/* pin-controller instance 3 data */
.pin_banks = exynos5420_pin_banks3,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks3),
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5420-gpio-ctrl3",
}, {
/* pin-controller instance 4 data */
.pin_banks = exynos5420_pin_banks4,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks4),
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5420-gpio-ctrl4",
},
};
/* pin banks of exynos7 pin-controller - ALIVE */
static const struct samsung_pin_bank_data exynos7_pin_banks0[] __initconst = {
EXYNOS_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00),
EXYNOS_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08),
EXYNOS_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c),
};
/* pin banks of exynos7 pin-controller - BUS0 */
static const struct samsung_pin_bank_data exynos7_pin_banks1[] __initconst = {
EXYNOS_PIN_BANK_EINTG(5, 0x000, "gpb0", 0x00),
EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpc0", 0x04),
EXYNOS_PIN_BANK_EINTG(2, 0x040, "gpc1", 0x08),
EXYNOS_PIN_BANK_EINTG(6, 0x060, "gpc2", 0x0c),
EXYNOS_PIN_BANK_EINTG(8, 0x080, "gpc3", 0x10),
EXYNOS_PIN_BANK_EINTG(4, 0x0a0, "gpd0", 0x14),
EXYNOS_PIN_BANK_EINTG(6, 0x0c0, "gpd1", 0x18),
EXYNOS_PIN_BANK_EINTG(8, 0x0e0, "gpd2", 0x1c),
EXYNOS_PIN_BANK_EINTG(5, 0x100, "gpd4", 0x20),
EXYNOS_PIN_BANK_EINTG(4, 0x120, "gpd5", 0x24),
EXYNOS_PIN_BANK_EINTG(6, 0x140, "gpd6", 0x28),
EXYNOS_PIN_BANK_EINTG(3, 0x160, "gpd7", 0x2c),
EXYNOS_PIN_BANK_EINTG(2, 0x180, "gpd8", 0x30),
EXYNOS_PIN_BANK_EINTG(2, 0x1a0, "gpg0", 0x34),
EXYNOS_PIN_BANK_EINTG(4, 0x1c0, "gpg3", 0x38),
};
/* pin banks of exynos7 pin-controller - NFC */
static const struct samsung_pin_bank_data exynos7_pin_banks2[] __initconst = {
EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj0", 0x00),
};
/* pin banks of exynos7 pin-controller - TOUCH */
static const struct samsung_pin_bank_data exynos7_pin_banks3[] __initconst = {
EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj1", 0x00),
};
/* pin banks of exynos7 pin-controller - FF */
static const struct samsung_pin_bank_data exynos7_pin_banks4[] __initconst = {
EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpg4", 0x00),
};
/* pin banks of exynos7 pin-controller - ESE */
static const struct samsung_pin_bank_data exynos7_pin_banks5[] __initconst = {
EXYNOS_PIN_BANK_EINTG(5, 0x000, "gpv7", 0x00),
};
/* pin banks of exynos7 pin-controller - FSYS0 */
static const struct samsung_pin_bank_data exynos7_pin_banks6[] __initconst = {
EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpr4", 0x00),
};
/* pin banks of exynos7 pin-controller - FSYS1 */
static const struct samsung_pin_bank_data exynos7_pin_banks7[] __initconst = {
EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpr0", 0x00),
EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpr1", 0x04),
EXYNOS_PIN_BANK_EINTG(5, 0x040, "gpr2", 0x08),
EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpr3", 0x0c),
};
const struct samsung_pin_ctrl exynos7_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 Alive data */
.pin_banks = exynos7_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos7_pin_banks0),
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
}, {
/* pin-controller instance 1 BUS0 data */
.pin_banks = exynos7_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos7_pin_banks1),
.eint_gpio_init = exynos_eint_gpio_init,
}, {
/* pin-controller instance 2 NFC data */
.pin_banks = exynos7_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos7_pin_banks2),
.eint_gpio_init = exynos_eint_gpio_init,
}, {
/* pin-controller instance 3 TOUCH data */
.pin_banks = exynos7_pin_banks3,
.nr_banks = ARRAY_SIZE(exynos7_pin_banks3),
.eint_gpio_init = exynos_eint_gpio_init,
}, {
/* pin-controller instance 4 FF data */
.pin_banks = exynos7_pin_banks4,
.nr_banks = ARRAY_SIZE(exynos7_pin_banks4),
.eint_gpio_init = exynos_eint_gpio_init,
}, {
/* pin-controller instance 5 ESE data */
.pin_banks = exynos7_pin_banks5,
.nr_banks = ARRAY_SIZE(exynos7_pin_banks5),
.eint_gpio_init = exynos_eint_gpio_init,
}, {
/* pin-controller instance 6 FSYS0 data */
.pin_banks = exynos7_pin_banks6,
.nr_banks = ARRAY_SIZE(exynos7_pin_banks6),
.eint_gpio_init = exynos_eint_gpio_init,
}, {
/* pin-controller instance 7 FSYS1 data */
.pin_banks = exynos7_pin_banks7,
.nr_banks = ARRAY_SIZE(exynos7_pin_banks7),
.eint_gpio_init = exynos_eint_gpio_init,
},
};

View file

@ -25,6 +25,9 @@
#define EXYNOS_WKUP_ECON_OFFSET 0xE00
#define EXYNOS_WKUP_EMASK_OFFSET 0xF00
#define EXYNOS_WKUP_EPEND_OFFSET 0xF40
#define EXYNOS7_WKUP_ECON_OFFSET 0x700
#define EXYNOS7_WKUP_EMASK_OFFSET 0x900
#define EXYNOS7_WKUP_EPEND_OFFSET 0xA00
#define EXYNOS_SVC_OFFSET 0xB08
#define EXYNOS_EINT_FUNC 0xF

View file

@ -44,12 +44,12 @@
#define EINT_EDGE_BOTH 6
#define EINT_MASK 0xf
static struct samsung_pin_bank_type bank_type_1bit = {
static const struct samsung_pin_bank_type bank_type_1bit = {
.fld_width = { 1, 1, },
.reg_offset = { 0x00, 0x04, },
};
static struct samsung_pin_bank_type bank_type_2bit = {
static const struct samsung_pin_bank_type bank_type_2bit = {
.fld_width = { 2, 1, 2, },
.reg_offset = { 0x00, 0x04, 0x08, },
};
@ -143,7 +143,7 @@ static void s3c24xx_eint_set_handler(unsigned int irq, unsigned int type)
static void s3c24xx_eint_set_function(struct samsung_pinctrl_drv_data *d,
struct samsung_pin_bank *bank, int pin)
{
struct samsung_pin_bank_type *bank_type = bank->type;
const struct samsung_pin_bank_type *bank_type = bank->type;
unsigned long flags;
void __iomem *reg;
u8 shift;
@ -518,8 +518,8 @@ static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d)
irq_set_handler_data(irq, eint_data);
}
bank = d->ctrl->pin_banks;
for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
bank = d->pin_banks;
for (i = 0; i < d->nr_banks; ++i, ++bank) {
struct s3c24xx_eint_domain_data *ddata;
unsigned int mask;
unsigned int irq;
@ -561,7 +561,7 @@ static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d)
return 0;
}
static struct samsung_pin_bank s3c2412_pin_banks[] = {
static const struct samsung_pin_bank_data s3c2412_pin_banks[] __initconst = {
PIN_BANK_A(23, 0x000, "gpa"),
PIN_BANK_2BIT(11, 0x010, "gpb"),
PIN_BANK_2BIT(16, 0x020, "gpc"),
@ -573,16 +573,15 @@ static struct samsung_pin_bank s3c2412_pin_banks[] = {
PIN_BANK_2BIT(13, 0x080, "gpj"),
};
struct samsung_pin_ctrl s3c2412_pin_ctrl[] = {
const struct samsung_pin_ctrl s3c2412_pin_ctrl[] __initconst = {
{
.pin_banks = s3c2412_pin_banks,
.nr_banks = ARRAY_SIZE(s3c2412_pin_banks),
.eint_wkup_init = s3c24xx_eint_init,
.label = "S3C2412-GPIO",
},
};
static struct samsung_pin_bank s3c2416_pin_banks[] = {
static const struct samsung_pin_bank_data s3c2416_pin_banks[] __initconst = {
PIN_BANK_A(27, 0x000, "gpa"),
PIN_BANK_2BIT(11, 0x010, "gpb"),
PIN_BANK_2BIT(16, 0x020, "gpc"),
@ -596,16 +595,15 @@ static struct samsung_pin_bank s3c2416_pin_banks[] = {
PIN_BANK_2BIT(2, 0x100, "gpm"),
};
struct samsung_pin_ctrl s3c2416_pin_ctrl[] = {
const struct samsung_pin_ctrl s3c2416_pin_ctrl[] __initconst = {
{
.pin_banks = s3c2416_pin_banks,
.nr_banks = ARRAY_SIZE(s3c2416_pin_banks),
.eint_wkup_init = s3c24xx_eint_init,
.label = "S3C2416-GPIO",
},
};
static struct samsung_pin_bank s3c2440_pin_banks[] = {
static const struct samsung_pin_bank_data s3c2440_pin_banks[] __initconst = {
PIN_BANK_A(25, 0x000, "gpa"),
PIN_BANK_2BIT(11, 0x010, "gpb"),
PIN_BANK_2BIT(16, 0x020, "gpc"),
@ -617,16 +615,15 @@ static struct samsung_pin_bank s3c2440_pin_banks[] = {
PIN_BANK_2BIT(13, 0x0d0, "gpj"),
};
struct samsung_pin_ctrl s3c2440_pin_ctrl[] = {
const struct samsung_pin_ctrl s3c2440_pin_ctrl[] __initconst = {
{
.pin_banks = s3c2440_pin_banks,
.nr_banks = ARRAY_SIZE(s3c2440_pin_banks),
.eint_wkup_init = s3c24xx_eint_init,
.label = "S3C2440-GPIO",
},
};
static struct samsung_pin_bank s3c2450_pin_banks[] = {
static const struct samsung_pin_bank_data s3c2450_pin_banks[] __initconst = {
PIN_BANK_A(28, 0x000, "gpa"),
PIN_BANK_2BIT(11, 0x010, "gpb"),
PIN_BANK_2BIT(16, 0x020, "gpc"),
@ -641,11 +638,10 @@ static struct samsung_pin_bank s3c2450_pin_banks[] = {
PIN_BANK_2BIT(2, 0x100, "gpm"),
};
struct samsung_pin_ctrl s3c2450_pin_ctrl[] = {
const struct samsung_pin_ctrl s3c2450_pin_ctrl[] __initconst = {
{
.pin_banks = s3c2450_pin_banks,
.nr_banks = ARRAY_SIZE(s3c2450_pin_banks),
.eint_wkup_init = s3c24xx_eint_init,
.label = "S3C2450-GPIO",
},
};

View file

@ -68,32 +68,32 @@
#define EINT_CON_MASK 0xF
#define EINT_CON_LEN 4
static struct samsung_pin_bank_type bank_type_4bit_off = {
static const struct samsung_pin_bank_type bank_type_4bit_off = {
.fld_width = { 4, 1, 2, 0, 2, 2, },
.reg_offset = { 0x00, 0x04, 0x08, 0, 0x0c, 0x10, },
};
static struct samsung_pin_bank_type bank_type_4bit_alive = {
static const struct samsung_pin_bank_type bank_type_4bit_alive = {
.fld_width = { 4, 1, 2, },
.reg_offset = { 0x00, 0x04, 0x08, },
};
static struct samsung_pin_bank_type bank_type_4bit2_off = {
static const struct samsung_pin_bank_type bank_type_4bit2_off = {
.fld_width = { 4, 1, 2, 0, 2, 2, },
.reg_offset = { 0x00, 0x08, 0x0c, 0, 0x10, 0x14, },
};
static struct samsung_pin_bank_type bank_type_4bit2_alive = {
static const struct samsung_pin_bank_type bank_type_4bit2_alive = {
.fld_width = { 4, 1, 2, },
.reg_offset = { 0x00, 0x08, 0x0c, },
};
static struct samsung_pin_bank_type bank_type_2bit_off = {
static const struct samsung_pin_bank_type bank_type_2bit_off = {
.fld_width = { 2, 1, 2, 0, 2, 2, },
.reg_offset = { 0x00, 0x04, 0x08, 0, 0x0c, 0x10, },
};
static struct samsung_pin_bank_type bank_type_2bit_alive = {
static const struct samsung_pin_bank_type bank_type_2bit_alive = {
.fld_width = { 2, 1, 2, },
.reg_offset = { 0x00, 0x04, 0x08, },
};
@ -272,7 +272,7 @@ static void s3c64xx_irq_set_handler(unsigned int irq, unsigned int type)
static void s3c64xx_irq_set_function(struct samsung_pinctrl_drv_data *d,
struct samsung_pin_bank *bank, int pin)
{
struct samsung_pin_bank_type *bank_type = bank->type;
const struct samsung_pin_bank_type *bank_type = bank->type;
unsigned long flags;
void __iomem *reg;
u8 shift;
@ -468,8 +468,8 @@ static int s3c64xx_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
}
nr_domains = 0;
bank = d->ctrl->pin_banks;
for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
bank = d->pin_banks;
for (i = 0; i < d->nr_banks; ++i, ++bank) {
unsigned int nr_eints;
unsigned int mask;
@ -497,9 +497,9 @@ static int s3c64xx_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
}
data->drvdata = d;
bank = d->ctrl->pin_banks;
bank = d->pin_banks;
nr_domains = 0;
for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
for (i = 0; i < d->nr_banks; ++i, ++bank) {
if (bank->eint_type != EINT_TYPE_GPIO)
continue;
@ -735,8 +735,8 @@ static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
irq_set_handler_data(irq, data);
}
bank = d->ctrl->pin_banks;
for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
bank = d->pin_banks;
for (i = 0; i < d->nr_banks; ++i, ++bank) {
struct s3c64xx_eint0_domain_data *ddata;
unsigned int nr_eints;
unsigned int mask;
@ -780,7 +780,7 @@ static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
}
/* pin banks of s3c64xx pin-controller 0 */
static struct samsung_pin_bank s3c64xx_pin_banks0[] = {
static const struct samsung_pin_bank_data s3c64xx_pin_banks0[] __initconst = {
PIN_BANK_4BIT_EINTG(8, 0x000, "gpa", 0),
PIN_BANK_4BIT_EINTG(7, 0x020, "gpb", 8),
PIN_BANK_4BIT_EINTG(8, 0x040, "gpc", 16),
@ -804,13 +804,12 @@ static struct samsung_pin_bank s3c64xx_pin_banks0[] = {
* Samsung pinctrl driver data for S3C64xx SoC. S3C64xx SoC includes
* one gpio/pin-mux/pinconfig controller.
*/
struct samsung_pin_ctrl s3c64xx_pin_ctrl[] = {
const struct samsung_pin_ctrl s3c64xx_pin_ctrl[] __initconst = {
{
/* pin-controller instance 1 data */
.pin_banks = s3c64xx_pin_banks0,
.nr_banks = ARRAY_SIZE(s3c64xx_pin_banks0),
.eint_gpio_init = s3c64xx_eint_gpio_init,
.eint_wkup_init = s3c64xx_eint_eint0_init,
.label = "S3C64xx-GPIO",
},
};

View file

@ -349,7 +349,7 @@ static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata,
{
struct samsung_pin_bank *b;
b = drvdata->ctrl->pin_banks;
b = drvdata->pin_banks;
while ((pin >= b->pin_base) &&
((b->pin_base + b->nr_pins - 1) < pin))
@ -366,7 +366,7 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
unsigned group, bool enable)
{
struct samsung_pinctrl_drv_data *drvdata;
struct samsung_pin_bank_type *type;
const struct samsung_pin_bank_type *type;
struct samsung_pin_bank *bank;
void __iomem *reg;
u32 mask, shift, data, pin_offset;
@ -378,7 +378,7 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
func = &drvdata->pmx_functions[selector];
grp = &drvdata->pin_groups[group];
pin_to_reg_bank(drvdata, grp->pins[0] - drvdata->ctrl->base,
pin_to_reg_bank(drvdata, grp->pins[0] - drvdata->pin_base,
&reg, &pin_offset, &bank);
type = bank->type;
mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1;
@ -422,7 +422,7 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *config, bool set)
{
struct samsung_pinctrl_drv_data *drvdata;
struct samsung_pin_bank_type *type;
const struct samsung_pin_bank_type *type;
struct samsung_pin_bank *bank;
void __iomem *reg_base;
enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(*config);
@ -431,7 +431,7 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long flags;
drvdata = pinctrl_dev_get_drvdata(pctldev);
pin_to_reg_bank(drvdata, pin - drvdata->ctrl->base, &reg_base,
pin_to_reg_bank(drvdata, pin - drvdata->pin_base, &reg_base,
&pin_offset, &bank);
type = bank->type;
@ -528,7 +528,7 @@ static const struct pinconf_ops samsung_pinconf_ops = {
static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
{
struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
struct samsung_pin_bank_type *type = bank->type;
const struct samsung_pin_bank_type *type = bank->type;
unsigned long flags;
void __iomem *reg;
u32 data;
@ -552,7 +552,7 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
void __iomem *reg;
u32 data;
struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
struct samsung_pin_bank_type *type = bank->type;
const struct samsung_pin_bank_type *type = bank->type;
reg = bank->drvdata->virt_base + bank->pctl_offset;
@ -569,7 +569,7 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
static int samsung_gpio_set_direction(struct gpio_chip *gc,
unsigned offset, bool input)
{
struct samsung_pin_bank_type *type;
const struct samsung_pin_bank_type *type;
struct samsung_pin_bank *bank;
struct samsung_pinctrl_drv_data *drvdata;
void __iomem *reg;
@ -834,32 +834,32 @@ static int samsung_pinctrl_register(struct platform_device *pdev,
ctrldesc->confops = &samsung_pinconf_ops;
pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) *
drvdata->ctrl->nr_pins, GFP_KERNEL);
drvdata->nr_pins, GFP_KERNEL);
if (!pindesc) {
dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n");
return -ENOMEM;
}
ctrldesc->pins = pindesc;
ctrldesc->npins = drvdata->ctrl->nr_pins;
ctrldesc->npins = drvdata->nr_pins;
/* dynamically populate the pin number and pin name for pindesc */
for (pin = 0, pdesc = pindesc; pin < ctrldesc->npins; pin++, pdesc++)
pdesc->number = pin + drvdata->ctrl->base;
pdesc->number = pin + drvdata->pin_base;
/*
* allocate space for storing the dynamically generated names for all
* the pins which belong to this pin-controller.
*/
pin_names = devm_kzalloc(&pdev->dev, sizeof(char) * PIN_NAME_LENGTH *
drvdata->ctrl->nr_pins, GFP_KERNEL);
drvdata->nr_pins, GFP_KERNEL);
if (!pin_names) {
dev_err(&pdev->dev, "mem alloc for pin names failed\n");
return -ENOMEM;
}
/* for each pin, the name of the pin is pin-bank name + pin number */
for (bank = 0; bank < drvdata->ctrl->nr_banks; bank++) {
pin_bank = &drvdata->ctrl->pin_banks[bank];
for (bank = 0; bank < drvdata->nr_banks; bank++) {
pin_bank = &drvdata->pin_banks[bank];
for (pin = 0; pin < pin_bank->nr_pins; pin++) {
sprintf(pin_names, "%s-%d", pin_bank->name, pin);
pdesc = pindesc + pin_bank->pin_base + pin;
@ -878,11 +878,11 @@ static int samsung_pinctrl_register(struct platform_device *pdev,
return -EINVAL;
}
for (bank = 0; bank < drvdata->ctrl->nr_banks; ++bank) {
pin_bank = &drvdata->ctrl->pin_banks[bank];
for (bank = 0; bank < drvdata->nr_banks; ++bank) {
pin_bank = &drvdata->pin_banks[bank];
pin_bank->grange.name = pin_bank->name;
pin_bank->grange.id = bank;
pin_bank->grange.pin_base = drvdata->ctrl->base
pin_bank->grange.pin_base = drvdata->pin_base
+ pin_bank->pin_base;
pin_bank->grange.base = pin_bank->gpio_chip.base;
pin_bank->grange.npins = pin_bank->gpio_chip.ngpio;
@ -918,17 +918,16 @@ static const struct gpio_chip samsung_gpiolib_chip = {
static int samsung_gpiolib_register(struct platform_device *pdev,
struct samsung_pinctrl_drv_data *drvdata)
{
struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
struct samsung_pin_bank *bank = ctrl->pin_banks;
struct samsung_pin_bank *bank = drvdata->pin_banks;
struct gpio_chip *gc;
int ret;
int i;
for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
for (i = 0; i < drvdata->nr_banks; ++i, ++bank) {
bank->gpio_chip = samsung_gpiolib_chip;
gc = &bank->gpio_chip;
gc->base = ctrl->base + bank->pin_base;
gc->base = drvdata->pin_base + bank->pin_base;
gc->ngpio = bank->nr_pins;
gc->dev = &pdev->dev;
gc->of_node = bank->of_node;
@ -954,51 +953,70 @@ fail:
static int samsung_gpiolib_unregister(struct platform_device *pdev,
struct samsung_pinctrl_drv_data *drvdata)
{
struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
struct samsung_pin_bank *bank = ctrl->pin_banks;
struct samsung_pin_bank *bank = drvdata->pin_banks;
int i;
for (i = 0; i < ctrl->nr_banks; ++i, ++bank)
for (i = 0; i < drvdata->nr_banks; ++i, ++bank)
gpiochip_remove(&bank->gpio_chip);
return 0;
}
static const struct of_device_id samsung_pinctrl_dt_match[];
/* retrieve the soc specific data */
static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
struct samsung_pinctrl_drv_data *d,
struct platform_device *pdev)
static const struct samsung_pin_ctrl *
samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
struct platform_device *pdev)
{
int id;
const struct of_device_id *match;
struct device_node *node = pdev->dev.of_node;
struct device_node *np;
struct samsung_pin_ctrl *ctrl;
const struct samsung_pin_bank_data *bdata;
const struct samsung_pin_ctrl *ctrl;
struct samsung_pin_bank *bank;
int i;
id = of_alias_get_id(node, "pinctrl");
if (id < 0) {
dev_err(&pdev->dev, "failed to get alias id\n");
return NULL;
return ERR_PTR(-ENOENT);
}
match = of_match_node(samsung_pinctrl_dt_match, node);
ctrl = (struct samsung_pin_ctrl *)match->data + id;
bank = ctrl->pin_banks;
for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
d->suspend = ctrl->suspend;
d->resume = ctrl->resume;
d->nr_banks = ctrl->nr_banks;
d->pin_banks = devm_kcalloc(&pdev->dev, d->nr_banks,
sizeof(*d->pin_banks), GFP_KERNEL);
if (!d->pin_banks)
return ERR_PTR(-ENOMEM);
bank = d->pin_banks;
bdata = ctrl->pin_banks;
for (i = 0; i < ctrl->nr_banks; ++i, ++bdata, ++bank) {
bank->type = bdata->type;
bank->pctl_offset = bdata->pctl_offset;
bank->nr_pins = bdata->nr_pins;
bank->eint_func = bdata->eint_func;
bank->eint_type = bdata->eint_type;
bank->eint_mask = bdata->eint_mask;
bank->eint_offset = bdata->eint_offset;
bank->name = bdata->name;
spin_lock_init(&bank->slock);
bank->drvdata = d;
bank->pin_base = ctrl->nr_pins;
ctrl->nr_pins += bank->nr_pins;
bank->pin_base = d->nr_pins;
d->nr_pins += bank->nr_pins;
}
for_each_child_of_node(node, np) {
if (!of_find_property(np, "gpio-controller", NULL))
continue;
bank = ctrl->pin_banks;
for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
bank = d->pin_banks;
for (i = 0; i < d->nr_banks; ++i, ++bank) {
if (!strcmp(bank->name, np->name)) {
bank->of_node = np;
break;
@ -1006,8 +1024,8 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
}
}
ctrl->base = pin_base;
pin_base += ctrl->nr_pins;
d->pin_base = pin_base;
pin_base += d->nr_pins;
return ctrl;
}
@ -1015,8 +1033,8 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
static int samsung_pinctrl_probe(struct platform_device *pdev)
{
struct samsung_pinctrl_drv_data *drvdata;
const struct samsung_pin_ctrl *ctrl;
struct device *dev = &pdev->dev;
struct samsung_pin_ctrl *ctrl;
struct resource *res;
int ret;
@ -1033,11 +1051,10 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
}
ctrl = samsung_pinctrl_get_soc_data(drvdata, pdev);
if (!ctrl) {
if (IS_ERR(ctrl)) {
dev_err(&pdev->dev, "driver data not available\n");
return -EINVAL;
return PTR_ERR(ctrl);
}
drvdata->ctrl = ctrl;
drvdata->dev = dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@ -1082,16 +1099,14 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
static void samsung_pinctrl_suspend_dev(
struct samsung_pinctrl_drv_data *drvdata)
{
struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
void __iomem *virt_base = drvdata->virt_base;
int i;
for (i = 0; i < ctrl->nr_banks; i++) {
struct samsung_pin_bank *bank = &ctrl->pin_banks[i];
for (i = 0; i < drvdata->nr_banks; i++) {
struct samsung_pin_bank *bank = &drvdata->pin_banks[i];
void __iomem *reg = virt_base + bank->pctl_offset;
u8 *offs = bank->type->reg_offset;
u8 *widths = bank->type->fld_width;
const u8 *offs = bank->type->reg_offset;
const u8 *widths = bank->type->fld_width;
enum pincfg_type type;
/* Registers without a powerdown config aren't lost */
@ -1116,8 +1131,8 @@ static void samsung_pinctrl_suspend_dev(
}
}
if (ctrl->suspend)
ctrl->suspend(drvdata);
if (drvdata->suspend)
drvdata->suspend(drvdata);
}
/**
@ -1130,19 +1145,17 @@ static void samsung_pinctrl_suspend_dev(
*/
static void samsung_pinctrl_resume_dev(struct samsung_pinctrl_drv_data *drvdata)
{
struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
void __iomem *virt_base = drvdata->virt_base;
int i;
if (ctrl->resume)
ctrl->resume(drvdata);
if (drvdata->resume)
drvdata->resume(drvdata);
for (i = 0; i < ctrl->nr_banks; i++) {
struct samsung_pin_bank *bank = &ctrl->pin_banks[i];
for (i = 0; i < drvdata->nr_banks; i++) {
struct samsung_pin_bank *bank = &drvdata->pin_banks[i];
void __iomem *reg = virt_base + bank->pctl_offset;
u8 *offs = bank->type->reg_offset;
u8 *widths = bank->type->fld_width;
const u8 *offs = bank->type->reg_offset;
const u8 *widths = bank->type->fld_width;
enum pincfg_type type;
/* Registers without a powerdown config aren't lost */
@ -1218,6 +1231,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
.data = (void *)exynos4210_pin_ctrl },
{ .compatible = "samsung,exynos4x12-pinctrl",
.data = (void *)exynos4x12_pin_ctrl },
{ .compatible = "samsung,exynos4415-pinctrl",
.data = (void *)exynos4415_pin_ctrl },
{ .compatible = "samsung,exynos5250-pinctrl",
.data = (void *)exynos5250_pin_ctrl },
{ .compatible = "samsung,exynos5260-pinctrl",
@ -1226,6 +1241,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
.data = (void *)exynos5420_pin_ctrl },
{ .compatible = "samsung,s5pv210-pinctrl",
.data = (void *)s5pv210_pin_ctrl },
{ .compatible = "samsung,exynos7-pinctrl",
.data = (void *)exynos7_pin_ctrl },
#endif
#ifdef CONFIG_PINCTRL_S3C64XX
{ .compatible = "samsung,s3c64xx-pinctrl",

View file

@ -113,39 +113,66 @@ struct samsung_pin_bank_type {
};
/**
* struct samsung_pin_bank: represent a controller pin-bank.
* struct samsung_pin_bank_data: represent a controller pin-bank (init data).
* @type: type of the bank (register offsets and bitfield widths)
* @pctl_offset: starting offset of the pin-bank registers.
* @pin_base: starting pin number of the bank.
* @nr_pins: number of pins included in this bank.
* @eint_func: function to set in CON register to configure pin as EINT.
* @eint_type: type of the external interrupt supported by the bank.
* @eint_mask: bit mask of pins which support EINT function.
* @eint_offset: SoC-specific EINT register or interrupt offset of bank.
* @name: name to be prefixed for each pin in this pin bank.
* @of_node: OF node of the bank.
* @drvdata: link to controller driver data
* @irq_domain: IRQ domain of the bank.
* @gpio_chip: GPIO chip of the bank.
* @grange: linux gpio pin range supported by this bank.
* @slock: spinlock protecting bank registers
* @pm_save: saved register values during suspend
*/
struct samsung_pin_bank {
struct samsung_pin_bank_type *type;
struct samsung_pin_bank_data {
const struct samsung_pin_bank_type *type;
u32 pctl_offset;
u32 pin_base;
u8 nr_pins;
u8 eint_func;
enum eint_type eint_type;
u32 eint_mask;
u32 eint_offset;
char *name;
const char *name;
};
/**
* struct samsung_pin_bank: represent a controller pin-bank.
* @type: type of the bank (register offsets and bitfield widths)
* @pctl_offset: starting offset of the pin-bank registers.
* @nr_pins: number of pins included in this bank.
* @eint_func: function to set in CON register to configure pin as EINT.
* @eint_type: type of the external interrupt supported by the bank.
* @eint_mask: bit mask of pins which support EINT function.
* @eint_offset: SoC-specific EINT register or interrupt offset of bank.
* @name: name to be prefixed for each pin in this pin bank.
* @pin_base: starting pin number of the bank.
* @soc_priv: per-bank private data for SoC-specific code.
* @of_node: OF node of the bank.
* @drvdata: link to controller driver data
* @irq_domain: IRQ domain of the bank.
* @gpio_chip: GPIO chip of the bank.
* @grange: linux gpio pin range supported by this bank.
* @irq_chip: link to irq chip for external gpio and wakeup interrupts.
* @slock: spinlock protecting bank registers
* @pm_save: saved register values during suspend
*/
struct samsung_pin_bank {
const struct samsung_pin_bank_type *type;
u32 pctl_offset;
u8 nr_pins;
u8 eint_func;
enum eint_type eint_type;
u32 eint_mask;
u32 eint_offset;
const char *name;
u32 pin_base;
void *soc_priv;
struct device_node *of_node;
struct samsung_pinctrl_drv_data *drvdata;
struct irq_domain *irq_domain;
struct gpio_chip gpio_chip;
struct pinctrl_gpio_range grange;
struct exynos_irq_chip *irq_chip;
spinlock_t slock;
u32 pm_save[PINCFG_TYPE_NUM + 1]; /* +1 to handle double CON registers*/
@ -155,27 +182,19 @@ struct samsung_pin_bank {
* struct samsung_pin_ctrl: represent a pin controller.
* @pin_banks: list of pin banks included in this controller.
* @nr_banks: number of pin banks.
* @base: starting system wide pin number.
* @nr_pins: number of pins supported by the controller.
* @eint_gpio_init: platform specific callback to setup the external gpio
* interrupts for the controller.
* @eint_wkup_init: platform specific callback to setup the external wakeup
* interrupts for the controller.
* @label: for debug information.
*/
struct samsung_pin_ctrl {
struct samsung_pin_bank *pin_banks;
const struct samsung_pin_bank_data *pin_banks;
u32 nr_banks;
u32 base;
u32 nr_pins;
int (*eint_gpio_init)(struct samsung_pinctrl_drv_data *);
int (*eint_wkup_init)(struct samsung_pinctrl_drv_data *);
void (*suspend)(struct samsung_pinctrl_drv_data *);
void (*resume)(struct samsung_pinctrl_drv_data *);
char *label;
};
/**
@ -191,6 +210,8 @@ struct samsung_pin_ctrl {
* @nr_groups: number of such pin groups.
* @pmx_functions: list of pin functions available to the driver.
* @nr_function: number of such pin functions.
* @pin_base: starting system wide pin number.
* @nr_pins: number of pins supported by the controller.
*/
struct samsung_pinctrl_drv_data {
struct list_head node;
@ -198,7 +219,6 @@ struct samsung_pinctrl_drv_data {
struct device *dev;
int irq;
struct samsung_pin_ctrl *ctrl;
struct pinctrl_desc pctl;
struct pinctrl_dev *pctl_dev;
@ -206,6 +226,14 @@ struct samsung_pinctrl_drv_data {
unsigned int nr_groups;
const struct samsung_pmx_func *pmx_functions;
unsigned int nr_functions;
struct samsung_pin_bank *pin_banks;
u32 nr_banks;
unsigned int pin_base;
unsigned int nr_pins;
void (*suspend)(struct samsung_pinctrl_drv_data *);
void (*resume)(struct samsung_pinctrl_drv_data *);
};
/**
@ -236,17 +264,19 @@ struct samsung_pmx_func {
};
/* list of all exported SoC specific data */
extern struct samsung_pin_ctrl exynos3250_pin_ctrl[];
extern struct samsung_pin_ctrl exynos4210_pin_ctrl[];
extern struct samsung_pin_ctrl exynos4x12_pin_ctrl[];
extern struct samsung_pin_ctrl exynos5250_pin_ctrl[];
extern struct samsung_pin_ctrl exynos5260_pin_ctrl[];
extern struct samsung_pin_ctrl exynos5420_pin_ctrl[];
extern struct samsung_pin_ctrl s3c64xx_pin_ctrl[];
extern struct samsung_pin_ctrl s3c2412_pin_ctrl[];
extern struct samsung_pin_ctrl s3c2416_pin_ctrl[];
extern struct samsung_pin_ctrl s3c2440_pin_ctrl[];
extern struct samsung_pin_ctrl s3c2450_pin_ctrl[];
extern struct samsung_pin_ctrl s5pv210_pin_ctrl[];
extern const struct samsung_pin_ctrl exynos3250_pin_ctrl[];
extern const struct samsung_pin_ctrl exynos4210_pin_ctrl[];
extern const struct samsung_pin_ctrl exynos4x12_pin_ctrl[];
extern const struct samsung_pin_ctrl exynos4415_pin_ctrl[];
extern const struct samsung_pin_ctrl exynos5250_pin_ctrl[];
extern const struct samsung_pin_ctrl exynos5260_pin_ctrl[];
extern const struct samsung_pin_ctrl exynos5420_pin_ctrl[];
extern const struct samsung_pin_ctrl exynos7_pin_ctrl[];
extern const struct samsung_pin_ctrl s3c64xx_pin_ctrl[];
extern const struct samsung_pin_ctrl s3c2412_pin_ctrl[];
extern const struct samsung_pin_ctrl s3c2416_pin_ctrl[];
extern const struct samsung_pin_ctrl s3c2440_pin_ctrl[];
extern const struct samsung_pin_ctrl s3c2450_pin_ctrl[];
extern const struct samsung_pin_ctrl s5pv210_pin_ctrl[];
#endif /* __PINCTRL_SAMSUNG_H */

View file

@ -39,4 +39,8 @@ config PINCTRL_SUN8I_A23_R
depends on RESET_CONTROLLER
select PINCTRL_SUNXI_COMMON
config PINCTRL_SUN9I_A80
def_bool MACH_SUN9I
select PINCTRL_SUNXI_COMMON
endif

View file

@ -10,3 +10,4 @@ obj-$(CONFIG_PINCTRL_SUN6I_A31_R) += pinctrl-sun6i-a31-r.o
obj-$(CONFIG_PINCTRL_SUN7I_A20) += pinctrl-sun7i-a20.o
obj-$(CONFIG_PINCTRL_SUN8I_A23) += pinctrl-sun8i-a23.o
obj-$(CONFIG_PINCTRL_SUN8I_A23_R) += pinctrl-sun8i-a23-r.o
obj-$(CONFIG_PINCTRL_SUN9I_A80) += pinctrl-sun9i-a80.o

View file

@ -0,0 +1,749 @@
/*
* Allwinner A80 SoCs pinctrl driver.
*
* Copyright (C) 2014 Maxime Ripard
*
* Maxime Ripard <maxime.ripard@free-electrons.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-sunxi.h"
static const struct sunxi_desc_pin sun9i_a80_pins[] = {
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD3 */
SUNXI_FUNCTION(0x4, "uart1"), /* TX */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)), /* PA_EINT0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD2 */
SUNXI_FUNCTION(0x4, "uart1"), /* RX */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)), /* PA_EINT1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD1 */
SUNXI_FUNCTION(0x4, "uart1"), /* RTS */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)), /* PA_EINT2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD0 */
SUNXI_FUNCTION(0x4, "uart1"), /* CTS */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)), /* PA_EINT3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXCK */
SUNXI_FUNCTION(0x4, "uart1"), /* DTR */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)), /* PA_EINT4 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXCTL */
SUNXI_FUNCTION(0x4, "uart1"), /* DSR */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)), /* PA_EINT5 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXERR */
SUNXI_FUNCTION(0x4, "uart1"), /* DCD */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)), /* PA_EINT6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD3 */
SUNXI_FUNCTION(0x4, "uart1"), /* RING */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)), /* PA_EINT7 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 8),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD2 */
SUNXI_FUNCTION(0x4, "eclk"), /* IN0 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)), /* PA_EINT8 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 9),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXEN */
SUNXI_FUNCTION(0x4, "eclk"), /* IN1 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)), /* PA_EINT9 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 10),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD0 */
SUNXI_FUNCTION(0x4, "clk_out_a"),
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 10)), /* PA_EINT10 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 11),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* MII-CRS */
SUNXI_FUNCTION(0x4, "clk_out_b"),
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 11)), /* PA_EINT11 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 12),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXCK */
SUNXI_FUNCTION(0x4, "pwm3"), /* PWM_P */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 12)), /* PA_EINT12 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 13),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RGMII-TXCK / GMII-TXEN */
SUNXI_FUNCTION(0x4, "pwm3"), /* PWM_N */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 13)), /* PA_EINT13 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 14),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* MII-TXERR */
SUNXI_FUNCTION(0x4, "spi1"), /* CS0 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 14)), /* PA_EINT14 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 15),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RGMII-CLKIN / MII-COL */
SUNXI_FUNCTION(0x4, "spi1"), /* CLK */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 15)), /* PA_EINT15 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 16),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* EMDC */
SUNXI_FUNCTION(0x4, "spi1"), /* MOSI */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 16)), /* PA_EINT16 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 17),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* EMDIO */
SUNXI_FUNCTION(0x4, "spi1"), /* MISO */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 17)), /* PA_EINT17 */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x3, "uart3"), /* TX */
SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 5)), /* PB_EINT5 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x3, "uart3"), /* RX */
SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 6)), /* PB_EINT6 */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 14),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x3, "mcsi"), /* MCLK */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 14)), /* PB_EINT14 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 15),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x3, "mcsi"), /* SCK */
SUNXI_FUNCTION(0x4, "i2c4"), /* SCK */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 15)), /* PB_EINT15 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 16),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x3, "mcsi"), /* SDA */
SUNXI_FUNCTION(0x4, "i2c4"), /* SDA */
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 16)), /* PB_EINT16 */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* WE */
SUNXI_FUNCTION(0x3, "spi0")), /* MOSI */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* ALE */
SUNXI_FUNCTION(0x3, "spi0")), /* MISO */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* CLE */
SUNXI_FUNCTION(0x3, "spi0")), /* CLK */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0")), /* CE1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0")), /* CE0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0")), /* RE */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* RB0 */
SUNXI_FUNCTION(0x3, "mmc2")), /* CMD */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* RB1 */
SUNXI_FUNCTION(0x3, "mmc2")), /* CLK */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 8),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* DQ0 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 9),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* DQ1 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 10),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* DQ2 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 11),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* DQ3 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 12),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* DQ4 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D4 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 13),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* DQ5 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D5 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* DQ6 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* DQ7 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* DQS */
SUNXI_FUNCTION(0x3, "mmc2")), /* RST */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 17),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* CE2 */
SUNXI_FUNCTION(0x3, "nand0_b")), /* RE */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 18),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* CE3 */
SUNXI_FUNCTION(0x3, "nand0_b")), /* DQS */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 19),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x3, "spi0")), /* CS0 */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D0 */
SUNXI_FUNCTION(0x3, "lvds0")), /* VP0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D1 */
SUNXI_FUNCTION(0x3, "lvds0")), /* VN0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D2 */
SUNXI_FUNCTION(0x3, "lvds0")), /* VP1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D3 */
SUNXI_FUNCTION(0x3, "lvds0")), /* VN1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D4 */
SUNXI_FUNCTION(0x3, "lvds0")), /* VP2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D5 */
SUNXI_FUNCTION(0x3, "lvds0")), /* VN2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D6 */
SUNXI_FUNCTION(0x3, "lvds0")), /* VPC */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D7 */
SUNXI_FUNCTION(0x3, "lvds0")), /* VNC */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 8),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D8 */
SUNXI_FUNCTION(0x3, "lvds0")), /* VP3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 9),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D9 */
SUNXI_FUNCTION(0x3, "lvds0")), /* VN3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 10),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D10 */
SUNXI_FUNCTION(0x3, "lvds1")), /* VP0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 11),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D11 */
SUNXI_FUNCTION(0x3, "lvds1")), /* VN0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 12),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D12 */
SUNXI_FUNCTION(0x3, "lvds1")), /* VP1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 13),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D13 */
SUNXI_FUNCTION(0x3, "lvds1")), /* VN1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 14),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D14 */
SUNXI_FUNCTION(0x3, "lvds1")), /* VP2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 15),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D15 */
SUNXI_FUNCTION(0x3, "lvds1")), /* VN2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 16),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D16 */
SUNXI_FUNCTION(0x3, "lvds1")), /* VPC */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 17),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D17 */
SUNXI_FUNCTION(0x3, "lvds1")), /* VNC */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 18),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D18 */
SUNXI_FUNCTION(0x3, "lvds1")), /* VP3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 19),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D19 */
SUNXI_FUNCTION(0x3, "lvds1")), /* VN3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 20),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0")), /* D20 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 21),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0")), /* D21 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 22),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0")), /* D22 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 23),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0")), /* D23 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 24),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0")), /* CLK */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 25),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0")), /* DE */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 26),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0")), /* HSYNC */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 27),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0")), /* VSYNC */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* PCLK */
SUNXI_FUNCTION(0x3, "ts"), /* CLK */
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 0)), /* PE_EINT0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* MCLK */
SUNXI_FUNCTION(0x3, "ts"), /* ERR */
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 1)), /* PE_EINT1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* HSYNC */
SUNXI_FUNCTION(0x3, "ts"), /* SYNC */
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 2)), /* PE_EINT2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* VSYNC */
SUNXI_FUNCTION(0x3, "ts"), /* DVLD */
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 3)), /* PE_EINT3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D0 */
SUNXI_FUNCTION(0x3, "spi2"), /* CS0 */
SUNXI_FUNCTION(0x4, "uart5"), /* TX */
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 4)), /* PE_EINT4 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D1 */
SUNXI_FUNCTION(0x3, "spi2"), /* CLK */
SUNXI_FUNCTION(0x4, "uart5"), /* RX */
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 5)), /* PE_EINT5 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D2 */
SUNXI_FUNCTION(0x3, "spi2"), /* MOSI */
SUNXI_FUNCTION(0x4, "uart5"), /* RTS */
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 6)), /* PE_EINT6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D3 */
SUNXI_FUNCTION(0x3, "spi2"), /* MISO */
SUNXI_FUNCTION(0x4, "uart5"), /* CTS */
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 7)), /* PE_EINT7 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D4 */
SUNXI_FUNCTION(0x3, "ts"), /* D0 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 8)), /* PE_EINT8 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D5 */
SUNXI_FUNCTION(0x3, "ts"), /* D1 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 9)), /* PE_EINT9 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D6 */
SUNXI_FUNCTION(0x3, "ts"), /* D2 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 10)), /* PE_EINT10 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D7 */
SUNXI_FUNCTION(0x3, "ts"), /* D3 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 11)), /* PE_EINT11 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D8 */
SUNXI_FUNCTION(0x3, "ts"), /* D4 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 12)), /* PE_EINT12 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D9 */
SUNXI_FUNCTION(0x3, "ts"), /* D5 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 13)), /* PE_EINT13 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D10 */
SUNXI_FUNCTION(0x3, "ts"), /* D6 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 14)), /* PE_EINT14 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D11 */
SUNXI_FUNCTION(0x3, "ts"), /* D7 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 15)), /* PE_EINT15 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 16),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* SCK */
SUNXI_FUNCTION(0x3, "i2c4"), /* SCK */
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 16)), /* PE_EINT16 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 17),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* SDA */
SUNXI_FUNCTION(0x3, "i2c4"), /* SDA */
SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 17)), /* PE_EINT17 */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc0")), /* D1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc0")), /* D0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc0"), /* CLK */
SUNXI_FUNCTION(0x4, "uart0")), /* TX */
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc0")), /* CMD */
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc0"), /* D3 */
SUNXI_FUNCTION(0x4, "uart0")), /* RX */
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc0")), /* D2 */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc1"), /* CLK */
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 0)), /* PG_EINT0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc1"), /* CMD */
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 1)), /* PG_EINT1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc1"), /* D0 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 2)), /* PG_EINT2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc1"), /* D1 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 3)), /* PG_EINT3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc1"), /* D2 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 4)), /* PG_EINT4 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc1"), /* D3 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 5)), /* PG_EINT5 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "uart2"), /* TX */
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 6)), /* PG_EINT6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "uart2"), /* RX */
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 7)), /* PG_EINT7 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "uart2"), /* RTS */
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 8)), /* PG_EINT8 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "uart2"), /* CTS */
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 9)), /* PG_EINT9 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c3"), /* SCK */
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 10)), /* PG_EINT10 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c3"), /* SDA */
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 11)), /* PG_EINT11 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "uart4"), /* TX */
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 12)), /* PG_EINT12 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "uart4"), /* RX */
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 13)), /* PG_EINT13 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 14),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "uart4"), /* RTS */
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 14)), /* PG_EINT14 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 15),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "uart4"), /* CTS */
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 15)), /* PG_EINT15 */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c0")), /* SCK */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c0")), /* SDA */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c1")), /* SCK */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c1")), /* SDA */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c2")), /* SCK */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c2")), /* SDA */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "pwm0")),
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 8),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x3, "pwm1"), /* Positive */
SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 8)), /* PH_EINT8 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x3, "pwm1"), /* Negative */
SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 9)), /* PH_EINT9 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 10),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x3, "pwm2"), /* Positive */
SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 10)), /* PH_EINT10 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 11),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x3, "pwm2"), /* Negative */
SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 11)), /* PH_EINT12 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 12),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "uart0"), /* TX */
SUNXI_FUNCTION(0x3, "spi3"), /* CS2 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 12)), /* PH_EINT12 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 13),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "uart0"), /* RX */
SUNXI_FUNCTION(0x3, "spi3"), /* CS2 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 13)), /* PH_EINT13 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 14),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi3"), /* CLK */
SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 14)), /* PH_EINT14 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 15),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi3"), /* MOSI */
SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 15)), /* PH_EINT15 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 16),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi3"), /* MISO */
SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 16)), /* PH_EINT16 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 17),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi3"), /* CS0 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 17)), /* PH_EINT17 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 18),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi3"), /* CS1 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 18)), /* PH_EINT18 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 19),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "hdmi")), /* SCL */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 20),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "hdmi")), /* SDA */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 21),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "hdmi")), /* CEC */
};
static const struct sunxi_pinctrl_desc sun9i_a80_pinctrl_data = {
.pins = sun9i_a80_pins,
.npins = ARRAY_SIZE(sun9i_a80_pins),
.irq_banks = 5,
};
static int sun9i_a80_pinctrl_probe(struct platform_device *pdev)
{
return sunxi_pinctrl_init(pdev,
&sun9i_a80_pinctrl_data);
}
static struct of_device_id sun9i_a80_pinctrl_match[] = {
{ .compatible = "allwinner,sun9i-a80-pinctrl", },
{}
};
MODULE_DEVICE_TABLE(of, sun9i_a80_pinctrl_match);
static struct platform_driver sun9i_a80_pinctrl_driver = {
.probe = sun9i_a80_pinctrl_probe,
.driver = {
.name = "sun9i-a80-pinctrl",
.of_match_table = sun9i_a80_pinctrl_match,
},
};
module_platform_driver(sun9i_a80_pinctrl_driver);
MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
MODULE_DESCRIPTION("Allwinner A80 pinctrl driver");
MODULE_LICENSE("GPL");

View file

@ -27,6 +27,7 @@
#define PI_BASE 256
#define PL_BASE 352
#define PM_BASE 384
#define PN_BASE 416
#define SUNXI_PINCTRL_PIN(bank, pin) \
PINCTRL_PIN(P ## bank ## _BASE + (pin), "P" #bank #pin)

View file

@ -0,0 +1,142 @@
/*
* This header provides constants for the Qualcomm PMIC GPIO binding.
*/
#ifndef _DT_BINDINGS_PINCTRL_QCOM_PMIC_GPIO_H
#define _DT_BINDINGS_PINCTRL_QCOM_PMIC_GPIO_H
#define PMIC_GPIO_PULL_UP_30 0
#define PMIC_GPIO_PULL_UP_1P5 1
#define PMIC_GPIO_PULL_UP_31P5 2
#define PMIC_GPIO_PULL_UP_1P5_30 3
#define PMIC_GPIO_STRENGTH_NO 0
#define PMIC_GPIO_STRENGTH_HIGH 1
#define PMIC_GPIO_STRENGTH_MED 2
#define PMIC_GPIO_STRENGTH_LOW 3
/*
* Note: PM8018 GPIO3 and GPIO4 are supporting
* only S3 and L2 options (1.8V)
*/
#define PM8018_GPIO_L6 0
#define PM8018_GPIO_L5 1
#define PM8018_GPIO_S3 2
#define PM8018_GPIO_L14 3
#define PM8018_GPIO_L2 4
#define PM8018_GPIO_L4 5
#define PM8018_GPIO_VDD 6
/*
* Note: PM8038 GPIO7 and GPIO8 are supporting
* only L11 and L4 options (1.8V)
*/
#define PM8038_GPIO_VPH 0
#define PM8038_GPIO_BB 1
#define PM8038_GPIO_L11 2
#define PM8038_GPIO_L15 3
#define PM8038_GPIO_L4 4
#define PM8038_GPIO_L3 5
#define PM8038_GPIO_L17 6
#define PM8058_GPIO_VPH 0
#define PM8058_GPIO_BB 1
#define PM8058_GPIO_S3 2
#define PM8058_GPIO_L3 3
#define PM8058_GPIO_L7 4
#define PM8058_GPIO_L6 5
#define PM8058_GPIO_L5 6
#define PM8058_GPIO_L2 7
#define PM8917_GPIO_VPH 0
#define PM8917_GPIO_S4 2
#define PM8917_GPIO_L15 3
#define PM8917_GPIO_L4 4
#define PM8917_GPIO_L3 5
#define PM8917_GPIO_L17 6
#define PM8921_GPIO_VPH 0
#define PM8921_GPIO_BB 1
#define PM8921_GPIO_S4 2
#define PM8921_GPIO_L15 3
#define PM8921_GPIO_L4 4
#define PM8921_GPIO_L3 5
#define PM8921_GPIO_L17 6
/*
* Note: PM8941 gpios from 15 to 18 are supporting
* only S3 and L6 options (1.8V)
*/
#define PM8941_GPIO_VPH 0
#define PM8941_GPIO_L1 1
#define PM8941_GPIO_S3 2
#define PM8941_GPIO_L6 3
/*
* Note: PMA8084 gpios from 15 to 18 are supporting
* only S4 and L6 options (1.8V)
*/
#define PMA8084_GPIO_VPH 0
#define PMA8084_GPIO_L1 1
#define PMA8084_GPIO_S4 2
#define PMA8084_GPIO_L6 3
/* To be used with "function" */
#define PMIC_GPIO_FUNC_NORMAL "normal"
#define PMIC_GPIO_FUNC_PAIRED "paired"
#define PMIC_GPIO_FUNC_FUNC1 "func1"
#define PMIC_GPIO_FUNC_FUNC2 "func2"
#define PMIC_GPIO_FUNC_DTEST1 "dtest1"
#define PMIC_GPIO_FUNC_DTEST2 "dtest2"
#define PMIC_GPIO_FUNC_DTEST3 "dtest3"
#define PMIC_GPIO_FUNC_DTEST4 "dtest4"
#define PM8038_GPIO1_2_LPG_DRV PMIC_GPIO_FUNC_FUNC1
#define PM8038_GPIO3_5V_BOOST_EN PMIC_GPIO_FUNC_FUNC1
#define PM8038_GPIO4_SSBI_ALT_CLK PMIC_GPIO_FUNC_FUNC1
#define PM8038_GPIO5_6_EXT_REG_EN PMIC_GPIO_FUNC_FUNC1
#define PM8038_GPIO10_11_EXT_REG_EN PMIC_GPIO_FUNC_FUNC1
#define PM8038_GPIO6_7_CLK PMIC_GPIO_FUNC_FUNC1
#define PM8038_GPIO9_BAT_ALRM_OUT PMIC_GPIO_FUNC_FUNC1
#define PM8038_GPIO6_12_KYPD_DRV PMIC_GPIO_FUNC_FUNC2
#define PM8058_GPIO7_8_MP3_CLK PMIC_GPIO_FUNC_FUNC1
#define PM8058_GPIO7_8_BCLK_19P2MHZ PMIC_GPIO_FUNC_FUNC2
#define PM8058_GPIO9_26_KYPD_DRV PMIC_GPIO_FUNC_FUNC1
#define PM8058_GPIO21_23_UART_TX PMIC_GPIO_FUNC_FUNC2
#define PM8058_GPIO24_26_LPG_DRV PMIC_GPIO_FUNC_FUNC2
#define PM8058_GPIO33_BCLK_19P2MHZ PMIC_GPIO_FUNC_FUNC1
#define PM8058_GPIO34_35_MP3_CLK PMIC_GPIO_FUNC_FUNC1
#define PM8058_GPIO36_BCLK_19P2MHZ PMIC_GPIO_FUNC_FUNC1
#define PM8058_GPIO37_UPL_OUT PMIC_GPIO_FUNC_FUNC1
#define PM8058_GPIO37_UART_M_RX PMIC_GPIO_FUNC_FUNC2
#define PM8058_GPIO38_XO_SLEEP_CLK PMIC_GPIO_FUNC_FUNC1
#define PM8058_GPIO38_39_CLK_32KHZ PMIC_GPIO_FUNC_FUNC2
#define PM8058_GPIO39_MP3_CLK PMIC_GPIO_FUNC_FUNC1
#define PM8058_GPIO40_EXT_BB_EN PMIC_GPIO_FUNC_FUNC1
#define PM8917_GPIO9_18_KEYP_DRV PMIC_GPIO_FUNC_FUNC1
#define PM8917_GPIO20_BAT_ALRM_OUT PMIC_GPIO_FUNC_FUNC1
#define PM8917_GPIO21_23_UART_TX PMIC_GPIO_FUNC_FUNC2
#define PM8917_GPIO25_26_EXT_REG_EN PMIC_GPIO_FUNC_FUNC1
#define PM8917_GPIO37_38_XO_SLEEP_CLK PMIC_GPIO_FUNC_FUNC1
#define PM8917_GPIO37_38_MP3_CLK PMIC_GPIO_FUNC_FUNC2
#define PM8941_GPIO9_14_KYPD_DRV PMIC_GPIO_FUNC_FUNC1
#define PM8941_GPIO15_18_DIV_CLK PMIC_GPIO_FUNC_FUNC1
#define PM8941_GPIO15_18_SLEEP_CLK PMIC_GPIO_FUNC_FUNC2
#define PM8941_GPIO23_26_KYPD_DRV PMIC_GPIO_FUNC_FUNC1
#define PM8941_GPIO23_26_LPG_DRV_HI PMIC_GPIO_FUNC_FUNC2
#define PM8941_GPIO31_BAT_ALRM_OUT PMIC_GPIO_FUNC_FUNC1
#define PM8941_GPIO33_36_LPG_DRV_3D PMIC_GPIO_FUNC_FUNC1
#define PM8941_GPIO33_36_LPG_DRV_HI PMIC_GPIO_FUNC_FUNC2
#define PMA8084_GPIO4_5_LPG_DRV PMIC_GPIO_FUNC_FUNC1
#define PMA8084_GPIO7_10_LPG_DRV PMIC_GPIO_FUNC_FUNC1
#define PMA8084_GPIO5_14_KEYP_DRV PMIC_GPIO_FUNC_FUNC2
#define PMA8084_GPIO19_21_KEYP_DRV PMIC_GPIO_FUNC_FUNC2
#define PMA8084_GPIO15_18_DIV_CLK PMIC_GPIO_FUNC_FUNC1
#define PMA8084_GPIO15_18_SLEEP_CLK PMIC_GPIO_FUNC_FUNC2
#define PMA8084_GPIO22_BAT_ALRM_OUT PMIC_GPIO_FUNC_FUNC1
#endif

View file

@ -0,0 +1,44 @@
/*
* This header provides constants for the Qualcomm PMIC's
* Multi-Purpose Pin binding.
*/
#ifndef _DT_BINDINGS_PINCTRL_QCOM_PMIC_MPP_H
#define _DT_BINDINGS_PINCTRL_QCOM_PMIC_MPP_H
/* power-source */
#define PM8841_MPP_VPH 0
#define PM8841_MPP_S3 2
#define PM8941_MPP_VPH 0
#define PM8941_MPP_L1 1
#define PM8941_MPP_S3 2
#define PM8941_MPP_L6 3
#define PMA8084_MPP_VPH 0
#define PMA8084_MPP_L1 1
#define PMA8084_MPP_S4 2
#define PMA8084_MPP_L6 3
/*
* Analog Input - Set the source for analog input.
* To be used with "qcom,amux-route" property
*/
#define PMIC_MPP_AMUX_ROUTE_CH5 0
#define PMIC_MPP_AMUX_ROUTE_CH6 1
#define PMIC_MPP_AMUX_ROUTE_CH7 2
#define PMIC_MPP_AMUX_ROUTE_CH8 3
#define PMIC_MPP_AMUX_ROUTE_ABUS1 4
#define PMIC_MPP_AMUX_ROUTE_ABUS2 5
#define PMIC_MPP_AMUX_ROUTE_ABUS3 6
#define PMIC_MPP_AMUX_ROUTE_ABUS4 7
/* To be used with "function" */
#define PMIC_MPP_FUNC_NORMAL "normal"
#define PMIC_MPP_FUNC_PAIRED "paired"
#define PMIC_MPP_FUNC_DTEST1 "dtest1"
#define PMIC_MPP_FUNC_DTEST2 "dtest2"
#define PMIC_MPP_FUNC_DTEST3 "dtest3"
#define PMIC_MPP_FUNC_DTEST4 "dtest4"
#endif