General improvements:

- Nicer debugfs output with one pin/config pair per line.
 
 - Continued efforts to strictify module vs bool.
 
 - Constification and similar from Coccinelle engineers.
 
 - Return error from pinctrl_bind_pins()
 
 - Pulling in the ability to selectively disable mapping of
   unusable IRQs from the GPIO subsystem.
 
 New drivers:
 
 - New driver for the Aspeed pin controller family: AST2400 (G4)
   and AST2500 (G5) are supported. These are used by OpenBMC
   on the IBM Witherspoon platform.
 
 - New subdriver for the Allwinner sunxi GR8.
 
 Driver improvements:
 
 - Drop default IRQ trigger types assigned during IRQ mapping on
   AT91 and Nomadik. This error was identified by improvements in
   the IRQ core by Marc Zyngier.
 
 - Active high/low types on the GPIO IRQs for the ST pin
   controller.
 
 - IRQ support on GPIOs on the STM32 pin controller.
 
 - Renesas Super-H/ARM sh-pfc: continued massive developments.
 
 - Misc MXC improvements.
 
 - SPDIF on the Allwiner A31 SoC
 
 - IR remote and SPI NOR flash, NAND flash, I2C pins on the
   AMLogic SoC.
 
 - PWM pins on the Meson.
 
 - Do not map unusable IRQs (taken by BIOS) on the Intel Cherryview.
 
 - Add GPIO IRQ wakeup support to the Intel driver so we can wake up
   from button pushes.
 
 Deprecation:
 
 - Deleted the obsolete STiH415/6 SoC support.
 -----BEGIN PGP SIGNATURE-----
 
 iQIcBAABAgAGBQJX9N/vAAoJEEEQszewGV1zQk0P/2LAB9Xk0YyPnCcjZ10/EZvn
 rSP2Jn5JymGTbbOrF11yHFIHAaT8LLVOkVBdaFgYR7Ek29vWLj4CB3+OkAEpuEMj
 UqBNraTC3qldCmMH/t9cXuhEVia1dEEbHcafup9LJVlPBPq/52c9/DOCzg6icMhh
 hem3bLlkLoxXmuQkQW0O6xoqtqW9rqeHdV33lmaSB/g3J6R2hReHV1M8yjQ+gYfQ
 JRVwJR6A51BOZ1EAVTuLRlFSaZFKiSdv8164zIYEME0mRJYjDyDA6qGLyQvX7sFO
 /kBbF0yLXIc86ssZsXVs355NsiJJmVMEGLRXkaVxQ1sH/35k7TvCgrSZ7woggBnE
 D/uPDYja0HJ8KJ+mV/AXhLSadism8ESwn7g/nG932GjhMNpHuYQHZmb5hHKlg8eu
 5VPeiZa54VoPOEx2bIfBVm7TKdwjzUlkOCb5Iyq1N9MAmH7f5pejxJBELZ9+vCjh
 QwnK2DdfUWvDI2PlE+dX8GNpUwilMsS+IOgKOj80qTl2dt0JniMmvhBjEGRqpS8y
 KOlyCLETsBVkxKHBawWSGIs1IER/U9TcJn6Xsp4rR/vqI4bI/MDDN+BgK1N6GiiE
 4dkhCnIxHtDva1dbOIWH9JCyAzqyEYo3DfYSmPKlwPDZxEbtMmhcr8iKV299zwa0
 lraII2LJmdQMzH2eY5vS
 =APsF
 -----END PGP SIGNATURE-----

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

Pull pin control updates from Linus Walleij:
 "This is the bulk of pin control changes for the v4.9 cycle.

  General improvements:

   - nicer debugfs output with one pin/config pair per line.

   - continued efforts to strictify module vs bool.

   - constification and similar from Coccinelle engineers.

   - return error from pinctrl_bind_pins()

   - pulling in the ability to selectively disable mapping of unusable
     IRQs from the GPIO subsystem.

  New drivers:

   - new driver for the Aspeed pin controller family: AST2400 (G4) and
     AST2500 (G5) are supported. These are used by OpenBMC on the IBM
     Witherspoon platform.

   - new subdriver for the Allwinner sunxi GR8.

  Driver improvements:

   - drop default IRQ trigger types assigned during IRQ mapping on AT91
     and Nomadik. This error was identified by improvements in the IRQ
     core by Marc Zyngier.

   - active high/low types on the GPIO IRQs for the ST pin controller.

   - IRQ support on GPIOs on the STM32 pin controller.

   - Renesas Super-H/ARM sh-pfc: continued massive developments.

   - misc MXC improvements.

   - SPDIF on the Allwiner A31 SoC

   - IR remote and SPI NOR flash, NAND flash, I2C pins on the AMLogic
     SoC.

   - PWM pins on the Meson.

   - do not map unusable IRQs (taken by BIOS) on the Intel Cherryview.

   - add GPIO IRQ wakeup support to the Intel driver so we can wake up
     from button pushes.

  Deprecation:

   - delete the obsolete STiH415/6 SoC support"

* tag 'pinctrl-v4.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (75 commits)
  pinctrl: qcom: fix masking of pinmux functions
  pinctrl: intel: Configure GPIO chip IRQ as wakeup interrupts
  pinctrl: cherryview: Convert to use devm_gpiochip_add_data()
  pinctrl: cherryview: Do not add all southwest and north GPIOs to IRQ domain
  gpiolib: Make it possible to exclude GPIOs from IRQ domain
  pinctrl: nomadik: don't default-flag IRQs as falling
  pinctrl: st: Remove obsolete platforms from pinctrl-st dt doc
  pinctrl: st: Remove STiH415/6 SoC pinctrl driver support.
  pinctrl: amlogic: gxbb: add i2c pins
  pinctrl: amlogic: gxbb: add nand pins
  pinctrl: stm32: add IRQ_DOMAIN_HIERARCHY dependency
  pinctrl: amlogic: gxbb: add spi nor pins
  pinctrl: sh-pfc: r8a7794: Implement voltage switching for SDHI
  pinctrl: sh-pfc: r8a7791: Implement voltage switching for SDHI
  pinctrl: sh-pfc: Add PORT_GP_24 helper macro
  pinctrl: Fix "st,syscfg" definition for STM32 pinctrl
  driver: base: pinctrl: return error from pinctrl_bind_pins()
  pinctrl: meson-gxbb: add the missing SDIO interrupt pin
  pinctrl: aspeed: fix regmap error handling
  pinctrl: mediatek: constify gpio_chip structures
  ...
This commit is contained in:
Linus Torvalds 2016-10-05 11:37:14 -07:00
commit d268dbe76a
65 changed files with 10355 additions and 517 deletions

View File

@ -23,6 +23,7 @@ Required properties:
"allwinner,sun8i-h3-pinctrl"
"allwinner,sun8i-h3-r-pinctrl"
"allwinner,sun50i-a64-pinctrl"
"nextthing,gr8-pinctrl"
- reg: Should contain the register physical address and length for the
pin controller.

View File

@ -0,0 +1,65 @@
Aspeed Pin Controllers
----------------------
The Aspeed SoCs vary in functionality inside a generation but have a common mux
device register layout.
Required properties:
- compatible : Should be any one of the following:
"aspeed,ast2400-pinctrl"
"aspeed,g4-pinctrl"
"aspeed,ast2500-pinctrl"
"aspeed,g5-pinctrl"
The pin controller node should be a child of a syscon node with the required
property:
- compatible: "syscon", "simple-mfd"
Refer to the the bindings described in
Documentation/devicetree/bindings/mfd/syscon.txt
Subnode Format
--------------
The required properties of child nodes are (as defined in pinctrl-bindings):
- function
- groups
Each function has only one associated pin group. Each group is named by its
function. The following values for the function and groups properties are
supported:
aspeed,ast2400-pinctrl, aspeed,g4-pinctrl:
ACPI BMCINT DDCCLK DDCDAT FLACK FLBUSY FLWP GPID0 GPIE0 GPIE2 GPIE4 GPIE6 I2C10
I2C11 I2C12 I2C13 I2C3 I2C4 I2C5 I2C6 I2C7 I2C8 I2C9 LPCPD LPCPME LPCSMI MDIO1
MDIO2 NCTS1 NCTS3 NCTS4 NDCD1 NDCD3 NDCD4 NDSR1 NDSR3 NDTR1 NDTR3 NRI1 NRI3
NRI4 NRTS1 NRTS3 PWM0 PWM1 PWM2 PWM3 PWM4 PWM5 PWM6 PWM7 RGMII1 RMII1 ROM16
ROM8 ROMCS1 ROMCS2 ROMCS3 ROMCS4 RXD1 RXD3 RXD4 SD1 SGPMI SIOPBI SIOPBO TIMER3
TIMER5 TIMER6 TIMER7 TIMER8 TXD1 TXD3 TXD4 UART6 VGAHS VGAVS VPI18 VPI24 VPI30
VPO12 VPO24
aspeed,ast2500-pinctrl, aspeed,g5-pinctrl:
GPID0 GPID2 GPIE0 I2C10 I2C11 I2C12 I2C13 I2C14 I2C3 I2C4 I2C5 I2C6 I2C7 I2C8
I2C9 MAC1LINK MDIO1 MDIO2 OSCCLK PEWAKE PWM0 PWM1 PWM2 PWM3 PWM4 PWM5 PWM6 PWM7
RGMII1 RGMII2 RMII1 RMII2 SD1 SPI1 TIMER4 TIMER5 TIMER6 TIMER7 TIMER8
Examples:
syscon: scu@1e6e2000 {
compatible = "syscon", "simple-mfd";
reg = <0x1e6e2000 0x1a8>;
pinctrl: pinctrl {
compatible = "aspeed,g4-pinctrl";
pinctrl_i2c3_default: i2c3_default {
function = "I2C3";
groups = "I2C3";
};
};
};
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices.

View File

@ -30,8 +30,7 @@ Second type has a dedicated interrupt per gpio bank.
Pin controller node:
Required properties:
- compatible : should be "st,<SOC>-<pio-block>-pinctrl"
like st,stih415-sbc-pinctrl, st,stih415-front-pinctrl and so on.
- compatible : should be "st,stih407-<pio-block>-pinctrl"
- st,syscfg : Should be a phandle of the syscfg node.
- st,retime-pin-mask : Should be mask to specify which pins can be retimed.
If the property is not present, it is assumed that all the pins in the
@ -50,7 +49,11 @@ Optional properties:
GPIO controller/bank node.
Required properties:
- gpio-controller : Indicates this device is a GPIO controller
- #gpio-cells : Should be one. The first cell is the pin number.
- #gpio-cells : Must be two.
- First cell: specifies the pin number inside the controller
- Second cell: specifies whether the pin is logically inverted.
- 0 = active high
- 1 = active low
- st,bank-name : Should be a name string for this bank as specified in
datasheet.
@ -76,23 +79,23 @@ include/dt-bindings/interrupt-controller/irq.h
Example:
pin-controller-sbc {
#address-cells = <1>;
#size-cells = <1>;
compatible = "st,stih415-sbc-pinctrl";
st,syscfg = <&syscfg_sbc>;
reg = <0xfe61f080 0x4>;
reg-names = "irqmux";
interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "irqmux";
ranges = <0 0xfe610000 0x5000>;
#address-cells = <1>;
#size-cells = <1>;
compatible = "st,stih407-sbc-pinctrl";
st,syscfg = <&syscfg_sbc>;
reg = <0x0961f080 0x4>;
reg-names = "irqmux";
interrupts = <GIC_SPI 188 IRQ_TYPE_NONE>;
interrupt-names = "irqmux";
ranges = <0 0x09610000 0x6000>;
PIO0: gpio@fe610000 {
pio0: gpio@09610000 {
gpio-controller;
#gpio-cells = <1>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
reg = <0 0x100>;
st,bank-name = "PIO0";
reg = <0x0 0x100>;
st,bank-name = "PIO0";
};
...
pin-functions nodes follow...
@ -162,7 +165,7 @@ pin-controller {
sdhci0:sdhci@fe810000{
...
interrupt-parent = <&PIO3>;
interrupt-parent = <&pio3>;
#interrupt-cells = <2>;
interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; /* Interrupt line via PIO3-3 */
interrupt-names = "card-detect";

View File

@ -17,6 +17,9 @@ PMIC's from Qualcomm.
"qcom,pm8994-gpio"
"qcom,pma8084-gpio"
And must contain either "qcom,spmi-gpio" or "qcom,ssbi-gpio"
if the device is on an spmi bus or an ssbi bus respectively
- reg:
Usage: required
Value type: <prop-encoded-array>
@ -183,7 +186,7 @@ to specify in a pin configuration subnode:
Example:
pm8921_gpio: gpio@150 {
compatible = "qcom,pm8921-gpio";
compatible = "qcom,pm8921-gpio", "qcom,ssbi-gpio";
reg = <0x150 0x160>;
interrupts = <192 1>, <193 1>, <194 1>,
<195 1>, <196 1>, <197 1>,

View File

@ -19,6 +19,9 @@ of PMIC's from Qualcomm.
"qcom,pm8994-mpp",
"qcom,pma8084-mpp",
And must contain either "qcom,spmi-mpp" or "qcom,ssbi-mpp"
if the device is on an spmi bus or an ssbi bus respectively.
- reg:
Usage: required
Value type: <prop-encoded-array>
@ -158,7 +161,7 @@ to specify in a pin configuration subnode:
Example:
mpps@a000 {
compatible = "qcom,pm8841-mpp";
compatible = "qcom,pm8841-mpp", "qcom,spmi-mpp";
reg = <0xa000>;
gpio-controller;
#gpio-cells = <2>;

View File

@ -17,9 +17,11 @@ Required Properties:
- "renesas,pfc-r8a7779": for R8A7779 (R-Car H1) compatible pin-controller.
- "renesas,pfc-r8a7790": for R8A7790 (R-Car H2) compatible pin-controller.
- "renesas,pfc-r8a7791": for R8A7791 (R-Car M2-W) compatible pin-controller.
- "renesas,pfc-r8a7792": for R8A7792 (R-Car V2H) compatible pin-controller.
- "renesas,pfc-r8a7793": for R8A7793 (R-Car M2-N) compatible pin-controller.
- "renesas,pfc-r8a7794": for R8A7794 (R-Car E2) compatible pin-controller.
- "renesas,pfc-r8a7795": for R8A7795 (R-Car H3) compatible pin-controller.
- "renesas,pfc-r8a7796": for R8A7796 (R-Car M3-W) compatible pin-controller.
- "renesas,pfc-sh73a0": for SH73A0 (SH-Mobile AG5) compatible pin-controller.
- reg: Base address and length of each memory resource used by the pin

View File

@ -14,6 +14,11 @@ Required properies:
- #size-cells : The value of this property must be 1
- ranges : defines mapping between pin controller node (parent) to
gpio-bank node (children).
- interrupt-parent: phandle of the interrupt parent to which the external
GPIO interrupts are forwarded to.
- st,syscfg: Should be phandle/offset pair. The phandle to the syscon node
which includes IRQ mux selection register, and the offset of the IRQ mux
selection register.
- pins-are-numbered: Specify the subnodes are using numbered pinmux to
specify pins.

View File

@ -262,6 +262,12 @@ symbol:
to the container using container_of().
(See Documentation/driver-model/design-patterns.txt)
If there is a need to exclude certain GPIOs from the IRQ domain, one can
set .irq_need_valid_mask of the gpiochip before gpiochip_add_data() is
called. This allocates .irq_valid_mask with as many bits set as there are
GPIOs in the chip. Drivers can exclude GPIOs by clearing bits from this
mask. The mask must be filled in before gpiochip_irqchip_add() is called.
* gpiochip_set_chained_irqchip(): sets up a chained irq handler for a
gpio_chip from a parent IRQ and passes the struct gpio_chip* as handler
data. (Notice handler data, since the irqchip data is likely used by the

View File

@ -91,9 +91,13 @@ cleanup_alloc:
devm_kfree(dev, dev->pins);
dev->pins = NULL;
/* Only return deferrals */
if (ret != -EPROBE_DEFER)
ret = 0;
/* Return deferrals */
if (ret == -EPROBE_DEFER)
return ret;
/* Return serious errors */
if (ret == -EINVAL)
return ret;
/* We ignore errors like -ENOENT meaning no pinctrl state */
return ret;
return 0;
}

View File

@ -458,6 +458,11 @@ static int mxc_gpio_probe(struct platform_device *pdev)
if (err)
goto out_bgio;
if (of_property_read_bool(np, "gpio-ranges")) {
port->gc.request = gpiochip_generic_request;
port->gc.free = gpiochip_generic_free;
}
port->gc.to_irq = mxc_gpio_to_irq;
port->gc.base = (pdev->id < 0) ? of_alias_get_id(np, "gpio") * 32 :
pdev->id * 32;
@ -510,7 +515,7 @@ static int __init gpio_mxc_init(void)
{
return platform_driver_register(&mxc_gpio_driver);
}
postcore_initcall(gpio_mxc_init);
subsys_initcall(gpio_mxc_init);
MODULE_AUTHOR("Freescale Semiconductor, "
"Daniel Mack <danielncaiaq.de>, "

View File

@ -71,6 +71,8 @@ LIST_HEAD(gpio_devices);
static void gpiochip_free_hogs(struct gpio_chip *chip);
static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip);
static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip);
static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip);
static bool gpiolib_initialized;
@ -1167,6 +1169,10 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data)
if (status)
goto err_remove_from_list;
status = gpiochip_irqchip_init_valid_mask(chip);
if (status)
goto err_remove_from_list;
status = of_gpiochip_add(chip);
if (status)
goto err_remove_chip;
@ -1192,6 +1198,7 @@ err_remove_chip:
acpi_gpiochip_remove(chip);
gpiochip_free_hogs(chip);
of_gpiochip_remove(chip);
gpiochip_irqchip_free_valid_mask(chip);
err_remove_from_list:
spin_lock_irqsave(&gpio_lock, flags);
list_del(&gdev->list);
@ -1401,6 +1408,40 @@ static struct gpio_chip *find_chip_by_name(const char *name)
* The following is irqchip helper code for gpiochips.
*/
static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip)
{
int i;
if (!gpiochip->irq_need_valid_mask)
return 0;
gpiochip->irq_valid_mask = kcalloc(BITS_TO_LONGS(gpiochip->ngpio),
sizeof(long), GFP_KERNEL);
if (!gpiochip->irq_valid_mask)
return -ENOMEM;
/* Assume by default all GPIOs are valid */
for (i = 0; i < gpiochip->ngpio; i++)
set_bit(i, gpiochip->irq_valid_mask);
return 0;
}
static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip)
{
kfree(gpiochip->irq_valid_mask);
gpiochip->irq_valid_mask = NULL;
}
static bool gpiochip_irqchip_irq_valid(const struct gpio_chip *gpiochip,
unsigned int offset)
{
/* No mask means all valid */
if (likely(!gpiochip->irq_valid_mask))
return true;
return test_bit(offset, gpiochip->irq_valid_mask);
}
/**
* gpiochip_set_chained_irqchip() - sets a chained irqchip to a gpiochip
* @gpiochip: the gpiochip to set the irqchip chain to
@ -1442,9 +1483,12 @@ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,
}
/* Set the parent IRQ for all affected IRQs */
for (offset = 0; offset < gpiochip->ngpio; offset++)
for (offset = 0; offset < gpiochip->ngpio; offset++) {
if (!gpiochip_irqchip_irq_valid(gpiochip, offset))
continue;
irq_set_parent(irq_find_mapping(gpiochip->irqdomain, offset),
parent_irq);
}
}
EXPORT_SYMBOL_GPL(gpiochip_set_chained_irqchip);
@ -1551,9 +1595,12 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip)
/* Remove all IRQ mappings and delete the domain */
if (gpiochip->irqdomain) {
for (offset = 0; offset < gpiochip->ngpio; offset++)
for (offset = 0; offset < gpiochip->ngpio; offset++) {
if (!gpiochip_irqchip_irq_valid(gpiochip, offset))
continue;
irq_dispose_mapping(
irq_find_mapping(gpiochip->irqdomain, offset));
}
irq_domain_remove(gpiochip->irqdomain);
}
@ -1562,6 +1609,8 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip)
gpiochip->irqchip->irq_release_resources = NULL;
gpiochip->irqchip = NULL;
}
gpiochip_irqchip_free_valid_mask(gpiochip);
}
/**
@ -1597,6 +1646,7 @@ int _gpiochip_irqchip_add(struct gpio_chip *gpiochip,
struct lock_class_key *lock_key)
{
struct device_node *of_node;
bool irq_base_set = false;
unsigned int offset;
unsigned irq_base = 0;
@ -1646,13 +1696,17 @@ int _gpiochip_irqchip_add(struct gpio_chip *gpiochip,
* necessary to allocate descriptors for all IRQs.
*/
for (offset = 0; offset < gpiochip->ngpio; offset++) {
if (!gpiochip_irqchip_irq_valid(gpiochip, offset))
continue;
irq_base = irq_create_mapping(gpiochip->irqdomain, offset);
if (offset == 0)
if (!irq_base_set) {
/*
* Store the base into the gpiochip to be used when
* unmapping the irqs.
*/
gpiochip->irq_base = irq_base;
irq_base_set = true;
}
}
acpi_gpiochip_request_interrupts(gpiochip);
@ -1664,6 +1718,12 @@ EXPORT_SYMBOL_GPL(_gpiochip_irqchip_add);
#else /* CONFIG_GPIOLIB_IRQCHIP */
static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) {}
static inline int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip)
{
return 0;
}
static inline void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip)
{ }
#endif /* CONFIG_GPIOLIB_IRQCHIP */

View File

@ -254,6 +254,7 @@ config PINCTRL_ZYNQ
help
This selects the pinctrl driver for Xilinx Zynq.
source "drivers/pinctrl/aspeed/Kconfig"
source "drivers/pinctrl/bcm/Kconfig"
source "drivers/pinctrl/berlin/Kconfig"
source "drivers/pinctrl/freescale/Kconfig"

View File

@ -37,6 +37,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o
obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o
obj-$(CONFIG_ARCH_ASPEED) += aspeed/
obj-y += bcm/
obj-$(CONFIG_PINCTRL_BERLIN) += berlin/
obj-y += freescale/

View File

@ -0,0 +1,24 @@
config PINCTRL_ASPEED
bool
depends on (ARCH_ASPEED || COMPILE_TEST) && OF
depends on MFD_SYSCON
select PINMUX
select PINCONF
select GENERIC_PINCONF
select REGMAP_MMIO
config PINCTRL_ASPEED_G4
bool "Aspeed G4 SoC pin control"
depends on (MACH_ASPEED_G4 || COMPILE_TEST) && OF
select PINCTRL_ASPEED
help
Say Y here to enable pin controller support for Aspeed's 4th
generation SoCs. GPIO is provided by a separate GPIO driver.
config PINCTRL_ASPEED_G5
bool "Aspeed G5 SoC pin control"
depends on (MACH_ASPEED_G5 || COMPILE_TEST) && OF
select PINCTRL_ASPEED
help
Say Y here to enable pin controller support for Aspeed's 5th
generation SoCs. GPIO is provided by a separate GPIO driver.

View File

