1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // regulator driver for the PF1550 4 // 5 // Copyright (C) 2016 Freescale Semiconductor, Inc. 6 // Robin Gong <yibin.gong@freescale.com> 7 // 8 // Portions Copyright (c) 2025 Savoir-faire Linux Inc. 9 // Samuel Kayode <samuel.kayode@savoirfairelinux.com> 10 // 11 12 #include <linux/err.h> 13 #include <linux/interrupt.h> 14 #include <linux/mfd/pf1550.h> 15 #include <linux/module.h> 16 #include <linux/platform_device.h> 17 #include <linux/regulator/driver.h> 18 #include <linux/regulator/machine.h> 19 20 #define PF1550_REGULATOR_IRQ_NR 11 21 #define PF1550_MAX_REGULATOR 7 22 23 struct pf1550_desc { 24 struct regulator_desc desc; 25 unsigned char stby_reg; 26 unsigned char stby_mask; 27 unsigned char stby_enable_reg; 28 unsigned char stby_enable_mask; 29 }; 30 31 struct pf1550_regulator_info { 32 struct device *dev; 33 const struct pf1550_ddata *pf1550; 34 struct pf1550_desc regulator_descs[PF1550_MAX_REGULATOR]; 35 struct regulator_dev *rdevs[PF1550_MAX_REGULATOR]; 36 }; 37 38 static const int pf1550_sw12_volts[] = { 39 1100000, 1200000, 1350000, 1500000, 1800000, 2500000, 3000000, 3300000, 40 }; 41 42 static const int pf1550_ldo13_volts[] = { 43 750000, 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, 44 1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, 45 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000, 46 2600000, 2700000, 2800000, 2900000, 3000000, 3100000, 3200000, 3300000, 47 }; 48 49 static int pf1550_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) 50 { 51 int id = rdev_get_id(rdev); 52 unsigned int ramp_bits = 0; 53 int ret; 54 55 if (id > PF1550_VREFDDR) 56 return -EACCES; 57 58 if (ramp_delay < 0 || ramp_delay > 6250) 59 return -EINVAL; 60 61 ramp_delay = 6250 / ramp_delay; 62 ramp_bits = ramp_delay >> 1; 63 64 ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg + 4, 0x10, 65 ramp_bits << 4); 66 if (ret < 0) 67 dev_err(&rdev->dev, "ramp failed, err %d\n", ret); 68 69 return ret; 70 } 71 72 static int pf1550_set_suspend_enable(struct regulator_dev *rdev) 73 { 74 const struct pf1550_desc *desc = container_of_const(rdev->desc, 75 struct pf1550_desc, 76 desc); 77 unsigned int val = desc->stby_enable_mask; 78 79 return regmap_update_bits(rdev->regmap, desc->stby_enable_reg, 80 desc->stby_enable_mask, val); 81 } 82 83 static int pf1550_set_suspend_disable(struct regulator_dev *rdev) 84 { 85 const struct pf1550_desc *desc = container_of_const(rdev->desc, 86 struct pf1550_desc, 87 desc); 88 89 return regmap_update_bits(rdev->regmap, desc->stby_enable_reg, 90 desc->stby_enable_mask, 0); 91 } 92 93 static int pf1550_buck_set_table_suspend_voltage(struct regulator_dev *rdev, 94 int uV) 95 { 96 const struct pf1550_desc *desc = container_of_const(rdev->desc, 97 struct pf1550_desc, 98 desc); 99 int ret; 100 101 ret = regulator_map_voltage_ascend(rdev, uV, uV); 102 if (ret < 0) { 103 dev_err(rdev_get_dev(rdev), "failed to map %i uV\n", uV); 104 return ret; 105 } 106 107 return regmap_update_bits(rdev->regmap, desc->stby_reg, 108 desc->stby_mask, ret); 109 } 110 111 static int pf1550_buck_set_linear_suspend_voltage(struct regulator_dev *rdev, 112 int uV) 113 { 114 const struct pf1550_desc *desc = container_of_const(rdev->desc, 115 struct pf1550_desc, 116 desc); 117 int ret; 118 119 ret = regulator_map_voltage_linear(rdev, uV, uV); 120 if (ret < 0) { 121 dev_err(rdev_get_dev(rdev), "failed to map %i uV\n", uV); 122 return ret; 123 } 124 125 return regmap_update_bits(rdev->regmap, desc->stby_reg, 126 desc->stby_mask, ret); 127 } 128 129 static const struct regulator_ops pf1550_sw1_ops = { 130 .enable = regulator_enable_regmap, 131 .disable = regulator_disable_regmap, 132 .set_suspend_enable = pf1550_set_suspend_enable, 133 .set_suspend_disable = pf1550_set_suspend_disable, 134 .is_enabled = regulator_is_enabled_regmap, 135 .list_voltage = regulator_list_voltage_table, 136 .set_voltage_sel = regulator_set_voltage_sel_regmap, 137 .get_voltage_sel = regulator_get_voltage_sel_regmap, 138 .set_voltage_time_sel = regulator_set_voltage_time_sel, 139 .set_suspend_voltage = pf1550_buck_set_table_suspend_voltage, 140 .map_voltage = regulator_map_voltage_ascend, 141 .set_ramp_delay = pf1550_set_ramp_delay, 142 }; 143 144 static const struct regulator_ops pf1550_sw2_ops = { 145 .enable = regulator_enable_regmap, 146 .disable = regulator_disable_regmap, 147 .set_suspend_enable = pf1550_set_suspend_enable, 148 .set_suspend_disable = pf1550_set_suspend_disable, 149 .is_enabled = regulator_is_enabled_regmap, 150 .list_voltage = regulator_list_voltage_linear, 151 .set_voltage_sel = regulator_set_voltage_sel_regmap, 152 .get_voltage_sel = regulator_get_voltage_sel_regmap, 153 .set_voltage_time_sel = regulator_set_voltage_time_sel, 154 .set_suspend_voltage = pf1550_buck_set_linear_suspend_voltage, 155 .map_voltage = regulator_map_voltage_linear, 156 .set_ramp_delay = pf1550_set_ramp_delay, 157 }; 158 159 static const struct regulator_ops pf1550_ldo1_ops = { 160 .enable = regulator_enable_regmap, 161 .disable = regulator_disable_regmap, 162 .set_suspend_enable = pf1550_set_suspend_enable, 163 .set_suspend_disable = pf1550_set_suspend_disable, 164 .is_enabled = regulator_is_enabled_regmap, 165 .list_voltage = regulator_list_voltage_table, 166 .map_voltage = regulator_map_voltage_ascend, 167 .set_voltage_sel = regulator_set_voltage_sel_regmap, 168 .get_voltage_sel = regulator_get_voltage_sel_regmap, 169 }; 170 171 static const struct regulator_ops pf1550_ldo2_ops = { 172 .enable = regulator_enable_regmap, 173 .disable = regulator_disable_regmap, 174 .set_suspend_enable = pf1550_set_suspend_enable, 175 .set_suspend_disable = pf1550_set_suspend_disable, 176 .is_enabled = regulator_is_enabled_regmap, 177 .list_voltage = regulator_list_voltage_linear, 178 .set_voltage_sel = regulator_set_voltage_sel_regmap, 179 .get_voltage_sel = regulator_get_voltage_sel_regmap, 180 .map_voltage = regulator_map_voltage_linear, 181 }; 182 183 static const struct regulator_ops pf1550_fixed_ops = { 184 .enable = regulator_enable_regmap, 185 .disable = regulator_disable_regmap, 186 .set_suspend_enable = pf1550_set_suspend_enable, 187 .set_suspend_disable = pf1550_set_suspend_disable, 188 .is_enabled = regulator_is_enabled_regmap, 189 .list_voltage = regulator_list_voltage_linear, 190 }; 191 192 #define PF_VREF(_chip, match, _name, voltage) { \ 193 .desc = { \ 194 .name = #_name, \ 195 .of_match = of_match_ptr(match), \ 196 .regulators_node = of_match_ptr("regulators"), \ 197 .n_voltages = 1, \ 198 .ops = &pf1550_fixed_ops, \ 199 .type = REGULATOR_VOLTAGE, \ 200 .id = _chip ## _ ## _name, \ 201 .owner = THIS_MODULE, \ 202 .min_uV = (voltage), \ 203 .enable_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \ 204 .enable_mask = 0x1, \ 205 }, \ 206 .stby_enable_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \ 207 .stby_enable_mask = 0x2, \ 208 } 209 210 #define PF_SW(_chip, match, _name, min, max, mask, step) { \ 211 .desc = { \ 212 .name = #_name, \ 213 .of_match = of_match_ptr(match), \ 214 .regulators_node = of_match_ptr("regulators"), \ 215 .n_voltages = ((max) - (min)) / (step) + 1, \ 216 .ops = &pf1550_sw2_ops, \ 217 .type = REGULATOR_VOLTAGE, \ 218 .id = _chip ## _ ## _name, \ 219 .owner = THIS_MODULE, \ 220 .min_uV = (min), \ 221 .uV_step = (step), \ 222 .linear_min_sel = 0, \ 223 .vsel_reg = _chip ## _PMIC_REG_ ## _name ## _VOLT, \ 224 .vsel_mask = (mask), \ 225 .enable_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \ 226 .enable_mask = 0x1, \ 227 }, \ 228 .stby_reg = _chip ## _PMIC_REG_ ## _name ## _STBY_VOLT, \ 229 .stby_mask = (mask), \ 230 .stby_enable_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \ 231 .stby_enable_mask = 0x2, \ 232 } 233 234 #define PF_LDO1(_chip, match, _name, mask, voltages) { \ 235 .desc = { \ 236 .name = #_name, \ 237 .of_match = of_match_ptr(match), \ 238 .regulators_node = of_match_ptr("regulators"), \ 239 .n_voltages = ARRAY_SIZE(voltages), \ 240 .ops = &pf1550_ldo1_ops, \ 241 .type = REGULATOR_VOLTAGE, \ 242 .id = _chip ## _ ## _name, \ 243 .owner = THIS_MODULE, \ 244 .volt_table = voltages, \ 245 .vsel_reg = _chip ## _PMIC_REG_ ## _name ## _VOLT, \ 246 .vsel_mask = (mask), \ 247 .enable_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \ 248 .enable_mask = 0x1, \ 249 }, \ 250 .stby_enable_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \ 251 .stby_enable_mask = 0x2, \ 252 } 253 254 #define PF_LDO2(_chip, match, _name, mask, min, max, step) { \ 255 .desc = { \ 256 .name = #_name, \ 257 .of_match = of_match_ptr(match), \ 258 .regulators_node = of_match_ptr("regulators"), \ 259 .n_voltages = ((max) - (min)) / (step) + 1, \ 260 .ops = &pf1550_ldo2_ops, \ 261 .type = REGULATOR_VOLTAGE, \ 262 .id = _chip ## _ ## _name, \ 263 .owner = THIS_MODULE, \ 264 .min_uV = (min), \ 265 .uV_step = (step), \ 266 .linear_min_sel = 0, \ 267 .vsel_reg = _chip ## _PMIC_REG_ ## _name ## _VOLT, \ 268 .vsel_mask = (mask), \ 269 .enable_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \ 270 .enable_mask = 0x1, \ 271 }, \ 272 .stby_enable_reg = _chip ## _PMIC_REG_ ## _name ## _CTRL, \ 273 .stby_enable_mask = 0x2, \ 274 } 275 276 static struct pf1550_desc pf1550_regulators[] = { 277 PF_SW(PF1550, "sw1", SW1, 600000, 1387500, 0x3f, 12500), 278 PF_SW(PF1550, "sw2", SW2, 600000, 1387500, 0x3f, 12500), 279 PF_SW(PF1550, "sw3", SW3, 1800000, 3300000, 0xf, 100000), 280 PF_VREF(PF1550, "vrefddr", VREFDDR, 1200000), 281 PF_LDO1(PF1550, "ldo1", LDO1, 0x1f, pf1550_ldo13_volts), 282 PF_LDO2(PF1550, "ldo2", LDO2, 0xf, 1800000, 3300000, 100000), 283 PF_LDO1(PF1550, "ldo3", LDO3, 0x1f, pf1550_ldo13_volts), 284 }; 285 286 static irqreturn_t pf1550_regulator_irq_handler(int irq, void *data) 287 { 288 struct pf1550_regulator_info *info = data; 289 struct device *dev = info->dev; 290 struct platform_device *pdev = to_platform_device(dev); 291 int i, irq_type = -1; 292 unsigned int event; 293 294 for (i = 0; i < PF1550_REGULATOR_IRQ_NR; i++) 295 if (irq == platform_get_irq(pdev, i)) 296 irq_type = i; 297 298 switch (irq_type) { 299 /* The _LS interrupts indicate over-current event. The _HS interrupts 300 * which are more accurate and can detect catastrophic faults, issue 301 * an error event. The current limit FAULT interrupt is similar to the 302 * _HS' 303 */ 304 case PF1550_PMIC_IRQ_SW1_LS: 305 case PF1550_PMIC_IRQ_SW2_LS: 306 case PF1550_PMIC_IRQ_SW3_LS: 307 event = REGULATOR_EVENT_OVER_CURRENT_WARN; 308 for (i = 0; i < PF1550_MAX_REGULATOR; i++) 309 if (!strcmp(rdev_get_name(info->rdevs[i]), "SW3")) 310 regulator_notifier_call_chain(info->rdevs[i], 311 event, NULL); 312 break; 313 case PF1550_PMIC_IRQ_SW1_HS: 314 case PF1550_PMIC_IRQ_SW2_HS: 315 case PF1550_PMIC_IRQ_SW3_HS: 316 event = REGULATOR_EVENT_OVER_CURRENT; 317 for (i = 0; i < PF1550_MAX_REGULATOR; i++) 318 if (!strcmp(rdev_get_name(info->rdevs[i]), "SW3")) 319 regulator_notifier_call_chain(info->rdevs[i], 320 event, NULL); 321 break; 322 case PF1550_PMIC_IRQ_LDO1_FAULT: 323 case PF1550_PMIC_IRQ_LDO2_FAULT: 324 case PF1550_PMIC_IRQ_LDO3_FAULT: 325 event = REGULATOR_EVENT_OVER_CURRENT; 326 for (i = 0; i < PF1550_MAX_REGULATOR; i++) 327 if (!strcmp(rdev_get_name(info->rdevs[i]), "LDO3")) 328 regulator_notifier_call_chain(info->rdevs[i], 329 event, NULL); 330 break; 331 case PF1550_PMIC_IRQ_TEMP_110: 332 case PF1550_PMIC_IRQ_TEMP_125: 333 event = REGULATOR_EVENT_OVER_TEMP; 334 for (i = 0; i < PF1550_MAX_REGULATOR; i++) 335 regulator_notifier_call_chain(info->rdevs[i], 336 event, NULL); 337 break; 338 default: 339 dev_err(dev, "regulator interrupt: irq %d occurred\n", 340 irq_type); 341 } 342 343 return IRQ_HANDLED; 344 } 345 346 static int pf1550_regulator_probe(struct platform_device *pdev) 347 { 348 const struct pf1550_ddata *pf1550 = dev_get_drvdata(pdev->dev.parent); 349 struct regulator_config config = { }; 350 struct pf1550_regulator_info *info; 351 int i, irq = -1, ret = 0; 352 353 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); 354 if (!info) 355 return -ENOMEM; 356 357 config.regmap = dev_get_regmap(pf1550->dev, NULL); 358 if (!config.regmap) 359 return dev_err_probe(&pdev->dev, -ENODEV, 360 "failed to get parent regmap\n"); 361 362 config.dev = pf1550->dev; 363 config.regmap = pf1550->regmap; 364 info->dev = &pdev->dev; 365 info->pf1550 = pf1550; 366 367 memcpy(info->regulator_descs, pf1550_regulators, 368 sizeof(info->regulator_descs)); 369 370 for (i = 0; i < ARRAY_SIZE(pf1550_regulators); i++) { 371 struct regulator_desc *desc; 372 373 desc = &info->regulator_descs[i].desc; 374 375 if ((desc->id == PF1550_SW2 && !pf1550->dvs2_enable) || 376 (desc->id == PF1550_SW1 && !pf1550->dvs1_enable)) { 377 /* OTP_SW2_DVS_ENB == 1? or OTP_SW1_DVS_ENB == 1? */ 378 desc->volt_table = pf1550_sw12_volts; 379 desc->n_voltages = ARRAY_SIZE(pf1550_sw12_volts); 380 desc->ops = &pf1550_sw1_ops; 381 } 382 383 info->rdevs[i] = devm_regulator_register(&pdev->dev, desc, 384 &config); 385 if (IS_ERR(info->rdevs[i])) 386 return dev_err_probe(&pdev->dev, 387 PTR_ERR(info->rdevs[i]), 388 "failed to initialize regulator-%d\n", 389 i); 390 } 391 392 platform_set_drvdata(pdev, info); 393 394 for (i = 0; i < PF1550_REGULATOR_IRQ_NR; i++) { 395 irq = platform_get_irq(pdev, i); 396 if (irq < 0) 397 return irq; 398 399 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, 400 pf1550_regulator_irq_handler, 401 IRQF_NO_SUSPEND, 402 "pf1550-regulator", info); 403 if (ret) 404 return dev_err_probe(&pdev->dev, ret, 405 "failed: irq request (IRQ: %d)\n", 406 i); 407 } 408 409 return 0; 410 } 411 412 static const struct platform_device_id pf1550_regulator_id[] = { 413 { "pf1550-regulator", }, 414 { /* sentinel */ } 415 }; 416 MODULE_DEVICE_TABLE(platform, pf1550_regulator_id); 417 418 static struct platform_driver pf1550_regulator_driver = { 419 .driver = { 420 .name = "pf1550-regulator", 421 }, 422 .probe = pf1550_regulator_probe, 423 .id_table = pf1550_regulator_id, 424 }; 425 module_platform_driver(pf1550_regulator_driver); 426 427 MODULE_DESCRIPTION("NXP PF1550 regulator driver"); 428 MODULE_AUTHOR("Robin Gong <yibin.gong@freescale.com>"); 429 MODULE_LICENSE("GPL"); 430