2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-26 06:04:14 +08:00

pinctrl: visconti: Add Toshiba Visconti SoCs pinctrl support

Add pinctrl support to Toshiba Visconti SoCs.

Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
Reviewed-by: Punit Agrawal <punit1.agrawal@toshiba.co.jp>
Link: https://lore.kernel.org/r/20200909204336.2558-3-nobuhiro1.iwamatsu@toshiba.co.jp
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
Nobuhiro Iwamatsu 2020-09-10 05:43:30 +09:00 committed by Linus Walleij
parent 1825c1fe00
commit a68a784426
7 changed files with 775 additions and 0 deletions

View File

@ -429,6 +429,7 @@ source "drivers/pinctrl/mediatek/Kconfig"
source "drivers/pinctrl/zte/Kconfig"
source "drivers/pinctrl/meson/Kconfig"
source "drivers/pinctrl/cirrus/Kconfig"
source "drivers/pinctrl/visconti/Kconfig"
config PINCTRL_XWAY
bool

View File

@ -74,3 +74,4 @@ obj-$(CONFIG_ARCH_VT8500) += vt8500/
obj-y += mediatek/
obj-$(CONFIG_PINCTRL_ZX) += zte/
obj-y += cirrus/
obj-$(CONFIG_PINCTRL_VISCONTI) += visconti/

View File

@ -0,0 +1,14 @@
# SPDX-License-Identifier: GPL-2.0-only
config PINCTRL_VISCONTI
bool
select PINMUX
select GENERIC_PINCONF
select GENERIC_PINCTRL_GROUPS
select GENERIC_PINMUX_FUNCTIONS
config PINCTRL_TMPV7700
bool "Toshiba Visconti TMPV7700 series pinctrl driver"
depends on OF
depends on ARM64 || COMPILE_TEST
select PINCTRL_VISCONTI
default ARM64 && ARCH_VISCONTI

View File

@ -0,0 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_PINCTRL_VISCONTI) += pinctrl-common.o
obj-$(CONFIG_PINCTRL_TMPV7700) += pinctrl-tmpv7700.o

View File

