All of lore.kernel.org
 help / color / mirror / Atom feed
* [RESEND v2 00/10] STMPE fixes/rework and add STMPE1600 support
@ 2016-08-10  7:39 ` patrice.chotard at st.com
  0 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard @ 2016-08-10  7:39 UTC (permalink / raw)
  To: lee.jones, linus.walleij, linux-gpio
  Cc: gnurou, amelie.delaunay, vireshk, Patrice Chotard,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

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 <shawnguo@kernel.org>
	_ Sascha Hauer <kernel@pengutronix.de>

For ARM/SOCFPGA ARCHITECTURE
	_ Dinh Nguyen <dinguyen@opensource.altera.com>

For SPEAR PLATFORM SUPPORT
	_ Viresh Kumar <vireshk@kernel.org>
	_ Shiraz Hashim <shiraz.linux.kernel@gmail.com>

For Apalis/Colibri board SUPPORT
	_ marcel.ziswiler@toradex.com
	_ stefan@agner.ch
	_ dev@lynxeye.de
	_ Thierry Reding <thierry.reding@gmail.com>
	_ Alexandre Courbot <gnurou@gmail.com>

For ARM/Ux500 ARM ARCHITECTURE
	_ Linus Walleij <linus.walleij@linaro.org>

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(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [RESEND v2 00/10] STMPE fixes/rework and add STMPE1600 support
@ 2016-08-10  7:39 ` patrice.chotard at st.com
  0 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard at st.com @ 2016-08-10  7:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

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 <shawnguo@kernel.org>
	_ Sascha Hauer <kernel@pengutronix.de>

For ARM/SOCFPGA ARCHITECTURE
	_ Dinh Nguyen <dinguyen@opensource.altera.com>

For SPEAR PLATFORM SUPPORT
	_ Viresh Kumar <vireshk@kernel.org>
	_ Shiraz Hashim <shiraz.linux.kernel@gmail.com>

For Apalis/Colibri board SUPPORT
	_ marcel.ziswiler at toradex.com
	_ stefan at agner.ch
	_ dev at lynxeye.de
	_ Thierry Reding <thierry.reding@gmail.com>
	_ Alexandre Courbot <gnurou@gmail.com>

For ARM/Ux500 ARM ARCHITECTURE
	_ Linus Walleij <linus.walleij@linaro.org>

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(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [RESEND v2 01/10] mfd: stmpe: Add STMPE_IDX_SYS_CTRL/2 enum
  2016-08-10  7:39 ` patrice.chotard at st.com
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  -1 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard @ 2016-08-10  7:39 UTC (permalink / raw)
  To: lee.jones, linus.walleij, linux-gpio
  Cc: gnurou, amelie.delaunay, vireshk, Patrice Chotard,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

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.

Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mfd/stmpe.c       | 21 ++++++++++++++-------
 drivers/mfd/stmpe.h       |  2 ++
 include/linux/mfd/stmpe.h |  2 ++
 3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index fb8f9e8..c553b73 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -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);
 }
 
diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
index 84adb46..406f9f2 100644
--- a/drivers/mfd/stmpe.h
+++ b/drivers/mfd/stmpe.h
@@ -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
diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h
index cb83883..6c6690f 100644
--- a/include/linux/mfd/stmpe.h
+++ b/include/linux/mfd/stmpe.h
@@ -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,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RESEND v2 01/10] mfd: stmpe: Add STMPE_IDX_SYS_CTRL/2 enum
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  0 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard at st.com @ 2016-08-10  7:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

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.

Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mfd/stmpe.c       | 21 ++++++++++++++-------
 drivers/mfd/stmpe.h       |  2 ++
 include/linux/mfd/stmpe.h |  2 ++
 3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index fb8f9e8..c553b73 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -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);
 }
 
diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
index 84adb46..406f9f2 100644
--- a/drivers/mfd/stmpe.h
+++ b/drivers/mfd/stmpe.h
@@ -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
diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h
index cb83883..6c6690f 100644
--- a/include/linux/mfd/stmpe.h
+++ b/include/linux/mfd/stmpe.h
@@ -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,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RESEND v2 02/10] mfd: stmpe: Add reset support for all STMPE variant
  2016-08-10  7:39 ` patrice.chotard at st.com
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  -1 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard @ 2016-08-10  7:39 UTC (permalink / raw)
  To: lee.jones, linus.walleij, linux-gpio
  Cc: gnurou, amelie.delaunay, vireshk, Patrice Chotard,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

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.

Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mfd/stmpe.c | 23 +++++++++++++++--------
 drivers/mfd/stmpe.h |  7 +++++--
 2 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index c553b73..af682d0 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -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)
diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
index 406f9f2..4ae343d 100644
--- a/drivers/mfd/stmpe.h
+++ b/drivers/mfd/stmpe.h
@@ -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)
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RESEND v2 02/10] mfd: stmpe: Add reset support for all STMPE variant
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  0 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard at st.com @ 2016-08-10  7:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

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.

Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mfd/stmpe.c | 23 +++++++++++++++--------
 drivers/mfd/stmpe.h |  7 +++++--
 2 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index c553b73..af682d0 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -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)
diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
index 406f9f2..4ae343d 100644
--- a/drivers/mfd/stmpe.h
+++ b/drivers/mfd/stmpe.h
@@ -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)
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RESEND v2 03/10] gpio: stmpe: fix edge and rising/falling edge detection
  2016-08-10  7:39 ` patrice.chotard at st.com
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  -1 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard @ 2016-08-10  7:39 UTC (permalink / raw)
  To: lee.jones, linus.walleij, linux-gpio
  Cc: gnurou, amelie.delaunay, vireshk, Patrice Chotard,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

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.

Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-stmpe.c | 85 +++++++++++++++++++++++++++++++++--------------
 1 file changed, 60 insertions(+), 25 deletions(-)

diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
index 5197edf..bfc918c 100644
--- a/drivers/gpio/gpio-stmpe.c
+++ b/drivers/gpio/gpio-stmpe.c
@@ -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]);
 	}
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RESEND v2 03/10] gpio: stmpe: fix edge and rising/falling edge detection
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  0 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard at st.com @ 2016-08-10  7:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

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.

Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-stmpe.c | 85 +++++++++++++++++++++++++++++++++--------------
 1 file changed, 60 insertions(+), 25 deletions(-)

diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
index 5197edf..bfc918c 100644
--- a/drivers/gpio/gpio-stmpe.c
+++ b/drivers/gpio/gpio-stmpe.c
@@ -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]);
 	}
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RESEND v2 04/10] gpio: stmpe: write int status register only when needed
  2016-08-10  7:39 ` patrice.chotard at st.com
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  -1 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard @ 2016-08-10  7:39 UTC (permalink / raw)
  To: lee.jones, linus.walleij, linux-gpio
  Cc: gnurou, amelie.delaunay, vireshk, Patrice Chotard,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

On STMPE801/1801 datasheets, it's mentionned writing
in interrupt status register has no effect, bits are
cleared when reading.

Signed-off-by: Amelie DELAUNAY <amelie.delaunay@st.com>
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-stmpe.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
index bfc918c..2789bdc 100644
--- a/drivers/gpio/gpio-stmpe.c
+++ b/drivers/gpio/gpio-stmpe.c
@@ -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;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RESEND v2 04/10] gpio: stmpe: write int status register only when needed
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  0 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard at st.com @ 2016-08-10  7:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

On STMPE801/1801 datasheets, it's mentionned writing
in interrupt status register has no effect, bits are
cleared when reading.

Signed-off-by: Amelie DELAUNAY <amelie.delaunay@st.com>
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-stmpe.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
index bfc918c..2789bdc 100644
--- a/drivers/gpio/gpio-stmpe.c
+++ b/drivers/gpio/gpio-stmpe.c
@@ -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;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RESEND v2 05/10] mfd: stmpe: use generic bit mask name
  2016-08-10  7:39 ` patrice.chotard at st.com
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  -1 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard @ 2016-08-10  7:39 UTC (permalink / raw)
  To: lee.jones, linus.walleij, linux-gpio
  Cc: gnurou, amelie.delaunay, vireshk, Patrice Chotard,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

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

Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mfd/stmpe.c | 4 ++--
 drivers/mfd/stmpe.h | 6 ++----
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index af682d0..2556463 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -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;
 		}
diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
index 4ae343d..4ba1123 100644
--- a/drivers/mfd/stmpe.h
+++ b/drivers/mfd/stmpe.h
@@ -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
  */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RESEND v2 05/10] mfd: stmpe: use generic bit mask name
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  0 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard at st.com @ 2016-08-10  7:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

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

Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mfd/stmpe.c | 4 ++--
 drivers/mfd/stmpe.h | 6 ++----
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index af682d0..2556463 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -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;
 		}
diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
index 4ae343d..4ba1123 100644
--- a/drivers/mfd/stmpe.h
+++ b/drivers/mfd/stmpe.h
@@ -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
  */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RESEND v2 06/10] mfd: stmpe: rework registers access
  2016-08-10  7:39 ` patrice.chotard at st.com
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  -1 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard @ 2016-08-10  7:39 UTC (permalink / raw)
  To: lee.jones, linus.walleij, linux-gpio
  Cc: gnurou, amelie.delaunay, vireshk, Patrice Chotard,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

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).

Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

---
 drivers/mfd/stmpe.c       | 48 ++++++++++++++++++++++++++++++++++++++++++----
 drivers/mfd/stmpe.h       | 49 +++++++++++++++++++++++++++++++++++++++++------
 include/linux/mfd/stmpe.h | 18 +++++++++++++++++
 3 files changed, 105 insertions(+), 10 deletions(-)

diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index 2556463..a060809 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -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);
diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
index 4ba1123..f127342 100644
--- a/drivers/mfd/stmpe.h
+++ b/drivers/mfd/stmpe.h
@@ -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)
diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h
index 6c6690f..3dced4a 100644
--- a/include/linux/mfd/stmpe.h
+++ b/include/linux/mfd/stmpe.h
@@ -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,
 };
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RESEND v2 06/10] mfd: stmpe: rework registers access
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  0 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard at st.com @ 2016-08-10  7:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

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).

Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

