forked from Minki/linux
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:
commit
d268dbe76a
@ -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.
|
||||
|
65
Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt
Normal file
65
Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt
Normal 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.
|
@ -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";
|
||||
|
@ -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>,
|
||||
|
@ -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>;
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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>, "
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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/
|
||||
|
24
drivers/pinctrl/aspeed/Kconfig
Normal file
24
drivers/pinctrl/aspeed/Kconfig
Normal 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.
|
6
drivers/pinctrl/aspeed/Makefile
Normal file
6
drivers/pinctrl/aspeed/Makefile
Normal 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
|
1231
drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c
Normal file
1231
drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c
Normal file
File diff suppressed because it is too large
Load Diff
808
drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
Normal file
808
drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
Normal 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);
|
498
drivers/pinctrl/aspeed/pinctrl-aspeed.c
Normal file
498
drivers/pinctrl/aspeed/pinctrl-aspeed.c
Normal 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;
|
||||
}
|
569
drivers/pinctrl/aspeed/pinctrl-aspeed.h
Normal file
569
drivers/pinctrl/aspeed/pinctrl-aspeed.h
Normal 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 */
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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>");
|
||||
|
@ -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),
|
||||
};
|
||||
|
@ -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, ®, &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,
|
||||
®, &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, ®, &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,
|
||||
®, &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, ®, &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, ®, &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, ®, &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, ®, &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, ®, &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, ®, &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, ®, &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, ®, &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;
|
||||
|
@ -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)
|
||||
|
@ -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),
|
||||
};
|
||||
|
@ -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),
|
||||
};
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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");
|
||||
|
@ -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 */ }
|
||||
};
|
||||
|
@ -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};
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
{ },
|
||||
};
|
||||
|
||||
|
@ -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 */
|
||||
{ },
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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 },
|
||||
|
2739
drivers/pinctrl/sh-pfc/pfc-r8a7792.c
Normal file
2739
drivers/pinctrl/sh-pfc/pfc-r8a7792.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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 },
|
||||
|
@ -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 = {
|
||||
|
2671
drivers/pinctrl/sh-pfc/pfc-r8a7796.c
Normal file
2671
drivers/pinctrl/sh-pfc/pfc-r8a7796.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) \
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
||||
|
@ -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++;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
541
drivers/pinctrl/sunxi/pinctrl-gr8.c
Normal file
541
drivers/pinctrl/sunxi/pinctrl-gr8.c
Normal 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");
|
@ -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"),
|
||||
|
@ -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"),
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user