1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Driver for TPS65218 Integrated power management chipsets 4 * 5 * Copyright (C) 2014 Texas Instruments Incorporated - https://www.ti.com/ 6 */ 7 8 #include <linux/kernel.h> 9 #include <linux/device.h> 10 #include <linux/module.h> 11 #include <linux/platform_device.h> 12 #include <linux/init.h> 13 #include <linux/i2c.h> 14 #include <linux/slab.h> 15 #include <linux/regmap.h> 16 #include <linux/err.h> 17 #include <linux/of.h> 18 #include <linux/of_device.h> 19 #include <linux/irq.h> 20 #include <linux/interrupt.h> 21 #include <linux/mutex.h> 22 23 #include <linux/mfd/core.h> 24 #include <linux/mfd/tps65218.h> 25 26 #define TPS65218_PASSWORD_REGS_UNLOCK 0x7D 27 28 static const struct mfd_cell tps65218_cells[] = { 29 { 30 .name = "tps65218-pwrbutton", 31 .of_compatible = "ti,tps65218-pwrbutton", 32 }, 33 { 34 .name = "tps65218-gpio", 35 .of_compatible = "ti,tps65218-gpio", 36 }, 37 { .name = "tps65218-regulator", }, 38 }; 39 40 /** 41 * tps65218_reg_write: Write a single tps65218 register. 42 * 43 * @tps: Device to write to. 44 * @reg: Register to write to. 45 * @val: Value to write. 46 * @level: Password protected level 47 */ 48 int tps65218_reg_write(struct tps65218 *tps, unsigned int reg, 49 unsigned int val, unsigned int level) 50 { 51 int ret; 52 unsigned int xor_reg_val; 53 54 switch (level) { 55 case TPS65218_PROTECT_NONE: 56 return regmap_write(tps->regmap, reg, val); 57 case TPS65218_PROTECT_L1: 58 xor_reg_val = reg ^ TPS65218_PASSWORD_REGS_UNLOCK; 59 ret = regmap_write(tps->regmap, TPS65218_REG_PASSWORD, 60 xor_reg_val); 61 if (ret < 0) 62 return ret; 63 64 return regmap_write(tps->regmap, reg, val); 65 default: 66 return -EINVAL; 67 } 68 } 69 EXPORT_SYMBOL_GPL(tps65218_reg_write); 70 71 /** 72 * tps65218_update_bits: Modify bits w.r.t mask, val and level. 73 * 74 * @tps: Device to write to. 75 * @reg: Register to read-write to. 76 * @mask: Mask. 77 * @val: Value to write. 78 * @level: Password protected level 79 */ 80 static int tps65218_update_bits(struct tps65218 *tps, unsigned int reg, 81 unsigned int mask, unsigned int val, unsigned int level) 82 { 83 int ret; 84 unsigned int data; 85 86 ret = regmap_read(tps->regmap, reg, &data); 87 if (ret) { 88 dev_err(tps->dev, "Read from reg 0x%x failed\n", reg); 89 return ret; 90 } 91 92 data &= ~mask; 93 data |= val & mask; 94 95 mutex_lock(&tps->tps_lock); 96 ret = tps65218_reg_write(tps, reg, data, level); 97 if (ret) 98 dev_err(tps->dev, "Write for reg 0x%x failed\n", reg); 99 mutex_unlock(&tps->tps_lock); 100 101 return ret; 102 } 103 104 int tps65218_set_bits(struct tps65218 *tps, unsigned int reg, 105 unsigned int mask, unsigned int val, unsigned int level) 106 { 107 return tps65218_update_bits(tps, reg, mask, val, level); 108 } 109 EXPORT_SYMBOL_GPL(tps65218_set_bits); 110 111 int tps65218_clear_bits(struct tps65218 *tps, unsigned int reg, 112 unsigned int mask, unsigned int level) 113 { 114 return tps65218_update_bits(tps, reg, mask, 0, level); 115 } 116 EXPORT_SYMBOL_GPL(tps65218_clear_bits); 117 118 static const struct regmap_range tps65218_yes_ranges[] = { 119 regmap_reg_range(TPS65218_REG_INT1, TPS65218_REG_INT2), 120 regmap_reg_range(TPS65218_REG_STATUS, TPS65218_REG_STATUS), 121 }; 122 123 static const struct regmap_access_table tps65218_volatile_table = { 124 .yes_ranges = tps65218_yes_ranges, 125 .n_yes_ranges = ARRAY_SIZE(tps65218_yes_ranges), 126 }; 127 128 static const struct regmap_config tps65218_regmap_config = { 129 .reg_bits = 8, 130 .val_bits = 8, 131 .cache_type = REGCACHE_RBTREE, 132 .volatile_table = &tps65218_volatile_table, 133 }; 134 135 static const struct regmap_irq tps65218_irqs[] = { 136 /* INT1 IRQs */ 137 [TPS65218_PRGC_IRQ] = { 138 .mask = TPS65218_INT1_PRGC, 139 }, 140 [TPS65218_CC_AQC_IRQ] = { 141 .mask = TPS65218_INT1_CC_AQC, 142 }, 143 [TPS65218_HOT_IRQ] = { 144 .mask = TPS65218_INT1_HOT, 145 }, 146 [TPS65218_PB_IRQ] = { 147 .mask = TPS65218_INT1_PB, 148 }, 149 [TPS65218_AC_IRQ] = { 150 .mask = TPS65218_INT1_AC, 151 }, 152 [TPS65218_VPRG_IRQ] = { 153 .mask = TPS65218_INT1_VPRG, 154 }, 155 [TPS65218_INVALID1_IRQ] = { 156 }, 157 [TPS65218_INVALID2_IRQ] = { 158 }, 159 /* INT2 IRQs*/ 160 [TPS65218_LS1_I_IRQ] = { 161 .mask = TPS65218_INT2_LS1_I, 162 .reg_offset = 1, 163 }, 164 [TPS65218_LS2_I_IRQ] = { 165 .mask = TPS65218_INT2_LS2_I, 166 .reg_offset = 1, 167 }, 168 [TPS65218_LS3_I_IRQ] = { 169 .mask = TPS65218_INT2_LS3_I, 170 .reg_offset = 1, 171 }, 172 [TPS65218_LS1_F_IRQ] = { 173 .mask = TPS65218_INT2_LS1_F, 174 .reg_offset = 1, 175 }, 176 [TPS65218_LS2_F_IRQ] = { 177 .mask = TPS65218_INT2_LS2_F, 178 .reg_offset = 1, 179 }, 180 [TPS65218_LS3_F_IRQ] = { 181 .mask = TPS65218_INT2_LS3_F, 182 .reg_offset = 1, 183 }, 184 [TPS65218_INVALID3_IRQ] = { 185 }, 186 [TPS65218_INVALID4_IRQ] = { 187 }, 188 }; 189 190 static struct regmap_irq_chip tps65218_irq_chip = { 191 .name = "tps65218", 192 .irqs = tps65218_irqs, 193 .num_irqs = ARRAY_SIZE(tps65218_irqs), 194 195 .num_regs = 2, 196 .mask_base = TPS65218_REG_INT_MASK1, 197 .status_base = TPS65218_REG_INT1, 198 }; 199 200 static const struct of_device_id of_tps65218_match_table[] = { 201 { .compatible = "ti,tps65218", }, 202 {} 203 }; 204 MODULE_DEVICE_TABLE(of, of_tps65218_match_table); 205 206 static int tps65218_voltage_set_strict(struct tps65218 *tps) 207 { 208 u32 strict; 209 210 if (of_property_read_u32(tps->dev->of_node, 211 "ti,strict-supply-voltage-supervision", 212 &strict)) 213 return 0; 214 215 if (strict != 0 && strict != 1) { 216 dev_err(tps->dev, 217 "Invalid ti,strict-supply-voltage-supervision value\n"); 218 return -EINVAL; 219 } 220 221 tps65218_update_bits(tps, TPS65218_REG_CONFIG1, 222 TPS65218_CONFIG1_STRICT, 223 strict ? TPS65218_CONFIG1_STRICT : 0, 224 TPS65218_PROTECT_L1); 225 return 0; 226 } 227 228 static int tps65218_voltage_set_uv_hyst(struct tps65218 *tps) 229 { 230 u32 hyst; 231 232 if (of_property_read_u32(tps->dev->of_node, 233 "ti,under-voltage-hyst-microvolt", &hyst)) 234 return 0; 235 236 if (hyst != 400000 && hyst != 200000) { 237 dev_err(tps->dev, 238 "Invalid ti,under-voltage-hyst-microvolt value\n"); 239 return -EINVAL; 240 } 241 242 tps65218_update_bits(tps, TPS65218_REG_CONFIG2, 243 TPS65218_CONFIG2_UVLOHYS, 244 hyst == 400000 ? TPS65218_CONFIG2_UVLOHYS : 0, 245 TPS65218_PROTECT_L1); 246 return 0; 247 } 248 249 static int tps65218_voltage_set_uvlo(struct tps65218 *tps) 250 { 251 u32 uvlo; 252 int uvloval; 253 254 if (of_property_read_u32(tps->dev->of_node, 255 "ti,under-voltage-limit-microvolt", &uvlo)) 256 return 0; 257 258 switch (uvlo) { 259 case 2750000: 260 uvloval = TPS65218_CONFIG1_UVLO_2750000; 261 break; 262 case 2950000: 263 uvloval = TPS65218_CONFIG1_UVLO_2950000; 264 break; 265 case 3250000: 266 uvloval = TPS65218_CONFIG1_UVLO_3250000; 267 break; 268 case 3350000: 269 uvloval = TPS65218_CONFIG1_UVLO_3350000; 270 break; 271 default: 272 dev_err(tps->dev, 273 "Invalid ti,under-voltage-limit-microvolt value\n"); 274 return -EINVAL; 275 } 276 277 tps65218_update_bits(tps, TPS65218_REG_CONFIG1, 278 TPS65218_CONFIG1_UVLO_MASK, uvloval, 279 TPS65218_PROTECT_L1); 280 return 0; 281 } 282 283 static int tps65218_probe(struct i2c_client *client) 284 { 285 struct tps65218 *tps; 286 int ret; 287 unsigned int chipid; 288 289 tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); 290 if (!tps) 291 return -ENOMEM; 292 293 i2c_set_clientdata(client, tps); 294 tps->dev = &client->dev; 295 tps->irq = client->irq; 296 tps->regmap = devm_regmap_init_i2c(client, &tps65218_regmap_config); 297 if (IS_ERR(tps->regmap)) { 298 ret = PTR_ERR(tps->regmap); 299 dev_err(tps->dev, "Failed to allocate register map: %d\n", 300 ret); 301 return ret; 302 } 303 304 mutex_init(&tps->tps_lock); 305 306 ret = devm_regmap_add_irq_chip(&client->dev, tps->regmap, tps->irq, 307 IRQF_ONESHOT, 0, &tps65218_irq_chip, 308 &tps->irq_data); 309 if (ret < 0) 310 return ret; 311 312 ret = regmap_read(tps->regmap, TPS65218_REG_CHIPID, &chipid); 313 if (ret) { 314 dev_err(tps->dev, "Failed to read chipid: %d\n", ret); 315 return ret; 316 } 317 318 tps->rev = chipid & TPS65218_CHIPID_REV_MASK; 319 320 ret = tps65218_voltage_set_strict(tps); 321 if (ret) 322 return ret; 323 324 ret = tps65218_voltage_set_uvlo(tps); 325 if (ret) 326 return ret; 327 328 ret = tps65218_voltage_set_uv_hyst(tps); 329 if (ret) 330 return ret; 331 332 ret = mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65218_cells, 333 ARRAY_SIZE(tps65218_cells), NULL, 0, 334 regmap_irq_get_domain(tps->irq_data)); 335 336 return ret; 337 } 338 339 static const struct i2c_device_id tps65218_id_table[] = { 340 { "tps65218", TPS65218 }, 341 { }, 342 }; 343 MODULE_DEVICE_TABLE(i2c, tps65218_id_table); 344 345 static struct i2c_driver tps65218_driver = { 346 .driver = { 347 .name = "tps65218", 348 .of_match_table = of_tps65218_match_table, 349 }, 350 .probe = tps65218_probe, 351 .id_table = tps65218_id_table, 352 }; 353 354 module_i2c_driver(tps65218_driver); 355 356 MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>"); 357 MODULE_DESCRIPTION("TPS65218 chip family multi-function driver"); 358 MODULE_LICENSE("GPL v2"); 359