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_IRQ_RTC_ALARM0,
  79                .end    = MAX8925_IRQ_RTC_ALARM0,
  80                .flags  = IORESOURCE_IRQ,
  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_THM_OK_R] = {
 214                .reg            = MAX8925_CHG_IRQ2,
 215                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 216                .offs           = 1 << 0,
 217        },
 218        [MAX8925_IRQ_VCHG_THM_OK_F] = {
 219                .reg            = MAX8925_CHG_IRQ2,
 220                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 221                .offs           = 1 << 1,
 222        },
 223        [MAX8925_IRQ_VCHG_SYSLOW_F] = {
 224                .reg            = MAX8925_CHG_IRQ2,
 225                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 226                .offs           = 1 << 2,
 227        },
 228        [MAX8925_IRQ_VCHG_SYSLOW_R] = {
 229                .reg            = MAX8925_CHG_IRQ2,
 230                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 231                .offs           = 1 << 3,
 232        },
 233        [MAX8925_IRQ_VCHG_RST] = {
 234                .reg            = MAX8925_CHG_IRQ2,
 235                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 236                .offs           = 1 << 4,
 237        },
 238        [MAX8925_IRQ_VCHG_DONE] = {
 239                .reg            = MAX8925_CHG_IRQ2,
 240                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 241                .offs           = 1 << 5,
 242        },
 243        [MAX8925_IRQ_VCHG_TOPOFF] = {
 244                .reg            = MAX8925_CHG_IRQ2,
 245                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 246                .offs           = 1 << 6,
 247        },
 248        [MAX8925_IRQ_VCHG_TMR_FAULT] = {
 249                .reg            = MAX8925_CHG_IRQ2,
 250                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 251                .offs           = 1 << 7,
 252        },
 253        [MAX8925_IRQ_GPM_RSTIN] = {
 254                .reg            = MAX8925_ON_OFF_IRQ1,
 255                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 256                .offs           = 1 << 0,
 257        },
 258        [MAX8925_IRQ_GPM_MPL] = {
 259                .reg            = MAX8925_ON_OFF_IRQ1,
 260                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 261                .offs           = 1 << 1,
 262        },
 263        [MAX8925_IRQ_GPM_SW_3SEC] = {
 264                .reg            = MAX8925_ON_OFF_IRQ1,
 265                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 266                .offs           = 1 << 2,
 267        },
 268        [MAX8925_IRQ_GPM_EXTON_F] = {
 269                .reg            = MAX8925_ON_OFF_IRQ1,
 270                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 271                .offs           = 1 << 3,
 272        },
 273        [MAX8925_IRQ_GPM_EXTON_R] = {
 274                .reg            = MAX8925_ON_OFF_IRQ1,
 275                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 276                .offs           = 1 << 4,
 277        },
 278        [MAX8925_IRQ_GPM_SW_1SEC] = {
 279                .reg            = MAX8925_ON_OFF_IRQ1,
 280                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 281                .offs           = 1 << 5,
 282        },
 283        [MAX8925_IRQ_GPM_SW_F] = {
 284                .reg            = MAX8925_ON_OFF_IRQ1,
 285                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 286                .offs           = 1 << 6,
 287        },
 288        [MAX8925_IRQ_GPM_SW_R] = {
 289                .reg            = MAX8925_ON_OFF_IRQ1,
 290                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 291                .offs           = 1 << 7,
 292        },
 293        [MAX8925_IRQ_GPM_SYSCKEN_F] = {
 294                .reg            = MAX8925_ON_OFF_IRQ2,
 295                .mask_reg       = MAX8925_ON_OFF_IRQ2_MASK,
 296                .offs           = 1 << 0,
 297        },
 298        [MAX8925_IRQ_GPM_SYSCKEN_R] = {
 299                .reg            = MAX8925_ON_OFF_IRQ2,
 300                .mask_reg       = MAX8925_ON_OFF_IRQ2_MASK,
 301                .offs           = 1 << 1,
 302        },
 303        [MAX8925_IRQ_RTC_ALARM1] = {
 304                .reg            = MAX8925_RTC_IRQ,
 305                .mask_reg       = MAX8925_RTC_IRQ_MASK,
 306                .offs           = 1 << 2,
 307                .flags          = FLAGS_RTC,
 308        },
 309        [MAX8925_IRQ_RTC_ALARM0] = {
 310                .reg            = MAX8925_RTC_IRQ,
 311                .mask_reg       = MAX8925_RTC_IRQ_MASK,
 312                .offs           = 1 << 3,
 313                .flags          = FLAGS_RTC,
 314        },
 315        [MAX8925_IRQ_TSC_STICK] = {
 316                .reg            = MAX8925_TSC_IRQ,
 317                .mask_reg       = MAX8925_TSC_IRQ_MASK,
 318                .offs           = 1 << 0,
 319                .flags          = FLAGS_ADC,
 320                .tsc_irq        = 1,
 321        },
 322        [MAX8925_IRQ_TSC_NSTICK] = {
 323                .reg            = MAX8925_TSC_IRQ,
 324                .mask_reg       = MAX8925_TSC_IRQ_MASK,
 325                .offs           = 1 << 1,
 326                .flags          = FLAGS_ADC,
 327                .tsc_irq        = 1,
 328        },
 329};
 330
 331static inline struct max8925_irq_data *irq_to_max8925(struct max8925_chip *chip,
 332                                                      int irq)
 333{
 334        return &max8925_irqs[irq - chip->irq_base];
 335}
 336
 337static irqreturn_t max8925_irq(int irq, void *data)
 338{
 339        struct max8925_chip *chip = data;
 340        struct max8925_irq_data *irq_data;
 341        struct i2c_client *i2c;
 342        int read_reg = -1, value = 0;
 343        int i;
 344
 345        for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
 346                irq_data = &max8925_irqs[i];
 347                /* TSC IRQ should be serviced in max8925_tsc_irq() */
 348                if (irq_data->tsc_irq)
 349                        continue;
 350                if (irq_data->flags == FLAGS_RTC)
 351                        i2c = chip->rtc;
 352                else if (irq_data->flags == FLAGS_ADC)
 353                        i2c = chip->adc;
 354                else
 355                        i2c = chip->i2c;
 356                if (read_reg != irq_data->reg) {
 357                        read_reg = irq_data->reg;
 358                        value = max8925_reg_read(i2c, irq_data->reg);
 359                }
 360                if (value & irq_data->enable)
 361                        handle_nested_irq(chip->irq_base + i);
 362        }
 363        return IRQ_HANDLED;
 364}
 365
 366static irqreturn_t max8925_tsc_irq(int irq, void *data)
 367{
 368        struct max8925_chip *chip = data;
 369        struct max8925_irq_data *irq_data;
 370        struct i2c_client *i2c;
 371        int read_reg = -1, value = 0;
 372        int i;
 373
 374        for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
 375                irq_data = &max8925_irqs[i];
 376                /* non TSC IRQ should be serviced in max8925_irq() */
 377                if (!irq_data->tsc_irq)
 378                        continue;
 379                if (irq_data->flags == FLAGS_RTC)
 380                        i2c = chip->rtc;
 381                else if (irq_data->flags == FLAGS_ADC)
 382                        i2c = chip->adc;
 383                else
 384                        i2c = chip->i2c;
 385                if (read_reg != irq_data->reg) {
 386                        read_reg = irq_data->reg;
 387                        value = max8925_reg_read(i2c, irq_data->reg);
 388                }
 389                if (value & irq_data->enable)
 390                        handle_nested_irq(chip->irq_base + i);
 391        }
 392        return IRQ_HANDLED;
 393}
 394
 395static void max8925_irq_lock(struct irq_data *data)
 396{
 397        struct max8925_chip *chip = irq_data_get_irq_chip_data(data);
 398
 399        mutex_lock(&chip->irq_lock);
 400}
 401
 402static void max8925_irq_sync_unlock(struct irq_data *data)
 403{
 404        struct max8925_chip *chip = irq_data_get_irq_chip_data(data);
 405        struct max8925_irq_data *irq_data;
 406        static unsigned char cache_chg[2] = {0xff, 0xff};
 407        static unsigned char cache_on[2] = {0xff, 0xff};
 408        static unsigned char cache_rtc = 0xff, cache_tsc = 0xff;
 409        unsigned char irq_chg[2], irq_on[2];
 410        unsigned char irq_rtc, irq_tsc;
 411        int i;
 412
 413        /* Load cached value. In initial, all IRQs are masked */
 414        irq_chg[0] = cache_chg[0];
 415        irq_chg[1] = cache_chg[1];
 416        irq_on[0] = cache_on[0];
 417        irq_on[1] = cache_on[1];
 418        irq_rtc = cache_rtc;
 419        irq_tsc = cache_tsc;
 420        for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
 421                irq_data = &max8925_irqs[i];
 422                /* 1 -- disable, 0 -- enable */
 423                switch (irq_data->mask_reg) {
 424                case MAX8925_CHG_IRQ1_MASK:
 425                        irq_chg[0] &= ~irq_data->enable;
 426                        break;
 427                case MAX8925_CHG_IRQ2_MASK:
 428                        irq_chg[1] &= ~irq_data->enable;
 429                        break;
 430                case MAX8925_ON_OFF_IRQ1_MASK:
 431                        irq_on[0] &= ~irq_data->enable;
 432                        break;
 433                case MAX8925_ON_OFF_IRQ2_MASK:
 434                        irq_on[1] &= ~irq_data->enable;
 435                        break;
 436                case MAX8925_RTC_IRQ_MASK:
 437                        irq_rtc &= ~irq_data->enable;
 438                        break;
 439                case MAX8925_TSC_IRQ_MASK:
 440                        irq_tsc &= ~irq_data->enable;
 441                        break;
 442                default:
 443                        dev_err(chip->dev, "wrong IRQ\n");
 444                        break;
 445                }
 446        }
 447        /* update mask into registers */
 448        if (cache_chg[0] != irq_chg[0]) {
 449                cache_chg[0] = irq_chg[0];
 450                max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ1_MASK,
 451                        irq_chg[0]);
 452        }
 453        if (cache_chg[1] != irq_chg[1]) {
 454                cache_chg[1] = irq_chg[1];
 455                max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ2_MASK,
 456                        irq_chg[1]);
 457        }
 458        if (cache_on[0] != irq_on[0]) {
 459                cache_on[0] = irq_on[0];
 460                max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ1_MASK,
 461                                irq_on[0]);
 462        }
 463        if (cache_on[1] != irq_on[1]) {
 464                cache_on[1] = irq_on[1];
 465                max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ2_MASK,
 466                                irq_on[1]);
 467        }
 468        if (cache_rtc != irq_rtc) {
 469                cache_rtc = irq_rtc;
 470                max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, irq_rtc);
 471        }
 472        if (cache_tsc != irq_tsc) {
 473                cache_tsc = irq_tsc;
 474                max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, irq_tsc);
 475        }
 476
 477        mutex_unlock(&chip->irq_lock);
 478}
 479
 480static void max8925_irq_enable(struct irq_data *data)
 481{
 482        struct max8925_chip *chip = irq_data_get_irq_chip_data(data);
 483        max8925_irqs[data->irq - chip->irq_base].enable
 484                = max8925_irqs[data->irq - chip->irq_base].offs;
 485}
 486
 487static void max8925_irq_disable(struct irq_data *data)
 488{
 489        struct max8925_chip *chip = irq_data_get_irq_chip_data(data);
 490        max8925_irqs[data->irq - chip->irq_base].enable = 0;
 491}
 492
 493static struct irq_chip max8925_irq_chip = {
 494        .name           = "max8925",
 495        .irq_bus_lock   = max8925_irq_lock,
 496        .irq_bus_sync_unlock = max8925_irq_sync_unlock,
 497        .irq_enable     = max8925_irq_enable,
 498        .irq_disable    = max8925_irq_disable,
 499};
 500
 501static int max8925_irq_init(struct max8925_chip *chip, int irq,
 502                            struct max8925_platform_data *pdata)
 503{
 504        unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
 505        int i, ret;
 506        int __irq;
 507
 508        if (!pdata || !pdata->irq_base) {
 509                dev_warn(chip->dev, "No interrupt support on IRQ base\n");
 510                return -EINVAL;
 511        }
 512        /* clear all interrupts */
 513        max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ1);
 514        max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ2);
 515        max8925_reg_read(chip->i2c, MAX8925_ON_OFF_IRQ1);
 516        max8925_reg_read(chip->i2c, MAX8925_ON_OFF_IRQ2);
 517        max8925_reg_read(chip->rtc, MAX8925_RTC_IRQ);
 518        max8925_reg_read(chip->adc, MAX8925_TSC_IRQ);
 519        /* mask all interrupts except for TSC */
 520        max8925_reg_write(chip->rtc, MAX8925_ALARM0_CNTL, 0);
 521        max8925_reg_write(chip->rtc, MAX8925_ALARM1_CNTL, 0);
 522        max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ1_MASK, 0xff);
 523        max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ2_MASK, 0xff);
 524        max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ1_MASK, 0xff);
 525        max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ2_MASK, 0xff);
 526        max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, 0xff);
 527
 528        mutex_init(&chip->irq_lock);
 529        chip->core_irq = irq;
 530        chip->irq_base = pdata->irq_base;
 531
 532        /* register with genirq */
 533        for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
 534                __irq = i + chip->irq_base;
 535                irq_set_chip_data(__irq, chip);
 536                irq_set_chip_and_handler(__irq, &max8925_irq_chip,
 537                                         handle_edge_irq);
 538                irq_set_nested_thread(__irq, 1);
 539#ifdef CONFIG_ARM
 540                set_irq_flags(__irq, IRQF_VALID);
 541#else
 542                irq_set_noprobe(__irq);
 543#endif
 544        }
 545        if (!irq) {
 546                dev_warn(chip->dev, "No interrupt support on core IRQ\n");
 547                goto tsc_irq;
 548        }
 549
 550        ret = request_threaded_irq(irq, NULL, max8925_irq, flags,
 551                                   "max8925", chip);
 552        if (ret) {
 553                dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret);
 554                chip->core_irq = 0;
 555        }
 556
 557tsc_irq:
 558        /* mask TSC interrupt */
 559        max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, 0x0f);
 560
 561        if (!pdata->tsc_irq) {
 562                dev_warn(chip->dev, "No interrupt support on TSC IRQ\n");
 563                return 0;
 564        }
 565        chip->tsc_irq = pdata->tsc_irq;
 566
 567        ret = request_threaded_irq(chip->tsc_irq, NULL, max8925_tsc_irq,
 568                                   flags, "max8925-tsc", chip);
 569        if (ret) {
 570                dev_err(chip->dev, "Failed to request TSC IRQ: %d\n", ret);
 571                chip->tsc_irq = 0;
 572        }
 573        return 0;
 574}
 575
 576int __devinit max8925_device_init(struct max8925_chip *chip,
 577                                  struct max8925_platform_data *pdata)
 578{
 579        int ret;
 580
 581        max8925_irq_init(chip, chip->i2c->irq, pdata);
 582
 583        if (pdata && (pdata->power || pdata->touch)) {
 584                /* enable ADC to control internal reference */
 585                max8925_set_bits(chip->i2c, MAX8925_RESET_CNFG, 1, 1);
 586                /* enable internal reference for ADC */
 587                max8925_set_bits(chip->adc, MAX8925_TSC_CNFG1, 3, 2);
 588                /* check for internal reference IRQ */
 589                do {
 590                        ret = max8925_reg_read(chip->adc, MAX8925_TSC_IRQ);
 591                } while (ret & MAX8925_NREF_OK);
 592                /* enaable ADC scheduler, interval is 1 second */
 593                max8925_set_bits(chip->adc, MAX8925_ADC_SCHED, 3, 2);
 594        }
 595
 596        /* enable Momentary Power Loss */
 597        max8925_set_bits(chip->rtc, MAX8925_MPL_CNTL, 1 << 4, 1 << 4);
 598
 599        ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
 600                              ARRAY_SIZE(rtc_devs),
 601                              &rtc_resources[0], chip->irq_base, NULL);
 602        if (ret < 0) {
 603                dev_err(chip->dev, "Failed to add rtc subdev\n");
 604                goto out;
 605        }
 606
 607        ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],
 608                              ARRAY_SIZE(onkey_devs),
 609                              &onkey_resources[0], 0, NULL);
 610        if (ret < 0) {
 611                dev_err(chip->dev, "Failed to add onkey subdev\n");
 612                goto out_dev;
 613        }
 614
 615        if (pdata) {
 616                ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
 617                                      ARRAY_SIZE(regulator_devs),
 618                                      &regulator_resources[0], 0, NULL);
 619                if (ret < 0) {
 620                        dev_err(chip->dev, "Failed to add regulator subdev\n");
 621                        goto out_dev;
 622                }
 623        }
 624
 625        if (pdata && pdata->backlight) {
 626                ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0],
 627                                      ARRAY_SIZE(backlight_devs),
 628                                      &backlight_resources[0], 0, NULL);
 629                if (ret < 0) {
 630                        dev_err(chip->dev, "Failed to add backlight subdev\n");
 631                        goto out_dev;
 632                }
 633        }
 634
 635        if (pdata && pdata->power) {
 636                ret = mfd_add_devices(chip->dev, 0, &power_devs[0],
 637                                        ARRAY_SIZE(power_devs),
 638                                      &power_supply_resources[0], 0, NULL);
 639                if (ret < 0) {
 640                        dev_err(chip->dev, "Failed to add power supply "
 641                                "subdev\n");
 642                        goto out_dev;
 643                }
 644        }
 645
 646        if (pdata && pdata->touch) {
 647                ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
 648                                      ARRAY_SIZE(touch_devs),
 649                                      &touch_resources[0], 0, NULL);
 650                if (ret < 0) {
 651                        dev_err(chip->dev, "Failed to add touch subdev\n");
 652                        goto out_dev;
 653                }
 654        }
 655
 656        return 0;
 657out_dev:
 658        mfd_remove_devices(chip->dev);
 659out:
 660        return ret;
 661}
 662
 663void __devexit max8925_device_exit(struct max8925_chip *chip)
 664{
 665        if (chip->core_irq)
 666                free_irq(chip->core_irq, chip);
 667        if (chip->tsc_irq)
 668                free_irq(chip->tsc_irq, chip);
 669        mfd_remove_devices(chip->dev);
 670}
 671
 672
 673MODULE_DESCRIPTION("PMIC Driver for Maxim MAX8925");
 674MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com");
 675MODULE_LICENSE("GPL");
 676
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.