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