stmpe.c revision dba61c8f4fd14c4cbf375f6cdc814da87722d825
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 */ 9611a6e4b7415339e3b11a87cff0d701b8a2e55f062Viresh Kumarint 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