提交 5a1bcbd9 编写于 作者: L Linus Torvalds

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

Pull pin control updates from Linus Walleij:
 "The most interesting aspect is that we now have initial support for
  the Apple pin controller as used in the M1 laptops and the iPhones
  which is a step forward for using Linux efficiently on this Apple
  silicon.

  Core changes:

   - Add infrastructure for per-parent interrupt data to support the
     Apple pin controller.

  New drivers:

   - New combined pin control and GPIO driver for the Apple SoC. This is
     used in all modern Apple silicon such as the M1 laptops but also in
     at least recent iPhone variants.

   - New subdriver for the Qualcomm SM6350

   - New subdriver for the Qualcomm QCM2290

   - New subdriver for the Qualcomm PM6350

   - New subdriver for the Uniphier NX1

   - New subdriver for the Samsung ExynosAutoV9

   - New subdriver for the Mediatek MT7986

   - New subdriver for the nVidia Tegra194

  Improvements:

   - Improve power management in the Mediatek driver.

   - Improvements to the Renesas internal consistency checker.

   - Convert the Rockchip pin control device tree bindings to YAML.

   - Finally convert the Qualcomm PMIC SSBI and SPMI MPP GPIO driver to
     use hierarchical interrupts.

   - Convert the Qualcomm PMIC MPP device tree bindings to YAML"

* tag 'pinctrl-v5.16-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (55 commits)
  pinctrl: add pinctrl/GPIO driver for Apple SoCs
  dt-bindings: pinctrl: Add apple,npins property to apple,pinctrl
  dt-bindings: pinctrl: add #interrupt-cells to apple,pinctrl
  gpio: Allow per-parent interrupt data
  pinctrl: tegra: Fix warnings and error
  pinctrl: intel: Kconfig: Add configuration menu to Intel pin control
  pinctrl: tegra: Use correct offset for pin group
  pinctrl: core: fix possible memory leak in pinctrl_enable()
  pinctrl: bcm2835: Allow building driver as a module
  pinctrl: equilibrium: Fix function addition in multiple groups
  pinctrl: tegra: Add pinmux support for Tegra194
  pinctrl: tegra: include lpdr pin properties
  pinctrl: mediatek: add support for MT7986 SoC
  dt-bindings: pinctrl: update bindings for MT7986 SoC
  pinctrl: microchip sgpio: use reset driver
  dt-bindings: pinctrl: pinctrl-microchip-sgpio: Add reset binding
  dt-bindings: pinctrl: qcom,pmic-mpp: switch to #interrupt-cells
  pinctrl: qcom: spmi-mpp: add support for hierarchical IRQ chip
  pinctrl: qcom: spmi-mpp: hardcode IRQ counts
  pinctrl: qcom: ssbi-mpp: add support for hierarchical IRQ chip
  ...
