1 /* 2 * Copyright (C) 2015 Samsung Electronics 3 * Przemyslaw Marczak <p.marczak@samsung.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <fdtdec.h> 10 #include <errno.h> 11 #include <dm.h> 12 #include <i2c.h> 13 #include <power/pmic.h> 14 #include <power/regulator.h> 15 #include <power/sandbox_pmic.h> 16 17 #define MODE(_id, _val, _name) [_id] = { \ 18 .id = _id, \ 19 .register_value = _val, \ 20 .name = _name, \ 21 } 22 23 #define RANGE(_min, _max, _step) { \ 24 .min = _min, \ 25 .max = _max, \ 26 .step = _step, \ 27 } 28 29 /* 30 * struct output_range - helper structure type to define the range of output 31 * operating values (current/voltage), limited by the PMIC IC design. 32 * 33 * @min - minimum value 34 * @max - maximum value 35 * @step - step value 36 */ 37 struct output_range { 38 int min; 39 int max; 40 int step; 41 }; 42 43 /* BUCK: 1,2 - voltage range */ 44 static struct output_range buck_voltage_range[] = { 45 RANGE(OUT_BUCK1_UV_MIN, OUT_BUCK1_UV_MAX, OUT_BUCK1_UV_STEP), 46 RANGE(OUT_BUCK2_UV_MIN, OUT_BUCK2_UV_MAX, OUT_BUCK2_UV_STEP), 47 }; 48 49 /* BUCK: 1 - current range */ 50 static struct output_range buck_current_range[] = { 51 RANGE(OUT_BUCK1_UA_MIN, OUT_BUCK1_UA_MAX, OUT_BUCK1_UA_STEP), 52 }; 53 54 /* BUCK operating modes */ 55 static struct dm_regulator_mode sandbox_buck_modes[] = { 56 MODE(BUCK_OM_OFF, OM2REG(BUCK_OM_OFF), "OFF"), 57 MODE(BUCK_OM_ON, OM2REG(BUCK_OM_ON), "ON"), 58 MODE(BUCK_OM_PWM, OM2REG(BUCK_OM_PWM), "PWM"), 59 }; 60 61 /* LDO: 1,2 - voltage range */ 62 static struct output_range ldo_voltage_range[] = { 63 RANGE(OUT_LDO1_UV_MIN, OUT_LDO1_UV_MAX, OUT_LDO1_UV_STEP), 64 RANGE(OUT_LDO2_UV_MIN, OUT_LDO2_UV_MAX, OUT_LDO2_UV_STEP), 65 }; 66 67 /* LDO: 1 - current range */ 68 static struct output_range ldo_current_range[] = { 69 RANGE(OUT_LDO1_UA_MIN, OUT_LDO1_UA_MAX, OUT_LDO1_UA_STEP), 70 }; 71 72 /* LDO operating modes */ 73 static struct dm_regulator_mode sandbox_ldo_modes[] = { 74 MODE(LDO_OM_OFF, OM2REG(LDO_OM_OFF), "OFF"), 75 MODE(LDO_OM_ON, OM2REG(LDO_OM_ON), "ON"), 76 MODE(LDO_OM_SLEEP, OM2REG(LDO_OM_SLEEP), "SLEEP"), 77 MODE(LDO_OM_STANDBY, OM2REG(LDO_OM_STANDBY), "STANDBY"), 78 }; 79 80 int out_get_value(struct udevice *dev, int output_count, int reg_type, 81 struct output_range *range) 82 { 83 uint8_t reg_val; 84 uint reg; 85 int ret; 86 87 if (dev->driver_data > output_count) { 88 pr_err("Unknown regulator number: %lu for PMIC %s!", 89 dev->driver_data, dev->name); 90 return -EINVAL; 91 } 92 93 reg = (dev->driver_data - 1) * OUT_REG_COUNT + reg_type; 94 ret = pmic_read(dev->parent, reg, ®_val, 1); 95 if (ret) { 96 pr_err("PMIC read failed: %d\n", ret); 97 return ret; 98 } 99 100 ret = REG2VAL(range[dev->driver_data - 1].min, 101 range[dev->driver_data - 1].step, 102 reg_val); 103 104 return ret; 105 } 106 107 static int out_set_value(struct udevice *dev, int output_count, int reg_type, 108 struct output_range *range, int value) 109 { 110 uint8_t reg_val; 111 uint reg; 112 int ret; 113 int max_value; 114 115 if (dev->driver_data > output_count) { 116 pr_err("Unknown regulator number: %lu for PMIC %s!", 117 dev->driver_data, dev->name); 118 return -EINVAL; 119 } 120 121 max_value = range[dev->driver_data - 1].max; 122 if (value > max_value) { 123 pr_err("Wrong value for %s: %lu. Max is: %d.", 124 dev->name, dev->driver_data, max_value); 125 return -EINVAL; 126 } 127 128 reg_val = VAL2REG(range[dev->driver_data - 1].min, 129 range[dev->driver_data - 1].step, 130 value); 131 132 reg = (dev->driver_data - 1) * OUT_REG_COUNT + reg_type; 133 ret = pmic_write(dev->parent, reg, ®_val, 1); 134 if (ret) { 135 pr_err("PMIC write failed: %d\n", ret); 136 return ret; 137 } 138 139 return 0; 140 } 141 142 static int out_get_mode(struct udevice *dev) 143 { 144 struct dm_regulator_uclass_platdata *uc_pdata; 145 uint8_t reg_val; 146 uint reg; 147 int ret; 148 int i; 149 150 uc_pdata = dev_get_uclass_platdata(dev); 151 152 reg = (dev->driver_data - 1) * OUT_REG_COUNT + OUT_REG_OM; 153 ret = pmic_read(dev->parent, reg, ®_val, 1); 154 if (ret) { 155 pr_err("PMIC read failed: %d\n", ret); 156 return ret; 157 } 158 159 for (i = 0; i < uc_pdata->mode_count; i++) { 160 if (reg_val == uc_pdata->mode[i].register_value) 161 return uc_pdata->mode[i].id; 162 } 163 164 pr_err("Unknown operation mode for %s!", dev->name); 165 return -EINVAL; 166 } 167 168 static int out_set_mode(struct udevice *dev, int mode) 169 { 170 struct dm_regulator_uclass_platdata *uc_pdata; 171 int reg_val = -1; 172 uint reg; 173 int ret; 174 int i; 175 176 uc_pdata = dev_get_uclass_platdata(dev); 177 178 if (mode >= uc_pdata->mode_count) 179 return -EINVAL; 180 181 for (i = 0; i < uc_pdata->mode_count; i++) { 182 if (mode == uc_pdata->mode[i].id) { 183 reg_val = uc_pdata->mode[i].register_value; 184 break; 185 } 186 } 187 188 if (reg_val == -1) { 189 pr_err("Unknown operation mode for %s!", dev->name); 190 return -EINVAL; 191 } 192 193 reg = (dev->driver_data - 1) * OUT_REG_COUNT + OUT_REG_OM; 194 ret = pmic_write(dev->parent, reg, (uint8_t *)®_val, 1); 195 if (ret) { 196 pr_err("PMIC write failed: %d\n", ret); 197 return ret; 198 } 199 200 return 0; 201 } 202 203 static int buck_get_voltage(struct udevice *dev) 204 { 205 return out_get_value(dev, SANDBOX_BUCK_COUNT, OUT_REG_UV, 206 buck_voltage_range); 207 } 208 209 static int buck_set_voltage(struct udevice *dev, int uV) 210 { 211 return out_set_value(dev, SANDBOX_BUCK_COUNT, OUT_REG_UV, 212 buck_voltage_range, uV); 213 } 214 215 static int buck_get_current(struct udevice *dev) 216 { 217 /* BUCK2 - unsupported */ 218 if (dev->driver_data == 2) 219 return -ENOSYS; 220 221 return out_get_value(dev, SANDBOX_BUCK_COUNT, OUT_REG_UA, 222 buck_current_range); 223 } 224 225 static int buck_set_current(struct udevice *dev, int uA) 226 { 227 /* BUCK2 - unsupported */ 228 if (dev->driver_data == 2) 229 return -ENOSYS; 230 231 return out_set_value(dev, SANDBOX_BUCK_COUNT, OUT_REG_UA, 232 buck_current_range, uA); 233 } 234 235 static int buck_get_enable(struct udevice *dev) 236 { 237 if (out_get_mode(dev) == BUCK_OM_OFF) 238 return false; 239 240 return true; 241 } 242 243 static int buck_set_enable(struct udevice *dev, bool enable) 244 { 245 return out_set_mode(dev, enable ? BUCK_OM_ON : BUCK_OM_OFF); 246 } 247 248 static int sandbox_buck_probe(struct udevice *dev) 249 { 250 struct dm_regulator_uclass_platdata *uc_pdata; 251 252 uc_pdata = dev_get_uclass_platdata(dev); 253 254 uc_pdata->type = REGULATOR_TYPE_BUCK; 255 uc_pdata->mode = sandbox_buck_modes; 256 uc_pdata->mode_count = ARRAY_SIZE(sandbox_buck_modes); 257 258 return 0; 259 } 260 261 static const struct dm_regulator_ops sandbox_buck_ops = { 262 .get_value = buck_get_voltage, 263 .set_value = buck_set_voltage, 264 .get_current = buck_get_current, 265 .set_current = buck_set_current, 266 .get_enable = buck_get_enable, 267 .set_enable = buck_set_enable, 268 .get_mode = out_get_mode, 269 .set_mode = out_set_mode, 270 }; 271 272 U_BOOT_DRIVER(sandbox_buck) = { 273 .name = SANDBOX_BUCK_DRIVER, 274 .id = UCLASS_REGULATOR, 275 .ops = &sandbox_buck_ops, 276 .probe = sandbox_buck_probe, 277 }; 278 279 static int ldo_get_voltage(struct udevice *dev) 280 { 281 return out_get_value(dev, SANDBOX_LDO_COUNT, OUT_REG_UV, 282 ldo_voltage_range); 283 } 284 285 static int ldo_set_voltage(struct udevice *dev, int uV) 286 { 287 return out_set_value(dev, SANDBOX_LDO_COUNT, OUT_REG_UV, 288 ldo_voltage_range, uV); 289 } 290 291 static int ldo_get_current(struct udevice *dev) 292 { 293 /* LDO2 - unsupported */ 294 if (dev->driver_data == 2) 295 return -ENOSYS; 296 297 return out_get_value(dev, SANDBOX_LDO_COUNT, OUT_REG_UA, 298 ldo_current_range); 299 } 300 301 static int ldo_set_current(struct udevice *dev, int uA) 302 { 303 /* LDO2 - unsupported */ 304 if (dev->driver_data == 2) 305 return -ENOSYS; 306 307 return out_set_value(dev, SANDBOX_LDO_COUNT, OUT_REG_UA, 308 ldo_current_range, uA); 309 } 310 311 static int ldo_get_enable(struct udevice *dev) 312 { 313 if (out_get_mode(dev) == LDO_OM_OFF) 314 return false; 315 316 return true; 317 } 318 319 static int ldo_set_enable(struct udevice *dev, bool enable) 320 { 321 return out_set_mode(dev, enable ? LDO_OM_ON : LDO_OM_OFF); 322 } 323 324 static int sandbox_ldo_probe(struct udevice *dev) 325 { 326 struct dm_regulator_uclass_platdata *uc_pdata; 327 328 uc_pdata = dev_get_uclass_platdata(dev); 329 330 uc_pdata->type = REGULATOR_TYPE_LDO; 331 uc_pdata->mode = sandbox_ldo_modes; 332 uc_pdata->mode_count = ARRAY_SIZE(sandbox_ldo_modes); 333 334 return 0; 335 } 336 337 static const struct dm_regulator_ops sandbox_ldo_ops = { 338 .get_value = ldo_get_voltage, 339 .set_value = ldo_set_voltage, 340 .get_current = ldo_get_current, 341 .set_current = ldo_set_current, 342 .get_enable = ldo_get_enable, 343 .set_enable = ldo_set_enable, 344 .get_mode = out_get_mode, 345 .set_mode = out_set_mode, 346 }; 347 348 U_BOOT_DRIVER(sandbox_ldo) = { 349 .name = SANDBOX_LDO_DRIVER, 350 .id = UCLASS_REGULATOR, 351 .ops = &sandbox_ldo_ops, 352 .probe = sandbox_ldo_probe, 353 }; 354