@ -0,0 +1,6 @@
# Aspeed pinctrl support
ccflags-y += -Woverride-init
obj-$(CONFIG_PINCTRL_ASPEED) += pinctrl-aspeed.o
obj-$(CONFIG_PINCTRL_ASPEED_G4) += pinctrl-aspeed-g4.o
obj-$(CONFIG_PINCTRL_ASPEED_G5) += pinctrl-aspeed-g5.o

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,808 @@
/*
* Copyright (C) 2016 IBM Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/bitops.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mutex.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"
#include "../pinctrl-utils.h"
#include "pinctrl-aspeed.h"
#define ASPEED_G5_NR_PINS 228
#define COND1 SIG_DESC_BIT(SCU90, 6, 0)
#define COND2 { SCU94, GENMASK(1, 0), 0, 0 }
#define B14 0
SSSF_PIN_DECL(B14, GPIOA0, MAC1LINK, SIG_DESC_SET(SCU80, 0));
#define E13 3
SSSF_PIN_DECL(E13, GPIOA3, TIMER4, SIG_DESC_SET(SCU80, 3));
#define I2C9_DESC SIG_DESC_SET(SCU90, 22)
#define C14 4
SIG_EXPR_LIST_DECL_SINGLE(SCL9, I2C9, I2C9_DESC, COND1);
SIG_EXPR_LIST_DECL_SINGLE(TIMER5, TIMER5, SIG_DESC_SET(SCU80, 4), COND1);
MS_PIN_DECL(C14, GPIOA4, SCL9, TIMER5);
FUNC_GROUP_DECL(TIMER5, C14);
#define A13 5
SIG_EXPR_LIST_DECL_SINGLE(SDA9, I2C9, I2C9_DESC, COND1);
SIG_EXPR_LIST_DECL_SINGLE(TIMER6, TIMER6, SIG_DESC_SET(SCU80, 5), COND1);
MS_PIN_DECL(A13, GPIOA5, SDA9, TIMER6);
FUNC_GROUP_DECL(TIMER6, A13);
FUNC_GROUP_DECL(I2C9, C14, A13);
#define MDIO2_DESC SIG_DESC_SET(SCU90, 2)
#define C13 6
SIG_EXPR_LIST_DECL_SINGLE(MDC2, MDIO2, MDIO2_DESC, COND1);
SIG_EXPR_LIST_DECL_SINGLE(TIMER7, TIMER7, SIG_DESC_SET(SCU80, 6), COND1);
MS_PIN_DECL(C13, GPIOA6, MDC2, TIMER7);
FUNC_GROUP_DECL(TIMER7, C13);
#define B13 7
SIG_EXPR_LIST_DECL_SINGLE(MDIO2, MDIO2, MDIO2_DESC, COND1);
SIG_EXPR_LIST_DECL_SINGLE(TIMER8, TIMER8, SIG_DESC_SET(SCU80, 7), COND1);
MS_PIN_DECL(B13, GPIOA7, MDIO2, TIMER8);
FUNC_GROUP_DECL(TIMER8, B13);
FUNC_GROUP_DECL(MDIO2, C13, B13);
#define H20 15
GPIO_PIN_DECL(H20, GPIOB7);
#define SD1_DESC SIG_DESC_SET(SCU90, 0)
#define C12 16
#define I2C10_DESC SIG_DESC_SET(SCU90, 23)
SIG_EXPR_LIST_DECL_SINGLE(SD1CLK, SD1, SD1_DESC);
SIG_EXPR_LIST_DECL_SINGLE(SCL10, I2C10, I2C10_DESC);
MS_PIN_DECL(C12, GPIOC0, SD1CLK, SCL10);
#define A12 17
SIG_EXPR_LIST_DECL_SINGLE(SD1CMD, SD1, SD1_DESC);
SIG_EXPR_LIST_DECL_SINGLE(SDA10, I2C10, I2C10_DESC);
MS_PIN_DECL(A12, GPIOC1, SD1CMD, SDA10);
FUNC_GROUP_DECL(I2C10, C12, A12);
#define B12 18
#define I2C11_DESC SIG_DESC_SET(SCU90, 24)
SIG_EXPR_LIST_DECL_SINGLE(SD1DAT0, SD1, SD1_DESC);
SIG_EXPR_LIST_DECL_SINGLE(SCL11, I2C11, I2C11_DESC);
MS_PIN_DECL(B12, GPIOC2, SD1DAT0, SCL11);
#define D9 19
SIG_EXPR_LIST_DECL_SINGLE(SD1DAT1, SD1, SD1_DESC);
SIG_EXPR_LIST_DECL_SINGLE(SDA11, I2C11, I2C11_DESC);
MS_PIN_DECL(D9, GPIOC3, SD1DAT1, SDA11);
FUNC_GROUP_DECL(I2C11, B12, D9);
#define D10 20
#define I2C12_DESC SIG_DESC_SET(SCU90, 25)
SIG_EXPR_LIST_DECL_SINGLE(SD1DAT2, SD1, SD1_DESC);
SIG_EXPR_LIST_DECL_SINGLE(SCL12, I2C12, I2C12_DESC);
MS_PIN_DECL(D10, GPIOC4, SD1DAT2, SCL12);
#define E12 21
SIG_EXPR_LIST_DECL_SINGLE(SD1DAT3, SD1, SD1_DESC);
SIG_EXPR_LIST_DECL_SINGLE(SDA12, I2C12, I2C12_DESC);
MS_PIN_DECL(E12, GPIOC5, SD1DAT3, SDA12);
FUNC_GROUP_DECL(I2C12, D10, E12);
#define C11 22
#define I2C13_DESC SIG_DESC_SET(SCU90, 26)
SIG_EXPR_LIST_DECL_SINGLE(SD1CD, SD1, SD1_DESC);
SIG_EXPR_LIST_DECL_SINGLE(SCL13, I2C13, I2C13_DESC);
MS_PIN_DECL(C11, GPIOC6, SD1CD, SCL13);
#define B11 23
SIG_EXPR_LIST_DECL_SINGLE(SD1WP, SD1, SD1_DESC);
SIG_EXPR_LIST_DECL_SINGLE(SDA13, I2C13, I2C13_DESC);
MS_PIN_DECL(B11, GPIOC7, SD1WP, SDA13);
FUNC_GROUP_DECL(I2C13, C11, B11);
FUNC_GROUP_DECL(SD1, C12, A12, B12, D9, D10, E12, C11, B11);
#define SD2_DESC SIG_DESC_SET(SCU90, 1)
#define GPID0_DESC SIG_DESC_SET(SCU8C, 8)
#define GPID_DESC SIG_DESC_SET(HW_STRAP1, 21)
#define F19 24
SIG_EXPR_LIST_DECL_SINGLE(SD2CLK, SD2, SD2_DESC);
SIG_EXPR_DECL(GPID0IN, GPID0, GPID0_DESC);
SIG_EXPR_DECL(GPID0IN, GPID, GPID_DESC);
SIG_EXPR_LIST_DECL_DUAL(GPID0IN, GPID0, GPID);
MS_PIN_DECL(F19, GPIOD0, SD2CLK, GPID0IN);
#define E21 25
SIG_EXPR_LIST_DECL_SINGLE(SD2CMD, SD2, SD2_DESC);
SIG_EXPR_DECL(GPID0OUT, GPID0, GPID0_DESC);
SIG_EXPR_DECL(GPID0OUT, GPID, GPID_DESC);
SIG_EXPR_LIST_DECL_DUAL(GPID0OUT, GPID0, GPID);
MS_PIN_DECL(E21, GPIOD1, SD2CMD, GPID0OUT);
FUNC_GROUP_DECL(GPID0, F19, E21);
#define GPID2_DESC SIG_DESC_SET(SCU8C, 9)
#define D20 26
SIG_EXPR_LIST_DECL_SINGLE(SD2DAT0, SD2, SD2_DESC);
SIG_EXPR_DECL(GPID2IN, GPID2, GPID2_DESC);
SIG_EXPR_DECL(GPID2IN, GPID, GPID_DESC);
SIG_EXPR_LIST_DECL_DUAL(GPID2IN, GPID2, GPID);
MS_PIN_DECL(D20, GPIOD2, SD2DAT0, GPID2IN);
#define D21 27
SIG_EXPR_LIST_DECL_SINGLE(SD2DAT1, SD2, SD2_DESC);
SIG_EXPR_DECL(GPID2OUT, GPID2, GPID2_DESC);
SIG_EXPR_DECL(GPID2OUT, GPID, GPID_DESC);
SIG_EXPR_LIST_DECL_DUAL(GPID2OUT, GPID2, GPID);
MS_PIN_DECL(D21, GPIOD3, SD2DAT1, GPID2OUT);
FUNC_GROUP_DECL(GPID2, D20, D21);
#define GPIE_DESC SIG_DESC_SET(HW_STRAP1, 21)
#define GPIE0_DESC SIG_DESC_SET(SCU8C, 12)
#define B20 32
SIG_EXPR_LIST_DECL_SINGLE(NCTS3, NCTS3, SIG_DESC_SET(SCU80, 16));
SIG_EXPR_DECL(GPIE0IN, GPIE0, GPIE0_DESC);
SIG_EXPR_DECL(GPIE0IN, GPIE, GPIE_DESC);
SIG_EXPR_LIST_DECL_DUAL(GPIE0IN, GPIE0, GPIE);
MS_PIN_DECL(B20, GPIOE0, NCTS3, GPIE0IN);
#define C20 33
SIG_EXPR_LIST_DECL_SINGLE(NDCD3, NDCD3, SIG_DESC_SET(SCU80, 17));
SIG_EXPR_DECL(GPIE0OUT, GPIE0, GPIE0_DESC);
SIG_EXPR_DECL(GPIE0OUT, GPIE, GPIE_DESC);
SIG_EXPR_LIST_DECL_DUAL(GPIE0OUT, GPIE0, GPIE);
MS_PIN_DECL(C20, GPIE0, NDCD3, GPIE0OUT);
FUNC_GROUP_DECL(GPIE0, B20, C20);
#define SPI1_DESC SIG_DESC_SET(HW_STRAP1, 13)
#define C18 64
SIG_EXPR_LIST_DECL_SINGLE(SYSCS, SPI1, COND1, SPI1_DESC);
SS_PIN_DECL(C18, GPIOI0, SYSCS);
#define E15 65
SIG_EXPR_LIST_DECL_SINGLE(SYSCK, SPI1, COND1, SPI1_DESC);
SS_PIN_DECL(E15, GPIOI1, SYSCK);
#define A14 66
SIG_EXPR_LIST_DECL_SINGLE(SYSMOSI, SPI1, COND1, SPI1_DESC);
SS_PIN_DECL(A14, GPIOI2, SYSMOSI);
#define C16 67
SIG_EXPR_LIST_DECL_SINGLE(SYSMISO, SPI1, COND1, SPI1_DESC);
SS_PIN_DECL(C16, GPIOI3, SYSMISO);
FUNC_GROUP_DECL(SPI1, C18, E15, A14, C16);
#define L2 73
SIG_EXPR_LIST_DECL_SINGLE(SGPMLD, SGPM, SIG_DESC_SET(SCU84, 9));
SS_PIN_DECL(L2, GPIOJ1, SGPMLD);
#define N3 74
SIG_EXPR_LIST_DECL_SINGLE(SGPMO, SGPM, SIG_DESC_SET(SCU84, 10));
SS_PIN_DECL(N3, GPIOJ2, SGPMO);
#define N4 75
SIG_EXPR_LIST_DECL_SINGLE(SGPMI, SGPM, SIG_DESC_SET(SCU84, 11));
SS_PIN_DECL(N4, GPIOJ3, SGPMI);
#define I2C5_DESC SIG_DESC_SET(SCU90, 18)
#define L3 80
SIG_EXPR_LIST_DECL_SINGLE(SCL5, I2C5, I2C5_DESC);
SS_PIN_DECL(L3, GPIOK0, SCL5);
#define L4 81
SIG_EXPR_LIST_DECL_SINGLE(SDA5, I2C5, I2C5_DESC);
SS_PIN_DECL(L4, GPIOK1, SDA5);
FUNC_GROUP_DECL(I2C5, L3, L4);
#define I2C6_DESC SIG_DESC_SET(SCU90, 19)
#define L1 82
SIG_EXPR_LIST_DECL_SINGLE(SCL6, I2C6, I2C6_DESC);
SS_PIN_DECL(L1, GPIOK2, SCL6);
#define N2 83
SIG_EXPR_LIST_DECL_SINGLE(SDA6, I2C6, I2C6_DESC);
SS_PIN_DECL(N2, GPIOK3, SDA6);
FUNC_GROUP_DECL(I2C6, L1, N2);
#define I2C7_DESC SIG_DESC_SET(SCU90, 20)
#define N1 84
SIG_EXPR_LIST_DECL_SINGLE(SCL7, I2C7, I2C7_DESC);
SS_PIN_DECL(N1, GPIOK4, SCL7);
#define P1 85
SIG_EXPR_LIST_DECL_SINGLE(SDA7, I2C7, I2C7_DESC);
SS_PIN_DECL(P1, GPIOK5, SDA7);
FUNC_GROUP_DECL(I2C7, N1, P1);
#define I2C8_DESC SIG_DESC_SET(SCU90, 21)
#define P2 86
SIG_EXPR_LIST_DECL_SINGLE(SCL8, I2C8, I2C8_DESC);
SS_PIN_DECL(P2, GPIOK6, SCL8);
#define R1 87
SIG_EXPR_LIST_DECL_SINGLE(SDA8, I2C8, I2C8_DESC);
SS_PIN_DECL(R1, GPIOK7, SDA8);
FUNC_GROUP_DECL(I2C8, P2, R1);
#define VPIOFF0_DESC { SCU90, GENMASK(5, 4), 0, 0 }
#define VPIOFF1_DESC { SCU90, GENMASK(5, 4), 1, 0 }
#define VPI24_DESC { SCU90, GENMASK(5, 4), 2, 0 }
#define VPIRSVD_DESC { SCU90, GENMASK(5, 4), 3, 0 }
#define V2 104
#define V2_DESC SIG_DESC_SET(SCU88, 0)
SIG_EXPR_LIST_DECL_SINGLE(DASHN0, DASHN0, VPIRSVD_DESC, V2_DESC);
SIG_EXPR_LIST_DECL_SINGLE(PWM0, PWM0, V2_DESC, COND2);
MS_PIN_DECL(V2, GPION0, DASHN0, PWM0);
FUNC_GROUP_DECL(PWM0, V2);
#define W2 105
#define W2_DESC SIG_DESC_SET(SCU88, 1)
SIG_EXPR_LIST_DECL_SINGLE(DASHN1, DASHN1, VPIRSVD_DESC, W2_DESC);
SIG_EXPR_LIST_DECL_SINGLE(PWM1, PWM1, W2_DESC, COND2);
MS_PIN_DECL(W2, GPION1, DASHN1, PWM1);
FUNC_GROUP_DECL(PWM1, W2);
#define V3 106
#define V3_DESC SIG_DESC_SET(SCU88, 2)
SIG_EXPR_DECL(VPIG2, VPI24, VPI24_DESC, V3_DESC, COND2);
SIG_EXPR_DECL(VPIG2, VPIRSVD, VPIRSVD_DESC, V3_DESC, COND2);
SIG_EXPR_LIST_DECL_DUAL(VPIG2, VPI24, VPIRSVD);
SIG_EXPR_LIST_DECL_SINGLE(PWM2, PWM2, V3_DESC, COND2);
MS_PIN_DECL(V3, GPION2, VPIG2, PWM2);
FUNC_GROUP_DECL(PWM2, V3);
#define U3 107
#define U3_DESC SIG_DESC_SET(SCU88, 3)
SIG_EXPR_DECL(VPIG3, VPI24, VPI24_DESC, U3_DESC, COND2);
SIG_EXPR_DECL(VPIG3, VPIRSVD, VPIRSVD_DESC, U3_DESC, COND2);
SIG_EXPR_LIST_DECL_DUAL(VPIG3, VPI24, VPIRSVD);
SIG_EXPR_LIST_DECL_SINGLE(PWM3, PWM3, U3_DESC, COND2);
MS_PIN_DECL(U3, GPION3, VPIG3, PWM3);
FUNC_GROUP_DECL(PWM3, U3);
#define W3 108
#define W3_DESC SIG_DESC_SET(SCU88, 4)
SIG_EXPR_DECL(VPIG4, VPI24, VPI24_DESC, W3_DESC, COND2);
SIG_EXPR_DECL(VPIG4, VPIRSVD, VPIRSVD_DESC, W3_DESC, COND2);
SIG_EXPR_LIST_DECL_DUAL(VPIG4, VPI24, VPIRSVD);
SIG_EXPR_LIST_DECL_SINGLE(PWM4, PWM4, W3_DESC, COND2);
MS_PIN_DECL(W3, GPION4, VPIG4, PWM4);
FUNC_GROUP_DECL(PWM4, W3);
#define AA3 109
#define AA3_DESC SIG_DESC_SET(SCU88, 5)
SIG_EXPR_DECL(VPIG5, VPI24, VPI24_DESC, AA3_DESC, COND2);
SIG_EXPR_DECL(VPIG5, VPIRSVD, VPIRSVD_DESC, AA3_DESC, COND2);
SIG_EXPR_LIST_DECL_DUAL(VPIG5, VPI24, VPIRSVD);
SIG_EXPR_LIST_DECL_SINGLE(PWM5, PWM5, AA3_DESC, COND2);
MS_PIN_DECL(AA3, GPION5, VPIG5, PWM5);
FUNC_GROUP_DECL(PWM5, AA3);
#define Y3 110
#define Y3_DESC SIG_DESC_SET(SCU88, 6)
SIG_EXPR_LIST_DECL_SINGLE(VPIG6, VPI24, VPI24_DESC, Y3_DESC);
SIG_EXPR_LIST_DECL_SINGLE(PWM6, PWM6, Y3_DESC, COND2);
MS_PIN_DECL(Y3, GPION6, VPIG6, PWM6);
FUNC_GROUP_DECL(PWM6, Y3);
#define T4 111
#define T4_DESC SIG_DESC_SET(SCU88, 7)
SIG_EXPR_LIST_DECL_SINGLE(VPIG7, VPI24, VPI24_DESC, T4_DESC);
SIG_EXPR_LIST_DECL_SINGLE(PWM7, PWM7, T4_DESC, COND2);
MS_PIN_DECL(T4, GPION7, VPIG7, PWM7);
FUNC_GROUP_DECL(PWM7, T4);
#define V6 127
SIG_EXPR_LIST_DECL_SINGLE(DASHV6, DASHV6, SIG_DESC_SET(SCU90, 28),
SIG_DESC_SET(SCU88, 23));
SS_PIN_DECL(V6, GPIOP7, DASHV6);
#define I2C3_DESC SIG_DESC_SET(SCU90, 16)
#define A11 128
SIG_EXPR_LIST_DECL_SINGLE(SCL3, I2C3, I2C3_DESC);
SS_PIN_DECL(A11, GPIOQ0, SCL3);
#define A10 129
SIG_EXPR_LIST_DECL_SINGLE(SDA3, I2C3, I2C3_DESC);
SS_PIN_DECL(A10, GPIOQ1, SDA3);
FUNC_GROUP_DECL(I2C3, A11, A10);
#define I2C4_DESC SIG_DESC_SET(SCU90, 17)
#define A9 130
SIG_EXPR_LIST_DECL_SINGLE(SCL4, I2C4, I2C4_DESC);
SS_PIN_DECL(A9, GPIOQ2, SCL4);
#define B9 131
SIG_EXPR_LIST_DECL_SINGLE(SDA4, I2C4, I2C4_DESC);
SS_PIN_DECL(B9, GPIOQ3, SDA4);
FUNC_GROUP_DECL(I2C4, A9, B9);
#define I2C14_DESC SIG_DESC_SET(SCU90, 27)
#define N21 132
SIG_EXPR_LIST_DECL_SINGLE(SCL14, I2C14, I2C14_DESC);
SS_PIN_DECL(N21, GPIOQ4, SCL14);
#define N22 133
SIG_EXPR_LIST_DECL_SINGLE(SDA14, I2C14, I2C14_DESC);
SS_PIN_DECL(N22, GPIOQ5, SDA14);
FUNC_GROUP_DECL(I2C14, N21, N22);
#define B10 134
SSSF_PIN_DECL(B10, GPIOQ6, OSCCLK, SIG_DESC_SET(SCU2C, 1));
#define N20 135
SSSF_PIN_DECL(N20, GPIOQ7, PEWAKE, SIG_DESC_SET(SCU2C, 29));
#define D8 142
SIG_EXPR_LIST_DECL_SINGLE(MDC1, MDIO1, SIG_DESC_SET(SCU88, 30));
SS_PIN_DECL(D8, GPIOR6, MDC1);
#define E10 143
SIG_EXPR_LIST_DECL_SINGLE(MDIO1, MDIO1, SIG_DESC_SET(SCU88, 31));
SS_PIN_DECL(E10, GPIOR7, MDIO1);
FUNC_GROUP_DECL(MDIO1, D8, E10);
/* RGMII1/RMII1 */
#define RMII1_DESC SIG_DESC_BIT(HW_STRAP1, 6, 0)
#define RMII2_DESC SIG_DESC_BIT(HW_STRAP1, 7, 0)
#define B5 152
SIG_EXPR_LIST_DECL_SINGLE(GPIOT0, GPIOT0, SIG_DESC_SET(SCUA0, 0));
SIG_EXPR_LIST_DECL_SINGLE(RMII1RCLKO, RMII1, RMII1_DESC,
SIG_DESC_SET(SCU48, 29));
SIG_EXPR_LIST_DECL_SINGLE(RGMII1TXCK, RGMII1);
MS_PIN_DECL_(B5, SIG_EXPR_LIST_PTR(GPIOT0), SIG_EXPR_LIST_PTR(RMII1RCLKO),
SIG_EXPR_LIST_PTR(RGMII1TXCK));
#define E9 153
SIG_EXPR_LIST_DECL_SINGLE(GPIOT1, GPIOT1, SIG_DESC_SET(SCUA0, 1));
SIG_EXPR_LIST_DECL_SINGLE(RMII1TXEN, RMII1, RMII1_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII1TXCTL, RGMII1);
MS_PIN_DECL_(E9, SIG_EXPR_LIST_PTR(GPIOT1), SIG_EXPR_LIST_PTR(RMII1TXEN),
SIG_EXPR_LIST_PTR(RGMII1TXCTL));
#define F9 154
SIG_EXPR_LIST_DECL_SINGLE(GPIOT2, GPIOT2, SIG_DESC_SET(SCUA0, 2));
SIG_EXPR_LIST_DECL_SINGLE(RMII1TXD0, RMII1, RMII1_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII1TXD0, RGMII1);
MS_PIN_DECL_(F9, SIG_EXPR_LIST_PTR(GPIOT2), SIG_EXPR_LIST_PTR(RMII1TXD0),
SIG_EXPR_LIST_PTR(RGMII1TXD0));
#define A5 155
SIG_EXPR_LIST_DECL_SINGLE(GPIOT3, GPIOT3, SIG_DESC_SET(SCUA0, 3));
SIG_EXPR_LIST_DECL_SINGLE(RMII1TXD1, RMII1, RMII1_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII1TXD1, RGMII1);
MS_PIN_DECL_(A5, SIG_EXPR_LIST_PTR(GPIOT3), SIG_EXPR_LIST_PTR(RMII1TXD1),
SIG_EXPR_LIST_PTR(RGMII1TXD1));
#define E7 156
SIG_EXPR_LIST_DECL_SINGLE(GPIOT4, GPIOT4, SIG_DESC_SET(SCUA0, 4));
SIG_EXPR_LIST_DECL_SINGLE(RMII1DASH0, RMII1, RMII1_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII1TXD2, RGMII1);
MS_PIN_DECL_(E7, SIG_EXPR_LIST_PTR(GPIOT4), SIG_EXPR_LIST_PTR(RMII1DASH0),
SIG_EXPR_LIST_PTR(RGMII1TXD2));
#define D7 157
SIG_EXPR_LIST_DECL_SINGLE(GPIOT5, GPIOT5, SIG_DESC_SET(SCUA0, 5));
SIG_EXPR_LIST_DECL_SINGLE(RMII1DASH1, RMII1, RMII1_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII1TXD3, RGMII1);
MS_PIN_DECL_(D7, SIG_EXPR_LIST_PTR(GPIOT5), SIG_EXPR_LIST_PTR(RMII1DASH1),
SIG_EXPR_LIST_PTR(RGMII1TXD3));
#define B2 158
SIG_EXPR_LIST_DECL_SINGLE(GPIOT6, GPIOT6, SIG_DESC_SET(SCUA0, 6));
SIG_EXPR_LIST_DECL_SINGLE(RMII2RCLKO, RMII2, RMII2_DESC,
SIG_DESC_SET(SCU48, 30));
SIG_EXPR_LIST_DECL_SINGLE(RGMII2TXCK, RGMII2);
MS_PIN_DECL_(B2, SIG_EXPR_LIST_PTR(GPIOT6), SIG_EXPR_LIST_PTR(RMII2RCLKO),
SIG_EXPR_LIST_PTR(RGMII2TXCK));
#define B1 159
SIG_EXPR_LIST_DECL_SINGLE(GPIOT7, GPIOT7, SIG_DESC_SET(SCUA0, 7));
SIG_EXPR_LIST_DECL_SINGLE(RMII2TXEN, RMII2, RMII2_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII2TXCTL, RGMII2);
MS_PIN_DECL_(B1, SIG_EXPR_LIST_PTR(GPIOT7), SIG_EXPR_LIST_PTR(RMII2TXEN),
SIG_EXPR_LIST_PTR(RGMII2TXCTL));
#define A2 160
SIG_EXPR_LIST_DECL_SINGLE(GPIOU0, GPIOU0, SIG_DESC_SET(SCUA0, 8));
SIG_EXPR_LIST_DECL_SINGLE(RMII2TXD0, RMII2, RMII2_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII2TXD0, RGMII2);
MS_PIN_DECL_(A2, SIG_EXPR_LIST_PTR(GPIOU0), SIG_EXPR_LIST_PTR(RMII2TXD0),
SIG_EXPR_LIST_PTR(RGMII2TXD0));
#define B3 161
SIG_EXPR_LIST_DECL_SINGLE(GPIOU1, GPIOU1, SIG_DESC_SET(SCUA0, 9));
SIG_EXPR_LIST_DECL_SINGLE(RMII2TXD1, RMII2, RMII2_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII2TXD1, RGMII2);
MS_PIN_DECL_(B3, SIG_EXPR_LIST_PTR(GPIOU1), SIG_EXPR_LIST_PTR(RMII2TXD1),
SIG_EXPR_LIST_PTR(RGMII2TXD1));
#define D5 162
SIG_EXPR_LIST_DECL_SINGLE(GPIOU2, GPIOU2, SIG_DESC_SET(SCUA0, 10));
SIG_EXPR_LIST_DECL_SINGLE(RMII2DASH0, RMII2, RMII2_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII2TXD2, RGMII2);
MS_PIN_DECL_(D5, SIG_EXPR_LIST_PTR(GPIOU2), SIG_EXPR_LIST_PTR(RMII2DASH0),
SIG_EXPR_LIST_PTR(RGMII2TXD2));
#define D4 163
SIG_EXPR_LIST_DECL_SINGLE(GPIOU3, GPIOU3, SIG_DESC_SET(SCUA0, 11));
SIG_EXPR_LIST_DECL_SINGLE(RMII2DASH1, RMII2, RMII2_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII2TXD3, RGMII2);
MS_PIN_DECL_(D4, SIG_EXPR_LIST_PTR(GPIOU3), SIG_EXPR_LIST_PTR(RMII2DASH1),
SIG_EXPR_LIST_PTR(RGMII2TXD3));
#define B4 164
SIG_EXPR_LIST_DECL_SINGLE(GPIOU4, GPIOU4, SIG_DESC_SET(SCUA0, 12));
SIG_EXPR_LIST_DECL_SINGLE(RMII1RCLKI, RMII1, RMII1_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII1RXCK, RGMII1);
MS_PIN_DECL_(B4, SIG_EXPR_LIST_PTR(GPIOU4), SIG_EXPR_LIST_PTR(RMII1RCLKI),
SIG_EXPR_LIST_PTR(RGMII1RXCK));
#define A4 165
SIG_EXPR_LIST_DECL_SINGLE(GPIOU5, GPIOU5, SIG_DESC_SET(SCUA0, 13));
SIG_EXPR_LIST_DECL_SINGLE(RMII1DASH2, RMII1, RMII1_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII1RXCTL, RGMII1);
MS_PIN_DECL_(A4, SIG_EXPR_LIST_PTR(GPIOU5), SIG_EXPR_LIST_PTR(RMII1DASH2),
SIG_EXPR_LIST_PTR(RGMII1RXCTL));
#define A3 166
SIG_EXPR_LIST_DECL_SINGLE(GPIOU6, GPIOU6, SIG_DESC_SET(SCUA0, 14));
SIG_EXPR_LIST_DECL_SINGLE(RMII1RXD0, RMII1, RMII1_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII1RXD0, RGMII1);
MS_PIN_DECL_(A3, SIG_EXPR_LIST_PTR(GPIOU6), SIG_EXPR_LIST_PTR(RMII1RXD0),
SIG_EXPR_LIST_PTR(RGMII1RXD0));
#define D6 167
SIG_EXPR_LIST_DECL_SINGLE(GPIOU7, GPIOU7, SIG_DESC_SET(SCUA0, 15));
SIG_EXPR_LIST_DECL_SINGLE(RMII1RXD1, RMII1, RMII1_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII1RXD1, RGMII1);
MS_PIN_DECL_(D6, SIG_EXPR_LIST_PTR(GPIOU7), SIG_EXPR_LIST_PTR(RMII1RXD1),
SIG_EXPR_LIST_PTR(RGMII1RXD1));
#define C5 168
SIG_EXPR_LIST_DECL_SINGLE(GPIOV0, GPIOV0, SIG_DESC_SET(SCUA0, 16));
SIG_EXPR_LIST_DECL_SINGLE(RMII1CRSDV, RMII1, RMII1_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII1RXD2, RGMII1);
MS_PIN_DECL_(C5, SIG_EXPR_LIST_PTR(GPIOV0), SIG_EXPR_LIST_PTR(RMII1CRSDV),
SIG_EXPR_LIST_PTR(RGMII1RXD2));
#define C4 169
SIG_EXPR_LIST_DECL_SINGLE(GPIOV1, GPIOV1, SIG_DESC_SET(SCUA0, 17));
SIG_EXPR_LIST_DECL_SINGLE(RMII1RXER, RMII1, RMII1_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII1RXD3, RGMII1);
MS_PIN_DECL_(C4, SIG_EXPR_LIST_PTR(GPIOV1), SIG_EXPR_LIST_PTR(RMII1RXER),
SIG_EXPR_LIST_PTR(RGMII1RXD3));
FUNC_GROUP_DECL(RGMII1, B4, A4, A3, D6, C5, C4, B5, E9, F9, A5, E7, D7);
FUNC_GROUP_DECL(RMII1, B4, A3, D6, C5, C4, B5, E9, F9, A5);
#define C2 170
SIG_EXPR_LIST_DECL_SINGLE(GPIOV2, GPIOV2, SIG_DESC_SET(SCUA0, 18));
SIG_EXPR_LIST_DECL_SINGLE(RMII2RCLKI, RMII2, RMII2_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII2RXCK, RGMII2);
MS_PIN_DECL_(C2, SIG_EXPR_LIST_PTR(GPIOV2), SIG_EXPR_LIST_PTR(RMII2RCLKI),
SIG_EXPR_LIST_PTR(RGMII2RXCK));
#define C1 171
SIG_EXPR_LIST_DECL_SINGLE(GPIOV3, GPIOV3, SIG_DESC_SET(SCUA0, 19));
SIG_EXPR_LIST_DECL_SINGLE(RMII2DASH2, RMII2, RMII2_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII2RXCTL, RGMII2);
MS_PIN_DECL_(C1, SIG_EXPR_LIST_PTR(GPIOV3), SIG_EXPR_LIST_PTR(RMII2DASH2),
SIG_EXPR_LIST_PTR(RGMII2RXCTL));
#define C3 172
SIG_EXPR_LIST_DECL_SINGLE(GPIOV4, GPIOV4, SIG_DESC_SET(SCUA0, 20));
SIG_EXPR_LIST_DECL_SINGLE(RMII2RXD0, RMII2, RMII2_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII2RXD0, RGMII2);
MS_PIN_DECL_(C3, SIG_EXPR_LIST_PTR(GPIOV4), SIG_EXPR_LIST_PTR(RMII2RXD0),
SIG_EXPR_LIST_PTR(RGMII2RXD0));
#define D1 173
SIG_EXPR_LIST_DECL_SINGLE(GPIOV5, GPIOV5, SIG_DESC_SET(SCUA0, 21));
SIG_EXPR_LIST_DECL_SINGLE(RMII2RXD1, RMII2, RMII2_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII2RXD1, RGMII2);
MS_PIN_DECL_(D1, SIG_EXPR_LIST_PTR(GPIOV5), SIG_EXPR_LIST_PTR(RMII2RXD1),
SIG_EXPR_LIST_PTR(RGMII2RXD1));
#define D2 174
SIG_EXPR_LIST_DECL_SINGLE(GPIOV6, GPIOV6, SIG_DESC_SET(SCUA0, 22));
SIG_EXPR_LIST_DECL_SINGLE(RMII2CRSDV, RMII2, RMII2_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII2RXD2, RGMII2);
MS_PIN_DECL_(D2, SIG_EXPR_LIST_PTR(GPIOV6), SIG_EXPR_LIST_PTR(RMII2CRSDV),
SIG_EXPR_LIST_PTR(RGMII2RXD2));
#define E6 175
SIG_EXPR_LIST_DECL_SINGLE(GPIOV7, GPIOV7, SIG_DESC_SET(SCUA0, 23));
SIG_EXPR_LIST_DECL_SINGLE(RMII2RXER, RMII2, RMII2_DESC);
SIG_EXPR_LIST_DECL_SINGLE(RGMII2RXD3, RGMII2);
MS_PIN_DECL_(E6, SIG_EXPR_LIST_PTR(GPIOV7), SIG_EXPR_LIST_PTR(RMII2RXER),
SIG_EXPR_LIST_PTR(RGMII2RXD3));
FUNC_GROUP_DECL(RGMII2, B2, B1, A2, B3, D5, D4, C2, C1, C3, D1, D2, E6);
FUNC_GROUP_DECL(RMII2, B2, B1, A2, B3, C2, C3, D1, D2, E6);
/* Pins, groups and functions are sort(1):ed alphabetically for sanity */
static struct pinctrl_pin_desc aspeed_g5_pins[ASPEED_G5_NR_PINS] = {
ASPEED_PINCTRL_PIN(A10),
ASPEED_PINCTRL_PIN(A11),
ASPEED_PINCTRL_PIN(A12),
ASPEED_PINCTRL_PIN(A13),
ASPEED_PINCTRL_PIN(A14),
ASPEED_PINCTRL_PIN(A2),
ASPEED_PINCTRL_PIN(A3),
ASPEED_PINCTRL_PIN(A4),
ASPEED_PINCTRL_PIN(A5),
ASPEED_PINCTRL_PIN(A9),
ASPEED_PINCTRL_PIN(AA3),
ASPEED_PINCTRL_PIN(B1),
ASPEED_PINCTRL_PIN(B10),
ASPEED_PINCTRL_PIN(B11),
ASPEED_PINCTRL_PIN(B12),
ASPEED_PINCTRL_PIN(B13),
ASPEED_PINCTRL_PIN(B14),
ASPEED_PINCTRL_PIN(B2),
ASPEED_PINCTRL_PIN(B20),
ASPEED_PINCTRL_PIN(B3),
ASPEED_PINCTRL_PIN(B4),
ASPEED_PINCTRL_PIN(B5),
ASPEED_PINCTRL_PIN(B9),
ASPEED_PINCTRL_PIN(C1),
ASPEED_PINCTRL_PIN(C11),
ASPEED_PINCTRL_PIN(C12),
ASPEED_PINCTRL_PIN(C13),
ASPEED_PINCTRL_PIN(C14),
ASPEED_PINCTRL_PIN(C16),
ASPEED_PINCTRL_PIN(C18),
ASPEED_PINCTRL_PIN(C2),
ASPEED_PINCTRL_PIN(C20),
ASPEED_PINCTRL_PIN(C3),
ASPEED_PINCTRL_PIN(C4),
ASPEED_PINCTRL_PIN(C5),
ASPEED_PINCTRL_PIN(D1),
ASPEED_PINCTRL_PIN(D10),
ASPEED_PINCTRL_PIN(D2),
ASPEED_PINCTRL_PIN(D20),
ASPEED_PINCTRL_PIN(D21),
ASPEED_PINCTRL_PIN(D4),
ASPEED_PINCTRL_PIN(D5),
ASPEED_PINCTRL_PIN(D6),
ASPEED_PINCTRL_PIN(D7),
ASPEED_PINCTRL_PIN(D8),
ASPEED_PINCTRL_PIN(D9),
ASPEED_PINCTRL_PIN(E10),
ASPEED_PINCTRL_PIN(E12),
ASPEED_PINCTRL_PIN(E13),
ASPEED_PINCTRL_PIN(E15),
ASPEED_PINCTRL_PIN(E21),
ASPEED_PINCTRL_PIN(E6),
ASPEED_PINCTRL_PIN(E7),
ASPEED_PINCTRL_PIN(E9),
ASPEED_PINCTRL_PIN(F19),
ASPEED_PINCTRL_PIN(F9),
ASPEED_PINCTRL_PIN(H20),
ASPEED_PINCTRL_PIN(L1),
ASPEED_PINCTRL_PIN(L2),
ASPEED_PINCTRL_PIN(L3),
ASPEED_PINCTRL_PIN(L4),
ASPEED_PINCTRL_PIN(N1),
ASPEED_PINCTRL_PIN(N2),
ASPEED_PINCTRL_PIN(N20),
ASPEED_PINCTRL_PIN(N21),
ASPEED_PINCTRL_PIN(N22),
ASPEED_PINCTRL_PIN(N3),
ASPEED_PINCTRL_PIN(N4),
ASPEED_PINCTRL_PIN(P1),
ASPEED_PINCTRL_PIN(P2),
ASPEED_PINCTRL_PIN(R1),
ASPEED_PINCTRL_PIN(T4),
ASPEED_PINCTRL_PIN(U3),
ASPEED_PINCTRL_PIN(V2),
ASPEED_PINCTRL_PIN(V3),
ASPEED_PINCTRL_PIN(V6),
ASPEED_PINCTRL_PIN(W2),
ASPEED_PINCTRL_PIN(W3),
ASPEED_PINCTRL_PIN(Y3),
};
static const struct aspeed_pin_group aspeed_g5_groups[] = {
ASPEED_PINCTRL_GROUP(GPID0),
ASPEED_PINCTRL_GROUP(GPID2),
ASPEED_PINCTRL_GROUP(GPIE0),
ASPEED_PINCTRL_GROUP(I2C10),
ASPEED_PINCTRL_GROUP(I2C11),
ASPEED_PINCTRL_GROUP(I2C12),
ASPEED_PINCTRL_GROUP(I2C13),
ASPEED_PINCTRL_GROUP(I2C14),
ASPEED_PINCTRL_GROUP(I2C3),
ASPEED_PINCTRL_GROUP(I2C4),
ASPEED_PINCTRL_GROUP(I2C5),
ASPEED_PINCTRL_GROUP(I2C6),
ASPEED_PINCTRL_GROUP(I2C7),
ASPEED_PINCTRL_GROUP(I2C8),
ASPEED_PINCTRL_GROUP(I2C9),
ASPEED_PINCTRL_GROUP(MAC1LINK),
ASPEED_PINCTRL_GROUP(MDIO1),
ASPEED_PINCTRL_GROUP(MDIO2),
ASPEED_PINCTRL_GROUP(OSCCLK),
ASPEED_PINCTRL_GROUP(PEWAKE),
ASPEED_PINCTRL_GROUP(PWM0),
ASPEED_PINCTRL_GROUP(PWM1),
ASPEED_PINCTRL_GROUP(PWM2),
ASPEED_PINCTRL_GROUP(PWM3),
ASPEED_PINCTRL_GROUP(PWM4),
ASPEED_PINCTRL_GROUP(PWM5),
ASPEED_PINCTRL_GROUP(PWM6),
ASPEED_PINCTRL_GROUP(PWM7),
ASPEED_PINCTRL_GROUP(RGMII1),
ASPEED_PINCTRL_GROUP(RGMII2),
ASPEED_PINCTRL_GROUP(RMII1),
ASPEED_PINCTRL_GROUP(RMII2),
ASPEED_PINCTRL_GROUP(SD1),
ASPEED_PINCTRL_GROUP(SPI1),
ASPEED_PINCTRL_GROUP(TIMER4),
ASPEED_PINCTRL_GROUP(TIMER5),
ASPEED_PINCTRL_GROUP(TIMER6),
ASPEED_PINCTRL_GROUP(TIMER7),
ASPEED_PINCTRL_GROUP(TIMER8),
};
static const struct aspeed_pin_function aspeed_g5_functions[] = {
ASPEED_PINCTRL_FUNC(GPID0),
ASPEED_PINCTRL_FUNC(GPID2),
ASPEED_PINCTRL_FUNC(GPIE0),
ASPEED_PINCTRL_FUNC(I2C10),
ASPEED_PINCTRL_FUNC(I2C11),
ASPEED_PINCTRL_FUNC(I2C12),
ASPEED_PINCTRL_FUNC(I2C13),
ASPEED_PINCTRL_FUNC(I2C14),
ASPEED_PINCTRL_FUNC(I2C3),
ASPEED_PINCTRL_FUNC(I2C4),
ASPEED_PINCTRL_FUNC(I2C5),
ASPEED_PINCTRL_FUNC(I2C6),
ASPEED_PINCTRL_FUNC(I2C7),
ASPEED_PINCTRL_FUNC(I2C8),
ASPEED_PINCTRL_FUNC(I2C9),
ASPEED_PINCTRL_FUNC(MAC1LINK),
ASPEED_PINCTRL_FUNC(MDIO1),
ASPEED_PINCTRL_FUNC(MDIO2),
ASPEED_PINCTRL_FUNC(OSCCLK),
ASPEED_PINCTRL_FUNC(PEWAKE),
ASPEED_PINCTRL_FUNC(PWM0),
ASPEED_PINCTRL_FUNC(PWM1),
ASPEED_PINCTRL_FUNC(PWM2),
ASPEED_PINCTRL_FUNC(PWM3),
ASPEED_PINCTRL_FUNC(PWM4),
ASPEED_PINCTRL_FUNC(PWM5),
ASPEED_PINCTRL_FUNC(PWM6),
ASPEED_PINCTRL_FUNC(PWM7),
ASPEED_PINCTRL_FUNC(RGMII1),
ASPEED_PINCTRL_FUNC(RGMII2),
ASPEED_PINCTRL_FUNC(RMII1),
ASPEED_PINCTRL_FUNC(RMII2),
ASPEED_PINCTRL_FUNC(SD1),
ASPEED_PINCTRL_FUNC(SPI1),
ASPEED_PINCTRL_FUNC(TIMER4),
ASPEED_PINCTRL_FUNC(TIMER5),
ASPEED_PINCTRL_FUNC(TIMER6),
ASPEED_PINCTRL_FUNC(TIMER7),
ASPEED_PINCTRL_FUNC(TIMER8),
};
static struct aspeed_pinctrl_data aspeed_g5_pinctrl_data = {
.pins = aspeed_g5_pins,
.npins = ARRAY_SIZE(aspeed_g5_pins),
.groups = aspeed_g5_groups,
.ngroups = ARRAY_SIZE(aspeed_g5_groups),
.functions = aspeed_g5_functions,
.nfunctions = ARRAY_SIZE(aspeed_g5_functions),
};
static struct pinmux_ops aspeed_g5_pinmux_ops = {
.get_functions_count = aspeed_pinmux_get_fn_count,
.get_function_name = aspeed_pinmux_get_fn_name,
.get_function_groups = aspeed_pinmux_get_fn_groups,
.set_mux = aspeed_pinmux_set_mux,
.gpio_request_enable = aspeed_gpio_request_enable,
.strict = true,
};
static struct pinctrl_ops aspeed_g5_pinctrl_ops = {
.get_groups_count = aspeed_pinctrl_get_groups_count,
.get_group_name = aspeed_pinctrl_get_group_name,
.get_group_pins = aspeed_pinctrl_get_group_pins,
.pin_dbg_show = aspeed_pinctrl_pin_dbg_show,
.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
.dt_free_map = pinctrl_utils_free_map,
};
static struct pinctrl_desc aspeed_g5_pinctrl_desc = {
.name = "aspeed-g5-pinctrl",
.pins = aspeed_g5_pins,
.npins = ARRAY_SIZE(aspeed_g5_pins),
.pctlops = &aspeed_g5_pinctrl_ops,
.pmxops = &aspeed_g5_pinmux_ops,
};
static int aspeed_g5_pinctrl_probe(struct platform_device *pdev)
{
int i;
for (i = 0; i < ARRAY_SIZE(aspeed_g5_pins); i++)
aspeed_g5_pins[i].number = i;
return aspeed_pinctrl_probe(pdev, &aspeed_g5_pinctrl_desc,
&aspeed_g5_pinctrl_data);
}
static const struct of_device_id aspeed_g5_pinctrl_of_match[] = {
{ .compatible = "aspeed,ast2500-pinctrl", },
{ .compatible = "aspeed,g5-pinctrl", },
{ },
};
static struct platform_driver aspeed_g5_pinctrl_driver = {
.probe = aspeed_g5_pinctrl_probe,
.driver = {
.name = "aspeed-g5-pinctrl",
.of_match_table = aspeed_g5_pinctrl_of_match,
},
};
static int aspeed_g5_pinctrl_init(void)
{
return platform_driver_register(&aspeed_g5_pinctrl_driver);
}
arch_initcall(aspeed_g5_pinctrl_init);

