Linux Audio

Check our new training course

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