root/drivers/mfd/tps65217.c

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

DEFINITIONS

This source file includes following definitions.
  1. tps65217_irq_lock
  2. tps65217_irq_sync_unlock
  3. tps65217_irq_enable
  4. tps65217_irq_disable
  5. tps65217_irq_thread
  6. tps65217_irq_map
  7. tps65217_irq_init
  8. tps65217_reg_read
  9. tps65217_reg_write
  10. tps65217_update_bits
  11. tps65217_set_bits
  12. tps65217_clear_bits
  13. tps65217_volatile_reg
  14. tps65217_probe
  15. tps65217_remove
  16. tps65217_init
  17. tps65217_exit

   1 /*
   2  * tps65217.c
   3  *
   4  * TPS65217 chip family multi-function driver
   5  *
   6  * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
   7  *
   8  * This program is free software; you can redistribute it and/or
   9  * modify it under the terms of the GNU General Public License as
  10  * published by the Free Software Foundation version 2.
  11  *
  12  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  13  * kind, whether express or implied; without even the implied warranty
  14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15  * GNU General Public License for more details.
  16  */
  17 
  18 #include <linux/device.h>
  19 #include <linux/err.h>
  20 #include <linux/init.h>
  21 #include <linux/interrupt.h>
  22 #include <linux/i2c.h>
  23 #include <linux/irq.h>
  24 #include <linux/irqdomain.h>
  25 #include <linux/kernel.h>
  26 #include <linux/module.h>
  27 #include <linux/of.h>
  28 #include <linux/of_device.h>
  29 #include <linux/platform_device.h>
  30 #include <linux/regmap.h>
  31 #include <linux/slab.h>
  32 
  33 #include <linux/mfd/core.h>
  34 #include <linux/mfd/tps65217.h>
  35 
  36 static struct resource charger_resources[] = {
  37         DEFINE_RES_IRQ_NAMED(TPS65217_IRQ_AC, "AC"),
  38         DEFINE_RES_IRQ_NAMED(TPS65217_IRQ_USB, "USB"),
  39 };
  40 
  41 static struct resource pb_resources[] = {
  42         DEFINE_RES_IRQ_NAMED(TPS65217_IRQ_PB, "PB"),
  43 };
  44 
  45 static void tps65217_irq_lock(struct irq_data *data)
  46 {
  47         struct tps65217 *tps = irq_data_get_irq_chip_data(data);
  48 
  49         mutex_lock(&tps->irq_lock);
  50 }
  51 
  52 static void tps65217_irq_sync_unlock(struct irq_data *data)
  53 {
  54         struct tps65217 *tps = irq_data_get_irq_chip_data(data);
  55         int ret;
  56 
  57         ret = tps65217_set_bits(tps, TPS65217_REG_INT, TPS65217_INT_MASK,
  58                                 tps->irq_mask, TPS65217_PROTECT_NONE);
  59         if (ret != 0)
  60                 dev_err(tps->dev, "Failed to sync IRQ masks\n");
  61 
  62         mutex_unlock(&tps->irq_lock);
  63 }
  64 
  65 static void tps65217_irq_enable(struct irq_data *data)
  66 {
  67         struct tps65217 *tps = irq_data_get_irq_chip_data(data);
  68         u8 mask = BIT(data->hwirq) << TPS65217_INT_SHIFT;
  69 
  70         tps->irq_mask &= ~mask;
  71 }
  72 
  73 static void tps65217_irq_disable(struct irq_data *data)
  74 {
  75         struct tps65217 *tps = irq_data_get_irq_chip_data(data);
  76         u8 mask = BIT(data->hwirq) << TPS65217_INT_SHIFT;
  77 
  78         tps->irq_mask |= mask;
  79 }
  80 
  81 static struct irq_chip tps65217_irq_chip = {
  82         .name                   = "tps65217",
  83         .irq_bus_lock           = tps65217_irq_lock,
  84         .irq_bus_sync_unlock    = tps65217_irq_sync_unlock,
  85         .irq_enable             = tps65217_irq_enable,
  86         .irq_disable            = tps65217_irq_disable,
  87 };
  88 
  89 static struct mfd_cell tps65217s[] = {
  90         {
  91                 .name = "tps65217-pmic",
  92                 .of_compatible = "ti,tps65217-pmic",
  93         },
  94         {
  95                 .name = "tps65217-bl",
  96                 .of_compatible = "ti,tps65217-bl",
  97         },
  98         {
  99                 .name = "tps65217-charger",
 100                 .num_resources = ARRAY_SIZE(charger_resources),
 101                 .resources = charger_resources,
 102                 .of_compatible = "ti,tps65217-charger",
 103         },
 104         {
 105                 .name = "tps65217-pwrbutton",
 106                 .num_resources = ARRAY_SIZE(pb_resources),
 107                 .resources = pb_resources,
 108                 .of_compatible = "ti,tps65217-pwrbutton",
 109         },
 110 };
 111 
 112 static irqreturn_t tps65217_irq_thread(int irq, void *data)
 113 {
 114         struct tps65217 *tps = data;
 115         unsigned int status;
 116         bool handled = false;
 117         int i;
 118         int ret;
 119 
 120         ret = tps65217_reg_read(tps, TPS65217_REG_INT, &status);
 121         if (ret < 0) {
 122                 dev_err(tps->dev, "Failed to read IRQ status: %d\n",
 123                         ret);
 124                 return IRQ_NONE;
 125         }
 126 
 127         for (i = 0; i < TPS65217_NUM_IRQ; i++) {
 128                 if (status & BIT(i)) {
 129                         handle_nested_irq(irq_find_mapping(tps->irq_domain, i));
 130                         handled = true;
 131                 }
 132         }
 133 
 134         if (handled)
 135                 return IRQ_HANDLED;
 136 
 137         return IRQ_NONE;
 138 }
 139 
 140 static int tps65217_irq_map(struct irq_domain *h, unsigned int virq,
 141                         irq_hw_number_t hw)
 142 {
 143         struct tps65217 *tps = h->host_data;
 144 
 145         irq_set_chip_data(virq, tps);
 146         irq_set_chip_and_handler(virq, &tps65217_irq_chip, handle_edge_irq);
 147         irq_set_nested_thread(virq, 1);
 148         irq_set_parent(virq, tps->irq);
 149         irq_set_noprobe(virq);
 150 
 151         return 0;
 152 }
 153 
 154 static const struct irq_domain_ops tps65217_irq_domain_ops = {
 155         .map = tps65217_irq_map,
 156 };
 157 
 158 static int tps65217_irq_init(struct tps65217 *tps, int irq)
 159 {
 160         int ret;
 161 
 162         mutex_init(&tps->irq_lock);
 163         tps->irq = irq;
 164 
 165         /* Mask all interrupt sources */
 166         tps->irq_mask = TPS65217_INT_MASK;
 167         tps65217_set_bits(tps, TPS65217_REG_INT, TPS65217_INT_MASK,
 168                           TPS65217_INT_MASK, TPS65217_PROTECT_NONE);
 169 
 170         tps->irq_domain = irq_domain_add_linear(tps->dev->of_node,
 171                 TPS65217_NUM_IRQ, &tps65217_irq_domain_ops, tps);
 172         if (!tps->irq_domain) {
 173                 dev_err(tps->dev, "Could not create IRQ domain\n");
 174                 return -ENOMEM;
 175         }
 176 
 177         ret = devm_request_threaded_irq(tps->dev, irq, NULL,
 178                                         tps65217_irq_thread, IRQF_ONESHOT,
 179                                         "tps65217-irq", tps);
 180         if (ret) {
 181                 dev_err(tps->dev, "Failed to request IRQ %d: %d\n",
 182                         irq, ret);
 183                 return ret;
 184         }
 185 
 186         enable_irq_wake(irq);
 187 
 188         return 0;
 189 }
 190 
 191 /**
 192  * tps65217_reg_read: Read a single tps65217 register.
 193  *
 194  * @tps: Device to read from.
 195  * @reg: Register to read.
 196  * @val: Contians the value
 197  */
 198 int tps65217_reg_read(struct tps65217 *tps, unsigned int reg,
 199                         unsigned int *val)
 200 {
 201         return regmap_read(tps->regmap, reg, val);
 202 }
 203 EXPORT_SYMBOL_GPL(tps65217_reg_read);
 204 
 205 /**
 206  * tps65217_reg_write: Write a single tps65217 register.
 207  *
 208  * @tps65217: Device to write to.
 209  * @reg: Register to write to.
 210  * @val: Value to write.
 211  * @level: Password protected level
 212  */
 213 int tps65217_reg_write(struct tps65217 *tps, unsigned int reg,
 214                         unsigned int val, unsigned int level)
 215 {
 216         int ret;
 217         unsigned int xor_reg_val;
 218 
 219         switch (level) {
 220         case TPS65217_PROTECT_NONE:
 221                 return regmap_write(tps->regmap, reg, val);
 222         case TPS65217_PROTECT_L1:
 223                 xor_reg_val = reg ^ TPS65217_PASSWORD_REGS_UNLOCK;
 224                 ret = regmap_write(tps->regmap, TPS65217_REG_PASSWORD,
 225                                                         xor_reg_val);
 226                 if (ret < 0)
 227                         return ret;
 228 
 229                 return regmap_write(tps->regmap, reg, val);
 230         case TPS65217_PROTECT_L2:
 231                 xor_reg_val = reg ^ TPS65217_PASSWORD_REGS_UNLOCK;
 232                 ret = regmap_write(tps->regmap, TPS65217_REG_PASSWORD,
 233                                                         xor_reg_val);
 234                 if (ret < 0)
 235                         return ret;
 236                 ret = regmap_write(tps->regmap, reg, val);
 237                 if (ret < 0)
 238                         return ret;
 239                 ret = regmap_write(tps->regmap, TPS65217_REG_PASSWORD,
 240                                                         xor_reg_val);
 241                 if (ret < 0)
 242                         return ret;
 243                 return regmap_write(tps->regmap, reg, val);
 244         default:
 245                 return -EINVAL;
 246         }
 247 }
 248 EXPORT_SYMBOL_GPL(tps65217_reg_write);
 249 
 250 /**
 251  * tps65217_update_bits: Modify bits w.r.t mask, val and level.
 252  *
 253  * @tps65217: Device to write to.
 254  * @reg: Register to read-write to.
 255  * @mask: Mask.
 256  * @val: Value to write.
 257  * @level: Password protected level
 258  */
 259 static int tps65217_update_bits(struct tps65217 *tps, unsigned int reg,
 260                 unsigned int mask, unsigned int val, unsigned int level)
 261 {
 262         int ret;
 263         unsigned int data;
 264 
 265         ret = tps65217_reg_read(tps, reg, &data);
 266         if (ret) {
 267                 dev_err(tps->dev, "Read from reg 0x%x failed\n", reg);
 268                 return ret;
 269         }
 270 
 271         data &= ~mask;
 272         data |= val & mask;
 273 
 274         ret = tps65217_reg_write(tps, reg, data, level);
 275         if (ret)
 276                 dev_err(tps->dev, "Write for reg 0x%x failed\n", reg);
 277 
 278         return ret;
 279 }
 280 
 281 int tps65217_set_bits(struct tps65217 *tps, unsigned int reg,
 282                 unsigned int mask, unsigned int val, unsigned int level)
 283 {
 284         return tps65217_update_bits(tps, reg, mask, val, level);
 285 }
 286 EXPORT_SYMBOL_GPL(tps65217_set_bits);
 287 
 288 int tps65217_clear_bits(struct tps65217 *tps, unsigned int reg,
 289                 unsigned int mask, unsigned int level)
 290 {
 291         return tps65217_update_bits(tps, reg, mask, 0, level);
 292 }
 293 EXPORT_SYMBOL_GPL(tps65217_clear_bits);
 294 
 295 static bool tps65217_volatile_reg(struct device *dev, unsigned int reg)
 296 {
 297         switch (reg) {
 298         case TPS65217_REG_INT:
 299                 return true;
 300         default:
 301                 return false;
 302         }
 303 }
 304 
 305 static const struct regmap_config tps65217_regmap_config = {
 306         .reg_bits = 8,
 307         .val_bits = 8,
 308 
 309         .max_register = TPS65217_REG_MAX,
 310         .volatile_reg = tps65217_volatile_reg,
 311 };
 312 
 313 static const struct of_device_id tps65217_of_match[] = {
 314         { .compatible = "ti,tps65217"},
 315         { /* sentinel */ },
 316 };
 317 MODULE_DEVICE_TABLE(of, tps65217_of_match);
 318 
 319 static int tps65217_probe(struct i2c_client *client)
 320 {
 321         struct tps65217 *tps;
 322         unsigned int version;
 323         bool status_off = false;
 324         int ret;
 325 
 326         status_off = of_property_read_bool(client->dev.of_node,
 327                                            "ti,pmic-shutdown-controller");
 328 
 329         tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
 330         if (!tps)
 331                 return -ENOMEM;
 332 
 333         i2c_set_clientdata(client, tps);
 334         tps->dev = &client->dev;
 335 
 336         tps->regmap = devm_regmap_init_i2c(client, &tps65217_regmap_config);
 337         if (IS_ERR(tps->regmap)) {
 338                 ret = PTR_ERR(tps->regmap);
 339                 dev_err(tps->dev, "Failed to allocate register map: %d\n",
 340                         ret);
 341                 return ret;
 342         }
 343 
 344         if (client->irq) {
 345                 tps65217_irq_init(tps, client->irq);
 346         } else {
 347                 int i;
 348 
 349                 /* Don't tell children about IRQ resources which won't fire */
 350                 for (i = 0; i < ARRAY_SIZE(tps65217s); i++)
 351                         tps65217s[i].num_resources = 0;
 352         }
 353 
 354         ret = devm_mfd_add_devices(tps->dev, -1, tps65217s,
 355                                    ARRAY_SIZE(tps65217s), NULL, 0,
 356                                    tps->irq_domain);
 357         if (ret < 0) {
 358                 dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret);
 359                 return ret;
 360         }
 361 
 362         ret = tps65217_reg_read(tps, TPS65217_REG_CHIPID, &version);
 363         if (ret < 0) {
 364                 dev_err(tps->dev, "Failed to read revision register: %d\n",
 365                         ret);
 366                 return ret;
 367         }
 368 
 369         /* Set the PMIC to shutdown on PWR_EN toggle */
 370         if (status_off) {
 371                 ret = tps65217_set_bits(tps, TPS65217_REG_STATUS,
 372                                 TPS65217_STATUS_OFF, TPS65217_STATUS_OFF,
 373                                 TPS65217_PROTECT_NONE);
 374                 if (ret)
 375                         dev_warn(tps->dev, "unable to set the status OFF\n");
 376         }
 377 
 378         dev_info(tps->dev, "TPS65217 ID %#x version 1.%d\n",
 379                         (version & TPS65217_CHIPID_CHIP_MASK) >> 4,
 380                         version & TPS65217_CHIPID_REV_MASK);
 381 
 382         return 0;
 383 }
 384 
 385 static int tps65217_remove(struct i2c_client *client)
 386 {
 387         struct tps65217 *tps = i2c_get_clientdata(client);
 388         unsigned int virq;
 389         int i;
 390 
 391         for (i = 0; i < TPS65217_NUM_IRQ; i++) {
 392                 virq = irq_find_mapping(tps->irq_domain, i);
 393                 if (virq)
 394                         irq_dispose_mapping(virq);
 395         }
 396 
 397         irq_domain_remove(tps->irq_domain);
 398         tps->irq_domain = NULL;
 399 
 400         return 0;
 401 }
 402 
 403 static const struct i2c_device_id tps65217_id_table[] = {
 404         {"tps65217", TPS65217},
 405         { /* sentinel */ }
 406 };
 407 MODULE_DEVICE_TABLE(i2c, tps65217_id_table);
 408 
 409 static struct i2c_driver tps65217_driver = {
 410         .driver         = {
 411                 .name   = "tps65217",
 412                 .of_match_table = tps65217_of_match,
 413         },
 414         .id_table       = tps65217_id_table,
 415         .probe_new      = tps65217_probe,
 416         .remove         = tps65217_remove,
 417 };
 418 
 419 static int __init tps65217_init(void)
 420 {
 421         return i2c_add_driver(&tps65217_driver);
 422 }
 423 subsys_initcall(tps65217_init);
 424 
 425 static void __exit tps65217_exit(void)
 426 {
 427         i2c_del_driver(&tps65217_driver);
 428 }
 429 module_exit(tps65217_exit);
 430 
 431 MODULE_AUTHOR("AnilKumar Ch <anilkumar@ti.com>");
 432 MODULE_DESCRIPTION("TPS65217 chip family multi-function driver");
 433 MODULE_LICENSE("GPL v2");

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