1*33621d24SKeerthy /* 2*33621d24SKeerthy * (C) Copyright 2016 Texas Instruments Incorporated, <www.ti.com> 3*33621d24SKeerthy * Keerthy <j-keerthy@ti.com> 4*33621d24SKeerthy * 5*33621d24SKeerthy * SPDX-License-Identifier: GPL-2.0+ 6*33621d24SKeerthy */ 7*33621d24SKeerthy 8*33621d24SKeerthy #include <common.h> 9*33621d24SKeerthy #include <fdtdec.h> 10*33621d24SKeerthy #include <errno.h> 11*33621d24SKeerthy #include <dm.h> 12*33621d24SKeerthy #include <i2c.h> 13*33621d24SKeerthy #include <power/pmic.h> 14*33621d24SKeerthy #include <power/regulator.h> 15*33621d24SKeerthy #include <power/palmas.h> 16*33621d24SKeerthy #include <dm/device.h> 17*33621d24SKeerthy 18*33621d24SKeerthy DECLARE_GLOBAL_DATA_PTR; 19*33621d24SKeerthy 20*33621d24SKeerthy static const struct pmic_child_info pmic_children_info[] = { 21*33621d24SKeerthy { .prefix = "ldo", .driver = PALMAS_LDO_DRIVER }, 22*33621d24SKeerthy { .prefix = "smps", .driver = PALMAS_SMPS_DRIVER }, 23*33621d24SKeerthy { }, 24*33621d24SKeerthy }; 25*33621d24SKeerthy 26*33621d24SKeerthy static int palmas_write(struct udevice *dev, uint reg, const uint8_t *buff, 27*33621d24SKeerthy int len) 28*33621d24SKeerthy { 29*33621d24SKeerthy if (dm_i2c_write(dev, reg, buff, len)) { 30*33621d24SKeerthy error("write error to device: %p register: %#x!", dev, reg); 31*33621d24SKeerthy return -EIO; 32*33621d24SKeerthy } 33*33621d24SKeerthy 34*33621d24SKeerthy return 0; 35*33621d24SKeerthy } 36*33621d24SKeerthy 37*33621d24SKeerthy static int palmas_read(struct udevice *dev, uint reg, uint8_t *buff, int len) 38*33621d24SKeerthy { 39*33621d24SKeerthy if (dm_i2c_read(dev, reg, buff, len)) { 40*33621d24SKeerthy error("read error from device: %p register: %#x!", dev, reg); 41*33621d24SKeerthy return -EIO; 42*33621d24SKeerthy } 43*33621d24SKeerthy 44*33621d24SKeerthy return 0; 45*33621d24SKeerthy } 46*33621d24SKeerthy 47*33621d24SKeerthy static int palmas_bind(struct udevice *dev) 48*33621d24SKeerthy { 49*33621d24SKeerthy int pmic_node = -1, regulators_node; 50*33621d24SKeerthy const void *blob = gd->fdt_blob; 51*33621d24SKeerthy int children; 52*33621d24SKeerthy int node = dev->of_offset; 53*33621d24SKeerthy int subnode, len; 54*33621d24SKeerthy 55*33621d24SKeerthy fdt_for_each_subnode(blob, subnode, node) { 56*33621d24SKeerthy const char *name; 57*33621d24SKeerthy char *temp; 58*33621d24SKeerthy 59*33621d24SKeerthy name = fdt_get_name(blob, subnode, &len); 60*33621d24SKeerthy temp = strstr(name, "pmic"); 61*33621d24SKeerthy if (temp) { 62*33621d24SKeerthy pmic_node = subnode; 63*33621d24SKeerthy break; 64*33621d24SKeerthy } 65*33621d24SKeerthy } 66*33621d24SKeerthy 67*33621d24SKeerthy if (pmic_node <= 0) { 68*33621d24SKeerthy debug("%s: %s pmic subnode not found!", __func__, dev->name); 69*33621d24SKeerthy return -ENXIO; 70*33621d24SKeerthy } 71*33621d24SKeerthy 72*33621d24SKeerthy regulators_node = fdt_subnode_offset(blob, pmic_node, "regulators"); 73*33621d24SKeerthy 74*33621d24SKeerthy if (regulators_node <= 0) { 75*33621d24SKeerthy debug("%s: %s reg subnode not found!", __func__, dev->name); 76*33621d24SKeerthy return -ENXIO; 77*33621d24SKeerthy } 78*33621d24SKeerthy 79*33621d24SKeerthy children = pmic_bind_children(dev, regulators_node, pmic_children_info); 80*33621d24SKeerthy if (!children) 81*33621d24SKeerthy debug("%s: %s - no child found\n", __func__, dev->name); 82*33621d24SKeerthy 83*33621d24SKeerthy /* Always return success for this device */ 84*33621d24SKeerthy return 0; 85*33621d24SKeerthy } 86*33621d24SKeerthy 87*33621d24SKeerthy static struct dm_pmic_ops palmas_ops = { 88*33621d24SKeerthy .read = palmas_read, 89*33621d24SKeerthy .write = palmas_write, 90*33621d24SKeerthy }; 91*33621d24SKeerthy 92*33621d24SKeerthy static const struct udevice_id palmas_ids[] = { 93*33621d24SKeerthy { .compatible = "ti,tps659038", .data = TPS659038 }, 94*33621d24SKeerthy { .compatible = "ti,tps65917" , .data = TPS65917 }, 95*33621d24SKeerthy { } 96*33621d24SKeerthy }; 97*33621d24SKeerthy 98*33621d24SKeerthy U_BOOT_DRIVER(pmic_palmas) = { 99*33621d24SKeerthy .name = "palmas_pmic", 100*33621d24SKeerthy .id = UCLASS_PMIC, 101*33621d24SKeerthy .of_match = palmas_ids, 102*33621d24SKeerthy .bind = palmas_bind, 103*33621d24SKeerthy .ops = &palmas_ops, 104*33621d24SKeerthy }; 105