mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-12-25 04:23:46 +00:00
dfb0a70a1a
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>
82 lines
1.8 KiB
C
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,
|
|
};
|