Commit 8a1a3b1d authored by Simon Horman's avatar Simon Horman

Merge commit '70c8f01a' into dt3-base

This is a commit from the for-next branch of Linus Walleij's pin control tre
git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git

It is the oldest commit in that branch that provides the dependencies
needed for SoC changes to the usage of sh-pfc.
parents bd060989 70c8f01a
* Freescale IMX25 IOMUX Controller
Please refer to fsl,imx-pinctrl.txt in this directory for common binding part
and usage.
CONFIG bits definition:
PAD_CTL_HYS (1 << 8)
PAD_CTL_PKE (1 << 7)
PAD_CTL_PUE (1 << 6)
PAD_CTL_PUS_100K_DOWN (0 << 4)
PAD_CTL_PUS_47K_UP (1 << 4)
PAD_CTL_PUS_100K_UP (2 << 4)
PAD_CTL_PUS_22K_UP (3 << 4)
PAD_CTL_ODE_CMOS (0 << 3)
PAD_CTL_ODE_OPENDRAIN (1 << 3)
PAD_CTL_DSE_NOMINAL (0 << 1)
PAD_CTL_DSE_HIGH (1 << 1)
PAD_CTL_DSE_MAX (2 << 1)
PAD_CTL_SRE_FAST (1 << 0)
PAD_CTL_SRE_SLOW (0 << 0)
Refer to imx25-pinfunc.h in device tree source folder for all available
imx25 PIN_FUNC_ID.
......@@ -52,12 +52,25 @@ Required properties for pin configuration node:
CONFIG can be 0 or 1, meaning Pullup disable/enable.
The iomux controller has gpio child nodes which are embedded in the iomux
control registers. They have to be defined as child nodes of the iomux device
node. If gpio subnodes are defined "#address-cells", "#size-cells" and "ranges"
properties for the iomux device node are required.
Example:
iomuxc: iomuxc@10015000 {
compatible = "fsl,imx27-iomuxc";
reg = <0x10015000 0x600>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
gpio1: gpio@10015000 {
...
};
...
uart {
pinctrl_uart1: uart-1 {
......@@ -83,6 +96,15 @@ The above example using macros:
iomuxc: iomuxc@10015000 {
compatible = "fsl,imx27-iomuxc";
reg = <0x10015000 0x600>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
gpio1: gpio@10015000 {
...
};
...
uart {
pinctrl_uart1: uart-1 {
......
Qualcomm MSM8x74 TLMM block
Required properties:
- compatible: "qcom,msm8x74-pinctrl"
- reg: Should be the base address and length of the TLMM block.
- interrupts: Should be the parent IRQ of the TLMM block.
- interrupt-controller: Marks the device node as an interrupt controller.
- #interrupt-cells: Should be two.
- gpio-controller: Marks the device node as a GPIO controller.
- #gpio-cells : Should be two.
The first cell is the gpio pin number and the
second cell is used for optional parameters.
Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
a general description of GPIO and interrupt bindings.
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices, including the meaning of the
phrase "pin configuration node".
Qualcomm's pin configuration nodes act as a container for an abitrary number of
subnodes. Each of these subnodes represents some desired configuration for a
pin, a group, or a list of pins or groups. This configuration can include the
mux function to select on those pin(s)/group(s), and various pin configuration
parameters, such as pull-up, drive strength, etc.
The name of each subnode is not important; all subnodes should be enumerated
and processed purely based on their content.
Each subnode only affects those parameters that are explicitly listed. In
other words, a subnode that lists a mux function but no pin configuration
parameters implies no information about any pin configuration parameters.
Similarly, a pin subnode that describes a pullup parameter implies no
information about e.g. the mux function.
The following generic properties as defined in pinctrl-bindings.txt are valid
to specify in a pin configuration subnode:
pins, function, bias-disable, bias-pull-down, bias-pull,up, drive-strength.
Non-empty subnodes must specify the 'pins' property.
Note that not all properties are valid for all pins.
Valid values for qcom,pins are:
gpio0-gpio145
Supports mux, bias and drive-strength
sdc1_clk, sdc1_cmd, sdc1_data, sdc2_clk, sdc2_cmd, sdc2_data
Supports bias and drive-strength
Valid values for qcom,function are:
blsp_i2c2, blsp_i2c6, blsp_i2c11, blsp_spi1, blsp_uart2, blsp_uart8, slimbus
(Note that this is not yet the complete list of functions)
Example:
msmgpio: pinctrl@fd510000 {
compatible = "qcom,msm8x74-pinctrl";
reg = <0xfd510000 0x4000>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <0 208 0>;
pinctrl-names = "default";
pinctrl-0 = <&uart2_default>;
uart2_default: uart2_default {
mux {
qcom,pins = "gpio4", "gpio5";
qcom,function = "blsp_uart2";
};
tx {
qcom,pins = "gpio4";
drive-strength = <4>;
bias-disable;
};
rx {
qcom,pins = "gpio5";
drive-strength = <2>;
bias-pull-up;
};
};
};
......@@ -26,6 +26,11 @@ Optional properties:
- #gpio-range-cells: Mandatory when the PFC doesn't handle GPIO, forbidden
otherwise. Should be 3.
- interrupts-extended: Specify the interrupts associated with external
IRQ pins. This property is mandatory when the PFC handles GPIOs and
forbidden otherwise. When specified, it must contain one interrupt per
external IRQ, sorted by external IRQ number.
The PFC node also acts as a container for pin configuration nodes. Please refer
to pinctrl-bindings.txt in this directory for the definition of the term "pin
configuration node" and for the common pinctrl bindings used by client devices.
......@@ -103,6 +108,15 @@ Example 1: SH73A0 (SH-Mobile AG5) pin controller node
<0xe605801c 0x1c>;
gpio-controller;
#gpio-cells = <2>;
interrupts-extended =
<&irqpin0 0 0>, <&irqpin0 1 0>, <&irqpin0 2 0>, <&irqpin0 3 0>,
<&irqpin0 4 0>, <&irqpin0 5 0>, <&irqpin0 6 0>, <&irqpin0 7 0>,
<&irqpin1 0 0>, <&irqpin1 1 0>, <&irqpin1 2 0>, <&irqpin1 3 0>,
<&irqpin1 4 0>, <&irqpin1 5 0>, <&irqpin1 6 0>, <&irqpin1 7 0>,
<&irqpin2 0 0>, <&irqpin2 1 0>, <&irqpin2 2 0>, <&irqpin2 3 0>,
<&irqpin2 4 0>, <&irqpin2 5 0>, <&irqpin2 6 0>, <&irqpin2 7 0>,
<&irqpin3 0 0>, <&irqpin3 1 0>, <&irqpin3 2 0>, <&irqpin3 3 0>,
<&irqpin3 4 0>, <&irqpin3 5 0>, <&irqpin3 6 0>, <&irqpin3 7 0>;
};
Example 2: A GPIO LED node that references a GPIO
......
......@@ -116,15 +116,22 @@ config PINCTRL_IMX1_CORE
config PINCTRL_IMX27
bool "IMX27 pinctrl driver"
depends on OF
depends on SOC_IMX27
select PINCTRL_IMX1_CORE
help
Say Y here to enable the imx27 pinctrl driver
config PINCTRL_IMX25
bool "IMX25 pinctrl driver"
depends on OF
depends on SOC_IMX25
select PINCTRL_IMX
help
Say Y here to enable the imx25 pinctrl driver
config PINCTRL_IMX35
bool "IMX35 pinctrl driver"
depends on OF
depends on SOC_IMX35
select PINCTRL_IMX
help
......@@ -132,7 +139,6 @@ config PINCTRL_IMX35
config PINCTRL_IMX50
bool "IMX50 pinctrl driver"
depends on OF
depends on SOC_IMX50
select PINCTRL_IMX
help
......@@ -140,7 +146,6 @@ config PINCTRL_IMX50
config PINCTRL_IMX51
bool "IMX51 pinctrl driver"
depends on OF
depends on SOC_IMX51
select PINCTRL_IMX
help
......@@ -148,7 +153,6 @@ config PINCTRL_IMX51
config PINCTRL_IMX53
bool "IMX53 pinctrl driver"
depends on OF
depends on SOC_IMX53
select PINCTRL_IMX
help
......@@ -156,7 +160,6 @@ config PINCTRL_IMX53
config PINCTRL_IMX6Q
bool "IMX6Q/DL pinctrl driver"
depends on OF
depends on SOC_IMX6Q
select PINCTRL_IMX
help
......@@ -164,7 +167,6 @@ config PINCTRL_IMX6Q
config PINCTRL_IMX6SL
bool "IMX6SL pinctrl driver"
depends on OF
depends on SOC_IMX6SL
select PINCTRL_IMX
help
......@@ -172,7 +174,6 @@ config PINCTRL_IMX6SL
config PINCTRL_VF610
bool "Freescale Vybrid VF610 pinctrl driver"
depends on OF
depends on SOC_VF610
select PINCTRL_IMX
help
......@@ -202,6 +203,17 @@ config PINCTRL_IMX28
bool
select PINCTRL_MXS
config PINCTRL_MSM
bool
select PINMUX
select PINCONF
select GENERIC_PINCONF
config PINCTRL_MSM8X74
bool "Qualcomm 8x74 pin controller driver"
depends on OF && OF_IRQ
select PINCTRL_MSM
config PINCTRL_NOMADIK
bool "Nomadik pin controller driver"
depends on ARCH_U8500 || ARCH_NOMADIK
......
......@@ -34,7 +34,10 @@ obj-$(CONFIG_PINCTRL_IMX6SL) += pinctrl-imx6sl.o
obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o
obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o
obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o
obj-$(CONFIG_PINCTRL_IMX25) += pinctrl-imx25.o
obj-$(CONFIG_PINCTRL_IMX28) += pinctrl-imx28.o
obj-$(CONFIG_PINCTRL_MSM) += pinctrl-msm.o
obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o
obj-$(CONFIG_PINCTRL_NOMADIK) += pinctrl-nomadik.o
obj-$(CONFIG_PINCTRL_STN8815) += pinctrl-nomadik-stn8815.o
obj-$(CONFIG_PINCTRL_DB8500) += pinctrl-nomadik-db8500.o
......
......@@ -28,12 +28,6 @@ int pinconf_check_ops(struct pinctrl_dev *pctldev)
{
const struct pinconf_ops *ops = pctldev->desc->confops;
/* We must be able to read out pin status */
if (!ops->pin_config_get && !ops->pin_config_group_get) {
dev_err(pctldev->dev,
"pinconf must be able to read out pin status\n");
return -EINVAL;
}
/* We have to be able to config the pins in SOME way */
if (!ops->pin_config_set && !ops->pin_config_group_set) {
dev_err(pctldev->dev,
......@@ -67,9 +61,9 @@ int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
const struct pinconf_ops *ops = pctldev->desc->confops;
if (!ops || !ops->pin_config_get) {
dev_err(pctldev->dev, "cannot get pin configuration, missing "
dev_dbg(pctldev->dev, "cannot get pin configuration, missing "
"pin_config_get() function in driver\n");
return -EINVAL;
return -ENOTSUPP;
}
return ops->pin_config_get(pctldev, pin, config);
......@@ -93,10 +87,10 @@ int pin_config_group_get(const char *dev_name, const char *pin_group,
ops = pctldev->desc->confops;
if (!ops || !ops->pin_config_group_get) {
dev_err(pctldev->dev, "cannot get configuration for pin "
dev_dbg(pctldev->dev, "cannot get configuration for pin "
"group, missing group config get function in "
"driver\n");
ret = -EINVAL;
ret = -ENOTSUPP;
goto unlock;
}
......@@ -305,9 +299,6 @@ static int pinconf_pins_show(struct seq_file *s, void *what)
const struct pinconf_ops *ops = pctldev->desc->confops;
unsigned i, pin;
if (!ops || !ops->pin_config_get)
return 0;
seq_puts(s, "Pin config settings per pin\n");
seq_puts(s, "Format: pin (name): configs\n");
......@@ -356,9 +347,6 @@ static int pinconf_groups_show(struct seq_file *s, void *what)
unsigned ngroups = pctlops->get_groups_count(pctldev);
unsigned selector = 0;
if (!ops || !ops->pin_config_group_get)
return 0;
seq_puts(s, "Pin config settings per pin group\n");
seq_puts(s, "Format: group (name): configs\n");
......
......@@ -118,7 +118,7 @@ struct at91_pin_group {
};
/**
* struct at91_pinctrl_mux_ops - describes an At91 mux ops group
* struct at91_pinctrl_mux_ops - describes an AT91 mux ops group
* on new IP with support for periph C and D the way to mux in
* periph A and B has changed
* So provide the right call back
......@@ -722,7 +722,8 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev,
unsigned pin;
int div;
dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__, __LINE__, pin_id, *config);
*config = 0;
dev_dbg(info->dev, "%s:%d, pin_id=%d", __func__, __LINE__, pin_id);
pio = pin_to_controller(info, pin_to_bank(pin_id));
pin = pin_id % MAX_NB_GPIO_PER_BANK;
......@@ -1396,7 +1397,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
chained_irq_enter(chip, desc);
for (;;) {
/* Reading ISR acks pending (edge triggered) GPIO interrupts.
* When there none are pending, we're finished unless we need
* When there are none pending, we're finished unless we need
* to process multiple banks (like ID_PIOCDE on sam9263).
*/
isr = readl_relaxed(pio + PIO_ISR) & readl_relaxed(pio + PIO_IMR);
......@@ -1505,7 +1506,7 @@ static int at91_gpio_of_irq_setup(struct device_node *node,
prev = gpio_chips[at91_gpio->pioc_idx - 1];
/* The top level handler handles one bank of GPIOs, except
* on some SoC it can handles up to three...
* on some SoC it can handle up to three...
* We only set up the handler for the first of the list.
*/
if (prev && prev->next == at91_gpio)
......
......@@ -286,13 +286,19 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
spin_lock_irqsave(&vg->lock, flags);
for (i = 0; i < vg->chip.ngpio; i++) {
const char *label;
offs = vg->range->pins[i] * 16;
conf0 = readl(vg->reg_base + offs + BYT_CONF0_REG);
val = readl(vg->reg_base + offs + BYT_VAL_REG);
label = gpiochip_is_requested(chip, i);
if (!label)
label = "Unrequested";
seq_printf(s,
" gpio-%-3d %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s\n",
" gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s\n",
i,
label,
val & BYT_INPUT_EN ? " " : "in",
val & BYT_OUTPUT_EN ? " " : "out",
val & BYT_LEVEL ? "hi" : "lo",
......@@ -366,11 +372,33 @@ static void byt_irq_mask(struct irq_data *d)
{
}
static unsigned int byt_irq_startup(struct irq_data *d)
{
struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
if (gpio_lock_as_irq(&vg->chip, irqd_to_hwirq(d)))
dev_err(vg->chip.dev,
"unable to lock HW IRQ %lu for IRQ\n",
irqd_to_hwirq(d));
byt_irq_unmask(d);
return 0;
}
static void byt_irq_shutdown(struct irq_data *d)
{
struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
byt_irq_mask(d);
gpio_unlock_as_irq(&vg->chip, irqd_to_hwirq(d));
}
static struct irq_chip byt_irqchip = {
.name = "BYT-GPIO",
.irq_mask = byt_irq_mask,
.irq_unmask = byt_irq_unmask,
.irq_set_type = byt_irq_type,
.irq_startup = byt_irq_startup,
.irq_shutdown = byt_irq_shutdown,
};
static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
......
......@@ -638,6 +638,13 @@ int imx1_pinctrl_core_probe(struct platform_device *pdev,
return -EINVAL;
}
ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
if (ret) {
pinctrl_unregister(ipctl->pctl);
dev_err(&pdev->dev, "Failed to populate subdevices\n");
return ret;
}
dev_info(&pdev->dev, "initialized IMX pinctrl driver\n");
return 0;
......
/*
* imx25 pinctrl driver.
*
* Copyright 2013 Eukréa Electromatique <denis@eukrea.com>
*
* This driver was mostly copied from the imx51 pinctrl driver which has:
*
* Copyright (C) 2012 Freescale Semiconductor, Inc.
* Copyright (C) 2012 Linaro, Inc.
*
* Author: Denis Carikli <denis@eukrea.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-imx.h"
enum imx25_pads {
MX25_PAD_RESERVE0 = 1,
MX25_PAD_RESERVE1 = 2,
MX25_PAD_A10 = 3,
MX25_PAD_A13 = 4,
MX25_PAD_A14 = 5,
MX25_PAD_A15 = 6,
MX25_PAD_A16 = 7,
MX25_PAD_A17 = 8,
MX25_PAD_A18 = 9,
MX25_PAD_A19 = 10,
MX25_PAD_A20 = 11,
MX25_PAD_A21 = 12,
MX25_PAD_A22 = 13,
MX25_PAD_A23 = 14,
MX25_PAD_A24 = 15,
MX25_PAD_A25 = 16,
MX25_PAD_EB0 = 17,
MX25_PAD_EB1 = 18,
MX25_PAD_OE = 19,
MX25_PAD_CS0 = 20,
MX25_PAD_CS1 = 21,
MX25_PAD_CS4 = 22,
MX25_PAD_CS5 = 23,
MX25_PAD_NF_CE0 = 24,
MX25_PAD_ECB = 25,
MX25_PAD_LBA = 26,
MX25_PAD_BCLK = 27,
MX25_PAD_RW = 28,
MX25_PAD_NFWE_B = 29,
MX25_PAD_NFRE_B = 30,
MX25_PAD_NFALE = 31,
MX25_PAD_NFCLE = 32,
MX25_PAD_NFWP_B = 33,
MX25_PAD_NFRB = 34,
MX25_PAD_D15 = 35,
MX25_PAD_D14 = 36,
MX25_PAD_D13 = 37,
MX25_PAD_D12 = 38,
MX25_PAD_D11 = 39,
MX25_PAD_D10 = 40,
MX25_PAD_D9 = 41,
MX25_PAD_D8 = 42,
MX25_PAD_D7 = 43,
MX25_PAD_D6 = 44,
MX25_PAD_D5 = 45,
MX25_PAD_D4 = 46,
MX25_PAD_D3 = 47,
MX25_PAD_D2 = 48,
MX25_PAD_D1 = 49,
MX25_PAD_D0 = 50,
MX25_PAD_LD0 = 51,
MX25_PAD_LD1 = 52,
MX25_PAD_LD2 = 53,
MX25_PAD_LD3 = 54,
MX25_PAD_LD4 = 55,
MX25_PAD_LD5 = 56,
MX25_PAD_LD6 = 57,
MX25_PAD_LD7 = 58,
MX25_PAD_LD8 = 59,
MX25_PAD_LD9 = 60,
MX25_PAD_LD10 = 61,
MX25_PAD_LD11 = 62,
MX25_PAD_LD12 = 63,
MX25_PAD_LD13 = 64,
MX25_PAD_LD14 = 65,
MX25_PAD_LD15 = 66,
MX25_PAD_HSYNC = 67,
MX25_PAD_VSYNC = 68,
MX25_PAD_LSCLK = 69,
MX25_PAD_OE_ACD = 70,
MX25_PAD_CONTRAST = 71,
MX25_PAD_PWM = 72,
MX25_PAD_CSI_D2 = 73,
MX25_PAD_CSI_D3 = 74,
MX25_PAD_CSI_D4 = 75,
MX25_PAD_CSI_D5 = 76,
MX25_PAD_CSI_D6 = 77,
MX25_PAD_CSI_D7 = 78,
MX25_PAD_CSI_D8 = 79,
MX25_PAD_CSI_D9 = 80,
MX25_PAD_CSI_MCLK = 81,
MX25_PAD_CSI_VSYNC = 82,
MX25_PAD_CSI_HSYNC = 83,
MX25_PAD_CSI_PIXCLK = 84,
MX25_PAD_I2C1_CLK = 85,
MX25_PAD_I2C1_DAT = 86,
MX25_PAD_CSPI1_MOSI = 87,
MX25_PAD_CSPI1_MISO = 88,
MX25_PAD_CSPI1_SS0 = 89,
MX25_PAD_CSPI1_SS1 = 90,
MX25_PAD_CSPI1_SCLK = 91,
MX25_PAD_CSPI1_RDY = 92,
MX25_PAD_UART1_RXD = 93,
MX25_PAD_UART1_TXD = 94,
MX25_PAD_UART1_RTS = 95,
MX25_PAD_UART1_CTS = 96,
MX25_PAD_UART2_RXD = 97,
MX25_PAD_UART2_TXD = 98,
MX25_PAD_UART2_RTS = 99,
MX25_PAD_UART2_CTS = 100,
MX25_PAD_SD1_CMD = 101,
MX25_PAD_SD1_CLK = 102,
MX25_PAD_SD1_DATA0 = 103,
MX25_PAD_SD1_DATA1 = 104,
MX25_PAD_SD1_DATA2 = 105,
MX25_PAD_SD1_DATA3 = 106,
MX25_PAD_KPP_ROW0 = 107,
MX25_PAD_KPP_ROW1 = 108,
MX25_PAD_KPP_ROW2 = 109,
MX25_PAD_KPP_ROW3 = 110,
MX25_PAD_KPP_COL0 = 111,
MX25_PAD_KPP_COL1 = 112,
MX25_PAD_KPP_COL2 = 113,
MX25_PAD_KPP_COL3 = 114,
MX25_PAD_FEC_MDC = 115,
MX25_PAD_FEC_MDIO = 116,
MX25_PAD_FEC_TDATA0 = 117,
MX25_PAD_FEC_TDATA1 = 118,
MX25_PAD_FEC_TX_EN = 119,
MX25_PAD_FEC_RDATA0 = 120,
MX25_PAD_FEC_RDATA1 = 121,
MX25_PAD_FEC_RX_DV = 122,
MX25_PAD_FEC_TX_CLK = 123,
MX25_PAD_RTCK = 124,
MX25_PAD_DE_B = 125,
MX25_PAD_GPIO_A = 126,
MX25_PAD_GPIO_B = 127,
MX25_PAD_GPIO_C = 128,
MX25_PAD_GPIO_D = 129,
MX25_PAD_GPIO_E = 130,
MX25_PAD_GPIO_F = 131,
MX25_PAD_EXT_ARMCLK = 132,
MX25_PAD_UPLL_BYPCLK = 133,
MX25_PAD_VSTBY_REQ = 134,
MX25_PAD_VSTBY_ACK = 135,
MX25_PAD_POWER_FAIL = 136,
MX25_PAD_CLKO = 137,
MX25_PAD_BOOT_MODE0 = 138,
MX25_PAD_BOOT_MODE1 = 139,
};
/* Pad names for the pinmux subsystem */
static const struct pinctrl_pin_desc imx25_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX25_PAD_RESERVE0),
IMX_PINCTRL_PIN(MX25_PAD_RESERVE1),
IMX_PINCTRL_PIN(MX25_PAD_A10),
IMX_PINCTRL_PIN(MX25_PAD_A13),
IMX_PINCTRL_PIN(MX25_PAD_A14),
IMX_PINCTRL_PIN(MX25_PAD_A15),
IMX_PINCTRL_PIN(MX25_PAD_A16),
IMX_PINCTRL_PIN(MX25_PAD_A17),
IMX_PINCTRL_PIN(MX25_PAD_A18),
IMX_PINCTRL_PIN(MX25_PAD_A19),
IMX_PINCTRL_PIN(MX25_PAD_A20),
IMX_PINCTRL_PIN(MX25_PAD_A21),
IMX_PINCTRL_PIN(MX25_PAD_A22),
IMX_PINCTRL_PIN(MX25_PAD_A23),
IMX_PINCTRL_PIN(MX25_PAD_A24),
IMX_PINCTRL_PIN(MX25_PAD_A25),
IMX_PINCTRL_PIN(MX25_PAD_EB0),
IMX_PINCTRL_PIN(MX25_PAD_EB1),
IMX_PINCTRL_PIN(MX25_PAD_OE),
IMX_PINCTRL_PIN(MX25_PAD_CS0),
IMX_PINCTRL_PIN(MX25_PAD_CS1),
IMX_PINCTRL_PIN(MX25_PAD_CS4),
IMX_PINCTRL_PIN(MX25_PAD_CS5),
IMX_PINCTRL_PIN(MX25_PAD_NF_CE0),
IMX_PINCTRL_PIN(MX25_PAD_ECB),
IMX_PINCTRL_PIN(MX25_PAD_LBA),
IMX_PINCTRL_PIN(MX25_PAD_BCLK),
IMX_PINCTRL_PIN(MX25_PAD_RW),
IMX_PINCTRL_PIN(MX25_PAD_NFWE_B),
IMX_PINCTRL_PIN(MX25_PAD_NFRE_B),
IMX_PINCTRL_PIN(MX25_PAD_NFALE),
IMX_PINCTRL_PIN(MX25_PAD_NFCLE),
IMX_PINCTRL_PIN(MX25_PAD_NFWP_B),
IMX_PINCTRL_PIN(MX25_PAD_NFRB),
IMX_PINCTRL_PIN(MX25_PAD_D15),
IMX_PINCTRL_PIN(MX25_PAD_D14),
IMX_PINCTRL_PIN(MX25_PAD_D13),
IMX_PINCTRL_PIN(MX25_PAD_D12),
IMX_PINCTRL_PIN(MX25_PAD_D11),
IMX_PINCTRL_PIN(MX25_PAD_D10),
IMX_PINCTRL_PIN(MX25_PAD_D9),
IMX_PINCTRL_PIN(MX25_PAD_D8),
IMX_PINCTRL_PIN(MX25_PAD_D7),
IMX_PINCTRL_PIN(MX25_PAD_D6),
IMX_PINCTRL_PIN(MX25_PAD_D5),
IMX_PINCTRL_PIN(MX25_PAD_D4),
IMX_PINCTRL_PIN(MX25_PAD_D3),
IMX_PINCTRL_PIN(MX25_PAD_D2),
IMX_PINCTRL_PIN(MX25_PAD_D1),
IMX_PINCTRL_PIN(MX25_PAD_D0),
IMX_PINCTRL_PIN(MX25_PAD_LD0),
IMX_PINCTRL_PIN(MX25_PAD_LD1),
IMX_PINCTRL_PIN(MX25_PAD_LD2),
IMX_PINCTRL_PIN(MX25_PAD_LD3),
IMX_PINCTRL_PIN(MX25_PAD_LD4),
IMX_PINCTRL_PIN(MX25_PAD_LD5),
IMX_PINCTRL_PIN(MX25_PAD_LD6),
IMX_PINCTRL_PIN(MX25_PAD_LD7),
IMX_PINCTRL_PIN(MX25_PAD_LD8),
IMX_PINCTRL_PIN(MX25_PAD_LD9),
IMX_PINCTRL_PIN(MX25_PAD_LD10),
IMX_PINCTRL_PIN(MX25_PAD_LD11),
IMX_PINCTRL_PIN(MX25_PAD_LD12),
IMX_PINCTRL_PIN(MX25_PAD_LD13),
IMX_PINCTRL_PIN(MX25_PAD_LD14),
IMX_PINCTRL_PIN(MX25_PAD_LD15),
IMX_PINCTRL_PIN(MX25_PAD_HSYNC),
IMX_PINCTRL_PIN(MX25_PAD_VSYNC),
IMX_PINCTRL_PIN(MX25_PAD_LSCLK),
IMX_PINCTRL_PIN(MX25_PAD_OE_ACD),
IMX_PINCTRL_PIN(MX25_PAD_CONTRAST),
IMX_PINCTRL_PIN(MX25_PAD_PWM),
IMX_PINCTRL_PIN(MX25_PAD_CSI_D2),
IMX_PINCTRL_PIN(MX25_PAD_CSI_D3),
IMX_PINCTRL_PIN(MX25_PAD_CSI_D4),
IMX_PINCTRL_PIN(MX25_PAD_CSI_D5),
IMX_PINCTRL_PIN(MX25_PAD_CSI_D6),
IMX_PINCTRL_PIN(MX25_PAD_CSI_D7),
IMX_PINCTRL_PIN(MX25_PAD_CSI_D8),
IMX_PINCTRL_PIN(MX25_PAD_CSI_D9),
IMX_PINCTRL_PIN(MX25_PAD_CSI_MCLK),
IMX_PINCTRL_PIN(MX25_PAD_CSI_VSYNC),
IMX_PINCTRL_PIN(MX25_PAD_CSI_HSYNC),
IMX_PINCTRL_PIN(MX25_PAD_CSI_PIXCLK),
IMX_PINCTRL_PIN(MX25_PAD_I2C1_CLK),
IMX_PINCTRL_PIN(MX25_PAD_I2C1_DAT),
IMX_PINCTRL_PIN(MX25_PAD_CSPI1_MOSI),
IMX_PINCTRL_PIN(MX25_PAD_CSPI1_MISO),
IMX_PINCTRL_PIN(MX25_PAD_CSPI1_SS0),
IMX_PINCTRL_PIN(MX25_PAD_CSPI1_SS1),
IMX_PINCTRL_PIN(MX25_PAD_CSPI1_SCLK),
IMX_PINCTRL_PIN(MX25_PAD_CSPI1_RDY),
IMX_PINCTRL_PIN(MX25_PAD_UART1_RXD),
IMX_PINCTRL_PIN(MX25_PAD_UART1_TXD),
IMX_PINCTRL_PIN(MX25_PAD_UART1_RTS),
IMX_PINCTRL_PIN(MX25_PAD_UART1_CTS),
IMX_PINCTRL_PIN(MX25_PAD_UART2_RXD),
IMX_PINCTRL_PIN(MX25_PAD_UART2_TXD),
IMX_PINCTRL_PIN(MX25_PAD_UART2_RTS),
IMX_PINCTRL_PIN(MX25_PAD_UART2_CTS),
IMX_PINCTRL_PIN(MX25_PAD_SD1_CMD),
IMX_PINCTRL_PIN(MX25_PAD_SD1_CLK),
IMX_PINCTRL_PIN(MX25_PAD_SD1_DATA0),
IMX_PINCTRL_PIN(MX25_PAD_SD1_DATA1),
IMX_PINCTRL_PIN(MX25_PAD_SD1_DATA2),
IMX_PINCTRL_PIN(MX25_PAD_SD1_DATA3),
IMX_PINCTRL_PIN(MX25_PAD_KPP_ROW0),
IMX_PINCTRL_PIN(MX25_PAD_KPP_ROW1),
IMX_PINCTRL_PIN(MX25_PAD_KPP_ROW2),
IMX_PINCTRL_PIN(MX25_PAD_KPP_ROW3),
IMX_PINCTRL_PIN(MX25_PAD_KPP_COL0),
IMX_PINCTRL_PIN(MX25_PAD_KPP_COL1),
IMX_PINCTRL_PIN(MX25_PAD_KPP_COL2),
IMX_PINCTRL_PIN(MX25_PAD_KPP_COL3),
IMX_PINCTRL_PIN(MX25_PAD_FEC_MDC),
IMX_PINCTRL_PIN(MX25_PAD_FEC_MDIO),
IMX_PINCTRL_PIN(MX25_PAD_FEC_TDATA0),
IMX_PINCTRL_PIN(MX25_PAD_FEC_TDATA1),
IMX_PINCTRL_PIN(MX25_PAD_FEC_TX_EN),
IMX_PINCTRL_PIN(MX25_PAD_FEC_RDATA0),
IMX_PINCTRL_PIN(MX25_PAD_FEC_RDATA1),
IMX_PINCTRL_PIN(MX25_PAD_FEC_RX_DV),
IMX_PINCTRL_PIN(MX25_PAD_FEC_TX_CLK),
IMX_PINCTRL_PIN(MX25_PAD_RTCK),
IMX_PINCTRL_PIN(MX25_PAD_DE_B),
IMX_PINCTRL_PIN(MX25_PAD_GPIO_A),
IMX_PINCTRL_PIN(MX25_PAD_GPIO_B),
IMX_PINCTRL_PIN(MX25_PAD_GPIO_C),
IMX_PINCTRL_PIN(MX25_PAD_GPIO_D),
IMX_PINCTRL_PIN(MX25_PAD_GPIO_E),
IMX_PINCTRL_PIN(MX25_PAD_GPIO_F),
IMX_PINCTRL_PIN(MX25_PAD_EXT_ARMCLK),
IMX_PINCTRL_PIN(MX25_PAD_UPLL_BYPCLK),
IMX_PINCTRL_PIN(MX25_PAD_VSTBY_REQ),
IMX_PINCTRL_PIN(MX25_PAD_VSTBY_ACK),
IMX_PINCTRL_PIN(MX25_PAD_POWER_FAIL),
IMX_PINCTRL_PIN(MX25_PAD_CLKO),
IMX_PINCTRL_PIN(MX25_PAD_BOOT_MODE0),
IMX_PINCTRL_PIN(MX25_PAD_BOOT_MODE1),
};
static struct imx_pinctrl_soc_info imx25_pinctrl_info = {
.pins = imx25_pinctrl_pads,
.npins = ARRAY_SIZE(imx25_pinctrl_pads),
};
static struct of_device_id imx25_pinctrl_of_match[] = {
{ .compatible = "fsl,imx25-iomuxc", },
{ /* sentinel */ }
};
static int imx25_pinctrl_probe(struct platform_device *pdev)
{
return imx_pinctrl_probe(pdev, &imx25_pinctrl_info);
}
static struct platform_driver imx25_pinctrl_driver = {
.driver = {
.name = "imx25-pinctrl",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(imx25_pinctrl_of_match),
},
.probe = imx25_pinctrl_probe,
.remove = imx_pinctrl_remove,
};
static int __init imx25_pinctrl_init(void)
{
return platform_driver_register(&imx25_pinctrl_driver);
}
arch_initcall(imx25_pinctrl_init);
static void __exit imx25_pinctrl_exit(void)
{
platform_driver_unregister(&imx25_pinctrl_driver);
}
module_exit(imx25_pinctrl_exit);
MODULE_AUTHOR("Denis Carikli <denis@eukrea.com>");
MODULE_DESCRIPTION("Freescale IMX25 pinctrl driver");
MODULE_LICENSE("GPL v2");
/*
* Copyright (c) 2013, Sony Mobile Communications AB.
* Copyright (c) 2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/err.h>
#include <linux/irqdomain.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/of_irq.h>
#include <linux/spinlock.h>
#include "core.h"
#include "pinconf.h"
#include "pinctrl-msm.h"
#include "pinctrl-utils.h"
/**
* struct msm_pinctrl - state for a pinctrl-msm device
* @dev: device handle.
* @pctrl: pinctrl handle.
* @domain: irqdomain handle.
* @chip: gpiochip handle.
* @irq: parent irq for the TLMM irq_chip.
* @lock: Spinlock to protect register resources as well
* as msm_pinctrl data structures.
* @enabled_irqs: Bitmap of currently enabled irqs.
* @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge
* detection.
* @wake_irqs: Bitmap of irqs with requested as wakeup source.
* @soc; Reference to soc_data of platform specific data.
* @regs: Base address for the TLMM register map.
*/
struct msm_pinctrl {
struct device *dev;
struct pinctrl_dev *pctrl;
struct irq_domain *domain;
struct gpio_chip chip;
unsigned irq;
spinlock_t lock;
unsigned long *enabled_irqs;
unsigned long *dual_edge_irqs;
unsigned long *wake_irqs;
const struct msm_pinctrl_soc_data *soc;
void __iomem *regs;
};
static int msm_get_groups_count(struct pinctrl_dev *pctldev)
{
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
return pctrl->soc->ngroups;
}
static const char *msm_get_group_name(struct pinctrl_dev *pctldev,
unsigned group)
{
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
return pctrl->soc->groups[group].name;
}
static int msm_get_group_pins(struct pinctrl_dev *pctldev,
unsigned group,
const unsigned **pins,
unsigned *num_pins)
{
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
*pins = pctrl->soc->groups[group].pins;
*num_pins = pctrl->soc->groups[group].npins;
return 0;
}
static struct pinctrl_ops msm_pinctrl_ops = {
.get_groups_count = msm_get_groups_count,
.get_group_name = msm_get_group_name,
.get_group_pins = msm_get_group_pins,
.dt_node_to_map = pinconf_generic_dt_node_to_map_group,
.dt_free_map = pinctrl_utils_dt_free_map,
};
static int msm_get_functions_count(struct pinctrl_dev *pctldev)
{
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
return pctrl->soc->nfunctions;
}
static const char *msm_get_function_name(struct pinctrl_dev *pctldev,
unsigned function)
{
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
return pctrl->soc->functions[function].name;
}
static int msm_get_function_groups(struct pinctrl_dev *pctldev,
unsigned function,
const char * const **groups,
unsigned * const num_groups)
{
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
*groups = pctrl->soc->functions[function].groups;
*num_groups = pctrl->soc->functions[function].ngroups;
return 0;
}
static int msm_pinmux_enable(struct pinctrl_dev *pctldev,
unsigned function,
unsigned group)
{
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
const struct msm_pingroup *g;
unsigned long flags;
u32 val;
int i;
g = &pctrl->soc->groups[group];
if (WARN_ON(g->mux_bit < 0))
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(g->funcs); i++) {
if (g->funcs[i] == function)
break;
}
if (WARN_ON(i == ARRAY_SIZE(g->funcs)))
return -EINVAL;
spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->ctl_reg);
val &= ~(0x7 << g->mux_bit);
val |= i << g->mux_bit;
writel(val, pctrl->regs + g->ctl_reg);
spin_unlock_irqrestore(&pctrl->lock, flags);
return 0;
}
static void msm_pinmux_disable(struct pinctrl_dev *pctldev,
unsigned function,
unsigned group)
{
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
const struct msm_pingroup *g;
unsigned long flags;
u32 val;
g = &pctrl->soc->groups[group];
if (WARN_ON(g->mux_bit < 0))
return;
spin_lock_irqsave(&pctrl->lock, flags);
/* Clear the mux bits to select gpio mode */
val = readl(pctrl->regs + g->ctl_reg);
val &= ~(0x7 << g->mux_bit);
writel(val, pctrl->regs + g->ctl_reg);
spin_unlock_irqrestore(&pctrl->lock, flags);
}
static struct pinmux_ops msm_pinmux_ops = {
.get_functions_count = msm_get_functions_count,
.get_function_name = msm_get_function_name,
.get_function_groups = msm_get_function_groups,
.enable = msm_pinmux_enable,
.disable = msm_pinmux_disable,
};
static int msm_config_reg(struct msm_pinctrl *pctrl,
const struct msm_pingroup *g,
unsigned param,
unsigned *reg,
unsigned *mask,
unsigned *bit)
{
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
*reg = g->ctl_reg;
*bit = g->pull_bit;
*mask = 3;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
*reg = g->ctl_reg;
*bit = g->pull_bit;
*mask = 3;
break;
case PIN_CONFIG_BIAS_PULL_UP:
*reg = g->ctl_reg;
*bit = g->pull_bit;
*mask = 3;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
*reg = g->ctl_reg;
*bit = g->drv_bit;
*mask = 7;
break;
default:
dev_err(pctrl->dev, "Invalid config param %04x\n", param);
return -ENOTSUPP;
}
if (*reg < 0) {
dev_err(pctrl->dev, "Config param %04x not supported on group %s\n",
param, g->name);
return -ENOTSUPP;
}
return 0;
}
static int msm_config_get(struct pinctrl_dev *pctldev,
unsigned int pin,
unsigned long *config)
{
dev_err(pctldev->dev, "pin_config_set op not supported\n");
return -ENOTSUPP;
}
static int msm_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned num_configs)
{
dev_err(pctldev->dev, "pin_config_set op not supported\n");
return -ENOTSUPP;
}
#define MSM_NO_PULL 0
#define MSM_PULL_DOWN 1
#define MSM_PULL_UP 3
static const unsigned msm_regval_to_drive[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
static const unsigned msm_drive_to_regval[] = { -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, 6, -1, 7 };
static int msm_config_group_get(struct pinctrl_dev *pctldev,
unsigned int group,
unsigned long *config)
{
const struct msm_pingroup *g;
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
unsigned param = pinconf_to_config_param(*config);
unsigned mask;
unsigned arg;
unsigned bit;
unsigned reg;
int ret;
u32 val;
g = &pctrl->soc->groups[group];
ret = msm_config_reg(pctrl, g, param, &reg, &mask, &bit);
if (ret < 0)
return ret;
val = readl(pctrl->regs + reg);
arg = (val >> bit) & mask;
/* Convert register value to pinconf value */
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
arg = arg == MSM_NO_PULL;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
arg = arg == MSM_PULL_DOWN;
break;
case PIN_CONFIG_BIAS_PULL_UP:
arg = arg == MSM_PULL_UP;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
arg = msm_regval_to_drive[arg];
break;
default:
dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
param);
return -EINVAL;
}
*config = pinconf_to_config_packed(param, arg);
return 0;
}
static int msm_config_group_set(struct pinctrl_dev *pctldev,
unsigned group,
unsigned long *configs,
unsigned num_configs)
{
const struct msm_pingroup *g;
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
unsigned long flags;
unsigned param;
unsigned mask;
unsigned arg;
unsigned bit;
unsigned reg;
int ret;
u32 val;
int i;
g = &pctrl->soc->groups[group];
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
ret = msm_config_reg(pctrl, g, param, &reg, &mask, &bit);
if (ret < 0)
return ret;
/* Convert pinconf values to register values */
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
arg = MSM_NO_PULL;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
arg = MSM_PULL_DOWN;
break;
case PIN_CONFIG_BIAS_PULL_UP:
arg = MSM_PULL_UP;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
/* Check for invalid values */
if (arg > ARRAY_SIZE(msm_drive_to_regval))
arg = -1;
else
arg = msm_drive_to_regval[arg];
break;
default:
dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
param);
return -EINVAL;
}
/* Range-check user-supplied value */
if (arg & ~mask) {
dev_err(pctrl->dev, "config %x: %x is invalid\n", param, arg);
return -EINVAL;
}
spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + reg);
val &= ~(mask << bit);
val |= arg << bit;
writel(val, pctrl->regs + reg);
spin_unlock_irqrestore(&pctrl->lock, flags);
}
return 0;
}
static struct pinconf_ops msm_pinconf_ops = {
.pin_config_get = msm_config_get,
.pin_config_set = msm_config_set,
.pin_config_group_get = msm_config_group_get,
.pin_config_group_set = msm_config_group_set,
};
static struct pinctrl_desc msm_pinctrl_desc = {
.pctlops = &msm_pinctrl_ops,
.pmxops = &msm_pinmux_ops,
.confops = &msm_pinconf_ops,
.owner = THIS_MODULE,
};
static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
const struct msm_pingroup *g;
struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
unsigned long flags;
u32 val;
if (WARN_ON(offset >= pctrl->soc->ngroups))
return -EINVAL;
g = &pctrl->soc->groups[offset];
if (WARN_ON(g->oe_bit < 0))
return -EINVAL;
spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->ctl_reg);
val &= ~BIT(g->oe_bit);
writel(val, pctrl->regs + g->ctl_reg);
spin_unlock_irqrestore(&pctrl->lock, flags);
return 0;
}
static int msm_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value)
{
const struct msm_pingroup *g;
struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
unsigned long flags;
u32 val;
if (WARN_ON(offset >= pctrl->soc->ngroups))
return -EINVAL;
g = &pctrl->soc->groups[offset];
if (WARN_ON(g->oe_bit < 0))
return -EINVAL;
spin_lock_irqsave(&pctrl->lock, flags);
writel(value ? BIT(g->out_bit) : 0, pctrl->regs + g->io_reg);
val = readl(pctrl->regs + g->ctl_reg);
val |= BIT(g->oe_bit);
writel(val, pctrl->regs + g->ctl_reg);
spin_unlock_irqrestore(&pctrl->lock, flags);
return 0;
}
static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
{
const struct msm_pingroup *g;
struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
u32 val;
if (WARN_ON(offset >= pctrl->soc->ngroups))
return -EINVAL;
g = &pctrl->soc->groups[offset];
val = readl(pctrl->regs + g->io_reg);
return !!(val & BIT(g->in_bit));
}
static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
const struct msm_pingroup *g;
struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
unsigned long flags;
u32 val;
if (WARN_ON(offset >= pctrl->soc->ngroups))
return;
g = &pctrl->soc->groups[offset];
spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->io_reg);
val |= BIT(g->out_bit);
writel(val, pctrl->regs + g->io_reg);
spin_unlock_irqrestore(&pctrl->lock, flags);
}
static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
return irq_find_mapping(pctrl->domain, offset);
}
static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
{
int gpio = chip->base + offset;
return pinctrl_request_gpio(gpio);
}
static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
{
int gpio = chip->base + offset;
return pinctrl_free_gpio(gpio);
}
#ifdef CONFIG_DEBUG_FS
#include <linux/seq_file.h>
static void msm_gpio_dbg_show_one(struct seq_file *s,
struct pinctrl_dev *pctldev,
struct gpio_chip *chip,
unsigned offset,
unsigned gpio)
{
const struct msm_pingroup *g;
struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
unsigned func;
int is_out;
int drive;
int pull;
u32 ctl_reg;
const char *pulls[] = {
"no pull",
"pull down",
"keeper",
"pull up"
};
g = &pctrl->soc->groups[offset];
ctl_reg = readl(pctrl->regs + g->ctl_reg);
is_out = !!(ctl_reg & BIT(g->oe_bit));
func = (ctl_reg >> g->mux_bit) & 7;
drive = (ctl_reg >> g->drv_bit) & 7;
pull = (ctl_reg >> g->pull_bit) & 3;
seq_printf(s, " %-8s: %-3s %d", g->name, is_out ? "out" : "in", func);
seq_printf(s, " %dmA", msm_regval_to_drive[drive]);
seq_printf(s, " %s", pulls[pull]);
}
static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
{
unsigned gpio = chip->base;
unsigned i;
for (i = 0; i < chip->ngpio; i++, gpio++) {
msm_gpio_dbg_show_one(s, NULL, chip, i, gpio);
seq_printf(s, "\n");
}
}
#else
#define msm_gpio_dbg_show NULL
#endif
static struct gpio_chip msm_gpio_template = {
.direction_input = msm_gpio_direction_input,
.direction_output = msm_gpio_direction_output,
.get = msm_gpio_get,
.set = msm_gpio_set,
.to_irq = msm_gpio_to_irq,
.request = msm_gpio_request,
.free = msm_gpio_free,
.dbg_show = msm_gpio_dbg_show,
};
/* For dual-edge interrupts in software, since some hardware has no
* such support:
*
* At appropriate moments, this function may be called to flip the polarity
* settings of both-edge irq lines to try and catch the next edge.
*
* The attempt is considered successful if:
* - the status bit goes high, indicating that an edge was caught, or
* - the input value of the gpio doesn't change during the attempt.
* If the value changes twice during the process, that would cause the first
* test to fail but would force the second, as two opposite
* transitions would cause a detection no matter the polarity setting.
*
* The do-loop tries to sledge-hammer closed the timing hole between
* the initial value-read and the polarity-write - if the line value changes
* during that window, an interrupt is lost, the new polarity setting is
* incorrect, and the first success test will fail, causing a retry.
*
* Algorithm comes from Google's msmgpio driver.
*/
static void msm_gpio_update_dual_edge_pos(struct msm_pinctrl *pctrl,
const struct msm_pingroup *g,
struct irq_data *d)
{
int loop_limit = 100;
unsigned val, val2, intstat;
unsigned pol;
do {
val = readl(pctrl->regs + g->io_reg) & BIT(g->in_bit);
pol = readl(pctrl->regs + g->intr_cfg_reg);
pol ^= BIT(g->intr_polarity_bit);
writel(pol, pctrl->regs + g->intr_cfg_reg);
val2 = readl(pctrl->regs + g->io_reg) & BIT(g->in_bit);
intstat = readl(pctrl->regs + g->intr_status_reg);
if (intstat || (val == val2))
return;
} while (loop_limit-- > 0);
dev_err(pctrl->dev, "dual-edge irq failed to stabilize, %#08x != %#08x\n",
val, val2);
}
static void msm_gpio_irq_mask(struct irq_data *d)
{
const struct msm_pingroup *g;
struct msm_pinctrl *pctrl;
unsigned long flags;
u32 val;
pctrl = irq_data_get_irq_chip_data(d);
if (!pctrl)
return;
if (WARN_ON(d->hwirq >= pctrl->soc->ngroups))
return;
g = &pctrl->soc->groups[d->hwirq];
spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->intr_cfg_reg);
val &= ~BIT(g->intr_enable_bit);
writel(val, pctrl->regs + g->intr_cfg_reg);
clear_bit(d->hwirq, pctrl->enabled_irqs);
spin_unlock_irqrestore(&pctrl->lock, flags);
}
static void msm_gpio_irq_unmask(struct irq_data *d)
{
const struct msm_pingroup *g;
struct msm_pinctrl *pctrl;
unsigned long flags;
u32 val;
pctrl = irq_data_get_irq_chip_data(d);
if (!pctrl)
return;
if (WARN_ON(d->hwirq >= pctrl->soc->ngroups))
return;
g = &pctrl->soc->groups[d->hwirq];
spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->intr_status_reg);
val &= ~BIT(g->intr_status_bit);
writel(val, pctrl->regs + g->intr_status_reg);
val = readl(pctrl->regs + g->intr_cfg_reg);
val |= BIT(g->intr_enable_bit);
writel(val, pctrl->regs + g->intr_cfg_reg);
set_bit(d->hwirq, pctrl->enabled_irqs);
spin_unlock_irqrestore(&pctrl->lock, flags);
}
static void msm_gpio_irq_ack(struct irq_data *d)
{
const struct msm_pingroup *g;
struct msm_pinctrl *pctrl;
unsigned long flags;
u32 val;
pctrl = irq_data_get_irq_chip_data(d);
if (!pctrl)
return;
if (WARN_ON(d->hwirq >= pctrl->soc->ngroups))
return;
g = &pctrl->soc->groups[d->hwirq];
spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->intr_status_reg);
val &= ~BIT(g->intr_status_bit);
writel(val, pctrl->regs + g->intr_status_reg);
if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
msm_gpio_update_dual_edge_pos(pctrl, g, d);
spin_unlock_irqrestore(&pctrl->lock, flags);
}
#define INTR_TARGET_PROC_APPS 4
static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{
const struct msm_pingroup *g;
struct msm_pinctrl *pctrl;
unsigned long flags;
u32 val;
pctrl = irq_data_get_irq_chip_data(d);
if (!pctrl)
return -EINVAL;
if (WARN_ON(d->hwirq >= pctrl->soc->ngroups))
return -EINVAL;
g = &pctrl->soc->groups[d->hwirq];
spin_lock_irqsave(&pctrl->lock, flags);
/*
* For hw without possibility of detecting both edges
*/
if (g->intr_detection_width == 1 && type == IRQ_TYPE_EDGE_BOTH)
set_bit(d->hwirq, pctrl->dual_edge_irqs);
else
clear_bit(d->hwirq, pctrl->dual_edge_irqs);
/* Route interrupts to application cpu */
val = readl(pctrl->regs + g->intr_target_reg);
val &= ~(7 << g->intr_target_bit);
val |= INTR_TARGET_PROC_APPS << g->intr_target_bit;
writel(val, pctrl->regs + g->intr_target_reg);
/* Update configuration for gpio.
* RAW_STATUS_EN is left on for all gpio irqs. Due to the
* internal circuitry of TLMM, toggling the RAW_STATUS
* could cause the INTR_STATUS to be set for EDGE interrupts.
*/
val = readl(pctrl->regs + g->intr_cfg_reg);
val |= BIT(g->intr_raw_status_bit);
if (g->intr_detection_width == 2) {
val &= ~(3 << g->intr_detection_bit);
val &= ~(1 << g->intr_polarity_bit);
switch (type) {
case IRQ_TYPE_EDGE_RISING:
val |= 1 << g->intr_detection_bit;
val |= BIT(g->intr_polarity_bit);
break;
case IRQ_TYPE_EDGE_FALLING:
val |= 2 << g->intr_detection_bit;
val |= BIT(g->intr_polarity_bit);
break;
case IRQ_TYPE_EDGE_BOTH:
val |= 3 << g->intr_detection_bit;
val |= BIT(g->intr_polarity_bit);
break;
case IRQ_TYPE_LEVEL_LOW:
break;
case IRQ_TYPE_LEVEL_HIGH:
val |= BIT(g->intr_polarity_bit);
break;
}
} else if (g->intr_detection_width == 1) {
val &= ~(1 << g->intr_detection_bit);
val &= ~(1 << g->intr_polarity_bit);
switch (type) {
case IRQ_TYPE_EDGE_RISING:
val |= BIT(g->intr_detection_bit);
val |= BIT(g->intr_polarity_bit);
break;
case IRQ_TYPE_EDGE_FALLING:
val |= BIT(g->intr_detection_bit);
break;
case IRQ_TYPE_EDGE_BOTH:
val |= BIT(g->intr_detection_bit);
break;
case IRQ_TYPE_LEVEL_LOW:
break;
case IRQ_TYPE_LEVEL_HIGH:
val |= BIT(g->intr_polarity_bit);
break;
}
} else {
BUG();
}
writel(val, pctrl->regs + g->intr_cfg_reg);
if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
msm_gpio_update_dual_edge_pos(pctrl, g, d);
spin_unlock_irqrestore(&pctrl->lock, flags);
if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
__irq_set_handler_locked(d->irq, handle_level_irq);
else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
__irq_set_handler_locked(d->irq, handle_edge_irq);
return 0;
}
static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
{
struct msm_pinctrl *pctrl;
unsigned long flags;
unsigned ngpio;
pctrl = irq_data_get_irq_chip_data(d);
if (!pctrl)
return -EINVAL;
ngpio = pctrl->chip.ngpio;
spin_lock_irqsave(&pctrl->lock, flags);
if (on) {
if (bitmap_empty(pctrl->wake_irqs, ngpio))
enable_irq_wake(pctrl->irq);
set_bit(d->hwirq, pctrl->wake_irqs);
} else {
clear_bit(d->hwirq, pctrl->wake_irqs);
if (bitmap_empty(pctrl->wake_irqs, ngpio))
disable_irq_wake(pctrl->irq);
}
spin_unlock_irqrestore(&pctrl->lock, flags);
return 0;
}
static unsigned int msm_gpio_irq_startup(struct irq_data *d)
{
struct msm_pinctrl *pctrl = irq_data_get_irq_chip_data(d);
if (gpio_lock_as_irq(&pctrl->chip, d->hwirq)) {
dev_err(pctrl->dev, "unable to lock HW IRQ %lu for IRQ\n",
d->hwirq);
}
msm_gpio_irq_unmask(d);
return 0;
}
static void msm_gpio_irq_shutdown(struct irq_data *d)
{
struct msm_pinctrl *pctrl = irq_data_get_irq_chip_data(d);
msm_gpio_irq_mask(d);
gpio_unlock_as_irq(&pctrl->chip, d->hwirq);
}
static struct irq_chip msm_gpio_irq_chip = {
.name = "msmgpio",
.irq_mask = msm_gpio_irq_mask,
.irq_unmask = msm_gpio_irq_unmask,
.irq_ack = msm_gpio_irq_ack,
.irq_set_type = msm_gpio_irq_set_type,
.irq_set_wake = msm_gpio_irq_set_wake,
.irq_startup = msm_gpio_irq_startup,
.irq_shutdown = msm_gpio_irq_shutdown,
};
static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
const struct msm_pingroup *g;
struct msm_pinctrl *pctrl = irq_desc_get_handler_data(desc);
struct irq_chip *chip = irq_get_chip(irq);
int irq_pin;
int handled = 0;
u32 val;
int i;
chained_irq_enter(chip, desc);
/*
* Each pin have it's own IRQ status register, so use
* enabled_irq bitmap to limit the number of reads.
*/
for_each_set_bit(i, pctrl->enabled_irqs, pctrl->chip.ngpio) {
g = &pctrl->soc->groups[i];
val = readl(pctrl->regs + g->intr_status_reg);
if (val & BIT(g->intr_status_bit)) {
irq_pin = irq_find_mapping(pctrl->domain, i);
generic_handle_irq(irq_pin);
handled++;
}
}
/* No interrutps where flagged */
if (handled == 0)
handle_bad_irq(irq, desc);
chained_irq_exit(chip, desc);
}
static int msm_gpio_init(struct msm_pinctrl *pctrl)
{
struct gpio_chip *chip;
int irq;
int ret;
int i;
int r;
chip = &pctrl->chip;
chip->base = 0;
chip->ngpio = pctrl->soc->ngpios;
chip->label = dev_name(pctrl->dev);
chip->dev = pctrl->dev;
chip->owner = THIS_MODULE;
chip->of_node = pctrl->dev->of_node;
pctrl->enabled_irqs = devm_kzalloc(pctrl->dev,
sizeof(unsigned long) * BITS_TO_LONGS(chip->ngpio),
GFP_KERNEL);
if (!pctrl->enabled_irqs) {
dev_err(pctrl->dev, "Failed to allocate enabled_irqs bitmap\n");
return -ENOMEM;
}
pctrl->dual_edge_irqs = devm_kzalloc(pctrl->dev,
sizeof(unsigned long) * BITS_TO_LONGS(chip->ngpio),
GFP_KERNEL);
if (!pctrl->dual_edge_irqs) {
dev_err(pctrl->dev, "Failed to allocate dual_edge_irqs bitmap\n");
return -ENOMEM;
}
pctrl->wake_irqs = devm_kzalloc(pctrl->dev,
sizeof(unsigned long) * BITS_TO_LONGS(chip->ngpio),
GFP_KERNEL);
if (!pctrl->wake_irqs) {
dev_err(pctrl->dev, "Failed to allocate wake_irqs bitmap\n");
return -ENOMEM;
}
ret = gpiochip_add(&pctrl->chip);
if (ret) {
dev_err(pctrl->dev, "Failed register gpiochip\n");
return ret;
}
ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev), 0, 0, chip->ngpio);
if (ret) {
dev_err(pctrl->dev, "Failed to add pin range\n");
return ret;
}
pctrl->domain = irq_domain_add_linear(pctrl->dev->of_node, chip->ngpio,
&irq_domain_simple_ops, NULL);
if (!pctrl->domain) {
dev_err(pctrl->dev, "Failed to register irq domain\n");
r = gpiochip_remove(&pctrl->chip);
return -ENOSYS;
}
for (i = 0; i < chip->ngpio; i++) {
irq = irq_create_mapping(pctrl->domain, i);
irq_set_chip_and_handler(irq, &msm_gpio_irq_chip, handle_edge_irq);
irq_set_chip_data(irq, pctrl);
}
irq_set_handler_data(pctrl->irq, pctrl);
irq_set_chained_handler(pctrl->irq, msm_gpio_irq_handler);
return 0;
}
int msm_pinctrl_probe(struct platform_device *pdev,
const struct msm_pinctrl_soc_data *soc_data)
{
struct msm_pinctrl *pctrl;
struct resource *res;
int ret;
pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
if (!pctrl) {
dev_err(&pdev->dev, "Can't allocate msm_pinctrl\n");
return -ENOMEM;
}
pctrl->dev = &pdev->dev;
pctrl->soc = soc_data;
pctrl->chip = msm_gpio_template;
spin_lock_init(&pctrl->lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pctrl->regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(pctrl->regs))
return PTR_ERR(pctrl->regs);
pctrl->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
if (pctrl->irq < 0) {
dev_err(&pdev->dev, "No interrupt defined for msmgpio\n");
return pctrl->irq;
}
msm_pinctrl_desc.name = dev_name(&pdev->dev);
msm_pinctrl_desc.pins = pctrl->soc->pins;
msm_pinctrl_desc.npins = pctrl->soc->npins;
pctrl->pctrl = pinctrl_register(&msm_pinctrl_desc, &pdev->dev, pctrl);
if (!pctrl->pctrl) {
dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
return -ENODEV;
}
ret = msm_gpio_init(pctrl);
if (ret) {
pinctrl_unregister(pctrl->pctrl);
return ret;
}
platform_set_drvdata(pdev, pctrl);
dev_dbg(&pdev->dev, "Probed Qualcomm pinctrl driver\n");
return 0;
}
EXPORT_SYMBOL(msm_pinctrl_probe);
int msm_pinctrl_remove(struct platform_device *pdev)
{
struct msm_pinctrl *pctrl = platform_get_drvdata(pdev);
int ret;
irq_set_chained_handler(pctrl->irq, NULL);
irq_domain_remove(pctrl->domain);
ret = gpiochip_remove(&pctrl->chip);
pinctrl_unregister(pctrl->pctrl);
return 0;
}
EXPORT_SYMBOL(msm_pinctrl_remove);
/*
* Copyright (c) 2013, Sony Mobile Communications AB.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __PINCTRL_MSM_H__
#define __PINCTRL_MSM_H__
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/machine.h>
/**
* struct msm_function - a pinmux function
* @name: Name of the pinmux function.
* @groups: List of pingroups for this function.
* @ngroups: Number of entries in @groups.
*/
struct msm_function {
const char *name;
const char * const *groups;
unsigned ngroups;
};
/**
* struct msm_pingroup - Qualcomm pingroup definition
* @name: Name of the pingroup.
* @pins: A list of pins assigned to this pingroup.
* @npins: Number of entries in @pins.
* @funcs: A list of pinmux functions that can be selected for
* this group. The index of the selected function is used
* for programming the function selector.
* Entries should be indices into the groups list of the
* struct msm_pinctrl_soc_data.
* @ctl_reg: Offset of the register holding control bits for this group.
* @io_reg: Offset of the register holding input/output bits for this group.
* @intr_cfg_reg: Offset of the register holding interrupt configuration bits.
* @intr_status_reg: Offset of the register holding the status bits for this group.
* @intr_target_reg: Offset of the register specifying routing of the interrupts
* from this group.
* @mux_bit: Offset in @ctl_reg for the pinmux function selection.
* @pull_bit: Offset in @ctl_reg for the bias configuration.
* @drv_bit: Offset in @ctl_reg for the drive strength configuration.
* @oe_bit: Offset in @ctl_reg for controlling output enable.
* @in_bit: Offset in @io_reg for the input bit value.
* @out_bit: Offset in @io_reg for the output bit value.
* @intr_enable_bit: Offset in @intr_cfg_reg for enabling the interrupt for this group.
* @intr_status_bit: Offset in @intr_status_reg for reading and acking the interrupt
* status.
* @intr_target_bit: Offset in @intr_target_reg for configuring the interrupt routing.
* @intr_raw_status_bit: Offset in @intr_cfg_reg for the raw status bit.
* @intr_polarity_bit: Offset in @intr_cfg_reg for specifying polarity of the interrupt.
* @intr_detection_bit: Offset in @intr_cfg_reg for specifying interrupt type.
* @intr_detection_width: Number of bits used for specifying interrupt type,
* Should be 2 for SoCs that can detect both edges in hardware,
* otherwise 1.
*/
struct msm_pingroup {
const char *name;
const unsigned *pins;
unsigned npins;
unsigned funcs[8];
s16 ctl_reg;
s16 io_reg;
s16 intr_cfg_reg;
s16 intr_status_reg;
s16 intr_target_reg;
unsigned mux_bit:5;
unsigned pull_bit:5;
unsigned drv_bit:5;
unsigned oe_bit:5;
unsigned in_bit:5;
unsigned out_bit:5;
unsigned intr_enable_bit:5;
unsigned intr_status_bit:5;
unsigned intr_target_bit:5;
unsigned intr_raw_status_bit:5;
unsigned intr_polarity_bit:5;
unsigned intr_detection_bit:5;
unsigned intr_detection_width:5;
};
/**
* struct msm_pinctrl_soc_data - Qualcomm pin controller driver configuration
* @pins: An array describing all pins the pin controller affects.
* @npins: The number of entries in @pins.
* @functions: An array describing all mux functions the SoC supports.
* @nfunctions: The number of entries in @functions.
* @groups: An array describing all pin groups the pin SoC supports.
* @ngroups: The numbmer of entries in @groups.
* @ngpio: The number of pingroups the driver should expose as GPIOs.
*/
struct msm_pinctrl_soc_data {
const struct pinctrl_pin_desc *pins;
unsigned npins;
const struct msm_function *functions;
unsigned nfunctions;
const struct msm_pingroup *groups;
unsigned ngroups;
unsigned ngpios;
};
int msm_pinctrl_probe(struct platform_device *pdev,
const struct msm_pinctrl_soc_data *soc_data);
int msm_pinctrl_remove(struct platform_device *pdev);
#endif
/*
* Copyright (c) 2013, Sony Mobile Communications AB.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include "pinctrl-msm.h"
static const struct pinctrl_pin_desc msm8x74_pins[] = {
PINCTRL_PIN(0, "GPIO_0"),
PINCTRL_PIN(1, "GPIO_1"),
PINCTRL_PIN(2, "GPIO_2"),
PINCTRL_PIN(3, "GPIO_3"),
PINCTRL_PIN(4, "GPIO_4"),
PINCTRL_PIN(5, "GPIO_5"),
PINCTRL_PIN(6, "GPIO_6"),
PINCTRL_PIN(7, "GPIO_7"),
PINCTRL_PIN(8, "GPIO_8"),
PINCTRL_PIN(9, "GPIO_9"),
PINCTRL_PIN(10, "GPIO_10"),
PINCTRL_PIN(11, "GPIO_11"),
PINCTRL_PIN(12, "GPIO_12"),
PINCTRL_PIN(13, "GPIO_13"),
PINCTRL_PIN(14, "GPIO_14"),
PINCTRL_PIN(15, "GPIO_15"),
PINCTRL_PIN(16, "GPIO_16"),
PINCTRL_PIN(17, "GPIO_17"),
PINCTRL_PIN(18, "GPIO_18"),
PINCTRL_PIN(19, "GPIO_19"),
PINCTRL_PIN(20, "GPIO_20"),
PINCTRL_PIN(21, "GPIO_21"),
PINCTRL_PIN(22, "GPIO_22"),
PINCTRL_PIN(23, "GPIO_23"),
PINCTRL_PIN(24, "GPIO_24"),
PINCTRL_PIN(25, "GPIO_25"),
PINCTRL_PIN(26, "GPIO_26"),
PINCTRL_PIN(27, "GPIO_27"),
PINCTRL_PIN(28, "GPIO_28"),
PINCTRL_PIN(29, "GPIO_29"),
PINCTRL_PIN(30, "GPIO_30"),
PINCTRL_PIN(31, "GPIO_31"),
PINCTRL_PIN(32, "GPIO_32"),
PINCTRL_PIN(33, "GPIO_33"),
PINCTRL_PIN(34, "GPIO_34"),
PINCTRL_PIN(35, "GPIO_35"),
PINCTRL_PIN(36, "GPIO_36"),
PINCTRL_PIN(37, "GPIO_37"),
PINCTRL_PIN(38, "GPIO_38"),
PINCTRL_PIN(39, "GPIO_39"),
PINCTRL_PIN(40, "GPIO_40"),
PINCTRL_PIN(41, "GPIO_41"),
PINCTRL_PIN(42, "GPIO_42"),
PINCTRL_PIN(43, "GPIO_43"),
PINCTRL_PIN(44, "GPIO_44"),
PINCTRL_PIN(45, "GPIO_45"),
PINCTRL_PIN(46, "GPIO_46"),
PINCTRL_PIN(47, "GPIO_47"),
PINCTRL_PIN(48, "GPIO_48"),
PINCTRL_PIN(49, "GPIO_49"),
PINCTRL_PIN(50, "GPIO_50"),
PINCTRL_PIN(51, "GPIO_51"),
PINCTRL_PIN(52, "GPIO_52"),
PINCTRL_PIN(53, "GPIO_53"),
PINCTRL_PIN(54, "GPIO_54"),
PINCTRL_PIN(55, "GPIO_55"),
PINCTRL_PIN(56, "GPIO_56"),
PINCTRL_PIN(57, "GPIO_57"),
PINCTRL_PIN(58, "GPIO_58"),
PINCTRL_PIN(59, "GPIO_59"),
PINCTRL_PIN(60, "GPIO_60"),
PINCTRL_PIN(61, "GPIO_61"),
PINCTRL_PIN(62, "GPIO_62"),
PINCTRL_PIN(63, "GPIO_63"),
PINCTRL_PIN(64, "GPIO_64"),
PINCTRL_PIN(65, "GPIO_65"),
PINCTRL_PIN(66, "GPIO_66"),
PINCTRL_PIN(67, "GPIO_67"),
PINCTRL_PIN(68, "GPIO_68"),
PINCTRL_PIN(69, "GPIO_69"),
PINCTRL_PIN(70, "GPIO_70"),
PINCTRL_PIN(71, "GPIO_71"),
PINCTRL_PIN(72, "GPIO_72"),
PINCTRL_PIN(73, "GPIO_73"),
PINCTRL_PIN(74, "GPIO_74"),
PINCTRL_PIN(75, "GPIO_75"),
PINCTRL_PIN(76, "GPIO_76"),
PINCTRL_PIN(77, "GPIO_77"),
PINCTRL_PIN(78, "GPIO_78"),
PINCTRL_PIN(79, "GPIO_79"),
PINCTRL_PIN(80, "GPIO_80"),
PINCTRL_PIN(81, "GPIO_81"),
PINCTRL_PIN(82, "GPIO_82"),
PINCTRL_PIN(83, "GPIO_83"),
PINCTRL_PIN(84, "GPIO_84"),
PINCTRL_PIN(85, "GPIO_85"),
PINCTRL_PIN(86, "GPIO_86"),
PINCTRL_PIN(87, "GPIO_87"),
PINCTRL_PIN(88, "GPIO_88"),
PINCTRL_PIN(89, "GPIO_89"),
PINCTRL_PIN(90, "GPIO_90"),
PINCTRL_PIN(91, "GPIO_91"),
PINCTRL_PIN(92, "GPIO_92"),
PINCTRL_PIN(93, "GPIO_93"),
PINCTRL_PIN(94, "GPIO_94"),
PINCTRL_PIN(95, "GPIO_95"),
PINCTRL_PIN(96, "GPIO_96"),
PINCTRL_PIN(97, "GPIO_97"),
PINCTRL_PIN(98, "GPIO_98"),
PINCTRL_PIN(99, "GPIO_99"),
PINCTRL_PIN(100, "GPIO_100"),
PINCTRL_PIN(101, "GPIO_101"),
PINCTRL_PIN(102, "GPIO_102"),
PINCTRL_PIN(103, "GPIO_103"),
PINCTRL_PIN(104, "GPIO_104"),
PINCTRL_PIN(105, "GPIO_105"),
PINCTRL_PIN(106, "GPIO_106"),
PINCTRL_PIN(107, "GPIO_107"),
PINCTRL_PIN(108, "GPIO_108"),
PINCTRL_PIN(109, "GPIO_109"),
PINCTRL_PIN(110, "GPIO_110"),
PINCTRL_PIN(111, "GPIO_111"),
PINCTRL_PIN(112, "GPIO_112"),
PINCTRL_PIN(113, "GPIO_113"),
PINCTRL_PIN(114, "GPIO_114"),
PINCTRL_PIN(115, "GPIO_115"),
PINCTRL_PIN(116, "GPIO_116"),
PINCTRL_PIN(117, "GPIO_117"),
PINCTRL_PIN(118, "GPIO_118"),
PINCTRL_PIN(119, "GPIO_119"),
PINCTRL_PIN(120, "GPIO_120"),
PINCTRL_PIN(121, "GPIO_121"),
PINCTRL_PIN(122, "GPIO_122"),
PINCTRL_PIN(123, "GPIO_123"),
PINCTRL_PIN(124, "GPIO_124"),
PINCTRL_PIN(125, "GPIO_125"),
PINCTRL_PIN(126, "GPIO_126"),
PINCTRL_PIN(127, "GPIO_127"),
PINCTRL_PIN(128, "GPIO_128"),
PINCTRL_PIN(129, "GPIO_129"),
PINCTRL_PIN(130, "GPIO_130"),
PINCTRL_PIN(131, "GPIO_131"),
PINCTRL_PIN(132, "GPIO_132"),
PINCTRL_PIN(133, "GPIO_133"),
PINCTRL_PIN(134, "GPIO_134"),
PINCTRL_PIN(135, "GPIO_135"),
PINCTRL_PIN(136, "GPIO_136"),
PINCTRL_PIN(137, "GPIO_137"),
PINCTRL_PIN(138, "GPIO_138"),
PINCTRL_PIN(139, "GPIO_139"),
PINCTRL_PIN(140, "GPIO_140"),
PINCTRL_PIN(141, "GPIO_141"),
PINCTRL_PIN(142, "GPIO_142"),
PINCTRL_PIN(143, "GPIO_143"),
PINCTRL_PIN(144, "GPIO_144"),
PINCTRL_PIN(145, "GPIO_145"),
PINCTRL_PIN(146, "SDC1_CLK"),
PINCTRL_PIN(147, "SDC1_CMD"),
PINCTRL_PIN(148, "SDC1_DATA"),
PINCTRL_PIN(149, "SDC2_CLK"),
PINCTRL_PIN(150, "SDC2_CMD"),
PINCTRL_PIN(151, "SDC2_DATA"),
};
#define DECLARE_MSM_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin }
DECLARE_MSM_GPIO_PINS(0);
DECLARE_MSM_GPIO_PINS(1);
DECLARE_MSM_GPIO_PINS(2);
DECLARE_MSM_GPIO_PINS(3);
DECLARE_MSM_GPIO_PINS(4);
DECLARE_MSM_GPIO_PINS(5);
DECLARE_MSM_GPIO_PINS(6);
DECLARE_MSM_GPIO_PINS(7);
DECLARE_MSM_GPIO_PINS(8);
DECLARE_MSM_GPIO_PINS(9);
DECLARE_MSM_GPIO_PINS(10);
DECLARE_MSM_GPIO_PINS(11);
DECLARE_MSM_GPIO_PINS(12);
DECLARE_MSM_GPIO_PINS(13);
DECLARE_MSM_GPIO_PINS(14);
DECLARE_MSM_GPIO_PINS(15);
DECLARE_MSM_GPIO_PINS(16);
DECLARE_MSM_GPIO_PINS(17);
DECLARE_MSM_GPIO_PINS(18);
DECLARE_MSM_GPIO_PINS(19);
DECLARE_MSM_GPIO_PINS(20);
DECLARE_MSM_GPIO_PINS(21);
DECLARE_MSM_GPIO_PINS(22);
DECLARE_MSM_GPIO_PINS(23);
DECLARE_MSM_GPIO_PINS(24);
DECLARE_MSM_GPIO_PINS(25);
DECLARE_MSM_GPIO_PINS(26);
DECLARE_MSM_GPIO_PINS(27);
DECLARE_MSM_GPIO_PINS(28);
DECLARE_MSM_GPIO_PINS(29);
DECLARE_MSM_GPIO_PINS(30);
DECLARE_MSM_GPIO_PINS(31);
DECLARE_MSM_GPIO_PINS(32);
DECLARE_MSM_GPIO_PINS(33);
DECLARE_MSM_GPIO_PINS(34);
DECLARE_MSM_GPIO_PINS(35);
DECLARE_MSM_GPIO_PINS(36);
DECLARE_MSM_GPIO_PINS(37);
DECLARE_MSM_GPIO_PINS(38);
DECLARE_MSM_GPIO_PINS(39);
DECLARE_MSM_GPIO_PINS(40);
DECLARE_MSM_GPIO_PINS(41);
DECLARE_MSM_GPIO_PINS(42);
DECLARE_MSM_GPIO_PINS(43);
DECLARE_MSM_GPIO_PINS(44);
DECLARE_MSM_GPIO_PINS(45);
DECLARE_MSM_GPIO_PINS(46);
DECLARE_MSM_GPIO_PINS(47);
DECLARE_MSM_GPIO_PINS(48);
DECLARE_MSM_GPIO_PINS(49);
DECLARE_MSM_GPIO_PINS(50);
DECLARE_MSM_GPIO_PINS(51);
DECLARE_MSM_GPIO_PINS(52);
DECLARE_MSM_GPIO_PINS(53);
DECLARE_MSM_GPIO_PINS(54);
DECLARE_MSM_GPIO_PINS(55);
DECLARE_MSM_GPIO_PINS(56);
DECLARE_MSM_GPIO_PINS(57);
DECLARE_MSM_GPIO_PINS(58);
DECLARE_MSM_GPIO_PINS(59);
DECLARE_MSM_GPIO_PINS(60);
DECLARE_MSM_GPIO_PINS(61);
DECLARE_MSM_GPIO_PINS(62);
DECLARE_MSM_GPIO_PINS(63);
DECLARE_MSM_GPIO_PINS(64);
DECLARE_MSM_GPIO_PINS(65);
DECLARE_MSM_GPIO_PINS(66);
DECLARE_MSM_GPIO_PINS(67);
DECLARE_MSM_GPIO_PINS(68);
DECLARE_MSM_GPIO_PINS(69);
DECLARE_MSM_GPIO_PINS(70);
DECLARE_MSM_GPIO_PINS(71);
DECLARE_MSM_GPIO_PINS(72);
DECLARE_MSM_GPIO_PINS(73);
DECLARE_MSM_GPIO_PINS(74);
DECLARE_MSM_GPIO_PINS(75);
DECLARE_MSM_GPIO_PINS(76);
DECLARE_MSM_GPIO_PINS(77);
DECLARE_MSM_GPIO_PINS(78);
DECLARE_MSM_GPIO_PINS(79);
DECLARE_MSM_GPIO_PINS(80);
DECLARE_MSM_GPIO_PINS(81);
DECLARE_MSM_GPIO_PINS(82);
DECLARE_MSM_GPIO_PINS(83);
DECLARE_MSM_GPIO_PINS(84);
DECLARE_MSM_GPIO_PINS(85);
DECLARE_MSM_GPIO_PINS(86);
DECLARE_MSM_GPIO_PINS(87);
DECLARE_MSM_GPIO_PINS(88);
DECLARE_MSM_GPIO_PINS(89);
DECLARE_MSM_GPIO_PINS(90);
DECLARE_MSM_GPIO_PINS(91);
DECLARE_MSM_GPIO_PINS(92);
DECLARE_MSM_GPIO_PINS(93);
DECLARE_MSM_GPIO_PINS(94);
DECLARE_MSM_GPIO_PINS(95);
DECLARE_MSM_GPIO_PINS(96);
DECLARE_MSM_GPIO_PINS(97);
DECLARE_MSM_GPIO_PINS(98);
DECLARE_MSM_GPIO_PINS(99);
DECLARE_MSM_GPIO_PINS(100);
DECLARE_MSM_GPIO_PINS(101);
DECLARE_MSM_GPIO_PINS(102);
DECLARE_MSM_GPIO_PINS(103);
DECLARE_MSM_GPIO_PINS(104);
DECLARE_MSM_GPIO_PINS(105);
DECLARE_MSM_GPIO_PINS(106);
DECLARE_MSM_GPIO_PINS(107);
DECLARE_MSM_GPIO_PINS(108);
DECLARE_MSM_GPIO_PINS(109);
DECLARE_MSM_GPIO_PINS(110);
DECLARE_MSM_GPIO_PINS(111);
DECLARE_MSM_GPIO_PINS(112);
DECLARE_MSM_GPIO_PINS(113);
DECLARE_MSM_GPIO_PINS(114);
DECLARE_MSM_GPIO_PINS(115);
DECLARE_MSM_GPIO_PINS(116);
DECLARE_MSM_GPIO_PINS(117);
DECLARE_MSM_GPIO_PINS(118);
DECLARE_MSM_GPIO_PINS(119);
DECLARE_MSM_GPIO_PINS(120);
DECLARE_MSM_GPIO_PINS(121);
DECLARE_MSM_GPIO_PINS(122);
DECLARE_MSM_GPIO_PINS(123);
DECLARE_MSM_GPIO_PINS(124);
DECLARE_MSM_GPIO_PINS(125);
DECLARE_MSM_GPIO_PINS(126);
DECLARE_MSM_GPIO_PINS(127);
DECLARE_MSM_GPIO_PINS(128);
DECLARE_MSM_GPIO_PINS(129);
DECLARE_MSM_GPIO_PINS(130);
DECLARE_MSM_GPIO_PINS(131);
DECLARE_MSM_GPIO_PINS(132);
DECLARE_MSM_GPIO_PINS(133);
DECLARE_MSM_GPIO_PINS(134);
DECLARE_MSM_GPIO_PINS(135);
DECLARE_MSM_GPIO_PINS(136);
DECLARE_MSM_GPIO_PINS(137);
DECLARE_MSM_GPIO_PINS(138);
DECLARE_MSM_GPIO_PINS(139);
DECLARE_MSM_GPIO_PINS(140);
DECLARE_MSM_GPIO_PINS(141);
DECLARE_MSM_GPIO_PINS(142);
DECLARE_MSM_GPIO_PINS(143);
DECLARE_MSM_GPIO_PINS(144);
DECLARE_MSM_GPIO_PINS(145);
static const unsigned int sdc1_clk_pins[] = { 146 };
static const unsigned int sdc1_cmd_pins[] = { 147 };
static const unsigned int sdc1_data_pins[] = { 148 };
static const unsigned int sdc2_clk_pins[] = { 149 };
static const unsigned int sdc2_cmd_pins[] = { 150 };
static const unsigned int sdc2_data_pins[] = { 151 };
#define FUNCTION(fname) \
[MSM_MUX_##fname] = { \
.name = #fname, \
.groups = fname##_groups, \
.ngroups = ARRAY_SIZE(fname##_groups), \
}
#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7) \
{ \
.name = "gpio" #id, \
.pins = gpio##id##_pins, \
.npins = ARRAY_SIZE(gpio##id##_pins), \
.funcs = { \
MSM_MUX_NA, /* gpio mode */ \
MSM_MUX_##f1, \
MSM_MUX_##f2, \
MSM_MUX_##f3, \
MSM_MUX_##f4, \
MSM_MUX_##f5, \
MSM_MUX_##f6, \
MSM_MUX_##f7 \
}, \
.ctl_reg = 0x1000 + 0x10 * id , \
.io_reg = 0x1004 + 0x10 * id, \
.intr_cfg_reg = 0x1008 + 0x10 * id, \
.intr_status_reg = 0x100c + 0x10 * id, \
.intr_target_reg = 0x1008 + 0x10 * id, \
.mux_bit = 2, \
.pull_bit = 0, \
.drv_bit = 6, \
.oe_bit = 9, \
.in_bit = 0, \
.out_bit = 1, \
.intr_enable_bit = 0, \
.intr_status_bit = 0, \
.intr_target_bit = 5, \
.intr_raw_status_bit = 4, \
.intr_polarity_bit = 1, \
.intr_detection_bit = 2, \
.intr_detection_width = 2, \
}
#define SDC_PINGROUP(pg_name, ctl, pull, drv) \
{ \
.name = #pg_name, \
.pins = pg_name##_pins, \
.npins = ARRAY_SIZE(pg_name##_pins), \
.ctl_reg = ctl, \
.io_reg = 0, \
.intr_cfg_reg = 0, \
.intr_status_reg = 0, \
.intr_target_reg = 0, \
.mux_bit = -1, \
.pull_bit = pull, \
.drv_bit = drv, \
.oe_bit = -1, \
.in_bit = -1, \
.out_bit = -1, \
.intr_enable_bit = -1, \
.intr_status_bit = -1, \
.intr_target_bit = -1, \
.intr_raw_status_bit = -1, \
.intr_polarity_bit = -1, \
.intr_detection_bit = -1, \
.intr_detection_width = -1, \
}
/*
* TODO: Add the rest of the possible functions and fill out
* the pingroup table below.
*/
enum msm8x74_functions {
MSM_MUX_blsp_i2c2,
MSM_MUX_blsp_i2c6,
MSM_MUX_blsp_i2c11,
MSM_MUX_blsp_spi1,
MSM_MUX_blsp_uart2,
MSM_MUX_blsp_uart8,
MSM_MUX_slimbus,
MSM_MUX_NA,
};
static const char * const blsp_i2c2_groups[] = { "gpio6", "gpio7" };
static const char * const blsp_i2c6_groups[] = { "gpio29", "gpio30" };
static const char * const blsp_i2c11_groups[] = { "gpio83", "gpio84" };
static const char * const blsp_spi1_groups[] = { "gpio0", "gpio1", "gpio2", "gpio3" };
static const char * const blsp_uart2_groups[] = { "gpio4", "gpio5" };
static const char * const blsp_uart8_groups[] = { "gpio45", "gpio46" };
static const char * const slimbus_groups[] = { "gpio70", "gpio71" };
static const struct msm_function msm8x74_functions[] = {
FUNCTION(blsp_i2c2),
FUNCTION(blsp_i2c6),
FUNCTION(blsp_i2c11),
FUNCTION(blsp_spi1),
FUNCTION(blsp_uart2),
FUNCTION(blsp_uart8),
FUNCTION(slimbus),
};
static const struct msm_pingroup msm8x74_groups[] = {
PINGROUP(0, blsp_spi1, NA, NA, NA, NA, NA, NA),
PINGROUP(1, blsp_spi1, NA, NA, NA, NA, NA, NA),
PINGROUP(2, blsp_spi1, NA, NA, NA, NA, NA, NA),
PINGROUP(3, blsp_spi1, NA, NA, NA, NA, NA, NA),
PINGROUP(4, NA, blsp_uart2, NA, NA, NA, NA, NA),
PINGROUP(5, NA, blsp_uart2, NA, NA, NA, NA, NA),
PINGROUP(6, NA, NA, blsp_i2c2, NA, NA, NA, NA),
PINGROUP(7, NA, NA, blsp_i2c2, NA, NA, NA, NA),
PINGROUP(8, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(9, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(10, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(11, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(12, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(13, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(14, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(15, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(16, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(17, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(18, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(19, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(20, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(21, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(22, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(23, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(24, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(25, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(26, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(27, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(28, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(29, NA, NA, blsp_i2c6, NA, NA, NA, NA),
PINGROUP(30, NA, NA, blsp_i2c6, NA, NA, NA, NA),
PINGROUP(31, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(32, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(33, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(34, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(35, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(36, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(37, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(38, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(39, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(40, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(41, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(42, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(43, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(44, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(45, NA, blsp_uart8, NA, NA, NA, NA, NA),
PINGROUP(46, NA, blsp_uart8, NA, NA, NA, NA, NA),
PINGROUP(47, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(48, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(49, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(50, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(51, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(52, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(53, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(54, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(55, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(56, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(57, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(58, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(59, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(60, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(61, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(62, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(63, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(64, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(65, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(66, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(67, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(68, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(69, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(70, slimbus, NA, NA, NA, NA, NA, NA),
PINGROUP(71, slimbus, NA, NA, NA, NA, NA, NA),
PINGROUP(72, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(73, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(74, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(75, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(76, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(77, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(78, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(79, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(80, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(81, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(82, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(83, NA, NA, blsp_i2c11, NA, NA, NA, NA),
PINGROUP(84, NA, NA, blsp_i2c11, NA, NA, NA, NA),
PINGROUP(85, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(86, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(87, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(88, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(89, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(90, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(91, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(92, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(93, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(94, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(95, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(96, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(97, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(98, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(99, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(100, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(101, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(102, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(103, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(104, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(105, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(106, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(107, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(108, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(109, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(110, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(111, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(112, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(113, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(114, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(115, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(116, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(117, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(118, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(119, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(120, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(121, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(122, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(123, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(124, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(125, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(126, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(127, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(128, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(129, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(130, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(131, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(132, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(133, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(134, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(135, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(136, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(137, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(138, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(139, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(140, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(141, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(143, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(143, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(144, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(145, NA, NA, NA, NA, NA, NA, NA),
SDC_PINGROUP(sdc1_clk, 0x2044, 13, 6),
SDC_PINGROUP(sdc1_cmd, 0x2044, 11, 3),
SDC_PINGROUP(sdc1_data, 0x2044, 9, 0),
SDC_PINGROUP(sdc2_clk, 0x2048, 14, 6),
SDC_PINGROUP(sdc2_cmd, 0x2048, 11, 3),
SDC_PINGROUP(sdc2_data, 0x2048, 9, 0),
};
#define NUM_GPIO_PINGROUPS 146
static const struct msm_pinctrl_soc_data msm8x74_pinctrl = {
.pins = msm8x74_pins,
.npins = ARRAY_SIZE(msm8x74_pins),
.functions = msm8x74_functions,
.nfunctions = ARRAY_SIZE(msm8x74_functions),
.groups = msm8x74_groups,
.ngroups = ARRAY_SIZE(msm8x74_groups),
.ngpios = NUM_GPIO_PINGROUPS,
};
static int msm8x74_pinctrl_probe(struct platform_device *pdev)
{
return msm_pinctrl_probe(pdev, &msm8x74_pinctrl);
}
static struct of_device_id msm8x74_pinctrl_of_match[] = {
{ .compatible = "qcom,msm8x74-pinctrl", },
{ },
};
static struct platform_driver msm8x74_pinctrl_driver = {
.driver = {
.name = "msm8x74-pinctrl",
.owner = THIS_MODULE,
.of_match_table = msm8x74_pinctrl_of_match,
},
.probe = msm8x74_pinctrl_probe,
.remove = msm_pinctrl_remove,
};
static int __init msm8x74_pinctrl_init(void)
{
return platform_driver_register(&msm8x74_pinctrl_driver);
}
arch_initcall(msm8x74_pinctrl_init);
static void __exit msm8x74_pinctrl_exit(void)
{
platform_driver_unregister(&msm8x74_pinctrl_driver);
}
module_exit(msm8x74_pinctrl_exit);
MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");
MODULE_DESCRIPTION("Qualcomm MSM8x74 pinctrl driver");
MODULE_LICENSE("GPL v2");
MODULE_DEVICE_TABLE(of, msm8x74_pinctrl_of_match);
......@@ -846,14 +846,14 @@ static void nmk_gpio_dbg_show_one(struct seq_file *s,
(mode < 0) ? "unknown" : modes[mode],
pull ? "pull" : "none");
if (label && !is_out) {
int irq = gpio_to_irq(gpio);
if (!is_out) {
int irq = gpio_to_irq(gpio);
struct irq_desc *desc = irq_to_desc(irq);
/* This races with request_irq(), set_irq_type(),
* and set_irq_wake() ... but those are "rare".
*/
if (irq >= 0 && desc->action) {
if (irq > 0 && desc && desc->action) {
char *trigger;
u32 bitmask = nmk_gpio_get_bitmask(gpio);
......
......@@ -26,29 +26,67 @@
#include "core.h"
static int sh_pfc_ioremap(struct sh_pfc *pfc, struct platform_device *pdev)
static int sh_pfc_map_resources(struct sh_pfc *pfc,
struct platform_device *pdev)
{
unsigned int num_windows = 0;
unsigned int num_irqs = 0;
struct sh_pfc_window *windows;
unsigned int *irqs = NULL;
struct resource *res;
int k;
unsigned int i;
/* Count the MEM and IRQ resources. */
for (i = 0; i < pdev->num_resources; ++i) {
switch (resource_type(&pdev->resource[i])) {
case IORESOURCE_MEM:
num_windows++;
break;
case IORESOURCE_IRQ:
num_irqs++;
break;
}
}
if (pdev->num_resources == 0)
if (num_windows == 0)
return -EINVAL;
pfc->window = devm_kzalloc(pfc->dev, pdev->num_resources *
sizeof(*pfc->window), GFP_NOWAIT);
if (!pfc->window)
/* Allocate memory windows and IRQs arrays. */
windows = devm_kzalloc(pfc->dev, num_windows * sizeof(*windows),
GFP_KERNEL);
if (windows == NULL)
return -ENOMEM;
pfc->num_windows = pdev->num_resources;
pfc->num_windows = num_windows;
pfc->windows = windows;
for (k = 0, res = pdev->resource; k < pdev->num_resources; k++, res++) {
WARN_ON(resource_type(res) != IORESOURCE_MEM);
pfc->window[k].phys = res->start;
pfc->window[k].size = resource_size(res);
pfc->window[k].virt = devm_ioremap_nocache(pfc->dev, res->start,
resource_size(res));
if (!pfc->window[k].virt)
if (num_irqs) {
irqs = devm_kzalloc(pfc->dev, num_irqs * sizeof(*irqs),
GFP_KERNEL);
if (irqs == NULL)
return -ENOMEM;
pfc->num_irqs = num_irqs;
pfc->irqs = irqs;
}
/* Fill them. */
for (i = 0, res = pdev->resource; i < pdev->num_resources; i++, res++) {
switch (resource_type(res)) {
case IORESOURCE_MEM:
windows->phys = res->start;
windows->size = resource_size(res);
windows->virt = devm_ioremap_resource(pfc->dev, res);
if (IS_ERR(windows->virt))
return -ENOMEM;
windows++;
break;
case IORESOURCE_IRQ:
*irqs++ = res->start;
break;
}
}
return 0;
......@@ -62,7 +100,7 @@ static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc,
/* scan through physical windows and convert address */
for (i = 0; i < pfc->num_windows; i++) {
window = pfc->window + i;
window = pfc->windows + i;
if (address < window->phys)
continue;
......@@ -147,7 +185,7 @@ static void sh_pfc_config_reg_helper(struct sh_pfc *pfc,
unsigned long *maskp,
unsigned long *posp)
{
int k;
unsigned int k;
*mapped_regp = sh_pfc_phys_to_virt(pfc, crp->reg);
......@@ -196,7 +234,7 @@ static int sh_pfc_get_config_reg(struct sh_pfc *pfc, u16 enum_id,
{
const struct pinmux_cfg_reg *config_reg;
unsigned long r_width, f_width, curr_width, ncomb;
int k, m, n, pos, bit_pos;
unsigned int k, m, n, pos, bit_pos;
k = 0;
while (1) {
......@@ -238,7 +276,7 @@ static int sh_pfc_mark_to_enum(struct sh_pfc *pfc, u16 mark, int pos,
u16 *enum_idp)
{
const u16 *data = pfc->info->gpio_data;
int k;
unsigned int k;
if (pos) {
*enum_idp = data[pos + 1];
......@@ -481,7 +519,7 @@ static int sh_pfc_probe(struct platform_device *pdev)
pfc->info = info;
pfc->dev = &pdev->dev;
ret = sh_pfc_ioremap(pfc, pdev);
ret = sh_pfc_map_resources(pfc, pdev);
if (unlikely(ret < 0))
return ret;
......
......@@ -37,7 +37,9 @@ struct sh_pfc {
spinlock_t lock;
unsigned int num_windows;
struct sh_pfc_window *window;
struct sh_pfc_window *windows;
unsigned int num_irqs;
unsigned int *irqs;
struct sh_pfc_pin_range *ranges;
unsigned int nr_ranges;
......
......@@ -204,18 +204,24 @@ static void gpio_pin_set(struct gpio_chip *gc, unsigned offset, int value)
static int gpio_pin_to_irq(struct gpio_chip *gc, unsigned offset)
{
struct sh_pfc *pfc = gpio_to_pfc(gc);
int i, k;
unsigned int i, k;
for (i = 0; i < pfc->info->gpio_irq_size; i++) {
unsigned short *gpios = pfc->info->gpio_irq[i].gpios;
short *gpios = pfc->info->gpio_irq[i].gpios;
for (k = 0; gpios[k]; k++) {
for (k = 0; gpios[k] >= 0; k++) {
if (gpios[k] == offset)
return pfc->info->gpio_irq[i].irq;
goto found;
}
}
return -ENOSYS;
found:
if (pfc->num_irqs)
return pfc->irqs[i];
else
return pfc->info->gpio_irq[i].irq;
}
static int gpio_pin_setup(struct sh_pfc_chip *chip)
......@@ -347,7 +353,7 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
* GPIOs.
*/
for (i = 0; i < pfc->num_windows; ++i) {
struct sh_pfc_window *window = &pfc->window[i];
struct sh_pfc_window *window = &pfc->windows[i];
if (pfc->info->data_regs[0].reg >= window->phys &&
pfc->info->data_regs[0].reg < window->phys + window->size)
......@@ -357,8 +363,14 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
if (i == pfc->num_windows)
return 0;
/* If we have IRQ resources make sure their number is correct. */
if (pfc->num_irqs && pfc->num_irqs != pfc->info->gpio_irq_size) {
dev_err(pfc->dev, "invalid number of IRQ resources\n");
return -EINVAL;
}
/* Register the real GPIOs chip. */
chip = sh_pfc_add_gpiochip(pfc, gpio_pin_setup, &pfc->window[i]);
chip = sh_pfc_add_gpiochip(pfc, gpio_pin_setup, &pfc->windows[i]);
if (IS_ERR(chip))
return PTR_ERR(chip);
......
......@@ -2061,17 +2061,6 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(sdhi2),
};
#undef PORTCR
#define PORTCR(nr, reg) \
{ \
PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
_PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT), \
PORT##nr##_FN0, PORT##nr##_FN1, \
PORT##nr##_FN2, PORT##nr##_FN3, \
PORT##nr##_FN4, PORT##nr##_FN5, \
PORT##nr##_FN6, PORT##nr##_FN7 } \
}
static const struct pinmux_cfg_reg pinmux_config_regs[] = {
PORTCR(0, 0xe6050000),
PORTCR(1, 0xe6050001),
......@@ -2691,7 +2680,7 @@ static unsigned int r8a73a4_pinmux_get_bias(struct sh_pfc *pfc,
{
void __iomem *addr;
addr = pfc->window->virt + r8a73a4_portcr_offsets[pin >> 5] + pin;
addr = pfc->windows->virt + r8a73a4_portcr_offsets[pin >> 5] + pin;
switch (ioread8(addr) & PORTCR_PULMD_MASK) {
case PORTCR_PULMD_UP:
......@@ -2710,7 +2699,7 @@ static void r8a73a4_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,
void __iomem *addr;
u32 value;
addr = pfc->window->virt + r8a73a4_portcr_offsets[pin >> 5] + pin;
addr = pfc->windows->virt + r8a73a4_portcr_offsets[pin >> 5] + pin;
value = ioread8(addr) & ~PORTCR_PULMD_MASK;
switch (bias) {
......
......@@ -3234,17 +3234,6 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(tpu0),
};
#undef PORTCR
#define PORTCR(nr, reg) \
{ \
PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
_PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT), \
PORT##nr##_FN0, PORT##nr##_FN1, \
PORT##nr##_FN2, PORT##nr##_FN3, \
PORT##nr##_FN4, PORT##nr##_FN5, \
PORT##nr##_FN6, PORT##nr##_FN7 } \
}
static const struct pinmux_cfg_reg pinmux_config_regs[] = {
PORTCR(0, 0xe6050000), /* PORT0CR */
PORTCR(1, 0xe6050001), /* PORT1CR */
......@@ -3721,7 +3710,7 @@ static void __iomem *r8a7740_pinmux_portcr(struct sh_pfc *pfc, unsigned int pin)
&r8a7740_portcr_offsets[i];
if (i <= group->end_pin)
return pfc->window->virt + group->offset + pin;
return pfc->windows->virt + group->offset + pin;
}
return NULL;
......
......@@ -1739,6 +1739,56 @@ static struct sh_pfc_pin pinmux_pins[] = {
SH_PFC_PIN_NAMED(ROW_GROUP_A('H'), 15, AH15),
};
/* - AUDIO CLOCK ------------------------------------------------------------ */
static const unsigned int audio_clk_a_pins[] = {
/* CLK A */
RCAR_GP_PIN(4, 25),
};
static const unsigned int audio_clk_a_mux[] = {
AUDIO_CLKA_MARK,
};
static const unsigned int audio_clk_b_pins[] = {
/* CLK B */
RCAR_GP_PIN(4, 26),
};
static const unsigned int audio_clk_b_mux[] = {
AUDIO_CLKB_MARK,
};
static const unsigned int audio_clk_c_pins[] = {
/* CLK C */
RCAR_GP_PIN(5, 27),
};
static const unsigned int audio_clk_c_mux[] = {
AUDIO_CLKC_MARK,
};
static const unsigned int audio_clkout_pins[] = {
/* CLK OUT */
RCAR_GP_PIN(5, 16),
};
static const unsigned int audio_clkout_mux[] = {
AUDIO_CLKOUT_MARK,
};
static const unsigned int audio_clkout_b_pins[] = {
/* CLK OUT B */
RCAR_GP_PIN(0, 23),
};
static const unsigned int audio_clkout_b_mux[] = {
AUDIO_CLKOUT_B_MARK,
};
static const unsigned int audio_clkout_c_pins[] = {
/* CLK OUT C */
RCAR_GP_PIN(5, 27),
};
static const unsigned int audio_clkout_c_mux[] = {
AUDIO_CLKOUT_C_MARK,
};
static const unsigned int audio_clkout_d_pins[] = {
/* CLK OUT D */
RCAR_GP_PIN(5, 20),
};
static const unsigned int audio_clkout_d_mux[] = {
AUDIO_CLKOUT_D_MARK,
};
/* - DU RGB ----------------------------------------------------------------- */
static const unsigned int du_rgb666_pins[] = {
/* R[7:2], G[7:2], B[7:2] */
......@@ -2961,6 +3011,189 @@ static const unsigned int sdhi3_wp_pins[] = {
static const unsigned int sdhi3_wp_mux[] = {
SD3_WP_MARK,
};
/* - SSI -------------------------------------------------------------------- */
static const unsigned int ssi0_data_pins[] = {
/* SDATA0 */
RCAR_GP_PIN(4, 5),
};
static const unsigned int ssi0_data_mux[] = {
SSI_SDATA0_MARK,
};
static const unsigned int ssi0129_ctrl_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(4, 3), RCAR_GP_PIN(4, 4),
};
static const unsigned int ssi0129_ctrl_mux[] = {
SSI_SCK0129_MARK, SSI_WS0129_MARK,
};
static const unsigned int ssi1_data_pins[] = {
/* SDATA1 */
RCAR_GP_PIN(4, 6),
};
static const unsigned int ssi1_data_mux[] = {
SSI_SDATA1_MARK,
};
static const unsigned int ssi1_ctrl_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(4, 7), RCAR_GP_PIN(4, 24),
};
static const unsigned int ssi1_ctrl_mux[] = {
SSI_SCK1_MARK, SSI_WS1_MARK,
};
static const unsigned int ssi2_data_pins[] = {
/* SDATA2 */
RCAR_GP_PIN(4, 7),
};
static const unsigned int ssi2_data_mux[] = {
SSI_SDATA2_MARK,
};
static const unsigned int ssi2_ctrl_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(5, 13), RCAR_GP_PIN(5, 17),
};
static const unsigned int ssi2_ctrl_mux[] = {
SSI_SCK2_MARK, SSI_WS2_MARK,
};
static const unsigned int ssi3_data_pins[] = {
/* SDATA3 */
RCAR_GP_PIN(4, 10),
};
static const unsigned int ssi3_data_mux[] = {
SSI_SDATA3_MARK
};
static const unsigned int ssi34_ctrl_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(4, 8), RCAR_GP_PIN(4, 9),
};
static const unsigned int ssi34_ctrl_mux[] = {
SSI_SCK34_MARK, SSI_WS34_MARK,
};
static const unsigned int ssi4_data_pins[] = {
/* SDATA4 */
RCAR_GP_PIN(4, 13),
};
static const unsigned int ssi4_data_mux[] = {
SSI_SDATA4_MARK,
};
static const unsigned int ssi4_ctrl_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(4, 11), RCAR_GP_PIN(4, 12),
};
static const unsigned int ssi4_ctrl_mux[] = {
SSI_SCK4_MARK, SSI_WS4_MARK,
};
static const unsigned int ssi5_pins[] = {
/* SDATA5, SCK, WS */
RCAR_GP_PIN(4, 16), RCAR_GP_PIN(4, 14), RCAR_GP_PIN(4, 15),
};
static const unsigned int ssi5_mux[] = {
SSI_SDATA5_MARK, SSI_SCK5_MARK, SSI_WS5_MARK,
};
static const unsigned int ssi5_b_pins[] = {
/* SDATA5, SCK, WS */
RCAR_GP_PIN(0, 26), RCAR_GP_PIN(0, 24), RCAR_GP_PIN(0, 25),
};
static const unsigned int ssi5_b_mux[] = {
SSI_SDATA5_B_MARK, SSI_SCK5_B_MARK, SSI_WS5_B_MARK
};
static const unsigned int ssi5_c_pins[] = {
/* SDATA5, SCK, WS */
RCAR_GP_PIN(4, 24), RCAR_GP_PIN(4, 11), RCAR_GP_PIN(4, 12),
};
static const unsigned int ssi5_c_mux[] = {
SSI_SDATA5_C_MARK, SSI_SCK5_C_MARK, SSI_WS5_C_MARK,
};
static const unsigned int ssi6_pins[] = {
/* SDATA6, SCK, WS */
RCAR_GP_PIN(4, 19), RCAR_GP_PIN(4, 17), RCAR_GP_PIN(4, 18),
};
static const unsigned int ssi6_mux[] = {
SSI_SDATA6_MARK, SSI_SCK6_MARK, SSI_WS6_MARK,
};
static const unsigned int ssi6_b_pins[] = {
/* SDATA6, SCK, WS */
RCAR_GP_PIN(1, 29), RCAR_GP_PIN(1, 25), RCAR_GP_PIN(1, 27),
};
static const unsigned int ssi6_b_mux[] = {
SSI_SDATA6_B_MARK, SSI_SCK6_B_MARK, SSI_WS6_B_MARK,
};
static const unsigned int ssi7_data_pins[] = {
/* SDATA7 */
RCAR_GP_PIN(4, 22),
};
static const unsigned int ssi7_data_mux[] = {
SSI_SDATA7_MARK,
};
static const unsigned int ssi7_b_data_pins[] = {
/* SDATA7 */
RCAR_GP_PIN(4, 22),
};
static const unsigned int ssi7_b_data_mux[] = {
SSI_SDATA7_B_MARK,
};
static const unsigned int ssi7_c_data_pins[] = {
/* SDATA7 */
RCAR_GP_PIN(1, 26),
};
static const unsigned int ssi7_c_data_mux[] = {
SSI_SDATA7_C_MARK,
};
static const unsigned int ssi78_ctrl_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(4, 20), RCAR_GP_PIN(4, 21),
};
static const unsigned int ssi78_ctrl_mux[] = {
SSI_SCK78_MARK, SSI_WS78_MARK,
};
static const unsigned int ssi78_b_ctrl_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(1, 26), RCAR_GP_PIN(1, 24),
};
static const unsigned int ssi78_b_ctrl_mux[] = {
SSI_SCK78_B_MARK, SSI_WS78_B_MARK,
};
static const unsigned int ssi78_c_ctrl_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(1, 24), RCAR_GP_PIN(1, 25),
};
static const unsigned int ssi78_c_ctrl_mux[] = {
SSI_SCK78_C_MARK, SSI_WS78_C_MARK,
};
static const unsigned int ssi8_data_pins[] = {
/* SDATA8 */
RCAR_GP_PIN(4, 23),
};
static const unsigned int ssi8_data_mux[] = {
SSI_SDATA8_MARK,
};
static const unsigned int ssi8_b_data_pins[] = {
/* SDATA8 */
RCAR_GP_PIN(4, 23),
};
static const unsigned int ssi8_b_data_mux[] = {
SSI_SDATA8_B_MARK,
};
static const unsigned int ssi8_c_data_pins[] = {
/* SDATA8 */
RCAR_GP_PIN(1, 27),
};
static const unsigned int ssi8_c_data_mux[] = {
SSI_SDATA8_C_MARK,
};
static const unsigned int ssi9_data_pins[] = {
/* SDATA9 */
RCAR_GP_PIN(4, 24),
};
static const unsigned int ssi9_data_mux[] = {
SSI_SDATA9_MARK,
};
static const unsigned int ssi9_ctrl_pins[] = {
/* SCK, WS */
RCAR_GP_PIN(5, 10), RCAR_GP_PIN(5, 11),
};
static const unsigned int ssi9_ctrl_mux[] = {
SSI_SCK9_MARK, SSI_WS9_MARK,
};
/* - TPU0 ------------------------------------------------------------------- */
static const unsigned int tpu0_to0_pins[] = {
/* TO */
......@@ -3014,59 +3247,110 @@ static const unsigned int usb2_pins[] = {
static const unsigned int usb2_mux[] = {
USB2_PWEN_MARK, USB2_OVC_MARK,
};
/* - VIN0 ------------------------------------------------------------------- */
static const unsigned int vin0_data_g_pins[] = {
RCAR_GP_PIN(0, 8), RCAR_GP_PIN(0, 9), RCAR_GP_PIN(0, 10),
RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 0), RCAR_GP_PIN(0, 1),
RCAR_GP_PIN(0, 2), RCAR_GP_PIN(0, 3),
};
static const unsigned int vin0_data_g_mux[] = {
VI0_G0_MARK, VI0_G1_MARK, VI0_G2_MARK,
VI0_G3_MARK, VI0_G4_MARK, VI0_G5_MARK,
VI0_G6_MARK, VI0_G7_MARK,
union vin_data {
unsigned int data24[24];
unsigned int data20[20];
unsigned int data16[16];
unsigned int data12[12];
unsigned int data10[10];
unsigned int data8[8];
unsigned int data4[4];
};
static const unsigned int vin0_data_r_pins[] = {
RCAR_GP_PIN(0, 4), RCAR_GP_PIN(0, 5), RCAR_GP_PIN(0, 6),
RCAR_GP_PIN(0, 7), RCAR_GP_PIN(0, 24), RCAR_GP_PIN(0, 25),
RCAR_GP_PIN(0, 26), RCAR_GP_PIN(1, 11),
#define VIN_DATA_PIN_GROUP(n, s) \
{ \
.name = #n#s, \
.pins = n##_pins.data##s, \
.mux = n##_mux.data##s, \
.nr_pins = ARRAY_SIZE(n##_pins.data##s), \
}
/* - VIN0 ------------------------------------------------------------------- */
static const union vin_data vin0_data_pins = {
.data24 = {
/* B */
RCAR_GP_PIN(2, 1), RCAR_GP_PIN(2, 2),
RCAR_GP_PIN(2, 3), RCAR_GP_PIN(2, 4),
RCAR_GP_PIN(2, 5), RCAR_GP_PIN(2, 6),
RCAR_GP_PIN(2, 7), RCAR_GP_PIN(2, 8),
/* G */
RCAR_GP_PIN(0, 8), RCAR_GP_PIN(0, 9),
RCAR_GP_PIN(0, 10), RCAR_GP_PIN(0, 11),
RCAR_GP_PIN(0, 0), RCAR_GP_PIN(0, 1),
RCAR_GP_PIN(0, 2), RCAR_GP_PIN(0, 3),
/* R */
RCAR_GP_PIN(0, 4), RCAR_GP_PIN(0, 5),
RCAR_GP_PIN(0, 6), RCAR_GP_PIN(0, 7),
RCAR_GP_PIN(0, 24), RCAR_GP_PIN(0, 25),
RCAR_GP_PIN(0, 26), RCAR_GP_PIN(1, 11),
},
};
static const unsigned int vin0_data_r_mux[] = {
VI0_R0_MARK, VI0_R1_MARK, VI0_R2_MARK,
VI0_R3_MARK, VI0_R4_MARK, VI0_R5_MARK,
VI0_R6_MARK, VI0_R7_MARK,
static const union vin_data vin0_data_mux = {
.data24 = {
/* B */
VI0_DATA0_VI0_B0_MARK, VI0_DATA1_VI0_B1_MARK,
VI0_DATA2_VI0_B2_MARK, VI0_DATA3_VI0_B3_MARK,
VI0_DATA4_VI0_B4_MARK, VI0_DATA5_VI0_B5_MARK,
VI0_DATA6_VI0_B6_MARK, VI0_DATA7_VI0_B7_MARK,
/* G */
VI0_G0_MARK, VI0_G1_MARK,
VI0_G2_MARK, VI0_G3_MARK,
VI0_G4_MARK, VI0_G5_MARK,
VI0_G6_MARK, VI0_G7_MARK,
/* R */
VI0_R0_MARK, VI0_R1_MARK,
VI0_R2_MARK, VI0_R3_MARK,
VI0_R4_MARK, VI0_R5_MARK,
VI0_R6_MARK, VI0_R7_MARK,
},
};
static const unsigned int vin0_data_b_pins[] = {
RCAR_GP_PIN(2, 1), RCAR_GP_PIN(2, 2), RCAR_GP_PIN(2, 3),
RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5), RCAR_GP_PIN(2, 6),
static const unsigned int vin0_data18_pins[] = {
/* B */
RCAR_GP_PIN(2, 3), RCAR_GP_PIN(2, 4),
RCAR_GP_PIN(2, 5), RCAR_GP_PIN(2, 6),
RCAR_GP_PIN(2, 7), RCAR_GP_PIN(2, 8),
/* G */
RCAR_GP_PIN(0, 10), RCAR_GP_PIN(0, 11),
RCAR_GP_PIN(0, 0), RCAR_GP_PIN(0, 1),
RCAR_GP_PIN(0, 2), RCAR_GP_PIN(0, 3),
/* R */
RCAR_GP_PIN(0, 6), RCAR_GP_PIN(0, 7),
RCAR_GP_PIN(0, 24), RCAR_GP_PIN(0, 25),
RCAR_GP_PIN(0, 26), RCAR_GP_PIN(1, 11),
};
static const unsigned int vin0_data_b_mux[] = {
VI0_DATA0_VI0_B0_MARK, VI0_DATA1_VI0_B1_MARK, VI0_DATA2_VI0_B2_MARK,
VI0_DATA3_VI0_B3_MARK, VI0_DATA4_VI0_B4_MARK, VI0_DATA5_VI0_B5_MARK,
static const unsigned int vin0_data18_mux[] = {
/* B */
VI0_DATA2_VI0_B2_MARK, VI0_DATA3_VI0_B3_MARK,
VI0_DATA4_VI0_B4_MARK, VI0_DATA5_VI0_B5_MARK,
VI0_DATA6_VI0_B6_MARK, VI0_DATA7_VI0_B7_MARK,
/* G */
VI0_G2_MARK, VI0_G3_MARK,
VI0_G4_MARK, VI0_G5_MARK,
VI0_G6_MARK, VI0_G7_MARK,
/* R */
VI0_R2_MARK, VI0_R3_MARK,
VI0_R4_MARK, VI0_R5_MARK,
VI0_R6_MARK, VI0_R7_MARK,
};
static const unsigned int vin0_hsync_signal_pins[] = {
RCAR_GP_PIN(0, 12),
static const unsigned int vin0_sync_pins[] = {
RCAR_GP_PIN(0, 12), /* HSYNC */
RCAR_GP_PIN(0, 13), /* VSYNC */
};
static const unsigned int vin0_hsync_signal_mux[] = {
static const unsigned int vin0_sync_mux[] = {
VI0_HSYNC_N_MARK,
};
static const unsigned int vin0_vsync_signal_pins[] = {
RCAR_GP_PIN(0, 13),
};
static const unsigned int vin0_vsync_signal_mux[] = {
VI0_VSYNC_N_MARK,
};
static const unsigned int vin0_field_signal_pins[] = {
static const unsigned int vin0_field_pins[] = {
RCAR_GP_PIN(0, 15),
};
static const unsigned int vin0_field_signal_mux[] = {
static const unsigned int vin0_field_mux[] = {
VI0_FIELD_MARK,
};
static const unsigned int vin0_data_enable_pins[] = {
static const unsigned int vin0_clkenb_pins[] = {
RCAR_GP_PIN(0, 14),
};
static const unsigned int vin0_data_enable_mux[] = {
static const unsigned int vin0_clkenb_mux[] = {
VI0_CLKENB_MARK,
};
static const unsigned int vin0_clk_pins[] = {
......@@ -3076,15 +3360,91 @@ static const unsigned int vin0_clk_mux[] = {
VI0_CLK_MARK,
};
/* - VIN1 ------------------------------------------------------------------- */
static const unsigned int vin1_data_pins[] = {
RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11), RCAR_GP_PIN(2, 12),
RCAR_GP_PIN(2, 13), RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 15),
RCAR_GP_PIN(2, 16), RCAR_GP_PIN(2, 17),
static const union vin_data vin1_data_pins = {
.data24 = {
/* B */
RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11),
RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13),
RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 15),
RCAR_GP_PIN(2, 16), RCAR_GP_PIN(2, 17),
/* G */
RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 15),
RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 20),
RCAR_GP_PIN(1, 22), RCAR_GP_PIN(1, 12),
RCAR_GP_PIN(1, 9), RCAR_GP_PIN(1, 7),
/* R */
RCAR_GP_PIN(0, 27), RCAR_GP_PIN(0, 28),
RCAR_GP_PIN(0, 29), RCAR_GP_PIN(1, 4),
RCAR_GP_PIN(1, 5), RCAR_GP_PIN(1, 6),
RCAR_GP_PIN(1, 10), RCAR_GP_PIN(1, 8),
},
};
static const unsigned int vin1_data_mux[] = {
VI1_DATA0_VI1_B0_MARK, VI1_DATA1_VI1_B1_MARK, VI1_DATA2_VI1_B2_MARK,
VI1_DATA3_VI1_B3_MARK, VI1_DATA4_VI1_B4_MARK, VI1_DATA5_VI1_B5_MARK,
static const union vin_data vin1_data_mux = {
.data24 = {
/* B */
VI1_DATA0_VI1_B0_MARK, VI1_DATA1_VI1_B1_MARK,
VI1_DATA2_VI1_B2_MARK, VI1_DATA3_VI1_B3_MARK,
VI1_DATA4_VI1_B4_MARK, VI1_DATA5_VI1_B5_MARK,
VI1_DATA6_VI1_B6_MARK, VI1_DATA7_VI1_B7_MARK,
/* G */
VI1_G0_MARK, VI1_G1_MARK,
VI1_G2_MARK, VI1_G3_MARK,
VI1_G4_MARK, VI1_G5_MARK,
VI1_G6_MARK, VI1_G7_MARK,
/* R */
VI1_R0_MARK, VI1_R1_MARK,
VI1_R2_MARK, VI1_R3_MARK,
VI1_R4_MARK, VI1_R5_MARK,
VI1_R6_MARK, VI1_R7_MARK,
},
};
static const unsigned int vin1_data18_pins[] = {
/* B */
RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13),
RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 15),
RCAR_GP_PIN(2, 16), RCAR_GP_PIN(2, 17),
/* G */
RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 20),
RCAR_GP_PIN(1, 22), RCAR_GP_PIN(1, 12),
RCAR_GP_PIN(1, 9), RCAR_GP_PIN(1, 7),
/* R */
RCAR_GP_PIN(0, 29), RCAR_GP_PIN(1, 4),
RCAR_GP_PIN(1, 5), RCAR_GP_PIN(1, 6),
RCAR_GP_PIN(1, 10), RCAR_GP_PIN(1, 8),
};
static const unsigned int vin1_data18_mux[] = {
/* B */
VI1_DATA2_VI1_B2_MARK, VI1_DATA3_VI1_B3_MARK,
VI1_DATA4_VI1_B4_MARK, VI1_DATA5_VI1_B5_MARK,
VI1_DATA6_VI1_B6_MARK, VI1_DATA7_VI1_B7_MARK,
/* G */
VI1_G2_MARK, VI1_G3_MARK,
VI1_G4_MARK, VI1_G5_MARK,
VI1_G6_MARK, VI1_G7_MARK,
/* R */
VI1_R2_MARK, VI1_R3_MARK,
VI1_R4_MARK, VI1_R5_MARK,
VI1_R6_MARK, VI1_R7_MARK,
};
static const unsigned int vin1_sync_pins[] = {
RCAR_GP_PIN(1, 24), /* HSYNC */
RCAR_GP_PIN(1, 25), /* VSYNC */
};
static const unsigned int vin1_sync_mux[] = {
VI1_HSYNC_N_MARK,
VI1_VSYNC_N_MARK,
};
static const unsigned int vin1_field_pins[] = {
RCAR_GP_PIN(1, 13),
};
static const unsigned int vin1_field_mux[] = {
VI1_FIELD_MARK,
};
static const unsigned int vin1_clkenb_pins[] = {
RCAR_GP_PIN(1, 26),
};
static const unsigned int vin1_clkenb_mux[] = {
VI1_CLKENB_MARK,
};
static const unsigned int vin1_clk_pins[] = {
RCAR_GP_PIN(2, 9),
......@@ -3092,8 +3452,147 @@ static const unsigned int vin1_clk_pins[] = {
static const unsigned int vin1_clk_mux[] = {
VI1_CLK_MARK,
};
/* - VIN2 ----------------------------------------------------------------- */
static const union vin_data vin2_data_pins = {
.data24 = {
/* B */
RCAR_GP_PIN(0, 8), RCAR_GP_PIN(0, 9),
RCAR_GP_PIN(0, 10), RCAR_GP_PIN(0, 11),
RCAR_GP_PIN(0, 12), RCAR_GP_PIN(0, 13),
RCAR_GP_PIN(0, 14), RCAR_GP_PIN(0, 15),
/* G */
RCAR_GP_PIN(0, 27), RCAR_GP_PIN(0, 28),
RCAR_GP_PIN(0, 29), RCAR_GP_PIN(1, 10),
RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 5),
RCAR_GP_PIN(1, 6), RCAR_GP_PIN(1, 7),
/* R */
RCAR_GP_PIN(1, 12), RCAR_GP_PIN(1, 13),
RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 15),
RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 20),
RCAR_GP_PIN(1, 22), RCAR_GP_PIN(1, 24),
},
};
static const union vin_data vin2_data_mux = {
.data24 = {
/* B */
VI2_DATA0_VI2_B0_MARK, VI2_DATA1_VI2_B1_MARK,
VI2_DATA2_VI2_B2_MARK, VI2_DATA3_VI2_B3_MARK,
VI2_DATA4_VI2_B4_MARK, VI2_DATA5_VI2_B5_MARK,
VI2_DATA6_VI2_B6_MARK, VI2_DATA7_VI2_B7_MARK,
/* G */
VI2_G0_MARK, VI2_G1_MARK,
VI2_G2_MARK, VI2_G3_MARK,
VI2_G4_MARK, VI2_G5_MARK,
VI2_G6_MARK, VI2_G7_MARK,
/* R */
VI2_R0_MARK, VI2_R1_MARK,
VI2_R2_MARK, VI2_R3_MARK,
VI2_R4_MARK, VI2_R5_MARK,
VI2_R6_MARK, VI2_R7_MARK,
},
};
static const unsigned int vin2_data18_pins[] = {
/* B */
RCAR_GP_PIN(0, 10), RCAR_GP_PIN(0, 11),
RCAR_GP_PIN(0, 12), RCAR_GP_PIN(0, 13),
RCAR_GP_PIN(0, 14), RCAR_GP_PIN(0, 15),
/* G */
RCAR_GP_PIN(0, 29), RCAR_GP_PIN(1, 10),
RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 5),
RCAR_GP_PIN(1, 6), RCAR_GP_PIN(1, 7),
/* R */
RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 15),
RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 20),
RCAR_GP_PIN(1, 22), RCAR_GP_PIN(1, 24),
};
static const unsigned int vin2_data18_mux[] = {
/* B */
VI2_DATA2_VI2_B2_MARK, VI2_DATA3_VI2_B3_MARK,
VI2_DATA4_VI2_B4_MARK, VI2_DATA5_VI2_B5_MARK,
VI2_DATA6_VI2_B6_MARK, VI2_DATA7_VI2_B7_MARK,
/* G */
VI2_G2_MARK, VI2_G3_MARK,
VI2_G4_MARK, VI2_G5_MARK,
VI2_G6_MARK, VI2_G7_MARK,
/* R */
VI2_R2_MARK, VI2_R3_MARK,
VI2_R4_MARK, VI2_R5_MARK,
VI2_R6_MARK, VI2_R7_MARK,
};
static const unsigned int vin2_sync_pins[] = {
RCAR_GP_PIN(1, 16), /* HSYNC */
RCAR_GP_PIN(1, 21), /* VSYNC */
};
static const unsigned int vin2_sync_mux[] = {
VI2_HSYNC_N_MARK,
VI2_VSYNC_N_MARK,
};
static const unsigned int vin2_field_pins[] = {
RCAR_GP_PIN(1, 9),
};
static const unsigned int vin2_field_mux[] = {
VI2_FIELD_MARK,
};
static const unsigned int vin2_clkenb_pins[] = {
RCAR_GP_PIN(1, 8),
};
static const unsigned int vin2_clkenb_mux[] = {
VI2_CLKENB_MARK,
};
static const unsigned int vin2_clk_pins[] = {
RCAR_GP_PIN(1, 11),
};
static const unsigned int vin2_clk_mux[] = {
VI2_CLK_MARK,
};
/* - VIN3 ----------------------------------------------------------------- */
static const unsigned int vin3_data8_pins[] = {
RCAR_GP_PIN(0, 0), RCAR_GP_PIN(0, 1),
RCAR_GP_PIN(0, 2), RCAR_GP_PIN(0, 3),
RCAR_GP_PIN(0, 4), RCAR_GP_PIN(0, 5),
RCAR_GP_PIN(0, 6), RCAR_GP_PIN(0, 7),
};
static const unsigned int vin3_data8_mux[] = {
VI3_DATA0_MARK, VI3_DATA1_MARK,
VI3_DATA2_MARK, VI3_DATA3_MARK,
VI3_DATA4_MARK, VI3_DATA5_MARK,
VI3_DATA6_MARK, VI3_DATA7_MARK,
};
static const unsigned int vin3_sync_pins[] = {
RCAR_GP_PIN(1, 16), /* HSYNC */
RCAR_GP_PIN(1, 17), /* VSYNC */
};
static const unsigned int vin3_sync_mux[] = {
VI3_HSYNC_N_MARK,
VI2_VSYNC_N_MARK,
};
static const unsigned int vin3_field_pins[] = {
RCAR_GP_PIN(1, 15),
};
static const unsigned int vin3_field_mux[] = {
VI3_FIELD_MARK,
};
static const unsigned int vin3_clkenb_pins[] = {
RCAR_GP_PIN(1, 14),
};
static const unsigned int vin3_clkenb_mux[] = {
VI3_CLKENB_MARK,
};
static const unsigned int vin3_clk_pins[] = {
RCAR_GP_PIN(1, 23),
};
static const unsigned int vin3_clk_mux[] = {
VI3_CLK_MARK,
};
static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(audio_clk_a),
SH_PFC_PIN_GROUP(audio_clk_b),
SH_PFC_PIN_GROUP(audio_clk_c),
SH_PFC_PIN_GROUP(audio_clkout),
SH_PFC_PIN_GROUP(audio_clkout_b),
SH_PFC_PIN_GROUP(audio_clkout_c),
SH_PFC_PIN_GROUP(audio_clkout_d),
SH_PFC_PIN_GROUP(du_rgb666),
SH_PFC_PIN_GROUP(du_rgb888),
SH_PFC_PIN_GROUP(du_clk_out_0),
......@@ -3259,6 +3758,32 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(sdhi3_ctrl),
SH_PFC_PIN_GROUP(sdhi3_cd),
SH_PFC_PIN_GROUP(sdhi3_wp),
SH_PFC_PIN_GROUP(ssi0_data),
SH_PFC_PIN_GROUP(ssi0129_ctrl),
SH_PFC_PIN_GROUP(ssi1_data),
SH_PFC_PIN_GROUP(ssi1_ctrl),
SH_PFC_PIN_GROUP(ssi2_data),
SH_PFC_PIN_GROUP(ssi2_ctrl),
SH_PFC_PIN_GROUP(ssi3_data),
SH_PFC_PIN_GROUP(ssi34_ctrl),
SH_PFC_PIN_GROUP(ssi4_data),
SH_PFC_PIN_GROUP(ssi4_ctrl),
SH_PFC_PIN_GROUP(ssi5),
SH_PFC_PIN_GROUP(ssi5_b),
SH_PFC_PIN_GROUP(ssi5_c),
SH_PFC_PIN_GROUP(ssi6),
SH_PFC_PIN_GROUP(ssi6_b),
SH_PFC_PIN_GROUP(ssi7_data),
SH_PFC_PIN_GROUP(ssi7_b_data),
SH_PFC_PIN_GROUP(ssi7_c_data),
SH_PFC_PIN_GROUP(ssi78_ctrl),
SH_PFC_PIN_GROUP(ssi78_b_ctrl),
SH_PFC_PIN_GROUP(ssi78_c_ctrl),
SH_PFC_PIN_GROUP(ssi8_data),
SH_PFC_PIN_GROUP(ssi8_b_data),
SH_PFC_PIN_GROUP(ssi8_c_data),
SH_PFC_PIN_GROUP(ssi9_data),
SH_PFC_PIN_GROUP(ssi9_ctrl),
SH_PFC_PIN_GROUP(tpu0_to0),
SH_PFC_PIN_GROUP(tpu0_to1),
SH_PFC_PIN_GROUP(tpu0_to2),
......@@ -3266,16 +3791,54 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(usb0),
SH_PFC_PIN_GROUP(usb1),
SH_PFC_PIN_GROUP(usb2),
SH_PFC_PIN_GROUP(vin0_data_g),
SH_PFC_PIN_GROUP(vin0_data_r),
SH_PFC_PIN_GROUP(vin0_data_b),
SH_PFC_PIN_GROUP(vin0_hsync_signal),
SH_PFC_PIN_GROUP(vin0_vsync_signal),
SH_PFC_PIN_GROUP(vin0_field_signal),
SH_PFC_PIN_GROUP(vin0_data_enable),
VIN_DATA_PIN_GROUP(vin0_data, 24),
VIN_DATA_PIN_GROUP(vin0_data, 20),
SH_PFC_PIN_GROUP(vin0_data18),
VIN_DATA_PIN_GROUP(vin0_data, 16),
VIN_DATA_PIN_GROUP(vin0_data, 12),
VIN_DATA_PIN_GROUP(vin0_data, 10),
VIN_DATA_PIN_GROUP(vin0_data, 8),
VIN_DATA_PIN_GROUP(vin0_data, 4),
SH_PFC_PIN_GROUP(vin0_sync),
SH_PFC_PIN_GROUP(vin0_field),
SH_PFC_PIN_GROUP(vin0_clkenb),
SH_PFC_PIN_GROUP(vin0_clk),
SH_PFC_PIN_GROUP(vin1_data),
VIN_DATA_PIN_GROUP(vin1_data, 24),
VIN_DATA_PIN_GROUP(vin1_data, 20),
SH_PFC_PIN_GROUP(vin1_data18),
VIN_DATA_PIN_GROUP(vin1_data, 16),
VIN_DATA_PIN_GROUP(vin1_data, 12),
VIN_DATA_PIN_GROUP(vin1_data, 10),
VIN_DATA_PIN_GROUP(vin1_data, 8),
VIN_DATA_PIN_GROUP(vin1_data, 4),
SH_PFC_PIN_GROUP(vin1_sync),
SH_PFC_PIN_GROUP(vin1_field),
SH_PFC_PIN_GROUP(vin1_clkenb),
SH_PFC_PIN_GROUP(vin1_clk),
VIN_DATA_PIN_GROUP(vin2_data, 24),
SH_PFC_PIN_GROUP(vin2_data18),
VIN_DATA_PIN_GROUP(vin2_data, 16),
VIN_DATA_PIN_GROUP(vin2_data, 8),
VIN_DATA_PIN_GROUP(vin2_data, 4),
SH_PFC_PIN_GROUP(vin2_sync),
SH_PFC_PIN_GROUP(vin2_field),
SH_PFC_PIN_GROUP(vin2_clkenb),
SH_PFC_PIN_GROUP(vin2_clk),
SH_PFC_PIN_GROUP(vin3_data8),
SH_PFC_PIN_GROUP(vin3_sync),
SH_PFC_PIN_GROUP(vin3_field),
SH_PFC_PIN_GROUP(vin3_clkenb),
SH_PFC_PIN_GROUP(vin3_clk),
};
static const char * const audio_clk_groups[] = {
"audio_clk_a",
"audio_clk_b",
"audio_clk_c",
"audio_clkout",
"audio_clkout_b",
"audio_clkout_c",
"audio_clkout_d",
};
static const char * const du_groups[] = {
......@@ -3533,6 +4096,35 @@ static const char * const sdhi3_groups[] = {
"sdhi3_wp",
};
static const char * const ssi_groups[] = {
"ssi0_data",
"ssi0129_ctrl",
"ssi1_data",
"ssi1_ctrl",
"ssi2_data",
"ssi2_ctrl",
"ssi3_data",
"ssi34_ctrl",
"ssi4_data",
"ssi4_ctrl",
"ssi5",
"ssi5_b",
"ssi5_c",
"ssi6",
"ssi6_b",
"ssi7_data",
"ssi7_b_data",
"ssi7_c_data",
"ssi78_ctrl",
"ssi78_b_ctrl",
"ssi78_c_ctrl",
"ssi8_data",
"ssi8_b_data",
"ssi8_c_data",
"ssi9_data",
"ssi9_ctrl",
};
static const char * const tpu0_groups[] = {
"tpu0_to0",
"tpu0_to1",
......@@ -3553,22 +4145,57 @@ static const char * const usb2_groups[] = {
};
static const char * const vin0_groups[] = {
"vin0_data_g",
"vin0_data_r",
"vin0_data_b",
"vin0_hsync_signal",
"vin0_vsync_signal",
"vin0_field_signal",
"vin0_data_enable",
"vin0_data24",
"vin0_data20",
"vin0_data18",
"vin0_data16",
"vin0_data12",
"vin0_data10",
"vin0_data8",
"vin0_data4",
"vin0_sync",
"vin0_field",
"vin0_clkenb",
"vin0_clk",
};
static const char * const vin1_groups[] = {
"vin1_data",
"vin1_data24",
"vin1_data20",
"vin1_data18",
"vin1_data16",
"vin1_data12",
"vin1_data10",
"vin1_data8",
"vin1_data4",
"vin1_sync",
"vin1_field",
"vin1_clkenb",
"vin1_clk",
};
static const char * const vin2_groups[] = {
"vin2_data24",
"vin2_data18",
"vin2_data16",
"vin2_data8",
"vin2_data4",
"vin2_sync",
"vin2_field",
"vin2_clkenb",
"vin2_clk",
};
static const char * const vin3_groups[] = {
"vin3_data8",
"vin3_sync",
"vin3_field",
"vin3_clkenb",
"vin3_clk",
};
static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(audio_clk),
SH_PFC_FUNCTION(du),
SH_PFC_FUNCTION(du0),
SH_PFC_FUNCTION(du1),
......@@ -3599,12 +4226,15 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(sdhi1),
SH_PFC_FUNCTION(sdhi2),
SH_PFC_FUNCTION(sdhi3),
SH_PFC_FUNCTION(ssi),
SH_PFC_FUNCTION(tpu0),
SH_PFC_FUNCTION(usb0),
SH_PFC_FUNCTION(usb1),
SH_PFC_FUNCTION(usb2),
SH_PFC_FUNCTION(vin0),
SH_PFC_FUNCTION(vin1),
SH_PFC_FUNCTION(vin2),
SH_PFC_FUNCTION(vin3),
};
static struct pinmux_cfg_reg pinmux_config_regs[] = {
......
......@@ -1730,11 +1730,11 @@ static const unsigned int du_clk_out_1_pins[] = {
static const unsigned int du_clk_out_1_mux[] = {
DU1_DOTCLKOUT1_MARK
};
static const unsigned int du_sync_1_pins[] = {
static const unsigned int du_sync_pins[] = {
/* EXVSYNC/VSYNC, EXHSYNC/HSYNC, EXDISP/EXODDF/EXCDE */
RCAR_GP_PIN(3, 29), RCAR_GP_PIN(3, 28), RCAR_GP_PIN(3, 27),
};
static const unsigned int du_sync_1_mux[] = {
static const unsigned int du_sync_mux[] = {
DU1_EXODDF_DU1_ODDF_DISP_CDE_MARK,
DU1_EXVSYNC_DU1_VSYNC_MARK, DU1_EXHSYNC_DU1_HSYNC_MARK
};
......@@ -1742,6 +1742,9 @@ static const unsigned int du_cde_disp_pins[] = {
/* CDE DISP */
RCAR_GP_PIN(3, 31), RCAR_GP_PIN(3, 30),
};
static const unsigned int du_cde_disp_mux[] = {
DU1_CDE_MARK, DU1_DISP_MARK
};
static const unsigned int du0_clk_in_pins[] = {
/* CLKIN */
RCAR_GP_PIN(6, 31),
......@@ -1749,15 +1752,26 @@ static const unsigned int du0_clk_in_pins[] = {
static const unsigned int du0_clk_in_mux[] = {
DU0_DOTCLKIN_MARK
};
static const unsigned int du_cde_disp_mux[] = {
DU1_CDE_MARK, DU1_DISP_MARK
};
static const unsigned int du1_clk_in_pins[] = {
/* CLKIN */
RCAR_GP_PIN(7, 20), RCAR_GP_PIN(7, 19), RCAR_GP_PIN(3, 24),
RCAR_GP_PIN(3, 24),
};
static const unsigned int du1_clk_in_mux[] = {
DU1_DOTCLKIN_C_MARK, DU1_DOTCLKIN_B_MARK, DU1_DOTCLKIN_MARK
DU1_DOTCLKIN_MARK
};
static const unsigned int du1_clk_in_b_pins[] = {
/* CLKIN */
RCAR_GP_PIN(7, 19),
};
static const unsigned int du1_clk_in_b_mux[] = {
DU1_DOTCLKIN_B_MARK,
};
static const unsigned int du1_clk_in_c_pins[] = {
/* CLKIN */
RCAR_GP_PIN(7, 20),
};
static const unsigned int du1_clk_in_c_mux[] = {
DU1_DOTCLKIN_C_MARK,
};
/* - ETH -------------------------------------------------------------------- */
static const unsigned int eth_link_pins[] = {
......@@ -2670,10 +2684,12 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
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_1),
SH_PFC_PIN_GROUP(du_sync),
SH_PFC_PIN_GROUP(du_cde_disp),
SH_PFC_PIN_GROUP(du0_clk_in),
SH_PFC_PIN_GROUP(du1_clk_in),
SH_PFC_PIN_GROUP(du1_clk_in_b),
SH_PFC_PIN_GROUP(du1_clk_in_c),
SH_PFC_PIN_GROUP(eth_link),
SH_PFC_PIN_GROUP(eth_magic),
SH_PFC_PIN_GROUP(eth_mdio),
......@@ -2805,7 +2821,7 @@ static const char * const du_groups[] = {
"du_rgb888",
"du_clk_out_0",
"du_clk_out_1",
"du_sync_1",
"du_sync",
"du_cde_disp",
};
......@@ -2815,6 +2831,8 @@ static const char * const du0_groups[] = {
static const char * const du1_groups[] = {
"du1_clk_in",
"du1_clk_in_b",
"du1_clk_in_c",
};
static const char * const eth_groups[] = {
......@@ -2840,20 +2858,29 @@ static const char * const mmc_groups[] = {
static const char * const msiof0_groups[] = {
"msiof0_clk",
"msiof0_ctrl",
"msiof0_data",
"msiof0_sync",
"msiof0_ss1",
"msiof0_ss2",
"msiof0_rx",
"msiof0_tx",
};
static const char * const msiof1_groups[] = {
"msiof1_clk",
"msiof1_ctrl",
"msiof1_data",
"msiof1_sync",
"msiof1_ss1",
"msiof1_ss2",
"msiof1_rx",
"msiof1_tx",
};
static const char * const msiof2_groups[] = {
"msiof2_clk",
"msiof2_ctrl",
"msiof2_data",
"msiof2_sync",
"msiof2_ss1",
"msiof2_ss2",
"msiof2_rx",
"msiof2_tx",
};
static const char * const scif0_groups[] = {
......
......@@ -2118,17 +2118,6 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(usb1),
};
#undef PORTCR
#define PORTCR(nr, reg) \
{ \
PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
_PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT), \
PORT##nr##_FN0, PORT##nr##_FN1, \
PORT##nr##_FN2, PORT##nr##_FN3, \
PORT##nr##_FN4, PORT##nr##_FN5, \
PORT##nr##_FN6, PORT##nr##_FN7 } \
}
static const struct pinmux_cfg_reg pinmux_config_regs[] = {
PORTCR(0, 0xE6051000), /* PORT0CR */
PORTCR(1, 0xE6051001), /* PORT1CR */
......@@ -2585,7 +2574,7 @@ static void __iomem *sh7372_pinmux_portcr(struct sh_pfc *pfc, unsigned int pin)
&sh7372_portcr_offsets[i];
if (i <= group->end_pin)
return pfc->window->virt + group->offset + pin;
return pfc->windows->virt + group->offset + pin;
}
return NULL;
......
......@@ -3138,16 +3138,6 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(usb),
};
#undef PORTCR
#define PORTCR(nr, reg) \
{ \
PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
_PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT), \
PORT##nr##_FN0, PORT##nr##_FN1, \
PORT##nr##_FN2, PORT##nr##_FN3, \
PORT##nr##_FN4, PORT##nr##_FN5, \
PORT##nr##_FN6, PORT##nr##_FN7 } \
}
static const struct pinmux_cfg_reg pinmux_config_regs[] = {
PORTCR(0, 0xe6050000), /* PORT0CR */
PORTCR(1, 0xe6050001), /* PORT1CR */
......@@ -3661,38 +3651,38 @@ static const struct pinmux_data_reg pinmux_data_regs[] = {
};
static const struct pinmux_irq pinmux_irqs[] = {
PINMUX_IRQ(irq_pin(19), 9),
PINMUX_IRQ(irq_pin(1), 10),
PINMUX_IRQ(irq_pin(0), 11),
PINMUX_IRQ(irq_pin(1), 10),
PINMUX_IRQ(irq_pin(2), 149),
PINMUX_IRQ(irq_pin(3), 224),
PINMUX_IRQ(irq_pin(4), 159),
PINMUX_IRQ(irq_pin(5), 227),
PINMUX_IRQ(irq_pin(6), 147),
PINMUX_IRQ(irq_pin(7), 150),
PINMUX_IRQ(irq_pin(8), 223),
PINMUX_IRQ(irq_pin(9), 56, 308),
PINMUX_IRQ(irq_pin(10), 54),
PINMUX_IRQ(irq_pin(11), 238),
PINMUX_IRQ(irq_pin(12), 156),
PINMUX_IRQ(irq_pin(13), 239),
PINMUX_IRQ(irq_pin(14), 251),
PINMUX_IRQ(irq_pin(15), 0),
PINMUX_IRQ(irq_pin(16), 249),
PINMUX_IRQ(irq_pin(17), 234),
PINMUX_IRQ(irq_pin(18), 13),
PINMUX_IRQ(irq_pin(19), 9),
PINMUX_IRQ(irq_pin(20), 14),
PINMUX_IRQ(irq_pin(21), 15),
PINMUX_IRQ(irq_pin(31), 26),
PINMUX_IRQ(irq_pin(30), 27),
PINMUX_IRQ(irq_pin(29), 28),
PINMUX_IRQ(irq_pin(22), 40),
PINMUX_IRQ(irq_pin(23), 53),
PINMUX_IRQ(irq_pin(10), 54),
PINMUX_IRQ(irq_pin(9), 56),
PINMUX_IRQ(irq_pin(24), 118),
PINMUX_IRQ(irq_pin(25), 164),
PINMUX_IRQ(irq_pin(26), 115),
PINMUX_IRQ(irq_pin(27), 116),
PINMUX_IRQ(irq_pin(28), 117),
PINMUX_IRQ(irq_pin(24), 118),
PINMUX_IRQ(irq_pin(6), 147),
PINMUX_IRQ(irq_pin(2), 149),
PINMUX_IRQ(irq_pin(7), 150),
PINMUX_IRQ(irq_pin(12), 156),
PINMUX_IRQ(irq_pin(4), 159),
PINMUX_IRQ(irq_pin(25), 164),
PINMUX_IRQ(irq_pin(8), 223),
PINMUX_IRQ(irq_pin(3), 224),
PINMUX_IRQ(irq_pin(5), 227),
PINMUX_IRQ(irq_pin(17), 234),
PINMUX_IRQ(irq_pin(11), 238),
PINMUX_IRQ(irq_pin(13), 239),
PINMUX_IRQ(irq_pin(16), 249),
PINMUX_IRQ(irq_pin(14), 251),
PINMUX_IRQ(irq_pin(9), 308),
PINMUX_IRQ(irq_pin(29), 28),
PINMUX_IRQ(irq_pin(30), 27),
PINMUX_IRQ(irq_pin(31), 26),
};
/* -----------------------------------------------------------------------------
......@@ -3702,7 +3692,7 @@ static const struct pinmux_irq pinmux_irqs[] = {
static void sh73a0_vccq_mc0_endisable(struct regulator_dev *reg, bool enable)
{
struct sh_pfc *pfc = reg->reg_data;
void __iomem *addr = pfc->window[1].virt + 4;
void __iomem *addr = pfc->windows[1].virt + 4;
unsigned long flags;
u32 value;
......@@ -3735,7 +3725,7 @@ static int sh73a0_vccq_mc0_disable(struct regulator_dev *reg)
static int sh73a0_vccq_mc0_is_enabled(struct regulator_dev *reg)
{
struct sh_pfc *pfc = reg->reg_data;
void __iomem *addr = pfc->window[1].virt + 4;
void __iomem *addr = pfc->windows[1].virt + 4;
unsigned long flags;
u32 value;
......@@ -3794,7 +3784,7 @@ static const unsigned int sh73a0_portcr_offsets[] = {
static unsigned int sh73a0_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin)
{
void __iomem *addr = pfc->window->virt
void __iomem *addr = pfc->windows->virt
+ sh73a0_portcr_offsets[pin >> 5] + pin;
u32 value = ioread8(addr) & PORTnCR_PULMD_MASK;
......@@ -3812,7 +3802,7 @@ static unsigned int sh73a0_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin)
static void sh73a0_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,
unsigned int bias)
{
void __iomem *addr = pfc->window->virt
void __iomem *addr = pfc->windows->virt
+ sh73a0_portcr_offsets[pin >> 5] + pin;
u32 value = ioread8(addr) & ~PORTnCR_PULMD_MASK;
......
......@@ -94,11 +94,11 @@ struct pinmux_data_reg {
struct pinmux_irq {
int irq;
unsigned short *gpios;
short *gpios;
};
#define PINMUX_IRQ(irq_nr, ids...) \
{ .irq = irq_nr, .gpios = (unsigned short []) { ids, 0 } } \
{ .irq = irq_nr, .gpios = (short []) { ids, -1 } }
struct pinmux_range {
u16 begin;
......@@ -304,8 +304,7 @@ struct sh_pfc_soc_info {
#define PORTCR(nr, reg) \
{ \
PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
_PCRH(PORT##nr##_IN, PORT##nr##_IN_PD, \
PORT##nr##_IN_PU, PORT##nr##_OUT), \
_PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT), \
PORT##nr##_FN0, PORT##nr##_FN1, \
PORT##nr##_FN2, PORT##nr##_FN3, \
PORT##nr##_FN4, PORT##nr##_FN5, \
......
......@@ -82,8 +82,10 @@
* operation, if several modes of operation are supported these can be
* passed in the argument on a custom form, else just use argument 1
* to indicate low power mode, argument 0 turns low power mode off.
* @PIN_CONFIG_OUTPUT: this will configure the pin in output, use argument
* 1 to indicate high level, argument 0 to indicate low level.
* @PIN_CONFIG_OUTPUT: this will configure the pin as an output. Use argument
* 1 to indicate high level, argument 0 to indicate low level. (Please
* see Documentation/pinctrl.txt, section "GPIO mode pitfalls" for a
* discussion around this parameter.)
* @PIN_CONFIG_END: this is the last enumerator for pin configurations, if
* you need to pass in custom configurations to the pin controller, use
* PIN_CONFIG_END+1 as the base offset.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment