1 /* 2 * Copyright (C) 2015 Google, Inc 3 * Written by Simon Glass <sjg@chromium.org> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <dm.h> 10 #include <errno.h> 11 #include <fdtdec.h> 12 #include <libfdt.h> 13 #include <power/rk8xx_pmic.h> 14 #include <power/pmic.h> 15 16 DECLARE_GLOBAL_DATA_PTR; 17 18 static const struct pmic_child_info pmic_children_info[] = { 19 { .prefix = "DCDC_REG", .driver = "rk8xx_buck"}, 20 { .prefix = "LDO_REG", .driver = "rk8xx_ldo"}, 21 { .prefix = "SWITCH_REG", .driver = "rk8xx_switch"}, 22 { }, 23 }; 24 25 static int rk8xx_reg_count(struct udevice *dev) 26 { 27 return RK808_NUM_OF_REGS; 28 } 29 30 static int rk8xx_write(struct udevice *dev, uint reg, const uint8_t *buff, 31 int len) 32 { 33 int ret; 34 35 ret = dm_i2c_write(dev, reg, buff, len); 36 if (ret) { 37 debug("write error to device: %p register: %#x!", dev, reg); 38 return ret; 39 } 40 41 return 0; 42 } 43 44 static int rk8xx_read(struct udevice *dev, uint reg, uint8_t *buff, int len) 45 { 46 int ret; 47 48 ret = dm_i2c_read(dev, reg, buff, len); 49 if (ret) { 50 debug("read error from device: %p register: %#x!", dev, reg); 51 return ret; 52 } 53 54 return 0; 55 } 56 57 #if CONFIG_IS_ENABLED(PMIC_CHILDREN) 58 static int rk8xx_bind(struct udevice *dev) 59 { 60 const void *blob = gd->fdt_blob; 61 int regulators_node; 62 int children; 63 64 regulators_node = fdt_subnode_offset(blob, dev_of_offset(dev), 65 "regulators"); 66 if (regulators_node <= 0) { 67 debug("%s: %s regulators subnode not found!", __func__, 68 dev->name); 69 return -ENXIO; 70 } 71 72 debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); 73 74 children = pmic_bind_children(dev, regulators_node, pmic_children_info); 75 if (!children) 76 debug("%s: %s - no child found\n", __func__, dev->name); 77 78 /* Always return success for this device */ 79 return 0; 80 } 81 #endif 82 83 static int rk8xx_probe(struct udevice *dev) 84 { 85 struct rk8xx_priv *priv = dev_get_priv(dev); 86 uint8_t msb, lsb; 87 88 /* read Chip variant */ 89 rk8xx_read(dev, ID_MSB, &msb, 1); 90 rk8xx_read(dev, ID_LSB, &lsb, 1); 91 92 priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK; 93 94 return 0; 95 } 96 97 static struct dm_pmic_ops rk8xx_ops = { 98 .reg_count = rk8xx_reg_count, 99 .read = rk8xx_read, 100 .write = rk8xx_write, 101 }; 102 103 static const struct udevice_id rk8xx_ids[] = { 104 { .compatible = "rockchip,rk808" }, 105 { .compatible = "rockchip,rk818" }, 106 { } 107 }; 108 109 U_BOOT_DRIVER(pmic_rk8xx) = { 110 .name = "rk8xx pmic", 111 .id = UCLASS_PMIC, 112 .of_match = rk8xx_ids, 113 #if CONFIG_IS_ENABLED(PMIC_CHILDREN) 114 .bind = rk8xx_bind, 115 #endif 116 .probe = rk8xx_probe, 117 .ops = &rk8xx_ops, 118 }; 119