127e34995SRabin Vincent /* 21a6e4b74SViresh Kumar * ST Microelectronics MFD: stmpe's driver 31a6e4b74SViresh Kumar * 427e34995SRabin Vincent * Copyright (C) ST-Ericsson SA 2010 527e34995SRabin Vincent * 627e34995SRabin Vincent * License Terms: GNU General Public License, version 2 727e34995SRabin Vincent * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson 827e34995SRabin Vincent */ 927e34995SRabin Vincent 1073de16dbSViresh Kumar #include <linux/gpio.h> 11dba61c8fSSamuel Ortiz #include <linux/export.h> 1227e34995SRabin Vincent #include <linux/kernel.h> 1327e34995SRabin Vincent #include <linux/interrupt.h> 1427e34995SRabin Vincent #include <linux/irq.h> 1576f93992SLee Jones #include <linux/irqdomain.h> 161a6e4b74SViresh Kumar #include <linux/pm.h> 1727e34995SRabin Vincent #include <linux/slab.h> 1827e34995SRabin Vincent #include <linux/mfd/core.h> 1927e34995SRabin Vincent #include "stmpe.h" 2027e34995SRabin Vincent 2127e34995SRabin Vincent static int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks) 2227e34995SRabin Vincent { 2327e34995SRabin Vincent return stmpe->variant->enable(stmpe, blocks, true); 2427e34995SRabin Vincent } 2527e34995SRabin Vincent 2627e34995SRabin Vincent static int __stmpe_disable(struct stmpe *stmpe, unsigned int blocks) 2727e34995SRabin Vincent { 2827e34995SRabin Vincent return stmpe->variant->enable(stmpe, blocks, false); 2927e34995SRabin Vincent } 3027e34995SRabin Vincent 3127e34995SRabin Vincent static int __stmpe_reg_read(struct stmpe *stmpe, u8 reg) 3227e34995SRabin Vincent { 3327e34995SRabin Vincent int ret; 3427e34995SRabin Vincent 351a6e4b74SViresh Kumar ret = stmpe->ci->read_byte(stmpe, reg); 3627e34995SRabin Vincent if (ret < 0) 371a6e4b74SViresh Kumar dev_err(stmpe->dev, "failed to read reg %#x: %d\n", reg, ret); 3827e34995SRabin Vincent 3927e34995SRabin Vincent dev_vdbg(stmpe->dev, "rd: reg %#x => data %#x\n", reg, ret); 4027e34995SRabin Vincent 4127e34995SRabin Vincent return ret; 4227e34995SRabin Vincent } 4327e34995SRabin Vincent 4427e34995SRabin Vincent static int __stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val) 4527e34995SRabin Vincent { 4627e34995SRabin Vincent int ret; 4727e34995SRabin Vincent 4827e34995SRabin Vincent dev_vdbg(stmpe->dev, "wr: reg %#x <= %#x\n", reg, val); 4927e34995SRabin Vincent 501a6e4b74SViresh Kumar ret = stmpe->ci->write_byte(stmpe, reg, val); 5127e34995SRabin Vincent if (ret < 0) 521a6e4b74SViresh Kumar dev_err(stmpe->dev, "failed to write reg %#x: %d\n", reg, ret); 5327e34995SRabin Vincent 5427e34995SRabin Vincent return ret; 5527e34995SRabin Vincent } 5627e34995SRabin Vincent 5727e34995SRabin Vincent static int __stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val) 5827e34995SRabin Vincent { 5927e34995SRabin Vincent int ret; 6027e34995SRabin Vincent 6127e34995SRabin Vincent ret = __stmpe_reg_read(stmpe, reg); 6227e34995SRabin Vincent if (ret < 0) 6327e34995SRabin Vincent return ret; 6427e34995SRabin Vincent 6527e34995SRabin Vincent ret &= ~mask; 6627e34995SRabin Vincent ret |= val; 6727e34995SRabin Vincent 6827e34995SRabin Vincent return __stmpe_reg_write(stmpe, reg, ret); 6927e34995SRabin Vincent } 7027e34995SRabin Vincent 7127e34995SRabin Vincent static int __stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length, 7227e34995SRabin Vincent u8 *values) 7327e34995SRabin Vincent { 7427e34995SRabin Vincent int ret; 7527e34995SRabin Vincent 761a6e4b74SViresh Kumar ret = stmpe->ci->read_block(stmpe, reg, length, values); 7727e34995SRabin Vincent if (ret < 0) 781a6e4b74SViresh Kumar dev_err(stmpe->dev, "failed to read regs %#x: %d\n", reg, ret); 7927e34995SRabin Vincent 8027e34995SRabin Vincent dev_vdbg(stmpe->dev, "rd: reg %#x (%d) => ret %#x\n", reg, length, ret); 8127e34995SRabin Vincent stmpe_dump_bytes("stmpe rd: ", values, length); 8227e34995SRabin Vincent 8327e34995SRabin Vincent return ret; 8427e34995SRabin Vincent } 8527e34995SRabin Vincent 8627e34995SRabin Vincent static int __stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length, 8727e34995SRabin Vincent const u8 *values) 8827e34995SRabin Vincent { 8927e34995SRabin Vincent int ret; 9027e34995SRabin Vincent 9127e34995SRabin Vincent dev_vdbg(stmpe->dev, "wr: regs %#x (%d)\n", reg, length); 9227e34995SRabin Vincent stmpe_dump_bytes("stmpe wr: ", values, length); 9327e34995SRabin Vincent 941a6e4b74SViresh Kumar ret = stmpe->ci->write_block(stmpe, reg, length, values); 9527e34995SRabin Vincent if (ret < 0) 961a6e4b74SViresh Kumar dev_err(stmpe->dev, "failed to write regs %#x: %d\n", reg, ret); 9727e34995SRabin Vincent 9827e34995SRabin Vincent return ret; 9927e34995SRabin Vincent } 10027e34995SRabin Vincent 10127e34995SRabin Vincent /** 10227e34995SRabin Vincent * stmpe_enable - enable blocks on an STMPE device 10327e34995SRabin Vincent * @stmpe: Device to work on 10427e34995SRabin Vincent * @blocks: Mask of blocks (enum stmpe_block values) to enable 10527e34995SRabin Vincent */ 10627e34995SRabin Vincent int stmpe_enable(struct stmpe *stmpe, unsigned int blocks) 10727e34995SRabin Vincent { 10827e34995SRabin Vincent int ret; 10927e34995SRabin Vincent 11027e34995SRabin Vincent mutex_lock(&stmpe->lock); 11127e34995SRabin Vincent ret = __stmpe_enable(stmpe, blocks); 11227e34995SRabin Vincent mutex_unlock(&stmpe->lock); 11327e34995SRabin Vincent 11427e34995SRabin Vincent return ret; 11527e34995SRabin Vincent } 11627e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_enable); 11727e34995SRabin Vincent 11827e34995SRabin Vincent /** 11927e34995SRabin Vincent * stmpe_disable - disable blocks on an STMPE device 12027e34995SRabin Vincent * @stmpe: Device to work on 12127e34995SRabin Vincent * @blocks: Mask of blocks (enum stmpe_block values) to enable 12227e34995SRabin Vincent */ 12327e34995SRabin Vincent int stmpe_disable(struct stmpe *stmpe, unsigned int blocks) 12427e34995SRabin Vincent { 12527e34995SRabin Vincent int ret; 12627e34995SRabin Vincent 12727e34995SRabin Vincent mutex_lock(&stmpe->lock); 12827e34995SRabin Vincent ret = __stmpe_disable(stmpe, blocks); 12927e34995SRabin Vincent mutex_unlock(&stmpe->lock); 13027e34995SRabin Vincent 13127e34995SRabin Vincent return ret; 13227e34995SRabin Vincent } 13327e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_disable); 13427e34995SRabin Vincent 13527e34995SRabin Vincent /** 13627e34995SRabin Vincent * stmpe_reg_read() - read a single STMPE register 13727e34995SRabin Vincent * @stmpe: Device to read from 13827e34995SRabin Vincent * @reg: Register to read 13927e34995SRabin Vincent */ 14027e34995SRabin Vincent int stmpe_reg_read(struct stmpe *stmpe, u8 reg) 14127e34995SRabin Vincent { 14227e34995SRabin Vincent int ret; 14327e34995SRabin Vincent 14427e34995SRabin Vincent mutex_lock(&stmpe->lock); 14527e34995SRabin Vincent ret = __stmpe_reg_read(stmpe, reg); 14627e34995SRabin Vincent mutex_unlock(&stmpe->lock); 14727e34995SRabin Vincent 14827e34995SRabin Vincent return ret; 14927e34995SRabin Vincent } 15027e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_reg_read); 15127e34995SRabin Vincent 15227e34995SRabin Vincent /** 15327e34995SRabin Vincent * stmpe_reg_write() - write a single STMPE register 15427e34995SRabin Vincent * @stmpe: Device to write to 15527e34995SRabin Vincent * @reg: Register to write 15627e34995SRabin Vincent * @val: Value to write 15727e34995SRabin Vincent */ 15827e34995SRabin Vincent int stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val) 15927e34995SRabin Vincent { 16027e34995SRabin Vincent int ret; 16127e34995SRabin Vincent 16227e34995SRabin Vincent mutex_lock(&stmpe->lock); 16327e34995SRabin Vincent ret = __stmpe_reg_write(stmpe, reg, val); 16427e34995SRabin Vincent mutex_unlock(&stmpe->lock); 16527e34995SRabin Vincent 16627e34995SRabin Vincent return ret; 16727e34995SRabin Vincent } 16827e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_reg_write); 16927e34995SRabin Vincent 17027e34995SRabin Vincent /** 17127e34995SRabin Vincent * stmpe_set_bits() - set the value of a bitfield in a STMPE register 17227e34995SRabin Vincent * @stmpe: Device to write to 17327e34995SRabin Vincent * @reg: Register to write 17427e34995SRabin Vincent * @mask: Mask of bits to set 17527e34995SRabin Vincent * @val: Value to set 17627e34995SRabin Vincent */ 17727e34995SRabin Vincent int stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val) 17827e34995SRabin Vincent { 17927e34995SRabin Vincent int ret; 18027e34995SRabin Vincent 18127e34995SRabin Vincent mutex_lock(&stmpe->lock); 18227e34995SRabin Vincent ret = __stmpe_set_bits(stmpe, reg, mask, val); 18327e34995SRabin Vincent mutex_unlock(&stmpe->lock); 18427e34995SRabin Vincent 18527e34995SRabin Vincent return ret; 18627e34995SRabin Vincent } 18727e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_set_bits); 18827e34995SRabin Vincent 18927e34995SRabin Vincent /** 19027e34995SRabin Vincent * stmpe_block_read() - read multiple STMPE registers 19127e34995SRabin Vincent * @stmpe: Device to read from 19227e34995SRabin Vincent * @reg: First register 19327e34995SRabin Vincent * @length: Number of registers 19427e34995SRabin Vincent * @values: Buffer to write to 19527e34995SRabin Vincent */ 19627e34995SRabin Vincent int stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values) 19727e34995SRabin Vincent { 19827e34995SRabin Vincent int ret; 19927e34995SRabin Vincent 20027e34995SRabin Vincent mutex_lock(&stmpe->lock); 20127e34995SRabin Vincent ret = __stmpe_block_read(stmpe, reg, length, values); 20227e34995SRabin Vincent mutex_unlock(&stmpe->lock); 20327e34995SRabin Vincent 20427e34995SRabin Vincent return ret; 20527e34995SRabin Vincent } 20627e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_block_read); 20727e34995SRabin Vincent 20827e34995SRabin Vincent /** 20927e34995SRabin Vincent * stmpe_block_write() - write multiple STMPE registers 21027e34995SRabin Vincent * @stmpe: Device to write to 21127e34995SRabin Vincent * @reg: First register 21227e34995SRabin Vincent * @length: Number of registers 21327e34995SRabin Vincent * @values: Values to write 21427e34995SRabin Vincent */ 21527e34995SRabin Vincent int stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length, 21627e34995SRabin Vincent const u8 *values) 21727e34995SRabin Vincent { 21827e34995SRabin Vincent int ret; 21927e34995SRabin Vincent 22027e34995SRabin Vincent mutex_lock(&stmpe->lock); 22127e34995SRabin Vincent ret = __stmpe_block_write(stmpe, reg, length, values); 22227e34995SRabin Vincent mutex_unlock(&stmpe->lock); 22327e34995SRabin Vincent 22427e34995SRabin Vincent return ret; 22527e34995SRabin Vincent } 22627e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_block_write); 22727e34995SRabin Vincent 22827e34995SRabin Vincent /** 2294dcaa6b6SOm Prakash * stmpe_set_altfunc()- set the alternate function for STMPE pins 23027e34995SRabin Vincent * @stmpe: Device to configure 23127e34995SRabin Vincent * @pins: Bitmask of pins to affect 23227e34995SRabin Vincent * @block: block to enable alternate functions for 23327e34995SRabin Vincent * 23427e34995SRabin Vincent * @pins is assumed to have a bit set for each of the bits whose alternate 23527e34995SRabin Vincent * function is to be changed, numbered according to the GPIOXY numbers. 23627e34995SRabin Vincent * 23727e34995SRabin Vincent * If the GPIO module is not enabled, this function automatically enables it in 23827e34995SRabin Vincent * order to perform the change. 23927e34995SRabin Vincent */ 24027e34995SRabin Vincent int stmpe_set_altfunc(struct stmpe *stmpe, u32 pins, enum stmpe_block block) 24127e34995SRabin Vincent { 24227e34995SRabin Vincent struct stmpe_variant_info *variant = stmpe->variant; 24327e34995SRabin Vincent u8 regaddr = stmpe->regs[STMPE_IDX_GPAFR_U_MSB]; 24427e34995SRabin Vincent int af_bits = variant->af_bits; 24527e34995SRabin Vincent int numregs = DIV_ROUND_UP(stmpe->num_gpios * af_bits, 8); 24627e34995SRabin Vincent int mask = (1 << af_bits) - 1; 24727e34995SRabin Vincent u8 regs[numregs]; 2487f7f4ea1SViresh Kumar int af, afperreg, ret; 24927e34995SRabin Vincent 2507f7f4ea1SViresh Kumar if (!variant->get_altfunc) 2517f7f4ea1SViresh Kumar return 0; 2527f7f4ea1SViresh Kumar 2537f7f4ea1SViresh Kumar afperreg = 8 / af_bits; 25427e34995SRabin Vincent mutex_lock(&stmpe->lock); 25527e34995SRabin Vincent 25627e34995SRabin Vincent ret = __stmpe_enable(stmpe, STMPE_BLOCK_GPIO); 25727e34995SRabin Vincent if (ret < 0) 25827e34995SRabin Vincent goto out; 25927e34995SRabin Vincent 26027e34995SRabin Vincent ret = __stmpe_block_read(stmpe, regaddr, numregs, regs); 26127e34995SRabin Vincent if (ret < 0) 26227e34995SRabin Vincent goto out; 26327e34995SRabin Vincent 26427e34995SRabin Vincent af = variant->get_altfunc(stmpe, block); 26527e34995SRabin Vincent 26627e34995SRabin Vincent while (pins) { 26727e34995SRabin Vincent int pin = __ffs(pins); 26827e34995SRabin Vincent int regoffset = numregs - (pin / afperreg) - 1; 26927e34995SRabin Vincent int pos = (pin % afperreg) * (8 / afperreg); 27027e34995SRabin Vincent 27127e34995SRabin Vincent regs[regoffset] &= ~(mask << pos); 27227e34995SRabin Vincent regs[regoffset] |= af << pos; 27327e34995SRabin Vincent 27427e34995SRabin Vincent pins &= ~(1 << pin); 27527e34995SRabin Vincent } 27627e34995SRabin Vincent 27727e34995SRabin Vincent ret = __stmpe_block_write(stmpe, regaddr, numregs, regs); 27827e34995SRabin Vincent 27927e34995SRabin Vincent out: 28027e34995SRabin Vincent mutex_unlock(&stmpe->lock); 28127e34995SRabin Vincent return ret; 28227e34995SRabin Vincent } 28327e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_set_altfunc); 28427e34995SRabin Vincent 28527e34995SRabin Vincent /* 28627e34995SRabin Vincent * GPIO (all variants) 28727e34995SRabin Vincent */ 28827e34995SRabin Vincent 28927e34995SRabin Vincent static struct resource stmpe_gpio_resources[] = { 29027e34995SRabin Vincent /* Start and end filled dynamically */ 29127e34995SRabin Vincent { 29227e34995SRabin Vincent .flags = IORESOURCE_IRQ, 29327e34995SRabin Vincent }, 29427e34995SRabin Vincent }; 29527e34995SRabin Vincent 29627e34995SRabin Vincent static struct mfd_cell stmpe_gpio_cell = { 29727e34995SRabin Vincent .name = "stmpe-gpio", 29827e34995SRabin Vincent .resources = stmpe_gpio_resources, 29927e34995SRabin Vincent .num_resources = ARRAY_SIZE(stmpe_gpio_resources), 30027e34995SRabin Vincent }; 30127e34995SRabin Vincent 302e31f9b82SChris Blair static struct mfd_cell stmpe_gpio_cell_noirq = { 303e31f9b82SChris Blair .name = "stmpe-gpio", 304e31f9b82SChris Blair /* gpio cell resources consist of an irq only so no resources here */ 305e31f9b82SChris Blair }; 306e31f9b82SChris Blair 30727e34995SRabin Vincent /* 30827e34995SRabin Vincent * Keypad (1601, 2401, 2403) 30927e34995SRabin Vincent */ 31027e34995SRabin Vincent 31127e34995SRabin Vincent static struct resource stmpe_keypad_resources[] = { 31227e34995SRabin Vincent { 31327e34995SRabin Vincent .name = "KEYPAD", 31427e34995SRabin Vincent .flags = IORESOURCE_IRQ, 31527e34995SRabin Vincent }, 31627e34995SRabin Vincent { 31727e34995SRabin Vincent .name = "KEYPAD_OVER", 31827e34995SRabin Vincent .flags = IORESOURCE_IRQ, 31927e34995SRabin Vincent }, 32027e34995SRabin Vincent }; 32127e34995SRabin Vincent 32227e34995SRabin Vincent static struct mfd_cell stmpe_keypad_cell = { 32327e34995SRabin Vincent .name = "stmpe-keypad", 32427e34995SRabin Vincent .resources = stmpe_keypad_resources, 32527e34995SRabin Vincent .num_resources = ARRAY_SIZE(stmpe_keypad_resources), 32627e34995SRabin Vincent }; 32727e34995SRabin Vincent 32827e34995SRabin Vincent /* 3297f7f4ea1SViresh Kumar * STMPE801 3307f7f4ea1SViresh Kumar */ 3317f7f4ea1SViresh Kumar static const u8 stmpe801_regs[] = { 3327f7f4ea1SViresh Kumar [STMPE_IDX_CHIP_ID] = STMPE801_REG_CHIP_ID, 3337f7f4ea1SViresh Kumar [STMPE_IDX_ICR_LSB] = STMPE801_REG_SYS_CTRL, 3347f7f4ea1SViresh Kumar [STMPE_IDX_GPMR_LSB] = STMPE801_REG_GPIO_MP_STA, 3357f7f4ea1SViresh Kumar [STMPE_IDX_GPSR_LSB] = STMPE801_REG_GPIO_SET_PIN, 3367f7f4ea1SViresh Kumar [STMPE_IDX_GPCR_LSB] = STMPE801_REG_GPIO_SET_PIN, 3377f7f4ea1SViresh Kumar [STMPE_IDX_GPDR_LSB] = STMPE801_REG_GPIO_DIR, 3387f7f4ea1SViresh Kumar [STMPE_IDX_IEGPIOR_LSB] = STMPE801_REG_GPIO_INT_EN, 3397f7f4ea1SViresh Kumar [STMPE_IDX_ISGPIOR_MSB] = STMPE801_REG_GPIO_INT_STA, 3407f7f4ea1SViresh Kumar 3417f7f4ea1SViresh Kumar }; 3427f7f4ea1SViresh Kumar 3437f7f4ea1SViresh Kumar static struct stmpe_variant_block stmpe801_blocks[] = { 3447f7f4ea1SViresh Kumar { 3457f7f4ea1SViresh Kumar .cell = &stmpe_gpio_cell, 3467f7f4ea1SViresh Kumar .irq = 0, 3477f7f4ea1SViresh Kumar .block = STMPE_BLOCK_GPIO, 3487f7f4ea1SViresh Kumar }, 3497f7f4ea1SViresh Kumar }; 3507f7f4ea1SViresh Kumar 351e31f9b82SChris Blair static struct stmpe_variant_block stmpe801_blocks_noirq[] = { 352e31f9b82SChris Blair { 353e31f9b82SChris Blair .cell = &stmpe_gpio_cell_noirq, 354e31f9b82SChris Blair .block = STMPE_BLOCK_GPIO, 355e31f9b82SChris Blair }, 356e31f9b82SChris Blair }; 357e31f9b82SChris Blair 3587f7f4ea1SViresh Kumar static int stmpe801_enable(struct stmpe *stmpe, unsigned int blocks, 3597f7f4ea1SViresh Kumar bool enable) 3607f7f4ea1SViresh Kumar { 3617f7f4ea1SViresh Kumar if (blocks & STMPE_BLOCK_GPIO) 3627f7f4ea1SViresh Kumar return 0; 3637f7f4ea1SViresh Kumar else 3647f7f4ea1SViresh Kumar return -EINVAL; 3657f7f4ea1SViresh Kumar } 3667f7f4ea1SViresh Kumar 3677f7f4ea1SViresh Kumar static struct stmpe_variant_info stmpe801 = { 3687f7f4ea1SViresh Kumar .name = "stmpe801", 3697f7f4ea1SViresh Kumar .id_val = STMPE801_ID, 3707f7f4ea1SViresh Kumar .id_mask = 0xffff, 3717f7f4ea1SViresh Kumar .num_gpios = 8, 3727f7f4ea1SViresh Kumar .regs = stmpe801_regs, 3737f7f4ea1SViresh Kumar .blocks = stmpe801_blocks, 3747f7f4ea1SViresh Kumar .num_blocks = ARRAY_SIZE(stmpe801_blocks), 3757f7f4ea1SViresh Kumar .num_irqs = STMPE801_NR_INTERNAL_IRQS, 3767f7f4ea1SViresh Kumar .enable = stmpe801_enable, 3777f7f4ea1SViresh Kumar }; 3787f7f4ea1SViresh Kumar 379e31f9b82SChris Blair static struct stmpe_variant_info stmpe801_noirq = { 380e31f9b82SChris Blair .name = "stmpe801", 381e31f9b82SChris Blair .id_val = STMPE801_ID, 382e31f9b82SChris Blair .id_mask = 0xffff, 383e31f9b82SChris Blair .num_gpios = 8, 384e31f9b82SChris Blair .regs = stmpe801_regs, 385e31f9b82SChris Blair .blocks = stmpe801_blocks_noirq, 386e31f9b82SChris Blair .num_blocks = ARRAY_SIZE(stmpe801_blocks_noirq), 387e31f9b82SChris Blair .enable = stmpe801_enable, 388e31f9b82SChris Blair }; 389e31f9b82SChris Blair 3907f7f4ea1SViresh Kumar /* 3911cda2394SViresh Kumar * Touchscreen (STMPE811 or STMPE610) 39227e34995SRabin Vincent */ 39327e34995SRabin Vincent 39427e34995SRabin Vincent static struct resource stmpe_ts_resources[] = { 39527e34995SRabin Vincent { 39627e34995SRabin Vincent .name = "TOUCH_DET", 39727e34995SRabin Vincent .flags = IORESOURCE_IRQ, 39827e34995SRabin Vincent }, 39927e34995SRabin Vincent { 40027e34995SRabin Vincent .name = "FIFO_TH", 40127e34995SRabin Vincent .flags = IORESOURCE_IRQ, 40227e34995SRabin Vincent }, 40327e34995SRabin Vincent }; 40427e34995SRabin Vincent 40527e34995SRabin Vincent static struct mfd_cell stmpe_ts_cell = { 40627e34995SRabin Vincent .name = "stmpe-ts", 40727e34995SRabin Vincent .resources = stmpe_ts_resources, 40827e34995SRabin Vincent .num_resources = ARRAY_SIZE(stmpe_ts_resources), 40927e34995SRabin Vincent }; 41027e34995SRabin Vincent 41127e34995SRabin Vincent /* 4121cda2394SViresh Kumar * STMPE811 or STMPE610 41327e34995SRabin Vincent */ 41427e34995SRabin Vincent 41527e34995SRabin Vincent static const u8 stmpe811_regs[] = { 41627e34995SRabin Vincent [STMPE_IDX_CHIP_ID] = STMPE811_REG_CHIP_ID, 41727e34995SRabin Vincent [STMPE_IDX_ICR_LSB] = STMPE811_REG_INT_CTRL, 41827e34995SRabin Vincent [STMPE_IDX_IER_LSB] = STMPE811_REG_INT_EN, 41927e34995SRabin Vincent [STMPE_IDX_ISR_MSB] = STMPE811_REG_INT_STA, 42027e34995SRabin Vincent [STMPE_IDX_GPMR_LSB] = STMPE811_REG_GPIO_MP_STA, 42127e34995SRabin Vincent [STMPE_IDX_GPSR_LSB] = STMPE811_REG_GPIO_SET_PIN, 42227e34995SRabin Vincent [STMPE_IDX_GPCR_LSB] = STMPE811_REG_GPIO_CLR_PIN, 42327e34995SRabin Vincent [STMPE_IDX_GPDR_LSB] = STMPE811_REG_GPIO_DIR, 42427e34995SRabin Vincent [STMPE_IDX_GPRER_LSB] = STMPE811_REG_GPIO_RE, 42527e34995SRabin Vincent [STMPE_IDX_GPFER_LSB] = STMPE811_REG_GPIO_FE, 42627e34995SRabin Vincent [STMPE_IDX_GPAFR_U_MSB] = STMPE811_REG_GPIO_AF, 42727e34995SRabin Vincent [STMPE_IDX_IEGPIOR_LSB] = STMPE811_REG_GPIO_INT_EN, 42827e34995SRabin Vincent [STMPE_IDX_ISGPIOR_MSB] = STMPE811_REG_GPIO_INT_STA, 42927e34995SRabin Vincent [STMPE_IDX_GPEDR_MSB] = STMPE811_REG_GPIO_ED, 43027e34995SRabin Vincent }; 43127e34995SRabin Vincent 43227e34995SRabin Vincent static struct stmpe_variant_block stmpe811_blocks[] = { 43327e34995SRabin Vincent { 43427e34995SRabin Vincent .cell = &stmpe_gpio_cell, 43527e34995SRabin Vincent .irq = STMPE811_IRQ_GPIOC, 43627e34995SRabin Vincent .block = STMPE_BLOCK_GPIO, 43727e34995SRabin Vincent }, 43827e34995SRabin Vincent { 43927e34995SRabin Vincent .cell = &stmpe_ts_cell, 44027e34995SRabin Vincent .irq = STMPE811_IRQ_TOUCH_DET, 44127e34995SRabin Vincent .block = STMPE_BLOCK_TOUCHSCREEN, 44227e34995SRabin Vincent }, 44327e34995SRabin Vincent }; 44427e34995SRabin Vincent 44527e34995SRabin Vincent static int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks, 44627e34995SRabin Vincent bool enable) 44727e34995SRabin Vincent { 44827e34995SRabin Vincent unsigned int mask = 0; 44927e34995SRabin Vincent 45027e34995SRabin Vincent if (blocks & STMPE_BLOCK_GPIO) 45127e34995SRabin Vincent mask |= STMPE811_SYS_CTRL2_GPIO_OFF; 45227e34995SRabin Vincent 45327e34995SRabin Vincent if (blocks & STMPE_BLOCK_ADC) 45427e34995SRabin Vincent mask |= STMPE811_SYS_CTRL2_ADC_OFF; 45527e34995SRabin Vincent 45627e34995SRabin Vincent if (blocks & STMPE_BLOCK_TOUCHSCREEN) 45727e34995SRabin Vincent mask |= STMPE811_SYS_CTRL2_TSC_OFF; 45827e34995SRabin Vincent 45927e34995SRabin Vincent return __stmpe_set_bits(stmpe, STMPE811_REG_SYS_CTRL2, mask, 46027e34995SRabin Vincent enable ? 0 : mask); 46127e34995SRabin Vincent } 46227e34995SRabin Vincent 46327e34995SRabin Vincent static int stmpe811_get_altfunc(struct stmpe *stmpe, enum stmpe_block block) 46427e34995SRabin Vincent { 46527e34995SRabin Vincent /* 0 for touchscreen, 1 for GPIO */ 46627e34995SRabin Vincent return block != STMPE_BLOCK_TOUCHSCREEN; 46727e34995SRabin Vincent } 46827e34995SRabin Vincent 46927e34995SRabin Vincent static struct stmpe_variant_info stmpe811 = { 47027e34995SRabin Vincent .name = "stmpe811", 47127e34995SRabin Vincent .id_val = 0x0811, 47227e34995SRabin Vincent .id_mask = 0xffff, 47327e34995SRabin Vincent .num_gpios = 8, 47427e34995SRabin Vincent .af_bits = 1, 47527e34995SRabin Vincent .regs = stmpe811_regs, 47627e34995SRabin Vincent .blocks = stmpe811_blocks, 47727e34995SRabin Vincent .num_blocks = ARRAY_SIZE(stmpe811_blocks), 47827e34995SRabin Vincent .num_irqs = STMPE811_NR_INTERNAL_IRQS, 47927e34995SRabin Vincent .enable = stmpe811_enable, 48027e34995SRabin Vincent .get_altfunc = stmpe811_get_altfunc, 48127e34995SRabin Vincent }; 48227e34995SRabin Vincent 4831cda2394SViresh Kumar /* Similar to 811, except number of gpios */ 4841cda2394SViresh Kumar static struct stmpe_variant_info stmpe610 = { 4851cda2394SViresh Kumar .name = "stmpe610", 4861cda2394SViresh Kumar .id_val = 0x0811, 4871cda2394SViresh Kumar .id_mask = 0xffff, 4881cda2394SViresh Kumar .num_gpios = 6, 4891cda2394SViresh Kumar .af_bits = 1, 4901cda2394SViresh Kumar .regs = stmpe811_regs, 4911cda2394SViresh Kumar .blocks = stmpe811_blocks, 4921cda2394SViresh Kumar .num_blocks = ARRAY_SIZE(stmpe811_blocks), 4931cda2394SViresh Kumar .num_irqs = STMPE811_NR_INTERNAL_IRQS, 4941cda2394SViresh Kumar .enable = stmpe811_enable, 4951cda2394SViresh Kumar .get_altfunc = stmpe811_get_altfunc, 4961cda2394SViresh Kumar }; 4971cda2394SViresh Kumar 49827e34995SRabin Vincent /* 49927e34995SRabin Vincent * STMPE1601 50027e34995SRabin Vincent */ 50127e34995SRabin Vincent 50227e34995SRabin Vincent static const u8 stmpe1601_regs[] = { 50327e34995SRabin Vincent [STMPE_IDX_CHIP_ID] = STMPE1601_REG_CHIP_ID, 50427e34995SRabin Vincent [STMPE_IDX_ICR_LSB] = STMPE1601_REG_ICR_LSB, 50527e34995SRabin Vincent [STMPE_IDX_IER_LSB] = STMPE1601_REG_IER_LSB, 50627e34995SRabin Vincent [STMPE_IDX_ISR_MSB] = STMPE1601_REG_ISR_MSB, 50727e34995SRabin Vincent [STMPE_IDX_GPMR_LSB] = STMPE1601_REG_GPIO_MP_LSB, 50827e34995SRabin Vincent [STMPE_IDX_GPSR_LSB] = STMPE1601_REG_GPIO_SET_LSB, 50927e34995SRabin Vincent [STMPE_IDX_GPCR_LSB] = STMPE1601_REG_GPIO_CLR_LSB, 51027e34995SRabin Vincent [STMPE_IDX_GPDR_LSB] = STMPE1601_REG_GPIO_SET_DIR_LSB, 51127e34995SRabin Vincent [STMPE_IDX_GPRER_LSB] = STMPE1601_REG_GPIO_RE_LSB, 51227e34995SRabin Vincent [STMPE_IDX_GPFER_LSB] = STMPE1601_REG_GPIO_FE_LSB, 51327e34995SRabin Vincent [STMPE_IDX_GPAFR_U_MSB] = STMPE1601_REG_GPIO_AF_U_MSB, 51427e34995SRabin Vincent [STMPE_IDX_IEGPIOR_LSB] = STMPE1601_REG_INT_EN_GPIO_MASK_LSB, 51527e34995SRabin Vincent [STMPE_IDX_ISGPIOR_MSB] = STMPE1601_REG_INT_STA_GPIO_MSB, 51627e34995SRabin Vincent [STMPE_IDX_GPEDR_MSB] = STMPE1601_REG_GPIO_ED_MSB, 51727e34995SRabin Vincent }; 51827e34995SRabin Vincent 51927e34995SRabin Vincent static struct stmpe_variant_block stmpe1601_blocks[] = { 52027e34995SRabin Vincent { 52127e34995SRabin Vincent .cell = &stmpe_gpio_cell, 5225204e51dSLee Jones .irq = STMPE1601_IRQ_GPIOC, 52327e34995SRabin Vincent .block = STMPE_BLOCK_GPIO, 52427e34995SRabin Vincent }, 52527e34995SRabin Vincent { 52627e34995SRabin Vincent .cell = &stmpe_keypad_cell, 5275204e51dSLee Jones .irq = STMPE1601_IRQ_KEYPAD, 52827e34995SRabin Vincent .block = STMPE_BLOCK_KEYPAD, 52927e34995SRabin Vincent }, 53027e34995SRabin Vincent }; 53127e34995SRabin Vincent 5325981f4e6SSundar R Iyer /* supported autosleep timeout delay (in msecs) */ 5335981f4e6SSundar R Iyer static const int stmpe_autosleep_delay[] = { 5345981f4e6SSundar R Iyer 4, 16, 32, 64, 128, 256, 512, 1024, 5355981f4e6SSundar R Iyer }; 5365981f4e6SSundar R Iyer 5375981f4e6SSundar R Iyer static int stmpe_round_timeout(int timeout) 5385981f4e6SSundar R Iyer { 5395981f4e6SSundar R Iyer int i; 5405981f4e6SSundar R Iyer 5415981f4e6SSundar R Iyer for (i = 0; i < ARRAY_SIZE(stmpe_autosleep_delay); i++) { 5425981f4e6SSundar R Iyer if (stmpe_autosleep_delay[i] >= timeout) 5435981f4e6SSundar R Iyer return i; 5445981f4e6SSundar R Iyer } 5455981f4e6SSundar R Iyer 5465981f4e6SSundar R Iyer /* 5475981f4e6SSundar R Iyer * requests for delays longer than supported should not return the 5485981f4e6SSundar R Iyer * longest supported delay 5495981f4e6SSundar R Iyer */ 5505981f4e6SSundar R Iyer return -EINVAL; 5515981f4e6SSundar R Iyer } 5525981f4e6SSundar R Iyer 5535981f4e6SSundar R Iyer static int stmpe_autosleep(struct stmpe *stmpe, int autosleep_timeout) 5545981f4e6SSundar R Iyer { 5555981f4e6SSundar R Iyer int ret; 5565981f4e6SSundar R Iyer 5575981f4e6SSundar R Iyer if (!stmpe->variant->enable_autosleep) 5585981f4e6SSundar R Iyer return -ENOSYS; 5595981f4e6SSundar R Iyer 5605981f4e6SSundar R Iyer mutex_lock(&stmpe->lock); 5615981f4e6SSundar R Iyer ret = stmpe->variant->enable_autosleep(stmpe, autosleep_timeout); 5625981f4e6SSundar R Iyer mutex_unlock(&stmpe->lock); 5635981f4e6SSundar R Iyer 5645981f4e6SSundar R Iyer return ret; 5655981f4e6SSundar R Iyer } 5665981f4e6SSundar R Iyer 5675981f4e6SSundar R Iyer /* 5685981f4e6SSundar R Iyer * Both stmpe 1601/2403 support same layout for autosleep 5695981f4e6SSundar R Iyer */ 5705981f4e6SSundar R Iyer static int stmpe1601_autosleep(struct stmpe *stmpe, 5715981f4e6SSundar R Iyer int autosleep_timeout) 5725981f4e6SSundar R Iyer { 5735981f4e6SSundar R Iyer int ret, timeout; 5745981f4e6SSundar R Iyer 5755981f4e6SSundar R Iyer /* choose the best available timeout */ 5765981f4e6SSundar R Iyer timeout = stmpe_round_timeout(autosleep_timeout); 5775981f4e6SSundar R Iyer if (timeout < 0) { 5785981f4e6SSundar R Iyer dev_err(stmpe->dev, "invalid timeout\n"); 5795981f4e6SSundar R Iyer return timeout; 5805981f4e6SSundar R Iyer } 5815981f4e6SSundar R Iyer 5825981f4e6SSundar R Iyer ret = __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL2, 5835981f4e6SSundar R Iyer STMPE1601_AUTOSLEEP_TIMEOUT_MASK, 5845981f4e6SSundar R Iyer timeout); 5855981f4e6SSundar R Iyer if (ret < 0) 5865981f4e6SSundar R Iyer return ret; 5875981f4e6SSundar R Iyer 5885981f4e6SSundar R Iyer return __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL2, 5895981f4e6SSundar R Iyer STPME1601_AUTOSLEEP_ENABLE, 5905981f4e6SSundar R Iyer STPME1601_AUTOSLEEP_ENABLE); 5915981f4e6SSundar R Iyer } 5925981f4e6SSundar R Iyer 59327e34995SRabin Vincent static int stmpe1601_enable(struct stmpe *stmpe, unsigned int blocks, 59427e34995SRabin Vincent bool enable) 59527e34995SRabin Vincent { 59627e34995SRabin Vincent unsigned int mask = 0; 59727e34995SRabin Vincent 59827e34995SRabin Vincent if (blocks & STMPE_BLOCK_GPIO) 59927e34995SRabin Vincent mask |= STMPE1601_SYS_CTRL_ENABLE_GPIO; 60027e34995SRabin Vincent 60127e34995SRabin Vincent if (blocks & STMPE_BLOCK_KEYPAD) 60227e34995SRabin Vincent mask |= STMPE1601_SYS_CTRL_ENABLE_KPC; 60327e34995SRabin Vincent 60427e34995SRabin Vincent return __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL, mask, 60527e34995SRabin Vincent enable ? mask : 0); 60627e34995SRabin Vincent } 60727e34995SRabin Vincent 60827e34995SRabin Vincent static int stmpe1601_get_altfunc(struct stmpe *stmpe, enum stmpe_block block) 60927e34995SRabin Vincent { 61027e34995SRabin Vincent switch (block) { 61127e34995SRabin Vincent case STMPE_BLOCK_PWM: 61227e34995SRabin Vincent return 2; 61327e34995SRabin Vincent 61427e34995SRabin Vincent case STMPE_BLOCK_KEYPAD: 61527e34995SRabin Vincent return 1; 61627e34995SRabin Vincent 61727e34995SRabin Vincent case STMPE_BLOCK_GPIO: 61827e34995SRabin Vincent default: 61927e34995SRabin Vincent return 0; 62027e34995SRabin Vincent } 62127e34995SRabin Vincent } 62227e34995SRabin Vincent 62327e34995SRabin Vincent static struct stmpe_variant_info stmpe1601 = { 62427e34995SRabin Vincent .name = "stmpe1601", 62527e34995SRabin Vincent .id_val = 0x0210, 62627e34995SRabin Vincent .id_mask = 0xfff0, /* at least 0x0210 and 0x0212 */ 62727e34995SRabin Vincent .num_gpios = 16, 62827e34995SRabin Vincent .af_bits = 2, 62927e34995SRabin Vincent .regs = stmpe1601_regs, 63027e34995SRabin Vincent .blocks = stmpe1601_blocks, 63127e34995SRabin Vincent .num_blocks = ARRAY_SIZE(stmpe1601_blocks), 63227e34995SRabin Vincent .num_irqs = STMPE1601_NR_INTERNAL_IRQS, 63327e34995SRabin Vincent .enable = stmpe1601_enable, 63427e34995SRabin Vincent .get_altfunc = stmpe1601_get_altfunc, 6355981f4e6SSundar R Iyer .enable_autosleep = stmpe1601_autosleep, 63627e34995SRabin Vincent }; 63727e34995SRabin Vincent 63827e34995SRabin Vincent /* 63927e34995SRabin Vincent * STMPE24XX 64027e34995SRabin Vincent */ 64127e34995SRabin Vincent 64227e34995SRabin Vincent static const u8 stmpe24xx_regs[] = { 64327e34995SRabin Vincent [STMPE_IDX_CHIP_ID] = STMPE24XX_REG_CHIP_ID, 64427e34995SRabin Vincent [STMPE_IDX_ICR_LSB] = STMPE24XX_REG_ICR_LSB, 64527e34995SRabin Vincent [STMPE_IDX_IER_LSB] = STMPE24XX_REG_IER_LSB, 64627e34995SRabin Vincent [STMPE_IDX_ISR_MSB] = STMPE24XX_REG_ISR_MSB, 64727e34995SRabin Vincent [STMPE_IDX_GPMR_LSB] = STMPE24XX_REG_GPMR_LSB, 64827e34995SRabin Vincent [STMPE_IDX_GPSR_LSB] = STMPE24XX_REG_GPSR_LSB, 64927e34995SRabin Vincent [STMPE_IDX_GPCR_LSB] = STMPE24XX_REG_GPCR_LSB, 65027e34995SRabin Vincent [STMPE_IDX_GPDR_LSB] = STMPE24XX_REG_GPDR_LSB, 65127e34995SRabin Vincent [STMPE_IDX_GPRER_LSB] = STMPE24XX_REG_GPRER_LSB, 65227e34995SRabin Vincent [STMPE_IDX_GPFER_LSB] = STMPE24XX_REG_GPFER_LSB, 65327e34995SRabin Vincent [STMPE_IDX_GPAFR_U_MSB] = STMPE24XX_REG_GPAFR_U_MSB, 65427e34995SRabin Vincent [STMPE_IDX_IEGPIOR_LSB] = STMPE24XX_REG_IEGPIOR_LSB, 65527e34995SRabin Vincent [STMPE_IDX_ISGPIOR_MSB] = STMPE24XX_REG_ISGPIOR_MSB, 65627e34995SRabin Vincent [STMPE_IDX_GPEDR_MSB] = STMPE24XX_REG_GPEDR_MSB, 65727e34995SRabin Vincent }; 65827e34995SRabin Vincent 65927e34995SRabin Vincent static struct stmpe_variant_block stmpe24xx_blocks[] = { 66027e34995SRabin Vincent { 66127e34995SRabin Vincent .cell = &stmpe_gpio_cell, 66227e34995SRabin Vincent .irq = STMPE24XX_IRQ_GPIOC, 66327e34995SRabin Vincent .block = STMPE_BLOCK_GPIO, 66427e34995SRabin Vincent }, 66527e34995SRabin Vincent { 66627e34995SRabin Vincent .cell = &stmpe_keypad_cell, 66727e34995SRabin Vincent .irq = STMPE24XX_IRQ_KEYPAD, 66827e34995SRabin Vincent .block = STMPE_BLOCK_KEYPAD, 66927e34995SRabin Vincent }, 67027e34995SRabin Vincent }; 67127e34995SRabin Vincent 67227e34995SRabin Vincent static int stmpe24xx_enable(struct stmpe *stmpe, unsigned int blocks, 67327e34995SRabin Vincent bool enable) 67427e34995SRabin Vincent { 67527e34995SRabin Vincent unsigned int mask = 0; 67627e34995SRabin Vincent 67727e34995SRabin Vincent if (blocks & STMPE_BLOCK_GPIO) 67827e34995SRabin Vincent mask |= STMPE24XX_SYS_CTRL_ENABLE_GPIO; 67927e34995SRabin Vincent 68027e34995SRabin Vincent if (blocks & STMPE_BLOCK_KEYPAD) 68127e34995SRabin Vincent mask |= STMPE24XX_SYS_CTRL_ENABLE_KPC; 68227e34995SRabin Vincent 68327e34995SRabin Vincent return __stmpe_set_bits(stmpe, STMPE24XX_REG_SYS_CTRL, mask, 68427e34995SRabin Vincent enable ? mask : 0); 68527e34995SRabin Vincent } 68627e34995SRabin Vincent 68727e34995SRabin Vincent static int stmpe24xx_get_altfunc(struct stmpe *stmpe, enum stmpe_block block) 68827e34995SRabin Vincent { 68927e34995SRabin Vincent switch (block) { 69027e34995SRabin Vincent case STMPE_BLOCK_ROTATOR: 69127e34995SRabin Vincent return 2; 69227e34995SRabin Vincent 69327e34995SRabin Vincent case STMPE_BLOCK_KEYPAD: 69427e34995SRabin Vincent return 1; 69527e34995SRabin Vincent 69627e34995SRabin Vincent case STMPE_BLOCK_GPIO: 69727e34995SRabin Vincent default: 69827e34995SRabin Vincent return 0; 69927e34995SRabin Vincent } 70027e34995SRabin Vincent } 70127e34995SRabin Vincent 70227e34995SRabin Vincent static struct stmpe_variant_info stmpe2401 = { 70327e34995SRabin Vincent .name = "stmpe2401", 70427e34995SRabin Vincent .id_val = 0x0101, 70527e34995SRabin Vincent .id_mask = 0xffff, 70627e34995SRabin Vincent .num_gpios = 24, 70727e34995SRabin Vincent .af_bits = 2, 70827e34995SRabin Vincent .regs = stmpe24xx_regs, 70927e34995SRabin Vincent .blocks = stmpe24xx_blocks, 71027e34995SRabin Vincent .num_blocks = ARRAY_SIZE(stmpe24xx_blocks), 71127e34995SRabin Vincent .num_irqs = STMPE24XX_NR_INTERNAL_IRQS, 71227e34995SRabin Vincent .enable = stmpe24xx_enable, 71327e34995SRabin Vincent .get_altfunc = stmpe24xx_get_altfunc, 71427e34995SRabin Vincent }; 71527e34995SRabin Vincent 71627e34995SRabin Vincent static struct stmpe_variant_info stmpe2403 = { 71727e34995SRabin Vincent .name = "stmpe2403", 71827e34995SRabin Vincent .id_val = 0x0120, 71927e34995SRabin Vincent .id_mask = 0xffff, 72027e34995SRabin Vincent .num_gpios = 24, 72127e34995SRabin Vincent .af_bits = 2, 72227e34995SRabin Vincent .regs = stmpe24xx_regs, 72327e34995SRabin Vincent .blocks = stmpe24xx_blocks, 72427e34995SRabin Vincent .num_blocks = ARRAY_SIZE(stmpe24xx_blocks), 72527e34995SRabin Vincent .num_irqs = STMPE24XX_NR_INTERNAL_IRQS, 72627e34995SRabin Vincent .enable = stmpe24xx_enable, 72727e34995SRabin Vincent .get_altfunc = stmpe24xx_get_altfunc, 7285981f4e6SSundar R Iyer .enable_autosleep = stmpe1601_autosleep, /* same as stmpe1601 */ 72927e34995SRabin Vincent }; 73027e34995SRabin Vincent 731e31f9b82SChris Blair static struct stmpe_variant_info *stmpe_variant_info[STMPE_NBR_PARTS] = { 7321cda2394SViresh Kumar [STMPE610] = &stmpe610, 7337f7f4ea1SViresh Kumar [STMPE801] = &stmpe801, 73427e34995SRabin Vincent [STMPE811] = &stmpe811, 73527e34995SRabin Vincent [STMPE1601] = &stmpe1601, 73627e34995SRabin Vincent [STMPE2401] = &stmpe2401, 73727e34995SRabin Vincent [STMPE2403] = &stmpe2403, 73827e34995SRabin Vincent }; 73927e34995SRabin Vincent 740e31f9b82SChris Blair /* 741e31f9b82SChris Blair * These devices can be connected in a 'no-irq' configuration - the irq pin 742e31f9b82SChris Blair * is not used and the device cannot interrupt the CPU. Here we only list 743e31f9b82SChris Blair * devices which support this configuration - the driver will fail probing 744e31f9b82SChris Blair * for any devices not listed here which are configured in this way. 745e31f9b82SChris Blair */ 746e31f9b82SChris Blair static struct stmpe_variant_info *stmpe_noirq_variant_info[STMPE_NBR_PARTS] = { 747e31f9b82SChris Blair [STMPE801] = &stmpe801_noirq, 748e31f9b82SChris Blair }; 749e31f9b82SChris Blair 75027e34995SRabin Vincent static irqreturn_t stmpe_irq(int irq, void *data) 75127e34995SRabin Vincent { 75227e34995SRabin Vincent struct stmpe *stmpe = data; 75327e34995SRabin Vincent struct stmpe_variant_info *variant = stmpe->variant; 75427e34995SRabin Vincent int num = DIV_ROUND_UP(variant->num_irqs, 8); 75527e34995SRabin Vincent u8 israddr = stmpe->regs[STMPE_IDX_ISR_MSB]; 75627e34995SRabin Vincent u8 isr[num]; 75727e34995SRabin Vincent int ret; 75827e34995SRabin Vincent int i; 75927e34995SRabin Vincent 7607f7f4ea1SViresh Kumar if (variant->id_val == STMPE801_ID) { 76176f93992SLee Jones int base = irq_create_mapping(stmpe->domain, 0); 76276f93992SLee Jones 76376f93992SLee Jones handle_nested_irq(base); 7647f7f4ea1SViresh Kumar return IRQ_HANDLED; 7657f7f4ea1SViresh Kumar } 7667f7f4ea1SViresh Kumar 76727e34995SRabin Vincent ret = stmpe_block_read(stmpe, israddr, num, isr); 76827e34995SRabin Vincent if (ret < 0) 76927e34995SRabin Vincent return IRQ_NONE; 77027e34995SRabin Vincent 77127e34995SRabin Vincent for (i = 0; i < num; i++) { 77227e34995SRabin Vincent int bank = num - i - 1; 77327e34995SRabin Vincent u8 status = isr[i]; 77427e34995SRabin Vincent u8 clear; 77527e34995SRabin Vincent 77627e34995SRabin Vincent status &= stmpe->ier[bank]; 77727e34995SRabin Vincent if (!status) 77827e34995SRabin Vincent continue; 77927e34995SRabin Vincent 78027e34995SRabin Vincent clear = status; 78127e34995SRabin Vincent while (status) { 78227e34995SRabin Vincent int bit = __ffs(status); 78327e34995SRabin Vincent int line = bank * 8 + bit; 78476f93992SLee Jones int nestedirq = irq_create_mapping(stmpe->domain, line); 78527e34995SRabin Vincent 78676f93992SLee Jones handle_nested_irq(nestedirq); 78727e34995SRabin Vincent status &= ~(1 << bit); 78827e34995SRabin Vincent } 78927e34995SRabin Vincent 79027e34995SRabin Vincent stmpe_reg_write(stmpe, israddr + i, clear); 79127e34995SRabin Vincent } 79227e34995SRabin Vincent 79327e34995SRabin Vincent return IRQ_HANDLED; 79427e34995SRabin Vincent } 79527e34995SRabin Vincent 79643b8c084SMark Brown static void stmpe_irq_lock(struct irq_data *data) 79727e34995SRabin Vincent { 79843b8c084SMark Brown struct stmpe *stmpe = irq_data_get_irq_chip_data(data); 79927e34995SRabin Vincent 80027e34995SRabin Vincent mutex_lock(&stmpe->irq_lock); 80127e34995SRabin Vincent } 80227e34995SRabin Vincent 80343b8c084SMark Brown static void stmpe_irq_sync_unlock(struct irq_data *data) 80427e34995SRabin Vincent { 80543b8c084SMark Brown struct stmpe *stmpe = irq_data_get_irq_chip_data(data); 80627e34995SRabin Vincent struct stmpe_variant_info *variant = stmpe->variant; 80727e34995SRabin Vincent int num = DIV_ROUND_UP(variant->num_irqs, 8); 80827e34995SRabin Vincent int i; 80927e34995SRabin Vincent 81027e34995SRabin Vincent for (i = 0; i < num; i++) { 81127e34995SRabin Vincent u8 new = stmpe->ier[i]; 81227e34995SRabin Vincent u8 old = stmpe->oldier[i]; 81327e34995SRabin Vincent 81427e34995SRabin Vincent if (new == old) 81527e34995SRabin Vincent continue; 81627e34995SRabin Vincent 81727e34995SRabin Vincent stmpe->oldier[i] = new; 81827e34995SRabin Vincent stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_IER_LSB] - i, new); 81927e34995SRabin Vincent } 82027e34995SRabin Vincent 82127e34995SRabin Vincent mutex_unlock(&stmpe->irq_lock); 82227e34995SRabin Vincent } 82327e34995SRabin Vincent 82443b8c084SMark Brown static void stmpe_irq_mask(struct irq_data *data) 82527e34995SRabin Vincent { 82643b8c084SMark Brown struct stmpe *stmpe = irq_data_get_irq_chip_data(data); 82776f93992SLee Jones int offset = data->hwirq; 82827e34995SRabin Vincent int regoffset = offset / 8; 82927e34995SRabin Vincent int mask = 1 << (offset % 8); 83027e34995SRabin Vincent 83127e34995SRabin Vincent stmpe->ier[regoffset] &= ~mask; 83227e34995SRabin Vincent } 83327e34995SRabin Vincent 83443b8c084SMark Brown static void stmpe_irq_unmask(struct irq_data *data) 83527e34995SRabin Vincent { 83643b8c084SMark Brown struct stmpe *stmpe = irq_data_get_irq_chip_data(data); 83776f93992SLee Jones int offset = data->hwirq; 83827e34995SRabin Vincent int regoffset = offset / 8; 83927e34995SRabin Vincent int mask = 1 << (offset % 8); 84027e34995SRabin Vincent 84127e34995SRabin Vincent stmpe->ier[regoffset] |= mask; 84227e34995SRabin Vincent } 84327e34995SRabin Vincent 84427e34995SRabin Vincent static struct irq_chip stmpe_irq_chip = { 84527e34995SRabin Vincent .name = "stmpe", 84643b8c084SMark Brown .irq_bus_lock = stmpe_irq_lock, 84743b8c084SMark Brown .irq_bus_sync_unlock = stmpe_irq_sync_unlock, 84843b8c084SMark Brown .irq_mask = stmpe_irq_mask, 84943b8c084SMark Brown .irq_unmask = stmpe_irq_unmask, 85027e34995SRabin Vincent }; 85127e34995SRabin Vincent 85276f93992SLee Jones static int stmpe_irq_map(struct irq_domain *d, unsigned int virq, 85376f93992SLee Jones irq_hw_number_t hwirq) 85427e34995SRabin Vincent { 85576f93992SLee Jones struct stmpe *stmpe = d->host_data; 8567f7f4ea1SViresh Kumar struct irq_chip *chip = NULL; 85727e34995SRabin Vincent 8587f7f4ea1SViresh Kumar if (stmpe->variant->id_val != STMPE801_ID) 8597f7f4ea1SViresh Kumar chip = &stmpe_irq_chip; 8607f7f4ea1SViresh Kumar 86176f93992SLee Jones irq_set_chip_data(virq, stmpe); 86276f93992SLee Jones irq_set_chip_and_handler(virq, chip, handle_edge_irq); 86376f93992SLee Jones irq_set_nested_thread(virq, 1); 86427e34995SRabin Vincent #ifdef CONFIG_ARM 86576f93992SLee Jones set_irq_flags(virq, IRQF_VALID); 86627e34995SRabin Vincent #else 86776f93992SLee Jones irq_set_noprobe(virq); 86827e34995SRabin Vincent #endif 86927e34995SRabin Vincent 87027e34995SRabin Vincent return 0; 87127e34995SRabin Vincent } 87227e34995SRabin Vincent 87376f93992SLee Jones static void stmpe_irq_unmap(struct irq_domain *d, unsigned int virq) 87427e34995SRabin Vincent { 87527e34995SRabin Vincent #ifdef CONFIG_ARM 87676f93992SLee Jones set_irq_flags(virq, 0); 87727e34995SRabin Vincent #endif 87876f93992SLee Jones irq_set_chip_and_handler(virq, NULL, NULL); 87976f93992SLee Jones irq_set_chip_data(virq, NULL); 88027e34995SRabin Vincent } 88176f93992SLee Jones 88276f93992SLee Jones static struct irq_domain_ops stmpe_irq_ops = { 88376f93992SLee Jones .map = stmpe_irq_map, 88476f93992SLee Jones .unmap = stmpe_irq_unmap, 88576f93992SLee Jones .xlate = irq_domain_xlate_twocell, 88676f93992SLee Jones }; 88776f93992SLee Jones 888909582caSLee Jones static int __devinit stmpe_irq_init(struct stmpe *stmpe, 889909582caSLee Jones struct device_node *np) 89076f93992SLee Jones { 89176f93992SLee Jones int base = stmpe->irq_base; 89276f93992SLee Jones int num_irqs = stmpe->variant->num_irqs; 89376f93992SLee Jones 89476f93992SLee Jones if (base) { 89576f93992SLee Jones stmpe->domain = irq_domain_add_legacy( 896909582caSLee Jones np, num_irqs, base, 0, &stmpe_irq_ops, stmpe); 89776f93992SLee Jones } 89876f93992SLee Jones else { 89976f93992SLee Jones stmpe->domain = irq_domain_add_linear( 900909582caSLee Jones np, num_irqs, &stmpe_irq_ops, stmpe); 90176f93992SLee Jones } 90276f93992SLee Jones 90376f93992SLee Jones if (!stmpe->domain) { 90476f93992SLee Jones dev_err(stmpe->dev, "Failed to create irqdomain\n"); 90576f93992SLee Jones return -ENOSYS; 90676f93992SLee Jones } 90776f93992SLee Jones 90876f93992SLee Jones return 0; 90927e34995SRabin Vincent } 91027e34995SRabin Vincent 91127e34995SRabin Vincent static int __devinit stmpe_chip_init(struct stmpe *stmpe) 91227e34995SRabin Vincent { 91327e34995SRabin Vincent unsigned int irq_trigger = stmpe->pdata->irq_trigger; 9145981f4e6SSundar R Iyer int autosleep_timeout = stmpe->pdata->autosleep_timeout; 91527e34995SRabin Vincent struct stmpe_variant_info *variant = stmpe->variant; 916e31f9b82SChris Blair u8 icr = 0; 91727e34995SRabin Vincent unsigned int id; 91827e34995SRabin Vincent u8 data[2]; 91927e34995SRabin Vincent int ret; 92027e34995SRabin Vincent 92127e34995SRabin Vincent ret = stmpe_block_read(stmpe, stmpe->regs[STMPE_IDX_CHIP_ID], 92227e34995SRabin Vincent ARRAY_SIZE(data), data); 92327e34995SRabin Vincent if (ret < 0) 92427e34995SRabin Vincent return ret; 92527e34995SRabin Vincent 92627e34995SRabin Vincent id = (data[0] << 8) | data[1]; 92727e34995SRabin Vincent if ((id & variant->id_mask) != variant->id_val) { 92827e34995SRabin Vincent dev_err(stmpe->dev, "unknown chip id: %#x\n", id); 92927e34995SRabin Vincent return -EINVAL; 93027e34995SRabin Vincent } 93127e34995SRabin Vincent 93227e34995SRabin Vincent dev_info(stmpe->dev, "%s detected, chip id: %#x\n", variant->name, id); 93327e34995SRabin Vincent 93427e34995SRabin Vincent /* Disable all modules -- subdrivers should enable what they need. */ 93527e34995SRabin Vincent ret = stmpe_disable(stmpe, ~0); 93627e34995SRabin Vincent if (ret) 93727e34995SRabin Vincent return ret; 93827e34995SRabin Vincent 939e31f9b82SChris Blair if (stmpe->irq >= 0) { 9407f7f4ea1SViresh Kumar if (id == STMPE801_ID) 9417f7f4ea1SViresh Kumar icr = STMPE801_REG_SYS_CTRL_INT_EN; 9427f7f4ea1SViresh Kumar else 9437f7f4ea1SViresh Kumar icr = STMPE_ICR_LSB_GIM; 9447f7f4ea1SViresh Kumar 9457f7f4ea1SViresh Kumar /* STMPE801 doesn't support Edge interrupts */ 9467f7f4ea1SViresh Kumar if (id != STMPE801_ID) { 94727e34995SRabin Vincent if (irq_trigger == IRQF_TRIGGER_FALLING || 94827e34995SRabin Vincent irq_trigger == IRQF_TRIGGER_RISING) 94927e34995SRabin Vincent icr |= STMPE_ICR_LSB_EDGE; 9507f7f4ea1SViresh Kumar } 95127e34995SRabin Vincent 95227e34995SRabin Vincent if (irq_trigger == IRQF_TRIGGER_RISING || 9537f7f4ea1SViresh Kumar irq_trigger == IRQF_TRIGGER_HIGH) { 9547f7f4ea1SViresh Kumar if (id == STMPE801_ID) 9557f7f4ea1SViresh Kumar icr |= STMPE801_REG_SYS_CTRL_INT_HI; 9567f7f4ea1SViresh Kumar else 95727e34995SRabin Vincent icr |= STMPE_ICR_LSB_HIGH; 9587f7f4ea1SViresh Kumar } 95927e34995SRabin Vincent 9607f7f4ea1SViresh Kumar if (stmpe->pdata->irq_invert_polarity) { 9617f7f4ea1SViresh Kumar if (id == STMPE801_ID) 9627f7f4ea1SViresh Kumar icr ^= STMPE801_REG_SYS_CTRL_INT_HI; 9637f7f4ea1SViresh Kumar else 96427e34995SRabin Vincent icr ^= STMPE_ICR_LSB_HIGH; 9657f7f4ea1SViresh Kumar } 966e31f9b82SChris Blair } 96727e34995SRabin Vincent 9685981f4e6SSundar R Iyer if (stmpe->pdata->autosleep) { 9695981f4e6SSundar R Iyer ret = stmpe_autosleep(stmpe, autosleep_timeout); 9705981f4e6SSundar R Iyer if (ret) 9715981f4e6SSundar R Iyer return ret; 9725981f4e6SSundar R Iyer } 9735981f4e6SSundar R Iyer 97427e34995SRabin Vincent return stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_ICR_LSB], icr); 97527e34995SRabin Vincent } 97627e34995SRabin Vincent 97727e34995SRabin Vincent static int __devinit stmpe_add_device(struct stmpe *stmpe, 9787da0cbfcSLee Jones struct mfd_cell *cell) 97927e34995SRabin Vincent { 98027e34995SRabin Vincent return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1, 98176f93992SLee Jones NULL, stmpe->irq_base, stmpe->domain); 98227e34995SRabin Vincent } 98327e34995SRabin Vincent 98427e34995SRabin Vincent static int __devinit stmpe_devices_init(struct stmpe *stmpe) 98527e34995SRabin Vincent { 98627e34995SRabin Vincent struct stmpe_variant_info *variant = stmpe->variant; 98727e34995SRabin Vincent unsigned int platform_blocks = stmpe->pdata->blocks; 98827e34995SRabin Vincent int ret = -EINVAL; 9897da0cbfcSLee Jones int i, j; 99027e34995SRabin Vincent 99127e34995SRabin Vincent for (i = 0; i < variant->num_blocks; i++) { 99227e34995SRabin Vincent struct stmpe_variant_block *block = &variant->blocks[i]; 99327e34995SRabin Vincent 99427e34995SRabin Vincent if (!(platform_blocks & block->block)) 99527e34995SRabin Vincent continue; 99627e34995SRabin Vincent 9977da0cbfcSLee Jones for (j = 0; j < block->cell->num_resources; j++) { 9987da0cbfcSLee Jones struct resource *res = 9997da0cbfcSLee Jones (struct resource *) &block->cell->resources[j]; 10007da0cbfcSLee Jones 10017da0cbfcSLee Jones /* Dynamically fill in a variant's IRQ. */ 10027da0cbfcSLee Jones if (res->flags & IORESOURCE_IRQ) 10037da0cbfcSLee Jones res->start = res->end = block->irq + j; 10047da0cbfcSLee Jones } 10057da0cbfcSLee Jones 100627e34995SRabin Vincent platform_blocks &= ~block->block; 10077da0cbfcSLee Jones ret = stmpe_add_device(stmpe, block->cell); 100827e34995SRabin Vincent if (ret) 100927e34995SRabin Vincent return ret; 101027e34995SRabin Vincent } 101127e34995SRabin Vincent 101227e34995SRabin Vincent if (platform_blocks) 101327e34995SRabin Vincent dev_warn(stmpe->dev, 101427e34995SRabin Vincent "platform wants blocks (%#x) not present on variant", 101527e34995SRabin Vincent platform_blocks); 101627e34995SRabin Vincent 101727e34995SRabin Vincent return ret; 101827e34995SRabin Vincent } 101927e34995SRabin Vincent 1020909582caSLee Jones void __devinit stmpe_of_probe(struct stmpe_platform_data *pdata, 1021909582caSLee Jones struct device_node *np) 1022909582caSLee Jones { 1023909582caSLee Jones struct device_node *child; 1024909582caSLee Jones 1025909582caSLee Jones of_property_read_u32(np, "st,autosleep-timeout", 1026909582caSLee Jones &pdata->autosleep_timeout); 1027909582caSLee Jones 1028909582caSLee Jones pdata->autosleep = (pdata->autosleep_timeout) ? true : false; 1029909582caSLee Jones 1030909582caSLee Jones for_each_child_of_node(np, child) { 1031909582caSLee Jones if (!strcmp(child->name, "stmpe_gpio")) { 1032909582caSLee Jones pdata->blocks |= STMPE_BLOCK_GPIO; 1033909582caSLee Jones } 1034909582caSLee Jones if (!strcmp(child->name, "stmpe_keypad")) { 1035909582caSLee Jones pdata->blocks |= STMPE_BLOCK_KEYPAD; 1036909582caSLee Jones } 1037909582caSLee Jones if (!strcmp(child->name, "stmpe_touchscreen")) { 1038909582caSLee Jones pdata->blocks |= STMPE_BLOCK_TOUCHSCREEN; 1039909582caSLee Jones } 1040909582caSLee Jones if (!strcmp(child->name, "stmpe_adc")) { 1041909582caSLee Jones pdata->blocks |= STMPE_BLOCK_ADC; 1042909582caSLee Jones } 1043909582caSLee Jones } 1044909582caSLee Jones } 1045909582caSLee Jones 10461a6e4b74SViresh Kumar /* Called from client specific probe routines */ 10478ad1a973SSamuel Ortiz int __devinit stmpe_probe(struct stmpe_client_info *ci, int partnum) 1048208c4343SSundar Iyer { 10491a6e4b74SViresh Kumar struct stmpe_platform_data *pdata = dev_get_platdata(ci->dev); 1050909582caSLee Jones struct device_node *np = ci->dev->of_node; 105127e34995SRabin Vincent struct stmpe *stmpe; 105227e34995SRabin Vincent int ret; 105327e34995SRabin Vincent 1054909582caSLee Jones if (!pdata) { 1055*cb5faba9SViresh Kumar if (!np) 1056*cb5faba9SViresh Kumar return -EINVAL; 1057*cb5faba9SViresh Kumar 1058*cb5faba9SViresh Kumar pdata = devm_kzalloc(ci->dev, sizeof(*pdata), GFP_KERNEL); 105927e34995SRabin Vincent if (!pdata) 1060909582caSLee Jones return -ENOMEM; 1061909582caSLee Jones 1062909582caSLee Jones stmpe_of_probe(pdata, np); 1063909582caSLee Jones } 106427e34995SRabin Vincent 1065*cb5faba9SViresh Kumar stmpe = devm_kzalloc(ci->dev, sizeof(struct stmpe), GFP_KERNEL); 106627e34995SRabin Vincent if (!stmpe) 106727e34995SRabin Vincent return -ENOMEM; 106827e34995SRabin Vincent 106927e34995SRabin Vincent mutex_init(&stmpe->irq_lock); 107027e34995SRabin Vincent mutex_init(&stmpe->lock); 107127e34995SRabin Vincent 10721a6e4b74SViresh Kumar stmpe->dev = ci->dev; 10731a6e4b74SViresh Kumar stmpe->client = ci->client; 107427e34995SRabin Vincent stmpe->pdata = pdata; 107527e34995SRabin Vincent stmpe->irq_base = pdata->irq_base; 10761a6e4b74SViresh Kumar stmpe->ci = ci; 10771a6e4b74SViresh Kumar stmpe->partnum = partnum; 10781a6e4b74SViresh Kumar stmpe->variant = stmpe_variant_info[partnum]; 107927e34995SRabin Vincent stmpe->regs = stmpe->variant->regs; 108027e34995SRabin Vincent stmpe->num_gpios = stmpe->variant->num_gpios; 10811a6e4b74SViresh Kumar dev_set_drvdata(stmpe->dev, stmpe); 108227e34995SRabin Vincent 10831a6e4b74SViresh Kumar if (ci->init) 10841a6e4b74SViresh Kumar ci->init(stmpe); 108527e34995SRabin Vincent 108673de16dbSViresh Kumar if (pdata->irq_over_gpio) { 1087*cb5faba9SViresh Kumar ret = devm_gpio_request_one(ci->dev, pdata->irq_gpio, 1088*cb5faba9SViresh Kumar GPIOF_DIR_IN, "stmpe"); 108973de16dbSViresh Kumar if (ret) { 109073de16dbSViresh Kumar dev_err(stmpe->dev, "failed to request IRQ GPIO: %d\n", 109173de16dbSViresh Kumar ret); 1092*cb5faba9SViresh Kumar return ret; 109373de16dbSViresh Kumar } 109473de16dbSViresh Kumar 109573de16dbSViresh Kumar stmpe->irq = gpio_to_irq(pdata->irq_gpio); 109673de16dbSViresh Kumar } else { 10971a6e4b74SViresh Kumar stmpe->irq = ci->irq; 109873de16dbSViresh Kumar } 109973de16dbSViresh Kumar 1100e31f9b82SChris Blair if (stmpe->irq < 0) { 1101e31f9b82SChris Blair /* use alternate variant info for no-irq mode, if supported */ 1102e31f9b82SChris Blair dev_info(stmpe->dev, 1103e31f9b82SChris Blair "%s configured in no-irq mode by platform data\n", 1104e31f9b82SChris Blair stmpe->variant->name); 1105e31f9b82SChris Blair if (!stmpe_noirq_variant_info[stmpe->partnum]) { 1106e31f9b82SChris Blair dev_err(stmpe->dev, 1107e31f9b82SChris Blair "%s does not support no-irq mode!\n", 1108e31f9b82SChris Blair stmpe->variant->name); 1109*cb5faba9SViresh Kumar return -ENODEV; 1110e31f9b82SChris Blair } 1111e31f9b82SChris Blair stmpe->variant = stmpe_noirq_variant_info[stmpe->partnum]; 1112e31f9b82SChris Blair } 1113e31f9b82SChris Blair 111427e34995SRabin Vincent ret = stmpe_chip_init(stmpe); 111527e34995SRabin Vincent if (ret) 1116*cb5faba9SViresh Kumar return ret; 111727e34995SRabin Vincent 1118e31f9b82SChris Blair if (stmpe->irq >= 0) { 1119909582caSLee Jones ret = stmpe_irq_init(stmpe, np); 112027e34995SRabin Vincent if (ret) 1121*cb5faba9SViresh Kumar return ret; 112227e34995SRabin Vincent 1123*cb5faba9SViresh Kumar ret = devm_request_threaded_irq(ci->dev, stmpe->irq, NULL, 1124*cb5faba9SViresh Kumar stmpe_irq, pdata->irq_trigger | IRQF_ONESHOT, 1125e31f9b82SChris Blair "stmpe", stmpe); 112627e34995SRabin Vincent if (ret) { 1127e31f9b82SChris Blair dev_err(stmpe->dev, "failed to request IRQ: %d\n", 1128e31f9b82SChris Blair ret); 1129*cb5faba9SViresh Kumar return ret; 113027e34995SRabin Vincent } 1131e31f9b82SChris Blair } 113227e34995SRabin Vincent 113327e34995SRabin Vincent ret = stmpe_devices_init(stmpe); 1134*cb5faba9SViresh Kumar if (!ret) 113527e34995SRabin Vincent return 0; 113627e34995SRabin Vincent 1137*cb5faba9SViresh Kumar dev_err(stmpe->dev, "failed to add children\n"); 113827e34995SRabin Vincent mfd_remove_devices(stmpe->dev); 1139*cb5faba9SViresh Kumar 114027e34995SRabin Vincent return ret; 114127e34995SRabin Vincent } 114227e34995SRabin Vincent 11431a6e4b74SViresh Kumar int stmpe_remove(struct stmpe *stmpe) 114427e34995SRabin Vincent { 114527e34995SRabin Vincent mfd_remove_devices(stmpe->dev); 114627e34995SRabin Vincent 114727e34995SRabin Vincent return 0; 114827e34995SRabin Vincent } 114927e34995SRabin Vincent 1150208c4343SSundar Iyer #ifdef CONFIG_PM 11511a6e4b74SViresh Kumar static int stmpe_suspend(struct device *dev) 11521a6e4b74SViresh Kumar { 11531a6e4b74SViresh Kumar struct stmpe *stmpe = dev_get_drvdata(dev); 11541a6e4b74SViresh Kumar 1155e31f9b82SChris Blair if (stmpe->irq >= 0 && device_may_wakeup(dev)) 11561a6e4b74SViresh Kumar enable_irq_wake(stmpe->irq); 11571a6e4b74SViresh Kumar 11581a6e4b74SViresh Kumar return 0; 11591a6e4b74SViresh Kumar } 11601a6e4b74SViresh Kumar 11611a6e4b74SViresh Kumar static int stmpe_resume(struct device *dev) 11621a6e4b74SViresh Kumar { 11631a6e4b74SViresh Kumar struct stmpe *stmpe = dev_get_drvdata(dev); 11641a6e4b74SViresh Kumar 1165e31f9b82SChris Blair if (stmpe->irq >= 0 && device_may_wakeup(dev)) 11661a6e4b74SViresh Kumar disable_irq_wake(stmpe->irq); 11671a6e4b74SViresh Kumar 11681a6e4b74SViresh Kumar return 0; 11691a6e4b74SViresh Kumar } 11701a6e4b74SViresh Kumar 11711a6e4b74SViresh Kumar const struct dev_pm_ops stmpe_dev_pm_ops = { 1172208c4343SSundar Iyer .suspend = stmpe_suspend, 1173208c4343SSundar Iyer .resume = stmpe_resume, 1174208c4343SSundar Iyer }; 1175208c4343SSundar Iyer #endif 1176