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/regulator/machine.h>
  19#include <linux/mfd/core.h>
  20#include <linux/mfd/max8925.h>
  21
  22static struct resource bk_resources[] = {
  23        { 0x84, 0x84, "mode control", IORESOURCE_REG, },
  24        { 0x85, 0x85, "control",      IORESOURCE_REG, },
  25};
  26
  27static struct mfd_cell bk_devs[] = {
  28        {
  29                .name           = "max8925-backlight",
  30                .num_resources  = ARRAY_SIZE(bk_resources),
  31                .resources      = &bk_resources[0],
  32                .id             = -1,
  33        },
  34};
  35
  36static struct resource touch_resources[] = {
  37        {
  38                .name   = "max8925-tsc",
  39                .start  = MAX8925_TSC_IRQ,
  40                .end    = MAX8925_ADC_RES_END,
  41                .flags  = IORESOURCE_REG,
  42        },
  43};
  44
  45static struct mfd_cell touch_devs[] = {
  46        {
  47                .name           = "max8925-touch",
  48                .num_resources  = 1,
  49                .resources      = &touch_resources[0],
  50                .id             = -1,
  51        },
  52};
  53
  54static struct resource power_supply_resources[] = {
  55        {
  56                .name   = "max8925-power",
  57                .start  = MAX8925_CHG_IRQ1,
  58                .end    = MAX8925_CHG_IRQ1_MASK,
  59                .flags  = IORESOURCE_REG,
  60        },
  61};
  62
  63static struct mfd_cell power_devs[] = {
  64        {
  65                .name           = "max8925-power",
  66                .num_resources  = 1,
  67                .resources      = &power_supply_resources[0],
  68                .id             = -1,
  69        },
  70};
  71
  72static struct resource rtc_resources[] = {
  73        {
  74                .name   = "max8925-rtc",
  75                .start  = MAX8925_IRQ_RTC_ALARM0,
  76                .end    = MAX8925_IRQ_RTC_ALARM0,
  77                .flags  = IORESOURCE_IRQ,
  78        },
  79};
  80
  81static struct mfd_cell rtc_devs[] = {
  82        {
  83                .name           = "max8925-rtc",
  84                .num_resources  = 1,
  85                .resources      = &rtc_resources[0],
  86                .id             = -1,
  87        },
  88};
  89
  90static struct resource onkey_resources[] = {
  91        {
  92                .name   = "max8925-onkey",
  93                .start  = MAX8925_IRQ_GPM_SW_R,
  94                .end    = MAX8925_IRQ_GPM_SW_R,
  95                .flags  = IORESOURCE_IRQ,
  96        }, {
  97                .name   = "max8925-onkey",
  98                .start  = MAX8925_IRQ_GPM_SW_F,
  99                .end    = MAX8925_IRQ_GPM_SW_F,
 100                .flags  = IORESOURCE_IRQ,
 101        },
 102};
 103
 104static struct mfd_cell onkey_devs[] = {
 105        {
 106                .name           = "max8925-onkey",
 107                .num_resources  = 2,
 108                .resources      = &onkey_resources[0],
 109                .id             = -1,
 110        },
 111};
 112
 113static struct resource sd1_resources[] = {
 114        {0x06, 0x06, "sdv", IORESOURCE_REG, },
 115};
 116
 117static struct resource sd2_resources[] = {
 118        {0x09, 0x09, "sdv", IORESOURCE_REG, },
 119};
 120
 121static struct resource sd3_resources[] = {
 122        {0x0c, 0x0c, "sdv", IORESOURCE_REG, },
 123};
 124
 125static struct resource ldo1_resources[] = {
 126        {0x1a, 0x1a, "ldov", IORESOURCE_REG, },
 127};
 128
 129static struct resource ldo2_resources[] = {
 130        {0x1e, 0x1e, "ldov", IORESOURCE_REG, },
 131};
 132
 133static struct resource ldo3_resources[] = {
 134        {0x22, 0x22, "ldov", IORESOURCE_REG, },
 135};
 136
 137static struct resource ldo4_resources[] = {
 138        {0x26, 0x26, "ldov", IORESOURCE_REG, },
 139};
 140
 141static struct resource ldo5_resources[] = {
 142        {0x2a, 0x2a, "ldov", IORESOURCE_REG, },
 143};
 144
 145static struct resource ldo6_resources[] = {
 146        {0x2e, 0x2e, "ldov", IORESOURCE_REG, },
 147};
 148
 149static struct resource ldo7_resources[] = {
 150        {0x32, 0x32, "ldov", IORESOURCE_REG, },
 151};
 152
 153static struct resource ldo8_resources[] = {
 154        {0x36, 0x36, "ldov", IORESOURCE_REG, },
 155};
 156
 157static struct resource ldo9_resources[] = {
 158        {0x3a, 0x3a, "ldov", IORESOURCE_REG, },
 159};
 160
 161static struct resource ldo10_resources[] = {
 162        {0x3e, 0x3e, "ldov", IORESOURCE_REG, },
 163};
 164
 165static struct resource ldo11_resources[] = {
 166        {0x42, 0x42, "ldov", IORESOURCE_REG, },
 167};
 168
 169static struct resource ldo12_resources[] = {
 170        {0x46, 0x46, "ldov", IORESOURCE_REG, },
 171};
 172
 173static struct resource ldo13_resources[] = {
 174        {0x4a, 0x4a, "ldov", IORESOURCE_REG, },
 175};
 176
 177static struct resource ldo14_resources[] = {
 178        {0x4e, 0x4e, "ldov", IORESOURCE_REG, },
 179};
 180
 181static struct resource ldo15_resources[] = {
 182        {0x52, 0x52, "ldov", IORESOURCE_REG, },
 183};
 184
 185static struct resource ldo16_resources[] = {
 186        {0x12, 0x12, "ldov", IORESOURCE_REG, },
 187};
 188
 189static struct resource ldo17_resources[] = {
 190        {0x16, 0x16, "ldov", IORESOURCE_REG, },
 191};
 192
 193static struct resource ldo18_resources[] = {
 194        {0x74, 0x74, "ldov", IORESOURCE_REG, },
 195};
 196
 197static struct resource ldo19_resources[] = {
 198        {0x5e, 0x5e, "ldov", IORESOURCE_REG, },
 199};
 200
 201static struct resource ldo20_resources[] = {
 202        {0x9e, 0x9e, "ldov", IORESOURCE_REG, },
 203};
 204
 205static struct mfd_cell reg_devs[] = {
 206        {
 207                .name = "max8925-regulator",
 208                .id = 0,
 209                .num_resources = ARRAY_SIZE(sd1_resources),
 210                .resources = sd1_resources,
 211        }, {
 212                .name = "max8925-regulator",
 213                .id = 1,
 214                .num_resources = ARRAY_SIZE(sd2_resources),
 215                .resources = sd2_resources,
 216        }, {
 217                .name = "max8925-regulator",
 218                .id = 2,
 219                .num_resources = ARRAY_SIZE(sd3_resources),
 220                .resources = sd3_resources,
 221        }, {
 222                .name = "max8925-regulator",
 223                .id = 3,
 224                .num_resources = ARRAY_SIZE(ldo1_resources),
 225                .resources = ldo1_resources,
 226        }, {
 227                .name = "max8925-regulator",
 228                .id = 4,
 229                .num_resources = ARRAY_SIZE(ldo2_resources),
 230                .resources = ldo2_resources,
 231        }, {
 232                .name = "max8925-regulator",
 233                .id = 5,
 234                .num_resources = ARRAY_SIZE(ldo3_resources),
 235                .resources = ldo3_resources,
 236        }, {
 237                .name = "max8925-regulator",
 238                .id = 6,
 239                .num_resources = ARRAY_SIZE(ldo4_resources),
 240                .resources = ldo4_resources,
 241        }, {
 242                .name = "max8925-regulator",
 243                .id = 7,
 244                .num_resources = ARRAY_SIZE(ldo5_resources),
 245                .resources = ldo5_resources,
 246        }, {
 247                .name = "max8925-regulator",
 248                .id = 8,
 249                .num_resources = ARRAY_SIZE(ldo6_resources),
 250                .resources = ldo6_resources,
 251        }, {
 252                .name = "max8925-regulator",
 253                .id = 9,
 254                .num_resources = ARRAY_SIZE(ldo7_resources),
 255                .resources = ldo7_resources,
 256        }, {
 257                .name = "max8925-regulator",
 258                .id = 10,
 259                .num_resources = ARRAY_SIZE(ldo8_resources),
 260                .resources = ldo8_resources,
 261        }, {
 262                .name = "max8925-regulator",
 263                .id = 11,
 264                .num_resources = ARRAY_SIZE(ldo9_resources),
 265                .resources = ldo9_resources,
 266        }, {
 267                .name = "max8925-regulator",
 268                .id = 12,
 269                .num_resources = ARRAY_SIZE(ldo10_resources),
 270                .resources = ldo10_resources,
 271        }, {
 272                .name = "max8925-regulator",
 273                .id = 13,
 274                .num_resources = ARRAY_SIZE(ldo11_resources),
 275                .resources = ldo11_resources,
 276        }, {
 277                .name = "max8925-regulator",
 278                .id = 14,
 279                .num_resources = ARRAY_SIZE(ldo12_resources),
 280                .resources = ldo12_resources,
 281        }, {
 282                .name = "max8925-regulator",
 283                .id = 15,
 284                .num_resources = ARRAY_SIZE(ldo13_resources),
 285                .resources = ldo13_resources,
 286        }, {
 287                .name = "max8925-regulator",
 288                .id = 16,
 289                .num_resources = ARRAY_SIZE(ldo14_resources),
 290                .resources = ldo14_resources,
 291        }, {
 292                .name = "max8925-regulator",
 293                .id = 17,
 294                .num_resources = ARRAY_SIZE(ldo15_resources),
 295                .resources = ldo15_resources,
 296        }, {
 297                .name = "max8925-regulator",
 298                .id = 18,
 299                .num_resources = ARRAY_SIZE(ldo16_resources),
 300                .resources = ldo16_resources,
 301        }, {
 302                .name = "max8925-regulator",
 303                .id = 19,
 304                .num_resources = ARRAY_SIZE(ldo17_resources),
 305                .resources = ldo17_resources,
 306        }, {
 307                .name = "max8925-regulator",
 308                .id = 20,
 309                .num_resources = ARRAY_SIZE(ldo18_resources),
 310                .resources = ldo18_resources,
 311        }, {
 312                .name = "max8925-regulator",
 313                .id = 21,
 314                .num_resources = ARRAY_SIZE(ldo19_resources),
 315                .resources = ldo19_resources,
 316        }, {
 317                .name = "max8925-regulator",
 318                .id = 22,
 319                .num_resources = ARRAY_SIZE(ldo20_resources),
 320                .resources = ldo20_resources,
 321        },
 322};
 323
 324enum {
 325        FLAGS_ADC = 1,  /* register in ADC component */
 326        FLAGS_RTC,      /* register in RTC component */
 327};
 328
 329struct max8925_irq_data {
 330        int     reg;
 331        int     mask_reg;
 332        int     enable;         /* enable or not */
 333        int     offs;           /* bit offset in mask register */
 334        int     flags;
 335        int     tsc_irq;
 336};
 337
 338static struct max8925_irq_data max8925_irqs[] = {
 339        [MAX8925_IRQ_VCHG_DC_OVP] = {
 340                .reg            = MAX8925_CHG_IRQ1,
 341                .mask_reg       = MAX8925_CHG_IRQ1_MASK,
 342                .offs           = 1 << 0,
 343        },
 344        [MAX8925_IRQ_VCHG_DC_F] = {
 345                .reg            = MAX8925_CHG_IRQ1,
 346                .mask_reg       = MAX8925_CHG_IRQ1_MASK,
 347                .offs           = 1 << 1,
 348        },
 349        [MAX8925_IRQ_VCHG_DC_R] = {
 350                .reg            = MAX8925_CHG_IRQ1,
 351                .mask_reg       = MAX8925_CHG_IRQ1_MASK,
 352                .offs           = 1 << 2,
 353        },
 354        [MAX8925_IRQ_VCHG_THM_OK_R] = {
 355                .reg            = MAX8925_CHG_IRQ2,
 356                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 357                .offs           = 1 << 0,
 358        },
 359        [MAX8925_IRQ_VCHG_THM_OK_F] = {
 360                .reg            = MAX8925_CHG_IRQ2,
 361                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 362                .offs           = 1 << 1,
 363        },
 364        [MAX8925_IRQ_VCHG_SYSLOW_F] = {
 365                .reg            = MAX8925_CHG_IRQ2,
 366                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 367                .offs           = 1 << 2,
 368        },
 369        [MAX8925_IRQ_VCHG_SYSLOW_R] = {
 370                .reg            = MAX8925_CHG_IRQ2,
 371                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 372                .offs           = 1 << 3,
 373        },
 374        [MAX8925_IRQ_VCHG_RST] = {
 375                .reg            = MAX8925_CHG_IRQ2,
 376                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 377                .offs           = 1 << 4,
 378        },
 379        [MAX8925_IRQ_VCHG_DONE] = {
 380                .reg            = MAX8925_CHG_IRQ2,
 381                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 382                .offs           = 1 << 5,
 383        },
 384        [MAX8925_IRQ_VCHG_TOPOFF] = {
 385                .reg            = MAX8925_CHG_IRQ2,
 386                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 387                .offs           = 1 << 6,
 388        },
 389        [MAX8925_IRQ_VCHG_TMR_FAULT] = {
 390                .reg            = MAX8925_CHG_IRQ2,
 391                .mask_reg       = MAX8925_CHG_IRQ2_MASK,
 392                .offs           = 1 << 7,
 393        },
 394        [MAX8925_IRQ_GPM_RSTIN] = {
 395                .reg            = MAX8925_ON_OFF_IRQ1,
 396                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 397                .offs           = 1 << 0,
 398        },
 399        [MAX8925_IRQ_GPM_MPL] = {
 400                .reg            = MAX8925_ON_OFF_IRQ1,
 401                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 402                .offs           = 1 << 1,
 403        },
 404        [MAX8925_IRQ_GPM_SW_3SEC] = {
 405                .reg            = MAX8925_ON_OFF_IRQ1,
 406                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 407                .offs           = 1 << 2,
 408        },
 409        [MAX8925_IRQ_GPM_EXTON_F] = {
 410                .reg            = MAX8925_ON_OFF_IRQ1,
 411                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 412                .offs           = 1 << 3,
 413        },
 414        [MAX8925_IRQ_GPM_EXTON_R] = {
 415                .reg            = MAX8925_ON_OFF_IRQ1,
 416                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 417                .offs           = 1 << 4,
 418        },
 419        [MAX8925_IRQ_GPM_SW_1SEC] = {
 420                .reg            = MAX8925_ON_OFF_IRQ1,
 421                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 422                .offs           = 1 << 5,
 423        },
 424        [MAX8925_IRQ_GPM_SW_F] = {
 425                .reg            = MAX8925_ON_OFF_IRQ1,
 426                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 427                .offs           = 1 << 6,
 428        },
 429        [MAX8925_IRQ_GPM_SW_R] = {
 430                .reg            = MAX8925_ON_OFF_IRQ1,
 431                .mask_reg       = MAX8925_ON_OFF_IRQ1_MASK,
 432                .offs           = 1 << 7,
 433        },
 434        [MAX8925_IRQ_GPM_SYSCKEN_F] = {
 435                .reg            = MAX8925_ON_OFF_IRQ2,
 436                .mask_reg       = MAX8925_ON_OFF_IRQ2_MASK,
 437                .offs           = 1 << 0,
 438        },
 439        [MAX8925_IRQ_GPM_SYSCKEN_R] = {
 440                .reg            = MAX8925_ON_OFF_IRQ2,
 441                .mask_reg       = MAX8925_ON_OFF_IRQ2_MASK,
 442                .offs           = 1 << 1,
 443        },
 444        [MAX8925_IRQ_RTC_ALARM1] = {
 445                .reg            = MAX8925_RTC_IRQ,
 446                .mask_reg       = MAX8925_RTC_IRQ_MASK,
 447                .offs           = 1 << 2,
 448                .flags          = FLAGS_RTC,
 449        },
 450        [MAX8925_IRQ_RTC_ALARM0] = {
 451                .reg            = MAX8925_RTC_IRQ,
 452                .mask_reg       = MAX8925_RTC_IRQ_MASK,
 453                .offs           = 1 << 3,
 454                .flags          = FLAGS_RTC,
 455        },
 456        [MAX8925_IRQ_TSC_STICK] = {
 457                .reg            = MAX8925_TSC_IRQ,
 458                .mask_reg       = MAX8925_TSC_IRQ_MASK,
 459                .offs           = 1 << 0,
 460                .flags          = FLAGS_ADC,
 461                .tsc_irq        = 1,
 462        },
 463        [MAX8925_IRQ_TSC_NSTICK] = {
 464                .reg            = MAX8925_TSC_IRQ,
 465                .mask_reg       = MAX8925_TSC_IRQ_MASK,
 466                .offs           = 1 << 1,
 467                .flags          = FLAGS_ADC,
 468                .tsc_irq        = 1,
 469        },
 470};
 471
 472static inline struct max8925_irq_data *irq_to_max8925(struct max8925_chip *chip,
 473                                                      int irq)
 474{
 475        return &max8925_irqs[irq - chip->irq_base];
 476}
 477
 478static irqreturn_t max8925_irq(int irq, void *data)
 479{
 480        struct max8925_chip *chip = data;
 481        struct max8925_irq_data *irq_data;
 482        struct i2c_client *i2c;
 483        int read_reg = -1, value = 0;
 484        int i;
 485
 486        for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
 487                irq_data = &max8925_irqs[i];
 488                /* TSC IRQ should be serviced in max8925_tsc_irq() */
 489                if (irq_data->tsc_irq)
 490                        continue;
 491                if (irq_data->flags == FLAGS_RTC)
 492                        i2c = chip->rtc;
 493                else if (irq_data->flags == FLAGS_ADC)
 494                        i2c = chip->adc;
 495                else
 496                        i2c = chip->i2c;
 497                if (read_reg != irq_data->reg) {
 498                        read_reg = irq_data->reg;
 499                        value = max8925_reg_read(i2c, irq_data->reg);
 500                }
 501                if (value & irq_data->enable)
 502                        handle_nested_irq(chip->irq_base + i);
 503        }
 504        return IRQ_HANDLED;
 505}
 506
 507static irqreturn_t max8925_tsc_irq(int irq, void *data)
 508{
 509        struct max8925_chip *chip = data;
 510        struct max8925_irq_data *irq_data;
 511        struct i2c_client *i2c;
 512        int read_reg = -1, value = 0;
 513        int i;
 514
 515        for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
 516                irq_data = &max8925_irqs[i];
 517                /* non TSC IRQ should be serviced in max8925_irq() */
 518                if (!irq_data->tsc_irq)
 519                        continue;
 520                if (irq_data->flags == FLAGS_RTC)
 521                        i2c = chip->rtc;
 522                else if (irq_data->flags == FLAGS_ADC)
 523                        i2c = chip->adc;
 524                else
 525                        i2c = chip->i2c;
 526                if (read_reg != irq_data->reg) {
 527                        read_reg = irq_data->reg;
 528                        value = max8925_reg_read(i2c, irq_data->reg);
 529                }
 530                if (value & irq_data->enable)
 531                        handle_nested_irq(chip->irq_base + i);
 532        }
 533        return IRQ_HANDLED;
 534}
 535
 536static void max8925_irq_lock(struct irq_data *data)
 537{
 538        struct max8925_chip *chip = irq_data_get_irq_chip_data(data);
 539
 540        mutex_lock(&chip->irq_lock);
 541}
 542
 543static void max8925_irq_sync_unlock(struct irq_data *data)
 544{
 545        struct max8925_chip *chip = irq_data_get_irq_chip_data(data);
 546        struct max8925_irq_data *irq_data;
 547        static unsigned char cache_chg[2] = {0xff, 0xff};
 548        static unsigned char cache_on[2] = {0xff, 0xff};
 549        static unsigned char cache_rtc = 0xff, cache_tsc = 0xff;
 550        unsigned char irq_chg[2], irq_on[2];
 551        unsigned char irq_rtc, irq_tsc;
 552        int i;
 553
 554        /* Load cached value. In initial, all IRQs are masked */
 555        irq_chg[0] = cache_chg[0];
 556        irq_chg[1] = cache_chg[1];
 557        irq_on[0] = cache_on[0];
 558        irq_on[1] = cache_on[1];
 559        irq_rtc = cache_rtc;
 560        irq_tsc = cache_tsc;
 561        for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
 562                irq_data = &max8925_irqs[i];
 563                /* 1 -- disable, 0 -- enable */
 564                switch (irq_data->mask_reg) {
 565                case MAX8925_CHG_IRQ1_MASK:
 566                        irq_chg[0] &= ~irq_data->enable;
 567                        break;
 568                case MAX8925_CHG_IRQ2_MASK:
 569                        irq_chg[1] &= ~irq_data->enable;
 570                        break;
 571                case MAX8925_ON_OFF_IRQ1_MASK:
 572                        irq_on[0] &= ~irq_data->enable;
 573                        break;
 574                case MAX8925_ON_OFF_IRQ2_MASK:
 575                        irq_on[1] &= ~irq_data->enable;
 576                        break;
 577                case MAX8925_RTC_IRQ_MASK:
 578                        irq_rtc &= ~irq_data->enable;
 579                        break;
 580                case MAX8925_TSC_IRQ_MASK:
 581                        irq_tsc &= ~irq_data->enable;
 582                        break;
 583                default:
 584                        dev_err(chip->dev, "wrong IRQ\n");
 585                        break;
 586                }
 587        }
 588        /* update mask into registers */
 589        if (cache_chg[0] != irq_chg[0]) {
 590                cache_chg[0] = irq_chg[0];
 591                max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ1_MASK,
 592                        irq_chg[0]);
 593        }
 594        if (cache_chg[1] != irq_chg[1]) {
 595                cache_chg[1] = irq_chg[1];
 596                max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ2_MASK,
 597                        irq_chg[1]);
 598        }
 599        if (cache_on[0] != irq_on[0]) {
 600                cache_on[0] = irq_on[0];
 601                max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ1_MASK,
 602                                irq_on[0]);
 603        }
 604        if (cache_on[1] != irq_on[1]) {
 605                cache_on[1] = irq_on[1];
 606                max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ2_MASK,
 607                                irq_on[1]);
 608        }
 609        if (cache_rtc != irq_rtc) {
 610                cache_rtc = irq_rtc;
 611                max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, irq_rtc);
 612        }
 613        if (cache_tsc != irq_tsc) {
 614                cache_tsc = irq_tsc;
 615                max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, irq_tsc);
 616        }
 617
 618        mutex_unlock(&chip->irq_lock);
 619}
 620
 621static void max8925_irq_enable(struct irq_data *data)
 622{
 623        struct max8925_chip *chip = irq_data_get_irq_chip_data(data);
 624        max8925_irqs[data->irq - chip->irq_base].enable
 625                = max8925_irqs[data->irq - chip->irq_base].offs;
 626}
 627
 628static void max8925_irq_disable(struct irq_data *data)
 629{
 630        struct max8925_chip *chip = irq_data_get_irq_chip_data(data);
 631        max8925_irqs[data->irq - chip->irq_base].enable = 0;
 632}
 633
 634static struct irq_chip max8925_irq_chip = {
 635        .name           = "max8925",
 636        .irq_bus_lock   = max8925_irq_lock,
 637        .irq_bus_sync_unlock = max8925_irq_sync_unlock,
 638        .irq_enable     = max8925_irq_enable,
 639        .irq_disable    = max8925_irq_disable,
 640};
 641
 642static int max8925_irq_init(struct max8925_chip *chip, int irq,
 643                            struct max8925_platform_data *pdata)
 644{
 645        unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
 646        int i, ret;
 647        int __irq;
 648
 649        if (!pdata || !pdata->irq_base) {
 650                dev_warn(chip->dev, "No interrupt support on IRQ base\n");
 651                return -EINVAL;
 652        }
 653        /* clear all interrupts */
 654        max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ1);
 655        max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ2);
 656        max8925_reg_read(chip->i2c, MAX8925_ON_OFF_IRQ1);
 657        max8925_reg_read(chip->i2c, MAX8925_ON_OFF_IRQ2);
 658        max8925_reg_read(chip->rtc, MAX8925_RTC_IRQ);
 659        max8925_reg_read(chip->adc, MAX8925_TSC_IRQ);
 660        /* mask all interrupts except for TSC */
 661        max8925_reg_write(chip->rtc, MAX8925_ALARM0_CNTL, 0);
 662        max8925_reg_write(chip->rtc, MAX8925_ALARM1_CNTL, 0);
 663        max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ1_MASK, 0xff);
 664        max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ2_MASK, 0xff);
 665        max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ1_MASK, 0xff);
 666        max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ2_MASK, 0xff);
 667        max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, 0xff);
 668
 669        mutex_init(&chip->irq_lock);
 670        chip->core_irq = irq;
 671        chip->irq_base = pdata->irq_base;
 672
 673        /* register with genirq */
 674        for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
 675                __irq = i + chip->irq_base;
 676                irq_set_chip_data(__irq, chip);
 677                irq_set_chip_and_handler(__irq, &max8925_irq_chip,
 678                                         handle_edge_irq);
 679                irq_set_nested_thread(__irq, 1);
 680#ifdef CONFIG_ARM
 681                set_irq_flags(__irq, IRQF_VALID);
 682#else
 683                irq_set_noprobe(__irq);
 684#endif
 685        }
 686        if (!irq) {
 687                dev_warn(chip->dev, "No interrupt support on core IRQ\n");
 688                goto tsc_irq;
 689        }
 690
 691        ret = request_threaded_irq(irq, NULL, max8925_irq, flags | IRQF_ONESHOT,
 692                                   "max8925", chip);
 693        if (ret) {
 694                dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret);
 695                chip->core_irq = 0;
 696        }
 697
 698tsc_irq:
 699        /* mask TSC interrupt */
 700        max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, 0x0f);
 701
 702        if (!pdata->tsc_irq) {
 703                dev_warn(chip->dev, "No interrupt support on TSC IRQ\n");
 704                return 0;
 705        }
 706        chip->tsc_irq = pdata->tsc_irq;
 707
 708        ret = request_threaded_irq(chip->tsc_irq, NULL, max8925_tsc_irq,
 709                                   flags | IRQF_ONESHOT, "max8925-tsc", chip);
 710        if (ret) {
 711                dev_err(chip->dev, "Failed to request TSC IRQ: %d\n", ret);
 712                chip->tsc_irq = 0;
 713        }
 714        return 0;
 715}
 716
 717static void init_regulator(struct max8925_chip *chip,
 718                                     struct max8925_platform_data *pdata)
 719{
 720        int ret;
 721
 722        if (!pdata)
 723                return;
 724        if (pdata->sd1) {
 725                reg_devs[0].platform_data = pdata->sd1;
 726                reg_devs[0].pdata_size = sizeof(struct regulator_init_data);
 727        }
 728        if (pdata->sd2) {
 729                reg_devs[1].platform_data = pdata->sd2;
 730                reg_devs[1].pdata_size = sizeof(struct regulator_init_data);
 731        }
 732        if (pdata->sd3) {
 733                reg_devs[2].platform_data = pdata->sd3;
 734                reg_devs[2].pdata_size = sizeof(struct regulator_init_data);
 735        }
 736        if (pdata->ldo1) {
 737                reg_devs[3].platform_data = pdata->ldo1;
 738                reg_devs[3].pdata_size = sizeof(struct regulator_init_data);
 739        }
 740        if (pdata->ldo2) {
 741                reg_devs[4].platform_data = pdata->ldo2;
 742                reg_devs[4].pdata_size = sizeof(struct regulator_init_data);
 743        }
 744        if (pdata->ldo3) {
 745                reg_devs[5].platform_data = pdata->ldo3;
 746                reg_devs[5].pdata_size = sizeof(struct regulator_init_data);
 747        }
 748        if (pdata->ldo4) {
 749                reg_devs[6].platform_data = pdata->ldo4;
 750                reg_devs[6].pdata_size = sizeof(struct regulator_init_data);
 751        }
 752        if (pdata->ldo5) {
 753                reg_devs[7].platform_data = pdata->ldo5;
 754                reg_devs[7].pdata_size = sizeof(struct regulator_init_data);
 755        }
 756        if (pdata->ldo6) {
 757                reg_devs[8].platform_data = pdata->ldo6;
 758                reg_devs[8].pdata_size = sizeof(struct regulator_init_data);
 759        }
 760        if (pdata->ldo7) {
 761                reg_devs[9].platform_data = pdata->ldo7;
 762                reg_devs[9].pdata_size = sizeof(struct regulator_init_data);
 763        }
 764        if (pdata->ldo8) {
 765                reg_devs[10].platform_data = pdata->ldo8;
 766                reg_devs[10].pdata_size = sizeof(struct regulator_init_data);
 767        }
 768        if (pdata->ldo9) {
 769                reg_devs[11].platform_data = pdata->ldo9;
 770                reg_devs[11].pdata_size = sizeof(struct regulator_init_data);
 771        }
 772        if (pdata->ldo10) {
 773                reg_devs[12].platform_data = pdata->ldo10;
 774                reg_devs[12].pdata_size = sizeof(struct regulator_init_data);
 775        }
 776        if (pdata->ldo11) {
 777                reg_devs[13].platform_data = pdata->ldo11;
 778                reg_devs[13].pdata_size = sizeof(struct regulator_init_data);
 779        }
 780        if (pdata->ldo12) {
 781                reg_devs[14].platform_data = pdata->ldo12;
 782                reg_devs[14].pdata_size = sizeof(struct regulator_init_data);
 783        }
 784        if (pdata->ldo13) {
 785                reg_devs[15].platform_data = pdata->ldo13;
 786                reg_devs[15].pdata_size = sizeof(struct regulator_init_data);
 787        }
 788        if (pdata->ldo14) {
 789                reg_devs[16].platform_data = pdata->ldo14;
 790                reg_devs[16].pdata_size = sizeof(struct regulator_init_data);
 791        }
 792        if (pdata->ldo15) {
 793                reg_devs[17].platform_data = pdata->ldo15;
 794                reg_devs[17].pdata_size = sizeof(struct regulator_init_data);
 795        }
 796        if (pdata->ldo16) {
 797                reg_devs[18].platform_data = pdata->ldo16;
 798                reg_devs[18].pdata_size = sizeof(struct regulator_init_data);
 799        }
 800        if (pdata->ldo17) {
 801                reg_devs[19].platform_data = pdata->ldo17;
 802                reg_devs[19].pdata_size = sizeof(struct regulator_init_data);
 803        }
 804        if (pdata->ldo18) {
 805                reg_devs[20].platform_data = pdata->ldo18;
 806                reg_devs[20].pdata_size = sizeof(struct regulator_init_data);
 807        }
 808        if (pdata->ldo19) {
 809                reg_devs[21].platform_data = pdata->ldo19;
 810                reg_devs[21].pdata_size = sizeof(struct regulator_init_data);
 811        }
 812        if (pdata->ldo20) {
 813                reg_devs[22].platform_data = pdata->ldo20;
 814                reg_devs[22].pdata_size = sizeof(struct regulator_init_data);
 815        }
 816        ret = mfd_add_devices(chip->dev, 0, reg_devs, ARRAY_SIZE(reg_devs),
 817                              NULL, 0, NULL);
 818        if (ret < 0) {
 819                dev_err(chip->dev, "Failed to add regulator subdev\n");
 820                return;
 821        }
 822}
 823
 824int max8925_device_init(struct max8925_chip *chip,
 825                                  struct max8925_platform_data *pdata)
 826{
 827        int ret;
 828
 829        max8925_irq_init(chip, chip->i2c->irq, pdata);
 830
 831        if (pdata && (pdata->power || pdata->touch)) {
 832                /* enable ADC to control internal reference */
 833                max8925_set_bits(chip->i2c, MAX8925_RESET_CNFG, 1, 1);
 834                /* enable internal reference for ADC */
 835                max8925_set_bits(chip->adc, MAX8925_TSC_CNFG1, 3, 2);
 836                /* check for internal reference IRQ */
 837                do {
 838                        ret = max8925_reg_read(chip->adc, MAX8925_TSC_IRQ);
 839                } while (ret & MAX8925_NREF_OK);
 840                /* enaable ADC scheduler, interval is 1 second */
 841                max8925_set_bits(chip->adc, MAX8925_ADC_SCHED, 3, 2);
 842        }
 843
 844        /* enable Momentary Power Loss */
 845        max8925_set_bits(chip->rtc, MAX8925_MPL_CNTL, 1 << 4, 1 << 4);
 846
 847        ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
 848                              ARRAY_SIZE(rtc_devs),
 849                              &rtc_resources[0], chip->irq_base, NULL);
 850        if (ret < 0) {
 851                dev_err(chip->dev, "Failed to add rtc subdev\n");
 852                goto out;
 853        }
 854
 855        ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],
 856                              ARRAY_SIZE(onkey_devs),
 857                              &onkey_resources[0], 0, NULL);
 858        if (ret < 0) {
 859                dev_err(chip->dev, "Failed to add onkey subdev\n");
 860                goto out_dev;
 861        }
 862
 863        init_regulator(chip, pdata);
 864
 865        if (pdata && pdata->backlight) {
 866                bk_devs[0].platform_data = &pdata->backlight;
 867                bk_devs[0].pdata_size = sizeof(struct max8925_backlight_pdata);
 868        }
 869        ret = mfd_add_devices(chip->dev, 0, bk_devs, ARRAY_SIZE(bk_devs),
 870                              NULL, 0, NULL);
 871        if (ret < 0) {
 872                dev_err(chip->dev, "Failed to add backlight subdev\n");
 873                goto out_dev;
 874        }
 875
 876        if (pdata && pdata->power) {
 877                ret = mfd_add_devices(chip->dev, 0, &power_devs[0],
 878                                        ARRAY_SIZE(power_devs),
 879                                      &power_supply_resources[0], 0, NULL);
 880                if (ret < 0) {
 881                        dev_err(chip->dev, "Failed to add power supply "
 882                                "subdev\n");
 883                        goto out_dev;
 884                }
 885        }
 886
 887        if (pdata && pdata->touch) {
 888                ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
 889                                      ARRAY_SIZE(touch_devs),
 890                                      &touch_resources[0], 0, NULL);
 891                if (ret < 0) {
 892                        dev_err(chip->dev, "Failed to add touch subdev\n");
 893                        goto out_dev;
 894                }
 895        }
 896
 897        return 0;
 898out_dev:
 899        mfd_remove_devices(chip->dev);
 900out:
 901        return ret;
 902}
 903
 904void max8925_device_exit(struct max8925_chip *chip)
 905{
 906        if (chip->core_irq)
 907                free_irq(chip->core_irq, chip);
 908        if (chip->tsc_irq)
 909                free_irq(chip->tsc_irq, chip);
 910        mfd_remove_devices(chip->dev);
 911}
 912
 913
 914MODULE_DESCRIPTION("PMIC Driver for Maxim MAX8925");
 915MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com");
 916MODULE_LICENSE("GPL");
 917
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.