127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent/*
21a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar * ST Microelectronics MFD: stmpe's driver
31a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar *
427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * Copyright (C) ST-Ericsson SA 2010
527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent *
627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * License Terms: GNU General Public License, version 2
727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent */
927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
1073de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar#include <linux/gpio.h>
11dba61c8f4fd14c4cbf375f6cdc814da87722d825Samuel Ortiz#include <linux/export.h>
1227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent#include <linux/kernel.h>
1327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent#include <linux/interrupt.h>
1427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent#include <linux/irq.h>
151a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar#include <linux/pm.h>
1627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent#include <linux/slab.h>
1727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent#include <linux/mfd/core.h>
1827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent#include "stmpe.h"
1927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
2027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks)
2127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
2227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return stmpe->variant->enable(stmpe, blocks, true);
2327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
2427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
2527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic int __stmpe_disable(struct stmpe *stmpe, unsigned int blocks)
2627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
2727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return stmpe->variant->enable(stmpe, blocks, false);
2827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
2927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
3027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic int __stmpe_reg_read(struct stmpe *stmpe, u8 reg)
3127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
3227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int ret;
3327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
341a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	ret = stmpe->ci->read_byte(stmpe, reg);
3527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (ret < 0)
361a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar		dev_err(stmpe->dev, "failed to read reg %#x: %d\n", reg, ret);
3727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
3827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	dev_vdbg(stmpe->dev, "rd: reg %#x => data %#x\n", reg, ret);
3927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
4027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return ret;
4127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
4227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
4327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic int __stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val)
4427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
4527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int ret;
4627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
4727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	dev_vdbg(stmpe->dev, "wr: reg %#x <= %#x\n", reg, val);
4827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
491a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	ret = stmpe->ci->write_byte(stmpe, reg, val);
5027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (ret < 0)
511a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar		dev_err(stmpe->dev, "failed to write reg %#x: %d\n", reg, ret);
5227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
5327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return ret;
5427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
5527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
5627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic int __stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val)
5727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
5827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int ret;
5927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
6027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	ret = __stmpe_reg_read(stmpe, reg);
6127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (ret < 0)
6227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		return ret;
6327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
6427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	ret &= ~mask;
6527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	ret |= val;
6627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
6727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return __stmpe_reg_write(stmpe, reg, ret);
6827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
6927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
7027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic int __stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length,
7127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent			      u8 *values)
7227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
7327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int ret;
7427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
751a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	ret = stmpe->ci->read_block(stmpe, reg, length, values);
7627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (ret < 0)
771a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar		dev_err(stmpe->dev, "failed to read regs %#x: %d\n", reg, ret);
7827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
7927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	dev_vdbg(stmpe->dev, "rd: reg %#x (%d) => ret %#x\n", reg, length, ret);
8027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	stmpe_dump_bytes("stmpe rd: ", values, length);
8127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
8227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return ret;
8327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
8427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
8527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic int __stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length,
8627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent			const u8 *values)
8727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
8827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int ret;
8927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
9027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	dev_vdbg(stmpe->dev, "wr: regs %#x (%d)\n", reg, length);
9127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	stmpe_dump_bytes("stmpe wr: ", values, length);
9227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
931a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	ret = stmpe->ci->write_block(stmpe, reg, length, values);
9427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (ret < 0)
951a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar		dev_err(stmpe->dev, "failed to write regs %#x: %d\n", reg, ret);
9627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
9727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return ret;
9827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
9927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
10027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent/**
10127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * stmpe_enable - enable blocks on an STMPE device
10227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @stmpe:	Device to work on
10327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @blocks:	Mask of blocks (enum stmpe_block values) to enable
10427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent */
10527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentint stmpe_enable(struct stmpe *stmpe, unsigned int blocks)
10627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
10727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int ret;
10827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
10927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_lock(&stmpe->lock);
11027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	ret = __stmpe_enable(stmpe, blocks);
11127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_unlock(&stmpe->lock);
11227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
11327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return ret;
11427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
11527e34995e1a863c1e9beba30e51dfe2a083f918dRabin VincentEXPORT_SYMBOL_GPL(stmpe_enable);
11627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
11727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent/**
11827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * stmpe_disable - disable blocks on an STMPE device
11927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @stmpe:	Device to work on
12027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @blocks:	Mask of blocks (enum stmpe_block values) to enable
12127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent */
12227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentint stmpe_disable(struct stmpe *stmpe, unsigned int blocks)
12327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
12427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int ret;
12527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
12627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_lock(&stmpe->lock);
12727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	ret = __stmpe_disable(stmpe, blocks);
12827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_unlock(&stmpe->lock);
12927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
13027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return ret;
13127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
13227e34995e1a863c1e9beba30e51dfe2a083f918dRabin VincentEXPORT_SYMBOL_GPL(stmpe_disable);
13327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
13427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent/**
13527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * stmpe_reg_read() - read a single STMPE register
13627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @stmpe:	Device to read from
13727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @reg:	Register to read
13827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent */
13927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentint stmpe_reg_read(struct stmpe *stmpe, u8 reg)
14027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
14127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int ret;
14227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
14327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_lock(&stmpe->lock);
14427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	ret = __stmpe_reg_read(stmpe, reg);
14527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_unlock(&stmpe->lock);
14627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
14727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return ret;
14827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
14927e34995e1a863c1e9beba30e51dfe2a083f918dRabin VincentEXPORT_SYMBOL_GPL(stmpe_reg_read);
15027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
15127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent/**
15227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * stmpe_reg_write() - write a single STMPE register
15327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @stmpe:	Device to write to
15427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @reg:	Register to write
15527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @val:	Value to write
15627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent */
15727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentint stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val)
15827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
15927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int ret;
16027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
16127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_lock(&stmpe->lock);
16227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	ret = __stmpe_reg_write(stmpe, reg, val);
16327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_unlock(&stmpe->lock);
16427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
16527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return ret;
16627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
16727e34995e1a863c1e9beba30e51dfe2a083f918dRabin VincentEXPORT_SYMBOL_GPL(stmpe_reg_write);
16827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
16927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent/**
17027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * stmpe_set_bits() - set the value of a bitfield in a STMPE register
17127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @stmpe:	Device to write to
17227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @reg:	Register to write
17327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @mask:	Mask of bits to set
17427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @val:	Value to set
17527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent */
17627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentint stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val)
17727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
17827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int ret;
17927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
18027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_lock(&stmpe->lock);
18127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	ret = __stmpe_set_bits(stmpe, reg, mask, val);
18227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_unlock(&stmpe->lock);
18327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
18427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return ret;
18527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
18627e34995e1a863c1e9beba30e51dfe2a083f918dRabin VincentEXPORT_SYMBOL_GPL(stmpe_set_bits);
18727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
18827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent/**
18927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * stmpe_block_read() - read multiple STMPE registers
19027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @stmpe:	Device to read from
19127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @reg:	First register
19227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @length:	Number of registers
19327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @values:	Buffer to write to
19427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent */
19527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentint stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values)
19627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
19727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int ret;
19827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
19927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_lock(&stmpe->lock);
20027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	ret = __stmpe_block_read(stmpe, reg, length, values);
20127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_unlock(&stmpe->lock);
20227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
20327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return ret;
20427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
20527e34995e1a863c1e9beba30e51dfe2a083f918dRabin VincentEXPORT_SYMBOL_GPL(stmpe_block_read);
20627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
20727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent/**
20827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * stmpe_block_write() - write multiple STMPE registers
20927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @stmpe:	Device to write to
21027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @reg:	First register
21127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @length:	Number of registers
21227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @values:	Values to write
21327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent */
21427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentint stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length,
21527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		      const u8 *values)
21627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
21727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int ret;
21827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
21927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_lock(&stmpe->lock);
22027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	ret = __stmpe_block_write(stmpe, reg, length, values);
22127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_unlock(&stmpe->lock);
22227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
22327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return ret;
22427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
22527e34995e1a863c1e9beba30e51dfe2a083f918dRabin VincentEXPORT_SYMBOL_GPL(stmpe_block_write);
22627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
22727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent/**
2284dcaa6b6df354fa44b3072bed3cb13aad7e5fbd4Om Prakash * stmpe_set_altfunc()- set the alternate function for STMPE pins
22927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @stmpe:	Device to configure
23027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @pins:	Bitmask of pins to affect
23127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @block:	block to enable alternate functions for
23227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent *
23327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * @pins is assumed to have a bit set for each of the bits whose alternate
23427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * function is to be changed, numbered according to the GPIOXY numbers.
23527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent *
23627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * If the GPIO module is not enabled, this function automatically enables it in
23727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * order to perform the change.
23827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent */
23927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentint stmpe_set_altfunc(struct stmpe *stmpe, u32 pins, enum stmpe_block block)
24027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
24127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	struct stmpe_variant_info *variant = stmpe->variant;
24227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	u8 regaddr = stmpe->regs[STMPE_IDX_GPAFR_U_MSB];
24327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int af_bits = variant->af_bits;
24427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int numregs = DIV_ROUND_UP(stmpe->num_gpios * af_bits, 8);
24527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int mask = (1 << af_bits) - 1;
24627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	u8 regs[numregs];
2477f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	int af, afperreg, ret;
2487f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar
2497f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	if (!variant->get_altfunc)
2507f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar		return 0;
25127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
2527f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	afperreg = 8 / af_bits;
25327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_lock(&stmpe->lock);
25427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
25527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	ret = __stmpe_enable(stmpe, STMPE_BLOCK_GPIO);
25627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (ret < 0)
25727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		goto out;
25827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
25927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	ret = __stmpe_block_read(stmpe, regaddr, numregs, regs);
26027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (ret < 0)
26127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		goto out;
26227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
26327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	af = variant->get_altfunc(stmpe, block);
26427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
26527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	while (pins) {
26627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		int pin = __ffs(pins);
26727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		int regoffset = numregs - (pin / afperreg) - 1;
26827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		int pos = (pin % afperreg) * (8 / afperreg);
26927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
27027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		regs[regoffset] &= ~(mask << pos);
27127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		regs[regoffset] |= af << pos;
27227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
27327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		pins &= ~(1 << pin);
27427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	}
27527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
27627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	ret = __stmpe_block_write(stmpe, regaddr, numregs, regs);
27727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
27827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentout:
27927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_unlock(&stmpe->lock);
28027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return ret;
28127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
28227e34995e1a863c1e9beba30e51dfe2a083f918dRabin VincentEXPORT_SYMBOL_GPL(stmpe_set_altfunc);
28327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
28427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent/*
28527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * GPIO (all variants)
28627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent */
28727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
28827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic struct resource stmpe_gpio_resources[] = {
28927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	/* Start and end filled dynamically */
29027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	{
29127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.flags	= IORESOURCE_IRQ,
29227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	},
29327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent};
29427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
29527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic struct mfd_cell stmpe_gpio_cell = {
29627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.name		= "stmpe-gpio",
29727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.resources	= stmpe_gpio_resources,
29827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.num_resources	= ARRAY_SIZE(stmpe_gpio_resources),
29927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent};
30027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
30127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent/*
30227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * Keypad (1601, 2401, 2403)
30327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent */
30427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
30527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic struct resource stmpe_keypad_resources[] = {
30627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	{
30727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.name	= "KEYPAD",
30827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.start	= 0,
30927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.end	= 0,
31027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.flags	= IORESOURCE_IRQ,
31127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	},
31227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	{
31327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.name	= "KEYPAD_OVER",
31427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.start	= 1,
31527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.end	= 1,
31627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.flags	= IORESOURCE_IRQ,
31727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	},
31827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent};
31927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
32027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic struct mfd_cell stmpe_keypad_cell = {
32127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.name		= "stmpe-keypad",
32227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.resources	= stmpe_keypad_resources,
32327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.num_resources	= ARRAY_SIZE(stmpe_keypad_resources),
32427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent};
32527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
32627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent/*
3277f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar * STMPE801
3287f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar */
3297f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumarstatic const u8 stmpe801_regs[] = {
3307f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	[STMPE_IDX_CHIP_ID]	= STMPE801_REG_CHIP_ID,
3317f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	[STMPE_IDX_ICR_LSB]	= STMPE801_REG_SYS_CTRL,
3327f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	[STMPE_IDX_GPMR_LSB]	= STMPE801_REG_GPIO_MP_STA,
3337f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	[STMPE_IDX_GPSR_LSB]	= STMPE801_REG_GPIO_SET_PIN,
3347f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	[STMPE_IDX_GPCR_LSB]	= STMPE801_REG_GPIO_SET_PIN,
3357f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	[STMPE_IDX_GPDR_LSB]	= STMPE801_REG_GPIO_DIR,
3367f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	[STMPE_IDX_IEGPIOR_LSB] = STMPE801_REG_GPIO_INT_EN,
3377f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	[STMPE_IDX_ISGPIOR_MSB] = STMPE801_REG_GPIO_INT_STA,
3387f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar
3397f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar};
3407f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar
3417f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumarstatic struct stmpe_variant_block stmpe801_blocks[] = {
3427f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	{
3437f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar		.cell	= &stmpe_gpio_cell,
3447f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar		.irq	= 0,
3457f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar		.block	= STMPE_BLOCK_GPIO,
3467f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	},
3477f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar};
3487f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar
3497f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumarstatic int stmpe801_enable(struct stmpe *stmpe, unsigned int blocks,
3507f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar			   bool enable)
3517f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar{
3527f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	if (blocks & STMPE_BLOCK_GPIO)
3537f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar		return 0;
3547f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	else
3557f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar		return -EINVAL;
3567f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar}
3577f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar
3587f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumarstatic struct stmpe_variant_info stmpe801 = {
3597f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	.name		= "stmpe801",
3607f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	.id_val		= STMPE801_ID,
3617f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	.id_mask	= 0xffff,
3627f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	.num_gpios	= 8,
3637f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	.regs		= stmpe801_regs,
3647f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	.blocks		= stmpe801_blocks,
3657f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	.num_blocks	= ARRAY_SIZE(stmpe801_blocks),
3667f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	.num_irqs	= STMPE801_NR_INTERNAL_IRQS,
3677f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	.enable		= stmpe801_enable,
3687f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar};
3697f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar
3707f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar/*
3711cda2394e95415f1469ab8eaffd081395e112551Viresh Kumar * Touchscreen (STMPE811 or STMPE610)
37227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent */
37327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
37427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic struct resource stmpe_ts_resources[] = {
37527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	{
37627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.name	= "TOUCH_DET",
37727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.start	= 0,
37827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.end	= 0,
37927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.flags	= IORESOURCE_IRQ,
38027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	},
38127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	{
38227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.name	= "FIFO_TH",
38327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.start	= 1,
38427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.end	= 1,
38527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.flags	= IORESOURCE_IRQ,
38627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	},
38727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent};
38827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
38927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic struct mfd_cell stmpe_ts_cell = {
39027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.name		= "stmpe-ts",
39127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.resources	= stmpe_ts_resources,
39227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.num_resources	= ARRAY_SIZE(stmpe_ts_resources),
39327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent};
39427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
39527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent/*
3961cda2394e95415f1469ab8eaffd081395e112551Viresh Kumar * STMPE811 or STMPE610
39727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent */
39827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
39927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic const u8 stmpe811_regs[] = {
40027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_CHIP_ID]	= STMPE811_REG_CHIP_ID,
40127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_ICR_LSB]	= STMPE811_REG_INT_CTRL,
40227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_IER_LSB]	= STMPE811_REG_INT_EN,
40327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_ISR_MSB]	= STMPE811_REG_INT_STA,
40427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPMR_LSB]	= STMPE811_REG_GPIO_MP_STA,
40527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPSR_LSB]	= STMPE811_REG_GPIO_SET_PIN,
40627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPCR_LSB]	= STMPE811_REG_GPIO_CLR_PIN,
40727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPDR_LSB]	= STMPE811_REG_GPIO_DIR,
40827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPRER_LSB]	= STMPE811_REG_GPIO_RE,
40927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPFER_LSB]	= STMPE811_REG_GPIO_FE,
41027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPAFR_U_MSB]	= STMPE811_REG_GPIO_AF,
41127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_IEGPIOR_LSB]	= STMPE811_REG_GPIO_INT_EN,
41227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_ISGPIOR_MSB]	= STMPE811_REG_GPIO_INT_STA,
41327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPEDR_MSB]	= STMPE811_REG_GPIO_ED,
41427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent};
41527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
41627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic struct stmpe_variant_block stmpe811_blocks[] = {
41727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	{
41827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.cell	= &stmpe_gpio_cell,
41927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.irq	= STMPE811_IRQ_GPIOC,
42027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.block	= STMPE_BLOCK_GPIO,
42127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	},
42227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	{
42327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.cell	= &stmpe_ts_cell,
42427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.irq	= STMPE811_IRQ_TOUCH_DET,
42527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.block	= STMPE_BLOCK_TOUCHSCREEN,
42627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	},
42727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent};
42827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
42927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks,
43027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent			   bool enable)
43127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
43227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	unsigned int mask = 0;
43327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
43427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (blocks & STMPE_BLOCK_GPIO)
43527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		mask |= STMPE811_SYS_CTRL2_GPIO_OFF;
43627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
43727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (blocks & STMPE_BLOCK_ADC)
43827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		mask |= STMPE811_SYS_CTRL2_ADC_OFF;
43927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
44027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (blocks & STMPE_BLOCK_TOUCHSCREEN)
44127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		mask |= STMPE811_SYS_CTRL2_TSC_OFF;
44227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
44327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return __stmpe_set_bits(stmpe, STMPE811_REG_SYS_CTRL2, mask,
44427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent				enable ? 0 : mask);
44527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
44627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
44727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic int stmpe811_get_altfunc(struct stmpe *stmpe, enum stmpe_block block)
44827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
44927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	/* 0 for touchscreen, 1 for GPIO */
45027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return block != STMPE_BLOCK_TOUCHSCREEN;
45127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
45227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
45327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic struct stmpe_variant_info stmpe811 = {
45427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.name		= "stmpe811",
45527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.id_val		= 0x0811,
45627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.id_mask	= 0xffff,
45727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.num_gpios	= 8,
45827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.af_bits	= 1,
45927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.regs		= stmpe811_regs,
46027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.blocks		= stmpe811_blocks,
46127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.num_blocks	= ARRAY_SIZE(stmpe811_blocks),
46227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.num_irqs	= STMPE811_NR_INTERNAL_IRQS,
46327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.enable		= stmpe811_enable,
46427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.get_altfunc	= stmpe811_get_altfunc,
46527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent};
46627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
4671cda2394e95415f1469ab8eaffd081395e112551Viresh Kumar/* Similar to 811, except number of gpios */
4681cda2394e95415f1469ab8eaffd081395e112551Viresh Kumarstatic struct stmpe_variant_info stmpe610 = {
4691cda2394e95415f1469ab8eaffd081395e112551Viresh Kumar	.name		= "stmpe610",
4701cda2394e95415f1469ab8eaffd081395e112551Viresh Kumar	.id_val		= 0x0811,
4711cda2394e95415f1469ab8eaffd081395e112551Viresh Kumar	.id_mask	= 0xffff,
4721cda2394e95415f1469ab8eaffd081395e112551Viresh Kumar	.num_gpios	= 6,
4731cda2394e95415f1469ab8eaffd081395e112551Viresh Kumar	.af_bits	= 1,
4741cda2394e95415f1469ab8eaffd081395e112551Viresh Kumar	.regs		= stmpe811_regs,
4751cda2394e95415f1469ab8eaffd081395e112551Viresh Kumar	.blocks		= stmpe811_blocks,
4761cda2394e95415f1469ab8eaffd081395e112551Viresh Kumar	.num_blocks	= ARRAY_SIZE(stmpe811_blocks),
4771cda2394e95415f1469ab8eaffd081395e112551Viresh Kumar	.num_irqs	= STMPE811_NR_INTERNAL_IRQS,
4781cda2394e95415f1469ab8eaffd081395e112551Viresh Kumar	.enable		= stmpe811_enable,
4791cda2394e95415f1469ab8eaffd081395e112551Viresh Kumar	.get_altfunc	= stmpe811_get_altfunc,
4801cda2394e95415f1469ab8eaffd081395e112551Viresh Kumar};
4811cda2394e95415f1469ab8eaffd081395e112551Viresh Kumar
48227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent/*
48327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * STMPE1601
48427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent */
48527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
48627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic const u8 stmpe1601_regs[] = {
48727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_CHIP_ID]	= STMPE1601_REG_CHIP_ID,
48827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_ICR_LSB]	= STMPE1601_REG_ICR_LSB,
48927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_IER_LSB]	= STMPE1601_REG_IER_LSB,
49027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_ISR_MSB]	= STMPE1601_REG_ISR_MSB,
49127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPMR_LSB]	= STMPE1601_REG_GPIO_MP_LSB,
49227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPSR_LSB]	= STMPE1601_REG_GPIO_SET_LSB,
49327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPCR_LSB]	= STMPE1601_REG_GPIO_CLR_LSB,
49427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPDR_LSB]	= STMPE1601_REG_GPIO_SET_DIR_LSB,
49527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPRER_LSB]	= STMPE1601_REG_GPIO_RE_LSB,
49627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPFER_LSB]	= STMPE1601_REG_GPIO_FE_LSB,
49727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPAFR_U_MSB]	= STMPE1601_REG_GPIO_AF_U_MSB,
49827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_IEGPIOR_LSB]	= STMPE1601_REG_INT_EN_GPIO_MASK_LSB,
49927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_ISGPIOR_MSB]	= STMPE1601_REG_INT_STA_GPIO_MSB,
50027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPEDR_MSB]	= STMPE1601_REG_GPIO_ED_MSB,
50127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent};
50227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
50327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic struct stmpe_variant_block stmpe1601_blocks[] = {
50427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	{
50527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.cell	= &stmpe_gpio_cell,
50627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.irq	= STMPE24XX_IRQ_GPIOC,
50727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.block	= STMPE_BLOCK_GPIO,
50827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	},
50927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	{
51027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.cell	= &stmpe_keypad_cell,
51127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.irq	= STMPE24XX_IRQ_KEYPAD,
51227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.block	= STMPE_BLOCK_KEYPAD,
51327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	},
51427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent};
51527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
5165981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer/* supported autosleep timeout delay (in msecs) */
5175981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyerstatic const int stmpe_autosleep_delay[] = {
5185981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	4, 16, 32, 64, 128, 256, 512, 1024,
5195981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer};
5205981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer
5215981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyerstatic int stmpe_round_timeout(int timeout)
5225981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer{
5235981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	int i;
5245981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer
5255981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	for (i = 0; i < ARRAY_SIZE(stmpe_autosleep_delay); i++) {
5265981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer		if (stmpe_autosleep_delay[i] >= timeout)
5275981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer			return i;
5285981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	}
5295981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer
5305981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	/*
5315981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	 * requests for delays longer than supported should not return the
5325981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	 * longest supported delay
5335981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	 */
5345981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	return -EINVAL;
5355981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer}
5365981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer
5375981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyerstatic int stmpe_autosleep(struct stmpe *stmpe, int autosleep_timeout)
5385981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer{
5395981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	int ret;
5405981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer
5415981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	if (!stmpe->variant->enable_autosleep)
5425981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer		return -ENOSYS;
5435981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer
5445981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	mutex_lock(&stmpe->lock);
5455981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	ret = stmpe->variant->enable_autosleep(stmpe, autosleep_timeout);
5465981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	mutex_unlock(&stmpe->lock);
5475981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer
5485981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	return ret;
5495981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer}
5505981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer
5515981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer/*
5525981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer * Both stmpe 1601/2403 support same layout for autosleep
5535981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer */
5545981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyerstatic int stmpe1601_autosleep(struct stmpe *stmpe,
5555981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer		int autosleep_timeout)
5565981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer{
5575981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	int ret, timeout;
5585981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer
5595981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	/* choose the best available timeout */
5605981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	timeout = stmpe_round_timeout(autosleep_timeout);
5615981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	if (timeout < 0) {
5625981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer		dev_err(stmpe->dev, "invalid timeout\n");
5635981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer		return timeout;
5645981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	}
5655981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer
5665981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	ret = __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL2,
5675981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer			STMPE1601_AUTOSLEEP_TIMEOUT_MASK,
5685981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer			timeout);
5695981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	if (ret < 0)
5705981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer		return ret;
5715981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer
5725981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	return __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL2,
5735981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer			STPME1601_AUTOSLEEP_ENABLE,
5745981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer			STPME1601_AUTOSLEEP_ENABLE);
5755981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer}
5765981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer
57727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic int stmpe1601_enable(struct stmpe *stmpe, unsigned int blocks,
57827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent			    bool enable)
57927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
58027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	unsigned int mask = 0;
58127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
58227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (blocks & STMPE_BLOCK_GPIO)
58327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		mask |= STMPE1601_SYS_CTRL_ENABLE_GPIO;
58427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
58527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (blocks & STMPE_BLOCK_KEYPAD)
58627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		mask |= STMPE1601_SYS_CTRL_ENABLE_KPC;
58727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
58827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL, mask,
58927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent				enable ? mask : 0);
59027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
59127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
59227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic int stmpe1601_get_altfunc(struct stmpe *stmpe, enum stmpe_block block)
59327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
59427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	switch (block) {
59527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	case STMPE_BLOCK_PWM:
59627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		return 2;
59727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
59827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	case STMPE_BLOCK_KEYPAD:
59927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		return 1;
60027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
60127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	case STMPE_BLOCK_GPIO:
60227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	default:
60327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		return 0;
60427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	}
60527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
60627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
60727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic struct stmpe_variant_info stmpe1601 = {
60827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.name		= "stmpe1601",
60927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.id_val		= 0x0210,
61027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.id_mask	= 0xfff0,	/* at least 0x0210 and 0x0212 */
61127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.num_gpios	= 16,
61227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.af_bits	= 2,
61327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.regs		= stmpe1601_regs,
61427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.blocks		= stmpe1601_blocks,
61527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.num_blocks	= ARRAY_SIZE(stmpe1601_blocks),
61627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.num_irqs	= STMPE1601_NR_INTERNAL_IRQS,
61727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.enable		= stmpe1601_enable,
61827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.get_altfunc	= stmpe1601_get_altfunc,
6195981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	.enable_autosleep	= stmpe1601_autosleep,
62027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent};
62127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
62227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent/*
62327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent * STMPE24XX
62427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent */
62527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
62627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic const u8 stmpe24xx_regs[] = {
62727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_CHIP_ID]	= STMPE24XX_REG_CHIP_ID,
62827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_ICR_LSB]	= STMPE24XX_REG_ICR_LSB,
62927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_IER_LSB]	= STMPE24XX_REG_IER_LSB,
63027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_ISR_MSB]	= STMPE24XX_REG_ISR_MSB,
63127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPMR_LSB]	= STMPE24XX_REG_GPMR_LSB,
63227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPSR_LSB]	= STMPE24XX_REG_GPSR_LSB,
63327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPCR_LSB]	= STMPE24XX_REG_GPCR_LSB,
63427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPDR_LSB]	= STMPE24XX_REG_GPDR_LSB,
63527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPRER_LSB]	= STMPE24XX_REG_GPRER_LSB,
63627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPFER_LSB]	= STMPE24XX_REG_GPFER_LSB,
63727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPAFR_U_MSB]	= STMPE24XX_REG_GPAFR_U_MSB,
63827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_IEGPIOR_LSB]	= STMPE24XX_REG_IEGPIOR_LSB,
63927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_ISGPIOR_MSB]	= STMPE24XX_REG_ISGPIOR_MSB,
64027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE_IDX_GPEDR_MSB]	= STMPE24XX_REG_GPEDR_MSB,
64127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent};
64227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
64327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic struct stmpe_variant_block stmpe24xx_blocks[] = {
64427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	{
64527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.cell	= &stmpe_gpio_cell,
64627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.irq	= STMPE24XX_IRQ_GPIOC,
64727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.block	= STMPE_BLOCK_GPIO,
64827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	},
64927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	{
65027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.cell	= &stmpe_keypad_cell,
65127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.irq	= STMPE24XX_IRQ_KEYPAD,
65227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		.block	= STMPE_BLOCK_KEYPAD,
65327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	},
65427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent};
65527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
65627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic int stmpe24xx_enable(struct stmpe *stmpe, unsigned int blocks,
65727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent			    bool enable)
65827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
65927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	unsigned int mask = 0;
66027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
66127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (blocks & STMPE_BLOCK_GPIO)
66227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		mask |= STMPE24XX_SYS_CTRL_ENABLE_GPIO;
66327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
66427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (blocks & STMPE_BLOCK_KEYPAD)
66527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		mask |= STMPE24XX_SYS_CTRL_ENABLE_KPC;
66627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
66727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return __stmpe_set_bits(stmpe, STMPE24XX_REG_SYS_CTRL, mask,
66827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent				enable ? mask : 0);
66927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
67027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
67127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic int stmpe24xx_get_altfunc(struct stmpe *stmpe, enum stmpe_block block)
67227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
67327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	switch (block) {
67427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	case STMPE_BLOCK_ROTATOR:
67527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		return 2;
67627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
67727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	case STMPE_BLOCK_KEYPAD:
67827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		return 1;
67927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
68027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	case STMPE_BLOCK_GPIO:
68127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	default:
68227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		return 0;
68327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	}
68427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
68527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
68627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic struct stmpe_variant_info stmpe2401 = {
68727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.name		= "stmpe2401",
68827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.id_val		= 0x0101,
68927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.id_mask	= 0xffff,
69027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.num_gpios	= 24,
69127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.af_bits	= 2,
69227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.regs		= stmpe24xx_regs,
69327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.blocks		= stmpe24xx_blocks,
69427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.num_blocks	= ARRAY_SIZE(stmpe24xx_blocks),
69527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.num_irqs	= STMPE24XX_NR_INTERNAL_IRQS,
69627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.enable		= stmpe24xx_enable,
69727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.get_altfunc	= stmpe24xx_get_altfunc,
69827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent};
69927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
70027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic struct stmpe_variant_info stmpe2403 = {
70127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.name		= "stmpe2403",
70227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.id_val		= 0x0120,
70327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.id_mask	= 0xffff,
70427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.num_gpios	= 24,
70527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.af_bits	= 2,
70627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.regs		= stmpe24xx_regs,
70727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.blocks		= stmpe24xx_blocks,
70827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.num_blocks	= ARRAY_SIZE(stmpe24xx_blocks),
70927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.num_irqs	= STMPE24XX_NR_INTERNAL_IRQS,
71027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.enable		= stmpe24xx_enable,
71127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.get_altfunc	= stmpe24xx_get_altfunc,
7125981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	.enable_autosleep	= stmpe1601_autosleep, /* same as stmpe1601 */
71327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent};
71427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
71527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic struct stmpe_variant_info *stmpe_variant_info[] = {
7161cda2394e95415f1469ab8eaffd081395e112551Viresh Kumar	[STMPE610]	= &stmpe610,
7177f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	[STMPE801]	= &stmpe801,
71827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE811]	= &stmpe811,
71927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE1601]	= &stmpe1601,
72027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE2401]	= &stmpe2401,
72127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	[STMPE2403]	= &stmpe2403,
72227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent};
72327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
72427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic irqreturn_t stmpe_irq(int irq, void *data)
72527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
72627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	struct stmpe *stmpe = data;
72727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	struct stmpe_variant_info *variant = stmpe->variant;
72827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int num = DIV_ROUND_UP(variant->num_irqs, 8);
72927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	u8 israddr = stmpe->regs[STMPE_IDX_ISR_MSB];
73027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	u8 isr[num];
73127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int ret;
73227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int i;
73327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
7347f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	if (variant->id_val == STMPE801_ID) {
7357f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar		handle_nested_irq(stmpe->irq_base);
7367f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar		return IRQ_HANDLED;
7377f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	}
7387f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar
73927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	ret = stmpe_block_read(stmpe, israddr, num, isr);
74027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (ret < 0)
74127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		return IRQ_NONE;
74227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
74327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	for (i = 0; i < num; i++) {
74427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		int bank = num - i - 1;
74527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		u8 status = isr[i];
74627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		u8 clear;
74727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
74827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		status &= stmpe->ier[bank];
74927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		if (!status)
75027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent			continue;
75127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
75227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		clear = status;
75327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		while (status) {
75427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent			int bit = __ffs(status);
75527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent			int line = bank * 8 + bit;
75627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
75727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent			handle_nested_irq(stmpe->irq_base + line);
75827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent			status &= ~(1 << bit);
75927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		}
76027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
76127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		stmpe_reg_write(stmpe, israddr + i, clear);
76227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	}
76327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
76427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return IRQ_HANDLED;
76527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
76627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
76743b8c08402de2fb85cd18ebc746b598ce2473664Mark Brownstatic void stmpe_irq_lock(struct irq_data *data)
76827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
76943b8c08402de2fb85cd18ebc746b598ce2473664Mark Brown	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
77027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
77127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_lock(&stmpe->irq_lock);
77227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
77327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
77443b8c08402de2fb85cd18ebc746b598ce2473664Mark Brownstatic void stmpe_irq_sync_unlock(struct irq_data *data)
77527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
77643b8c08402de2fb85cd18ebc746b598ce2473664Mark Brown	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
77727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	struct stmpe_variant_info *variant = stmpe->variant;
77827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int num = DIV_ROUND_UP(variant->num_irqs, 8);
77927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int i;
78027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
78127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	for (i = 0; i < num; i++) {
78227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		u8 new = stmpe->ier[i];
78327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		u8 old = stmpe->oldier[i];
78427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
78527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		if (new == old)
78627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent			continue;
78727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
78827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		stmpe->oldier[i] = new;
78927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_IER_LSB] - i, new);
79027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	}
79127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
79227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_unlock(&stmpe->irq_lock);
79327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
79427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
79543b8c08402de2fb85cd18ebc746b598ce2473664Mark Brownstatic void stmpe_irq_mask(struct irq_data *data)
79627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
79743b8c08402de2fb85cd18ebc746b598ce2473664Mark Brown	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
79843b8c08402de2fb85cd18ebc746b598ce2473664Mark Brown	int offset = data->irq - stmpe->irq_base;
79927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int regoffset = offset / 8;
80027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int mask = 1 << (offset % 8);
80127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
80227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	stmpe->ier[regoffset] &= ~mask;
80327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
80427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
80543b8c08402de2fb85cd18ebc746b598ce2473664Mark Brownstatic void stmpe_irq_unmask(struct irq_data *data)
80627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
80743b8c08402de2fb85cd18ebc746b598ce2473664Mark Brown	struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
80843b8c08402de2fb85cd18ebc746b598ce2473664Mark Brown	int offset = data->irq - stmpe->irq_base;
80927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int regoffset = offset / 8;
81027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int mask = 1 << (offset % 8);
81127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
81227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	stmpe->ier[regoffset] |= mask;
81327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
81427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
81527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic struct irq_chip stmpe_irq_chip = {
81627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	.name			= "stmpe",
81743b8c08402de2fb85cd18ebc746b598ce2473664Mark Brown	.irq_bus_lock		= stmpe_irq_lock,
81843b8c08402de2fb85cd18ebc746b598ce2473664Mark Brown	.irq_bus_sync_unlock	= stmpe_irq_sync_unlock,
81943b8c08402de2fb85cd18ebc746b598ce2473664Mark Brown	.irq_mask		= stmpe_irq_mask,
82043b8c08402de2fb85cd18ebc746b598ce2473664Mark Brown	.irq_unmask		= stmpe_irq_unmask,
82127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent};
82227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
82327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic int __devinit stmpe_irq_init(struct stmpe *stmpe)
82427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
8257f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	struct irq_chip *chip = NULL;
82627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int num_irqs = stmpe->variant->num_irqs;
82727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int base = stmpe->irq_base;
82827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int irq;
82927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
8307f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	if (stmpe->variant->id_val != STMPE801_ID)
8317f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar		chip = &stmpe_irq_chip;
8327f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar
83327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	for (irq = base; irq < base + num_irqs; irq++) {
834d5bb122165981aed327845c32a9916d1b8ae0e4bThomas Gleixner		irq_set_chip_data(irq, stmpe);
8357f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar		irq_set_chip_and_handler(irq, chip, handle_edge_irq);
836d5bb122165981aed327845c32a9916d1b8ae0e4bThomas Gleixner		irq_set_nested_thread(irq, 1);
83727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent#ifdef CONFIG_ARM
83827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		set_irq_flags(irq, IRQF_VALID);
83927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent#else
840d5bb122165981aed327845c32a9916d1b8ae0e4bThomas Gleixner		irq_set_noprobe(irq);
84127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent#endif
84227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	}
84327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
84427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return 0;
84527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
84627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
84727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic void stmpe_irq_remove(struct stmpe *stmpe)
84827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
84927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int num_irqs = stmpe->variant->num_irqs;
85027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int base = stmpe->irq_base;
85127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int irq;
85227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
85327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	for (irq = base; irq < base + num_irqs; irq++) {
85427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent#ifdef CONFIG_ARM
85527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		set_irq_flags(irq, 0);
85627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent#endif
857d5bb122165981aed327845c32a9916d1b8ae0e4bThomas Gleixner		irq_set_chip_and_handler(irq, NULL, NULL);
858d5bb122165981aed327845c32a9916d1b8ae0e4bThomas Gleixner		irq_set_chip_data(irq, NULL);
85927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	}
86027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
86127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
86227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic int __devinit stmpe_chip_init(struct stmpe *stmpe)
86327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
86427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	unsigned int irq_trigger = stmpe->pdata->irq_trigger;
8655981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	int autosleep_timeout = stmpe->pdata->autosleep_timeout;
86627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	struct stmpe_variant_info *variant = stmpe->variant;
8677f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	u8 icr;
86827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	unsigned int id;
86927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	u8 data[2];
87027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int ret;
87127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
87227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	ret = stmpe_block_read(stmpe, stmpe->regs[STMPE_IDX_CHIP_ID],
87327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent			       ARRAY_SIZE(data), data);
87427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (ret < 0)
87527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		return ret;
87627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
87727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	id = (data[0] << 8) | data[1];
87827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if ((id & variant->id_mask) != variant->id_val) {
87927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		dev_err(stmpe->dev, "unknown chip id: %#x\n", id);
88027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		return -EINVAL;
88127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	}
88227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
88327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	dev_info(stmpe->dev, "%s detected, chip id: %#x\n", variant->name, id);
88427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
88527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	/* Disable all modules -- subdrivers should enable what they need. */
88627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	ret = stmpe_disable(stmpe, ~0);
88727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (ret)
88827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		return ret;
88927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
8907f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	if (id == STMPE801_ID)
8917f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar		icr = STMPE801_REG_SYS_CTRL_INT_EN;
8927f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	else
8937f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar		icr = STMPE_ICR_LSB_GIM;
8947f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar
8957f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	/* STMPE801 doesn't support Edge interrupts */
8967f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	if (id != STMPE801_ID) {
8977f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar		if (irq_trigger == IRQF_TRIGGER_FALLING ||
8987f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar				irq_trigger == IRQF_TRIGGER_RISING)
8997f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar			icr |= STMPE_ICR_LSB_EDGE;
9007f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	}
90127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
90227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (irq_trigger == IRQF_TRIGGER_RISING ||
9037f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar			irq_trigger == IRQF_TRIGGER_HIGH) {
9047f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar		if (id == STMPE801_ID)
9057f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar			icr |= STMPE801_REG_SYS_CTRL_INT_HI;
9067f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar		else
9077f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar			icr |= STMPE_ICR_LSB_HIGH;
9087f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	}
90927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
9107f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	if (stmpe->pdata->irq_invert_polarity) {
9117f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar		if (id == STMPE801_ID)
9127f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar			icr ^= STMPE801_REG_SYS_CTRL_INT_HI;
9137f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar		else
9147f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar			icr ^= STMPE_ICR_LSB_HIGH;
9157f7f4ea15ef4645f3888310a7a761fc2c4f689c9Viresh Kumar	}
91627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
9175981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	if (stmpe->pdata->autosleep) {
9185981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer		ret = stmpe_autosleep(stmpe, autosleep_timeout);
9195981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer		if (ret)
9205981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer			return ret;
9215981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer	}
9225981f4e65cb455a820b3d07b8e4bac506233f3eaSundar R Iyer
92327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_ICR_LSB], icr);
92427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
92527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
92627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic int __devinit stmpe_add_device(struct stmpe *stmpe,
92727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent				      struct mfd_cell *cell, int irq)
92827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
92927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1,
93027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent			       NULL, stmpe->irq_base + irq);
93127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
93227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
93327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentstatic int __devinit stmpe_devices_init(struct stmpe *stmpe)
93427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
93527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	struct stmpe_variant_info *variant = stmpe->variant;
93627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	unsigned int platform_blocks = stmpe->pdata->blocks;
93727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int ret = -EINVAL;
93827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int i;
93927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
94027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	for (i = 0; i < variant->num_blocks; i++) {
94127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		struct stmpe_variant_block *block = &variant->blocks[i];
94227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
94327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		if (!(platform_blocks & block->block))
94427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent			continue;
94527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
94627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		platform_blocks &= ~block->block;
94727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		ret = stmpe_add_device(stmpe, block->cell, block->irq);
94827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		if (ret)
94927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent			return ret;
95027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	}
95127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
95227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (platform_blocks)
95327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		dev_warn(stmpe->dev,
95427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent			 "platform wants blocks (%#x) not present on variant",
95527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent			 platform_blocks);
95627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
95727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return ret;
95827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
95927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
9601a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar/* Called from client specific probe routines */
9618ad1a973f9a9aad8e170419581a8e98a0f8d1e19Samuel Ortizint __devinit stmpe_probe(struct stmpe_client_info *ci, int partnum)
962208c4343192c052048ddf096d8e189162e5ee219Sundar Iyer{
9631a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	struct stmpe_platform_data *pdata = dev_get_platdata(ci->dev);
96427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	struct stmpe *stmpe;
96527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	int ret;
96627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
96727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (!pdata)
96827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		return -EINVAL;
96927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
97027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	stmpe = kzalloc(sizeof(struct stmpe), GFP_KERNEL);
97127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (!stmpe)
97227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		return -ENOMEM;
97327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
97427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_init(&stmpe->irq_lock);
97527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mutex_init(&stmpe->lock);
97627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
9771a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	stmpe->dev = ci->dev;
9781a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	stmpe->client = ci->client;
97927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	stmpe->pdata = pdata;
98027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	stmpe->irq_base = pdata->irq_base;
9811a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	stmpe->ci = ci;
9821a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	stmpe->partnum = partnum;
9831a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	stmpe->variant = stmpe_variant_info[partnum];
98427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	stmpe->regs = stmpe->variant->regs;
98527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	stmpe->num_gpios = stmpe->variant->num_gpios;
9861a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	dev_set_drvdata(stmpe->dev, stmpe);
98727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
9881a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	if (ci->init)
9891a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar		ci->init(stmpe);
99027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
99173de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar	if (pdata->irq_over_gpio) {
99273de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar		ret = gpio_request_one(pdata->irq_gpio, GPIOF_DIR_IN, "stmpe");
99373de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar		if (ret) {
99473de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar			dev_err(stmpe->dev, "failed to request IRQ GPIO: %d\n",
99573de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar					ret);
99673de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar			goto out_free;
99773de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar		}
99873de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar
99973de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar		stmpe->irq = gpio_to_irq(pdata->irq_gpio);
100073de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar	} else {
10011a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar		stmpe->irq = ci->irq;
100273de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar	}
100373de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar
100427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	ret = stmpe_chip_init(stmpe);
100527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (ret)
100673de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar		goto free_gpio;
100727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
100827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	ret = stmpe_irq_init(stmpe);
100927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (ret)
101073de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar		goto free_gpio;
101127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
101273de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar	ret = request_threaded_irq(stmpe->irq, NULL, stmpe_irq,
10131a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar			pdata->irq_trigger | IRQF_ONESHOT, "stmpe", stmpe);
101427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (ret) {
101527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		dev_err(stmpe->dev, "failed to request IRQ: %d\n", ret);
101627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		goto out_removeirq;
101727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	}
101827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
101927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	ret = stmpe_devices_init(stmpe);
102027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	if (ret) {
102127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		dev_err(stmpe->dev, "failed to add children\n");
102227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent		goto out_removedevs;
102327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	}
102427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
102527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return 0;
102627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
102727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentout_removedevs:
102827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mfd_remove_devices(stmpe->dev);
102973de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar	free_irq(stmpe->irq, stmpe);
103027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentout_removeirq:
103127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	stmpe_irq_remove(stmpe);
103273de16db43f8dcb833ab032ed274b60b23676680Viresh Kumarfree_gpio:
103373de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar	if (pdata->irq_over_gpio)
103473de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar		gpio_free(pdata->irq_gpio);
103527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincentout_free:
103627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	kfree(stmpe);
103727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return ret;
103827e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
103927e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
10401a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumarint stmpe_remove(struct stmpe *stmpe)
104127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
104227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	mfd_remove_devices(stmpe->dev);
104327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
104473de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar	free_irq(stmpe->irq, stmpe);
104527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	stmpe_irq_remove(stmpe);
104627e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
104773de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar	if (stmpe->pdata->irq_over_gpio)
104873de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar		gpio_free(stmpe->pdata->irq_gpio);
104973de16db43f8dcb833ab032ed274b60b23676680Viresh Kumar
105027e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	kfree(stmpe);
105127e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
105227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent	return 0;
105327e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
105427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
1055208c4343192c052048ddf096d8e189162e5ee219Sundar Iyer#ifdef CONFIG_PM
10561a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumarstatic int stmpe_suspend(struct device *dev)
10571a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar{
10581a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	struct stmpe *stmpe = dev_get_drvdata(dev);
1059208c4343192c052048ddf096d8e189162e5ee219Sundar Iyer
10601a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	if (device_may_wakeup(dev))
10611a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar		enable_irq_wake(stmpe->irq);
106227e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
10631a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	return 0;
106427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
106527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
10661a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumarstatic int stmpe_resume(struct device *dev)
106727e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent{
10681a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	struct stmpe *stmpe = dev_get_drvdata(dev);
10691a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar
10701a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	if (device_may_wakeup(dev))
10711a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar		disable_irq_wake(stmpe->irq);
10721a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar
10731a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	return 0;
107427e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent}
107527e34995e1a863c1e9beba30e51dfe2a083f918dRabin Vincent
10761a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumarconst struct dev_pm_ops stmpe_dev_pm_ops = {
10771a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	.suspend	= stmpe_suspend,
10781a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar	.resume		= stmpe_resume,
10791a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar};
10801a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumar#endif
1081