---
 drivers/mfd/stmpe.c       | 48 ++++++++++++++++++++++++++++++++++++++++++----
 drivers/mfd/stmpe.h       | 49 +++++++++++++++++++++++++++++++++++++++++------
 include/linux/mfd/stmpe.h | 18 +++++++++++++++++
 3 files changed, 105 insertions(+), 10 deletions(-)

diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index 2556463..a060809 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -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);
diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
index 4ba1123..f127342 100644
--- a/drivers/mfd/stmpe.h
+++ b/drivers/mfd/stmpe.h
@@ -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)
diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h
index 6c6690f..3dced4a 100644
--- a/include/linux/mfd/stmpe.h
+++ b/include/linux/mfd/stmpe.h
@@ -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,
 };
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RESEND v2 07/10] gpio: stmpe: rework registers access
  2016-08-10  7:39 ` patrice.chotard at st.com
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  -1 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard @ 2016-08-10  7:39 UTC (permalink / raw)
  To: lee.jones, linus.walleij, linux-gpio
  Cc: gnurou, amelie.delaunay, vireshk, Patrice Chotard,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

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).

Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-stmpe.c | 48 ++++++++++++++++++++++++++---------------------
 1 file changed, 27 insertions(+), 21 deletions(-)

diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
index 2789bdc..6d6d76a 100644
--- a/drivers/gpio/gpio-stmpe.c
+++ b/drivers/gpio/gpio-stmpe.c
@@ -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]);
 		}
 	}
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RESEND v2 07/10] gpio: stmpe: rework registers access
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  0 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard at st.com @ 2016-08-10  7:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

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).

Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-stmpe.c | 48 ++++++++++++++++++++++++++---------------------
 1 file changed, 27 insertions(+), 21 deletions(-)

diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
index 2789bdc..6d6d76a 100644
--- a/drivers/gpio/gpio-stmpe.c
+++ b/drivers/gpio/gpio-stmpe.c
@@ -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]);
 		}
 	}
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RESEND v2 08/10] Documentation: dt: add stmpe1600 compatible string to stmpe mfd
  2016-08-10  7:39 ` patrice.chotard at st.com
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  -1 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard @ 2016-08-10  7:39 UTC (permalink / raw)
  To: lee.jones, linus.walleij, linux-gpio
  Cc: gnurou, amelie.delaunay, vireshk, Patrice Chotard,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

This patch adds a new compatible string for stmpe mfd to support
stmpe1600 variant.

Signed-off-by: Amelie DELAUNAY <amelie.delaunay@st.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
---
 Documentation/devicetree/bindings/mfd/stmpe.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mfd/stmpe.txt b/Documentation/devicetree/bindings/mfd/stmpe.txt
index 3fb68bf..f9065a5 100644
--- a/Documentation/devicetree/bindings/mfd/stmpe.txt
+++ b/Documentation/devicetree/bindings/mfd/stmpe.txt
@@ -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:
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RESEND v2 08/10] Documentation: dt: add stmpe1600 compatible string to stmpe mfd
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  0 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard at st.com @ 2016-08-10  7:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

This patch adds a new compatible string for stmpe mfd to support
stmpe1600 variant.

Signed-off-by: Amelie DELAUNAY <amelie.delaunay@st.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
---
 Documentation/devicetree/bindings/mfd/stmpe.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mfd/stmpe.txt b/Documentation/devicetree/bindings/mfd/stmpe.txt
index 3fb68bf..f9065a5 100644
--- a/Documentation/devicetree/bindings/mfd/stmpe.txt
+++ b/Documentation/devicetree/bindings/mfd/stmpe.txt
@@ -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:
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RESEND v2 09/10] mfd: Add STMPE1600 support
  2016-08-10  7:39 ` patrice.chotard at st.com
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  -1 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard @ 2016-08-10  7:39 UTC (permalink / raw)
  To: lee.jones, linus.walleij, linux-gpio
  Cc: gnurou, amelie.delaunay, vireshk, Patrice Chotard,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

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

Signed-off-by: Amelie DELAUNAY <amelie.delaunay@st.com>
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
 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(-)

diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c
index c3f4aab..863c39a 100644
--- a/drivers/mfd/stmpe-i2c.c
+++ b/drivers/mfd/stmpe-i2c.c
@@ -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 },
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index a060809..3a65331 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -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;
diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
index f127342..f7efdd8 100644
--- a/drivers/mfd/stmpe.h
+++ b/drivers/mfd/stmpe.h
@@ -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
  */
 
diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h
index 3dced4a..0170bd6 100644
--- a/include/linux/mfd/stmpe.h
+++ b/include/linux/mfd/stmpe.h
@@ -26,6 +26,7 @@ enum stmpe_partnum {
 	STMPE610,
 	STMPE801,
 	STMPE811,
+	STMPE1600,
 	STMPE1601,
 	STMPE1801,
 	STMPE2401,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RESEND v2 09/10] mfd: Add STMPE1600 support
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  0 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard at st.com @ 2016-08-10  7:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

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

Signed-off-by: Amelie DELAUNAY <amelie.delaunay@st.com>
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
 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(-)

diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c
index c3f4aab..863c39a 100644
--- a/drivers/mfd/stmpe-i2c.c
+++ b/drivers/mfd/stmpe-i2c.c
@@ -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 },
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index a060809..3a65331 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -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;
diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
index f127342..f7efdd8 100644
--- a/drivers/mfd/stmpe.h
+++ b/drivers/mfd/stmpe.h
@@ -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
  */
 
diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h
index 3dced4a..0170bd6 100644
--- a/include/linux/mfd/stmpe.h
+++ b/include/linux/mfd/stmpe.h
@@ -26,6 +26,7 @@ enum stmpe_partnum {
 	STMPE610,
 	STMPE801,
 	STMPE811,
+	STMPE1600,
 	STMPE1601,
 	STMPE1801,
 	STMPE2401,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RESEND v2 10/10] gpio: stmpe: Add STMPE1600 support
  2016-08-10  7:39 ` patrice.chotard at st.com
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  -1 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard @ 2016-08-10  7:39 UTC (permalink / raw)
  To: lee.jones, linus.walleij, linux-gpio
  Cc: gnurou, amelie.delaunay, vireshk, Patrice Chotard,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

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.