@ -0,0 +1,305 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2020 TOSHIBA CORPORATION
* Copyright (c) 2020 Toshiba Electronic Devices & Storage Corporation
* Copyright (c) 2020 Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
*/
#include <linux/init.h>
#include <linux/of.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include "pinctrl-common.h"
#include "../core.h"
#include "../pinconf.h"
#include "../pinctrl-utils.h"
#define DSEL_MASK GENMASK(3, 0)
/* private data */
struct visconti_pinctrl {
void __iomem *base;
struct device *dev;
struct pinctrl_dev *pctl;
struct pinctrl_desc pctl_desc;
const struct visconti_pinctrl_devdata *devdata;
spinlock_t lock; /* protect pinctrl register */
};
/* pinconf */
static int visconti_pin_config_set(struct pinctrl_dev *pctldev,
unsigned int _pin,
unsigned long *configs,
unsigned int num_configs)
{
struct visconti_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev);
const struct visconti_desc_pin *pin = &priv->devdata->pins[_pin];
enum pin_config_param param;
unsigned int arg;
int i, ret = 0;
unsigned int val, set_val, pude_val;
unsigned long flags;
dev_dbg(priv->dev, "%s: pin = %d (%s)\n", __func__, _pin, pin->pin.name);
spin_lock_irqsave(&priv->lock, flags);
for (i = 0; i < num_configs; i++) {
set_val = 0;
pude_val = 0;
param = pinconf_to_config_param(configs[i]);
switch (param) {
case PIN_CONFIG_BIAS_PULL_UP:
set_val = 1;
fallthrough;
case PIN_CONFIG_BIAS_PULL_DOWN:
/* update pudsel setting */
val = readl(priv->base + pin->pudsel_offset);
val &= ~BIT(pin->pud_shift);
val |= set_val << pin->pud_shift;
writel(val, priv->base + pin->pudsel_offset);
pude_val = 1;
fallthrough;
case PIN_CONFIG_BIAS_DISABLE:
/* update pude setting */
val = readl(priv->base + pin->pude_offset);
val &= ~BIT(pin->pud_shift);
val |= pude_val << pin->pud_shift;
writel(val, priv->base + pin->pude_offset);
dev_dbg(priv->dev, "BIAS(%d): off = 0x%x val = 0x%x\n",
param, pin->pude_offset, val);
break;
case PIN_CONFIG_DRIVE_STRENGTH:
arg = pinconf_to_config_argument(configs[i]);
dev_dbg(priv->dev, "DRV_STR arg = %d\n", arg);
switch (arg) {
case 2:
case 4:
case 8:
case 16:
case 24:
case 32:
/*
* I/O drive capacity setting:
* 2mA: 0
* 4mA: 1
* 8mA: 3
* 16mA: 7
* 24mA: 11
* 32mA: 15
*/
set_val = DIV_ROUND_CLOSEST(arg, 2) - 1;
break;
default:
ret = -EINVAL;
goto err;
}
/* update drive setting */
val = readl(priv->base + pin->dsel_offset);
val &= ~(DSEL_MASK << pin->dsel_shift);
val |= set_val << pin->dsel_shift;
writel(val, priv->base + pin->dsel_offset);
break;
default:
ret = -EOPNOTSUPP;
goto err;
}
}
err:
spin_unlock_irqrestore(&priv->lock, flags);
return ret;
}
static int visconti_pin_config_group_set(struct pinctrl_dev *pctldev,
unsigned int selector,
unsigned long *configs,
unsigned int num_configs)
{
struct visconti_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev);
const unsigned int *pins;
unsigned int num_pins;
int i, ret;
pins = priv->devdata->groups[selector].pins;
num_pins = priv->devdata->groups[selector].nr_pins;
dev_dbg(priv->dev, "%s: select = %d, n_pin = %d, n_config = %d\n",
__func__, selector, num_pins, num_configs);
for (i = 0; i < num_pins; i++) {
ret = visconti_pin_config_set(pctldev, pins[i],
configs, num_configs);
if (ret)
return ret;
}
return 0;
}
static const struct pinconf_ops visconti_pinconf_ops = {
.is_generic = true,
.pin_config_set = visconti_pin_config_set,
.pin_config_group_set = visconti_pin_config_group_set,
.pin_config_config_dbg_show = pinconf_generic_dump_config,
};
/* pinctrl */
static int visconti_get_groups_count(struct pinctrl_dev *pctldev)
{
struct visconti_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev);
return priv->devdata->nr_groups;
}
static const char *visconti_get_group_name(struct pinctrl_dev *pctldev,
unsigned int selector)
{
struct visconti_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev);
return priv->devdata->groups[selector].name;
}
static int visconti_get_group_pins(struct pinctrl_dev *pctldev,
unsigned int selector,
const unsigned int **pins,
unsigned int *num_pins)
{
struct visconti_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev);
*pins = priv->devdata->groups[selector].pins;
*num_pins = priv->devdata->groups[selector].nr_pins;
return 0;
}
static const struct pinctrl_ops visconti_pinctrl_ops = {
.get_groups_count = visconti_get_groups_count,
.get_group_name = visconti_get_group_name,
.get_group_pins = visconti_get_group_pins,
.dt_node_to_map = pinconf_generic_dt_node_to_map_group,
.dt_free_map = pinctrl_utils_free_map,
};
/* pinmux */
static int visconti_get_functions_count(struct pinctrl_dev *pctldev)
{
struct visconti_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev);
return priv->devdata->nr_functions;
}
static const char *visconti_get_function_name(struct pinctrl_dev *pctldev,
unsigned int selector)
{
struct visconti_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev);
return priv->devdata->functions[selector].name;
}
static int visconti_get_function_groups(struct pinctrl_dev *pctldev,
unsigned int selector,
const char * const **groups,
unsigned * const num_groups)
{
struct visconti_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev);
*groups = priv->devdata->functions[selector].groups;
*num_groups = priv->devdata->functions[selector].nr_groups;
return 0;
}
static int visconti_set_mux(struct pinctrl_dev *pctldev,
unsigned int function, unsigned int group)
{
struct visconti_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev);
const struct visconti_pin_function *func = &priv->devdata->functions[function];
const struct visconti_pin_group *grp = &priv->devdata->groups[group];
const struct visconti_mux *mux = &grp->mux;
unsigned int val;
unsigned long flags;
dev_dbg(priv->dev, "%s: function = %d(%s) group = %d(%s)\n", __func__,
function, func->name, group, grp->name);
spin_lock_irqsave(&priv->lock, flags);
/* update mux */
val = readl(priv->base + mux->offset);
val &= ~mux->mask;
val |= mux->val;
writel(val, priv->base + mux->offset);
spin_unlock_irqrestore(&priv->lock, flags);
dev_dbg(priv->dev, "[%x]: 0x%x\n", mux->offset, val);
return 0;
}
static const struct pinmux_ops visconti_pinmux_ops = {
.get_functions_count = visconti_get_functions_count,
.get_function_name = visconti_get_function_name,
.get_function_groups = visconti_get_function_groups,
.set_mux = visconti_set_mux,
.strict = true,
};
int visconti_pinctrl_probe(struct platform_device *pdev,
const struct visconti_pinctrl_devdata *devdata)
{
struct device *dev = &pdev->dev;
struct visconti_pinctrl *priv;
struct pinctrl_pin_desc *pins;
int i, ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->dev = dev;
priv->devdata = devdata;
spin_lock_init(&priv->lock);
priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base)) {
dev_err(dev, "unable to map I/O space\n");
return PTR_ERR(priv->base);
}
pins = devm_kcalloc(dev, devdata->nr_pins,
sizeof(*pins), GFP_KERNEL);
if (!pins)
return -ENOMEM;
for (i = 0; i < devdata->nr_pins; i++)
pins[i] = devdata->pins[i].pin;
priv->pctl_desc.name = dev_name(dev);
priv->pctl_desc.owner = THIS_MODULE;
priv->pctl_desc.pins = pins;
priv->pctl_desc.npins = devdata->nr_pins;
priv->pctl_desc.confops = &visconti_pinconf_ops;
priv->pctl_desc.pctlops = &visconti_pinctrl_ops;
priv->pctl_desc.pmxops = &visconti_pinmux_ops;
ret = devm_pinctrl_register_and_init(dev, &priv->pctl_desc,
priv, &priv->pctl);
if (ret) {
dev_err(dev, "couldn't register pinctrl: %d\n", ret);
return ret;
}
if (devdata->unlock)
devdata->unlock(priv->base);
return pinctrl_enable(priv->pctl);
}

