root/drivers/mfd/tps65090.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. is_volatile_reg
  2. tps65090_i2c_probe
  3. tps65090_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Core driver for TI TPS65090 PMIC family
   4  *
   5  * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
   6  *
   7  * Author: Venu Byravarasu <vbyravarasu@nvidia.com>
   8  */
   9 
  10 #include <linux/interrupt.h>
  11 #include <linux/irq.h>
  12 #include <linux/kernel.h>
  13 #include <linux/init.h>
  14 #include <linux/mutex.h>
  15 #include <linux/slab.h>
  16 #include <linux/i2c.h>
  17 #include <linux/mfd/core.h>
  18 #include <linux/mfd/tps65090.h>
  19 #include <linux/of.h>
  20 #include <linux/of_device.h>
  21 #include <linux/err.h>
  22 
  23 #define NUM_INT_REG 2
  24 
  25 #define TPS65090_INT1_MASK_VAC_STATUS_CHANGE            1
  26 #define TPS65090_INT1_MASK_VSYS_STATUS_CHANGE           2
  27 #define TPS65090_INT1_MASK_BAT_STATUS_CHANGE            3
  28 #define TPS65090_INT1_MASK_CHARGING_STATUS_CHANGE       4
  29 #define TPS65090_INT1_MASK_CHARGING_COMPLETE            5
  30 #define TPS65090_INT1_MASK_OVERLOAD_DCDC1               6
  31 #define TPS65090_INT1_MASK_OVERLOAD_DCDC2               7
  32 #define TPS65090_INT2_MASK_OVERLOAD_DCDC3               0
  33 #define TPS65090_INT2_MASK_OVERLOAD_FET1                1
  34 #define TPS65090_INT2_MASK_OVERLOAD_FET2                2
  35 #define TPS65090_INT2_MASK_OVERLOAD_FET3                3
  36 #define TPS65090_INT2_MASK_OVERLOAD_FET4                4
  37 #define TPS65090_INT2_MASK_OVERLOAD_FET5                5
  38 #define TPS65090_INT2_MASK_OVERLOAD_FET6                6
  39 #define TPS65090_INT2_MASK_OVERLOAD_FET7                7
  40 
  41 static struct resource charger_resources[] = {
  42         {
  43                 .start  = TPS65090_IRQ_VAC_STATUS_CHANGE,
  44                 .end    = TPS65090_IRQ_VAC_STATUS_CHANGE,
  45                 .flags  = IORESOURCE_IRQ,
  46         }
  47 };
  48 
  49 enum tps65090_cells {
  50         PMIC = 0,
  51         CHARGER = 1,
  52 };
  53 
  54 static struct mfd_cell tps65090s[] = {
  55         [PMIC] = {
  56                 .name = "tps65090-pmic",
  57         },
  58         [CHARGER] = {
  59                 .name = "tps65090-charger",
  60                 .num_resources = ARRAY_SIZE(charger_resources),
  61                 .resources = &charger_resources[0],
  62                 .of_compatible = "ti,tps65090-charger",
  63         },
  64 };
  65 
  66 static const struct regmap_irq tps65090_irqs[] = {
  67         /* INT1 IRQs*/
  68         [TPS65090_IRQ_VAC_STATUS_CHANGE] = {
  69                 .mask = TPS65090_INT1_MASK_VAC_STATUS_CHANGE,
  70         },
  71         [TPS65090_IRQ_VSYS_STATUS_CHANGE] = {
  72                 .mask = TPS65090_INT1_MASK_VSYS_STATUS_CHANGE,
  73         },
  74         [TPS65090_IRQ_BAT_STATUS_CHANGE] = {
  75                 .mask = TPS65090_INT1_MASK_BAT_STATUS_CHANGE,
  76         },
  77         [TPS65090_IRQ_CHARGING_STATUS_CHANGE] = {
  78                 .mask = TPS65090_INT1_MASK_CHARGING_STATUS_CHANGE,
  79         },
  80         [TPS65090_IRQ_CHARGING_COMPLETE] = {
  81                 .mask = TPS65090_INT1_MASK_CHARGING_COMPLETE,
  82         },
  83         [TPS65090_IRQ_OVERLOAD_DCDC1] = {
  84                 .mask = TPS65090_INT1_MASK_OVERLOAD_DCDC1,
  85         },
  86         [TPS65090_IRQ_OVERLOAD_DCDC2] = {
  87                 .mask = TPS65090_INT1_MASK_OVERLOAD_DCDC2,
  88         },
  89         /* INT2 IRQs*/
  90         [TPS65090_IRQ_OVERLOAD_DCDC3] = {
  91                 .reg_offset = 1,
  92                 .mask = TPS65090_INT2_MASK_OVERLOAD_DCDC3,
  93         },
  94         [TPS65090_IRQ_OVERLOAD_FET1] = {
  95                 .reg_offset = 1,
  96                 .mask = TPS65090_INT2_MASK_OVERLOAD_FET1,
  97         },
  98         [TPS65090_IRQ_OVERLOAD_FET2] = {
  99                 .reg_offset = 1,
 100                 .mask = TPS65090_INT2_MASK_OVERLOAD_FET2,
 101         },
 102         [TPS65090_IRQ_OVERLOAD_FET3] = {
 103                 .reg_offset = 1,
 104                 .mask = TPS65090_INT2_MASK_OVERLOAD_FET3,
 105         },
 106         [TPS65090_IRQ_OVERLOAD_FET4] = {
 107                 .reg_offset = 1,
 108                 .mask = TPS65090_INT2_MASK_OVERLOAD_FET4,
 109         },
 110         [TPS65090_IRQ_OVERLOAD_FET5] = {
 111                 .reg_offset = 1,
 112                 .mask = TPS65090_INT2_MASK_OVERLOAD_FET5,
 113         },
 114         [TPS65090_IRQ_OVERLOAD_FET6] = {
 115                 .reg_offset = 1,
 116                 .mask = TPS65090_INT2_MASK_OVERLOAD_FET6,
 117         },
 118         [TPS65090_IRQ_OVERLOAD_FET7] = {
 119                 .reg_offset = 1,
 120                 .mask = TPS65090_INT2_MASK_OVERLOAD_FET7,
 121         },
 122 };
 123 
 124 static struct regmap_irq_chip tps65090_irq_chip = {
 125         .name = "tps65090",
 126         .irqs = tps65090_irqs,
 127         .num_irqs = ARRAY_SIZE(tps65090_irqs),
 128         .num_regs = NUM_INT_REG,
 129         .status_base = TPS65090_REG_INTR_STS,
 130         .mask_base = TPS65090_REG_INTR_MASK,
 131         .mask_invert = true,
 132 };
 133 
 134 static bool is_volatile_reg(struct device *dev, unsigned int reg)
 135 {
 136         /* Nearly all registers have status bits mixed in, except a few */
 137         switch (reg) {
 138         case TPS65090_REG_INTR_MASK:
 139         case TPS65090_REG_INTR_MASK2:
 140         case TPS65090_REG_CG_CTRL0:
 141         case TPS65090_REG_CG_CTRL1:
 142         case TPS65090_REG_CG_CTRL2:
 143         case TPS65090_REG_CG_CTRL3:
 144         case TPS65090_REG_CG_CTRL4:
 145         case TPS65090_REG_CG_CTRL5:
 146                 return false;
 147         }
 148         return true;
 149 }
 150 
 151 static const struct regmap_config tps65090_regmap_config = {
 152         .reg_bits = 8,
 153         .val_bits = 8,
 154         .max_register = TPS65090_MAX_REG,
 155         .num_reg_defaults_raw = TPS65090_NUM_REGS,
 156         .cache_type = REGCACHE_RBTREE,
 157         .volatile_reg = is_volatile_reg,
 158 };
 159 
 160 #ifdef CONFIG_OF
 161 static const struct of_device_id tps65090_of_match[] = {
 162         { .compatible = "ti,tps65090",},
 163         {},
 164 };
 165 #endif
 166 
 167 static int tps65090_i2c_probe(struct i2c_client *client,
 168                               const struct i2c_device_id *id)
 169 {
 170         struct tps65090_platform_data *pdata = dev_get_platdata(&client->dev);
 171         int irq_base = 0;
 172         struct tps65090 *tps65090;
 173         int ret;
 174 
 175         if (!pdata && !client->dev.of_node) {
 176                 dev_err(&client->dev,
 177                         "tps65090 requires platform data or of_node\n");
 178                 return -EINVAL;
 179         }
 180 
 181         if (pdata)
 182                 irq_base = pdata->irq_base;
 183 
 184         tps65090 = devm_kzalloc(&client->dev, sizeof(*tps65090), GFP_KERNEL);
 185         if (!tps65090)
 186                 return -ENOMEM;
 187 
 188         tps65090->dev = &client->dev;
 189         i2c_set_clientdata(client, tps65090);
 190 
 191         tps65090->rmap = devm_regmap_init_i2c(client, &tps65090_regmap_config);
 192         if (IS_ERR(tps65090->rmap)) {
 193                 ret = PTR_ERR(tps65090->rmap);
 194                 dev_err(&client->dev, "regmap_init failed with err: %d\n", ret);
 195                 return ret;
 196         }
 197 
 198         if (client->irq) {
 199                 ret = regmap_add_irq_chip(tps65090->rmap, client->irq,
 200                                           IRQF_ONESHOT | IRQF_TRIGGER_LOW, irq_base,
 201                                           &tps65090_irq_chip, &tps65090->irq_data);
 202                 if (ret) {
 203                         dev_err(&client->dev,
 204                                 "IRQ init failed with err: %d\n", ret);
 205                         return ret;
 206                 }
 207         } else {
 208                 /* Don't tell children they have an IRQ that'll never fire */
 209                 tps65090s[CHARGER].num_resources = 0;
 210         }
 211 
 212         ret = mfd_add_devices(tps65090->dev, -1, tps65090s,
 213                               ARRAY_SIZE(tps65090s), NULL,
 214                               0, regmap_irq_get_domain(tps65090->irq_data));
 215         if (ret) {
 216                 dev_err(&client->dev, "add mfd devices failed with err: %d\n",
 217                         ret);
 218                 goto err_irq_exit;
 219         }
 220 
 221         return 0;
 222 
 223 err_irq_exit:
 224         if (client->irq)
 225                 regmap_del_irq_chip(client->irq, tps65090->irq_data);
 226         return ret;
 227 }
 228 
 229 
 230 static const struct i2c_device_id tps65090_id_table[] = {
 231         { "tps65090", 0 },
 232         { },
 233 };
 234 
 235 static struct i2c_driver tps65090_driver = {
 236         .driver = {
 237                 .name   = "tps65090",
 238                 .suppress_bind_attrs = true,
 239                 .of_match_table = of_match_ptr(tps65090_of_match),
 240         },
 241         .probe          = tps65090_i2c_probe,
 242         .id_table       = tps65090_id_table,
 243 };
 244 
 245 static int __init tps65090_init(void)
 246 {
 247         return i2c_add_driver(&tps65090_driver);
 248 }
 249 subsys_initcall(tps65090_init);

/* [<][>][^][v][top][bottom][index][help] */