1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright(C) 2023 Svyatoslav Ryhel <clamor95@gmail.com> 4 */ 5 6#include <dm.h> 7#include <power/pmic.h> 8#include <power/regulator.h> 9#include <power/max77663.h> 10 11/* fist row is control registers, second is voltage registers */ 12static const char max77663_sd_reg[][MAX77663_SD_NUM] = { 13 { 0x1d, 0x1e, 0x1f, 0x20, 0x21 }, 14 { 0x16, 0x17, 0x18, 0x19, 0x2a }, 15}; 16 17static const char max77663_ldo_reg[MAX77663_LDO_NUM] = { 18 0x23, 0x25, 0x27, 0x29, 0x2b, 0x2d, 0x2f, 0x31, 0x33 19}; 20 21static int max77663_sd_enable(struct udevice *dev, int op, bool *enable) 22{ 23 struct dm_regulator_uclass_plat *uc_pdata = 24 dev_get_uclass_plat(dev); 25 u32 adr = uc_pdata->ctrl_reg; 26 int val, ret; 27 28 val = pmic_reg_read(dev->parent, adr); 29 if (val < 0) 30 return val; 31 32 if (op == PMIC_OP_GET) { 33 if (val & SD_STATUS_MASK) 34 *enable = true; 35 else 36 *enable = false; 37 38 return 0; 39 } else if (op == PMIC_OP_SET) { 40 val &= ~SD_STATUS_MASK; 41 42 if (*enable) 43 val |= SD_STATUS_MASK; 44 45 ret = pmic_reg_write(dev->parent, adr, val); 46 if (ret) 47 return ret; 48 } 49 50 return 0; 51} 52 53/** 54 * max77663_*_volt2hex() - convert voltage in uV into 55 * applicable to register hex value 56 * 57 * @idx: regulator index 58 * @uV: voltage in uV 59 * 60 * Return: voltage in hex on success, -ve on failure 61 */ 62static int max77663_sd_volt2hex(int idx, int uV) 63{ 64 switch (idx) { 65 case 0: 66 /* SD0 has max voltage 1.4V */ 67 if (uV > SD0_VOLT_MAX) 68 return -EINVAL; 69 break; 70 case 1: 71 /* SD1 has max voltage 1.55V */ 72 if (uV > SD1_VOLT_MAX) 73 return -EINVAL; 74 break; 75 default: 76 /* SD2 and SD3 have max voltage 3.79V */ 77 if (uV > SD_VOLT_MAX) 78 return -EINVAL; 79 break; 80 }; 81 82 if (uV < SD_VOLT_MIN) 83 uV = SD_VOLT_MIN; 84 85 return (uV - SD_VOLT_BASE) / 12500; 86} 87 88/** 89 * max77663_*_hex2volt() - convert register hex value into 90 * actual voltage in uV 91 * 92 * @idx: regulator index 93 * @hex: hex value of register 94 * 95 * Return: voltage in uV on success, -ve on failure 96 */ 97static int max77663_sd_hex2volt(int idx, int hex) 98{ 99 switch (idx) { 100 case 0: 101 /* SD0 has max voltage 1.4V */ 102 if (hex > SD0_VOLT_MAX_HEX) 103 return -EINVAL; 104 break; 105 case 1: 106 /* SD1 has max voltage 1.55V */ 107 if (hex > SD1_VOLT_MAX_HEX) 108 return -EINVAL; 109 break; 110 default: 111 /* SD2 and SD3 have max voltage 3.79V */ 112 if (hex > SD_VOLT_MAX_HEX) 113 return -EINVAL; 114 break; 115 }; 116 117 if (hex < SD_VOLT_MIN_HEX) 118 hex = SD_VOLT_MIN_HEX; 119 120 return SD_VOLT_BASE + hex * 12500; 121} 122 123static int max77663_sd_val(struct udevice *dev, int op, int *uV) 124{ 125 struct dm_regulator_uclass_plat *uc_pdata = 126 dev_get_uclass_plat(dev); 127 u32 adr = uc_pdata->volt_reg; 128 int idx = dev->driver_data; 129 int hex, ret; 130 131 if (op == PMIC_OP_GET) { 132 hex = pmic_reg_read(dev->parent, adr); 133 if (hex < 0) 134 return hex; 135 136 *uV = 0; 137 138 ret = max77663_sd_hex2volt(idx, hex); 139 if (ret < 0) 140 return ret; 141 *uV = ret; 142 143 return 0; 144 } 145 146 /* SD regulators use entire register for voltage */ 147 hex = max77663_sd_volt2hex(idx, *uV); 148 if (hex < 0) 149 return hex; 150 151 return pmic_reg_write(dev->parent, adr, hex); 152} 153 154static int max77663_sd_probe(struct udevice *dev) 155{ 156 struct dm_regulator_uclass_plat *uc_pdata = 157 dev_get_uclass_plat(dev); 158 int idx = dev->driver_data; 159 160 uc_pdata->type = REGULATOR_TYPE_BUCK; 161 uc_pdata->ctrl_reg = max77663_sd_reg[0][idx]; 162 uc_pdata->volt_reg = max77663_sd_reg[1][idx]; 163 164 return 0; 165} 166 167static int sd_get_value(struct udevice *dev) 168{ 169 int uV; 170 int ret; 171 172 ret = max77663_sd_val(dev, PMIC_OP_GET, &uV); 173 if (ret) 174 return ret; 175 176 return uV; 177} 178 179static int sd_set_value(struct udevice *dev, int uV) 180{ 181 return max77663_sd_val(dev, PMIC_OP_SET, &uV); 182} 183 184static int sd_get_enable(struct udevice *dev) 185{ 186 bool enable = false; 187 int ret; 188 189 ret = max77663_sd_enable(dev, PMIC_OP_GET, &enable); 190 if (ret) 191 return ret; 192 193 return enable; 194} 195 196static int sd_set_enable(struct udevice *dev, bool enable) 197{ 198 return max77663_sd_enable(dev, PMIC_OP_SET, &enable); 199} 200 201static const struct dm_regulator_ops max77663_sd_ops = { 202 .get_value = sd_get_value, 203 .set_value = sd_set_value, 204 .get_enable = sd_get_enable, 205 .set_enable = sd_set_enable, 206}; 207 208U_BOOT_DRIVER(max77663_sd) = { 209 .name = MAX77663_SD_DRIVER, 210 .id = UCLASS_REGULATOR, 211 .ops = &max77663_sd_ops, 212 .probe = max77663_sd_probe, 213}; 214 215static int max77663_ldo_enable(struct udevice *dev, int op, bool *enable) 216{ 217 struct dm_regulator_uclass_plat *uc_pdata = 218 dev_get_uclass_plat(dev); 219 u32 adr = uc_pdata->ctrl_reg; 220 int val, ret; 221 222 val = pmic_reg_read(dev->parent, adr); 223 if (val < 0) 224 return val; 225 226 if (op == PMIC_OP_GET) { 227 if (val & LDO_STATUS_MASK) 228 *enable = true; 229 else 230 *enable = false; 231 232 return 0; 233 } else if (op == PMIC_OP_SET) { 234 val &= ~LDO_STATUS_MASK; 235 236 if (*enable) 237 val |= LDO_STATUS_MASK; 238 239 ret = pmic_reg_write(dev->parent, adr, val); 240 if (ret) 241 return ret; 242 } 243 244 return 0; 245} 246 247static int max77663_ldo_volt2hex(int idx, int uV) 248{ 249 switch (idx) { 250 case 0: 251 case 1: 252 if (uV > LDO01_VOLT_MAX) 253 return -EINVAL; 254 255 return (uV - LDO_VOLT_BASE) / 25000; 256 case 4: 257 if (uV > LDO4_VOLT_MAX) 258 return -EINVAL; 259 260 return (uV - LDO_VOLT_BASE) / 12500; 261 default: 262 if (uV > LDO_VOLT_MAX) 263 return -EINVAL; 264 265 return (uV - LDO_VOLT_BASE) / 50000; 266 }; 267} 268 269static int max77663_ldo_hex2volt(int idx, int hex) 270{ 271 if (hex > LDO_VOLT_MAX_HEX) 272 return -EINVAL; 273 274 switch (idx) { 275 case 0: 276 case 1: 277 return (hex * 25000) + LDO_VOLT_BASE; 278 case 4: 279 return (hex * 12500) + LDO_VOLT_BASE; 280 default: 281 return (hex * 50000) + LDO_VOLT_BASE; 282 }; 283} 284 285static int max77663_ldo_val(struct udevice *dev, int op, int *uV) 286{ 287 struct dm_regulator_uclass_plat *uc_pdata = 288 dev_get_uclass_plat(dev); 289 u32 adr = uc_pdata->ctrl_reg; 290 int idx = dev->driver_data; 291 int hex, val, ret; 292 293 val = pmic_reg_read(dev->parent, adr); 294 if (val < 0) 295 return val; 296 297 if (op == PMIC_OP_GET) { 298 *uV = 0; 299 300 ret = max77663_ldo_hex2volt(idx, val & LDO_VOLT_MASK); 301 if (ret < 0) 302 return ret; 303 304 *uV = ret; 305 return 0; 306 } 307 308 hex = max77663_ldo_volt2hex(idx, *uV); 309 if (hex < 0) 310 return hex; 311 312 val &= ~LDO_VOLT_MASK; 313 314 return pmic_reg_write(dev->parent, adr, val | hex); 315} 316 317static int max77663_ldo_probe(struct udevice *dev) 318{ 319 struct dm_regulator_uclass_plat *uc_pdata = 320 dev_get_uclass_plat(dev); 321 int idx = dev->driver_data; 322 323 uc_pdata->type = REGULATOR_TYPE_LDO; 324 uc_pdata->ctrl_reg = max77663_ldo_reg[idx]; 325 326 return 0; 327} 328 329static int ldo_get_value(struct udevice *dev) 330{ 331 int uV; 332 int ret; 333 334 ret = max77663_ldo_val(dev, PMIC_OP_GET, &uV); 335 if (ret) 336 return ret; 337 338 return uV; 339} 340 341static int ldo_set_value(struct udevice *dev, int uV) 342{ 343 return max77663_ldo_val(dev, PMIC_OP_SET, &uV); 344} 345 346static int ldo_get_enable(struct udevice *dev) 347{ 348 bool enable = false; 349 int ret; 350 351 ret = max77663_ldo_enable(dev, PMIC_OP_GET, &enable); 352 if (ret) 353 return ret; 354 355 return enable; 356} 357 358static int ldo_set_enable(struct udevice *dev, bool enable) 359{ 360 return max77663_ldo_enable(dev, PMIC_OP_SET, &enable); 361} 362 363static const struct dm_regulator_ops max77663_ldo_ops = { 364 .get_value = ldo_get_value, 365 .set_value = ldo_set_value, 366 .get_enable = ldo_get_enable, 367 .set_enable = ldo_set_enable, 368}; 369 370U_BOOT_DRIVER(max77663_ldo) = { 371 .name = MAX77663_LDO_DRIVER, 372 .id = UCLASS_REGULATOR, 373 .ops = &max77663_ldo_ops, 374 .probe = max77663_ldo_probe, 375}; 376