View File

@ -0,0 +1,498 @@
/*
* Copyright (C) 2016 IBM Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/mfd/syscon.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/string.h>
#include "../core.h"
#include "pinctrl-aspeed.h"
int aspeed_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
{
struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
return pdata->ngroups;
}
const char *aspeed_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
unsigned int group)
{
struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
return pdata->groups[group].name;
}
int aspeed_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
unsigned int group, const unsigned int **pins,
unsigned int *npins)
{
struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
*pins = &pdata->groups[group].pins[0];
*npins = pdata->groups[group].npins;
return 0;
}
void aspeed_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s, unsigned int offset)
{
seq_printf(s, " %s", dev_name(pctldev->dev));
}
int aspeed_pinmux_get_fn_count(struct pinctrl_dev *pctldev)
{
struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
return pdata->nfunctions;
}
const char *aspeed_pinmux_get_fn_name(struct pinctrl_dev *pctldev,
unsigned int function)
{
struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
return pdata->functions[function].name;
}
int aspeed_pinmux_get_fn_groups(struct pinctrl_dev *pctldev,
unsigned int function,
const char * const **groups,
unsigned int * const num_groups)
{
struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
*groups = pdata->functions[function].groups;
*num_groups = pdata->functions[function].ngroups;
return 0;
}
static inline void aspeed_sig_desc_print_val(
const struct aspeed_sig_desc *desc, bool enable, u32 rv)
{
pr_debug("SCU%x[0x%08x]=0x%x, got 0x%x from 0x%08x\n", desc->reg,
desc->mask, enable ? desc->enable : desc->disable,
(rv & desc->mask) >> __ffs(desc->mask), rv);
}
/**
* Query the enabled or disabled state of a signal descriptor
*
* @desc: The signal descriptor of interest
* @enabled: True to query the enabled state, false to query disabled state
* @regmap: The SCU regmap instance
*
* @return True if the descriptor's bitfield is configured to the state
* selected by @enabled, false otherwise
*
* Evaluation of descriptor state is non-trivial in that it is not a binary
* outcome: The bitfields can be greater than one bit in size and thus can take
* a value that is neither the enabled nor disabled state recorded in the
* descriptor (typically this means a different function to the one of interest
* is enabled). Thus we must explicitly test for either condition as required.
*/
static bool aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc,
bool enabled, struct regmap *map)
{
unsigned int raw;
u32 want;
if (regmap_read(map, desc->reg, &raw) < 0)
return false;
aspeed_sig_desc_print_val(desc, enabled, raw);
want = enabled ? desc->enable : desc->disable;
return ((raw & desc->mask) >> __ffs(desc->mask)) == want;
}
/**
* Query the enabled or disabled state for a mux function's signal on a pin
*
* @expr: An expression controlling the signal for a mux function on a pin
* @enabled: True to query the enabled state, false to query disabled state
* @regmap: The SCU regmap instance
*
* @return True if the expression composed by @enabled evaluates true, false
* otherwise
*
* A mux function is enabled or disabled if the function's signal expression
* for each pin in the function's pin group evaluates true for the desired
* state. An signal expression evaluates true if all of its associated signal
* descriptors evaluate true for the desired state.
*
* If an expression's state is described by more than one bit, either through
* multi-bit bitfields in a single signal descriptor or through multiple signal
* descriptors of a single bit then it is possible for the expression to be in
* neither the enabled nor disabled state. Thus we must explicitly test for
* either condition as required.
*/
static bool aspeed_sig_expr_eval(const struct aspeed_sig_expr *expr,
bool enabled, struct regmap *map)
{
int i;
for (i = 0; i < expr->ndescs; i++) {
const struct aspeed_sig_desc *desc = &expr->descs[i];
if (!aspeed_sig_desc_eval(desc, enabled, map))
return false;
}
return true;
}
/**
* Configure a pin's signal by applying an expression's descriptor state for
* all descriptors in the expression.
*
* @expr: The expression associated with the function whose signal is to be
* configured
* @enable: true to enable an function's signal through a pin's signal
* expression, false to disable the function's signal
* @map: The SCU's regmap instance for pinmux register access.
*
* @return true if the expression is configured as requested, false otherwise
*/
static bool aspeed_sig_expr_set(const struct aspeed_sig_expr *expr,
bool enable, struct regmap *map)
{
int i;
bool ret;
ret = aspeed_sig_expr_eval(expr, enable, map);
if (ret)
return ret;
for (i = 0; i < expr->ndescs; i++) {
const struct aspeed_sig_desc *desc = &expr->descs[i];
u32 pattern = enable ? desc->enable : desc->disable;
/*
* Strap registers are configured in hardware or by early-boot
* firmware. Treat them as read-only despite that we can write
* them. This may mean that certain functions cannot be
* deconfigured and is the reason we re-evaluate after writing
* all descriptor bits.
*/
if (desc->reg == HW_STRAP1 || desc->reg == HW_STRAP2)
continue;
ret = regmap_update_bits(map, desc->reg, desc->mask,
pattern << __ffs(desc->mask)) == 0;
if (!ret)
return ret;
}
return aspeed_sig_expr_eval(expr, enable, map);
}
static bool aspeed_sig_expr_enable(const struct aspeed_sig_expr *expr,
struct regmap *map)
{
return aspeed_sig_expr_set(expr, true, map);
}
static bool aspeed_sig_expr_disable(const struct aspeed_sig_expr *expr,
struct regmap *map)
{
return aspeed_sig_expr_set(expr, false, map);
}
/**
* Disable a signal on a pin by disabling all provided signal expressions.
*
* @exprs: The list of signal expressions (from a priority level on a pin)
* @map: The SCU's regmap instance for pinmux register access.
*
* @return true if all expressions in the list are successfully disabled, false
* otherwise
*/
static bool aspeed_disable_sig(const struct aspeed_sig_expr **exprs,
struct regmap *map)
{
bool disabled = true;
if (!exprs)
return true;
while (*exprs) {
bool ret;
ret = aspeed_sig_expr_disable(*exprs, map);
disabled = disabled && ret;
exprs++;
}
return disabled;
}
/**
* Search for the signal expression needed to enable the pin's signal for the
* requested function.
*
* @exprs: List of signal expressions (haystack)
* @name: The name of the requested function (needle)
*
* @return A pointer to the signal expression whose function tag matches the
* provided name, otherwise NULL.
*
*/
static const struct aspeed_sig_expr *aspeed_find_expr_by_name(
const struct aspeed_sig_expr **exprs, const char *name)
{
while (*exprs) {
if (strcmp((*exprs)->function, name) == 0)
return *exprs;
exprs++;
}
return NULL;
}
static char *get_defined_attribute(const struct aspeed_pin_desc *pdesc,
const char *(*get)(
const struct aspeed_sig_expr *))
{
char *found = NULL;
size_t len = 0;
const struct aspeed_sig_expr ***prios, **funcs, *expr;
prios = pdesc->prios;
while ((funcs = *prios)) {
while ((expr = *funcs)) {
const char *str = get(expr);
size_t delta = strlen(str) + 2;
char *expanded;
expanded = krealloc(found, len + delta + 1, GFP_KERNEL);
if (!expanded) {
kfree(found);
return expanded;
}
found = expanded;
found[len] = '\0';
len += delta;
strcat(found, str);
strcat(found, ", ");
funcs++;
}
prios++;
}
if (len < 2) {
kfree(found);
return NULL;
}
found[len - 2] = '\0';
return found;
}
static const char *aspeed_sig_expr_function(const struct aspeed_sig_expr *expr)
{
return expr->function;
}
static char *get_defined_functions(const struct aspeed_pin_desc *pdesc)
{
return get_defined_attribute(pdesc, aspeed_sig_expr_function);
}
static const char *aspeed_sig_expr_signal(const struct aspeed_sig_expr *expr)
{
return expr->signal;
}
static char *get_defined_signals(const struct aspeed_pin_desc *pdesc)
{
return get_defined_attribute(pdesc, aspeed_sig_expr_signal);
}
int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
unsigned int group)
{
int i;
const struct aspeed_pinctrl_data *pdata =
pinctrl_dev_get_drvdata(pctldev);
const struct aspeed_pin_group *pgroup = &pdata->groups[group];
const struct aspeed_pin_function *pfunc =
&pdata->functions[function];
for (i = 0; i < pgroup->npins; i++) {
int pin = pgroup->pins[i];
const struct aspeed_pin_desc *pdesc = pdata->pins[pin].drv_data;
const struct aspeed_sig_expr *expr = NULL;
const struct aspeed_sig_expr **funcs;
const struct aspeed_sig_expr ***prios;
if (!pdesc)
return -EINVAL;
prios = pdesc->prios;
if (!prios)
continue;
/* Disable functions at a higher priority than that requested */
while ((funcs = *prios)) {
expr = aspeed_find_expr_by_name(funcs, pfunc->name);
if (expr)
break;
if (!aspeed_disable_sig(funcs, pdata->map))
return -EPERM;
prios++;
}
if (!expr) {
char *functions = get_defined_functions(pdesc);
char *signals = get_defined_signals(pdesc);
pr_warn("No function %s found on pin %s (%d). Found signal(s) %s for function(s) %s\n",
pfunc->name, pdesc->name, pin, signals,
functions);
kfree(signals);
kfree(functions);
return -ENXIO;
}
if (!aspeed_sig_expr_enable(expr, pdata->map))
return -EPERM;
}
return 0;
}
static bool aspeed_expr_is_gpio(const struct aspeed_sig_expr *expr)
{
/*
* The signal type is GPIO if the signal name has "GPIO" as a prefix.
* strncmp (rather than strcmp) is used to implement the prefix
* requirement.
*
* expr->signal might look like "GPIOT3" in the GPIO case.
*/
return strncmp(expr->signal, "GPIO", 4) == 0;
}
static bool aspeed_gpio_in_exprs(const struct aspeed_sig_expr **exprs)
{
if (!exprs)
return false;
while (*exprs) {
if (aspeed_expr_is_gpio(*exprs))
return true;
exprs++;
}
return false;
}
int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int offset)
{
const struct aspeed_pinctrl_data *pdata =
pinctrl_dev_get_drvdata(pctldev);
const struct aspeed_pin_desc *pdesc = pdata->pins[offset].drv_data;
const struct aspeed_sig_expr ***prios, **funcs, *expr;
if (!pdesc)
return -EINVAL;
prios = pdesc->prios;
if (!prios)
return -ENXIO;
/* Disable any functions of higher priority than GPIO */
while ((funcs = *prios)) {
if (aspeed_gpio_in_exprs(funcs))
break;
if (!aspeed_disable_sig(funcs, pdata->map))
return -EPERM;
prios++;
}
if (!funcs) {
char *signals = get_defined_signals(pdesc);
pr_warn("No GPIO signal type found on pin %s (%d). Found: %s\n",
pdesc->name, offset, signals);
kfree(signals);
return -ENXIO;
}
expr = *funcs;
/*
* Disabling all higher-priority expressions is enough to enable the
* lowest-priority signal type. As such it has no associated
* expression.
*/
if (!expr)
return 0;
/*
* If GPIO is not the lowest priority signal type, assume there is only
* one expression defined to enable the GPIO function
*/
if (!aspeed_sig_expr_enable(expr, pdata->map))
return -EPERM;
return 0;
}
int aspeed_pinctrl_probe(struct platform_device *pdev,
struct pinctrl_desc *pdesc,
struct aspeed_pinctrl_data *pdata)
{
struct device *parent;
struct pinctrl_dev *pctl;
parent = pdev->dev.parent;
if (!parent) {
dev_err(&pdev->dev, "No parent for syscon pincontroller\n");
return -ENODEV;
}
pdata->map = syscon_node_to_regmap(parent->of_node);
if (IS_ERR(pdata->map)) {
dev_err(&pdev->dev, "No regmap for syscon pincontroller parent\n");
return PTR_ERR(pdata->map);
}
pctl = pinctrl_register(pdesc, &pdev->dev, pdata);
if (IS_ERR(pctl)) {
dev_err(&pdev->dev, "Failed to register pinctrl\n");
return PTR_ERR(pctl);
}
platform_set_drvdata(pdev, pdata);
return 0;
}

View File

