183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
233621d24SKeerthy /*
333621d24SKeerthy * (C) Copyright 2016 Texas Instruments Incorporated, <www.ti.com>
433621d24SKeerthy * Keerthy <j-keerthy@ti.com>
533621d24SKeerthy */
633621d24SKeerthy
733621d24SKeerthy #include <common.h>
833621d24SKeerthy #include <fdtdec.h>
933621d24SKeerthy #include <errno.h>
1033621d24SKeerthy #include <dm.h>
1133621d24SKeerthy #include <i2c.h>
1233621d24SKeerthy #include <power/pmic.h>
1333621d24SKeerthy #include <power/regulator.h>
1433621d24SKeerthy #include <power/palmas.h>
1533621d24SKeerthy #include <dm/device.h>
1633621d24SKeerthy
1733621d24SKeerthy static const struct pmic_child_info pmic_children_info[] = {
1833621d24SKeerthy { .prefix = "ldo", .driver = PALMAS_LDO_DRIVER },
1933621d24SKeerthy { .prefix = "smps", .driver = PALMAS_SMPS_DRIVER },
2033621d24SKeerthy { },
2133621d24SKeerthy };
2233621d24SKeerthy
palmas_write(struct udevice * dev,uint reg,const uint8_t * buff,int len)2333621d24SKeerthy static int palmas_write(struct udevice *dev, uint reg, const uint8_t *buff,
2433621d24SKeerthy int len)
2533621d24SKeerthy {
2633621d24SKeerthy if (dm_i2c_write(dev, reg, buff, len)) {
27*c83c436dSSimon Glass pr_err("write error to device: %p register: %#x!\n", dev, reg);
2833621d24SKeerthy return -EIO;
2933621d24SKeerthy }
3033621d24SKeerthy
3133621d24SKeerthy return 0;
3233621d24SKeerthy }
3333621d24SKeerthy
palmas_read(struct udevice * dev,uint reg,uint8_t * buff,int len)3433621d24SKeerthy static int palmas_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
3533621d24SKeerthy {
3633621d24SKeerthy if (dm_i2c_read(dev, reg, buff, len)) {
37*c83c436dSSimon Glass pr_err("read error from device: %p register: %#x!\n", dev, reg);
3833621d24SKeerthy return -EIO;
3933621d24SKeerthy }
4033621d24SKeerthy
4133621d24SKeerthy return 0;
4233621d24SKeerthy }
4333621d24SKeerthy
palmas_bind(struct udevice * dev)4433621d24SKeerthy static int palmas_bind(struct udevice *dev)
4533621d24SKeerthy {
467a869e6cSSimon Glass ofnode pmic_node = ofnode_null(), regulators_node;
477a869e6cSSimon Glass ofnode subnode;
4833621d24SKeerthy int children;
4933621d24SKeerthy
507a869e6cSSimon Glass dev_for_each_subnode(subnode, dev) {
5133621d24SKeerthy const char *name;
5233621d24SKeerthy char *temp;
5333621d24SKeerthy
547a869e6cSSimon Glass name = ofnode_get_name(subnode);
5533621d24SKeerthy temp = strstr(name, "pmic");
5633621d24SKeerthy if (temp) {
5733621d24SKeerthy pmic_node = subnode;
5833621d24SKeerthy break;
5933621d24SKeerthy }
6033621d24SKeerthy }
6133621d24SKeerthy
627a869e6cSSimon Glass if (!ofnode_valid(pmic_node)) {
63*c83c436dSSimon Glass debug("%s: %s pmic subnode not found!\n", __func__, dev->name);
6433621d24SKeerthy return -ENXIO;
6533621d24SKeerthy }
6633621d24SKeerthy
677a869e6cSSimon Glass regulators_node = ofnode_find_subnode(pmic_node, "regulators");
6833621d24SKeerthy
697a869e6cSSimon Glass if (!ofnode_valid(regulators_node)) {
70*c83c436dSSimon Glass debug("%s: %s reg subnode not found!\n", __func__, dev->name);
7133621d24SKeerthy return -ENXIO;
7233621d24SKeerthy }
7333621d24SKeerthy
7433621d24SKeerthy children = pmic_bind_children(dev, regulators_node, pmic_children_info);
7533621d24SKeerthy if (!children)
7633621d24SKeerthy debug("%s: %s - no child found\n", __func__, dev->name);
7733621d24SKeerthy
7833621d24SKeerthy /* Always return success for this device */
7933621d24SKeerthy return 0;
8033621d24SKeerthy }
8133621d24SKeerthy
8233621d24SKeerthy static struct dm_pmic_ops palmas_ops = {
8333621d24SKeerthy .read = palmas_read,
8433621d24SKeerthy .write = palmas_write,
8533621d24SKeerthy };
8633621d24SKeerthy
8733621d24SKeerthy static const struct udevice_id palmas_ids[] = {
8833621d24SKeerthy { .compatible = "ti,tps659038", .data = TPS659038 },
8933621d24SKeerthy { .compatible = "ti,tps65917" , .data = TPS65917 },
9033621d24SKeerthy { }
9133621d24SKeerthy };
9233621d24SKeerthy
9333621d24SKeerthy U_BOOT_DRIVER(pmic_palmas) = {
9433621d24SKeerthy .name = "palmas_pmic",
9533621d24SKeerthy .id = UCLASS_PMIC,
9633621d24SKeerthy .of_match = palmas_ids,
9733621d24SKeerthy .bind = palmas_bind,
9833621d24SKeerthy .ops = &palmas_ops,
9933621d24SKeerthy };
100