Signed-off-by: Amelie DELAUNAY <amelie.delaunay@st.com>
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-stmpe.c | 48 +++++++++++++++++++++++++++++++++++++----------
 1 file changed, 38 insertions(+), 10 deletions(-)

diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
index 6d6d76a..32c5a72 100644
--- a/drivers/gpio/gpio-stmpe.c
+++ b/drivers/gpio/gpio-stmpe.c
@@ -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],
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [RESEND v2 10/10] gpio: stmpe: Add STMPE1600 support
@ 2016-08-10  7:39   ` patrice.chotard at st.com
  0 siblings, 0 replies; 46+ messages in thread
From: patrice.chotard at st.com @ 2016-08-10  7:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

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.

Signed-off-by: Amelie DELAUNAY <amelie.delaunay@st.com>
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-stmpe.c | 48 +++++++++++++++++++++++++++++++++++++----------
 1 file changed, 38 insertions(+), 10 deletions(-)

diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
index 6d6d76a..32c5a72 100644
--- a/drivers/gpio/gpio-stmpe.c
+++ b/drivers/gpio/gpio-stmpe.c
@@ -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],
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [RESEND v2 01/10] mfd: stmpe: Add STMPE_IDX_SYS_CTRL/2 enum
  2016-08-10  7:39   ` patrice.chotard at st.com
@ 2016-08-10  8:28     ` Lee Jones
  -1 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:28 UTC (permalink / raw)
  To: patrice.chotard
  Cc: gnurou, amelie.delaunay, vireshk, linus.walleij, linux-gpio,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard@st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> 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.
> 
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> Acked-by: Lee Jones <lee.jones@linaro.org>
> ---
>  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.

> diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
> index fb8f9e8..c553b73 100644
> --- a/drivers/mfd/stmpe.c
> +++ b/drivers/mfd/stmpe.c
> @@ -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);
>  }
>  
> diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
> index 84adb46..406f9f2 100644
> --- a/drivers/mfd/stmpe.h
> +++ b/drivers/mfd/stmpe.h
> @@ -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
> diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h
> index cb83883..6c6690f 100644
> --- a/include/linux/mfd/stmpe.h
> +++ b/include/linux/mfd/stmpe.h
> @@ -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,

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [RESEND v2 01/10] mfd: stmpe: Add STMPE_IDX_SYS_CTRL/2 enum
@ 2016-08-10  8:28     ` Lee Jones
  0 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard at st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> 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.
> 
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> Acked-by: Lee Jones <lee.jones@linaro.org>
> ---
>  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.

> diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
> index fb8f9e8..c553b73 100644
> --- a/drivers/mfd/stmpe.c
> +++ b/drivers/mfd/stmpe.c
> @@ -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);
>  }
>  
> diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
> index 84adb46..406f9f2 100644
> --- a/drivers/mfd/stmpe.h
> +++ b/drivers/mfd/stmpe.h
> @@ -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
> diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h
> index cb83883..6c6690f 100644
> --- a/include/linux/mfd/stmpe.h
> +++ b/include/linux/mfd/stmpe.h
> @@ -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,

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RESEND v2 02/10] mfd: stmpe: Add reset support for all STMPE variant
  2016-08-10  7:39   ` patrice.chotard at st.com
@ 2016-08-10  8:28     ` Lee Jones
  -1 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:28 UTC (permalink / raw)
  To: patrice.chotard
  Cc: gnurou, amelie.delaunay, vireshk, linus.walleij, linux-gpio,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard@st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> 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.
> 
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> Acked-by: Lee Jones <lee.jones@linaro.org>
> ---
>  drivers/mfd/stmpe.c | 23 +++++++++++++++--------
>  drivers/mfd/stmpe.h |  7 +++++--
>  2 files changed, 20 insertions(+), 10 deletions(-)

Applied, thanks.

> diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
> index c553b73..af682d0 100644
> --- a/drivers/mfd/stmpe.c
> +++ b/drivers/mfd/stmpe.c
> @@ -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)
> diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
> index 406f9f2..4ae343d 100644
> --- a/drivers/mfd/stmpe.h
> +++ b/drivers/mfd/stmpe.h
> @@ -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)
>  

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [RESEND v2 02/10] mfd: stmpe: Add reset support for all STMPE variant
@ 2016-08-10  8:28     ` Lee Jones
  0 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard at st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> 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.
> 
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> Acked-by: Lee Jones <lee.jones@linaro.org>
> ---
>  drivers/mfd/stmpe.c | 23 +++++++++++++++--------
>  drivers/mfd/stmpe.h |  7 +++++--
>  2 files changed, 20 insertions(+), 10 deletions(-)

Applied, thanks.

> diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
> index c553b73..af682d0 100644
> --- a/drivers/mfd/stmpe.c
> +++ b/drivers/mfd/stmpe.c
> @@ -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)
> diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
> index 406f9f2..4ae343d 100644
> --- a/drivers/mfd/stmpe.h
> +++ b/drivers/mfd/stmpe.h
> @@ -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)
>  

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RESEND v2 03/10] gpio: stmpe: fix edge and rising/falling edge detection
  2016-08-10  7:39   ` patrice.chotard at st.com
@ 2016-08-10  8:29     ` Lee Jones
  -1 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:29 UTC (permalink / raw)
  To: patrice.chotard
  Cc: gnurou, amelie.delaunay, vireshk, linus.walleij, linux-gpio,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard@st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> 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.
> 
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  drivers/gpio/gpio-stmpe.c | 85 +++++++++++++++++++++++++++++++++--------------
>  1 file changed, 60 insertions(+), 25 deletions(-)

Applied, thanks.

> diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
> index 5197edf..bfc918c 100644
> --- a/drivers/gpio/gpio-stmpe.c
> +++ b/drivers/gpio/gpio-stmpe.c
> @@ -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]);
>  	}

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [RESEND v2 03/10] gpio: stmpe: fix edge and rising/falling edge detection
@ 2016-08-10  8:29     ` Lee Jones
  0 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard at st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> 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.
> 
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  drivers/gpio/gpio-stmpe.c | 85 +++++++++++++++++++++++++++++++++--------------
>  1 file changed, 60 insertions(+), 25 deletions(-)

Applied, thanks.

> diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
> index 5197edf..bfc918c 100644
> --- a/drivers/gpio/gpio-stmpe.c
> +++ b/drivers/gpio/gpio-stmpe.c
> @@ -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]);
>  	}

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RESEND v2 04/10] gpio: stmpe: write int status register only when needed
  2016-08-10  7:39   ` patrice.chotard at st.com
@ 2016-08-10  8:29     ` Lee Jones
  -1 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:29 UTC (permalink / raw)
  To: patrice.chotard
  Cc: gnurou, amelie.delaunay, vireshk, linus.walleij, linux-gpio,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard@st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> On STMPE801/1801 datasheets, it's mentionned writing
> in interrupt status register has no effect, bits are
> cleared when reading.
> 
> Signed-off-by: Amelie DELAUNAY <amelie.delaunay@st.com>
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  drivers/gpio/gpio-stmpe.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)

Applied, thanks.

> diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
> index bfc918c..2789bdc 100644
> --- a/drivers/gpio/gpio-stmpe.c
> +++ b/drivers/gpio/gpio-stmpe.c
> @@ -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;

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [RESEND v2 04/10] gpio: stmpe: write int status register only when needed
@ 2016-08-10  8:29     ` Lee Jones
  0 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard at st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> On STMPE801/1801 datasheets, it's mentionned writing
> in interrupt status register has no effect, bits are
> cleared when reading.
> 
> Signed-off-by: Amelie DELAUNAY <amelie.delaunay@st.com>
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  drivers/gpio/gpio-stmpe.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)

Applied, thanks.

> diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
> index bfc918c..2789bdc 100644
> --- a/drivers/gpio/gpio-stmpe.c
> +++ b/drivers/gpio/gpio-stmpe.c
> @@ -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;

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RESEND v2 05/10] mfd: stmpe: use generic bit mask name
  2016-08-10  7:39   ` patrice.chotard at st.com
@ 2016-08-10  8:29     ` Lee Jones
  -1 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:29 UTC (permalink / raw)
  To: patrice.chotard
  Cc: gnurou, amelie.delaunay, vireshk, linus.walleij, linux-gpio,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard@st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> 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
> 
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Acked-by: Lee Jones <lee.jones@linaro.org>
> ---
>  drivers/mfd/stmpe.c | 4 ++--
>  drivers/mfd/stmpe.h | 6 ++----
>  2 files changed, 4 insertions(+), 6 deletions(-)

Applied, thanks.

> diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
> index af682d0..2556463 100644
> --- a/drivers/mfd/stmpe.c
> +++ b/drivers/mfd/stmpe.c
> @@ -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;
>  		}
> diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
> index 4ae343d..4ba1123 100644
> --- a/drivers/mfd/stmpe.h
> +++ b/drivers/mfd/stmpe.h
> @@ -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
>   */

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [RESEND v2 05/10] mfd: stmpe: use generic bit mask name
@ 2016-08-10  8:29     ` Lee Jones
  0 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard at st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> 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
> 
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Acked-by: Lee Jones <lee.jones@linaro.org>
> ---
>  drivers/mfd/stmpe.c | 4 ++--
>  drivers/mfd/stmpe.h | 6 ++----
>  2 files changed, 4 insertions(+), 6 deletions(-)

