u-boot/drivers/power/pmic/fan53555.c
Philipp Tomsich dfb0a70a1a power: add FAN53555 family support
This adds a driver for the FAN53555 family of regulators and wraps it
in a PMIC implementation.

While these devices support a 'normal' and 'suspend' mode (controlled
via an external pin) to switch between two programmable voltages, this
incarnation of the driver assumes that the device is always operating
in 'normal' mode.

Only setting/reading the programmed voltage is supported at this time
and the following device functionality remains unsupported:
  - switching the selected voltage (via a GPIO)
  - disabling the voltage output via software-control
This matches the functionality of the Linux driver.

Tested on a RK3399-Q7 (with 'option 5' devices): setting voltages from
the U-Boot shell and verifying output voltages on the board.

Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Tested-by: Klaus Goger <klaus.goger@theobroma-systems.com>
2018-12-10 10:04:45 +01:00

82 lines
1.8 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* (C) 2018 Theobroma Systems Design und Consulting GmbH
*/
#include <common.h>
#include <dm.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <i2c.h>
#include <power/pmic.h>
#include <power/regulator.h>
static int pmic_fan53555_reg_count(struct udevice *dev)
{
return 1;
};
static int pmic_fan53555_read(struct udevice *dev, uint reg,
u8 *buff, int len)
{
if (dm_i2c_read(dev, reg, buff, len)) {
pr_err("%s: read error for register: %#x!", dev->name, reg);
return -EIO;
}
return 0;
}
static int pmic_fan53555_write(struct udevice *dev, uint reg,
const u8 *buff, int len)
{
if (dm_i2c_write(dev, reg, buff, len)) {
pr_err("%s: write error for register: %#x!", dev->name, reg);
return -EIO;
}
return 0;
}
static int pmic_fan53555_bind(struct udevice *dev)
{
/*
* The FAN53555 has only a single regulator and therefore doesn't
* have a subnode. So we have to rebind a child device (the one
* regulator) here.
*/
const char *regulator_driver_name = "fan53555_regulator";
struct udevice *child;
struct driver *drv;
debug("%s\n", __func__);
drv = lists_driver_lookup_name(regulator_driver_name);
if (!drv) {
dev_err(dev, "no driver '%s'\n", regulator_driver_name);
return -ENOENT;
}
return device_bind_with_driver_data(dev, drv, "SW", 0,
dev_ofnode(dev), &child);
};
static struct dm_pmic_ops pmic_fan53555_ops = {
.reg_count = pmic_fan53555_reg_count,
.read = pmic_fan53555_read,
.write = pmic_fan53555_write,
};
static const struct udevice_id pmic_fan53555_match[] = {
{ .compatible = "fcs,fan53555" },
{ },
};
U_BOOT_DRIVER(pmic_fan53555) = {
.name = "pmic_fan53555",
.id = UCLASS_PMIC,
.of_match = pmic_fan53555_match,
.bind = pmic_fan53555_bind,
.ops = &pmic_fan53555_ops,
};