1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Copyright (C) 2018 BayLibre SAS 4 // Author: Bartosz Golaszewski <bgolaszewski@baylibre.com> 5 // 6 // Regulator driver for MAXIM 77650/77651 charger/power-supply. 7 8 #include <linux/of.h> 9 #include <linux/mfd/max77650.h> 10 #include <linux/module.h> 11 #include <linux/platform_device.h> 12 #include <linux/regmap.h> 13 #include <linux/regulator/driver.h> 14 15 #define MAX77650_REGULATOR_EN_CTRL_MASK GENMASK(3, 0) 16 #define MAX77650_REGULATOR_EN_CTRL_BITS(_reg) \ 17 ((_reg) & MAX77650_REGULATOR_EN_CTRL_MASK) 18 #define MAX77650_REGULATOR_ENABLED GENMASK(2, 1) 19 #define MAX77650_REGULATOR_DISABLED BIT(2) 20 21 #define MAX77650_REGULATOR_V_LDO_MASK GENMASK(6, 0) 22 #define MAX77650_REGULATOR_V_SBB_MASK GENMASK(5, 0) 23 24 #define MAX77650_REGULATOR_AD_MASK BIT(3) 25 #define MAX77650_REGULATOR_AD_DISABLED 0x00 26 #define MAX77650_REGULATOR_AD_ENABLED BIT(3) 27 28 #define MAX77650_REGULATOR_CURR_LIM_MASK GENMASK(7, 6) 29 30 enum { 31 MAX77650_REGULATOR_ID_LDO = 0, 32 MAX77650_REGULATOR_ID_SBB0, 33 MAX77650_REGULATOR_ID_SBB1, 34 MAX77650_REGULATOR_ID_SBB2, 35 MAX77650_REGULATOR_NUM_REGULATORS, 36 }; 37 38 struct max77650_regulator_desc { 39 struct regulator_desc desc; 40 unsigned int regA; 41 unsigned int regB; 42 }; 43 44 static const unsigned int max77651_sbb1_regulator_volt_table[] = { 45 2400000, 3200000, 4000000, 4800000, 46 2450000, 3250000, 4050000, 4850000, 47 2500000, 3300000, 4100000, 4900000, 48 2550000, 3350000, 4150000, 4950000, 49 2600000, 3400000, 4200000, 5000000, 50 2650000, 3450000, 4250000, 5050000, 51 2700000, 3500000, 4300000, 5100000, 52 2750000, 3550000, 4350000, 5150000, 53 2800000, 3600000, 4400000, 5200000, 54 2850000, 3650000, 4450000, 5250000, 55 2900000, 3700000, 4500000, 0, 56 2950000, 3750000, 4550000, 0, 57 3000000, 3800000, 4600000, 0, 58 3050000, 3850000, 4650000, 0, 59 3100000, 3900000, 4700000, 0, 60 3150000, 3950000, 4750000, 0, 61 }; 62 63 #define MAX77651_REGULATOR_SBB1_SEL_DEC(_val) \ 64 (((_val & 0x3c) >> 2) | ((_val & 0x03) << 4)) 65 #define MAX77651_REGULATOR_SBB1_SEL_ENC(_val) \ 66 (((_val & 0x30) >> 4) | ((_val & 0x0f) << 2)) 67 68 #define MAX77650_REGULATOR_SBB1_SEL_DECR(_val) \ 69 do { \ 70 _val = MAX77651_REGULATOR_SBB1_SEL_DEC(_val); \ 71 _val--; \ 72 _val = MAX77651_REGULATOR_SBB1_SEL_ENC(_val); \ 73 } while (0) 74 75 #define MAX77650_REGULATOR_SBB1_SEL_INCR(_val) \ 76 do { \ 77 _val = MAX77651_REGULATOR_SBB1_SEL_DEC(_val); \ 78 _val++; \ 79 _val = MAX77651_REGULATOR_SBB1_SEL_ENC(_val); \ 80 } while (0) 81 82 static const unsigned int max77650_current_limit_table[] = { 83 1000000, 866000, 707000, 500000, 84 }; 85 86 static int max77650_regulator_is_enabled(struct regulator_dev *rdev) 87 { 88 struct max77650_regulator_desc *rdesc; 89 struct regmap *map; 90 int val, rv, en; 91 92 rdesc = rdev_get_drvdata(rdev); 93 map = rdev_get_regmap(rdev); 94 95 rv = regmap_read(map, rdesc->regB, &val); 96 if (rv) 97 return rv; 98 99 en = MAX77650_REGULATOR_EN_CTRL_BITS(val); 100 101 return en != MAX77650_REGULATOR_DISABLED; 102 } 103 104 static int max77650_regulator_enable(struct regulator_dev *rdev) 105 { 106 struct max77650_regulator_desc *rdesc; 107 struct regmap *map; 108 109 rdesc = rdev_get_drvdata(rdev); 110 map = rdev_get_regmap(rdev); 111 112 return regmap_update_bits(map, rdesc->regB, 113 MAX77650_REGULATOR_EN_CTRL_MASK, 114 MAX77650_REGULATOR_ENABLED); 115 } 116 117 static int max77650_regulator_disable(struct regulator_dev *rdev) 118 { 119 struct max77650_regulator_desc *rdesc; 120 struct regmap *map; 121 122 rdesc = rdev_get_drvdata(rdev); 123 map = rdev_get_regmap(rdev); 124 125 return regmap_update_bits(map, rdesc->regB, 126 MAX77650_REGULATOR_EN_CTRL_MASK, 127 MAX77650_REGULATOR_DISABLED); 128 } 129 130 static int max77650_regulator_set_voltage_sel(struct regulator_dev *rdev, 131 unsigned int sel) 132 { 133 int rv = 0, curr, diff; 134 bool ascending; 135 136 /* 137 * If the regulator is disabled, we can program the desired 138 * voltage right away. 139 */ 140 if (!max77650_regulator_is_enabled(rdev)) 141 return regulator_set_voltage_sel_regmap(rdev, sel); 142 143 /* 144 * Otherwise we need to manually ramp the output voltage up/down 145 * one step at a time. 146 */ 147 148 curr = regulator_get_voltage_sel_regmap(rdev); 149 if (curr < 0) 150 return curr; 151 152 diff = curr - sel; 153 if (diff == 0) 154 return 0; /* Already there. */ 155 else if (diff > 0) 156 ascending = false; 157 else 158 ascending = true; 159 160 /* 161 * Make sure we'll get to the right voltage and break the loop even if 162 * the selector equals 0. 163 */ 164 for (ascending ? curr++ : curr--;; ascending ? curr++ : curr--) { 165 rv = regulator_set_voltage_sel_regmap(rdev, curr); 166 if (rv) 167 return rv; 168 169 if (curr == sel) 170 break; 171 } 172 173 return 0; 174 } 175 176 /* 177 * Special case: non-linear voltage table for max77651 SBB1 - software 178 * must ensure the voltage is ramped in 50mV increments. 179 */ 180 static int max77651_regulator_sbb1_set_voltage_sel(struct regulator_dev *rdev, 181 unsigned int sel) 182 { 183 int rv = 0, curr, vcurr, vdest, vdiff; 184 185 /* 186 * If the regulator is disabled, we can program the desired 187 * voltage right away. 188 */ 189 if (!max77650_regulator_is_enabled(rdev)) 190 return regulator_set_voltage_sel_regmap(rdev, sel); 191 192 curr = regulator_get_voltage_sel_regmap(rdev); 193 if (curr < 0) 194 return curr; 195 196 if (curr == sel) 197 return 0; /* Already there. */ 198 199 vcurr = max77651_sbb1_regulator_volt_table[curr]; 200 vdest = max77651_sbb1_regulator_volt_table[sel]; 201 vdiff = vcurr - vdest; 202 203 for (;;) { 204 if (vdiff > 0) 205 MAX77650_REGULATOR_SBB1_SEL_DECR(curr); 206 else 207 MAX77650_REGULATOR_SBB1_SEL_INCR(curr); 208 209 rv = regulator_set_voltage_sel_regmap(rdev, curr); 210 if (rv) 211 return rv; 212 213 if (curr == sel) 214 break; 215 }; 216 217 return 0; 218 } 219 220 static const struct regulator_ops max77650_regulator_LDO_ops = { 221 .is_enabled = max77650_regulator_is_enabled, 222 .enable = max77650_regulator_enable, 223 .disable = max77650_regulator_disable, 224 .list_voltage = regulator_list_voltage_linear, 225 .map_voltage = regulator_map_voltage_linear, 226 .get_voltage_sel = regulator_get_voltage_sel_regmap, 227 .set_voltage_sel = max77650_regulator_set_voltage_sel, 228 .set_active_discharge = regulator_set_active_discharge_regmap, 229 }; 230 231 static const struct regulator_ops max77650_regulator_SBB_ops = { 232 .is_enabled = max77650_regulator_is_enabled, 233 .enable = max77650_regulator_enable, 234 .disable = max77650_regulator_disable, 235 .list_voltage = regulator_list_voltage_linear, 236 .map_voltage = regulator_map_voltage_linear, 237 .get_voltage_sel = regulator_get_voltage_sel_regmap, 238 .set_voltage_sel = max77650_regulator_set_voltage_sel, 239 .get_current_limit = regulator_get_current_limit_regmap, 240 .set_current_limit = regulator_set_current_limit_regmap, 241 .set_active_discharge = regulator_set_active_discharge_regmap, 242 }; 243 244 /* Special case for max77651 SBB1 - non-linear voltage mapping. */ 245 static const struct regulator_ops max77651_SBB1_regulator_ops = { 246 .is_enabled = max77650_regulator_is_enabled, 247 .enable = max77650_regulator_enable, 248 .disable = max77650_regulator_disable, 249 .list_voltage = regulator_list_voltage_table, 250 .get_voltage_sel = regulator_get_voltage_sel_regmap, 251 .set_voltage_sel = max77651_regulator_sbb1_set_voltage_sel, 252 .get_current_limit = regulator_get_current_limit_regmap, 253 .set_current_limit = regulator_set_current_limit_regmap, 254 .set_active_discharge = regulator_set_active_discharge_regmap, 255 }; 256 257 static struct max77650_regulator_desc max77650_LDO_desc = { 258 .desc = { 259 .name = "ldo", 260 .of_match = of_match_ptr("ldo"), 261 .regulators_node = of_match_ptr("regulators"), 262 .supply_name = "in-ldo", 263 .id = MAX77650_REGULATOR_ID_LDO, 264 .ops = &max77650_regulator_LDO_ops, 265 .min_uV = 1350000, 266 .uV_step = 12500, 267 .n_voltages = 128, 268 .vsel_mask = MAX77650_REGULATOR_V_LDO_MASK, 269 .vsel_reg = MAX77650_REG_CNFG_LDO_A, 270 .active_discharge_off = MAX77650_REGULATOR_AD_DISABLED, 271 .active_discharge_on = MAX77650_REGULATOR_AD_ENABLED, 272 .active_discharge_mask = MAX77650_REGULATOR_AD_MASK, 273 .active_discharge_reg = MAX77650_REG_CNFG_LDO_B, 274 .enable_time = 100, 275 .type = REGULATOR_VOLTAGE, 276 .owner = THIS_MODULE, 277 }, 278 .regA = MAX77650_REG_CNFG_LDO_A, 279 .regB = MAX77650_REG_CNFG_LDO_B, 280 }; 281 282 static struct max77650_regulator_desc max77650_SBB0_desc = { 283 .desc = { 284 .name = "sbb0", 285 .of_match = of_match_ptr("sbb0"), 286 .regulators_node = of_match_ptr("regulators"), 287 .supply_name = "in-sbb0", 288 .id = MAX77650_REGULATOR_ID_SBB0, 289 .ops = &max77650_regulator_SBB_ops, 290 .min_uV = 800000, 291 .uV_step = 25000, 292 .n_voltages = 64, 293 .vsel_mask = MAX77650_REGULATOR_V_SBB_MASK, 294 .vsel_reg = MAX77650_REG_CNFG_SBB0_A, 295 .active_discharge_off = MAX77650_REGULATOR_AD_DISABLED, 296 .active_discharge_on = MAX77650_REGULATOR_AD_ENABLED, 297 .active_discharge_mask = MAX77650_REGULATOR_AD_MASK, 298 .active_discharge_reg = MAX77650_REG_CNFG_SBB0_B, 299 .enable_time = 100, 300 .type = REGULATOR_VOLTAGE, 301 .owner = THIS_MODULE, 302 .csel_reg = MAX77650_REG_CNFG_SBB0_A, 303 .csel_mask = MAX77650_REGULATOR_CURR_LIM_MASK, 304 .curr_table = max77650_current_limit_table, 305 .n_current_limits = ARRAY_SIZE(max77650_current_limit_table), 306 }, 307 .regA = MAX77650_REG_CNFG_SBB0_A, 308 .regB = MAX77650_REG_CNFG_SBB0_B, 309 }; 310 311 static struct max77650_regulator_desc max77650_SBB1_desc = { 312 .desc = { 313 .name = "sbb1", 314 .of_match = of_match_ptr("sbb1"), 315 .regulators_node = of_match_ptr("regulators"), 316 .supply_name = "in-sbb1", 317 .id = MAX77650_REGULATOR_ID_SBB1, 318 .ops = &max77650_regulator_SBB_ops, 319 .min_uV = 800000, 320 .uV_step = 12500, 321 .n_voltages = 64, 322 .vsel_mask = MAX77650_REGULATOR_V_SBB_MASK, 323 .vsel_reg = MAX77650_REG_CNFG_SBB1_A, 324 .active_discharge_off = MAX77650_REGULATOR_AD_DISABLED, 325 .active_discharge_on = MAX77650_REGULATOR_AD_ENABLED, 326 .active_discharge_mask = MAX77650_REGULATOR_AD_MASK, 327 .active_discharge_reg = MAX77650_REG_CNFG_SBB1_B, 328 .enable_time = 100, 329 .type = REGULATOR_VOLTAGE, 330 .owner = THIS_MODULE, 331 .csel_reg = MAX77650_REG_CNFG_SBB1_A, 332 .csel_mask = MAX77650_REGULATOR_CURR_LIM_MASK, 333 .curr_table = max77650_current_limit_table, 334 .n_current_limits = ARRAY_SIZE(max77650_current_limit_table), 335 }, 336 .regA = MAX77650_REG_CNFG_SBB1_A, 337 .regB = MAX77650_REG_CNFG_SBB1_B, 338 }; 339 340 static struct max77650_regulator_desc max77651_SBB1_desc = { 341 .desc = { 342 .name = "sbb1", 343 .of_match = of_match_ptr("sbb1"), 344 .regulators_node = of_match_ptr("regulators"), 345 .supply_name = "in-sbb1", 346 .id = MAX77650_REGULATOR_ID_SBB1, 347 .ops = &max77651_SBB1_regulator_ops, 348 .volt_table = max77651_sbb1_regulator_volt_table, 349 .n_voltages = ARRAY_SIZE(max77651_sbb1_regulator_volt_table), 350 .vsel_mask = MAX77650_REGULATOR_V_SBB_MASK, 351 .vsel_reg = MAX77650_REG_CNFG_SBB1_A, 352 .active_discharge_off = MAX77650_REGULATOR_AD_DISABLED, 353 .active_discharge_on = MAX77650_REGULATOR_AD_ENABLED, 354 .active_discharge_mask = MAX77650_REGULATOR_AD_MASK, 355 .active_discharge_reg = MAX77650_REG_CNFG_SBB1_B, 356 .enable_time = 100, 357 .type = REGULATOR_VOLTAGE, 358 .owner = THIS_MODULE, 359 .csel_reg = MAX77650_REG_CNFG_SBB1_A, 360 .csel_mask = MAX77650_REGULATOR_CURR_LIM_MASK, 361 .curr_table = max77650_current_limit_table, 362 .n_current_limits = ARRAY_SIZE(max77650_current_limit_table), 363 }, 364 .regA = MAX77650_REG_CNFG_SBB1_A, 365 .regB = MAX77650_REG_CNFG_SBB1_B, 366 }; 367 368 static struct max77650_regulator_desc max77650_SBB2_desc = { 369 .desc = { 370 .name = "sbb2", 371 .of_match = of_match_ptr("sbb2"), 372 .regulators_node = of_match_ptr("regulators"), 373 .supply_name = "in-sbb0", 374 .id = MAX77650_REGULATOR_ID_SBB2, 375 .ops = &max77650_regulator_SBB_ops, 376 .min_uV = 800000, 377 .uV_step = 50000, 378 .n_voltages = 64, 379 .vsel_mask = MAX77650_REGULATOR_V_SBB_MASK, 380 .vsel_reg = MAX77650_REG_CNFG_SBB2_A, 381 .active_discharge_off = MAX77650_REGULATOR_AD_DISABLED, 382 .active_discharge_on = MAX77650_REGULATOR_AD_ENABLED, 383 .active_discharge_mask = MAX77650_REGULATOR_AD_MASK, 384 .active_discharge_reg = MAX77650_REG_CNFG_SBB2_B, 385 .enable_time = 100, 386 .type = REGULATOR_VOLTAGE, 387 .owner = THIS_MODULE, 388 .csel_reg = MAX77650_REG_CNFG_SBB2_A, 389 .csel_mask = MAX77650_REGULATOR_CURR_LIM_MASK, 390 .curr_table = max77650_current_limit_table, 391 .n_current_limits = ARRAY_SIZE(max77650_current_limit_table), 392 }, 393 .regA = MAX77650_REG_CNFG_SBB2_A, 394 .regB = MAX77650_REG_CNFG_SBB2_B, 395 }; 396 397 static struct max77650_regulator_desc max77651_SBB2_desc = { 398 .desc = { 399 .name = "sbb2", 400 .of_match = of_match_ptr("sbb2"), 401 .regulators_node = of_match_ptr("regulators"), 402 .supply_name = "in-sbb0", 403 .id = MAX77650_REGULATOR_ID_SBB2, 404 .ops = &max77650_regulator_SBB_ops, 405 .min_uV = 2400000, 406 .uV_step = 50000, 407 .n_voltages = 64, 408 .vsel_mask = MAX77650_REGULATOR_V_SBB_MASK, 409 .vsel_reg = MAX77650_REG_CNFG_SBB2_A, 410 .active_discharge_off = MAX77650_REGULATOR_AD_DISABLED, 411 .active_discharge_on = MAX77650_REGULATOR_AD_ENABLED, 412 .active_discharge_mask = MAX77650_REGULATOR_AD_MASK, 413 .active_discharge_reg = MAX77650_REG_CNFG_SBB2_B, 414 .enable_time = 100, 415 .type = REGULATOR_VOLTAGE, 416 .owner = THIS_MODULE, 417 .csel_reg = MAX77650_REG_CNFG_SBB2_A, 418 .csel_mask = MAX77650_REGULATOR_CURR_LIM_MASK, 419 .curr_table = max77650_current_limit_table, 420 .n_current_limits = ARRAY_SIZE(max77650_current_limit_table), 421 }, 422 .regA = MAX77650_REG_CNFG_SBB2_A, 423 .regB = MAX77650_REG_CNFG_SBB2_B, 424 }; 425 426 static int max77650_regulator_probe(struct platform_device *pdev) 427 { 428 struct max77650_regulator_desc **rdescs; 429 struct max77650_regulator_desc *rdesc; 430 struct regulator_config config = { }; 431 struct device *dev, *parent; 432 struct regulator_dev *rdev; 433 struct regmap *map; 434 unsigned int val; 435 int i, rv; 436 437 dev = &pdev->dev; 438 parent = dev->parent; 439 440 if (!dev->of_node) 441 dev->of_node = parent->of_node; 442 443 rdescs = devm_kcalloc(dev, MAX77650_REGULATOR_NUM_REGULATORS, 444 sizeof(*rdescs), GFP_KERNEL); 445 if (!rdescs) 446 return -ENOMEM; 447 448 map = dev_get_regmap(parent, NULL); 449 if (!map) 450 return -ENODEV; 451 452 rv = regmap_read(map, MAX77650_REG_CID, &val); 453 if (rv) 454 return rv; 455 456 rdescs[MAX77650_REGULATOR_ID_LDO] = &max77650_LDO_desc; 457 rdescs[MAX77650_REGULATOR_ID_SBB0] = &max77650_SBB0_desc; 458 459 switch (MAX77650_CID_BITS(val)) { 460 case MAX77650_CID_77650A: 461 case MAX77650_CID_77650C: 462 rdescs[MAX77650_REGULATOR_ID_SBB1] = &max77650_SBB1_desc; 463 rdescs[MAX77650_REGULATOR_ID_SBB2] = &max77650_SBB2_desc; 464 break; 465 case MAX77650_CID_77651A: 466 case MAX77650_CID_77651B: 467 rdescs[MAX77650_REGULATOR_ID_SBB1] = &max77651_SBB1_desc; 468 rdescs[MAX77650_REGULATOR_ID_SBB2] = &max77651_SBB2_desc; 469 break; 470 default: 471 return -ENODEV; 472 } 473 474 config.dev = parent; 475 476 for (i = 0; i < MAX77650_REGULATOR_NUM_REGULATORS; i++) { 477 rdesc = rdescs[i]; 478 config.driver_data = rdesc; 479 480 rdev = devm_regulator_register(dev, &rdesc->desc, &config); 481 if (IS_ERR(rdev)) 482 return PTR_ERR(rdev); 483 } 484 485 return 0; 486 } 487 488 static struct platform_driver max77650_regulator_driver = { 489 .driver = { 490 .name = "max77650-regulator", 491 }, 492 .probe = max77650_regulator_probe, 493 }; 494 module_platform_driver(max77650_regulator_driver); 495 496 MODULE_DESCRIPTION("MAXIM 77650/77651 regulator driver"); 497 MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>"); 498 MODULE_LICENSE("GPL v2"); 499