linux/drivers/mfd/twl6040.c
<<
>>
Prefs
   1/*
   2 * MFD driver for TWL6040 audio device
   3 *
   4 * Authors:     Misael Lopez Cruz <misael.lopez@ti.com>
   5 *              Jorge Eduardo Candelaria <jorge.candelaria@ti.com>
   6 *              Peter Ujfalusi <peter.ujfalusi@ti.com>
   7 *
   8 * Copyright:   (C) 2011 Texas Instruments, Inc.
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as
  12 * published by the Free Software Foundation.
  13 *
  14 * This program is distributed in the hope that it will be useful, but
  15 * WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  22 * 02110-1301 USA
  23 *
  24 */
  25
  26#include <linux/module.h>
  27#include <linux/types.h>
  28#include <linux/slab.h>
  29#include <linux/kernel.h>
  30#include <linux/err.h>
  31#include <linux/platform_device.h>
  32#include <linux/of.h>
  33#include <linux/of_irq.h>
  34#include <linux/of_gpio.h>
  35#include <linux/of_platform.h>
  36#include <linux/gpio.h>
  37#include <linux/delay.h>
  38#include <linux/i2c.h>
  39#include <linux/regmap.h>
  40#include <linux/mfd/core.h>
  41#include <linux/mfd/twl6040.h>
  42#include <linux/regulator/consumer.h>
  43
  44#define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1)
  45#define TWL6040_NUM_SUPPLIES    (2)
  46
  47static bool twl6040_has_vibra(struct device_node *node)
  48{
  49#ifdef CONFIG_OF
  50        if (of_find_node_by_name(node, "vibra"))
  51                return true;
  52#endif
  53        return false;
  54}
  55
  56int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)
  57{
  58        int ret;
  59        unsigned int val;
  60
  61        ret = regmap_read(twl6040->regmap, reg, &val);
  62        if (ret < 0)
  63                return ret;
  64
  65        return val;
  66}
  67EXPORT_SYMBOL(twl6040_reg_read);
  68
  69int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg, u8 val)
  70{
  71        int ret;
  72
  73        ret = regmap_write(twl6040->regmap, reg, val);
  74
  75        return ret;
  76}
  77EXPORT_SYMBOL(twl6040_reg_write);
  78
  79int twl6040_set_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask)
  80{
  81        return regmap_update_bits(twl6040->regmap, reg, mask, mask);
  82}
  83EXPORT_SYMBOL(twl6040_set_bits);
  84
  85int twl6040_clear_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask)
  86{
  87        return regmap_update_bits(twl6040->regmap, reg, mask, 0);
  88}
  89EXPORT_SYMBOL(twl6040_clear_bits);
  90
  91/* twl6040 codec manual power-up sequence */
  92static int twl6040_power_up_manual(struct twl6040 *twl6040)
  93{
  94        u8 ldoctl, ncpctl, lppllctl;
  95        int ret;
  96
  97        /* enable high-side LDO, reference system and internal oscillator */
  98        ldoctl = TWL6040_HSLDOENA | TWL6040_REFENA | TWL6040_OSCENA;
  99        ret = twl6040_reg_write(twl6040, TWL6040_REG_LDOCTL, ldoctl);
 100        if (ret)
 101                return ret;
 102        usleep_range(10000, 10500);
 103
 104        /* enable negative charge pump */
 105        ncpctl = TWL6040_NCPENA;
 106        ret = twl6040_reg_write(twl6040, TWL6040_REG_NCPCTL, ncpctl);
 107        if (ret)
 108                goto ncp_err;
 109        usleep_range(1000, 1500);
 110
 111        /* enable low-side LDO */
 112        ldoctl |= TWL6040_LSLDOENA;
 113        ret = twl6040_reg_write(twl6040, TWL6040_REG_LDOCTL, ldoctl);
 114        if (ret)
 115                goto lsldo_err;
 116        usleep_range(1000, 1500);
 117
 118        /* enable low-power PLL */
 119        lppllctl = TWL6040_LPLLENA;
 120        ret = twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl);
 121        if (ret)
 122                goto lppll_err;
 123        usleep_range(5000, 5500);
 124
 125        /* disable internal oscillator */
 126        ldoctl &= ~TWL6040_OSCENA;
 127        ret = twl6040_reg_write(twl6040, TWL6040_REG_LDOCTL, ldoctl);
 128        if (ret)
 129                goto osc_err;
 130
 131        return 0;
 132
 133osc_err:
 134        lppllctl &= ~TWL6040_LPLLENA;
 135        twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl);
 136lppll_err:
 137        ldoctl &= ~TWL6040_LSLDOENA;
 138        twl6040_reg_write(twl6040, TWL6040_REG_LDOCTL, ldoctl);
 139lsldo_err:
 140        ncpctl &= ~TWL6040_NCPENA;
 141        twl6040_reg_write(twl6040, TWL6040_REG_NCPCTL, ncpctl);
 142ncp_err:
 143        ldoctl &= ~(TWL6040_HSLDOENA | TWL6040_REFENA | TWL6040_OSCENA);
 144        twl6040_reg_write(twl6040, TWL6040_REG_LDOCTL, ldoctl);
 145
 146        dev_err(twl6040->dev, "manual power-up failed\n");
 147        return ret;
 148}
 149
 150/* twl6040 manual power-down sequence */
 151static void twl6040_power_down_manual(struct twl6040 *twl6040)
 152{
 153        u8 ncpctl, ldoctl, lppllctl;
 154
 155        ncpctl = twl6040_reg_read(twl6040, TWL6040_REG_NCPCTL);
 156        ldoctl = twl6040_reg_read(twl6040, TWL6040_REG_LDOCTL);
 157        lppllctl = twl6040_reg_read(twl6040, TWL6040_REG_LPPLLCTL);
 158
 159        /* enable internal oscillator */
 160        ldoctl |= TWL6040_OSCENA;
 161        twl6040_reg_write(twl6040, TWL6040_REG_LDOCTL, ldoctl);
 162        usleep_range(1000, 1500);
 163
 164        /* disable low-power PLL */
 165        lppllctl &= ~TWL6040_LPLLENA;
 166        twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl);
 167
 168        /* disable low-side LDO */
 169        ldoctl &= ~TWL6040_LSLDOENA;
 170        twl6040_reg_write(twl6040, TWL6040_REG_LDOCTL, ldoctl);
 171
 172        /* disable negative charge pump */
 173        ncpctl &= ~TWL6040_NCPENA;
 174        twl6040_reg_write(twl6040, TWL6040_REG_NCPCTL, ncpctl);
 175
 176        /* disable high-side LDO, reference system and internal oscillator */
 177        ldoctl &= ~(TWL6040_HSLDOENA | TWL6040_REFENA | TWL6040_OSCENA);
 178        twl6040_reg_write(twl6040, TWL6040_REG_LDOCTL, ldoctl);
 179}
 180
 181static irqreturn_t twl6040_readyint_handler(int irq, void *data)
 182{
 183        struct twl6040 *twl6040 = data;
 184
 185        complete(&twl6040->ready);
 186
 187        return IRQ_HANDLED;
 188}
 189
 190static irqreturn_t twl6040_thint_handler(int irq, void *data)
 191{
 192        struct twl6040 *twl6040 = data;
 193        u8 status;
 194
 195        status = twl6040_reg_read(twl6040, TWL6040_REG_STATUS);
 196        if (status & TWL6040_TSHUTDET) {
 197                dev_warn(twl6040->dev, "Thermal shutdown, powering-off");
 198                twl6040_power(twl6040, 0);
 199        } else {
 200                dev_warn(twl6040->dev, "Leaving thermal shutdown, powering-on");
 201                twl6040_power(twl6040, 1);
 202        }
 203
 204        return IRQ_HANDLED;
 205}
 206
 207static int twl6040_power_up_automatic(struct twl6040 *twl6040)
 208{
 209        int time_left;
 210
 211        gpio_set_value(twl6040->audpwron, 1);
 212
 213        time_left = wait_for_completion_timeout(&twl6040->ready,
 214                                                msecs_to_jiffies(144));
 215        if (!time_left) {
 216                u8 intid;
 217
 218                dev_warn(twl6040->dev, "timeout waiting for READYINT\n");
 219                intid = twl6040_reg_read(twl6040, TWL6040_REG_INTID);
 220                if (!(intid & TWL6040_READYINT)) {
 221                        dev_err(twl6040->dev, "automatic power-up failed\n");
 222                        gpio_set_value(twl6040->audpwron, 0);
 223                        return -ETIMEDOUT;
 224                }
 225        }
 226
 227        return 0;
 228}
 229
 230int twl6040_power(struct twl6040 *twl6040, int on)
 231{
 232        int ret = 0;
 233
 234        mutex_lock(&twl6040->mutex);
 235
 236        if (on) {
 237                /* already powered-up */
 238                if (twl6040->power_count++)
 239                        goto out;
 240
 241                if (gpio_is_valid(twl6040->audpwron)) {
 242                        /* use automatic power-up sequence */
 243                        ret = twl6040_power_up_automatic(twl6040);
 244                        if (ret) {
 245                                twl6040->power_count = 0;
 246                                goto out;
 247                        }
 248                } else {
 249                        /* use manual power-up sequence */
 250                        ret = twl6040_power_up_manual(twl6040);
 251                        if (ret) {
 252                                twl6040->power_count = 0;
 253                                goto out;
 254                        }
 255                }
 256                /* Default PLL configuration after power up */
 257                twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL;
 258                twl6040->sysclk = 19200000;
 259                twl6040->mclk = 32768;
 260        } else {
 261                /* already powered-down */
 262                if (!twl6040->power_count) {
 263                        dev_err(twl6040->dev,
 264                                "device is already powered-off\n");
 265                        ret = -EPERM;
 266                        goto out;
 267                }
 268
 269                if (--twl6040->power_count)
 270                        goto out;
 271
 272                if (gpio_is_valid(twl6040->audpwron)) {
 273                        /* use AUDPWRON line */
 274                        gpio_set_value(twl6040->audpwron, 0);
 275
 276                        /* power-down sequence latency */
 277                        usleep_range(500, 700);
 278                } else {
 279                        /* use manual power-down sequence */
 280                        twl6040_power_down_manual(twl6040);
 281                }
 282                twl6040->sysclk = 0;
 283                twl6040->mclk = 0;
 284        }
 285
 286out:
 287        mutex_unlock(&twl6040->mutex);
 288        return ret;
 289}
 290EXPORT_SYMBOL(twl6040_power);
 291
 292int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
 293                    unsigned int freq_in, unsigned int freq_out)
 294{
 295        u8 hppllctl, lppllctl;
 296        int ret = 0;
 297
 298        mutex_lock(&twl6040->mutex);
 299
 300        hppllctl = twl6040_reg_read(twl6040, TWL6040_REG_HPPLLCTL);
 301        lppllctl = twl6040_reg_read(twl6040, TWL6040_REG_LPPLLCTL);
 302
 303        /* Force full reconfiguration when switching between PLL */
 304        if (pll_id != twl6040->pll) {
 305                twl6040->sysclk = 0;
 306                twl6040->mclk = 0;
 307        }
 308
 309        switch (pll_id) {
 310        case TWL6040_SYSCLK_SEL_LPPLL:
 311                /* low-power PLL divider */
 312                /* Change the sysclk configuration only if it has been canged */
 313                if (twl6040->sysclk != freq_out) {
 314                        switch (freq_out) {
 315                        case 17640000:
 316                                lppllctl |= TWL6040_LPLLFIN;
 317                                break;
 318                        case 19200000:
 319                                lppllctl &= ~TWL6040_LPLLFIN;
 320                                break;
 321                        default:
 322                                dev_err(twl6040->dev,
 323                                        "freq_out %d not supported\n",
 324                                        freq_out);
 325                                ret = -EINVAL;
 326                                goto pll_out;
 327                        }
 328                        twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL,
 329                                          lppllctl);
 330                }
 331
 332                /* The PLL in use has not been change, we can exit */
 333                if (twl6040->pll == pll_id)
 334                        break;
 335
 336                switch (freq_in) {
 337                case 32768:
 338                        lppllctl |= TWL6040_LPLLENA;
 339                        twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL,
 340                                          lppllctl);
 341                        mdelay(5);
 342                        lppllctl &= ~TWL6040_HPLLSEL;
 343                        twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL,
 344                                          lppllctl);
 345                        hppllctl &= ~TWL6040_HPLLENA;
 346                        twl6040_reg_write(twl6040, TWL6040_REG_HPPLLCTL,
 347                                          hppllctl);
 348                        break;
 349                default:
 350                        dev_err(twl6040->dev,
 351                                "freq_in %d not supported\n", freq_in);
 352                        ret = -EINVAL;
 353                        goto pll_out;
 354                }
 355                break;
 356        case TWL6040_SYSCLK_SEL_HPPLL:
 357                /* high-performance PLL can provide only 19.2 MHz */
 358                if (freq_out != 19200000) {
 359                        dev_err(twl6040->dev,
 360                                "freq_out %d not supported\n", freq_out);
 361                        ret = -EINVAL;
 362                        goto pll_out;
 363                }
 364
 365                if (twl6040->mclk != freq_in) {
 366                        hppllctl &= ~TWL6040_MCLK_MSK;
 367
 368                        switch (freq_in) {
 369                        case 12000000:
 370                                /* PLL enabled, active mode */
 371                                hppllctl |= TWL6040_MCLK_12000KHZ |
 372                                            TWL6040_HPLLENA;
 373                                break;
 374                        case 19200000:
 375                                /*
 376                                * PLL disabled
 377                                * (enable PLL if MCLK jitter quality
 378                                *  doesn't meet specification)
 379                                */
 380                                hppllctl |= TWL6040_MCLK_19200KHZ;
 381                                break;
 382                        case 26000000:
 383                                /* PLL enabled, active mode */
 384                                hppllctl |= TWL6040_MCLK_26000KHZ |
 385                                            TWL6040_HPLLENA;
 386                                break;
 387                        case 38400000:
 388                                /* PLL enabled, active mode */
 389                                hppllctl |= TWL6040_MCLK_38400KHZ |
 390                                            TWL6040_HPLLENA;
 391                                break;
 392                        default:
 393                                dev_err(twl6040->dev,
 394                                        "freq_in %d not supported\n", freq_in);
 395                                ret = -EINVAL;
 396                                goto pll_out;
 397                        }
 398
 399                        /*
 400                         * enable clock slicer to ensure input waveform is
 401                         * square
 402                         */
 403                        hppllctl |= TWL6040_HPLLSQRENA;
 404
 405                        twl6040_reg_write(twl6040, TWL6040_REG_HPPLLCTL,
 406                                          hppllctl);
 407                        usleep_range(500, 700);
 408                        lppllctl |= TWL6040_HPLLSEL;
 409                        twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL,
 410                                          lppllctl);
 411                        lppllctl &= ~TWL6040_LPLLENA;
 412                        twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL,
 413                                          lppllctl);
 414                }
 415                break;
 416        default:
 417                dev_err(twl6040->dev, "unknown pll id %d\n", pll_id);
 418                ret = -EINVAL;
 419                goto pll_out;
 420        }
 421
 422        twl6040->sysclk = freq_out;
 423        twl6040->mclk = freq_in;
 424        twl6040->pll = pll_id;
 425
 426pll_out:
 427        mutex_unlock(&twl6040->mutex);
 428        return ret;
 429}
 430EXPORT_SYMBOL(twl6040_set_pll);
 431
 432int twl6040_get_pll(struct twl6040 *twl6040)
 433{
 434        if (twl6040->power_count)
 435                return twl6040->pll;
 436        else
 437                return -ENODEV;
 438}
 439EXPORT_SYMBOL(twl6040_get_pll);
 440
 441unsigned int twl6040_get_sysclk(struct twl6040 *twl6040)
 442{
 443        return twl6040->sysclk;
 444}
 445EXPORT_SYMBOL(twl6040_get_sysclk);
 446
 447/* Get the combined status of the vibra control register */
 448int twl6040_get_vibralr_status(struct twl6040 *twl6040)
 449{
 450        unsigned int reg;
 451        int ret;
 452        u8 status;
 453
 454        ret = regmap_read(twl6040->regmap, TWL6040_REG_VIBCTLL, &reg);
 455        if (ret != 0)
 456                return ret;
 457        status = reg;
 458
 459        ret = regmap_read(twl6040->regmap, TWL6040_REG_VIBCTLR, &reg);
 460        if (ret != 0)
 461                return ret;
 462        status |= reg;
 463
 464        status &= (TWL6040_VIBENA | TWL6040_VIBSEL);
 465
 466        return status;
 467}
 468EXPORT_SYMBOL(twl6040_get_vibralr_status);
 469
 470static struct resource twl6040_vibra_rsrc[] = {
 471        {
 472                .flags = IORESOURCE_IRQ,
 473        },
 474};
 475
 476static struct resource twl6040_codec_rsrc[] = {
 477        {
 478                .flags = IORESOURCE_IRQ,
 479        },
 480};
 481
 482static bool twl6040_readable_reg(struct device *dev, unsigned int reg)
 483{
 484        /* Register 0 is not readable */
 485        if (!reg)
 486                return false;
 487        return true;
 488}
 489
 490static bool twl6040_volatile_reg(struct device *dev, unsigned int reg)
 491{
 492        switch (reg) {
 493        case TWL6040_REG_VIBCTLL:
 494        case TWL6040_REG_VIBCTLR:
 495        case TWL6040_REG_INTMR:
 496                return false;
 497        default:
 498                return true;
 499        }
 500}
 501
 502static struct regmap_config twl6040_regmap_config = {
 503        .reg_bits = 8,
 504        .val_bits = 8,
 505        .max_register = TWL6040_REG_STATUS, /* 0x2e */
 506
 507        .readable_reg = twl6040_readable_reg,
 508        .volatile_reg = twl6040_volatile_reg,
 509
 510        .cache_type = REGCACHE_RBTREE,
 511};
 512
 513static const struct regmap_irq twl6040_irqs[] = {
 514        { .reg_offset = 0, .mask = TWL6040_THINT, },
 515        { .reg_offset = 0, .mask = TWL6040_PLUGINT | TWL6040_UNPLUGINT, },
 516        { .reg_offset = 0, .mask = TWL6040_HOOKINT, },
 517        { .reg_offset = 0, .mask = TWL6040_HFINT, },
 518        { .reg_offset = 0, .mask = TWL6040_VIBINT, },
 519        { .reg_offset = 0, .mask = TWL6040_READYINT, },
 520};
 521
 522static struct regmap_irq_chip twl6040_irq_chip = {
 523        .name = "twl6040",
 524        .irqs = twl6040_irqs,
 525        .num_irqs = ARRAY_SIZE(twl6040_irqs),
 526
 527        .num_regs = 1,
 528        .status_base = TWL6040_REG_INTID,
 529        .mask_base = TWL6040_REG_INTMR,
 530};
 531
 532static int twl6040_probe(struct i2c_client *client,
 533                         const struct i2c_device_id *id)
 534{
 535        struct device_node *node = client->dev.of_node;
 536        struct twl6040 *twl6040;
 537        struct mfd_cell *cell = NULL;
 538        int irq, ret, children = 0;
 539
 540        if (!node) {
 541                dev_err(&client->dev, "of node is missing\n");
 542                return -EINVAL;
 543        }
 544
 545        /* In order to operate correctly we need valid interrupt config */
 546        if (!client->irq) {
 547                dev_err(&client->dev, "Invalid IRQ configuration\n");
 548                return -EINVAL;
 549        }
 550
 551        twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040),
 552                               GFP_KERNEL);
 553        if (!twl6040)
 554                return -ENOMEM;
 555
 556        twl6040->regmap = devm_regmap_init_i2c(client, &twl6040_regmap_config);
 557        if (IS_ERR(twl6040->regmap))
 558                return PTR_ERR(twl6040->regmap);
 559
 560        i2c_set_clientdata(client, twl6040);
 561
 562        twl6040->supplies[0].supply = "vio";
 563        twl6040->supplies[1].supply = "v2v1";
 564        ret = devm_regulator_bulk_get(&client->dev, TWL6040_NUM_SUPPLIES,
 565                                      twl6040->supplies);
 566        if (ret != 0) {
 567                dev_err(&client->dev, "Failed to get supplies: %d\n", ret);
 568                goto regulator_get_err;
 569        }
 570
 571        ret = regulator_bulk_enable(TWL6040_NUM_SUPPLIES, twl6040->supplies);
 572        if (ret != 0) {
 573                dev_err(&client->dev, "Failed to enable supplies: %d\n", ret);
 574                goto regulator_get_err;
 575        }
 576
 577        twl6040->dev = &client->dev;
 578        twl6040->irq = client->irq;
 579
 580        mutex_init(&twl6040->mutex);
 581        init_completion(&twl6040->ready);
 582
 583        twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV);
 584
 585        /* ERRATA: Automatic power-up is not possible in ES1.0 */
 586        if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0)
 587                twl6040->audpwron = of_get_named_gpio(node,
 588                                                      "ti,audpwron-gpio", 0);
 589        else
 590                twl6040->audpwron = -EINVAL;
 591
 592        if (gpio_is_valid(twl6040->audpwron)) {
 593                ret = devm_gpio_request_one(&client->dev, twl6040->audpwron,
 594                                            GPIOF_OUT_INIT_LOW, "audpwron");
 595                if (ret)
 596                        goto gpio_err;
 597        }
 598
 599        ret = regmap_add_irq_chip(twl6040->regmap, twl6040->irq, IRQF_ONESHOT,
 600                                  0, &twl6040_irq_chip,&twl6040->irq_data);
 601        if (ret < 0)
 602                goto gpio_err;
 603
 604        twl6040->irq_ready = regmap_irq_get_virq(twl6040->irq_data,
 605                                                 TWL6040_IRQ_READY);
 606        twl6040->irq_th = regmap_irq_get_virq(twl6040->irq_data,
 607                                              TWL6040_IRQ_TH);
 608
 609        ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_ready, NULL,
 610                                        twl6040_readyint_handler, IRQF_ONESHOT,
 611                                        "twl6040_irq_ready", twl6040);
 612        if (ret) {
 613                dev_err(twl6040->dev, "READY IRQ request failed: %d\n", ret);
 614                goto readyirq_err;
 615        }
 616
 617        ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_th, NULL,
 618                                        twl6040_thint_handler, IRQF_ONESHOT,
 619                                        "twl6040_irq_th", twl6040);
 620        if (ret) {
 621                dev_err(twl6040->dev, "Thermal IRQ request failed: %d\n", ret);
 622                goto thirq_err;
 623        }
 624
 625        /* dual-access registers controlled by I2C only */
 626        twl6040_set_bits(twl6040, TWL6040_REG_ACCCTL, TWL6040_I2CSEL);
 627
 628        /*
 629         * The main functionality of twl6040 to provide audio on OMAP4+ systems.
 630         * We can add the ASoC codec child whenever this driver has been loaded.
 631         */
 632        irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_PLUG);
 633        cell = &twl6040->cells[children];
 634        cell->name = "twl6040-codec";
 635        twl6040_codec_rsrc[0].start = irq;
 636        twl6040_codec_rsrc[0].end = irq;
 637        cell->resources = twl6040_codec_rsrc;
 638        cell->num_resources = ARRAY_SIZE(twl6040_codec_rsrc);
 639        children++;
 640
 641        /* Vibra input driver support */
 642        if (twl6040_has_vibra(node)) {
 643                irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_VIB);
 644
 645                cell = &twl6040->cells[children];
 646                cell->name = "twl6040-vibra";
 647                twl6040_vibra_rsrc[0].start = irq;
 648                twl6040_vibra_rsrc[0].end = irq;
 649                cell->resources = twl6040_vibra_rsrc;
 650                cell->num_resources = ARRAY_SIZE(twl6040_vibra_rsrc);
 651                children++;
 652        }
 653
 654        /* GPO support */
 655        cell = &twl6040->cells[children];
 656        cell->name = "twl6040-gpo";
 657        children++;
 658
 659        ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children,
 660                              NULL, 0, NULL);
 661        if (ret)
 662                goto mfd_err;
 663
 664        return 0;
 665
 666mfd_err:
 667        devm_free_irq(&client->dev, twl6040->irq_th, twl6040);
 668thirq_err:
 669        devm_free_irq(&client->dev, twl6040->irq_ready, twl6040);
 670readyirq_err:
 671        regmap_del_irq_chip(twl6040->irq, twl6040->irq_data);
 672gpio_err:
 673        regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies);
 674regulator_get_err:
 675        i2c_set_clientdata(client, NULL);
 676
 677        return ret;
 678}
 679
 680static int twl6040_remove(struct i2c_client *client)
 681{
 682        struct twl6040 *twl6040 = i2c_get_clientdata(client);
 683
 684        if (twl6040->power_count)
 685                twl6040_power(twl6040, 0);
 686
 687        devm_free_irq(&client->dev, twl6040->irq_ready, twl6040);
 688        devm_free_irq(&client->dev, twl6040->irq_th, twl6040);
 689        regmap_del_irq_chip(twl6040->irq, twl6040->irq_data);
 690
 691        mfd_remove_devices(&client->dev);
 692        i2c_set_clientdata(client, NULL);
 693
 694        regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies);
 695
 696        return 0;
 697}
 698
 699static const struct i2c_device_id twl6040_i2c_id[] = {
 700        { "twl6040", 0, },
 701        { "twl6041", 0, },
 702        { },
 703};
 704MODULE_DEVICE_TABLE(i2c, twl6040_i2c_id);
 705
 706static struct i2c_driver twl6040_driver = {
 707        .driver = {
 708                .name = "twl6040",
 709                .owner = THIS_MODULE,
 710        },
 711        .probe          = twl6040_probe,
 712        .remove         = twl6040_remove,
 713        .id_table       = twl6040_i2c_id,
 714};
 715
 716module_i2c_driver(twl6040_driver);
 717
 718MODULE_DESCRIPTION("TWL6040 MFD");
 719MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
 720MODULE_AUTHOR("Jorge Eduardo Candelaria <jorge.candelaria@ti.com>");
 721MODULE_LICENSE("GPL");
 722MODULE_ALIAS("platform:twl6040");
 723
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.