xref: /linux/drivers/mfd/stmpe.c (revision 104d32bd81f620bb9f67fbf7d1159c414e89f05f)
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>
11ac3e9119SDmitry Torokhov #include <linux/gpio/consumer.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>
181a6e4b74SViresh Kumar #include <linux/pm.h>
1927e34995SRabin Vincent #include <linux/slab.h>
2027e34995SRabin Vincent #include <linux/mfd/core.h>
21230f13a5SJean-Nicolas Graux #include <linux/delay.h>
229c9e3214SLinus Walleij #include <linux/regulator/consumer.h>
2327e34995SRabin Vincent #include "stmpe.h"
2427e34995SRabin Vincent 
25fc1882dcSLinus Walleij /**
26fc1882dcSLinus Walleij  * struct stmpe_platform_data - STMPE platform data
27fc1882dcSLinus Walleij  * @id: device id to distinguish between multiple STMPEs on the same board
28fc1882dcSLinus Walleij  * @blocks: bitmask of blocks to enable (use STMPE_BLOCK_*)
29fc1882dcSLinus Walleij  * @irq_trigger: IRQ trigger to use for the interrupt to the host
30fc1882dcSLinus Walleij  * @autosleep: bool to enable/disable stmpe autosleep
31fc1882dcSLinus Walleij  * @autosleep_timeout: inactivity timeout in milliseconds for autosleep
32fc1882dcSLinus Walleij  */
33fc1882dcSLinus Walleij struct stmpe_platform_data {
34fc1882dcSLinus Walleij 	int id;
35fc1882dcSLinus Walleij 	unsigned int blocks;
36fc1882dcSLinus Walleij 	unsigned int irq_trigger;
37fc1882dcSLinus Walleij 	bool autosleep;
38fc1882dcSLinus Walleij 	int autosleep_timeout;
39fc1882dcSLinus Walleij };
40fc1882dcSLinus Walleij 
4127e34995SRabin Vincent static int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks)
4227e34995SRabin Vincent {
4327e34995SRabin Vincent 	return stmpe->variant->enable(stmpe, blocks, true);
4427e34995SRabin Vincent }
4527e34995SRabin Vincent 
4627e34995SRabin Vincent static int __stmpe_disable(struct stmpe *stmpe, unsigned int blocks)
4727e34995SRabin Vincent {
4827e34995SRabin Vincent 	return stmpe->variant->enable(stmpe, blocks, false);
4927e34995SRabin Vincent }
5027e34995SRabin Vincent 
5127e34995SRabin Vincent static int __stmpe_reg_read(struct stmpe *stmpe, u8 reg)
5227e34995SRabin Vincent {
5327e34995SRabin Vincent 	int ret;
5427e34995SRabin Vincent 
551a6e4b74SViresh Kumar 	ret = stmpe->ci->read_byte(stmpe, reg);
5627e34995SRabin Vincent 	if (ret < 0)
571a6e4b74SViresh Kumar 		dev_err(stmpe->dev, "failed to read reg %#x: %d\n", reg, ret);
5827e34995SRabin Vincent 
5927e34995SRabin Vincent 	dev_vdbg(stmpe->dev, "rd: reg %#x => data %#x\n", reg, ret);
6027e34995SRabin Vincent 
6127e34995SRabin Vincent 	return ret;
6227e34995SRabin Vincent }
6327e34995SRabin Vincent 
6427e34995SRabin Vincent static int __stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val)
6527e34995SRabin Vincent {
6627e34995SRabin Vincent 	int ret;
6727e34995SRabin Vincent 
6827e34995SRabin Vincent 	dev_vdbg(stmpe->dev, "wr: reg %#x <= %#x\n", reg, val);
6927e34995SRabin Vincent 
701a6e4b74SViresh Kumar 	ret = stmpe->ci->write_byte(stmpe, reg, val);
7127e34995SRabin Vincent 	if (ret < 0)
721a6e4b74SViresh Kumar 		dev_err(stmpe->dev, "failed to write reg %#x: %d\n", reg, ret);
7327e34995SRabin Vincent 
7427e34995SRabin Vincent 	return ret;
7527e34995SRabin Vincent }
7627e34995SRabin Vincent 
7727e34995SRabin Vincent static int __stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val)
7827e34995SRabin Vincent {
7927e34995SRabin Vincent 	int ret;
8027e34995SRabin Vincent 
8127e34995SRabin Vincent 	ret = __stmpe_reg_read(stmpe, reg);
8227e34995SRabin Vincent 	if (ret < 0)
8327e34995SRabin Vincent 		return ret;
8427e34995SRabin Vincent 
8527e34995SRabin Vincent 	ret &= ~mask;
8627e34995SRabin Vincent 	ret |= val;
8727e34995SRabin Vincent 
8827e34995SRabin Vincent 	return __stmpe_reg_write(stmpe, reg, ret);
8927e34995SRabin Vincent }
9027e34995SRabin Vincent 
9127e34995SRabin Vincent static int __stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length,
9227e34995SRabin Vincent 			      u8 *values)
9327e34995SRabin Vincent {
9427e34995SRabin Vincent 	int ret;
9527e34995SRabin Vincent 
961a6e4b74SViresh Kumar 	ret = stmpe->ci->read_block(stmpe, reg, length, values);
9727e34995SRabin Vincent 	if (ret < 0)
981a6e4b74SViresh Kumar 		dev_err(stmpe->dev, "failed to read regs %#x: %d\n", reg, ret);
9927e34995SRabin Vincent 
10027e34995SRabin Vincent 	dev_vdbg(stmpe->dev, "rd: reg %#x (%d) => ret %#x\n", reg, length, ret);
10127e34995SRabin Vincent 	stmpe_dump_bytes("stmpe rd: ", values, length);
10227e34995SRabin Vincent 
10327e34995SRabin Vincent 	return ret;
10427e34995SRabin Vincent }
10527e34995SRabin Vincent 
10627e34995SRabin Vincent static int __stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length,
10727e34995SRabin Vincent 			const u8 *values)
10827e34995SRabin Vincent {
10927e34995SRabin Vincent 	int ret;
11027e34995SRabin Vincent 
11127e34995SRabin Vincent 	dev_vdbg(stmpe->dev, "wr: regs %#x (%d)\n", reg, length);
11227e34995SRabin Vincent 	stmpe_dump_bytes("stmpe wr: ", values, length);
11327e34995SRabin Vincent 
1141a6e4b74SViresh Kumar 	ret = stmpe->ci->write_block(stmpe, reg, length, values);
11527e34995SRabin Vincent 	if (ret < 0)
1161a6e4b74SViresh Kumar 		dev_err(stmpe->dev, "failed to write regs %#x: %d\n", reg, ret);
11727e34995SRabin Vincent 
11827e34995SRabin Vincent 	return ret;
11927e34995SRabin Vincent }
12027e34995SRabin Vincent 
12127e34995SRabin Vincent /**
12227e34995SRabin Vincent  * stmpe_enable - enable blocks on an STMPE device
12327e34995SRabin Vincent  * @stmpe:	Device to work on
12427e34995SRabin Vincent  * @blocks:	Mask of blocks (enum stmpe_block values) to enable
12527e34995SRabin Vincent  */
12627e34995SRabin Vincent int stmpe_enable(struct stmpe *stmpe, unsigned int blocks)
12727e34995SRabin Vincent {
12827e34995SRabin Vincent 	int ret;
12927e34995SRabin Vincent 
13027e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
13127e34995SRabin Vincent 	ret = __stmpe_enable(stmpe, blocks);
13227e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
13327e34995SRabin Vincent 
13427e34995SRabin Vincent 	return ret;
13527e34995SRabin Vincent }
13627e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_enable);
13727e34995SRabin Vincent 
13827e34995SRabin Vincent /**
13927e34995SRabin Vincent  * stmpe_disable - disable blocks on an STMPE device
14027e34995SRabin Vincent  * @stmpe:	Device to work on
14127e34995SRabin Vincent  * @blocks:	Mask of blocks (enum stmpe_block values) to enable
14227e34995SRabin Vincent  */
14327e34995SRabin Vincent int stmpe_disable(struct stmpe *stmpe, unsigned int blocks)
14427e34995SRabin Vincent {
14527e34995SRabin Vincent 	int ret;
14627e34995SRabin Vincent 
14727e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
14827e34995SRabin Vincent 	ret = __stmpe_disable(stmpe, blocks);
14927e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
15027e34995SRabin Vincent 
15127e34995SRabin Vincent 	return ret;
15227e34995SRabin Vincent }
15327e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_disable);
15427e34995SRabin Vincent 
15527e34995SRabin Vincent /**
15627e34995SRabin Vincent  * stmpe_reg_read() - read a single STMPE register
15727e34995SRabin Vincent  * @stmpe:	Device to read from
15827e34995SRabin Vincent  * @reg:	Register to read
15927e34995SRabin Vincent  */
16027e34995SRabin Vincent int stmpe_reg_read(struct stmpe *stmpe, u8 reg)
16127e34995SRabin Vincent {
16227e34995SRabin Vincent 	int ret;
16327e34995SRabin Vincent 
16427e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
16527e34995SRabin Vincent 	ret = __stmpe_reg_read(stmpe, reg);
16627e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
16727e34995SRabin Vincent 
16827e34995SRabin Vincent 	return ret;
16927e34995SRabin Vincent }
17027e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_reg_read);
17127e34995SRabin Vincent 
17227e34995SRabin Vincent /**
17327e34995SRabin Vincent  * stmpe_reg_write() - write a single STMPE register
17427e34995SRabin Vincent  * @stmpe:	Device to write to
17527e34995SRabin Vincent  * @reg:	Register to write
17627e34995SRabin Vincent  * @val:	Value to write
17727e34995SRabin Vincent  */
17827e34995SRabin Vincent int stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val)
17927e34995SRabin Vincent {
18027e34995SRabin Vincent 	int ret;
18127e34995SRabin Vincent 
18227e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
18327e34995SRabin Vincent 	ret = __stmpe_reg_write(stmpe, reg, val);
18427e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
18527e34995SRabin Vincent 
18627e34995SRabin Vincent 	return ret;
18727e34995SRabin Vincent }
18827e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_reg_write);
18927e34995SRabin Vincent 
19027e34995SRabin Vincent /**
19127e34995SRabin Vincent  * stmpe_set_bits() - set the value of a bitfield in a STMPE register
19227e34995SRabin Vincent  * @stmpe:	Device to write to
19327e34995SRabin Vincent  * @reg:	Register to write
19427e34995SRabin Vincent  * @mask:	Mask of bits to set
19527e34995SRabin Vincent  * @val:	Value to set
19627e34995SRabin Vincent  */
19727e34995SRabin Vincent int stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val)
19827e34995SRabin Vincent {
19927e34995SRabin Vincent 	int ret;
20027e34995SRabin Vincent 
20127e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
20227e34995SRabin Vincent 	ret = __stmpe_set_bits(stmpe, reg, mask, val);
20327e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
20427e34995SRabin Vincent 
20527e34995SRabin Vincent 	return ret;
20627e34995SRabin Vincent }
20727e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_set_bits);
20827e34995SRabin Vincent 
20927e34995SRabin Vincent /**
21027e34995SRabin Vincent  * stmpe_block_read() - read multiple STMPE registers
21127e34995SRabin Vincent  * @stmpe:	Device to read from
21227e34995SRabin Vincent  * @reg:	First register
21327e34995SRabin Vincent  * @length:	Number of registers
21427e34995SRabin Vincent  * @values:	Buffer to write to
21527e34995SRabin Vincent  */
21627e34995SRabin Vincent int stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values)
21727e34995SRabin Vincent {
21827e34995SRabin Vincent 	int ret;
21927e34995SRabin Vincent 
22027e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
22127e34995SRabin Vincent 	ret = __stmpe_block_read(stmpe, reg, length, values);
22227e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
22327e34995SRabin Vincent 
22427e34995SRabin Vincent 	return ret;
22527e34995SRabin Vincent }
22627e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_block_read);
22727e34995SRabin Vincent 
22827e34995SRabin Vincent /**
22927e34995SRabin Vincent  * stmpe_block_write() - write multiple STMPE registers
23027e34995SRabin Vincent  * @stmpe:	Device to write to
23127e34995SRabin Vincent  * @reg:	First register
23227e34995SRabin Vincent  * @length:	Number of registers
23327e34995SRabin Vincent  * @values:	Values to write
23427e34995SRabin Vincent  */
23527e34995SRabin Vincent int stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length,
23627e34995SRabin Vincent 		      const u8 *values)
23727e34995SRabin Vincent {
23827e34995SRabin Vincent 	int ret;
23927e34995SRabin Vincent 
24027e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
24127e34995SRabin Vincent 	ret = __stmpe_block_write(stmpe, reg, length, values);
24227e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
24327e34995SRabin Vincent 
24427e34995SRabin Vincent 	return ret;
24527e34995SRabin Vincent }
24627e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_block_write);
24727e34995SRabin Vincent 
24827e34995SRabin Vincent /**
2494dcaa6b6SOm Prakash  * stmpe_set_altfunc()- set the alternate function for STMPE pins
25027e34995SRabin Vincent  * @stmpe:	Device to configure
25127e34995SRabin Vincent  * @pins:	Bitmask of pins to affect
25227e34995SRabin Vincent  * @block:	block to enable alternate functions for
25327e34995SRabin Vincent  *
25427e34995SRabin Vincent  * @pins is assumed to have a bit set for each of the bits whose alternate
25527e34995SRabin Vincent  * function is to be changed, numbered according to the GPIOXY numbers.
25627e34995SRabin Vincent  *
25727e34995SRabin Vincent  * If the GPIO module is not enabled, this function automatically enables it in
25827e34995SRabin Vincent  * order to perform the change.
25927e34995SRabin Vincent  */
26027e34995SRabin Vincent int stmpe_set_altfunc(struct stmpe *stmpe, u32 pins, enum stmpe_block block)
26127e34995SRabin Vincent {
26227e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
26327e34995SRabin Vincent 	u8 regaddr = stmpe->regs[STMPE_IDX_GPAFR_U_MSB];
26427e34995SRabin Vincent 	int af_bits = variant->af_bits;
26527e34995SRabin Vincent 	int numregs = DIV_ROUND_UP(stmpe->num_gpios * af_bits, 8);
26627e34995SRabin Vincent 	int mask = (1 << af_bits) - 1;
2677929fa77SLee Jones 	u8 regs[8];
2687f7f4ea1SViresh Kumar 	int af, afperreg, ret;
26927e34995SRabin Vincent 
2707f7f4ea1SViresh Kumar 	if (!variant->get_altfunc)
2717f7f4ea1SViresh Kumar 		return 0;
2727f7f4ea1SViresh Kumar 
2737f7f4ea1SViresh Kumar 	afperreg = 8 / af_bits;
27427e34995SRabin Vincent 	mutex_lock(&stmpe->lock);
27527e34995SRabin Vincent 
27627e34995SRabin Vincent 	ret = __stmpe_enable(stmpe, STMPE_BLOCK_GPIO);
27727e34995SRabin Vincent 	if (ret < 0)
27827e34995SRabin Vincent 		goto out;
27927e34995SRabin Vincent 
28027e34995SRabin Vincent 	ret = __stmpe_block_read(stmpe, regaddr, numregs, regs);
28127e34995SRabin Vincent 	if (ret < 0)
28227e34995SRabin Vincent 		goto out;
28327e34995SRabin Vincent 
28427e34995SRabin Vincent 	af = variant->get_altfunc(stmpe, block);
28527e34995SRabin Vincent 
28627e34995SRabin Vincent 	while (pins) {
28727e34995SRabin Vincent 		int pin = __ffs(pins);
28827e34995SRabin Vincent 		int regoffset = numregs - (pin / afperreg) - 1;
28927e34995SRabin Vincent 		int pos = (pin % afperreg) * (8 / afperreg);
29027e34995SRabin Vincent 
29127e34995SRabin Vincent 		regs[regoffset] &= ~(mask << pos);
29227e34995SRabin Vincent 		regs[regoffset] |= af << pos;
29327e34995SRabin Vincent 
29427e34995SRabin Vincent 		pins &= ~(1 << pin);
29527e34995SRabin Vincent 	}
29627e34995SRabin Vincent 
29727e34995SRabin Vincent 	ret = __stmpe_block_write(stmpe, regaddr, numregs, regs);
29827e34995SRabin Vincent 
29927e34995SRabin Vincent out:
30027e34995SRabin Vincent 	mutex_unlock(&stmpe->lock);
30127e34995SRabin Vincent 	return ret;
30227e34995SRabin Vincent }
30327e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_set_altfunc);
30427e34995SRabin Vincent 
30527e34995SRabin Vincent /*
30627e34995SRabin Vincent  * GPIO (all variants)
30727e34995SRabin Vincent  */
30827e34995SRabin Vincent 
309cb9e880aSRikard Falkeborn static struct resource stmpe_gpio_resources[] = {
31027e34995SRabin Vincent 	/* Start and end filled dynamically */
31127e34995SRabin Vincent 	{
31227e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
31327e34995SRabin Vincent 	},
31427e34995SRabin Vincent };
31527e34995SRabin Vincent 
3166bbb3c4cSGeert Uytterhoeven static const struct mfd_cell stmpe_gpio_cell = {
31727e34995SRabin Vincent 	.name		= "stmpe-gpio",
31886605cfeSVipul Kumar Samar 	.of_compatible	= "st,stmpe-gpio",
31927e34995SRabin Vincent 	.resources	= stmpe_gpio_resources,
32027e34995SRabin Vincent 	.num_resources	= ARRAY_SIZE(stmpe_gpio_resources),
32127e34995SRabin Vincent };
32227e34995SRabin Vincent 
3236bbb3c4cSGeert Uytterhoeven static const struct mfd_cell stmpe_gpio_cell_noirq = {
324e31f9b82SChris Blair 	.name		= "stmpe-gpio",
32586605cfeSVipul Kumar Samar 	.of_compatible	= "st,stmpe-gpio",
326e31f9b82SChris Blair 	/* gpio cell resources consist of an irq only so no resources here */
327e31f9b82SChris Blair };
328e31f9b82SChris Blair 
32927e34995SRabin Vincent /*
33027e34995SRabin Vincent  * Keypad (1601, 2401, 2403)
33127e34995SRabin Vincent  */
33227e34995SRabin Vincent 
333cb9e880aSRikard Falkeborn static struct resource stmpe_keypad_resources[] = {
334cb9e880aSRikard Falkeborn 	/* Start and end filled dynamically */
33527e34995SRabin Vincent 	{
33627e34995SRabin Vincent 		.name	= "KEYPAD",
33727e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
33827e34995SRabin Vincent 	},
33927e34995SRabin Vincent 	{
34027e34995SRabin Vincent 		.name	= "KEYPAD_OVER",
34127e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
34227e34995SRabin Vincent 	},
34327e34995SRabin Vincent };
34427e34995SRabin Vincent 
3456bbb3c4cSGeert Uytterhoeven static const struct mfd_cell stmpe_keypad_cell = {
34627e34995SRabin Vincent 	.name		= "stmpe-keypad",
3476ea32387SDmitry Torokhov 	.of_compatible  = "st,stmpe-keypad",
34827e34995SRabin Vincent 	.resources	= stmpe_keypad_resources,
34927e34995SRabin Vincent 	.num_resources	= ARRAY_SIZE(stmpe_keypad_resources),
35027e34995SRabin Vincent };
35127e34995SRabin Vincent 
35227e34995SRabin Vincent /*
353b273c5e0SLinus Walleij  * PWM (1601, 2401, 2403)
354b273c5e0SLinus Walleij  */
355cb9e880aSRikard Falkeborn static struct resource stmpe_pwm_resources[] = {
356cb9e880aSRikard Falkeborn 	/* Start and end filled dynamically */
357b273c5e0SLinus Walleij 	{
358b273c5e0SLinus Walleij 		.name	= "PWM0",
359b273c5e0SLinus Walleij 		.flags	= IORESOURCE_IRQ,
360b273c5e0SLinus Walleij 	},
361b273c5e0SLinus Walleij 	{
362b273c5e0SLinus Walleij 		.name	= "PWM1",
363b273c5e0SLinus Walleij 		.flags	= IORESOURCE_IRQ,
364b273c5e0SLinus Walleij 	},
365b273c5e0SLinus Walleij 	{
366b273c5e0SLinus Walleij 		.name	= "PWM2",
367b273c5e0SLinus Walleij 		.flags	= IORESOURCE_IRQ,
368b273c5e0SLinus Walleij 	},
369b273c5e0SLinus Walleij };
370b273c5e0SLinus Walleij 
371b273c5e0SLinus Walleij static const struct mfd_cell stmpe_pwm_cell = {
372b273c5e0SLinus Walleij 	.name		= "stmpe-pwm",
373b273c5e0SLinus Walleij 	.of_compatible  = "st,stmpe-pwm",
374b273c5e0SLinus Walleij 	.resources	= stmpe_pwm_resources,
375b273c5e0SLinus Walleij 	.num_resources	= ARRAY_SIZE(stmpe_pwm_resources),
376b273c5e0SLinus Walleij };
377b273c5e0SLinus Walleij 
378b273c5e0SLinus Walleij /*
3797f7f4ea1SViresh Kumar  * STMPE801
3807f7f4ea1SViresh Kumar  */
3817f7f4ea1SViresh Kumar static const u8 stmpe801_regs[] = {
3827f7f4ea1SViresh Kumar 	[STMPE_IDX_CHIP_ID]	= STMPE801_REG_CHIP_ID,
3837f7f4ea1SViresh Kumar 	[STMPE_IDX_ICR_LSB]	= STMPE801_REG_SYS_CTRL,
3847f7f4ea1SViresh Kumar 	[STMPE_IDX_GPMR_LSB]	= STMPE801_REG_GPIO_MP_STA,
3857f7f4ea1SViresh Kumar 	[STMPE_IDX_GPSR_LSB]	= STMPE801_REG_GPIO_SET_PIN,
3867f7f4ea1SViresh Kumar 	[STMPE_IDX_GPCR_LSB]	= STMPE801_REG_GPIO_SET_PIN,
3877f7f4ea1SViresh Kumar 	[STMPE_IDX_GPDR_LSB]	= STMPE801_REG_GPIO_DIR,
3887f7f4ea1SViresh Kumar 	[STMPE_IDX_IEGPIOR_LSB] = STMPE801_REG_GPIO_INT_EN,
3897f7f4ea1SViresh Kumar 	[STMPE_IDX_ISGPIOR_MSB] = STMPE801_REG_GPIO_INT_STA,
3907f7f4ea1SViresh Kumar 
3917f7f4ea1SViresh Kumar };
3927f7f4ea1SViresh Kumar 
3937f7f4ea1SViresh Kumar static struct stmpe_variant_block stmpe801_blocks[] = {
3947f7f4ea1SViresh Kumar 	{
3957f7f4ea1SViresh Kumar 		.cell	= &stmpe_gpio_cell,
3967f7f4ea1SViresh Kumar 		.irq	= 0,
3977f7f4ea1SViresh Kumar 		.block	= STMPE_BLOCK_GPIO,
3987f7f4ea1SViresh Kumar 	},
3997f7f4ea1SViresh Kumar };
4007f7f4ea1SViresh Kumar 
401e31f9b82SChris Blair static struct stmpe_variant_block stmpe801_blocks_noirq[] = {
402e31f9b82SChris Blair 	{
403e31f9b82SChris Blair 		.cell	= &stmpe_gpio_cell_noirq,
404e31f9b82SChris Blair 		.block	= STMPE_BLOCK_GPIO,
405e31f9b82SChris Blair 	},
406e31f9b82SChris Blair };
407e31f9b82SChris Blair 
4087f7f4ea1SViresh Kumar static int stmpe801_enable(struct stmpe *stmpe, unsigned int blocks,
4097f7f4ea1SViresh Kumar 			   bool enable)
4107f7f4ea1SViresh Kumar {
4117f7f4ea1SViresh Kumar 	if (blocks & STMPE_BLOCK_GPIO)
4127f7f4ea1SViresh Kumar 		return 0;
4137f7f4ea1SViresh Kumar 	else
4147f7f4ea1SViresh Kumar 		return -EINVAL;
4157f7f4ea1SViresh Kumar }
4167f7f4ea1SViresh Kumar 
4177f7f4ea1SViresh Kumar static struct stmpe_variant_info stmpe801 = {
4187f7f4ea1SViresh Kumar 	.name		= "stmpe801",
4197f7f4ea1SViresh Kumar 	.id_val		= STMPE801_ID,
4207f7f4ea1SViresh Kumar 	.id_mask	= 0xffff,
4217f7f4ea1SViresh Kumar 	.num_gpios	= 8,
4227f7f4ea1SViresh Kumar 	.regs		= stmpe801_regs,
4237f7f4ea1SViresh Kumar 	.blocks		= stmpe801_blocks,
4247f7f4ea1SViresh Kumar 	.num_blocks	= ARRAY_SIZE(stmpe801_blocks),
4257f7f4ea1SViresh Kumar 	.num_irqs	= STMPE801_NR_INTERNAL_IRQS,
4267f7f4ea1SViresh Kumar 	.enable		= stmpe801_enable,
4277f7f4ea1SViresh Kumar };
4287f7f4ea1SViresh Kumar 
429e31f9b82SChris Blair static struct stmpe_variant_info stmpe801_noirq = {
430e31f9b82SChris Blair 	.name		= "stmpe801",
431e31f9b82SChris Blair 	.id_val		= STMPE801_ID,
432e31f9b82SChris Blair 	.id_mask	= 0xffff,
433e31f9b82SChris Blair 	.num_gpios	= 8,
434e31f9b82SChris Blair 	.regs		= stmpe801_regs,
435e31f9b82SChris Blair 	.blocks		= stmpe801_blocks_noirq,
436e31f9b82SChris Blair 	.num_blocks	= ARRAY_SIZE(stmpe801_blocks_noirq),
437e31f9b82SChris Blair 	.enable		= stmpe801_enable,
438e31f9b82SChris Blair };
439e31f9b82SChris Blair 
4407f7f4ea1SViresh Kumar /*
4411cda2394SViresh Kumar  * Touchscreen (STMPE811 or STMPE610)
44227e34995SRabin Vincent  */
44327e34995SRabin Vincent 
444cb9e880aSRikard Falkeborn static struct resource stmpe_ts_resources[] = {
445cb9e880aSRikard Falkeborn 	/* Start and end filled dynamically */
44627e34995SRabin Vincent 	{
44727e34995SRabin Vincent 		.name	= "TOUCH_DET",
44827e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
44927e34995SRabin Vincent 	},
45027e34995SRabin Vincent 	{
45127e34995SRabin Vincent 		.name	= "FIFO_TH",
45227e34995SRabin Vincent 		.flags	= IORESOURCE_IRQ,
45327e34995SRabin Vincent 	},
45427e34995SRabin Vincent };
45527e34995SRabin Vincent 
4566bbb3c4cSGeert Uytterhoeven static const struct mfd_cell stmpe_ts_cell = {
45727e34995SRabin Vincent 	.name		= "stmpe-ts",
458037db524SVipul Kumar Samar 	.of_compatible	= "st,stmpe-ts",
45927e34995SRabin Vincent 	.resources	= stmpe_ts_resources,
46027e34995SRabin Vincent 	.num_resources	= ARRAY_SIZE(stmpe_ts_resources),
46127e34995SRabin Vincent };
46227e34995SRabin Vincent 
46327e34995SRabin Vincent /*
4646377cfa3SStefan Agner  * ADC (STMPE811)
4656377cfa3SStefan Agner  */
4666377cfa3SStefan Agner 
467cb9e880aSRikard Falkeborn static struct resource stmpe_adc_resources[] = {
468cb9e880aSRikard Falkeborn 	/* Start and end filled dynamically */
4696377cfa3SStefan Agner 	{
4706377cfa3SStefan Agner 		.name	= "STMPE_TEMP_SENS",
4716377cfa3SStefan Agner 		.flags	= IORESOURCE_IRQ,
4726377cfa3SStefan Agner 	},
4736377cfa3SStefan Agner 	{
4746377cfa3SStefan Agner 		.name	= "STMPE_ADC",
4756377cfa3SStefan Agner 		.flags	= IORESOURCE_IRQ,
4766377cfa3SStefan Agner 	},
4776377cfa3SStefan Agner };
4786377cfa3SStefan Agner 
4796377cfa3SStefan Agner static const struct mfd_cell stmpe_adc_cell = {
4806377cfa3SStefan Agner 	.name		= "stmpe-adc",
4816377cfa3SStefan Agner 	.of_compatible	= "st,stmpe-adc",
4826377cfa3SStefan Agner 	.resources	= stmpe_adc_resources,
4836377cfa3SStefan Agner 	.num_resources	= ARRAY_SIZE(stmpe_adc_resources),
4846377cfa3SStefan Agner };
4856377cfa3SStefan Agner 
4866377cfa3SStefan Agner /*
4871cda2394SViresh Kumar  * STMPE811 or STMPE610
48827e34995SRabin Vincent  */
48927e34995SRabin Vincent 
49027e34995SRabin Vincent static const u8 stmpe811_regs[] = {
49127e34995SRabin Vincent 	[STMPE_IDX_CHIP_ID]	= STMPE811_REG_CHIP_ID,
4920f4be8cfSPatrice Chotard 	[STMPE_IDX_SYS_CTRL]	= STMPE811_REG_SYS_CTRL,
4930f4be8cfSPatrice Chotard 	[STMPE_IDX_SYS_CTRL2]	= STMPE811_REG_SYS_CTRL2,
49427e34995SRabin Vincent 	[STMPE_IDX_ICR_LSB]	= STMPE811_REG_INT_CTRL,
49527e34995SRabin Vincent 	[STMPE_IDX_IER_LSB]	= STMPE811_REG_INT_EN,
49627e34995SRabin Vincent 	[STMPE_IDX_ISR_MSB]	= STMPE811_REG_INT_STA,
49727e34995SRabin Vincent 	[STMPE_IDX_GPMR_LSB]	= STMPE811_REG_GPIO_MP_STA,
49827e34995SRabin Vincent 	[STMPE_IDX_GPSR_LSB]	= STMPE811_REG_GPIO_SET_PIN,
49927e34995SRabin Vincent 	[STMPE_IDX_GPCR_LSB]	= STMPE811_REG_GPIO_CLR_PIN,
50027e34995SRabin Vincent 	[STMPE_IDX_GPDR_LSB]	= STMPE811_REG_GPIO_DIR,
50127e34995SRabin Vincent 	[STMPE_IDX_GPRER_LSB]	= STMPE811_REG_GPIO_RE,
50227e34995SRabin Vincent 	[STMPE_IDX_GPFER_LSB]	= STMPE811_REG_GPIO_FE,
50327e34995SRabin Vincent 	[STMPE_IDX_GPAFR_U_MSB]	= STMPE811_REG_GPIO_AF,
50427e34995SRabin Vincent 	[STMPE_IDX_IEGPIOR_LSB]	= STMPE811_REG_GPIO_INT_EN,
50527e34995SRabin Vincent 	[STMPE_IDX_ISGPIOR_MSB]	= STMPE811_REG_GPIO_INT_STA,
506897ac667SPatrice Chotard 	[STMPE_IDX_GPEDR_LSB]	= STMPE811_REG_GPIO_ED,
50727e34995SRabin Vincent };
50827e34995SRabin Vincent 
50927e34995SRabin Vincent static struct stmpe_variant_block stmpe811_blocks[] = {
51027e34995SRabin Vincent 	{
51127e34995SRabin Vincent 		.cell	= &stmpe_gpio_cell,
51227e34995SRabin Vincent 		.irq	= STMPE811_IRQ_GPIOC,
51327e34995SRabin Vincent 		.block	= STMPE_BLOCK_GPIO,
51427e34995SRabin Vincent 	},
51527e34995SRabin Vincent 	{
51627e34995SRabin Vincent 		.cell	= &stmpe_ts_cell,
51727e34995SRabin Vincent 		.irq	= STMPE811_IRQ_TOUCH_DET,
51827e34995SRabin Vincent 		.block	= STMPE_BLOCK_TOUCHSCREEN,
51927e34995SRabin Vincent 	},
5206377cfa3SStefan Agner 	{
5216377cfa3SStefan Agner 		.cell	= &stmpe_adc_cell,
5226377cfa3SStefan Agner 		.irq	= STMPE811_IRQ_TEMP_SENS,
5236377cfa3SStefan Agner 		.block	= STMPE_BLOCK_ADC,
5246377cfa3SStefan Agner 	},
52527e34995SRabin Vincent };
52627e34995SRabin Vincent 
52727e34995SRabin Vincent static int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks,
52827e34995SRabin Vincent 			   bool enable)
52927e34995SRabin Vincent {
53027e34995SRabin Vincent 	unsigned int mask = 0;
53127e34995SRabin Vincent 
53227e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_GPIO)
53327e34995SRabin Vincent 		mask |= STMPE811_SYS_CTRL2_GPIO_OFF;
53427e34995SRabin Vincent 
53527e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_ADC)
53627e34995SRabin Vincent 		mask |= STMPE811_SYS_CTRL2_ADC_OFF;
53727e34995SRabin Vincent 
53827e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_TOUCHSCREEN)
53927e34995SRabin Vincent 		mask |= STMPE811_SYS_CTRL2_TSC_OFF;
54027e34995SRabin Vincent 
5410f4be8cfSPatrice Chotard 	return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2], mask,
54227e34995SRabin Vincent 				enable ? 0 : mask);
54327e34995SRabin Vincent }
54427e34995SRabin Vincent 
5456377cfa3SStefan Agner int stmpe811_adc_common_init(struct stmpe *stmpe)
5466377cfa3SStefan Agner {
5476377cfa3SStefan Agner 	int ret;
5486377cfa3SStefan Agner 	u8 adc_ctrl1, adc_ctrl1_mask;
5496377cfa3SStefan Agner 
5506377cfa3SStefan Agner 	adc_ctrl1 = STMPE_SAMPLE_TIME(stmpe->sample_time) |
5516377cfa3SStefan Agner 		    STMPE_MOD_12B(stmpe->mod_12b) |
5526377cfa3SStefan Agner 		    STMPE_REF_SEL(stmpe->ref_sel);
5536377cfa3SStefan Agner 	adc_ctrl1_mask = STMPE_SAMPLE_TIME(0xff) | STMPE_MOD_12B(0xff) |
5546377cfa3SStefan Agner 			 STMPE_REF_SEL(0xff);
5556377cfa3SStefan Agner 
5566377cfa3SStefan Agner 	ret = stmpe_set_bits(stmpe, STMPE811_REG_ADC_CTRL1,
5576377cfa3SStefan Agner 			adc_ctrl1_mask, adc_ctrl1);
5586377cfa3SStefan Agner 	if (ret) {
5596377cfa3SStefan Agner 		dev_err(stmpe->dev, "Could not setup ADC\n");
5606377cfa3SStefan Agner 		return ret;
5616377cfa3SStefan Agner 	}
5626377cfa3SStefan Agner 
5636377cfa3SStefan Agner 	ret = stmpe_set_bits(stmpe, STMPE811_REG_ADC_CTRL2,
5646377cfa3SStefan Agner 			STMPE_ADC_FREQ(0xff), STMPE_ADC_FREQ(stmpe->adc_freq));
5656377cfa3SStefan Agner 	if (ret) {
5666377cfa3SStefan Agner 		dev_err(stmpe->dev, "Could not setup ADC\n");
5676377cfa3SStefan Agner 		return ret;
5686377cfa3SStefan Agner 	}
5696377cfa3SStefan Agner 
5706377cfa3SStefan Agner 	return 0;
5716377cfa3SStefan Agner }
5726377cfa3SStefan Agner EXPORT_SYMBOL_GPL(stmpe811_adc_common_init);
5736377cfa3SStefan Agner 
57427e34995SRabin Vincent static int stmpe811_get_altfunc(struct stmpe *stmpe, enum stmpe_block block)
57527e34995SRabin Vincent {
57627e34995SRabin Vincent 	/* 0 for touchscreen, 1 for GPIO */
57727e34995SRabin Vincent 	return block != STMPE_BLOCK_TOUCHSCREEN;
57827e34995SRabin Vincent }
57927e34995SRabin Vincent 
58027e34995SRabin Vincent static struct stmpe_variant_info stmpe811 = {
58127e34995SRabin Vincent 	.name		= "stmpe811",
58227e34995SRabin Vincent 	.id_val		= 0x0811,
58327e34995SRabin Vincent 	.id_mask	= 0xffff,
58427e34995SRabin Vincent 	.num_gpios	= 8,
58527e34995SRabin Vincent 	.af_bits	= 1,
58627e34995SRabin Vincent 	.regs		= stmpe811_regs,
58727e34995SRabin Vincent 	.blocks		= stmpe811_blocks,
58827e34995SRabin Vincent 	.num_blocks	= ARRAY_SIZE(stmpe811_blocks),
58927e34995SRabin Vincent 	.num_irqs	= STMPE811_NR_INTERNAL_IRQS,
59027e34995SRabin Vincent 	.enable		= stmpe811_enable,
59127e34995SRabin Vincent 	.get_altfunc	= stmpe811_get_altfunc,
59227e34995SRabin Vincent };
59327e34995SRabin Vincent 
5941cda2394SViresh Kumar /* Similar to 811, except number of gpios */
5951cda2394SViresh Kumar static struct stmpe_variant_info stmpe610 = {
5961cda2394SViresh Kumar 	.name		= "stmpe610",
5971cda2394SViresh Kumar 	.id_val		= 0x0811,
5981cda2394SViresh Kumar 	.id_mask	= 0xffff,
5991cda2394SViresh Kumar 	.num_gpios	= 6,
6001cda2394SViresh Kumar 	.af_bits	= 1,
6011cda2394SViresh Kumar 	.regs		= stmpe811_regs,
6021cda2394SViresh Kumar 	.blocks		= stmpe811_blocks,
6031cda2394SViresh Kumar 	.num_blocks	= ARRAY_SIZE(stmpe811_blocks),
6041cda2394SViresh Kumar 	.num_irqs	= STMPE811_NR_INTERNAL_IRQS,
6051cda2394SViresh Kumar 	.enable		= stmpe811_enable,
6061cda2394SViresh Kumar 	.get_altfunc	= stmpe811_get_altfunc,
6071cda2394SViresh Kumar };
6081cda2394SViresh Kumar 
60927e34995SRabin Vincent /*
6106bb9f0d9SPatrice Chotard  * STMPE1600
6116bb9f0d9SPatrice Chotard  * Compared to all others STMPE variant, LSB and MSB regs are located in this
6126bb9f0d9SPatrice Chotard  * order :	LSB   addr
6136bb9f0d9SPatrice Chotard  *		MSB   addr + 1
6146bb9f0d9SPatrice Chotard  * As there is only 2 * 8bits registers for GPMR/GPSR/IEGPIOPR, CSB index is MSB registers
6156bb9f0d9SPatrice Chotard  */
6166bb9f0d9SPatrice Chotard 
6176bb9f0d9SPatrice Chotard static const u8 stmpe1600_regs[] = {
6186bb9f0d9SPatrice Chotard 	[STMPE_IDX_CHIP_ID]	= STMPE1600_REG_CHIP_ID,
6196bb9f0d9SPatrice Chotard 	[STMPE_IDX_SYS_CTRL]	= STMPE1600_REG_SYS_CTRL,
6206bb9f0d9SPatrice Chotard 	[STMPE_IDX_ICR_LSB]	= STMPE1600_REG_SYS_CTRL,
6216bb9f0d9SPatrice Chotard 	[STMPE_IDX_GPMR_LSB]	= STMPE1600_REG_GPMR_LSB,
6226bb9f0d9SPatrice Chotard 	[STMPE_IDX_GPMR_CSB]	= STMPE1600_REG_GPMR_MSB,
6236bb9f0d9SPatrice Chotard 	[STMPE_IDX_GPSR_LSB]	= STMPE1600_REG_GPSR_LSB,
6246bb9f0d9SPatrice Chotard 	[STMPE_IDX_GPSR_CSB]	= STMPE1600_REG_GPSR_MSB,
625b97eef5dSHugues Fruchet 	[STMPE_IDX_GPCR_LSB]	= STMPE1600_REG_GPSR_LSB,
626b97eef5dSHugues Fruchet 	[STMPE_IDX_GPCR_CSB]	= STMPE1600_REG_GPSR_MSB,
6276bb9f0d9SPatrice Chotard 	[STMPE_IDX_GPDR_LSB]	= STMPE1600_REG_GPDR_LSB,
6286bb9f0d9SPatrice Chotard 	[STMPE_IDX_GPDR_CSB]	= STMPE1600_REG_GPDR_MSB,
6296bb9f0d9SPatrice Chotard 	[STMPE_IDX_IEGPIOR_LSB]	= STMPE1600_REG_IEGPIOR_LSB,
6306bb9f0d9SPatrice Chotard 	[STMPE_IDX_IEGPIOR_CSB]	= STMPE1600_REG_IEGPIOR_MSB,
6316bb9f0d9SPatrice Chotard 	[STMPE_IDX_ISGPIOR_LSB]	= STMPE1600_REG_ISGPIOR_LSB,
6326bb9f0d9SPatrice Chotard };
6336bb9f0d9SPatrice Chotard 
6346bb9f0d9SPatrice Chotard static struct stmpe_variant_block stmpe1600_blocks[] = {
6356bb9f0d9SPatrice Chotard 	{
6366bb9f0d9SPatrice Chotard 		.cell	= &stmpe_gpio_cell,
6376bb9f0d9SPatrice Chotard 		.irq	= 0,
6386bb9f0d9SPatrice Chotard 		.block	= STMPE_BLOCK_GPIO,
6396bb9f0d9SPatrice Chotard 	},
6406bb9f0d9SPatrice Chotard };
6416bb9f0d9SPatrice Chotard 
6426bb9f0d9SPatrice Chotard static int stmpe1600_enable(struct stmpe *stmpe, unsigned int blocks,
6436bb9f0d9SPatrice Chotard 			   bool enable)
6446bb9f0d9SPatrice Chotard {
6456bb9f0d9SPatrice Chotard 	if (blocks & STMPE_BLOCK_GPIO)
6466bb9f0d9SPatrice Chotard 		return 0;
6476bb9f0d9SPatrice Chotard 	else
6486bb9f0d9SPatrice Chotard 		return -EINVAL;
6496bb9f0d9SPatrice Chotard }
6506bb9f0d9SPatrice Chotard 
6516bb9f0d9SPatrice Chotard static struct stmpe_variant_info stmpe1600 = {
6526bb9f0d9SPatrice Chotard 	.name		= "stmpe1600",
6536bb9f0d9SPatrice Chotard 	.id_val		= STMPE1600_ID,
6546bb9f0d9SPatrice Chotard 	.id_mask	= 0xffff,
6556bb9f0d9SPatrice Chotard 	.num_gpios	= 16,
6566bb9f0d9SPatrice Chotard 	.af_bits	= 0,
6576bb9f0d9SPatrice Chotard 	.regs		= stmpe1600_regs,
6586bb9f0d9SPatrice Chotard 	.blocks		= stmpe1600_blocks,
6596bb9f0d9SPatrice Chotard 	.num_blocks	= ARRAY_SIZE(stmpe1600_blocks),
6606bb9f0d9SPatrice Chotard 	.num_irqs	= STMPE1600_NR_INTERNAL_IRQS,
6616bb9f0d9SPatrice Chotard 	.enable		= stmpe1600_enable,
6626bb9f0d9SPatrice Chotard };
6636bb9f0d9SPatrice Chotard 
6646bb9f0d9SPatrice Chotard /*
66527e34995SRabin Vincent  * STMPE1601
66627e34995SRabin Vincent  */
66727e34995SRabin Vincent 
66827e34995SRabin Vincent static const u8 stmpe1601_regs[] = {
66927e34995SRabin Vincent 	[STMPE_IDX_CHIP_ID]	= STMPE1601_REG_CHIP_ID,
6700f4be8cfSPatrice Chotard 	[STMPE_IDX_SYS_CTRL]	= STMPE1601_REG_SYS_CTRL,
6710f4be8cfSPatrice Chotard 	[STMPE_IDX_SYS_CTRL2]	= STMPE1601_REG_SYS_CTRL2,
67227e34995SRabin Vincent 	[STMPE_IDX_ICR_LSB]	= STMPE1601_REG_ICR_LSB,
673897ac667SPatrice Chotard 	[STMPE_IDX_IER_MSB]	= STMPE1601_REG_IER_MSB,
67427e34995SRabin Vincent 	[STMPE_IDX_IER_LSB]	= STMPE1601_REG_IER_LSB,
67527e34995SRabin Vincent 	[STMPE_IDX_ISR_MSB]	= STMPE1601_REG_ISR_MSB,
67627e34995SRabin Vincent 	[STMPE_IDX_GPMR_LSB]	= STMPE1601_REG_GPIO_MP_LSB,
677897ac667SPatrice Chotard 	[STMPE_IDX_GPMR_CSB]	= STMPE1601_REG_GPIO_MP_MSB,
67827e34995SRabin Vincent 	[STMPE_IDX_GPSR_LSB]	= STMPE1601_REG_GPIO_SET_LSB,
679897ac667SPatrice Chotard 	[STMPE_IDX_GPSR_CSB]	= STMPE1601_REG_GPIO_SET_MSB,
68027e34995SRabin Vincent 	[STMPE_IDX_GPCR_LSB]	= STMPE1601_REG_GPIO_CLR_LSB,
681897ac667SPatrice Chotard 	[STMPE_IDX_GPCR_CSB]	= STMPE1601_REG_GPIO_CLR_MSB,
68227e34995SRabin Vincent 	[STMPE_IDX_GPDR_LSB]	= STMPE1601_REG_GPIO_SET_DIR_LSB,
683897ac667SPatrice Chotard 	[STMPE_IDX_GPDR_CSB]	= STMPE1601_REG_GPIO_SET_DIR_MSB,
684897ac667SPatrice Chotard 	[STMPE_IDX_GPEDR_LSB]	= STMPE1601_REG_GPIO_ED_LSB,
685897ac667SPatrice Chotard 	[STMPE_IDX_GPEDR_CSB]	= STMPE1601_REG_GPIO_ED_MSB,
68627e34995SRabin Vincent 	[STMPE_IDX_GPRER_LSB]	= STMPE1601_REG_GPIO_RE_LSB,
687897ac667SPatrice Chotard 	[STMPE_IDX_GPRER_CSB]	= STMPE1601_REG_GPIO_RE_MSB,
68827e34995SRabin Vincent 	[STMPE_IDX_GPFER_LSB]	= STMPE1601_REG_GPIO_FE_LSB,
689897ac667SPatrice Chotard 	[STMPE_IDX_GPFER_CSB]	= STMPE1601_REG_GPIO_FE_MSB,
69080e1dd82SLinus Walleij 	[STMPE_IDX_GPPUR_LSB]	= STMPE1601_REG_GPIO_PU_LSB,
69127e34995SRabin Vincent 	[STMPE_IDX_GPAFR_U_MSB]	= STMPE1601_REG_GPIO_AF_U_MSB,
69227e34995SRabin Vincent 	[STMPE_IDX_IEGPIOR_LSB]	= STMPE1601_REG_INT_EN_GPIO_MASK_LSB,
693897ac667SPatrice Chotard 	[STMPE_IDX_IEGPIOR_CSB]	= STMPE1601_REG_INT_EN_GPIO_MASK_MSB,
69427e34995SRabin Vincent 	[STMPE_IDX_ISGPIOR_MSB]	= STMPE1601_REG_INT_STA_GPIO_MSB,
69527e34995SRabin Vincent };
69627e34995SRabin Vincent 
69727e34995SRabin Vincent static struct stmpe_variant_block stmpe1601_blocks[] = {
69827e34995SRabin Vincent 	{
69927e34995SRabin Vincent 		.cell	= &stmpe_gpio_cell,
7005204e51dSLee Jones 		.irq	= STMPE1601_IRQ_GPIOC,
70127e34995SRabin Vincent 		.block	= STMPE_BLOCK_GPIO,
70227e34995SRabin Vincent 	},
70327e34995SRabin Vincent 	{
70427e34995SRabin Vincent 		.cell	= &stmpe_keypad_cell,
7055204e51dSLee Jones 		.irq	= STMPE1601_IRQ_KEYPAD,
70627e34995SRabin Vincent 		.block	= STMPE_BLOCK_KEYPAD,
70727e34995SRabin Vincent 	},
708b273c5e0SLinus Walleij 	{
709b273c5e0SLinus Walleij 		.cell	= &stmpe_pwm_cell,
710b273c5e0SLinus Walleij 		.irq	= STMPE1601_IRQ_PWM0,
711b273c5e0SLinus Walleij 		.block	= STMPE_BLOCK_PWM,
712b273c5e0SLinus Walleij 	},
71327e34995SRabin Vincent };
71427e34995SRabin Vincent 
7155981f4e6SSundar R Iyer /* supported autosleep timeout delay (in msecs) */
7165981f4e6SSundar R Iyer static const int stmpe_autosleep_delay[] = {
7175981f4e6SSundar R Iyer 	4, 16, 32, 64, 128, 256, 512, 1024,
7185981f4e6SSundar R Iyer };
7195981f4e6SSundar R Iyer 
7205981f4e6SSundar R Iyer static int stmpe_round_timeout(int timeout)
7215981f4e6SSundar R Iyer {
7225981f4e6SSundar R Iyer 	int i;
7235981f4e6SSundar R Iyer 
7245981f4e6SSundar R Iyer 	for (i = 0; i < ARRAY_SIZE(stmpe_autosleep_delay); i++) {
7255981f4e6SSundar R Iyer 		if (stmpe_autosleep_delay[i] >= timeout)
7265981f4e6SSundar R Iyer 			return i;
7275981f4e6SSundar R Iyer 	}
7285981f4e6SSundar R Iyer 
7295981f4e6SSundar R Iyer 	/*
7305981f4e6SSundar R Iyer 	 * requests for delays longer than supported should not return the
7315981f4e6SSundar R Iyer 	 * longest supported delay
7325981f4e6SSundar R Iyer 	 */
7335981f4e6SSundar R Iyer 	return -EINVAL;
7345981f4e6SSundar R Iyer }
7355981f4e6SSundar R Iyer 
7365981f4e6SSundar R Iyer static int stmpe_autosleep(struct stmpe *stmpe, int autosleep_timeout)
7375981f4e6SSundar R Iyer {
7385981f4e6SSundar R Iyer 	int ret;
7395981f4e6SSundar R Iyer 
7405981f4e6SSundar R Iyer 	if (!stmpe->variant->enable_autosleep)
7415981f4e6SSundar R Iyer 		return -ENOSYS;
7425981f4e6SSundar R Iyer 
7435981f4e6SSundar R Iyer 	mutex_lock(&stmpe->lock);
7445981f4e6SSundar R Iyer 	ret = stmpe->variant->enable_autosleep(stmpe, autosleep_timeout);
7455981f4e6SSundar R Iyer 	mutex_unlock(&stmpe->lock);
7465981f4e6SSundar R Iyer 
7475981f4e6SSundar R Iyer 	return ret;
7485981f4e6SSundar R Iyer }
7495981f4e6SSundar R Iyer 
7505981f4e6SSundar R Iyer /*
7515981f4e6SSundar R Iyer  * Both stmpe 1601/2403 support same layout for autosleep
7525981f4e6SSundar R Iyer  */
7535981f4e6SSundar R Iyer static int stmpe1601_autosleep(struct stmpe *stmpe,
7545981f4e6SSundar R Iyer 		int autosleep_timeout)
7555981f4e6SSundar R Iyer {
7565981f4e6SSundar R Iyer 	int ret, timeout;
7575981f4e6SSundar R Iyer 
7585981f4e6SSundar R Iyer 	/* choose the best available timeout */
7595981f4e6SSundar R Iyer 	timeout = stmpe_round_timeout(autosleep_timeout);
7605981f4e6SSundar R Iyer 	if (timeout < 0) {
7615981f4e6SSundar R Iyer 		dev_err(stmpe->dev, "invalid timeout\n");
7625981f4e6SSundar R Iyer 		return timeout;
7635981f4e6SSundar R Iyer 	}
7645981f4e6SSundar R Iyer 
7650f4be8cfSPatrice Chotard 	ret = __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2],
7665981f4e6SSundar R Iyer 			STMPE1601_AUTOSLEEP_TIMEOUT_MASK,
7675981f4e6SSundar R Iyer 			timeout);
7685981f4e6SSundar R Iyer 	if (ret < 0)
7695981f4e6SSundar R Iyer 		return ret;
7705981f4e6SSundar R Iyer 
7710f4be8cfSPatrice Chotard 	return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2],
7725981f4e6SSundar R Iyer 			STPME1601_AUTOSLEEP_ENABLE,
7735981f4e6SSundar R Iyer 			STPME1601_AUTOSLEEP_ENABLE);
7745981f4e6SSundar R Iyer }
7755981f4e6SSundar R Iyer 
77627e34995SRabin Vincent static int stmpe1601_enable(struct stmpe *stmpe, unsigned int blocks,
77727e34995SRabin Vincent 			    bool enable)
77827e34995SRabin Vincent {
77927e34995SRabin Vincent 	unsigned int mask = 0;
78027e34995SRabin Vincent 
78127e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_GPIO)
78227e34995SRabin Vincent 		mask |= STMPE1601_SYS_CTRL_ENABLE_GPIO;
783b69d2ad6SLinus Walleij 	else
784b69d2ad6SLinus Walleij 		mask &= ~STMPE1601_SYS_CTRL_ENABLE_GPIO;
78527e34995SRabin Vincent 
78627e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_KEYPAD)
78727e34995SRabin Vincent 		mask |= STMPE1601_SYS_CTRL_ENABLE_KPC;
788b69d2ad6SLinus Walleij 	else
789b69d2ad6SLinus Walleij 		mask &= ~STMPE1601_SYS_CTRL_ENABLE_KPC;
790b69d2ad6SLinus Walleij 
791b69d2ad6SLinus Walleij 	if (blocks & STMPE_BLOCK_PWM)
792b69d2ad6SLinus Walleij 		mask |= STMPE1601_SYS_CTRL_ENABLE_SPWM;
793b69d2ad6SLinus Walleij 	else
794b69d2ad6SLinus Walleij 		mask &= ~STMPE1601_SYS_CTRL_ENABLE_SPWM;
79527e34995SRabin Vincent 
7960f4be8cfSPatrice Chotard 	return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], mask,
79727e34995SRabin Vincent 				enable ? mask : 0);
79827e34995SRabin Vincent }
79927e34995SRabin Vincent 
80027e34995SRabin Vincent static int stmpe1601_get_altfunc(struct stmpe *stmpe, enum stmpe_block block)
80127e34995SRabin Vincent {
80227e34995SRabin Vincent 	switch (block) {
80327e34995SRabin Vincent 	case STMPE_BLOCK_PWM:
80427e34995SRabin Vincent 		return 2;
80527e34995SRabin Vincent 
80627e34995SRabin Vincent 	case STMPE_BLOCK_KEYPAD:
80727e34995SRabin Vincent 		return 1;
80827e34995SRabin Vincent 
80927e34995SRabin Vincent 	case STMPE_BLOCK_GPIO:
81027e34995SRabin Vincent 	default:
81127e34995SRabin Vincent 		return 0;
81227e34995SRabin Vincent 	}
81327e34995SRabin Vincent }
81427e34995SRabin Vincent 
81527e34995SRabin Vincent static struct stmpe_variant_info stmpe1601 = {
81627e34995SRabin Vincent 	.name		= "stmpe1601",
81727e34995SRabin Vincent 	.id_val		= 0x0210,
81827e34995SRabin Vincent 	.id_mask	= 0xfff0,	/* at least 0x0210 and 0x0212 */
81927e34995SRabin Vincent 	.num_gpios	= 16,
82027e34995SRabin Vincent 	.af_bits	= 2,
82127e34995SRabin Vincent 	.regs		= stmpe1601_regs,
82227e34995SRabin Vincent 	.blocks		= stmpe1601_blocks,
82327e34995SRabin Vincent 	.num_blocks	= ARRAY_SIZE(stmpe1601_blocks),
82427e34995SRabin Vincent 	.num_irqs	= STMPE1601_NR_INTERNAL_IRQS,
82527e34995SRabin Vincent 	.enable		= stmpe1601_enable,
82627e34995SRabin Vincent 	.get_altfunc	= stmpe1601_get_altfunc,
8275981f4e6SSundar R Iyer 	.enable_autosleep	= stmpe1601_autosleep,
82827e34995SRabin Vincent };
82927e34995SRabin Vincent 
83027e34995SRabin Vincent /*
831230f13a5SJean-Nicolas Graux  * STMPE1801
832230f13a5SJean-Nicolas Graux  */
833230f13a5SJean-Nicolas Graux static const u8 stmpe1801_regs[] = {
834230f13a5SJean-Nicolas Graux 	[STMPE_IDX_CHIP_ID]	= STMPE1801_REG_CHIP_ID,
8350f4be8cfSPatrice Chotard 	[STMPE_IDX_SYS_CTRL]	= STMPE1801_REG_SYS_CTRL,
836230f13a5SJean-Nicolas Graux 	[STMPE_IDX_ICR_LSB]	= STMPE1801_REG_INT_CTRL_LOW,
837230f13a5SJean-Nicolas Graux 	[STMPE_IDX_IER_LSB]	= STMPE1801_REG_INT_EN_MASK_LOW,
838230f13a5SJean-Nicolas Graux 	[STMPE_IDX_ISR_LSB]	= STMPE1801_REG_INT_STA_LOW,
839230f13a5SJean-Nicolas Graux 	[STMPE_IDX_GPMR_LSB]	= STMPE1801_REG_GPIO_MP_LOW,
840897ac667SPatrice Chotard 	[STMPE_IDX_GPMR_CSB]	= STMPE1801_REG_GPIO_MP_MID,
841897ac667SPatrice Chotard 	[STMPE_IDX_GPMR_MSB]	= STMPE1801_REG_GPIO_MP_HIGH,
842230f13a5SJean-Nicolas Graux 	[STMPE_IDX_GPSR_LSB]	= STMPE1801_REG_GPIO_SET_LOW,
843897ac667SPatrice Chotard 	[STMPE_IDX_GPSR_CSB]	= STMPE1801_REG_GPIO_SET_MID,
844897ac667SPatrice Chotard 	[STMPE_IDX_GPSR_MSB]	= STMPE1801_REG_GPIO_SET_HIGH,
845230f13a5SJean-Nicolas Graux 	[STMPE_IDX_GPCR_LSB]	= STMPE1801_REG_GPIO_CLR_LOW,
846897ac667SPatrice Chotard 	[STMPE_IDX_GPCR_CSB]	= STMPE1801_REG_GPIO_CLR_MID,
847897ac667SPatrice Chotard 	[STMPE_IDX_GPCR_MSB]	= STMPE1801_REG_GPIO_CLR_HIGH,
848230f13a5SJean-Nicolas Graux 	[STMPE_IDX_GPDR_LSB]	= STMPE1801_REG_GPIO_SET_DIR_LOW,
849897ac667SPatrice Chotard 	[STMPE_IDX_GPDR_CSB]	= STMPE1801_REG_GPIO_SET_DIR_MID,
850897ac667SPatrice Chotard 	[STMPE_IDX_GPDR_MSB]	= STMPE1801_REG_GPIO_SET_DIR_HIGH,
851230f13a5SJean-Nicolas Graux 	[STMPE_IDX_GPRER_LSB]	= STMPE1801_REG_GPIO_RE_LOW,
852897ac667SPatrice Chotard 	[STMPE_IDX_GPRER_CSB]	= STMPE1801_REG_GPIO_RE_MID,
853897ac667SPatrice Chotard 	[STMPE_IDX_GPRER_MSB]	= STMPE1801_REG_GPIO_RE_HIGH,
854230f13a5SJean-Nicolas Graux 	[STMPE_IDX_GPFER_LSB]	= STMPE1801_REG_GPIO_FE_LOW,
855897ac667SPatrice Chotard 	[STMPE_IDX_GPFER_CSB]	= STMPE1801_REG_GPIO_FE_MID,
856897ac667SPatrice Chotard 	[STMPE_IDX_GPFER_MSB]	= STMPE1801_REG_GPIO_FE_HIGH,
85780e1dd82SLinus Walleij 	[STMPE_IDX_GPPUR_LSB]	= STMPE1801_REG_GPIO_PULL_UP_LOW,
858230f13a5SJean-Nicolas Graux 	[STMPE_IDX_IEGPIOR_LSB]	= STMPE1801_REG_INT_EN_GPIO_MASK_LOW,
859897ac667SPatrice Chotard 	[STMPE_IDX_IEGPIOR_CSB]	= STMPE1801_REG_INT_EN_GPIO_MASK_MID,
860897ac667SPatrice Chotard 	[STMPE_IDX_IEGPIOR_MSB]	= STMPE1801_REG_INT_EN_GPIO_MASK_HIGH,
861897ac667SPatrice Chotard 	[STMPE_IDX_ISGPIOR_MSB]	= STMPE1801_REG_INT_STA_GPIO_HIGH,
862230f13a5SJean-Nicolas Graux };
863230f13a5SJean-Nicolas Graux 
864230f13a5SJean-Nicolas Graux static struct stmpe_variant_block stmpe1801_blocks[] = {
865230f13a5SJean-Nicolas Graux 	{
866230f13a5SJean-Nicolas Graux 		.cell	= &stmpe_gpio_cell,
867230f13a5SJean-Nicolas Graux 		.irq	= STMPE1801_IRQ_GPIOC,
868230f13a5SJean-Nicolas Graux 		.block	= STMPE_BLOCK_GPIO,
869230f13a5SJean-Nicolas Graux 	},
870230f13a5SJean-Nicolas Graux 	{
871230f13a5SJean-Nicolas Graux 		.cell	= &stmpe_keypad_cell,
872230f13a5SJean-Nicolas Graux 		.irq	= STMPE1801_IRQ_KEYPAD,
873230f13a5SJean-Nicolas Graux 		.block	= STMPE_BLOCK_KEYPAD,
874230f13a5SJean-Nicolas Graux 	},
875230f13a5SJean-Nicolas Graux };
876230f13a5SJean-Nicolas Graux 
877230f13a5SJean-Nicolas Graux static int stmpe1801_enable(struct stmpe *stmpe, unsigned int blocks,
878230f13a5SJean-Nicolas Graux 			    bool enable)
879230f13a5SJean-Nicolas Graux {
880230f13a5SJean-Nicolas Graux 	unsigned int mask = 0;
881230f13a5SJean-Nicolas Graux 	if (blocks & STMPE_BLOCK_GPIO)
882230f13a5SJean-Nicolas Graux 		mask |= STMPE1801_MSK_INT_EN_GPIO;
883230f13a5SJean-Nicolas Graux 
884230f13a5SJean-Nicolas Graux 	if (blocks & STMPE_BLOCK_KEYPAD)
885230f13a5SJean-Nicolas Graux 		mask |= STMPE1801_MSK_INT_EN_KPC;
886230f13a5SJean-Nicolas Graux 
887230f13a5SJean-Nicolas Graux 	return __stmpe_set_bits(stmpe, STMPE1801_REG_INT_EN_MASK_LOW, mask,
888230f13a5SJean-Nicolas Graux 				enable ? mask : 0);
889230f13a5SJean-Nicolas Graux }
890230f13a5SJean-Nicolas Graux 
891c4dd1ba3SPatrice Chotard static int stmpe_reset(struct stmpe *stmpe)
892230f13a5SJean-Nicolas Graux {
893c4dd1ba3SPatrice Chotard 	u16 id_val = stmpe->variant->id_val;
894230f13a5SJean-Nicolas Graux 	unsigned long timeout;
895230f13a5SJean-Nicolas Graux 	int ret = 0;
896c4dd1ba3SPatrice Chotard 	u8 reset_bit;
897c4dd1ba3SPatrice Chotard 
898c4dd1ba3SPatrice Chotard 	if (id_val == STMPE811_ID)
899c4dd1ba3SPatrice Chotard 		/* STMPE801 and STMPE610 use bit 1 of SYS_CTRL register */
900c4dd1ba3SPatrice Chotard 		reset_bit = STMPE811_SYS_CTRL_RESET;
901c4dd1ba3SPatrice Chotard 	else
902c4dd1ba3SPatrice Chotard 		/* all other STMPE variant use bit 7 of SYS_CTRL register */
903c4dd1ba3SPatrice Chotard 		reset_bit = STMPE_SYS_CTRL_RESET;
904230f13a5SJean-Nicolas Graux 
9050f4be8cfSPatrice Chotard 	ret = __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL],
906c4dd1ba3SPatrice Chotard 			       reset_bit, reset_bit);
907230f13a5SJean-Nicolas Graux 	if (ret < 0)
908230f13a5SJean-Nicolas Graux 		return ret;
909230f13a5SJean-Nicolas Graux 
910f4058420SLinus Walleij 	msleep(10);
911f4058420SLinus Walleij 
912230f13a5SJean-Nicolas Graux 	timeout = jiffies + msecs_to_jiffies(100);
913230f13a5SJean-Nicolas Graux 	while (time_before(jiffies, timeout)) {
9140f4be8cfSPatrice Chotard 		ret = __stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL]);
915230f13a5SJean-Nicolas Graux 		if (ret < 0)
916230f13a5SJean-Nicolas Graux 			return ret;
917c4dd1ba3SPatrice Chotard 		if (!(ret & reset_bit))
918230f13a5SJean-Nicolas Graux 			return 0;
919230f13a5SJean-Nicolas Graux 		usleep_range(100, 200);
92052397fe1SSachin Kamat 	}
921230f13a5SJean-Nicolas Graux 	return -EIO;
922230f13a5SJean-Nicolas Graux }
923230f13a5SJean-Nicolas Graux 
924230f13a5SJean-Nicolas Graux static struct stmpe_variant_info stmpe1801 = {
925230f13a5SJean-Nicolas Graux 	.name		= "stmpe1801",
926230f13a5SJean-Nicolas Graux 	.id_val		= STMPE1801_ID,
927230f13a5SJean-Nicolas Graux 	.id_mask	= 0xfff0,
928230f13a5SJean-Nicolas Graux 	.num_gpios	= 18,
929230f13a5SJean-Nicolas Graux 	.af_bits	= 0,
930230f13a5SJean-Nicolas Graux 	.regs		= stmpe1801_regs,
931230f13a5SJean-Nicolas Graux 	.blocks		= stmpe1801_blocks,
932230f13a5SJean-Nicolas Graux 	.num_blocks	= ARRAY_SIZE(stmpe1801_blocks),
933230f13a5SJean-Nicolas Graux 	.num_irqs	= STMPE1801_NR_INTERNAL_IRQS,
934230f13a5SJean-Nicolas Graux 	.enable		= stmpe1801_enable,
935230f13a5SJean-Nicolas Graux 	/* stmpe1801 do not have any gpio alternate function */
936230f13a5SJean-Nicolas Graux 	.get_altfunc	= NULL,
937230f13a5SJean-Nicolas Graux };
938230f13a5SJean-Nicolas Graux 
939230f13a5SJean-Nicolas Graux /*
94027e34995SRabin Vincent  * STMPE24XX
94127e34995SRabin Vincent  */
94227e34995SRabin Vincent 
94327e34995SRabin Vincent static const u8 stmpe24xx_regs[] = {
94427e34995SRabin Vincent 	[STMPE_IDX_CHIP_ID]	= STMPE24XX_REG_CHIP_ID,
9450f4be8cfSPatrice Chotard 	[STMPE_IDX_SYS_CTRL]	= STMPE24XX_REG_SYS_CTRL,
9460f4be8cfSPatrice Chotard 	[STMPE_IDX_SYS_CTRL2]	= STMPE24XX_REG_SYS_CTRL2,
94727e34995SRabin Vincent 	[STMPE_IDX_ICR_LSB]	= STMPE24XX_REG_ICR_LSB,
948897ac667SPatrice Chotard 	[STMPE_IDX_IER_MSB]	= STMPE24XX_REG_IER_MSB,
94927e34995SRabin Vincent 	[STMPE_IDX_IER_LSB]	= STMPE24XX_REG_IER_LSB,
95027e34995SRabin Vincent 	[STMPE_IDX_ISR_MSB]	= STMPE24XX_REG_ISR_MSB,
95127e34995SRabin Vincent 	[STMPE_IDX_GPMR_LSB]	= STMPE24XX_REG_GPMR_LSB,
952897ac667SPatrice Chotard 	[STMPE_IDX_GPMR_CSB]	= STMPE24XX_REG_GPMR_CSB,
953897ac667SPatrice Chotard 	[STMPE_IDX_GPMR_MSB]	= STMPE24XX_REG_GPMR_MSB,
95427e34995SRabin Vincent 	[STMPE_IDX_GPSR_LSB]	= STMPE24XX_REG_GPSR_LSB,
955897ac667SPatrice Chotard 	[STMPE_IDX_GPSR_CSB]	= STMPE24XX_REG_GPSR_CSB,
956897ac667SPatrice Chotard 	[STMPE_IDX_GPSR_MSB]	= STMPE24XX_REG_GPSR_MSB,
95727e34995SRabin Vincent 	[STMPE_IDX_GPCR_LSB]	= STMPE24XX_REG_GPCR_LSB,
958897ac667SPatrice Chotard 	[STMPE_IDX_GPCR_CSB]	= STMPE24XX_REG_GPCR_CSB,
959897ac667SPatrice Chotard 	[STMPE_IDX_GPCR_MSB]	= STMPE24XX_REG_GPCR_MSB,
96027e34995SRabin Vincent 	[STMPE_IDX_GPDR_LSB]	= STMPE24XX_REG_GPDR_LSB,
961897ac667SPatrice Chotard 	[STMPE_IDX_GPDR_CSB]	= STMPE24XX_REG_GPDR_CSB,
962897ac667SPatrice Chotard 	[STMPE_IDX_GPDR_MSB]	= STMPE24XX_REG_GPDR_MSB,
96327e34995SRabin Vincent 	[STMPE_IDX_GPRER_LSB]	= STMPE24XX_REG_GPRER_LSB,
964897ac667SPatrice Chotard 	[STMPE_IDX_GPRER_CSB]	= STMPE24XX_REG_GPRER_CSB,
965897ac667SPatrice Chotard 	[STMPE_IDX_GPRER_MSB]	= STMPE24XX_REG_GPRER_MSB,
96627e34995SRabin Vincent 	[STMPE_IDX_GPFER_LSB]	= STMPE24XX_REG_GPFER_LSB,
967897ac667SPatrice Chotard 	[STMPE_IDX_GPFER_CSB]	= STMPE24XX_REG_GPFER_CSB,
968897ac667SPatrice Chotard 	[STMPE_IDX_GPFER_MSB]	= STMPE24XX_REG_GPFER_MSB,
96980e1dd82SLinus Walleij 	[STMPE_IDX_GPPUR_LSB]	= STMPE24XX_REG_GPPUR_LSB,
97080e1dd82SLinus Walleij 	[STMPE_IDX_GPPDR_LSB]	= STMPE24XX_REG_GPPDR_LSB,
97127e34995SRabin Vincent 	[STMPE_IDX_GPAFR_U_MSB]	= STMPE24XX_REG_GPAFR_U_MSB,
97227e34995SRabin Vincent 	[STMPE_IDX_IEGPIOR_LSB]	= STMPE24XX_REG_IEGPIOR_LSB,
973897ac667SPatrice Chotard 	[STMPE_IDX_IEGPIOR_CSB]	= STMPE24XX_REG_IEGPIOR_CSB,
974897ac667SPatrice Chotard 	[STMPE_IDX_IEGPIOR_MSB]	= STMPE24XX_REG_IEGPIOR_MSB,
97527e34995SRabin Vincent 	[STMPE_IDX_ISGPIOR_MSB]	= STMPE24XX_REG_ISGPIOR_MSB,
976897ac667SPatrice Chotard 	[STMPE_IDX_GPEDR_LSB]	= STMPE24XX_REG_GPEDR_LSB,
977897ac667SPatrice Chotard 	[STMPE_IDX_GPEDR_CSB]	= STMPE24XX_REG_GPEDR_CSB,
97827e34995SRabin Vincent 	[STMPE_IDX_GPEDR_MSB]	= STMPE24XX_REG_GPEDR_MSB,
97927e34995SRabin Vincent };
98027e34995SRabin Vincent 
98127e34995SRabin Vincent static struct stmpe_variant_block stmpe24xx_blocks[] = {
98227e34995SRabin Vincent 	{
98327e34995SRabin Vincent 		.cell	= &stmpe_gpio_cell,
98427e34995SRabin Vincent 		.irq	= STMPE24XX_IRQ_GPIOC,
98527e34995SRabin Vincent 		.block	= STMPE_BLOCK_GPIO,
98627e34995SRabin Vincent 	},
98727e34995SRabin Vincent 	{
98827e34995SRabin Vincent 		.cell	= &stmpe_keypad_cell,
98927e34995SRabin Vincent 		.irq	= STMPE24XX_IRQ_KEYPAD,
99027e34995SRabin Vincent 		.block	= STMPE_BLOCK_KEYPAD,
99127e34995SRabin Vincent 	},
992b273c5e0SLinus Walleij 	{
993b273c5e0SLinus Walleij 		.cell	= &stmpe_pwm_cell,
994b273c5e0SLinus Walleij 		.irq	= STMPE24XX_IRQ_PWM0,
995b273c5e0SLinus Walleij 		.block	= STMPE_BLOCK_PWM,
996b273c5e0SLinus Walleij 	},
99727e34995SRabin Vincent };
99827e34995SRabin Vincent 
99927e34995SRabin Vincent static int stmpe24xx_enable(struct stmpe *stmpe, unsigned int blocks,
100027e34995SRabin Vincent 			    bool enable)
100127e34995SRabin Vincent {
100227e34995SRabin Vincent 	unsigned int mask = 0;
100327e34995SRabin Vincent 
100427e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_GPIO)
100527e34995SRabin Vincent 		mask |= STMPE24XX_SYS_CTRL_ENABLE_GPIO;
100627e34995SRabin Vincent 
100727e34995SRabin Vincent 	if (blocks & STMPE_BLOCK_KEYPAD)
100827e34995SRabin Vincent 		mask |= STMPE24XX_SYS_CTRL_ENABLE_KPC;
100927e34995SRabin Vincent 
10100f4be8cfSPatrice Chotard 	return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], mask,
101127e34995SRabin Vincent 				enable ? mask : 0);
101227e34995SRabin Vincent }
101327e34995SRabin Vincent 
101427e34995SRabin Vincent static int stmpe24xx_get_altfunc(struct stmpe *stmpe, enum stmpe_block block)
101527e34995SRabin Vincent {
101627e34995SRabin Vincent 	switch (block) {
101727e34995SRabin Vincent 	case STMPE_BLOCK_ROTATOR:
101827e34995SRabin Vincent 		return 2;
101927e34995SRabin Vincent 
102027e34995SRabin Vincent 	case STMPE_BLOCK_KEYPAD:
1021f6d10341SLinus Walleij 	case STMPE_BLOCK_PWM:
102227e34995SRabin Vincent 		return 1;
102327e34995SRabin Vincent 
102427e34995SRabin Vincent 	case STMPE_BLOCK_GPIO:
102527e34995SRabin Vincent 	default:
102627e34995SRabin Vincent 		return 0;
102727e34995SRabin Vincent 	}
102827e34995SRabin Vincent }
102927e34995SRabin Vincent 
103027e34995SRabin Vincent static struct stmpe_variant_info stmpe2401 = {
103127e34995SRabin Vincent 	.name		= "stmpe2401",
103227e34995SRabin Vincent 	.id_val		= 0x0101,
103327e34995SRabin Vincent 	.id_mask	= 0xffff,
103427e34995SRabin Vincent 	.num_gpios	= 24,
103527e34995SRabin Vincent 	.af_bits	= 2,
103627e34995SRabin Vincent 	.regs		= stmpe24xx_regs,
103727e34995SRabin Vincent 	.blocks		= stmpe24xx_blocks,
103827e34995SRabin Vincent 	.num_blocks	= ARRAY_SIZE(stmpe24xx_blocks),
103927e34995SRabin Vincent 	.num_irqs	= STMPE24XX_NR_INTERNAL_IRQS,
104027e34995SRabin Vincent 	.enable		= stmpe24xx_enable,
104127e34995SRabin Vincent 	.get_altfunc	= stmpe24xx_get_altfunc,
104227e34995SRabin Vincent };
104327e34995SRabin Vincent 
104427e34995SRabin Vincent static struct stmpe_variant_info stmpe2403 = {
104527e34995SRabin Vincent 	.name		= "stmpe2403",
104627e34995SRabin Vincent 	.id_val		= 0x0120,
104727e34995SRabin Vincent 	.id_mask	= 0xffff,
104827e34995SRabin Vincent 	.num_gpios	= 24,
104927e34995SRabin Vincent 	.af_bits	= 2,
105027e34995SRabin Vincent 	.regs		= stmpe24xx_regs,
105127e34995SRabin Vincent 	.blocks		= stmpe24xx_blocks,
105227e34995SRabin Vincent 	.num_blocks	= ARRAY_SIZE(stmpe24xx_blocks),
105327e34995SRabin Vincent 	.num_irqs	= STMPE24XX_NR_INTERNAL_IRQS,
105427e34995SRabin Vincent 	.enable		= stmpe24xx_enable,
105527e34995SRabin Vincent 	.get_altfunc	= stmpe24xx_get_altfunc,
10565981f4e6SSundar R Iyer 	.enable_autosleep	= stmpe1601_autosleep, /* same as stmpe1601 */
105727e34995SRabin Vincent };
105827e34995SRabin Vincent 
1059e31f9b82SChris Blair static struct stmpe_variant_info *stmpe_variant_info[STMPE_NBR_PARTS] = {
10601cda2394SViresh Kumar 	[STMPE610]	= &stmpe610,
10617f7f4ea1SViresh Kumar 	[STMPE801]	= &stmpe801,
106227e34995SRabin Vincent 	[STMPE811]	= &stmpe811,
10636bb9f0d9SPatrice Chotard 	[STMPE1600]	= &stmpe1600,
106427e34995SRabin Vincent 	[STMPE1601]	= &stmpe1601,
1065230f13a5SJean-Nicolas Graux 	[STMPE1801]	= &stmpe1801,
106627e34995SRabin Vincent 	[STMPE2401]	= &stmpe2401,
106727e34995SRabin Vincent 	[STMPE2403]	= &stmpe2403,
106827e34995SRabin Vincent };
106927e34995SRabin Vincent 
1070e31f9b82SChris Blair /*
1071e31f9b82SChris Blair  * These devices can be connected in a 'no-irq' configuration - the irq pin
1072e31f9b82SChris Blair  * is not used and the device cannot interrupt the CPU. Here we only list
1073e31f9b82SChris Blair  * devices which support this configuration - the driver will fail probing
1074e31f9b82SChris Blair  * for any devices not listed here which are configured in this way.
1075e31f9b82SChris Blair  */
1076e31f9b82SChris Blair static struct stmpe_variant_info *stmpe_noirq_variant_info[STMPE_NBR_PARTS] = {
1077e31f9b82SChris Blair 	[STMPE801]	= &stmpe801_noirq,
1078e31f9b82SChris Blair };
1079e31f9b82SChris Blair 
108027e34995SRabin Vincent static irqreturn_t stmpe_irq(int irq, void *data)
108127e34995SRabin Vincent {
108227e34995SRabin Vincent 	struct stmpe *stmpe = data;
108327e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
108427e34995SRabin Vincent 	int num = DIV_ROUND_UP(variant->num_irqs, 8);
1085230f13a5SJean-Nicolas Graux 	u8 israddr;
10867929fa77SLee Jones 	u8 isr[3];
108727e34995SRabin Vincent 	int ret;
108827e34995SRabin Vincent 	int i;
108927e34995SRabin Vincent 
10906bb9f0d9SPatrice Chotard 	if (variant->id_val == STMPE801_ID ||
10916bb9f0d9SPatrice Chotard 	    variant->id_val == STMPE1600_ID) {
10929ff80e2dSMarc Zyngier 		int base = irq_find_mapping(stmpe->domain, 0);
109376f93992SLee Jones 
109476f93992SLee Jones 		handle_nested_irq(base);
10957f7f4ea1SViresh Kumar 		return IRQ_HANDLED;
10967f7f4ea1SViresh Kumar 	}
10977f7f4ea1SViresh Kumar 
1098230f13a5SJean-Nicolas Graux 	if (variant->id_val == STMPE1801_ID)
1099230f13a5SJean-Nicolas Graux 		israddr = stmpe->regs[STMPE_IDX_ISR_LSB];
1100230f13a5SJean-Nicolas Graux 	else
1101230f13a5SJean-Nicolas Graux 		israddr = stmpe->regs[STMPE_IDX_ISR_MSB];
1102230f13a5SJean-Nicolas Graux 
110327e34995SRabin Vincent 	ret = stmpe_block_read(stmpe, israddr, num, isr);
110427e34995SRabin Vincent 	if (ret < 0)
110527e34995SRabin Vincent 		return IRQ_NONE;
110627e34995SRabin Vincent 
110727e34995SRabin Vincent 	for (i = 0; i < num; i++) {
110827e34995SRabin Vincent 		int bank = num - i - 1;
110927e34995SRabin Vincent 		u8 status = isr[i];
111027e34995SRabin Vincent 		u8 clear;
111127e34995SRabin Vincent 
111227e34995SRabin Vincent 		status &= stmpe->ier[bank];
111327e34995SRabin Vincent 		if (!status)
111427e34995SRabin Vincent 			continue;
111527e34995SRabin Vincent 
111627e34995SRabin Vincent 		clear = status;
111727e34995SRabin Vincent 		while (status) {
111827e34995SRabin Vincent 			int bit = __ffs(status);
111927e34995SRabin Vincent 			int line = bank * 8 + bit;
11209ff80e2dSMarc Zyngier 			int nestedirq = irq_find_mapping(stmpe->domain, line);
112127e34995SRabin Vincent 
112276f93992SLee Jones 			handle_nested_irq(nestedirq);
112327e34995SRabin Vincent 			status &= ~(1 << bit);
112427e34995SRabin Vincent 		}
112527e34995SRabin Vincent 
112627e34995SRabin Vincent 		stmpe_reg_write(stmpe, israddr + i, clear);
112727e34995SRabin Vincent 	}
112827e34995SRabin Vincent 
112927e34995SRabin Vincent 	return IRQ_HANDLED;
113027e34995SRabin Vincent }
113127e34995SRabin Vincent 
113243b8c084SMark Brown static void stmpe_irq_lock(struct irq_data *data)
113327e34995SRabin Vincent {
113443b8c084SMark Brown 	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
113527e34995SRabin Vincent 
113627e34995SRabin Vincent 	mutex_lock(&stmpe->irq_lock);
113727e34995SRabin Vincent }
113827e34995SRabin Vincent 
113943b8c084SMark Brown static void stmpe_irq_sync_unlock(struct irq_data *data)
114027e34995SRabin Vincent {
114143b8c084SMark Brown 	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
114227e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
114327e34995SRabin Vincent 	int num = DIV_ROUND_UP(variant->num_irqs, 8);
114427e34995SRabin Vincent 	int i;
114527e34995SRabin Vincent 
114627e34995SRabin Vincent 	for (i = 0; i < num; i++) {
114727e34995SRabin Vincent 		u8 new = stmpe->ier[i];
114827e34995SRabin Vincent 		u8 old = stmpe->oldier[i];
114927e34995SRabin Vincent 
115027e34995SRabin Vincent 		if (new == old)
115127e34995SRabin Vincent 			continue;
115227e34995SRabin Vincent 
115327e34995SRabin Vincent 		stmpe->oldier[i] = new;
1154897ac667SPatrice Chotard 		stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_IER_LSB + i], new);
115527e34995SRabin Vincent 	}
115627e34995SRabin Vincent 
115727e34995SRabin Vincent 	mutex_unlock(&stmpe->irq_lock);
115827e34995SRabin Vincent }
115927e34995SRabin Vincent 
116043b8c084SMark Brown static void stmpe_irq_mask(struct irq_data *data)
116127e34995SRabin Vincent {
116243b8c084SMark Brown 	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
116376f93992SLee Jones 	int offset = data->hwirq;
116427e34995SRabin Vincent 	int regoffset = offset / 8;
116527e34995SRabin Vincent 	int mask = 1 << (offset % 8);
116627e34995SRabin Vincent 
116727e34995SRabin Vincent 	stmpe->ier[regoffset] &= ~mask;
116827e34995SRabin Vincent }
116927e34995SRabin Vincent 
117043b8c084SMark Brown static void stmpe_irq_unmask(struct irq_data *data)
117127e34995SRabin Vincent {
117243b8c084SMark Brown 	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
117376f93992SLee Jones 	int offset = data->hwirq;
117427e34995SRabin Vincent 	int regoffset = offset / 8;
117527e34995SRabin Vincent 	int mask = 1 << (offset % 8);
117627e34995SRabin Vincent 
117727e34995SRabin Vincent 	stmpe->ier[regoffset] |= mask;
117827e34995SRabin Vincent }
117927e34995SRabin Vincent 
118027e34995SRabin Vincent static struct irq_chip stmpe_irq_chip = {
118127e34995SRabin Vincent 	.name			= "stmpe",
118243b8c084SMark Brown 	.irq_bus_lock		= stmpe_irq_lock,
118343b8c084SMark Brown 	.irq_bus_sync_unlock	= stmpe_irq_sync_unlock,
118443b8c084SMark Brown 	.irq_mask		= stmpe_irq_mask,
118543b8c084SMark Brown 	.irq_unmask		= stmpe_irq_unmask,
118627e34995SRabin Vincent };
118727e34995SRabin Vincent 
118876f93992SLee Jones static int stmpe_irq_map(struct irq_domain *d, unsigned int virq,
118976f93992SLee Jones                                 irq_hw_number_t hwirq)
119027e34995SRabin Vincent {
119176f93992SLee Jones 	struct stmpe *stmpe = d->host_data;
11927f7f4ea1SViresh Kumar 	struct irq_chip *chip = NULL;
119327e34995SRabin Vincent 
11947f7f4ea1SViresh Kumar 	if (stmpe->variant->id_val != STMPE801_ID)
11957f7f4ea1SViresh Kumar 		chip = &stmpe_irq_chip;
11967f7f4ea1SViresh Kumar 
119776f93992SLee Jones 	irq_set_chip_data(virq, stmpe);
119876f93992SLee Jones 	irq_set_chip_and_handler(virq, chip, handle_edge_irq);
119976f93992SLee Jones 	irq_set_nested_thread(virq, 1);
120076f93992SLee Jones 	irq_set_noprobe(virq);
120127e34995SRabin Vincent 
120227e34995SRabin Vincent 	return 0;
120327e34995SRabin Vincent }
120427e34995SRabin Vincent 
120576f93992SLee Jones static void stmpe_irq_unmap(struct irq_domain *d, unsigned int virq)
120627e34995SRabin Vincent {
120776f93992SLee Jones 		irq_set_chip_and_handler(virq, NULL, NULL);
120876f93992SLee Jones 		irq_set_chip_data(virq, NULL);
120927e34995SRabin Vincent }
121076f93992SLee Jones 
12117ce7b26fSKrzysztof Kozlowski static const struct irq_domain_ops stmpe_irq_ops = {
121276f93992SLee Jones         .map    = stmpe_irq_map,
121376f93992SLee Jones         .unmap  = stmpe_irq_unmap,
121476f93992SLee Jones         .xlate  = irq_domain_xlate_twocell,
121576f93992SLee Jones };
121676f93992SLee Jones 
1217612b95cdSGreg Kroah-Hartman static int stmpe_irq_init(struct stmpe *stmpe, struct device_node *np)
121876f93992SLee Jones {
1219b20a4371SLee Jones 	int base = 0;
122076f93992SLee Jones 	int num_irqs = stmpe->variant->num_irqs;
122176f93992SLee Jones 
1222b20a4371SLee Jones 	stmpe->domain = irq_domain_add_simple(np, num_irqs, base,
1223b20a4371SLee Jones 					      &stmpe_irq_ops, stmpe);
122476f93992SLee Jones 	if (!stmpe->domain) {
122576f93992SLee Jones 		dev_err(stmpe->dev, "Failed to create irqdomain\n");
122676f93992SLee Jones 		return -ENOSYS;
122776f93992SLee Jones 	}
122876f93992SLee Jones 
122976f93992SLee Jones 	return 0;
123027e34995SRabin Vincent }
123127e34995SRabin Vincent 
1232612b95cdSGreg Kroah-Hartman static int stmpe_chip_init(struct stmpe *stmpe)
123327e34995SRabin Vincent {
123427e34995SRabin Vincent 	unsigned int irq_trigger = stmpe->pdata->irq_trigger;
12355981f4e6SSundar R Iyer 	int autosleep_timeout = stmpe->pdata->autosleep_timeout;
123627e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
1237e31f9b82SChris Blair 	u8 icr = 0;
123827e34995SRabin Vincent 	unsigned int id;
123927e34995SRabin Vincent 	u8 data[2];
124027e34995SRabin Vincent 	int ret;
124127e34995SRabin Vincent 
124227e34995SRabin Vincent 	ret = stmpe_block_read(stmpe, stmpe->regs[STMPE_IDX_CHIP_ID],
124327e34995SRabin Vincent 			       ARRAY_SIZE(data), data);
124427e34995SRabin Vincent 	if (ret < 0)
124527e34995SRabin Vincent 		return ret;
124627e34995SRabin Vincent 
124727e34995SRabin Vincent 	id = (data[0] << 8) | data[1];
124827e34995SRabin Vincent 	if ((id & variant->id_mask) != variant->id_val) {
124927e34995SRabin Vincent 		dev_err(stmpe->dev, "unknown chip id: %#x\n", id);
125027e34995SRabin Vincent 		return -EINVAL;
125127e34995SRabin Vincent 	}
125227e34995SRabin Vincent 
125327e34995SRabin Vincent 	dev_info(stmpe->dev, "%s detected, chip id: %#x\n", variant->name, id);
125427e34995SRabin Vincent 
125527e34995SRabin Vincent 	/* Disable all modules -- subdrivers should enable what they need. */
125627e34995SRabin Vincent 	ret = stmpe_disable(stmpe, ~0);
125727e34995SRabin Vincent 	if (ret)
125827e34995SRabin Vincent 		return ret;
125927e34995SRabin Vincent 
1260c4dd1ba3SPatrice Chotard 	ret =  stmpe_reset(stmpe);
1261230f13a5SJean-Nicolas Graux 	if (ret < 0)
1262230f13a5SJean-Nicolas Graux 		return ret;
1263230f13a5SJean-Nicolas Graux 
1264e31f9b82SChris Blair 	if (stmpe->irq >= 0) {
12656bb9f0d9SPatrice Chotard 		if (id == STMPE801_ID || id == STMPE1600_ID)
1266c16bee78SPatrice Chotard 			icr = STMPE_SYS_CTRL_INT_EN;
12677f7f4ea1SViresh Kumar 		else
12687f7f4ea1SViresh Kumar 			icr = STMPE_ICR_LSB_GIM;
12697f7f4ea1SViresh Kumar 
12706bb9f0d9SPatrice Chotard 		/* STMPE801 and STMPE1600 don't support Edge interrupts */
12716bb9f0d9SPatrice Chotard 		if (id != STMPE801_ID && id != STMPE1600_ID) {
127227e34995SRabin Vincent 			if (irq_trigger == IRQF_TRIGGER_FALLING ||
127327e34995SRabin Vincent 					irq_trigger == IRQF_TRIGGER_RISING)
127427e34995SRabin Vincent 				icr |= STMPE_ICR_LSB_EDGE;
12757f7f4ea1SViresh Kumar 		}
127627e34995SRabin Vincent 
127727e34995SRabin Vincent 		if (irq_trigger == IRQF_TRIGGER_RISING ||
12787f7f4ea1SViresh Kumar 				irq_trigger == IRQF_TRIGGER_HIGH) {
12796bb9f0d9SPatrice Chotard 			if (id == STMPE801_ID || id == STMPE1600_ID)
1280c16bee78SPatrice Chotard 				icr |= STMPE_SYS_CTRL_INT_HI;
12817f7f4ea1SViresh Kumar 			else
128227e34995SRabin Vincent 				icr |= STMPE_ICR_LSB_HIGH;
12837f7f4ea1SViresh Kumar 		}
1284e31f9b82SChris Blair 	}
128527e34995SRabin Vincent 
12865981f4e6SSundar R Iyer 	if (stmpe->pdata->autosleep) {
12875981f4e6SSundar R Iyer 		ret = stmpe_autosleep(stmpe, autosleep_timeout);
12885981f4e6SSundar R Iyer 		if (ret)
12895981f4e6SSundar R Iyer 			return ret;
12905981f4e6SSundar R Iyer 	}
12915981f4e6SSundar R Iyer 
129227e34995SRabin Vincent 	return stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_ICR_LSB], icr);
129327e34995SRabin Vincent }
129427e34995SRabin Vincent 
12956bbb3c4cSGeert Uytterhoeven static int stmpe_add_device(struct stmpe *stmpe, const struct mfd_cell *cell)
129627e34995SRabin Vincent {
129727e34995SRabin Vincent 	return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1,
12989e9dc7d9SLinus Walleij 			       NULL, 0, stmpe->domain);
129927e34995SRabin Vincent }
130027e34995SRabin Vincent 
1301612b95cdSGreg Kroah-Hartman static int stmpe_devices_init(struct stmpe *stmpe)
130227e34995SRabin Vincent {
130327e34995SRabin Vincent 	struct stmpe_variant_info *variant = stmpe->variant;
130427e34995SRabin Vincent 	unsigned int platform_blocks = stmpe->pdata->blocks;
130527e34995SRabin Vincent 	int ret = -EINVAL;
13067da0cbfcSLee Jones 	int i, j;
130727e34995SRabin Vincent 
130827e34995SRabin Vincent 	for (i = 0; i < variant->num_blocks; i++) {
130927e34995SRabin Vincent 		struct stmpe_variant_block *block = &variant->blocks[i];
131027e34995SRabin Vincent 
131127e34995SRabin Vincent 		if (!(platform_blocks & block->block))
131227e34995SRabin Vincent 			continue;
131327e34995SRabin Vincent 
13147da0cbfcSLee Jones 		for (j = 0; j < block->cell->num_resources; j++) {
13157da0cbfcSLee Jones 			struct resource *res =
13167da0cbfcSLee Jones 				(struct resource *) &block->cell->resources[j];
13177da0cbfcSLee Jones 
13187da0cbfcSLee Jones 			/* Dynamically fill in a variant's IRQ. */
13197da0cbfcSLee Jones 			if (res->flags & IORESOURCE_IRQ)
13207da0cbfcSLee Jones 				res->start = res->end = block->irq + j;
13217da0cbfcSLee Jones 		}
13227da0cbfcSLee Jones 
132327e34995SRabin Vincent 		platform_blocks &= ~block->block;
13247da0cbfcSLee Jones 		ret = stmpe_add_device(stmpe, block->cell);
132527e34995SRabin Vincent 		if (ret)
132627e34995SRabin Vincent 			return ret;
132727e34995SRabin Vincent 	}
132827e34995SRabin Vincent 
132927e34995SRabin Vincent 	if (platform_blocks)
133027e34995SRabin Vincent 		dev_warn(stmpe->dev,
133127e34995SRabin Vincent 			 "platform wants blocks (%#x) not present on variant",
133227e34995SRabin Vincent 			 platform_blocks);
133327e34995SRabin Vincent 
133427e34995SRabin Vincent 	return ret;
133527e34995SRabin Vincent }
133627e34995SRabin Vincent 
1337a9c4055dSMark Brown static void stmpe_of_probe(struct stmpe_platform_data *pdata,
1338a9c4055dSMark Brown 			   struct device_node *np)
1339909582caSLee Jones {
1340909582caSLee Jones 	struct device_node *child;
1341909582caSLee Jones 
1342408a3fa8SGabriel Fernandez 	pdata->id = of_alias_get_id(np, "stmpe-i2c");
1343408a3fa8SGabriel Fernandez 	if (pdata->id < 0)
1344ac713cc9SVipul Kumar Samar 		pdata->id = -1;
1345408a3fa8SGabriel Fernandez 
1346909582caSLee Jones 	of_property_read_u32(np, "st,autosleep-timeout",
1347909582caSLee Jones 			&pdata->autosleep_timeout);
1348909582caSLee Jones 
1349909582caSLee Jones 	pdata->autosleep = (pdata->autosleep_timeout) ? true : false;
1350909582caSLee Jones 
1351786c6f14SOleksandr Suvorov 	for_each_available_child_of_node(np, child) {
1352d7667f19SFrancesco Dolcini 		if (of_device_is_compatible(child, stmpe_gpio_cell.of_compatible))
1353909582caSLee Jones 			pdata->blocks |= STMPE_BLOCK_GPIO;
1354d7667f19SFrancesco Dolcini 		else if (of_device_is_compatible(child, stmpe_keypad_cell.of_compatible))
1355909582caSLee Jones 			pdata->blocks |= STMPE_BLOCK_KEYPAD;
1356d7667f19SFrancesco Dolcini 		else if (of_device_is_compatible(child, stmpe_ts_cell.of_compatible))
1357909582caSLee Jones 			pdata->blocks |= STMPE_BLOCK_TOUCHSCREEN;
1358d7667f19SFrancesco Dolcini 		else if (of_device_is_compatible(child, stmpe_adc_cell.of_compatible))
1359909582caSLee Jones 			pdata->blocks |= STMPE_BLOCK_ADC;
1360d7667f19SFrancesco Dolcini 		else if (of_device_is_compatible(child, stmpe_pwm_cell.of_compatible))
1361ac713cc9SVipul Kumar Samar 			pdata->blocks |= STMPE_BLOCK_PWM;
1362909582caSLee Jones 	}
1363909582caSLee Jones }
1364909582caSLee Jones 
13651a6e4b74SViresh Kumar /* Called from client specific probe routines */
1366c00572bcSLee Jones int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum)
1367208c4343SSundar Iyer {
1368fc1882dcSLinus Walleij 	struct stmpe_platform_data *pdata;
1369909582caSLee Jones 	struct device_node *np = ci->dev->of_node;
137027e34995SRabin Vincent 	struct stmpe *stmpe;
1371ac3e9119SDmitry Torokhov 	struct gpio_desc *irq_gpio;
137227e34995SRabin Vincent 	int ret;
13736377cfa3SStefan Agner 	u32 val;
137427e34995SRabin Vincent 
1375cb5faba9SViresh Kumar 	pdata = devm_kzalloc(ci->dev, sizeof(*pdata), GFP_KERNEL);
137627e34995SRabin Vincent 	if (!pdata)
1377909582caSLee Jones 		return -ENOMEM;
1378909582caSLee Jones 
1379909582caSLee Jones 	stmpe_of_probe(pdata, np);
1380a200e320SGabriel Fernandez 
13811ba58fbbSRob Herring 	if (!of_property_present(np, "interrupts"))
1382a200e320SGabriel Fernandez 		ci->irq = -1;
138327e34995SRabin Vincent 
1384cb5faba9SViresh Kumar 	stmpe = devm_kzalloc(ci->dev, sizeof(struct stmpe), GFP_KERNEL);
138527e34995SRabin Vincent 	if (!stmpe)
138627e34995SRabin Vincent 		return -ENOMEM;
138727e34995SRabin Vincent 
138827e34995SRabin Vincent 	mutex_init(&stmpe->irq_lock);
138927e34995SRabin Vincent 	mutex_init(&stmpe->lock);
139027e34995SRabin Vincent 
13916377cfa3SStefan Agner 	if (!of_property_read_u32(np, "st,sample-time", &val))
13926377cfa3SStefan Agner 		stmpe->sample_time = val;
13936377cfa3SStefan Agner 	if (!of_property_read_u32(np, "st,mod-12b", &val))
13946377cfa3SStefan Agner 		stmpe->mod_12b = val;
13956377cfa3SStefan Agner 	if (!of_property_read_u32(np, "st,ref-sel", &val))
13966377cfa3SStefan Agner 		stmpe->ref_sel = val;
13976377cfa3SStefan Agner 	if (!of_property_read_u32(np, "st,adc-freq", &val))
13986377cfa3SStefan Agner 		stmpe->adc_freq = val;
13996377cfa3SStefan Agner 
14001a6e4b74SViresh Kumar 	stmpe->dev = ci->dev;
14011a6e4b74SViresh Kumar 	stmpe->client = ci->client;
140227e34995SRabin Vincent 	stmpe->pdata = pdata;
14031a6e4b74SViresh Kumar 	stmpe->ci = ci;
14041a6e4b74SViresh Kumar 	stmpe->partnum = partnum;
14051a6e4b74SViresh Kumar 	stmpe->variant = stmpe_variant_info[partnum];
140627e34995SRabin Vincent 	stmpe->regs = stmpe->variant->regs;
140727e34995SRabin Vincent 	stmpe->num_gpios = stmpe->variant->num_gpios;
14089c9e3214SLinus Walleij 	stmpe->vcc = devm_regulator_get_optional(ci->dev, "vcc");
14099c9e3214SLinus Walleij 	if (!IS_ERR(stmpe->vcc)) {
14109c9e3214SLinus Walleij 		ret = regulator_enable(stmpe->vcc);
14119c9e3214SLinus Walleij 		if (ret)
14129c9e3214SLinus Walleij 			dev_warn(ci->dev, "failed to enable VCC supply\n");
14139c9e3214SLinus Walleij 	}
14149c9e3214SLinus Walleij 	stmpe->vio = devm_regulator_get_optional(ci->dev, "vio");
14159c9e3214SLinus Walleij 	if (!IS_ERR(stmpe->vio)) {
14169c9e3214SLinus Walleij 		ret = regulator_enable(stmpe->vio);
14179c9e3214SLinus Walleij 		if (ret)
14189c9e3214SLinus Walleij 			dev_warn(ci->dev, "failed to enable VIO supply\n");
14199c9e3214SLinus Walleij 	}
14201a6e4b74SViresh Kumar 	dev_set_drvdata(stmpe->dev, stmpe);
142127e34995SRabin Vincent 
14221a6e4b74SViresh Kumar 	if (ci->init)
14231a6e4b74SViresh Kumar 		ci->init(stmpe);
142427e34995SRabin Vincent 
1425ac3e9119SDmitry Torokhov 	irq_gpio = devm_gpiod_get_optional(ci->dev, "irq", GPIOD_ASIS);
1426ac3e9119SDmitry Torokhov 	ret = PTR_ERR_OR_ZERO(irq_gpio);
142773de16dbSViresh Kumar 	if (ret) {
1428ac3e9119SDmitry Torokhov 		dev_err(stmpe->dev, "failed to request IRQ GPIO: %d\n", ret);
1429cb5faba9SViresh Kumar 		return ret;
143073de16dbSViresh Kumar 	}
143173de16dbSViresh Kumar 
1432ac3e9119SDmitry Torokhov 	if (irq_gpio) {
1433ac3e9119SDmitry Torokhov 		stmpe->irq = gpiod_to_irq(irq_gpio);
1434ac3e9119SDmitry Torokhov 		pdata->irq_trigger = gpiod_is_active_low(irq_gpio) ?
1435ac3e9119SDmitry Torokhov 					IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH;
143673de16dbSViresh Kumar 	} else {
14371a6e4b74SViresh Kumar 		stmpe->irq = ci->irq;
1438ac3e9119SDmitry Torokhov 		pdata->irq_trigger = IRQF_TRIGGER_NONE;
143973de16dbSViresh Kumar 	}
144073de16dbSViresh Kumar 
1441e31f9b82SChris Blair 	if (stmpe->irq < 0) {
1442e31f9b82SChris Blair 		/* use alternate variant info for no-irq mode, if supported */
1443e31f9b82SChris Blair 		dev_info(stmpe->dev,
1444e31f9b82SChris Blair 			"%s configured in no-irq mode by platform data\n",
1445e31f9b82SChris Blair 			stmpe->variant->name);
1446e31f9b82SChris Blair 		if (!stmpe_noirq_variant_info[stmpe->partnum]) {
1447e31f9b82SChris Blair 			dev_err(stmpe->dev,
1448e31f9b82SChris Blair 				"%s does not support no-irq mode!\n",
1449e31f9b82SChris Blair 				stmpe->variant->name);
1450cb5faba9SViresh Kumar 			return -ENODEV;
1451e31f9b82SChris Blair 		}
1452e31f9b82SChris Blair 		stmpe->variant = stmpe_noirq_variant_info[stmpe->partnum];
1453ac713cc9SVipul Kumar Samar 	} else if (pdata->irq_trigger == IRQF_TRIGGER_NONE) {
14541a5595cbSJavier Martinez Canillas 		pdata->irq_trigger = irq_get_trigger_type(stmpe->irq);
1455e31f9b82SChris Blair 	}
1456e31f9b82SChris Blair 
145727e34995SRabin Vincent 	ret = stmpe_chip_init(stmpe);
145827e34995SRabin Vincent 	if (ret)
1459cb5faba9SViresh Kumar 		return ret;
146027e34995SRabin Vincent 
1461e31f9b82SChris Blair 	if (stmpe->irq >= 0) {
1462909582caSLee Jones 		ret = stmpe_irq_init(stmpe, np);
146327e34995SRabin Vincent 		if (ret)
1464cb5faba9SViresh Kumar 			return ret;
146527e34995SRabin Vincent 
1466cb5faba9SViresh Kumar 		ret = devm_request_threaded_irq(ci->dev, stmpe->irq, NULL,
1467cb5faba9SViresh Kumar 				stmpe_irq, pdata->irq_trigger | IRQF_ONESHOT,
1468e31f9b82SChris Blair 				"stmpe", stmpe);
146927e34995SRabin Vincent 		if (ret) {
1470e31f9b82SChris Blair 			dev_err(stmpe->dev, "failed to request IRQ: %d\n",
1471e31f9b82SChris Blair 					ret);
1472cb5faba9SViresh Kumar 			return ret;
147327e34995SRabin Vincent 		}
1474e31f9b82SChris Blair 	}
147527e34995SRabin Vincent 
147627e34995SRabin Vincent 	ret = stmpe_devices_init(stmpe);
1477cb5faba9SViresh Kumar 	if (!ret)
147827e34995SRabin Vincent 		return 0;
147927e34995SRabin Vincent 
1480cb5faba9SViresh Kumar 	dev_err(stmpe->dev, "failed to add children\n");
148127e34995SRabin Vincent 	mfd_remove_devices(stmpe->dev);
1482cb5faba9SViresh Kumar 
148327e34995SRabin Vincent 	return ret;
148427e34995SRabin Vincent }
148527e34995SRabin Vincent 
1486356bbabaSUwe Kleine-König void stmpe_remove(struct stmpe *stmpe)
148727e34995SRabin Vincent {
1488*104d32bdSChristophe JAILLET 	if (!IS_ERR(stmpe->vio) && regulator_is_enabled(stmpe->vio))
14899c9e3214SLinus Walleij 		regulator_disable(stmpe->vio);
1490*104d32bdSChristophe JAILLET 	if (!IS_ERR(stmpe->vcc) && regulator_is_enabled(stmpe->vcc))
14919c9e3214SLinus Walleij 		regulator_disable(stmpe->vcc);
14929c9e3214SLinus Walleij 
14936377cfa3SStefan Agner 	__stmpe_disable(stmpe, STMPE_BLOCK_ADC);
14946377cfa3SStefan Agner 
149527e34995SRabin Vincent 	mfd_remove_devices(stmpe->dev);
149627e34995SRabin Vincent }
149727e34995SRabin Vincent 
14981a6e4b74SViresh Kumar static int stmpe_suspend(struct device *dev)
14991a6e4b74SViresh Kumar {
15001a6e4b74SViresh Kumar 	struct stmpe *stmpe = dev_get_drvdata(dev);
15011a6e4b74SViresh Kumar 
1502e31f9b82SChris Blair 	if (stmpe->irq >= 0 && device_may_wakeup(dev))
15031a6e4b74SViresh Kumar 		enable_irq_wake(stmpe->irq);
15041a6e4b74SViresh Kumar 
15051a6e4b74SViresh Kumar 	return 0;
15061a6e4b74SViresh Kumar }
15071a6e4b74SViresh Kumar 
15081a6e4b74SViresh Kumar static int stmpe_resume(struct device *dev)
15091a6e4b74SViresh Kumar {
15101a6e4b74SViresh Kumar 	struct stmpe *stmpe = dev_get_drvdata(dev);
15111a6e4b74SViresh Kumar 
1512e31f9b82SChris Blair 	if (stmpe->irq >= 0 && device_may_wakeup(dev))
15131a6e4b74SViresh Kumar 		disable_irq_wake(stmpe->irq);
15141a6e4b74SViresh Kumar 
15151a6e4b74SViresh Kumar 	return 0;
15161a6e4b74SViresh Kumar }
15171a6e4b74SViresh Kumar 
1518f7f292feSPaul Cercueil EXPORT_GPL_SIMPLE_DEV_PM_OPS(stmpe_dev_pm_ops,
1519f7f292feSPaul Cercueil 			     stmpe_suspend, stmpe_resume);
1520