Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Core driver for TI TPS65090 PMIC family
0004  *
0005  * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
0006  *
0007  * Author: Venu Byravarasu <vbyravarasu@nvidia.com>
0008  */
0009 
0010 #include <linux/interrupt.h>
0011 #include <linux/irq.h>
0012 #include <linux/kernel.h>
0013 #include <linux/init.h>
0014 #include <linux/mutex.h>
0015 #include <linux/slab.h>
0016 #include <linux/i2c.h>
0017 #include <linux/mfd/core.h>
0018 #include <linux/mfd/tps65090.h>
0019 #include <linux/of.h>
0020 #include <linux/of_device.h>
0021 #include <linux/err.h>
0022 
0023 #define NUM_INT_REG 2
0024 
0025 #define TPS65090_INT1_MASK_VAC_STATUS_CHANGE        1
0026 #define TPS65090_INT1_MASK_VSYS_STATUS_CHANGE       2
0027 #define TPS65090_INT1_MASK_BAT_STATUS_CHANGE        3
0028 #define TPS65090_INT1_MASK_CHARGING_STATUS_CHANGE   4
0029 #define TPS65090_INT1_MASK_CHARGING_COMPLETE        5
0030 #define TPS65090_INT1_MASK_OVERLOAD_DCDC1       6
0031 #define TPS65090_INT1_MASK_OVERLOAD_DCDC2       7
0032 #define TPS65090_INT2_MASK_OVERLOAD_DCDC3       0
0033 #define TPS65090_INT2_MASK_OVERLOAD_FET1        1
0034 #define TPS65090_INT2_MASK_OVERLOAD_FET2        2
0035 #define TPS65090_INT2_MASK_OVERLOAD_FET3        3
0036 #define TPS65090_INT2_MASK_OVERLOAD_FET4        4
0037 #define TPS65090_INT2_MASK_OVERLOAD_FET5        5
0038 #define TPS65090_INT2_MASK_OVERLOAD_FET6        6
0039 #define TPS65090_INT2_MASK_OVERLOAD_FET7        7
0040 
0041 static const struct resource charger_resources[] = {
0042     {
0043         .start  = TPS65090_IRQ_VAC_STATUS_CHANGE,
0044         .end    = TPS65090_IRQ_VAC_STATUS_CHANGE,
0045         .flags  = IORESOURCE_IRQ,
0046     }
0047 };
0048 
0049 enum tps65090_cells {
0050     PMIC = 0,
0051     CHARGER = 1,
0052 };
0053 
0054 static struct mfd_cell tps65090s[] = {
0055     [PMIC] = {
0056         .name = "tps65090-pmic",
0057     },
0058     [CHARGER] = {
0059         .name = "tps65090-charger",
0060         .num_resources = ARRAY_SIZE(charger_resources),
0061         .resources = &charger_resources[0],
0062         .of_compatible = "ti,tps65090-charger",
0063     },
0064 };
0065 
0066 static const struct regmap_irq tps65090_irqs[] = {
0067     /* INT1 IRQs*/
0068     [TPS65090_IRQ_VAC_STATUS_CHANGE] = {
0069         .mask = TPS65090_INT1_MASK_VAC_STATUS_CHANGE,
0070     },
0071     [TPS65090_IRQ_VSYS_STATUS_CHANGE] = {
0072         .mask = TPS65090_INT1_MASK_VSYS_STATUS_CHANGE,
0073     },
0074     [TPS65090_IRQ_BAT_STATUS_CHANGE] = {
0075         .mask = TPS65090_INT1_MASK_BAT_STATUS_CHANGE,
0076     },
0077     [TPS65090_IRQ_CHARGING_STATUS_CHANGE] = {
0078         .mask = TPS65090_INT1_MASK_CHARGING_STATUS_CHANGE,
0079     },
0080     [TPS65090_IRQ_CHARGING_COMPLETE] = {
0081         .mask = TPS65090_INT1_MASK_CHARGING_COMPLETE,
0082     },
0083     [TPS65090_IRQ_OVERLOAD_DCDC1] = {
0084         .mask = TPS65090_INT1_MASK_OVERLOAD_DCDC1,
0085     },
0086     [TPS65090_IRQ_OVERLOAD_DCDC2] = {
0087         .mask = TPS65090_INT1_MASK_OVERLOAD_DCDC2,
0088     },
0089     /* INT2 IRQs*/
0090     [TPS65090_IRQ_OVERLOAD_DCDC3] = {
0091         .reg_offset = 1,
0092         .mask = TPS65090_INT2_MASK_OVERLOAD_DCDC3,
0093     },
0094     [TPS65090_IRQ_OVERLOAD_FET1] = {
0095         .reg_offset = 1,
0096         .mask = TPS65090_INT2_MASK_OVERLOAD_FET1,
0097     },
0098     [TPS65090_IRQ_OVERLOAD_FET2] = {
0099         .reg_offset = 1,
0100         .mask = TPS65090_INT2_MASK_OVERLOAD_FET2,
0101     },
0102     [TPS65090_IRQ_OVERLOAD_FET3] = {
0103         .reg_offset = 1,
0104         .mask = TPS65090_INT2_MASK_OVERLOAD_FET3,
0105     },
0106     [TPS65090_IRQ_OVERLOAD_FET4] = {
0107         .reg_offset = 1,
0108         .mask = TPS65090_INT2_MASK_OVERLOAD_FET4,
0109     },
0110     [TPS65090_IRQ_OVERLOAD_FET5] = {
0111         .reg_offset = 1,
0112         .mask = TPS65090_INT2_MASK_OVERLOAD_FET5,
0113     },
0114     [TPS65090_IRQ_OVERLOAD_FET6] = {
0115         .reg_offset = 1,
0116         .mask = TPS65090_INT2_MASK_OVERLOAD_FET6,
0117     },
0118     [TPS65090_IRQ_OVERLOAD_FET7] = {
0119         .reg_offset = 1,
0120         .mask = TPS65090_INT2_MASK_OVERLOAD_FET7,
0121     },
0122 };
0123 
0124 static struct regmap_irq_chip tps65090_irq_chip = {
0125     .name = "tps65090",
0126     .irqs = tps65090_irqs,
0127     .num_irqs = ARRAY_SIZE(tps65090_irqs),
0128     .num_regs = NUM_INT_REG,
0129     .status_base = TPS65090_REG_INTR_STS,
0130     .mask_base = TPS65090_REG_INTR_MASK,
0131     .mask_invert = true,
0132 };
0133 
0134 static bool is_volatile_reg(struct device *dev, unsigned int reg)
0135 {
0136     /* Nearly all registers have status bits mixed in, except a few */
0137     switch (reg) {
0138     case TPS65090_REG_INTR_MASK:
0139     case TPS65090_REG_INTR_MASK2:
0140     case TPS65090_REG_CG_CTRL0:
0141     case TPS65090_REG_CG_CTRL1:
0142     case TPS65090_REG_CG_CTRL2:
0143     case TPS65090_REG_CG_CTRL3:
0144     case TPS65090_REG_CG_CTRL4:
0145     case TPS65090_REG_CG_CTRL5:
0146         return false;
0147     }
0148     return true;
0149 }
0150 
0151 static const struct regmap_config tps65090_regmap_config = {
0152     .reg_bits = 8,
0153     .val_bits = 8,
0154     .max_register = TPS65090_MAX_REG,
0155     .num_reg_defaults_raw = TPS65090_NUM_REGS,
0156     .cache_type = REGCACHE_RBTREE,
0157     .volatile_reg = is_volatile_reg,
0158 };
0159 
0160 #ifdef CONFIG_OF
0161 static const struct of_device_id tps65090_of_match[] = {
0162     { .compatible = "ti,tps65090",},
0163     {},
0164 };
0165 #endif
0166 
0167 static int tps65090_i2c_probe(struct i2c_client *client,
0168                   const struct i2c_device_id *id)
0169 {
0170     struct tps65090_platform_data *pdata = dev_get_platdata(&client->dev);
0171     int irq_base = 0;
0172     struct tps65090 *tps65090;
0173     int ret;
0174 
0175     if (!pdata && !client->dev.of_node) {
0176         dev_err(&client->dev,
0177             "tps65090 requires platform data or of_node\n");
0178         return -EINVAL;
0179     }
0180 
0181     if (pdata)
0182         irq_base = pdata->irq_base;
0183 
0184     tps65090 = devm_kzalloc(&client->dev, sizeof(*tps65090), GFP_KERNEL);
0185     if (!tps65090)
0186         return -ENOMEM;
0187 
0188     tps65090->dev = &client->dev;
0189     i2c_set_clientdata(client, tps65090);
0190 
0191     tps65090->rmap = devm_regmap_init_i2c(client, &tps65090_regmap_config);
0192     if (IS_ERR(tps65090->rmap)) {
0193         ret = PTR_ERR(tps65090->rmap);
0194         dev_err(&client->dev, "regmap_init failed with err: %d\n", ret);
0195         return ret;
0196     }
0197 
0198     if (client->irq) {
0199         ret = regmap_add_irq_chip(tps65090->rmap, client->irq,
0200                       IRQF_ONESHOT | IRQF_TRIGGER_LOW, irq_base,
0201                       &tps65090_irq_chip, &tps65090->irq_data);
0202         if (ret) {
0203             dev_err(&client->dev,
0204                 "IRQ init failed with err: %d\n", ret);
0205             return ret;
0206         }
0207     } else {
0208         /* Don't tell children they have an IRQ that'll never fire */
0209         tps65090s[CHARGER].num_resources = 0;
0210     }
0211 
0212     ret = mfd_add_devices(tps65090->dev, -1, tps65090s,
0213                   ARRAY_SIZE(tps65090s), NULL,
0214                   0, regmap_irq_get_domain(tps65090->irq_data));
0215     if (ret) {
0216         dev_err(&client->dev, "add mfd devices failed with err: %d\n",
0217             ret);
0218         goto err_irq_exit;
0219     }
0220 
0221     return 0;
0222 
0223 err_irq_exit:
0224     if (client->irq)
0225         regmap_del_irq_chip(client->irq, tps65090->irq_data);
0226     return ret;
0227 }
0228 
0229 
0230 static const struct i2c_device_id tps65090_id_table[] = {
0231     { "tps65090", 0 },
0232     { },
0233 };
0234 
0235 static struct i2c_driver tps65090_driver = {
0236     .driver = {
0237         .name   = "tps65090",
0238         .suppress_bind_attrs = true,
0239         .of_match_table = of_match_ptr(tps65090_of_match),
0240     },
0241     .probe      = tps65090_i2c_probe,
0242     .id_table   = tps65090_id_table,
0243 };
0244 
0245 static int __init tps65090_init(void)
0246 {
0247     return i2c_add_driver(&tps65090_driver);
0248 }
0249 subsys_initcall(tps65090_init);