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