diff options
author | Ye Li <ye.li@nxp.com> | 2018-05-22 22:43:00 -0700 |
---|---|---|
committer | Ye Li <ye.li@nxp.com> | 2018-05-23 04:15:48 -0700 |
commit | e9a3bec2e95a4b2b4641223c8ee4ebd8da76d7f9 (patch) | |
tree | 97fda2e1fd75395fe4e87af2ea700db7a23bf03c | |
parent | f3d2fba8183ac9b9274348f9bbe4c85da266984d (diff) |
MLK-18387 pmic: Add pmic driver for BD71837
The iMX8MM EVK board uses BD71837MWV pmic. Add its driver to u-boot.
Signed-off-by: Ye Li <ye.li@nxp.com>
-rw-r--r-- | drivers/power/pmic/Kconfig | 7 | ||||
-rw-r--r-- | drivers/power/pmic/Makefile | 2 | ||||
-rw-r--r-- | drivers/power/pmic/bd71837.c | 92 | ||||
-rw-r--r-- | drivers/power/pmic/pmic_bd71837.c | 33 | ||||
-rw-r--r-- | include/power/bd71837.h | 62 |
5 files changed, 196 insertions, 0 deletions
diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index 5d49c93f32a..4cf72173182 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -48,6 +48,13 @@ config PMIC_AS3722 interface and is designs to cover most of the power managementment required for a tablets or laptop. +config DM_PMIC_BD71837 + bool "Enable Driver Model for PMIC BD71837" + depends on DM_PMIC + help + This config enables implementation of driver-model pmic uclass features + for PMIC BD71837. The driver implements read/write operations. + config DM_PMIC_PFUZE100 bool "Enable Driver Model for PMIC PFUZE100" depends on DM_PMIC diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index 67930225017..2a885b0af2a 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_$(SPL_)DM_PMIC) += pmic-uclass.o obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o obj-$(CONFIG_DM_PMIC_MAX8998) += max8998.o obj-$(CONFIG_$(SPL_)DM_PMIC_PFUZE100) += pfuze100.o +obj-$(CONFIG_$(SPL_)DM_PMIC_BD71837) += bd71837.o obj-$(CONFIG_PMIC_S2MPS11) += s2mps11.o obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o obj-$(CONFIG_PMIC_ACT8846) += act8846.o @@ -30,6 +31,7 @@ obj-$(CONFIG_POWER_MAX8998) += pmic_max8998.o obj-$(CONFIG_POWER_MAX8997) += pmic_max8997.o obj-$(CONFIG_POWER_MUIC_MAX8997) += muic_max8997.o obj-$(CONFIG_POWER_MAX77686) += pmic_max77686.o +obj-$(CONFIG_POWER_BD71837) += pmic_bd71837.o obj-$(CONFIG_POWER_PFUZE100) += pmic_pfuze100.o obj-$(CONFIG_POWER_PFUZE3000) += pmic_pfuze3000.o obj-$(CONFIG_POWER_TPS65217) += pmic_tps65217.o diff --git a/drivers/power/pmic/bd71837.c b/drivers/power/pmic/bd71837.c new file mode 100644 index 00000000000..1405e7987fb --- /dev/null +++ b/drivers/power/pmic/bd71837.c @@ -0,0 +1,92 @@ +/* + * Copyright 2018 NXP * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <fdtdec.h> +#include <errno.h> +#include <dm.h> +#include <i2c.h> +#include <power/pmic.h> +#include <power/regulator.h> +#include <power/bd71837.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const struct pmic_child_info pmic_children_info[] = { + /* buck */ + { .prefix = "b", .driver = BD71837_REGULATOR_DRIVER}, + /* ldo */ + { .prefix = "l", .driver = BD71837_REGULATOR_DRIVER}, + { }, +}; + +static int bd71837_reg_count(struct udevice *dev) +{ + return BD71837_REG_NUM; +} + +static int bd71837_write(struct udevice *dev, uint reg, const uint8_t *buff, + int len) +{ + if (dm_i2c_write(dev, reg, buff, len)) { + error("write error to device: %p register: %#x!", dev, reg); + return -EIO; + } + + return 0; +} + +static int bd71837_read(struct udevice *dev, uint reg, uint8_t *buff, int len) +{ + if (dm_i2c_read(dev, reg, buff, len)) { + error("read error from device: %p register: %#x!", dev, reg); + return -EIO; + } + + return 0; +} + +static int bd71837_bind(struct udevice *dev) +{ + int children; + int regulators_node; + const void *blob = gd->fdt_blob; + + regulators_node = fdt_subnode_offset(blob, dev_of_offset(dev), + "regulators"); + if (regulators_node <= 0) { + debug("%s: %s regulators subnode not found!", __func__, + dev->name); + return -ENXIO; + } + + debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); + + children = pmic_bind_children(dev, regulators_node, pmic_children_info); + if (!children) + debug("%s: %s - no child found\n", __func__, dev->name); + + /* Always return success for this device */ + return 0; +} + +static struct dm_pmic_ops bd71837_ops = { + .reg_count = bd71837_reg_count, + .read = bd71837_read, + .write = bd71837_write, +}; + +static const struct udevice_id bd71837_ids[] = { + { .compatible = "rohm,bd71837", .data = 0x4b, }, + { } +}; + +U_BOOT_DRIVER(pmic_bd71837) = { + .name = "bd71837 pmic", + .id = UCLASS_PMIC, + .of_match = bd71837_ids, + .bind = bd71837_bind, + .ops = &bd71837_ops, +}; diff --git a/drivers/power/pmic/pmic_bd71837.c b/drivers/power/pmic/pmic_bd71837.c new file mode 100644 index 00000000000..74195ccae89 --- /dev/null +++ b/drivers/power/pmic/pmic_bd71837.c @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2014 Gateworks Corporation + * Tim Harvey <tharvey@gateworks.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <errno.h> +#include <i2c.h> +#include <power/pmic.h> +#include <power/bd71837.h> + +static const char bd71837_name[] = "BD71837"; +int power_bd71837_init (unsigned char bus) { + struct pmic *p = pmic_alloc(); + + if (!p) { + printf("%s: POWER allocation error!\n", __func__); + return -ENOMEM; + } + + p->name = bd71837_name; + p->interface = PMIC_I2C; + p->number_of_regs = BD71837_REG_NUM; + p->hw.i2c.addr = 0x4b; + p->hw.i2c.tx_num = 1; + p->bus = bus; + + printf("power_bd71837_init\n"); + + return 0; +} diff --git a/include/power/bd71837.h b/include/power/bd71837.h new file mode 100644 index 00000000000..189c3df5f3d --- /dev/null +++ b/include/power/bd71837.h @@ -0,0 +1,62 @@ + +#ifndef BD71837_H_ +#define BD71837_H_ + +#define BD71837_REGULATOR_DRIVER "bd71837_regulator" + +enum { + BD71837_REV = 0x00, + BD71837_SWRESET = 0x01, + BD71837_I2C_DEV = 0x02, + BD71837_PWRCTRL0 = 0x03, + BD71837_PWRCTRL1 = 0x04, + BD71837_BUCK1_CTRL = 0x05, + BD71837_BUCK2_CTRL = 0x06, + BD71837_BUCK3_CTRL = 0x07, + BD71837_BUCK4_CTRL = 0x08, + BD71837_BUCK5_CTRL = 0x09, + BD71837_BUCK6_CTRL = 0x0A, + BD71837_BUCK7_CTRL = 0x0B, + BD71837_BUCK8_CTRL = 0x0C, + BD71837_BUCK1_VOLT_RUN = 0x0D, + BD71837_BUCK1_VOLT_IDLE = 0x0E, + BD71837_BUCK1_VOLT_SUSP = 0x0F, + BD71837_BUCK2_VOLT_RUN = 0x10, + BD71837_BUCK2_VOLT_IDLE = 0x11, + BD71837_BUCK3_VOLT_RUN = 0x12, + BD71837_BUCK4_VOLT_RUN = 0x13, + BD71837_BUCK5_VOLT = 0x14, + BD71837_BUCK6_VOLT = 0x15, + BD71837_BUCK7_VOLT = 0x16, + BD71837_BUCK8_VOLT = 0x17, + BD71837_LDO1_VOLT = 0x18, + BD71837_LDO2_VOLT = 0x19, + BD71837_LDO3_VOLT = 0x1A, + BD71837_LDO4_VOLT = 0x1B, + BD71837_LDO5_VOLT = 0x1C, + BD71837_LDO6_VOLT = 0x1D, + BD71837_LDO7_VOLT = 0x1E, + BD71837_TRANS_COND0 = 0x1F, + BD71837_TRANS_COND1 = 0x20, + BD71837_VRFAULTEN = 0x21, + BD71837_MVRFLTMASK0 = 0x22, + BD71837_MVRFLTMASK1 = 0x23, + BD71837_MVRFLTMASK2 = 0x24, + BD71837_RCVCFG = 0x25, + BD71837_RCVNUM = 0x26, + BD71837_PWRONCONFIG0 = 0x27, + BD71837_PWRONCONFIG1 = 0x28, + BD71837_RESETSRC = 0x29, + BD71837_MIRQ = 0x2A, + BD71837_IRQ = 0x2B, + BD71837_IN_MON = 0x2C, + BD71837_POW_STATE = 0x2D, + BD71837_OUT32K = 0x2E, + BD71837_REGLOCK = 0x2F, + BD71837_MUXSW_EN = 0x30, + BD71837_REG_NUM, +}; + +int power_bd71837_init(unsigned char bus); + +#endif |