linux/drivers/mfd/tps6586x.c
<<
>>
Prefs
   1/*
   2 * Core driver for TI TPS6586x PMIC family
   3 *
   4 * Copyright (c) 2010 CompuLab Ltd.
   5 * Mike Rapoport <mike@compulab.co.il>
   6 *
   7 * Based on da903x.c.
   8 * Copyright (C) 2008 Compulab, Ltd.
   9 * Mike Rapoport <mike@compulab.co.il>
  10 * Copyright (C) 2006-2008 Marvell International Ltd.
  11 * Eric Miao <eric.miao@marvell.com>
  12 *
  13 * This program is free software; you can redistribute it and/or modify
  14 * it under the terms of the GNU General Public License version 2 as
  15 * published by the Free Software Foundation.
  16 */
  17
  18#include <linux/interrupt.h>
  19#include <linux/irq.h>
  20#include <linux/kernel.h>
  21#include <linux/module.h>
  22#include <linux/mutex.h>
  23#include <linux/slab.h>
  24#include <linux/err.h>
  25#include <linux/i2c.h>
  26#include <linux/regmap.h>
  27#include <linux/regulator/of_regulator.h>
  28
  29#include <linux/mfd/core.h>
  30#include <linux/mfd/tps6586x.h>
  31
  32/* interrupt control registers */
  33#define TPS6586X_INT_ACK1       0xb5
  34#define TPS6586X_INT_ACK2       0xb6
  35#define TPS6586X_INT_ACK3       0xb7
  36#define TPS6586X_INT_ACK4       0xb8
  37
  38/* interrupt mask registers */
  39#define TPS6586X_INT_MASK1      0xb0
  40#define TPS6586X_INT_MASK2      0xb1
  41#define TPS6586X_INT_MASK3      0xb2
  42#define TPS6586X_INT_MASK4      0xb3
  43#define TPS6586X_INT_MASK5      0xb4
  44
  45/* device id */
  46#define TPS6586X_VERSIONCRC     0xcd
  47
  48/* Maximum register */
  49#define TPS6586X_MAX_REGISTER   (TPS6586X_VERSIONCRC + 1)
  50
  51struct tps6586x_irq_data {
  52        u8      mask_reg;
  53        u8      mask_mask;
  54};
  55
  56#define TPS6586X_IRQ(_reg, _mask)                               \
  57        {                                                       \
  58                .mask_reg = (_reg) - TPS6586X_INT_MASK1,        \
  59                .mask_mask = (_mask),                           \
  60        }
  61
  62static const struct tps6586x_irq_data tps6586x_irqs[] = {
  63        [TPS6586X_INT_PLDO_0]   = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 0),
  64        [TPS6586X_INT_PLDO_1]   = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 1),
  65        [TPS6586X_INT_PLDO_2]   = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 2),
  66        [TPS6586X_INT_PLDO_3]   = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 3),
  67        [TPS6586X_INT_PLDO_4]   = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 4),
  68        [TPS6586X_INT_PLDO_5]   = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 5),
  69        [TPS6586X_INT_PLDO_6]   = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 6),
  70        [TPS6586X_INT_PLDO_7]   = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 7),
  71        [TPS6586X_INT_COMP_DET] = TPS6586X_IRQ(TPS6586X_INT_MASK4, 1 << 0),
  72        [TPS6586X_INT_ADC]      = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 1),
  73        [TPS6586X_INT_PLDO_8]   = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 2),
  74        [TPS6586X_INT_PLDO_9]   = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 3),
  75        [TPS6586X_INT_PSM_0]    = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 4),
  76        [TPS6586X_INT_PSM_1]    = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 5),
  77        [TPS6586X_INT_PSM_2]    = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 6),
  78        [TPS6586X_INT_PSM_3]    = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 7),
  79        [TPS6586X_INT_RTC_ALM1] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 4),
  80        [TPS6586X_INT_ACUSB_OVP] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 0x03),
  81        [TPS6586X_INT_USB_DET]  = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 2),
  82        [TPS6586X_INT_AC_DET]   = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 3),
  83        [TPS6586X_INT_BAT_DET]  = TPS6586X_IRQ(TPS6586X_INT_MASK3, 1 << 0),
  84        [TPS6586X_INT_CHG_STAT] = TPS6586X_IRQ(TPS6586X_INT_MASK4, 0xfc),
  85        [TPS6586X_INT_CHG_TEMP] = TPS6586X_IRQ(TPS6586X_INT_MASK3, 0x06),
  86        [TPS6586X_INT_PP]       = TPS6586X_IRQ(TPS6586X_INT_MASK3, 0xf0),
  87        [TPS6586X_INT_RESUME]   = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 5),
  88        [TPS6586X_INT_LOW_SYS]  = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 6),
  89        [TPS6586X_INT_RTC_ALM2] = TPS6586X_IRQ(TPS6586X_INT_MASK4, 1 << 1),
  90};
  91
  92static struct mfd_cell tps6586x_cell[] = {
  93        {
  94                .name = "tps6586x-gpio",
  95        },
  96        {
  97                .name = "tps6586x-rtc",
  98        },
  99        {
 100                .name = "tps6586x-onkey",
 101        },
 102};
 103
 104struct tps6586x {
 105        struct device           *dev;
 106        struct i2c_client       *client;
 107        struct regmap           *regmap;
 108
 109        struct irq_chip         irq_chip;
 110        struct mutex            irq_lock;
 111        int                     irq_base;
 112        u32                     irq_en;
 113        u8                      mask_reg[5];
 114};
 115
 116static inline struct tps6586x *dev_to_tps6586x(struct device *dev)
 117{
 118        return i2c_get_clientdata(to_i2c_client(dev));
 119}
 120
 121int tps6586x_write(struct device *dev, int reg, uint8_t val)
 122{
 123        struct tps6586x *tps6586x = dev_to_tps6586x(dev);
 124
 125        return regmap_write(tps6586x->regmap, reg, val);
 126}
 127EXPORT_SYMBOL_GPL(tps6586x_write);
 128
 129int tps6586x_writes(struct device *dev, int reg, int len, uint8_t *val)
 130{
 131        struct tps6586x *tps6586x = dev_to_tps6586x(dev);
 132
 133        return regmap_bulk_write(tps6586x->regmap, reg, val, len);
 134}
 135EXPORT_SYMBOL_GPL(tps6586x_writes);
 136
 137int tps6586x_read(struct device *dev, int reg, uint8_t *val)
 138{
 139        struct tps6586x *tps6586x = dev_to_tps6586x(dev);
 140        unsigned int rval;
 141        int ret;
 142
 143        ret = regmap_read(tps6586x->regmap, reg, &rval);
 144        if (!ret)
 145                *val = rval;
 146        return ret;
 147}
 148EXPORT_SYMBOL_GPL(tps6586x_read);
 149
 150int tps6586x_reads(struct device *dev, int reg, int len, uint8_t *val)
 151{
 152        struct tps6586x *tps6586x = dev_to_tps6586x(dev);
 153
 154        return regmap_bulk_read(tps6586x->regmap, reg, val, len);
 155}
 156EXPORT_SYMBOL_GPL(tps6586x_reads);
 157
 158int tps6586x_set_bits(struct device *dev, int reg, uint8_t bit_mask)
 159{
 160        struct tps6586x *tps6586x = dev_to_tps6586x(dev);
 161
 162        return regmap_update_bits(tps6586x->regmap, reg, bit_mask, bit_mask);
 163}
 164EXPORT_SYMBOL_GPL(tps6586x_set_bits);
 165
 166int tps6586x_clr_bits(struct device *dev, int reg, uint8_t bit_mask)
 167{
 168        struct tps6586x *tps6586x = dev_to_tps6586x(dev);
 169
 170        return regmap_update_bits(tps6586x->regmap, reg, bit_mask, 0);
 171}
 172EXPORT_SYMBOL_GPL(tps6586x_clr_bits);
 173
 174int tps6586x_update(struct device *dev, int reg, uint8_t val, uint8_t mask)
 175{
 176        struct tps6586x *tps6586x = dev_to_tps6586x(dev);
 177
 178        return regmap_update_bits(tps6586x->regmap, reg, mask, val);
 179}
 180EXPORT_SYMBOL_GPL(tps6586x_update);
 181
 182static int __remove_subdev(struct device *dev, void *unused)
 183{
 184        platform_device_unregister(to_platform_device(dev));
 185        return 0;
 186}
 187
 188static int tps6586x_remove_subdevs(struct tps6586x *tps6586x)
 189{
 190        return device_for_each_child(tps6586x->dev, NULL, __remove_subdev);
 191}
 192
 193static void tps6586x_irq_lock(struct irq_data *data)
 194{
 195        struct tps6586x *tps6586x = irq_data_get_irq_chip_data(data);
 196
 197        mutex_lock(&tps6586x->irq_lock);
 198}
 199
 200static void tps6586x_irq_enable(struct irq_data *irq_data)
 201{
 202        struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data);
 203        unsigned int __irq = irq_data->irq - tps6586x->irq_base;
 204        const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq];
 205
 206        tps6586x->mask_reg[data->mask_reg] &= ~data->mask_mask;
 207        tps6586x->irq_en |= (1 << __irq);
 208}
 209
 210static void tps6586x_irq_disable(struct irq_data *irq_data)
 211{
 212        struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data);
 213
 214        unsigned int __irq = irq_data->irq - tps6586x->irq_base;
 215        const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq];
 216
 217        tps6586x->mask_reg[data->mask_reg] |= data->mask_mask;
 218        tps6586x->irq_en &= ~(1 << __irq);
 219}
 220
 221static void tps6586x_irq_sync_unlock(struct irq_data *data)
 222{
 223        struct tps6586x *tps6586x = irq_data_get_irq_chip_data(data);
 224        int i;
 225
 226        for (i = 0; i < ARRAY_SIZE(tps6586x->mask_reg); i++) {
 227                int ret;
 228                ret = tps6586x_write(tps6586x->dev,
 229                                            TPS6586X_INT_MASK1 + i,
 230                                            tps6586x->mask_reg[i]);
 231                WARN_ON(ret);
 232        }
 233
 234        mutex_unlock(&tps6586x->irq_lock);
 235}
 236
 237static irqreturn_t tps6586x_irq(int irq, void *data)
 238{
 239        struct tps6586x *tps6586x = data;
 240        u32 acks;
 241        int ret = 0;
 242
 243        ret = tps6586x_reads(tps6586x->dev, TPS6586X_INT_ACK1,
 244                             sizeof(acks), (uint8_t *)&acks);
 245
 246        if (ret < 0) {
 247                dev_err(tps6586x->dev, "failed to read interrupt status\n");
 248                return IRQ_NONE;
 249        }
 250
 251        acks = le32_to_cpu(acks);
 252
 253        while (acks) {
 254                int i = __ffs(acks);
 255
 256                if (tps6586x->irq_en & (1 << i))
 257                        handle_nested_irq(tps6586x->irq_base + i);
 258
 259                acks &= ~(1 << i);
 260        }
 261
 262        return IRQ_HANDLED;
 263}
 264
 265static int __devinit tps6586x_irq_init(struct tps6586x *tps6586x, int irq,
 266                                       int irq_base)
 267{
 268        int i, ret;
 269        u8 tmp[4];
 270
 271        if (!irq_base) {
 272                dev_warn(tps6586x->dev, "No interrupt support on IRQ base\n");
 273                return -EINVAL;
 274        }
 275
 276        mutex_init(&tps6586x->irq_lock);
 277        for (i = 0; i < 5; i++) {
 278                tps6586x->mask_reg[i] = 0xff;
 279                tps6586x_write(tps6586x->dev, TPS6586X_INT_MASK1 + i, 0xff);
 280        }
 281
 282        tps6586x_reads(tps6586x->dev, TPS6586X_INT_ACK1, sizeof(tmp), tmp);
 283
 284        tps6586x->irq_base = irq_base;
 285
 286        tps6586x->irq_chip.name = "tps6586x";
 287        tps6586x->irq_chip.irq_enable = tps6586x_irq_enable;
 288        tps6586x->irq_chip.irq_disable = tps6586x_irq_disable;
 289        tps6586x->irq_chip.irq_bus_lock = tps6586x_irq_lock;
 290        tps6586x->irq_chip.irq_bus_sync_unlock = tps6586x_irq_sync_unlock;
 291
 292        for (i = 0; i < ARRAY_SIZE(tps6586x_irqs); i++) {
 293                int __irq = i + tps6586x->irq_base;
 294                irq_set_chip_data(__irq, tps6586x);
 295                irq_set_chip_and_handler(__irq, &tps6586x->irq_chip,
 296                                         handle_simple_irq);
 297                irq_set_nested_thread(__irq, 1);
 298#ifdef CONFIG_ARM
 299                set_irq_flags(__irq, IRQF_VALID);
 300#endif
 301        }
 302
 303        ret = request_threaded_irq(irq, NULL, tps6586x_irq, IRQF_ONESHOT,
 304                                   "tps6586x", tps6586x);
 305
 306        if (!ret) {
 307                device_init_wakeup(tps6586x->dev, 1);
 308                enable_irq_wake(irq);
 309        }
 310
 311        return ret;
 312}
 313
 314static int __devinit tps6586x_add_subdevs(struct tps6586x *tps6586x,
 315                                          struct tps6586x_platform_data *pdata)
 316{
 317        struct tps6586x_subdev_info *subdev;
 318        struct platform_device *pdev;
 319        int i, ret = 0;
 320
 321        for (i = 0; i < pdata->num_subdevs; i++) {
 322                subdev = &pdata->subdevs[i];
 323
 324                pdev = platform_device_alloc(subdev->name, subdev->id);
 325                if (!pdev) {
 326                        ret = -ENOMEM;
 327                        goto failed;
 328                }
 329
 330                pdev->dev.parent = tps6586x->dev;
 331                pdev->dev.platform_data = subdev->platform_data;
 332                pdev->dev.of_node = subdev->of_node;
 333
 334                ret = platform_device_add(pdev);
 335                if (ret) {
 336                        platform_device_put(pdev);
 337                        goto failed;
 338                }
 339        }
 340        return 0;
 341
 342failed:
 343        tps6586x_remove_subdevs(tps6586x);
 344        return ret;
 345}
 346
 347#ifdef CONFIG_OF
 348static struct of_regulator_match tps6586x_matches[] = {
 349        { .name = "sm0",     .driver_data = (void *)TPS6586X_ID_SM_0    },
 350        { .name = "sm1",     .driver_data = (void *)TPS6586X_ID_SM_1    },
 351        { .name = "sm2",     .driver_data = (void *)TPS6586X_ID_SM_2    },
 352        { .name = "ldo0",    .driver_data = (void *)TPS6586X_ID_LDO_0   },
 353        { .name = "ldo1",    .driver_data = (void *)TPS6586X_ID_LDO_1   },
 354        { .name = "ldo2",    .driver_data = (void *)TPS6586X_ID_LDO_2   },
 355        { .name = "ldo3",    .driver_data = (void *)TPS6586X_ID_LDO_3   },
 356        { .name = "ldo4",    .driver_data = (void *)TPS6586X_ID_LDO_4   },
 357        { .name = "ldo5",    .driver_data = (void *)TPS6586X_ID_LDO_5   },
 358        { .name = "ldo6",    .driver_data = (void *)TPS6586X_ID_LDO_6   },
 359        { .name = "ldo7",    .driver_data = (void *)TPS6586X_ID_LDO_7   },
 360        { .name = "ldo8",    .driver_data = (void *)TPS6586X_ID_LDO_8   },
 361        { .name = "ldo9",    .driver_data = (void *)TPS6586X_ID_LDO_9   },
 362        { .name = "ldo_rtc", .driver_data = (void *)TPS6586X_ID_LDO_RTC },
 363};
 364
 365static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client)
 366{
 367        const unsigned int num = ARRAY_SIZE(tps6586x_matches);
 368        struct device_node *np = client->dev.of_node;
 369        struct tps6586x_platform_data *pdata;
 370        struct tps6586x_subdev_info *devs;
 371        struct device_node *regs;
 372        unsigned int count;
 373        unsigned int i, j;
 374        int err;
 375
 376        regs = of_find_node_by_name(np, "regulators");
 377        if (!regs)
 378                return NULL;
 379
 380        err = of_regulator_match(&client->dev, regs, tps6586x_matches, num);
 381        if (err < 0) {
 382                of_node_put(regs);
 383                return NULL;
 384        }
 385
 386        of_node_put(regs);
 387        count = err;
 388
 389        devs = devm_kzalloc(&client->dev, count * sizeof(*devs), GFP_KERNEL);
 390        if (!devs)
 391                return NULL;
 392
 393        for (i = 0, j = 0; i < num && j < count; i++) {
 394                if (!tps6586x_matches[i].init_data)
 395                        continue;
 396
 397                devs[j].name = "tps6586x-regulator";
 398                devs[j].platform_data = tps6586x_matches[i].init_data;
 399                devs[j].id = (int)tps6586x_matches[i].driver_data;
 400                devs[j].of_node = tps6586x_matches[i].of_node;
 401                j++;
 402        }
 403
 404        pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
 405        if (!pdata)
 406                return NULL;
 407
 408        pdata->num_subdevs = count;
 409        pdata->subdevs = devs;
 410        pdata->gpio_base = -1;
 411        pdata->irq_base = -1;
 412
 413        return pdata;
 414}
 415
 416static struct of_device_id tps6586x_of_match[] = {
 417        { .compatible = "ti,tps6586x", },
 418        { },
 419};
 420#else
 421static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client)
 422{
 423        return NULL;
 424}
 425#endif
 426
 427static bool is_volatile_reg(struct device *dev, unsigned int reg)
 428{
 429        /* Cache all interrupt mask register */
 430        if ((reg >= TPS6586X_INT_MASK1) && (reg <= TPS6586X_INT_MASK5))
 431                return false;
 432
 433        return true;
 434}
 435
 436static const struct regmap_config tps6586x_regmap_config = {
 437        .reg_bits = 8,
 438        .val_bits = 8,
 439        .max_register = TPS6586X_MAX_REGISTER - 1,
 440        .volatile_reg = is_volatile_reg,
 441        .cache_type = REGCACHE_RBTREE,
 442};
 443
 444static int __devinit tps6586x_i2c_probe(struct i2c_client *client,
 445                                        const struct i2c_device_id *id)
 446{
 447        struct tps6586x_platform_data *pdata = client->dev.platform_data;
 448        struct tps6586x *tps6586x;
 449        int ret;
 450
 451        if (!pdata && client->dev.of_node)
 452                pdata = tps6586x_parse_dt(client);
 453
 454        if (!pdata) {
 455                dev_err(&client->dev, "tps6586x requires platform data\n");
 456                return -ENOTSUPP;
 457        }
 458
 459        ret = i2c_smbus_read_byte_data(client, TPS6586X_VERSIONCRC);
 460        if (ret < 0) {
 461                dev_err(&client->dev, "Chip ID read failed: %d\n", ret);
 462                return -EIO;
 463        }
 464
 465        dev_info(&client->dev, "VERSIONCRC is %02x\n", ret);
 466
 467        tps6586x = devm_kzalloc(&client->dev, sizeof(*tps6586x), GFP_KERNEL);
 468        if (tps6586x == NULL) {
 469                dev_err(&client->dev, "memory for tps6586x alloc failed\n");
 470                return -ENOMEM;
 471        }
 472
 473        tps6586x->client = client;
 474        tps6586x->dev = &client->dev;
 475        i2c_set_clientdata(client, tps6586x);
 476
 477        tps6586x->regmap = devm_regmap_init_i2c(client,
 478                                        &tps6586x_regmap_config);
 479        if (IS_ERR(tps6586x->regmap)) {
 480                ret = PTR_ERR(tps6586x->regmap);
 481                dev_err(&client->dev, "regmap init failed: %d\n", ret);
 482                return ret;
 483        }
 484
 485
 486        if (client->irq) {
 487                ret = tps6586x_irq_init(tps6586x, client->irq,
 488                                        pdata->irq_base);
 489                if (ret) {
 490                        dev_err(&client->dev, "IRQ init failed: %d\n", ret);
 491                        return ret;
 492                }
 493        }
 494
 495        ret = mfd_add_devices(tps6586x->dev, -1,
 496                              tps6586x_cell, ARRAY_SIZE(tps6586x_cell),
 497                              NULL, 0, NULL);
 498        if (ret < 0) {
 499                dev_err(&client->dev, "mfd_add_devices failed: %d\n", ret);
 500                goto err_mfd_add;
 501        }
 502
 503        ret = tps6586x_add_subdevs(tps6586x, pdata);
 504        if (ret) {
 505                dev_err(&client->dev, "add devices failed: %d\n", ret);
 506                goto err_add_devs;
 507        }
 508
 509        return 0;
 510
 511err_add_devs:
 512        mfd_remove_devices(tps6586x->dev);
 513err_mfd_add:
 514        if (client->irq)
 515                free_irq(client->irq, tps6586x);
 516        return ret;
 517}
 518
 519static int __devexit tps6586x_i2c_remove(struct i2c_client *client)
 520{
 521        struct tps6586x *tps6586x = i2c_get_clientdata(client);
 522
 523        tps6586x_remove_subdevs(tps6586x);
 524        mfd_remove_devices(tps6586x->dev);
 525        if (client->irq)
 526                free_irq(client->irq, tps6586x);
 527        return 0;
 528}
 529
 530static const struct i2c_device_id tps6586x_id_table[] = {
 531        { "tps6586x", 0 },
 532        { },
 533};
 534MODULE_DEVICE_TABLE(i2c, tps6586x_id_table);
 535
 536static struct i2c_driver tps6586x_driver = {
 537        .driver = {
 538                .name   = "tps6586x",
 539                .owner  = THIS_MODULE,
 540                .of_match_table = of_match_ptr(tps6586x_of_match),
 541        },
 542        .probe          = tps6586x_i2c_probe,
 543        .remove         = __devexit_p(tps6586x_i2c_remove),
 544        .id_table       = tps6586x_id_table,
 545};
 546
 547static int __init tps6586x_init(void)
 548{
 549        return i2c_add_driver(&tps6586x_driver);
 550}
 551subsys_initcall(tps6586x_init);
 552
 553static void __exit tps6586x_exit(void)
 554{
 555        i2c_del_driver(&tps6586x_driver);
 556}
 557module_exit(tps6586x_exit);
 558
 559MODULE_DESCRIPTION("TPS6586X core driver");
 560MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
 561MODULE_LICENSE("GPL");
 562
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.