1 // SPDX-License-Identifier: GPL-2.0+ 2 3 // documentation of this device is available at 4 // https://www.nxp.com/docs/en/data-sheet/PF5300.pdf 5 6 #include <linux/delay.h> 7 #include <linux/err.h> 8 #include <linux/gpio/consumer.h> 9 #include <linux/i2c.h> 10 #include <linux/module.h> 11 #include <linux/regmap.h> 12 #include <linux/regulator/driver.h> 13 #include <linux/regulator/consumer.h> 14 #include <linux/regulator/machine.h> 15 #include <linux/regulator/of_regulator.h> 16 17 /* registers */ 18 #define PF530X_DEVICEID 0x00 19 #define PF530X_REV 0x01 20 #define PF530X_EMREV 0x02 21 #define PF530X_PROGID 0x03 22 #define PF530X_CONFIG1 0x04 23 #define PF530X_INT_STATUS1 0x05 24 #define PF530X_INT_SENSE1 0x06 25 #define PF530X_INT_STATUS2 0x07 26 #define PF530X_INT_SENSE2 0x08 27 #define PF530X_BIST_STAT1 0x09 28 #define PF530X_BIST_CTRL 0x0a 29 #define PF530X_STATE 0x0b 30 #define PF530X_STATE_CTRL 0x0c 31 #define PF530X_SW1_VOLT 0x0d 32 #define PF530X_SW1_STBY_VOLT 0x0e 33 #define PF530X_SW1_CTRL1 0x0f 34 #define PF530X_SW1_CTRL2 0x10 35 #define PF530X_CLK_CTRL 0x11 36 #define PF530X_SEQ_CTRL1 0x12 37 #define PF530X_SEQ_CTRL2 0x13 38 #define PF530X_RANDOM_CHK 0x14 39 #define PF530X_RANDOM_GEN 0x15 40 #define PF530X_WD_CTRL1 0x16 41 #define PF530X_WD_SEED 0x17 42 #define PF530X_WD_ANSWER 0x18 43 #define PF530X_FLT_CNT1 0x19 44 #define PF530X_FLT_CNT2 0x1a 45 #define PF530X_OTP_MODE 0x2f 46 47 enum pf530x_states { 48 PF530X_STATE_POF, 49 PF530X_STATE_FUSE_LOAD, 50 PF530X_STATE_LP_OFF, 51 PF530X_STATE_SELF_TEST, 52 PF530X_STATE_POWER_UP, 53 PF530X_STATE_INIT, 54 PF530X_STATE_IO_RELEASE, 55 PF530X_STATE_RUN, 56 PF530X_STATE_STANDBY, 57 PF530X_STATE_FAULT, 58 PF530X_STATE_FAILSAFE, 59 PF530X_STATE_POWER_DOWN, 60 PF530X_STATE_2MS_SELFTEST_RETRY, 61 PF530X_STATE_OFF_DLY, 62 }; 63 64 #define PF530_FAM 0x50 65 enum pf530x_devid { 66 PF5300 = 0x3, 67 PF5301 = 0x4, 68 PF5302 = 0x5, 69 }; 70 71 #define PF530x_FAM 0x50 72 #define PF530x_DEVICE_FAM_MASK GENMASK(7, 4) 73 #define PF530x_DEVICE_ID_MASK GENMASK(3, 0) 74 75 #define PF530x_STATE_MASK GENMASK(3, 0) 76 #define PF530x_STATE_RUN 0x07 77 #define PF530x_STATE_STANDBY 0x08 78 #define PF530x_STATE_LP_OFF 0x02 79 80 #define PF530X_OTP_STBY_MODE GENMASK(3, 2) 81 #define PF530X_OTP_RUN_MODE GENMASK(1, 0) 82 83 #define PF530X_INT_STATUS_OV BIT(1) 84 #define PF530X_INT_STATUS_UV BIT(2) 85 #define PF530X_INT_STATUS_ILIM BIT(3) 86 87 #define SW1_ILIM_S BIT(0) 88 #define VMON_UV_S BIT(1) 89 #define VMON_OV_S BIT(2) 90 #define VIN_OVLO_S BIT(3) 91 #define BG_ERR_S BIT(6) 92 93 #define THERM_155_S BIT(3) 94 #define THERM_140_S BIT(2) 95 #define THERM_125_S BIT(1) 96 #define THERM_110_S BIT(0) 97 98 struct pf530x_chip { 99 struct regmap *regmap; 100 struct device *dev; 101 }; 102 103 static const struct regmap_config pf530x_regmap_config = { 104 .reg_bits = 8, 105 .val_bits = 8, 106 .max_register = PF530X_OTP_MODE, 107 .cache_type = REGCACHE_MAPLE, 108 }; 109 110 static int pf530x_get_status(struct regulator_dev *rdev) 111 { 112 unsigned int state; 113 int ret; 114 115 ret = regmap_read(rdev->regmap, PF530X_INT_SENSE1, &state); 116 if (ret != 0) 117 return ret; 118 119 if ((state & (BG_ERR_S | SW1_ILIM_S | VMON_UV_S | VMON_OV_S | VIN_OVLO_S)) 120 != 0) 121 return REGULATOR_STATUS_ERROR; 122 123 // no errors, check if what non-error state we're in 124 ret = regmap_read(rdev->regmap, PF530X_STATE, &state); 125 if (ret != 0) 126 return ret; 127 128 state &= PF530x_STATE_MASK; 129 130 switch (state) { 131 case PF530x_STATE_RUN: 132 ret = REGULATOR_STATUS_NORMAL; 133 break; 134 case PF530x_STATE_STANDBY: 135 ret = REGULATOR_STATUS_STANDBY; 136 break; 137 case PF530x_STATE_LP_OFF: 138 ret = REGULATOR_STATUS_OFF; 139 break; 140 default: 141 ret = REGULATOR_STATUS_ERROR; 142 break; 143 } 144 return ret; 145 } 146 147 static int pf530x_get_error_flags(struct regulator_dev *rdev, unsigned int *flags) 148 { 149 unsigned int status; 150 int ret; 151 152 ret = regmap_read(rdev->regmap, PF530X_INT_STATUS1, &status); 153 154 if (ret != 0) 155 return ret; 156 157 *flags = 0; 158 159 if (status & PF530X_INT_STATUS_OV) 160 *flags |= REGULATOR_ERROR_OVER_VOLTAGE_WARN; 161 162 if (status & PF530X_INT_STATUS_UV) 163 *flags |= REGULATOR_ERROR_UNDER_VOLTAGE; 164 165 if (status & PF530X_INT_STATUS_ILIM) 166 *flags |= REGULATOR_ERROR_OVER_CURRENT; 167 168 ret = regmap_read(rdev->regmap, PF530X_INT_SENSE2, &status); 169 170 if (ret != 0) 171 return ret; 172 173 if ((status & (THERM_155_S | 174 THERM_140_S | 175 THERM_125_S | 176 THERM_110_S)) != 0) 177 *flags |= REGULATOR_ERROR_OVER_TEMP_WARN; 178 179 return 0; 180 } 181 182 static const struct regulator_ops pf530x_regulator_ops = { 183 .enable = regulator_enable_regmap, 184 .disable = regulator_disable_regmap, 185 .is_enabled = regulator_is_enabled_regmap, 186 .map_voltage = regulator_map_voltage_linear_range, 187 .list_voltage = regulator_list_voltage_linear_range, 188 .set_voltage_sel = regulator_set_voltage_sel_regmap, 189 .get_voltage_sel = regulator_get_voltage_sel_regmap, 190 .get_status = pf530x_get_status, 191 .get_error_flags = pf530x_get_error_flags, 192 .set_bypass = regulator_set_bypass_regmap, 193 .get_bypass = regulator_get_bypass_regmap, 194 }; 195 196 static const struct linear_range vrange = REGULATOR_LINEAR_RANGE(500000, 0, 140, 5000); 197 198 static const struct regulator_desc pf530x_reg_desc = { 199 .name = "SW1", 200 .ops = &pf530x_regulator_ops, 201 .linear_ranges = &vrange, 202 .n_linear_ranges = 1, 203 .type = REGULATOR_VOLTAGE, 204 .id = 0, 205 .owner = THIS_MODULE, 206 .vsel_reg = PF530X_SW1_VOLT, 207 .vsel_mask = 0xFF, 208 .bypass_reg = PF530X_SW1_CTRL2, 209 .bypass_mask = 0x07, 210 .bypass_val_on = 0x07, 211 .bypass_val_off = 0x00, 212 .enable_reg = PF530X_SW1_CTRL1, 213 .enable_mask = GENMASK(5, 2), 214 .enable_val = GENMASK(5, 2), 215 .disable_val = 0, 216 }; 217 218 static int pf530x_identify(struct pf530x_chip *chip) 219 { 220 unsigned int value; 221 u8 dev_fam, dev_id, full_layer_rev, metal_layer_rev, prog_idh, prog_idl, emrev; 222 const char *name = NULL; 223 int ret; 224 225 ret = regmap_read(chip->regmap, PF530X_DEVICEID, &value); 226 if (ret) { 227 dev_err(chip->dev, "failed to read chip family\n"); 228 return ret; 229 } 230 231 dev_fam = value & PF530x_DEVICE_FAM_MASK; 232 switch (dev_fam) { 233 case PF530x_FAM: 234 break; 235 default: 236 dev_err(chip->dev, 237 "Chip 0x%x is not from PF530X family\n", dev_fam); 238 return ret; 239 } 240 241 dev_id = value & PF530x_DEVICE_ID_MASK; 242 switch (dev_id) { 243 case PF5300: 244 name = "PF5300"; 245 break; 246 case PF5301: 247 name = "PF5301"; 248 break; 249 case PF5302: 250 name = "PF5302"; 251 break; 252 default: 253 dev_err(chip->dev, "Unknown pf530x device id 0x%x\n", dev_id); 254 return -ENODEV; 255 } 256 257 ret = regmap_read(chip->regmap, PF530X_REV, &value); 258 if (ret) { 259 dev_err(chip->dev, "failed to read chip rev\n"); 260 return ret; 261 } 262 263 full_layer_rev = ((value & 0xF0) == 0) ? '0' : ((((value & 0xF0) >> 4) - 1) + 'A'); 264 metal_layer_rev = value & 0xF; 265 266 ret = regmap_read(chip->regmap, PF530X_EMREV, &value); 267 if (ret) { 268 dev_err(chip->dev, "failed to read chip emrev register\n"); 269 return ret; 270 } 271 272 prog_idh = (value >> 4) + 'A'; 273 // prog_idh skips 'O', per page 96 of the datasheet 274 if (prog_idh >= 'O') 275 prog_idh += 1; 276 277 emrev = value & 0x7; 278 279 ret = regmap_read(chip->regmap, PF530X_PROGID, &value); 280 if (ret) { 281 dev_err(chip->dev, "failed to read chip progid register\n"); 282 return ret; 283 } 284 285 if (value >= 0x22) { 286 dev_err(chip->dev, "invalid value for progid register\n"); 287 return -ENODEV; 288 } else if (value < 10) { 289 prog_idl = value + '0'; 290 } else { 291 prog_idl = (value - 10) + 'A'; 292 // prog_idh skips 'O', per page 97 of the datasheet 293 if (prog_idl >= 'O') 294 prog_idl += 1; 295 } 296 297 dev_info(chip->dev, "%s Regulator found (Rev %c%d ProgID %c%c EMREV %x).\n", 298 name, full_layer_rev, metal_layer_rev, prog_idh, prog_idl, emrev); 299 300 return 0; 301 } 302 303 static int pf530x_i2c_probe(struct i2c_client *client) 304 { 305 struct regulator_config config = { NULL, }; 306 struct pf530x_chip *chip; 307 int ret; 308 struct regulator_dev *rdev; 309 struct regulator_init_data *init_data; 310 311 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 312 if (!chip) 313 return -ENOMEM; 314 315 i2c_set_clientdata(client, chip); 316 chip->dev = &client->dev; 317 318 chip->regmap = devm_regmap_init_i2c(client, &pf530x_regmap_config); 319 if (IS_ERR(chip->regmap)) { 320 ret = PTR_ERR(chip->regmap); 321 dev_err(&client->dev, 322 "regmap allocation failed with err %d\n", ret); 323 return ret; 324 } 325 326 ret = pf530x_identify(chip); 327 if (ret) 328 return ret; 329 330 init_data = of_get_regulator_init_data(chip->dev, chip->dev->of_node, &pf530x_reg_desc); 331 if (!init_data) 332 return -ENODATA; 333 334 config.dev = chip->dev; 335 config.of_node = chip->dev->of_node; 336 config.regmap = chip->regmap; 337 config.init_data = init_data; 338 339 // the config parameter gets copied, it's ok to pass a pointer on the stack here 340 rdev = devm_regulator_register(&client->dev, &pf530x_reg_desc, &config); 341 if (IS_ERR(rdev)) { 342 dev_err(&client->dev, "failed to register %s regulator\n", pf530x_reg_desc.name); 343 return PTR_ERR(rdev); 344 } 345 346 return 0; 347 } 348 349 static const struct of_device_id pf530x_dt_ids[] = { 350 { .compatible = "nxp,pf5300",}, 351 { } 352 }; 353 MODULE_DEVICE_TABLE(of, pf530x_dt_ids); 354 355 static const struct i2c_device_id pf530x_i2c_id[] = { 356 { "pf5300", 0 }, 357 { "pf5301", 0 }, 358 { "pf5302", 0 }, 359 {}, 360 }; 361 MODULE_DEVICE_TABLE(i2c, pf530x_i2c_id); 362 363 static struct i2c_driver pf530x_regulator_driver = { 364 .id_table = pf530x_i2c_id, 365 .driver = { 366 .name = "pf530x", 367 .of_match_table = pf530x_dt_ids, 368 }, 369 .probe = pf530x_i2c_probe, 370 }; 371 module_i2c_driver(pf530x_regulator_driver); 372 373 MODULE_AUTHOR("Woodrow Douglass <wdouglass@carnegierobotics.com>"); 374 MODULE_DESCRIPTION("Regulator Driver for NXP's PF5300/PF5301/PF5302 PMIC"); 375 MODULE_LICENSE("GPL"); 376