linux/drivers/mfd/max8925-core.c
<<
>>
Prefs
   1/*
   2 * Base driver for Maxim MAX8925
   3 *
   4 * Copyright (C) 2009-2010 Marvell International Ltd.
   5 *      Haojian Zhuang <haojian.zhuang@marvell.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 */
  11
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/i2c.h>
  15#include <linux/irq.h>
  16#include <linux/interrupt.h>
  17#include <linux/platform_device.h>
  18#include <linux/mfd/core.h>
  19#include <linux/mfd/max8925.h>
  20
  21static struct resource backlight_resources[] = {
  22        {
  23                .name   = "max8925-backlight",
  24                .start  = MAX8925_WLED_MODE_CNTL,
  25                .end    = MAX8925_WLED_CNTL,
  26                .flags  = IORESOURCE_IO,
  27        },
  28};
  29
  30static struct mfd_cell backlight_devs[] = {
  31        {
  32                .name           = "max8925-backlight",
  33                .num_resources  = 1,
  34                .resources      = &backlight_resources[0],
  35                .id             = -1,
  36        },
  37};
  38
  39static struct resource touch_resources[] = {
  40        {
  41                .name   = "max8925-tsc",
  42                .start  = MAX8925_TSC_IRQ,
  43                .end    = MAX8925_ADC_RES_END,
  44                .flags  = IORESOURCE_IO,
  45        },
  46};
  47
  48static struct mfd_cell touch_devs[] = {
  49        {
  50                .name           = "max8925-touch",
  51                .num_resources  = 1,
  52                .resources      = &touch_resources[0],
  53                .id             = -1,
  54        },
  55};
  56
  57static struct resource power_supply_resources[] = {
  58        {
  59                .name   = "max8925-power",
  60                .start  = MAX8925_CHG_IRQ1,
  61                .end    = MAX8925_CHG_IRQ1_MASK,
  62                .flags  = IORESOURCE_IO,
  63        },
  64};
  65
  66static struct mfd_cell power_devs[] = {
  67        {
  68                .name           = "max8925-power",
  69                .num_resources  = 1,
  70                .resources      = &power_supply_resources[0],
  71                .id             = -1,
  72        },
  73};
  74
  75static struct resource rtc_resources[] = {
  76        {
  77                .name   = "max8925-rtc",
  78                .start  = MAX8925_RTC_IRQ,
  79                .end    = MAX8925_RTC_IRQ_MASK,
  80                .flags  = IORESOURCE_IO,
  81        },
  82};
  83
  84static struct mfd_cell rtc_devs[] = {
  85        {
  86                .name           = "max8925-rtc",
  87                .num_resources  = 1,
  88                .resources      = &rtc_resources[0],
  89                .id             = -1,
  90        },
  91};
  92
  93static struct resource onkey_resources[] = {
  94        {
  95                .name   = "max8925-onkey",
  96                .start  = MAX8925_IRQ_GPM_SW_R,
  97                .end    = MAX8925_IRQ_GPM_SW_R,
  98                .flags  = IORESOURCE_IRQ,
  99        }, {
 100                .name   = "max8925-onkey",
 101                .start  = MAX8925_IRQ_GPM_SW_F,
 102                .end    = MAX8925_IRQ_GPM_SW_F,
 103                .flags  = IORESOURCE_IRQ,
 104        },
 105};
 106
 107static struct mfd_cell onkey_devs[] = {
 108        {
 109                .name           = "max8925-onkey",
 110                .num_resources  = 2,
 111                .resources      = &onkey_resources[0],
 112                .id             = -1,
 113        },
 114};
 115
 116#define MAX8925_REG_RESOURCE(_start, _end)      \
 117{                                               \
 118        .start  = MAX8925_##_start,             \
 119        .end    = MAX8925_##_end,               \
 120        .flags  = IORESOURCE_IO,                \
 121}
 122
 123static struct resource regulator_resources[] = {
 124        MAX8925_REG_RESOURCE(SDCTL1, SDCTL1),
 125        MAX8925_REG_RESOURCE(SDCTL2, SDCTL2),
 126        MAX8925_REG_RESOURCE(SDCTL3, SDCTL3),
 127        MAX8925_REG_RESOURCE(LDOCTL1, LDOCTL1),
 128        MAX8925_REG_RESOURCE(LDOCTL2, LDOCTL2),
 129        MAX8925_REG_RESOURCE(LDOCTL3, LDOCTL3),
 130        MAX8925_REG_RESOURCE(LDOCTL4, LDOCTL4),
 131        MAX8925_REG_RESOURCE(LDOCTL5, LDOCTL5),
 132        MAX8925_REG_RESOURCE(LDOCTL6, LDOCTL6),
 133        MAX8925_REG_RESOURCE(LDOCTL7, LDOCTL7),
 134        MAX8925_REG_RESOURCE(LDOCTL8, LDOCTL8),
 135        MAX8925_REG_RESOURCE(LDOCTL9, LDOCTL9),
 136        MAX8925_REG_RESOURCE(LDOCTL10, LDOCTL10),
 137        MAX8925_REG_RESOURCE(LDOCTL11, LDOCTL11),
 138        MAX8925_REG_RESOURCE(LDOCTL12, LDOCTL12),
 139        MAX8925_REG_RESOURCE(LDOCTL13, LDOCTL13),
 140        MAX8925_REG_RESOURCE(LDOCTL14, LDOCTL14),
 141        MAX8925_REG_RESOURCE(LDOCTL15, LDOCTL15),
 142        MAX8925_REG_RESOURCE(LDOCTL16, LDOCTL16),
 143        MAX8925_REG_RESOURCE(LDOCTL17, LDOCTL17),
 144        MAX8925_REG_RESOURCE(LDOCTL18, LDOCTL18),
 145        MAX8925_REG_RESOURCE(LDOCTL19, LDOCTL19),
 146        MAX8925_REG_RESOURCE(LDOCTL20, LDOCTL20),
 147};
 148
 149#define MAX8925_REG_DEVS(_id)                                           \
 150{                                                                       \
 151        .name           = "max8925-regulator",                          \
 152        .num_resources  = 1,                                            \
 153        .resources      = &regulator_resources[MAX8925_ID_##_id],       \
 154        .id             = MAX8925_ID_##_id,                             \
 155}
 156
 157static struct mfd_cell regulator_devs[] = {
 158        MAX8925_REG_DEVS(SD1),
 159        MAX8925_REG_DEVS(SD2),
 160        MAX8925_REG_DEVS(SD3),
 161        MAX8925_REG_DEVS(LDO1),
 162        MAX8925_REG_DEVS(LDO2),
 163        MAX8925_REG_DEVS(LDO3),
 164        MAX8925_REG_DEVS(LDO4),
 165        MAX8925_REG_DEVS(LDO5),
 166        MAX8925_REG_DEVS(LDO6),
 167        MAX8925_REG_DEVS(LDO7),
 168        MAX8925_REG_DEVS(LDO8),
 169        MAX8925_REG_DEVS(LDO9),
 170        MAX8925_REG_DEVS(LDO10),
 171        MAX8925_REG_DEVS(LDO11),
 172        MAX8925_REG_DEVS(LDO12),
 173        MAX8925_REG_DEVS(LDO13),
 174        MAX8925_REG_DEVS(LDO14),
 175        MAX8925_REG_DEVS(LDO15),
 176        MAX8925_REG_DEVS(LDO16),
 177        MAX8925_REG_DEVS(LDO17),
 178        MAX8925_REG_DEVS(LDO18),
 179        MAX8925_REG_DEVS(LDO19),
 180        MAX8925_REG_DEVS(LDO20),
 181};
 182
 183enum {
 184        FLAGS_ADC = 1,  /* register in ADC component */
 185        FLAGS_RTC,      /* register in RTC component */
 186};
 187
 188struct max8925_irq_data {
 189        int     reg;
 190        int     mask_reg;
 191        int     enable;         /* enable or not */
 192        int     offs;           /* bit offset in mask register */
 193        int     flags;
 194        int     tsc_irq;
 195};
 196
 197static struct max8925_irq_data max8925_irqs[] = {
 198        [MAX8925_IRQ_VCHG_DC_OVP] = {
 199                .reg            = MAX8925_CHG_IRQ1,
 200                .mask_reg       = MAX8925_CHG_IRQ1_MASK,
 201                .offs           = 1 << 0,
 202        },
 203        [MAX8925_IRQ_VCHG_DC_F] = {
 204                .reg            = MAX8925_CHG_IRQ1,
 205                .mask_reg       = MAX8925_CHG_IRQ1_MASK,
 206                .offs           = 1 << 1,
 207        },
 208        [MAX8925_IRQ_VCHG_DC_R] = {
 209                .reg            = MAX8925_CHG_IRQ1,
 210                .mask_reg       = MAX8925_CHG_IRQ1_MASK,
 211                .offs           = 1 << 2,
 212        },
 213        [MAX8925_IRQ_VCHG_USB_OVP] = {
 214                .reg            = MAX8925_CHG_IRQ1,
 215                .mask_reg       = MAX8925_CHG_IRQ1_MASK,
 216                .offs           = 1 << 3,
 217        },
 218        [MAX8925_IRQ_VCHG_USB_F] =  {
 219                .reg            = MAX8925_CHG_IRQ1,
 220                .mask_reg       = MAX8925_CHG_IRQ1_MASK,
 221                .offs           = 1 << 4,
 222        },
 223        [MAX8925_IRQ_VCHG_USB_R] = {
 224                .reg            = MAX8925_CHG_IRQ1,
 225                .mask_reg       = MAX8925_CHG_IRQ1_MASK,
 226                .offs           = 1 << 5,
 227        },
 228        [MAX8925_IRQ_VCHG_THM_OK_R] = {
 229                .reg            = MAX8925_CHG_IRQ2,
 230                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 231                .offs           = 1 << 0,
 232        },
 233        [MAX8925_IRQ_VCHG_THM_OK_F] = {
 234                .reg            = MAX8925_CHG_IRQ2,
 235                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 236                .offs           = 1 << 1,
 237        },
 238        [MAX8925_IRQ_VCHG_SYSLOW_F] = {
 239                .reg            = MAX8925_CHG_IRQ2,
 240                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 241                .offs           = 1 << 2,
 242        },
 243        [MAX8925_IRQ_VCHG_SYSLOW_R] = {
 244                .reg            = MAX8925_CHG_IRQ2,
 245                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 246                .offs           = 1 << 3,
 247        },
 248        [MAX8925_IRQ_VCHG_RST] = {
 249                .reg            = MAX8925_CHG_IRQ2,
 250                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 251                .offs           = 1 << 4,
 252        },
 253        [MAX8925_IRQ_VCHG_DONE] = {
 254                .reg            = MAX8925_CHG_IRQ2,
 255                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 256                .offs           = 1 << 5,
 257        },
 258        [MAX8925_IRQ_VCHG_TOPOFF] = {
 259                .reg            = MAX8925_CHG_IRQ2,
 260                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 261                .offs           = 1 << 6,
 262        },
 263        [MAX8925_IRQ_VCHG_TMR_FAULT] = {
 264                .reg            = MAX8925_CHG_IRQ2,
 265                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 266                .offs           = 1 << 7,
 267        },
 268        [MAX8925_IRQ_GPM_RSTIN] = {
 269                .reg            = MAX8925_ON_OFF_IRQ1,
 270                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 271                .offs           = 1 << 0,
 272        },
 273        [MAX8925_IRQ_GPM_MPL] = {
 274                .reg            = MAX8925_ON_OFF_IRQ1,
 275                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 276                .offs           = 1 << 1,
 277        },
 278        [MAX8925_IRQ_GPM_SW_3SEC] = {
 279                .reg            = MAX8925_ON_OFF_IRQ1,
 280                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 281                .offs           = 1 << 2,
 282        },
 283        [MAX8925_IRQ_GPM_EXTON_F] = {
 284                .reg            = MAX8925_ON_OFF_IRQ1,
 285                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 286                .offs           = 1 << 3,
 287        },
 288        [MAX8925_IRQ_GPM_EXTON_R] = {
 289                .reg            = MAX8925_ON_OFF_IRQ1,
 290                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 291                .offs           = 1 << 4,
 292        },
 293        [MAX8925_IRQ_GPM_SW_1SEC] = {
 294                .reg            = MAX8925_ON_OFF_IRQ1,
 295                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 296                .offs           = 1 << 5,
 297        },
 298        [MAX8925_IRQ_GPM_SW_F] = {
 299                .reg            = MAX8925_ON_OFF_IRQ1,
 300                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 301                .offs           = 1 << 6,
 302        },
 303        [MAX8925_IRQ_GPM_SW_R] = {
 304                .reg            = MAX8925_ON_OFF_IRQ1,
 305                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 306                .offs           = 1 << 7,
 307        },
 308        [MAX8925_IRQ_GPM_SYSCKEN_F] = {
 309                .reg            = MAX8925_ON_OFF_IRQ2,
 310                .mask_reg       = MAX8925_ON_OFF_IRQ2_MASK,
 311                .offs           = 1 << 0,
 312        },
 313        [MAX8925_IRQ_GPM_SYSCKEN_R] = {
 314                .reg            = MAX8925_ON_OFF_IRQ2,
 315                .mask_reg       = MAX8925_ON_OFF_IRQ2_MASK,
 316                .offs           = 1 << 1,
 317        },
 318        [MAX8925_IRQ_RTC_ALARM1] = {
 319                .reg            = MAX8925_RTC_IRQ,
 320                .mask_reg       = MAX8925_RTC_IRQ_MASK,
 321                .offs           = 1 << 2,
 322                .flags          = FLAGS_RTC,
 323        },
 324        [MAX8925_IRQ_RTC_ALARM0] = {
 325                .reg            = MAX8925_RTC_IRQ,
 326                .mask_reg       = MAX8925_RTC_IRQ_MASK,
 327                .offs           = 1 << 3,
 328                .flags          = FLAGS_RTC,
 329        },
 330        [MAX8925_IRQ_TSC_STICK] = {
 331                .reg            = MAX8925_TSC_IRQ,
 332                .mask_reg       = MAX8925_TSC_IRQ_MASK,
 333                .offs           = 1 << 0,
 334                .flags          = FLAGS_ADC,
 335                .tsc_irq        = 1,
 336        },
 337        [MAX8925_IRQ_TSC_NSTICK] = {
 338                .reg            = MAX8925_TSC_IRQ,
 339                .mask_reg       = MAX8925_TSC_IRQ_MASK,
 340                .offs           = 1 << 1,
 341                .flags          = FLAGS_ADC,
 342                .tsc_irq        = 1,
 343        },
 344};
 345
 346static inline struct max8925_irq_data *irq_to_max8925(struct max8925_chip *chip,
 347                                                      int irq)
 348{
 349        return &max8925_irqs[irq - chip->irq_base];
 350}
 351
 352static irqreturn_t max8925_irq(int irq, void *data)
 353{
 354        struct max8925_chip *chip = data;
 355        struct max8925_irq_data *irq_data;
 356        struct i2c_client *i2c;
 357        int read_reg = -1, value = 0;
 358        int i;
 359
 360        for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
 361                irq_data = &max8925_irqs[i];
 362                /* TSC IRQ should be serviced in max8925_tsc_irq() */
 363                if (irq_data->tsc_irq)
 364                        continue;
 365                if (irq_data->flags == FLAGS_RTC)
 366                        i2c = chip->rtc;
 367                else if (irq_data->flags == FLAGS_ADC)
 368                        i2c = chip->adc;
 369                else
 370                        i2c = chip->i2c;
 371                if (read_reg != irq_data->reg) {
 372                        read_reg = irq_data->reg;
 373                        value = max8925_reg_read(i2c, irq_data->reg);
 374                }
 375                if (value & irq_data->enable)
 376                        handle_nested_irq(chip->irq_base + i);
 377        }
 378        return IRQ_HANDLED;
 379}
 380
 381static irqreturn_t max8925_tsc_irq(int irq, void *data)
 382{
 383        struct max8925_chip *chip = data;
 384        struct max8925_irq_data *irq_data;
 385        struct i2c_client *i2c;
 386        int read_reg = -1, value = 0;
 387        int i;
 388
 389        for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
 390                irq_data = &max8925_irqs[i];
 391                /* non TSC IRQ should be serviced in max8925_irq() */
 392                if (!irq_data->tsc_irq)
 393                        continue;
 394                if (irq_data->flags == FLAGS_RTC)
 395                        i2c = chip->rtc;
 396                else if (irq_data->flags == FLAGS_ADC)
 397                        i2c = chip->adc;
 398                else
 399                        i2c = chip->i2c;
 400                if (read_reg != irq_data->reg) {
 401                        read_reg = irq_data->reg;
 402                        value = max8925_reg_read(i2c, irq_data->reg);
 403                }
 404                if (value & irq_data->enable)
 405                        handle_nested_irq(chip->irq_base + i);
 406        }
 407        return IRQ_HANDLED;
 408}
 409
 410static void max8925_irq_lock(struct irq_data *data)
 411{
 412        struct max8925_chip *chip = irq_data_get_irq_chip_data(data);
 413
 414        mutex_lock(&chip->irq_lock);
 415}
 416
 417static void max8925_irq_sync_unlock(struct irq_data *data)
 418{
 419        struct max8925_chip *chip = irq_data_get_irq_chip_data(data);
 420        struct max8925_irq_data *irq_data;
 421        static unsigned char cache_chg[2] = {0xff, 0xff};
 422        static unsigned char cache_on[2] = {0xff, 0xff};
 423        static unsigned char cache_rtc = 0xff, cache_tsc = 0xff;
 424        unsigned char irq_chg[2], irq_on[2];
 425        unsigned char irq_rtc, irq_tsc;
 426        int i;
 427
 428        /* Load cached value. In initial, all IRQs are masked */
 429        irq_chg[0] = cache_chg[0];
 430        irq_chg[1] = cache_chg[1];
 431        irq_on[0] = cache_on[0];
 432        irq_on[1] = cache_on[1];
 433        irq_rtc = cache_rtc;
 434        irq_tsc = cache_tsc;
 435        for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
 436                irq_data = &max8925_irqs[i];
 437                /* 1 -- disable, 0 -- enable */
 438                switch (irq_data->mask_reg) {
 439                case MAX8925_CHG_IRQ1_MASK:
 440                        irq_chg[0] &= ~irq_data->enable;
 441                        break;
 442                case MAX8925_CHG_IRQ2_MASK:
 443                        irq_chg[1] &= ~irq_data->enable;
 444                        break;
 445                case MAX8925_ON_OFF_IRQ1_MASK:
 446                        irq_on[0] &= ~irq_data->enable;
 447                        break;
 448                case MAX8925_ON_OFF_IRQ2_MASK:
 449                        irq_on[1] &= ~irq_data->enable;
 450                        break;
 451                case MAX8925_RTC_IRQ_MASK:
 452                        irq_rtc &= ~irq_data->enable;
 453                        break;
 454                case MAX8925_TSC_IRQ_MASK:
 455                        irq_tsc &= ~irq_data->enable;
 456                        break;
 457                default:
 458                        dev_err(chip->dev, "wrong IRQ\n");
 459                        break;
 460                }
 461        }
 462        /* update mask into registers */
 463        if (cache_chg[0] != irq_chg[0]) {
 464                cache_chg[0] = irq_chg[0];
 465                max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ1_MASK,
 466                        irq_chg[0]);
 467        }
 468        if (cache_chg[1] != irq_chg[1]) {
 469                cache_chg[1] = irq_chg[1];
 470                max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ2_MASK,
 471                        irq_chg[1]);
 472        }
 473        if (cache_on[0] != irq_on[0]) {
 474                cache_on[0] = irq_on[0];
 475                max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ1_MASK,
 476                                irq_on[0]);
 477        }
 478        if (cache_on[1] != irq_on[1]) {
 479                cache_on[1] = irq_on[1];
 480                max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ2_MASK,
 481                                irq_on[1]);
 482        }
 483        if (cache_rtc != irq_rtc) {
 484                cache_rtc = irq_rtc;
 485                max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, irq_rtc);
 486        }
 487        if (cache_tsc != irq_tsc) {
 488                cache_tsc = irq_tsc;
 489                max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, irq_tsc);
 490        }
 491
 492        mutex_unlock(&chip->irq_lock);
 493}
 494
 495static void max8925_irq_enable(struct irq_data *data)
 496{
 497        struct max8925_chip *chip = irq_data_get_irq_chip_data(data);
 498        max8925_irqs[data->irq - chip->irq_base].enable
 499                = max8925_irqs[data->irq - chip->irq_base].offs;
 500}
 501
 502static void max8925_irq_disable(struct irq_data *data)
 503{
 504        struct max8925_chip *chip = irq_data_get_irq_chip_data(data);
 505        max8925_irqs[data->irq - chip->irq_base].enable = 0;
 506}
 507
 508static struct irq_chip max8925_irq_chip = {
 509        .name           = "max8925",
 510        .irq_bus_lock   = max8925_irq_lock,
 511        .irq_bus_sync_unlock = max8925_irq_sync_unlock,
 512        .irq_enable     = max8925_irq_enable,
 513        .irq_disable    = max8925_irq_disable,
 514};
 515
 516static int max8925_irq_init(struct max8925_chip *chip, int irq,
 517                            struct max8925_platform_data *pdata)
 518{
 519        unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
 520        int i, ret;
 521        int __irq;
 522
 523        if (!pdata || !pdata->irq_base) {
 524                dev_warn(chip->dev, "No interrupt support on IRQ base\n");
 525                return -EINVAL;
 526        }
 527        /* clear all interrupts */
 528        max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ1);
 529        max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ2);
 530        max8925_reg_read(chip->i2c, MAX8925_ON_OFF_IRQ1);
 531        max8925_reg_read(chip->i2c, MAX8925_ON_OFF_IRQ2);
 532        max8925_reg_read(chip->rtc, MAX8925_RTC_IRQ);
 533        max8925_reg_read(chip->adc, MAX8925_TSC_IRQ);
 534        /* mask all interrupts except for TSC */
 535        max8925_reg_write(chip->rtc, MAX8925_ALARM0_CNTL, 0);
 536        max8925_reg_write(chip->rtc, MAX8925_ALARM1_CNTL, 0);
 537        max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ1_MASK, 0xff);
 538        max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ2_MASK, 0xff);
 539        max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ1_MASK, 0xff);
 540        max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ2_MASK, 0xff);
 541        max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, 0xff);
 542
 543        mutex_init(&chip->irq_lock);
 544        chip->core_irq = irq;
 545        chip->irq_base = pdata->irq_base;
 546
 547        /* register with genirq */
 548        for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
 549                __irq = i + chip->irq_base;
 550                irq_set_chip_data(__irq, chip);
 551                irq_set_chip_and_handler(__irq, &max8925_irq_chip,
 552                                         handle_edge_irq);
 553                irq_set_nested_thread(__irq, 1);
 554#ifdef CONFIG_ARM
 555                set_irq_flags(__irq, IRQF_VALID);
 556#else
 557                irq_set_noprobe(__irq);
 558#endif
 559        }
 560        if (!irq) {
 561                dev_warn(chip->dev, "No interrupt support on core IRQ\n");
 562                goto tsc_irq;
 563        }
 564
 565        ret = request_threaded_irq(irq, NULL, max8925_irq, flags,
 566                                   "max8925", chip);
 567        if (ret) {
 568                dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret);
 569                chip->core_irq = 0;
 570        }
 571
 572tsc_irq:
 573        /* mask TSC interrupt */
 574        max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, 0x0f);
 575
 576        if (!pdata->tsc_irq) {
 577                dev_warn(chip->dev, "No interrupt support on TSC IRQ\n");
 578                return 0;
 579        }
 580        chip->tsc_irq = pdata->tsc_irq;
 581
 582        ret = request_threaded_irq(chip->tsc_irq, NULL, max8925_tsc_irq,
 583                                   flags, "max8925-tsc", chip);
 584        if (ret) {
 585                dev_err(chip->dev, "Failed to request TSC IRQ: %d\n", ret);
 586                chip->tsc_irq = 0;
 587        }
 588        return 0;
 589}
 590
 591int __devinit max8925_device_init(struct max8925_chip *chip,
 592                                  struct max8925_platform_data *pdata)
 593{
 594        int ret;
 595
 596        max8925_irq_init(chip, chip->i2c->irq, pdata);
 597
 598        if (pdata && (pdata->power || pdata->touch)) {
 599                /* enable ADC to control internal reference */
 600                max8925_set_bits(chip->i2c, MAX8925_RESET_CNFG, 1, 1);
 601                /* enable internal reference for ADC */
 602                max8925_set_bits(chip->adc, MAX8925_TSC_CNFG1, 3, 2);
 603                /* check for internal reference IRQ */
 604                do {
 605                        ret = max8925_reg_read(chip->adc, MAX8925_TSC_IRQ);
 606                } while (ret & MAX8925_NREF_OK);
 607                /* enaable ADC scheduler, interval is 1 second */
 608                max8925_set_bits(chip->adc, MAX8925_ADC_SCHED, 3, 2);
 609        }
 610
 611        /* enable Momentary Power Loss */
 612        max8925_set_bits(chip->rtc, MAX8925_MPL_CNTL, 1 << 4, 1 << 4);
 613
 614        ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
 615                              ARRAY_SIZE(rtc_devs),
 616                              &rtc_resources[0], 0);
 617        if (ret < 0) {
 618                dev_err(chip->dev, "Failed to add rtc subdev\n");
 619                goto out;
 620        }
 621
 622        ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],
 623                              ARRAY_SIZE(onkey_devs),
 624                              &onkey_resources[0], 0);
 625        if (ret < 0) {
 626                dev_err(chip->dev, "Failed to add onkey subdev\n");
 627                goto out_dev;
 628        }
 629
 630        if (pdata && pdata->regulator[0]) {
 631                ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
 632                                      ARRAY_SIZE(regulator_devs),
 633                                      &regulator_resources[0], 0);
 634                if (ret < 0) {
 635                        dev_err(chip->dev, "Failed to add regulator subdev\n");
 636                        goto out_dev;
 637                }
 638        }
 639
 640        if (pdata && pdata->backlight) {
 641                ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0],
 642                                      ARRAY_SIZE(backlight_devs),
 643                                      &backlight_resources[0], 0);
 644                if (ret < 0) {
 645                        dev_err(chip->dev, "Failed to add backlight subdev\n");
 646                        goto out_dev;
 647                }
 648        }
 649
 650        if (pdata && pdata->power) {
 651                ret = mfd_add_devices(chip->dev, 0, &power_devs[0],
 652                                        ARRAY_SIZE(power_devs),
 653                                        &power_supply_resources[0], 0);
 654                if (ret < 0) {
 655                        dev_err(chip->dev, "Failed to add power supply "
 656                                "subdev\n");
 657                        goto out_dev;
 658                }
 659        }
 660
 661        if (pdata && pdata->touch) {
 662                ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
 663                                      ARRAY_SIZE(touch_devs),
 664                                      &touch_resources[0], 0);
 665                if (ret < 0) {
 666                        dev_err(chip->dev, "Failed to add touch subdev\n");
 667                        goto out_dev;
 668                }
 669        }
 670
 671        return 0;
 672out_dev:
 673        mfd_remove_devices(chip->dev);
 674out:
 675        return ret;
 676}
 677
 678void __devexit max8925_device_exit(struct max8925_chip *chip)
 679{
 680        if (chip->core_irq)
 681                free_irq(chip->core_irq, chip);
 682        if (chip->tsc_irq)
 683                free_irq(chip->tsc_irq, chip);
 684        mfd_remove_devices(chip->dev);
 685}
 686
 687
 688MODULE_DESCRIPTION("PMIC Driver for Maxim MAX8925");
 689MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com");
 690MODULE_LICENSE("GPL");
 691