Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Driver for TPS65218 Integrated power management chipsets
0004  *
0005  * Copyright (C) 2014 Texas Instruments Incorporated - https://www.ti.com/
0006  */
0007 
0008 #include <linux/kernel.h>
0009 #include <linux/device.h>
0010 #include <linux/module.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/init.h>
0013 #include <linux/i2c.h>
0014 #include <linux/slab.h>
0015 #include <linux/regmap.h>
0016 #include <linux/err.h>
0017 #include <linux/of.h>
0018 #include <linux/of_device.h>
0019 #include <linux/irq.h>
0020 #include <linux/interrupt.h>
0021 #include <linux/mutex.h>
0022 
0023 #include <linux/mfd/core.h>
0024 #include <linux/mfd/tps65218.h>
0025 
0026 #define TPS65218_PASSWORD_REGS_UNLOCK   0x7D
0027 
0028 static const struct mfd_cell tps65218_cells[] = {
0029     {
0030         .name = "tps65218-pwrbutton",
0031         .of_compatible = "ti,tps65218-pwrbutton",
0032     },
0033     {
0034         .name = "tps65218-gpio",
0035         .of_compatible = "ti,tps65218-gpio",
0036     },
0037     { .name = "tps65218-regulator", },
0038 };
0039 
0040 /**
0041  * tps65218_reg_write: Write a single tps65218 register.
0042  *
0043  * @tps: Device to write to.
0044  * @reg: Register to write to.
0045  * @val: Value to write.
0046  * @level: Password protected level
0047  */
0048 int tps65218_reg_write(struct tps65218 *tps, unsigned int reg,
0049             unsigned int val, unsigned int level)
0050 {
0051     int ret;
0052     unsigned int xor_reg_val;
0053 
0054     switch (level) {
0055     case TPS65218_PROTECT_NONE:
0056         return regmap_write(tps->regmap, reg, val);
0057     case TPS65218_PROTECT_L1:
0058         xor_reg_val = reg ^ TPS65218_PASSWORD_REGS_UNLOCK;
0059         ret = regmap_write(tps->regmap, TPS65218_REG_PASSWORD,
0060                             xor_reg_val);
0061         if (ret < 0)
0062             return ret;
0063 
0064         return regmap_write(tps->regmap, reg, val);
0065     default:
0066         return -EINVAL;
0067     }
0068 }
0069 EXPORT_SYMBOL_GPL(tps65218_reg_write);
0070 
0071 /**
0072  * tps65218_update_bits: Modify bits w.r.t mask, val and level.
0073  *
0074  * @tps: Device to write to.
0075  * @reg: Register to read-write to.
0076  * @mask: Mask.
0077  * @val: Value to write.
0078  * @level: Password protected level
0079  */
0080 static int tps65218_update_bits(struct tps65218 *tps, unsigned int reg,
0081         unsigned int mask, unsigned int val, unsigned int level)
0082 {
0083     int ret;
0084     unsigned int data;
0085 
0086     ret = regmap_read(tps->regmap, reg, &data);
0087     if (ret) {
0088         dev_err(tps->dev, "Read from reg 0x%x failed\n", reg);
0089         return ret;
0090     }
0091 
0092     data &= ~mask;
0093     data |= val & mask;
0094 
0095     mutex_lock(&tps->tps_lock);
0096     ret = tps65218_reg_write(tps, reg, data, level);
0097     if (ret)
0098         dev_err(tps->dev, "Write for reg 0x%x failed\n", reg);
0099     mutex_unlock(&tps->tps_lock);
0100 
0101     return ret;
0102 }
0103 
0104 int tps65218_set_bits(struct tps65218 *tps, unsigned int reg,
0105         unsigned int mask, unsigned int val, unsigned int level)
0106 {
0107     return tps65218_update_bits(tps, reg, mask, val, level);
0108 }
0109 EXPORT_SYMBOL_GPL(tps65218_set_bits);
0110 
0111 int tps65218_clear_bits(struct tps65218 *tps, unsigned int reg,
0112         unsigned int mask, unsigned int level)
0113 {
0114     return tps65218_update_bits(tps, reg, mask, 0, level);
0115 }
0116 EXPORT_SYMBOL_GPL(tps65218_clear_bits);
0117 
0118 static const struct regmap_range tps65218_yes_ranges[] = {
0119     regmap_reg_range(TPS65218_REG_INT1, TPS65218_REG_INT2),
0120     regmap_reg_range(TPS65218_REG_STATUS, TPS65218_REG_STATUS),
0121 };
0122 
0123 static const struct regmap_access_table tps65218_volatile_table = {
0124     .yes_ranges = tps65218_yes_ranges,
0125     .n_yes_ranges = ARRAY_SIZE(tps65218_yes_ranges),
0126 };
0127 
0128 static const struct regmap_config tps65218_regmap_config = {
0129     .reg_bits = 8,
0130     .val_bits = 8,
0131     .cache_type = REGCACHE_RBTREE,
0132     .volatile_table = &tps65218_volatile_table,
0133 };
0134 
0135 static const struct regmap_irq tps65218_irqs[] = {
0136     /* INT1 IRQs */
0137     [TPS65218_PRGC_IRQ] = {
0138         .mask = TPS65218_INT1_PRGC,
0139     },
0140     [TPS65218_CC_AQC_IRQ] = {
0141         .mask = TPS65218_INT1_CC_AQC,
0142     },
0143     [TPS65218_HOT_IRQ] = {
0144         .mask = TPS65218_INT1_HOT,
0145     },
0146     [TPS65218_PB_IRQ] = {
0147         .mask = TPS65218_INT1_PB,
0148     },
0149     [TPS65218_AC_IRQ] = {
0150         .mask = TPS65218_INT1_AC,
0151     },
0152     [TPS65218_VPRG_IRQ] = {
0153         .mask = TPS65218_INT1_VPRG,
0154     },
0155     [TPS65218_INVALID1_IRQ] = {
0156     },
0157     [TPS65218_INVALID2_IRQ] = {
0158     },
0159     /* INT2 IRQs*/
0160     [TPS65218_LS1_I_IRQ] = {
0161         .mask = TPS65218_INT2_LS1_I,
0162         .reg_offset = 1,
0163     },
0164     [TPS65218_LS2_I_IRQ] = {
0165         .mask = TPS65218_INT2_LS2_I,
0166         .reg_offset = 1,
0167     },
0168     [TPS65218_LS3_I_IRQ] = {
0169         .mask = TPS65218_INT2_LS3_I,
0170         .reg_offset = 1,
0171     },
0172     [TPS65218_LS1_F_IRQ] = {
0173         .mask = TPS65218_INT2_LS1_F,
0174         .reg_offset = 1,
0175     },
0176     [TPS65218_LS2_F_IRQ] = {
0177         .mask = TPS65218_INT2_LS2_F,
0178         .reg_offset = 1,
0179     },
0180     [TPS65218_LS3_F_IRQ] = {
0181         .mask = TPS65218_INT2_LS3_F,
0182         .reg_offset = 1,
0183     },
0184     [TPS65218_INVALID3_IRQ] = {
0185     },
0186     [TPS65218_INVALID4_IRQ] = {
0187     },
0188 };
0189 
0190 static struct regmap_irq_chip tps65218_irq_chip = {
0191     .name = "tps65218",
0192     .irqs = tps65218_irqs,
0193     .num_irqs = ARRAY_SIZE(tps65218_irqs),
0194 
0195     .num_regs = 2,
0196     .mask_base = TPS65218_REG_INT_MASK1,
0197     .status_base = TPS65218_REG_INT1,
0198 };
0199 
0200 static const struct of_device_id of_tps65218_match_table[] = {
0201     { .compatible = "ti,tps65218", },
0202     {}
0203 };
0204 MODULE_DEVICE_TABLE(of, of_tps65218_match_table);
0205 
0206 static int tps65218_voltage_set_strict(struct tps65218 *tps)
0207 {
0208     u32 strict;
0209 
0210     if (of_property_read_u32(tps->dev->of_node,
0211                  "ti,strict-supply-voltage-supervision",
0212                  &strict))
0213         return 0;
0214 
0215     if (strict != 0 && strict != 1) {
0216         dev_err(tps->dev,
0217             "Invalid ti,strict-supply-voltage-supervision value\n");
0218         return -EINVAL;
0219     }
0220 
0221     tps65218_update_bits(tps, TPS65218_REG_CONFIG1,
0222                  TPS65218_CONFIG1_STRICT,
0223                  strict ? TPS65218_CONFIG1_STRICT : 0,
0224                  TPS65218_PROTECT_L1);
0225     return 0;
0226 }
0227 
0228 static int tps65218_voltage_set_uv_hyst(struct tps65218 *tps)
0229 {
0230     u32 hyst;
0231 
0232     if (of_property_read_u32(tps->dev->of_node,
0233                  "ti,under-voltage-hyst-microvolt", &hyst))
0234         return 0;
0235 
0236     if (hyst != 400000 && hyst != 200000) {
0237         dev_err(tps->dev,
0238             "Invalid ti,under-voltage-hyst-microvolt value\n");
0239         return -EINVAL;
0240     }
0241 
0242     tps65218_update_bits(tps, TPS65218_REG_CONFIG2,
0243                  TPS65218_CONFIG2_UVLOHYS,
0244                  hyst == 400000 ? TPS65218_CONFIG2_UVLOHYS : 0,
0245                  TPS65218_PROTECT_L1);
0246     return 0;
0247 }
0248 
0249 static int tps65218_voltage_set_uvlo(struct tps65218 *tps)
0250 {
0251     u32 uvlo;
0252     int uvloval;
0253 
0254     if (of_property_read_u32(tps->dev->of_node,
0255                  "ti,under-voltage-limit-microvolt", &uvlo))
0256         return 0;
0257 
0258     switch (uvlo) {
0259     case 2750000:
0260         uvloval = TPS65218_CONFIG1_UVLO_2750000;
0261         break;
0262     case 2950000:
0263         uvloval = TPS65218_CONFIG1_UVLO_2950000;
0264         break;
0265     case 3250000:
0266         uvloval = TPS65218_CONFIG1_UVLO_3250000;
0267         break;
0268     case 3350000:
0269         uvloval = TPS65218_CONFIG1_UVLO_3350000;
0270         break;
0271     default:
0272         dev_err(tps->dev,
0273             "Invalid ti,under-voltage-limit-microvolt value\n");
0274         return -EINVAL;
0275     }
0276 
0277     tps65218_update_bits(tps, TPS65218_REG_CONFIG1,
0278                  TPS65218_CONFIG1_UVLO_MASK, uvloval,
0279                  TPS65218_PROTECT_L1);
0280     return 0;
0281 }
0282 
0283 static int tps65218_probe(struct i2c_client *client,
0284                 const struct i2c_device_id *ids)
0285 {
0286     struct tps65218 *tps;
0287     int ret;
0288     unsigned int chipid;
0289 
0290     tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
0291     if (!tps)
0292         return -ENOMEM;
0293 
0294     i2c_set_clientdata(client, tps);
0295     tps->dev = &client->dev;
0296     tps->irq = client->irq;
0297     tps->regmap = devm_regmap_init_i2c(client, &tps65218_regmap_config);
0298     if (IS_ERR(tps->regmap)) {
0299         ret = PTR_ERR(tps->regmap);
0300         dev_err(tps->dev, "Failed to allocate register map: %d\n",
0301             ret);
0302         return ret;
0303     }
0304 
0305     mutex_init(&tps->tps_lock);
0306 
0307     ret = devm_regmap_add_irq_chip(&client->dev, tps->regmap, tps->irq,
0308                        IRQF_ONESHOT, 0, &tps65218_irq_chip,
0309                        &tps->irq_data);
0310     if (ret < 0)
0311         return ret;
0312 
0313     ret = regmap_read(tps->regmap, TPS65218_REG_CHIPID, &chipid);
0314     if (ret) {
0315         dev_err(tps->dev, "Failed to read chipid: %d\n", ret);
0316         return ret;
0317     }
0318 
0319     tps->rev = chipid & TPS65218_CHIPID_REV_MASK;
0320 
0321     ret = tps65218_voltage_set_strict(tps);
0322     if (ret)
0323         return ret;
0324 
0325     ret = tps65218_voltage_set_uvlo(tps);
0326     if (ret)
0327         return ret;
0328 
0329     ret = tps65218_voltage_set_uv_hyst(tps);
0330     if (ret)
0331         return ret;
0332 
0333     ret = mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65218_cells,
0334                   ARRAY_SIZE(tps65218_cells), NULL, 0,
0335                   regmap_irq_get_domain(tps->irq_data));
0336 
0337     return ret;
0338 }
0339 
0340 static const struct i2c_device_id tps65218_id_table[] = {
0341     { "tps65218", TPS65218 },
0342     { },
0343 };
0344 MODULE_DEVICE_TABLE(i2c, tps65218_id_table);
0345 
0346 static struct i2c_driver tps65218_driver = {
0347     .driver     = {
0348         .name   = "tps65218",
0349         .of_match_table = of_tps65218_match_table,
0350     },
0351     .probe      = tps65218_probe,
0352     .id_table       = tps65218_id_table,
0353 };
0354 
0355 module_i2c_driver(tps65218_driver);
0356 
0357 MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>");
0358 MODULE_DESCRIPTION("TPS65218 chip family multi-function driver");
0359 MODULE_LICENSE("GPL v2");