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