@ -0,0 +1,569 @@
/*
* Copyright (C) 2016 IBM Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef PINCTRL_ASPEED
#define PINCTRL_ASPEED
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/regmap.h>
/*
* The ASPEED SoCs provide typically more than 200 pins for GPIO and other
* functions. The SoC function enabled on a pin is determined on a priority
* basis where a given pin can provide a number of different signal types.
*
* The signal active on a pin is described by both a priority level and
* compound logical expressions involving multiple operators, registers and
* bits. Some difficulty arises as the pin's function bit masks for each
* priority level are frequently not the same (i.e. cannot just flip a bit to
* change from a high to low priority signal), or even in the same register.
* Further, not all signals can be unmuxed, as some expressions depend on
* values in the hardware strapping register (which is treated as read-only).
*
* SoC Multi-function Pin Expression Examples
* ------------------------------------------
*
* Here are some sample mux configurations from the AST2400 and AST2500
* datasheets to illustrate the corner cases, roughly in order of least to most
* corner. The signal priorities are in decending order from P0 (highest).
*
* D6 is a pin with a single function (beside GPIO); a high priority signal
* that participates in one function:
*
* Ball | Default | P0 Signal | P0 Expression | P1 Signal | P1 Expression | Other
* -----+---------+-----------+-----------------------------+-----------+---------------+----------
* D6 GPIOA0 MAC1LINK SCU80[0]=1 GPIOA0
* -----+---------+-----------+-----------------------------+-----------+---------------+----------
*
* C5 is a multi-signal pin (high and low priority signals). Here we touch
* different registers for the different functions that enable each signal:
*
* -----+---------+-----------+-----------------------------+-----------+---------------+----------
* C5 GPIOA4 SCL9 SCU90[22]=1 TIMER5 SCU80[4]=1 GPIOA4
* -----+---------+-----------+-----------------------------+-----------+---------------+----------
*
* E19 is a single-signal pin with two functions that influence the active
* signal. In this case both bits have the same meaning - enable a dedicated
* LPC reset pin. However it's not always the case that the bits in the
* OR-relationship have the same meaning.
*
* -----+---------+-----------+-----------------------------+-----------+---------------+----------
* E19 GPIOB4 LPCRST# SCU80[12]=1 | Strap[14]=1 GPIOB4
* -----+---------+-----------+-----------------------------+-----------+---------------+----------
*
* For example, pin B19 has a low-priority signal that's enabled by two
* distinct SoC functions: A specific SIOPBI bit in register SCUA4, and an ACPI
* bit in the STRAP register. The ACPI bit configures signals on pins in
* addition to B19. Both of the low priority functions as well as the high
* priority function must be disabled for GPIOF1 to be used.
*
* Ball | Default | P0 Signal | P0 Expression | P1 Signal | P1 Expression | Other
* -----+---------+-----------+-----------------------------------------+-----------+----------------------------------------+----------
* B19 GPIOF1 NDCD4 SCU80[25]=1 SIOPBI# SCUA4[12]=1 | Strap[19]=0 GPIOF1
* -----+---------+-----------+-----------------------------------------+-----------+----------------------------------------+----------
*
* For pin E18, the SoC ANDs the expected state of three bits to determine the
* pin's active signal:
*
* * SCU3C[3]: Enable external SOC reset function
* * SCU80[15]: Enable SPICS1# or EXTRST# function pin
* * SCU90[31]: Select SPI interface CS# output
*
* -----+---------+-----------+-----------------------------------------+-----------+----------------------------------------+----------
* E18 GPIOB7 EXTRST# SCU3C[3]=1 & SCU80[15]=1 & SCU90[31]=0 SPICS1# SCU3C[3]=1 & SCU80[15]=1 & SCU90[31]=1 GPIOB7
* -----+---------+-----------+-----------------------------------------+-----------+----------------------------------------+----------
*
* (Bits SCU3C[3] and SCU80[15] appear to only be used in the expressions for
* selecting the signals on pin E18)
*
* Pin T5 is a multi-signal pin with a more complex configuration:
*
* Ball | Default | P0 Signal | P0 Expression | P1 Signal | P1 Expression | Other
* -----+---------+-----------+------------------------------+-----------+---------------+----------
* T5 GPIOL1 VPIDE SCU90[5:4]!=0 & SCU84[17]=1 NDCD1 SCU84[17]=1 GPIOL1
* -----+---------+-----------+------------------------------+-----------+---------------+----------
*
* The high priority signal configuration is best thought of in terms of its
* exploded form, with reference to the SCU90[5:4] bits:
*
* * SCU90[5:4]=00: disable
* * SCU90[5:4]=01: 18 bits (R6/G6/B6) video mode.
* * SCU90[5:4]=10: 24 bits (R8/G8/B8) video mode.
* * SCU90[5:4]=11: 30 bits (R10/G10/B10) video mode.
*
* Re-writing:
*
* -----+---------+-----------+------------------------------+-----------+---------------+----------
* T5 GPIOL1 VPIDE (SCU90[5:4]=1 & SCU84[17]=1) NDCD1 SCU84[17]=1 GPIOL1
* | (SCU90[5:4]=2 & SCU84[17]=1)
* | (SCU90[5:4]=3 & SCU84[17]=1)
* -----+---------+-----------+------------------------------+-----------+---------------+----------
*
* For reference the SCU84[17] bit configure the "UART1 NDCD1 or Video VPIDE
* function pin", where the signal itself is determined by whether SCU94[5:4]
* is disabled or in one of the 18, 24 or 30bit video modes.
*
* Other video-input-related pins require an explicit state in SCU90[5:4], e.g.
* W1 and U5:
*
* -----+---------+-----------+------------------------------+-----------+---------------+----------
* W1 GPIOL6 VPIB0 SCU90[5:4]=3 & SCU84[22]=1 TXD1 SCU84[22]=1 GPIOL6
* U5 GPIOL7 VPIB1 SCU90[5:4]=3 & SCU84[23]=1 RXD1 SCU84[23]=1 GPIOL7
* -----+---------+-----------+------------------------------+-----------+---------------+----------
*
* The examples of T5 and W1 are particularly fertile, as they also demonstrate
* that despite operating as part of the video input bus each signal needs to
* be enabled individually via it's own SCU84 (in the cases of T5 and W1)
* register bit. This is a little crazy if the bus doesn't have optional
* signals, but is used to decent effect with some of the UARTs where not all
* signals are required. However, this isn't done consistently - UART1 is
* enabled on a per-pin basis, and by contrast, all signals for UART6 are
* enabled by a single bit.
*
* Further, the high and low priority signals listed in the table above share
* a configuration bit. The VPI signals should operate in concert in a single
* function, but the UART signals should retain the ability to be configured
* independently. This pushes the implementation down the path of tagging a
* signal's expressions with the function they participate in, rather than
* defining masks affecting multiple signals per function. The latter approach
* fails in this instance where applying the configuration for the UART pin of
* interest will stomp on the state of other UART signals when disabling the
* VPI functions on the current pin.
*
* Ball | Default | P0 Signal | P0 Expression | P1 Signal | P1 Expression | Other
* -----+------------+-----------+---------------------------+-----------+---------------+------------
* A12 RGMII1TXCK GPIOT0 SCUA0[0]=1 RMII1TXEN Strap[6]=0 RGMII1TXCK
* B12 RGMII1TXCTL GPIOT1 SCUA0[1]=1 Strap[6]=0 RGMII1TXCTL
* -----+------------+-----------+---------------------------+-----------+---------------+------------
*
* A12 demonstrates that the "Other" signal isn't always GPIO - in this case
* GPIOT0 is a high-priority signal and RGMII1TXCK is Other. Thus, GPIO
* should be treated like any other signal type with full function expression
* requirements, and not assumed to be the default case. Separately, GPIOT0 and
* GPIOT1's signal descriptor bits are distinct, therefore we must iterate all
* pins in the function's group to disable the higher-priority signals such
* that the signal for the function of interest is correctly enabled.
*
* Finally, three priority levels aren't always enough; the AST2500 brings with
* it 18 pins of five priority levels, however the 18 pins only use three of
* the five priority levels.
*
* Ultimately the requirement to control pins in the examples above drive the
* design:
*
* * Pins provide signals according to functions activated in the mux
* configuration
*
* * Pins provide up to five signal types in a priority order
*
* * For priorities levels defined on a pin, each priority provides one signal
*
* * Enabling lower priority signals requires higher priority signals be
* disabled
*
* * A function represents a set of signals; functions are distinct if their
* sets of signals are not equal
*
* * Signals participate in one or more functions
*
* * A function is described by an expression of one or more signal
* descriptors, which compare bit values in a register
*
* * A signal expression is the smallest set of signal descriptors whose
* comparisons must evaluate 'true' for a signal to be enabled on a pin.
*
* * A function's signal is active on a pin if evaluating all signal
* descriptors in the pin's signal expression for the function yields a 'true'
* result
*
* * A signal at a given priority on a given pin is active if any of the
* functions in which the signal participates are active, and no higher
* priority signal on the pin is active
*
* * GPIO is configured per-pin
*
* And so:
*
* * To disable a signal, any function(s) activating the signal must be
* disabled
*
* * Each pin must know the signal expressions of functions in which it
* participates, for the purpose of enabling the Other function. This is done
* by deactivating all functions that activate higher priority signals on the
* pin.
*
* As a concrete example:
*
* * T5 provides three signals types: VPIDE, NDCD1 and GPIO
*
* * The VPIDE signal participates in 3 functions: VPI18, VPI24 and VPI30
*
* * The NDCD1 signal participates in just its own NDCD1 function
*
* * VPIDE is high priority, NDCD1 is low priority, and GPIOL1 is the least
* prioritised
*
* * The prerequisit for activating the NDCD1 signal is that the VPI18, VPI24
* and VPI30 functions all be disabled
*
* * Similarly, all of VPI18, VPI24, VPI30 and NDCD1 functions must be disabled
* to provide GPIOL6
*
* Considerations
* --------------
*
* If pinctrl allows us to allocate a pin we can configure a function without
* concern for the function of already allocated pins, if pin groups are
* created with respect to the SoC functions in which they participate. This is
* intuitive, but it did not feel obvious from the bit/pin relationships.
*
* Conversely, failing to allocate all pins in a group indicates some bits (as
* well as pins) required for the group's configuration will already be in use,
* likely in a way that's inconsistent with the requirements of the failed
* group.
*/
/*
* The "Multi-function Pins Mapping and Control" table in the SoC datasheet
* references registers by the device/offset mnemonic. The register macros
* below are named the same way to ease transcription and verification (as
* opposed to naming them e.g. PINMUX_CTRL_[0-9]). Further, signal expressions
* reference registers beyond those dedicated to pinmux, such as the system
* reset control and MAC clock configuration registers. The AST2500 goes a step
* further and references registers in the graphics IP block, but that isn't
* handled yet.
*/
#define SCU2C 0x2C /* Misc. Control Register */
#define SCU3C 0x3C /* System Reset Control/Status Register */
#define SCU48 0x48 /* MAC Interface Clock Delay Setting */
#define HW_STRAP1 0x70 /* AST2400 strapping is 33 bits, is split */
#define SCU80 0x80 /* Multi-function Pin Control #1 */
#define SCU84 0x84 /* Multi-function Pin Control #2 */
#define SCU88 0x88 /* Multi-function Pin Control #3 */
#define SCU8C 0x8C /* Multi-function Pin Control #4 */
#define SCU90 0x90 /* Multi-function Pin Control #5 */
#define SCU94 0x94 /* Multi-function Pin Control #6 */
#define SCUA0 0xA0 /* Multi-function Pin Control #7 */
#define SCUA4 0xA4 /* Multi-function Pin Control #8 */
#define SCUA8 0xA8 /* Multi-function Pin Control #9 */
#define HW_STRAP2 0xD0 /* Strapping */
/**
* A signal descriptor, which describes the register, bits and the
* enable/disable values that should be compared or written.
*
* @reg: The register offset from base in bytes
* @mask: The mask to apply to the register. The lowest set bit of the mask is
* used to derive the shift value.
* @enable: The value that enables the function. Value should be in the LSBs,
* not at the position of the mask.
* @disable: The value that disables the function. Value should be in the
* LSBs, not at the position of the mask.
*/
struct aspeed_sig_desc {
unsigned int reg;
u32 mask;
u32 enable;
u32 disable;
};
/**
* Describes a signal expression. The expression is evaluated by ANDing the
* evaluation of the descriptors.
*
* @signal: The signal name for the priority level on the pin. If the signal
* type is GPIO, then the signal name must begin with the string
* "GPIO", e.g. GPIOA0, GPIOT4 etc.
* @function: The name of the function the signal participates in for the
* associated expression
* @ndescs: The number of signal descriptors in the expression
* @descs: Pointer to an array of signal descriptors that comprise the
* function expression
*/
struct aspeed_sig_expr {
const char *signal;
const char *function;
int ndescs;
const struct aspeed_sig_desc *descs;
};
/**
* A struct capturing the list of expressions enabling signals at each priority
* for a given pin. The signal configuration for a priority level is evaluated
* by ORing the evaluation of the signal expressions in the respective
* priority's list.
*
* @name: A name for the pin
* @prios: A pointer to an array of expression list pointers
*
*/
struct aspeed_pin_desc {
const char *name;
const struct aspeed_sig_expr ***prios;
};
/* Macro hell */
/**
* Short-hand macro for describing a configuration enabled by the state of one
* bit. The disable value is derived.
*
* @reg: The signal's associated register, offset from base
* @idx: The signal's bit index in the register
* @val: The value (0 or 1) that enables the function
*/
#define SIG_DESC_BIT(reg, idx, val) \
{ reg, BIT_MASK(idx), val, (((val) + 1) & 1) }
/**
* A further short-hand macro describing a configuration enabled with a set bit.
*
* @reg: The configuration's associated register, offset from base
* @idx: The configuration's bit index in the register
*/
#define SIG_DESC_SET(reg, idx) SIG_DESC_BIT(reg, idx, 1)
#define SIG_DESC_LIST_SYM(sig, func) sig_descs_ ## sig ## _ ## func
#define SIG_DESC_LIST_DECL(sig, func, ...) \
static const struct aspeed_sig_desc SIG_DESC_LIST_SYM(sig, func)[] = \
{ __VA_ARGS__ }
#define SIG_EXPR_SYM(sig, func) sig_expr_ ## sig ## _ ## func
#define SIG_EXPR_DECL_(sig, func) \
static const struct aspeed_sig_expr SIG_EXPR_SYM(sig, func) = \
{ \
.signal = #sig, \
.function = #func, \
.ndescs = ARRAY_SIZE(SIG_DESC_LIST_SYM(sig, func)), \
.descs = &(SIG_DESC_LIST_SYM(sig, func))[0], \
}
/**
* Declare a signal expression.
*
* @sig: A macro symbol name for the signal (is subjected to stringification
* and token pasting)
* @func: The function in which the signal is participating
* @...: Signal descriptors that define the signal expression
*
* For example, the following declares the ROMD8 signal for the ROM16 function:
*
* SIG_EXPR_DECL(ROMD8, ROM16, SIG_DESC_SET(SCU90, 6));
*
* And with multiple signal descriptors:
*
* SIG_EXPR_DECL(ROMD8, ROM16S, SIG_DESC_SET(HW_STRAP1, 4),
* { HW_STRAP1, GENMASK(1, 0), 0, 0 });
*/
#define SIG_EXPR_DECL(sig, func, ...) \
SIG_DESC_LIST_DECL(sig, func, __VA_ARGS__); \
SIG_EXPR_DECL_(sig, func)
/**
* Declare a pointer to a signal expression
*
* @sig: The macro symbol name for the signal (subjected to token pasting)
* @func: The macro symbol name for the function (subjected to token pasting)
*/
#define SIG_EXPR_PTR(sig, func) (&SIG_EXPR_SYM(sig, func))
#define SIG_EXPR_LIST_SYM(sig) sig_exprs_ ## sig
/**
* Declare a signal expression list for reference in a struct aspeed_pin_prio.
*
* @sig: A macro symbol name for the signal (is subjected to token pasting)
* @...: Signal expression structure pointers (use SIG_EXPR_PTR())
*
* For example, the 16-bit ROM bus can be enabled by one of two possible signal
* expressions:
*
* SIG_EXPR_DECL(ROMD8, ROM16, SIG_DESC_SET(SCU90, 6));
* SIG_EXPR_DECL(ROMD8, ROM16S, SIG_DESC_SET(HW_STRAP1, 4),
* { HW_STRAP1, GENMASK(1, 0), 0, 0 });
* SIG_EXPR_LIST_DECL(ROMD8, SIG_EXPR_PTR(ROMD8, ROM16),
* SIG_EXPR_PTR(ROMD8, ROM16S));
*/
#define SIG_EXPR_LIST_DECL(sig, ...) \
static const struct aspeed_sig_expr *SIG_EXPR_LIST_SYM(sig)[] = \
{ __VA_ARGS__, NULL }
/**
* A short-hand macro for declaring a function expression and an expression
* list with a single function.
*
* @func: A macro symbol name for the function (is subjected to token pasting)
* @...: Function descriptors that define the function expression
*
* For example, signal NCTS6 participates in its own function with one group:
*
* SIG_EXPR_LIST_DECL_SINGLE(NCTS6, NCTS6, SIG_DESC_SET(SCU90, 7));
*/
#define SIG_EXPR_LIST_DECL_SINGLE(sig, func, ...) \
SIG_DESC_LIST_DECL(sig, func, __VA_ARGS__); \
SIG_EXPR_DECL_(sig, func); \
SIG_EXPR_LIST_DECL(sig, SIG_EXPR_PTR(sig, func))
#define SIG_EXPR_LIST_DECL_DUAL(sig, f0, f1) \
SIG_EXPR_LIST_DECL(sig, SIG_EXPR_PTR(sig, f0), SIG_EXPR_PTR(sig, f1))
#define SIG_EXPR_LIST_PTR(sig) (&SIG_EXPR_LIST_SYM(sig)[0])
#define PIN_EXPRS_SYM(pin) pin_exprs_ ## pin
#define PIN_EXPRS_PTR(pin) (&PIN_EXPRS_SYM(pin)[0])
#define PIN_SYM(pin) pin_ ## pin
#define MS_PIN_DECL_(pin, ...) \
static const struct aspeed_sig_expr **PIN_EXPRS_SYM(pin)[] = \
{ __VA_ARGS__, NULL }; \
static const struct aspeed_pin_desc PIN_SYM(pin) = \
{ #pin, PIN_EXPRS_PTR(pin) }
/**
* Declare a multi-signal pin
*
* @pin: The pin number
* @other: Macro name for "other" functionality (subjected to stringification)
* @high: Macro name for the highest priority signal functions
* @low: Macro name for the low signal functions
*
* For example:
*
* #define A8 56
* SIG_EXPR_DECL(ROMD8, ROM16, SIG_DESC_SET(SCU90, 6));
* SIG_EXPR_DECL(ROMD8, ROM16S, SIG_DESC_SET(HW_STRAP1, 4),
* { HW_STRAP1, GENMASK(1, 0), 0, 0 });
* SIG_EXPR_LIST_DECL(ROMD8, SIG_EXPR_PTR(ROMD8, ROM16),
* SIG_EXPR_PTR(ROMD8, ROM16S));
* SIG_EXPR_LIST_DECL_SINGLE(NCTS6, NCTS6, SIG_DESC_SET(SCU90, 7));
* MS_PIN_DECL(A8, GPIOH0, ROMD8, NCTS6);
*/
#define MS_PIN_DECL(pin, other, high, low) \
SIG_EXPR_LIST_DECL_SINGLE(other, other); \
MS_PIN_DECL_(pin, \
SIG_EXPR_LIST_PTR(high), \
SIG_EXPR_LIST_PTR(low), \
SIG_EXPR_LIST_PTR(other))
#define PIN_GROUP_SYM(func) pins_ ## func
#define FUNC_GROUP_SYM(func) groups_ ## func
#define FUNC_GROUP_DECL(func, ...) \
static const int PIN_GROUP_SYM(func)[] = { __VA_ARGS__ }; \
static const char *FUNC_GROUP_SYM(func)[] = { #func }
/**
* Declare a single signal pin
*
* @pin: The pin number
* @other: Macro name for "other" functionality (subjected to stringification)
* @sig: Macro name for the signal (subjected to stringification)
*
* For example:
*
* #define E3 80
* SIG_EXPR_LIST_DECL_SINGLE(SCL5, I2C5, I2C5_DESC);
* SS_PIN_DECL(E3, GPIOK0, SCL5);
*/
#define SS_PIN_DECL(pin, other, sig) \
SIG_EXPR_LIST_DECL_SINGLE(other, other); \
MS_PIN_DECL_(pin, SIG_EXPR_LIST_PTR(sig), SIG_EXPR_LIST_PTR(other))
/**
* Single signal, single function pin declaration
*
* @pin: The pin number
* @other: Macro name for "other" functionality (subjected to stringification)
* @sig: Macro name for the signal (subjected to stringification)
* @...: Signal descriptors that define the function expression
*
* For example:
*
* SSSF_PIN_DECL(A4, GPIOA2, TIMER3, SIG_DESC_SET(SCU80, 2));
*/
#define SSSF_PIN_DECL(pin, other, sig, ...) \
SIG_EXPR_LIST_DECL_SINGLE(sig, sig, __VA_ARGS__); \
SIG_EXPR_LIST_DECL_SINGLE(other, other); \
MS_PIN_DECL_(pin, SIG_EXPR_LIST_PTR(sig), SIG_EXPR_LIST_PTR(other)); \
FUNC_GROUP_DECL(sig, pin)
#define GPIO_PIN_DECL(pin, gpio) \
SIG_EXPR_LIST_DECL_SINGLE(gpio, gpio); \
MS_PIN_DECL_(pin, SIG_EXPR_LIST_PTR(gpio))
struct aspeed_pinctrl_data {
struct regmap *map;
const struct pinctrl_pin_desc *pins;
const unsigned int npins;
const struct aspeed_pin_group *groups;
const unsigned int ngroups;
const struct aspeed_pin_function *functions;
const unsigned int nfunctions;
};
#define ASPEED_PINCTRL_PIN(name_) \
[name_] = { \
.number = name_, \
.name = #name_, \
.drv_data = (void *) &(PIN_SYM(name_)) \
}
struct aspeed_pin_group {
const char *name;
const unsigned int *pins;
const unsigned int npins;
};
#define ASPEED_PINCTRL_GROUP(name_) { \
.name = #name_, \
.pins = &(PIN_GROUP_SYM(name_))[0], \
.npins = ARRAY_SIZE(PIN_GROUP_SYM(name_)), \
}
struct aspeed_pin_function {
const char *name;
const char *const *groups;
unsigned int ngroups;
};
#define ASPEED_PINCTRL_FUNC(name_, ...) { \
.name = #name_, \
.groups = &FUNC_GROUP_SYM(name_)[0], \
.ngroups = ARRAY_SIZE(FUNC_GROUP_SYM(name_)), \
}
int aspeed_pinctrl_get_groups_count(struct pinctrl_dev *pctldev);
const char *aspeed_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
unsigned int group);
int aspeed_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
unsigned int group, const unsigned int **pins,
unsigned int *npins);
void aspeed_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s, unsigned int offset);
int aspeed_pinmux_get_fn_count(struct pinctrl_dev *pctldev);
const char *aspeed_pinmux_get_fn_name(struct pinctrl_dev *pctldev,
unsigned int function);
int aspeed_pinmux_get_fn_groups(struct pinctrl_dev *pctldev,
unsigned int function, const char * const **groups,
unsigned int * const num_groups);
int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
unsigned int group);
int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int offset);
int aspeed_pinctrl_probe(struct platform_device *pdev,
struct pinctrl_desc *pdesc,
struct aspeed_pinctrl_data *pdata);
#endif /* PINCTRL_ASPEED */

View File