Applied, thanks.

> diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
> index af682d0..2556463 100644
> --- a/drivers/mfd/stmpe.c
> +++ b/drivers/mfd/stmpe.c
> @@ -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;
>  		}
> diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
> index 4ae343d..4ba1123 100644
> --- a/drivers/mfd/stmpe.h
> +++ b/drivers/mfd/stmpe.h
> @@ -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
>   */

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RESEND v2 06/10] mfd: stmpe: rework registers access
  2016-08-10  7:39   ` patrice.chotard at st.com
@ 2016-08-10  8:29     ` Lee Jones
  -1 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:29 UTC (permalink / raw)
  To: patrice.chotard
  Cc: gnurou, amelie.delaunay, vireshk, linus.walleij, linux-gpio,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard@st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> 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).
> 
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> 
> ---
>  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.

> diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
> index 2556463..a060809 100644
> --- a/drivers/mfd/stmpe.c
> +++ b/drivers/mfd/stmpe.c
> @@ -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);
> diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
> index 4ba1123..f127342 100644
> --- a/drivers/mfd/stmpe.h
> +++ b/drivers/mfd/stmpe.h
> @@ -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)
> diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h
> index 6c6690f..3dced4a 100644
> --- a/include/linux/mfd/stmpe.h
> +++ b/include/linux/mfd/stmpe.h
> @@ -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,
>  };

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [RESEND v2 06/10] mfd: stmpe: rework registers access
@ 2016-08-10  8:29     ` Lee Jones
  0 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard at st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> 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).
> 
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> 
> ---
>  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.

> diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
> index 2556463..a060809 100644
> --- a/drivers/mfd/stmpe.c
> +++ b/drivers/mfd/stmpe.c
> @@ -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);
> diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
> index 4ba1123..f127342 100644
> --- a/drivers/mfd/stmpe.h
> +++ b/drivers/mfd/stmpe.h
> @@ -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)
> diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h
> index 6c6690f..3dced4a 100644
> --- a/include/linux/mfd/stmpe.h
> +++ b/include/linux/mfd/stmpe.h
> @@ -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,
>  };

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RESEND v2 07/10] gpio: stmpe: rework registers access
  2016-08-10  7:39   ` patrice.chotard at st.com
@ 2016-08-10  8:29     ` Lee Jones
  -1 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:29 UTC (permalink / raw)
  To: patrice.chotard
  Cc: gnurou, amelie.delaunay, vireshk, linus.walleij, linux-gpio,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard@st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> 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).
> 
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  drivers/gpio/gpio-stmpe.c | 48 ++++++++++++++++++++++++++---------------------
>  1 file changed, 27 insertions(+), 21 deletions(-)

Applied, thanks.

> diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
> index 2789bdc..6d6d76a 100644
> --- a/drivers/gpio/gpio-stmpe.c
> +++ b/drivers/gpio/gpio-stmpe.c
> @@ -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]);
>  		}
>  	}
>  

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [RESEND v2 07/10] gpio: stmpe: rework registers access
@ 2016-08-10  8:29     ` Lee Jones
  0 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard at st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> 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).
> 
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  drivers/gpio/gpio-stmpe.c | 48 ++++++++++++++++++++++++++---------------------
>  1 file changed, 27 insertions(+), 21 deletions(-)

Applied, thanks.

> diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
> index 2789bdc..6d6d76a 100644
> --- a/drivers/gpio/gpio-stmpe.c
> +++ b/drivers/gpio/gpio-stmpe.c
> @@ -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]);
>  		}
>  	}
>  

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RESEND v2 08/10] Documentation: dt: add stmpe1600 compatible string to stmpe mfd
  2016-08-10  7:39   ` patrice.chotard at st.com
@ 2016-08-10  8:30     ` Lee Jones
  -1 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:30 UTC (permalink / raw)
  To: patrice.chotard
  Cc: gnurou, amelie.delaunay, vireshk, linus.walleij, linux-gpio,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard@st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> This patch adds a new compatible string for stmpe mfd to support
> stmpe1600 variant.
> 
> Signed-off-by: Amelie DELAUNAY <amelie.delaunay@st.com>
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  Documentation/devicetree/bindings/mfd/stmpe.txt | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Applied, thanks.

> diff --git a/Documentation/devicetree/bindings/mfd/stmpe.txt b/Documentation/devicetree/bindings/mfd/stmpe.txt
> index 3fb68bf..f9065a5 100644
> --- a/Documentation/devicetree/bindings/mfd/stmpe.txt
> +++ b/Documentation/devicetree/bindings/mfd/stmpe.txt
> @@ -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:

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [RESEND v2 08/10] Documentation: dt: add stmpe1600 compatible string to stmpe mfd
@ 2016-08-10  8:30     ` Lee Jones
  0 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard at st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> This patch adds a new compatible string for stmpe mfd to support
> stmpe1600 variant.
> 
> Signed-off-by: Amelie DELAUNAY <amelie.delaunay@st.com>
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  Documentation/devicetree/bindings/mfd/stmpe.txt | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Applied, thanks.

> diff --git a/Documentation/devicetree/bindings/mfd/stmpe.txt b/Documentation/devicetree/bindings/mfd/stmpe.txt
> index 3fb68bf..f9065a5 100644
> --- a/Documentation/devicetree/bindings/mfd/stmpe.txt
> +++ b/Documentation/devicetree/bindings/mfd/stmpe.txt
> @@ -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:

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RESEND v2 09/10] mfd: Add STMPE1600 support
  2016-08-10  7:39   ` patrice.chotard at st.com
