xref: /linux/drivers/mfd/stmpe.c (revision ac713cc9fcb8a5f9503af08421772b85ca4685f1)
127e34995SRabin Vincent /*
21a6e4b74SViresh Kumar  * ST Microelectronics MFD: stmpe's driver
31a6e4b74SViresh Kumar  *
427e34995SRabin Vincent  * Copyright (C) ST-Ericsson SA 2010
527e34995SRabin Vincent  *
627e34995SRabin Vincent  * License Terms: GNU General Public License, version 2
727e34995SRabin Vincent  * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
827e34995SRabin Vincent  */
927e34995SRabin Vincent 
10*ac713cc9SVipul Kumar Samar #include <linux/err.h>
1173de16dbSViresh Kumar #include <linux/gpio.h>
12dba61c8fSSamuel Ortiz #include <linux/export.h>
1327e34995SRabin Vincent #include <linux/kernel.h>
1427e34995SRabin Vincent #include <linux/interrupt.h>
1527e34995SRabin Vincent #include <linux/irq.h>
1676f93992SLee Jones #include <linux/irqdomain.h>
1720d5c7deSRandy Dunlap #include <linux/of.h>
18*ac713cc9SVipul Kumar Samar #include <linux/of_gpio.h>
191a6e4b74SViresh Kumar #include <linux/pm.h>
2027e34995SRabin Vincent #include <linux/slab.h>
2127e34995SRabin Vincent #include <linux/mfd/core.h>
2227e34995SRabin Vincent #include "stmpe.h"
2327e34995SRabin Vincent 
2427e34995SRabin Vincent static int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks)
2527e34995SRabin Vincent {
2627e34995SRabin Vincent 	return stmpe->variant->enable(stmpe, blocks, true);
2727e34995SRabin Vincent }
2827e34995SRabin Vincent 
2927e34995SRabin Vincent static int __stmpe_disable(struct stmpe *stmpe, unsigned int blocks)
3027e34995SRabin Vincent {
3127e34995SRabin Vincent 	return stmpe->variant->enable(stmpe, blocks, false);
3227e34995SRabin Vincent }
3327e34995SRabin Vincent 
3427e34995SRabin Vincent static int __stmpe_reg_read(struct stmpe *stmpe, u8 reg)
3527e34995SRabin Vincent {
3627e34995SRabin Vincent 	int ret;
3727e34995SRabin Vincent 
381a6e4b74SViresh Kumar 	ret = stmpe->ci->read_byte(stmpe, reg);
3927e34995SRabin Vincent 	if (ret < 0)
401a6e4b74SViresh Kumar 		dev_err(stmpe->dev, "failed to read reg %#x: %d\n", reg, ret);
4127e34995SRabin Vincent 
4227e34995SRabin Vincent 	dev_vdbg(stmpe->dev, "rd: reg %#x => data %#x\n", reg, ret);
4327e34995SRabin Vincent 
4427e34995SRabin Vincent 	return ret;
4527e34995SRabin Vincent }
4627e34995SRabin Vincent 
4727e34995SRabin Vincent static int __stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val)
4827e34995SRabin Vincent {
4927e34995SRabin Vincent 	int ret;
5027e34995SRabin Vincent 
5127e34995SRabin Vincent 	dev_vdbg(stmpe->dev, "wr: reg %#x <= %#x\n", reg, val);
5227e34995SRabin Vincent 
531a6e4b74SViresh Kumar 	ret = stmpe->ci->write_byte(stmpe, reg, val);
5427e34995SRabin Vincent 	if (ret < 0)
551a6e4b74SViresh Kumar 		dev_err(stmpe->dev, "failed to write reg %#x: %d\n", reg, ret);
5627e34995SRabin Vincent 
5727e34995SRabin Vincent 	return ret;
5827e34995SRabin Vincent }
5927e34995SRabin Vincent 
6027e34995SRabin Vincent static int __stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val)
6127e34995SRabin Vincent {
6227e34995SRabin Vincent 	int ret;
6327e34995SRabin Vincent 
6427e34995SRabin Vincent 	ret = __stmpe_reg_read(stmpe, reg);
6527e34995SRabin Vincent 	if (ret < 0)
6627e34995SRabin Vincent 		return ret;
6727e34995SRabin Vincent 
6827e34995SRabin Vincent 	ret &= ~mask;
6927e34995SRabin Vincent 	ret |= val;
7027e34995SRabin Vincent 
7127e34995SRabin Vincent 	return __stmpe_reg_write(stmpe, reg, ret);
7227e34995SRabin Vincent }
7327e34995SRabin Vincent 
7427e34995SRabin Vincent static int __stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length,
7527e34995SRabin Vincent 			      u8 *values)
7627e34995SRabin Vincent {
7727e34995SRabin Vincent 	int ret;
7827e34995SRabin Vincent 
791a6e4b74SViresh Kumar 	ret = stmpe->ci->read_block(stmpe, reg, length, values);
8027e34995SRabin Vincent 	if (ret < 0)
811a6e4b74SViresh Kumar 		dev_err(stmpe->dev, "failed to read regs %#x: %d\n", reg, ret);
8227e34995SRabin Vincent 
8327e34995SRabin Vincent 	dev_vdbg(stmpe->dev, "rd: reg %#x (%d) => ret %#x\n", reg, length, ret);
8427e34995SRabin Vincent 	stmpe_dump_bytes("stmpe rd: ", values, length);
8527e34995SRabin Vincent 
8627e34995SRabin Vincent 	return ret;
8727e34995SRabin Vincent }
8827e34995SRabin Vincent 
8927e34995SRabin Vincent static int __stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length,
9027e34995SRabin Vincent 			const u8 *values)
9127e34995SRabin Vincent {
9227e34995SRabin Vincent 	int ret;
9327e34995SRabin Vincent 
9427e34995SRabin Vincent 	dev_vdbg(stmpe->dev, "wr: regs %#x (%d)\n", reg, length);
9527e34995SRabin Vincent 	stmpe_dump_bytes("stmpe wr: ", values, length);
9627e34995SRabin Vincent 
971a6e4b74SViresh Kumar 	ret = stmpe->ci->write_block(stmpe, reg, length, values);
9827e34995SRabin Vincent 	if (ret < 0)
991a6e4b74SViresh Kumar 		dev_err(stmpe->dev, "failed to write regs %#x: %d\n", reg, ret);
10027e34995SRabin Vincent 
10127e34995SRabin Vincent 	return ret;
10227e34995SRabin Vincent }
10327e34995SRabin Vincent 
10427e34995SRabin Vincent /**
10527e34995SRabin Vincent  * stmpe_enable - enable blocks on an STMPE device
10627e34995SRabin Vincent  * @stmpe:	Device to work on
10727e34995SRabin Vincent  * @blocks:	Mask of blocks (enum stmpe_block values) to enable
10827e34995SRabin Vincent  */
10927e34995SRabin Vincent int stmpe_enable(struct stmpe *stmpe, unsigned int blocks)
11027e34995SRabin Vincent {
11127e34995SRabin Vincent 	int ret;
11227e34995SRabin Vincent 
11327e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
11427e34995SRabin Vincent 	ret = __stmpe_enable(stmpe, blocks);
11527e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
11627e34995SRabin Vincent 
11727e34995SRabin Vincent 	return ret;
11827e34995SRabin Vincent }
11927e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_enable);
12027e34995SRabin Vincent 
12127e34995SRabin Vincent /**
12227e34995SRabin Vincent  * stmpe_disable - disable blocks on an STMPE device
12327e34995SRabin Vincent  * @stmpe:	Device to work on
12427e34995SRabin Vincent  * @blocks:	Mask of blocks (enum stmpe_block values) to enable
12527e34995SRabin Vincent  */
12627e34995SRabin Vincent int stmpe_disable(struct stmpe *stmpe, unsigned int blocks)
12727e34995SRabin Vincent {
12827e34995SRabin Vincent 	int ret;
12927e34995SRabin Vincent 
13027e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
13127e34995SRabin Vincent 	ret = __stmpe_disable(stmpe, blocks);
13227e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
13327e34995SRabin Vincent 
13427e34995SRabin Vincent 	return ret;
13527e34995SRabin Vincent }
13627e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_disable);
13727e34995SRabin Vincent 
13827e34995SRabin Vincent /**
13927e34995SRabin Vincent  * stmpe_reg_read() - read a single STMPE register
14027e34995SRabin Vincent  * @stmpe:	Device to read from
14127e34995SRabin Vincent  * @reg:	Register to read
14227e34995SRabin Vincent  */
14327e34995SRabin Vincent int stmpe_reg_read(struct stmpe *stmpe, u8 reg)
14427e34995SRabin Vincent {
14527e34995SRabin Vincent 	int ret;
14627e34995SRabin Vincent 
14727e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
14827e34995SRabin Vincent 	ret = __stmpe_reg_read(stmpe, reg);
14927e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
15027e34995SRabin Vincent 
15127e34995SRabin Vincent 	return ret;
15227e34995SRabin Vincent }
15327e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_reg_read);
15427e34995SRabin Vincent 
15527e34995SRabin Vincent /**
15627e34995SRabin Vincent  * stmpe_reg_write() - write a single STMPE register
15727e34995SRabin Vincent  * @stmpe:	Device to write to
15827e34995SRabin Vincent  * @reg:	Register to write
15927e34995SRabin Vincent  * @val:	Value to write
16027e34995SRabin Vincent  */
16127e34995SRabin Vincent int stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val)
16227e34995SRabin Vincent {
16327e34995SRabin Vincent 	int ret;
16427e34995SRabin Vincent 
16527e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
16627e34995SRabin Vincent 	ret = __stmpe_reg_write(stmpe, reg, val);
16727e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
16827e34995SRabin Vincent 
16927e34995SRabin Vincent 	return ret;
17027e34995SRabin Vincent }
17127e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_reg_write);
17227e34995SRabin Vincent 
17327e34995SRabin Vincent /**
17427e34995SRabin Vincent  * stmpe_set_bits() - set the value of a bitfield in a STMPE register
17527e34995SRabin Vincent  * @stmpe:	Device to write to
17627e34995SRabin Vincent  * @reg:	Register to write
17727e34995SRabin Vincent  * @mask:	Mask of bits to set
17827e34995SRabin Vincent  * @val:	Value to set
17927e34995SRabin Vincent  */
18027e34995SRabin Vincent int stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val)
18127e34995SRabin Vincent {
18227e34995SRabin Vincent 	int ret;
18327e34995SRabin Vincent 
18427e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
18527e34995SRabin Vincent 	ret = __stmpe_set_bits(stmpe, reg, mask, val);
18627e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
18727e34995SRabin Vincent 
18827e34995SRabin Vincent 	return ret;
18927e34995SRabin Vincent }
19027e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_set_bits);
19127e34995SRabin Vincent 
19227e34995SRabin Vincent /**
19327e34995SRabin Vincent  * stmpe_block_read() - read multiple STMPE registers
19427e34995SRabin Vincent  * @stmpe:	Device to read from
19527e34995SRabin Vincent  * @reg:	First register
19627e34995SRabin Vincent  * @length:	Number of registers
19727e34995SRabin Vincent  * @values:	Buffer to write to
19827e34995SRabin Vincent  */
19927e34995SRabin Vincent int stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values)
20027e34995SRabin Vincent {
20127e34995SRabin Vincent 	int ret;
20227e34995SRabin Vincent 
20327e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
20427e34995SRabin Vincent 	ret = __stmpe_block_read(stmpe, reg, length, values);
20527e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
20627e34995SRabin Vincent 
20727e34995SRabin Vincent 	return ret;
20827e34995SRabin Vincent }
20927e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_block_read);
21027e34995SRabin Vincent 
21127e34995SRabin Vincent /**
21227e34995SRabin Vincent  * stmpe_block_write() - write multiple STMPE registers
21327e34995SRabin Vincent  * @stmpe:	Device to write to
21427e34995SRabin Vincent  * @reg:	First register
21527e34995SRabin Vincent  * @length:	Number of registers
21627e34995SRabin Vincent  * @values:	Values to write
21727e34995SRabin Vincent  */
21827e34995SRabin Vincent int stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length,
21927e34995SRabin Vincent 		      const u8 *values)
22027e34995SRabin Vincent {
22127e34995SRabin Vincent 	int ret;
22227e34995SRabin Vincent 
22327e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
22427e34995SRabin Vincent 	ret = __stmpe_block_write(stmpe, reg, length, values);
22527e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
22627e34995SRabin Vincent 
22727e34995SRabin Vincent 	return ret;
22827e34995SRabin Vincent }
22927e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_block_write);
23027e34995SRabin Vincent 
23127e34995SRabin Vincent /**
2324dcaa6b6SOm Prakash  * stmpe_set_altfunc()- set the alternate function for STMPE pins
23327e34995SRabin Vincent  * @stmpe:	Device to configure
23427e34995SRabin Vincent  * @pins:	Bitmask of pins to affect
23527e34995SRabin Vincent  * @block:	block to enable alternate functions for
23627e34995SRabin Vincent  *
23727e34995SRabin Vincent  * @pins is assumed to have a bit set for each of the bits whose alternate
23827e34995SRabin Vincent  * function is to be changed, numbered according to the GPIOXY numbers.
23927e34995SRabin Vincent  *
24027e34995SRabin Vincent  * If the GPIO module is not enabled, this function automatically enables it in
24127e34995SRabin Vincent  * order to perform the change.
24227e34995SRabin Vincent  */
24327e34995SRabin Vincent int stmpe_set_altfunc(struct stmpe *stmpe, u32 pins, enum stmpe_block block)
24427e34995SRabin Vincent {
24527e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
24627e34995SRabin Vincent 	u8 regaddr = stmpe->regs[STMPE_IDX_GPAFR_U_MSB];
24727e34995SRabin Vincent 	int af_bits = variant->af_bits;
24827e34995SRabin Vincent 	int numregs = DIV_ROUND_UP(stmpe->num_gpios * af_bits, 8);
24927e34995SRabin Vincent 	int mask = (1 << af_bits) - 1;
25027e34995SRabin Vincent 	u8 regs[numregs];
2517f7f4ea1SViresh Kumar 	int af, afperreg, ret;
25227e34995SRabin Vincent 
2537f7f4ea1SViresh Kumar 	if (!variant->get_altfunc)
2547f7f4ea1SViresh Kumar 		return 0;
2557f7f4ea1SViresh Kumar 
2567f7f4ea1SViresh Kumar 	afperreg = 8 / af_bits;
25727e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
25827e34995SRabin Vincent 
25927e34995SRabin Vincent 	ret = __stmpe_enable(stmpe, STMPE_BLOCK_GPIO);
26027e34995SRabin Vincent 	if (ret < 0)
26127e34995SRabin Vincent 		goto out;
26227e34995SRabin Vincent 
26327e34995SRabin Vincent 	ret = __stmpe_block_read(stmpe, regaddr, numregs, regs);
26427e34995SRabin Vincent 	if (ret < 0)
26527e34995SRabin Vincent 		goto out;
26627e34995SRabin Vincent 
26727e34995SRabin Vincent 	af = variant->get_altfunc(stmpe, block);
26827e34995SRabin Vincent 
26927e34995SRabin Vincent 	while (pins) {
27027e34995SRabin Vincent 		int pin = __ffs(pins);
27127e34995SRabin Vincent 		int regoffset = numregs - (pin / afperreg) - 1;
27227e34995SRabin Vincent 		int pos = (pin % afperreg) * (8 / afperreg);
27327e34995SRabin Vincent 
27427e34995SRabin Vincent 		regs[regoffset] &= ~(mask << pos);
27527e34995SRabin Vincent 		regs[regoffset] |= af << pos;
27627e34995SRabin Vincent 
27727e34995SRabin Vincent 		pins &= ~(1 << pin);
27827e34995SRabin Vincent 	}
27927e34995SRabin Vincent 
28027e34995SRabin Vincent 	ret = __stmpe_block_write(stmpe, regaddr, numregs, regs);
28127e34995SRabin Vincent 
28227e34995SRabin Vincent out:
28327e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
28427e34995SRabin Vincent 	return ret;
28527e34995SRabin Vincent }
28627e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_set_altfunc);
28727e34995SRabin Vincent 
28827e34995SRabin Vincent /*
28927e34995SRabin Vincent  * GPIO (all variants)
29027e34995SRabin Vincent  */
29127e34995SRabin Vincent 
29227e34995SRabin Vincent static struct resource stmpe_gpio_resources[] = {
29327e34995SRabin Vincent 	/* Start and end filled dynamically */
29427e34995SRabin Vincent 	{
29527e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
29627e34995SRabin Vincent 	},
29727e34995SRabin Vincent };
29827e34995SRabin Vincent 
29927e34995SRabin Vincent static struct mfd_cell stmpe_gpio_cell = {
30027e34995SRabin Vincent 	.name		= "stmpe-gpio",
30127e34995SRabin Vincent 	.resources	= stmpe_gpio_resources,
30227e34995SRabin Vincent 	.num_resources	= ARRAY_SIZE(stmpe_gpio_resources),
30327e34995SRabin Vincent };
30427e34995SRabin Vincent 
305e31f9b82SChris Blair static struct mfd_cell stmpe_gpio_cell_noirq = {
306e31f9b82SChris Blair 	.name		= "stmpe-gpio",
307e31f9b82SChris Blair 	/* gpio cell resources consist of an irq only so no resources here */
308e31f9b82SChris Blair };
309e31f9b82SChris Blair 
31027e34995SRabin Vincent /*
31127e34995SRabin Vincent  * Keypad (1601, 2401, 2403)
31227e34995SRabin Vincent  */
31327e34995SRabin Vincent 
31427e34995SRabin Vincent static struct resource stmpe_keypad_resources[] = {
31527e34995SRabin Vincent 	{
31627e34995SRabin Vincent 		.name	= "KEYPAD",
31727e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
31827e34995SRabin Vincent 	},
31927e34995SRabin Vincent 	{
32027e34995SRabin Vincent 		.name	= "KEYPAD_OVER",
32127e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
32227e34995SRabin Vincent 	},
32327e34995SRabin Vincent };
32427e34995SRabin Vincent 
32527e34995SRabin Vincent static struct mfd_cell stmpe_keypad_cell = {
32627e34995SRabin Vincent 	.name		= "stmpe-keypad",
32727e34995SRabin Vincent 	.resources	= stmpe_keypad_resources,
32827e34995SRabin Vincent 	.num_resources	= ARRAY_SIZE(stmpe_keypad_resources),
32927e34995SRabin Vincent };
33027e34995SRabin Vincent 
33127e34995SRabin Vincent /*
3327f7f4ea1SViresh Kumar  * STMPE801
3337f7f4ea1SViresh Kumar  */
3347f7f4ea1SViresh Kumar static const u8 stmpe801_regs[] = {
3357f7f4ea1SViresh Kumar 	[STMPE_IDX_CHIP_ID]	= STMPE801_REG_CHIP_ID,
3367f7f4ea1SViresh Kumar 	[STMPE_IDX_ICR_LSB]	= STMPE801_REG_SYS_CTRL,
3377f7f4ea1SViresh Kumar 	[STMPE_IDX_GPMR_LSB]	= STMPE801_REG_GPIO_MP_STA,
3387f7f4ea1SViresh Kumar 	[STMPE_IDX_GPSR_LSB]	= STMPE801_REG_GPIO_SET_PIN,
3397f7f4ea1SViresh Kumar 	[STMPE_IDX_GPCR_LSB]	= STMPE801_REG_GPIO_SET_PIN,
3407f7f4ea1SViresh Kumar 	[STMPE_IDX_GPDR_LSB]	= STMPE801_REG_GPIO_DIR,
3417f7f4ea1SViresh Kumar 	[STMPE_IDX_IEGPIOR_LSB] = STMPE801_REG_GPIO_INT_EN,
3427f7f4ea1SViresh Kumar 	[STMPE_IDX_ISGPIOR_MSB] = STMPE801_REG_GPIO_INT_STA,
3437f7f4ea1SViresh Kumar 
3447f7f4ea1SViresh Kumar };
3457f7f4ea1SViresh Kumar 
3467f7f4ea1SViresh Kumar static struct stmpe_variant_block stmpe801_blocks[] = {
3477f7f4ea1SViresh Kumar 	{
3487f7f4ea1SViresh Kumar 		.cell	= &stmpe_gpio_cell,
3497f7f4ea1SViresh Kumar 		.irq	= 0,
3507f7f4ea1SViresh Kumar 		.block	= STMPE_BLOCK_GPIO,
3517f7f4ea1SViresh Kumar 	},
3527f7f4ea1SViresh Kumar };
3537f7f4ea1SViresh Kumar 
354e31f9b82SChris Blair static struct stmpe_variant_block stmpe801_blocks_noirq[] = {
355e31f9b82SChris Blair 	{
356e31f9b82SChris Blair 		.cell	= &stmpe_gpio_cell_noirq,
357e31f9b82SChris Blair 		.block	= STMPE_BLOCK_GPIO,
358e31f9b82SChris Blair 	},
359e31f9b82SChris Blair };
360e31f9b82SChris Blair 
3617f7f4ea1SViresh Kumar static int stmpe801_enable(struct stmpe *stmpe, unsigned int blocks,
3627f7f4ea1SViresh Kumar 			   bool enable)
3637f7f4ea1SViresh Kumar {
3647f7f4ea1SViresh Kumar 	if (blocks & STMPE_BLOCK_GPIO)
3657f7f4ea1SViresh Kumar 		return 0;
3667f7f4ea1SViresh Kumar 	else
3677f7f4ea1SViresh Kumar 		return -EINVAL;
3687f7f4ea1SViresh Kumar }
3697f7f4ea1SViresh Kumar 
3707f7f4ea1SViresh Kumar static struct stmpe_variant_info stmpe801 = {
3717f7f4ea1SViresh Kumar 	.name		= "stmpe801",
3727f7f4ea1SViresh Kumar 	.id_val		= STMPE801_ID,
3737f7f4ea1SViresh Kumar 	.id_mask	= 0xffff,
3747f7f4ea1SViresh Kumar 	.num_gpios	= 8,
3757f7f4ea1SViresh Kumar 	.regs		= stmpe801_regs,
3767f7f4ea1SViresh Kumar 	.blocks		= stmpe801_blocks,
3777f7f4ea1SViresh Kumar 	.num_blocks	= ARRAY_SIZE(stmpe801_blocks),
3787f7f4ea1SViresh Kumar 	.num_irqs	= STMPE801_NR_INTERNAL_IRQS,
3797f7f4ea1SViresh Kumar 	.enable		= stmpe801_enable,
3807f7f4ea1SViresh Kumar };
3817f7f4ea1SViresh Kumar 
382e31f9b82SChris Blair static struct stmpe_variant_info stmpe801_noirq = {
383e31f9b82SChris Blair 	.name		= "stmpe801",
384e31f9b82SChris Blair 	.id_val		= STMPE801_ID,
385e31f9b82SChris Blair 	.id_mask	= 0xffff,
386e31f9b82SChris Blair 	.num_gpios	= 8,
387e31f9b82SChris Blair 	.regs		= stmpe801_regs,
388e31f9b82SChris Blair 	.blocks		= stmpe801_blocks_noirq,
389e31f9b82SChris Blair 	.num_blocks	= ARRAY_SIZE(stmpe801_blocks_noirq),
390e31f9b82SChris Blair 	.enable		= stmpe801_enable,
391e31f9b82SChris Blair };
392e31f9b82SChris Blair 
3937f7f4ea1SViresh Kumar /*
3941cda2394SViresh Kumar  * Touchscreen (STMPE811 or STMPE610)
39527e34995SRabin Vincent  */
39627e34995SRabin Vincent 
39727e34995SRabin Vincent static struct resource stmpe_ts_resources[] = {
39827e34995SRabin Vincent 	{
39927e34995SRabin Vincent 		.name	= "TOUCH_DET",
40027e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
40127e34995SRabin Vincent 	},
40227e34995SRabin Vincent 	{
40327e34995SRabin Vincent 		.name	= "FIFO_TH",
40427e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
40527e34995SRabin Vincent 	},
40627e34995SRabin Vincent };
40727e34995SRabin Vincent 
40827e34995SRabin Vincent static struct mfd_cell stmpe_ts_cell = {
40927e34995SRabin Vincent 	.name		= "stmpe-ts",
41027e34995SRabin Vincent 	.resources	= stmpe_ts_resources,
41127e34995SRabin Vincent 	.num_resources	= ARRAY_SIZE(stmpe_ts_resources),
41227e34995SRabin Vincent };
41327e34995SRabin Vincent 
41427e34995SRabin Vincent /*
4151cda2394SViresh Kumar  * STMPE811 or STMPE610
41627e34995SRabin Vincent  */
41727e34995SRabin Vincent 
41827e34995SRabin Vincent static const u8 stmpe811_regs[] = {
41927e34995SRabin Vincent 	[STMPE_IDX_CHIP_ID]	= STMPE811_REG_CHIP_ID,
42027e34995SRabin Vincent 	[STMPE_IDX_ICR_LSB]	= STMPE811_REG_INT_CTRL,
42127e34995SRabin Vincent 	[STMPE_IDX_IER_LSB]	= STMPE811_REG_INT_EN,
42227e34995SRabin Vincent 	[STMPE_IDX_ISR_MSB]	= STMPE811_REG_INT_STA,
42327e34995SRabin Vincent 	[STMPE_IDX_GPMR_LSB]	= STMPE811_REG_GPIO_MP_STA,
42427e34995SRabin Vincent 	[STMPE_IDX_GPSR_LSB]	= STMPE811_REG_GPIO_SET_PIN,
42527e34995SRabin Vincent 	[STMPE_IDX_GPCR_LSB]	= STMPE811_REG_GPIO_CLR_PIN,
42627e34995SRabin Vincent 	[STMPE_IDX_GPDR_LSB]	= STMPE811_REG_GPIO_DIR,
42727e34995SRabin Vincent 	[STMPE_IDX_GPRER_LSB]	= STMPE811_REG_GPIO_RE,
42827e34995SRabin Vincent 	[STMPE_IDX_GPFER_LSB]	= STMPE811_REG_GPIO_FE,
42927e34995SRabin Vincent 	[STMPE_IDX_GPAFR_U_MSB]	= STMPE811_REG_GPIO_AF,
43027e34995SRabin Vincent 	[STMPE_IDX_IEGPIOR_LSB]	= STMPE811_REG_GPIO_INT_EN,
43127e34995SRabin Vincent 	[STMPE_IDX_ISGPIOR_MSB]	= STMPE811_REG_GPIO_INT_STA,
43227e34995SRabin Vincent 	[STMPE_IDX_GPEDR_MSB]	= STMPE811_REG_GPIO_ED,
43327e34995SRabin Vincent };
43427e34995SRabin Vincent 
43527e34995SRabin Vincent static struct stmpe_variant_block stmpe811_blocks[] = {
43627e34995SRabin Vincent 	{
43727e34995SRabin Vincent 		.cell	= &stmpe_gpio_cell,
43827e34995SRabin Vincent 		.irq	= STMPE811_IRQ_GPIOC,
43927e34995SRabin Vincent 		.block	= STMPE_BLOCK_GPIO,
44027e34995SRabin Vincent 	},
44127e34995SRabin Vincent 	{
44227e34995SRabin Vincent 		.cell	= &stmpe_ts_cell,
44327e34995SRabin Vincent 		.irq	= STMPE811_IRQ_TOUCH_DET,
44427e34995SRabin Vincent 		.block	= STMPE_BLOCK_TOUCHSCREEN,
44527e34995SRabin Vincent 	},
44627e34995SRabin Vincent };
44727e34995SRabin Vincent 
44827e34995SRabin Vincent static int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks,
44927e34995SRabin Vincent 			   bool enable)
45027e34995SRabin Vincent {
45127e34995SRabin Vincent 	unsigned int mask = 0;
45227e34995SRabin Vincent 
45327e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_GPIO)
45427e34995SRabin Vincent 		mask |= STMPE811_SYS_CTRL2_GPIO_OFF;
45527e34995SRabin Vincent 
45627e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_ADC)
45727e34995SRabin Vincent 		mask |= STMPE811_SYS_CTRL2_ADC_OFF;
45827e34995SRabin Vincent 
45927e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_TOUCHSCREEN)
46027e34995SRabin Vincent 		mask |= STMPE811_SYS_CTRL2_TSC_OFF;
46127e34995SRabin Vincent 
46227e34995SRabin Vincent 	return __stmpe_set_bits(stmpe, STMPE811_REG_SYS_CTRL2, mask,
46327e34995SRabin Vincent 				enable ? 0 : mask);
46427e34995SRabin Vincent }
46527e34995SRabin Vincent 
46627e34995SRabin Vincent static int stmpe811_get_altfunc(struct stmpe *stmpe, enum stmpe_block block)
46727e34995SRabin Vincent {
46827e34995SRabin Vincent 	/* 0 for touchscreen, 1 for GPIO */
46927e34995SRabin Vincent 	return block != STMPE_BLOCK_TOUCHSCREEN;
47027e34995SRabin Vincent }
47127e34995SRabin Vincent 
47227e34995SRabin Vincent static struct stmpe_variant_info stmpe811 = {
47327e34995SRabin Vincent 	.name		= "stmpe811",
47427e34995SRabin Vincent 	.id_val		= 0x0811,
47527e34995SRabin Vincent 	.id_mask	= 0xffff,
47627e34995SRabin Vincent 	.num_gpios	= 8,
47727e34995SRabin Vincent 	.af_bits	= 1,
47827e34995SRabin Vincent 	.regs		= stmpe811_regs,
47927e34995SRabin Vincent 	.blocks		= stmpe811_blocks,
48027e34995SRabin Vincent 	.num_blocks	= ARRAY_SIZE(stmpe811_blocks),
48127e34995SRabin Vincent 	.num_irqs	= STMPE811_NR_INTERNAL_IRQS,
48227e34995SRabin Vincent 	.enable		= stmpe811_enable,
48327e34995SRabin Vincent 	.get_altfunc	= stmpe811_get_altfunc,
48427e34995SRabin Vincent };
48527e34995SRabin Vincent 
4861cda2394SViresh Kumar /* Similar to 811, except number of gpios */
4871cda2394SViresh Kumar static struct stmpe_variant_info stmpe610 = {
4881cda2394SViresh Kumar 	.name		= "stmpe610",
4891cda2394SViresh Kumar 	.id_val		= 0x0811,
4901cda2394SViresh Kumar 	.id_mask	= 0xffff,
4911cda2394SViresh Kumar 	.num_gpios	= 6,
4921cda2394SViresh Kumar 	.af_bits	= 1,
4931cda2394SViresh Kumar 	.regs		= stmpe811_regs,
4941cda2394SViresh Kumar 	.blocks		= stmpe811_blocks,
4951cda2394SViresh Kumar 	.num_blocks	= ARRAY_SIZE(stmpe811_blocks),
4961cda2394SViresh Kumar 	.num_irqs	= STMPE811_NR_INTERNAL_IRQS,
4971cda2394SViresh Kumar 	.enable		= stmpe811_enable,
4981cda2394SViresh Kumar 	.get_altfunc	= stmpe811_get_altfunc,
4991cda2394SViresh Kumar };
5001cda2394SViresh Kumar 
50127e34995SRabin Vincent /*
50227e34995SRabin Vincent  * STMPE1601
50327e34995SRabin Vincent  */
50427e34995SRabin Vincent 
50527e34995SRabin Vincent static const u8 stmpe1601_regs[] = {
50627e34995SRabin Vincent 	[STMPE_IDX_CHIP_ID]	= STMPE1601_REG_CHIP_ID,
50727e34995SRabin Vincent 	[STMPE_IDX_ICR_LSB]	= STMPE1601_REG_ICR_LSB,
50827e34995SRabin Vincent 	[STMPE_IDX_IER_LSB]	= STMPE1601_REG_IER_LSB,
50927e34995SRabin Vincent 	[STMPE_IDX_ISR_MSB]	= STMPE1601_REG_ISR_MSB,
51027e34995SRabin Vincent 	[STMPE_IDX_GPMR_LSB]	= STMPE1601_REG_GPIO_MP_LSB,
51127e34995SRabin Vincent 	[STMPE_IDX_GPSR_LSB]	= STMPE1601_REG_GPIO_SET_LSB,
51227e34995SRabin Vincent 	[STMPE_IDX_GPCR_LSB]	= STMPE1601_REG_GPIO_CLR_LSB,
51327e34995SRabin Vincent 	[STMPE_IDX_GPDR_LSB]	= STMPE1601_REG_GPIO_SET_DIR_LSB,
51427e34995SRabin Vincent 	[STMPE_IDX_GPRER_LSB]	= STMPE1601_REG_GPIO_RE_LSB,
51527e34995SRabin Vincent 	[STMPE_IDX_GPFER_LSB]	= STMPE1601_REG_GPIO_FE_LSB,
51627e34995SRabin Vincent 	[STMPE_IDX_GPAFR_U_MSB]	= STMPE1601_REG_GPIO_AF_U_MSB,
51727e34995SRabin Vincent 	[STMPE_IDX_IEGPIOR_LSB]	= STMPE1601_REG_INT_EN_GPIO_MASK_LSB,
51827e34995SRabin Vincent 	[STMPE_IDX_ISGPIOR_MSB]	= STMPE1601_REG_INT_STA_GPIO_MSB,
51927e34995SRabin Vincent 	[STMPE_IDX_GPEDR_MSB]	= STMPE1601_REG_GPIO_ED_MSB,
52027e34995SRabin Vincent };
52127e34995SRabin Vincent 
52227e34995SRabin Vincent static struct stmpe_variant_block stmpe1601_blocks[] = {
52327e34995SRabin Vincent 	{
52427e34995SRabin Vincent 		.cell	= &stmpe_gpio_cell,
5255204e51dSLee Jones 		.irq	= STMPE1601_IRQ_GPIOC,
52627e34995SRabin Vincent 		.block	= STMPE_BLOCK_GPIO,
52727e34995SRabin Vincent 	},
52827e34995SRabin Vincent 	{
52927e34995SRabin Vincent 		.cell	= &stmpe_keypad_cell,
5305204e51dSLee Jones 		.irq	= STMPE1601_IRQ_KEYPAD,
53127e34995SRabin Vincent 		.block	= STMPE_BLOCK_KEYPAD,
53227e34995SRabin Vincent 	},
53327e34995SRabin Vincent };
53427e34995SRabin Vincent 
5355981f4e6SSundar R Iyer /* supported autosleep timeout delay (in msecs) */
5365981f4e6SSundar R Iyer static const int stmpe_autosleep_delay[] = {
5375981f4e6SSundar R Iyer 	4, 16, 32, 64, 128, 256, 512, 1024,
5385981f4e6SSundar R Iyer };
5395981f4e6SSundar R Iyer 
5405981f4e6SSundar R Iyer static int stmpe_round_timeout(int timeout)
5415981f4e6SSundar R Iyer {
5425981f4e6SSundar R Iyer 	int i;
5435981f4e6SSundar R Iyer 
5445981f4e6SSundar R Iyer 	for (i = 0; i < ARRAY_SIZE(stmpe_autosleep_delay); i++) {
5455981f4e6SSundar R Iyer 		if (stmpe_autosleep_delay[i] >= timeout)
5465981f4e6SSundar R Iyer 			return i;
5475981f4e6SSundar R Iyer 	}
5485981f4e6SSundar R Iyer 
5495981f4e6SSundar R Iyer 	/*
5505981f4e6SSundar R Iyer 	 * requests for delays longer than supported should not return the
5515981f4e6SSundar R Iyer 	 * longest supported delay
5525981f4e6SSundar R Iyer 	 */
5535981f4e6SSundar R Iyer 	return -EINVAL;
5545981f4e6SSundar R Iyer }
5555981f4e6SSundar R Iyer 
5565981f4e6SSundar R Iyer static int stmpe_autosleep(struct stmpe *stmpe, int autosleep_timeout)
5575981f4e6SSundar R Iyer {
5585981f4e6SSundar R Iyer 	int ret;
5595981f4e6SSundar R Iyer 
5605981f4e6SSundar R Iyer 	if (!stmpe->variant->enable_autosleep)
5615981f4e6SSundar R Iyer 		return -ENOSYS;
5625981f4e6SSundar R Iyer 
5635981f4e6SSundar R Iyer 	mutex_lock(&stmpe->lock);
5645981f4e6SSundar R Iyer 	ret = stmpe->variant->enable_autosleep(stmpe, autosleep_timeout);
5655981f4e6SSundar R Iyer 	mutex_unlock(&stmpe->lock);
5665981f4e6SSundar R Iyer 
5675981f4e6SSundar R Iyer 	return ret;
5685981f4e6SSundar R Iyer }
5695981f4e6SSundar R Iyer 
5705981f4e6SSundar R Iyer /*
5715981f4e6SSundar R Iyer  * Both stmpe 1601/2403 support same layout for autosleep
5725981f4e6SSundar R Iyer  */
5735981f4e6SSundar R Iyer static int stmpe1601_autosleep(struct stmpe *stmpe,
5745981f4e6SSundar R Iyer 		int autosleep_timeout)
5755981f4e6SSundar R Iyer {
5765981f4e6SSundar R Iyer 	int ret, timeout;
5775981f4e6SSundar R Iyer 
5785981f4e6SSundar R Iyer 	/* choose the best available timeout */
5795981f4e6SSundar R Iyer 	timeout = stmpe_round_timeout(autosleep_timeout);
5805981f4e6SSundar R Iyer 	if (timeout < 0) {
5815981f4e6SSundar R Iyer 		dev_err(stmpe->dev, "invalid timeout\n");
5825981f4e6SSundar R Iyer 		return timeout;
5835981f4e6SSundar R Iyer 	}
5845981f4e6SSundar R Iyer 
5855981f4e6SSundar R Iyer 	ret = __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL2,
5865981f4e6SSundar R Iyer 			STMPE1601_AUTOSLEEP_TIMEOUT_MASK,
5875981f4e6SSundar R Iyer 			timeout);
5885981f4e6SSundar R Iyer 	if (ret < 0)
5895981f4e6SSundar R Iyer 		return ret;
5905981f4e6SSundar R Iyer 
5915981f4e6SSundar R Iyer 	return __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL2,
5925981f4e6SSundar R Iyer 			STPME1601_AUTOSLEEP_ENABLE,
5935981f4e6SSundar R Iyer 			STPME1601_AUTOSLEEP_ENABLE);
5945981f4e6SSundar R Iyer }
5955981f4e6SSundar R Iyer 
59627e34995SRabin Vincent static int stmpe1601_enable(struct stmpe *stmpe, unsigned int blocks,
59727e34995SRabin Vincent 			    bool enable)
59827e34995SRabin Vincent {
59927e34995SRabin Vincent 	unsigned int mask = 0;
60027e34995SRabin Vincent 
60127e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_GPIO)
60227e34995SRabin Vincent 		mask |= STMPE1601_SYS_CTRL_ENABLE_GPIO;
60327e34995SRabin Vincent 
60427e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_KEYPAD)
60527e34995SRabin Vincent 		mask |= STMPE1601_SYS_CTRL_ENABLE_KPC;
60627e34995SRabin Vincent 
60727e34995SRabin Vincent 	return __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL, mask,
60827e34995SRabin Vincent 				enable ? mask : 0);
60927e34995SRabin Vincent }
61027e34995SRabin Vincent 
61127e34995SRabin Vincent static int stmpe1601_get_altfunc(struct stmpe *stmpe, enum stmpe_block block)
61227e34995SRabin Vincent {
61327e34995SRabin Vincent 	switch (block) {
61427e34995SRabin Vincent 	case STMPE_BLOCK_PWM:
61527e34995SRabin Vincent 		return 2;
61627e34995SRabin Vincent 
61727e34995SRabin Vincent 	case STMPE_BLOCK_KEYPAD:
61827e34995SRabin Vincent 		return 1;
61927e34995SRabin Vincent 
62027e34995SRabin Vincent 	case STMPE_BLOCK_GPIO:
62127e34995SRabin Vincent 	default:
62227e34995SRabin Vincent 		return 0;
62327e34995SRabin Vincent 	}
62427e34995SRabin Vincent }
62527e34995SRabin Vincent 
62627e34995SRabin Vincent static struct stmpe_variant_info stmpe1601 = {
62727e34995SRabin Vincent 	.name		= "stmpe1601",
62827e34995SRabin Vincent 	.id_val		= 0x0210,
62927e34995SRabin Vincent 	.id_mask	= 0xfff0,	/* at least 0x0210 and 0x0212 */
63027e34995SRabin Vincent 	.num_gpios	= 16,
63127e34995SRabin Vincent 	.af_bits	= 2,
63227e34995SRabin Vincent 	.regs		= stmpe1601_regs,
63327e34995SRabin Vincent 	.blocks		= stmpe1601_blocks,
63427e34995SRabin Vincent 	.num_blocks	= ARRAY_SIZE(stmpe1601_blocks),
63527e34995SRabin Vincent 	.num_irqs	= STMPE1601_NR_INTERNAL_IRQS,
63627e34995SRabin Vincent 	.enable		= stmpe1601_enable,
63727e34995SRabin Vincent 	.get_altfunc	= stmpe1601_get_altfunc,
6385981f4e6SSundar R Iyer 	.enable_autosleep	= stmpe1601_autosleep,
63927e34995SRabin Vincent };
64027e34995SRabin Vincent 
64127e34995SRabin Vincent /*
64227e34995SRabin Vincent  * STMPE24XX
64327e34995SRabin Vincent  */
64427e34995SRabin Vincent 
64527e34995SRabin Vincent static const u8 stmpe24xx_regs[] = {
64627e34995SRabin Vincent 	[STMPE_IDX_CHIP_ID]	= STMPE24XX_REG_CHIP_ID,
64727e34995SRabin Vincent 	[STMPE_IDX_ICR_LSB]	= STMPE24XX_REG_ICR_LSB,
64827e34995SRabin Vincent 	[STMPE_IDX_IER_LSB]	= STMPE24XX_REG_IER_LSB,
64927e34995SRabin Vincent 	[STMPE_IDX_ISR_MSB]	= STMPE24XX_REG_ISR_MSB,
65027e34995SRabin Vincent 	[STMPE_IDX_GPMR_LSB]	= STMPE24XX_REG_GPMR_LSB,
65127e34995SRabin Vincent 	[STMPE_IDX_GPSR_LSB]	= STMPE24XX_REG_GPSR_LSB,
65227e34995SRabin Vincent 	[STMPE_IDX_GPCR_LSB]	= STMPE24XX_REG_GPCR_LSB,
65327e34995SRabin Vincent 	[STMPE_IDX_GPDR_LSB]	= STMPE24XX_REG_GPDR_LSB,
65427e34995SRabin Vincent 	[STMPE_IDX_GPRER_LSB]	= STMPE24XX_REG_GPRER_LSB,
65527e34995SRabin Vincent 	[STMPE_IDX_GPFER_LSB]	= STMPE24XX_REG_GPFER_LSB,
65627e34995SRabin Vincent 	[STMPE_IDX_GPAFR_U_MSB]	= STMPE24XX_REG_GPAFR_U_MSB,
65727e34995SRabin Vincent 	[STMPE_IDX_IEGPIOR_LSB]	= STMPE24XX_REG_IEGPIOR_LSB,
65827e34995SRabin Vincent 	[STMPE_IDX_ISGPIOR_MSB]	= STMPE24XX_REG_ISGPIOR_MSB,
65927e34995SRabin Vincent 	[STMPE_IDX_GPEDR_MSB]	= STMPE24XX_REG_GPEDR_MSB,
66027e34995SRabin Vincent };
66127e34995SRabin Vincent 
66227e34995SRabin Vincent static struct stmpe_variant_block stmpe24xx_blocks[] = {
66327e34995SRabin Vincent 	{
66427e34995SRabin Vincent 		.cell	= &stmpe_gpio_cell,
66527e34995SRabin Vincent 		.irq	= STMPE24XX_IRQ_GPIOC,
66627e34995SRabin Vincent 		.block	= STMPE_BLOCK_GPIO,
66727e34995SRabin Vincent 	},
66827e34995SRabin Vincent 	{
66927e34995SRabin Vincent 		.cell	= &stmpe_keypad_cell,
67027e34995SRabin Vincent 		.irq	= STMPE24XX_IRQ_KEYPAD,
67127e34995SRabin Vincent 		.block	= STMPE_BLOCK_KEYPAD,
67227e34995SRabin Vincent 	},
67327e34995SRabin Vincent };
67427e34995SRabin Vincent 
67527e34995SRabin Vincent static int stmpe24xx_enable(struct stmpe *stmpe, unsigned int blocks,
67627e34995SRabin Vincent 			    bool enable)
67727e34995SRabin Vincent {
67827e34995SRabin Vincent 	unsigned int mask = 0;
67927e34995SRabin Vincent 
68027e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_GPIO)
68127e34995SRabin Vincent 		mask |= STMPE24XX_SYS_CTRL_ENABLE_GPIO;
68227e34995SRabin Vincent 
68327e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_KEYPAD)
68427e34995SRabin Vincent 		mask |= STMPE24XX_SYS_CTRL_ENABLE_KPC;
68527e34995SRabin Vincent 
68627e34995SRabin Vincent 	return __stmpe_set_bits(stmpe, STMPE24XX_REG_SYS_CTRL, mask,
68727e34995SRabin Vincent 				enable ? mask : 0);
68827e34995SRabin Vincent }
68927e34995SRabin Vincent 
69027e34995SRabin Vincent static int stmpe24xx_get_altfunc(struct stmpe *stmpe, enum stmpe_block block)
69127e34995SRabin Vincent {
69227e34995SRabin Vincent 	switch (block) {
69327e34995SRabin Vincent 	case STMPE_BLOCK_ROTATOR:
69427e34995SRabin Vincent 		return 2;
69527e34995SRabin Vincent 
69627e34995SRabin Vincent 	case STMPE_BLOCK_KEYPAD:
69727e34995SRabin Vincent 		return 1;
69827e34995SRabin Vincent 
69927e34995SRabin Vincent 	case STMPE_BLOCK_GPIO:
70027e34995SRabin Vincent 	default:
70127e34995SRabin Vincent 		return 0;
70227e34995SRabin Vincent 	}
70327e34995SRabin Vincent }
70427e34995SRabin Vincent 
70527e34995SRabin Vincent static struct stmpe_variant_info stmpe2401 = {
70627e34995SRabin Vincent 	.name		= "stmpe2401",
70727e34995SRabin Vincent 	.id_val		= 0x0101,
70827e34995SRabin Vincent 	.id_mask	= 0xffff,
70927e34995SRabin Vincent 	.num_gpios	= 24,
71027e34995SRabin Vincent 	.af_bits	= 2,
71127e34995SRabin Vincent 	.regs		= stmpe24xx_regs,
71227e34995SRabin Vincent 	.blocks		= stmpe24xx_blocks,
71327e34995SRabin Vincent 	.num_blocks	= ARRAY_SIZE(stmpe24xx_blocks),
71427e34995SRabin Vincent 	.num_irqs	= STMPE24XX_NR_INTERNAL_IRQS,
71527e34995SRabin Vincent 	.enable		= stmpe24xx_enable,
71627e34995SRabin Vincent 	.get_altfunc	= stmpe24xx_get_altfunc,
71727e34995SRabin Vincent };
71827e34995SRabin Vincent 
71927e34995SRabin Vincent static struct stmpe_variant_info stmpe2403 = {
72027e34995SRabin Vincent 	.name		= "stmpe2403",
72127e34995SRabin Vincent 	.id_val		= 0x0120,
72227e34995SRabin Vincent 	.id_mask	= 0xffff,
72327e34995SRabin Vincent 	.num_gpios	= 24,
72427e34995SRabin Vincent 	.af_bits	= 2,
72527e34995SRabin Vincent 	.regs		= stmpe24xx_regs,
72627e34995SRabin Vincent 	.blocks		= stmpe24xx_blocks,
72727e34995SRabin Vincent 	.num_blocks	= ARRAY_SIZE(stmpe24xx_blocks),
72827e34995SRabin Vincent 	.num_irqs	= STMPE24XX_NR_INTERNAL_IRQS,
72927e34995SRabin Vincent 	.enable		= stmpe24xx_enable,
73027e34995SRabin Vincent 	.get_altfunc	= stmpe24xx_get_altfunc,
7315981f4e6SSundar R Iyer 	.enable_autosleep	= stmpe1601_autosleep, /* same as stmpe1601 */
73227e34995SRabin Vincent };
73327e34995SRabin Vincent 
734e31f9b82SChris Blair static struct stmpe_variant_info *stmpe_variant_info[STMPE_NBR_PARTS] = {
7351cda2394SViresh Kumar 	[STMPE610]	= &stmpe610,
7367f7f4ea1SViresh Kumar 	[STMPE801]	= &stmpe801,
73727e34995SRabin Vincent 	[STMPE811]	= &stmpe811,
73827e34995SRabin Vincent 	[STMPE1601]	= &stmpe1601,
73927e34995SRabin Vincent 	[STMPE2401]	= &stmpe2401,
74027e34995SRabin Vincent 	[STMPE2403]	= &stmpe2403,
74127e34995SRabin Vincent };
74227e34995SRabin Vincent 
743e31f9b82SChris Blair /*
744e31f9b82SChris Blair  * These devices can be connected in a 'no-irq' configuration - the irq pin
745e31f9b82SChris Blair  * is not used and the device cannot interrupt the CPU. Here we only list
746e31f9b82SChris Blair  * devices which support this configuration - the driver will fail probing
747e31f9b82SChris Blair  * for any devices not listed here which are configured in this way.
748e31f9b82SChris Blair  */
749e31f9b82SChris Blair static struct stmpe_variant_info *stmpe_noirq_variant_info[STMPE_NBR_PARTS] = {
750e31f9b82SChris Blair 	[STMPE801]	= &stmpe801_noirq,
751e31f9b82SChris Blair };
752e31f9b82SChris Blair 
75327e34995SRabin Vincent static irqreturn_t stmpe_irq(int irq, void *data)
75427e34995SRabin Vincent {
75527e34995SRabin Vincent 	struct stmpe *stmpe = data;
75627e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
75727e34995SRabin Vincent 	int num = DIV_ROUND_UP(variant->num_irqs, 8);
75827e34995SRabin Vincent 	u8 israddr = stmpe->regs[STMPE_IDX_ISR_MSB];
75927e34995SRabin Vincent 	u8 isr[num];
76027e34995SRabin Vincent 	int ret;
76127e34995SRabin Vincent 	int i;
76227e34995SRabin Vincent 
7637f7f4ea1SViresh Kumar 	if (variant->id_val == STMPE801_ID) {
76476f93992SLee Jones 		int base = irq_create_mapping(stmpe->domain, 0);
76576f93992SLee Jones 
76676f93992SLee Jones 		handle_nested_irq(base);
7677f7f4ea1SViresh Kumar 		return IRQ_HANDLED;
7687f7f4ea1SViresh Kumar 	}
7697f7f4ea1SViresh Kumar 
77027e34995SRabin Vincent 	ret = stmpe_block_read(stmpe, israddr, num, isr);
77127e34995SRabin Vincent 	if (ret < 0)
77227e34995SRabin Vincent 		return IRQ_NONE;
77327e34995SRabin Vincent 
77427e34995SRabin Vincent 	for (i = 0; i < num; i++) {
77527e34995SRabin Vincent 		int bank = num - i - 1;
77627e34995SRabin Vincent 		u8 status = isr[i];
77727e34995SRabin Vincent 		u8 clear;
77827e34995SRabin Vincent 
77927e34995SRabin Vincent 		status &= stmpe->ier[bank];
78027e34995SRabin Vincent 		if (!status)
78127e34995SRabin Vincent 			continue;
78227e34995SRabin Vincent 
78327e34995SRabin Vincent 		clear = status;
78427e34995SRabin Vincent 		while (status) {
78527e34995SRabin Vincent 			int bit = __ffs(status);
78627e34995SRabin Vincent 			int line = bank * 8 + bit;
78776f93992SLee Jones 			int nestedirq = irq_create_mapping(stmpe->domain, line);
78827e34995SRabin Vincent 
78976f93992SLee Jones 			handle_nested_irq(nestedirq);
79027e34995SRabin Vincent 			status &= ~(1 << bit);
79127e34995SRabin Vincent 		}
79227e34995SRabin Vincent 
79327e34995SRabin Vincent 		stmpe_reg_write(stmpe, israddr + i, clear);
79427e34995SRabin Vincent 	}
79527e34995SRabin Vincent 
79627e34995SRabin Vincent 	return IRQ_HANDLED;
79727e34995SRabin Vincent }
79827e34995SRabin Vincent 
79943b8c084SMark Brown static void stmpe_irq_lock(struct irq_data *data)
80027e34995SRabin Vincent {
80143b8c084SMark Brown 	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
80227e34995SRabin Vincent 
80327e34995SRabin Vincent 	mutex_lock(&stmpe->irq_lock);
80427e34995SRabin Vincent }
80527e34995SRabin Vincent 
80643b8c084SMark Brown static void stmpe_irq_sync_unlock(struct irq_data *data)
80727e34995SRabin Vincent {
80843b8c084SMark Brown 	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
80927e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
81027e34995SRabin Vincent 	int num = DIV_ROUND_UP(variant->num_irqs, 8);
81127e34995SRabin Vincent 	int i;
81227e34995SRabin Vincent 
81327e34995SRabin Vincent 	for (i = 0; i < num; i++) {
81427e34995SRabin Vincent 		u8 new = stmpe->ier[i];
81527e34995SRabin Vincent 		u8 old = stmpe->oldier[i];
81627e34995SRabin Vincent 
81727e34995SRabin Vincent 		if (new == old)
81827e34995SRabin Vincent 			continue;
81927e34995SRabin Vincent 
82027e34995SRabin Vincent 		stmpe->oldier[i] = new;
82127e34995SRabin Vincent 		stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_IER_LSB] - i, new);
82227e34995SRabin Vincent 	}
82327e34995SRabin Vincent 
82427e34995SRabin Vincent 	mutex_unlock(&stmpe->irq_lock);
82527e34995SRabin Vincent }
82627e34995SRabin Vincent 
82743b8c084SMark Brown static void stmpe_irq_mask(struct irq_data *data)
82827e34995SRabin Vincent {
82943b8c084SMark Brown 	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
83076f93992SLee Jones 	int offset = data->hwirq;
83127e34995SRabin Vincent 	int regoffset = offset / 8;
83227e34995SRabin Vincent 	int mask = 1 << (offset % 8);
83327e34995SRabin Vincent 
83427e34995SRabin Vincent 	stmpe->ier[regoffset] &= ~mask;
83527e34995SRabin Vincent }
83627e34995SRabin Vincent 
83743b8c084SMark Brown static void stmpe_irq_unmask(struct irq_data *data)
83827e34995SRabin Vincent {
83943b8c084SMark Brown 	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
84076f93992SLee Jones 	int offset = data->hwirq;
84127e34995SRabin Vincent 	int regoffset = offset / 8;
84227e34995SRabin Vincent 	int mask = 1 << (offset % 8);
84327e34995SRabin Vincent 
84427e34995SRabin Vincent 	stmpe->ier[regoffset] |= mask;
84527e34995SRabin Vincent }
84627e34995SRabin Vincent 
84727e34995SRabin Vincent static struct irq_chip stmpe_irq_chip = {
84827e34995SRabin Vincent 	.name			= "stmpe",
84943b8c084SMark Brown 	.irq_bus_lock		= stmpe_irq_lock,
85043b8c084SMark Brown 	.irq_bus_sync_unlock	= stmpe_irq_sync_unlock,
85143b8c084SMark Brown 	.irq_mask		= stmpe_irq_mask,
85243b8c084SMark Brown 	.irq_unmask		= stmpe_irq_unmask,
85327e34995SRabin Vincent };
85427e34995SRabin Vincent 
85576f93992SLee Jones static int stmpe_irq_map(struct irq_domain *d, unsigned int virq,
85676f93992SLee Jones                                 irq_hw_number_t hwirq)
85727e34995SRabin Vincent {
85876f93992SLee Jones 	struct stmpe *stmpe = d->host_data;
8597f7f4ea1SViresh Kumar 	struct irq_chip *chip = NULL;
86027e34995SRabin Vincent 
8617f7f4ea1SViresh Kumar 	if (stmpe->variant->id_val != STMPE801_ID)
8627f7f4ea1SViresh Kumar 		chip = &stmpe_irq_chip;
8637f7f4ea1SViresh Kumar 
86476f93992SLee Jones 	irq_set_chip_data(virq, stmpe);
86576f93992SLee Jones 	irq_set_chip_and_handler(virq, chip, handle_edge_irq);
86676f93992SLee Jones 	irq_set_nested_thread(virq, 1);
86727e34995SRabin Vincent #ifdef CONFIG_ARM
86876f93992SLee Jones 	set_irq_flags(virq, IRQF_VALID);
86927e34995SRabin Vincent #else
87076f93992SLee Jones 	irq_set_noprobe(virq);
87127e34995SRabin Vincent #endif
87227e34995SRabin Vincent 
87327e34995SRabin Vincent 	return 0;
87427e34995SRabin Vincent }
87527e34995SRabin Vincent 
87676f93992SLee Jones static void stmpe_irq_unmap(struct irq_domain *d, unsigned int virq)
87727e34995SRabin Vincent {
87827e34995SRabin Vincent #ifdef CONFIG_ARM
87976f93992SLee Jones 		set_irq_flags(virq, 0);
88027e34995SRabin Vincent #endif
88176f93992SLee Jones 		irq_set_chip_and_handler(virq, NULL, NULL);
88276f93992SLee Jones 		irq_set_chip_data(virq, NULL);
88327e34995SRabin Vincent }
88476f93992SLee Jones 
88576f93992SLee Jones static struct irq_domain_ops stmpe_irq_ops = {
88676f93992SLee Jones         .map    = stmpe_irq_map,
88776f93992SLee Jones         .unmap  = stmpe_irq_unmap,
88876f93992SLee Jones         .xlate  = irq_domain_xlate_twocell,
88976f93992SLee Jones };
89076f93992SLee Jones 
891909582caSLee Jones static int __devinit stmpe_irq_init(struct stmpe *stmpe,
892909582caSLee Jones 				struct device_node *np)
89376f93992SLee Jones {
894b20a4371SLee Jones 	int base = 0;
89576f93992SLee Jones 	int num_irqs = stmpe->variant->num_irqs;
89676f93992SLee Jones 
897b20a4371SLee Jones 	if (!np)
898b20a4371SLee Jones 		base = stmpe->irq_base;
89976f93992SLee Jones 
900b20a4371SLee Jones 	stmpe->domain = irq_domain_add_simple(np, num_irqs, base,
901b20a4371SLee Jones 					      &stmpe_irq_ops, stmpe);
90276f93992SLee Jones 	if (!stmpe->domain) {
90376f93992SLee Jones 		dev_err(stmpe->dev, "Failed to create irqdomain\n");
90476f93992SLee Jones 		return -ENOSYS;
90576f93992SLee Jones 	}
90676f93992SLee Jones 
90776f93992SLee Jones 	return 0;
90827e34995SRabin Vincent }
90927e34995SRabin Vincent 
91027e34995SRabin Vincent static int __devinit stmpe_chip_init(struct stmpe *stmpe)
91127e34995SRabin Vincent {
91227e34995SRabin Vincent 	unsigned int irq_trigger = stmpe->pdata->irq_trigger;
9135981f4e6SSundar R Iyer 	int autosleep_timeout = stmpe->pdata->autosleep_timeout;
91427e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
915e31f9b82SChris Blair 	u8 icr = 0;
91627e34995SRabin Vincent 	unsigned int id;
91727e34995SRabin Vincent 	u8 data[2];
91827e34995SRabin Vincent 	int ret;
91927e34995SRabin Vincent 
92027e34995SRabin Vincent 	ret = stmpe_block_read(stmpe, stmpe->regs[STMPE_IDX_CHIP_ID],
92127e34995SRabin Vincent 			       ARRAY_SIZE(data), data);
92227e34995SRabin Vincent 	if (ret < 0)
92327e34995SRabin Vincent 		return ret;
92427e34995SRabin Vincent 
92527e34995SRabin Vincent 	id = (data[0] << 8) | data[1];
92627e34995SRabin Vincent 	if ((id & variant->id_mask) != variant->id_val) {
92727e34995SRabin Vincent 		dev_err(stmpe->dev, "unknown chip id: %#x\n", id);
92827e34995SRabin Vincent 		return -EINVAL;
92927e34995SRabin Vincent 	}
93027e34995SRabin Vincent 
93127e34995SRabin Vincent 	dev_info(stmpe->dev, "%s detected, chip id: %#x\n", variant->name, id);
93227e34995SRabin Vincent 
93327e34995SRabin Vincent 	/* Disable all modules -- subdrivers should enable what they need. */
93427e34995SRabin Vincent 	ret = stmpe_disable(stmpe, ~0);
93527e34995SRabin Vincent 	if (ret)
93627e34995SRabin Vincent 		return ret;
93727e34995SRabin Vincent 
938e31f9b82SChris Blair 	if (stmpe->irq >= 0) {
9397f7f4ea1SViresh Kumar 		if (id == STMPE801_ID)
9407f7f4ea1SViresh Kumar 			icr = STMPE801_REG_SYS_CTRL_INT_EN;
9417f7f4ea1SViresh Kumar 		else
9427f7f4ea1SViresh Kumar 			icr = STMPE_ICR_LSB_GIM;
9437f7f4ea1SViresh Kumar 
9447f7f4ea1SViresh Kumar 		/* STMPE801 doesn't support Edge interrupts */
9457f7f4ea1SViresh Kumar 		if (id != STMPE801_ID) {
94627e34995SRabin Vincent 			if (irq_trigger == IRQF_TRIGGER_FALLING ||
94727e34995SRabin Vincent 					irq_trigger == IRQF_TRIGGER_RISING)
94827e34995SRabin Vincent 				icr |= STMPE_ICR_LSB_EDGE;
9497f7f4ea1SViresh Kumar 		}
95027e34995SRabin Vincent 
95127e34995SRabin Vincent 		if (irq_trigger == IRQF_TRIGGER_RISING ||
9527f7f4ea1SViresh Kumar 				irq_trigger == IRQF_TRIGGER_HIGH) {
9537f7f4ea1SViresh Kumar 			if (id == STMPE801_ID)
9547f7f4ea1SViresh Kumar 				icr |= STMPE801_REG_SYS_CTRL_INT_HI;
9557f7f4ea1SViresh Kumar 			else
95627e34995SRabin Vincent 				icr |= STMPE_ICR_LSB_HIGH;
9577f7f4ea1SViresh Kumar 		}
958e31f9b82SChris Blair 	}
95927e34995SRabin Vincent 
9605981f4e6SSundar R Iyer 	if (stmpe->pdata->autosleep) {
9615981f4e6SSundar R Iyer 		ret = stmpe_autosleep(stmpe, autosleep_timeout);
9625981f4e6SSundar R Iyer 		if (ret)
9635981f4e6SSundar R Iyer 			return ret;
9645981f4e6SSundar R Iyer 	}
9655981f4e6SSundar R Iyer 
96627e34995SRabin Vincent 	return stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_ICR_LSB], icr);
96727e34995SRabin Vincent }
96827e34995SRabin Vincent 
96927e34995SRabin Vincent static int __devinit stmpe_add_device(struct stmpe *stmpe,
9707da0cbfcSLee Jones 				      struct mfd_cell *cell)
97127e34995SRabin Vincent {
97227e34995SRabin Vincent 	return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1,
97376f93992SLee Jones 			       NULL, stmpe->irq_base, stmpe->domain);
97427e34995SRabin Vincent }
97527e34995SRabin Vincent 
97627e34995SRabin Vincent static int __devinit stmpe_devices_init(struct stmpe *stmpe)
97727e34995SRabin Vincent {
97827e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
97927e34995SRabin Vincent 	unsigned int platform_blocks = stmpe->pdata->blocks;
98027e34995SRabin Vincent 	int ret = -EINVAL;
9817da0cbfcSLee Jones 	int i, j;
98227e34995SRabin Vincent 
98327e34995SRabin Vincent 	for (i = 0; i < variant->num_blocks; i++) {
98427e34995SRabin Vincent 		struct stmpe_variant_block *block = &variant->blocks[i];
98527e34995SRabin Vincent 
98627e34995SRabin Vincent 		if (!(platform_blocks & block->block))
98727e34995SRabin Vincent 			continue;
98827e34995SRabin Vincent 
9897da0cbfcSLee Jones 		for (j = 0; j < block->cell->num_resources; j++) {
9907da0cbfcSLee Jones 			struct resource *res =
9917da0cbfcSLee Jones 				(struct resource *) &block->cell->resources[j];
9927da0cbfcSLee Jones 
9937da0cbfcSLee Jones 			/* Dynamically fill in a variant's IRQ. */
9947da0cbfcSLee Jones 			if (res->flags & IORESOURCE_IRQ)
9957da0cbfcSLee Jones 				res->start = res->end = block->irq + j;
9967da0cbfcSLee Jones 		}
9977da0cbfcSLee Jones 
99827e34995SRabin Vincent 		platform_blocks &= ~block->block;
9997da0cbfcSLee Jones 		ret = stmpe_add_device(stmpe, block->cell);
100027e34995SRabin Vincent 		if (ret)
100127e34995SRabin Vincent 			return ret;
100227e34995SRabin Vincent 	}
100327e34995SRabin Vincent 
100427e34995SRabin Vincent 	if (platform_blocks)
100527e34995SRabin Vincent 		dev_warn(stmpe->dev,
100627e34995SRabin Vincent 			 "platform wants blocks (%#x) not present on variant",
100727e34995SRabin Vincent 			 platform_blocks);
100827e34995SRabin Vincent 
100927e34995SRabin Vincent 	return ret;
101027e34995SRabin Vincent }
101127e34995SRabin Vincent 
1012909582caSLee Jones void __devinit stmpe_of_probe(struct stmpe_platform_data *pdata,
1013909582caSLee Jones 			struct device_node *np)
1014909582caSLee Jones {
1015909582caSLee Jones 	struct device_node *child;
1016909582caSLee Jones 
1017*ac713cc9SVipul Kumar Samar 	pdata->id = -1;
1018*ac713cc9SVipul Kumar Samar 	pdata->irq_trigger = IRQF_TRIGGER_NONE;
1019*ac713cc9SVipul Kumar Samar 
1020909582caSLee Jones 	of_property_read_u32(np, "st,autosleep-timeout",
1021909582caSLee Jones 			&pdata->autosleep_timeout);
1022909582caSLee Jones 
1023909582caSLee Jones 	pdata->autosleep = (pdata->autosleep_timeout) ? true : false;
1024909582caSLee Jones 
1025909582caSLee Jones 	for_each_child_of_node(np, child) {
1026909582caSLee Jones 		if (!strcmp(child->name, "stmpe_gpio")) {
1027909582caSLee Jones 			pdata->blocks |= STMPE_BLOCK_GPIO;
1028*ac713cc9SVipul Kumar Samar 		} else if (!strcmp(child->name, "stmpe_keypad")) {
1029909582caSLee Jones 			pdata->blocks |= STMPE_BLOCK_KEYPAD;
1030*ac713cc9SVipul Kumar Samar 		} else if (!strcmp(child->name, "stmpe_touchscreen")) {
1031909582caSLee Jones 			pdata->blocks |= STMPE_BLOCK_TOUCHSCREEN;
1032*ac713cc9SVipul Kumar Samar 		} else if (!strcmp(child->name, "stmpe_adc")) {
1033909582caSLee Jones 			pdata->blocks |= STMPE_BLOCK_ADC;
1034*ac713cc9SVipul Kumar Samar 		} else if (!strcmp(child->name, "stmpe_pwm")) {
1035*ac713cc9SVipul Kumar Samar 			pdata->blocks |= STMPE_BLOCK_PWM;
1036*ac713cc9SVipul Kumar Samar 		} else if (!strcmp(child->name, "stmpe_rotator")) {
1037*ac713cc9SVipul Kumar Samar 			pdata->blocks |= STMPE_BLOCK_ROTATOR;
1038909582caSLee Jones 		}
1039909582caSLee Jones 	}
1040909582caSLee Jones }
1041909582caSLee Jones 
10421a6e4b74SViresh Kumar /* Called from client specific probe routines */
10438ad1a973SSamuel Ortiz int __devinit stmpe_probe(struct stmpe_client_info *ci, int partnum)
1044208c4343SSundar Iyer {
10451a6e4b74SViresh Kumar 	struct stmpe_platform_data *pdata = dev_get_platdata(ci->dev);
1046909582caSLee Jones 	struct device_node *np = ci->dev->of_node;
104727e34995SRabin Vincent 	struct stmpe *stmpe;
104827e34995SRabin Vincent 	int ret;
104927e34995SRabin Vincent 
1050909582caSLee Jones 	if (!pdata) {
1051cb5faba9SViresh Kumar 		if (!np)
1052cb5faba9SViresh Kumar 			return -EINVAL;
1053cb5faba9SViresh Kumar 
1054cb5faba9SViresh Kumar 		pdata = devm_kzalloc(ci->dev, sizeof(*pdata), GFP_KERNEL);
105527e34995SRabin Vincent 		if (!pdata)
1056909582caSLee Jones 			return -ENOMEM;
1057909582caSLee Jones 
1058909582caSLee Jones 		stmpe_of_probe(pdata, np);
1059909582caSLee Jones 	}
106027e34995SRabin Vincent 
1061cb5faba9SViresh Kumar 	stmpe = devm_kzalloc(ci->dev, sizeof(struct stmpe), GFP_KERNEL);
106227e34995SRabin Vincent 	if (!stmpe)
106327e34995SRabin Vincent 		return -ENOMEM;
106427e34995SRabin Vincent 
106527e34995SRabin Vincent 	mutex_init(&stmpe->irq_lock);
106627e34995SRabin Vincent 	mutex_init(&stmpe->lock);
106727e34995SRabin Vincent 
10681a6e4b74SViresh Kumar 	stmpe->dev = ci->dev;
10691a6e4b74SViresh Kumar 	stmpe->client = ci->client;
107027e34995SRabin Vincent 	stmpe->pdata = pdata;
107127e34995SRabin Vincent 	stmpe->irq_base = pdata->irq_base;
10721a6e4b74SViresh Kumar 	stmpe->ci = ci;
10731a6e4b74SViresh Kumar 	stmpe->partnum = partnum;
10741a6e4b74SViresh Kumar 	stmpe->variant = stmpe_variant_info[partnum];
107527e34995SRabin Vincent 	stmpe->regs = stmpe->variant->regs;
107627e34995SRabin Vincent 	stmpe->num_gpios = stmpe->variant->num_gpios;
10771a6e4b74SViresh Kumar 	dev_set_drvdata(stmpe->dev, stmpe);
107827e34995SRabin Vincent 
10791a6e4b74SViresh Kumar 	if (ci->init)
10801a6e4b74SViresh Kumar 		ci->init(stmpe);
108127e34995SRabin Vincent 
108273de16dbSViresh Kumar 	if (pdata->irq_over_gpio) {
1083cb5faba9SViresh Kumar 		ret = devm_gpio_request_one(ci->dev, pdata->irq_gpio,
1084cb5faba9SViresh Kumar 				GPIOF_DIR_IN, "stmpe");
108573de16dbSViresh Kumar 		if (ret) {
108673de16dbSViresh Kumar 			dev_err(stmpe->dev, "failed to request IRQ GPIO: %d\n",
108773de16dbSViresh Kumar 					ret);
1088cb5faba9SViresh Kumar 			return ret;
108973de16dbSViresh Kumar 		}
109073de16dbSViresh Kumar 
109173de16dbSViresh Kumar 		stmpe->irq = gpio_to_irq(pdata->irq_gpio);
109273de16dbSViresh Kumar 	} else {
10931a6e4b74SViresh Kumar 		stmpe->irq = ci->irq;
109473de16dbSViresh Kumar 	}
109573de16dbSViresh Kumar 
1096e31f9b82SChris Blair 	if (stmpe->irq < 0) {
1097e31f9b82SChris Blair 		/* use alternate variant info for no-irq mode, if supported */
1098e31f9b82SChris Blair 		dev_info(stmpe->dev,
1099e31f9b82SChris Blair 			"%s configured in no-irq mode by platform data\n",
1100e31f9b82SChris Blair 			stmpe->variant->name);
1101e31f9b82SChris Blair 		if (!stmpe_noirq_variant_info[stmpe->partnum]) {
1102e31f9b82SChris Blair 			dev_err(stmpe->dev,
1103e31f9b82SChris Blair 				"%s does not support no-irq mode!\n",
1104e31f9b82SChris Blair 				stmpe->variant->name);
1105cb5faba9SViresh Kumar 			return -ENODEV;
1106e31f9b82SChris Blair 		}
1107e31f9b82SChris Blair 		stmpe->variant = stmpe_noirq_variant_info[stmpe->partnum];
1108*ac713cc9SVipul Kumar Samar 	} else if (pdata->irq_trigger == IRQF_TRIGGER_NONE) {
1109*ac713cc9SVipul Kumar Samar 		pdata->irq_trigger =
1110*ac713cc9SVipul Kumar Samar 			irqd_get_trigger_type(irq_get_irq_data(stmpe->irq));
1111e31f9b82SChris Blair 	}
1112e31f9b82SChris Blair 
111327e34995SRabin Vincent 	ret = stmpe_chip_init(stmpe);
111427e34995SRabin Vincent 	if (ret)
1115cb5faba9SViresh Kumar 		return ret;
111627e34995SRabin Vincent 
1117e31f9b82SChris Blair 	if (stmpe->irq >= 0) {
1118909582caSLee Jones 		ret = stmpe_irq_init(stmpe, np);
111927e34995SRabin Vincent 		if (ret)
1120cb5faba9SViresh Kumar 			return ret;
112127e34995SRabin Vincent 
1122cb5faba9SViresh Kumar 		ret = devm_request_threaded_irq(ci->dev, stmpe->irq, NULL,
1123cb5faba9SViresh Kumar 				stmpe_irq, pdata->irq_trigger | IRQF_ONESHOT,
1124e31f9b82SChris Blair 				"stmpe", stmpe);
112527e34995SRabin Vincent 		if (ret) {
1126e31f9b82SChris Blair 			dev_err(stmpe->dev, "failed to request IRQ: %d\n",
1127e31f9b82SChris Blair 					ret);
1128cb5faba9SViresh Kumar 			return ret;
112927e34995SRabin Vincent 		}
1130e31f9b82SChris Blair 	}
113127e34995SRabin Vincent 
113227e34995SRabin Vincent 	ret = stmpe_devices_init(stmpe);
1133cb5faba9SViresh Kumar 	if (!ret)
113427e34995SRabin Vincent 		return 0;
113527e34995SRabin Vincent 
1136cb5faba9SViresh Kumar 	dev_err(stmpe->dev, "failed to add children\n");
113727e34995SRabin Vincent 	mfd_remove_devices(stmpe->dev);
1138cb5faba9SViresh Kumar 
113927e34995SRabin Vincent 	return ret;
114027e34995SRabin Vincent }
114127e34995SRabin Vincent 
11421a6e4b74SViresh Kumar int stmpe_remove(struct stmpe *stmpe)
114327e34995SRabin Vincent {
114427e34995SRabin Vincent 	mfd_remove_devices(stmpe->dev);
114527e34995SRabin Vincent 
114627e34995SRabin Vincent 	return 0;
114727e34995SRabin Vincent }
114827e34995SRabin Vincent 
1149208c4343SSundar Iyer #ifdef CONFIG_PM
11501a6e4b74SViresh Kumar static int stmpe_suspend(struct device *dev)
11511a6e4b74SViresh Kumar {
11521a6e4b74SViresh Kumar 	struct stmpe *stmpe = dev_get_drvdata(dev);
11531a6e4b74SViresh Kumar 
1154e31f9b82SChris Blair 	if (stmpe->irq >= 0 && device_may_wakeup(dev))
11551a6e4b74SViresh Kumar 		enable_irq_wake(stmpe->irq);
11561a6e4b74SViresh Kumar 
11571a6e4b74SViresh Kumar 	return 0;
11581a6e4b74SViresh Kumar }
11591a6e4b74SViresh Kumar 
11601a6e4b74SViresh Kumar static int stmpe_resume(struct device *dev)
11611a6e4b74SViresh Kumar {
11621a6e4b74SViresh Kumar 	struct stmpe *stmpe = dev_get_drvdata(dev);
11631a6e4b74SViresh Kumar 
1164e31f9b82SChris Blair 	if (stmpe->irq >= 0 && device_may_wakeup(dev))
11651a6e4b74SViresh Kumar 		disable_irq_wake(stmpe->irq);
11661a6e4b74SViresh Kumar 
11671a6e4b74SViresh Kumar 	return 0;
11681a6e4b74SViresh Kumar }
11691a6e4b74SViresh Kumar 
11701a6e4b74SViresh Kumar const struct dev_pm_ops stmpe_dev_pm_ops = {
1171208c4343SSundar Iyer 	.suspend	= stmpe_suspend,
1172208c4343SSundar Iyer 	.resume		= stmpe_resume,
1173208c4343SSundar Iyer };
1174208c4343SSundar Iyer #endif
1175