11f67b599SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 227e34995SRabin Vincent /* 31a6e4b74SViresh Kumar * ST Microelectronics MFD: stmpe's driver 41a6e4b74SViresh Kumar * 527e34995SRabin Vincent * Copyright (C) ST-Ericsson SA 2010 627e34995SRabin Vincent * 727e34995SRabin Vincent * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson 827e34995SRabin Vincent */ 927e34995SRabin Vincent 10ac713cc9SVipul Kumar Samar #include <linux/err.h> 11ac3e9119SDmitry Torokhov #include <linux/gpio/consumer.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> 181a6e4b74SViresh Kumar #include <linux/pm.h> 1927e34995SRabin Vincent #include <linux/slab.h> 2027e34995SRabin Vincent #include <linux/mfd/core.h> 21230f13a5SJean-Nicolas Graux #include <linux/delay.h> 229c9e3214SLinus Walleij #include <linux/regulator/consumer.h> 2327e34995SRabin Vincent #include "stmpe.h" 2427e34995SRabin Vincent 25fc1882dcSLinus Walleij /** 26fc1882dcSLinus Walleij * struct stmpe_platform_data - STMPE platform data 27fc1882dcSLinus Walleij * @id: device id to distinguish between multiple STMPEs on the same board 28fc1882dcSLinus Walleij * @blocks: bitmask of blocks to enable (use STMPE_BLOCK_*) 29fc1882dcSLinus Walleij * @irq_trigger: IRQ trigger to use for the interrupt to the host 30fc1882dcSLinus Walleij * @autosleep: bool to enable/disable stmpe autosleep 31fc1882dcSLinus Walleij * @autosleep_timeout: inactivity timeout in milliseconds for autosleep 32fc1882dcSLinus Walleij */ 33fc1882dcSLinus Walleij struct stmpe_platform_data { 34fc1882dcSLinus Walleij int id; 35fc1882dcSLinus Walleij unsigned int blocks; 36fc1882dcSLinus Walleij unsigned int irq_trigger; 37fc1882dcSLinus Walleij bool autosleep; 38fc1882dcSLinus Walleij int autosleep_timeout; 39fc1882dcSLinus Walleij }; 40fc1882dcSLinus Walleij 4127e34995SRabin Vincent static int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks) 4227e34995SRabin Vincent { 4327e34995SRabin Vincent return stmpe->variant->enable(stmpe, blocks, true); 4427e34995SRabin Vincent } 4527e34995SRabin Vincent 4627e34995SRabin Vincent static int __stmpe_disable(struct stmpe *stmpe, unsigned int blocks) 4727e34995SRabin Vincent { 4827e34995SRabin Vincent return stmpe->variant->enable(stmpe, blocks, false); 4927e34995SRabin Vincent } 5027e34995SRabin Vincent 5127e34995SRabin Vincent static int __stmpe_reg_read(struct stmpe *stmpe, u8 reg) 5227e34995SRabin Vincent { 5327e34995SRabin Vincent int ret; 5427e34995SRabin Vincent 551a6e4b74SViresh Kumar ret = stmpe->ci->read_byte(stmpe, reg); 5627e34995SRabin Vincent if (ret < 0) 571a6e4b74SViresh Kumar dev_err(stmpe->dev, "failed to read reg %#x: %d\n", reg, ret); 5827e34995SRabin Vincent 5927e34995SRabin Vincent dev_vdbg(stmpe->dev, "rd: reg %#x => data %#x\n", reg, ret); 6027e34995SRabin Vincent 6127e34995SRabin Vincent return ret; 6227e34995SRabin Vincent } 6327e34995SRabin Vincent 6427e34995SRabin Vincent static int __stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val) 6527e34995SRabin Vincent { 6627e34995SRabin Vincent int ret; 6727e34995SRabin Vincent 6827e34995SRabin Vincent dev_vdbg(stmpe->dev, "wr: reg %#x <= %#x\n", reg, val); 6927e34995SRabin Vincent 701a6e4b74SViresh Kumar ret = stmpe->ci->write_byte(stmpe, reg, val); 7127e34995SRabin Vincent if (ret < 0) 721a6e4b74SViresh Kumar dev_err(stmpe->dev, "failed to write reg %#x: %d\n", reg, ret); 7327e34995SRabin Vincent 7427e34995SRabin Vincent return ret; 7527e34995SRabin Vincent } 7627e34995SRabin Vincent 7727e34995SRabin Vincent static int __stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val) 7827e34995SRabin Vincent { 7927e34995SRabin Vincent int ret; 8027e34995SRabin Vincent 8127e34995SRabin Vincent ret = __stmpe_reg_read(stmpe, reg); 8227e34995SRabin Vincent if (ret < 0) 8327e34995SRabin Vincent return ret; 8427e34995SRabin Vincent 8527e34995SRabin Vincent ret &= ~mask; 8627e34995SRabin Vincent ret |= val; 8727e34995SRabin Vincent 8827e34995SRabin Vincent return __stmpe_reg_write(stmpe, reg, ret); 8927e34995SRabin Vincent } 9027e34995SRabin Vincent 9127e34995SRabin Vincent static int __stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length, 9227e34995SRabin Vincent u8 *values) 9327e34995SRabin Vincent { 9427e34995SRabin Vincent int ret; 9527e34995SRabin Vincent 961a6e4b74SViresh Kumar ret = stmpe->ci->read_block(stmpe, reg, length, values); 9727e34995SRabin Vincent if (ret < 0) 981a6e4b74SViresh Kumar dev_err(stmpe->dev, "failed to read regs %#x: %d\n", reg, ret); 9927e34995SRabin Vincent 10027e34995SRabin Vincent dev_vdbg(stmpe->dev, "rd: reg %#x (%d) => ret %#x\n", reg, length, ret); 10127e34995SRabin Vincent stmpe_dump_bytes("stmpe rd: ", values, length); 10227e34995SRabin Vincent 10327e34995SRabin Vincent return ret; 10427e34995SRabin Vincent } 10527e34995SRabin Vincent 10627e34995SRabin Vincent static int __stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length, 10727e34995SRabin Vincent const u8 *values) 10827e34995SRabin Vincent { 10927e34995SRabin Vincent int ret; 11027e34995SRabin Vincent 11127e34995SRabin Vincent dev_vdbg(stmpe->dev, "wr: regs %#x (%d)\n", reg, length); 11227e34995SRabin Vincent stmpe_dump_bytes("stmpe wr: ", values, length); 11327e34995SRabin Vincent 1141a6e4b74SViresh Kumar ret = stmpe->ci->write_block(stmpe, reg, length, values); 11527e34995SRabin Vincent if (ret < 0) 1161a6e4b74SViresh Kumar dev_err(stmpe->dev, "failed to write regs %#x: %d\n", reg, ret); 11727e34995SRabin Vincent 11827e34995SRabin Vincent return ret; 11927e34995SRabin Vincent } 12027e34995SRabin Vincent 12127e34995SRabin Vincent /** 12227e34995SRabin Vincent * stmpe_enable - enable blocks on an STMPE device 12327e34995SRabin Vincent * @stmpe: Device to work on 12427e34995SRabin Vincent * @blocks: Mask of blocks (enum stmpe_block values) to enable 12527e34995SRabin Vincent */ 12627e34995SRabin Vincent int stmpe_enable(struct stmpe *stmpe, unsigned int blocks) 12727e34995SRabin Vincent { 12827e34995SRabin Vincent int ret; 12927e34995SRabin Vincent 13027e34995SRabin Vincent mutex_lock(&stmpe->lock); 13127e34995SRabin Vincent ret = __stmpe_enable(stmpe, blocks); 13227e34995SRabin Vincent mutex_unlock(&stmpe->lock); 13327e34995SRabin Vincent 13427e34995SRabin Vincent return ret; 13527e34995SRabin Vincent } 13627e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_enable); 13727e34995SRabin Vincent 13827e34995SRabin Vincent /** 13927e34995SRabin Vincent * stmpe_disable - disable blocks on an STMPE device 14027e34995SRabin Vincent * @stmpe: Device to work on 14127e34995SRabin Vincent * @blocks: Mask of blocks (enum stmpe_block values) to enable 14227e34995SRabin Vincent */ 14327e34995SRabin Vincent int stmpe_disable(struct stmpe *stmpe, unsigned int blocks) 14427e34995SRabin Vincent { 14527e34995SRabin Vincent int ret; 14627e34995SRabin Vincent 14727e34995SRabin Vincent mutex_lock(&stmpe->lock); 14827e34995SRabin Vincent ret = __stmpe_disable(stmpe, blocks); 14927e34995SRabin Vincent mutex_unlock(&stmpe->lock); 15027e34995SRabin Vincent 15127e34995SRabin Vincent return ret; 15227e34995SRabin Vincent } 15327e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_disable); 15427e34995SRabin Vincent 15527e34995SRabin Vincent /** 15627e34995SRabin Vincent * stmpe_reg_read() - read a single STMPE register 15727e34995SRabin Vincent * @stmpe: Device to read from 15827e34995SRabin Vincent * @reg: Register to read 15927e34995SRabin Vincent */ 16027e34995SRabin Vincent int stmpe_reg_read(struct stmpe *stmpe, u8 reg) 16127e34995SRabin Vincent { 16227e34995SRabin Vincent int ret; 16327e34995SRabin Vincent 16427e34995SRabin Vincent mutex_lock(&stmpe->lock); 16527e34995SRabin Vincent ret = __stmpe_reg_read(stmpe, reg); 16627e34995SRabin Vincent mutex_unlock(&stmpe->lock); 16727e34995SRabin Vincent 16827e34995SRabin Vincent return ret; 16927e34995SRabin Vincent } 17027e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_reg_read); 17127e34995SRabin Vincent 17227e34995SRabin Vincent /** 17327e34995SRabin Vincent * stmpe_reg_write() - write a single STMPE register 17427e34995SRabin Vincent * @stmpe: Device to write to 17527e34995SRabin Vincent * @reg: Register to write 17627e34995SRabin Vincent * @val: Value to write 17727e34995SRabin Vincent */ 17827e34995SRabin Vincent int stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val) 17927e34995SRabin Vincent { 18027e34995SRabin Vincent int ret; 18127e34995SRabin Vincent 18227e34995SRabin Vincent mutex_lock(&stmpe->lock); 18327e34995SRabin Vincent ret = __stmpe_reg_write(stmpe, reg, val); 18427e34995SRabin Vincent mutex_unlock(&stmpe->lock); 18527e34995SRabin Vincent 18627e34995SRabin Vincent return ret; 18727e34995SRabin Vincent } 18827e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_reg_write); 18927e34995SRabin Vincent 19027e34995SRabin Vincent /** 19127e34995SRabin Vincent * stmpe_set_bits() - set the value of a bitfield in a STMPE register 19227e34995SRabin Vincent * @stmpe: Device to write to 19327e34995SRabin Vincent * @reg: Register to write 19427e34995SRabin Vincent * @mask: Mask of bits to set 19527e34995SRabin Vincent * @val: Value to set 19627e34995SRabin Vincent */ 19727e34995SRabin Vincent int stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val) 19827e34995SRabin Vincent { 19927e34995SRabin Vincent int ret; 20027e34995SRabin Vincent 20127e34995SRabin Vincent mutex_lock(&stmpe->lock); 20227e34995SRabin Vincent ret = __stmpe_set_bits(stmpe, reg, mask, val); 20327e34995SRabin Vincent mutex_unlock(&stmpe->lock); 20427e34995SRabin Vincent 20527e34995SRabin Vincent return ret; 20627e34995SRabin Vincent } 20727e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_set_bits); 20827e34995SRabin Vincent 20927e34995SRabin Vincent /** 21027e34995SRabin Vincent * stmpe_block_read() - read multiple STMPE registers 21127e34995SRabin Vincent * @stmpe: Device to read from 21227e34995SRabin Vincent * @reg: First register 21327e34995SRabin Vincent * @length: Number of registers 21427e34995SRabin Vincent * @values: Buffer to write to 21527e34995SRabin Vincent */ 21627e34995SRabin Vincent int stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values) 21727e34995SRabin Vincent { 21827e34995SRabin Vincent int ret; 21927e34995SRabin Vincent 22027e34995SRabin Vincent mutex_lock(&stmpe->lock); 22127e34995SRabin Vincent ret = __stmpe_block_read(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_read); 22727e34995SRabin Vincent 22827e34995SRabin Vincent /** 22927e34995SRabin Vincent * stmpe_block_write() - write multiple STMPE registers 23027e34995SRabin Vincent * @stmpe: Device to write to 23127e34995SRabin Vincent * @reg: First register 23227e34995SRabin Vincent * @length: Number of registers 23327e34995SRabin Vincent * @values: Values to write 23427e34995SRabin Vincent */ 23527e34995SRabin Vincent int stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length, 23627e34995SRabin Vincent const u8 *values) 23727e34995SRabin Vincent { 23827e34995SRabin Vincent int ret; 23927e34995SRabin Vincent 24027e34995SRabin Vincent mutex_lock(&stmpe->lock); 24127e34995SRabin Vincent ret = __stmpe_block_write(stmpe, reg, length, values); 24227e34995SRabin Vincent mutex_unlock(&stmpe->lock); 24327e34995SRabin Vincent 24427e34995SRabin Vincent return ret; 24527e34995SRabin Vincent } 24627e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_block_write); 24727e34995SRabin Vincent 24827e34995SRabin Vincent /** 2494dcaa6b6SOm Prakash * stmpe_set_altfunc()- set the alternate function for STMPE pins 25027e34995SRabin Vincent * @stmpe: Device to configure 25127e34995SRabin Vincent * @pins: Bitmask of pins to affect 25227e34995SRabin Vincent * @block: block to enable alternate functions for 25327e34995SRabin Vincent * 25427e34995SRabin Vincent * @pins is assumed to have a bit set for each of the bits whose alternate 25527e34995SRabin Vincent * function is to be changed, numbered according to the GPIOXY numbers. 25627e34995SRabin Vincent * 25727e34995SRabin Vincent * If the GPIO module is not enabled, this function automatically enables it in 25827e34995SRabin Vincent * order to perform the change. 25927e34995SRabin Vincent */ 26027e34995SRabin Vincent int stmpe_set_altfunc(struct stmpe *stmpe, u32 pins, enum stmpe_block block) 26127e34995SRabin Vincent { 26227e34995SRabin Vincent struct stmpe_variant_info *variant = stmpe->variant; 26327e34995SRabin Vincent u8 regaddr = stmpe->regs[STMPE_IDX_GPAFR_U_MSB]; 26427e34995SRabin Vincent int af_bits = variant->af_bits; 26527e34995SRabin Vincent int numregs = DIV_ROUND_UP(stmpe->num_gpios * af_bits, 8); 26627e34995SRabin Vincent int mask = (1 << af_bits) - 1; 2677929fa77SLee Jones u8 regs[8]; 2687f7f4ea1SViresh Kumar int af, afperreg, ret; 26927e34995SRabin Vincent 2707f7f4ea1SViresh Kumar if (!variant->get_altfunc) 2717f7f4ea1SViresh Kumar return 0; 2727f7f4ea1SViresh Kumar 2737f7f4ea1SViresh Kumar afperreg = 8 / af_bits; 27427e34995SRabin Vincent mutex_lock(&stmpe->lock); 27527e34995SRabin Vincent 27627e34995SRabin Vincent ret = __stmpe_enable(stmpe, STMPE_BLOCK_GPIO); 27727e34995SRabin Vincent if (ret < 0) 27827e34995SRabin Vincent goto out; 27927e34995SRabin Vincent 28027e34995SRabin Vincent ret = __stmpe_block_read(stmpe, regaddr, numregs, regs); 28127e34995SRabin Vincent if (ret < 0) 28227e34995SRabin Vincent goto out; 28327e34995SRabin Vincent 28427e34995SRabin Vincent af = variant->get_altfunc(stmpe, block); 28527e34995SRabin Vincent 28627e34995SRabin Vincent while (pins) { 28727e34995SRabin Vincent int pin = __ffs(pins); 28827e34995SRabin Vincent int regoffset = numregs - (pin / afperreg) - 1; 28927e34995SRabin Vincent int pos = (pin % afperreg) * (8 / afperreg); 29027e34995SRabin Vincent 29127e34995SRabin Vincent regs[regoffset] &= ~(mask << pos); 29227e34995SRabin Vincent regs[regoffset] |= af << pos; 29327e34995SRabin Vincent 29427e34995SRabin Vincent pins &= ~(1 << pin); 29527e34995SRabin Vincent } 29627e34995SRabin Vincent 29727e34995SRabin Vincent ret = __stmpe_block_write(stmpe, regaddr, numregs, regs); 29827e34995SRabin Vincent 29927e34995SRabin Vincent out: 30027e34995SRabin Vincent mutex_unlock(&stmpe->lock); 30127e34995SRabin Vincent return ret; 30227e34995SRabin Vincent } 30327e34995SRabin Vincent EXPORT_SYMBOL_GPL(stmpe_set_altfunc); 30427e34995SRabin Vincent 30527e34995SRabin Vincent /* 30627e34995SRabin Vincent * GPIO (all variants) 30727e34995SRabin Vincent */ 30827e34995SRabin Vincent 309cb9e880aSRikard Falkeborn static struct resource stmpe_gpio_resources[] = { 31027e34995SRabin Vincent /* Start and end filled dynamically */ 31127e34995SRabin Vincent { 31227e34995SRabin Vincent .flags = IORESOURCE_IRQ, 31327e34995SRabin Vincent }, 31427e34995SRabin Vincent }; 31527e34995SRabin Vincent 3166bbb3c4cSGeert Uytterhoeven static const struct mfd_cell stmpe_gpio_cell = { 31727e34995SRabin Vincent .name = "stmpe-gpio", 31886605cfeSVipul Kumar Samar .of_compatible = "st,stmpe-gpio", 31927e34995SRabin Vincent .resources = stmpe_gpio_resources, 32027e34995SRabin Vincent .num_resources = ARRAY_SIZE(stmpe_gpio_resources), 32127e34995SRabin Vincent }; 32227e34995SRabin Vincent 3236bbb3c4cSGeert Uytterhoeven static const struct mfd_cell stmpe_gpio_cell_noirq = { 324e31f9b82SChris Blair .name = "stmpe-gpio", 32586605cfeSVipul Kumar Samar .of_compatible = "st,stmpe-gpio", 326e31f9b82SChris Blair /* gpio cell resources consist of an irq only so no resources here */ 327e31f9b82SChris Blair }; 328e31f9b82SChris Blair 32927e34995SRabin Vincent /* 33027e34995SRabin Vincent * Keypad (1601, 2401, 2403) 33127e34995SRabin Vincent */ 33227e34995SRabin Vincent 333cb9e880aSRikard Falkeborn static struct resource stmpe_keypad_resources[] = { 334cb9e880aSRikard Falkeborn /* Start and end filled dynamically */ 33527e34995SRabin Vincent { 33627e34995SRabin Vincent .name = "KEYPAD", 33727e34995SRabin Vincent .flags = IORESOURCE_IRQ, 33827e34995SRabin Vincent }, 33927e34995SRabin Vincent { 34027e34995SRabin Vincent .name = "KEYPAD_OVER", 34127e34995SRabin Vincent .flags = IORESOURCE_IRQ, 34227e34995SRabin Vincent }, 34327e34995SRabin Vincent }; 34427e34995SRabin Vincent 3456bbb3c4cSGeert Uytterhoeven static const struct mfd_cell stmpe_keypad_cell = { 34627e34995SRabin Vincent .name = "stmpe-keypad", 3476ea32387SDmitry Torokhov .of_compatible = "st,stmpe-keypad", 34827e34995SRabin Vincent .resources = stmpe_keypad_resources, 34927e34995SRabin Vincent .num_resources = ARRAY_SIZE(stmpe_keypad_resources), 35027e34995SRabin Vincent }; 35127e34995SRabin Vincent 35227e34995SRabin Vincent /* 353b273c5e0SLinus Walleij * PWM (1601, 2401, 2403) 354b273c5e0SLinus Walleij */ 355cb9e880aSRikard Falkeborn static struct resource stmpe_pwm_resources[] = { 356cb9e880aSRikard Falkeborn /* Start and end filled dynamically */ 357b273c5e0SLinus Walleij { 358b273c5e0SLinus Walleij .name = "PWM0", 359b273c5e0SLinus Walleij .flags = IORESOURCE_IRQ, 360b273c5e0SLinus Walleij }, 361b273c5e0SLinus Walleij { 362b273c5e0SLinus Walleij .name = "PWM1", 363b273c5e0SLinus Walleij .flags = IORESOURCE_IRQ, 364b273c5e0SLinus Walleij }, 365b273c5e0SLinus Walleij { 366b273c5e0SLinus Walleij .name = "PWM2", 367b273c5e0SLinus Walleij .flags = IORESOURCE_IRQ, 368b273c5e0SLinus Walleij }, 369b273c5e0SLinus Walleij }; 370b273c5e0SLinus Walleij 371b273c5e0SLinus Walleij static const struct mfd_cell stmpe_pwm_cell = { 372b273c5e0SLinus Walleij .name = "stmpe-pwm", 373b273c5e0SLinus Walleij .of_compatible = "st,stmpe-pwm", 374b273c5e0SLinus Walleij .resources = stmpe_pwm_resources, 375b273c5e0SLinus Walleij .num_resources = ARRAY_SIZE(stmpe_pwm_resources), 376b273c5e0SLinus Walleij }; 377b273c5e0SLinus Walleij 378b273c5e0SLinus Walleij /* 3797f7f4ea1SViresh Kumar * STMPE801 3807f7f4ea1SViresh Kumar */ 3817f7f4ea1SViresh Kumar static const u8 stmpe801_regs[] = { 3827f7f4ea1SViresh Kumar [STMPE_IDX_CHIP_ID] = STMPE801_REG_CHIP_ID, 3837f7f4ea1SViresh Kumar [STMPE_IDX_ICR_LSB] = STMPE801_REG_SYS_CTRL, 3847f7f4ea1SViresh Kumar [STMPE_IDX_GPMR_LSB] = STMPE801_REG_GPIO_MP_STA, 3857f7f4ea1SViresh Kumar [STMPE_IDX_GPSR_LSB] = STMPE801_REG_GPIO_SET_PIN, 3867f7f4ea1SViresh Kumar [STMPE_IDX_GPCR_LSB] = STMPE801_REG_GPIO_SET_PIN, 3877f7f4ea1SViresh Kumar [STMPE_IDX_GPDR_LSB] = STMPE801_REG_GPIO_DIR, 3887f7f4ea1SViresh Kumar [STMPE_IDX_IEGPIOR_LSB] = STMPE801_REG_GPIO_INT_EN, 3897f7f4ea1SViresh Kumar [STMPE_IDX_ISGPIOR_MSB] = STMPE801_REG_GPIO_INT_STA, 3907f7f4ea1SViresh Kumar 3917f7f4ea1SViresh Kumar }; 3927f7f4ea1SViresh Kumar 3937f7f4ea1SViresh Kumar static struct stmpe_variant_block stmpe801_blocks[] = { 3947f7f4ea1SViresh Kumar { 3957f7f4ea1SViresh Kumar .cell = &stmpe_gpio_cell, 3967f7f4ea1SViresh Kumar .irq = 0, 3977f7f4ea1SViresh Kumar .block = STMPE_BLOCK_GPIO, 3987f7f4ea1SViresh Kumar }, 3997f7f4ea1SViresh Kumar }; 4007f7f4ea1SViresh Kumar 401e31f9b82SChris Blair static struct stmpe_variant_block stmpe801_blocks_noirq[] = { 402e31f9b82SChris Blair { 403e31f9b82SChris Blair .cell = &stmpe_gpio_cell_noirq, 404e31f9b82SChris Blair .block = STMPE_BLOCK_GPIO, 405e31f9b82SChris Blair }, 406e31f9b82SChris Blair }; 407e31f9b82SChris Blair 4087f7f4ea1SViresh Kumar static int stmpe801_enable(struct stmpe *stmpe, unsigned int blocks, 4097f7f4ea1SViresh Kumar bool enable) 4107f7f4ea1SViresh Kumar { 4117f7f4ea1SViresh Kumar if (blocks & STMPE_BLOCK_GPIO) 4127f7f4ea1SViresh Kumar return 0; 4137f7f4ea1SViresh Kumar else 4147f7f4ea1SViresh Kumar return -EINVAL; 4157f7f4ea1SViresh Kumar } 4167f7f4ea1SViresh Kumar 4177f7f4ea1SViresh Kumar static struct stmpe_variant_info stmpe801 = { 4187f7f4ea1SViresh Kumar .name = "stmpe801", 4197f7f4ea1SViresh Kumar .id_val = STMPE801_ID, 4207f7f4ea1SViresh Kumar .id_mask = 0xffff, 4217f7f4ea1SViresh Kumar .num_gpios = 8, 4227f7f4ea1SViresh Kumar .regs = stmpe801_regs, 4237f7f4ea1SViresh Kumar .blocks = stmpe801_blocks, 4247f7f4ea1SViresh Kumar .num_blocks = ARRAY_SIZE(stmpe801_blocks), 4257f7f4ea1SViresh Kumar .num_irqs = STMPE801_NR_INTERNAL_IRQS, 4267f7f4ea1SViresh Kumar .enable = stmpe801_enable, 4277f7f4ea1SViresh Kumar }; 4287f7f4ea1SViresh Kumar 429e31f9b82SChris Blair static struct stmpe_variant_info stmpe801_noirq = { 430e31f9b82SChris Blair .name = "stmpe801", 431e31f9b82SChris Blair .id_val = STMPE801_ID, 432e31f9b82SChris Blair .id_mask = 0xffff, 433e31f9b82SChris Blair .num_gpios = 8, 434e31f9b82SChris Blair .regs = stmpe801_regs, 435e31f9b82SChris Blair .blocks = stmpe801_blocks_noirq, 436e31f9b82SChris Blair .num_blocks = ARRAY_SIZE(stmpe801_blocks_noirq), 437e31f9b82SChris Blair .enable = stmpe801_enable, 438e31f9b82SChris Blair }; 439e31f9b82SChris Blair 4407f7f4ea1SViresh Kumar /* 4411cda2394SViresh Kumar * Touchscreen (STMPE811 or STMPE610) 44227e34995SRabin Vincent */ 44327e34995SRabin Vincent 444cb9e880aSRikard Falkeborn static struct resource stmpe_ts_resources[] = { 445cb9e880aSRikard Falkeborn /* Start and end filled dynamically */ 44627e34995SRabin Vincent { 44727e34995SRabin Vincent .name = "TOUCH_DET", 44827e34995SRabin Vincent .flags = IORESOURCE_IRQ, 44927e34995SRabin Vincent }, 45027e34995SRabin Vincent { 45127e34995SRabin Vincent .name = "FIFO_TH", 45227e34995SRabin Vincent .flags = IORESOURCE_IRQ, 45327e34995SRabin Vincent }, 45427e34995SRabin Vincent }; 45527e34995SRabin Vincent 4566bbb3c4cSGeert Uytterhoeven static const struct mfd_cell stmpe_ts_cell = { 45727e34995SRabin Vincent .name = "stmpe-ts", 458037db524SVipul Kumar Samar .of_compatible = "st,stmpe-ts", 45927e34995SRabin Vincent .resources = stmpe_ts_resources, 46027e34995SRabin Vincent .num_resources = ARRAY_SIZE(stmpe_ts_resources), 46127e34995SRabin Vincent }; 46227e34995SRabin Vincent 46327e34995SRabin Vincent /* 4646377cfa3SStefan Agner * ADC (STMPE811) 4656377cfa3SStefan Agner */ 4666377cfa3SStefan Agner 467cb9e880aSRikard Falkeborn static struct resource stmpe_adc_resources[] = { 468cb9e880aSRikard Falkeborn /* Start and end filled dynamically */ 4696377cfa3SStefan Agner { 4706377cfa3SStefan Agner .name = "STMPE_TEMP_SENS", 4716377cfa3SStefan Agner .flags = IORESOURCE_IRQ, 4726377cfa3SStefan Agner }, 4736377cfa3SStefan Agner { 4746377cfa3SStefan Agner .name = "STMPE_ADC", 4756377cfa3SStefan Agner .flags = IORESOURCE_IRQ, 4766377cfa3SStefan Agner }, 4776377cfa3SStefan Agner }; 4786377cfa3SStefan Agner 4796377cfa3SStefan Agner static const struct mfd_cell stmpe_adc_cell = { 4806377cfa3SStefan Agner .name = "stmpe-adc", 4816377cfa3SStefan Agner .of_compatible = "st,stmpe-adc", 4826377cfa3SStefan Agner .resources = stmpe_adc_resources, 4836377cfa3SStefan Agner .num_resources = ARRAY_SIZE(stmpe_adc_resources), 4846377cfa3SStefan Agner }; 4856377cfa3SStefan Agner 4866377cfa3SStefan Agner /* 4871cda2394SViresh Kumar * STMPE811 or STMPE610 48827e34995SRabin Vincent */ 48927e34995SRabin Vincent 49027e34995SRabin Vincent static const u8 stmpe811_regs[] = { 49127e34995SRabin Vincent [STMPE_IDX_CHIP_ID] = STMPE811_REG_CHIP_ID, 4920f4be8cfSPatrice Chotard [STMPE_IDX_SYS_CTRL] = STMPE811_REG_SYS_CTRL, 4930f4be8cfSPatrice Chotard [STMPE_IDX_SYS_CTRL2] = STMPE811_REG_SYS_CTRL2, 49427e34995SRabin Vincent [STMPE_IDX_ICR_LSB] = STMPE811_REG_INT_CTRL, 49527e34995SRabin Vincent [STMPE_IDX_IER_LSB] = STMPE811_REG_INT_EN, 49627e34995SRabin Vincent [STMPE_IDX_ISR_MSB] = STMPE811_REG_INT_STA, 49727e34995SRabin Vincent [STMPE_IDX_GPMR_LSB] = STMPE811_REG_GPIO_MP_STA, 49827e34995SRabin Vincent [STMPE_IDX_GPSR_LSB] = STMPE811_REG_GPIO_SET_PIN, 49927e34995SRabin Vincent [STMPE_IDX_GPCR_LSB] = STMPE811_REG_GPIO_CLR_PIN, 50027e34995SRabin Vincent [STMPE_IDX_GPDR_LSB] = STMPE811_REG_GPIO_DIR, 50127e34995SRabin Vincent [STMPE_IDX_GPRER_LSB] = STMPE811_REG_GPIO_RE, 50227e34995SRabin Vincent [STMPE_IDX_GPFER_LSB] = STMPE811_REG_GPIO_FE, 50327e34995SRabin Vincent [STMPE_IDX_GPAFR_U_MSB] = STMPE811_REG_GPIO_AF, 50427e34995SRabin Vincent [STMPE_IDX_IEGPIOR_LSB] = STMPE811_REG_GPIO_INT_EN, 50527e34995SRabin Vincent [STMPE_IDX_ISGPIOR_MSB] = STMPE811_REG_GPIO_INT_STA, 506897ac667SPatrice Chotard [STMPE_IDX_GPEDR_LSB] = STMPE811_REG_GPIO_ED, 50727e34995SRabin Vincent }; 50827e34995SRabin Vincent 50927e34995SRabin Vincent static struct stmpe_variant_block stmpe811_blocks[] = { 51027e34995SRabin Vincent { 51127e34995SRabin Vincent .cell = &stmpe_gpio_cell, 51227e34995SRabin Vincent .irq = STMPE811_IRQ_GPIOC, 51327e34995SRabin Vincent .block = STMPE_BLOCK_GPIO, 51427e34995SRabin Vincent }, 51527e34995SRabin Vincent { 51627e34995SRabin Vincent .cell = &stmpe_ts_cell, 51727e34995SRabin Vincent .irq = STMPE811_IRQ_TOUCH_DET, 51827e34995SRabin Vincent .block = STMPE_BLOCK_TOUCHSCREEN, 51927e34995SRabin Vincent }, 5206377cfa3SStefan Agner { 5216377cfa3SStefan Agner .cell = &stmpe_adc_cell, 5226377cfa3SStefan Agner .irq = STMPE811_IRQ_TEMP_SENS, 5236377cfa3SStefan Agner .block = STMPE_BLOCK_ADC, 5246377cfa3SStefan Agner }, 52527e34995SRabin Vincent }; 52627e34995SRabin Vincent 52727e34995SRabin Vincent static int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks, 52827e34995SRabin Vincent bool enable) 52927e34995SRabin Vincent { 53027e34995SRabin Vincent unsigned int mask = 0; 53127e34995SRabin Vincent 53227e34995SRabin Vincent if (blocks & STMPE_BLOCK_GPIO) 53327e34995SRabin Vincent mask |= STMPE811_SYS_CTRL2_GPIO_OFF; 53427e34995SRabin Vincent 53527e34995SRabin Vincent if (blocks & STMPE_BLOCK_ADC) 53627e34995SRabin Vincent mask |= STMPE811_SYS_CTRL2_ADC_OFF; 53727e34995SRabin Vincent 53827e34995SRabin Vincent if (blocks & STMPE_BLOCK_TOUCHSCREEN) 53927e34995SRabin Vincent mask |= STMPE811_SYS_CTRL2_TSC_OFF; 54027e34995SRabin Vincent 5410f4be8cfSPatrice Chotard return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2], mask, 54227e34995SRabin Vincent enable ? 0 : mask); 54327e34995SRabin Vincent } 54427e34995SRabin Vincent 5456377cfa3SStefan Agner int stmpe811_adc_common_init(struct stmpe *stmpe) 5466377cfa3SStefan Agner { 5476377cfa3SStefan Agner int ret; 5486377cfa3SStefan Agner u8 adc_ctrl1, adc_ctrl1_mask; 5496377cfa3SStefan Agner 5506377cfa3SStefan Agner adc_ctrl1 = STMPE_SAMPLE_TIME(stmpe->sample_time) | 5516377cfa3SStefan Agner STMPE_MOD_12B(stmpe->mod_12b) | 5526377cfa3SStefan Agner STMPE_REF_SEL(stmpe->ref_sel); 5536377cfa3SStefan Agner adc_ctrl1_mask = STMPE_SAMPLE_TIME(0xff) | STMPE_MOD_12B(0xff) | 5546377cfa3SStefan Agner STMPE_REF_SEL(0xff); 5556377cfa3SStefan Agner 5566377cfa3SStefan Agner ret = stmpe_set_bits(stmpe, STMPE811_REG_ADC_CTRL1, 5576377cfa3SStefan Agner adc_ctrl1_mask, adc_ctrl1); 5586377cfa3SStefan Agner if (ret) { 5596377cfa3SStefan Agner dev_err(stmpe->dev, "Could not setup ADC\n"); 5606377cfa3SStefan Agner return ret; 5616377cfa3SStefan Agner } 5626377cfa3SStefan Agner 5636377cfa3SStefan Agner ret = stmpe_set_bits(stmpe, STMPE811_REG_ADC_CTRL2, 5646377cfa3SStefan Agner STMPE_ADC_FREQ(0xff), STMPE_ADC_FREQ(stmpe->adc_freq)); 5656377cfa3SStefan Agner if (ret) { 5666377cfa3SStefan Agner dev_err(stmpe->dev, "Could not setup ADC\n"); 5676377cfa3SStefan Agner return ret; 5686377cfa3SStefan Agner } 5696377cfa3SStefan Agner 5706377cfa3SStefan Agner return 0; 5716377cfa3SStefan Agner } 5726377cfa3SStefan Agner EXPORT_SYMBOL_GPL(stmpe811_adc_common_init); 5736377cfa3SStefan Agner 57427e34995SRabin Vincent static int stmpe811_get_altfunc(struct stmpe *stmpe, enum stmpe_block block) 57527e34995SRabin Vincent { 57627e34995SRabin Vincent /* 0 for touchscreen, 1 for GPIO */ 57727e34995SRabin Vincent return block != STMPE_BLOCK_TOUCHSCREEN; 57827e34995SRabin Vincent } 57927e34995SRabin Vincent 58027e34995SRabin Vincent static struct stmpe_variant_info stmpe811 = { 58127e34995SRabin Vincent .name = "stmpe811", 58227e34995SRabin Vincent .id_val = 0x0811, 58327e34995SRabin Vincent .id_mask = 0xffff, 58427e34995SRabin Vincent .num_gpios = 8, 58527e34995SRabin Vincent .af_bits = 1, 58627e34995SRabin Vincent .regs = stmpe811_regs, 58727e34995SRabin Vincent .blocks = stmpe811_blocks, 58827e34995SRabin Vincent .num_blocks = ARRAY_SIZE(stmpe811_blocks), 58927e34995SRabin Vincent .num_irqs = STMPE811_NR_INTERNAL_IRQS, 59027e34995SRabin Vincent .enable = stmpe811_enable, 59127e34995SRabin Vincent .get_altfunc = stmpe811_get_altfunc, 59227e34995SRabin Vincent }; 59327e34995SRabin Vincent 5941cda2394SViresh Kumar /* Similar to 811, except number of gpios */ 5951cda2394SViresh Kumar static struct stmpe_variant_info stmpe610 = { 5961cda2394SViresh Kumar .name = "stmpe610", 5971cda2394SViresh Kumar .id_val = 0x0811, 5981cda2394SViresh Kumar .id_mask = 0xffff, 5991cda2394SViresh Kumar .num_gpios = 6, 6001cda2394SViresh Kumar .af_bits = 1, 6011cda2394SViresh Kumar .regs = stmpe811_regs, 6021cda2394SViresh Kumar .blocks = stmpe811_blocks, 6031cda2394SViresh Kumar .num_blocks = ARRAY_SIZE(stmpe811_blocks), 6041cda2394SViresh Kumar .num_irqs = STMPE811_NR_INTERNAL_IRQS, 6051cda2394SViresh Kumar .enable = stmpe811_enable, 6061cda2394SViresh Kumar .get_altfunc = stmpe811_get_altfunc, 6071cda2394SViresh Kumar }; 6081cda2394SViresh Kumar 60927e34995SRabin Vincent /* 6106bb9f0d9SPatrice Chotard * STMPE1600 6116bb9f0d9SPatrice Chotard * Compared to all others STMPE variant, LSB and MSB regs are located in this 6126bb9f0d9SPatrice Chotard * order : LSB addr 6136bb9f0d9SPatrice Chotard * MSB addr + 1 6146bb9f0d9SPatrice Chotard * As there is only 2 * 8bits registers for GPMR/GPSR/IEGPIOPR, CSB index is MSB registers 6156bb9f0d9SPatrice Chotard */ 6166bb9f0d9SPatrice Chotard 6176bb9f0d9SPatrice Chotard static const u8 stmpe1600_regs[] = { 6186bb9f0d9SPatrice Chotard [STMPE_IDX_CHIP_ID] = STMPE1600_REG_CHIP_ID, 6196bb9f0d9SPatrice Chotard [STMPE_IDX_SYS_CTRL] = STMPE1600_REG_SYS_CTRL, 6206bb9f0d9SPatrice Chotard [STMPE_IDX_ICR_LSB] = STMPE1600_REG_SYS_CTRL, 6216bb9f0d9SPatrice Chotard [STMPE_IDX_GPMR_LSB] = STMPE1600_REG_GPMR_LSB, 6226bb9f0d9SPatrice Chotard [STMPE_IDX_GPMR_CSB] = STMPE1600_REG_GPMR_MSB, 6236bb9f0d9SPatrice Chotard [STMPE_IDX_GPSR_LSB] = STMPE1600_REG_GPSR_LSB, 6246bb9f0d9SPatrice Chotard [STMPE_IDX_GPSR_CSB] = STMPE1600_REG_GPSR_MSB, 625b97eef5dSHugues Fruchet [STMPE_IDX_GPCR_LSB] = STMPE1600_REG_GPSR_LSB, 626b97eef5dSHugues Fruchet [STMPE_IDX_GPCR_CSB] = STMPE1600_REG_GPSR_MSB, 6276bb9f0d9SPatrice Chotard [STMPE_IDX_GPDR_LSB] = STMPE1600_REG_GPDR_LSB, 6286bb9f0d9SPatrice Chotard [STMPE_IDX_GPDR_CSB] = STMPE1600_REG_GPDR_MSB, 6296bb9f0d9SPatrice Chotard [STMPE_IDX_IEGPIOR_LSB] = STMPE1600_REG_IEGPIOR_LSB, 6306bb9f0d9SPatrice Chotard [STMPE_IDX_IEGPIOR_CSB] = STMPE1600_REG_IEGPIOR_MSB, 6316bb9f0d9SPatrice Chotard [STMPE_IDX_ISGPIOR_LSB] = STMPE1600_REG_ISGPIOR_LSB, 6326bb9f0d9SPatrice Chotard }; 6336bb9f0d9SPatrice Chotard 6346bb9f0d9SPatrice Chotard static struct stmpe_variant_block stmpe1600_blocks[] = { 6356bb9f0d9SPatrice Chotard { 6366bb9f0d9SPatrice Chotard .cell = &stmpe_gpio_cell, 6376bb9f0d9SPatrice Chotard .irq = 0, 6386bb9f0d9SPatrice Chotard .block = STMPE_BLOCK_GPIO, 6396bb9f0d9SPatrice Chotard }, 6406bb9f0d9SPatrice Chotard }; 6416bb9f0d9SPatrice Chotard 6426bb9f0d9SPatrice Chotard static int stmpe1600_enable(struct stmpe *stmpe, unsigned int blocks, 6436bb9f0d9SPatrice Chotard bool enable) 6446bb9f0d9SPatrice Chotard { 6456bb9f0d9SPatrice Chotard if (blocks & STMPE_BLOCK_GPIO) 6466bb9f0d9SPatrice Chotard return 0; 6476bb9f0d9SPatrice Chotard else 6486bb9f0d9SPatrice Chotard return -EINVAL; 6496bb9f0d9SPatrice Chotard } 6506bb9f0d9SPatrice Chotard 6516bb9f0d9SPatrice Chotard static struct stmpe_variant_info stmpe1600 = { 6526bb9f0d9SPatrice Chotard .name = "stmpe1600", 6536bb9f0d9SPatrice Chotard .id_val = STMPE1600_ID, 6546bb9f0d9SPatrice Chotard .id_mask = 0xffff, 6556bb9f0d9SPatrice Chotard .num_gpios = 16, 6566bb9f0d9SPatrice Chotard .af_bits = 0, 6576bb9f0d9SPatrice Chotard .regs = stmpe1600_regs, 6586bb9f0d9SPatrice Chotard .blocks = stmpe1600_blocks, 6596bb9f0d9SPatrice Chotard .num_blocks = ARRAY_SIZE(stmpe1600_blocks), 6606bb9f0d9SPatrice Chotard .num_irqs = STMPE1600_NR_INTERNAL_IRQS, 6616bb9f0d9SPatrice Chotard .enable = stmpe1600_enable, 6626bb9f0d9SPatrice Chotard }; 6636bb9f0d9SPatrice Chotard 6646bb9f0d9SPatrice Chotard /* 66527e34995SRabin Vincent * STMPE1601 66627e34995SRabin Vincent */ 66727e34995SRabin Vincent 66827e34995SRabin Vincent static const u8 stmpe1601_regs[] = { 66927e34995SRabin Vincent [STMPE_IDX_CHIP_ID] = STMPE1601_REG_CHIP_ID, 6700f4be8cfSPatrice Chotard [STMPE_IDX_SYS_CTRL] = STMPE1601_REG_SYS_CTRL, 6710f4be8cfSPatrice Chotard [STMPE_IDX_SYS_CTRL2] = STMPE1601_REG_SYS_CTRL2, 67227e34995SRabin Vincent [STMPE_IDX_ICR_LSB] = STMPE1601_REG_ICR_LSB, 673897ac667SPatrice Chotard [STMPE_IDX_IER_MSB] = STMPE1601_REG_IER_MSB, 67427e34995SRabin Vincent [STMPE_IDX_IER_LSB] = STMPE1601_REG_IER_LSB, 67527e34995SRabin Vincent [STMPE_IDX_ISR_MSB] = STMPE1601_REG_ISR_MSB, 67627e34995SRabin Vincent [STMPE_IDX_GPMR_LSB] = STMPE1601_REG_GPIO_MP_LSB, 677897ac667SPatrice Chotard [STMPE_IDX_GPMR_CSB] = STMPE1601_REG_GPIO_MP_MSB, 67827e34995SRabin Vincent [STMPE_IDX_GPSR_LSB] = STMPE1601_REG_GPIO_SET_LSB, 679897ac667SPatrice Chotard [STMPE_IDX_GPSR_CSB] = STMPE1601_REG_GPIO_SET_MSB, 68027e34995SRabin Vincent [STMPE_IDX_GPCR_LSB] = STMPE1601_REG_GPIO_CLR_LSB, 681897ac667SPatrice Chotard [STMPE_IDX_GPCR_CSB] = STMPE1601_REG_GPIO_CLR_MSB, 68227e34995SRabin Vincent [STMPE_IDX_GPDR_LSB] = STMPE1601_REG_GPIO_SET_DIR_LSB, 683897ac667SPatrice Chotard [STMPE_IDX_GPDR_CSB] = STMPE1601_REG_GPIO_SET_DIR_MSB, 684897ac667SPatrice Chotard [STMPE_IDX_GPEDR_LSB] = STMPE1601_REG_GPIO_ED_LSB, 685897ac667SPatrice Chotard [STMPE_IDX_GPEDR_CSB] = STMPE1601_REG_GPIO_ED_MSB, 68627e34995SRabin Vincent [STMPE_IDX_GPRER_LSB] = STMPE1601_REG_GPIO_RE_LSB, 687897ac667SPatrice Chotard [STMPE_IDX_GPRER_CSB] = STMPE1601_REG_GPIO_RE_MSB, 68827e34995SRabin Vincent [STMPE_IDX_GPFER_LSB] = STMPE1601_REG_GPIO_FE_LSB, 689897ac667SPatrice Chotard [STMPE_IDX_GPFER_CSB] = STMPE1601_REG_GPIO_FE_MSB, 69080e1dd82SLinus Walleij [STMPE_IDX_GPPUR_LSB] = STMPE1601_REG_GPIO_PU_LSB, 69127e34995SRabin Vincent [STMPE_IDX_GPAFR_U_MSB] = STMPE1601_REG_GPIO_AF_U_MSB, 69227e34995SRabin Vincent [STMPE_IDX_IEGPIOR_LSB] = STMPE1601_REG_INT_EN_GPIO_MASK_LSB, 693897ac667SPatrice Chotard [STMPE_IDX_IEGPIOR_CSB] = STMPE1601_REG_INT_EN_GPIO_MASK_MSB, 69427e34995SRabin Vincent [STMPE_IDX_ISGPIOR_MSB] = STMPE1601_REG_INT_STA_GPIO_MSB, 69527e34995SRabin Vincent }; 69627e34995SRabin Vincent 69727e34995SRabin Vincent static struct stmpe_variant_block stmpe1601_blocks[] = { 69827e34995SRabin Vincent { 69927e34995SRabin Vincent .cell = &stmpe_gpio_cell, 7005204e51dSLee Jones .irq = STMPE1601_IRQ_GPIOC, 70127e34995SRabin Vincent .block = STMPE_BLOCK_GPIO, 70227e34995SRabin Vincent }, 70327e34995SRabin Vincent { 70427e34995SRabin Vincent .cell = &stmpe_keypad_cell, 7055204e51dSLee Jones .irq = STMPE1601_IRQ_KEYPAD, 70627e34995SRabin Vincent .block = STMPE_BLOCK_KEYPAD, 70727e34995SRabin Vincent }, 708b273c5e0SLinus Walleij { 709b273c5e0SLinus Walleij .cell = &stmpe_pwm_cell, 710b273c5e0SLinus Walleij .irq = STMPE1601_IRQ_PWM0, 711b273c5e0SLinus Walleij .block = STMPE_BLOCK_PWM, 712b273c5e0SLinus Walleij }, 71327e34995SRabin Vincent }; 71427e34995SRabin Vincent 7155981f4e6SSundar R Iyer /* supported autosleep timeout delay (in msecs) */ 7165981f4e6SSundar R Iyer static const int stmpe_autosleep_delay[] = { 7175981f4e6SSundar R Iyer 4, 16, 32, 64, 128, 256, 512, 1024, 7185981f4e6SSundar R Iyer }; 7195981f4e6SSundar R Iyer 7205981f4e6SSundar R Iyer static int stmpe_round_timeout(int timeout) 7215981f4e6SSundar R Iyer { 7225981f4e6SSundar R Iyer int i; 7235981f4e6SSundar R Iyer 7245981f4e6SSundar R Iyer for (i = 0; i < ARRAY_SIZE(stmpe_autosleep_delay); i++) { 7255981f4e6SSundar R Iyer if (stmpe_autosleep_delay[i] >= timeout) 7265981f4e6SSundar R Iyer return i; 7275981f4e6SSundar R Iyer } 7285981f4e6SSundar R Iyer 7295981f4e6SSundar R Iyer /* 7305981f4e6SSundar R Iyer * requests for delays longer than supported should not return the 7315981f4e6SSundar R Iyer * longest supported delay 7325981f4e6SSundar R Iyer */ 7335981f4e6SSundar R Iyer return -EINVAL; 7345981f4e6SSundar R Iyer } 7355981f4e6SSundar R Iyer 7365981f4e6SSundar R Iyer static int stmpe_autosleep(struct stmpe *stmpe, int autosleep_timeout) 7375981f4e6SSundar R Iyer { 7385981f4e6SSundar R Iyer int ret; 7395981f4e6SSundar R Iyer 7405981f4e6SSundar R Iyer if (!stmpe->variant->enable_autosleep) 7415981f4e6SSundar R Iyer return -ENOSYS; 7425981f4e6SSundar R Iyer 7435981f4e6SSundar R Iyer mutex_lock(&stmpe->lock); 7445981f4e6SSundar R Iyer ret = stmpe->variant->enable_autosleep(stmpe, autosleep_timeout); 7455981f4e6SSundar R Iyer mutex_unlock(&stmpe->lock); 7465981f4e6SSundar R Iyer 7475981f4e6SSundar R Iyer return ret; 7485981f4e6SSundar R Iyer } 7495981f4e6SSundar R Iyer 7505981f4e6SSundar R Iyer /* 7515981f4e6SSundar R Iyer * Both stmpe 1601/2403 support same layout for autosleep 7525981f4e6SSundar R Iyer */ 7535981f4e6SSundar R Iyer static int stmpe1601_autosleep(struct stmpe *stmpe, 7545981f4e6SSundar R Iyer int autosleep_timeout) 7555981f4e6SSundar R Iyer { 7565981f4e6SSundar R Iyer int ret, timeout; 7575981f4e6SSundar R Iyer 7585981f4e6SSundar R Iyer /* choose the best available timeout */ 7595981f4e6SSundar R Iyer timeout = stmpe_round_timeout(autosleep_timeout); 7605981f4e6SSundar R Iyer if (timeout < 0) { 7615981f4e6SSundar R Iyer dev_err(stmpe->dev, "invalid timeout\n"); 7625981f4e6SSundar R Iyer return timeout; 7635981f4e6SSundar R Iyer } 7645981f4e6SSundar R Iyer 7650f4be8cfSPatrice Chotard ret = __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2], 7665981f4e6SSundar R Iyer STMPE1601_AUTOSLEEP_TIMEOUT_MASK, 7675981f4e6SSundar R Iyer timeout); 7685981f4e6SSundar R Iyer if (ret < 0) 7695981f4e6SSundar R Iyer return ret; 7705981f4e6SSundar R Iyer 7710f4be8cfSPatrice Chotard return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2], 7725981f4e6SSundar R Iyer STPME1601_AUTOSLEEP_ENABLE, 7735981f4e6SSundar R Iyer STPME1601_AUTOSLEEP_ENABLE); 7745981f4e6SSundar R Iyer } 7755981f4e6SSundar R Iyer 77627e34995SRabin Vincent static int stmpe1601_enable(struct stmpe *stmpe, unsigned int blocks, 77727e34995SRabin Vincent bool enable) 77827e34995SRabin Vincent { 77927e34995SRabin Vincent unsigned int mask = 0; 78027e34995SRabin Vincent 78127e34995SRabin Vincent if (blocks & STMPE_BLOCK_GPIO) 78227e34995SRabin Vincent mask |= STMPE1601_SYS_CTRL_ENABLE_GPIO; 783b69d2ad6SLinus Walleij else 784b69d2ad6SLinus Walleij mask &= ~STMPE1601_SYS_CTRL_ENABLE_GPIO; 78527e34995SRabin Vincent 78627e34995SRabin Vincent if (blocks & STMPE_BLOCK_KEYPAD) 78727e34995SRabin Vincent mask |= STMPE1601_SYS_CTRL_ENABLE_KPC; 788b69d2ad6SLinus Walleij else 789b69d2ad6SLinus Walleij mask &= ~STMPE1601_SYS_CTRL_ENABLE_KPC; 790b69d2ad6SLinus Walleij 791b69d2ad6SLinus Walleij if (blocks & STMPE_BLOCK_PWM) 792b69d2ad6SLinus Walleij mask |= STMPE1601_SYS_CTRL_ENABLE_SPWM; 793b69d2ad6SLinus Walleij else 794b69d2ad6SLinus Walleij mask &= ~STMPE1601_SYS_CTRL_ENABLE_SPWM; 79527e34995SRabin Vincent 7960f4be8cfSPatrice Chotard return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], mask, 79727e34995SRabin Vincent enable ? mask : 0); 79827e34995SRabin Vincent } 79927e34995SRabin Vincent 80027e34995SRabin Vincent static int stmpe1601_get_altfunc(struct stmpe *stmpe, enum stmpe_block block) 80127e34995SRabin Vincent { 80227e34995SRabin Vincent switch (block) { 80327e34995SRabin Vincent case STMPE_BLOCK_PWM: 80427e34995SRabin Vincent return 2; 80527e34995SRabin Vincent 80627e34995SRabin Vincent case STMPE_BLOCK_KEYPAD: 80727e34995SRabin Vincent return 1; 80827e34995SRabin Vincent 80927e34995SRabin Vincent case STMPE_BLOCK_GPIO: 81027e34995SRabin Vincent default: 81127e34995SRabin Vincent return 0; 81227e34995SRabin Vincent } 81327e34995SRabin Vincent } 81427e34995SRabin Vincent 81527e34995SRabin Vincent static struct stmpe_variant_info stmpe1601 = { 81627e34995SRabin Vincent .name = "stmpe1601", 81727e34995SRabin Vincent .id_val = 0x0210, 81827e34995SRabin Vincent .id_mask = 0xfff0, /* at least 0x0210 and 0x0212 */ 81927e34995SRabin Vincent .num_gpios = 16, 82027e34995SRabin Vincent .af_bits = 2, 82127e34995SRabin Vincent .regs = stmpe1601_regs, 82227e34995SRabin Vincent .blocks = stmpe1601_blocks, 82327e34995SRabin Vincent .num_blocks = ARRAY_SIZE(stmpe1601_blocks), 82427e34995SRabin Vincent .num_irqs = STMPE1601_NR_INTERNAL_IRQS, 82527e34995SRabin Vincent .enable = stmpe1601_enable, 82627e34995SRabin Vincent .get_altfunc = stmpe1601_get_altfunc, 8275981f4e6SSundar R Iyer .enable_autosleep = stmpe1601_autosleep, 82827e34995SRabin Vincent }; 82927e34995SRabin Vincent 83027e34995SRabin Vincent /* 831230f13a5SJean-Nicolas Graux * STMPE1801 832230f13a5SJean-Nicolas Graux */ 833230f13a5SJean-Nicolas Graux static const u8 stmpe1801_regs[] = { 834230f13a5SJean-Nicolas Graux [STMPE_IDX_CHIP_ID] = STMPE1801_REG_CHIP_ID, 8350f4be8cfSPatrice Chotard [STMPE_IDX_SYS_CTRL] = STMPE1801_REG_SYS_CTRL, 836230f13a5SJean-Nicolas Graux [STMPE_IDX_ICR_LSB] = STMPE1801_REG_INT_CTRL_LOW, 837230f13a5SJean-Nicolas Graux [STMPE_IDX_IER_LSB] = STMPE1801_REG_INT_EN_MASK_LOW, 838230f13a5SJean-Nicolas Graux [STMPE_IDX_ISR_LSB] = STMPE1801_REG_INT_STA_LOW, 839230f13a5SJean-Nicolas Graux [STMPE_IDX_GPMR_LSB] = STMPE1801_REG_GPIO_MP_LOW, 840897ac667SPatrice Chotard [STMPE_IDX_GPMR_CSB] = STMPE1801_REG_GPIO_MP_MID, 841897ac667SPatrice Chotard [STMPE_IDX_GPMR_MSB] = STMPE1801_REG_GPIO_MP_HIGH, 842230f13a5SJean-Nicolas Graux [STMPE_IDX_GPSR_LSB] = STMPE1801_REG_GPIO_SET_LOW, 843897ac667SPatrice Chotard [STMPE_IDX_GPSR_CSB] = STMPE1801_REG_GPIO_SET_MID, 844897ac667SPatrice Chotard [STMPE_IDX_GPSR_MSB] = STMPE1801_REG_GPIO_SET_HIGH, 845230f13a5SJean-Nicolas Graux [STMPE_IDX_GPCR_LSB] = STMPE1801_REG_GPIO_CLR_LOW, 846897ac667SPatrice Chotard [STMPE_IDX_GPCR_CSB] = STMPE1801_REG_GPIO_CLR_MID, 847897ac667SPatrice Chotard [STMPE_IDX_GPCR_MSB] = STMPE1801_REG_GPIO_CLR_HIGH, 848230f13a5SJean-Nicolas Graux [STMPE_IDX_GPDR_LSB] = STMPE1801_REG_GPIO_SET_DIR_LOW, 849897ac667SPatrice Chotard [STMPE_IDX_GPDR_CSB] = STMPE1801_REG_GPIO_SET_DIR_MID, 850897ac667SPatrice Chotard [STMPE_IDX_GPDR_MSB] = STMPE1801_REG_GPIO_SET_DIR_HIGH, 851230f13a5SJean-Nicolas Graux [STMPE_IDX_GPRER_LSB] = STMPE1801_REG_GPIO_RE_LOW, 852897ac667SPatrice Chotard [STMPE_IDX_GPRER_CSB] = STMPE1801_REG_GPIO_RE_MID, 853897ac667SPatrice Chotard [STMPE_IDX_GPRER_MSB] = STMPE1801_REG_GPIO_RE_HIGH, 854230f13a5SJean-Nicolas Graux [STMPE_IDX_GPFER_LSB] = STMPE1801_REG_GPIO_FE_LOW, 855897ac667SPatrice Chotard [STMPE_IDX_GPFER_CSB] = STMPE1801_REG_GPIO_FE_MID, 856897ac667SPatrice Chotard [STMPE_IDX_GPFER_MSB] = STMPE1801_REG_GPIO_FE_HIGH, 85780e1dd82SLinus Walleij [STMPE_IDX_GPPUR_LSB] = STMPE1801_REG_GPIO_PULL_UP_LOW, 858230f13a5SJean-Nicolas Graux [STMPE_IDX_IEGPIOR_LSB] = STMPE1801_REG_INT_EN_GPIO_MASK_LOW, 859897ac667SPatrice Chotard [STMPE_IDX_IEGPIOR_CSB] = STMPE1801_REG_INT_EN_GPIO_MASK_MID, 860897ac667SPatrice Chotard [STMPE_IDX_IEGPIOR_MSB] = STMPE1801_REG_INT_EN_GPIO_MASK_HIGH, 861897ac667SPatrice Chotard [STMPE_IDX_ISGPIOR_MSB] = STMPE1801_REG_INT_STA_GPIO_HIGH, 862230f13a5SJean-Nicolas Graux }; 863230f13a5SJean-Nicolas Graux 864230f13a5SJean-Nicolas Graux static struct stmpe_variant_block stmpe1801_blocks[] = { 865230f13a5SJean-Nicolas Graux { 866230f13a5SJean-Nicolas Graux .cell = &stmpe_gpio_cell, 867230f13a5SJean-Nicolas Graux .irq = STMPE1801_IRQ_GPIOC, 868230f13a5SJean-Nicolas Graux .block = STMPE_BLOCK_GPIO, 869230f13a5SJean-Nicolas Graux }, 870230f13a5SJean-Nicolas Graux { 871230f13a5SJean-Nicolas Graux .cell = &stmpe_keypad_cell, 872230f13a5SJean-Nicolas Graux .irq = STMPE1801_IRQ_KEYPAD, 873230f13a5SJean-Nicolas Graux .block = STMPE_BLOCK_KEYPAD, 874230f13a5SJean-Nicolas Graux }, 875230f13a5SJean-Nicolas Graux }; 876230f13a5SJean-Nicolas Graux 877230f13a5SJean-Nicolas Graux static int stmpe1801_enable(struct stmpe *stmpe, unsigned int blocks, 878230f13a5SJean-Nicolas Graux bool enable) 879230f13a5SJean-Nicolas Graux { 880230f13a5SJean-Nicolas Graux unsigned int mask = 0; 881230f13a5SJean-Nicolas Graux if (blocks & STMPE_BLOCK_GPIO) 882230f13a5SJean-Nicolas Graux mask |= STMPE1801_MSK_INT_EN_GPIO; 883230f13a5SJean-Nicolas Graux 884230f13a5SJean-Nicolas Graux if (blocks & STMPE_BLOCK_KEYPAD) 885230f13a5SJean-Nicolas Graux mask |= STMPE1801_MSK_INT_EN_KPC; 886230f13a5SJean-Nicolas Graux 887230f13a5SJean-Nicolas Graux return __stmpe_set_bits(stmpe, STMPE1801_REG_INT_EN_MASK_LOW, mask, 888230f13a5SJean-Nicolas Graux enable ? mask : 0); 889230f13a5SJean-Nicolas Graux } 890230f13a5SJean-Nicolas Graux 891c4dd1ba3SPatrice Chotard static int stmpe_reset(struct stmpe *stmpe) 892230f13a5SJean-Nicolas Graux { 893c4dd1ba3SPatrice Chotard u16 id_val = stmpe->variant->id_val; 894230f13a5SJean-Nicolas Graux unsigned long timeout; 895230f13a5SJean-Nicolas Graux int ret = 0; 896c4dd1ba3SPatrice Chotard u8 reset_bit; 897c4dd1ba3SPatrice Chotard 898c4dd1ba3SPatrice Chotard if (id_val == STMPE811_ID) 899c4dd1ba3SPatrice Chotard /* STMPE801 and STMPE610 use bit 1 of SYS_CTRL register */ 900c4dd1ba3SPatrice Chotard reset_bit = STMPE811_SYS_CTRL_RESET; 901c4dd1ba3SPatrice Chotard else 902c4dd1ba3SPatrice Chotard /* all other STMPE variant use bit 7 of SYS_CTRL register */ 903c4dd1ba3SPatrice Chotard reset_bit = STMPE_SYS_CTRL_RESET; 904230f13a5SJean-Nicolas Graux 9050f4be8cfSPatrice Chotard ret = __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], 906c4dd1ba3SPatrice Chotard reset_bit, reset_bit); 907230f13a5SJean-Nicolas Graux if (ret < 0) 908230f13a5SJean-Nicolas Graux return ret; 909230f13a5SJean-Nicolas Graux 910f4058420SLinus Walleij msleep(10); 911f4058420SLinus Walleij 912230f13a5SJean-Nicolas Graux timeout = jiffies + msecs_to_jiffies(100); 913230f13a5SJean-Nicolas Graux while (time_before(jiffies, timeout)) { 9140f4be8cfSPatrice Chotard ret = __stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL]); 915230f13a5SJean-Nicolas Graux if (ret < 0) 916230f13a5SJean-Nicolas Graux return ret; 917c4dd1ba3SPatrice Chotard if (!(ret & reset_bit)) 918230f13a5SJean-Nicolas Graux return 0; 919230f13a5SJean-Nicolas Graux usleep_range(100, 200); 92052397fe1SSachin Kamat } 921230f13a5SJean-Nicolas Graux return -EIO; 922230f13a5SJean-Nicolas Graux } 923230f13a5SJean-Nicolas Graux 924230f13a5SJean-Nicolas Graux static struct stmpe_variant_info stmpe1801 = { 925230f13a5SJean-Nicolas Graux .name = "stmpe1801", 926230f13a5SJean-Nicolas Graux .id_val = STMPE1801_ID, 927230f13a5SJean-Nicolas Graux .id_mask = 0xfff0, 928230f13a5SJean-Nicolas Graux .num_gpios = 18, 929230f13a5SJean-Nicolas Graux .af_bits = 0, 930230f13a5SJean-Nicolas Graux .regs = stmpe1801_regs, 931230f13a5SJean-Nicolas Graux .blocks = stmpe1801_blocks, 932230f13a5SJean-Nicolas Graux .num_blocks = ARRAY_SIZE(stmpe1801_blocks), 933230f13a5SJean-Nicolas Graux .num_irqs = STMPE1801_NR_INTERNAL_IRQS, 934230f13a5SJean-Nicolas Graux .enable = stmpe1801_enable, 935230f13a5SJean-Nicolas Graux /* stmpe1801 do not have any gpio alternate function */ 936230f13a5SJean-Nicolas Graux .get_altfunc = NULL, 937230f13a5SJean-Nicolas Graux }; 938230f13a5SJean-Nicolas Graux 939230f13a5SJean-Nicolas Graux /* 94027e34995SRabin Vincent * STMPE24XX 94127e34995SRabin Vincent */ 94227e34995SRabin Vincent 94327e34995SRabin Vincent static const u8 stmpe24xx_regs[] = { 94427e34995SRabin Vincent [STMPE_IDX_CHIP_ID] = STMPE24XX_REG_CHIP_ID, 9450f4be8cfSPatrice Chotard [STMPE_IDX_SYS_CTRL] = STMPE24XX_REG_SYS_CTRL, 9460f4be8cfSPatrice Chotard [STMPE_IDX_SYS_CTRL2] = STMPE24XX_REG_SYS_CTRL2, 94727e34995SRabin Vincent [STMPE_IDX_ICR_LSB] = STMPE24XX_REG_ICR_LSB, 948897ac667SPatrice Chotard [STMPE_IDX_IER_MSB] = STMPE24XX_REG_IER_MSB, 94927e34995SRabin Vincent [STMPE_IDX_IER_LSB] = STMPE24XX_REG_IER_LSB, 95027e34995SRabin Vincent [STMPE_IDX_ISR_MSB] = STMPE24XX_REG_ISR_MSB, 95127e34995SRabin Vincent [STMPE_IDX_GPMR_LSB] = STMPE24XX_REG_GPMR_LSB, 952897ac667SPatrice Chotard [STMPE_IDX_GPMR_CSB] = STMPE24XX_REG_GPMR_CSB, 953897ac667SPatrice Chotard [STMPE_IDX_GPMR_MSB] = STMPE24XX_REG_GPMR_MSB, 95427e34995SRabin Vincent [STMPE_IDX_GPSR_LSB] = STMPE24XX_REG_GPSR_LSB, 955897ac667SPatrice Chotard [STMPE_IDX_GPSR_CSB] = STMPE24XX_REG_GPSR_CSB, 956897ac667SPatrice Chotard [STMPE_IDX_GPSR_MSB] = STMPE24XX_REG_GPSR_MSB, 95727e34995SRabin Vincent [STMPE_IDX_GPCR_LSB] = STMPE24XX_REG_GPCR_LSB, 958897ac667SPatrice Chotard [STMPE_IDX_GPCR_CSB] = STMPE24XX_REG_GPCR_CSB, 959897ac667SPatrice Chotard [STMPE_IDX_GPCR_MSB] = STMPE24XX_REG_GPCR_MSB, 96027e34995SRabin Vincent [STMPE_IDX_GPDR_LSB] = STMPE24XX_REG_GPDR_LSB, 961897ac667SPatrice Chotard [STMPE_IDX_GPDR_CSB] = STMPE24XX_REG_GPDR_CSB, 962897ac667SPatrice Chotard [STMPE_IDX_GPDR_MSB] = STMPE24XX_REG_GPDR_MSB, 96327e34995SRabin Vincent [STMPE_IDX_GPRER_LSB] = STMPE24XX_REG_GPRER_LSB, 964897ac667SPatrice Chotard [STMPE_IDX_GPRER_CSB] = STMPE24XX_REG_GPRER_CSB, 965897ac667SPatrice Chotard [STMPE_IDX_GPRER_MSB] = STMPE24XX_REG_GPRER_MSB, 96627e34995SRabin Vincent [STMPE_IDX_GPFER_LSB] = STMPE24XX_REG_GPFER_LSB, 967897ac667SPatrice Chotard [STMPE_IDX_GPFER_CSB] = STMPE24XX_REG_GPFER_CSB, 968897ac667SPatrice Chotard [STMPE_IDX_GPFER_MSB] = STMPE24XX_REG_GPFER_MSB, 96980e1dd82SLinus Walleij [STMPE_IDX_GPPUR_LSB] = STMPE24XX_REG_GPPUR_LSB, 97080e1dd82SLinus Walleij [STMPE_IDX_GPPDR_LSB] = STMPE24XX_REG_GPPDR_LSB, 97127e34995SRabin Vincent [STMPE_IDX_GPAFR_U_MSB] = STMPE24XX_REG_GPAFR_U_MSB, 97227e34995SRabin Vincent [STMPE_IDX_IEGPIOR_LSB] = STMPE24XX_REG_IEGPIOR_LSB, 973897ac667SPatrice Chotard [STMPE_IDX_IEGPIOR_CSB] = STMPE24XX_REG_IEGPIOR_CSB, 974897ac667SPatrice Chotard [STMPE_IDX_IEGPIOR_MSB] = STMPE24XX_REG_IEGPIOR_MSB, 97527e34995SRabin Vincent [STMPE_IDX_ISGPIOR_MSB] = STMPE24XX_REG_ISGPIOR_MSB, 976897ac667SPatrice Chotard [STMPE_IDX_GPEDR_LSB] = STMPE24XX_REG_GPEDR_LSB, 977897ac667SPatrice Chotard [STMPE_IDX_GPEDR_CSB] = STMPE24XX_REG_GPEDR_CSB, 97827e34995SRabin Vincent [STMPE_IDX_GPEDR_MSB] = STMPE24XX_REG_GPEDR_MSB, 97927e34995SRabin Vincent }; 98027e34995SRabin Vincent 98127e34995SRabin Vincent static struct stmpe_variant_block stmpe24xx_blocks[] = { 98227e34995SRabin Vincent { 98327e34995SRabin Vincent .cell = &stmpe_gpio_cell, 98427e34995SRabin Vincent .irq = STMPE24XX_IRQ_GPIOC, 98527e34995SRabin Vincent .block = STMPE_BLOCK_GPIO, 98627e34995SRabin Vincent }, 98727e34995SRabin Vincent { 98827e34995SRabin Vincent .cell = &stmpe_keypad_cell, 98927e34995SRabin Vincent .irq = STMPE24XX_IRQ_KEYPAD, 99027e34995SRabin Vincent .block = STMPE_BLOCK_KEYPAD, 99127e34995SRabin Vincent }, 992b273c5e0SLinus Walleij { 993b273c5e0SLinus Walleij .cell = &stmpe_pwm_cell, 994b273c5e0SLinus Walleij .irq = STMPE24XX_IRQ_PWM0, 995b273c5e0SLinus Walleij .block = STMPE_BLOCK_PWM, 996b273c5e0SLinus Walleij }, 99727e34995SRabin Vincent }; 99827e34995SRabin Vincent 99927e34995SRabin Vincent static int stmpe24xx_enable(struct stmpe *stmpe, unsigned int blocks, 100027e34995SRabin Vincent bool enable) 100127e34995SRabin Vincent { 100227e34995SRabin Vincent unsigned int mask = 0; 100327e34995SRabin Vincent 100427e34995SRabin Vincent if (blocks & STMPE_BLOCK_GPIO) 100527e34995SRabin Vincent mask |= STMPE24XX_SYS_CTRL_ENABLE_GPIO; 100627e34995SRabin Vincent 100727e34995SRabin Vincent if (blocks & STMPE_BLOCK_KEYPAD) 100827e34995SRabin Vincent mask |= STMPE24XX_SYS_CTRL_ENABLE_KPC; 100927e34995SRabin Vincent 10100f4be8cfSPatrice Chotard return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], mask, 101127e34995SRabin Vincent enable ? mask : 0); 101227e34995SRabin Vincent } 101327e34995SRabin Vincent 101427e34995SRabin Vincent static int stmpe24xx_get_altfunc(struct stmpe *stmpe, enum stmpe_block block) 101527e34995SRabin Vincent { 101627e34995SRabin Vincent switch (block) { 101727e34995SRabin Vincent case STMPE_BLOCK_ROTATOR: 101827e34995SRabin Vincent return 2; 101927e34995SRabin Vincent 102027e34995SRabin Vincent case STMPE_BLOCK_KEYPAD: 1021f6d10341SLinus Walleij case STMPE_BLOCK_PWM: 102227e34995SRabin Vincent return 1; 102327e34995SRabin Vincent 102427e34995SRabin Vincent case STMPE_BLOCK_GPIO: 102527e34995SRabin Vincent default: 102627e34995SRabin Vincent return 0; 102727e34995SRabin Vincent } 102827e34995SRabin Vincent } 102927e34995SRabin Vincent 103027e34995SRabin Vincent static struct stmpe_variant_info stmpe2401 = { 103127e34995SRabin Vincent .name = "stmpe2401", 103227e34995SRabin Vincent .id_val = 0x0101, 103327e34995SRabin Vincent .id_mask = 0xffff, 103427e34995SRabin Vincent .num_gpios = 24, 103527e34995SRabin Vincent .af_bits = 2, 103627e34995SRabin Vincent .regs = stmpe24xx_regs, 103727e34995SRabin Vincent .blocks = stmpe24xx_blocks, 103827e34995SRabin Vincent .num_blocks = ARRAY_SIZE(stmpe24xx_blocks), 103927e34995SRabin Vincent .num_irqs = STMPE24XX_NR_INTERNAL_IRQS, 104027e34995SRabin Vincent .enable = stmpe24xx_enable, 104127e34995SRabin Vincent .get_altfunc = stmpe24xx_get_altfunc, 104227e34995SRabin Vincent }; 104327e34995SRabin Vincent 104427e34995SRabin Vincent static struct stmpe_variant_info stmpe2403 = { 104527e34995SRabin Vincent .name = "stmpe2403", 104627e34995SRabin Vincent .id_val = 0x0120, 104727e34995SRabin Vincent .id_mask = 0xffff, 104827e34995SRabin Vincent .num_gpios = 24, 104927e34995SRabin Vincent .af_bits = 2, 105027e34995SRabin Vincent .regs = stmpe24xx_regs, 105127e34995SRabin Vincent .blocks = stmpe24xx_blocks, 105227e34995SRabin Vincent .num_blocks = ARRAY_SIZE(stmpe24xx_blocks), 105327e34995SRabin Vincent .num_irqs = STMPE24XX_NR_INTERNAL_IRQS, 105427e34995SRabin Vincent .enable = stmpe24xx_enable, 105527e34995SRabin Vincent .get_altfunc = stmpe24xx_get_altfunc, 10565981f4e6SSundar R Iyer .enable_autosleep = stmpe1601_autosleep, /* same as stmpe1601 */ 105727e34995SRabin Vincent }; 105827e34995SRabin Vincent 1059e31f9b82SChris Blair static struct stmpe_variant_info *stmpe_variant_info[STMPE_NBR_PARTS] = { 10601cda2394SViresh Kumar [STMPE610] = &stmpe610, 10617f7f4ea1SViresh Kumar [STMPE801] = &stmpe801, 106227e34995SRabin Vincent [STMPE811] = &stmpe811, 10636bb9f0d9SPatrice Chotard [STMPE1600] = &stmpe1600, 106427e34995SRabin Vincent [STMPE1601] = &stmpe1601, 1065230f13a5SJean-Nicolas Graux [STMPE1801] = &stmpe1801, 106627e34995SRabin Vincent [STMPE2401] = &stmpe2401, 106727e34995SRabin Vincent [STMPE2403] = &stmpe2403, 106827e34995SRabin Vincent }; 106927e34995SRabin Vincent 1070e31f9b82SChris Blair /* 1071e31f9b82SChris Blair * These devices can be connected in a 'no-irq' configuration - the irq pin 1072e31f9b82SChris Blair * is not used and the device cannot interrupt the CPU. Here we only list 1073e31f9b82SChris Blair * devices which support this configuration - the driver will fail probing 1074e31f9b82SChris Blair * for any devices not listed here which are configured in this way. 1075e31f9b82SChris Blair */ 1076e31f9b82SChris Blair static struct stmpe_variant_info *stmpe_noirq_variant_info[STMPE_NBR_PARTS] = { 1077e31f9b82SChris Blair [STMPE801] = &stmpe801_noirq, 1078e31f9b82SChris Blair }; 1079e31f9b82SChris Blair 108027e34995SRabin Vincent static irqreturn_t stmpe_irq(int irq, void *data) 108127e34995SRabin Vincent { 108227e34995SRabin Vincent struct stmpe *stmpe = data; 108327e34995SRabin Vincent struct stmpe_variant_info *variant = stmpe->variant; 108427e34995SRabin Vincent int num = DIV_ROUND_UP(variant->num_irqs, 8); 1085230f13a5SJean-Nicolas Graux u8 israddr; 10867929fa77SLee Jones u8 isr[3]; 108727e34995SRabin Vincent int ret; 108827e34995SRabin Vincent int i; 108927e34995SRabin Vincent 10906bb9f0d9SPatrice Chotard if (variant->id_val == STMPE801_ID || 10916bb9f0d9SPatrice Chotard variant->id_val == STMPE1600_ID) { 10929ff80e2dSMarc Zyngier int base = irq_find_mapping(stmpe->domain, 0); 109376f93992SLee Jones 109476f93992SLee Jones handle_nested_irq(base); 10957f7f4ea1SViresh Kumar return IRQ_HANDLED; 10967f7f4ea1SViresh Kumar } 10977f7f4ea1SViresh Kumar 1098230f13a5SJean-Nicolas Graux if (variant->id_val == STMPE1801_ID) 1099230f13a5SJean-Nicolas Graux israddr = stmpe->regs[STMPE_IDX_ISR_LSB]; 1100230f13a5SJean-Nicolas Graux else 1101230f13a5SJean-Nicolas Graux israddr = stmpe->regs[STMPE_IDX_ISR_MSB]; 1102230f13a5SJean-Nicolas Graux 110327e34995SRabin Vincent ret = stmpe_block_read(stmpe, israddr, num, isr); 110427e34995SRabin Vincent if (ret < 0) 110527e34995SRabin Vincent return IRQ_NONE; 110627e34995SRabin Vincent 110727e34995SRabin Vincent for (i = 0; i < num; i++) { 110827e34995SRabin Vincent int bank = num - i - 1; 110927e34995SRabin Vincent u8 status = isr[i]; 111027e34995SRabin Vincent u8 clear; 111127e34995SRabin Vincent 111227e34995SRabin Vincent status &= stmpe->ier[bank]; 111327e34995SRabin Vincent if (!status) 111427e34995SRabin Vincent continue; 111527e34995SRabin Vincent 111627e34995SRabin Vincent clear = status; 111727e34995SRabin Vincent while (status) { 111827e34995SRabin Vincent int bit = __ffs(status); 111927e34995SRabin Vincent int line = bank * 8 + bit; 11209ff80e2dSMarc Zyngier int nestedirq = irq_find_mapping(stmpe->domain, line); 112127e34995SRabin Vincent 112276f93992SLee Jones handle_nested_irq(nestedirq); 112327e34995SRabin Vincent status &= ~(1 << bit); 112427e34995SRabin Vincent } 112527e34995SRabin Vincent 112627e34995SRabin Vincent stmpe_reg_write(stmpe, israddr + i, clear); 112727e34995SRabin Vincent } 112827e34995SRabin Vincent 112927e34995SRabin Vincent return IRQ_HANDLED; 113027e34995SRabin Vincent } 113127e34995SRabin Vincent 113243b8c084SMark Brown static void stmpe_irq_lock(struct irq_data *data) 113327e34995SRabin Vincent { 113443b8c084SMark Brown struct stmpe *stmpe = irq_data_get_irq_chip_data(data); 113527e34995SRabin Vincent 113627e34995SRabin Vincent mutex_lock(&stmpe->irq_lock); 113727e34995SRabin Vincent } 113827e34995SRabin Vincent 113943b8c084SMark Brown static void stmpe_irq_sync_unlock(struct irq_data *data) 114027e34995SRabin Vincent { 114143b8c084SMark Brown struct stmpe *stmpe = irq_data_get_irq_chip_data(data); 114227e34995SRabin Vincent struct stmpe_variant_info *variant = stmpe->variant; 114327e34995SRabin Vincent int num = DIV_ROUND_UP(variant->num_irqs, 8); 114427e34995SRabin Vincent int i; 114527e34995SRabin Vincent 114627e34995SRabin Vincent for (i = 0; i < num; i++) { 114727e34995SRabin Vincent u8 new = stmpe->ier[i]; 114827e34995SRabin Vincent u8 old = stmpe->oldier[i]; 114927e34995SRabin Vincent 115027e34995SRabin Vincent if (new == old) 115127e34995SRabin Vincent continue; 115227e34995SRabin Vincent 115327e34995SRabin Vincent stmpe->oldier[i] = new; 1154897ac667SPatrice Chotard stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_IER_LSB + i], new); 115527e34995SRabin Vincent } 115627e34995SRabin Vincent 115727e34995SRabin Vincent mutex_unlock(&stmpe->irq_lock); 115827e34995SRabin Vincent } 115927e34995SRabin Vincent 116043b8c084SMark Brown static void stmpe_irq_mask(struct irq_data *data) 116127e34995SRabin Vincent { 116243b8c084SMark Brown struct stmpe *stmpe = irq_data_get_irq_chip_data(data); 116376f93992SLee Jones int offset = data->hwirq; 116427e34995SRabin Vincent int regoffset = offset / 8; 116527e34995SRabin Vincent int mask = 1 << (offset % 8); 116627e34995SRabin Vincent 116727e34995SRabin Vincent stmpe->ier[regoffset] &= ~mask; 116827e34995SRabin Vincent } 116927e34995SRabin Vincent 117043b8c084SMark Brown static void stmpe_irq_unmask(struct irq_data *data) 117127e34995SRabin Vincent { 117243b8c084SMark Brown struct stmpe *stmpe = irq_data_get_irq_chip_data(data); 117376f93992SLee Jones int offset = data->hwirq; 117427e34995SRabin Vincent int regoffset = offset / 8; 117527e34995SRabin Vincent int mask = 1 << (offset % 8); 117627e34995SRabin Vincent 117727e34995SRabin Vincent stmpe->ier[regoffset] |= mask; 117827e34995SRabin Vincent } 117927e34995SRabin Vincent 118027e34995SRabin Vincent static struct irq_chip stmpe_irq_chip = { 118127e34995SRabin Vincent .name = "stmpe", 118243b8c084SMark Brown .irq_bus_lock = stmpe_irq_lock, 118343b8c084SMark Brown .irq_bus_sync_unlock = stmpe_irq_sync_unlock, 118443b8c084SMark Brown .irq_mask = stmpe_irq_mask, 118543b8c084SMark Brown .irq_unmask = stmpe_irq_unmask, 118627e34995SRabin Vincent }; 118727e34995SRabin Vincent 118876f93992SLee Jones static int stmpe_irq_map(struct irq_domain *d, unsigned int virq, 118976f93992SLee Jones irq_hw_number_t hwirq) 119027e34995SRabin Vincent { 119176f93992SLee Jones struct stmpe *stmpe = d->host_data; 11927f7f4ea1SViresh Kumar struct irq_chip *chip = NULL; 119327e34995SRabin Vincent 11947f7f4ea1SViresh Kumar if (stmpe->variant->id_val != STMPE801_ID) 11957f7f4ea1SViresh Kumar chip = &stmpe_irq_chip; 11967f7f4ea1SViresh Kumar 119776f93992SLee Jones irq_set_chip_data(virq, stmpe); 119876f93992SLee Jones irq_set_chip_and_handler(virq, chip, handle_edge_irq); 119976f93992SLee Jones irq_set_nested_thread(virq, 1); 120076f93992SLee Jones irq_set_noprobe(virq); 120127e34995SRabin Vincent 120227e34995SRabin Vincent return 0; 120327e34995SRabin Vincent } 120427e34995SRabin Vincent 120576f93992SLee Jones static void stmpe_irq_unmap(struct irq_domain *d, unsigned int virq) 120627e34995SRabin Vincent { 120776f93992SLee Jones irq_set_chip_and_handler(virq, NULL, NULL); 120876f93992SLee Jones irq_set_chip_data(virq, NULL); 120927e34995SRabin Vincent } 121076f93992SLee Jones 12117ce7b26fSKrzysztof Kozlowski static const struct irq_domain_ops stmpe_irq_ops = { 121276f93992SLee Jones .map = stmpe_irq_map, 121376f93992SLee Jones .unmap = stmpe_irq_unmap, 121476f93992SLee Jones .xlate = irq_domain_xlate_twocell, 121576f93992SLee Jones }; 121676f93992SLee Jones 1217612b95cdSGreg Kroah-Hartman static int stmpe_irq_init(struct stmpe *stmpe, struct device_node *np) 121876f93992SLee Jones { 1219b20a4371SLee Jones int base = 0; 122076f93992SLee Jones int num_irqs = stmpe->variant->num_irqs; 122176f93992SLee Jones 1222b20a4371SLee Jones stmpe->domain = irq_domain_add_simple(np, num_irqs, base, 1223b20a4371SLee Jones &stmpe_irq_ops, stmpe); 122476f93992SLee Jones if (!stmpe->domain) { 122576f93992SLee Jones dev_err(stmpe->dev, "Failed to create irqdomain\n"); 122676f93992SLee Jones return -ENOSYS; 122776f93992SLee Jones } 122876f93992SLee Jones 122976f93992SLee Jones return 0; 123027e34995SRabin Vincent } 123127e34995SRabin Vincent 1232612b95cdSGreg Kroah-Hartman static int stmpe_chip_init(struct stmpe *stmpe) 123327e34995SRabin Vincent { 123427e34995SRabin Vincent unsigned int irq_trigger = stmpe->pdata->irq_trigger; 12355981f4e6SSundar R Iyer int autosleep_timeout = stmpe->pdata->autosleep_timeout; 123627e34995SRabin Vincent struct stmpe_variant_info *variant = stmpe->variant; 1237e31f9b82SChris Blair u8 icr = 0; 123827e34995SRabin Vincent unsigned int id; 123927e34995SRabin Vincent u8 data[2]; 124027e34995SRabin Vincent int ret; 124127e34995SRabin Vincent 124227e34995SRabin Vincent ret = stmpe_block_read(stmpe, stmpe->regs[STMPE_IDX_CHIP_ID], 124327e34995SRabin Vincent ARRAY_SIZE(data), data); 124427e34995SRabin Vincent if (ret < 0) 124527e34995SRabin Vincent return ret; 124627e34995SRabin Vincent 124727e34995SRabin Vincent id = (data[0] << 8) | data[1]; 124827e34995SRabin Vincent if ((id & variant->id_mask) != variant->id_val) { 124927e34995SRabin Vincent dev_err(stmpe->dev, "unknown chip id: %#x\n", id); 125027e34995SRabin Vincent return -EINVAL; 125127e34995SRabin Vincent } 125227e34995SRabin Vincent 125327e34995SRabin Vincent dev_info(stmpe->dev, "%s detected, chip id: %#x\n", variant->name, id); 125427e34995SRabin Vincent 125527e34995SRabin Vincent /* Disable all modules -- subdrivers should enable what they need. */ 125627e34995SRabin Vincent ret = stmpe_disable(stmpe, ~0); 125727e34995SRabin Vincent if (ret) 125827e34995SRabin Vincent return ret; 125927e34995SRabin Vincent 1260c4dd1ba3SPatrice Chotard ret = stmpe_reset(stmpe); 1261230f13a5SJean-Nicolas Graux if (ret < 0) 1262230f13a5SJean-Nicolas Graux return ret; 1263230f13a5SJean-Nicolas Graux 1264e31f9b82SChris Blair if (stmpe->irq >= 0) { 12656bb9f0d9SPatrice Chotard if (id == STMPE801_ID || id == STMPE1600_ID) 1266c16bee78SPatrice Chotard icr = STMPE_SYS_CTRL_INT_EN; 12677f7f4ea1SViresh Kumar else 12687f7f4ea1SViresh Kumar icr = STMPE_ICR_LSB_GIM; 12697f7f4ea1SViresh Kumar 12706bb9f0d9SPatrice Chotard /* STMPE801 and STMPE1600 don't support Edge interrupts */ 12716bb9f0d9SPatrice Chotard if (id != STMPE801_ID && id != STMPE1600_ID) { 127227e34995SRabin Vincent if (irq_trigger == IRQF_TRIGGER_FALLING || 127327e34995SRabin Vincent irq_trigger == IRQF_TRIGGER_RISING) 127427e34995SRabin Vincent icr |= STMPE_ICR_LSB_EDGE; 12757f7f4ea1SViresh Kumar } 127627e34995SRabin Vincent 127727e34995SRabin Vincent if (irq_trigger == IRQF_TRIGGER_RISING || 12787f7f4ea1SViresh Kumar irq_trigger == IRQF_TRIGGER_HIGH) { 12796bb9f0d9SPatrice Chotard if (id == STMPE801_ID || id == STMPE1600_ID) 1280c16bee78SPatrice Chotard icr |= STMPE_SYS_CTRL_INT_HI; 12817f7f4ea1SViresh Kumar else 128227e34995SRabin Vincent icr |= STMPE_ICR_LSB_HIGH; 12837f7f4ea1SViresh Kumar } 1284e31f9b82SChris Blair } 128527e34995SRabin Vincent 12865981f4e6SSundar R Iyer if (stmpe->pdata->autosleep) { 12875981f4e6SSundar R Iyer ret = stmpe_autosleep(stmpe, autosleep_timeout); 12885981f4e6SSundar R Iyer if (ret) 12895981f4e6SSundar R Iyer return ret; 12905981f4e6SSundar R Iyer } 12915981f4e6SSundar R Iyer 129227e34995SRabin Vincent return stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_ICR_LSB], icr); 129327e34995SRabin Vincent } 129427e34995SRabin Vincent 12956bbb3c4cSGeert Uytterhoeven static int stmpe_add_device(struct stmpe *stmpe, const struct mfd_cell *cell) 129627e34995SRabin Vincent { 129727e34995SRabin Vincent return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1, 12989e9dc7d9SLinus Walleij NULL, 0, stmpe->domain); 129927e34995SRabin Vincent } 130027e34995SRabin Vincent 1301612b95cdSGreg Kroah-Hartman static int stmpe_devices_init(struct stmpe *stmpe) 130227e34995SRabin Vincent { 130327e34995SRabin Vincent struct stmpe_variant_info *variant = stmpe->variant; 130427e34995SRabin Vincent unsigned int platform_blocks = stmpe->pdata->blocks; 130527e34995SRabin Vincent int ret = -EINVAL; 13067da0cbfcSLee Jones int i, j; 130727e34995SRabin Vincent 130827e34995SRabin Vincent for (i = 0; i < variant->num_blocks; i++) { 130927e34995SRabin Vincent struct stmpe_variant_block *block = &variant->blocks[i]; 131027e34995SRabin Vincent 131127e34995SRabin Vincent if (!(platform_blocks & block->block)) 131227e34995SRabin Vincent continue; 131327e34995SRabin Vincent 13147da0cbfcSLee Jones for (j = 0; j < block->cell->num_resources; j++) { 13157da0cbfcSLee Jones struct resource *res = 13167da0cbfcSLee Jones (struct resource *) &block->cell->resources[j]; 13177da0cbfcSLee Jones 13187da0cbfcSLee Jones /* Dynamically fill in a variant's IRQ. */ 13197da0cbfcSLee Jones if (res->flags & IORESOURCE_IRQ) 13207da0cbfcSLee Jones res->start = res->end = block->irq + j; 13217da0cbfcSLee Jones } 13227da0cbfcSLee Jones 132327e34995SRabin Vincent platform_blocks &= ~block->block; 13247da0cbfcSLee Jones ret = stmpe_add_device(stmpe, block->cell); 132527e34995SRabin Vincent if (ret) 132627e34995SRabin Vincent return ret; 132727e34995SRabin Vincent } 132827e34995SRabin Vincent 132927e34995SRabin Vincent if (platform_blocks) 133027e34995SRabin Vincent dev_warn(stmpe->dev, 133127e34995SRabin Vincent "platform wants blocks (%#x) not present on variant", 133227e34995SRabin Vincent platform_blocks); 133327e34995SRabin Vincent 133427e34995SRabin Vincent return ret; 133527e34995SRabin Vincent } 133627e34995SRabin Vincent 1337a9c4055dSMark Brown static void stmpe_of_probe(struct stmpe_platform_data *pdata, 1338a9c4055dSMark Brown struct device_node *np) 1339909582caSLee Jones { 1340909582caSLee Jones struct device_node *child; 1341909582caSLee Jones 1342408a3fa8SGabriel Fernandez pdata->id = of_alias_get_id(np, "stmpe-i2c"); 1343408a3fa8SGabriel Fernandez if (pdata->id < 0) 1344ac713cc9SVipul Kumar Samar pdata->id = -1; 1345408a3fa8SGabriel Fernandez 1346909582caSLee Jones of_property_read_u32(np, "st,autosleep-timeout", 1347909582caSLee Jones &pdata->autosleep_timeout); 1348909582caSLee Jones 1349909582caSLee Jones pdata->autosleep = (pdata->autosleep_timeout) ? true : false; 1350909582caSLee Jones 1351786c6f14SOleksandr Suvorov for_each_available_child_of_node(np, child) { 1352d7667f19SFrancesco Dolcini if (of_device_is_compatible(child, stmpe_gpio_cell.of_compatible)) 1353909582caSLee Jones pdata->blocks |= STMPE_BLOCK_GPIO; 1354d7667f19SFrancesco Dolcini else if (of_device_is_compatible(child, stmpe_keypad_cell.of_compatible)) 1355909582caSLee Jones pdata->blocks |= STMPE_BLOCK_KEYPAD; 1356d7667f19SFrancesco Dolcini else if (of_device_is_compatible(child, stmpe_ts_cell.of_compatible)) 1357909582caSLee Jones pdata->blocks |= STMPE_BLOCK_TOUCHSCREEN; 1358d7667f19SFrancesco Dolcini else if (of_device_is_compatible(child, stmpe_adc_cell.of_compatible)) 1359909582caSLee Jones pdata->blocks |= STMPE_BLOCK_ADC; 1360d7667f19SFrancesco Dolcini else if (of_device_is_compatible(child, stmpe_pwm_cell.of_compatible)) 1361ac713cc9SVipul Kumar Samar pdata->blocks |= STMPE_BLOCK_PWM; 1362909582caSLee Jones } 1363909582caSLee Jones } 1364909582caSLee Jones 13651a6e4b74SViresh Kumar /* Called from client specific probe routines */ 1366c00572bcSLee Jones int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum) 1367208c4343SSundar Iyer { 1368fc1882dcSLinus Walleij struct stmpe_platform_data *pdata; 1369909582caSLee Jones struct device_node *np = ci->dev->of_node; 137027e34995SRabin Vincent struct stmpe *stmpe; 1371ac3e9119SDmitry Torokhov struct gpio_desc *irq_gpio; 137227e34995SRabin Vincent int ret; 13736377cfa3SStefan Agner u32 val; 137427e34995SRabin Vincent 1375cb5faba9SViresh Kumar pdata = devm_kzalloc(ci->dev, sizeof(*pdata), GFP_KERNEL); 137627e34995SRabin Vincent if (!pdata) 1377909582caSLee Jones return -ENOMEM; 1378909582caSLee Jones 1379909582caSLee Jones stmpe_of_probe(pdata, np); 1380a200e320SGabriel Fernandez 13811ba58fbbSRob Herring if (!of_property_present(np, "interrupts")) 1382a200e320SGabriel Fernandez ci->irq = -1; 138327e34995SRabin Vincent 1384cb5faba9SViresh Kumar stmpe = devm_kzalloc(ci->dev, sizeof(struct stmpe), GFP_KERNEL); 138527e34995SRabin Vincent if (!stmpe) 138627e34995SRabin Vincent return -ENOMEM; 138727e34995SRabin Vincent 138827e34995SRabin Vincent mutex_init(&stmpe->irq_lock); 138927e34995SRabin Vincent mutex_init(&stmpe->lock); 139027e34995SRabin Vincent 13916377cfa3SStefan Agner if (!of_property_read_u32(np, "st,sample-time", &val)) 13926377cfa3SStefan Agner stmpe->sample_time = val; 13936377cfa3SStefan Agner if (!of_property_read_u32(np, "st,mod-12b", &val)) 13946377cfa3SStefan Agner stmpe->mod_12b = val; 13956377cfa3SStefan Agner if (!of_property_read_u32(np, "st,ref-sel", &val)) 13966377cfa3SStefan Agner stmpe->ref_sel = val; 13976377cfa3SStefan Agner if (!of_property_read_u32(np, "st,adc-freq", &val)) 13986377cfa3SStefan Agner stmpe->adc_freq = val; 13996377cfa3SStefan Agner 14001a6e4b74SViresh Kumar stmpe->dev = ci->dev; 14011a6e4b74SViresh Kumar stmpe->client = ci->client; 140227e34995SRabin Vincent stmpe->pdata = pdata; 14031a6e4b74SViresh Kumar stmpe->ci = ci; 14041a6e4b74SViresh Kumar stmpe->partnum = partnum; 14051a6e4b74SViresh Kumar stmpe->variant = stmpe_variant_info[partnum]; 140627e34995SRabin Vincent stmpe->regs = stmpe->variant->regs; 140727e34995SRabin Vincent stmpe->num_gpios = stmpe->variant->num_gpios; 14089c9e3214SLinus Walleij stmpe->vcc = devm_regulator_get_optional(ci->dev, "vcc"); 14099c9e3214SLinus Walleij if (!IS_ERR(stmpe->vcc)) { 14109c9e3214SLinus Walleij ret = regulator_enable(stmpe->vcc); 14119c9e3214SLinus Walleij if (ret) 14129c9e3214SLinus Walleij dev_warn(ci->dev, "failed to enable VCC supply\n"); 14139c9e3214SLinus Walleij } 14149c9e3214SLinus Walleij stmpe->vio = devm_regulator_get_optional(ci->dev, "vio"); 14159c9e3214SLinus Walleij if (!IS_ERR(stmpe->vio)) { 14169c9e3214SLinus Walleij ret = regulator_enable(stmpe->vio); 14179c9e3214SLinus Walleij if (ret) 14189c9e3214SLinus Walleij dev_warn(ci->dev, "failed to enable VIO supply\n"); 14199c9e3214SLinus Walleij } 14201a6e4b74SViresh Kumar dev_set_drvdata(stmpe->dev, stmpe); 142127e34995SRabin Vincent 14221a6e4b74SViresh Kumar if (ci->init) 14231a6e4b74SViresh Kumar ci->init(stmpe); 142427e34995SRabin Vincent 1425ac3e9119SDmitry Torokhov irq_gpio = devm_gpiod_get_optional(ci->dev, "irq", GPIOD_ASIS); 1426ac3e9119SDmitry Torokhov ret = PTR_ERR_OR_ZERO(irq_gpio); 142773de16dbSViresh Kumar if (ret) { 1428ac3e9119SDmitry Torokhov dev_err(stmpe->dev, "failed to request IRQ GPIO: %d\n", ret); 1429cb5faba9SViresh Kumar return ret; 143073de16dbSViresh Kumar } 143173de16dbSViresh Kumar 1432ac3e9119SDmitry Torokhov if (irq_gpio) { 1433ac3e9119SDmitry Torokhov stmpe->irq = gpiod_to_irq(irq_gpio); 1434ac3e9119SDmitry Torokhov pdata->irq_trigger = gpiod_is_active_low(irq_gpio) ? 1435ac3e9119SDmitry Torokhov IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH; 143673de16dbSViresh Kumar } else { 14371a6e4b74SViresh Kumar stmpe->irq = ci->irq; 1438ac3e9119SDmitry Torokhov pdata->irq_trigger = IRQF_TRIGGER_NONE; 143973de16dbSViresh Kumar } 144073de16dbSViresh Kumar 1441e31f9b82SChris Blair if (stmpe->irq < 0) { 1442e31f9b82SChris Blair /* use alternate variant info for no-irq mode, if supported */ 1443e31f9b82SChris Blair dev_info(stmpe->dev, 1444e31f9b82SChris Blair "%s configured in no-irq mode by platform data\n", 1445e31f9b82SChris Blair stmpe->variant->name); 1446e31f9b82SChris Blair if (!stmpe_noirq_variant_info[stmpe->partnum]) { 1447e31f9b82SChris Blair dev_err(stmpe->dev, 1448e31f9b82SChris Blair "%s does not support no-irq mode!\n", 1449e31f9b82SChris Blair stmpe->variant->name); 1450cb5faba9SViresh Kumar return -ENODEV; 1451e31f9b82SChris Blair } 1452e31f9b82SChris Blair stmpe->variant = stmpe_noirq_variant_info[stmpe->partnum]; 1453ac713cc9SVipul Kumar Samar } else if (pdata->irq_trigger == IRQF_TRIGGER_NONE) { 14541a5595cbSJavier Martinez Canillas pdata->irq_trigger = irq_get_trigger_type(stmpe->irq); 1455e31f9b82SChris Blair } 1456e31f9b82SChris Blair 145727e34995SRabin Vincent ret = stmpe_chip_init(stmpe); 145827e34995SRabin Vincent if (ret) 1459cb5faba9SViresh Kumar return ret; 146027e34995SRabin Vincent 1461e31f9b82SChris Blair if (stmpe->irq >= 0) { 1462909582caSLee Jones ret = stmpe_irq_init(stmpe, np); 146327e34995SRabin Vincent if (ret) 1464cb5faba9SViresh Kumar return ret; 146527e34995SRabin Vincent 1466cb5faba9SViresh Kumar ret = devm_request_threaded_irq(ci->dev, stmpe->irq, NULL, 1467cb5faba9SViresh Kumar stmpe_irq, pdata->irq_trigger | IRQF_ONESHOT, 1468e31f9b82SChris Blair "stmpe", stmpe); 146927e34995SRabin Vincent if (ret) { 1470e31f9b82SChris Blair dev_err(stmpe->dev, "failed to request IRQ: %d\n", 1471e31f9b82SChris Blair ret); 1472cb5faba9SViresh Kumar return ret; 147327e34995SRabin Vincent } 1474e31f9b82SChris Blair } 147527e34995SRabin Vincent 147627e34995SRabin Vincent ret = stmpe_devices_init(stmpe); 1477cb5faba9SViresh Kumar if (!ret) 147827e34995SRabin Vincent return 0; 147927e34995SRabin Vincent 1480cb5faba9SViresh Kumar dev_err(stmpe->dev, "failed to add children\n"); 148127e34995SRabin Vincent mfd_remove_devices(stmpe->dev); 1482cb5faba9SViresh Kumar 148327e34995SRabin Vincent return ret; 148427e34995SRabin Vincent } 148527e34995SRabin Vincent 1486356bbabaSUwe Kleine-König void stmpe_remove(struct stmpe *stmpe) 148727e34995SRabin Vincent { 1488*104d32bdSChristophe JAILLET if (!IS_ERR(stmpe->vio) && regulator_is_enabled(stmpe->vio)) 14899c9e3214SLinus Walleij regulator_disable(stmpe->vio); 1490*104d32bdSChristophe JAILLET if (!IS_ERR(stmpe->vcc) && regulator_is_enabled(stmpe->vcc)) 14919c9e3214SLinus Walleij regulator_disable(stmpe->vcc); 14929c9e3214SLinus Walleij 14936377cfa3SStefan Agner __stmpe_disable(stmpe, STMPE_BLOCK_ADC); 14946377cfa3SStefan Agner 149527e34995SRabin Vincent mfd_remove_devices(stmpe->dev); 149627e34995SRabin Vincent } 149727e34995SRabin Vincent 14981a6e4b74SViresh Kumar static int stmpe_suspend(struct device *dev) 14991a6e4b74SViresh Kumar { 15001a6e4b74SViresh Kumar struct stmpe *stmpe = dev_get_drvdata(dev); 15011a6e4b74SViresh Kumar 1502e31f9b82SChris Blair if (stmpe->irq >= 0 && device_may_wakeup(dev)) 15031a6e4b74SViresh Kumar enable_irq_wake(stmpe->irq); 15041a6e4b74SViresh Kumar 15051a6e4b74SViresh Kumar return 0; 15061a6e4b74SViresh Kumar } 15071a6e4b74SViresh Kumar 15081a6e4b74SViresh Kumar static int stmpe_resume(struct device *dev) 15091a6e4b74SViresh Kumar { 15101a6e4b74SViresh Kumar struct stmpe *stmpe = dev_get_drvdata(dev); 15111a6e4b74SViresh Kumar 1512e31f9b82SChris Blair if (stmpe->irq >= 0 && device_may_wakeup(dev)) 15131a6e4b74SViresh Kumar disable_irq_wake(stmpe->irq); 15141a6e4b74SViresh Kumar 15151a6e4b74SViresh Kumar return 0; 15161a6e4b74SViresh Kumar } 15171a6e4b74SViresh Kumar 1518f7f292feSPaul Cercueil EXPORT_GPL_SIMPLE_DEV_PM_OPS(stmpe_dev_pm_ops, 1519f7f292feSPaul Cercueil stmpe_suspend, stmpe_resume); 1520