@ 2016-08-10  8:30     ` Lee Jones
  -1 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:30 UTC (permalink / raw)
  To: patrice.chotard
  Cc: gnurou, amelie.delaunay, vireshk, linus.walleij, linux-gpio,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard@st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> 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
> 
> Signed-off-by: Amelie DELAUNAY <amelie.delaunay@st.com>
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> Acked-by: Lee Jones <lee.jones@linaro.org>
> ---
>  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.

> diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c
> index c3f4aab..863c39a 100644
> --- a/drivers/mfd/stmpe-i2c.c
> +++ b/drivers/mfd/stmpe-i2c.c
> @@ -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 },
> diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
> index a060809..3a65331 100644
> --- a/drivers/mfd/stmpe.c
> +++ b/drivers/mfd/stmpe.c
> @@ -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;
> diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
> index f127342..f7efdd8 100644
> --- a/drivers/mfd/stmpe.h
> +++ b/drivers/mfd/stmpe.h
> @@ -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
>   */
>  
> diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h
> index 3dced4a..0170bd6 100644
> --- a/include/linux/mfd/stmpe.h
> +++ b/include/linux/mfd/stmpe.h
> @@ -26,6 +26,7 @@ enum stmpe_partnum {
>  	STMPE610,
>  	STMPE801,
>  	STMPE811,
> +	STMPE1600,
>  	STMPE1601,
>  	STMPE1801,
>  	STMPE2401,

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [RESEND v2 09/10] mfd: Add STMPE1600 support
@ 2016-08-10  8:30     ` Lee Jones
  0 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard at st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> 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
> 
> Signed-off-by: Amelie DELAUNAY <amelie.delaunay@st.com>
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> Acked-by: Lee Jones <lee.jones@linaro.org>
> ---
>  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.

> diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c
> index c3f4aab..863c39a 100644
> --- a/drivers/mfd/stmpe-i2c.c
> +++ b/drivers/mfd/stmpe-i2c.c
> @@ -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 },
> diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
> index a060809..3a65331 100644
> --- a/drivers/mfd/stmpe.c
> +++ b/drivers/mfd/stmpe.c
> @@ -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;
> diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
> index f127342..f7efdd8 100644
> --- a/drivers/mfd/stmpe.h
> +++ b/drivers/mfd/stmpe.h
> @@ -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
>   */
>  
> diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h
> index 3dced4a..0170bd6 100644
> --- a/include/linux/mfd/stmpe.h
> +++ b/include/linux/mfd/stmpe.h
> @@ -26,6 +26,7 @@ enum stmpe_partnum {
>  	STMPE610,
>  	STMPE801,
>  	STMPE811,
> +	STMPE1600,
>  	STMPE1601,
>  	STMPE1801,
>  	STMPE2401,

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [RESEND v2 10/10] gpio: stmpe: Add STMPE1600 support
  2016-08-10  7:39   ` patrice.chotard at st.com
@ 2016-08-10  8:30     ` Lee Jones
  -1 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:30 UTC (permalink / raw)
  To: patrice.chotard
  Cc: gnurou, amelie.delaunay, vireshk, linus.walleij, linux-gpio,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard@st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> 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.
> 
> Signed-off-by: Amelie DELAUNAY <amelie.delaunay@st.com>
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  drivers/gpio/gpio-stmpe.c | 48 +++++++++++++++++++++++++++++++++++++----------
>  1 file changed, 38 insertions(+), 10 deletions(-)

Applied, thanks.

> diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
> index 6d6d76a..32c5a72 100644
> --- a/drivers/gpio/gpio-stmpe.c
> +++ b/drivers/gpio/gpio-stmpe.c
> @@ -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],

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [RESEND v2 10/10] gpio: stmpe: Add STMPE1600 support
@ 2016-08-10  8:30     ` Lee Jones
  0 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 10 Aug 2016, patrice.chotard at st.com wrote:

> From: Patrice Chotard <patrice.chotard@st.com>
> 
> 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.
> 
> Signed-off-by: Amelie DELAUNAY <amelie.delaunay@st.com>
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  drivers/gpio/gpio-stmpe.c | 48 +++++++++++++++++++++++++++++++++++++----------
>  1 file changed, 38 insertions(+), 10 deletions(-)

Applied, thanks.

> diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
> index 6d6d76a..32c5a72 100644
> --- a/drivers/gpio/gpio-stmpe.c
> +++ b/drivers/gpio/gpio-stmpe.c
> @@ -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],

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [GIT PULL] Immutable branch between MFD and GPIO due for v4.9
  2016-08-10  7:39 ` patrice.chotard at st.com
