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 struct reg_data rk817_init_reg[] = { 17 /* enable the under-voltage protection, 18 * the under-voltage protection will shutdown the LDO3 and reset the PMIC 19 */ 20 { RK817_BUCK4_CMIN, 0x60, 0x60}, 21 /* 22 * Only when system suspend while U-Boot charge needs this config support 23 */ 24 #ifdef CONFIG_DM_CHARGE_DISPLAY 25 /* Set pmic_sleep as sleep function */ 26 { RK817_PMIC_SYS_CFG3, 0x08, 0x18 }, 27 /* Set pmic_int active low */ 28 { RK817_GPIO_INT_CFG, 0x00, 0x02 }, 29 #endif 30 }; 31 32 static const struct pmic_child_info pmic_children_info[] = { 33 { .prefix = "DCDC", .driver = "rk8xx_buck"}, 34 { .prefix = "LDO", .driver = "rk8xx_ldo"}, 35 { .prefix = "SWITCH", .driver = "rk8xx_switch"}, 36 { }, 37 }; 38 39 static const struct pmic_child_info power_key_info[] = { 40 { .prefix = "pwrkey", .driver = "rk8xx_pwrkey"}, 41 { }, 42 }; 43 44 static const struct pmic_child_info rtc_info[] = { 45 { .prefix = "rtc", .driver = "rk8xx_rtc"}, 46 { }, 47 }; 48 49 static const struct pmic_child_info fuel_gauge_info[] = { 50 { .prefix = "battery", .driver = "rk818_fg"}, 51 { .prefix = "battery", .driver = "rk817_fg"}, 52 { .prefix = "battery", .driver = "rk816_fg"}, 53 { }, 54 }; 55 56 static const struct pmic_child_info rk817_codec_info[] = { 57 { .prefix = "codec", .driver = "rk817_codec"}, 58 { }, 59 }; 60 61 static int rk8xx_reg_count(struct udevice *dev) 62 { 63 return RK808_NUM_OF_REGS; 64 } 65 66 static int rk8xx_write(struct udevice *dev, uint reg, const uint8_t *buff, 67 int len) 68 { 69 int ret; 70 71 ret = dm_i2c_write(dev, reg, buff, len); 72 if (ret) { 73 printf("%s: write reg 0x%02x failed, ret=%d\n", __func__, reg, ret); 74 return ret; 75 } 76 77 return 0; 78 } 79 80 static int rk8xx_read(struct udevice *dev, uint reg, uint8_t *buff, int len) 81 { 82 int ret; 83 84 ret = dm_i2c_read(dev, reg, buff, len); 85 if (ret) { 86 printf("%s: read reg 0x%02x failed, ret=%d\n", __func__, reg, ret); 87 return ret; 88 } 89 90 return 0; 91 } 92 93 static int rk8xx_shutdown(struct udevice *dev) 94 { 95 struct rk8xx_priv *priv = dev_get_priv(dev); 96 u8 val, dev_off, devctrl_reg; 97 int ret = 0; 98 99 switch (priv->variant) { 100 case RK808_ID: 101 devctrl_reg = REG_DEVCTRL; 102 dev_off = BIT(3); 103 break; 104 case RK805_ID: 105 case RK816_ID: 106 case RK818_ID: 107 devctrl_reg = REG_DEVCTRL; 108 dev_off = BIT(0); 109 break; 110 case RK809_ID: 111 case RK817_ID: 112 devctrl_reg = RK817_REG_SYS_CFG3; 113 dev_off = BIT(0); 114 break; 115 default: 116 printf("Unknown PMIC: RK%x\n", priv->variant); 117 return -EINVAL; 118 } 119 120 ret = dm_i2c_read(dev, devctrl_reg, &val, 1); 121 if (ret) { 122 printf("%s: read reg 0x%02x failed, ret=%d\n", __func__, devctrl_reg, ret); 123 return ret; 124 } 125 126 val |= dev_off; 127 ret = dm_i2c_write(dev, devctrl_reg, &val, 1); 128 if (ret) { 129 printf("%s: write reg 0x%02x failed, ret=%d\n", __func__, devctrl_reg, ret); 130 return ret; 131 } 132 133 return 0; 134 } 135 136 #if CONFIG_IS_ENABLED(PMIC_CHILDREN) 137 static int rk8xx_bind(struct udevice *dev) 138 { 139 ofnode regulators_node; 140 int children; 141 142 regulators_node = dev_read_subnode(dev, "regulators"); 143 if (!ofnode_valid(regulators_node)) { 144 debug("%s: %s regulators subnode not found!\n", __func__, 145 dev->name); 146 return -ENXIO; 147 } 148 149 debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); 150 151 children = pmic_bind_children(dev, regulators_node, pmic_children_info); 152 if (!children) 153 debug("%s: %s - no child found\n", __func__, dev->name); 154 155 children = pmic_bind_children(dev, dev->node, power_key_info); 156 if (!children) 157 debug("%s: %s - no child found\n", __func__, dev->name); 158 159 children = pmic_bind_children(dev, dev->node, rtc_info); 160 if (!children) 161 debug("%s: %s - no child found\n", __func__, dev->name); 162 163 children = pmic_bind_children(dev, dev->node, fuel_gauge_info); 164 if (!children) 165 debug("%s: %s - no child found\n", __func__, dev->name); 166 167 children = pmic_bind_children(dev, dev->node, rk817_codec_info); 168 if (!children) 169 debug("%s: %s - no child found\n", __func__, dev->name); 170 171 /* Always return success for this device */ 172 return 0; 173 } 174 #endif 175 176 static int rk8xx_probe(struct udevice *dev) 177 { 178 struct rk8xx_priv *priv = dev_get_priv(dev); 179 struct reg_data *init_data = NULL; 180 int init_data_num = 0; 181 int ret = 0, i, show_variant; 182 uint8_t msb, lsb, id_msb, id_lsb; 183 uint8_t on_source = 0, off_source = 0; 184 uint8_t power_en0, power_en1, power_en2, power_en3; 185 uint8_t value; 186 187 /* read Chip variant */ 188 if (device_is_compatible(dev, "rockchip,rk817") || 189 device_is_compatible(dev, "rockchip,rk809")) { 190 id_msb = RK817_ID_MSB; 191 id_lsb = RK817_ID_LSB; 192 } else { 193 id_msb = ID_MSB; 194 id_lsb = ID_LSB; 195 } 196 197 ret = rk8xx_read(dev, id_msb, &msb, 1); 198 if (ret) 199 return ret; 200 ret = rk8xx_read(dev, id_lsb, &lsb, 1); 201 if (ret) 202 return ret; 203 204 priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK; 205 show_variant = priv->variant; 206 switch (priv->variant) { 207 case RK808_ID: 208 show_variant = 0x808; /* RK808 hardware ID is 0 */ 209 break; 210 case RK805_ID: 211 case RK816_ID: 212 case RK818_ID: 213 on_source = RK8XX_ON_SOURCE; 214 off_source = RK8XX_OFF_SOURCE; 215 break; 216 case RK809_ID: 217 case RK817_ID: 218 on_source = RK817_ON_SOURCE; 219 off_source = RK817_OFF_SOURCE; 220 init_data = rk817_init_reg; 221 init_data_num = ARRAY_SIZE(rk817_init_reg); 222 power_en0 = pmic_reg_read(dev, RK817_POWER_EN0); 223 power_en1 = pmic_reg_read(dev, RK817_POWER_EN1); 224 power_en2 = pmic_reg_read(dev, RK817_POWER_EN2); 225 power_en3 = pmic_reg_read(dev, RK817_POWER_EN3); 226 227 value = (power_en0 & 0x0f) | ((power_en1 & 0x0f) << 4); 228 pmic_reg_write(dev, RK817_POWER_EN_SAVE0, value); 229 value = (power_en2 & 0x0f) | ((power_en3 & 0x0f) << 4); 230 pmic_reg_write(dev, RK817_POWER_EN_SAVE1, value); 231 break; 232 default: 233 printf("Unknown PMIC: RK%x!!\n", priv->variant); 234 return -EINVAL; 235 } 236 237 for (i = 0; i < init_data_num; i++) { 238 ret = pmic_clrsetbits(dev, 239 init_data[i].reg, 240 init_data[i].mask, 241 init_data[i].val); 242 if (ret < 0) { 243 printf("%s: i2c set reg 0x%x failed, ret=%d\n", 244 __func__, init_data[i].reg, ret); 245 } 246 247 debug("%s: reg[0x%x] = 0x%x\n", __func__, init_data[i].reg, 248 pmic_reg_read(dev, init_data[i].reg)); 249 } 250 251 printf("PMIC: RK%x ", show_variant); 252 253 if (on_source && off_source) 254 printf("(on=0x%02x, off=0x%02x)", 255 pmic_reg_read(dev, on_source), 256 pmic_reg_read(dev, off_source)); 257 printf("\n"); 258 259 return 0; 260 } 261 262 static struct dm_pmic_ops rk8xx_ops = { 263 .reg_count = rk8xx_reg_count, 264 .read = rk8xx_read, 265 .write = rk8xx_write, 266 .shutdown = rk8xx_shutdown, 267 }; 268 269 static const struct udevice_id rk8xx_ids[] = { 270 { .compatible = "rockchip,rk805" }, 271 { .compatible = "rockchip,rk808" }, 272 { .compatible = "rockchip,rk809" }, 273 { .compatible = "rockchip,rk816" }, 274 { .compatible = "rockchip,rk817" }, 275 { .compatible = "rockchip,rk818" }, 276 { } 277 }; 278 279 U_BOOT_DRIVER(pmic_rk8xx) = { 280 .name = "rk8xx pmic", 281 .id = UCLASS_PMIC, 282 .of_match = rk8xx_ids, 283 #if CONFIG_IS_ENABLED(PMIC_CHILDREN) 284 .bind = rk8xx_bind, 285 #endif 286 .priv_auto_alloc_size = sizeof(struct rk8xx_priv), 287 .probe = rk8xx_probe, 288 .ops = &rk8xx_ops, 289 }; 290