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