@ -1018,7 +1018,7 @@ static void bcm281xx_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
seq_printf(s, " %s", dev_name(pctldev->dev));
}
static struct pinctrl_ops bcm281xx_pinctrl_ops = {
static const struct pinctrl_ops bcm281xx_pinctrl_ops = {
.get_groups_count = bcm281xx_pinctrl_get_groups_count,
.get_group_name = bcm281xx_pinctrl_get_group_name,
.get_group_pins = bcm281xx_pinctrl_get_group_pins,
@ -1080,7 +1080,7 @@ static int bcm281xx_pinmux_set(struct pinctrl_dev *pctldev,
return rc;
}
static struct pinmux_ops bcm281xx_pinctrl_pinmux_ops = {
static const struct pinmux_ops bcm281xx_pinctrl_pinmux_ops = {
.get_functions_count = bcm281xx_pinctrl_get_fcns_count,
.get_function_name = bcm281xx_pinctrl_get_fcn_name,
.get_function_groups = bcm281xx_pinctrl_get_fcn_groups,

View File

@ -531,7 +531,7 @@ static void ns2_pin_dbg_show(struct pinctrl_dev *pctrl_dev,
seq_printf(s, " %s", dev_name(pctrl_dev->dev));
}
static struct pinctrl_ops ns2_pinctrl_ops = {
static const struct pinctrl_ops ns2_pinctrl_ops = {
.get_groups_count = ns2_get_groups_count,
.get_group_name = ns2_get_group_name,
.get_group_pins = ns2_get_group_pins,
@ -959,7 +959,7 @@ static int ns2_pin_config_set(struct pinctrl_dev *pctrldev, unsigned int pin,
out:
return ret;
}
static struct pinmux_ops ns2_pinmux_ops = {
static const struct pinmux_ops ns2_pinmux_ops = {
.get_functions_count = ns2_get_functions_count,
.get_function_name = ns2_get_function_name,
.get_function_groups = ns2_get_function_groups,

View File

@ -348,7 +348,7 @@ static void nsp_pin_dbg_show(struct pinctrl_dev *pctrl_dev,
seq_printf(s, " %s", dev_name(pctrl_dev->dev));
}
static struct pinctrl_ops nsp_pinctrl_ops = {
static const struct pinctrl_ops nsp_pinctrl_ops = {
.get_groups_count = nsp_get_groups_count,
.get_group_name = nsp_get_group_name,
.get_group_pins = nsp_get_group_pins,
@ -518,7 +518,7 @@ static void nsp_gpio_disable_free(struct pinctrl_dev *pctrl_dev,
spin_unlock_irqrestore(&pinctrl->lock, flags);
}
static struct pinmux_ops nsp_pinmux_ops = {
static const struct pinmux_ops nsp_pinmux_ops = {
.get_functions_count = nsp_get_functions_count,
.get_function_name = nsp_get_function_name,
.get_function_groups = nsp_get_function_groups,

View File

@ -315,7 +315,7 @@ static int imx_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
/* Currently implementation only for shared mux/conf register */
if (!(info->flags & SHARE_MUX_CONF_REG))
return -EINVAL;
return 0;
pin_reg = &info->pin_regs[offset];
if (pin_reg->mux_reg == -1)
@ -380,7 +380,7 @@ static int imx_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
* They are part of the shared mux/conf register.
*/
if (!(info->flags & SHARE_MUX_CONF_REG))
return -EINVAL;
return 0;
pin_reg = &info->pin_regs[offset];
if (pin_reg->mux_reg == -1)
@ -501,7 +501,7 @@ static void imx_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
ret = imx_pinconf_get(pctldev, pin->pin, &config);
if (ret)
return;
seq_printf(s, "%s: 0x%lx", name, config);
seq_printf(s, " %s: 0x%lx\n", name, config);
}
}

View File

@ -134,6 +134,7 @@ struct chv_gpio_pinrange {
* @gpio_ranges: An array of GPIO ranges in this community
* @ngpio_ranges: Number of GPIO ranges
* @ngpios: Total number of GPIOs in this community
* @nirqs: Total number of IRQs this community can generate
*/
struct chv_community {
const char *uid;
@ -146,6 +147,7 @@ struct chv_community {
const struct chv_gpio_pinrange *gpio_ranges;
size_t ngpio_ranges;
size_t ngpios;
size_t nirqs;
};
struct chv_pin_context {
@ -396,6 +398,12 @@ static const struct chv_community southwest_community = {
.gpio_ranges = southwest_gpio_ranges,
.ngpio_ranges = ARRAY_SIZE(southwest_gpio_ranges),
.ngpios = ARRAY_SIZE(southwest_pins),
/*
* Southwest community can benerate GPIO interrupts only for the
* first 8 interrupts. The upper half (8-15) can only be used to
* trigger GPEs.
*/
.nirqs = 8,
};
static const struct pinctrl_pin_desc north_pins[] = {
@ -479,6 +487,12 @@ static const struct chv_community north_community = {
.gpio_ranges = north_gpio_ranges,
.ngpio_ranges = ARRAY_SIZE(north_gpio_ranges),
.ngpios = ARRAY_SIZE(north_pins),
/*
* North community can benerate GPIO interrupts only for the first
* 8 interrupts. The upper half (8-15) can only be used to trigger
* GPEs.
*/
.nirqs = 8,
};
static const struct pinctrl_pin_desc east_pins[] = {
@ -521,6 +535,7 @@ static const struct chv_community east_community = {
.gpio_ranges = east_gpio_ranges,
.ngpio_ranges = ARRAY_SIZE(east_gpio_ranges),
.ngpios = ARRAY_SIZE(east_pins),
.nirqs = 16,
};
static const struct pinctrl_pin_desc southeast_pins[] = {
@ -646,6 +661,7 @@ static const struct chv_community southeast_community = {
.gpio_ranges = southeast_gpio_ranges,
.ngpio_ranges = ARRAY_SIZE(southeast_gpio_ranges),
.ngpios = ARRAY_SIZE(southeast_pins),
.nirqs = 16,
};
static const struct chv_community *chv_communities[] = {
@ -1497,7 +1513,7 @@ static void chv_gpio_irq_handler(struct irq_desc *desc)
chained_irq_enter(chip, desc);
pending = readl(pctrl->regs + CHV_INTSTAT);
for_each_set_bit(intr_line, &pending, 16) {
for_each_set_bit(intr_line, &pending, pctrl->community->nirqs) {
unsigned irq, offset;
offset = pctrl->intr_lines[intr_line];
@ -1520,8 +1536,9 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
chip->label = dev_name(pctrl->dev);
chip->parent = pctrl->dev;
chip->base = -1;
chip->irq_need_valid_mask = true;
ret = gpiochip_add_data(chip, pctrl);
ret = devm_gpiochip_add_data(pctrl->dev, chip, pctrl);
if (ret) {
dev_err(pctrl->dev, "Failed to register gpiochip\n");
return ret;
@ -1533,12 +1550,27 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
range->base, range->npins);
if (ret) {
dev_err(pctrl->dev, "failed to add GPIO pin range\n");
goto fail;
return ret;
}
offset += range->npins;
}
/* Do not add GPIOs that can only generate GPEs to the IRQ domain */
for (i = 0; i < pctrl->community->npins; i++) {
const struct pinctrl_pin_desc *desc;
u32 intsel;
desc = &pctrl->community->pins[i];
intsel = readl(chv_padreg(pctrl, desc->number, CHV_PADCTRL0));
intsel &= CHV_PADCTRL0_INTSEL_MASK;
intsel >>= CHV_PADCTRL0_INTSEL_SHIFT;
if (intsel >= pctrl->community->nirqs)
clear_bit(i, chip->irq_valid_mask);
}
/* Clear all interrupts */
chv_writel(0xffff, pctrl->regs + CHV_INTSTAT);
@ -1546,17 +1578,12 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
handle_bad_irq, IRQ_TYPE_NONE);
if (ret) {
dev_err(pctrl->dev, "failed to add IRQ chip\n");
goto fail;
return ret;
}
gpiochip_set_chained_irqchip(chip, &chv_gpio_irqchip, irq,
chv_gpio_irq_handler);
return 0;
fail:
gpiochip_remove(chip);
return ret;
}
static int chv_pinctrl_probe(struct platform_device *pdev)
@ -1624,15 +1651,6 @@ static int chv_pinctrl_probe(struct platform_device *pdev)
return 0;
}
static int chv_pinctrl_remove(struct platform_device *pdev)
{
struct chv_pinctrl *pctrl = platform_get_drvdata(pdev);
gpiochip_remove(&pctrl->chip);
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int chv_pinctrl_suspend(struct device *dev)
{
@ -1729,7 +1747,6 @@ MODULE_DEVICE_TABLE(acpi, chv_pinctrl_acpi_match);
static struct platform_driver chv_pinctrl_driver = {
.probe = chv_pinctrl_probe,
.remove = chv_pinctrl_remove,
.driver = {
.name = "cherryview-pinctrl",
.pm = &chv_pinctrl_pm_ops,

View File

@ -86,6 +86,7 @@ struct intel_pinctrl_context {
* @communities: All communities in this pin controller
* @ncommunities: Number of communities in this pin controller
* @context: Configuration saved over system sleep
* @irq: pinctrl/GPIO chip irq number
*/
struct intel_pinctrl {
struct device *dev;
@ -97,6 +98,7 @@ struct intel_pinctrl {
struct intel_community *communities;
size_t ncommunities;
struct intel_pinctrl_context context;
int irq;
};
#define pin_to_padno(c, p) ((p) - (c)->pin_base)
@ -793,38 +795,12 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
const struct intel_community *community;
unsigned pin = irqd_to_hwirq(d);
unsigned padno, gpp, gpp_offset;
unsigned long flags;
u32 gpe_en;
community = intel_get_community(pctrl, pin);
if (!community)
return -EINVAL;
raw_spin_lock_irqsave(&pctrl->lock, flags);
padno = pin_to_padno(community, pin);
gpp = padno / community->gpp_size;
gpp_offset = padno % community->gpp_size;
/* Clear the existing wake status */
writel(BIT(gpp_offset), community->regs + GPI_GPE_STS + gpp * 4);
/*
* The controller will generate wake when GPE of the corresponding
* pad is enabled and it is not routed to SCI (GPIROUTSCI is not
* set).
*/
gpe_en = readl(community->regs + GPI_GPE_EN + gpp * 4);
if (on)
gpe_en |= BIT(gpp_offset);
enable_irq_wake(pctrl->irq);
else
gpe_en &= ~BIT(gpp_offset);
writel(gpe_en, community->regs + GPI_GPE_EN + gpp * 4);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
disable_irq_wake(pctrl->irq);
dev_dbg(pctrl->dev, "%sable wake for pin %u\n", on ? "en" : "dis", pin);
return 0;
@ -905,6 +881,7 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
pctrl->chip.label = dev_name(pctrl->dev);
pctrl->chip.parent = pctrl->dev;
pctrl->chip.base = -1;
pctrl->irq = irq;
ret = gpiochip_add_data(&pctrl->chip, pctrl);
if (ret) {

View File

@ -854,7 +854,7 @@ static int mrfld_pinctrl_probe(struct platform_device *pdev)
*/
nfamilies = ARRAY_SIZE(mrfld_families),
families = devm_kmemdup(&pdev->dev, mrfld_families,
nfamilies * sizeof(mrfld_families),
sizeof(mrfld_families),
GFP_KERNEL);
if (!families)
return -ENOMEM;

View File

@ -15,7 +15,6 @@
#include <linux/io.h>
#include <linux/gpio/driver.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
@ -1055,7 +1054,7 @@ static int mtk_gpio_set_debounce(struct gpio_chip *chip, unsigned offset,
return 0;
}
static struct gpio_chip mtk_gpio_chip = {
static const struct gpio_chip mtk_gpio_chip = {
.owner = THIS_MODULE,
.request = gpiochip_generic_request,
.free = gpiochip_generic_free,
@ -1496,7 +1495,3 @@ chip_error:
gpiochip_remove(pctl->chip);
return ret;
}
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MediaTek Pinctrl Driver");
MODULE_AUTHOR("Hongzhou Yang <hongzhou.yang@mediatek.com>");

View File

@ -156,6 +156,11 @@ static const unsigned int emmc_clk_pins[] = { PIN(BOOT_8, EE_OFF) };
static const unsigned int emmc_cmd_pins[] = { PIN(BOOT_10, EE_OFF) };
static const unsigned int emmc_ds_pins[] = { PIN(BOOT_15, EE_OFF) };
static const unsigned int nor_d_pins[] = { PIN(BOOT_11, EE_OFF) };
static const unsigned int nor_q_pins[] = { PIN(BOOT_12, EE_OFF) };
static const unsigned int nor_c_pins[] = { PIN(BOOT_13, EE_OFF) };
static const unsigned int nor_cs_pins[] = { PIN(BOOT_15, EE_OFF) };
static const unsigned int sdcard_d0_pins[] = { PIN(CARD_1, EE_OFF) };
static const unsigned int sdcard_d1_pins[] = { PIN(CARD_0, EE_OFF) };
static const unsigned int sdcard_d2_pins[] = { PIN(CARD_5, EE_OFF) };
@ -163,6 +168,23 @@ static const unsigned int sdcard_d3_pins[] = { PIN(CARD_4, EE_OFF) };
static const unsigned int sdcard_cmd_pins[] = { PIN(CARD_3, EE_OFF) };
static const unsigned int sdcard_clk_pins[] = { PIN(CARD_2, EE_OFF) };
static const unsigned int sdio_d0_pins[] = { PIN(GPIOX_0, EE_OFF) };
static const unsigned int sdio_d1_pins[] = { PIN(GPIOX_1, EE_OFF) };
static const unsigned int sdio_d2_pins[] = { PIN(GPIOX_2, EE_OFF) };
static const unsigned int sdio_d3_pins[] = { PIN(GPIOX_3, EE_OFF) };
static const unsigned int sdio_cmd_pins[] = { PIN(GPIOX_4, EE_OFF) };
static const unsigned int sdio_clk_pins[] = { PIN(GPIOX_5, EE_OFF) };
static const unsigned int sdio_irq_pins[] = { PIN(GPIOX_7, EE_OFF) };
static const unsigned int nand_ce0_pins[] = { PIN(BOOT_8, EE_OFF) };
static const unsigned int nand_ce1_pins[] = { PIN(BOOT_9, EE_OFF) };
static const unsigned int nand_rb0_pins[] = { PIN(BOOT_10, EE_OFF) };
static const unsigned int nand_ale_pins[] = { PIN(BOOT_11, EE_OFF) };
static const unsigned int nand_cle_pins[] = { PIN(BOOT_12, EE_OFF) };
static const unsigned int nand_wen_clk_pins[] = { PIN(BOOT_13, EE_OFF) };
static const unsigned int nand_ren_wr_pins[] = { PIN(BOOT_14, EE_OFF) };
static const unsigned int nand_dqs_pins[] = { PIN(BOOT_15, EE_OFF) };
static const unsigned int uart_tx_a_pins[] = { PIN(GPIOX_12, EE_OFF) };
static const unsigned int uart_rx_a_pins[] = { PIN(GPIOX_13, EE_OFF) };
static const unsigned int uart_cts_a_pins[] = { PIN(GPIOX_14, EE_OFF) };
@ -178,6 +200,15 @@ static const unsigned int uart_rx_c_pins[] = { PIN(GPIOY_14, EE_OFF) };
static const unsigned int uart_cts_c_pins[] = { PIN(GPIOX_11, EE_OFF) };
static const unsigned int uart_rts_c_pins[] = { PIN(GPIOX_12, EE_OFF) };
static const unsigned int i2c_sck_a_pins[] = { PIN(GPIODV_25, EE_OFF) };
static const unsigned int i2c_sda_a_pins[] = { PIN(GPIODV_24, EE_OFF) };
static const unsigned int i2c_sck_b_pins[] = { PIN(GPIODV_27, EE_OFF) };
static const unsigned int i2c_sda_b_pins[] = { PIN(GPIODV_26, EE_OFF) };
static const unsigned int i2c_sck_c_pins[] = { PIN(GPIODV_29, EE_OFF) };
static const unsigned int i2c_sda_c_pins[] = { PIN(GPIODV_28, EE_OFF) };
static const unsigned int eth_mdio_pins[] = { PIN(GPIOZ_0, EE_OFF) };
static const unsigned int eth_mdc_pins[] = { PIN(GPIOZ_1, EE_OFF) };
static const unsigned int eth_clk_rx_clk_pins[] = { PIN(GPIOZ_2, EE_OFF) };
@ -193,6 +224,14 @@ static const unsigned int eth_txd1_pins[] = { PIN(GPIOZ_11, EE_OFF) };
static const unsigned int eth_txd2_pins[] = { PIN(GPIOZ_12, EE_OFF) };
static const unsigned int eth_txd3_pins[] = { PIN(GPIOZ_13, EE_OFF) };
static const unsigned int pwm_a_x_pins[] = { PIN(GPIOX_6, EE_OFF) };
static const unsigned int pwm_a_y_pins[] = { PIN(GPIOY_16, EE_OFF) };
static const unsigned int pwm_b_pins[] = { PIN(GPIODV_29, EE_OFF) };
static const unsigned int pwm_d_pins[] = { PIN(GPIODV_28, EE_OFF) };
static const unsigned int pwm_e_pins[] = { PIN(GPIOX_19, EE_OFF) };
static const unsigned int pwm_f_x_pins[] = { PIN(GPIOX_7, EE_OFF) };
static const unsigned int pwm_f_y_pins[] = { PIN(GPIOY_15, EE_OFF) };
static const struct pinctrl_pin_desc meson_gxbb_aobus_pins[] = {
MESON_PIN(GPIOAO_0, 0),
MESON_PIN(GPIOAO_1, 0),
@ -225,6 +264,13 @@ static const unsigned int i2c_sda_ao_pins[] = {PIN(GPIOAO_5, 0) };
static const unsigned int i2c_slave_sck_ao_pins[] = {PIN(GPIOAO_4, 0) };
static const unsigned int i2c_slave_sda_ao_pins[] = {PIN(GPIOAO_5, 0) };
static const unsigned int remote_input_ao_pins[] = {PIN(GPIOAO_7, 0) };
static const unsigned int pwm_ao_a_3_pins[] = { PIN(GPIOAO_3, 0) };
static const unsigned int pwm_ao_a_6_pins[] = { PIN(GPIOAO_6, 0) };
static const unsigned int pwm_ao_a_12_pins[] = { PIN(GPIOAO_12, 0) };
static const unsigned int pwm_ao_b_pins[] = { PIN(GPIOAO_13, 0) };
static struct meson_pmx_group meson_gxbb_periphs_groups[] = {
GPIO_GROUP(GPIOZ_0, EE_OFF),
GPIO_GROUP(GPIOZ_1, EE_OFF),
@ -355,16 +401,28 @@ static struct meson_pmx_group meson_gxbb_periphs_groups[] = {
GPIO_GROUP(GPIO_TEST_N, EE_OFF),
/* Bank X */
GROUP(sdio_d0, 8, 5),
GROUP(sdio_d1, 8, 4),
GROUP(sdio_d2, 8, 3),
GROUP(sdio_d3, 8, 2),
GROUP(sdio_cmd, 8, 1),
GROUP(sdio_clk, 8, 0),
GROUP(sdio_irq, 8, 11),
GROUP(uart_tx_a, 4, 13),
GROUP(uart_rx_a, 4, 12),
GROUP(uart_cts_a, 4, 11),
GROUP(uart_rts_a, 4, 10),
GROUP(pwm_a_x, 3, 17),
GROUP(pwm_e, 2, 30),
GROUP(pwm_f_x, 3, 18),
/* Bank Y */
GROUP(uart_cts_c, 1, 19),
GROUP(uart_rts_c, 1, 18),
GROUP(uart_tx_c, 1, 17),
GROUP(uart_rx_c, 1, 16),
GROUP(pwm_a_y, 1, 21),
GROUP(pwm_f_y, 1, 20),
/* Bank Z */
GROUP(eth_mdio, 6, 1),
@ -387,12 +445,32 @@ static struct meson_pmx_group meson_gxbb_periphs_groups[] = {
GROUP(uart_rx_b, 2, 28),
GROUP(uart_cts_b, 2, 27),
GROUP(uart_rts_b, 2, 26),
GROUP(pwm_b, 3, 21),
GROUP(pwm_d, 3, 20),
GROUP(i2c_sck_a, 7, 27),
GROUP(i2c_sda_a, 7, 26),
GROUP(i2c_sck_b, 7, 25),
GROUP(i2c_sda_b, 7, 24),
GROUP(i2c_sck_c, 7, 23),
GROUP(i2c_sda_c, 7, 22),
/* Bank BOOT */
GROUP(emmc_nand_d07, 4, 30),
GROUP(emmc_clk, 4, 18),
GROUP(emmc_cmd, 4, 19),
GROUP(emmc_ds, 4, 31),
GROUP(nor_d, 5, 1),
GROUP(nor_q, 5, 3),
GROUP(nor_c, 5, 2),
GROUP(nor_cs, 5, 0),
GROUP(nand_ce0, 4, 26),
GROUP(nand_ce1, 4, 27),
GROUP(nand_rb0, 4, 25),
GROUP(nand_ale, 4, 24),
GROUP(nand_cle, 4, 23),
GROUP(nand_wen_clk, 4, 22),
GROUP(nand_ren_wr, 4, 21),
GROUP(nand_dqs, 4, 20),
/* Bank CARD */
GROUP(sdcard_d1, 2, 14),
@ -432,6 +510,11 @@ static struct meson_pmx_group meson_gxbb_aobus_groups[] = {
GROUP(i2c_sda_ao, 0, 5),
GROUP(i2c_slave_sck_ao, 0, 2),
GROUP(i2c_slave_sda_ao, 0, 1),
GROUP(remote_input_ao, 0, 0),
GROUP(pwm_ao_a_3, 0, 22),
GROUP(pwm_ao_a_6, 0, 18),
GROUP(pwm_ao_a_12, 0, 17),
GROUP(pwm_ao_b, 0, 3),
};
static const char * const gpio_periphs_groups[] = {
@ -475,11 +558,25 @@ static const char * const emmc_groups[] = {
"emmc_nand_d07", "emmc_clk", "emmc_cmd", "emmc_ds",
};
static const char * const nor_groups[] = {
"nor_d", "nor_q", "nor_c", "nor_cs",
};
static const char * const sdcard_groups[] = {
"sdcard_d0", "sdcard_d1", "sdcard_d2", "sdcard_d3",
"sdcard_cmd", "sdcard_clk",
};
static const char * const sdio_groups[] = {
"sdio_d0", "sdio_d1", "sdio_d2", "sdio_d3",
"sdio_cmd", "sdio_clk", "sdio_irq",
};
static const char * const nand_groups[] = {
"nand_ce0", "nand_ce1", "nand_rb0", "nand_ale", "nand_cle",
"nand_wen_clk", "nand_ren_wr", "nand_dqs",
};
static const char * const uart_a_groups[] = {
"uart_tx_a", "uart_rx_a", "uart_cts_a", "uart_rts_a",
};
@ -492,6 +589,18 @@ static const char * const uart_c_groups[] = {
"uart_tx_c", "uart_rx_c", "uart_cts_c", "uart_rts_c",
};
static const char * const i2c_a_groups[] = {
"i2c_sck_a", "i2c_sda_a",
};
static const char * const i2c_b_groups[] = {
"i2c_sck_b", "i2c_sda_b",
};
static const char * const i2c_c_groups[] = {
"i2c_sck_c", "i2c_sda_c",
};
static const char * const eth_groups[] = {
"eth_mdio", "eth_mdc", "eth_clk_rx_clk", "eth_rx_dv",
"eth_rxd0", "eth_rxd1", "eth_rxd2", "eth_rxd3",
@ -499,6 +608,34 @@ static const char * const eth_groups[] = {
"eth_txd0", "eth_txd1", "eth_txd2", "eth_txd3",
};
static const char * const pwm_a_x_groups[] = {
"pwm_a_x",
};
static const char * const pwm_a_y_groups[] = {
"pwm_a_y",
};
static const char * const pwm_b_groups[] = {
"pwm_b",
};
static const char * const pwm_d_groups[] = {
"pwm_d",
};
static const char * const pwm_e_groups[] = {
"pwm_e",
};
static const char * const pwm_f_x_groups[] = {
"pwm_f_x",
};
static const char * const pwm_f_y_groups[] = {
"pwm_f_y",
};
static const char * const gpio_aobus_groups[] = {
"GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4",
"GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9",
@ -521,14 +658,47 @@ static const char * const i2c_slave_ao_groups[] = {
"i2c_slave_sdk_ao", "i2c_slave_sda_ao",
};
static const char * const remote_input_ao_groups[] = {
"remote_input_ao",
};
static const char * const pwm_ao_a_3_groups[] = {
"pwm_ao_a_3",
};
static const char * const pwm_ao_a_6_groups[] = {
"pwm_ao_a_6",
};
static const char * const pwm_ao_a_12_groups[] = {
"pwm_ao_a_12",
};
static const char * const pwm_ao_b_groups[] = {
"pwm_ao_b",
};
static struct meson_pmx_func meson_gxbb_periphs_functions[] = {
FUNCTION(gpio_periphs),
FUNCTION(emmc),
FUNCTION(nor),
FUNCTION(sdcard),
FUNCTION(sdio),
FUNCTION(nand),
FUNCTION(uart_a),
FUNCTION(uart_b),
FUNCTION(uart_c),
FUNCTION(i2c_a),
FUNCTION(i2c_b),
FUNCTION(i2c_c),
FUNCTION(eth),
FUNCTION(pwm_a_x),
FUNCTION(pwm_a_y),
FUNCTION(pwm_b),
FUNCTION(pwm_d),
FUNCTION(pwm_e),
FUNCTION(pwm_f_x),
FUNCTION(pwm_f_y),
};
static struct meson_pmx_func meson_gxbb_aobus_functions[] = {
@ -537,6 +707,11 @@ static struct meson_pmx_func meson_gxbb_aobus_functions[] = {
FUNCTION(uart_ao_b),
FUNCTION(i2c_ao),
FUNCTION(i2c_slave_ao),
FUNCTION(remote_input_ao),
FUNCTION(pwm_ao_a_3),
FUNCTION(pwm_ao_a_6),
FUNCTION(pwm_ao_a_12),
FUNCTION(pwm_ao_b),
};
static struct meson_bank meson_gxbb_periphs_banks[] = {
@ -556,38 +731,28 @@ static struct meson_bank meson_gxbb_aobus_banks[] = {
BANK("AO", PIN(GPIOAO_0, 0), PIN(GPIOAO_13, 0), 0, 0, 0, 16, 0, 0, 0, 16, 1, 0),
};
static struct meson_domain_data meson_gxbb_periphs_domain_data = {
.name = "periphs-banks",
.banks = meson_gxbb_periphs_banks,
.num_banks = ARRAY_SIZE(meson_gxbb_periphs_banks),
.pin_base = 14,
.num_pins = 120,
};
static struct meson_domain_data meson_gxbb_aobus_domain_data = {
.name = "aobus-banks",
.banks = meson_gxbb_aobus_banks,
.num_banks = ARRAY_SIZE(meson_gxbb_aobus_banks),
.pin_base = 0,
.num_pins = 14,
};
struct meson_pinctrl_data meson_gxbb_periphs_pinctrl_data = {
.name = "periphs-banks",
.pin_base = 14,
.pins = meson_gxbb_periphs_pins,
.groups = meson_gxbb_periphs_groups,
.funcs = meson_gxbb_periphs_functions,
.domain_data = &meson_gxbb_periphs_domain_data,
.banks = meson_gxbb_periphs_banks,
.num_pins = ARRAY_SIZE(meson_gxbb_periphs_pins),
.num_groups = ARRAY_SIZE(meson_gxbb_periphs_groups),
.num_funcs = ARRAY_SIZE(meson_gxbb_periphs_functions),
.num_banks = ARRAY_SIZE(meson_gxbb_periphs_banks),
};
struct meson_pinctrl_data meson_gxbb_aobus_pinctrl_data = {
.name = "aobus-banks",
.pin_base = 0,
.pins = meson_gxbb_aobus_pins,
.groups = meson_gxbb_aobus_groups,
.funcs = meson_gxbb_aobus_functions,
.domain_data = &meson_gxbb_aobus_domain_data,
.banks = meson_gxbb_aobus_banks,
.num_pins = ARRAY_SIZE(meson_gxbb_aobus_pins),
.num_groups = ARRAY_SIZE(meson_gxbb_aobus_groups),
.num_funcs = ARRAY_SIZE(meson_gxbb_aobus_functions),
.num_banks = ARRAY_SIZE(meson_gxbb_aobus_banks),
};

View File

@ -21,9 +21,8 @@
* domain which can't be powered off; the bank also uses a set of
* registers different from the other banks.
*
* For each of the two power domains (regular and always-on) there are
* 4 different register ranges that control the following properties
* of the pins:
* For each pin controller there are 4 different register ranges that
* control the following properties of the pins:
* 1) pin muxing
* 2) pull enable/disable
* 3) pull up/down
@ -33,8 +32,8 @@
* direction are the same and thus there are only 3 register ranges.
*
* Every pinmux group can be enabled by a specific bit in the first
* register range of the domain; when all groups for a given pin are
* disabled the pin acts as a GPIO.
* register range; when all groups for a given pin are disabled the
* pin acts as a GPIO.
*
* For the pull and GPIO configuration every bank uses a contiguous
* set of bits in the register sets described above; the same register
@ -66,21 +65,21 @@
/**
* meson_get_bank() - find the bank containing a given pin
*
* @domain: the domain containing the pin
* @pc: the pinctrl instance
* @pin: the pin number
* @bank: the found bank
*
* Return: 0 on success, a negative value on error
*/
static int meson_get_bank(struct meson_domain *domain, unsigned int pin,
static int meson_get_bank(struct meson_pinctrl *pc, unsigned int pin,
struct meson_bank **bank)
{
int i;
for (i = 0; i < domain->data->num_banks; i++) {
if (pin >= domain->data->banks[i].first &&
pin <= domain->data->banks[i].last) {
*bank = &domain->data->banks[i];
for (i = 0; i < pc->data->num_banks; i++) {
if (pin >= pc->data->banks[i].first &&
pin <= pc->data->banks[i].last) {
*bank = &pc->data->banks[i];
return 0;
}
}
@ -88,33 +87,6 @@ static int meson_get_bank(struct meson_domain *domain, unsigned int pin,
return -EINVAL;
}
/**
* meson_get_domain_and_bank() - find domain and bank containing a given pin
*
* @pc: Meson pin controller device
* @pin: the pin number
* @domain: the found domain
* @bank: the found bank
*
* Return: 0 on success, a negative value on error
*/
static int meson_get_domain_and_bank(struct meson_pinctrl *pc, unsigned int pin,
struct meson_domain **domain,
struct meson_bank **bank)
{
struct meson_domain *d;
d = pc->domain;
if (pin >= d->data->pin_base &&
pin < d->data->pin_base + d->data->num_pins) {
*domain = d;
return meson_get_bank(d, pin, bank);
}
return -EINVAL;
}
/**
* meson_calc_reg_and_bit() - calculate register and bit for a pin
*
@ -190,7 +162,6 @@ static void meson_pmx_disable_other_groups(struct meson_pinctrl *pc,
unsigned int pin, int sel_group)
{
struct meson_pmx_group *group;
struct meson_domain *domain;
int i, j;
for (i = 0; i < pc->data->num_groups; i++) {
@ -201,8 +172,7 @@ static void meson_pmx_disable_other_groups(struct meson_pinctrl *pc,
for (j = 0; j < group->num_pins; j++) {
if (group->pins[j] == pin) {
/* We have found a group using the pin */
domain = pc->domain;
regmap_update_bits(domain->reg_mux,
regmap_update_bits(pc->reg_mux,
group->reg * 4,
BIT(group->bit), 0);
}
@ -216,7 +186,6 @@ static int meson_pmx_set_mux(struct pinctrl_dev *pcdev, unsigned func_num,
struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
struct meson_pmx_func *func = &pc->data->funcs[func_num];
struct meson_pmx_group *group = &pc->data->groups[group_num];
struct meson_domain *domain = pc->domain;
int i, ret = 0;
dev_dbg(pc->dev, "enable function %s, group %s\n", func->name,
@ -231,7 +200,7 @@ static int meson_pmx_set_mux(struct pinctrl_dev *pcdev, unsigned func_num,
/* Function 0 (GPIO) doesn't need any additional setting */
if (func_num)
ret = regmap_update_bits(domain->reg_mux, group->reg * 4,
ret = regmap_update_bits(pc->reg_mux, group->reg * 4,
BIT(group->bit), BIT(group->bit));
return ret;
@ -287,14 +256,13 @@ static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
unsigned long *configs, unsigned num_configs)
{
struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
struct meson_domain *domain;
struct meson_bank *bank;
enum pin_config_param param;
unsigned int reg, bit;
int i, ret;
u16 arg;
ret = meson_get_domain_and_bank(pc, pin, &domain, &bank);
ret = meson_get_bank(pc, pin, &bank);
if (ret)
return ret;
@ -307,7 +275,7 @@ static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
dev_dbg(pc->dev, "pin %u: disable bias\n", pin);
meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
ret = regmap_update_bits(domain->reg_pull, reg,
ret = regmap_update_bits(pc->reg_pull, reg,
BIT(bit), 0);
if (ret)
return ret;
@ -317,13 +285,13 @@ static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
meson_calc_reg_and_bit(bank, pin, REG_PULLEN,
&reg, &bit);
ret = regmap_update_bits(domain->reg_pullen, reg,
ret = regmap_update_bits(pc->reg_pullen, reg,
BIT(bit), BIT(bit));
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
ret = regmap_update_bits(domain->reg_pull, reg,
ret = regmap_update_bits(pc->reg_pull, reg,
BIT(bit), BIT(bit));
if (ret)
return ret;
@ -333,13 +301,13 @@ static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
meson_calc_reg_and_bit(bank, pin, REG_PULLEN,
&reg, &bit);
ret = regmap_update_bits(domain->reg_pullen, reg,
ret = regmap_update_bits(pc->reg_pullen, reg,
BIT(bit), BIT(bit));
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
ret = regmap_update_bits(domain->reg_pull, reg,
ret = regmap_update_bits(pc->reg_pull, reg,
BIT(bit), 0);
if (ret)
return ret;
@ -354,18 +322,17 @@ static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
static int meson_pinconf_get_pull(struct meson_pinctrl *pc, unsigned int pin)
{
struct meson_domain *domain;
struct meson_bank *bank;
unsigned int reg, bit, val;
int ret, conf;
ret = meson_get_domain_and_bank(pc, pin, &domain, &bank);
ret = meson_get_bank(pc, pin, &bank);
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_PULLEN, &reg, &bit);
ret = regmap_read(domain->reg_pullen, reg, &val);
ret = regmap_read(pc->reg_pullen, reg, &val);
if (ret)
return ret;
@ -374,7 +341,7 @@ static int meson_pinconf_get_pull(struct meson_pinctrl *pc, unsigned int pin)
} else {
meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
ret = regmap_read(domain->reg_pull, reg, &val);
ret = regmap_read(pc->reg_pull, reg, &val);
if (ret)
return ret;
@ -452,82 +419,82 @@ static int meson_gpio_request(struct gpio_chip *chip, unsigned gpio)
static void meson_gpio_free(struct gpio_chip *chip, unsigned gpio)
{
struct meson_domain *domain = gpiochip_get_data(chip);
struct meson_pinctrl *pc = gpiochip_get_data(chip);
pinctrl_free_gpio(domain->data->pin_base + gpio);
pinctrl_free_gpio(pc->data->pin_base + gpio);
}
static int meson_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
{
struct meson_domain *domain = gpiochip_get_data(chip);
struct meson_pinctrl *pc = gpiochip_get_data(chip);
unsigned int reg, bit, pin;
struct meson_bank *bank;
int ret;
pin = domain->data->pin_base + gpio;
ret = meson_get_bank(domain, pin, &bank);
pin = pc->data->pin_base + gpio;
ret = meson_get_bank(pc, pin, &bank);
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_DIR, &reg, &bit);
return regmap_update_bits(domain->reg_gpio, reg, BIT(bit), BIT(bit));
return regmap_update_bits(pc->reg_gpio, reg, BIT(bit), BIT(bit));
}
static int meson_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
int value)
{
struct meson_domain *domain = gpiochip_get_data(chip);
struct meson_pinctrl *pc = gpiochip_get_data(chip);
unsigned int reg, bit, pin;
struct meson_bank *bank;
int ret;
pin = domain->data->pin_base + gpio;
ret = meson_get_bank(domain, pin, &bank);
pin = pc->data->pin_base + gpio;
ret = meson_get_bank(pc, pin, &bank);
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_DIR, &reg, &bit);
ret = regmap_update_bits(domain->reg_gpio, reg, BIT(bit), 0);
ret = regmap_update_bits(pc->reg_gpio, reg, BIT(bit), 0);
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_OUT, &reg, &bit);
return regmap_update_bits(domain->reg_gpio, reg, BIT(bit),
return regmap_update_bits(pc->reg_gpio, reg, BIT(bit),
value ? BIT(bit) : 0);
}
static void meson_gpio_set(struct gpio_chip *chip, unsigned gpio, int value)
{
struct meson_domain *domain = gpiochip_get_data(chip);
struct meson_pinctrl *pc = gpiochip_get_data(chip);
unsigned int reg, bit, pin;
struct meson_bank *bank;
int ret;
pin = domain->data->pin_base + gpio;
ret = meson_get_bank(domain, pin, &bank);
pin = pc->data->pin_base + gpio;
ret = meson_get_bank(pc, pin, &bank);
if (ret)
return;
meson_calc_reg_and_bit(bank, pin, REG_OUT, &reg, &bit);
regmap_update_bits(domain->reg_gpio, reg, BIT(bit),
regmap_update_bits(pc->reg_gpio, reg, BIT(bit),
value ? BIT(bit) : 0);
}
static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio)
{
struct meson_domain *domain = gpiochip_get_data(chip);
struct meson_pinctrl *pc = gpiochip_get_data(chip);
unsigned int reg, bit, val, pin;
struct meson_bank *bank;
int ret;
pin = domain->data->pin_base + gpio;
ret = meson_get_bank(domain, pin, &bank);
pin = pc->data->pin_base + gpio;
ret = meson_get_bank(pc, pin, &bank);
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_IN, &reg, &bit);
regmap_read(domain->reg_gpio, reg, &val);
regmap_read(pc->reg_gpio, reg, &val);
return !!(val & BIT(bit));
}
@ -562,35 +529,32 @@ static const struct of_device_id meson_pinctrl_dt_match[] = {
static int meson_gpiolib_register(struct meson_pinctrl *pc)
{
struct meson_domain *domain;
int ret;
domain = pc->domain;
pc->chip.label = pc->data->name;
pc->chip.parent = pc->dev;
pc->chip.request = meson_gpio_request;
pc->chip.free = meson_gpio_free;
pc->chip.direction_input = meson_gpio_direction_input;
pc->chip.direction_output = meson_gpio_direction_output;
pc->chip.get = meson_gpio_get;
pc->chip.set = meson_gpio_set;
pc->chip.base = pc->data->pin_base;
pc->chip.ngpio = pc->data->num_pins;
pc->chip.can_sleep = false;
pc->chip.of_node = pc->of_node;
pc->chip.of_gpio_n_cells = 2;
domain->chip.label = domain->data->name;
domain->chip.parent = pc->dev;
domain->chip.request = meson_gpio_request;
domain->chip.free = meson_gpio_free;
domain->chip.direction_input = meson_gpio_direction_input;
domain->chip.direction_output = meson_gpio_direction_output;
domain->chip.get = meson_gpio_get;
domain->chip.set = meson_gpio_set;
domain->chip.base = domain->data->pin_base;
domain->chip.ngpio = domain->data->num_pins;
domain->chip.can_sleep = false;
domain->chip.of_node = domain->of_node;
domain->chip.of_gpio_n_cells = 2;
ret = gpiochip_add_data(&domain->chip, domain);
ret = gpiochip_add_data(&pc->chip, pc);
if (ret) {
dev_err(pc->dev, "can't add gpio chip %s\n",
domain->data->name);
pc->data->name);
goto fail;
}
ret = gpiochip_add_pin_range(&domain->chip, dev_name(pc->dev),
0, domain->data->pin_base,
domain->chip.ngpio);
ret = gpiochip_add_pin_range(&pc->chip, dev_name(pc->dev),
0, pc->data->pin_base,
pc->chip.ngpio);
if (ret) {
dev_err(pc->dev, "can't add pin range\n");
goto fail;
@ -598,7 +562,7 @@ static int meson_gpiolib_register(struct meson_pinctrl *pc)
return 0;
fail:
gpiochip_remove(&pc->domain->chip);
gpiochip_remove(&pc->chip);
return ret;
}
@ -637,58 +601,46 @@ static struct regmap *meson_map_resource(struct meson_pinctrl *pc,
static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc,
struct device_node *node)
{
struct device_node *np;
struct meson_domain *domain;
int num_domains = 0;
struct device_node *np, *gpio_np = NULL;
for_each_child_of_node(node, np) {
if (!of_find_property(np, "gpio-controller", NULL))
continue;
num_domains++;
if (gpio_np) {
dev_err(pc->dev, "multiple gpio nodes\n");
return -EINVAL;
}
gpio_np = np;
}
if (num_domains != 1) {
dev_err(pc->dev, "wrong number of subnodes\n");
if (!gpio_np) {
dev_err(pc->dev, "no gpio node found\n");
return -EINVAL;
}
pc->domain = devm_kzalloc(pc->dev, sizeof(struct meson_domain), GFP_KERNEL);
if (!pc->domain)
return -ENOMEM;
pc->of_node = gpio_np;
domain = pc->domain;
domain->data = pc->data->domain_data;
pc->reg_mux = meson_map_resource(pc, gpio_np, "mux");
if (IS_ERR(pc->reg_mux)) {
dev_err(pc->dev, "mux registers not found\n");
return PTR_ERR(pc->reg_mux);
}
for_each_child_of_node(node, np) {
if (!of_find_property(np, "gpio-controller", NULL))
continue;
pc->reg_pull = meson_map_resource(pc, gpio_np, "pull");
if (IS_ERR(pc->reg_pull)) {
dev_err(pc->dev, "pull registers not found\n");
return PTR_ERR(pc->reg_pull);
}
domain->of_node = np;
pc->reg_pullen = meson_map_resource(pc, gpio_np, "pull-enable");
/* Use pull region if pull-enable one is not present */
if (IS_ERR(pc->reg_pullen))
pc->reg_pullen = pc->reg_pull;
domain->reg_mux = meson_map_resource(pc, np, "mux");
if (IS_ERR(domain->reg_mux)) {
dev_err(pc->dev, "mux registers not found\n");
return PTR_ERR(domain->reg_mux);
}
domain->reg_pull = meson_map_resource(pc, np, "pull");
if (IS_ERR(domain->reg_pull)) {
dev_err(pc->dev, "pull registers not found\n");
return PTR_ERR(domain->reg_pull);
}
domain->reg_pullen = meson_map_resource(pc, np, "pull-enable");
/* Use pull region if pull-enable one is not present */
if (IS_ERR(domain->reg_pullen))
domain->reg_pullen = domain->reg_pull;
domain->reg_gpio = meson_map_resource(pc, np, "gpio");
if (IS_ERR(domain->reg_gpio)) {
dev_err(pc->dev, "gpio registers not found\n");
return PTR_ERR(domain->reg_gpio);
}
break;
pc->reg_gpio = meson_map_resource(pc, gpio_np, "gpio");
if (IS_ERR(pc->reg_gpio)) {
dev_err(pc->dev, "gpio registers not found\n");
return PTR_ERR(pc->reg_gpio);
}
return 0;

View File

@ -95,54 +95,17 @@ struct meson_bank {
struct meson_reg_desc regs[NUM_REG];
};
/**
* struct meson_domain_data - domain platform data
*
* @name: name of the domain
* @banks: set of banks belonging to the domain
* @num_banks: number of banks in the domain
*/
struct meson_domain_data {
const char *name;
struct meson_bank *banks;
unsigned int num_banks;
unsigned int pin_base;
unsigned int num_pins;
};
/**
* struct meson_domain
*
* @reg_mux: registers for mux settings
* @reg_pullen: registers for pull-enable settings
* @reg_pull: registers for pull settings
* @reg_gpio: registers for gpio settings
* @chip: gpio chip associated with the domain
* @data; platform data for the domain
* @node: device tree node for the domain
*
* A domain represents a set of banks controlled by the same set of
* registers.
*/
struct meson_domain {
struct regmap *reg_mux;
struct regmap *reg_pullen;
struct regmap *reg_pull;
struct regmap *reg_gpio;
struct gpio_chip chip;
struct meson_domain_data *data;
struct device_node *of_node;
};
struct meson_pinctrl_data {
const char *name;
const struct pinctrl_pin_desc *pins;
struct meson_pmx_group *groups;
struct meson_pmx_func *funcs;
struct meson_domain_data *domain_data;
unsigned int pin_base;
unsigned int num_pins;
unsigned int num_groups;
unsigned int num_funcs;
struct meson_bank *banks;
unsigned int num_banks;
};
struct meson_pinctrl {
@ -150,7 +113,12 @@ struct meson_pinctrl {
struct pinctrl_dev *pcdev;
struct pinctrl_desc desc;
struct meson_pinctrl_data *data;
struct meson_domain *domain;
struct regmap *reg_mux;
struct regmap *reg_pullen;
struct regmap *reg_pull;
struct regmap *reg_gpio;
struct gpio_chip chip;
struct device_node *of_node;
};
#define PIN(x, b) (b + x)

View File

@ -931,38 +931,28 @@ static struct meson_bank meson8_aobus_banks[] = {
BANK("AO", PIN(GPIOAO_0, AO_OFF), PIN(GPIO_TEST_N, AO_OFF), 0, 0, 0, 16, 0, 0, 0, 16, 1, 0),
};
static struct meson_domain_data meson8_cbus_domain_data = {
.name = "cbus-banks",
.banks = meson8_cbus_banks,
.num_banks = ARRAY_SIZE(meson8_cbus_banks),
.pin_base = 0,
.num_pins = 120,
};
static struct meson_domain_data meson8_aobus_domain_data = {
.name = "ao-bank",
.banks = meson8_aobus_banks,
.num_banks = ARRAY_SIZE(meson8_aobus_banks),
.pin_base = 120,
.num_pins = 16,
};
struct meson_pinctrl_data meson8_cbus_pinctrl_data = {
.name = "cbus-banks",
.pin_base = 0,
.pins = meson8_cbus_pins,
.groups = meson8_cbus_groups,
.funcs = meson8_cbus_functions,
.domain_data = &meson8_cbus_domain_data,
.banks = meson8_cbus_banks,
.num_pins = ARRAY_SIZE(meson8_cbus_pins),
.num_groups = ARRAY_SIZE(meson8_cbus_groups),
.num_funcs = ARRAY_SIZE(meson8_cbus_functions),
.num_banks = ARRAY_SIZE(meson8_cbus_banks),
};
struct meson_pinctrl_data meson8_aobus_pinctrl_data = {
.name = "ao-bank",
.pin_base = 120,
.pins = meson8_aobus_pins,
.groups = meson8_aobus_groups,
.funcs = meson8_aobus_functions,
.domain_data = &meson8_aobus_domain_data,
.banks = meson8_aobus_banks,
.num_pins = ARRAY_SIZE(meson8_aobus_pins),
.num_groups = ARRAY_SIZE(meson8_aobus_groups),
.num_funcs = ARRAY_SIZE(meson8_aobus_functions),
.num_banks = ARRAY_SIZE(meson8_aobus_banks),
};

View File

@ -896,38 +896,28 @@ static struct meson_bank meson8b_aobus_banks[] = {
BANK("AO", PIN(GPIOAO_0, AO_OFF), PIN(GPIO_TEST_N, AO_OFF), 0, 0, 0, 16, 0, 0, 0, 16, 1, 0),
};
static struct meson_domain_data meson8b_cbus_domain_data = {
.name = "cbus-banks",
.banks = meson8b_cbus_banks,
.num_banks = ARRAY_SIZE(meson8b_cbus_banks),
.pin_base = 0,
.num_pins = 130,
};
static struct meson_domain_data meson8b_aobus_domain_data = {
.name = "aobus-banks",
.banks = meson8b_aobus_banks,
.num_banks = ARRAY_SIZE(meson8b_aobus_banks),
.pin_base = 130,
.num_pins = 16,
};
struct meson_pinctrl_data meson8b_cbus_pinctrl_data = {
.name = "cbus-banks",
.pin_base = 0,
.pins = meson8b_cbus_pins,
.groups = meson8b_cbus_groups,
.funcs = meson8b_cbus_functions,
.domain_data = &meson8b_cbus_domain_data,
.banks = meson8b_cbus_banks,
.num_pins = ARRAY_SIZE(meson8b_cbus_pins),
.num_groups = ARRAY_SIZE(meson8b_cbus_groups),
.num_funcs = ARRAY_SIZE(meson8b_cbus_functions),
.num_banks = ARRAY_SIZE(meson8b_cbus_banks),
};
struct meson_pinctrl_data meson8b_aobus_pinctrl_data = {
.name = "aobus-banks",
.pin_base = 130,
.pins = meson8b_aobus_pins,
.groups = meson8b_aobus_groups,
.funcs = meson8b_aobus_functions,
.domain_data = &meson8b_aobus_domain_data,
.banks = meson8b_aobus_banks,
.num_pins = ARRAY_SIZE(meson8b_aobus_pins),
.num_groups = ARRAY_SIZE(meson8b_aobus_groups),
.num_funcs = ARRAY_SIZE(meson8b_aobus_functions),
.num_banks = ARRAY_SIZE(meson8b_aobus_banks),
};

View File

@ -4,6 +4,8 @@
* Author: Patrice Chotard <patrice.chotard@st.com>
* License terms: GNU General Public License (GPL) version 2
*
* Driver allows to use AxB5xx unused pins to be used as GPIO
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
@ -12,7 +14,6 @@
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/of_device.h>
@ -1269,8 +1270,3 @@ static int __init abx500_gpio_init(void)
return platform_driver_register(&abx500_gpio_driver);
}
core_initcall(abx500_gpio_init);
MODULE_AUTHOR("Patrice Chotard <patrice.chotard@st.com>");
MODULE_DESCRIPTION("Driver allows to use AxB5xx unused pins to be used as GPIO");
MODULE_ALIAS("platform:abx500-gpio");
MODULE_LICENSE("GPL v2");

View File

@ -11,7 +11,6 @@
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/platform_device.h>
@ -1110,10 +1109,8 @@ static int nmk_gpio_probe(struct platform_device *dev)
return PTR_ERR(nmk_chip);
}
if (of_get_property(np, "st,supports-sleepmode", NULL))
supports_sleepmode = true;
else
supports_sleepmode = false;
supports_sleepmode =
of_property_read_bool(np, "st,supports-sleepmode");
/* Correct platform device ID */
dev->id = nmk_chip->bank;
@ -1180,7 +1177,7 @@ static int nmk_gpio_probe(struct platform_device *dev)
irqchip,
0,
handle_edge_irq,
IRQ_TYPE_EDGE_FALLING);
IRQ_TYPE_NONE);
if (ret) {
dev_err(&dev->dev, "could not add irqchip\n");
gpiochip_remove(&nmk_chip->chip);
@ -1985,7 +1982,3 @@ static int __init nmk_pinctrl_init(void)
return platform_driver_register(&nmk_pinctrl_driver);
}
core_initcall(nmk_pinctrl_init);
MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini");
MODULE_DESCRIPTION("Nomadik GPIO Driver");
MODULE_LICENSE("GPL");

View File

@ -383,12 +383,26 @@ static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type)
int ret = 0;
u32 pin_reg;
unsigned long flags;
bool level_trig;
u32 active_level;
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
/*
* When level_trig is set EDGE and active_level is set HIGH in BIOS
* default settings, ignore incoming settings from client and use
* BIOS settings to configure GPIO register.
*/
level_trig = !(pin_reg & (LEVEL_TRIGGER << LEVEL_TRIG_OFF));
active_level = pin_reg & (ACTIVE_LEVEL_MASK << ACTIVE_LEVEL_OFF);
if(level_trig &&
((active_level >> ACTIVE_LEVEL_OFF) == ACTIVE_HIGH))
type = IRQ_TYPE_EDGE_FALLING;
switch (type & IRQ_TYPE_SENSE_MASK) {
case IRQ_TYPE_EDGE_RISING:
pin_reg &= ~BIT(LEVEL_TRIG_OFF);

View File

@ -1614,7 +1614,7 @@ static int at91_gpio_of_irq_setup(struct platform_device *pdev,
&gpio_irqchip,
0,
handle_edge_irq,
IRQ_TYPE_EDGE_BOTH);
IRQ_TYPE_NONE);
if (ret) {
dev_err(&pdev->dev, "at91_gpio.%d: Couldn't add irqchip to gpiochip.\n",
at91_gpio->pioc_idx);

View File

@ -1004,9 +1004,7 @@ static int palmas_pinctrl_probe(struct platform_device *pdev)
bool enable_dvfs2 = false;
if (pdev->dev.of_node) {
const struct of_device_id *match;
match = of_match_device(palmas_pinctrl_of_match, &pdev->dev);
pinctrl_data = match->data;
pinctrl_data = of_device_get_match_data(&pdev->dev);
enable_dvfs1 = of_property_read_bool(pdev->dev.of_node,
"ti,palmas-enable-dvfs1");
enable_dvfs2 = of_property_read_bool(pdev->dev.of_node,

View File

@ -23,7 +23,7 @@
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/bitops.h>
@ -2704,7 +2704,6 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = {
.data = (void *)&rk3399_pin_ctrl },
{},
};
MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match);
static struct platform_driver rockchip_pinctrl_driver = {
.probe = rockchip_pinctrl_probe,
@ -2720,7 +2719,3 @@ static int __init rockchip_pinctrl_drv_register(void)
return platform_driver_register(&rockchip_pinctrl_driver);
}
postcore_initcall(rockchip_pinctrl_drv_register);
MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
MODULE_DESCRIPTION("Rockchip pinctrl driver");
MODULE_LICENSE("GPL v2");

View File

@ -335,61 +335,25 @@ struct st_pinctrl {
};
/* SOC specific data */
/* STiH415 data */
static const unsigned int stih415_input_delays[] = {0, 500, 1000, 1500};
static const unsigned int stih415_output_delays[] = {0, 1000, 2000, 3000};
#define STIH415_PCTRL_COMMON_DATA \
.rt_style = st_retime_style_packed, \
.input_delays = stih415_input_delays, \
.ninput_delays = ARRAY_SIZE(stih415_input_delays), \
.output_delays = stih415_output_delays, \
.noutput_delays = ARRAY_SIZE(stih415_output_delays)
static const struct st_pctl_data stih415_sbc_data = {
STIH415_PCTRL_COMMON_DATA,
.alt = 0, .oe = 5, .pu = 7, .od = 9, .rt = 16,
};
static const struct st_pctl_data stih415_front_data = {
STIH415_PCTRL_COMMON_DATA,
.alt = 0, .oe = 8, .pu = 10, .od = 12, .rt = 16,
};
static const struct st_pctl_data stih415_rear_data = {
STIH415_PCTRL_COMMON_DATA,
.alt = 0, .oe = 6, .pu = 8, .od = 10, .rt = 38,
};
static const struct st_pctl_data stih415_left_data = {
STIH415_PCTRL_COMMON_DATA,
.alt = 0, .oe = 3, .pu = 4, .od = 5, .rt = 6,
};
static const struct st_pctl_data stih415_right_data = {
STIH415_PCTRL_COMMON_DATA,
.alt = 0, .oe = 5, .pu = 7, .od = 9, .rt = 11,
};
/* STiH416 data */
static const unsigned int stih416_delays[] = {0, 300, 500, 750, 1000, 1250,
static const unsigned int stih407_delays[] = {0, 300, 500, 750, 1000, 1250,
1500, 1750, 2000, 2250, 2500, 2750, 3000, 3250 };
static const struct st_pctl_data stih416_data = {
.rt_style = st_retime_style_dedicated,
.input_delays = stih416_delays,
.ninput_delays = ARRAY_SIZE(stih416_delays),
.output_delays = stih416_delays,
.noutput_delays = ARRAY_SIZE(stih416_delays),
static const struct st_pctl_data stih407_data = {
.rt_style = st_retime_style_dedicated,
.input_delays = stih407_delays,
.ninput_delays = ARRAY_SIZE(stih407_delays),
.output_delays = stih407_delays,
.noutput_delays = ARRAY_SIZE(stih407_delays),
.alt = 0, .oe = 40, .pu = 50, .od = 60, .rt = 100,
};
static const struct st_pctl_data stih407_flashdata = {
.rt_style = st_retime_style_none,
.input_delays = stih416_delays,
.ninput_delays = ARRAY_SIZE(stih416_delays),
.output_delays = stih416_delays,
.noutput_delays = ARRAY_SIZE(stih416_delays),
.input_delays = stih407_delays,
.ninput_delays = ARRAY_SIZE(stih407_delays),
.output_delays = stih407_delays,
.noutput_delays = ARRAY_SIZE(stih407_delays),
.alt = 0,
.oe = -1, /* Not Available */
.pu = -1, /* Not Available */
@ -799,21 +763,6 @@ static int st_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
return (direction == ST_GPIO_DIRECTION_IN);
}
static int st_gpio_xlate(struct gpio_chip *gc,
const struct of_phandle_args *gpiospec, u32 *flags)
{
if (WARN_ON(gc->of_gpio_n_cells < 1))
return -EINVAL;
if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
return -EINVAL;
if (gpiospec->args[0] > gc->ngpio)
return -EINVAL;
return gpiospec->args[0];
}
/* Pinctrl Groups */
static int st_pctl_get_groups_count(struct pinctrl_dev *pctldev)
{
@ -1486,8 +1435,6 @@ static struct gpio_chip st_gpio_template = {
.direction_output = st_gpio_direction_output,
.get_direction = st_gpio_get_direction,
.ngpio = ST_GPIO_PINS_PER_BANK,
.of_gpio_n_cells = 1,
.of_xlate = st_gpio_xlate,
};
static struct irq_chip st_gpio_irqchip = {
@ -1579,21 +1526,9 @@ static int st_gpiolib_register_bank(struct st_pinctrl *info,
}
static const struct of_device_id st_pctl_of_match[] = {
{ .compatible = "st,stih415-sbc-pinctrl", .data = &stih415_sbc_data },
{ .compatible = "st,stih415-rear-pinctrl", .data = &stih415_rear_data },
{ .compatible = "st,stih415-left-pinctrl", .data = &stih415_left_data },
{ .compatible = "st,stih415-right-pinctrl",
.data = &stih415_right_data },
{ .compatible = "st,stih415-front-pinctrl",
.data = &stih415_front_data },
{ .compatible = "st,stih416-sbc-pinctrl", .data = &stih416_data},
{ .compatible = "st,stih416-front-pinctrl", .data = &stih416_data},
{ .compatible = "st,stih416-rear-pinctrl", .data = &stih416_data},
{ .compatible = "st,stih416-fvdp-fe-pinctrl", .data = &stih416_data},
{ .compatible = "st,stih416-fvdp-lite-pinctrl", .data = &stih416_data},
{ .compatible = "st,stih407-sbc-pinctrl", .data = &stih416_data},
{ .compatible = "st,stih407-front-pinctrl", .data = &stih416_data},
{ .compatible = "st,stih407-rear-pinctrl", .data = &stih416_data},
{ .compatible = "st,stih407-sbc-pinctrl", .data = &stih407_data},
{ .compatible = "st,stih407-front-pinctrl", .data = &stih407_data},
{ .compatible = "st,stih407-rear-pinctrl", .data = &stih407_data},
{ .compatible = "st,stih407-flash-pinctrl", .data = &stih407_flashdata},
{ /* sentinel */ }
};

View File

@ -233,7 +233,7 @@ static const unsigned int sdio0_2_pins[] = {40, 41, 42, 43, 44, 45};
static const unsigned int sdio1_0_pins[] = {10, 11, 12, 13, 14, 15};
static const unsigned int sdio1_1_pins[] = {22, 23, 24, 25, 26, 27};
static const unsigned int sdio1_2_pins[] = {34, 35, 36, 37, 38, 39};
static const unsigned int sdio1_3_pins[] = {46, 47, 48, 49, 40, 51};
static const unsigned int sdio1_3_pins[] = {46, 47, 48, 49, 50, 51};
static const unsigned int sdio0_emio_wp_pins[] = {54};
static const unsigned int sdio0_emio_cd_pins[] = {55};
static const unsigned int sdio1_emio_wp_pins[] = {56};

View File

@ -156,7 +156,7 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->ctl_reg);
val &= mask;
val &= ~mask;
val |= i << g->mux_bit;
writel(val, pctrl->regs + g->ctl_reg);

View File

@ -800,6 +800,7 @@ static const struct of_device_id pmic_gpio_of_match[] = {
{ .compatible = "qcom,pm8941-gpio" }, /* 36 GPIO's */
{ .compatible = "qcom,pm8994-gpio" }, /* 22 GPIO's */
{ .compatible = "qcom,pma8084-gpio" }, /* 22 GPIO's */
{ .compatible = "qcom,spmi-gpio" }, /* Generic */
{ },
};

View File

@ -914,6 +914,7 @@ static const struct of_device_id pmic_mpp_of_match[] = {
{ .compatible = "qcom,pm8941-mpp" }, /* 8 MPP's */
{ .compatible = "qcom,pm8994-mpp" }, /* 8 MPP's */
{ .compatible = "qcom,pma8084-mpp" }, /* 8 MPP's */
{ .compatible = "qcom,spmi-mpp" }, /* Generic */
{ },
};

View File

@ -428,14 +428,10 @@ static void exynos_irq_eint0_15(struct irq_desc *desc)
int eint_irq;
chained_irq_enter(chip, desc);
chip->irq_mask(&desc->irq_data);
if (chip->irq_ack)
chip->irq_ack(&desc->irq_data);
eint_irq = irq_linear_revmap(bank->irq_domain, eintd->irq);
generic_handle_irq(eint_irq);
chip->irq_unmask(&desc->irq_data);
chained_irq_exit(chip, desc);
}

View File

@ -1041,17 +1041,9 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
struct resource *res;
int ret;
if (!dev->of_node) {
dev_err(dev, "device tree node not found\n");
return -ENODEV;
}
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata) {
dev_err(dev, "failed to allocate memory for driver's "
"private data\n");
if (!drvdata)
return -ENOMEM;
}
ctrl = samsung_pinctrl_get_soc_data(drvdata, pdev);
if (IS_ERR(ctrl)) {

View File

@ -54,6 +54,11 @@ config PINCTRL_PFC_R8A7791
depends on ARCH_R8A7791
select PINCTRL_SH_PFC
config PINCTRL_PFC_R8A7792
def_bool y
depends on ARCH_R8A7792
select PINCTRL_SH_PFC
config PINCTRL_PFC_R8A7793
def_bool y
depends on ARCH_R8A7793
@ -69,6 +74,11 @@ config PINCTRL_PFC_R8A7795
depends on ARCH_R8A7795
select PINCTRL_SH_PFC
config PINCTRL_PFC_R8A7796
def_bool y
depends on ARCH_R8A7796
select PINCTRL_SH_PFC
config PINCTRL_PFC_SH7203
def_bool y
depends on CPU_SUBTYPE_SH7203

View File

@ -7,9 +7,11 @@ obj-$(CONFIG_PINCTRL_PFC_R8A7778) += pfc-r8a7778.o
obj-$(CONFIG_PINCTRL_PFC_R8A7779) += pfc-r8a7779.o
obj-$(CONFIG_PINCTRL_PFC_R8A7790) += pfc-r8a7790.o
obj-$(CONFIG_PINCTRL_PFC_R8A7791) += pfc-r8a7791.o
obj-$(CONFIG_PINCTRL_PFC_R8A7792) += pfc-r8a7792.o
obj-$(CONFIG_PINCTRL_PFC_R8A7793) += pfc-r8a7791.o
obj-$(CONFIG_PINCTRL_PFC_R8A7794) += pfc-r8a7794.o
obj-$(CONFIG_PINCTRL_PFC_R8A7795) += pfc-r8a7795.o
obj-$(CONFIG_PINCTRL_PFC_R8A7796) += pfc-r8a7796.o
obj-$(CONFIG_PINCTRL_PFC_SH7203) += pfc-sh7203.o
obj-$(CONFIG_PINCTRL_PFC_SH7264) += pfc-sh7264.o
obj-$(CONFIG_PINCTRL_PFC_SH7269) += pfc-sh7269.o

View File

@ -494,6 +494,12 @@ static const struct of_device_id sh_pfc_of_table[] = {
.data = &r8a7791_pinmux_info,
},
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A7792
{
.compatible = "renesas,pfc-r8a7792",
.data = &r8a7792_pinmux_info,
},
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A7793
{
.compatible = "renesas,pfc-r8a7793",
@ -512,6 +518,12 @@ static const struct of_device_id sh_pfc_of_table[] = {
.data = &r8a7795_pinmux_info,
},
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A7796
{
.compatible = "renesas,pfc-r8a7796",
.data = &r8a7796_pinmux_info,
},
#endif
#ifdef CONFIG_PINCTRL_PFC_SH73A0
{
.compatible = "renesas,pfc-sh73a0",

View File

@ -13,6 +13,10 @@
#include "sh_pfc.h"
/*
* Pins 0-23 assigned to GPIO bank 6 can be used for SD interfaces in
* which case they support both 3.3V and 1.8V signalling.
*/
#define CPU_ALL_PORT(fn, sfx) \
PORT_GP_32(0, fn, sfx), \
PORT_GP_26(1, fn, sfx), \
@ -20,7 +24,15 @@
PORT_GP_32(3, fn, sfx), \
PORT_GP_32(4, fn, sfx), \
PORT_GP_32(5, fn, sfx), \
PORT_GP_32(6, fn, sfx), \
PORT_GP_CFG_24(6, fn, sfx, SH_PFC_PIN_CFG_IO_VOLTAGE), \
PORT_GP_1(6, 24, fn, sfx), \
PORT_GP_1(6, 25, fn, sfx), \
PORT_GP_1(6, 26, fn, sfx), \
PORT_GP_1(6, 27, fn, sfx), \
PORT_GP_1(6, 28, fn, sfx), \
PORT_GP_1(6, 29, fn, sfx), \
PORT_GP_1(6, 30, fn, sfx), \
PORT_GP_1(6, 31, fn, sfx), \
PORT_GP_26(7, fn, sfx)
enum {
@ -6404,9 +6416,24 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
{ },
};
static int r8a7791_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl)
{
if (pin < RCAR_GP_PIN(6, 0) || pin > RCAR_GP_PIN(6, 23))
return -EINVAL;
*pocctrl = 0xe606008c;
return 31 - (pin & 0x1f);
}
static const struct sh_pfc_soc_operations r8a7791_pinmux_ops = {
.pin_to_pocctrl = r8a7791_pin_to_pocctrl,
};
#ifdef CONFIG_PINCTRL_PFC_R8A7791
const struct sh_pfc_soc_info r8a7791_pinmux_info = {
.name = "r8a77910_pfc",
.ops = &r8a7791_pinmux_ops,
.unlock_reg = 0xe6060000, /* PMMR */
.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,9 @@
PORT_GP_32(3, fn, sfx), \
PORT_GP_32(4, fn, sfx), \
PORT_GP_28(5, fn, sfx), \
PORT_GP_26(6, fn, sfx)
PORT_GP_CFG_24(6, fn, sfx, SH_PFC_PIN_CFG_IO_VOLTAGE), \
PORT_GP_1(6, 24, fn, sfx), \
PORT_GP_1(6, 25, fn, sfx)
enum {
PINMUX_RESERVED = 0,
@ -5160,8 +5162,32 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
{ },
};
static int r8a7794_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl)
{
*pocctrl = 0xe606006c;
switch (pin & 0x1f) {
case 6: return 23;
case 7: return 16;
case 14: return 15;
case 15: return 8;
case 0 ... 5:
case 8 ... 13:
return 22 - (pin & 0x1f);
case 16 ... 23:
return 47 - (pin & 0x1f);
}
return -EINVAL;
}
static const struct sh_pfc_soc_operations r8a7794_pinmux_ops = {
.pin_to_pocctrl = r8a7794_pin_to_pocctrl,
};
const struct sh_pfc_soc_info r8a7794_pinmux_info = {
.name = "r8a77940_pfc",
.ops = &r8a7794_pinmux_ops,
.unlock_reg = 0xe6060000, /* PMMR */
.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },

View File

@ -1,5 +1,5 @@
/*
* R-Car Gen3 processor support - PFC hardware block.
* R8A7795 processor support - PFC hardware block.
*
* Copyright (C) 2015 Renesas Electronics Corporation
*
@ -13,19 +13,23 @@
#include "core.h"
#include "sh_pfc.h"
#define CFG_FLAGS (SH_PFC_PIN_CFG_DRIVE_STRENGTH | \
SH_PFC_PIN_CFG_PULL_UP | \
SH_PFC_PIN_CFG_PULL_DOWN)
#define CPU_ALL_PORT(fn, sfx) \
PORT_GP_CFG_16(0, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_28(1, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_15(2, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_12(3, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH | SH_PFC_PIN_CFG_IO_VOLTAGE), \
PORT_GP_CFG_1(3, 12, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_1(3, 13, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_1(3, 14, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_1(3, 15, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_18(4, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH | SH_PFC_PIN_CFG_IO_VOLTAGE), \
PORT_GP_CFG_26(5, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_32(6, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
PORT_GP_CFG_4(7, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH)
PORT_GP_CFG_16(0, fn, sfx, CFG_FLAGS), \
PORT_GP_CFG_28(1, fn, sfx, CFG_FLAGS), \
PORT_GP_CFG_15(2, fn, sfx, CFG_FLAGS), \
PORT_GP_CFG_12(3, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE), \
PORT_GP_CFG_1(3, 12, fn, sfx, CFG_FLAGS), \
PORT_GP_CFG_1(3, 13, fn, sfx, CFG_FLAGS), \
PORT_GP_CFG_1(3, 14, fn, sfx, CFG_FLAGS), \
PORT_GP_CFG_1(3, 15, fn, sfx, CFG_FLAGS), \
PORT_GP_CFG_18(4, fn, sfx, CFG_FLAGS | SH_PFC_PIN_CFG_IO_VOLTAGE), \
PORT_GP_CFG_26(5, fn, sfx, CFG_FLAGS), \
PORT_GP_CFG_32(6, fn, sfx, CFG_FLAGS), \
PORT_GP_CFG_4(7, fn, sfx, CFG_FLAGS)
/*
* F_() : just information
* FM() : macro for FN_xxx / xxx_MARK
@ -1871,6 +1875,86 @@ static const unsigned int drif3_data1_b_mux[] = {
RIF3_D1_B_MARK,
};
/* - DU --------------------------------------------------------------------- */
static const unsigned int du_rgb666_pins[] = {
/* R[7:2], G[7:2], B[7:2] */
RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 14), RCAR_GP_PIN(0, 13),
RCAR_GP_PIN(0, 12), RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 10),
RCAR_GP_PIN(1, 15), RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 13),
RCAR_GP_PIN(1, 12), RCAR_GP_PIN(1, 19), RCAR_GP_PIN(1, 18),
RCAR_GP_PIN(1, 7), RCAR_GP_PIN(1, 6), RCAR_GP_PIN(1, 5),
RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 3), RCAR_GP_PIN(1, 2),
};
static const unsigned int du_rgb666_mux[] = {
DU_DR7_MARK, DU_DR6_MARK, DU_DR5_MARK, DU_DR4_MARK,
DU_DR3_MARK, DU_DR2_MARK,
DU_DG7_MARK, DU_DG6_MARK, DU_DG5_MARK, DU_DG4_MARK,
DU_DG3_MARK, DU_DG2_MARK,
DU_DB7_MARK, DU_DB6_MARK, DU_DB5_MARK, DU_DB4_MARK,
DU_DB3_MARK, DU_DB2_MARK,
};
static const unsigned int du_rgb888_pins[] = {
/* R[7:0], G[7:0], B[7:0] */
RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 14), RCAR_GP_PIN(0, 13),
RCAR_GP_PIN(0, 12), RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 10),
RCAR_GP_PIN(0, 9), RCAR_GP_PIN(0, 8),
RCAR_GP_PIN(1, 15), RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 13),
RCAR_GP_PIN(1, 12), RCAR_GP_PIN(1, 19), RCAR_GP_PIN(1, 18),
RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 16),
RCAR_GP_PIN(1, 7), RCAR_GP_PIN(1, 6), RCAR_GP_PIN(1, 5),
RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 3), RCAR_GP_PIN(1, 2),
RCAR_GP_PIN(1, 1), RCAR_GP_PIN(1, 0),
};
static const unsigned int du_rgb888_mux[] = {
DU_DR7_MARK, DU_DR6_MARK, DU_DR5_MARK, DU_DR4_MARK,
DU_DR3_MARK, DU_DR2_MARK, DU_DR1_MARK, DU_DR0_MARK,
DU_DG7_MARK, DU_DG6_MARK, DU_DG5_MARK, DU_DG4_MARK,
DU_DG3_MARK, DU_DG2_MARK, DU_DG1_MARK, DU_DG0_MARK,
DU_DB7_MARK, DU_DB6_MARK, DU_DB5_MARK, DU_DB4_MARK,
DU_DB3_MARK, DU_DB2_MARK, DU_DB1_MARK, DU_DB0_MARK,
};
static const unsigned int du_clk_out_0_pins[] = {
/* CLKOUT */
RCAR_GP_PIN(1, 27),
};
static const unsigned int du_clk_out_0_mux[] = {
DU_DOTCLKOUT0_MARK
};
static const unsigned int du_clk_out_1_pins[] = {
/* CLKOUT */
RCAR_GP_PIN(2, 3),
};
static const unsigned int du_clk_out_1_mux[] = {
DU_DOTCLKOUT1_MARK
};
static const unsigned int du_sync_pins[] = {
/* EXVSYNC/VSYNC, EXHSYNC/HSYNC */
RCAR_GP_PIN(2, 5), RCAR_GP_PIN(2, 4),
};
static const unsigned int du_sync_mux[] = {
DU_EXVSYNC_DU_VSYNC_MARK, DU_EXHSYNC_DU_HSYNC_MARK
};
static const unsigned int du_oddf_pins[] = {
/* EXDISP/EXODDF/EXCDE */
RCAR_GP_PIN(2, 2),
};
static const unsigned int du_oddf_mux[] = {
DU_EXODDF_DU_ODDF_DISP_CDE_MARK,
};
static const unsigned int du_cde_pins[] = {
/* CDE */
RCAR_GP_PIN(2, 0),
};
static const unsigned int du_cde_mux[] = {
DU_CDE_MARK,
};
static const unsigned int du_disp_pins[] = {
/* DISP */
RCAR_GP_PIN(2, 1),
};
static const unsigned int du_disp_mux[] = {
DU_DISP_MARK,
};
/* - HSCIF0 ----------------------------------------------------------------- */
static const unsigned int hscif0_data_pins[] = {
/* RX, TX */
@ -3593,6 +3677,14 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(drif3_ctrl_b),
SH_PFC_PIN_GROUP(drif3_data0_b),
SH_PFC_PIN_GROUP(drif3_data1_b),
SH_PFC_PIN_GROUP(du_rgb666),
SH_PFC_PIN_GROUP(du_rgb888),
SH_PFC_PIN_GROUP(du_clk_out_0),
SH_PFC_PIN_GROUP(du_clk_out_1),
SH_PFC_PIN_GROUP(du_sync),
SH_PFC_PIN_GROUP(du_oddf),
SH_PFC_PIN_GROUP(du_cde),
SH_PFC_PIN_GROUP(du_disp),
SH_PFC_PIN_GROUP(hscif0_data),
SH_PFC_PIN_GROUP(hscif0_clk),
SH_PFC_PIN_GROUP(hscif0_ctrl),
@ -3918,6 +4010,17 @@ static const char * const drif3_groups[] = {
"drif3_data1_b",
};
static const char * const du_groups[] = {
"du_rgb666",
"du_rgb888",
"du_clk_out_0",
"du_clk_out_1",
"du_sync",
"du_oddf",
"du_cde",
"du_disp",
};
static const char * const hscif0_groups[] = {
"hscif0_data",
"hscif0_clk",
@ -4265,6 +4368,7 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(drif1),
SH_PFC_FUNCTION(drif2),
SH_PFC_FUNCTION(drif3),
SH_PFC_FUNCTION(du),
SH_PFC_FUNCTION(hscif0),
SH_PFC_FUNCTION(hscif1),
SH_PFC_FUNCTION(hscif2),
@ -5073,8 +5177,234 @@ static int r8a7795_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin, u32 *poc
return bit;
}
#define PUEN 0xe6060400
#define PUD 0xe6060440
#define PU0 0x00
#define PU1 0x04
#define PU2 0x08
#define PU3 0x0c
#define PU4 0x10
#define PU5 0x14
#define PU6 0x18
static const struct {
u16 reg : 11;
u16 bit : 5;
} pullups[] = {
[RCAR_GP_PIN(2, 11)] = { PU0, 31 }, /* AVB_PHY_INT */
[RCAR_GP_PIN(2, 10)] = { PU0, 30 }, /* AVB_MAGIC */
[RCAR_GP_PIN(2, 9)] = { PU0, 29 }, /* AVB_MDC */
[RCAR_GP_PIN(1, 19)] = { PU1, 31 }, /* A19 */
[RCAR_GP_PIN(1, 18)] = { PU1, 30 }, /* A18 */
[RCAR_GP_PIN(1, 17)] = { PU1, 29 }, /* A17 */
[RCAR_GP_PIN(1, 16)] = { PU1, 28 }, /* A16 */
[RCAR_GP_PIN(1, 15)] = { PU1, 27 }, /* A15 */
[RCAR_GP_PIN(1, 14)] = { PU1, 26 }, /* A14 */
[RCAR_GP_PIN(1, 13)] = { PU1, 25 }, /* A13 */
[RCAR_GP_PIN(1, 12)] = { PU1, 24 }, /* A12 */
[RCAR_GP_PIN(1, 11)] = { PU1, 23 }, /* A11 */
[RCAR_GP_PIN(1, 10)] = { PU1, 22 }, /* A10 */
[RCAR_GP_PIN(1, 9)] = { PU1, 21 }, /* A9 */
[RCAR_GP_PIN(1, 8)] = { PU1, 20 }, /* A8 */
[RCAR_GP_PIN(1, 7)] = { PU1, 19 }, /* A7 */
[RCAR_GP_PIN(1, 6)] = { PU1, 18 }, /* A6 */
[RCAR_GP_PIN(1, 5)] = { PU1, 17 }, /* A5 */
[RCAR_GP_PIN(1, 4)] = { PU1, 16 }, /* A4 */
[RCAR_GP_PIN(1, 3)] = { PU1, 15 }, /* A3 */
[RCAR_GP_PIN(1, 2)] = { PU1, 14 }, /* A2 */
[RCAR_GP_PIN(1, 1)] = { PU1, 13 }, /* A1 */
[RCAR_GP_PIN(1, 0)] = { PU1, 12 }, /* A0 */
[RCAR_GP_PIN(2, 8)] = { PU1, 11 }, /* PWM2_A */
[RCAR_GP_PIN(2, 7)] = { PU1, 10 }, /* PWM1_A */
[RCAR_GP_PIN(2, 6)] = { PU1, 9 }, /* PWM0 */
[RCAR_GP_PIN(2, 5)] = { PU1, 8 }, /* IRQ5 */
[RCAR_GP_PIN(2, 4)] = { PU1, 7 }, /* IRQ4 */
[RCAR_GP_PIN(2, 3)] = { PU1, 6 }, /* IRQ3 */
[RCAR_GP_PIN(2, 2)] = { PU1, 5 }, /* IRQ2 */
[RCAR_GP_PIN(2, 1)] = { PU1, 4 }, /* IRQ1 */
[RCAR_GP_PIN(2, 0)] = { PU1, 3 }, /* IRQ0 */
[RCAR_GP_PIN(2, 14)] = { PU1, 2 }, /* AVB_AVTP_CAPTURE_A */
[RCAR_GP_PIN(2, 13)] = { PU1, 1 }, /* AVB_AVTP_MATCH_A */
[RCAR_GP_PIN(2, 12)] = { PU1, 0 }, /* AVB_LINK */
[RCAR_GP_PIN(7, 3)] = { PU2, 29 }, /* HDMI1_CEC */
[RCAR_GP_PIN(7, 2)] = { PU2, 28 }, /* HDMI0_CEC */
[RCAR_GP_PIN(7, 1)] = { PU2, 27 }, /* AVS2 */
[RCAR_GP_PIN(7, 0)] = { PU2, 26 }, /* AVS1 */
[RCAR_GP_PIN(0, 15)] = { PU2, 25 }, /* D15 */
[RCAR_GP_PIN(0, 14)] = { PU2, 24 }, /* D14 */
[RCAR_GP_PIN(0, 13)] = { PU2, 23 }, /* D13 */
[RCAR_GP_PIN(0, 12)] = { PU2, 22 }, /* D12 */
[RCAR_GP_PIN(0, 11)] = { PU2, 21 }, /* D11 */
[RCAR_GP_PIN(0, 10)] = { PU2, 20 }, /* D10 */
[RCAR_GP_PIN(0, 9)] = { PU2, 19 }, /* D9 */
[RCAR_GP_PIN(0, 8)] = { PU2, 18 }, /* D8 */
[RCAR_GP_PIN(0, 7)] = { PU2, 17 }, /* D7 */
[RCAR_GP_PIN(0, 6)] = { PU2, 16 }, /* D6 */
[RCAR_GP_PIN(0, 5)] = { PU2, 15 }, /* D5 */
[RCAR_GP_PIN(0, 4)] = { PU2, 14 }, /* D4 */
[RCAR_GP_PIN(0, 3)] = { PU2, 13 }, /* D3 */
[RCAR_GP_PIN(0, 2)] = { PU2, 12 }, /* D2 */
[RCAR_GP_PIN(0, 1)] = { PU2, 11 }, /* D1 */
[RCAR_GP_PIN(0, 0)] = { PU2, 10 }, /* D0 */
[RCAR_GP_PIN(1, 27)] = { PU2, 8 }, /* EX_WAIT0_A */
[RCAR_GP_PIN(1, 26)] = { PU2, 7 }, /* WE1_N */
[RCAR_GP_PIN(1, 25)] = { PU2, 6 }, /* WE0_N */
[RCAR_GP_PIN(1, 24)] = { PU2, 5 }, /* RD_WR_N */
[RCAR_GP_PIN(1, 23)] = { PU2, 4 }, /* RD_N */
[RCAR_GP_PIN(1, 22)] = { PU2, 3 }, /* BS_N */
[RCAR_GP_PIN(1, 21)] = { PU2, 2 }, /* CS1_N_A26 */
[RCAR_GP_PIN(1, 20)] = { PU2, 1 }, /* CS0_N */
[RCAR_GP_PIN(4, 9)] = { PU3, 31 }, /* SD3_DAT0 */
[RCAR_GP_PIN(4, 8)] = { PU3, 30 }, /* SD3_CMD */
[RCAR_GP_PIN(4, 7)] = { PU3, 29 }, /* SD3_CLK */
[RCAR_GP_PIN(4, 6)] = { PU3, 28 }, /* SD2_DS */
[RCAR_GP_PIN(4, 5)] = { PU3, 27 }, /* SD2_DAT3 */
[RCAR_GP_PIN(4, 4)] = { PU3, 26 }, /* SD2_DAT2 */
[RCAR_GP_PIN(4, 3)] = { PU3, 25 }, /* SD2_DAT1 */
[RCAR_GP_PIN(4, 2)] = { PU3, 24 }, /* SD2_DAT0 */
[RCAR_GP_PIN(4, 1)] = { PU3, 23 }, /* SD2_CMD */
[RCAR_GP_PIN(4, 0)] = { PU3, 22 }, /* SD2_CLK */
[RCAR_GP_PIN(3, 11)] = { PU3, 21 }, /* SD1_DAT3 */
[RCAR_GP_PIN(3, 10)] = { PU3, 20 }, /* SD1_DAT2 */
[RCAR_GP_PIN(3, 9)] = { PU3, 19 }, /* SD1_DAT1 */
[RCAR_GP_PIN(3, 8)] = { PU3, 18 }, /* SD1_DAT0 */
[RCAR_GP_PIN(3, 7)] = { PU3, 17 }, /* SD1_CMD */
[RCAR_GP_PIN(3, 6)] = { PU3, 16 }, /* SD1_CLK */
[RCAR_GP_PIN(3, 5)] = { PU3, 15 }, /* SD0_DAT3 */
[RCAR_GP_PIN(3, 4)] = { PU3, 14 }, /* SD0_DAT2 */
[RCAR_GP_PIN(3, 3)] = { PU3, 13 }, /* SD0_DAT1 */
[RCAR_GP_PIN(3, 2)] = { PU3, 12 }, /* SD0_DAT0 */
[RCAR_GP_PIN(3, 1)] = { PU3, 11 }, /* SD0_CMD */
[RCAR_GP_PIN(3, 0)] = { PU3, 10 }, /* SD0_CLK */
[RCAR_GP_PIN(5, 19)] = { PU4, 31 }, /* MSIOF0_SS1 */
[RCAR_GP_PIN(5, 18)] = { PU4, 30 }, /* MSIOF0_SYNC */
[RCAR_GP_PIN(5, 17)] = { PU4, 29 }, /* MSIOF0_SCK */
[RCAR_GP_PIN(5, 16)] = { PU4, 28 }, /* HRTS0_N */
[RCAR_GP_PIN(5, 15)] = { PU4, 27 }, /* HCTS0_N */
[RCAR_GP_PIN(5, 14)] = { PU4, 26 }, /* HTX0 */
[RCAR_GP_PIN(5, 13)] = { PU4, 25 }, /* HRX0 */
[RCAR_GP_PIN(5, 12)] = { PU4, 24 }, /* HSCK0 */
[RCAR_GP_PIN(5, 11)] = { PU4, 23 }, /* RX2_A */
[RCAR_GP_PIN(5, 10)] = { PU4, 22 }, /* TX2_A */
[RCAR_GP_PIN(5, 9)] = { PU4, 21 }, /* SCK2 */
[RCAR_GP_PIN(5, 8)] = { PU4, 20 }, /* RTS1_N_TANS */
[RCAR_GP_PIN(5, 7)] = { PU4, 19 }, /* CTS1_N */
[RCAR_GP_PIN(5, 6)] = { PU4, 18 }, /* TX1_A */
[RCAR_GP_PIN(5, 5)] = { PU4, 17 }, /* RX1_A */
[RCAR_GP_PIN(5, 4)] = { PU4, 16 }, /* RTS0_N_TANS */
[RCAR_GP_PIN(5, 3)] = { PU4, 15 }, /* CTS0_N */
[RCAR_GP_PIN(5, 2)] = { PU4, 14 }, /* TX0 */
[RCAR_GP_PIN(5, 1)] = { PU4, 13 }, /* RX0 */
[RCAR_GP_PIN(5, 0)] = { PU4, 12 }, /* SCK0 */
[RCAR_GP_PIN(3, 15)] = { PU4, 11 }, /* SD1_WP */
[RCAR_GP_PIN(3, 14)] = { PU4, 10 }, /* SD1_CD */
[RCAR_GP_PIN(3, 13)] = { PU4, 9 }, /* SD0_WP */
[RCAR_GP_PIN(3, 12)] = { PU4, 8 }, /* SD0_CD */
[RCAR_GP_PIN(4, 17)] = { PU4, 7 }, /* SD3_DS */
[RCAR_GP_PIN(4, 16)] = { PU4, 6 }, /* SD3_DAT7 */
[RCAR_GP_PIN(4, 15)] = { PU4, 5 }, /* SD3_DAT6 */
[RCAR_GP_PIN(4, 14)] = { PU4, 4 }, /* SD3_DAT5 */
[RCAR_GP_PIN(4, 13)] = { PU4, 3 }, /* SD3_DAT4 */
[RCAR_GP_PIN(4, 12)] = { PU4, 2 }, /* SD3_DAT3 */
[RCAR_GP_PIN(4, 11)] = { PU4, 1 }, /* SD3_DAT2 */
[RCAR_GP_PIN(4, 10)] = { PU4, 0 }, /* SD3_DAT1 */
[RCAR_GP_PIN(6, 24)] = { PU5, 31 }, /* USB0_PWEN */
[RCAR_GP_PIN(6, 23)] = { PU5, 30 }, /* AUDIO_CLKB_B */
[RCAR_GP_PIN(6, 22)] = { PU5, 29 }, /* AUDIO_CLKA_A */
[RCAR_GP_PIN(6, 21)] = { PU5, 28 }, /* SSI_SDATA9_A */
[RCAR_GP_PIN(6, 20)] = { PU5, 27 }, /* SSI_SDATA8 */
[RCAR_GP_PIN(6, 19)] = { PU5, 26 }, /* SSI_SDATA7 */
[RCAR_GP_PIN(6, 18)] = { PU5, 25 }, /* SSI_WS78 */
[RCAR_GP_PIN(6, 17)] = { PU5, 24 }, /* SSI_SCK78 */
[RCAR_GP_PIN(6, 16)] = { PU5, 23 }, /* SSI_SDATA6 */
[RCAR_GP_PIN(6, 15)] = { PU5, 22 }, /* SSI_WS6 */
[RCAR_GP_PIN(6, 14)] = { PU5, 21 }, /* SSI_SCK6 */
[RCAR_GP_PIN(6, 13)] = { PU5, 20 }, /* SSI_SDATA5 */
[RCAR_GP_PIN(6, 12)] = { PU5, 19 }, /* SSI_WS5 */
[RCAR_GP_PIN(6, 11)] = { PU5, 18 }, /* SSI_SCK5 */
[RCAR_GP_PIN(6, 10)] = { PU5, 17 }, /* SSI_SDATA4 */
[RCAR_GP_PIN(6, 9)] = { PU5, 16 }, /* SSI_WS4 */
[RCAR_GP_PIN(6, 8)] = { PU5, 15 }, /* SSI_SCK4 */
[RCAR_GP_PIN(6, 7)] = { PU5, 14 }, /* SSI_SDATA3 */
[RCAR_GP_PIN(6, 6)] = { PU5, 13 }, /* SSI_WS34 */
[RCAR_GP_PIN(6, 5)] = { PU5, 12 }, /* SSI_SCK34 */
[RCAR_GP_PIN(6, 4)] = { PU5, 11 }, /* SSI_SDATA2_A */
[RCAR_GP_PIN(6, 3)] = { PU5, 10 }, /* SSI_SDATA1_A */
[RCAR_GP_PIN(6, 2)] = { PU5, 9 }, /* SSI_SDATA0 */
[RCAR_GP_PIN(6, 1)] = { PU5, 8 }, /* SSI_WS01239 */
[RCAR_GP_PIN(6, 0)] = { PU5, 7 }, /* SSI_SCK01239 */
[RCAR_GP_PIN(5, 25)] = { PU5, 5 }, /* MLB_DAT */
[RCAR_GP_PIN(5, 24)] = { PU5, 4 }, /* MLB_SIG */
[RCAR_GP_PIN(5, 23)] = { PU5, 3 }, /* MLB_CLK */
[RCAR_GP_PIN(5, 22)] = { PU5, 2 }, /* MSIOF0_RXD */
[RCAR_GP_PIN(5, 21)] = { PU5, 1 }, /* MSIOF0_SS2 */
[RCAR_GP_PIN(5, 20)] = { PU5, 0 }, /* MSIOF0_TXD */
[RCAR_GP_PIN(6, 31)] = { PU6, 6 }, /* USB31_OVC */
[RCAR_GP_PIN(6, 30)] = { PU6, 5 }, /* USB31_PWEN */
[RCAR_GP_PIN(6, 29)] = { PU6, 4 }, /* USB30_OVC */
[RCAR_GP_PIN(6, 28)] = { PU6, 3 }, /* USB30_PWEN */
[RCAR_GP_PIN(6, 27)] = { PU6, 2 }, /* USB1_OVC */
[RCAR_GP_PIN(6, 26)] = { PU6, 1 }, /* USB1_PWEN */
[RCAR_GP_PIN(6, 25)] = { PU6, 0 }, /* USB0_OVC */
};
static unsigned int r8a7795_pinmux_get_bias(struct sh_pfc *pfc,
unsigned int pin)
{
u32 reg;
u32 bit;
if (WARN_ON_ONCE(!pullups[pin].reg))
return PIN_CONFIG_BIAS_DISABLE;
reg = pullups[pin].reg;
bit = BIT(pullups[pin].bit);
if (sh_pfc_read_reg(pfc, PUEN + reg, 32) & bit) {
if (sh_pfc_read_reg(pfc, PUD + reg, 32) & bit)
return PIN_CONFIG_BIAS_PULL_UP;
else
return PIN_CONFIG_BIAS_PULL_DOWN;
} else
return PIN_CONFIG_BIAS_DISABLE;
}
static void r8a7795_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,
unsigned int bias)
{
u32 enable, updown;
u32 reg;
u32 bit;
if (WARN_ON_ONCE(!pullups[pin].reg))
return;
reg = pullups[pin].reg;
bit = BIT(pullups[pin].bit);
enable = sh_pfc_read_reg(pfc, PUEN + reg, 32) & ~bit;
if (bias != PIN_CONFIG_BIAS_DISABLE)
enable |= bit;
updown = sh_pfc_read_reg(pfc, PUD + reg, 32) & ~bit;
if (bias == PIN_CONFIG_BIAS_PULL_UP)
updown |= bit;
sh_pfc_write_reg(pfc, PUD + reg, 32, updown);
sh_pfc_write_reg(pfc, PUEN + reg, 32, enable);
}
static const struct sh_pfc_soc_operations r8a7795_pinmux_ops = {
.pin_to_pocctrl = r8a7795_pin_to_pocctrl,
.get_bias = r8a7795_pinmux_get_bias,
.set_bias = r8a7795_pinmux_set_bias,
};
const struct sh_pfc_soc_info r8a7795_pinmux_info = {

File diff suppressed because it is too large Load Diff

View File

@ -596,6 +596,7 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin,
struct sh_pfc *pfc = pmx->pfc;
enum pin_config_param param = pinconf_to_config_param(*config);
unsigned long flags;
unsigned int arg;
if (!sh_pfc_pinconf_validate(pfc, _pin, param))
return -ENOTSUPP;
@ -616,7 +617,7 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin,
if (bias != param)
return -EINVAL;
*config = 0;
arg = 0;
break;
}
@ -627,7 +628,7 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin,
if (ret < 0)
return ret;
*config = ret;
arg = ret;
break;
}
@ -646,7 +647,7 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin,
val = sh_pfc_read_reg(pfc, pocctrl, 32);
spin_unlock_irqrestore(&pfc->lock, flags);
*config = (val & BIT(bit)) ? 3300 : 1800;
arg = (val & BIT(bit)) ? 3300 : 1800;
break;
}
@ -654,6 +655,7 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin,
return -ENOTSUPP;
}
*config = pinconf_to_config_packed(param, arg);
return 0;
}

View File

@ -257,9 +257,11 @@ extern const struct sh_pfc_soc_info r8a7778_pinmux_info;
extern const struct sh_pfc_soc_info r8a7779_pinmux_info;
extern const struct sh_pfc_soc_info r8a7790_pinmux_info;
extern const struct sh_pfc_soc_info r8a7791_pinmux_info;
extern const struct sh_pfc_soc_info r8a7792_pinmux_info;
extern const struct sh_pfc_soc_info r8a7793_pinmux_info;
extern const struct sh_pfc_soc_info r8a7794_pinmux_info;
extern const struct sh_pfc_soc_info r8a7795_pinmux_info;
extern const struct sh_pfc_soc_info r8a7796_pinmux_info;
extern const struct sh_pfc_soc_info sh7203_pinmux_info;
extern const struct sh_pfc_soc_info sh7264_pinmux_info;
extern const struct sh_pfc_soc_info sh7269_pinmux_info;
@ -354,72 +356,103 @@ extern const struct sh_pfc_soc_info shx3_pinmux_info;
* GP port style (32 ports banks)
*/
#define PORT_GP_CFG_1(bank, pin, fn, sfx, cfg) fn(bank, pin, GP_##bank##_##pin, sfx, cfg)
#define PORT_GP_CFG_1(bank, pin, fn, sfx, cfg) \
fn(bank, pin, GP_##bank##_##pin, sfx, cfg)
#define PORT_GP_1(bank, pin, fn, sfx) PORT_GP_CFG_1(bank, pin, fn, sfx, 0)
#define PORT_GP_CFG_4(bank, fn, sfx, cfg) \
PORT_GP_CFG_1(bank, 0, fn, sfx, cfg), PORT_GP_CFG_1(bank, 1, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 2, fn, sfx, cfg), PORT_GP_CFG_1(bank, 3, fn, sfx, cfg)
#define PORT_GP_CFG_4(bank, fn, sfx, cfg) \
PORT_GP_CFG_1(bank, 0, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 1, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 2, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 3, fn, sfx, cfg)
#define PORT_GP_4(bank, fn, sfx) PORT_GP_CFG_4(bank, fn, sfx, 0)
#define PORT_GP_CFG_8(bank, fn, sfx, cfg) \
PORT_GP_CFG_4(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 4, fn, sfx, cfg), PORT_GP_CFG_1(bank, 5, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 6, fn, sfx, cfg), PORT_GP_CFG_1(bank, 7, fn, sfx, cfg)
#define PORT_GP_CFG_8(bank, fn, sfx, cfg) \
PORT_GP_CFG_4(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 4, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 5, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 6, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 7, fn, sfx, cfg)
#define PORT_GP_8(bank, fn, sfx) PORT_GP_CFG_8(bank, fn, sfx, 0)
#define PORT_GP_CFG_9(bank, fn, sfx, cfg) \
PORT_GP_CFG_8(bank, fn, sfx, cfg), \
#define PORT_GP_CFG_9(bank, fn, sfx, cfg) \
PORT_GP_CFG_8(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 8, fn, sfx, cfg)
#define PORT_GP_9(bank, fn, sfx) PORT_GP_CFG_9(bank, fn, sfx, 0)
#define PORT_GP_CFG_12(bank, fn, sfx, cfg) \
PORT_GP_CFG_8(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 8, fn, sfx, cfg), PORT_GP_CFG_1(bank, 9, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 10, fn, sfx, cfg), PORT_GP_CFG_1(bank, 11, fn, sfx, cfg)
#define PORT_GP_CFG_12(bank, fn, sfx, cfg) \
PORT_GP_CFG_9(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 9, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 10, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 11, fn, sfx, cfg)
#define PORT_GP_12(bank, fn, sfx) PORT_GP_CFG_12(bank, fn, sfx, 0)
#define PORT_GP_CFG_14(bank, fn, sfx, cfg) \
PORT_GP_CFG_12(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 12, fn, sfx, cfg), PORT_GP_CFG_1(bank, 13, fn, sfx, cfg)
#define PORT_GP_CFG_14(bank, fn, sfx, cfg) \
PORT_GP_CFG_12(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 12, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 13, fn, sfx, cfg)
#define PORT_GP_14(bank, fn, sfx) PORT_GP_CFG_14(bank, fn, sfx, 0)
#define PORT_GP_CFG_15(bank, fn, sfx, cfg) \
PORT_GP_CFG_14(bank, fn, sfx, cfg), \
#define PORT_GP_CFG_15(bank, fn, sfx, cfg) \
PORT_GP_CFG_14(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 14, fn, sfx, cfg)
#define PORT_GP_15(bank, fn, sfx) PORT_GP_CFG_15(bank, fn, sfx, 0)
#define PORT_GP_CFG_16(bank, fn, sfx, cfg) \
PORT_GP_CFG_14(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 14, fn, sfx, cfg), PORT_GP_CFG_1(bank, 15, fn, sfx, cfg)
#define PORT_GP_CFG_16(bank, fn, sfx, cfg) \
PORT_GP_CFG_15(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 15, fn, sfx, cfg)
#define PORT_GP_16(bank, fn, sfx) PORT_GP_CFG_16(bank, fn, sfx, 0)
#define PORT_GP_CFG_18(bank, fn, sfx, cfg) \
PORT_GP_CFG_16(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 16, fn, sfx, cfg), PORT_GP_CFG_1(bank, 17, fn, sfx, cfg)
#define PORT_GP_CFG_17(bank, fn, sfx, cfg) \
PORT_GP_CFG_16(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 16, fn, sfx, cfg)
#define PORT_GP_17(bank, fn, sfx) PORT_GP_CFG_17(bank, fn, sfx, 0)
#define PORT_GP_CFG_18(bank, fn, sfx, cfg) \
PORT_GP_CFG_17(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 17, fn, sfx, cfg)
#define PORT_GP_18(bank, fn, sfx) PORT_GP_CFG_18(bank, fn, sfx, 0)
#define PORT_GP_CFG_26(bank, fn, sfx, cfg) \
PORT_GP_CFG_18(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 18, fn, sfx, cfg), PORT_GP_CFG_1(bank, 19, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 20, fn, sfx, cfg), PORT_GP_CFG_1(bank, 21, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 22, fn, sfx, cfg), PORT_GP_CFG_1(bank, 23, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 24, fn, sfx, cfg), PORT_GP_CFG_1(bank, 25, fn, sfx, cfg)
#define PORT_GP_CFG_23(bank, fn, sfx, cfg) \
PORT_GP_CFG_18(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 18, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 19, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 20, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 21, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 22, fn, sfx, cfg)
#define PORT_GP_23(bank, fn, sfx) PORT_GP_CFG_23(bank, fn, sfx, 0)
#define PORT_GP_CFG_24(bank, fn, sfx, cfg) \
PORT_GP_CFG_23(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 23, fn, sfx, cfg)
#define PORT_GP_24(bank, fn, sfx) PORT_GP_CFG_24(bank, fn, sfx, 0)
#define PORT_GP_CFG_26(bank, fn, sfx, cfg) \
PORT_GP_CFG_24(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 24, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 25, fn, sfx, cfg)
#define PORT_GP_26(bank, fn, sfx) PORT_GP_CFG_26(bank, fn, sfx, 0)
#define PORT_GP_CFG_28(bank, fn, sfx, cfg) \
PORT_GP_CFG_26(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 26, fn, sfx, cfg), PORT_GP_CFG_1(bank, 27, fn, sfx, cfg)
#define PORT_GP_CFG_28(bank, fn, sfx, cfg) \
PORT_GP_CFG_26(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 26, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 27, fn, sfx, cfg)
#define PORT_GP_28(bank, fn, sfx) PORT_GP_CFG_28(bank, fn, sfx, 0)
#define PORT_GP_CFG_30(bank, fn, sfx, cfg) \
PORT_GP_CFG_28(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 28, fn, sfx, cfg), PORT_GP_CFG_1(bank, 29, fn, sfx, cfg)
#define PORT_GP_CFG_29(bank, fn, sfx, cfg) \
PORT_GP_CFG_28(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 28, fn, sfx, cfg)
#define PORT_GP_29(bank, fn, sfx) PORT_GP_CFG_29(bank, fn, sfx, 0)
#define PORT_GP_CFG_30(bank, fn, sfx, cfg) \
PORT_GP_CFG_29(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 29, fn, sfx, cfg)
#define PORT_GP_30(bank, fn, sfx) PORT_GP_CFG_30(bank, fn, sfx, 0)
#define PORT_GP_CFG_32(bank, fn, sfx, cfg) \
PORT_GP_CFG_30(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 30, fn, sfx, cfg), PORT_GP_CFG_1(bank, 31, fn, sfx, cfg)
#define PORT_GP_CFG_32(bank, fn, sfx, cfg) \
PORT_GP_CFG_30(bank, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 30, fn, sfx, cfg), \
PORT_GP_CFG_1(bank, 31, fn, sfx, cfg)
#define PORT_GP_32(bank, fn, sfx) PORT_GP_CFG_32(bank, fn, sfx, 0)
#define PORT_GP_32_REV(bank, fn, sfx) \

View File

@ -7,7 +7,7 @@
* Licensed under GPLv2 or later.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/bitops.h>
@ -6158,6 +6158,3 @@ static int __init atlas7_gpio_init(void)
return platform_driver_register(&atlas7_gpio_driver);
}
subsys_initcall(atlas7_gpio_init);
MODULE_DESCRIPTION("SIRFSOC Atlas7 pin control driver");
MODULE_LICENSE("GPL");

View File

@ -1,6 +1,11 @@
/*
* pinmux driver for CSR SiRFprimaII
*
* Authors:
* Rongjun Ying <rongjun.ying@csr.com>
* Yuping Luo <yuping.luo@csr.com>
* Barry Song <baohua.song@csr.com>
*
* Copyright (c) 2011 - 2014 Cambridge Silicon Radio Limited, a CSR plc group
* company.
*
@ -8,7 +13,6 @@
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/io.h>
@ -884,9 +888,3 @@ static int __init sirfsoc_gpio_init(void)
return sirfsoc_gpio_probe(np);
}
subsys_initcall(sirfsoc_gpio_init);
MODULE_AUTHOR("Rongjun Ying <rongjun.ying@csr.com>");
MODULE_AUTHOR("Yuping Luo <yuping.luo@csr.com>");
MODULE_AUTHOR("Barry Song <baohua.song@csr.com>");
MODULE_DESCRIPTION("SIRFSOC pin control driver");
MODULE_LICENSE("GPL");

View File

@ -6,16 +6,17 @@ config PINCTRL_STM32
select PINMUX
select GENERIC_PINCONF
select GPIOLIB
select MFD_SYSCON
config PINCTRL_STM32F429
bool "STMicroelectronics STM32F429 pin control" if COMPILE_TEST && !MACH_STM32F429
depends on OF
depends on OF && IRQ_DOMAIN_HIERARCHY
default MACH_STM32F429
select PINCTRL_STM32
config PINCTRL_STM32F746
bool "STMicroelectronics STM32F746 pin control" if COMPILE_TEST && !MACH_STM32F746
depends on OF
depends on OF && IRQ_DOMAIN_HIERARCHY
default MACH_STM32F746
select PINCTRL_STM32

View File

@ -8,6 +8,8 @@
#include <linux/clk.h>
#include <linux/gpio/driver.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
@ -20,6 +22,7 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/slab.h>
@ -40,6 +43,7 @@
#define STM32_GPIO_AFRH 0x24
#define STM32_GPIO_PINS_PER_BANK 16
#define STM32_GPIO_IRQ_LINE 16
#define gpio_range_to_bank(chip) \
container_of(chip, struct stm32_gpio_bank, range)
@ -65,6 +69,8 @@ struct stm32_gpio_bank {
spinlock_t lock;
struct gpio_chip gpio_chip;
struct pinctrl_gpio_range range;
struct fwnode_handle *fwnode;
struct irq_domain *domain;
};
struct stm32_pinctrl {
@ -77,6 +83,9 @@ struct stm32_pinctrl {
struct stm32_gpio_bank *banks;
unsigned nbanks;
const struct stm32_pinctrl_match_data *match_data;
struct irq_domain *domain;
struct regmap *regmap;
struct regmap_field *irqmux[STM32_GPIO_PINS_PER_BANK];
};
static inline int stm32_gpio_pin(int gpio)
@ -174,17 +183,113 @@ static int stm32_gpio_direction_output(struct gpio_chip *chip,
return 0;
}
static struct gpio_chip stm32_gpio_template = {
static int stm32_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
{
struct stm32_gpio_bank *bank = gpiochip_get_data(chip);
struct irq_fwspec fwspec;
fwspec.fwnode = bank->fwnode;
fwspec.param_count = 2;
fwspec.param[0] = offset;
fwspec.param[1] = IRQ_TYPE_NONE;
return irq_create_fwspec_mapping(&fwspec);
}
static const struct gpio_chip stm32_gpio_template = {
.request = stm32_gpio_request,
.free = stm32_gpio_free,
.get = stm32_gpio_get,
.set = stm32_gpio_set,
.direction_input = stm32_gpio_direction_input,
.direction_output = stm32_gpio_direction_output,
.to_irq = stm32_gpio_to_irq,
};
static struct irq_chip stm32_gpio_irq_chip = {
.name = "stm32gpio",
.irq_eoi = irq_chip_eoi_parent,
.irq_mask = irq_chip_mask_parent,
.irq_unmask = irq_chip_unmask_parent,
.irq_set_type = irq_chip_set_type_parent,
};
static int stm32_gpio_domain_translate(struct irq_domain *d,
struct irq_fwspec *fwspec,
unsigned long *hwirq,
unsigned int *type)
{
if ((fwspec->param_count != 2) ||
(fwspec->param[0] >= STM32_GPIO_IRQ_LINE))
return -EINVAL;
*hwirq = fwspec->param[0];
*type = fwspec->param[1];
return 0;
}
static void stm32_gpio_domain_activate(struct irq_domain *d,
struct irq_data *irq_data)
{
struct stm32_gpio_bank *bank = d->host_data;
struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent);
regmap_field_write(pctl->irqmux[irq_data->hwirq], bank->range.id);
}
static int stm32_gpio_domain_alloc(struct irq_domain *d,
unsigned int virq,
unsigned int nr_irqs, void *data)
{
struct stm32_gpio_bank *bank = d->host_data;
struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent);
struct irq_fwspec *fwspec = data;
struct irq_fwspec parent_fwspec;
irq_hw_number_t hwirq;
int ret;
hwirq = fwspec->param[0];
parent_fwspec.fwnode = d->parent->fwnode;
parent_fwspec.param_count = 2;
parent_fwspec.param[0] = fwspec->param[0];
parent_fwspec.param[1] = fwspec->param[1];
irq_domain_set_hwirq_and_chip(d, virq, hwirq, &stm32_gpio_irq_chip,
bank);
ret = gpiochip_lock_as_irq(&bank->gpio_chip, hwirq);
if (ret) {
dev_err(pctl->dev, "Unable to configure STM32 %s%ld as IRQ\n",
bank->gpio_chip.label, hwirq);
return ret;
}
ret = irq_domain_alloc_irqs_parent(d, virq, nr_irqs, &parent_fwspec);
if (ret)
gpiochip_unlock_as_irq(&bank->gpio_chip, hwirq);
return ret;
}
static void stm32_gpio_domain_free(struct irq_domain *d, unsigned int virq,
unsigned int nr_irqs)
{
struct stm32_gpio_bank *bank = d->host_data;
struct irq_data *data = irq_get_irq_data(virq);
irq_domain_free_irqs_common(d, virq, nr_irqs);
gpiochip_unlock_as_irq(&bank->gpio_chip, data->hwirq);
}
static const struct irq_domain_ops stm32_gpio_domain_ops = {
.translate = stm32_gpio_domain_translate,
.alloc = stm32_gpio_domain_alloc,
.free = stm32_gpio_domain_free,
.activate = stm32_gpio_domain_activate,
};
/* Pinctrl functions */
static struct stm32_pinctrl_group *
stm32_pctrl_find_group_by_pin(struct stm32_pinctrl *pctl, u32 pin)
{
@ -857,6 +962,17 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
range->pin_base = range->base = range->id * STM32_GPIO_PINS_PER_BANK;
range->npins = bank->gpio_chip.ngpio;
range->gc = &bank->gpio_chip;
/* create irq hierarchical domain */
bank->fwnode = of_node_to_fwnode(np);
bank->domain = irq_domain_create_hierarchy(pctl->domain, 0,
STM32_GPIO_IRQ_LINE, bank->fwnode,
&stm32_gpio_domain_ops, bank);
if (!bank->domain)
return -ENODEV;
err = gpiochip_add_data(&bank->gpio_chip, bank);
if (err) {
dev_err(dev, "Failed to add gpiochip(%d)!\n", bank_nr);
@ -867,6 +983,47 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
return 0;
}
static int stm32_pctrl_dt_setup_irq(struct platform_device *pdev,
struct stm32_pinctrl *pctl)
{
struct device_node *np = pdev->dev.of_node, *parent;
struct device *dev = &pdev->dev;
struct regmap *rm;
int offset, ret, i;
parent = of_irq_find_parent(np);
if (!parent)
return -ENXIO;
pctl->domain = irq_find_host(parent);
if (!pctl->domain)
return -ENXIO;
pctl->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
if (IS_ERR(pctl->regmap))
return PTR_ERR(pctl->regmap);
rm = pctl->regmap;
ret = of_property_read_u32_index(np, "st,syscfg", 1, &offset);
if (ret)
return ret;
for (i = 0; i < STM32_GPIO_PINS_PER_BANK; i++) {
struct reg_field mux;
mux.reg = offset + (i / 4) * 4;
mux.lsb = (i % 4) * 4;
mux.msb = mux.lsb + 3;
pctl->irqmux[i] = devm_regmap_field_alloc(dev, rm, mux);
if (IS_ERR(pctl->irqmux[i]))
return PTR_ERR(pctl->irqmux[i]);
}
return 0;
}
static int stm32_pctrl_build_state(struct platform_device *pdev)
{
struct stm32_pinctrl *pctl = platform_get_drvdata(pdev);
@ -935,6 +1092,10 @@ int stm32_pctl_probe(struct platform_device *pdev)
return -EINVAL;
}
ret = stm32_pctrl_dt_setup_irq(pdev, pctl);
if (ret)
return ret;
for_each_child_of_node(np, child)
if (of_property_read_bool(child, "gpio-controller"))
banks++;

View File

@ -17,6 +17,10 @@ config PINCTRL_SUN5I_A13
def_bool MACH_SUN5I
select PINCTRL_SUNXI
config PINCTRL_GR8
def_bool MACH_SUN5I
select PINCTRL_SUNXI_COMMON
config PINCTRL_SUN6I_A31
def_bool MACH_SUN6I
select PINCTRL_SUNXI

View File

@ -5,6 +5,7 @@ obj-y += pinctrl-sunxi.o
obj-$(CONFIG_PINCTRL_SUN4I_A10) += pinctrl-sun4i-a10.o
obj-$(CONFIG_PINCTRL_SUN5I_A10S) += pinctrl-sun5i-a10s.o
obj-$(CONFIG_PINCTRL_SUN5I_A13) += pinctrl-sun5i-a13.o
obj-$(CONFIG_PINCTRL_GR8) += pinctrl-gr8.o
obj-$(CONFIG_PINCTRL_SUN6I_A31) += pinctrl-sun6i-a31.o
obj-$(CONFIG_PINCTRL_SUN6I_A31S) += pinctrl-sun6i-a31s.o
obj-$(CONFIG_PINCTRL_SUN6I_A31_R) += pinctrl-sun6i-a31-r.o

View File

@ -0,0 +1,541 @@
/*
* NextThing GR8 SoCs pinctrl driver.
*
* Copyright (C) 2016 Mylene Josserand
*
* Based on pinctrl-sun5i-a13.c
*
* Mylene Josserand <mylene.josserand@free-electrons.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-sunxi.h"
static const struct sunxi_desc_pin sun5i_gr8_pins[] = {
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c0")), /* SCK */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c0")), /* SDA */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "pwm0"),
SUNXI_FUNCTION(0x3, "spdif"), /* DO */
SUNXI_FUNCTION_IRQ(0x6, 16)), /* EINT16 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "ir0"), /* TX */
SUNXI_FUNCTION_IRQ(0x6, 17)), /* EINT17 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "ir0"), /* RX */
SUNXI_FUNCTION_IRQ(0x6, 18)), /* EINT18 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2s0"), /* MCLK */
SUNXI_FUNCTION_IRQ(0x6, 19)), /* EINT19 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2s0"), /* BCLK */
SUNXI_FUNCTION_IRQ(0x6, 20)), /* EINT20 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2s0"), /* LRCK */
SUNXI_FUNCTION_IRQ(0x6, 21)), /* EINT21 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 8),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2s0"), /* DO */
SUNXI_FUNCTION_IRQ(0x6, 22)), /* EINT22 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 9),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2s0"), /* DI */
SUNXI_FUNCTION(0x3, "spdif"), /* DI */
SUNXI_FUNCTION_IRQ(0x6, 23)), /* EINT23 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 10),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi2"), /* CS1 */
SUNXI_FUNCTION(0x3, "spdif"), /* DO */
SUNXI_FUNCTION_IRQ(0x6, 24)), /* EINT24 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 11),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi2"), /* CS0 */
SUNXI_FUNCTION(0x3, "jtag"), /* MS0 */
SUNXI_FUNCTION_IRQ(0x6, 25)), /* EINT25 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 12),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi2"), /* CLK */
SUNXI_FUNCTION(0x3, "jtag"), /* CK0 */
SUNXI_FUNCTION_IRQ(0x6, 26)), /* EINT26 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 13),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi2"), /* MOSI */
SUNXI_FUNCTION(0x3, "jtag"), /* DO0 */
SUNXI_FUNCTION_IRQ(0x6, 27)), /* EINT27 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 14),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi2"), /* MISO */
SUNXI_FUNCTION(0x3, "jtag"), /* DI0 */
SUNXI_FUNCTION_IRQ(0x6, 28)), /* EINT28 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 15),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c1")), /* SCK */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 16),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c1")), /* SDA */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 17),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c2")), /* SCK */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 18),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c2")), /* SDA */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* NWE */
SUNXI_FUNCTION(0x3, "spi0")), /* MOSI */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* NALE */
SUNXI_FUNCTION(0x3, "spi0")), /* MISO */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* NCLE */
SUNXI_FUNCTION(0x3, "spi0")), /* CLK */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* NCE1 */
SUNXI_FUNCTION(0x3, "spi0")), /* CS0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0")), /* NCE0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0")), /* NRE */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* NRB0 */
SUNXI_FUNCTION(0x3, "mmc2")), /* CMD */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* NRB1 */
SUNXI_FUNCTION(0x3, "mmc2")), /* CLK */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 8),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* NDQ0 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 9),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* NDQ1 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 10),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* NDQ2 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 11),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* NDQ3 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 12),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* NDQ4 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D4 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 13),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* NDQ5 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D5 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* NDQ6 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* NDQ7 */
SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 19),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "nand0"), /* NDQS */
SUNXI_FUNCTION(0x3, "uart2"), /* RX */
SUNXI_FUNCTION(0x4, "uart3")), /* RTS */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D2 */
SUNXI_FUNCTION(0x3, "uart2")), /* TX */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D3 */
SUNXI_FUNCTION(0x3, "uart2")), /* RX */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D4 */
SUNXI_FUNCTION(0x3, "uart2")), /* CTS */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D5 */
SUNXI_FUNCTION(0x3, "uart2")), /* RTS */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D6 */
SUNXI_FUNCTION(0x3, "emac")), /* ECRS */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D7 */
SUNXI_FUNCTION(0x3, "emac")), /* ECOL */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 10),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D10 */
SUNXI_FUNCTION(0x3, "emac")), /* ERXD0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 11),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D11 */
SUNXI_FUNCTION(0x3, "emac")), /* ERXD1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 12),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D12 */
SUNXI_FUNCTION(0x3, "emac")), /* ERXD2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 13),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D13 */
SUNXI_FUNCTION(0x3, "emac")), /* ERXD3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 14),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D14 */
SUNXI_FUNCTION(0x3, "emac")), /* ERXCK */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 15),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D15 */
SUNXI_FUNCTION(0x3, "emac")), /* ERXERR */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 18),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D18 */
SUNXI_FUNCTION(0x3, "emac")), /* ERXDV */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 19),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D19 */
SUNXI_FUNCTION(0x3, "emac")), /* ETXD0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 20),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D20 */
SUNXI_FUNCTION(0x3, "emac")), /* ETXD1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 21),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D21 */
SUNXI_FUNCTION(0x3, "emac")), /* ETXD2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 22),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D22 */
SUNXI_FUNCTION(0x3, "emac")), /* ETXD3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 23),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* D23 */
SUNXI_FUNCTION(0x3, "emac")), /* ETXEN */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 24),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* CLK */
SUNXI_FUNCTION(0x3, "emac")), /* ETXCK */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 25),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* DE */
SUNXI_FUNCTION(0x3, "emac")), /* ETXERR*/
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 26),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* HSYNC */
SUNXI_FUNCTION(0x3, "emac")), /* EMDC */
SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 27),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "lcd0"), /* VSYNC */
SUNXI_FUNCTION(0x3, "emac")), /* EMDIO */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x2, "ts0"), /* CLK */
SUNXI_FUNCTION(0x3, "csi0"), /* PCLK */
SUNXI_FUNCTION(0x4, "spi2"), /* CS0 */
SUNXI_FUNCTION_IRQ(0x6, 14)), /* EINT14 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x2, "ts0"), /* ERR */
SUNXI_FUNCTION(0x3, "csi0"), /* MCLK */
SUNXI_FUNCTION(0x4, "spi2"), /* CLK */
SUNXI_FUNCTION_IRQ(0x6, 15)), /* EINT15 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x2, "ts0"), /* SYNC */
SUNXI_FUNCTION(0x3, "csi0"), /* HSYNC */
SUNXI_FUNCTION(0x4, "spi2")), /* MOSI */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "ts0"), /* DVLD */
SUNXI_FUNCTION(0x3, "csi0"), /* VSYNC */
SUNXI_FUNCTION(0x4, "spi2")), /* MISO */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "ts0"), /* D0 */
SUNXI_FUNCTION(0x3, "csi0"), /* D0 */
SUNXI_FUNCTION(0x4, "mmc2")), /* D0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "ts0"), /* D1 */
SUNXI_FUNCTION(0x3, "csi0"), /* D1 */
SUNXI_FUNCTION(0x4, "mmc2")), /* D1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "ts0"), /* D2 */
SUNXI_FUNCTION(0x3, "csi0"), /* D2 */
SUNXI_FUNCTION(0x4, "mmc2")), /* D2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "ts0"), /* D3 */
SUNXI_FUNCTION(0x3, "csi0"), /* D3 */
SUNXI_FUNCTION(0x4, "mmc2")), /* D3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "ts0"), /* D4 */
SUNXI_FUNCTION(0x3, "csi0"), /* D4 */
SUNXI_FUNCTION(0x4, "mmc2")), /* CMD */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "ts0"), /* D5 */
SUNXI_FUNCTION(0x3, "csi0"), /* D5 */
SUNXI_FUNCTION(0x4, "mmc2")), /* CLK */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "ts0"), /* D6 */
SUNXI_FUNCTION(0x3, "csi0"), /* D6 */
SUNXI_FUNCTION(0x4, "uart1")), /* TX */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "ts0"), /* D7 */
SUNXI_FUNCTION(0x3, "csi0"), /* D7 */
SUNXI_FUNCTION(0x4, "uart1")), /* RX */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc0"), /* D1 */
SUNXI_FUNCTION(0x4, "jtag")), /* MS1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc0"), /* D0 */
SUNXI_FUNCTION(0x4, "jtag")), /* DI1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc0"), /* CLK */
SUNXI_FUNCTION(0x4, "uart0")), /* TX */
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc0"), /* CMD */
SUNXI_FUNCTION(0x4, "jtag")), /* DO1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc0"), /* D3 */
SUNXI_FUNCTION(0x4, "uart0")), /* RX */
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc0"), /* D2 */
SUNXI_FUNCTION(0x4, "jtag")), /* CK1 */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x2, "gps"), /* CLK */
SUNXI_FUNCTION_IRQ(0x6, 0)), /* EINT0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x2, "gps"), /* SIGN */
SUNXI_FUNCTION_IRQ(0x6, 1)), /* EINT1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x2, "gps"), /* MAG */
SUNXI_FUNCTION_IRQ(0x6, 2)), /* EINT2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc1"), /* CMD */
SUNXI_FUNCTION(0x3, "ms"), /* BS */
SUNXI_FUNCTION(0x4, "uart1"), /* TX */
SUNXI_FUNCTION_IRQ(0x6, 3)), /* EINT3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc1"), /* CLK */
SUNXI_FUNCTION(0x3, "ms"), /* CLK */
SUNXI_FUNCTION(0x4, "uart1"), /* RX */
SUNXI_FUNCTION_IRQ(0x6, 4)), /* EINT4 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc1"), /* D0 */
SUNXI_FUNCTION(0x3, "ms"), /* D0 */
SUNXI_FUNCTION(0x4, "uart1"), /* CTS */
SUNXI_FUNCTION_IRQ(0x6, 5)), /* EINT5 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc1"), /* D1 */
SUNXI_FUNCTION(0x3, "ms"), /* D1 */
SUNXI_FUNCTION(0x4, "uart1"), /* RTS */
SUNXI_FUNCTION(0x5, "uart2"), /* RTS */
SUNXI_FUNCTION_IRQ(0x6, 6)), /* EINT6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc1"), /* D2 */
SUNXI_FUNCTION(0x3, "ms"), /* D2 */
SUNXI_FUNCTION(0x5, "uart2"), /* TX */
SUNXI_FUNCTION_IRQ(0x6, 7)), /* EINT7 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "mmc1"), /* D3 */
SUNXI_FUNCTION(0x3, "ms"), /* D3 */
SUNXI_FUNCTION(0x5, "uart2"), /* RX */
SUNXI_FUNCTION_IRQ(0x6, 8)), /* EINT8 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* CS0 */
SUNXI_FUNCTION(0x3, "uart3"), /* TX */
SUNXI_FUNCTION_IRQ(0x6, 9)), /* EINT9 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* CLK */
SUNXI_FUNCTION(0x3, "uart3"), /* RX */
SUNXI_FUNCTION_IRQ(0x6, 10)), /* EINT10 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* MOSI */
SUNXI_FUNCTION(0x3, "uart3"), /* CTS */
SUNXI_FUNCTION_IRQ(0x6, 11)), /* EINT11 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* MISO */
SUNXI_FUNCTION(0x3, "uart3"), /* RTS */
SUNXI_FUNCTION_IRQ(0x6, 12)), /* EINT12 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* CS1 */
SUNXI_FUNCTION(0x3, "pwm1"),
SUNXI_FUNCTION(0x5, "uart2"), /* CTS */
SUNXI_FUNCTION_IRQ(0x6, 13)), /* EINT13 */
};
static const struct sunxi_pinctrl_desc sun5i_gr8_pinctrl_data = {
.pins = sun5i_gr8_pins,
.npins = ARRAY_SIZE(sun5i_gr8_pins),
.irq_banks = 1,
};
static int sun5i_gr8_pinctrl_probe(struct platform_device *pdev)
{
return sunxi_pinctrl_init(pdev,
&sun5i_gr8_pinctrl_data);
}
static const struct of_device_id sun5i_gr8_pinctrl_match[] = {
{ .compatible = "nextthing,gr8-pinctrl", },
{}
};
MODULE_DEVICE_TABLE(of, sun5i_gr8_pinctrl_match);
static struct platform_driver sun5i_gr8_pinctrl_driver = {
.probe = sun5i_gr8_pinctrl_probe,
.driver = {
.name = "gr8-pinctrl",
.of_match_table = sun5i_gr8_pinctrl_match,
},
};
module_platform_driver(sun5i_gr8_pinctrl_driver);
MODULE_AUTHOR("Mylene Josserand <mylene.josserand@free-electrons.com");
MODULE_DESCRIPTION("NextThing GR8 pinctrl driver");
MODULE_LICENSE("GPL");

