linux/drivers/mfd/88pm860x-core.c
<<
>>
Prefs
   1/*
   2 * Base driver for Marvell 88PM8607
   3 *
   4 * Copyright (C) 2009 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/err.h>
  15#include <linux/i2c.h>
  16#include <linux/irq.h>
  17#include <linux/interrupt.h>
  18#include <linux/irqdomain.h>
  19#include <linux/of.h>
  20#include <linux/of_platform.h>
  21#include <linux/platform_device.h>
  22#include <linux/regmap.h>
  23#include <linux/slab.h>
  24#include <linux/mfd/core.h>
  25#include <linux/mfd/88pm860x.h>
  26#include <linux/regulator/machine.h>
  27#include <linux/power/charger-manager.h>
  28
  29#define INT_STATUS_NUM                  3
  30
  31static struct resource bk0_resources[] = {
  32        {2, 2, "duty cycle", IORESOURCE_REG, },
  33        {3, 3, "always on",  IORESOURCE_REG, },
  34        {3, 3, "current",    IORESOURCE_REG, },
  35};
  36static struct resource bk1_resources[] = {
  37        {4, 4, "duty cycle", IORESOURCE_REG, },
  38        {5, 5, "always on",  IORESOURCE_REG, },
  39        {5, 5, "current",    IORESOURCE_REG, },
  40};
  41static struct resource bk2_resources[] = {
  42        {6, 6, "duty cycle", IORESOURCE_REG, },
  43        {7, 7, "always on",  IORESOURCE_REG, },
  44        {5, 5, "current",    IORESOURCE_REG, },
  45};
  46
  47static struct resource led0_resources[] = {
  48        /* RGB1 Red LED */
  49        {0xd, 0xd, "control", IORESOURCE_REG, },
  50        {0xc, 0xc, "blink",   IORESOURCE_REG, },
  51};
  52static struct resource led1_resources[] = {
  53        /* RGB1 Green LED */
  54        {0xe, 0xe, "control", IORESOURCE_REG, },
  55        {0xc, 0xc, "blink",   IORESOURCE_REG, },
  56};
  57static struct resource led2_resources[] = {
  58        /* RGB1 Blue LED */
  59        {0xf, 0xf, "control", IORESOURCE_REG, },
  60        {0xc, 0xc, "blink",   IORESOURCE_REG, },
  61};
  62static struct resource led3_resources[] = {
  63        /* RGB2 Red LED */
  64        {0x9, 0x9, "control", IORESOURCE_REG, },
  65        {0x8, 0x8, "blink",   IORESOURCE_REG, },
  66};
  67static struct resource led4_resources[] = {
  68        /* RGB2 Green LED */
  69        {0xa, 0xa, "control", IORESOURCE_REG, },
  70        {0x8, 0x8, "blink",   IORESOURCE_REG, },
  71};
  72static struct resource led5_resources[] = {
  73        /* RGB2 Blue LED */
  74        {0xb, 0xb, "control", IORESOURCE_REG, },
  75        {0x8, 0x8, "blink",   IORESOURCE_REG, },
  76};
  77
  78static struct resource buck1_resources[] = {
  79        {0x24, 0x24, "buck set", IORESOURCE_REG, },
  80};
  81static struct resource buck2_resources[] = {
  82        {0x25, 0x25, "buck set", IORESOURCE_REG, },
  83};
  84static struct resource buck3_resources[] = {
  85        {0x26, 0x26, "buck set", IORESOURCE_REG, },
  86};
  87static struct resource ldo1_resources[] = {
  88        {0x10, 0x10, "ldo set", IORESOURCE_REG, },
  89};
  90static struct resource ldo2_resources[] = {
  91        {0x11, 0x11, "ldo set", IORESOURCE_REG, },
  92};
  93static struct resource ldo3_resources[] = {
  94        {0x12, 0x12, "ldo set", IORESOURCE_REG, },
  95};
  96static struct resource ldo4_resources[] = {
  97        {0x13, 0x13, "ldo set", IORESOURCE_REG, },
  98};
  99static struct resource ldo5_resources[] = {
 100        {0x14, 0x14, "ldo set", IORESOURCE_REG, },
 101};
 102static struct resource ldo6_resources[] = {
 103        {0x15, 0x15, "ldo set", IORESOURCE_REG, },
 104};
 105static struct resource ldo7_resources[] = {
 106        {0x16, 0x16, "ldo set", IORESOURCE_REG, },
 107};
 108static struct resource ldo8_resources[] = {
 109        {0x17, 0x17, "ldo set", IORESOURCE_REG, },
 110};
 111static struct resource ldo9_resources[] = {
 112        {0x18, 0x18, "ldo set", IORESOURCE_REG, },
 113};
 114static struct resource ldo10_resources[] = {
 115        {0x19, 0x19, "ldo set", IORESOURCE_REG, },
 116};
 117static struct resource ldo12_resources[] = {
 118        {0x1a, 0x1a, "ldo set", IORESOURCE_REG, },
 119};
 120static struct resource ldo_vibrator_resources[] = {
 121        {0x28, 0x28, "ldo set", IORESOURCE_REG, },
 122};
 123static struct resource ldo14_resources[] = {
 124        {0x1b, 0x1b, "ldo set", IORESOURCE_REG, },
 125};
 126
 127static struct resource touch_resources[] = {
 128        {PM8607_IRQ_PEN, PM8607_IRQ_PEN, "touch", IORESOURCE_IRQ,},
 129};
 130
 131static struct resource onkey_resources[] = {
 132        {PM8607_IRQ_ONKEY, PM8607_IRQ_ONKEY, "onkey", IORESOURCE_IRQ,},
 133};
 134
 135static struct resource codec_resources[] = {
 136        /* Headset microphone insertion or removal */
 137        {PM8607_IRQ_MICIN,   PM8607_IRQ_MICIN,   "micin",   IORESOURCE_IRQ,},
 138        /* Hook-switch press or release */
 139        {PM8607_IRQ_HOOK,    PM8607_IRQ_HOOK,    "hook",    IORESOURCE_IRQ,},
 140        /* Headset insertion or removal */
 141        {PM8607_IRQ_HEADSET, PM8607_IRQ_HEADSET, "headset", IORESOURCE_IRQ,},
 142        /* Audio short */
 143        {PM8607_IRQ_AUDIO_SHORT, PM8607_IRQ_AUDIO_SHORT, "audio-short", IORESOURCE_IRQ,},
 144};
 145
 146static struct resource battery_resources[] = {
 147        {PM8607_IRQ_CC,  PM8607_IRQ_CC,  "columb counter", IORESOURCE_IRQ,},
 148        {PM8607_IRQ_BAT, PM8607_IRQ_BAT, "battery",        IORESOURCE_IRQ,},
 149};
 150
 151static struct resource charger_resources[] = {
 152        {PM8607_IRQ_CHG,  PM8607_IRQ_CHG,  "charger detect",  IORESOURCE_IRQ,},
 153        {PM8607_IRQ_CHG_DONE,  PM8607_IRQ_CHG_DONE,  "charging done",       IORESOURCE_IRQ,},
 154        {PM8607_IRQ_CHG_FAIL,  PM8607_IRQ_CHG_FAIL,  "charging timeout",    IORESOURCE_IRQ,},
 155        {PM8607_IRQ_CHG_FAULT, PM8607_IRQ_CHG_FAULT, "charging fault",      IORESOURCE_IRQ,},
 156        {PM8607_IRQ_GPADC1,    PM8607_IRQ_GPADC1,    "battery temperature", IORESOURCE_IRQ,},
 157        {PM8607_IRQ_VBAT, PM8607_IRQ_VBAT, "battery voltage", IORESOURCE_IRQ,},
 158        {PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage",    IORESOURCE_IRQ,},
 159};
 160
 161static struct resource rtc_resources[] = {
 162        {PM8607_IRQ_RTC, PM8607_IRQ_RTC, "rtc", IORESOURCE_IRQ,},
 163};
 164
 165static struct mfd_cell bk_devs[] = {
 166        {
 167                .name = "88pm860x-backlight",
 168                .id = 0,
 169                .num_resources = ARRAY_SIZE(bk0_resources),
 170                .resources = bk0_resources,
 171        }, {
 172                .name = "88pm860x-backlight",
 173                .id = 1,
 174                .num_resources = ARRAY_SIZE(bk1_resources),
 175                .resources = bk1_resources,
 176        }, {
 177                .name = "88pm860x-backlight",
 178                .id = 2,
 179                .num_resources = ARRAY_SIZE(bk2_resources),
 180                .resources = bk2_resources,
 181        },
 182};
 183
 184static struct mfd_cell led_devs[] = {
 185        {
 186                .name = "88pm860x-led",
 187                .id = 0,
 188                .num_resources = ARRAY_SIZE(led0_resources),
 189                .resources = led0_resources,
 190        }, {
 191                .name = "88pm860x-led",
 192                .id = 1,
 193                .num_resources = ARRAY_SIZE(led1_resources),
 194                .resources = led1_resources,
 195        }, {
 196                .name = "88pm860x-led",
 197                .id = 2,
 198                .num_resources = ARRAY_SIZE(led2_resources),
 199                .resources = led2_resources,
 200        }, {
 201                .name = "88pm860x-led",
 202                .id = 3,
 203                .num_resources = ARRAY_SIZE(led3_resources),
 204                .resources = led3_resources,
 205        }, {
 206                .name = "88pm860x-led",
 207                .id = 4,
 208                .num_resources = ARRAY_SIZE(led4_resources),
 209                .resources = led4_resources,
 210        }, {
 211                .name = "88pm860x-led",
 212                .id = 5,
 213                .num_resources = ARRAY_SIZE(led5_resources),
 214                .resources = led5_resources,
 215        },
 216};
 217
 218static struct mfd_cell reg_devs[] = {
 219        {
 220                .name = "88pm860x-regulator",
 221                .id = 0,
 222                .num_resources = ARRAY_SIZE(buck1_resources),
 223                .resources = buck1_resources,
 224        }, {
 225                .name = "88pm860x-regulator",
 226                .id = 1,
 227                .num_resources = ARRAY_SIZE(buck2_resources),
 228                .resources = buck2_resources,
 229        }, {
 230                .name = "88pm860x-regulator",
 231                .id = 2,
 232                .num_resources = ARRAY_SIZE(buck3_resources),
 233                .resources = buck3_resources,
 234        }, {
 235                .name = "88pm860x-regulator",
 236                .id = 3,
 237                .num_resources = ARRAY_SIZE(ldo1_resources),
 238                .resources = ldo1_resources,
 239        }, {
 240                .name = "88pm860x-regulator",
 241                .id = 4,
 242                .num_resources = ARRAY_SIZE(ldo2_resources),
 243                .resources = ldo2_resources,
 244        }, {
 245                .name = "88pm860x-regulator",
 246                .id = 5,
 247                .num_resources = ARRAY_SIZE(ldo3_resources),
 248                .resources = ldo3_resources,
 249        }, {
 250                .name = "88pm860x-regulator",
 251                .id = 6,
 252                .num_resources = ARRAY_SIZE(ldo4_resources),
 253                .resources = ldo4_resources,
 254        }, {
 255                .name = "88pm860x-regulator",
 256                .id = 7,
 257                .num_resources = ARRAY_SIZE(ldo5_resources),
 258                .resources = ldo5_resources,
 259        }, {
 260                .name = "88pm860x-regulator",
 261                .id = 8,
 262                .num_resources = ARRAY_SIZE(ldo6_resources),
 263                .resources = ldo6_resources,
 264        }, {
 265                .name = "88pm860x-regulator",
 266                .id = 9,
 267                .num_resources = ARRAY_SIZE(ldo7_resources),
 268                .resources = ldo7_resources,
 269        }, {
 270                .name = "88pm860x-regulator",
 271                .id = 10,
 272                .num_resources = ARRAY_SIZE(ldo8_resources),
 273                .resources = ldo8_resources,
 274        }, {
 275                .name = "88pm860x-regulator",
 276                .id = 11,
 277                .num_resources = ARRAY_SIZE(ldo9_resources),
 278                .resources = ldo9_resources,
 279        }, {
 280                .name = "88pm860x-regulator",
 281                .id = 12,
 282                .num_resources = ARRAY_SIZE(ldo10_resources),
 283                .resources = ldo10_resources,
 284        }, {
 285                .name = "88pm860x-regulator",
 286                .id = 13,
 287                .num_resources = ARRAY_SIZE(ldo12_resources),
 288                .resources = ldo12_resources,
 289        }, {
 290                .name = "88pm860x-regulator",
 291                .id = 14,
 292                .num_resources = ARRAY_SIZE(ldo_vibrator_resources),
 293                .resources = ldo_vibrator_resources,
 294        }, {
 295                .name = "88pm860x-regulator",
 296                .id = 15,
 297                .num_resources = ARRAY_SIZE(ldo14_resources),
 298                .resources = ldo14_resources,
 299        },
 300};
 301
 302static struct mfd_cell touch_devs[] = {
 303        {"88pm860x-touch", -1,},
 304};
 305
 306static struct mfd_cell onkey_devs[] = {
 307        {"88pm860x-onkey", -1,},
 308};
 309
 310static struct mfd_cell codec_devs[] = {
 311        {"88pm860x-codec", -1,},
 312};
 313
 314static struct regulator_consumer_supply preg_supply[] = {
 315        REGULATOR_SUPPLY("preg", "charger-manager"),
 316};
 317
 318static struct regulator_init_data preg_init_data = {
 319        .num_consumer_supplies  = ARRAY_SIZE(preg_supply),
 320        .consumer_supplies      = &preg_supply[0],
 321};
 322
 323static struct charger_regulator chg_desc_regulator_data[] = {
 324        { .regulator_name = "preg", },
 325};
 326
 327static struct mfd_cell power_devs[] = {
 328        {"88pm860x-battery", -1,},
 329        {"88pm860x-charger", -1,},
 330        {"88pm860x-preg",    -1,},
 331        {"charger-manager", -1,},
 332};
 333
 334static struct mfd_cell rtc_devs[] = {
 335        {"88pm860x-rtc", -1,},
 336};
 337
 338
 339struct pm860x_irq_data {
 340        int     reg;
 341        int     mask_reg;
 342        int     enable;         /* enable or not */
 343        int     offs;           /* bit offset in mask register */
 344};
 345
 346static struct pm860x_irq_data pm860x_irqs[] = {
 347        [PM8607_IRQ_ONKEY] = {
 348                .reg            = PM8607_INT_STATUS1,
 349                .mask_reg       = PM8607_INT_MASK_1,
 350                .offs           = 1 << 0,
 351        },
 352        [PM8607_IRQ_EXTON] = {
 353                .reg            = PM8607_INT_STATUS1,
 354                .mask_reg       = PM8607_INT_MASK_1,
 355                .offs           = 1 << 1,
 356        },
 357        [PM8607_IRQ_CHG] = {
 358                .reg            = PM8607_INT_STATUS1,
 359                .mask_reg       = PM8607_INT_MASK_1,
 360                .offs           = 1 << 2,
 361        },
 362        [PM8607_IRQ_BAT] = {
 363                .reg            = PM8607_INT_STATUS1,
 364                .mask_reg       = PM8607_INT_MASK_1,
 365                .offs           = 1 << 3,
 366        },
 367        [PM8607_IRQ_RTC] = {
 368                .reg            = PM8607_INT_STATUS1,
 369                .mask_reg       = PM8607_INT_MASK_1,
 370                .offs           = 1 << 4,
 371        },
 372        [PM8607_IRQ_CC] = {
 373                .reg            = PM8607_INT_STATUS1,
 374                .mask_reg       = PM8607_INT_MASK_1,
 375                .offs           = 1 << 5,
 376        },
 377        [PM8607_IRQ_VBAT] = {
 378                .reg            = PM8607_INT_STATUS2,
 379                .mask_reg       = PM8607_INT_MASK_2,
 380                .offs           = 1 << 0,
 381        },
 382        [PM8607_IRQ_VCHG] = {
 383                .reg            = PM8607_INT_STATUS2,
 384                .mask_reg       = PM8607_INT_MASK_2,
 385                .offs           = 1 << 1,
 386        },
 387        [PM8607_IRQ_VSYS] = {
 388                .reg            = PM8607_INT_STATUS2,
 389                .mask_reg       = PM8607_INT_MASK_2,
 390                .offs           = 1 << 2,
 391        },
 392        [PM8607_IRQ_TINT] = {
 393                .reg            = PM8607_INT_STATUS2,
 394                .mask_reg       = PM8607_INT_MASK_2,
 395                .offs           = 1 << 3,
 396        },
 397        [PM8607_IRQ_GPADC0] = {
 398                .reg            = PM8607_INT_STATUS2,
 399                .mask_reg       = PM8607_INT_MASK_2,
 400                .offs           = 1 << 4,
 401        },
 402        [PM8607_IRQ_GPADC1] = {
 403                .reg            = PM8607_INT_STATUS2,
 404                .mask_reg       = PM8607_INT_MASK_2,
 405                .offs           = 1 << 5,
 406        },
 407        [PM8607_IRQ_GPADC2] = {
 408                .reg            = PM8607_INT_STATUS2,
 409                .mask_reg       = PM8607_INT_MASK_2,
 410                .offs           = 1 << 6,
 411        },
 412        [PM8607_IRQ_GPADC3] = {
 413                .reg            = PM8607_INT_STATUS2,
 414                .mask_reg       = PM8607_INT_MASK_2,
 415                .offs           = 1 << 7,
 416        },
 417        [PM8607_IRQ_AUDIO_SHORT] = {
 418                .reg            = PM8607_INT_STATUS3,
 419                .mask_reg       = PM8607_INT_MASK_3,
 420                .offs           = 1 << 0,
 421        },
 422        [PM8607_IRQ_PEN] = {
 423                .reg            = PM8607_INT_STATUS3,
 424                .mask_reg       = PM8607_INT_MASK_3,
 425                .offs           = 1 << 1,
 426        },
 427        [PM8607_IRQ_HEADSET] = {
 428                .reg            = PM8607_INT_STATUS3,
 429                .mask_reg       = PM8607_INT_MASK_3,
 430                .offs           = 1 << 2,
 431        },
 432        [PM8607_IRQ_HOOK] = {
 433                .reg            = PM8607_INT_STATUS3,
 434                .mask_reg       = PM8607_INT_MASK_3,
 435                .offs           = 1 << 3,
 436        },
 437        [PM8607_IRQ_MICIN] = {
 438                .reg            = PM8607_INT_STATUS3,
 439                .mask_reg       = PM8607_INT_MASK_3,
 440                .offs           = 1 << 4,
 441        },
 442        [PM8607_IRQ_CHG_FAIL] = {
 443                .reg            = PM8607_INT_STATUS3,
 444                .mask_reg       = PM8607_INT_MASK_3,
 445                .offs           = 1 << 5,
 446        },
 447        [PM8607_IRQ_CHG_DONE] = {
 448                .reg            = PM8607_INT_STATUS3,
 449                .mask_reg       = PM8607_INT_MASK_3,
 450                .offs           = 1 << 6,
 451        },
 452        [PM8607_IRQ_CHG_FAULT] = {
 453                .reg            = PM8607_INT_STATUS3,
 454                .mask_reg       = PM8607_INT_MASK_3,
 455                .offs           = 1 << 7,
 456        },
 457};
 458
 459static irqreturn_t pm860x_irq(int irq, void *data)
 460{
 461        struct pm860x_chip *chip = data;
 462        struct pm860x_irq_data *irq_data;
 463        struct i2c_client *i2c;
 464        int read_reg = -1, value = 0;
 465        int i;
 466
 467        i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
 468        for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) {
 469                irq_data = &pm860x_irqs[i];
 470                if (read_reg != irq_data->reg) {
 471                        read_reg = irq_data->reg;
 472                        value = pm860x_reg_read(i2c, irq_data->reg);
 473                }
 474                if (value & irq_data->enable)
 475                        handle_nested_irq(chip->irq_base + i);
 476        }
 477        return IRQ_HANDLED;
 478}
 479
 480static void pm860x_irq_lock(struct irq_data *data)
 481{
 482        struct pm860x_chip *chip = irq_data_get_irq_chip_data(data);
 483
 484        mutex_lock(&chip->irq_lock);
 485}
 486
 487static void pm860x_irq_sync_unlock(struct irq_data *data)
 488{
 489        struct pm860x_chip *chip = irq_data_get_irq_chip_data(data);
 490        struct pm860x_irq_data *irq_data;
 491        struct i2c_client *i2c;
 492        static unsigned char cached[3] = {0x0, 0x0, 0x0};
 493        unsigned char mask[3];
 494        int i;
 495
 496        i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
 497        /* Load cached value. In initial, all IRQs are masked */
 498        for (i = 0; i < 3; i++)
 499                mask[i] = cached[i];
 500        for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) {
 501                irq_data = &pm860x_irqs[i];
 502                switch (irq_data->mask_reg) {
 503                case PM8607_INT_MASK_1:
 504                        mask[0] &= ~irq_data->offs;
 505                        mask[0] |= irq_data->enable;
 506                        break;
 507                case PM8607_INT_MASK_2:
 508                        mask[1] &= ~irq_data->offs;
 509                        mask[1] |= irq_data->enable;
 510                        break;
 511                case PM8607_INT_MASK_3:
 512                        mask[2] &= ~irq_data->offs;
 513                        mask[2] |= irq_data->enable;
 514                        break;
 515                default:
 516                        dev_err(chip->dev, "wrong IRQ\n");
 517                        break;
 518                }
 519        }
 520        /* update mask into registers */
 521        for (i = 0; i < 3; i++) {
 522                if (mask[i] != cached[i]) {
 523                        cached[i] = mask[i];
 524                        pm860x_reg_write(i2c, PM8607_INT_MASK_1 + i, mask[i]);
 525                }
 526        }
 527
 528        mutex_unlock(&chip->irq_lock);
 529}
 530
 531static void pm860x_irq_enable(struct irq_data *data)
 532{
 533        pm860x_irqs[data->hwirq].enable = pm860x_irqs[data->hwirq].offs;
 534}
 535
 536static void pm860x_irq_disable(struct irq_data *data)
 537{
 538        pm860x_irqs[data->hwirq].enable = 0;
 539}
 540
 541static struct irq_chip pm860x_irq_chip = {
 542        .name           = "88pm860x",
 543        .irq_bus_lock   = pm860x_irq_lock,
 544        .irq_bus_sync_unlock = pm860x_irq_sync_unlock,
 545        .irq_enable     = pm860x_irq_enable,
 546        .irq_disable    = pm860x_irq_disable,
 547};
 548
 549static int pm860x_irq_domain_map(struct irq_domain *d, unsigned int virq,
 550                                 irq_hw_number_t hw)
 551{
 552        irq_set_chip_data(virq, d->host_data);
 553        irq_set_chip_and_handler(virq, &pm860x_irq_chip, handle_edge_irq);
 554        irq_set_nested_thread(virq, 1);
 555#ifdef CONFIG_ARM
 556        set_irq_flags(virq, IRQF_VALID);
 557#else
 558        irq_set_noprobe(virq);
 559#endif
 560        return 0;
 561}
 562
 563static struct irq_domain_ops pm860x_irq_domain_ops = {
 564        .map    = pm860x_irq_domain_map,
 565        .xlate  = irq_domain_xlate_onetwocell,
 566};
 567
 568static int device_irq_init(struct pm860x_chip *chip,
 569                                     struct pm860x_platform_data *pdata)
 570{
 571        struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
 572                                : chip->companion;
 573        unsigned char status_buf[INT_STATUS_NUM];
 574        unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
 575        int data, mask, ret = -EINVAL;
 576        int nr_irqs, irq_base = -1;
 577        struct device_node *node = i2c->dev.of_node;
 578
 579        mask = PM8607_B0_MISC1_INV_INT | PM8607_B0_MISC1_INT_CLEAR
 580                | PM8607_B0_MISC1_INT_MASK;
 581        data = 0;
 582        chip->irq_mode = 0;
 583        if (pdata && pdata->irq_mode) {
 584                /*
 585                 * irq_mode defines the way of clearing interrupt. If it's 1,
 586                 * clear IRQ by write. Otherwise, clear it by read.
 587                 * This control bit is valid from 88PM8607 B0 steping.
 588                 */
 589                data |= PM8607_B0_MISC1_INT_CLEAR;
 590                chip->irq_mode = 1;
 591        }
 592        ret = pm860x_set_bits(i2c, PM8607_B0_MISC1, mask, data);
 593        if (ret < 0)
 594                goto out;
 595
 596        /* mask all IRQs */
 597        memset(status_buf, 0, INT_STATUS_NUM);
 598        ret = pm860x_bulk_write(i2c, PM8607_INT_MASK_1,
 599                                INT_STATUS_NUM, status_buf);
 600        if (ret < 0)
 601                goto out;
 602
 603        if (chip->irq_mode) {
 604                /* clear interrupt status by write */
 605                memset(status_buf, 0xFF, INT_STATUS_NUM);
 606                ret = pm860x_bulk_write(i2c, PM8607_INT_STATUS1,
 607                                        INT_STATUS_NUM, status_buf);
 608        } else {
 609                /* clear interrupt status by read */
 610                ret = pm860x_bulk_read(i2c, PM8607_INT_STATUS1,
 611                                        INT_STATUS_NUM, status_buf);
 612        }
 613        if (ret < 0)
 614                goto out;
 615
 616        mutex_init(&chip->irq_lock);
 617
 618        if (pdata && pdata->irq_base)
 619                irq_base = pdata->irq_base;
 620        nr_irqs = ARRAY_SIZE(pm860x_irqs);
 621        chip->irq_base = irq_alloc_descs(irq_base, 0, nr_irqs, 0);
 622        if (chip->irq_base < 0) {
 623                dev_err(&i2c->dev, "Failed to allocate interrupts, ret:%d\n",
 624                        chip->irq_base);
 625                ret = -EBUSY;
 626                goto out;
 627        }
 628        irq_domain_add_legacy(node, nr_irqs, chip->irq_base, 0,
 629                              &pm860x_irq_domain_ops, chip);
 630        chip->core_irq = i2c->irq;
 631        if (!chip->core_irq)
 632                goto out;
 633
 634        ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, flags | IRQF_ONESHOT,
 635                                   "88pm860x", chip);
 636        if (ret) {
 637                dev_err(chip->dev, "Failed to request IRQ: %d\n", ret);
 638                chip->core_irq = 0;
 639        }
 640
 641        return 0;
 642out:
 643        chip->core_irq = 0;
 644        return ret;
 645}
 646
 647static void device_irq_exit(struct pm860x_chip *chip)
 648{
 649        if (chip->core_irq)
 650                free_irq(chip->core_irq, chip);
 651}
 652
 653int pm8606_osc_enable(struct pm860x_chip *chip, unsigned short client)
 654{
 655        int ret = -EIO;
 656        struct i2c_client *i2c = (chip->id == CHIP_PM8606) ?
 657                chip->client : chip->companion;
 658
 659        dev_dbg(chip->dev, "%s(B): client=0x%x\n", __func__, client);
 660        dev_dbg(chip->dev, "%s(B): vote=0x%x status=%d\n",
 661                        __func__, chip->osc_vote,
 662                        chip->osc_status);
 663
 664        mutex_lock(&chip->osc_lock);
 665        /* Update voting status */
 666        chip->osc_vote |= client;
 667        /* If reference group is off - turn on*/
 668        if (chip->osc_status != PM8606_REF_GP_OSC_ON) {
 669                chip->osc_status = PM8606_REF_GP_OSC_UNKNOWN;
 670                /* Enable Reference group Vsys */
 671                if (pm860x_set_bits(i2c, PM8606_VSYS,
 672                                PM8606_VSYS_EN, PM8606_VSYS_EN))
 673                        goto out;
 674
 675                /*Enable Internal Oscillator */
 676                if (pm860x_set_bits(i2c, PM8606_MISC,
 677                                PM8606_MISC_OSC_EN, PM8606_MISC_OSC_EN))
 678                        goto out;
 679                /* Update status (only if writes succeed) */
 680                chip->osc_status = PM8606_REF_GP_OSC_ON;
 681        }
 682        mutex_unlock(&chip->osc_lock);
 683
 684        dev_dbg(chip->dev, "%s(A): vote=0x%x status=%d ret=%d\n",
 685                        __func__, chip->osc_vote,
 686                        chip->osc_status, ret);
 687        return 0;
 688out:
 689        mutex_unlock(&chip->osc_lock);
 690        return ret;
 691}
 692EXPORT_SYMBOL(pm8606_osc_enable);
 693
 694int pm8606_osc_disable(struct pm860x_chip *chip, unsigned short client)
 695{
 696        int ret = -EIO;
 697        struct i2c_client *i2c = (chip->id == CHIP_PM8606) ?
 698                chip->client : chip->companion;
 699
 700        dev_dbg(chip->dev, "%s(B): client=0x%x\n", __func__, client);
 701        dev_dbg(chip->dev, "%s(B): vote=0x%x status=%d\n",
 702                        __func__, chip->osc_vote,
 703                        chip->osc_status);
 704
 705        mutex_lock(&chip->osc_lock);
 706        /*Update voting status */
 707        chip->osc_vote &= ~(client);
 708        /* If reference group is off and this is the last client to release
 709         * - turn off */
 710        if ((chip->osc_status != PM8606_REF_GP_OSC_OFF) &&
 711                        (chip->osc_vote == REF_GP_NO_CLIENTS)) {
 712                chip->osc_status = PM8606_REF_GP_OSC_UNKNOWN;
 713                /* Disable Reference group Vsys */
 714                if (pm860x_set_bits(i2c, PM8606_VSYS, PM8606_VSYS_EN, 0))
 715                        goto out;
 716                /* Disable Internal Oscillator */
 717                if (pm860x_set_bits(i2c, PM8606_MISC, PM8606_MISC_OSC_EN, 0))
 718                        goto out;
 719                chip->osc_status = PM8606_REF_GP_OSC_OFF;
 720        }
 721        mutex_unlock(&chip->osc_lock);
 722
 723        dev_dbg(chip->dev, "%s(A): vote=0x%x status=%d ret=%d\n",
 724                        __func__, chip->osc_vote,
 725                        chip->osc_status, ret);
 726        return 0;
 727out:
 728        mutex_unlock(&chip->osc_lock);
 729        return ret;
 730}
 731EXPORT_SYMBOL(pm8606_osc_disable);
 732
 733static void device_osc_init(struct i2c_client *i2c)
 734{
 735        struct pm860x_chip *chip = i2c_get_clientdata(i2c);
 736
 737        mutex_init(&chip->osc_lock);
 738        /* init portofino reference group voting and status */
 739        /* Disable Reference group Vsys */
 740        pm860x_set_bits(i2c, PM8606_VSYS, PM8606_VSYS_EN, 0);
 741        /* Disable Internal Oscillator */
 742        pm860x_set_bits(i2c, PM8606_MISC, PM8606_MISC_OSC_EN, 0);
 743
 744        chip->osc_vote = REF_GP_NO_CLIENTS;
 745        chip->osc_status = PM8606_REF_GP_OSC_OFF;
 746}
 747
 748static void device_bk_init(struct pm860x_chip *chip,
 749                                     struct pm860x_platform_data *pdata)
 750{
 751        int ret, i;
 752
 753        if (pdata && pdata->backlight) {
 754                if (pdata->num_backlights > ARRAY_SIZE(bk_devs))
 755                        pdata->num_backlights = ARRAY_SIZE(bk_devs);
 756                for (i = 0; i < pdata->num_backlights; i++) {
 757                        bk_devs[i].platform_data = &pdata->backlight[i];
 758                        bk_devs[i].pdata_size =
 759                                sizeof(struct pm860x_backlight_pdata);
 760                }
 761        }
 762        ret = mfd_add_devices(chip->dev, 0, bk_devs,
 763                              ARRAY_SIZE(bk_devs), NULL, 0, NULL);
 764        if (ret < 0)
 765                dev_err(chip->dev, "Failed to add backlight subdev\n");
 766}
 767
 768static void device_led_init(struct pm860x_chip *chip,
 769                                      struct pm860x_platform_data *pdata)
 770{
 771        int ret, i;
 772
 773        if (pdata && pdata->led) {
 774                if (pdata->num_leds > ARRAY_SIZE(led_devs))
 775                        pdata->num_leds = ARRAY_SIZE(led_devs);
 776                for (i = 0; i < pdata->num_leds; i++) {
 777                        led_devs[i].platform_data = &pdata->led[i];
 778                        led_devs[i].pdata_size =
 779                                sizeof(struct pm860x_led_pdata);
 780                }
 781        }
 782        ret = mfd_add_devices(chip->dev, 0, led_devs,
 783                              ARRAY_SIZE(led_devs), NULL, 0, NULL);
 784        if (ret < 0) {
 785                dev_err(chip->dev, "Failed to add led subdev\n");
 786                return;
 787        }
 788}
 789
 790static void device_regulator_init(struct pm860x_chip *chip,
 791                                            struct pm860x_platform_data *pdata)
 792{
 793        int ret;
 794
 795        if (pdata == NULL)
 796                return;
 797        if (pdata->buck1) {
 798                reg_devs[0].platform_data = pdata->buck1;
 799                reg_devs[0].pdata_size = sizeof(struct regulator_init_data);
 800        }
 801        if (pdata->buck2) {
 802                reg_devs[1].platform_data = pdata->buck2;
 803                reg_devs[1].pdata_size = sizeof(struct regulator_init_data);
 804        }
 805        if (pdata->buck3) {
 806                reg_devs[2].platform_data = pdata->buck3;
 807                reg_devs[2].pdata_size = sizeof(struct regulator_init_data);
 808        }
 809        if (pdata->ldo1) {
 810                reg_devs[3].platform_data = pdata->ldo1;
 811                reg_devs[3].pdata_size = sizeof(struct regulator_init_data);
 812        }
 813        if (pdata->ldo2) {
 814                reg_devs[4].platform_data = pdata->ldo2;
 815                reg_devs[4].pdata_size = sizeof(struct regulator_init_data);
 816        }
 817        if (pdata->ldo3) {
 818                reg_devs[5].platform_data = pdata->ldo3;
 819                reg_devs[5].pdata_size = sizeof(struct regulator_init_data);
 820        }
 821        if (pdata->ldo4) {
 822                reg_devs[6].platform_data = pdata->ldo4;
 823                reg_devs[6].pdata_size = sizeof(struct regulator_init_data);
 824        }
 825        if (pdata->ldo5) {
 826                reg_devs[7].platform_data = pdata->ldo5;
 827                reg_devs[7].pdata_size = sizeof(struct regulator_init_data);
 828        }
 829        if (pdata->ldo6) {
 830                reg_devs[8].platform_data = pdata->ldo6;
 831                reg_devs[8].pdata_size = sizeof(struct regulator_init_data);
 832        }
 833        if (pdata->ldo7) {
 834                reg_devs[9].platform_data = pdata->ldo7;
 835                reg_devs[9].pdata_size = sizeof(struct regulator_init_data);
 836        }
 837        if (pdata->ldo8) {
 838                reg_devs[10].platform_data = pdata->ldo8;
 839                reg_devs[10].pdata_size = sizeof(struct regulator_init_data);
 840        }
 841        if (pdata->ldo9) {
 842                reg_devs[11].platform_data = pdata->ldo9;
 843                reg_devs[11].pdata_size = sizeof(struct regulator_init_data);
 844        }
 845        if (pdata->ldo10) {
 846                reg_devs[12].platform_data = pdata->ldo10;
 847                reg_devs[12].pdata_size = sizeof(struct regulator_init_data);
 848        }
 849        if (pdata->ldo12) {
 850                reg_devs[13].platform_data = pdata->ldo12;
 851                reg_devs[13].pdata_size = sizeof(struct regulator_init_data);
 852        }
 853        if (pdata->ldo_vibrator) {
 854                reg_devs[14].platform_data = pdata->ldo_vibrator;
 855                reg_devs[14].pdata_size = sizeof(struct regulator_init_data);
 856        }
 857        if (pdata->ldo14) {
 858                reg_devs[15].platform_data = pdata->ldo14;
 859                reg_devs[15].pdata_size = sizeof(struct regulator_init_data);
 860        }
 861        ret = mfd_add_devices(chip->dev, 0, reg_devs,
 862                              ARRAY_SIZE(reg_devs), NULL, 0, NULL);
 863        if (ret < 0) {
 864                dev_err(chip->dev, "Failed to add regulator subdev\n");
 865                return;
 866        }
 867}
 868
 869static void device_rtc_init(struct pm860x_chip *chip,
 870                                      struct pm860x_platform_data *pdata)
 871{
 872        int ret;
 873
 874        if ((pdata == NULL))
 875                return;
 876
 877        rtc_devs[0].platform_data = pdata->rtc;
 878        rtc_devs[0].pdata_size = sizeof(struct pm860x_rtc_pdata);
 879        rtc_devs[0].num_resources = ARRAY_SIZE(rtc_resources);
 880        rtc_devs[0].resources = &rtc_resources[0];
 881        ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
 882                              ARRAY_SIZE(rtc_devs), &rtc_resources[0],
 883                              chip->irq_base, NULL);
 884        if (ret < 0)
 885                dev_err(chip->dev, "Failed to add rtc subdev\n");
 886}
 887
 888static void device_touch_init(struct pm860x_chip *chip,
 889                                        struct pm860x_platform_data *pdata)
 890{
 891        int ret;
 892
 893        if (pdata == NULL)
 894                return;
 895
 896        touch_devs[0].platform_data = pdata->touch;
 897        touch_devs[0].pdata_size = sizeof(struct pm860x_touch_pdata);
 898        touch_devs[0].num_resources = ARRAY_SIZE(touch_resources);
 899        touch_devs[0].resources = &touch_resources[0];
 900        ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
 901                              ARRAY_SIZE(touch_devs), &touch_resources[0],
 902                              chip->irq_base, NULL);
 903        if (ret < 0)
 904                dev_err(chip->dev, "Failed to add touch subdev\n");
 905}
 906
 907static void device_power_init(struct pm860x_chip *chip,
 908                                        struct pm860x_platform_data *pdata)
 909{
 910        int ret;
 911
 912        if (pdata == NULL)
 913                return;
 914
 915        power_devs[0].platform_data = pdata->power;
 916        power_devs[0].pdata_size = sizeof(struct pm860x_power_pdata);
 917        power_devs[0].num_resources = ARRAY_SIZE(battery_resources);
 918        power_devs[0].resources = &battery_resources[0],
 919        ret = mfd_add_devices(chip->dev, 0, &power_devs[0], 1,
 920                              &battery_resources[0], chip->irq_base, NULL);
 921        if (ret < 0)
 922                dev_err(chip->dev, "Failed to add battery subdev\n");
 923
 924        power_devs[1].platform_data = pdata->power;
 925        power_devs[1].pdata_size = sizeof(struct pm860x_power_pdata);
 926        power_devs[1].num_resources = ARRAY_SIZE(charger_resources);
 927        power_devs[1].resources = &charger_resources[0],
 928        ret = mfd_add_devices(chip->dev, 0, &power_devs[1], 1,
 929                              &charger_resources[0], chip->irq_base, NULL);
 930        if (ret < 0)
 931                dev_err(chip->dev, "Failed to add charger subdev\n");
 932
 933        power_devs[2].platform_data = &preg_init_data;
 934        power_devs[2].pdata_size = sizeof(struct regulator_init_data);
 935        ret = mfd_add_devices(chip->dev, 0, &power_devs[2], 1,
 936                              NULL, chip->irq_base, NULL);
 937        if (ret < 0)
 938                dev_err(chip->dev, "Failed to add preg subdev\n");
 939
 940        if (pdata->chg_desc) {
 941                pdata->chg_desc->charger_regulators =
 942                        &chg_desc_regulator_data[0];
 943                pdata->chg_desc->num_charger_regulators =
 944                        ARRAY_SIZE(chg_desc_regulator_data),
 945                power_devs[3].platform_data = pdata->chg_desc;
 946                power_devs[3].pdata_size = sizeof(*pdata->chg_desc);
 947                ret = mfd_add_devices(chip->dev, 0, &power_devs[3], 1,
 948                                      NULL, chip->irq_base, NULL);
 949                if (ret < 0)
 950                        dev_err(chip->dev, "Failed to add chg-manager subdev\n");
 951        }
 952}
 953
 954static void device_onkey_init(struct pm860x_chip *chip,
 955                                        struct pm860x_platform_data *pdata)
 956{
 957        int ret;
 958
 959        onkey_devs[0].num_resources = ARRAY_SIZE(onkey_resources);
 960        onkey_devs[0].resources = &onkey_resources[0],
 961        ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],
 962                              ARRAY_SIZE(onkey_devs), &onkey_resources[0],
 963                              chip->irq_base, NULL);
 964        if (ret < 0)
 965                dev_err(chip->dev, "Failed to add onkey subdev\n");
 966}
 967
 968static void device_codec_init(struct pm860x_chip *chip,
 969                                        struct pm860x_platform_data *pdata)
 970{
 971        int ret;
 972
 973        codec_devs[0].num_resources = ARRAY_SIZE(codec_resources);
 974        codec_devs[0].resources = &codec_resources[0],
 975        ret = mfd_add_devices(chip->dev, 0, &codec_devs[0],
 976                              ARRAY_SIZE(codec_devs), &codec_resources[0], 0,
 977                              NULL);
 978        if (ret < 0)
 979                dev_err(chip->dev, "Failed to add codec subdev\n");
 980}
 981
 982static void device_8607_init(struct pm860x_chip *chip,
 983                                       struct i2c_client *i2c,
 984                                       struct pm860x_platform_data *pdata)
 985{
 986        int data, ret;
 987
 988        ret = pm860x_reg_read(i2c, PM8607_CHIP_ID);
 989        if (ret < 0) {
 990                dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret);
 991                goto out;
 992        }
 993        switch (ret & PM8607_VERSION_MASK) {
 994        case 0x40:
 995        case 0x50:
 996                dev_info(chip->dev, "Marvell 88PM8607 (ID: %02x) detected\n",
 997                         ret);
 998                break;
 999        default:
1000                dev_err(chip->dev, "Failed to detect Marvell 88PM8607. "
1001                        "Chip ID: %02x\n", ret);
1002                goto out;
1003        }
1004
1005        ret = pm860x_reg_read(i2c, PM8607_BUCK3);
1006        if (ret < 0) {
1007                dev_err(chip->dev, "Failed to read BUCK3 register: %d\n", ret);
1008                goto out;
1009        }
1010        if (ret & PM8607_BUCK3_DOUBLE)
1011                chip->buck3_double = 1;
1012
1013        ret = pm860x_reg_read(i2c, PM8607_B0_MISC1);
1014        if (ret < 0) {
1015                dev_err(chip->dev, "Failed to read MISC1 register: %d\n", ret);
1016                goto out;
1017        }
1018
1019        if (pdata && (pdata->i2c_port == PI2C_PORT))
1020                data = PM8607_B0_MISC1_PI2C;
1021        else
1022                data = 0;
1023        ret = pm860x_set_bits(i2c, PM8607_B0_MISC1, PM8607_B0_MISC1_PI2C, data);
1024        if (ret < 0) {
1025                dev_err(chip->dev, "Failed to access MISC1:%d\n", ret);
1026                goto out;
1027        }
1028
1029        ret = device_irq_init(chip, pdata);
1030        if (ret < 0)
1031                goto out;
1032
1033        device_regulator_init(chip, pdata);
1034        device_rtc_init(chip, pdata);
1035        device_onkey_init(chip, pdata);
1036        device_touch_init(chip, pdata);
1037        device_power_init(chip, pdata);
1038        device_codec_init(chip, pdata);
1039out:
1040        return;
1041}
1042
1043static void device_8606_init(struct pm860x_chip *chip,
1044                                       struct i2c_client *i2c,
1045                                       struct pm860x_platform_data *pdata)
1046{
1047        device_osc_init(i2c);
1048        device_bk_init(chip, pdata);
1049        device_led_init(chip, pdata);
1050}
1051
1052static int pm860x_device_init(struct pm860x_chip *chip,
1053                                        struct pm860x_platform_data *pdata)
1054{
1055        chip->core_irq = 0;
1056
1057        switch (chip->id) {
1058        case CHIP_PM8606:
1059                device_8606_init(chip, chip->client, pdata);
1060                break;
1061        case CHIP_PM8607:
1062                device_8607_init(chip, chip->client, pdata);
1063                break;
1064        }
1065
1066        if (chip->companion) {
1067                switch (chip->id) {
1068                case CHIP_PM8607:
1069                        device_8606_init(chip, chip->companion, pdata);
1070                        break;
1071                case CHIP_PM8606:
1072                        device_8607_init(chip, chip->companion, pdata);
1073                        break;
1074                }
1075        }
1076
1077        return 0;
1078}
1079
1080static void pm860x_device_exit(struct pm860x_chip *chip)
1081{
1082        device_irq_exit(chip);
1083        mfd_remove_devices(chip->dev);
1084}
1085
1086static int verify_addr(struct i2c_client *i2c)
1087{
1088        unsigned short addr_8607[] = {0x30, 0x34};
1089        unsigned short addr_8606[] = {0x10, 0x11};
1090        int size, i;
1091
1092        if (i2c == NULL)
1093                return 0;
1094        size = ARRAY_SIZE(addr_8606);
1095        for (i = 0; i < size; i++) {
1096                if (i2c->addr == *(addr_8606 + i))
1097                        return CHIP_PM8606;
1098        }
1099        size = ARRAY_SIZE(addr_8607);
1100        for (i = 0; i < size; i++) {
1101                if (i2c->addr == *(addr_8607 + i))
1102                        return CHIP_PM8607;
1103        }
1104        return 0;
1105}
1106
1107static struct regmap_config pm860x_regmap_config = {
1108        .reg_bits = 8,
1109        .val_bits = 8,
1110};
1111
1112static int pm860x_dt_init(struct device_node *np,
1113                                    struct device *dev,
1114                                    struct pm860x_platform_data *pdata)
1115{
1116        int ret;
1117
1118        if (of_get_property(np, "marvell,88pm860x-irq-read-clr", NULL))
1119                pdata->irq_mode = 1;
1120        ret = of_property_read_u32(np, "marvell,88pm860x-slave-addr",
1121                                   &pdata->companion_addr);
1122        if (ret) {
1123                dev_err(dev, "Not found \"marvell,88pm860x-slave-addr\" "
1124                        "property\n");
1125                pdata->companion_addr = 0;
1126        }
1127        return 0;
1128}
1129
1130static int pm860x_probe(struct i2c_client *client,
1131                                  const struct i2c_device_id *id)
1132{
1133        struct pm860x_platform_data *pdata = client->dev.platform_data;
1134        struct device_node *node = client->dev.of_node;
1135        struct pm860x_chip *chip;
1136        int ret;
1137
1138        if (node && !pdata) {
1139                /* parse DT to get platform data */
1140                pdata = devm_kzalloc(&client->dev,
1141                                     sizeof(struct pm860x_platform_data),
1142                                     GFP_KERNEL);
1143                if (!pdata)
1144                        return -ENOMEM;
1145                ret = pm860x_dt_init(node, &client->dev, pdata);
1146                if (ret)
1147                        return ret;
1148        } else if (!pdata) {
1149                pr_info("No platform data in %s!\n", __func__);
1150                return -EINVAL;
1151        }
1152
1153        chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL);
1154        if (chip == NULL)
1155                return -ENOMEM;
1156
1157        chip->id = verify_addr(client);
1158        chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config);
1159        if (IS_ERR(chip->regmap)) {
1160                ret = PTR_ERR(chip->regmap);
1161                dev_err(&client->dev, "Failed to allocate register map: %d\n",
1162                                ret);
1163                kfree(chip);
1164                return ret;
1165        }
1166        chip->client = client;
1167        i2c_set_clientdata(client, chip);
1168        chip->dev = &client->dev;
1169        dev_set_drvdata(chip->dev, chip);
1170
1171        /*
1172         * Both client and companion client shares same platform driver.
1173         * Driver distinguishes them by pdata->companion_addr.
1174         * pdata->companion_addr is only assigned if companion chip exists.
1175         * At the same time, the companion_addr shouldn't equal to client
1176         * address.
1177         */
1178        if (pdata->companion_addr && (pdata->companion_addr != client->addr)) {
1179                chip->companion_addr = pdata->companion_addr;
1180                chip->companion = i2c_new_dummy(chip->client->adapter,
1181                                                chip->companion_addr);
1182                chip->regmap_companion = regmap_init_i2c(chip->companion,
1183                                                        &pm860x_regmap_config);
1184                if (IS_ERR(chip->regmap_companion)) {
1185                        ret = PTR_ERR(chip->regmap_companion);
1186                        dev_err(&chip->companion->dev,
1187                                "Failed to allocate register map: %d\n", ret);
1188                        return ret;
1189                }
1190                i2c_set_clientdata(chip->companion, chip);
1191        }
1192
1193        pm860x_device_init(chip, pdata);
1194        return 0;
1195}
1196
1197static int pm860x_remove(struct i2c_client *client)
1198{
1199        struct pm860x_chip *chip = i2c_get_clientdata(client);
1200
1201        pm860x_device_exit(chip);
1202        if (chip->companion) {
1203                regmap_exit(chip->regmap_companion);
1204                i2c_unregister_device(chip->companion);
1205        }
1206        regmap_exit(chip->regmap);
1207        kfree(chip);
1208        return 0;
1209}
1210
1211#ifdef CONFIG_PM_SLEEP
1212static int pm860x_suspend(struct device *dev)
1213{
1214        struct i2c_client *client = container_of(dev, struct i2c_client, dev);
1215        struct pm860x_chip *chip = i2c_get_clientdata(client);
1216
1217        if (device_may_wakeup(dev) && chip->wakeup_flag)
1218                enable_irq_wake(chip->core_irq);
1219        return 0;
1220}
1221
1222static int pm860x_resume(struct device *dev)
1223{
1224        struct i2c_client *client = container_of(dev, struct i2c_client, dev);
1225        struct pm860x_chip *chip = i2c_get_clientdata(client);
1226
1227        if (device_may_wakeup(dev) && chip->wakeup_flag)
1228                disable_irq_wake(chip->core_irq);
1229        return 0;
1230}
1231#endif
1232
1233static SIMPLE_DEV_PM_OPS(pm860x_pm_ops, pm860x_suspend, pm860x_resume);
1234
1235static const struct i2c_device_id pm860x_id_table[] = {
1236        { "88PM860x", 0 },
1237        {}
1238};
1239MODULE_DEVICE_TABLE(i2c, pm860x_id_table);
1240
1241static const struct of_device_id pm860x_dt_ids[] = {
1242        { .compatible = "marvell,88pm860x", },
1243        {},
1244};
1245MODULE_DEVICE_TABLE(of, pm860x_dt_ids);
1246
1247static struct i2c_driver pm860x_driver = {
1248        .driver = {
1249                .name   = "88PM860x",
1250                .owner  = THIS_MODULE,
1251                .pm     = &pm860x_pm_ops,
1252                .of_match_table = of_match_ptr(pm860x_dt_ids),
1253        },
1254        .probe          = pm860x_probe,
1255        .remove         = pm860x_remove,
1256        .id_table       = pm860x_id_table,
1257};
1258
1259static int __init pm860x_i2c_init(void)
1260{
1261        int ret;
1262        ret = i2c_add_driver(&pm860x_driver);
1263        if (ret != 0)
1264                pr_err("Failed to register 88PM860x I2C driver: %d\n", ret);
1265        return ret;
1266}
1267subsys_initcall(pm860x_i2c_init);
1268
1269static void __exit pm860x_i2c_exit(void)
1270{
1271        i2c_del_driver(&pm860x_driver);
1272}
1273module_exit(pm860x_i2c_exit);
1274
1275MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM860x");
1276MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
1277MODULE_LICENSE("GPL");
1278
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.