1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2015 Google, Inc 4 * Written by Simon Glass <sjg@chromium.org> 5 * 6 * Based on Rockchip's drivers/power/pmic/pmic_rk808.c: 7 * Copyright (C) 2012 rockchips 8 * zyw <zyw@rock-chips.com> 9 */ 10 11 #include <common.h> 12 #include <dm.h> 13 #include <errno.h> 14 #include <power/rk8xx_pmic.h> 15 #include <power/pmic.h> 16 #include <power/regulator.h> 17 18 #ifndef CONFIG_SPL_BUILD 19 #define ENABLE_DRIVER 20 #endif 21 22 /* Field Definitions */ 23 #define RK808_BUCK_VSEL_MASK 0x3f 24 #define RK808_BUCK4_VSEL_MASK 0xf 25 #define RK808_LDO_VSEL_MASK 0x1f 26 27 #define RK818_BUCK_VSEL_MASK 0x3f 28 #define RK818_BUCK4_VSEL_MASK 0x1f 29 #define RK818_LDO_VSEL_MASK 0x1f 30 #define RK818_LDO3_ON_VSEL_MASK 0xf 31 #define RK818_BOOST_ON_VSEL_MASK 0xe0 32 #define RK818_USB_ILIM_SEL_MASK 0x0f 33 #define RK818_USB_CHG_SD_VSEL_MASK 0x70 34 35 36 struct rk8xx_reg_info { 37 uint min_uv; 38 uint step_uv; 39 s8 vsel_reg; 40 u8 vsel_mask; 41 }; 42 43 static const struct rk8xx_reg_info rk808_buck[] = { 44 { 712500, 12500, REG_BUCK1_ON_VSEL, RK808_BUCK_VSEL_MASK, }, 45 { 712500, 12500, REG_BUCK2_ON_VSEL, RK808_BUCK_VSEL_MASK, }, 46 { 712500, 12500, -1, RK808_BUCK_VSEL_MASK, }, 47 { 1800000, 100000, REG_BUCK4_ON_VSEL, RK808_BUCK4_VSEL_MASK, }, 48 }; 49 50 static const struct rk8xx_reg_info rk818_buck[] = { 51 { 712500, 12500, REG_BUCK1_ON_VSEL, RK818_BUCK_VSEL_MASK, }, 52 { 712500, 12500, REG_BUCK2_ON_VSEL, RK818_BUCK_VSEL_MASK, }, 53 { 712500, 12500, -1, RK818_BUCK_VSEL_MASK, }, 54 { 1800000, 100000, REG_BUCK4_ON_VSEL, RK818_BUCK4_VSEL_MASK, }, 55 }; 56 57 #ifdef ENABLE_DRIVER 58 static const struct rk8xx_reg_info rk808_ldo[] = { 59 { 1800000, 100000, REG_LDO1_ON_VSEL, RK808_LDO_VSEL_MASK, }, 60 { 1800000, 100000, REG_LDO2_ON_VSEL, RK808_LDO_VSEL_MASK, }, 61 { 800000, 100000, REG_LDO3_ON_VSEL, RK808_BUCK4_VSEL_MASK, }, 62 { 1800000, 100000, REG_LDO4_ON_VSEL, RK808_LDO_VSEL_MASK, }, 63 { 1800000, 100000, REG_LDO5_ON_VSEL, RK808_LDO_VSEL_MASK, }, 64 { 800000, 100000, REG_LDO6_ON_VSEL, RK808_LDO_VSEL_MASK, }, 65 { 800000, 100000, REG_LDO7_ON_VSEL, RK808_LDO_VSEL_MASK, }, 66 { 1800000, 100000, REG_LDO8_ON_VSEL, RK808_LDO_VSEL_MASK, }, 67 }; 68 69 static const struct rk8xx_reg_info rk818_ldo[] = { 70 { 1800000, 100000, REG_LDO1_ON_VSEL, RK818_LDO_VSEL_MASK, }, 71 { 1800000, 100000, REG_LDO2_ON_VSEL, RK818_LDO_VSEL_MASK, }, 72 { 800000, 100000, REG_LDO3_ON_VSEL, RK818_LDO3_ON_VSEL_MASK, }, 73 { 1800000, 100000, REG_LDO4_ON_VSEL, RK818_LDO_VSEL_MASK, }, 74 { 1800000, 100000, REG_LDO5_ON_VSEL, RK818_LDO_VSEL_MASK, }, 75 { 800000, 100000, REG_LDO6_ON_VSEL, RK818_LDO_VSEL_MASK, }, 76 { 800000, 100000, REG_LDO7_ON_VSEL, RK818_LDO_VSEL_MASK, }, 77 { 1800000, 100000, REG_LDO8_ON_VSEL, RK818_LDO_VSEL_MASK, }, 78 }; 79 #endif 80 81 static const u16 rk818_chrg_cur_input_array[] = { 82 450, 800, 850, 1000, 1250, 1500, 1750, 2000, 2250, 2500, 2750, 3000 83 }; 84 85 static const uint rk818_chrg_shutdown_vsel_array[] = { 86 2780000, 2850000, 2920000, 2990000, 3060000, 3130000, 3190000, 3260000 87 }; 88 89 static const struct rk8xx_reg_info *get_buck_reg(struct udevice *pmic, 90 int num) 91 { 92 struct rk8xx_priv *priv = dev_get_priv(pmic); 93 switch (priv->variant) { 94 case RK818_ID: 95 return &rk818_buck[num]; 96 default: 97 return &rk808_buck[num]; 98 } 99 } 100 101 static int _buck_set_value(struct udevice *pmic, int buck, int uvolt) 102 { 103 const struct rk8xx_reg_info *info = get_buck_reg(pmic, buck - 1); 104 int mask = info->vsel_mask; 105 int val; 106 107 if (info->vsel_reg == -1) 108 return -ENOSYS; 109 val = (uvolt - info->min_uv) / info->step_uv; 110 debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_reg, mask, 111 val); 112 113 return pmic_clrsetbits(pmic, info->vsel_reg, mask, val); 114 } 115 116 static int _buck_set_enable(struct udevice *pmic, int buck, bool enable) 117 { 118 uint mask; 119 int ret; 120 121 buck--; 122 mask = 1 << buck; 123 if (enable) { 124 ret = pmic_clrsetbits(pmic, REG_DCDC_ILMAX, 0, 3 << (buck * 2)); 125 if (ret) 126 return ret; 127 ret = pmic_clrsetbits(pmic, REG_DCDC_UV_ACT, 1 << buck, 0); 128 if (ret) 129 return ret; 130 } 131 132 return pmic_clrsetbits(pmic, REG_DCDC_EN, mask, enable ? mask : 0); 133 } 134 135 #ifdef ENABLE_DRIVER 136 static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic, 137 int num) 138 { 139 struct rk8xx_priv *priv = dev_get_priv(pmic); 140 switch (priv->variant) { 141 case RK818_ID: 142 return &rk818_ldo[num]; 143 default: 144 return &rk808_ldo[num]; 145 } 146 } 147 148 static int buck_get_value(struct udevice *dev) 149 { 150 int buck = dev->driver_data - 1; 151 const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck); 152 int mask = info->vsel_mask; 153 int ret, val; 154 155 if (info->vsel_reg == -1) 156 return -ENOSYS; 157 ret = pmic_reg_read(dev->parent, info->vsel_reg); 158 if (ret < 0) 159 return ret; 160 val = ret & mask; 161 162 return info->min_uv + val * info->step_uv; 163 } 164 165 static int buck_set_value(struct udevice *dev, int uvolt) 166 { 167 int buck = dev->driver_data; 168 169 return _buck_set_value(dev->parent, buck, uvolt); 170 } 171 172 static int buck_set_enable(struct udevice *dev, bool enable) 173 { 174 int buck = dev->driver_data; 175 176 return _buck_set_enable(dev->parent, buck, enable); 177 } 178 179 static int buck_get_enable(struct udevice *dev) 180 { 181 int buck = dev->driver_data - 1; 182 int ret; 183 uint mask; 184 185 mask = 1 << buck; 186 187 ret = pmic_reg_read(dev->parent, REG_DCDC_EN); 188 if (ret < 0) 189 return ret; 190 191 return ret & mask ? true : false; 192 } 193 194 static int ldo_get_value(struct udevice *dev) 195 { 196 int ldo = dev->driver_data - 1; 197 const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo); 198 int mask = info->vsel_mask; 199 int ret, val; 200 201 if (info->vsel_reg == -1) 202 return -ENOSYS; 203 ret = pmic_reg_read(dev->parent, info->vsel_reg); 204 if (ret < 0) 205 return ret; 206 val = ret & mask; 207 208 return info->min_uv + val * info->step_uv; 209 } 210 211 static int ldo_set_value(struct udevice *dev, int uvolt) 212 { 213 int ldo = dev->driver_data - 1; 214 const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo); 215 int mask = info->vsel_mask; 216 int val; 217 218 if (info->vsel_reg == -1) 219 return -ENOSYS; 220 val = (uvolt - info->min_uv) / info->step_uv; 221 debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_reg, mask, 222 val); 223 224 return pmic_clrsetbits(dev->parent, info->vsel_reg, mask, val); 225 } 226 227 static int ldo_set_enable(struct udevice *dev, bool enable) 228 { 229 int ldo = dev->driver_data - 1; 230 uint mask; 231 232 mask = 1 << ldo; 233 234 return pmic_clrsetbits(dev->parent, REG_LDO_EN, mask, 235 enable ? mask : 0); 236 } 237 238 static int ldo_get_enable(struct udevice *dev) 239 { 240 int ldo = dev->driver_data - 1; 241 int ret; 242 uint mask; 243 244 mask = 1 << ldo; 245 246 ret = pmic_reg_read(dev->parent, REG_LDO_EN); 247 if (ret < 0) 248 return ret; 249 250 return ret & mask ? true : false; 251 } 252 253 static int switch_set_enable(struct udevice *dev, bool enable) 254 { 255 int sw = dev->driver_data - 1; 256 uint mask; 257 258 mask = 1 << (sw + 5); 259 260 return pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask, 261 enable ? mask : 0); 262 } 263 264 static int switch_get_enable(struct udevice *dev) 265 { 266 int sw = dev->driver_data - 1; 267 int ret; 268 uint mask; 269 270 mask = 1 << (sw + 5); 271 272 ret = pmic_reg_read(dev->parent, REG_DCDC_EN); 273 if (ret < 0) 274 return ret; 275 276 return ret & mask ? true : false; 277 } 278 279 static int rk8xx_buck_probe(struct udevice *dev) 280 { 281 struct dm_regulator_uclass_platdata *uc_pdata; 282 283 uc_pdata = dev_get_uclass_platdata(dev); 284 285 uc_pdata->type = REGULATOR_TYPE_BUCK; 286 uc_pdata->mode_count = 0; 287 288 return 0; 289 } 290 291 static int rk8xx_ldo_probe(struct udevice *dev) 292 { 293 struct dm_regulator_uclass_platdata *uc_pdata; 294 295 uc_pdata = dev_get_uclass_platdata(dev); 296 297 uc_pdata->type = REGULATOR_TYPE_LDO; 298 uc_pdata->mode_count = 0; 299 300 return 0; 301 } 302 303 static int rk8xx_switch_probe(struct udevice *dev) 304 { 305 struct dm_regulator_uclass_platdata *uc_pdata; 306 307 uc_pdata = dev_get_uclass_platdata(dev); 308 309 uc_pdata->type = REGULATOR_TYPE_FIXED; 310 uc_pdata->mode_count = 0; 311 312 return 0; 313 } 314 315 static const struct dm_regulator_ops rk8xx_buck_ops = { 316 .get_value = buck_get_value, 317 .set_value = buck_set_value, 318 .get_enable = buck_get_enable, 319 .set_enable = buck_set_enable, 320 }; 321 322 static const struct dm_regulator_ops rk8xx_ldo_ops = { 323 .get_value = ldo_get_value, 324 .set_value = ldo_set_value, 325 .get_enable = ldo_get_enable, 326 .set_enable = ldo_set_enable, 327 }; 328 329 static const struct dm_regulator_ops rk8xx_switch_ops = { 330 .get_enable = switch_get_enable, 331 .set_enable = switch_set_enable, 332 }; 333 334 U_BOOT_DRIVER(rk8xx_buck) = { 335 .name = "rk8xx_buck", 336 .id = UCLASS_REGULATOR, 337 .ops = &rk8xx_buck_ops, 338 .probe = rk8xx_buck_probe, 339 }; 340 341 U_BOOT_DRIVER(rk8xx_ldo) = { 342 .name = "rk8xx_ldo", 343 .id = UCLASS_REGULATOR, 344 .ops = &rk8xx_ldo_ops, 345 .probe = rk8xx_ldo_probe, 346 }; 347 348 U_BOOT_DRIVER(rk8xx_switch) = { 349 .name = "rk8xx_switch", 350 .id = UCLASS_REGULATOR, 351 .ops = &rk8xx_switch_ops, 352 .probe = rk8xx_switch_probe, 353 }; 354 #endif 355 356 int rk8xx_spl_configure_buck(struct udevice *pmic, int buck, int uvolt) 357 { 358 int ret; 359 360 ret = _buck_set_value(pmic, buck, uvolt); 361 if (ret) 362 return ret; 363 364 return _buck_set_enable(pmic, buck, true); 365 } 366 367 int rk818_spl_configure_usb_input_current(struct udevice *pmic, int current_ma) 368 { 369 uint i; 370 371 for (i = 0; i < ARRAY_SIZE(rk818_chrg_cur_input_array); i++) 372 if (current_ma <= rk818_chrg_cur_input_array[i]) 373 break; 374 375 return pmic_clrsetbits(pmic, REG_USB_CTRL, RK818_USB_ILIM_SEL_MASK, i); 376 } 377 378 int rk818_spl_configure_usb_chrg_shutdown(struct udevice *pmic, int uvolt) 379 { 380 uint i; 381 382 for (i = 0; i < ARRAY_SIZE(rk818_chrg_shutdown_vsel_array); i++) 383 if (uvolt <= rk818_chrg_shutdown_vsel_array[i]) 384 break; 385 386 return pmic_clrsetbits(pmic, REG_USB_CTRL, RK818_USB_CHG_SD_VSEL_MASK, 387 i); 388 } 389