......@@ -34,6 +34,10 @@ properties:
gpio-ranges:
maxItems: 1
apple,npins:
$ref: /schemas/types.yaml#/definitions/uint32
description: The number of pins in this GPIO controller.
interrupts:
description: One interrupt for each of the (up to 7) interrupt
groups supported by the controller sorted by interrupt group
......@@ -43,6 +47,9 @@ properties:
interrupt-controller: true
'#interrupt-cells':
const: 2
patternProperties:
'-pins$':
type: object
......@@ -66,6 +73,7 @@ required:
- gpio-controller
- '#gpio-cells'
- gpio-ranges
- apple,npins
additionalProperties: false
......@@ -86,8 +94,10 @@ examples:
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pinctrl 0 0 212>;
apple,npins = <212>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&aic>;
interrupts = <AIC_IRQ 16 IRQ_TYPE_LEVEL_HIGH>,
<AIC_IRQ 17 IRQ_TYPE_LEVEL_HIGH>,
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/mediatek,mt7986-pinctrl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mediatek MT7986 Pin Controller Device Tree Bindings
maintainers:
- Sean Wang <sean.wang@kernel.org>
description: |+
The MediaTek's MT7986 Pin controller is used to control SoC pins.
properties:
compatible:
enum:
- mediatek,mt7986a-pinctrl
- mediatek,mt7986b-pinctrl
reg:
minItems: 8
maxItems: 8
reg-names:
items:
- const: gpio
- const: iocfg_rt
- const: iocfg_rb
- const: iocfg_lt
- const: iocfg_lb
- const: iocfg_tr
- const: iocfg_tl
- const: eint
gpio-controller: true
"#gpio-cells":
const: 2
description: |
Number of cells in GPIO specifier. Since the generic GPIO
binding is used, the amount of cells must be specified as 2. See the below
mentioned gpio binding representation for description of particular cells.
gpio-ranges:
minItems: 1
maxItems: 5
description: |
GPIO valid number range.
interrupt-controller: true
interrupts:
maxItems: 1
"#interrupt-cells":
const: 2
required:
- compatible
- reg
- reg-names
- gpio-controller
- "#gpio-cells"
patternProperties:
'-pins$':
type: object
additionalProperties: false
patternProperties:
'.*mux.*':
type: object
additionalProperties: false
description: |
pinmux configuration nodes.
The following table shows the effective values of "group", "function"
properties and chip pinout pins
groups function pins (in pin#)
---------------------------------------------------------------------
"watchdog" "watchdog" 0
"wifi_led" "led" 1, 2
"i2c" "i2c" 3, 4
"uart1_0" "uart" 7, 8, 9, 10
"pcie_clk" "pcie" 9
"pcie_wake" "pcie" 10
"spi1_0" "spi" 11, 12, 13, 14
"pwm1_1" "pwm" 20,
"pwm0" "pwm" 21,
"pwm1_0" "pwm" 22,
"snfi" "flash" 23, 24, 25, 26, 27, 28
"spi1_2" "spi" 29, 30, 31, 32
"emmc_45" "emmc" 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32
"spi1_1" "spi" 23, 24, 25, 26
"uart1_2" "uart" 29, 30, 31, 32
"uart1_1" "uart" 23, 24, 25, 26
"uart2_0" "uart" 29, 30, 31, 32
"spi0" "spi" 33, 34, 35, 36
"spi0_wp_hold" "spi" 37, 38
"uart1_3_rx_tx" "uart" 35, 36
"uart1_3_cts_rts" "uart" 37, 38
"uart2_1" "uart" 33, 34, 35, 36
"spi1_3" "spi" 33, 34, 35, 36
"uart0" "uart" 39, 40
"pcie_pereset" "pcie" 41
"uart1" "uart" 42, 43, 44, 45
"uart2" "uart" 46, 47, 48, 49
"emmc_51" "emmc" 50, 51, 52, 53, 54, 55, 56, 57, 57,
59, 60, 61
"pcm" "audio" 62, 63, 64, 65
"i2s" "audio" 62, 63, 64, 65
"switch_int" "eth" 66
"mdc_mdio" "eth" 67
$ref: "/schemas/pinctrl/pinmux-node.yaml"
properties:
function:
description: |
A string containing the name of the function to mux to the group.
There is no "audio", "pcie" functions on mt7986b, you can only use
those functions on mt7986a.
enum: [audio, emmc, eth, i2c, led, flash, pcie, pwm, spi, uart,
watchdog, wifi]
groups:
description: |
An array of strings. Each string contains the name of a group.
There is no "pcie_pereset", "uart1", "uart2" "emmc_51", "pcm",
and "i2s" groups on mt7986b, you can only use those groups on
mt7986a.
required:
- function
- groups
allOf:
- if:
properties:
function:
const: audio
then:
properties:
groups:
enum: [pcm, i2s]
- if:
properties:
function:
const: emmc
then:
properties:
groups:
enum: [emmc, emmc_rst]
- if:
properties:
function:
const: eth
then:
properties:
groups:
enum: [switch_int, mdc_mdio]
- if:
properties:
function:
const: i2c
then:
properties:
groups:
enum: [i2c]
- if:
properties:
function:
const: led
then:
properties:
groups:
enum: [wifi_led]
- if:
properties:
function:
const: flash
then:
properties:
groups:
enum: [snfi]
- if:
properties:
function:
const: pcie
then:
properties:
groups:
enum: [pcie_clk, pcie_wake, pcie_pereset]
- if:
properties:
function:
const: pwm
then:
properties:
groups:
enum: [pwm0, pwm1_0, pwm1_1]
- if:
properties:
function:
const: spi
then:
properties:
groups:
enum: [spi0, spi0_wp_hold, spi1_0, spi1_1, spi1_2, spi1_3]
- if:
properties:
function:
const: uart
then:
properties:
groups:
enum: [uart1_0, uart1_1, uart1_2, uart1_3_rx_tx,
uart1_3_cts_rts, uart2_0, uart2_1, uart0, uart1, uart2]
- if:
properties:
function:
const: watchdog
then:
properties:
groups:
enum: [watchdog]
- if:
properties:
function:
const: wifi
then:
properties:
groups:
enum: [wf_2g, wf_5g, wf_dbdc]
'.*conf.*':
type: object
additionalProperties: false
description: |
pinconf configuration nodes.
$ref: "/schemas/pinctrl/pincfg-node.yaml"
properties:
pins:
description: |
An array of strings. Each string contains the name of a pin.
There is no PIN 41 to PIN 65 above on mt7686b, you can only use
those pins on mt7986a.
enum: [SYS_WATCHDOG, WF2G_LED, WF5G_LED, I2C_SCL, I2C_SDA, GPIO_0,
GPIO_1, GPIO_2, GPIO_3, GPIO_4, GPIO_5, GPIO_6, GPIO_7,
GPIO_8, GPIO_9, GPIO_10, GPIO_11, GPIO_12, GPIO_13, GPIO_14,
GPIO_15, PWM0, PWM1, SPI0_CLK, SPI0_MOSI, SPI0_MISO, SPI0_CS,
SPI0_HOLD, SPI0_WP, SPI1_CLK, SPI1_MOSI, SPI1_MISO, SPI1_CS,
SPI2_CLK, SPI2_MOSI, SPI2_MISO, SPI2_CS, SPI2_HOLD, SPI2_WP,
UART0_RXD, UART0_TXD, PCIE_PERESET_N, UART1_RXD, UART1_TXD,
UART1_CTS, UART1_RTS, UART2_RXD, UART2_TXD, UART2_CTS,
UART2_RTS, EMMC_DATA_0, EMMC_DATA_1, EMMC_DATA_2,
EMMC_DATA_3, EMMC_DATA_4, EMMC_DATA_5, EMMC_DATA_6,
EMMC_DATA_7, EMMC_CMD, EMMC_CK, EMMC_DSL, EMMC_RSTB, PCM_DTX,
PCM_DRX, PCM_CLK, PCM_FS, MT7531_INT, SMI_MDC, SMI_MDIO,
WF0_DIG_RESETB, WF0_CBA_RESETB, WF0_XO_REQ, WF0_TOP_CLK,
WF0_TOP_DATA, WF0_HB1, WF0_HB2, WF0_HB3, WF0_HB4, WF0_HB0,
WF0_HB0_B, WF0_HB5, WF0_HB6, WF0_HB7, WF0_HB8, WF0_HB9,
WF0_HB10, WF1_DIG_RESETB, WF1_CBA_RESETB, WF1_XO_REQ,
WF1_TOP_CLK, WF1_TOP_DATA, WF1_HB1, WF1_HB2, WF1_HB3,
WF1_HB4, WF1_HB0, WF1_HB0_B, WF1_HB5, WF1_HB6, WF1_HB7,
WF1_HB8]
bias-disable: true
bias-pull-up: true
bias-pull-down: true
input-enable: true
input-disable: true
output-enable: true
output-low: true
output-high: true
input-schmitt-enable: true
input-schmitt-disable: true
drive-strength:
enum: [2, 4, 6, 8, 10, 12, 14, 16]
mediatek,pull-up-adv:
description: |
Valid arguments for 'mediatek,pull-up-adv' are '0', '1', '2', '3'
Pull up setings for 2 pull resistors, R0 and R1. Valid arguments
are described as below:
0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2, 3]
mediatek,pull-down-adv:
description: |
Valid arguments for 'mediatek,pull-up-adv' are '0', '1', '2', '3'
Pull down setings for 2 pull resistors, R0 and R1. Valid arguments
are described as below:
0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2, 3]
required:
- pins
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
soc {
#address-cells = <2>;
#size-cells = <2>;
pio: pinctrl@1001f000 {
compatible = "mediatek,mt7986a-pinctrl";
reg = <0 0x1001f000 0 0x1000>,
<0 0x11c30000 0 0x1000>,
<0 0x11c40000 0 0x1000>,
<0 0x11e20000 0 0x1000>,
<0 0x11e30000 0 0x1000>,
<0 0x11f00000 0 0x1000>,
<0 0x11f10000 0 0x1000>,
<0 0x1000b000 0 0x1000>;
reg-names = "gpio", "iocfg_rt", "iocfg_rb", "iocfg_lt",
"iocfg_lb", "iocfg_tr", "iocfg_tl", "eint";
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pio 0 0 100>;
interrupt-controller;
interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&gic>;
#interrupt-cells = <2>;
uart1_pins: uart1-pins {
mux {
function = "uart";
groups = "uart1";
};
};
uart2_pins: uart2-pins {
mux {
function = "uart";
groups = "uart2";
};
};
};
};
......@@ -68,6 +68,13 @@ properties:
clock, and larger than zero.
default: 12500000
resets:
maxItems: 1
reset-names:
items:
- const: switch
patternProperties:
"^gpio@[0-1]$":
type: object
......
......@@ -49,6 +49,12 @@ properties:
description: The interrupt outputs to sysirq.
maxItems: 1
mediatek,rsel_resistance_in_si_unit:
type: boolean
description: |
Identifying i2c pins pull up/down type which is RSEL. It can support
RSEL define or si unit value(ohm) to set different resistance.
#PIN CONFIGURATION NODES
patternProperties:
'-pins$':
......@@ -82,9 +88,85 @@ patternProperties:
drive-strength:
enum: [2, 4, 6, 8, 10, 12, 14, 16]
bias-pull-down: true
bias-pull-down:
description: |
For pull down type is normal, it don't need add RSEL & R1R0 define
and resistance value.
For pull down type is PUPD/R0/R1 type, it can add R1R0 define to
set different resistance. It can support "MTK_PUPD_SET_R1R0_00" &
"MTK_PUPD_SET_R1R0_01" & "MTK_PUPD_SET_R1R0_10" & "MTK_PUPD_SET_R1R0_11"
define in mt8195.
For pull down type is RSEL, it can add RSEL define & resistance value(ohm)
to set different resistance by identifying property "mediatek,rsel_resistance_in_si_unit".
It can support "MTK_PULL_SET_RSEL_000" & "MTK_PULL_SET_RSEL_001"
& "MTK_PULL_SET_RSEL_010" & "MTK_PULL_SET_RSEL_011" & "MTK_PULL_SET_RSEL_100"
& "MTK_PULL_SET_RSEL_101" & "MTK_PULL_SET_RSEL_110" & "MTK_PULL_SET_RSEL_111"
define in mt8195. It can also support resistance value(ohm) "75000" & "5000" in mt8195.
oneOf:
- enum: [100, 101, 102, 103]
- description: mt8195 pull down PUPD/R0/R1 type define value.
- enum: [200, 201, 202, 203, 204, 205, 206, 207]
- description: mt8195 pull down RSEL type define value.
- enum: [75000, 5000]
- description: mt8195 pull down RSEL type si unit value(ohm).
An example of using RSEL define:
pincontroller {
i2c0_pin {
pinmux = <PINMUX_GPIO8__FUNC_SDA0>;
bias-pull-down = <MTK_PULL_SET_RSEL_001>;
};
};
An example of using si unit resistance value(ohm):
&pio {
mediatek,rsel_resistance_in_si_unit;
}
pincontroller {
i2c0_pin {
pinmux = <PINMUX_GPIO8__FUNC_SDA0>;
bias-pull-down = <75000>;
};
};
bias-pull-up: true
bias-pull-up:
description: |
For pull up type is normal, it don't need add RSEL & R1R0 define
and resistance value.
For pull up type is PUPD/R0/R1 type, it can add R1R0 define to
set different resistance. It can support "MTK_PUPD_SET_R1R0_00" &
"MTK_PUPD_SET_R1R0_01" & "MTK_PUPD_SET_R1R0_10" & "MTK_PUPD_SET_R1R0_11"
define in mt8195.
For pull up type is RSEL, it can add RSEL define & resistance value(ohm)
to set different resistance by identifying property "mediatek,rsel_resistance_in_si_unit".
It can support "MTK_PULL_SET_RSEL_000" & "MTK_PULL_SET_RSEL_001"
& "MTK_PULL_SET_RSEL_010" & "MTK_PULL_SET_RSEL_011" & "MTK_PULL_SET_RSEL_100"
& "MTK_PULL_SET_RSEL_101" & "MTK_PULL_SET_RSEL_110" & "MTK_PULL_SET_RSEL_111"
define in mt8195. It can also support resistance value(ohm)
"1000" & "1500" & "2000" & "3000" & "4000" & "5000" & "10000" & "75000" in mt8195.
oneOf:
- enum: [100, 101, 102, 103]
- description: mt8195 pull up PUPD/R0/R1 type define value.
- enum: [200, 201, 202, 203, 204, 205, 206, 207]
- description: mt8195 pull up RSEL type define value.
- enum: [1000, 1500, 2000, 3000, 4000, 5000, 10000, 75000]
- description: mt8195 pull up RSEL type si unit value(ohm).
An example of using RSEL define:
pincontroller {
i2c0_pin {
pinmux = <PINMUX_GPIO8__FUNC_SDA0>;
bias-pull-up = <MTK_PULL_SET_RSEL_001>;
};
};
An example of using si unit resistance value(ohm):
&pio {
mediatek,rsel_resistance_in_si_unit;
}
pincontroller {
i2c0_pin {
pinmux = <PINMUX_GPIO8__FUNC_SDA0>;
bias-pull-up = <1000>;
};
};
bias-disable: true
......
......@@ -21,6 +21,7 @@ properties:
- qcom,pm660l-gpio
- qcom,pm6150-gpio
- qcom,pm6150l-gpio
- qcom,pm6350-gpio
- qcom,pm7325-gpio
- qcom,pm8005-gpio
- qcom,pm8008-gpio
......@@ -103,6 +104,7 @@ $defs:
this subnode. Valid pins are
- gpio1-gpio10 for pm6150
- gpio1-gpio12 for pm6150l
- gpio1-gpio9 for pm6350
- gpio1-gpio10 for pm7325
- gpio1-gpio4 for pm8005
- gpio1-gpio2 for pm8008
......@@ -170,6 +172,8 @@ $defs:
input-enable: true
output-high: true
output-low: true
output-enable: true
output-disable: true
power-source: true
qcom,drive-strength:
......
Qualcomm PMIC Multi-Purpose Pin (MPP) block
This binding describes the MPP block(s) found in the 8xxx series
of PMIC's from Qualcomm.
- compatible:
Usage: required
Value type: <string>
Definition: Should contain one of:
"qcom,pm8018-mpp",
"qcom,pm8019-mpp",
"qcom,pm8038-mpp",
"qcom,pm8058-mpp",
"qcom,pm8821-mpp",
"qcom,pm8841-mpp",
"qcom,pm8916-mpp",
"qcom,pm8917-mpp",
"qcom,pm8921-mpp",
"qcom,pm8941-mpp",
"qcom,pm8950-mpp",
"qcom,pmi8950-mpp",
"qcom,pm8994-mpp",
"qcom,pma8084-mpp",
"qcom,pmi8994-mpp",
And must contain either "qcom,spmi-mpp" or "qcom,ssbi-mpp"
if the device is on an spmi bus or an ssbi bus respectively.
- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: Register base of the MPP block and length.
- interrupts:
Usage: required
Value type: <prop-encoded-array>
Definition: Must contain an array of encoded interrupt specifiers for
each available MPP
- gpio-controller:
Usage: required
Value type: <none>
Definition: Mark the device node as a GPIO controller
- #gpio-cells:
Usage: required
Value type: <u32>
Definition: Must be 2;
the first cell will be used to define MPP number and the
second denotes the flags for this MPP
Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
a general description of GPIO and interrupt bindings.
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices, including the meaning of the
phrase "pin configuration node".
The pin configuration nodes act as a container for an arbitrary number of
subnodes. Each of these subnodes represents some desired configuration for a
pin or a list of pins. This configuration can include the
mux function to select on those pin(s), and various pin configuration
parameters, as listed below.
SUBNODES:
The name of each subnode is not important; all subnodes should be enumerated
and processed purely based on their content.
Each subnode only affects those parameters that are explicitly listed. In
other words, a subnode that lists a mux function but no pin configuration
parameters implies no information about any pin configuration parameters.
Similarly, a pin subnode that describes a pullup parameter implies no
information about e.g. the mux function.
The following generic properties as defined in pinctrl-bindings.txt are valid
to specify in a pin configuration subnode:
- pins:
Usage: required
Value type: <string-array>
Definition: List of MPP pins affected by the properties specified in
this subnode. Valid pins are:
mpp1-mpp4 for pm8841
mpp1-mpp4 for pm8916
mpp1-mpp8 for pm8941
mpp1-mpp4 for pm8950
mpp1-mpp4 for pmi8950
mpp1-mpp4 for pma8084
- function:
Usage: required
Value type: <string>
Definition: Specify the alternative function to be configured for the
specified pins. Valid values are:
"digital",
"analog",
"sink"
- bias-disable:
Usage: optional
Value type: <none>
Definition: The specified pins should be configured as no pull.
- bias-pull-up:
Usage: optional
Value type: <u32>
Definition: The specified pins should be configured as pull up.
Valid values are 600, 10000 and 30000 in bidirectional mode
only, i.e. when operating in qcom,analog-mode and input and
outputs are enabled. The hardware ignores the configuration
when operating in other modes.
- bias-high-impedance:
Usage: optional
Value type: <none>
Definition: The specified pins will put in high-Z mode and disabled.
- input-enable:
Usage: optional
Value type: <none>
Definition: The specified pins are put in input mode, i.e. their input
buffer is enabled
- output-high:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
high.
- output-low:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
low.
- power-source:
Usage: optional
Value type: <u32>
Definition: Selects the power source for the specified pins. Valid power
sources are defined in <dt-bindings/pinctrl/qcom,pmic-mpp.h>
- qcom,analog-level:
Usage: optional
Value type: <u32>
Definition: Selects the source for analog output. Valued values are
defined in <dt-binding/pinctrl/qcom,pmic-mpp.h>
PMIC_MPP_AOUT_LVL_*
- qcom,dtest:
Usage: optional
Value type: <u32>
Definition: Selects which dtest rail to be routed in the various functions.
Valid values are 1-4
- qcom,amux-route:
Usage: optional
Value type: <u32>
Definition: Selects the source for analog input. Valid values are
defined in <dt-bindings/pinctrl/qcom,pmic-mpp.h>
PMIC_MPP_AMUX_ROUTE_CH5, PMIC_MPP_AMUX_ROUTE_CH6...
- qcom,paired:
Usage: optional
Value type: <none>
Definition: Indicates that the pin should be operating in paired mode.
Example:
mpps@a000 {
compatible = "qcom,pm8841-mpp", "qcom,spmi-mpp";
reg = <0xa000>;
gpio-controller;
#gpio-cells = <2>;
interrupts = <4 0xa0 0 0>, <4 0xa1 0 0>, <4 0xa2 0 0>, <4 0xa3 0 0>;
pinctrl-names = "default";
pinctrl-0 = <&pm8841_default>;
pm8841_default: default {
gpio {
pins = "mpp1", "mpp2", "mpp3", "mpp4";
function = "digital";
input-enable;
power-source = <PM8841_MPP_S3>;
};
};
};
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/qcom,pmic-mpp.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm PMIC Multi-Purpose Pin (MPP) block
maintainers:
- Bjorn Andersson <bjorn.andersson@linaro.org>
description:
This binding describes the MPP block(s) found in the 8xxx series of
PMIC's from Qualcomm.
properties:
compatible:
items:
- enum:
- qcom,pm8018-mpp
- qcom,pm8019-mpp
- qcom,pm8038-mpp
- qcom,pm8058-mpp
- qcom,pm8821-mpp
- qcom,pm8841-mpp
- qcom,pm8916-mpp
- qcom,pm8917-mpp
- qcom,pm8921-mpp
- qcom,pm8941-mpp
- qcom,pm8950-mpp
- qcom,pmi8950-mpp
- qcom,pm8994-mpp
- qcom,pma8084-mpp
- qcom,pmi8994-mpp
- enum:
- qcom,spmi-mpp
- qcom,ssbi-mpp
reg:
maxItems: 1
interrupt-controller: true
'#interrupt-cells':
const: 2
gpio-controller: true
gpio-line-names: true
gpio-ranges:
maxItems: 1
'#gpio-cells':
const: 2
description:
The first cell will be used to define gpio number and the
second denotes the flags for this gpio
additionalProperties: false
required:
- compatible
- reg
- gpio-controller
- '#gpio-cells'
- gpio-ranges
- interrupt-controller
patternProperties:
'-state$':
oneOf:
- $ref: "#/$defs/qcom-pmic-mpp-state"
- patternProperties:
"mpp":
$ref: "#/$defs/qcom-pmic-mpp-state"
additionalProperties: false
$defs:
qcom-pmic-mpp-state:
type: object
allOf:
- $ref: "pinmux-node.yaml"
- $ref: "pincfg-node.yaml"
properties:
pins:
description:
List of gpio pins affected by the properties specified in
this subnode. Valid pins are
- mpp1-mpp4 for pm8841
- mpp1-mpp4 for pm8916
- mpp1-mpp8 for pm8941
- mpp1-mpp4 for pm8950
- mpp1-mpp4 for pmi8950
- mpp1-mpp4 for pma8084
items:
pattern: "^mpp([0-9]+)$"
function:
items:
- enum:
- digital
- analog
- sink
bias-disable: true
bias-pull-up: true
bias-high-impedance: true
input-enable: true
output-high: true
output-low: true
power-source: true
qcom,analog-level:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Selects the source for analog output. Valued values are defined in
<dt-binding/pinctrl/qcom,pmic-mpp.h> PMIC_MPP_AOUT_LVL_*
enum: [0, 1, 2, 3, 4, 5, 6, 7]
qcom,atest:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Selects ATEST rail to route to GPIO when it's
configured in analog-pass-through mode.
enum: [1, 2, 3, 4]
qcom,dtest:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Selects DTEST rail to route to GPIO when it's
configured as digital input.
enum: [1, 2, 3, 4]
qcom,amux-route:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Selects the source for analog input. Valid values are defined in
<dt-bindings/pinctrl/qcom,pmic-mpp.h> PMIC_MPP_AMUX_ROUTE_CH5,
PMIC_MPP_AMUX_ROUTE_CH6...
enum: [0, 1, 2, 3, 4, 5, 6, 7]
qcom,paired:
- description:
Indicates that the pin should be operating in paired mode.
required:
- pins
- function
additionalProperties: false
examples:
- |
#include <dt-bindings/pinctrl/qcom,pmic-mpp.h>
pm8841_mpp: mpps@a000 {
compatible = "qcom,pm8841-mpp", "qcom,spmi-mpp";
reg = <0xa000 0>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pm8841_mpp 0 0 4>;
gpio-line-names = "VDD_PX_BIAS", "WLAN_LED_CTRL",
"BT_LED_CTRL", "GPIO-F";
interrupt-controller;
#interrupt-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pm8841_default>;
mpp1-state {
pins = "mpp1";
function = "digital";
input-enable;
power-source = <PM8841_MPP_S3>;
};
default-state {
gpio-mpp {
pins = "mpp1", "mpp2", "mpp3", "mpp4";
function = "digital";
input-enable;
power-source = <PM8841_MPP_S3>;
};
};
};
...
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/qcom,qcm2290-pinctrl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Technologies, Inc. QCM2290 TLMM block
maintainers:
- Shawn Guo <shawn.guo@linaro.org>
description:
This binding describes the Top Level Mode Multiplexer block found in the
QCM2290 platform.
properties:
compatible:
const: qcom,qcm2290-tlmm
reg:
maxItems: 1
interrupts:
description: Specifies the TLMM summary IRQ
maxItems: 1
interrupt-controller: true
'#interrupt-cells':
description:
Specifies the PIN numbers and Flags, as defined in defined in
include/dt-bindings/interrupt-controller/irq.h
const: 2
gpio-controller: true
'#gpio-cells':
description: Specifying the pin number and flags, as defined in
include/dt-bindings/gpio/gpio.h
const: 2
gpio-ranges:
maxItems: 1
wakeup-parent:
maxItems: 1
#PIN CONFIGURATION NODES
patternProperties:
'-state$':
oneOf:
- $ref: "#/$defs/qcom-qcm2290-tlmm-state"
- patternProperties:
".*":
$ref: "#/$defs/qcom-qcm2290-tlmm-state"
'$defs':
qcom-qcm2290-tlmm-state:
type: object
description:
Pinctrl node's client devices use subnodes for desired pin configuration.
Client device subnodes use below standard properties.
$ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state"
properties:
pins:
description:
List of gpio pins affected by the properties specified in this
subnode.
items:
oneOf:
- pattern: "^gpio([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-6])$"
- enum: [ sdc1_rclk, sdc1_clk, sdc1_cmd, sdc1_data,
sdc2_clk, sdc2_cmd, sdc2_data ]
minItems: 1
maxItems: 36
function:
description:
Specify the alternative function to be configured for the specified
pins.
enum: [ adsp_ext, agera_pll, atest, cam_mclk, cci_async, cci_i2c,
cci_timer0, cci_timer1, cci_timer2, cci_timer3, char_exec,
cri_trng, cri_trng0, cri_trng1, dac_calib, dbg_out, ddr_bist,
ddr_pxi0, ddr_pxi1, ddr_pxi2, ddr_pxi3, gcc_gp1, gcc_gp2,
gcc_gp3, gpio, gp_pdm0, gp_pdm1, gp_pdm2, gsm0_tx, gsm1_tx,
jitter_bist, mdp_vsync, mdp_vsync_out_0, mdp_vsync_out_1,
mpm_pwr, mss_lte, m_voc, nav_gpio, pa_indicator, pbs0, pbs1,
pbs2, pbs3, pbs4, pbs5, pbs6, pbs7, pbs8, pbs9, pbs10, pbs11,
pbs12, pbs13, pbs14, pbs15, pbs_out, phase_flag, pll_bist,
pll_bypassnl, pll_reset, prng_rosc, pwm_0, pwm_1, pwm_2, pwm_3,
pwm_4, pwm_5, pwm_6, pwm_7, pwm_8, pwm_9, qdss_cti, qdss_gpio,
qup0, qup1, qup2, qup3, qup4, qup5, sdc1_tb, sdc2_tb, sd_write,
ssbi_wtr1, tgu_ch0, tgu_ch1, tgu_ch2, tgu_ch3, tsense_pwm,
uim1_clk, uim1_data, uim1_present, uim1_reset, uim2_clk,
uim2_data, uim2_present, uim2_reset, usb_phy, vfr_1,
vsense_trigger, wlan1_adc0, wlan1_adc1 ]
drive-strength:
enum: [2, 4, 6, 8, 10, 12, 14, 16]
default: 2
description:
Selects the drive strength for the specified pins, in mA.
bias-pull-down: true
bias-pull-up: true
bias-disable: true
output-high: true
output-low: true
required:
- pins
additionalProperties: false
required:
- compatible
- reg
- interrupts
- interrupt-controller
- '#interrupt-cells'
- gpio-controller
- '#gpio-cells'
- gpio-ranges
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
tlmm: pinctrl@500000 {
compatible = "qcom,qcm2290-tlmm";
reg = <0x500000 0x300000>;
interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
gpio-ranges = <&tlmm 0 0 127>;
sdc2_on_state: sdc2-on-state {
clk {
pins = "sdc2_clk";
bias-disable;
drive-strength = <16>;
};
cmd {
pins = "sdc2_cmd";
bias-pull-up;
drive-strength = <10>;
};
data {
pins = "sdc2_data";
bias-pull-up;
drive-strength = <10>;
};
};
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/qcom,sm6350-pinctrl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Technologies, Inc. SM6350 TLMM block
maintainers:
- Konrad Dybcio <konrad.dybcio@somainline.org>
description: |
This binding describes the Top Level Mode Multiplexer (TLMM) block found
in the SM6350 platform.
allOf:
- $ref: /schemas/pinctrl/qcom,tlmm-common.yaml#
properties:
compatible:
const: qcom,sm6350-tlmm
reg:
maxItems: 1
interrupts: true
interrupt-controller: true
'#interrupt-cells': true
gpio-controller: true
gpio-reserved-ranges: true
'#gpio-cells': true
gpio-ranges: true
wakeup-parent: true
required:
- compatible
- reg
additionalProperties: false
patternProperties:
'-state$':
oneOf:
- $ref: "#/$defs/qcom-sm6350-tlmm-state"
- patternProperties:
".*":
$ref: "#/$defs/qcom-sm6350-tlmm-state"
$defs:
qcom-sm6350-tlmm-state:
type: object
description:
Pinctrl node's client devices use subnodes for desired pin configuration.
Client device subnodes use below standard properties.
$ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state"
properties:
pins:
description:
List of gpio pins affected by the properties specified in this
subnode.
items:
oneOf:
- pattern: "^gpio([0-9]|[1-9][0-9]|1[0-4][0-9]|15[0-7])$"
- enum: [ sdc1_clk, sdc1_cmd, sdc1_data, sdc2_clk, sdc2_cmd, sdc2_data ]
minItems: 1
maxItems: 36
function:
description:
Specify the alternative function to be configured for the specified
pins.
enum: [ adsp_ext, agera_pll, atest_char, atest_char0, atest_char1, atest_char2,
atest_char3, atest_tsens, atest_tsens2, atest_usb1, atest_usb10, atest_usb11,
atest_usb12, atest_usb13, atest_usb2, atest_usb20, atest_usb21, atest_usb22,
atest_usb23, audio_ref, btfm_slimbus, cam_mclk0, cam_mclk1, cam_mclk2, cam_mclk3,
cam_mclk4, cci_async, cci_i2c, cci_timer0, cci_timer1, cci_timer2, cci_timer3,
cci_timer4, cri_trng, dbg_out, ddr_bist, ddr_pxi0, ddr_pxi1, ddr_pxi2, ddr_pxi3,
dp_hot, edp_lcd, gcc_gp1, gcc_gp2, gcc_gp3, gp_pdm0, gp_pdm1, gp_pdm2, gpio,
gps_tx, ibi_i3c, jitter_bist, ldo_en, ldo_update, lpass_ext, m_voc, mclk,
mdp_vsync, mdp_vsync0, mdp_vsync1, mdp_vsync2, mdp_vsync3, mi2s_0, mi2s_1, mi2s_2,
mss_lte, nav_gpio, nav_pps, pa_indicator, pcie0_clk, phase_flag0, phase_flag1,
phase_flag10, phase_flag11, phase_flag12, phase_flag13, phase_flag14, phase_flag15,
phase_flag16, phase_flag17, phase_flag18, phase_flag19, phase_flag2, phase_flag20,
phase_flag21, phase_flag22, phase_flag23, phase_flag24, phase_flag25, phase_flag26,
phase_flag27, phase_flag28, phase_flag29, phase_flag3, phase_flag30, phase_flag31,
phase_flag4, phase_flag5, phase_flag6, phase_flag7, phase_flag8, phase_flag9,
pll_bist, pll_bypassnl, pll_reset, prng_rosc, qdss_cti, qdss_gpio, qdss_gpio0,
qdss_gpio1, qdss_gpio10, qdss_gpio11, qdss_gpio12, qdss_gpio13, qdss_gpio14,
qdss_gpio15, qdss_gpio2, qdss_gpio3, qdss_gpio4, qdss_gpio5, qdss_gpio6,
qdss_gpio7, qdss_gpio8, qdss_gpio9, qlink0_enable, qlink0_request, qlink0_wmss,
qlink1_enable, qlink1_request, qlink1_wmss, qup00, qup01, qup02, qup10, qup11,
qup12, qup13_f1, qup13_f2, qup14, rffe0_clk, rffe0_data, rffe1_clk, rffe1_data,
rffe2_clk, rffe2_data, rffe3_clk, rffe3_data, rffe4_clk, rffe4_data, sd_write,
sdc1_tb, sdc2_tb, sp_cmu, tgu_ch0, tgu_ch1, tgu_ch2, tgu_ch3, tsense_pwm1,
tsense_pwm2, uim1_clk, uim1_data, uim1_present, uim1_reset, uim2_clk, uim2_data,
uim2_present, uim2_reset, usb_phy, vfr_1, vsense_trigger, wlan1_adc0, wlan1_adc1,
wlan2_adc0, wlan2_adc1, ]
bias-disable: true
bias-pull-down: true
bias-pull-up: true
drive-strength: true
input-enable: true
output-high: true
output-low: true
required:
- pins
- function
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
pinctrl@f100000 {
compatible = "qcom,sm6350-tlmm";
reg = <0x0f100000 0x300000>;
interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
gpio-ranges = <&tlmm 0 0 157>;
gpio-wo-subnode-state {
pins = "gpio1";
function = "gpio";
};
uart-w-subnodes-state {
rx {
pins = "gpio25";
function = "qup13_f2";
bias-disable;
};
tx {
pins = "gpio26";
function = "qup13_f2";
bias-disable;
};
};
};
...
* Rockchip Pinmux Controller
The Rockchip Pinmux Controller, enables the IC
to share one PAD to several functional blocks. The sharing is done by
multiplexing the PAD input/output signals. For each PAD there are several
muxing options with option 0 being the use as a GPIO.
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 Rockchip pin configuration node is a node of a group of pins which can be
used for a specific device or function. This node represents both mux and
config of the pins in that group. The 'pins' selects the function mode(also
named pin mode) this pin can work on and the 'config' configures various pad
settings such as pull-up, etc.
The pins are grouped into up to 5 individual pin banks which need to be
defined as gpio sub-nodes of the pinmux controller.
Required properties for iomux controller:
- compatible: should be
"rockchip,px30-pinctrl": for Rockchip PX30
"rockchip,rv1108-pinctrl": for Rockchip RV1108
"rockchip,rk2928-pinctrl": for Rockchip RK2928
"rockchip,rk3066a-pinctrl": for Rockchip RK3066a
"rockchip,rk3066b-pinctrl": for Rockchip RK3066b
"rockchip,rk3128-pinctrl": for Rockchip RK3128
"rockchip,rk3188-pinctrl": for Rockchip RK3188
"rockchip,rk3228-pinctrl": for Rockchip RK3228
"rockchip,rk3288-pinctrl": for Rockchip RK3288
"rockchip,rk3308-pinctrl": for Rockchip RK3308
"rockchip,rk3328-pinctrl": for Rockchip RK3328
"rockchip,rk3368-pinctrl": for Rockchip RK3368
"rockchip,rk3399-pinctrl": for Rockchip RK3399
"rockchip,rk3568-pinctrl": for Rockchip RK3568
- rockchip,grf: phandle referencing a syscon providing the
"general register files"
Optional properties for iomux controller:
- rockchip,pmu: phandle referencing a syscon providing the pmu registers
as some SoCs carry parts of the iomux controller registers there.
Required for at least rk3188 and rk3288. On the rk3368 this should
point to the PMUGRF syscon.
Deprecated properties for iomux controller:
- reg: first element is the general register space of the iomux controller
It should be large enough to contain also separate pull registers.
second element is the separate pull register space of the rk3188.
Use rockchip,grf and rockchip,pmu described above instead.
Required properties for gpio sub nodes:
See rockchip,gpio-bank.yaml
Required properties for pin configuration node:
- rockchip,pins: 3 integers array, represents a group of pins mux and config
setting. The format is rockchip,pins = <PIN_BANK PIN_BANK_IDX MUX &phandle>.
The MUX 0 means gpio and MUX 1 to N mean the specific device function.
The phandle of a node containing the generic pinconfig options
to use, as described in pinctrl-bindings.txt in this directory.
Examples:
#include <dt-bindings/pinctrl/rockchip.h>
...
pinctrl@20008000 {
compatible = "rockchip,rk3066a-pinctrl";
rockchip,grf = <&grf>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
gpio0: gpio0@20034000 {
compatible = "rockchip,gpio-bank";
reg = <0x20034000 0x100>;
interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk_gates8 9>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
...
pcfg_pull_default: pcfg_pull_default {
bias-pull-pin-default
};
uart2 {
uart2_xfer: uart2-xfer {
rockchip,pins = <1 RK_PB0 1 &pcfg_pull_default>,
<1 RK_PB1 1 &pcfg_pull_default>;
};
};
};
uart2: serial@20064000 {
compatible = "snps,dw-apb-uart";
reg = <0x20064000 0x400>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <1>;
clocks = <&mux_uart2>;
pinctrl-names = "default";
pinctrl-0 = <&uart2_xfer>;
};
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/rockchip,pinctrl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Rockchip Pinmux Controller
maintainers:
- Heiko Stuebner <heiko@sntech.de>
description: |
The Rockchip Pinmux Controller enables the IC to share one PAD
to several functional blocks. The sharing is done by multiplexing
the PAD input/output signals. For each PAD there are several muxing
options with option 0 being used as a GPIO.
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 Rockchip pin configuration node is a node of a group of pins which can be
used for a specific device or function. This node represents both mux and
config of the pins in that group. The 'pins' selects the function mode
(also named pin mode) this pin can work on and the 'config' configures
various pad settings such as pull-up, etc.
The pins are grouped into up to 9 individual pin banks which need to be
defined as gpio sub-nodes of the pinmux controller.
properties:
compatible:
enum:
- rockchip,px30-pinctrl
- rockchip,rk2928-pinctrl
- rockchip,rk3066a-pinctrl
- rockchip,rk3066b-pinctrl
- rockchip,rk3128-pinctrl
- rockchip,rk3188-pinctrl
- rockchip,rk3228-pinctrl
- rockchip,rk3288-pinctrl
- rockchip,rk3308-pinctrl
- rockchip,rk3328-pinctrl
- rockchip,rk3368-pinctrl
- rockchip,rk3399-pinctrl
- rockchip,rk3568-pinctrl
- rockchip,rv1108-pinctrl
rockchip,grf:
$ref: "/schemas/types.yaml#/definitions/phandle"
description:
The phandle of the syscon node for the GRF registers.
rockchip,pmu:
$ref: "/schemas/types.yaml#/definitions/phandle"
description:
The phandle of the syscon node for the PMU registers,
as some SoCs carry parts of the iomux controller registers there.
Required for at least rk3188 and rk3288. On the rk3368 this should
point to the PMUGRF syscon.
"#address-cells":
enum: [1, 2]
"#size-cells":
enum: [1, 2]
ranges: true
required:
- compatible
- rockchip,grf
- "#address-cells"
- "#size-cells"
- ranges
patternProperties:
"gpio@[0-9a-f]+$":
type: object
$ref: "/schemas/gpio/rockchip,gpio-bank.yaml#"
unevaluatedProperties: false
"pcfg-[a-z0-9-]+$":
type: object
properties:
bias-disable: true
bias-pull-down: true
bias-pull-pin-default: true
bias-pull-up: true
drive-strength:
minimum: 0
maximum: 20
input-enable: true
input-schmitt-enable: true
output-high: true
output-low: true
additionalProperties: false
additionalProperties:
type: object
additionalProperties:
type: object
properties:
rockchip,pins:
$ref: "/schemas/types.yaml#/definitions/uint32-matrix"
minItems: 1
items:
items:
- minimum: 0
maximum: 8
description:
Pin bank.
- minimum: 0
maximum: 31
description:
Pin bank index.
- minimum: 0
maximum: 6
description:
Mux 0 means GPIO and mux 1 to N means
the specific device function.
- description:
The phandle of a node contains the generic pinconfig options
to use as described in pinctrl-bindings.txt.
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/pinctrl/rockchip.h>
pinctrl: pinctrl {
compatible = "rockchip,rk3066a-pinctrl";
rockchip,grf = <&grf>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
gpio0: gpio@20034000 {
compatible = "rockchip,gpio-bank";
reg = <0x20034000 0x100>;
interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk_gates8 9>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
pcfg_pull_default: pcfg-pull-default {
bias-pull-pin-default;
};
uart2 {
uart2_xfer: uart2-xfer {
rockchip,pins = <1 RK_PB0 1 &pcfg_pull_default>,
<1 RK_PB1 1 &pcfg_pull_default>;
};
};
};
uart2: serial@20064000 {
compatible = "snps,dw-apb-uart";
reg = <0x20064000 0x400>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mux_uart2>;
pinctrl-0 = <&uart2_xfer>;
pinctrl-names = "default";
reg-io-width = <1>;
reg-shift = <2>;
};
......@@ -23,6 +23,7 @@ Required Properties:
- "samsung,exynos5433-pinctrl": for Exynos5433 compatible pin-controller.
- "samsung,exynos7-pinctrl": for Exynos7 compatible pin-controller.
- "samsung,exynos850-pinctrl": for Exynos850 compatible pin-controller.
- "samsung,exynosautov9-pinctrl": for ExynosAutov9 compatible pin-controller.
- reg: Base address of the pin controller hardware module and length of
the address space it occupies.
......
......@@ -24,6 +24,7 @@ properties:
- socionext,uniphier-ld11-pinctrl
- socionext,uniphier-ld20-pinctrl
- socionext,uniphier-pxs3-pinctrl
- socionext,uniphier-nx1-pinctrl
required:
- compatible
......
......@@ -1534,9 +1534,14 @@ static int gpiochip_add_irqchip(struct gpio_chip *gc,
}
if (gc->irq.parent_handler) {
void *data = gc->irq.parent_handler_data ?: gc;
for (i = 0; i < gc->irq.num_parents; i++) {
void *data;
if (gc->irq.per_parent_data)
data = gc->irq.parent_handler_data_array[i];
else
data = gc->irq.parent_handler_data ?: gc;
/*
* The parent IRQ chip is already using the chip_data
* for this IRQ chip, so our callbacks simply use the
......
......@@ -31,6 +31,22 @@ config DEBUG_PINCTRL
help
Say Y here to add some extra checks and diagnostics to PINCTRL calls.
config PINCTRL_APPLE_GPIO
tristate "Apple SoC GPIO pin controller driver"
depends on ARCH_APPLE
select PINMUX
select GPIOLIB
select GPIOLIB_IRQCHIP
select GENERIC_PINCTRL_GROUPS
select GENERIC_PINMUX_FUNCTIONS
select OF_GPIO
help
This is the driver for the GPIO controller found on Apple ARM SoCs,
including M1.
This driver can also be built as a module. If so, the module
will be called pinctrl-apple-gpio.
config PINCTRL_ARTPEC6
bool "Axis ARTPEC-6 pin controller driver"
depends on MACH_ARTPEC6
......
......@@ -8,6 +8,7 @@ obj-$(CONFIG_PINMUX) += pinmux.o
obj-$(CONFIG_PINCONF) += pinconf.o
obj-$(CONFIG_OF) += devicetree.o
obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o
obj-$(CONFIG_PINCTRL_APPLE_GPIO) += pinctrl-apple-gpio.o
obj-$(CONFIG_PINCTRL_ARTPEC6) += pinctrl-artpec6.o
obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o
obj-$(CONFIG_PINCTRL_AXP209) += pinctrl-axp209.o
......
......@@ -18,7 +18,7 @@ config PINCTRL_BCM281XX
framework. GPIO is provided by a separate GPIO driver.
config PINCTRL_BCM2835
bool "Broadcom BCM2835 GPIO (with PINCONF) driver"
tristate "Broadcom BCM2835 GPIO (with PINCONF) driver"
depends on OF && (ARCH_BCM2835 || ARCH_BRCMSTB || COMPILE_TEST)
select PINMUX
select PINCONF
......
......@@ -20,6 +20,7 @@
#include <linux/irqdesc.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of.h>
#include <linux/of_irq.h>
......@@ -1332,4 +1333,10 @@ static struct platform_driver bcm2835_pinctrl_driver = {
.suppress_bind_attrs = true,
},
};
builtin_platform_driver(bcm2835_pinctrl_driver);
module_platform_driver(bcm2835_pinctrl_driver);
MODULE_AUTHOR("Chris Boot");
MODULE_AUTHOR("Simon Arlott");
MODULE_AUTHOR("Stephen Warren");
MODULE_DESCRIPTION("Broadcom BCM2835/2711 pinctrl and GPIO driver");
MODULE_LICENSE("GPL");
......@@ -2100,6 +2100,8 @@ int pinctrl_enable(struct pinctrl_dev *pctldev)
if (error) {
dev_err(pctldev->dev, "could not claim hogs: %i\n",
error);
pinctrl_free_pindescs(pctldev, pctldev->desc->pins,
pctldev->desc->npins);
mutex_destroy(&pctldev->mutex);
kfree(pctldev);
......
# SPDX-License-Identifier: GPL-2.0
# Intel pin control drivers
if (X86 || COMPILE_TEST)
menu "Intel pinctrl drivers"
depends on X86 || COMPILE_TEST
config PINCTRL_BAYTRAIL
bool "Intel Baytrail GPIO pin control"
......@@ -168,4 +168,4 @@ config PINCTRL_TIGERLAKE
This pinctrl driver provides an interface that allows configuring
of Intel Tiger Lake PCH pins and using them as GPIOs.
endif
endmenu
......@@ -119,6 +119,13 @@ config PINCTRL_MT7622
default ARM64 && ARCH_MEDIATEK
select PINCTRL_MTK_MOORE
config PINCTRL_MT7986
bool "Mediatek MT7986 pin control"
depends on OF
depends on ARM64 || COMPILE_TEST
default ARM64 && ARCH_MEDIATEK
select PINCTRL_MTK_MOORE
config PINCTRL_MT8167
bool "Mediatek MT8167 pin control"
depends on OF
......
......@@ -17,6 +17,7 @@ obj-$(CONFIG_PINCTRL_MT6797) += pinctrl-mt6797.o
obj-$(CONFIG_PINCTRL_MT7622) += pinctrl-mt7622.o
obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o
obj-$(CONFIG_PINCTRL_MT7629) += pinctrl-mt7629.o
obj-$(CONFIG_PINCTRL_MT7986) += pinctrl-mt7986.o
obj-$(CONFIG_PINCTRL_MT8167) += pinctrl-mt8167.o
obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o
obj-$(CONFIG_PINCTRL_MT8183) += pinctrl-mt8183.o
......
......@@ -60,6 +60,8 @@ static int mtk_pinmux_set_mux(struct pinctrl_dev *pctldev,
int pin = grp->pins[i];
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
if (!desc->name)
return -ENOTSUPP;
mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,
pin_modes[i]);
......@@ -76,6 +78,8 @@ static int mtk_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
const struct mtk_pin_desc *desc;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
if (!desc->name)
return -ENOTSUPP;
return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,
hw->soc->gpio_m);
......@@ -89,6 +93,8 @@ static int mtk_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
const struct mtk_pin_desc *desc;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
if (!desc->name)
return -ENOTSUPP;
/* hardware would take 0 as input direction */
return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !input);
......@@ -103,6 +109,8 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
const struct mtk_pin_desc *desc;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
if (!desc->name)
return -ENOTSUPP;
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
......@@ -218,6 +226,8 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
int cfg, err = 0;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
if (!desc->name)
return -ENOTSUPP;
for (cfg = 0; cfg < num_configs; cfg++) {
param = pinconf_to_config_param(configs[cfg]);
......@@ -435,6 +445,8 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)
int value, err;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
if (!desc->name)
return -ENOTSUPP;
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
if (err)
......@@ -449,6 +461,10 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
const struct mtk_pin_desc *desc;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
if (!desc->name) {
dev_err(hw->dev, "Failed to set gpio %d\n", gpio);
return;
}
mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
}
......@@ -490,6 +506,8 @@ static int mtk_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
u32 debounce;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[offset];
if (!desc->name)
return -ENOTSUPP;
if (!hw->eint ||
pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE ||
......
此差异已折叠。
......@@ -779,6 +779,135 @@ static const struct mtk_pin_field_calc mt8195_pin_drv_adv_range[] = {
PIN_FIELD_BASE(45, 45, 1, 0x040, 0x10, 9, 3),
};
static const struct mtk_pin_field_calc mt8195_pin_rsel_range[] = {
PIN_FIELD_BASE(8, 8, 4, 0x0c0, 0x10, 15, 3),
PIN_FIELD_BASE(9, 9, 4, 0x0c0, 0x10, 0, 3),
PIN_FIELD_BASE(10, 10, 4, 0x0c0, 0x10, 18, 3),
PIN_FIELD_BASE(11, 11, 4, 0x0c0, 0x10, 3, 3),
PIN_FIELD_BASE(12, 12, 4, 0x0c0, 0x10, 21, 3),
PIN_FIELD_BASE(13, 13, 4, 0x0c0, 0x10, 6, 3),
PIN_FIELD_BASE(14, 14, 4, 0x0c0, 0x10, 24, 3),
PIN_FIELD_BASE(15, 15, 4, 0x0c0, 0x10, 9, 3),
PIN_FIELD_BASE(16, 16, 4, 0x0c0, 0x10, 27, 3),
PIN_FIELD_BASE(17, 17, 4, 0x0c0, 0x10, 12, 3),
PIN_FIELD_BASE(29, 29, 2, 0x080, 0x10, 0, 3),
PIN_FIELD_BASE(30, 30, 2, 0x080, 0x10, 3, 3),
PIN_FIELD_BASE(34, 34, 1, 0x0e0, 0x10, 0, 3),
PIN_FIELD_BASE(35, 35, 1, 0x0e0, 0x10, 3, 3),
PIN_FIELD_BASE(44, 44, 1, 0x0e0, 0x10, 6, 3),
PIN_FIELD_BASE(45, 45, 1, 0x0e0, 0x10, 9, 3),
};
static const struct mtk_pin_rsel mt8195_pin_rsel_val_range[] = {
PIN_RSEL(8, 17, 0x0, 75000, 75000),
PIN_RSEL(8, 17, 0x1, 10000, 5000),
PIN_RSEL(8, 17, 0x2, 5000, 75000),
PIN_RSEL(8, 17, 0x3, 4000, 5000),
PIN_RSEL(8, 17, 0x4, 3000, 75000),
PIN_RSEL(8, 17, 0x5, 2000, 5000),
PIN_RSEL(8, 17, 0x6, 1500, 75000),
PIN_RSEL(8, 17, 0x7, 1000, 5000),
PIN_RSEL(29, 30, 0x0, 75000, 75000),
PIN_RSEL(29, 30, 0x1, 10000, 5000),
PIN_RSEL(29, 30, 0x2, 5000, 75000),
PIN_RSEL(29, 30, 0x3, 4000, 5000),
PIN_RSEL(29, 30, 0x4, 3000, 75000),
PIN_RSEL(29, 30, 0x5, 2000, 5000),
PIN_RSEL(29, 30, 0x6, 1500, 75000),
PIN_RSEL(29, 30, 0x7, 1000, 5000),
PIN_RSEL(34, 35, 0x0, 75000, 75000),
PIN_RSEL(34, 35, 0x1, 10000, 5000),
PIN_RSEL(34, 35, 0x2, 5000, 75000),
PIN_RSEL(34, 35, 0x3, 4000, 5000),
PIN_RSEL(34, 35, 0x4, 3000, 75000),
PIN_RSEL(34, 35, 0x5, 2000, 5000),
PIN_RSEL(34, 35, 0x6, 1500, 75000),
PIN_RSEL(34, 35, 0x7, 1000, 5000),
PIN_RSEL(44, 45, 0x0, 75000, 75000),
PIN_RSEL(44, 45, 0x1, 10000, 5000),
PIN_RSEL(44, 45, 0x2, 5000, 75000),
PIN_RSEL(44, 45, 0x3, 4000, 5000),
PIN_RSEL(44, 45, 0x4, 3000, 75000),
PIN_RSEL(44, 45, 0x5, 2000, 5000),
PIN_RSEL(44, 45, 0x6, 1500, 75000),
PIN_RSEL(44, 45, 0x7, 1000, 5000),
};
static const unsigned int mt8195_pull_type[] = {
MTK_PULL_PUPD_R1R0_TYPE /* 0 */, MTK_PULL_PUPD_R1R0_TYPE /* 1 */,
MTK_PULL_PUPD_R1R0_TYPE /* 2 */, MTK_PULL_PUPD_R1R0_TYPE /* 3 */,
MTK_PULL_PUPD_R1R0_TYPE /* 4 */, MTK_PULL_PUPD_R1R0_TYPE /* 5 */,
MTK_PULL_PU_PD_TYPE /* 6 */, MTK_PULL_PU_PD_TYPE /* 7 */,
MTK_PULL_PU_PD_RSEL_TYPE /* 8 */, MTK_PULL_PU_PD_RSEL_TYPE /* 9 */,
MTK_PULL_PU_PD_RSEL_TYPE /* 10 */, MTK_PULL_PU_PD_RSEL_TYPE /* 11 */,
MTK_PULL_PU_PD_RSEL_TYPE /* 12 */, MTK_PULL_PU_PD_RSEL_TYPE /* 13 */,
MTK_PULL_PU_PD_RSEL_TYPE /* 14 */, MTK_PULL_PU_PD_RSEL_TYPE /* 15 */,
MTK_PULL_PU_PD_RSEL_TYPE /* 16 */, MTK_PULL_PU_PD_RSEL_TYPE /* 17 */,
MTK_PULL_PU_PD_TYPE /* 18 */, MTK_PULL_PU_PD_TYPE /* 19 */,
MTK_PULL_PU_PD_TYPE /* 20 */, MTK_PULL_PU_PD_TYPE /* 21 */,
MTK_PULL_PU_PD_TYPE /* 22 */, MTK_PULL_PU_PD_TYPE /* 23 */,
MTK_PULL_PU_PD_TYPE /* 24 */, MTK_PULL_PU_PD_TYPE /* 25 */,
MTK_PULL_PU_PD_TYPE /* 26 */, MTK_PULL_PU_PD_TYPE /* 27 */,
MTK_PULL_PU_PD_TYPE /* 28 */, MTK_PULL_PU_PD_RSEL_TYPE /* 29 */,
MTK_PULL_PU_PD_RSEL_TYPE /* 30 */, MTK_PULL_PU_PD_TYPE /* 31 */,
MTK_PULL_PU_PD_TYPE /* 32 */, MTK_PULL_PU_PD_TYPE /* 33 */,
MTK_PULL_PU_PD_RSEL_TYPE /* 34 */, MTK_PULL_PU_PD_RSEL_TYPE /* 35 */,
MTK_PULL_PU_PD_TYPE /* 36 */, MTK_PULL_PU_PD_TYPE /* 37 */,
MTK_PULL_PU_PD_TYPE /* 38 */, MTK_PULL_PU_PD_TYPE /* 39 */,
MTK_PULL_PU_PD_TYPE /* 40 */, MTK_PULL_PU_PD_TYPE /* 41 */,
MTK_PULL_PU_PD_TYPE /* 42 */, MTK_PULL_PU_PD_TYPE /* 43 */,
MTK_PULL_PU_PD_RSEL_TYPE /* 44 */, MTK_PULL_PU_PD_RSEL_TYPE /* 45 */,
MTK_PULL_PU_PD_TYPE /* 46 */, MTK_PULL_PU_PD_TYPE /* 47 */,
MTK_PULL_PU_PD_TYPE /* 48 */, MTK_PULL_PU_PD_TYPE /* 49 */,
MTK_PULL_PU_PD_TYPE /* 50 */, MTK_PULL_PU_PD_TYPE /* 51 */,
MTK_PULL_PU_PD_TYPE /* 52 */, MTK_PULL_PU_PD_TYPE /* 53 */,
MTK_PULL_PU_PD_TYPE /* 54 */, MTK_PULL_PU_PD_TYPE /* 55 */,
MTK_PULL_PU_PD_TYPE /* 56 */, MTK_PULL_PU_PD_TYPE /* 57 */,
MTK_PULL_PU_PD_TYPE /* 58 */, MTK_PULL_PU_PD_TYPE /* 59 */,
MTK_PULL_PU_PD_TYPE /* 60 */, MTK_PULL_PU_PD_TYPE /* 61 */,
MTK_PULL_PU_PD_TYPE /* 62 */, MTK_PULL_PU_PD_TYPE /* 63 */,
MTK_PULL_PU_PD_TYPE /* 64 */, MTK_PULL_PU_PD_TYPE /* 65 */,
MTK_PULL_PU_PD_TYPE /* 66 */, MTK_PULL_PU_PD_TYPE /* 67 */,
MTK_PULL_PU_PD_TYPE /* 68 */, MTK_PULL_PU_PD_TYPE /* 69 */,
MTK_PULL_PU_PD_TYPE /* 70 */, MTK_PULL_PU_PD_TYPE /* 71 */,
MTK_PULL_PU_PD_TYPE /* 72 */, MTK_PULL_PU_PD_TYPE /* 73 */,
MTK_PULL_PU_PD_TYPE /* 74 */, MTK_PULL_PU_PD_TYPE /* 75 */,
MTK_PULL_PU_PD_TYPE /* 76 */, MTK_PULL_PUPD_R1R0_TYPE /* 77 */,
MTK_PULL_PUPD_R1R0_TYPE /* 78 */, MTK_PULL_PUPD_R1R0_TYPE /* 79 */,
MTK_PULL_PUPD_R1R0_TYPE /* 80 */, MTK_PULL_PUPD_R1R0_TYPE /* 81 */,
MTK_PULL_PUPD_R1R0_TYPE /* 82 */, MTK_PULL_PUPD_R1R0_TYPE /* 83 */,
MTK_PULL_PUPD_R1R0_TYPE /* 84 */, MTK_PULL_PUPD_R1R0_TYPE /* 85 */,
MTK_PULL_PUPD_R1R0_TYPE /* 86 */, MTK_PULL_PUPD_R1R0_TYPE /* 87 */,
MTK_PULL_PUPD_R1R0_TYPE /* 88 */, MTK_PULL_PUPD_R1R0_TYPE /* 89 */,
MTK_PULL_PUPD_R1R0_TYPE /* 90 */, MTK_PULL_PUPD_R1R0_TYPE /* 91 */,
MTK_PULL_PUPD_R1R0_TYPE /* 92 */, MTK_PULL_PUPD_R1R0_TYPE /* 93 */,
MTK_PULL_PUPD_R1R0_TYPE /* 94 */, MTK_PULL_PUPD_R1R0_TYPE /* 95 */,
MTK_PULL_PUPD_R1R0_TYPE /* 96 */, MTK_PULL_PU_PD_TYPE /* 97 */,
MTK_PULL_PU_PD_TYPE /* 98 */, MTK_PULL_PU_PD_TYPE /* 99 */,
MTK_PULL_PU_PD_TYPE /* 100 */, MTK_PULL_PU_PD_TYPE /* 101 */,
MTK_PULL_PU_PD_TYPE /* 102 */, MTK_PULL_PU_PD_TYPE /* 103 */,
MTK_PULL_PUPD_R1R0_TYPE /* 104 */, MTK_PULL_PUPD_R1R0_TYPE /* 105 */,
MTK_PULL_PUPD_R1R0_TYPE /* 106 */, MTK_PULL_PUPD_R1R0_TYPE /* 107 */,
MTK_PULL_PU_PD_TYPE /* 108 */, MTK_PULL_PU_PD_TYPE /* 109 */,
MTK_PULL_PUPD_R1R0_TYPE /* 110 */, MTK_PULL_PUPD_R1R0_TYPE /* 111 */,
MTK_PULL_PUPD_R1R0_TYPE /* 112 */, MTK_PULL_PUPD_R1R0_TYPE /* 113 */,
MTK_PULL_PUPD_R1R0_TYPE /* 114 */, MTK_PULL_PUPD_R1R0_TYPE /* 115 */,
MTK_PULL_PUPD_R1R0_TYPE /* 116 */, MTK_PULL_PUPD_R1R0_TYPE /* 117 */,
MTK_PULL_PUPD_R1R0_TYPE /* 118 */, MTK_PULL_PUPD_R1R0_TYPE /* 119 */,
MTK_PULL_PUPD_R1R0_TYPE /* 120 */, MTK_PULL_PUPD_R1R0_TYPE /* 121 */,
MTK_PULL_PUPD_R1R0_TYPE /* 122 */, MTK_PULL_PUPD_R1R0_TYPE /* 123 */,
MTK_PULL_PUPD_R1R0_TYPE /* 124 */, MTK_PULL_PUPD_R1R0_TYPE /* 125 */,
MTK_PULL_PUPD_R1R0_TYPE /* 126 */, MTK_PULL_PUPD_R1R0_TYPE /* 127 */,
MTK_PULL_PU_PD_TYPE /* 128 */, MTK_PULL_PU_PD_TYPE /* 129 */,
MTK_PULL_PU_PD_TYPE /* 130 */, MTK_PULL_PU_PD_TYPE /* 131 */,
MTK_PULL_PU_PD_TYPE /* 132 */, MTK_PULL_PU_PD_TYPE /* 133 */,
MTK_PULL_PU_PD_TYPE /* 134 */, MTK_PULL_PU_PD_TYPE /* 135 */,
MTK_PULL_PU_PD_TYPE /* 136 */, MTK_PULL_PU_PD_TYPE /* 137 */,
MTK_PULL_PU_PD_TYPE /* 138 */, MTK_PULL_PU_PD_TYPE /* 139 */,
MTK_PULL_PU_PD_TYPE /* 140 */, MTK_PULL_PU_PD_TYPE /* 141 */,
MTK_PULL_PU_PD_TYPE /* 142 */, MTK_PULL_PU_PD_TYPE /* 143 */,
};
static const struct mtk_pin_reg_calc mt8195_reg_cals[PINCTRL_PIN_REG_MAX] = {
[PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt8195_pin_mode_range),
[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt8195_pin_dir_range),
......@@ -793,6 +922,7 @@ static const struct mtk_pin_reg_calc mt8195_reg_cals[PINCTRL_PIN_REG_MAX] = {
[PINCTRL_PIN_REG_R0] = MTK_RANGE(mt8195_pin_r0_range),
[PINCTRL_PIN_REG_R1] = MTK_RANGE(mt8195_pin_r1_range),
[PINCTRL_PIN_REG_DRV_ADV] = MTK_RANGE(mt8195_pin_drv_adv_range),
[PINCTRL_PIN_REG_RSEL] = MTK_RANGE(mt8195_pin_rsel_range),
};
static const char * const mt8195_pinctrl_register_base_names[] = {
......@@ -817,6 +947,9 @@ static const struct mtk_pin_soc mt8195_data = {
.gpio_m = 0,
.base_names = mt8195_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt8195_pinctrl_register_base_names),
.pull_type = mt8195_pull_type,
.pin_rsel = mt8195_pin_rsel_val_range,
.npin_rsel = ARRAY_SIZE(mt8195_pin_rsel_val_range),
.bias_set_combo = mtk_pinconf_bias_set_combo,
.bias_get_combo = mtk_pinconf_bias_get_combo,
.drive_set = mtk_pinconf_drive_set_rev1,
......@@ -839,6 +972,7 @@ static struct platform_driver mt8195_pinctrl_driver = {
.driver = {
.name = "mt8195-pinctrl",
.of_match_table = mt8195_pinctrl_of_match,
.pm = &mtk_paris_pinctrl_pm_ops,
},
.probe = mt8195_pinctrl_probe,
};
......
......@@ -661,6 +661,181 @@ static int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw,
return err;
}
static int mtk_hw_pin_rsel_lookup(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 pullup, u32 arg, u32 *rsel_val)
{
const struct mtk_pin_rsel *rsel;
int check;
bool found = false;
rsel = hw->soc->pin_rsel;
for (check = 0; check <= hw->soc->npin_rsel - 1; check++) {
if (desc->number >= rsel[check].s_pin &&
desc->number <= rsel[check].e_pin) {
if (pullup) {
if (rsel[check].up_rsel == arg) {
found = true;
*rsel_val = rsel[check].rsel_index;
break;
}
} else {
if (rsel[check].down_rsel == arg) {
found = true;
*rsel_val = rsel[check].rsel_index;
break;
}
}
}
}
if (!found) {
dev_err(hw->dev, "Not support rsel value %d Ohm for pin = %d (%s)\n",
arg, desc->number, desc->name);
return -ENOTSUPP;
}
return 0;
}
static int mtk_pinconf_bias_set_rsel(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 pullup, u32 arg)
{
int err, rsel_val;
if (hw->rsel_si_unit) {
/* find pin rsel_index from pin_rsel array*/
err = mtk_hw_pin_rsel_lookup(hw, desc, pullup, arg, &rsel_val);
if (err)
goto out;
} else {
if (arg < MTK_PULL_SET_RSEL_000 ||
arg > MTK_PULL_SET_RSEL_111) {
err = -EINVAL;
goto out;
}
rsel_val = arg - MTK_PULL_SET_RSEL_000;
}
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_RSEL, rsel_val);
if (err)
goto out;
err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, MTK_ENABLE);
out:
return err;
}
int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 pullup, u32 arg)
{
int err = -ENOTSUPP;
u32 try_all_type;
if (hw->soc->pull_type)
try_all_type = hw->soc->pull_type[desc->number];
else
try_all_type = MTK_PULL_TYPE_MASK;
if (try_all_type & MTK_PULL_RSEL_TYPE) {
err = mtk_pinconf_bias_set_rsel(hw, desc, pullup, arg);
if (!err)
return err;
}
if (try_all_type & MTK_PULL_PU_PD_TYPE) {
err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
if (!err)
return err;
}
if (try_all_type & MTK_PULL_PULLSEL_TYPE) {
err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc,
pullup, arg);
if (!err)
return err;
}
if (try_all_type & MTK_PULL_PUPD_R1R0_TYPE)
err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg);
if (err)
dev_err(hw->dev, "Invalid pull argument\n");
return err;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_combo);
static int mtk_rsel_get_si_unit(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 pullup, u32 rsel_val, u32 *si_unit)
{
const struct mtk_pin_rsel *rsel;
int check;
rsel = hw->soc->pin_rsel;
for (check = 0; check <= hw->soc->npin_rsel - 1; check++) {
if (desc->number >= rsel[check].s_pin &&
desc->number <= rsel[check].e_pin) {
if (rsel_val == rsel[check].rsel_index) {
if (pullup)
*si_unit = rsel[check].up_rsel;
else
*si_unit = rsel[check].down_rsel;
break;
}
}
}
return 0;
}
static int mtk_pinconf_bias_get_rsel(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 *pullup, u32 *enable)
{
int pu, pd, rsel, err;
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_RSEL, &rsel);
if (err)
goto out;
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu);
if (err)
goto out;
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
if (pu == 0 && pd == 0) {
*pullup = 0;
*enable = MTK_DISABLE;
} else if (pu == 1 && pd == 0) {
*pullup = 1;
if (hw->rsel_si_unit)
mtk_rsel_get_si_unit(hw, desc, *pullup, rsel, enable);
else
*enable = rsel + MTK_PULL_SET_RSEL_000;
} else if (pu == 0 && pd == 1) {
*pullup = 0;
if (hw->rsel_si_unit)
mtk_rsel_get_si_unit(hw, desc, *pullup, rsel, enable);
else
*enable = rsel + MTK_PULL_SET_RSEL_000;
} else {
err = -EINVAL;
goto out;
}
out:
return err;
}
static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 *pullup, u32 *enable)
......@@ -742,44 +917,40 @@ static int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw,
return err;
}
int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 pullup, u32 arg)
{
int err;
err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
if (!err)
goto out;
err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, pullup, arg);
if (!err)
goto out;
err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg);
out:
return err;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_combo);
int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 *pullup, u32 *enable)
{
int err;
int err = -ENOTSUPP;
u32 try_all_type;
err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
if (!err)
goto out;
if (hw->soc->pull_type)
try_all_type = hw->soc->pull_type[desc->number];
else
try_all_type = MTK_PULL_TYPE_MASK;
err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, pullup, enable);
if (!err)
goto out;
if (try_all_type & MTK_PULL_RSEL_TYPE) {
err = mtk_pinconf_bias_get_rsel(hw, desc, pullup, enable);
if (!err)
return err;
}
err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable);
if (try_all_type & MTK_PULL_PU_PD_TYPE) {
err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
if (!err)
return err;
}
if (try_all_type & MTK_PULL_PULLSEL_TYPE) {
err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc,
pullup, enable);
if (!err)
return err;
}
if (try_all_type & MTK_PULL_PUPD_R1R0_TYPE)
err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable);
out:
return err;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_combo);
......
......@@ -17,6 +17,22 @@
#define MTK_ENABLE 1
#define MTK_PULLDOWN 0
#define MTK_PULLUP 1
#define MTK_PULL_PU_PD_TYPE BIT(0)
#define MTK_PULL_PULLSEL_TYPE BIT(1)
#define MTK_PULL_PUPD_R1R0_TYPE BIT(2)
/* MTK_PULL_RSEL_TYPE can select resistance and can be
* turned on/off itself. But it can't be selected pull up/down
*/
#define MTK_PULL_RSEL_TYPE BIT(3)
/* MTK_PULL_PU_PD_RSEL_TYPE is a type which is controlled by
* MTK_PULL_PU_PD_TYPE and MTK_PULL_RSEL_TYPE.
*/
#define MTK_PULL_PU_PD_RSEL_TYPE (MTK_PULL_PU_PD_TYPE \
| MTK_PULL_RSEL_TYPE)
#define MTK_PULL_TYPE_MASK (MTK_PULL_PU_PD_TYPE |\
MTK_PULL_PULLSEL_TYPE |\
MTK_PULL_PUPD_R1R0_TYPE |\
MTK_PULL_RSEL_TYPE)
#define EINT_NA U16_MAX
#define NO_EINT_SUPPORT EINT_NA
......@@ -42,6 +58,14 @@
PIN_FIELD_CALC(_s_pin, _e_pin, 0, _s_addr, _x_addrs, _s_bit, \
_x_bits, 32, 1)
#define PIN_RSEL(_s_pin, _e_pin, _rsel_index, _up_resl, _down_rsel) { \
.s_pin = _s_pin, \
.e_pin = _e_pin, \
.rsel_index = _rsel_index, \
.up_rsel = _up_resl, \
.down_rsel = _down_rsel, \
}
/* List these attributes which could be modified for the pin */
enum {
PINCTRL_PIN_REG_MODE,
......@@ -67,6 +91,7 @@ enum {
PINCTRL_PIN_REG_DRV_E0,
PINCTRL_PIN_REG_DRV_E1,
PINCTRL_PIN_REG_DRV_ADV,
PINCTRL_PIN_REG_RSEL,
PINCTRL_PIN_REG_MAX,
};
......@@ -129,6 +154,22 @@ struct mtk_pin_field_calc {
u8 fixed;
};
/**
* struct mtk_pin_rsel - the structure that provides bias resistance selection.
* @s_pin: the start pin within the rsel range
* @e_pin: the end pin within the rsel range
* @rsel_index: the rsel bias resistance index
* @up_rsel: the pullup rsel bias resistance value
* @down_rsel: the pulldown rsel bias resistance value
*/
struct mtk_pin_rsel {
u16 s_pin;
u16 e_pin;
u16 rsel_index;
u32 up_rsel;
u32 down_rsel;
};
/* struct mtk_pin_reg_calc - the structure that holds all ranges used to
* determine which register the pin would make use of
* for certain pin attribute.
......@@ -206,6 +247,9 @@ struct mtk_pin_soc {
bool ies_present;
const char * const *base_names;
unsigned int nbase_names;
const unsigned int *pull_type;
const struct mtk_pin_rsel *pin_rsel;
unsigned int npin_rsel;
/* Specific pinconfig operations */
int (*bias_disable_set)(struct mtk_pinctrl *hw,
......@@ -254,6 +298,8 @@ struct mtk_pinctrl {
const char **grp_names;
/* lock pin's register resource to avoid multiple threads issue*/
spinlock_t lock;
/* identify rsel setting by si unit or rsel define in dts node */
bool rsel_si_unit;
};
void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set);
......
......@@ -577,10 +577,11 @@ static int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int
mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DRV)
ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
unsigned int gpio, char *buf, unsigned int bufLen)
unsigned int gpio, char *buf, unsigned int buf_len)
{
int pinmux, pullup, pullen, len = 0, r1 = -1, r0 = -1;
int pinmux, pullup, pullen, len = 0, r1 = -1, r0 = -1, rsel = -1;
const struct mtk_pin_desc *desc;
u32 try_all_type;
if (gpio >= hw->soc->npins)
return -EINVAL;
......@@ -591,26 +592,41 @@ ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
pinmux -= hw->soc->nfuncs;
mtk_pinconf_bias_get_combo(hw, desc, &pullup, &pullen);
if (pullen == MTK_PUPD_SET_R1R0_00) {
pullen = 0;
r1 = 0;
r0 = 0;
} else if (pullen == MTK_PUPD_SET_R1R0_01) {
pullen = 1;
r1 = 0;
r0 = 1;
} else if (pullen == MTK_PUPD_SET_R1R0_10) {
pullen = 1;
r1 = 1;
r0 = 0;
} else if (pullen == MTK_PUPD_SET_R1R0_11) {
if (hw->soc->pull_type)
try_all_type = hw->soc->pull_type[desc->number];
if (hw->rsel_si_unit && (try_all_type & MTK_PULL_RSEL_TYPE)) {
rsel = pullen;
pullen = 1;
r1 = 1;
r0 = 1;
} else if (pullen != MTK_DISABLE && pullen != MTK_ENABLE) {
pullen = 0;
} else {
/* Case for: R1R0 */
if (pullen == MTK_PUPD_SET_R1R0_00) {
pullen = 0;
r1 = 0;
r0 = 0;
} else if (pullen == MTK_PUPD_SET_R1R0_01) {
pullen = 1;
r1 = 0;
r0 = 1;
} else if (pullen == MTK_PUPD_SET_R1R0_10) {
pullen = 1;
r1 = 1;
r0 = 0;
} else if (pullen == MTK_PUPD_SET_R1R0_11) {
pullen = 1;
r1 = 1;
r0 = 1;
}
/* Case for: RSEL */
if (pullen >= MTK_PULL_SET_RSEL_000 &&
pullen <= MTK_PULL_SET_RSEL_111) {
rsel = pullen - MTK_PULL_SET_RSEL_000;
pullen = 1;
}
}
len += scnprintf(buf + len, bufLen - len,
len += scnprintf(buf + len, buf_len - len,
"%03d: %1d%1d%1d%1d%02d%1d%1d%1d%1d",
gpio,
pinmux,
......@@ -624,10 +640,12 @@ ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
pullup);
if (r1 != -1) {
len += scnprintf(buf + len, bufLen - len, " (%1d %1d)\n",
len += scnprintf(buf + len, buf_len - len, " (%1d %1d)\n",
r1, r0);
} else if (rsel != -1) {
len += scnprintf(buf + len, buf_len - len, " (%1d)\n", rsel);
} else {
len += scnprintf(buf + len, bufLen - len, "\n");
len += scnprintf(buf + len, buf_len - len, "\n");
}
return len;
......@@ -970,6 +988,12 @@ int mtk_paris_pinctrl_probe(struct platform_device *pdev,
hw->nbase = hw->soc->nbase_names;
if (of_find_property(hw->dev->of_node,
"mediatek,rsel_resistance_in_si_unit", NULL))
hw->rsel_si_unit = true;
else
hw->rsel_si_unit = false;
spin_lock_init(&hw->lock);
err = mtk_pctrl_build_state(pdev);
......
......@@ -22,7 +22,6 @@ if (ARCH_U8500 || ARCH_NOMADIK)
config PINCTRL_NOMADIK
bool "Nomadik pin controller driver"
depends on ARCH_U8500 || ARCH_NOMADIK
depends on OF && GPIOLIB
select PINMUX
select PINCONF
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* Apple SoC pinctrl+GPIO+external IRQ driver
*
* Copyright (C) The Asahi Linux Contributors
* Copyright (C) 2020 Corellium LLC
*
* Based on: pinctrl-pistachio.c
* Copyright (C) 2014 Imagination Technologies Ltd.
* Copyright (C) 2014 Google, Inc.
*/
#include <dt-bindings/pinctrl/apple.h>
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include "pinctrl-utils.h"
#include "core.h"
#include "pinmux.h"
struct apple_gpio_pinctrl {
struct device *dev;
struct pinctrl_dev *pctldev;
void __iomem *base;
struct regmap *map;
struct pinctrl_desc pinctrl_desc;
struct gpio_chip gpio_chip;
struct irq_chip irq_chip;
u8 irqgrps[0];
};
#define REG_GPIO(x) (4 * (x))
#define REG_GPIOx_DATA BIT(0)
#define REG_GPIOx_MODE GENMASK(3, 1)
#define REG_GPIOx_OUT 1
#define REG_GPIOx_IN_IRQ_HI 2
#define REG_GPIOx_IN_IRQ_LO 3
#define REG_GPIOx_IN_IRQ_UP 4
#define REG_GPIOx_IN_IRQ_DN 5
#define REG_GPIOx_IN_IRQ_ANY 6
#define REG_GPIOx_IN_IRQ_OFF 7
#define REG_GPIOx_PERIPH GENMASK(6, 5)
#define REG_GPIOx_PULL GENMASK(8, 7)
#define REG_GPIOx_PULL_OFF 0
#define REG_GPIOx_PULL_DOWN 1
#define REG_GPIOx_PULL_UP_STRONG 2
#define REG_GPIOx_PULL_UP 3
#define REG_GPIOx_INPUT_ENABLE BIT(9)
#define REG_GPIOx_DRIVE_STRENGTH0 GENMASK(11, 10)
#define REG_GPIOx_SCHMITT BIT(15)
#define REG_GPIOx_GRP GENMASK(18, 16)
#define REG_GPIOx_LOCK BIT(21)
#define REG_GPIOx_DRIVE_STRENGTH1 GENMASK(23, 22)
#define REG_IRQ(g, x) (0x800 + 0x40 * (g) + 4 * ((x) >> 5))
struct regmap_config regmap_config = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
.cache_type = REGCACHE_FLAT,
.max_register = 512 * sizeof(u32),
.num_reg_defaults_raw = 512,
.use_relaxed_mmio = true
};
// No locking needed to mask/unmask IRQs as the interrupt mode is per pin-register.
static void apple_gpio_set_reg(struct apple_gpio_pinctrl *pctl,
unsigned int pin, u32 mask, u32 value)
{
regmap_update_bits(pctl->map, REG_GPIO(pin), mask, value);
}
static uint32_t apple_gpio_get_reg(struct apple_gpio_pinctrl *pctl,
unsigned int pin)
{
unsigned int val = 0;
regmap_read(pctl->map, REG_GPIO(pin), &val);
return val;
}
/* Pin controller functions */
static int apple_gpio_dt_node_to_map(struct pinctrl_dev *pctldev,
struct device_node *node,
struct pinctrl_map **map,
unsigned *num_maps)
{
unsigned reserved_maps;
struct apple_gpio_pinctrl *pctl;
u32 pinfunc, pin, func;
int num_pins, i, ret;
const char *group_name;
const char *function_name;
*map = NULL;
*num_maps = 0;
reserved_maps = 0;
pctl = pinctrl_dev_get_drvdata(pctldev);
ret = of_property_count_u32_elems(node, "pinmux");
if (ret <= 0) {
dev_err(pctl->dev,
"missing or empty pinmux property in node %pOFn.\n",
node);
return ret;
}
num_pins = ret;
ret = pinctrl_utils_reserve_map(pctldev, map, &reserved_maps, num_maps,
num_pins);
if (ret)
return ret;
for (i = 0; i < num_pins; i++) {
ret = of_property_read_u32_index(node, "pinmux", i, &pinfunc);
if (ret)
goto free_map;
pin = APPLE_PIN(pinfunc);
func = APPLE_FUNC(pinfunc);
if (func >= pinmux_generic_get_function_count(pctldev)) {
ret = -EINVAL;
goto free_map;
}
group_name = pinctrl_generic_get_group_name(pctldev, pin);
function_name =
pinmux_generic_get_function_name(pctl->pctldev, func);
ret = pinctrl_utils_add_map_mux(pctl->pctldev, map,
&reserved_maps, num_maps,
group_name, function_name);
if (ret)
goto free_map;
}
free_map:
if (ret < 0)
pinctrl_utils_free_map(pctldev, *map, *num_maps);
return ret;
}
static const struct pinctrl_ops apple_gpio_pinctrl_ops = {
.get_groups_count = pinctrl_generic_get_group_count,
.get_group_name = pinctrl_generic_get_group_name,
.get_group_pins = pinctrl_generic_get_group_pins,
.dt_node_to_map = apple_gpio_dt_node_to_map,
.dt_free_map = pinctrl_utils_free_map,
};
/* Pin multiplexer functions */
static int apple_gpio_pinmux_set(struct pinctrl_dev *pctldev, unsigned func,
unsigned group)
{
struct apple_gpio_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
apple_gpio_set_reg(
pctl, group, REG_GPIOx_PERIPH | REG_GPIOx_INPUT_ENABLE,
FIELD_PREP(REG_GPIOx_PERIPH, func) | REG_GPIOx_INPUT_ENABLE);
return 0;
}
static const struct pinmux_ops apple_gpio_pinmux_ops = {
.get_functions_count = pinmux_generic_get_function_count,
.get_function_name = pinmux_generic_get_function_name,
.get_function_groups = pinmux_generic_get_function_groups,
.set_mux = apple_gpio_pinmux_set,
.strict = true,
};
/* GPIO chip functions */
static int apple_gpio_get_direction(struct gpio_chip *chip,
unsigned int offset)
{
struct apple_gpio_pinctrl *pctl = gpiochip_get_data(chip);
unsigned int reg = apple_gpio_get_reg(pctl, offset);
return (FIELD_GET(REG_GPIOx_MODE, reg) == REG_GPIOx_OUT) ?
GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
}
static int apple_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct apple_gpio_pinctrl *pctl = gpiochip_get_data(chip);
unsigned int reg = apple_gpio_get_reg(pctl, offset);
/*
* If this is an input GPIO, read the actual value (not the
* cached regmap value)
*/
if (FIELD_GET(REG_GPIOx_MODE, reg) != REG_GPIOx_OUT)
reg = readl_relaxed(pctl->base + REG_GPIO(offset));
return !!(reg & REG_GPIOx_DATA);
}
static void apple_gpio_set(struct gpio_chip *chip, unsigned int offset,
int value)
{
struct apple_gpio_pinctrl *pctl = gpiochip_get_data(chip);
apple_gpio_set_reg(pctl, offset, REG_GPIOx_DATA,
value ? REG_GPIOx_DATA : 0);
}
static int apple_gpio_direction_input(struct gpio_chip *chip,
unsigned int offset)
{
struct apple_gpio_pinctrl *pctl = gpiochip_get_data(chip);
apple_gpio_set_reg(pctl, offset,
REG_GPIOx_PERIPH | REG_GPIOx_MODE | REG_GPIOx_DATA |
REG_GPIOx_INPUT_ENABLE,
FIELD_PREP(REG_GPIOx_MODE, REG_GPIOx_IN_IRQ_OFF) |
REG_GPIOx_INPUT_ENABLE);
return 0;
}
static int apple_gpio_direction_output(struct gpio_chip *chip,
unsigned int offset, int value)
{
struct apple_gpio_pinctrl *pctl = gpiochip_get_data(chip);
apple_gpio_set_reg(pctl, offset,
REG_GPIOx_PERIPH | REG_GPIOx_MODE | REG_GPIOx_DATA,
FIELD_PREP(REG_GPIOx_MODE, REG_GPIOx_OUT) |
(value ? REG_GPIOx_DATA : 0));
return 0;
}
/* IRQ chip functions */
static void apple_gpio_irq_ack(struct irq_data *data)
{
struct apple_gpio_pinctrl *pctl =
gpiochip_get_data(irq_data_get_irq_chip_data(data));
unsigned int irqgrp =
FIELD_GET(REG_GPIOx_GRP, apple_gpio_get_reg(pctl, data->hwirq));
writel(BIT(data->hwirq & 31),
pctl->base + REG_IRQ(irqgrp, data->hwirq));
}
static int apple_gpio_irq_type(unsigned int type)
{
switch (type & IRQ_TYPE_SENSE_MASK) {
case IRQ_TYPE_EDGE_RISING:
return REG_GPIOx_IN_IRQ_UP;
case IRQ_TYPE_EDGE_FALLING:
return REG_GPIOx_IN_IRQ_DN;
case IRQ_TYPE_EDGE_BOTH:
return REG_GPIOx_IN_IRQ_ANY;
case IRQ_TYPE_LEVEL_HIGH:
return REG_GPIOx_IN_IRQ_HI;
case IRQ_TYPE_LEVEL_LOW:
return REG_GPIOx_IN_IRQ_LO;
default:
return -EINVAL;
}
}
static void apple_gpio_irq_mask(struct irq_data *data)
{
struct apple_gpio_pinctrl *pctl =
gpiochip_get_data(irq_data_get_irq_chip_data(data));
apple_gpio_set_reg(pctl, data->hwirq, REG_GPIOx_MODE,
FIELD_PREP(REG_GPIOx_MODE, REG_GPIOx_IN_IRQ_OFF));
}
static void apple_gpio_irq_unmask(struct irq_data *data)
{
struct apple_gpio_pinctrl *pctl =
gpiochip_get_data(irq_data_get_irq_chip_data(data));
int irqtype = apple_gpio_irq_type(irqd_get_trigger_type(data));
apple_gpio_set_reg(pctl, data->hwirq, REG_GPIOx_MODE,
FIELD_PREP(REG_GPIOx_MODE, irqtype));
}
static unsigned int apple_gpio_irq_startup(struct irq_data *data)
{
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct apple_gpio_pinctrl *pctl = gpiochip_get_data(chip);
apple_gpio_set_reg(pctl, data->hwirq, REG_GPIOx_GRP,
FIELD_PREP(REG_GPIOx_GRP, 0));
apple_gpio_direction_input(chip, data->hwirq);
apple_gpio_irq_unmask(data);
return 0;
}
static int apple_gpio_irq_set_type(struct irq_data *data,
unsigned int type)
{
struct apple_gpio_pinctrl *pctl =
gpiochip_get_data(irq_data_get_irq_chip_data(data));
int irqtype = apple_gpio_irq_type(type);
if (irqtype < 0)
return irqtype;
apple_gpio_set_reg(pctl, data->hwirq, REG_GPIOx_MODE,
FIELD_PREP(REG_GPIOx_MODE, irqtype));
if (type & IRQ_TYPE_LEVEL_MASK)
irq_set_handler_locked(data, handle_level_irq);
else
irq_set_handler_locked(data, handle_edge_irq);
return 0;
}
static void apple_gpio_irq_handler(struct irq_desc *desc)
{
struct irq_chip *chip = irq_desc_get_chip(desc);
u8 *grpp = irq_desc_get_handler_data(desc);
struct apple_gpio_pinctrl *pctl;
unsigned int pinh, pinl;
unsigned long pending;
struct gpio_chip *gc;
pctl = container_of(grpp - *grpp, typeof(*pctl), irqgrps[0]);
gc = &pctl->gpio_chip;
chained_irq_enter(chip, desc);
for (pinh = 0; pinh < gc->ngpio; pinh += 32) {
pending = readl_relaxed(pctl->base + REG_IRQ(*grpp, pinh));
for_each_set_bit(pinl, &pending, 32)
generic_handle_domain_irq(gc->irq.domain, pinh + pinl);
}
chained_irq_exit(chip, desc);
}
static struct irq_chip apple_gpio_irqchip = {
.name = "Apple-GPIO",
.irq_startup = apple_gpio_irq_startup,
.irq_ack = apple_gpio_irq_ack,
.irq_mask = apple_gpio_irq_mask,
.irq_unmask = apple_gpio_irq_unmask,
.irq_set_type = apple_gpio_irq_set_type,
};
/* Probe & register */
static int apple_gpio_register(struct apple_gpio_pinctrl *pctl)
{
struct gpio_irq_chip *girq = &pctl->gpio_chip.irq;
void **irq_data = NULL;
int ret;
if (!of_property_read_bool(pctl->dev->of_node, "gpio-controller"))
return dev_err_probe(pctl->dev, -ENODEV,
"No gpio-controller property\n");
pctl->irq_chip = apple_gpio_irqchip;
pctl->gpio_chip.label = dev_name(pctl->dev);
pctl->gpio_chip.request = gpiochip_generic_request;
pctl->gpio_chip.free = gpiochip_generic_free;
pctl->gpio_chip.get_direction = apple_gpio_get_direction;
pctl->gpio_chip.direction_input = apple_gpio_direction_input;
pctl->gpio_chip.direction_output = apple_gpio_direction_output;
pctl->gpio_chip.get = apple_gpio_get;
pctl->gpio_chip.set = apple_gpio_set;
pctl->gpio_chip.base = -1;
pctl->gpio_chip.ngpio = pctl->pinctrl_desc.npins;
pctl->gpio_chip.parent = pctl->dev;
pctl->gpio_chip.of_node = pctl->dev->of_node;
if (girq->num_parents) {
int i;
girq->chip = &pctl->irq_chip;
girq->parent_handler = apple_gpio_irq_handler;
girq->parents = kmalloc_array(girq->num_parents,
sizeof(*girq->parents),
GFP_KERNEL);
irq_data = kmalloc_array(girq->num_parents, sizeof(*irq_data),
GFP_KERNEL);
if (!girq->parents || !irq_data) {
ret = -ENOMEM;
goto out;
}
for (i = 0; i < girq->num_parents; i++) {
ret = platform_get_irq(to_platform_device(pctl->dev),
i);
if (ret < 0)
goto out;
girq->parents[i] = ret;
pctl->irqgrps[i] = i;
irq_data[i] = &pctl->irqgrps[i];
}
girq->parent_handler_data_array = irq_data;
girq->per_parent_data = true;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_level_irq;
}
ret = devm_gpiochip_add_data(pctl->dev, &pctl->gpio_chip, pctl);
out:
kfree(girq->parents);
kfree(irq_data);
return ret;
}
static int apple_gpio_pinctrl_probe(struct platform_device *pdev)
{
struct apple_gpio_pinctrl *pctl;
struct pinctrl_pin_desc *pins;
unsigned int npins;
const char **pin_names;
unsigned int *pin_nums;
static const char* pinmux_functions[] = {
"gpio", "periph1", "periph2", "periph3"
};
unsigned int i, nirqs = 0;
int res;
if (of_property_read_bool(pdev->dev.of_node, "interrupt-controller")) {
res = platform_irq_count(pdev);
if (res > 0)
nirqs = res;
}
pctl = devm_kzalloc(&pdev->dev, struct_size(pctl, irqgrps, nirqs),
GFP_KERNEL);
if (!pctl)
return -ENOMEM;
pctl->dev = &pdev->dev;
pctl->gpio_chip.irq.num_parents = nirqs;
dev_set_drvdata(&pdev->dev, pctl);
if (of_property_read_u32(pdev->dev.of_node, "apple,npins", &npins))
return dev_err_probe(&pdev->dev, -EINVAL,
"apple,npins property not found\n");
pins = devm_kmalloc_array(&pdev->dev, npins, sizeof(pins[0]),
GFP_KERNEL);
pin_names = devm_kmalloc_array(&pdev->dev, npins, sizeof(pin_names[0]),
GFP_KERNEL);
pin_nums = devm_kmalloc_array(&pdev->dev, npins, sizeof(pin_nums[0]),
GFP_KERNEL);
if (!pins || !pin_names || !pin_nums)
return -ENOMEM;
pctl->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pctl->base))
return PTR_ERR(pctl->base);
pctl->map = devm_regmap_init_mmio(&pdev->dev, pctl->base, &regmap_config);
if (IS_ERR(pctl->map))
return dev_err_probe(&pdev->dev, PTR_ERR(pctl->map),
"Failed to create regmap\n");
for (i = 0; i < npins; i++) {
pins[i].number = i;
pins[i].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "PIN%u", i);
pins[i].drv_data = pctl;
pin_names[i] = pins[i].name;
pin_nums[i] = i;
}
pctl->pinctrl_desc.name = dev_name(pctl->dev);
pctl->pinctrl_desc.pins = pins;
pctl->pinctrl_desc.npins = npins;
pctl->pinctrl_desc.pctlops = &apple_gpio_pinctrl_ops;
pctl->pinctrl_desc.pmxops = &apple_gpio_pinmux_ops;
pctl->pctldev = devm_pinctrl_register(&pdev->dev, &pctl->pinctrl_desc, pctl);
if (IS_ERR(pctl->pctldev))
return dev_err_probe(&pdev->dev, PTR_ERR(pctl->pctldev),
"Failed to register pinctrl device.\n");
for (i = 0; i < npins; i++) {
res = pinctrl_generic_add_group(pctl->pctldev, pins[i].name,
pin_nums + i, 1, pctl);
if (res < 0)
return dev_err_probe(pctl->dev, res,
"Failed to register group");
}
for (i = 0; i < ARRAY_SIZE(pinmux_functions); ++i) {
res = pinmux_generic_add_function(pctl->pctldev, pinmux_functions[i],
pin_names, npins, pctl);
if (res < 0)
return dev_err_probe(pctl->dev, res,
"Failed to register function.");
}
return apple_gpio_register(pctl);
}
static const struct of_device_id apple_gpio_pinctrl_of_match[] = {
{ .compatible = "apple,pinctrl", },
{ }
};
static struct platform_driver apple_gpio_pinctrl_driver = {
.driver = {
.name = "apple-gpio-pinctrl",
.of_match_table = apple_gpio_pinctrl_of_match,
.suppress_bind_attrs = true,
},
.probe = apple_gpio_pinctrl_probe,
};
module_platform_driver(apple_gpio_pinctrl_driver);
MODULE_DESCRIPTION("Apple pinctrl/GPIO driver");
MODULE_AUTHOR("Stan Skowronek <stan@corellium.com>");
MODULE_AUTHOR("Joey Gouly <joey.gouly@arm.com>");
MODULE_LICENSE("GPL v2");
......@@ -675,6 +675,11 @@ static int eqbr_build_functions(struct eqbr_pinctrl_drv_data *drvdata)
return ret;
for (i = 0; i < nr_funcs; i++) {
/* Ignore the same function with multiple groups */
if (funcs[i].name == NULL)
continue;
ret = pinmux_generic_add_function(drvdata->pctl_dev,
funcs[i].name,
funcs[i].groups,
......@@ -815,7 +820,7 @@ static int pinctrl_reg(struct eqbr_pinctrl_drv_data *drvdata)
ret = eqbr_build_functions(drvdata);
if (ret) {
dev_err(dev, "Failed to build groups\n");
dev_err(dev, "Failed to build functions\n");
return ret;
}
......
......@@ -412,7 +412,7 @@ static const struct pinctrl_pin_desc gemini_3512_pins[] = {
PINCTRL_PIN(249, "P16 GPIO0 17"),
PINCTRL_PIN(250, "P17 GPIO0 18"),
PINCTRL_PIN(251, "P18 GPIO0 19"),
/* Row R (for some reason Q us skipped) */
/* Row R (for some reason Q is skipped) */
PINCTRL_PIN(252, "R1 IDE DD6"),
PINCTRL_PIN(253, "R2 IDE DD8"),
PINCTRL_PIN(254, "R3 IDE DD7"),
......@@ -1306,7 +1306,7 @@ static const struct pinctrl_pin_desc gemini_3516_pins[] = {
PINCTRL_PIN(277, "P18 PCI AD1"),
PINCTRL_PIN(278, "P19 PCI AD3"),
PINCTRL_PIN(279, "P20 PCI AD5"),
/* Row R (for some reason Q us skipped) */
/* Row R (for some reason Q is skipped) */
PINCTRL_PIN(280, "R1 IDE DD13"),
PINCTRL_PIN(281, "R2 IDE DD12"),
PINCTRL_PIN(282, "R3 IDE DD10"),
......
......@@ -17,6 +17,7 @@
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/reset.h>
#include "core.h"
#include "pinconf.h"
......@@ -803,6 +804,7 @@ static int microchip_sgpio_probe(struct platform_device *pdev)
int div_clock = 0, ret, port, i, nbanks;
struct device *dev = &pdev->dev;
struct fwnode_handle *fwnode;
struct reset_control *reset;
struct sgpio_priv *priv;
struct clk *clk;
u32 val;
......@@ -813,6 +815,11 @@ static int microchip_sgpio_probe(struct platform_device *pdev)
priv->dev = dev;
reset = devm_reset_control_get_optional_shared(&pdev->dev, "switch");
if (IS_ERR(reset))
return dev_err_probe(dev, PTR_ERR(reset), "Failed to get reset\n");
reset_control_reset(reset);
clk = devm_clk_get(dev, NULL);
if (IS_ERR(clk))
return dev_err_probe(dev, PTR_ERR(clk), "Failed to get clock\n");
......
......@@ -1588,7 +1588,7 @@ static int st_pctl_probe_dt(struct platform_device *pdev,
st_pctl_dt_child_count(info, np);
if (!info->nbanks) {
dev_err(&pdev->dev, "you need atleast one gpio bank\n");
dev_err(&pdev->dev, "you need at least one gpio bank\n");
return -EINVAL;
}
......
......@@ -166,6 +166,14 @@ config PINCTRL_MSM8998
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm MSM8998 platform.
config PINCTRL_QCM2290
tristate "Qualcomm QCM2290 pin controller driver"
depends on OF
depends on PINCTRL_MSM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
TLMM block found in the Qualcomm QCM2290 platform.
config PINCTRL_QCS404
tristate "Qualcomm QCS404 pin controller driver"
depends on OF
......@@ -283,6 +291,15 @@ config PINCTRL_SM6125
Qualcomm Technologies Inc TLMM block found on the Qualcomm
Technologies Inc SM6125 platform.
config PINCTRL_SM6350
tristate "Qualcomm Technologies Inc SM6350 pin controller driver"
depends on GPIOLIB && OF
depends on PINCTRL_MSM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
Technologies Inc SM6350 platform.
config PINCTRL_SM8150
tristate "Qualcomm Technologies Inc SM8150 pin controller driver"
depends on OF
......
......@@ -17,6 +17,7 @@ obj-$(CONFIG_PINCTRL_MSM8976) += pinctrl-msm8976.o
obj-$(CONFIG_PINCTRL_MSM8994) += pinctrl-msm8994.o
obj-$(CONFIG_PINCTRL_MSM8996) += pinctrl-msm8996.o
obj-$(CONFIG_PINCTRL_MSM8998) += pinctrl-msm8998.o
obj-$(CONFIG_PINCTRL_QCM2290) += pinctrl-qcm2290.o
obj-$(CONFIG_PINCTRL_QCS404) += pinctrl-qcs404.o
obj-$(CONFIG_PINCTRL_QDF2XXX) += pinctrl-qdf2xxx.o
obj-$(CONFIG_PINCTRL_MDM9607) += pinctrl-mdm9607.o
......@@ -33,6 +34,7 @@ obj-$(CONFIG_PINCTRL_SDM845) += pinctrl-sdm845.o
obj-$(CONFIG_PINCTRL_SDX55) += pinctrl-sdx55.o
obj-$(CONFIG_PINCTRL_SM6115) += pinctrl-sm6115.o
obj-$(CONFIG_PINCTRL_SM6125) += pinctrl-sm6125.o
obj-$(CONFIG_PINCTRL_SM6350) += pinctrl-sm6350.o
obj-$(CONFIG_PINCTRL_SM8150) += pinctrl-sm8150.o
obj-$(CONFIG_PINCTRL_SM8250) += pinctrl-sm8250.o
obj-$(CONFIG_PINCTRL_SM8350) += pinctrl-sm8350.o
......
......@@ -338,26 +338,32 @@ static const unsigned int sdc2_data_pins[] = { 122 };
* the pingroup table below.
*/
enum msm8226_functions {
MSM_MUX_gpio,
MSM_MUX_cci_i2c0,
MSM_MUX_audio_pcm,
MSM_MUX_blsp_i2c1,
MSM_MUX_blsp_i2c2,
MSM_MUX_blsp_i2c3,
MSM_MUX_blsp_i2c4,
MSM_MUX_blsp_i2c5,
MSM_MUX_blsp_spi1,
MSM_MUX_blsp_spi2,
MSM_MUX_blsp_spi3,
MSM_MUX_blsp_spi4,
MSM_MUX_blsp_spi5,
MSM_MUX_blsp_uart1,
MSM_MUX_blsp_uart2,
MSM_MUX_blsp_uart3,
MSM_MUX_blsp_uart4,
MSM_MUX_blsp_uart5,
MSM_MUX_blsp_uim1,
MSM_MUX_blsp_uim2,
MSM_MUX_blsp_uim3,
MSM_MUX_blsp_uim4,
MSM_MUX_blsp_uim5,
MSM_MUX_cam_mclk0,
MSM_MUX_cam_mclk1,
MSM_MUX_cci_i2c0,
MSM_MUX_gpio,
MSM_MUX_sdc3,
MSM_MUX_wlan,
MSM_MUX_NA,
};
......@@ -382,6 +388,10 @@ static const char * const gpio_groups[] = {
"gpio111", "gpio112", "gpio113", "gpio114", "gpio115", "gpio116",
};
static const char * const audio_pcm_groups[] = {
"gpio63", "gpio64", "gpio65", "gpio66"
};
static const char * const blsp_uart1_groups[] = {
"gpio0", "gpio1", "gpio2", "gpio3"
};
......@@ -412,6 +422,16 @@ static const char * const blsp_spi3_groups[] = {
"gpio8", "gpio9", "gpio10", "gpio11"
};
static const char * const blsp_uart4_groups[] = {
"gpio12", "gpio13", "gpio14", "gpio15"
};
static const char * const blsp_uim4_groups[] = { "gpio12", "gpio13" };
static const char * const blsp_i2c4_groups[] = { "gpio14", "gpio15" };
static const char * const blsp_spi4_groups[] = {
"gpio12", "gpio13", "gpio14", "gpio15"
};
static const char * const blsp_uart5_groups[] = {
"gpio16", "gpio17", "gpio18", "gpio19"
};
......@@ -427,31 +447,41 @@ static const char * const cci_i2c0_groups[] = { "gpio29", "gpio30" };
static const char * const cam_mclk0_groups[] = { "gpio26" };
static const char * const cam_mclk1_groups[] = { "gpio27" };
static const char * const sdc3_groups[] = {
"gpio39", "gpio40", "gpio41", "gpio42", "gpio43", "gpio44"
};
static const char * const wlan_groups[] = {
"gpio40", "gpio41", "gpio42", "gpio43", "gpio44"
};
static const struct msm_function msm8226_functions[] = {
FUNCTION(gpio),
FUNCTION(cci_i2c0),
FUNCTION(blsp_uim1),
FUNCTION(blsp_uim2),
FUNCTION(blsp_uim3),
FUNCTION(blsp_uim5),
FUNCTION(audio_pcm),
FUNCTION(blsp_i2c1),
FUNCTION(blsp_i2c2),
FUNCTION(blsp_i2c3),
FUNCTION(blsp_i2c4),
FUNCTION(blsp_i2c5),
FUNCTION(blsp_spi1),
FUNCTION(blsp_spi2),
FUNCTION(blsp_spi3),
FUNCTION(blsp_spi4),
FUNCTION(blsp_spi5),
FUNCTION(blsp_uart1),
FUNCTION(blsp_uart2),
FUNCTION(blsp_uart3),
FUNCTION(blsp_uart4),
FUNCTION(blsp_uart5),
FUNCTION(blsp_uim1),
FUNCTION(blsp_uim2),
FUNCTION(blsp_uim3),
FUNCTION(blsp_uim4),
FUNCTION(blsp_uim5),
FUNCTION(cam_mclk0),
FUNCTION(cam_mclk1),
FUNCTION(cci_i2c0),
FUNCTION(gpio),
FUNCTION(sdc3),
FUNCTION(wlan),
};
......@@ -468,10 +498,10 @@ static const struct msm_pingroup msm8226_groups[] = {
PINGROUP(9, blsp_spi3, blsp_uart3, blsp_uim3, NA, NA, NA, NA),
PINGROUP(10, blsp_spi3, blsp_uart3, blsp_i2c3, NA, NA, NA, NA),
PINGROUP(11, blsp_spi3, blsp_uart3, blsp_i2c3, NA, NA, NA, NA),
PINGROUP(12, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(13, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(14, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(15, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(12, blsp_spi4, blsp_uart4, blsp_uim4, NA, NA, NA, NA),
PINGROUP(13, blsp_spi4, blsp_uart4, blsp_uim4, NA, NA, NA, NA),
PINGROUP(14, blsp_spi4, blsp_uart4, blsp_i2c4, NA, NA, NA, NA),
PINGROUP(15, blsp_spi4, blsp_uart4, blsp_i2c4, NA, NA, NA, NA),
PINGROUP(16, blsp_spi5, blsp_uart5, blsp_uim5, NA, NA, NA, NA),
PINGROUP(17, blsp_spi5, blsp_uart5, blsp_uim5, NA, NA, NA, NA),
PINGROUP(18, blsp_spi5, blsp_uart5, blsp_i2c5, NA, NA, NA, NA),
......@@ -495,12 +525,12 @@ static const struct msm_pingroup msm8226_groups[] = {
PINGROUP(36, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(37, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(38, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(39, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(40, wlan, NA, NA, NA, NA, NA, NA),
PINGROUP(41, wlan, NA, NA, NA, NA, NA, NA),
PINGROUP(42, wlan, NA, NA, NA, NA, NA, NA),
PINGROUP(43, wlan, NA, NA, NA, NA, NA, NA),
PINGROUP(44, wlan, NA, NA, NA, NA, NA, NA),
PINGROUP(39, NA, sdc3, NA, NA, NA, NA, NA),
PINGROUP(40, wlan, sdc3, NA, NA, NA, NA, NA),
PINGROUP(41, wlan, sdc3, NA, NA, NA, NA, NA),
PINGROUP(42, wlan, sdc3, NA, NA, NA, NA, NA),
PINGROUP(43, wlan, sdc3, NA, NA, NA, NA, NA),
PINGROUP(44, wlan, sdc3, NA, NA, NA, NA, NA),
PINGROUP(45, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(46, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(47, NA, NA, NA, NA, NA, NA, NA),
......@@ -519,10 +549,10 @@ static const struct msm_pingroup msm8226_groups[] = {
PINGROUP(60, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(61, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(62, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(63, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(64, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(65, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(66, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(63, audio_pcm, NA, NA, NA, NA, NA, NA),
PINGROUP(64, audio_pcm, NA, NA, NA, NA, NA, NA),
PINGROUP(65, audio_pcm, NA, NA, NA, NA, NA, NA),
PINGROUP(66, audio_pcm, NA, NA, NA, NA, NA, NA),
PINGROUP(67, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(68, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(69, NA, NA, NA, NA, NA, NA, NA),
......
此差异已折叠。
此差异已折叠。
......@@ -427,6 +427,9 @@ static int pmic_gpio_config_get(struct pinctrl_dev *pctldev,
return -EINVAL;
arg = 1;
break;
case PIN_CONFIG_OUTPUT_ENABLE:
arg = pad->output_enabled;
break;
case PIN_CONFIG_OUTPUT:
arg = pad->out_value;
break;
......@@ -506,6 +509,9 @@ static int pmic_gpio_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
case PIN_CONFIG_INPUT_ENABLE:
pad->input_enabled = arg ? true : false;
break;
case PIN_CONFIG_OUTPUT_ENABLE:
pad->output_enabled = arg ? true : false;
break;
case PIN_CONFIG_OUTPUT:
pad->output_enabled = true;
pad->out_value = arg;
......@@ -1141,6 +1147,7 @@ static const struct of_device_id pmic_gpio_of_match[] = {
{ .compatible = "qcom,pm660l-gpio", .data = (void *) 12 },
{ .compatible = "qcom,pm6150-gpio", .data = (void *) 10 },
{ .compatible = "qcom,pm6150l-gpio", .data = (void *) 12 },
{ .compatible = "qcom,pm6350-gpio", .data = (void *) 9 },
{ .compatible = "qcom,pm7325-gpio", .data = (void *) 10 },
{ .compatible = "qcom,pm8005-gpio", .data = (void *) 4 },
{ .compatible = "qcom,pm8008-gpio", .data = (void *) 2 },
......
......@@ -103,7 +103,6 @@
/**
* struct pmic_mpp_pad - keep current MPP settings
* @base: Address base in SPMI device.
* @irq: IRQ number which this MPP generate.
* @is_enabled: Set to false when MPP should be put in high Z state.
* @out_value: Cached pin output value.
* @output_enabled: Set to true if MPP output logic is enabled.
......@@ -121,7 +120,6 @@
*/
struct pmic_mpp_pad {
u16 base;
int irq;
bool is_enabled;
bool out_value;
bool output_enabled;
......@@ -143,6 +141,7 @@ struct pmic_mpp_state {
struct regmap *map;
struct pinctrl_dev *ctrl;
struct gpio_chip chip;
struct irq_chip irq;
};
static const struct pinconf_generic_params pmic_mpp_bindings[] = {
......@@ -622,16 +621,6 @@ static int pmic_mpp_of_xlate(struct gpio_chip *chip,
return gpio_desc->args[0] - PMIC_MPP_PHYSICAL_OFFSET;
}
static int pmic_mpp_to_irq(struct gpio_chip *chip, unsigned pin)
{
struct pmic_mpp_state *state = gpiochip_get_data(chip);
struct pmic_mpp_pad *pad;
pad = state->ctrl->desc->pins[pin].drv_data;
return pad->irq;
}
static void pmic_mpp_dbg_show(struct seq_file *s, struct gpio_chip *chip)
{
struct pmic_mpp_state *state = gpiochip_get_data(chip);
......@@ -651,7 +640,6 @@ static const struct gpio_chip pmic_mpp_gpio_template = {
.request = gpiochip_generic_request,
.free = gpiochip_generic_free,
.of_xlate = pmic_mpp_of_xlate,
.to_irq = pmic_mpp_to_irq,
.dbg_show = pmic_mpp_dbg_show,
};
......@@ -796,13 +784,53 @@ static int pmic_mpp_populate(struct pmic_mpp_state *state,
return 0;
}
static int pmic_mpp_domain_translate(struct irq_domain *domain,
struct irq_fwspec *fwspec,
unsigned long *hwirq,
unsigned int *type)
{
struct pmic_mpp_state *state = container_of(domain->host_data,
struct pmic_mpp_state,
chip);
if (fwspec->param_count != 2 ||
fwspec->param[0] < 1 || fwspec->param[0] > state->chip.ngpio)
return -EINVAL;
*hwirq = fwspec->param[0] - PMIC_MPP_PHYSICAL_OFFSET;
*type = fwspec->param[1];
return 0;
}
static unsigned int pmic_mpp_child_offset_to_irq(struct gpio_chip *chip,
unsigned int offset)
{
return offset + PMIC_MPP_PHYSICAL_OFFSET;
}
static int pmic_mpp_child_to_parent_hwirq(struct gpio_chip *chip,
unsigned int child_hwirq,
unsigned int child_type,
unsigned int *parent_hwirq,
unsigned int *parent_type)
{
*parent_hwirq = child_hwirq + 0xc0;
*parent_type = child_type;
return 0;
}
static int pmic_mpp_probe(struct platform_device *pdev)
{
struct irq_domain *parent_domain;
struct device_node *parent_node;
struct device *dev = &pdev->dev;
struct pinctrl_pin_desc *pindesc;
struct pinctrl_desc *pctrldesc;
struct pmic_mpp_pad *pad, *pads;
struct pmic_mpp_state *state;
struct gpio_irq_chip *girq;
int ret, npins, i;
u32 reg;
......@@ -812,11 +840,7 @@ static int pmic_mpp_probe(struct platform_device *pdev)
return ret;
}
npins = platform_irq_count(pdev);
if (!npins)
return -EINVAL;
if (npins < 0)
return npins;
npins = (uintptr_t) device_get_match_data(&pdev->dev);
BUG_ON(npins > ARRAY_SIZE(pmic_mpp_groups));
......@@ -861,10 +885,6 @@ static int pmic_mpp_probe(struct platform_device *pdev)
pindesc->number = i;
pindesc->name = pmic_mpp_groups[i];
pad->irq = platform_get_irq(pdev, i);
if (pad->irq < 0)
return pad->irq;
pad->base = reg + i * PMIC_MPP_ADDRESS_RANGE;
ret = pmic_mpp_populate(state, pad);
......@@ -884,6 +904,34 @@ static int pmic_mpp_probe(struct platform_device *pdev)
if (IS_ERR(state->ctrl))
return PTR_ERR(state->ctrl);
parent_node = of_irq_find_parent(state->dev->of_node);
if (!parent_node)
return -ENXIO;
parent_domain = irq_find_host(parent_node);
of_node_put(parent_node);
if (!parent_domain)
return -ENXIO;
state->irq.name = "spmi-mpp",
state->irq.irq_ack = irq_chip_ack_parent,
state->irq.irq_mask = irq_chip_mask_parent,
state->irq.irq_unmask = irq_chip_unmask_parent,
state->irq.irq_set_type = irq_chip_set_type_parent,
state->irq.irq_set_wake = irq_chip_set_wake_parent,
state->irq.flags = IRQCHIP_MASK_ON_SUSPEND,
girq = &state->chip.irq;
girq->chip = &state->irq;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_level_irq;
girq->fwnode = of_node_to_fwnode(state->dev->of_node);
girq->parent_domain = parent_domain;
girq->child_to_parent_hwirq = pmic_mpp_child_to_parent_hwirq;
girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_fourcell;
girq->child_offset_to_irq = pmic_mpp_child_offset_to_irq;
girq->child_irq_domain_ops.translate = pmic_mpp_domain_translate;
ret = gpiochip_add_data(&state->chip, state);
if (ret) {
dev_err(state->dev, "can't add gpio chip\n");
......@@ -912,16 +960,15 @@ static int pmic_mpp_remove(struct platform_device *pdev)
}
static const struct of_device_id pmic_mpp_of_match[] = {
{ .compatible = "qcom,pm8019-mpp" }, /* 6 MPP's */
{ .compatible = "qcom,pm8841-mpp" }, /* 4 MPP's */
{ .compatible = "qcom,pm8916-mpp" }, /* 4 MPP's */
{ .compatible = "qcom,pm8941-mpp" }, /* 8 MPP's */
{ .compatible = "qcom,pm8950-mpp" }, /* 4 MPP's */
{ .compatible = "qcom,pmi8950-mpp" }, /* 4 MPP's */
{ .compatible = "qcom,pm8994-mpp" }, /* 8 MPP's */
{ .compatible = "qcom,pma8084-mpp" }, /* 8 MPP's */
{ .compatible = "qcom,pmi8994-mpp" }, /* 4 MPP's */
{ .compatible = "qcom,spmi-mpp" }, /* Generic */
{ .compatible = "qcom,pm8019-mpp", .data = (void *) 6 },
{ .compatible = "qcom,pm8841-mpp", .data = (void *) 4 },
{ .compatible = "qcom,pm8916-mpp", .data = (void *) 4 },
{ .compatible = "qcom,pm8941-mpp", .data = (void *) 8 },
{ .compatible = "qcom,pm8950-mpp", .data = (void *) 4 },
{ .compatible = "qcom,pmi8950-mpp", .data = (void *) 4 },
{ .compatible = "qcom,pm8994-mpp", .data = (void *) 8 },
{ .compatible = "qcom,pma8084-mpp", .data = (void *) 8 },
{ .compatible = "qcom,pmi8994-mpp", .data = (void *) 4 },
{ },
};
......
......@@ -87,7 +87,6 @@
/**
* struct pm8xxx_pin_data - dynamic configuration for a pin
* @reg: address of the control register
* @irq: IRQ from the PMIC interrupt controller
* @mode: operating mode for the pin (digital, analog or current sink)
* @input: pin is input
* @output: pin is output
......@@ -103,7 +102,6 @@
*/
struct pm8xxx_pin_data {
unsigned reg;
int irq;
u8 mode;
......@@ -126,6 +124,7 @@ struct pm8xxx_mpp {
struct regmap *regmap;
struct pinctrl_dev *pctrl;
struct gpio_chip chip;
struct irq_chip irq;
struct pinctrl_desc desc;
unsigned npins;
......@@ -148,6 +147,8 @@ static const struct pin_config_item pm8xxx_conf_items[] = {
#endif
#define PM8XXX_MAX_MPPS 12
#define PM8XXX_MPP_PHYSICAL_OFFSET 1
static const char * const pm8xxx_groups[PM8XXX_MAX_MPPS] = {
"mpp1", "mpp2", "mpp3", "mpp4", "mpp5", "mpp6", "mpp7", "mpp8",
"mpp9", "mpp10", "mpp11", "mpp12",
......@@ -492,12 +493,16 @@ static int pm8xxx_mpp_get(struct gpio_chip *chip, unsigned offset)
struct pm8xxx_mpp *pctrl = gpiochip_get_data(chip);
struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
bool state;
int ret;
int ret, irq;
if (!pin->input)
return !!pin->output_value;
ret = irq_get_irqchip_state(pin->irq, IRQCHIP_STATE_LINE_LEVEL, &state);
irq = chip->to_irq(chip, offset);
if (irq < 0)
return irq;
ret = irq_get_irqchip_state(irq, IRQCHIP_STATE_LINE_LEVEL, &state);
if (!ret)
ret = !!state;
......@@ -524,18 +529,10 @@ static int pm8xxx_mpp_of_xlate(struct gpio_chip *chip,
if (flags)
*flags = gpio_desc->args[1];
return gpio_desc->args[0] - 1;
return gpio_desc->args[0] - PM8XXX_MPP_PHYSICAL_OFFSET;
}
static int pm8xxx_mpp_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct pm8xxx_mpp *pctrl = gpiochip_get_data(chip);
struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
return pin->irq;
}
#ifdef CONFIG_DEBUG_FS
#include <linux/seq_file.h>
......@@ -558,7 +555,7 @@ static void pm8xxx_mpp_dbg_show_one(struct seq_file *s,
"abus3",
};
seq_printf(s, " mpp%-2d:", offset + 1);
seq_printf(s, " mpp%-2d:", offset + PM8XXX_MPP_PHYSICAL_OFFSET);
switch (pin->mode) {
case PM8XXX_MPP_DIGITAL:
......@@ -640,7 +637,6 @@ static const struct gpio_chip pm8xxx_mpp_template = {
.get = pm8xxx_mpp_get,
.set = pm8xxx_mpp_set,
.of_xlate = pm8xxx_mpp_of_xlate,
.to_irq = pm8xxx_mpp_to_irq,
.dbg_show = pm8xxx_mpp_dbg_show,
.owner = THIS_MODULE,
};
......@@ -732,14 +728,62 @@ static int pm8xxx_pin_populate(struct pm8xxx_mpp *pctrl,
return 0;
}
static int pm8xxx_mpp_domain_translate(struct irq_domain *domain,
struct irq_fwspec *fwspec,
unsigned long *hwirq,
unsigned int *type)
{
struct pm8xxx_mpp *pctrl = container_of(domain->host_data,
struct pm8xxx_mpp, chip);
if (fwspec->param_count != 2 ||
fwspec->param[0] < PM8XXX_MPP_PHYSICAL_OFFSET ||
fwspec->param[0] > pctrl->chip.ngpio)
return -EINVAL;
*hwirq = fwspec->param[0] - PM8XXX_MPP_PHYSICAL_OFFSET;
*type = fwspec->param[1];
return 0;
}
static unsigned int pm8xxx_mpp_child_offset_to_irq(struct gpio_chip *chip,
unsigned int offset)
{
return offset + PM8XXX_MPP_PHYSICAL_OFFSET;
}
static int pm8821_mpp_child_to_parent_hwirq(struct gpio_chip *chip,
unsigned int child_hwirq,
unsigned int child_type,
unsigned int *parent_hwirq,
unsigned int *parent_type)
{
*parent_hwirq = child_hwirq + 24;
*parent_type = child_type;
return 0;
}
static int pm8xxx_mpp_child_to_parent_hwirq(struct gpio_chip *chip,
unsigned int child_hwirq,
unsigned int child_type,
unsigned int *parent_hwirq,
unsigned int *parent_type)
{
*parent_hwirq = child_hwirq + 0x80;
*parent_type = child_type;
return 0;
}
static const struct of_device_id pm8xxx_mpp_of_match[] = {
{ .compatible = "qcom,pm8018-mpp" },
{ .compatible = "qcom,pm8038-mpp" },
{ .compatible = "qcom,pm8058-mpp" },
{ .compatible = "qcom,pm8917-mpp" },
{ .compatible = "qcom,pm8821-mpp" },
{ .compatible = "qcom,pm8921-mpp" },
{ .compatible = "qcom,ssbi-mpp" },
{ .compatible = "qcom,pm8018-mpp", .data = (void *) 6 },
{ .compatible = "qcom,pm8038-mpp", .data = (void *) 6 },
{ .compatible = "qcom,pm8058-mpp", .data = (void *) 12 },
{ .compatible = "qcom,pm8821-mpp", .data = (void *) 4 },
{ .compatible = "qcom,pm8917-mpp", .data = (void *) 10 },
{ .compatible = "qcom,pm8921-mpp", .data = (void *) 12 },
{ },
};
MODULE_DEVICE_TABLE(of, pm8xxx_mpp_of_match);
......@@ -747,22 +791,20 @@ MODULE_DEVICE_TABLE(of, pm8xxx_mpp_of_match);
static int pm8xxx_mpp_probe(struct platform_device *pdev)
{
struct pm8xxx_pin_data *pin_data;
struct irq_domain *parent_domain;
struct device_node *parent_node;
struct pinctrl_pin_desc *pins;
struct gpio_irq_chip *girq;
struct pm8xxx_mpp *pctrl;
int ret;
int i, npins;
int i;
pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
if (!pctrl)
return -ENOMEM;
pctrl->dev = &pdev->dev;
npins = platform_irq_count(pdev);
if (!npins)
return -EINVAL;
if (npins < 0)
return npins;
pctrl->npins = npins;
pctrl->npins = (uintptr_t) device_get_match_data(&pdev->dev);
pctrl->regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!pctrl->regmap) {
......@@ -789,9 +831,6 @@ static int pm8xxx_mpp_probe(struct platform_device *pdev)
for (i = 0; i < pctrl->desc.npins; i++) {
pin_data[i].reg = SSBI_REG_ADDR_MPP(i);
pin_data[i].irq = platform_get_irq(pdev, i);
if (pin_data[i].irq < 0)
return pin_data[i].irq;
ret = pm8xxx_pin_populate(pctrl, &pin_data[i]);
if (ret)
......@@ -822,6 +861,36 @@ static int pm8xxx_mpp_probe(struct platform_device *pdev)
pctrl->chip.of_gpio_n_cells = 2;
pctrl->chip.label = dev_name(pctrl->dev);
pctrl->chip.ngpio = pctrl->npins;
parent_node = of_irq_find_parent(pctrl->dev->of_node);
if (!parent_node)
return -ENXIO;
parent_domain = irq_find_host(parent_node);
of_node_put(parent_node);
if (!parent_domain)
return -ENXIO;
pctrl->irq.name = "ssbi-mpp";
pctrl->irq.irq_mask_ack = irq_chip_mask_ack_parent;
pctrl->irq.irq_unmask = irq_chip_unmask_parent;
pctrl->irq.irq_set_type = irq_chip_set_type_parent;
pctrl->irq.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE;
girq = &pctrl->chip.irq;
girq->chip = &pctrl->irq;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_level_irq;
girq->fwnode = of_node_to_fwnode(pctrl->dev->of_node);
girq->parent_domain = parent_domain;
if (of_device_is_compatible(pdev->dev.of_node, "qcom,pm8821-mpp"))
girq->child_to_parent_hwirq = pm8821_mpp_child_to_parent_hwirq;
else
girq->child_to_parent_hwirq = pm8xxx_mpp_child_to_parent_hwirq;
girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_twocell;
girq->child_offset_to_irq = pm8xxx_mpp_child_offset_to_irq;
girq->child_irq_domain_ops.translate = pm8xxx_mpp_domain_translate;
ret = gpiochip_add_data(&pctrl->chip, pctrl);
if (ret) {
dev_err(&pdev->dev, "failed register gpiochip\n");
......
......@@ -675,8 +675,10 @@ static unsigned int sh_pfc_walk_regs(struct sh_pfc *pfc,
do_reg(pfc, pfc->info->drive_regs[i].reg, n++);
if (pfc->info->bias_regs)
for (i = 0; pfc->info->bias_regs[i].puen; i++) {
do_reg(pfc, pfc->info->bias_regs[i].puen, n++);
for (i = 0; pfc->info->bias_regs[i].puen ||
pfc->info->bias_regs[i].pud; i++) {
if (pfc->info->bias_regs[i].puen)
do_reg(pfc, pfc->info->bias_regs[i].puen, n++);
if (pfc->info->bias_regs[i].pud)
do_reg(pfc, pfc->info->bias_regs[i].pud, n++);
}
......@@ -741,12 +743,15 @@ static int sh_pfc_suspend_init(struct sh_pfc *pfc) { return 0; }
#define SH_PFC_MAX_REGS 300
#define SH_PFC_MAX_ENUMS 3000
static unsigned int sh_pfc_errors __initdata = 0;
static unsigned int sh_pfc_warnings __initdata = 0;
static u32 *sh_pfc_regs __initdata = NULL;
static u32 sh_pfc_num_regs __initdata = 0;
static u16 *sh_pfc_enums __initdata = NULL;
static u32 sh_pfc_num_enums __initdata = 0;
static unsigned int sh_pfc_errors __initdata;
static unsigned int sh_pfc_warnings __initdata;
static struct {
u32 reg;
u32 bits;
} *sh_pfc_regs __initdata;
static u32 sh_pfc_num_regs __initdata;
static u16 *sh_pfc_enums __initdata;
static u32 sh_pfc_num_enums __initdata;
#define sh_pfc_err(fmt, ...) \
do { \
......@@ -778,22 +783,30 @@ static bool __init same_name(const char *a, const char *b)
return !strcmp(a, b);
}
static void __init sh_pfc_check_reg(const char *drvname, u32 reg)
static void __init sh_pfc_check_reg(const char *drvname, u32 reg, u32 bits)
{
unsigned int i;
for (i = 0; i < sh_pfc_num_regs; i++)
if (reg == sh_pfc_regs[i]) {
sh_pfc_err("reg 0x%x conflict\n", reg);
return;
}
for (i = 0; i < sh_pfc_num_regs; i++) {
if (reg != sh_pfc_regs[i].reg)
continue;
if (bits & sh_pfc_regs[i].bits)
sh_pfc_err("reg 0x%x: bits 0x%x conflict\n", reg,
bits & sh_pfc_regs[i].bits);
sh_pfc_regs[i].bits |= bits;
return;
}
if (sh_pfc_num_regs == SH_PFC_MAX_REGS) {
pr_warn_once("%s: Please increase SH_PFC_MAX_REGS\n", drvname);
return;
}
sh_pfc_regs[sh_pfc_num_regs++] = reg;
sh_pfc_regs[sh_pfc_num_regs].reg = reg;
sh_pfc_regs[sh_pfc_num_regs].bits = bits;
sh_pfc_num_regs++;
}
static int __init sh_pfc_check_enum(const char *drvname, u16 enum_id)
......@@ -848,7 +861,8 @@ static void __init sh_pfc_check_cfg_reg(const char *drvname,
{
unsigned int i, n, rw, fw;
sh_pfc_check_reg(drvname, cfg_reg->reg);
sh_pfc_check_reg(drvname, cfg_reg->reg,
GENMASK(cfg_reg->reg_width - 1, 0));
if (cfg_reg->field_width) {
n = cfg_reg->reg_width / cfg_reg->field_width;
......@@ -879,22 +893,17 @@ static void __init sh_pfc_check_cfg_reg(const char *drvname,
static void __init sh_pfc_check_drive_reg(const struct sh_pfc_soc_info *info,
const struct pinmux_drive_reg *drive)
{
const char *drvname = info->name;
unsigned long seen = 0, mask;
unsigned int i;
sh_pfc_check_reg(info->name, drive->reg);
for (i = 0; i < ARRAY_SIZE(drive->fields); i++) {
const struct pinmux_drive_reg_field *field = &drive->fields[i];
if (!field->pin && !field->offset && !field->size)
continue;
mask = GENMASK(field->offset + field->size, field->offset);
if (mask & seen)
sh_pfc_err("drive_reg 0x%x: field %u overlap\n",
drive->reg, i);
seen |= mask;
sh_pfc_check_reg(info->name, drive->reg,
GENMASK(field->offset + field->size - 1,
field->offset));
sh_pfc_check_pin(info, drive->reg, field->pin);
}
......@@ -904,21 +913,28 @@ static void __init sh_pfc_check_bias_reg(const struct sh_pfc_soc_info *info,
const struct pinmux_bias_reg *bias)
{
unsigned int i;
u32 bits;
for (i = 0, bits = 0; i < ARRAY_SIZE(bias->pins); i++)
if (bias->pins[i] != SH_PFC_PIN_NONE)
bits |= BIT(i);
sh_pfc_check_reg(info->name, bias->puen);
if (bias->puen)
sh_pfc_check_reg(info->name, bias->puen, bits);
if (bias->pud)
sh_pfc_check_reg(info->name, bias->pud);
sh_pfc_check_reg(info->name, bias->pud, bits);
for (i = 0; i < ARRAY_SIZE(bias->pins); i++)
sh_pfc_check_pin(info, bias->puen, bias->pins[i]);
}
static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info)
{
const struct pinmux_bias_reg *bias_regs = info->bias_regs;
const char *drvname = info->name;
unsigned int *refcnts;
unsigned int i, j, k;
pr_info("Checking %s\n", drvname);
pr_info("sh_pfc: Checking %s\n", drvname);
sh_pfc_num_regs = 0;
sh_pfc_num_enums = 0;
......@@ -1010,16 +1026,17 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info)
sh_pfc_check_drive_reg(info, &info->drive_regs[i]);
/* Check bias registers */
for (i = 0; info->bias_regs && info->bias_regs[i].puen; i++)
sh_pfc_check_bias_reg(info, &info->bias_regs[i]);
for (i = 0; bias_regs && (bias_regs[i].puen || bias_regs[i].pud); i++)
sh_pfc_check_bias_reg(info, &bias_regs[i]);
/* Check ioctrl registers */
for (i = 0; info->ioctrl_regs && info->ioctrl_regs[i].reg; i++)
sh_pfc_check_reg(drvname, info->ioctrl_regs[i].reg);
sh_pfc_check_reg(drvname, info->ioctrl_regs[i].reg, U32_MAX);
/* Check data registers */
for (i = 0; info->data_regs && info->data_regs[i].reg; i++) {
sh_pfc_check_reg(drvname, info->data_regs[i].reg);
sh_pfc_check_reg(drvname, info->data_regs[i].reg,
GENMASK(info->data_regs[i].reg_width - 1, 0));
sh_pfc_check_reg_enums(drvname, info->data_regs[i].reg,
info->data_regs[i].enum_ids,
info->data_regs[i].reg_width);
......@@ -1064,7 +1081,7 @@ static void __init sh_pfc_check_driver(const struct platform_driver *pdrv)
if (!sh_pfc_enums)
goto free_regs;
pr_warn("Checking builtin pinmux tables\n");
pr_warn("sh_pfc: Checking builtin pinmux tables\n");
for (i = 0; pdrv->id_table[i].name[0]; i++)
sh_pfc_check_info((void *)pdrv->id_table[i].driver_data);
......@@ -1074,7 +1091,7 @@ static void __init sh_pfc_check_driver(const struct platform_driver *pdrv)
sh_pfc_check_info(pdrv->driver.of_match_table[i].data);
#endif
pr_warn("Detected %u errors and %u warnings\n", sh_pfc_errors,
pr_warn("sh_pfc: Detected %u errors and %u warnings\n", sh_pfc_errors,
sh_pfc_warnings);
kfree(sh_pfc_enums);
......
......@@ -2369,6 +2369,14 @@ static const unsigned int intc_ex_irq5_mux[] = {
IRQ5_MARK,
};
/* - MLB+ ------------------------------------------------------------------- */
static const unsigned int mlb_3pin_pins[] = {
RCAR_GP_PIN(5, 23), RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 25),
};
static const unsigned int mlb_3pin_mux[] = {
MLB_CLK_MARK, MLB_SIG_MARK, MLB_DAT_MARK,
};
/* - MSIOF0 ----------------------------------------------------------------- */
static const unsigned int msiof0_clk_pins[] = {
/* SCK */
......@@ -3987,6 +3995,7 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(intc_ex_irq3),
SH_PFC_PIN_GROUP(intc_ex_irq4),
SH_PFC_PIN_GROUP(intc_ex_irq5),
SH_PFC_PIN_GROUP(mlb_3pin),
SH_PFC_PIN_GROUP(msiof0_clk),
SH_PFC_PIN_GROUP(msiof0_sync),
SH_PFC_PIN_GROUP(msiof0_ss1),
......@@ -4380,6 +4389,10 @@ static const char * const intc_ex_groups[] = {
"intc_ex_irq5",
};
static const char * const mlb_3pin_groups[] = {
"mlb_3pin",
};
static const char * const msiof0_groups[] = {
"msiof0_clk",
"msiof0_sync",
......@@ -4709,6 +4722,7 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(i2c5),
SH_PFC_FUNCTION(i2c6),
SH_PFC_FUNCTION(intc_ex),
SH_PFC_FUNCTION(mlb_3pin),
SH_PFC_FUNCTION(msiof0),
SH_PFC_FUNCTION(msiof1),
SH_PFC_FUNCTION(msiof2),
......
......@@ -2453,6 +2453,16 @@ static const unsigned int intc_ex_irq5_mux[] = {
IRQ5_MARK,
};
#ifdef CONFIG_PINCTRL_PFC_R8A77951
/* - MLB+ ------------------------------------------------------------------- */
static const unsigned int mlb_3pin_pins[] = {
RCAR_GP_PIN(5, 23), RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 25),
};
static const unsigned int mlb_3pin_mux[] = {
MLB_CLK_MARK, MLB_SIG_MARK, MLB_DAT_MARK,
};
#endif /* CONFIG_PINCTRL_PFC_R8A77951 */
/* - MSIOF0 ----------------------------------------------------------------- */
static const unsigned int msiof0_clk_pins[] = {
/* SCK */
......@@ -4235,7 +4245,7 @@ static const unsigned int vin5_clk_mux[] = {
static const struct {
struct sh_pfc_pin_group common[328];
#ifdef CONFIG_PINCTRL_PFC_R8A77951
struct sh_pfc_pin_group automotive[30];
struct sh_pfc_pin_group automotive[31];
#endif
} pinmux_groups = {
.common = {
......@@ -4600,6 +4610,7 @@ static const struct {
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(mlb_3pin),
}
#endif /* CONFIG_PINCTRL_PFC_R8A77951 */
};
......@@ -4795,6 +4806,12 @@ static const char * const intc_ex_groups[] = {
"intc_ex_irq5",
};
#ifdef CONFIG_PINCTRL_PFC_R8A77951
static const char * const mlb_3pin_groups[] = {
"mlb_3pin",
};
#endif /* CONFIG_PINCTRL_PFC_R8A77951 */
static const char * const msiof0_groups[] = {
"msiof0_clk",
"msiof0_sync",
......@@ -5144,7 +5161,7 @@ static const char * const vin5_groups[] = {
static const struct {
struct sh_pfc_function common[55];
#ifdef CONFIG_PINCTRL_PFC_R8A77951
struct sh_pfc_function automotive[4];
struct sh_pfc_function automotive[5];
#endif
} pinmux_functions = {
.common = {
......@@ -5210,6 +5227,7 @@ static const struct {
SH_PFC_FUNCTION(drif1),
SH_PFC_FUNCTION(drif2),
SH_PFC_FUNCTION(drif3),
SH_PFC_FUNCTION(mlb_3pin),
}
#endif /* CONFIG_PINCTRL_PFC_R8A77951 */
};
......
......@@ -2458,6 +2458,16 @@ static const unsigned int intc_ex_irq5_mux[] = {
IRQ5_MARK,
};
#if defined(CONFIG_PINCTRL_PFC_R8A77960) || defined(CONFIG_PINCTRL_PFC_R8A77961)
/* - MLB+ ------------------------------------------------------------------- */
static const unsigned int mlb_3pin_pins[] = {
RCAR_GP_PIN(5, 23), RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 25),
};
static const unsigned int mlb_3pin_mux[] = {
MLB_CLK_MARK, MLB_SIG_MARK, MLB_DAT_MARK,
};
#endif /* CONFIG_PINCTRL_PFC_R8A77960 || CONFIG_PINCTRL_PFC_R8A77961 */
/* - MSIOF0 ----------------------------------------------------------------- */
static const unsigned int msiof0_clk_pins[] = {
/* SCK */
......@@ -4210,7 +4220,7 @@ static const unsigned int vin5_clk_mux[] = {
static const struct {
struct sh_pfc_pin_group common[324];
#if defined(CONFIG_PINCTRL_PFC_R8A77960) || defined(CONFIG_PINCTRL_PFC_R8A77961)
struct sh_pfc_pin_group automotive[30];
struct sh_pfc_pin_group automotive[31];
#endif
} pinmux_groups = {
.common = {
......@@ -4571,6 +4581,7 @@ static const struct {
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(mlb_3pin),
}
#endif /* CONFIG_PINCTRL_PFC_R8A77960 || CONFIG_PINCTRL_PFC_R8A77961 */
};
......@@ -4766,6 +4777,12 @@ static const char * const intc_ex_groups[] = {
"intc_ex_irq5",
};
#if defined(CONFIG_PINCTRL_PFC_R8A77960) || defined(CONFIG_PINCTRL_PFC_R8A77961)
static const char * const mlb_3pin_groups[] = {
"mlb_3pin",
};
#endif /* CONFIG_PINCTRL_PFC_R8A77960 || CONFIG_PINCTRL_PFC_R8A77961 */
static const char * const msiof0_groups[] = {
"msiof0_clk",
"msiof0_sync",
......@@ -5102,7 +5119,7 @@ static const char * const vin5_groups[] = {
static const struct {
struct sh_pfc_function common[52];
#if defined(CONFIG_PINCTRL_PFC_R8A77960) || defined(CONFIG_PINCTRL_PFC_R8A77961)
struct sh_pfc_function automotive[4];
struct sh_pfc_function automotive[5];
#endif
} pinmux_functions = {
.common = {
......@@ -5165,6 +5182,7 @@ static const struct {
SH_PFC_FUNCTION(drif1),
SH_PFC_FUNCTION(drif2),
SH_PFC_FUNCTION(drif3),
SH_PFC_FUNCTION(mlb_3pin),
}
#endif /* CONFIG_PINCTRL_PFC_R8A77960 || CONFIG_PINCTRL_PFC_R8A77961 */
};
......
......@@ -2609,6 +2609,16 @@ static const unsigned int intc_ex_irq5_mux[] = {
IRQ5_MARK,
};
#ifdef CONFIG_PINCTRL_PFC_R8A77965
/* - MLB+ ------------------------------------------------------------------- */
static const unsigned int mlb_3pin_pins[] = {
RCAR_GP_PIN(5, 23), RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 25),
};
static const unsigned int mlb_3pin_mux[] = {
MLB_CLK_MARK, MLB_SIG_MARK, MLB_DAT_MARK,
};
#endif /* CONFIG_PINCTRL_PFC_R8A77965 */
/* - MSIOF0 ----------------------------------------------------------------- */
static const unsigned int msiof0_clk_pins[] = {
/* SCK */
......@@ -4460,7 +4470,7 @@ static const unsigned int vin5_clk_mux[] = {
static const struct {
struct sh_pfc_pin_group common[326];
#ifdef CONFIG_PINCTRL_PFC_R8A77965
struct sh_pfc_pin_group automotive[30];
struct sh_pfc_pin_group automotive[31];
#endif
} pinmux_groups = {
.common = {
......@@ -4823,6 +4833,7 @@ static const struct {
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(mlb_3pin),
}
#endif /* CONFIG_PINCTRL_PFC_R8A77965 */
};
......@@ -5018,6 +5029,12 @@ static const char * const intc_ex_groups[] = {
"intc_ex_irq5",
};
#ifdef CONFIG_PINCTRL_PFC_R8A77965
static const char * const mlb_3pin_groups[] = {
"mlb_3pin",
};
#endif /* CONFIG_PINCTRL_PFC_R8A77965 */
static const char * const msiof0_groups[] = {
"msiof0_clk",
"msiof0_sync",
......@@ -5358,7 +5375,7 @@ static const char * const vin5_groups[] = {
static const struct {
struct sh_pfc_function common[53];
#ifdef CONFIG_PINCTRL_PFC_R8A77965
struct sh_pfc_function automotive[4];
struct sh_pfc_function automotive[5];
#endif
} pinmux_functions = {
.common = {
......@@ -5422,6 +5439,7 @@ static const struct {
SH_PFC_FUNCTION(drif1),
SH_PFC_FUNCTION(drif2),
SH_PFC_FUNCTION(drif3),
SH_PFC_FUNCTION(mlb_3pin),
}
#endif /* CONFIG_PINCTRL_PFC_R8A77965 */
};
......
......@@ -852,7 +852,7 @@ static const u32 rzg2l_gpio_configs[] = {
RZG2L_GPIO_PORT_PACK(2, 0x1e, RZG2L_MPXED_PIN_FUNCS),
RZG2L_GPIO_PORT_PACK(2, 0x1f, RZG2L_MPXED_PIN_FUNCS),
RZG2L_GPIO_PORT_PACK(2, 0x20, RZG2L_MPXED_PIN_FUNCS),
RZG2L_GPIO_PORT_PACK(3, 0x22, RZG2L_MPXED_PIN_FUNCS),
RZG2L_GPIO_PORT_PACK(3, 0x21, RZG2L_MPXED_PIN_FUNCS),
RZG2L_GPIO_PORT_PACK(2, 0x22, RZG2L_MPXED_PIN_FUNCS),
RZG2L_GPIO_PORT_PACK(2, 0x23, RZG2L_MPXED_PIN_FUNCS),
RZG2L_GPIO_PORT_PACK(3, 0x24, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IOLH_ETH0)),
......
......@@ -538,3 +538,111 @@ const struct samsung_pinctrl_of_match_data exynos850_of_data __initconst = {
.ctrl = exynos850_pin_ctrl,
.num_ctrl = ARRAY_SIZE(exynos850_pin_ctrl),
};
/* pin banks of exynosautov9 pin-controller 0 (ALIVE) */
static const struct samsung_pin_bank_data exynosautov9_pin_banks0[] __initconst = {
EXYNOS850_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00),
EXYNOS850_PIN_BANK_EINTW(2, 0x020, "gpa1", 0x04),
EXYNOS850_PIN_BANK_EINTN(2, 0x040, "gpq0"),
};
/* pin banks of exynosautov9 pin-controller 1 (AUD) */
static const struct samsung_pin_bank_data exynosautov9_pin_banks1[] __initconst = {
EXYNOS850_PIN_BANK_EINTG(5, 0x000, "gpb0", 0x00),
EXYNOS850_PIN_BANK_EINTG(8, 0x020, "gpb1", 0x04),
EXYNOS850_PIN_BANK_EINTG(8, 0x040, "gpb2", 0x08),
EXYNOS850_PIN_BANK_EINTG(8, 0x060, "gpb3", 0x0C),
};
/* pin banks of exynosautov9 pin-controller 2 (FSYS0) */
static const struct samsung_pin_bank_data exynosautov9_pin_banks2[] __initconst = {
EXYNOS850_PIN_BANK_EINTG(6, 0x000, "gpf0", 0x00),
EXYNOS850_PIN_BANK_EINTG(6, 0x020, "gpf1", 0x04),
};
/* pin banks of exynosautov9 pin-controller 3 (FSYS1) */
static const struct samsung_pin_bank_data exynosautov9_pin_banks3[] __initconst = {
EXYNOS850_PIN_BANK_EINTG(6, 0x000, "gpf8", 0x00),
};
/* pin banks of exynosautov9 pin-controller 4 (FSYS2) */
static const struct samsung_pin_bank_data exynosautov9_pin_banks4[] __initconst = {
EXYNOS850_PIN_BANK_EINTG(4, 0x000, "gpf2", 0x00),
EXYNOS850_PIN_BANK_EINTG(8, 0x020, "gpf3", 0x04),
EXYNOS850_PIN_BANK_EINTG(7, 0x040, "gpf4", 0x08),
EXYNOS850_PIN_BANK_EINTG(8, 0x060, "gpf5", 0x0C),
EXYNOS850_PIN_BANK_EINTG(7, 0x080, "gpf6", 0x10),
};
/* pin banks of exynosautov9 pin-controller 5 (PERIC0) */
static const struct samsung_pin_bank_data exynosautov9_pin_banks5[] __initconst = {
EXYNOS850_PIN_BANK_EINTG(8, 0x000, "gpp0", 0x00),
EXYNOS850_PIN_BANK_EINTG(8, 0x020, "gpp1", 0x04),
EXYNOS850_PIN_BANK_EINTG(8, 0x040, "gpp2", 0x08),
EXYNOS850_PIN_BANK_EINTG(5, 0x060, "gpg0", 0x0C),
};
/* pin banks of exynosautov9 pin-controller 6 (PERIC1) */
static const struct samsung_pin_bank_data exynosautov9_pin_banks6[] __initconst = {
EXYNOS850_PIN_BANK_EINTG(8, 0x000, "gpp3", 0x00),
EXYNOS850_PIN_BANK_EINTG(8, 0x020, "gpp4", 0x04),
EXYNOS850_PIN_BANK_EINTG(8, 0x040, "gpp5", 0x08),
EXYNOS850_PIN_BANK_EINTG(8, 0x060, "gpg1", 0x0C),
EXYNOS850_PIN_BANK_EINTG(8, 0x080, "gpg2", 0x10),
EXYNOS850_PIN_BANK_EINTG(4, 0x0A0, "gpg3", 0x14),
};
static const struct samsung_pin_ctrl exynosautov9_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 ALIVE data */
.pin_banks = exynosautov9_pin_banks0,
.nr_banks = ARRAY_SIZE(exynosautov9_pin_banks0),
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 1 AUD data */
.pin_banks = exynosautov9_pin_banks1,
.nr_banks = ARRAY_SIZE(exynosautov9_pin_banks1),
}, {
/* pin-controller instance 2 FSYS0 data */
.pin_banks = exynosautov9_pin_banks2,
.nr_banks = ARRAY_SIZE(exynosautov9_pin_banks2),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 3 FSYS1 data */
.pin_banks = exynosautov9_pin_banks3,
.nr_banks = ARRAY_SIZE(exynosautov9_pin_banks3),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 4 FSYS2 data */
.pin_banks = exynosautov9_pin_banks4,
.nr_banks = ARRAY_SIZE(exynosautov9_pin_banks4),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 5 PERIC0 data */
.pin_banks = exynosautov9_pin_banks5,
.nr_banks = ARRAY_SIZE(exynosautov9_pin_banks5),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 6 PERIC1 data */
.pin_banks = exynosautov9_pin_banks6,
.nr_banks = ARRAY_SIZE(exynosautov9_pin_banks6),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
},
};
const struct samsung_pinctrl_of_match_data exynosautov9_of_data __initconst = {
.ctrl = exynosautov9_pin_ctrl,
.num_ctrl = ARRAY_SIZE(exynosautov9_pin_ctrl),
};
......@@ -1266,6 +1266,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
.data = &exynos7_of_data },
{ .compatible = "samsung,exynos850-pinctrl",
.data = &exynos850_of_data },
{ .compatible = "samsung,exynosautov9-pinctrl",
.data = &exynosautov9_of_data },
#endif
#ifdef CONFIG_PINCTRL_S3C64XX
{ .compatible = "samsung,s3c64xx-pinctrl",
......
......@@ -340,6 +340,7 @@ extern const struct samsung_pinctrl_of_match_data exynos5420_of_data;
extern const struct samsung_pinctrl_of_match_data exynos5433_of_data;
extern const struct samsung_pinctrl_of_match_data exynos7_of_data;
extern const struct samsung_pinctrl_of_match_data exynos850_of_data;
extern const struct samsung_pinctrl_of_match_data exynosautov9_of_data;
extern const struct samsung_pinctrl_of_match_data s3c64xx_of_data;
extern const struct samsung_pinctrl_of_match_data s3c2412_of_data;
extern const struct samsung_pinctrl_of_match_data s3c2416_of_data;
......
......@@ -118,6 +118,7 @@ struct tegra_function {
* @slwr_width: Slew Rising field width.
* @slwf_bit: Slew Falling register bit.
* @slwf_width: Slew Falling field width.
* @lpdr_bit: Base driver enabling bit.
* @drvtype_bit: Drive type register bit.
* @parked_bitmask: Parked register mask. 0 if unsupported.
*
......@@ -161,6 +162,7 @@ struct tegra_pingroup {
s32 drvup_bit:6;
s32 slwr_bit:6;
s32 slwf_bit:6;
s32 lpdr_bit:6;
s32 drvtype_bit:6;
s32 drvdn_width:6;
s32 drvup_width:6;
......
......@@ -45,4 +45,8 @@ config PINCTRL_UNIPHIER_PXS3
bool "UniPhier PXs3 SoC pinctrl driver"
default ARM64
config PINCTRL_UNIPHIER_NX1
bool "UniPhier NX1 SoC pinctrl driver"
default ARM64
endif
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册