u-boot/drivers/pinctrl/nxp/pinctrl-mxs.c
Walter Lozano e3e2470fdd drivers: rename drivers to match compatible string
When using OF_PLATDATA, the bind process between devices and drivers
is performed trying to match compatible string with driver names.
However driver names are not strictly defined, and also there are different
names used when declaring a driver with U_BOOT_DRIVER, the name of the
symbol used in the linker list and the used in the struct driver_info.

In order to make things a bit more clear, rename the drivers names. This
will also help for further OF_PLATDATA improvements, such as checking
for valid driver names.

Signed-off-by: Walter Lozano <walter.lozano@collabora.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Add a fix for sandbox of-platdata to avoid using an invalid ANSI colour:
Signed-off-by: Simon Glass <sjg@chromium.org>
2020-07-09 18:57:22 -06:00

193 lines
4.1 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2019 DENX Software Engineering
* Lukasz Majewski, DENX Software Engineering, lukma@denx.de
*/
#include <common.h>
#include <log.h>
#include <dm/device_compat.h>
#include <dm/devres.h>
#include <linux/io.h>
#include <linux/err.h>
#include <dm.h>
#include <dm/pinctrl.h>
#include <dm/read.h>
#include "pinctrl-mxs.h"
DECLARE_GLOBAL_DATA_PTR;
struct mxs_pinctrl_priv {
void __iomem *base;
const struct mxs_regs *regs;
};
static unsigned long mxs_dt_node_to_map(struct udevice *conf)
{
unsigned long config = 0;
int ret;
u32 val;
ret = dev_read_u32(conf, "fsl,drive-strength", &val);
if (!ret)
config = val | MA_PRESENT;
ret = dev_read_u32(conf, "fsl,voltage", &val);
if (!ret)
config |= val << VOL_SHIFT | VOL_PRESENT;
ret = dev_read_u32(conf, "fsl,pull-up", &val);
if (!ret)
config |= val << PULL_SHIFT | PULL_PRESENT;
return config;
}
static int mxs_pinctrl_set_mux(struct udevice *dev, u32 val, int bank, int pin)
{
struct mxs_pinctrl_priv *iomux = dev_get_priv(dev);
int muxsel = MUXID_TO_MUXSEL(val), shift;
void __iomem *reg;
reg = iomux->base + iomux->regs->muxsel;
reg += bank * 0x20 + pin / 16 * 0x10;
shift = pin % 16 * 2;
mxs_pinctrl_rmwl(muxsel, 0x3, shift, reg);
debug(" mux %d,", muxsel);
return 0;
}
static int mxs_pinctrl_set_state(struct udevice *dev, struct udevice *conf)
{
struct mxs_pinctrl_priv *iomux = dev_get_priv(dev);
u32 *pin_data, val, ma, vol, pull;
int npins, size, i, ret;
unsigned long config;
debug("\n%s: set state: %s\n", __func__, conf->name);
size = dev_read_size(conf, "fsl,pinmux-ids");
if (size < 0)
return size;
if (!size || size % sizeof(int)) {
dev_err(dev, "Invalid fsl,pinmux-ids property in %s\n",
conf->name);
return -EINVAL;
}
npins = size / sizeof(int);
pin_data = devm_kzalloc(dev, size, 0);
if (!pin_data)
return -ENOMEM;
ret = dev_read_u32_array(conf, "fsl,pinmux-ids", pin_data, npins);
if (ret) {
dev_err(dev, "Error reading pin data.\n");
devm_kfree(dev, pin_data);
return -EINVAL;
}
config = mxs_dt_node_to_map(conf);
ma = CONFIG_TO_MA(config);
vol = CONFIG_TO_VOL(config);
pull = CONFIG_TO_PULL(config);
for (i = 0; i < npins; i++) {
int pinid, bank, pin, shift;
void __iomem *reg;
val = pin_data[i];
pinid = MUXID_TO_PINID(val);
bank = PINID_TO_BANK(pinid);
pin = PINID_TO_PIN(pinid);
debug("(val: 0x%x) pin %d,", val, pinid);
/* Setup pinmux */
mxs_pinctrl_set_mux(dev, val, bank, pin);
debug(" ma: %d, vol: %d, pull: %d\n", ma, vol, pull);
/* drive */
reg = iomux->base + iomux->regs->drive;
reg += bank * 0x40 + pin / 8 * 0x10;
/* mA */
if (config & MA_PRESENT) {
shift = pin % 8 * 4;
mxs_pinctrl_rmwl(ma, 0x3, shift, reg);
}
/* vol */
if (config & VOL_PRESENT) {
shift = pin % 8 * 4 + 2;
if (vol)
writel(1 << shift, reg + SET);
else
writel(1 << shift, reg + CLR);
}
/* pull */
if (config & PULL_PRESENT) {
reg = iomux->base + iomux->regs->pull;
reg += bank * 0x10;
shift = pin;
if (pull)
writel(1 << shift, reg + SET);
else
writel(1 << shift, reg + CLR);
}
}
devm_kfree(dev, pin_data);
return 0;
}
static struct pinctrl_ops mxs_pinctrl_ops = {
.set_state = mxs_pinctrl_set_state,
};
static int mxs_pinctrl_probe(struct udevice *dev)
{
struct mxs_pinctrl_priv *iomux = dev_get_priv(dev);
iomux->base = dev_read_addr_ptr(dev);
iomux->regs = (struct mxs_regs *)dev_get_driver_data(dev);
return 0;
}
static const struct mxs_regs imx23_regs = {
.muxsel = 0x100,
.drive = 0x200,
.pull = 0x400,
};
static const struct mxs_regs imx28_regs = {
.muxsel = 0x100,
.drive = 0x300,
.pull = 0x600,
};
static const struct udevice_id mxs_pinctrl_match[] = {
{ .compatible = "fsl,imx23-pinctrl", .data = (ulong)&imx23_regs },
{ .compatible = "fsl,imx28-pinctrl", .data = (ulong)&imx28_regs },
{ /* sentinel */ }
};
U_BOOT_DRIVER(fsl_imx23_pinctrl) = {
.name = "fsl_imx23_pinctrl",
.id = UCLASS_PINCTRL,
.of_match = of_match_ptr(mxs_pinctrl_match),
.probe = mxs_pinctrl_probe,
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
.bind = dm_scan_fdt_dev,
#endif
.priv_auto_alloc_size = sizeof(struct mxs_pinctrl_priv),
.ops = &mxs_pinctrl_ops,
};