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 const struct pmic_child_info power_key_info[] = { 26 { .prefix = "pwrkey", .driver = "rk8xx_pwrkey"}, 27 { }, 28 }; 29 30 static const struct pmic_child_info fuel_gauge_info[] = { 31 { .prefix = "battery", .driver = "rk818_fg"}, 32 { .prefix = "battery", .driver = "rk816_fg"}, 33 { }, 34 }; 35 36 static int rk8xx_reg_count(struct udevice *dev) 37 { 38 return RK808_NUM_OF_REGS; 39 } 40 41 static int rk8xx_write(struct udevice *dev, uint reg, const uint8_t *buff, 42 int len) 43 { 44 int ret; 45 46 ret = dm_i2c_write(dev, reg, buff, len); 47 if (ret) { 48 debug("write error to device: %p register: %#x!", dev, reg); 49 return ret; 50 } 51 52 return 0; 53 } 54 55 static int rk8xx_read(struct udevice *dev, uint reg, uint8_t *buff, int len) 56 { 57 int ret; 58 59 ret = dm_i2c_read(dev, reg, buff, len); 60 if (ret) { 61 debug("read error from device: %p register: %#x!", dev, reg); 62 return ret; 63 } 64 65 return 0; 66 } 67 68 static int rk8xx_shutdown(struct udevice *dev) 69 { 70 struct rk8xx_priv *priv = dev_get_priv(dev); 71 u8 val, dev_off; 72 int ret = 0; 73 74 switch (priv->variant) { 75 case RK808_ID: 76 dev_off = BIT(3); 77 break; 78 case RK805_ID: 79 case RK816_ID: 80 case RK818_ID: 81 dev_off = BIT(0); 82 break; 83 default: 84 printf("Unknown PMIC: RK%x\n", priv->variant); 85 return -EINVAL; 86 } 87 88 ret = dm_i2c_read(dev, REG_DEVCTRL, &val, 1); 89 if (ret) { 90 printf("read error from device: %p register: %#x!", 91 dev, REG_DEVCTRL); 92 return ret; 93 } 94 95 val |= dev_off; 96 ret = dm_i2c_write(dev, REG_DEVCTRL, &val, 1); 97 if (ret) { 98 printf("write error to device: %p register: %#x!", 99 dev, REG_DEVCTRL); 100 return ret; 101 } 102 103 return 0; 104 } 105 106 #if CONFIG_IS_ENABLED(PMIC_CHILDREN) 107 static int rk8xx_bind(struct udevice *dev) 108 { 109 ofnode regulators_node; 110 int children; 111 112 regulators_node = dev_read_subnode(dev, "regulators"); 113 if (!ofnode_valid(regulators_node)) { 114 debug("%s: %s regulators subnode not found!", __func__, 115 dev->name); 116 return -ENXIO; 117 } 118 119 debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); 120 121 children = pmic_bind_children(dev, regulators_node, pmic_children_info); 122 if (!children) 123 debug("%s: %s - no child found\n", __func__, dev->name); 124 125 children = pmic_bind_children(dev, dev->node, power_key_info); 126 if (!children) 127 debug("%s: %s - no child found\n", __func__, dev->name); 128 129 children = pmic_bind_children(dev, dev->node, fuel_gauge_info); 130 if (!children) 131 debug("%s: %s - no child found\n", __func__, dev->name); 132 133 /* Always return success for this device */ 134 return 0; 135 } 136 #endif 137 138 static int rk8xx_probe(struct udevice *dev) 139 { 140 struct rk8xx_priv *priv = dev_get_priv(dev); 141 uint8_t msb, lsb; 142 143 /* read Chip variant */ 144 rk8xx_read(dev, ID_MSB, &msb, 1); 145 rk8xx_read(dev, ID_LSB, &lsb, 1); 146 147 priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK; 148 149 return 0; 150 } 151 152 static struct dm_pmic_ops rk8xx_ops = { 153 .reg_count = rk8xx_reg_count, 154 .read = rk8xx_read, 155 .write = rk8xx_write, 156 .shutdown = rk8xx_shutdown, 157 }; 158 159 static const struct udevice_id rk8xx_ids[] = { 160 { .compatible = "rockchip,rk805" }, 161 { .compatible = "rockchip,rk808" }, 162 { .compatible = "rockchip,rk816" }, 163 { .compatible = "rockchip,rk818" }, 164 { } 165 }; 166 167 U_BOOT_DRIVER(pmic_rk8xx) = { 168 .name = "rk8xx pmic", 169 .id = UCLASS_PMIC, 170 .of_match = rk8xx_ids, 171 #if CONFIG_IS_ENABLED(PMIC_CHILDREN) 172 .bind = rk8xx_bind, 173 #endif 174 .priv_auto_alloc_size = sizeof(struct rk8xx_priv), 175 .probe = rk8xx_probe, 176 .ops = &rk8xx_ops, 177 }; 178