162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * ST Microelectronics MFD: stmpe's driver
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) ST-Ericsson SA 2010
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/err.h>
1162306a36Sopenharmony_ci#include <linux/gpio/consumer.h>
1262306a36Sopenharmony_ci#include <linux/export.h>
1362306a36Sopenharmony_ci#include <linux/kernel.h>
1462306a36Sopenharmony_ci#include <linux/interrupt.h>
1562306a36Sopenharmony_ci#include <linux/irq.h>
1662306a36Sopenharmony_ci#include <linux/irqdomain.h>
1762306a36Sopenharmony_ci#include <linux/of.h>
1862306a36Sopenharmony_ci#include <linux/pm.h>
1962306a36Sopenharmony_ci#include <linux/slab.h>
2062306a36Sopenharmony_ci#include <linux/mfd/core.h>
2162306a36Sopenharmony_ci#include <linux/delay.h>
2262306a36Sopenharmony_ci#include <linux/regulator/consumer.h>
2362306a36Sopenharmony_ci#include "stmpe.h"
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci/**
2662306a36Sopenharmony_ci * struct stmpe_platform_data - STMPE platform data
2762306a36Sopenharmony_ci * @id: device id to distinguish between multiple STMPEs on the same board
2862306a36Sopenharmony_ci * @blocks: bitmask of blocks to enable (use STMPE_BLOCK_*)
2962306a36Sopenharmony_ci * @irq_trigger: IRQ trigger to use for the interrupt to the host
3062306a36Sopenharmony_ci * @autosleep: bool to enable/disable stmpe autosleep
3162306a36Sopenharmony_ci * @autosleep_timeout: inactivity timeout in milliseconds for autosleep
3262306a36Sopenharmony_ci */
3362306a36Sopenharmony_cistruct stmpe_platform_data {
3462306a36Sopenharmony_ci	int id;
3562306a36Sopenharmony_ci	unsigned int blocks;
3662306a36Sopenharmony_ci	unsigned int irq_trigger;
3762306a36Sopenharmony_ci	bool autosleep;
3862306a36Sopenharmony_ci	int autosleep_timeout;
3962306a36Sopenharmony_ci};
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_cistatic int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks)
4262306a36Sopenharmony_ci{
4362306a36Sopenharmony_ci	return stmpe->variant->enable(stmpe, blocks, true);
4462306a36Sopenharmony_ci}
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cistatic int __stmpe_disable(struct stmpe *stmpe, unsigned int blocks)
4762306a36Sopenharmony_ci{
4862306a36Sopenharmony_ci	return stmpe->variant->enable(stmpe, blocks, false);
4962306a36Sopenharmony_ci}
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cistatic int __stmpe_reg_read(struct stmpe *stmpe, u8 reg)
5262306a36Sopenharmony_ci{
5362306a36Sopenharmony_ci	int ret;
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	ret = stmpe->ci->read_byte(stmpe, reg);
5662306a36Sopenharmony_ci	if (ret < 0)
5762306a36Sopenharmony_ci		dev_err(stmpe->dev, "failed to read reg %#x: %d\n", reg, ret);
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	dev_vdbg(stmpe->dev, "rd: reg %#x => data %#x\n", reg, ret);
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	return ret;
6262306a36Sopenharmony_ci}
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_cistatic int __stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val)
6562306a36Sopenharmony_ci{
6662306a36Sopenharmony_ci	int ret;
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	dev_vdbg(stmpe->dev, "wr: reg %#x <= %#x\n", reg, val);
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	ret = stmpe->ci->write_byte(stmpe, reg, val);
7162306a36Sopenharmony_ci	if (ret < 0)
7262306a36Sopenharmony_ci		dev_err(stmpe->dev, "failed to write reg %#x: %d\n", reg, ret);
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci	return ret;
7562306a36Sopenharmony_ci}
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_cistatic int __stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val)
7862306a36Sopenharmony_ci{
7962306a36Sopenharmony_ci	int ret;
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	ret = __stmpe_reg_read(stmpe, reg);
8262306a36Sopenharmony_ci	if (ret < 0)
8362306a36Sopenharmony_ci		return ret;
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	ret &= ~mask;
8662306a36Sopenharmony_ci	ret |= val;
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	return __stmpe_reg_write(stmpe, reg, ret);
8962306a36Sopenharmony_ci}
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_cistatic int __stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length,
9262306a36Sopenharmony_ci			      u8 *values)
9362306a36Sopenharmony_ci{
9462306a36Sopenharmony_ci	int ret;
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci	ret = stmpe->ci->read_block(stmpe, reg, length, values);
9762306a36Sopenharmony_ci	if (ret < 0)
9862306a36Sopenharmony_ci		dev_err(stmpe->dev, "failed to read regs %#x: %d\n", reg, ret);
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	dev_vdbg(stmpe->dev, "rd: reg %#x (%d) => ret %#x\n", reg, length, ret);
10162306a36Sopenharmony_ci	stmpe_dump_bytes("stmpe rd: ", values, length);
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	return ret;
10462306a36Sopenharmony_ci}
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_cistatic int __stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length,
10762306a36Sopenharmony_ci			const u8 *values)
10862306a36Sopenharmony_ci{
10962306a36Sopenharmony_ci	int ret;
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	dev_vdbg(stmpe->dev, "wr: regs %#x (%d)\n", reg, length);
11262306a36Sopenharmony_ci	stmpe_dump_bytes("stmpe wr: ", values, length);
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci	ret = stmpe->ci->write_block(stmpe, reg, length, values);
11562306a36Sopenharmony_ci	if (ret < 0)
11662306a36Sopenharmony_ci		dev_err(stmpe->dev, "failed to write regs %#x: %d\n", reg, ret);
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	return ret;
11962306a36Sopenharmony_ci}
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci/**
12262306a36Sopenharmony_ci * stmpe_enable - enable blocks on an STMPE device
12362306a36Sopenharmony_ci * @stmpe:	Device to work on
12462306a36Sopenharmony_ci * @blocks:	Mask of blocks (enum stmpe_block values) to enable
12562306a36Sopenharmony_ci */
12662306a36Sopenharmony_ciint stmpe_enable(struct stmpe *stmpe, unsigned int blocks)
12762306a36Sopenharmony_ci{
12862306a36Sopenharmony_ci	int ret;
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	mutex_lock(&stmpe->lock);
13162306a36Sopenharmony_ci	ret = __stmpe_enable(stmpe, blocks);
13262306a36Sopenharmony_ci	mutex_unlock(&stmpe->lock);
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci	return ret;
13562306a36Sopenharmony_ci}
13662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(stmpe_enable);
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci/**
13962306a36Sopenharmony_ci * stmpe_disable - disable blocks on an STMPE device
14062306a36Sopenharmony_ci * @stmpe:	Device to work on
14162306a36Sopenharmony_ci * @blocks:	Mask of blocks (enum stmpe_block values) to enable
14262306a36Sopenharmony_ci */
14362306a36Sopenharmony_ciint stmpe_disable(struct stmpe *stmpe, unsigned int blocks)
14462306a36Sopenharmony_ci{
14562306a36Sopenharmony_ci	int ret;
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci	mutex_lock(&stmpe->lock);
14862306a36Sopenharmony_ci	ret = __stmpe_disable(stmpe, blocks);
14962306a36Sopenharmony_ci	mutex_unlock(&stmpe->lock);
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci	return ret;
15262306a36Sopenharmony_ci}
15362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(stmpe_disable);
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci/**
15662306a36Sopenharmony_ci * stmpe_reg_read() - read a single STMPE register
15762306a36Sopenharmony_ci * @stmpe:	Device to read from
15862306a36Sopenharmony_ci * @reg:	Register to read
15962306a36Sopenharmony_ci */
16062306a36Sopenharmony_ciint stmpe_reg_read(struct stmpe *stmpe, u8 reg)
16162306a36Sopenharmony_ci{
16262306a36Sopenharmony_ci	int ret;
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci	mutex_lock(&stmpe->lock);
16562306a36Sopenharmony_ci	ret = __stmpe_reg_read(stmpe, reg);
16662306a36Sopenharmony_ci	mutex_unlock(&stmpe->lock);
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci	return ret;
16962306a36Sopenharmony_ci}
17062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(stmpe_reg_read);
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci/**
17362306a36Sopenharmony_ci * stmpe_reg_write() - write a single STMPE register
17462306a36Sopenharmony_ci * @stmpe:	Device to write to
17562306a36Sopenharmony_ci * @reg:	Register to write
17662306a36Sopenharmony_ci * @val:	Value to write
17762306a36Sopenharmony_ci */
17862306a36Sopenharmony_ciint stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val)
17962306a36Sopenharmony_ci{
18062306a36Sopenharmony_ci	int ret;
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci	mutex_lock(&stmpe->lock);
18362306a36Sopenharmony_ci	ret = __stmpe_reg_write(stmpe, reg, val);
18462306a36Sopenharmony_ci	mutex_unlock(&stmpe->lock);
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci	return ret;
18762306a36Sopenharmony_ci}
18862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(stmpe_reg_write);
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci/**
19162306a36Sopenharmony_ci * stmpe_set_bits() - set the value of a bitfield in a STMPE register
19262306a36Sopenharmony_ci * @stmpe:	Device to write to
19362306a36Sopenharmony_ci * @reg:	Register to write
19462306a36Sopenharmony_ci * @mask:	Mask of bits to set
19562306a36Sopenharmony_ci * @val:	Value to set
19662306a36Sopenharmony_ci */
19762306a36Sopenharmony_ciint stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val)
19862306a36Sopenharmony_ci{
19962306a36Sopenharmony_ci	int ret;
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci	mutex_lock(&stmpe->lock);
20262306a36Sopenharmony_ci	ret = __stmpe_set_bits(stmpe, reg, mask, val);
20362306a36Sopenharmony_ci	mutex_unlock(&stmpe->lock);
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci	return ret;
20662306a36Sopenharmony_ci}
20762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(stmpe_set_bits);
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci/**
21062306a36Sopenharmony_ci * stmpe_block_read() - read multiple STMPE registers
21162306a36Sopenharmony_ci * @stmpe:	Device to read from
21262306a36Sopenharmony_ci * @reg:	First register
21362306a36Sopenharmony_ci * @length:	Number of registers
21462306a36Sopenharmony_ci * @values:	Buffer to write to
21562306a36Sopenharmony_ci */
21662306a36Sopenharmony_ciint stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values)
21762306a36Sopenharmony_ci{
21862306a36Sopenharmony_ci	int ret;
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	mutex_lock(&stmpe->lock);
22162306a36Sopenharmony_ci	ret = __stmpe_block_read(stmpe, reg, length, values);
22262306a36Sopenharmony_ci	mutex_unlock(&stmpe->lock);
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	return ret;
22562306a36Sopenharmony_ci}
22662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(stmpe_block_read);
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci/**
22962306a36Sopenharmony_ci * stmpe_block_write() - write multiple STMPE registers
23062306a36Sopenharmony_ci * @stmpe:	Device to write to
23162306a36Sopenharmony_ci * @reg:	First register
23262306a36Sopenharmony_ci * @length:	Number of registers
23362306a36Sopenharmony_ci * @values:	Values to write
23462306a36Sopenharmony_ci */
23562306a36Sopenharmony_ciint stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length,
23662306a36Sopenharmony_ci		      const u8 *values)
23762306a36Sopenharmony_ci{
23862306a36Sopenharmony_ci	int ret;
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	mutex_lock(&stmpe->lock);
24162306a36Sopenharmony_ci	ret = __stmpe_block_write(stmpe, reg, length, values);
24262306a36Sopenharmony_ci	mutex_unlock(&stmpe->lock);
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci	return ret;
24562306a36Sopenharmony_ci}
24662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(stmpe_block_write);
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci/**
24962306a36Sopenharmony_ci * stmpe_set_altfunc()- set the alternate function for STMPE pins
25062306a36Sopenharmony_ci * @stmpe:	Device to configure
25162306a36Sopenharmony_ci * @pins:	Bitmask of pins to affect
25262306a36Sopenharmony_ci * @block:	block to enable alternate functions for
25362306a36Sopenharmony_ci *
25462306a36Sopenharmony_ci * @pins is assumed to have a bit set for each of the bits whose alternate
25562306a36Sopenharmony_ci * function is to be changed, numbered according to the GPIOXY numbers.
25662306a36Sopenharmony_ci *
25762306a36Sopenharmony_ci * If the GPIO module is not enabled, this function automatically enables it in
25862306a36Sopenharmony_ci * order to perform the change.
25962306a36Sopenharmony_ci */
26062306a36Sopenharmony_ciint stmpe_set_altfunc(struct stmpe *stmpe, u32 pins, enum stmpe_block block)
26162306a36Sopenharmony_ci{
26262306a36Sopenharmony_ci	struct stmpe_variant_info *variant = stmpe->variant;
26362306a36Sopenharmony_ci	u8 regaddr = stmpe->regs[STMPE_IDX_GPAFR_U_MSB];
26462306a36Sopenharmony_ci	int af_bits = variant->af_bits;
26562306a36Sopenharmony_ci	int numregs = DIV_ROUND_UP(stmpe->num_gpios * af_bits, 8);
26662306a36Sopenharmony_ci	int mask = (1 << af_bits) - 1;
26762306a36Sopenharmony_ci	u8 regs[8];
26862306a36Sopenharmony_ci	int af, afperreg, ret;
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci	if (!variant->get_altfunc)
27162306a36Sopenharmony_ci		return 0;
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci	afperreg = 8 / af_bits;
27462306a36Sopenharmony_ci	mutex_lock(&stmpe->lock);
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci	ret = __stmpe_enable(stmpe, STMPE_BLOCK_GPIO);
27762306a36Sopenharmony_ci	if (ret < 0)
27862306a36Sopenharmony_ci		goto out;
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci	ret = __stmpe_block_read(stmpe, regaddr, numregs, regs);
28162306a36Sopenharmony_ci	if (ret < 0)
28262306a36Sopenharmony_ci		goto out;
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci	af = variant->get_altfunc(stmpe, block);
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	while (pins) {
28762306a36Sopenharmony_ci		int pin = __ffs(pins);
28862306a36Sopenharmony_ci		int regoffset = numregs - (pin / afperreg) - 1;
28962306a36Sopenharmony_ci		int pos = (pin % afperreg) * (8 / afperreg);
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci		regs[regoffset] &= ~(mask << pos);
29262306a36Sopenharmony_ci		regs[regoffset] |= af << pos;
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci		pins &= ~(1 << pin);
29562306a36Sopenharmony_ci	}
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	ret = __stmpe_block_write(stmpe, regaddr, numregs, regs);
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ciout:
30062306a36Sopenharmony_ci	mutex_unlock(&stmpe->lock);
30162306a36Sopenharmony_ci	return ret;
30262306a36Sopenharmony_ci}
30362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(stmpe_set_altfunc);
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci/*
30662306a36Sopenharmony_ci * GPIO (all variants)
30762306a36Sopenharmony_ci */
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_cistatic struct resource stmpe_gpio_resources[] = {
31062306a36Sopenharmony_ci	/* Start and end filled dynamically */
31162306a36Sopenharmony_ci	{
31262306a36Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
31362306a36Sopenharmony_ci	},
31462306a36Sopenharmony_ci};
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_cistatic const struct mfd_cell stmpe_gpio_cell = {
31762306a36Sopenharmony_ci	.name		= "stmpe-gpio",
31862306a36Sopenharmony_ci	.of_compatible	= "st,stmpe-gpio",
31962306a36Sopenharmony_ci	.resources	= stmpe_gpio_resources,
32062306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(stmpe_gpio_resources),
32162306a36Sopenharmony_ci};
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_cistatic const struct mfd_cell stmpe_gpio_cell_noirq = {
32462306a36Sopenharmony_ci	.name		= "stmpe-gpio",
32562306a36Sopenharmony_ci	.of_compatible	= "st,stmpe-gpio",
32662306a36Sopenharmony_ci	/* gpio cell resources consist of an irq only so no resources here */
32762306a36Sopenharmony_ci};
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci/*
33062306a36Sopenharmony_ci * Keypad (1601, 2401, 2403)
33162306a36Sopenharmony_ci */
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_cistatic struct resource stmpe_keypad_resources[] = {
33462306a36Sopenharmony_ci	/* Start and end filled dynamically */
33562306a36Sopenharmony_ci	{
33662306a36Sopenharmony_ci		.name	= "KEYPAD",
33762306a36Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
33862306a36Sopenharmony_ci	},
33962306a36Sopenharmony_ci	{
34062306a36Sopenharmony_ci		.name	= "KEYPAD_OVER",
34162306a36Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
34262306a36Sopenharmony_ci	},
34362306a36Sopenharmony_ci};
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_cistatic const struct mfd_cell stmpe_keypad_cell = {
34662306a36Sopenharmony_ci	.name		= "stmpe-keypad",
34762306a36Sopenharmony_ci	.of_compatible  = "st,stmpe-keypad",
34862306a36Sopenharmony_ci	.resources	= stmpe_keypad_resources,
34962306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(stmpe_keypad_resources),
35062306a36Sopenharmony_ci};
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci/*
35362306a36Sopenharmony_ci * PWM (1601, 2401, 2403)
35462306a36Sopenharmony_ci */
35562306a36Sopenharmony_cistatic struct resource stmpe_pwm_resources[] = {
35662306a36Sopenharmony_ci	/* Start and end filled dynamically */
35762306a36Sopenharmony_ci	{
35862306a36Sopenharmony_ci		.name	= "PWM0",
35962306a36Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
36062306a36Sopenharmony_ci	},
36162306a36Sopenharmony_ci	{
36262306a36Sopenharmony_ci		.name	= "PWM1",
36362306a36Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
36462306a36Sopenharmony_ci	},
36562306a36Sopenharmony_ci	{
36662306a36Sopenharmony_ci		.name	= "PWM2",
36762306a36Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
36862306a36Sopenharmony_ci	},
36962306a36Sopenharmony_ci};
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_cistatic const struct mfd_cell stmpe_pwm_cell = {
37262306a36Sopenharmony_ci	.name		= "stmpe-pwm",
37362306a36Sopenharmony_ci	.of_compatible  = "st,stmpe-pwm",
37462306a36Sopenharmony_ci	.resources	= stmpe_pwm_resources,
37562306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(stmpe_pwm_resources),
37662306a36Sopenharmony_ci};
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci/*
37962306a36Sopenharmony_ci * STMPE801
38062306a36Sopenharmony_ci */
38162306a36Sopenharmony_cistatic const u8 stmpe801_regs[] = {
38262306a36Sopenharmony_ci	[STMPE_IDX_CHIP_ID]	= STMPE801_REG_CHIP_ID,
38362306a36Sopenharmony_ci	[STMPE_IDX_ICR_LSB]	= STMPE801_REG_SYS_CTRL,
38462306a36Sopenharmony_ci	[STMPE_IDX_GPMR_LSB]	= STMPE801_REG_GPIO_MP_STA,
38562306a36Sopenharmony_ci	[STMPE_IDX_GPSR_LSB]	= STMPE801_REG_GPIO_SET_PIN,
38662306a36Sopenharmony_ci	[STMPE_IDX_GPCR_LSB]	= STMPE801_REG_GPIO_SET_PIN,
38762306a36Sopenharmony_ci	[STMPE_IDX_GPDR_LSB]	= STMPE801_REG_GPIO_DIR,
38862306a36Sopenharmony_ci	[STMPE_IDX_IEGPIOR_LSB] = STMPE801_REG_GPIO_INT_EN,
38962306a36Sopenharmony_ci	[STMPE_IDX_ISGPIOR_MSB] = STMPE801_REG_GPIO_INT_STA,
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_ci};
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_cistatic struct stmpe_variant_block stmpe801_blocks[] = {
39462306a36Sopenharmony_ci	{
39562306a36Sopenharmony_ci		.cell	= &stmpe_gpio_cell,
39662306a36Sopenharmony_ci		.irq	= 0,
39762306a36Sopenharmony_ci		.block	= STMPE_BLOCK_GPIO,
39862306a36Sopenharmony_ci	},
39962306a36Sopenharmony_ci};
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_cistatic struct stmpe_variant_block stmpe801_blocks_noirq[] = {
40262306a36Sopenharmony_ci	{
40362306a36Sopenharmony_ci		.cell	= &stmpe_gpio_cell_noirq,
40462306a36Sopenharmony_ci		.block	= STMPE_BLOCK_GPIO,
40562306a36Sopenharmony_ci	},
40662306a36Sopenharmony_ci};
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_cistatic int stmpe801_enable(struct stmpe *stmpe, unsigned int blocks,
40962306a36Sopenharmony_ci			   bool enable)
41062306a36Sopenharmony_ci{
41162306a36Sopenharmony_ci	if (blocks & STMPE_BLOCK_GPIO)
41262306a36Sopenharmony_ci		return 0;
41362306a36Sopenharmony_ci	else
41462306a36Sopenharmony_ci		return -EINVAL;
41562306a36Sopenharmony_ci}
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_cistatic struct stmpe_variant_info stmpe801 = {
41862306a36Sopenharmony_ci	.name		= "stmpe801",
41962306a36Sopenharmony_ci	.id_val		= STMPE801_ID,
42062306a36Sopenharmony_ci	.id_mask	= 0xffff,
42162306a36Sopenharmony_ci	.num_gpios	= 8,
42262306a36Sopenharmony_ci	.regs		= stmpe801_regs,
42362306a36Sopenharmony_ci	.blocks		= stmpe801_blocks,
42462306a36Sopenharmony_ci	.num_blocks	= ARRAY_SIZE(stmpe801_blocks),
42562306a36Sopenharmony_ci	.num_irqs	= STMPE801_NR_INTERNAL_IRQS,
42662306a36Sopenharmony_ci	.enable		= stmpe801_enable,
42762306a36Sopenharmony_ci};
42862306a36Sopenharmony_ci
42962306a36Sopenharmony_cistatic struct stmpe_variant_info stmpe801_noirq = {
43062306a36Sopenharmony_ci	.name		= "stmpe801",
43162306a36Sopenharmony_ci	.id_val		= STMPE801_ID,
43262306a36Sopenharmony_ci	.id_mask	= 0xffff,
43362306a36Sopenharmony_ci	.num_gpios	= 8,
43462306a36Sopenharmony_ci	.regs		= stmpe801_regs,
43562306a36Sopenharmony_ci	.blocks		= stmpe801_blocks_noirq,
43662306a36Sopenharmony_ci	.num_blocks	= ARRAY_SIZE(stmpe801_blocks_noirq),
43762306a36Sopenharmony_ci	.enable		= stmpe801_enable,
43862306a36Sopenharmony_ci};
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci/*
44162306a36Sopenharmony_ci * Touchscreen (STMPE811 or STMPE610)
44262306a36Sopenharmony_ci */
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_cistatic struct resource stmpe_ts_resources[] = {
44562306a36Sopenharmony_ci	/* Start and end filled dynamically */
44662306a36Sopenharmony_ci	{
44762306a36Sopenharmony_ci		.name	= "TOUCH_DET",
44862306a36Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
44962306a36Sopenharmony_ci	},
45062306a36Sopenharmony_ci	{
45162306a36Sopenharmony_ci		.name	= "FIFO_TH",
45262306a36Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
45362306a36Sopenharmony_ci	},
45462306a36Sopenharmony_ci};
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_cistatic const struct mfd_cell stmpe_ts_cell = {
45762306a36Sopenharmony_ci	.name		= "stmpe-ts",
45862306a36Sopenharmony_ci	.of_compatible	= "st,stmpe-ts",
45962306a36Sopenharmony_ci	.resources	= stmpe_ts_resources,
46062306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(stmpe_ts_resources),
46162306a36Sopenharmony_ci};
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_ci/*
46462306a36Sopenharmony_ci * ADC (STMPE811)
46562306a36Sopenharmony_ci */
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_cistatic struct resource stmpe_adc_resources[] = {
46862306a36Sopenharmony_ci	/* Start and end filled dynamically */
46962306a36Sopenharmony_ci	{
47062306a36Sopenharmony_ci		.name	= "STMPE_TEMP_SENS",
47162306a36Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
47262306a36Sopenharmony_ci	},
47362306a36Sopenharmony_ci	{
47462306a36Sopenharmony_ci		.name	= "STMPE_ADC",
47562306a36Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
47662306a36Sopenharmony_ci	},
47762306a36Sopenharmony_ci};
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_cistatic const struct mfd_cell stmpe_adc_cell = {
48062306a36Sopenharmony_ci	.name		= "stmpe-adc",
48162306a36Sopenharmony_ci	.of_compatible	= "st,stmpe-adc",
48262306a36Sopenharmony_ci	.resources	= stmpe_adc_resources,
48362306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(stmpe_adc_resources),
48462306a36Sopenharmony_ci};
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci/*
48762306a36Sopenharmony_ci * STMPE811 or STMPE610
48862306a36Sopenharmony_ci */
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_cistatic const u8 stmpe811_regs[] = {
49162306a36Sopenharmony_ci	[STMPE_IDX_CHIP_ID]	= STMPE811_REG_CHIP_ID,
49262306a36Sopenharmony_ci	[STMPE_IDX_SYS_CTRL]	= STMPE811_REG_SYS_CTRL,
49362306a36Sopenharmony_ci	[STMPE_IDX_SYS_CTRL2]	= STMPE811_REG_SYS_CTRL2,
49462306a36Sopenharmony_ci	[STMPE_IDX_ICR_LSB]	= STMPE811_REG_INT_CTRL,
49562306a36Sopenharmony_ci	[STMPE_IDX_IER_LSB]	= STMPE811_REG_INT_EN,
49662306a36Sopenharmony_ci	[STMPE_IDX_ISR_MSB]	= STMPE811_REG_INT_STA,
49762306a36Sopenharmony_ci	[STMPE_IDX_GPMR_LSB]	= STMPE811_REG_GPIO_MP_STA,
49862306a36Sopenharmony_ci	[STMPE_IDX_GPSR_LSB]	= STMPE811_REG_GPIO_SET_PIN,
49962306a36Sopenharmony_ci	[STMPE_IDX_GPCR_LSB]	= STMPE811_REG_GPIO_CLR_PIN,
50062306a36Sopenharmony_ci	[STMPE_IDX_GPDR_LSB]	= STMPE811_REG_GPIO_DIR,
50162306a36Sopenharmony_ci	[STMPE_IDX_GPRER_LSB]	= STMPE811_REG_GPIO_RE,
50262306a36Sopenharmony_ci	[STMPE_IDX_GPFER_LSB]	= STMPE811_REG_GPIO_FE,
50362306a36Sopenharmony_ci	[STMPE_IDX_GPAFR_U_MSB]	= STMPE811_REG_GPIO_AF,
50462306a36Sopenharmony_ci	[STMPE_IDX_IEGPIOR_LSB]	= STMPE811_REG_GPIO_INT_EN,
50562306a36Sopenharmony_ci	[STMPE_IDX_ISGPIOR_MSB]	= STMPE811_REG_GPIO_INT_STA,
50662306a36Sopenharmony_ci	[STMPE_IDX_GPEDR_LSB]	= STMPE811_REG_GPIO_ED,
50762306a36Sopenharmony_ci};
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_cistatic struct stmpe_variant_block stmpe811_blocks[] = {
51062306a36Sopenharmony_ci	{
51162306a36Sopenharmony_ci		.cell	= &stmpe_gpio_cell,
51262306a36Sopenharmony_ci		.irq	= STMPE811_IRQ_GPIOC,
51362306a36Sopenharmony_ci		.block	= STMPE_BLOCK_GPIO,
51462306a36Sopenharmony_ci	},
51562306a36Sopenharmony_ci	{
51662306a36Sopenharmony_ci		.cell	= &stmpe_ts_cell,
51762306a36Sopenharmony_ci		.irq	= STMPE811_IRQ_TOUCH_DET,
51862306a36Sopenharmony_ci		.block	= STMPE_BLOCK_TOUCHSCREEN,
51962306a36Sopenharmony_ci	},
52062306a36Sopenharmony_ci	{
52162306a36Sopenharmony_ci		.cell	= &stmpe_adc_cell,
52262306a36Sopenharmony_ci		.irq	= STMPE811_IRQ_TEMP_SENS,
52362306a36Sopenharmony_ci		.block	= STMPE_BLOCK_ADC,
52462306a36Sopenharmony_ci	},
52562306a36Sopenharmony_ci};
52662306a36Sopenharmony_ci
52762306a36Sopenharmony_cistatic int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks,
52862306a36Sopenharmony_ci			   bool enable)
52962306a36Sopenharmony_ci{
53062306a36Sopenharmony_ci	unsigned int mask = 0;
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_ci	if (blocks & STMPE_BLOCK_GPIO)
53362306a36Sopenharmony_ci		mask |= STMPE811_SYS_CTRL2_GPIO_OFF;
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci	if (blocks & STMPE_BLOCK_ADC)
53662306a36Sopenharmony_ci		mask |= STMPE811_SYS_CTRL2_ADC_OFF;
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_ci	if (blocks & STMPE_BLOCK_TOUCHSCREEN)
53962306a36Sopenharmony_ci		mask |= STMPE811_SYS_CTRL2_TSC_OFF;
54062306a36Sopenharmony_ci
54162306a36Sopenharmony_ci	return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2], mask,
54262306a36Sopenharmony_ci				enable ? 0 : mask);
54362306a36Sopenharmony_ci}
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ciint stmpe811_adc_common_init(struct stmpe *stmpe)
54662306a36Sopenharmony_ci{
54762306a36Sopenharmony_ci	int ret;
54862306a36Sopenharmony_ci	u8 adc_ctrl1, adc_ctrl1_mask;
54962306a36Sopenharmony_ci
55062306a36Sopenharmony_ci	adc_ctrl1 = STMPE_SAMPLE_TIME(stmpe->sample_time) |
55162306a36Sopenharmony_ci		    STMPE_MOD_12B(stmpe->mod_12b) |
55262306a36Sopenharmony_ci		    STMPE_REF_SEL(stmpe->ref_sel);
55362306a36Sopenharmony_ci	adc_ctrl1_mask = STMPE_SAMPLE_TIME(0xff) | STMPE_MOD_12B(0xff) |
55462306a36Sopenharmony_ci			 STMPE_REF_SEL(0xff);
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_ci	ret = stmpe_set_bits(stmpe, STMPE811_REG_ADC_CTRL1,
55762306a36Sopenharmony_ci			adc_ctrl1_mask, adc_ctrl1);
55862306a36Sopenharmony_ci	if (ret) {
55962306a36Sopenharmony_ci		dev_err(stmpe->dev, "Could not setup ADC\n");
56062306a36Sopenharmony_ci		return ret;
56162306a36Sopenharmony_ci	}
56262306a36Sopenharmony_ci
56362306a36Sopenharmony_ci	ret = stmpe_set_bits(stmpe, STMPE811_REG_ADC_CTRL2,
56462306a36Sopenharmony_ci			STMPE_ADC_FREQ(0xff), STMPE_ADC_FREQ(stmpe->adc_freq));
56562306a36Sopenharmony_ci	if (ret) {
56662306a36Sopenharmony_ci		dev_err(stmpe->dev, "Could not setup ADC\n");
56762306a36Sopenharmony_ci		return ret;
56862306a36Sopenharmony_ci	}
56962306a36Sopenharmony_ci
57062306a36Sopenharmony_ci	return 0;
57162306a36Sopenharmony_ci}
57262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(stmpe811_adc_common_init);
57362306a36Sopenharmony_ci
57462306a36Sopenharmony_cistatic int stmpe811_get_altfunc(struct stmpe *stmpe, enum stmpe_block block)
57562306a36Sopenharmony_ci{
57662306a36Sopenharmony_ci	/* 0 for touchscreen, 1 for GPIO */
57762306a36Sopenharmony_ci	return block != STMPE_BLOCK_TOUCHSCREEN;
57862306a36Sopenharmony_ci}
57962306a36Sopenharmony_ci
58062306a36Sopenharmony_cistatic struct stmpe_variant_info stmpe811 = {
58162306a36Sopenharmony_ci	.name		= "stmpe811",
58262306a36Sopenharmony_ci	.id_val		= 0x0811,
58362306a36Sopenharmony_ci	.id_mask	= 0xffff,
58462306a36Sopenharmony_ci	.num_gpios	= 8,
58562306a36Sopenharmony_ci	.af_bits	= 1,
58662306a36Sopenharmony_ci	.regs		= stmpe811_regs,
58762306a36Sopenharmony_ci	.blocks		= stmpe811_blocks,
58862306a36Sopenharmony_ci	.num_blocks	= ARRAY_SIZE(stmpe811_blocks),
58962306a36Sopenharmony_ci	.num_irqs	= STMPE811_NR_INTERNAL_IRQS,
59062306a36Sopenharmony_ci	.enable		= stmpe811_enable,
59162306a36Sopenharmony_ci	.get_altfunc	= stmpe811_get_altfunc,
59262306a36Sopenharmony_ci};
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_ci/* Similar to 811, except number of gpios */
59562306a36Sopenharmony_cistatic struct stmpe_variant_info stmpe610 = {
59662306a36Sopenharmony_ci	.name		= "stmpe610",
59762306a36Sopenharmony_ci	.id_val		= 0x0811,
59862306a36Sopenharmony_ci	.id_mask	= 0xffff,
59962306a36Sopenharmony_ci	.num_gpios	= 6,
60062306a36Sopenharmony_ci	.af_bits	= 1,
60162306a36Sopenharmony_ci	.regs		= stmpe811_regs,
60262306a36Sopenharmony_ci	.blocks		= stmpe811_blocks,
60362306a36Sopenharmony_ci	.num_blocks	= ARRAY_SIZE(stmpe811_blocks),
60462306a36Sopenharmony_ci	.num_irqs	= STMPE811_NR_INTERNAL_IRQS,
60562306a36Sopenharmony_ci	.enable		= stmpe811_enable,
60662306a36Sopenharmony_ci	.get_altfunc	= stmpe811_get_altfunc,
60762306a36Sopenharmony_ci};
60862306a36Sopenharmony_ci
60962306a36Sopenharmony_ci/*
61062306a36Sopenharmony_ci * STMPE1600
61162306a36Sopenharmony_ci * Compared to all others STMPE variant, LSB and MSB regs are located in this
61262306a36Sopenharmony_ci * order :	LSB   addr
61362306a36Sopenharmony_ci *		MSB   addr + 1
61462306a36Sopenharmony_ci * As there is only 2 * 8bits registers for GPMR/GPSR/IEGPIOPR, CSB index is MSB registers
61562306a36Sopenharmony_ci */
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_cistatic const u8 stmpe1600_regs[] = {
61862306a36Sopenharmony_ci	[STMPE_IDX_CHIP_ID]	= STMPE1600_REG_CHIP_ID,
61962306a36Sopenharmony_ci	[STMPE_IDX_SYS_CTRL]	= STMPE1600_REG_SYS_CTRL,
62062306a36Sopenharmony_ci	[STMPE_IDX_ICR_LSB]	= STMPE1600_REG_SYS_CTRL,
62162306a36Sopenharmony_ci	[STMPE_IDX_GPMR_LSB]	= STMPE1600_REG_GPMR_LSB,
62262306a36Sopenharmony_ci	[STMPE_IDX_GPMR_CSB]	= STMPE1600_REG_GPMR_MSB,
62362306a36Sopenharmony_ci	[STMPE_IDX_GPSR_LSB]	= STMPE1600_REG_GPSR_LSB,
62462306a36Sopenharmony_ci	[STMPE_IDX_GPSR_CSB]	= STMPE1600_REG_GPSR_MSB,
62562306a36Sopenharmony_ci	[STMPE_IDX_GPCR_LSB]	= STMPE1600_REG_GPSR_LSB,
62662306a36Sopenharmony_ci	[STMPE_IDX_GPCR_CSB]	= STMPE1600_REG_GPSR_MSB,
62762306a36Sopenharmony_ci	[STMPE_IDX_GPDR_LSB]	= STMPE1600_REG_GPDR_LSB,
62862306a36Sopenharmony_ci	[STMPE_IDX_GPDR_CSB]	= STMPE1600_REG_GPDR_MSB,
62962306a36Sopenharmony_ci	[STMPE_IDX_IEGPIOR_LSB]	= STMPE1600_REG_IEGPIOR_LSB,
63062306a36Sopenharmony_ci	[STMPE_IDX_IEGPIOR_CSB]	= STMPE1600_REG_IEGPIOR_MSB,
63162306a36Sopenharmony_ci	[STMPE_IDX_ISGPIOR_LSB]	= STMPE1600_REG_ISGPIOR_LSB,
63262306a36Sopenharmony_ci};
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_cistatic struct stmpe_variant_block stmpe1600_blocks[] = {
63562306a36Sopenharmony_ci	{
63662306a36Sopenharmony_ci		.cell	= &stmpe_gpio_cell,
63762306a36Sopenharmony_ci		.irq	= 0,
63862306a36Sopenharmony_ci		.block	= STMPE_BLOCK_GPIO,
63962306a36Sopenharmony_ci	},
64062306a36Sopenharmony_ci};
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_cistatic int stmpe1600_enable(struct stmpe *stmpe, unsigned int blocks,
64362306a36Sopenharmony_ci			   bool enable)
64462306a36Sopenharmony_ci{
64562306a36Sopenharmony_ci	if (blocks & STMPE_BLOCK_GPIO)
64662306a36Sopenharmony_ci		return 0;
64762306a36Sopenharmony_ci	else
64862306a36Sopenharmony_ci		return -EINVAL;
64962306a36Sopenharmony_ci}
65062306a36Sopenharmony_ci
65162306a36Sopenharmony_cistatic struct stmpe_variant_info stmpe1600 = {
65262306a36Sopenharmony_ci	.name		= "stmpe1600",
65362306a36Sopenharmony_ci	.id_val		= STMPE1600_ID,
65462306a36Sopenharmony_ci	.id_mask	= 0xffff,
65562306a36Sopenharmony_ci	.num_gpios	= 16,
65662306a36Sopenharmony_ci	.af_bits	= 0,
65762306a36Sopenharmony_ci	.regs		= stmpe1600_regs,
65862306a36Sopenharmony_ci	.blocks		= stmpe1600_blocks,
65962306a36Sopenharmony_ci	.num_blocks	= ARRAY_SIZE(stmpe1600_blocks),
66062306a36Sopenharmony_ci	.num_irqs	= STMPE1600_NR_INTERNAL_IRQS,
66162306a36Sopenharmony_ci	.enable		= stmpe1600_enable,
66262306a36Sopenharmony_ci};
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_ci/*
66562306a36Sopenharmony_ci * STMPE1601
66662306a36Sopenharmony_ci */
66762306a36Sopenharmony_ci
66862306a36Sopenharmony_cistatic const u8 stmpe1601_regs[] = {
66962306a36Sopenharmony_ci	[STMPE_IDX_CHIP_ID]	= STMPE1601_REG_CHIP_ID,
67062306a36Sopenharmony_ci	[STMPE_IDX_SYS_CTRL]	= STMPE1601_REG_SYS_CTRL,
67162306a36Sopenharmony_ci	[STMPE_IDX_SYS_CTRL2]	= STMPE1601_REG_SYS_CTRL2,
67262306a36Sopenharmony_ci	[STMPE_IDX_ICR_LSB]	= STMPE1601_REG_ICR_LSB,
67362306a36Sopenharmony_ci	[STMPE_IDX_IER_MSB]	= STMPE1601_REG_IER_MSB,
67462306a36Sopenharmony_ci	[STMPE_IDX_IER_LSB]	= STMPE1601_REG_IER_LSB,
67562306a36Sopenharmony_ci	[STMPE_IDX_ISR_MSB]	= STMPE1601_REG_ISR_MSB,
67662306a36Sopenharmony_ci	[STMPE_IDX_GPMR_LSB]	= STMPE1601_REG_GPIO_MP_LSB,
67762306a36Sopenharmony_ci	[STMPE_IDX_GPMR_CSB]	= STMPE1601_REG_GPIO_MP_MSB,
67862306a36Sopenharmony_ci	[STMPE_IDX_GPSR_LSB]	= STMPE1601_REG_GPIO_SET_LSB,
67962306a36Sopenharmony_ci	[STMPE_IDX_GPSR_CSB]	= STMPE1601_REG_GPIO_SET_MSB,
68062306a36Sopenharmony_ci	[STMPE_IDX_GPCR_LSB]	= STMPE1601_REG_GPIO_CLR_LSB,
68162306a36Sopenharmony_ci	[STMPE_IDX_GPCR_CSB]	= STMPE1601_REG_GPIO_CLR_MSB,
68262306a36Sopenharmony_ci	[STMPE_IDX_GPDR_LSB]	= STMPE1601_REG_GPIO_SET_DIR_LSB,
68362306a36Sopenharmony_ci	[STMPE_IDX_GPDR_CSB]	= STMPE1601_REG_GPIO_SET_DIR_MSB,
68462306a36Sopenharmony_ci	[STMPE_IDX_GPEDR_LSB]	= STMPE1601_REG_GPIO_ED_LSB,
68562306a36Sopenharmony_ci	[STMPE_IDX_GPEDR_CSB]	= STMPE1601_REG_GPIO_ED_MSB,
68662306a36Sopenharmony_ci	[STMPE_IDX_GPRER_LSB]	= STMPE1601_REG_GPIO_RE_LSB,
68762306a36Sopenharmony_ci	[STMPE_IDX_GPRER_CSB]	= STMPE1601_REG_GPIO_RE_MSB,
68862306a36Sopenharmony_ci	[STMPE_IDX_GPFER_LSB]	= STMPE1601_REG_GPIO_FE_LSB,
68962306a36Sopenharmony_ci	[STMPE_IDX_GPFER_CSB]	= STMPE1601_REG_GPIO_FE_MSB,
69062306a36Sopenharmony_ci	[STMPE_IDX_GPPUR_LSB]	= STMPE1601_REG_GPIO_PU_LSB,
69162306a36Sopenharmony_ci	[STMPE_IDX_GPAFR_U_MSB]	= STMPE1601_REG_GPIO_AF_U_MSB,
69262306a36Sopenharmony_ci	[STMPE_IDX_IEGPIOR_LSB]	= STMPE1601_REG_INT_EN_GPIO_MASK_LSB,
69362306a36Sopenharmony_ci	[STMPE_IDX_IEGPIOR_CSB]	= STMPE1601_REG_INT_EN_GPIO_MASK_MSB,
69462306a36Sopenharmony_ci	[STMPE_IDX_ISGPIOR_MSB]	= STMPE1601_REG_INT_STA_GPIO_MSB,
69562306a36Sopenharmony_ci};
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_cistatic struct stmpe_variant_block stmpe1601_blocks[] = {
69862306a36Sopenharmony_ci	{
69962306a36Sopenharmony_ci		.cell	= &stmpe_gpio_cell,
70062306a36Sopenharmony_ci		.irq	= STMPE1601_IRQ_GPIOC,
70162306a36Sopenharmony_ci		.block	= STMPE_BLOCK_GPIO,
70262306a36Sopenharmony_ci	},
70362306a36Sopenharmony_ci	{
70462306a36Sopenharmony_ci		.cell	= &stmpe_keypad_cell,
70562306a36Sopenharmony_ci		.irq	= STMPE1601_IRQ_KEYPAD,
70662306a36Sopenharmony_ci		.block	= STMPE_BLOCK_KEYPAD,
70762306a36Sopenharmony_ci	},
70862306a36Sopenharmony_ci	{
70962306a36Sopenharmony_ci		.cell	= &stmpe_pwm_cell,
71062306a36Sopenharmony_ci		.irq	= STMPE1601_IRQ_PWM0,
71162306a36Sopenharmony_ci		.block	= STMPE_BLOCK_PWM,
71262306a36Sopenharmony_ci	},
71362306a36Sopenharmony_ci};
71462306a36Sopenharmony_ci
71562306a36Sopenharmony_ci/* supported autosleep timeout delay (in msecs) */
71662306a36Sopenharmony_cistatic const int stmpe_autosleep_delay[] = {
71762306a36Sopenharmony_ci	4, 16, 32, 64, 128, 256, 512, 1024,
71862306a36Sopenharmony_ci};
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_cistatic int stmpe_round_timeout(int timeout)
72162306a36Sopenharmony_ci{
72262306a36Sopenharmony_ci	int i;
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(stmpe_autosleep_delay); i++) {
72562306a36Sopenharmony_ci		if (stmpe_autosleep_delay[i] >= timeout)
72662306a36Sopenharmony_ci			return i;
72762306a36Sopenharmony_ci	}
72862306a36Sopenharmony_ci
72962306a36Sopenharmony_ci	/*
73062306a36Sopenharmony_ci	 * requests for delays longer than supported should not return the
73162306a36Sopenharmony_ci	 * longest supported delay
73262306a36Sopenharmony_ci	 */
73362306a36Sopenharmony_ci	return -EINVAL;
73462306a36Sopenharmony_ci}
73562306a36Sopenharmony_ci
73662306a36Sopenharmony_cistatic int stmpe_autosleep(struct stmpe *stmpe, int autosleep_timeout)
73762306a36Sopenharmony_ci{
73862306a36Sopenharmony_ci	int ret;
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_ci	if (!stmpe->variant->enable_autosleep)
74162306a36Sopenharmony_ci		return -ENOSYS;
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_ci	mutex_lock(&stmpe->lock);
74462306a36Sopenharmony_ci	ret = stmpe->variant->enable_autosleep(stmpe, autosleep_timeout);
74562306a36Sopenharmony_ci	mutex_unlock(&stmpe->lock);
74662306a36Sopenharmony_ci
74762306a36Sopenharmony_ci	return ret;
74862306a36Sopenharmony_ci}
74962306a36Sopenharmony_ci
75062306a36Sopenharmony_ci/*
75162306a36Sopenharmony_ci * Both stmpe 1601/2403 support same layout for autosleep
75262306a36Sopenharmony_ci */
75362306a36Sopenharmony_cistatic int stmpe1601_autosleep(struct stmpe *stmpe,
75462306a36Sopenharmony_ci		int autosleep_timeout)
75562306a36Sopenharmony_ci{
75662306a36Sopenharmony_ci	int ret, timeout;
75762306a36Sopenharmony_ci
75862306a36Sopenharmony_ci	/* choose the best available timeout */
75962306a36Sopenharmony_ci	timeout = stmpe_round_timeout(autosleep_timeout);
76062306a36Sopenharmony_ci	if (timeout < 0) {
76162306a36Sopenharmony_ci		dev_err(stmpe->dev, "invalid timeout\n");
76262306a36Sopenharmony_ci		return timeout;
76362306a36Sopenharmony_ci	}
76462306a36Sopenharmony_ci
76562306a36Sopenharmony_ci	ret = __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2],
76662306a36Sopenharmony_ci			STMPE1601_AUTOSLEEP_TIMEOUT_MASK,
76762306a36Sopenharmony_ci			timeout);
76862306a36Sopenharmony_ci	if (ret < 0)
76962306a36Sopenharmony_ci		return ret;
77062306a36Sopenharmony_ci
77162306a36Sopenharmony_ci	return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2],
77262306a36Sopenharmony_ci			STPME1601_AUTOSLEEP_ENABLE,
77362306a36Sopenharmony_ci			STPME1601_AUTOSLEEP_ENABLE);
77462306a36Sopenharmony_ci}
77562306a36Sopenharmony_ci
77662306a36Sopenharmony_cistatic int stmpe1601_enable(struct stmpe *stmpe, unsigned int blocks,
77762306a36Sopenharmony_ci			    bool enable)
77862306a36Sopenharmony_ci{
77962306a36Sopenharmony_ci	unsigned int mask = 0;
78062306a36Sopenharmony_ci
78162306a36Sopenharmony_ci	if (blocks & STMPE_BLOCK_GPIO)
78262306a36Sopenharmony_ci		mask |= STMPE1601_SYS_CTRL_ENABLE_GPIO;
78362306a36Sopenharmony_ci	else
78462306a36Sopenharmony_ci		mask &= ~STMPE1601_SYS_CTRL_ENABLE_GPIO;
78562306a36Sopenharmony_ci
78662306a36Sopenharmony_ci	if (blocks & STMPE_BLOCK_KEYPAD)
78762306a36Sopenharmony_ci		mask |= STMPE1601_SYS_CTRL_ENABLE_KPC;
78862306a36Sopenharmony_ci	else
78962306a36Sopenharmony_ci		mask &= ~STMPE1601_SYS_CTRL_ENABLE_KPC;
79062306a36Sopenharmony_ci
79162306a36Sopenharmony_ci	if (blocks & STMPE_BLOCK_PWM)
79262306a36Sopenharmony_ci		mask |= STMPE1601_SYS_CTRL_ENABLE_SPWM;
79362306a36Sopenharmony_ci	else
79462306a36Sopenharmony_ci		mask &= ~STMPE1601_SYS_CTRL_ENABLE_SPWM;
79562306a36Sopenharmony_ci
79662306a36Sopenharmony_ci	return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], mask,
79762306a36Sopenharmony_ci				enable ? mask : 0);
79862306a36Sopenharmony_ci}
79962306a36Sopenharmony_ci
80062306a36Sopenharmony_cistatic int stmpe1601_get_altfunc(struct stmpe *stmpe, enum stmpe_block block)
80162306a36Sopenharmony_ci{
80262306a36Sopenharmony_ci	switch (block) {
80362306a36Sopenharmony_ci	case STMPE_BLOCK_PWM:
80462306a36Sopenharmony_ci		return 2;
80562306a36Sopenharmony_ci
80662306a36Sopenharmony_ci	case STMPE_BLOCK_KEYPAD:
80762306a36Sopenharmony_ci		return 1;
80862306a36Sopenharmony_ci
80962306a36Sopenharmony_ci	case STMPE_BLOCK_GPIO:
81062306a36Sopenharmony_ci	default:
81162306a36Sopenharmony_ci		return 0;
81262306a36Sopenharmony_ci	}
81362306a36Sopenharmony_ci}
81462306a36Sopenharmony_ci
81562306a36Sopenharmony_cistatic struct stmpe_variant_info stmpe1601 = {
81662306a36Sopenharmony_ci	.name		= "stmpe1601",
81762306a36Sopenharmony_ci	.id_val		= 0x0210,
81862306a36Sopenharmony_ci	.id_mask	= 0xfff0,	/* at least 0x0210 and 0x0212 */
81962306a36Sopenharmony_ci	.num_gpios	= 16,
82062306a36Sopenharmony_ci	.af_bits	= 2,
82162306a36Sopenharmony_ci	.regs		= stmpe1601_regs,
82262306a36Sopenharmony_ci	.blocks		= stmpe1601_blocks,
82362306a36Sopenharmony_ci	.num_blocks	= ARRAY_SIZE(stmpe1601_blocks),
82462306a36Sopenharmony_ci	.num_irqs	= STMPE1601_NR_INTERNAL_IRQS,
82562306a36Sopenharmony_ci	.enable		= stmpe1601_enable,
82662306a36Sopenharmony_ci	.get_altfunc	= stmpe1601_get_altfunc,
82762306a36Sopenharmony_ci	.enable_autosleep	= stmpe1601_autosleep,
82862306a36Sopenharmony_ci};
82962306a36Sopenharmony_ci
83062306a36Sopenharmony_ci/*
83162306a36Sopenharmony_ci * STMPE1801
83262306a36Sopenharmony_ci */
83362306a36Sopenharmony_cistatic const u8 stmpe1801_regs[] = {
83462306a36Sopenharmony_ci	[STMPE_IDX_CHIP_ID]	= STMPE1801_REG_CHIP_ID,
83562306a36Sopenharmony_ci	[STMPE_IDX_SYS_CTRL]	= STMPE1801_REG_SYS_CTRL,
83662306a36Sopenharmony_ci	[STMPE_IDX_ICR_LSB]	= STMPE1801_REG_INT_CTRL_LOW,
83762306a36Sopenharmony_ci	[STMPE_IDX_IER_LSB]	= STMPE1801_REG_INT_EN_MASK_LOW,
83862306a36Sopenharmony_ci	[STMPE_IDX_ISR_LSB]	= STMPE1801_REG_INT_STA_LOW,
83962306a36Sopenharmony_ci	[STMPE_IDX_GPMR_LSB]	= STMPE1801_REG_GPIO_MP_LOW,
84062306a36Sopenharmony_ci	[STMPE_IDX_GPMR_CSB]	= STMPE1801_REG_GPIO_MP_MID,
84162306a36Sopenharmony_ci	[STMPE_IDX_GPMR_MSB]	= STMPE1801_REG_GPIO_MP_HIGH,
84262306a36Sopenharmony_ci	[STMPE_IDX_GPSR_LSB]	= STMPE1801_REG_GPIO_SET_LOW,
84362306a36Sopenharmony_ci	[STMPE_IDX_GPSR_CSB]	= STMPE1801_REG_GPIO_SET_MID,
84462306a36Sopenharmony_ci	[STMPE_IDX_GPSR_MSB]	= STMPE1801_REG_GPIO_SET_HIGH,
84562306a36Sopenharmony_ci	[STMPE_IDX_GPCR_LSB]	= STMPE1801_REG_GPIO_CLR_LOW,
84662306a36Sopenharmony_ci	[STMPE_IDX_GPCR_CSB]	= STMPE1801_REG_GPIO_CLR_MID,
84762306a36Sopenharmony_ci	[STMPE_IDX_GPCR_MSB]	= STMPE1801_REG_GPIO_CLR_HIGH,
84862306a36Sopenharmony_ci	[STMPE_IDX_GPDR_LSB]	= STMPE1801_REG_GPIO_SET_DIR_LOW,
84962306a36Sopenharmony_ci	[STMPE_IDX_GPDR_CSB]	= STMPE1801_REG_GPIO_SET_DIR_MID,
85062306a36Sopenharmony_ci	[STMPE_IDX_GPDR_MSB]	= STMPE1801_REG_GPIO_SET_DIR_HIGH,
85162306a36Sopenharmony_ci	[STMPE_IDX_GPRER_LSB]	= STMPE1801_REG_GPIO_RE_LOW,
85262306a36Sopenharmony_ci	[STMPE_IDX_GPRER_CSB]	= STMPE1801_REG_GPIO_RE_MID,
85362306a36Sopenharmony_ci	[STMPE_IDX_GPRER_MSB]	= STMPE1801_REG_GPIO_RE_HIGH,
85462306a36Sopenharmony_ci	[STMPE_IDX_GPFER_LSB]	= STMPE1801_REG_GPIO_FE_LOW,
85562306a36Sopenharmony_ci	[STMPE_IDX_GPFER_CSB]	= STMPE1801_REG_GPIO_FE_MID,
85662306a36Sopenharmony_ci	[STMPE_IDX_GPFER_MSB]	= STMPE1801_REG_GPIO_FE_HIGH,
85762306a36Sopenharmony_ci	[STMPE_IDX_GPPUR_LSB]	= STMPE1801_REG_GPIO_PULL_UP_LOW,
85862306a36Sopenharmony_ci	[STMPE_IDX_IEGPIOR_LSB]	= STMPE1801_REG_INT_EN_GPIO_MASK_LOW,
85962306a36Sopenharmony_ci	[STMPE_IDX_IEGPIOR_CSB]	= STMPE1801_REG_INT_EN_GPIO_MASK_MID,
86062306a36Sopenharmony_ci	[STMPE_IDX_IEGPIOR_MSB]	= STMPE1801_REG_INT_EN_GPIO_MASK_HIGH,
86162306a36Sopenharmony_ci	[STMPE_IDX_ISGPIOR_MSB]	= STMPE1801_REG_INT_STA_GPIO_HIGH,
86262306a36Sopenharmony_ci};
86362306a36Sopenharmony_ci
86462306a36Sopenharmony_cistatic struct stmpe_variant_block stmpe1801_blocks[] = {
86562306a36Sopenharmony_ci	{
86662306a36Sopenharmony_ci		.cell	= &stmpe_gpio_cell,
86762306a36Sopenharmony_ci		.irq	= STMPE1801_IRQ_GPIOC,
86862306a36Sopenharmony_ci		.block	= STMPE_BLOCK_GPIO,
86962306a36Sopenharmony_ci	},
87062306a36Sopenharmony_ci	{
87162306a36Sopenharmony_ci		.cell	= &stmpe_keypad_cell,
87262306a36Sopenharmony_ci		.irq	= STMPE1801_IRQ_KEYPAD,
87362306a36Sopenharmony_ci		.block	= STMPE_BLOCK_KEYPAD,
87462306a36Sopenharmony_ci	},
87562306a36Sopenharmony_ci};
87662306a36Sopenharmony_ci
87762306a36Sopenharmony_cistatic int stmpe1801_enable(struct stmpe *stmpe, unsigned int blocks,
87862306a36Sopenharmony_ci			    bool enable)
87962306a36Sopenharmony_ci{
88062306a36Sopenharmony_ci	unsigned int mask = 0;
88162306a36Sopenharmony_ci	if (blocks & STMPE_BLOCK_GPIO)
88262306a36Sopenharmony_ci		mask |= STMPE1801_MSK_INT_EN_GPIO;
88362306a36Sopenharmony_ci
88462306a36Sopenharmony_ci	if (blocks & STMPE_BLOCK_KEYPAD)
88562306a36Sopenharmony_ci		mask |= STMPE1801_MSK_INT_EN_KPC;
88662306a36Sopenharmony_ci
88762306a36Sopenharmony_ci	return __stmpe_set_bits(stmpe, STMPE1801_REG_INT_EN_MASK_LOW, mask,
88862306a36Sopenharmony_ci				enable ? mask : 0);
88962306a36Sopenharmony_ci}
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_cistatic int stmpe_reset(struct stmpe *stmpe)
89262306a36Sopenharmony_ci{
89362306a36Sopenharmony_ci	u16 id_val = stmpe->variant->id_val;
89462306a36Sopenharmony_ci	unsigned long timeout;
89562306a36Sopenharmony_ci	int ret = 0;
89662306a36Sopenharmony_ci	u8 reset_bit;
89762306a36Sopenharmony_ci
89862306a36Sopenharmony_ci	if (id_val == STMPE811_ID)
89962306a36Sopenharmony_ci		/* STMPE801 and STMPE610 use bit 1 of SYS_CTRL register */
90062306a36Sopenharmony_ci		reset_bit = STMPE811_SYS_CTRL_RESET;
90162306a36Sopenharmony_ci	else
90262306a36Sopenharmony_ci		/* all other STMPE variant use bit 7 of SYS_CTRL register */
90362306a36Sopenharmony_ci		reset_bit = STMPE_SYS_CTRL_RESET;
90462306a36Sopenharmony_ci
90562306a36Sopenharmony_ci	ret = __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL],
90662306a36Sopenharmony_ci			       reset_bit, reset_bit);
90762306a36Sopenharmony_ci	if (ret < 0)
90862306a36Sopenharmony_ci		return ret;
90962306a36Sopenharmony_ci
91062306a36Sopenharmony_ci	msleep(10);
91162306a36Sopenharmony_ci
91262306a36Sopenharmony_ci	timeout = jiffies + msecs_to_jiffies(100);
91362306a36Sopenharmony_ci	while (time_before(jiffies, timeout)) {
91462306a36Sopenharmony_ci		ret = __stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL]);
91562306a36Sopenharmony_ci		if (ret < 0)
91662306a36Sopenharmony_ci			return ret;
91762306a36Sopenharmony_ci		if (!(ret & reset_bit))
91862306a36Sopenharmony_ci			return 0;
91962306a36Sopenharmony_ci		usleep_range(100, 200);
92062306a36Sopenharmony_ci	}
92162306a36Sopenharmony_ci	return -EIO;
92262306a36Sopenharmony_ci}
92362306a36Sopenharmony_ci
92462306a36Sopenharmony_cistatic struct stmpe_variant_info stmpe1801 = {
92562306a36Sopenharmony_ci	.name		= "stmpe1801",
92662306a36Sopenharmony_ci	.id_val		= STMPE1801_ID,
92762306a36Sopenharmony_ci	.id_mask	= 0xfff0,
92862306a36Sopenharmony_ci	.num_gpios	= 18,
92962306a36Sopenharmony_ci	.af_bits	= 0,
93062306a36Sopenharmony_ci	.regs		= stmpe1801_regs,
93162306a36Sopenharmony_ci	.blocks		= stmpe1801_blocks,
93262306a36Sopenharmony_ci	.num_blocks	= ARRAY_SIZE(stmpe1801_blocks),
93362306a36Sopenharmony_ci	.num_irqs	= STMPE1801_NR_INTERNAL_IRQS,
93462306a36Sopenharmony_ci	.enable		= stmpe1801_enable,
93562306a36Sopenharmony_ci	/* stmpe1801 do not have any gpio alternate function */
93662306a36Sopenharmony_ci	.get_altfunc	= NULL,
93762306a36Sopenharmony_ci};
93862306a36Sopenharmony_ci
93962306a36Sopenharmony_ci/*
94062306a36Sopenharmony_ci * STMPE24XX
94162306a36Sopenharmony_ci */
94262306a36Sopenharmony_ci
94362306a36Sopenharmony_cistatic const u8 stmpe24xx_regs[] = {
94462306a36Sopenharmony_ci	[STMPE_IDX_CHIP_ID]	= STMPE24XX_REG_CHIP_ID,
94562306a36Sopenharmony_ci	[STMPE_IDX_SYS_CTRL]	= STMPE24XX_REG_SYS_CTRL,
94662306a36Sopenharmony_ci	[STMPE_IDX_SYS_CTRL2]	= STMPE24XX_REG_SYS_CTRL2,
94762306a36Sopenharmony_ci	[STMPE_IDX_ICR_LSB]	= STMPE24XX_REG_ICR_LSB,
94862306a36Sopenharmony_ci	[STMPE_IDX_IER_MSB]	= STMPE24XX_REG_IER_MSB,
94962306a36Sopenharmony_ci	[STMPE_IDX_IER_LSB]	= STMPE24XX_REG_IER_LSB,
95062306a36Sopenharmony_ci	[STMPE_IDX_ISR_MSB]	= STMPE24XX_REG_ISR_MSB,
95162306a36Sopenharmony_ci	[STMPE_IDX_GPMR_LSB]	= STMPE24XX_REG_GPMR_LSB,
95262306a36Sopenharmony_ci	[STMPE_IDX_GPMR_CSB]	= STMPE24XX_REG_GPMR_CSB,
95362306a36Sopenharmony_ci	[STMPE_IDX_GPMR_MSB]	= STMPE24XX_REG_GPMR_MSB,
95462306a36Sopenharmony_ci	[STMPE_IDX_GPSR_LSB]	= STMPE24XX_REG_GPSR_LSB,
95562306a36Sopenharmony_ci	[STMPE_IDX_GPSR_CSB]	= STMPE24XX_REG_GPSR_CSB,
95662306a36Sopenharmony_ci	[STMPE_IDX_GPSR_MSB]	= STMPE24XX_REG_GPSR_MSB,
95762306a36Sopenharmony_ci	[STMPE_IDX_GPCR_LSB]	= STMPE24XX_REG_GPCR_LSB,
95862306a36Sopenharmony_ci	[STMPE_IDX_GPCR_CSB]	= STMPE24XX_REG_GPCR_CSB,
95962306a36Sopenharmony_ci	[STMPE_IDX_GPCR_MSB]	= STMPE24XX_REG_GPCR_MSB,
96062306a36Sopenharmony_ci	[STMPE_IDX_GPDR_LSB]	= STMPE24XX_REG_GPDR_LSB,
96162306a36Sopenharmony_ci	[STMPE_IDX_GPDR_CSB]	= STMPE24XX_REG_GPDR_CSB,
96262306a36Sopenharmony_ci	[STMPE_IDX_GPDR_MSB]	= STMPE24XX_REG_GPDR_MSB,
96362306a36Sopenharmony_ci	[STMPE_IDX_GPRER_LSB]	= STMPE24XX_REG_GPRER_LSB,
96462306a36Sopenharmony_ci	[STMPE_IDX_GPRER_CSB]	= STMPE24XX_REG_GPRER_CSB,
96562306a36Sopenharmony_ci	[STMPE_IDX_GPRER_MSB]	= STMPE24XX_REG_GPRER_MSB,
96662306a36Sopenharmony_ci	[STMPE_IDX_GPFER_LSB]	= STMPE24XX_REG_GPFER_LSB,
96762306a36Sopenharmony_ci	[STMPE_IDX_GPFER_CSB]	= STMPE24XX_REG_GPFER_CSB,
96862306a36Sopenharmony_ci	[STMPE_IDX_GPFER_MSB]	= STMPE24XX_REG_GPFER_MSB,
96962306a36Sopenharmony_ci	[STMPE_IDX_GPPUR_LSB]	= STMPE24XX_REG_GPPUR_LSB,
97062306a36Sopenharmony_ci	[STMPE_IDX_GPPDR_LSB]	= STMPE24XX_REG_GPPDR_LSB,
97162306a36Sopenharmony_ci	[STMPE_IDX_GPAFR_U_MSB]	= STMPE24XX_REG_GPAFR_U_MSB,
97262306a36Sopenharmony_ci	[STMPE_IDX_IEGPIOR_LSB]	= STMPE24XX_REG_IEGPIOR_LSB,
97362306a36Sopenharmony_ci	[STMPE_IDX_IEGPIOR_CSB]	= STMPE24XX_REG_IEGPIOR_CSB,
97462306a36Sopenharmony_ci	[STMPE_IDX_IEGPIOR_MSB]	= STMPE24XX_REG_IEGPIOR_MSB,
97562306a36Sopenharmony_ci	[STMPE_IDX_ISGPIOR_MSB]	= STMPE24XX_REG_ISGPIOR_MSB,
97662306a36Sopenharmony_ci	[STMPE_IDX_GPEDR_LSB]	= STMPE24XX_REG_GPEDR_LSB,
97762306a36Sopenharmony_ci	[STMPE_IDX_GPEDR_CSB]	= STMPE24XX_REG_GPEDR_CSB,
97862306a36Sopenharmony_ci	[STMPE_IDX_GPEDR_MSB]	= STMPE24XX_REG_GPEDR_MSB,
97962306a36Sopenharmony_ci};
98062306a36Sopenharmony_ci
98162306a36Sopenharmony_cistatic struct stmpe_variant_block stmpe24xx_blocks[] = {
98262306a36Sopenharmony_ci	{
98362306a36Sopenharmony_ci		.cell	= &stmpe_gpio_cell,
98462306a36Sopenharmony_ci		.irq	= STMPE24XX_IRQ_GPIOC,
98562306a36Sopenharmony_ci		.block	= STMPE_BLOCK_GPIO,
98662306a36Sopenharmony_ci	},
98762306a36Sopenharmony_ci	{
98862306a36Sopenharmony_ci		.cell	= &stmpe_keypad_cell,
98962306a36Sopenharmony_ci		.irq	= STMPE24XX_IRQ_KEYPAD,
99062306a36Sopenharmony_ci		.block	= STMPE_BLOCK_KEYPAD,
99162306a36Sopenharmony_ci	},
99262306a36Sopenharmony_ci	{
99362306a36Sopenharmony_ci		.cell	= &stmpe_pwm_cell,
99462306a36Sopenharmony_ci		.irq	= STMPE24XX_IRQ_PWM0,
99562306a36Sopenharmony_ci		.block	= STMPE_BLOCK_PWM,
99662306a36Sopenharmony_ci	},
99762306a36Sopenharmony_ci};
99862306a36Sopenharmony_ci
99962306a36Sopenharmony_cistatic int stmpe24xx_enable(struct stmpe *stmpe, unsigned int blocks,
100062306a36Sopenharmony_ci			    bool enable)
100162306a36Sopenharmony_ci{
100262306a36Sopenharmony_ci	unsigned int mask = 0;
100362306a36Sopenharmony_ci
100462306a36Sopenharmony_ci	if (blocks & STMPE_BLOCK_GPIO)
100562306a36Sopenharmony_ci		mask |= STMPE24XX_SYS_CTRL_ENABLE_GPIO;
100662306a36Sopenharmony_ci
100762306a36Sopenharmony_ci	if (blocks & STMPE_BLOCK_KEYPAD)
100862306a36Sopenharmony_ci		mask |= STMPE24XX_SYS_CTRL_ENABLE_KPC;
100962306a36Sopenharmony_ci
101062306a36Sopenharmony_ci	return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], mask,
101162306a36Sopenharmony_ci				enable ? mask : 0);
101262306a36Sopenharmony_ci}
101362306a36Sopenharmony_ci
101462306a36Sopenharmony_cistatic int stmpe24xx_get_altfunc(struct stmpe *stmpe, enum stmpe_block block)
101562306a36Sopenharmony_ci{
101662306a36Sopenharmony_ci	switch (block) {
101762306a36Sopenharmony_ci	case STMPE_BLOCK_ROTATOR:
101862306a36Sopenharmony_ci		return 2;
101962306a36Sopenharmony_ci
102062306a36Sopenharmony_ci	case STMPE_BLOCK_KEYPAD:
102162306a36Sopenharmony_ci	case STMPE_BLOCK_PWM:
102262306a36Sopenharmony_ci		return 1;
102362306a36Sopenharmony_ci
102462306a36Sopenharmony_ci	case STMPE_BLOCK_GPIO:
102562306a36Sopenharmony_ci	default:
102662306a36Sopenharmony_ci		return 0;
102762306a36Sopenharmony_ci	}
102862306a36Sopenharmony_ci}
102962306a36Sopenharmony_ci
103062306a36Sopenharmony_cistatic struct stmpe_variant_info stmpe2401 = {
103162306a36Sopenharmony_ci	.name		= "stmpe2401",
103262306a36Sopenharmony_ci	.id_val		= 0x0101,
103362306a36Sopenharmony_ci	.id_mask	= 0xffff,
103462306a36Sopenharmony_ci	.num_gpios	= 24,
103562306a36Sopenharmony_ci	.af_bits	= 2,
103662306a36Sopenharmony_ci	.regs		= stmpe24xx_regs,
103762306a36Sopenharmony_ci	.blocks		= stmpe24xx_blocks,
103862306a36Sopenharmony_ci	.num_blocks	= ARRAY_SIZE(stmpe24xx_blocks),
103962306a36Sopenharmony_ci	.num_irqs	= STMPE24XX_NR_INTERNAL_IRQS,
104062306a36Sopenharmony_ci	.enable		= stmpe24xx_enable,
104162306a36Sopenharmony_ci	.get_altfunc	= stmpe24xx_get_altfunc,
104262306a36Sopenharmony_ci};
104362306a36Sopenharmony_ci
104462306a36Sopenharmony_cistatic struct stmpe_variant_info stmpe2403 = {
104562306a36Sopenharmony_ci	.name		= "stmpe2403",
104662306a36Sopenharmony_ci	.id_val		= 0x0120,
104762306a36Sopenharmony_ci	.id_mask	= 0xffff,
104862306a36Sopenharmony_ci	.num_gpios	= 24,
104962306a36Sopenharmony_ci	.af_bits	= 2,
105062306a36Sopenharmony_ci	.regs		= stmpe24xx_regs,
105162306a36Sopenharmony_ci	.blocks		= stmpe24xx_blocks,
105262306a36Sopenharmony_ci	.num_blocks	= ARRAY_SIZE(stmpe24xx_blocks),
105362306a36Sopenharmony_ci	.num_irqs	= STMPE24XX_NR_INTERNAL_IRQS,
105462306a36Sopenharmony_ci	.enable		= stmpe24xx_enable,
105562306a36Sopenharmony_ci	.get_altfunc	= stmpe24xx_get_altfunc,
105662306a36Sopenharmony_ci	.enable_autosleep	= stmpe1601_autosleep, /* same as stmpe1601 */
105762306a36Sopenharmony_ci};
105862306a36Sopenharmony_ci
105962306a36Sopenharmony_cistatic struct stmpe_variant_info *stmpe_variant_info[STMPE_NBR_PARTS] = {
106062306a36Sopenharmony_ci	[STMPE610]	= &stmpe610,
106162306a36Sopenharmony_ci	[STMPE801]	= &stmpe801,
106262306a36Sopenharmony_ci	[STMPE811]	= &stmpe811,
106362306a36Sopenharmony_ci	[STMPE1600]	= &stmpe1600,
106462306a36Sopenharmony_ci	[STMPE1601]	= &stmpe1601,
106562306a36Sopenharmony_ci	[STMPE1801]	= &stmpe1801,
106662306a36Sopenharmony_ci	[STMPE2401]	= &stmpe2401,
106762306a36Sopenharmony_ci	[STMPE2403]	= &stmpe2403,
106862306a36Sopenharmony_ci};
106962306a36Sopenharmony_ci
107062306a36Sopenharmony_ci/*
107162306a36Sopenharmony_ci * These devices can be connected in a 'no-irq' configuration - the irq pin
107262306a36Sopenharmony_ci * is not used and the device cannot interrupt the CPU. Here we only list
107362306a36Sopenharmony_ci * devices which support this configuration - the driver will fail probing
107462306a36Sopenharmony_ci * for any devices not listed here which are configured in this way.
107562306a36Sopenharmony_ci */
107662306a36Sopenharmony_cistatic struct stmpe_variant_info *stmpe_noirq_variant_info[STMPE_NBR_PARTS] = {
107762306a36Sopenharmony_ci	[STMPE801]	= &stmpe801_noirq,
107862306a36Sopenharmony_ci};
107962306a36Sopenharmony_ci
108062306a36Sopenharmony_cistatic irqreturn_t stmpe_irq(int irq, void *data)
108162306a36Sopenharmony_ci{
108262306a36Sopenharmony_ci	struct stmpe *stmpe = data;
108362306a36Sopenharmony_ci	struct stmpe_variant_info *variant = stmpe->variant;
108462306a36Sopenharmony_ci	int num = DIV_ROUND_UP(variant->num_irqs, 8);
108562306a36Sopenharmony_ci	u8 israddr;
108662306a36Sopenharmony_ci	u8 isr[3];
108762306a36Sopenharmony_ci	int ret;
108862306a36Sopenharmony_ci	int i;
108962306a36Sopenharmony_ci
109062306a36Sopenharmony_ci	if (variant->id_val == STMPE801_ID ||
109162306a36Sopenharmony_ci	    variant->id_val == STMPE1600_ID) {
109262306a36Sopenharmony_ci		int base = irq_find_mapping(stmpe->domain, 0);
109362306a36Sopenharmony_ci
109462306a36Sopenharmony_ci		handle_nested_irq(base);
109562306a36Sopenharmony_ci		return IRQ_HANDLED;
109662306a36Sopenharmony_ci	}
109762306a36Sopenharmony_ci
109862306a36Sopenharmony_ci	if (variant->id_val == STMPE1801_ID)
109962306a36Sopenharmony_ci		israddr = stmpe->regs[STMPE_IDX_ISR_LSB];
110062306a36Sopenharmony_ci	else
110162306a36Sopenharmony_ci		israddr = stmpe->regs[STMPE_IDX_ISR_MSB];
110262306a36Sopenharmony_ci
110362306a36Sopenharmony_ci	ret = stmpe_block_read(stmpe, israddr, num, isr);
110462306a36Sopenharmony_ci	if (ret < 0)
110562306a36Sopenharmony_ci		return IRQ_NONE;
110662306a36Sopenharmony_ci
110762306a36Sopenharmony_ci	for (i = 0; i < num; i++) {
110862306a36Sopenharmony_ci		int bank = num - i - 1;
110962306a36Sopenharmony_ci		u8 status = isr[i];
111062306a36Sopenharmony_ci		u8 clear;
111162306a36Sopenharmony_ci
111262306a36Sopenharmony_ci		status &= stmpe->ier[bank];
111362306a36Sopenharmony_ci		if (!status)
111462306a36Sopenharmony_ci			continue;
111562306a36Sopenharmony_ci
111662306a36Sopenharmony_ci		clear = status;
111762306a36Sopenharmony_ci		while (status) {
111862306a36Sopenharmony_ci			int bit = __ffs(status);
111962306a36Sopenharmony_ci			int line = bank * 8 + bit;
112062306a36Sopenharmony_ci			int nestedirq = irq_find_mapping(stmpe->domain, line);
112162306a36Sopenharmony_ci
112262306a36Sopenharmony_ci			handle_nested_irq(nestedirq);
112362306a36Sopenharmony_ci			status &= ~(1 << bit);
112462306a36Sopenharmony_ci		}
112562306a36Sopenharmony_ci
112662306a36Sopenharmony_ci		stmpe_reg_write(stmpe, israddr + i, clear);
112762306a36Sopenharmony_ci	}
112862306a36Sopenharmony_ci
112962306a36Sopenharmony_ci	return IRQ_HANDLED;
113062306a36Sopenharmony_ci}
113162306a36Sopenharmony_ci
113262306a36Sopenharmony_cistatic void stmpe_irq_lock(struct irq_data *data)
113362306a36Sopenharmony_ci{
113462306a36Sopenharmony_ci	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
113562306a36Sopenharmony_ci
113662306a36Sopenharmony_ci	mutex_lock(&stmpe->irq_lock);
113762306a36Sopenharmony_ci}
113862306a36Sopenharmony_ci
113962306a36Sopenharmony_cistatic void stmpe_irq_sync_unlock(struct irq_data *data)
114062306a36Sopenharmony_ci{
114162306a36Sopenharmony_ci	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
114262306a36Sopenharmony_ci	struct stmpe_variant_info *variant = stmpe->variant;
114362306a36Sopenharmony_ci	int num = DIV_ROUND_UP(variant->num_irqs, 8);
114462306a36Sopenharmony_ci	int i;
114562306a36Sopenharmony_ci
114662306a36Sopenharmony_ci	for (i = 0; i < num; i++) {
114762306a36Sopenharmony_ci		u8 new = stmpe->ier[i];
114862306a36Sopenharmony_ci		u8 old = stmpe->oldier[i];
114962306a36Sopenharmony_ci
115062306a36Sopenharmony_ci		if (new == old)
115162306a36Sopenharmony_ci			continue;
115262306a36Sopenharmony_ci
115362306a36Sopenharmony_ci		stmpe->oldier[i] = new;
115462306a36Sopenharmony_ci		stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_IER_LSB + i], new);
115562306a36Sopenharmony_ci	}
115662306a36Sopenharmony_ci
115762306a36Sopenharmony_ci	mutex_unlock(&stmpe->irq_lock);
115862306a36Sopenharmony_ci}
115962306a36Sopenharmony_ci
116062306a36Sopenharmony_cistatic void stmpe_irq_mask(struct irq_data *data)
116162306a36Sopenharmony_ci{
116262306a36Sopenharmony_ci	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
116362306a36Sopenharmony_ci	int offset = data->hwirq;
116462306a36Sopenharmony_ci	int regoffset = offset / 8;
116562306a36Sopenharmony_ci	int mask = 1 << (offset % 8);
116662306a36Sopenharmony_ci
116762306a36Sopenharmony_ci	stmpe->ier[regoffset] &= ~mask;
116862306a36Sopenharmony_ci}
116962306a36Sopenharmony_ci
117062306a36Sopenharmony_cistatic void stmpe_irq_unmask(struct irq_data *data)
117162306a36Sopenharmony_ci{
117262306a36Sopenharmony_ci	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
117362306a36Sopenharmony_ci	int offset = data->hwirq;
117462306a36Sopenharmony_ci	int regoffset = offset / 8;
117562306a36Sopenharmony_ci	int mask = 1 << (offset % 8);
117662306a36Sopenharmony_ci
117762306a36Sopenharmony_ci	stmpe->ier[regoffset] |= mask;
117862306a36Sopenharmony_ci}
117962306a36Sopenharmony_ci
118062306a36Sopenharmony_cistatic struct irq_chip stmpe_irq_chip = {
118162306a36Sopenharmony_ci	.name			= "stmpe",
118262306a36Sopenharmony_ci	.irq_bus_lock		= stmpe_irq_lock,
118362306a36Sopenharmony_ci	.irq_bus_sync_unlock	= stmpe_irq_sync_unlock,
118462306a36Sopenharmony_ci	.irq_mask		= stmpe_irq_mask,
118562306a36Sopenharmony_ci	.irq_unmask		= stmpe_irq_unmask,
118662306a36Sopenharmony_ci};
118762306a36Sopenharmony_ci
118862306a36Sopenharmony_cistatic int stmpe_irq_map(struct irq_domain *d, unsigned int virq,
118962306a36Sopenharmony_ci                                irq_hw_number_t hwirq)
119062306a36Sopenharmony_ci{
119162306a36Sopenharmony_ci	struct stmpe *stmpe = d->host_data;
119262306a36Sopenharmony_ci	struct irq_chip *chip = NULL;
119362306a36Sopenharmony_ci
119462306a36Sopenharmony_ci	if (stmpe->variant->id_val != STMPE801_ID)
119562306a36Sopenharmony_ci		chip = &stmpe_irq_chip;
119662306a36Sopenharmony_ci
119762306a36Sopenharmony_ci	irq_set_chip_data(virq, stmpe);
119862306a36Sopenharmony_ci	irq_set_chip_and_handler(virq, chip, handle_edge_irq);
119962306a36Sopenharmony_ci	irq_set_nested_thread(virq, 1);
120062306a36Sopenharmony_ci	irq_set_noprobe(virq);
120162306a36Sopenharmony_ci
120262306a36Sopenharmony_ci	return 0;
120362306a36Sopenharmony_ci}
120462306a36Sopenharmony_ci
120562306a36Sopenharmony_cistatic void stmpe_irq_unmap(struct irq_domain *d, unsigned int virq)
120662306a36Sopenharmony_ci{
120762306a36Sopenharmony_ci		irq_set_chip_and_handler(virq, NULL, NULL);
120862306a36Sopenharmony_ci		irq_set_chip_data(virq, NULL);
120962306a36Sopenharmony_ci}
121062306a36Sopenharmony_ci
121162306a36Sopenharmony_cistatic const struct irq_domain_ops stmpe_irq_ops = {
121262306a36Sopenharmony_ci        .map    = stmpe_irq_map,
121362306a36Sopenharmony_ci        .unmap  = stmpe_irq_unmap,
121462306a36Sopenharmony_ci        .xlate  = irq_domain_xlate_twocell,
121562306a36Sopenharmony_ci};
121662306a36Sopenharmony_ci
121762306a36Sopenharmony_cistatic int stmpe_irq_init(struct stmpe *stmpe, struct device_node *np)
121862306a36Sopenharmony_ci{
121962306a36Sopenharmony_ci	int base = 0;
122062306a36Sopenharmony_ci	int num_irqs = stmpe->variant->num_irqs;
122162306a36Sopenharmony_ci
122262306a36Sopenharmony_ci	stmpe->domain = irq_domain_add_simple(np, num_irqs, base,
122362306a36Sopenharmony_ci					      &stmpe_irq_ops, stmpe);
122462306a36Sopenharmony_ci	if (!stmpe->domain) {
122562306a36Sopenharmony_ci		dev_err(stmpe->dev, "Failed to create irqdomain\n");
122662306a36Sopenharmony_ci		return -ENOSYS;
122762306a36Sopenharmony_ci	}
122862306a36Sopenharmony_ci
122962306a36Sopenharmony_ci	return 0;
123062306a36Sopenharmony_ci}
123162306a36Sopenharmony_ci
123262306a36Sopenharmony_cistatic int stmpe_chip_init(struct stmpe *stmpe)
123362306a36Sopenharmony_ci{
123462306a36Sopenharmony_ci	unsigned int irq_trigger = stmpe->pdata->irq_trigger;
123562306a36Sopenharmony_ci	int autosleep_timeout = stmpe->pdata->autosleep_timeout;
123662306a36Sopenharmony_ci	struct stmpe_variant_info *variant = stmpe->variant;
123762306a36Sopenharmony_ci	u8 icr = 0;
123862306a36Sopenharmony_ci	unsigned int id;
123962306a36Sopenharmony_ci	u8 data[2];
124062306a36Sopenharmony_ci	int ret;
124162306a36Sopenharmony_ci
124262306a36Sopenharmony_ci	ret = stmpe_block_read(stmpe, stmpe->regs[STMPE_IDX_CHIP_ID],
124362306a36Sopenharmony_ci			       ARRAY_SIZE(data), data);
124462306a36Sopenharmony_ci	if (ret < 0)
124562306a36Sopenharmony_ci		return ret;
124662306a36Sopenharmony_ci
124762306a36Sopenharmony_ci	id = (data[0] << 8) | data[1];
124862306a36Sopenharmony_ci	if ((id & variant->id_mask) != variant->id_val) {
124962306a36Sopenharmony_ci		dev_err(stmpe->dev, "unknown chip id: %#x\n", id);
125062306a36Sopenharmony_ci		return -EINVAL;
125162306a36Sopenharmony_ci	}
125262306a36Sopenharmony_ci
125362306a36Sopenharmony_ci	dev_info(stmpe->dev, "%s detected, chip id: %#x\n", variant->name, id);
125462306a36Sopenharmony_ci
125562306a36Sopenharmony_ci	/* Disable all modules -- subdrivers should enable what they need. */
125662306a36Sopenharmony_ci	ret = stmpe_disable(stmpe, ~0);
125762306a36Sopenharmony_ci	if (ret)
125862306a36Sopenharmony_ci		return ret;
125962306a36Sopenharmony_ci
126062306a36Sopenharmony_ci	ret =  stmpe_reset(stmpe);
126162306a36Sopenharmony_ci	if (ret < 0)
126262306a36Sopenharmony_ci		return ret;
126362306a36Sopenharmony_ci
126462306a36Sopenharmony_ci	if (stmpe->irq >= 0) {
126562306a36Sopenharmony_ci		if (id == STMPE801_ID || id == STMPE1600_ID)
126662306a36Sopenharmony_ci			icr = STMPE_SYS_CTRL_INT_EN;
126762306a36Sopenharmony_ci		else
126862306a36Sopenharmony_ci			icr = STMPE_ICR_LSB_GIM;
126962306a36Sopenharmony_ci
127062306a36Sopenharmony_ci		/* STMPE801 and STMPE1600 don't support Edge interrupts */
127162306a36Sopenharmony_ci		if (id != STMPE801_ID && id != STMPE1600_ID) {
127262306a36Sopenharmony_ci			if (irq_trigger == IRQF_TRIGGER_FALLING ||
127362306a36Sopenharmony_ci					irq_trigger == IRQF_TRIGGER_RISING)
127462306a36Sopenharmony_ci				icr |= STMPE_ICR_LSB_EDGE;
127562306a36Sopenharmony_ci		}
127662306a36Sopenharmony_ci
127762306a36Sopenharmony_ci		if (irq_trigger == IRQF_TRIGGER_RISING ||
127862306a36Sopenharmony_ci				irq_trigger == IRQF_TRIGGER_HIGH) {
127962306a36Sopenharmony_ci			if (id == STMPE801_ID || id == STMPE1600_ID)
128062306a36Sopenharmony_ci				icr |= STMPE_SYS_CTRL_INT_HI;
128162306a36Sopenharmony_ci			else
128262306a36Sopenharmony_ci				icr |= STMPE_ICR_LSB_HIGH;
128362306a36Sopenharmony_ci		}
128462306a36Sopenharmony_ci	}
128562306a36Sopenharmony_ci
128662306a36Sopenharmony_ci	if (stmpe->pdata->autosleep) {
128762306a36Sopenharmony_ci		ret = stmpe_autosleep(stmpe, autosleep_timeout);
128862306a36Sopenharmony_ci		if (ret)
128962306a36Sopenharmony_ci			return ret;
129062306a36Sopenharmony_ci	}
129162306a36Sopenharmony_ci
129262306a36Sopenharmony_ci	return stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_ICR_LSB], icr);
129362306a36Sopenharmony_ci}
129462306a36Sopenharmony_ci
129562306a36Sopenharmony_cistatic int stmpe_add_device(struct stmpe *stmpe, const struct mfd_cell *cell)
129662306a36Sopenharmony_ci{
129762306a36Sopenharmony_ci	return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1,
129862306a36Sopenharmony_ci			       NULL, 0, stmpe->domain);
129962306a36Sopenharmony_ci}
130062306a36Sopenharmony_ci
130162306a36Sopenharmony_cistatic int stmpe_devices_init(struct stmpe *stmpe)
130262306a36Sopenharmony_ci{
130362306a36Sopenharmony_ci	struct stmpe_variant_info *variant = stmpe->variant;
130462306a36Sopenharmony_ci	unsigned int platform_blocks = stmpe->pdata->blocks;
130562306a36Sopenharmony_ci	int ret = -EINVAL;
130662306a36Sopenharmony_ci	int i, j;
130762306a36Sopenharmony_ci
130862306a36Sopenharmony_ci	for (i = 0; i < variant->num_blocks; i++) {
130962306a36Sopenharmony_ci		struct stmpe_variant_block *block = &variant->blocks[i];
131062306a36Sopenharmony_ci
131162306a36Sopenharmony_ci		if (!(platform_blocks & block->block))
131262306a36Sopenharmony_ci			continue;
131362306a36Sopenharmony_ci
131462306a36Sopenharmony_ci		for (j = 0; j < block->cell->num_resources; j++) {
131562306a36Sopenharmony_ci			struct resource *res =
131662306a36Sopenharmony_ci				(struct resource *) &block->cell->resources[j];
131762306a36Sopenharmony_ci
131862306a36Sopenharmony_ci			/* Dynamically fill in a variant's IRQ. */
131962306a36Sopenharmony_ci			if (res->flags & IORESOURCE_IRQ)
132062306a36Sopenharmony_ci				res->start = res->end = block->irq + j;
132162306a36Sopenharmony_ci		}
132262306a36Sopenharmony_ci
132362306a36Sopenharmony_ci		platform_blocks &= ~block->block;
132462306a36Sopenharmony_ci		ret = stmpe_add_device(stmpe, block->cell);
132562306a36Sopenharmony_ci		if (ret)
132662306a36Sopenharmony_ci			return ret;
132762306a36Sopenharmony_ci	}
132862306a36Sopenharmony_ci
132962306a36Sopenharmony_ci	if (platform_blocks)
133062306a36Sopenharmony_ci		dev_warn(stmpe->dev,
133162306a36Sopenharmony_ci			 "platform wants blocks (%#x) not present on variant",
133262306a36Sopenharmony_ci			 platform_blocks);
133362306a36Sopenharmony_ci
133462306a36Sopenharmony_ci	return ret;
133562306a36Sopenharmony_ci}
133662306a36Sopenharmony_ci
133762306a36Sopenharmony_cistatic void stmpe_of_probe(struct stmpe_platform_data *pdata,
133862306a36Sopenharmony_ci			   struct device_node *np)
133962306a36Sopenharmony_ci{
134062306a36Sopenharmony_ci	struct device_node *child;
134162306a36Sopenharmony_ci
134262306a36Sopenharmony_ci	pdata->id = of_alias_get_id(np, "stmpe-i2c");
134362306a36Sopenharmony_ci	if (pdata->id < 0)
134462306a36Sopenharmony_ci		pdata->id = -1;
134562306a36Sopenharmony_ci
134662306a36Sopenharmony_ci	of_property_read_u32(np, "st,autosleep-timeout",
134762306a36Sopenharmony_ci			&pdata->autosleep_timeout);
134862306a36Sopenharmony_ci
134962306a36Sopenharmony_ci	pdata->autosleep = (pdata->autosleep_timeout) ? true : false;
135062306a36Sopenharmony_ci
135162306a36Sopenharmony_ci	for_each_available_child_of_node(np, child) {
135262306a36Sopenharmony_ci		if (of_device_is_compatible(child, stmpe_gpio_cell.of_compatible))
135362306a36Sopenharmony_ci			pdata->blocks |= STMPE_BLOCK_GPIO;
135462306a36Sopenharmony_ci		else if (of_device_is_compatible(child, stmpe_keypad_cell.of_compatible))
135562306a36Sopenharmony_ci			pdata->blocks |= STMPE_BLOCK_KEYPAD;
135662306a36Sopenharmony_ci		else if (of_device_is_compatible(child, stmpe_ts_cell.of_compatible))
135762306a36Sopenharmony_ci			pdata->blocks |= STMPE_BLOCK_TOUCHSCREEN;
135862306a36Sopenharmony_ci		else if (of_device_is_compatible(child, stmpe_adc_cell.of_compatible))
135962306a36Sopenharmony_ci			pdata->blocks |= STMPE_BLOCK_ADC;
136062306a36Sopenharmony_ci		else if (of_device_is_compatible(child, stmpe_pwm_cell.of_compatible))
136162306a36Sopenharmony_ci			pdata->blocks |= STMPE_BLOCK_PWM;
136262306a36Sopenharmony_ci	}
136362306a36Sopenharmony_ci}
136462306a36Sopenharmony_ci
136562306a36Sopenharmony_ci/* Called from client specific probe routines */
136662306a36Sopenharmony_ciint stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum)
136762306a36Sopenharmony_ci{
136862306a36Sopenharmony_ci	struct stmpe_platform_data *pdata;
136962306a36Sopenharmony_ci	struct device_node *np = ci->dev->of_node;
137062306a36Sopenharmony_ci	struct stmpe *stmpe;
137162306a36Sopenharmony_ci	struct gpio_desc *irq_gpio;
137262306a36Sopenharmony_ci	int ret;
137362306a36Sopenharmony_ci	u32 val;
137462306a36Sopenharmony_ci
137562306a36Sopenharmony_ci	pdata = devm_kzalloc(ci->dev, sizeof(*pdata), GFP_KERNEL);
137662306a36Sopenharmony_ci	if (!pdata)
137762306a36Sopenharmony_ci		return -ENOMEM;
137862306a36Sopenharmony_ci
137962306a36Sopenharmony_ci	stmpe_of_probe(pdata, np);
138062306a36Sopenharmony_ci
138162306a36Sopenharmony_ci	if (!of_property_present(np, "interrupts"))
138262306a36Sopenharmony_ci		ci->irq = -1;
138362306a36Sopenharmony_ci
138462306a36Sopenharmony_ci	stmpe = devm_kzalloc(ci->dev, sizeof(struct stmpe), GFP_KERNEL);
138562306a36Sopenharmony_ci	if (!stmpe)
138662306a36Sopenharmony_ci		return -ENOMEM;
138762306a36Sopenharmony_ci
138862306a36Sopenharmony_ci	mutex_init(&stmpe->irq_lock);
138962306a36Sopenharmony_ci	mutex_init(&stmpe->lock);
139062306a36Sopenharmony_ci
139162306a36Sopenharmony_ci	if (!of_property_read_u32(np, "st,sample-time", &val))
139262306a36Sopenharmony_ci		stmpe->sample_time = val;
139362306a36Sopenharmony_ci	if (!of_property_read_u32(np, "st,mod-12b", &val))
139462306a36Sopenharmony_ci		stmpe->mod_12b = val;
139562306a36Sopenharmony_ci	if (!of_property_read_u32(np, "st,ref-sel", &val))
139662306a36Sopenharmony_ci		stmpe->ref_sel = val;
139762306a36Sopenharmony_ci	if (!of_property_read_u32(np, "st,adc-freq", &val))
139862306a36Sopenharmony_ci		stmpe->adc_freq = val;
139962306a36Sopenharmony_ci
140062306a36Sopenharmony_ci	stmpe->dev = ci->dev;
140162306a36Sopenharmony_ci	stmpe->client = ci->client;
140262306a36Sopenharmony_ci	stmpe->pdata = pdata;
140362306a36Sopenharmony_ci	stmpe->ci = ci;
140462306a36Sopenharmony_ci	stmpe->partnum = partnum;
140562306a36Sopenharmony_ci	stmpe->variant = stmpe_variant_info[partnum];
140662306a36Sopenharmony_ci	stmpe->regs = stmpe->variant->regs;
140762306a36Sopenharmony_ci	stmpe->num_gpios = stmpe->variant->num_gpios;
140862306a36Sopenharmony_ci	stmpe->vcc = devm_regulator_get_optional(ci->dev, "vcc");
140962306a36Sopenharmony_ci	if (!IS_ERR(stmpe->vcc)) {
141062306a36Sopenharmony_ci		ret = regulator_enable(stmpe->vcc);
141162306a36Sopenharmony_ci		if (ret)
141262306a36Sopenharmony_ci			dev_warn(ci->dev, "failed to enable VCC supply\n");
141362306a36Sopenharmony_ci	}
141462306a36Sopenharmony_ci	stmpe->vio = devm_regulator_get_optional(ci->dev, "vio");
141562306a36Sopenharmony_ci	if (!IS_ERR(stmpe->vio)) {
141662306a36Sopenharmony_ci		ret = regulator_enable(stmpe->vio);
141762306a36Sopenharmony_ci		if (ret)
141862306a36Sopenharmony_ci			dev_warn(ci->dev, "failed to enable VIO supply\n");
141962306a36Sopenharmony_ci	}
142062306a36Sopenharmony_ci	dev_set_drvdata(stmpe->dev, stmpe);
142162306a36Sopenharmony_ci
142262306a36Sopenharmony_ci	if (ci->init)
142362306a36Sopenharmony_ci		ci->init(stmpe);
142462306a36Sopenharmony_ci
142562306a36Sopenharmony_ci	irq_gpio = devm_gpiod_get_optional(ci->dev, "irq", GPIOD_ASIS);
142662306a36Sopenharmony_ci	ret = PTR_ERR_OR_ZERO(irq_gpio);
142762306a36Sopenharmony_ci	if (ret) {
142862306a36Sopenharmony_ci		dev_err(stmpe->dev, "failed to request IRQ GPIO: %d\n", ret);
142962306a36Sopenharmony_ci		return ret;
143062306a36Sopenharmony_ci	}
143162306a36Sopenharmony_ci
143262306a36Sopenharmony_ci	if (irq_gpio) {
143362306a36Sopenharmony_ci		stmpe->irq = gpiod_to_irq(irq_gpio);
143462306a36Sopenharmony_ci		pdata->irq_trigger = gpiod_is_active_low(irq_gpio) ?
143562306a36Sopenharmony_ci					IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH;
143662306a36Sopenharmony_ci	} else {
143762306a36Sopenharmony_ci		stmpe->irq = ci->irq;
143862306a36Sopenharmony_ci		pdata->irq_trigger = IRQF_TRIGGER_NONE;
143962306a36Sopenharmony_ci	}
144062306a36Sopenharmony_ci
144162306a36Sopenharmony_ci	if (stmpe->irq < 0) {
144262306a36Sopenharmony_ci		/* use alternate variant info for no-irq mode, if supported */
144362306a36Sopenharmony_ci		dev_info(stmpe->dev,
144462306a36Sopenharmony_ci			"%s configured in no-irq mode by platform data\n",
144562306a36Sopenharmony_ci			stmpe->variant->name);
144662306a36Sopenharmony_ci		if (!stmpe_noirq_variant_info[stmpe->partnum]) {
144762306a36Sopenharmony_ci			dev_err(stmpe->dev,
144862306a36Sopenharmony_ci				"%s does not support no-irq mode!\n",
144962306a36Sopenharmony_ci				stmpe->variant->name);
145062306a36Sopenharmony_ci			return -ENODEV;
145162306a36Sopenharmony_ci		}
145262306a36Sopenharmony_ci		stmpe->variant = stmpe_noirq_variant_info[stmpe->partnum];
145362306a36Sopenharmony_ci	} else if (pdata->irq_trigger == IRQF_TRIGGER_NONE) {
145462306a36Sopenharmony_ci		pdata->irq_trigger = irq_get_trigger_type(stmpe->irq);
145562306a36Sopenharmony_ci	}
145662306a36Sopenharmony_ci
145762306a36Sopenharmony_ci	ret = stmpe_chip_init(stmpe);
145862306a36Sopenharmony_ci	if (ret)
145962306a36Sopenharmony_ci		return ret;
146062306a36Sopenharmony_ci
146162306a36Sopenharmony_ci	if (stmpe->irq >= 0) {
146262306a36Sopenharmony_ci		ret = stmpe_irq_init(stmpe, np);
146362306a36Sopenharmony_ci		if (ret)
146462306a36Sopenharmony_ci			return ret;
146562306a36Sopenharmony_ci
146662306a36Sopenharmony_ci		ret = devm_request_threaded_irq(ci->dev, stmpe->irq, NULL,
146762306a36Sopenharmony_ci				stmpe_irq, pdata->irq_trigger | IRQF_ONESHOT,
146862306a36Sopenharmony_ci				"stmpe", stmpe);
146962306a36Sopenharmony_ci		if (ret) {
147062306a36Sopenharmony_ci			dev_err(stmpe->dev, "failed to request IRQ: %d\n",
147162306a36Sopenharmony_ci					ret);
147262306a36Sopenharmony_ci			return ret;
147362306a36Sopenharmony_ci		}
147462306a36Sopenharmony_ci	}
147562306a36Sopenharmony_ci
147662306a36Sopenharmony_ci	ret = stmpe_devices_init(stmpe);
147762306a36Sopenharmony_ci	if (!ret)
147862306a36Sopenharmony_ci		return 0;
147962306a36Sopenharmony_ci
148062306a36Sopenharmony_ci	dev_err(stmpe->dev, "failed to add children\n");
148162306a36Sopenharmony_ci	mfd_remove_devices(stmpe->dev);
148262306a36Sopenharmony_ci
148362306a36Sopenharmony_ci	return ret;
148462306a36Sopenharmony_ci}
148562306a36Sopenharmony_ci
148662306a36Sopenharmony_civoid stmpe_remove(struct stmpe *stmpe)
148762306a36Sopenharmony_ci{
148862306a36Sopenharmony_ci	if (!IS_ERR(stmpe->vio) && regulator_is_enabled(stmpe->vio))
148962306a36Sopenharmony_ci		regulator_disable(stmpe->vio);
149062306a36Sopenharmony_ci	if (!IS_ERR(stmpe->vcc) && regulator_is_enabled(stmpe->vcc))
149162306a36Sopenharmony_ci		regulator_disable(stmpe->vcc);
149262306a36Sopenharmony_ci
149362306a36Sopenharmony_ci	__stmpe_disable(stmpe, STMPE_BLOCK_ADC);
149462306a36Sopenharmony_ci
149562306a36Sopenharmony_ci	mfd_remove_devices(stmpe->dev);
149662306a36Sopenharmony_ci}
149762306a36Sopenharmony_ci
149862306a36Sopenharmony_cistatic int stmpe_suspend(struct device *dev)
149962306a36Sopenharmony_ci{
150062306a36Sopenharmony_ci	struct stmpe *stmpe = dev_get_drvdata(dev);
150162306a36Sopenharmony_ci
150262306a36Sopenharmony_ci	if (stmpe->irq >= 0 && device_may_wakeup(dev))
150362306a36Sopenharmony_ci		enable_irq_wake(stmpe->irq);
150462306a36Sopenharmony_ci
150562306a36Sopenharmony_ci	return 0;
150662306a36Sopenharmony_ci}
150762306a36Sopenharmony_ci
150862306a36Sopenharmony_cistatic int stmpe_resume(struct device *dev)
150962306a36Sopenharmony_ci{
151062306a36Sopenharmony_ci	struct stmpe *stmpe = dev_get_drvdata(dev);
151162306a36Sopenharmony_ci
151262306a36Sopenharmony_ci	if (stmpe->irq >= 0 && device_may_wakeup(dev))
151362306a36Sopenharmony_ci		disable_irq_wake(stmpe->irq);
151462306a36Sopenharmony_ci
151562306a36Sopenharmony_ci	return 0;
151662306a36Sopenharmony_ci}
151762306a36Sopenharmony_ci
151862306a36Sopenharmony_ciEXPORT_GPL_SIMPLE_DEV_PM_OPS(stmpe_dev_pm_ops,
151962306a36Sopenharmony_ci			     stmpe_suspend, stmpe_resume);
1520