From 8996395939a1dc8d5870a185e13e4cd102d7108b Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Sun, 18 Sep 2016 12:08:28 +0200 Subject: dm: pmic: wrap RSB into dm driver Implement driver to wrap RSB in a device-model I2C driver. --- drivers/i2c/Makefile | 1 + drivers/i2c/sunxi-rsb.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 drivers/i2c/sunxi-rsb.c diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index c75c5793ef..0b6d8beb6c 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -40,5 +40,6 @@ obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o obj-$(CONFIG_SYS_I2C_UNIPHIER) += i2c-uniphier.o obj-$(CONFIG_SYS_I2C_UNIPHIER_F) += i2c-uniphier-f.o obj-$(CONFIG_SYS_I2C_ZYNQ) += zynq_i2c.o +obj-$(CONFIG_MACH_SUN9I) += sunxi-rsb.o obj-$(CONFIG_I2C_MUX) += muxes/ diff --git a/drivers/i2c/sunxi-rsb.c b/drivers/i2c/sunxi-rsb.c new file mode 100644 index 0000000000..2f332da44e --- /dev/null +++ b/drivers/i2c/sunxi-rsb.c @@ -0,0 +1,104 @@ +/* + * (C) Copyright 2016 Theobroma Systems Design und Consulting GmbH + * Written by Philipp Tomsich + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include /* Should go away, once this driver is stand-alone */ +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +struct sunxi_rsb { + void* regs; +}; + +/* This is just a simple wrapper around the native RSB driver, but should + in fact pull in the initialisation and hardware control in the future. */ + +static int sunxi_rsb_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs) +{ + int ret = 0; + int reg = -1; + + for (; nmsgs > 0; nmsgs--, msg++) { + debug("sunxi_rsb_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len); + if (msg->flags & I2C_M_RD) { + while ( (msg->len)-- && !ret ) { + debug("rsb_read(a: %d, r: %d, d: ...)\n", msg->addr, reg); + ret = rsb_read(msg->addr, reg++, (msg->buf)++); //, msg->len); + } + } else { + reg = *(msg->buf++); --(msg->len); + debug("sunxi_rsb_xfer: setting reg to %d\n", reg); + while ( (msg->len)-- && !ret ) { + debug("rsb_write(a: %d, r: %d, d: 0x%x)\n", msg->addr, reg, *(msg->buf)); + ret = rsb_write(msg->addr, reg++, *(msg->buf++)); + } + } + if (ret) { + debug("sunxi_rsb_xfer: error sending\n"); + return -EREMOTEIO; + } + } + + return ret; +} + +int sunxi_rsb_set_bus_speed(struct udevice *bus, unsigned int speed) +{ + debug("sunxi_rsb_set_bus_speed\n"); + return 0; +} + +static int sunxi_rsb_ofdata_to_platdata(struct udevice *bus) +{ + debug("sunxi_rsb_ofdata_to_platdata\n"); + return 0; +} + +static int sunxi_rsb_probe(struct udevice *bus) +{ + struct sunxi_rsb *priv = dev_get_priv(bus); + int ret; + debug("sunxi_rsb_probe\n"); + + /* make sure the RSB bus is initialised */ + ret = pmic_bus_init(); + debug("retval from pmic_bus_init(): %d\n", ret); + + priv->regs = (void *)dev_get_addr(bus); + + return 0; +} + +static const struct dm_i2c_ops sunxi_rsb_ops = { + .xfer = sunxi_rsb_xfer, + .set_bus_speed = sunxi_rsb_set_bus_speed, +}; + +static const struct udevice_id sunxi_rsb_ids[] = { + { .compatible = "allwinner,sun8i-a23-rsb" }, + { } +}; + +U_BOOT_DRIVER(i2c_rockchip) = { + .name = "sunxi_rsb", + .id = UCLASS_I2C, + .flags = DM_I2C_CHIP_RD_ADDRESS | DM_I2C_CHIP_WR_ADDRESS, + .of_match = sunxi_rsb_ids, + .ofdata_to_platdata = sunxi_rsb_ofdata_to_platdata, + .probe = sunxi_rsb_probe, + .priv_auto_alloc_size = sizeof(struct sunxi_rsb), + .ops = &sunxi_rsb_ops, +}; -- cgit v1.2.3