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