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