View File

@ -0,0 +1,96 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2020 TOSHIBA CORPORATION
* Copyright (c) 2020 Toshiba Electronic Devices & Storage Corporation
* Copyright (c) 2020 Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
*/
#ifndef __VISCONTI_PINCTRL_COMMON_H__
#define __VISCONTI_PINCTRL_COMMON_H__
struct pinctrl_pin_desc;
/* PIN */
#define VISCONTI_PINS(pins_name, ...) \
static const unsigned int pins_name ## _pins[] = { __VA_ARGS__ }
struct visconti_desc_pin {
struct pinctrl_pin_desc pin;
unsigned int dsel_offset;
unsigned int dsel_shift;
unsigned int pude_offset;
unsigned int pudsel_offset;
unsigned int pud_shift;
};
#define VISCONTI_PIN(_pin, dsel, d_sh, pude, pudsel, p_sh) \
{ \
.pin = _pin, \
.dsel_offset = dsel, \
.dsel_shift = d_sh, \
.pude_offset = pude, \
.pudsel_offset = pudsel, \
.pud_shift = p_sh, \
}
/* Group */
#define VISCONTI_GROUPS(groups_name, ...) \
static const char * const groups_name ## _grps[] = { __VA_ARGS__ }
struct visconti_mux {
unsigned int offset;
unsigned int mask;
unsigned int val;
};
struct visconti_pin_group {
const char *name;
const unsigned int *pins;
unsigned int nr_pins;
struct visconti_mux mux;
};
#define VISCONTI_PIN_GROUP(group_name, off, msk, v) \
{ \
.name = __stringify(group_name) "_grp", \
.pins = group_name ## _pins, \
.nr_pins = ARRAY_SIZE(group_name ## _pins), \
.mux = { \
.offset = off, \
.mask = msk, \
.val = v, \
} \
}
/* MUX */
struct visconti_pin_function {
const char *name;
const char * const *groups;
unsigned int nr_groups;
};
#define VISCONTI_PIN_FUNCTION(func) \
{ \
.name = #func, \
.groups = func ## _grps, \
.nr_groups = ARRAY_SIZE(func ## _grps), \
}
/* chip dependent data */
struct visconti_pinctrl_devdata {
const struct visconti_desc_pin *pins;
unsigned int nr_pins;
const struct visconti_pin_group *groups;
unsigned int nr_groups;
const struct visconti_pin_function *functions;
unsigned int nr_functions;
const struct visconti_mux *gpio_mux;
void (*unlock)(void __iomem *base);
};
int visconti_pinctrl_probe(struct platform_device *pdev,
const struct visconti_pinctrl_devdata *devdata);
#endif /* __VISCONTI_PINCTRL_COMMON_H__ */

View File

@ -0,0 +1,355 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2020 TOSHIBA CORPORATION
* Copyright (c) 2020 Toshiba Electronic Devices & Storage Corporation
* Copyright (c) 2020 Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
*/
#include <linux/init.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-common.h"
#define tmpv7700_MAGIC_NUM 0x4932f70e
/* register offset */
#define REG_KEY_CTRL 0x0000
#define REG_KEY_CMD 0x0004
#define REG_PINMUX1 0x3000
#define REG_PINMUX2 0x3004
#define REG_PINMUX3 0x3008
#define REG_PINMUX4 0x300c
#define REG_PINMUX5 0x3010
#define REG_IOSET 0x3014
#define REG_IO_VSEL 0x3018
#define REG_IO_DSEL1 0x301c
#define REG_IO_DSEL2 0x3020
#define REG_IO_DSEL3 0x3024
#define REG_IO_DSEL4 0x3028
#define REG_IO_DSEL5 0x302c
#define REG_IO_DSEL6 0x3030
#define REG_IO_DSEL7 0x3034
#define REG_IO_DSEL8 0x3038
#define REG_IO_PUDE1 0x303c
#define REG_IO_PUDE2 0x3040
#define REG_IO_PUDSEL1 0x3044
#define REG_IO_PUDSEL2 0x3048
/* PIN */
static const struct visconti_desc_pin pins_tmpv7700[] = {
VISCONTI_PIN(PINCTRL_PIN(0, "gpio0"), REG_IO_DSEL4, 24,
REG_IO_PUDE1, REG_IO_PUDSEL1, 30),
VISCONTI_PIN(PINCTRL_PIN(1, "gpio1"), REG_IO_DSEL4, 28,
REG_IO_PUDE1, REG_IO_PUDSEL1, 31),
VISCONTI_PIN(PINCTRL_PIN(2, "gpio2"), REG_IO_DSEL5, 0,
REG_IO_PUDE2, REG_IO_PUDSEL2, 0),
VISCONTI_PIN(PINCTRL_PIN(3, "gpio3"), REG_IO_DSEL5, 4,
REG_IO_PUDE2, REG_IO_PUDSEL2, 1),
VISCONTI_PIN(PINCTRL_PIN(4, "gpio4"), REG_IO_DSEL5, 8,
REG_IO_PUDE2, REG_IO_PUDSEL2, 2),
VISCONTI_PIN(PINCTRL_PIN(5, "gpio5"), REG_IO_DSEL5, 12,
REG_IO_PUDE2, REG_IO_PUDSEL2, 3),
VISCONTI_PIN(PINCTRL_PIN(6, "gpio6"), REG_IO_DSEL5, 16,
REG_IO_PUDE2, REG_IO_PUDSEL2, 4),
VISCONTI_PIN(PINCTRL_PIN(7, "gpio7"), REG_IO_DSEL5, 20,
REG_IO_PUDE2, REG_IO_PUDSEL2, 5),
VISCONTI_PIN(PINCTRL_PIN(8, "gpio8"), REG_IO_DSEL5, 24,
REG_IO_PUDE2, REG_IO_PUDSEL2, 6),
VISCONTI_PIN(PINCTRL_PIN(9, "gpio9"), REG_IO_DSEL5, 28,
REG_IO_PUDE2, REG_IO_PUDSEL2, 7),
VISCONTI_PIN(PINCTRL_PIN(10, "gpio10"), REG_IO_DSEL6, 0,
REG_IO_PUDE2, REG_IO_PUDSEL2, 8),
VISCONTI_PIN(PINCTRL_PIN(11, "gpio11"), REG_IO_DSEL6, 4,
REG_IO_PUDE2, REG_IO_PUDSEL2, 9),
VISCONTI_PIN(PINCTRL_PIN(12, "gpio12"), REG_IO_DSEL6, 8,
REG_IO_PUDE2, REG_IO_PUDSEL2, 10),
VISCONTI_PIN(PINCTRL_PIN(13, "gpio13"), REG_IO_DSEL6, 12,
REG_IO_PUDE2, REG_IO_PUDSEL2, 11),
VISCONTI_PIN(PINCTRL_PIN(14, "gpio14"), REG_IO_DSEL6, 16,
REG_IO_PUDE2, REG_IO_PUDSEL2, 12),
VISCONTI_PIN(PINCTRL_PIN(15, "gpio15"), REG_IO_DSEL6, 20,
REG_IO_PUDE2, REG_IO_PUDSEL2, 13),
VISCONTI_PIN(PINCTRL_PIN(16, "gpio16"), REG_IO_DSEL6, 24,
REG_IO_PUDE2, REG_IO_PUDSEL2, 14),
VISCONTI_PIN(PINCTRL_PIN(17, "gpio17"), REG_IO_DSEL6, 28,
REG_IO_PUDE2, REG_IO_PUDSEL2, 15),
VISCONTI_PIN(PINCTRL_PIN(18, "gpio18"), REG_IO_DSEL7, 0,
REG_IO_PUDE2, REG_IO_PUDSEL2, 16),
VISCONTI_PIN(PINCTRL_PIN(19, "gpio19"), REG_IO_DSEL7, 4,
REG_IO_PUDE2, REG_IO_PUDSEL2, 17),
VISCONTI_PIN(PINCTRL_PIN(20, "gpio20"), REG_IO_DSEL7, 8,
REG_IO_PUDE2, REG_IO_PUDSEL2, 18),
VISCONTI_PIN(PINCTRL_PIN(21, "gpio21"), REG_IO_DSEL7, 12,
REG_IO_PUDE2, REG_IO_PUDSEL2, 19),
VISCONTI_PIN(PINCTRL_PIN(22, "gpio22"), REG_IO_DSEL7, 16,
REG_IO_PUDE2, REG_IO_PUDSEL2, 20),
VISCONTI_PIN(PINCTRL_PIN(23, "gpio23"), REG_IO_DSEL7, 20,
REG_IO_PUDE2, REG_IO_PUDSEL2, 21),
VISCONTI_PIN(PINCTRL_PIN(24, "gpio24"), REG_IO_DSEL7, 24,
REG_IO_PUDE2, REG_IO_PUDSEL2, 22),
VISCONTI_PIN(PINCTRL_PIN(25, "gpio25"), REG_IO_DSEL7, 28,
REG_IO_PUDE2, REG_IO_PUDSEL2, 23),
VISCONTI_PIN(PINCTRL_PIN(26, "gpio26"), REG_IO_DSEL8, 0,
REG_IO_PUDE2, REG_IO_PUDSEL2, 24),
VISCONTI_PIN(PINCTRL_PIN(27, "gpio27"), REG_IO_DSEL8, 4,
REG_IO_PUDE2, REG_IO_PUDSEL2, 25),
VISCONTI_PIN(PINCTRL_PIN(28, "gpio28"), REG_IO_DSEL8, 8,
REG_IO_PUDE2, REG_IO_PUDSEL2, 26),
VISCONTI_PIN(PINCTRL_PIN(29, "gpio29"), REG_IO_DSEL4, 8,
REG_IO_PUDE1, REG_IO_PUDSEL1, 26),
VISCONTI_PIN(PINCTRL_PIN(30, "gpio30"), REG_IO_DSEL4, 4,
REG_IO_PUDE1, REG_IO_PUDSEL1, 25),
VISCONTI_PIN(PINCTRL_PIN(31, "gpio31"), REG_IO_DSEL4, 0,
REG_IO_PUDE1, REG_IO_PUDSEL1, 24),
VISCONTI_PIN(PINCTRL_PIN(32, "spi_sck"), REG_IO_DSEL4, 12,
REG_IO_PUDE1, REG_IO_PUDSEL1, 27),
VISCONTI_PIN(PINCTRL_PIN(33, "spi_sdo"), REG_IO_DSEL4, 16,
REG_IO_PUDE1, REG_IO_PUDSEL1, 28),
VISCONTI_PIN(PINCTRL_PIN(34, "spi_sdi"), REG_IO_DSEL4, 20,
REG_IO_PUDE1, REG_IO_PUDSEL1, 29),
};
/* Group */
VISCONTI_PINS(i2c0, 0, 1);
VISCONTI_PINS(i2c1, 2, 3);
VISCONTI_PINS(i2c2, 12, 13);
VISCONTI_PINS(i2c3, 14, 15);
VISCONTI_PINS(i2c4, 16, 17);
VISCONTI_PINS(i2c5, 18, 19);
VISCONTI_PINS(i2c6, 33, 34);
VISCONTI_PINS(i2c7, 29, 32);
VISCONTI_PINS(i2c8, 30, 31);
VISCONTI_PINS(spi0_cs0, 29);
VISCONTI_PINS(spi0_cs1, 30);
VISCONTI_PINS(spi0_cs2, 31);
VISCONTI_PINS(spi1_cs, 3);
VISCONTI_PINS(spi2_cs, 7);
VISCONTI_PINS(spi3_cs, 11);
VISCONTI_PINS(spi4_cs, 15);
VISCONTI_PINS(spi5_cs, 19);
VISCONTI_PINS(spi6_cs, 27);
VISCONTI_PINS(spi0, 32, 33, 34);
VISCONTI_PINS(spi1, 0, 1, 2);
VISCONTI_PINS(spi2, 4, 5, 6);
VISCONTI_PINS(spi3, 8, 9, 10);
VISCONTI_PINS(spi4, 12, 13, 14);
VISCONTI_PINS(spi5, 16, 17, 18);
VISCONTI_PINS(spi6, 24, 25, 26);
VISCONTI_PINS(uart0, 4, 5, 6, 7);
VISCONTI_PINS(uart1, 8, 9, 10, 11);
VISCONTI_PINS(uart2, 12, 13, 14, 15);
VISCONTI_PINS(uart3, 16, 17, 18, 19);
VISCONTI_PINS(pwm0_gpio4, 4);
VISCONTI_PINS(pwm1_gpio5, 5);
VISCONTI_PINS(pwm2_gpio6, 6);
VISCONTI_PINS(pwm3_gpio7, 7);
VISCONTI_PINS(pwm0_gpio8, 8);
VISCONTI_PINS(pwm1_gpio9, 9);
VISCONTI_PINS(pwm2_gpio10, 10);
VISCONTI_PINS(pwm3_gpio11, 11);
VISCONTI_PINS(pwm0_gpio12, 12);
VISCONTI_PINS(pwm1_gpio13, 13);
VISCONTI_PINS(pwm2_gpio14, 14);
VISCONTI_PINS(pwm3_gpio15, 15);
VISCONTI_PINS(pwm0_gpio16, 16);
VISCONTI_PINS(pwm1_gpio17, 17);
VISCONTI_PINS(pwm2_gpio18, 18);
VISCONTI_PINS(pwm3_gpio19, 19);
VISCONTI_PINS(pcmif_out, 20, 21, 22);
VISCONTI_PINS(pcmif_in, 24, 25, 26);
static const struct visconti_pin_group groups_tmpv7700[] = {
VISCONTI_PIN_GROUP(i2c0, REG_PINMUX2, GENMASK(7, 0), 0x00000022),
VISCONTI_PIN_GROUP(i2c1, REG_PINMUX2, GENMASK(15, 8), 0x00002200),
VISCONTI_PIN_GROUP(i2c2, REG_PINMUX3, GENMASK(23, 16), 0x00770000),
VISCONTI_PIN_GROUP(i2c3, REG_PINMUX3, GENMASK(31, 24), 0x77000000),
VISCONTI_PIN_GROUP(i2c4, REG_PINMUX4, GENMASK(7, 0), 0x00000077),
VISCONTI_PIN_GROUP(i2c5, REG_PINMUX4, GENMASK(15, 8), 0x00007700),
VISCONTI_PIN_GROUP(i2c6, REG_PINMUX1, GENMASK(3, 0), 0x0000002),
VISCONTI_PIN_GROUP(i2c7, REG_PINMUX5, GENMASK(23, 20), 0x00200000),
VISCONTI_PIN_GROUP(i2c8, REG_PINMUX5, GENMASK(31, 24), 0x22000000),
VISCONTI_PIN_GROUP(spi0_cs0, REG_PINMUX5, GENMASK(23, 20), 0x00100000),
VISCONTI_PIN_GROUP(spi0_cs1, REG_PINMUX5, GENMASK(27, 24), 0x01000000),
VISCONTI_PIN_GROUP(spi0_cs2, REG_PINMUX5, GENMASK(31, 28), 0x10000000),
VISCONTI_PIN_GROUP(spi1_cs, REG_PINMUX2, GENMASK(15, 12), 0x00001000),
VISCONTI_PIN_GROUP(spi2_cs, REG_PINMUX2, GENMASK(31, 28), 0x10000000),
VISCONTI_PIN_GROUP(spi3_cs, REG_PINMUX3, GENMASK(15, 12), 0x00001000),
VISCONTI_PIN_GROUP(spi4_cs, REG_PINMUX4, GENMASK(31, 28), 0x10000000),
VISCONTI_PIN_GROUP(spi5_cs, REG_PINMUX4, GENMASK(15, 12), 0x00001000),
VISCONTI_PIN_GROUP(spi6_cs, REG_PINMUX5, GENMASK(15, 12), 0x00001000),
VISCONTI_PIN_GROUP(spi0, REG_PINMUX1, GENMASK(3, 0), 0x00000001),
VISCONTI_PIN_GROUP(spi1, REG_PINMUX2, GENMASK(11, 0), 0x00000111),
VISCONTI_PIN_GROUP(spi2, REG_PINMUX2, GENMASK(27, 16), 0x01110000),
VISCONTI_PIN_GROUP(spi3, REG_PINMUX3, GENMASK(11, 0), 0x00000111),
VISCONTI_PIN_GROUP(spi4, REG_PINMUX3, GENMASK(27, 16), 0x01110000),
VISCONTI_PIN_GROUP(spi5, REG_PINMUX4, GENMASK(11, 0), 0x00000111),
VISCONTI_PIN_GROUP(spi6, REG_PINMUX5, GENMASK(11, 0), 0x00000111),
VISCONTI_PIN_GROUP(uart0, REG_PINMUX2, GENMASK(31, 16), 0x22220000),
VISCONTI_PIN_GROUP(uart1, REG_PINMUX3, GENMASK(15, 0), 0x00002222),
VISCONTI_PIN_GROUP(uart2, REG_PINMUX3, GENMASK(31, 16), 0x22220000),
VISCONTI_PIN_GROUP(uart3, REG_PINMUX4, GENMASK(15, 0), 0x00002222),
VISCONTI_PIN_GROUP(pwm0_gpio4, REG_PINMUX2, GENMASK(19, 16), 0x00050000),
VISCONTI_PIN_GROUP(pwm1_gpio5, REG_PINMUX2, GENMASK(23, 20), 0x00500000),
VISCONTI_PIN_GROUP(pwm2_gpio6, REG_PINMUX2, GENMASK(27, 24), 0x05000000),
VISCONTI_PIN_GROUP(pwm3_gpio7, REG_PINMUX2, GENMASK(31, 28), 0x50000000),
VISCONTI_PIN_GROUP(pwm0_gpio8, REG_PINMUX3, GENMASK(3, 0), 0x00000005),
VISCONTI_PIN_GROUP(pwm1_gpio9, REG_PINMUX3, GENMASK(7, 4), 0x00000050),
VISCONTI_PIN_GROUP(pwm2_gpio10, REG_PINMUX3, GENMASK(11, 8), 0x00000500),
VISCONTI_PIN_GROUP(pwm3_gpio11, REG_PINMUX3, GENMASK(15, 12), 0x00005000),
VISCONTI_PIN_GROUP(pwm0_gpio12, REG_PINMUX3, GENMASK(19, 16), 0x00050000),
VISCONTI_PIN_GROUP(pwm1_gpio13, REG_PINMUX3, GENMASK(23, 20), 0x00500000),
VISCONTI_PIN_GROUP(pwm2_gpio14, REG_PINMUX3, GENMASK(27, 24), 0x05000000),
VISCONTI_PIN_GROUP(pwm3_gpio15, REG_PINMUX3, GENMASK(31, 28), 0x50000000),
VISCONTI_PIN_GROUP(pwm0_gpio16, REG_PINMUX4, GENMASK(3, 0), 0x00000005),
VISCONTI_PIN_GROUP(pwm1_gpio17, REG_PINMUX4, GENMASK(7, 4), 0x00000050),
VISCONTI_PIN_GROUP(pwm2_gpio18, REG_PINMUX4, GENMASK(11, 8), 0x00000500),
VISCONTI_PIN_GROUP(pwm3_gpio19, REG_PINMUX4, GENMASK(15, 12), 0x00005000),
VISCONTI_PIN_GROUP(pcmif_out, REG_PINMUX4, GENMASK(27, 16), 0x01110000),
VISCONTI_PIN_GROUP(pcmif_in, REG_PINMUX5, GENMASK(11, 0), 0x00000222),
};
/* MUX */
VISCONTI_GROUPS(i2c0, "i2c0_grp");
VISCONTI_GROUPS(i2c1, "i2c1_grp");
VISCONTI_GROUPS(i2c2, "i2c2_grp");
VISCONTI_GROUPS(i2c3, "i2c3_grp");
VISCONTI_GROUPS(i2c4, "i2c4_grp");
VISCONTI_GROUPS(i2c5, "i2c5_grp");
VISCONTI_GROUPS(i2c6, "i2c6_grp");
VISCONTI_GROUPS(i2c7, "i2c7_grp");
VISCONTI_GROUPS(i2c8, "i2c8_grp");
VISCONTI_GROUPS(spi0, "spi0_grp", "spi0_cs0_grp",
"spi0_cs1_grp", "spi0_cs2_grp");
VISCONTI_GROUPS(spi1, "spi1_grp", "spi1_cs_grp");
VISCONTI_GROUPS(spi2, "spi2_grp", "spi2_cs_grp");
VISCONTI_GROUPS(spi3, "spi3_grp", "spi3_cs_grp");
VISCONTI_GROUPS(spi4, "spi4_grp", "spi4_cs_grp");
VISCONTI_GROUPS(spi5, "spi5_grp", "spi5_cs_grp");
VISCONTI_GROUPS(spi6, "spi6_grp", "spi6_cs_grp");
VISCONTI_GROUPS(uart0, "uart0_grp");
VISCONTI_GROUPS(uart1, "uart1_grp");
VISCONTI_GROUPS(uart2, "uart2_grp");
VISCONTI_GROUPS(uart3, "uart3_grp");
VISCONTI_GROUPS(pwm, "pwm0_gpio4_grp", "pwm0_gpio8_grp",
"pwm0_gpio12_grp", "pwm0_gpio16_grp",
"pwm1_gpio5_grp", "pwm1_gpio9_grp",
"pwm1_gpio13_grp", "pwm1_gpio17_grp",
"pwm2_gpio6_grp", "pwm2_gpio10_grp",
"pwm2_gpio14_grp", "pwm2_gpio18_grp",
"pwm3_gpio7_grp", "pwm3_gpio11_grp",
"pwm3_gpio15_grp", "pwm3_gpio19_grp");
VISCONTI_GROUPS(pcmif_out, "pcmif_out_grp");
VISCONTI_GROUPS(pcmif_in, "pcmif_in_grp");
static const struct visconti_pin_function functions_tmpv7700[] = {
VISCONTI_PIN_FUNCTION(i2c0),
VISCONTI_PIN_FUNCTION(i2c1),
VISCONTI_PIN_FUNCTION(i2c2),
VISCONTI_PIN_FUNCTION(i2c3),
VISCONTI_PIN_FUNCTION(i2c4),
VISCONTI_PIN_FUNCTION(i2c5),
VISCONTI_PIN_FUNCTION(i2c6),
VISCONTI_PIN_FUNCTION(i2c7),
VISCONTI_PIN_FUNCTION(i2c8),
VISCONTI_PIN_FUNCTION(spi0),
VISCONTI_PIN_FUNCTION(spi1),
VISCONTI_PIN_FUNCTION(spi2),
VISCONTI_PIN_FUNCTION(spi3),
VISCONTI_PIN_FUNCTION(spi4),
VISCONTI_PIN_FUNCTION(spi5),
VISCONTI_PIN_FUNCTION(spi6),
VISCONTI_PIN_FUNCTION(uart0),
VISCONTI_PIN_FUNCTION(uart1),
VISCONTI_PIN_FUNCTION(uart2),
VISCONTI_PIN_FUNCTION(uart3),
VISCONTI_PIN_FUNCTION(pwm),
VISCONTI_PIN_FUNCTION(pcmif_in),
VISCONTI_PIN_FUNCTION(pcmif_out),
};
/* GPIO MUX */
#define tmpv7700_GPIO_MUX(off, msk) \
{ \
.offset = off, \
.mask = msk, \
.val = 0, \
}
static const struct visconti_mux gpio_mux_tmpv7700[] = {
tmpv7700_GPIO_MUX(REG_PINMUX2, GENMASK(3, 0)),
tmpv7700_GPIO_MUX(REG_PINMUX2, GENMASK(7, 4)),
tmpv7700_GPIO_MUX(REG_PINMUX2, GENMASK(11, 8)),
tmpv7700_GPIO_MUX(REG_PINMUX2, GENMASK(15, 12)),
tmpv7700_GPIO_MUX(REG_PINMUX2, GENMASK(19, 16)),
tmpv7700_GPIO_MUX(REG_PINMUX2, GENMASK(23, 20)),
tmpv7700_GPIO_MUX(REG_PINMUX2, GENMASK(27, 24)),
tmpv7700_GPIO_MUX(REG_PINMUX2, GENMASK(31, 28)),
tmpv7700_GPIO_MUX(REG_PINMUX3, GENMASK(3, 0)),
tmpv7700_GPIO_MUX(REG_PINMUX3, GENMASK(7, 4)),
tmpv7700_GPIO_MUX(REG_PINMUX3, GENMASK(11, 8)),
tmpv7700_GPIO_MUX(REG_PINMUX3, GENMASK(15, 12)),
tmpv7700_GPIO_MUX(REG_PINMUX3, GENMASK(19, 16)),
tmpv7700_GPIO_MUX(REG_PINMUX3, GENMASK(23, 20)),
tmpv7700_GPIO_MUX(REG_PINMUX3, GENMASK(27, 24)),
tmpv7700_GPIO_MUX(REG_PINMUX3, GENMASK(31, 28)),
tmpv7700_GPIO_MUX(REG_PINMUX4, GENMASK(3, 0)),
tmpv7700_GPIO_MUX(REG_PINMUX4, GENMASK(7, 4)),
tmpv7700_GPIO_MUX(REG_PINMUX4, GENMASK(11, 8)),
tmpv7700_GPIO_MUX(REG_PINMUX4, GENMASK(15, 12)),
tmpv7700_GPIO_MUX(REG_PINMUX4, GENMASK(19, 16)),
tmpv7700_GPIO_MUX(REG_PINMUX4, GENMASK(23, 20)),
tmpv7700_GPIO_MUX(REG_PINMUX4, GENMASK(27, 24)),
tmpv7700_GPIO_MUX(REG_PINMUX4, GENMASK(31, 28)),
tmpv7700_GPIO_MUX(REG_PINMUX5, GENMASK(3, 0)),
tmpv7700_GPIO_MUX(REG_PINMUX5, GENMASK(7, 4)),
tmpv7700_GPIO_MUX(REG_PINMUX5, GENMASK(11, 8)),
tmpv7700_GPIO_MUX(REG_PINMUX5, GENMASK(15, 12)),
tmpv7700_GPIO_MUX(REG_PINMUX5, GENMASK(19, 16)),
tmpv7700_GPIO_MUX(REG_PINMUX5, GENMASK(23, 20)),
tmpv7700_GPIO_MUX(REG_PINMUX5, GENMASK(27, 24)),
tmpv7700_GPIO_MUX(REG_PINMUX5, GENMASK(31, 28)),
};
static void tmpv7700_pinctrl_unlock(void __iomem *base)
{
writel(1, base + REG_KEY_CTRL);
writel(tmpv7700_MAGIC_NUM, base + REG_KEY_CMD);
}
/* chip dependent data */
static const struct visconti_pinctrl_devdata tmpv7700_pinctrl_data = {
.pins = pins_tmpv7700,
.nr_pins = ARRAY_SIZE(pins_tmpv7700),
.groups = groups_tmpv7700,
.nr_groups = ARRAY_SIZE(groups_tmpv7700),
.functions = functions_tmpv7700,
.nr_functions = ARRAY_SIZE(functions_tmpv7700),
.gpio_mux = gpio_mux_tmpv7700,
.unlock = tmpv7700_pinctrl_unlock,
};
static int tmpv7700_pinctrl_probe(struct platform_device *pdev)
{
return visconti_pinctrl_probe(pdev, &tmpv7700_pinctrl_data);
}
static const struct of_device_id tmpv7700_pctrl_of_match[] = {
{ .compatible = "toshiba,tmpv7708-pinctrl", },
{},
};
static struct platform_driver tmpv7700_pinctrl_driver = {
.probe = tmpv7700_pinctrl_probe,
.driver = {
.name = "tmpv7700-pinctrl",
.of_match_table = tmpv7700_pctrl_of_match,
},
};
static int __init tmpv7700_pinctrl_init(void)
{
return platform_driver_register(&tmpv7700_pinctrl_driver);
}
arch_initcall(tmpv7700_pinctrl_init);