xref: /openbmc/linux/drivers/mfd/stmpe.c (revision 9ff80e2d)
11f67b599SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
227e34995SRabin Vincent /*
31a6e4b74SViresh Kumar  * ST Microelectronics MFD: stmpe's driver
41a6e4b74SViresh Kumar  *
527e34995SRabin Vincent  * Copyright (C) ST-Ericsson SA 2010
627e34995SRabin Vincent  *
727e34995SRabin Vincent  * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
827e34995SRabin Vincent  */
927e34995SRabin Vincent 
10ac713cc9SVipul 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>
18ac713cc9SVipul 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>
22230f13a5SJean-Nicolas Graux #include <linux/delay.h>
239c9e3214SLinus Walleij #include <linux/regulator/consumer.h>
2427e34995SRabin Vincent #include "stmpe.h"
2527e34995SRabin Vincent 
26fc1882dcSLinus Walleij /**
27fc1882dcSLinus Walleij  * struct stmpe_platform_data - STMPE platform data
28fc1882dcSLinus Walleij  * @id: device id to distinguish between multiple STMPEs on the same board
29fc1882dcSLinus Walleij  * @blocks: bitmask of blocks to enable (use STMPE_BLOCK_*)
30fc1882dcSLinus Walleij  * @irq_trigger: IRQ trigger to use for the interrupt to the host
31fc1882dcSLinus Walleij  * @autosleep: bool to enable/disable stmpe autosleep
32fc1882dcSLinus Walleij  * @autosleep_timeout: inactivity timeout in milliseconds for autosleep
33fc1882dcSLinus Walleij  * @irq_over_gpio: true if gpio is used to get irq
34fc1882dcSLinus Walleij  * @irq_gpio: gpio number over which irq will be requested (significant only if
35fc1882dcSLinus Walleij  *	      irq_over_gpio is true)
36fc1882dcSLinus Walleij  */
37fc1882dcSLinus Walleij struct stmpe_platform_data {
38fc1882dcSLinus Walleij 	int id;
39fc1882dcSLinus Walleij 	unsigned int blocks;
40fc1882dcSLinus Walleij 	unsigned int irq_trigger;
41fc1882dcSLinus Walleij 	bool autosleep;
42fc1882dcSLinus Walleij 	bool irq_over_gpio;
43fc1882dcSLinus Walleij 	int irq_gpio;
44fc1882dcSLinus Walleij 	int autosleep_timeout;
45fc1882dcSLinus Walleij };
46fc1882dcSLinus Walleij 
4727e34995SRabin Vincent static int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks)
4827e34995SRabin Vincent {
4927e34995SRabin Vincent 	return stmpe->variant->enable(stmpe, blocks, true);
5027e34995SRabin Vincent }
5127e34995SRabin Vincent 
5227e34995SRabin Vincent static int __stmpe_disable(struct stmpe *stmpe, unsigned int blocks)
5327e34995SRabin Vincent {
5427e34995SRabin Vincent 	return stmpe->variant->enable(stmpe, blocks, false);
5527e34995SRabin Vincent }
5627e34995SRabin Vincent 
5727e34995SRabin Vincent static int __stmpe_reg_read(struct stmpe *stmpe, u8 reg)
5827e34995SRabin Vincent {
5927e34995SRabin Vincent 	int ret;
6027e34995SRabin Vincent 
611a6e4b74SViresh Kumar 	ret = stmpe->ci->read_byte(stmpe, reg);
6227e34995SRabin Vincent 	if (ret < 0)
631a6e4b74SViresh Kumar 		dev_err(stmpe->dev, "failed to read reg %#x: %d\n", reg, ret);
6427e34995SRabin Vincent 
6527e34995SRabin Vincent 	dev_vdbg(stmpe->dev, "rd: reg %#x => data %#x\n", reg, ret);
6627e34995SRabin Vincent 
6727e34995SRabin Vincent 	return ret;
6827e34995SRabin Vincent }
6927e34995SRabin Vincent 
7027e34995SRabin Vincent static int __stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val)
7127e34995SRabin Vincent {
7227e34995SRabin Vincent 	int ret;
7327e34995SRabin Vincent 
7427e34995SRabin Vincent 	dev_vdbg(stmpe->dev, "wr: reg %#x <= %#x\n", reg, val);
7527e34995SRabin Vincent 
761a6e4b74SViresh Kumar 	ret = stmpe->ci->write_byte(stmpe, reg, val);
7727e34995SRabin Vincent 	if (ret < 0)
781a6e4b74SViresh Kumar 		dev_err(stmpe->dev, "failed to write reg %#x: %d\n", reg, ret);
7927e34995SRabin Vincent 
8027e34995SRabin Vincent 	return ret;
8127e34995SRabin Vincent }
8227e34995SRabin Vincent 
8327e34995SRabin Vincent static int __stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val)
8427e34995SRabin Vincent {
8527e34995SRabin Vincent 	int ret;
8627e34995SRabin Vincent 
8727e34995SRabin Vincent 	ret = __stmpe_reg_read(stmpe, reg);
8827e34995SRabin Vincent 	if (ret < 0)
8927e34995SRabin Vincent 		return ret;
9027e34995SRabin Vincent 
9127e34995SRabin Vincent 	ret &= ~mask;
9227e34995SRabin Vincent 	ret |= val;
9327e34995SRabin Vincent 
9427e34995SRabin Vincent 	return __stmpe_reg_write(stmpe, reg, ret);
9527e34995SRabin Vincent }
9627e34995SRabin Vincent 
9727e34995SRabin Vincent static int __stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length,
9827e34995SRabin Vincent 			      u8 *values)
9927e34995SRabin Vincent {
10027e34995SRabin Vincent 	int ret;
10127e34995SRabin Vincent 
1021a6e4b74SViresh Kumar 	ret = stmpe->ci->read_block(stmpe, reg, length, values);
10327e34995SRabin Vincent 	if (ret < 0)
1041a6e4b74SViresh Kumar 		dev_err(stmpe->dev, "failed to read regs %#x: %d\n", reg, ret);
10527e34995SRabin Vincent 
10627e34995SRabin Vincent 	dev_vdbg(stmpe->dev, "rd: reg %#x (%d) => ret %#x\n", reg, length, ret);
10727e34995SRabin Vincent 	stmpe_dump_bytes("stmpe rd: ", values, length);
10827e34995SRabin Vincent 
10927e34995SRabin Vincent 	return ret;
11027e34995SRabin Vincent }
11127e34995SRabin Vincent 
11227e34995SRabin Vincent static int __stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length,
11327e34995SRabin Vincent 			const u8 *values)
11427e34995SRabin Vincent {
11527e34995SRabin Vincent 	int ret;
11627e34995SRabin Vincent 
11727e34995SRabin Vincent 	dev_vdbg(stmpe->dev, "wr: regs %#x (%d)\n", reg, length);
11827e34995SRabin Vincent 	stmpe_dump_bytes("stmpe wr: ", values, length);
11927e34995SRabin Vincent 
1201a6e4b74SViresh Kumar 	ret = stmpe->ci->write_block(stmpe, reg, length, values);
12127e34995SRabin Vincent 	if (ret < 0)
1221a6e4b74SViresh Kumar 		dev_err(stmpe->dev, "failed to write regs %#x: %d\n", reg, ret);
12327e34995SRabin Vincent 
12427e34995SRabin Vincent 	return ret;
12527e34995SRabin Vincent }
12627e34995SRabin Vincent 
12727e34995SRabin Vincent /**
12827e34995SRabin Vincent  * stmpe_enable - enable blocks on an STMPE device
12927e34995SRabin Vincent  * @stmpe:	Device to work on
13027e34995SRabin Vincent  * @blocks:	Mask of blocks (enum stmpe_block values) to enable
13127e34995SRabin Vincent  */
13227e34995SRabin Vincent int stmpe_enable(struct stmpe *stmpe, unsigned int blocks)
13327e34995SRabin Vincent {
13427e34995SRabin Vincent 	int ret;
13527e34995SRabin Vincent 
13627e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
13727e34995SRabin Vincent 	ret = __stmpe_enable(stmpe, blocks);
13827e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
13927e34995SRabin Vincent 
14027e34995SRabin Vincent 	return ret;
14127e34995SRabin Vincent }
14227e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_enable);
14327e34995SRabin Vincent 
14427e34995SRabin Vincent /**
14527e34995SRabin Vincent  * stmpe_disable - disable blocks on an STMPE device
14627e34995SRabin Vincent  * @stmpe:	Device to work on
14727e34995SRabin Vincent  * @blocks:	Mask of blocks (enum stmpe_block values) to enable
14827e34995SRabin Vincent  */
14927e34995SRabin Vincent int stmpe_disable(struct stmpe *stmpe, unsigned int blocks)
15027e34995SRabin Vincent {
15127e34995SRabin Vincent 	int ret;
15227e34995SRabin Vincent 
15327e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
15427e34995SRabin Vincent 	ret = __stmpe_disable(stmpe, blocks);
15527e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
15627e34995SRabin Vincent 
15727e34995SRabin Vincent 	return ret;
15827e34995SRabin Vincent }
15927e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_disable);
16027e34995SRabin Vincent 
16127e34995SRabin Vincent /**
16227e34995SRabin Vincent  * stmpe_reg_read() - read a single STMPE register
16327e34995SRabin Vincent  * @stmpe:	Device to read from
16427e34995SRabin Vincent  * @reg:	Register to read
16527e34995SRabin Vincent  */
16627e34995SRabin Vincent int stmpe_reg_read(struct stmpe *stmpe, u8 reg)
16727e34995SRabin Vincent {
16827e34995SRabin Vincent 	int ret;
16927e34995SRabin Vincent 
17027e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
17127e34995SRabin Vincent 	ret = __stmpe_reg_read(stmpe, reg);
17227e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
17327e34995SRabin Vincent 
17427e34995SRabin Vincent 	return ret;
17527e34995SRabin Vincent }
17627e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_reg_read);
17727e34995SRabin Vincent 
17827e34995SRabin Vincent /**
17927e34995SRabin Vincent  * stmpe_reg_write() - write a single STMPE register
18027e34995SRabin Vincent  * @stmpe:	Device to write to
18127e34995SRabin Vincent  * @reg:	Register to write
18227e34995SRabin Vincent  * @val:	Value to write
18327e34995SRabin Vincent  */
18427e34995SRabin Vincent int stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val)
18527e34995SRabin Vincent {
18627e34995SRabin Vincent 	int ret;
18727e34995SRabin Vincent 
18827e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
18927e34995SRabin Vincent 	ret = __stmpe_reg_write(stmpe, reg, val);
19027e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
19127e34995SRabin Vincent 
19227e34995SRabin Vincent 	return ret;
19327e34995SRabin Vincent }
19427e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_reg_write);
19527e34995SRabin Vincent 
19627e34995SRabin Vincent /**
19727e34995SRabin Vincent  * stmpe_set_bits() - set the value of a bitfield in a STMPE register
19827e34995SRabin Vincent  * @stmpe:	Device to write to
19927e34995SRabin Vincent  * @reg:	Register to write
20027e34995SRabin Vincent  * @mask:	Mask of bits to set
20127e34995SRabin Vincent  * @val:	Value to set
20227e34995SRabin Vincent  */
20327e34995SRabin Vincent int stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val)
20427e34995SRabin Vincent {
20527e34995SRabin Vincent 	int ret;
20627e34995SRabin Vincent 
20727e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
20827e34995SRabin Vincent 	ret = __stmpe_set_bits(stmpe, reg, mask, val);
20927e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
21027e34995SRabin Vincent 
21127e34995SRabin Vincent 	return ret;
21227e34995SRabin Vincent }
21327e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_set_bits);
21427e34995SRabin Vincent 
21527e34995SRabin Vincent /**
21627e34995SRabin Vincent  * stmpe_block_read() - read multiple STMPE registers
21727e34995SRabin Vincent  * @stmpe:	Device to read from
21827e34995SRabin Vincent  * @reg:	First register
21927e34995SRabin Vincent  * @length:	Number of registers
22027e34995SRabin Vincent  * @values:	Buffer to write to
22127e34995SRabin Vincent  */
22227e34995SRabin Vincent int stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values)
22327e34995SRabin Vincent {
22427e34995SRabin Vincent 	int ret;
22527e34995SRabin Vincent 
22627e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
22727e34995SRabin Vincent 	ret = __stmpe_block_read(stmpe, reg, length, values);
22827e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
22927e34995SRabin Vincent 
23027e34995SRabin Vincent 	return ret;
23127e34995SRabin Vincent }
23227e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_block_read);
23327e34995SRabin Vincent 
23427e34995SRabin Vincent /**
23527e34995SRabin Vincent  * stmpe_block_write() - write multiple STMPE registers
23627e34995SRabin Vincent  * @stmpe:	Device to write to
23727e34995SRabin Vincent  * @reg:	First register
23827e34995SRabin Vincent  * @length:	Number of registers
23927e34995SRabin Vincent  * @values:	Values to write
24027e34995SRabin Vincent  */
24127e34995SRabin Vincent int stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length,
24227e34995SRabin Vincent 		      const u8 *values)
24327e34995SRabin Vincent {
24427e34995SRabin Vincent 	int ret;
24527e34995SRabin Vincent 
24627e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
24727e34995SRabin Vincent 	ret = __stmpe_block_write(stmpe, reg, length, values);
24827e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
24927e34995SRabin Vincent 
25027e34995SRabin Vincent 	return ret;
25127e34995SRabin Vincent }
25227e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_block_write);
25327e34995SRabin Vincent 
25427e34995SRabin Vincent /**
2554dcaa6b6SOm Prakash  * stmpe_set_altfunc()- set the alternate function for STMPE pins
25627e34995SRabin Vincent  * @stmpe:	Device to configure
25727e34995SRabin Vincent  * @pins:	Bitmask of pins to affect
25827e34995SRabin Vincent  * @block:	block to enable alternate functions for
25927e34995SRabin Vincent  *
26027e34995SRabin Vincent  * @pins is assumed to have a bit set for each of the bits whose alternate
26127e34995SRabin Vincent  * function is to be changed, numbered according to the GPIOXY numbers.
26227e34995SRabin Vincent  *
26327e34995SRabin Vincent  * If the GPIO module is not enabled, this function automatically enables it in
26427e34995SRabin Vincent  * order to perform the change.
26527e34995SRabin Vincent  */
26627e34995SRabin Vincent int stmpe_set_altfunc(struct stmpe *stmpe, u32 pins, enum stmpe_block block)
26727e34995SRabin Vincent {
26827e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
26927e34995SRabin Vincent 	u8 regaddr = stmpe->regs[STMPE_IDX_GPAFR_U_MSB];
27027e34995SRabin Vincent 	int af_bits = variant->af_bits;
27127e34995SRabin Vincent 	int numregs = DIV_ROUND_UP(stmpe->num_gpios * af_bits, 8);
27227e34995SRabin Vincent 	int mask = (1 << af_bits) - 1;
2737929fa77SLee Jones 	u8 regs[8];
2747f7f4ea1SViresh Kumar 	int af, afperreg, ret;
27527e34995SRabin Vincent 
2767f7f4ea1SViresh Kumar 	if (!variant->get_altfunc)
2777f7f4ea1SViresh Kumar 		return 0;
2787f7f4ea1SViresh Kumar 
2797f7f4ea1SViresh Kumar 	afperreg = 8 / af_bits;
28027e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
28127e34995SRabin Vincent 
28227e34995SRabin Vincent 	ret = __stmpe_enable(stmpe, STMPE_BLOCK_GPIO);
28327e34995SRabin Vincent 	if (ret < 0)
28427e34995SRabin Vincent 		goto out;
28527e34995SRabin Vincent 
28627e34995SRabin Vincent 	ret = __stmpe_block_read(stmpe, regaddr, numregs, regs);
28727e34995SRabin Vincent 	if (ret < 0)
28827e34995SRabin Vincent 		goto out;
28927e34995SRabin Vincent 
29027e34995SRabin Vincent 	af = variant->get_altfunc(stmpe, block);
29127e34995SRabin Vincent 
29227e34995SRabin Vincent 	while (pins) {
29327e34995SRabin Vincent 		int pin = __ffs(pins);
29427e34995SRabin Vincent 		int regoffset = numregs - (pin / afperreg) - 1;
29527e34995SRabin Vincent 		int pos = (pin % afperreg) * (8 / afperreg);
29627e34995SRabin Vincent 
29727e34995SRabin Vincent 		regs[regoffset] &= ~(mask << pos);
29827e34995SRabin Vincent 		regs[regoffset] |= af << pos;
29927e34995SRabin Vincent 
30027e34995SRabin Vincent 		pins &= ~(1 << pin);
30127e34995SRabin Vincent 	}
30227e34995SRabin Vincent 
30327e34995SRabin Vincent 	ret = __stmpe_block_write(stmpe, regaddr, numregs, regs);
30427e34995SRabin Vincent 
30527e34995SRabin Vincent out:
30627e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
30727e34995SRabin Vincent 	return ret;
30827e34995SRabin Vincent }
30927e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_set_altfunc);
31027e34995SRabin Vincent 
31127e34995SRabin Vincent /*
31227e34995SRabin Vincent  * GPIO (all variants)
31327e34995SRabin Vincent  */
31427e34995SRabin Vincent 
315cb9e880aSRikard Falkeborn static struct resource stmpe_gpio_resources[] = {
31627e34995SRabin Vincent 	/* Start and end filled dynamically */
31727e34995SRabin Vincent 	{
31827e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
31927e34995SRabin Vincent 	},
32027e34995SRabin Vincent };
32127e34995SRabin Vincent 
3226bbb3c4cSGeert Uytterhoeven static const struct mfd_cell stmpe_gpio_cell = {
32327e34995SRabin Vincent 	.name		= "stmpe-gpio",
32486605cfeSVipul Kumar Samar 	.of_compatible	= "st,stmpe-gpio",
32527e34995SRabin Vincent 	.resources	= stmpe_gpio_resources,
32627e34995SRabin Vincent 	.num_resources	= ARRAY_SIZE(stmpe_gpio_resources),
32727e34995SRabin Vincent };
32827e34995SRabin Vincent 
3296bbb3c4cSGeert Uytterhoeven static const struct mfd_cell stmpe_gpio_cell_noirq = {
330e31f9b82SChris Blair 	.name		= "stmpe-gpio",
33186605cfeSVipul Kumar Samar 	.of_compatible	= "st,stmpe-gpio",
332e31f9b82SChris Blair 	/* gpio cell resources consist of an irq only so no resources here */
333e31f9b82SChris Blair };
334e31f9b82SChris Blair 
33527e34995SRabin Vincent /*
33627e34995SRabin Vincent  * Keypad (1601, 2401, 2403)
33727e34995SRabin Vincent  */
33827e34995SRabin Vincent 
339cb9e880aSRikard Falkeborn static struct resource stmpe_keypad_resources[] = {
340cb9e880aSRikard Falkeborn 	/* Start and end filled dynamically */
34127e34995SRabin Vincent 	{
34227e34995SRabin Vincent 		.name	= "KEYPAD",
34327e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
34427e34995SRabin Vincent 	},
34527e34995SRabin Vincent 	{
34627e34995SRabin Vincent 		.name	= "KEYPAD_OVER",
34727e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
34827e34995SRabin Vincent 	},
34927e34995SRabin Vincent };
35027e34995SRabin Vincent 
3516bbb3c4cSGeert Uytterhoeven static const struct mfd_cell stmpe_keypad_cell = {
35227e34995SRabin Vincent 	.name		= "stmpe-keypad",
3536ea32387SDmitry Torokhov 	.of_compatible  = "st,stmpe-keypad",
35427e34995SRabin Vincent 	.resources	= stmpe_keypad_resources,
35527e34995SRabin Vincent 	.num_resources	= ARRAY_SIZE(stmpe_keypad_resources),
35627e34995SRabin Vincent };
35727e34995SRabin Vincent 
35827e34995SRabin Vincent /*
359b273c5e0SLinus Walleij  * PWM (1601, 2401, 2403)
360b273c5e0SLinus Walleij  */
361cb9e880aSRikard Falkeborn static struct resource stmpe_pwm_resources[] = {
362cb9e880aSRikard Falkeborn 	/* Start and end filled dynamically */
363b273c5e0SLinus Walleij 	{
364b273c5e0SLinus Walleij 		.name	= "PWM0",
365b273c5e0SLinus Walleij 		.flags	= IORESOURCE_IRQ,
366b273c5e0SLinus Walleij 	},
367b273c5e0SLinus Walleij 	{
368b273c5e0SLinus Walleij 		.name	= "PWM1",
369b273c5e0SLinus Walleij 		.flags	= IORESOURCE_IRQ,
370b273c5e0SLinus Walleij 	},
371b273c5e0SLinus Walleij 	{
372b273c5e0SLinus Walleij 		.name	= "PWM2",
373b273c5e0SLinus Walleij 		.flags	= IORESOURCE_IRQ,
374b273c5e0SLinus Walleij 	},
375b273c5e0SLinus Walleij };
376b273c5e0SLinus Walleij 
377b273c5e0SLinus Walleij static const struct mfd_cell stmpe_pwm_cell = {
378b273c5e0SLinus Walleij 	.name		= "stmpe-pwm",
379b273c5e0SLinus Walleij 	.of_compatible  = "st,stmpe-pwm",
380b273c5e0SLinus Walleij 	.resources	= stmpe_pwm_resources,
381b273c5e0SLinus Walleij 	.num_resources	= ARRAY_SIZE(stmpe_pwm_resources),
382b273c5e0SLinus Walleij };
383b273c5e0SLinus Walleij 
384b273c5e0SLinus Walleij /*
3857f7f4ea1SViresh Kumar  * STMPE801
3867f7f4ea1SViresh Kumar  */
3877f7f4ea1SViresh Kumar static const u8 stmpe801_regs[] = {
3887f7f4ea1SViresh Kumar 	[STMPE_IDX_CHIP_ID]	= STMPE801_REG_CHIP_ID,
3897f7f4ea1SViresh Kumar 	[STMPE_IDX_ICR_LSB]	= STMPE801_REG_SYS_CTRL,
3907f7f4ea1SViresh Kumar 	[STMPE_IDX_GPMR_LSB]	= STMPE801_REG_GPIO_MP_STA,
3917f7f4ea1SViresh Kumar 	[STMPE_IDX_GPSR_LSB]	= STMPE801_REG_GPIO_SET_PIN,
3927f7f4ea1SViresh Kumar 	[STMPE_IDX_GPCR_LSB]	= STMPE801_REG_GPIO_SET_PIN,
3937f7f4ea1SViresh Kumar 	[STMPE_IDX_GPDR_LSB]	= STMPE801_REG_GPIO_DIR,
3947f7f4ea1SViresh Kumar 	[STMPE_IDX_IEGPIOR_LSB] = STMPE801_REG_GPIO_INT_EN,
3957f7f4ea1SViresh Kumar 	[STMPE_IDX_ISGPIOR_MSB] = STMPE801_REG_GPIO_INT_STA,
3967f7f4ea1SViresh Kumar 
3977f7f4ea1SViresh Kumar };
3987f7f4ea1SViresh Kumar 
3997f7f4ea1SViresh Kumar static struct stmpe_variant_block stmpe801_blocks[] = {
4007f7f4ea1SViresh Kumar 	{
4017f7f4ea1SViresh Kumar 		.cell	= &stmpe_gpio_cell,
4027f7f4ea1SViresh Kumar 		.irq	= 0,
4037f7f4ea1SViresh Kumar 		.block	= STMPE_BLOCK_GPIO,
4047f7f4ea1SViresh Kumar 	},
4057f7f4ea1SViresh Kumar };
4067f7f4ea1SViresh Kumar 
407e31f9b82SChris Blair static struct stmpe_variant_block stmpe801_blocks_noirq[] = {
408e31f9b82SChris Blair 	{
409e31f9b82SChris Blair 		.cell	= &stmpe_gpio_cell_noirq,
410e31f9b82SChris Blair 		.block	= STMPE_BLOCK_GPIO,
411e31f9b82SChris Blair 	},
412e31f9b82SChris Blair };
413e31f9b82SChris Blair 
4147f7f4ea1SViresh Kumar static int stmpe801_enable(struct stmpe *stmpe, unsigned int blocks,
4157f7f4ea1SViresh Kumar 			   bool enable)
4167f7f4ea1SViresh Kumar {
4177f7f4ea1SViresh Kumar 	if (blocks & STMPE_BLOCK_GPIO)
4187f7f4ea1SViresh Kumar 		return 0;
4197f7f4ea1SViresh Kumar 	else
4207f7f4ea1SViresh Kumar 		return -EINVAL;
4217f7f4ea1SViresh Kumar }
4227f7f4ea1SViresh Kumar 
4237f7f4ea1SViresh Kumar static struct stmpe_variant_info stmpe801 = {
4247f7f4ea1SViresh Kumar 	.name		= "stmpe801",
4257f7f4ea1SViresh Kumar 	.id_val		= STMPE801_ID,
4267f7f4ea1SViresh Kumar 	.id_mask	= 0xffff,
4277f7f4ea1SViresh Kumar 	.num_gpios	= 8,
4287f7f4ea1SViresh Kumar 	.regs		= stmpe801_regs,
4297f7f4ea1SViresh Kumar 	.blocks		= stmpe801_blocks,
4307f7f4ea1SViresh Kumar 	.num_blocks	= ARRAY_SIZE(stmpe801_blocks),
4317f7f4ea1SViresh Kumar 	.num_irqs	= STMPE801_NR_INTERNAL_IRQS,
4327f7f4ea1SViresh Kumar 	.enable		= stmpe801_enable,
4337f7f4ea1SViresh Kumar };
4347f7f4ea1SViresh Kumar 
435e31f9b82SChris Blair static struct stmpe_variant_info stmpe801_noirq = {
436e31f9b82SChris Blair 	.name		= "stmpe801",
437e31f9b82SChris Blair 	.id_val		= STMPE801_ID,
438e31f9b82SChris Blair 	.id_mask	= 0xffff,
439e31f9b82SChris Blair 	.num_gpios	= 8,
440e31f9b82SChris Blair 	.regs		= stmpe801_regs,
441e31f9b82SChris Blair 	.blocks		= stmpe801_blocks_noirq,
442e31f9b82SChris Blair 	.num_blocks	= ARRAY_SIZE(stmpe801_blocks_noirq),
443e31f9b82SChris Blair 	.enable		= stmpe801_enable,
444e31f9b82SChris Blair };
445e31f9b82SChris Blair 
4467f7f4ea1SViresh Kumar /*
4471cda2394SViresh Kumar  * Touchscreen (STMPE811 or STMPE610)
44827e34995SRabin Vincent  */
44927e34995SRabin Vincent 
450cb9e880aSRikard Falkeborn static struct resource stmpe_ts_resources[] = {
451cb9e880aSRikard Falkeborn 	/* Start and end filled dynamically */
45227e34995SRabin Vincent 	{
45327e34995SRabin Vincent 		.name	= "TOUCH_DET",
45427e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
45527e34995SRabin Vincent 	},
45627e34995SRabin Vincent 	{
45727e34995SRabin Vincent 		.name	= "FIFO_TH",
45827e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
45927e34995SRabin Vincent 	},
46027e34995SRabin Vincent };
46127e34995SRabin Vincent 
4626bbb3c4cSGeert Uytterhoeven static const struct mfd_cell stmpe_ts_cell = {
46327e34995SRabin Vincent 	.name		= "stmpe-ts",
464037db524SVipul Kumar Samar 	.of_compatible	= "st,stmpe-ts",
46527e34995SRabin Vincent 	.resources	= stmpe_ts_resources,
46627e34995SRabin Vincent 	.num_resources	= ARRAY_SIZE(stmpe_ts_resources),
46727e34995SRabin Vincent };
46827e34995SRabin Vincent 
46927e34995SRabin Vincent /*
4706377cfa3SStefan Agner  * ADC (STMPE811)
4716377cfa3SStefan Agner  */
4726377cfa3SStefan Agner 
473cb9e880aSRikard Falkeborn static struct resource stmpe_adc_resources[] = {
474cb9e880aSRikard Falkeborn 	/* Start and end filled dynamically */
4756377cfa3SStefan Agner 	{
4766377cfa3SStefan Agner 		.name	= "STMPE_TEMP_SENS",
4776377cfa3SStefan Agner 		.flags	= IORESOURCE_IRQ,
4786377cfa3SStefan Agner 	},
4796377cfa3SStefan Agner 	{
4806377cfa3SStefan Agner 		.name	= "STMPE_ADC",
4816377cfa3SStefan Agner 		.flags	= IORESOURCE_IRQ,
4826377cfa3SStefan Agner 	},
4836377cfa3SStefan Agner };
4846377cfa3SStefan Agner 
4856377cfa3SStefan Agner static const struct mfd_cell stmpe_adc_cell = {
4866377cfa3SStefan Agner 	.name		= "stmpe-adc",
4876377cfa3SStefan Agner 	.of_compatible	= "st,stmpe-adc",
4886377cfa3SStefan Agner 	.resources	= stmpe_adc_resources,
4896377cfa3SStefan Agner 	.num_resources	= ARRAY_SIZE(stmpe_adc_resources),
4906377cfa3SStefan Agner };
4916377cfa3SStefan Agner 
4926377cfa3SStefan Agner /*
4931cda2394SViresh Kumar  * STMPE811 or STMPE610
49427e34995SRabin Vincent  */
49527e34995SRabin Vincent 
49627e34995SRabin Vincent static const u8 stmpe811_regs[] = {
49727e34995SRabin Vincent 	[STMPE_IDX_CHIP_ID]	= STMPE811_REG_CHIP_ID,
4980f4be8cfSPatrice Chotard 	[STMPE_IDX_SYS_CTRL]	= STMPE811_REG_SYS_CTRL,
4990f4be8cfSPatrice Chotard 	[STMPE_IDX_SYS_CTRL2]	= STMPE811_REG_SYS_CTRL2,
50027e34995SRabin Vincent 	[STMPE_IDX_ICR_LSB]	= STMPE811_REG_INT_CTRL,
50127e34995SRabin Vincent 	[STMPE_IDX_IER_LSB]	= STMPE811_REG_INT_EN,
50227e34995SRabin Vincent 	[STMPE_IDX_ISR_MSB]	= STMPE811_REG_INT_STA,
50327e34995SRabin Vincent 	[STMPE_IDX_GPMR_LSB]	= STMPE811_REG_GPIO_MP_STA,
50427e34995SRabin Vincent 	[STMPE_IDX_GPSR_LSB]	= STMPE811_REG_GPIO_SET_PIN,
50527e34995SRabin Vincent 	[STMPE_IDX_GPCR_LSB]	= STMPE811_REG_GPIO_CLR_PIN,
50627e34995SRabin Vincent 	[STMPE_IDX_GPDR_LSB]	= STMPE811_REG_GPIO_DIR,
50727e34995SRabin Vincent 	[STMPE_IDX_GPRER_LSB]	= STMPE811_REG_GPIO_RE,
50827e34995SRabin Vincent 	[STMPE_IDX_GPFER_LSB]	= STMPE811_REG_GPIO_FE,
50927e34995SRabin Vincent 	[STMPE_IDX_GPAFR_U_MSB]	= STMPE811_REG_GPIO_AF,
51027e34995SRabin Vincent 	[STMPE_IDX_IEGPIOR_LSB]	= STMPE811_REG_GPIO_INT_EN,
51127e34995SRabin Vincent 	[STMPE_IDX_ISGPIOR_MSB]	= STMPE811_REG_GPIO_INT_STA,
512897ac667SPatrice Chotard 	[STMPE_IDX_GPEDR_LSB]	= STMPE811_REG_GPIO_ED,
51327e34995SRabin Vincent };
51427e34995SRabin Vincent 
51527e34995SRabin Vincent static struct stmpe_variant_block stmpe811_blocks[] = {
51627e34995SRabin Vincent 	{
51727e34995SRabin Vincent 		.cell	= &stmpe_gpio_cell,
51827e34995SRabin Vincent 		.irq	= STMPE811_IRQ_GPIOC,
51927e34995SRabin Vincent 		.block	= STMPE_BLOCK_GPIO,
52027e34995SRabin Vincent 	},
52127e34995SRabin Vincent 	{
52227e34995SRabin Vincent 		.cell	= &stmpe_ts_cell,
52327e34995SRabin Vincent 		.irq	= STMPE811_IRQ_TOUCH_DET,
52427e34995SRabin Vincent 		.block	= STMPE_BLOCK_TOUCHSCREEN,
52527e34995SRabin Vincent 	},
5266377cfa3SStefan Agner 	{
5276377cfa3SStefan Agner 		.cell	= &stmpe_adc_cell,
5286377cfa3SStefan Agner 		.irq	= STMPE811_IRQ_TEMP_SENS,
5296377cfa3SStefan Agner 		.block	= STMPE_BLOCK_ADC,
5306377cfa3SStefan Agner 	},
53127e34995SRabin Vincent };
53227e34995SRabin Vincent 
53327e34995SRabin Vincent static int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks,
53427e34995SRabin Vincent 			   bool enable)
53527e34995SRabin Vincent {
53627e34995SRabin Vincent 	unsigned int mask = 0;
53727e34995SRabin Vincent 
53827e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_GPIO)
53927e34995SRabin Vincent 		mask |= STMPE811_SYS_CTRL2_GPIO_OFF;
54027e34995SRabin Vincent 
54127e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_ADC)
54227e34995SRabin Vincent 		mask |= STMPE811_SYS_CTRL2_ADC_OFF;
54327e34995SRabin Vincent 
54427e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_TOUCHSCREEN)
54527e34995SRabin Vincent 		mask |= STMPE811_SYS_CTRL2_TSC_OFF;
54627e34995SRabin Vincent 
5470f4be8cfSPatrice Chotard 	return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2], mask,
54827e34995SRabin Vincent 				enable ? 0 : mask);
54927e34995SRabin Vincent }
55027e34995SRabin Vincent 
5516377cfa3SStefan Agner int stmpe811_adc_common_init(struct stmpe *stmpe)
5526377cfa3SStefan Agner {
5536377cfa3SStefan Agner 	int ret;
5546377cfa3SStefan Agner 	u8 adc_ctrl1, adc_ctrl1_mask;
5556377cfa3SStefan Agner 
5566377cfa3SStefan Agner 	adc_ctrl1 = STMPE_SAMPLE_TIME(stmpe->sample_time) |
5576377cfa3SStefan Agner 		    STMPE_MOD_12B(stmpe->mod_12b) |
5586377cfa3SStefan Agner 		    STMPE_REF_SEL(stmpe->ref_sel);
5596377cfa3SStefan Agner 	adc_ctrl1_mask = STMPE_SAMPLE_TIME(0xff) | STMPE_MOD_12B(0xff) |
5606377cfa3SStefan Agner 			 STMPE_REF_SEL(0xff);
5616377cfa3SStefan Agner 
5626377cfa3SStefan Agner 	ret = stmpe_set_bits(stmpe, STMPE811_REG_ADC_CTRL1,
5636377cfa3SStefan Agner 			adc_ctrl1_mask, adc_ctrl1);
5646377cfa3SStefan Agner 	if (ret) {
5656377cfa3SStefan Agner 		dev_err(stmpe->dev, "Could not setup ADC\n");
5666377cfa3SStefan Agner 		return ret;
5676377cfa3SStefan Agner 	}
5686377cfa3SStefan Agner 
5696377cfa3SStefan Agner 	ret = stmpe_set_bits(stmpe, STMPE811_REG_ADC_CTRL2,
5706377cfa3SStefan Agner 			STMPE_ADC_FREQ(0xff), STMPE_ADC_FREQ(stmpe->adc_freq));
5716377cfa3SStefan Agner 	if (ret) {
5726377cfa3SStefan Agner 		dev_err(stmpe->dev, "Could not setup ADC\n");
5736377cfa3SStefan Agner 		return ret;
5746377cfa3SStefan Agner 	}
5756377cfa3SStefan Agner 
5766377cfa3SStefan Agner 	return 0;
5776377cfa3SStefan Agner }
5786377cfa3SStefan Agner EXPORT_SYMBOL_GPL(stmpe811_adc_common_init);
5796377cfa3SStefan Agner 
58027e34995SRabin Vincent static int stmpe811_get_altfunc(struct stmpe *stmpe, enum stmpe_block block)
58127e34995SRabin Vincent {
58227e34995SRabin Vincent 	/* 0 for touchscreen, 1 for GPIO */
58327e34995SRabin Vincent 	return block != STMPE_BLOCK_TOUCHSCREEN;
58427e34995SRabin Vincent }
58527e34995SRabin Vincent 
58627e34995SRabin Vincent static struct stmpe_variant_info stmpe811 = {
58727e34995SRabin Vincent 	.name		= "stmpe811",
58827e34995SRabin Vincent 	.id_val		= 0x0811,
58927e34995SRabin Vincent 	.id_mask	= 0xffff,
59027e34995SRabin Vincent 	.num_gpios	= 8,
59127e34995SRabin Vincent 	.af_bits	= 1,
59227e34995SRabin Vincent 	.regs		= stmpe811_regs,
59327e34995SRabin Vincent 	.blocks		= stmpe811_blocks,
59427e34995SRabin Vincent 	.num_blocks	= ARRAY_SIZE(stmpe811_blocks),
59527e34995SRabin Vincent 	.num_irqs	= STMPE811_NR_INTERNAL_IRQS,
59627e34995SRabin Vincent 	.enable		= stmpe811_enable,
59727e34995SRabin Vincent 	.get_altfunc	= stmpe811_get_altfunc,
59827e34995SRabin Vincent };
59927e34995SRabin Vincent 
6001cda2394SViresh Kumar /* Similar to 811, except number of gpios */
6011cda2394SViresh Kumar static struct stmpe_variant_info stmpe610 = {
6021cda2394SViresh Kumar 	.name		= "stmpe610",
6031cda2394SViresh Kumar 	.id_val		= 0x0811,
6041cda2394SViresh Kumar 	.id_mask	= 0xffff,
6051cda2394SViresh Kumar 	.num_gpios	= 6,
6061cda2394SViresh Kumar 	.af_bits	= 1,
6071cda2394SViresh Kumar 	.regs		= stmpe811_regs,
6081cda2394SViresh Kumar 	.blocks		= stmpe811_blocks,
6091cda2394SViresh Kumar 	.num_blocks	= ARRAY_SIZE(stmpe811_blocks),
6101cda2394SViresh Kumar 	.num_irqs	= STMPE811_NR_INTERNAL_IRQS,
6111cda2394SViresh Kumar 	.enable		= stmpe811_enable,
6121cda2394SViresh Kumar 	.get_altfunc	= stmpe811_get_altfunc,
6131cda2394SViresh Kumar };
6141cda2394SViresh Kumar 
61527e34995SRabin Vincent /*
6166bb9f0d9SPatrice Chotard  * STMPE1600
6176bb9f0d9SPatrice Chotard  * Compared to all others STMPE variant, LSB and MSB regs are located in this
6186bb9f0d9SPatrice Chotard  * order :	LSB   addr
6196bb9f0d9SPatrice Chotard  *		MSB   addr + 1
6206bb9f0d9SPatrice Chotard  * As there is only 2 * 8bits registers for GPMR/GPSR/IEGPIOPR, CSB index is MSB registers
6216bb9f0d9SPatrice Chotard  */
6226bb9f0d9SPatrice Chotard 
6236bb9f0d9SPatrice Chotard static const u8 stmpe1600_regs[] = {
6246bb9f0d9SPatrice Chotard 	[STMPE_IDX_CHIP_ID]	= STMPE1600_REG_CHIP_ID,
6256bb9f0d9SPatrice Chotard 	[STMPE_IDX_SYS_CTRL]	= STMPE1600_REG_SYS_CTRL,
6266bb9f0d9SPatrice Chotard 	[STMPE_IDX_ICR_LSB]	= STMPE1600_REG_SYS_CTRL,
6276bb9f0d9SPatrice Chotard 	[STMPE_IDX_GPMR_LSB]	= STMPE1600_REG_GPMR_LSB,
6286bb9f0d9SPatrice Chotard 	[STMPE_IDX_GPMR_CSB]	= STMPE1600_REG_GPMR_MSB,
6296bb9f0d9SPatrice Chotard 	[STMPE_IDX_GPSR_LSB]	= STMPE1600_REG_GPSR_LSB,
6306bb9f0d9SPatrice Chotard 	[STMPE_IDX_GPSR_CSB]	= STMPE1600_REG_GPSR_MSB,
631b97eef5dSHugues Fruchet 	[STMPE_IDX_GPCR_LSB]	= STMPE1600_REG_GPSR_LSB,
632b97eef5dSHugues Fruchet 	[STMPE_IDX_GPCR_CSB]	= STMPE1600_REG_GPSR_MSB,
6336bb9f0d9SPatrice Chotard 	[STMPE_IDX_GPDR_LSB]	= STMPE1600_REG_GPDR_LSB,
6346bb9f0d9SPatrice Chotard 	[STMPE_IDX_GPDR_CSB]	= STMPE1600_REG_GPDR_MSB,
6356bb9f0d9SPatrice Chotard 	[STMPE_IDX_IEGPIOR_LSB]	= STMPE1600_REG_IEGPIOR_LSB,
6366bb9f0d9SPatrice Chotard 	[STMPE_IDX_IEGPIOR_CSB]	= STMPE1600_REG_IEGPIOR_MSB,
6376bb9f0d9SPatrice Chotard 	[STMPE_IDX_ISGPIOR_LSB]	= STMPE1600_REG_ISGPIOR_LSB,
6386bb9f0d9SPatrice Chotard };
6396bb9f0d9SPatrice Chotard 
6406bb9f0d9SPatrice Chotard static struct stmpe_variant_block stmpe1600_blocks[] = {
6416bb9f0d9SPatrice Chotard 	{
6426bb9f0d9SPatrice Chotard 		.cell	= &stmpe_gpio_cell,
6436bb9f0d9SPatrice Chotard 		.irq	= 0,
6446bb9f0d9SPatrice Chotard 		.block	= STMPE_BLOCK_GPIO,
6456bb9f0d9SPatrice Chotard 	},
6466bb9f0d9SPatrice Chotard };
6476bb9f0d9SPatrice Chotard 
6486bb9f0d9SPatrice Chotard static int stmpe1600_enable(struct stmpe *stmpe, unsigned int blocks,
6496bb9f0d9SPatrice Chotard 			   bool enable)
6506bb9f0d9SPatrice Chotard {
6516bb9f0d9SPatrice Chotard 	if (blocks & STMPE_BLOCK_GPIO)
6526bb9f0d9SPatrice Chotard 		return 0;
6536bb9f0d9SPatrice Chotard 	else
6546bb9f0d9SPatrice Chotard 		return -EINVAL;
6556bb9f0d9SPatrice Chotard }
6566bb9f0d9SPatrice Chotard 
6576bb9f0d9SPatrice Chotard static struct stmpe_variant_info stmpe1600 = {
6586bb9f0d9SPatrice Chotard 	.name		= "stmpe1600",
6596bb9f0d9SPatrice Chotard 	.id_val		= STMPE1600_ID,
6606bb9f0d9SPatrice Chotard 	.id_mask	= 0xffff,
6616bb9f0d9SPatrice Chotard 	.num_gpios	= 16,
6626bb9f0d9SPatrice Chotard 	.af_bits	= 0,
6636bb9f0d9SPatrice Chotard 	.regs		= stmpe1600_regs,
6646bb9f0d9SPatrice Chotard 	.blocks		= stmpe1600_blocks,
6656bb9f0d9SPatrice Chotard 	.num_blocks	= ARRAY_SIZE(stmpe1600_blocks),
6666bb9f0d9SPatrice Chotard 	.num_irqs	= STMPE1600_NR_INTERNAL_IRQS,
6676bb9f0d9SPatrice Chotard 	.enable		= stmpe1600_enable,
6686bb9f0d9SPatrice Chotard };
6696bb9f0d9SPatrice Chotard 
6706bb9f0d9SPatrice Chotard /*
67127e34995SRabin Vincent  * STMPE1601
67227e34995SRabin Vincent  */
67327e34995SRabin Vincent 
67427e34995SRabin Vincent static const u8 stmpe1601_regs[] = {
67527e34995SRabin Vincent 	[STMPE_IDX_CHIP_ID]	= STMPE1601_REG_CHIP_ID,
6760f4be8cfSPatrice Chotard 	[STMPE_IDX_SYS_CTRL]	= STMPE1601_REG_SYS_CTRL,
6770f4be8cfSPatrice Chotard 	[STMPE_IDX_SYS_CTRL2]	= STMPE1601_REG_SYS_CTRL2,
67827e34995SRabin Vincent 	[STMPE_IDX_ICR_LSB]	= STMPE1601_REG_ICR_LSB,
679897ac667SPatrice Chotard 	[STMPE_IDX_IER_MSB]	= STMPE1601_REG_IER_MSB,
68027e34995SRabin Vincent 	[STMPE_IDX_IER_LSB]	= STMPE1601_REG_IER_LSB,
68127e34995SRabin Vincent 	[STMPE_IDX_ISR_MSB]	= STMPE1601_REG_ISR_MSB,
68227e34995SRabin Vincent 	[STMPE_IDX_GPMR_LSB]	= STMPE1601_REG_GPIO_MP_LSB,
683897ac667SPatrice Chotard 	[STMPE_IDX_GPMR_CSB]	= STMPE1601_REG_GPIO_MP_MSB,
68427e34995SRabin Vincent 	[STMPE_IDX_GPSR_LSB]	= STMPE1601_REG_GPIO_SET_LSB,
685897ac667SPatrice Chotard 	[STMPE_IDX_GPSR_CSB]	= STMPE1601_REG_GPIO_SET_MSB,
68627e34995SRabin Vincent 	[STMPE_IDX_GPCR_LSB]	= STMPE1601_REG_GPIO_CLR_LSB,
687897ac667SPatrice Chotard 	[STMPE_IDX_GPCR_CSB]	= STMPE1601_REG_GPIO_CLR_MSB,
68827e34995SRabin Vincent 	[STMPE_IDX_GPDR_LSB]	= STMPE1601_REG_GPIO_SET_DIR_LSB,
689897ac667SPatrice Chotard 	[STMPE_IDX_GPDR_CSB]	= STMPE1601_REG_GPIO_SET_DIR_MSB,
690897ac667SPatrice Chotard 	[STMPE_IDX_GPEDR_LSB]	= STMPE1601_REG_GPIO_ED_LSB,
691897ac667SPatrice Chotard 	[STMPE_IDX_GPEDR_CSB]	= STMPE1601_REG_GPIO_ED_MSB,
69227e34995SRabin Vincent 	[STMPE_IDX_GPRER_LSB]	= STMPE1601_REG_GPIO_RE_LSB,
693897ac667SPatrice Chotard 	[STMPE_IDX_GPRER_CSB]	= STMPE1601_REG_GPIO_RE_MSB,
69427e34995SRabin Vincent 	[STMPE_IDX_GPFER_LSB]	= STMPE1601_REG_GPIO_FE_LSB,
695897ac667SPatrice Chotard 	[STMPE_IDX_GPFER_CSB]	= STMPE1601_REG_GPIO_FE_MSB,
69680e1dd82SLinus Walleij 	[STMPE_IDX_GPPUR_LSB]	= STMPE1601_REG_GPIO_PU_LSB,
69727e34995SRabin Vincent 	[STMPE_IDX_GPAFR_U_MSB]	= STMPE1601_REG_GPIO_AF_U_MSB,
69827e34995SRabin Vincent 	[STMPE_IDX_IEGPIOR_LSB]	= STMPE1601_REG_INT_EN_GPIO_MASK_LSB,
699897ac667SPatrice Chotard 	[STMPE_IDX_IEGPIOR_CSB]	= STMPE1601_REG_INT_EN_GPIO_MASK_MSB,
70027e34995SRabin Vincent 	[STMPE_IDX_ISGPIOR_MSB]	= STMPE1601_REG_INT_STA_GPIO_MSB,
70127e34995SRabin Vincent };
70227e34995SRabin Vincent 
70327e34995SRabin Vincent static struct stmpe_variant_block stmpe1601_blocks[] = {
70427e34995SRabin Vincent 	{
70527e34995SRabin Vincent 		.cell	= &stmpe_gpio_cell,
7065204e51dSLee Jones 		.irq	= STMPE1601_IRQ_GPIOC,
70727e34995SRabin Vincent 		.block	= STMPE_BLOCK_GPIO,
70827e34995SRabin Vincent 	},
70927e34995SRabin Vincent 	{
71027e34995SRabin Vincent 		.cell	= &stmpe_keypad_cell,
7115204e51dSLee Jones 		.irq	= STMPE1601_IRQ_KEYPAD,
71227e34995SRabin Vincent 		.block	= STMPE_BLOCK_KEYPAD,
71327e34995SRabin Vincent 	},
714b273c5e0SLinus Walleij 	{
715b273c5e0SLinus Walleij 		.cell	= &stmpe_pwm_cell,
716b273c5e0SLinus Walleij 		.irq	= STMPE1601_IRQ_PWM0,
717b273c5e0SLinus Walleij 		.block	= STMPE_BLOCK_PWM,
718b273c5e0SLinus Walleij 	},
71927e34995SRabin Vincent };
72027e34995SRabin Vincent 
7215981f4e6SSundar R Iyer /* supported autosleep timeout delay (in msecs) */
7225981f4e6SSundar R Iyer static const int stmpe_autosleep_delay[] = {
7235981f4e6SSundar R Iyer 	4, 16, 32, 64, 128, 256, 512, 1024,
7245981f4e6SSundar R Iyer };
7255981f4e6SSundar R Iyer 
7265981f4e6SSundar R Iyer static int stmpe_round_timeout(int timeout)
7275981f4e6SSundar R Iyer {
7285981f4e6SSundar R Iyer 	int i;
7295981f4e6SSundar R Iyer 
7305981f4e6SSundar R Iyer 	for (i = 0; i < ARRAY_SIZE(stmpe_autosleep_delay); i++) {
7315981f4e6SSundar R Iyer 		if (stmpe_autosleep_delay[i] >= timeout)
7325981f4e6SSundar R Iyer 			return i;
7335981f4e6SSundar R Iyer 	}
7345981f4e6SSundar R Iyer 
7355981f4e6SSundar R Iyer 	/*
7365981f4e6SSundar R Iyer 	 * requests for delays longer than supported should not return the
7375981f4e6SSundar R Iyer 	 * longest supported delay
7385981f4e6SSundar R Iyer 	 */
7395981f4e6SSundar R Iyer 	return -EINVAL;
7405981f4e6SSundar R Iyer }
7415981f4e6SSundar R Iyer 
7425981f4e6SSundar R Iyer static int stmpe_autosleep(struct stmpe *stmpe, int autosleep_timeout)
7435981f4e6SSundar R Iyer {
7445981f4e6SSundar R Iyer 	int ret;
7455981f4e6SSundar R Iyer 
7465981f4e6SSundar R Iyer 	if (!stmpe->variant->enable_autosleep)
7475981f4e6SSundar R Iyer 		return -ENOSYS;
7485981f4e6SSundar R Iyer 
7495981f4e6SSundar R Iyer 	mutex_lock(&stmpe->lock);
7505981f4e6SSundar R Iyer 	ret = stmpe->variant->enable_autosleep(stmpe, autosleep_timeout);
7515981f4e6SSundar R Iyer 	mutex_unlock(&stmpe->lock);
7525981f4e6SSundar R Iyer 
7535981f4e6SSundar R Iyer 	return ret;
7545981f4e6SSundar R Iyer }
7555981f4e6SSundar R Iyer 
7565981f4e6SSundar R Iyer /*
7575981f4e6SSundar R Iyer  * Both stmpe 1601/2403 support same layout for autosleep
7585981f4e6SSundar R Iyer  */
7595981f4e6SSundar R Iyer static int stmpe1601_autosleep(struct stmpe *stmpe,
7605981f4e6SSundar R Iyer 		int autosleep_timeout)
7615981f4e6SSundar R Iyer {
7625981f4e6SSundar R Iyer 	int ret, timeout;
7635981f4e6SSundar R Iyer 
7645981f4e6SSundar R Iyer 	/* choose the best available timeout */
7655981f4e6SSundar R Iyer 	timeout = stmpe_round_timeout(autosleep_timeout);
7665981f4e6SSundar R Iyer 	if (timeout < 0) {
7675981f4e6SSundar R Iyer 		dev_err(stmpe->dev, "invalid timeout\n");
7685981f4e6SSundar R Iyer 		return timeout;
7695981f4e6SSundar R Iyer 	}
7705981f4e6SSundar R Iyer 
7710f4be8cfSPatrice Chotard 	ret = __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2],
7725981f4e6SSundar R Iyer 			STMPE1601_AUTOSLEEP_TIMEOUT_MASK,
7735981f4e6SSundar R Iyer 			timeout);
7745981f4e6SSundar R Iyer 	if (ret < 0)
7755981f4e6SSundar R Iyer 		return ret;
7765981f4e6SSundar R Iyer 
7770f4be8cfSPatrice Chotard 	return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2],
7785981f4e6SSundar R Iyer 			STPME1601_AUTOSLEEP_ENABLE,
7795981f4e6SSundar R Iyer 			STPME1601_AUTOSLEEP_ENABLE);
7805981f4e6SSundar R Iyer }
7815981f4e6SSundar R Iyer 
78227e34995SRabin Vincent static int stmpe1601_enable(struct stmpe *stmpe, unsigned int blocks,
78327e34995SRabin Vincent 			    bool enable)
78427e34995SRabin Vincent {
78527e34995SRabin Vincent 	unsigned int mask = 0;
78627e34995SRabin Vincent 
78727e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_GPIO)
78827e34995SRabin Vincent 		mask |= STMPE1601_SYS_CTRL_ENABLE_GPIO;
789b69d2ad6SLinus Walleij 	else
790b69d2ad6SLinus Walleij 		mask &= ~STMPE1601_SYS_CTRL_ENABLE_GPIO;
79127e34995SRabin Vincent 
79227e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_KEYPAD)
79327e34995SRabin Vincent 		mask |= STMPE1601_SYS_CTRL_ENABLE_KPC;
794b69d2ad6SLinus Walleij 	else
795b69d2ad6SLinus Walleij 		mask &= ~STMPE1601_SYS_CTRL_ENABLE_KPC;
796b69d2ad6SLinus Walleij 
797b69d2ad6SLinus Walleij 	if (blocks & STMPE_BLOCK_PWM)
798b69d2ad6SLinus Walleij 		mask |= STMPE1601_SYS_CTRL_ENABLE_SPWM;
799b69d2ad6SLinus Walleij 	else
800b69d2ad6SLinus Walleij 		mask &= ~STMPE1601_SYS_CTRL_ENABLE_SPWM;
80127e34995SRabin Vincent 
8020f4be8cfSPatrice Chotard 	return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], mask,
80327e34995SRabin Vincent 				enable ? mask : 0);
80427e34995SRabin Vincent }
80527e34995SRabin Vincent 
80627e34995SRabin Vincent static int stmpe1601_get_altfunc(struct stmpe *stmpe, enum stmpe_block block)
80727e34995SRabin Vincent {
80827e34995SRabin Vincent 	switch (block) {
80927e34995SRabin Vincent 	case STMPE_BLOCK_PWM:
81027e34995SRabin Vincent 		return 2;
81127e34995SRabin Vincent 
81227e34995SRabin Vincent 	case STMPE_BLOCK_KEYPAD:
81327e34995SRabin Vincent 		return 1;
81427e34995SRabin Vincent 
81527e34995SRabin Vincent 	case STMPE_BLOCK_GPIO:
81627e34995SRabin Vincent 	default:
81727e34995SRabin Vincent 		return 0;
81827e34995SRabin Vincent 	}
81927e34995SRabin Vincent }
82027e34995SRabin Vincent 
82127e34995SRabin Vincent static struct stmpe_variant_info stmpe1601 = {
82227e34995SRabin Vincent 	.name		= "stmpe1601",
82327e34995SRabin Vincent 	.id_val		= 0x0210,
82427e34995SRabin Vincent 	.id_mask	= 0xfff0,	/* at least 0x0210 and 0x0212 */
82527e34995SRabin Vincent 	.num_gpios	= 16,
82627e34995SRabin Vincent 	.af_bits	= 2,
82727e34995SRabin Vincent 	.regs		= stmpe1601_regs,
82827e34995SRabin Vincent 	.blocks		= stmpe1601_blocks,
82927e34995SRabin Vincent 	.num_blocks	= ARRAY_SIZE(stmpe1601_blocks),
83027e34995SRabin Vincent 	.num_irqs	= STMPE1601_NR_INTERNAL_IRQS,
83127e34995SRabin Vincent 	.enable		= stmpe1601_enable,
83227e34995SRabin Vincent 	.get_altfunc	= stmpe1601_get_altfunc,
8335981f4e6SSundar R Iyer 	.enable_autosleep	= stmpe1601_autosleep,
83427e34995SRabin Vincent };
83527e34995SRabin Vincent 
83627e34995SRabin Vincent /*
837230f13a5SJean-Nicolas Graux  * STMPE1801
838230f13a5SJean-Nicolas Graux  */
839230f13a5SJean-Nicolas Graux static const u8 stmpe1801_regs[] = {
840230f13a5SJean-Nicolas Graux 	[STMPE_IDX_CHIP_ID]	= STMPE1801_REG_CHIP_ID,
8410f4be8cfSPatrice Chotard 	[STMPE_IDX_SYS_CTRL]	= STMPE1801_REG_SYS_CTRL,
842230f13a5SJean-Nicolas Graux 	[STMPE_IDX_ICR_LSB]	= STMPE1801_REG_INT_CTRL_LOW,
843230f13a5SJean-Nicolas Graux 	[STMPE_IDX_IER_LSB]	= STMPE1801_REG_INT_EN_MASK_LOW,
844230f13a5SJean-Nicolas Graux 	[STMPE_IDX_ISR_LSB]	= STMPE1801_REG_INT_STA_LOW,
845230f13a5SJean-Nicolas Graux 	[STMPE_IDX_GPMR_LSB]	= STMPE1801_REG_GPIO_MP_LOW,
846897ac667SPatrice Chotard 	[STMPE_IDX_GPMR_CSB]	= STMPE1801_REG_GPIO_MP_MID,
847897ac667SPatrice Chotard 	[STMPE_IDX_GPMR_MSB]	= STMPE1801_REG_GPIO_MP_HIGH,
848230f13a5SJean-Nicolas Graux 	[STMPE_IDX_GPSR_LSB]	= STMPE1801_REG_GPIO_SET_LOW,
849897ac667SPatrice Chotard 	[STMPE_IDX_GPSR_CSB]	= STMPE1801_REG_GPIO_SET_MID,
850897ac667SPatrice Chotard 	[STMPE_IDX_GPSR_MSB]	= STMPE1801_REG_GPIO_SET_HIGH,
851230f13a5SJean-Nicolas Graux 	[STMPE_IDX_GPCR_LSB]	= STMPE1801_REG_GPIO_CLR_LOW,
852897ac667SPatrice Chotard 	[STMPE_IDX_GPCR_CSB]	= STMPE1801_REG_GPIO_CLR_MID,
853897ac667SPatrice Chotard 	[STMPE_IDX_GPCR_MSB]	= STMPE1801_REG_GPIO_CLR_HIGH,
854230f13a5SJean-Nicolas Graux 	[STMPE_IDX_GPDR_LSB]	= STMPE1801_REG_GPIO_SET_DIR_LOW,
855897ac667SPatrice Chotard 	[STMPE_IDX_GPDR_CSB]	= STMPE1801_REG_GPIO_SET_DIR_MID,
856897ac667SPatrice Chotard 	[STMPE_IDX_GPDR_MSB]	= STMPE1801_REG_GPIO_SET_DIR_HIGH,
857230f13a5SJean-Nicolas Graux 	[STMPE_IDX_GPRER_LSB]	= STMPE1801_REG_GPIO_RE_LOW,
858897ac667SPatrice Chotard 	[STMPE_IDX_GPRER_CSB]	= STMPE1801_REG_GPIO_RE_MID,
859897ac667SPatrice Chotard 	[STMPE_IDX_GPRER_MSB]	= STMPE1801_REG_GPIO_RE_HIGH,
860230f13a5SJean-Nicolas Graux 	[STMPE_IDX_GPFER_LSB]	= STMPE1801_REG_GPIO_FE_LOW,
861897ac667SPatrice Chotard 	[STMPE_IDX_GPFER_CSB]	= STMPE1801_REG_GPIO_FE_MID,
862897ac667SPatrice Chotard 	[STMPE_IDX_GPFER_MSB]	= STMPE1801_REG_GPIO_FE_HIGH,
86380e1dd82SLinus Walleij 	[STMPE_IDX_GPPUR_LSB]	= STMPE1801_REG_GPIO_PULL_UP_LOW,
864230f13a5SJean-Nicolas Graux 	[STMPE_IDX_IEGPIOR_LSB]	= STMPE1801_REG_INT_EN_GPIO_MASK_LOW,
865897ac667SPatrice Chotard 	[STMPE_IDX_IEGPIOR_CSB]	= STMPE1801_REG_INT_EN_GPIO_MASK_MID,
866897ac667SPatrice Chotard 	[STMPE_IDX_IEGPIOR_MSB]	= STMPE1801_REG_INT_EN_GPIO_MASK_HIGH,
867897ac667SPatrice Chotard 	[STMPE_IDX_ISGPIOR_MSB]	= STMPE1801_REG_INT_STA_GPIO_HIGH,
868230f13a5SJean-Nicolas Graux };
869230f13a5SJean-Nicolas Graux 
870230f13a5SJean-Nicolas Graux static struct stmpe_variant_block stmpe1801_blocks[] = {
871230f13a5SJean-Nicolas Graux 	{
872230f13a5SJean-Nicolas Graux 		.cell	= &stmpe_gpio_cell,
873230f13a5SJean-Nicolas Graux 		.irq	= STMPE1801_IRQ_GPIOC,
874230f13a5SJean-Nicolas Graux 		.block	= STMPE_BLOCK_GPIO,
875230f13a5SJean-Nicolas Graux 	},
876230f13a5SJean-Nicolas Graux 	{
877230f13a5SJean-Nicolas Graux 		.cell	= &stmpe_keypad_cell,
878230f13a5SJean-Nicolas Graux 		.irq	= STMPE1801_IRQ_KEYPAD,
879230f13a5SJean-Nicolas Graux 		.block	= STMPE_BLOCK_KEYPAD,
880230f13a5SJean-Nicolas Graux 	},
881230f13a5SJean-Nicolas Graux };
882230f13a5SJean-Nicolas Graux 
883230f13a5SJean-Nicolas Graux static int stmpe1801_enable(struct stmpe *stmpe, unsigned int blocks,
884230f13a5SJean-Nicolas Graux 			    bool enable)
885230f13a5SJean-Nicolas Graux {
886230f13a5SJean-Nicolas Graux 	unsigned int mask = 0;
887230f13a5SJean-Nicolas Graux 	if (blocks & STMPE_BLOCK_GPIO)
888230f13a5SJean-Nicolas Graux 		mask |= STMPE1801_MSK_INT_EN_GPIO;
889230f13a5SJean-Nicolas Graux 
890230f13a5SJean-Nicolas Graux 	if (blocks & STMPE_BLOCK_KEYPAD)
891230f13a5SJean-Nicolas Graux 		mask |= STMPE1801_MSK_INT_EN_KPC;
892230f13a5SJean-Nicolas Graux 
893230f13a5SJean-Nicolas Graux 	return __stmpe_set_bits(stmpe, STMPE1801_REG_INT_EN_MASK_LOW, mask,
894230f13a5SJean-Nicolas Graux 				enable ? mask : 0);
895230f13a5SJean-Nicolas Graux }
896230f13a5SJean-Nicolas Graux 
897c4dd1ba3SPatrice Chotard static int stmpe_reset(struct stmpe *stmpe)
898230f13a5SJean-Nicolas Graux {
899c4dd1ba3SPatrice Chotard 	u16 id_val = stmpe->variant->id_val;
900230f13a5SJean-Nicolas Graux 	unsigned long timeout;
901230f13a5SJean-Nicolas Graux 	int ret = 0;
902c4dd1ba3SPatrice Chotard 	u8 reset_bit;
903c4dd1ba3SPatrice Chotard 
904c4dd1ba3SPatrice Chotard 	if (id_val == STMPE811_ID)
905c4dd1ba3SPatrice Chotard 		/* STMPE801 and STMPE610 use bit 1 of SYS_CTRL register */
906c4dd1ba3SPatrice Chotard 		reset_bit = STMPE811_SYS_CTRL_RESET;
907c4dd1ba3SPatrice Chotard 	else
908c4dd1ba3SPatrice Chotard 		/* all other STMPE variant use bit 7 of SYS_CTRL register */
909c4dd1ba3SPatrice Chotard 		reset_bit = STMPE_SYS_CTRL_RESET;
910230f13a5SJean-Nicolas Graux 
9110f4be8cfSPatrice Chotard 	ret = __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL],
912c4dd1ba3SPatrice Chotard 			       reset_bit, reset_bit);
913230f13a5SJean-Nicolas Graux 	if (ret < 0)
914230f13a5SJean-Nicolas Graux 		return ret;
915230f13a5SJean-Nicolas Graux 
916f4058420SLinus Walleij 	msleep(10);
917f4058420SLinus Walleij 
918230f13a5SJean-Nicolas Graux 	timeout = jiffies + msecs_to_jiffies(100);
919230f13a5SJean-Nicolas Graux 	while (time_before(jiffies, timeout)) {
9200f4be8cfSPatrice Chotard 		ret = __stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL]);
921230f13a5SJean-Nicolas Graux 		if (ret < 0)
922230f13a5SJean-Nicolas Graux 			return ret;
923c4dd1ba3SPatrice Chotard 		if (!(ret & reset_bit))
924230f13a5SJean-Nicolas Graux 			return 0;
925230f13a5SJean-Nicolas Graux 		usleep_range(100, 200);
92652397fe1SSachin Kamat 	}
927230f13a5SJean-Nicolas Graux 	return -EIO;
928230f13a5SJean-Nicolas Graux }
929230f13a5SJean-Nicolas Graux 
930230f13a5SJean-Nicolas Graux static struct stmpe_variant_info stmpe1801 = {
931230f13a5SJean-Nicolas Graux 	.name		= "stmpe1801",
932230f13a5SJean-Nicolas Graux 	.id_val		= STMPE1801_ID,
933230f13a5SJean-Nicolas Graux 	.id_mask	= 0xfff0,
934230f13a5SJean-Nicolas Graux 	.num_gpios	= 18,
935230f13a5SJean-Nicolas Graux 	.af_bits	= 0,
936230f13a5SJean-Nicolas Graux 	.regs		= stmpe1801_regs,
937230f13a5SJean-Nicolas Graux 	.blocks		= stmpe1801_blocks,
938230f13a5SJean-Nicolas Graux 	.num_blocks	= ARRAY_SIZE(stmpe1801_blocks),
939230f13a5SJean-Nicolas Graux 	.num_irqs	= STMPE1801_NR_INTERNAL_IRQS,
940230f13a5SJean-Nicolas Graux 	.enable		= stmpe1801_enable,
941230f13a5SJean-Nicolas Graux 	/* stmpe1801 do not have any gpio alternate function */
942230f13a5SJean-Nicolas Graux 	.get_altfunc	= NULL,
943230f13a5SJean-Nicolas Graux };
944230f13a5SJean-Nicolas Graux 
945230f13a5SJean-Nicolas Graux /*
94627e34995SRabin Vincent  * STMPE24XX
94727e34995SRabin Vincent  */
94827e34995SRabin Vincent 
94927e34995SRabin Vincent static const u8 stmpe24xx_regs[] = {
95027e34995SRabin Vincent 	[STMPE_IDX_CHIP_ID]	= STMPE24XX_REG_CHIP_ID,
9510f4be8cfSPatrice Chotard 	[STMPE_IDX_SYS_CTRL]	= STMPE24XX_REG_SYS_CTRL,
9520f4be8cfSPatrice Chotard 	[STMPE_IDX_SYS_CTRL2]	= STMPE24XX_REG_SYS_CTRL2,
95327e34995SRabin Vincent 	[STMPE_IDX_ICR_LSB]	= STMPE24XX_REG_ICR_LSB,
954897ac667SPatrice Chotard 	[STMPE_IDX_IER_MSB]	= STMPE24XX_REG_IER_MSB,
95527e34995SRabin Vincent 	[STMPE_IDX_IER_LSB]	= STMPE24XX_REG_IER_LSB,
95627e34995SRabin Vincent 	[STMPE_IDX_ISR_MSB]	= STMPE24XX_REG_ISR_MSB,
95727e34995SRabin Vincent 	[STMPE_IDX_GPMR_LSB]	= STMPE24XX_REG_GPMR_LSB,
958897ac667SPatrice Chotard 	[STMPE_IDX_GPMR_CSB]	= STMPE24XX_REG_GPMR_CSB,
959897ac667SPatrice Chotard 	[STMPE_IDX_GPMR_MSB]	= STMPE24XX_REG_GPMR_MSB,
96027e34995SRabin Vincent 	[STMPE_IDX_GPSR_LSB]	= STMPE24XX_REG_GPSR_LSB,
961897ac667SPatrice Chotard 	[STMPE_IDX_GPSR_CSB]	= STMPE24XX_REG_GPSR_CSB,
962897ac667SPatrice Chotard 	[STMPE_IDX_GPSR_MSB]	= STMPE24XX_REG_GPSR_MSB,
96327e34995SRabin Vincent 	[STMPE_IDX_GPCR_LSB]	= STMPE24XX_REG_GPCR_LSB,
964897ac667SPatrice Chotard 	[STMPE_IDX_GPCR_CSB]	= STMPE24XX_REG_GPCR_CSB,
965897ac667SPatrice Chotard 	[STMPE_IDX_GPCR_MSB]	= STMPE24XX_REG_GPCR_MSB,
96627e34995SRabin Vincent 	[STMPE_IDX_GPDR_LSB]	= STMPE24XX_REG_GPDR_LSB,
967897ac667SPatrice Chotard 	[STMPE_IDX_GPDR_CSB]	= STMPE24XX_REG_GPDR_CSB,
968897ac667SPatrice Chotard 	[STMPE_IDX_GPDR_MSB]	= STMPE24XX_REG_GPDR_MSB,
96927e34995SRabin Vincent 	[STMPE_IDX_GPRER_LSB]	= STMPE24XX_REG_GPRER_LSB,
970897ac667SPatrice Chotard 	[STMPE_IDX_GPRER_CSB]	= STMPE24XX_REG_GPRER_CSB,
971897ac667SPatrice Chotard 	[STMPE_IDX_GPRER_MSB]	= STMPE24XX_REG_GPRER_MSB,
97227e34995SRabin Vincent 	[STMPE_IDX_GPFER_LSB]	= STMPE24XX_REG_GPFER_LSB,
973897ac667SPatrice Chotard 	[STMPE_IDX_GPFER_CSB]	= STMPE24XX_REG_GPFER_CSB,
974897ac667SPatrice Chotard 	[STMPE_IDX_GPFER_MSB]	= STMPE24XX_REG_GPFER_MSB,
97580e1dd82SLinus Walleij 	[STMPE_IDX_GPPUR_LSB]	= STMPE24XX_REG_GPPUR_LSB,
97680e1dd82SLinus Walleij 	[STMPE_IDX_GPPDR_LSB]	= STMPE24XX_REG_GPPDR_LSB,
97727e34995SRabin Vincent 	[STMPE_IDX_GPAFR_U_MSB]	= STMPE24XX_REG_GPAFR_U_MSB,
97827e34995SRabin Vincent 	[STMPE_IDX_IEGPIOR_LSB]	= STMPE24XX_REG_IEGPIOR_LSB,
979897ac667SPatrice Chotard 	[STMPE_IDX_IEGPIOR_CSB]	= STMPE24XX_REG_IEGPIOR_CSB,
980897ac667SPatrice Chotard 	[STMPE_IDX_IEGPIOR_MSB]	= STMPE24XX_REG_IEGPIOR_MSB,
98127e34995SRabin Vincent 	[STMPE_IDX_ISGPIOR_MSB]	= STMPE24XX_REG_ISGPIOR_MSB,
982897ac667SPatrice Chotard 	[STMPE_IDX_GPEDR_LSB]	= STMPE24XX_REG_GPEDR_LSB,
983897ac667SPatrice Chotard 	[STMPE_IDX_GPEDR_CSB]	= STMPE24XX_REG_GPEDR_CSB,
98427e34995SRabin Vincent 	[STMPE_IDX_GPEDR_MSB]	= STMPE24XX_REG_GPEDR_MSB,
98527e34995SRabin Vincent };
98627e34995SRabin Vincent 
98727e34995SRabin Vincent static struct stmpe_variant_block stmpe24xx_blocks[] = {
98827e34995SRabin Vincent 	{
98927e34995SRabin Vincent 		.cell	= &stmpe_gpio_cell,
99027e34995SRabin Vincent 		.irq	= STMPE24XX_IRQ_GPIOC,
99127e34995SRabin Vincent 		.block	= STMPE_BLOCK_GPIO,
99227e34995SRabin Vincent 	},
99327e34995SRabin Vincent 	{
99427e34995SRabin Vincent 		.cell	= &stmpe_keypad_cell,
99527e34995SRabin Vincent 		.irq	= STMPE24XX_IRQ_KEYPAD,
99627e34995SRabin Vincent 		.block	= STMPE_BLOCK_KEYPAD,
99727e34995SRabin Vincent 	},
998b273c5e0SLinus Walleij 	{
999b273c5e0SLinus Walleij 		.cell	= &stmpe_pwm_cell,
1000b273c5e0SLinus Walleij 		.irq	= STMPE24XX_IRQ_PWM0,
1001b273c5e0SLinus Walleij 		.block	= STMPE_BLOCK_PWM,
1002b273c5e0SLinus Walleij 	},
100327e34995SRabin Vincent };
100427e34995SRabin Vincent 
100527e34995SRabin Vincent static int stmpe24xx_enable(struct stmpe *stmpe, unsigned int blocks,
100627e34995SRabin Vincent 			    bool enable)
100727e34995SRabin Vincent {
100827e34995SRabin Vincent 	unsigned int mask = 0;
100927e34995SRabin Vincent 
101027e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_GPIO)
101127e34995SRabin Vincent 		mask |= STMPE24XX_SYS_CTRL_ENABLE_GPIO;
101227e34995SRabin Vincent 
101327e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_KEYPAD)
101427e34995SRabin Vincent 		mask |= STMPE24XX_SYS_CTRL_ENABLE_KPC;
101527e34995SRabin Vincent 
10160f4be8cfSPatrice Chotard 	return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], mask,
101727e34995SRabin Vincent 				enable ? mask : 0);
101827e34995SRabin Vincent }
101927e34995SRabin Vincent 
102027e34995SRabin Vincent static int stmpe24xx_get_altfunc(struct stmpe *stmpe, enum stmpe_block block)
102127e34995SRabin Vincent {
102227e34995SRabin Vincent 	switch (block) {
102327e34995SRabin Vincent 	case STMPE_BLOCK_ROTATOR:
102427e34995SRabin Vincent 		return 2;
102527e34995SRabin Vincent 
102627e34995SRabin Vincent 	case STMPE_BLOCK_KEYPAD:
1027f6d10341SLinus Walleij 	case STMPE_BLOCK_PWM:
102827e34995SRabin Vincent 		return 1;
102927e34995SRabin Vincent 
103027e34995SRabin Vincent 	case STMPE_BLOCK_GPIO:
103127e34995SRabin Vincent 	default:
103227e34995SRabin Vincent 		return 0;
103327e34995SRabin Vincent 	}
103427e34995SRabin Vincent }
103527e34995SRabin Vincent 
103627e34995SRabin Vincent static struct stmpe_variant_info stmpe2401 = {
103727e34995SRabin Vincent 	.name		= "stmpe2401",
103827e34995SRabin Vincent 	.id_val		= 0x0101,
103927e34995SRabin Vincent 	.id_mask	= 0xffff,
104027e34995SRabin Vincent 	.num_gpios	= 24,
104127e34995SRabin Vincent 	.af_bits	= 2,
104227e34995SRabin Vincent 	.regs		= stmpe24xx_regs,
104327e34995SRabin Vincent 	.blocks		= stmpe24xx_blocks,
104427e34995SRabin Vincent 	.num_blocks	= ARRAY_SIZE(stmpe24xx_blocks),
104527e34995SRabin Vincent 	.num_irqs	= STMPE24XX_NR_INTERNAL_IRQS,
104627e34995SRabin Vincent 	.enable		= stmpe24xx_enable,
104727e34995SRabin Vincent 	.get_altfunc	= stmpe24xx_get_altfunc,
104827e34995SRabin Vincent };
104927e34995SRabin Vincent 
105027e34995SRabin Vincent static struct stmpe_variant_info stmpe2403 = {
105127e34995SRabin Vincent 	.name		= "stmpe2403",
105227e34995SRabin Vincent 	.id_val		= 0x0120,
105327e34995SRabin Vincent 	.id_mask	= 0xffff,
105427e34995SRabin Vincent 	.num_gpios	= 24,
105527e34995SRabin Vincent 	.af_bits	= 2,
105627e34995SRabin Vincent 	.regs		= stmpe24xx_regs,
105727e34995SRabin Vincent 	.blocks		= stmpe24xx_blocks,
105827e34995SRabin Vincent 	.num_blocks	= ARRAY_SIZE(stmpe24xx_blocks),
105927e34995SRabin Vincent 	.num_irqs	= STMPE24XX_NR_INTERNAL_IRQS,
106027e34995SRabin Vincent 	.enable		= stmpe24xx_enable,
106127e34995SRabin Vincent 	.get_altfunc	= stmpe24xx_get_altfunc,
10625981f4e6SSundar R Iyer 	.enable_autosleep	= stmpe1601_autosleep, /* same as stmpe1601 */
106327e34995SRabin Vincent };
106427e34995SRabin Vincent 
1065e31f9b82SChris Blair static struct stmpe_variant_info *stmpe_variant_info[STMPE_NBR_PARTS] = {
10661cda2394SViresh Kumar 	[STMPE610]	= &stmpe610,
10677f7f4ea1SViresh Kumar 	[STMPE801]	= &stmpe801,
106827e34995SRabin Vincent 	[STMPE811]	= &stmpe811,
10696bb9f0d9SPatrice Chotard 	[STMPE1600]	= &stmpe1600,
107027e34995SRabin Vincent 	[STMPE1601]	= &stmpe1601,
1071230f13a5SJean-Nicolas Graux 	[STMPE1801]	= &stmpe1801,
107227e34995SRabin Vincent 	[STMPE2401]	= &stmpe2401,
107327e34995SRabin Vincent 	[STMPE2403]	= &stmpe2403,
107427e34995SRabin Vincent };
107527e34995SRabin Vincent 
1076e31f9b82SChris Blair /*
1077e31f9b82SChris Blair  * These devices can be connected in a 'no-irq' configuration - the irq pin
1078e31f9b82SChris Blair  * is not used and the device cannot interrupt the CPU. Here we only list
1079e31f9b82SChris Blair  * devices which support this configuration - the driver will fail probing
1080e31f9b82SChris Blair  * for any devices not listed here which are configured in this way.
1081e31f9b82SChris Blair  */
1082e31f9b82SChris Blair static struct stmpe_variant_info *stmpe_noirq_variant_info[STMPE_NBR_PARTS] = {
1083e31f9b82SChris Blair 	[STMPE801]	= &stmpe801_noirq,
1084e31f9b82SChris Blair };
1085e31f9b82SChris Blair 
108627e34995SRabin Vincent static irqreturn_t stmpe_irq(int irq, void *data)
108727e34995SRabin Vincent {
108827e34995SRabin Vincent 	struct stmpe *stmpe = data;
108927e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
109027e34995SRabin Vincent 	int num = DIV_ROUND_UP(variant->num_irqs, 8);
1091230f13a5SJean-Nicolas Graux 	u8 israddr;
10927929fa77SLee Jones 	u8 isr[3];
109327e34995SRabin Vincent 	int ret;
109427e34995SRabin Vincent 	int i;
109527e34995SRabin Vincent 
10966bb9f0d9SPatrice Chotard 	if (variant->id_val == STMPE801_ID ||
10976bb9f0d9SPatrice Chotard 	    variant->id_val == STMPE1600_ID) {
1098*9ff80e2dSMarc Zyngier 		int base = irq_find_mapping(stmpe->domain, 0);
109976f93992SLee Jones 
110076f93992SLee Jones 		handle_nested_irq(base);
11017f7f4ea1SViresh Kumar 		return IRQ_HANDLED;
11027f7f4ea1SViresh Kumar 	}
11037f7f4ea1SViresh Kumar 
1104230f13a5SJean-Nicolas Graux 	if (variant->id_val == STMPE1801_ID)
1105230f13a5SJean-Nicolas Graux 		israddr = stmpe->regs[STMPE_IDX_ISR_LSB];
1106230f13a5SJean-Nicolas Graux 	else
1107230f13a5SJean-Nicolas Graux 		israddr = stmpe->regs[STMPE_IDX_ISR_MSB];
1108230f13a5SJean-Nicolas Graux 
110927e34995SRabin Vincent 	ret = stmpe_block_read(stmpe, israddr, num, isr);
111027e34995SRabin Vincent 	if (ret < 0)
111127e34995SRabin Vincent 		return IRQ_NONE;
111227e34995SRabin Vincent 
111327e34995SRabin Vincent 	for (i = 0; i < num; i++) {
111427e34995SRabin Vincent 		int bank = num - i - 1;
111527e34995SRabin Vincent 		u8 status = isr[i];
111627e34995SRabin Vincent 		u8 clear;
111727e34995SRabin Vincent 
111827e34995SRabin Vincent 		status &= stmpe->ier[bank];
111927e34995SRabin Vincent 		if (!status)
112027e34995SRabin Vincent 			continue;
112127e34995SRabin Vincent 
112227e34995SRabin Vincent 		clear = status;
112327e34995SRabin Vincent 		while (status) {
112427e34995SRabin Vincent 			int bit = __ffs(status);
112527e34995SRabin Vincent 			int line = bank * 8 + bit;
1126*9ff80e2dSMarc Zyngier 			int nestedirq = irq_find_mapping(stmpe->domain, line);
112727e34995SRabin Vincent 
112876f93992SLee Jones 			handle_nested_irq(nestedirq);
112927e34995SRabin Vincent 			status &= ~(1 << bit);
113027e34995SRabin Vincent 		}
113127e34995SRabin Vincent 
113227e34995SRabin Vincent 		stmpe_reg_write(stmpe, israddr + i, clear);
113327e34995SRabin Vincent 	}
113427e34995SRabin Vincent 
113527e34995SRabin Vincent 	return IRQ_HANDLED;
113627e34995SRabin Vincent }
113727e34995SRabin Vincent 
113843b8c084SMark Brown static void stmpe_irq_lock(struct irq_data *data)
113927e34995SRabin Vincent {
114043b8c084SMark Brown 	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
114127e34995SRabin Vincent 
114227e34995SRabin Vincent 	mutex_lock(&stmpe->irq_lock);
114327e34995SRabin Vincent }
114427e34995SRabin Vincent 
114543b8c084SMark Brown static void stmpe_irq_sync_unlock(struct irq_data *data)
114627e34995SRabin Vincent {
114743b8c084SMark Brown 	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
114827e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
114927e34995SRabin Vincent 	int num = DIV_ROUND_UP(variant->num_irqs, 8);
115027e34995SRabin Vincent 	int i;
115127e34995SRabin Vincent 
115227e34995SRabin Vincent 	for (i = 0; i < num; i++) {
115327e34995SRabin Vincent 		u8 new = stmpe->ier[i];
115427e34995SRabin Vincent 		u8 old = stmpe->oldier[i];
115527e34995SRabin Vincent 
115627e34995SRabin Vincent 		if (new == old)
115727e34995SRabin Vincent 			continue;
115827e34995SRabin Vincent 
115927e34995SRabin Vincent 		stmpe->oldier[i] = new;
1160897ac667SPatrice Chotard 		stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_IER_LSB + i], new);
116127e34995SRabin Vincent 	}
116227e34995SRabin Vincent 
116327e34995SRabin Vincent 	mutex_unlock(&stmpe->irq_lock);
116427e34995SRabin Vincent }
116527e34995SRabin Vincent 
116643b8c084SMark Brown static void stmpe_irq_mask(struct irq_data *data)
116727e34995SRabin Vincent {
116843b8c084SMark Brown 	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
116976f93992SLee Jones 	int offset = data->hwirq;
117027e34995SRabin Vincent 	int regoffset = offset / 8;
117127e34995SRabin Vincent 	int mask = 1 << (offset % 8);
117227e34995SRabin Vincent 
117327e34995SRabin Vincent 	stmpe->ier[regoffset] &= ~mask;
117427e34995SRabin Vincent }
117527e34995SRabin Vincent 
117643b8c084SMark Brown static void stmpe_irq_unmask(struct irq_data *data)
117727e34995SRabin Vincent {
117843b8c084SMark Brown 	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
117976f93992SLee Jones 	int offset = data->hwirq;
118027e34995SRabin Vincent 	int regoffset = offset / 8;
118127e34995SRabin Vincent 	int mask = 1 << (offset % 8);
118227e34995SRabin Vincent 
118327e34995SRabin Vincent 	stmpe->ier[regoffset] |= mask;
118427e34995SRabin Vincent }
118527e34995SRabin Vincent 
118627e34995SRabin Vincent static struct irq_chip stmpe_irq_chip = {
118727e34995SRabin Vincent 	.name			= "stmpe",
118843b8c084SMark Brown 	.irq_bus_lock		= stmpe_irq_lock,
118943b8c084SMark Brown 	.irq_bus_sync_unlock	= stmpe_irq_sync_unlock,
119043b8c084SMark Brown 	.irq_mask		= stmpe_irq_mask,
119143b8c084SMark Brown 	.irq_unmask		= stmpe_irq_unmask,
119227e34995SRabin Vincent };
119327e34995SRabin Vincent 
119476f93992SLee Jones static int stmpe_irq_map(struct irq_domain *d, unsigned int virq,
119576f93992SLee Jones                                 irq_hw_number_t hwirq)
119627e34995SRabin Vincent {
119776f93992SLee Jones 	struct stmpe *stmpe = d->host_data;
11987f7f4ea1SViresh Kumar 	struct irq_chip *chip = NULL;
119927e34995SRabin Vincent 
12007f7f4ea1SViresh Kumar 	if (stmpe->variant->id_val != STMPE801_ID)
12017f7f4ea1SViresh Kumar 		chip = &stmpe_irq_chip;
12027f7f4ea1SViresh Kumar 
120376f93992SLee Jones 	irq_set_chip_data(virq, stmpe);
120476f93992SLee Jones 	irq_set_chip_and_handler(virq, chip, handle_edge_irq);
120576f93992SLee Jones 	irq_set_nested_thread(virq, 1);
120676f93992SLee Jones 	irq_set_noprobe(virq);
120727e34995SRabin Vincent 
120827e34995SRabin Vincent 	return 0;
120927e34995SRabin Vincent }
121027e34995SRabin Vincent 
121176f93992SLee Jones static void stmpe_irq_unmap(struct irq_domain *d, unsigned int virq)
121227e34995SRabin Vincent {
121376f93992SLee Jones 		irq_set_chip_and_handler(virq, NULL, NULL);
121476f93992SLee Jones 		irq_set_chip_data(virq, NULL);
121527e34995SRabin Vincent }
121676f93992SLee Jones 
12177ce7b26fSKrzysztof Kozlowski static const struct irq_domain_ops stmpe_irq_ops = {
121876f93992SLee Jones         .map    = stmpe_irq_map,
121976f93992SLee Jones         .unmap  = stmpe_irq_unmap,
122076f93992SLee Jones         .xlate  = irq_domain_xlate_twocell,
122176f93992SLee Jones };
122276f93992SLee Jones 
1223612b95cdSGreg Kroah-Hartman static int stmpe_irq_init(struct stmpe *stmpe, struct device_node *np)
122476f93992SLee Jones {
1225b20a4371SLee Jones 	int base = 0;
122676f93992SLee Jones 	int num_irqs = stmpe->variant->num_irqs;
122776f93992SLee Jones 
1228b20a4371SLee Jones 	stmpe->domain = irq_domain_add_simple(np, num_irqs, base,
1229b20a4371SLee Jones 					      &stmpe_irq_ops, stmpe);
123076f93992SLee Jones 	if (!stmpe->domain) {
123176f93992SLee Jones 		dev_err(stmpe->dev, "Failed to create irqdomain\n");
123276f93992SLee Jones 		return -ENOSYS;
123376f93992SLee Jones 	}
123476f93992SLee Jones 
123576f93992SLee Jones 	return 0;
123627e34995SRabin Vincent }
123727e34995SRabin Vincent 
1238612b95cdSGreg Kroah-Hartman static int stmpe_chip_init(struct stmpe *stmpe)
123927e34995SRabin Vincent {
124027e34995SRabin Vincent 	unsigned int irq_trigger = stmpe->pdata->irq_trigger;
12415981f4e6SSundar R Iyer 	int autosleep_timeout = stmpe->pdata->autosleep_timeout;
124227e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
1243e31f9b82SChris Blair 	u8 icr = 0;
124427e34995SRabin Vincent 	unsigned int id;
124527e34995SRabin Vincent 	u8 data[2];
124627e34995SRabin Vincent 	int ret;
124727e34995SRabin Vincent 
124827e34995SRabin Vincent 	ret = stmpe_block_read(stmpe, stmpe->regs[STMPE_IDX_CHIP_ID],
124927e34995SRabin Vincent 			       ARRAY_SIZE(data), data);
125027e34995SRabin Vincent 	if (ret < 0)
125127e34995SRabin Vincent 		return ret;
125227e34995SRabin Vincent 
125327e34995SRabin Vincent 	id = (data[0] << 8) | data[1];
125427e34995SRabin Vincent 	if ((id & variant->id_mask) != variant->id_val) {
125527e34995SRabin Vincent 		dev_err(stmpe->dev, "unknown chip id: %#x\n", id);
125627e34995SRabin Vincent 		return -EINVAL;
125727e34995SRabin Vincent 	}
125827e34995SRabin Vincent 
125927e34995SRabin Vincent 	dev_info(stmpe->dev, "%s detected, chip id: %#x\n", variant->name, id);
126027e34995SRabin Vincent 
126127e34995SRabin Vincent 	/* Disable all modules -- subdrivers should enable what they need. */
126227e34995SRabin Vincent 	ret = stmpe_disable(stmpe, ~0);
126327e34995SRabin Vincent 	if (ret)
126427e34995SRabin Vincent 		return ret;
126527e34995SRabin Vincent 
1266c4dd1ba3SPatrice Chotard 	ret =  stmpe_reset(stmpe);
1267230f13a5SJean-Nicolas Graux 	if (ret < 0)
1268230f13a5SJean-Nicolas Graux 		return ret;
1269230f13a5SJean-Nicolas Graux 
1270e31f9b82SChris Blair 	if (stmpe->irq >= 0) {
12716bb9f0d9SPatrice Chotard 		if (id == STMPE801_ID || id == STMPE1600_ID)
1272c16bee78SPatrice Chotard 			icr = STMPE_SYS_CTRL_INT_EN;
12737f7f4ea1SViresh Kumar 		else
12747f7f4ea1SViresh Kumar 			icr = STMPE_ICR_LSB_GIM;
12757f7f4ea1SViresh Kumar 
12766bb9f0d9SPatrice Chotard 		/* STMPE801 and STMPE1600 don't support Edge interrupts */
12776bb9f0d9SPatrice Chotard 		if (id != STMPE801_ID && id != STMPE1600_ID) {
127827e34995SRabin Vincent 			if (irq_trigger == IRQF_TRIGGER_FALLING ||
127927e34995SRabin Vincent 					irq_trigger == IRQF_TRIGGER_RISING)
128027e34995SRabin Vincent 				icr |= STMPE_ICR_LSB_EDGE;
12817f7f4ea1SViresh Kumar 		}
128227e34995SRabin Vincent 
128327e34995SRabin Vincent 		if (irq_trigger == IRQF_TRIGGER_RISING ||
12847f7f4ea1SViresh Kumar 				irq_trigger == IRQF_TRIGGER_HIGH) {
12856bb9f0d9SPatrice Chotard 			if (id == STMPE801_ID || id == STMPE1600_ID)
1286c16bee78SPatrice Chotard 				icr |= STMPE_SYS_CTRL_INT_HI;
12877f7f4ea1SViresh Kumar 			else
128827e34995SRabin Vincent 				icr |= STMPE_ICR_LSB_HIGH;
12897f7f4ea1SViresh Kumar 		}
1290e31f9b82SChris Blair 	}
129127e34995SRabin Vincent 
12925981f4e6SSundar R Iyer 	if (stmpe->pdata->autosleep) {
12935981f4e6SSundar R Iyer 		ret = stmpe_autosleep(stmpe, autosleep_timeout);
12945981f4e6SSundar R Iyer 		if (ret)
12955981f4e6SSundar R Iyer 			return ret;
12965981f4e6SSundar R Iyer 	}
12975981f4e6SSundar R Iyer 
129827e34995SRabin Vincent 	return stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_ICR_LSB], icr);
129927e34995SRabin Vincent }
130027e34995SRabin Vincent 
13016bbb3c4cSGeert Uytterhoeven static int stmpe_add_device(struct stmpe *stmpe, const struct mfd_cell *cell)
130227e34995SRabin Vincent {
130327e34995SRabin Vincent 	return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1,
13049e9dc7d9SLinus Walleij 			       NULL, 0, stmpe->domain);
130527e34995SRabin Vincent }
130627e34995SRabin Vincent 
1307612b95cdSGreg Kroah-Hartman static int stmpe_devices_init(struct stmpe *stmpe)
130827e34995SRabin Vincent {
130927e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
131027e34995SRabin Vincent 	unsigned int platform_blocks = stmpe->pdata->blocks;
131127e34995SRabin Vincent 	int ret = -EINVAL;
13127da0cbfcSLee Jones 	int i, j;
131327e34995SRabin Vincent 
131427e34995SRabin Vincent 	for (i = 0; i < variant->num_blocks; i++) {
131527e34995SRabin Vincent 		struct stmpe_variant_block *block = &variant->blocks[i];
131627e34995SRabin Vincent 
131727e34995SRabin Vincent 		if (!(platform_blocks & block->block))
131827e34995SRabin Vincent 			continue;
131927e34995SRabin Vincent 
13207da0cbfcSLee Jones 		for (j = 0; j < block->cell->num_resources; j++) {
13217da0cbfcSLee Jones 			struct resource *res =
13227da0cbfcSLee Jones 				(struct resource *) &block->cell->resources[j];
13237da0cbfcSLee Jones 
13247da0cbfcSLee Jones 			/* Dynamically fill in a variant's IRQ. */
13257da0cbfcSLee Jones 			if (res->flags & IORESOURCE_IRQ)
13267da0cbfcSLee Jones 				res->start = res->end = block->irq + j;
13277da0cbfcSLee Jones 		}
13287da0cbfcSLee Jones 
132927e34995SRabin Vincent 		platform_blocks &= ~block->block;
13307da0cbfcSLee Jones 		ret = stmpe_add_device(stmpe, block->cell);
133127e34995SRabin Vincent 		if (ret)
133227e34995SRabin Vincent 			return ret;
133327e34995SRabin Vincent 	}
133427e34995SRabin Vincent 
133527e34995SRabin Vincent 	if (platform_blocks)
133627e34995SRabin Vincent 		dev_warn(stmpe->dev,
133727e34995SRabin Vincent 			 "platform wants blocks (%#x) not present on variant",
133827e34995SRabin Vincent 			 platform_blocks);
133927e34995SRabin Vincent 
134027e34995SRabin Vincent 	return ret;
134127e34995SRabin Vincent }
134227e34995SRabin Vincent 
1343a9c4055dSMark Brown static void stmpe_of_probe(struct stmpe_platform_data *pdata,
1344a9c4055dSMark Brown 			   struct device_node *np)
1345909582caSLee Jones {
1346909582caSLee Jones 	struct device_node *child;
1347909582caSLee Jones 
1348408a3fa8SGabriel Fernandez 	pdata->id = of_alias_get_id(np, "stmpe-i2c");
1349408a3fa8SGabriel Fernandez 	if (pdata->id < 0)
1350ac713cc9SVipul Kumar Samar 		pdata->id = -1;
1351408a3fa8SGabriel Fernandez 
1352851ec596SSean Cross 	pdata->irq_gpio = of_get_named_gpio_flags(np, "irq-gpio", 0,
1353851ec596SSean Cross 				&pdata->irq_trigger);
1354851ec596SSean Cross 	if (gpio_is_valid(pdata->irq_gpio))
1355851ec596SSean Cross 		pdata->irq_over_gpio = 1;
1356851ec596SSean Cross 	else
1357ac713cc9SVipul Kumar Samar 		pdata->irq_trigger = IRQF_TRIGGER_NONE;
1358ac713cc9SVipul Kumar Samar 
1359909582caSLee Jones 	of_property_read_u32(np, "st,autosleep-timeout",
1360909582caSLee Jones 			&pdata->autosleep_timeout);
1361909582caSLee Jones 
1362909582caSLee Jones 	pdata->autosleep = (pdata->autosleep_timeout) ? true : false;
1363909582caSLee Jones 
1364909582caSLee Jones 	for_each_child_of_node(np, child) {
136538df91ccSRob Herring 		if (of_node_name_eq(child, "stmpe_gpio")) {
1366909582caSLee Jones 			pdata->blocks |= STMPE_BLOCK_GPIO;
136738df91ccSRob Herring 		} else if (of_node_name_eq(child, "stmpe_keypad")) {
1368909582caSLee Jones 			pdata->blocks |= STMPE_BLOCK_KEYPAD;
136938df91ccSRob Herring 		} else if (of_node_name_eq(child, "stmpe_touchscreen")) {
1370909582caSLee Jones 			pdata->blocks |= STMPE_BLOCK_TOUCHSCREEN;
137138df91ccSRob Herring 		} else if (of_node_name_eq(child, "stmpe_adc")) {
1372909582caSLee Jones 			pdata->blocks |= STMPE_BLOCK_ADC;
137338df91ccSRob Herring 		} else if (of_node_name_eq(child, "stmpe_pwm")) {
1374ac713cc9SVipul Kumar Samar 			pdata->blocks |= STMPE_BLOCK_PWM;
137538df91ccSRob Herring 		} else if (of_node_name_eq(child, "stmpe_rotator")) {
1376ac713cc9SVipul Kumar Samar 			pdata->blocks |= STMPE_BLOCK_ROTATOR;
1377909582caSLee Jones 		}
1378909582caSLee Jones 	}
1379909582caSLee Jones }
1380909582caSLee Jones 
13811a6e4b74SViresh Kumar /* Called from client specific probe routines */
1382c00572bcSLee Jones int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum)
1383208c4343SSundar Iyer {
1384fc1882dcSLinus Walleij 	struct stmpe_platform_data *pdata;
1385909582caSLee Jones 	struct device_node *np = ci->dev->of_node;
138627e34995SRabin Vincent 	struct stmpe *stmpe;
138727e34995SRabin Vincent 	int ret;
13886377cfa3SStefan Agner 	u32 val;
138927e34995SRabin Vincent 
1390cb5faba9SViresh Kumar 	pdata = devm_kzalloc(ci->dev, sizeof(*pdata), GFP_KERNEL);
139127e34995SRabin Vincent 	if (!pdata)
1392909582caSLee Jones 		return -ENOMEM;
1393909582caSLee Jones 
1394909582caSLee Jones 	stmpe_of_probe(pdata, np);
1395a200e320SGabriel Fernandez 
1396a200e320SGabriel Fernandez 	if (of_find_property(np, "interrupts", NULL) == NULL)
1397a200e320SGabriel Fernandez 		ci->irq = -1;
139827e34995SRabin Vincent 
1399cb5faba9SViresh Kumar 	stmpe = devm_kzalloc(ci->dev, sizeof(struct stmpe), GFP_KERNEL);
140027e34995SRabin Vincent 	if (!stmpe)
140127e34995SRabin Vincent 		return -ENOMEM;
140227e34995SRabin Vincent 
140327e34995SRabin Vincent 	mutex_init(&stmpe->irq_lock);
140427e34995SRabin Vincent 	mutex_init(&stmpe->lock);
140527e34995SRabin Vincent 
14066377cfa3SStefan Agner 	if (!of_property_read_u32(np, "st,sample-time", &val))
14076377cfa3SStefan Agner 		stmpe->sample_time = val;
14086377cfa3SStefan Agner 	if (!of_property_read_u32(np, "st,mod-12b", &val))
14096377cfa3SStefan Agner 		stmpe->mod_12b = val;
14106377cfa3SStefan Agner 	if (!of_property_read_u32(np, "st,ref-sel", &val))
14116377cfa3SStefan Agner 		stmpe->ref_sel = val;
14126377cfa3SStefan Agner 	if (!of_property_read_u32(np, "st,adc-freq", &val))
14136377cfa3SStefan Agner 		stmpe->adc_freq = val;
14146377cfa3SStefan Agner 
14151a6e4b74SViresh Kumar 	stmpe->dev = ci->dev;
14161a6e4b74SViresh Kumar 	stmpe->client = ci->client;
141727e34995SRabin Vincent 	stmpe->pdata = pdata;
14181a6e4b74SViresh Kumar 	stmpe->ci = ci;
14191a6e4b74SViresh Kumar 	stmpe->partnum = partnum;
14201a6e4b74SViresh Kumar 	stmpe->variant = stmpe_variant_info[partnum];
142127e34995SRabin Vincent 	stmpe->regs = stmpe->variant->regs;
142227e34995SRabin Vincent 	stmpe->num_gpios = stmpe->variant->num_gpios;
14239c9e3214SLinus Walleij 	stmpe->vcc = devm_regulator_get_optional(ci->dev, "vcc");
14249c9e3214SLinus Walleij 	if (!IS_ERR(stmpe->vcc)) {
14259c9e3214SLinus Walleij 		ret = regulator_enable(stmpe->vcc);
14269c9e3214SLinus Walleij 		if (ret)
14279c9e3214SLinus Walleij 			dev_warn(ci->dev, "failed to enable VCC supply\n");
14289c9e3214SLinus Walleij 	}
14299c9e3214SLinus Walleij 	stmpe->vio = devm_regulator_get_optional(ci->dev, "vio");
14309c9e3214SLinus Walleij 	if (!IS_ERR(stmpe->vio)) {
14319c9e3214SLinus Walleij 		ret = regulator_enable(stmpe->vio);
14329c9e3214SLinus Walleij 		if (ret)
14339c9e3214SLinus Walleij 			dev_warn(ci->dev, "failed to enable VIO supply\n");
14349c9e3214SLinus Walleij 	}
14351a6e4b74SViresh Kumar 	dev_set_drvdata(stmpe->dev, stmpe);
143627e34995SRabin Vincent 
14371a6e4b74SViresh Kumar 	if (ci->init)
14381a6e4b74SViresh Kumar 		ci->init(stmpe);
143927e34995SRabin Vincent 
144073de16dbSViresh Kumar 	if (pdata->irq_over_gpio) {
1441cb5faba9SViresh Kumar 		ret = devm_gpio_request_one(ci->dev, pdata->irq_gpio,
1442cb5faba9SViresh Kumar 				GPIOF_DIR_IN, "stmpe");
144373de16dbSViresh Kumar 		if (ret) {
144473de16dbSViresh Kumar 			dev_err(stmpe->dev, "failed to request IRQ GPIO: %d\n",
144573de16dbSViresh Kumar 					ret);
1446cb5faba9SViresh Kumar 			return ret;
144773de16dbSViresh Kumar 		}
144873de16dbSViresh Kumar 
144973de16dbSViresh Kumar 		stmpe->irq = gpio_to_irq(pdata->irq_gpio);
145073de16dbSViresh Kumar 	} else {
14511a6e4b74SViresh Kumar 		stmpe->irq = ci->irq;
145273de16dbSViresh Kumar 	}
145373de16dbSViresh Kumar 
1454e31f9b82SChris Blair 	if (stmpe->irq < 0) {
1455e31f9b82SChris Blair 		/* use alternate variant info for no-irq mode, if supported */
1456e31f9b82SChris Blair 		dev_info(stmpe->dev,
1457e31f9b82SChris Blair 			"%s configured in no-irq mode by platform data\n",
1458e31f9b82SChris Blair 			stmpe->variant->name);
1459e31f9b82SChris Blair 		if (!stmpe_noirq_variant_info[stmpe->partnum]) {
1460e31f9b82SChris Blair 			dev_err(stmpe->dev,
1461e31f9b82SChris Blair 				"%s does not support no-irq mode!\n",
1462e31f9b82SChris Blair 				stmpe->variant->name);
1463cb5faba9SViresh Kumar 			return -ENODEV;
1464e31f9b82SChris Blair 		}
1465e31f9b82SChris Blair 		stmpe->variant = stmpe_noirq_variant_info[stmpe->partnum];
1466ac713cc9SVipul Kumar Samar 	} else if (pdata->irq_trigger == IRQF_TRIGGER_NONE) {
14671a5595cbSJavier Martinez Canillas 		pdata->irq_trigger = irq_get_trigger_type(stmpe->irq);
1468e31f9b82SChris Blair 	}
1469e31f9b82SChris Blair 
147027e34995SRabin Vincent 	ret = stmpe_chip_init(stmpe);
147127e34995SRabin Vincent 	if (ret)
1472cb5faba9SViresh Kumar 		return ret;
147327e34995SRabin Vincent 
1474e31f9b82SChris Blair 	if (stmpe->irq >= 0) {
1475909582caSLee Jones 		ret = stmpe_irq_init(stmpe, np);
147627e34995SRabin Vincent 		if (ret)
1477cb5faba9SViresh Kumar 			return ret;
147827e34995SRabin Vincent 
1479cb5faba9SViresh Kumar 		ret = devm_request_threaded_irq(ci->dev, stmpe->irq, NULL,
1480cb5faba9SViresh Kumar 				stmpe_irq, pdata->irq_trigger | IRQF_ONESHOT,
1481e31f9b82SChris Blair 				"stmpe", stmpe);
148227e34995SRabin Vincent 		if (ret) {
1483e31f9b82SChris Blair 			dev_err(stmpe->dev, "failed to request IRQ: %d\n",
1484e31f9b82SChris Blair 					ret);
1485cb5faba9SViresh Kumar 			return ret;
148627e34995SRabin Vincent 		}
1487e31f9b82SChris Blair 	}
148827e34995SRabin Vincent 
148927e34995SRabin Vincent 	ret = stmpe_devices_init(stmpe);
1490cb5faba9SViresh Kumar 	if (!ret)
149127e34995SRabin Vincent 		return 0;
149227e34995SRabin Vincent 
1493cb5faba9SViresh Kumar 	dev_err(stmpe->dev, "failed to add children\n");
149427e34995SRabin Vincent 	mfd_remove_devices(stmpe->dev);
1495cb5faba9SViresh Kumar 
149627e34995SRabin Vincent 	return ret;
149727e34995SRabin Vincent }
149827e34995SRabin Vincent 
14991a6e4b74SViresh Kumar int stmpe_remove(struct stmpe *stmpe)
150027e34995SRabin Vincent {
15019c9e3214SLinus Walleij 	if (!IS_ERR(stmpe->vio))
15029c9e3214SLinus Walleij 		regulator_disable(stmpe->vio);
15039c9e3214SLinus Walleij 	if (!IS_ERR(stmpe->vcc))
15049c9e3214SLinus Walleij 		regulator_disable(stmpe->vcc);
15059c9e3214SLinus Walleij 
15066377cfa3SStefan Agner 	__stmpe_disable(stmpe, STMPE_BLOCK_ADC);
15076377cfa3SStefan Agner 
150827e34995SRabin Vincent 	mfd_remove_devices(stmpe->dev);
150927e34995SRabin Vincent 
151027e34995SRabin Vincent 	return 0;
151127e34995SRabin Vincent }
151227e34995SRabin Vincent 
1513208c4343SSundar Iyer #ifdef CONFIG_PM
15141a6e4b74SViresh Kumar static int stmpe_suspend(struct device *dev)
15151a6e4b74SViresh Kumar {
15161a6e4b74SViresh Kumar 	struct stmpe *stmpe = dev_get_drvdata(dev);
15171a6e4b74SViresh Kumar 
1518e31f9b82SChris Blair 	if (stmpe->irq >= 0 && device_may_wakeup(dev))
15191a6e4b74SViresh Kumar 		enable_irq_wake(stmpe->irq);
15201a6e4b74SViresh Kumar 
15211a6e4b74SViresh Kumar 	return 0;
15221a6e4b74SViresh Kumar }
15231a6e4b74SViresh Kumar 
15241a6e4b74SViresh Kumar static int stmpe_resume(struct device *dev)
15251a6e4b74SViresh Kumar {
15261a6e4b74SViresh Kumar 	struct stmpe *stmpe = dev_get_drvdata(dev);
15271a6e4b74SViresh Kumar 
1528e31f9b82SChris Blair 	if (stmpe->irq >= 0 && device_may_wakeup(dev))
15291a6e4b74SViresh Kumar 		disable_irq_wake(stmpe->irq);
15301a6e4b74SViresh Kumar 
15311a6e4b74SViresh Kumar 	return 0;
15321a6e4b74SViresh Kumar }
15331a6e4b74SViresh Kumar 
15341a6e4b74SViresh Kumar const struct dev_pm_ops stmpe_dev_pm_ops = {
1535208c4343SSundar Iyer 	.suspend	= stmpe_suspend,
1536208c4343SSundar Iyer 	.resume		= stmpe_resume,
1537208c4343SSundar Iyer };
1538208c4343SSundar Iyer #endif
1539