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 10ac713cc9SVipul Kumar Samar #include <linux/err.h> 1173de16dbSViresh Kumar #include <linux/gpio.h> 12dba61c8fSSamuel Ortiz #include <linux/export.h> 1327e34995SRabin Vincent #include <linux/kernel.h> 1427e34995SRabin Vincent #include <linux/interrupt.h> 1527e34995SRabin Vincent #include <linux/irq.h> 1676f93992SLee Jones #include <linux/irqdomain.h> 1720d5c7deSRandy Dunlap #include <linux/of.h> 18ac713cc9SVipul Kumar Samar #include <linux/of_gpio.h> 191a6e4b74SViresh Kumar #include <linux/pm.h> 2027e34995SRabin Vincent #include <linux/slab.h> 2127e34995SRabin Vincent #include <linux/mfd/core.h> 22230f13a5SJean-Nicolas Graux #include <linux/delay.h> 239c9e3214SLinus Walleij #include <linux/regulator/consumer.h> 2427e34995SRabin Vincent #include "stmpe.h" 2527e34995SRabin Vincent 26fc1882dcSLinus Walleij /** 27fc1882dcSLinus Walleij * struct stmpe_platform_data - STMPE platform data 28fc1882dcSLinus Walleij * @id: device id to distinguish between multiple STMPEs on the same board 29fc1882dcSLinus Walleij * @blocks: bitmask of blocks to enable (use STMPE_BLOCK_*) 30fc1882dcSLinus Walleij * @irq_trigger: IRQ trigger to use for the interrupt to the host 31fc1882dcSLinus Walleij * @autosleep: bool to enable/disable stmpe autosleep 32fc1882dcSLinus Walleij * @autosleep_timeout: inactivity timeout in milliseconds for autosleep 33fc1882dcSLinus Walleij * @irq_over_gpio: true if gpio is used to get irq 34fc1882dcSLinus Walleij * @irq_gpio: gpio number over which irq will be requested (significant only if 35fc1882dcSLinus Walleij * irq_over_gpio is true) 36fc1882dcSLinus Walleij */ 37fc1882dcSLinus Walleij struct stmpe_platform_data { 38fc1882dcSLinus Walleij int id; 39fc1882dcSLinus Walleij unsigned int blocks; 40fc1882dcSLinus Walleij unsigned int irq_trigger; 41fc1882dcSLinus Walleij bool autosleep; 42fc1882dcSLinus Walleij bool irq_over_gpio; 43fc1882dcSLinus Walleij int irq_gpio; 44fc1882dcSLinus Walleij int autosleep_timeout; 45fc1882dcSLinus Walleij }; 46fc1882dcSLinus Walleij 4727e34995SRabin Vincent static int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks) 4827e34995SRabin Vincent { 4927e34995SRabin Vincent return stmpe->variant->enable(stmpe, blocks, true); 5027e34995SRabin Vincent } 5127e34995SRabin Vincent 5227e34995SRabin Vincent static int __stmpe_disable(struct stmpe *stmpe, unsigned int blocks) 5327e34995SRabin Vincent { 5427e34995SRabin Vincent return stmpe->variant->enable(stmpe, blocks, false); 5527e34995SRabin Vincent } 5627e34995SRabin Vincent 5727e34995SRabin Vincent static int __stmpe_reg_read(struct stmpe *stmpe, u8 reg) 5827e34995SRabin Vincent { 5927e34995SRabin Vincent int ret; 6027e34995SRabin Vincent 611a6e4b74SViresh Kumar ret = stmpe->ci->read_byte(stmpe, reg); 6227e34995SRabin Vincent if (ret < 0) 631a6e4b74SViresh Kumar dev_err(stmpe->dev, "failed to read reg %#x: %d\n", reg, ret); 6427e34995SRabin Vincent 6527e34995SRabin Vincent dev_vdbg(stmpe->dev, "rd: reg %#x => data %#x\n", reg, ret); 6627e34995SRabin Vincent 6727e34995SRabin Vincent return ret; 6827e34995SRabin Vincent } 6927e34995SRabin Vincent 7027e34995SRabin Vincent static int __stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val) 7127e34995SRabin Vincent { 7227e34995SRabin Vincent int ret; 7327e34995SRabin Vincent 7427e34995SRabin Vincent dev_vdbg(stmpe->dev, "wr: reg %#x <= %#x\n", reg, val); 7527e34995SRabin Vincent 761a6e4b74SViresh Kumar ret = stmpe->ci->write_byte(stmpe, reg, val); 7727e34995SRabin Vincent if (ret < 0) 781a6e4b74SViresh Kumar dev_err(stmpe->dev, "failed to write reg %#x: %d\n", reg, ret); 7927e34995SRabin Vincent 8027e34995SRabin Vincent return ret; 8127e34995SRabin Vincent } 8227e34995SRabin Vincent 8327e34995SRabin Vincent static int __stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val) 8427e34995SRabin Vincent { 8527e34995SRabin Vincent int ret; 8627e34995SRabin Vincent 8727e34995SRabin Vincent ret = __stmpe_reg_read(stmpe, reg); 8827e34995SRabin Vincent if (ret < 0) 8927e34995SRabin Vincent return ret; 9027e34995SRabin Vincent 9127e34995SRabin Vincent ret &= ~mask; 9227e34995SRabin Vincent ret |= val; 9327e34995SRabin Vincent 9427e34995SRabin Vincent return __stmpe_reg_write(stmpe, reg, ret); 9527e34995SRabin Vincent } 9627e34995SRabin Vincent 9727e34995SRabin Vincent static int __stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length, 9827e34995SRabin Vincent u8 *values) 9927e34995SRabin Vincent { 10027e34995SRabin Vincent int ret; 10127e34995SRabin Vincent 1021a6e4b74SViresh Kumar ret = stmpe->ci->read_block(stmpe, reg, length, values); 10327e34995SRabin Vincent if (ret < 0) 1041a6e4b74SViresh Kumar dev_err(stmpe->dev, "failed to read regs %#x: %d\n", reg, ret); 10527e34995SRabin Vincent 10627e34995SRabin Vincent dev_vdbg(stmpe->dev, "rd: reg %#x (%d) => ret %#x\n", reg, length, ret); 10727e34995SRabin Vincent stmpe_dump_bytes("stmpe rd: ", values, length); 10827e34995SRabin Vincent 10927e34995SRabin Vincent return ret; 11027e34995SRabin Vincent } 11127e34995SRabin Vincent 11227e34995SRabin Vincent static int __stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length, 11327e34995SRabin Vincent const u8 *values) 11427e34995SRabin Vincent { 11527e34995SRabin Vincent int ret; 11627e34995SRabin Vincent 11727e34995SRabin Vincent dev_vdbg(stmpe->dev, "wr: regs %#x (%d)\n", reg, length); 11827e34995SRabin Vincent stmpe_dump_bytes("stmpe wr: ", values, length); 11927e34995SRabin Vincent 1201a6e4b74SViresh Kumar ret = stmpe->ci->write_block(stmpe, reg, length, values); 12127e34995SRabin Vincent if (ret < 0) 1221a6e4b74SViresh Kumar dev_err(stmpe->dev, "failed to write regs %#x: %d\n", reg, ret); 12327e34995SRabin Vincent 12427e34995SRabin Vincent return ret; 12527e34995SRabin Vincent } 12627e34995SRabin Vincent 12727e34995SRabin Vincent /** 12827e34995SRabin Vincent * stmpe_enable - enable blocks on an STMPE device 12927e34995SRabin Vincent * @stmpe: Device to work on 13027e34995SRabin Vincent * @blocks: Mask of blocks (enum stmpe_block values) to enable 13127e34995SRabin Vincent */ 13227e34995SRabin Vincent int stmpe_enable(struct stmpe *stmpe, unsigned int blocks) 13327e34995SRabin Vincent { 13427e34995SRabin Vincent int ret; 13527e34995SRabin Vincent 13627e34995SRabin Vincent mutex_lock(&stmpe->lock); 13727e34995SRabin Vincent ret = __stmpe_enable(stmpe, blocks); 13827e34995SRabin Vincent mutex_unlock(&stmpe->lock); 13927e34995SRabin Vincent 14027e34995SRabin Vincent return ret; 14127e34995SRabin Vincent } 14227e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_enable); 14327e34995SRabin Vincent 14427e34995SRabin Vincent /** 14527e34995SRabin Vincent * stmpe_disable - disable blocks on an STMPE device 14627e34995SRabin Vincent * @stmpe: Device to work on 14727e34995SRabin Vincent * @blocks: Mask of blocks (enum stmpe_block values) to enable 14827e34995SRabin Vincent */ 14927e34995SRabin Vincent int stmpe_disable(struct stmpe *stmpe, unsigned int blocks) 15027e34995SRabin Vincent { 15127e34995SRabin Vincent int ret; 15227e34995SRabin Vincent 15327e34995SRabin Vincent mutex_lock(&stmpe->lock); 15427e34995SRabin Vincent ret = __stmpe_disable(stmpe, blocks); 15527e34995SRabin Vincent mutex_unlock(&stmpe->lock); 15627e34995SRabin Vincent 15727e34995SRabin Vincent return ret; 15827e34995SRabin Vincent } 15927e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_disable); 16027e34995SRabin Vincent 16127e34995SRabin Vincent /** 16227e34995SRabin Vincent * stmpe_reg_read() - read a single STMPE register 16327e34995SRabin Vincent * @stmpe: Device to read from 16427e34995SRabin Vincent * @reg: Register to read 16527e34995SRabin Vincent */ 16627e34995SRabin Vincent int stmpe_reg_read(struct stmpe *stmpe, u8 reg) 16727e34995SRabin Vincent { 16827e34995SRabin Vincent int ret; 16927e34995SRabin Vincent 17027e34995SRabin Vincent mutex_lock(&stmpe->lock); 17127e34995SRabin Vincent ret = __stmpe_reg_read(stmpe, reg); 17227e34995SRabin Vincent mutex_unlock(&stmpe->lock); 17327e34995SRabin Vincent 17427e34995SRabin Vincent return ret; 17527e34995SRabin Vincent } 17627e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_reg_read); 17727e34995SRabin Vincent 17827e34995SRabin Vincent /** 17927e34995SRabin Vincent * stmpe_reg_write() - write a single STMPE register 18027e34995SRabin Vincent * @stmpe: Device to write to 18127e34995SRabin Vincent * @reg: Register to write 18227e34995SRabin Vincent * @val: Value to write 18327e34995SRabin Vincent */ 18427e34995SRabin Vincent int stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val) 18527e34995SRabin Vincent { 18627e34995SRabin Vincent int ret; 18727e34995SRabin Vincent 18827e34995SRabin Vincent mutex_lock(&stmpe->lock); 18927e34995SRabin Vincent ret = __stmpe_reg_write(stmpe, reg, val); 19027e34995SRabin Vincent mutex_unlock(&stmpe->lock); 19127e34995SRabin Vincent 19227e34995SRabin Vincent return ret; 19327e34995SRabin Vincent } 19427e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_reg_write); 19527e34995SRabin Vincent 19627e34995SRabin Vincent /** 19727e34995SRabin Vincent * stmpe_set_bits() - set the value of a bitfield in a STMPE register 19827e34995SRabin Vincent * @stmpe: Device to write to 19927e34995SRabin Vincent * @reg: Register to write 20027e34995SRabin Vincent * @mask: Mask of bits to set 20127e34995SRabin Vincent * @val: Value to set 20227e34995SRabin Vincent */ 20327e34995SRabin Vincent int stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val) 20427e34995SRabin Vincent { 20527e34995SRabin Vincent int ret; 20627e34995SRabin Vincent 20727e34995SRabin Vincent mutex_lock(&stmpe->lock); 20827e34995SRabin Vincent ret = __stmpe_set_bits(stmpe, reg, mask, val); 20927e34995SRabin Vincent mutex_unlock(&stmpe->lock); 21027e34995SRabin Vincent 21127e34995SRabin Vincent return ret; 21227e34995SRabin Vincent } 21327e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_set_bits); 21427e34995SRabin Vincent 21527e34995SRabin Vincent /** 21627e34995SRabin Vincent * stmpe_block_read() - read multiple STMPE registers 21727e34995SRabin Vincent * @stmpe: Device to read from 21827e34995SRabin Vincent * @reg: First register 21927e34995SRabin Vincent * @length: Number of registers 22027e34995SRabin Vincent * @values: Buffer to write to 22127e34995SRabin Vincent */ 22227e34995SRabin Vincent int stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values) 22327e34995SRabin Vincent { 22427e34995SRabin Vincent int ret; 22527e34995SRabin Vincent 22627e34995SRabin Vincent mutex_lock(&stmpe->lock); 22727e34995SRabin Vincent ret = __stmpe_block_read(stmpe, reg, length, values); 22827e34995SRabin Vincent mutex_unlock(&stmpe->lock); 22927e34995SRabin Vincent 23027e34995SRabin Vincent return ret; 23127e34995SRabin Vincent } 23227e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_block_read); 23327e34995SRabin Vincent 23427e34995SRabin Vincent /** 23527e34995SRabin Vincent * stmpe_block_write() - write multiple STMPE registers 23627e34995SRabin Vincent * @stmpe: Device to write to 23727e34995SRabin Vincent * @reg: First register 23827e34995SRabin Vincent * @length: Number of registers 23927e34995SRabin Vincent * @values: Values to write 24027e34995SRabin Vincent */ 24127e34995SRabin Vincent int stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length, 24227e34995SRabin Vincent const u8 *values) 24327e34995SRabin Vincent { 24427e34995SRabin Vincent int ret; 24527e34995SRabin Vincent 24627e34995SRabin Vincent mutex_lock(&stmpe->lock); 24727e34995SRabin Vincent ret = __stmpe_block_write(stmpe, reg, length, values); 24827e34995SRabin Vincent mutex_unlock(&stmpe->lock); 24927e34995SRabin Vincent 25027e34995SRabin Vincent return ret; 25127e34995SRabin Vincent } 25227e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_block_write); 25327e34995SRabin Vincent 25427e34995SRabin Vincent /** 2554dcaa6b6SOm Prakash * stmpe_set_altfunc()- set the alternate function for STMPE pins 25627e34995SRabin Vincent * @stmpe: Device to configure 25727e34995SRabin Vincent * @pins: Bitmask of pins to affect 25827e34995SRabin Vincent * @block: block to enable alternate functions for 25927e34995SRabin Vincent * 26027e34995SRabin Vincent * @pins is assumed to have a bit set for each of the bits whose alternate 26127e34995SRabin Vincent * function is to be changed, numbered according to the GPIOXY numbers. 26227e34995SRabin Vincent * 26327e34995SRabin Vincent * If the GPIO module is not enabled, this function automatically enables it in 26427e34995SRabin Vincent * order to perform the change. 26527e34995SRabin Vincent */ 26627e34995SRabin Vincent int stmpe_set_altfunc(struct stmpe *stmpe, u32 pins, enum stmpe_block block) 26727e34995SRabin Vincent { 26827e34995SRabin Vincent struct stmpe_variant_info *variant = stmpe->variant; 26927e34995SRabin Vincent u8 regaddr = stmpe->regs[STMPE_IDX_GPAFR_U_MSB]; 27027e34995SRabin Vincent int af_bits = variant->af_bits; 27127e34995SRabin Vincent int numregs = DIV_ROUND_UP(stmpe->num_gpios * af_bits, 8); 27227e34995SRabin Vincent int mask = (1 << af_bits) - 1; 2737929fa77SLee Jones u8 regs[8]; 2747f7f4ea1SViresh Kumar int af, afperreg, ret; 27527e34995SRabin Vincent 2767f7f4ea1SViresh Kumar if (!variant->get_altfunc) 2777f7f4ea1SViresh Kumar return 0; 2787f7f4ea1SViresh Kumar 2797f7f4ea1SViresh Kumar afperreg = 8 / af_bits; 28027e34995SRabin Vincent mutex_lock(&stmpe->lock); 28127e34995SRabin Vincent 28227e34995SRabin Vincent ret = __stmpe_enable(stmpe, STMPE_BLOCK_GPIO); 28327e34995SRabin Vincent if (ret < 0) 28427e34995SRabin Vincent goto out; 28527e34995SRabin Vincent 28627e34995SRabin Vincent ret = __stmpe_block_read(stmpe, regaddr, numregs, regs); 28727e34995SRabin Vincent if (ret < 0) 28827e34995SRabin Vincent goto out; 28927e34995SRabin Vincent 29027e34995SRabin Vincent af = variant->get_altfunc(stmpe, block); 29127e34995SRabin Vincent 29227e34995SRabin Vincent while (pins) { 29327e34995SRabin Vincent int pin = __ffs(pins); 29427e34995SRabin Vincent int regoffset = numregs - (pin / afperreg) - 1; 29527e34995SRabin Vincent int pos = (pin % afperreg) * (8 / afperreg); 29627e34995SRabin Vincent 29727e34995SRabin Vincent regs[regoffset] &= ~(mask << pos); 29827e34995SRabin Vincent regs[regoffset] |= af << pos; 29927e34995SRabin Vincent 30027e34995SRabin Vincent pins &= ~(1 << pin); 30127e34995SRabin Vincent } 30227e34995SRabin Vincent 30327e34995SRabin Vincent ret = __stmpe_block_write(stmpe, regaddr, numregs, regs); 30427e34995SRabin Vincent 30527e34995SRabin Vincent out: 30627e34995SRabin Vincent mutex_unlock(&stmpe->lock); 30727e34995SRabin Vincent return ret; 30827e34995SRabin Vincent } 30927e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_set_altfunc); 31027e34995SRabin Vincent 31127e34995SRabin Vincent /* 31227e34995SRabin Vincent * GPIO (all variants) 31327e34995SRabin Vincent */ 31427e34995SRabin Vincent 31527e34995SRabin Vincent static struct resource stmpe_gpio_resources[] = { 31627e34995SRabin Vincent /* Start and end filled dynamically */ 31727e34995SRabin Vincent { 31827e34995SRabin Vincent .flags = IORESOURCE_IRQ, 31927e34995SRabin Vincent }, 32027e34995SRabin Vincent }; 32127e34995SRabin Vincent 3226bbb3c4cSGeert Uytterhoeven static const struct mfd_cell stmpe_gpio_cell = { 32327e34995SRabin Vincent .name = "stmpe-gpio", 32486605cfeSVipul Kumar Samar .of_compatible = "st,stmpe-gpio", 32527e34995SRabin Vincent .resources = stmpe_gpio_resources, 32627e34995SRabin Vincent .num_resources = ARRAY_SIZE(stmpe_gpio_resources), 32727e34995SRabin Vincent }; 32827e34995SRabin Vincent 3296bbb3c4cSGeert Uytterhoeven static const struct mfd_cell stmpe_gpio_cell_noirq = { 330e31f9b82SChris Blair .name = "stmpe-gpio", 33186605cfeSVipul Kumar Samar .of_compatible = "st,stmpe-gpio", 332e31f9b82SChris Blair /* gpio cell resources consist of an irq only so no resources here */ 333e31f9b82SChris Blair }; 334e31f9b82SChris Blair 33527e34995SRabin Vincent /* 33627e34995SRabin Vincent * Keypad (1601, 2401, 2403) 33727e34995SRabin Vincent */ 33827e34995SRabin Vincent 33927e34995SRabin Vincent static struct resource stmpe_keypad_resources[] = { 34027e34995SRabin Vincent { 34127e34995SRabin Vincent .name = "KEYPAD", 34227e34995SRabin Vincent .flags = IORESOURCE_IRQ, 34327e34995SRabin Vincent }, 34427e34995SRabin Vincent { 34527e34995SRabin Vincent .name = "KEYPAD_OVER", 34627e34995SRabin Vincent .flags = IORESOURCE_IRQ, 34727e34995SRabin Vincent }, 34827e34995SRabin Vincent }; 34927e34995SRabin Vincent 3506bbb3c4cSGeert Uytterhoeven static const struct mfd_cell stmpe_keypad_cell = { 35127e34995SRabin Vincent .name = "stmpe-keypad", 3526ea32387SDmitry Torokhov .of_compatible = "st,stmpe-keypad", 35327e34995SRabin Vincent .resources = stmpe_keypad_resources, 35427e34995SRabin Vincent .num_resources = ARRAY_SIZE(stmpe_keypad_resources), 35527e34995SRabin Vincent }; 35627e34995SRabin Vincent 35727e34995SRabin Vincent /* 358b273c5e0SLinus Walleij * PWM (1601, 2401, 2403) 359b273c5e0SLinus Walleij */ 360b273c5e0SLinus Walleij static struct resource stmpe_pwm_resources[] = { 361b273c5e0SLinus Walleij { 362b273c5e0SLinus Walleij .name = "PWM0", 363b273c5e0SLinus Walleij .flags = IORESOURCE_IRQ, 364b273c5e0SLinus Walleij }, 365b273c5e0SLinus Walleij { 366b273c5e0SLinus Walleij .name = "PWM1", 367b273c5e0SLinus Walleij .flags = IORESOURCE_IRQ, 368b273c5e0SLinus Walleij }, 369b273c5e0SLinus Walleij { 370b273c5e0SLinus Walleij .name = "PWM2", 371b273c5e0SLinus Walleij .flags = IORESOURCE_IRQ, 372b273c5e0SLinus Walleij }, 373b273c5e0SLinus Walleij }; 374b273c5e0SLinus Walleij 375b273c5e0SLinus Walleij static const struct mfd_cell stmpe_pwm_cell = { 376b273c5e0SLinus Walleij .name = "stmpe-pwm", 377b273c5e0SLinus Walleij .of_compatible = "st,stmpe-pwm", 378b273c5e0SLinus Walleij .resources = stmpe_pwm_resources, 379b273c5e0SLinus Walleij .num_resources = ARRAY_SIZE(stmpe_pwm_resources), 380b273c5e0SLinus Walleij }; 381b273c5e0SLinus Walleij 382b273c5e0SLinus Walleij /* 3837f7f4ea1SViresh Kumar * STMPE801 3847f7f4ea1SViresh Kumar */ 3857f7f4ea1SViresh Kumar static const u8 stmpe801_regs[] = { 3867f7f4ea1SViresh Kumar [STMPE_IDX_CHIP_ID] = STMPE801_REG_CHIP_ID, 3877f7f4ea1SViresh Kumar [STMPE_IDX_ICR_LSB] = STMPE801_REG_SYS_CTRL, 3887f7f4ea1SViresh Kumar [STMPE_IDX_GPMR_LSB] = STMPE801_REG_GPIO_MP_STA, 3897f7f4ea1SViresh Kumar [STMPE_IDX_GPSR_LSB] = STMPE801_REG_GPIO_SET_PIN, 3907f7f4ea1SViresh Kumar [STMPE_IDX_GPCR_LSB] = STMPE801_REG_GPIO_SET_PIN, 3917f7f4ea1SViresh Kumar [STMPE_IDX_GPDR_LSB] = STMPE801_REG_GPIO_DIR, 3927f7f4ea1SViresh Kumar [STMPE_IDX_IEGPIOR_LSB] = STMPE801_REG_GPIO_INT_EN, 3937f7f4ea1SViresh Kumar [STMPE_IDX_ISGPIOR_MSB] = STMPE801_REG_GPIO_INT_STA, 3947f7f4ea1SViresh Kumar 3957f7f4ea1SViresh Kumar }; 3967f7f4ea1SViresh Kumar 3977f7f4ea1SViresh Kumar static struct stmpe_variant_block stmpe801_blocks[] = { 3987f7f4ea1SViresh Kumar { 3997f7f4ea1SViresh Kumar .cell = &stmpe_gpio_cell, 4007f7f4ea1SViresh Kumar .irq = 0, 4017f7f4ea1SViresh Kumar .block = STMPE_BLOCK_GPIO, 4027f7f4ea1SViresh Kumar }, 4037f7f4ea1SViresh Kumar }; 4047f7f4ea1SViresh Kumar 405e31f9b82SChris Blair static struct stmpe_variant_block stmpe801_blocks_noirq[] = { 406e31f9b82SChris Blair { 407e31f9b82SChris Blair .cell = &stmpe_gpio_cell_noirq, 408e31f9b82SChris Blair .block = STMPE_BLOCK_GPIO, 409e31f9b82SChris Blair }, 410e31f9b82SChris Blair }; 411e31f9b82SChris Blair 4127f7f4ea1SViresh Kumar static int stmpe801_enable(struct stmpe *stmpe, unsigned int blocks, 4137f7f4ea1SViresh Kumar bool enable) 4147f7f4ea1SViresh Kumar { 4157f7f4ea1SViresh Kumar if (blocks & STMPE_BLOCK_GPIO) 4167f7f4ea1SViresh Kumar return 0; 4177f7f4ea1SViresh Kumar else 4187f7f4ea1SViresh Kumar return -EINVAL; 4197f7f4ea1SViresh Kumar } 4207f7f4ea1SViresh Kumar 4217f7f4ea1SViresh Kumar static struct stmpe_variant_info stmpe801 = { 4227f7f4ea1SViresh Kumar .name = "stmpe801", 4237f7f4ea1SViresh Kumar .id_val = STMPE801_ID, 4247f7f4ea1SViresh Kumar .id_mask = 0xffff, 4257f7f4ea1SViresh Kumar .num_gpios = 8, 4267f7f4ea1SViresh Kumar .regs = stmpe801_regs, 4277f7f4ea1SViresh Kumar .blocks = stmpe801_blocks, 4287f7f4ea1SViresh Kumar .num_blocks = ARRAY_SIZE(stmpe801_blocks), 4297f7f4ea1SViresh Kumar .num_irqs = STMPE801_NR_INTERNAL_IRQS, 4307f7f4ea1SViresh Kumar .enable = stmpe801_enable, 4317f7f4ea1SViresh Kumar }; 4327f7f4ea1SViresh Kumar 433e31f9b82SChris Blair static struct stmpe_variant_info stmpe801_noirq = { 434e31f9b82SChris Blair .name = "stmpe801", 435e31f9b82SChris Blair .id_val = STMPE801_ID, 436e31f9b82SChris Blair .id_mask = 0xffff, 437e31f9b82SChris Blair .num_gpios = 8, 438e31f9b82SChris Blair .regs = stmpe801_regs, 439e31f9b82SChris Blair .blocks = stmpe801_blocks_noirq, 440e31f9b82SChris Blair .num_blocks = ARRAY_SIZE(stmpe801_blocks_noirq), 441e31f9b82SChris Blair .enable = stmpe801_enable, 442e31f9b82SChris Blair }; 443e31f9b82SChris Blair 4447f7f4ea1SViresh Kumar /* 4451cda2394SViresh Kumar * Touchscreen (STMPE811 or STMPE610) 44627e34995SRabin Vincent */ 44727e34995SRabin Vincent 44827e34995SRabin Vincent static struct resource stmpe_ts_resources[] = { 44927e34995SRabin Vincent { 45027e34995SRabin Vincent .name = "TOUCH_DET", 45127e34995SRabin Vincent .flags = IORESOURCE_IRQ, 45227e34995SRabin Vincent }, 45327e34995SRabin Vincent { 45427e34995SRabin Vincent .name = "FIFO_TH", 45527e34995SRabin Vincent .flags = IORESOURCE_IRQ, 45627e34995SRabin Vincent }, 45727e34995SRabin Vincent }; 45827e34995SRabin Vincent 4596bbb3c4cSGeert Uytterhoeven static const struct mfd_cell stmpe_ts_cell = { 46027e34995SRabin Vincent .name = "stmpe-ts", 461037db524SVipul Kumar Samar .of_compatible = "st,stmpe-ts", 46227e34995SRabin Vincent .resources = stmpe_ts_resources, 46327e34995SRabin Vincent .num_resources = ARRAY_SIZE(stmpe_ts_resources), 46427e34995SRabin Vincent }; 46527e34995SRabin Vincent 46627e34995SRabin Vincent /* 4671cda2394SViresh Kumar * STMPE811 or STMPE610 46827e34995SRabin Vincent */ 46927e34995SRabin Vincent 47027e34995SRabin Vincent static const u8 stmpe811_regs[] = { 47127e34995SRabin Vincent [STMPE_IDX_CHIP_ID] = STMPE811_REG_CHIP_ID, 4720f4be8cfSPatrice Chotard [STMPE_IDX_SYS_CTRL] = STMPE811_REG_SYS_CTRL, 4730f4be8cfSPatrice Chotard [STMPE_IDX_SYS_CTRL2] = STMPE811_REG_SYS_CTRL2, 47427e34995SRabin Vincent [STMPE_IDX_ICR_LSB] = STMPE811_REG_INT_CTRL, 47527e34995SRabin Vincent [STMPE_IDX_IER_LSB] = STMPE811_REG_INT_EN, 47627e34995SRabin Vincent [STMPE_IDX_ISR_MSB] = STMPE811_REG_INT_STA, 47727e34995SRabin Vincent [STMPE_IDX_GPMR_LSB] = STMPE811_REG_GPIO_MP_STA, 47827e34995SRabin Vincent [STMPE_IDX_GPSR_LSB] = STMPE811_REG_GPIO_SET_PIN, 47927e34995SRabin Vincent [STMPE_IDX_GPCR_LSB] = STMPE811_REG_GPIO_CLR_PIN, 48027e34995SRabin Vincent [STMPE_IDX_GPDR_LSB] = STMPE811_REG_GPIO_DIR, 48127e34995SRabin Vincent [STMPE_IDX_GPRER_LSB] = STMPE811_REG_GPIO_RE, 48227e34995SRabin Vincent [STMPE_IDX_GPFER_LSB] = STMPE811_REG_GPIO_FE, 48327e34995SRabin Vincent [STMPE_IDX_GPAFR_U_MSB] = STMPE811_REG_GPIO_AF, 48427e34995SRabin Vincent [STMPE_IDX_IEGPIOR_LSB] = STMPE811_REG_GPIO_INT_EN, 48527e34995SRabin Vincent [STMPE_IDX_ISGPIOR_MSB] = STMPE811_REG_GPIO_INT_STA, 486897ac667SPatrice Chotard [STMPE_IDX_GPEDR_LSB] = STMPE811_REG_GPIO_ED, 48727e34995SRabin Vincent }; 48827e34995SRabin Vincent 48927e34995SRabin Vincent static struct stmpe_variant_block stmpe811_blocks[] = { 49027e34995SRabin Vincent { 49127e34995SRabin Vincent .cell = &stmpe_gpio_cell, 49227e34995SRabin Vincent .irq = STMPE811_IRQ_GPIOC, 49327e34995SRabin Vincent .block = STMPE_BLOCK_GPIO, 49427e34995SRabin Vincent }, 49527e34995SRabin Vincent { 49627e34995SRabin Vincent .cell = &stmpe_ts_cell, 49727e34995SRabin Vincent .irq = STMPE811_IRQ_TOUCH_DET, 49827e34995SRabin Vincent .block = STMPE_BLOCK_TOUCHSCREEN, 49927e34995SRabin Vincent }, 50027e34995SRabin Vincent }; 50127e34995SRabin Vincent 50227e34995SRabin Vincent static int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks, 50327e34995SRabin Vincent bool enable) 50427e34995SRabin Vincent { 50527e34995SRabin Vincent unsigned int mask = 0; 50627e34995SRabin Vincent 50727e34995SRabin Vincent if (blocks & STMPE_BLOCK_GPIO) 50827e34995SRabin Vincent mask |= STMPE811_SYS_CTRL2_GPIO_OFF; 50927e34995SRabin Vincent 51027e34995SRabin Vincent if (blocks & STMPE_BLOCK_ADC) 51127e34995SRabin Vincent mask |= STMPE811_SYS_CTRL2_ADC_OFF; 51227e34995SRabin Vincent 51327e34995SRabin Vincent if (blocks & STMPE_BLOCK_TOUCHSCREEN) 51427e34995SRabin Vincent mask |= STMPE811_SYS_CTRL2_TSC_OFF; 51527e34995SRabin Vincent 5160f4be8cfSPatrice Chotard return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2], mask, 51727e34995SRabin Vincent enable ? 0 : mask); 51827e34995SRabin Vincent } 51927e34995SRabin Vincent 52027e34995SRabin Vincent static int stmpe811_get_altfunc(struct stmpe *stmpe, enum stmpe_block block) 52127e34995SRabin Vincent { 52227e34995SRabin Vincent /* 0 for touchscreen, 1 for GPIO */ 52327e34995SRabin Vincent return block != STMPE_BLOCK_TOUCHSCREEN; 52427e34995SRabin Vincent } 52527e34995SRabin Vincent 52627e34995SRabin Vincent static struct stmpe_variant_info stmpe811 = { 52727e34995SRabin Vincent .name = "stmpe811", 52827e34995SRabin Vincent .id_val = 0x0811, 52927e34995SRabin Vincent .id_mask = 0xffff, 53027e34995SRabin Vincent .num_gpios = 8, 53127e34995SRabin Vincent .af_bits = 1, 53227e34995SRabin Vincent .regs = stmpe811_regs, 53327e34995SRabin Vincent .blocks = stmpe811_blocks, 53427e34995SRabin Vincent .num_blocks = ARRAY_SIZE(stmpe811_blocks), 53527e34995SRabin Vincent .num_irqs = STMPE811_NR_INTERNAL_IRQS, 53627e34995SRabin Vincent .enable = stmpe811_enable, 53727e34995SRabin Vincent .get_altfunc = stmpe811_get_altfunc, 53827e34995SRabin Vincent }; 53927e34995SRabin Vincent 5401cda2394SViresh Kumar /* Similar to 811, except number of gpios */ 5411cda2394SViresh Kumar static struct stmpe_variant_info stmpe610 = { 5421cda2394SViresh Kumar .name = "stmpe610", 5431cda2394SViresh Kumar .id_val = 0x0811, 5441cda2394SViresh Kumar .id_mask = 0xffff, 5451cda2394SViresh Kumar .num_gpios = 6, 5461cda2394SViresh Kumar .af_bits = 1, 5471cda2394SViresh Kumar .regs = stmpe811_regs, 5481cda2394SViresh Kumar .blocks = stmpe811_blocks, 5491cda2394SViresh Kumar .num_blocks = ARRAY_SIZE(stmpe811_blocks), 5501cda2394SViresh Kumar .num_irqs = STMPE811_NR_INTERNAL_IRQS, 5511cda2394SViresh Kumar .enable = stmpe811_enable, 5521cda2394SViresh Kumar .get_altfunc = stmpe811_get_altfunc, 5531cda2394SViresh Kumar }; 5541cda2394SViresh Kumar 55527e34995SRabin Vincent /* 556*6bb9f0d9SPatrice Chotard * STMPE1600 557*6bb9f0d9SPatrice Chotard * Compared to all others STMPE variant, LSB and MSB regs are located in this 558*6bb9f0d9SPatrice Chotard * order : LSB addr 559*6bb9f0d9SPatrice Chotard * MSB addr + 1 560*6bb9f0d9SPatrice Chotard * As there is only 2 * 8bits registers for GPMR/GPSR/IEGPIOPR, CSB index is MSB registers 561*6bb9f0d9SPatrice Chotard */ 562*6bb9f0d9SPatrice Chotard 563*6bb9f0d9SPatrice Chotard static const u8 stmpe1600_regs[] = { 564*6bb9f0d9SPatrice Chotard [STMPE_IDX_CHIP_ID] = STMPE1600_REG_CHIP_ID, 565*6bb9f0d9SPatrice Chotard [STMPE_IDX_SYS_CTRL] = STMPE1600_REG_SYS_CTRL, 566*6bb9f0d9SPatrice Chotard [STMPE_IDX_ICR_LSB] = STMPE1600_REG_SYS_CTRL, 567*6bb9f0d9SPatrice Chotard [STMPE_IDX_GPMR_LSB] = STMPE1600_REG_GPMR_LSB, 568*6bb9f0d9SPatrice Chotard [STMPE_IDX_GPMR_CSB] = STMPE1600_REG_GPMR_MSB, 569*6bb9f0d9SPatrice Chotard [STMPE_IDX_GPSR_LSB] = STMPE1600_REG_GPSR_LSB, 570*6bb9f0d9SPatrice Chotard [STMPE_IDX_GPSR_CSB] = STMPE1600_REG_GPSR_MSB, 571*6bb9f0d9SPatrice Chotard [STMPE_IDX_GPDR_LSB] = STMPE1600_REG_GPDR_LSB, 572*6bb9f0d9SPatrice Chotard [STMPE_IDX_GPDR_CSB] = STMPE1600_REG_GPDR_MSB, 573*6bb9f0d9SPatrice Chotard [STMPE_IDX_IEGPIOR_LSB] = STMPE1600_REG_IEGPIOR_LSB, 574*6bb9f0d9SPatrice Chotard [STMPE_IDX_IEGPIOR_CSB] = STMPE1600_REG_IEGPIOR_MSB, 575*6bb9f0d9SPatrice Chotard [STMPE_IDX_ISGPIOR_LSB] = STMPE1600_REG_ISGPIOR_LSB, 576*6bb9f0d9SPatrice Chotard }; 577*6bb9f0d9SPatrice Chotard 578*6bb9f0d9SPatrice Chotard static struct stmpe_variant_block stmpe1600_blocks[] = { 579*6bb9f0d9SPatrice Chotard { 580*6bb9f0d9SPatrice Chotard .cell = &stmpe_gpio_cell, 581*6bb9f0d9SPatrice Chotard .irq = 0, 582*6bb9f0d9SPatrice Chotard .block = STMPE_BLOCK_GPIO, 583*6bb9f0d9SPatrice Chotard }, 584*6bb9f0d9SPatrice Chotard }; 585*6bb9f0d9SPatrice Chotard 586*6bb9f0d9SPatrice Chotard static int stmpe1600_enable(struct stmpe *stmpe, unsigned int blocks, 587*6bb9f0d9SPatrice Chotard bool enable) 588*6bb9f0d9SPatrice Chotard { 589*6bb9f0d9SPatrice Chotard if (blocks & STMPE_BLOCK_GPIO) 590*6bb9f0d9SPatrice Chotard return 0; 591*6bb9f0d9SPatrice Chotard else 592*6bb9f0d9SPatrice Chotard return -EINVAL; 593*6bb9f0d9SPatrice Chotard } 594*6bb9f0d9SPatrice Chotard 595*6bb9f0d9SPatrice Chotard static struct stmpe_variant_info stmpe1600 = { 596*6bb9f0d9SPatrice Chotard .name = "stmpe1600", 597*6bb9f0d9SPatrice Chotard .id_val = STMPE1600_ID, 598*6bb9f0d9SPatrice Chotard .id_mask = 0xffff, 599*6bb9f0d9SPatrice Chotard .num_gpios = 16, 600*6bb9f0d9SPatrice Chotard .af_bits = 0, 601*6bb9f0d9SPatrice Chotard .regs = stmpe1600_regs, 602*6bb9f0d9SPatrice Chotard .blocks = stmpe1600_blocks, 603*6bb9f0d9SPatrice Chotard .num_blocks = ARRAY_SIZE(stmpe1600_blocks), 604*6bb9f0d9SPatrice Chotard .num_irqs = STMPE1600_NR_INTERNAL_IRQS, 605*6bb9f0d9SPatrice Chotard .enable = stmpe1600_enable, 606*6bb9f0d9SPatrice Chotard }; 607*6bb9f0d9SPatrice Chotard 608*6bb9f0d9SPatrice Chotard /* 60927e34995SRabin Vincent * STMPE1601 61027e34995SRabin Vincent */ 61127e34995SRabin Vincent 61227e34995SRabin Vincent static const u8 stmpe1601_regs[] = { 61327e34995SRabin Vincent [STMPE_IDX_CHIP_ID] = STMPE1601_REG_CHIP_ID, 6140f4be8cfSPatrice Chotard [STMPE_IDX_SYS_CTRL] = STMPE1601_REG_SYS_CTRL, 6150f4be8cfSPatrice Chotard [STMPE_IDX_SYS_CTRL2] = STMPE1601_REG_SYS_CTRL2, 61627e34995SRabin Vincent [STMPE_IDX_ICR_LSB] = STMPE1601_REG_ICR_LSB, 617897ac667SPatrice Chotard [STMPE_IDX_IER_MSB] = STMPE1601_REG_IER_MSB, 61827e34995SRabin Vincent [STMPE_IDX_IER_LSB] = STMPE1601_REG_IER_LSB, 61927e34995SRabin Vincent [STMPE_IDX_ISR_MSB] = STMPE1601_REG_ISR_MSB, 62027e34995SRabin Vincent [STMPE_IDX_GPMR_LSB] = STMPE1601_REG_GPIO_MP_LSB, 621897ac667SPatrice Chotard [STMPE_IDX_GPMR_CSB] = STMPE1601_REG_GPIO_MP_MSB, 62227e34995SRabin Vincent [STMPE_IDX_GPSR_LSB] = STMPE1601_REG_GPIO_SET_LSB, 623897ac667SPatrice Chotard [STMPE_IDX_GPSR_CSB] = STMPE1601_REG_GPIO_SET_MSB, 62427e34995SRabin Vincent [STMPE_IDX_GPCR_LSB] = STMPE1601_REG_GPIO_CLR_LSB, 625897ac667SPatrice Chotard [STMPE_IDX_GPCR_CSB] = STMPE1601_REG_GPIO_CLR_MSB, 62627e34995SRabin Vincent [STMPE_IDX_GPDR_LSB] = STMPE1601_REG_GPIO_SET_DIR_LSB, 627897ac667SPatrice Chotard [STMPE_IDX_GPDR_CSB] = STMPE1601_REG_GPIO_SET_DIR_MSB, 628897ac667SPatrice Chotard [STMPE_IDX_GPEDR_LSB] = STMPE1601_REG_GPIO_ED_LSB, 629897ac667SPatrice Chotard [STMPE_IDX_GPEDR_CSB] = STMPE1601_REG_GPIO_ED_MSB, 63027e34995SRabin Vincent [STMPE_IDX_GPRER_LSB] = STMPE1601_REG_GPIO_RE_LSB, 631897ac667SPatrice Chotard [STMPE_IDX_GPRER_CSB] = STMPE1601_REG_GPIO_RE_MSB, 63227e34995SRabin Vincent [STMPE_IDX_GPFER_LSB] = STMPE1601_REG_GPIO_FE_LSB, 633897ac667SPatrice Chotard [STMPE_IDX_GPFER_CSB] = STMPE1601_REG_GPIO_FE_MSB, 63480e1dd82SLinus Walleij [STMPE_IDX_GPPUR_LSB] = STMPE1601_REG_GPIO_PU_LSB, 63527e34995SRabin Vincent [STMPE_IDX_GPAFR_U_MSB] = STMPE1601_REG_GPIO_AF_U_MSB, 63627e34995SRabin Vincent [STMPE_IDX_IEGPIOR_LSB] = STMPE1601_REG_INT_EN_GPIO_MASK_LSB, 637897ac667SPatrice Chotard [STMPE_IDX_IEGPIOR_CSB] = STMPE1601_REG_INT_EN_GPIO_MASK_MSB, 63827e34995SRabin Vincent [STMPE_IDX_ISGPIOR_MSB] = STMPE1601_REG_INT_STA_GPIO_MSB, 63927e34995SRabin Vincent }; 64027e34995SRabin Vincent 64127e34995SRabin Vincent static struct stmpe_variant_block stmpe1601_blocks[] = { 64227e34995SRabin Vincent { 64327e34995SRabin Vincent .cell = &stmpe_gpio_cell, 6445204e51dSLee Jones .irq = STMPE1601_IRQ_GPIOC, 64527e34995SRabin Vincent .block = STMPE_BLOCK_GPIO, 64627e34995SRabin Vincent }, 64727e34995SRabin Vincent { 64827e34995SRabin Vincent .cell = &stmpe_keypad_cell, 6495204e51dSLee Jones .irq = STMPE1601_IRQ_KEYPAD, 65027e34995SRabin Vincent .block = STMPE_BLOCK_KEYPAD, 65127e34995SRabin Vincent }, 652b273c5e0SLinus Walleij { 653b273c5e0SLinus Walleij .cell = &stmpe_pwm_cell, 654b273c5e0SLinus Walleij .irq = STMPE1601_IRQ_PWM0, 655b273c5e0SLinus Walleij .block = STMPE_BLOCK_PWM, 656b273c5e0SLinus Walleij }, 65727e34995SRabin Vincent }; 65827e34995SRabin Vincent 6595981f4e6SSundar R Iyer /* supported autosleep timeout delay (in msecs) */ 6605981f4e6SSundar R Iyer static const int stmpe_autosleep_delay[] = { 6615981f4e6SSundar R Iyer 4, 16, 32, 64, 128, 256, 512, 1024, 6625981f4e6SSundar R Iyer }; 6635981f4e6SSundar R Iyer 6645981f4e6SSundar R Iyer static int stmpe_round_timeout(int timeout) 6655981f4e6SSundar R Iyer { 6665981f4e6SSundar R Iyer int i; 6675981f4e6SSundar R Iyer 6685981f4e6SSundar R Iyer for (i = 0; i < ARRAY_SIZE(stmpe_autosleep_delay); i++) { 6695981f4e6SSundar R Iyer if (stmpe_autosleep_delay[i] >= timeout) 6705981f4e6SSundar R Iyer return i; 6715981f4e6SSundar R Iyer } 6725981f4e6SSundar R Iyer 6735981f4e6SSundar R Iyer /* 6745981f4e6SSundar R Iyer * requests for delays longer than supported should not return the 6755981f4e6SSundar R Iyer * longest supported delay 6765981f4e6SSundar R Iyer */ 6775981f4e6SSundar R Iyer return -EINVAL; 6785981f4e6SSundar R Iyer } 6795981f4e6SSundar R Iyer 6805981f4e6SSundar R Iyer static int stmpe_autosleep(struct stmpe *stmpe, int autosleep_timeout) 6815981f4e6SSundar R Iyer { 6825981f4e6SSundar R Iyer int ret; 6835981f4e6SSundar R Iyer 6845981f4e6SSundar R Iyer if (!stmpe->variant->enable_autosleep) 6855981f4e6SSundar R Iyer return -ENOSYS; 6865981f4e6SSundar R Iyer 6875981f4e6SSundar R Iyer mutex_lock(&stmpe->lock); 6885981f4e6SSundar R Iyer ret = stmpe->variant->enable_autosleep(stmpe, autosleep_timeout); 6895981f4e6SSundar R Iyer mutex_unlock(&stmpe->lock); 6905981f4e6SSundar R Iyer 6915981f4e6SSundar R Iyer return ret; 6925981f4e6SSundar R Iyer } 6935981f4e6SSundar R Iyer 6945981f4e6SSundar R Iyer /* 6955981f4e6SSundar R Iyer * Both stmpe 1601/2403 support same layout for autosleep 6965981f4e6SSundar R Iyer */ 6975981f4e6SSundar R Iyer static int stmpe1601_autosleep(struct stmpe *stmpe, 6985981f4e6SSundar R Iyer int autosleep_timeout) 6995981f4e6SSundar R Iyer { 7005981f4e6SSundar R Iyer int ret, timeout; 7015981f4e6SSundar R Iyer 7025981f4e6SSundar R Iyer /* choose the best available timeout */ 7035981f4e6SSundar R Iyer timeout = stmpe_round_timeout(autosleep_timeout); 7045981f4e6SSundar R Iyer if (timeout < 0) { 7055981f4e6SSundar R Iyer dev_err(stmpe->dev, "invalid timeout\n"); 7065981f4e6SSundar R Iyer return timeout; 7075981f4e6SSundar R Iyer } 7085981f4e6SSundar R Iyer 7090f4be8cfSPatrice Chotard ret = __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2], 7105981f4e6SSundar R Iyer STMPE1601_AUTOSLEEP_TIMEOUT_MASK, 7115981f4e6SSundar R Iyer timeout); 7125981f4e6SSundar R Iyer if (ret < 0) 7135981f4e6SSundar R Iyer return ret; 7145981f4e6SSundar R Iyer 7150f4be8cfSPatrice Chotard return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2], 7165981f4e6SSundar R Iyer STPME1601_AUTOSLEEP_ENABLE, 7175981f4e6SSundar R Iyer STPME1601_AUTOSLEEP_ENABLE); 7185981f4e6SSundar R Iyer } 7195981f4e6SSundar R Iyer 72027e34995SRabin Vincent static int stmpe1601_enable(struct stmpe *stmpe, unsigned int blocks, 72127e34995SRabin Vincent bool enable) 72227e34995SRabin Vincent { 72327e34995SRabin Vincent unsigned int mask = 0; 72427e34995SRabin Vincent 72527e34995SRabin Vincent if (blocks & STMPE_BLOCK_GPIO) 72627e34995SRabin Vincent mask |= STMPE1601_SYS_CTRL_ENABLE_GPIO; 727b69d2ad6SLinus Walleij else 728b69d2ad6SLinus Walleij mask &= ~STMPE1601_SYS_CTRL_ENABLE_GPIO; 72927e34995SRabin Vincent 73027e34995SRabin Vincent if (blocks & STMPE_BLOCK_KEYPAD) 73127e34995SRabin Vincent mask |= STMPE1601_SYS_CTRL_ENABLE_KPC; 732b69d2ad6SLinus Walleij else 733b69d2ad6SLinus Walleij mask &= ~STMPE1601_SYS_CTRL_ENABLE_KPC; 734b69d2ad6SLinus Walleij 735b69d2ad6SLinus Walleij if (blocks & STMPE_BLOCK_PWM) 736b69d2ad6SLinus Walleij mask |= STMPE1601_SYS_CTRL_ENABLE_SPWM; 737b69d2ad6SLinus Walleij else 738b69d2ad6SLinus Walleij mask &= ~STMPE1601_SYS_CTRL_ENABLE_SPWM; 73927e34995SRabin Vincent 7400f4be8cfSPatrice Chotard return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], mask, 74127e34995SRabin Vincent enable ? mask : 0); 74227e34995SRabin Vincent } 74327e34995SRabin Vincent 74427e34995SRabin Vincent static int stmpe1601_get_altfunc(struct stmpe *stmpe, enum stmpe_block block) 74527e34995SRabin Vincent { 74627e34995SRabin Vincent switch (block) { 74727e34995SRabin Vincent case STMPE_BLOCK_PWM: 74827e34995SRabin Vincent return 2; 74927e34995SRabin Vincent 75027e34995SRabin Vincent case STMPE_BLOCK_KEYPAD: 75127e34995SRabin Vincent return 1; 75227e34995SRabin Vincent 75327e34995SRabin Vincent case STMPE_BLOCK_GPIO: 75427e34995SRabin Vincent default: 75527e34995SRabin Vincent return 0; 75627e34995SRabin Vincent } 75727e34995SRabin Vincent } 75827e34995SRabin Vincent 75927e34995SRabin Vincent static struct stmpe_variant_info stmpe1601 = { 76027e34995SRabin Vincent .name = "stmpe1601", 76127e34995SRabin Vincent .id_val = 0x0210, 76227e34995SRabin Vincent .id_mask = 0xfff0, /* at least 0x0210 and 0x0212 */ 76327e34995SRabin Vincent .num_gpios = 16, 76427e34995SRabin Vincent .af_bits = 2, 76527e34995SRabin Vincent .regs = stmpe1601_regs, 76627e34995SRabin Vincent .blocks = stmpe1601_blocks, 76727e34995SRabin Vincent .num_blocks = ARRAY_SIZE(stmpe1601_blocks), 76827e34995SRabin Vincent .num_irqs = STMPE1601_NR_INTERNAL_IRQS, 76927e34995SRabin Vincent .enable = stmpe1601_enable, 77027e34995SRabin Vincent .get_altfunc = stmpe1601_get_altfunc, 7715981f4e6SSundar R Iyer .enable_autosleep = stmpe1601_autosleep, 77227e34995SRabin Vincent }; 77327e34995SRabin Vincent 77427e34995SRabin Vincent /* 775230f13a5SJean-Nicolas Graux * STMPE1801 776230f13a5SJean-Nicolas Graux */ 777230f13a5SJean-Nicolas Graux static const u8 stmpe1801_regs[] = { 778230f13a5SJean-Nicolas Graux [STMPE_IDX_CHIP_ID] = STMPE1801_REG_CHIP_ID, 7790f4be8cfSPatrice Chotard [STMPE_IDX_SYS_CTRL] = STMPE1801_REG_SYS_CTRL, 780230f13a5SJean-Nicolas Graux [STMPE_IDX_ICR_LSB] = STMPE1801_REG_INT_CTRL_LOW, 781230f13a5SJean-Nicolas Graux [STMPE_IDX_IER_LSB] = STMPE1801_REG_INT_EN_MASK_LOW, 782230f13a5SJean-Nicolas Graux [STMPE_IDX_ISR_LSB] = STMPE1801_REG_INT_STA_LOW, 783230f13a5SJean-Nicolas Graux [STMPE_IDX_GPMR_LSB] = STMPE1801_REG_GPIO_MP_LOW, 784897ac667SPatrice Chotard [STMPE_IDX_GPMR_CSB] = STMPE1801_REG_GPIO_MP_MID, 785897ac667SPatrice Chotard [STMPE_IDX_GPMR_MSB] = STMPE1801_REG_GPIO_MP_HIGH, 786230f13a5SJean-Nicolas Graux [STMPE_IDX_GPSR_LSB] = STMPE1801_REG_GPIO_SET_LOW, 787897ac667SPatrice Chotard [STMPE_IDX_GPSR_CSB] = STMPE1801_REG_GPIO_SET_MID, 788897ac667SPatrice Chotard [STMPE_IDX_GPSR_MSB] = STMPE1801_REG_GPIO_SET_HIGH, 789230f13a5SJean-Nicolas Graux [STMPE_IDX_GPCR_LSB] = STMPE1801_REG_GPIO_CLR_LOW, 790897ac667SPatrice Chotard [STMPE_IDX_GPCR_CSB] = STMPE1801_REG_GPIO_CLR_MID, 791897ac667SPatrice Chotard [STMPE_IDX_GPCR_MSB] = STMPE1801_REG_GPIO_CLR_HIGH, 792230f13a5SJean-Nicolas Graux [STMPE_IDX_GPDR_LSB] = STMPE1801_REG_GPIO_SET_DIR_LOW, 793897ac667SPatrice Chotard [STMPE_IDX_GPDR_CSB] = STMPE1801_REG_GPIO_SET_DIR_MID, 794897ac667SPatrice Chotard [STMPE_IDX_GPDR_MSB] = STMPE1801_REG_GPIO_SET_DIR_HIGH, 795230f13a5SJean-Nicolas Graux [STMPE_IDX_GPRER_LSB] = STMPE1801_REG_GPIO_RE_LOW, 796897ac667SPatrice Chotard [STMPE_IDX_GPRER_CSB] = STMPE1801_REG_GPIO_RE_MID, 797897ac667SPatrice Chotard [STMPE_IDX_GPRER_MSB] = STMPE1801_REG_GPIO_RE_HIGH, 798230f13a5SJean-Nicolas Graux [STMPE_IDX_GPFER_LSB] = STMPE1801_REG_GPIO_FE_LOW, 799897ac667SPatrice Chotard [STMPE_IDX_GPFER_CSB] = STMPE1801_REG_GPIO_FE_MID, 800897ac667SPatrice Chotard [STMPE_IDX_GPFER_MSB] = STMPE1801_REG_GPIO_FE_HIGH, 80180e1dd82SLinus Walleij [STMPE_IDX_GPPUR_LSB] = STMPE1801_REG_GPIO_PULL_UP_LOW, 802230f13a5SJean-Nicolas Graux [STMPE_IDX_IEGPIOR_LSB] = STMPE1801_REG_INT_EN_GPIO_MASK_LOW, 803897ac667SPatrice Chotard [STMPE_IDX_IEGPIOR_CSB] = STMPE1801_REG_INT_EN_GPIO_MASK_MID, 804897ac667SPatrice Chotard [STMPE_IDX_IEGPIOR_MSB] = STMPE1801_REG_INT_EN_GPIO_MASK_HIGH, 805897ac667SPatrice Chotard [STMPE_IDX_ISGPIOR_MSB] = STMPE1801_REG_INT_STA_GPIO_HIGH, 806230f13a5SJean-Nicolas Graux }; 807230f13a5SJean-Nicolas Graux 808230f13a5SJean-Nicolas Graux static struct stmpe_variant_block stmpe1801_blocks[] = { 809230f13a5SJean-Nicolas Graux { 810230f13a5SJean-Nicolas Graux .cell = &stmpe_gpio_cell, 811230f13a5SJean-Nicolas Graux .irq = STMPE1801_IRQ_GPIOC, 812230f13a5SJean-Nicolas Graux .block = STMPE_BLOCK_GPIO, 813230f13a5SJean-Nicolas Graux }, 814230f13a5SJean-Nicolas Graux { 815230f13a5SJean-Nicolas Graux .cell = &stmpe_keypad_cell, 816230f13a5SJean-Nicolas Graux .irq = STMPE1801_IRQ_KEYPAD, 817230f13a5SJean-Nicolas Graux .block = STMPE_BLOCK_KEYPAD, 818230f13a5SJean-Nicolas Graux }, 819230f13a5SJean-Nicolas Graux }; 820230f13a5SJean-Nicolas Graux 821230f13a5SJean-Nicolas Graux static int stmpe1801_enable(struct stmpe *stmpe, unsigned int blocks, 822230f13a5SJean-Nicolas Graux bool enable) 823230f13a5SJean-Nicolas Graux { 824230f13a5SJean-Nicolas Graux unsigned int mask = 0; 825230f13a5SJean-Nicolas Graux if (blocks & STMPE_BLOCK_GPIO) 826230f13a5SJean-Nicolas Graux mask |= STMPE1801_MSK_INT_EN_GPIO; 827230f13a5SJean-Nicolas Graux 828230f13a5SJean-Nicolas Graux if (blocks & STMPE_BLOCK_KEYPAD) 829230f13a5SJean-Nicolas Graux mask |= STMPE1801_MSK_INT_EN_KPC; 830230f13a5SJean-Nicolas Graux 831230f13a5SJean-Nicolas Graux return __stmpe_set_bits(stmpe, STMPE1801_REG_INT_EN_MASK_LOW, mask, 832230f13a5SJean-Nicolas Graux enable ? mask : 0); 833230f13a5SJean-Nicolas Graux } 834230f13a5SJean-Nicolas Graux 835c4dd1ba3SPatrice Chotard static int stmpe_reset(struct stmpe *stmpe) 836230f13a5SJean-Nicolas Graux { 837c4dd1ba3SPatrice Chotard u16 id_val = stmpe->variant->id_val; 838230f13a5SJean-Nicolas Graux unsigned long timeout; 839230f13a5SJean-Nicolas Graux int ret = 0; 840c4dd1ba3SPatrice Chotard u8 reset_bit; 841c4dd1ba3SPatrice Chotard 842c4dd1ba3SPatrice Chotard if (id_val == STMPE811_ID) 843c4dd1ba3SPatrice Chotard /* STMPE801 and STMPE610 use bit 1 of SYS_CTRL register */ 844c4dd1ba3SPatrice Chotard reset_bit = STMPE811_SYS_CTRL_RESET; 845c4dd1ba3SPatrice Chotard else 846c4dd1ba3SPatrice Chotard /* all other STMPE variant use bit 7 of SYS_CTRL register */ 847c4dd1ba3SPatrice Chotard reset_bit = STMPE_SYS_CTRL_RESET; 848230f13a5SJean-Nicolas Graux 8490f4be8cfSPatrice Chotard ret = __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], 850c4dd1ba3SPatrice Chotard reset_bit, reset_bit); 851230f13a5SJean-Nicolas Graux if (ret < 0) 852230f13a5SJean-Nicolas Graux return ret; 853230f13a5SJean-Nicolas Graux 854230f13a5SJean-Nicolas Graux timeout = jiffies + msecs_to_jiffies(100); 855230f13a5SJean-Nicolas Graux while (time_before(jiffies, timeout)) { 8560f4be8cfSPatrice Chotard ret = __stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL]); 857230f13a5SJean-Nicolas Graux if (ret < 0) 858230f13a5SJean-Nicolas Graux return ret; 859c4dd1ba3SPatrice Chotard if (!(ret & reset_bit)) 860230f13a5SJean-Nicolas Graux return 0; 861230f13a5SJean-Nicolas Graux usleep_range(100, 200); 86252397fe1SSachin Kamat } 863230f13a5SJean-Nicolas Graux return -EIO; 864230f13a5SJean-Nicolas Graux } 865230f13a5SJean-Nicolas Graux 866230f13a5SJean-Nicolas Graux static struct stmpe_variant_info stmpe1801 = { 867230f13a5SJean-Nicolas Graux .name = "stmpe1801", 868230f13a5SJean-Nicolas Graux .id_val = STMPE1801_ID, 869230f13a5SJean-Nicolas Graux .id_mask = 0xfff0, 870230f13a5SJean-Nicolas Graux .num_gpios = 18, 871230f13a5SJean-Nicolas Graux .af_bits = 0, 872230f13a5SJean-Nicolas Graux .regs = stmpe1801_regs, 873230f13a5SJean-Nicolas Graux .blocks = stmpe1801_blocks, 874230f13a5SJean-Nicolas Graux .num_blocks = ARRAY_SIZE(stmpe1801_blocks), 875230f13a5SJean-Nicolas Graux .num_irqs = STMPE1801_NR_INTERNAL_IRQS, 876230f13a5SJean-Nicolas Graux .enable = stmpe1801_enable, 877230f13a5SJean-Nicolas Graux /* stmpe1801 do not have any gpio alternate function */ 878230f13a5SJean-Nicolas Graux .get_altfunc = NULL, 879230f13a5SJean-Nicolas Graux }; 880230f13a5SJean-Nicolas Graux 881230f13a5SJean-Nicolas Graux /* 88227e34995SRabin Vincent * STMPE24XX 88327e34995SRabin Vincent */ 88427e34995SRabin Vincent 88527e34995SRabin Vincent static const u8 stmpe24xx_regs[] = { 88627e34995SRabin Vincent [STMPE_IDX_CHIP_ID] = STMPE24XX_REG_CHIP_ID, 8870f4be8cfSPatrice Chotard [STMPE_IDX_SYS_CTRL] = STMPE24XX_REG_SYS_CTRL, 8880f4be8cfSPatrice Chotard [STMPE_IDX_SYS_CTRL2] = STMPE24XX_REG_SYS_CTRL2, 88927e34995SRabin Vincent [STMPE_IDX_ICR_LSB] = STMPE24XX_REG_ICR_LSB, 890897ac667SPatrice Chotard [STMPE_IDX_IER_MSB] = STMPE24XX_REG_IER_MSB, 89127e34995SRabin Vincent [STMPE_IDX_IER_LSB] = STMPE24XX_REG_IER_LSB, 89227e34995SRabin Vincent [STMPE_IDX_ISR_MSB] = STMPE24XX_REG_ISR_MSB, 89327e34995SRabin Vincent [STMPE_IDX_GPMR_LSB] = STMPE24XX_REG_GPMR_LSB, 894897ac667SPatrice Chotard [STMPE_IDX_GPMR_CSB] = STMPE24XX_REG_GPMR_CSB, 895897ac667SPatrice Chotard [STMPE_IDX_GPMR_MSB] = STMPE24XX_REG_GPMR_MSB, 89627e34995SRabin Vincent [STMPE_IDX_GPSR_LSB] = STMPE24XX_REG_GPSR_LSB, 897897ac667SPatrice Chotard [STMPE_IDX_GPSR_CSB] = STMPE24XX_REG_GPSR_CSB, 898897ac667SPatrice Chotard [STMPE_IDX_GPSR_MSB] = STMPE24XX_REG_GPSR_MSB, 89927e34995SRabin Vincent [STMPE_IDX_GPCR_LSB] = STMPE24XX_REG_GPCR_LSB, 900897ac667SPatrice Chotard [STMPE_IDX_GPCR_CSB] = STMPE24XX_REG_GPCR_CSB, 901897ac667SPatrice Chotard [STMPE_IDX_GPCR_MSB] = STMPE24XX_REG_GPCR_MSB, 90227e34995SRabin Vincent [STMPE_IDX_GPDR_LSB] = STMPE24XX_REG_GPDR_LSB, 903897ac667SPatrice Chotard [STMPE_IDX_GPDR_CSB] = STMPE24XX_REG_GPDR_CSB, 904897ac667SPatrice Chotard [STMPE_IDX_GPDR_MSB] = STMPE24XX_REG_GPDR_MSB, 90527e34995SRabin Vincent [STMPE_IDX_GPRER_LSB] = STMPE24XX_REG_GPRER_LSB, 906897ac667SPatrice Chotard [STMPE_IDX_GPRER_CSB] = STMPE24XX_REG_GPRER_CSB, 907897ac667SPatrice Chotard [STMPE_IDX_GPRER_MSB] = STMPE24XX_REG_GPRER_MSB, 90827e34995SRabin Vincent [STMPE_IDX_GPFER_LSB] = STMPE24XX_REG_GPFER_LSB, 909897ac667SPatrice Chotard [STMPE_IDX_GPFER_CSB] = STMPE24XX_REG_GPFER_CSB, 910897ac667SPatrice Chotard [STMPE_IDX_GPFER_MSB] = STMPE24XX_REG_GPFER_MSB, 91180e1dd82SLinus Walleij [STMPE_IDX_GPPUR_LSB] = STMPE24XX_REG_GPPUR_LSB, 91280e1dd82SLinus Walleij [STMPE_IDX_GPPDR_LSB] = STMPE24XX_REG_GPPDR_LSB, 91327e34995SRabin Vincent [STMPE_IDX_GPAFR_U_MSB] = STMPE24XX_REG_GPAFR_U_MSB, 91427e34995SRabin Vincent [STMPE_IDX_IEGPIOR_LSB] = STMPE24XX_REG_IEGPIOR_LSB, 915897ac667SPatrice Chotard [STMPE_IDX_IEGPIOR_CSB] = STMPE24XX_REG_IEGPIOR_CSB, 916897ac667SPatrice Chotard [STMPE_IDX_IEGPIOR_MSB] = STMPE24XX_REG_IEGPIOR_MSB, 91727e34995SRabin Vincent [STMPE_IDX_ISGPIOR_MSB] = STMPE24XX_REG_ISGPIOR_MSB, 918897ac667SPatrice Chotard [STMPE_IDX_GPEDR_LSB] = STMPE24XX_REG_GPEDR_LSB, 919897ac667SPatrice Chotard [STMPE_IDX_GPEDR_CSB] = STMPE24XX_REG_GPEDR_CSB, 92027e34995SRabin Vincent [STMPE_IDX_GPEDR_MSB] = STMPE24XX_REG_GPEDR_MSB, 92127e34995SRabin Vincent }; 92227e34995SRabin Vincent 92327e34995SRabin Vincent static struct stmpe_variant_block stmpe24xx_blocks[] = { 92427e34995SRabin Vincent { 92527e34995SRabin Vincent .cell = &stmpe_gpio_cell, 92627e34995SRabin Vincent .irq = STMPE24XX_IRQ_GPIOC, 92727e34995SRabin Vincent .block = STMPE_BLOCK_GPIO, 92827e34995SRabin Vincent }, 92927e34995SRabin Vincent { 93027e34995SRabin Vincent .cell = &stmpe_keypad_cell, 93127e34995SRabin Vincent .irq = STMPE24XX_IRQ_KEYPAD, 93227e34995SRabin Vincent .block = STMPE_BLOCK_KEYPAD, 93327e34995SRabin Vincent }, 934b273c5e0SLinus Walleij { 935b273c5e0SLinus Walleij .cell = &stmpe_pwm_cell, 936b273c5e0SLinus Walleij .irq = STMPE24XX_IRQ_PWM0, 937b273c5e0SLinus Walleij .block = STMPE_BLOCK_PWM, 938b273c5e0SLinus Walleij }, 93927e34995SRabin Vincent }; 94027e34995SRabin Vincent 94127e34995SRabin Vincent static int stmpe24xx_enable(struct stmpe *stmpe, unsigned int blocks, 94227e34995SRabin Vincent bool enable) 94327e34995SRabin Vincent { 94427e34995SRabin Vincent unsigned int mask = 0; 94527e34995SRabin Vincent 94627e34995SRabin Vincent if (blocks & STMPE_BLOCK_GPIO) 94727e34995SRabin Vincent mask |= STMPE24XX_SYS_CTRL_ENABLE_GPIO; 94827e34995SRabin Vincent 94927e34995SRabin Vincent if (blocks & STMPE_BLOCK_KEYPAD) 95027e34995SRabin Vincent mask |= STMPE24XX_SYS_CTRL_ENABLE_KPC; 95127e34995SRabin Vincent 9520f4be8cfSPatrice Chotard return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], mask, 95327e34995SRabin Vincent enable ? mask : 0); 95427e34995SRabin Vincent } 95527e34995SRabin Vincent 95627e34995SRabin Vincent static int stmpe24xx_get_altfunc(struct stmpe *stmpe, enum stmpe_block block) 95727e34995SRabin Vincent { 95827e34995SRabin Vincent switch (block) { 95927e34995SRabin Vincent case STMPE_BLOCK_ROTATOR: 96027e34995SRabin Vincent return 2; 96127e34995SRabin Vincent 96227e34995SRabin Vincent case STMPE_BLOCK_KEYPAD: 963f6d10341SLinus Walleij case STMPE_BLOCK_PWM: 96427e34995SRabin Vincent return 1; 96527e34995SRabin Vincent 96627e34995SRabin Vincent case STMPE_BLOCK_GPIO: 96727e34995SRabin Vincent default: 96827e34995SRabin Vincent return 0; 96927e34995SRabin Vincent } 97027e34995SRabin Vincent } 97127e34995SRabin Vincent 97227e34995SRabin Vincent static struct stmpe_variant_info stmpe2401 = { 97327e34995SRabin Vincent .name = "stmpe2401", 97427e34995SRabin Vincent .id_val = 0x0101, 97527e34995SRabin Vincent .id_mask = 0xffff, 97627e34995SRabin Vincent .num_gpios = 24, 97727e34995SRabin Vincent .af_bits = 2, 97827e34995SRabin Vincent .regs = stmpe24xx_regs, 97927e34995SRabin Vincent .blocks = stmpe24xx_blocks, 98027e34995SRabin Vincent .num_blocks = ARRAY_SIZE(stmpe24xx_blocks), 98127e34995SRabin Vincent .num_irqs = STMPE24XX_NR_INTERNAL_IRQS, 98227e34995SRabin Vincent .enable = stmpe24xx_enable, 98327e34995SRabin Vincent .get_altfunc = stmpe24xx_get_altfunc, 98427e34995SRabin Vincent }; 98527e34995SRabin Vincent 98627e34995SRabin Vincent static struct stmpe_variant_info stmpe2403 = { 98727e34995SRabin Vincent .name = "stmpe2403", 98827e34995SRabin Vincent .id_val = 0x0120, 98927e34995SRabin Vincent .id_mask = 0xffff, 99027e34995SRabin Vincent .num_gpios = 24, 99127e34995SRabin Vincent .af_bits = 2, 99227e34995SRabin Vincent .regs = stmpe24xx_regs, 99327e34995SRabin Vincent .blocks = stmpe24xx_blocks, 99427e34995SRabin Vincent .num_blocks = ARRAY_SIZE(stmpe24xx_blocks), 99527e34995SRabin Vincent .num_irqs = STMPE24XX_NR_INTERNAL_IRQS, 99627e34995SRabin Vincent .enable = stmpe24xx_enable, 99727e34995SRabin Vincent .get_altfunc = stmpe24xx_get_altfunc, 9985981f4e6SSundar R Iyer .enable_autosleep = stmpe1601_autosleep, /* same as stmpe1601 */ 99927e34995SRabin Vincent }; 100027e34995SRabin Vincent 1001e31f9b82SChris Blair static struct stmpe_variant_info *stmpe_variant_info[STMPE_NBR_PARTS] = { 10021cda2394SViresh Kumar [STMPE610] = &stmpe610, 10037f7f4ea1SViresh Kumar [STMPE801] = &stmpe801, 100427e34995SRabin Vincent [STMPE811] = &stmpe811, 1005*6bb9f0d9SPatrice Chotard [STMPE1600] = &stmpe1600, 100627e34995SRabin Vincent [STMPE1601] = &stmpe1601, 1007230f13a5SJean-Nicolas Graux [STMPE1801] = &stmpe1801, 100827e34995SRabin Vincent [STMPE2401] = &stmpe2401, 100927e34995SRabin Vincent [STMPE2403] = &stmpe2403, 101027e34995SRabin Vincent }; 101127e34995SRabin Vincent 1012e31f9b82SChris Blair /* 1013e31f9b82SChris Blair * These devices can be connected in a 'no-irq' configuration - the irq pin 1014e31f9b82SChris Blair * is not used and the device cannot interrupt the CPU. Here we only list 1015e31f9b82SChris Blair * devices which support this configuration - the driver will fail probing 1016e31f9b82SChris Blair * for any devices not listed here which are configured in this way. 1017e31f9b82SChris Blair */ 1018e31f9b82SChris Blair static struct stmpe_variant_info *stmpe_noirq_variant_info[STMPE_NBR_PARTS] = { 1019e31f9b82SChris Blair [STMPE801] = &stmpe801_noirq, 1020e31f9b82SChris Blair }; 1021e31f9b82SChris Blair 102227e34995SRabin Vincent static irqreturn_t stmpe_irq(int irq, void *data) 102327e34995SRabin Vincent { 102427e34995SRabin Vincent struct stmpe *stmpe = data; 102527e34995SRabin Vincent struct stmpe_variant_info *variant = stmpe->variant; 102627e34995SRabin Vincent int num = DIV_ROUND_UP(variant->num_irqs, 8); 1027230f13a5SJean-Nicolas Graux u8 israddr; 10287929fa77SLee Jones u8 isr[3]; 102927e34995SRabin Vincent int ret; 103027e34995SRabin Vincent int i; 103127e34995SRabin Vincent 1032*6bb9f0d9SPatrice Chotard if (variant->id_val == STMPE801_ID || 1033*6bb9f0d9SPatrice Chotard variant->id_val == STMPE1600_ID) { 103476f93992SLee Jones int base = irq_create_mapping(stmpe->domain, 0); 103576f93992SLee Jones 103676f93992SLee Jones handle_nested_irq(base); 10377f7f4ea1SViresh Kumar return IRQ_HANDLED; 10387f7f4ea1SViresh Kumar } 10397f7f4ea1SViresh Kumar 1040230f13a5SJean-Nicolas Graux if (variant->id_val == STMPE1801_ID) 1041230f13a5SJean-Nicolas Graux israddr = stmpe->regs[STMPE_IDX_ISR_LSB]; 1042230f13a5SJean-Nicolas Graux else 1043230f13a5SJean-Nicolas Graux israddr = stmpe->regs[STMPE_IDX_ISR_MSB]; 1044230f13a5SJean-Nicolas Graux 104527e34995SRabin Vincent ret = stmpe_block_read(stmpe, israddr, num, isr); 104627e34995SRabin Vincent if (ret < 0) 104727e34995SRabin Vincent return IRQ_NONE; 104827e34995SRabin Vincent 104927e34995SRabin Vincent for (i = 0; i < num; i++) { 105027e34995SRabin Vincent int bank = num - i - 1; 105127e34995SRabin Vincent u8 status = isr[i]; 105227e34995SRabin Vincent u8 clear; 105327e34995SRabin Vincent 105427e34995SRabin Vincent status &= stmpe->ier[bank]; 105527e34995SRabin Vincent if (!status) 105627e34995SRabin Vincent continue; 105727e34995SRabin Vincent 105827e34995SRabin Vincent clear = status; 105927e34995SRabin Vincent while (status) { 106027e34995SRabin Vincent int bit = __ffs(status); 106127e34995SRabin Vincent int line = bank * 8 + bit; 106276f93992SLee Jones int nestedirq = irq_create_mapping(stmpe->domain, line); 106327e34995SRabin Vincent 106476f93992SLee Jones handle_nested_irq(nestedirq); 106527e34995SRabin Vincent status &= ~(1 << bit); 106627e34995SRabin Vincent } 106727e34995SRabin Vincent 106827e34995SRabin Vincent stmpe_reg_write(stmpe, israddr + i, clear); 106927e34995SRabin Vincent } 107027e34995SRabin Vincent 107127e34995SRabin Vincent return IRQ_HANDLED; 107227e34995SRabin Vincent } 107327e34995SRabin Vincent 107443b8c084SMark Brown static void stmpe_irq_lock(struct irq_data *data) 107527e34995SRabin Vincent { 107643b8c084SMark Brown struct stmpe *stmpe = irq_data_get_irq_chip_data(data); 107727e34995SRabin Vincent 107827e34995SRabin Vincent mutex_lock(&stmpe->irq_lock); 107927e34995SRabin Vincent } 108027e34995SRabin Vincent 108143b8c084SMark Brown static void stmpe_irq_sync_unlock(struct irq_data *data) 108227e34995SRabin Vincent { 108343b8c084SMark Brown struct stmpe *stmpe = irq_data_get_irq_chip_data(data); 108427e34995SRabin Vincent struct stmpe_variant_info *variant = stmpe->variant; 108527e34995SRabin Vincent int num = DIV_ROUND_UP(variant->num_irqs, 8); 108627e34995SRabin Vincent int i; 108727e34995SRabin Vincent 108827e34995SRabin Vincent for (i = 0; i < num; i++) { 108927e34995SRabin Vincent u8 new = stmpe->ier[i]; 109027e34995SRabin Vincent u8 old = stmpe->oldier[i]; 109127e34995SRabin Vincent 109227e34995SRabin Vincent if (new == old) 109327e34995SRabin Vincent continue; 109427e34995SRabin Vincent 109527e34995SRabin Vincent stmpe->oldier[i] = new; 1096897ac667SPatrice Chotard stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_IER_LSB + i], new); 109727e34995SRabin Vincent } 109827e34995SRabin Vincent 109927e34995SRabin Vincent mutex_unlock(&stmpe->irq_lock); 110027e34995SRabin Vincent } 110127e34995SRabin Vincent 110243b8c084SMark Brown static void stmpe_irq_mask(struct irq_data *data) 110327e34995SRabin Vincent { 110443b8c084SMark Brown struct stmpe *stmpe = irq_data_get_irq_chip_data(data); 110576f93992SLee Jones int offset = data->hwirq; 110627e34995SRabin Vincent int regoffset = offset / 8; 110727e34995SRabin Vincent int mask = 1 << (offset % 8); 110827e34995SRabin Vincent 110927e34995SRabin Vincent stmpe->ier[regoffset] &= ~mask; 111027e34995SRabin Vincent } 111127e34995SRabin Vincent 111243b8c084SMark Brown static void stmpe_irq_unmask(struct irq_data *data) 111327e34995SRabin Vincent { 111443b8c084SMark Brown struct stmpe *stmpe = irq_data_get_irq_chip_data(data); 111576f93992SLee Jones int offset = data->hwirq; 111627e34995SRabin Vincent int regoffset = offset / 8; 111727e34995SRabin Vincent int mask = 1 << (offset % 8); 111827e34995SRabin Vincent 111927e34995SRabin Vincent stmpe->ier[regoffset] |= mask; 112027e34995SRabin Vincent } 112127e34995SRabin Vincent 112227e34995SRabin Vincent static struct irq_chip stmpe_irq_chip = { 112327e34995SRabin Vincent .name = "stmpe", 112443b8c084SMark Brown .irq_bus_lock = stmpe_irq_lock, 112543b8c084SMark Brown .irq_bus_sync_unlock = stmpe_irq_sync_unlock, 112643b8c084SMark Brown .irq_mask = stmpe_irq_mask, 112743b8c084SMark Brown .irq_unmask = stmpe_irq_unmask, 112827e34995SRabin Vincent }; 112927e34995SRabin Vincent 113076f93992SLee Jones static int stmpe_irq_map(struct irq_domain *d, unsigned int virq, 113176f93992SLee Jones irq_hw_number_t hwirq) 113227e34995SRabin Vincent { 113376f93992SLee Jones struct stmpe *stmpe = d->host_data; 11347f7f4ea1SViresh Kumar struct irq_chip *chip = NULL; 113527e34995SRabin Vincent 11367f7f4ea1SViresh Kumar if (stmpe->variant->id_val != STMPE801_ID) 11377f7f4ea1SViresh Kumar chip = &stmpe_irq_chip; 11387f7f4ea1SViresh Kumar 113976f93992SLee Jones irq_set_chip_data(virq, stmpe); 114076f93992SLee Jones irq_set_chip_and_handler(virq, chip, handle_edge_irq); 114176f93992SLee Jones irq_set_nested_thread(virq, 1); 114276f93992SLee Jones irq_set_noprobe(virq); 114327e34995SRabin Vincent 114427e34995SRabin Vincent return 0; 114527e34995SRabin Vincent } 114627e34995SRabin Vincent 114776f93992SLee Jones static void stmpe_irq_unmap(struct irq_domain *d, unsigned int virq) 114827e34995SRabin Vincent { 114976f93992SLee Jones irq_set_chip_and_handler(virq, NULL, NULL); 115076f93992SLee Jones irq_set_chip_data(virq, NULL); 115127e34995SRabin Vincent } 115276f93992SLee Jones 11537ce7b26fSKrzysztof Kozlowski static const struct irq_domain_ops stmpe_irq_ops = { 115476f93992SLee Jones .map = stmpe_irq_map, 115576f93992SLee Jones .unmap = stmpe_irq_unmap, 115676f93992SLee Jones .xlate = irq_domain_xlate_twocell, 115776f93992SLee Jones }; 115876f93992SLee Jones 1159612b95cdSGreg Kroah-Hartman static int stmpe_irq_init(struct stmpe *stmpe, struct device_node *np) 116076f93992SLee Jones { 1161b20a4371SLee Jones int base = 0; 116276f93992SLee Jones int num_irqs = stmpe->variant->num_irqs; 116376f93992SLee Jones 1164b20a4371SLee Jones stmpe->domain = irq_domain_add_simple(np, num_irqs, base, 1165b20a4371SLee Jones &stmpe_irq_ops, stmpe); 116676f93992SLee Jones if (!stmpe->domain) { 116776f93992SLee Jones dev_err(stmpe->dev, "Failed to create irqdomain\n"); 116876f93992SLee Jones return -ENOSYS; 116976f93992SLee Jones } 117076f93992SLee Jones 117176f93992SLee Jones return 0; 117227e34995SRabin Vincent } 117327e34995SRabin Vincent 1174612b95cdSGreg Kroah-Hartman static int stmpe_chip_init(struct stmpe *stmpe) 117527e34995SRabin Vincent { 117627e34995SRabin Vincent unsigned int irq_trigger = stmpe->pdata->irq_trigger; 11775981f4e6SSundar R Iyer int autosleep_timeout = stmpe->pdata->autosleep_timeout; 117827e34995SRabin Vincent struct stmpe_variant_info *variant = stmpe->variant; 1179e31f9b82SChris Blair u8 icr = 0; 118027e34995SRabin Vincent unsigned int id; 118127e34995SRabin Vincent u8 data[2]; 118227e34995SRabin Vincent int ret; 118327e34995SRabin Vincent 118427e34995SRabin Vincent ret = stmpe_block_read(stmpe, stmpe->regs[STMPE_IDX_CHIP_ID], 118527e34995SRabin Vincent ARRAY_SIZE(data), data); 118627e34995SRabin Vincent if (ret < 0) 118727e34995SRabin Vincent return ret; 118827e34995SRabin Vincent 118927e34995SRabin Vincent id = (data[0] << 8) | data[1]; 119027e34995SRabin Vincent if ((id & variant->id_mask) != variant->id_val) { 119127e34995SRabin Vincent dev_err(stmpe->dev, "unknown chip id: %#x\n", id); 119227e34995SRabin Vincent return -EINVAL; 119327e34995SRabin Vincent } 119427e34995SRabin Vincent 119527e34995SRabin Vincent dev_info(stmpe->dev, "%s detected, chip id: %#x\n", variant->name, id); 119627e34995SRabin Vincent 119727e34995SRabin Vincent /* Disable all modules -- subdrivers should enable what they need. */ 119827e34995SRabin Vincent ret = stmpe_disable(stmpe, ~0); 119927e34995SRabin Vincent if (ret) 120027e34995SRabin Vincent return ret; 120127e34995SRabin Vincent 1202c4dd1ba3SPatrice Chotard ret = stmpe_reset(stmpe); 1203230f13a5SJean-Nicolas Graux if (ret < 0) 1204230f13a5SJean-Nicolas Graux return ret; 1205230f13a5SJean-Nicolas Graux 1206e31f9b82SChris Blair if (stmpe->irq >= 0) { 1207*6bb9f0d9SPatrice Chotard if (id == STMPE801_ID || id == STMPE1600_ID) 1208c16bee78SPatrice Chotard icr = STMPE_SYS_CTRL_INT_EN; 12097f7f4ea1SViresh Kumar else 12107f7f4ea1SViresh Kumar icr = STMPE_ICR_LSB_GIM; 12117f7f4ea1SViresh Kumar 1212*6bb9f0d9SPatrice Chotard /* STMPE801 and STMPE1600 don't support Edge interrupts */ 1213*6bb9f0d9SPatrice Chotard if (id != STMPE801_ID && id != STMPE1600_ID) { 121427e34995SRabin Vincent if (irq_trigger == IRQF_TRIGGER_FALLING || 121527e34995SRabin Vincent irq_trigger == IRQF_TRIGGER_RISING) 121627e34995SRabin Vincent icr |= STMPE_ICR_LSB_EDGE; 12177f7f4ea1SViresh Kumar } 121827e34995SRabin Vincent 121927e34995SRabin Vincent if (irq_trigger == IRQF_TRIGGER_RISING || 12207f7f4ea1SViresh Kumar irq_trigger == IRQF_TRIGGER_HIGH) { 1221*6bb9f0d9SPatrice Chotard if (id == STMPE801_ID || id == STMPE1600_ID) 1222c16bee78SPatrice Chotard icr |= STMPE_SYS_CTRL_INT_HI; 12237f7f4ea1SViresh Kumar else 122427e34995SRabin Vincent icr |= STMPE_ICR_LSB_HIGH; 12257f7f4ea1SViresh Kumar } 1226e31f9b82SChris Blair } 122727e34995SRabin Vincent 12285981f4e6SSundar R Iyer if (stmpe->pdata->autosleep) { 12295981f4e6SSundar R Iyer ret = stmpe_autosleep(stmpe, autosleep_timeout); 12305981f4e6SSundar R Iyer if (ret) 12315981f4e6SSundar R Iyer return ret; 12325981f4e6SSundar R Iyer } 12335981f4e6SSundar R Iyer 123427e34995SRabin Vincent return stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_ICR_LSB], icr); 123527e34995SRabin Vincent } 123627e34995SRabin Vincent 12376bbb3c4cSGeert Uytterhoeven static int stmpe_add_device(struct stmpe *stmpe, const struct mfd_cell *cell) 123827e34995SRabin Vincent { 123927e34995SRabin Vincent return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1, 12409e9dc7d9SLinus Walleij NULL, 0, stmpe->domain); 124127e34995SRabin Vincent } 124227e34995SRabin Vincent 1243612b95cdSGreg Kroah-Hartman static int stmpe_devices_init(struct stmpe *stmpe) 124427e34995SRabin Vincent { 124527e34995SRabin Vincent struct stmpe_variant_info *variant = stmpe->variant; 124627e34995SRabin Vincent unsigned int platform_blocks = stmpe->pdata->blocks; 124727e34995SRabin Vincent int ret = -EINVAL; 12487da0cbfcSLee Jones int i, j; 124927e34995SRabin Vincent 125027e34995SRabin Vincent for (i = 0; i < variant->num_blocks; i++) { 125127e34995SRabin Vincent struct stmpe_variant_block *block = &variant->blocks[i]; 125227e34995SRabin Vincent 125327e34995SRabin Vincent if (!(platform_blocks & block->block)) 125427e34995SRabin Vincent continue; 125527e34995SRabin Vincent 12567da0cbfcSLee Jones for (j = 0; j < block->cell->num_resources; j++) { 12577da0cbfcSLee Jones struct resource *res = 12587da0cbfcSLee Jones (struct resource *) &block->cell->resources[j]; 12597da0cbfcSLee Jones 12607da0cbfcSLee Jones /* Dynamically fill in a variant's IRQ. */ 12617da0cbfcSLee Jones if (res->flags & IORESOURCE_IRQ) 12627da0cbfcSLee Jones res->start = res->end = block->irq + j; 12637da0cbfcSLee Jones } 12647da0cbfcSLee Jones 126527e34995SRabin Vincent platform_blocks &= ~block->block; 12667da0cbfcSLee Jones ret = stmpe_add_device(stmpe, block->cell); 126727e34995SRabin Vincent if (ret) 126827e34995SRabin Vincent return ret; 126927e34995SRabin Vincent } 127027e34995SRabin Vincent 127127e34995SRabin Vincent if (platform_blocks) 127227e34995SRabin Vincent dev_warn(stmpe->dev, 127327e34995SRabin Vincent "platform wants blocks (%#x) not present on variant", 127427e34995SRabin Vincent platform_blocks); 127527e34995SRabin Vincent 127627e34995SRabin Vincent return ret; 127727e34995SRabin Vincent } 127827e34995SRabin Vincent 1279a9c4055dSMark Brown static void stmpe_of_probe(struct stmpe_platform_data *pdata, 1280a9c4055dSMark Brown struct device_node *np) 1281909582caSLee Jones { 1282909582caSLee Jones struct device_node *child; 1283909582caSLee Jones 1284408a3fa8SGabriel Fernandez pdata->id = of_alias_get_id(np, "stmpe-i2c"); 1285408a3fa8SGabriel Fernandez if (pdata->id < 0) 1286ac713cc9SVipul Kumar Samar pdata->id = -1; 1287408a3fa8SGabriel Fernandez 1288851ec596SSean Cross pdata->irq_gpio = of_get_named_gpio_flags(np, "irq-gpio", 0, 1289851ec596SSean Cross &pdata->irq_trigger); 1290851ec596SSean Cross if (gpio_is_valid(pdata->irq_gpio)) 1291851ec596SSean Cross pdata->irq_over_gpio = 1; 1292851ec596SSean Cross else 1293ac713cc9SVipul Kumar Samar pdata->irq_trigger = IRQF_TRIGGER_NONE; 1294ac713cc9SVipul Kumar Samar 1295909582caSLee Jones of_property_read_u32(np, "st,autosleep-timeout", 1296909582caSLee Jones &pdata->autosleep_timeout); 1297909582caSLee Jones 1298909582caSLee Jones pdata->autosleep = (pdata->autosleep_timeout) ? true : false; 1299909582caSLee Jones 1300909582caSLee Jones for_each_child_of_node(np, child) { 1301909582caSLee Jones if (!strcmp(child->name, "stmpe_gpio")) { 1302909582caSLee Jones pdata->blocks |= STMPE_BLOCK_GPIO; 1303ac713cc9SVipul Kumar Samar } else if (!strcmp(child->name, "stmpe_keypad")) { 1304909582caSLee Jones pdata->blocks |= STMPE_BLOCK_KEYPAD; 1305ac713cc9SVipul Kumar Samar } else if (!strcmp(child->name, "stmpe_touchscreen")) { 1306909582caSLee Jones pdata->blocks |= STMPE_BLOCK_TOUCHSCREEN; 1307ac713cc9SVipul Kumar Samar } else if (!strcmp(child->name, "stmpe_adc")) { 1308909582caSLee Jones pdata->blocks |= STMPE_BLOCK_ADC; 1309ac713cc9SVipul Kumar Samar } else if (!strcmp(child->name, "stmpe_pwm")) { 1310ac713cc9SVipul Kumar Samar pdata->blocks |= STMPE_BLOCK_PWM; 1311ac713cc9SVipul Kumar Samar } else if (!strcmp(child->name, "stmpe_rotator")) { 1312ac713cc9SVipul Kumar Samar pdata->blocks |= STMPE_BLOCK_ROTATOR; 1313909582caSLee Jones } 1314909582caSLee Jones } 1315909582caSLee Jones } 1316909582caSLee Jones 13171a6e4b74SViresh Kumar /* Called from client specific probe routines */ 1318c00572bcSLee Jones int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum) 1319208c4343SSundar Iyer { 1320fc1882dcSLinus Walleij struct stmpe_platform_data *pdata; 1321909582caSLee Jones struct device_node *np = ci->dev->of_node; 132227e34995SRabin Vincent struct stmpe *stmpe; 132327e34995SRabin Vincent int ret; 132427e34995SRabin Vincent 1325cb5faba9SViresh Kumar pdata = devm_kzalloc(ci->dev, sizeof(*pdata), GFP_KERNEL); 132627e34995SRabin Vincent if (!pdata) 1327909582caSLee Jones return -ENOMEM; 1328909582caSLee Jones 1329909582caSLee Jones stmpe_of_probe(pdata, np); 1330a200e320SGabriel Fernandez 1331a200e320SGabriel Fernandez if (of_find_property(np, "interrupts", NULL) == NULL) 1332a200e320SGabriel Fernandez ci->irq = -1; 133327e34995SRabin Vincent 1334cb5faba9SViresh Kumar stmpe = devm_kzalloc(ci->dev, sizeof(struct stmpe), GFP_KERNEL); 133527e34995SRabin Vincent if (!stmpe) 133627e34995SRabin Vincent return -ENOMEM; 133727e34995SRabin Vincent 133827e34995SRabin Vincent mutex_init(&stmpe->irq_lock); 133927e34995SRabin Vincent mutex_init(&stmpe->lock); 134027e34995SRabin Vincent 13411a6e4b74SViresh Kumar stmpe->dev = ci->dev; 13421a6e4b74SViresh Kumar stmpe->client = ci->client; 134327e34995SRabin Vincent stmpe->pdata = pdata; 13441a6e4b74SViresh Kumar stmpe->ci = ci; 13451a6e4b74SViresh Kumar stmpe->partnum = partnum; 13461a6e4b74SViresh Kumar stmpe->variant = stmpe_variant_info[partnum]; 134727e34995SRabin Vincent stmpe->regs = stmpe->variant->regs; 134827e34995SRabin Vincent stmpe->num_gpios = stmpe->variant->num_gpios; 13499c9e3214SLinus Walleij stmpe->vcc = devm_regulator_get_optional(ci->dev, "vcc"); 13509c9e3214SLinus Walleij if (!IS_ERR(stmpe->vcc)) { 13519c9e3214SLinus Walleij ret = regulator_enable(stmpe->vcc); 13529c9e3214SLinus Walleij if (ret) 13539c9e3214SLinus Walleij dev_warn(ci->dev, "failed to enable VCC supply\n"); 13549c9e3214SLinus Walleij } 13559c9e3214SLinus Walleij stmpe->vio = devm_regulator_get_optional(ci->dev, "vio"); 13569c9e3214SLinus Walleij if (!IS_ERR(stmpe->vio)) { 13579c9e3214SLinus Walleij ret = regulator_enable(stmpe->vio); 13589c9e3214SLinus Walleij if (ret) 13599c9e3214SLinus Walleij dev_warn(ci->dev, "failed to enable VIO supply\n"); 13609c9e3214SLinus Walleij } 13611a6e4b74SViresh Kumar dev_set_drvdata(stmpe->dev, stmpe); 136227e34995SRabin Vincent 13631a6e4b74SViresh Kumar if (ci->init) 13641a6e4b74SViresh Kumar ci->init(stmpe); 136527e34995SRabin Vincent 136673de16dbSViresh Kumar if (pdata->irq_over_gpio) { 1367cb5faba9SViresh Kumar ret = devm_gpio_request_one(ci->dev, pdata->irq_gpio, 1368cb5faba9SViresh Kumar GPIOF_DIR_IN, "stmpe"); 136973de16dbSViresh Kumar if (ret) { 137073de16dbSViresh Kumar dev_err(stmpe->dev, "failed to request IRQ GPIO: %d\n", 137173de16dbSViresh Kumar ret); 1372cb5faba9SViresh Kumar return ret; 137373de16dbSViresh Kumar } 137473de16dbSViresh Kumar 137573de16dbSViresh Kumar stmpe->irq = gpio_to_irq(pdata->irq_gpio); 137673de16dbSViresh Kumar } else { 13771a6e4b74SViresh Kumar stmpe->irq = ci->irq; 137873de16dbSViresh Kumar } 137973de16dbSViresh Kumar 1380e31f9b82SChris Blair if (stmpe->irq < 0) { 1381e31f9b82SChris Blair /* use alternate variant info for no-irq mode, if supported */ 1382e31f9b82SChris Blair dev_info(stmpe->dev, 1383e31f9b82SChris Blair "%s configured in no-irq mode by platform data\n", 1384e31f9b82SChris Blair stmpe->variant->name); 1385e31f9b82SChris Blair if (!stmpe_noirq_variant_info[stmpe->partnum]) { 1386e31f9b82SChris Blair dev_err(stmpe->dev, 1387e31f9b82SChris Blair "%s does not support no-irq mode!\n", 1388e31f9b82SChris Blair stmpe->variant->name); 1389cb5faba9SViresh Kumar return -ENODEV; 1390e31f9b82SChris Blair } 1391e31f9b82SChris Blair stmpe->variant = stmpe_noirq_variant_info[stmpe->partnum]; 1392ac713cc9SVipul Kumar Samar } else if (pdata->irq_trigger == IRQF_TRIGGER_NONE) { 13931a5595cbSJavier Martinez Canillas pdata->irq_trigger = irq_get_trigger_type(stmpe->irq); 1394e31f9b82SChris Blair } 1395e31f9b82SChris Blair 139627e34995SRabin Vincent ret = stmpe_chip_init(stmpe); 139727e34995SRabin Vincent if (ret) 1398cb5faba9SViresh Kumar return ret; 139927e34995SRabin Vincent 1400e31f9b82SChris Blair if (stmpe->irq >= 0) { 1401909582caSLee Jones ret = stmpe_irq_init(stmpe, np); 140227e34995SRabin Vincent if (ret) 1403cb5faba9SViresh Kumar return ret; 140427e34995SRabin Vincent 1405cb5faba9SViresh Kumar ret = devm_request_threaded_irq(ci->dev, stmpe->irq, NULL, 1406cb5faba9SViresh Kumar stmpe_irq, pdata->irq_trigger | IRQF_ONESHOT, 1407e31f9b82SChris Blair "stmpe", stmpe); 140827e34995SRabin Vincent if (ret) { 1409e31f9b82SChris Blair dev_err(stmpe->dev, "failed to request IRQ: %d\n", 1410e31f9b82SChris Blair ret); 1411cb5faba9SViresh Kumar return ret; 141227e34995SRabin Vincent } 1413e31f9b82SChris Blair } 141427e34995SRabin Vincent 141527e34995SRabin Vincent ret = stmpe_devices_init(stmpe); 1416cb5faba9SViresh Kumar if (!ret) 141727e34995SRabin Vincent return 0; 141827e34995SRabin Vincent 1419cb5faba9SViresh Kumar dev_err(stmpe->dev, "failed to add children\n"); 142027e34995SRabin Vincent mfd_remove_devices(stmpe->dev); 1421cb5faba9SViresh Kumar 142227e34995SRabin Vincent return ret; 142327e34995SRabin Vincent } 142427e34995SRabin Vincent 14251a6e4b74SViresh Kumar int stmpe_remove(struct stmpe *stmpe) 142627e34995SRabin Vincent { 14279c9e3214SLinus Walleij if (!IS_ERR(stmpe->vio)) 14289c9e3214SLinus Walleij regulator_disable(stmpe->vio); 14299c9e3214SLinus Walleij if (!IS_ERR(stmpe->vcc)) 14309c9e3214SLinus Walleij regulator_disable(stmpe->vcc); 14319c9e3214SLinus Walleij 143227e34995SRabin Vincent mfd_remove_devices(stmpe->dev); 143327e34995SRabin Vincent 143427e34995SRabin Vincent return 0; 143527e34995SRabin Vincent } 143627e34995SRabin Vincent 1437208c4343SSundar Iyer #ifdef CONFIG_PM 14381a6e4b74SViresh Kumar static int stmpe_suspend(struct device *dev) 14391a6e4b74SViresh Kumar { 14401a6e4b74SViresh Kumar struct stmpe *stmpe = dev_get_drvdata(dev); 14411a6e4b74SViresh Kumar 1442e31f9b82SChris Blair if (stmpe->irq >= 0 && device_may_wakeup(dev)) 14431a6e4b74SViresh Kumar enable_irq_wake(stmpe->irq); 14441a6e4b74SViresh Kumar 14451a6e4b74SViresh Kumar return 0; 14461a6e4b74SViresh Kumar } 14471a6e4b74SViresh Kumar 14481a6e4b74SViresh Kumar static int stmpe_resume(struct device *dev) 14491a6e4b74SViresh Kumar { 14501a6e4b74SViresh Kumar struct stmpe *stmpe = dev_get_drvdata(dev); 14511a6e4b74SViresh Kumar 1452e31f9b82SChris Blair if (stmpe->irq >= 0 && device_may_wakeup(dev)) 14531a6e4b74SViresh Kumar disable_irq_wake(stmpe->irq); 14541a6e4b74SViresh Kumar 14551a6e4b74SViresh Kumar return 0; 14561a6e4b74SViresh Kumar } 14571a6e4b74SViresh Kumar 14581a6e4b74SViresh Kumar const struct dev_pm_ops stmpe_dev_pm_ops = { 1459208c4343SSundar Iyer .suspend = stmpe_suspend, 1460208c4343SSundar Iyer .resume = stmpe_resume, 1461208c4343SSundar Iyer }; 1462208c4343SSundar Iyer #endif 1463