xref: /openbmc/linux/drivers/mfd/stmpe.c (revision 43b8c084)
127e34995SRabin Vincent /*
227e34995SRabin Vincent  * Copyright (C) ST-Ericsson SA 2010
327e34995SRabin Vincent  *
427e34995SRabin Vincent  * License Terms: GNU General Public License, version 2
527e34995SRabin Vincent  * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
627e34995SRabin Vincent  */
727e34995SRabin Vincent 
827e34995SRabin Vincent #include <linux/kernel.h>
927e34995SRabin Vincent #include <linux/module.h>
1027e34995SRabin Vincent #include <linux/interrupt.h>
1127e34995SRabin Vincent #include <linux/irq.h>
1227e34995SRabin Vincent #include <linux/slab.h>
1327e34995SRabin Vincent #include <linux/i2c.h>
1427e34995SRabin Vincent #include <linux/mfd/core.h>
1527e34995SRabin Vincent #include <linux/mfd/stmpe.h>
1627e34995SRabin Vincent #include "stmpe.h"
1727e34995SRabin Vincent 
1827e34995SRabin Vincent static int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks)
1927e34995SRabin Vincent {
2027e34995SRabin Vincent 	return stmpe->variant->enable(stmpe, blocks, true);
2127e34995SRabin Vincent }
2227e34995SRabin Vincent 
2327e34995SRabin Vincent static int __stmpe_disable(struct stmpe *stmpe, unsigned int blocks)
2427e34995SRabin Vincent {
2527e34995SRabin Vincent 	return stmpe->variant->enable(stmpe, blocks, false);
2627e34995SRabin Vincent }
2727e34995SRabin Vincent 
2827e34995SRabin Vincent static int __stmpe_reg_read(struct stmpe *stmpe, u8 reg)
2927e34995SRabin Vincent {
3027e34995SRabin Vincent 	int ret;
3127e34995SRabin Vincent 
3227e34995SRabin Vincent 	ret = i2c_smbus_read_byte_data(stmpe->i2c, reg);
3327e34995SRabin Vincent 	if (ret < 0)
3427e34995SRabin Vincent 		dev_err(stmpe->dev, "failed to read reg %#x: %d\n",
3527e34995SRabin Vincent 			reg, ret);
3627e34995SRabin Vincent 
3727e34995SRabin Vincent 	dev_vdbg(stmpe->dev, "rd: reg %#x => data %#x\n", reg, ret);
3827e34995SRabin Vincent 
3927e34995SRabin Vincent 	return ret;
4027e34995SRabin Vincent }
4127e34995SRabin Vincent 
4227e34995SRabin Vincent static int __stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val)
4327e34995SRabin Vincent {
4427e34995SRabin Vincent 	int ret;
4527e34995SRabin Vincent 
4627e34995SRabin Vincent 	dev_vdbg(stmpe->dev, "wr: reg %#x <= %#x\n", reg, val);
4727e34995SRabin Vincent 
4827e34995SRabin Vincent 	ret = i2c_smbus_write_byte_data(stmpe->i2c, reg, val);
4927e34995SRabin Vincent 	if (ret < 0)
5027e34995SRabin Vincent 		dev_err(stmpe->dev, "failed to write reg %#x: %d\n",
5127e34995SRabin Vincent 			reg, ret);
5227e34995SRabin Vincent 
5327e34995SRabin Vincent 	return ret;
5427e34995SRabin Vincent }
5527e34995SRabin Vincent 
5627e34995SRabin Vincent static int __stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val)
5727e34995SRabin Vincent {
5827e34995SRabin Vincent 	int ret;
5927e34995SRabin Vincent 
6027e34995SRabin Vincent 	ret = __stmpe_reg_read(stmpe, reg);
6127e34995SRabin Vincent 	if (ret < 0)
6227e34995SRabin Vincent 		return ret;
6327e34995SRabin Vincent 
6427e34995SRabin Vincent 	ret &= ~mask;
6527e34995SRabin Vincent 	ret |= val;
6627e34995SRabin Vincent 
6727e34995SRabin Vincent 	return __stmpe_reg_write(stmpe, reg, ret);
6827e34995SRabin Vincent }
6927e34995SRabin Vincent 
7027e34995SRabin Vincent static int __stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length,
7127e34995SRabin Vincent 			      u8 *values)
7227e34995SRabin Vincent {
7327e34995SRabin Vincent 	int ret;
7427e34995SRabin Vincent 
7527e34995SRabin Vincent 	ret = i2c_smbus_read_i2c_block_data(stmpe->i2c, reg, length, values);
7627e34995SRabin Vincent 	if (ret < 0)
7727e34995SRabin Vincent 		dev_err(stmpe->dev, "failed to read regs %#x: %d\n",
7827e34995SRabin Vincent 			reg, ret);
7927e34995SRabin Vincent 
8027e34995SRabin Vincent 	dev_vdbg(stmpe->dev, "rd: reg %#x (%d) => ret %#x\n", reg, length, ret);
8127e34995SRabin Vincent 	stmpe_dump_bytes("stmpe rd: ", values, length);
8227e34995SRabin Vincent 
8327e34995SRabin Vincent 	return ret;
8427e34995SRabin Vincent }
8527e34995SRabin Vincent 
8627e34995SRabin Vincent static int __stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length,
8727e34995SRabin Vincent 			const u8 *values)
8827e34995SRabin Vincent {
8927e34995SRabin Vincent 	int ret;
9027e34995SRabin Vincent 
9127e34995SRabin Vincent 	dev_vdbg(stmpe->dev, "wr: regs %#x (%d)\n", reg, length);
9227e34995SRabin Vincent 	stmpe_dump_bytes("stmpe wr: ", values, length);
9327e34995SRabin Vincent 
9427e34995SRabin Vincent 	ret = i2c_smbus_write_i2c_block_data(stmpe->i2c, reg, length,
9527e34995SRabin Vincent 					     values);
9627e34995SRabin Vincent 	if (ret < 0)
9727e34995SRabin Vincent 		dev_err(stmpe->dev, "failed to write regs %#x: %d\n",
9827e34995SRabin Vincent 			reg, ret);
9927e34995SRabin Vincent 
10027e34995SRabin Vincent 	return ret;
10127e34995SRabin Vincent }
10227e34995SRabin Vincent 
10327e34995SRabin Vincent /**
10427e34995SRabin Vincent  * stmpe_enable - enable blocks on an STMPE device
10527e34995SRabin Vincent  * @stmpe:	Device to work on
10627e34995SRabin Vincent  * @blocks:	Mask of blocks (enum stmpe_block values) to enable
10727e34995SRabin Vincent  */
10827e34995SRabin Vincent int stmpe_enable(struct stmpe *stmpe, unsigned int blocks)
10927e34995SRabin Vincent {
11027e34995SRabin Vincent 	int ret;
11127e34995SRabin Vincent 
11227e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
11327e34995SRabin Vincent 	ret = __stmpe_enable(stmpe, blocks);
11427e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
11527e34995SRabin Vincent 
11627e34995SRabin Vincent 	return ret;
11727e34995SRabin Vincent }
11827e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_enable);
11927e34995SRabin Vincent 
12027e34995SRabin Vincent /**
12127e34995SRabin Vincent  * stmpe_disable - disable blocks on an STMPE device
12227e34995SRabin Vincent  * @stmpe:	Device to work on
12327e34995SRabin Vincent  * @blocks:	Mask of blocks (enum stmpe_block values) to enable
12427e34995SRabin Vincent  */
12527e34995SRabin Vincent int stmpe_disable(struct stmpe *stmpe, unsigned int blocks)
12627e34995SRabin Vincent {
12727e34995SRabin Vincent 	int ret;
12827e34995SRabin Vincent 
12927e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
13027e34995SRabin Vincent 	ret = __stmpe_disable(stmpe, blocks);
13127e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
13227e34995SRabin Vincent 
13327e34995SRabin Vincent 	return ret;
13427e34995SRabin Vincent }
13527e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_disable);
13627e34995SRabin Vincent 
13727e34995SRabin Vincent /**
13827e34995SRabin Vincent  * stmpe_reg_read() - read a single STMPE register
13927e34995SRabin Vincent  * @stmpe:	Device to read from
14027e34995SRabin Vincent  * @reg:	Register to read
14127e34995SRabin Vincent  */
14227e34995SRabin Vincent int stmpe_reg_read(struct stmpe *stmpe, u8 reg)
14327e34995SRabin Vincent {
14427e34995SRabin Vincent 	int ret;
14527e34995SRabin Vincent 
14627e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
14727e34995SRabin Vincent 	ret = __stmpe_reg_read(stmpe, reg);
14827e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
14927e34995SRabin Vincent 
15027e34995SRabin Vincent 	return ret;
15127e34995SRabin Vincent }
15227e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_reg_read);
15327e34995SRabin Vincent 
15427e34995SRabin Vincent /**
15527e34995SRabin Vincent  * stmpe_reg_write() - write a single STMPE register
15627e34995SRabin Vincent  * @stmpe:	Device to write to
15727e34995SRabin Vincent  * @reg:	Register to write
15827e34995SRabin Vincent  * @val:	Value to write
15927e34995SRabin Vincent  */
16027e34995SRabin Vincent int stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val)
16127e34995SRabin Vincent {
16227e34995SRabin Vincent 	int ret;
16327e34995SRabin Vincent 
16427e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
16527e34995SRabin Vincent 	ret = __stmpe_reg_write(stmpe, reg, val);
16627e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
16727e34995SRabin Vincent 
16827e34995SRabin Vincent 	return ret;
16927e34995SRabin Vincent }
17027e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_reg_write);
17127e34995SRabin Vincent 
17227e34995SRabin Vincent /**
17327e34995SRabin Vincent  * stmpe_set_bits() - set the value of a bitfield in a STMPE register
17427e34995SRabin Vincent  * @stmpe:	Device to write to
17527e34995SRabin Vincent  * @reg:	Register to write
17627e34995SRabin Vincent  * @mask:	Mask of bits to set
17727e34995SRabin Vincent  * @val:	Value to set
17827e34995SRabin Vincent  */
17927e34995SRabin Vincent int stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val)
18027e34995SRabin Vincent {
18127e34995SRabin Vincent 	int ret;
18227e34995SRabin Vincent 
18327e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
18427e34995SRabin Vincent 	ret = __stmpe_set_bits(stmpe, reg, mask, val);
18527e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
18627e34995SRabin Vincent 
18727e34995SRabin Vincent 	return ret;
18827e34995SRabin Vincent }
18927e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_set_bits);
19027e34995SRabin Vincent 
19127e34995SRabin Vincent /**
19227e34995SRabin Vincent  * stmpe_block_read() - read multiple STMPE registers
19327e34995SRabin Vincent  * @stmpe:	Device to read from
19427e34995SRabin Vincent  * @reg:	First register
19527e34995SRabin Vincent  * @length:	Number of registers
19627e34995SRabin Vincent  * @values:	Buffer to write to
19727e34995SRabin Vincent  */
19827e34995SRabin Vincent int stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values)
19927e34995SRabin Vincent {
20027e34995SRabin Vincent 	int ret;
20127e34995SRabin Vincent 
20227e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
20327e34995SRabin Vincent 	ret = __stmpe_block_read(stmpe, reg, length, values);
20427e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
20527e34995SRabin Vincent 
20627e34995SRabin Vincent 	return ret;
20727e34995SRabin Vincent }
20827e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_block_read);
20927e34995SRabin Vincent 
21027e34995SRabin Vincent /**
21127e34995SRabin Vincent  * stmpe_block_write() - write multiple STMPE registers
21227e34995SRabin Vincent  * @stmpe:	Device to write to
21327e34995SRabin Vincent  * @reg:	First register
21427e34995SRabin Vincent  * @length:	Number of registers
21527e34995SRabin Vincent  * @values:	Values to write
21627e34995SRabin Vincent  */
21727e34995SRabin Vincent int stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length,
21827e34995SRabin Vincent 		      const u8 *values)
21927e34995SRabin Vincent {
22027e34995SRabin Vincent 	int ret;
22127e34995SRabin Vincent 
22227e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
22327e34995SRabin Vincent 	ret = __stmpe_block_write(stmpe, reg, length, values);
22427e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
22527e34995SRabin Vincent 
22627e34995SRabin Vincent 	return ret;
22727e34995SRabin Vincent }
22827e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_block_write);
22927e34995SRabin Vincent 
23027e34995SRabin Vincent /**
23127e34995SRabin Vincent  * stmpe_set_altfunc: set the alternate function for STMPE pins
23227e34995SRabin Vincent  * @stmpe:	Device to configure
23327e34995SRabin Vincent  * @pins:	Bitmask of pins to affect
23427e34995SRabin Vincent  * @block:	block to enable alternate functions for
23527e34995SRabin Vincent  *
23627e34995SRabin Vincent  * @pins is assumed to have a bit set for each of the bits whose alternate
23727e34995SRabin Vincent  * function is to be changed, numbered according to the GPIOXY numbers.
23827e34995SRabin Vincent  *
23927e34995SRabin Vincent  * If the GPIO module is not enabled, this function automatically enables it in
24027e34995SRabin Vincent  * order to perform the change.
24127e34995SRabin Vincent  */
24227e34995SRabin Vincent int stmpe_set_altfunc(struct stmpe *stmpe, u32 pins, enum stmpe_block block)
24327e34995SRabin Vincent {
24427e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
24527e34995SRabin Vincent 	u8 regaddr = stmpe->regs[STMPE_IDX_GPAFR_U_MSB];
24627e34995SRabin Vincent 	int af_bits = variant->af_bits;
24727e34995SRabin Vincent 	int numregs = DIV_ROUND_UP(stmpe->num_gpios * af_bits, 8);
24827e34995SRabin Vincent 	int afperreg = 8 / af_bits;
24927e34995SRabin Vincent 	int mask = (1 << af_bits) - 1;
25027e34995SRabin Vincent 	u8 regs[numregs];
25127e34995SRabin Vincent 	int af;
25227e34995SRabin Vincent 	int ret;
25327e34995SRabin Vincent 
25427e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
25527e34995SRabin Vincent 
25627e34995SRabin Vincent 	ret = __stmpe_enable(stmpe, STMPE_BLOCK_GPIO);
25727e34995SRabin Vincent 	if (ret < 0)
25827e34995SRabin Vincent 		goto out;
25927e34995SRabin Vincent 
26027e34995SRabin Vincent 	ret = __stmpe_block_read(stmpe, regaddr, numregs, regs);
26127e34995SRabin Vincent 	if (ret < 0)
26227e34995SRabin Vincent 		goto out;
26327e34995SRabin Vincent 
26427e34995SRabin Vincent 	af = variant->get_altfunc(stmpe, block);
26527e34995SRabin Vincent 
26627e34995SRabin Vincent 	while (pins) {
26727e34995SRabin Vincent 		int pin = __ffs(pins);
26827e34995SRabin Vincent 		int regoffset = numregs - (pin / afperreg) - 1;
26927e34995SRabin Vincent 		int pos = (pin % afperreg) * (8 / afperreg);
27027e34995SRabin Vincent 
27127e34995SRabin Vincent 		regs[regoffset] &= ~(mask << pos);
27227e34995SRabin Vincent 		regs[regoffset] |= af << pos;
27327e34995SRabin Vincent 
27427e34995SRabin Vincent 		pins &= ~(1 << pin);
27527e34995SRabin Vincent 	}
27627e34995SRabin Vincent 
27727e34995SRabin Vincent 	ret = __stmpe_block_write(stmpe, regaddr, numregs, regs);
27827e34995SRabin Vincent 
27927e34995SRabin Vincent out:
28027e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
28127e34995SRabin Vincent 	return ret;
28227e34995SRabin Vincent }
28327e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_set_altfunc);
28427e34995SRabin Vincent 
28527e34995SRabin Vincent /*
28627e34995SRabin Vincent  * GPIO (all variants)
28727e34995SRabin Vincent  */
28827e34995SRabin Vincent 
28927e34995SRabin Vincent static struct resource stmpe_gpio_resources[] = {
29027e34995SRabin Vincent 	/* Start and end filled dynamically */
29127e34995SRabin Vincent 	{
29227e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
29327e34995SRabin Vincent 	},
29427e34995SRabin Vincent };
29527e34995SRabin Vincent 
29627e34995SRabin Vincent static struct mfd_cell stmpe_gpio_cell = {
29727e34995SRabin Vincent 	.name		= "stmpe-gpio",
29827e34995SRabin Vincent 	.resources	= stmpe_gpio_resources,
29927e34995SRabin Vincent 	.num_resources	= ARRAY_SIZE(stmpe_gpio_resources),
30027e34995SRabin Vincent };
30127e34995SRabin Vincent 
30227e34995SRabin Vincent /*
30327e34995SRabin Vincent  * Keypad (1601, 2401, 2403)
30427e34995SRabin Vincent  */
30527e34995SRabin Vincent 
30627e34995SRabin Vincent static struct resource stmpe_keypad_resources[] = {
30727e34995SRabin Vincent 	{
30827e34995SRabin Vincent 		.name	= "KEYPAD",
30927e34995SRabin Vincent 		.start	= 0,
31027e34995SRabin Vincent 		.end	= 0,
31127e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
31227e34995SRabin Vincent 	},
31327e34995SRabin Vincent 	{
31427e34995SRabin Vincent 		.name	= "KEYPAD_OVER",
31527e34995SRabin Vincent 		.start	= 1,
31627e34995SRabin Vincent 		.end	= 1,
31727e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
31827e34995SRabin Vincent 	},
31927e34995SRabin Vincent };
32027e34995SRabin Vincent 
32127e34995SRabin Vincent static struct mfd_cell stmpe_keypad_cell = {
32227e34995SRabin Vincent 	.name		= "stmpe-keypad",
32327e34995SRabin Vincent 	.resources	= stmpe_keypad_resources,
32427e34995SRabin Vincent 	.num_resources	= ARRAY_SIZE(stmpe_keypad_resources),
32527e34995SRabin Vincent };
32627e34995SRabin Vincent 
32727e34995SRabin Vincent /*
32827e34995SRabin Vincent  * Touchscreen (STMPE811)
32927e34995SRabin Vincent  */
33027e34995SRabin Vincent 
33127e34995SRabin Vincent static struct resource stmpe_ts_resources[] = {
33227e34995SRabin Vincent 	{
33327e34995SRabin Vincent 		.name	= "TOUCH_DET",
33427e34995SRabin Vincent 		.start	= 0,
33527e34995SRabin Vincent 		.end	= 0,
33627e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
33727e34995SRabin Vincent 	},
33827e34995SRabin Vincent 	{
33927e34995SRabin Vincent 		.name	= "FIFO_TH",
34027e34995SRabin Vincent 		.start	= 1,
34127e34995SRabin Vincent 		.end	= 1,
34227e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
34327e34995SRabin Vincent 	},
34427e34995SRabin Vincent };
34527e34995SRabin Vincent 
34627e34995SRabin Vincent static struct mfd_cell stmpe_ts_cell = {
34727e34995SRabin Vincent 	.name		= "stmpe-ts",
34827e34995SRabin Vincent 	.resources	= stmpe_ts_resources,
34927e34995SRabin Vincent 	.num_resources	= ARRAY_SIZE(stmpe_ts_resources),
35027e34995SRabin Vincent };
35127e34995SRabin Vincent 
35227e34995SRabin Vincent /*
35327e34995SRabin Vincent  * STMPE811
35427e34995SRabin Vincent  */
35527e34995SRabin Vincent 
35627e34995SRabin Vincent static const u8 stmpe811_regs[] = {
35727e34995SRabin Vincent 	[STMPE_IDX_CHIP_ID]	= STMPE811_REG_CHIP_ID,
35827e34995SRabin Vincent 	[STMPE_IDX_ICR_LSB]	= STMPE811_REG_INT_CTRL,
35927e34995SRabin Vincent 	[STMPE_IDX_IER_LSB]	= STMPE811_REG_INT_EN,
36027e34995SRabin Vincent 	[STMPE_IDX_ISR_MSB]	= STMPE811_REG_INT_STA,
36127e34995SRabin Vincent 	[STMPE_IDX_GPMR_LSB]	= STMPE811_REG_GPIO_MP_STA,
36227e34995SRabin Vincent 	[STMPE_IDX_GPSR_LSB]	= STMPE811_REG_GPIO_SET_PIN,
36327e34995SRabin Vincent 	[STMPE_IDX_GPCR_LSB]	= STMPE811_REG_GPIO_CLR_PIN,
36427e34995SRabin Vincent 	[STMPE_IDX_GPDR_LSB]	= STMPE811_REG_GPIO_DIR,
36527e34995SRabin Vincent 	[STMPE_IDX_GPRER_LSB]	= STMPE811_REG_GPIO_RE,
36627e34995SRabin Vincent 	[STMPE_IDX_GPFER_LSB]	= STMPE811_REG_GPIO_FE,
36727e34995SRabin Vincent 	[STMPE_IDX_GPAFR_U_MSB]	= STMPE811_REG_GPIO_AF,
36827e34995SRabin Vincent 	[STMPE_IDX_IEGPIOR_LSB]	= STMPE811_REG_GPIO_INT_EN,
36927e34995SRabin Vincent 	[STMPE_IDX_ISGPIOR_MSB]	= STMPE811_REG_GPIO_INT_STA,
37027e34995SRabin Vincent 	[STMPE_IDX_GPEDR_MSB]	= STMPE811_REG_GPIO_ED,
37127e34995SRabin Vincent };
37227e34995SRabin Vincent 
37327e34995SRabin Vincent static struct stmpe_variant_block stmpe811_blocks[] = {
37427e34995SRabin Vincent 	{
37527e34995SRabin Vincent 		.cell	= &stmpe_gpio_cell,
37627e34995SRabin Vincent 		.irq	= STMPE811_IRQ_GPIOC,
37727e34995SRabin Vincent 		.block	= STMPE_BLOCK_GPIO,
37827e34995SRabin Vincent 	},
37927e34995SRabin Vincent 	{
38027e34995SRabin Vincent 		.cell	= &stmpe_ts_cell,
38127e34995SRabin Vincent 		.irq	= STMPE811_IRQ_TOUCH_DET,
38227e34995SRabin Vincent 		.block	= STMPE_BLOCK_TOUCHSCREEN,
38327e34995SRabin Vincent 	},
38427e34995SRabin Vincent };
38527e34995SRabin Vincent 
38627e34995SRabin Vincent static int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks,
38727e34995SRabin Vincent 			   bool enable)
38827e34995SRabin Vincent {
38927e34995SRabin Vincent 	unsigned int mask = 0;
39027e34995SRabin Vincent 
39127e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_GPIO)
39227e34995SRabin Vincent 		mask |= STMPE811_SYS_CTRL2_GPIO_OFF;
39327e34995SRabin Vincent 
39427e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_ADC)
39527e34995SRabin Vincent 		mask |= STMPE811_SYS_CTRL2_ADC_OFF;
39627e34995SRabin Vincent 
39727e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_TOUCHSCREEN)
39827e34995SRabin Vincent 		mask |= STMPE811_SYS_CTRL2_TSC_OFF;
39927e34995SRabin Vincent 
40027e34995SRabin Vincent 	return __stmpe_set_bits(stmpe, STMPE811_REG_SYS_CTRL2, mask,
40127e34995SRabin Vincent 				enable ? 0 : mask);
40227e34995SRabin Vincent }
40327e34995SRabin Vincent 
40427e34995SRabin Vincent static int stmpe811_get_altfunc(struct stmpe *stmpe, enum stmpe_block block)
40527e34995SRabin Vincent {
40627e34995SRabin Vincent 	/* 0 for touchscreen, 1 for GPIO */
40727e34995SRabin Vincent 	return block != STMPE_BLOCK_TOUCHSCREEN;
40827e34995SRabin Vincent }
40927e34995SRabin Vincent 
41027e34995SRabin Vincent static struct stmpe_variant_info stmpe811 = {
41127e34995SRabin Vincent 	.name		= "stmpe811",
41227e34995SRabin Vincent 	.id_val		= 0x0811,
41327e34995SRabin Vincent 	.id_mask	= 0xffff,
41427e34995SRabin Vincent 	.num_gpios	= 8,
41527e34995SRabin Vincent 	.af_bits	= 1,
41627e34995SRabin Vincent 	.regs		= stmpe811_regs,
41727e34995SRabin Vincent 	.blocks		= stmpe811_blocks,
41827e34995SRabin Vincent 	.num_blocks	= ARRAY_SIZE(stmpe811_blocks),
41927e34995SRabin Vincent 	.num_irqs	= STMPE811_NR_INTERNAL_IRQS,
42027e34995SRabin Vincent 	.enable		= stmpe811_enable,
42127e34995SRabin Vincent 	.get_altfunc	= stmpe811_get_altfunc,
42227e34995SRabin Vincent };
42327e34995SRabin Vincent 
42427e34995SRabin Vincent /*
42527e34995SRabin Vincent  * STMPE1601
42627e34995SRabin Vincent  */
42727e34995SRabin Vincent 
42827e34995SRabin Vincent static const u8 stmpe1601_regs[] = {
42927e34995SRabin Vincent 	[STMPE_IDX_CHIP_ID]	= STMPE1601_REG_CHIP_ID,
43027e34995SRabin Vincent 	[STMPE_IDX_ICR_LSB]	= STMPE1601_REG_ICR_LSB,
43127e34995SRabin Vincent 	[STMPE_IDX_IER_LSB]	= STMPE1601_REG_IER_LSB,
43227e34995SRabin Vincent 	[STMPE_IDX_ISR_MSB]	= STMPE1601_REG_ISR_MSB,
43327e34995SRabin Vincent 	[STMPE_IDX_GPMR_LSB]	= STMPE1601_REG_GPIO_MP_LSB,
43427e34995SRabin Vincent 	[STMPE_IDX_GPSR_LSB]	= STMPE1601_REG_GPIO_SET_LSB,
43527e34995SRabin Vincent 	[STMPE_IDX_GPCR_LSB]	= STMPE1601_REG_GPIO_CLR_LSB,
43627e34995SRabin Vincent 	[STMPE_IDX_GPDR_LSB]	= STMPE1601_REG_GPIO_SET_DIR_LSB,
43727e34995SRabin Vincent 	[STMPE_IDX_GPRER_LSB]	= STMPE1601_REG_GPIO_RE_LSB,
43827e34995SRabin Vincent 	[STMPE_IDX_GPFER_LSB]	= STMPE1601_REG_GPIO_FE_LSB,
43927e34995SRabin Vincent 	[STMPE_IDX_GPAFR_U_MSB]	= STMPE1601_REG_GPIO_AF_U_MSB,
44027e34995SRabin Vincent 	[STMPE_IDX_IEGPIOR_LSB]	= STMPE1601_REG_INT_EN_GPIO_MASK_LSB,
44127e34995SRabin Vincent 	[STMPE_IDX_ISGPIOR_MSB]	= STMPE1601_REG_INT_STA_GPIO_MSB,
44227e34995SRabin Vincent 	[STMPE_IDX_GPEDR_MSB]	= STMPE1601_REG_GPIO_ED_MSB,
44327e34995SRabin Vincent };
44427e34995SRabin Vincent 
44527e34995SRabin Vincent static struct stmpe_variant_block stmpe1601_blocks[] = {
44627e34995SRabin Vincent 	{
44727e34995SRabin Vincent 		.cell	= &stmpe_gpio_cell,
44827e34995SRabin Vincent 		.irq	= STMPE24XX_IRQ_GPIOC,
44927e34995SRabin Vincent 		.block	= STMPE_BLOCK_GPIO,
45027e34995SRabin Vincent 	},
45127e34995SRabin Vincent 	{
45227e34995SRabin Vincent 		.cell	= &stmpe_keypad_cell,
45327e34995SRabin Vincent 		.irq	= STMPE24XX_IRQ_KEYPAD,
45427e34995SRabin Vincent 		.block	= STMPE_BLOCK_KEYPAD,
45527e34995SRabin Vincent 	},
45627e34995SRabin Vincent };
45727e34995SRabin Vincent 
4585981f4e6SSundar R Iyer /* supported autosleep timeout delay (in msecs) */
4595981f4e6SSundar R Iyer static const int stmpe_autosleep_delay[] = {
4605981f4e6SSundar R Iyer 	4, 16, 32, 64, 128, 256, 512, 1024,
4615981f4e6SSundar R Iyer };
4625981f4e6SSundar R Iyer 
4635981f4e6SSundar R Iyer static int stmpe_round_timeout(int timeout)
4645981f4e6SSundar R Iyer {
4655981f4e6SSundar R Iyer 	int i;
4665981f4e6SSundar R Iyer 
4675981f4e6SSundar R Iyer 	for (i = 0; i < ARRAY_SIZE(stmpe_autosleep_delay); i++) {
4685981f4e6SSundar R Iyer 		if (stmpe_autosleep_delay[i] >= timeout)
4695981f4e6SSundar R Iyer 			return i;
4705981f4e6SSundar R Iyer 	}
4715981f4e6SSundar R Iyer 
4725981f4e6SSundar R Iyer 	/*
4735981f4e6SSundar R Iyer 	 * requests for delays longer than supported should not return the
4745981f4e6SSundar R Iyer 	 * longest supported delay
4755981f4e6SSundar R Iyer 	 */
4765981f4e6SSundar R Iyer 	return -EINVAL;
4775981f4e6SSundar R Iyer }
4785981f4e6SSundar R Iyer 
4795981f4e6SSundar R Iyer static int stmpe_autosleep(struct stmpe *stmpe, int autosleep_timeout)
4805981f4e6SSundar R Iyer {
4815981f4e6SSundar R Iyer 	int ret;
4825981f4e6SSundar R Iyer 
4835981f4e6SSundar R Iyer 	if (!stmpe->variant->enable_autosleep)
4845981f4e6SSundar R Iyer 		return -ENOSYS;
4855981f4e6SSundar R Iyer 
4865981f4e6SSundar R Iyer 	mutex_lock(&stmpe->lock);
4875981f4e6SSundar R Iyer 	ret = stmpe->variant->enable_autosleep(stmpe, autosleep_timeout);
4885981f4e6SSundar R Iyer 	mutex_unlock(&stmpe->lock);
4895981f4e6SSundar R Iyer 
4905981f4e6SSundar R Iyer 	return ret;
4915981f4e6SSundar R Iyer }
4925981f4e6SSundar R Iyer 
4935981f4e6SSundar R Iyer /*
4945981f4e6SSundar R Iyer  * Both stmpe 1601/2403 support same layout for autosleep
4955981f4e6SSundar R Iyer  */
4965981f4e6SSundar R Iyer static int stmpe1601_autosleep(struct stmpe *stmpe,
4975981f4e6SSundar R Iyer 		int autosleep_timeout)
4985981f4e6SSundar R Iyer {
4995981f4e6SSundar R Iyer 	int ret, timeout;
5005981f4e6SSundar R Iyer 
5015981f4e6SSundar R Iyer 	/* choose the best available timeout */
5025981f4e6SSundar R Iyer 	timeout = stmpe_round_timeout(autosleep_timeout);
5035981f4e6SSundar R Iyer 	if (timeout < 0) {
5045981f4e6SSundar R Iyer 		dev_err(stmpe->dev, "invalid timeout\n");
5055981f4e6SSundar R Iyer 		return timeout;
5065981f4e6SSundar R Iyer 	}
5075981f4e6SSundar R Iyer 
5085981f4e6SSundar R Iyer 	ret = __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL2,
5095981f4e6SSundar R Iyer 			STMPE1601_AUTOSLEEP_TIMEOUT_MASK,
5105981f4e6SSundar R Iyer 			timeout);
5115981f4e6SSundar R Iyer 	if (ret < 0)
5125981f4e6SSundar R Iyer 		return ret;
5135981f4e6SSundar R Iyer 
5145981f4e6SSundar R Iyer 	return __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL2,
5155981f4e6SSundar R Iyer 			STPME1601_AUTOSLEEP_ENABLE,
5165981f4e6SSundar R Iyer 			STPME1601_AUTOSLEEP_ENABLE);
5175981f4e6SSundar R Iyer }
5185981f4e6SSundar R Iyer 
51927e34995SRabin Vincent static int stmpe1601_enable(struct stmpe *stmpe, unsigned int blocks,
52027e34995SRabin Vincent 			    bool enable)
52127e34995SRabin Vincent {
52227e34995SRabin Vincent 	unsigned int mask = 0;
52327e34995SRabin Vincent 
52427e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_GPIO)
52527e34995SRabin Vincent 		mask |= STMPE1601_SYS_CTRL_ENABLE_GPIO;
52627e34995SRabin Vincent 
52727e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_KEYPAD)
52827e34995SRabin Vincent 		mask |= STMPE1601_SYS_CTRL_ENABLE_KPC;
52927e34995SRabin Vincent 
53027e34995SRabin Vincent 	return __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL, mask,
53127e34995SRabin Vincent 				enable ? mask : 0);
53227e34995SRabin Vincent }
53327e34995SRabin Vincent 
53427e34995SRabin Vincent static int stmpe1601_get_altfunc(struct stmpe *stmpe, enum stmpe_block block)
53527e34995SRabin Vincent {
53627e34995SRabin Vincent 	switch (block) {
53727e34995SRabin Vincent 	case STMPE_BLOCK_PWM:
53827e34995SRabin Vincent 		return 2;
53927e34995SRabin Vincent 
54027e34995SRabin Vincent 	case STMPE_BLOCK_KEYPAD:
54127e34995SRabin Vincent 		return 1;
54227e34995SRabin Vincent 
54327e34995SRabin Vincent 	case STMPE_BLOCK_GPIO:
54427e34995SRabin Vincent 	default:
54527e34995SRabin Vincent 		return 0;
54627e34995SRabin Vincent 	}
54727e34995SRabin Vincent }
54827e34995SRabin Vincent 
54927e34995SRabin Vincent static struct stmpe_variant_info stmpe1601 = {
55027e34995SRabin Vincent 	.name		= "stmpe1601",
55127e34995SRabin Vincent 	.id_val		= 0x0210,
55227e34995SRabin Vincent 	.id_mask	= 0xfff0,	/* at least 0x0210 and 0x0212 */
55327e34995SRabin Vincent 	.num_gpios	= 16,
55427e34995SRabin Vincent 	.af_bits	= 2,
55527e34995SRabin Vincent 	.regs		= stmpe1601_regs,
55627e34995SRabin Vincent 	.blocks		= stmpe1601_blocks,
55727e34995SRabin Vincent 	.num_blocks	= ARRAY_SIZE(stmpe1601_blocks),
55827e34995SRabin Vincent 	.num_irqs	= STMPE1601_NR_INTERNAL_IRQS,
55927e34995SRabin Vincent 	.enable		= stmpe1601_enable,
56027e34995SRabin Vincent 	.get_altfunc	= stmpe1601_get_altfunc,
5615981f4e6SSundar R Iyer 	.enable_autosleep	= stmpe1601_autosleep,
56227e34995SRabin Vincent };
56327e34995SRabin Vincent 
56427e34995SRabin Vincent /*
56527e34995SRabin Vincent  * STMPE24XX
56627e34995SRabin Vincent  */
56727e34995SRabin Vincent 
56827e34995SRabin Vincent static const u8 stmpe24xx_regs[] = {
56927e34995SRabin Vincent 	[STMPE_IDX_CHIP_ID]	= STMPE24XX_REG_CHIP_ID,
57027e34995SRabin Vincent 	[STMPE_IDX_ICR_LSB]	= STMPE24XX_REG_ICR_LSB,
57127e34995SRabin Vincent 	[STMPE_IDX_IER_LSB]	= STMPE24XX_REG_IER_LSB,
57227e34995SRabin Vincent 	[STMPE_IDX_ISR_MSB]	= STMPE24XX_REG_ISR_MSB,
57327e34995SRabin Vincent 	[STMPE_IDX_GPMR_LSB]	= STMPE24XX_REG_GPMR_LSB,
57427e34995SRabin Vincent 	[STMPE_IDX_GPSR_LSB]	= STMPE24XX_REG_GPSR_LSB,
57527e34995SRabin Vincent 	[STMPE_IDX_GPCR_LSB]	= STMPE24XX_REG_GPCR_LSB,
57627e34995SRabin Vincent 	[STMPE_IDX_GPDR_LSB]	= STMPE24XX_REG_GPDR_LSB,
57727e34995SRabin Vincent 	[STMPE_IDX_GPRER_LSB]	= STMPE24XX_REG_GPRER_LSB,
57827e34995SRabin Vincent 	[STMPE_IDX_GPFER_LSB]	= STMPE24XX_REG_GPFER_LSB,
57927e34995SRabin Vincent 	[STMPE_IDX_GPAFR_U_MSB]	= STMPE24XX_REG_GPAFR_U_MSB,
58027e34995SRabin Vincent 	[STMPE_IDX_IEGPIOR_LSB]	= STMPE24XX_REG_IEGPIOR_LSB,
58127e34995SRabin Vincent 	[STMPE_IDX_ISGPIOR_MSB]	= STMPE24XX_REG_ISGPIOR_MSB,
58227e34995SRabin Vincent 	[STMPE_IDX_GPEDR_MSB]	= STMPE24XX_REG_GPEDR_MSB,
58327e34995SRabin Vincent };
58427e34995SRabin Vincent 
58527e34995SRabin Vincent static struct stmpe_variant_block stmpe24xx_blocks[] = {
58627e34995SRabin Vincent 	{
58727e34995SRabin Vincent 		.cell	= &stmpe_gpio_cell,
58827e34995SRabin Vincent 		.irq	= STMPE24XX_IRQ_GPIOC,
58927e34995SRabin Vincent 		.block	= STMPE_BLOCK_GPIO,
59027e34995SRabin Vincent 	},
59127e34995SRabin Vincent 	{
59227e34995SRabin Vincent 		.cell	= &stmpe_keypad_cell,
59327e34995SRabin Vincent 		.irq	= STMPE24XX_IRQ_KEYPAD,
59427e34995SRabin Vincent 		.block	= STMPE_BLOCK_KEYPAD,
59527e34995SRabin Vincent 	},
59627e34995SRabin Vincent };
59727e34995SRabin Vincent 
59827e34995SRabin Vincent static int stmpe24xx_enable(struct stmpe *stmpe, unsigned int blocks,
59927e34995SRabin Vincent 			    bool enable)
60027e34995SRabin Vincent {
60127e34995SRabin Vincent 	unsigned int mask = 0;
60227e34995SRabin Vincent 
60327e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_GPIO)
60427e34995SRabin Vincent 		mask |= STMPE24XX_SYS_CTRL_ENABLE_GPIO;
60527e34995SRabin Vincent 
60627e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_KEYPAD)
60727e34995SRabin Vincent 		mask |= STMPE24XX_SYS_CTRL_ENABLE_KPC;
60827e34995SRabin Vincent 
60927e34995SRabin Vincent 	return __stmpe_set_bits(stmpe, STMPE24XX_REG_SYS_CTRL, mask,
61027e34995SRabin Vincent 				enable ? mask : 0);
61127e34995SRabin Vincent }
61227e34995SRabin Vincent 
61327e34995SRabin Vincent static int stmpe24xx_get_altfunc(struct stmpe *stmpe, enum stmpe_block block)
61427e34995SRabin Vincent {
61527e34995SRabin Vincent 	switch (block) {
61627e34995SRabin Vincent 	case STMPE_BLOCK_ROTATOR:
61727e34995SRabin Vincent 		return 2;
61827e34995SRabin Vincent 
61927e34995SRabin Vincent 	case STMPE_BLOCK_KEYPAD:
62027e34995SRabin Vincent 		return 1;
62127e34995SRabin Vincent 
62227e34995SRabin Vincent 	case STMPE_BLOCK_GPIO:
62327e34995SRabin Vincent 	default:
62427e34995SRabin Vincent 		return 0;
62527e34995SRabin Vincent 	}
62627e34995SRabin Vincent }
62727e34995SRabin Vincent 
62827e34995SRabin Vincent static struct stmpe_variant_info stmpe2401 = {
62927e34995SRabin Vincent 	.name		= "stmpe2401",
63027e34995SRabin Vincent 	.id_val		= 0x0101,
63127e34995SRabin Vincent 	.id_mask	= 0xffff,
63227e34995SRabin Vincent 	.num_gpios	= 24,
63327e34995SRabin Vincent 	.af_bits	= 2,
63427e34995SRabin Vincent 	.regs		= stmpe24xx_regs,
63527e34995SRabin Vincent 	.blocks		= stmpe24xx_blocks,
63627e34995SRabin Vincent 	.num_blocks	= ARRAY_SIZE(stmpe24xx_blocks),
63727e34995SRabin Vincent 	.num_irqs	= STMPE24XX_NR_INTERNAL_IRQS,
63827e34995SRabin Vincent 	.enable		= stmpe24xx_enable,
63927e34995SRabin Vincent 	.get_altfunc	= stmpe24xx_get_altfunc,
64027e34995SRabin Vincent };
64127e34995SRabin Vincent 
64227e34995SRabin Vincent static struct stmpe_variant_info stmpe2403 = {
64327e34995SRabin Vincent 	.name		= "stmpe2403",
64427e34995SRabin Vincent 	.id_val		= 0x0120,
64527e34995SRabin Vincent 	.id_mask	= 0xffff,
64627e34995SRabin Vincent 	.num_gpios	= 24,
64727e34995SRabin Vincent 	.af_bits	= 2,
64827e34995SRabin Vincent 	.regs		= stmpe24xx_regs,
64927e34995SRabin Vincent 	.blocks		= stmpe24xx_blocks,
65027e34995SRabin Vincent 	.num_blocks	= ARRAY_SIZE(stmpe24xx_blocks),
65127e34995SRabin Vincent 	.num_irqs	= STMPE24XX_NR_INTERNAL_IRQS,
65227e34995SRabin Vincent 	.enable		= stmpe24xx_enable,
65327e34995SRabin Vincent 	.get_altfunc	= stmpe24xx_get_altfunc,
6545981f4e6SSundar R Iyer 	.enable_autosleep	= stmpe1601_autosleep, /* same as stmpe1601 */
65527e34995SRabin Vincent };
65627e34995SRabin Vincent 
65727e34995SRabin Vincent static struct stmpe_variant_info *stmpe_variant_info[] = {
65827e34995SRabin Vincent 	[STMPE811]	= &stmpe811,
65927e34995SRabin Vincent 	[STMPE1601]	= &stmpe1601,
66027e34995SRabin Vincent 	[STMPE2401]	= &stmpe2401,
66127e34995SRabin Vincent 	[STMPE2403]	= &stmpe2403,
66227e34995SRabin Vincent };
66327e34995SRabin Vincent 
66427e34995SRabin Vincent static irqreturn_t stmpe_irq(int irq, void *data)
66527e34995SRabin Vincent {
66627e34995SRabin Vincent 	struct stmpe *stmpe = data;
66727e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
66827e34995SRabin Vincent 	int num = DIV_ROUND_UP(variant->num_irqs, 8);
66927e34995SRabin Vincent 	u8 israddr = stmpe->regs[STMPE_IDX_ISR_MSB];
67027e34995SRabin Vincent 	u8 isr[num];
67127e34995SRabin Vincent 	int ret;
67227e34995SRabin Vincent 	int i;
67327e34995SRabin Vincent 
67427e34995SRabin Vincent 	ret = stmpe_block_read(stmpe, israddr, num, isr);
67527e34995SRabin Vincent 	if (ret < 0)
67627e34995SRabin Vincent 		return IRQ_NONE;
67727e34995SRabin Vincent 
67827e34995SRabin Vincent 	for (i = 0; i < num; i++) {
67927e34995SRabin Vincent 		int bank = num - i - 1;
68027e34995SRabin Vincent 		u8 status = isr[i];
68127e34995SRabin Vincent 		u8 clear;
68227e34995SRabin Vincent 
68327e34995SRabin Vincent 		status &= stmpe->ier[bank];
68427e34995SRabin Vincent 		if (!status)
68527e34995SRabin Vincent 			continue;
68627e34995SRabin Vincent 
68727e34995SRabin Vincent 		clear = status;
68827e34995SRabin Vincent 		while (status) {
68927e34995SRabin Vincent 			int bit = __ffs(status);
69027e34995SRabin Vincent 			int line = bank * 8 + bit;
69127e34995SRabin Vincent 
69227e34995SRabin Vincent 			handle_nested_irq(stmpe->irq_base + line);
69327e34995SRabin Vincent 			status &= ~(1 << bit);
69427e34995SRabin Vincent 		}
69527e34995SRabin Vincent 
69627e34995SRabin Vincent 		stmpe_reg_write(stmpe, israddr + i, clear);
69727e34995SRabin Vincent 	}
69827e34995SRabin Vincent 
69927e34995SRabin Vincent 	return IRQ_HANDLED;
70027e34995SRabin Vincent }
70127e34995SRabin Vincent 
70243b8c084SMark Brown static void stmpe_irq_lock(struct irq_data *data)
70327e34995SRabin Vincent {
70443b8c084SMark Brown 	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
70527e34995SRabin Vincent 
70627e34995SRabin Vincent 	mutex_lock(&stmpe->irq_lock);
70727e34995SRabin Vincent }
70827e34995SRabin Vincent 
70943b8c084SMark Brown static void stmpe_irq_sync_unlock(struct irq_data *data)
71027e34995SRabin Vincent {
71143b8c084SMark Brown 	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
71227e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
71327e34995SRabin Vincent 	int num = DIV_ROUND_UP(variant->num_irqs, 8);
71427e34995SRabin Vincent 	int i;
71527e34995SRabin Vincent 
71627e34995SRabin Vincent 	for (i = 0; i < num; i++) {
71727e34995SRabin Vincent 		u8 new = stmpe->ier[i];
71827e34995SRabin Vincent 		u8 old = stmpe->oldier[i];
71927e34995SRabin Vincent 
72027e34995SRabin Vincent 		if (new == old)
72127e34995SRabin Vincent 			continue;
72227e34995SRabin Vincent 
72327e34995SRabin Vincent 		stmpe->oldier[i] = new;
72427e34995SRabin Vincent 		stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_IER_LSB] - i, new);
72527e34995SRabin Vincent 	}
72627e34995SRabin Vincent 
72727e34995SRabin Vincent 	mutex_unlock(&stmpe->irq_lock);
72827e34995SRabin Vincent }
72927e34995SRabin Vincent 
73043b8c084SMark Brown static void stmpe_irq_mask(struct irq_data *data)
73127e34995SRabin Vincent {
73243b8c084SMark Brown 	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
73343b8c084SMark Brown 	int offset = data->irq - stmpe->irq_base;
73427e34995SRabin Vincent 	int regoffset = offset / 8;
73527e34995SRabin Vincent 	int mask = 1 << (offset % 8);
73627e34995SRabin Vincent 
73727e34995SRabin Vincent 	stmpe->ier[regoffset] &= ~mask;
73827e34995SRabin Vincent }
73927e34995SRabin Vincent 
74043b8c084SMark Brown static void stmpe_irq_unmask(struct irq_data *data)
74127e34995SRabin Vincent {
74243b8c084SMark Brown 	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
74343b8c084SMark Brown 	int offset = data->irq - stmpe->irq_base;
74427e34995SRabin Vincent 	int regoffset = offset / 8;
74527e34995SRabin Vincent 	int mask = 1 << (offset % 8);
74627e34995SRabin Vincent 
74727e34995SRabin Vincent 	stmpe->ier[regoffset] |= mask;
74827e34995SRabin Vincent }
74927e34995SRabin Vincent 
75027e34995SRabin Vincent static struct irq_chip stmpe_irq_chip = {
75127e34995SRabin Vincent 	.name			= "stmpe",
75243b8c084SMark Brown 	.irq_bus_lock		= stmpe_irq_lock,
75343b8c084SMark Brown 	.irq_bus_sync_unlock	= stmpe_irq_sync_unlock,
75443b8c084SMark Brown 	.irq_mask		= stmpe_irq_mask,
75543b8c084SMark Brown 	.irq_unmask		= stmpe_irq_unmask,
75627e34995SRabin Vincent };
75727e34995SRabin Vincent 
75827e34995SRabin Vincent static int __devinit stmpe_irq_init(struct stmpe *stmpe)
75927e34995SRabin Vincent {
76027e34995SRabin Vincent 	int num_irqs = stmpe->variant->num_irqs;
76127e34995SRabin Vincent 	int base = stmpe->irq_base;
76227e34995SRabin Vincent 	int irq;
76327e34995SRabin Vincent 
76427e34995SRabin Vincent 	for (irq = base; irq < base + num_irqs; irq++) {
76527e34995SRabin Vincent 		set_irq_chip_data(irq, stmpe);
76627e34995SRabin Vincent 		set_irq_chip_and_handler(irq, &stmpe_irq_chip,
76727e34995SRabin Vincent 					 handle_edge_irq);
76827e34995SRabin Vincent 		set_irq_nested_thread(irq, 1);
76927e34995SRabin Vincent #ifdef CONFIG_ARM
77027e34995SRabin Vincent 		set_irq_flags(irq, IRQF_VALID);
77127e34995SRabin Vincent #else
77227e34995SRabin Vincent 		set_irq_noprobe(irq);
77327e34995SRabin Vincent #endif
77427e34995SRabin Vincent 	}
77527e34995SRabin Vincent 
77627e34995SRabin Vincent 	return 0;
77727e34995SRabin Vincent }
77827e34995SRabin Vincent 
77927e34995SRabin Vincent static void stmpe_irq_remove(struct stmpe *stmpe)
78027e34995SRabin Vincent {
78127e34995SRabin Vincent 	int num_irqs = stmpe->variant->num_irqs;
78227e34995SRabin Vincent 	int base = stmpe->irq_base;
78327e34995SRabin Vincent 	int irq;
78427e34995SRabin Vincent 
78527e34995SRabin Vincent 	for (irq = base; irq < base + num_irqs; irq++) {
78627e34995SRabin Vincent #ifdef CONFIG_ARM
78727e34995SRabin Vincent 		set_irq_flags(irq, 0);
78827e34995SRabin Vincent #endif
78927e34995SRabin Vincent 		set_irq_chip_and_handler(irq, NULL, NULL);
79027e34995SRabin Vincent 		set_irq_chip_data(irq, NULL);
79127e34995SRabin Vincent 	}
79227e34995SRabin Vincent }
79327e34995SRabin Vincent 
79427e34995SRabin Vincent static int __devinit stmpe_chip_init(struct stmpe *stmpe)
79527e34995SRabin Vincent {
79627e34995SRabin Vincent 	unsigned int irq_trigger = stmpe->pdata->irq_trigger;
7975981f4e6SSundar R Iyer 	int autosleep_timeout = stmpe->pdata->autosleep_timeout;
79827e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
79927e34995SRabin Vincent 	u8 icr = STMPE_ICR_LSB_GIM;
80027e34995SRabin Vincent 	unsigned int id;
80127e34995SRabin Vincent 	u8 data[2];
80227e34995SRabin Vincent 	int ret;
80327e34995SRabin Vincent 
80427e34995SRabin Vincent 	ret = stmpe_block_read(stmpe, stmpe->regs[STMPE_IDX_CHIP_ID],
80527e34995SRabin Vincent 			       ARRAY_SIZE(data), data);
80627e34995SRabin Vincent 	if (ret < 0)
80727e34995SRabin Vincent 		return ret;
80827e34995SRabin Vincent 
80927e34995SRabin Vincent 	id = (data[0] << 8) | data[1];
81027e34995SRabin Vincent 	if ((id & variant->id_mask) != variant->id_val) {
81127e34995SRabin Vincent 		dev_err(stmpe->dev, "unknown chip id: %#x\n", id);
81227e34995SRabin Vincent 		return -EINVAL;
81327e34995SRabin Vincent 	}
81427e34995SRabin Vincent 
81527e34995SRabin Vincent 	dev_info(stmpe->dev, "%s detected, chip id: %#x\n", variant->name, id);
81627e34995SRabin Vincent 
81727e34995SRabin Vincent 	/* Disable all modules -- subdrivers should enable what they need. */
81827e34995SRabin Vincent 	ret = stmpe_disable(stmpe, ~0);
81927e34995SRabin Vincent 	if (ret)
82027e34995SRabin Vincent 		return ret;
82127e34995SRabin Vincent 
82227e34995SRabin Vincent 	if (irq_trigger == IRQF_TRIGGER_FALLING ||
82327e34995SRabin Vincent 	    irq_trigger == IRQF_TRIGGER_RISING)
82427e34995SRabin Vincent 		icr |= STMPE_ICR_LSB_EDGE;
82527e34995SRabin Vincent 
82627e34995SRabin Vincent 	if (irq_trigger == IRQF_TRIGGER_RISING ||
82727e34995SRabin Vincent 	    irq_trigger == IRQF_TRIGGER_HIGH)
82827e34995SRabin Vincent 		icr |= STMPE_ICR_LSB_HIGH;
82927e34995SRabin Vincent 
83027e34995SRabin Vincent 	if (stmpe->pdata->irq_invert_polarity)
83127e34995SRabin Vincent 		icr ^= STMPE_ICR_LSB_HIGH;
83227e34995SRabin Vincent 
8335981f4e6SSundar R Iyer 	if (stmpe->pdata->autosleep) {
8345981f4e6SSundar R Iyer 		ret = stmpe_autosleep(stmpe, autosleep_timeout);
8355981f4e6SSundar R Iyer 		if (ret)
8365981f4e6SSundar R Iyer 			return ret;
8375981f4e6SSundar R Iyer 	}
8385981f4e6SSundar R Iyer 
83927e34995SRabin Vincent 	return stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_ICR_LSB], icr);
84027e34995SRabin Vincent }
84127e34995SRabin Vincent 
84227e34995SRabin Vincent static int __devinit stmpe_add_device(struct stmpe *stmpe,
84327e34995SRabin Vincent 				      struct mfd_cell *cell, int irq)
84427e34995SRabin Vincent {
84527e34995SRabin Vincent 	return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1,
84627e34995SRabin Vincent 			       NULL, stmpe->irq_base + irq);
84727e34995SRabin Vincent }
84827e34995SRabin Vincent 
84927e34995SRabin Vincent static int __devinit stmpe_devices_init(struct stmpe *stmpe)
85027e34995SRabin Vincent {
85127e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
85227e34995SRabin Vincent 	unsigned int platform_blocks = stmpe->pdata->blocks;
85327e34995SRabin Vincent 	int ret = -EINVAL;
85427e34995SRabin Vincent 	int i;
85527e34995SRabin Vincent 
85627e34995SRabin Vincent 	for (i = 0; i < variant->num_blocks; i++) {
85727e34995SRabin Vincent 		struct stmpe_variant_block *block = &variant->blocks[i];
85827e34995SRabin Vincent 
85927e34995SRabin Vincent 		if (!(platform_blocks & block->block))
86027e34995SRabin Vincent 			continue;
86127e34995SRabin Vincent 
86227e34995SRabin Vincent 		platform_blocks &= ~block->block;
86327e34995SRabin Vincent 		ret = stmpe_add_device(stmpe, block->cell, block->irq);
86427e34995SRabin Vincent 		if (ret)
86527e34995SRabin Vincent 			return ret;
86627e34995SRabin Vincent 	}
86727e34995SRabin Vincent 
86827e34995SRabin Vincent 	if (platform_blocks)
86927e34995SRabin Vincent 		dev_warn(stmpe->dev,
87027e34995SRabin Vincent 			 "platform wants blocks (%#x) not present on variant",
87127e34995SRabin Vincent 			 platform_blocks);
87227e34995SRabin Vincent 
87327e34995SRabin Vincent 	return ret;
87427e34995SRabin Vincent }
87527e34995SRabin Vincent 
876208c4343SSundar Iyer #ifdef CONFIG_PM
877208c4343SSundar Iyer static int stmpe_suspend(struct device *dev)
878208c4343SSundar Iyer {
879208c4343SSundar Iyer 	struct i2c_client *i2c = to_i2c_client(dev);
880208c4343SSundar Iyer 
881208c4343SSundar Iyer 	if (device_may_wakeup(&i2c->dev))
882208c4343SSundar Iyer 		enable_irq_wake(i2c->irq);
883208c4343SSundar Iyer 
884208c4343SSundar Iyer 	return 0;
885208c4343SSundar Iyer }
886208c4343SSundar Iyer 
887208c4343SSundar Iyer static int stmpe_resume(struct device *dev)
888208c4343SSundar Iyer {
889208c4343SSundar Iyer 	struct i2c_client *i2c = to_i2c_client(dev);
890208c4343SSundar Iyer 
891208c4343SSundar Iyer 	if (device_may_wakeup(&i2c->dev))
892208c4343SSundar Iyer 		disable_irq_wake(i2c->irq);
893208c4343SSundar Iyer 
894208c4343SSundar Iyer 	return 0;
895208c4343SSundar Iyer }
896208c4343SSundar Iyer #endif
897208c4343SSundar Iyer 
89827e34995SRabin Vincent static int __devinit stmpe_probe(struct i2c_client *i2c,
89927e34995SRabin Vincent 				 const struct i2c_device_id *id)
90027e34995SRabin Vincent {
90127e34995SRabin Vincent 	struct stmpe_platform_data *pdata = i2c->dev.platform_data;
90227e34995SRabin Vincent 	struct stmpe *stmpe;
90327e34995SRabin Vincent 	int ret;
90427e34995SRabin Vincent 
90527e34995SRabin Vincent 	if (!pdata)
90627e34995SRabin Vincent 		return -EINVAL;
90727e34995SRabin Vincent 
90827e34995SRabin Vincent 	stmpe = kzalloc(sizeof(struct stmpe), GFP_KERNEL);
90927e34995SRabin Vincent 	if (!stmpe)
91027e34995SRabin Vincent 		return -ENOMEM;
91127e34995SRabin Vincent 
91227e34995SRabin Vincent 	mutex_init(&stmpe->irq_lock);
91327e34995SRabin Vincent 	mutex_init(&stmpe->lock);
91427e34995SRabin Vincent 
91527e34995SRabin Vincent 	stmpe->dev = &i2c->dev;
91627e34995SRabin Vincent 	stmpe->i2c = i2c;
91727e34995SRabin Vincent 
91827e34995SRabin Vincent 	stmpe->pdata = pdata;
91927e34995SRabin Vincent 	stmpe->irq_base = pdata->irq_base;
92027e34995SRabin Vincent 
92127e34995SRabin Vincent 	stmpe->partnum = id->driver_data;
92227e34995SRabin Vincent 	stmpe->variant = stmpe_variant_info[stmpe->partnum];
92327e34995SRabin Vincent 	stmpe->regs = stmpe->variant->regs;
92427e34995SRabin Vincent 	stmpe->num_gpios = stmpe->variant->num_gpios;
92527e34995SRabin Vincent 
92627e34995SRabin Vincent 	i2c_set_clientdata(i2c, stmpe);
92727e34995SRabin Vincent 
92827e34995SRabin Vincent 	ret = stmpe_chip_init(stmpe);
92927e34995SRabin Vincent 	if (ret)
93027e34995SRabin Vincent 		goto out_free;
93127e34995SRabin Vincent 
93227e34995SRabin Vincent 	ret = stmpe_irq_init(stmpe);
93327e34995SRabin Vincent 	if (ret)
93427e34995SRabin Vincent 		goto out_free;
93527e34995SRabin Vincent 
93627e34995SRabin Vincent 	ret = request_threaded_irq(stmpe->i2c->irq, NULL, stmpe_irq,
93727e34995SRabin Vincent 				   pdata->irq_trigger | IRQF_ONESHOT,
93827e34995SRabin Vincent 				   "stmpe", stmpe);
93927e34995SRabin Vincent 	if (ret) {
94027e34995SRabin Vincent 		dev_err(stmpe->dev, "failed to request IRQ: %d\n", ret);
94127e34995SRabin Vincent 		goto out_removeirq;
94227e34995SRabin Vincent 	}
94327e34995SRabin Vincent 
94427e34995SRabin Vincent 	ret = stmpe_devices_init(stmpe);
94527e34995SRabin Vincent 	if (ret) {
94627e34995SRabin Vincent 		dev_err(stmpe->dev, "failed to add children\n");
94727e34995SRabin Vincent 		goto out_removedevs;
94827e34995SRabin Vincent 	}
94927e34995SRabin Vincent 
95027e34995SRabin Vincent 	return 0;
95127e34995SRabin Vincent 
95227e34995SRabin Vincent out_removedevs:
95327e34995SRabin Vincent 	mfd_remove_devices(stmpe->dev);
95427e34995SRabin Vincent 	free_irq(stmpe->i2c->irq, stmpe);
95527e34995SRabin Vincent out_removeirq:
95627e34995SRabin Vincent 	stmpe_irq_remove(stmpe);
95727e34995SRabin Vincent out_free:
95827e34995SRabin Vincent 	kfree(stmpe);
95927e34995SRabin Vincent 	return ret;
96027e34995SRabin Vincent }
96127e34995SRabin Vincent 
96227e34995SRabin Vincent static int __devexit stmpe_remove(struct i2c_client *client)
96327e34995SRabin Vincent {
96427e34995SRabin Vincent 	struct stmpe *stmpe = i2c_get_clientdata(client);
96527e34995SRabin Vincent 
96627e34995SRabin Vincent 	mfd_remove_devices(stmpe->dev);
96727e34995SRabin Vincent 
96827e34995SRabin Vincent 	free_irq(stmpe->i2c->irq, stmpe);
96927e34995SRabin Vincent 	stmpe_irq_remove(stmpe);
97027e34995SRabin Vincent 
97127e34995SRabin Vincent 	kfree(stmpe);
97227e34995SRabin Vincent 
97327e34995SRabin Vincent 	return 0;
97427e34995SRabin Vincent }
97527e34995SRabin Vincent 
97627e34995SRabin Vincent static const struct i2c_device_id stmpe_id[] = {
97727e34995SRabin Vincent 	{ "stmpe811", STMPE811 },
97827e34995SRabin Vincent 	{ "stmpe1601", STMPE1601 },
97927e34995SRabin Vincent 	{ "stmpe2401", STMPE2401 },
98027e34995SRabin Vincent 	{ "stmpe2403", STMPE2403 },
98127e34995SRabin Vincent 	{ }
98227e34995SRabin Vincent };
98327e34995SRabin Vincent MODULE_DEVICE_TABLE(i2c, stmpe_id);
98427e34995SRabin Vincent 
985208c4343SSundar Iyer #ifdef CONFIG_PM
986208c4343SSundar Iyer static const struct dev_pm_ops stmpe_dev_pm_ops = {
987208c4343SSundar Iyer 	.suspend	= stmpe_suspend,
988208c4343SSundar Iyer 	.resume		= stmpe_resume,
989208c4343SSundar Iyer };
990208c4343SSundar Iyer #endif
991208c4343SSundar Iyer 
99227e34995SRabin Vincent static struct i2c_driver stmpe_driver = {
99327e34995SRabin Vincent 	.driver.name	= "stmpe",
99427e34995SRabin Vincent 	.driver.owner	= THIS_MODULE,
995208c4343SSundar Iyer #ifdef CONFIG_PM
996208c4343SSundar Iyer 	.driver.pm	= &stmpe_dev_pm_ops,
997208c4343SSundar Iyer #endif
99827e34995SRabin Vincent 	.probe		= stmpe_probe,
99927e34995SRabin Vincent 	.remove		= __devexit_p(stmpe_remove),
100027e34995SRabin Vincent 	.id_table	= stmpe_id,
100127e34995SRabin Vincent };
100227e34995SRabin Vincent 
100327e34995SRabin Vincent static int __init stmpe_init(void)
100427e34995SRabin Vincent {
100527e34995SRabin Vincent 	return i2c_add_driver(&stmpe_driver);
100627e34995SRabin Vincent }
100727e34995SRabin Vincent subsys_initcall(stmpe_init);
100827e34995SRabin Vincent 
100927e34995SRabin Vincent static void __exit stmpe_exit(void)
101027e34995SRabin Vincent {
101127e34995SRabin Vincent 	i2c_del_driver(&stmpe_driver);
101227e34995SRabin Vincent }
101327e34995SRabin Vincent module_exit(stmpe_exit);
101427e34995SRabin Vincent 
101527e34995SRabin Vincent MODULE_LICENSE("GPL v2");
101627e34995SRabin Vincent MODULE_DESCRIPTION("STMPE MFD core driver");
101727e34995SRabin Vincent MODULE_AUTHOR("Rabin Vincent <rabin.vincent@stericsson.com>");
1018