This is the bulk of pin control changes for the v4.8 kernel cycle.
New drivers: - New driver for Oxnas pin control and GPIO. This ARM-based chipset is used in a few storage (NAS) type devices. - New driver for the MAX77620/MAX20024 pin controller portions. - New driver for the Intel Merrifield pin controller. New subdrivers: - New subdriver for the Qualcomm MDM9615 - New subdriver for the STM32F746 MCU - New subdriver for the Broadcom NSP SoC. Cleanups: - Demodularization of bool compiled-in drivers. Apart from this there is just regular incremental improvements to a lot of drivers, especially Uniphier and PFC. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJXmcthAAoJEEEQszewGV1z2ukP/1T34tgMllEzBcnyTM28pnPl 80anOiCi/jkLuW1hYTLc4Rx0tZT2oWw9hrZdKGNMuzNCaJSmFaRhUrbzxhZ8E+6O 3AHYSopAYUTKVYJsuY+fs3HbNajKBsSWYdmxin4e953BPudLjhZ2WliDXxupsbwZ /KI6s8J2pDZcPurrlozT5Avp3BTwwCq+fo12NIMkkmuhURb69OsDAVjPlwjocq73 BKcdH8AdgO7w5Ss5/IQbvrhyuFc2kCQ/wH1tiuE2a4iYWhp+QkMOEqWUSdYs33bx Sbn3KTK6IYYS1eb4xharh7H/zoBs20aCQ2kS8qbYmG+Fv7rB7qboI0qM7m7+25O8 7F6Tf4F0HUg6IjcABcI5lFuTxACBG8p5ZlmQAp/36EaeIblLALBCvd1ArmZ6fdG+ Pzu5vLaZBAmxQn6EseHLAJkH4FEzV7II/Sk7U23TINHUpl/L2GJO+6irz7eelKAk XED6mrNU8rRnZMka02ZnIgIbABG7ELNJsRxEnf8k9CX7cfi4p568eZeR1nfKcy4+ uldJLipNv3NfwuRY5JEEa7pFW4azYmnzS1GcoVYPy7snYc4Rr8cbBD6YvcxyMhVz RXHc21mj45JnboldAYU59t5BbVZNwZqF8hmg935ngoaZjYfhhnfGoNQF7hy6/1fS bwojoQtBqGcriKZYGs0o =po0g -----END PGP SIGNATURE----- Merge tag 'pinctrl-v4.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl Pull pin control updates from Linus Walleij: "This is the bulk of pin control changes for the v4.8 kernel cycle. Nothing stands out as especially exiting: new drivers, new subdrivers, lots of cleanups and incremental features. Business as usual. New drivers: - New driver for Oxnas pin control and GPIO. This ARM-based chipset is used in a few storage (NAS) type devices. - New driver for the MAX77620/MAX20024 pin controller portions. - New driver for the Intel Merrifield pin controller. New subdrivers: - New subdriver for the Qualcomm MDM9615 - New subdriver for the STM32F746 MCU - New subdriver for the Broadcom NSP SoC. Cleanups: - Demodularization of bool compiled-in drivers. Apart from this there is just regular incremental improvements to a lot of drivers, especially Uniphier and PFC" * tag 'pinctrl-v4.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (131 commits) pinctrl: fix pincontrol definition for marvell pinctrl: xway: fix typo Revert "pinctrl: amd: make it explicitly non-modular" pinctrl: iproc: Add NSP and Stingray GPIO support pinctrl: Update iProc GPIO DT bindings pinctrl: bcm: add OF dependencies pinctrl: ns2: remove redundant dev_err call in ns2_pinmux_probe() pinctrl: Add STM32F746 MCU support pinctrl: intel: Protect set wake flow by spin lock pinctrl: nsp: remove redundant dev_err call in nsp_pinmux_probe() pinctrl: uniphier: add Ethernet pin-mux settings sh-pfc: Use PTR_ERR_OR_ZERO() to simplify the code pinctrl: ns2: fix return value check in ns2_pinmux_probe() pinctrl: qcom: update DT bindings with ebi2 groups pinctrl: qcom: establish proper EBI2 pin groups pinctrl: imx21: Remove the MODULE_DEVICE_TABLE() macro Documentation: dt: Add new compatible to STM32 pinctrl driver bindings includes: dt-bindings: Add STM32F746 pinctrl DT bindings pinctrl: sunxi: fix nand0 function name for sun8i pinctrl: uniphier: remove pointless pin-mux settings for PH1-LD11 ...
This commit is contained in:
commit
d94ba9e7d8
|
@ -0,0 +1,47 @@
|
||||||
|
* Oxford Semiconductor OXNAS SoC GPIO Controller
|
||||||
|
|
||||||
|
Please refer to gpio.txt for generic information regarding GPIO bindings.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible: "oxsemi,ox810se-gpio"
|
||||||
|
- reg: Base address and length for the device.
|
||||||
|
- interrupts: The port interrupt shared by all pins.
|
||||||
|
- gpio-controller: Marks the port as GPIO controller.
|
||||||
|
- #gpio-cells: Two. The first cell is the pin number and
|
||||||
|
the second cell is used to specify the gpio polarity as defined in
|
||||||
|
defined in <dt-bindings/gpio/gpio.h>:
|
||||||
|
0 = GPIO_ACTIVE_HIGH
|
||||||
|
1 = GPIO_ACTIVE_LOW
|
||||||
|
- interrupt-controller: Marks the device node as an interrupt controller.
|
||||||
|
- #interrupt-cells: Two. The first cell is the GPIO number and second cell
|
||||||
|
is used to specify the trigger type as defined in
|
||||||
|
<dt-bindings/interrupt-controller/irq.h>:
|
||||||
|
IRQ_TYPE_EDGE_RISING
|
||||||
|
IRQ_TYPE_EDGE_FALLING
|
||||||
|
IRQ_TYPE_EDGE_BOTH
|
||||||
|
- gpio-ranges: Interaction with the PINCTRL subsystem, it also specifies the
|
||||||
|
gpio base and count, should be in the format of numeric-gpio-range as
|
||||||
|
specified in the gpio.txt file.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
gpio0: gpio@0 {
|
||||||
|
compatible = "oxsemi,ox810se-gpio";
|
||||||
|
reg = <0x000000 0x100000>;
|
||||||
|
interrupts = <21>;
|
||||||
|
#gpio-cells = <2>;
|
||||||
|
gpio-controller;
|
||||||
|
interrupt-controller;
|
||||||
|
#interrupt-cells = <2>;
|
||||||
|
gpio-ranges = <&pinctrl 0 0 32>;
|
||||||
|
};
|
||||||
|
|
||||||
|
keys {
|
||||||
|
...
|
||||||
|
|
||||||
|
button-esc {
|
||||||
|
label = "ESC";
|
||||||
|
linux,code = <1>;
|
||||||
|
gpios = <&gpio0 12 0>;
|
||||||
|
};
|
||||||
|
};
|
|
@ -3,8 +3,22 @@ Broadcom iProc GPIO/PINCONF Controller
|
||||||
Required properties:
|
Required properties:
|
||||||
|
|
||||||
- compatible:
|
- compatible:
|
||||||
Must be "brcm,cygnus-ccm-gpio", "brcm,cygnus-asiu-gpio",
|
"brcm,iproc-gpio" for the generic iProc based GPIO controller IP that
|
||||||
"brcm,cygnus-crmu-gpio" or "brcm,iproc-gpio"
|
supports full-featured pinctrl and GPIO functions used in various iProc
|
||||||
|
based SoCs
|
||||||
|
|
||||||
|
May contain an SoC-specific compatibility string to accommodate any
|
||||||
|
SoC-specific features
|
||||||
|
|
||||||
|
"brcm,cygnus-ccm-gpio", "brcm,cygnus-asiu-gpio", or
|
||||||
|
"brcm,cygnus-crmu-gpio" for Cygnus SoCs
|
||||||
|
|
||||||
|
"brcm,iproc-nsp-gpio" for the iProc NSP SoC that has drive strength support
|
||||||
|
disabled
|
||||||
|
|
||||||
|
"brcm,iproc-stingray-gpio" for the iProc Stingray SoC that has the general
|
||||||
|
pinctrl support completely disabled in this IP block. In Stingray, a
|
||||||
|
different IP block is used to handle pinctrl related functions
|
||||||
|
|
||||||
- reg:
|
- reg:
|
||||||
Define the base and range of the I/O address space that contains SoC
|
Define the base and range of the I/O address space that contains SoC
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
Broadcom NSP (Northstar plus) IOMUX Controller
|
||||||
|
|
||||||
|
The NSP IOMUX controller supports group based mux configuration. In
|
||||||
|
addition, certain pins can be muxed to GPIO function individually.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible:
|
||||||
|
Must be "brcm,nsp-pinmux"
|
||||||
|
|
||||||
|
- reg:
|
||||||
|
Should contain the register physical address and length for each of
|
||||||
|
GPIO_CONTROL0, GP_AUX_SEL and IPROC_CONFIG IOMUX registers
|
||||||
|
|
||||||
|
Properties in subnodes:
|
||||||
|
- function:
|
||||||
|
The mux function to select
|
||||||
|
|
||||||
|
- groups:
|
||||||
|
The list of groups to select with a given function
|
||||||
|
|
||||||
|
For more details, refer to
|
||||||
|
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
pinmux: pinmux@1803f1c0 {
|
||||||
|
compatible = "brcm,nsp-pinmux";
|
||||||
|
reg = <0x1803f1c0 0x04>,
|
||||||
|
<0x18030028 0x04>,
|
||||||
|
<0x1803f408 0x04>;
|
||||||
|
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&pwm &gpio_b &nand_sel>;
|
||||||
|
|
||||||
|
pwm: pwm {
|
||||||
|
function = "pwm";
|
||||||
|
groups = "pwm0_grp", "pwm1_grp";
|
||||||
|
};
|
||||||
|
|
||||||
|
gpio_b: gpio_b {
|
||||||
|
function = "gpio_b";
|
||||||
|
groups = "gpio_b_0_grp", "gpio_b_1_grp";
|
||||||
|
};
|
||||||
|
|
||||||
|
nand_sel: nand_sel {
|
||||||
|
function = "nand";
|
||||||
|
groups = "nand_grp";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
List of supported functions and groups in Northstar Plus:
|
||||||
|
|
||||||
|
"spi": "spi_grp"
|
||||||
|
|
||||||
|
"i2c": "i2c_grp"
|
||||||
|
|
||||||
|
"mdio": "mdio_grp"
|
||||||
|
|
||||||
|
"pwm": "pwm0_grp", "pwm1_grp", "pwm2_grp", "pwm3_grp"
|
||||||
|
|
||||||
|
"gpio_b": "gpio_b_0_grp", "gpio_b_1_grp", "gpio_b_2_grp", "gpio_b_3_grp"
|
||||||
|
|
||||||
|
"uart1": "uart1_grp"
|
||||||
|
|
||||||
|
"uart2": "uart2_grp"
|
||||||
|
|
||||||
|
"synce": "synce_grp"
|
||||||
|
|
||||||
|
"sata_led_grps": "sata0_led_grp", "sata1_led_grp"
|
||||||
|
|
||||||
|
"xtal_out": "xtal_out_grp"
|
||||||
|
|
||||||
|
"sdio": "sdio_pwr_grp", "sdio_1p8v_grp"
|
||||||
|
|
||||||
|
"switch_led": "switch_p05_led0_grp", "switch_p05_led1_grp"
|
||||||
|
|
||||||
|
"nand": "nand_grp"
|
||||||
|
|
||||||
|
"emmc": "emmc_grp"
|
|
@ -0,0 +1,57 @@
|
||||||
|
* Oxford Semiconductor OXNAS SoC Family Pin Controller
|
||||||
|
|
||||||
|
Please refer to pinctrl-bindings.txt, ../gpio/gpio.txt, and
|
||||||
|
../interrupt-controller/interrupts.txt for generic information regarding
|
||||||
|
pin controller, GPIO, and interrupt bindings.
|
||||||
|
|
||||||
|
OXNAS 'pin configuration node' is a node of a group of pins which can be
|
||||||
|
used for a specific device or function. This node represents configurations of
|
||||||
|
pins, optional function, and optional mux related configuration.
|
||||||
|
|
||||||
|
Required properties for pin controller node:
|
||||||
|
- compatible: "oxsemi,ox810se-pinctrl"
|
||||||
|
- oxsemi,sys-ctrl: a phandle to the system controller syscon node
|
||||||
|
|
||||||
|
Required properties for pin configuration sub-nodes:
|
||||||
|
- pins: List of pins to which the configuration applies.
|
||||||
|
|
||||||
|
Optional properties for pin configuration sub-nodes:
|
||||||
|
----------------------------------------------------
|
||||||
|
- function: Mux function for the specified pins.
|
||||||
|
- bias-pull-up: Enable weak pull-up.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
pinctrl: pinctrl {
|
||||||
|
compatible = "oxsemi,ox810se-pinctrl";
|
||||||
|
|
||||||
|
/* Regmap for sys registers */
|
||||||
|
oxsemi,sys-ctrl = <&sys>;
|
||||||
|
|
||||||
|
pinctrl_uart2: pinctrl_uart2 {
|
||||||
|
uart2a {
|
||||||
|
pins = "gpio31";
|
||||||
|
function = "fct3";
|
||||||
|
};
|
||||||
|
uart2b {
|
||||||
|
pins = "gpio32";
|
||||||
|
function = "fct3";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
uart2: serial@900000 {
|
||||||
|
compatible = "ns16550a";
|
||||||
|
reg = <0x900000 0x100000>;
|
||||||
|
clocks = <&sysclk>;
|
||||||
|
interrupts = <29>;
|
||||||
|
reg-shift = <0>;
|
||||||
|
fifo-size = <16>;
|
||||||
|
reg-io-width = <1>;
|
||||||
|
current-speed = <115200>;
|
||||||
|
no-loopback-test;
|
||||||
|
status = "disabled";
|
||||||
|
resets = <&reset 22>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&pinctrl_uart2>;
|
||||||
|
};
|
|
@ -0,0 +1,127 @@
|
||||||
|
Pincontrol driver for MAX77620 Power management IC from Maxim Semiconductor.
|
||||||
|
|
||||||
|
Device has 8 GPIO pins which can be configured as GPIO as well as the
|
||||||
|
special IO functions.
|
||||||
|
|
||||||
|
Please refer file <devicetree/bindings/pinctrl/pinctrl-bindings.txt>
|
||||||
|
for details of the common pinctrl bindings used by client devices,
|
||||||
|
including the meaning of the phrase "pin configuration node".
|
||||||
|
|
||||||
|
Optional Pinmux properties:
|
||||||
|
--------------------------
|
||||||
|
Following properties are required if default setting of pins are required
|
||||||
|
at boot.
|
||||||
|
- pinctrl-names: A pinctrl state named per <pinctrl-binding.txt>.
|
||||||
|
- pinctrl[0...n]: Properties to contain the phandle for pinctrl states per
|
||||||
|
<pinctrl-binding.txt>.
|
||||||
|
|
||||||
|
The pin configurations are defined as child of the pinctrl states node. Each
|
||||||
|
sub-node have following properties:
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
------------------
|
||||||
|
- pins: List of pins. Valid values of pins properties are:
|
||||||
|
gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7.
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
-------------------
|
||||||
|
Following are optional properties defined as pinmux DT binding document
|
||||||
|
<pinctrl-bindings.txt>. Absence of properties will leave the configuration
|
||||||
|
on default.
|
||||||
|
function,
|
||||||
|
drive-push-pull,
|
||||||
|
drive-open-drain,
|
||||||
|
bias-pull-up,
|
||||||
|
bias-pull-down.
|
||||||
|
|
||||||
|
Valid values for function properties are:
|
||||||
|
gpio, lpm-control-in, fps-out, 32k-out, sd0-dvs-in, sd1-dvs-in,
|
||||||
|
reference-out
|
||||||
|
|
||||||
|
Theres is also customised properties for the GPIO1, GPIO2 and GPIO3. These
|
||||||
|
customised properties are required to configure FPS configuration parameters
|
||||||
|
of these GPIOs. Please refer <devicetree/bindings/mfd/max77620.txt> for more
|
||||||
|
detail of Flexible Power Sequence (FPS).
|
||||||
|
|
||||||
|
- maxim,active-fps-source: FPS source for the GPIOs to get
|
||||||
|
enabled/disabled when system is in
|
||||||
|
active state. Valid values are:
|
||||||
|
- MAX77620_FPS_SRC_0,
|
||||||
|
FPS source is FPS0.
|
||||||
|
- MAX77620_FPS_SRC_1,
|
||||||
|
FPS source is FPS1
|
||||||
|
- MAX77620_FPS_SRC_2 and
|
||||||
|
FPS source is FPS2
|
||||||
|
- MAX77620_FPS_SRC_NONE.
|
||||||
|
GPIO is not controlled
|
||||||
|
by FPS events and it gets
|
||||||
|
enabled/disabled by register
|
||||||
|
access.
|
||||||
|
Absence of this property will leave
|
||||||
|
the FPS configuration register for that
|
||||||
|
GPIO to default configuration.
|
||||||
|
|
||||||
|
- maxim,active-fps-power-up-slot: Sequencing event slot number on which
|
||||||
|
the GPIO get enabled when
|
||||||
|
master FPS input event set to HIGH.
|
||||||
|
Valid values are 0 to 7.
|
||||||
|
This is applicable if FPS source is
|
||||||
|
selected as FPS0, FPS1 or FPS2.
|
||||||
|
|
||||||
|
- maxim,active-fps-power-down-slot: Sequencing event slot number on which
|
||||||
|
the GPIO get disabled when master
|
||||||
|
FPS input event set to LOW.
|
||||||
|
Valid values are 0 to 7.
|
||||||
|
This is applicable if FPS source is
|
||||||
|
selected as FPS0, FPS1 or FPS2.
|
||||||
|
|
||||||
|
- maxim,suspend-fps-source: This is same as property
|
||||||
|
"maxim,active-fps-source" but value
|
||||||
|
get configured when system enters in
|
||||||
|
to suspend state.
|
||||||
|
|
||||||
|
- maxim,suspend-fps-power-up-slot: This is same as property
|
||||||
|
"maxim,active-fps-power-up-slot" but
|
||||||
|
this value get configured into FPS
|
||||||
|
configuration register when system
|
||||||
|
enters into suspend.
|
||||||
|
This is applicable if suspend state
|
||||||
|
FPS source is selected as FPS0, FPS1 or
|
||||||
|
|
||||||
|
- maxim,suspend-fps-power-down-slot: This is same as property
|
||||||
|
"maxim,active-fps-power-down-slot" but
|
||||||
|
this value get configured into FPS
|
||||||
|
configuration register when system
|
||||||
|
enters into suspend.
|
||||||
|
This is applicable if suspend state
|
||||||
|
FPS source is selected as FPS0, FPS1 or
|
||||||
|
FPS2.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
--------
|
||||||
|
#include <dt-bindings/mfd/max77620.h>
|
||||||
|
...
|
||||||
|
max77620@3c {
|
||||||
|
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&spmic_default>;
|
||||||
|
|
||||||
|
spmic_default: pinmux@0 {
|
||||||
|
pin_gpio0 {
|
||||||
|
pins = "gpio0";
|
||||||
|
function = "gpio";
|
||||||
|
};
|
||||||
|
|
||||||
|
pin_gpio1 {
|
||||||
|
pins = "gpio1";
|
||||||
|
function = "fps-out";
|
||||||
|
maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
pin_gpio2 {
|
||||||
|
pins = "gpio2";
|
||||||
|
function = "fps-out";
|
||||||
|
maxim,active-fps-source = <MAX77620_FPS_SRC_1>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,152 @@
|
||||||
|
Qualcomm MDM9615 TLMM block
|
||||||
|
|
||||||
|
This binding describes the Top Level Mode Multiplexer block found in the
|
||||||
|
MDM9615 platform.
|
||||||
|
|
||||||
|
- compatible:
|
||||||
|
Usage: required
|
||||||
|
Value type: <string>
|
||||||
|
Definition: must be "qcom,mdm9615-pinctrl"
|
||||||
|
|
||||||
|
- reg:
|
||||||
|
Usage: required
|
||||||
|
Value type: <prop-encoded-array>
|
||||||
|
Definition: the base address and size of the TLMM register space.
|
||||||
|
|
||||||
|
- interrupts:
|
||||||
|
Usage: required
|
||||||
|
Value type: <prop-encoded-array>
|
||||||
|
Definition: should specify the TLMM summary IRQ.
|
||||||
|
|
||||||
|
- interrupt-controller:
|
||||||
|
Usage: required
|
||||||
|
Value type: <none>
|
||||||
|
Definition: identifies this node as an interrupt controller
|
||||||
|
|
||||||
|
- #interrupt-cells:
|
||||||
|
Usage: required
|
||||||
|
Value type: <u32>
|
||||||
|
Definition: must be 2. Specifying the pin number and flags, as defined
|
||||||
|
in <dt-bindings/interrupt-controller/irq.h>
|
||||||
|
|
||||||
|
- gpio-controller:
|
||||||
|
Usage: required
|
||||||
|
Value type: <none>
|
||||||
|
Definition: identifies this node as a gpio controller
|
||||||
|
|
||||||
|
- #gpio-cells:
|
||||||
|
Usage: required
|
||||||
|
Value type: <u32>
|
||||||
|
Definition: must be 2. Specifying the pin number and flags, as defined
|
||||||
|
in <dt-bindings/gpio/gpio.h>
|
||||||
|
|
||||||
|
Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
|
||||||
|
a general description of GPIO and interrupt bindings.
|
||||||
|
|
||||||
|
Please refer to pinctrl-bindings.txt in this directory for details of the
|
||||||
|
common pinctrl bindings used by client devices, including the meaning of the
|
||||||
|
phrase "pin configuration node".
|
||||||
|
|
||||||
|
The pin configuration nodes act as a container for an arbitrary number of
|
||||||
|
subnodes. Each of these subnodes represents some desired configuration for a
|
||||||
|
pin, a group, or a list of pins or groups. This configuration can include the
|
||||||
|
mux function to select on those pin(s)/group(s), and various pin configuration
|
||||||
|
parameters, such as pull-up, drive strength, etc.
|
||||||
|
|
||||||
|
|
||||||
|
PIN CONFIGURATION NODES:
|
||||||
|
|
||||||
|
The name of each subnode is not important; all subnodes should be enumerated
|
||||||
|
and processed purely based on their content.
|
||||||
|
|
||||||
|
Each subnode only affects those parameters that are explicitly listed. In
|
||||||
|
other words, a subnode that lists a mux function but no pin configuration
|
||||||
|
parameters implies no information about any pin configuration parameters.
|
||||||
|
Similarly, a pin subnode that describes a pullup parameter implies no
|
||||||
|
information about e.g. the mux function.
|
||||||
|
|
||||||
|
|
||||||
|
The following generic properties as defined in pinctrl-bindings.txt are valid
|
||||||
|
to specify in a pin configuration subnode:
|
||||||
|
|
||||||
|
- pins:
|
||||||
|
Usage: required
|
||||||
|
Value type: <string-array>
|
||||||
|
Definition: List of gpio pins affected by the properties specified in
|
||||||
|
this subnode. Valid pins are:
|
||||||
|
gpio0-gpio87
|
||||||
|
|
||||||
|
- function:
|
||||||
|
Usage: required
|
||||||
|
Value type: <string>
|
||||||
|
Definition: Specify the alternative function to be configured for the
|
||||||
|
specified pins.
|
||||||
|
Valid values are:
|
||||||
|
gpio, gsbi2_i2c, gsbi3, gsbi4, gsbi5_i2c, gsbi5_uart,
|
||||||
|
sdc2, ebi2_lcdc, ps_hold, prim_audio, sec_audio,
|
||||||
|
cdc_mclk
|
||||||
|
|
||||||
|
- bias-disable:
|
||||||
|
Usage: optional
|
||||||
|
Value type: <none>
|
||||||
|
Definition: The specified pins should be configued as no pull.
|
||||||
|
|
||||||
|
- bias-pull-down:
|
||||||
|
Usage: optional
|
||||||
|
Value type: <none>
|
||||||
|
Definition: The specified pins should be configued as pull down.
|
||||||
|
|
||||||
|
- bias-pull-up:
|
||||||
|
Usage: optional
|
||||||
|
Value type: <none>
|
||||||
|
Definition: The specified pins should be configued as pull up.
|
||||||
|
|
||||||
|
- output-high:
|
||||||
|
Usage: optional
|
||||||
|
Value type: <none>
|
||||||
|
Definition: The specified pins are configured in output mode, driven
|
||||||
|
high.
|
||||||
|
|
||||||
|
- output-low:
|
||||||
|
Usage: optional
|
||||||
|
Value type: <none>
|
||||||
|
Definition: The specified pins are configured in output mode, driven
|
||||||
|
low.
|
||||||
|
|
||||||
|
- drive-strength:
|
||||||
|
Usage: optional
|
||||||
|
Value type: <u32>
|
||||||
|
Definition: Selects the drive strength for the specified pins, in mA.
|
||||||
|
Valid values are: 2, 4, 6, 8, 10, 12, 14 and 16
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
msmgpio: pinctrl@800000 {
|
||||||
|
compatible = "qcom,mdm9615-pinctrl";
|
||||||
|
reg = <0x800000 0x4000>;
|
||||||
|
|
||||||
|
gpio-controller;
|
||||||
|
#gpio-cells = <2>;
|
||||||
|
interrupt-controller;
|
||||||
|
#interrupt-cells = <2>;
|
||||||
|
interrupts = <0 16 0x4>;
|
||||||
|
|
||||||
|
gsbi8_uart: gsbi8-uart {
|
||||||
|
mux {
|
||||||
|
pins = "gpio34", "gpio35";
|
||||||
|
function = "gsbi8";
|
||||||
|
};
|
||||||
|
|
||||||
|
tx {
|
||||||
|
pins = "gpio34";
|
||||||
|
drive-strength = <4>;
|
||||||
|
bias-disable;
|
||||||
|
};
|
||||||
|
|
||||||
|
rx {
|
||||||
|
pins = "gpio35";
|
||||||
|
drive-strength = <2>;
|
||||||
|
bias-pull-up;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
|
@ -52,7 +52,7 @@ Valid values for function are:
|
||||||
gsbi2_spi_cs3_n, gsbi3, gsbi3_spi_cs1_n, gsbi3_spi_cs2_n, gsbi3_spi_cs3_n,
|
gsbi2_spi_cs3_n, gsbi3, gsbi3_spi_cs1_n, gsbi3_spi_cs2_n, gsbi3_spi_cs3_n,
|
||||||
gsbi4, gsbi5, gsbi6, gsbi7, gsbi8, gsbi9, gsbi10, gsbi11, gsbi12, hdmi, i2s,
|
gsbi4, gsbi5, gsbi6, gsbi7, gsbi8, gsbi9, gsbi10, gsbi11, gsbi12, hdmi, i2s,
|
||||||
lcdc, mdp_vsync, mi2s, pcm, ps_hold, sdc1, sdc2, sdc5, tsif1, tsif2, usb_fs1,
|
lcdc, mdp_vsync, mi2s, pcm, ps_hold, sdc1, sdc2, sdc5, tsif1, tsif2, usb_fs1,
|
||||||
usb_fs1_oe_n, usb_fs2, usb_fs2_oe_n, vfe, vsens_alarm,
|
usb_fs1_oe_n, usb_fs2, usb_fs2_oe_n, vfe, vsens_alarm, ebi2, ebi2cs
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,9 @@ Valid values for pins are:
|
||||||
sdc1_clk, sdc1_cmd, sdc1_data, sdc2_clk, sdc2_cmd, sdc2_data
|
sdc1_clk, sdc1_cmd, sdc1_data, sdc2_clk, sdc2_cmd, sdc2_data
|
||||||
Supports bias and drive-strength
|
Supports bias and drive-strength
|
||||||
|
|
||||||
|
hsic_data, hsic_strobe
|
||||||
|
Supports only mux
|
||||||
|
|
||||||
Valid values for function are:
|
Valid values for function are:
|
||||||
cci_i2c0, cci_i2c1, uim1, uim2, uim_batt_alarm,
|
cci_i2c0, cci_i2c1, uim1, uim2, uim_batt_alarm,
|
||||||
blsp_uim1, blsp_uart1, blsp_i2c1, blsp_spi1,
|
blsp_uim1, blsp_uart1, blsp_i2c1, blsp_spi1,
|
||||||
|
@ -70,7 +73,7 @@ Valid values for function are:
|
||||||
cam_mckl0, cam_mclk1, cam_mclk2, cam_mclk3, mdp_vsync, hdmi_cec, hdmi_ddc,
|
cam_mckl0, cam_mclk1, cam_mclk2, cam_mclk3, mdp_vsync, hdmi_cec, hdmi_ddc,
|
||||||
hdmi_hpd, edp_hpd, gp_pdm0, gp_pdm1, gp_pdm2, gp_pdm3, gp0_clk, gp1_clk,
|
hdmi_hpd, edp_hpd, gp_pdm0, gp_pdm1, gp_pdm2, gp_pdm3, gp0_clk, gp1_clk,
|
||||||
gp_mn, tsif1, tsif2, hsic, grfc, audio_ref_clk, qua_mi2s, pri_mi2s, spkr_mi2s,
|
gp_mn, tsif1, tsif2, hsic, grfc, audio_ref_clk, qua_mi2s, pri_mi2s, spkr_mi2s,
|
||||||
ter_mi2s, sec_mi2s, bt, fm, wlan, slimbus, gpio
|
ter_mi2s, sec_mi2s, bt, fm, wlan, slimbus, hsic_ctl, gpio
|
||||||
|
|
||||||
(Note that this is not yet the complete list of functions)
|
(Note that this is not yet the complete list of functions)
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ of PMIC's from Qualcomm.
|
||||||
Definition: Should contain one of:
|
Definition: Should contain one of:
|
||||||
"qcom,pm8018-mpp",
|
"qcom,pm8018-mpp",
|
||||||
"qcom,pm8038-mpp",
|
"qcom,pm8038-mpp",
|
||||||
|
"qcom,pm8058-mpp",
|
||||||
"qcom,pm8821-mpp",
|
"qcom,pm8821-mpp",
|
||||||
"qcom,pm8841-mpp",
|
"qcom,pm8841-mpp",
|
||||||
"qcom,pm8916-mpp",
|
"qcom,pm8916-mpp",
|
||||||
|
|
|
@ -72,7 +72,7 @@ Pin Configuration Node Properties:
|
||||||
|
|
||||||
The pin configuration parameters use the generic pinconf bindings defined in
|
The pin configuration parameters use the generic pinconf bindings defined in
|
||||||
pinctrl-bindings.txt in this directory. The supported parameters are
|
pinctrl-bindings.txt in this directory. The supported parameters are
|
||||||
bias-disable, bias-pull-up, bias-pull-down, drive strength and power-source. For
|
bias-disable, bias-pull-up, bias-pull-down, drive-strength and power-source. For
|
||||||
pins that have a configurable I/O voltage, the power-source value should be the
|
pins that have a configurable I/O voltage, the power-source value should be the
|
||||||
nominal I/O voltage in millivolts.
|
nominal I/O voltage in millivolts.
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ Pin controller node:
|
||||||
Required properies:
|
Required properies:
|
||||||
- compatible: value should be one of the following:
|
- compatible: value should be one of the following:
|
||||||
(a) "st,stm32f429-pinctrl"
|
(a) "st,stm32f429-pinctrl"
|
||||||
|
(b) "st,stm32f746-pinctrl"
|
||||||
- #address-cells: The value of this property must be 1
|
- #address-cells: The value of this property must be 1
|
||||||
- #size-cells : The value of this property must be 1
|
- #size-cells : The value of this property must be 1
|
||||||
- ranges : defines mapping between pin controller node (parent) to
|
- ranges : defines mapping between pin controller node (parent) to
|
||||||
|
|
|
@ -286,13 +286,13 @@ see the section named "pin control requests from drivers" and
|
||||||
"drivers needing both pin control and GPIOs" below for details. But in some
|
"drivers needing both pin control and GPIOs" below for details. But in some
|
||||||
situations a cross-subsystem mapping between pins and GPIOs is needed.
|
situations a cross-subsystem mapping between pins and GPIOs is needed.
|
||||||
|
|
||||||
Since the pin controller subsystem have its pinspace local to the pin
|
Since the pin controller subsystem has its pinspace local to the pin controller
|
||||||
controller we need a mapping so that the pin control subsystem can figure out
|
we need a mapping so that the pin control subsystem can figure out which pin
|
||||||
which pin controller handles control of a certain GPIO pin. Since a single
|
controller handles control of a certain GPIO pin. Since a single pin controller
|
||||||
pin controller may be muxing several GPIO ranges (typically SoCs that have
|
may be muxing several GPIO ranges (typically SoCs that have one set of pins,
|
||||||
one set of pins, but internally several GPIO silicon blocks, each modelled as
|
but internally several GPIO silicon blocks, each modelled as a struct
|
||||||
a struct gpio_chip) any number of GPIO ranges can be added to a pin controller
|
gpio_chip) any number of GPIO ranges can be added to a pin controller instance
|
||||||
instance like this:
|
like this:
|
||||||
|
|
||||||
struct gpio_chip chip_a;
|
struct gpio_chip chip_a;
|
||||||
struct gpio_chip chip_b;
|
struct gpio_chip chip_b;
|
||||||
|
@ -493,12 +493,12 @@ Definitions:
|
||||||
- The combination of a FUNCTION and a PIN GROUP determine a certain function
|
- The combination of a FUNCTION and a PIN GROUP determine a certain function
|
||||||
for a certain set of pins. The knowledge of the functions and pin groups
|
for a certain set of pins. The knowledge of the functions and pin groups
|
||||||
and their machine-specific particulars are kept inside the pinmux driver,
|
and their machine-specific particulars are kept inside the pinmux driver,
|
||||||
from the outside only the enumerators are known, and the driver core can:
|
from the outside only the enumerators are known, and the driver core can
|
||||||
|
request:
|
||||||
|
|
||||||
- Request the name of a function with a certain selector (>= 0)
|
- The name of a function with a certain selector (>= 0)
|
||||||
- A list of groups associated with a certain function
|
- A list of groups associated with a certain function
|
||||||
- Request that a certain group in that list to be activated for a certain
|
- That a certain group in that list to be activated for a certain function
|
||||||
function
|
|
||||||
|
|
||||||
As already described above, pin groups are in turn self-descriptive, so
|
As already described above, pin groups are in turn self-descriptive, so
|
||||||
the core will retrieve the actual pin range in a certain group from the
|
the core will retrieve the actual pin range in a certain group from the
|
||||||
|
@ -831,7 +831,7 @@ separate memory range only intended for GPIO driving, and the register
|
||||||
range dealing with pin config and pin multiplexing get placed into a
|
range dealing with pin config and pin multiplexing get placed into a
|
||||||
different memory range and a separate section of the data sheet.
|
different memory range and a separate section of the data sheet.
|
||||||
|
|
||||||
A flag "strict" in struct pinctrl_desc is available to check and deny
|
A flag "strict" in struct pinmux_ops is available to check and deny
|
||||||
simultaneous access to the same pin from GPIO and pin multiplexing
|
simultaneous access to the same pin from GPIO and pin multiplexing
|
||||||
consumers on hardware of this type. The pinctrl driver should set this flag
|
consumers on hardware of this type. The pinctrl driver should set this flag
|
||||||
accordingly.
|
accordingly.
|
||||||
|
|
|
@ -35,7 +35,7 @@ config PINCTRL_ADI2
|
||||||
machine and arch are selected to build.
|
machine and arch are selected to build.
|
||||||
|
|
||||||
config PINCTRL_AS3722
|
config PINCTRL_AS3722
|
||||||
bool "Pinctrl and GPIO driver for ams AS3722 PMIC"
|
tristate "Pinctrl and GPIO driver for ams AS3722 PMIC"
|
||||||
depends on MFD_AS3722 && GPIOLIB
|
depends on MFD_AS3722 && GPIOLIB
|
||||||
select PINMUX
|
select PINMUX
|
||||||
select GENERIC_PINCONF
|
select GENERIC_PINCONF
|
||||||
|
@ -129,6 +129,17 @@ config PINCTRL_MESON
|
||||||
select OF_GPIO
|
select OF_GPIO
|
||||||
select REGMAP_MMIO
|
select REGMAP_MMIO
|
||||||
|
|
||||||
|
config PINCTRL_OXNAS
|
||||||
|
bool
|
||||||
|
depends on OF
|
||||||
|
select PINMUX
|
||||||
|
select PINCONF
|
||||||
|
select GENERIC_PINCONF
|
||||||
|
select GPIOLIB
|
||||||
|
select OF_GPIO
|
||||||
|
select GPIOLIB_IRQCHIP
|
||||||
|
select MFD_SYSCON
|
||||||
|
|
||||||
config PINCTRL_ROCKCHIP
|
config PINCTRL_ROCKCHIP
|
||||||
bool
|
bool
|
||||||
select PINMUX
|
select PINMUX
|
||||||
|
@ -196,8 +207,19 @@ config PINCTRL_COH901
|
||||||
COH 901 335 and COH 901 571/3. They contain 3, 5 or 7
|
COH 901 335 and COH 901 571/3. They contain 3, 5 or 7
|
||||||
ports of 8 GPIO pins each.
|
ports of 8 GPIO pins each.
|
||||||
|
|
||||||
|
config PINCTRL_MAX77620
|
||||||
|
tristate "MAX77620/MAX20024 Pincontrol support"
|
||||||
|
depends on MFD_MAX77620
|
||||||
|
select PINMUX
|
||||||
|
select GENERIC_PINCONF
|
||||||
|
help
|
||||||
|
Say Yes here to enable Pin control support for Maxim PMIC MAX77620.
|
||||||
|
This PMIC has 8 GPIO pins that work as GPIO as well as special
|
||||||
|
function in alternate mode. This driver also configure push-pull,
|
||||||
|
open drain, FPS slots etc.
|
||||||
|
|
||||||
config PINCTRL_PALMAS
|
config PINCTRL_PALMAS
|
||||||
bool "Pinctrl driver for the PALMAS Series MFD devices"
|
tristate "Pinctrl driver for the PALMAS Series MFD devices"
|
||||||
depends on OF && MFD_PALMAS
|
depends on OF && MFD_PALMAS
|
||||||
select PINMUX
|
select PINMUX
|
||||||
select GENERIC_PINCONF
|
select GENERIC_PINCONF
|
||||||
|
|
|
@ -16,7 +16,9 @@ obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o
|
||||||
obj-$(CONFIG_PINCTRL_AMD) += pinctrl-amd.o
|
obj-$(CONFIG_PINCTRL_AMD) += pinctrl-amd.o
|
||||||
obj-$(CONFIG_PINCTRL_DIGICOLOR) += pinctrl-digicolor.o
|
obj-$(CONFIG_PINCTRL_DIGICOLOR) += pinctrl-digicolor.o
|
||||||
obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o
|
obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o
|
||||||
|
obj-$(CONFIG_PINCTRL_MAX77620) += pinctrl-max77620.o
|
||||||
obj-$(CONFIG_PINCTRL_MESON) += meson/
|
obj-$(CONFIG_PINCTRL_MESON) += meson/
|
||||||
|
obj-$(CONFIG_PINCTRL_OXNAS) += pinctrl-oxnas.o
|
||||||
obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o
|
obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o
|
||||||
obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-pic32.o
|
obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-pic32.o
|
||||||
obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o
|
obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o
|
||||||
|
@ -35,7 +37,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o
|
||||||
obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
|
obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
|
||||||
obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o
|
obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o
|
||||||
|
|
||||||
obj-$(CONFIG_ARCH_BCM) += bcm/
|
obj-y += bcm/
|
||||||
obj-$(CONFIG_PINCTRL_BERLIN) += berlin/
|
obj-$(CONFIG_PINCTRL_BERLIN) += berlin/
|
||||||
obj-y += freescale/
|
obj-y += freescale/
|
||||||
obj-$(CONFIG_X86) += intel/
|
obj-$(CONFIG_X86) += intel/
|
||||||
|
|
|
@ -60,6 +60,7 @@ config PINCTRL_IPROC_GPIO
|
||||||
config PINCTRL_CYGNUS_MUX
|
config PINCTRL_CYGNUS_MUX
|
||||||
bool "Broadcom Cygnus IOMUX driver"
|
bool "Broadcom Cygnus IOMUX driver"
|
||||||
depends on (ARCH_BCM_CYGNUS || COMPILE_TEST)
|
depends on (ARCH_BCM_CYGNUS || COMPILE_TEST)
|
||||||
|
depends on OF
|
||||||
select PINMUX
|
select PINMUX
|
||||||
select GENERIC_PINCONF
|
select GENERIC_PINCONF
|
||||||
default ARCH_BCM_CYGNUS
|
default ARCH_BCM_CYGNUS
|
||||||
|
@ -99,3 +100,17 @@ config PINCTRL_NS2_MUX
|
||||||
|
|
||||||
The Broadcom Northstar2 IOMUX driver supports group based IOMUX
|
The Broadcom Northstar2 IOMUX driver supports group based IOMUX
|
||||||
configuration.
|
configuration.
|
||||||
|
|
||||||
|
config PINCTRL_NSP_MUX
|
||||||
|
bool "Broadcom NSP IOMUX driver"
|
||||||
|
depends on (ARCH_BCM_NSP || COMPILE_TEST)
|
||||||
|
depends on OF
|
||||||
|
select PINMUX
|
||||||
|
select GENERIC_PINCONF
|
||||||
|
default ARCH_BCM_NSP
|
||||||
|
help
|
||||||
|
Say yes here to enable the Broadcom NSP SOC IOMUX driver.
|
||||||
|
|
||||||
|
The Broadcom Northstar Plus IOMUX driver supports pin based IOMUX
|
||||||
|
configuration, with certain individual pins can be overridden
|
||||||
|
to GPIO function.
|
||||||
|
|
|
@ -6,3 +6,4 @@ obj-$(CONFIG_PINCTRL_IPROC_GPIO) += pinctrl-iproc-gpio.o
|
||||||
obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o
|
obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o
|
||||||
obj-$(CONFIG_PINCTRL_NSP_GPIO) += pinctrl-nsp-gpio.o
|
obj-$(CONFIG_PINCTRL_NSP_GPIO) += pinctrl-nsp-gpio.o
|
||||||
obj-$(CONFIG_PINCTRL_NS2_MUX) += pinctrl-ns2-mux.o
|
obj-$(CONFIG_PINCTRL_NS2_MUX) += pinctrl-ns2-mux.o
|
||||||
|
obj-$(CONFIG_PINCTRL_NSP_MUX) += pinctrl-nsp-mux.o
|
||||||
|
|
|
@ -66,6 +66,14 @@
|
||||||
#define GPIO_DRV_STRENGTH_BITS 3
|
#define GPIO_DRV_STRENGTH_BITS 3
|
||||||
#define GPIO_DRV_STRENGTH_BIT_MASK ((1 << GPIO_DRV_STRENGTH_BITS) - 1)
|
#define GPIO_DRV_STRENGTH_BIT_MASK ((1 << GPIO_DRV_STRENGTH_BITS) - 1)
|
||||||
|
|
||||||
|
enum iproc_pinconf_param {
|
||||||
|
IPROC_PINCONF_DRIVE_STRENGTH = 0,
|
||||||
|
IPROC_PINCONF_BIAS_DISABLE,
|
||||||
|
IPROC_PINCONF_BIAS_PULL_UP,
|
||||||
|
IPROC_PINCONF_BIAS_PULL_DOWN,
|
||||||
|
IPROC_PINCON_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Iproc GPIO core
|
* Iproc GPIO core
|
||||||
*
|
*
|
||||||
|
@ -78,6 +86,10 @@
|
||||||
* @num_banks: number of GPIO banks, each bank supports up to 32 GPIOs
|
* @num_banks: number of GPIO banks, each bank supports up to 32 GPIOs
|
||||||
* @pinmux_is_supported: flag to indicate this GPIO controller contains pins
|
* @pinmux_is_supported: flag to indicate this GPIO controller contains pins
|
||||||
* that can be individually muxed to GPIO
|
* that can be individually muxed to GPIO
|
||||||
|
* @pinconf_disable: contains a list of PINCONF parameters that need to be
|
||||||
|
* disabled
|
||||||
|
* @nr_pinconf_disable: total number of PINCONF parameters that need to be
|
||||||
|
* disabled
|
||||||
* @pctl: pointer to pinctrl_dev
|
* @pctl: pointer to pinctrl_dev
|
||||||
* @pctldesc: pinctrl descriptor
|
* @pctldesc: pinctrl descriptor
|
||||||
*/
|
*/
|
||||||
|
@ -94,6 +106,9 @@ struct iproc_gpio {
|
||||||
|
|
||||||
bool pinmux_is_supported;
|
bool pinmux_is_supported;
|
||||||
|
|
||||||
|
enum pin_config_param *pinconf_disable;
|
||||||
|
unsigned int nr_pinconf_disable;
|
||||||
|
|
||||||
struct pinctrl_dev *pctl;
|
struct pinctrl_dev *pctl;
|
||||||
struct pinctrl_desc pctldesc;
|
struct pinctrl_desc pctldesc;
|
||||||
};
|
};
|
||||||
|
@ -360,6 +375,65 @@ static int iproc_gpio_get(struct gpio_chip *gc, unsigned gpio)
|
||||||
return !!(readl(chip->base + offset) & BIT(shift));
|
return !!(readl(chip->base + offset) & BIT(shift));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mapping of the iProc PINCONF parameters to the generic pin configuration
|
||||||
|
* parameters
|
||||||
|
*/
|
||||||
|
static const enum pin_config_param iproc_pinconf_disable_map[] = {
|
||||||
|
[IPROC_PINCONF_DRIVE_STRENGTH] = PIN_CONFIG_DRIVE_STRENGTH,
|
||||||
|
[IPROC_PINCONF_BIAS_DISABLE] = PIN_CONFIG_BIAS_DISABLE,
|
||||||
|
[IPROC_PINCONF_BIAS_PULL_UP] = PIN_CONFIG_BIAS_PULL_UP,
|
||||||
|
[IPROC_PINCONF_BIAS_PULL_DOWN] = PIN_CONFIG_BIAS_PULL_DOWN,
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool iproc_pinconf_param_is_disabled(struct iproc_gpio *chip,
|
||||||
|
enum pin_config_param param)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (!chip->nr_pinconf_disable)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (i = 0; i < chip->nr_pinconf_disable; i++)
|
||||||
|
if (chip->pinconf_disable[i] == param)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int iproc_pinconf_disable_map_create(struct iproc_gpio *chip,
|
||||||
|
unsigned long disable_mask)
|
||||||
|
{
|
||||||
|
unsigned int map_size = ARRAY_SIZE(iproc_pinconf_disable_map);
|
||||||
|
unsigned int bit, nbits = 0;
|
||||||
|
|
||||||
|
/* figure out total number of PINCONF parameters to disable */
|
||||||
|
for_each_set_bit(bit, &disable_mask, map_size)
|
||||||
|
nbits++;
|
||||||
|
|
||||||
|
if (!nbits)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate an array to store PINCONF parameters that need to be
|
||||||
|
* disabled
|
||||||
|
*/
|
||||||
|
chip->pinconf_disable = devm_kcalloc(chip->dev, nbits,
|
||||||
|
sizeof(*chip->pinconf_disable),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!chip->pinconf_disable)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
chip->nr_pinconf_disable = nbits;
|
||||||
|
|
||||||
|
/* now store these parameters */
|
||||||
|
nbits = 0;
|
||||||
|
for_each_set_bit(bit, &disable_mask, map_size)
|
||||||
|
chip->pinconf_disable[nbits++] = iproc_pinconf_disable_map[bit];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int iproc_get_groups_count(struct pinctrl_dev *pctldev)
|
static int iproc_get_groups_count(struct pinctrl_dev *pctldev)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -500,6 +574,9 @@ static int iproc_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
|
||||||
bool disable, pull_up;
|
bool disable, pull_up;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (iproc_pinconf_param_is_disabled(chip, param))
|
||||||
|
return -ENOTSUPP;
|
||||||
|
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case PIN_CONFIG_BIAS_DISABLE:
|
case PIN_CONFIG_BIAS_DISABLE:
|
||||||
iproc_gpio_get_pull(chip, gpio, &disable, &pull_up);
|
iproc_gpio_get_pull(chip, gpio, &disable, &pull_up);
|
||||||
|
@ -548,6 +625,10 @@ static int iproc_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
|
||||||
|
|
||||||
for (i = 0; i < num_configs; i++) {
|
for (i = 0; i < num_configs; i++) {
|
||||||
param = pinconf_to_config_param(configs[i]);
|
param = pinconf_to_config_param(configs[i]);
|
||||||
|
|
||||||
|
if (iproc_pinconf_param_is_disabled(chip, param))
|
||||||
|
return -ENOTSUPP;
|
||||||
|
|
||||||
arg = pinconf_to_config_argument(configs[i]);
|
arg = pinconf_to_config_argument(configs[i]);
|
||||||
|
|
||||||
switch (param) {
|
switch (param) {
|
||||||
|
@ -633,11 +714,13 @@ static int iproc_gpio_register_pinconf(struct iproc_gpio *chip)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id iproc_gpio_of_match[] = {
|
static const struct of_device_id iproc_gpio_of_match[] = {
|
||||||
|
{ .compatible = "brcm,iproc-gpio" },
|
||||||
{ .compatible = "brcm,cygnus-ccm-gpio" },
|
{ .compatible = "brcm,cygnus-ccm-gpio" },
|
||||||
{ .compatible = "brcm,cygnus-asiu-gpio" },
|
{ .compatible = "brcm,cygnus-asiu-gpio" },
|
||||||
{ .compatible = "brcm,cygnus-crmu-gpio" },
|
{ .compatible = "brcm,cygnus-crmu-gpio" },
|
||||||
{ .compatible = "brcm,iproc-gpio" },
|
{ .compatible = "brcm,iproc-nsp-gpio" },
|
||||||
{ }
|
{ .compatible = "brcm,iproc-stingray-gpio" },
|
||||||
|
{ /* sentinel */ }
|
||||||
};
|
};
|
||||||
|
|
||||||
static int iproc_gpio_probe(struct platform_device *pdev)
|
static int iproc_gpio_probe(struct platform_device *pdev)
|
||||||
|
@ -646,8 +729,17 @@ static int iproc_gpio_probe(struct platform_device *pdev)
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
struct iproc_gpio *chip;
|
struct iproc_gpio *chip;
|
||||||
struct gpio_chip *gc;
|
struct gpio_chip *gc;
|
||||||
u32 ngpios;
|
u32 ngpios, pinconf_disable_mask = 0;
|
||||||
int irq, ret;
|
int irq, ret;
|
||||||
|
bool no_pinconf = false;
|
||||||
|
|
||||||
|
/* NSP does not support drive strength config */
|
||||||
|
if (of_device_is_compatible(dev->of_node, "brcm,iproc-nsp-gpio"))
|
||||||
|
pinconf_disable_mask = BIT(IPROC_PINCONF_DRIVE_STRENGTH);
|
||||||
|
/* Stingray does not support pinconf in this controller */
|
||||||
|
else if (of_device_is_compatible(dev->of_node,
|
||||||
|
"brcm,iproc-stingray-gpio"))
|
||||||
|
no_pinconf = true;
|
||||||
|
|
||||||
chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
|
chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
|
||||||
if (!chip)
|
if (!chip)
|
||||||
|
@ -702,10 +794,22 @@ static int iproc_gpio_probe(struct platform_device *pdev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = iproc_gpio_register_pinconf(chip);
|
if (!no_pinconf) {
|
||||||
if (ret) {
|
ret = iproc_gpio_register_pinconf(chip);
|
||||||
dev_err(dev, "unable to register pinconf\n");
|
if (ret) {
|
||||||
goto err_rm_gpiochip;
|
dev_err(dev, "unable to register pinconf\n");
|
||||||
|
goto err_rm_gpiochip;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pinconf_disable_mask) {
|
||||||
|
ret = iproc_pinconf_disable_map_create(chip,
|
||||||
|
pinconf_disable_mask);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev,
|
||||||
|
"unable to create pinconf disable map\n");
|
||||||
|
goto err_rm_gpiochip;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* optional GPIO interrupt support */
|
/* optional GPIO interrupt support */
|
||||||
|
|
|
@ -1044,10 +1044,8 @@ static int ns2_pinmux_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
pinctrl->base0 = devm_ioremap_resource(&pdev->dev, res);
|
pinctrl->base0 = devm_ioremap_resource(&pdev->dev, res);
|
||||||
if (IS_ERR(pinctrl->base0)) {
|
if (IS_ERR(pinctrl->base0))
|
||||||
dev_err(&pdev->dev, "unable to map I/O space\n");
|
|
||||||
return PTR_ERR(pinctrl->base0);
|
return PTR_ERR(pinctrl->base0);
|
||||||
}
|
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||||
pinctrl->base1 = devm_ioremap_nocache(&pdev->dev, res->start,
|
pinctrl->base1 = devm_ioremap_nocache(&pdev->dev, res->start,
|
||||||
|
@ -1059,10 +1057,8 @@ static int ns2_pinmux_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
|
||||||
pinctrl->pinconf_base = devm_ioremap_resource(&pdev->dev, res);
|
pinctrl->pinconf_base = devm_ioremap_resource(&pdev->dev, res);
|
||||||
if (IS_ERR(pinctrl->pinconf_base)) {
|
if (IS_ERR(pinctrl->pinconf_base))
|
||||||
dev_err(&pdev->dev, "unable to map I/O space\n");
|
|
||||||
return PTR_ERR(pinctrl->pinconf_base);
|
return PTR_ERR(pinctrl->pinconf_base);
|
||||||
}
|
|
||||||
|
|
||||||
ret = ns2_mux_log_init(pinctrl);
|
ret = ns2_mux_log_init(pinctrl);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -1089,9 +1085,9 @@ static int ns2_pinmux_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
pinctrl->pctl = pinctrl_register(&ns2_pinctrl_desc, &pdev->dev,
|
pinctrl->pctl = pinctrl_register(&ns2_pinctrl_desc, &pdev->dev,
|
||||||
pinctrl);
|
pinctrl);
|
||||||
if (!pinctrl->pctl) {
|
if (IS_ERR(pinctrl->pctl)) {
|
||||||
dev_err(&pdev->dev, "unable to register IOMUX pinctrl\n");
|
dev_err(&pdev->dev, "unable to register IOMUX pinctrl\n");
|
||||||
return -EINVAL;
|
return PTR_ERR(pinctrl->pctl);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -458,13 +458,15 @@ static int nsp_gpio_get_strength(struct nsp_gpio *chip, unsigned gpio,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nsp_pin_config_group_get(struct pinctrl_dev *pctldev, unsigned selector,
|
static int nsp_pin_config_group_get(struct pinctrl_dev *pctldev,
|
||||||
|
unsigned selector,
|
||||||
unsigned long *config)
|
unsigned long *config)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nsp_pin_config_group_set(struct pinctrl_dev *pctldev, unsigned selector,
|
static int nsp_pin_config_group_set(struct pinctrl_dev *pctldev,
|
||||||
|
unsigned selector,
|
||||||
unsigned long *configs, unsigned num_configs)
|
unsigned long *configs, unsigned num_configs)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -0,0 +1,642 @@
|
||||||
|
/* Copyright (C) 2015 Broadcom Corporation
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation version 2.
|
||||||
|
*
|
||||||
|
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||||
|
* kind, whether express or implied; without even the implied warranty
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* This file contains the Northstar plus (NSP) IOMUX driver that supports
|
||||||
|
* group based PINMUX configuration. The Northstar plus IOMUX controller
|
||||||
|
* allows pins to be individually muxed to GPIO function. The NAND and MMC is
|
||||||
|
* a group based selection. The gpio_a 8 - 11 are muxed with gpio_b and pwm.
|
||||||
|
* To select PWM, one need to enable the corresponding gpio_b as well.
|
||||||
|
*
|
||||||
|
* gpio_a (8 - 11)
|
||||||
|
* +----------
|
||||||
|
* |
|
||||||
|
* gpio_a (8-11) | gpio_b (0 - 3)
|
||||||
|
* ------------------------+-------+----------
|
||||||
|
* |
|
||||||
|
* | pwm (0 - 3)
|
||||||
|
* +----------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/pinctrl/pinconf.h>
|
||||||
|
#include <linux/pinctrl/pinconf-generic.h>
|
||||||
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
#include <linux/pinctrl/pinmux.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
#include "../core.h"
|
||||||
|
#include "../pinctrl-utils.h"
|
||||||
|
|
||||||
|
#define NSP_MUX_BASE0 0x00
|
||||||
|
#define NSP_MUX_BASE1 0x01
|
||||||
|
#define NSP_MUX_BASE2 0x02
|
||||||
|
/*
|
||||||
|
* nsp IOMUX register description
|
||||||
|
*
|
||||||
|
* @base: base 0 or base 1
|
||||||
|
* @shift: bit shift for mux configuration of a group
|
||||||
|
* @mask: bit mask of the function
|
||||||
|
* @alt: alternate function to set to
|
||||||
|
*/
|
||||||
|
struct nsp_mux {
|
||||||
|
unsigned int base;
|
||||||
|
unsigned int shift;
|
||||||
|
unsigned int mask;
|
||||||
|
unsigned int alt;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Keep track of nsp IOMUX configuration and prevent double configuration
|
||||||
|
*
|
||||||
|
* @nsp_mux: nsp IOMUX register description
|
||||||
|
* @is_configured: flag to indicate whether a mux setting has already been
|
||||||
|
* configured
|
||||||
|
*/
|
||||||
|
struct nsp_mux_log {
|
||||||
|
struct nsp_mux mux;
|
||||||
|
bool is_configured;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Group based IOMUX configuration
|
||||||
|
*
|
||||||
|
* @name: name of the group
|
||||||
|
* @pins: array of pins used by this group
|
||||||
|
* @num_pins: total number of pins used by this group
|
||||||
|
* @mux: nsp group based IOMUX configuration
|
||||||
|
*/
|
||||||
|
struct nsp_pin_group {
|
||||||
|
const char *name;
|
||||||
|
const unsigned int *pins;
|
||||||
|
const unsigned int num_pins;
|
||||||
|
const struct nsp_mux mux;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* nsp mux function and supported pin groups
|
||||||
|
*
|
||||||
|
* @name: name of the function
|
||||||
|
* @groups: array of groups that can be supported by this function
|
||||||
|
* @num_groups: total number of groups that can be supported by this function
|
||||||
|
*/
|
||||||
|
struct nsp_pin_function {
|
||||||
|
const char *name;
|
||||||
|
const char * const *groups;
|
||||||
|
const unsigned int num_groups;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* nsp IOMUX pinctrl core
|
||||||
|
*
|
||||||
|
* @pctl: pointer to pinctrl_dev
|
||||||
|
* @dev: pointer to device
|
||||||
|
* @base0: first mux register
|
||||||
|
* @base1: second mux register
|
||||||
|
* @base2: third mux register
|
||||||
|
* @groups: pointer to array of groups
|
||||||
|
* @num_groups: total number of groups
|
||||||
|
* @functions: pointer to array of functions
|
||||||
|
* @num_functions: total number of functions
|
||||||
|
* @mux_log: pointer to the array of mux logs
|
||||||
|
* @lock: lock to protect register access
|
||||||
|
*/
|
||||||
|
struct nsp_pinctrl {
|
||||||
|
struct pinctrl_dev *pctl;
|
||||||
|
struct device *dev;
|
||||||
|
void __iomem *base0;
|
||||||
|
void __iomem *base1;
|
||||||
|
void __iomem *base2;
|
||||||
|
const struct nsp_pin_group *groups;
|
||||||
|
unsigned int num_groups;
|
||||||
|
const struct nsp_pin_function *functions;
|
||||||
|
unsigned int num_functions;
|
||||||
|
struct nsp_mux_log *mux_log;
|
||||||
|
spinlock_t lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Description of a pin in nsp
|
||||||
|
*
|
||||||
|
* @pin: pin number
|
||||||
|
* @name: pin name
|
||||||
|
* @gpio_select: reg data to select GPIO
|
||||||
|
*/
|
||||||
|
struct nsp_pin {
|
||||||
|
unsigned int pin;
|
||||||
|
char *name;
|
||||||
|
unsigned int gpio_select;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NSP_PIN_DESC(p, n, g) \
|
||||||
|
{ \
|
||||||
|
.pin = p, \
|
||||||
|
.name = n, \
|
||||||
|
.gpio_select = g, \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List of muxable pins in nsp
|
||||||
|
*/
|
||||||
|
static struct nsp_pin nsp_pins[] = {
|
||||||
|
NSP_PIN_DESC(0, "spi_clk", 1),
|
||||||
|
NSP_PIN_DESC(1, "spi_ss", 1),
|
||||||
|
NSP_PIN_DESC(2, "spi_mosi", 1),
|
||||||
|
NSP_PIN_DESC(3, "spi_miso", 1),
|
||||||
|
NSP_PIN_DESC(4, "scl", 1),
|
||||||
|
NSP_PIN_DESC(5, "sda", 1),
|
||||||
|
NSP_PIN_DESC(6, "mdc", 1),
|
||||||
|
NSP_PIN_DESC(7, "mdio", 1),
|
||||||
|
NSP_PIN_DESC(8, "pwm0", 1),
|
||||||
|
NSP_PIN_DESC(9, "pwm1", 1),
|
||||||
|
NSP_PIN_DESC(10, "pwm2", 1),
|
||||||
|
NSP_PIN_DESC(11, "pwm3", 1),
|
||||||
|
NSP_PIN_DESC(12, "uart1_rx", 1),
|
||||||
|
NSP_PIN_DESC(13, "uart1_tx", 1),
|
||||||
|
NSP_PIN_DESC(14, "uart1_cts", 1),
|
||||||
|
NSP_PIN_DESC(15, "uart1_rts", 1),
|
||||||
|
NSP_PIN_DESC(16, "uart2_rx", 1),
|
||||||
|
NSP_PIN_DESC(17, "uart2_tx", 1),
|
||||||
|
NSP_PIN_DESC(18, "synce", 0),
|
||||||
|
NSP_PIN_DESC(19, "sata0_led", 0),
|
||||||
|
NSP_PIN_DESC(20, "sata1_led", 0),
|
||||||
|
NSP_PIN_DESC(21, "xtal_out", 1),
|
||||||
|
NSP_PIN_DESC(22, "sdio_pwr", 1),
|
||||||
|
NSP_PIN_DESC(23, "sdio_en_1p8v", 1),
|
||||||
|
NSP_PIN_DESC(24, "gpio_24", 1),
|
||||||
|
NSP_PIN_DESC(25, "gpio_25", 1),
|
||||||
|
NSP_PIN_DESC(26, "p5_led0", 0),
|
||||||
|
NSP_PIN_DESC(27, "p5_led1", 0),
|
||||||
|
NSP_PIN_DESC(28, "gpio_28", 1),
|
||||||
|
NSP_PIN_DESC(29, "gpio_29", 1),
|
||||||
|
NSP_PIN_DESC(30, "gpio_30", 1),
|
||||||
|
NSP_PIN_DESC(31, "gpio_31", 1),
|
||||||
|
NSP_PIN_DESC(32, "nand_ale", 0),
|
||||||
|
NSP_PIN_DESC(33, "nand_ce0", 0),
|
||||||
|
NSP_PIN_DESC(34, "nand_r/b", 0),
|
||||||
|
NSP_PIN_DESC(35, "nand_dq0", 0),
|
||||||
|
NSP_PIN_DESC(36, "nand_dq1", 0),
|
||||||
|
NSP_PIN_DESC(37, "nand_dq2", 0),
|
||||||
|
NSP_PIN_DESC(38, "nand_dq3", 0),
|
||||||
|
NSP_PIN_DESC(39, "nand_dq4", 0),
|
||||||
|
NSP_PIN_DESC(40, "nand_dq5", 0),
|
||||||
|
NSP_PIN_DESC(41, "nand_dq6", 0),
|
||||||
|
NSP_PIN_DESC(42, "nand_dq7", 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List of groups of pins
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const unsigned int spi_pins[] = {0, 1, 2, 3};
|
||||||
|
static const unsigned int i2c_pins[] = {4, 5};
|
||||||
|
static const unsigned int mdio_pins[] = {6, 7};
|
||||||
|
static const unsigned int pwm0_pins[] = {8};
|
||||||
|
static const unsigned int gpio_b_0_pins[] = {8};
|
||||||
|
static const unsigned int pwm1_pins[] = {9};
|
||||||
|
static const unsigned int gpio_b_1_pins[] = {9};
|
||||||
|
static const unsigned int pwm2_pins[] = {10};
|
||||||
|
static const unsigned int gpio_b_2_pins[] = {10};
|
||||||
|
static const unsigned int pwm3_pins[] = {11};
|
||||||
|
static const unsigned int gpio_b_3_pins[] = {11};
|
||||||
|
static const unsigned int uart1_pins[] = {12, 13, 14, 15};
|
||||||
|
static const unsigned int uart2_pins[] = {16, 17};
|
||||||
|
static const unsigned int synce_pins[] = {18};
|
||||||
|
static const unsigned int sata0_led_pins[] = {19};
|
||||||
|
static const unsigned int sata1_led_pins[] = {20};
|
||||||
|
static const unsigned int xtal_out_pins[] = {21};
|
||||||
|
static const unsigned int sdio_pwr_pins[] = {22};
|
||||||
|
static const unsigned int sdio_1p8v_pins[] = {23};
|
||||||
|
static const unsigned int switch_p05_led0_pins[] = {26};
|
||||||
|
static const unsigned int switch_p05_led1_pins[] = {27};
|
||||||
|
static const unsigned int nand_pins[] = {32, 33, 34, 35, 36, 37, 38, 39,
|
||||||
|
40, 41, 42};
|
||||||
|
static const unsigned int emmc_pins[] = {32, 33, 34, 35, 36, 37, 38, 39,
|
||||||
|
40, 41, 42};
|
||||||
|
|
||||||
|
#define NSP_PIN_GROUP(group_name, ba, sh, ma, al) \
|
||||||
|
{ \
|
||||||
|
.name = __stringify(group_name) "_grp", \
|
||||||
|
.pins = group_name ## _pins, \
|
||||||
|
.num_pins = ARRAY_SIZE(group_name ## _pins), \
|
||||||
|
.mux = { \
|
||||||
|
.base = ba, \
|
||||||
|
.shift = sh, \
|
||||||
|
.mask = ma, \
|
||||||
|
.alt = al, \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List of nsp pin groups
|
||||||
|
*/
|
||||||
|
static const struct nsp_pin_group nsp_pin_groups[] = {
|
||||||
|
NSP_PIN_GROUP(spi, NSP_MUX_BASE0, 0, 0x0f, 0x00),
|
||||||
|
NSP_PIN_GROUP(i2c, NSP_MUX_BASE0, 3, 0x03, 0x00),
|
||||||
|
NSP_PIN_GROUP(mdio, NSP_MUX_BASE0, 5, 0x03, 0x00),
|
||||||
|
NSP_PIN_GROUP(gpio_b_0, NSP_MUX_BASE0, 7, 0x01, 0x00),
|
||||||
|
NSP_PIN_GROUP(pwm0, NSP_MUX_BASE1, 0, 0x01, 0x01),
|
||||||
|
NSP_PIN_GROUP(gpio_b_1, NSP_MUX_BASE0, 8, 0x01, 0x00),
|
||||||
|
NSP_PIN_GROUP(pwm1, NSP_MUX_BASE1, 1, 0x01, 0x01),
|
||||||
|
NSP_PIN_GROUP(gpio_b_2, NSP_MUX_BASE0, 9, 0x01, 0x00),
|
||||||
|
NSP_PIN_GROUP(pwm2, NSP_MUX_BASE1, 2, 0x01, 0x01),
|
||||||
|
NSP_PIN_GROUP(gpio_b_3, NSP_MUX_BASE0, 10, 0x01, 0x00),
|
||||||
|
NSP_PIN_GROUP(pwm3, NSP_MUX_BASE1, 3, 0x01, 0x01),
|
||||||
|
NSP_PIN_GROUP(uart1, NSP_MUX_BASE0, 11, 0x0f, 0x00),
|
||||||
|
NSP_PIN_GROUP(uart2, NSP_MUX_BASE0, 15, 0x03, 0x00),
|
||||||
|
NSP_PIN_GROUP(synce, NSP_MUX_BASE0, 17, 0x01, 0x01),
|
||||||
|
NSP_PIN_GROUP(sata0_led, NSP_MUX_BASE0, 18, 0x01, 0x01),
|
||||||
|
NSP_PIN_GROUP(sata1_led, NSP_MUX_BASE0, 19, 0x01, 0x01),
|
||||||
|
NSP_PIN_GROUP(xtal_out, NSP_MUX_BASE0, 20, 0x01, 0x00),
|
||||||
|
NSP_PIN_GROUP(sdio_pwr, NSP_MUX_BASE0, 21, 0x01, 0x00),
|
||||||
|
NSP_PIN_GROUP(sdio_1p8v, NSP_MUX_BASE0, 22, 0x01, 0x00),
|
||||||
|
NSP_PIN_GROUP(switch_p05_led0, NSP_MUX_BASE0, 26, 0x01, 0x01),
|
||||||
|
NSP_PIN_GROUP(switch_p05_led1, NSP_MUX_BASE0, 27, 0x01, 0x01),
|
||||||
|
NSP_PIN_GROUP(nand, NSP_MUX_BASE2, 0, 0x01, 0x00),
|
||||||
|
NSP_PIN_GROUP(emmc, NSP_MUX_BASE2, 0, 0x01, 0x01)
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List of groups supported by functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const char * const spi_grps[] = {"spi_grp"};
|
||||||
|
static const char * const i2c_grps[] = {"i2c_grp"};
|
||||||
|
static const char * const mdio_grps[] = {"mdio_grp"};
|
||||||
|
static const char * const pwm_grps[] = {"pwm0_grp", "pwm1_grp", "pwm2_grp"
|
||||||
|
, "pwm3_grp"};
|
||||||
|
static const char * const gpio_b_grps[] = {"gpio_b_0_grp", "gpio_b_1_grp",
|
||||||
|
"gpio_b_2_grp", "gpio_b_3_grp"};
|
||||||
|
static const char * const uart1_grps[] = {"uart1_grp"};
|
||||||
|
static const char * const uart2_grps[] = {"uart2_grp"};
|
||||||
|
static const char * const synce_grps[] = {"synce_grp"};
|
||||||
|
static const char * const sata_led_grps[] = {"sata0_led_grp", "sata1_led_grp"};
|
||||||
|
static const char * const xtal_out_grps[] = {"xtal_out_grp"};
|
||||||
|
static const char * const sdio_grps[] = {"sdio_pwr_grp", "sdio_1p8v_grp"};
|
||||||
|
static const char * const switch_led_grps[] = {"switch_p05_led0_grp",
|
||||||
|
"switch_p05_led1_grp"};
|
||||||
|
static const char * const nand_grps[] = {"nand_grp"};
|
||||||
|
static const char * const emmc_grps[] = {"emmc_grp"};
|
||||||
|
|
||||||
|
#define NSP_PIN_FUNCTION(func) \
|
||||||
|
{ \
|
||||||
|
.name = #func, \
|
||||||
|
.groups = func ## _grps, \
|
||||||
|
.num_groups = ARRAY_SIZE(func ## _grps), \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List of supported functions in nsp
|
||||||
|
*/
|
||||||
|
static const struct nsp_pin_function nsp_pin_functions[] = {
|
||||||
|
NSP_PIN_FUNCTION(spi),
|
||||||
|
NSP_PIN_FUNCTION(i2c),
|
||||||
|
NSP_PIN_FUNCTION(mdio),
|
||||||
|
NSP_PIN_FUNCTION(pwm),
|
||||||
|
NSP_PIN_FUNCTION(gpio_b),
|
||||||
|
NSP_PIN_FUNCTION(uart1),
|
||||||
|
NSP_PIN_FUNCTION(uart2),
|
||||||
|
NSP_PIN_FUNCTION(synce),
|
||||||
|
NSP_PIN_FUNCTION(sata_led),
|
||||||
|
NSP_PIN_FUNCTION(xtal_out),
|
||||||
|
NSP_PIN_FUNCTION(sdio),
|
||||||
|
NSP_PIN_FUNCTION(switch_led),
|
||||||
|
NSP_PIN_FUNCTION(nand),
|
||||||
|
NSP_PIN_FUNCTION(emmc)
|
||||||
|
};
|
||||||
|
|
||||||
|
static int nsp_get_groups_count(struct pinctrl_dev *pctrl_dev)
|
||||||
|
{
|
||||||
|
struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
|
||||||
|
|
||||||
|
return pinctrl->num_groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *nsp_get_group_name(struct pinctrl_dev *pctrl_dev,
|
||||||
|
unsigned int selector)
|
||||||
|
{
|
||||||
|
struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
|
||||||
|
|
||||||
|
return pinctrl->groups[selector].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nsp_get_group_pins(struct pinctrl_dev *pctrl_dev,
|
||||||
|
unsigned int selector, const unsigned int **pins,
|
||||||
|
unsigned int *num_pins)
|
||||||
|
{
|
||||||
|
struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
|
||||||
|
|
||||||
|
*pins = pinctrl->groups[selector].pins;
|
||||||
|
*num_pins = pinctrl->groups[selector].num_pins;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nsp_pin_dbg_show(struct pinctrl_dev *pctrl_dev,
|
||||||
|
struct seq_file *s, unsigned int offset)
|
||||||
|
{
|
||||||
|
seq_printf(s, " %s", dev_name(pctrl_dev->dev));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pinctrl_ops nsp_pinctrl_ops = {
|
||||||
|
.get_groups_count = nsp_get_groups_count,
|
||||||
|
.get_group_name = nsp_get_group_name,
|
||||||
|
.get_group_pins = nsp_get_group_pins,
|
||||||
|
.pin_dbg_show = nsp_pin_dbg_show,
|
||||||
|
.dt_node_to_map = pinconf_generic_dt_node_to_map_group,
|
||||||
|
.dt_free_map = pinctrl_utils_free_map,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int nsp_get_functions_count(struct pinctrl_dev *pctrl_dev)
|
||||||
|
{
|
||||||
|
struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
|
||||||
|
|
||||||
|
return pinctrl->num_functions;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *nsp_get_function_name(struct pinctrl_dev *pctrl_dev,
|
||||||
|
unsigned int selector)
|
||||||
|
{
|
||||||
|
struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
|
||||||
|
|
||||||
|
return pinctrl->functions[selector].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nsp_get_function_groups(struct pinctrl_dev *pctrl_dev,
|
||||||
|
unsigned int selector,
|
||||||
|
const char * const **groups,
|
||||||
|
unsigned * const num_groups)
|
||||||
|
{
|
||||||
|
struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
|
||||||
|
|
||||||
|
*groups = pinctrl->functions[selector].groups;
|
||||||
|
*num_groups = pinctrl->functions[selector].num_groups;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nsp_pinmux_set(struct nsp_pinctrl *pinctrl,
|
||||||
|
const struct nsp_pin_function *func,
|
||||||
|
const struct nsp_pin_group *grp,
|
||||||
|
struct nsp_mux_log *mux_log)
|
||||||
|
{
|
||||||
|
const struct nsp_mux *mux = &grp->mux;
|
||||||
|
int i;
|
||||||
|
u32 val, mask;
|
||||||
|
unsigned long flags;
|
||||||
|
void __iomem *base_address;
|
||||||
|
|
||||||
|
for (i = 0; i < pinctrl->num_groups; i++) {
|
||||||
|
if ((mux->shift != mux_log[i].mux.shift) ||
|
||||||
|
(mux->base != mux_log[i].mux.base))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* if this is a new configuration, just do it! */
|
||||||
|
if (!mux_log[i].is_configured)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IOMUX has been configured previously and one is trying to
|
||||||
|
* configure it to a different function
|
||||||
|
*/
|
||||||
|
if (mux_log[i].mux.alt != mux->alt) {
|
||||||
|
dev_err(pinctrl->dev,
|
||||||
|
"double configuration error detected!\n");
|
||||||
|
dev_err(pinctrl->dev, "func:%s grp:%s\n",
|
||||||
|
func->name, grp->name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (i == pinctrl->num_groups)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
mask = mux->mask;
|
||||||
|
mux_log[i].mux.alt = mux->alt;
|
||||||
|
mux_log[i].is_configured = true;
|
||||||
|
|
||||||
|
switch (mux->base) {
|
||||||
|
case NSP_MUX_BASE0:
|
||||||
|
base_address = pinctrl->base0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NSP_MUX_BASE1:
|
||||||
|
base_address = pinctrl->base1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NSP_MUX_BASE2:
|
||||||
|
base_address = pinctrl->base2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock_irqsave(&pinctrl->lock, flags);
|
||||||
|
val = readl(base_address);
|
||||||
|
val &= ~(mask << grp->mux.shift);
|
||||||
|
val |= grp->mux.alt << grp->mux.shift;
|
||||||
|
writel(val, base_address);
|
||||||
|
spin_unlock_irqrestore(&pinctrl->lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nsp_pinmux_enable(struct pinctrl_dev *pctrl_dev,
|
||||||
|
unsigned int func_select, unsigned int grp_select)
|
||||||
|
{
|
||||||
|
struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
|
||||||
|
const struct nsp_pin_function *func;
|
||||||
|
const struct nsp_pin_group *grp;
|
||||||
|
|
||||||
|
if (grp_select > pinctrl->num_groups ||
|
||||||
|
func_select > pinctrl->num_functions)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
func = &pinctrl->functions[func_select];
|
||||||
|
grp = &pinctrl->groups[grp_select];
|
||||||
|
|
||||||
|
dev_dbg(pctrl_dev->dev, "func:%u name:%s grp:%u name:%s\n",
|
||||||
|
func_select, func->name, grp_select, grp->name);
|
||||||
|
|
||||||
|
dev_dbg(pctrl_dev->dev, "shift:%u alt:%u\n", grp->mux.shift,
|
||||||
|
grp->mux.alt);
|
||||||
|
|
||||||
|
return nsp_pinmux_set(pinctrl, func, grp, pinctrl->mux_log);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int nsp_gpio_request_enable(struct pinctrl_dev *pctrl_dev,
|
||||||
|
struct pinctrl_gpio_range *range,
|
||||||
|
unsigned int pin)
|
||||||
|
{
|
||||||
|
struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
|
||||||
|
u32 *gpio_select = pctrl_dev->desc->pins[pin].drv_data;
|
||||||
|
u32 val;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&pinctrl->lock, flags);
|
||||||
|
val = readl(pinctrl->base0);
|
||||||
|
if ((val & BIT(pin)) != (*gpio_select << pin)) {
|
||||||
|
val &= ~BIT(pin);
|
||||||
|
val |= *gpio_select << pin;
|
||||||
|
writel(val, pinctrl->base0);
|
||||||
|
}
|
||||||
|
spin_unlock_irqrestore(&pinctrl->lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nsp_gpio_disable_free(struct pinctrl_dev *pctrl_dev,
|
||||||
|
struct pinctrl_gpio_range *range,
|
||||||
|
unsigned int pin)
|
||||||
|
{
|
||||||
|
struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
|
||||||
|
u32 *gpio_select = pctrl_dev->desc->pins[pin].drv_data;
|
||||||
|
u32 val;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&pinctrl->lock, flags);
|
||||||
|
val = readl(pinctrl->base0);
|
||||||
|
if ((val & (1 << pin)) == (*gpio_select << pin)) {
|
||||||
|
val &= ~(1 << pin);
|
||||||
|
if (!(*gpio_select))
|
||||||
|
val |= (1 << pin);
|
||||||
|
writel(val, pinctrl->base0);
|
||||||
|
}
|
||||||
|
spin_unlock_irqrestore(&pinctrl->lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pinmux_ops nsp_pinmux_ops = {
|
||||||
|
.get_functions_count = nsp_get_functions_count,
|
||||||
|
.get_function_name = nsp_get_function_name,
|
||||||
|
.get_function_groups = nsp_get_function_groups,
|
||||||
|
.set_mux = nsp_pinmux_enable,
|
||||||
|
.gpio_request_enable = nsp_gpio_request_enable,
|
||||||
|
.gpio_disable_free = nsp_gpio_disable_free,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct pinctrl_desc nsp_pinctrl_desc = {
|
||||||
|
.name = "nsp-pinmux",
|
||||||
|
.pctlops = &nsp_pinctrl_ops,
|
||||||
|
.pmxops = &nsp_pinmux_ops,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int nsp_mux_log_init(struct nsp_pinctrl *pinctrl)
|
||||||
|
{
|
||||||
|
struct nsp_mux_log *log;
|
||||||
|
unsigned int i;
|
||||||
|
u32 no_of_groups = ARRAY_SIZE(nsp_pin_groups);
|
||||||
|
|
||||||
|
pinctrl->mux_log = devm_kcalloc(pinctrl->dev, no_of_groups,
|
||||||
|
sizeof(struct nsp_mux_log),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!pinctrl->mux_log)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
for (i = 0; i < no_of_groups; i++) {
|
||||||
|
log = &pinctrl->mux_log[i];
|
||||||
|
log->mux.base = nsp_pin_groups[i].mux.base;
|
||||||
|
log->mux.shift = nsp_pin_groups[i].mux.shift;
|
||||||
|
log->mux.alt = 0;
|
||||||
|
log->is_configured = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nsp_pinmux_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct nsp_pinctrl *pinctrl;
|
||||||
|
struct resource *res;
|
||||||
|
int i, ret;
|
||||||
|
struct pinctrl_pin_desc *pins;
|
||||||
|
unsigned int num_pins = ARRAY_SIZE(nsp_pins);
|
||||||
|
|
||||||
|
pinctrl = devm_kzalloc(&pdev->dev, sizeof(*pinctrl), GFP_KERNEL);
|
||||||
|
if (!pinctrl)
|
||||||
|
return -ENOMEM;
|
||||||
|
pinctrl->dev = &pdev->dev;
|
||||||
|
platform_set_drvdata(pdev, pinctrl);
|
||||||
|
spin_lock_init(&pinctrl->lock);
|
||||||
|
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
pinctrl->base0 = devm_ioremap_resource(&pdev->dev, res);
|
||||||
|
if (IS_ERR(pinctrl->base0))
|
||||||
|
return PTR_ERR(pinctrl->base0);
|
||||||
|
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||||
|
pinctrl->base1 = devm_ioremap_nocache(&pdev->dev, res->start,
|
||||||
|
resource_size(res));
|
||||||
|
if (!pinctrl->base1) {
|
||||||
|
dev_err(&pdev->dev, "unable to map I/O space\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
|
||||||
|
pinctrl->base2 = devm_ioremap_resource(&pdev->dev, res);
|
||||||
|
if (IS_ERR(pinctrl->base2))
|
||||||
|
return PTR_ERR(pinctrl->base2);
|
||||||
|
|
||||||
|
ret = nsp_mux_log_init(pinctrl);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "unable to initialize IOMUX log\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
pins = devm_kcalloc(&pdev->dev, num_pins, sizeof(*pins), GFP_KERNEL);
|
||||||
|
if (!pins)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
for (i = 0; i < num_pins; i++) {
|
||||||
|
pins[i].number = nsp_pins[i].pin;
|
||||||
|
pins[i].name = nsp_pins[i].name;
|
||||||
|
pins[i].drv_data = &nsp_pins[i].gpio_select;
|
||||||
|
}
|
||||||
|
|
||||||
|
pinctrl->groups = nsp_pin_groups;
|
||||||
|
pinctrl->num_groups = ARRAY_SIZE(nsp_pin_groups);
|
||||||
|
pinctrl->functions = nsp_pin_functions;
|
||||||
|
pinctrl->num_functions = ARRAY_SIZE(nsp_pin_functions);
|
||||||
|
nsp_pinctrl_desc.pins = pins;
|
||||||
|
nsp_pinctrl_desc.npins = num_pins;
|
||||||
|
|
||||||
|
pinctrl->pctl = devm_pinctrl_register(&pdev->dev, &nsp_pinctrl_desc,
|
||||||
|
pinctrl);
|
||||||
|
if (IS_ERR(pinctrl->pctl)) {
|
||||||
|
dev_err(&pdev->dev, "unable to register nsp IOMUX pinctrl\n");
|
||||||
|
return PTR_ERR(pinctrl->pctl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id nsp_pinmux_of_match[] = {
|
||||||
|
{ .compatible = "brcm,nsp-pinmux" },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_driver nsp_pinmux_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = "nsp-pinmux",
|
||||||
|
.of_match_table = nsp_pinmux_of_match,
|
||||||
|
},
|
||||||
|
.probe = nsp_pinmux_probe,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init nsp_pinmux_init(void)
|
||||||
|
{
|
||||||
|
return platform_driver_register(&nsp_pinmux_driver);
|
||||||
|
}
|
||||||
|
arch_initcall(nsp_pinmux_init);
|
|
@ -225,13 +225,14 @@ static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
|
static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
|
||||||
unsigned number, const char *name)
|
const struct pinctrl_pin_desc *pin)
|
||||||
{
|
{
|
||||||
struct pin_desc *pindesc;
|
struct pin_desc *pindesc;
|
||||||
|
|
||||||
pindesc = pin_desc_get(pctldev, number);
|
pindesc = pin_desc_get(pctldev, pin->number);
|
||||||
if (pindesc != NULL) {
|
if (pindesc != NULL) {
|
||||||
dev_err(pctldev->dev, "pin %d already registered\n", number);
|
dev_err(pctldev->dev, "pin %d already registered\n",
|
||||||
|
pin->number);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,10 +246,10 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
|
||||||
pindesc->pctldev = pctldev;
|
pindesc->pctldev = pctldev;
|
||||||
|
|
||||||
/* Copy basic pin info */
|
/* Copy basic pin info */
|
||||||
if (name) {
|
if (pin->name) {
|
||||||
pindesc->name = name;
|
pindesc->name = pin->name;
|
||||||
} else {
|
} else {
|
||||||
pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", number);
|
pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", pin->number);
|
||||||
if (pindesc->name == NULL) {
|
if (pindesc->name == NULL) {
|
||||||
kfree(pindesc);
|
kfree(pindesc);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -256,9 +257,11 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
|
||||||
pindesc->dynamic_name = true;
|
pindesc->dynamic_name = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
radix_tree_insert(&pctldev->pin_desc_tree, number, pindesc);
|
pindesc->drv_data = pin->drv_data;
|
||||||
|
|
||||||
|
radix_tree_insert(&pctldev->pin_desc_tree, pin->number, pindesc);
|
||||||
pr_debug("registered pin %d (%s) on %s\n",
|
pr_debug("registered pin %d (%s) on %s\n",
|
||||||
number, pindesc->name, pctldev->desc->name);
|
pin->number, pindesc->name, pctldev->desc->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,8 +273,7 @@ static int pinctrl_register_pins(struct pinctrl_dev *pctldev,
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
for (i = 0; i < num_descs; i++) {
|
for (i = 0; i < num_descs; i++) {
|
||||||
ret = pinctrl_register_one_pin(pctldev,
|
ret = pinctrl_register_one_pin(pctldev, &pins[i]);
|
||||||
pins[i].number, pins[i].name);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1367,8 +1369,7 @@ static int pinctrl_pins_show(struct seq_file *s, void *what)
|
||||||
if (desc == NULL)
|
if (desc == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
seq_printf(s, "pin %d (%s) ", pin,
|
seq_printf(s, "pin %d (%s) ", pin, desc->name);
|
||||||
desc->name ? desc->name : "unnamed");
|
|
||||||
|
|
||||||
/* Driver-specific info per pin */
|
/* Driver-specific info per pin */
|
||||||
if (ops->pin_dbg_show)
|
if (ops->pin_dbg_show)
|
||||||
|
|
|
@ -134,6 +134,7 @@ struct pinctrl_setting {
|
||||||
* @name: a name for the pin, e.g. the name of the pin/pad/finger on a
|
* @name: a name for the pin, e.g. the name of the pin/pad/finger on a
|
||||||
* datasheet or such
|
* datasheet or such
|
||||||
* @dynamic_name: if the name of this pin was dynamically allocated
|
* @dynamic_name: if the name of this pin was dynamically allocated
|
||||||
|
* @drv_data: driver-defined per-pin data. pinctrl core does not touch this
|
||||||
* @mux_usecount: If zero, the pin is not claimed, and @owner should be NULL.
|
* @mux_usecount: If zero, the pin is not claimed, and @owner should be NULL.
|
||||||
* If non-zero, this pin is claimed by @owner. This field is an integer
|
* If non-zero, this pin is claimed by @owner. This field is an integer
|
||||||
* rather than a boolean, since pinctrl_get() might process multiple
|
* rather than a boolean, since pinctrl_get() might process multiple
|
||||||
|
@ -148,6 +149,7 @@ struct pin_desc {
|
||||||
struct pinctrl_dev *pctldev;
|
struct pinctrl_dev *pctldev;
|
||||||
const char *name;
|
const char *name;
|
||||||
bool dynamic_name;
|
bool dynamic_name;
|
||||||
|
void *drv_data;
|
||||||
/* These fields only added when supporting pinmux drivers */
|
/* These fields only added when supporting pinmux drivers */
|
||||||
#ifdef CONFIG_PINMUX
|
#ifdef CONFIG_PINMUX
|
||||||
unsigned mux_usecount;
|
unsigned mux_usecount;
|
||||||
|
|
|
@ -195,8 +195,13 @@ int pinctrl_dt_to_map(struct pinctrl *p)
|
||||||
propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state);
|
propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state);
|
||||||
prop = of_find_property(np, propname, &size);
|
prop = of_find_property(np, propname, &size);
|
||||||
kfree(propname);
|
kfree(propname);
|
||||||
if (!prop)
|
if (!prop) {
|
||||||
|
if (state == 0) {
|
||||||
|
of_node_put(np);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
list = prop->value;
|
list = prop->value;
|
||||||
size /= sizeof(*list);
|
size /= sizeof(*list);
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/mfd/syscon.h>
|
#include <linux/mfd/syscon.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
|
@ -46,7 +45,7 @@ struct imx_pinctrl {
|
||||||
const struct imx_pinctrl_soc_info *info;
|
const struct imx_pinctrl_soc_info *info;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const inline struct imx_pin_group *imx_pinctrl_find_group_by_name(
|
static inline const struct imx_pin_group *imx_pinctrl_find_group_by_name(
|
||||||
const struct imx_pinctrl_soc_info *info,
|
const struct imx_pinctrl_soc_info *info,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
|
@ -513,13 +512,6 @@ static const struct pinconf_ops imx_pinconf_ops = {
|
||||||
.pin_config_group_dbg_show = imx_pinconf_group_dbg_show,
|
.pin_config_group_dbg_show = imx_pinconf_group_dbg_show,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct pinctrl_desc imx_pinctrl_desc = {
|
|
||||||
.pctlops = &imx_pctrl_ops,
|
|
||||||
.pmxops = &imx_pmx_ops,
|
|
||||||
.confops = &imx_pinconf_ops,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Each pin represented in fsl,pins consists of 5 u32 PIN_FUNC_ID and
|
* Each pin represented in fsl,pins consists of 5 u32 PIN_FUNC_ID and
|
||||||
* 1 u32 CONFIG, so 24 types in total for each pin.
|
* 1 u32 CONFIG, so 24 types in total for each pin.
|
||||||
|
@ -722,6 +714,7 @@ int imx_pinctrl_probe(struct platform_device *pdev,
|
||||||
{
|
{
|
||||||
struct regmap_config config = { .name = "gpr" };
|
struct regmap_config config = { .name = "gpr" };
|
||||||
struct device_node *dev_np = pdev->dev.of_node;
|
struct device_node *dev_np = pdev->dev.of_node;
|
||||||
|
struct pinctrl_desc *imx_pinctrl_desc;
|
||||||
struct device_node *np;
|
struct device_node *np;
|
||||||
struct imx_pinctrl *ipctl;
|
struct imx_pinctrl *ipctl;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
|
@ -776,9 +769,18 @@ int imx_pinctrl_probe(struct platform_device *pdev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
imx_pinctrl_desc.name = dev_name(&pdev->dev);
|
imx_pinctrl_desc = devm_kzalloc(&pdev->dev, sizeof(*imx_pinctrl_desc),
|
||||||
imx_pinctrl_desc.pins = info->pins;
|
GFP_KERNEL);
|
||||||
imx_pinctrl_desc.npins = info->npins;
|
if (!imx_pinctrl_desc)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
imx_pinctrl_desc->name = dev_name(&pdev->dev);
|
||||||
|
imx_pinctrl_desc->pins = info->pins;
|
||||||
|
imx_pinctrl_desc->npins = info->npins;
|
||||||
|
imx_pinctrl_desc->pctlops = &imx_pctrl_ops,
|
||||||
|
imx_pinctrl_desc->pmxops = &imx_pmx_ops,
|
||||||
|
imx_pinctrl_desc->confops = &imx_pinconf_ops,
|
||||||
|
imx_pinctrl_desc->owner = THIS_MODULE,
|
||||||
|
|
||||||
ret = imx_pinctrl_probe_dt(pdev, info);
|
ret = imx_pinctrl_probe_dt(pdev, info);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -789,7 +791,8 @@ int imx_pinctrl_probe(struct platform_device *pdev,
|
||||||
ipctl->info = info;
|
ipctl->info = info;
|
||||||
ipctl->dev = info->dev;
|
ipctl->dev = info->dev;
|
||||||
platform_set_drvdata(pdev, ipctl);
|
platform_set_drvdata(pdev, ipctl);
|
||||||
ipctl->pctl = devm_pinctrl_register(&pdev->dev, &imx_pinctrl_desc, ipctl);
|
ipctl->pctl = devm_pinctrl_register(&pdev->dev,
|
||||||
|
imx_pinctrl_desc, ipctl);
|
||||||
if (IS_ERR(ipctl->pctl)) {
|
if (IS_ERR(ipctl->pctl)) {
|
||||||
dev_err(&pdev->dev, "could not register IMX pinctrl driver\n");
|
dev_err(&pdev->dev, "could not register IMX pinctrl driver\n");
|
||||||
return PTR_ERR(ipctl->pctl);
|
return PTR_ERR(ipctl->pctl);
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/pinctrl/machine.h>
|
#include <linux/pinctrl/machine.h>
|
||||||
|
@ -157,7 +156,7 @@ static int imx1_read_bit(struct imx1_pinctrl *ipctl, unsigned int pin_id,
|
||||||
return !!(readl(reg) & BIT(offset));
|
return !!(readl(reg) & BIT(offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const inline struct imx1_pin_group *imx1_pinctrl_find_group_by_name(
|
static inline const struct imx1_pin_group *imx1_pinctrl_find_group_by_name(
|
||||||
const struct imx1_pinctrl_soc_info *info,
|
const struct imx1_pinctrl_soc_info *info,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/init.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
@ -262,7 +262,6 @@ static const struct of_device_id imx1_pinctrl_of_match[] = {
|
||||||
{ .compatible = "fsl,imx1-iomuxc", },
|
{ .compatible = "fsl,imx1-iomuxc", },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, imx1_pinctrl_of_match);
|
|
||||||
|
|
||||||
static struct platform_driver imx1_pinctrl_driver = {
|
static struct platform_driver imx1_pinctrl_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
|
@ -270,8 +269,4 @@ static struct platform_driver imx1_pinctrl_driver = {
|
||||||
.of_match_table = imx1_pinctrl_of_match,
|
.of_match_table = imx1_pinctrl_of_match,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
module_platform_driver_probe(imx1_pinctrl_driver, imx1_pinctrl_probe);
|
builtin_platform_driver_probe(imx1_pinctrl_driver, imx1_pinctrl_probe);
|
||||||
|
|
||||||
MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
|
|
||||||
MODULE_DESCRIPTION("Freescale i.MX1 pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL");
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/init.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
@ -325,7 +325,6 @@ static const struct of_device_id imx21_pinctrl_of_match[] = {
|
||||||
{ .compatible = "fsl,imx21-iomuxc", },
|
{ .compatible = "fsl,imx21-iomuxc", },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, imx21_pinctrl_of_match);
|
|
||||||
|
|
||||||
static struct platform_driver imx21_pinctrl_driver = {
|
static struct platform_driver imx21_pinctrl_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
|
@ -333,8 +332,4 @@ static struct platform_driver imx21_pinctrl_driver = {
|
||||||
.of_match_table = imx21_pinctrl_of_match,
|
.of_match_table = imx21_pinctrl_of_match,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
module_platform_driver_probe(imx21_pinctrl_driver, imx21_pinctrl_probe);
|
builtin_platform_driver_probe(imx21_pinctrl_driver, imx21_pinctrl_probe);
|
||||||
|
|
||||||
MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
|
|
||||||
MODULE_DESCRIPTION("Freescale i.MX21 pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL");
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
/*
|
/*
|
||||||
|
* Freescale i.MX23 pinctrl driver
|
||||||
|
*
|
||||||
|
* Author: Shawn Guo <shawn.guo@linaro.org>
|
||||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||||
*
|
*
|
||||||
* The code contained herein is licensed under the GNU General Public
|
* The code contained herein is licensed under the GNU General Public
|
||||||
|
@ -10,7 +13,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
#include "pinctrl-mxs.h"
|
#include "pinctrl-mxs.h"
|
||||||
|
@ -276,15 +278,14 @@ static const struct of_device_id imx23_pinctrl_of_match[] = {
|
||||||
{ .compatible = "fsl,imx23-pinctrl", },
|
{ .compatible = "fsl,imx23-pinctrl", },
|
||||||
{ /* sentinel */ }
|
{ /* sentinel */ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, imx23_pinctrl_of_match);
|
|
||||||
|
|
||||||
static struct platform_driver imx23_pinctrl_driver = {
|
static struct platform_driver imx23_pinctrl_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "imx23-pinctrl",
|
.name = "imx23-pinctrl",
|
||||||
|
.suppress_bind_attrs = true,
|
||||||
.of_match_table = imx23_pinctrl_of_match,
|
.of_match_table = imx23_pinctrl_of_match,
|
||||||
},
|
},
|
||||||
.probe = imx23_pinctrl_probe,
|
.probe = imx23_pinctrl_probe,
|
||||||
.remove = mxs_pinctrl_remove,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init imx23_pinctrl_init(void)
|
static int __init imx23_pinctrl_init(void)
|
||||||
|
@ -292,13 +293,3 @@ static int __init imx23_pinctrl_init(void)
|
||||||
return platform_driver_register(&imx23_pinctrl_driver);
|
return platform_driver_register(&imx23_pinctrl_driver);
|
||||||
}
|
}
|
||||||
postcore_initcall(imx23_pinctrl_init);
|
postcore_initcall(imx23_pinctrl_init);
|
||||||
|
|
||||||
static void __exit imx23_pinctrl_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&imx23_pinctrl_driver);
|
|
||||||
}
|
|
||||||
module_exit(imx23_pinctrl_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
|
|
||||||
MODULE_DESCRIPTION("Freescale i.MX23 pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
@ -338,12 +337,3 @@ static int __init imx25_pinctrl_init(void)
|
||||||
return platform_driver_register(&imx25_pinctrl_driver);
|
return platform_driver_register(&imx25_pinctrl_driver);
|
||||||
}
|
}
|
||||||
arch_initcall(imx25_pinctrl_init);
|
arch_initcall(imx25_pinctrl_init);
|
||||||
|
|
||||||
static void __exit imx25_pinctrl_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&imx25_pinctrl_driver);
|
|
||||||
}
|
|
||||||
module_exit(imx25_pinctrl_exit);
|
|
||||||
MODULE_AUTHOR("Denis Carikli <denis@eukrea.com>");
|
|
||||||
MODULE_DESCRIPTION("Freescale IMX25 pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
@ -412,12 +411,3 @@ static int __init imx27_pinctrl_init(void)
|
||||||
return platform_driver_register(&imx27_pinctrl_driver);
|
return platform_driver_register(&imx27_pinctrl_driver);
|
||||||
}
|
}
|
||||||
arch_initcall(imx27_pinctrl_init);
|
arch_initcall(imx27_pinctrl_init);
|
||||||
|
|
||||||
static void __exit imx27_pinctrl_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&imx27_pinctrl_driver);
|
|
||||||
}
|
|
||||||
module_exit(imx27_pinctrl_exit);
|
|
||||||
MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
|
|
||||||
MODULE_DESCRIPTION("Freescale IMX27 pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
/*
|
/*
|
||||||
|
* Freescale i.MX28 pinctrl driver
|
||||||
|
*
|
||||||
|
* Author: Shawn Guo <shawn.guo@linaro.org>
|
||||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||||
*
|
*
|
||||||
* The code contained herein is licensed under the GNU General Public
|
* The code contained herein is licensed under the GNU General Public
|
||||||
|
@ -10,7 +13,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
#include "pinctrl-mxs.h"
|
#include "pinctrl-mxs.h"
|
||||||
|
@ -392,15 +394,14 @@ static const struct of_device_id imx28_pinctrl_of_match[] = {
|
||||||
{ .compatible = "fsl,imx28-pinctrl", },
|
{ .compatible = "fsl,imx28-pinctrl", },
|
||||||
{ /* sentinel */ }
|
{ /* sentinel */ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, imx28_pinctrl_of_match);
|
|
||||||
|
|
||||||
static struct platform_driver imx28_pinctrl_driver = {
|
static struct platform_driver imx28_pinctrl_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "imx28-pinctrl",
|
.name = "imx28-pinctrl",
|
||||||
|
.suppress_bind_attrs = true,
|
||||||
.of_match_table = imx28_pinctrl_of_match,
|
.of_match_table = imx28_pinctrl_of_match,
|
||||||
},
|
},
|
||||||
.probe = imx28_pinctrl_probe,
|
.probe = imx28_pinctrl_probe,
|
||||||
.remove = mxs_pinctrl_remove,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init imx28_pinctrl_init(void)
|
static int __init imx28_pinctrl_init(void)
|
||||||
|
@ -408,13 +409,3 @@ static int __init imx28_pinctrl_init(void)
|
||||||
return platform_driver_register(&imx28_pinctrl_driver);
|
return platform_driver_register(&imx28_pinctrl_driver);
|
||||||
}
|
}
|
||||||
postcore_initcall(imx28_pinctrl_init);
|
postcore_initcall(imx28_pinctrl_init);
|
||||||
|
|
||||||
static void __exit imx28_pinctrl_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&imx28_pinctrl_driver);
|
|
||||||
}
|
|
||||||
module_exit(imx28_pinctrl_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
|
|
||||||
MODULE_DESCRIPTION("Freescale i.MX28 pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
@ -1028,12 +1027,3 @@ static int __init imx35_pinctrl_init(void)
|
||||||
return platform_driver_register(&imx35_pinctrl_driver);
|
return platform_driver_register(&imx35_pinctrl_driver);
|
||||||
}
|
}
|
||||||
arch_initcall(imx35_pinctrl_init);
|
arch_initcall(imx35_pinctrl_init);
|
||||||
|
|
||||||
static void __exit imx35_pinctrl_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&imx35_pinctrl_driver);
|
|
||||||
}
|
|
||||||
module_exit(imx35_pinctrl_exit);
|
|
||||||
MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>");
|
|
||||||
MODULE_DESCRIPTION("Freescale IMX35 pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
@ -415,11 +414,3 @@ static int __init imx50_pinctrl_init(void)
|
||||||
return platform_driver_register(&imx50_pinctrl_driver);
|
return platform_driver_register(&imx50_pinctrl_driver);
|
||||||
}
|
}
|
||||||
arch_initcall(imx50_pinctrl_init);
|
arch_initcall(imx50_pinctrl_init);
|
||||||
|
|
||||||
static void __exit imx50_pinctrl_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&imx50_pinctrl_driver);
|
|
||||||
}
|
|
||||||
module_exit(imx50_pinctrl_exit);
|
|
||||||
MODULE_DESCRIPTION("Freescale IMX50 pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
@ -791,12 +790,3 @@ static int __init imx51_pinctrl_init(void)
|
||||||
return platform_driver_register(&imx51_pinctrl_driver);
|
return platform_driver_register(&imx51_pinctrl_driver);
|
||||||
}
|
}
|
||||||
arch_initcall(imx51_pinctrl_init);
|
arch_initcall(imx51_pinctrl_init);
|
||||||
|
|
||||||
static void __exit imx51_pinctrl_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&imx51_pinctrl_driver);
|
|
||||||
}
|
|
||||||
module_exit(imx51_pinctrl_exit);
|
|
||||||
MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>");
|
|
||||||
MODULE_DESCRIPTION("Freescale IMX51 pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
@ -478,12 +477,3 @@ static int __init imx53_pinctrl_init(void)
|
||||||
return platform_driver_register(&imx53_pinctrl_driver);
|
return platform_driver_register(&imx53_pinctrl_driver);
|
||||||
}
|
}
|
||||||
arch_initcall(imx53_pinctrl_init);
|
arch_initcall(imx53_pinctrl_init);
|
||||||
|
|
||||||
static void __exit imx53_pinctrl_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&imx53_pinctrl_driver);
|
|
||||||
}
|
|
||||||
module_exit(imx53_pinctrl_exit);
|
|
||||||
MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>");
|
|
||||||
MODULE_DESCRIPTION("Freescale IMX53 pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
/*
|
/*
|
||||||
|
* Freescale imx6dl pinctrl driver
|
||||||
|
*
|
||||||
|
* Author: Shawn Guo <shawn.guo@linaro.org>
|
||||||
* Copyright (C) 2013 Freescale Semiconductor, Inc.
|
* Copyright (C) 2013 Freescale Semiconductor, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -9,7 +12,6 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
@ -484,13 +486,3 @@ static int __init imx6dl_pinctrl_init(void)
|
||||||
return platform_driver_register(&imx6dl_pinctrl_driver);
|
return platform_driver_register(&imx6dl_pinctrl_driver);
|
||||||
}
|
}
|
||||||
arch_initcall(imx6dl_pinctrl_init);
|
arch_initcall(imx6dl_pinctrl_init);
|
||||||
|
|
||||||
static void __exit imx6dl_pinctrl_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&imx6dl_pinctrl_driver);
|
|
||||||
}
|
|
||||||
module_exit(imx6dl_pinctrl_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
|
|
||||||
MODULE_DESCRIPTION("Freescale imx6dl pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
@ -490,12 +489,3 @@ static int __init imx6q_pinctrl_init(void)
|
||||||
return platform_driver_register(&imx6q_pinctrl_driver);
|
return platform_driver_register(&imx6q_pinctrl_driver);
|
||||||
}
|
}
|
||||||
arch_initcall(imx6q_pinctrl_init);
|
arch_initcall(imx6q_pinctrl_init);
|
||||||
|
|
||||||
static void __exit imx6q_pinctrl_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&imx6q_pinctrl_driver);
|
|
||||||
}
|
|
||||||
module_exit(imx6q_pinctrl_exit);
|
|
||||||
MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>");
|
|
||||||
MODULE_DESCRIPTION("Freescale IMX6Q pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
/*
|
/*
|
||||||
|
* Freescale imx6sl pinctrl driver
|
||||||
|
*
|
||||||
|
* Author: Shawn Guo <shawn.guo@linaro.org>
|
||||||
* Copyright (C) 2013 Freescale Semiconductor, Inc.
|
* Copyright (C) 2013 Freescale Semiconductor, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -9,7 +12,6 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
@ -371,7 +373,6 @@ static const struct of_device_id imx6sl_pinctrl_of_match[] = {
|
||||||
{ .compatible = "fsl,imx6sl-iomuxc", },
|
{ .compatible = "fsl,imx6sl-iomuxc", },
|
||||||
{ /* sentinel */ }
|
{ /* sentinel */ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, imx6sl_pinctrl_of_match);
|
|
||||||
|
|
||||||
static int imx6sl_pinctrl_probe(struct platform_device *pdev)
|
static int imx6sl_pinctrl_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
@ -391,13 +392,3 @@ static int __init imx6sl_pinctrl_init(void)
|
||||||
return platform_driver_register(&imx6sl_pinctrl_driver);
|
return platform_driver_register(&imx6sl_pinctrl_driver);
|
||||||
}
|
}
|
||||||
arch_initcall(imx6sl_pinctrl_init);
|
arch_initcall(imx6sl_pinctrl_init);
|
||||||
|
|
||||||
static void __exit imx6sl_pinctrl_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&imx6sl_pinctrl_driver);
|
|
||||||
}
|
|
||||||
module_exit(imx6sl_pinctrl_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
|
|
||||||
MODULE_DESCRIPTION("Freescale imx6sl pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
/*
|
/*
|
||||||
|
* Freescale imx6sx pinctrl driver
|
||||||
|
*
|
||||||
|
* Author: Anson Huang <Anson.Huang@freescale.com>
|
||||||
* Copyright (C) 2014 Freescale Semiconductor, Inc.
|
* Copyright (C) 2014 Freescale Semiconductor, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -9,7 +12,6 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
@ -394,13 +396,3 @@ static int __init imx6sx_pinctrl_init(void)
|
||||||
return platform_driver_register(&imx6sx_pinctrl_driver);
|
return platform_driver_register(&imx6sx_pinctrl_driver);
|
||||||
}
|
}
|
||||||
arch_initcall(imx6sx_pinctrl_init);
|
arch_initcall(imx6sx_pinctrl_init);
|
||||||
|
|
||||||
static void __exit imx6sx_pinctrl_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&imx6sx_pinctrl_driver);
|
|
||||||
}
|
|
||||||
module_exit(imx6sx_pinctrl_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Anson Huang <Anson.Huang@freescale.com>");
|
|
||||||
MODULE_DESCRIPTION("Freescale imx6sx pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
/*
|
/*
|
||||||
|
* Freescale imx6ul pinctrl driver
|
||||||
|
*
|
||||||
|
* Author: Anson Huang <Anson.Huang@freescale.com>
|
||||||
* Copyright (C) 2015 Freescale Semiconductor, Inc.
|
* Copyright (C) 2015 Freescale Semiconductor, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -9,7 +12,6 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
@ -310,13 +312,3 @@ static int __init imx6ul_pinctrl_init(void)
|
||||||
return platform_driver_register(&imx6ul_pinctrl_driver);
|
return platform_driver_register(&imx6ul_pinctrl_driver);
|
||||||
}
|
}
|
||||||
arch_initcall(imx6ul_pinctrl_init);
|
arch_initcall(imx6ul_pinctrl_init);
|
||||||
|
|
||||||
static void __exit imx6ul_pinctrl_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&imx6ul_pinctrl_driver);
|
|
||||||
}
|
|
||||||
module_exit(imx6ul_pinctrl_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Anson Huang <Anson.Huang@freescale.com>");
|
|
||||||
MODULE_DESCRIPTION("Freescale imx6ul pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
/*
|
/*
|
||||||
|
* Freescale imx7d pinctrl driver
|
||||||
|
*
|
||||||
|
* Author: Anson Huang <Anson.Huang@freescale.com>
|
||||||
* Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
|
* Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -9,7 +12,6 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
@ -402,13 +404,3 @@ static int __init imx7d_pinctrl_init(void)
|
||||||
return platform_driver_register(&imx7d_pinctrl_driver);
|
return platform_driver_register(&imx7d_pinctrl_driver);
|
||||||
}
|
}
|
||||||
arch_initcall(imx7d_pinctrl_init);
|
arch_initcall(imx7d_pinctrl_init);
|
||||||
|
|
||||||
static void __exit imx7d_pinctrl_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&imx7d_pinctrl_driver);
|
|
||||||
}
|
|
||||||
module_exit(imx7d_pinctrl_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Anson Huang <Anson.Huang@freescale.com>");
|
|
||||||
MODULE_DESCRIPTION("Freescale imx7d pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
#include <linux/pinctrl/machine.h>
|
#include <linux/pinctrl/machine.h>
|
||||||
|
@ -553,14 +552,3 @@ err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mxs_pinctrl_probe);
|
EXPORT_SYMBOL_GPL(mxs_pinctrl_probe);
|
||||||
|
|
||||||
int mxs_pinctrl_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
struct mxs_pinctrl_data *d = platform_get_drvdata(pdev);
|
|
||||||
|
|
||||||
pinctrl_unregister(d->pctl);
|
|
||||||
iounmap(d->base);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(mxs_pinctrl_remove);
|
|
||||||
|
|
|
@ -86,6 +86,5 @@ struct mxs_pinctrl_soc_data {
|
||||||
|
|
||||||
int mxs_pinctrl_probe(struct platform_device *pdev,
|
int mxs_pinctrl_probe(struct platform_device *pdev,
|
||||||
struct mxs_pinctrl_soc_data *soc);
|
struct mxs_pinctrl_soc_data *soc);
|
||||||
int mxs_pinctrl_remove(struct platform_device *pdev);
|
|
||||||
|
|
||||||
#endif /* __PINCTRL_MXS_H */
|
#endif /* __PINCTRL_MXS_H */
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
@ -325,12 +324,3 @@ static int __init vf610_pinctrl_init(void)
|
||||||
return platform_driver_register(&vf610_pinctrl_driver);
|
return platform_driver_register(&vf610_pinctrl_driver);
|
||||||
}
|
}
|
||||||
arch_initcall(vf610_pinctrl_init);
|
arch_initcall(vf610_pinctrl_init);
|
||||||
|
|
||||||
static void __exit vf610_pinctrl_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&vf610_pinctrl_driver);
|
|
||||||
}
|
|
||||||
module_exit(vf610_pinctrl_exit);
|
|
||||||
|
|
||||||
MODULE_DESCRIPTION("Freescale VF610 pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
||||||
|
|
|
@ -29,6 +29,17 @@ config PINCTRL_CHERRYVIEW
|
||||||
Cherryview/Braswell pinctrl driver provides an interface that
|
Cherryview/Braswell pinctrl driver provides an interface that
|
||||||
allows configuring of SoC pins and using them as GPIOs.
|
allows configuring of SoC pins and using them as GPIOs.
|
||||||
|
|
||||||
|
config PINCTRL_MERRIFIELD
|
||||||
|
tristate "Intel Merrifield pinctrl driver"
|
||||||
|
depends on X86_INTEL_MID
|
||||||
|
select PINMUX
|
||||||
|
select PINCONF
|
||||||
|
select GENERIC_PINCONF
|
||||||
|
help
|
||||||
|
Merrifield Family-Level Interface Shim (FLIS) driver provides an
|
||||||
|
interface that allows configuring of SoC pins and using them as
|
||||||
|
GPIOs.
|
||||||
|
|
||||||
config PINCTRL_INTEL
|
config PINCTRL_INTEL
|
||||||
tristate
|
tristate
|
||||||
select PINMUX
|
select PINMUX
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o
|
obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o
|
||||||
obj-$(CONFIG_PINCTRL_CHERRYVIEW) += pinctrl-cherryview.o
|
obj-$(CONFIG_PINCTRL_CHERRYVIEW) += pinctrl-cherryview.o
|
||||||
|
obj-$(CONFIG_PINCTRL_MERRIFIELD) += pinctrl-merrifield.o
|
||||||
obj-$(CONFIG_PINCTRL_INTEL) += pinctrl-intel.o
|
obj-$(CONFIG_PINCTRL_INTEL) += pinctrl-intel.o
|
||||||
obj-$(CONFIG_PINCTRL_BROXTON) += pinctrl-broxton.o
|
obj-$(CONFIG_PINCTRL_BROXTON) += pinctrl-broxton.o
|
||||||
obj-$(CONFIG_PINCTRL_SUNRISEPOINT) += pinctrl-sunrisepoint.o
|
obj-$(CONFIG_PINCTRL_SUNRISEPOINT) += pinctrl-sunrisepoint.o
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
|
@ -1822,17 +1821,6 @@ static int byt_pinctrl_probe(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int byt_pinctrl_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
struct byt_gpio *vg = platform_get_drvdata(pdev);
|
|
||||||
|
|
||||||
pm_runtime_disable(&pdev->dev);
|
|
||||||
gpiochip_remove(&vg->chip);
|
|
||||||
pinctrl_unregister(vg->pctl_dev);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
static int byt_gpio_suspend(struct device *dev)
|
static int byt_gpio_suspend(struct device *dev)
|
||||||
{
|
{
|
||||||
|
@ -1930,10 +1918,11 @@ static const struct dev_pm_ops byt_gpio_pm_ops = {
|
||||||
|
|
||||||
static struct platform_driver byt_gpio_driver = {
|
static struct platform_driver byt_gpio_driver = {
|
||||||
.probe = byt_pinctrl_probe,
|
.probe = byt_pinctrl_probe,
|
||||||
.remove = byt_pinctrl_remove,
|
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "byt_gpio",
|
.name = "byt_gpio",
|
||||||
.pm = &byt_gpio_pm_ops,
|
.pm = &byt_gpio_pm_ops,
|
||||||
|
.suppress_bind_attrs = true,
|
||||||
|
|
||||||
.acpi_match_table = ACPI_PTR(byt_gpio_acpi_match),
|
.acpi_match_table = ACPI_PTR(byt_gpio_acpi_match),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1943,9 +1932,3 @@ static int __init byt_gpio_init(void)
|
||||||
return platform_driver_register(&byt_gpio_driver);
|
return platform_driver_register(&byt_gpio_driver);
|
||||||
}
|
}
|
||||||
subsys_initcall(byt_gpio_init);
|
subsys_initcall(byt_gpio_init);
|
||||||
|
|
||||||
static void __exit byt_gpio_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&byt_gpio_driver);
|
|
||||||
}
|
|
||||||
module_exit(byt_gpio_exit);
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Intel Broxton SoC pinctrl/GPIO driver
|
* Intel Broxton SoC pinctrl/GPIO driver
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015, Intel Corporation
|
* Copyright (C) 2015, 2016 Intel Corporation
|
||||||
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
|
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -1003,29 +1003,46 @@ static const struct acpi_device_id bxt_pinctrl_acpi_match[] = {
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(acpi, bxt_pinctrl_acpi_match);
|
MODULE_DEVICE_TABLE(acpi, bxt_pinctrl_acpi_match);
|
||||||
|
|
||||||
|
static const struct platform_device_id bxt_pinctrl_platform_ids[] = {
|
||||||
|
{ "apl-pinctrl", (kernel_ulong_t)&apl_pinctrl_soc_data },
|
||||||
|
{ "broxton-pinctrl", (kernel_ulong_t)&bxt_pinctrl_soc_data },
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
|
||||||
static int bxt_pinctrl_probe(struct platform_device *pdev)
|
static int bxt_pinctrl_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
const struct intel_pinctrl_soc_data *soc_data = NULL;
|
const struct intel_pinctrl_soc_data *soc_data = NULL;
|
||||||
const struct intel_pinctrl_soc_data **soc_table;
|
const struct intel_pinctrl_soc_data **soc_table;
|
||||||
const struct acpi_device_id *id;
|
|
||||||
struct acpi_device *adev;
|
struct acpi_device *adev;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
adev = ACPI_COMPANION(&pdev->dev);
|
adev = ACPI_COMPANION(&pdev->dev);
|
||||||
if (!adev)
|
if (adev) {
|
||||||
return -ENODEV;
|
const struct acpi_device_id *id;
|
||||||
|
|
||||||
id = acpi_match_device(bxt_pinctrl_acpi_match, &pdev->dev);
|
id = acpi_match_device(bxt_pinctrl_acpi_match, &pdev->dev);
|
||||||
if (!id)
|
if (!id)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
soc_table = (const struct intel_pinctrl_soc_data **)id->driver_data;
|
soc_table = (const struct intel_pinctrl_soc_data **)
|
||||||
|
id->driver_data;
|
||||||
|
|
||||||
for (i = 0; soc_table[i]; i++) {
|
for (i = 0; soc_table[i]; i++) {
|
||||||
if (!strcmp(adev->pnp.unique_id, soc_table[i]->uid)) {
|
if (!strcmp(adev->pnp.unique_id, soc_table[i]->uid)) {
|
||||||
soc_data = soc_table[i];
|
soc_data = soc_table[i];
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
const struct platform_device_id *pid;
|
||||||
|
|
||||||
|
pid = platform_get_device_id(pdev);
|
||||||
|
if (!pid)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
soc_table = (const struct intel_pinctrl_soc_data **)
|
||||||
|
pid->driver_data;
|
||||||
|
soc_data = soc_table[pdev->id];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!soc_data)
|
if (!soc_data)
|
||||||
|
@ -1047,6 +1064,7 @@ static struct platform_driver bxt_pinctrl_driver = {
|
||||||
.acpi_match_table = bxt_pinctrl_acpi_match,
|
.acpi_match_table = bxt_pinctrl_acpi_match,
|
||||||
.pm = &bxt_pinctrl_pm_ops,
|
.pm = &bxt_pinctrl_pm_ops,
|
||||||
},
|
},
|
||||||
|
.id_table = bxt_pinctrl_platform_ids,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init bxt_pinctrl_init(void)
|
static int __init bxt_pinctrl_init(void)
|
||||||
|
@ -1064,3 +1082,4 @@ module_exit(bxt_pinctrl_exit);
|
||||||
MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
|
MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
|
||||||
MODULE_DESCRIPTION("Intel Broxton SoC pinctrl/GPIO driver");
|
MODULE_DESCRIPTION("Intel Broxton SoC pinctrl/GPIO driver");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
|
MODULE_ALIAS("platform:broxton-pinctrl");
|
||||||
|
|
|
@ -160,7 +160,6 @@ struct chv_pin_context {
|
||||||
* @pctldev: Pointer to the pin controller device
|
* @pctldev: Pointer to the pin controller device
|
||||||
* @chip: GPIO chip in this pin controller
|
* @chip: GPIO chip in this pin controller
|
||||||
* @regs: MMIO registers
|
* @regs: MMIO registers
|
||||||
* @lock: Lock to serialize register accesses
|
|
||||||
* @intr_lines: Stores mapping between 16 HW interrupt wires and GPIO
|
* @intr_lines: Stores mapping between 16 HW interrupt wires and GPIO
|
||||||
* offset (in GPIO number space)
|
* offset (in GPIO number space)
|
||||||
* @community: Community this pinctrl instance represents
|
* @community: Community this pinctrl instance represents
|
||||||
|
@ -174,7 +173,6 @@ struct chv_pinctrl {
|
||||||
struct pinctrl_dev *pctldev;
|
struct pinctrl_dev *pctldev;
|
||||||
struct gpio_chip chip;
|
struct gpio_chip chip;
|
||||||
void __iomem *regs;
|
void __iomem *regs;
|
||||||
raw_spinlock_t lock;
|
|
||||||
unsigned intr_lines[16];
|
unsigned intr_lines[16];
|
||||||
const struct chv_community *community;
|
const struct chv_community *community;
|
||||||
u32 saved_intmask;
|
u32 saved_intmask;
|
||||||
|
@ -657,6 +655,17 @@ static const struct chv_community *chv_communities[] = {
|
||||||
&southeast_community,
|
&southeast_community,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lock to serialize register accesses
|
||||||
|
*
|
||||||
|
* Due to a silicon issue, a shared lock must be used to prevent
|
||||||
|
* concurrent accesses across the 4 GPIO controllers.
|
||||||
|
*
|
||||||
|
* See Intel Atom Z8000 Processor Series Specification Update (Rev. 005),
|
||||||
|
* errata #CHT34, for further information.
|
||||||
|
*/
|
||||||
|
static DEFINE_RAW_SPINLOCK(chv_lock);
|
||||||
|
|
||||||
static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned offset,
|
static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned offset,
|
||||||
unsigned reg)
|
unsigned reg)
|
||||||
{
|
{
|
||||||
|
@ -718,13 +727,13 @@ static void chv_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
|
||||||
u32 ctrl0, ctrl1;
|
u32 ctrl0, ctrl1;
|
||||||
bool locked;
|
bool locked;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&chv_lock, flags);
|
||||||
|
|
||||||
ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0));
|
ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0));
|
||||||
ctrl1 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL1));
|
ctrl1 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL1));
|
||||||
locked = chv_pad_locked(pctrl, offset);
|
locked = chv_pad_locked(pctrl, offset);
|
||||||
|
|
||||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
||||||
|
|
||||||
if (ctrl0 & CHV_PADCTRL0_GPIOEN) {
|
if (ctrl0 & CHV_PADCTRL0_GPIOEN) {
|
||||||
seq_puts(s, "GPIO ");
|
seq_puts(s, "GPIO ");
|
||||||
|
@ -787,14 +796,14 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function,
|
||||||
|
|
||||||
grp = &pctrl->community->groups[group];
|
grp = &pctrl->community->groups[group];
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&chv_lock, flags);
|
||||||
|
|
||||||
/* Check first that the pad is not locked */
|
/* Check first that the pad is not locked */
|
||||||
for (i = 0; i < grp->npins; i++) {
|
for (i = 0; i < grp->npins; i++) {
|
||||||
if (chv_pad_locked(pctrl, grp->pins[i])) {
|
if (chv_pad_locked(pctrl, grp->pins[i])) {
|
||||||
dev_warn(pctrl->dev, "unable to set mode for locked pin %u\n",
|
dev_warn(pctrl->dev, "unable to set mode for locked pin %u\n",
|
||||||
grp->pins[i]);
|
grp->pins[i]);
|
||||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -837,7 +846,7 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function,
|
||||||
pin, altfunc->mode, altfunc->invert_oe ? "" : "not ");
|
pin, altfunc->mode, altfunc->invert_oe ? "" : "not ");
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -851,13 +860,13 @@ static int chv_gpio_request_enable(struct pinctrl_dev *pctldev,
|
||||||
void __iomem *reg;
|
void __iomem *reg;
|
||||||
u32 value;
|
u32 value;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&chv_lock, flags);
|
||||||
|
|
||||||
if (chv_pad_locked(pctrl, offset)) {
|
if (chv_pad_locked(pctrl, offset)) {
|
||||||
value = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0));
|
value = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0));
|
||||||
if (!(value & CHV_PADCTRL0_GPIOEN)) {
|
if (!(value & CHV_PADCTRL0_GPIOEN)) {
|
||||||
/* Locked so cannot enable */
|
/* Locked so cannot enable */
|
||||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -897,7 +906,7 @@ static int chv_gpio_request_enable(struct pinctrl_dev *pctldev,
|
||||||
chv_writel(value, reg);
|
chv_writel(value, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -911,13 +920,13 @@ static void chv_gpio_disable_free(struct pinctrl_dev *pctldev,
|
||||||
void __iomem *reg;
|
void __iomem *reg;
|
||||||
u32 value;
|
u32 value;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&chv_lock, flags);
|
||||||
|
|
||||||
reg = chv_padreg(pctrl, offset, CHV_PADCTRL0);
|
reg = chv_padreg(pctrl, offset, CHV_PADCTRL0);
|
||||||
value = readl(reg) & ~CHV_PADCTRL0_GPIOEN;
|
value = readl(reg) & ~CHV_PADCTRL0_GPIOEN;
|
||||||
chv_writel(value, reg);
|
chv_writel(value, reg);
|
||||||
|
|
||||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int chv_gpio_set_direction(struct pinctrl_dev *pctldev,
|
static int chv_gpio_set_direction(struct pinctrl_dev *pctldev,
|
||||||
|
@ -929,7 +938,7 @@ static int chv_gpio_set_direction(struct pinctrl_dev *pctldev,
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 ctrl0;
|
u32 ctrl0;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&chv_lock, flags);
|
||||||
|
|
||||||
ctrl0 = readl(reg) & ~CHV_PADCTRL0_GPIOCFG_MASK;
|
ctrl0 = readl(reg) & ~CHV_PADCTRL0_GPIOCFG_MASK;
|
||||||
if (input)
|
if (input)
|
||||||
|
@ -938,7 +947,7 @@ static int chv_gpio_set_direction(struct pinctrl_dev *pctldev,
|
||||||
ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPO << CHV_PADCTRL0_GPIOCFG_SHIFT;
|
ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPO << CHV_PADCTRL0_GPIOCFG_SHIFT;
|
||||||
chv_writel(ctrl0, reg);
|
chv_writel(ctrl0, reg);
|
||||||
|
|
||||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -963,10 +972,10 @@ static int chv_config_get(struct pinctrl_dev *pctldev, unsigned pin,
|
||||||
u16 arg = 0;
|
u16 arg = 0;
|
||||||
u32 term;
|
u32 term;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&chv_lock, flags);
|
||||||
ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
|
ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
|
||||||
ctrl1 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL1));
|
ctrl1 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL1));
|
||||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
||||||
|
|
||||||
term = (ctrl0 & CHV_PADCTRL0_TERM_MASK) >> CHV_PADCTRL0_TERM_SHIFT;
|
term = (ctrl0 & CHV_PADCTRL0_TERM_MASK) >> CHV_PADCTRL0_TERM_SHIFT;
|
||||||
|
|
||||||
|
@ -1040,7 +1049,7 @@ static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned pin,
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 ctrl0, pull;
|
u32 ctrl0, pull;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&chv_lock, flags);
|
||||||
ctrl0 = readl(reg);
|
ctrl0 = readl(reg);
|
||||||
|
|
||||||
switch (param) {
|
switch (param) {
|
||||||
|
@ -1063,7 +1072,7 @@ static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned pin,
|
||||||
pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT;
|
pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1081,7 +1090,7 @@ static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned pin,
|
||||||
pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT;
|
pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1089,12 +1098,33 @@ static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned pin,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
chv_writel(ctrl0, reg);
|
chv_writel(ctrl0, reg);
|
||||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int chv_config_set_oden(struct chv_pinctrl *pctrl, unsigned int pin,
|
||||||
|
bool enable)
|
||||||
|
{
|
||||||
|
void __iomem *reg = chv_padreg(pctrl, pin, CHV_PADCTRL1);
|
||||||
|
unsigned long flags;
|
||||||
|
u32 ctrl1;
|
||||||
|
|
||||||
|
raw_spin_lock_irqsave(&chv_lock, flags);
|
||||||
|
ctrl1 = readl(reg);
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
ctrl1 |= CHV_PADCTRL1_ODEN;
|
||||||
|
else
|
||||||
|
ctrl1 &= ~CHV_PADCTRL1_ODEN;
|
||||||
|
|
||||||
|
chv_writel(ctrl1, reg);
|
||||||
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1123,6 +1153,18 @@ static int chv_config_set(struct pinctrl_dev *pctldev, unsigned pin,
|
||||||
return ret;
|
return ret;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PIN_CONFIG_DRIVE_PUSH_PULL:
|
||||||
|
ret = chv_config_set_oden(pctrl, pin, false);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
|
||||||
|
ret = chv_config_set_oden(pctrl, pin, true);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
}
|
}
|
||||||
|
@ -1134,10 +1176,52 @@ static int chv_config_set(struct pinctrl_dev *pctldev, unsigned pin,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int chv_config_group_get(struct pinctrl_dev *pctldev,
|
||||||
|
unsigned int group,
|
||||||
|
unsigned long *config)
|
||||||
|
{
|
||||||
|
const unsigned int *pins;
|
||||||
|
unsigned int npins;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = chv_get_group_pins(pctldev, group, &pins, &npins);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = chv_config_get(pctldev, pins[0], config);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int chv_config_group_set(struct pinctrl_dev *pctldev,
|
||||||
|
unsigned int group, unsigned long *configs,
|
||||||
|
unsigned int num_configs)
|
||||||
|
{
|
||||||
|
const unsigned int *pins;
|
||||||
|
unsigned int npins;
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
ret = chv_get_group_pins(pctldev, group, &pins, &npins);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
for (i = 0; i < npins; i++) {
|
||||||
|
ret = chv_config_set(pctldev, pins[i], configs, num_configs);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct pinconf_ops chv_pinconf_ops = {
|
static const struct pinconf_ops chv_pinconf_ops = {
|
||||||
.is_generic = true,
|
.is_generic = true,
|
||||||
.pin_config_set = chv_config_set,
|
.pin_config_set = chv_config_set,
|
||||||
.pin_config_get = chv_config_get,
|
.pin_config_get = chv_config_get,
|
||||||
|
.pin_config_group_get = chv_config_group_get,
|
||||||
|
.pin_config_group_set = chv_config_group_set,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct pinctrl_desc chv_pinctrl_desc = {
|
static struct pinctrl_desc chv_pinctrl_desc = {
|
||||||
|
@ -1160,9 +1244,9 @@ static int chv_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 ctrl0, cfg;
|
u32 ctrl0, cfg;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&chv_lock, flags);
|
||||||
ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
|
ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
|
||||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
||||||
|
|
||||||
cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK;
|
cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK;
|
||||||
cfg >>= CHV_PADCTRL0_GPIOCFG_SHIFT;
|
cfg >>= CHV_PADCTRL0_GPIOCFG_SHIFT;
|
||||||
|
@ -1180,7 +1264,7 @@ static void chv_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||||
void __iomem *reg;
|
void __iomem *reg;
|
||||||
u32 ctrl0;
|
u32 ctrl0;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&chv_lock, flags);
|
||||||
|
|
||||||
reg = chv_padreg(pctrl, pin, CHV_PADCTRL0);
|
reg = chv_padreg(pctrl, pin, CHV_PADCTRL0);
|
||||||
ctrl0 = readl(reg);
|
ctrl0 = readl(reg);
|
||||||
|
@ -1192,7 +1276,7 @@ static void chv_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||||
|
|
||||||
chv_writel(ctrl0, reg);
|
chv_writel(ctrl0, reg);
|
||||||
|
|
||||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
|
static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
|
||||||
|
@ -1202,9 +1286,9 @@ static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
|
||||||
u32 ctrl0, direction;
|
u32 ctrl0, direction;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&chv_lock, flags);
|
||||||
ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
|
ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
|
||||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
||||||
|
|
||||||
direction = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK;
|
direction = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK;
|
||||||
direction >>= CHV_PADCTRL0_GPIOCFG_SHIFT;
|
direction >>= CHV_PADCTRL0_GPIOCFG_SHIFT;
|
||||||
|
@ -1242,14 +1326,14 @@ static void chv_gpio_irq_ack(struct irq_data *d)
|
||||||
int pin = chv_gpio_offset_to_pin(pctrl, irqd_to_hwirq(d));
|
int pin = chv_gpio_offset_to_pin(pctrl, irqd_to_hwirq(d));
|
||||||
u32 intr_line;
|
u32 intr_line;
|
||||||
|
|
||||||
raw_spin_lock(&pctrl->lock);
|
raw_spin_lock(&chv_lock);
|
||||||
|
|
||||||
intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
|
intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
|
||||||
intr_line &= CHV_PADCTRL0_INTSEL_MASK;
|
intr_line &= CHV_PADCTRL0_INTSEL_MASK;
|
||||||
intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT;
|
intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT;
|
||||||
chv_writel(BIT(intr_line), pctrl->regs + CHV_INTSTAT);
|
chv_writel(BIT(intr_line), pctrl->regs + CHV_INTSTAT);
|
||||||
|
|
||||||
raw_spin_unlock(&pctrl->lock);
|
raw_spin_unlock(&chv_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
|
static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
|
||||||
|
@ -1260,7 +1344,7 @@ static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
|
||||||
u32 value, intr_line;
|
u32 value, intr_line;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&chv_lock, flags);
|
||||||
|
|
||||||
intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
|
intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
|
||||||
intr_line &= CHV_PADCTRL0_INTSEL_MASK;
|
intr_line &= CHV_PADCTRL0_INTSEL_MASK;
|
||||||
|
@ -1273,7 +1357,7 @@ static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
|
||||||
value |= BIT(intr_line);
|
value |= BIT(intr_line);
|
||||||
chv_writel(value, pctrl->regs + CHV_INTMASK);
|
chv_writel(value, pctrl->regs + CHV_INTMASK);
|
||||||
|
|
||||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void chv_gpio_irq_mask(struct irq_data *d)
|
static void chv_gpio_irq_mask(struct irq_data *d)
|
||||||
|
@ -1307,7 +1391,7 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 intsel, value;
|
u32 intsel, value;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&chv_lock, flags);
|
||||||
intsel = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
|
intsel = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
|
||||||
intsel &= CHV_PADCTRL0_INTSEL_MASK;
|
intsel &= CHV_PADCTRL0_INTSEL_MASK;
|
||||||
intsel >>= CHV_PADCTRL0_INTSEL_SHIFT;
|
intsel >>= CHV_PADCTRL0_INTSEL_SHIFT;
|
||||||
|
@ -1322,7 +1406,7 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d)
|
||||||
irq_set_handler_locked(d, handler);
|
irq_set_handler_locked(d, handler);
|
||||||
pctrl->intr_lines[intsel] = offset;
|
pctrl->intr_lines[intsel] = offset;
|
||||||
}
|
}
|
||||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
chv_gpio_irq_unmask(d);
|
chv_gpio_irq_unmask(d);
|
||||||
|
@ -1338,7 +1422,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned type)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 value;
|
u32 value;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&chv_lock, flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pins which can be used as shared interrupt are configured in
|
* Pins which can be used as shared interrupt are configured in
|
||||||
|
@ -1387,7 +1471,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned type)
|
||||||
else if (type & IRQ_TYPE_LEVEL_MASK)
|
else if (type & IRQ_TYPE_LEVEL_MASK)
|
||||||
irq_set_handler_locked(d, handle_level_irq);
|
irq_set_handler_locked(d, handle_level_irq);
|
||||||
|
|
||||||
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1499,7 +1583,6 @@ static int chv_pinctrl_probe(struct platform_device *pdev)
|
||||||
if (i == ARRAY_SIZE(chv_communities))
|
if (i == ARRAY_SIZE(chv_communities))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
raw_spin_lock_init(&pctrl->lock);
|
|
||||||
pctrl->dev = &pdev->dev;
|
pctrl->dev = &pdev->dev;
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
|
|
|
@ -89,7 +89,7 @@ struct intel_pinctrl_context {
|
||||||
*/
|
*/
|
||||||
struct intel_pinctrl {
|
struct intel_pinctrl {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
spinlock_t lock;
|
raw_spinlock_t lock;
|
||||||
struct pinctrl_desc pctldesc;
|
struct pinctrl_desc pctldesc;
|
||||||
struct pinctrl_dev *pctldev;
|
struct pinctrl_dev *pctldev;
|
||||||
struct gpio_chip chip;
|
struct gpio_chip chip;
|
||||||
|
@ -318,7 +318,7 @@ static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function,
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All pins in the groups needs to be accessible and writable
|
* All pins in the groups needs to be accessible and writable
|
||||||
|
@ -326,7 +326,7 @@ static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function,
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < grp->npins; i++) {
|
for (i = 0; i < grp->npins; i++) {
|
||||||
if (!intel_pad_usable(pctrl, grp->pins[i])) {
|
if (!intel_pad_usable(pctrl, grp->pins[i])) {
|
||||||
spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,7 +345,7 @@ static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function,
|
||||||
writel(value, padcfg0);
|
writel(value, padcfg0);
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -359,10 +359,10 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 value;
|
u32 value;
|
||||||
|
|
||||||
spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||||
|
|
||||||
if (!intel_pad_usable(pctrl, pin)) {
|
if (!intel_pad_usable(pctrl, pin)) {
|
||||||
spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,7 +377,7 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
|
||||||
value |= PADCFG0_GPIOTXDIS;
|
value |= PADCFG0_GPIOTXDIS;
|
||||||
writel(value, padcfg0);
|
writel(value, padcfg0);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -391,7 +391,7 @@ static int intel_gpio_set_direction(struct pinctrl_dev *pctldev,
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 value;
|
u32 value;
|
||||||
|
|
||||||
spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||||
|
|
||||||
padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
|
padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
|
||||||
|
|
||||||
|
@ -402,7 +402,7 @@ static int intel_gpio_set_direction(struct pinctrl_dev *pctldev,
|
||||||
value &= ~PADCFG0_GPIOTXDIS;
|
value &= ~PADCFG0_GPIOTXDIS;
|
||||||
writel(value, padcfg0);
|
writel(value, padcfg0);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -490,7 +490,7 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned pin,
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
u32 value;
|
u32 value;
|
||||||
|
|
||||||
spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||||
|
|
||||||
padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1);
|
padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1);
|
||||||
value = readl(padcfg1);
|
value = readl(padcfg1);
|
||||||
|
@ -544,7 +544,7 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned pin,
|
||||||
if (!ret)
|
if (!ret)
|
||||||
writel(value, padcfg1);
|
writel(value, padcfg1);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -611,14 +611,14 @@ static void intel_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 padcfg0;
|
u32 padcfg0;
|
||||||
|
|
||||||
spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||||
padcfg0 = readl(reg);
|
padcfg0 = readl(reg);
|
||||||
if (value)
|
if (value)
|
||||||
padcfg0 |= PADCFG0_GPIOTXSTATE;
|
padcfg0 |= PADCFG0_GPIOTXSTATE;
|
||||||
else
|
else
|
||||||
padcfg0 &= ~PADCFG0_GPIOTXSTATE;
|
padcfg0 &= ~PADCFG0_GPIOTXSTATE;
|
||||||
writel(padcfg0, reg);
|
writel(padcfg0, reg);
|
||||||
spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,7 +651,7 @@ static void intel_gpio_irq_ack(struct irq_data *d)
|
||||||
const struct intel_community *community;
|
const struct intel_community *community;
|
||||||
unsigned pin = irqd_to_hwirq(d);
|
unsigned pin = irqd_to_hwirq(d);
|
||||||
|
|
||||||
spin_lock(&pctrl->lock);
|
raw_spin_lock(&pctrl->lock);
|
||||||
|
|
||||||
community = intel_get_community(pctrl, pin);
|
community = intel_get_community(pctrl, pin);
|
||||||
if (community) {
|
if (community) {
|
||||||
|
@ -662,7 +662,7 @@ static void intel_gpio_irq_ack(struct irq_data *d)
|
||||||
writel(BIT(gpp_offset), community->regs + GPI_IS + gpp * 4);
|
writel(BIT(gpp_offset), community->regs + GPI_IS + gpp * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock(&pctrl->lock);
|
raw_spin_unlock(&pctrl->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void intel_gpio_irq_enable(struct irq_data *d)
|
static void intel_gpio_irq_enable(struct irq_data *d)
|
||||||
|
@ -673,7 +673,7 @@ static void intel_gpio_irq_enable(struct irq_data *d)
|
||||||
unsigned pin = irqd_to_hwirq(d);
|
unsigned pin = irqd_to_hwirq(d);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||||
|
|
||||||
community = intel_get_community(pctrl, pin);
|
community = intel_get_community(pctrl, pin);
|
||||||
if (community) {
|
if (community) {
|
||||||
|
@ -691,7 +691,7 @@ static void intel_gpio_irq_enable(struct irq_data *d)
|
||||||
writel(value, community->regs + community->ie_offset + gpp * 4);
|
writel(value, community->regs + community->ie_offset + gpp * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
|
static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
|
||||||
|
@ -702,7 +702,7 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
|
||||||
unsigned pin = irqd_to_hwirq(d);
|
unsigned pin = irqd_to_hwirq(d);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||||
|
|
||||||
community = intel_get_community(pctrl, pin);
|
community = intel_get_community(pctrl, pin);
|
||||||
if (community) {
|
if (community) {
|
||||||
|
@ -721,7 +721,7 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
|
||||||
writel(value, reg);
|
writel(value, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void intel_gpio_irq_mask(struct irq_data *d)
|
static void intel_gpio_irq_mask(struct irq_data *d)
|
||||||
|
@ -757,7 +757,7 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned type)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&pctrl->lock, flags);
|
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||||
|
|
||||||
value = readl(reg);
|
value = readl(reg);
|
||||||
|
|
||||||
|
@ -784,7 +784,7 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned type)
|
||||||
else if (type & IRQ_TYPE_LEVEL_MASK)
|
else if (type & IRQ_TYPE_LEVEL_MASK)
|
||||||
irq_set_handler_locked(d, handle_level_irq);
|
irq_set_handler_locked(d, handle_level_irq);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&pctrl->lock, flags);
|
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -796,12 +796,15 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on)
|
||||||
const struct intel_community *community;
|
const struct intel_community *community;
|
||||||
unsigned pin = irqd_to_hwirq(d);
|
unsigned pin = irqd_to_hwirq(d);
|
||||||
unsigned padno, gpp, gpp_offset;
|
unsigned padno, gpp, gpp_offset;
|
||||||
|
unsigned long flags;
|
||||||
u32 gpe_en;
|
u32 gpe_en;
|
||||||
|
|
||||||
community = intel_get_community(pctrl, pin);
|
community = intel_get_community(pctrl, pin);
|
||||||
if (!community)
|
if (!community)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||||
|
|
||||||
padno = pin_to_padno(community, pin);
|
padno = pin_to_padno(community, pin);
|
||||||
gpp = padno / community->gpp_size;
|
gpp = padno / community->gpp_size;
|
||||||
gpp_offset = padno % community->gpp_size;
|
gpp_offset = padno % community->gpp_size;
|
||||||
|
@ -821,6 +824,8 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on)
|
||||||
gpe_en &= ~BIT(gpp_offset);
|
gpe_en &= ~BIT(gpp_offset);
|
||||||
writel(gpe_en, community->regs + GPI_GPE_EN + gpp * 4);
|
writel(gpe_en, community->regs + GPI_GPE_EN + gpp * 4);
|
||||||
|
|
||||||
|
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||||
|
|
||||||
dev_dbg(pctrl->dev, "%sable wake for pin %u\n", on ? "en" : "dis", pin);
|
dev_dbg(pctrl->dev, "%sable wake for pin %u\n", on ? "en" : "dis", pin);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -919,7 +924,8 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
|
||||||
* to the irq directly) because on some platforms several GPIO
|
* to the irq directly) because on some platforms several GPIO
|
||||||
* controllers share the same interrupt line.
|
* controllers share the same interrupt line.
|
||||||
*/
|
*/
|
||||||
ret = devm_request_irq(pctrl->dev, irq, intel_gpio_irq, IRQF_SHARED,
|
ret = devm_request_irq(pctrl->dev, irq, intel_gpio_irq,
|
||||||
|
IRQF_SHARED | IRQF_NO_THREAD,
|
||||||
dev_name(pctrl->dev), pctrl);
|
dev_name(pctrl->dev), pctrl);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(pctrl->dev, "failed to request interrupt\n");
|
dev_err(pctrl->dev, "failed to request interrupt\n");
|
||||||
|
@ -995,7 +1001,7 @@ int intel_pinctrl_probe(struct platform_device *pdev,
|
||||||
|
|
||||||
pctrl->dev = &pdev->dev;
|
pctrl->dev = &pdev->dev;
|
||||||
pctrl->soc = soc_data;
|
pctrl->soc = soc_data;
|
||||||
spin_lock_init(&pctrl->lock);
|
raw_spin_lock_init(&pctrl->lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make a copy of the communities which we can use to hold pointers
|
* Make a copy of the communities which we can use to hold pointers
|
||||||
|
|
|
@ -0,0 +1,911 @@
|
||||||
|
/*
|
||||||
|
* Intel Merrifield SoC pinctrl driver
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016, Intel Corporation
|
||||||
|
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/bitops.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/pinctrl/pinconf.h>
|
||||||
|
#include <linux/pinctrl/pinconf-generic.h>
|
||||||
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
#include <linux/pinctrl/pinmux.h>
|
||||||
|
|
||||||
|
#include "pinctrl-intel.h"
|
||||||
|
|
||||||
|
#define MRFLD_FAMILY_NR 64
|
||||||
|
#define MRFLD_FAMILY_LEN 0x400
|
||||||
|
|
||||||
|
#define SLEW_OFFSET 0x000
|
||||||
|
#define BUFCFG_OFFSET 0x100
|
||||||
|
#define MISC_OFFSET 0x300
|
||||||
|
|
||||||
|
#define BUFCFG_PINMODE_SHIFT 0
|
||||||
|
#define BUFCFG_PINMODE_MASK GENMASK(2, 0)
|
||||||
|
#define BUFCFG_PINMODE_GPIO 0
|
||||||
|
#define BUFCFG_PUPD_VAL_SHIFT 4
|
||||||
|
#define BUFCFG_PUPD_VAL_MASK GENMASK(5, 4)
|
||||||
|
#define BUFCFG_PUPD_VAL_2K 0
|
||||||
|
#define BUFCFG_PUPD_VAL_20K 1
|
||||||
|
#define BUFCFG_PUPD_VAL_50K 2
|
||||||
|
#define BUFCFG_PUPD_VAL_910 3
|
||||||
|
#define BUFCFG_PU_EN BIT(8)
|
||||||
|
#define BUFCFG_PD_EN BIT(9)
|
||||||
|
#define BUFCFG_Px_EN_MASK GENMASK(9, 8)
|
||||||
|
#define BUFCFG_SLEWSEL BIT(10)
|
||||||
|
#define BUFCFG_OVINEN BIT(12)
|
||||||
|
#define BUFCFG_OVINEN_EN BIT(13)
|
||||||
|
#define BUFCFG_OVINEN_MASK GENMASK(13, 12)
|
||||||
|
#define BUFCFG_OVOUTEN BIT(14)
|
||||||
|
#define BUFCFG_OVOUTEN_EN BIT(15)
|
||||||
|
#define BUFCFG_OVOUTEN_MASK GENMASK(15, 14)
|
||||||
|
#define BUFCFG_INDATAOV_VAL BIT(16)
|
||||||
|
#define BUFCFG_INDATAOV_EN BIT(17)
|
||||||
|
#define BUFCFG_INDATAOV_MASK GENMASK(17, 16)
|
||||||
|
#define BUFCFG_OUTDATAOV_VAL BIT(18)
|
||||||
|
#define BUFCFG_OUTDATAOV_EN BIT(19)
|
||||||
|
#define BUFCFG_OUTDATAOV_MASK GENMASK(19, 18)
|
||||||
|
#define BUFCFG_OD_EN BIT(21)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct mrfld_family - Intel pin family description
|
||||||
|
* @barno: MMIO BAR number where registers for this family reside
|
||||||
|
* @pin_base: Starting pin of pins in this family
|
||||||
|
* @npins: Number of pins in this family
|
||||||
|
* @protected: True if family is protected by access
|
||||||
|
* @regs: family specific common registers
|
||||||
|
*/
|
||||||
|
struct mrfld_family {
|
||||||
|
unsigned int barno;
|
||||||
|
unsigned int pin_base;
|
||||||
|
size_t npins;
|
||||||
|
bool protected;
|
||||||
|
void __iomem *regs;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MRFLD_FAMILY(b, s, e) \
|
||||||
|
{ \
|
||||||
|
.barno = (b), \
|
||||||
|
.pin_base = (s), \
|
||||||
|
.npins = (e) - (s) + 1, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MRFLD_FAMILY_PROTECTED(b, s, e) \
|
||||||
|
{ \
|
||||||
|
.barno = (b), \
|
||||||
|
.pin_base = (s), \
|
||||||
|
.npins = (e) - (s) + 1, \
|
||||||
|
.protected = true, \
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct pinctrl_pin_desc mrfld_pins[] = {
|
||||||
|
/* Family 0: OCP2SSC (0 pins) */
|
||||||
|
/* Family 1: ULPI (13 pins) */
|
||||||
|
PINCTRL_PIN(0, "ULPI_CLK"),
|
||||||
|
PINCTRL_PIN(1, "ULPI_D0"),
|
||||||
|
PINCTRL_PIN(2, "ULPI_D1"),
|
||||||
|
PINCTRL_PIN(3, "ULPI_D2"),
|
||||||
|
PINCTRL_PIN(4, "ULPI_D3"),
|
||||||
|
PINCTRL_PIN(5, "ULPI_D4"),
|
||||||
|
PINCTRL_PIN(6, "ULPI_D5"),
|
||||||
|
PINCTRL_PIN(7, "ULPI_D6"),
|
||||||
|
PINCTRL_PIN(8, "ULPI_D7"),
|
||||||
|
PINCTRL_PIN(9, "ULPI_DIR"),
|
||||||
|
PINCTRL_PIN(10, "ULPI_NXT"),
|
||||||
|
PINCTRL_PIN(11, "ULPI_REFCLK"),
|
||||||
|
PINCTRL_PIN(12, "ULPI_STP"),
|
||||||
|
/* Family 2: eMMC (24 pins) */
|
||||||
|
PINCTRL_PIN(13, "EMMC_CLK"),
|
||||||
|
PINCTRL_PIN(14, "EMMC_CMD"),
|
||||||
|
PINCTRL_PIN(15, "EMMC_D0"),
|
||||||
|
PINCTRL_PIN(16, "EMMC_D1"),
|
||||||
|
PINCTRL_PIN(17, "EMMC_D2"),
|
||||||
|
PINCTRL_PIN(18, "EMMC_D3"),
|
||||||
|
PINCTRL_PIN(19, "EMMC_D4"),
|
||||||
|
PINCTRL_PIN(20, "EMMC_D5"),
|
||||||
|
PINCTRL_PIN(21, "EMMC_D6"),
|
||||||
|
PINCTRL_PIN(22, "EMMC_D7"),
|
||||||
|
PINCTRL_PIN(23, "EMMC_RST_N"),
|
||||||
|
PINCTRL_PIN(24, "GP154"),
|
||||||
|
PINCTRL_PIN(25, "GP155"),
|
||||||
|
PINCTRL_PIN(26, "GP156"),
|
||||||
|
PINCTRL_PIN(27, "GP157"),
|
||||||
|
PINCTRL_PIN(28, "GP158"),
|
||||||
|
PINCTRL_PIN(29, "GP159"),
|
||||||
|
PINCTRL_PIN(30, "GP160"),
|
||||||
|
PINCTRL_PIN(31, "GP161"),
|
||||||
|
PINCTRL_PIN(32, "GP162"),
|
||||||
|
PINCTRL_PIN(33, "GP163"),
|
||||||
|
PINCTRL_PIN(34, "GP97"),
|
||||||
|
PINCTRL_PIN(35, "GP14"),
|
||||||
|
PINCTRL_PIN(36, "GP15"),
|
||||||
|
/* Family 3: SDIO (20 pins) */
|
||||||
|
PINCTRL_PIN(37, "GP77_SD_CD"),
|
||||||
|
PINCTRL_PIN(38, "GP78_SD_CLK"),
|
||||||
|
PINCTRL_PIN(39, "GP79_SD_CMD"),
|
||||||
|
PINCTRL_PIN(40, "GP80_SD_D0"),
|
||||||
|
PINCTRL_PIN(41, "GP81_SD_D1"),
|
||||||
|
PINCTRL_PIN(42, "GP82_SD_D2"),
|
||||||
|
PINCTRL_PIN(43, "GP83_SD_D3"),
|
||||||
|
PINCTRL_PIN(44, "GP84_SD_LS_CLK_FB"),
|
||||||
|
PINCTRL_PIN(45, "GP85_SD_LS_CMD_DIR"),
|
||||||
|
PINCTRL_PIN(46, "GP86_SD_LVL_D_DIR"),
|
||||||
|
PINCTRL_PIN(47, "GP88_SD_LS_SEL"),
|
||||||
|
PINCTRL_PIN(48, "GP87_SD_PD"),
|
||||||
|
PINCTRL_PIN(49, "GP89_SD_WP"),
|
||||||
|
PINCTRL_PIN(50, "GP90_SDIO_CLK"),
|
||||||
|
PINCTRL_PIN(51, "GP91_SDIO_CMD"),
|
||||||
|
PINCTRL_PIN(52, "GP92_SDIO_D0"),
|
||||||
|
PINCTRL_PIN(53, "GP93_SDIO_D1"),
|
||||||
|
PINCTRL_PIN(54, "GP94_SDIO_D2"),
|
||||||
|
PINCTRL_PIN(55, "GP95_SDIO_D3"),
|
||||||
|
PINCTRL_PIN(56, "GP96_SDIO_PD"),
|
||||||
|
/* Family 4: HSI (8 pins) */
|
||||||
|
PINCTRL_PIN(57, "HSI_ACDATA"),
|
||||||
|
PINCTRL_PIN(58, "HSI_ACFLAG"),
|
||||||
|
PINCTRL_PIN(59, "HSI_ACREADY"),
|
||||||
|
PINCTRL_PIN(60, "HSI_ACWAKE"),
|
||||||
|
PINCTRL_PIN(61, "HSI_CADATA"),
|
||||||
|
PINCTRL_PIN(62, "HSI_CAFLAG"),
|
||||||
|
PINCTRL_PIN(63, "HSI_CAREADY"),
|
||||||
|
PINCTRL_PIN(64, "HSI_CAWAKE"),
|
||||||
|
/* Family 5: SSP Audio (14 pins) */
|
||||||
|
PINCTRL_PIN(65, "GP70"),
|
||||||
|
PINCTRL_PIN(66, "GP71"),
|
||||||
|
PINCTRL_PIN(67, "GP32_I2S_0_CLK"),
|
||||||
|
PINCTRL_PIN(68, "GP33_I2S_0_FS"),
|
||||||
|
PINCTRL_PIN(69, "GP34_I2S_0_RXD"),
|
||||||
|
PINCTRL_PIN(70, "GP35_I2S_0_TXD"),
|
||||||
|
PINCTRL_PIN(71, "GP36_I2S_1_CLK"),
|
||||||
|
PINCTRL_PIN(72, "GP37_I2S_1_FS"),
|
||||||
|
PINCTRL_PIN(73, "GP38_I2S_1_RXD"),
|
||||||
|
PINCTRL_PIN(74, "GP39_I2S_1_TXD"),
|
||||||
|
PINCTRL_PIN(75, "GP40_I2S_2_CLK"),
|
||||||
|
PINCTRL_PIN(76, "GP41_I2S_2_FS"),
|
||||||
|
PINCTRL_PIN(77, "GP42_I2S_2_RXD"),
|
||||||
|
PINCTRL_PIN(78, "GP43_I2S_2_TXD"),
|
||||||
|
/* Family 6: GP SSP (22 pins) */
|
||||||
|
PINCTRL_PIN(79, "GP120_SPI_3_CLK"),
|
||||||
|
PINCTRL_PIN(80, "GP121_SPI_3_SS"),
|
||||||
|
PINCTRL_PIN(81, "GP122_SPI_3_RXD"),
|
||||||
|
PINCTRL_PIN(82, "GP123_SPI_3_TXD"),
|
||||||
|
PINCTRL_PIN(83, "GP102_SPI_4_CLK"),
|
||||||
|
PINCTRL_PIN(84, "GP103_SPI_4_SS_0"),
|
||||||
|
PINCTRL_PIN(85, "GP104_SPI_4_SS_1"),
|
||||||
|
PINCTRL_PIN(86, "GP105_SPI_4_SS_2"),
|
||||||
|
PINCTRL_PIN(87, "GP106_SPI_4_SS_3"),
|
||||||
|
PINCTRL_PIN(88, "GP107_SPI_4_RXD"),
|
||||||
|
PINCTRL_PIN(89, "GP108_SPI_4_TXD"),
|
||||||
|
PINCTRL_PIN(90, "GP109_SPI_5_CLK"),
|
||||||
|
PINCTRL_PIN(91, "GP110_SPI_5_SS_0"),
|
||||||
|
PINCTRL_PIN(92, "GP111_SPI_5_SS_1"),
|
||||||
|
PINCTRL_PIN(93, "GP112_SPI_5_SS_2"),
|
||||||
|
PINCTRL_PIN(94, "GP113_SPI_5_SS_3"),
|
||||||
|
PINCTRL_PIN(95, "GP114_SPI_5_RXD"),
|
||||||
|
PINCTRL_PIN(96, "GP115_SPI_5_TXD"),
|
||||||
|
PINCTRL_PIN(97, "GP116_SPI_6_CLK"),
|
||||||
|
PINCTRL_PIN(98, "GP117_SPI_6_SS"),
|
||||||
|
PINCTRL_PIN(99, "GP118_SPI_6_RXD"),
|
||||||
|
PINCTRL_PIN(100, "GP119_SPI_6_TXD"),
|
||||||
|
/* Family 7: I2C (14 pins) */
|
||||||
|
PINCTRL_PIN(101, "GP19_I2C_1_SCL"),
|
||||||
|
PINCTRL_PIN(102, "GP20_I2C_1_SDA"),
|
||||||
|
PINCTRL_PIN(103, "GP21_I2C_2_SCL"),
|
||||||
|
PINCTRL_PIN(104, "GP22_I2C_2_SDA"),
|
||||||
|
PINCTRL_PIN(105, "GP17_I2C_3_SCL_HDMI"),
|
||||||
|
PINCTRL_PIN(106, "GP18_I2C_3_SDA_HDMI"),
|
||||||
|
PINCTRL_PIN(107, "GP23_I2C_4_SCL"),
|
||||||
|
PINCTRL_PIN(108, "GP24_I2C_4_SDA"),
|
||||||
|
PINCTRL_PIN(109, "GP25_I2C_5_SCL"),
|
||||||
|
PINCTRL_PIN(110, "GP26_I2C_5_SDA"),
|
||||||
|
PINCTRL_PIN(111, "GP27_I2C_6_SCL"),
|
||||||
|
PINCTRL_PIN(112, "GP28_I2C_6_SDA"),
|
||||||
|
PINCTRL_PIN(113, "GP29_I2C_7_SCL"),
|
||||||
|
PINCTRL_PIN(114, "GP30_I2C_7_SDA"),
|
||||||
|
/* Family 8: UART (12 pins) */
|
||||||
|
PINCTRL_PIN(115, "GP124_UART_0_CTS"),
|
||||||
|
PINCTRL_PIN(116, "GP125_UART_0_RTS"),
|
||||||
|
PINCTRL_PIN(117, "GP126_UART_0_RX"),
|
||||||
|
PINCTRL_PIN(118, "GP127_UART_0_TX"),
|
||||||
|
PINCTRL_PIN(119, "GP128_UART_1_CTS"),
|
||||||
|
PINCTRL_PIN(120, "GP129_UART_1_RTS"),
|
||||||
|
PINCTRL_PIN(121, "GP130_UART_1_RX"),
|
||||||
|
PINCTRL_PIN(122, "GP131_UART_1_TX"),
|
||||||
|
PINCTRL_PIN(123, "GP132_UART_2_CTS"),
|
||||||
|
PINCTRL_PIN(124, "GP133_UART_2_RTS"),
|
||||||
|
PINCTRL_PIN(125, "GP134_UART_2_RX"),
|
||||||
|
PINCTRL_PIN(126, "GP135_UART_2_TX"),
|
||||||
|
/* Family 9: GPIO South (19 pins) */
|
||||||
|
PINCTRL_PIN(127, "GP177"),
|
||||||
|
PINCTRL_PIN(128, "GP178"),
|
||||||
|
PINCTRL_PIN(129, "GP179"),
|
||||||
|
PINCTRL_PIN(130, "GP180"),
|
||||||
|
PINCTRL_PIN(131, "GP181"),
|
||||||
|
PINCTRL_PIN(132, "GP182_PWM2"),
|
||||||
|
PINCTRL_PIN(133, "GP183_PWM3"),
|
||||||
|
PINCTRL_PIN(134, "GP184"),
|
||||||
|
PINCTRL_PIN(135, "GP185"),
|
||||||
|
PINCTRL_PIN(136, "GP186"),
|
||||||
|
PINCTRL_PIN(137, "GP187"),
|
||||||
|
PINCTRL_PIN(138, "GP188"),
|
||||||
|
PINCTRL_PIN(139, "GP189"),
|
||||||
|
PINCTRL_PIN(140, "GP64_FAST_INT0"),
|
||||||
|
PINCTRL_PIN(141, "GP65_FAST_INT1"),
|
||||||
|
PINCTRL_PIN(142, "GP66_FAST_INT2"),
|
||||||
|
PINCTRL_PIN(143, "GP67_FAST_INT3"),
|
||||||
|
PINCTRL_PIN(144, "GP12_PWM0"),
|
||||||
|
PINCTRL_PIN(145, "GP13_PWM1"),
|
||||||
|
/* Family 10: Camera Sideband (12 pins) */
|
||||||
|
PINCTRL_PIN(146, "GP0"),
|
||||||
|
PINCTRL_PIN(147, "GP1"),
|
||||||
|
PINCTRL_PIN(148, "GP2"),
|
||||||
|
PINCTRL_PIN(149, "GP3"),
|
||||||
|
PINCTRL_PIN(150, "GP4"),
|
||||||
|
PINCTRL_PIN(151, "GP5"),
|
||||||
|
PINCTRL_PIN(152, "GP6"),
|
||||||
|
PINCTRL_PIN(153, "GP7"),
|
||||||
|
PINCTRL_PIN(154, "GP8"),
|
||||||
|
PINCTRL_PIN(155, "GP9"),
|
||||||
|
PINCTRL_PIN(156, "GP10"),
|
||||||
|
PINCTRL_PIN(157, "GP11"),
|
||||||
|
/* Family 11: Clock (22 pins) */
|
||||||
|
PINCTRL_PIN(158, "GP137"),
|
||||||
|
PINCTRL_PIN(159, "GP138"),
|
||||||
|
PINCTRL_PIN(160, "GP139"),
|
||||||
|
PINCTRL_PIN(161, "GP140"),
|
||||||
|
PINCTRL_PIN(162, "GP141"),
|
||||||
|
PINCTRL_PIN(163, "GP142"),
|
||||||
|
PINCTRL_PIN(164, "GP16_HDMI_HPD"),
|
||||||
|
PINCTRL_PIN(165, "GP68_DSI_A_TE"),
|
||||||
|
PINCTRL_PIN(166, "GP69_DSI_C_TE"),
|
||||||
|
PINCTRL_PIN(167, "OSC_CLK_CTRL0"),
|
||||||
|
PINCTRL_PIN(168, "OSC_CLK_CTRL1"),
|
||||||
|
PINCTRL_PIN(169, "OSC_CLK0"),
|
||||||
|
PINCTRL_PIN(170, "OSC_CLK1"),
|
||||||
|
PINCTRL_PIN(171, "OSC_CLK2"),
|
||||||
|
PINCTRL_PIN(172, "OSC_CLK3"),
|
||||||
|
PINCTRL_PIN(173, "OSC_CLK4"),
|
||||||
|
PINCTRL_PIN(174, "RESETOUT"),
|
||||||
|
PINCTRL_PIN(175, "PMODE"),
|
||||||
|
PINCTRL_PIN(176, "PRDY"),
|
||||||
|
PINCTRL_PIN(177, "PREQ"),
|
||||||
|
PINCTRL_PIN(178, "GP190"),
|
||||||
|
PINCTRL_PIN(179, "GP191"),
|
||||||
|
/* Family 12: MSIC (15 pins) */
|
||||||
|
PINCTRL_PIN(180, "I2C_0_SCL"),
|
||||||
|
PINCTRL_PIN(181, "I2C_0_SDA"),
|
||||||
|
PINCTRL_PIN(182, "IERR"),
|
||||||
|
PINCTRL_PIN(183, "JTAG_TCK"),
|
||||||
|
PINCTRL_PIN(184, "JTAG_TDI"),
|
||||||
|
PINCTRL_PIN(185, "JTAG_TDO"),
|
||||||
|
PINCTRL_PIN(186, "JTAG_TMS"),
|
||||||
|
PINCTRL_PIN(187, "JTAG_TRST"),
|
||||||
|
PINCTRL_PIN(188, "PROCHOT"),
|
||||||
|
PINCTRL_PIN(189, "RTC_CLK"),
|
||||||
|
PINCTRL_PIN(190, "SVID_ALERT"),
|
||||||
|
PINCTRL_PIN(191, "SVID_CLK"),
|
||||||
|
PINCTRL_PIN(192, "SVID_D"),
|
||||||
|
PINCTRL_PIN(193, "THERMTRIP"),
|
||||||
|
PINCTRL_PIN(194, "STANDBY"),
|
||||||
|
/* Family 13: Keyboard (20 pins) */
|
||||||
|
PINCTRL_PIN(195, "GP44"),
|
||||||
|
PINCTRL_PIN(196, "GP45"),
|
||||||
|
PINCTRL_PIN(197, "GP46"),
|
||||||
|
PINCTRL_PIN(198, "GP47"),
|
||||||
|
PINCTRL_PIN(199, "GP48"),
|
||||||
|
PINCTRL_PIN(200, "GP49"),
|
||||||
|
PINCTRL_PIN(201, "GP50"),
|
||||||
|
PINCTRL_PIN(202, "GP51"),
|
||||||
|
PINCTRL_PIN(203, "GP52"),
|
||||||
|
PINCTRL_PIN(204, "GP53"),
|
||||||
|
PINCTRL_PIN(205, "GP54"),
|
||||||
|
PINCTRL_PIN(206, "GP55"),
|
||||||
|
PINCTRL_PIN(207, "GP56"),
|
||||||
|
PINCTRL_PIN(208, "GP57"),
|
||||||
|
PINCTRL_PIN(209, "GP58"),
|
||||||
|
PINCTRL_PIN(210, "GP59"),
|
||||||
|
PINCTRL_PIN(211, "GP60"),
|
||||||
|
PINCTRL_PIN(212, "GP61"),
|
||||||
|
PINCTRL_PIN(213, "GP62"),
|
||||||
|
PINCTRL_PIN(214, "GP63"),
|
||||||
|
/* Family 14: GPIO North (13 pins) */
|
||||||
|
PINCTRL_PIN(215, "GP164"),
|
||||||
|
PINCTRL_PIN(216, "GP165"),
|
||||||
|
PINCTRL_PIN(217, "GP166"),
|
||||||
|
PINCTRL_PIN(218, "GP167"),
|
||||||
|
PINCTRL_PIN(219, "GP168_MJTAG_TCK"),
|
||||||
|
PINCTRL_PIN(220, "GP169_MJTAG_TDI"),
|
||||||
|
PINCTRL_PIN(221, "GP170_MJTAG_TDO"),
|
||||||
|
PINCTRL_PIN(222, "GP171_MJTAG_TMS"),
|
||||||
|
PINCTRL_PIN(223, "GP172_MJTAG_TRST"),
|
||||||
|
PINCTRL_PIN(224, "GP173"),
|
||||||
|
PINCTRL_PIN(225, "GP174"),
|
||||||
|
PINCTRL_PIN(226, "GP175"),
|
||||||
|
PINCTRL_PIN(227, "GP176"),
|
||||||
|
/* Family 15: PTI (5 pins) */
|
||||||
|
PINCTRL_PIN(228, "GP72_PTI_CLK"),
|
||||||
|
PINCTRL_PIN(229, "GP73_PTI_D0"),
|
||||||
|
PINCTRL_PIN(230, "GP74_PTI_D1"),
|
||||||
|
PINCTRL_PIN(231, "GP75_PTI_D2"),
|
||||||
|
PINCTRL_PIN(232, "GP76_PTI_D3"),
|
||||||
|
/* Family 16: USB3 (0 pins) */
|
||||||
|
/* Family 17: HSIC (0 pins) */
|
||||||
|
/* Family 18: Broadcast (0 pins) */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned int mrfld_sdio_pins[] = { 50, 51, 52, 53, 54, 55, 56 };
|
||||||
|
static const unsigned int mrfld_spi5_pins[] = { 90, 91, 92, 93, 94, 95, 96 };
|
||||||
|
static const unsigned int mrfld_uart0_pins[] = { 124, 125, 126, 127 };
|
||||||
|
static const unsigned int mrfld_uart1_pins[] = { 128, 129, 130, 131 };
|
||||||
|
static const unsigned int mrfld_uart2_pins[] = { 132, 133, 134, 135 };
|
||||||
|
static const unsigned int mrfld_pwm0_pins[] = { 144 };
|
||||||
|
static const unsigned int mrfld_pwm1_pins[] = { 145 };
|
||||||
|
static const unsigned int mrfld_pwm2_pins[] = { 132 };
|
||||||
|
static const unsigned int mrfld_pwm3_pins[] = { 133 };
|
||||||
|
|
||||||
|
static const struct intel_pingroup mrfld_groups[] = {
|
||||||
|
PIN_GROUP("sdio_grp", mrfld_sdio_pins, 1),
|
||||||
|
PIN_GROUP("spi5_grp", mrfld_spi5_pins, 1),
|
||||||
|
PIN_GROUP("uart0_grp", mrfld_uart0_pins, 1),
|
||||||
|
PIN_GROUP("uart1_grp", mrfld_uart1_pins, 1),
|
||||||
|
PIN_GROUP("uart2_grp", mrfld_uart2_pins, 1),
|
||||||
|
PIN_GROUP("pwm0_grp", mrfld_pwm0_pins, 1),
|
||||||
|
PIN_GROUP("pwm1_grp", mrfld_pwm1_pins, 1),
|
||||||
|
PIN_GROUP("pwm2_grp", mrfld_pwm2_pins, 1),
|
||||||
|
PIN_GROUP("pwm3_grp", mrfld_pwm3_pins, 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const mrfld_sdio_groups[] = { "sdio_grp" };
|
||||||
|
static const char * const mrfld_spi5_groups[] = { "spi5_grp" };
|
||||||
|
static const char * const mrfld_uart0_groups[] = { "uart0_grp" };
|
||||||
|
static const char * const mrfld_uart1_groups[] = { "uart1_grp" };
|
||||||
|
static const char * const mrfld_uart2_groups[] = { "uart2_grp" };
|
||||||
|
static const char * const mrfld_pwm0_groups[] = { "pwm0_grp" };
|
||||||
|
static const char * const mrfld_pwm1_groups[] = { "pwm1_grp" };
|
||||||
|
static const char * const mrfld_pwm2_groups[] = { "pwm2_grp" };
|
||||||
|
static const char * const mrfld_pwm3_groups[] = { "pwm3_grp" };
|
||||||
|
|
||||||
|
static const struct intel_function mrfld_functions[] = {
|
||||||
|
FUNCTION("sdio", mrfld_sdio_groups),
|
||||||
|
FUNCTION("spi5", mrfld_spi5_groups),
|
||||||
|
FUNCTION("uart0", mrfld_uart0_groups),
|
||||||
|
FUNCTION("uart1", mrfld_uart1_groups),
|
||||||
|
FUNCTION("uart2", mrfld_uart2_groups),
|
||||||
|
FUNCTION("pwm0", mrfld_pwm0_groups),
|
||||||
|
FUNCTION("pwm1", mrfld_pwm1_groups),
|
||||||
|
FUNCTION("pwm2", mrfld_pwm2_groups),
|
||||||
|
FUNCTION("pwm3", mrfld_pwm3_groups),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct mrfld_family mrfld_families[] = {
|
||||||
|
MRFLD_FAMILY(1, 0, 12),
|
||||||
|
MRFLD_FAMILY(2, 13, 36),
|
||||||
|
MRFLD_FAMILY(3, 37, 56),
|
||||||
|
MRFLD_FAMILY(4, 57, 64),
|
||||||
|
MRFLD_FAMILY(5, 65, 78),
|
||||||
|
MRFLD_FAMILY(6, 79, 100),
|
||||||
|
MRFLD_FAMILY_PROTECTED(7, 101, 114),
|
||||||
|
MRFLD_FAMILY(8, 115, 126),
|
||||||
|
MRFLD_FAMILY(9, 127, 145),
|
||||||
|
MRFLD_FAMILY(10, 146, 157),
|
||||||
|
MRFLD_FAMILY(11, 158, 179),
|
||||||
|
MRFLD_FAMILY_PROTECTED(12, 180, 194),
|
||||||
|
MRFLD_FAMILY(13, 195, 214),
|
||||||
|
MRFLD_FAMILY(14, 215, 227),
|
||||||
|
MRFLD_FAMILY(15, 228, 232),
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct mrfld_pinctrl - Intel Merrifield pinctrl private structure
|
||||||
|
* @dev: Pointer to the device structure
|
||||||
|
* @lock: Lock to serialize register access
|
||||||
|
* @pctldesc: Pin controller description
|
||||||
|
* @pctldev: Pointer to the pin controller device
|
||||||
|
* @families: Array of families this pinctrl handles
|
||||||
|
* @nfamilies: Number of families in the array
|
||||||
|
* @functions: Array of functions
|
||||||
|
* @nfunctions: Number of functions in the array
|
||||||
|
* @groups: Array of pin groups
|
||||||
|
* @ngroups: Number of groups in the array
|
||||||
|
* @pins: Array of pins this pinctrl controls
|
||||||
|
* @npins: Number of pins in the array
|
||||||
|
*/
|
||||||
|
struct mrfld_pinctrl {
|
||||||
|
struct device *dev;
|
||||||
|
raw_spinlock_t lock;
|
||||||
|
struct pinctrl_desc pctldesc;
|
||||||
|
struct pinctrl_dev *pctldev;
|
||||||
|
|
||||||
|
/* Pin controller configuration */
|
||||||
|
const struct mrfld_family *families;
|
||||||
|
size_t nfamilies;
|
||||||
|
const struct intel_function *functions;
|
||||||
|
size_t nfunctions;
|
||||||
|
const struct intel_pingroup *groups;
|
||||||
|
size_t ngroups;
|
||||||
|
const struct pinctrl_pin_desc *pins;
|
||||||
|
size_t npins;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define pin_to_bufno(f, p) ((p) - (f)->pin_base)
|
||||||
|
|
||||||
|
static const struct mrfld_family *mrfld_get_family(struct mrfld_pinctrl *mp,
|
||||||
|
unsigned int pin)
|
||||||
|
{
|
||||||
|
const struct mrfld_family *family;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < mp->nfamilies; i++) {
|
||||||
|
family = &mp->families[i];
|
||||||
|
if (pin >= family->pin_base &&
|
||||||
|
pin < family->pin_base + family->npins)
|
||||||
|
return family;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_warn(mp->dev, "failed to find family for pin %u\n", pin);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool mrfld_buf_available(struct mrfld_pinctrl *mp, unsigned int pin)
|
||||||
|
{
|
||||||
|
const struct mrfld_family *family;
|
||||||
|
|
||||||
|
family = mrfld_get_family(mp, pin);
|
||||||
|
if (!family)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return !family->protected;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __iomem *mrfld_get_bufcfg(struct mrfld_pinctrl *mp, unsigned int pin)
|
||||||
|
{
|
||||||
|
const struct mrfld_family *family;
|
||||||
|
unsigned int bufno;
|
||||||
|
|
||||||
|
family = mrfld_get_family(mp, pin);
|
||||||
|
if (!family)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
bufno = pin_to_bufno(family, pin);
|
||||||
|
return family->regs + BUFCFG_OFFSET + bufno * 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mrfld_get_groups_count(struct pinctrl_dev *pctldev)
|
||||||
|
{
|
||||||
|
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
|
||||||
|
return mp->ngroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *mrfld_get_group_name(struct pinctrl_dev *pctldev,
|
||||||
|
unsigned int group)
|
||||||
|
{
|
||||||
|
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
|
||||||
|
return mp->groups[group].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mrfld_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group,
|
||||||
|
const unsigned int **pins, unsigned int *npins)
|
||||||
|
{
|
||||||
|
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
|
||||||
|
*pins = mp->groups[group].pins;
|
||||||
|
*npins = mp->groups[group].npins;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mrfld_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
|
||||||
|
unsigned int pin)
|
||||||
|
{
|
||||||
|
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
void __iomem *bufcfg;
|
||||||
|
u32 value, mode;
|
||||||
|
|
||||||
|
if (!mrfld_buf_available(mp, pin)) {
|
||||||
|
seq_puts(s, "not available");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufcfg = mrfld_get_bufcfg(mp, pin);
|
||||||
|
value = readl(bufcfg);
|
||||||
|
|
||||||
|
mode = (value & BUFCFG_PINMODE_MASK) >> BUFCFG_PINMODE_SHIFT;
|
||||||
|
if (!mode)
|
||||||
|
seq_puts(s, "GPIO ");
|
||||||
|
else
|
||||||
|
seq_printf(s, "mode %d ", mode);
|
||||||
|
|
||||||
|
seq_printf(s, "0x%08x", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct pinctrl_ops mrfld_pinctrl_ops = {
|
||||||
|
.get_groups_count = mrfld_get_groups_count,
|
||||||
|
.get_group_name = mrfld_get_group_name,
|
||||||
|
.get_group_pins = mrfld_get_group_pins,
|
||||||
|
.pin_dbg_show = mrfld_pin_dbg_show,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mrfld_get_functions_count(struct pinctrl_dev *pctldev)
|
||||||
|
{
|
||||||
|
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
|
||||||
|
return mp->nfunctions;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *mrfld_get_function_name(struct pinctrl_dev *pctldev,
|
||||||
|
unsigned int function)
|
||||||
|
{
|
||||||
|
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
|
||||||
|
return mp->functions[function].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mrfld_get_function_groups(struct pinctrl_dev *pctldev,
|
||||||
|
unsigned int function,
|
||||||
|
const char * const **groups,
|
||||||
|
unsigned int * const ngroups)
|
||||||
|
{
|
||||||
|
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
|
||||||
|
*groups = mp->functions[function].groups;
|
||||||
|
*ngroups = mp->functions[function].ngroups;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mrfld_update_bufcfg(struct mrfld_pinctrl *mp, unsigned int pin,
|
||||||
|
u32 bits, u32 mask)
|
||||||
|
{
|
||||||
|
void __iomem *bufcfg;
|
||||||
|
u32 value;
|
||||||
|
|
||||||
|
bufcfg = mrfld_get_bufcfg(mp, pin);
|
||||||
|
value = readl(bufcfg);
|
||||||
|
|
||||||
|
value &= ~mask;
|
||||||
|
value |= bits & mask;
|
||||||
|
|
||||||
|
writel(value, bufcfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mrfld_pinmux_set_mux(struct pinctrl_dev *pctldev,
|
||||||
|
unsigned int function,
|
||||||
|
unsigned int group)
|
||||||
|
{
|
||||||
|
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
const struct intel_pingroup *grp = &mp->groups[group];
|
||||||
|
u32 bits = grp->mode << BUFCFG_PINMODE_SHIFT;
|
||||||
|
u32 mask = BUFCFG_PINMODE_MASK;
|
||||||
|
unsigned long flags;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All pins in the groups needs to be accessible and writable
|
||||||
|
* before we can enable the mux for this group.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < grp->npins; i++) {
|
||||||
|
if (!mrfld_buf_available(mp, grp->pins[i]))
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now enable the mux setting for each pin in the group */
|
||||||
|
raw_spin_lock_irqsave(&mp->lock, flags);
|
||||||
|
for (i = 0; i < grp->npins; i++)
|
||||||
|
mrfld_update_bufcfg(mp, grp->pins[i], bits, mask);
|
||||||
|
raw_spin_unlock_irqrestore(&mp->lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mrfld_gpio_request_enable(struct pinctrl_dev *pctldev,
|
||||||
|
struct pinctrl_gpio_range *range,
|
||||||
|
unsigned int pin)
|
||||||
|
{
|
||||||
|
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
u32 bits = BUFCFG_PINMODE_GPIO << BUFCFG_PINMODE_SHIFT;
|
||||||
|
u32 mask = BUFCFG_PINMODE_MASK;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (!mrfld_buf_available(mp, pin))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
|
raw_spin_lock_irqsave(&mp->lock, flags);
|
||||||
|
mrfld_update_bufcfg(mp, pin, bits, mask);
|
||||||
|
raw_spin_unlock_irqrestore(&mp->lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct pinmux_ops mrfld_pinmux_ops = {
|
||||||
|
.get_functions_count = mrfld_get_functions_count,
|
||||||
|
.get_function_name = mrfld_get_function_name,
|
||||||
|
.get_function_groups = mrfld_get_function_groups,
|
||||||
|
.set_mux = mrfld_pinmux_set_mux,
|
||||||
|
.gpio_request_enable = mrfld_gpio_request_enable,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mrfld_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
|
||||||
|
unsigned long *config)
|
||||||
|
{
|
||||||
|
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
enum pin_config_param param = pinconf_to_config_param(*config);
|
||||||
|
u32 value, term;
|
||||||
|
u16 arg = 0;
|
||||||
|
|
||||||
|
if (!mrfld_buf_available(mp, pin))
|
||||||
|
return -ENOTSUPP;
|
||||||
|
|
||||||
|
value = readl(mrfld_get_bufcfg(mp, pin));
|
||||||
|
term = (value & BUFCFG_PUPD_VAL_MASK) >> BUFCFG_PUPD_VAL_SHIFT;
|
||||||
|
|
||||||
|
switch (param) {
|
||||||
|
case PIN_CONFIG_BIAS_DISABLE:
|
||||||
|
if (value & BUFCFG_Px_EN_MASK)
|
||||||
|
return -EINVAL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIN_CONFIG_BIAS_PULL_UP:
|
||||||
|
if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PU_EN)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
switch (term) {
|
||||||
|
case BUFCFG_PUPD_VAL_910:
|
||||||
|
arg = 910;
|
||||||
|
break;
|
||||||
|
case BUFCFG_PUPD_VAL_2K:
|
||||||
|
arg = 2000;
|
||||||
|
break;
|
||||||
|
case BUFCFG_PUPD_VAL_20K:
|
||||||
|
arg = 20000;
|
||||||
|
break;
|
||||||
|
case BUFCFG_PUPD_VAL_50K:
|
||||||
|
arg = 50000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||||
|
if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PD_EN)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
switch (term) {
|
||||||
|
case BUFCFG_PUPD_VAL_910:
|
||||||
|
arg = 910;
|
||||||
|
break;
|
||||||
|
case BUFCFG_PUPD_VAL_2K:
|
||||||
|
arg = 2000;
|
||||||
|
break;
|
||||||
|
case BUFCFG_PUPD_VAL_20K:
|
||||||
|
arg = 20000;
|
||||||
|
break;
|
||||||
|
case BUFCFG_PUPD_VAL_50K:
|
||||||
|
arg = 50000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
|
||||||
|
if (!(value & BUFCFG_OD_EN))
|
||||||
|
return -EINVAL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIN_CONFIG_SLEW_RATE:
|
||||||
|
if (!(value & BUFCFG_SLEWSEL))
|
||||||
|
arg = 0;
|
||||||
|
else
|
||||||
|
arg = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -ENOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
*config = pinconf_to_config_packed(param, arg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mrfld_config_set_pin(struct mrfld_pinctrl *mp, unsigned int pin,
|
||||||
|
unsigned long config)
|
||||||
|
{
|
||||||
|
unsigned int param = pinconf_to_config_param(config);
|
||||||
|
unsigned int arg = pinconf_to_config_argument(config);
|
||||||
|
u32 bits = 0, mask = 0;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
switch (param) {
|
||||||
|
case PIN_CONFIG_BIAS_DISABLE:
|
||||||
|
mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIN_CONFIG_BIAS_PULL_UP:
|
||||||
|
mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;
|
||||||
|
bits |= BUFCFG_PU_EN;
|
||||||
|
|
||||||
|
switch (arg) {
|
||||||
|
case 50000:
|
||||||
|
bits |= BUFCFG_PUPD_VAL_50K << BUFCFG_PUPD_VAL_SHIFT;
|
||||||
|
break;
|
||||||
|
case 20000:
|
||||||
|
bits |= BUFCFG_PUPD_VAL_20K << BUFCFG_PUPD_VAL_SHIFT;
|
||||||
|
break;
|
||||||
|
case 2000:
|
||||||
|
bits |= BUFCFG_PUPD_VAL_2K << BUFCFG_PUPD_VAL_SHIFT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||||
|
mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;
|
||||||
|
bits |= BUFCFG_PD_EN;
|
||||||
|
|
||||||
|
switch (arg) {
|
||||||
|
case 50000:
|
||||||
|
bits |= BUFCFG_PUPD_VAL_50K << BUFCFG_PUPD_VAL_SHIFT;
|
||||||
|
break;
|
||||||
|
case 20000:
|
||||||
|
bits |= BUFCFG_PUPD_VAL_20K << BUFCFG_PUPD_VAL_SHIFT;
|
||||||
|
break;
|
||||||
|
case 2000:
|
||||||
|
bits |= BUFCFG_PUPD_VAL_2K << BUFCFG_PUPD_VAL_SHIFT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
|
||||||
|
mask |= BUFCFG_OD_EN;
|
||||||
|
if (arg)
|
||||||
|
bits |= BUFCFG_OD_EN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIN_CONFIG_SLEW_RATE:
|
||||||
|
mask |= BUFCFG_SLEWSEL;
|
||||||
|
if (arg)
|
||||||
|
bits |= BUFCFG_SLEWSEL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
raw_spin_lock_irqsave(&mp->lock, flags);
|
||||||
|
mrfld_update_bufcfg(mp, pin, bits, mask);
|
||||||
|
raw_spin_unlock_irqrestore(&mp->lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mrfld_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
|
||||||
|
unsigned long *configs, unsigned int nconfigs)
|
||||||
|
{
|
||||||
|
struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
unsigned int i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
for (i = 0; i < nconfigs; i++) {
|
||||||
|
switch (pinconf_to_config_param(configs[i])) {
|
||||||
|
case PIN_CONFIG_BIAS_DISABLE:
|
||||||
|
case PIN_CONFIG_BIAS_PULL_UP:
|
||||||
|
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||||
|
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
|
||||||
|
case PIN_CONFIG_SLEW_RATE:
|
||||||
|
ret = mrfld_config_set_pin(mp, pin, configs[i]);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -ENOTSUPP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct pinconf_ops mrfld_pinconf_ops = {
|
||||||
|
.is_generic = true,
|
||||||
|
.pin_config_get = mrfld_config_get,
|
||||||
|
.pin_config_set = mrfld_config_set,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct pinctrl_desc mrfld_pinctrl_desc = {
|
||||||
|
.pctlops = &mrfld_pinctrl_ops,
|
||||||
|
.pmxops = &mrfld_pinmux_ops,
|
||||||
|
.confops = &mrfld_pinconf_ops,
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mrfld_pinctrl_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct mrfld_family *families;
|
||||||
|
struct mrfld_pinctrl *mp;
|
||||||
|
struct resource *mem;
|
||||||
|
void __iomem *regs;
|
||||||
|
size_t nfamilies;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
mp = devm_kzalloc(&pdev->dev, sizeof(*mp), GFP_KERNEL);
|
||||||
|
if (!mp)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
mp->dev = &pdev->dev;
|
||||||
|
raw_spin_lock_init(&mp->lock);
|
||||||
|
|
||||||
|
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
regs = devm_ioremap_resource(&pdev->dev, mem);
|
||||||
|
if (IS_ERR(regs))
|
||||||
|
return PTR_ERR(regs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make a copy of the families which we can use to hold pointers
|
||||||
|
* to the registers.
|
||||||
|
*/
|
||||||
|
nfamilies = ARRAY_SIZE(mrfld_families),
|
||||||
|
families = devm_kmemdup(&pdev->dev, mrfld_families,
|
||||||
|
nfamilies * sizeof(mrfld_families),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!families)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
/* Splice memory resource by chunk per family */
|
||||||
|
for (i = 0; i < nfamilies; i++) {
|
||||||
|
struct mrfld_family *family = &families[i];
|
||||||
|
|
||||||
|
family->regs = regs + family->barno * MRFLD_FAMILY_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp->families = families;
|
||||||
|
mp->nfamilies = nfamilies;
|
||||||
|
mp->functions = mrfld_functions;
|
||||||
|
mp->nfunctions = ARRAY_SIZE(mrfld_functions);
|
||||||
|
mp->groups = mrfld_groups;
|
||||||
|
mp->ngroups = ARRAY_SIZE(mrfld_groups);
|
||||||
|
mp->pctldesc = mrfld_pinctrl_desc;
|
||||||
|
mp->pctldesc.name = dev_name(&pdev->dev);
|
||||||
|
mp->pctldesc.pins = mrfld_pins;
|
||||||
|
mp->pctldesc.npins = ARRAY_SIZE(mrfld_pins);
|
||||||
|
|
||||||
|
mp->pctldev = devm_pinctrl_register(&pdev->dev, &mp->pctldesc, mp);
|
||||||
|
if (IS_ERR(mp->pctldev)) {
|
||||||
|
dev_err(&pdev->dev, "failed to register pinctrl driver\n");
|
||||||
|
return PTR_ERR(mp->pctldev);
|
||||||
|
}
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, mp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct platform_driver mrfld_pinctrl_driver = {
|
||||||
|
.probe = mrfld_pinctrl_probe,
|
||||||
|
.driver = {
|
||||||
|
.name = "pinctrl-merrifield",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init mrfld_pinctrl_init(void)
|
||||||
|
{
|
||||||
|
return platform_driver_register(&mrfld_pinctrl_driver);
|
||||||
|
}
|
||||||
|
subsys_initcall(mrfld_pinctrl_init);
|
||||||
|
|
||||||
|
static void __exit mrfld_pinctrl_exit(void)
|
||||||
|
{
|
||||||
|
platform_driver_unregister(&mrfld_pinctrl_driver);
|
||||||
|
}
|
||||||
|
module_exit(mrfld_pinctrl_exit);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
|
||||||
|
MODULE_DESCRIPTION("Intel Merrifield SoC pinctrl driver");
|
||||||
|
MODULE_LICENSE("GPL v2");
|
||||||
|
MODULE_ALIAS("platform:pinctrl-merrifield");
|
|
@ -1183,8 +1183,8 @@ static int mtk_eint_resume(struct device *device)
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct dev_pm_ops mtk_eint_pm_ops = {
|
const struct dev_pm_ops mtk_eint_pm_ops = {
|
||||||
.suspend = mtk_eint_suspend,
|
.suspend_noirq = mtk_eint_suspend,
|
||||||
.resume = mtk_eint_resume,
|
.resume_noirq = mtk_eint_resume,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void mtk_eint_ack(struct irq_data *d)
|
static void mtk_eint_ack(struct irq_data *d)
|
||||||
|
|
|
@ -147,6 +147,52 @@ static const struct pinctrl_pin_desc meson_gxbb_periphs_pins[] = {
|
||||||
MESON_PIN(GPIO_TEST_N, EE_OFF),
|
MESON_PIN(GPIO_TEST_N, EE_OFF),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const unsigned int emmc_nand_d07_pins[] = {
|
||||||
|
PIN(BOOT_0, EE_OFF), PIN(BOOT_1, EE_OFF), PIN(BOOT_2, EE_OFF),
|
||||||
|
PIN(BOOT_3, EE_OFF), PIN(BOOT_4, EE_OFF), PIN(BOOT_5, EE_OFF),
|
||||||
|
PIN(BOOT_6, EE_OFF), PIN(BOOT_7, EE_OFF),
|
||||||
|
};
|
||||||
|
static const unsigned int emmc_clk_pins[] = { PIN(BOOT_8, EE_OFF) };
|
||||||
|
static const unsigned int emmc_cmd_pins[] = { PIN(BOOT_10, EE_OFF) };
|
||||||
|
static const unsigned int emmc_ds_pins[] = { PIN(BOOT_15, EE_OFF) };
|
||||||
|
|
||||||
|
static const unsigned int sdcard_d0_pins[] = { PIN(CARD_1, EE_OFF) };
|
||||||
|
static const unsigned int sdcard_d1_pins[] = { PIN(CARD_0, EE_OFF) };
|
||||||
|
static const unsigned int sdcard_d2_pins[] = { PIN(CARD_5, EE_OFF) };
|
||||||
|
static const unsigned int sdcard_d3_pins[] = { PIN(CARD_4, EE_OFF) };
|
||||||
|
static const unsigned int sdcard_cmd_pins[] = { PIN(CARD_3, EE_OFF) };
|
||||||
|
static const unsigned int sdcard_clk_pins[] = { PIN(CARD_2, EE_OFF) };
|
||||||
|
|
||||||
|
static const unsigned int uart_tx_a_pins[] = { PIN(GPIOX_12, EE_OFF) };
|
||||||
|
static const unsigned int uart_rx_a_pins[] = { PIN(GPIOX_13, EE_OFF) };
|
||||||
|
static const unsigned int uart_cts_a_pins[] = { PIN(GPIOX_14, EE_OFF) };
|
||||||
|
static const unsigned int uart_rts_a_pins[] = { PIN(GPIOX_15, EE_OFF) };
|
||||||
|
|
||||||
|
static const unsigned int uart_tx_b_pins[] = { PIN(GPIODV_24, EE_OFF) };
|
||||||
|
static const unsigned int uart_rx_b_pins[] = { PIN(GPIODV_25, EE_OFF) };
|
||||||
|
static const unsigned int uart_cts_b_pins[] = { PIN(GPIODV_26, EE_OFF) };
|
||||||
|
static const unsigned int uart_rts_b_pins[] = { PIN(GPIODV_27, EE_OFF) };
|
||||||
|
|
||||||
|
static const unsigned int uart_tx_c_pins[] = { PIN(GPIOY_13, EE_OFF) };
|
||||||
|
static const unsigned int uart_rx_c_pins[] = { PIN(GPIOY_14, EE_OFF) };
|
||||||
|
static const unsigned int uart_cts_c_pins[] = { PIN(GPIOX_11, EE_OFF) };
|
||||||
|
static const unsigned int uart_rts_c_pins[] = { PIN(GPIOX_12, EE_OFF) };
|
||||||
|
|
||||||
|
static const unsigned int eth_mdio_pins[] = { PIN(GPIOZ_0, EE_OFF) };
|
||||||
|
static const unsigned int eth_mdc_pins[] = { PIN(GPIOZ_1, EE_OFF) };
|
||||||
|
static const unsigned int eth_clk_rx_clk_pins[] = { PIN(GPIOZ_2, EE_OFF) };
|
||||||
|
static const unsigned int eth_rx_dv_pins[] = { PIN(GPIOZ_3, EE_OFF) };
|
||||||
|
static const unsigned int eth_rxd0_pins[] = { PIN(GPIOZ_4, EE_OFF) };
|
||||||
|
static const unsigned int eth_rxd1_pins[] = { PIN(GPIOZ_5, EE_OFF) };
|
||||||
|
static const unsigned int eth_rxd2_pins[] = { PIN(GPIOZ_6, EE_OFF) };
|
||||||
|
static const unsigned int eth_rxd3_pins[] = { PIN(GPIOZ_7, EE_OFF) };
|
||||||
|
static const unsigned int eth_rgmii_tx_clk_pins[] = { PIN(GPIOZ_8, EE_OFF) };
|
||||||
|
static const unsigned int eth_tx_en_pins[] = { PIN(GPIOZ_9, EE_OFF) };
|
||||||
|
static const unsigned int eth_txd0_pins[] = { PIN(GPIOZ_10, EE_OFF) };
|
||||||
|
static const unsigned int eth_txd1_pins[] = { PIN(GPIOZ_11, EE_OFF) };
|
||||||
|
static const unsigned int eth_txd2_pins[] = { PIN(GPIOZ_12, EE_OFF) };
|
||||||
|
static const unsigned int eth_txd3_pins[] = { PIN(GPIOZ_13, EE_OFF) };
|
||||||
|
|
||||||
static const struct pinctrl_pin_desc meson_gxbb_aobus_pins[] = {
|
static const struct pinctrl_pin_desc meson_gxbb_aobus_pins[] = {
|
||||||
MESON_PIN(GPIOAO_0, 0),
|
MESON_PIN(GPIOAO_0, 0),
|
||||||
MESON_PIN(GPIOAO_1, 0),
|
MESON_PIN(GPIOAO_1, 0),
|
||||||
|
@ -168,6 +214,16 @@ static const unsigned int uart_tx_ao_a_pins[] = { PIN(GPIOAO_0, 0) };
|
||||||
static const unsigned int uart_rx_ao_a_pins[] = { PIN(GPIOAO_1, 0) };
|
static const unsigned int uart_rx_ao_a_pins[] = { PIN(GPIOAO_1, 0) };
|
||||||
static const unsigned int uart_cts_ao_a_pins[] = { PIN(GPIOAO_2, 0) };
|
static const unsigned int uart_cts_ao_a_pins[] = { PIN(GPIOAO_2, 0) };
|
||||||
static const unsigned int uart_rts_ao_a_pins[] = { PIN(GPIOAO_3, 0) };
|
static const unsigned int uart_rts_ao_a_pins[] = { PIN(GPIOAO_3, 0) };
|
||||||
|
static const unsigned int uart_tx_ao_b_pins[] = { PIN(GPIOAO_0, 0) };
|
||||||
|
static const unsigned int uart_rx_ao_b_pins[] = { PIN(GPIOAO_1, 0),
|
||||||
|
PIN(GPIOAO_5, 0) };
|
||||||
|
static const unsigned int uart_cts_ao_b_pins[] = { PIN(GPIOAO_2, 0) };
|
||||||
|
static const unsigned int uart_rts_ao_b_pins[] = { PIN(GPIOAO_3, 0) };
|
||||||
|
|
||||||
|
static const unsigned int i2c_sck_ao_pins[] = {PIN(GPIOAO_4, 0) };
|
||||||
|
static const unsigned int i2c_sda_ao_pins[] = {PIN(GPIOAO_5, 0) };
|
||||||
|
static const unsigned int i2c_slave_sck_ao_pins[] = {PIN(GPIOAO_4, 0) };
|
||||||
|
static const unsigned int i2c_slave_sda_ao_pins[] = {PIN(GPIOAO_5, 0) };
|
||||||
|
|
||||||
static struct meson_pmx_group meson_gxbb_periphs_groups[] = {
|
static struct meson_pmx_group meson_gxbb_periphs_groups[] = {
|
||||||
GPIO_GROUP(GPIOZ_0, EE_OFF),
|
GPIO_GROUP(GPIOZ_0, EE_OFF),
|
||||||
|
@ -297,6 +353,54 @@ static struct meson_pmx_group meson_gxbb_periphs_groups[] = {
|
||||||
GPIO_GROUP(GPIOCLK_3, EE_OFF),
|
GPIO_GROUP(GPIOCLK_3, EE_OFF),
|
||||||
|
|
||||||
GPIO_GROUP(GPIO_TEST_N, EE_OFF),
|
GPIO_GROUP(GPIO_TEST_N, EE_OFF),
|
||||||
|
|
||||||
|
/* Bank X */
|
||||||
|
GROUP(uart_tx_a, 4, 13),
|
||||||
|
GROUP(uart_rx_a, 4, 12),
|
||||||
|
GROUP(uart_cts_a, 4, 11),
|
||||||
|
GROUP(uart_rts_a, 4, 10),
|
||||||
|
|
||||||
|
/* Bank Y */
|
||||||
|
GROUP(uart_cts_c, 1, 19),
|
||||||
|
GROUP(uart_rts_c, 1, 18),
|
||||||
|
GROUP(uart_tx_c, 1, 17),
|
||||||
|
GROUP(uart_rx_c, 1, 16),
|
||||||
|
|
||||||
|
/* Bank Z */
|
||||||
|
GROUP(eth_mdio, 6, 1),
|
||||||
|
GROUP(eth_mdc, 6, 0),
|
||||||
|
GROUP(eth_clk_rx_clk, 6, 13),
|
||||||
|
GROUP(eth_rx_dv, 6, 12),
|
||||||
|
GROUP(eth_rxd0, 6, 11),
|
||||||
|
GROUP(eth_rxd1, 6, 10),
|
||||||
|
GROUP(eth_rxd2, 6, 9),
|
||||||
|
GROUP(eth_rxd3, 6, 8),
|
||||||
|
GROUP(eth_rgmii_tx_clk, 6, 7),
|
||||||
|
GROUP(eth_tx_en, 6, 6),
|
||||||
|
GROUP(eth_txd0, 6, 5),
|
||||||
|
GROUP(eth_txd1, 6, 4),
|
||||||
|
GROUP(eth_txd2, 6, 3),
|
||||||
|
GROUP(eth_txd3, 6, 2),
|
||||||
|
|
||||||
|
/* Bank DV */
|
||||||
|
GROUP(uart_tx_b, 2, 29),
|
||||||
|
GROUP(uart_rx_b, 2, 28),
|
||||||
|
GROUP(uart_cts_b, 2, 27),
|
||||||
|
GROUP(uart_rts_b, 2, 26),
|
||||||
|
|
||||||
|
/* Bank BOOT */
|
||||||
|
GROUP(emmc_nand_d07, 4, 30),
|
||||||
|
GROUP(emmc_clk, 4, 18),
|
||||||
|
GROUP(emmc_cmd, 4, 19),
|
||||||
|
GROUP(emmc_ds, 4, 31),
|
||||||
|
|
||||||
|
/* Bank CARD */
|
||||||
|
GROUP(sdcard_d1, 2, 14),
|
||||||
|
GROUP(sdcard_d0, 2, 15),
|
||||||
|
GROUP(sdcard_d3, 2, 12),
|
||||||
|
GROUP(sdcard_d2, 2, 13),
|
||||||
|
GROUP(sdcard_cmd, 2, 10),
|
||||||
|
GROUP(sdcard_clk, 2, 11),
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct meson_pmx_group meson_gxbb_aobus_groups[] = {
|
static struct meson_pmx_group meson_gxbb_aobus_groups[] = {
|
||||||
|
@ -316,10 +420,18 @@ static struct meson_pmx_group meson_gxbb_aobus_groups[] = {
|
||||||
GPIO_GROUP(GPIOAO_13, 0),
|
GPIO_GROUP(GPIOAO_13, 0),
|
||||||
|
|
||||||
/* bank AO */
|
/* bank AO */
|
||||||
|
GROUP(uart_tx_ao_b, 0, 26),
|
||||||
|
GROUP(uart_rx_ao_b, 0, 25),
|
||||||
GROUP(uart_tx_ao_a, 0, 12),
|
GROUP(uart_tx_ao_a, 0, 12),
|
||||||
GROUP(uart_rx_ao_a, 0, 11),
|
GROUP(uart_rx_ao_a, 0, 11),
|
||||||
GROUP(uart_cts_ao_a, 0, 10),
|
GROUP(uart_cts_ao_a, 0, 10),
|
||||||
GROUP(uart_rts_ao_a, 0, 9),
|
GROUP(uart_rts_ao_a, 0, 9),
|
||||||
|
GROUP(uart_cts_ao_b, 0, 8),
|
||||||
|
GROUP(uart_rts_ao_b, 0, 7),
|
||||||
|
GROUP(i2c_sck_ao, 0, 6),
|
||||||
|
GROUP(i2c_sda_ao, 0, 5),
|
||||||
|
GROUP(i2c_slave_sck_ao, 0, 2),
|
||||||
|
GROUP(i2c_slave_sda_ao, 0, 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char * const gpio_periphs_groups[] = {
|
static const char * const gpio_periphs_groups[] = {
|
||||||
|
@ -359,6 +471,34 @@ static const char * const gpio_periphs_groups[] = {
|
||||||
"GPIO_TEST_N",
|
"GPIO_TEST_N",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char * const emmc_groups[] = {
|
||||||
|
"emmc_nand_d07", "emmc_clk", "emmc_cmd", "emmc_ds",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const sdcard_groups[] = {
|
||||||
|
"sdcard_d0", "sdcard_d1", "sdcard_d2", "sdcard_d3",
|
||||||
|
"sdcard_cmd", "sdcard_clk",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const uart_a_groups[] = {
|
||||||
|
"uart_tx_a", "uart_rx_a", "uart_cts_a", "uart_rts_a",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const uart_b_groups[] = {
|
||||||
|
"uart_tx_b", "uart_rx_b", "uart_cts_b", "uart_rts_b",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const uart_c_groups[] = {
|
||||||
|
"uart_tx_c", "uart_rx_c", "uart_cts_c", "uart_rts_c",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const eth_groups[] = {
|
||||||
|
"eth_mdio", "eth_mdc", "eth_clk_rx_clk", "eth_rx_dv",
|
||||||
|
"eth_rxd0", "eth_rxd1", "eth_rxd2", "eth_rxd3",
|
||||||
|
"eth_rgmii_tx_clk", "eth_tx_en",
|
||||||
|
"eth_txd0", "eth_txd1", "eth_txd2", "eth_txd3",
|
||||||
|
};
|
||||||
|
|
||||||
static const char * const gpio_aobus_groups[] = {
|
static const char * const gpio_aobus_groups[] = {
|
||||||
"GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4",
|
"GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4",
|
||||||
"GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9",
|
"GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9",
|
||||||
|
@ -366,16 +506,37 @@ static const char * const gpio_aobus_groups[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char * const uart_ao_groups[] = {
|
static const char * const uart_ao_groups[] = {
|
||||||
"uart_tx_ao_a", "uart_rx_ao_a", "uart_cts_ao_a", "uart_rts_ao_a"
|
"uart_tx_ao_a", "uart_rx_ao_a", "uart_cts_ao_a", "uart_rts_ao_a",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const uart_ao_b_groups[] = {
|
||||||
|
"uart_tx_ao_b", "uart_rx_ao_b", "uart_cts_ao_b", "uart_rts_ao_b",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const i2c_ao_groups[] = {
|
||||||
|
"i2c_sdk_ao", "i2c_sda_ao",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const i2c_slave_ao_groups[] = {
|
||||||
|
"i2c_slave_sdk_ao", "i2c_slave_sda_ao",
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct meson_pmx_func meson_gxbb_periphs_functions[] = {
|
static struct meson_pmx_func meson_gxbb_periphs_functions[] = {
|
||||||
FUNCTION(gpio_periphs),
|
FUNCTION(gpio_periphs),
|
||||||
|
FUNCTION(emmc),
|
||||||
|
FUNCTION(sdcard),
|
||||||
|
FUNCTION(uart_a),
|
||||||
|
FUNCTION(uart_b),
|
||||||
|
FUNCTION(uart_c),
|
||||||
|
FUNCTION(eth),
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct meson_pmx_func meson_gxbb_aobus_functions[] = {
|
static struct meson_pmx_func meson_gxbb_aobus_functions[] = {
|
||||||
FUNCTION(gpio_aobus),
|
FUNCTION(gpio_aobus),
|
||||||
FUNCTION(uart_ao),
|
FUNCTION(uart_ao),
|
||||||
|
FUNCTION(uart_ao_b),
|
||||||
|
FUNCTION(i2c_ao),
|
||||||
|
FUNCTION(i2c_slave_ao),
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct meson_bank meson_gxbb_periphs_banks[] = {
|
static struct meson_bank meson_gxbb_periphs_banks[] = {
|
||||||
|
|
|
@ -168,87 +168,87 @@ static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = {
|
||||||
MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1, 1)),
|
MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1, 1)),
|
||||||
MPP_VAR_FUNCTION(0x1, "nand", "io1", V(1, 1, 1, 1, 1, 1))),
|
MPP_VAR_FUNCTION(0x1, "nand", "io1", V(1, 1, 1, 1, 1, 1))),
|
||||||
MPP_MODE(20,
|
MPP_MODE(20,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x3, "ge1", "txd0", V(0, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x3, "ge1", "txd0", V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "lcd", "d0", V(0, 0, 0, 0, 1, 0)),
|
MPP_VAR_FUNCTION(0xb, "lcd", "d0", V(0, 0, 0, 0, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(1, 0, 0, 0, 0, 0))),
|
MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(0, 0, 0, 0, 0, 0))),
|
||||||
MPP_MODE(21,
|
MPP_MODE(21,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x3, "ge1", "txd1", V(0, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x3, "ge1", "txd1", V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(1, 0, 0, 0, 0, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 0, 0, 0, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "lcd", "d1", V(0, 0, 0, 0, 1, 0))),
|
MPP_VAR_FUNCTION(0xb, "lcd", "d1", V(0, 0, 0, 0, 1, 0))),
|
||||||
MPP_MODE(22,
|
MPP_MODE(22,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x3, "ge1", "txd2", V(0, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x3, "ge1", "txd2", V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(1, 0, 0, 0, 0, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 0, 0, 0, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x5, "sata1", "prsnt", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x5, "sata1", "prsnt", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "lcd", "d2", V(0, 0, 0, 0, 1, 0))),
|
MPP_VAR_FUNCTION(0xb, "lcd", "d2", V(0, 0, 0, 0, 1, 0))),
|
||||||
MPP_MODE(23,
|
MPP_MODE(23,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x3, "ge1", "txd3", V(0, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x3, "ge1", "txd3", V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(1, 0, 0, 0, 0, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 0, 0, 0, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x5, "sata0", "prsnt", V(0, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x5, "sata0", "prsnt", V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "lcd", "d3", V(0, 0, 0, 0, 1, 0))),
|
MPP_VAR_FUNCTION(0xb, "lcd", "d3", V(0, 0, 0, 0, 1, 0))),
|
||||||
MPP_MODE(24,
|
MPP_MODE(24,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x3, "ge1", "rxd0", V(0, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x3, "ge1", "rxd0", V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(1, 0, 0, 0, 0, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 0, 0, 0, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "lcd", "d4", V(0, 0, 0, 0, 1, 0))),
|
MPP_VAR_FUNCTION(0xb, "lcd", "d4", V(0, 0, 0, 0, 1, 0))),
|
||||||
MPP_MODE(25,
|
MPP_MODE(25,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x3, "ge1", "rxd1", V(0, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x3, "ge1", "rxd1", V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(1, 0, 0, 0, 0, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 0, 0, 0, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "lcd", "d5", V(0, 0, 0, 0, 1, 0))),
|
MPP_VAR_FUNCTION(0xb, "lcd", "d5", V(0, 0, 0, 0, 1, 0))),
|
||||||
MPP_MODE(26,
|
MPP_MODE(26,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x3, "ge1", "rxd2", V(0, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x3, "ge1", "rxd2", V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(1, 0, 0, 0, 0, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 0, 0, 0, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "lcd", "d6", V(0, 0, 0, 0, 1, 0))),
|
MPP_VAR_FUNCTION(0xb, "lcd", "d6", V(0, 0, 0, 0, 1, 0))),
|
||||||
MPP_MODE(27,
|
MPP_MODE(27,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x3, "ge1", "rxd3", V(0, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x3, "ge1", "rxd3", V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(1, 0, 0, 0, 0, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 0, 0, 0, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "lcd", "d7", V(0, 0, 0, 0, 1, 0))),
|
MPP_VAR_FUNCTION(0xb, "lcd", "d7", V(0, 0, 0, 0, 1, 0))),
|
||||||
MPP_MODE(28,
|
MPP_MODE(28,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x3, "ge1", "col", V(0, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x3, "ge1", "col", V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(1, 0, 0, 0, 0, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 0, 0, 0, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "lcd", "d8", V(0, 0, 0, 0, 1, 0))),
|
MPP_VAR_FUNCTION(0xb, "lcd", "d8", V(0, 0, 0, 0, 1, 0))),
|
||||||
MPP_MODE(29,
|
MPP_MODE(29,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x3, "ge1", "txclk", V(0, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x3, "ge1", "txclk", V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(1, 0, 0, 0, 0, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 0, 0, 0, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "lcd", "d9", V(0, 0, 0, 0, 1, 0))),
|
MPP_VAR_FUNCTION(0xb, "lcd", "d9", V(0, 0, 0, 0, 1, 0))),
|
||||||
MPP_MODE(30,
|
MPP_MODE(30,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)),
|
||||||
|
@ -280,65 +280,65 @@ static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = {
|
||||||
MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "lcd", "d14", V(0, 0, 0, 0, 1, 0))),
|
MPP_VAR_FUNCTION(0xb, "lcd", "d14", V(0, 0, 0, 0, 1, 0))),
|
||||||
MPP_MODE(35,
|
MPP_MODE(35,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 1)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 1)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x3, "ge1", "rxerr", V(0, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x3, "ge1", "rxerr", V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "lcd", "d15", V(0, 0, 0, 0, 1, 0)),
|
MPP_VAR_FUNCTION(0xb, "lcd", "d15", V(0, 0, 0, 0, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(0, 1, 1, 1, 1, 0))),
|
MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(1, 1, 1, 1, 1, 0))),
|
||||||
MPP_MODE(36,
|
MPP_MODE(36,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)),
|
||||||
MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1", V(0, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(1, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "twsi1", "sda", V(0, 0, 0, 0, 1, 0))),
|
MPP_VAR_FUNCTION(0xb, "twsi1", "sda", V(0, 0, 0, 0, 1, 0))),
|
||||||
MPP_MODE(37,
|
MPP_MODE(37,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)),
|
||||||
MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(1, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "twsi1", "sck", V(0, 0, 0, 0, 1, 0))),
|
MPP_VAR_FUNCTION(0xb, "twsi1", "sck", V(0, 0, 0, 0, 1, 0))),
|
||||||
MPP_MODE(38,
|
MPP_MODE(38,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)),
|
||||||
MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(1, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "lcd", "d18", V(0, 0, 0, 0, 1, 0))),
|
MPP_VAR_FUNCTION(0xb, "lcd", "d18", V(0, 0, 0, 0, 1, 0))),
|
||||||
MPP_MODE(39,
|
MPP_MODE(39,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)),
|
||||||
MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(1, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "lcd", "d19", V(0, 0, 0, 0, 1, 0))),
|
MPP_VAR_FUNCTION(0xb, "lcd", "d19", V(0, 0, 0, 0, 1, 0))),
|
||||||
MPP_MODE(40,
|
MPP_MODE(40,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)),
|
||||||
MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(1, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "lcd", "d20", V(0, 0, 0, 0, 1, 0))),
|
MPP_VAR_FUNCTION(0xb, "lcd", "d20", V(0, 0, 0, 0, 1, 0))),
|
||||||
MPP_MODE(41,
|
MPP_MODE(41,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)),
|
||||||
MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(1, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "lcd", "d21", V(0, 0, 0, 0, 1, 0))),
|
MPP_VAR_FUNCTION(0xb, "lcd", "d21", V(0, 0, 0, 0, 1, 0))),
|
||||||
MPP_MODE(42,
|
MPP_MODE(42,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)),
|
||||||
MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(1, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "lcd", "d22", V(0, 0, 0, 0, 1, 0))),
|
MPP_VAR_FUNCTION(0xb, "lcd", "d22", V(0, 0, 0, 0, 1, 0))),
|
||||||
MPP_MODE(43,
|
MPP_MODE(43,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)),
|
||||||
MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(1, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "lcd", "d23", V(0, 0, 0, 0, 1, 0))),
|
MPP_VAR_FUNCTION(0xb, "lcd", "d23", V(0, 0, 0, 0, 1, 0))),
|
||||||
MPP_MODE(44,
|
MPP_MODE(44,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)),
|
||||||
MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 0, 1, 1, 0)),
|
MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(1, 0, 0, 1, 1, 0)),
|
||||||
MPP_VAR_FUNCTION(0xb, "lcd", "clk", V(0, 0, 0, 0, 1, 0))),
|
MPP_VAR_FUNCTION(0xb, "lcd", "clk", V(0, 0, 0, 0, 1, 0))),
|
||||||
MPP_MODE(45,
|
MPP_MODE(45,
|
||||||
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
|
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)),
|
||||||
|
@ -371,11 +371,12 @@ static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct mvebu_mpp_ctrl mv88f6180_mpp_controls[] = {
|
static struct mvebu_mpp_ctrl mv88f6180_mpp_controls[] = {
|
||||||
MPP_FUNC_CTRL(0, 29, NULL, kirkwood_mpp_ctrl),
|
MPP_FUNC_CTRL(0, 44, NULL, kirkwood_mpp_ctrl),
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = {
|
static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = {
|
||||||
MPP_GPIO_RANGE(0, 0, 0, 30),
|
MPP_GPIO_RANGE(0, 0, 0, 20),
|
||||||
|
MPP_GPIO_RANGE(1, 35, 35, 10),
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct mvebu_mpp_ctrl mv88f619x_mpp_controls[] = {
|
static struct mvebu_mpp_ctrl mv88f619x_mpp_controls[] = {
|
||||||
|
|
|
@ -1033,102 +1033,6 @@ static inline void nmk_gpio_dbg_show_one(struct seq_file *s,
|
||||||
#define nmk_gpio_dbg_show NULL
|
#define nmk_gpio_dbg_show NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void nmk_gpio_clocks_enable(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_BANKS; i++) {
|
|
||||||
struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
|
|
||||||
|
|
||||||
if (!chip)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
clk_enable(chip->clk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nmk_gpio_clocks_disable(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_BANKS; i++) {
|
|
||||||
struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
|
|
||||||
|
|
||||||
if (!chip)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
clk_disable(chip->clk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Called from the suspend/resume path to only keep the real wakeup interrupts
|
|
||||||
* (those that have had set_irq_wake() called on them) as wakeup interrupts,
|
|
||||||
* and not the rest of the interrupts which we needed to have as wakeups for
|
|
||||||
* cpuidle.
|
|
||||||
*
|
|
||||||
* PM ops are not used since this needs to be done at the end, after all the
|
|
||||||
* other drivers are done with their suspend callbacks.
|
|
||||||
*/
|
|
||||||
void nmk_gpio_wakeups_suspend(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_BANKS; i++) {
|
|
||||||
struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
|
|
||||||
|
|
||||||
if (!chip)
|
|
||||||
break;
|
|
||||||
|
|
||||||
clk_enable(chip->clk);
|
|
||||||
|
|
||||||
writel(chip->rwimsc & chip->real_wake,
|
|
||||||
chip->addr + NMK_GPIO_RWIMSC);
|
|
||||||
writel(chip->fwimsc & chip->real_wake,
|
|
||||||
chip->addr + NMK_GPIO_FWIMSC);
|
|
||||||
|
|
||||||
clk_disable(chip->clk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nmk_gpio_wakeups_resume(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_BANKS; i++) {
|
|
||||||
struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
|
|
||||||
|
|
||||||
if (!chip)
|
|
||||||
break;
|
|
||||||
|
|
||||||
clk_enable(chip->clk);
|
|
||||||
|
|
||||||
writel(chip->rwimsc, chip->addr + NMK_GPIO_RWIMSC);
|
|
||||||
writel(chip->fwimsc, chip->addr + NMK_GPIO_FWIMSC);
|
|
||||||
|
|
||||||
clk_disable(chip->clk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read the pull up/pull down status.
|
|
||||||
* A bit set in 'pull_up' means that pull up
|
|
||||||
* is selected if pull is enabled in PDIS register.
|
|
||||||
* Note: only pull up/down set via this driver can
|
|
||||||
* be detected due to HW limitations.
|
|
||||||
*/
|
|
||||||
void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up)
|
|
||||||
{
|
|
||||||
if (gpio_bank < NUM_BANKS) {
|
|
||||||
struct nmk_gpio_chip *chip = nmk_gpio_chips[gpio_bank];
|
|
||||||
|
|
||||||
if (!chip)
|
|
||||||
return;
|
|
||||||
|
|
||||||
*pull_up = chip->pull_up;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We will allocate memory for the state container using devm* allocators
|
* We will allocate memory for the state container using devm* allocators
|
||||||
* binding to the first device reaching this point, it doesn't matter if
|
* binding to the first device reaching this point, it doesn't matter if
|
||||||
|
|
|
@ -53,7 +53,7 @@ static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev,
|
||||||
struct seq_file *s, const char *gname,
|
struct seq_file *s, const char *gname,
|
||||||
unsigned pin,
|
unsigned pin,
|
||||||
const struct pin_config_item *items,
|
const struct pin_config_item *items,
|
||||||
int nitems)
|
int nitems, int *print_sep)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -75,8 +75,10 @@ static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev,
|
||||||
seq_printf(s, "ERROR READING CONFIG SETTING %d ", i);
|
seq_printf(s, "ERROR READING CONFIG SETTING %d ", i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* Space between multiple configs */
|
/* comma between multiple configs */
|
||||||
seq_puts(s, " ");
|
if (*print_sep)
|
||||||
|
seq_puts(s, ", ");
|
||||||
|
*print_sep = 1;
|
||||||
seq_puts(s, items[i].display);
|
seq_puts(s, items[i].display);
|
||||||
/* Print unit if available */
|
/* Print unit if available */
|
||||||
if (items[i].has_arg) {
|
if (items[i].has_arg) {
|
||||||
|
@ -105,19 +107,21 @@ void pinconf_generic_dump_pins(struct pinctrl_dev *pctldev, struct seq_file *s,
|
||||||
const char *gname, unsigned pin)
|
const char *gname, unsigned pin)
|
||||||
{
|
{
|
||||||
const struct pinconf_ops *ops = pctldev->desc->confops;
|
const struct pinconf_ops *ops = pctldev->desc->confops;
|
||||||
|
int print_sep = 0;
|
||||||
|
|
||||||
if (!ops->is_generic)
|
if (!ops->is_generic)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* generic parameters */
|
/* generic parameters */
|
||||||
pinconf_generic_dump_one(pctldev, s, gname, pin, conf_items,
|
pinconf_generic_dump_one(pctldev, s, gname, pin, conf_items,
|
||||||
ARRAY_SIZE(conf_items));
|
ARRAY_SIZE(conf_items), &print_sep);
|
||||||
/* driver-specific parameters */
|
/* driver-specific parameters */
|
||||||
if (pctldev->desc->num_custom_params &&
|
if (pctldev->desc->num_custom_params &&
|
||||||
pctldev->desc->custom_conf_items)
|
pctldev->desc->custom_conf_items)
|
||||||
pinconf_generic_dump_one(pctldev, s, gname, pin,
|
pinconf_generic_dump_one(pctldev, s, gname, pin,
|
||||||
pctldev->desc->custom_conf_items,
|
pctldev->desc->custom_conf_items,
|
||||||
pctldev->desc->num_custom_params);
|
pctldev->desc->num_custom_params,
|
||||||
|
&print_sep);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pinconf_generic_dump_config(struct pinctrl_dev *pctldev,
|
void pinconf_generic_dump_config(struct pinctrl_dev *pctldev,
|
||||||
|
@ -391,4 +395,12 @@ exit:
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pinconf_generic_dt_node_to_map);
|
EXPORT_SYMBOL_GPL(pinconf_generic_dt_node_to_map);
|
||||||
|
|
||||||
|
void pinconf_generic_dt_free_map(struct pinctrl_dev *pctldev,
|
||||||
|
struct pinctrl_map *map,
|
||||||
|
unsigned num_maps)
|
||||||
|
{
|
||||||
|
pinctrl_utils_free_map(pctldev, map, num_maps);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(pinconf_generic_dt_free_map);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -258,8 +258,7 @@ void pinconf_show_setting(struct seq_file *s,
|
||||||
case PIN_MAP_TYPE_CONFIGS_PIN:
|
case PIN_MAP_TYPE_CONFIGS_PIN:
|
||||||
desc = pin_desc_get(setting->pctldev,
|
desc = pin_desc_get(setting->pctldev,
|
||||||
setting->data.configs.group_or_pin);
|
setting->data.configs.group_or_pin);
|
||||||
seq_printf(s, "pin %s (%d)",
|
seq_printf(s, "pin %s (%d)", desc->name,
|
||||||
desc->name ? desc->name : "unnamed",
|
|
||||||
setting->data.configs.group_or_pin);
|
setting->data.configs.group_or_pin);
|
||||||
break;
|
break;
|
||||||
case PIN_MAP_TYPE_CONFIGS_GROUP:
|
case PIN_MAP_TYPE_CONFIGS_GROUP:
|
||||||
|
@ -311,8 +310,7 @@ static int pinconf_pins_show(struct seq_file *s, void *what)
|
||||||
if (desc == NULL)
|
if (desc == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
seq_printf(s, "pin %d (%s):", pin,
|
seq_printf(s, "pin %d (%s): ", pin, desc->name);
|
||||||
desc->name ? desc->name : "unnamed");
|
|
||||||
|
|
||||||
pinconf_dump_pin(pctldev, s, pin);
|
pinconf_dump_pin(pctldev, s, pin);
|
||||||
|
|
||||||
|
@ -349,7 +347,7 @@ static int pinconf_groups_show(struct seq_file *s, void *what)
|
||||||
while (selector < ngroups) {
|
while (selector < ngroups) {
|
||||||
const char *gname = pctlops->get_group_name(pctldev, selector);
|
const char *gname = pctlops->get_group_name(pctldev, selector);
|
||||||
|
|
||||||
seq_printf(s, "%u (%s):", selector, gname);
|
seq_printf(s, "%u (%s): ", selector, gname);
|
||||||
pinconf_dump_group(pctldev, s, selector, gname);
|
pinconf_dump_group(pctldev, s, selector, gname);
|
||||||
seq_printf(s, "\n");
|
seq_printf(s, "\n");
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/module.h>
|
#include <linux/init.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/pinctrl/pinconf.h>
|
#include <linux/pinctrl/pinconf.h>
|
||||||
|
@ -421,8 +421,8 @@ static int atmel_pctl_get_group_pins(struct pinctrl_dev *pctldev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct atmel_group *atmel_pctl_find_group_by_pin(struct pinctrl_dev *pctldev,
|
static struct atmel_group *
|
||||||
unsigned pin)
|
atmel_pctl_find_group_by_pin(struct pinctrl_dev *pctldev, unsigned pin)
|
||||||
{
|
{
|
||||||
struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev);
|
struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev);
|
||||||
int i;
|
int i;
|
||||||
|
@ -879,7 +879,6 @@ static const struct of_device_id atmel_pctrl_of_match[] = {
|
||||||
/* sentinel */
|
/* sentinel */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, atmel_pctrl_of_match);
|
|
||||||
|
|
||||||
static int atmel_pinctrl_probe(struct platform_device *pdev)
|
static int atmel_pinctrl_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
@ -1074,28 +1073,13 @@ clk_prepare_enable_error:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int atmel_pinctrl_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
struct atmel_pioctrl *atmel_pioctrl = platform_get_drvdata(pdev);
|
|
||||||
|
|
||||||
irq_domain_remove(atmel_pioctrl->irq_domain);
|
|
||||||
clk_disable_unprepare(atmel_pioctrl->clk);
|
|
||||||
gpiochip_remove(atmel_pioctrl->gpio_chip);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct platform_driver atmel_pinctrl_driver = {
|
static struct platform_driver atmel_pinctrl_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "pinctrl-at91-pio4",
|
.name = "pinctrl-at91-pio4",
|
||||||
.of_match_table = atmel_pctrl_of_match,
|
.of_match_table = atmel_pctrl_of_match,
|
||||||
.pm = &atmel_pctrl_pm_ops,
|
.pm = &atmel_pctrl_pm_ops,
|
||||||
|
.suppress_bind_attrs = true,
|
||||||
},
|
},
|
||||||
.probe = atmel_pinctrl_probe,
|
.probe = atmel_pinctrl_probe,
|
||||||
.remove = atmel_pinctrl_remove,
|
|
||||||
};
|
};
|
||||||
module_platform_driver(atmel_pinctrl_driver);
|
builtin_platform_driver(atmel_pinctrl_driver);
|
||||||
|
|
||||||
MODULE_AUTHOR(Ludovic Desroches <ludovic.desroches@atmel.com>);
|
|
||||||
MODULE_DESCRIPTION("Atmel PIO4 pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
|
@ -189,7 +188,7 @@ struct at91_pinctrl {
|
||||||
struct at91_pinctrl_mux_ops *ops;
|
struct at91_pinctrl_mux_ops *ops;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const inline struct at91_pin_group *at91_pinctrl_find_group_by_name(
|
static inline const struct at91_pin_group *at91_pinctrl_find_group_by_name(
|
||||||
const struct at91_pinctrl *info,
|
const struct at91_pinctrl *info,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
|
@ -1818,13 +1817,3 @@ static int __init at91_pinctrl_init(void)
|
||||||
return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
|
return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
|
||||||
}
|
}
|
||||||
arch_initcall(at91_pinctrl_init);
|
arch_initcall(at91_pinctrl_init);
|
||||||
|
|
||||||
static void __exit at91_pinctrl_exit(void)
|
|
||||||
{
|
|
||||||
platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
|
|
||||||
}
|
|
||||||
|
|
||||||
module_exit(at91_pinctrl_exit);
|
|
||||||
MODULE_AUTHOR("Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>");
|
|
||||||
MODULE_DESCRIPTION("Atmel AT91 pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* - Pin pad configuration (pull up/down, strength)
|
* - Pin pad configuration (pull up/down, strength)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/init.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
|
@ -335,27 +335,17 @@ static int dc_pinctrl_probe(struct platform_device *pdev)
|
||||||
return dc_gpiochip_add(pmap, pdev->dev.of_node);
|
return dc_gpiochip_add(pmap, pdev->dev.of_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dc_pinctrl_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
struct dc_pinmap *pmap = platform_get_drvdata(pdev);
|
|
||||||
|
|
||||||
gpiochip_remove(&pmap->chip);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct of_device_id dc_pinctrl_ids[] = {
|
static const struct of_device_id dc_pinctrl_ids[] = {
|
||||||
{ .compatible = "cnxt,cx92755-pinctrl" },
|
{ .compatible = "cnxt,cx92755-pinctrl" },
|
||||||
{ /* sentinel */ }
|
{ /* sentinel */ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, dc_pinctrl_ids);
|
|
||||||
|
|
||||||
static struct platform_driver dc_pinctrl_driver = {
|
static struct platform_driver dc_pinctrl_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = DRIVER_NAME,
|
.name = DRIVER_NAME,
|
||||||
.of_match_table = dc_pinctrl_ids,
|
.of_match_table = dc_pinctrl_ids,
|
||||||
|
.suppress_bind_attrs = true,
|
||||||
},
|
},
|
||||||
.probe = dc_pinctrl_probe,
|
.probe = dc_pinctrl_probe,
|
||||||
.remove = dc_pinctrl_remove,
|
|
||||||
};
|
};
|
||||||
module_platform_driver(dc_pinctrl_driver);
|
builtin_platform_driver(dc_pinctrl_driver);
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/module.h>
|
#include <linux/init.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
@ -1365,31 +1365,17 @@ static int lpc18xx_scu_probe(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lpc18xx_scu_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
struct lpc18xx_scu_data *scu = platform_get_drvdata(pdev);
|
|
||||||
|
|
||||||
clk_disable_unprepare(scu->clk);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct of_device_id lpc18xx_scu_match[] = {
|
static const struct of_device_id lpc18xx_scu_match[] = {
|
||||||
{ .compatible = "nxp,lpc1850-scu" },
|
{ .compatible = "nxp,lpc1850-scu" },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, lpc18xx_scu_match);
|
|
||||||
|
|
||||||
static struct platform_driver lpc18xx_scu_driver = {
|
static struct platform_driver lpc18xx_scu_driver = {
|
||||||
.probe = lpc18xx_scu_probe,
|
.probe = lpc18xx_scu_probe,
|
||||||
.remove = lpc18xx_scu_remove,
|
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "lpc18xx-scu",
|
.name = "lpc18xx-scu",
|
||||||
.of_match_table = lpc18xx_scu_match,
|
.of_match_table = lpc18xx_scu_match,
|
||||||
|
.suppress_bind_attrs = true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
module_platform_driver(lpc18xx_scu_driver);
|
builtin_platform_driver(lpc18xx_scu_driver);
|
||||||
|
|
||||||
MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>");
|
|
||||||
MODULE_DESCRIPTION("Pinctrl driver for NXP LPC18xx/43xx SCU");
|
|
||||||
MODULE_LICENSE("GPL v2");
|
|
||||||
|
|
|
@ -0,0 +1,673 @@
|
||||||
|
/*
|
||||||
|
* MAX77620 pin control driver.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
|
||||||
|
*
|
||||||
|
* Author:
|
||||||
|
* Chaitanya Bandi <bandik@nvidia.com>
|
||||||
|
* Laxman Dewangan <ldewangan@nvidia.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/mfd/max77620.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/pinctrl/pinctrl.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 "core.h"
|
||||||
|
#include "pinconf.h"
|
||||||
|
#include "pinctrl-utils.h"
|
||||||
|
|
||||||
|
#define MAX77620_PIN_NUM 8
|
||||||
|
|
||||||
|
enum max77620_pin_ppdrv {
|
||||||
|
MAX77620_PIN_UNCONFIG_DRV,
|
||||||
|
MAX77620_PIN_OD_DRV,
|
||||||
|
MAX77620_PIN_PP_DRV,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum max77620_pinconf_param {
|
||||||
|
MAX77620_ACTIVE_FPS_SOURCE = PIN_CONFIG_END + 1,
|
||||||
|
MAX77620_ACTIVE_FPS_POWER_ON_SLOTS,
|
||||||
|
MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS,
|
||||||
|
MAX77620_SUSPEND_FPS_SOURCE,
|
||||||
|
MAX77620_SUSPEND_FPS_POWER_ON_SLOTS,
|
||||||
|
MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct max77620_pin_function {
|
||||||
|
const char *name;
|
||||||
|
const char * const *groups;
|
||||||
|
unsigned int ngroups;
|
||||||
|
int mux_option;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct pinconf_generic_params max77620_cfg_params[] = {
|
||||||
|
{
|
||||||
|
.property = "maxim,active-fps-source",
|
||||||
|
.param = MAX77620_ACTIVE_FPS_SOURCE,
|
||||||
|
}, {
|
||||||
|
.property = "maxim,active-fps-power-up-slot",
|
||||||
|
.param = MAX77620_ACTIVE_FPS_POWER_ON_SLOTS,
|
||||||
|
}, {
|
||||||
|
.property = "maxim,active-fps-power-down-slot",
|
||||||
|
.param = MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS,
|
||||||
|
}, {
|
||||||
|
.property = "maxim,suspend-fps-source",
|
||||||
|
.param = MAX77620_SUSPEND_FPS_SOURCE,
|
||||||
|
}, {
|
||||||
|
.property = "maxim,suspend-fps-power-up-slot",
|
||||||
|
.param = MAX77620_SUSPEND_FPS_POWER_ON_SLOTS,
|
||||||
|
}, {
|
||||||
|
.property = "maxim,suspend-fps-power-down-slot",
|
||||||
|
.param = MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
enum max77620_alternate_pinmux_option {
|
||||||
|
MAX77620_PINMUX_GPIO = 0,
|
||||||
|
MAX77620_PINMUX_LOW_POWER_MODE_CONTROL_IN = 1,
|
||||||
|
MAX77620_PINMUX_FLEXIBLE_POWER_SEQUENCER_OUT = 2,
|
||||||
|
MAX77620_PINMUX_32K_OUT1 = 3,
|
||||||
|
MAX77620_PINMUX_SD0_DYNAMIC_VOLTAGE_SCALING_IN = 4,
|
||||||
|
MAX77620_PINMUX_SD1_DYNAMIC_VOLTAGE_SCALING_IN = 5,
|
||||||
|
MAX77620_PINMUX_REFERENCE_OUT = 6,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct max77620_pingroup {
|
||||||
|
const char *name;
|
||||||
|
const unsigned int pins[1];
|
||||||
|
unsigned int npins;
|
||||||
|
enum max77620_alternate_pinmux_option alt_option;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct max77620_pin_info {
|
||||||
|
enum max77620_pin_ppdrv drv_type;
|
||||||
|
int pull_config;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct max77620_fps_config {
|
||||||
|
int active_fps_src;
|
||||||
|
int active_power_up_slots;
|
||||||
|
int active_power_down_slots;
|
||||||
|
int suspend_fps_src;
|
||||||
|
int suspend_power_up_slots;
|
||||||
|
int suspend_power_down_slots;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct max77620_pctrl_info {
|
||||||
|
struct device *dev;
|
||||||
|
struct pinctrl_dev *pctl;
|
||||||
|
struct regmap *rmap;
|
||||||
|
int pins_current_opt[MAX77620_GPIO_NR];
|
||||||
|
const struct max77620_pin_function *functions;
|
||||||
|
unsigned int num_functions;
|
||||||
|
const struct max77620_pingroup *pin_groups;
|
||||||
|
int num_pin_groups;
|
||||||
|
const struct pinctrl_pin_desc *pins;
|
||||||
|
unsigned int num_pins;
|
||||||
|
struct max77620_pin_info pin_info[MAX77620_PIN_NUM];
|
||||||
|
struct max77620_fps_config fps_config[MAX77620_PIN_NUM];
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct pinctrl_pin_desc max77620_pins_desc[] = {
|
||||||
|
PINCTRL_PIN(MAX77620_GPIO0, "gpio0"),
|
||||||
|
PINCTRL_PIN(MAX77620_GPIO1, "gpio1"),
|
||||||
|
PINCTRL_PIN(MAX77620_GPIO2, "gpio2"),
|
||||||
|
PINCTRL_PIN(MAX77620_GPIO3, "gpio3"),
|
||||||
|
PINCTRL_PIN(MAX77620_GPIO4, "gpio4"),
|
||||||
|
PINCTRL_PIN(MAX77620_GPIO5, "gpio5"),
|
||||||
|
PINCTRL_PIN(MAX77620_GPIO6, "gpio6"),
|
||||||
|
PINCTRL_PIN(MAX77620_GPIO7, "gpio7"),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const gpio_groups[] = {
|
||||||
|
"gpio0",
|
||||||
|
"gpio1",
|
||||||
|
"gpio2",
|
||||||
|
"gpio3",
|
||||||
|
"gpio4",
|
||||||
|
"gpio5",
|
||||||
|
"gpio6",
|
||||||
|
"gpio7",
|
||||||
|
};
|
||||||
|
|
||||||
|
#define FUNCTION_GROUP(fname, mux) \
|
||||||
|
{ \
|
||||||
|
.name = fname, \
|
||||||
|
.groups = gpio_groups, \
|
||||||
|
.ngroups = ARRAY_SIZE(gpio_groups), \
|
||||||
|
.mux_option = MAX77620_PINMUX_##mux, \
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct max77620_pin_function max77620_pin_function[] = {
|
||||||
|
FUNCTION_GROUP("gpio", GPIO),
|
||||||
|
FUNCTION_GROUP("lpm-control-in", LOW_POWER_MODE_CONTROL_IN),
|
||||||
|
FUNCTION_GROUP("fps-out", FLEXIBLE_POWER_SEQUENCER_OUT),
|
||||||
|
FUNCTION_GROUP("32k-out1", 32K_OUT1),
|
||||||
|
FUNCTION_GROUP("sd0-dvs-in", SD0_DYNAMIC_VOLTAGE_SCALING_IN),
|
||||||
|
FUNCTION_GROUP("sd1-dvs-in", SD1_DYNAMIC_VOLTAGE_SCALING_IN),
|
||||||
|
FUNCTION_GROUP("reference-out", REFERENCE_OUT),
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX77620_PINGROUP(pg_name, pin_id, option) \
|
||||||
|
{ \
|
||||||
|
.name = #pg_name, \
|
||||||
|
.pins = {MAX77620_##pin_id}, \
|
||||||
|
.npins = 1, \
|
||||||
|
.alt_option = MAX77620_PINMUX_##option, \
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct max77620_pingroup max77620_pingroups[] = {
|
||||||
|
MAX77620_PINGROUP(gpio0, GPIO0, LOW_POWER_MODE_CONTROL_IN),
|
||||||
|
MAX77620_PINGROUP(gpio1, GPIO1, FLEXIBLE_POWER_SEQUENCER_OUT),
|
||||||
|
MAX77620_PINGROUP(gpio2, GPIO2, FLEXIBLE_POWER_SEQUENCER_OUT),
|
||||||
|
MAX77620_PINGROUP(gpio3, GPIO3, FLEXIBLE_POWER_SEQUENCER_OUT),
|
||||||
|
MAX77620_PINGROUP(gpio4, GPIO4, 32K_OUT1),
|
||||||
|
MAX77620_PINGROUP(gpio5, GPIO5, SD0_DYNAMIC_VOLTAGE_SCALING_IN),
|
||||||
|
MAX77620_PINGROUP(gpio6, GPIO6, SD1_DYNAMIC_VOLTAGE_SCALING_IN),
|
||||||
|
MAX77620_PINGROUP(gpio7, GPIO7, REFERENCE_OUT),
|
||||||
|
};
|
||||||
|
|
||||||
|
static int max77620_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
|
||||||
|
{
|
||||||
|
struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
|
||||||
|
return mpci->num_pin_groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *max77620_pinctrl_get_group_name(
|
||||||
|
struct pinctrl_dev *pctldev, unsigned int group)
|
||||||
|
{
|
||||||
|
struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
|
||||||
|
return mpci->pin_groups[group].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77620_pinctrl_get_group_pins(
|
||||||
|
struct pinctrl_dev *pctldev, unsigned int group,
|
||||||
|
const unsigned int **pins, unsigned int *num_pins)
|
||||||
|
{
|
||||||
|
struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
|
||||||
|
*pins = mpci->pin_groups[group].pins;
|
||||||
|
*num_pins = mpci->pin_groups[group].npins;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct pinctrl_ops max77620_pinctrl_ops = {
|
||||||
|
.get_groups_count = max77620_pinctrl_get_groups_count,
|
||||||
|
.get_group_name = max77620_pinctrl_get_group_name,
|
||||||
|
.get_group_pins = max77620_pinctrl_get_group_pins,
|
||||||
|
.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
|
||||||
|
.dt_free_map = pinctrl_utils_free_map,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int max77620_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
|
||||||
|
{
|
||||||
|
struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
|
||||||
|
return mpci->num_functions;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *max77620_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
|
||||||
|
unsigned int function)
|
||||||
|
{
|
||||||
|
struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
|
||||||
|
return mpci->functions[function].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77620_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
|
||||||
|
unsigned int function,
|
||||||
|
const char * const **groups,
|
||||||
|
unsigned int * const num_groups)
|
||||||
|
{
|
||||||
|
struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
|
||||||
|
*groups = mpci->functions[function].groups;
|
||||||
|
*num_groups = mpci->functions[function].ngroups;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77620_pinctrl_enable(struct pinctrl_dev *pctldev,
|
||||||
|
unsigned int function, unsigned int group)
|
||||||
|
{
|
||||||
|
struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
u8 val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (function == MAX77620_PINMUX_GPIO) {
|
||||||
|
val = 0;
|
||||||
|
} else if (function == mpci->pin_groups[group].alt_option) {
|
||||||
|
val = 1 << group;
|
||||||
|
} else {
|
||||||
|
dev_err(mpci->dev, "GPIO %u doesn't have function %u\n",
|
||||||
|
group, function);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
ret = regmap_update_bits(mpci->rmap, MAX77620_REG_AME_GPIO,
|
||||||
|
BIT(group), val);
|
||||||
|
if (ret < 0)
|
||||||
|
dev_err(mpci->dev, "REG AME GPIO update failed: %d\n", ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct pinmux_ops max77620_pinmux_ops = {
|
||||||
|
.get_functions_count = max77620_pinctrl_get_funcs_count,
|
||||||
|
.get_function_name = max77620_pinctrl_get_func_name,
|
||||||
|
.get_function_groups = max77620_pinctrl_get_func_groups,
|
||||||
|
.set_mux = max77620_pinctrl_enable,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int max77620_pinconf_get(struct pinctrl_dev *pctldev,
|
||||||
|
unsigned int pin, unsigned long *config)
|
||||||
|
{
|
||||||
|
struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
struct device *dev = mpci->dev;
|
||||||
|
enum pin_config_param param = pinconf_to_config_param(*config);
|
||||||
|
unsigned int val;
|
||||||
|
int arg = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
switch (param) {
|
||||||
|
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
|
||||||
|
if (mpci->pin_info[pin].drv_type == MAX77620_PIN_OD_DRV)
|
||||||
|
arg = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIN_CONFIG_DRIVE_PUSH_PULL:
|
||||||
|
if (mpci->pin_info[pin].drv_type == MAX77620_PIN_PP_DRV)
|
||||||
|
arg = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIN_CONFIG_BIAS_PULL_UP:
|
||||||
|
ret = regmap_read(mpci->rmap, MAX77620_REG_PUE_GPIO, &val);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "Reg PUE_GPIO read failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (val & BIT(pin))
|
||||||
|
arg = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||||
|
ret = regmap_read(mpci->rmap, MAX77620_REG_PDE_GPIO, &val);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "Reg PDE_GPIO read failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (val & BIT(pin))
|
||||||
|
arg = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dev_err(dev, "Properties not supported\n");
|
||||||
|
return -ENOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
*config = pinconf_to_config_packed(param, (u16)arg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77620_get_default_fps(struct max77620_pctrl_info *mpci,
|
||||||
|
int addr, int *fps)
|
||||||
|
{
|
||||||
|
unsigned int val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = regmap_read(mpci->rmap, addr, &val);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(mpci->dev, "Reg PUE_GPIO read failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
*fps = (val & MAX77620_FPS_SRC_MASK) >> MAX77620_FPS_SRC_SHIFT;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77620_set_fps_param(struct max77620_pctrl_info *mpci,
|
||||||
|
int pin, int param)
|
||||||
|
{
|
||||||
|
struct max77620_fps_config *fps_config = &mpci->fps_config[pin];
|
||||||
|
int addr, ret;
|
||||||
|
int param_val;
|
||||||
|
int mask, shift;
|
||||||
|
|
||||||
|
if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
addr = MAX77620_REG_FPS_GPIO1 + pin - 1;
|
||||||
|
switch (param) {
|
||||||
|
case MAX77620_ACTIVE_FPS_SOURCE:
|
||||||
|
case MAX77620_SUSPEND_FPS_SOURCE:
|
||||||
|
mask = MAX77620_FPS_SRC_MASK;
|
||||||
|
shift = MAX77620_FPS_SRC_SHIFT;
|
||||||
|
param_val = fps_config->active_fps_src;
|
||||||
|
if (param == MAX77620_SUSPEND_FPS_SOURCE)
|
||||||
|
param_val = fps_config->suspend_fps_src;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAX77620_ACTIVE_FPS_POWER_ON_SLOTS:
|
||||||
|
case MAX77620_SUSPEND_FPS_POWER_ON_SLOTS:
|
||||||
|
mask = MAX77620_FPS_PU_PERIOD_MASK;
|
||||||
|
shift = MAX77620_FPS_PU_PERIOD_SHIFT;
|
||||||
|
param_val = fps_config->active_power_up_slots;
|
||||||
|
if (param == MAX77620_SUSPEND_FPS_POWER_ON_SLOTS)
|
||||||
|
param_val = fps_config->suspend_power_up_slots;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS:
|
||||||
|
case MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS:
|
||||||
|
mask = MAX77620_FPS_PD_PERIOD_MASK;
|
||||||
|
shift = MAX77620_FPS_PD_PERIOD_SHIFT;
|
||||||
|
param_val = fps_config->active_power_down_slots;
|
||||||
|
if (param == MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS)
|
||||||
|
param_val = fps_config->suspend_power_down_slots;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dev_err(mpci->dev, "Invalid parameter %d for pin %d\n",
|
||||||
|
param, pin);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param_val < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = regmap_update_bits(mpci->rmap, addr, mask, param_val << shift);
|
||||||
|
if (ret < 0)
|
||||||
|
dev_err(mpci->dev, "Reg 0x%02x update failed %d\n", addr, ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77620_pinconf_set(struct pinctrl_dev *pctldev,
|
||||||
|
unsigned int pin, unsigned long *configs,
|
||||||
|
unsigned int num_configs)
|
||||||
|
{
|
||||||
|
struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
struct device *dev = mpci->dev;
|
||||||
|
struct max77620_fps_config *fps_config;
|
||||||
|
int param;
|
||||||
|
u16 param_val;
|
||||||
|
unsigned int val;
|
||||||
|
unsigned int pu_val;
|
||||||
|
unsigned int pd_val;
|
||||||
|
int addr, ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_configs; i++) {
|
||||||
|
param = pinconf_to_config_param(configs[i]);
|
||||||
|
param_val = pinconf_to_config_argument(configs[i]);
|
||||||
|
|
||||||
|
switch (param) {
|
||||||
|
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
|
||||||
|
val = param_val ? 0 : 1;
|
||||||
|
ret = regmap_update_bits(mpci->rmap,
|
||||||
|
MAX77620_REG_GPIO0 + pin,
|
||||||
|
MAX77620_CNFG_GPIO_DRV_MASK,
|
||||||
|
val);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "Reg 0x%02x update failed %d\n",
|
||||||
|
MAX77620_REG_GPIO0 + pin, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
mpci->pin_info[pin].drv_type = val ?
|
||||||
|
MAX77620_PIN_PP_DRV : MAX77620_PIN_OD_DRV;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIN_CONFIG_DRIVE_PUSH_PULL:
|
||||||
|
val = param_val ? 1 : 0;
|
||||||
|
ret = regmap_update_bits(mpci->rmap,
|
||||||
|
MAX77620_REG_GPIO0 + pin,
|
||||||
|
MAX77620_CNFG_GPIO_DRV_MASK,
|
||||||
|
val);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "Reg 0x%02x update failed %d\n",
|
||||||
|
MAX77620_REG_GPIO0 + pin, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
mpci->pin_info[pin].drv_type = val ?
|
||||||
|
MAX77620_PIN_PP_DRV : MAX77620_PIN_OD_DRV;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAX77620_ACTIVE_FPS_SOURCE:
|
||||||
|
case MAX77620_ACTIVE_FPS_POWER_ON_SLOTS:
|
||||||
|
case MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS:
|
||||||
|
if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
fps_config = &mpci->fps_config[pin];
|
||||||
|
|
||||||
|
if ((param == MAX77620_ACTIVE_FPS_SOURCE) &&
|
||||||
|
(param_val == MAX77620_FPS_SRC_DEF)) {
|
||||||
|
addr = MAX77620_REG_FPS_GPIO1 + pin - 1;
|
||||||
|
ret = max77620_get_default_fps(
|
||||||
|
mpci, addr,
|
||||||
|
&fps_config->active_fps_src);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param == MAX77620_ACTIVE_FPS_SOURCE)
|
||||||
|
fps_config->active_fps_src = param_val;
|
||||||
|
else if (param == MAX77620_ACTIVE_FPS_POWER_ON_SLOTS)
|
||||||
|
fps_config->active_power_up_slots = param_val;
|
||||||
|
else
|
||||||
|
fps_config->active_power_down_slots = param_val;
|
||||||
|
|
||||||
|
ret = max77620_set_fps_param(mpci, pin, param);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAX77620_SUSPEND_FPS_SOURCE:
|
||||||
|
case MAX77620_SUSPEND_FPS_POWER_ON_SLOTS:
|
||||||
|
case MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS:
|
||||||
|
if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
fps_config = &mpci->fps_config[pin];
|
||||||
|
|
||||||
|
if ((param == MAX77620_SUSPEND_FPS_SOURCE) &&
|
||||||
|
(param_val == MAX77620_FPS_SRC_DEF)) {
|
||||||
|
addr = MAX77620_REG_FPS_GPIO1 + pin - 1;
|
||||||
|
ret = max77620_get_default_fps(
|
||||||
|
mpci, addr,
|
||||||
|
&fps_config->suspend_fps_src);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param == MAX77620_SUSPEND_FPS_SOURCE)
|
||||||
|
fps_config->suspend_fps_src = param_val;
|
||||||
|
else if (param == MAX77620_SUSPEND_FPS_POWER_ON_SLOTS)
|
||||||
|
fps_config->suspend_power_up_slots = param_val;
|
||||||
|
else
|
||||||
|
fps_config->suspend_power_down_slots =
|
||||||
|
param_val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIN_CONFIG_BIAS_PULL_UP:
|
||||||
|
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||||
|
pu_val = (param == PIN_CONFIG_BIAS_PULL_UP) ?
|
||||||
|
BIT(pin) : 0;
|
||||||
|
pd_val = (param == PIN_CONFIG_BIAS_PULL_DOWN) ?
|
||||||
|
BIT(pin) : 0;
|
||||||
|
|
||||||
|
ret = regmap_update_bits(mpci->rmap,
|
||||||
|
MAX77620_REG_PUE_GPIO,
|
||||||
|
BIT(pin), pu_val);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "PUE_GPIO update failed: %d\n",
|
||||||
|
ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = regmap_update_bits(mpci->rmap,
|
||||||
|
MAX77620_REG_PDE_GPIO,
|
||||||
|
BIT(pin), pd_val);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "PDE_GPIO update failed: %d\n",
|
||||||
|
ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dev_err(dev, "Properties not supported\n");
|
||||||
|
return -ENOTSUPP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct pinconf_ops max77620_pinconf_ops = {
|
||||||
|
.pin_config_get = max77620_pinconf_get,
|
||||||
|
.pin_config_set = max77620_pinconf_set,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct pinctrl_desc max77620_pinctrl_desc = {
|
||||||
|
.pctlops = &max77620_pinctrl_ops,
|
||||||
|
.pmxops = &max77620_pinmux_ops,
|
||||||
|
.confops = &max77620_pinconf_ops,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int max77620_pinctrl_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct max77620_chip *max77620 = dev_get_drvdata(pdev->dev.parent);
|
||||||
|
struct max77620_pctrl_info *mpci;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
mpci = devm_kzalloc(&pdev->dev, sizeof(*mpci), GFP_KERNEL);
|
||||||
|
if (!mpci)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
mpci->dev = &pdev->dev;
|
||||||
|
mpci->dev->of_node = pdev->dev.parent->of_node;
|
||||||
|
mpci->rmap = max77620->rmap;
|
||||||
|
|
||||||
|
mpci->pins = max77620_pins_desc;
|
||||||
|
mpci->num_pins = ARRAY_SIZE(max77620_pins_desc);
|
||||||
|
mpci->functions = max77620_pin_function;
|
||||||
|
mpci->num_functions = ARRAY_SIZE(max77620_pin_function);
|
||||||
|
mpci->pin_groups = max77620_pingroups;
|
||||||
|
mpci->num_pin_groups = ARRAY_SIZE(max77620_pingroups);
|
||||||
|
platform_set_drvdata(pdev, mpci);
|
||||||
|
|
||||||
|
max77620_pinctrl_desc.name = dev_name(&pdev->dev);
|
||||||
|
max77620_pinctrl_desc.pins = max77620_pins_desc;
|
||||||
|
max77620_pinctrl_desc.npins = ARRAY_SIZE(max77620_pins_desc);
|
||||||
|
max77620_pinctrl_desc.num_custom_params =
|
||||||
|
ARRAY_SIZE(max77620_cfg_params);
|
||||||
|
max77620_pinctrl_desc.custom_params = max77620_cfg_params;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX77620_PIN_NUM; ++i) {
|
||||||
|
mpci->fps_config[i].active_fps_src = -1;
|
||||||
|
mpci->fps_config[i].active_power_up_slots = -1;
|
||||||
|
mpci->fps_config[i].active_power_down_slots = -1;
|
||||||
|
mpci->fps_config[i].suspend_fps_src = -1;
|
||||||
|
mpci->fps_config[i].suspend_power_up_slots = -1;
|
||||||
|
mpci->fps_config[i].suspend_power_down_slots = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mpci->pctl = devm_pinctrl_register(&pdev->dev, &max77620_pinctrl_desc,
|
||||||
|
mpci);
|
||||||
|
if (IS_ERR(mpci->pctl)) {
|
||||||
|
dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
|
||||||
|
return PTR_ERR(mpci->pctl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_SLEEP
|
||||||
|
static int max77620_suspend_fps_param[] = {
|
||||||
|
MAX77620_SUSPEND_FPS_SOURCE,
|
||||||
|
MAX77620_SUSPEND_FPS_POWER_ON_SLOTS,
|
||||||
|
MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int max77620_active_fps_param[] = {
|
||||||
|
MAX77620_ACTIVE_FPS_SOURCE,
|
||||||
|
MAX77620_ACTIVE_FPS_POWER_ON_SLOTS,
|
||||||
|
MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int max77620_pinctrl_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
struct max77620_pctrl_info *mpci = dev_get_drvdata(dev);
|
||||||
|
int pin, p;
|
||||||
|
|
||||||
|
for (pin = 0; pin < MAX77620_PIN_NUM; ++pin) {
|
||||||
|
if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3))
|
||||||
|
continue;
|
||||||
|
for (p = 0; p < 3; ++p)
|
||||||
|
max77620_set_fps_param(
|
||||||
|
mpci, pin, max77620_suspend_fps_param[p]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int max77620_pinctrl_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
struct max77620_pctrl_info *mpci = dev_get_drvdata(dev);
|
||||||
|
int pin, p;
|
||||||
|
|
||||||
|
for (pin = 0; pin < MAX77620_PIN_NUM; ++pin) {
|
||||||
|
if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3))
|
||||||
|
continue;
|
||||||
|
for (p = 0; p < 3; ++p)
|
||||||
|
max77620_set_fps_param(
|
||||||
|
mpci, pin, max77620_active_fps_param[p]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const struct dev_pm_ops max77620_pinctrl_pm_ops = {
|
||||||
|
SET_SYSTEM_SLEEP_PM_OPS(
|
||||||
|
max77620_pinctrl_suspend, max77620_pinctrl_resume)
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct platform_device_id max77620_pinctrl_devtype[] = {
|
||||||
|
{ .name = "max77620-pinctrl", },
|
||||||
|
{ .name = "max20024-pinctrl", },
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(platform, max77620_pinctrl_devtype);
|
||||||
|
|
||||||
|
static struct platform_driver max77620_pinctrl_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = "max77620-pinctrl",
|
||||||
|
.pm = &max77620_pinctrl_pm_ops,
|
||||||
|
},
|
||||||
|
.probe = max77620_pinctrl_probe,
|
||||||
|
.id_table = max77620_pinctrl_devtype,
|
||||||
|
};
|
||||||
|
|
||||||
|
module_platform_driver(max77620_pinctrl_driver);
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("MAX77620/MAX20024 pin control driver");
|
||||||
|
MODULE_AUTHOR("Chaitanya Bandi<bandik@nvidia.com>");
|
||||||
|
MODULE_AUTHOR("Laxman Dewangan<ldewangan@nvidia.com>");
|
||||||
|
MODULE_ALIAS("platform:max77620-pinctrl");
|
||||||
|
MODULE_LICENSE("GPL v2");
|
|
@ -0,0 +1,846 @@
|
||||||
|
/*
|
||||||
|
* Oxford Semiconductor OXNAS SoC Family pinctrl driver
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
|
||||||
|
*
|
||||||
|
* Based on pinctrl-pic32.c
|
||||||
|
* Joshua Henderson, <joshua.henderson@microchip.com>
|
||||||
|
* Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can distribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License (Version 2) as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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/driver.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/irq.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_device.h>
|
||||||
|
#include <linux/pinctrl/pinconf.h>
|
||||||
|
#include <linux/pinctrl/pinconf-generic.h>
|
||||||
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
#include <linux/pinctrl/pinmux.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/regmap.h>
|
||||||
|
#include <linux/mfd/syscon.h>
|
||||||
|
|
||||||
|
#include "pinctrl-utils.h"
|
||||||
|
|
||||||
|
#define PINS_PER_BANK 32
|
||||||
|
|
||||||
|
#define GPIO_BANK_START(bank) ((bank) * PINS_PER_BANK)
|
||||||
|
|
||||||
|
/* Regmap Offsets */
|
||||||
|
#define PINMUX_PRIMARY_SEL0 0x0c
|
||||||
|
#define PINMUX_SECONDARY_SEL0 0x14
|
||||||
|
#define PINMUX_TERTIARY_SEL0 0x8c
|
||||||
|
#define PINMUX_PRIMARY_SEL1 0x10
|
||||||
|
#define PINMUX_SECONDARY_SEL1 0x18
|
||||||
|
#define PINMUX_TERTIARY_SEL1 0x90
|
||||||
|
#define PINMUX_PULLUP_CTRL0 0xac
|
||||||
|
#define PINMUX_PULLUP_CTRL1 0xb0
|
||||||
|
|
||||||
|
/* GPIO Registers */
|
||||||
|
#define INPUT_VALUE 0x00
|
||||||
|
#define OUTPUT_EN 0x04
|
||||||
|
#define IRQ_PENDING 0x0c
|
||||||
|
#define OUTPUT_SET 0x14
|
||||||
|
#define OUTPUT_CLEAR 0x18
|
||||||
|
#define OUTPUT_EN_SET 0x1c
|
||||||
|
#define OUTPUT_EN_CLEAR 0x20
|
||||||
|
#define RE_IRQ_ENABLE 0x28
|
||||||
|
#define FE_IRQ_ENABLE 0x2c
|
||||||
|
|
||||||
|
struct oxnas_function {
|
||||||
|
const char *name;
|
||||||
|
const char * const *groups;
|
||||||
|
unsigned int ngroups;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct oxnas_pin_group {
|
||||||
|
const char *name;
|
||||||
|
unsigned int pin;
|
||||||
|
unsigned int bank;
|
||||||
|
struct oxnas_desc_function *functions;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct oxnas_desc_function {
|
||||||
|
const char *name;
|
||||||
|
unsigned int fct;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct oxnas_gpio_bank {
|
||||||
|
void __iomem *reg_base;
|
||||||
|
struct gpio_chip gpio_chip;
|
||||||
|
struct irq_chip irq_chip;
|
||||||
|
unsigned int id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct oxnas_pinctrl {
|
||||||
|
struct regmap *regmap;
|
||||||
|
struct device *dev;
|
||||||
|
struct pinctrl_dev *pctldev;
|
||||||
|
const struct pinctrl_pin_desc *pins;
|
||||||
|
unsigned int npins;
|
||||||
|
const struct oxnas_function *functions;
|
||||||
|
unsigned int nfunctions;
|
||||||
|
const struct oxnas_pin_group *groups;
|
||||||
|
unsigned int ngroups;
|
||||||
|
struct oxnas_gpio_bank *gpio_banks;
|
||||||
|
unsigned int nbanks;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct pinctrl_pin_desc oxnas_pins[] = {
|
||||||
|
PINCTRL_PIN(0, "gpio0"),
|
||||||
|
PINCTRL_PIN(1, "gpio1"),
|
||||||
|
PINCTRL_PIN(2, "gpio2"),
|
||||||
|
PINCTRL_PIN(3, "gpio3"),
|
||||||
|
PINCTRL_PIN(4, "gpio4"),
|
||||||
|
PINCTRL_PIN(5, "gpio5"),
|
||||||
|
PINCTRL_PIN(6, "gpio6"),
|
||||||
|
PINCTRL_PIN(7, "gpio7"),
|
||||||
|
PINCTRL_PIN(8, "gpio8"),
|
||||||
|
PINCTRL_PIN(9, "gpio9"),
|
||||||
|
PINCTRL_PIN(10, "gpio10"),
|
||||||
|
PINCTRL_PIN(11, "gpio11"),
|
||||||
|
PINCTRL_PIN(12, "gpio12"),
|
||||||
|
PINCTRL_PIN(13, "gpio13"),
|
||||||
|
PINCTRL_PIN(14, "gpio14"),
|
||||||
|
PINCTRL_PIN(15, "gpio15"),
|
||||||
|
PINCTRL_PIN(16, "gpio16"),
|
||||||
|
PINCTRL_PIN(17, "gpio17"),
|
||||||
|
PINCTRL_PIN(18, "gpio18"),
|
||||||
|
PINCTRL_PIN(19, "gpio19"),
|
||||||
|
PINCTRL_PIN(20, "gpio20"),
|
||||||
|
PINCTRL_PIN(21, "gpio21"),
|
||||||
|
PINCTRL_PIN(22, "gpio22"),
|
||||||
|
PINCTRL_PIN(23, "gpio23"),
|
||||||
|
PINCTRL_PIN(24, "gpio24"),
|
||||||
|
PINCTRL_PIN(25, "gpio25"),
|
||||||
|
PINCTRL_PIN(26, "gpio26"),
|
||||||
|
PINCTRL_PIN(27, "gpio27"),
|
||||||
|
PINCTRL_PIN(28, "gpio28"),
|
||||||
|
PINCTRL_PIN(29, "gpio29"),
|
||||||
|
PINCTRL_PIN(30, "gpio30"),
|
||||||
|
PINCTRL_PIN(31, "gpio31"),
|
||||||
|
PINCTRL_PIN(32, "gpio32"),
|
||||||
|
PINCTRL_PIN(33, "gpio33"),
|
||||||
|
PINCTRL_PIN(34, "gpio34"),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const oxnas_fct0_group[] = {
|
||||||
|
"gpio0", "gpio1", "gpio2", "gpio3",
|
||||||
|
"gpio4", "gpio5", "gpio6", "gpio7",
|
||||||
|
"gpio8", "gpio9", "gpio10", "gpio11",
|
||||||
|
"gpio12", "gpio13", "gpio14", "gpio15",
|
||||||
|
"gpio16", "gpio17", "gpio18", "gpio19",
|
||||||
|
"gpio20", "gpio21", "gpio22", "gpio23",
|
||||||
|
"gpio24", "gpio25", "gpio26", "gpio27",
|
||||||
|
"gpio28", "gpio29", "gpio30", "gpio31",
|
||||||
|
"gpio32", "gpio33", "gpio34"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const oxnas_fct3_group[] = {
|
||||||
|
"gpio0", "gpio1", "gpio2", "gpio3",
|
||||||
|
"gpio4", "gpio5", "gpio6", "gpio7",
|
||||||
|
"gpio8", "gpio9",
|
||||||
|
"gpio20",
|
||||||
|
"gpio22", "gpio23", "gpio24", "gpio25",
|
||||||
|
"gpio26", "gpio27", "gpio28", "gpio29",
|
||||||
|
"gpio30", "gpio31", "gpio32", "gpio33",
|
||||||
|
"gpio34"
|
||||||
|
};
|
||||||
|
|
||||||
|
#define FUNCTION(_name, _gr) \
|
||||||
|
{ \
|
||||||
|
.name = #_name, \
|
||||||
|
.groups = oxnas_##_gr##_group, \
|
||||||
|
.ngroups = ARRAY_SIZE(oxnas_##_gr##_group), \
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct oxnas_function oxnas_functions[] = {
|
||||||
|
FUNCTION(gpio, fct0),
|
||||||
|
FUNCTION(fct3, fct3),
|
||||||
|
};
|
||||||
|
|
||||||
|
#define OXNAS_PINCTRL_GROUP(_pin, _name, ...) \
|
||||||
|
{ \
|
||||||
|
.name = #_name, \
|
||||||
|
.pin = _pin, \
|
||||||
|
.bank = _pin / PINS_PER_BANK, \
|
||||||
|
.functions = (struct oxnas_desc_function[]){ \
|
||||||
|
__VA_ARGS__, { } }, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OXNAS_PINCTRL_FUNCTION(_name, _fct) \
|
||||||
|
{ \
|
||||||
|
.name = #_name, \
|
||||||
|
.fct = _fct, \
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct oxnas_pin_group oxnas_groups[] = {
|
||||||
|
OXNAS_PINCTRL_GROUP(0, gpio0,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(1, gpio1,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(2, gpio2,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(3, gpio3,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(4, gpio4,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(5, gpio5,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(6, gpio6,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(7, gpio7,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(8, gpio8,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(9, gpio9,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(10, gpio10,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
|
||||||
|
OXNAS_PINCTRL_GROUP(11, gpio11,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
|
||||||
|
OXNAS_PINCTRL_GROUP(12, gpio12,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
|
||||||
|
OXNAS_PINCTRL_GROUP(13, gpio13,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
|
||||||
|
OXNAS_PINCTRL_GROUP(14, gpio14,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
|
||||||
|
OXNAS_PINCTRL_GROUP(15, gpio15,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
|
||||||
|
OXNAS_PINCTRL_GROUP(16, gpio16,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
|
||||||
|
OXNAS_PINCTRL_GROUP(17, gpio17,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
|
||||||
|
OXNAS_PINCTRL_GROUP(18, gpio18,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
|
||||||
|
OXNAS_PINCTRL_GROUP(19, gpio19,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
|
||||||
|
OXNAS_PINCTRL_GROUP(20, gpio20,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(21, gpio21,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0)),
|
||||||
|
OXNAS_PINCTRL_GROUP(22, gpio22,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(23, gpio23,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(24, gpio24,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(25, gpio25,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(26, gpio26,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(27, gpio27,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(28, gpio28,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(29, gpio29,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(30, gpio30,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(31, gpio31,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(32, gpio32,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(33, gpio33,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
OXNAS_PINCTRL_GROUP(34, gpio34,
|
||||||
|
OXNAS_PINCTRL_FUNCTION(gpio, 0),
|
||||||
|
OXNAS_PINCTRL_FUNCTION(fct3, 3)),
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct oxnas_gpio_bank *pctl_to_bank(struct oxnas_pinctrl *pctl,
|
||||||
|
unsigned int pin)
|
||||||
|
{
|
||||||
|
return &pctl->gpio_banks[pin / PINS_PER_BANK];
|
||||||
|
}
|
||||||
|
|
||||||
|
static int oxnas_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
|
||||||
|
{
|
||||||
|
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
|
||||||
|
return pctl->ngroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *oxnas_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
|
||||||
|
unsigned int group)
|
||||||
|
{
|
||||||
|
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
|
||||||
|
return pctl->groups[group].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int oxnas_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
|
||||||
|
unsigned int group,
|
||||||
|
const unsigned int **pins,
|
||||||
|
unsigned int *num_pins)
|
||||||
|
{
|
||||||
|
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
|
||||||
|
*pins = &pctl->groups[group].pin;
|
||||||
|
*num_pins = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct pinctrl_ops oxnas_pinctrl_ops = {
|
||||||
|
.get_groups_count = oxnas_pinctrl_get_groups_count,
|
||||||
|
.get_group_name = oxnas_pinctrl_get_group_name,
|
||||||
|
.get_group_pins = oxnas_pinctrl_get_group_pins,
|
||||||
|
.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
|
||||||
|
.dt_free_map = pinctrl_utils_free_map,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int oxnas_pinmux_get_functions_count(struct pinctrl_dev *pctldev)
|
||||||
|
{
|
||||||
|
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
|
||||||
|
return pctl->nfunctions;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
oxnas_pinmux_get_function_name(struct pinctrl_dev *pctldev, unsigned int func)
|
||||||
|
{
|
||||||
|
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
|
||||||
|
return pctl->functions[func].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int oxnas_pinmux_get_function_groups(struct pinctrl_dev *pctldev,
|
||||||
|
unsigned int func,
|
||||||
|
const char * const **groups,
|
||||||
|
unsigned int * const num_groups)
|
||||||
|
{
|
||||||
|
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
|
||||||
|
*groups = pctl->functions[func].groups;
|
||||||
|
*num_groups = pctl->functions[func].ngroups;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int oxnas_pinmux_enable(struct pinctrl_dev *pctldev,
|
||||||
|
unsigned int func, unsigned int group)
|
||||||
|
{
|
||||||
|
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
const struct oxnas_pin_group *pg = &pctl->groups[group];
|
||||||
|
const struct oxnas_function *pf = &pctl->functions[func];
|
||||||
|
const char *fname = pf->name;
|
||||||
|
struct oxnas_desc_function *functions = pg->functions;
|
||||||
|
u32 mask = BIT(pg->pin);
|
||||||
|
|
||||||
|
while (functions->name) {
|
||||||
|
if (!strcmp(functions->name, fname)) {
|
||||||
|
dev_dbg(pctl->dev,
|
||||||
|
"setting function %s bank %d pin %d fct %d mask %x\n",
|
||||||
|
fname, pg->bank, pg->pin,
|
||||||
|
functions->fct, mask);
|
||||||
|
|
||||||
|
regmap_write_bits(pctl->regmap,
|
||||||
|
(pg->bank ?
|
||||||
|
PINMUX_PRIMARY_SEL1 :
|
||||||
|
PINMUX_PRIMARY_SEL0),
|
||||||
|
mask,
|
||||||
|
(functions->fct == 1 ?
|
||||||
|
mask : 0));
|
||||||
|
regmap_write_bits(pctl->regmap,
|
||||||
|
(pg->bank ?
|
||||||
|
PINMUX_SECONDARY_SEL1 :
|
||||||
|
PINMUX_SECONDARY_SEL0),
|
||||||
|
mask,
|
||||||
|
(functions->fct == 2 ?
|
||||||
|
mask : 0));
|
||||||
|
regmap_write_bits(pctl->regmap,
|
||||||
|
(pg->bank ?
|
||||||
|
PINMUX_TERTIARY_SEL1 :
|
||||||
|
PINMUX_TERTIARY_SEL0),
|
||||||
|
mask,
|
||||||
|
(functions->fct == 3 ?
|
||||||
|
mask : 0));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
functions++;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_err(pctl->dev, "cannot mux pin %u to function %u\n", group, func);
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int oxnas_gpio_request_enable(struct pinctrl_dev *pctldev,
|
||||||
|
struct pinctrl_gpio_range *range,
|
||||||
|
unsigned int offset)
|
||||||
|
{
|
||||||
|
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
struct oxnas_gpio_bank *bank = gpiochip_get_data(range->gc);
|
||||||
|
u32 mask = BIT(offset - bank->gpio_chip.base);
|
||||||
|
|
||||||
|
dev_dbg(pctl->dev, "requesting gpio %d in bank %d (id %d) with mask 0x%x\n",
|
||||||
|
offset, bank->gpio_chip.base, bank->id, mask);
|
||||||
|
|
||||||
|
regmap_write_bits(pctl->regmap,
|
||||||
|
(bank->id ?
|
||||||
|
PINMUX_PRIMARY_SEL1 :
|
||||||
|
PINMUX_PRIMARY_SEL0),
|
||||||
|
mask, 0);
|
||||||
|
regmap_write_bits(pctl->regmap,
|
||||||
|
(bank->id ?
|
||||||
|
PINMUX_SECONDARY_SEL1 :
|
||||||
|
PINMUX_SECONDARY_SEL0),
|
||||||
|
mask, 0);
|
||||||
|
regmap_write_bits(pctl->regmap,
|
||||||
|
(bank->id ?
|
||||||
|
PINMUX_TERTIARY_SEL1 :
|
||||||
|
PINMUX_TERTIARY_SEL0),
|
||||||
|
mask, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int oxnas_gpio_get_direction(struct gpio_chip *chip,
|
||||||
|
unsigned int offset)
|
||||||
|
{
|
||||||
|
struct oxnas_gpio_bank *bank = gpiochip_get_data(chip);
|
||||||
|
u32 mask = BIT(offset);
|
||||||
|
|
||||||
|
return !(readl_relaxed(bank->reg_base + OUTPUT_EN) & mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int oxnas_gpio_direction_input(struct gpio_chip *chip,
|
||||||
|
unsigned int offset)
|
||||||
|
{
|
||||||
|
struct oxnas_gpio_bank *bank = gpiochip_get_data(chip);
|
||||||
|
u32 mask = BIT(offset);
|
||||||
|
|
||||||
|
writel_relaxed(mask, bank->reg_base + OUTPUT_EN_CLEAR);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int oxnas_gpio_get(struct gpio_chip *chip, unsigned int offset)
|
||||||
|
{
|
||||||
|
struct oxnas_gpio_bank *bank = gpiochip_get_data(chip);
|
||||||
|
u32 mask = BIT(offset);
|
||||||
|
|
||||||
|
return (readl_relaxed(bank->reg_base + INPUT_VALUE) & mask) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void oxnas_gpio_set(struct gpio_chip *chip, unsigned int offset,
|
||||||
|
int value)
|
||||||
|
{
|
||||||
|
struct oxnas_gpio_bank *bank = gpiochip_get_data(chip);
|
||||||
|
u32 mask = BIT(offset);
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
writel_relaxed(mask, bank->reg_base + OUTPUT_SET);
|
||||||
|
else
|
||||||
|
writel_relaxed(mask, bank->reg_base + OUTPUT_CLEAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int oxnas_gpio_direction_output(struct gpio_chip *chip,
|
||||||
|
unsigned int offset, int value)
|
||||||
|
{
|
||||||
|
struct oxnas_gpio_bank *bank = gpiochip_get_data(chip);
|
||||||
|
u32 mask = BIT(offset);
|
||||||
|
|
||||||
|
oxnas_gpio_set(chip, offset, value);
|
||||||
|
writel_relaxed(mask, bank->reg_base + OUTPUT_EN_SET);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int oxnas_gpio_set_direction(struct pinctrl_dev *pctldev,
|
||||||
|
struct pinctrl_gpio_range *range,
|
||||||
|
unsigned int offset, bool input)
|
||||||
|
{
|
||||||
|
struct gpio_chip *chip = range->gc;
|
||||||
|
|
||||||
|
if (input)
|
||||||
|
oxnas_gpio_direction_input(chip, offset);
|
||||||
|
else
|
||||||
|
oxnas_gpio_direction_output(chip, offset, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct pinmux_ops oxnas_pinmux_ops = {
|
||||||
|
.get_functions_count = oxnas_pinmux_get_functions_count,
|
||||||
|
.get_function_name = oxnas_pinmux_get_function_name,
|
||||||
|
.get_function_groups = oxnas_pinmux_get_function_groups,
|
||||||
|
.set_mux = oxnas_pinmux_enable,
|
||||||
|
.gpio_request_enable = oxnas_gpio_request_enable,
|
||||||
|
.gpio_set_direction = oxnas_gpio_set_direction,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int oxnas_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
|
||||||
|
unsigned long *config)
|
||||||
|
{
|
||||||
|
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
struct oxnas_gpio_bank *bank = pctl_to_bank(pctl, pin);
|
||||||
|
unsigned int param = pinconf_to_config_param(*config);
|
||||||
|
u32 mask = BIT(pin - bank->gpio_chip.base);
|
||||||
|
int ret;
|
||||||
|
u32 arg;
|
||||||
|
|
||||||
|
switch (param) {
|
||||||
|
case PIN_CONFIG_BIAS_PULL_UP:
|
||||||
|
ret = regmap_read(pctl->regmap,
|
||||||
|
(bank->id ?
|
||||||
|
PINMUX_PULLUP_CTRL1 :
|
||||||
|
PINMUX_PULLUP_CTRL0),
|
||||||
|
&arg);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
arg = !!(arg & mask);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -ENOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
*config = pinconf_to_config_packed(param, arg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int oxnas_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
|
||||||
|
unsigned long *configs, unsigned int num_configs)
|
||||||
|
{
|
||||||
|
struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
struct oxnas_gpio_bank *bank = pctl_to_bank(pctl, pin);
|
||||||
|
unsigned int param;
|
||||||
|
u32 arg;
|
||||||
|
unsigned int i;
|
||||||
|
u32 offset = pin - bank->gpio_chip.base;
|
||||||
|
u32 mask = BIT(offset);
|
||||||
|
|
||||||
|
dev_dbg(pctl->dev, "setting pin %d bank %d mask 0x%x\n",
|
||||||
|
pin, bank->gpio_chip.base, mask);
|
||||||
|
|
||||||
|
for (i = 0; i < num_configs; i++) {
|
||||||
|
param = pinconf_to_config_param(configs[i]);
|
||||||
|
arg = pinconf_to_config_argument(configs[i]);
|
||||||
|
|
||||||
|
switch (param) {
|
||||||
|
case PIN_CONFIG_BIAS_PULL_UP:
|
||||||
|
dev_dbg(pctl->dev, " pullup\n");
|
||||||
|
regmap_write_bits(pctl->regmap,
|
||||||
|
(bank->id ?
|
||||||
|
PINMUX_PULLUP_CTRL1 :
|
||||||
|
PINMUX_PULLUP_CTRL0),
|
||||||
|
mask, mask);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_err(pctl->dev, "Property %u not supported\n",
|
||||||
|
param);
|
||||||
|
return -ENOTSUPP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct pinconf_ops oxnas_pinconf_ops = {
|
||||||
|
.pin_config_get = oxnas_pinconf_get,
|
||||||
|
.pin_config_set = oxnas_pinconf_set,
|
||||||
|
.is_generic = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct pinctrl_desc oxnas_pinctrl_desc = {
|
||||||
|
.name = "oxnas-pinctrl",
|
||||||
|
.pctlops = &oxnas_pinctrl_ops,
|
||||||
|
.pmxops = &oxnas_pinmux_ops,
|
||||||
|
.confops = &oxnas_pinconf_ops,
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void oxnas_gpio_irq_ack(struct irq_data *data)
|
||||||
|
{
|
||||||
|
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
|
||||||
|
struct oxnas_gpio_bank *bank = gpiochip_get_data(chip);
|
||||||
|
u32 mask = BIT(data->hwirq);
|
||||||
|
|
||||||
|
writel(mask, bank->reg_base + IRQ_PENDING);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void oxnas_gpio_irq_mask(struct irq_data *data)
|
||||||
|
{
|
||||||
|
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
|
||||||
|
struct oxnas_gpio_bank *bank = gpiochip_get_data(chip);
|
||||||
|
unsigned int type = irqd_get_trigger_type(data);
|
||||||
|
u32 mask = BIT(data->hwirq);
|
||||||
|
|
||||||
|
if (type & IRQ_TYPE_EDGE_RISING)
|
||||||
|
writel(readl(bank->reg_base + RE_IRQ_ENABLE) & ~mask,
|
||||||
|
bank->reg_base + RE_IRQ_ENABLE);
|
||||||
|
|
||||||
|
if (type & IRQ_TYPE_EDGE_FALLING)
|
||||||
|
writel(readl(bank->reg_base + FE_IRQ_ENABLE) & ~mask,
|
||||||
|
bank->reg_base + FE_IRQ_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void oxnas_gpio_irq_unmask(struct irq_data *data)
|
||||||
|
{
|
||||||
|
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
|
||||||
|
struct oxnas_gpio_bank *bank = gpiochip_get_data(chip);
|
||||||
|
unsigned int type = irqd_get_trigger_type(data);
|
||||||
|
u32 mask = BIT(data->hwirq);
|
||||||
|
|
||||||
|
if (type & IRQ_TYPE_EDGE_RISING)
|
||||||
|
writel(readl(bank->reg_base + RE_IRQ_ENABLE) | mask,
|
||||||
|
bank->reg_base + RE_IRQ_ENABLE);
|
||||||
|
|
||||||
|
if (type & IRQ_TYPE_EDGE_FALLING)
|
||||||
|
writel(readl(bank->reg_base + FE_IRQ_ENABLE) | mask,
|
||||||
|
bank->reg_base + FE_IRQ_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int oxnas_gpio_irq_startup(struct irq_data *data)
|
||||||
|
{
|
||||||
|
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
|
||||||
|
|
||||||
|
oxnas_gpio_direction_input(chip, data->hwirq);
|
||||||
|
oxnas_gpio_irq_unmask(data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int oxnas_gpio_irq_set_type(struct irq_data *data, unsigned int type)
|
||||||
|
{
|
||||||
|
if ((type & (IRQ_TYPE_EDGE_RISING|IRQ_TYPE_EDGE_FALLING)) == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
irq_set_handler_locked(data, handle_edge_irq);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void oxnas_gpio_irq_handler(struct irq_desc *desc)
|
||||||
|
{
|
||||||
|
struct gpio_chip *gc = irq_desc_get_handler_data(desc);
|
||||||
|
struct oxnas_gpio_bank *bank = gpiochip_get_data(gc);
|
||||||
|
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||||
|
unsigned long stat;
|
||||||
|
unsigned int pin;
|
||||||
|
|
||||||
|
chained_irq_enter(chip, desc);
|
||||||
|
|
||||||
|
stat = readl(bank->reg_base + IRQ_PENDING);
|
||||||
|
|
||||||
|
for_each_set_bit(pin, &stat, BITS_PER_LONG)
|
||||||
|
generic_handle_irq(irq_linear_revmap(gc->irqdomain, pin));
|
||||||
|
|
||||||
|
chained_irq_exit(chip, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GPIO_BANK(_bank) \
|
||||||
|
{ \
|
||||||
|
.gpio_chip = { \
|
||||||
|
.label = "GPIO" #_bank, \
|
||||||
|
.request = gpiochip_generic_request, \
|
||||||
|
.free = gpiochip_generic_free, \
|
||||||
|
.get_direction = oxnas_gpio_get_direction, \
|
||||||
|
.direction_input = oxnas_gpio_direction_input, \
|
||||||
|
.direction_output = oxnas_gpio_direction_output, \
|
||||||
|
.get = oxnas_gpio_get, \
|
||||||
|
.set = oxnas_gpio_set, \
|
||||||
|
.ngpio = PINS_PER_BANK, \
|
||||||
|
.base = GPIO_BANK_START(_bank), \
|
||||||
|
.owner = THIS_MODULE, \
|
||||||
|
.can_sleep = 0, \
|
||||||
|
}, \
|
||||||
|
.irq_chip = { \
|
||||||
|
.name = "GPIO" #_bank, \
|
||||||
|
.irq_startup = oxnas_gpio_irq_startup, \
|
||||||
|
.irq_ack = oxnas_gpio_irq_ack, \
|
||||||
|
.irq_mask = oxnas_gpio_irq_mask, \
|
||||||
|
.irq_unmask = oxnas_gpio_irq_unmask, \
|
||||||
|
.irq_set_type = oxnas_gpio_irq_set_type, \
|
||||||
|
}, \
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct oxnas_gpio_bank oxnas_gpio_banks[] = {
|
||||||
|
GPIO_BANK(0),
|
||||||
|
GPIO_BANK(1),
|
||||||
|
};
|
||||||
|
|
||||||
|
static int oxnas_pinctrl_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct oxnas_pinctrl *pctl;
|
||||||
|
|
||||||
|
pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
|
||||||
|
if (!pctl)
|
||||||
|
return -ENOMEM;
|
||||||
|
pctl->dev = &pdev->dev;
|
||||||
|
dev_set_drvdata(&pdev->dev, pctl);
|
||||||
|
|
||||||
|
pctl->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
|
||||||
|
"oxsemi,sys-ctrl");
|
||||||
|
if (IS_ERR(pctl->regmap)) {
|
||||||
|
dev_err(&pdev->dev, "failed to get sys ctrl regmap\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
pctl->pins = oxnas_pins;
|
||||||
|
pctl->npins = ARRAY_SIZE(oxnas_pins);
|
||||||
|
pctl->functions = oxnas_functions;
|
||||||
|
pctl->nfunctions = ARRAY_SIZE(oxnas_functions);
|
||||||
|
pctl->groups = oxnas_groups;
|
||||||
|
pctl->ngroups = ARRAY_SIZE(oxnas_groups);
|
||||||
|
pctl->gpio_banks = oxnas_gpio_banks;
|
||||||
|
pctl->nbanks = ARRAY_SIZE(oxnas_gpio_banks);
|
||||||
|
|
||||||
|
oxnas_pinctrl_desc.pins = pctl->pins;
|
||||||
|
oxnas_pinctrl_desc.npins = pctl->npins;
|
||||||
|
|
||||||
|
pctl->pctldev = pinctrl_register(&oxnas_pinctrl_desc,
|
||||||
|
&pdev->dev, pctl);
|
||||||
|
if (IS_ERR(pctl->pctldev)) {
|
||||||
|
dev_err(&pdev->dev, "Failed to register pinctrl device\n");
|
||||||
|
return PTR_ERR(pctl->pctldev);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int oxnas_gpio_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct device_node *np = pdev->dev.of_node;
|
||||||
|
struct of_phandle_args pinspec;
|
||||||
|
struct oxnas_gpio_bank *bank;
|
||||||
|
unsigned int id, ngpios;
|
||||||
|
int irq, ret;
|
||||||
|
struct resource *res;
|
||||||
|
|
||||||
|
if (of_parse_phandle_with_fixed_args(np, "gpio-ranges",
|
||||||
|
3, 0, &pinspec)) {
|
||||||
|
dev_err(&pdev->dev, "gpio-ranges property not found\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
id = pinspec.args[1] / PINS_PER_BANK;
|
||||||
|
ngpios = pinspec.args[2];
|
||||||
|
|
||||||
|
if (id >= ARRAY_SIZE(oxnas_gpio_banks)) {
|
||||||
|
dev_err(&pdev->dev, "invalid gpio-ranges base arg\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ngpios > PINS_PER_BANK) {
|
||||||
|
dev_err(&pdev->dev, "invalid gpio-ranges count arg\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bank = &oxnas_gpio_banks[id];
|
||||||
|
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
bank->reg_base = devm_ioremap_resource(&pdev->dev, res);
|
||||||
|
if (IS_ERR(bank->reg_base))
|
||||||
|
return PTR_ERR(bank->reg_base);
|
||||||
|
|
||||||
|
irq = platform_get_irq(pdev, 0);
|
||||||
|
if (irq < 0) {
|
||||||
|
dev_err(&pdev->dev, "irq get failed\n");
|
||||||
|
return irq;
|
||||||
|
}
|
||||||
|
|
||||||
|
bank->id = id;
|
||||||
|
bank->gpio_chip.parent = &pdev->dev;
|
||||||
|
bank->gpio_chip.of_node = np;
|
||||||
|
bank->gpio_chip.ngpio = ngpios;
|
||||||
|
ret = gpiochip_add_data(&bank->gpio_chip, bank);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(&pdev->dev, "Failed to add GPIO chip %u: %d\n",
|
||||||
|
id, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = gpiochip_irqchip_add(&bank->gpio_chip, &bank->irq_chip,
|
||||||
|
0, handle_level_irq, IRQ_TYPE_NONE);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(&pdev->dev, "Failed to add IRQ chip %u: %d\n",
|
||||||
|
id, ret);
|
||||||
|
gpiochip_remove(&bank->gpio_chip);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpiochip_set_chained_irqchip(&bank->gpio_chip, &bank->irq_chip,
|
||||||
|
irq, oxnas_gpio_irq_handler);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id oxnas_pinctrl_of_match[] = {
|
||||||
|
{ .compatible = "oxsemi,ox810se-pinctrl", },
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_driver oxnas_pinctrl_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = "oxnas-pinctrl",
|
||||||
|
.of_match_table = oxnas_pinctrl_of_match,
|
||||||
|
.suppress_bind_attrs = true,
|
||||||
|
},
|
||||||
|
.probe = oxnas_pinctrl_probe,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct of_device_id oxnas_gpio_of_match[] = {
|
||||||
|
{ .compatible = "oxsemi,ox810se-gpio", },
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_driver oxnas_gpio_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = "oxnas-gpio",
|
||||||
|
.of_match_table = oxnas_gpio_of_match,
|
||||||
|
.suppress_bind_attrs = true,
|
||||||
|
},
|
||||||
|
.probe = oxnas_gpio_probe,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init oxnas_gpio_register(void)
|
||||||
|
{
|
||||||
|
return platform_driver_register(&oxnas_gpio_driver);
|
||||||
|
}
|
||||||
|
arch_initcall(oxnas_gpio_register);
|
||||||
|
|
||||||
|
static int __init oxnas_pinctrl_register(void)
|
||||||
|
{
|
||||||
|
return platform_driver_register(&oxnas_pinctrl_driver);
|
||||||
|
}
|
||||||
|
arch_initcall(oxnas_pinctrl_register);
|
|
@ -360,7 +360,7 @@ static struct regmap_config rockchip_regmap_config = {
|
||||||
.reg_stride = 4,
|
.reg_stride = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const inline struct rockchip_pin_group *pinctrl_name_to_group(
|
static inline const struct rockchip_pin_group *pinctrl_name_to_group(
|
||||||
const struct rockchip_pinctrl *info,
|
const struct rockchip_pinctrl *info,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
|
@ -2007,7 +2007,7 @@ static void rockchip_irq_gc_mask_clr_bit(struct irq_data *d)
|
||||||
irq_gc_mask_clr_bit(d);
|
irq_gc_mask_clr_bit(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rockchip_irq_gc_mask_set_bit(struct irq_data *d)
|
static void rockchip_irq_gc_mask_set_bit(struct irq_data *d)
|
||||||
{
|
{
|
||||||
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
|
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
|
||||||
struct rockchip_pin_bank *bank = gc->private;
|
struct rockchip_pin_bank *bank = gc->private;
|
||||||
|
|
|
@ -844,7 +844,7 @@ static int st_pctl_get_group_pins(struct pinctrl_dev *pctldev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const inline struct st_pctl_group *st_pctl_find_group_by_name(
|
static inline const struct st_pctl_group *st_pctl_find_group_by_name(
|
||||||
const struct st_pinctrl *info, const char *name)
|
const struct st_pinctrl *info, const char *name)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -670,7 +670,7 @@ struct u300_pmx {
|
||||||
* u300_pmx_registers - the array of registers read/written for each pinmux
|
* u300_pmx_registers - the array of registers read/written for each pinmux
|
||||||
* shunt setting
|
* shunt setting
|
||||||
*/
|
*/
|
||||||
const u32 u300_pmx_registers[] = {
|
static const u32 u300_pmx_registers[] = {
|
||||||
U300_SYSCON_PMC1LR,
|
U300_SYSCON_PMC1LR,
|
||||||
U300_SYSCON_PMC1HR,
|
U300_SYSCON_PMC1HR,
|
||||||
U300_SYSCON_PMC2R,
|
U300_SYSCON_PMC2R,
|
||||||
|
|
|
@ -1616,50 +1616,74 @@ struct pinctrl_xway_soc {
|
||||||
|
|
||||||
/* xway xr9 series (DEPRECATED: Use XWAY xRX100/xRX200 Family) */
|
/* xway xr9 series (DEPRECATED: Use XWAY xRX100/xRX200 Family) */
|
||||||
static struct pinctrl_xway_soc xr9_pinctrl = {
|
static struct pinctrl_xway_soc xr9_pinctrl = {
|
||||||
XR9_MAX_PIN, xway_mfp,
|
.pin_count = XR9_MAX_PIN,
|
||||||
xway_grps, ARRAY_SIZE(xway_grps),
|
.mfp = xway_mfp,
|
||||||
xrx_funcs, ARRAY_SIZE(xrx_funcs),
|
.grps = xway_grps,
|
||||||
xway_exin_pin_map, 6
|
.num_grps = ARRAY_SIZE(xway_grps),
|
||||||
|
.funcs = xrx_funcs,
|
||||||
|
.num_funcs = ARRAY_SIZE(xrx_funcs),
|
||||||
|
.exin = xway_exin_pin_map,
|
||||||
|
.num_exin = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
/* XWAY AMAZON Family */
|
/* XWAY AMAZON Family */
|
||||||
static struct pinctrl_xway_soc ase_pinctrl = {
|
static struct pinctrl_xway_soc ase_pinctrl = {
|
||||||
ASE_MAX_PIN, ase_mfp,
|
.pin_count = ASE_MAX_PIN,
|
||||||
ase_grps, ARRAY_SIZE(ase_grps),
|
.mfp = ase_mfp,
|
||||||
ase_funcs, ARRAY_SIZE(ase_funcs),
|
.grps = ase_grps,
|
||||||
ase_exin_pin_map, 3
|
.num_grps = ARRAY_SIZE(ase_grps),
|
||||||
|
.funcs = ase_funcs,
|
||||||
|
.num_funcs = ARRAY_SIZE(ase_funcs),
|
||||||
|
.exin = ase_exin_pin_map,
|
||||||
|
.num_exin = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
/* XWAY DANUBE Family */
|
/* XWAY DANUBE Family */
|
||||||
static struct pinctrl_xway_soc danube_pinctrl = {
|
static struct pinctrl_xway_soc danube_pinctrl = {
|
||||||
DANUBE_MAX_PIN, danube_mfp,
|
.pin_count = DANUBE_MAX_PIN,
|
||||||
danube_grps, ARRAY_SIZE(danube_grps),
|
.mfp = danube_mfp,
|
||||||
danube_funcs, ARRAY_SIZE(danube_funcs),
|
.grps = danube_grps,
|
||||||
danube_exin_pin_map, 3
|
.num_grps = ARRAY_SIZE(danube_grps),
|
||||||
|
.funcs = danube_funcs,
|
||||||
|
.num_funcs = ARRAY_SIZE(danube_funcs),
|
||||||
|
.exin = danube_exin_pin_map,
|
||||||
|
.num_exin = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
/* XWAY xRX100 Family */
|
/* XWAY xRX100 Family */
|
||||||
static struct pinctrl_xway_soc xrx100_pinctrl = {
|
static struct pinctrl_xway_soc xrx100_pinctrl = {
|
||||||
XRX100_MAX_PIN, xrx100_mfp,
|
.pin_count = XRX100_MAX_PIN,
|
||||||
xrx100_grps, ARRAY_SIZE(xrx100_grps),
|
.mfp = xrx100_mfp,
|
||||||
xrx100_funcs, ARRAY_SIZE(xrx100_funcs),
|
.grps = xrx100_grps,
|
||||||
xrx100_exin_pin_map, 6
|
.num_grps = ARRAY_SIZE(xrx100_grps),
|
||||||
|
.funcs = xrx100_funcs,
|
||||||
|
.num_funcs = ARRAY_SIZE(xrx100_funcs),
|
||||||
|
.exin = xrx100_exin_pin_map,
|
||||||
|
.num_exin = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
/* XWAY xRX200 Family */
|
/* XWAY xRX200 Family */
|
||||||
static struct pinctrl_xway_soc xrx200_pinctrl = {
|
static struct pinctrl_xway_soc xrx200_pinctrl = {
|
||||||
XRX200_MAX_PIN, xrx200_mfp,
|
.pin_count = XRX200_MAX_PIN,
|
||||||
xrx200_grps, ARRAY_SIZE(xrx200_grps),
|
.mfp = xrx200_mfp,
|
||||||
xrx200_funcs, ARRAY_SIZE(xrx200_funcs),
|
.grps = xrx200_grps,
|
||||||
xrx200_exin_pin_map, 6
|
.num_grps = ARRAY_SIZE(xrx200_grps),
|
||||||
|
.funcs = xrx200_funcs,
|
||||||
|
.num_funcs = ARRAY_SIZE(xrx200_funcs),
|
||||||
|
.exin = xrx200_exin_pin_map,
|
||||||
|
.num_exin = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
/* XWAY xRX300 Family */
|
/* XWAY xRX300 Family */
|
||||||
static struct pinctrl_xway_soc xrx300_pinctrl = {
|
static struct pinctrl_xway_soc xrx300_pinctrl = {
|
||||||
XRX300_MAX_PIN, xrx300_mfp,
|
.pin_count = XRX300_MAX_PIN,
|
||||||
xrx300_grps, ARRAY_SIZE(xrx300_grps),
|
.mfp = xrx300_mfp,
|
||||||
xrx300_funcs, ARRAY_SIZE(xrx300_funcs),
|
.grps = xrx300_grps,
|
||||||
xrx300_exin_pin_map, 5
|
.num_grps = ARRAY_SIZE(xrx300_grps),
|
||||||
|
.funcs = xrx300_funcs,
|
||||||
|
.num_funcs = ARRAY_SIZE(xrx300_funcs),
|
||||||
|
.exin = xrx300_exin_pin_map,
|
||||||
|
.num_exin = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct pinctrl_gpio_range xway_gpio_range = {
|
static struct pinctrl_gpio_range xway_gpio_range = {
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
*/
|
*/
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/mfd/syscon.h>
|
#include <linux/mfd/syscon.h>
|
||||||
#include <linux/module.h>
|
#include <linux/init.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
@ -1210,7 +1210,6 @@ static const struct of_device_id zynq_pinctrl_of_match[] = {
|
||||||
{ .compatible = "xlnx,pinctrl-zynq" },
|
{ .compatible = "xlnx,pinctrl-zynq" },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, zynq_pinctrl_of_match);
|
|
||||||
|
|
||||||
static struct platform_driver zynq_pinctrl_driver = {
|
static struct platform_driver zynq_pinctrl_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
|
@ -1225,13 +1224,3 @@ static int __init zynq_pinctrl_init(void)
|
||||||
return platform_driver_register(&zynq_pinctrl_driver);
|
return platform_driver_register(&zynq_pinctrl_driver);
|
||||||
}
|
}
|
||||||
arch_initcall(zynq_pinctrl_init);
|
arch_initcall(zynq_pinctrl_init);
|
||||||
|
|
||||||
static void __exit zynq_pinctrl_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&zynq_pinctrl_driver);
|
|
||||||
}
|
|
||||||
module_exit(zynq_pinctrl_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Sören Brinkmann <soren.brinkmann@xilinx.com>");
|
|
||||||
MODULE_DESCRIPTION("Xilinx Zynq pinctrl driver");
|
|
||||||
MODULE_LICENSE("GPL");
|
|
||||||
|
|
|
@ -256,7 +256,7 @@ int pinmux_request_gpio(struct pinctrl_dev *pctldev,
|
||||||
/* Conjure some name stating what chip and pin this is taken by */
|
/* Conjure some name stating what chip and pin this is taken by */
|
||||||
owner = kasprintf(GFP_KERNEL, "%s:%d", range->name, gpio);
|
owner = kasprintf(GFP_KERNEL, "%s:%d", range->name, gpio);
|
||||||
if (!owner)
|
if (!owner)
|
||||||
return -EINVAL;
|
return -ENOMEM;
|
||||||
|
|
||||||
ret = pin_request(pctldev, pin, owner, range);
|
ret = pin_request(pctldev, pin, owner, range);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -606,23 +606,17 @@ static int pinmux_pins_show(struct seq_file *s, void *what)
|
||||||
if (pmxops->strict) {
|
if (pmxops->strict) {
|
||||||
if (desc->mux_owner)
|
if (desc->mux_owner)
|
||||||
seq_printf(s, "pin %d (%s): device %s%s",
|
seq_printf(s, "pin %d (%s): device %s%s",
|
||||||
pin,
|
pin, desc->name, desc->mux_owner,
|
||||||
desc->name ? desc->name : "unnamed",
|
|
||||||
desc->mux_owner,
|
|
||||||
is_hog ? " (HOG)" : "");
|
is_hog ? " (HOG)" : "");
|
||||||
else if (desc->gpio_owner)
|
else if (desc->gpio_owner)
|
||||||
seq_printf(s, "pin %d (%s): GPIO %s",
|
seq_printf(s, "pin %d (%s): GPIO %s",
|
||||||
pin,
|
pin, desc->name, desc->gpio_owner);
|
||||||
desc->name ? desc->name : "unnamed",
|
|
||||||
desc->gpio_owner);
|
|
||||||
else
|
else
|
||||||
seq_printf(s, "pin %d (%s): UNCLAIMED",
|
seq_printf(s, "pin %d (%s): UNCLAIMED",
|
||||||
pin,
|
pin, desc->name);
|
||||||
desc->name ? desc->name : "unnamed");
|
|
||||||
} else {
|
} else {
|
||||||
/* For non-strict controllers */
|
/* For non-strict controllers */
|
||||||
seq_printf(s, "pin %d (%s): %s %s%s", pin,
|
seq_printf(s, "pin %d (%s): %s %s%s", pin, desc->name,
|
||||||
desc->name ? desc->name : "unnamed",
|
|
||||||
desc->mux_owner ? desc->mux_owner
|
desc->mux_owner ? desc->mux_owner
|
||||||
: "(MUX UNCLAIMED)",
|
: "(MUX UNCLAIMED)",
|
||||||
desc->gpio_owner ? desc->gpio_owner
|
desc->gpio_owner ? desc->gpio_owner
|
||||||
|
|
|
@ -55,6 +55,14 @@ config PINCTRL_MSM8960
|
||||||
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
|
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
|
||||||
Qualcomm TLMM block found in the Qualcomm 8960 platform.
|
Qualcomm TLMM block found in the Qualcomm 8960 platform.
|
||||||
|
|
||||||
|
config PINCTRL_MDM9615
|
||||||
|
tristate "Qualcomm 9615 pin controller driver"
|
||||||
|
depends on GPIOLIB && OF
|
||||||
|
select PINCTRL_MSM
|
||||||
|
help
|
||||||
|
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
|
||||||
|
Qualcomm TLMM block found in the Qualcomm 9615 platform.
|
||||||
|
|
||||||
config PINCTRL_MSM8X74
|
config PINCTRL_MSM8X74
|
||||||
tristate "Qualcomm 8x74 pin controller driver"
|
tristate "Qualcomm 8x74 pin controller driver"
|
||||||
depends on GPIOLIB && OF
|
depends on GPIOLIB && OF
|
||||||
|
|
|
@ -10,6 +10,7 @@ obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o
|
||||||
obj-$(CONFIG_PINCTRL_MSM8916) += pinctrl-msm8916.o
|
obj-$(CONFIG_PINCTRL_MSM8916) += pinctrl-msm8916.o
|
||||||
obj-$(CONFIG_PINCTRL_MSM8996) += pinctrl-msm8996.o
|
obj-$(CONFIG_PINCTRL_MSM8996) += pinctrl-msm8996.o
|
||||||
obj-$(CONFIG_PINCTRL_QDF2XXX) += pinctrl-qdf2xxx.o
|
obj-$(CONFIG_PINCTRL_QDF2XXX) += pinctrl-qdf2xxx.o
|
||||||
|
obj-$(CONFIG_PINCTRL_MDM9615) += pinctrl-mdm9615.o
|
||||||
obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-gpio.o
|
obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-gpio.o
|
||||||
obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-mpp.o
|
obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-mpp.o
|
||||||
obj-$(CONFIG_PINCTRL_QCOM_SSBI_PMIC) += pinctrl-ssbi-gpio.o
|
obj-$(CONFIG_PINCTRL_QCOM_SSBI_PMIC) += pinctrl-ssbi-gpio.o
|
||||||
|
|
|
@ -0,0 +1,483 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, Sony Mobile Communications AB.
|
||||||
|
* Copyright (c) 2016 BayLibre, SAS.
|
||||||
|
* Author : Neil Armstrong <narmstrong@baylibre.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 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/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
|
#include <linux/pinctrl/pinmux.h>
|
||||||
|
|
||||||
|
#include "pinctrl-msm.h"
|
||||||
|
|
||||||
|
static const struct pinctrl_pin_desc mdm9615_pins[] = {
|
||||||
|
PINCTRL_PIN(0, "GPIO_0"),
|
||||||
|
PINCTRL_PIN(1, "GPIO_1"),
|
||||||
|
PINCTRL_PIN(2, "GPIO_2"),
|
||||||
|
PINCTRL_PIN(3, "GPIO_3"),
|
||||||
|
PINCTRL_PIN(4, "GPIO_4"),
|
||||||
|
PINCTRL_PIN(5, "GPIO_5"),
|
||||||
|
PINCTRL_PIN(6, "GPIO_6"),
|
||||||
|
PINCTRL_PIN(7, "GPIO_7"),
|
||||||
|
PINCTRL_PIN(8, "GPIO_8"),
|
||||||
|
PINCTRL_PIN(9, "GPIO_9"),
|
||||||
|
PINCTRL_PIN(10, "GPIO_10"),
|
||||||
|
PINCTRL_PIN(11, "GPIO_11"),
|
||||||
|
PINCTRL_PIN(12, "GPIO_12"),
|
||||||
|
PINCTRL_PIN(13, "GPIO_13"),
|
||||||
|
PINCTRL_PIN(14, "GPIO_14"),
|
||||||
|
PINCTRL_PIN(15, "GPIO_15"),
|
||||||
|
PINCTRL_PIN(16, "GPIO_16"),
|
||||||
|
PINCTRL_PIN(17, "GPIO_17"),
|
||||||
|
PINCTRL_PIN(18, "GPIO_18"),
|
||||||
|
PINCTRL_PIN(19, "GPIO_19"),
|
||||||
|
PINCTRL_PIN(20, "GPIO_20"),
|
||||||
|
PINCTRL_PIN(21, "GPIO_21"),
|
||||||
|
PINCTRL_PIN(22, "GPIO_22"),
|
||||||
|
PINCTRL_PIN(23, "GPIO_23"),
|
||||||
|
PINCTRL_PIN(24, "GPIO_24"),
|
||||||
|
PINCTRL_PIN(25, "GPIO_25"),
|
||||||
|
PINCTRL_PIN(26, "GPIO_26"),
|
||||||
|
PINCTRL_PIN(27, "GPIO_27"),
|
||||||
|
PINCTRL_PIN(28, "GPIO_28"),
|
||||||
|
PINCTRL_PIN(29, "GPIO_29"),
|
||||||
|
PINCTRL_PIN(30, "GPIO_30"),
|
||||||
|
PINCTRL_PIN(31, "GPIO_31"),
|
||||||
|
PINCTRL_PIN(32, "GPIO_32"),
|
||||||
|
PINCTRL_PIN(33, "GPIO_33"),
|
||||||
|
PINCTRL_PIN(34, "GPIO_34"),
|
||||||
|
PINCTRL_PIN(35, "GPIO_35"),
|
||||||
|
PINCTRL_PIN(36, "GPIO_36"),
|
||||||
|
PINCTRL_PIN(37, "GPIO_37"),
|
||||||
|
PINCTRL_PIN(38, "GPIO_38"),
|
||||||
|
PINCTRL_PIN(39, "GPIO_39"),
|
||||||
|
PINCTRL_PIN(40, "GPIO_40"),
|
||||||
|
PINCTRL_PIN(41, "GPIO_41"),
|
||||||
|
PINCTRL_PIN(42, "GPIO_42"),
|
||||||
|
PINCTRL_PIN(43, "GPIO_43"),
|
||||||
|
PINCTRL_PIN(44, "GPIO_44"),
|
||||||
|
PINCTRL_PIN(45, "GPIO_45"),
|
||||||
|
PINCTRL_PIN(46, "GPIO_46"),
|
||||||
|
PINCTRL_PIN(47, "GPIO_47"),
|
||||||
|
PINCTRL_PIN(48, "GPIO_48"),
|
||||||
|
PINCTRL_PIN(49, "GPIO_49"),
|
||||||
|
PINCTRL_PIN(50, "GPIO_50"),
|
||||||
|
PINCTRL_PIN(51, "GPIO_51"),
|
||||||
|
PINCTRL_PIN(52, "GPIO_52"),
|
||||||
|
PINCTRL_PIN(53, "GPIO_53"),
|
||||||
|
PINCTRL_PIN(54, "GPIO_54"),
|
||||||
|
PINCTRL_PIN(55, "GPIO_55"),
|
||||||
|
PINCTRL_PIN(56, "GPIO_56"),
|
||||||
|
PINCTRL_PIN(57, "GPIO_57"),
|
||||||
|
PINCTRL_PIN(58, "GPIO_58"),
|
||||||
|
PINCTRL_PIN(59, "GPIO_59"),
|
||||||
|
PINCTRL_PIN(60, "GPIO_60"),
|
||||||
|
PINCTRL_PIN(61, "GPIO_61"),
|
||||||
|
PINCTRL_PIN(62, "GPIO_62"),
|
||||||
|
PINCTRL_PIN(63, "GPIO_63"),
|
||||||
|
PINCTRL_PIN(64, "GPIO_64"),
|
||||||
|
PINCTRL_PIN(65, "GPIO_65"),
|
||||||
|
PINCTRL_PIN(66, "GPIO_66"),
|
||||||
|
PINCTRL_PIN(67, "GPIO_67"),
|
||||||
|
PINCTRL_PIN(68, "GPIO_68"),
|
||||||
|
PINCTRL_PIN(69, "GPIO_69"),
|
||||||
|
PINCTRL_PIN(70, "GPIO_70"),
|
||||||
|
PINCTRL_PIN(71, "GPIO_71"),
|
||||||
|
PINCTRL_PIN(72, "GPIO_72"),
|
||||||
|
PINCTRL_PIN(73, "GPIO_73"),
|
||||||
|
PINCTRL_PIN(74, "GPIO_74"),
|
||||||
|
PINCTRL_PIN(75, "GPIO_75"),
|
||||||
|
PINCTRL_PIN(76, "GPIO_76"),
|
||||||
|
PINCTRL_PIN(77, "GPIO_77"),
|
||||||
|
PINCTRL_PIN(78, "GPIO_78"),
|
||||||
|
PINCTRL_PIN(79, "GPIO_79"),
|
||||||
|
PINCTRL_PIN(80, "GPIO_80"),
|
||||||
|
PINCTRL_PIN(81, "GPIO_81"),
|
||||||
|
PINCTRL_PIN(82, "GPIO_82"),
|
||||||
|
PINCTRL_PIN(83, "GPIO_83"),
|
||||||
|
PINCTRL_PIN(84, "GPIO_84"),
|
||||||
|
PINCTRL_PIN(85, "GPIO_85"),
|
||||||
|
PINCTRL_PIN(86, "GPIO_86"),
|
||||||
|
PINCTRL_PIN(87, "GPIO_87"),
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DECLARE_MSM_GPIO_PINS(pin) \
|
||||||
|
static const unsigned int gpio##pin##_pins[] = { pin }
|
||||||
|
DECLARE_MSM_GPIO_PINS(0);
|
||||||
|
DECLARE_MSM_GPIO_PINS(1);
|
||||||
|
DECLARE_MSM_GPIO_PINS(2);
|
||||||
|
DECLARE_MSM_GPIO_PINS(3);
|
||||||
|
DECLARE_MSM_GPIO_PINS(4);
|
||||||
|
DECLARE_MSM_GPIO_PINS(5);
|
||||||
|
DECLARE_MSM_GPIO_PINS(6);
|
||||||
|
DECLARE_MSM_GPIO_PINS(7);
|
||||||
|
DECLARE_MSM_GPIO_PINS(8);
|
||||||
|
DECLARE_MSM_GPIO_PINS(9);
|
||||||
|
DECLARE_MSM_GPIO_PINS(10);
|
||||||
|
DECLARE_MSM_GPIO_PINS(11);
|
||||||
|
DECLARE_MSM_GPIO_PINS(12);
|
||||||
|
DECLARE_MSM_GPIO_PINS(13);
|
||||||
|
DECLARE_MSM_GPIO_PINS(14);
|
||||||
|
DECLARE_MSM_GPIO_PINS(15);
|
||||||
|
DECLARE_MSM_GPIO_PINS(16);
|
||||||
|
DECLARE_MSM_GPIO_PINS(17);
|
||||||
|
DECLARE_MSM_GPIO_PINS(18);
|
||||||
|
DECLARE_MSM_GPIO_PINS(19);
|
||||||
|
DECLARE_MSM_GPIO_PINS(20);
|
||||||
|
DECLARE_MSM_GPIO_PINS(21);
|
||||||
|
DECLARE_MSM_GPIO_PINS(22);
|
||||||
|
DECLARE_MSM_GPIO_PINS(23);
|
||||||
|
DECLARE_MSM_GPIO_PINS(24);
|
||||||
|
DECLARE_MSM_GPIO_PINS(25);
|
||||||
|
DECLARE_MSM_GPIO_PINS(26);
|
||||||
|
DECLARE_MSM_GPIO_PINS(27);
|
||||||
|
DECLARE_MSM_GPIO_PINS(28);
|
||||||
|
DECLARE_MSM_GPIO_PINS(29);
|
||||||
|
DECLARE_MSM_GPIO_PINS(30);
|
||||||
|
DECLARE_MSM_GPIO_PINS(31);
|
||||||
|
DECLARE_MSM_GPIO_PINS(32);
|
||||||
|
DECLARE_MSM_GPIO_PINS(33);
|
||||||
|
DECLARE_MSM_GPIO_PINS(34);
|
||||||
|
DECLARE_MSM_GPIO_PINS(35);
|
||||||
|
DECLARE_MSM_GPIO_PINS(36);
|
||||||
|
DECLARE_MSM_GPIO_PINS(37);
|
||||||
|
DECLARE_MSM_GPIO_PINS(38);
|
||||||
|
DECLARE_MSM_GPIO_PINS(39);
|
||||||
|
DECLARE_MSM_GPIO_PINS(40);
|
||||||
|
DECLARE_MSM_GPIO_PINS(41);
|
||||||
|
DECLARE_MSM_GPIO_PINS(42);
|
||||||
|
DECLARE_MSM_GPIO_PINS(43);
|
||||||
|
DECLARE_MSM_GPIO_PINS(44);
|
||||||
|
DECLARE_MSM_GPIO_PINS(45);
|
||||||
|
DECLARE_MSM_GPIO_PINS(46);
|
||||||
|
DECLARE_MSM_GPIO_PINS(47);
|
||||||
|
DECLARE_MSM_GPIO_PINS(48);
|
||||||
|
DECLARE_MSM_GPIO_PINS(49);
|
||||||
|
DECLARE_MSM_GPIO_PINS(50);
|
||||||
|
DECLARE_MSM_GPIO_PINS(51);
|
||||||
|
DECLARE_MSM_GPIO_PINS(52);
|
||||||
|
DECLARE_MSM_GPIO_PINS(53);
|
||||||
|
DECLARE_MSM_GPIO_PINS(54);
|
||||||
|
DECLARE_MSM_GPIO_PINS(55);
|
||||||
|
DECLARE_MSM_GPIO_PINS(56);
|
||||||
|
DECLARE_MSM_GPIO_PINS(57);
|
||||||
|
DECLARE_MSM_GPIO_PINS(58);
|
||||||
|
DECLARE_MSM_GPIO_PINS(59);
|
||||||
|
DECLARE_MSM_GPIO_PINS(60);
|
||||||
|
DECLARE_MSM_GPIO_PINS(61);
|
||||||
|
DECLARE_MSM_GPIO_PINS(62);
|
||||||
|
DECLARE_MSM_GPIO_PINS(63);
|
||||||
|
DECLARE_MSM_GPIO_PINS(64);
|
||||||
|
DECLARE_MSM_GPIO_PINS(65);
|
||||||
|
DECLARE_MSM_GPIO_PINS(66);
|
||||||
|
DECLARE_MSM_GPIO_PINS(67);
|
||||||
|
DECLARE_MSM_GPIO_PINS(68);
|
||||||
|
DECLARE_MSM_GPIO_PINS(69);
|
||||||
|
DECLARE_MSM_GPIO_PINS(70);
|
||||||
|
DECLARE_MSM_GPIO_PINS(71);
|
||||||
|
DECLARE_MSM_GPIO_PINS(72);
|
||||||
|
DECLARE_MSM_GPIO_PINS(73);
|
||||||
|
DECLARE_MSM_GPIO_PINS(74);
|
||||||
|
DECLARE_MSM_GPIO_PINS(75);
|
||||||
|
DECLARE_MSM_GPIO_PINS(76);
|
||||||
|
DECLARE_MSM_GPIO_PINS(77);
|
||||||
|
DECLARE_MSM_GPIO_PINS(78);
|
||||||
|
DECLARE_MSM_GPIO_PINS(79);
|
||||||
|
DECLARE_MSM_GPIO_PINS(80);
|
||||||
|
DECLARE_MSM_GPIO_PINS(81);
|
||||||
|
DECLARE_MSM_GPIO_PINS(82);
|
||||||
|
DECLARE_MSM_GPIO_PINS(83);
|
||||||
|
DECLARE_MSM_GPIO_PINS(84);
|
||||||
|
DECLARE_MSM_GPIO_PINS(85);
|
||||||
|
DECLARE_MSM_GPIO_PINS(86);
|
||||||
|
DECLARE_MSM_GPIO_PINS(87);
|
||||||
|
|
||||||
|
#define FUNCTION(fname) \
|
||||||
|
[MSM_MUX_##fname] = { \
|
||||||
|
.name = #fname, \
|
||||||
|
.groups = fname##_groups, \
|
||||||
|
.ngroups = ARRAY_SIZE(fname##_groups), \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11) \
|
||||||
|
{ \
|
||||||
|
.name = "gpio" #id, \
|
||||||
|
.pins = gpio##id##_pins, \
|
||||||
|
.npins = ARRAY_SIZE(gpio##id##_pins), \
|
||||||
|
.funcs = (int[]){ \
|
||||||
|
MSM_MUX_gpio, \
|
||||||
|
MSM_MUX_##f1, \
|
||||||
|
MSM_MUX_##f2, \
|
||||||
|
MSM_MUX_##f3, \
|
||||||
|
MSM_MUX_##f4, \
|
||||||
|
MSM_MUX_##f5, \
|
||||||
|
MSM_MUX_##f6, \
|
||||||
|
MSM_MUX_##f7, \
|
||||||
|
MSM_MUX_##f8, \
|
||||||
|
MSM_MUX_##f9, \
|
||||||
|
MSM_MUX_##f10, \
|
||||||
|
MSM_MUX_##f11 \
|
||||||
|
}, \
|
||||||
|
.nfuncs = 12, \
|
||||||
|
.ctl_reg = 0x1000 + 0x10 * id, \
|
||||||
|
.io_reg = 0x1004 + 0x10 * id, \
|
||||||
|
.intr_cfg_reg = 0x1008 + 0x10 * id, \
|
||||||
|
.intr_status_reg = 0x100c + 0x10 * id, \
|
||||||
|
.intr_target_reg = 0x400 + 0x4 * id, \
|
||||||
|
.mux_bit = 2, \
|
||||||
|
.pull_bit = 0, \
|
||||||
|
.drv_bit = 6, \
|
||||||
|
.oe_bit = 9, \
|
||||||
|
.in_bit = 0, \
|
||||||
|
.out_bit = 1, \
|
||||||
|
.intr_enable_bit = 0, \
|
||||||
|
.intr_status_bit = 0, \
|
||||||
|
.intr_ack_high = 1, \
|
||||||
|
.intr_target_bit = 0, \
|
||||||
|
.intr_target_kpss_val = 4, \
|
||||||
|
.intr_raw_status_bit = 3, \
|
||||||
|
.intr_polarity_bit = 1, \
|
||||||
|
.intr_detection_bit = 2, \
|
||||||
|
.intr_detection_width = 1, \
|
||||||
|
}
|
||||||
|
|
||||||
|
enum mdm9615_functions {
|
||||||
|
MSM_MUX_gpio,
|
||||||
|
MSM_MUX_gsbi2_i2c,
|
||||||
|
MSM_MUX_gsbi3,
|
||||||
|
MSM_MUX_gsbi4,
|
||||||
|
MSM_MUX_gsbi5_i2c,
|
||||||
|
MSM_MUX_gsbi5_uart,
|
||||||
|
MSM_MUX_sdc2,
|
||||||
|
MSM_MUX_ebi2_lcdc,
|
||||||
|
MSM_MUX_ps_hold,
|
||||||
|
MSM_MUX_prim_audio,
|
||||||
|
MSM_MUX_sec_audio,
|
||||||
|
MSM_MUX_cdc_mclk,
|
||||||
|
MSM_MUX_NA,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const gpio_groups[] = {
|
||||||
|
"gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
|
||||||
|
"gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
|
||||||
|
"gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
|
||||||
|
"gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
|
||||||
|
"gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
|
||||||
|
"gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
|
||||||
|
"gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
|
||||||
|
"gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
|
||||||
|
"gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
|
||||||
|
"gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
|
||||||
|
"gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
|
||||||
|
"gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84",
|
||||||
|
"gpio85", "gpio86", "gpio87"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const gsbi2_i2c_groups[] = {
|
||||||
|
"gpio4", "gpio5"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const gsbi3_groups[] = {
|
||||||
|
"gpio8", "gpio9", "gpio10", "gpio11"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const gsbi4_groups[] = {
|
||||||
|
"gpio12", "gpio13", "gpio14", "gpio15"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const gsbi5_i2c_groups[] = {
|
||||||
|
"gpio16", "gpio17"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const gsbi5_uart_groups[] = {
|
||||||
|
"gpio18", "gpio19"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const sdc2_groups[] = {
|
||||||
|
"gpio25", "gpio26", "gpio27", "gpio28", "gpio29", "gpio30",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const ebi2_lcdc_groups[] = {
|
||||||
|
"gpio21", "gpio22", "gpio24",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const ps_hold_groups[] = {
|
||||||
|
"gpio83",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const prim_audio_groups[] = {
|
||||||
|
"gpio20", "gpio21", "gpio22", "gpio23",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const sec_audio_groups[] = {
|
||||||
|
"gpio25", "gpio26", "gpio27", "gpio28",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const cdc_mclk_groups[] = {
|
||||||
|
"gpio24",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct msm_function mdm9615_functions[] = {
|
||||||
|
FUNCTION(gpio),
|
||||||
|
FUNCTION(gsbi2_i2c),
|
||||||
|
FUNCTION(gsbi3),
|
||||||
|
FUNCTION(gsbi4),
|
||||||
|
FUNCTION(gsbi5_i2c),
|
||||||
|
FUNCTION(gsbi5_uart),
|
||||||
|
FUNCTION(sdc2),
|
||||||
|
FUNCTION(ebi2_lcdc),
|
||||||
|
FUNCTION(ps_hold),
|
||||||
|
FUNCTION(prim_audio),
|
||||||
|
FUNCTION(sec_audio),
|
||||||
|
FUNCTION(cdc_mclk),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct msm_pingroup mdm9615_groups[] = {
|
||||||
|
PINGROUP(0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(4, gsbi2_i2c, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(5, gsbi2_i2c, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(6, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(7, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(8, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(9, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(10, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(11, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(12, gsbi4, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(13, gsbi4, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(14, gsbi4, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(15, gsbi4, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(16, gsbi5_i2c, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(17, gsbi5_i2c, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(18, gsbi5_uart, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(19, gsbi5_uart, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(20, prim_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(21, prim_audio, ebi2_lcdc, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(22, prim_audio, ebi2_lcdc, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(23, prim_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(24, cdc_mclk, NA, ebi2_lcdc, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(25, sdc2, sec_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(26, sdc2, sec_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(27, sdc2, sec_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(28, sdc2, sec_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(29, sdc2, sec_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(30, sdc2, sec_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(31, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(32, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(33, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(34, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(35, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(36, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(37, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(38, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(39, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(40, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(41, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(42, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(43, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(44, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(45, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(46, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(47, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(48, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(49, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(50, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(51, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(52, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(53, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(54, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(55, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(56, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(57, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(58, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(59, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(60, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(61, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(62, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(63, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(64, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(65, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(66, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(67, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(68, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(69, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(70, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(71, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(72, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(73, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(74, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(75, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(76, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(77, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(78, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(79, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(80, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(81, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(82, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(83, ps_hold, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(84, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(85, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(86, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
PINGROUP(87, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NUM_GPIO_PINGROUPS 88
|
||||||
|
|
||||||
|
static const struct msm_pinctrl_soc_data mdm9615_pinctrl = {
|
||||||
|
.pins = mdm9615_pins,
|
||||||
|
.npins = ARRAY_SIZE(mdm9615_pins),
|
||||||
|
.functions = mdm9615_functions,
|
||||||
|
.nfunctions = ARRAY_SIZE(mdm9615_functions),
|
||||||
|
.groups = mdm9615_groups,
|
||||||
|
.ngroups = ARRAY_SIZE(mdm9615_groups),
|
||||||
|
.ngpios = NUM_GPIO_PINGROUPS,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mdm9615_pinctrl_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
return msm_pinctrl_probe(pdev, &mdm9615_pinctrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id mdm9615_pinctrl_of_match[] = {
|
||||||
|
{ .compatible = "qcom,mdm9615-pinctrl", },
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_driver mdm9615_pinctrl_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = "mdm9615-pinctrl",
|
||||||
|
.of_match_table = mdm9615_pinctrl_of_match,
|
||||||
|
},
|
||||||
|
.probe = mdm9615_pinctrl_probe,
|
||||||
|
.remove = msm_pinctrl_remove,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init mdm9615_pinctrl_init(void)
|
||||||
|
{
|
||||||
|
return platform_driver_register(&mdm9615_pinctrl_driver);
|
||||||
|
}
|
||||||
|
arch_initcall(mdm9615_pinctrl_init);
|
||||||
|
|
||||||
|
static void __exit mdm9615_pinctrl_exit(void)
|
||||||
|
{
|
||||||
|
platform_driver_unregister(&mdm9615_pinctrl_driver);
|
||||||
|
}
|
||||||
|
module_exit(mdm9615_pinctrl_exit);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
|
||||||
|
MODULE_DESCRIPTION("Qualcomm MDM9615 pinctrl driver");
|
||||||
|
MODULE_LICENSE("GPL v2");
|
||||||
|
MODULE_DEVICE_TABLE(of, mdm9615_pinctrl_of_match);
|
|
@ -29,6 +29,7 @@
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/reboot.h>
|
#include <linux/reboot.h>
|
||||||
#include <linux/pm.h>
|
#include <linux/pm.h>
|
||||||
|
#include <linux/log2.h>
|
||||||
|
|
||||||
#include "../core.h"
|
#include "../core.h"
|
||||||
#include "../pinconf.h"
|
#include "../pinconf.h"
|
||||||
|
@ -138,10 +139,11 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
|
||||||
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
|
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
|
||||||
const struct msm_pingroup *g;
|
const struct msm_pingroup *g;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 val;
|
u32 val, mask;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
g = &pctrl->soc->groups[group];
|
g = &pctrl->soc->groups[group];
|
||||||
|
mask = GENMASK(g->mux_bit + order_base_2(g->nfuncs) - 1, g->mux_bit);
|
||||||
|
|
||||||
for (i = 0; i < g->nfuncs; i++) {
|
for (i = 0; i < g->nfuncs; i++) {
|
||||||
if (g->funcs[i] == function)
|
if (g->funcs[i] == function)
|
||||||
|
@ -154,7 +156,7 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
|
||||||
spin_lock_irqsave(&pctrl->lock, flags);
|
spin_lock_irqsave(&pctrl->lock, flags);
|
||||||
|
|
||||||
val = readl(pctrl->regs + g->ctl_reg);
|
val = readl(pctrl->regs + g->ctl_reg);
|
||||||
val &= ~(0x7 << g->mux_bit);
|
val &= mask;
|
||||||
val |= i << g->mux_bit;
|
val |= i << g->mux_bit;
|
||||||
writel(val, pctrl->regs + g->ctl_reg);
|
writel(val, pctrl->regs + g->ctl_reg);
|
||||||
|
|
||||||
|
|
|
@ -506,6 +506,8 @@ enum msm8660_functions {
|
||||||
MSM_MUX_usb_fs2_oe_n,
|
MSM_MUX_usb_fs2_oe_n,
|
||||||
MSM_MUX_vfe,
|
MSM_MUX_vfe,
|
||||||
MSM_MUX_vsens_alarm,
|
MSM_MUX_vsens_alarm,
|
||||||
|
MSM_MUX_ebi2cs,
|
||||||
|
MSM_MUX_ebi2,
|
||||||
MSM_MUX__,
|
MSM_MUX__,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -696,6 +698,36 @@ static const char * const vfe_groups[] = {
|
||||||
static const char * const vsens_alarm_groups[] = {
|
static const char * const vsens_alarm_groups[] = {
|
||||||
"gpio127"
|
"gpio127"
|
||||||
};
|
};
|
||||||
|
static const char * const ebi2cs_groups[] = {
|
||||||
|
"gpio39", /* CS1A */
|
||||||
|
"gpio40", /* CS2A */
|
||||||
|
"gpio123", /* CS1B */
|
||||||
|
"gpio124", /* CS2B */
|
||||||
|
"gpio131", /* CS5 */
|
||||||
|
"gpio132", /* CS4 */
|
||||||
|
"gpio133", /* CS3 */
|
||||||
|
"gpio134", /* CS0 */
|
||||||
|
};
|
||||||
|
static const char * const ebi2_groups[] = {
|
||||||
|
/* ADDR9 & ADDR8 */
|
||||||
|
"gpio37", "gpio38",
|
||||||
|
/* ADDR7 - ADDR 0 */
|
||||||
|
"gpio123", "gpio124", "gpio125", "gpio126",
|
||||||
|
"gpio127", "gpio128", "gpio129", "gpio130",
|
||||||
|
/* (muxed address+data) AD15 - AD0 */
|
||||||
|
"gpio135", "gpio136", "gpio137", "gpio138", "gpio139",
|
||||||
|
"gpio140", "gpio141", "gpio142", "gpio143", "gpio144",
|
||||||
|
"gpio145", "gpio146", "gpio147", "gpio148", "gpio149",
|
||||||
|
"gpio150",
|
||||||
|
"gpio151", /* OE output enable */
|
||||||
|
"gpio152", /* clock */
|
||||||
|
"gpio153", /* ADV */
|
||||||
|
"gpio154", /* WAIT (input) */
|
||||||
|
"gpio155", /* UB Upper Byte Enable */
|
||||||
|
"gpio156", /* LB Lower Byte Enable */
|
||||||
|
"gpio157", /* WE Write Enable */
|
||||||
|
"gpio158", /* busy */
|
||||||
|
};
|
||||||
|
|
||||||
static const struct msm_function msm8660_functions[] = {
|
static const struct msm_function msm8660_functions[] = {
|
||||||
FUNCTION(gpio),
|
FUNCTION(gpio),
|
||||||
|
@ -749,6 +781,8 @@ static const struct msm_function msm8660_functions[] = {
|
||||||
FUNCTION(usb_fs2_oe_n),
|
FUNCTION(usb_fs2_oe_n),
|
||||||
FUNCTION(vfe),
|
FUNCTION(vfe),
|
||||||
FUNCTION(vsens_alarm),
|
FUNCTION(vsens_alarm),
|
||||||
|
FUNCTION(ebi2cs), /* for EBI2 chip selects */
|
||||||
|
FUNCTION(ebi2), /* for general EBI2 pins */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct msm_pingroup msm8660_groups[] = {
|
static const struct msm_pingroup msm8660_groups[] = {
|
||||||
|
@ -789,10 +823,10 @@ static const struct msm_pingroup msm8660_groups[] = {
|
||||||
PINGROUP(34, gsbi1, _, _, _, _, _, _),
|
PINGROUP(34, gsbi1, _, _, _, _, _, _),
|
||||||
PINGROUP(35, gsbi1, _, _, _, _, _, _),
|
PINGROUP(35, gsbi1, _, _, _, _, _, _),
|
||||||
PINGROUP(36, gsbi1, _, _, _, _, _, _),
|
PINGROUP(36, gsbi1, _, _, _, _, _, _),
|
||||||
PINGROUP(37, gsbi2, _, _, _, _, _, _),
|
PINGROUP(37, gsbi2, ebi2, _, _, _, _, _),
|
||||||
PINGROUP(38, gsbi2, _, _, _, _, _, _),
|
PINGROUP(38, gsbi2, ebi2, _, _, _, _, _),
|
||||||
PINGROUP(39, gsbi2, _, mdp_vsync, _, _, _, _),
|
PINGROUP(39, gsbi2, ebi2cs, mdp_vsync, _, _, _, _),
|
||||||
PINGROUP(40, gsbi2, _, _, _, _, _, _),
|
PINGROUP(40, gsbi2, ebi2cs, _, _, _, _, _),
|
||||||
PINGROUP(41, gsbi3, mdp_vsync, _, _, _, _, _),
|
PINGROUP(41, gsbi3, mdp_vsync, _, _, _, _, _),
|
||||||
PINGROUP(42, gsbi3, vfe, _, _, _, _, _),
|
PINGROUP(42, gsbi3, vfe, _, _, _, _, _),
|
||||||
PINGROUP(43, gsbi3, _, _, _, _, _, _),
|
PINGROUP(43, gsbi3, _, _, _, _, _, _),
|
||||||
|
@ -875,42 +909,42 @@ static const struct msm_pingroup msm8660_groups[] = {
|
||||||
PINGROUP(120, i2s, _, _, _, _, _, _),
|
PINGROUP(120, i2s, _, _, _, _, _, _),
|
||||||
PINGROUP(121, i2s, _, _, _, _, _, _),
|
PINGROUP(121, i2s, _, _, _, _, _, _),
|
||||||
PINGROUP(122, i2s, gp_clk_1b, _, _, _, _, _),
|
PINGROUP(122, i2s, gp_clk_1b, _, _, _, _, _),
|
||||||
PINGROUP(123, _, gsbi2_spi_cs1_n, _, _, _, _, _),
|
PINGROUP(123, ebi2, gsbi2_spi_cs1_n, ebi2cs, _, _, _, _),
|
||||||
PINGROUP(124, _, gsbi2_spi_cs2_n, _, _, _, _, _),
|
PINGROUP(124, ebi2, gsbi2_spi_cs2_n, ebi2cs, _, _, _, _),
|
||||||
PINGROUP(125, _, gsbi2_spi_cs3_n, _, _, _, _, _),
|
PINGROUP(125, ebi2, gsbi2_spi_cs3_n, _, _, _, _, _),
|
||||||
PINGROUP(126, _, _, _, _, _, _, _),
|
PINGROUP(126, ebi2, _, _, _, _, _, _),
|
||||||
PINGROUP(127, _, vsens_alarm, _, _, _, _, _),
|
PINGROUP(127, ebi2, vsens_alarm, _, _, _, _, _),
|
||||||
PINGROUP(128, _, _, _, _, _, _, _),
|
PINGROUP(128, ebi2, _, _, _, _, _, _),
|
||||||
PINGROUP(129, _, _, _, _, _, _, _),
|
PINGROUP(129, ebi2, _, _, _, _, _, _),
|
||||||
PINGROUP(130, _, _, _, _, _, _, _),
|
PINGROUP(130, ebi2, _, _, _, _, _, _),
|
||||||
PINGROUP(131, _, _, _, _, _, _, _),
|
PINGROUP(131, ebi2cs, _, _, _, _, _, _),
|
||||||
PINGROUP(132, _, _, _, _, _, _, _),
|
PINGROUP(132, ebi2cs, _, _, _, _, _, _),
|
||||||
PINGROUP(133, _, _, _, _, _, _, _),
|
PINGROUP(133, ebi2cs, _, _, _, _, _, _),
|
||||||
PINGROUP(134, _, _, _, _, _, _, _),
|
PINGROUP(134, ebi2cs, _, _, _, _, _, _),
|
||||||
PINGROUP(135, _, _, _, _, _, _, _),
|
PINGROUP(135, ebi2, _, _, _, _, _, _),
|
||||||
PINGROUP(136, _, _, _, _, _, _, _),
|
PINGROUP(136, ebi2, _, _, _, _, _, _),
|
||||||
PINGROUP(137, _, _, _, _, _, _, _),
|
PINGROUP(137, ebi2, _, _, _, _, _, _),
|
||||||
PINGROUP(138, _, _, _, _, _, _, _),
|
PINGROUP(138, ebi2, _, _, _, _, _, _),
|
||||||
PINGROUP(139, _, _, _, _, _, _, _),
|
PINGROUP(139, ebi2, _, _, _, _, _, _),
|
||||||
PINGROUP(140, _, _, _, _, _, _, _),
|
PINGROUP(140, ebi2, _, _, _, _, _, _),
|
||||||
PINGROUP(141, _, _, _, _, _, _, _),
|
PINGROUP(141, ebi2, _, _, _, _, _, _),
|
||||||
PINGROUP(142, _, _, _, _, _, _, _),
|
PINGROUP(142, ebi2, _, _, _, _, _, _),
|
||||||
PINGROUP(143, _, sdc2, _, _, _, _, _),
|
PINGROUP(143, ebi2, sdc2, _, _, _, _, _),
|
||||||
PINGROUP(144, _, sdc2, _, _, _, _, _),
|
PINGROUP(144, ebi2, sdc2, _, _, _, _, _),
|
||||||
PINGROUP(145, _, sdc2, _, _, _, _, _),
|
PINGROUP(145, ebi2, sdc2, _, _, _, _, _),
|
||||||
PINGROUP(146, _, sdc2, _, _, _, _, _),
|
PINGROUP(146, ebi2, sdc2, _, _, _, _, _),
|
||||||
PINGROUP(147, _, sdc2, _, _, _, _, _),
|
PINGROUP(147, ebi2, sdc2, _, _, _, _, _),
|
||||||
PINGROUP(148, _, sdc2, _, _, _, _, _),
|
PINGROUP(148, ebi2, sdc2, _, _, _, _, _),
|
||||||
PINGROUP(149, _, sdc2, _, _, _, _, _),
|
PINGROUP(149, ebi2, sdc2, _, _, _, _, _),
|
||||||
PINGROUP(150, _, sdc2, _, _, _, _, _),
|
PINGROUP(150, ebi2, sdc2, _, _, _, _, _),
|
||||||
PINGROUP(151, _, sdc2, _, _, _, _, _),
|
PINGROUP(151, ebi2, sdc2, _, _, _, _, _),
|
||||||
PINGROUP(152, _, sdc2, _, _, _, _, _),
|
PINGROUP(152, ebi2, sdc2, _, _, _, _, _),
|
||||||
PINGROUP(153, _, _, _, _, _, _, _),
|
PINGROUP(153, ebi2, _, _, _, _, _, _),
|
||||||
PINGROUP(154, _, _, _, _, _, _, _),
|
PINGROUP(154, ebi2, _, _, _, _, _, _),
|
||||||
PINGROUP(155, _, _, _, _, _, _, _),
|
PINGROUP(155, ebi2, _, _, _, _, _, _),
|
||||||
PINGROUP(156, _, _, _, _, _, _, _),
|
PINGROUP(156, ebi2, _, _, _, _, _, _),
|
||||||
PINGROUP(157, _, _, _, _, _, _, _),
|
PINGROUP(157, ebi2, _, _, _, _, _, _),
|
||||||
PINGROUP(158, _, _, _, _, _, _, _),
|
PINGROUP(158, ebi2, _, _, _, _, _, _),
|
||||||
PINGROUP(159, sdc1, _, _, _, _, _, _),
|
PINGROUP(159, sdc1, _, _, _, _, _, _),
|
||||||
PINGROUP(160, sdc1, _, _, _, _, _, _),
|
PINGROUP(160, sdc1, _, _, _, _, _, _),
|
||||||
PINGROUP(161, sdc1, _, _, _, _, _, _),
|
PINGROUP(161, sdc1, _, _, _, _, _, _),
|
||||||
|
|
|
@ -172,6 +172,8 @@ static const struct pinctrl_pin_desc msm8x74_pins[] = {
|
||||||
PINCTRL_PIN(149, "SDC2_CLK"),
|
PINCTRL_PIN(149, "SDC2_CLK"),
|
||||||
PINCTRL_PIN(150, "SDC2_CMD"),
|
PINCTRL_PIN(150, "SDC2_CMD"),
|
||||||
PINCTRL_PIN(151, "SDC2_DATA"),
|
PINCTRL_PIN(151, "SDC2_DATA"),
|
||||||
|
PINCTRL_PIN(152, "HSIC_STROBE"),
|
||||||
|
PINCTRL_PIN(153, "HSIC_DATA"),
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DECLARE_MSM_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin }
|
#define DECLARE_MSM_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin }
|
||||||
|
@ -328,6 +330,8 @@ static const unsigned int sdc1_data_pins[] = { 148 };
|
||||||
static const unsigned int sdc2_clk_pins[] = { 149 };
|
static const unsigned int sdc2_clk_pins[] = { 149 };
|
||||||
static const unsigned int sdc2_cmd_pins[] = { 150 };
|
static const unsigned int sdc2_cmd_pins[] = { 150 };
|
||||||
static const unsigned int sdc2_data_pins[] = { 151 };
|
static const unsigned int sdc2_data_pins[] = { 151 };
|
||||||
|
static const unsigned int hsic_strobe_pins[] = { 152 };
|
||||||
|
static const unsigned int hsic_data_pins[] = { 153 };
|
||||||
|
|
||||||
#define FUNCTION(fname) \
|
#define FUNCTION(fname) \
|
||||||
[MSM_MUX_##fname] = { \
|
[MSM_MUX_##fname] = { \
|
||||||
|
@ -399,6 +403,37 @@ static const unsigned int sdc2_data_pins[] = { 151 };
|
||||||
.intr_detection_width = -1, \
|
.intr_detection_width = -1, \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define HSIC_PINGROUP(pg_name, ctl) \
|
||||||
|
{ \
|
||||||
|
.name = #pg_name, \
|
||||||
|
.pins = pg_name##_pins, \
|
||||||
|
.npins = ARRAY_SIZE(pg_name##_pins), \
|
||||||
|
.funcs = (int[]){ \
|
||||||
|
MSM_MUX_gpio, \
|
||||||
|
MSM_MUX_hsic_ctl, \
|
||||||
|
}, \
|
||||||
|
.nfuncs = 2, \
|
||||||
|
.ctl_reg = ctl, \
|
||||||
|
.io_reg = 0, \
|
||||||
|
.intr_cfg_reg = 0, \
|
||||||
|
.intr_status_reg = 0, \
|
||||||
|
.intr_target_reg = 0, \
|
||||||
|
.mux_bit = 25, \
|
||||||
|
.pull_bit = -1, \
|
||||||
|
.drv_bit = -1, \
|
||||||
|
.oe_bit = -1, \
|
||||||
|
.in_bit = -1, \
|
||||||
|
.out_bit = -1, \
|
||||||
|
.intr_enable_bit = -1, \
|
||||||
|
.intr_status_bit = -1, \
|
||||||
|
.intr_target_bit = -1, \
|
||||||
|
.intr_target_kpss_val = -1, \
|
||||||
|
.intr_raw_status_bit = -1, \
|
||||||
|
.intr_polarity_bit = -1, \
|
||||||
|
.intr_detection_bit = -1, \
|
||||||
|
.intr_detection_width = -1, \
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: Add the rest of the possible functions and fill out
|
* TODO: Add the rest of the possible functions and fill out
|
||||||
* the pingroup table below.
|
* the pingroup table below.
|
||||||
|
@ -509,6 +544,7 @@ enum msm8x74_functions {
|
||||||
MSM_MUX_fm,
|
MSM_MUX_fm,
|
||||||
MSM_MUX_wlan,
|
MSM_MUX_wlan,
|
||||||
MSM_MUX_slimbus,
|
MSM_MUX_slimbus,
|
||||||
|
MSM_MUX_hsic_ctl,
|
||||||
MSM_MUX_NA,
|
MSM_MUX_NA,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -534,7 +570,8 @@ static const char * const gpio_groups[] = {
|
||||||
"gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128",
|
"gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128",
|
||||||
"gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134",
|
"gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134",
|
||||||
"gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140",
|
"gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140",
|
||||||
"gpio141", "gpio142", "gpio143", "gpio144", "gpio145"
|
"gpio141", "gpio142", "gpio143", "gpio144", "gpio145", "hsic_data",
|
||||||
|
"hsic_strobe",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char * const blsp_uart1_groups[] = {
|
static const char * const blsp_uart1_groups[] = {
|
||||||
|
@ -754,6 +791,7 @@ static const char * const wlan_groups[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char * const slimbus_groups[] = { "gpio70", "gpio71" };
|
static const char * const slimbus_groups[] = { "gpio70", "gpio71" };
|
||||||
|
static const char * const hsic_ctl_groups[] = { "hsic_strobe", "hsic_data" };
|
||||||
|
|
||||||
static const struct msm_function msm8x74_functions[] = {
|
static const struct msm_function msm8x74_functions[] = {
|
||||||
FUNCTION(gpio),
|
FUNCTION(gpio),
|
||||||
|
@ -861,6 +899,7 @@ static const struct msm_function msm8x74_functions[] = {
|
||||||
FUNCTION(fm),
|
FUNCTION(fm),
|
||||||
FUNCTION(wlan),
|
FUNCTION(wlan),
|
||||||
FUNCTION(slimbus),
|
FUNCTION(slimbus),
|
||||||
|
FUNCTION(hsic_ctl),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct msm_pingroup msm8x74_groups[] = {
|
static const struct msm_pingroup msm8x74_groups[] = {
|
||||||
|
@ -1016,6 +1055,8 @@ static const struct msm_pingroup msm8x74_groups[] = {
|
||||||
SDC_PINGROUP(sdc2_clk, 0x2048, 14, 6),
|
SDC_PINGROUP(sdc2_clk, 0x2048, 14, 6),
|
||||||
SDC_PINGROUP(sdc2_cmd, 0x2048, 11, 3),
|
SDC_PINGROUP(sdc2_cmd, 0x2048, 11, 3),
|
||||||
SDC_PINGROUP(sdc2_data, 0x2048, 9, 0),
|
SDC_PINGROUP(sdc2_data, 0x2048, 9, 0),
|
||||||
|
HSIC_PINGROUP(hsic_strobe, 0x2050),
|
||||||
|
HSIC_PINGROUP(hsic_data, 0x2054),
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NUM_GPIO_PINGROUPS 146
|
#define NUM_GPIO_PINGROUPS 146
|
||||||
|
|
|
@ -744,6 +744,7 @@ static int pm8xxx_pin_populate(struct pm8xxx_mpp *pctrl,
|
||||||
static const struct of_device_id pm8xxx_mpp_of_match[] = {
|
static const struct of_device_id pm8xxx_mpp_of_match[] = {
|
||||||
{ .compatible = "qcom,pm8018-mpp" },
|
{ .compatible = "qcom,pm8018-mpp" },
|
||||||
{ .compatible = "qcom,pm8038-mpp" },
|
{ .compatible = "qcom,pm8038-mpp" },
|
||||||
|
{ .compatible = "qcom,pm8058-mpp" },
|
||||||
{ .compatible = "qcom,pm8917-mpp" },
|
{ .compatible = "qcom,pm8917-mpp" },
|
||||||
{ .compatible = "qcom,pm8821-mpp" },
|
{ .compatible = "qcom,pm8821-mpp" },
|
||||||
{ .compatible = "qcom,pm8921-mpp" },
|
{ .compatible = "qcom,pm8921-mpp" },
|
||||||
|
|
|
@ -998,6 +998,7 @@ static struct platform_driver exynos5440_pinctrl_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "exynos5440-pinctrl",
|
.name = "exynos5440-pinctrl",
|
||||||
.of_match_table = exynos5440_pinctrl_dt_match,
|
.of_match_table = exynos5440_pinctrl_dt_match,
|
||||||
|
.suppress_bind_attrs = true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1274,6 +1274,7 @@ static struct platform_driver samsung_pinctrl_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "samsung-pinctrl",
|
.name = "samsung-pinctrl",
|
||||||
.of_match_table = samsung_pinctrl_dt_match,
|
.of_match_table = samsung_pinctrl_dt_match,
|
||||||
|
.suppress_bind_attrs = true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -598,15 +598,6 @@ static int sh_pfc_probe(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sh_pfc_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_PINCTRL_SH_PFC_GPIO
|
|
||||||
sh_pfc_unregister_gpiochip(platform_get_drvdata(pdev));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct platform_device_id sh_pfc_id_table[] = {
|
static const struct platform_device_id sh_pfc_id_table[] = {
|
||||||
#ifdef CONFIG_PINCTRL_PFC_SH7203
|
#ifdef CONFIG_PINCTRL_PFC_SH7203
|
||||||
{ "pfc-sh7203", (kernel_ulong_t)&sh7203_pinmux_info },
|
{ "pfc-sh7203", (kernel_ulong_t)&sh7203_pinmux_info },
|
||||||
|
@ -650,7 +641,6 @@ static const struct platform_device_id sh_pfc_id_table[] = {
|
||||||
|
|
||||||
static struct platform_driver sh_pfc_driver = {
|
static struct platform_driver sh_pfc_driver = {
|
||||||
.probe = sh_pfc_probe,
|
.probe = sh_pfc_probe,
|
||||||
.remove = sh_pfc_remove,
|
|
||||||
.id_table = sh_pfc_id_table,
|
.id_table = sh_pfc_id_table,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
|
|
|
@ -10,50 +10,16 @@
|
||||||
#ifndef __SH_PFC_CORE_H__
|
#ifndef __SH_PFC_CORE_H__
|
||||||
#define __SH_PFC_CORE_H__
|
#define __SH_PFC_CORE_H__
|
||||||
|
|
||||||
#include <linux/compiler.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
#include "sh_pfc.h"
|
#include "sh_pfc.h"
|
||||||
|
|
||||||
struct sh_pfc_window {
|
|
||||||
phys_addr_t phys;
|
|
||||||
void __iomem *virt;
|
|
||||||
unsigned long size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sh_pfc_chip;
|
|
||||||
struct sh_pfc_pinctrl;
|
|
||||||
|
|
||||||
struct sh_pfc_pin_range {
|
struct sh_pfc_pin_range {
|
||||||
u16 start;
|
u16 start;
|
||||||
u16 end;
|
u16 end;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sh_pfc {
|
|
||||||
struct device *dev;
|
|
||||||
const struct sh_pfc_soc_info *info;
|
|
||||||
spinlock_t lock;
|
|
||||||
|
|
||||||
unsigned int num_windows;
|
|
||||||
struct sh_pfc_window *windows;
|
|
||||||
unsigned int num_irqs;
|
|
||||||
unsigned int *irqs;
|
|
||||||
|
|
||||||
struct sh_pfc_pin_range *ranges;
|
|
||||||
unsigned int nr_ranges;
|
|
||||||
|
|
||||||
unsigned int nr_gpio_pins;
|
|
||||||
|
|
||||||
struct sh_pfc_chip *gpio;
|
|
||||||
#ifdef CONFIG_SUPERH
|
|
||||||
struct sh_pfc_chip *func;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
int sh_pfc_register_gpiochip(struct sh_pfc *pfc);
|
int sh_pfc_register_gpiochip(struct sh_pfc *pfc);
|
||||||
int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc);
|
|
||||||
|
|
||||||
int sh_pfc_register_pinctrl(struct sh_pfc *pfc);
|
int sh_pfc_register_pinctrl(struct sh_pfc *pfc);
|
||||||
|
|
||||||
|
@ -67,28 +33,4 @@ void sh_pfc_write_reg(struct sh_pfc *pfc, u32 reg, unsigned int width,
|
||||||
int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin);
|
int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin);
|
||||||
int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type);
|
int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type);
|
||||||
|
|
||||||
extern const struct sh_pfc_soc_info emev2_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info r8a73a4_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info r8a7740_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info r8a7778_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info r8a7779_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info r8a7790_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info r8a7791_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info r8a7793_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info r8a7794_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info r8a7795_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info sh7203_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info sh7264_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info sh7269_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info sh73a0_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info sh7720_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info sh7722_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info sh7723_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info sh7724_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info sh7734_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info sh7757_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info sh7785_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info sh7786_pinmux_info;
|
|
||||||
extern const struct sh_pfc_soc_info shx3_pinmux_info;
|
|
||||||
|
|
||||||
#endif /* __SH_PFC_CORE_H__ */
|
#endif /* __SH_PFC_CORE_H__ */
|
||||||
|
|
|
@ -318,7 +318,7 @@ sh_pfc_add_gpiochip(struct sh_pfc *pfc, int(*setup)(struct sh_pfc_chip *),
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
|
|
||||||
ret = gpiochip_add_data(&chip->gpio_chip, chip);
|
ret = devm_gpiochip_add_data(pfc->dev, &chip->gpio_chip, chip);
|
||||||
if (unlikely(ret < 0))
|
if (unlikely(ret < 0))
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
|
|
||||||
|
@ -399,18 +399,7 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
|
||||||
chip = sh_pfc_add_gpiochip(pfc, gpio_function_setup, NULL);
|
chip = sh_pfc_add_gpiochip(pfc, gpio_function_setup, NULL);
|
||||||
if (IS_ERR(chip))
|
if (IS_ERR(chip))
|
||||||
return PTR_ERR(chip);
|
return PTR_ERR(chip);
|
||||||
|
|
||||||
pfc->func = chip;
|
|
||||||
#endif /* CONFIG_SUPERH */
|
#endif /* CONFIG_SUPERH */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc)
|
|
||||||
{
|
|
||||||
gpiochip_remove(&pfc->gpio->gpio_chip);
|
|
||||||
#ifdef CONFIG_SUPERH
|
|
||||||
gpiochip_remove(&pfc->func->gpio_chip);
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/pinctrl/pinconf-generic.h>
|
#include <linux/pinctrl/pinconf-generic.h>
|
||||||
|
|
||||||
#include "core.h"
|
|
||||||
#include "sh_pfc.h"
|
#include "sh_pfc.h"
|
||||||
|
|
||||||
#define CPU_ALL_PORT(fn, pfx, sfx) \
|
#define CPU_ALL_PORT(fn, pfx, sfx) \
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/pinctrl/pinconf-generic.h>
|
#include <linux/pinctrl/pinconf-generic.h>
|
||||||
|
|
||||||
#include "core.h"
|
|
||||||
#include "sh_pfc.h"
|
#include "sh_pfc.h"
|
||||||
|
|
||||||
#define CPU_ALL_PORT(fn, pfx, sfx) \
|
#define CPU_ALL_PORT(fn, pfx, sfx) \
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/pinctrl/pinconf-generic.h>
|
#include <linux/pinctrl/pinconf-generic.h>
|
||||||
#include "core.h"
|
|
||||||
#include "sh_pfc.h"
|
#include "sh_pfc.h"
|
||||||
|
|
||||||
#define PORT_GP_PUP_1(bank, pin, fn, sfx) \
|
#define PORT_GP_PUP_1(bank, pin, fn, sfx) \
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
|
||||||
#include "core.h"
|
|
||||||
#include "sh_pfc.h"
|
#include "sh_pfc.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -4696,47 +4695,6 @@ static const char * const vin3_groups[] = {
|
||||||
"vin3_clk",
|
"vin3_clk",
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IOCTRL6 0x8c
|
|
||||||
|
|
||||||
static int r8a7790_get_io_voltage(struct sh_pfc *pfc, unsigned int pin)
|
|
||||||
{
|
|
||||||
u32 data, mask;
|
|
||||||
|
|
||||||
if (WARN(pin < RCAR_GP_PIN(3, 0) || pin > RCAR_GP_PIN(3, 31), "invalid pin %#x", pin))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
data = ioread32(pfc->windows->virt + IOCTRL6),
|
|
||||||
/* Bits in IOCTRL6 are numbered in opposite order to pins */
|
|
||||||
mask = 0x80000000 >> (pin & 0x1f);
|
|
||||||
|
|
||||||
return (data & mask) ? 3300 : 1800;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8a7790_set_io_voltage(struct sh_pfc *pfc, unsigned int pin, u16 mV)
|
|
||||||
{
|
|
||||||
u32 data, mask;
|
|
||||||
|
|
||||||
if (WARN(pin < RCAR_GP_PIN(3, 0) || pin > RCAR_GP_PIN(3, 31), "invalid pin %#x", pin))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (mV != 1800 && mV != 3300)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
data = ioread32(pfc->windows->virt + IOCTRL6);
|
|
||||||
/* Bits in IOCTRL6 are numbered in opposite order to pins */
|
|
||||||
mask = 0x80000000 >> (pin & 0x1f);
|
|
||||||
|
|
||||||
if (mV == 3300)
|
|
||||||
data |= mask;
|
|
||||||
else
|
|
||||||
data &= ~mask;
|
|
||||||
|
|
||||||
iowrite32(~data, pfc->windows->virt); /* unlock reg */
|
|
||||||
iowrite32(data, pfc->windows->virt + IOCTRL6);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct sh_pfc_function pinmux_functions[] = {
|
static const struct sh_pfc_function pinmux_functions[] = {
|
||||||
SH_PFC_FUNCTION(audio_clk),
|
SH_PFC_FUNCTION(audio_clk),
|
||||||
SH_PFC_FUNCTION(avb),
|
SH_PFC_FUNCTION(avb),
|
||||||
|
@ -5736,14 +5694,23 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct sh_pfc_soc_operations pinmux_ops = {
|
static int r8a7790_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl)
|
||||||
.get_io_voltage = r8a7790_get_io_voltage,
|
{
|
||||||
.set_io_voltage = r8a7790_set_io_voltage,
|
if (pin < RCAR_GP_PIN(3, 0) || pin > RCAR_GP_PIN(3, 31))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
*pocctrl = 0xe606008c;
|
||||||
|
|
||||||
|
return 31 - (pin & 0x1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct sh_pfc_soc_operations r8a7790_pinmux_ops = {
|
||||||
|
.pin_to_pocctrl = r8a7790_pin_to_pocctrl,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct sh_pfc_soc_info r8a7790_pinmux_info = {
|
const struct sh_pfc_soc_info r8a7790_pinmux_info = {
|
||||||
.name = "r8a77900_pfc",
|
.name = "r8a77900_pfc",
|
||||||
.ops = &pinmux_ops,
|
.ops = &r8a7790_pinmux_ops,
|
||||||
.unlock_reg = 0xe6060000, /* PMMR */
|
.unlock_reg = 0xe6060000, /* PMMR */
|
||||||
|
|
||||||
.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
|
.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
|
||||||
#include "core.h"
|
|
||||||
#include "sh_pfc.h"
|
#include "sh_pfc.h"
|
||||||
|
|
||||||
#define CPU_ALL_PORT(fn, sfx) \
|
#define CPU_ALL_PORT(fn, sfx) \
|
||||||
|
|
|
@ -17,8 +17,12 @@
|
||||||
PORT_GP_CFG_16(0, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
|
PORT_GP_CFG_16(0, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
|
||||||
PORT_GP_CFG_28(1, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
|
PORT_GP_CFG_28(1, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
|
||||||
PORT_GP_CFG_15(2, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
|
PORT_GP_CFG_15(2, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
|
||||||
PORT_GP_CFG_16(3, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
|
PORT_GP_CFG_12(3, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH | SH_PFC_PIN_CFG_IO_VOLTAGE), \
|
||||||
PORT_GP_CFG_18(4, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
|
PORT_GP_CFG_1(3, 12, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
|
||||||
|
PORT_GP_CFG_1(3, 13, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
|
||||||
|
PORT_GP_CFG_1(3, 14, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
|
||||||
|
PORT_GP_CFG_1(3, 15, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
|
||||||
|
PORT_GP_CFG_18(4, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH | SH_PFC_PIN_CFG_IO_VOLTAGE), \
|
||||||
PORT_GP_CFG_26(5, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
|
PORT_GP_CFG_26(5, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
|
||||||
PORT_GP_CFG_32(6, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
|
PORT_GP_CFG_32(6, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
|
||||||
PORT_GP_CFG_4(7, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH)
|
PORT_GP_CFG_4(7, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH)
|
||||||
|
@ -552,6 +556,9 @@ static const u16 pinmux_data[] = {
|
||||||
PINMUX_SINGLE(AVS2),
|
PINMUX_SINGLE(AVS2),
|
||||||
PINMUX_SINGLE(HDMI0_CEC),
|
PINMUX_SINGLE(HDMI0_CEC),
|
||||||
PINMUX_SINGLE(HDMI1_CEC),
|
PINMUX_SINGLE(HDMI1_CEC),
|
||||||
|
PINMUX_SINGLE(I2C_SEL_0_1),
|
||||||
|
PINMUX_SINGLE(I2C_SEL_3_1),
|
||||||
|
PINMUX_SINGLE(I2C_SEL_5_1),
|
||||||
PINMUX_SINGLE(MSIOF0_RXD),
|
PINMUX_SINGLE(MSIOF0_RXD),
|
||||||
PINMUX_SINGLE(MSIOF0_SCK),
|
PINMUX_SINGLE(MSIOF0_SCK),
|
||||||
PINMUX_SINGLE(MSIOF0_TXD),
|
PINMUX_SINGLE(MSIOF0_TXD),
|
||||||
|
@ -1401,11 +1408,6 @@ static const u16 pinmux_data[] = {
|
||||||
PINMUX_IPSR_MSEL(IP17_7_4, STP_ISSYNC_0_E, SEL_SSP1_0_4),
|
PINMUX_IPSR_MSEL(IP17_7_4, STP_ISSYNC_0_E, SEL_SSP1_0_4),
|
||||||
PINMUX_IPSR_MSEL(IP17_7_4, RIF2_D1_B, SEL_DRIF2_1),
|
PINMUX_IPSR_MSEL(IP17_7_4, RIF2_D1_B, SEL_DRIF2_1),
|
||||||
PINMUX_IPSR_GPSR(IP17_7_4, TPU0TO3),
|
PINMUX_IPSR_GPSR(IP17_7_4, TPU0TO3),
|
||||||
|
|
||||||
/* I2C */
|
|
||||||
PINMUX_IPSR_NOGP(0, I2C_SEL_0_1),
|
|
||||||
PINMUX_IPSR_NOGP(0, I2C_SEL_3_1),
|
|
||||||
PINMUX_IPSR_NOGP(0, I2C_SEL_5_1),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct sh_pfc_pin pinmux_pins[] = {
|
static const struct sh_pfc_pin pinmux_pins[] = {
|
||||||
|
@ -1654,6 +1656,221 @@ static const unsigned int canfd1_data_mux[] = {
|
||||||
CANFD1_TX_MARK, CANFD1_RX_MARK,
|
CANFD1_TX_MARK, CANFD1_RX_MARK,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* - DRIF0 --------------------------------------------------------------- */
|
||||||
|
static const unsigned int drif0_ctrl_a_pins[] = {
|
||||||
|
/* CLK, SYNC */
|
||||||
|
RCAR_GP_PIN(6, 8), RCAR_GP_PIN(6, 9),
|
||||||
|
};
|
||||||
|
static const unsigned int drif0_ctrl_a_mux[] = {
|
||||||
|
RIF0_CLK_A_MARK, RIF0_SYNC_A_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif0_data0_a_pins[] = {
|
||||||
|
/* D0 */
|
||||||
|
RCAR_GP_PIN(6, 10),
|
||||||
|
};
|
||||||
|
static const unsigned int drif0_data0_a_mux[] = {
|
||||||
|
RIF0_D0_A_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif0_data1_a_pins[] = {
|
||||||
|
/* D1 */
|
||||||
|
RCAR_GP_PIN(6, 7),
|
||||||
|
};
|
||||||
|
static const unsigned int drif0_data1_a_mux[] = {
|
||||||
|
RIF0_D1_A_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif0_ctrl_b_pins[] = {
|
||||||
|
/* CLK, SYNC */
|
||||||
|
RCAR_GP_PIN(5, 0), RCAR_GP_PIN(5, 4),
|
||||||
|
};
|
||||||
|
static const unsigned int drif0_ctrl_b_mux[] = {
|
||||||
|
RIF0_CLK_B_MARK, RIF0_SYNC_B_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif0_data0_b_pins[] = {
|
||||||
|
/* D0 */
|
||||||
|
RCAR_GP_PIN(5, 1),
|
||||||
|
};
|
||||||
|
static const unsigned int drif0_data0_b_mux[] = {
|
||||||
|
RIF0_D0_B_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif0_data1_b_pins[] = {
|
||||||
|
/* D1 */
|
||||||
|
RCAR_GP_PIN(5, 2),
|
||||||
|
};
|
||||||
|
static const unsigned int drif0_data1_b_mux[] = {
|
||||||
|
RIF0_D1_B_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif0_ctrl_c_pins[] = {
|
||||||
|
/* CLK, SYNC */
|
||||||
|
RCAR_GP_PIN(5, 12), RCAR_GP_PIN(5, 15),
|
||||||
|
};
|
||||||
|
static const unsigned int drif0_ctrl_c_mux[] = {
|
||||||
|
RIF0_CLK_C_MARK, RIF0_SYNC_C_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif0_data0_c_pins[] = {
|
||||||
|
/* D0 */
|
||||||
|
RCAR_GP_PIN(5, 13),
|
||||||
|
};
|
||||||
|
static const unsigned int drif0_data0_c_mux[] = {
|
||||||
|
RIF0_D0_C_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif0_data1_c_pins[] = {
|
||||||
|
/* D1 */
|
||||||
|
RCAR_GP_PIN(5, 14),
|
||||||
|
};
|
||||||
|
static const unsigned int drif0_data1_c_mux[] = {
|
||||||
|
RIF0_D1_C_MARK,
|
||||||
|
};
|
||||||
|
/* - DRIF1 --------------------------------------------------------------- */
|
||||||
|
static const unsigned int drif1_ctrl_a_pins[] = {
|
||||||
|
/* CLK, SYNC */
|
||||||
|
RCAR_GP_PIN(6, 17), RCAR_GP_PIN(6, 18),
|
||||||
|
};
|
||||||
|
static const unsigned int drif1_ctrl_a_mux[] = {
|
||||||
|
RIF1_CLK_A_MARK, RIF1_SYNC_A_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif1_data0_a_pins[] = {
|
||||||
|
/* D0 */
|
||||||
|
RCAR_GP_PIN(6, 19),
|
||||||
|
};
|
||||||
|
static const unsigned int drif1_data0_a_mux[] = {
|
||||||
|
RIF1_D0_A_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif1_data1_a_pins[] = {
|
||||||
|
/* D1 */
|
||||||
|
RCAR_GP_PIN(6, 20),
|
||||||
|
};
|
||||||
|
static const unsigned int drif1_data1_a_mux[] = {
|
||||||
|
RIF1_D1_A_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif1_ctrl_b_pins[] = {
|
||||||
|
/* CLK, SYNC */
|
||||||
|
RCAR_GP_PIN(5, 9), RCAR_GP_PIN(5, 3),
|
||||||
|
};
|
||||||
|
static const unsigned int drif1_ctrl_b_mux[] = {
|
||||||
|
RIF1_CLK_B_MARK, RIF1_SYNC_B_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif1_data0_b_pins[] = {
|
||||||
|
/* D0 */
|
||||||
|
RCAR_GP_PIN(5, 7),
|
||||||
|
};
|
||||||
|
static const unsigned int drif1_data0_b_mux[] = {
|
||||||
|
RIF1_D0_B_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif1_data1_b_pins[] = {
|
||||||
|
/* D1 */
|
||||||
|
RCAR_GP_PIN(5, 8),
|
||||||
|
};
|
||||||
|
static const unsigned int drif1_data1_b_mux[] = {
|
||||||
|
RIF1_D1_B_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif1_ctrl_c_pins[] = {
|
||||||
|
/* CLK, SYNC */
|
||||||
|
RCAR_GP_PIN(5, 5), RCAR_GP_PIN(5, 11),
|
||||||
|
};
|
||||||
|
static const unsigned int drif1_ctrl_c_mux[] = {
|
||||||
|
RIF1_CLK_C_MARK, RIF1_SYNC_C_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif1_data0_c_pins[] = {
|
||||||
|
/* D0 */
|
||||||
|
RCAR_GP_PIN(5, 6),
|
||||||
|
};
|
||||||
|
static const unsigned int drif1_data0_c_mux[] = {
|
||||||
|
RIF1_D0_C_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif1_data1_c_pins[] = {
|
||||||
|
/* D1 */
|
||||||
|
RCAR_GP_PIN(5, 10),
|
||||||
|
};
|
||||||
|
static const unsigned int drif1_data1_c_mux[] = {
|
||||||
|
RIF1_D1_C_MARK,
|
||||||
|
};
|
||||||
|
/* - DRIF2 --------------------------------------------------------------- */
|
||||||
|
static const unsigned int drif2_ctrl_a_pins[] = {
|
||||||
|
/* CLK, SYNC */
|
||||||
|
RCAR_GP_PIN(6, 8), RCAR_GP_PIN(6, 9),
|
||||||
|
};
|
||||||
|
static const unsigned int drif2_ctrl_a_mux[] = {
|
||||||
|
RIF2_CLK_A_MARK, RIF2_SYNC_A_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif2_data0_a_pins[] = {
|
||||||
|
/* D0 */
|
||||||
|
RCAR_GP_PIN(6, 7),
|
||||||
|
};
|
||||||
|
static const unsigned int drif2_data0_a_mux[] = {
|
||||||
|
RIF2_D0_A_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif2_data1_a_pins[] = {
|
||||||
|
/* D1 */
|
||||||
|
RCAR_GP_PIN(6, 10),
|
||||||
|
};
|
||||||
|
static const unsigned int drif2_data1_a_mux[] = {
|
||||||
|
RIF2_D1_A_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif2_ctrl_b_pins[] = {
|
||||||
|
/* CLK, SYNC */
|
||||||
|
RCAR_GP_PIN(6, 26), RCAR_GP_PIN(6, 27),
|
||||||
|
};
|
||||||
|
static const unsigned int drif2_ctrl_b_mux[] = {
|
||||||
|
RIF2_CLK_B_MARK, RIF2_SYNC_B_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif2_data0_b_pins[] = {
|
||||||
|
/* D0 */
|
||||||
|
RCAR_GP_PIN(6, 30),
|
||||||
|
};
|
||||||
|
static const unsigned int drif2_data0_b_mux[] = {
|
||||||
|
RIF2_D0_B_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif2_data1_b_pins[] = {
|
||||||
|
/* D1 */
|
||||||
|
RCAR_GP_PIN(6, 31),
|
||||||
|
};
|
||||||
|
static const unsigned int drif2_data1_b_mux[] = {
|
||||||
|
RIF2_D1_B_MARK,
|
||||||
|
};
|
||||||
|
/* - DRIF3 --------------------------------------------------------------- */
|
||||||
|
static const unsigned int drif3_ctrl_a_pins[] = {
|
||||||
|
/* CLK, SYNC */
|
||||||
|
RCAR_GP_PIN(6, 17), RCAR_GP_PIN(6, 18),
|
||||||
|
};
|
||||||
|
static const unsigned int drif3_ctrl_a_mux[] = {
|
||||||
|
RIF3_CLK_A_MARK, RIF3_SYNC_A_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif3_data0_a_pins[] = {
|
||||||
|
/* D0 */
|
||||||
|
RCAR_GP_PIN(6, 19),
|
||||||
|
};
|
||||||
|
static const unsigned int drif3_data0_a_mux[] = {
|
||||||
|
RIF3_D0_A_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif3_data1_a_pins[] = {
|
||||||
|
/* D1 */
|
||||||
|
RCAR_GP_PIN(6, 20),
|
||||||
|
};
|
||||||
|
static const unsigned int drif3_data1_a_mux[] = {
|
||||||
|
RIF3_D1_A_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif3_ctrl_b_pins[] = {
|
||||||
|
/* CLK, SYNC */
|
||||||
|
RCAR_GP_PIN(6, 24), RCAR_GP_PIN(6, 25),
|
||||||
|
};
|
||||||
|
static const unsigned int drif3_ctrl_b_mux[] = {
|
||||||
|
RIF3_CLK_B_MARK, RIF3_SYNC_B_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif3_data0_b_pins[] = {
|
||||||
|
/* D0 */
|
||||||
|
RCAR_GP_PIN(6, 28),
|
||||||
|
};
|
||||||
|
static const unsigned int drif3_data0_b_mux[] = {
|
||||||
|
RIF3_D0_B_MARK,
|
||||||
|
};
|
||||||
|
static const unsigned int drif3_data1_b_pins[] = {
|
||||||
|
/* D1 */
|
||||||
|
RCAR_GP_PIN(6, 29),
|
||||||
|
};
|
||||||
|
static const unsigned int drif3_data1_b_mux[] = {
|
||||||
|
RIF3_D1_B_MARK,
|
||||||
|
};
|
||||||
|
|
||||||
/* - HSCIF0 ----------------------------------------------------------------- */
|
/* - HSCIF0 ----------------------------------------------------------------- */
|
||||||
static const unsigned int hscif0_data_pins[] = {
|
static const unsigned int hscif0_data_pins[] = {
|
||||||
/* RX, TX */
|
/* RX, TX */
|
||||||
|
@ -3346,6 +3563,36 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
|
||||||
SH_PFC_PIN_GROUP(canfd0_data_a),
|
SH_PFC_PIN_GROUP(canfd0_data_a),
|
||||||
SH_PFC_PIN_GROUP(canfd0_data_b),
|
SH_PFC_PIN_GROUP(canfd0_data_b),
|
||||||
SH_PFC_PIN_GROUP(canfd1_data),
|
SH_PFC_PIN_GROUP(canfd1_data),
|
||||||
|
SH_PFC_PIN_GROUP(drif0_ctrl_a),
|
||||||
|
SH_PFC_PIN_GROUP(drif0_data0_a),
|
||||||
|
SH_PFC_PIN_GROUP(drif0_data1_a),
|
||||||
|
SH_PFC_PIN_GROUP(drif0_ctrl_b),
|
||||||
|
SH_PFC_PIN_GROUP(drif0_data0_b),
|
||||||
|
SH_PFC_PIN_GROUP(drif0_data1_b),
|
||||||
|
SH_PFC_PIN_GROUP(drif0_ctrl_c),
|
||||||
|
SH_PFC_PIN_GROUP(drif0_data0_c),
|
||||||
|
SH_PFC_PIN_GROUP(drif0_data1_c),
|
||||||
|
SH_PFC_PIN_GROUP(drif1_ctrl_a),
|
||||||
|
SH_PFC_PIN_GROUP(drif1_data0_a),
|
||||||
|
SH_PFC_PIN_GROUP(drif1_data1_a),
|
||||||
|
SH_PFC_PIN_GROUP(drif1_ctrl_b),
|
||||||
|
SH_PFC_PIN_GROUP(drif1_data0_b),
|
||||||
|
SH_PFC_PIN_GROUP(drif1_data1_b),
|
||||||
|
SH_PFC_PIN_GROUP(drif1_ctrl_c),
|
||||||
|
SH_PFC_PIN_GROUP(drif1_data0_c),
|
||||||
|
SH_PFC_PIN_GROUP(drif1_data1_c),
|
||||||
|
SH_PFC_PIN_GROUP(drif2_ctrl_a),
|
||||||
|
SH_PFC_PIN_GROUP(drif2_data0_a),
|
||||||
|
SH_PFC_PIN_GROUP(drif2_data1_a),
|
||||||
|
SH_PFC_PIN_GROUP(drif2_ctrl_b),
|
||||||
|
SH_PFC_PIN_GROUP(drif2_data0_b),
|
||||||
|
SH_PFC_PIN_GROUP(drif2_data1_b),
|
||||||
|
SH_PFC_PIN_GROUP(drif3_ctrl_a),
|
||||||
|
SH_PFC_PIN_GROUP(drif3_data0_a),
|
||||||
|
SH_PFC_PIN_GROUP(drif3_data1_a),
|
||||||
|
SH_PFC_PIN_GROUP(drif3_ctrl_b),
|
||||||
|
SH_PFC_PIN_GROUP(drif3_data0_b),
|
||||||
|
SH_PFC_PIN_GROUP(drif3_data1_b),
|
||||||
SH_PFC_PIN_GROUP(hscif0_data),
|
SH_PFC_PIN_GROUP(hscif0_data),
|
||||||
SH_PFC_PIN_GROUP(hscif0_clk),
|
SH_PFC_PIN_GROUP(hscif0_clk),
|
||||||
SH_PFC_PIN_GROUP(hscif0_ctrl),
|
SH_PFC_PIN_GROUP(hscif0_ctrl),
|
||||||
|
@ -3629,6 +3876,48 @@ static const char * const canfd1_groups[] = {
|
||||||
"canfd1_data",
|
"canfd1_data",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char * const drif0_groups[] = {
|
||||||
|
"drif0_ctrl_a",
|
||||||
|
"drif0_data0_a",
|
||||||
|
"drif0_data1_a",
|
||||||
|
"drif0_ctrl_b",
|
||||||
|
"drif0_data0_b",
|
||||||
|
"drif0_data1_b",
|
||||||
|
"drif0_ctrl_c",
|
||||||
|
"drif0_data0_c",
|
||||||
|
"drif0_data1_c",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const drif1_groups[] = {
|
||||||
|
"drif1_ctrl_a",
|
||||||
|
"drif1_data0_a",
|
||||||
|
"drif1_data1_a",
|
||||||
|
"drif1_ctrl_b",
|
||||||
|
"drif1_data0_b",
|
||||||
|
"drif1_data1_b",
|
||||||
|
"drif1_ctrl_c",
|
||||||
|
"drif1_data0_c",
|
||||||
|
"drif1_data1_c",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const drif2_groups[] = {
|
||||||
|
"drif2_ctrl_a",
|
||||||
|
"drif2_data0_a",
|
||||||
|
"drif2_data1_a",
|
||||||
|
"drif2_ctrl_b",
|
||||||
|
"drif2_data0_b",
|
||||||
|
"drif2_data1_b",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const drif3_groups[] = {
|
||||||
|
"drif3_ctrl_a",
|
||||||
|
"drif3_data0_a",
|
||||||
|
"drif3_data1_a",
|
||||||
|
"drif3_ctrl_b",
|
||||||
|
"drif3_data0_b",
|
||||||
|
"drif3_data1_b",
|
||||||
|
};
|
||||||
|
|
||||||
static const char * const hscif0_groups[] = {
|
static const char * const hscif0_groups[] = {
|
||||||
"hscif0_data",
|
"hscif0_data",
|
||||||
"hscif0_clk",
|
"hscif0_clk",
|
||||||
|
@ -3972,6 +4261,10 @@ static const struct sh_pfc_function pinmux_functions[] = {
|
||||||
SH_PFC_FUNCTION(can_clk),
|
SH_PFC_FUNCTION(can_clk),
|
||||||
SH_PFC_FUNCTION(canfd0),
|
SH_PFC_FUNCTION(canfd0),
|
||||||
SH_PFC_FUNCTION(canfd1),
|
SH_PFC_FUNCTION(canfd1),
|
||||||
|
SH_PFC_FUNCTION(drif0),
|
||||||
|
SH_PFC_FUNCTION(drif1),
|
||||||
|
SH_PFC_FUNCTION(drif2),
|
||||||
|
SH_PFC_FUNCTION(drif3),
|
||||||
SH_PFC_FUNCTION(hscif0),
|
SH_PFC_FUNCTION(hscif0),
|
||||||
SH_PFC_FUNCTION(hscif1),
|
SH_PFC_FUNCTION(hscif1),
|
||||||
SH_PFC_FUNCTION(hscif2),
|
SH_PFC_FUNCTION(hscif2),
|
||||||
|
@ -4765,8 +5058,28 @@ static const struct pinmux_drive_reg pinmux_drive_regs[] = {
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int r8a7795_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl)
|
||||||
|
{
|
||||||
|
int bit = -EINVAL;
|
||||||
|
|
||||||
|
*pocctrl = 0xe6060380;
|
||||||
|
|
||||||
|
if (pin >= RCAR_GP_PIN(3, 0) && pin <= RCAR_GP_PIN(3, 11))
|
||||||
|
bit = pin & 0x1f;
|
||||||
|
|
||||||
|
if (pin >= RCAR_GP_PIN(4, 0) && pin <= RCAR_GP_PIN(4, 17))
|
||||||
|
bit = (pin & 0x1f) + 12;
|
||||||
|
|
||||||
|
return bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct sh_pfc_soc_operations r8a7795_pinmux_ops = {
|
||||||
|
.pin_to_pocctrl = r8a7795_pin_to_pocctrl,
|
||||||
|
};
|
||||||
|
|
||||||
const struct sh_pfc_soc_info r8a7795_pinmux_info = {
|
const struct sh_pfc_soc_info r8a7795_pinmux_info = {
|
||||||
.name = "r8a77950_pfc",
|
.name = "r8a77950_pfc",
|
||||||
|
.ops = &r8a7795_pinmux_ops,
|
||||||
.unlock_reg = 0xe6060000, /* PMMR */
|
.unlock_reg = 0xe6060000, /* PMMR */
|
||||||
|
|
||||||
.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
|
.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
|
||||||
|
|
|
@ -1625,7 +1625,6 @@ static const struct pinmux_func pinmux_func_gpios[] = {
|
||||||
GPIO_FN(VBIOS_CS),
|
GPIO_FN(VBIOS_CS),
|
||||||
|
|
||||||
/* PTW (mobule: LBSC, EVC, SCIF) */
|
/* PTW (mobule: LBSC, EVC, SCIF) */
|
||||||
GPIO_FN(A16),
|
|
||||||
GPIO_FN(A15),
|
GPIO_FN(A15),
|
||||||
GPIO_FN(A14),
|
GPIO_FN(A14),
|
||||||
GPIO_FN(A13),
|
GPIO_FN(A13),
|
||||||
|
|
|
@ -632,19 +632,21 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin,
|
||||||
}
|
}
|
||||||
|
|
||||||
case PIN_CONFIG_POWER_SOURCE: {
|
case PIN_CONFIG_POWER_SOURCE: {
|
||||||
int ret;
|
u32 pocctrl, val;
|
||||||
|
int bit;
|
||||||
|
|
||||||
if (!pfc->info->ops || !pfc->info->ops->get_io_voltage)
|
if (!pfc->info->ops || !pfc->info->ops->pin_to_pocctrl)
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
|
|
||||||
|
bit = pfc->info->ops->pin_to_pocctrl(pfc, _pin, &pocctrl);
|
||||||
|
if (WARN(bit < 0, "invalid pin %#x", _pin))
|
||||||
|
return bit;
|
||||||
|
|
||||||
spin_lock_irqsave(&pfc->lock, flags);
|
spin_lock_irqsave(&pfc->lock, flags);
|
||||||
ret = pfc->info->ops->get_io_voltage(pfc, _pin);
|
val = sh_pfc_read_reg(pfc, pocctrl, 32);
|
||||||
spin_unlock_irqrestore(&pfc->lock, flags);
|
spin_unlock_irqrestore(&pfc->lock, flags);
|
||||||
|
|
||||||
if (ret < 0)
|
*config = (val & BIT(bit)) ? 3300 : 1800;
|
||||||
return ret;
|
|
||||||
|
|
||||||
*config = ret;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,19 +698,28 @@ static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin,
|
||||||
}
|
}
|
||||||
|
|
||||||
case PIN_CONFIG_POWER_SOURCE: {
|
case PIN_CONFIG_POWER_SOURCE: {
|
||||||
unsigned int arg =
|
unsigned int mV = pinconf_to_config_argument(configs[i]);
|
||||||
pinconf_to_config_argument(configs[i]);
|
u32 pocctrl, val;
|
||||||
int ret;
|
int bit;
|
||||||
|
|
||||||
if (!pfc->info->ops || !pfc->info->ops->set_io_voltage)
|
if (!pfc->info->ops || !pfc->info->ops->pin_to_pocctrl)
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
|
|
||||||
spin_lock_irqsave(&pfc->lock, flags);
|
bit = pfc->info->ops->pin_to_pocctrl(pfc, _pin, &pocctrl);
|
||||||
ret = pfc->info->ops->set_io_voltage(pfc, _pin, arg);
|
if (WARN(bit < 0, "invalid pin %#x", _pin))
|
||||||
spin_unlock_irqrestore(&pfc->lock, flags);
|
return bit;
|
||||||
|
|
||||||
if (ret)
|
if (mV != 1800 && mV != 3300)
|
||||||
return ret;
|
return -EINVAL;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&pfc->lock, flags);
|
||||||
|
val = sh_pfc_read_reg(pfc, pocctrl, 32);
|
||||||
|
if (mV == 3300)
|
||||||
|
val |= BIT(bit);
|
||||||
|
else
|
||||||
|
val &= ~BIT(bit);
|
||||||
|
sh_pfc_write_reg(pfc, pocctrl, 32, val);
|
||||||
|
spin_unlock_irqrestore(&pfc->lock, flags);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -803,8 +814,5 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc)
|
||||||
pmx->pctl_desc.npins = pfc->info->nr_pins;
|
pmx->pctl_desc.npins = pfc->info->nr_pins;
|
||||||
|
|
||||||
pmx->pctl = devm_pinctrl_register(pfc->dev, &pmx->pctl_desc, pmx);
|
pmx->pctl = devm_pinctrl_register(pfc->dev, &pmx->pctl_desc, pmx);
|
||||||
if (IS_ERR(pmx->pctl))
|
return PTR_ERR_OR_ZERO(pmx->pctl);
|
||||||
return PTR_ERR(pmx->pctl);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include <linux/bug.h>
|
#include <linux/bug.h>
|
||||||
#include <linux/pinctrl/pinconf-generic.h>
|
#include <linux/pinctrl/pinconf-generic.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
#include <linux/stringify.h>
|
#include <linux/stringify.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -182,16 +183,38 @@ struct pinmux_range {
|
||||||
u16 force;
|
u16 force;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sh_pfc;
|
struct sh_pfc_window {
|
||||||
|
phys_addr_t phys;
|
||||||
|
void __iomem *virt;
|
||||||
|
unsigned long size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sh_pfc_pin_range;
|
||||||
|
|
||||||
|
struct sh_pfc {
|
||||||
|
struct device *dev;
|
||||||
|
const struct sh_pfc_soc_info *info;
|
||||||
|
spinlock_t lock;
|
||||||
|
|
||||||
|
unsigned int num_windows;
|
||||||
|
struct sh_pfc_window *windows;
|
||||||
|
unsigned int num_irqs;
|
||||||
|
unsigned int *irqs;
|
||||||
|
|
||||||
|
struct sh_pfc_pin_range *ranges;
|
||||||
|
unsigned int nr_ranges;
|
||||||
|
|
||||||
|
unsigned int nr_gpio_pins;
|
||||||
|
|
||||||
|
struct sh_pfc_chip *gpio;
|
||||||
|
};
|
||||||
|
|
||||||
struct sh_pfc_soc_operations {
|
struct sh_pfc_soc_operations {
|
||||||
int (*init)(struct sh_pfc *pfc);
|
int (*init)(struct sh_pfc *pfc);
|
||||||
unsigned int (*get_bias)(struct sh_pfc *pfc, unsigned int pin);
|
unsigned int (*get_bias)(struct sh_pfc *pfc, unsigned int pin);
|
||||||
void (*set_bias)(struct sh_pfc *pfc, unsigned int pin,
|
void (*set_bias)(struct sh_pfc *pfc, unsigned int pin,
|
||||||
unsigned int bias);
|
unsigned int bias);
|
||||||
int (*get_io_voltage)(struct sh_pfc *pfc, unsigned int pin);
|
int (*pin_to_pocctrl)(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl);
|
||||||
int (*set_io_voltage)(struct sh_pfc *pfc, unsigned int pin,
|
|
||||||
u16 voltage_mV);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sh_pfc_soc_info {
|
struct sh_pfc_soc_info {
|
||||||
|
@ -227,6 +250,30 @@ struct sh_pfc_soc_info {
|
||||||
u32 unlock_reg;
|
u32 unlock_reg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern const struct sh_pfc_soc_info emev2_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info r8a73a4_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info r8a7740_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info r8a7778_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info r8a7779_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info r8a7790_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info r8a7791_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info r8a7793_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info r8a7794_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info r8a7795_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info sh7203_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info sh7264_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info sh7269_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info sh73a0_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info sh7720_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info sh7722_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info sh7723_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info sh7724_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info sh7734_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info sh7757_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info sh7785_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info sh7786_pinmux_info;
|
||||||
|
extern const struct sh_pfc_soc_info shx3_pinmux_info;
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Helper macros to create pin and port lists
|
* Helper macros to create pin and port lists
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -5424,8 +5424,10 @@ static int atlas7_pinmux_probe(struct platform_device *pdev)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
pmx->sys2pci_base = devm_ioremap_resource(&pdev->dev, &res);
|
pmx->sys2pci_base = devm_ioremap_resource(&pdev->dev, &res);
|
||||||
if (IS_ERR(pmx->sys2pci_base))
|
if (IS_ERR(pmx->sys2pci_base)) {
|
||||||
|
of_node_put(sys2pci_np);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
pmx->dev = &pdev->dev;
|
pmx->dev = &pdev->dev;
|
||||||
|
|
||||||
|
|
|
@ -13,4 +13,10 @@ config PINCTRL_STM32F429
|
||||||
default MACH_STM32F429
|
default MACH_STM32F429
|
||||||
select PINCTRL_STM32
|
select PINCTRL_STM32
|
||||||
|
|
||||||
|
config PINCTRL_STM32F746
|
||||||
|
bool "STMicroelectronics STM32F746 pin control" if COMPILE_TEST && !MACH_STM32F746
|
||||||
|
depends on OF
|
||||||
|
default MACH_STM32F746
|
||||||
|
select PINCTRL_STM32
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -3,3 +3,4 @@ obj-$(CONFIG_PINCTRL_STM32) += pinctrl-stm32.o
|
||||||
|
|
||||||
# SoC Drivers
|
# SoC Drivers
|
||||||
obj-$(CONFIG_PINCTRL_STM32F429) += pinctrl-stm32f429.o
|
obj-$(CONFIG_PINCTRL_STM32F429) += pinctrl-stm32f429.o
|
||||||
|
obj-$(CONFIG_PINCTRL_STM32F746) += pinctrl-stm32f746.o
|
||||||
|
|
|
@ -638,8 +638,8 @@ static u32 stm32_pconf_get_bias(struct stm32_gpio_bank *bank,
|
||||||
return (val >> (offset * 2));
|
return (val >> (offset * 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool stm32_pconf_input_get(struct stm32_gpio_bank *bank,
|
static bool stm32_pconf_get(struct stm32_gpio_bank *bank,
|
||||||
unsigned int offset)
|
unsigned int offset, bool dir)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 val;
|
u32 val;
|
||||||
|
@ -647,23 +647,12 @@ static bool stm32_pconf_input_get(struct stm32_gpio_bank *bank,
|
||||||
clk_enable(bank->clk);
|
clk_enable(bank->clk);
|
||||||
spin_lock_irqsave(&bank->lock, flags);
|
spin_lock_irqsave(&bank->lock, flags);
|
||||||
|
|
||||||
val = !!(readl_relaxed(bank->base + STM32_GPIO_IDR) & BIT(offset));
|
if (dir)
|
||||||
|
val = !!(readl_relaxed(bank->base + STM32_GPIO_IDR) &
|
||||||
spin_unlock_irqrestore(&bank->lock, flags);
|
BIT(offset));
|
||||||
clk_disable(bank->clk);
|
else
|
||||||
|
val = !!(readl_relaxed(bank->base + STM32_GPIO_ODR) &
|
||||||
return val;
|
BIT(offset));
|
||||||
}
|
|
||||||
|
|
||||||
static bool stm32_pconf_output_get(struct stm32_gpio_bank *bank,
|
|
||||||
unsigned int offset)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
clk_enable(bank->clk);
|
|
||||||
spin_lock_irqsave(&bank->lock, flags);
|
|
||||||
val = !!(readl_relaxed(bank->base + STM32_GPIO_ODR) & BIT(offset));
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bank->lock, flags);
|
spin_unlock_irqrestore(&bank->lock, flags);
|
||||||
clk_disable(bank->clk);
|
clk_disable(bank->clk);
|
||||||
|
@ -772,7 +761,7 @@ static void stm32_pconf_dbg_show(struct pinctrl_dev *pctldev,
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
/* input */
|
/* input */
|
||||||
case 0:
|
case 0:
|
||||||
val = stm32_pconf_input_get(bank, offset);
|
val = stm32_pconf_get(bank, offset, true);
|
||||||
seq_printf(s, "- %s - %s",
|
seq_printf(s, "- %s - %s",
|
||||||
val ? "high" : "low",
|
val ? "high" : "low",
|
||||||
biasing[bias]);
|
biasing[bias]);
|
||||||
|
@ -782,7 +771,7 @@ static void stm32_pconf_dbg_show(struct pinctrl_dev *pctldev,
|
||||||
case 1:
|
case 1:
|
||||||
drive = stm32_pconf_get_driving(bank, offset);
|
drive = stm32_pconf_get_driving(bank, offset);
|
||||||
speed = stm32_pconf_get_speed(bank, offset);
|
speed = stm32_pconf_get_speed(bank, offset);
|
||||||
val = stm32_pconf_output_get(bank, offset);
|
val = stm32_pconf_get(bank, offset, false);
|
||||||
seq_printf(s, "- %s - %s - %s - %s %s",
|
seq_printf(s, "- %s - %s - %s - %s %s",
|
||||||
val ? "high" : "low",
|
val ? "high" : "low",
|
||||||
drive ? "open drain" : "push pull",
|
drive ? "open drain" : "push pull",
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -180,17 +180,17 @@ static const struct sunxi_desc_pin sun8i_a23_pins[] = {
|
||||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
|
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
|
||||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||||
SUNXI_FUNCTION(0x2, "nand"), /* DQ6 */
|
SUNXI_FUNCTION(0x2, "nand0"), /* DQ6 */
|
||||||
SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */
|
SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */
|
||||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
|
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
|
||||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||||
SUNXI_FUNCTION(0x2, "nand"), /* DQ7 */
|
SUNXI_FUNCTION(0x2, "nand0"), /* DQ7 */
|
||||||
SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */
|
SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */
|
||||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
|
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
|
||||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||||
SUNXI_FUNCTION(0x2, "nand"), /* DQS */
|
SUNXI_FUNCTION(0x2, "nand0"), /* DQS */
|
||||||
SUNXI_FUNCTION(0x3, "mmc2")), /* RST */
|
SUNXI_FUNCTION(0x3, "mmc2")), /* RST */
|
||||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 17),
|
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 17),
|
||||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||||
|
|
|
@ -140,17 +140,17 @@ static const struct sunxi_desc_pin sun8i_a33_pins[] = {
|
||||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
|
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
|
||||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||||
SUNXI_FUNCTION(0x2, "nand"), /* DQ6 */
|
SUNXI_FUNCTION(0x2, "nand0"), /* DQ6 */
|
||||||
SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */
|
SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */
|
||||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
|
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
|
||||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||||
SUNXI_FUNCTION(0x2, "nand"), /* DQ7 */
|
SUNXI_FUNCTION(0x2, "nand0"), /* DQ7 */
|
||||||
SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */
|
SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */
|
||||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
|
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
|
||||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||||
SUNXI_FUNCTION(0x2, "nand"), /* DQS */
|
SUNXI_FUNCTION(0x2, "nand0"), /* DQS */
|
||||||
SUNXI_FUNCTION(0x3, "mmc2")), /* RST */
|
SUNXI_FUNCTION(0x3, "mmc2")), /* RST */
|
||||||
/* Hole */
|
/* Hole */
|
||||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2),
|
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2),
|
||||||
|
|
|
@ -219,17 +219,17 @@ static const struct sunxi_desc_pin sun8i_h3_pins[] = {
|
||||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
|
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
|
||||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||||
SUNXI_FUNCTION(0x2, "nand"), /* DQ6 */
|
SUNXI_FUNCTION(0x2, "nand0"), /* DQ6 */
|
||||||
SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */
|
SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */
|
||||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
|
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
|
||||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||||
SUNXI_FUNCTION(0x2, "nand"), /* DQ7 */
|
SUNXI_FUNCTION(0x2, "nand0"), /* DQ7 */
|
||||||
SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */
|
SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */
|
||||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
|
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
|
||||||
SUNXI_FUNCTION(0x0, "gpio_in"),
|
SUNXI_FUNCTION(0x0, "gpio_in"),
|
||||||
SUNXI_FUNCTION(0x1, "gpio_out"),
|
SUNXI_FUNCTION(0x1, "gpio_out"),
|
||||||
SUNXI_FUNCTION(0x2, "nand"), /* DQS */
|
SUNXI_FUNCTION(0x2, "nand0"), /* DQS */
|
||||||
SUNXI_FUNCTION(0x3, "mmc2")), /* RST */
|
SUNXI_FUNCTION(0x3, "mmc2")), /* RST */
|
||||||
/* Hole */
|
/* Hole */
|
||||||
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 0),
|
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 0),
|
||||||
|
|
|
@ -632,11 +632,11 @@ static void tegra_pinctrl_clear_parked_bits(struct tegra_pmx *pmx)
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
for (i = 0; i < pmx->soc->ngroups; ++i) {
|
for (i = 0; i < pmx->soc->ngroups; ++i) {
|
||||||
if (pmx->soc->groups[i].parked_reg >= 0) {
|
g = &pmx->soc->groups[i];
|
||||||
g = &pmx->soc->groups[i];
|
if (g->parked_bit >= 0) {
|
||||||
val = pmx_readl(pmx, g->parked_bank, g->parked_reg);
|
val = pmx_readl(pmx, g->mux_bank, g->mux_reg);
|
||||||
val &= ~(1 << g->parked_bit);
|
val &= ~(1 << g->parked_bit);
|
||||||
pmx_writel(pmx, val, g->parked_bank, g->parked_reg);
|
pmx_writel(pmx, val, g->mux_bank, g->mux_reg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,9 +93,7 @@ struct tegra_function {
|
||||||
* @tri_reg: Tri-state register offset.
|
* @tri_reg: Tri-state register offset.
|
||||||
* @tri_bank: Tri-state register bank.
|
* @tri_bank: Tri-state register bank.
|
||||||
* @tri_bit: Tri-state register bit.
|
* @tri_bit: Tri-state register bit.
|
||||||
* @parked_reg: Parked register offset. -1 if unsupported.
|
* @parked_bit: Parked register bit. -1 if unsupported.
|
||||||
* @parked_bank: Parked register bank. 0 if unsupported.
|
|
||||||
* @parked_bit: Parked register bit. 0 if unsupported.
|
|
||||||
* @einput_bit: Enable-input register bit.
|
* @einput_bit: Enable-input register bit.
|
||||||
* @odrain_bit: Open-drain register bit.
|
* @odrain_bit: Open-drain register bit.
|
||||||
* @lock_bit: Lock register bit.
|
* @lock_bit: Lock register bit.
|
||||||
|
@ -138,12 +136,10 @@ struct tegra_pingroup {
|
||||||
s16 pupd_reg;
|
s16 pupd_reg;
|
||||||
s16 tri_reg;
|
s16 tri_reg;
|
||||||
s16 drv_reg;
|
s16 drv_reg;
|
||||||
s16 parked_reg;
|
|
||||||
u32 mux_bank:2;
|
u32 mux_bank:2;
|
||||||
u32 pupd_bank:2;
|
u32 pupd_bank:2;
|
||||||
u32 tri_bank:2;
|
u32 tri_bank:2;
|
||||||
u32 drv_bank:2;
|
u32 drv_bank:2;
|
||||||
u32 parked_bank:2;
|
|
||||||
s32 mux_bit:6;
|
s32 mux_bit:6;
|
||||||
s32 pupd_bit:6;
|
s32 pupd_bit:6;
|
||||||
s32 tri_bit:6;
|
s32 tri_bit:6;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue