diff options
Diffstat (limited to 'drivers/pinctrl/berlin')
-rw-r--r-- | drivers/pinctrl/berlin/Kconfig | 20 | ||||
-rw-r--r-- | drivers/pinctrl/berlin/Makefile | 4 | ||||
-rw-r--r-- | drivers/pinctrl/berlin/berlin-bg2.c | 274 | ||||
-rw-r--r-- | drivers/pinctrl/berlin/berlin-bg2cd.c | 217 | ||||
-rw-r--r-- | drivers/pinctrl/berlin/berlin-bg2q.c | 436 | ||||
-rw-r--r-- | drivers/pinctrl/berlin/berlin.c | 348 | ||||
-rw-r--r-- | drivers/pinctrl/berlin/berlin.h | 61 |
7 files changed, 1360 insertions, 0 deletions
diff --git a/drivers/pinctrl/berlin/Kconfig b/drivers/pinctrl/berlin/Kconfig new file mode 100644 index 00000000000..b18322bc7bf --- /dev/null +++ b/drivers/pinctrl/berlin/Kconfig @@ -0,0 +1,20 @@ +if ARCH_BERLIN + +config PINCTRL_BERLIN + bool + select PINMUX + select REGMAP_MMIO + +config PINCTRL_BERLIN_BG2 + bool + select PINCTRL_BERLIN + +config PINCTRL_BERLIN_BG2CD + bool + select PINCTRL_BERLIN + +config PINCTRL_BERLIN_BG2Q + bool + select PINCTRL_BERLIN + +endif diff --git a/drivers/pinctrl/berlin/Makefile b/drivers/pinctrl/berlin/Makefile new file mode 100644 index 00000000000..deb0c6baf31 --- /dev/null +++ b/drivers/pinctrl/berlin/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_PINCTRL_BERLIN) += berlin.o +obj-$(CONFIG_PINCTRL_BERLIN_BG2) += berlin-bg2.o +obj-$(CONFIG_PINCTRL_BERLIN_BG2CD) += berlin-bg2cd.o +obj-$(CONFIG_PINCTRL_BERLIN_BG2Q) += berlin-bg2q.o diff --git a/drivers/pinctrl/berlin/berlin-bg2.c b/drivers/pinctrl/berlin/berlin-bg2.c new file mode 100644 index 00000000000..dcd4f6a4fc5 --- /dev/null +++ b/drivers/pinctrl/berlin/berlin-bg2.c @@ -0,0 +1,274 @@ +/* + * Marvell Berlin BG2 pinctrl driver. + * + * Copyright (C) 2014 Marvell Technology Group Ltd. + * + * Antoine Ténart <antoine.tenart@free-electrons.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include "berlin.h" + +static const struct berlin_desc_group berlin2_soc_pinctrl_groups[] = { + /* G */ + BERLIN_PINCTRL_GROUP("G0", 0x00, 0x1, 0x00, + BERLIN_PINCTRL_FUNCTION(0x0, "spi1"), + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), + BERLIN_PINCTRL_GROUP("G1", 0x00, 0x2, 0x01, + BERLIN_PINCTRL_FUNCTION(0x0, "spi1"), + BERLIN_PINCTRL_FUNCTION(0x1, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x2, "usb1")), + BERLIN_PINCTRL_GROUP("G2", 0x00, 0x2, 0x02, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "spi1"), + BERLIN_PINCTRL_FUNCTION(0x2, "pwm"), + BERLIN_PINCTRL_FUNCTION(0x3, "i2s0")), + BERLIN_PINCTRL_GROUP("G3", 0x00, 0x2, 0x04, + BERLIN_PINCTRL_FUNCTION(0x0, "soc"), + BERLIN_PINCTRL_FUNCTION(0x1, "spi1"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x3, "i2s1")), + BERLIN_PINCTRL_GROUP("G4", 0x00, 0x2, 0x06, + BERLIN_PINCTRL_FUNCTION(0x0, "spi1"), + BERLIN_PINCTRL_FUNCTION(0x1, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x2, "pwm")), + BERLIN_PINCTRL_GROUP("G5", 0x00, 0x3, 0x08, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "sts1"), + BERLIN_PINCTRL_FUNCTION(0x2, "et"), + /* + * Mode 0x3 mux i2s2 mclk *and* i2s3 mclk: + * add two functions so it can be used with other groups + * within the same subnode in the device tree + */ + BERLIN_PINCTRL_FUNCTION(0x3, "i2s2"), + BERLIN_PINCTRL_FUNCTION(0x3, "i2s3")), + BERLIN_PINCTRL_GROUP("G6", 0x00, 0x2, 0x0b, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "sts0"), + BERLIN_PINCTRL_FUNCTION(0x2, "et")), + BERLIN_PINCTRL_GROUP("G7", 0x00, 0x3, 0x0d, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "sts0"), + BERLIN_PINCTRL_FUNCTION(0x2, "et"), + BERLIN_PINCTRL_FUNCTION(0x3, "vdac")), + BERLIN_PINCTRL_GROUP("G8", 0x00, 0x3, 0x10, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "sd0"), + BERLIN_PINCTRL_FUNCTION(0x2, "et"), + BERLIN_PINCTRL_FUNCTION(0x3, "usb0_dbg"), + BERLIN_PINCTRL_FUNCTION(0x4, "sata_dbg"), + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")), + BERLIN_PINCTRL_GROUP("G9", 0x00, 0x3, 0x13, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "sd0"), + BERLIN_PINCTRL_FUNCTION(0x2, "et"), + BERLIN_PINCTRL_FUNCTION(0x3, "usb0_dbg"), + BERLIN_PINCTRL_FUNCTION(0x4, "sata_dbg"), + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")), + BERLIN_PINCTRL_GROUP("G10", 0x00, 0x2, 0x16, + BERLIN_PINCTRL_FUNCTION(0x0, "soc"), + BERLIN_PINCTRL_FUNCTION(0x1, "twsi0"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x3, "ptp")), + BERLIN_PINCTRL_GROUP("G11", 0x00, 0x2, 0x18, + BERLIN_PINCTRL_FUNCTION(0x0, "soc"), + BERLIN_PINCTRL_FUNCTION(0x1, "twsi1"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x3, "eddc")), + BERLIN_PINCTRL_GROUP("G12", 0x00, 0x3, 0x1a, + BERLIN_PINCTRL_FUNCTION(0x0, "sts2"), + BERLIN_PINCTRL_FUNCTION(0x1, "sata"), + BERLIN_PINCTRL_FUNCTION(0x2, "sd1"), + BERLIN_PINCTRL_FUNCTION(0x3, "usb0_dbg"), + BERLIN_PINCTRL_FUNCTION(0x4, "sts1"), + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")), + BERLIN_PINCTRL_GROUP("G13", 0x04, 0x3, 0x00, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "sata"), + BERLIN_PINCTRL_FUNCTION(0x2, "sd1"), + BERLIN_PINCTRL_FUNCTION(0x3, "usb0_dbg"), + BERLIN_PINCTRL_FUNCTION(0x4, "sts1"), + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")), + BERLIN_PINCTRL_GROUP("G14", 0x04, 0x1, 0x03, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("G15", 0x04, 0x2, 0x04, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x2, "et"), + BERLIN_PINCTRL_FUNCTION(0x3, "osco")), + BERLIN_PINCTRL_GROUP("G16", 0x04, 0x3, 0x06, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"), + BERLIN_PINCTRL_FUNCTION(0x2, "fp")), + BERLIN_PINCTRL_GROUP("G17", 0x04, 0x3, 0x09, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"), + BERLIN_PINCTRL_FUNCTION(0x2, "fp")), + BERLIN_PINCTRL_GROUP("G18", 0x04, 0x1, 0x0c, + BERLIN_PINCTRL_FUNCTION(0x0, "pll"), + BERLIN_PINCTRL_FUNCTION(0x1, "i2s0")), + BERLIN_PINCTRL_GROUP("G19", 0x04, 0x1, 0x0d, + BERLIN_PINCTRL_FUNCTION(0x0, "i2s0"), + BERLIN_PINCTRL_FUNCTION(0x1, "pwm")), + BERLIN_PINCTRL_GROUP("G20", 0x04, 0x1, 0x0e, + BERLIN_PINCTRL_FUNCTION(0x0, "spdif"), + BERLIN_PINCTRL_FUNCTION(0x1, "arc")), + BERLIN_PINCTRL_GROUP("G21", 0x04, 0x3, 0x0f, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"), + BERLIN_PINCTRL_FUNCTION(0x2, "fp"), + BERLIN_PINCTRL_FUNCTION(0x3, "adac_dbg"), + BERLIN_PINCTRL_FUNCTION(0x4, "pdm_a"), /* gpio17..19,pdm */ + BERLIN_PINCTRL_FUNCTION(0x7, "pdm_b")), /* gpio12..14,pdm */ + BERLIN_PINCTRL_GROUP("G22", 0x04, 0x3, 0x12, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "dv0"), + BERLIN_PINCTRL_FUNCTION(0x2, "fp"), + BERLIN_PINCTRL_FUNCTION(0x3, "twsi0"), + BERLIN_PINCTRL_FUNCTION(0x4, "pwm")), + BERLIN_PINCTRL_GROUP("G23", 0x04, 0x3, 0x15, + BERLIN_PINCTRL_FUNCTION(0x0, "vclki"), + BERLIN_PINCTRL_FUNCTION(0x1, "dv0"), + BERLIN_PINCTRL_FUNCTION(0x2, "fp"), + BERLIN_PINCTRL_FUNCTION(0x3, "i2s0"), + BERLIN_PINCTRL_FUNCTION(0x4, "pwm"), + BERLIN_PINCTRL_FUNCTION(0x7, "pdm")), + BERLIN_PINCTRL_GROUP("G24", 0x04, 0x2, 0x18, + BERLIN_PINCTRL_FUNCTION(0x0, "i2s2"), + BERLIN_PINCTRL_FUNCTION(0x1, "i2s1")), + BERLIN_PINCTRL_GROUP("G25", 0x04, 0x2, 0x1a, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "nand"), + BERLIN_PINCTRL_FUNCTION(0x2, "i2s2")), + BERLIN_PINCTRL_GROUP("G26", 0x04, 0x1, 0x1c, + BERLIN_PINCTRL_FUNCTION(0x0, "nand"), + BERLIN_PINCTRL_FUNCTION(0x1, "emmc")), + BERLIN_PINCTRL_GROUP("G27", 0x04, 0x1, 0x1d, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "nand")), + BERLIN_PINCTRL_GROUP("G28", 0x04, 0x2, 0x1e, + BERLIN_PINCTRL_FUNCTION(0x0, "dvo"), + BERLIN_PINCTRL_FUNCTION(0x2, "sp")), +}; + +static const struct berlin_desc_group berlin2_sysmgr_pinctrl_groups[] = { + /* GSM */ + BERLIN_PINCTRL_GROUP("GSM0", 0x40, 0x2, 0x00, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "spi2"), + BERLIN_PINCTRL_FUNCTION(0x2, "eth1")), + BERLIN_PINCTRL_GROUP("GSM1", 0x40, 0x2, 0x02, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "spi2"), + BERLIN_PINCTRL_FUNCTION(0x2, "eth1")), + BERLIN_PINCTRL_GROUP("GSM2", 0x40, 0x2, 0x04, + BERLIN_PINCTRL_FUNCTION(0x0, "twsi2"), + BERLIN_PINCTRL_FUNCTION(0x1, "spi2")), + BERLIN_PINCTRL_GROUP("GSM3", 0x40, 0x2, 0x06, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "uart0"), /* CTS/RTS */ + BERLIN_PINCTRL_FUNCTION(0x2, "uart2"), /* RX/TX */ + BERLIN_PINCTRL_FUNCTION(0x3, "twsi2")), + BERLIN_PINCTRL_GROUP("GSM4", 0x40, 0x2, 0x08, + BERLIN_PINCTRL_FUNCTION(0x0, "uart0"), /* RX/TX */ + BERLIN_PINCTRL_FUNCTION(0x1, "irda0")), + BERLIN_PINCTRL_GROUP("GSM5", 0x40, 0x2, 0x0a, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "uart1"), /* RX/TX */ + BERLIN_PINCTRL_FUNCTION(0x2, "irda1"), + BERLIN_PINCTRL_FUNCTION(0x3, "twsi3")), + BERLIN_PINCTRL_GROUP("GSM6", 0x40, 0x2, 0x0c, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "spi2"), + BERLIN_PINCTRL_FUNCTION(0x1, "clki")), + BERLIN_PINCTRL_GROUP("GSM7", 0x40, 0x1, 0x0e, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")), + BERLIN_PINCTRL_GROUP("GSM8", 0x40, 0x1, 0x0f, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")), + BERLIN_PINCTRL_GROUP("GSM9", 0x40, 0x1, 0x10, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "led")), + BERLIN_PINCTRL_GROUP("GSM10", 0x40, 0x1, 0x11, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "led")), + BERLIN_PINCTRL_GROUP("GSM11", 0x40, 0x1, 0x12, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "led")), +}; + +static const struct berlin_pinctrl_desc berlin2_soc_pinctrl_data = { + .groups = berlin2_soc_pinctrl_groups, + .ngroups = ARRAY_SIZE(berlin2_soc_pinctrl_groups), +}; + +static const struct berlin_pinctrl_desc berlin2_sysmgr_pinctrl_data = { + .groups = berlin2_sysmgr_pinctrl_groups, + .ngroups = ARRAY_SIZE(berlin2_sysmgr_pinctrl_groups), +}; + +static const struct of_device_id berlin2_pinctrl_match[] = { + { + .compatible = "marvell,berlin2-chip-ctrl", + .data = &berlin2_soc_pinctrl_data + }, + { + .compatible = "marvell,berlin2-system-ctrl", + .data = &berlin2_sysmgr_pinctrl_data + }, + {} +}; +MODULE_DEVICE_TABLE(of, berlin2_pinctrl_match); + +static int berlin2_pinctrl_probe(struct platform_device *pdev) +{ + const struct of_device_id *match = + of_match_device(berlin2_pinctrl_match, &pdev->dev); + struct regmap_config *rmconfig; + struct regmap *regmap; + struct resource *res; + void __iomem *base; + + rmconfig = devm_kzalloc(&pdev->dev, sizeof(*rmconfig), GFP_KERNEL); + if (!rmconfig) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + rmconfig->reg_bits = 32, + rmconfig->val_bits = 32, + rmconfig->reg_stride = 4, + rmconfig->max_register = resource_size(res); + + regmap = devm_regmap_init_mmio(&pdev->dev, base, rmconfig); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + return berlin_pinctrl_probe(pdev, match->data); +} + +static struct platform_driver berlin2_pinctrl_driver = { + .probe = berlin2_pinctrl_probe, + .driver = { + .name = "berlin-bg2-pinctrl", + .owner = THIS_MODULE, + .of_match_table = berlin2_pinctrl_match, + }, +}; +module_platform_driver(berlin2_pinctrl_driver); + +MODULE_AUTHOR("Antoine Ténart <antoine.tenart@free-electrons.com>"); +MODULE_DESCRIPTION("Marvell Berlin BG2 pinctrl driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/pinctrl/berlin/berlin-bg2cd.c b/drivers/pinctrl/berlin/berlin-bg2cd.c new file mode 100644 index 00000000000..89d585ef7da --- /dev/null +++ b/drivers/pinctrl/berlin/berlin-bg2cd.c @@ -0,0 +1,217 @@ +/* + * Marvell Berlin BG2CD pinctrl driver. + * + * Copyright (C) 2014 Marvell Technology Group Ltd. + * + * Antoine Ténart <antoine.tenart@free-electrons.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include "berlin.h" + +static const struct berlin_desc_group berlin2cd_soc_pinctrl_groups[] = { + /* G */ + BERLIN_PINCTRL_GROUP("G0", 0x00, 0x1, 0x00, + BERLIN_PINCTRL_FUNCTION(0x0, "jtag"), + BERLIN_PINCTRL_FUNCTION(0x1, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x2, "led"), + BERLIN_PINCTRL_FUNCTION(0x3, "pwm")), + BERLIN_PINCTRL_GROUP("G1", 0x00, 0x2, 0x01, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "sd0"), + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"), + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")), + BERLIN_PINCTRL_GROUP("G2", 0x00, 0x2, 0x02, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "sd0"), + BERLIN_PINCTRL_FUNCTION(0x2, "fe"), + BERLIN_PINCTRL_FUNCTION(0x3, "pll"), + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"), + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")), + BERLIN_PINCTRL_GROUP("G3", 0x00, 0x2, 0x04, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "sd0"), + BERLIN_PINCTRL_FUNCTION(0x2, "twsi2"), + BERLIN_PINCTRL_FUNCTION(0x3, "pll"), + BERLIN_PINCTRL_FUNCTION(0x4, "fe"), + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"), + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")), + BERLIN_PINCTRL_GROUP("G4", 0x00, 0x2, 0x06, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "sd0"), + BERLIN_PINCTRL_FUNCTION(0x2, "twsi3"), + BERLIN_PINCTRL_FUNCTION(0x3, "pll"), + BERLIN_PINCTRL_FUNCTION(0x4, "pwm"), + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"), + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")), + BERLIN_PINCTRL_GROUP("G5", 0x00, 0x3, 0x08, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "sd0"), + BERLIN_PINCTRL_FUNCTION(0x2, "twsi3"), + BERLIN_PINCTRL_FUNCTION(0x3, "arc"), + BERLIN_PINCTRL_FUNCTION(0x4, "pwm"), + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"), + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")), + BERLIN_PINCTRL_GROUP("G6", 0x00, 0x2, 0x0b, + BERLIN_PINCTRL_FUNCTION(0x0, "uart0"), /* RX/TX */ + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), + BERLIN_PINCTRL_GROUP("G7", 0x00, 0x3, 0x0d, + BERLIN_PINCTRL_FUNCTION(0x0, "eddc"), + BERLIN_PINCTRL_FUNCTION(0x1, "twsi1"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")), + BERLIN_PINCTRL_GROUP("G8", 0x00, 0x3, 0x10, + BERLIN_PINCTRL_FUNCTION(0x0, "ss0"), + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), + BERLIN_PINCTRL_GROUP("G9", 0x00, 0x3, 0x13, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "spi1"), + BERLIN_PINCTRL_FUNCTION(0x2, "twsi0")), + BERLIN_PINCTRL_GROUP("G10", 0x00, 0x2, 0x16, + BERLIN_PINCTRL_FUNCTION(0x0, "spi1"), + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), + BERLIN_PINCTRL_GROUP("G11", 0x00, 0x2, 0x18, + BERLIN_PINCTRL_FUNCTION(0x0, "spi1"), + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), + BERLIN_PINCTRL_GROUP("G12", 0x00, 0x3, 0x1a, + BERLIN_PINCTRL_FUNCTION(0x0, "usb1"), + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), + BERLIN_PINCTRL_GROUP("G13", 0x04, 0x3, 0x00, + BERLIN_PINCTRL_FUNCTION(0x0, "nand"), + BERLIN_PINCTRL_FUNCTION(0x1, "usb0_dbg"), + BERLIN_PINCTRL_FUNCTION(0x2, "usb1_dbg")), + BERLIN_PINCTRL_GROUP("G14", 0x04, 0x1, 0x03, + BERLIN_PINCTRL_FUNCTION(0x0, "nand"), + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), + BERLIN_PINCTRL_GROUP("G15", 0x04, 0x2, 0x04, + BERLIN_PINCTRL_FUNCTION(0x0, "jtag"), + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), + BERLIN_PINCTRL_GROUP("G16", 0x04, 0x3, 0x06, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("G17", 0x04, 0x3, 0x09, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("G18", 0x04, 0x1, 0x0c, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("G19", 0x04, 0x1, 0x0d, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("G20", 0x04, 0x1, 0x0e, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("G21", 0x04, 0x3, 0x0f, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("G22", 0x04, 0x3, 0x12, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("G23", 0x04, 0x3, 0x15, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("G24", 0x04, 0x2, 0x18, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("G25", 0x04, 0x2, 0x1a, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("G26", 0x04, 0x1, 0x1c, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("G27", 0x04, 0x1, 0x1d, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("G28", 0x04, 0x2, 0x1e, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), +}; + +static const struct berlin_desc_group berlin2cd_sysmgr_pinctrl_groups[] = { + /* GSM */ + BERLIN_PINCTRL_GROUP("GSM0", 0x40, 0x2, 0x00, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("GSM1", 0x40, 0x2, 0x02, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("GSM2", 0x40, 0x2, 0x04, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("GSM3", 0x40, 0x2, 0x06, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("GSM4", 0x40, 0x2, 0x08, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("GSM5", 0x40, 0x2, 0x0a, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("GSM6", 0x40, 0x2, 0x0c, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("GSM7", 0x40, 0x1, 0x0e, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("GSM8", 0x40, 0x1, 0x0f, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("GSM9", 0x40, 0x1, 0x10, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("GSM10", 0x40, 0x1, 0x11, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), + BERLIN_PINCTRL_GROUP("GSM11", 0x40, 0x1, 0x12, + BERLIN_PINCTRL_FUNCTION_UNKNOWN), +}; + +static const struct berlin_pinctrl_desc berlin2cd_soc_pinctrl_data = { + .groups = berlin2cd_soc_pinctrl_groups, + .ngroups = ARRAY_SIZE(berlin2cd_soc_pinctrl_groups), +}; + +static const struct berlin_pinctrl_desc berlin2cd_sysmgr_pinctrl_data = { + .groups = berlin2cd_sysmgr_pinctrl_groups, + .ngroups = ARRAY_SIZE(berlin2cd_sysmgr_pinctrl_groups), +}; + +static const struct of_device_id berlin2cd_pinctrl_match[] = { + { + .compatible = "marvell,berlin2cd-chip-ctrl", + .data = &berlin2cd_soc_pinctrl_data + }, + { + .compatible = "marvell,berlin2cd-system-ctrl", + .data = &berlin2cd_sysmgr_pinctrl_data + }, + {} +}; +MODULE_DEVICE_TABLE(of, berlin2cd_pinctrl_match); + +static int berlin2cd_pinctrl_probe(struct platform_device *pdev) +{ + const struct of_device_id *match = + of_match_device(berlin2cd_pinctrl_match, &pdev->dev); + struct regmap_config *rmconfig; + struct regmap *regmap; + struct resource *res; + void __iomem *base; + + rmconfig = devm_kzalloc(&pdev->dev, sizeof(*rmconfig), GFP_KERNEL); + if (!rmconfig) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + rmconfig->reg_bits = 32, + rmconfig->val_bits = 32, + rmconfig->reg_stride = 4, + rmconfig->max_register = resource_size(res); + + regmap = devm_regmap_init_mmio(&pdev->dev, base, rmconfig); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + return berlin_pinctrl_probe(pdev, match->data); +} + +static struct platform_driver berlin2cd_pinctrl_driver = { + .probe = berlin2cd_pinctrl_probe, + .driver = { + .name = "berlin-bg2cd-pinctrl", + .owner = THIS_MODULE, + .of_match_table = berlin2cd_pinctrl_match, + }, +}; +module_platform_driver(berlin2cd_pinctrl_driver); + +MODULE_AUTHOR("Antoine Ténart <antoine.tenart@free-electrons.com>"); +MODULE_DESCRIPTION("Marvell Berlin BG2CD pinctrl driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/pinctrl/berlin/berlin-bg2q.c b/drivers/pinctrl/berlin/berlin-bg2q.c new file mode 100644 index 00000000000..9fcf9836045 --- /dev/null +++ b/drivers/pinctrl/berlin/berlin-bg2q.c @@ -0,0 +1,436 @@ +/* + * Marvell Berlin BG2Q pinctrl driver + * + * Copyright (C) 2014 Marvell Technology Group Ltd. + * + * Antoine Ténart <antoine.tenart@free-electrons.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include "berlin.h" + +static const struct berlin_desc_group berlin2q_soc_pinctrl_groups[] = { + /* G */ + BERLIN_PINCTRL_GROUP("G0", 0x18, 0x3, 0x00, + BERLIN_PINCTRL_FUNCTION(0x0, "nand"), + BERLIN_PINCTRL_FUNCTION(0x1, "mmc"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")), + BERLIN_PINCTRL_GROUP("G1", 0x18, 0x3, 0x03, + BERLIN_PINCTRL_FUNCTION(0x0, "nand"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")), + BERLIN_PINCTRL_GROUP("G2", 0x18, 0x3, 0x06, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x2, "arc"), + BERLIN_PINCTRL_FUNCTION(0x3, "lvds")), + BERLIN_PINCTRL_GROUP("G3", 0x18, 0x3, 0x09, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x2, "i2s2"), + BERLIN_PINCTRL_FUNCTION(0x3, "lvds")), + BERLIN_PINCTRL_GROUP("G4", 0x18, 0x3, 0x0c, + BERLIN_PINCTRL_FUNCTION(0x0, "pll"), + BERLIN_PINCTRL_FUNCTION(0x1, "sd0"), + BERLIN_PINCTRL_FUNCTION(0x2, "rgmii"), + BERLIN_PINCTRL_FUNCTION(0x3, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x5, "sata_dbg"), + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"), + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")), + BERLIN_PINCTRL_GROUP("G5", 0x18, 0x3, 0x0f, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "sd0"), + BERLIN_PINCTRL_FUNCTION(0x2, "rgmii"), + BERLIN_PINCTRL_FUNCTION(0x5, "sata_dbg"), + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"), + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")), + BERLIN_PINCTRL_GROUP("G6", 0x18, 0x3, 0x12, + BERLIN_PINCTRL_FUNCTION(0x0, "jtag"), + BERLIN_PINCTRL_FUNCTION(0x1, "twsi0"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")), + BERLIN_PINCTRL_GROUP("G7", 0x18, 0x3, 0x15, + BERLIN_PINCTRL_FUNCTION(0x0, "jtag"), + BERLIN_PINCTRL_FUNCTION(0x1, "twsi1"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x3, "eddc")), + BERLIN_PINCTRL_GROUP("G8", 0x18, 0x3, 0x18, + BERLIN_PINCTRL_FUNCTION(0x0, "spi1"), + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), + BERLIN_PINCTRL_GROUP("G9", 0x18, 0x3, 0x1b, + BERLIN_PINCTRL_FUNCTION(0x0, "spi1"), + BERLIN_PINCTRL_FUNCTION(0x1, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x5, "sata")), + BERLIN_PINCTRL_GROUP("G10", 0x1c, 0x3, 0x00, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "spi1"), + BERLIN_PINCTRL_FUNCTION(0x3, "i2s0"), + BERLIN_PINCTRL_FUNCTION(0x4, "pwm"), + BERLIN_PINCTRL_FUNCTION(0x5, "sata")), + BERLIN_PINCTRL_GROUP("G11", 0x1c, 0x3, 0x03, + BERLIN_PINCTRL_FUNCTION(0x0, "jtag"), + BERLIN_PINCTRL_FUNCTION(0x1, "spi1"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x3, "i2s1"), + BERLIN_PINCTRL_FUNCTION(0x4, "pwm"), + BERLIN_PINCTRL_FUNCTION(0x5, "sata")), + BERLIN_PINCTRL_GROUP("G12", 0x1c, 0x3, 0x06, + BERLIN_PINCTRL_FUNCTION(0x0, "agc"), + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), + BERLIN_PINCTRL_GROUP("G13", 0x1c, 0x3, 0x09, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "sts1"), + BERLIN_PINCTRL_FUNCTION(0x2, "rgmii"), + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"), + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")), + BERLIN_PINCTRL_GROUP("G14", 0x1c, 0x3, 0x0c, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "sts0"), + BERLIN_PINCTRL_FUNCTION(0x4, "sts1"), + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"), + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")), + BERLIN_PINCTRL_GROUP("G15", 0x1c, 0x3, 0x0f, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "sts0"), + BERLIN_PINCTRL_FUNCTION(0x4, "sts1"), + BERLIN_PINCTRL_FUNCTION(0x5, "vdac"), + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"), + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")), + BERLIN_PINCTRL_GROUP("G16", 0x1c, 0x3, 0x12, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "sts0"), + BERLIN_PINCTRL_FUNCTION(0x4, "sts1"), + BERLIN_PINCTRL_FUNCTION(0x5, "osco"), + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"), + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")), + BERLIN_PINCTRL_GROUP("G17", 0x1c, 0x3, 0x15, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x2, "rgmii"), + BERLIN_PINCTRL_FUNCTION(0x3, "spdif"), + BERLIN_PINCTRL_FUNCTION(0x4, "sts1"), + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"), + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")), + BERLIN_PINCTRL_GROUP("G18", 0x1c, 0x3, 0x18, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x2, "rgmii"), + BERLIN_PINCTRL_FUNCTION(0x3, "i2s2"), + BERLIN_PINCTRL_FUNCTION(0x4, "sts1")), + BERLIN_PINCTRL_GROUP("G19", 0x1c, 0x3, 0x1b, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x2, "rgmii"), + BERLIN_PINCTRL_FUNCTION(0x3, "i2s3"), + BERLIN_PINCTRL_FUNCTION(0x4, "sts1"), + BERLIN_PINCTRL_FUNCTION(0x5, "osco")), + BERLIN_PINCTRL_GROUP("G20", 0x20, 0x3, 0x00, + BERLIN_PINCTRL_FUNCTION(0x0, "cam"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x3, "demod"), + /* + * Mode 0x4 mux usb2_dbg *and* usb3_dbg: + * add two functions so it can be used with other groups + * within the same subnode in the device tree + */ + BERLIN_PINCTRL_FUNCTION(0x4, "usb2_dbg"), + BERLIN_PINCTRL_FUNCTION(0x4, "usb3_dbg")), + BERLIN_PINCTRL_GROUP("G21", 0x20, 0x3, 0x03, + BERLIN_PINCTRL_FUNCTION(0x0, "cam"), + BERLIN_PINCTRL_FUNCTION(0x1, "sts2"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x3, "demod")), + BERLIN_PINCTRL_GROUP("G22", 0x20, 0x3, 0x06, + BERLIN_PINCTRL_FUNCTION(0x0, "cam"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")), + BERLIN_PINCTRL_GROUP("G23", 0x20, 0x3, 0x09, + BERLIN_PINCTRL_FUNCTION(0x0, "cam"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x3, "avif"), + BERLIN_PINCTRL_FUNCTION(0x4, "usb2_dbg")), + BERLIN_PINCTRL_GROUP("G24", 0x20, 0x3, 0x0c, + BERLIN_PINCTRL_FUNCTION(0x0, "cam"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x3, "demod"), + BERLIN_PINCTRL_FUNCTION(0x4, "usb2_dbg")), + BERLIN_PINCTRL_GROUP("G25", 0x20, 0x3, 0x0f, + BERLIN_PINCTRL_FUNCTION(0x0, "cam"), + BERLIN_PINCTRL_FUNCTION(0x1, "vga"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x3, "avif"), + BERLIN_PINCTRL_FUNCTION(0x4, "usb2_dbg")), + BERLIN_PINCTRL_GROUP("G26", 0x20, 0x3, 0x12, + BERLIN_PINCTRL_FUNCTION(0x0, "cam"), + BERLIN_PINCTRL_FUNCTION(0x1, "lvds"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")), + BERLIN_PINCTRL_GROUP("G27", 0x20, 0x3, 0x15, + BERLIN_PINCTRL_FUNCTION(0x0, "cam"), + BERLIN_PINCTRL_FUNCTION(0x1, "agc"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")), + BERLIN_PINCTRL_GROUP("G28", 0x20, 0x3, 0x18, + BERLIN_PINCTRL_FUNCTION(0x0, "cam"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x3, "avif"), + BERLIN_PINCTRL_FUNCTION(0x4, "usb2_dbg")), + BERLIN_PINCTRL_GROUP("G29", 0x20, 0x3, 0x1b, + BERLIN_PINCTRL_FUNCTION(0x0, "cam"), + BERLIN_PINCTRL_FUNCTION(0x1, "scrd0"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")), + BERLIN_PINCTRL_GROUP("G30", 0x24, 0x3, 0x00, + BERLIN_PINCTRL_FUNCTION(0x0, "cam"), + BERLIN_PINCTRL_FUNCTION(0x1, "scrd1"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")), + BERLIN_PINCTRL_GROUP("G31", 0x24, 0x3, 0x03, + BERLIN_PINCTRL_FUNCTION(0x0, "cam"), + BERLIN_PINCTRL_FUNCTION(0x1, "sd1"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")), + BERLIN_PINCTRL_GROUP("G32", 0x24, 0x3, 0x06, + BERLIN_PINCTRL_FUNCTION(0x0, "cam"), + BERLIN_PINCTRL_FUNCTION(0x1, "sd1"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")), + /* GAV */ + BERLIN_PINCTRL_GROUP("GAV0", 0x24, 0x3, 0x09, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"), + BERLIN_PINCTRL_FUNCTION(0x2, "fp"), + BERLIN_PINCTRL_FUNCTION(0x4, "lvds")), + BERLIN_PINCTRL_GROUP("GAV1", 0x24, 0x3, 0x0c, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"), + BERLIN_PINCTRL_FUNCTION(0x2, "fp"), + BERLIN_PINCTRL_FUNCTION(0x4, "vga")), + BERLIN_PINCTRL_GROUP("GAV2", 0x24, 0x3, 0x0f, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"), + BERLIN_PINCTRL_FUNCTION(0x2, "fp"), + BERLIN_PINCTRL_FUNCTION(0x3, "i2s3"), + BERLIN_PINCTRL_FUNCTION(0x4, "pdm"), + BERLIN_PINCTRL_FUNCTION(0x6, "adac")), + BERLIN_PINCTRL_GROUP("GAV3", 0x24, 0x3, 0x12, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"), + BERLIN_PINCTRL_FUNCTION(0x2, "fp"), + BERLIN_PINCTRL_FUNCTION(0x3, "i2s3"), + BERLIN_PINCTRL_FUNCTION(0x6, "adac")), + BERLIN_PINCTRL_GROUP("GAV4", 0x24, 0x3, 0x15, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"), + BERLIN_PINCTRL_FUNCTION(0x2, "fp"), + BERLIN_PINCTRL_FUNCTION(0x4, "i2s1"), + BERLIN_PINCTRL_FUNCTION(0x6, "adac")), + BERLIN_PINCTRL_GROUP("GAV5", 0x24, 0x3, 0x18, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"), + BERLIN_PINCTRL_FUNCTION(0x2, "fp"), + BERLIN_PINCTRL_FUNCTION(0x4, "spdif")), + BERLIN_PINCTRL_GROUP("GAV6", 0x24, 0x3, 0x1b, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"), + BERLIN_PINCTRL_FUNCTION(0x2, "fp"), + BERLIN_PINCTRL_FUNCTION(0x4, "i2s2")), + BERLIN_PINCTRL_GROUP("GAV7", 0x28, 0x3, 0x00, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"), + BERLIN_PINCTRL_FUNCTION(0x2, "fp"), + BERLIN_PINCTRL_FUNCTION(0x4, "i2s3")), + BERLIN_PINCTRL_GROUP("GAV8", 0x28, 0x3, 0x03, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "dv0"), + BERLIN_PINCTRL_FUNCTION(0x2, "fp"), + BERLIN_PINCTRL_FUNCTION(0x4, "pwm")), + BERLIN_PINCTRL_GROUP("GAV9", 0x28, 0x3, 0x06, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "dv0"), + BERLIN_PINCTRL_FUNCTION(0x2, "fp"), + BERLIN_PINCTRL_FUNCTION(0x4, "pwm")), + BERLIN_PINCTRL_GROUP("GAV10", 0x28, 0x3, 0x09, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "dv0"), + BERLIN_PINCTRL_FUNCTION(0x2, "fp"), + BERLIN_PINCTRL_FUNCTION(0x4, "agc")), + BERLIN_PINCTRL_GROUP("GAV11", 0x28, 0x3, 0x0c, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "dv0"), + BERLIN_PINCTRL_FUNCTION(0x2, "fp"), + BERLIN_PINCTRL_FUNCTION(0x3, "i2s0"), + BERLIN_PINCTRL_FUNCTION(0x4, "pwm"), + BERLIN_PINCTRL_FUNCTION(0x5, "vclki")), + BERLIN_PINCTRL_GROUP("GAV12", 0x28, 0x3, 0x0f, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "i2s2"), + BERLIN_PINCTRL_FUNCTION(0x2, "i2s1")), + BERLIN_PINCTRL_GROUP("GAV13", 0x28, 0x3, 0x12, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "i2s2")), + BERLIN_PINCTRL_GROUP("GAV14", 0x28, 0x3, 0x15, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "i2s2"), + BERLIN_PINCTRL_FUNCTION(0x2, "i2s1")), + BERLIN_PINCTRL_GROUP("GAV15", 0x28, 0x3, 0x18, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "i2s1"), + BERLIN_PINCTRL_FUNCTION(0x6, "dac_dbg")), + BERLIN_PINCTRL_GROUP("GAV16", 0x28, 0x3, 0x1b, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "i2s0"), + BERLIN_PINCTRL_FUNCTION(0x2, "i2s1"), + BERLIN_PINCTRL_FUNCTION(0x4, "i2s3"), + BERLIN_PINCTRL_FUNCTION(0x5, "pdm"), + BERLIN_PINCTRL_FUNCTION(0x6, "dac_dbg")), + BERLIN_PINCTRL_GROUP("GAV17", 0x2c, 0x3, 0x00, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "i2s0"), + BERLIN_PINCTRL_FUNCTION(0x2, "i2s1"), + BERLIN_PINCTRL_FUNCTION(0x3, "pwm"), + BERLIN_PINCTRL_FUNCTION(0x4, "i2s3"), + BERLIN_PINCTRL_FUNCTION(0x5, "pdm"), + BERLIN_PINCTRL_FUNCTION(0x6, "dac_dbg")), + BERLIN_PINCTRL_GROUP("GAV18", 0x2c, 0x3, 0x03, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "spdif"), + BERLIN_PINCTRL_FUNCTION(0x2, "arc")), + BERLIN_PINCTRL_GROUP("GAV19", 0x2c, 0x3, 0x06, + BERLIN_PINCTRL_FUNCTION(0x0, "avio"), + BERLIN_PINCTRL_FUNCTION(0x1, "spdif"), + BERLIN_PINCTRL_FUNCTION(0x4, "i2s3"), + BERLIN_PINCTRL_FUNCTION(0x5, "pdm")), +}; + +static const struct berlin_desc_group berlin2q_sysmgr_pinctrl_groups[] = { + /* GSM */ + BERLIN_PINCTRL_GROUP("GSM0", 0x40, 0x2, 0x00, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "spi2"), + BERLIN_PINCTRL_FUNCTION(0x2, "eth1")), + BERLIN_PINCTRL_GROUP("GSM1", 0x40, 0x2, 0x02, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "spi2"), + BERLIN_PINCTRL_FUNCTION(0x2, "eth1")), + BERLIN_PINCTRL_GROUP("GSM2", 0x40, 0x2, 0x04, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "spi2"), + BERLIN_PINCTRL_FUNCTION(0x2, "eddc")), + BERLIN_PINCTRL_GROUP("GSM3", 0x40, 0x2, 0x06, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "spi2"), + BERLIN_PINCTRL_FUNCTION(0x2, "eddc")), + BERLIN_PINCTRL_GROUP("GSM4", 0x40, 0x1, 0x08, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")), + BERLIN_PINCTRL_GROUP("GSM5", 0x40, 0x1, 0x09, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")), + BERLIN_PINCTRL_GROUP("GSM6", 0x40, 0x1, 0x0a, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")), + BERLIN_PINCTRL_GROUP("GSM7", 0x40, 0x1, 0x0b, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")), + BERLIN_PINCTRL_GROUP("GSM8", 0x40, 0x1, 0x0c, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")), + BERLIN_PINCTRL_GROUP("GSM9", 0x40, 0x1, 0x0d, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")), + BERLIN_PINCTRL_GROUP("GSM10", 0x40, 0x1, 0x0e, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "led")), + BERLIN_PINCTRL_GROUP("GSM11", 0x40, 0x1, 0x0f, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "led")), + BERLIN_PINCTRL_GROUP("GSM12", 0x40, 0x2, 0x10, + BERLIN_PINCTRL_FUNCTION(0x0, "uart0"), /* RX/TX */ + BERLIN_PINCTRL_FUNCTION(0x1, "irda0"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")), + BERLIN_PINCTRL_GROUP("GSM13", 0x40, 0x2, 0x12, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "uart0"), /* CTS/RTS */ + BERLIN_PINCTRL_FUNCTION(0x2, "uart1"), /* RX/TX */ + BERLIN_PINCTRL_FUNCTION(0x3, "twsi2")), + BERLIN_PINCTRL_GROUP("GSM14", 0x40, 0x2, 0x14, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "uart1"), /* RX/TX */ + BERLIN_PINCTRL_FUNCTION(0x2, "irda1"), + BERLIN_PINCTRL_FUNCTION(0x3, "twsi3")), + BERLIN_PINCTRL_GROUP("GSM15", 0x40, 0x2, 0x16, + BERLIN_PINCTRL_FUNCTION(0x0, "pwr"), + BERLIN_PINCTRL_FUNCTION(0x1, "led"), + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")), + BERLIN_PINCTRL_GROUP("GSM16", 0x40, 0x1, 0x18, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "eddc")), + BERLIN_PINCTRL_GROUP("GSM17", 0x40, 0x1, 0x19, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "eddc")), + BERLIN_PINCTRL_GROUP("GSM18", 0x40, 0x1, 0x1a, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), + BERLIN_PINCTRL_FUNCTION(0x1, "eddc")), +}; + +static const struct berlin_pinctrl_desc berlin2q_soc_pinctrl_data = { + .groups = berlin2q_soc_pinctrl_groups, + .ngroups = ARRAY_SIZE(berlin2q_soc_pinctrl_groups), +}; + +static const struct berlin_pinctrl_desc berlin2q_sysmgr_pinctrl_data = { + .groups = berlin2q_sysmgr_pinctrl_groups, + .ngroups = ARRAY_SIZE(berlin2q_sysmgr_pinctrl_groups), +}; + +static const struct of_device_id berlin2q_pinctrl_match[] = { + { + .compatible = "marvell,berlin2q-chip-ctrl", + .data = &berlin2q_soc_pinctrl_data, + }, + { + .compatible = "marvell,berlin2q-system-ctrl", + .data = &berlin2q_sysmgr_pinctrl_data, + }, + {} +}; +MODULE_DEVICE_TABLE(of, berlin2q_pinctrl_match); + +static int berlin2q_pinctrl_probe(struct platform_device *pdev) +{ + const struct of_device_id *match = + of_match_device(berlin2q_pinctrl_match, &pdev->dev); + struct regmap_config *rmconfig; + struct regmap *regmap; + struct resource *res; + void __iomem *base; + + rmconfig = devm_kzalloc(&pdev->dev, sizeof(*rmconfig), GFP_KERNEL); + if (!rmconfig) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + rmconfig->reg_bits = 32, + rmconfig->val_bits = 32, + rmconfig->reg_stride = 4, + rmconfig->max_register = resource_size(res); + + regmap = devm_regmap_init_mmio(&pdev->dev, base, rmconfig); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + return berlin_pinctrl_probe(pdev, match->data); +} + +static struct platform_driver berlin2q_pinctrl_driver = { + .probe = berlin2q_pinctrl_probe, + .driver = { + .name = "berlin-bg2q-pinctrl", + .owner = THIS_MODULE, + .of_match_table = berlin2q_pinctrl_match, + }, +}; +module_platform_driver(berlin2q_pinctrl_driver); + +MODULE_AUTHOR("Antoine Ténart <antoine.tenart@free-electrons.com>"); +MODULE_DESCRIPTION("Marvell Berlin BG2Q pinctrl driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/pinctrl/berlin/berlin.c b/drivers/pinctrl/berlin/berlin.c new file mode 100644 index 00000000000..edf5d2fd2b2 --- /dev/null +++ b/drivers/pinctrl/berlin/berlin.c @@ -0,0 +1,348 @@ +/* + * Marvell Berlin SoC pinctrl core driver + * + * Copyright (C) 2014 Marvell Technology Group Ltd. + * + * Antoine Ténart <antoine.tenart@free-electrons.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinmux.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/slab.h> + +#include "../core.h" +#include "../pinctrl-utils.h" +#include "berlin.h" + +struct berlin_pinctrl { + struct regmap *regmap; + struct device *dev; + const struct berlin_pinctrl_desc *desc; + struct berlin_pinctrl_function *functions; + unsigned nfunctions; + struct pinctrl_dev *pctrl_dev; +}; + +static int berlin_pinctrl_get_group_count(struct pinctrl_dev *pctrl_dev) +{ + struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); + + return pctrl->desc->ngroups; +} + +static const char *berlin_pinctrl_get_group_name(struct pinctrl_dev *pctrl_dev, + unsigned group) +{ + struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); + + return pctrl->desc->groups[group].name; +} + +static int berlin_pinctrl_dt_node_to_map(struct pinctrl_dev *pctrl_dev, + struct device_node *node, + struct pinctrl_map **map, + unsigned *num_maps) +{ + struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); + struct property *prop; + const char *function_name, *group_name; + unsigned reserved_maps = 0; + int ret, ngroups; + + *map = NULL; + *num_maps = 0; + + ret = of_property_read_string(node, "function", &function_name); + if (ret) { + dev_err(pctrl->dev, + "missing function property in node %s\n", + node->name); + return -EINVAL; + } + + ngroups = of_property_count_strings(node, "groups"); + if (ngroups < 0) { + dev_err(pctrl->dev, + "missing groups property in node %s\n", + node->name); + return -EINVAL; + } + + ret = pinctrl_utils_reserve_map(pctrl_dev, map, &reserved_maps, + num_maps, ngroups); + if (ret) { + dev_err(pctrl->dev, "can't reserve map: %d\n", ret); + return ret; + } + + of_property_for_each_string(node, "groups", prop, group_name) { + ret = pinctrl_utils_add_map_mux(pctrl_dev, map, &reserved_maps, + num_maps, group_name, + function_name); + if (ret) { + dev_err(pctrl->dev, "can't add map: %d\n", ret); + return ret; + } + } + + return 0; +} + +static void berlin_pinctrl_dt_free_map(struct pinctrl_dev *pctrl_dev, + struct pinctrl_map *map, + unsigned nmaps) +{ + int i; + + for (i = 0; i < nmaps; i++) { + if (map[i].type == PIN_MAP_TYPE_MUX_GROUP) { + kfree(map[i].data.mux.group); + + /* a function can be applied to multiple groups */ + if (i == 0) + kfree(map[i].data.mux.function); + } + } + + kfree(map); +} + +static const struct pinctrl_ops berlin_pinctrl_ops = { + .get_groups_count = &berlin_pinctrl_get_group_count, + .get_group_name = &berlin_pinctrl_get_group_name, + .dt_node_to_map = &berlin_pinctrl_dt_node_to_map, + .dt_free_map = &berlin_pinctrl_dt_free_map, +}; + +static int berlin_pinmux_get_functions_count(struct pinctrl_dev *pctrl_dev) +{ + struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); + + return pctrl->nfunctions; +} + +static const char *berlin_pinmux_get_function_name(struct pinctrl_dev *pctrl_dev, + unsigned function) +{ + struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); + + return pctrl->functions[function].name; +} + +static int berlin_pinmux_get_function_groups(struct pinctrl_dev *pctrl_dev, + unsigned function, + const char * const **groups, + unsigned * const num_groups) +{ + struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); + + *groups = pctrl->functions[function].groups; + *num_groups = pctrl->functions[function].ngroups; + + return 0; +} + +static struct berlin_desc_function * +berlin_pinctrl_find_function_by_name(struct berlin_pinctrl *pctrl, + const struct berlin_desc_group *group, + const char *fname) +{ + struct berlin_desc_function *function = group->functions; + + while (function->name) { + if (!strcmp(function->name, fname)) + return function; + + function++; + } + + return NULL; +} + +static int berlin_pinmux_enable(struct pinctrl_dev *pctrl_dev, + unsigned function, + unsigned group) +{ + struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); + const struct berlin_desc_group *group_desc = pctrl->desc->groups + group; + struct berlin_pinctrl_function *func = pctrl->functions + function; + struct berlin_desc_function *function_desc = + berlin_pinctrl_find_function_by_name(pctrl, group_desc, + func->name); + u32 mask, val; + + if (!function_desc) + return -EINVAL; + + mask = GENMASK(group_desc->lsb + group_desc->bit_width - 1, + group_desc->lsb); + val = function_desc->muxval << group_desc->lsb; + regmap_update_bits(pctrl->regmap, group_desc->offset, mask, val); + + return 0; +} + +static const struct pinmux_ops berlin_pinmux_ops = { + .get_functions_count = &berlin_pinmux_get_functions_count, + .get_function_name = &berlin_pinmux_get_function_name, + .get_function_groups = &berlin_pinmux_get_function_groups, + .enable = &berlin_pinmux_enable, +}; + +static int berlin_pinctrl_add_function(struct berlin_pinctrl *pctrl, + const char *name) +{ + struct berlin_pinctrl_function *function = pctrl->functions; + + while (function->name) { + if (!strcmp(function->name, name)) { + function->ngroups++; + return -EEXIST; + } + function++; + } + + function->name = name; + function->ngroups = 1; + + pctrl->nfunctions++; + + return 0; +} + +static int berlin_pinctrl_build_state(struct platform_device *pdev) +{ + struct berlin_pinctrl *pctrl = platform_get_drvdata(pdev); + struct berlin_desc_group const *desc_group; + struct berlin_desc_function const *desc_function; + int i, max_functions = 0; + + pctrl->nfunctions = 0; + + for (i = 0; i < pctrl->desc->ngroups; i++) { + desc_group = pctrl->desc->groups + i; + /* compute the maxiumum number of functions a group can have */ + max_functions += 1 << (desc_group->bit_width + 1); + } + + /* we will reallocate later */ + pctrl->functions = devm_kzalloc(&pdev->dev, + max_functions * sizeof(*pctrl->functions), + GFP_KERNEL); + if (!pctrl->functions) + return -ENOMEM; + + /* register all functions */ + for (i = 0; i < pctrl->desc->ngroups; i++) { + desc_group = pctrl->desc->groups + i; + desc_function = desc_group->functions; + + while (desc_function->name) { + berlin_pinctrl_add_function(pctrl, desc_function->name); + desc_function++; + } + } + + pctrl->functions = krealloc(pctrl->functions, + pctrl->nfunctions * sizeof(*pctrl->functions), + GFP_KERNEL); + + /* map functions to theirs groups */ + for (i = 0; i < pctrl->desc->ngroups; i++) { + desc_group = pctrl->desc->groups + i; + desc_function = desc_group->functions; + + while (desc_function->name) { + struct berlin_pinctrl_function + *function = pctrl->functions; + const char **groups; + bool found = false; + + while (function->name) { + if (!strcmp(desc_function->name, function->name)) { + found = true; + break; + } + function++; + } + + if (!found) + return -EINVAL; + + if (!function->groups) { + function->groups = + devm_kzalloc(&pdev->dev, + function->ngroups * sizeof(char *), + GFP_KERNEL); + + if (!function->groups) + return -ENOMEM; + } + + groups = function->groups; + while (*groups) + groups++; + + *groups = desc_group->name; + + desc_function++; + } + } + + return 0; +} + +static struct pinctrl_desc berlin_pctrl_desc = { + .name = "berlin-pinctrl", + .pctlops = &berlin_pinctrl_ops, + .pmxops = &berlin_pinmux_ops, + .owner = THIS_MODULE, +}; + +int berlin_pinctrl_probe(struct platform_device *pdev, + const struct berlin_pinctrl_desc *desc) +{ + struct device *dev = &pdev->dev; + struct berlin_pinctrl *pctrl; + struct regmap *regmap; + int ret; + + regmap = dev_get_regmap(&pdev->dev, NULL); + if (!regmap) + return PTR_ERR(regmap); + + pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL); + if (!pctrl) + return -ENOMEM; + + platform_set_drvdata(pdev, pctrl); + + pctrl->regmap = regmap; + pctrl->dev = &pdev->dev; + pctrl->desc = desc; + + ret = berlin_pinctrl_build_state(pdev); + if (ret) { + dev_err(dev, "cannot build driver state: %d\n", ret); + return ret; + } + + pctrl->pctrl_dev = pinctrl_register(&berlin_pctrl_desc, dev, pctrl); + if (!pctrl->pctrl_dev) { + dev_err(dev, "failed to register pinctrl driver\n"); + return -EINVAL; + } + + return 0; +} diff --git a/drivers/pinctrl/berlin/berlin.h b/drivers/pinctrl/berlin/berlin.h new file mode 100644 index 00000000000..e1aa8414519 --- /dev/null +++ b/drivers/pinctrl/berlin/berlin.h @@ -0,0 +1,61 @@ +/* + * Marvell Berlin SoC pinctrl driver. + * + * Copyright (C) 2014 Marvell Technology Group Ltd. + * + * Antoine Ténart <antoine.tenart@free-electrons.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __PINCTRL_BERLIN_H +#define __PINCTRL_BERLIN_H + +struct berlin_desc_function { + const char *name; + u8 muxval; +}; + +struct berlin_desc_group { + const char *name; + u8 offset; + u8 bit_width; + u8 lsb; + struct berlin_desc_function *functions; +}; + +struct berlin_pinctrl_desc { + const struct berlin_desc_group *groups; + unsigned ngroups; +}; + +struct berlin_pinctrl_function { + const char *name; + const char **groups; + unsigned ngroups; +}; + +#define BERLIN_PINCTRL_GROUP(_name, _offset, _width, _lsb, ...) \ + { \ + .name = _name, \ + .offset = _offset, \ + .bit_width = _width, \ + .lsb = _lsb, \ + .functions = (struct berlin_desc_function[]){ \ + __VA_ARGS__, { } }, \ + } + +#define BERLIN_PINCTRL_FUNCTION(_muxval, _name) \ + { \ + .name = _name, \ + .muxval = _muxval, \ + } + +#define BERLIN_PINCTRL_FUNCTION_UNKNOWN {} + +int berlin_pinctrl_probe(struct platform_device *pdev, + const struct berlin_pinctrl_desc *desc); + +#endif /* __PINCTRL_BERLIN_H */ |