STMPE fixes/rework and add STMPE1600 support
Subsystems (4)
v2 cover STMPE fixes/rework and add STMPE1600 support
From: Patrice Chotard <[email protected]>
This series cleans and fixes some bugs in MFD/GPIO STMPE drivers and prepare
the ground to add new STMPE1600 support.
STMPE1600 datasheet is available here :
http://www2.st.com/content/st_com/en/products/interfaces-and-transceivers/
i-o-expanders-and-level-translators/i-o-expanders/stmpe1600.html
Only STMPE1600 has been tested on STM32 platform. As i have no board with others STMPE variant(STMPE610/STMPE801/STMPE811/STMPE1601/STMPE1801/STMPE2401 and STMPE2403), i put in CC boards's maintainers which are using others STMPE variant.
If they can kindly check that no regression has been introduce by this series :
For ARM/FREESCALE IMX / MXC ARM ARCHITECTURE:
_ Shawn Guo <[email protected]>
_ Sascha Hauer <[email protected]>
For ARM/SOCFPGA ARCHITECTURE
_ Dinh Nguyen <[email protected]>
For SPEAR PLATFORM SUPPORT
_ Viresh Kumar <[email protected]>
_ Shiraz Hashim <[email protected]>
For Apalis/Colibri board SUPPORT
_ marcel.ziswiler at toradex.com
_ stefan at agner.ch
_ dev at lynxeye.de
_ Thierry Reding <[email protected]> _ Alexandre Courbot <[email protected]>
For ARM/Ux500 ARM ARCHITECTURE
_ Linus Walleij <[email protected]>
resend v2:
_ add Linus Walleij and Lee Jones's acked-by/reviewed-by
v1 => v2:
_ update Cc list
_ fix kbuild test robot warnings on original patch 3 _ split patch 6 to extract usage of generic bitmask name _ split patch 6 and 7 and introduce a new way to access registers
for both mfd/stmpe and gpio/gpio-stmpe drivers.
_ remove patch 8
Patrice Chotard (10):
mfd: stmpe: Add STMPE_IDX_SYS_CTRL/2 enum
mfd: stmpe: Add reset support for all STMPE variant
gpio: stmpe: fix edge and rising/falling edge detection
gpio: stmpe: write int status register only when needed
mfd: stmpe: use generic bit mask name
mfd: stmpe: rework registers access
gpio: stmpe: rework registers access
Documentation: dt: add stmpe1600 compatible string to stmpe mfd
mfd: Add STMPE1600 support
gpio: stmpe: Add STMPE1600 support
Documentation/devicetree/bindings/mfd/stmpe.txt | 2 +- drivers/gpio/gpio-stmpe.c | 167 +++++++++++++++++------- drivers/mfd/stmpe-i2c.c | 2 + drivers/mfd/stmpe.c | 161 +++++++++++++++++++---- drivers/mfd/stmpe.h | 85 ++++++++++-- include/linux/mfd/stmpe.h | 21 +++ 6 files changed, 352 insertions(+), 86 deletions(-)
Signature · 1 line
1.9.1
PATCH RESEND v2 1/10 mfd: stmpe: Add STMPE_IDX_SYS_CTRL/2 enum
From: Patrice Chotard <[email protected]>
As STMPE1801/1601/24xx has a SYS_CTRL register and STMPE1601/2403 has even a SYS_CTRL2 register, add STMPE_IDX_SYS_CTRL/2 and update driver code accordingly
This update prepares the ground for not yet supported STMPE1600 which share similar REG_SYS_CTRL register.
--- drivers/mfd/stmpe.c | 21 ++++++++++++++------- drivers/mfd/stmpe.h | 2 ++ include/linux/mfd/stmpe.h | 2 ++ 3 files changed, 18 insertions(+), 7 deletions(-)
drivers/mfd/stmpe.c +14 -7
@@ -448,6 +448,8 @@ static const struct mfd_cell stmpe_ts_cell = {static const u8 stmpe811_regs[] = { [STMPE_IDX_CHIP_ID ] =STMPE811_REG_CHIP_ID , + [STMPE_IDX_SYS_CTRL ] =STMPE811_REG_SYS_CTRL , + [STMPE_IDX_SYS_CTRL2 ] =STMPE811_REG_SYS_CTRL2 , [STMPE_IDX_ICR_LSB ] =STMPE811_REG_INT_CTRL , [STMPE_IDX_IER_LSB ] =STMPE811_REG_INT_EN , [STMPE_IDX_ISR_MSB ] =STMPE811_REG_INT_STA ,
@@ -490,7 +492,7 @@ static int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks,if (blocks &STMPE_BLOCK_TOUCHSCREEN ) mask |=STMPE811_SYS_CTRL2_TSC_OFF ; -return __stmpe_set_bits (stmpe,STMPE811_REG_SYS_CTRL2 , mask, +return __stmpe_set_bits (stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2 ], mask, enable ?0 : mask); }
@@ -535,6 +537,8 @@ static struct stmpe_variant_info stmpe610 = {static const u8 stmpe1601_regs[] = { [STMPE_IDX_CHIP_ID ] =STMPE1601_REG_CHIP_ID , + [STMPE_IDX_SYS_CTRL ] =STMPE1601_REG_SYS_CTRL , + [STMPE_IDX_SYS_CTRL2 ] =STMPE1601_REG_SYS_CTRL2 , [STMPE_IDX_ICR_LSB ] =STMPE1601_REG_ICR_LSB , [STMPE_IDX_IER_LSB ] =STMPE1601_REG_IER_LSB , [STMPE_IDX_ISR_MSB ] =STMPE1601_REG_ISR_MSB ,
@@ -619,13 +623,13 @@ static int stmpe1601_autosleep(struct stmpe *stmpe,return timeout; } - ret =__stmpe_set_bits (stmpe,STMPE1601_REG_SYS_CTRL2 , + ret =__stmpe_set_bits (stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2 ],STMPE1601_AUTOSLEEP_TIMEOUT_MASK , timeout);if (ret <0 )return ret; -return __stmpe_set_bits (stmpe,STMPE1601_REG_SYS_CTRL2 , +return __stmpe_set_bits (stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2 ],STPME1601_AUTOSLEEP_ENABLE ,STPME1601_AUTOSLEEP_ENABLE ); }
@@ -650,7 +654,7 @@ static int stmpe1601_enable(struct stmpe *stmpe, unsigned int blocks,else mask &= ~STMPE1601_SYS_CTRL_ENABLE_SPWM ; -return __stmpe_set_bits (stmpe,STMPE1601_REG_SYS_CTRL , mask, +return __stmpe_set_bits (stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL ], mask, enable ? mask :0 ); }
@@ -689,6 +693,7 @@ static struct stmpe_variant_info stmpe1601 = {*/ static const u8 stmpe1801_regs[] = { [STMPE_IDX_CHIP_ID ] =STMPE1801_REG_CHIP_ID , + [STMPE_IDX_SYS_CTRL ] =STMPE1801_REG_SYS_CTRL , [STMPE_IDX_ICR_LSB ] =STMPE1801_REG_INT_CTRL_LOW , [STMPE_IDX_IER_LSB ] =STMPE1801_REG_INT_EN_MASK_LOW , [STMPE_IDX_ISR_LSB ] =STMPE1801_REG_INT_STA_LOW ,
@@ -735,14 +740,14 @@ static int stmpe1801_reset(struct stmpe *stmpe)unsigned long timeout;int ret =0 ; - ret =__stmpe_set_bits (stmpe,STMPE1801_REG_SYS_CTRL , + ret =__stmpe_set_bits (stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL ],STMPE1801_MSK_SYS_CTRL_RESET ,STMPE1801_MSK_SYS_CTRL_RESET );if (ret <0 )return ret; timeout = jiffies +msecs_to_jiffies (100 );while (time_before (jiffies, timeout)) { - ret =__stmpe_reg_read (stmpe,STMPE1801_REG_SYS_CTRL ); + ret =__stmpe_reg_read (stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL ]);if (ret <0 )return ret;if (!(ret &STMPE1801_MSK_SYS_CTRL_RESET ))
@@ -773,6 +778,8 @@ static struct stmpe_variant_info stmpe1801 = {static const u8 stmpe24xx_regs[] = { [STMPE_IDX_CHIP_ID ] =STMPE24XX_REG_CHIP_ID , + [STMPE_IDX_SYS_CTRL ] =STMPE24XX_REG_SYS_CTRL , + [STMPE_IDX_SYS_CTRL2 ] =STMPE24XX_REG_SYS_CTRL2 , [STMPE_IDX_ICR_LSB ] =STMPE24XX_REG_ICR_LSB , [STMPE_IDX_IER_LSB ] =STMPE24XX_REG_IER_LSB , [STMPE_IDX_ISR_MSB ] =STMPE24XX_REG_ISR_MSB ,
@@ -819,7 +826,7 @@ static int stmpe24xx_enable(struct stmpe *stmpe, unsigned int blocks,if (blocks &STMPE_BLOCK_KEYPAD ) mask |=STMPE24XX_SYS_CTRL_ENABLE_KPC ; -return __stmpe_set_bits (stmpe,STMPE24XX_REG_SYS_CTRL , mask, +return __stmpe_set_bits (stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL ], mask, enable ? mask :0 ); }
drivers/mfd/stmpe.h +2 -0
@@ -138,6 +138,7 @@ int stmpe_remove(struct stmpe *stmpe);#define STMPE811_NR_INTERNAL_IRQS 8#define STMPE811_REG_CHIP_ID 0x00 +#define STMPE811_REG_SYS_CTRL 0x03#define STMPE811_REG_SYS_CTRL2 0x04#define STMPE811_REG_SPI_CFG 0x08#define STMPE811_REG_INT_CTRL 0x09
@@ -264,6 +265,7 @@ int stmpe_remove(struct stmpe *stmpe);#define STMPE24XX_NR_INTERNAL_IRQS 9#define STMPE24XX_REG_SYS_CTRL 0x02 +#define STMPE24XX_REG_SYS_CTRL2 0x03#define STMPE24XX_REG_ICR_LSB 0x11#define STMPE24XX_REG_IER_LSB 0x13#define STMPE24XX_REG_ISR_MSB 0x14
include/linux/mfd/stmpe.h +2 -0
@@ -39,6 +39,8 @@ enum stmpe_partnum {*/ enum {STMPE_IDX_CHIP_ID , +STMPE_IDX_SYS_CTRL , +STMPE_IDX_SYS_CTRL2 ,STMPE_IDX_ICR_LSB ,STMPE_IDX_IER_LSB ,STMPE_IDX_ISR_LSB ,
Signature · 1 line
1.9.1
Lee Jones
AppliedPATCH RESEND v2 1/10 mfd: stmpe: Add STMPE_IDX_SYS_CTRL/2 enum
Quoted 9 lines · patrice.chotard at st.com
From: Patrice Chotard <[email protected]>
As STMPE1801/1601/24xx has a
SYS_CTRLregister and STMPE1601/2403 has even aSYS_CTRL2register, add STMPE_IDX_SYS_CTRL/2 and update driver code accordinglyThis update prepares the ground for not yet supported STMPE1600 which share similar
REG_SYS_CTRLregister.
Quoted 8 lines
Signed-off-by Patrice Chotard <[email protected]>Acked-by Linus Walleij <[email protected]>Acked-by Lee Jones <[email protected]>--- drivers/mfd/stmpe.c | 21 ++++++++++++++------- drivers/mfd/stmpe.h | 2 ++ include/linux/mfd/stmpe.h | 2 ++ 3 files changed, 18 insertions(+), 7 deletions(-)
Applied, thanks.
Quoted 132 lines
drivers/mfd/stmpe.c +14
-7@@ -448,6 +448,8 @@ static const struct mfd_cell stmpe_ts_cell = {static const u8 stmpe811_regs[] = { [STMPE_IDX_CHIP_ID ] =STMPE811_REG_CHIP_ID , + [STMPE_IDX_SYS_CTRL ] =STMPE811_REG_SYS_CTRL , + [STMPE_IDX_SYS_CTRL2 ] =STMPE811_REG_SYS_CTRL2 , [STMPE_IDX_ICR_LSB ] =STMPE811_REG_INT_CTRL , [STMPE_IDX_IER_LSB ] =STMPE811_REG_INT_EN , [STMPE_IDX_ISR_MSB ] =STMPE811_REG_INT_STA ,@@ -490,7 +492,7 @@ static int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks,if (blocks &STMPE_BLOCK_TOUCHSCREEN ) mask |=STMPE811_SYS_CTRL2_TSC_OFF ; -return __stmpe_set_bits (stmpe,STMPE811_REG_SYS_CTRL2 , mask, +return __stmpe_set_bits (stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2 ], mask, enable ?0 : mask); }@@ -535,6 +537,8 @@ static struct stmpe_variant_info stmpe610 = {static const u8 stmpe1601_regs[] = { [STMPE_IDX_CHIP_ID ] =STMPE1601_REG_CHIP_ID , + [STMPE_IDX_SYS_CTRL ] =STMPE1601_REG_SYS_CTRL , + [STMPE_IDX_SYS_CTRL2 ] =STMPE1601_REG_SYS_CTRL2 , [STMPE_IDX_ICR_LSB ] =STMPE1601_REG_ICR_LSB , [STMPE_IDX_IER_LSB ] =STMPE1601_REG_IER_LSB , [STMPE_IDX_ISR_MSB ] =STMPE1601_REG_ISR_MSB ,@@ -619,13 +623,13 @@ static int stmpe1601_autosleep(struct stmpe *stmpe,return timeout; } - ret =__stmpe_set_bits (stmpe,STMPE1601_REG_SYS_CTRL2 , + ret =__stmpe_set_bits (stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2 ],STMPE1601_AUTOSLEEP_TIMEOUT_MASK , timeout);if (ret <0 )return ret; -return __stmpe_set_bits (stmpe,STMPE1601_REG_SYS_CTRL2 , +return __stmpe_set_bits (stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2 ],STPME1601_AUTOSLEEP_ENABLE ,STPME1601_AUTOSLEEP_ENABLE ); }@@ -650,7 +654,7 @@ static int stmpe1601_enable(struct stmpe *stmpe, unsigned int blocks,else mask &= ~STMPE1601_SYS_CTRL_ENABLE_SPWM ; -return __stmpe_set_bits (stmpe,STMPE1601_REG_SYS_CTRL , mask, +return __stmpe_set_bits (stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL ], mask, enable ? mask :0 ); }@@ -689,6 +693,7 @@ static struct stmpe_variant_info stmpe1601 = {*/ static const u8 stmpe1801_regs[] = { [STMPE_IDX_CHIP_ID ] =STMPE1801_REG_CHIP_ID , + [STMPE_IDX_SYS_CTRL ] =STMPE1801_REG_SYS_CTRL , [STMPE_IDX_ICR_LSB ] =STMPE1801_REG_INT_CTRL_LOW , [STMPE_IDX_IER_LSB ] =STMPE1801_REG_INT_EN_MASK_LOW , [STMPE_IDX_ISR_LSB ] =STMPE1801_REG_INT_STA_LOW ,@@ -735,14 +740,14 @@ static int stmpe1801_reset(struct stmpe *stmpe)unsigned long timeout;int ret =0 ; - ret =__stmpe_set_bits (stmpe,STMPE1801_REG_SYS_CTRL , + ret =__stmpe_set_bits (stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL ],STMPE1801_MSK_SYS_CTRL_RESET ,STMPE1801_MSK_SYS_CTRL_RESET );if (ret <0 )return ret; timeout = jiffies +msecs_to_jiffies (100 );while (time_before (jiffies, timeout)) { - ret =__stmpe_reg_read (stmpe,STMPE1801_REG_SYS_CTRL ); + ret =__stmpe_reg_read (stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL ]);if (ret <0 )return ret;if (!(ret &STMPE1801_MSK_SYS_CTRL_RESET ))@@ -773,6 +778,8 @@ static struct stmpe_variant_info stmpe1801 = {static const u8 stmpe24xx_regs[] = { [STMPE_IDX_CHIP_ID ] =STMPE24XX_REG_CHIP_ID , + [STMPE_IDX_SYS_CTRL ] =STMPE24XX_REG_SYS_CTRL , + [STMPE_IDX_SYS_CTRL2 ] =STMPE24XX_REG_SYS_CTRL2 , [STMPE_IDX_ICR_LSB ] =STMPE24XX_REG_ICR_LSB , [STMPE_IDX_IER_LSB ] =STMPE24XX_REG_IER_LSB , [STMPE_IDX_ISR_MSB ] =STMPE24XX_REG_ISR_MSB ,@@ -819,7 +826,7 @@ static int stmpe24xx_enable(struct stmpe *stmpe, unsigned int blocks,if (blocks &STMPE_BLOCK_KEYPAD ) mask |=STMPE24XX_SYS_CTRL_ENABLE_KPC ; -return __stmpe_set_bits (stmpe,STMPE24XX_REG_SYS_CTRL , mask, +return __stmpe_set_bits (stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL ], mask, enable ? mask :0 ); }drivers/mfd/stmpe.h +2
-0@@ -138,6 +138,7 @@ int stmpe_remove(struct stmpe *stmpe);#define STMPE811_NR_INTERNAL_IRQS 8#define STMPE811_REG_CHIP_ID 0x00 +#define STMPE811_REG_SYS_CTRL 0x03#define STMPE811_REG_SYS_CTRL2 0x04#define STMPE811_REG_SPI_CFG 0x08#define STMPE811_REG_INT_CTRL 0x09@@ -264,6 +265,7 @@ int stmpe_remove(struct stmpe *stmpe);#define STMPE24XX_NR_INTERNAL_IRQS 9#define STMPE24XX_REG_SYS_CTRL 0x02 +#define STMPE24XX_REG_SYS_CTRL2 0x03#define STMPE24XX_REG_ICR_LSB 0x11#define STMPE24XX_REG_IER_LSB 0x13#define STMPE24XX_REG_ISR_MSB 0x14include/linux/mfd/stmpe.h +2
-0@@ -39,6 +39,8 @@ enum stmpe_partnum {*/ enum {STMPE_IDX_CHIP_ID , +STMPE_IDX_SYS_CTRL , +STMPE_IDX_SYS_CTRL2 ,STMPE_IDX_ICR_LSB ,STMPE_IDX_IER_LSB ,STMPE_IDX_ISR_LSB ,
Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org ? Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
PATCH RESEND v2 2/10 mfd: stmpe: Add reset support for all STMPE variant
In reply to patrice.chotard at st.comFrom: Patrice Chotard <[email protected]>
Reset was only implemented for STMPE1801 variant despite all variant have a SOFT_RESET bit.
For STMPE2401/2403/801/1601/1801 SOFT_RESET bit is bit 7 of SYS_CTRL register.
For STMPE610/811 (which have the same variant id) SOFT_RESET bit is bit 1 of SYS_CTRL register.
--- drivers/mfd/stmpe.c | 23 +++++++++++++++-------- drivers/mfd/stmpe.h | 7 +++++-- 2 files changed, 20 insertions(+), 10 deletions(-)
drivers/mfd/stmpe.c +15 -8
@@ -735,13 +735,22 @@ static int stmpe1801_enable(struct stmpe *stmpe, unsigned int blocks, enable ? mask : 0); } -static int stmpe1801_reset (struct stmpe *stmpe) +static int stmpe_reset (struct stmpe *stmpe) { +u16 id_val = stmpe->variant->id_val;unsigned long timeout;int ret =0 ; +u8 reset_bit; + +if (id_val ==STMPE811_ID ) +/* STMPE801 and STMPE610 use bit 1 of SYS_CTRL register */ + reset_bit =STMPE811_SYS_CTRL_RESET ; +else +/* all other STMPE variant use bit 7 of SYS_CTRL register */ + reset_bit =STMPE_SYS_CTRL_RESET ; ret =__stmpe_set_bits (stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL ], -STMPE1801_MSK_SYS_CTRL_RESET ,STMPE1801_MSK_SYS_CTRL_RESET ); + reset_bit, reset_bit);if (ret <0 )return ret;
@@ -750,7 +759,7 @@ static int stmpe1801_reset(struct stmpe *stmpe) ret =__stmpe_reg_read (stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL ]);if (ret <0 )return ret; -if (!(ret &STMPE1801_MSK_SYS_CTRL_RESET )) +if (!(ret & reset_bit))return 0 ;usleep_range (100 ,200 ); }
@@ -1074,11 +1083,9 @@ static int stmpe_chip_init(struct stmpe *stmpe)if (ret)return ret; -if (id ==STMPE1801_ID ) { - ret =stmpe1801_reset (stmpe); -if (ret <0 ) -return ret; - } + ret =stmpe_reset (stmpe); +if (ret <0 ) +return ret;if (stmpe->irq >=0 ) {if (id ==STMPE801_ID )
drivers/mfd/stmpe.h +5 -2
@@ -104,6 +104,8 @@ int stmpe_remove(struct stmpe *stmpe);#define STMPE_ICR_LSB_EDGE (1 << 1)#define STMPE_ICR_LSB_GIM (1 << 0) +#define STMPE_SYS_CTRL_RESET (1 << 7) +/* * STMPE801 */
@@ -126,6 +128,7 @@ int stmpe_remove(struct stmpe *stmpe);/* * STMPE811 */ +#define STMPE811_ID 0x0811#define STMPE811_IRQ_TOUCH_DET 0#define STMPE811_IRQ_FIFO_TH 1
@@ -155,6 +158,8 @@ int stmpe_remove(struct stmpe *stmpe);#define STMPE811_REG_GPIO_FE 0x16#define STMPE811_REG_GPIO_AF 0x17 +#define STMPE811_SYS_CTRL_RESET (1 << 1) +#define STMPE811_SYS_CTRL2_ADC_OFF (1 << 0)#define STMPE811_SYS_CTRL2_TSC_OFF (1 << 1)#define STMPE811_SYS_CTRL2_GPIO_OFF (1 << 2)
@@ -244,8 +249,6 @@ int stmpe_remove(struct stmpe *stmpe);#define STMPE1801_REG_GPIO_PULL_UP_MID 0x23#define STMPE1801_REG_GPIO_PULL_UP_HIGH 0x24 -#define STMPE1801_MSK_SYS_CTRL_RESET (1 << 7) -#define STMPE1801_MSK_INT_EN_KPC (1 << 1)#define STMPE1801_MSK_INT_EN_GPIO (1 << 3)
Signature · 1 line
1.9.1
Lee Jones
AppliedPATCH RESEND v2 2/10 mfd: stmpe: Add reset support for all STMPE variant
Quoted 10 lines · patrice.chotard at st.com
From: Patrice Chotard <[email protected]>
Reset was only implemented for STMPE1801 variant despite all variant have a
SOFT_RESETbit.For STMPE2401/2403/801/1601/1801
SOFT_RESETbit is bit 7 ofSYS_CTRLregister.
For STMPE610/811 (which have the same variant id)SOFT_RESETbit is bit 1 ofSYS_CTRLregister.
Quoted 7 lines
Signed-off-by Patrice Chotard <[email protected]>Acked-by Linus Walleij <[email protected]>Acked-by Lee Jones <[email protected]>--- drivers/mfd/stmpe.c | 23 +++++++++++++++-------- drivers/mfd/stmpe.h | 7 +++++-- 2 files changed, 20 insertions(+), 10 deletions(-)
Applied, thanks.
Quoted 92 lines
drivers/mfd/stmpe.c +15
-8@@ -735,13 +735,22 @@ static int stmpe1801_enable(struct stmpe *stmpe, unsigned int blocks, enable ? mask : 0); } -static int stmpe1801_reset (struct stmpe *stmpe) +static int stmpe_reset (struct stmpe *stmpe) { +u16 id_val = stmpe->variant->id_val;unsigned long timeout;int ret =0 ; +u8 reset_bit; + +if (id_val ==STMPE811_ID ) +/* STMPE801 and STMPE610 use bit 1 of SYS_CTRL register */ + reset_bit =STMPE811_SYS_CTRL_RESET ; +else +/* all other STMPE variant use bit 7 of SYS_CTRL register */ + reset_bit =STMPE_SYS_CTRL_RESET ; ret =__stmpe_set_bits (stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL ], -STMPE1801_MSK_SYS_CTRL_RESET ,STMPE1801_MSK_SYS_CTRL_RESET ); + reset_bit, reset_bit);if (ret <0 )return ret;@@ -750,7 +759,7 @@ static int stmpe1801_reset(struct stmpe *stmpe) ret =__stmpe_reg_read (stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL ]);if (ret <0 )return ret; -if (!(ret &STMPE1801_MSK_SYS_CTRL_RESET )) +if (!(ret & reset_bit))return 0 ;usleep_range (100 ,200 ); }@@ -1074,11 +1083,9 @@ static int stmpe_chip_init(struct stmpe *stmpe)if (ret)return ret; -if (id ==STMPE1801_ID ) { - ret =stmpe1801_reset (stmpe); -if (ret <0 ) -return ret; - } + ret =stmpe_reset (stmpe); +if (ret <0 ) +return ret;if (stmpe->irq >=0 ) {if (id ==STMPE801_ID )drivers/mfd/stmpe.h +5
-2@@ -104,6 +104,8 @@ int stmpe_remove(struct stmpe *stmpe);#define STMPE_ICR_LSB_EDGE (1 << 1)#define STMPE_ICR_LSB_GIM (1 << 0) +#define STMPE_SYS_CTRL_RESET (1 << 7) +/* * STMPE801 */ @@ -126,6 +128,7 @@ int stmpe_remove(struct stmpe *stmpe);/* * STMPE811 */ +#define STMPE811_ID 0x0811#define STMPE811_IRQ_TOUCH_DET 0#define STMPE811_IRQ_FIFO_TH 1@@ -155,6 +158,8 @@ int stmpe_remove(struct stmpe *stmpe);#define STMPE811_REG_GPIO_FE 0x16#define STMPE811_REG_GPIO_AF 0x17 +#define STMPE811_SYS_CTRL_RESET (1 << 1) +#define STMPE811_SYS_CTRL2_ADC_OFF (1 << 0)#define STMPE811_SYS_CTRL2_TSC_OFF (1 << 1)#define STMPE811_SYS_CTRL2_GPIO_OFF (1 << 2)@@ -244,8 +249,6 @@ int stmpe_remove(struct stmpe *stmpe);#define STMPE1801_REG_GPIO_PULL_UP_MID 0x23#define STMPE1801_REG_GPIO_PULL_UP_HIGH 0x24 -#define STMPE1801_MSK_SYS_CTRL_RESET (1 << 7) -#define STMPE1801_MSK_INT_EN_KPC (1 << 1)#define STMPE1801_MSK_INT_EN_GPIO (1 << 3)
Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org ? Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
PATCH RESEND v2 3/10 gpio: stmpe: fix edge and rising/falling edge detection
In reply to patrice.chotard at st.comFrom: Patrice Chotard <[email protected]>
By cross-checking STMPE 610/801/811/1601/2401/2403 datasheets, it appears that edge detection and rising/falling edge detection is not supported by all STMPE variant:
GPIO GPIO
Edge detection rising/falling
edge detection
610 | X | X | 801 | | | 811 | X | X | 1600 | | | 1601 | X | X | 1801 | | X | 2401 | X | X | 2403 | X | X |
Rework stmpe_dbg_show_one() and stmpe_gpio_irq to correctly take these cases into account.
--- drivers/gpio/gpio-stmpe.c | 85 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 25 deletions(-)
drivers/gpio/gpio-stmpe.c +60 -25
@@ -231,39 +231,74 @@ static void stmpe_dbg_show_one(struct seq_file *s, gpio, label ?:"(none)" , val ? "hi" : "lo"); }else { -u8 edge_det_reg = stmpe->regs[STMPE_IDX_GPEDR_MSB ] + num_banks -1 - (offset /8 ); -u8 rise_reg = stmpe->regs[STMPE_IDX_GPRER_LSB ] - (offset /8 ); -u8 fall_reg = stmpe->regs[STMPE_IDX_GPFER_LSB ] - (offset /8 ); -u8 irqen_reg = stmpe->regs[STMPE_IDX_IEGPIOR_LSB ] - (offset /8 ); -bool edge_det; -bool rise; -bool fall; +u8 edge_det_reg; +u8 rise_reg; +u8 fall_reg; +u8 irqen_reg; + +char *edge_det_values[] = {"edge-inactive" , +"edge-asserted" , +"not-supported" }; +char *rise_values[] = {"no-rising-edge-detection" , +"rising-edge-detection" , +"not-supported" }; +char *fall_values[] = {"no-falling-edge-detection" , +"falling-edge-detection" , +"not-supported" }; +#define NOT_SUPPORTED_IDX 2 +u8 edge_det =NOT_SUPPORTED_IDX ; +u8 rise =NOT_SUPPORTED_IDX ; +u8 fall =NOT_SUPPORTED_IDX ;bool irqen; - ret =stmpe_reg_read (stmpe, edge_det_reg); -if (ret <0 ) -return ; - edge_det = !!(ret & mask); - ret =stmpe_reg_read (stmpe, rise_reg); -if (ret <0 ) +switch (stmpe->partnum) { +case STMPE610 : +case STMPE811 : +case STMPE1601 : +case STMPE2401 : +case STMPE2403 : + edge_det_reg = stmpe->regs[STMPE_IDX_GPEDR_MSB ] + + num_banks -1 - (offset /8 ); + ret =stmpe_reg_read (stmpe, edge_det_reg); +if (ret <0 ) +return ; + edge_det = !!(ret & mask); + +case STMPE1801 : + rise_reg = stmpe->regs[STMPE_IDX_GPRER_LSB ] - + (offset /8 ); + fall_reg = stmpe->regs[STMPE_IDX_GPFER_LSB ] - + (offset /8 ); + ret =stmpe_reg_read (stmpe, rise_reg); +if (ret <0 ) +return ; + rise = !!(ret & mask); + ret =stmpe_reg_read (stmpe, fall_reg); +if (ret <0 ) +return ; + fall = !!(ret & mask); + +case STMPE801 : + irqen_reg = stmpe->regs[STMPE_IDX_IEGPIOR_LSB ] - + (offset /8 ); +break ; + +default :return ; - rise = !!(ret & mask); - ret =stmpe_reg_read (stmpe, fall_reg); -if (ret <0 ) -return ; - fall = !!(ret & mask); + } + ret =stmpe_reg_read (stmpe, irqen_reg);if (ret <0 )return ; irqen = !!(ret & mask); -seq_printf (s," gpio-%-3d (%-20.20s) in %s %s %s%s%s" , +seq_printf (s," gpio-%-3d (%-20.20s) in %s %13s %13s %25s %25s" , gpio, label ?:"(none)" , val ?"hi" :"lo" , - edge_det ?"edge-asserted" :"edge-inactive" , - irqen ?"IRQ-enabled" :"" , - rise ?" rising-edge-detection" :"" , - fall ?" falling-edge-detection" :"" ); + edge_det_values[edge_det], + irqen ?"IRQ-enabled" :"IRQ-disabled" , + rise_values[rise], + fall_values[fall]); } }
@@ -322,8 +357,8 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev)stmpe_reg_write (stmpe, statmsbreg + i, status[i]); -/* Edge detect register is not present on 801 */ -if (stmpe->partnum !=STMPE801 ) +/* Edge detect register is not present on 801 and 1801 */ +if (stmpe->partnum !=STMPE801 || stmpe->partnum !=STMPE1801 )stmpe_reg_write (stmpe, stmpe->regs[STMPE_IDX_GPEDR_MSB ] + i, status[i]); }
Signature · 1 line
1.9.1
Lee Jones
AppliedPATCH RESEND v2 3/10 gpio: stmpe: fix edge and rising/falling edge detection
Quoted 18 lines · patrice.chotard at st.com
From: Patrice Chotard <[email protected]>
By cross-checking STMPE 610/801/811/1601/2401/2403 datasheets, it appears that edge detection and rising/falling edge detection is not supported by all STMPE variant:
GPIO GPIO
Edge detection rising/falling
edge detection610 | X | X | 801 | | | 811 | X | X | 1600 | | | 1601 | X | X | 1801 | | X | 2401 | X | X | 2403 | X | X |
Quoted 8 lines
Rework
stmpe_dbg_show_one()andstmpe_gpio_irqto correctly take these cases into account.Signed-off-by Patrice Chotard <[email protected]>Reviewed-by Linus Walleij <[email protected]>--- drivers/gpio/gpio-stmpe.c | 85 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 25 deletions(-)
Applied, thanks.
Quoted 113 lines
drivers/gpio/gpio-stmpe.c +60
-25@@ -231,39 +231,74 @@ static void stmpe_dbg_show_one(struct seq_file *s, gpio, label ?:"(none)" , val ? "hi" : "lo"); }else { -u8 edge_det_reg = stmpe->regs[STMPE_IDX_GPEDR_MSB ] + num_banks -1 - (offset /8 ); -u8 rise_reg = stmpe->regs[STMPE_IDX_GPRER_LSB ] - (offset /8 ); -u8 fall_reg = stmpe->regs[STMPE_IDX_GPFER_LSB ] - (offset /8 ); -u8 irqen_reg = stmpe->regs[STMPE_IDX_IEGPIOR_LSB ] - (offset /8 ); -bool edge_det; -bool rise; -bool fall; +u8 edge_det_reg; +u8 rise_reg; +u8 fall_reg; +u8 irqen_reg; + +char *edge_det_values[] = {"edge-inactive" , +"edge-asserted" , +"not-supported" }; +char *rise_values[] = {"no-rising-edge-detection" , +"rising-edge-detection" , +"not-supported" }; +char *fall_values[] = {"no-falling-edge-detection" , +"falling-edge-detection" , +"not-supported" }; +#define NOT_SUPPORTED_IDX 2 +u8 edge_det =NOT_SUPPORTED_IDX ; +u8 rise =NOT_SUPPORTED_IDX ; +u8 fall =NOT_SUPPORTED_IDX ;bool irqen; - ret =stmpe_reg_read (stmpe, edge_det_reg); -if (ret <0 ) -return ; - edge_det = !!(ret & mask); - ret =stmpe_reg_read (stmpe, rise_reg); -if (ret <0 ) +switch (stmpe->partnum) { +case STMPE610 : +case STMPE811 : +case STMPE1601 : +case STMPE2401 : +case STMPE2403 : + edge_det_reg = stmpe->regs[STMPE_IDX_GPEDR_MSB ] + + num_banks -1 - (offset /8 ); + ret =stmpe_reg_read (stmpe, edge_det_reg); +if (ret <0 ) +return ; + edge_det = !!(ret & mask); + +case STMPE1801 : + rise_reg = stmpe->regs[STMPE_IDX_GPRER_LSB ] - + (offset /8 ); + fall_reg = stmpe->regs[STMPE_IDX_GPFER_LSB ] - + (offset /8 ); + ret =stmpe_reg_read (stmpe, rise_reg); +if (ret <0 ) +return ; + rise = !!(ret & mask); + ret =stmpe_reg_read (stmpe, fall_reg); +if (ret <0 ) +return ; + fall = !!(ret & mask); + +case STMPE801 : + irqen_reg = stmpe->regs[STMPE_IDX_IEGPIOR_LSB ] - + (offset /8 ); +break ; + +default :return ; - rise = !!(ret & mask); - ret =stmpe_reg_read (stmpe, fall_reg); -if (ret <0 ) -return ; - fall = !!(ret & mask); + } + ret =stmpe_reg_read (stmpe, irqen_reg);if (ret <0 )return ; irqen = !!(ret & mask); -seq_printf (s," gpio-%-3d (%-20.20s) in %s %s %s%s%s" , +seq_printf (s," gpio-%-3d (%-20.20s) in %s %13s %13s %25s %25s" , gpio, label ?:"(none)" , val ?"hi" :"lo" , - edge_det ?"edge-asserted" :"edge-inactive" , - irqen ?"IRQ-enabled" :"" , - rise ?" rising-edge-detection" :"" , - fall ?" falling-edge-detection" :"" ); + edge_det_values[edge_det], + irqen ?"IRQ-enabled" :"IRQ-disabled" , + rise_values[rise], + fall_values[fall]); } }@@ -322,8 +357,8 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev)stmpe_reg_write (stmpe, statmsbreg + i, status[i]); -/* Edge detect register is not present on 801 */ -if (stmpe->partnum !=STMPE801 ) +/* Edge detect register is not present on 801 and 1801 */ +if (stmpe->partnum !=STMPE801 || stmpe->partnum !=STMPE1801 )stmpe_reg_write (stmpe, stmpe->regs[STMPE_IDX_GPEDR_MSB ] + i, status[i]); }
Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org ? Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
PATCH RESEND v2 4/10 gpio: stmpe: write int status register only when needed
In reply to patrice.chotard at st.comFrom: Patrice Chotard <[email protected]>
On STMPE801/1801 datasheets, it's mentionned writing in interrupt status register has no effect, bits are cleared when reading.
--- drivers/gpio/gpio-stmpe.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/gpio/gpio-stmpe.c +8 -4
@@ -355,12 +355,16 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) stat &= ~(1 << bit); } -stmpe_reg_write (stmpe, statmsbreg + i, status[i]); - -/* Edge detect register is not present on 801 and 1801 */ -if (stmpe->partnum !=STMPE801 || stmpe->partnum !=STMPE1801 ) +/* +* interrupt status register write has no effect on +* 801 and 1801, bits are cleared when read. +* Edge detect register is not present on 801 and 1801 +*/ +if (stmpe->partnum !=STMPE801 || stmpe->partnum !=STMPE1801 ) { +stmpe_reg_write (stmpe, statmsbreg + i, status[i]);stmpe_reg_write (stmpe, stmpe->regs[STMPE_IDX_GPEDR_MSB ] + i, status[i]); + } }return IRQ_HANDLED ;
Signature · 1 line
1.9.1
Lee Jones
AppliedPATCH RESEND v2 4/10 gpio: stmpe: write int status register only when needed
Quoted 6 lines · patrice.chotard at st.com
From: Patrice Chotard <[email protected]>
On STMPE801/1801 datasheets, it's mentionned writing in interrupt status register has no effect, bits are cleared when reading.
Quoted 6 lines
Signed-off-by Amelie DELAUNAY <[email protected]>Signed-off-by Patrice Chotard <[email protected]>Reviewed-by Linus Walleij <[email protected]>--- drivers/gpio/gpio-stmpe.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
Applied, thanks.
Quoted 25 lines
drivers/gpio/gpio-stmpe.c +8
-4@@ -355,12 +355,16 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) stat &= ~(1 << bit); } -stmpe_reg_write (stmpe, statmsbreg + i, status[i]); - -/* Edge detect register is not present on 801 and 1801 */ -if (stmpe->partnum !=STMPE801 || stmpe->partnum !=STMPE1801 ) +/* +* interrupt status register write has no effect on +* 801 and 1801, bits are cleared when read. +* Edge detect register is not present on 801 and 1801 +*/ +if (stmpe->partnum !=STMPE801 || stmpe->partnum !=STMPE1801 ) { +stmpe_reg_write (stmpe, statmsbreg + i, status[i]);stmpe_reg_write (stmpe, stmpe->regs[STMPE_IDX_GPEDR_MSB ] + i, status[i]); + } }return IRQ_HANDLED ;
Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org ? Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
PATCH RESEND v2 5/10 mfd: stmpe: use generic bit mask name
In reply to patrice.chotard at st.comFrom: Patrice Chotard <[email protected]>
In order to prepare the ground to STMPE1600,
as STMPE1600's SYS_CTRL register has the same layout as STMPE801 variant, unify STMPExxx_REG_SYS_CTRL_RESET/INT_EN/INT_HI bit masks to more generic STMPE_SYS_CTRL_RESET/INT_EN/INT_HI
--- drivers/mfd/stmpe.c | 4 ++-- drivers/mfd/stmpe.h | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-)
drivers/mfd/stmpe.c +2 -2
@@ -1089,7 +1089,7 @@ static int stmpe_chip_init(struct stmpe *stmpe)if (stmpe->irq >=0 ) {if (id ==STMPE801_ID ) - icr =STMPE801_REG_SYS_CTRL_INT_EN ; + icr =STMPE_SYS_CTRL_INT_EN ;else icr =STMPE_ICR_LSB_GIM ;
@@ -1103,7 +1103,7 @@ static int stmpe_chip_init(struct stmpe *stmpe)if (irq_trigger ==IRQF_TRIGGER_RISING || irq_trigger ==IRQF_TRIGGER_HIGH ) {if (id ==STMPE801_ID ) - icr |=STMPE801_REG_SYS_CTRL_INT_HI ; + icr |=STMPE_SYS_CTRL_INT_HI ;else icr |=STMPE_ICR_LSB_HIGH ; }
drivers/mfd/stmpe.h +2 -4
@@ -105,6 +105,8 @@ int stmpe_remove(struct stmpe *stmpe);#define STMPE_ICR_LSB_GIM (1 << 0)#define STMPE_SYS_CTRL_RESET (1 << 7) +#define STMPE_SYS_CTRL_INT_EN (1 << 2) +#define STMPE_SYS_CTRL_INT_HI (1 << 0)/* * STMPE801
@@ -121,10 +123,6 @@ int stmpe_remove(struct stmpe *stmpe);#define STMPE801_REG_GPIO_SET_PIN 0x11#define STMPE801_REG_GPIO_DIR 0x12 -#define STMPE801_REG_SYS_CTRL_RESET (1 << 7) -#define STMPE801_REG_SYS_CTRL_INT_EN (1 << 2) -#define STMPE801_REG_SYS_CTRL_INT_HI (1 << 0) -/* * STMPE811 */
Signature · 1 line
1.9.1
Lee Jones
AppliedPATCH RESEND v2 5/10 mfd: stmpe: use generic bit mask name
Quoted 7 lines · patrice.chotard at st.com
From: Patrice Chotard <[email protected]>
In order to prepare the ground to STMPE1600,
as STMPE1600'sSYS_CTRLregister has the same layout as STMPE801 variant, unify STMPExxx_REG_SYS_CTRL_RESET/INT_EN/INT_HI bit masks to more generic STMPE_SYS_CTRL_RESET/INT_EN/INT_HI
Quoted 6 lines
Signed-off-by Patrice Chotard <[email protected]>Acked-by Lee Jones <[email protected]>--- drivers/mfd/stmpe.c | 4 ++-- drivers/mfd/stmpe.h | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-)
Applied, thanks.
Quoted 46 lines
drivers/mfd/stmpe.c +2
-2@@ -1089,7 +1089,7 @@ static int stmpe_chip_init(struct stmpe *stmpe)if (stmpe->irq >=0 ) {if (id ==STMPE801_ID ) - icr =STMPE801_REG_SYS_CTRL_INT_EN ; + icr =STMPE_SYS_CTRL_INT_EN ;else icr =STMPE_ICR_LSB_GIM ;@@ -1103,7 +1103,7 @@ static int stmpe_chip_init(struct stmpe *stmpe)if (irq_trigger ==IRQF_TRIGGER_RISING || irq_trigger ==IRQF_TRIGGER_HIGH ) {if (id ==STMPE801_ID ) - icr |=STMPE801_REG_SYS_CTRL_INT_HI ; + icr |=STMPE_SYS_CTRL_INT_HI ;else icr |=STMPE_ICR_LSB_HIGH ; }drivers/mfd/stmpe.h +2
-4@@ -105,6 +105,8 @@ int stmpe_remove(struct stmpe *stmpe);#define STMPE_ICR_LSB_GIM (1 << 0)#define STMPE_SYS_CTRL_RESET (1 << 7) +#define STMPE_SYS_CTRL_INT_EN (1 << 2) +#define STMPE_SYS_CTRL_INT_HI (1 << 0)/* * STMPE801 @@ -121,10 +123,6 @@ int stmpe_remove(struct stmpe *stmpe);#define STMPE801_REG_GPIO_SET_PIN 0x11#define STMPE801_REG_GPIO_DIR 0x12 -#define STMPE801_REG_SYS_CTRL_RESET (1 << 7) -#define STMPE801_REG_SYS_CTRL_INT_EN (1 << 2) -#define STMPE801_REG_SYS_CTRL_INT_HI (1 << 0) -/* * STMPE811 */
Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org ? Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
PATCH RESEND v2 6/10 mfd: stmpe: rework registers access
In reply to patrice.chotard at st.comFrom: Patrice Chotard <[email protected]>
this update allows to use registers map as following :
regs[reg_index + offset] instead of regs[reg_index] + offset
This makes code clearer and will facilitate the addition of STMPE1600 on which LSB and MSB registers are respectively located at addr and addr + 1. Despite for all others STMPE variant, LSB and MSB registers are respectively located in reverse order at addr + 1 and addr.
For variant which have 3 registers's bank, we use LSB,CSB and MSB indexes which contains respectively LSB (or LOW), CSB (or MID) and MSB (or HIGH) register addresses (STMPE1801/STMPE24xx).
For variant which have 2 registers's bank, we use LSB and CSB indexes only. In this case the CSB index contains the MSB regs address (STMPE 1601).
--- drivers/mfd/stmpe.c | 48 ++++++++++++++++++++++++++++++++++++++++++---- drivers/mfd/stmpe.h | 49 +++++++++++++++++++++++++++++++++++++++++------ include/linux/mfd/stmpe.h | 18 +++++++++++++++++ 3 files changed, 105 insertions(+), 10 deletions(-)
drivers/mfd/stmpe.c +44 -4
@@ -462,7 +462,7 @@ static const u8 stmpe811_regs[] = { [STMPE_IDX_GPAFR_U_MSB] = STMPE811_REG_GPIO_AF, [STMPE_IDX_IEGPIOR_LSB] = STMPE811_REG_GPIO_INT_EN, [STMPE_IDX_ISGPIOR_MSB] = STMPE811_REG_GPIO_INT_STA, - [STMPE_IDX_GPEDR_MSB] = STMPE811_REG_GPIO_ED, + [STMPE_IDX_GPEDR_LSB] = STMPE811_REG_GPIO_ED, };static struct stmpe_variant_block stmpe811_blocks[] = {
@@ -540,19 +540,28 @@ static const u8 stmpe1601_regs[] = { [STMPE_IDX_SYS_CTRL] = STMPE1601_REG_SYS_CTRL, [STMPE_IDX_SYS_CTRL2] = STMPE1601_REG_SYS_CTRL2, [STMPE_IDX_ICR_LSB] = STMPE1601_REG_ICR_LSB, + [STMPE_IDX_IER_MSB] = STMPE1601_REG_IER_MSB, [STMPE_IDX_IER_LSB] = STMPE1601_REG_IER_LSB, [STMPE_IDX_ISR_MSB] = STMPE1601_REG_ISR_MSB, [STMPE_IDX_GPMR_LSB] = STMPE1601_REG_GPIO_MP_LSB, + [STMPE_IDX_GPMR_CSB] = STMPE1601_REG_GPIO_MP_MSB, [STMPE_IDX_GPSR_LSB] = STMPE1601_REG_GPIO_SET_LSB, + [STMPE_IDX_GPSR_CSB] = STMPE1601_REG_GPIO_SET_MSB, [STMPE_IDX_GPCR_LSB] = STMPE1601_REG_GPIO_CLR_LSB, + [STMPE_IDX_GPCR_CSB] = STMPE1601_REG_GPIO_CLR_MSB, [STMPE_IDX_GPDR_LSB] = STMPE1601_REG_GPIO_SET_DIR_LSB, + [STMPE_IDX_GPDR_CSB] = STMPE1601_REG_GPIO_SET_DIR_MSB, + [STMPE_IDX_GPEDR_LSB] = STMPE1601_REG_GPIO_ED_LSB, + [STMPE_IDX_GPEDR_CSB] = STMPE1601_REG_GPIO_ED_MSB, [STMPE_IDX_GPRER_LSB] = STMPE1601_REG_GPIO_RE_LSB, + [STMPE_IDX_GPRER_CSB] = STMPE1601_REG_GPIO_RE_MSB, [STMPE_IDX_GPFER_LSB] = STMPE1601_REG_GPIO_FE_LSB, + [STMPE_IDX_GPFER_CSB] = STMPE1601_REG_GPIO_FE_MSB, [STMPE_IDX_GPPUR_LSB] = STMPE1601_REG_GPIO_PU_LSB, [STMPE_IDX_GPAFR_U_MSB] = STMPE1601_REG_GPIO_AF_U_MSB, [STMPE_IDX_IEGPIOR_LSB] = STMPE1601_REG_INT_EN_GPIO_MASK_LSB, + [STMPE_IDX_IEGPIOR_CSB] = STMPE1601_REG_INT_EN_GPIO_MASK_MSB, [STMPE_IDX_ISGPIOR_MSB] = STMPE1601_REG_INT_STA_GPIO_MSB, - [STMPE_IDX_GPEDR_MSB] = STMPE1601_REG_GPIO_ED_MSB, };static struct stmpe_variant_block stmpe1601_blocks[] = {
@@ -698,14 +707,28 @@ static const u8 stmpe1801_regs[] = { [STMPE_IDX_IER_LSB] = STMPE1801_REG_INT_EN_MASK_LOW, [STMPE_IDX_ISR_LSB] = STMPE1801_REG_INT_STA_LOW, [STMPE_IDX_GPMR_LSB] = STMPE1801_REG_GPIO_MP_LOW, + [STMPE_IDX_GPMR_CSB] = STMPE1801_REG_GPIO_MP_MID, + [STMPE_IDX_GPMR_MSB] = STMPE1801_REG_GPIO_MP_HIGH, [STMPE_IDX_GPSR_LSB] = STMPE1801_REG_GPIO_SET_LOW, + [STMPE_IDX_GPSR_CSB] = STMPE1801_REG_GPIO_SET_MID, + [STMPE_IDX_GPSR_MSB] = STMPE1801_REG_GPIO_SET_HIGH, [STMPE_IDX_GPCR_LSB] = STMPE1801_REG_GPIO_CLR_LOW, + [STMPE_IDX_GPCR_CSB] = STMPE1801_REG_GPIO_CLR_MID, + [STMPE_IDX_GPCR_MSB] = STMPE1801_REG_GPIO_CLR_HIGH, [STMPE_IDX_GPDR_LSB] = STMPE1801_REG_GPIO_SET_DIR_LOW, + [STMPE_IDX_GPDR_CSB] = STMPE1801_REG_GPIO_SET_DIR_MID, + [STMPE_IDX_GPDR_MSB] = STMPE1801_REG_GPIO_SET_DIR_HIGH, [STMPE_IDX_GPRER_LSB] = STMPE1801_REG_GPIO_RE_LOW, + [STMPE_IDX_GPRER_CSB] = STMPE1801_REG_GPIO_RE_MID, + [STMPE_IDX_GPRER_MSB] = STMPE1801_REG_GPIO_RE_HIGH, [STMPE_IDX_GPFER_LSB] = STMPE1801_REG_GPIO_FE_LOW, + [STMPE_IDX_GPFER_CSB] = STMPE1801_REG_GPIO_FE_MID, + [STMPE_IDX_GPFER_MSB] = STMPE1801_REG_GPIO_FE_HIGH, [STMPE_IDX_GPPUR_LSB] = STMPE1801_REG_GPIO_PULL_UP_LOW, [STMPE_IDX_IEGPIOR_LSB] = STMPE1801_REG_INT_EN_GPIO_MASK_LOW, - [STMPE_IDX_ISGPIOR_LSB] = STMPE1801_REG_INT_STA_GPIO_LOW, + [STMPE_IDX_IEGPIOR_CSB] = STMPE1801_REG_INT_EN_GPIO_MASK_MID, + [STMPE_IDX_IEGPIOR_MSB] = STMPE1801_REG_INT_EN_GPIO_MASK_HIGH, + [STMPE_IDX_ISGPIOR_MSB] = STMPE1801_REG_INT_STA_GPIO_HIGH, };static struct stmpe_variant_block stmpe1801_blocks[] = {
@@ -790,19 +813,36 @@ static const u8 stmpe24xx_regs[] = { [STMPE_IDX_SYS_CTRL] = STMPE24XX_REG_SYS_CTRL, [STMPE_IDX_SYS_CTRL2] = STMPE24XX_REG_SYS_CTRL2, [STMPE_IDX_ICR_LSB] = STMPE24XX_REG_ICR_LSB, + [STMPE_IDX_IER_MSB] = STMPE24XX_REG_IER_MSB, [STMPE_IDX_IER_LSB] = STMPE24XX_REG_IER_LSB, [STMPE_IDX_ISR_MSB] = STMPE24XX_REG_ISR_MSB, [STMPE_IDX_GPMR_LSB] = STMPE24XX_REG_GPMR_LSB, + [STMPE_IDX_GPMR_CSB] = STMPE24XX_REG_GPMR_CSB, + [STMPE_IDX_GPMR_MSB] = STMPE24XX_REG_GPMR_MSB, [STMPE_IDX_GPSR_LSB] = STMPE24XX_REG_GPSR_LSB, + [STMPE_IDX_GPSR_CSB] = STMPE24XX_REG_GPSR_CSB, + [STMPE_IDX_GPSR_MSB] = STMPE24XX_REG_GPSR_MSB, [STMPE_IDX_GPCR_LSB] = STMPE24XX_REG_GPCR_LSB, + [STMPE_IDX_GPCR_CSB] = STMPE24XX_REG_GPCR_CSB, + [STMPE_IDX_GPCR_MSB] = STMPE24XX_REG_GPCR_MSB, [STMPE_IDX_GPDR_LSB] = STMPE24XX_REG_GPDR_LSB, + [STMPE_IDX_GPDR_CSB] = STMPE24XX_REG_GPDR_CSB, + [STMPE_IDX_GPDR_MSB] = STMPE24XX_REG_GPDR_MSB, [STMPE_IDX_GPRER_LSB] = STMPE24XX_REG_GPRER_LSB, + [STMPE_IDX_GPRER_CSB] = STMPE24XX_REG_GPRER_CSB, + [STMPE_IDX_GPRER_MSB] = STMPE24XX_REG_GPRER_MSB, [STMPE_IDX_GPFER_LSB] = STMPE24XX_REG_GPFER_LSB, + [STMPE_IDX_GPFER_CSB] = STMPE24XX_REG_GPFER_CSB, + [STMPE_IDX_GPFER_MSB] = STMPE24XX_REG_GPFER_MSB, [STMPE_IDX_GPPUR_LSB] = STMPE24XX_REG_GPPUR_LSB, [STMPE_IDX_GPPDR_LSB] = STMPE24XX_REG_GPPDR_LSB, [STMPE_IDX_GPAFR_U_MSB] = STMPE24XX_REG_GPAFR_U_MSB, [STMPE_IDX_IEGPIOR_LSB] = STMPE24XX_REG_IEGPIOR_LSB, + [STMPE_IDX_IEGPIOR_CSB] = STMPE24XX_REG_IEGPIOR_CSB, + [STMPE_IDX_IEGPIOR_MSB] = STMPE24XX_REG_IEGPIOR_MSB, [STMPE_IDX_ISGPIOR_MSB] = STMPE24XX_REG_ISGPIOR_MSB, + [STMPE_IDX_GPEDR_LSB] = STMPE24XX_REG_GPEDR_LSB, + [STMPE_IDX_GPEDR_CSB] = STMPE24XX_REG_GPEDR_CSB, [STMPE_IDX_GPEDR_MSB] = STMPE24XX_REG_GPEDR_MSB, };
@@ -977,7 +1017,7 @@ static void stmpe_irq_sync_unlock(struct irq_data *data)continue ; stmpe->oldier[i] = new; -stmpe_reg_write (stmpe, stmpe->regs[STMPE_IDX_IER_LSB ] - i, new); +stmpe_reg_write (stmpe, stmpe->regs[STMPE_IDX_IER_LSB + i], new); }mutex_unlock (&stmpe->irq_lock);
drivers/mfd/stmpe.h +43 -6
85 lines not on this page · raw message
include/linux/mfd/stmpe.h +18 -0
@@ -43,20 +43,38 @@ enum {STMPE_IDX_SYS_CTRL2 ,STMPE_IDX_ICR_LSB ,STMPE_IDX_IER_LSB , +STMPE_IDX_IER_MSB ,STMPE_IDX_ISR_LSB ,STMPE_IDX_ISR_MSB ,STMPE_IDX_GPMR_LSB , +STMPE_IDX_GPMR_CSB , +STMPE_IDX_GPMR_MSB ,STMPE_IDX_GPSR_LSB , +STMPE_IDX_GPSR_CSB , +STMPE_IDX_GPSR_MSB ,STMPE_IDX_GPCR_LSB , +STMPE_IDX_GPCR_CSB , +STMPE_IDX_GPCR_MSB ,STMPE_IDX_GPDR_LSB , +STMPE_IDX_GPDR_CSB , +STMPE_IDX_GPDR_MSB , +STMPE_IDX_GPEDR_LSB , +STMPE_IDX_GPEDR_CSB ,STMPE_IDX_GPEDR_MSB ,STMPE_IDX_GPRER_LSB , +STMPE_IDX_GPRER_CSB , +STMPE_IDX_GPRER_MSB ,STMPE_IDX_GPFER_LSB , +STMPE_IDX_GPFER_CSB , +STMPE_IDX_GPFER_MSB ,STMPE_IDX_GPPUR_LSB ,STMPE_IDX_GPPDR_LSB ,STMPE_IDX_GPAFR_U_MSB ,STMPE_IDX_IEGPIOR_LSB , +STMPE_IDX_IEGPIOR_CSB , +STMPE_IDX_IEGPIOR_MSB ,STMPE_IDX_ISGPIOR_LSB , +STMPE_IDX_ISGPIOR_CSB ,STMPE_IDX_ISGPIOR_MSB , STMPE_IDX_MAX, };
Signature · 1 line
1.9.1
Lee Jones
AppliedPATCH RESEND v2 6/10 mfd: stmpe: rework registers access
Quoted 17 lines · patrice.chotard at st.com
From: Patrice Chotard <[email protected]>
this update allows to use registers map as following :
regs[reg_index + offset] instead of regs[reg_index] + offsetThis makes code clearer and will facilitate the addition of STMPE1600 on which LSB and MSB registers are respectively located at addr and addr + 1. Despite for all others STMPE variant, LSB and MSB registers are respectively located in reverse order at addr + 1 and addr.
For variant which have 3 registers's bank, we use LSB,CSB and MSB indexes which contains respectively LSB (or LOW), CSB (or MID) and MSB (or HIGH) register addresses (STMPE1801/STMPE24xx).
For variant which have 2 registers's bank, we use LSB and CSB indexes only. In this case the CSB index contains the MSB regs address (STMPE 1601).
Quoted 8 lines
Signed-off-by Patrice Chotard <[email protected]>Reviewed-by Linus Walleij <[email protected]>--- drivers/mfd/stmpe.c | 48 ++++++++++++++++++++++++++++++++++++++++++---- drivers/mfd/stmpe.h | 49 +++++++++++++++++++++++++++++++++++++++++------ include/linux/mfd/stmpe.h | 18 +++++++++++++++++ 3 files changed, 105 insertions(+), 10 deletions(-)
Applied, thanks.
Quoted 253 lines
drivers/mfd/stmpe.c +44
-4@@ -462,7 +462,7 @@ static const u8 stmpe811_regs[] = { [STMPE_IDX_GPAFR_U_MSB] = STMPE811_REG_GPIO_AF, [STMPE_IDX_IEGPIOR_LSB] = STMPE811_REG_GPIO_INT_EN, [STMPE_IDX_ISGPIOR_MSB] = STMPE811_REG_GPIO_INT_STA, - [STMPE_IDX_GPEDR_MSB] = STMPE811_REG_GPIO_ED, + [STMPE_IDX_GPEDR_LSB] = STMPE811_REG_GPIO_ED, };static struct stmpe_variant_block stmpe811_blocks[] = {@@ -540,19 +540,28 @@ static const u8 stmpe1601_regs[] = { [STMPE_IDX_SYS_CTRL] = STMPE1601_REG_SYS_CTRL, [STMPE_IDX_SYS_CTRL2] = STMPE1601_REG_SYS_CTRL2, [STMPE_IDX_ICR_LSB] = STMPE1601_REG_ICR_LSB, + [STMPE_IDX_IER_MSB] = STMPE1601_REG_IER_MSB, [STMPE_IDX_IER_LSB] = STMPE1601_REG_IER_LSB, [STMPE_IDX_ISR_MSB] = STMPE1601_REG_ISR_MSB, [STMPE_IDX_GPMR_LSB] = STMPE1601_REG_GPIO_MP_LSB, + [STMPE_IDX_GPMR_CSB] = STMPE1601_REG_GPIO_MP_MSB, [STMPE_IDX_GPSR_LSB] = STMPE1601_REG_GPIO_SET_LSB, + [STMPE_IDX_GPSR_CSB] = STMPE1601_REG_GPIO_SET_MSB, [STMPE_IDX_GPCR_LSB] = STMPE1601_REG_GPIO_CLR_LSB, + [STMPE_IDX_GPCR_CSB] = STMPE1601_REG_GPIO_CLR_MSB, [STMPE_IDX_GPDR_LSB] = STMPE1601_REG_GPIO_SET_DIR_LSB, + [STMPE_IDX_GPDR_CSB] = STMPE1601_REG_GPIO_SET_DIR_MSB, + [STMPE_IDX_GPEDR_LSB] = STMPE1601_REG_GPIO_ED_LSB, + [STMPE_IDX_GPEDR_CSB] = STMPE1601_REG_GPIO_ED_MSB, [STMPE_IDX_GPRER_LSB] = STMPE1601_REG_GPIO_RE_LSB, + [STMPE_IDX_GPRER_CSB] = STMPE1601_REG_GPIO_RE_MSB, [STMPE_IDX_GPFER_LSB] = STMPE1601_REG_GPIO_FE_LSB, + [STMPE_IDX_GPFER_CSB] = STMPE1601_REG_GPIO_FE_MSB, [STMPE_IDX_GPPUR_LSB] = STMPE1601_REG_GPIO_PU_LSB, [STMPE_IDX_GPAFR_U_MSB] = STMPE1601_REG_GPIO_AF_U_MSB, [STMPE_IDX_IEGPIOR_LSB] = STMPE1601_REG_INT_EN_GPIO_MASK_LSB, + [STMPE_IDX_IEGPIOR_CSB] = STMPE1601_REG_INT_EN_GPIO_MASK_MSB, [STMPE_IDX_ISGPIOR_MSB] = STMPE1601_REG_INT_STA_GPIO_MSB, - [STMPE_IDX_GPEDR_MSB] = STMPE1601_REG_GPIO_ED_MSB, };static struct stmpe_variant_block stmpe1601_blocks[] = {@@ -698,14 +707,28 @@ static const u8 stmpe1801_regs[] = { [STMPE_IDX_IER_LSB] = STMPE1801_REG_INT_EN_MASK_LOW, [STMPE_IDX_ISR_LSB] = STMPE1801_REG_INT_STA_LOW, [STMPE_IDX_GPMR_LSB] = STMPE1801_REG_GPIO_MP_LOW, + [STMPE_IDX_GPMR_CSB] = STMPE1801_REG_GPIO_MP_MID, + [STMPE_IDX_GPMR_MSB] = STMPE1801_REG_GPIO_MP_HIGH, [STMPE_IDX_GPSR_LSB] = STMPE1801_REG_GPIO_SET_LOW, + [STMPE_IDX_GPSR_CSB] = STMPE1801_REG_GPIO_SET_MID, + [STMPE_IDX_GPSR_MSB] = STMPE1801_REG_GPIO_SET_HIGH, [STMPE_IDX_GPCR_LSB] = STMPE1801_REG_GPIO_CLR_LOW, + [STMPE_IDX_GPCR_CSB] = STMPE1801_REG_GPIO_CLR_MID, + [STMPE_IDX_GPCR_MSB] = STMPE1801_REG_GPIO_CLR_HIGH, [STMPE_IDX_GPDR_LSB] = STMPE1801_REG_GPIO_SET_DIR_LOW, + [STMPE_IDX_GPDR_CSB] = STMPE1801_REG_GPIO_SET_DIR_MID, + [STMPE_IDX_GPDR_MSB] = STMPE1801_REG_GPIO_SET_DIR_HIGH, [STMPE_IDX_GPRER_LSB] = STMPE1801_REG_GPIO_RE_LOW, + [STMPE_IDX_GPRER_CSB] = STMPE1801_REG_GPIO_RE_MID, + [STMPE_IDX_GPRER_MSB] = STMPE1801_REG_GPIO_RE_HIGH, [STMPE_IDX_GPFER_LSB] = STMPE1801_REG_GPIO_FE_LOW, + [STMPE_IDX_GPFER_CSB] = STMPE1801_REG_GPIO_FE_MID, + [STMPE_IDX_GPFER_MSB] = STMPE1801_REG_GPIO_FE_HIGH, [STMPE_IDX_GPPUR_LSB] = STMPE1801_REG_GPIO_PULL_UP_LOW, [STMPE_IDX_IEGPIOR_LSB] = STMPE1801_REG_INT_EN_GPIO_MASK_LOW, - [STMPE_IDX_ISGPIOR_LSB] = STMPE1801_REG_INT_STA_GPIO_LOW, + [STMPE_IDX_IEGPIOR_CSB] = STMPE1801_REG_INT_EN_GPIO_MASK_MID, + [STMPE_IDX_IEGPIOR_MSB] = STMPE1801_REG_INT_EN_GPIO_MASK_HIGH, + [STMPE_IDX_ISGPIOR_MSB] = STMPE1801_REG_INT_STA_GPIO_HIGH, };static struct stmpe_variant_block stmpe1801_blocks[] = {@@ -790,19 +813,36 @@ static const u8 stmpe24xx_regs[] = { [STMPE_IDX_SYS_CTRL] = STMPE24XX_REG_SYS_CTRL, [STMPE_IDX_SYS_CTRL2] = STMPE24XX_REG_SYS_CTRL2, [STMPE_IDX_ICR_LSB] = STMPE24XX_REG_ICR_LSB, + [STMPE_IDX_IER_MSB] = STMPE24XX_REG_IER_MSB, [STMPE_IDX_IER_LSB] = STMPE24XX_REG_IER_LSB, [STMPE_IDX_ISR_MSB] = STMPE24XX_REG_ISR_MSB, [STMPE_IDX_GPMR_LSB] = STMPE24XX_REG_GPMR_LSB, + [STMPE_IDX_GPMR_CSB] = STMPE24XX_REG_GPMR_CSB, + [STMPE_IDX_GPMR_MSB] = STMPE24XX_REG_GPMR_MSB, [STMPE_IDX_GPSR_LSB] = STMPE24XX_REG_GPSR_LSB, + [STMPE_IDX_GPSR_CSB] = STMPE24XX_REG_GPSR_CSB, + [STMPE_IDX_GPSR_MSB] = STMPE24XX_REG_GPSR_MSB, [STMPE_IDX_GPCR_LSB] = STMPE24XX_REG_GPCR_LSB, + [STMPE_IDX_GPCR_CSB] = STMPE24XX_REG_GPCR_CSB, + [STMPE_IDX_GPCR_MSB] = STMPE24XX_REG_GPCR_MSB, [STMPE_IDX_GPDR_LSB] = STMPE24XX_REG_GPDR_LSB, + [STMPE_IDX_GPDR_CSB] = STMPE24XX_REG_GPDR_CSB, + [STMPE_IDX_GPDR_MSB] = STMPE24XX_REG_GPDR_MSB, [STMPE_IDX_GPRER_LSB] = STMPE24XX_REG_GPRER_LSB, + [STMPE_IDX_GPRER_CSB] = STMPE24XX_REG_GPRER_CSB, + [STMPE_IDX_GPRER_MSB] = STMPE24XX_REG_GPRER_MSB, [STMPE_IDX_GPFER_LSB] = STMPE24XX_REG_GPFER_LSB, + [STMPE_IDX_GPFER_CSB] = STMPE24XX_REG_GPFER_CSB, + [STMPE_IDX_GPFER_MSB] = STMPE24XX_REG_GPFER_MSB, [STMPE_IDX_GPPUR_LSB] = STMPE24XX_REG_GPPUR_LSB, [STMPE_IDX_GPPDR_LSB] = STMPE24XX_REG_GPPDR_LSB, [STMPE_IDX_GPAFR_U_MSB] = STMPE24XX_REG_GPAFR_U_MSB, [STMPE_IDX_IEGPIOR_LSB] = STMPE24XX_REG_IEGPIOR_LSB, + [STMPE_IDX_IEGPIOR_CSB] = STMPE24XX_REG_IEGPIOR_CSB, + [STMPE_IDX_IEGPIOR_MSB] = STMPE24XX_REG_IEGPIOR_MSB, [STMPE_IDX_ISGPIOR_MSB] = STMPE24XX_REG_ISGPIOR_MSB, + [STMPE_IDX_GPEDR_LSB] = STMPE24XX_REG_GPEDR_LSB, + [STMPE_IDX_GPEDR_CSB] = STMPE24XX_REG_GPEDR_CSB, [STMPE_IDX_GPEDR_MSB] = STMPE24XX_REG_GPEDR_MSB, };@@ -977,7 +1017,7 @@ static void stmpe_irq_sync_unlock(struct irq_data *data)continue ; stmpe->oldier[i] = new; -stmpe_reg_write (stmpe, stmpe->regs[STMPE_IDX_IER_LSB ] - i, new); +stmpe_reg_write (stmpe, stmpe->regs[STMPE_IDX_IER_LSB + i], new); }mutex_unlock (&stmpe->irq_lock);drivers/mfd/stmpe.h +43
-6@@ -179,19 +179,32 @@ int stmpe_remove(struct stmpe *stmpe);#define STMPE1601_REG_SYS_CTRL 0x02#define STMPE1601_REG_SYS_CTRL2 0x03 +#define STMPE1601_REG_ICR_MSB 0x10#define STMPE1601_REG_ICR_LSB 0x11 +#define STMPE1601_REG_IER_MSB 0x12#define STMPE1601_REG_IER_LSB 0x13#define STMPE1601_REG_ISR_MSB 0x14 -#define STMPE1601_REG_CHIP_ID 0x80 +#define STMPE1601_REG_ISR_LSB 0x15 +#define STMPE1601_REG_INT_EN_GPIO_MASK_MSB 0x16#define STMPE1601_REG_INT_EN_GPIO_MASK_LSB 0x17#define STMPE1601_REG_INT_STA_GPIO_MSB 0x18 -#define STMPE1601_REG_GPIO_MP_LSB 0x87 +#define STMPE1601_REG_INT_STA_GPIO_LSB 0x19 +#define STMPE1601_REG_CHIP_ID 0x80 +#define STMPE1601_REG_GPIO_SET_MSB 0x82#define STMPE1601_REG_GPIO_SET_LSB 0x83 +#define STMPE1601_REG_GPIO_CLR_MSB 0x84#define STMPE1601_REG_GPIO_CLR_LSB 0x85 +#define STMPE1601_REG_GPIO_MP_MSB 0x86 +#define STMPE1601_REG_GPIO_MP_LSB 0x87 +#define STMPE1601_REG_GPIO_SET_DIR_MSB 0x88#define STMPE1601_REG_GPIO_SET_DIR_LSB 0x89#define STMPE1601_REG_GPIO_ED_MSB 0x8A +#define STMPE1601_REG_GPIO_ED_LSB 0x8B +#define STMPE1601_REG_GPIO_RE_MSB 0x8C#define STMPE1601_REG_GPIO_RE_LSB 0x8D +#define STMPE1601_REG_GPIO_FE_MSB 0x8E#define STMPE1601_REG_GPIO_FE_LSB 0x8F +#define STMPE1601_REG_GPIO_PU_MSB 0x90#define STMPE1601_REG_GPIO_PU_LSB 0x91#define STMPE1601_REG_GPIO_AF_U_MSB 0x92@@ -267,23 +280,47 @@ int stmpe_remove(struct stmpe *stmpe);#define STMPE24XX_REG_SYS_CTRL 0x02#define STMPE24XX_REG_SYS_CTRL2 0x03 +#define STMPE24XX_REG_ICR_MSB 0x10#define STMPE24XX_REG_ICR_LSB 0x11 +#define STMPE24XX_REG_IER_MSB 0x12#define STMPE24XX_REG_IER_LSB 0x13#define STMPE24XX_REG_ISR_MSB 0x14 -#define STMPE24XX_REG_CHIP_ID 0x80 +#define STMPE24XX_REG_ISR_LSB 0x15 +#define STMPE24XX_REG_IEGPIOR_MSB 0x16 +#define STMPE24XX_REG_IEGPIOR_CSB 0x17#define STMPE24XX_REG_IEGPIOR_LSB 0x18#define STMPE24XX_REG_ISGPIOR_MSB 0x19 -#define STMPE24XX_REG_GPMR_LSB 0xA4 +#define STMPE24XX_REG_ISGPIOR_CSB 0x1A +#define STMPE24XX_REG_ISGPIOR_LSB 0x1B +#define STMPE24XX_REG_CHIP_ID 0x80 +#define STMPE24XX_REG_GPSR_MSB 0x83 +#define STMPE24XX_REG_GPSR_CSB 0x84#define STMPE24XX_REG_GPSR_LSB 0x85 +#define STMPE24XX_REG_GPCR_MSB 0x86 +#define STMPE24XX_REG_GPCR_CSB 0x87#define STMPE24XX_REG_GPCR_LSB 0x88 +#define STMPE24XX_REG_GPDR_MSB 0x89 +#define STMPE24XX_REG_GPDR_CSB 0x8A#define STMPE24XX_REG_GPDR_LSB 0x8B#define STMPE24XX_REG_GPEDR_MSB 0x8C +#define STMPE24XX_REG_GPEDR_CSB 0x8D +#define STMPE24XX_REG_GPEDR_LSB 0x8E +#define STMPE24XX_REG_GPRER_MSB 0x8F +#define STMPE24XX_REG_GPRER_CSB 0x90#define STMPE24XX_REG_GPRER_LSB 0x91 +#define STMPE24XX_REG_GPFER_MSB 0x92 +#define STMPE24XX_REG_GPFER_CSB 0x93#define STMPE24XX_REG_GPFER_LSB 0x94 +#define STMPE24XX_REG_GPPUR_MSB 0x95 +#define STMPE24XX_REG_GPPUR_CSB 0x96#define STMPE24XX_REG_GPPUR_LSB 0x97 -#define STMPE24XX_REG_GPPDR_LSB 0x9a +#define STMPE24XX_REG_GPPDR_MSB 0x98 +#define STMPE24XX_REG_GPPDR_CSB 0x99 +#define STMPE24XX_REG_GPPDR_LSB 0x9A#define STMPE24XX_REG_GPAFR_U_MSB 0x9B - +#define STMPE24XX_REG_GPMR_MSB 0xA2 +#define STMPE24XX_REG_GPMR_CSB 0xA3 +#define STMPE24XX_REG_GPMR_LSB 0xA4#define STMPE24XX_SYS_CTRL_ENABLE_GPIO (1 << 3)#define STMPE24XX_SYSCON_ENABLE_PWM (1 << 2)#define STMPE24XX_SYS_CTRL_ENABLE_KPC (1 << 1)include/linux/mfd/stmpe.h +18
-0@@ -43,20 +43,38 @@ enum {STMPE_IDX_SYS_CTRL2 ,STMPE_IDX_ICR_LSB ,STMPE_IDX_IER_LSB , +STMPE_IDX_IER_MSB ,STMPE_IDX_ISR_LSB ,STMPE_IDX_ISR_MSB ,STMPE_IDX_GPMR_LSB , +STMPE_IDX_GPMR_CSB , +STMPE_IDX_GPMR_MSB ,STMPE_IDX_GPSR_LSB , +STMPE_IDX_GPSR_CSB , +STMPE_IDX_GPSR_MSB ,STMPE_IDX_GPCR_LSB , +STMPE_IDX_GPCR_CSB , +STMPE_IDX_GPCR_MSB ,STMPE_IDX_GPDR_LSB , +STMPE_IDX_GPDR_CSB , +STMPE_IDX_GPDR_MSB , +STMPE_IDX_GPEDR_LSB , +STMPE_IDX_GPEDR_CSB ,STMPE_IDX_GPEDR_MSB ,STMPE_IDX_GPRER_LSB , +STMPE_IDX_GPRER_CSB , +STMPE_IDX_GPRER_MSB ,STMPE_IDX_GPFER_LSB , +STMPE_IDX_GPFER_CSB , +STMPE_IDX_GPFER_MSB ,STMPE_IDX_GPPUR_LSB ,STMPE_IDX_GPPDR_LSB ,STMPE_IDX_GPAFR_U_MSB ,STMPE_IDX_IEGPIOR_LSB , +STMPE_IDX_IEGPIOR_CSB , +STMPE_IDX_IEGPIOR_MSB ,STMPE_IDX_ISGPIOR_LSB , +STMPE_IDX_ISGPIOR_CSB ,STMPE_IDX_ISGPIOR_MSB , STMPE_IDX_MAX, };
Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org ? Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
PATCH RESEND v2 7/10 gpio: stmpe: rework registers access
In reply to patrice.chotard at st.comFrom: Patrice Chotard <[email protected]>
This update allows to use registers map as following :
regs[reg_index + offset] instead of regs[reg_index] + offset
This makes code clearer and will facilitate the addition of STMPE1600 on which LSB and MSB registers are respectively located at addr and addr + 1. Despite for all others STMPE variant, LSB and MSB registers are respectively located in reverse order at addr + 1 and addr.
For variant which have 3 registers's bank, we use LSB,CSB and MSB indexes which contains respectively LSB (or LOW), CSB (or MID) and MSB (or HIGH) register addresses (STMPE1801/STMPE24xx).
For variant which have 2 registers's bank, we use LSB and CSB indexes only. In this case the CSB index contains the MSB regs address (STMPE 1601).
--- drivers/gpio/gpio-stmpe.c | 48 ++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-)
drivers/gpio/gpio-stmpe.c +27 -21
@@ -21,6 +21,8 @@*/ enum {REG_RE ,REG_FE ,REG_IE }; +enum {LSB ,CSB ,MSB }; +#define CACHE_NR_REGS 3/* No variant has more than 24 GPIOs */ #define CACHE_NR_BANKS (24 / 8)
@@ -40,7 +42,7 @@ static int stmpe_gpio_get(struct gpio_chip *chip, unsigned offset) {struct stmpe_gpio *stmpe_gpio =gpiochip_get_data (chip);struct stmpe *stmpe = stmpe_gpio->stmpe; -u8 reg = stmpe->regs[STMPE_IDX_GPMR_LSB ] - (offset /8 ); +u8 reg = stmpe->regs[STMPE_IDX_GPMR_LSB + (offset /8 )];u8 mask =1 << (offset %8 );int ret;
@@ -56,7 +58,7 @@ static void stmpe_gpio_set(struct gpio_chip *chip, unsigned offset, int val)struct stmpe_gpio *stmpe_gpio =gpiochip_get_data (chip);struct stmpe *stmpe = stmpe_gpio->stmpe;int which = val ?STMPE_IDX_GPSR_LSB :STMPE_IDX_GPCR_LSB ; -u8 reg = stmpe->regs[which] - (offset /8 ); +u8 reg = stmpe->regs[which + (offset /8 )];u8 mask =1 << (offset %8 );/*
@@ -74,7 +76,7 @@ static int stmpe_gpio_direction_output(struct gpio_chip *chip, {struct stmpe_gpio *stmpe_gpio =gpiochip_get_data (chip);struct stmpe *stmpe = stmpe_gpio->stmpe; -u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB ] - (offset /8 ); +u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB + (offset /8 )];u8 mask =1 << (offset %8 );stmpe_gpio_set (chip, offset, val);
@@ -87,7 +89,7 @@ static int stmpe_gpio_direction_input(struct gpio_chip *chip, {struct stmpe_gpio *stmpe_gpio =gpiochip_get_data (chip);struct stmpe *stmpe = stmpe_gpio->stmpe; -u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB ] - (offset /8 ); +u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB + (offset /8 )];u8 mask =1 << (offset %8 );return stmpe_set_bits (stmpe, reg, mask,0 );
@@ -157,10 +159,16 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d)struct stmpe_gpio *stmpe_gpio =gpiochip_get_data (gc);struct stmpe *stmpe = stmpe_gpio->stmpe;int num_banks =DIV_ROUND_UP (stmpe->num_gpios,8 ); -static const u8 regmap[] = { - [REG_RE ] =STMPE_IDX_GPRER_LSB , - [REG_FE ] =STMPE_IDX_GPFER_LSB , - [REG_IE ] =STMPE_IDX_IEGPIOR_LSB , +static const u8 regmap[CACHE_NR_REGS ][CACHE_NR_BANKS ] = { + [REG_RE ][LSB ] =STMPE_IDX_GPRER_LSB , + [REG_RE ][CSB ] =STMPE_IDX_GPRER_CSB , + [REG_RE ][MSB ] =STMPE_IDX_GPRER_MSB , + [REG_FE ][LSB ] =STMPE_IDX_GPFER_LSB , + [REG_FE ][CSB ] =STMPE_IDX_GPFER_CSB , + [REG_FE ][MSB ] =STMPE_IDX_GPFER_MSB , + [REG_IE ][LSB ] =STMPE_IDX_IEGPIOR_LSB , + [REG_IE ][CSB ] =STMPE_IDX_IEGPIOR_CSB , + [REG_IE ][MSB ] =STMPE_IDX_IEGPIOR_MSB , };int i, j;
@@ -178,7 +186,7 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d)continue ; stmpe_gpio->oldregs[i][j] = new; -stmpe_reg_write (stmpe, stmpe->regs[regmap[i]] - j, new); +stmpe_reg_write (stmpe, stmpe->regs[regmap[i][j]], new); } }
@@ -214,9 +222,9 @@ static void stmpe_dbg_show_one(struct seq_file *s,struct stmpe_gpio *stmpe_gpio =gpiochip_get_data (gc);struct stmpe *stmpe = stmpe_gpio->stmpe;const char *label =gpiochip_is_requested (gc, offset); -int num_banks =DIV_ROUND_UP (stmpe->num_gpios,8 );bool val = !!stmpe_gpio_get (gc, offset); -u8 dir_reg = stmpe->regs[STMPE_IDX_GPDR_LSB ] - (offset /8 ); +u8 bank = offset /8 ; +u8 dir_reg = stmpe->regs[STMPE_IDX_GPDR_LSB + bank];u8 mask =1 << (offset %8 );int ret;u8 dir;
@@ -257,18 +265,16 @@ static void stmpe_dbg_show_one(struct seq_file *s,case STMPE1601 :case STMPE2401 :case STMPE2403 : - edge_det_reg = stmpe->regs[STMPE_IDX_GPEDR_MSB ] + - num_banks -1 - (offset /8 ); + edge_det_reg = stmpe->regs[STMPE_IDX_GPEDR_LSB + bank]; ret =stmpe_reg_read (stmpe, edge_det_reg);if (ret <0 )return ; edge_det = !!(ret & mask);case STMPE1801 : - rise_reg = stmpe->regs[STMPE_IDX_GPRER_LSB ] - - (offset /8 ); - fall_reg = stmpe->regs[STMPE_IDX_GPFER_LSB ] - - (offset /8 ); + rise_reg = stmpe->regs[STMPE_IDX_GPRER_LSB + bank]; + fall_reg = stmpe->regs[STMPE_IDX_GPFER_LSB + bank]; + ret =stmpe_reg_read (stmpe, rise_reg);if (ret <0 )return ;
@@ -279,8 +285,7 @@ static void stmpe_dbg_show_one(struct seq_file *s, fall = !!(ret & mask);case STMPE801 : - irqen_reg = stmpe->regs[STMPE_IDX_IEGPIOR_LSB ] - - (offset /8 ); + irqen_reg = stmpe->regs[STMPE_IDX_IEGPIOR_LSB + bank];break ;default :
@@ -362,8 +367,9 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev)*/ if (stmpe->partnum !=STMPE801 || stmpe->partnum !=STMPE1801 ) {stmpe_reg_write (stmpe, statmsbreg + i, status[i]); -stmpe_reg_write (stmpe, stmpe->regs[STMPE_IDX_GPEDR_MSB ] - + i, status[i]); +stmpe_reg_write (stmpe, + stmpe->regs[STMPE_IDX_GPEDR_LSB + i], + status[i]); } }
Signature · 1 line
1.9.1
Lee Jones
AppliedPATCH RESEND v2 7/10 gpio: stmpe: rework registers access
Quoted 17 lines · patrice.chotard at st.com
From: Patrice Chotard <[email protected]>
This update allows to use registers map as following :
regs[reg_index + offset] instead of regs[reg_index] + offsetThis makes code clearer and will facilitate the addition of STMPE1600 on which LSB and MSB registers are respectively located at addr and addr + 1. Despite for all others STMPE variant, LSB and MSB registers are respectively located in reverse order at addr + 1 and addr.
For variant which have 3 registers's bank, we use LSB,CSB and MSB indexes which contains respectively LSB (or LOW), CSB (or MID) and MSB (or HIGH) register addresses (STMPE1801/STMPE24xx).
For variant which have 2 registers's bank, we use LSB and CSB indexes only. In this case the CSB index contains the MSB regs address (STMPE 1601).
Quoted 5 lines
Signed-off-by Patrice Chotard <[email protected]>Reviewed-by Linus Walleij <[email protected]>--- drivers/gpio/gpio-stmpe.c | 48 ++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-)
Applied, thanks.
Quoted 136 lines
drivers/gpio/gpio-stmpe.c +27
-21@@ -21,6 +21,8 @@*/ enum {REG_RE ,REG_FE ,REG_IE }; +enum {LSB ,CSB ,MSB }; +#define CACHE_NR_REGS 3/* No variant has more than 24 GPIOs */ #define CACHE_NR_BANKS (24 / 8)@@ -40,7 +42,7 @@ static int stmpe_gpio_get(struct gpio_chip *chip, unsigned offset) {struct stmpe_gpio *stmpe_gpio =gpiochip_get_data (chip);struct stmpe *stmpe = stmpe_gpio->stmpe; -u8 reg = stmpe->regs[STMPE_IDX_GPMR_LSB ] - (offset /8 ); +u8 reg = stmpe->regs[STMPE_IDX_GPMR_LSB + (offset /8 )];u8 mask =1 << (offset %8 );int ret;@@ -56,7 +58,7 @@ static void stmpe_gpio_set(struct gpio_chip *chip, unsigned offset, int val)struct stmpe_gpio *stmpe_gpio =gpiochip_get_data (chip);struct stmpe *stmpe = stmpe_gpio->stmpe;int which = val ?STMPE_IDX_GPSR_LSB :STMPE_IDX_GPCR_LSB ; -u8 reg = stmpe->regs[which] - (offset /8 ); +u8 reg = stmpe->regs[which + (offset /8 )];u8 mask =1 << (offset %8 );/* @@ -74,7 +76,7 @@ static int stmpe_gpio_direction_output(struct gpio_chip *chip, {struct stmpe_gpio *stmpe_gpio =gpiochip_get_data (chip);struct stmpe *stmpe = stmpe_gpio->stmpe; -u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB ] - (offset /8 ); +u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB + (offset /8 )];u8 mask =1 << (offset %8 );stmpe_gpio_set (chip, offset, val);@@ -87,7 +89,7 @@ static int stmpe_gpio_direction_input(struct gpio_chip *chip, {struct stmpe_gpio *stmpe_gpio =gpiochip_get_data (chip);struct stmpe *stmpe = stmpe_gpio->stmpe; -u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB ] - (offset /8 ); +u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB + (offset /8 )];u8 mask =1 << (offset %8 );return stmpe_set_bits (stmpe, reg, mask,0 );@@ -157,10 +159,16 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d)struct stmpe_gpio *stmpe_gpio =gpiochip_get_data (gc);struct stmpe *stmpe = stmpe_gpio->stmpe;int num_banks =DIV_ROUND_UP (stmpe->num_gpios,8 ); -static const u8 regmap[] = { - [REG_RE ] =STMPE_IDX_GPRER_LSB , - [REG_FE ] =STMPE_IDX_GPFER_LSB , - [REG_IE ] =STMPE_IDX_IEGPIOR_LSB , +static const u8 regmap[CACHE_NR_REGS ][CACHE_NR_BANKS ] = { + [REG_RE ][LSB ] =STMPE_IDX_GPRER_LSB , + [REG_RE ][CSB ] =STMPE_IDX_GPRER_CSB , + [REG_RE ][MSB ] =STMPE_IDX_GPRER_MSB , + [REG_FE ][LSB ] =STMPE_IDX_GPFER_LSB , + [REG_FE ][CSB ] =STMPE_IDX_GPFER_CSB , + [REG_FE ][MSB ] =STMPE_IDX_GPFER_MSB , + [REG_IE ][LSB ] =STMPE_IDX_IEGPIOR_LSB , + [REG_IE ][CSB ] =STMPE_IDX_IEGPIOR_CSB , + [REG_IE ][MSB ] =STMPE_IDX_IEGPIOR_MSB , };int i, j;@@ -178,7 +186,7 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d)continue ; stmpe_gpio->oldregs[i][j] = new; -stmpe_reg_write (stmpe, stmpe->regs[regmap[i]] - j, new); +stmpe_reg_write (stmpe, stmpe->regs[regmap[i][j]], new); } }@@ -214,9 +222,9 @@ static void stmpe_dbg_show_one(struct seq_file *s,struct stmpe_gpio *stmpe_gpio =gpiochip_get_data (gc);struct stmpe *stmpe = stmpe_gpio->stmpe;const char *label =gpiochip_is_requested (gc, offset); -int num_banks =DIV_ROUND_UP (stmpe->num_gpios,8 );bool val = !!stmpe_gpio_get (gc, offset); -u8 dir_reg = stmpe->regs[STMPE_IDX_GPDR_LSB ] - (offset /8 ); +u8 bank = offset /8 ; +u8 dir_reg = stmpe->regs[STMPE_IDX_GPDR_LSB + bank];u8 mask =1 << (offset %8 );int ret;u8 dir;@@ -257,18 +265,16 @@ static void stmpe_dbg_show_one(struct seq_file *s,case STMPE1601 :case STMPE2401 :case STMPE2403 : - edge_det_reg = stmpe->regs[STMPE_IDX_GPEDR_MSB ] + - num_banks -1 - (offset /8 ); + edge_det_reg = stmpe->regs[STMPE_IDX_GPEDR_LSB + bank]; ret =stmpe_reg_read (stmpe, edge_det_reg);if (ret <0 )return ; edge_det = !!(ret & mask);case STMPE1801 : - rise_reg = stmpe->regs[STMPE_IDX_GPRER_LSB ] - - (offset /8 ); - fall_reg = stmpe->regs[STMPE_IDX_GPFER_LSB ] - - (offset /8 ); + rise_reg = stmpe->regs[STMPE_IDX_GPRER_LSB + bank]; + fall_reg = stmpe->regs[STMPE_IDX_GPFER_LSB + bank]; + ret =stmpe_reg_read (stmpe, rise_reg);if (ret <0 )return ;@@ -279,8 +285,7 @@ static void stmpe_dbg_show_one(struct seq_file *s, fall = !!(ret & mask);case STMPE801 : - irqen_reg = stmpe->regs[STMPE_IDX_IEGPIOR_LSB ] - - (offset /8 ); + irqen_reg = stmpe->regs[STMPE_IDX_IEGPIOR_LSB + bank];break ;default :@@ -362,8 +367,9 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev)*/ if (stmpe->partnum !=STMPE801 || stmpe->partnum !=STMPE1801 ) {stmpe_reg_write (stmpe, statmsbreg + i, status[i]); -stmpe_reg_write (stmpe, stmpe->regs[STMPE_IDX_GPEDR_MSB ] - + i, status[i]); +stmpe_reg_write (stmpe, + stmpe->regs[STMPE_IDX_GPEDR_LSB + i], + status[i]); } }
Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org ? Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
PATCH RESEND v2 8/10 Documentation: dt: add stmpe1600 compatible string to stmpe mfd
In reply to patrice.chotard at st.comFrom: Patrice Chotard <[email protected]>
This patch adds a new compatible string for stmpe mfd to support stmpe1600 variant.
--- Documentation/devicetree/bindings/mfd/stmpe.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Documentation/devicetree/bindings/mfd/stmpe.txt +1 -1
@@ -4,7 +4,7 @@ STMPE is an MFD device which may expose the following inbuilt devices: gpio, keypad, touchscreen, adc, pwm, rotator. Required properties: - - compatible : "st,stmpe[610|801|811|1601|2401|2403]" + - compatible : "st,stmpe[610|801|811|1600|1601|2401|2403]" - reg : I2C/SPI address of the device Optional properties:
Signature · 1 line
1.9.1
Lee Jones
AppliedPATCH RESEND v2 8/10 Documentation: dt: add stmpe1600 compatible string to stmpe mfd
Quoted 10 lines · patrice.chotard at st.com
From: Patrice Chotard <[email protected]>
This patch adds a new compatible string for stmpe mfd to support stmpe1600 variant.
Signed-off-by Amelie DELAUNAY <[email protected]>Acked-by Linus Walleij <[email protected]>--- Documentation/devicetree/bindings/mfd/stmpe.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Applied, thanks.
Quoted 13 lines
Documentation/devicetree/bindings/mfd/stmpe.txt +1
-1@@ -4,7 +4,7 @@ STMPE is an MFD device which may expose the following inbuilt devices: gpio, keypad, touchscreen, adc, pwm, rotator. Required properties: - - compatible : "st,stmpe[610|801|811|1601|2401|2403]" + - compatible : "st,stmpe[610|801|811|1600|1601|2401|2403]" - reg : I2C/SPI address of the device Optional properties:
Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org ? Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
PATCH RESEND v2 9/10 mfd: Add STMPE1600 support
In reply to patrice.chotard at st.comFrom: Patrice Chotard <[email protected]>
STMPE1600 is a 16-bit port expander.
Datasheet is available here :
http://www2.st.com/content/st_com/en/products/interfaces-and-transceivers/
i-o-expanders-and-level-translators/i-o-expanders/stmpe1600.html
--- drivers/mfd/stmpe-i2c.c | 2 ++ drivers/mfd/stmpe.c | 65 +++++++++++++++++++++++++++++++++++++++++++---- drivers/mfd/stmpe.h | 21 +++++++++++++++ include/linux/mfd/stmpe.h | 1 + 4 files changed, 84 insertions(+), 5 deletions(-)
drivers/mfd/stmpe-i2c.c +2 -0
@@ -57,6 +57,7 @@ static const struct of_device_id stmpe_of_match[] = { { .compatible = "st,stmpe610", .data = (void *)STMPE610, }, { .compatible = "st,stmpe801", .data = (void *)STMPE801, }, { .compatible = "st,stmpe811", .data = (void *)STMPE811, }, + { .compatible = "st,stmpe1600", .data = (void *)STMPE1600, }, { .compatible = "st,stmpe1601", .data = (void *)STMPE1601, }, { .compatible = "st,stmpe1801", .data = (void *)STMPE1801, }, { .compatible = "st,stmpe2401", .data = (void *)STMPE2401, },
@@ -101,6 +102,7 @@ static const struct i2c_device_id stmpe_i2c_id[] = { { "stmpe610", STMPE610 }, { "stmpe801", STMPE801 }, { "stmpe811", STMPE811 }, + { "stmpe1600", STMPE1600 }, { "stmpe1601", STMPE1601 }, { "stmpe1801", STMPE1801 }, { "stmpe2401", STMPE2401 },
drivers/mfd/stmpe.c +60 -5
99 lines not on this page · raw message
drivers/mfd/stmpe.h +21 -0
@@ -164,6 +164,27 @@ int stmpe_remove(struct stmpe *stmpe);#define STMPE811_SYS_CTRL2_TS_OFF (1 << 3)/* +* STMPE1600 +*/ +#define STMPE1600_ID 0x0016 +#define STMPE1600_NR_INTERNAL_IRQS 16 + +#define STMPE1600_REG_CHIP_ID 0x00 +#define STMPE1600_REG_SYS_CTRL 0x03 +#define STMPE1600_REG_IEGPIOR_LSB 0x08 +#define STMPE1600_REG_IEGPIOR_MSB 0x09 +#define STMPE1600_REG_ISGPIOR_LSB 0x0A +#define STMPE1600_REG_ISGPIOR_MSB 0x0B +#define STMPE1600_REG_GPMR_LSB 0x10 +#define STMPE1600_REG_GPMR_MSB 0x11 +#define STMPE1600_REG_GPSR_LSB 0x12 +#define STMPE1600_REG_GPSR_MSB 0x13 +#define STMPE1600_REG_GPDR_LSB 0x14 +#define STMPE1600_REG_GPDR_MSB 0x15 +#define STMPE1600_REG_GPPIR_LSB 0x16 +#define STMPE1600_REG_GPPIR_MSB 0x17 + +/* * STMPE1601 */
include/linux/mfd/stmpe.h +1 -0
@@ -26,6 +26,7 @@ enum stmpe_partnum {STMPE610 ,STMPE801 ,STMPE811 , +STMPE1600 ,STMPE1601 ,STMPE1801 , STMPE2401,
Signature · 1 line
1.9.1
Lee Jones
AppliedPATCH RESEND v2 9/10 mfd: Add STMPE1600 support
Quoted 11 lines · patrice.chotard at st.com
From: Patrice Chotard <[email protected]>
STMPE1600 is a 16-bit port expander.
Datasheet is available here :
http://www2.st.com/content/st_com/en/products/interfaces-and-transceivers/
i-o-expanders-and-level-translators/i-o-expanders/stmpe1600.htmlSigned-off-by Amelie DELAUNAY <[email protected]>Signed-off-by Patrice Chotard <[email protected]>Acked-by Linus Walleij <[email protected]>Acked-by Lee Jones <[email protected]>
Quoted 6 lines
--- drivers/mfd/stmpe-i2c.c | 2 ++ drivers/mfd/stmpe.c | 65 +++++++++++++++++++++++++++++++++++++++++++---- drivers/mfd/stmpe.h | 21 +++++++++++++++ include/linux/mfd/stmpe.h | 1 + 4 files changed, 84 insertions(+), 5 deletions(-)
Applied, thanks.
Quoted 172 lines
drivers/mfd/stmpe-i2c.c +2
-0@@ -57,6 +57,7 @@ static const struct of_device_id stmpe_of_match[] = { { .compatible = "st,stmpe610", .data = (void *)STMPE610, }, { .compatible = "st,stmpe801", .data = (void *)STMPE801, }, { .compatible = "st,stmpe811", .data = (void *)STMPE811, }, + { .compatible = "st,stmpe1600", .data = (void *)STMPE1600, }, { .compatible = "st,stmpe1601", .data = (void *)STMPE1601, }, { .compatible = "st,stmpe1801", .data = (void *)STMPE1801, }, { .compatible = "st,stmpe2401", .data = (void *)STMPE2401, },@@ -101,6 +102,7 @@ static const struct i2c_device_id stmpe_i2c_id[] = { { "stmpe610", STMPE610 }, { "stmpe801", STMPE801 }, { "stmpe811", STMPE811 }, + { "stmpe1600", STMPE1600 }, { "stmpe1601", STMPE1601 }, { "stmpe1801", STMPE1801 }, { "stmpe2401", STMPE2401 },drivers/mfd/stmpe.c +60
-5@@ -532,6 +532,59 @@ static struct stmpe_variant_info stmpe610 = { };/* +* STMPE1600 +* Compared to all others STMPE variant, LSB and MSB regs are located in this +* order : LSB addr +* MSB addr + 1 +* As there is only 2 * 8bits registers for GPMR/GPSR/IEGPIOPR, CSB index is MSB registers +*/ + +static const u8 stmpe1600_regs[] = { + [STMPE_IDX_CHIP_ID ] =STMPE1600_REG_CHIP_ID , + [STMPE_IDX_SYS_CTRL ] =STMPE1600_REG_SYS_CTRL , + [STMPE_IDX_ICR_LSB ] =STMPE1600_REG_SYS_CTRL , + [STMPE_IDX_GPMR_LSB ] =STMPE1600_REG_GPMR_LSB , + [STMPE_IDX_GPMR_CSB ] =STMPE1600_REG_GPMR_MSB , + [STMPE_IDX_GPSR_LSB ] =STMPE1600_REG_GPSR_LSB , + [STMPE_IDX_GPSR_CSB ] =STMPE1600_REG_GPSR_MSB , + [STMPE_IDX_GPDR_LSB ] =STMPE1600_REG_GPDR_LSB , + [STMPE_IDX_GPDR_CSB ] =STMPE1600_REG_GPDR_MSB , + [STMPE_IDX_IEGPIOR_LSB ] =STMPE1600_REG_IEGPIOR_LSB , + [STMPE_IDX_IEGPIOR_CSB ] =STMPE1600_REG_IEGPIOR_MSB , + [STMPE_IDX_ISGPIOR_LSB ] =STMPE1600_REG_ISGPIOR_LSB , +}; + +static struct stmpe_variant_block stmpe1600_blocks[] = { + { + .cell = &stmpe_gpio_cell, + .irq =0 , + .block =STMPE_BLOCK_GPIO , + }, +}; + +static int stmpe1600_enable (struct stmpe *stmpe,unsigned int blocks, +bool enable) +{ +if (blocks &STMPE_BLOCK_GPIO ) +return 0 ; +else +return -EINVAL ; +} + +static struct stmpe_variant_info stmpe1600 = { + .name ="stmpe1600" , + .id_val =STMPE1600_ID , + .id_mask =0xffff , + .num_gpios =16 , + .af_bits =0 , + .regs = stmpe1600_regs, + .blocks = stmpe1600_blocks, + .num_blocks =ARRAY_SIZE (stmpe1600_blocks), + .num_irqs =STMPE1600_NR_INTERNAL_IRQS , + .enable = stmpe1600_enable, +}; + +/* * STMPE1601 */ @@ -928,6 +981,7 @@ static struct stmpe_variant_info *stmpe_variant_info[STMPE_NBR_PARTS] = { [STMPE610] = &stmpe610, [STMPE801] = &stmpe801, [STMPE811] = &stmpe811, + [STMPE1600] = &stmpe1600, [STMPE1601] = &stmpe1601, [STMPE1801] = &stmpe1801, [STMPE2401] = &stmpe2401,@@ -954,7 +1008,8 @@ static irqreturn_t stmpe_irq(int irq, void *data)int ret;int i; -if (variant->id_val ==STMPE801_ID ) { +if (variant->id_val ==STMPE801_ID || + variant->id_val ==STMPE1600_ID ) {int base =irq_create_mapping (stmpe->domain,0 );handle_nested_irq (base);@@ -1128,13 +1183,13 @@ static int stmpe_chip_init(struct stmpe *stmpe)return ret;if (stmpe->irq >=0 ) { -if (id ==STMPE801_ID ) +if (id ==STMPE801_ID || id ==STMPE1600_ID ) icr =STMPE_SYS_CTRL_INT_EN ;else icr =STMPE_ICR_LSB_GIM ; -/* STMPE801 doesn't support Edge interrupts */ -if (id !=STMPE801_ID ) { +/* STMPE801 and STMPE1600 don't support Edge interrupts */ +if (id !=STMPE801_ID && id !=STMPE1600_ID ) {if (irq_trigger ==IRQF_TRIGGER_FALLING || irq_trigger ==IRQF_TRIGGER_RISING ) icr |=STMPE_ICR_LSB_EDGE ;@@ -1142,7 +1197,7 @@ static int stmpe_chip_init(struct stmpe *stmpe)if (irq_trigger ==IRQF_TRIGGER_RISING || irq_trigger ==IRQF_TRIGGER_HIGH ) { -if (id ==STMPE801_ID ) +if (id ==STMPE801_ID || id ==STMPE1600_ID ) icr |=STMPE_SYS_CTRL_INT_HI ;else icr |=STMPE_ICR_LSB_HIGH ;drivers/mfd/stmpe.h +21
-0@@ -164,6 +164,27 @@ int stmpe_remove(struct stmpe *stmpe);#define STMPE811_SYS_CTRL2_TS_OFF (1 << 3)/* +* STMPE1600 +*/ +#define STMPE1600_ID 0x0016 +#define STMPE1600_NR_INTERNAL_IRQS 16 + +#define STMPE1600_REG_CHIP_ID 0x00 +#define STMPE1600_REG_SYS_CTRL 0x03 +#define STMPE1600_REG_IEGPIOR_LSB 0x08 +#define STMPE1600_REG_IEGPIOR_MSB 0x09 +#define STMPE1600_REG_ISGPIOR_LSB 0x0A +#define STMPE1600_REG_ISGPIOR_MSB 0x0B +#define STMPE1600_REG_GPMR_LSB 0x10 +#define STMPE1600_REG_GPMR_MSB 0x11 +#define STMPE1600_REG_GPSR_LSB 0x12 +#define STMPE1600_REG_GPSR_MSB 0x13 +#define STMPE1600_REG_GPDR_LSB 0x14 +#define STMPE1600_REG_GPDR_MSB 0x15 +#define STMPE1600_REG_GPPIR_LSB 0x16 +#define STMPE1600_REG_GPPIR_MSB 0x17 + +/* * STMPE1601 */ include/linux/mfd/stmpe.h +1
-0@@ -26,6 +26,7 @@ enum stmpe_partnum {STMPE610 ,STMPE801 ,STMPE811 , +STMPE1600 ,STMPE1601 ,STMPE1801 , STMPE2401,
Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org ? Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
PATCH RESEND v2 10/10 gpio: stmpe: Add STMPE1600 support
In reply to patrice.chotard at st.comFrom: Patrice Chotard <[email protected]>
The particularities of this variant are:
- GPIO_XXX_LSB and GPIO_XXX_MSB memory locations are inverted compared to other variants.
- There is no Edge detection, Rising Edge and Falling Edge registers.
- IRQ flags are cleared when read, no need to write in Status register.
--- drivers/gpio/gpio-stmpe.c | 48 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 10 deletions(-)
drivers/gpio/gpio-stmpe.c +38 -10
@@ -128,8 +128,9 @@ static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type)if (type &IRQ_TYPE_LEVEL_LOW || type &IRQ_TYPE_LEVEL_HIGH )return -EINVAL ; -/* STMPE801 doesn't have RE and FE registers */ -if (stmpe_gpio->stmpe->partnum ==STMPE801 ) +/* STMPE801 and STMPE 1600 don't have RE and FE registers */ +if (stmpe_gpio->stmpe->partnum ==STMPE801 || + stmpe_gpio->stmpe->partnum ==STMPE1600 )return 0 ;if (type &IRQ_TYPE_EDGE_RISING )
@@ -173,9 +174,10 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d)int i, j;for (i =0 ; i <CACHE_NR_REGS ; i++) { -/* STMPE801 doesn't have RE and FE registers */ -if ((stmpe->partnum ==STMPE801 ) && - (i !=REG_IE )) +/* STMPE801 and STMPE1600 don't have RE and FE registers */ +if ((stmpe->partnum ==STMPE801 || + stmpe->partnum ==STMPE1600 ) && + (i !=REG_IE ))continue ;for (j =0 ; j < num_banks; j++) {
@@ -208,11 +210,21 @@ static void stmpe_gpio_irq_unmask(struct irq_data *d) {struct gpio_chip *gc =irq_data_get_irq_chip_data (d);struct stmpe_gpio *stmpe_gpio =gpiochip_get_data (gc); +struct stmpe *stmpe = stmpe_gpio->stmpe;int offset = d->hwirq;int regoffset = offset /8 ;int mask =1 << (offset %8 ); stmpe_gpio->regs[REG_IE ][regoffset] |= mask; + +/* +* STMPE1600 workaround: to be able to get IRQ from pins, +* a read must be done on GPMR register, or a write in +* GPSR or GPCR registers +*/ +if (stmpe->partnum ==STMPE1600 ) +stmpe_reg_read (stmpe, + stmpe->regs[STMPE_IDX_GPMR_LSB + regoffset]); } static void stmpe_dbg_show_one(struct seq_file *s,
@@ -285,6 +297,7 @@ static void stmpe_dbg_show_one(struct seq_file *s, fall = !!(ret & mask);case STMPE801 : +case STMPE1600 : irqen_reg = stmpe->regs[STMPE_IDX_IEGPIOR_LSB + bank];break ;
@@ -331,18 +344,32 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) {struct stmpe_gpio *stmpe_gpio = dev;struct stmpe *stmpe = stmpe_gpio->stmpe; -u8 statmsbreg = stmpe->regs[STMPE_IDX_ISGPIOR_MSB ]; +u8 statmsbreg;int num_banks =DIV_ROUND_UP (stmpe->num_gpios,8 );u8 status[num_banks];int ret;int i; +/* +* the stmpe_block_read() call below, imposes to set statmsbreg +* with the register located at the lowest address. As STMPE1600 +* variant is the only one which respect registers address's order +* (LSB regs located at lowest address than MSB ones) whereas all +* the others have a registers layout with MSB located before the +* LSB regs. +*/ +if (stmpe->partnum ==STMPE1600 ) + statmsbreg = stmpe->regs[STMPE_IDX_ISGPIOR_LSB ]; +else + statmsbreg = stmpe->regs[STMPE_IDX_ISGPIOR_MSB ]; + ret =stmpe_block_read (stmpe, statmsbreg, num_banks, status);if (ret <0 )return IRQ_NONE ;for (i =0 ; i < num_banks; i++) { -int bank = num_banks - i -1 ; +int bank = (stmpe_gpio->stmpe->partnum ==STMPE1600 ) ? i : + num_banks - i -1 ;unsigned int enabled = stmpe_gpio->regs[REG_IE ][bank];unsigned int stat = status[i];
@@ -362,10 +389,11 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev)/* * interrupt status register write has no effect on -* 801 and 1801, bits are cleared when read. -* Edge detect register is not present on 801 and 1801 +* 801/1801/1600, bits are cleared when read. +* Edge detect register is not present on 801/1600/1801 */ -if (stmpe->partnum !=STMPE801 || stmpe->partnum !=STMPE1801 ) { +if (stmpe->partnum !=STMPE801 || stmpe->partnum !=STMPE1600 || + stmpe->partnum !=STMPE1801 ) {stmpe_reg_write (stmpe, statmsbreg + i, status[i]); stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_GPEDR_LSB + i],
Signature · 1 line
1.9.1
Lee Jones
AppliedPATCH RESEND v2 10/10 gpio: stmpe: Add STMPE1600 support
Quoted 8 lines · patrice.chotard at st.com
From: Patrice Chotard <[email protected]>
The particularities of this variant are:
-GPIO_XXX_LSBandGPIO_XXX_MSBmemory locations are inverted compared to other variants.
- There is no Edge detection, Rising Edge and Falling Edge registers.
- IRQ flags are cleared when read, no need to write in Status register.
Quoted 6 lines
Signed-off-by Amelie DELAUNAY <[email protected]>Signed-off-by Patrice Chotard <[email protected]>Reviewed-by Linus Walleij <[email protected]>--- drivers/gpio/gpio-stmpe.c | 48 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 10 deletions(-)
Applied, thanks.
Quoted 110 lines
drivers/gpio/gpio-stmpe.c +38
-10@@ -128,8 +128,9 @@ static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type)if (type &IRQ_TYPE_LEVEL_LOW || type &IRQ_TYPE_LEVEL_HIGH )return -EINVAL ; -/* STMPE801 doesn't have RE and FE registers */ -if (stmpe_gpio->stmpe->partnum ==STMPE801 ) +/* STMPE801 and STMPE 1600 don't have RE and FE registers */ +if (stmpe_gpio->stmpe->partnum ==STMPE801 || + stmpe_gpio->stmpe->partnum ==STMPE1600 )return 0 ;if (type &IRQ_TYPE_EDGE_RISING )@@ -173,9 +174,10 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d)int i, j;for (i =0 ; i <CACHE_NR_REGS ; i++) { -/* STMPE801 doesn't have RE and FE registers */ -if ((stmpe->partnum ==STMPE801 ) && - (i !=REG_IE )) +/* STMPE801 and STMPE1600 don't have RE and FE registers */ +if ((stmpe->partnum ==STMPE801 || + stmpe->partnum ==STMPE1600 ) && + (i !=REG_IE ))continue ;for (j =0 ; j < num_banks; j++) {@@ -208,11 +210,21 @@ static void stmpe_gpio_irq_unmask(struct irq_data *d) {struct gpio_chip *gc =irq_data_get_irq_chip_data (d);struct stmpe_gpio *stmpe_gpio =gpiochip_get_data (gc); +struct stmpe *stmpe = stmpe_gpio->stmpe;int offset = d->hwirq;int regoffset = offset /8 ;int mask =1 << (offset %8 ); stmpe_gpio->regs[REG_IE ][regoffset] |= mask; + +/* +* STMPE1600 workaround: to be able to get IRQ from pins, +* a read must be done on GPMR register, or a write in +* GPSR or GPCR registers +*/ +if (stmpe->partnum ==STMPE1600 ) +stmpe_reg_read (stmpe, + stmpe->regs[STMPE_IDX_GPMR_LSB + regoffset]); } static void stmpe_dbg_show_one(struct seq_file *s,@@ -285,6 +297,7 @@ static void stmpe_dbg_show_one(struct seq_file *s, fall = !!(ret & mask);case STMPE801 : +case STMPE1600 : irqen_reg = stmpe->regs[STMPE_IDX_IEGPIOR_LSB + bank];break ;@@ -331,18 +344,32 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) {struct stmpe_gpio *stmpe_gpio = dev;struct stmpe *stmpe = stmpe_gpio->stmpe; -u8 statmsbreg = stmpe->regs[STMPE_IDX_ISGPIOR_MSB ]; +u8 statmsbreg;int num_banks =DIV_ROUND_UP (stmpe->num_gpios,8 );u8 status[num_banks];int ret;int i; +/* +* the stmpe_block_read() call below, imposes to set statmsbreg +* with the register located at the lowest address. As STMPE1600 +* variant is the only one which respect registers address's order +* (LSB regs located at lowest address than MSB ones) whereas all +* the others have a registers layout with MSB located before the +* LSB regs. +*/ +if (stmpe->partnum ==STMPE1600 ) + statmsbreg = stmpe->regs[STMPE_IDX_ISGPIOR_LSB ]; +else + statmsbreg = stmpe->regs[STMPE_IDX_ISGPIOR_MSB ]; + ret =stmpe_block_read (stmpe, statmsbreg, num_banks, status);if (ret <0 )return IRQ_NONE ;for (i =0 ; i < num_banks; i++) { -int bank = num_banks - i -1 ; +int bank = (stmpe_gpio->stmpe->partnum ==STMPE1600 ) ? i : + num_banks - i -1 ;unsigned int enabled = stmpe_gpio->regs[REG_IE ][bank];unsigned int stat = status[i];@@ -362,10 +389,11 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev)/* * interrupt status register write has no effect on -* 801 and 1801, bits are cleared when read. -* Edge detect register is not present on 801 and 1801 +* 801/1801/1600, bits are cleared when read. +* Edge detect register is not present on 801/1600/1801 */ -if (stmpe->partnum !=STMPE801 || stmpe->partnum !=STMPE1801 ) { +if (stmpe->partnum !=STMPE801 || stmpe->partnum !=STMPE1600 || + stmpe->partnum !=STMPE1801 ) {stmpe_reg_write (stmpe, statmsbreg + i, status[i]); stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_GPEDR_LSB + i],
Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org ? Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
[GIT PULL] Immutable branch between MFD and GPIO due for v4.9
In reply to patrice.chotard at st.comEnjoy!
The following changes since commit 29b4817d4018df78086157ea3a55c1d9424a7cfc:
Linux 4.8-rc1 (2016-08-07 18:18:00 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git tags/ib-mfd-gpio-v4.9
for you to fetch changes up to c6a05a0563efd6cddafe4e8c857cf87d1311e83b:
gpio: stmpe: Add STMPE1600 support (2016-08-10 09:25:26 +0100)
----------------------------------------------------------------
Immutable branch between MFD and GPIO due for the v4.9 merge window
----------------------------------------------------------------
Patrice Chotard (10):
mfd: stmpe: Add STMPE_IDX_SYS_CTRL/2 enum
mfd: stmpe: Add reset support for all STMPE variant
gpio: stmpe: Fix edge and rising/falling edge detection
gpio: stmpe: Write int status register only when needed
mfd: stmpe: Use generic bit mask name
mfd: stmpe: Rework registers access
gpio: stmpe: Rework registers access
Documentation: dt: Add stmpe1600 compatible string to STMPE MFD
mfd: Add STMPE1600 support
gpio: stmpe: Add STMPE1600 support
Documentation/devicetree/bindings/mfd/stmpe.txt | 2 +- drivers/gpio/gpio-stmpe.c | 167 +++++++++++++++++------- drivers/mfd/stmpe-i2c.c | 2 + drivers/mfd/stmpe.c | 161 +++++++++++++++++++---- drivers/mfd/stmpe.h | 85 ++++++++++-- include/linux/mfd/stmpe.h | 21 +++ 6 files changed, 352 insertions(+), 86 deletions(-)
Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org ? Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
[GIT PULL] Immutable branch between MFD and GPIO due for v4.9
Quoted 1 line · Lee Jones
Immutable branch between MFD and GPIO due for the v4.9 merge window
Awesome, pulled into the GPIO devel branch for v4.9.
Yours,
Linus Walleij