mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 01:24:47 +01:00
Pin control changes for the v7.0 kernel cycle:
Core changes:
- Drop the unused devm_pinctrl_unregister() function.
- Move pretended generic pin control functionality out of the
core and into the Amlogic AM4 driver. We have something better
coming (hopefully).
New hardware support:
- Spacemit K3 (RISC-V) pin control support.
- Atmel AT91 PIO4 (ARM32) SAMA7D65 pin control support.
- Exynos9610 (ARM64) pin control support.
- Qualcomm Mahua TLMM (ARM64) pin control support.
- Microchip Polarfire MSSIO (RISC-V) pin control support.
- Ocelot LAN9645XF (multiplatform) pin control support.
Improvements:
- Using a few more guards for locking.
- Various nonurgent fixes and tweaks.
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEElDRnuGcz/wPCXQWMQRCzN7AZXXMFAmmS7tgACgkQQRCzN7AZ
XXMnww/+ON7+DH8YA5+yI3fPdejv+6LK4es22B3r8bPVW4HtnfGxNqC7HZ8v9SWQ
H7BkSiEv0XLNVjKIV00WESeaK2V5MN9e52V2HfsSEDEheVdG7uA+9UVM7K2WkDnX
zhfucJdYHa1OEwcnrWMZl+6gAMw7cjuaG3ckNzay+okNme9kiyrnjFzT7NWoCut8
WBbzmpbMCtWdHMk7HSkPDF2LhyB7jVBbbH7qvjjrfxy1L+ybAf8tZJ6urwn+7uCZ
dEe5YYghre2SXi4j9v+WJ+8024RaXG//7JsZvUEGs7Kb9CZAcqAdHwUiRK/rLckj
anHoDEpall0yyH3gZA5ETn8Gw7vChAhm1CTfhUYcV9kc7/9MiShOE1UbBNvjXvCW
e+0zixRrBp0LzJEkJD7b2NhjMLHyXS3D/uN1l5+d04uFwskttVhtQ26Icz3P/3T/
aELNcIemwLQeAIy4btAWYu5dKE0IR80Z/nYozR7W+at9rzt9/8FleALScMXgPRMf
HfcdKj9/cDzFNYOVtPf20gVXqSm/Yv+ZPYTpq45jKDH8U393Ly3XmNXAYOhflf+i
Zt0KBSFf86/+u3Uo0EsQo+4JBK8FpEJT3qz6On7hXevbFiVZsXvfH0MU9up6s11d
zfW56C4mHe0anB8y5Kc0ZKuOt4MzMJm0OOuuiZqnpnK2xFLBmlU=
=lmwJ
-----END PGP SIGNATURE-----
Merge tag 'pinctrl-v7.0-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pin control updates from Linus Walleij:
"Core changes:
- Drop the unused devm_pinctrl_unregister() function
- Move pretended generic pin control functionality out of the core
and into the Amlogic AM4 driver. We have something better coming
(hopefully)
New hardware support:
- Spacemit K3 (RISC-V) pin control support
- Atmel AT91 PIO4 (ARM32) SAMA7D65 pin control support
- Exynos9610 (ARM64) pin control support
- Qualcomm Mahua TLMM (ARM64) pin control support
- Microchip Polarfire MSSIO (RISC-V) pin control support
- Ocelot LAN9645XF (multiplatform) pin control support
Improvements:
- Using a few more guards for locking
- Various nonurgent fixes and tweaks"
* tag 'pinctrl-v7.0-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (73 commits)
pinctrl: generic: move function to amlogic-am4 driver
pinctrl: intel: Align Copyright note with corporate guidelines
pinctrl: mediatek: remove unused drv_offset field
pinctrl: canaan: k230: Fix NULL pointer dereference when parsing devicetree
pinctrl: single: fix refcount leak in pcs_add_gpio_func()
pinctrl: meson: amlogic-a4: Fix device node reference leak in bank helpers
pinctrl: qcom: sm8250-lpass-lpi: Fix i2s2_data_groups definition
pinctrl: core: Remove duplicate error messages
pinctrl: core: Simplify devm_pinctrl_*()
pinctrl: core: Remove unused devm_pinctrl_unregister()
dt-bindings: pinctrl: spacemit: fix drive-strength check warning
pinctrl: fix kismet issues with GENERIC_PINCTRL
pinctrl: tangier: Join tng_pinctrl_probe() into its wrapper
pinctrl: tangier: Remove duplicate error messages
pinctrl: lynxpoint: Remove duplicate error messages
pinctrl: cherryview: Remove duplicate error messages
pinctrl: baytrail: Remove duplicate error messages
pinctrl: intel: Remove duplicate error messages
pinctrl: equilibrium: Fix device node reference leak in pinbank_init()
dt-bindings: pinctrl: pinctrl-microchip-sgpio: add LAN969x
...
This commit is contained in:
commit
46a1daac56
93 changed files with 2671 additions and 497 deletions
|
|
@ -106,7 +106,7 @@ patternProperties:
|
|||
# the pin numbers then,
|
||||
# - Finally, the name will end with either -pin or pins.
|
||||
|
||||
"^([rs]-)?(([a-z0-9]{3,}|[a-oq-z][a-z0-9]*?)?-)+?(p[a-ilm][0-9]*?-)??pins?$":
|
||||
"^([rs]-)?(([a-z0-9]{3,}|[a-oq-z0-9][a-z0-9]*?)?-)+?(p[a-ilm][0-9]*?-)??pins?$":
|
||||
type: object
|
||||
|
||||
properties:
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ properties:
|
|||
interrupts:
|
||||
description:
|
||||
Specifies the interrupt lines to be used by the controller.
|
||||
Each interrupt line is shared by upto 4 GPIO lines.
|
||||
Each interrupt line is shared by up to 4 GPIO lines.
|
||||
maxItems: 8
|
||||
|
||||
interrupt-controller: true
|
||||
|
|
|
|||
|
|
@ -0,0 +1,109 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/pinctrl/microchip,mpfs-pinctrl-mssio.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Microchip Polarfire SoC MSSIO pinctrl
|
||||
|
||||
maintainers:
|
||||
- Conor Dooley <conor.dooley@microchip.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: microchip,mpfs-pinctrl-mssio
|
||||
- items:
|
||||
- const: microchip,pic64gx-pinctrl-mssio
|
||||
- const: microchip,mpfs-pinctrl-mssio
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
pinctrl-use-default: true
|
||||
|
||||
patternProperties:
|
||||
'-cfg$':
|
||||
type: object
|
||||
additionalProperties: false
|
||||
|
||||
patternProperties:
|
||||
'-pins$':
|
||||
type: object
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- $ref: pincfg-node.yaml#
|
||||
- $ref: pinmux-node.yaml#
|
||||
|
||||
properties:
|
||||
pins:
|
||||
description:
|
||||
The list of IOs that properties in the pincfg node apply to.
|
||||
|
||||
function:
|
||||
description:
|
||||
A string containing the name of the function to mux for these
|
||||
pins. The "reserved" function tristates a pin.
|
||||
enum: [ sd, emmc, qspi, spi, usb, uart, i2c, can, mdio, misc
|
||||
reserved, gpio, fabric-test, tied-low, tied-high, tristate ]
|
||||
|
||||
bias-bus-hold: true
|
||||
bias-disable: true
|
||||
bias-pull-down: true
|
||||
bias-pull-up: true
|
||||
input-schmitt-enable: true
|
||||
low-power-enable: true
|
||||
|
||||
drive-strength:
|
||||
enum: [ 2, 4, 6, 8, 10, 12, 16, 20 ]
|
||||
|
||||
power-source:
|
||||
description:
|
||||
Which bank voltage to use. This cannot differ for pins in a
|
||||
given bank, the whole bank uses the same voltage.
|
||||
enum: [ 1200000, 1500000, 1800000, 2500000, 3300000 ]
|
||||
|
||||
microchip,clamp-diode:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description:
|
||||
Reflects the "Clamp Diode" setting in the MSS Configurator for
|
||||
this pin. This setting controls whether or not input voltage
|
||||
clamping should be enabled.
|
||||
|
||||
microchip,ibufmd:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
default: 0
|
||||
description:
|
||||
Reflects the "IBUFMD" bits in the MSS Configurator output files
|
||||
for this pin.
|
||||
|
||||
required:
|
||||
- pins
|
||||
- function
|
||||
- power-source
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
pinctrl@204 {
|
||||
compatible = "microchip,mpfs-pinctrl-mssio";
|
||||
reg = <0x204 0x7c>;
|
||||
|
||||
ikrd-spi1-cfg {
|
||||
spi1-pins {
|
||||
pins = <30>, <31>, <32>, <33>;
|
||||
function = "spi";
|
||||
bias-pull-up;
|
||||
drive-strength = <8>;
|
||||
power-source = <3300000>;
|
||||
microchip,ibufmd = <0x1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
@ -21,10 +21,15 @@ properties:
|
|||
pattern: '^gpio@[0-9a-f]+$'
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- microchip,sparx5-sgpio
|
||||
- mscc,ocelot-sgpio
|
||||
- mscc,luton-sgpio
|
||||
oneOf:
|
||||
- enum:
|
||||
- microchip,sparx5-sgpio
|
||||
- mscc,ocelot-sgpio
|
||||
- mscc,luton-sgpio
|
||||
- items:
|
||||
- enum:
|
||||
- microchip,lan9691-sgpio
|
||||
- const: microchip,sparx5-sgpio
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
|
@ -80,7 +85,12 @@ patternProperties:
|
|||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: microchip,sparx5-sgpio-bank
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- microchip,lan9691-sgpio-bank
|
||||
- const: microchip,sparx5-sgpio-bank
|
||||
- const: microchip,sparx5-sgpio-bank
|
||||
|
||||
reg:
|
||||
description: |
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ properties:
|
|||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- microchip,lan96455f-pinctrl
|
||||
- microchip,lan966x-pinctrl
|
||||
- microchip,lan9691-pinctrl
|
||||
- microchip,sparx5-pinctrl
|
||||
|
|
@ -30,6 +31,11 @@ properties:
|
|||
- microchip,lan9693-pinctrl
|
||||
- microchip,lan9692-pinctrl
|
||||
- const: microchip,lan9691-pinctrl
|
||||
- items:
|
||||
- enum:
|
||||
- microchip,lan96457f-pinctrl
|
||||
- microchip,lan96459f-pinctrl
|
||||
- const: microchip,lan96455f-pinctrl
|
||||
|
||||
reg:
|
||||
items:
|
||||
|
|
|
|||
|
|
@ -10,14 +10,16 @@ maintainers:
|
|||
- Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
|
||||
|
||||
description:
|
||||
Top Level Mode Multiplexer pin controller in Qualcomm Glymur SoC.
|
||||
Top Level Mode Multiplexer pin controller in Qualcomm Glymur and Mahua SoC.
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/pinctrl/qcom,tlmm-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,glymur-tlmm
|
||||
enum:
|
||||
- qcom,glymur-tlmm
|
||||
- qcom,mahua-tlmm
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -49,6 +49,17 @@ properties:
|
|||
gpio-ranges:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-controller: true
|
||||
|
||||
'#interrupt-cells':
|
||||
const: 2
|
||||
description:
|
||||
The first cell contains the global GPIO port index, constructed using the
|
||||
RZT2H_GPIO() helper macro from <dt-bindings/pinctrl/renesas,r9a09g077-pinctrl.h>
|
||||
and the second cell is used to specify the flag.
|
||||
E.g. "interrupts = <RZT2H_GPIO(8, 6) IRQ_TYPE_EDGE_FALLING>;" if P08_6 is
|
||||
being used as an interrupt.
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
|
|
@ -139,6 +150,8 @@ examples:
|
|||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
gpio-ranges = <&pinctrl 0 0 288>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
power-domains = <&cpg>;
|
||||
|
||||
serial0-pins {
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ properties:
|
|||
- enum:
|
||||
- google,gs101-wakeup-eint
|
||||
- samsung,exynos2200-wakeup-eint
|
||||
- samsung,exynos9610-wakeup-eint
|
||||
- samsung,exynos9810-wakeup-eint
|
||||
- samsung,exynos990-wakeup-eint
|
||||
- samsung,exynosautov9-wakeup-eint
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ properties:
|
|||
- samsung,exynos850-pinctrl
|
||||
- samsung,exynos8890-pinctrl
|
||||
- samsung,exynos8895-pinctrl
|
||||
- samsung,exynos9610-pinctrl
|
||||
- samsung,exynos9810-pinctrl
|
||||
- samsung,exynos990-pinctrl
|
||||
- samsung,exynosautov9-pinctrl
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@ maintainers:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
const: spacemit,k1-pinctrl
|
||||
enum:
|
||||
- spacemit,k1-pinctrl
|
||||
- spacemit,k3-pinctrl
|
||||
|
||||
reg:
|
||||
items:
|
||||
|
|
@ -30,6 +32,10 @@ properties:
|
|||
resets:
|
||||
maxItems: 1
|
||||
|
||||
spacemit,apbc:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: Phandle to syscon that access the protected register
|
||||
|
||||
patternProperties:
|
||||
'-cfg$':
|
||||
type: object
|
||||
|
|
@ -72,10 +78,20 @@ patternProperties:
|
|||
enum: [ 0, 1 ]
|
||||
|
||||
drive-strength:
|
||||
description: |
|
||||
typical current when output high level.
|
||||
1.8V output: 11, 21, 32, 42 (mA)
|
||||
3.3V output: 7, 10, 13, 16, 19, 23, 26, 29 (mA)
|
||||
description:
|
||||
typical current (in mA) when the output at high level.
|
||||
anyOf:
|
||||
- enum: [ 11, 21, 32, 42 ]
|
||||
description: For K1 SoC, 1.8V voltage output
|
||||
|
||||
- enum: [ 7, 10, 13, 16, 19, 23, 26, 29 ]
|
||||
description: For K1 SoC, 3.3V voltage output
|
||||
|
||||
- enum: [ 2, 4, 6, 7, 9, 11, 13, 14, 21, 23, 25, 26, 28, 30, 31, 33 ]
|
||||
description: For K3 SoC, 1.8V voltage output
|
||||
|
||||
- enum: [ 3, 5, 7, 9, 11, 13, 15, 17, 25, 27, 29, 31, 33, 35, 37, 38 ]
|
||||
description: For K3 SoC, 3.3V voltage output
|
||||
|
||||
input-schmitt:
|
||||
description: |
|
||||
|
|
@ -126,6 +142,7 @@ examples:
|
|||
clocks = <&syscon_apbc 42>,
|
||||
<&syscon_apbc 94>;
|
||||
clock-names = "func", "bus";
|
||||
spacemit,apbc = <&syscon_apbc>;
|
||||
|
||||
uart0_2_cfg: uart0-2-cfg {
|
||||
uart0-2-pins {
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ properties:
|
|||
type: object
|
||||
$ref: /schemas/pinctrl/microchip,mpfs-pinctrl-iomux0.yaml
|
||||
|
||||
pinctrl@204:
|
||||
type: object
|
||||
$ref: /schemas/pinctrl/microchip,mpfs-pinctrl-mssio.yaml
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
|
|
|||
|
|
@ -408,7 +408,6 @@ PINCTRL
|
|||
devm_pinctrl_get_select()
|
||||
devm_pinctrl_register()
|
||||
devm_pinctrl_register_and_init()
|
||||
devm_pinctrl_unregister()
|
||||
|
||||
POWER
|
||||
devm_reboot_mode_register()
|
||||
|
|
|
|||
|
|
@ -22666,6 +22666,7 @@ F: Documentation/devicetree/bindings/i2c/microchip,corei2c.yaml
|
|||
F: Documentation/devicetree/bindings/mailbox/microchip,mpfs-mailbox.yaml
|
||||
F: Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml
|
||||
F: Documentation/devicetree/bindings/pinctrl/microchip,mpfs-pinctrl-iomux0.yaml
|
||||
F: Documentation/devicetree/bindings/pinctrl/microchip,mpfs-pinctrl-mssio.yaml
|
||||
F: Documentation/devicetree/bindings/pinctrl/microchip,pic64gx-pinctrl-gpio2.yaml
|
||||
F: Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml
|
||||
F: Documentation/devicetree/bindings/riscv/microchip.yaml
|
||||
|
|
@ -22680,8 +22681,9 @@ F: drivers/gpio/gpio-mpfs.c
|
|||
F: drivers/i2c/busses/i2c-microchip-corei2c.c
|
||||
F: drivers/mailbox/mailbox-mpfs.c
|
||||
F: drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
F: drivers/pinctrl/pinctrl-mpfs-iomux0.c
|
||||
F: drivers/pinctrl/pinctrl-pic64gx-gpio2.c
|
||||
F: drivers/pinctrl/microchip/pinctrl-mpfs-iomux0.c
|
||||
F: drivers/pinctrl/microchip/pinctrl-mpfs-mssio.c
|
||||
F: drivers/pinctrl/microchip/pinctrl-pic64gx-gpio2.c
|
||||
F: drivers/pwm/pwm-microchip-core.c
|
||||
F: drivers/reset/reset-mpfs.c
|
||||
F: drivers/rtc/rtc-mpfs.c
|
||||
|
|
|
|||
|
|
@ -302,3 +302,12 @@ static inline int devtmpfs_delete_node(struct device *dev) { return 0; }
|
|||
|
||||
void software_node_notify(struct device *dev);
|
||||
void software_node_notify_remove(struct device *dev);
|
||||
|
||||
#ifdef CONFIG_PINCTRL
|
||||
int pinctrl_bind_pins(struct device *dev);
|
||||
#else
|
||||
static inline int pinctrl_bind_pins(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PINCTRL */
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "base.h"
|
||||
|
||||
/**
|
||||
* pinctrl_bind_pins() - called by the device core before probe
|
||||
* @dev: the device that is just about to probe
|
||||
|
|
|
|||
|
|
@ -25,6 +25,12 @@ config GENERIC_PINCONF
|
|||
bool
|
||||
select PINCONF
|
||||
|
||||
config GENERIC_PINCTRL
|
||||
bool
|
||||
select GENERIC_PINCONF
|
||||
select GENERIC_PINCTRL_GROUPS
|
||||
select GENERIC_PINMUX_FUNCTIONS
|
||||
|
||||
config DEBUG_PINCTRL
|
||||
bool "Debug PINCTRL calls"
|
||||
depends on DEBUG_KERNEL
|
||||
|
|
@ -486,16 +492,6 @@ config PINCTRL_PIC32MZDA
|
|||
def_bool y if PIC32MZDA
|
||||
select PINCTRL_PIC32
|
||||
|
||||
config PINCTRL_PIC64GX
|
||||
bool "pic64gx gpio2 pinctrl driver"
|
||||
depends on ARCH_MICROCHIP || COMPILE_TEST
|
||||
depends on OF
|
||||
select GENERIC_PINCONF
|
||||
select REGMAP_MMIO
|
||||
default y
|
||||
help
|
||||
This selects the pinctrl driver for gpio2 on pic64gx.
|
||||
|
||||
config PINCTRL_PISTACHIO
|
||||
bool "IMG Pistachio SoC pinctrl driver"
|
||||
depends on OF && (MIPS || COMPILE_TEST)
|
||||
|
|
@ -507,15 +503,6 @@ config PINCTRL_PISTACHIO
|
|||
help
|
||||
This support pinctrl and GPIO driver for IMG Pistachio SoC.
|
||||
|
||||
config PINCTRL_POLARFIRE_SOC
|
||||
bool "Polarfire SoC pinctrl driver"
|
||||
depends on ARCH_MICROCHIP || COMPILE_TEST
|
||||
depends on OF
|
||||
select GENERIC_PINCONF
|
||||
default y
|
||||
help
|
||||
This selects the pinctrl driver for Microchip Polarfire SoC.
|
||||
|
||||
config PINCTRL_RK805
|
||||
tristate "Pinctrl and GPIO driver for RK805 PMIC"
|
||||
depends on MFD_RK8XX
|
||||
|
|
@ -710,6 +697,7 @@ source "drivers/pinctrl/freescale/Kconfig"
|
|||
source "drivers/pinctrl/intel/Kconfig"
|
||||
source "drivers/pinctrl/mediatek/Kconfig"
|
||||
source "drivers/pinctrl/meson/Kconfig"
|
||||
source "drivers/pinctrl/microchip/Kconfig"
|
||||
source "drivers/pinctrl/mvebu/Kconfig"
|
||||
source "drivers/pinctrl/nomadik/Kconfig"
|
||||
source "drivers/pinctrl/nuvoton/Kconfig"
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ obj-y += core.o pinctrl-utils.o
|
|||
obj-$(CONFIG_PINMUX) += pinmux.o
|
||||
obj-$(CONFIG_PINCONF) += pinconf.o
|
||||
obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o
|
||||
obj-$(CONFIG_GENERIC_PINCTRL) += pinctrl-generic.o
|
||||
obj-$(CONFIG_OF) += devicetree.o
|
||||
|
||||
obj-$(CONFIG_PINCTRL_AMD) += pinctrl-amd.o
|
||||
|
|
@ -48,9 +49,7 @@ obj-$(CONFIG_PINCTRL_OCELOT) += pinctrl-ocelot.o
|
|||
obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o
|
||||
obj-$(CONFIG_PINCTRL_PEF2256) += pinctrl-pef2256.o
|
||||
obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-pic32.o
|
||||
obj-$(CONFIG_PINCTRL_PIC64GX) += pinctrl-pic64gx-gpio2.o
|
||||
obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o
|
||||
obj-$(CONFIG_PINCTRL_POLARFIRE_SOC) += pinctrl-mpfs-iomux0.o
|
||||
obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o
|
||||
obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
|
||||
obj-$(CONFIG_PINCTRL_RP1) += pinctrl-rp1.o
|
||||
|
|
@ -76,6 +75,7 @@ obj-y += freescale/
|
|||
obj-$(CONFIG_X86) += intel/
|
||||
obj-y += mediatek/
|
||||
obj-$(CONFIG_PINCTRL_MESON) += meson/
|
||||
obj-y += microchip/
|
||||
obj-y += mvebu/
|
||||
obj-y += nomadik/
|
||||
obj-y += nuvoton/
|
||||
|
|
|
|||
|
|
@ -6,14 +6,12 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/pinctrl/pinmux.h>
|
||||
#include <linux/pinctrl/pinconf.h>
|
||||
#include <linux/pinctrl/pinconf-generic.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "../core.h"
|
||||
|
|
|
|||
|
|
@ -7,14 +7,13 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/pinctrl/pinmux.h>
|
||||
#include <linux/pinctrl/pinconf.h>
|
||||
#include <linux/pinctrl/pinconf-generic.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "../core.h"
|
||||
|
|
@ -2654,9 +2653,7 @@ static struct regmap *aspeed_g5_acquire_regmap(struct aspeed_pinmux_data *ctx,
|
|||
np = of_parse_phandle(ctx->dev->of_node,
|
||||
"aspeed,external-nodes", 1);
|
||||
if (np) {
|
||||
if (!of_device_is_compatible(np->parent, "aspeed,ast2400-lpc-v2") &&
|
||||
!of_device_is_compatible(np->parent, "aspeed,ast2500-lpc-v2") &&
|
||||
!of_device_is_compatible(np->parent, "aspeed,ast2600-lpc-v2"))
|
||||
if (!of_device_is_compatible(np->parent, "aspeed,ast2500-lpc-v2"))
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
map = syscon_node_to_regmap(np->parent);
|
||||
|
|
|
|||
|
|
@ -4,13 +4,10 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/pinctrl/pinmux.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "../core.h"
|
||||
|
|
|
|||
|
|
@ -1383,9 +1383,9 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(pinctrl_select_state);
|
||||
|
||||
static void devm_pinctrl_release(struct device *dev, void *res)
|
||||
static void devm_pinctrl_release(void *p)
|
||||
{
|
||||
pinctrl_put(*(struct pinctrl **)res);
|
||||
pinctrl_put(p);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1397,31 +1397,21 @@ static void devm_pinctrl_release(struct device *dev, void *res)
|
|||
*/
|
||||
struct pinctrl *devm_pinctrl_get(struct device *dev)
|
||||
{
|
||||
struct pinctrl **ptr, *p;
|
||||
|
||||
ptr = devres_alloc(devm_pinctrl_release, sizeof(*ptr), GFP_KERNEL);
|
||||
if (!ptr)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
struct pinctrl *p;
|
||||
int ret;
|
||||
|
||||
p = pinctrl_get(dev);
|
||||
if (!IS_ERR(p)) {
|
||||
*ptr = p;
|
||||
devres_add(dev, ptr);
|
||||
} else {
|
||||
devres_free(ptr);
|
||||
}
|
||||
if (IS_ERR(p))
|
||||
return p;
|
||||
|
||||
ret = devm_add_action_or_reset(dev, devm_pinctrl_release, p);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return p;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_pinctrl_get);
|
||||
|
||||
static int devm_pinctrl_match(struct device *dev, void *res, void *data)
|
||||
{
|
||||
struct pinctrl **p = res;
|
||||
|
||||
return *p == data;
|
||||
}
|
||||
|
||||
/**
|
||||
* devm_pinctrl_put() - Resource managed pinctrl_put()
|
||||
* @p: the pinctrl handle to release
|
||||
|
|
@ -1432,8 +1422,7 @@ static int devm_pinctrl_match(struct device *dev, void *res, void *data)
|
|||
*/
|
||||
void devm_pinctrl_put(struct pinctrl *p)
|
||||
{
|
||||
WARN_ON(devres_release(p->dev, devm_pinctrl_release,
|
||||
devm_pinctrl_match, p));
|
||||
devm_release_action(p->dev, devm_pinctrl_release, p);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_pinctrl_put);
|
||||
|
||||
|
|
@ -2198,10 +2187,8 @@ int pinctrl_enable(struct pinctrl_dev *pctldev)
|
|||
int error;
|
||||
|
||||
error = pinctrl_claim_hogs(pctldev);
|
||||
if (error) {
|
||||
dev_err(pctldev->dev, "could not claim hogs: %i\n", error);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
mutex_lock(&pinctrldev_list_mutex);
|
||||
list_add_tail(&pctldev->node, &pinctrldev_list);
|
||||
|
|
@ -2316,23 +2303,11 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(pinctrl_unregister);
|
||||
|
||||
static void devm_pinctrl_dev_release(struct device *dev, void *res)
|
||||
static void devm_pinctrl_dev_release(void *pctldev)
|
||||
{
|
||||
struct pinctrl_dev *pctldev = *(struct pinctrl_dev **)res;
|
||||
|
||||
pinctrl_unregister(pctldev);
|
||||
}
|
||||
|
||||
static int devm_pinctrl_dev_match(struct device *dev, void *res, void *data)
|
||||
{
|
||||
struct pctldev **r = res;
|
||||
|
||||
if (WARN_ON(!r || !*r))
|
||||
return 0;
|
||||
|
||||
return *r == data;
|
||||
}
|
||||
|
||||
/**
|
||||
* devm_pinctrl_register() - Resource managed version of pinctrl_register().
|
||||
* @dev: parent device for this pin controller
|
||||
|
|
@ -2348,20 +2323,16 @@ struct pinctrl_dev *devm_pinctrl_register(struct device *dev,
|
|||
const struct pinctrl_desc *pctldesc,
|
||||
void *driver_data)
|
||||
{
|
||||
struct pinctrl_dev **ptr, *pctldev;
|
||||
|
||||
ptr = devres_alloc(devm_pinctrl_dev_release, sizeof(*ptr), GFP_KERNEL);
|
||||
if (!ptr)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
struct pinctrl_dev *pctldev;
|
||||
int ret;
|
||||
|
||||
pctldev = pinctrl_register(pctldesc, dev, driver_data);
|
||||
if (IS_ERR(pctldev)) {
|
||||
devres_free(ptr);
|
||||
if (IS_ERR(pctldev))
|
||||
return pctldev;
|
||||
}
|
||||
|
||||
*ptr = pctldev;
|
||||
devres_add(dev, ptr);
|
||||
ret = devm_add_action_or_reset(dev, devm_pinctrl_dev_release, pctldev);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return pctldev;
|
||||
}
|
||||
|
|
@ -2383,38 +2354,16 @@ int devm_pinctrl_register_and_init(struct device *dev,
|
|||
void *driver_data,
|
||||
struct pinctrl_dev **pctldev)
|
||||
{
|
||||
struct pinctrl_dev **ptr;
|
||||
int error;
|
||||
|
||||
ptr = devres_alloc(devm_pinctrl_dev_release, sizeof(*ptr), GFP_KERNEL);
|
||||
if (!ptr)
|
||||
return -ENOMEM;
|
||||
|
||||
error = pinctrl_register_and_init(pctldesc, dev, driver_data, pctldev);
|
||||
if (error) {
|
||||
devres_free(ptr);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
*ptr = *pctldev;
|
||||
devres_add(dev, ptr);
|
||||
|
||||
return 0;
|
||||
return devm_add_action_or_reset(dev, devm_pinctrl_dev_release, *pctldev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_pinctrl_register_and_init);
|
||||
|
||||
/**
|
||||
* devm_pinctrl_unregister() - Resource managed version of pinctrl_unregister().
|
||||
* @dev: device for which resource was allocated
|
||||
* @pctldev: the pinctrl device to unregister.
|
||||
*/
|
||||
void devm_pinctrl_unregister(struct device *dev, struct pinctrl_dev *pctldev)
|
||||
{
|
||||
WARN_ON(devres_release(dev, devm_pinctrl_dev_release,
|
||||
devm_pinctrl_dev_match, pctldev));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_pinctrl_unregister);
|
||||
|
||||
static int __init pinctrl_init(void)
|
||||
{
|
||||
pr_debug("initialized pinctrl subsystem\n");
|
||||
|
|
|
|||
|
|
@ -38,11 +38,12 @@ struct scmi_pinctrl_imx {
|
|||
};
|
||||
|
||||
/* SCMI pin control types, aligned with SCMI firmware */
|
||||
#define IMX_SCMI_NUM_CFG 4
|
||||
#define IMX_SCMI_NUM_CFG 5
|
||||
#define IMX_SCMI_PIN_MUX 192
|
||||
#define IMX_SCMI_PIN_CONFIG 193
|
||||
#define IMX_SCMI_PIN_DAISY_ID 194
|
||||
#define IMX_SCMI_PIN_DAISY_CFG 195
|
||||
#define IMX_SCMI_PIN_EXT 196
|
||||
|
||||
#define IMX_SCMI_NO_PAD_CTL BIT(31)
|
||||
#define IMX_SCMI_PAD_SION BIT(30)
|
||||
|
|
@ -50,8 +51,9 @@ struct scmi_pinctrl_imx {
|
|||
|
||||
#define IMX_SCMI_PIN_SIZE 24
|
||||
|
||||
#define IMX95_DAISY_OFF 0x408
|
||||
#define IMX94_DAISY_OFF 0x608
|
||||
#define IMX95_DAISY_OFF 0x408
|
||||
#define IMX952_DAISY_OFF 0x460
|
||||
|
||||
static int pinctrl_scmi_imx_dt_node_to_map(struct pinctrl_dev *pctldev,
|
||||
struct device_node *np,
|
||||
|
|
@ -73,6 +75,8 @@ static int pinctrl_scmi_imx_dt_node_to_map(struct pinctrl_dev *pctldev,
|
|||
daisy_off = IMX95_DAISY_OFF;
|
||||
} else if (of_machine_is_compatible("fsl,imx94")) {
|
||||
daisy_off = IMX94_DAISY_OFF;
|
||||
} else if (of_machine_is_compatible("fsl,imx952")) {
|
||||
daisy_off = IMX952_DAISY_OFF;
|
||||
} else {
|
||||
dev_err(pctldev->dev, "platform not support scmi pinctrl\n");
|
||||
return -EINVAL;
|
||||
|
|
@ -118,7 +122,14 @@ static int pinctrl_scmi_imx_dt_node_to_map(struct pinctrl_dev *pctldev,
|
|||
|
||||
pin_id = mux_reg / 4;
|
||||
|
||||
cfg[j++] = pinconf_to_config_packed(IMX_SCMI_PIN_MUX, mux_val);
|
||||
cfg[j++] = pinconf_to_config_packed(IMX_SCMI_PIN_MUX, (mux_val & 0xFF));
|
||||
|
||||
if (mux_val & 0xFF00) {
|
||||
int ext_val = (mux_val & 0xFF00) >> 8;
|
||||
|
||||
cfg[j++] = pinconf_to_config_packed(IMX_SCMI_PIN_EXT, ext_val);
|
||||
} else
|
||||
ncfg--;
|
||||
|
||||
if (!conf_reg || (conf_val & IMX_SCMI_NO_PAD_CTL))
|
||||
ncfg--;
|
||||
|
|
@ -291,8 +302,9 @@ scmi_pinctrl_imx_get_pins(struct scmi_pinctrl_imx *pmx, struct pinctrl_desc *des
|
|||
}
|
||||
|
||||
static const char * const scmi_pinctrl_imx_allowlist[] = {
|
||||
"fsl,imx95",
|
||||
"fsl,imx94",
|
||||
"fsl,imx95",
|
||||
"fsl,imx952",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ config PINCTRL_INTEL_PLATFORM
|
|||
of Intel PCH pins and using them as GPIOs. Currently the following
|
||||
Intel SoCs / platforms require this to be functional:
|
||||
- Lunar Lake
|
||||
- Nova Lake
|
||||
- Panther Lake
|
||||
|
||||
config PINCTRL_ALDERLAKE
|
||||
|
|
@ -52,7 +53,10 @@ config PINCTRL_ALDERLAKE
|
|||
select PINCTRL_INTEL
|
||||
help
|
||||
This pinctrl driver provides an interface that allows configuring
|
||||
of Intel Alder Lake PCH pins and using them as GPIOs.
|
||||
PCH pins of the following platforms and using them as GPIOs:
|
||||
- Alder Lake HX, N, and S
|
||||
- Raptor Lake HX, E, and S
|
||||
- Twin Lake
|
||||
|
||||
config PINCTRL_BROXTON
|
||||
tristate "Intel Broxton pinctrl and GPIO driver"
|
||||
|
|
@ -136,15 +140,17 @@ config PINCTRL_METEORLAKE
|
|||
select PINCTRL_INTEL
|
||||
help
|
||||
This pinctrl driver provides an interface that allows configuring
|
||||
of Intel Meteor Lake pins and using them as GPIOs.
|
||||
SoC pins of the following platforms and using them as GPIOs:
|
||||
- Arrow Lake (all variants)
|
||||
- Meteor Lake (all variants)
|
||||
|
||||
config PINCTRL_METEORPOINT
|
||||
tristate "Intel Meteor Point pinctrl and GPIO driver"
|
||||
select PINCTRL_INTEL
|
||||
help
|
||||
Meteor Point is the PCH of Intel Meteor Lake. This pinctrl driver
|
||||
provides an interface that allows configuring of PCH pins and
|
||||
using them as GPIOs.
|
||||
This pinctrl driver provides an interface that allows configuring
|
||||
PCH pins of the following platforms and using them as GPIOs:
|
||||
- Arrow Lake HX and S
|
||||
|
||||
config PINCTRL_SUNRISEPOINT
|
||||
tristate "Intel Sunrisepoint pinctrl and GPIO driver"
|
||||
|
|
@ -159,7 +165,11 @@ config PINCTRL_TIGERLAKE
|
|||
select PINCTRL_INTEL
|
||||
help
|
||||
This pinctrl driver provides an interface that allows configuring
|
||||
of Intel Tiger Lake PCH pins and using them as GPIOs.
|
||||
PCH pins of the following platforms and using them as GPIOs:
|
||||
- Alder Lake H, P, PS, and U
|
||||
- Raptor Lake H, P, PS, PX, and U
|
||||
- Rocket Lake S
|
||||
- Tiger Lake (all variants)
|
||||
|
||||
source "drivers/pinctrl/intel/Kconfig.tng"
|
||||
endmenu
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Alder Lake PCH pinctrl/GPIO driver
|
||||
*
|
||||
* Copyright (C) 2020, 2022 Intel Corporation
|
||||
* Copyright (C) 2020-2022 Intel Corporation
|
||||
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Pinctrl GPIO driver for Intel Baytrail
|
||||
*
|
||||
* Copyright (c) 2012-2013, Intel Corporation
|
||||
* Copyright (C) 2012-2013 Intel Corporation
|
||||
* Author: Mathias Nyman <mathias.nyman@linux.intel.com>
|
||||
*/
|
||||
|
||||
|
|
@ -101,10 +101,12 @@ struct intel_pad_context {
|
|||
u32 val;
|
||||
};
|
||||
|
||||
#define COMMUNITY(p, n, map) \
|
||||
#define BYT_COMMUNITY(p, n, g, map) \
|
||||
{ \
|
||||
.pin_base = (p), \
|
||||
.npins = (n), \
|
||||
.gpps = (g), \
|
||||
.ngpps = ARRAY_SIZE(g), \
|
||||
.pad_map = (map),\
|
||||
}
|
||||
|
||||
|
|
@ -360,8 +362,15 @@ static const struct intel_function byt_score_functions[] = {
|
|||
FUNCTION("gpio", byt_score_gpio_groups),
|
||||
};
|
||||
|
||||
static const struct intel_padgroup byt_score_gpps[] = {
|
||||
INTEL_GPP(0, 0, 31, 0),
|
||||
INTEL_GPP(1, 32, 63, 32),
|
||||
INTEL_GPP(2, 64, 95, 64),
|
||||
INTEL_GPP(3, 96, 101, 96),
|
||||
};
|
||||
|
||||
static const struct intel_community byt_score_communities[] = {
|
||||
COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map),
|
||||
BYT_COMMUNITY(0, 102, byt_score_gpps, byt_score_pins_map),
|
||||
};
|
||||
|
||||
static const struct intel_pinctrl_soc_data byt_score_soc_data = {
|
||||
|
|
@ -483,8 +492,13 @@ static const struct intel_function byt_sus_functions[] = {
|
|||
FUNCTION("pmu_clk", byt_sus_pmu_clk_groups),
|
||||
};
|
||||
|
||||
static const struct intel_padgroup byt_sus_gpps[] = {
|
||||
INTEL_GPP(0, 0, 31, 0),
|
||||
INTEL_GPP(1, 32, 43, 32),
|
||||
};
|
||||
|
||||
static const struct intel_community byt_sus_communities[] = {
|
||||
COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map),
|
||||
BYT_COMMUNITY(0, 44, byt_sus_gpps, byt_sus_pins_map),
|
||||
};
|
||||
|
||||
static const struct intel_pinctrl_soc_data byt_sus_soc_data = {
|
||||
|
|
@ -536,8 +550,12 @@ static const unsigned int byt_ncore_pins_map[BYT_NGPIO_NCORE] = {
|
|||
3, 6, 10, 13, 2, 5, 9, 7,
|
||||
};
|
||||
|
||||
static const struct intel_padgroup byt_ncore_gpps[] = {
|
||||
INTEL_GPP(0, 0, 27, 0),
|
||||
};
|
||||
|
||||
static const struct intel_community byt_ncore_communities[] = {
|
||||
COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map),
|
||||
BYT_COMMUNITY(0, 28, byt_ncore_gpps, byt_ncore_pins_map),
|
||||
};
|
||||
|
||||
static const struct intel_pinctrl_soc_data byt_ncore_soc_data = {
|
||||
|
|
@ -1490,19 +1508,6 @@ static int byt_gpio_irq_init_hw(struct gpio_chip *chip)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int byt_gpio_add_pin_ranges(struct gpio_chip *chip)
|
||||
{
|
||||
struct intel_pinctrl *vg = gpiochip_get_data(chip);
|
||||
struct device *dev = vg->dev;
|
||||
int ret;
|
||||
|
||||
ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, vg->soc->npins);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to add GPIO pin range\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int byt_gpio_probe(struct intel_pinctrl *vg)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(vg->dev);
|
||||
|
|
@ -1515,7 +1520,7 @@ static int byt_gpio_probe(struct intel_pinctrl *vg)
|
|||
gc->label = dev_name(vg->dev);
|
||||
gc->base = -1;
|
||||
gc->can_sleep = false;
|
||||
gc->add_pin_ranges = byt_gpio_add_pin_ranges;
|
||||
gc->add_pin_ranges = intel_gpio_add_pin_ranges;
|
||||
gc->parent = vg->dev;
|
||||
gc->ngpio = vg->soc->npins;
|
||||
|
||||
|
|
@ -1611,7 +1616,7 @@ static int byt_pinctrl_probe(struct platform_device *pdev)
|
|||
|
||||
vg->pctldev = devm_pinctrl_register(dev, &vg->pctldesc, vg);
|
||||
if (IS_ERR(vg->pctldev))
|
||||
return dev_err_probe(dev, PTR_ERR(vg->pctldev), "failed to register pinctrl\n");
|
||||
return PTR_ERR(vg->pctldev);
|
||||
|
||||
ret = byt_gpio_probe(vg);
|
||||
if (ret)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Broxton SoC pinctrl/GPIO driver
|
||||
*
|
||||
* Copyright (C) 2015, 2016 Intel Corporation
|
||||
* Copyright (C) 2015-2016 Intel Corporation
|
||||
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Cannon Lake PCH pinctrl/GPIO driver
|
||||
*
|
||||
* Copyright (C) 2017, Intel Corporation
|
||||
* Copyright (C) 2017 Intel Corporation
|
||||
* Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
* Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Cedar Fork PCH pinctrl/GPIO driver
|
||||
*
|
||||
* Copyright (C) 2017, Intel Corporation
|
||||
* Copyright (C) 2017 Intel Corporation
|
||||
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Cherryview/Braswell pinctrl driver
|
||||
*
|
||||
* Copyright (C) 2014, 2020 Intel Corporation
|
||||
* Copyright (C) 2014-2020 Intel Corporation
|
||||
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
*
|
||||
* This driver is based on the original Cherryview GPIO driver by
|
||||
|
|
@ -1644,7 +1644,7 @@ static int chv_pinctrl_probe(struct platform_device *pdev)
|
|||
|
||||
pctrl->pctldev = devm_pinctrl_register(dev, &pctrl->pctldesc, pctrl);
|
||||
if (IS_ERR(pctrl->pctldev))
|
||||
return dev_err_probe(dev, PTR_ERR(pctrl->pctldev), "failed to register pinctrl\n");
|
||||
return PTR_ERR(pctrl->pctldev);
|
||||
|
||||
ret = chv_gpio_probe(pctrl, irq);
|
||||
if (ret)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Denverton SoC pinctrl/GPIO driver
|
||||
*
|
||||
* Copyright (C) 2017, Intel Corporation
|
||||
* Copyright (C) 2017 Intel Corporation
|
||||
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Elkhart Lake PCH pinctrl/GPIO driver
|
||||
*
|
||||
* Copyright (C) 2019, Intel Corporation
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Emmitsburg PCH pinctrl/GPIO driver
|
||||
*
|
||||
* Copyright (C) 2020, Intel Corporation
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Ice Lake PCH pinctrl/GPIO driver
|
||||
*
|
||||
* Copyright (C) 2018, 2022 Intel Corporation
|
||||
* Copyright (C) 2018-2022 Intel Corporation
|
||||
* Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
* Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel PCH pinctrl/GPIO driver
|
||||
*
|
||||
* Copyright (C) 2021-2023, Intel Corporation
|
||||
* Copyright (C) 2021-2023 Intel Corporation
|
||||
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel pinctrl/GPIO core driver.
|
||||
*
|
||||
* Copyright (C) 2015, Intel Corporation
|
||||
* Copyright (C) 2015 Intel Corporation
|
||||
* Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
|
||||
* Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
*/
|
||||
|
|
@ -1673,7 +1673,7 @@ int intel_pinctrl_probe(struct platform_device *pdev,
|
|||
|
||||
pctrl->pctldev = devm_pinctrl_register(dev, &pctrl->pctldesc, pctrl);
|
||||
if (IS_ERR(pctrl->pctldev))
|
||||
return dev_err_probe(dev, PTR_ERR(pctrl->pctldev), "failed to register pinctrl\n");
|
||||
return PTR_ERR(pctrl->pctldev);
|
||||
|
||||
ret = intel_gpio_probe(pctrl, irq);
|
||||
if (ret)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Core pinctrl/GPIO driver for Intel GPIO controllers
|
||||
*
|
||||
* Copyright (C) 2015, Intel Corporation
|
||||
* Copyright (C) 2015 Intel Corporation
|
||||
* Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
|
||||
* Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Jasper Lake PCH pinctrl/GPIO driver
|
||||
*
|
||||
* Copyright (C) 2020, Intel Corporation
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Lakefield PCH pinctrl/GPIO driver
|
||||
*
|
||||
* Copyright (C) 2020, Intel Corporation
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Lewisburg pinctrl/GPIO driver
|
||||
*
|
||||
* Copyright (C) 2017, Intel Corporation
|
||||
* Copyright (C) 2017 Intel Corporation
|
||||
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Lynxpoint PCH pinctrl/GPIO driver
|
||||
*
|
||||
* Copyright (c) 2012, 2019, Intel Corporation
|
||||
* Copyright (C) 2012-2019 Intel Corporation
|
||||
* Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
|
||||
* Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
*/
|
||||
|
|
@ -29,10 +29,12 @@
|
|||
|
||||
#include "pinctrl-intel.h"
|
||||
|
||||
#define COMMUNITY(p, n) \
|
||||
#define LPTLP_COMMUNITY(p, n, g) \
|
||||
{ \
|
||||
.pin_base = (p), \
|
||||
.npins = (n), \
|
||||
.gpps = (g), \
|
||||
.ngpps = ARRAY_SIZE(g), \
|
||||
}
|
||||
|
||||
static const struct pinctrl_pin_desc lptlp_pins[] = {
|
||||
|
|
@ -133,8 +135,14 @@ static const struct pinctrl_pin_desc lptlp_pins[] = {
|
|||
PINCTRL_PIN(94, "GP94_UART0_CTSB"),
|
||||
};
|
||||
|
||||
static const struct intel_padgroup lptlp_gpps[] = {
|
||||
INTEL_GPP(0, 0, 31, 0),
|
||||
INTEL_GPP(1, 32, 63, 32),
|
||||
INTEL_GPP(2, 64, 94, 64),
|
||||
};
|
||||
|
||||
static const struct intel_community lptlp_communities[] = {
|
||||
COMMUNITY(0, 95),
|
||||
LPTLP_COMMUNITY(0, 95, lptlp_gpps),
|
||||
};
|
||||
|
||||
static const struct intel_pinctrl_soc_data lptlp_soc_data = {
|
||||
|
|
@ -692,19 +700,6 @@ static int lp_gpio_irq_init_hw(struct gpio_chip *chip)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lp_gpio_add_pin_ranges(struct gpio_chip *chip)
|
||||
{
|
||||
struct intel_pinctrl *lg = gpiochip_get_data(chip);
|
||||
struct device *dev = lg->dev;
|
||||
int ret;
|
||||
|
||||
ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, lg->soc->npins);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to add GPIO pin range\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct intel_pinctrl_soc_data *soc;
|
||||
|
|
@ -740,7 +735,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
|
|||
|
||||
lg->pctldev = devm_pinctrl_register(dev, &lg->pctldesc, lg);
|
||||
if (IS_ERR(lg->pctldev))
|
||||
return dev_err_probe(dev, PTR_ERR(lg->pctldev), "failed to register pinctrl\n");
|
||||
return PTR_ERR(lg->pctldev);
|
||||
|
||||
platform_set_drvdata(pdev, lg);
|
||||
|
||||
|
|
@ -777,7 +772,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
|
|||
gc->base = -1;
|
||||
gc->ngpio = LP_NUM_GPIO;
|
||||
gc->can_sleep = false;
|
||||
gc->add_pin_ranges = lp_gpio_add_pin_ranges;
|
||||
gc->add_pin_ranges = intel_gpio_add_pin_ranges;
|
||||
gc->parent = dev;
|
||||
|
||||
/* set up interrupts */
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Merrifield SoC pinctrl driver
|
||||
*
|
||||
* Copyright (C) 2016, Intel Corporation
|
||||
* Copyright (C) 2016 Intel Corporation
|
||||
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Meteor Lake PCH pinctrl/GPIO driver
|
||||
*
|
||||
* Copyright (C) 2022, Intel Corporation
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Meteor Point PCH pinctrl/GPIO driver
|
||||
*
|
||||
* Copyright (C) 2022-2023, Intel Corporation
|
||||
* Copyright (C) 2022-2023 Intel Corporation
|
||||
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Moorefield SoC pinctrl driver
|
||||
*
|
||||
* Copyright (C) 2022, Intel Corporation
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Sunrisepoint PCH pinctrl/GPIO driver
|
||||
*
|
||||
* Copyright (C) 2015, Intel Corporation
|
||||
* Copyright (C) 2015 Intel Corporation
|
||||
* Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
|
||||
* Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Tangier pinctrl driver
|
||||
*
|
||||
* Copyright (C) 2016, 2023 Intel Corporation
|
||||
* Copyright (C) 2016-2023 Intel Corporation
|
||||
*
|
||||
* Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
* Raag Jadav <raag.jadav@intel.com>
|
||||
|
|
@ -518,15 +518,19 @@ static const struct pinctrl_desc tng_pinctrl_desc = {
|
|||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int tng_pinctrl_probe(struct platform_device *pdev,
|
||||
const struct tng_pinctrl *data)
|
||||
int devm_tng_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
const struct tng_pinctrl *data;
|
||||
struct tng_family *families;
|
||||
struct tng_pinctrl *tp;
|
||||
void __iomem *regs;
|
||||
unsigned int i;
|
||||
|
||||
data = device_get_match_data(dev);
|
||||
if (!data)
|
||||
return -ENODATA;
|
||||
|
||||
tp = devm_kmemdup(dev, data, sizeof(*data), GFP_KERNEL);
|
||||
if (!tp)
|
||||
return -ENOMEM;
|
||||
|
|
@ -562,21 +566,10 @@ static int tng_pinctrl_probe(struct platform_device *pdev,
|
|||
|
||||
tp->pctldev = devm_pinctrl_register(dev, &tp->pctldesc, tp);
|
||||
if (IS_ERR(tp->pctldev))
|
||||
return dev_err_probe(dev, PTR_ERR(tp->pctldev), "failed to register pinctrl\n");
|
||||
return PTR_ERR(tp->pctldev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int devm_tng_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct tng_pinctrl *data;
|
||||
|
||||
data = device_get_match_data(&pdev->dev);
|
||||
if (!data)
|
||||
return -ENODATA;
|
||||
|
||||
return tng_pinctrl_probe(pdev, data);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(devm_tng_pinctrl_probe, "PINCTRL_TANGIER");
|
||||
|
||||
MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Tangier pinctrl functions
|
||||
*
|
||||
* Copyright (C) 2016, 2023 Intel Corporation
|
||||
* Copyright (C) 2016-2023 Intel Corporation
|
||||
*
|
||||
* Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
* Raag Jadav <raag.jadav@intel.com>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Tiger Lake PCH pinctrl/GPIO driver
|
||||
*
|
||||
* Copyright (C) 2019 - 2020, Intel Corporation
|
||||
* Copyright (C) 2019-2020 Intel Corporation
|
||||
* Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
* Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -544,24 +544,32 @@ int mtk_eint_do_init(struct mtk_eint *eint, struct mtk_eint_pin *eint_pin)
|
|||
}
|
||||
}
|
||||
|
||||
eint->pin_list = devm_kmalloc(eint->dev, eint->nbase * sizeof(u16 *), GFP_KERNEL);
|
||||
eint->pin_list = devm_kcalloc(eint->dev, eint->nbase,
|
||||
sizeof(*eint->pin_list), GFP_KERNEL);
|
||||
if (!eint->pin_list)
|
||||
goto err_pin_list;
|
||||
|
||||
eint->wake_mask = devm_kmalloc(eint->dev, eint->nbase * sizeof(u32 *), GFP_KERNEL);
|
||||
eint->wake_mask = devm_kcalloc(eint->dev, eint->nbase,
|
||||
sizeof(*eint->wake_mask), GFP_KERNEL);
|
||||
if (!eint->wake_mask)
|
||||
goto err_wake_mask;
|
||||
|
||||
eint->cur_mask = devm_kmalloc(eint->dev, eint->nbase * sizeof(u32 *), GFP_KERNEL);
|
||||
eint->cur_mask = devm_kcalloc(eint->dev, eint->nbase,
|
||||
sizeof(*eint->cur_mask), GFP_KERNEL);
|
||||
if (!eint->cur_mask)
|
||||
goto err_cur_mask;
|
||||
|
||||
for (i = 0; i < eint->nbase; i++) {
|
||||
eint->pin_list[i] = devm_kzalloc(eint->dev, eint->base_pin_num[i] * sizeof(u16),
|
||||
eint->pin_list[i] = devm_kzalloc(eint->dev,
|
||||
eint->base_pin_num[i] * sizeof(**eint->pin_list),
|
||||
GFP_KERNEL);
|
||||
port = DIV_ROUND_UP(eint->base_pin_num[i], 32);
|
||||
eint->wake_mask[i] = devm_kzalloc(eint->dev, port * sizeof(u32), GFP_KERNEL);
|
||||
eint->cur_mask[i] = devm_kzalloc(eint->dev, port * sizeof(u32), GFP_KERNEL);
|
||||
eint->wake_mask[i] = devm_kzalloc(eint->dev,
|
||||
port * sizeof(**eint->wake_mask),
|
||||
GFP_KERNEL);
|
||||
eint->cur_mask[i] = devm_kzalloc(eint->dev,
|
||||
port * sizeof(**eint->cur_mask),
|
||||
GFP_KERNEL);
|
||||
if (!eint->pin_list[i] || !eint->wake_mask[i] || !eint->cur_mask[i])
|
||||
goto err_eint;
|
||||
}
|
||||
|
|
@ -597,12 +605,9 @@ int mtk_eint_do_init(struct mtk_eint *eint, struct mtk_eint_pin *eint_pin)
|
|||
|
||||
err_eint:
|
||||
for (i = 0; i < eint->nbase; i++) {
|
||||
if (eint->cur_mask[i])
|
||||
devm_kfree(eint->dev, eint->cur_mask[i]);
|
||||
if (eint->wake_mask[i])
|
||||
devm_kfree(eint->dev, eint->wake_mask[i]);
|
||||
if (eint->pin_list[i])
|
||||
devm_kfree(eint->dev, eint->pin_list[i]);
|
||||
devm_kfree(eint->dev, eint->cur_mask[i]);
|
||||
devm_kfree(eint->dev, eint->wake_mask[i]);
|
||||
devm_kfree(eint->dev, eint->pin_list[i]);
|
||||
}
|
||||
devm_kfree(eint->dev, eint->cur_mask);
|
||||
err_cur_mask:
|
||||
|
|
|
|||
|
|
@ -1019,7 +1019,7 @@ static struct mtk_pin_soc mt7981_data = {
|
|||
.nfuncs = ARRAY_SIZE(mt7981_functions),
|
||||
.eint_hw = &mt7981_eint_hw,
|
||||
.gpio_m = 0,
|
||||
.ies_present = false,
|
||||
.ies_present = true,
|
||||
.base_names = mt7981_pinctrl_register_base_names,
|
||||
.nbase_names = ARRAY_SIZE(mt7981_pinctrl_register_base_names),
|
||||
.bias_disable_set = mtk_pinconf_bias_disable_set,
|
||||
|
|
|
|||
|
|
@ -919,7 +919,7 @@ static struct mtk_pin_soc mt7986a_data = {
|
|||
.nfuncs = ARRAY_SIZE(mt7986_functions),
|
||||
.eint_hw = &mt7986a_eint_hw,
|
||||
.gpio_m = 0,
|
||||
.ies_present = false,
|
||||
.ies_present = true,
|
||||
.base_names = mt7986_pinctrl_register_base_names,
|
||||
.nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
|
||||
.bias_disable_set = mtk_pinconf_bias_disable_set,
|
||||
|
|
@ -945,7 +945,7 @@ static struct mtk_pin_soc mt7986b_data = {
|
|||
.nfuncs = ARRAY_SIZE(mt7986_functions),
|
||||
.eint_hw = &mt7986b_eint_hw,
|
||||
.gpio_m = 0,
|
||||
.ies_present = false,
|
||||
.ies_present = true,
|
||||
.base_names = mt7986_pinctrl_register_base_names,
|
||||
.nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
|
||||
.bias_disable_set = mtk_pinconf_bias_disable_set,
|
||||
|
|
|
|||
|
|
@ -1505,7 +1505,7 @@ static const struct mtk_pin_soc mt7988_data = {
|
|||
.nfuncs = ARRAY_SIZE(mt7988_functions),
|
||||
.eint_hw = &mt7988_eint_hw,
|
||||
.gpio_m = 0,
|
||||
.ies_present = false,
|
||||
.ies_present = true,
|
||||
.base_names = mt7988_pinctrl_register_base_names,
|
||||
.nbase_names = ARRAY_SIZE(mt7988_pinctrl_register_base_names),
|
||||
.bias_disable_set = mtk_pinconf_bias_disable_set,
|
||||
|
|
|
|||
|
|
@ -456,7 +456,6 @@ static const struct mtk_pinctrl_devdata mt8365_pinctrl_data = {
|
|||
.smt_offset = 0x0470,
|
||||
.pullen_offset = 0x0860,
|
||||
.pullsel_offset = 0x0900,
|
||||
.drv_offset = 0x0710,
|
||||
.type1_start = 145,
|
||||
.type1_end = 145,
|
||||
.port_shf = 4,
|
||||
|
|
|
|||
|
|
@ -263,7 +263,6 @@ struct mtk_pinctrl_devdata {
|
|||
unsigned int smt_offset;
|
||||
unsigned int pullen_offset;
|
||||
unsigned int pullsel_offset;
|
||||
unsigned int drv_offset;
|
||||
unsigned int dout_offset;
|
||||
unsigned int din_offset;
|
||||
unsigned int pinmux_offset;
|
||||
|
|
|
|||
|
|
@ -15,25 +15,25 @@ if PINCTRL_MESON
|
|||
|
||||
config PINCTRL_MESON8
|
||||
bool "Meson 8 SoC pinctrl driver"
|
||||
depends on ARM
|
||||
depends on ARM || COMPILE_TEST
|
||||
select PINCTRL_MESON8_PMX
|
||||
default ARCH_MESON
|
||||
|
||||
config PINCTRL_MESON8B
|
||||
bool "Meson 8b SoC pinctrl driver"
|
||||
depends on ARM
|
||||
depends on ARM || COMPILE_TEST
|
||||
select PINCTRL_MESON8_PMX
|
||||
default ARCH_MESON
|
||||
|
||||
config PINCTRL_MESON_GXBB
|
||||
tristate "Meson gxbb SoC pinctrl driver"
|
||||
depends on ARM64
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select PINCTRL_MESON8_PMX
|
||||
default ARCH_MESON
|
||||
|
||||
config PINCTRL_MESON_GXL
|
||||
tristate "Meson gxl SoC pinctrl driver"
|
||||
depends on ARM64
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select PINCTRL_MESON8_PMX
|
||||
default ARCH_MESON
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ config PINCTRL_MESON8_PMX
|
|||
|
||||
config PINCTRL_MESON_AXG
|
||||
tristate "Meson axg Soc pinctrl driver"
|
||||
depends on ARM64
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select PINCTRL_MESON_AXG_PMX
|
||||
default ARCH_MESON
|
||||
|
||||
|
|
@ -51,25 +51,25 @@ config PINCTRL_MESON_AXG_PMX
|
|||
|
||||
config PINCTRL_MESON_G12A
|
||||
tristate "Meson g12a Soc pinctrl driver"
|
||||
depends on ARM64
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select PINCTRL_MESON_AXG_PMX
|
||||
default ARCH_MESON
|
||||
|
||||
config PINCTRL_MESON_A1
|
||||
tristate "Meson a1 Soc pinctrl driver"
|
||||
depends on ARM64
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select PINCTRL_MESON_AXG_PMX
|
||||
default ARCH_MESON
|
||||
|
||||
config PINCTRL_MESON_S4
|
||||
tristate "Meson s4 Soc pinctrl driver"
|
||||
depends on ARM64
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select PINCTRL_MESON_AXG_PMX
|
||||
default ARCH_MESON
|
||||
|
||||
config PINCTRL_AMLOGIC_A4
|
||||
bool "AMLOGIC pincontrol"
|
||||
depends on ARM64
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
default ARCH_MESON
|
||||
help
|
||||
This is the driver for the pin controller found on Amlogic SoCs.
|
||||
|
|
@ -80,13 +80,13 @@ config PINCTRL_AMLOGIC_A4
|
|||
|
||||
config PINCTRL_AMLOGIC_C3
|
||||
tristate "Amlogic C3 SoC pinctrl driver"
|
||||
depends on ARM64
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select PINCTRL_MESON_AXG_PMX
|
||||
default ARCH_MESON
|
||||
|
||||
config PINCTRL_AMLOGIC_T7
|
||||
tristate "Amlogic T7 SoC pinctrl driver"
|
||||
depends on ARM64
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select PINCTRL_MESON_AXG_PMX
|
||||
default ARCH_MESON
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include <dt-bindings/pinctrl/amlogic,pinctrl.h>
|
||||
|
||||
#include "../core.h"
|
||||
#include "../pinctrl-utils.h"
|
||||
#include "../pinconf.h"
|
||||
|
||||
#define gpio_chip_to_bank(chip) \
|
||||
|
|
@ -672,11 +673,79 @@ static void aml_pin_dbg_show(struct pinctrl_dev *pcdev, struct seq_file *s,
|
|||
seq_printf(s, " %s", dev_name(pcdev->dev));
|
||||
}
|
||||
|
||||
static int aml_dt_node_to_map_pinmux(struct pinctrl_dev *pctldev,
|
||||
struct device_node *np,
|
||||
struct pinctrl_map **map,
|
||||
unsigned int *num_maps)
|
||||
{
|
||||
struct device *dev = pctldev->dev;
|
||||
struct device_node *pnode;
|
||||
unsigned long *configs = NULL;
|
||||
unsigned int num_configs = 0;
|
||||
struct property *prop;
|
||||
unsigned int reserved_maps;
|
||||
int reserve;
|
||||
int ret;
|
||||
|
||||
prop = of_find_property(np, "pinmux", NULL);
|
||||
if (!prop) {
|
||||
dev_info(dev, "Missing pinmux property\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
pnode = of_get_parent(np);
|
||||
if (!pnode) {
|
||||
dev_info(dev, "Missing function node\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
reserved_maps = 0;
|
||||
*map = NULL;
|
||||
*num_maps = 0;
|
||||
|
||||
ret = pinconf_generic_parse_dt_config(np, pctldev, &configs,
|
||||
&num_configs);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%pOF: could not parse node property\n", np);
|
||||
return ret;
|
||||
}
|
||||
|
||||
reserve = 1;
|
||||
if (num_configs)
|
||||
reserve++;
|
||||
|
||||
ret = pinctrl_utils_reserve_map(pctldev, map, &reserved_maps,
|
||||
num_maps, reserve);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
ret = pinctrl_utils_add_map_mux(pctldev, map,
|
||||
&reserved_maps, num_maps, np->name,
|
||||
pnode->name);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
if (num_configs) {
|
||||
ret = pinctrl_utils_add_map_configs(pctldev, map, &reserved_maps,
|
||||
num_maps, np->name, configs,
|
||||
num_configs, PIN_MAP_TYPE_CONFIGS_GROUP);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
kfree(configs);
|
||||
if (ret)
|
||||
pinctrl_utils_free_map(pctldev, *map, *num_maps);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct pinctrl_ops aml_pctrl_ops = {
|
||||
.get_groups_count = aml_get_groups_count,
|
||||
.get_group_name = aml_get_group_name,
|
||||
.get_group_pins = aml_get_group_pins,
|
||||
.dt_node_to_map = pinconf_generic_dt_node_to_map_pinmux,
|
||||
.dt_node_to_map = aml_dt_node_to_map_pinmux,
|
||||
.dt_free_map = pinconf_generic_dt_free_map,
|
||||
.pin_dbg_show = aml_pin_dbg_show,
|
||||
};
|
||||
|
|
@ -725,8 +794,9 @@ static u32 aml_bank_pins(struct device_node *np)
|
|||
if (of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3,
|
||||
0, &of_args))
|
||||
return 0;
|
||||
else
|
||||
return of_args.args[2];
|
||||
|
||||
of_node_put(of_args.np);
|
||||
return of_args.args[2];
|
||||
}
|
||||
|
||||
static int aml_bank_number(struct device_node *np)
|
||||
|
|
@ -736,8 +806,9 @@ static int aml_bank_number(struct device_node *np)
|
|||
if (of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3,
|
||||
0, &of_args))
|
||||
return -EINVAL;
|
||||
else
|
||||
return of_args.args[1] >> 8;
|
||||
|
||||
of_node_put(of_args.np);
|
||||
return of_args.args[1] >> 8;
|
||||
}
|
||||
|
||||
static unsigned int aml_count_pins(struct device_node *np)
|
||||
|
|
@ -893,7 +964,7 @@ static const struct gpio_chip aml_gpio_template = {
|
|||
.direction_input = aml_gpio_direction_input,
|
||||
.direction_output = aml_gpio_direction_output,
|
||||
.get_direction = aml_gpio_get_direction,
|
||||
.can_sleep = false,
|
||||
.can_sleep = true,
|
||||
};
|
||||
|
||||
static void init_bank_register_bit(struct aml_pinctrl *info,
|
||||
|
|
|
|||
18
drivers/pinctrl/microchip/Kconfig
Normal file
18
drivers/pinctrl/microchip/Kconfig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
config PINCTRL_PIC64GX
|
||||
bool "pic64gx gpio2 pinctrl driver"
|
||||
depends on ARCH_MICROCHIP || COMPILE_TEST
|
||||
depends on OF
|
||||
select GENERIC_PINCONF
|
||||
select REGMAP_MMIO
|
||||
help
|
||||
This selects the pinctrl driver for gpio2 on pic64gx.
|
||||
|
||||
config PINCTRL_POLARFIRE_SOC
|
||||
bool "Polarfire SoC pinctrl drivers"
|
||||
depends on ARCH_MICROCHIP || COMPILE_TEST
|
||||
depends on OF
|
||||
select GENERIC_PINCTRL
|
||||
help
|
||||
This selects the pinctrl drivers for Microchip Polarfire SoC.
|
||||
5
drivers/pinctrl/microchip/Makefile
Normal file
5
drivers/pinctrl/microchip/Makefile
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
obj-$(CONFIG_PINCTRL_PIC64GX) += pinctrl-pic64gx-gpio2.o
|
||||
obj-$(CONFIG_PINCTRL_POLARFIRE_SOC) += pinctrl-mpfs-iomux0.o
|
||||
obj-$(CONFIG_PINCTRL_POLARFIRE_SOC) += pinctrl-mpfs-mssio.o
|
||||
|
|
@ -15,10 +15,10 @@
|
|||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/pinctrl/pinmux.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "pinctrl-utils.h"
|
||||
#include "pinconf.h"
|
||||
#include "pinmux.h"
|
||||
#include "../core.h"
|
||||
#include "../pinctrl-utils.h"
|
||||
#include "../pinconf.h"
|
||||
#include "../pinmux.h"
|
||||
|
||||
#define MPFS_IOMUX0_REG 0x200
|
||||
|
||||
737
drivers/pinctrl/microchip/pinctrl-mpfs-mssio.c
Normal file
737
drivers/pinctrl/microchip/pinctrl-mpfs-mssio.c
Normal file
|
|
@ -0,0 +1,737 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
#include <linux/pinctrl/pinconf-generic.h>
|
||||
#include <linux/pinctrl/pinconf.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/pinctrl/pinmux.h>
|
||||
|
||||
#include "../core.h"
|
||||
#include "../pinctrl-utils.h"
|
||||
#include "../pinconf.h"
|
||||
#include "../pinmux.h"
|
||||
|
||||
#define MPFS_PINCTRL_PAD_MUX_MASK GENMASK(3, 0)
|
||||
|
||||
#define MPFS_PINCTRL_IOCFG_MASK GENMASK(14, 0)
|
||||
#define MPFS_PINCTRL_IBUFMD_MASK GENMASK(2, 0)
|
||||
#define MPFS_PINCTRL_DRV_MASK GENMASK(6, 3)
|
||||
#define MPFS_PINCTRL_CLAMP BIT(7)
|
||||
#define MPFS_PINCTRL_ENHYST BIT(8)
|
||||
#define MPFS_PINCTRL_LOCKDN BIT(9)
|
||||
#define MPFS_PINCTRL_WPD BIT(10)
|
||||
#define MPFS_PINCTRL_WPU BIT(11)
|
||||
#define MPFS_PINCTRL_PULL_MASK GENMASK(11, 10)
|
||||
#define MPFS_PINCTRL_LP_PERSIST_EN BIT(12)
|
||||
#define MPFS_PINCTRL_LP_BYPASS_EN BIT(13)
|
||||
|
||||
#define MPFS_PINCTRL_MSSIO_BANK2_CFG_CR 0x1c4
|
||||
#define MPFS_PINCTRL_MSSIO_BANK4_CFG_CR 0x1c8
|
||||
#define MPFS_PINCTRL_BANK_VOLTAGE_MASK GENMASK(19, 16)
|
||||
|
||||
#define MPFS_PINCTRL_IOCFG01_REG 0x234
|
||||
|
||||
#define MPFS_PINCTRL_INTER_BANK_GAP 0x4
|
||||
|
||||
#define MPFS_PINCTRL_BANK2_START 14
|
||||
|
||||
#define MPFS_PINCTRL_LOCKDOWN (PIN_CONFIG_END + 1)
|
||||
#define MPFS_PINCTRL_CLAMP_DIODE (PIN_CONFIG_END + 2)
|
||||
#define MPFS_PINCTRL_IBUFMD (PIN_CONFIG_END + 3)
|
||||
|
||||
struct mpfs_pinctrl_mux_config {
|
||||
u8 pin;
|
||||
u8 function;
|
||||
};
|
||||
|
||||
struct mpfs_pinctrl {
|
||||
struct pinctrl_dev *pctrl;
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct regmap *sysreg_regmap;
|
||||
struct mutex mutex;
|
||||
struct pinctrl_desc desc;
|
||||
};
|
||||
|
||||
struct mpfs_pinctrl_drive_strength {
|
||||
u8 ma;
|
||||
u8 val;
|
||||
};
|
||||
|
||||
struct mpfs_pinctrl_bank_voltage {
|
||||
u32 uv;
|
||||
u8 val;
|
||||
};
|
||||
|
||||
static struct mpfs_pinctrl_drive_strength mpfs_pinctrl_drive_strengths[8] = {
|
||||
{ .ma = 2, .val = 2 },
|
||||
{ .ma = 4, .val = 3 },
|
||||
{ .ma = 6, .val = 4 },
|
||||
{ .ma = 8, .val = 5 },
|
||||
{ .ma = 10, .val = 6 },
|
||||
{ .ma = 12, .val = 7 },
|
||||
{ .ma = 16, .val = 10 },
|
||||
{ .ma = 20, .val = 12 },
|
||||
};
|
||||
static struct mpfs_pinctrl_bank_voltage mpfs_pinctrl_bank_voltages[8] = {
|
||||
{ .uv = 1200000, .val = 0 },
|
||||
{ .uv = 1500000, .val = 2 },
|
||||
{ .uv = 1800000, .val = 4 },
|
||||
{ .uv = 2500000, .val = 6 },
|
||||
{ .uv = 3300000, .val = 8 },
|
||||
{ .uv = 0, .val = 0x3f }, // pin unused
|
||||
};
|
||||
|
||||
static int mpfs_pinctrl_get_drive_strength_ma(u32 drive_strength)
|
||||
{
|
||||
size_t num = ARRAY_SIZE(mpfs_pinctrl_drive_strengths);
|
||||
|
||||
for (int i = 0; i < num; i++)
|
||||
if (drive_strength == mpfs_pinctrl_drive_strengths[i].val)
|
||||
return mpfs_pinctrl_drive_strengths[i].ma;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int mpfs_pinctrl_get_drive_strength_val(u32 drive_strength_ma)
|
||||
{
|
||||
size_t num = ARRAY_SIZE(mpfs_pinctrl_drive_strengths);
|
||||
|
||||
if (!drive_strength_ma)
|
||||
return -EINVAL;
|
||||
|
||||
for (int i = 0; i < num; i++)
|
||||
if (drive_strength_ma <= mpfs_pinctrl_drive_strengths[i].ma)
|
||||
return mpfs_pinctrl_drive_strengths[i].val;
|
||||
|
||||
return mpfs_pinctrl_drive_strengths[num - 1].val;
|
||||
}
|
||||
|
||||
static int mpfs_pinctrl_get_bank_voltage_uv(u32 bank_voltage)
|
||||
{
|
||||
size_t num = ARRAY_SIZE(mpfs_pinctrl_bank_voltages);
|
||||
|
||||
for (int i = 0; i < num; i++)
|
||||
if (bank_voltage == mpfs_pinctrl_bank_voltages[i].val)
|
||||
return mpfs_pinctrl_bank_voltages[i].uv;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int mpfs_pinctrl_get_bank_voltage_val(u32 bank_voltage_uv)
|
||||
{
|
||||
size_t num = ARRAY_SIZE(mpfs_pinctrl_bank_voltages);
|
||||
|
||||
for (int i = 0; i < num; i++)
|
||||
if (bank_voltage_uv <= mpfs_pinctrl_bank_voltages[i].uv)
|
||||
return mpfs_pinctrl_bank_voltages[i].val;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static u32 mpfs_pinctrl_pin_to_bank_voltage(struct mpfs_pinctrl *pctrl, unsigned int pin)
|
||||
{
|
||||
u32 bank_voltage, val;
|
||||
|
||||
if (pin < MPFS_PINCTRL_BANK2_START)
|
||||
regmap_read(pctrl->sysreg_regmap, MPFS_PINCTRL_MSSIO_BANK4_CFG_CR, &val);
|
||||
else
|
||||
regmap_read(pctrl->sysreg_regmap, MPFS_PINCTRL_MSSIO_BANK2_CFG_CR, &val);
|
||||
|
||||
bank_voltage = FIELD_GET(MPFS_PINCTRL_BANK_VOLTAGE_MASK, val);
|
||||
|
||||
return mpfs_pinctrl_get_bank_voltage_uv(bank_voltage);
|
||||
}
|
||||
|
||||
static void mpfs_pinctrl_set_bank_voltage(struct mpfs_pinctrl *pctrl, unsigned int pin,
|
||||
u32 bank_voltage)
|
||||
{
|
||||
u32 val = FIELD_PREP(MPFS_PINCTRL_BANK_VOLTAGE_MASK, bank_voltage);
|
||||
|
||||
if (pin < MPFS_PINCTRL_BANK2_START)
|
||||
regmap_assign_bits(pctrl->sysreg_regmap, MPFS_PINCTRL_MSSIO_BANK4_CFG_CR,
|
||||
MPFS_PINCTRL_BANK_VOLTAGE_MASK, val);
|
||||
else
|
||||
regmap_assign_bits(pctrl->sysreg_regmap, MPFS_PINCTRL_MSSIO_BANK2_CFG_CR,
|
||||
MPFS_PINCTRL_BANK_VOLTAGE_MASK, val);
|
||||
}
|
||||
|
||||
static char *mpfs_pinctrl_function_names[] = {
|
||||
"sd",
|
||||
"emmc",
|
||||
"qspi",
|
||||
"spi",
|
||||
"usb",
|
||||
"uart",
|
||||
"i2c",
|
||||
"can",
|
||||
"mdio",
|
||||
"misc",
|
||||
"reserved",
|
||||
"gpio",
|
||||
"fabric test",
|
||||
"tied-low",
|
||||
"tied-high",
|
||||
"tristate"
|
||||
};
|
||||
|
||||
static int mpfs_pinctrl_function_map(const char *function)
|
||||
{
|
||||
size_t num = ARRAY_SIZE(mpfs_pinctrl_function_names);
|
||||
|
||||
for (int i = 0; i < num; i++)
|
||||
if (!strcmp(function, mpfs_pinctrl_function_names[i]))
|
||||
return i;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static const struct pinconf_generic_params mpfs_pinctrl_custom_bindings[] = {
|
||||
{ "microchip,clamp-diode", MPFS_PINCTRL_CLAMP_DIODE, 1 },
|
||||
{ "microchip,ibufmd", MPFS_PINCTRL_IBUFMD, 0x0 },
|
||||
};
|
||||
|
||||
static int mpfs_pinctrl_pin_to_iomux_offset(unsigned int pin)
|
||||
{
|
||||
int offset;
|
||||
|
||||
switch (pin) {
|
||||
case 0 ... 7:
|
||||
offset = pin * 4;
|
||||
break;
|
||||
case 8 ... 13:
|
||||
offset = (pin - 8) * 4;
|
||||
break;
|
||||
case 14 ... 21:
|
||||
offset = (pin - 14) * 4;
|
||||
break;
|
||||
case 22 ... 29:
|
||||
offset = (pin - 22) * 4;
|
||||
break;
|
||||
case 30 ... 37:
|
||||
offset = (pin - 30) * 4;
|
||||
break;
|
||||
default:
|
||||
offset = -EINVAL;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int mpfs_pinctrl_pin_to_iomux_reg(unsigned int pin)
|
||||
{
|
||||
int reg;
|
||||
|
||||
switch (pin) {
|
||||
case 0 ... 7:
|
||||
reg = 0x204;
|
||||
break;
|
||||
case 8 ... 13:
|
||||
reg = 0x208;
|
||||
break;
|
||||
case 14 ... 21:
|
||||
reg = 0x20c;
|
||||
break;
|
||||
case 22 ... 29:
|
||||
reg = 0x210;
|
||||
break;
|
||||
case 30 ... 37:
|
||||
reg = 0x214;
|
||||
break;
|
||||
default:
|
||||
reg = -EINVAL;
|
||||
}
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
static int mpfs_pinctrl_pin_to_iocfg_reg(unsigned int pin)
|
||||
{
|
||||
u32 reg = MPFS_PINCTRL_IOCFG01_REG;
|
||||
|
||||
if (pin >= MPFS_PINCTRL_BANK2_START)
|
||||
reg += MPFS_PINCTRL_INTER_BANK_GAP;
|
||||
|
||||
// 2 pins per 32-bit register
|
||||
reg += (pin / 2) * 0x4;
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
static int mpfs_pinctrl_pin_to_iocfg_offset(unsigned int pin)
|
||||
{
|
||||
return 16 * (pin % 2);
|
||||
}
|
||||
|
||||
static void mpfs_pinctrl_dbg_show(struct pinctrl_dev *pctrl_dev, struct seq_file *seq,
|
||||
unsigned int pin)
|
||||
{
|
||||
struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
|
||||
u32 func;
|
||||
int reg, offset;
|
||||
|
||||
reg = mpfs_pinctrl_pin_to_iomux_reg(pin);
|
||||
offset = mpfs_pinctrl_pin_to_iomux_offset(pin);
|
||||
|
||||
seq_printf(seq, "reg: %x, offset: %u ", reg, offset);
|
||||
seq_printf(seq, "pin: %u ", pin);
|
||||
|
||||
if (reg < 0 || offset < 0)
|
||||
return;
|
||||
|
||||
regmap_read(pctrl->regmap, reg, &func);
|
||||
func = (func >> offset) & MPFS_PINCTRL_PAD_MUX_MASK;
|
||||
seq_printf(seq, "func: %s (%x)\n", mpfs_pinctrl_function_names[func], func);
|
||||
}
|
||||
|
||||
static const struct pinctrl_ops mpfs_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,
|
||||
.pin_dbg_show = mpfs_pinctrl_dbg_show,
|
||||
.dt_node_to_map = pinctrl_generic_pins_function_dt_node_to_map,
|
||||
.dt_free_map = pinctrl_utils_free_map,
|
||||
};
|
||||
|
||||
static int mpfs_pinctrl_set_pin_func(struct mpfs_pinctrl *pctrl, u8 pin, u8 function)
|
||||
{
|
||||
struct device *dev = pctrl->dev;
|
||||
int reg, offset;
|
||||
u32 func, mask;
|
||||
|
||||
reg = mpfs_pinctrl_pin_to_iomux_reg(pin);
|
||||
offset = mpfs_pinctrl_pin_to_iomux_offset(pin);
|
||||
|
||||
func = function << offset;
|
||||
mask = MPFS_PINCTRL_PAD_MUX_MASK << offset;
|
||||
|
||||
dev_dbg(dev, "Setting pin %u. reg: %x offset %u func %x\n", pin, reg, offset, func);
|
||||
|
||||
if (reg < 0 || offset < 0)
|
||||
return -EINVAL;
|
||||
|
||||
regmap_update_bits(pctrl->regmap, reg, mask, func);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpfs_pinctrl_set_mux(struct pinctrl_dev *pctrl_dev, unsigned int fsel,
|
||||
unsigned int gsel)
|
||||
{
|
||||
struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
|
||||
const struct group_desc *group;
|
||||
const char **functions;
|
||||
|
||||
group = pinctrl_generic_get_group(pctrl_dev, gsel);
|
||||
if (!group)
|
||||
return -EINVAL;
|
||||
|
||||
functions = group->data;
|
||||
|
||||
for (int i = 0; i < group->grp.npins; i++) {
|
||||
int function;
|
||||
|
||||
function = mpfs_pinctrl_function_map(functions[i]);
|
||||
if (function < 0) {
|
||||
dev_err(pctrl->dev, "invalid function %s\n", functions[i]);
|
||||
return function;
|
||||
}
|
||||
|
||||
mpfs_pinctrl_set_pin_func(pctrl, group->grp.pins[i], function);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pinmux_ops mpfs_pinctrl_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 = mpfs_pinctrl_set_mux,
|
||||
};
|
||||
|
||||
static int mpfs_pinctrl_pinconf_get(struct pinctrl_dev *pctrl_dev, unsigned int pin,
|
||||
unsigned long *config)
|
||||
{
|
||||
struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
|
||||
int param = pinconf_to_config_param(*config);
|
||||
int reg = mpfs_pinctrl_pin_to_iocfg_reg(pin);
|
||||
int val;
|
||||
u32 arg;
|
||||
u8 str;
|
||||
|
||||
regmap_read(pctrl->regmap, reg, &val);
|
||||
|
||||
val = val >> mpfs_pinctrl_pin_to_iocfg_offset(pin);
|
||||
val = val & MPFS_PINCTRL_IOCFG_MASK;
|
||||
|
||||
switch (param) {
|
||||
case PIN_CONFIG_BIAS_BUS_HOLD:
|
||||
if (!(val & MPFS_PINCTRL_WPD))
|
||||
return -EINVAL;
|
||||
|
||||
if (!(val & MPFS_PINCTRL_WPU))
|
||||
return -EINVAL;
|
||||
|
||||
arg = 1;
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
if (!(val & MPFS_PINCTRL_WPD))
|
||||
return -EINVAL;
|
||||
|
||||
if (val & MPFS_PINCTRL_WPU)
|
||||
return -EINVAL;
|
||||
|
||||
arg = 1;
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
if (!(val & MPFS_PINCTRL_WPU))
|
||||
return -EINVAL;
|
||||
|
||||
if (val & MPFS_PINCTRL_WPD)
|
||||
return -EINVAL;
|
||||
|
||||
arg = 1;
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_DISABLE:
|
||||
if (val & MPFS_PINCTRL_PULL_MASK)
|
||||
return -EINVAL;
|
||||
|
||||
arg = 1;
|
||||
break;
|
||||
case PIN_CONFIG_DRIVE_STRENGTH:
|
||||
str = FIELD_GET(MPFS_PINCTRL_DRV_MASK, val);
|
||||
if (!str)
|
||||
return -EINVAL;
|
||||
|
||||
arg = mpfs_pinctrl_get_drive_strength_ma(str);
|
||||
break;
|
||||
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
|
||||
if (!FIELD_GET(MPFS_PINCTRL_ENHYST, val))
|
||||
return -EINVAL;
|
||||
|
||||
arg = 1;
|
||||
break;
|
||||
case PIN_CONFIG_PERSIST_STATE:
|
||||
if (!FIELD_GET(MPFS_PINCTRL_LP_PERSIST_EN, val))
|
||||
return -EINVAL;
|
||||
|
||||
arg = 1;
|
||||
break;
|
||||
case PIN_CONFIG_MODE_LOW_POWER:
|
||||
if (!FIELD_GET(MPFS_PINCTRL_LP_BYPASS_EN, val))
|
||||
return -EINVAL;
|
||||
|
||||
arg = 1;
|
||||
break;
|
||||
case PIN_CONFIG_POWER_SOURCE:
|
||||
arg = mpfs_pinctrl_pin_to_bank_voltage(pctrl, pin);
|
||||
break;
|
||||
case MPFS_PINCTRL_CLAMP_DIODE:
|
||||
if (!FIELD_GET(MPFS_PINCTRL_CLAMP, val))
|
||||
return -EINVAL;
|
||||
|
||||
arg = 1;
|
||||
break;
|
||||
case MPFS_PINCTRL_LOCKDOWN:
|
||||
/*
|
||||
* Lockdown is a read-only configuration, it'll get set if the
|
||||
* tamper unit triggers global lockdown and lockdown has been
|
||||
* set in the MSS Configurator for the bank a pin belongs to.
|
||||
*/
|
||||
if (!FIELD_GET(MPFS_PINCTRL_LOCKDN, val))
|
||||
return -EINVAL;
|
||||
|
||||
arg = 1;
|
||||
break;
|
||||
case MPFS_PINCTRL_IBUFMD:
|
||||
arg = FIELD_GET(MPFS_PINCTRL_IBUFMD_MASK, val);
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
*config = pinconf_to_config_packed(param, arg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpfs_pinctrl_pinconf_generate_config(struct mpfs_pinctrl *pctrl, unsigned int pin,
|
||||
unsigned long *configs, unsigned int num_configs,
|
||||
u32 *value, u32 *bank_voltage)
|
||||
{
|
||||
u32 val = 0;
|
||||
|
||||
for (int i = 0; i < num_configs; i++) {
|
||||
int param, tmp;
|
||||
u32 arg;
|
||||
|
||||
param = pinconf_to_config_param(configs[i]);
|
||||
arg = pinconf_to_config_argument(configs[i]);
|
||||
|
||||
switch (param) {
|
||||
case PIN_CONFIG_BIAS_BUS_HOLD:
|
||||
val |= MPFS_PINCTRL_PULL_MASK;
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
val &= ~MPFS_PINCTRL_PULL_MASK;
|
||||
val |= MPFS_PINCTRL_WPD;
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
val &= ~MPFS_PINCTRL_PULL_MASK;
|
||||
val |= MPFS_PINCTRL_WPU;
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_DISABLE:
|
||||
val &= ~MPFS_PINCTRL_PULL_MASK;
|
||||
break;
|
||||
case PIN_CONFIG_DRIVE_STRENGTH:
|
||||
tmp = mpfs_pinctrl_get_drive_strength_val(arg);
|
||||
if (tmp < 0)
|
||||
return tmp;
|
||||
|
||||
val |= FIELD_PREP(MPFS_PINCTRL_DRV_MASK, tmp);
|
||||
break;
|
||||
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
|
||||
if (!arg)
|
||||
break;
|
||||
val |= MPFS_PINCTRL_ENHYST;
|
||||
break;
|
||||
case PIN_CONFIG_PERSIST_STATE:
|
||||
val |= MPFS_PINCTRL_LP_PERSIST_EN;
|
||||
break;
|
||||
case PIN_CONFIG_MODE_LOW_POWER:
|
||||
if (arg)
|
||||
val |= MPFS_PINCTRL_LP_BYPASS_EN;
|
||||
break;
|
||||
case PIN_CONFIG_POWER_SOURCE:
|
||||
tmp = mpfs_pinctrl_get_bank_voltage_val(arg);
|
||||
if (tmp < 0)
|
||||
return tmp;
|
||||
|
||||
*bank_voltage = tmp;
|
||||
break;
|
||||
case MPFS_PINCTRL_CLAMP_DIODE:
|
||||
val |= MPFS_PINCTRL_CLAMP;
|
||||
break;
|
||||
case MPFS_PINCTRL_IBUFMD:
|
||||
val |= FIELD_PREP(MPFS_PINCTRL_IBUFMD_MASK, arg);
|
||||
break;
|
||||
default:
|
||||
dev_err(pctrl->dev, "config %u not supported\n", param);
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
*value = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpfs_pinctrl_pin_set_config(struct mpfs_pinctrl *pctrl, unsigned int pin, u32 config)
|
||||
{
|
||||
int reg = mpfs_pinctrl_pin_to_iocfg_reg(pin);
|
||||
int offset = mpfs_pinctrl_pin_to_iocfg_offset(pin);
|
||||
u32 val, mask;
|
||||
|
||||
mask = MPFS_PINCTRL_IOCFG_MASK << offset;
|
||||
val = config << offset;
|
||||
|
||||
regmap_update_bits(pctrl->regmap, reg, mask, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpfs_pinctrl_pinconf_set(struct pinctrl_dev *pctrl_dev, unsigned int pin,
|
||||
unsigned long *configs, unsigned int num_configs)
|
||||
{
|
||||
struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
|
||||
u32 val, bank_voltage = 0;
|
||||
int ret;
|
||||
|
||||
ret = mpfs_pinctrl_pinconf_generate_config(pctrl, pin, configs, num_configs, &val,
|
||||
&bank_voltage);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mpfs_pinctrl_pin_set_config(pctrl, pin, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (bank_voltage)
|
||||
mpfs_pinctrl_set_bank_voltage(pctrl, pin, bank_voltage);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpfs_pinctrl_pinconf_group_set(struct pinctrl_dev *pctrl_dev, unsigned int gsel,
|
||||
unsigned long *configs, unsigned int num_configs)
|
||||
{
|
||||
struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
|
||||
const struct group_desc *group;
|
||||
unsigned int pin;
|
||||
u32 val, bank_voltage = 0;
|
||||
int ret;
|
||||
|
||||
group = pinctrl_generic_get_group(pctrl_dev, gsel);
|
||||
if (!group)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Assume that the first pin in a group is representative, as the mss
|
||||
* configurator doesn't allow splitting a function between two banks.
|
||||
*/
|
||||
pin = group->grp.pins[0];
|
||||
|
||||
ret = mpfs_pinctrl_pinconf_generate_config(pctrl, pin, configs, num_configs, &val,
|
||||
&bank_voltage);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (int i = 0; i < group->grp.npins; i++)
|
||||
mpfs_pinctrl_pin_set_config(pctrl, group->grp.pins[i], val);
|
||||
|
||||
if (bank_voltage)
|
||||
mpfs_pinctrl_set_bank_voltage(pctrl, group->grp.pins[0], bank_voltage);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mpfs_pinctrl_pinconf_dbg_show(struct pinctrl_dev *pctrl_dev, struct seq_file *seq,
|
||||
unsigned int pin)
|
||||
{
|
||||
struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
|
||||
u32 val;
|
||||
int reg, offset;
|
||||
|
||||
reg = mpfs_pinctrl_pin_to_iocfg_reg(pin);
|
||||
offset = mpfs_pinctrl_pin_to_iocfg_offset(pin);
|
||||
|
||||
seq_printf(seq, "pin: %u ", pin);
|
||||
seq_printf(seq, "reg: %x offset: %u ", reg, offset);
|
||||
|
||||
if (reg < 0 || offset < 0)
|
||||
return;
|
||||
|
||||
regmap_read(pctrl->regmap, reg, &val);
|
||||
val = (val & (MPFS_PINCTRL_IOCFG_MASK << offset)) >> offset;
|
||||
seq_printf(seq, "val: %x\n", val);
|
||||
}
|
||||
|
||||
static const struct pinconf_ops mpfs_pinctrl_pinconf_ops = {
|
||||
.pin_config_get = mpfs_pinctrl_pinconf_get,
|
||||
.pin_config_set = mpfs_pinctrl_pinconf_set,
|
||||
.pin_config_group_set = mpfs_pinctrl_pinconf_group_set,
|
||||
.pin_config_dbg_show = mpfs_pinctrl_pinconf_dbg_show,
|
||||
.is_generic = true,
|
||||
};
|
||||
|
||||
static const struct pinctrl_pin_desc mpfs_pinctrl_pins[] = {
|
||||
PINCTRL_PIN(0, "bank 4 0"),
|
||||
PINCTRL_PIN(1, "bank 4 1"),
|
||||
PINCTRL_PIN(2, "bank 4 2"),
|
||||
PINCTRL_PIN(3, "bank 4 3"),
|
||||
PINCTRL_PIN(4, "bank 4 4"),
|
||||
PINCTRL_PIN(5, "bank 4 5"),
|
||||
PINCTRL_PIN(6, "bank 4 6"),
|
||||
PINCTRL_PIN(7, "bank 4 7"),
|
||||
PINCTRL_PIN(8, "bank 4 8"),
|
||||
PINCTRL_PIN(9, "bank 4 9"),
|
||||
PINCTRL_PIN(10, "bank 4 10"),
|
||||
PINCTRL_PIN(11, "bank 4 11"),
|
||||
PINCTRL_PIN(12, "bank 4 12"),
|
||||
PINCTRL_PIN(13, "bank 4 13"),
|
||||
|
||||
PINCTRL_PIN(14, "bank 2 0"),
|
||||
PINCTRL_PIN(15, "bank 2 1"),
|
||||
PINCTRL_PIN(16, "bank 2 2"),
|
||||
PINCTRL_PIN(17, "bank 2 3"),
|
||||
PINCTRL_PIN(18, "bank 2 4"),
|
||||
PINCTRL_PIN(19, "bank 2 5"),
|
||||
PINCTRL_PIN(20, "bank 2 6"),
|
||||
PINCTRL_PIN(21, "bank 2 7"),
|
||||
PINCTRL_PIN(22, "bank 2 8"),
|
||||
PINCTRL_PIN(23, "bank 2 9"),
|
||||
PINCTRL_PIN(24, "bank 2 10"),
|
||||
PINCTRL_PIN(25, "bank 2 11"),
|
||||
PINCTRL_PIN(26, "bank 2 12"),
|
||||
PINCTRL_PIN(27, "bank 2 13"),
|
||||
PINCTRL_PIN(28, "bank 2 14"),
|
||||
PINCTRL_PIN(29, "bank 2 15"),
|
||||
PINCTRL_PIN(30, "bank 2 16"),
|
||||
PINCTRL_PIN(31, "bank 2 17"),
|
||||
PINCTRL_PIN(32, "bank 2 18"),
|
||||
PINCTRL_PIN(33, "bank 2 19"),
|
||||
PINCTRL_PIN(34, "bank 2 20"),
|
||||
PINCTRL_PIN(35, "bank 2 21"),
|
||||
PINCTRL_PIN(36, "bank 2 22"),
|
||||
PINCTRL_PIN(37, "bank 2 23"),
|
||||
};
|
||||
|
||||
static int mpfs_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct mpfs_pinctrl *pctrl;
|
||||
int ret;
|
||||
|
||||
pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL);
|
||||
if (!pctrl)
|
||||
return -ENOMEM;
|
||||
|
||||
pctrl->regmap = device_node_to_regmap(pdev->dev.parent->of_node);
|
||||
if (IS_ERR(pctrl->regmap))
|
||||
dev_err_probe(dev, PTR_ERR(pctrl->regmap), "Failed to find syscon regmap\n");
|
||||
|
||||
pctrl->sysreg_regmap = syscon_regmap_lookup_by_compatible("microchip,mpfs-sysreg-scb");
|
||||
if (IS_ERR(pctrl->sysreg_regmap))
|
||||
return PTR_ERR(pctrl->sysreg_regmap);
|
||||
|
||||
pctrl->desc.name = dev_name(dev);
|
||||
pctrl->desc.pins = mpfs_pinctrl_pins;
|
||||
pctrl->desc.npins = ARRAY_SIZE(mpfs_pinctrl_pins);
|
||||
pctrl->desc.pctlops = &mpfs_pinctrl_ops;
|
||||
pctrl->desc.pmxops = &mpfs_pinctrl_pinmux_ops;
|
||||
pctrl->desc.confops = &mpfs_pinctrl_pinconf_ops;
|
||||
pctrl->desc.owner = THIS_MODULE;
|
||||
pctrl->desc.num_custom_params = ARRAY_SIZE(mpfs_pinctrl_custom_bindings);
|
||||
pctrl->desc.custom_params = mpfs_pinctrl_custom_bindings;
|
||||
|
||||
pctrl->dev = dev;
|
||||
|
||||
ret = devm_mutex_init(dev, &pctrl->mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
platform_set_drvdata(pdev, pctrl);
|
||||
|
||||
pctrl->pctrl = devm_pinctrl_register(&pdev->dev, &pctrl->desc, pctrl);
|
||||
if (IS_ERR(pctrl->pctrl))
|
||||
return PTR_ERR(pctrl->pctrl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id mpfs_pinctrl_of_match[] = {
|
||||
{ .compatible = "microchip,mpfs-pinctrl-mssio" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mpfs_pinctrl_of_match);
|
||||
|
||||
static struct platform_driver mpfs_pinctrl_driver = {
|
||||
.driver = {
|
||||
.name = "mpfs-pinctrl",
|
||||
.of_match_table = mpfs_pinctrl_of_match,
|
||||
},
|
||||
.probe = mpfs_pinctrl_probe,
|
||||
};
|
||||
module_platform_driver(mpfs_pinctrl_driver);
|
||||
|
||||
MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
|
||||
MODULE_DESCRIPTION("Polarfire SoC mssio pinctrl driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/pinctrl/pinmux.h>
|
||||
|
||||
#include "pinctrl-utils.h"
|
||||
#include "../pinctrl-utils.h"
|
||||
|
||||
#define PIC64GX_PINMUX_REG 0x0
|
||||
|
||||
|
|
@ -385,75 +385,6 @@ out:
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(pinconf_generic_parse_dt_config);
|
||||
|
||||
int pinconf_generic_dt_node_to_map_pinmux(struct pinctrl_dev *pctldev,
|
||||
struct device_node *np,
|
||||
struct pinctrl_map **map,
|
||||
unsigned int *num_maps)
|
||||
{
|
||||
struct device *dev = pctldev->dev;
|
||||
struct device_node *pnode;
|
||||
unsigned long *configs = NULL;
|
||||
unsigned int num_configs = 0;
|
||||
struct property *prop;
|
||||
unsigned int reserved_maps;
|
||||
int reserve;
|
||||
int ret;
|
||||
|
||||
prop = of_find_property(np, "pinmux", NULL);
|
||||
if (!prop) {
|
||||
dev_info(dev, "Missing pinmux property\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
pnode = of_get_parent(np);
|
||||
if (!pnode) {
|
||||
dev_info(dev, "Missing function node\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
reserved_maps = 0;
|
||||
*map = NULL;
|
||||
*num_maps = 0;
|
||||
|
||||
ret = pinconf_generic_parse_dt_config(np, pctldev, &configs,
|
||||
&num_configs);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%pOF: could not parse node property\n", np);
|
||||
return ret;
|
||||
}
|
||||
|
||||
reserve = 1;
|
||||
if (num_configs)
|
||||
reserve++;
|
||||
|
||||
ret = pinctrl_utils_reserve_map(pctldev, map, &reserved_maps,
|
||||
num_maps, reserve);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
ret = pinctrl_utils_add_map_mux(pctldev, map,
|
||||
&reserved_maps, num_maps, np->name,
|
||||
pnode->name);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
if (num_configs) {
|
||||
ret = pinctrl_utils_add_map_configs(pctldev, map, &reserved_maps,
|
||||
num_maps, np->name, configs,
|
||||
num_configs, PIN_MAP_TYPE_CONFIGS_GROUP);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
kfree(configs);
|
||||
if (ret)
|
||||
pinctrl_utils_free_map(pctldev, *map, *num_maps);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pinconf_generic_dt_node_to_map_pinmux);
|
||||
|
||||
int pinconf_generic_dt_subnode_to_map(struct pinctrl_dev *pctldev,
|
||||
struct device_node *np, struct pinctrl_map **map,
|
||||
unsigned int *reserved_maps, unsigned int *num_maps,
|
||||
|
|
|
|||
|
|
@ -160,3 +160,19 @@ pinconf_generic_parse_dt_pinmux(struct device_node *np, struct device *dev,
|
|||
return -ENOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_GENERIC_PINCTRL) && defined (CONFIG_OF)
|
||||
int pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,
|
||||
struct device_node *np,
|
||||
struct pinctrl_map **maps,
|
||||
unsigned int *num_maps);
|
||||
#else
|
||||
static inline int
|
||||
pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,
|
||||
struct device_node *np,
|
||||
struct pinctrl_map **maps,
|
||||
unsigned int *num_maps)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,11 +21,9 @@
|
|||
#include <linux/gpio/driver.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/pinctrl/pinconf.h>
|
||||
#include <linux/pinctrl/pinconf-generic.h>
|
||||
|
|
|
|||
|
|
@ -102,9 +102,9 @@ static u32 apple_gpio_get_reg(struct apple_gpio_pinctrl *pctl,
|
|||
static int apple_gpio_dt_node_to_map(struct pinctrl_dev *pctldev,
|
||||
struct device_node *node,
|
||||
struct pinctrl_map **map,
|
||||
unsigned *num_maps)
|
||||
unsigned int *num_maps)
|
||||
{
|
||||
unsigned reserved_maps;
|
||||
unsigned int reserved_maps;
|
||||
struct apple_gpio_pinctrl *pctl;
|
||||
u32 pinfunc, pin, func;
|
||||
int num_pins, i, ret;
|
||||
|
|
@ -170,8 +170,15 @@ static const struct pinctrl_ops apple_gpio_pinctrl_ops = {
|
|||
|
||||
/* Pin multiplexer functions */
|
||||
|
||||
static int apple_gpio_pinmux_set(struct pinctrl_dev *pctldev, unsigned func,
|
||||
unsigned group)
|
||||
static bool apple_gpio_pinmux_func_is_gpio(struct pinctrl_dev *pctldev,
|
||||
unsigned int selector)
|
||||
{
|
||||
/* Function selector 0 is always the GPIO mode */
|
||||
return (selector == 0);
|
||||
}
|
||||
|
||||
static int apple_gpio_pinmux_set(struct pinctrl_dev *pctldev, unsigned int func,
|
||||
unsigned int group)
|
||||
{
|
||||
struct apple_gpio_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
|
|
@ -186,6 +193,7 @@ 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,
|
||||
.function_is_gpio = apple_gpio_pinmux_func_is_gpio,
|
||||
.set_mux = apple_gpio_pinmux_set,
|
||||
.strict = true,
|
||||
};
|
||||
|
|
@ -202,7 +210,7 @@ static int apple_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
|
|||
return GPIO_LINE_DIRECTION_IN;
|
||||
}
|
||||
|
||||
static int apple_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
static int apple_gpio_get(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);
|
||||
|
|
|
|||
|
|
@ -1053,6 +1053,12 @@ static const struct atmel_pioctrl_data atmel_sama5d2_pioctrl_data = {
|
|||
.last_bank_count = ATMEL_PIO_NPINS_PER_BANK,
|
||||
};
|
||||
|
||||
static const struct atmel_pioctrl_data microchip_sama7d65_pioctrl_data = {
|
||||
.nbanks = 5,
|
||||
.last_bank_count = 14, /* sama7d65 has only PE0 to PE13 */
|
||||
.slew_rate_support = 1,
|
||||
};
|
||||
|
||||
static const struct atmel_pioctrl_data microchip_sama7g5_pioctrl_data = {
|
||||
.nbanks = 5,
|
||||
.last_bank_count = 8, /* sama7g5 has only PE0 to PE7 */
|
||||
|
|
@ -1063,6 +1069,9 @@ static const struct of_device_id atmel_pctrl_of_match[] = {
|
|||
{
|
||||
.compatible = "atmel,sama5d2-pinctrl",
|
||||
.data = &atmel_sama5d2_pioctrl_data,
|
||||
}, {
|
||||
.compatible = "microchip,sama7d65-pinctrl",
|
||||
.data = µchip_sama7d65_pioctrl_data,
|
||||
}, {
|
||||
.compatible = "microchip,sama7g5-pinctrl",
|
||||
.data = µchip_sama7g5_pioctrl_data,
|
||||
|
|
|
|||
|
|
@ -291,14 +291,14 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
|
|||
unsigned int mask, val;
|
||||
int i, rc;
|
||||
|
||||
mutex_lock(&awi->i2c_lock);
|
||||
guard(mutex)(&awi->i2c_lock);
|
||||
for (i = 0; i < num_configs; i++) {
|
||||
param = pinconf_to_config_param(configs[i]);
|
||||
arg = pinconf_to_config_argument(configs[i]);
|
||||
|
||||
rc = aw9523_pcfg_param_to_reg(param, pin, ®);
|
||||
if (rc)
|
||||
goto end;
|
||||
return rc;
|
||||
|
||||
switch (param) {
|
||||
case PIN_CONFIG_LEVEL:
|
||||
|
|
@ -307,7 +307,7 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
|
|||
AW9523_REG_CONF_STATE(pin),
|
||||
BIT(regbit), 0);
|
||||
if (rc)
|
||||
goto end;
|
||||
return rc;
|
||||
|
||||
/* Then, fall through to config output level */
|
||||
fallthrough;
|
||||
|
|
@ -323,10 +323,9 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
|
|||
break;
|
||||
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
|
||||
/* Open-Drain is supported only on port 0 */
|
||||
if (pin >= AW9523_PINS_PER_PORT) {
|
||||
rc = -ENOTSUPP;
|
||||
goto end;
|
||||
}
|
||||
if (pin >= AW9523_PINS_PER_PORT)
|
||||
return -ENOTSUPP;
|
||||
|
||||
mask = AW9523_GCR_GPOMD_MASK;
|
||||
val = 0;
|
||||
break;
|
||||
|
|
@ -341,17 +340,15 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
|
|||
val = AW9523_GCR_GPOMD_MASK;
|
||||
break;
|
||||
default:
|
||||
rc = -ENOTSUPP;
|
||||
goto end;
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
rc = regmap_update_bits(awi->regmap, reg, mask, val);
|
||||
if (rc)
|
||||
goto end;
|
||||
return rc;
|
||||
}
|
||||
end:
|
||||
mutex_unlock(&awi->i2c_lock);
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pinconf_ops aw9523_pinconf_ops = {
|
||||
|
|
@ -599,14 +596,14 @@ static int aw9523_gpio_get_multiple(struct gpio_chip *chip,
|
|||
u8 m, state = 0;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&awi->i2c_lock);
|
||||
guard(mutex)(&awi->i2c_lock);
|
||||
|
||||
/* Port 0 (gpio 0-7) */
|
||||
m = *mask;
|
||||
if (m) {
|
||||
ret = _aw9523_gpio_get_multiple(awi, 0, &state, m);
|
||||
if (ret)
|
||||
goto out;
|
||||
return ret;
|
||||
}
|
||||
*bits = state;
|
||||
|
||||
|
|
@ -616,13 +613,12 @@ static int aw9523_gpio_get_multiple(struct gpio_chip *chip,
|
|||
ret = _aw9523_gpio_get_multiple(awi, AW9523_PINS_PER_PORT,
|
||||
&state, m);
|
||||
if (ret)
|
||||
goto out;
|
||||
return ret;
|
||||
|
||||
*bits |= (state << 8);
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&awi->i2c_lock);
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw9523_gpio_set_multiple(struct gpio_chip *chip,
|
||||
|
|
@ -632,30 +628,28 @@ static int aw9523_gpio_set_multiple(struct gpio_chip *chip,
|
|||
struct aw9523 *awi = gpiochip_get_data(chip);
|
||||
u8 mask_lo, mask_hi, bits_lo, bits_hi;
|
||||
unsigned int reg;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
mask_lo = *mask;
|
||||
mask_hi = *mask >> 8;
|
||||
bits_lo = *bits;
|
||||
bits_hi = *bits >> 8;
|
||||
|
||||
mutex_lock(&awi->i2c_lock);
|
||||
guard(mutex)(&awi->i2c_lock);
|
||||
if (mask_hi) {
|
||||
reg = AW9523_REG_OUT_STATE(AW9523_PINS_PER_PORT);
|
||||
ret = regmap_write_bits(awi->regmap, reg, mask_hi, bits_hi);
|
||||
if (ret)
|
||||
goto out;
|
||||
return ret;
|
||||
}
|
||||
if (mask_lo) {
|
||||
reg = AW9523_REG_OUT_STATE(0);
|
||||
ret = regmap_write_bits(awi->regmap, reg, mask_lo, bits_lo);
|
||||
if (ret)
|
||||
goto out;
|
||||
return ret;
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&awi->i2c_lock);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw9523_gpio_set(struct gpio_chip *chip, unsigned int offset,
|
||||
|
|
@ -695,16 +689,15 @@ static int aw9523_direction_output(struct gpio_chip *chip,
|
|||
u8 regbit = offset % AW9523_PINS_PER_PORT;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&awi->i2c_lock);
|
||||
guard(mutex)(&awi->i2c_lock);
|
||||
ret = regmap_update_bits(awi->regmap, AW9523_REG_OUT_STATE(offset),
|
||||
BIT(regbit), value ? BIT(regbit) : 0);
|
||||
if (ret)
|
||||
goto end;
|
||||
return ret;
|
||||
|
||||
ret = regmap_update_bits(awi->regmap, AW9523_REG_CONF_STATE(offset),
|
||||
BIT(regbit), 0);
|
||||
end:
|
||||
mutex_unlock(&awi->i2c_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -846,6 +846,7 @@ static int pinbank_init(struct device_node *np,
|
|||
|
||||
bank->pin_base = spec.args[1];
|
||||
bank->nr_pins = spec.args[2];
|
||||
of_node_put(spec.np);
|
||||
|
||||
bank->aval_pinmap = readl(bank->membase + REG_AVAIL);
|
||||
bank->id = id;
|
||||
|
|
|
|||
189
drivers/pinctrl/pinctrl-generic.c
Normal file
189
drivers/pinctrl/pinctrl-generic.c
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#define pr_fmt(fmt) "generic pinconfig core: " fmt
|
||||
|
||||
#include <linux/array_size.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <linux/pinctrl/pinconf-generic.h>
|
||||
#include <linux/pinctrl/pinconf.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "pinconf.h"
|
||||
#include "pinctrl-utils.h"
|
||||
#include "pinmux.h"
|
||||
|
||||
static int pinctrl_generic_pins_function_dt_subnode_to_map(struct pinctrl_dev *pctldev,
|
||||
struct device_node *parent,
|
||||
struct device_node *np,
|
||||
struct pinctrl_map **maps,
|
||||
unsigned int *num_maps,
|
||||
unsigned int *num_reserved_maps,
|
||||
const char **group_names,
|
||||
unsigned int ngroups)
|
||||
{
|
||||
struct device *dev = pctldev->dev;
|
||||
const char **functions;
|
||||
const char *group_name;
|
||||
unsigned long *configs;
|
||||
unsigned int num_configs, pin, *pins;
|
||||
int npins, ret, reserve = 1;
|
||||
|
||||
npins = of_property_count_u32_elems(np, "pins");
|
||||
|
||||
if (npins < 1) {
|
||||
dev_err(dev, "invalid pinctrl group %pOFn.%pOFn %d\n",
|
||||
parent, np, npins);
|
||||
return npins;
|
||||
}
|
||||
|
||||
group_name = devm_kasprintf(dev, GFP_KERNEL, "%pOFn.%pOFn", parent, np);
|
||||
if (!group_name)
|
||||
return -ENOMEM;
|
||||
|
||||
group_names[ngroups] = group_name;
|
||||
|
||||
pins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL);
|
||||
if (!pins)
|
||||
return -ENOMEM;
|
||||
|
||||
functions = devm_kcalloc(dev, npins, sizeof(*functions), GFP_KERNEL);
|
||||
if (!functions)
|
||||
return -ENOMEM;
|
||||
|
||||
for (int i = 0; i < npins; i++) {
|
||||
ret = of_property_read_u32_index(np, "pins", i, &pin);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pins[i] = pin;
|
||||
|
||||
ret = of_property_read_string(np, "function", &functions[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = pinctrl_utils_reserve_map(pctldev, maps, num_reserved_maps, num_maps, reserve);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pinctrl_utils_add_map_mux(pctldev, maps, num_reserved_maps, num_maps, group_name,
|
||||
parent->name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = pinctrl_generic_add_group(pctldev, group_name, pins, npins, functions);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret, "failed to add group %s: %d\n",
|
||||
group_name, ret);
|
||||
|
||||
ret = pinconf_generic_parse_dt_config(np, pctldev, &configs, &num_configs);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to parse pin config of group %s\n",
|
||||
group_name);
|
||||
|
||||
if (num_configs == 0)
|
||||
return 0;
|
||||
|
||||
ret = pinctrl_utils_reserve_map(pctldev, maps, num_reserved_maps, num_maps, reserve);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pinctrl_utils_add_map_configs(pctldev, maps, num_reserved_maps, num_maps, group_name,
|
||||
configs,
|
||||
num_configs, PIN_MAP_TYPE_CONFIGS_GROUP);
|
||||
kfree(configs);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
/*
|
||||
* For platforms that do not define groups or functions in the driver, but
|
||||
* instead use the devicetree to describe them. This function will, unlike
|
||||
* pinconf_generic_dt_node_to_map() etc which rely on driver defined groups
|
||||
* and functions, create them in addition to parsing pinconf properties and
|
||||
* adding mappings.
|
||||
*/
|
||||
int pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,
|
||||
struct device_node *np,
|
||||
struct pinctrl_map **maps,
|
||||
unsigned int *num_maps)
|
||||
{
|
||||
struct device *dev = pctldev->dev;
|
||||
struct device_node *child_np;
|
||||
const char **group_names;
|
||||
unsigned int num_reserved_maps = 0;
|
||||
int ngroups = 0;
|
||||
int ret;
|
||||
|
||||
*maps = NULL;
|
||||
*num_maps = 0;
|
||||
|
||||
/*
|
||||
* Check if this is actually the pins node, or a parent containing
|
||||
* multiple pins nodes.
|
||||
*/
|
||||
if (!of_property_present(np, "pins"))
|
||||
goto parent;
|
||||
|
||||
group_names = devm_kcalloc(dev, 1, sizeof(*group_names), GFP_KERNEL);
|
||||
if (!group_names)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = pinctrl_generic_pins_function_dt_subnode_to_map(pctldev, np, np,
|
||||
maps, num_maps,
|
||||
&num_reserved_maps,
|
||||
group_names,
|
||||
ngroups);
|
||||
if (ret) {
|
||||
pinctrl_utils_free_map(pctldev, *maps, *num_maps);
|
||||
return dev_err_probe(dev, ret, "error figuring out mappings for %s\n", np->name);
|
||||
}
|
||||
|
||||
ret = pinmux_generic_add_function(pctldev, np->name, group_names, 1, NULL);
|
||||
if (ret < 0) {
|
||||
pinctrl_utils_free_map(pctldev, *maps, *num_maps);
|
||||
return dev_err_probe(dev, ret, "error adding function %s\n", np->name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
parent:
|
||||
for_each_available_child_of_node(np, child_np)
|
||||
ngroups += 1;
|
||||
|
||||
group_names = devm_kcalloc(dev, ngroups, sizeof(*group_names), GFP_KERNEL);
|
||||
if (!group_names)
|
||||
return -ENOMEM;
|
||||
|
||||
ngroups = 0;
|
||||
for_each_available_child_of_node_scoped(np, child_np) {
|
||||
ret = pinctrl_generic_pins_function_dt_subnode_to_map(pctldev, np, child_np,
|
||||
maps, num_maps,
|
||||
&num_reserved_maps,
|
||||
group_names,
|
||||
ngroups);
|
||||
if (ret) {
|
||||
pinctrl_utils_free_map(pctldev, *maps, *num_maps);
|
||||
return dev_err_probe(dev, ret, "error figuring out mappings for %s\n",
|
||||
np->name);
|
||||
}
|
||||
|
||||
ngroups++;
|
||||
}
|
||||
|
||||
ret = pinmux_generic_add_function(pctldev, np->name, group_names, ngroups, NULL);
|
||||
if (ret < 0) {
|
||||
pinctrl_utils_free_map(pctldev, *maps, *num_maps);
|
||||
return dev_err_probe(dev, ret, "error adding function %s\n", np->name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pinctrl_generic_pins_function_dt_node_to_map);
|
||||
|
|
@ -65,6 +65,7 @@ struct k230_pmx_func {
|
|||
};
|
||||
|
||||
struct k230_pinctrl {
|
||||
struct device *dev;
|
||||
struct pinctrl_desc pctl;
|
||||
struct pinctrl_dev *pctl_dev;
|
||||
struct regmap *regmap_base;
|
||||
|
|
@ -470,7 +471,7 @@ static int k230_pinctrl_parse_groups(struct device_node *np,
|
|||
struct k230_pinctrl *info,
|
||||
unsigned int index)
|
||||
{
|
||||
struct device *dev = info->pctl_dev->dev;
|
||||
struct device *dev = info->dev;
|
||||
const __be32 *list;
|
||||
int size, i, ret;
|
||||
|
||||
|
|
@ -511,7 +512,7 @@ static int k230_pinctrl_parse_functions(struct device_node *np,
|
|||
struct k230_pinctrl *info,
|
||||
unsigned int index)
|
||||
{
|
||||
struct device *dev = info->pctl_dev->dev;
|
||||
struct device *dev = info->dev;
|
||||
struct k230_pmx_func *func;
|
||||
struct k230_pin_group *grp;
|
||||
static unsigned int idx, i;
|
||||
|
|
@ -596,6 +597,8 @@ static int k230_pinctrl_probe(struct platform_device *pdev)
|
|||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
info->dev = dev;
|
||||
|
||||
pctl = &info->pctl;
|
||||
|
||||
pctl->name = "k230-pinctrl";
|
||||
|
|
|
|||
|
|
@ -264,19 +264,17 @@ static int sgpio_single_shot(struct sgpio_priv *priv)
|
|||
* setting.
|
||||
* After the manual burst, reenable the auto repeat mode again.
|
||||
*/
|
||||
mutex_lock(&priv->poll_lock);
|
||||
guard(mutex)(&priv->poll_lock);
|
||||
ret = regmap_update_bits(priv->regs, addr, single_shot | auto_repeat,
|
||||
single_shot);
|
||||
if (ret)
|
||||
goto out;
|
||||
return ret;
|
||||
|
||||
ret = regmap_read_poll_timeout(priv->regs, addr, ctrl,
|
||||
!(ctrl & single_shot), 100, 60000);
|
||||
|
||||
/* reenable auto repeat mode even if there was an error */
|
||||
ret2 = regmap_update_bits(priv->regs, addr, auto_repeat, auto_repeat);
|
||||
out:
|
||||
mutex_unlock(&priv->poll_lock);
|
||||
|
||||
return ret ?: ret2;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,6 +97,8 @@ enum {
|
|||
FUNC_FC_SHRD20,
|
||||
FUNC_FUSA,
|
||||
FUNC_GPIO,
|
||||
FUNC_I2C,
|
||||
FUNC_I2C_Sa,
|
||||
FUNC_IB_TRG_a,
|
||||
FUNC_IB_TRG_b,
|
||||
FUNC_IB_TRG_c,
|
||||
|
|
@ -112,9 +114,11 @@ enum {
|
|||
FUNC_IRQ1,
|
||||
FUNC_IRQ1_IN,
|
||||
FUNC_IRQ1_OUT,
|
||||
FUNC_IRQ2,
|
||||
FUNC_IRQ3,
|
||||
FUNC_IRQ4,
|
||||
FUNC_EXT_IRQ,
|
||||
FUNC_MACLED,
|
||||
FUNC_MIIM,
|
||||
FUNC_MIIM_a,
|
||||
FUNC_MIIM_b,
|
||||
|
|
@ -126,6 +130,7 @@ enum {
|
|||
FUNC_OB_TRG_a,
|
||||
FUNC_OB_TRG_b,
|
||||
FUNC_PHY_LED,
|
||||
FUNC_PHY_DBG,
|
||||
FUNC_PCI_WAKE,
|
||||
FUNC_MD,
|
||||
FUNC_PCIE_PERST,
|
||||
|
|
@ -156,10 +161,12 @@ enum {
|
|||
FUNC_SG0,
|
||||
FUNC_SG1,
|
||||
FUNC_SG2,
|
||||
FUNC_SPI,
|
||||
FUNC_SGPIO_a,
|
||||
FUNC_SGPIO_b,
|
||||
FUNC_SI,
|
||||
FUNC_SI2,
|
||||
FUNC_SI_Sa,
|
||||
FUNC_SYNCE,
|
||||
FUNC_TACHO,
|
||||
FUNC_TACHO_a,
|
||||
|
|
@ -188,6 +195,7 @@ enum {
|
|||
FUNC_EMMC_SD,
|
||||
FUNC_REF_CLK,
|
||||
FUNC_RCVRD_CLK,
|
||||
FUNC_RGMII,
|
||||
FUNC_MAX
|
||||
};
|
||||
|
||||
|
|
@ -237,6 +245,8 @@ static const char *const ocelot_function_names[] = {
|
|||
[FUNC_FC_SHRD20] = "fc_shrd20",
|
||||
[FUNC_FUSA] = "fusa",
|
||||
[FUNC_GPIO] = "gpio",
|
||||
[FUNC_I2C] = "i2c",
|
||||
[FUNC_I2C_Sa] = "i2c_slave_a",
|
||||
[FUNC_IB_TRG_a] = "ib_trig_a",
|
||||
[FUNC_IB_TRG_b] = "ib_trig_b",
|
||||
[FUNC_IB_TRG_c] = "ib_trig_c",
|
||||
|
|
@ -252,9 +262,11 @@ static const char *const ocelot_function_names[] = {
|
|||
[FUNC_IRQ1] = "irq1",
|
||||
[FUNC_IRQ1_IN] = "irq1_in",
|
||||
[FUNC_IRQ1_OUT] = "irq1_out",
|
||||
[FUNC_IRQ2] = "irq2",
|
||||
[FUNC_IRQ3] = "irq3",
|
||||
[FUNC_IRQ4] = "irq4",
|
||||
[FUNC_EXT_IRQ] = "ext_irq",
|
||||
[FUNC_MACLED] = "mac_led",
|
||||
[FUNC_MIIM] = "miim",
|
||||
[FUNC_MIIM_a] = "miim_a",
|
||||
[FUNC_MIIM_b] = "miim_b",
|
||||
|
|
@ -263,6 +275,7 @@ static const char *const ocelot_function_names[] = {
|
|||
[FUNC_MIIM_Sb] = "miim_slave_b",
|
||||
[FUNC_MIIM_IRQ] = "miim_irq",
|
||||
[FUNC_PHY_LED] = "phy_led",
|
||||
[FUNC_PHY_DBG] = "phy_dbg",
|
||||
[FUNC_PCI_WAKE] = "pci_wake",
|
||||
[FUNC_PCIE_PERST] = "pcie_perst",
|
||||
[FUNC_MD] = "md",
|
||||
|
|
@ -300,6 +313,8 @@ static const char *const ocelot_function_names[] = {
|
|||
[FUNC_SGPIO_b] = "sgpio_b",
|
||||
[FUNC_SI] = "si",
|
||||
[FUNC_SI2] = "si2",
|
||||
[FUNC_SI_Sa] = "si_slave_a",
|
||||
[FUNC_SPI] = "spi",
|
||||
[FUNC_SYNCE] = "synce",
|
||||
[FUNC_TACHO] = "tacho",
|
||||
[FUNC_TACHO_a] = "tacho_a",
|
||||
|
|
@ -328,6 +343,7 @@ static const char *const ocelot_function_names[] = {
|
|||
[FUNC_EMMC_SD] = "emmc_sd",
|
||||
[FUNC_REF_CLK] = "ref_clk",
|
||||
[FUNC_RCVRD_CLK] = "rcvrd_clk",
|
||||
[FUNC_RGMII] = "rgmii",
|
||||
};
|
||||
|
||||
struct ocelot_pmx_func {
|
||||
|
|
@ -358,12 +374,14 @@ struct ocelot_pinctrl {
|
|||
const struct ocelot_pincfg_data *pincfg_data;
|
||||
struct ocelot_pmx_func func[FUNC_MAX];
|
||||
u8 stride;
|
||||
u8 altm_stride;
|
||||
struct workqueue_struct *wq;
|
||||
};
|
||||
|
||||
struct ocelot_match_data {
|
||||
struct pinctrl_desc desc;
|
||||
struct ocelot_pincfg_data pincfg_data;
|
||||
unsigned int n_alt_modes;
|
||||
};
|
||||
|
||||
struct ocelot_irq_work {
|
||||
|
|
@ -1321,6 +1339,132 @@ static const struct pinctrl_pin_desc lan969x_pins[] = {
|
|||
LAN969X_PIN(66),
|
||||
};
|
||||
|
||||
#define LAN9645X_P(p, f0, f1, f2, f3, f4, f5, f6, f7) \
|
||||
static struct ocelot_pin_caps lan9645x_pin_##p = { \
|
||||
.pin = p, \
|
||||
.functions = { \
|
||||
FUNC_##f0, FUNC_##f1, FUNC_##f2, \
|
||||
FUNC_##f3 \
|
||||
}, \
|
||||
.a_functions = { \
|
||||
FUNC_##f4, FUNC_##f5, FUNC_##f6, \
|
||||
FUNC_##f7 \
|
||||
}, \
|
||||
}
|
||||
|
||||
/* Pin FUNC0 FUNC1 FUNC2 FUNC3 FUNC4 FUNC5 FUNC6 FUNC7 */
|
||||
LAN9645X_P(0, GPIO, SPI, SI_Sa, I2C_Sa, MIIM_Sa, UART, MIIM, PHY_DBG);
|
||||
LAN9645X_P(1, GPIO, SPI, SI_Sa, I2C_Sa, MIIM_Sa, UART, MIIM, PHY_DBG);
|
||||
LAN9645X_P(2, GPIO, SPI, SI_Sa, I2C, NONE, NONE, NONE, PHY_DBG);
|
||||
LAN9645X_P(3, GPIO, SPI, SI_Sa, I2C, MIIM_Sa, NONE, NONE, PHY_DBG);
|
||||
LAN9645X_P(4, GPIO, RGMII, TWI_SCL_M, I2C, NONE, NONE, SI_Sa, PHY_DBG);
|
||||
LAN9645X_P(5, GPIO, RGMII, TWI_SCL_M, I2C, NONE, NONE, SI_Sa, PHY_DBG);
|
||||
LAN9645X_P(6, GPIO, RGMII, TWI_SCL_M, NONE, NONE, NONE, SI_Sa, PHY_DBG);
|
||||
LAN9645X_P(7, GPIO, RGMII, TWI_SCL_M, SFP, SGPIO_a, MIIM, SI_Sa, PHY_DBG);
|
||||
LAN9645X_P(8, GPIO, RGMII, TWI_SCL_M, SFP, SGPIO_a, MIIM, NONE, PHY_DBG);
|
||||
LAN9645X_P(9, GPIO, RGMII, TWI_SCL_M, RECO_CLK, SGPIO_a, IRQ1, UART, PHY_DBG);
|
||||
LAN9645X_P(10, GPIO, RGMII, TWI_SCL_M, RECO_CLK, SGPIO_a, IRQ2, UART, PHY_DBG);
|
||||
LAN9645X_P(11, GPIO, RGMII, TWI_SCL_M, MIIM, NONE, IRQ3, NONE, PHY_DBG);
|
||||
LAN9645X_P(12, GPIO, RGMII, TWI_SCL_M, MIIM, PTP0, NONE, NONE, PHY_DBG);
|
||||
LAN9645X_P(13, GPIO, RGMII, TWI_SCL_M, CLKMON, PTP1, MACLED, NONE, PHY_DBG);
|
||||
LAN9645X_P(14, GPIO, RGMII, TWI_SCL_M, CLKMON, PTP2, MACLED, NONE, PHY_DBG);
|
||||
LAN9645X_P(15, GPIO, RGMII, TWI_SCL_M, CLKMON, PTP3, NONE, NONE, PHY_DBG);
|
||||
LAN9645X_P(16, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
|
||||
LAN9645X_P(17, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
|
||||
LAN9645X_P(18, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
|
||||
LAN9645X_P(19, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
|
||||
LAN9645X_P(20, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
|
||||
LAN9645X_P(21, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
|
||||
LAN9645X_P(22, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
|
||||
LAN9645X_P(23, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
|
||||
LAN9645X_P(24, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
|
||||
LAN9645X_P(25, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
|
||||
LAN9645X_P(26, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
|
||||
LAN9645X_P(27, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG);
|
||||
LAN9645X_P(28, GPIO, RECO_CLK, MIIM, NONE, NONE, NONE, NONE, R);
|
||||
LAN9645X_P(29, GPIO, RECO_CLK, MIIM, NONE, NONE, NONE, NONE, R);
|
||||
LAN9645X_P(30, GPIO, PTP0, I2C, UART, NONE, NONE, NONE, R);
|
||||
LAN9645X_P(31, GPIO, PTP1, TWI_SCL_M, UART, NONE, NONE, NONE, R);
|
||||
LAN9645X_P(32, GPIO, PTP2, TWI_SCL_M, NONE, NONE, NONE, NONE, R);
|
||||
LAN9645X_P(33, GPIO, PTP3, IRQ0, NONE, NONE, NONE, NONE, R);
|
||||
LAN9645X_P(34, GPIO, RECO_CLK, PHY_LED, PHY_LED, NONE, NONE, NONE, R);
|
||||
LAN9645X_P(35, GPIO, RECO_CLK, PHY_LED, PHY_LED, NONE, MACLED, NONE, R);
|
||||
LAN9645X_P(36, GPIO, PTP0, PHY_LED, PHY_LED, NONE, MACLED, NONE, R);
|
||||
LAN9645X_P(37, GPIO, PTP1, PHY_LED, PHY_LED, NONE, MACLED, NONE, R);
|
||||
LAN9645X_P(38, GPIO, NONE, PHY_LED, PHY_LED, NONE, MACLED, NONE, R);
|
||||
LAN9645X_P(39, GPIO, UART, PHY_LED, NONE, NONE, MACLED, NONE, R);
|
||||
LAN9645X_P(40, GPIO, SPI, PHY_LED, SGPIO_a, NONE, MACLED, NONE, R);
|
||||
LAN9645X_P(41, GPIO, SPI, PHY_LED, SGPIO_a, IRQ1, MACLED, NONE, R);
|
||||
LAN9645X_P(42, GPIO, SPI, PHY_LED, SGPIO_a, IRQ2, MACLED, SFP, R);
|
||||
LAN9645X_P(43, GPIO, SPI, PHY_LED, SGPIO_a, IRQ3, MACLED, SFP, R);
|
||||
LAN9645X_P(44, GPIO, MIIM, I2C, NONE, NONE, NONE, NONE, R);
|
||||
LAN9645X_P(45, GPIO, MIIM, I2C, NONE, NONE, NONE, NONE, R);
|
||||
LAN9645X_P(46, GPIO, NONE, PHY_LED, NONE, NONE, NONE, NONE, R);
|
||||
LAN9645X_P(47, GPIO, NONE, PHY_LED, NONE, NONE, NONE, NONE, R);
|
||||
LAN9645X_P(48, GPIO, MIIM_Sa, PHY_LED, NONE, NONE, NONE, NONE, R);
|
||||
LAN9645X_P(49, GPIO, MIIM_Sa, PHY_LED, I2C_Sa, NONE, NONE, NONE, R);
|
||||
LAN9645X_P(50, GPIO, MIIM_Sa, PHY_LED, I2C_Sa, NONE, NONE, NONE, R);
|
||||
|
||||
#define LAN9645X_PIN(n) { \
|
||||
.number = n, \
|
||||
.name = "GPIO_"#n, \
|
||||
.drv_data = &lan9645x_pin_##n \
|
||||
}
|
||||
|
||||
static const struct pinctrl_pin_desc lan9645x_pins[] = {
|
||||
LAN9645X_PIN(0),
|
||||
LAN9645X_PIN(1),
|
||||
LAN9645X_PIN(2),
|
||||
LAN9645X_PIN(3),
|
||||
LAN9645X_PIN(4),
|
||||
LAN9645X_PIN(5),
|
||||
LAN9645X_PIN(6),
|
||||
LAN9645X_PIN(7),
|
||||
LAN9645X_PIN(8),
|
||||
LAN9645X_PIN(9),
|
||||
LAN9645X_PIN(10),
|
||||
LAN9645X_PIN(11),
|
||||
LAN9645X_PIN(12),
|
||||
LAN9645X_PIN(13),
|
||||
LAN9645X_PIN(14),
|
||||
LAN9645X_PIN(15),
|
||||
LAN9645X_PIN(16),
|
||||
LAN9645X_PIN(17),
|
||||
LAN9645X_PIN(18),
|
||||
LAN9645X_PIN(19),
|
||||
LAN9645X_PIN(20),
|
||||
LAN9645X_PIN(21),
|
||||
LAN9645X_PIN(22),
|
||||
LAN9645X_PIN(23),
|
||||
LAN9645X_PIN(24),
|
||||
LAN9645X_PIN(25),
|
||||
LAN9645X_PIN(26),
|
||||
LAN9645X_PIN(27),
|
||||
LAN9645X_PIN(28),
|
||||
LAN9645X_PIN(29),
|
||||
LAN9645X_PIN(30),
|
||||
LAN9645X_PIN(31),
|
||||
LAN9645X_PIN(32),
|
||||
LAN9645X_PIN(33),
|
||||
LAN9645X_PIN(34),
|
||||
LAN9645X_PIN(35),
|
||||
LAN9645X_PIN(36),
|
||||
LAN9645X_PIN(37),
|
||||
LAN9645X_PIN(38),
|
||||
LAN9645X_PIN(39),
|
||||
LAN9645X_PIN(40),
|
||||
LAN9645X_PIN(41),
|
||||
LAN9645X_PIN(42),
|
||||
LAN9645X_PIN(43),
|
||||
LAN9645X_PIN(44),
|
||||
LAN9645X_PIN(45),
|
||||
LAN9645X_PIN(46),
|
||||
LAN9645X_PIN(47),
|
||||
LAN9645X_PIN(48),
|
||||
LAN9645X_PIN(49),
|
||||
LAN9645X_PIN(50),
|
||||
};
|
||||
|
||||
static int ocelot_get_functions_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
return ARRAY_SIZE(ocelot_function_names);
|
||||
|
|
@ -1362,7 +1506,7 @@ static int ocelot_pin_function_idx(struct ocelot_pinctrl *info,
|
|||
return -1;
|
||||
}
|
||||
|
||||
#define REG_ALT(msb, info, p) (OCELOT_GPIO_ALT0 * (info)->stride + 4 * ((msb) + ((info)->stride * ((p) / 32))))
|
||||
#define REG_ALT(msb, info, p) (OCELOT_GPIO_ALT0 * (info)->stride + 4 * ((msb) + ((info)->altm_stride * ((p) / 32))))
|
||||
|
||||
static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev,
|
||||
unsigned int selector, unsigned int group)
|
||||
|
|
@ -1469,6 +1613,13 @@ static int lan966x_gpio_request_enable(struct pinctrl_dev *pctldev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lan9645x_gpio_request_enable(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
unsigned int offset)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pinmux_ops ocelot_pmx_ops = {
|
||||
.get_functions_count = ocelot_get_functions_count,
|
||||
.get_function_name = ocelot_get_function_name,
|
||||
|
|
@ -1487,6 +1638,15 @@ static const struct pinmux_ops lan966x_pmx_ops = {
|
|||
.gpio_request_enable = lan966x_gpio_request_enable,
|
||||
};
|
||||
|
||||
static const struct pinmux_ops lan9645x_pmx_ops = {
|
||||
.get_functions_count = ocelot_get_functions_count,
|
||||
.get_function_name = ocelot_get_function_name,
|
||||
.get_function_groups = ocelot_get_function_groups,
|
||||
.set_mux = lan966x_pinmux_set_mux,
|
||||
.gpio_set_direction = ocelot_gpio_set_direction,
|
||||
.gpio_request_enable = lan9645x_gpio_request_enable,
|
||||
};
|
||||
|
||||
static int ocelot_pctl_get_groups_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
|
@ -1884,6 +2044,24 @@ static const struct ocelot_match_data lan969x_desc = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct ocelot_match_data lan9645xf_desc = {
|
||||
.desc = {
|
||||
.name = "lan9645xf-pinctrl",
|
||||
.pins = lan9645x_pins,
|
||||
.npins = ARRAY_SIZE(lan9645x_pins),
|
||||
.pctlops = &ocelot_pctl_ops,
|
||||
.pmxops = &lan9645x_pmx_ops,
|
||||
.confops = &ocelot_confops,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.pincfg_data = {
|
||||
.pd_bit = BIT(3),
|
||||
.pu_bit = BIT(2),
|
||||
.drive_bits = GENMASK(1, 0),
|
||||
},
|
||||
.n_alt_modes = 7,
|
||||
};
|
||||
|
||||
static int ocelot_create_group_func_map(struct device *dev,
|
||||
struct ocelot_pinctrl *info)
|
||||
{
|
||||
|
|
@ -2218,6 +2396,7 @@ static const struct of_device_id ocelot_pinctrl_of_match[] = {
|
|||
{ .compatible = "microchip,sparx5-pinctrl", .data = &sparx5_desc },
|
||||
{ .compatible = "microchip,lan966x-pinctrl", .data = &lan966x_desc },
|
||||
{ .compatible = "microchip,lan9691-pinctrl", .data = &lan969x_desc },
|
||||
{ .compatible = "microchip,lan96455f-pinctrl", .data = &lan9645xf_desc },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ocelot_pinctrl_of_match);
|
||||
|
|
@ -2294,6 +2473,9 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
|
|||
reset_control_reset(reset);
|
||||
|
||||
info->stride = 1 + (info->desc->npins - 1) / 32;
|
||||
info->altm_stride = info->stride;
|
||||
if (data->n_alt_modes)
|
||||
info->altm_stride = fls(data->n_alt_modes);
|
||||
|
||||
regmap_config.max_register = OCELOT_GPIO_SD_MAP * info->stride + 15 * 4;
|
||||
|
||||
|
|
|
|||
|
|
@ -3639,17 +3639,16 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
|
|||
* The lock makes sure that either gpio-probe has completed
|
||||
* or the gpio driver hasn't probed yet.
|
||||
*/
|
||||
mutex_lock(&bank->deferred_lock);
|
||||
if (!gpio || !gpio->direction_output) {
|
||||
rc = rockchip_pinconf_defer_pin(bank, pin - bank->pin_base, param,
|
||||
arg);
|
||||
mutex_unlock(&bank->deferred_lock);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
break;
|
||||
scoped_guard(mutex, &bank->deferred_lock) {
|
||||
if (!gpio || !gpio->direction_output) {
|
||||
rc = rockchip_pinconf_defer_pin(bank,
|
||||
pin - bank->pin_base,
|
||||
param, arg);
|
||||
if (rc)
|
||||
return rc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&bank->deferred_lock);
|
||||
}
|
||||
|
||||
switch (param) {
|
||||
|
|
|
|||
|
|
@ -504,8 +504,9 @@ static int pinctrl_scmi_get_pins(struct scmi_pinctrl *pmx,
|
|||
}
|
||||
|
||||
static const char * const scmi_pinctrl_blocklist[] = {
|
||||
"fsl,imx95",
|
||||
"fsl,imx94",
|
||||
"fsl,imx95",
|
||||
"fsl,imx952",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1359,6 +1359,7 @@ static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs)
|
|||
}
|
||||
range = devm_kzalloc(pcs->dev, sizeof(*range), GFP_KERNEL);
|
||||
if (!range) {
|
||||
of_node_put(gpiospec.np);
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1368,6 +1369,7 @@ static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs)
|
|||
mutex_lock(&pcs->mutex);
|
||||
list_add_tail(&range->node, &pcs->gpiofuncs);
|
||||
mutex_unlock(&pcs->mutex);
|
||||
of_node_put(gpiospec.np);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -987,6 +987,7 @@ static int st_pinconf_get(struct pinctrl_dev *pctldev,
|
|||
|
||||
static void st_pinconf_dbg_show(struct pinctrl_dev *pctldev,
|
||||
struct seq_file *s, unsigned pin_id)
|
||||
__must_hold(&pctldev->mutex)
|
||||
{
|
||||
struct st_pio_control *pc;
|
||||
unsigned long config;
|
||||
|
|
|
|||
|
|
@ -607,7 +607,7 @@ static int tb10x_gpio_request_enable(struct pinctrl_dev *pctl,
|
|||
int muxmode = -1;
|
||||
int i;
|
||||
|
||||
mutex_lock(&state->mutex);
|
||||
guard(mutex)(&state->mutex);
|
||||
|
||||
/*
|
||||
* Figure out to which port the requested GPIO belongs and how to
|
||||
|
|
@ -642,7 +642,6 @@ static int tb10x_gpio_request_enable(struct pinctrl_dev *pctl,
|
|||
* Error: The requested pin is already
|
||||
* used for something else.
|
||||
*/
|
||||
mutex_unlock(&state->mutex);
|
||||
return -EBUSY;
|
||||
}
|
||||
break;
|
||||
|
|
@ -667,8 +666,6 @@ static int tb10x_gpio_request_enable(struct pinctrl_dev *pctl,
|
|||
if (muxport >= 0)
|
||||
tb10x_pinctrl_set_config(state, muxport, muxmode);
|
||||
|
||||
mutex_unlock(&state->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -695,34 +692,28 @@ static int tb10x_pctl_set_mux(struct pinctrl_dev *pctl,
|
|||
if (grp->port < 0)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&state->mutex);
|
||||
guard(mutex)(&state->mutex);
|
||||
|
||||
/*
|
||||
* Check if the requested function is compatible with previously
|
||||
* requested functions.
|
||||
*/
|
||||
if (state->ports[grp->port].count
|
||||
&& (state->ports[grp->port].mode != grp->mode)) {
|
||||
mutex_unlock(&state->mutex);
|
||||
&& (state->ports[grp->port].mode != grp->mode))
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the requested function is compatible with previously
|
||||
* requested GPIOs.
|
||||
*/
|
||||
for (i = 0; i < grp->pincnt; i++)
|
||||
if (test_bit(grp->pins[i], state->gpios)) {
|
||||
mutex_unlock(&state->mutex);
|
||||
if (test_bit(grp->pins[i], state->gpios))
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
tb10x_pinctrl_set_config(state, grp->port, grp->mode);
|
||||
|
||||
state->ports[grp->port].count++;
|
||||
|
||||
mutex_unlock(&state->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1729,6 +1729,26 @@ static const struct msm_gpio_wakeirq_map glymur_pdc_map[] = {
|
|||
{ 232, 206 }, { 234, 172 }, { 235, 173 }, { 242, 158 }, { 244, 156 },
|
||||
};
|
||||
|
||||
static const struct msm_gpio_wakeirq_map mahua_pdc_map[] = {
|
||||
{ 0, 116 }, { 2, 114 }, { 3, 115 }, { 4, 175 }, { 5, 176 },
|
||||
{ 7, 111 }, { 11, 129 }, { 13, 130 }, { 15, 112 }, { 19, 113 },
|
||||
{ 23, 187 }, { 27, 188 }, { 28, 121 }, { 29, 122 }, { 30, 136 },
|
||||
{ 31, 203 }, { 32, 189 }, { 34, 174 }, { 35, 190 }, { 36, 191 },
|
||||
{ 39, 124 }, { 43, 192 }, { 47, 193 }, { 51, 123 }, { 53, 133 },
|
||||
{ 55, 125 }, { 59, 131 }, { 64, 134 }, { 65, 150 }, { 66, 186 },
|
||||
{ 67, 132 }, { 68, 195 }, { 71, 135 }, { 75, 196 }, { 79, 197 },
|
||||
{ 83, 198 }, { 84, 181 }, { 85, 199 }, { 87, 200 }, { 91, 201 },
|
||||
{ 92, 182 }, { 93, 183 }, { 94, 184 }, { 95, 185 }, { 98, 202 },
|
||||
{ 105, 157 }, { 113, 128 }, { 121, 117 }, { 123, 118 }, { 125, 119 },
|
||||
{ 129, 120 }, { 131, 126 }, { 132, 160 }, { 133, 194 }, { 134, 127 },
|
||||
{ 141, 137 }, { 144, 138 }, { 145, 139 }, { 147, 140 }, { 148, 141 },
|
||||
{ 150, 146 }, { 151, 147 }, { 153, 148 }, { 154, 144 }, { 155, 159 },
|
||||
{ 156, 149 }, { 157, 151 }, { 163, 142 }, { 172, 143 }, { 181, 145 },
|
||||
{ 193, 161 }, { 196, 152 }, { 203, 177 }, { 208, 178 }, { 215, 162 },
|
||||
{ 217, 153 }, { 220, 154 }, { 221, 155 }, { 228, 179 }, { 230, 180 },
|
||||
{ 232, 206 }, { 234, 172 }, { 235, 173 }, { 242, 158 }, { 244, 156 },
|
||||
};
|
||||
|
||||
static const struct msm_pinctrl_soc_data glymur_tlmm = {
|
||||
.pins = glymur_pins,
|
||||
.npins = ARRAY_SIZE(glymur_pins),
|
||||
|
|
@ -1742,14 +1762,34 @@ static const struct msm_pinctrl_soc_data glymur_tlmm = {
|
|||
.egpio_func = 11,
|
||||
};
|
||||
|
||||
static const struct msm_pinctrl_soc_data mahua_tlmm = {
|
||||
.pins = glymur_pins,
|
||||
.npins = ARRAY_SIZE(glymur_pins),
|
||||
.functions = glymur_functions,
|
||||
.nfunctions = ARRAY_SIZE(glymur_functions),
|
||||
.groups = glymur_groups,
|
||||
.ngroups = ARRAY_SIZE(glymur_groups),
|
||||
.ngpios = 251,
|
||||
.wakeirq_map = mahua_pdc_map,
|
||||
.nwakeirq_map = ARRAY_SIZE(mahua_pdc_map),
|
||||
.egpio_func = 11,
|
||||
};
|
||||
|
||||
static const struct of_device_id glymur_tlmm_of_match[] = {
|
||||
{ .compatible = "qcom,glymur-tlmm", },
|
||||
{ }
|
||||
{ .compatible = "qcom,glymur-tlmm", .data = &glymur_tlmm },
|
||||
{ .compatible = "qcom,mahua-tlmm", .data = &mahua_tlmm },
|
||||
{ },
|
||||
};
|
||||
|
||||
static int glymur_tlmm_probe(struct platform_device *pdev)
|
||||
{
|
||||
return msm_pinctrl_probe(pdev, &glymur_tlmm);
|
||||
const struct msm_pinctrl_soc_data *data;
|
||||
|
||||
data = of_device_get_match_data(&pdev->dev);
|
||||
if (!data)
|
||||
return -ENODEV;
|
||||
|
||||
return msm_pinctrl_probe(pdev, data);
|
||||
}
|
||||
|
||||
static struct platform_driver glymur_tlmm_driver = {
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ static const char * const i2s1_ws_groups[] = { "gpio7" };
|
|||
static const char * const i2s1_data_groups[] = { "gpio8", "gpio9" };
|
||||
static const char * const wsa_swr_clk_groups[] = { "gpio10" };
|
||||
static const char * const wsa_swr_data_groups[] = { "gpio11" };
|
||||
static const char * const i2s2_data_groups[] = { "gpio12", "gpio12" };
|
||||
static const char * const i2s2_data_groups[] = { "gpio12", "gpio13" };
|
||||
|
||||
static const struct lpi_pingroup sm8250_groups[] = {
|
||||
LPI_PINGROUP(0, 0, swr_tx_clk, qua_mi2s_sclk, _, _),
|
||||
|
|
|
|||
|
|
@ -308,9 +308,11 @@ config PINCTRL_RZT2H
|
|||
bool "pin control support for RZ/N2H and RZ/T2H" if COMPILE_TEST
|
||||
depends on 64BIT && OF
|
||||
select GPIOLIB
|
||||
select GPIOLIB_IRQCHIP
|
||||
select GENERIC_PINCTRL_GROUPS
|
||||
select GENERIC_PINMUX_FUNCTIONS
|
||||
select GENERIC_PINCONF
|
||||
select IRQ_DOMAIN_HIERARCHY
|
||||
help
|
||||
This selects GPIO and pinctrl driver for Renesas RZ/T2H
|
||||
platforms.
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
|
@ -51,6 +52,7 @@
|
|||
|
||||
#define PFC_MASK GENMASK_ULL(5, 0)
|
||||
#define PFC_PIN_MASK(pin) (PFC_MASK << ((pin) * 8))
|
||||
#define PFC_FUNC_INTERRUPT 0
|
||||
|
||||
/*
|
||||
* Use 16 lower bits [15:0] for pin identifier
|
||||
|
|
@ -64,6 +66,9 @@
|
|||
|
||||
#define RZT2H_MAX_SAFETY_PORTS 12
|
||||
|
||||
#define RZT2H_INTERRUPTS_START 16
|
||||
#define RZT2H_INTERRUPTS_NUM 17
|
||||
|
||||
struct rzt2h_pinctrl_data {
|
||||
unsigned int n_port_pins;
|
||||
const u8 *port_pin_configs;
|
||||
|
|
@ -79,9 +84,11 @@ struct rzt2h_pinctrl {
|
|||
struct device *dev;
|
||||
struct gpio_chip gpio_chip;
|
||||
struct pinctrl_gpio_range gpio_range;
|
||||
DECLARE_BITMAP(used_irqs, RZT2H_INTERRUPTS_NUM);
|
||||
spinlock_t lock; /* lock read/write registers */
|
||||
struct mutex mutex; /* serialize adding groups and functions */
|
||||
bool safety_port_enabled;
|
||||
atomic_t wakeup_path;
|
||||
};
|
||||
|
||||
#define RZT2H_GET_BASE(pctrl, port) \
|
||||
|
|
@ -119,6 +126,19 @@ static int rzt2h_validate_pin(struct rzt2h_pinctrl *pctrl, unsigned int offset)
|
|||
return (pincfg & BIT(pin)) ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
static void rzt2h_pinctrl_set_gpio_en(struct rzt2h_pinctrl *pctrl,
|
||||
u8 port, u8 pin, bool en)
|
||||
{
|
||||
u8 reg = rzt2h_pinctrl_readb(pctrl, port, PMC(port));
|
||||
|
||||
if (en)
|
||||
reg &= ~BIT(pin);
|
||||
else
|
||||
reg |= BIT(pin);
|
||||
|
||||
rzt2h_pinctrl_writeb(pctrl, port, reg, PMC(port));
|
||||
}
|
||||
|
||||
static void rzt2h_pinctrl_set_pfc_mode(struct rzt2h_pinctrl *pctrl,
|
||||
u8 port, u8 pin, u8 func)
|
||||
{
|
||||
|
|
@ -133,8 +153,7 @@ static void rzt2h_pinctrl_set_pfc_mode(struct rzt2h_pinctrl *pctrl,
|
|||
rzt2h_pinctrl_writew(pctrl, port, reg16, PM(port));
|
||||
|
||||
/* Temporarily switch to GPIO mode with PMC register */
|
||||
reg16 = rzt2h_pinctrl_readb(pctrl, port, PMC(port));
|
||||
rzt2h_pinctrl_writeb(pctrl, port, reg16 & ~BIT(pin), PMC(port));
|
||||
rzt2h_pinctrl_set_gpio_en(pctrl, port, pin, true);
|
||||
|
||||
/* Select Pin function mode with PFC register */
|
||||
reg64 = rzt2h_pinctrl_readq(pctrl, port, PFC(port));
|
||||
|
|
@ -142,8 +161,7 @@ static void rzt2h_pinctrl_set_pfc_mode(struct rzt2h_pinctrl *pctrl,
|
|||
rzt2h_pinctrl_writeq(pctrl, port, reg64 | ((u64)func << (pin * 8)), PFC(port));
|
||||
|
||||
/* Switch to Peripheral pin function with PMC register */
|
||||
reg16 = rzt2h_pinctrl_readb(pctrl, port, PMC(port));
|
||||
rzt2h_pinctrl_writeb(pctrl, port, reg16 | BIT(pin), PMC(port));
|
||||
rzt2h_pinctrl_set_gpio_en(pctrl, port, pin, false);
|
||||
}
|
||||
|
||||
static int rzt2h_pinctrl_set_mux(struct pinctrl_dev *pctldev,
|
||||
|
|
@ -447,7 +465,6 @@ static int rzt2h_gpio_request(struct gpio_chip *chip, unsigned int offset)
|
|||
u8 port = RZT2H_PIN_ID_TO_PORT(offset);
|
||||
u8 bit = RZT2H_PIN_ID_TO_PIN(offset);
|
||||
int ret;
|
||||
u8 reg;
|
||||
|
||||
ret = rzt2h_validate_pin(pctrl, offset);
|
||||
if (ret)
|
||||
|
|
@ -460,9 +477,7 @@ static int rzt2h_gpio_request(struct gpio_chip *chip, unsigned int offset)
|
|||
guard(spinlock_irqsave)(&pctrl->lock);
|
||||
|
||||
/* Select GPIO mode in PMC Register */
|
||||
reg = rzt2h_pinctrl_readb(pctrl, port, PMC(port));
|
||||
reg &= ~BIT(bit);
|
||||
rzt2h_pinctrl_writeb(pctrl, port, reg, PMC(port));
|
||||
rzt2h_pinctrl_set_gpio_en(pctrl, port, bit, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -486,6 +501,7 @@ static int rzt2h_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
|
|||
struct rzt2h_pinctrl *pctrl = gpiochip_get_data(chip);
|
||||
u8 port = RZT2H_PIN_ID_TO_PORT(offset);
|
||||
u8 bit = RZT2H_PIN_ID_TO_PIN(offset);
|
||||
u64 reg64;
|
||||
u16 reg;
|
||||
int ret;
|
||||
|
||||
|
|
@ -493,8 +509,25 @@ static int rzt2h_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (rzt2h_pinctrl_readb(pctrl, port, PMC(port)) & BIT(bit))
|
||||
guard(spinlock_irqsave)(&pctrl->lock);
|
||||
|
||||
if (rzt2h_pinctrl_readb(pctrl, port, PMC(port)) & BIT(bit)) {
|
||||
/*
|
||||
* When a GPIO is being requested as an IRQ, the pinctrl
|
||||
* framework expects to be able to read the GPIO's direction.
|
||||
* IRQ function is separate from GPIO, and enabling it takes the
|
||||
* pin out of GPIO mode.
|
||||
* At this point, .child_to_parent_hwirq() has already been
|
||||
* called to enable the IRQ function.
|
||||
* Default to input direction for IRQ function.
|
||||
*/
|
||||
reg64 = rzt2h_pinctrl_readq(pctrl, port, PFC(port));
|
||||
reg64 = (reg64 >> (bit * 8)) & PFC_MASK;
|
||||
if (reg64 == PFC_FUNC_INTERRUPT)
|
||||
return GPIO_LINE_DIRECTION_IN;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
reg = rzt2h_pinctrl_readw(pctrl, port, PM(port));
|
||||
reg = (reg >> (bit * 2)) & PM_MASK;
|
||||
|
|
@ -617,14 +650,185 @@ static const char * const rzt2h_gpio_names[] = {
|
|||
"P35_0", "P35_1", "P35_2", "P35_3", "P35_4", "P35_5", "P35_6", "P35_7",
|
||||
};
|
||||
|
||||
/*
|
||||
* Interrupts 0-15 are for INTCPUn, which are not exposed externally.
|
||||
* Interrupts 16-31 are for IRQn. SEI is 32.
|
||||
* This table matches the information found in User Manual's Section
|
||||
* 17.5, Multiplexed Pin Configurations, Tables 17.5 to 17.40, on the
|
||||
* Interrupt rows.
|
||||
* RZ/N2H has the same GPIO to IRQ mapping, except for the pins which
|
||||
* are not present.
|
||||
*/
|
||||
static const u8 rzt2h_gpio_irq_map[] = {
|
||||
32, 16, 17, 18, 19, 0, 20, 21,
|
||||
22, 0, 0, 0, 0, 0, 0, 0,
|
||||
23, 24, 25, 26, 27, 0, 0, 0,
|
||||
0, 0, 28, 29, 30, 31, 0, 0,
|
||||
0, 0, 0, 0, 0, 32, 16, 17,
|
||||
18, 19, 20, 21, 22, 0, 0, 0,
|
||||
0, 0, 24, 25, 26, 27, 0, 28,
|
||||
29, 30, 31, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 24, 32, 16,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
20, 23, 17, 18, 19, 0, 16, 25,
|
||||
29, 20, 21, 22, 23, 0, 0, 0,
|
||||
0, 0, 0, 0, 17, 0, 0, 18,
|
||||
0, 0, 19, 0, 0, 20, 0, 30,
|
||||
21, 0, 0, 22, 0, 0, 24, 25,
|
||||
0, 0, 0, 0, 0, 16, 17, 0,
|
||||
18, 0, 0, 26, 27, 0, 0, 0,
|
||||
28, 29, 30, 31, 0, 0, 0, 0,
|
||||
23, 31, 32, 16, 17, 18, 19, 20,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
27, 0, 0, 21, 22, 23, 24, 25,
|
||||
26, 0, 0, 0, 0, 0, 0, 0,
|
||||
27, 28, 29, 30, 31, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 28, 32, 16,
|
||||
17, 18, 19, 0, 0, 0, 0, 20,
|
||||
21, 22, 23, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 24, 25, 0, 0,
|
||||
0, 0, 26, 27, 0, 0, 0, 30,
|
||||
0, 29, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 28, 29, 30, 31, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 30,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
static void rzt2h_gpio_irq_disable(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
unsigned int hwirq = irqd_to_hwirq(d);
|
||||
|
||||
irq_chip_disable_parent(d);
|
||||
gpiochip_disable_irq(gc, hwirq);
|
||||
}
|
||||
|
||||
static void rzt2h_gpio_irq_enable(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
unsigned int hwirq = irqd_to_hwirq(d);
|
||||
|
||||
gpiochip_enable_irq(gc, hwirq);
|
||||
irq_chip_enable_parent(d);
|
||||
}
|
||||
|
||||
static int rzt2h_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct rzt2h_pinctrl *pctrl = container_of(gc, struct rzt2h_pinctrl, gpio_chip);
|
||||
int ret;
|
||||
|
||||
ret = irq_chip_set_wake_parent(d, on);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* If any of the IRQs are in use, put the entire pin controller on the
|
||||
* device wakeup path.
|
||||
*/
|
||||
if (on)
|
||||
atomic_inc(&pctrl->wakeup_path);
|
||||
else
|
||||
atomic_dec(&pctrl->wakeup_path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct irq_chip rzt2h_gpio_irqchip = {
|
||||
.name = "rzt2h-gpio",
|
||||
.irq_disable = rzt2h_gpio_irq_disable,
|
||||
.irq_enable = rzt2h_gpio_irq_enable,
|
||||
.irq_mask = irq_chip_mask_parent,
|
||||
.irq_unmask = irq_chip_unmask_parent,
|
||||
.irq_set_type = irq_chip_set_type_parent,
|
||||
.irq_set_wake = rzt2h_gpio_irq_set_wake,
|
||||
.irq_eoi = irq_chip_eoi_parent,
|
||||
.irq_set_affinity = irq_chip_set_affinity_parent,
|
||||
.flags = IRQCHIP_IMMUTABLE,
|
||||
GPIOCHIP_IRQ_RESOURCE_HELPERS,
|
||||
};
|
||||
|
||||
static int rzt2h_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
|
||||
unsigned int child,
|
||||
unsigned int child_type,
|
||||
unsigned int *parent,
|
||||
unsigned int *parent_type)
|
||||
{
|
||||
struct rzt2h_pinctrl *pctrl = gpiochip_get_data(gc);
|
||||
u8 port = RZT2H_PIN_ID_TO_PORT(child);
|
||||
u8 pin = RZT2H_PIN_ID_TO_PIN(child);
|
||||
u8 parent_irq;
|
||||
|
||||
parent_irq = rzt2h_gpio_irq_map[child];
|
||||
if (parent_irq < RZT2H_INTERRUPTS_START)
|
||||
return -EINVAL;
|
||||
|
||||
if (test_and_set_bit(parent_irq - RZT2H_INTERRUPTS_START,
|
||||
pctrl->used_irqs))
|
||||
return -EBUSY;
|
||||
|
||||
rzt2h_pinctrl_set_pfc_mode(pctrl, port, pin, PFC_FUNC_INTERRUPT);
|
||||
|
||||
*parent = parent_irq;
|
||||
*parent_type = child_type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rzt2h_gpio_irq_domain_free(struct irq_domain *domain, unsigned int virq,
|
||||
unsigned int nr_irqs)
|
||||
{
|
||||
struct irq_data *d = irq_domain_get_irq_data(domain, virq);
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct rzt2h_pinctrl *pctrl = container_of(gc, struct rzt2h_pinctrl, gpio_chip);
|
||||
irq_hw_number_t hwirq = irqd_to_hwirq(d);
|
||||
u8 port = RZT2H_PIN_ID_TO_PORT(hwirq);
|
||||
u8 pin = RZT2H_PIN_ID_TO_PIN(hwirq);
|
||||
|
||||
if (test_and_clear_bit(hwirq - RZT2H_INTERRUPTS_START, pctrl->used_irqs))
|
||||
rzt2h_pinctrl_set_gpio_en(pctrl, port, pin, false);
|
||||
|
||||
irq_domain_free_irqs_common(domain, virq, nr_irqs);
|
||||
}
|
||||
|
||||
static void rzt2h_gpio_init_irq_valid_mask(struct gpio_chip *gc,
|
||||
unsigned long *valid_mask,
|
||||
unsigned int ngpios)
|
||||
{
|
||||
struct rzt2h_pinctrl *pctrl = gpiochip_get_data(gc);
|
||||
unsigned int offset;
|
||||
|
||||
for (offset = 0; offset < ngpios; offset++) {
|
||||
if (!rzt2h_gpio_irq_map[offset] || rzt2h_validate_pin(pctrl, offset))
|
||||
clear_bit(offset, valid_mask);
|
||||
}
|
||||
}
|
||||
|
||||
static int rzt2h_gpio_register(struct rzt2h_pinctrl *pctrl)
|
||||
{
|
||||
struct pinctrl_gpio_range *range = &pctrl->gpio_range;
|
||||
struct gpio_chip *chip = &pctrl->gpio_chip;
|
||||
struct device_node *np = pctrl->dev->of_node;
|
||||
struct irq_domain *parent_domain;
|
||||
struct device *dev = pctrl->dev;
|
||||
struct of_phandle_args of_args;
|
||||
struct device_node *parent_np;
|
||||
struct gpio_irq_chip *girq;
|
||||
int ret;
|
||||
|
||||
parent_np = of_irq_find_parent(np);
|
||||
if (!parent_np)
|
||||
return -ENXIO;
|
||||
|
||||
parent_domain = irq_find_host(parent_np);
|
||||
of_node_put(parent_np);
|
||||
if (!parent_domain)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
ret = of_parse_phandle_with_fixed_args(dev->of_node, "gpio-ranges", 3, 0, &of_args);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Unable to parse gpio-ranges\n");
|
||||
|
|
@ -648,6 +852,17 @@ static int rzt2h_gpio_register(struct rzt2h_pinctrl *pctrl)
|
|||
chip->set = rzt2h_gpio_set;
|
||||
chip->label = dev_name(dev);
|
||||
|
||||
if (of_property_present(np, "interrupt-controller")) {
|
||||
girq = &chip->irq;
|
||||
gpio_irq_chip_set_chip(girq, &rzt2h_gpio_irqchip);
|
||||
girq->fwnode = dev_fwnode(pctrl->dev);
|
||||
girq->parent_domain = parent_domain;
|
||||
girq->child_to_parent_hwirq = rzt2h_gpio_child_to_parent_hwirq;
|
||||
girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_twocell;
|
||||
girq->child_irq_domain_ops.free = rzt2h_gpio_irq_domain_free;
|
||||
girq->init_valid_mask = rzt2h_gpio_init_irq_valid_mask;
|
||||
}
|
||||
|
||||
range->id = 0;
|
||||
range->pin_base = 0;
|
||||
range->base = 0;
|
||||
|
|
@ -792,10 +1007,25 @@ static const struct of_device_id rzt2h_pinctrl_of_table[] = {
|
|||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static int rzt2h_pinctrl_suspend_noirq(struct device *dev)
|
||||
{
|
||||
struct rzt2h_pinctrl *pctrl = dev_get_drvdata(dev);
|
||||
|
||||
if (atomic_read(&pctrl->wakeup_path))
|
||||
device_set_wakeup_path(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops rzt2h_pinctrl_pm_ops = {
|
||||
NOIRQ_SYSTEM_SLEEP_PM_OPS(rzt2h_pinctrl_suspend_noirq, NULL)
|
||||
};
|
||||
|
||||
static struct platform_driver rzt2h_pinctrl_driver = {
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.of_match_table = of_match_ptr(rzt2h_pinctrl_of_table),
|
||||
.pm = pm_sleep_ptr(&rzt2h_pinctrl_pm_ops),
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
.probe = rzt2h_pinctrl_probe,
|
||||
|
|
|
|||
|
|
@ -1770,6 +1770,123 @@ const struct samsung_pinctrl_of_match_data exynos8895_of_data __initconst = {
|
|||
.num_ctrl = ARRAY_SIZE(exynos8895_pin_ctrl),
|
||||
};
|
||||
|
||||
/* pin banks of exynos9610 pin-controller 0 (ALIVE) */
|
||||
static const struct samsung_pin_bank_data exynos9610_pin_banks0[] __initconst = {
|
||||
EXYNOS850_PIN_BANK_EINTN(6, 0x000, "etc0"),
|
||||
GS101_PIN_BANK_EINTW(8, 0x020, "gpa0", 0x00, 0x00),
|
||||
GS101_PIN_BANK_EINTW(8, 0x040, "gpa1", 0x04, 0x08),
|
||||
GS101_PIN_BANK_EINTW(8, 0x060, "gpa2", 0x08, 0x0c),
|
||||
EXYNOS850_PIN_BANK_EINTN(5, 0x080, "gpq0"),
|
||||
};
|
||||
|
||||
/* pin banks of exynos9610 pin-controller 1 (CMGP) */
|
||||
static const struct samsung_pin_bank_data exynos9610_pin_banks1[] __initconst = {
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x000, "gpm0", 0x00),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x020, "gpm1", 0x04),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x040, "gpm2", 0x08),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x060, "gpm3", 0x0C),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x080, "gpm4", 0x10),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x0A0, "gpm5", 0x14),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x0C0, "gpm6", 0x18),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x0E0, "gpm7", 0x1C),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x100, "gpm8", 0x20),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x120, "gpm9", 0x24),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x140, "gpm10", 0x28),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x160, "gpm11", 0x2C),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x180, "gpm12", 0x30),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x1A0, "gpm13", 0x34),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x1C0, "gpm14", 0x38),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x1E0, "gpm15", 0x3C),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x200, "gpm16", 0x40),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x220, "gpm17", 0x44),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x240, "gpm18", 0x48),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x260, "gpm19", 0x4C),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x280, "gpm20", 0x50),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x2A0, "gpm21", 0x54),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x2C0, "gpm22", 0x58),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x2E0, "gpm23", 0x5C),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x300, "gpm24", 0x60),
|
||||
EXYNOS850_PIN_BANK_EINTW(1, 0x320, "gpm25", 0x64),
|
||||
};
|
||||
|
||||
/* pin banks of exynos9610 pin-controller 2 (DISPAUD) */
|
||||
static const struct samsung_pin_bank_data exynos9610_pin_banks2[] __initconst = {
|
||||
GS101_PIN_BANK_EINTG(5, 0x000, "gpb0", 0x00, 0x00),
|
||||
GS101_PIN_BANK_EINTG(4, 0x020, "gpb1", 0x04, 0x08),
|
||||
GS101_PIN_BANK_EINTG(5, 0x040, "gpb2", 0x08, 0x0c),
|
||||
};
|
||||
|
||||
/* pin banks of exynos9610 pin-controller 3 (FSYS) */
|
||||
static const struct samsung_pin_bank_data exynos9610_pin_banks3[] __initconst = {
|
||||
GS101_PIN_BANK_EINTG(4, 0x000, "gpf0", 0x00, 0x00),
|
||||
GS101_PIN_BANK_EINTG(8, 0x020, "gpf1", 0x04, 0x04),
|
||||
GS101_PIN_BANK_EINTG(6, 0x040, "gpf2", 0x08, 0x0c),
|
||||
};
|
||||
|
||||
/* pin banks of exynos9610 pin-controller 4 (TOP) */
|
||||
static const struct samsung_pin_bank_data exynos9610_pin_banks4[] __initconst = {
|
||||
GS101_PIN_BANK_EINTG(8, 0x000, "gpp0", 0x00, 0x00),
|
||||
GS101_PIN_BANK_EINTG(6, 0x020, "gpp1", 0x04, 0x08),
|
||||
GS101_PIN_BANK_EINTG(8, 0x040, "gpp2", 0x08, 0x10),
|
||||
GS101_PIN_BANK_EINTG(8, 0x060, "gpc0", 0x0C, 0x18),
|
||||
GS101_PIN_BANK_EINTG(8, 0x080, "gpc1", 0x10, 0x20),
|
||||
GS101_PIN_BANK_EINTG(5, 0x0A0, "gpc2", 0x14, 0x28),
|
||||
GS101_PIN_BANK_EINTG(8, 0x0C0, "gpg0", 0x18, 0x30),
|
||||
GS101_PIN_BANK_EINTG(8, 0x0E0, "gpg1", 0x1C, 0x38),
|
||||
GS101_PIN_BANK_EINTG(8, 0x100, "gpg2", 0x20, 0x40),
|
||||
GS101_PIN_BANK_EINTG(6, 0x120, "gpg3", 0x24, 0x48),
|
||||
GS101_PIN_BANK_EINTG(3, 0x140, "gpg4", 0x28, 0x50),
|
||||
};
|
||||
|
||||
/* pin banks of exynos9610 pin-controller 5 (SHUB) */
|
||||
static const struct samsung_pin_bank_data exynos9610_pin_banks5[] __initconst = {
|
||||
EXYNOS850_PIN_BANK_EINTG(4, 0x000, "gph0", 0x00),
|
||||
EXYNOS850_PIN_BANK_EINTG(3, 0x020, "gph1", 0x04),
|
||||
};
|
||||
|
||||
static const struct samsung_pin_ctrl exynos9610_pin_ctrl[] __initconst = {
|
||||
{
|
||||
/* pin-controller instance 0 ALIVE data */
|
||||
.pin_banks = exynos9610_pin_banks0,
|
||||
.nr_banks = ARRAY_SIZE(exynos9610_pin_banks0),
|
||||
.eint_wkup_init = exynos_eint_wkup_init,
|
||||
.suspend = exynos_pinctrl_suspend,
|
||||
.resume = exynos_pinctrl_resume,
|
||||
}, {
|
||||
/* pin-controller instance 1 CMGP data */
|
||||
.pin_banks = exynos9610_pin_banks1,
|
||||
.nr_banks = ARRAY_SIZE(exynos9610_pin_banks1),
|
||||
.eint_wkup_init = exynos_eint_wkup_init,
|
||||
.suspend = exynos_pinctrl_suspend,
|
||||
.resume = exynos_pinctrl_resume,
|
||||
}, {
|
||||
/* pin-controller instance 2 DISPAUD data */
|
||||
.pin_banks = exynos9610_pin_banks2,
|
||||
.nr_banks = ARRAY_SIZE(exynos9610_pin_banks2),
|
||||
}, {
|
||||
/* pin-controller instance 3 FSYS data */
|
||||
.pin_banks = exynos9610_pin_banks3,
|
||||
.nr_banks = ARRAY_SIZE(exynos9610_pin_banks3),
|
||||
.suspend = exynos_pinctrl_suspend,
|
||||
.resume = exynos_pinctrl_resume,
|
||||
}, {
|
||||
/* pin-controller instance 4 TOP data */
|
||||
.pin_banks = exynos9610_pin_banks4,
|
||||
.nr_banks = ARRAY_SIZE(exynos9610_pin_banks4),
|
||||
.suspend = exynos_pinctrl_suspend,
|
||||
.resume = exynos_pinctrl_resume,
|
||||
}, {
|
||||
/* pin-controller instance 5 SHUB data */
|
||||
.pin_banks = exynos9610_pin_banks5,
|
||||
.nr_banks = ARRAY_SIZE(exynos9610_pin_banks5),
|
||||
},
|
||||
};
|
||||
|
||||
const struct samsung_pinctrl_of_match_data exynos9610_of_data __initconst = {
|
||||
.ctrl = exynos9610_pin_ctrl,
|
||||
.num_ctrl = ARRAY_SIZE(exynos9610_pin_ctrl),
|
||||
};
|
||||
|
||||
/*
|
||||
* Pinctrl driver data for Tesla FSD SoC. FSD SoC includes three
|
||||
* gpio/pin-mux/pinconfig controllers.
|
||||
|
|
|
|||
|
|
@ -1504,6 +1504,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
|
|||
.data = &exynos8890_of_data },
|
||||
{ .compatible = "samsung,exynos8895-pinctrl",
|
||||
.data = &exynos8895_of_data },
|
||||
{ .compatible = "samsung,exynos9610-pinctrl",
|
||||
.data = &exynos9610_of_data },
|
||||
{ .compatible = "samsung,exynos9810-pinctrl",
|
||||
.data = &exynos9810_of_data },
|
||||
{ .compatible = "samsung,exynos990-pinctrl",
|
||||
|
|
|
|||
|
|
@ -398,6 +398,7 @@ extern const struct samsung_pinctrl_of_match_data exynos7885_of_data;
|
|||
extern const struct samsung_pinctrl_of_match_data exynos850_of_data;
|
||||
extern const struct samsung_pinctrl_of_match_data exynos8890_of_data;
|
||||
extern const struct samsung_pinctrl_of_match_data exynos8895_of_data;
|
||||
extern const struct samsung_pinctrl_of_match_data exynos9610_of_data;
|
||||
extern const struct samsung_pinctrl_of_match_data exynos9810_of_data;
|
||||
extern const struct samsung_pinctrl_of_match_data exynos990_of_data;
|
||||
extern const struct samsung_pinctrl_of_match_data exynosautov9_of_data;
|
||||
|
|
|
|||
|
|
@ -6,11 +6,7 @@
|
|||
#ifndef _PINCTRL_SOPHGO_CV18XX_H
|
||||
#define _PINCTRL_SOPHGO_CV18XX_H
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/pinctrl/pinconf.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -6,12 +6,6 @@
|
|||
#ifndef _PINCTRL_SOPHGO_SG2042_H
|
||||
#define _PINCTRL_SOPHGO_SG2042_H
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/pinctrl/pinconf.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
#
|
||||
|
||||
config PINCTRL_SPACEMIT_K1
|
||||
bool "SpacemiT K1 SoC Pinctrl driver"
|
||||
bool "SpacemiT K1/K3 SoC Pinctrl driver"
|
||||
depends on ARCH_SPACEMIT || COMPILE_TEST
|
||||
depends on OF
|
||||
default ARCH_SPACEMIT
|
||||
|
|
@ -12,7 +12,7 @@ config PINCTRL_SPACEMIT_K1
|
|||
select GENERIC_PINMUX_FUNCTIONS
|
||||
select GENERIC_PINCONF
|
||||
help
|
||||
Say Y to select the pinctrl driver for K1 SoC.
|
||||
Say Y to select the pinctrl driver for K1/K3 SoC.
|
||||
This pin controller allows selecting the mux function for
|
||||
each pin. This driver can also be built as a module called
|
||||
pinctrl-k1.
|
||||
|
|
|
|||
|
|
@ -7,8 +7,10 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
|
|
@ -24,11 +26,12 @@
|
|||
#include "pinctrl-k1.h"
|
||||
|
||||
/*
|
||||
* +---------+----------+-----------+--------+--------+----------+--------+
|
||||
* | pull | drive | schmitter | slew | edge | strong | mux |
|
||||
* | up/down | strength | trigger | rate | detect | pull | mode |
|
||||
* +---------+----------+-----------+--------+--------+----------+--------+
|
||||
* 3 bits 3 bits 2 bits 1 bit 3 bits 1 bit 3 bits
|
||||
* | pull | drive | schmitter | slew | edge | strong | mux |
|
||||
* SoC | up/down | strength | trigger | rate | detect | pull | mode |
|
||||
*-----+---------+----------+-----------+-------+--------+--------+--------+
|
||||
* K1 | 3 bits | 3 bits | 2 bits | 1 bit | 3 bits | 1 bit | 3 bits |
|
||||
*-----+---------+----------+-----------+-------+--------+--------+--------+
|
||||
* K3 | 3 bits | 4 bits | 1 bits | 1 bit | 3 bits | 1 bit | 3 bits |
|
||||
*/
|
||||
|
||||
#define PAD_MUX GENMASK(2, 0)
|
||||
|
|
@ -38,12 +41,50 @@
|
|||
#define PAD_EDGE_CLEAR BIT(6)
|
||||
#define PAD_SLEW_RATE GENMASK(12, 11)
|
||||
#define PAD_SLEW_RATE_EN BIT(7)
|
||||
#define PAD_SCHMITT GENMASK(9, 8)
|
||||
#define PAD_DRIVE GENMASK(12, 10)
|
||||
#define PAD_SCHMITT_K1 GENMASK(9, 8)
|
||||
#define PAD_DRIVE_K1 GENMASK(12, 10)
|
||||
#define PAD_SCHMITT_K3 BIT(8)
|
||||
#define PAD_DRIVE_K3 GENMASK(12, 9)
|
||||
#define PAD_PULLDOWN BIT(13)
|
||||
#define PAD_PULLUP BIT(14)
|
||||
#define PAD_PULL_EN BIT(15)
|
||||
|
||||
#define IO_PWR_DOMAIN_OFFSET 0x800
|
||||
|
||||
#define IO_PWR_DOMAIN_GPIO2_Kx 0x0c
|
||||
#define IO_PWR_DOMAIN_MMC_Kx 0x1c
|
||||
|
||||
#define IO_PWR_DOMAIN_GPIO3_K1 0x10
|
||||
#define IO_PWR_DOMAIN_QSPI_K1 0x20
|
||||
|
||||
#define IO_PWR_DOMAIN_GPIO1_K3 0x04
|
||||
#define IO_PWR_DOMAIN_GPIO5_K3 0x10
|
||||
#define IO_PWR_DOMAIN_GPIO4_K3 0x20
|
||||
#define IO_PWR_DOMAIN_QSPI_K3 0x2c
|
||||
|
||||
#define IO_PWR_DOMAIN_V18EN BIT(2)
|
||||
|
||||
#define APBC_ASFAR 0x50
|
||||
#define APBC_ASSAR 0x54
|
||||
|
||||
#define APBC_ASFAR_AKEY 0xbaba
|
||||
#define APBC_ASSAR_AKEY 0xeb10
|
||||
|
||||
struct spacemit_pin_drv_strength {
|
||||
u8 val;
|
||||
u32 mA;
|
||||
};
|
||||
|
||||
struct spacemit_pinctrl_dconf {
|
||||
u64 schmitt_mask;
|
||||
u64 drive_mask;
|
||||
|
||||
struct spacemit_pin_drv_strength *ds_1v8_tbl;
|
||||
size_t ds_1v8_tbl_num;
|
||||
struct spacemit_pin_drv_strength *ds_3v3_tbl;
|
||||
size_t ds_3v3_tbl_num;
|
||||
};
|
||||
|
||||
struct spacemit_pin {
|
||||
u16 pin;
|
||||
u16 flags;
|
||||
|
|
@ -60,12 +101,17 @@ struct spacemit_pinctrl {
|
|||
raw_spinlock_t lock;
|
||||
|
||||
void __iomem *regs;
|
||||
|
||||
struct regmap *regmap_apbc;
|
||||
};
|
||||
|
||||
struct spacemit_pinctrl_data {
|
||||
const struct pinctrl_pin_desc *pins;
|
||||
const struct spacemit_pin *data;
|
||||
u16 npins;
|
||||
unsigned int (*pin_to_offset)(unsigned int pin);
|
||||
unsigned int (*pin_to_io_pd_offset)(unsigned int pin);
|
||||
const struct spacemit_pinctrl_dconf *dconf;
|
||||
};
|
||||
|
||||
struct spacemit_pin_mux_config {
|
||||
|
|
@ -73,13 +119,8 @@ struct spacemit_pin_mux_config {
|
|||
u32 config;
|
||||
};
|
||||
|
||||
struct spacemit_pin_drv_strength {
|
||||
u8 val;
|
||||
u32 mA;
|
||||
};
|
||||
|
||||
/* map pin id to pinctrl register offset, refer MFPR definition */
|
||||
static unsigned int spacemit_pin_to_offset(unsigned int pin)
|
||||
static unsigned int spacemit_k1_pin_to_offset(unsigned int pin)
|
||||
{
|
||||
unsigned int offset = 0;
|
||||
|
||||
|
|
@ -124,10 +165,67 @@ static unsigned int spacemit_pin_to_offset(unsigned int pin)
|
|||
return offset << 2;
|
||||
}
|
||||
|
||||
static unsigned int spacemit_k3_pin_to_offset(unsigned int pin)
|
||||
{
|
||||
unsigned int offset = pin > 130 ? (pin + 2) : pin;
|
||||
|
||||
return offset << 2;
|
||||
}
|
||||
|
||||
static unsigned int spacemit_k1_pin_to_io_pd_offset(unsigned int pin)
|
||||
{
|
||||
unsigned int offset = 0;
|
||||
|
||||
switch (pin) {
|
||||
case 47 ... 52:
|
||||
offset = IO_PWR_DOMAIN_GPIO3_K1;
|
||||
break;
|
||||
case 75 ... 80:
|
||||
offset = IO_PWR_DOMAIN_GPIO2_Kx;
|
||||
break;
|
||||
case 98 ... 103:
|
||||
offset = IO_PWR_DOMAIN_QSPI_K1;
|
||||
break;
|
||||
case 104 ... 109:
|
||||
offset = IO_PWR_DOMAIN_MMC_Kx;
|
||||
break;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static unsigned int spacemit_k3_pin_to_io_pd_offset(unsigned int pin)
|
||||
{
|
||||
unsigned int offset = 0;
|
||||
|
||||
switch (pin) {
|
||||
case 0 ... 20:
|
||||
offset = IO_PWR_DOMAIN_GPIO1_K3;
|
||||
break;
|
||||
case 21 ... 41:
|
||||
offset = IO_PWR_DOMAIN_GPIO2_Kx;
|
||||
break;
|
||||
case 76 ... 98:
|
||||
offset = IO_PWR_DOMAIN_GPIO4_K3;
|
||||
break;
|
||||
case 99 ... 127:
|
||||
offset = IO_PWR_DOMAIN_GPIO5_K3;
|
||||
break;
|
||||
case 132 ... 137:
|
||||
offset = IO_PWR_DOMAIN_MMC_Kx;
|
||||
break;
|
||||
case 138 ... 144:
|
||||
offset = IO_PWR_DOMAIN_QSPI_K3;
|
||||
break;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static inline void __iomem *spacemit_pin_to_reg(struct spacemit_pinctrl *pctrl,
|
||||
unsigned int pin)
|
||||
{
|
||||
return pctrl->regs + spacemit_pin_to_offset(pin);
|
||||
return pctrl->regs + pctrl->data->pin_to_offset(pin);
|
||||
}
|
||||
|
||||
static u16 spacemit_dt_get_pin(u32 value)
|
||||
|
|
@ -177,7 +275,7 @@ static void spacemit_pctrl_dbg_show(struct pinctrl_dev *pctldev,
|
|||
void __iomem *reg;
|
||||
u32 value;
|
||||
|
||||
seq_printf(seq, "offset: 0x%04x ", spacemit_pin_to_offset(pin));
|
||||
seq_printf(seq, "offset: 0x%04x ", pctrl->data->pin_to_offset(pin));
|
||||
seq_printf(seq, "type: %s ", io_type_desc[type]);
|
||||
|
||||
reg = spacemit_pin_to_reg(pctrl, pin);
|
||||
|
|
@ -185,23 +283,70 @@ static void spacemit_pctrl_dbg_show(struct pinctrl_dev *pctldev,
|
|||
seq_printf(seq, "mux: %ld reg: 0x%04x", (value & PAD_MUX), value);
|
||||
}
|
||||
|
||||
/* use IO high level output current as the table */
|
||||
static struct spacemit_pin_drv_strength spacemit_ds_1v8_tbl[4] = {
|
||||
{ 0, 11 },
|
||||
{ 2, 21 },
|
||||
{ 4, 32 },
|
||||
{ 6, 42 },
|
||||
static const struct spacemit_pinctrl_dconf k1_drive_conf = {
|
||||
.drive_mask = PAD_DRIVE_K1,
|
||||
.schmitt_mask = PAD_SCHMITT_K1,
|
||||
.ds_1v8_tbl = (struct spacemit_pin_drv_strength[]) {
|
||||
{ 0, 11 },
|
||||
{ 2, 21 },
|
||||
{ 4, 32 },
|
||||
{ 6, 42 },
|
||||
},
|
||||
.ds_1v8_tbl_num = 4,
|
||||
.ds_3v3_tbl = (struct spacemit_pin_drv_strength[]) {
|
||||
{ 0, 7 },
|
||||
{ 2, 10 },
|
||||
{ 4, 13 },
|
||||
{ 6, 16 },
|
||||
{ 1, 19 },
|
||||
{ 3, 23 },
|
||||
{ 5, 26 },
|
||||
{ 7, 29 },
|
||||
},
|
||||
.ds_3v3_tbl_num = 8,
|
||||
};
|
||||
|
||||
static struct spacemit_pin_drv_strength spacemit_ds_3v3_tbl[8] = {
|
||||
{ 0, 7 },
|
||||
{ 2, 10 },
|
||||
{ 4, 13 },
|
||||
{ 6, 16 },
|
||||
{ 1, 19 },
|
||||
{ 3, 23 },
|
||||
{ 5, 26 },
|
||||
{ 7, 29 },
|
||||
static const struct spacemit_pinctrl_dconf k3_drive_conf = {
|
||||
.drive_mask = PAD_DRIVE_K3,
|
||||
.schmitt_mask = PAD_SCHMITT_K3,
|
||||
.ds_1v8_tbl = (struct spacemit_pin_drv_strength[]) {
|
||||
{ 0, 2 },
|
||||
{ 1, 4 },
|
||||
{ 2, 6 },
|
||||
{ 3, 7 },
|
||||
{ 4, 9 },
|
||||
{ 5, 11 },
|
||||
{ 6, 13 },
|
||||
{ 7, 14 },
|
||||
{ 8, 21 },
|
||||
{ 9, 23 },
|
||||
{ 10, 25 },
|
||||
{ 11, 26 },
|
||||
{ 12, 28 },
|
||||
{ 13, 30 },
|
||||
{ 14, 31 },
|
||||
{ 15, 33 },
|
||||
},
|
||||
.ds_1v8_tbl_num = 16,
|
||||
.ds_3v3_tbl = (struct spacemit_pin_drv_strength[]) {
|
||||
{ 0, 3 },
|
||||
{ 1, 5 },
|
||||
{ 2, 7 },
|
||||
{ 3, 9 },
|
||||
{ 4, 11 },
|
||||
{ 5, 13 },
|
||||
{ 6, 15 },
|
||||
{ 7, 17 },
|
||||
{ 8, 25 },
|
||||
{ 9, 27 },
|
||||
{ 10, 29 },
|
||||
{ 11, 31 },
|
||||
{ 12, 33 },
|
||||
{ 13, 35 },
|
||||
{ 14, 37 },
|
||||
{ 15, 38 },
|
||||
},
|
||||
.ds_3v3_tbl_num = 16,
|
||||
};
|
||||
|
||||
static inline u8 spacemit_get_ds_value(struct spacemit_pin_drv_strength *tbl,
|
||||
|
|
@ -229,16 +374,17 @@ static inline u32 spacemit_get_ds_mA(struct spacemit_pin_drv_strength *tbl,
|
|||
}
|
||||
|
||||
static inline u8 spacemit_get_driver_strength(enum spacemit_pin_io_type type,
|
||||
const struct spacemit_pinctrl_dconf *dconf,
|
||||
u32 mA)
|
||||
{
|
||||
switch (type) {
|
||||
case IO_TYPE_1V8:
|
||||
return spacemit_get_ds_value(spacemit_ds_1v8_tbl,
|
||||
ARRAY_SIZE(spacemit_ds_1v8_tbl),
|
||||
return spacemit_get_ds_value(dconf->ds_1v8_tbl,
|
||||
dconf->ds_1v8_tbl_num,
|
||||
mA);
|
||||
case IO_TYPE_3V3:
|
||||
return spacemit_get_ds_value(spacemit_ds_3v3_tbl,
|
||||
ARRAY_SIZE(spacemit_ds_3v3_tbl),
|
||||
return spacemit_get_ds_value(dconf->ds_3v3_tbl,
|
||||
dconf->ds_3v3_tbl_num,
|
||||
mA);
|
||||
default:
|
||||
return 0;
|
||||
|
|
@ -246,16 +392,17 @@ static inline u8 spacemit_get_driver_strength(enum spacemit_pin_io_type type,
|
|||
}
|
||||
|
||||
static inline u32 spacemit_get_drive_strength_mA(enum spacemit_pin_io_type type,
|
||||
const struct spacemit_pinctrl_dconf *dconf,
|
||||
u32 value)
|
||||
{
|
||||
switch (type) {
|
||||
case IO_TYPE_1V8:
|
||||
return spacemit_get_ds_mA(spacemit_ds_1v8_tbl,
|
||||
ARRAY_SIZE(spacemit_ds_1v8_tbl),
|
||||
value & 0x6);
|
||||
return spacemit_get_ds_mA(dconf->ds_1v8_tbl,
|
||||
dconf->ds_1v8_tbl_num,
|
||||
value);
|
||||
case IO_TYPE_3V3:
|
||||
return spacemit_get_ds_mA(spacemit_ds_3v3_tbl,
|
||||
ARRAY_SIZE(spacemit_ds_3v3_tbl),
|
||||
return spacemit_get_ds_mA(dconf->ds_3v3_tbl,
|
||||
dconf->ds_3v3_tbl_num,
|
||||
value);
|
||||
default:
|
||||
return 0;
|
||||
|
|
@ -294,6 +441,42 @@ static int spacemit_pctrl_check_power(struct pinctrl_dev *pctldev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void spacemit_set_io_pwr_domain(struct spacemit_pinctrl *pctrl,
|
||||
const struct spacemit_pin *spin,
|
||||
const enum spacemit_pin_io_type type)
|
||||
{
|
||||
u32 offset, val = 0;
|
||||
|
||||
if (!pctrl->regmap_apbc)
|
||||
return;
|
||||
|
||||
offset = pctrl->data->pin_to_io_pd_offset(spin->pin);
|
||||
|
||||
/* Other bits are reserved so don't need to save them */
|
||||
if (type == IO_TYPE_1V8)
|
||||
val = IO_PWR_DOMAIN_V18EN;
|
||||
|
||||
/*
|
||||
* IO power domain registers are protected and cannot be accessed
|
||||
* directly. Before performing any read or write to the IO power
|
||||
* domain registers, an explicit unlock sequence must be issued
|
||||
* via the AIB Secure Access Register (ASAR).
|
||||
*
|
||||
* The unlock sequence allows exactly one subsequent access to the
|
||||
* IO power domain registers. After that access completes, the ASAR
|
||||
* keys are automatically cleared, and the registers become locked
|
||||
* again.
|
||||
*
|
||||
* This mechanism ensures that IO power domain configuration is
|
||||
* performed intentionally, as incorrect voltage settings may
|
||||
* result in functional failures or hardware damage.
|
||||
*/
|
||||
regmap_write(pctrl->regmap_apbc, APBC_ASFAR, APBC_ASFAR_AKEY);
|
||||
regmap_write(pctrl->regmap_apbc, APBC_ASSAR, APBC_ASSAR_AKEY);
|
||||
|
||||
writel_relaxed(val, pctrl->regs + IO_PWR_DOMAIN_OFFSET + offset);
|
||||
}
|
||||
|
||||
static int spacemit_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
|
||||
struct device_node *np,
|
||||
struct pinctrl_map **maps,
|
||||
|
|
@ -501,7 +684,9 @@ static int spacemit_pinconf_get(struct pinctrl_dev *pctldev,
|
|||
|
||||
#define ENABLE_DRV_STRENGTH BIT(1)
|
||||
#define ENABLE_SLEW_RATE BIT(2)
|
||||
static int spacemit_pinconf_generate_config(const struct spacemit_pin *spin,
|
||||
static int spacemit_pinconf_generate_config(struct spacemit_pinctrl *pctrl,
|
||||
const struct spacemit_pin *spin,
|
||||
const struct spacemit_pinctrl_dconf *dconf,
|
||||
unsigned long *configs,
|
||||
unsigned int num_configs,
|
||||
u32 *value)
|
||||
|
|
@ -539,8 +724,8 @@ static int spacemit_pinconf_generate_config(const struct spacemit_pin *spin,
|
|||
drv_strength = arg;
|
||||
break;
|
||||
case PIN_CONFIG_INPUT_SCHMITT:
|
||||
v &= ~PAD_SCHMITT;
|
||||
v |= FIELD_PREP(PAD_SCHMITT, arg);
|
||||
v &= ~dconf->schmitt_mask;
|
||||
v |= (arg << __ffs(dconf->schmitt_mask)) & dconf->schmitt_mask;
|
||||
break;
|
||||
case PIN_CONFIG_POWER_SOURCE:
|
||||
voltage = arg;
|
||||
|
|
@ -574,12 +759,13 @@ static int spacemit_pinconf_generate_config(const struct spacemit_pin *spin,
|
|||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
spacemit_set_io_pwr_domain(pctrl, spin, type);
|
||||
}
|
||||
|
||||
val = spacemit_get_driver_strength(type, drv_strength);
|
||||
val = spacemit_get_driver_strength(type, dconf, drv_strength);
|
||||
|
||||
v &= ~PAD_DRIVE;
|
||||
v |= FIELD_PREP(PAD_DRIVE, val);
|
||||
v &= ~dconf->drive_mask;
|
||||
v |= (val << __ffs(dconf->drive_mask)) & dconf->drive_mask;
|
||||
}
|
||||
|
||||
if (flag & ENABLE_SLEW_RATE) {
|
||||
|
|
@ -629,7 +815,8 @@ static int spacemit_pinconf_set(struct pinctrl_dev *pctldev,
|
|||
const struct spacemit_pin *spin = spacemit_get_pin(pctrl, pin);
|
||||
u32 value;
|
||||
|
||||
if (spacemit_pinconf_generate_config(spin, configs, num_configs, &value))
|
||||
if (spacemit_pinconf_generate_config(pctrl, spin, pctrl->data->dconf,
|
||||
configs, num_configs, &value))
|
||||
return -EINVAL;
|
||||
|
||||
return spacemit_pin_set_config(pctrl, pin, value);
|
||||
|
|
@ -651,7 +838,8 @@ static int spacemit_pinconf_group_set(struct pinctrl_dev *pctldev,
|
|||
return -EINVAL;
|
||||
|
||||
spin = spacemit_get_pin(pctrl, group->grp.pins[0]);
|
||||
if (spacemit_pinconf_generate_config(spin, configs, num_configs, &value))
|
||||
if (spacemit_pinconf_generate_config(pctrl, spin, pctrl->data->dconf,
|
||||
configs, num_configs, &value))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < group->grp.npins; i++)
|
||||
|
|
@ -685,6 +873,7 @@ static void spacemit_pinconf_dbg_show(struct pinctrl_dev *pctldev,
|
|||
struct seq_file *seq, unsigned int pin)
|
||||
{
|
||||
struct spacemit_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct spacemit_pinctrl_dconf *dconf = pctrl->data->dconf;
|
||||
const struct spacemit_pin *spin = spacemit_get_pin(pctrl, pin);
|
||||
enum spacemit_pin_io_type type = spacemit_to_pin_io_type(spin);
|
||||
void __iomem *reg = spacemit_pin_to_reg(pctrl, pin);
|
||||
|
|
@ -695,17 +884,17 @@ static void spacemit_pinconf_dbg_show(struct pinctrl_dev *pctldev,
|
|||
|
||||
seq_printf(seq, ", io type (%s)", io_type_desc[type]);
|
||||
|
||||
tmp = FIELD_GET(PAD_DRIVE, value);
|
||||
tmp = (value & dconf->drive_mask) >> __ffs(dconf->drive_mask);
|
||||
if (type == IO_TYPE_1V8 || type == IO_TYPE_3V3) {
|
||||
mA = spacemit_get_drive_strength_mA(type, tmp);
|
||||
mA = spacemit_get_drive_strength_mA(type, dconf, tmp);
|
||||
seq_printf(seq, ", drive strength (%d mA)", mA);
|
||||
}
|
||||
|
||||
/* drive strength depend on power source, so show all values */
|
||||
if (type == IO_TYPE_EXTERNAL)
|
||||
seq_printf(seq, ", drive strength (%d or %d mA)",
|
||||
spacemit_get_drive_strength_mA(IO_TYPE_1V8, tmp),
|
||||
spacemit_get_drive_strength_mA(IO_TYPE_3V3, tmp));
|
||||
spacemit_get_drive_strength_mA(IO_TYPE_1V8, dconf, tmp),
|
||||
spacemit_get_drive_strength_mA(IO_TYPE_3V3, dconf, tmp));
|
||||
|
||||
seq_printf(seq, ", register (0x%04x)", value);
|
||||
}
|
||||
|
|
@ -720,6 +909,7 @@ static const struct pinconf_ops spacemit_pinconf_ops = {
|
|||
|
||||
static int spacemit_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct spacemit_pinctrl *pctrl;
|
||||
struct clk *func_clk, *bus_clk;
|
||||
|
|
@ -741,6 +931,12 @@ static int spacemit_pinctrl_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(pctrl->regs))
|
||||
return PTR_ERR(pctrl->regs);
|
||||
|
||||
pctrl->regmap_apbc = syscon_regmap_lookup_by_phandle(np, "spacemit,apbc");
|
||||
if (IS_ERR(pctrl->regmap_apbc)) {
|
||||
dev_warn(dev, "no syscon found, disable power voltage switch functionality\n");
|
||||
pctrl->regmap_apbc = NULL;
|
||||
}
|
||||
|
||||
func_clk = devm_clk_get_enabled(dev, "func");
|
||||
if (IS_ERR(func_clk))
|
||||
return dev_err_probe(dev, PTR_ERR(func_clk), "failed to get func clock\n");
|
||||
|
|
@ -1042,10 +1238,352 @@ static const struct spacemit_pinctrl_data k1_pinctrl_data = {
|
|||
.pins = k1_pin_desc,
|
||||
.data = k1_pin_data,
|
||||
.npins = ARRAY_SIZE(k1_pin_desc),
|
||||
.pin_to_offset = spacemit_k1_pin_to_offset,
|
||||
.pin_to_io_pd_offset = spacemit_k1_pin_to_io_pd_offset,
|
||||
.dconf = &k1_drive_conf,
|
||||
};
|
||||
|
||||
static const struct pinctrl_pin_desc k3_pin_desc[] = {
|
||||
PINCTRL_PIN(0, "GPIO_00"),
|
||||
PINCTRL_PIN(1, "GPIO_01"),
|
||||
PINCTRL_PIN(2, "GPIO_02"),
|
||||
PINCTRL_PIN(3, "GPIO_03"),
|
||||
PINCTRL_PIN(4, "GPIO_04"),
|
||||
PINCTRL_PIN(5, "GPIO_05"),
|
||||
PINCTRL_PIN(6, "GPIO_06"),
|
||||
PINCTRL_PIN(7, "GPIO_07"),
|
||||
PINCTRL_PIN(8, "GPIO_08"),
|
||||
PINCTRL_PIN(9, "GPIO_09"),
|
||||
PINCTRL_PIN(10, "GPIO_10"),
|
||||
PINCTRL_PIN(11, "GPIO_11"),
|
||||
PINCTRL_PIN(12, "GPIO_12"),
|
||||
PINCTRL_PIN(13, "GPIO_13"),
|
||||
PINCTRL_PIN(14, "GPIO_14"),
|
||||
PINCTRL_PIN(15, "GPIO_15"),
|
||||
PINCTRL_PIN(16, "GPIO_16"),
|
||||
PINCTRL_PIN(17, "GPIO_17"),
|
||||
PINCTRL_PIN(18, "GPIO_18"),
|
||||
PINCTRL_PIN(19, "GPIO_19"),
|
||||
PINCTRL_PIN(20, "GPIO_20"),
|
||||
PINCTRL_PIN(21, "GPIO_21"),
|
||||
PINCTRL_PIN(22, "GPIO_22"),
|
||||
PINCTRL_PIN(23, "GPIO_23"),
|
||||
PINCTRL_PIN(24, "GPIO_24"),
|
||||
PINCTRL_PIN(25, "GPIO_25"),
|
||||
PINCTRL_PIN(26, "GPIO_26"),
|
||||
PINCTRL_PIN(27, "GPIO_27"),
|
||||
PINCTRL_PIN(28, "GPIO_28"),
|
||||
PINCTRL_PIN(29, "GPIO_29"),
|
||||
PINCTRL_PIN(30, "GPIO_30"),
|
||||
PINCTRL_PIN(31, "GPIO_31"),
|
||||
PINCTRL_PIN(32, "GPIO_32"),
|
||||
PINCTRL_PIN(33, "GPIO_33"),
|
||||
PINCTRL_PIN(34, "GPIO_34"),
|
||||
PINCTRL_PIN(35, "GPIO_35"),
|
||||
PINCTRL_PIN(36, "GPIO_36"),
|
||||
PINCTRL_PIN(37, "GPIO_37"),
|
||||
PINCTRL_PIN(38, "GPIO_38"),
|
||||
PINCTRL_PIN(39, "GPIO_39"),
|
||||
PINCTRL_PIN(40, "GPIO_40"),
|
||||
PINCTRL_PIN(41, "GPIO_41"),
|
||||
PINCTRL_PIN(42, "GPIO_42"),
|
||||
PINCTRL_PIN(43, "GPIO_43"),
|
||||
PINCTRL_PIN(44, "GPIO_44"),
|
||||
PINCTRL_PIN(45, "GPIO_45"),
|
||||
PINCTRL_PIN(46, "GPIO_46"),
|
||||
PINCTRL_PIN(47, "GPIO_47"),
|
||||
PINCTRL_PIN(48, "GPIO_48"),
|
||||
PINCTRL_PIN(49, "GPIO_49"),
|
||||
PINCTRL_PIN(50, "GPIO_50"),
|
||||
PINCTRL_PIN(51, "GPIO_51"),
|
||||
PINCTRL_PIN(52, "GPIO_52"),
|
||||
PINCTRL_PIN(53, "GPIO_53"),
|
||||
PINCTRL_PIN(54, "GPIO_54"),
|
||||
PINCTRL_PIN(55, "GPIO_55"),
|
||||
PINCTRL_PIN(56, "GPIO_56"),
|
||||
PINCTRL_PIN(57, "GPIO_57"),
|
||||
PINCTRL_PIN(58, "GPIO_58"),
|
||||
PINCTRL_PIN(59, "GPIO_59"),
|
||||
PINCTRL_PIN(60, "GPIO_60"),
|
||||
PINCTRL_PIN(61, "GPIO_61"),
|
||||
PINCTRL_PIN(62, "GPIO_62"),
|
||||
PINCTRL_PIN(63, "GPIO_63"),
|
||||
PINCTRL_PIN(64, "GPIO_64"),
|
||||
PINCTRL_PIN(65, "GPIO_65"),
|
||||
PINCTRL_PIN(66, "GPIO_66"),
|
||||
PINCTRL_PIN(67, "GPIO_67"),
|
||||
PINCTRL_PIN(68, "GPIO_68"),
|
||||
PINCTRL_PIN(69, "GPIO_69"),
|
||||
PINCTRL_PIN(70, "GPIO_70"),
|
||||
PINCTRL_PIN(71, "GPIO_71"),
|
||||
PINCTRL_PIN(72, "GPIO_72"),
|
||||
PINCTRL_PIN(73, "GPIO_73"),
|
||||
PINCTRL_PIN(74, "GPIO_74"),
|
||||
PINCTRL_PIN(75, "GPIO_75"),
|
||||
PINCTRL_PIN(76, "GPIO_76"),
|
||||
PINCTRL_PIN(77, "GPIO_77"),
|
||||
PINCTRL_PIN(78, "GPIO_78"),
|
||||
PINCTRL_PIN(79, "GPIO_79"),
|
||||
PINCTRL_PIN(80, "GPIO_80"),
|
||||
PINCTRL_PIN(81, "GPIO_81"),
|
||||
PINCTRL_PIN(82, "GPIO_82"),
|
||||
PINCTRL_PIN(83, "GPIO_83"),
|
||||
PINCTRL_PIN(84, "GPIO_84"),
|
||||
PINCTRL_PIN(85, "GPIO_85"),
|
||||
PINCTRL_PIN(86, "GPIO_86"),
|
||||
PINCTRL_PIN(87, "GPIO_87"),
|
||||
PINCTRL_PIN(88, "GPIO_88"),
|
||||
PINCTRL_PIN(89, "GPIO_89"),
|
||||
PINCTRL_PIN(90, "GPIO_90"),
|
||||
PINCTRL_PIN(91, "GPIO_91"),
|
||||
PINCTRL_PIN(92, "GPIO_92"),
|
||||
PINCTRL_PIN(93, "GPIO_93"),
|
||||
PINCTRL_PIN(94, "GPIO_94"),
|
||||
PINCTRL_PIN(95, "GPIO_95"),
|
||||
PINCTRL_PIN(96, "GPIO_96"),
|
||||
PINCTRL_PIN(97, "GPIO_97"),
|
||||
PINCTRL_PIN(98, "GPIO_98"),
|
||||
PINCTRL_PIN(99, "GPIO_99"),
|
||||
PINCTRL_PIN(100, "GPIO_100"),
|
||||
PINCTRL_PIN(101, "GPIO_101"),
|
||||
PINCTRL_PIN(102, "GPIO_102"),
|
||||
PINCTRL_PIN(103, "GPIO_103"),
|
||||
PINCTRL_PIN(104, "GPIO_104"),
|
||||
PINCTRL_PIN(105, "GPIO_105"),
|
||||
PINCTRL_PIN(106, "GPIO_106"),
|
||||
PINCTRL_PIN(107, "GPIO_107"),
|
||||
PINCTRL_PIN(108, "GPIO_108"),
|
||||
PINCTRL_PIN(109, "GPIO_109"),
|
||||
PINCTRL_PIN(110, "GPIO_110"),
|
||||
PINCTRL_PIN(111, "GPIO_111"),
|
||||
PINCTRL_PIN(112, "GPIO_112"),
|
||||
PINCTRL_PIN(113, "GPIO_113"),
|
||||
PINCTRL_PIN(114, "GPIO_114"),
|
||||
PINCTRL_PIN(115, "GPIO_115"),
|
||||
PINCTRL_PIN(116, "GPIO_116"),
|
||||
PINCTRL_PIN(117, "GPIO_117"),
|
||||
PINCTRL_PIN(118, "GPIO_118"),
|
||||
PINCTRL_PIN(119, "GPIO_119"),
|
||||
PINCTRL_PIN(120, "GPIO_120"),
|
||||
PINCTRL_PIN(121, "GPIO_121"),
|
||||
PINCTRL_PIN(122, "GPIO_122"),
|
||||
PINCTRL_PIN(123, "GPIO_123"),
|
||||
PINCTRL_PIN(124, "GPIO_124"),
|
||||
PINCTRL_PIN(125, "GPIO_125"),
|
||||
PINCTRL_PIN(126, "GPIO_126"),
|
||||
PINCTRL_PIN(127, "GPIO_127"),
|
||||
PINCTRL_PIN(128, "PWR_SCL"),
|
||||
PINCTRL_PIN(129, "PWR_SDA"),
|
||||
PINCTRL_PIN(130, "VCXO_EN"),
|
||||
PINCTRL_PIN(131, "PMIC_INT_N"),
|
||||
PINCTRL_PIN(132, "MMC1_DAT3"),
|
||||
PINCTRL_PIN(133, "MMC1_DAT2"),
|
||||
PINCTRL_PIN(134, "MMC1_DAT1"),
|
||||
PINCTRL_PIN(135, "MMC1_DAT0"),
|
||||
PINCTRL_PIN(136, "MMC1_CMD"),
|
||||
PINCTRL_PIN(137, "MMC1_CLK"),
|
||||
PINCTRL_PIN(138, "QSPI_DAT0"),
|
||||
PINCTRL_PIN(139, "QSPI_DAT1"),
|
||||
PINCTRL_PIN(140, "QSPI_DAT2"),
|
||||
PINCTRL_PIN(141, "QSPI_DAT3"),
|
||||
PINCTRL_PIN(142, "QSPI_CS0"),
|
||||
PINCTRL_PIN(143, "QSPI_CS1"),
|
||||
PINCTRL_PIN(144, "QSPI_CLK"),
|
||||
PINCTRL_PIN(145, "PRI_TDI"),
|
||||
PINCTRL_PIN(146, "PRI_TMS"),
|
||||
PINCTRL_PIN(147, "PRI_TCK"),
|
||||
PINCTRL_PIN(148, "PRI_TDO"),
|
||||
PINCTRL_PIN(149, "PWR_SSP_SCLK"),
|
||||
PINCTRL_PIN(150, "PWR_SSP_FRM"),
|
||||
PINCTRL_PIN(151, "PWR_SSP_TXD"),
|
||||
PINCTRL_PIN(152, "PWR_SSP_RXD"),
|
||||
};
|
||||
|
||||
static const struct spacemit_pin k3_pin_data[ARRAY_SIZE(k3_pin_desc)] = {
|
||||
/* GPIO1 bank */
|
||||
K1_FUNC_PIN(0, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(1, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(2, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(3, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(4, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(5, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(6, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(7, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(8, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(9, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(10, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(11, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(12, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(13, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(14, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(15, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(16, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(17, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(18, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(19, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(20, 0, IO_TYPE_EXTERNAL),
|
||||
|
||||
/* GPIO2 bank */
|
||||
K1_FUNC_PIN(21, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(22, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(23, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(24, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(25, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(26, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(27, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(28, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(29, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(30, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(31, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(32, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(33, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(34, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(35, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(36, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(37, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(38, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(39, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(40, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(41, 0, IO_TYPE_EXTERNAL),
|
||||
|
||||
/* GPIO3 bank */
|
||||
K1_FUNC_PIN(42, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(43, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(44, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(45, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(46, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(47, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(48, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(49, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(50, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(51, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(52, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(53, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(54, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(55, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(56, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(57, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(58, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(59, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(60, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(61, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(62, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(63, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(64, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(65, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(66, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(67, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(68, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(69, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(70, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(71, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(72, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(73, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(74, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(75, 0, IO_TYPE_1V8),
|
||||
|
||||
/* GPIO4 bank */
|
||||
K1_FUNC_PIN(76, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(77, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(78, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(79, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(80, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(81, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(82, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(83, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(84, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(85, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(86, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(87, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(88, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(89, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(90, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(91, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(92, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(93, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(94, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(95, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(96, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(97, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(98, 0, IO_TYPE_EXTERNAL),
|
||||
|
||||
/* GPIO5 bank */
|
||||
K1_FUNC_PIN(99, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(100, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(101, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(102, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(103, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(104, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(105, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(106, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(107, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(108, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(109, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(110, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(111, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(112, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(113, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(114, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(115, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(116, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(117, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(118, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(119, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(120, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(121, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(122, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(123, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(124, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(125, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(126, 0, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(127, 0, IO_TYPE_EXTERNAL),
|
||||
|
||||
/* PMIC */
|
||||
K1_FUNC_PIN(128, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(129, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(130, 0, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(131, 0, IO_TYPE_1V8),
|
||||
|
||||
/* SD/MMC1 */
|
||||
K1_FUNC_PIN(132, 1, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(133, 1, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(134, 1, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(135, 1, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(136, 1, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(137, 1, IO_TYPE_EXTERNAL),
|
||||
|
||||
/* QSPI */
|
||||
K1_FUNC_PIN(138, 1, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(139, 1, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(140, 1, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(141, 1, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(142, 1, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(143, 1, IO_TYPE_EXTERNAL),
|
||||
K1_FUNC_PIN(144, 1, IO_TYPE_EXTERNAL),
|
||||
|
||||
/* PMIC */
|
||||
K1_FUNC_PIN(145, 1, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(146, 1, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(147, 1, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(148, 1, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(149, 1, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(150, 1, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(151, 1, IO_TYPE_1V8),
|
||||
K1_FUNC_PIN(152, 1, IO_TYPE_1V8),
|
||||
};
|
||||
|
||||
static const struct spacemit_pinctrl_data k3_pinctrl_data = {
|
||||
.pins = k3_pin_desc,
|
||||
.data = k3_pin_data,
|
||||
.npins = ARRAY_SIZE(k3_pin_desc),
|
||||
.pin_to_offset = spacemit_k3_pin_to_offset,
|
||||
.pin_to_io_pd_offset = spacemit_k3_pin_to_io_pd_offset,
|
||||
.dconf = &k3_drive_conf,
|
||||
};
|
||||
|
||||
static const struct of_device_id k1_pinctrl_ids[] = {
|
||||
{ .compatible = "spacemit,k1-pinctrl", .data = &k1_pinctrl_data },
|
||||
{ .compatible = "spacemit,k3-pinctrl", .data = &k3_pinctrl_data },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, k1_pinctrl_ids);
|
||||
|
|
@ -1061,5 +1599,5 @@ static struct platform_driver k1_pinctrl_driver = {
|
|||
builtin_platform_driver(k1_pinctrl_driver);
|
||||
|
||||
MODULE_AUTHOR("Yixun Lan <dlan@gentoo.org>");
|
||||
MODULE_DESCRIPTION("Pinctrl driver for the SpacemiT K1 SoC");
|
||||
MODULE_DESCRIPTION("Pinctrl driver for the SpacemiT K1/K3 SoC");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -7,14 +7,11 @@
|
|||
*/
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
|
|
|
|||
|
|
@ -474,14 +474,14 @@ static const struct pinconf_ops tegra_xusb_padctl_pinconf_ops = {
|
|||
#endif
|
||||
};
|
||||
|
||||
static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl)
|
||||
static void tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl)
|
||||
{
|
||||
u32 value;
|
||||
|
||||
mutex_lock(&padctl->lock);
|
||||
guard(mutex)(&padctl->lock);
|
||||
|
||||
if (padctl->enable++ > 0)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
|
||||
value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
|
||||
|
|
@ -498,23 +498,19 @@ static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl)
|
|||
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
|
||||
value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
|
||||
|
||||
out:
|
||||
mutex_unlock(&padctl->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl)
|
||||
static void tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl)
|
||||
{
|
||||
u32 value;
|
||||
|
||||
mutex_lock(&padctl->lock);
|
||||
guard(mutex)(&padctl->lock);
|
||||
|
||||
if (WARN_ON(padctl->enable == 0))
|
||||
goto out;
|
||||
return;
|
||||
|
||||
if (--padctl->enable > 0)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
|
||||
value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
|
||||
|
|
@ -531,24 +527,24 @@ static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl)
|
|||
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
|
||||
value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
|
||||
|
||||
out:
|
||||
mutex_unlock(&padctl->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_xusb_phy_init(struct phy *phy)
|
||||
{
|
||||
struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
|
||||
|
||||
return tegra_xusb_padctl_enable(padctl);
|
||||
tegra_xusb_padctl_enable(padctl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_xusb_phy_exit(struct phy *phy)
|
||||
{
|
||||
struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
|
||||
|
||||
return tegra_xusb_padctl_disable(padctl);
|
||||
tegra_xusb_padctl_disable(padctl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pcie_phy_power_on(struct phy *phy)
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ struct dev_pin_info {
|
|||
#endif
|
||||
};
|
||||
|
||||
extern int pinctrl_bind_pins(struct device *dev);
|
||||
extern int pinctrl_init_done(struct device *dev);
|
||||
|
||||
static inline struct pinctrl *dev_pinctrl(struct device *dev)
|
||||
|
|
@ -58,11 +57,6 @@ static inline struct pinctrl *dev_pinctrl(struct device *dev)
|
|||
|
||||
/* Stubs if we're not using pinctrl */
|
||||
|
||||
static inline int pinctrl_bind_pins(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pinctrl_init_done(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -250,9 +250,4 @@ static inline int pinconf_generic_dt_node_to_map_all(struct pinctrl_dev *pctldev
|
|||
return pinconf_generic_dt_node_to_map(pctldev, np_config, map, num_maps,
|
||||
PIN_MAP_TYPE_INVALID);
|
||||
}
|
||||
|
||||
int pinconf_generic_dt_node_to_map_pinmux(struct pinctrl_dev *pctldev,
|
||||
struct device_node *np,
|
||||
struct pinctrl_map **map,
|
||||
unsigned int *num_maps);
|
||||
#endif /* __LINUX_PINCTRL_PINCONF_GENERIC_H */
|
||||
|
|
|
|||
|
|
@ -187,9 +187,6 @@ extern struct pinctrl_dev *devm_pinctrl_register(struct device *dev,
|
|||
const struct pinctrl_desc *pctldesc,
|
||||
void *driver_data);
|
||||
|
||||
extern void devm_pinctrl_unregister(struct device *dev,
|
||||
struct pinctrl_dev *pctldev);
|
||||
|
||||
extern void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range);
|
||||
extern void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue