linux/drivers/mfd/tps65090.c
<<
>>
Prefs
   1/*
   2 * Core driver for TI TPS65090 PMIC family
   3 *
   4 * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
   5
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms and conditions of the GNU General Public License,
   8 * version 2, as published by the Free Software Foundation.
   9
  10 * This program is distributed in the hope it will be useful, but WITHOUT
  11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13 * more details.
  14
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17 */
  18
  19#include <linux/interrupt.h>
  20#include <linux/irq.h>
  21#include <linux/kernel.h>
  22#include <linux/module.h>
  23#include <linux/mutex.h>
  24#include <linux/slab.h>
  25#include <linux/i2c.h>
  26#include <linux/mfd/core.h>
  27#include <linux/mfd/tps65090.h>
  28#include <linux/regmap.h>
  29#include <linux/err.h>
  30
  31#define NUM_INT_REG 2
  32#define TOTAL_NUM_REG 0x18
  33
  34/* interrupt status registers */
  35#define TPS65090_INT_STS        0x0
  36#define TPS65090_INT_STS2       0x1
  37
  38/* interrupt mask registers */
  39#define TPS65090_INT_MSK        0x2
  40#define TPS65090_INT_MSK2       0x3
  41
  42struct tps65090_irq_data {
  43        u8              mask_reg;
  44        u8              mask_pos;
  45};
  46
  47#define TPS65090_IRQ(_reg, _mask_pos)           \
  48        {                                       \
  49                .mask_reg       = (_reg),       \
  50                .mask_pos       = (_mask_pos),  \
  51        }
  52
  53static const struct tps65090_irq_data tps65090_irqs[] = {
  54        [0]             = TPS65090_IRQ(0, 0),
  55        [1]             = TPS65090_IRQ(0, 1),
  56        [2]             = TPS65090_IRQ(0, 2),
  57        [3]             = TPS65090_IRQ(0, 3),
  58        [4]             = TPS65090_IRQ(0, 4),
  59        [5]             = TPS65090_IRQ(0, 5),
  60        [6]             = TPS65090_IRQ(0, 6),
  61        [7]             = TPS65090_IRQ(0, 7),
  62        [8]             = TPS65090_IRQ(1, 0),
  63        [9]             = TPS65090_IRQ(1, 1),
  64        [10]            = TPS65090_IRQ(1, 2),
  65        [11]            = TPS65090_IRQ(1, 3),
  66        [12]            = TPS65090_IRQ(1, 4),
  67        [13]            = TPS65090_IRQ(1, 5),
  68        [14]            = TPS65090_IRQ(1, 6),
  69        [15]            = TPS65090_IRQ(1, 7),
  70};
  71
  72static struct mfd_cell tps65090s[] = {
  73        {
  74                .name = "tps65090-pmic",
  75        },
  76        {
  77                .name = "tps65090-regulator",
  78        },
  79};
  80
  81int tps65090_write(struct device *dev, int reg, uint8_t val)
  82{
  83        struct tps65090 *tps = dev_get_drvdata(dev);
  84        return regmap_write(tps->rmap, reg, val);
  85}
  86EXPORT_SYMBOL_GPL(tps65090_write);
  87
  88int tps65090_read(struct device *dev, int reg, uint8_t *val)
  89{
  90        struct tps65090 *tps = dev_get_drvdata(dev);
  91        unsigned int temp_val;
  92        int ret;
  93        ret = regmap_read(tps->rmap, reg, &temp_val);
  94        if (!ret)
  95                *val = temp_val;
  96        return ret;
  97}
  98EXPORT_SYMBOL_GPL(tps65090_read);
  99
 100int tps65090_set_bits(struct device *dev, int reg, uint8_t bit_num)
 101{
 102        struct tps65090 *tps = dev_get_drvdata(dev);
 103        return regmap_update_bits(tps->rmap, reg, BIT(bit_num), ~0u);
 104}
 105EXPORT_SYMBOL_GPL(tps65090_set_bits);
 106
 107int tps65090_clr_bits(struct device *dev, int reg, uint8_t bit_num)
 108{
 109        struct tps65090 *tps = dev_get_drvdata(dev);
 110        return regmap_update_bits(tps->rmap, reg, BIT(bit_num), 0u);
 111}
 112EXPORT_SYMBOL_GPL(tps65090_clr_bits);
 113
 114static void tps65090_irq_lock(struct irq_data *data)
 115{
 116        struct tps65090 *tps65090 = irq_data_get_irq_chip_data(data);
 117
 118        mutex_lock(&tps65090->irq_lock);
 119}
 120
 121static void tps65090_irq_mask(struct irq_data *irq_data)
 122{
 123        struct tps65090 *tps65090 = irq_data_get_irq_chip_data(irq_data);
 124        unsigned int __irq = irq_data->hwirq;
 125        const struct tps65090_irq_data *data = &tps65090_irqs[__irq];
 126
 127        tps65090_set_bits(tps65090->dev, (TPS65090_INT_MSK + data->mask_reg),
 128                data->mask_pos);
 129}
 130
 131static void tps65090_irq_unmask(struct irq_data *irq_data)
 132{
 133        struct tps65090 *tps65090 = irq_data_get_irq_chip_data(irq_data);
 134        unsigned int __irq = irq_data->irq - tps65090->irq_base;
 135        const struct tps65090_irq_data *data = &tps65090_irqs[__irq];
 136
 137        tps65090_clr_bits(tps65090->dev, (TPS65090_INT_MSK + data->mask_reg),
 138                data->mask_pos);
 139}
 140
 141static void tps65090_irq_sync_unlock(struct irq_data *data)
 142{
 143        struct tps65090 *tps65090 = irq_data_get_irq_chip_data(data);
 144
 145        mutex_unlock(&tps65090->irq_lock);
 146}
 147
 148static irqreturn_t tps65090_irq(int irq, void *data)
 149{
 150        struct tps65090 *tps65090 = data;
 151        int ret = 0;
 152        u8 status, mask;
 153        unsigned long int acks = 0;
 154        int i;
 155
 156        for (i = 0; i < NUM_INT_REG; i++) {
 157                ret = tps65090_read(tps65090->dev, TPS65090_INT_MSK + i, &mask);
 158                if (ret < 0) {
 159                        dev_err(tps65090->dev,
 160                                "failed to read mask reg [addr:%d]\n",
 161                                TPS65090_INT_MSK + i);
 162                        return IRQ_NONE;
 163                }
 164                ret = tps65090_read(tps65090->dev, TPS65090_INT_STS + i,
 165                        &status);
 166                if (ret < 0) {
 167                        dev_err(tps65090->dev,
 168                                "failed to read status reg [addr:%d]\n",
 169                                 TPS65090_INT_STS + i);
 170                        return IRQ_NONE;
 171                }
 172                if (status) {
 173                        /* Ack only those interrupts which are not masked */
 174                        status &= (~mask);
 175                        ret = tps65090_write(tps65090->dev,
 176                                        TPS65090_INT_STS + i, status);
 177                        if (ret < 0) {
 178                                dev_err(tps65090->dev,
 179                                        "failed to write interrupt status\n");
 180                                return IRQ_NONE;
 181                        }
 182                        acks |= (status << (i * 8));
 183                }
 184        }
 185
 186        for_each_set_bit(i, &acks, ARRAY_SIZE(tps65090_irqs))
 187                handle_nested_irq(tps65090->irq_base + i);
 188        return acks ? IRQ_HANDLED : IRQ_NONE;
 189}
 190
 191static int __devinit tps65090_irq_init(struct tps65090 *tps65090, int irq,
 192        int irq_base)
 193{
 194        int i, ret;
 195
 196        if (!irq_base) {
 197                dev_err(tps65090->dev, "IRQ base not set\n");
 198                return -EINVAL;
 199        }
 200
 201        mutex_init(&tps65090->irq_lock);
 202
 203        for (i = 0; i < NUM_INT_REG; i++)
 204                tps65090_write(tps65090->dev, TPS65090_INT_MSK + i, 0xFF);
 205
 206        for (i = 0; i < NUM_INT_REG; i++)
 207                tps65090_write(tps65090->dev, TPS65090_INT_STS + i, 0xff);
 208
 209        tps65090->irq_base = irq_base;
 210        tps65090->irq_chip.name = "tps65090";
 211        tps65090->irq_chip.irq_mask = tps65090_irq_mask;
 212        tps65090->irq_chip.irq_unmask = tps65090_irq_unmask;
 213        tps65090->irq_chip.irq_bus_lock = tps65090_irq_lock;
 214        tps65090->irq_chip.irq_bus_sync_unlock = tps65090_irq_sync_unlock;
 215
 216        for (i = 0; i < ARRAY_SIZE(tps65090_irqs); i++) {
 217                int __irq = i + tps65090->irq_base;
 218                irq_set_chip_data(__irq, tps65090);
 219                irq_set_chip_and_handler(__irq, &tps65090->irq_chip,
 220                                         handle_simple_irq);
 221                irq_set_nested_thread(__irq, 1);
 222#ifdef CONFIG_ARM
 223                set_irq_flags(__irq, IRQF_VALID);
 224#endif
 225        }
 226
 227        ret = request_threaded_irq(irq, NULL, tps65090_irq, IRQF_ONESHOT,
 228                                "tps65090", tps65090);
 229        if (!ret) {
 230                device_init_wakeup(tps65090->dev, 1);
 231                enable_irq_wake(irq);
 232        }
 233
 234        return ret;
 235}
 236
 237static bool is_volatile_reg(struct device *dev, unsigned int reg)
 238{
 239        if (reg == TPS65090_INT_STS)
 240                return true;
 241        else
 242                return false;
 243}
 244
 245static const struct regmap_config tps65090_regmap_config = {
 246        .reg_bits = 8,
 247        .val_bits = 8,
 248        .max_register = TOTAL_NUM_REG,
 249        .num_reg_defaults_raw = TOTAL_NUM_REG,
 250        .cache_type = REGCACHE_RBTREE,
 251        .volatile_reg = is_volatile_reg,
 252};
 253
 254static int __devinit tps65090_i2c_probe(struct i2c_client *client,
 255                                        const struct i2c_device_id *id)
 256{
 257        struct tps65090_platform_data *pdata = client->dev.platform_data;
 258        struct tps65090 *tps65090;
 259        int ret;
 260
 261        if (!pdata) {
 262                dev_err(&client->dev, "tps65090 requires platform data\n");
 263                return -EINVAL;
 264        }
 265
 266        tps65090 = devm_kzalloc(&client->dev, sizeof(struct tps65090),
 267                GFP_KERNEL);
 268        if (tps65090 == NULL)
 269                return -ENOMEM;
 270
 271        tps65090->client = client;
 272        tps65090->dev = &client->dev;
 273        i2c_set_clientdata(client, tps65090);
 274
 275        mutex_init(&tps65090->lock);
 276
 277        if (client->irq) {
 278                ret = tps65090_irq_init(tps65090, client->irq, pdata->irq_base);
 279                if (ret) {
 280                        dev_err(&client->dev, "IRQ init failed with err: %d\n",
 281                                ret);
 282                        goto err_exit;
 283                }
 284        }
 285
 286        tps65090->rmap = devm_regmap_init_i2c(tps65090->client,
 287                                              &tps65090_regmap_config);
 288        if (IS_ERR(tps65090->rmap)) {
 289                ret = PTR_ERR(tps65090->rmap);
 290                dev_err(&client->dev, "regmap_init failed with err: %d\n", ret);
 291                goto err_irq_exit;
 292        }
 293
 294        ret = mfd_add_devices(tps65090->dev, -1, tps65090s,
 295                              ARRAY_SIZE(tps65090s), NULL, 0, NULL);
 296        if (ret) {
 297                dev_err(&client->dev, "add mfd devices failed with err: %d\n",
 298                        ret);
 299                goto err_irq_exit;
 300        }
 301
 302        return 0;
 303
 304err_irq_exit:
 305        if (client->irq)
 306                free_irq(client->irq, tps65090);
 307err_exit:
 308        return ret;
 309}
 310
 311static int __devexit tps65090_i2c_remove(struct i2c_client *client)
 312{
 313        struct tps65090 *tps65090 = i2c_get_clientdata(client);
 314
 315        mfd_remove_devices(tps65090->dev);
 316        if (client->irq)
 317                free_irq(client->irq, tps65090);
 318
 319        return 0;
 320}
 321
 322#ifdef CONFIG_PM_SLEEP
 323static int tps65090_suspend(struct device *dev)
 324{
 325        struct i2c_client *client = to_i2c_client(dev);
 326        if (client->irq)
 327                disable_irq(client->irq);
 328        return 0;
 329}
 330
 331static int tps65090_resume(struct device *dev)
 332{
 333        struct i2c_client *client = to_i2c_client(dev);
 334        if (client->irq)
 335                enable_irq(client->irq);
 336        return 0;
 337}
 338#endif
 339
 340static const struct dev_pm_ops tps65090_pm_ops = {
 341        SET_SYSTEM_SLEEP_PM_OPS(tps65090_suspend, tps65090_resume)
 342};
 343
 344static const struct i2c_device_id tps65090_id_table[] = {
 345        { "tps65090", 0 },
 346        { },
 347};
 348MODULE_DEVICE_TABLE(i2c, tps65090_id_table);
 349
 350static struct i2c_driver tps65090_driver = {
 351        .driver = {
 352                .name   = "tps65090",
 353                .owner  = THIS_MODULE,
 354                .pm     = &tps65090_pm_ops,
 355        },
 356        .probe          = tps65090_i2c_probe,
 357        .remove         = __devexit_p(tps65090_i2c_remove),
 358        .id_table       = tps65090_id_table,
 359};
 360
 361static int __init tps65090_init(void)
 362{
 363        return i2c_add_driver(&tps65090_driver);
 364}
 365subsys_initcall(tps65090_init);
 366
 367static void __exit tps65090_exit(void)
 368{
 369        i2c_del_driver(&tps65090_driver);
 370}
 371module_exit(tps65090_exit);
 372
 373MODULE_DESCRIPTION("TPS65090 core driver");
 374MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>");
 375MODULE_LICENSE("GPL v2");
 376
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.