@ 2016-08-10  8:42   ` Lee Jones
  -1 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:42 UTC (permalink / raw)
  To: patrice.chotard
  Cc: gnurou, amelie.delaunay, vireshk, linus.walleij, linux-gpio,
	thierry.reding, kernel, dinguyen, shawnguo, shiraz.linux.kernel,
	linux-arm-kernel

Enjoy!

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(-)

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [GIT PULL] Immutable branch between MFD and GPIO due for v4.9
@ 2016-08-10  8:42   ` Lee Jones
  0 siblings, 0 replies; 46+ messages in thread
From: Lee Jones @ 2016-08-10  8:42 UTC (permalink / raw)
  To: linux-arm-kernel

Enjoy!

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(-)

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [GIT PULL] Immutable branch between MFD and GPIO due for v4.9
  2016-08-10  8:42   ` Lee Jones
@ 2016-08-11 12:07     ` Linus Walleij
  -1 siblings, 0 replies; 46+ messages in thread
From: Linus Walleij @ 2016-08-11 12:07 UTC (permalink / raw)
  To: Lee Jones
  Cc: Patrice CHOTARD, Alexandre Courbot, linux-gpio, linux-arm-kernel,
	amelie.delaunay, Shawn Guo, Sascha Hauer, Dinh Nguyen,
	Viresh Kumar, Shiraz Hashim, Thierry Reding

On Wed, Aug 10, 2016 at 10:42 AM, Lee Jones <lee.jones@linaro.org> wrote:

> 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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [GIT PULL] Immutable branch between MFD and GPIO due for v4.9
@ 2016-08-11 12:07     ` Linus Walleij
  0 siblings, 0 replies; 46+ messages in thread
From: Linus Walleij @ 2016-08-11 12:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Aug 10, 2016 at 10:42 AM, Lee Jones <lee.jones@linaro.org> wrote:

> 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

^ permalink raw reply	[flat|nested] 46+ messages in thread

end of thread, other threads:[~2016-08-11 12:07 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-10  7:39 [RESEND v2 00/10] STMPE fixes/rework and add STMPE1600 support patrice.chotard
2016-08-10  7:39 ` patrice.chotard at st.com
2016-08-10  7:39 ` [RESEND v2 01/10] mfd: stmpe: Add STMPE_IDX_SYS_CTRL/2 enum patrice.chotard
2016-08-10  7:39   ` patrice.chotard at st.com
2016-08-10  8:28   ` Lee Jones
2016-08-10  8:28     ` Lee Jones
2016-08-10  7:39 ` [RESEND v2 02/10] mfd: stmpe: Add reset support for all STMPE variant patrice.chotard
2016-08-10  7:39   ` patrice.chotard at st.com
2016-08-10  8:28   ` Lee Jones
2016-08-10  8:28     ` Lee Jones
2016-08-10  7:39 ` [RESEND v2 03/10] gpio: stmpe: fix edge and rising/falling edge detection patrice.chotard
2016-08-10  7:39   ` patrice.chotard at st.com
2016-08-10  8:29   ` Lee Jones
2016-08-10  8:29     ` Lee Jones
2016-08-10  7:39 ` [RESEND v2 04/10] gpio: stmpe: write int status register only when needed patrice.chotard
2016-08-10  7:39   ` patrice.chotard at st.com
2016-08-10  8:29   ` Lee Jones
2016-08-10  8:29     ` Lee Jones
2016-08-10  7:39 ` [RESEND v2 05/10] mfd: stmpe: use generic bit mask name patrice.chotard
2016-08-10  7:39   ` patrice.chotard at st.com
2016-08-10  8:29   ` Lee Jones
2016-08-10  8:29     ` Lee Jones
2016-08-10  7:39 ` [RESEND v2 06/10] mfd: stmpe: rework registers access patrice.chotard
2016-08-10  7:39   ` patrice.chotard at st.com
2016-08-10  8:29   ` Lee Jones
2016-08-10  8:29     ` Lee Jones
2016-08-10  7:39 ` [RESEND v2 07/10] gpio: " patrice.chotard
2016-08-10  7:39   ` patrice.chotard at st.com
2016-08-10  8:29   ` Lee Jones
2016-08-10  8:29     ` Lee Jones
2016-08-10  7:39 ` [RESEND v2 08/10] Documentation: dt: add stmpe1600 compatible string to stmpe mfd patrice.chotard
2016-08-10  7:39   ` patrice.chotard at st.com
2016-08-10  8:30   ` Lee Jones
2016-08-10  8:30     ` Lee Jones
2016-08-10  7:39 ` [RESEND v2 09/10] mfd: Add STMPE1600 support patrice.chotard
2016-08-10  7:39   ` patrice.chotard at st.com
2016-08-10  8:30   ` Lee Jones
2016-08-10  8:30     ` Lee Jones
2016-08-10  7:39 ` [RESEND v2 10/10] gpio: stmpe: " patrice.chotard
2016-08-10  7:39   ` patrice.chotard at st.com
2016-08-10  8:30   ` Lee Jones
2016-08-10  8:30     ` Lee Jones
2016-08-10  8:42 ` [GIT PULL] Immutable branch between MFD and GPIO due for v4.9 Lee Jones
2016-08-10  8:42   ` Lee Jones
2016-08-11 12:07   ` Linus Walleij
2016-08-11 12:07     ` Linus Walleij

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.