1 /* 2 * (C) Copyright 2016 3 * Texas Instruments Incorporated, <www.ti.com> 4 * 5 * Keerthy <j-keerthy@ti.com> 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include <common.h> 11 #include <fdtdec.h> 12 #include <errno.h> 13 #include <dm.h> 14 #include <i2c.h> 15 #include <power/pmic.h> 16 #include <power/regulator.h> 17 #include <power/lp873x.h> 18 19 DECLARE_GLOBAL_DATA_PTR; 20 21 static const char lp873x_buck_ctrl[LP873X_BUCK_NUM] = {0x2, 0x4}; 22 static const char lp873x_buck_volt[LP873X_BUCK_NUM] = {0x6, 0x7}; 23 static const char lp873x_ldo_ctrl[LP873X_LDO_NUM] = {0x8, 0x9}; 24 static const char lp873x_ldo_volt[LP873X_LDO_NUM] = {0xA, 0xB}; 25 26 static int lp873x_buck_enable(struct udevice *dev, int op, bool *enable) 27 { 28 int ret; 29 unsigned int adr; 30 struct dm_regulator_uclass_platdata *uc_pdata; 31 32 uc_pdata = dev_get_uclass_platdata(dev); 33 adr = uc_pdata->ctrl_reg; 34 35 ret = pmic_reg_read(dev->parent, adr); 36 if (ret < 0) 37 return ret; 38 39 if (op == PMIC_OP_GET) { 40 ret &= LP873X_BUCK_MODE_MASK; 41 42 if (ret) 43 *enable = true; 44 else 45 *enable = false; 46 47 return 0; 48 } else if (op == PMIC_OP_SET) { 49 if (*enable) 50 ret |= LP873X_BUCK_MODE_MASK; 51 else 52 ret &= ~(LP873X_BUCK_MODE_MASK); 53 ret = pmic_reg_write(dev->parent, adr, ret); 54 if (ret) 55 return ret; 56 } 57 58 return 0; 59 } 60 61 static int lp873x_buck_volt2hex(int uV) 62 { 63 if (uV > LP873X_BUCK_VOLT_MAX) 64 return -EINVAL; 65 else if (uV > 1400000) 66 return (uV - 1420000) / 20000 + 0x9E; 67 else if (uV > 730000) 68 return (uV - 735000) / 5000 + 0x18; 69 else if (uV >= 700000) 70 return (uV - 700000) / 10000 + 0x1; 71 else 72 return -EINVAL; 73 } 74 75 static int lp873x_buck_hex2volt(int hex) 76 { 77 if (hex > LP873X_BUCK_VOLT_MAX_HEX) 78 return -EINVAL; 79 else if (hex > 0x9D) 80 return 1400000 + (hex - 0x9D) * 20000; 81 else if (hex > 0x17) 82 return 730000 + (hex - 0x17) * 5000; 83 else if (hex >= 0x14) 84 return 700000 + (hex - 0x14) * 10000; 85 else 86 return -EINVAL; 87 } 88 89 static int lp873x_buck_val(struct udevice *dev, int op, int *uV) 90 { 91 unsigned int hex, adr; 92 int ret; 93 struct dm_regulator_uclass_platdata *uc_pdata; 94 95 uc_pdata = dev_get_uclass_platdata(dev); 96 97 if (op == PMIC_OP_GET) 98 *uV = 0; 99 100 adr = uc_pdata->volt_reg; 101 102 ret = pmic_reg_read(dev->parent, adr); 103 if (ret < 0) 104 return ret; 105 106 if (op == PMIC_OP_GET) { 107 ret &= LP873X_BUCK_VOLT_MASK; 108 ret = lp873x_buck_hex2volt(ret); 109 if (ret < 0) 110 return ret; 111 *uV = ret; 112 113 return 0; 114 } 115 116 hex = lp873x_buck_volt2hex(*uV); 117 if (hex < 0) 118 return hex; 119 120 ret &= 0x0; 121 ret |= hex; 122 123 ret = pmic_reg_write(dev->parent, adr, ret); 124 125 return ret; 126 } 127 128 static int lp873x_ldo_enable(struct udevice *dev, int op, bool *enable) 129 { 130 int ret; 131 unsigned int adr; 132 struct dm_regulator_uclass_platdata *uc_pdata; 133 134 uc_pdata = dev_get_uclass_platdata(dev); 135 adr = uc_pdata->ctrl_reg; 136 137 ret = pmic_reg_read(dev->parent, adr); 138 if (ret < 0) 139 return ret; 140 141 if (op == PMIC_OP_GET) { 142 ret &= LP873X_LDO_MODE_MASK; 143 144 if (ret) 145 *enable = true; 146 else 147 *enable = false; 148 149 return 0; 150 } else if (op == PMIC_OP_SET) { 151 if (*enable) 152 ret |= LP873X_LDO_MODE_MASK; 153 else 154 ret &= ~(LP873X_LDO_MODE_MASK); 155 156 ret = pmic_reg_write(dev->parent, adr, ret); 157 if (ret) 158 return ret; 159 } 160 161 return 0; 162 } 163 164 static int lp873x_ldo_volt2hex(int uV) 165 { 166 if (uV > LP873X_LDO_VOLT_MAX) 167 return -EINVAL; 168 169 return (uV - 800000) / 100000; 170 } 171 172 static int lp873x_ldo_hex2volt(int hex) 173 { 174 if (hex > LP873X_LDO_VOLT_MAX_HEX) 175 return -EINVAL; 176 177 if (!hex) 178 return 0; 179 180 return (hex * 100000) + 800000; 181 } 182 183 static int lp873x_ldo_val(struct udevice *dev, int op, int *uV) 184 { 185 unsigned int hex, adr; 186 int ret; 187 188 struct dm_regulator_uclass_platdata *uc_pdata; 189 190 if (op == PMIC_OP_GET) 191 *uV = 0; 192 193 uc_pdata = dev_get_uclass_platdata(dev); 194 195 adr = uc_pdata->volt_reg; 196 197 ret = pmic_reg_read(dev->parent, adr); 198 if (ret < 0) 199 return ret; 200 201 if (op == PMIC_OP_GET) { 202 ret &= LP873X_LDO_VOLT_MASK; 203 ret = lp873x_ldo_hex2volt(ret); 204 if (ret < 0) 205 return ret; 206 *uV = ret; 207 return 0; 208 } 209 210 hex = lp873x_ldo_volt2hex(*uV); 211 if (hex < 0) 212 return hex; 213 214 ret &= ~LP873X_LDO_VOLT_MASK; 215 ret |= hex; 216 if (*uV > 1650000) 217 ret |= 0x80; 218 ret = pmic_reg_write(dev->parent, adr, ret); 219 220 return ret; 221 } 222 223 static int lp873x_ldo_probe(struct udevice *dev) 224 { 225 struct dm_regulator_uclass_platdata *uc_pdata; 226 227 uc_pdata = dev_get_uclass_platdata(dev); 228 uc_pdata->type = REGULATOR_TYPE_LDO; 229 230 int idx = dev->driver_data; 231 if (idx >= LP873X_LDO_NUM) { 232 printf("Wrong ID for regulator\n"); 233 return -1; 234 } 235 236 uc_pdata->ctrl_reg = lp873x_ldo_ctrl[idx]; 237 uc_pdata->volt_reg = lp873x_ldo_volt[idx]; 238 239 return 0; 240 } 241 242 static int ldo_get_value(struct udevice *dev) 243 { 244 int uV; 245 int ret; 246 247 ret = lp873x_ldo_val(dev, PMIC_OP_GET, &uV); 248 if (ret) 249 return ret; 250 251 return uV; 252 } 253 254 static int ldo_set_value(struct udevice *dev, int uV) 255 { 256 return lp873x_ldo_val(dev, PMIC_OP_SET, &uV); 257 } 258 259 static int ldo_get_enable(struct udevice *dev) 260 { 261 bool enable = false; 262 int ret; 263 264 ret = lp873x_ldo_enable(dev, PMIC_OP_GET, &enable); 265 if (ret) 266 return ret; 267 268 return enable; 269 } 270 271 static int ldo_set_enable(struct udevice *dev, bool enable) 272 { 273 return lp873x_ldo_enable(dev, PMIC_OP_SET, &enable); 274 } 275 276 static int lp873x_buck_probe(struct udevice *dev) 277 { 278 struct dm_regulator_uclass_platdata *uc_pdata; 279 int idx; 280 281 uc_pdata = dev_get_uclass_platdata(dev); 282 uc_pdata->type = REGULATOR_TYPE_BUCK; 283 284 idx = dev->driver_data; 285 if (idx >= LP873X_BUCK_NUM) { 286 printf("Wrong ID for regulator\n"); 287 return -1; 288 } 289 290 uc_pdata->ctrl_reg = lp873x_buck_ctrl[idx]; 291 uc_pdata->volt_reg = lp873x_buck_volt[idx]; 292 293 return 0; 294 } 295 296 static int buck_get_value(struct udevice *dev) 297 { 298 int uV; 299 int ret; 300 301 ret = lp873x_buck_val(dev, PMIC_OP_GET, &uV); 302 if (ret) 303 return ret; 304 305 return uV; 306 } 307 308 static int buck_set_value(struct udevice *dev, int uV) 309 { 310 return lp873x_buck_val(dev, PMIC_OP_SET, &uV); 311 } 312 313 static int buck_get_enable(struct udevice *dev) 314 { 315 bool enable = false; 316 int ret; 317 318 319 ret = lp873x_buck_enable(dev, PMIC_OP_GET, &enable); 320 if (ret) 321 return ret; 322 323 return enable; 324 } 325 326 static int buck_set_enable(struct udevice *dev, bool enable) 327 { 328 return lp873x_buck_enable(dev, PMIC_OP_SET, &enable); 329 } 330 331 static const struct dm_regulator_ops lp873x_ldo_ops = { 332 .get_value = ldo_get_value, 333 .set_value = ldo_set_value, 334 .get_enable = ldo_get_enable, 335 .set_enable = ldo_set_enable, 336 }; 337 338 U_BOOT_DRIVER(lp873x_ldo) = { 339 .name = LP873X_LDO_DRIVER, 340 .id = UCLASS_REGULATOR, 341 .ops = &lp873x_ldo_ops, 342 .probe = lp873x_ldo_probe, 343 }; 344 345 static const struct dm_regulator_ops lp873x_buck_ops = { 346 .get_value = buck_get_value, 347 .set_value = buck_set_value, 348 .get_enable = buck_get_enable, 349 .set_enable = buck_set_enable, 350 }; 351 352 U_BOOT_DRIVER(lp873x_buck) = { 353 .name = LP873X_BUCK_DRIVER, 354 .id = UCLASS_REGULATOR, 355 .ops = &lp873x_buck_ops, 356 .probe = lp873x_buck_probe, 357 }; 358