1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // tps65219-regulator.c 4 // 5 // Regulator driver for TPS65219 PMIC 6 // 7 // Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/ 8 // 9 // This implementation derived from tps65218 authored by 10 // "J Keerthy <j-keerthy@ti.com>" 11 // 12 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/device.h> 16 #include <linux/init.h> 17 #include <linux/err.h> 18 #include <linux/of.h> 19 #include <linux/platform_device.h> 20 #include <linux/regmap.h> 21 #include <linux/regulator/of_regulator.h> 22 #include <linux/regulator/driver.h> 23 #include <linux/regulator/machine.h> 24 #include <linux/mfd/tps65219.h> 25 26 struct tps65219_regulator_irq_type { 27 const char *irq_name; 28 const char *regulator_name; 29 const char *event_name; 30 unsigned long event; 31 }; 32 33 static struct tps65219_regulator_irq_type tps65219_regulator_irq_types[] = { 34 { "LDO3_SCG", "LDO3", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT }, 35 { "LDO3_OC", "LDO3", "overcurrent", REGULATOR_EVENT_OVER_CURRENT }, 36 { "LDO3_UV", "LDO3", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE }, 37 { "LDO4_SCG", "LDO4", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT }, 38 { "LDO4_OC", "LDO4", "overcurrent", REGULATOR_EVENT_OVER_CURRENT }, 39 { "LDO4_UV", "LDO4", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE }, 40 { "LDO1_SCG", "LDO1", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT }, 41 { "LDO1_OC", "LDO1", "overcurrent", REGULATOR_EVENT_OVER_CURRENT }, 42 { "LDO1_UV", "LDO1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE }, 43 { "LDO2_SCG", "LDO2", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT }, 44 { "LDO2_OC", "LDO2", "overcurrent", REGULATOR_EVENT_OVER_CURRENT }, 45 { "LDO2_UV", "LDO2", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE }, 46 { "BUCK3_SCG", "BUCK3", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT }, 47 { "BUCK3_OC", "BUCK3", "overcurrent", REGULATOR_EVENT_OVER_CURRENT }, 48 { "BUCK3_NEG_OC", "BUCK3", "negative overcurrent", REGULATOR_EVENT_OVER_CURRENT }, 49 { "BUCK3_UV", "BUCK3", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE }, 50 { "BUCK1_SCG", "BUCK1", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT }, 51 { "BUCK1_OC", "BUCK1", "overcurrent", REGULATOR_EVENT_OVER_CURRENT }, 52 { "BUCK1_NEG_OC", "BUCK1", "negative overcurrent", REGULATOR_EVENT_OVER_CURRENT }, 53 { "BUCK1_UV", "BUCK1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE }, 54 { "BUCK2_SCG", "BUCK2", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT }, 55 { "BUCK2_OC", "BUCK2", "overcurrent", REGULATOR_EVENT_OVER_CURRENT }, 56 { "BUCK2_NEG_OC", "BUCK2", "negative overcurrent", REGULATOR_EVENT_OVER_CURRENT }, 57 { "BUCK2_UV", "BUCK2", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE }, 58 { "BUCK1_RV", "BUCK1", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN }, 59 { "BUCK2_RV", "BUCK2", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN }, 60 { "BUCK3_RV", "BUCK3", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN }, 61 { "LDO1_RV", "LDO1", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN }, 62 { "LDO2_RV", "LDO2", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN }, 63 { "LDO3_RV", "LDO3", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN }, 64 { "LDO4_RV", "LDO4", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN }, 65 { "BUCK1_RV_SD", "BUCK1", "residual voltage on shutdown", 66 REGULATOR_EVENT_OVER_VOLTAGE_WARN }, 67 { "BUCK2_RV_SD", "BUCK2", "residual voltage on shutdown", 68 REGULATOR_EVENT_OVER_VOLTAGE_WARN }, 69 { "BUCK3_RV_SD", "BUCK3", "residual voltage on shutdown", 70 REGULATOR_EVENT_OVER_VOLTAGE_WARN }, 71 { "LDO1_RV_SD", "LDO1", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN }, 72 { "LDO2_RV_SD", "LDO2", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN }, 73 { "LDO3_RV_SD", "LDO3", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN }, 74 { "LDO4_RV_SD", "LDO4", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN }, 75 { "SENSOR_3_WARM", "SENSOR3", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN}, 76 { "SENSOR_2_WARM", "SENSOR2", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN }, 77 { "SENSOR_1_WARM", "SENSOR1", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN }, 78 { "SENSOR_0_WARM", "SENSOR0", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN }, 79 { "SENSOR_3_HOT", "SENSOR3", "hot temperature", REGULATOR_EVENT_OVER_TEMP}, 80 { "SENSOR_2_HOT", "SENSOR2", "hot temperature", REGULATOR_EVENT_OVER_TEMP }, 81 { "SENSOR_1_HOT", "SENSOR1", "hot temperature", REGULATOR_EVENT_OVER_TEMP }, 82 { "SENSOR_0_HOT", "SENSOR0", "hot temperature", REGULATOR_EVENT_OVER_TEMP }, 83 { "TIMEOUT", "", "", REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE }, 84 }; 85 86 struct tps65219_regulator_irq_data { 87 struct device *dev; 88 struct tps65219_regulator_irq_type *type; 89 struct regulator_dev *rdev; 90 }; 91 92 #define TPS65219_REGULATOR(_name, _of, _id, _type, _ops, _n, _vr, _vm, _er, \ 93 _em, _cr, _cm, _lr, _nlr, _delay, _fuv, \ 94 _ct, _ncl, _bpm) \ 95 { \ 96 .name = _name, \ 97 .of_match = _of, \ 98 .regulators_node = of_match_ptr("regulators"), \ 99 .supply_name = _of, \ 100 .id = _id, \ 101 .ops = &(_ops), \ 102 .n_voltages = _n, \ 103 .type = _type, \ 104 .owner = THIS_MODULE, \ 105 .vsel_reg = _vr, \ 106 .vsel_mask = _vm, \ 107 .csel_reg = _cr, \ 108 .csel_mask = _cm, \ 109 .curr_table = _ct, \ 110 .n_current_limits = _ncl, \ 111 .enable_reg = _er, \ 112 .enable_mask = _em, \ 113 .volt_table = NULL, \ 114 .linear_ranges = _lr, \ 115 .n_linear_ranges = _nlr, \ 116 .ramp_delay = _delay, \ 117 .fixed_uV = _fuv, \ 118 .bypass_reg = _vr, \ 119 .bypass_mask = _bpm, \ 120 } \ 121 122 static const struct linear_range bucks_ranges[] = { 123 REGULATOR_LINEAR_RANGE(600000, 0x0, 0x1f, 25000), 124 REGULATOR_LINEAR_RANGE(1400000, 0x20, 0x33, 100000), 125 REGULATOR_LINEAR_RANGE(3400000, 0x34, 0x3f, 0), 126 }; 127 128 static const struct linear_range ldos_1_2_ranges[] = { 129 REGULATOR_LINEAR_RANGE(600000, 0x0, 0x37, 50000), 130 REGULATOR_LINEAR_RANGE(3400000, 0x38, 0x3f, 0), 131 }; 132 133 static const struct linear_range ldos_3_4_ranges[] = { 134 REGULATOR_LINEAR_RANGE(1200000, 0x0, 0xC, 0), 135 REGULATOR_LINEAR_RANGE(1250000, 0xD, 0x35, 50000), 136 REGULATOR_LINEAR_RANGE(3300000, 0x36, 0x3F, 0), 137 }; 138 139 static int tps65219_set_mode(struct regulator_dev *dev, unsigned int mode) 140 { 141 struct tps65219 *tps = rdev_get_drvdata(dev); 142 143 switch (mode) { 144 case REGULATOR_MODE_NORMAL: 145 return regmap_set_bits(tps->regmap, TPS65219_REG_STBY_1_CONFIG, 146 dev->desc->enable_mask); 147 148 case REGULATOR_MODE_STANDBY: 149 return regmap_clear_bits(tps->regmap, 150 TPS65219_REG_STBY_1_CONFIG, 151 dev->desc->enable_mask); 152 default: 153 return -EINVAL; 154 } 155 } 156 157 static unsigned int tps65219_get_mode(struct regulator_dev *dev) 158 { 159 struct tps65219 *tps = rdev_get_drvdata(dev); 160 unsigned int rid = rdev_get_id(dev); 161 int ret, value = 0; 162 163 ret = regmap_read(tps->regmap, TPS65219_REG_STBY_1_CONFIG, &value); 164 if (ret) { 165 dev_dbg(tps->dev, "%s failed for regulator %s: %d ", 166 __func__, dev->desc->name, ret); 167 return ret; 168 } 169 value = (value & BIT(rid)) >> rid; 170 if (value) 171 return REGULATOR_MODE_STANDBY; 172 else 173 return REGULATOR_MODE_NORMAL; 174 } 175 176 /* Operations permitted on BUCK1/2/3 */ 177 static const struct regulator_ops tps65219_bucks_ops = { 178 .is_enabled = regulator_is_enabled_regmap, 179 .enable = regulator_enable_regmap, 180 .disable = regulator_disable_regmap, 181 .set_mode = tps65219_set_mode, 182 .get_mode = tps65219_get_mode, 183 .get_voltage_sel = regulator_get_voltage_sel_regmap, 184 .set_voltage_sel = regulator_set_voltage_sel_regmap, 185 .list_voltage = regulator_list_voltage_linear_range, 186 .map_voltage = regulator_map_voltage_linear_range, 187 .set_voltage_time_sel = regulator_set_voltage_time_sel, 188 189 }; 190 191 /* Operations permitted on LDO1/2 */ 192 static const struct regulator_ops tps65219_ldos_1_2_ops = { 193 .is_enabled = regulator_is_enabled_regmap, 194 .enable = regulator_enable_regmap, 195 .disable = regulator_disable_regmap, 196 .set_mode = tps65219_set_mode, 197 .get_mode = tps65219_get_mode, 198 .get_voltage_sel = regulator_get_voltage_sel_regmap, 199 .set_voltage_sel = regulator_set_voltage_sel_regmap, 200 .list_voltage = regulator_list_voltage_linear_range, 201 .map_voltage = regulator_map_voltage_linear_range, 202 .set_bypass = regulator_set_bypass_regmap, 203 .get_bypass = regulator_get_bypass_regmap, 204 }; 205 206 /* Operations permitted on LDO3/4 */ 207 static const struct regulator_ops tps65219_ldos_3_4_ops = { 208 .is_enabled = regulator_is_enabled_regmap, 209 .enable = regulator_enable_regmap, 210 .disable = regulator_disable_regmap, 211 .set_mode = tps65219_set_mode, 212 .get_mode = tps65219_get_mode, 213 .get_voltage_sel = regulator_get_voltage_sel_regmap, 214 .set_voltage_sel = regulator_set_voltage_sel_regmap, 215 .list_voltage = regulator_list_voltage_linear_range, 216 .map_voltage = regulator_map_voltage_linear_range, 217 }; 218 219 static const struct regulator_desc regulators[] = { 220 TPS65219_REGULATOR("BUCK1", "buck1", TPS65219_BUCK_1, 221 REGULATOR_VOLTAGE, tps65219_bucks_ops, 64, 222 TPS65219_REG_BUCK1_VOUT, 223 TPS65219_BUCKS_LDOS_VOUT_VSET_MASK, 224 TPS65219_REG_ENABLE_CTRL, 225 TPS65219_ENABLE_BUCK1_EN_MASK, 0, 0, bucks_ranges, 226 3, 4000, 0, NULL, 0, 0), 227 TPS65219_REGULATOR("BUCK2", "buck2", TPS65219_BUCK_2, 228 REGULATOR_VOLTAGE, tps65219_bucks_ops, 64, 229 TPS65219_REG_BUCK2_VOUT, 230 TPS65219_BUCKS_LDOS_VOUT_VSET_MASK, 231 TPS65219_REG_ENABLE_CTRL, 232 TPS65219_ENABLE_BUCK2_EN_MASK, 0, 0, bucks_ranges, 233 3, 4000, 0, NULL, 0, 0), 234 TPS65219_REGULATOR("BUCK3", "buck3", TPS65219_BUCK_3, 235 REGULATOR_VOLTAGE, tps65219_bucks_ops, 64, 236 TPS65219_REG_BUCK3_VOUT, 237 TPS65219_BUCKS_LDOS_VOUT_VSET_MASK, 238 TPS65219_REG_ENABLE_CTRL, 239 TPS65219_ENABLE_BUCK3_EN_MASK, 0, 0, bucks_ranges, 240 3, 0, 0, NULL, 0, 0), 241 TPS65219_REGULATOR("LDO1", "ldo1", TPS65219_LDO_1, 242 REGULATOR_VOLTAGE, tps65219_ldos_1_2_ops, 64, 243 TPS65219_REG_LDO1_VOUT, 244 TPS65219_BUCKS_LDOS_VOUT_VSET_MASK, 245 TPS65219_REG_ENABLE_CTRL, 246 TPS65219_ENABLE_LDO1_EN_MASK, 0, 0, ldos_1_2_ranges, 247 2, 0, 0, NULL, 0, TPS65219_LDOS_BYP_CONFIG_MASK), 248 TPS65219_REGULATOR("LDO2", "ldo2", TPS65219_LDO_2, 249 REGULATOR_VOLTAGE, tps65219_ldos_1_2_ops, 64, 250 TPS65219_REG_LDO2_VOUT, 251 TPS65219_BUCKS_LDOS_VOUT_VSET_MASK, 252 TPS65219_REG_ENABLE_CTRL, 253 TPS65219_ENABLE_LDO2_EN_MASK, 0, 0, ldos_1_2_ranges, 254 2, 0, 0, NULL, 0, TPS65219_LDOS_BYP_CONFIG_MASK), 255 TPS65219_REGULATOR("LDO3", "ldo3", TPS65219_LDO_3, 256 REGULATOR_VOLTAGE, tps65219_ldos_3_4_ops, 64, 257 TPS65219_REG_LDO3_VOUT, 258 TPS65219_BUCKS_LDOS_VOUT_VSET_MASK, 259 TPS65219_REG_ENABLE_CTRL, 260 TPS65219_ENABLE_LDO3_EN_MASK, 0, 0, ldos_3_4_ranges, 261 3, 0, 0, NULL, 0, 0), 262 TPS65219_REGULATOR("LDO4", "ldo4", TPS65219_LDO_4, 263 REGULATOR_VOLTAGE, tps65219_ldos_3_4_ops, 64, 264 TPS65219_REG_LDO4_VOUT, 265 TPS65219_BUCKS_LDOS_VOUT_VSET_MASK, 266 TPS65219_REG_ENABLE_CTRL, 267 TPS65219_ENABLE_LDO4_EN_MASK, 0, 0, ldos_3_4_ranges, 268 3, 0, 0, NULL, 0, 0), 269 }; 270 271 static irqreturn_t tps65219_regulator_irq_handler(int irq, void *data) 272 { 273 struct tps65219_regulator_irq_data *irq_data = data; 274 275 if (irq_data->type->event_name[0] == '\0') { 276 /* This is the timeout interrupt no specific regulator */ 277 dev_err(irq_data->dev, 278 "System was put in shutdown due to timeout during an active or standby transition.\n"); 279 return IRQ_HANDLED; 280 } 281 282 regulator_notifier_call_chain(irq_data->rdev, 283 irq_data->type->event, NULL); 284 285 dev_err(irq_data->dev, "Error IRQ trap %s for %s\n", 286 irq_data->type->event_name, irq_data->type->regulator_name); 287 return IRQ_HANDLED; 288 } 289 290 static int tps65219_get_rdev_by_name(const char *regulator_name, 291 struct regulator_dev *rdevtbl[7], 292 struct regulator_dev **dev) 293 { 294 int i; 295 296 for (i = 0; i < ARRAY_SIZE(regulators); i++) { 297 if (strcmp(regulator_name, regulators[i].name) == 0) { 298 *dev = rdevtbl[i]; 299 return 0; 300 } 301 } 302 return -EINVAL; 303 } 304 305 static int tps65219_regulator_probe(struct platform_device *pdev) 306 { 307 struct tps65219 *tps = dev_get_drvdata(pdev->dev.parent); 308 struct regulator_dev *rdev; 309 struct regulator_config config = { }; 310 int i; 311 int error; 312 int irq; 313 struct tps65219_regulator_irq_data *irq_data; 314 struct tps65219_regulator_irq_type *irq_type; 315 struct regulator_dev *rdevtbl[7]; 316 317 config.dev = tps->dev; 318 config.driver_data = tps; 319 config.regmap = tps->regmap; 320 321 for (i = 0; i < ARRAY_SIZE(regulators); i++) { 322 dev_dbg(tps->dev, "%s regul i= %d START", __func__, i); 323 rdev = devm_regulator_register(&pdev->dev, ®ulators[i], 324 &config); 325 if (IS_ERR(rdev)) { 326 dev_err(tps->dev, "failed to register %s regulator\n", 327 regulators[i].name); 328 return PTR_ERR(rdev); 329 } 330 rdevtbl[i] = rdev; 331 dev_dbg(tps->dev, "%s regul i= %d COMPLETED", __func__, i); 332 } 333 334 irq_data = devm_kmalloc(tps->dev, 335 ARRAY_SIZE(tps65219_regulator_irq_types) * 336 sizeof(struct tps65219_regulator_irq_data), 337 GFP_KERNEL); 338 if (!irq_data) 339 return -ENOMEM; 340 341 for (i = 0; i < ARRAY_SIZE(tps65219_regulator_irq_types); ++i) { 342 irq_type = &tps65219_regulator_irq_types[i]; 343 344 irq = platform_get_irq_byname(pdev, irq_type->irq_name); 345 if (irq < 0) 346 return -EINVAL; 347 348 irq_data[i].dev = tps->dev; 349 irq_data[i].type = irq_type; 350 351 tps65219_get_rdev_by_name(irq_type->regulator_name, rdevtbl, &rdev); 352 if (IS_ERR(rdev)) { 353 dev_err(tps->dev, "Failed to get rdev for %s\n", 354 irq_type->regulator_name); 355 return -EINVAL; 356 } 357 irq_data[i].rdev = rdev; 358 359 error = devm_request_threaded_irq(tps->dev, irq, NULL, 360 tps65219_regulator_irq_handler, 361 IRQF_ONESHOT, 362 irq_type->irq_name, 363 &irq_data[i]); 364 if (error) { 365 dev_err(tps->dev, "failed to request %s IRQ %d: %d\n", 366 irq_type->irq_name, irq, error); 367 return error; 368 } 369 } 370 371 return 0; 372 } 373 374 static const struct platform_device_id tps65219_regulator_id_table[] = { 375 { "tps65219-regulator", }, 376 { /* sentinel */ } 377 }; 378 MODULE_DEVICE_TABLE(platform, tps65219_regulator_id_table); 379 380 static struct platform_driver tps65219_regulator_driver = { 381 .driver = { 382 .name = "tps65219-pmic", 383 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 384 }, 385 .probe = tps65219_regulator_probe, 386 .id_table = tps65219_regulator_id_table, 387 }; 388 389 module_platform_driver(tps65219_regulator_driver); 390 391 MODULE_AUTHOR("Jerome Neanne <j-neanne@baylibre.com>"); 392 MODULE_DESCRIPTION("TPS65219 voltage regulator driver"); 393 MODULE_ALIAS("platform:tps65219-pmic"); 394 MODULE_LICENSE("GPL"); 395