View File

@ -896,10 +896,18 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
SUNXI_FUNCTION(0x1, "gpio_out")),
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 27),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out")),
SUNXI_FUNCTION(0x1, "gpio_out"),
/*
* The SPDIF block is not referenced at all in the A31 user
* manual. However it is described in the code leaked and the
* configuration files supplied by vendors.
*/
SUNXI_FUNCTION(0x3, "spdif")), /* SPDIF IN */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 28),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out")),
SUNXI_FUNCTION(0x1, "gpio_out"),
/* Undocumented mux function - see above */
SUNXI_FUNCTION(0x3, "spdif")), /* SPDIF OUT */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 29),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),

View File

@ -60,7 +60,6 @@ static const struct sunxi_desc_pin sun8i_h3_pins[] = {
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "sim"), /* PWREN */
SUNXI_FUNCTION(0x3, "pwm1"),
SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)), /* PA_EINT6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),

View File

@ -112,6 +112,10 @@ enum single_ended_mode {
* initialization, provided by GPIO driver
* @irq_parent: GPIO IRQ chip parent/bank linux irq number,
* provided by GPIO driver
* @irq_need_valid_mask: If set core allocates @irq_valid_mask with all
* bits set to one
* @irq_valid_mask: If not %NULL holds bitmask of GPIOs which are valid to
* be included in IRQ domain of the chip
* @lock_key: per GPIO IRQ chip lockdep class
*
* A gpio_chip can help platforms abstract various sources of GPIOs so
@ -190,6 +194,8 @@ struct gpio_chip {
irq_flow_handler_t irq_handler;
unsigned int irq_default_type;
int irq_parent;
bool irq_need_valid_mask;
unsigned long *irq_valid_mask;
struct lock_class_key *lock_key;
#endif