brintos

brintos / linux-shallow public Read only

0
0
Text · 22.9 KiB · 105d79b Raw
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