All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/10] iio: adc: at91-sama5d2_adc: add support for sama7g5
@ 2021-08-24 11:54 ` Eugen Hristev
  0 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev


Hi,

This series adds support for sama7g5.

The sama7g5 is slightly different from sama5d2, but has the same basic
operations. The register map is a bit different, so, I added some primitives
to differentiate between the two classes of hardware blocks (sama5d2-sam9x60
and sama7g5).

Sama7g5 has 16 channels ADC, no resistive touch, and extra features
(FIFOs, better oversampling , not implemented yet).

It is a rework of the series initially sent here:
https://marc.info/?l=linux-iio&m=161461656807826&w=2

I reworked this according to review by Jonathan, meaning that first I created
a no-op patch that will convert the driver to a more platform specific data
dedicated type of driver. This adds various structures that hold things like
register layout and channel information.
After this I created few patches that implement the main differences between
sama7g5 and older products: the end-of-conversion new register. I added
helper functions to make code more easy to read and more simple.
One the last patches adds the layout and channels for sama7g5.
At this moment in linux-next, the DT for sama7g5 and sama7g5ek is present,
and the last patches add and enable this node in DT for this board.

Eugen



Eugen Hristev (10):
  dt-bindings: iio: adc: at91-sama5d2: add compatible for sama7g5-adc
  iio: adc: at91-sama5d2_adc: initialize hardware after clock is started
  iio: adc: at91-sama5d2_adc: remove unused definition
  iio: adc: at91-sama5d2_adc: convert to platform specific data
    structures
  iio: adc: at91-sama5d2-adc: add support for separate end of conversion
    registers
  iio: adc: at91-sama5d2_adc: add helper for COR register
  iio: adc: at91-sama5d2_adc: add support for sama7g5 device
  iio: adc: at91-sama5d2_adc: update copyright and authors information
  ARM: dts: at91: sama7g5: add node for the ADC
  ARM: dts: at91: sama7g5ek: enable ADC on the board

 .../bindings/iio/adc/atmel,sama5d2-adc.yaml   |   1 +
 arch/arm/boot/dts/at91-sama7g5ek.dts          |   8 +
 arch/arm/boot/dts/sama7g5.dtsi                |  16 +
 drivers/iio/adc/at91-sama5d2_adc.c            | 586 ++++++++++++------
 4 files changed, 425 insertions(+), 186 deletions(-)

-- 
2.25.1


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

* [PATCH v2 00/10] iio: adc: at91-sama5d2_adc: add support for sama7g5
@ 2021-08-24 11:54 ` Eugen Hristev
  0 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev


Hi,

This series adds support for sama7g5.

The sama7g5 is slightly different from sama5d2, but has the same basic
operations. The register map is a bit different, so, I added some primitives
to differentiate between the two classes of hardware blocks (sama5d2-sam9x60
and sama7g5).

Sama7g5 has 16 channels ADC, no resistive touch, and extra features
(FIFOs, better oversampling , not implemented yet).

It is a rework of the series initially sent here:
https://marc.info/?l=linux-iio&m=161461656807826&w=2

I reworked this according to review by Jonathan, meaning that first I created
a no-op patch that will convert the driver to a more platform specific data
dedicated type of driver. This adds various structures that hold things like
register layout and channel information.
After this I created few patches that implement the main differences between
sama7g5 and older products: the end-of-conversion new register. I added
helper functions to make code more easy to read and more simple.
One the last patches adds the layout and channels for sama7g5.
At this moment in linux-next, the DT for sama7g5 and sama7g5ek is present,
and the last patches add and enable this node in DT for this board.

Eugen



Eugen Hristev (10):
  dt-bindings: iio: adc: at91-sama5d2: add compatible for sama7g5-adc
  iio: adc: at91-sama5d2_adc: initialize hardware after clock is started
  iio: adc: at91-sama5d2_adc: remove unused definition
  iio: adc: at91-sama5d2_adc: convert to platform specific data
    structures
  iio: adc: at91-sama5d2-adc: add support for separate end of conversion
    registers
  iio: adc: at91-sama5d2_adc: add helper for COR register
  iio: adc: at91-sama5d2_adc: add support for sama7g5 device
  iio: adc: at91-sama5d2_adc: update copyright and authors information
  ARM: dts: at91: sama7g5: add node for the ADC
  ARM: dts: at91: sama7g5ek: enable ADC on the board

 .../bindings/iio/adc/atmel,sama5d2-adc.yaml   |   1 +
 arch/arm/boot/dts/at91-sama7g5ek.dts          |   8 +
 arch/arm/boot/dts/sama7g5.dtsi                |  16 +
 drivers/iio/adc/at91-sama5d2_adc.c            | 586 ++++++++++++------
 4 files changed, 425 insertions(+), 186 deletions(-)

-- 
2.25.1


_______________________________________________
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] 44+ messages in thread

* [PATCH v2 01/10] dt-bindings: iio: adc: at91-sama5d2: add compatible for sama7g5-adc
  2021-08-24 11:54 ` Eugen Hristev
@ 2021-08-24 11:54   ` Eugen Hristev
  -1 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev, Rob Herring

Add compatible for microchip,sama7g5-adc device.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml b/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml
index 79c13b408eda..efed361215b4 100644
--- a/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml
@@ -15,6 +15,7 @@ properties:
     enum:
       - atmel,sama5d2-adc
       - microchip,sam9x60-adc
+      - microchip,sama7g5-adc
 
   reg:
     maxItems: 1
-- 
2.25.1


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

* [PATCH v2 01/10] dt-bindings: iio: adc: at91-sama5d2: add compatible for sama7g5-adc
@ 2021-08-24 11:54   ` Eugen Hristev
  0 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev, Rob Herring

Add compatible for microchip,sama7g5-adc device.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml b/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml
index 79c13b408eda..efed361215b4 100644
--- a/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml
@@ -15,6 +15,7 @@ properties:
     enum:
       - atmel,sama5d2-adc
       - microchip,sam9x60-adc
+      - microchip,sama7g5-adc
 
   reg:
     maxItems: 1
-- 
2.25.1


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

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

* [PATCH v2 02/10] iio: adc: at91-sama5d2_adc: initialize hardware after clock is started
  2021-08-24 11:54 ` Eugen Hristev
@ 2021-08-24 11:54   ` Eugen Hristev
  -1 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev

The hw_init hardware init call must happen after the clock is prepared and
enabled. Otherwise, writing to the registers might lead to a block or
external abort.

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index ea5ca163d879..1f4d461c2c18 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -1833,12 +1833,12 @@ static int at91_adc_probe(struct platform_device *pdev)
 		goto vref_disable;
 	}
 
-	at91_adc_hw_init(indio_dev);
-
 	ret = clk_prepare_enable(st->per_clk);
 	if (ret)
 		goto vref_disable;
 
+	at91_adc_hw_init(indio_dev);
+
 	platform_set_drvdata(pdev, indio_dev);
 
 	ret = at91_adc_buffer_and_trigger_init(&pdev->dev, indio_dev);
-- 
2.25.1


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

* [PATCH v2 02/10] iio: adc: at91-sama5d2_adc: initialize hardware after clock is started
@ 2021-08-24 11:54   ` Eugen Hristev
  0 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev

The hw_init hardware init call must happen after the clock is prepared and
enabled. Otherwise, writing to the registers might lead to a block or
external abort.

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index ea5ca163d879..1f4d461c2c18 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -1833,12 +1833,12 @@ static int at91_adc_probe(struct platform_device *pdev)
 		goto vref_disable;
 	}
 
-	at91_adc_hw_init(indio_dev);
-
 	ret = clk_prepare_enable(st->per_clk);
 	if (ret)
 		goto vref_disable;
 
+	at91_adc_hw_init(indio_dev);
+
 	platform_set_drvdata(pdev, indio_dev);
 
 	ret = at91_adc_buffer_and_trigger_init(&pdev->dev, indio_dev);
-- 
2.25.1


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

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

* [PATCH v2 03/10] iio: adc: at91-sama5d2_adc: remove unused definition
  2021-08-24 11:54 ` Eugen Hristev
@ 2021-08-24 11:54   ` Eugen Hristev
  -1 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev

Remove unused register definition

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index 1f4d461c2c18..9d71dcffcf93 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -143,8 +143,6 @@
 #define AT91_SAMA5D2_COR	0x4c
 #define AT91_SAMA5D2_COR_DIFF_OFFSET	16
 
-/* Channel Data Register 0 */
-#define AT91_SAMA5D2_CDR0	0x50
 /* Analog Control Register */
 #define AT91_SAMA5D2_ACR	0x94
 /* Analog Control Register - Pen detect sensitivity mask */
-- 
2.25.1


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

* [PATCH v2 03/10] iio: adc: at91-sama5d2_adc: remove unused definition
@ 2021-08-24 11:54   ` Eugen Hristev
  0 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev

Remove unused register definition

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index 1f4d461c2c18..9d71dcffcf93 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -143,8 +143,6 @@
 #define AT91_SAMA5D2_COR	0x4c
 #define AT91_SAMA5D2_COR_DIFF_OFFSET	16
 
-/* Channel Data Register 0 */
-#define AT91_SAMA5D2_CDR0	0x50
 /* Analog Control Register */
 #define AT91_SAMA5D2_ACR	0x94
 /* Analog Control Register - Pen detect sensitivity mask */
-- 
2.25.1


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

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

* [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform specific data structures
  2021-08-24 11:54 ` Eugen Hristev
@ 2021-08-24 11:54   ` Eugen Hristev
  -1 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev

Convert the driver to platform specific structures. This means:
- create a register layout struct that will hold offsets for registers
- create a platform struct that will hold platform information (number of
channels, indexes for different channels and pointer to layout struct)
- convert specific macros that are platform dependent into platform variables

This step is in fact a no-op, but allows the driver to be more flexible
and for future enhancement including adding new platforms that are partly
compatible with the current driver and differ slightly in register layout
or capabilities for example.

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
 1 file changed, 247 insertions(+), 163 deletions(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index 9d71dcffcf93..8ede18b8d789 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -27,8 +27,9 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/regulator/consumer.h>
 
+struct at91_adc_reg_layout {
 /* Control Register */
-#define AT91_SAMA5D2_CR		0x00
+	u16				CR;
 /* Software Reset */
 #define	AT91_SAMA5D2_CR_SWRST		BIT(0)
 /* Start Conversion */
@@ -39,7 +40,7 @@
 #define	AT91_SAMA5D2_CR_CMPRST		BIT(4)
 
 /* Mode Register */
-#define AT91_SAMA5D2_MR		0x04
+	u16				MR;
 /* Trigger Selection */
 #define	AT91_SAMA5D2_MR_TRGSEL(v)	((v) << 1)
 /* ADTRG */
@@ -82,19 +83,19 @@
 #define	AT91_SAMA5D2_MR_USEQ		BIT(31)
 
 /* Channel Sequence Register 1 */
-#define AT91_SAMA5D2_SEQR1	0x08
+	u16				SEQR1;
 /* Channel Sequence Register 2 */
-#define AT91_SAMA5D2_SEQR2	0x0c
+	u16				SEQR2;
 /* Channel Enable Register */
-#define AT91_SAMA5D2_CHER	0x10
+	u16				CHER;
 /* Channel Disable Register */
-#define AT91_SAMA5D2_CHDR	0x14
+	u16				CHDR;
 /* Channel Status Register */
-#define AT91_SAMA5D2_CHSR	0x18
+	u16				CHSR;
 /* Last Converted Data Register */
-#define AT91_SAMA5D2_LCDR	0x20
+	u16				LCDR;
 /* Interrupt Enable Register */
-#define AT91_SAMA5D2_IER	0x24
+	u16				IER;
 /* Interrupt Enable Register - TS X measurement ready */
 #define AT91_SAMA5D2_IER_XRDY   BIT(20)
 /* Interrupt Enable Register - TS Y measurement ready */
@@ -109,22 +110,23 @@
 #define AT91_SAMA5D2_IER_PEN    BIT(29)
 /* Interrupt Enable Register - No pen detect */
 #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
+
 /* Interrupt Disable Register */
-#define AT91_SAMA5D2_IDR	0x28
+	u16				IDR;
 /* Interrupt Mask Register */
-#define AT91_SAMA5D2_IMR	0x2c
+	u16				IMR;
 /* Interrupt Status Register */
-#define AT91_SAMA5D2_ISR	0x30
+	u16				ISR;
 /* Interrupt Status Register - Pen touching sense status */
 #define AT91_SAMA5D2_ISR_PENS   BIT(31)
 /* Last Channel Trigger Mode Register */
-#define AT91_SAMA5D2_LCTMR	0x34
+	u16				LCTMR;
 /* Last Channel Compare Window Register */
-#define AT91_SAMA5D2_LCCWR	0x38
+	u16				LCCWR;
 /* Overrun Status Register */
-#define AT91_SAMA5D2_OVER	0x3c
+	u16				OVER;
 /* Extended Mode Register */
-#define AT91_SAMA5D2_EMR	0x40
+	u16				EMR;
 /* Extended Mode Register - Oversampling rate */
 #define AT91_SAMA5D2_EMR_OSR(V)			((V) << 16)
 #define AT91_SAMA5D2_EMR_OSR_MASK		GENMASK(17, 16)
@@ -134,22 +136,22 @@
 
 /* Extended Mode Register - Averaging on single trigger event */
 #define AT91_SAMA5D2_EMR_ASTE(V)		((V) << 20)
+
 /* Compare Window Register */
-#define AT91_SAMA5D2_CWR	0x44
+	u16				CWR;
 /* Channel Gain Register */
-#define AT91_SAMA5D2_CGR	0x48
-
+	u16				CGR;
 /* Channel Offset Register */
-#define AT91_SAMA5D2_COR	0x4c
+	u16				COR;
 #define AT91_SAMA5D2_COR_DIFF_OFFSET	16
 
 /* Analog Control Register */
-#define AT91_SAMA5D2_ACR	0x94
+	u16				ACR;
 /* Analog Control Register - Pen detect sensitivity mask */
 #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
 
 /* Touchscreen Mode Register */
-#define AT91_SAMA5D2_TSMR	0xb0
+	u16				TSMR;
 /* Touchscreen Mode Register - No touch mode */
 #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
 /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
@@ -178,13 +180,13 @@
 #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
 
 /* Touchscreen X Position Register */
-#define AT91_SAMA5D2_XPOSR	0xb4
+	u16				XPOSR;
 /* Touchscreen Y Position Register */
-#define AT91_SAMA5D2_YPOSR	0xb8
+	u16				YPOSR;
 /* Touchscreen Pressure Register */
-#define AT91_SAMA5D2_PRESSR	0xbc
+	u16				PRESSR;
 /* Trigger Register */
-#define AT91_SAMA5D2_TRGR	0xc0
+	u16				TRGR;
 /* Mask for TRGMOD field of TRGR register */
 #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
 /* No trigger, only software trigger can start conversions */
@@ -203,30 +205,52 @@
 #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
 
 /* Correction Select Register */
-#define AT91_SAMA5D2_COSR	0xd0
+	u16				COSR;
 /* Correction Value Register */
-#define AT91_SAMA5D2_CVR	0xd4
+	u16				CVR;
 /* Channel Error Correction Register */
-#define AT91_SAMA5D2_CECR	0xd8
+	u16				CECR;
 /* Write Protection Mode Register */
-#define AT91_SAMA5D2_WPMR	0xe4
+	u16				WPMR;
 /* Write Protection Status Register */
-#define AT91_SAMA5D2_WPSR	0xe8
+	u16				WPSR;
 /* Version Register */
-#define AT91_SAMA5D2_VERSION	0xfc
-
-#define AT91_SAMA5D2_HW_TRIG_CNT 3
-#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
-#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
-
-#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
-					 AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
+	u16				VERSION;
+};
 
-#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
-					 AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
-#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
-#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
-#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
+static const struct at91_adc_reg_layout sama5d2_layout = {
+	.CR =			0x00,
+	.MR =			0x04,
+	.SEQR1 =		0x08,
+	.SEQR2 =		0x0c,
+	.CHER =			0x10,
+	.CHDR =			0x14,
+	.CHSR =			0x18,
+	.LCDR =			0x20,
+	.IER =			0x24,
+	.IDR =			0x28,
+	.IMR =			0x2c,
+	.ISR =			0x30,
+	.LCTMR =		0x34,
+	.LCCWR =		0x38,
+	.OVER =			0x3c,
+	.EMR =			0x40,
+	.CWR =			0x44,
+	.CGR =			0x48,
+	.COR =			0x4c,
+	.ACR =			0x94,
+	.TSMR =			0xb0,
+	.XPOSR =		0xb4,
+	.YPOSR =		0xb8,
+	.PRESSR =		0xbc,
+	.TRGR =			0xc0,
+	.COSR =			0xd0,
+	.CVR =			0xd4,
+	.CECR =			0xd8,
+	.WPMR =			0xe4,
+	.WPSR =			0xe8,
+	.VERSION =		0xfc,
+};
 
 #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
 #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
@@ -235,18 +259,6 @@
 
 #define AT91_SAMA5D2_MAX_POS_BITS			12
 
-/*
- * Maximum number of bytes to hold conversion from all channels
- * without the timestamp.
- */
-#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
-					 AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
-
-/* This total must also include the timestamp */
-#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
-
-#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
-
 #define AT91_HWFIFO_MAX_SIZE_STR	"128"
 #define AT91_HWFIFO_MAX_SIZE		128
 
@@ -255,12 +267,12 @@
 #define AT91_OSR_4SAMPLES		4
 #define AT91_OSR_16SAMPLES		16
 
-#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)				\
+#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)			\
 	{								\
 		.type = IIO_VOLTAGE,					\
 		.channel = num,						\
 		.address = addr,					\
-		.scan_index = num,					\
+		.scan_index = index,					\
 		.scan_type = {						\
 			.sign = 'u',					\
 			.realbits = 14,					\
@@ -274,14 +286,14 @@
 		.indexed = 1,						\
 	}
 
-#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)				\
+#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)			\
 	{								\
 		.type = IIO_VOLTAGE,					\
 		.differential = 1,					\
 		.channel = num,						\
 		.channel2 = num2,					\
 		.address = addr,					\
-		.scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,	\
+		.scan_index = index,					\
 		.scan_type = {						\
 			.sign = 's',					\
 			.realbits = 14,					\
@@ -328,13 +340,48 @@
 		.datasheet_name = name,					\
 	}
 
-#define at91_adc_readl(st, reg)		readl_relaxed(st->base + reg)
-#define at91_adc_writel(st, reg, val)	writel_relaxed(val, st->base + reg)
+#define at91_adc_readl(st, reg)						\
+	readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
+#define at91_adc_read_chan(st, reg)					\
+	readl_relaxed((st)->base + reg)
+#define at91_adc_writel(st, reg, val)					\
+	writel_relaxed(val, (st)->base + (st)->soc_info.platform->layout->reg)
+
+/**
+ * struct at91_adc_platform - at91-sama5d2 platform information struct
+ * @layout:		pointer to the reg layout struct
+ * @adc_channels:	pointer to an array of channels for registering in
+ *			the iio subsystem
+ * @nr_channels:	number of physical channels available
+ * @touch_chan_x:	index of the touchscreen X channel
+ * @touch_chan_y:	index of the touchscreen Y channel
+ * @touch_chan_p:	index of the touchscreen P channel
+ * @max_channels:	number of total channels
+ * @hw_trig_cnt:	number of possible hardware triggers
+ */
+struct at91_adc_platform {
+	const struct at91_adc_reg_layout	*layout;
+	const struct iio_chan_spec		(*adc_channels)[];
+	unsigned int				nr_channels;
+	unsigned int				touch_chan_x;
+	unsigned int				touch_chan_y;
+	unsigned int				touch_chan_p;
+	unsigned int				max_channels;
+	unsigned int				hw_trig_cnt;
+};
 
+/**
+ * struct at91_adc_soc_info - at91-sama5d2 soc information struct
+ * @startup_time:	device startup time
+ * @min_sample_rate:	minimum sample rate in Hz
+ * @max_sample_rate:	maximum sample rate in Hz
+ * @platform:		pointer to the platform structure
+ */
 struct at91_adc_soc_info {
 	unsigned			startup_time;
 	unsigned			min_sample_rate;
 	unsigned			max_sample_rate;
+	const struct at91_adc_platform	*platform;
 };
 
 struct at91_adc_trigger {
@@ -382,6 +429,15 @@ struct at91_adc_touch {
 	struct work_struct		workq;
 };
 
+/*
+ * Buffer size requirements:
+ * No channels * bytes_per_channel(2) + timestamp bytes (8)
+ * Divided by 2 because we need half words.
+ * We assume 32 channels for now, has to be increased if needed.
+ * Nobody minds a buffer being too big.
+ */
+#define AT91_BUFFER_MAX_HWORDS ((32 * 2 + 8) / 2)
+
 struct at91_adc_state {
 	void __iomem			*base;
 	int				irq;
@@ -437,29 +493,49 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = {
 	},
 };
 
-static const struct iio_chan_spec at91_adc_channels[] = {
-	AT91_SAMA5D2_CHAN_SINGLE(0, 0x50),
-	AT91_SAMA5D2_CHAN_SINGLE(1, 0x54),
-	AT91_SAMA5D2_CHAN_SINGLE(2, 0x58),
-	AT91_SAMA5D2_CHAN_SINGLE(3, 0x5c),
-	AT91_SAMA5D2_CHAN_SINGLE(4, 0x60),
-	AT91_SAMA5D2_CHAN_SINGLE(5, 0x64),
-	AT91_SAMA5D2_CHAN_SINGLE(6, 0x68),
-	AT91_SAMA5D2_CHAN_SINGLE(7, 0x6c),
-	AT91_SAMA5D2_CHAN_SINGLE(8, 0x70),
-	AT91_SAMA5D2_CHAN_SINGLE(9, 0x74),
-	AT91_SAMA5D2_CHAN_SINGLE(10, 0x78),
-	AT91_SAMA5D2_CHAN_SINGLE(11, 0x7c),
-	AT91_SAMA5D2_CHAN_DIFF(0, 1, 0x50),
-	AT91_SAMA5D2_CHAN_DIFF(2, 3, 0x58),
-	AT91_SAMA5D2_CHAN_DIFF(4, 5, 0x60),
-	AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68),
-	AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70),
-	AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78),
-	IIO_CHAN_SOFT_TIMESTAMP(AT91_SAMA5D2_TIMESTAMP_CHAN_IDX),
-	AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_X_CHAN_IDX, "x", IIO_MOD_X),
-	AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, "y", IIO_MOD_Y),
-	AT91_SAMA5D2_CHAN_PRESSURE(AT91_SAMA5D2_TOUCH_P_CHAN_IDX, "pressure"),
+static const struct iio_chan_spec at91_sama5d2_adc_channels[] = {
+	AT91_SAMA5D2_CHAN_SINGLE(0, 0, 0x50),
+	AT91_SAMA5D2_CHAN_SINGLE(1, 1, 0x54),
+	AT91_SAMA5D2_CHAN_SINGLE(2, 2, 0x58),
+	AT91_SAMA5D2_CHAN_SINGLE(3, 3, 0x5c),
+	AT91_SAMA5D2_CHAN_SINGLE(4, 4, 0x60),
+	AT91_SAMA5D2_CHAN_SINGLE(5, 5, 0x64),
+	AT91_SAMA5D2_CHAN_SINGLE(6, 6, 0x68),
+	AT91_SAMA5D2_CHAN_SINGLE(7, 7, 0x6c),
+	AT91_SAMA5D2_CHAN_SINGLE(8, 8, 0x70),
+	AT91_SAMA5D2_CHAN_SINGLE(9, 9, 0x74),
+	AT91_SAMA5D2_CHAN_SINGLE(10, 10, 0x78),
+	AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x7c),
+	AT91_SAMA5D2_CHAN_DIFF(12, 0, 1, 0x50),
+	AT91_SAMA5D2_CHAN_DIFF(13, 2, 3, 0x58),
+	AT91_SAMA5D2_CHAN_DIFF(14, 4, 5, 0x60),
+	AT91_SAMA5D2_CHAN_DIFF(15, 6, 7, 0x68),
+	AT91_SAMA5D2_CHAN_DIFF(16, 8, 9, 0x70),
+	AT91_SAMA5D2_CHAN_DIFF(17, 10, 11, 0x78),
+	IIO_CHAN_SOFT_TIMESTAMP(18),
+	AT91_SAMA5D2_CHAN_TOUCH(19, "x", IIO_MOD_X),
+	AT91_SAMA5D2_CHAN_TOUCH(20, "y", IIO_MOD_Y),
+	AT91_SAMA5D2_CHAN_PRESSURE(21, "pressure"),
+};
+
+static const struct at91_adc_platform sama5d2_platform = {
+	.layout = &sama5d2_layout,
+	.adc_channels = &at91_sama5d2_adc_channels,
+#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
+#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
+	.nr_channels = AT91_SAMA5D2_SINGLE_CHAN_CNT +
+		       AT91_SAMA5D2_DIFF_CHAN_CNT,
+#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX	(AT91_SAMA5D2_SINGLE_CHAN_CNT + \
+					AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
+	.touch_chan_x = AT91_SAMA5D2_TOUCH_X_CHAN_IDX,
+#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX	(AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
+	.touch_chan_y = AT91_SAMA5D2_TOUCH_Y_CHAN_IDX,
+#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX	(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
+	.touch_chan_p = AT91_SAMA5D2_TOUCH_P_CHAN_IDX,
+#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
+	.max_channels = ARRAY_SIZE(at91_sama5d2_adc_channels),
+#define AT91_SAMA5D2_HW_TRIG_CNT	3
+	.hw_trig_cnt = AT91_SAMA5D2_HW_TRIG_CNT,
 };
 
 static int at91_adc_chan_xlate(struct iio_dev *indio_dev, int chan)
@@ -493,6 +569,7 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
 {
 	u32 mask = 0;
 	u8 bit;
+	struct at91_adc_state *st = iio_priv(indio_dev);
 
 	for_each_set_bit(bit, indio_dev->active_scan_mask,
 			 indio_dev->num_channels) {
@@ -501,13 +578,13 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
 		mask |= BIT(chan->channel);
 	}
 
-	return mask & GENMASK(11, 0);
+	return mask & GENMASK(st->soc_info.platform->nr_channels, 0);
 }
 
 static void at91_adc_config_emr(struct at91_adc_state *st)
 {
 	/* configure the extended mode register */
-	unsigned int emr = at91_adc_readl(st, AT91_SAMA5D2_EMR);
+	unsigned int emr = at91_adc_readl(st, EMR);
 
 	/* select oversampling per single trigger event */
 	emr |= AT91_SAMA5D2_EMR_ASTE(1);
@@ -531,7 +608,7 @@ static void at91_adc_config_emr(struct at91_adc_state *st)
 		break;
 	}
 
-	at91_adc_writel(st, AT91_SAMA5D2_EMR, emr);
+	at91_adc_writel(st, EMR, emr);
 }
 
 static int at91_adc_adjust_val_osr(struct at91_adc_state *st, int *val)
@@ -584,9 +661,9 @@ static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
 
 	if (!state) {
 		/* disabling touch IRQs and setting mode to no touch enabled */
-		at91_adc_writel(st, AT91_SAMA5D2_IDR,
+		at91_adc_writel(st, IDR,
 				AT91_SAMA5D2_IER_PEN | AT91_SAMA5D2_IER_NOPEN);
-		at91_adc_writel(st, AT91_SAMA5D2_TSMR, 0);
+		at91_adc_writel(st, TSMR, 0);
 		return 0;
 	}
 	/*
@@ -612,19 +689,19 @@ static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
 	tsmr |= AT91_SAMA5D2_TSMR_PENDET_ENA;
 	tsmr |= AT91_SAMA5D2_TSMR_TSFREQ(2) & AT91_SAMA5D2_TSMR_TSFREQ_MASK;
 
-	at91_adc_writel(st, AT91_SAMA5D2_TSMR, tsmr);
+	at91_adc_writel(st, TSMR, tsmr);
 
-	acr =  at91_adc_readl(st, AT91_SAMA5D2_ACR);
+	acr =  at91_adc_readl(st, ACR);
 	acr &= ~AT91_SAMA5D2_ACR_PENDETSENS_MASK;
 	acr |= 0x02 & AT91_SAMA5D2_ACR_PENDETSENS_MASK;
-	at91_adc_writel(st, AT91_SAMA5D2_ACR, acr);
+	at91_adc_writel(st, ACR, acr);
 
 	/* Sample Period Time = (TRGPER + 1) / ADCClock */
 	st->touch_st.sample_period_val =
 				 round_up((AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US *
 				 clk_khz / 1000) - 1, 1);
 	/* enable pen detect IRQ */
-	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
+	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_PEN);
 
 	return 0;
 }
@@ -640,7 +717,11 @@ static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
 	 * max = 2^AT91_SAMA5D2_MAX_POS_BITS - 1
 	 */
 	/* first half of register is the x or y, second half is the scale */
-	val = at91_adc_readl(st, reg);
+	if (reg == st->soc_info.platform->layout->XPOSR)
+		val = at91_adc_readl(st, XPOSR);
+	else if (reg == st->soc_info.platform->layout->YPOSR)
+		val = at91_adc_readl(st, YPOSR);
+
 	if (!val)
 		dev_dbg(&st->indio_dev->dev, "pos is 0\n");
 
@@ -658,13 +739,13 @@ static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
 
 static u16 at91_adc_touch_x_pos(struct at91_adc_state *st)
 {
-	st->touch_st.x_pos = at91_adc_touch_pos(st, AT91_SAMA5D2_XPOSR);
+	st->touch_st.x_pos = at91_adc_touch_pos(st, st->soc_info.platform->layout->XPOSR);
 	return st->touch_st.x_pos;
 }
 
 static u16 at91_adc_touch_y_pos(struct at91_adc_state *st)
 {
-	return at91_adc_touch_pos(st, AT91_SAMA5D2_YPOSR);
+	return at91_adc_touch_pos(st, st->soc_info.platform->layout->YPOSR);
 }
 
 static u16 at91_adc_touch_pressure(struct at91_adc_state *st)
@@ -676,7 +757,7 @@ static u16 at91_adc_touch_pressure(struct at91_adc_state *st)
 	u32 factor = 1000;
 
 	/* calculate the pressure */
-	val = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
+	val = at91_adc_readl(st, PRESSR);
 	z1 = val & AT91_SAMA5D2_XYZ_MASK;
 	z2 = (val >> 16) & AT91_SAMA5D2_XYZ_MASK;
 
@@ -700,9 +781,9 @@ static int at91_adc_read_position(struct at91_adc_state *st, int chan, u16 *val)
 	*val = 0;
 	if (!st->touch_st.touching)
 		return -ENODATA;
-	if (chan == AT91_SAMA5D2_TOUCH_X_CHAN_IDX)
+	if (chan == st->soc_info.platform->touch_chan_x)
 		*val = at91_adc_touch_x_pos(st);
-	else if (chan == AT91_SAMA5D2_TOUCH_Y_CHAN_IDX)
+	else if (chan == st->soc_info.platform->touch_chan_y)
 		*val = at91_adc_touch_y_pos(st);
 	else
 		return -ENODATA;
@@ -715,7 +796,7 @@ static int at91_adc_read_pressure(struct at91_adc_state *st, int chan, u16 *val)
 	*val = 0;
 	if (!st->touch_st.touching)
 		return -ENODATA;
-	if (chan == AT91_SAMA5D2_TOUCH_P_CHAN_IDX)
+	if (chan == st->soc_info.platform->touch_chan_y)
 		*val = at91_adc_touch_pressure(st);
 	else
 		return -ENODATA;
@@ -727,7 +808,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
 {
 	struct iio_dev *indio = iio_trigger_get_drvdata(trig);
 	struct at91_adc_state *st = iio_priv(indio);
-	u32 status = at91_adc_readl(st, AT91_SAMA5D2_TRGR);
+	u32 status = at91_adc_readl(st, TRGR);
 
 	/* clear TRGMOD */
 	status &= ~AT91_SAMA5D2_TRGR_TRGMOD_MASK;
@@ -736,7 +817,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
 		status |= st->selected_trig->trgmod_value;
 
 	/* set/unset hw trigger */
-	at91_adc_writel(st, AT91_SAMA5D2_TRGR, status);
+	at91_adc_writel(st, TRGR, status);
 
 	return 0;
 }
@@ -753,7 +834,7 @@ static void at91_adc_reenable_trigger(struct iio_trigger *trig)
 	enable_irq(st->irq);
 
 	/* Needed to ACK the DRDY interruption */
-	at91_adc_readl(st, AT91_SAMA5D2_LCDR);
+	at91_adc_readl(st, LCDR);
 }
 
 static const struct iio_trigger_ops at91_adc_trigger_ops = {
@@ -848,7 +929,7 @@ static int at91_adc_dma_start(struct iio_dev *indio_dev)
 	}
 
 	/* enable general overrun error signaling */
-	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_GOVRE);
+	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_GOVRE);
 	/* Issue pending DMA requests */
 	dma_async_issue_pending(st->dma_st.dma_chan);
 
@@ -878,7 +959,7 @@ static bool at91_adc_current_chan_is_touch(struct iio_dev *indio_dev)
 
 	return !!bitmap_subset(indio_dev->active_scan_mask,
 			       &st->touch_st.channels_bitmask,
-			       AT91_SAMA5D2_MAX_CHAN_IDX + 1);
+			       st->soc_info.platform->max_channels + 1);
 }
 
 static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
@@ -915,7 +996,7 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
 		    chan->type == IIO_PRESSURE)
 			continue;
 
-		cor = at91_adc_readl(st, AT91_SAMA5D2_COR);
+		cor = at91_adc_readl(st, COR);
 
 		if (chan->differential)
 			cor |= (BIT(chan->channel) | BIT(chan->channel2)) <<
@@ -924,13 +1005,13 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
 			cor &= ~(BIT(chan->channel) <<
 			       AT91_SAMA5D2_COR_DIFF_OFFSET);
 
-		at91_adc_writel(st, AT91_SAMA5D2_COR, cor);
+		at91_adc_writel(st, COR, cor);
 
-		at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel));
+		at91_adc_writel(st, CHER, BIT(chan->channel));
 	}
 
 	if (at91_adc_buffer_check_use_irq(indio_dev, st))
-		at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_DRDY);
+		at91_adc_writel(st, IER, AT91_SAMA5D2_IER_DRDY);
 
 	return 0;
 }
@@ -966,17 +1047,17 @@ static int at91_adc_buffer_postdisable(struct iio_dev *indio_dev)
 		    chan->type == IIO_PRESSURE)
 			continue;
 
-		at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
+		at91_adc_writel(st, CHDR, BIT(chan->channel));
 
 		if (st->dma_st.dma_chan)
-			at91_adc_readl(st, chan->address);
+			at91_adc_read_chan(st, chan->address);
 	}
 
 	if (at91_adc_buffer_check_use_irq(indio_dev, st))
-		at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_DRDY);
+		at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_DRDY);
 
 	/* read overflow register to clear possible overflow status */
-	at91_adc_readl(st, AT91_SAMA5D2_OVER);
+	at91_adc_readl(st, OVER);
 
 	/* if we are using DMA we must clear registers and end DMA */
 	if (st->dma_st.dma_chan)
@@ -1024,7 +1105,7 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
 	 * Check if the conversion is ready. If not, wait a little bit, and
 	 * in case of timeout exit with an error.
 	 */
-	while ((at91_adc_readl(st, AT91_SAMA5D2_ISR) & mask) != mask &&
+	while ((at91_adc_readl(st, ISR) & mask) != mask &&
 	       timeout) {
 		usleep_range(50, 100);
 		timeout--;
@@ -1052,7 +1133,7 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
 		 * Thus, emit a warning.
 		 */
 		if (chan->type == IIO_VOLTAGE) {
-			val = at91_adc_readl(st, chan->address);
+			val = at91_adc_read_chan(st, chan->address);
 			at91_adc_adjust_val_osr(st, &val);
 			st->buffer[i] = val;
 		} else {
@@ -1073,7 +1154,7 @@ static void at91_adc_trigger_handler_dma(struct iio_dev *indio_dev)
 	s64 interval;
 	int sample_index = 0, sample_count, sample_size;
 
-	u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
+	u32 status = at91_adc_readl(st, ISR);
 	/* if we reached this point, we cannot sample faster */
 	if (status & AT91_SAMA5D2_IER_GOVRE)
 		pr_info_ratelimited("%s: conversion overrun detected\n",
@@ -1125,7 +1206,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
 	 * actually polling the trigger now.
 	 */
 	if (iio_trigger_validate_own_device(indio_dev->trig, indio_dev))
-		at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START);
+		at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
 
 	if (st->dma_st.dma_chan)
 		at91_adc_trigger_handler_dma(indio_dev);
@@ -1172,11 +1253,11 @@ static void at91_adc_setup_samp_freq(struct iio_dev *indio_dev, unsigned freq)
 	startup = at91_adc_startup_time(st->soc_info.startup_time,
 					freq / 1000);
 
-	mr = at91_adc_readl(st, AT91_SAMA5D2_MR);
+	mr = at91_adc_readl(st, MR);
 	mr &= ~(AT91_SAMA5D2_MR_STARTUP_MASK | AT91_SAMA5D2_MR_PRESCAL_MASK);
 	mr |= AT91_SAMA5D2_MR_STARTUP(startup);
 	mr |= AT91_SAMA5D2_MR_PRESCAL(prescal);
-	at91_adc_writel(st, AT91_SAMA5D2_MR, mr);
+	at91_adc_writel(st, MR, mr);
 
 	dev_dbg(&indio_dev->dev, "freq: %u, startup: %u, prescal: %u\n",
 		freq, startup, prescal);
@@ -1196,7 +1277,7 @@ static void at91_adc_touch_data_handler(struct iio_dev *indio_dev)
 	int i = 0;
 
 	for_each_set_bit(bit, indio_dev->active_scan_mask,
-			 AT91_SAMA5D2_MAX_CHAN_IDX + 1) {
+			 st->soc_info.platform->max_channels + 1) {
 		struct iio_chan_spec const *chan =
 					 at91_adc_chan_get(indio_dev, bit);
 
@@ -1222,12 +1303,11 @@ static void at91_adc_touch_data_handler(struct iio_dev *indio_dev)
 
 static void at91_adc_pen_detect_interrupt(struct at91_adc_state *st)
 {
-	at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_PEN);
-	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_NOPEN |
+	at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_PEN);
+	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_NOPEN |
 			AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
 			AT91_SAMA5D2_IER_PRDY);
-	at91_adc_writel(st, AT91_SAMA5D2_TRGR,
-			AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC |
+	at91_adc_writel(st, TRGR, AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC |
 			AT91_SAMA5D2_TRGR_TRGPER(st->touch_st.sample_period_val));
 	st->touch_st.touching = true;
 }
@@ -1236,16 +1316,15 @@ static void at91_adc_no_pen_detect_interrupt(struct iio_dev *indio_dev)
 {
 	struct at91_adc_state *st = iio_priv(indio_dev);
 
-	at91_adc_writel(st, AT91_SAMA5D2_TRGR,
-			AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER);
-	at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_NOPEN |
+	at91_adc_writel(st, TRGR, AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER);
+	at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_NOPEN |
 			AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
 			AT91_SAMA5D2_IER_PRDY);
 	st->touch_st.touching = false;
 
 	at91_adc_touch_data_handler(indio_dev);
 
-	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
+	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_PEN);
 }
 
 static void at91_adc_workq_handler(struct work_struct *workq)
@@ -1263,8 +1342,8 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
 {
 	struct iio_dev *indio = private;
 	struct at91_adc_state *st = iio_priv(indio);
-	u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
-	u32 imr = at91_adc_readl(st, AT91_SAMA5D2_IMR);
+	u32 status = at91_adc_readl(st, ISR);
+	u32 imr = at91_adc_readl(st, IMR);
 	u32 rdy_mask = AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
 			AT91_SAMA5D2_IER_PRDY;
 
@@ -1285,9 +1364,9 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
 		 * touching, but the measurements are not ready yet.
 		 * read and ignore.
 		 */
-		status = at91_adc_readl(st, AT91_SAMA5D2_XPOSR);
-		status = at91_adc_readl(st, AT91_SAMA5D2_YPOSR);
-		status = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
+		status = at91_adc_readl(st, XPOSR);
+		status = at91_adc_readl(st, YPOSR);
+		status = at91_adc_readl(st, PRESSR);
 	} else if (iio_buffer_enabled(indio) &&
 		   (status & AT91_SAMA5D2_IER_DRDY)) {
 		/* triggered buffer without DMA */
@@ -1299,7 +1378,7 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
 		WARN(true, "Unexpected irq occurred\n");
 	} else if (!iio_buffer_enabled(indio)) {
 		/* software requested conversion */
-		st->conversion_value = at91_adc_readl(st, st->chan->address);
+		st->conversion_value = at91_adc_read_chan(st, st->chan->address);
 		st->conversion_done = true;
 		wake_up_interruptible(&st->wq_data_available);
 	}
@@ -1360,10 +1439,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
 		cor = (BIT(chan->channel) | BIT(chan->channel2)) <<
 		      AT91_SAMA5D2_COR_DIFF_OFFSET;
 
-	at91_adc_writel(st, AT91_SAMA5D2_COR, cor);
-	at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel));
-	at91_adc_writel(st, AT91_SAMA5D2_IER, BIT(chan->channel));
-	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START);
+	at91_adc_writel(st, COR, cor);
+	at91_adc_writel(st, CHER, BIT(chan->channel));
+	at91_adc_writel(st, IER, BIT(chan->channel));
+	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
 
 	ret = wait_event_interruptible_timeout(st->wq_data_available,
 					       st->conversion_done,
@@ -1379,11 +1458,11 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
 		st->conversion_done = false;
 	}
 
-	at91_adc_writel(st, AT91_SAMA5D2_IDR, BIT(chan->channel));
-	at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
+	at91_adc_writel(st, IDR, BIT(chan->channel));
+	at91_adc_writel(st, CHDR, BIT(chan->channel));
 
 	/* Needed to ACK the DRDY interruption */
-	at91_adc_readl(st, AT91_SAMA5D2_LCDR);
+	at91_adc_readl(st, LCDR);
 
 	mutex_unlock(&st->lock);
 
@@ -1455,14 +1534,15 @@ static void at91_adc_dma_init(struct platform_device *pdev)
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct at91_adc_state *st = iio_priv(indio_dev);
 	struct dma_slave_config config = {0};
+	/* we have 2 bytes for each channel */
+	unsigned int sample_size = st->soc_info.platform->nr_channels * 2;
 	/*
 	 * We make the buffer double the size of the fifo,
 	 * such that DMA uses one half of the buffer (full fifo size)
 	 * and the software uses the other half to read/write.
 	 */
 	unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
-					  AT91_BUFFER_MAX_CONVERSION_BYTES * 2,
-					  PAGE_SIZE);
+					  sample_size * 2, PAGE_SIZE);
 
 	if (st->dma_st.dma_chan)
 		return;
@@ -1486,7 +1566,7 @@ static void at91_adc_dma_init(struct platform_device *pdev)
 	/* Configure DMA channel to read data register */
 	config.direction = DMA_DEV_TO_MEM;
 	config.src_addr = (phys_addr_t)(st->dma_st.phys_addr
-			  + AT91_SAMA5D2_LCDR);
+			  + st->soc_info.platform->layout->LCDR);
 	config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
 	config.src_maxburst = 1;
 	config.dst_maxburst = 1;
@@ -1515,9 +1595,10 @@ static void at91_adc_dma_disable(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct at91_adc_state *st = iio_priv(indio_dev);
+	/* we have 2 bytes for each channel */
+	unsigned int sample_size = st->soc_info.platform->nr_channels * 2;
 	unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
-					  AT91_BUFFER_MAX_CONVERSION_BYTES * 2,
-					  PAGE_SIZE);
+					  sample_size * 2, PAGE_SIZE);
 
 	/* if we are not using DMA, just return */
 	if (!st->dma_st.dma_chan)
@@ -1578,14 +1659,14 @@ static int at91_adc_update_scan_mode(struct iio_dev *indio_dev,
 	struct at91_adc_state *st = iio_priv(indio_dev);
 
 	if (bitmap_subset(scan_mask, &st->touch_st.channels_bitmask,
-			  AT91_SAMA5D2_MAX_CHAN_IDX + 1))
+			  st->soc_info.platform->max_channels + 1))
 		return 0;
 	/*
 	 * if the new bitmap is a combination of touchscreen and regular
 	 * channels, then we are not fine
 	 */
 	if (bitmap_intersects(&st->touch_st.channels_bitmask, scan_mask,
-			      AT91_SAMA5D2_MAX_CHAN_IDX + 1))
+			      st->soc_info.platform->max_channels + 1))
 		return -EINVAL;
 	return 0;
 }
@@ -1594,13 +1675,13 @@ static void at91_adc_hw_init(struct iio_dev *indio_dev)
 {
 	struct at91_adc_state *st = iio_priv(indio_dev);
 
-	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
-	at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff);
+	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
+	at91_adc_writel(st, IDR, 0xffffffff);
 	/*
 	 * Transfer field must be set to 2 according to the datasheet and
 	 * allows different analog settings for each channel.
 	 */
-	at91_adc_writel(st, AT91_SAMA5D2_MR,
+	at91_adc_writel(st, MR,
 			AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH);
 
 	at91_adc_setup_samp_freq(indio_dev, st->soc_info.min_sample_rate);
@@ -1716,21 +1797,23 @@ static int at91_adc_probe(struct platform_device *pdev)
 	if (!indio_dev)
 		return -ENOMEM;
 
+	st = iio_priv(indio_dev);
+	st->indio_dev = indio_dev;
+
+	st->soc_info.platform = of_device_get_match_data(&pdev->dev);
+
 	indio_dev->name = dev_name(&pdev->dev);
 	indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
 	indio_dev->info = &at91_adc_info;
-	indio_dev->channels = at91_adc_channels;
-	indio_dev->num_channels = ARRAY_SIZE(at91_adc_channels);
-
-	st = iio_priv(indio_dev);
-	st->indio_dev = indio_dev;
+	indio_dev->channels = *st->soc_info.platform->adc_channels;
+	indio_dev->num_channels = st->soc_info.platform->max_channels;
 
 	bitmap_set(&st->touch_st.channels_bitmask,
-		   AT91_SAMA5D2_TOUCH_X_CHAN_IDX, 1);
+		   st->soc_info.platform->touch_chan_x, 1);
 	bitmap_set(&st->touch_st.channels_bitmask,
-		   AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, 1);
+		   st->soc_info.platform->touch_chan_y, 1);
 	bitmap_set(&st->touch_st.channels_bitmask,
-		   AT91_SAMA5D2_TOUCH_P_CHAN_IDX, 1);
+		   st->soc_info.platform->touch_chan_p, 1);
 
 	st->oversampling_ratio = AT91_OSR_1SAMPLES;
 
@@ -1770,7 +1853,7 @@ static int at91_adc_probe(struct platform_device *pdev)
 	st->selected_trig = NULL;
 
 	/* find the right trigger, or no trigger at all */
-	for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT + 1; i++)
+	for (i = 0; i < st->soc_info.platform->hw_trig_cnt + 1; i++)
 		if (at91_adc_trigger_list[i].edge_type == edge_type) {
 			st->selected_trig = &at91_adc_trigger_list[i];
 			break;
@@ -1855,7 +1938,7 @@ static int at91_adc_probe(struct platform_device *pdev)
 			 st->selected_trig->name);
 
 	dev_info(&pdev->dev, "version: %x\n",
-		 readl_relaxed(st->base + AT91_SAMA5D2_VERSION));
+		 readl_relaxed(st->base + st->soc_info.platform->layout->VERSION));
 
 	return 0;
 
@@ -1898,7 +1981,7 @@ static __maybe_unused int at91_adc_suspend(struct device *dev)
 	 * and can be used by for other devices.
 	 * Otherwise, ADC will hog them and we can't go to suspend mode.
 	 */
-	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
+	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
 
 	clk_disable_unprepare(st->per_clk);
 	regulator_disable(st->vref);
@@ -1958,6 +2041,7 @@ static SIMPLE_DEV_PM_OPS(at91_adc_pm_ops, at91_adc_suspend, at91_adc_resume);
 static const struct of_device_id at91_adc_dt_match[] = {
 	{
 		.compatible = "atmel,sama5d2-adc",
+		.data = (const void *)&sama5d2_platform,
 	}, {
 		/* sentinel */
 	}
-- 
2.25.1


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

* [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform specific data structures
@ 2021-08-24 11:54   ` Eugen Hristev
  0 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev

Convert the driver to platform specific structures. This means:
- create a register layout struct that will hold offsets for registers
- create a platform struct that will hold platform information (number of
channels, indexes for different channels and pointer to layout struct)
- convert specific macros that are platform dependent into platform variables

This step is in fact a no-op, but allows the driver to be more flexible
and for future enhancement including adding new platforms that are partly
compatible with the current driver and differ slightly in register layout
or capabilities for example.

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
 1 file changed, 247 insertions(+), 163 deletions(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index 9d71dcffcf93..8ede18b8d789 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -27,8 +27,9 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/regulator/consumer.h>
 
+struct at91_adc_reg_layout {
 /* Control Register */
-#define AT91_SAMA5D2_CR		0x00
+	u16				CR;
 /* Software Reset */
 #define	AT91_SAMA5D2_CR_SWRST		BIT(0)
 /* Start Conversion */
@@ -39,7 +40,7 @@
 #define	AT91_SAMA5D2_CR_CMPRST		BIT(4)
 
 /* Mode Register */
-#define AT91_SAMA5D2_MR		0x04
+	u16				MR;
 /* Trigger Selection */
 #define	AT91_SAMA5D2_MR_TRGSEL(v)	((v) << 1)
 /* ADTRG */
@@ -82,19 +83,19 @@
 #define	AT91_SAMA5D2_MR_USEQ		BIT(31)
 
 /* Channel Sequence Register 1 */
-#define AT91_SAMA5D2_SEQR1	0x08
+	u16				SEQR1;
 /* Channel Sequence Register 2 */
-#define AT91_SAMA5D2_SEQR2	0x0c
+	u16				SEQR2;
 /* Channel Enable Register */
-#define AT91_SAMA5D2_CHER	0x10
+	u16				CHER;
 /* Channel Disable Register */
-#define AT91_SAMA5D2_CHDR	0x14
+	u16				CHDR;
 /* Channel Status Register */
-#define AT91_SAMA5D2_CHSR	0x18
+	u16				CHSR;
 /* Last Converted Data Register */
-#define AT91_SAMA5D2_LCDR	0x20
+	u16				LCDR;
 /* Interrupt Enable Register */
-#define AT91_SAMA5D2_IER	0x24
+	u16				IER;
 /* Interrupt Enable Register - TS X measurement ready */
 #define AT91_SAMA5D2_IER_XRDY   BIT(20)
 /* Interrupt Enable Register - TS Y measurement ready */
@@ -109,22 +110,23 @@
 #define AT91_SAMA5D2_IER_PEN    BIT(29)
 /* Interrupt Enable Register - No pen detect */
 #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
+
 /* Interrupt Disable Register */
-#define AT91_SAMA5D2_IDR	0x28
+	u16				IDR;
 /* Interrupt Mask Register */
-#define AT91_SAMA5D2_IMR	0x2c
+	u16				IMR;
 /* Interrupt Status Register */
-#define AT91_SAMA5D2_ISR	0x30
+	u16				ISR;
 /* Interrupt Status Register - Pen touching sense status */
 #define AT91_SAMA5D2_ISR_PENS   BIT(31)
 /* Last Channel Trigger Mode Register */
-#define AT91_SAMA5D2_LCTMR	0x34
+	u16				LCTMR;
 /* Last Channel Compare Window Register */
-#define AT91_SAMA5D2_LCCWR	0x38
+	u16				LCCWR;
 /* Overrun Status Register */
-#define AT91_SAMA5D2_OVER	0x3c
+	u16				OVER;
 /* Extended Mode Register */
-#define AT91_SAMA5D2_EMR	0x40
+	u16				EMR;
 /* Extended Mode Register - Oversampling rate */
 #define AT91_SAMA5D2_EMR_OSR(V)			((V) << 16)
 #define AT91_SAMA5D2_EMR_OSR_MASK		GENMASK(17, 16)
@@ -134,22 +136,22 @@
 
 /* Extended Mode Register - Averaging on single trigger event */
 #define AT91_SAMA5D2_EMR_ASTE(V)		((V) << 20)
+
 /* Compare Window Register */
-#define AT91_SAMA5D2_CWR	0x44
+	u16				CWR;
 /* Channel Gain Register */
-#define AT91_SAMA5D2_CGR	0x48
-
+	u16				CGR;
 /* Channel Offset Register */
-#define AT91_SAMA5D2_COR	0x4c
+	u16				COR;
 #define AT91_SAMA5D2_COR_DIFF_OFFSET	16
 
 /* Analog Control Register */
-#define AT91_SAMA5D2_ACR	0x94
+	u16				ACR;
 /* Analog Control Register - Pen detect sensitivity mask */
 #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
 
 /* Touchscreen Mode Register */
-#define AT91_SAMA5D2_TSMR	0xb0
+	u16				TSMR;
 /* Touchscreen Mode Register - No touch mode */
 #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
 /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
@@ -178,13 +180,13 @@
 #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
 
 /* Touchscreen X Position Register */
-#define AT91_SAMA5D2_XPOSR	0xb4
+	u16				XPOSR;
 /* Touchscreen Y Position Register */
-#define AT91_SAMA5D2_YPOSR	0xb8
+	u16				YPOSR;
 /* Touchscreen Pressure Register */
-#define AT91_SAMA5D2_PRESSR	0xbc
+	u16				PRESSR;
 /* Trigger Register */
-#define AT91_SAMA5D2_TRGR	0xc0
+	u16				TRGR;
 /* Mask for TRGMOD field of TRGR register */
 #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
 /* No trigger, only software trigger can start conversions */
@@ -203,30 +205,52 @@
 #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
 
 /* Correction Select Register */
-#define AT91_SAMA5D2_COSR	0xd0
+	u16				COSR;
 /* Correction Value Register */
-#define AT91_SAMA5D2_CVR	0xd4
+	u16				CVR;
 /* Channel Error Correction Register */
-#define AT91_SAMA5D2_CECR	0xd8
+	u16				CECR;
 /* Write Protection Mode Register */
-#define AT91_SAMA5D2_WPMR	0xe4
+	u16				WPMR;
 /* Write Protection Status Register */
-#define AT91_SAMA5D2_WPSR	0xe8
+	u16				WPSR;
 /* Version Register */
-#define AT91_SAMA5D2_VERSION	0xfc
-
-#define AT91_SAMA5D2_HW_TRIG_CNT 3
-#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
-#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
-
-#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
-					 AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
+	u16				VERSION;
+};
 
-#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
-					 AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
-#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
-#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
-#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
+static const struct at91_adc_reg_layout sama5d2_layout = {
+	.CR =			0x00,
+	.MR =			0x04,
+	.SEQR1 =		0x08,
+	.SEQR2 =		0x0c,
+	.CHER =			0x10,
+	.CHDR =			0x14,
+	.CHSR =			0x18,
+	.LCDR =			0x20,
+	.IER =			0x24,
+	.IDR =			0x28,
+	.IMR =			0x2c,
+	.ISR =			0x30,
+	.LCTMR =		0x34,
+	.LCCWR =		0x38,
+	.OVER =			0x3c,
+	.EMR =			0x40,
+	.CWR =			0x44,
+	.CGR =			0x48,
+	.COR =			0x4c,
+	.ACR =			0x94,
+	.TSMR =			0xb0,
+	.XPOSR =		0xb4,
+	.YPOSR =		0xb8,
+	.PRESSR =		0xbc,
+	.TRGR =			0xc0,
+	.COSR =			0xd0,
+	.CVR =			0xd4,
+	.CECR =			0xd8,
+	.WPMR =			0xe4,
+	.WPSR =			0xe8,
+	.VERSION =		0xfc,
+};
 
 #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
 #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
@@ -235,18 +259,6 @@
 
 #define AT91_SAMA5D2_MAX_POS_BITS			12
 
-/*
- * Maximum number of bytes to hold conversion from all channels
- * without the timestamp.
- */
-#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
-					 AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
-
-/* This total must also include the timestamp */
-#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
-
-#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
-
 #define AT91_HWFIFO_MAX_SIZE_STR	"128"
 #define AT91_HWFIFO_MAX_SIZE		128
 
@@ -255,12 +267,12 @@
 #define AT91_OSR_4SAMPLES		4
 #define AT91_OSR_16SAMPLES		16
 
-#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)				\
+#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)			\
 	{								\
 		.type = IIO_VOLTAGE,					\
 		.channel = num,						\
 		.address = addr,					\
-		.scan_index = num,					\
+		.scan_index = index,					\
 		.scan_type = {						\
 			.sign = 'u',					\
 			.realbits = 14,					\
@@ -274,14 +286,14 @@
 		.indexed = 1,						\
 	}
 
-#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)				\
+#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)			\
 	{								\
 		.type = IIO_VOLTAGE,					\
 		.differential = 1,					\
 		.channel = num,						\
 		.channel2 = num2,					\
 		.address = addr,					\
-		.scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,	\
+		.scan_index = index,					\
 		.scan_type = {						\
 			.sign = 's',					\
 			.realbits = 14,					\
@@ -328,13 +340,48 @@
 		.datasheet_name = name,					\
 	}
 
-#define at91_adc_readl(st, reg)		readl_relaxed(st->base + reg)
-#define at91_adc_writel(st, reg, val)	writel_relaxed(val, st->base + reg)
+#define at91_adc_readl(st, reg)						\
+	readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
+#define at91_adc_read_chan(st, reg)					\
+	readl_relaxed((st)->base + reg)
+#define at91_adc_writel(st, reg, val)					\
+	writel_relaxed(val, (st)->base + (st)->soc_info.platform->layout->reg)
+
+/**
+ * struct at91_adc_platform - at91-sama5d2 platform information struct
+ * @layout:		pointer to the reg layout struct
+ * @adc_channels:	pointer to an array of channels for registering in
+ *			the iio subsystem
+ * @nr_channels:	number of physical channels available
+ * @touch_chan_x:	index of the touchscreen X channel
+ * @touch_chan_y:	index of the touchscreen Y channel
+ * @touch_chan_p:	index of the touchscreen P channel
+ * @max_channels:	number of total channels
+ * @hw_trig_cnt:	number of possible hardware triggers
+ */
+struct at91_adc_platform {
+	const struct at91_adc_reg_layout	*layout;
+	const struct iio_chan_spec		(*adc_channels)[];
+	unsigned int				nr_channels;
+	unsigned int				touch_chan_x;
+	unsigned int				touch_chan_y;
+	unsigned int				touch_chan_p;
+	unsigned int				max_channels;
+	unsigned int				hw_trig_cnt;
+};
 
+/**
+ * struct at91_adc_soc_info - at91-sama5d2 soc information struct
+ * @startup_time:	device startup time
+ * @min_sample_rate:	minimum sample rate in Hz
+ * @max_sample_rate:	maximum sample rate in Hz
+ * @platform:		pointer to the platform structure
+ */
 struct at91_adc_soc_info {
 	unsigned			startup_time;
 	unsigned			min_sample_rate;
 	unsigned			max_sample_rate;
+	const struct at91_adc_platform	*platform;
 };
 
 struct at91_adc_trigger {
@@ -382,6 +429,15 @@ struct at91_adc_touch {
 	struct work_struct		workq;
 };
 
+/*
+ * Buffer size requirements:
+ * No channels * bytes_per_channel(2) + timestamp bytes (8)
+ * Divided by 2 because we need half words.
+ * We assume 32 channels for now, has to be increased if needed.
+ * Nobody minds a buffer being too big.
+ */
+#define AT91_BUFFER_MAX_HWORDS ((32 * 2 + 8) / 2)
+
 struct at91_adc_state {
 	void __iomem			*base;
 	int				irq;
@@ -437,29 +493,49 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = {
 	},
 };
 
-static const struct iio_chan_spec at91_adc_channels[] = {
-	AT91_SAMA5D2_CHAN_SINGLE(0, 0x50),
-	AT91_SAMA5D2_CHAN_SINGLE(1, 0x54),
-	AT91_SAMA5D2_CHAN_SINGLE(2, 0x58),
-	AT91_SAMA5D2_CHAN_SINGLE(3, 0x5c),
-	AT91_SAMA5D2_CHAN_SINGLE(4, 0x60),
-	AT91_SAMA5D2_CHAN_SINGLE(5, 0x64),
-	AT91_SAMA5D2_CHAN_SINGLE(6, 0x68),
-	AT91_SAMA5D2_CHAN_SINGLE(7, 0x6c),
-	AT91_SAMA5D2_CHAN_SINGLE(8, 0x70),
-	AT91_SAMA5D2_CHAN_SINGLE(9, 0x74),
-	AT91_SAMA5D2_CHAN_SINGLE(10, 0x78),
-	AT91_SAMA5D2_CHAN_SINGLE(11, 0x7c),
-	AT91_SAMA5D2_CHAN_DIFF(0, 1, 0x50),
-	AT91_SAMA5D2_CHAN_DIFF(2, 3, 0x58),
-	AT91_SAMA5D2_CHAN_DIFF(4, 5, 0x60),
-	AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68),
-	AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70),
-	AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78),
-	IIO_CHAN_SOFT_TIMESTAMP(AT91_SAMA5D2_TIMESTAMP_CHAN_IDX),
-	AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_X_CHAN_IDX, "x", IIO_MOD_X),
-	AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, "y", IIO_MOD_Y),
-	AT91_SAMA5D2_CHAN_PRESSURE(AT91_SAMA5D2_TOUCH_P_CHAN_IDX, "pressure"),
+static const struct iio_chan_spec at91_sama5d2_adc_channels[] = {
+	AT91_SAMA5D2_CHAN_SINGLE(0, 0, 0x50),
+	AT91_SAMA5D2_CHAN_SINGLE(1, 1, 0x54),
+	AT91_SAMA5D2_CHAN_SINGLE(2, 2, 0x58),
+	AT91_SAMA5D2_CHAN_SINGLE(3, 3, 0x5c),
+	AT91_SAMA5D2_CHAN_SINGLE(4, 4, 0x60),
+	AT91_SAMA5D2_CHAN_SINGLE(5, 5, 0x64),
+	AT91_SAMA5D2_CHAN_SINGLE(6, 6, 0x68),
+	AT91_SAMA5D2_CHAN_SINGLE(7, 7, 0x6c),
+	AT91_SAMA5D2_CHAN_SINGLE(8, 8, 0x70),
+	AT91_SAMA5D2_CHAN_SINGLE(9, 9, 0x74),
+	AT91_SAMA5D2_CHAN_SINGLE(10, 10, 0x78),
+	AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x7c),
+	AT91_SAMA5D2_CHAN_DIFF(12, 0, 1, 0x50),
+	AT91_SAMA5D2_CHAN_DIFF(13, 2, 3, 0x58),
+	AT91_SAMA5D2_CHAN_DIFF(14, 4, 5, 0x60),
+	AT91_SAMA5D2_CHAN_DIFF(15, 6, 7, 0x68),
+	AT91_SAMA5D2_CHAN_DIFF(16, 8, 9, 0x70),
+	AT91_SAMA5D2_CHAN_DIFF(17, 10, 11, 0x78),
+	IIO_CHAN_SOFT_TIMESTAMP(18),
+	AT91_SAMA5D2_CHAN_TOUCH(19, "x", IIO_MOD_X),
+	AT91_SAMA5D2_CHAN_TOUCH(20, "y", IIO_MOD_Y),
+	AT91_SAMA5D2_CHAN_PRESSURE(21, "pressure"),
+};
+
+static const struct at91_adc_platform sama5d2_platform = {
+	.layout = &sama5d2_layout,
+	.adc_channels = &at91_sama5d2_adc_channels,
+#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
+#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
+	.nr_channels = AT91_SAMA5D2_SINGLE_CHAN_CNT +
+		       AT91_SAMA5D2_DIFF_CHAN_CNT,
+#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX	(AT91_SAMA5D2_SINGLE_CHAN_CNT + \
+					AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
+	.touch_chan_x = AT91_SAMA5D2_TOUCH_X_CHAN_IDX,
+#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX	(AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
+	.touch_chan_y = AT91_SAMA5D2_TOUCH_Y_CHAN_IDX,
+#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX	(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
+	.touch_chan_p = AT91_SAMA5D2_TOUCH_P_CHAN_IDX,
+#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
+	.max_channels = ARRAY_SIZE(at91_sama5d2_adc_channels),
+#define AT91_SAMA5D2_HW_TRIG_CNT	3
+	.hw_trig_cnt = AT91_SAMA5D2_HW_TRIG_CNT,
 };
 
 static int at91_adc_chan_xlate(struct iio_dev *indio_dev, int chan)
@@ -493,6 +569,7 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
 {
 	u32 mask = 0;
 	u8 bit;
+	struct at91_adc_state *st = iio_priv(indio_dev);
 
 	for_each_set_bit(bit, indio_dev->active_scan_mask,
 			 indio_dev->num_channels) {
@@ -501,13 +578,13 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
 		mask |= BIT(chan->channel);
 	}
 
-	return mask & GENMASK(11, 0);
+	return mask & GENMASK(st->soc_info.platform->nr_channels, 0);
 }
 
 static void at91_adc_config_emr(struct at91_adc_state *st)
 {
 	/* configure the extended mode register */
-	unsigned int emr = at91_adc_readl(st, AT91_SAMA5D2_EMR);
+	unsigned int emr = at91_adc_readl(st, EMR);
 
 	/* select oversampling per single trigger event */
 	emr |= AT91_SAMA5D2_EMR_ASTE(1);
@@ -531,7 +608,7 @@ static void at91_adc_config_emr(struct at91_adc_state *st)
 		break;
 	}
 
-	at91_adc_writel(st, AT91_SAMA5D2_EMR, emr);
+	at91_adc_writel(st, EMR, emr);
 }
 
 static int at91_adc_adjust_val_osr(struct at91_adc_state *st, int *val)
@@ -584,9 +661,9 @@ static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
 
 	if (!state) {
 		/* disabling touch IRQs and setting mode to no touch enabled */
-		at91_adc_writel(st, AT91_SAMA5D2_IDR,
+		at91_adc_writel(st, IDR,
 				AT91_SAMA5D2_IER_PEN | AT91_SAMA5D2_IER_NOPEN);
-		at91_adc_writel(st, AT91_SAMA5D2_TSMR, 0);
+		at91_adc_writel(st, TSMR, 0);
 		return 0;
 	}
 	/*
@@ -612,19 +689,19 @@ static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
 	tsmr |= AT91_SAMA5D2_TSMR_PENDET_ENA;
 	tsmr |= AT91_SAMA5D2_TSMR_TSFREQ(2) & AT91_SAMA5D2_TSMR_TSFREQ_MASK;
 
-	at91_adc_writel(st, AT91_SAMA5D2_TSMR, tsmr);
+	at91_adc_writel(st, TSMR, tsmr);
 
-	acr =  at91_adc_readl(st, AT91_SAMA5D2_ACR);
+	acr =  at91_adc_readl(st, ACR);
 	acr &= ~AT91_SAMA5D2_ACR_PENDETSENS_MASK;
 	acr |= 0x02 & AT91_SAMA5D2_ACR_PENDETSENS_MASK;
-	at91_adc_writel(st, AT91_SAMA5D2_ACR, acr);
+	at91_adc_writel(st, ACR, acr);
 
 	/* Sample Period Time = (TRGPER + 1) / ADCClock */
 	st->touch_st.sample_period_val =
 				 round_up((AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US *
 				 clk_khz / 1000) - 1, 1);
 	/* enable pen detect IRQ */
-	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
+	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_PEN);
 
 	return 0;
 }
@@ -640,7 +717,11 @@ static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
 	 * max = 2^AT91_SAMA5D2_MAX_POS_BITS - 1
 	 */
 	/* first half of register is the x or y, second half is the scale */
-	val = at91_adc_readl(st, reg);
+	if (reg == st->soc_info.platform->layout->XPOSR)
+		val = at91_adc_readl(st, XPOSR);
+	else if (reg == st->soc_info.platform->layout->YPOSR)
+		val = at91_adc_readl(st, YPOSR);
+
 	if (!val)
 		dev_dbg(&st->indio_dev->dev, "pos is 0\n");
 
@@ -658,13 +739,13 @@ static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
 
 static u16 at91_adc_touch_x_pos(struct at91_adc_state *st)
 {
-	st->touch_st.x_pos = at91_adc_touch_pos(st, AT91_SAMA5D2_XPOSR);
+	st->touch_st.x_pos = at91_adc_touch_pos(st, st->soc_info.platform->layout->XPOSR);
 	return st->touch_st.x_pos;
 }
 
 static u16 at91_adc_touch_y_pos(struct at91_adc_state *st)
 {
-	return at91_adc_touch_pos(st, AT91_SAMA5D2_YPOSR);
+	return at91_adc_touch_pos(st, st->soc_info.platform->layout->YPOSR);
 }
 
 static u16 at91_adc_touch_pressure(struct at91_adc_state *st)
@@ -676,7 +757,7 @@ static u16 at91_adc_touch_pressure(struct at91_adc_state *st)
 	u32 factor = 1000;
 
 	/* calculate the pressure */
-	val = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
+	val = at91_adc_readl(st, PRESSR);
 	z1 = val & AT91_SAMA5D2_XYZ_MASK;
 	z2 = (val >> 16) & AT91_SAMA5D2_XYZ_MASK;
 
@@ -700,9 +781,9 @@ static int at91_adc_read_position(struct at91_adc_state *st, int chan, u16 *val)
 	*val = 0;
 	if (!st->touch_st.touching)
 		return -ENODATA;
-	if (chan == AT91_SAMA5D2_TOUCH_X_CHAN_IDX)
+	if (chan == st->soc_info.platform->touch_chan_x)
 		*val = at91_adc_touch_x_pos(st);
-	else if (chan == AT91_SAMA5D2_TOUCH_Y_CHAN_IDX)
+	else if (chan == st->soc_info.platform->touch_chan_y)
 		*val = at91_adc_touch_y_pos(st);
 	else
 		return -ENODATA;
@@ -715,7 +796,7 @@ static int at91_adc_read_pressure(struct at91_adc_state *st, int chan, u16 *val)
 	*val = 0;
 	if (!st->touch_st.touching)
 		return -ENODATA;
-	if (chan == AT91_SAMA5D2_TOUCH_P_CHAN_IDX)
+	if (chan == st->soc_info.platform->touch_chan_y)
 		*val = at91_adc_touch_pressure(st);
 	else
 		return -ENODATA;
@@ -727,7 +808,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
 {
 	struct iio_dev *indio = iio_trigger_get_drvdata(trig);
 	struct at91_adc_state *st = iio_priv(indio);
-	u32 status = at91_adc_readl(st, AT91_SAMA5D2_TRGR);
+	u32 status = at91_adc_readl(st, TRGR);
 
 	/* clear TRGMOD */
 	status &= ~AT91_SAMA5D2_TRGR_TRGMOD_MASK;
@@ -736,7 +817,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
 		status |= st->selected_trig->trgmod_value;
 
 	/* set/unset hw trigger */
-	at91_adc_writel(st, AT91_SAMA5D2_TRGR, status);
+	at91_adc_writel(st, TRGR, status);
 
 	return 0;
 }
@@ -753,7 +834,7 @@ static void at91_adc_reenable_trigger(struct iio_trigger *trig)
 	enable_irq(st->irq);
 
 	/* Needed to ACK the DRDY interruption */
-	at91_adc_readl(st, AT91_SAMA5D2_LCDR);
+	at91_adc_readl(st, LCDR);
 }
 
 static const struct iio_trigger_ops at91_adc_trigger_ops = {
@@ -848,7 +929,7 @@ static int at91_adc_dma_start(struct iio_dev *indio_dev)
 	}
 
 	/* enable general overrun error signaling */
-	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_GOVRE);
+	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_GOVRE);
 	/* Issue pending DMA requests */
 	dma_async_issue_pending(st->dma_st.dma_chan);
 
@@ -878,7 +959,7 @@ static bool at91_adc_current_chan_is_touch(struct iio_dev *indio_dev)
 
 	return !!bitmap_subset(indio_dev->active_scan_mask,
 			       &st->touch_st.channels_bitmask,
-			       AT91_SAMA5D2_MAX_CHAN_IDX + 1);
+			       st->soc_info.platform->max_channels + 1);
 }
 
 static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
@@ -915,7 +996,7 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
 		    chan->type == IIO_PRESSURE)
 			continue;
 
-		cor = at91_adc_readl(st, AT91_SAMA5D2_COR);
+		cor = at91_adc_readl(st, COR);
 
 		if (chan->differential)
 			cor |= (BIT(chan->channel) | BIT(chan->channel2)) <<
@@ -924,13 +1005,13 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
 			cor &= ~(BIT(chan->channel) <<
 			       AT91_SAMA5D2_COR_DIFF_OFFSET);
 
-		at91_adc_writel(st, AT91_SAMA5D2_COR, cor);
+		at91_adc_writel(st, COR, cor);
 
-		at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel));
+		at91_adc_writel(st, CHER, BIT(chan->channel));
 	}
 
 	if (at91_adc_buffer_check_use_irq(indio_dev, st))
-		at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_DRDY);
+		at91_adc_writel(st, IER, AT91_SAMA5D2_IER_DRDY);
 
 	return 0;
 }
@@ -966,17 +1047,17 @@ static int at91_adc_buffer_postdisable(struct iio_dev *indio_dev)
 		    chan->type == IIO_PRESSURE)
 			continue;
 
-		at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
+		at91_adc_writel(st, CHDR, BIT(chan->channel));
 
 		if (st->dma_st.dma_chan)
-			at91_adc_readl(st, chan->address);
+			at91_adc_read_chan(st, chan->address);
 	}
 
 	if (at91_adc_buffer_check_use_irq(indio_dev, st))
-		at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_DRDY);
+		at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_DRDY);
 
 	/* read overflow register to clear possible overflow status */
-	at91_adc_readl(st, AT91_SAMA5D2_OVER);
+	at91_adc_readl(st, OVER);
 
 	/* if we are using DMA we must clear registers and end DMA */
 	if (st->dma_st.dma_chan)
@@ -1024,7 +1105,7 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
 	 * Check if the conversion is ready. If not, wait a little bit, and
 	 * in case of timeout exit with an error.
 	 */
-	while ((at91_adc_readl(st, AT91_SAMA5D2_ISR) & mask) != mask &&
+	while ((at91_adc_readl(st, ISR) & mask) != mask &&
 	       timeout) {
 		usleep_range(50, 100);
 		timeout--;
@@ -1052,7 +1133,7 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
 		 * Thus, emit a warning.
 		 */
 		if (chan->type == IIO_VOLTAGE) {
-			val = at91_adc_readl(st, chan->address);
+			val = at91_adc_read_chan(st, chan->address);
 			at91_adc_adjust_val_osr(st, &val);
 			st->buffer[i] = val;
 		} else {
@@ -1073,7 +1154,7 @@ static void at91_adc_trigger_handler_dma(struct iio_dev *indio_dev)
 	s64 interval;
 	int sample_index = 0, sample_count, sample_size;
 
-	u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
+	u32 status = at91_adc_readl(st, ISR);
 	/* if we reached this point, we cannot sample faster */
 	if (status & AT91_SAMA5D2_IER_GOVRE)
 		pr_info_ratelimited("%s: conversion overrun detected\n",
@@ -1125,7 +1206,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
 	 * actually polling the trigger now.
 	 */
 	if (iio_trigger_validate_own_device(indio_dev->trig, indio_dev))
-		at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START);
+		at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
 
 	if (st->dma_st.dma_chan)
 		at91_adc_trigger_handler_dma(indio_dev);
@@ -1172,11 +1253,11 @@ static void at91_adc_setup_samp_freq(struct iio_dev *indio_dev, unsigned freq)
 	startup = at91_adc_startup_time(st->soc_info.startup_time,
 					freq / 1000);
 
-	mr = at91_adc_readl(st, AT91_SAMA5D2_MR);
+	mr = at91_adc_readl(st, MR);
 	mr &= ~(AT91_SAMA5D2_MR_STARTUP_MASK | AT91_SAMA5D2_MR_PRESCAL_MASK);
 	mr |= AT91_SAMA5D2_MR_STARTUP(startup);
 	mr |= AT91_SAMA5D2_MR_PRESCAL(prescal);
-	at91_adc_writel(st, AT91_SAMA5D2_MR, mr);
+	at91_adc_writel(st, MR, mr);
 
 	dev_dbg(&indio_dev->dev, "freq: %u, startup: %u, prescal: %u\n",
 		freq, startup, prescal);
@@ -1196,7 +1277,7 @@ static void at91_adc_touch_data_handler(struct iio_dev *indio_dev)
 	int i = 0;
 
 	for_each_set_bit(bit, indio_dev->active_scan_mask,
-			 AT91_SAMA5D2_MAX_CHAN_IDX + 1) {
+			 st->soc_info.platform->max_channels + 1) {
 		struct iio_chan_spec const *chan =
 					 at91_adc_chan_get(indio_dev, bit);
 
@@ -1222,12 +1303,11 @@ static void at91_adc_touch_data_handler(struct iio_dev *indio_dev)
 
 static void at91_adc_pen_detect_interrupt(struct at91_adc_state *st)
 {
-	at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_PEN);
-	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_NOPEN |
+	at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_PEN);
+	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_NOPEN |
 			AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
 			AT91_SAMA5D2_IER_PRDY);
-	at91_adc_writel(st, AT91_SAMA5D2_TRGR,
-			AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC |
+	at91_adc_writel(st, TRGR, AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC |
 			AT91_SAMA5D2_TRGR_TRGPER(st->touch_st.sample_period_val));
 	st->touch_st.touching = true;
 }
@@ -1236,16 +1316,15 @@ static void at91_adc_no_pen_detect_interrupt(struct iio_dev *indio_dev)
 {
 	struct at91_adc_state *st = iio_priv(indio_dev);
 
-	at91_adc_writel(st, AT91_SAMA5D2_TRGR,
-			AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER);
-	at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_NOPEN |
+	at91_adc_writel(st, TRGR, AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER);
+	at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_NOPEN |
 			AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
 			AT91_SAMA5D2_IER_PRDY);
 	st->touch_st.touching = false;
 
 	at91_adc_touch_data_handler(indio_dev);
 
-	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
+	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_PEN);
 }
 
 static void at91_adc_workq_handler(struct work_struct *workq)
@@ -1263,8 +1342,8 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
 {
 	struct iio_dev *indio = private;
 	struct at91_adc_state *st = iio_priv(indio);
-	u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
-	u32 imr = at91_adc_readl(st, AT91_SAMA5D2_IMR);
+	u32 status = at91_adc_readl(st, ISR);
+	u32 imr = at91_adc_readl(st, IMR);
 	u32 rdy_mask = AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
 			AT91_SAMA5D2_IER_PRDY;
 
@@ -1285,9 +1364,9 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
 		 * touching, but the measurements are not ready yet.
 		 * read and ignore.
 		 */
-		status = at91_adc_readl(st, AT91_SAMA5D2_XPOSR);
-		status = at91_adc_readl(st, AT91_SAMA5D2_YPOSR);
-		status = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
+		status = at91_adc_readl(st, XPOSR);
+		status = at91_adc_readl(st, YPOSR);
+		status = at91_adc_readl(st, PRESSR);
 	} else if (iio_buffer_enabled(indio) &&
 		   (status & AT91_SAMA5D2_IER_DRDY)) {
 		/* triggered buffer without DMA */
@@ -1299,7 +1378,7 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
 		WARN(true, "Unexpected irq occurred\n");
 	} else if (!iio_buffer_enabled(indio)) {
 		/* software requested conversion */
-		st->conversion_value = at91_adc_readl(st, st->chan->address);
+		st->conversion_value = at91_adc_read_chan(st, st->chan->address);
 		st->conversion_done = true;
 		wake_up_interruptible(&st->wq_data_available);
 	}
@@ -1360,10 +1439,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
 		cor = (BIT(chan->channel) | BIT(chan->channel2)) <<
 		      AT91_SAMA5D2_COR_DIFF_OFFSET;
 
-	at91_adc_writel(st, AT91_SAMA5D2_COR, cor);
-	at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel));
-	at91_adc_writel(st, AT91_SAMA5D2_IER, BIT(chan->channel));
-	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START);
+	at91_adc_writel(st, COR, cor);
+	at91_adc_writel(st, CHER, BIT(chan->channel));
+	at91_adc_writel(st, IER, BIT(chan->channel));
+	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
 
 	ret = wait_event_interruptible_timeout(st->wq_data_available,
 					       st->conversion_done,
@@ -1379,11 +1458,11 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
 		st->conversion_done = false;
 	}
 
-	at91_adc_writel(st, AT91_SAMA5D2_IDR, BIT(chan->channel));
-	at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
+	at91_adc_writel(st, IDR, BIT(chan->channel));
+	at91_adc_writel(st, CHDR, BIT(chan->channel));
 
 	/* Needed to ACK the DRDY interruption */
-	at91_adc_readl(st, AT91_SAMA5D2_LCDR);
+	at91_adc_readl(st, LCDR);
 
 	mutex_unlock(&st->lock);
 
@@ -1455,14 +1534,15 @@ static void at91_adc_dma_init(struct platform_device *pdev)
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct at91_adc_state *st = iio_priv(indio_dev);
 	struct dma_slave_config config = {0};
+	/* we have 2 bytes for each channel */
+	unsigned int sample_size = st->soc_info.platform->nr_channels * 2;
 	/*
 	 * We make the buffer double the size of the fifo,
 	 * such that DMA uses one half of the buffer (full fifo size)
 	 * and the software uses the other half to read/write.
 	 */
 	unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
-					  AT91_BUFFER_MAX_CONVERSION_BYTES * 2,
-					  PAGE_SIZE);
+					  sample_size * 2, PAGE_SIZE);
 
 	if (st->dma_st.dma_chan)
 		return;
@@ -1486,7 +1566,7 @@ static void at91_adc_dma_init(struct platform_device *pdev)
 	/* Configure DMA channel to read data register */
 	config.direction = DMA_DEV_TO_MEM;
 	config.src_addr = (phys_addr_t)(st->dma_st.phys_addr
-			  + AT91_SAMA5D2_LCDR);
+			  + st->soc_info.platform->layout->LCDR);
 	config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
 	config.src_maxburst = 1;
 	config.dst_maxburst = 1;
@@ -1515,9 +1595,10 @@ static void at91_adc_dma_disable(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct at91_adc_state *st = iio_priv(indio_dev);
+	/* we have 2 bytes for each channel */
+	unsigned int sample_size = st->soc_info.platform->nr_channels * 2;
 	unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
-					  AT91_BUFFER_MAX_CONVERSION_BYTES * 2,
-					  PAGE_SIZE);
+					  sample_size * 2, PAGE_SIZE);
 
 	/* if we are not using DMA, just return */
 	if (!st->dma_st.dma_chan)
@@ -1578,14 +1659,14 @@ static int at91_adc_update_scan_mode(struct iio_dev *indio_dev,
 	struct at91_adc_state *st = iio_priv(indio_dev);
 
 	if (bitmap_subset(scan_mask, &st->touch_st.channels_bitmask,
-			  AT91_SAMA5D2_MAX_CHAN_IDX + 1))
+			  st->soc_info.platform->max_channels + 1))
 		return 0;
 	/*
 	 * if the new bitmap is a combination of touchscreen and regular
 	 * channels, then we are not fine
 	 */
 	if (bitmap_intersects(&st->touch_st.channels_bitmask, scan_mask,
-			      AT91_SAMA5D2_MAX_CHAN_IDX + 1))
+			      st->soc_info.platform->max_channels + 1))
 		return -EINVAL;
 	return 0;
 }
@@ -1594,13 +1675,13 @@ static void at91_adc_hw_init(struct iio_dev *indio_dev)
 {
 	struct at91_adc_state *st = iio_priv(indio_dev);
 
-	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
-	at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff);
+	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
+	at91_adc_writel(st, IDR, 0xffffffff);
 	/*
 	 * Transfer field must be set to 2 according to the datasheet and
 	 * allows different analog settings for each channel.
 	 */
-	at91_adc_writel(st, AT91_SAMA5D2_MR,
+	at91_adc_writel(st, MR,
 			AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH);
 
 	at91_adc_setup_samp_freq(indio_dev, st->soc_info.min_sample_rate);
@@ -1716,21 +1797,23 @@ static int at91_adc_probe(struct platform_device *pdev)
 	if (!indio_dev)
 		return -ENOMEM;
 
+	st = iio_priv(indio_dev);
+	st->indio_dev = indio_dev;
+
+	st->soc_info.platform = of_device_get_match_data(&pdev->dev);
+
 	indio_dev->name = dev_name(&pdev->dev);
 	indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
 	indio_dev->info = &at91_adc_info;
-	indio_dev->channels = at91_adc_channels;
-	indio_dev->num_channels = ARRAY_SIZE(at91_adc_channels);
-
-	st = iio_priv(indio_dev);
-	st->indio_dev = indio_dev;
+	indio_dev->channels = *st->soc_info.platform->adc_channels;
+	indio_dev->num_channels = st->soc_info.platform->max_channels;
 
 	bitmap_set(&st->touch_st.channels_bitmask,
-		   AT91_SAMA5D2_TOUCH_X_CHAN_IDX, 1);
+		   st->soc_info.platform->touch_chan_x, 1);
 	bitmap_set(&st->touch_st.channels_bitmask,
-		   AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, 1);
+		   st->soc_info.platform->touch_chan_y, 1);
 	bitmap_set(&st->touch_st.channels_bitmask,
-		   AT91_SAMA5D2_TOUCH_P_CHAN_IDX, 1);
+		   st->soc_info.platform->touch_chan_p, 1);
 
 	st->oversampling_ratio = AT91_OSR_1SAMPLES;
 
@@ -1770,7 +1853,7 @@ static int at91_adc_probe(struct platform_device *pdev)
 	st->selected_trig = NULL;
 
 	/* find the right trigger, or no trigger at all */
-	for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT + 1; i++)
+	for (i = 0; i < st->soc_info.platform->hw_trig_cnt + 1; i++)
 		if (at91_adc_trigger_list[i].edge_type == edge_type) {
 			st->selected_trig = &at91_adc_trigger_list[i];
 			break;
@@ -1855,7 +1938,7 @@ static int at91_adc_probe(struct platform_device *pdev)
 			 st->selected_trig->name);
 
 	dev_info(&pdev->dev, "version: %x\n",
-		 readl_relaxed(st->base + AT91_SAMA5D2_VERSION));
+		 readl_relaxed(st->base + st->soc_info.platform->layout->VERSION));
 
 	return 0;
 
@@ -1898,7 +1981,7 @@ static __maybe_unused int at91_adc_suspend(struct device *dev)
 	 * and can be used by for other devices.
 	 * Otherwise, ADC will hog them and we can't go to suspend mode.
 	 */
-	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
+	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
 
 	clk_disable_unprepare(st->per_clk);
 	regulator_disable(st->vref);
@@ -1958,6 +2041,7 @@ static SIMPLE_DEV_PM_OPS(at91_adc_pm_ops, at91_adc_suspend, at91_adc_resume);
 static const struct of_device_id at91_adc_dt_match[] = {
 	{
 		.compatible = "atmel,sama5d2-adc",
+		.data = (const void *)&sama5d2_platform,
 	}, {
 		/* sentinel */
 	}
-- 
2.25.1


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

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

* [PATCH v2 05/10] iio: adc: at91-sama5d2-adc: add support for separate end of conversion registers
  2021-08-24 11:54 ` Eugen Hristev
@ 2021-08-24 11:54   ` Eugen Hristev
  -1 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev

Some platforms have separated the end-of-conversion information from the
usual ISR/IMR/IER/IDR registers, into EOC_ISR/EOC_IMR/EOC_IER/EOC_IDR.
To cope with both variants, helpers are being added, that will make
code more clear and more easy to read.

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 66 ++++++++++++++++++++++++++----
 1 file changed, 59 insertions(+), 7 deletions(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index 8ede18b8d789..23be7cec063e 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -117,6 +117,14 @@ struct at91_adc_reg_layout {
 	u16				IMR;
 /* Interrupt Status Register */
 	u16				ISR;
+/* End of Conversion Interrupt Enable Register */
+	u16				EOC_IER;
+/* End of Conversion Interrupt Disable Register */
+	u16				EOC_IDR;
+/* End of Conversion Interrupt Mask Register */
+	u16				EOC_IMR;
+/* End of Conversion Interrupt Status Register */
+	u16				EOC_ISR;
 /* Interrupt Status Register - Pen touching sense status */
 #define AT91_SAMA5D2_ISR_PENS   BIT(31)
 /* Last Channel Trigger Mode Register */
@@ -581,6 +589,44 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
 	return mask & GENMASK(st->soc_info.platform->nr_channels, 0);
 }
 
+static void at91_adc_irq_status(struct at91_adc_state *st, u32 *status,
+				u32 *eoc)
+{
+	*status = at91_adc_readl(st, ISR);
+	if (st->soc_info.platform->layout->EOC_ISR)
+		*eoc = at91_adc_readl(st, EOC_ISR);
+	else
+		*eoc = *status;
+}
+
+static void at91_adc_irq_mask(struct at91_adc_state *st, u32 *status, u32 *eoc)
+{
+	*status = at91_adc_readl(st, IMR);
+	if (st->soc_info.platform->layout->EOC_IMR)
+		*eoc = at91_adc_readl(st, EOC_IMR);
+	else
+		*eoc = *status;
+}
+
+static void at91_adc_eoc_dis(struct at91_adc_state *st, unsigned int channel)
+{
+	/*
+	 * On some products having the EOC bits in a separate register,
+	 * errata recommends not writing this register (EOC_IDR).
+	 * On products having the EOC bits in the IDR register, it's fine to write it.
+	 */
+	if (!st->soc_info.platform->layout->EOC_IDR)
+		at91_adc_writel(st, IDR, BIT(channel));
+}
+
+static void at91_adc_eoc_ena(struct at91_adc_state *st, unsigned int channel)
+{
+	if (!st->soc_info.platform->layout->EOC_IDR)
+		at91_adc_writel(st, IER, BIT(channel));
+	else
+		at91_adc_writel(st, EOC_IER, BIT(channel));
+}
+
 static void at91_adc_config_emr(struct at91_adc_state *st)
 {
 	/* configure the extended mode register */
@@ -1100,13 +1146,15 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
 	u8 bit;
 	u32 mask = at91_adc_active_scan_mask_to_reg(indio_dev);
 	unsigned int timeout = 50;
+	u32 status, imr, eoc = 0, eoc_imr;
 
 	/*
 	 * Check if the conversion is ready. If not, wait a little bit, and
 	 * in case of timeout exit with an error.
 	 */
-	while ((at91_adc_readl(st, ISR) & mask) != mask &&
-	       timeout) {
+	while (((eoc & mask) != mask) && timeout) {
+		at91_adc_irq_status(st, &status, &eoc);
+		at91_adc_irq_mask(st, &imr, &eoc_imr);
 		usleep_range(50, 100);
 		timeout--;
 	}
@@ -1342,12 +1390,14 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
 {
 	struct iio_dev *indio = private;
 	struct at91_adc_state *st = iio_priv(indio);
-	u32 status = at91_adc_readl(st, ISR);
-	u32 imr = at91_adc_readl(st, IMR);
+	u32 status, eoc, imr, eoc_imr;
 	u32 rdy_mask = AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
 			AT91_SAMA5D2_IER_PRDY;
 
-	if (!(status & imr))
+	at91_adc_irq_status(st, &status, &eoc);
+	at91_adc_irq_mask(st, &imr, &eoc_imr);
+
+	if (!(status & imr) && !(eoc & eoc_imr))
 		return IRQ_NONE;
 	if (status & AT91_SAMA5D2_IER_PEN) {
 		/* pen detected IRQ */
@@ -1441,7 +1491,7 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
 
 	at91_adc_writel(st, COR, cor);
 	at91_adc_writel(st, CHER, BIT(chan->channel));
-	at91_adc_writel(st, IER, BIT(chan->channel));
+	at91_adc_eoc_ena(st, chan->channel);
 	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
 
 	ret = wait_event_interruptible_timeout(st->wq_data_available,
@@ -1458,7 +1508,7 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
 		st->conversion_done = false;
 	}
 
-	at91_adc_writel(st, IDR, BIT(chan->channel));
+	at91_adc_eoc_dis(st, st->chan->channel);
 	at91_adc_writel(st, CHDR, BIT(chan->channel));
 
 	/* Needed to ACK the DRDY interruption */
@@ -1676,6 +1726,8 @@ static void at91_adc_hw_init(struct iio_dev *indio_dev)
 	struct at91_adc_state *st = iio_priv(indio_dev);
 
 	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
+	if (st->soc_info.platform->layout->EOC_IDR)
+		at91_adc_writel(st, EOC_IDR, 0xffffffff);
 	at91_adc_writel(st, IDR, 0xffffffff);
 	/*
 	 * Transfer field must be set to 2 according to the datasheet and
-- 
2.25.1


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

* [PATCH v2 05/10] iio: adc: at91-sama5d2-adc: add support for separate end of conversion registers
@ 2021-08-24 11:54   ` Eugen Hristev
  0 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev

Some platforms have separated the end-of-conversion information from the
usual ISR/IMR/IER/IDR registers, into EOC_ISR/EOC_IMR/EOC_IER/EOC_IDR.
To cope with both variants, helpers are being added, that will make
code more clear and more easy to read.

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 66 ++++++++++++++++++++++++++----
 1 file changed, 59 insertions(+), 7 deletions(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index 8ede18b8d789..23be7cec063e 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -117,6 +117,14 @@ struct at91_adc_reg_layout {
 	u16				IMR;
 /* Interrupt Status Register */
 	u16				ISR;
+/* End of Conversion Interrupt Enable Register */
+	u16				EOC_IER;
+/* End of Conversion Interrupt Disable Register */
+	u16				EOC_IDR;
+/* End of Conversion Interrupt Mask Register */
+	u16				EOC_IMR;
+/* End of Conversion Interrupt Status Register */
+	u16				EOC_ISR;
 /* Interrupt Status Register - Pen touching sense status */
 #define AT91_SAMA5D2_ISR_PENS   BIT(31)
 /* Last Channel Trigger Mode Register */
@@ -581,6 +589,44 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
 	return mask & GENMASK(st->soc_info.platform->nr_channels, 0);
 }
 
+static void at91_adc_irq_status(struct at91_adc_state *st, u32 *status,
+				u32 *eoc)
+{
+	*status = at91_adc_readl(st, ISR);
+	if (st->soc_info.platform->layout->EOC_ISR)
+		*eoc = at91_adc_readl(st, EOC_ISR);
+	else
+		*eoc = *status;
+}
+
+static void at91_adc_irq_mask(struct at91_adc_state *st, u32 *status, u32 *eoc)
+{
+	*status = at91_adc_readl(st, IMR);
+	if (st->soc_info.platform->layout->EOC_IMR)
+		*eoc = at91_adc_readl(st, EOC_IMR);
+	else
+		*eoc = *status;
+}
+
+static void at91_adc_eoc_dis(struct at91_adc_state *st, unsigned int channel)
+{
+	/*
+	 * On some products having the EOC bits in a separate register,
+	 * errata recommends not writing this register (EOC_IDR).
+	 * On products having the EOC bits in the IDR register, it's fine to write it.
+	 */
+	if (!st->soc_info.platform->layout->EOC_IDR)
+		at91_adc_writel(st, IDR, BIT(channel));
+}
+
+static void at91_adc_eoc_ena(struct at91_adc_state *st, unsigned int channel)
+{
+	if (!st->soc_info.platform->layout->EOC_IDR)
+		at91_adc_writel(st, IER, BIT(channel));
+	else
+		at91_adc_writel(st, EOC_IER, BIT(channel));
+}
+
 static void at91_adc_config_emr(struct at91_adc_state *st)
 {
 	/* configure the extended mode register */
@@ -1100,13 +1146,15 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
 	u8 bit;
 	u32 mask = at91_adc_active_scan_mask_to_reg(indio_dev);
 	unsigned int timeout = 50;
+	u32 status, imr, eoc = 0, eoc_imr;
 
 	/*
 	 * Check if the conversion is ready. If not, wait a little bit, and
 	 * in case of timeout exit with an error.
 	 */
-	while ((at91_adc_readl(st, ISR) & mask) != mask &&
-	       timeout) {
+	while (((eoc & mask) != mask) && timeout) {
+		at91_adc_irq_status(st, &status, &eoc);
+		at91_adc_irq_mask(st, &imr, &eoc_imr);
 		usleep_range(50, 100);
 		timeout--;
 	}
@@ -1342,12 +1390,14 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
 {
 	struct iio_dev *indio = private;
 	struct at91_adc_state *st = iio_priv(indio);
-	u32 status = at91_adc_readl(st, ISR);
-	u32 imr = at91_adc_readl(st, IMR);
+	u32 status, eoc, imr, eoc_imr;
 	u32 rdy_mask = AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
 			AT91_SAMA5D2_IER_PRDY;
 
-	if (!(status & imr))
+	at91_adc_irq_status(st, &status, &eoc);
+	at91_adc_irq_mask(st, &imr, &eoc_imr);
+
+	if (!(status & imr) && !(eoc & eoc_imr))
 		return IRQ_NONE;
 	if (status & AT91_SAMA5D2_IER_PEN) {
 		/* pen detected IRQ */
@@ -1441,7 +1491,7 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
 
 	at91_adc_writel(st, COR, cor);
 	at91_adc_writel(st, CHER, BIT(chan->channel));
-	at91_adc_writel(st, IER, BIT(chan->channel));
+	at91_adc_eoc_ena(st, chan->channel);
 	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
 
 	ret = wait_event_interruptible_timeout(st->wq_data_available,
@@ -1458,7 +1508,7 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
 		st->conversion_done = false;
 	}
 
-	at91_adc_writel(st, IDR, BIT(chan->channel));
+	at91_adc_eoc_dis(st, st->chan->channel);
 	at91_adc_writel(st, CHDR, BIT(chan->channel));
 
 	/* Needed to ACK the DRDY interruption */
@@ -1676,6 +1726,8 @@ static void at91_adc_hw_init(struct iio_dev *indio_dev)
 	struct at91_adc_state *st = iio_priv(indio_dev);
 
 	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
+	if (st->soc_info.platform->layout->EOC_IDR)
+		at91_adc_writel(st, EOC_IDR, 0xffffffff);
 	at91_adc_writel(st, IDR, 0xffffffff);
 	/*
 	 * Transfer field must be set to 2 according to the datasheet and
-- 
2.25.1


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

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

* [PATCH v2 06/10] iio: adc: at91-sama5d2_adc: add helper for COR register
  2021-08-24 11:54 ` Eugen Hristev
@ 2021-08-24 11:54   ` Eugen Hristev
  -1 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev

Add helper for the COR register. This helper allows to modify the COR
register, removes duplicate code and improves readability.
The COR offset is now part of the register layout. This will allow
different platform with a different offset to use the same helper.

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 40 +++++++++++++++---------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index 23be7cec063e..bb4e5e1e3ce4 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -151,8 +151,8 @@ struct at91_adc_reg_layout {
 	u16				CGR;
 /* Channel Offset Register */
 	u16				COR;
-#define AT91_SAMA5D2_COR_DIFF_OFFSET	16
-
+/* Channel Offset Register differential offset - constant, not a register */
+	u16				COR_diff_offset;
 /* Analog Control Register */
 	u16				ACR;
 /* Analog Control Register - Pen detect sensitivity mask */
@@ -246,6 +246,7 @@ static const struct at91_adc_reg_layout sama5d2_layout = {
 	.CWR =			0x44,
 	.CGR =			0x48,
 	.COR =			0x4c,
+	.COR_diff_offset =	16,
 	.ACR =			0x94,
 	.TSMR =			0xb0,
 	.XPOSR =		0xb4,
@@ -589,6 +590,21 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
 	return mask & GENMASK(st->soc_info.platform->nr_channels, 0);
 }
 
+static void at91_adc_cor(struct at91_adc_state *st,
+			 struct iio_chan_spec const *chan)
+{
+	u32 cor, cur_cor;
+
+	cor = (BIT(chan->channel) | BIT(chan->channel2));
+
+	cur_cor = at91_adc_readl(st, COR);
+	cor <<= st->soc_info.platform->layout->COR_diff_offset;
+	if (chan->differential)
+		at91_adc_writel(st, COR, cur_cor | cor);
+	else
+		at91_adc_writel(st, COR, cur_cor & ~cor);
+}
+
 static void at91_adc_irq_status(struct at91_adc_state *st, u32 *status,
 				u32 *eoc)
 {
@@ -1033,8 +1049,6 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
 			 indio_dev->num_channels) {
 		struct iio_chan_spec const *chan =
 					at91_adc_chan_get(indio_dev, bit);
-		u32 cor;
-
 		if (!chan)
 			continue;
 		/* these channel types cannot be handled by this trigger */
@@ -1042,16 +1056,7 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
 		    chan->type == IIO_PRESSURE)
 			continue;
 
-		cor = at91_adc_readl(st, COR);
-
-		if (chan->differential)
-			cor |= (BIT(chan->channel) | BIT(chan->channel2)) <<
-				AT91_SAMA5D2_COR_DIFF_OFFSET;
-		else
-			cor &= ~(BIT(chan->channel) <<
-			       AT91_SAMA5D2_COR_DIFF_OFFSET);
-
-		at91_adc_writel(st, COR, cor);
+		at91_adc_cor(st, chan);
 
 		at91_adc_writel(st, CHER, BIT(chan->channel));
 	}
@@ -1439,7 +1444,6 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
 				  struct iio_chan_spec const *chan, int *val)
 {
 	struct at91_adc_state *st = iio_priv(indio_dev);
-	u32 cor = 0;
 	u16 tmp_val;
 	int ret;
 
@@ -1485,11 +1489,7 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
 
 	st->chan = chan;
 
-	if (chan->differential)
-		cor = (BIT(chan->channel) | BIT(chan->channel2)) <<
-		      AT91_SAMA5D2_COR_DIFF_OFFSET;
-
-	at91_adc_writel(st, COR, cor);
+	at91_adc_cor(st, chan);
 	at91_adc_writel(st, CHER, BIT(chan->channel));
 	at91_adc_eoc_ena(st, chan->channel);
 	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
-- 
2.25.1


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

* [PATCH v2 06/10] iio: adc: at91-sama5d2_adc: add helper for COR register
@ 2021-08-24 11:54   ` Eugen Hristev
  0 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev

Add helper for the COR register. This helper allows to modify the COR
register, removes duplicate code and improves readability.
The COR offset is now part of the register layout. This will allow
different platform with a different offset to use the same helper.

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 40 +++++++++++++++---------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index 23be7cec063e..bb4e5e1e3ce4 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -151,8 +151,8 @@ struct at91_adc_reg_layout {
 	u16				CGR;
 /* Channel Offset Register */
 	u16				COR;
-#define AT91_SAMA5D2_COR_DIFF_OFFSET	16
-
+/* Channel Offset Register differential offset - constant, not a register */
+	u16				COR_diff_offset;
 /* Analog Control Register */
 	u16				ACR;
 /* Analog Control Register - Pen detect sensitivity mask */
@@ -246,6 +246,7 @@ static const struct at91_adc_reg_layout sama5d2_layout = {
 	.CWR =			0x44,
 	.CGR =			0x48,
 	.COR =			0x4c,
+	.COR_diff_offset =	16,
 	.ACR =			0x94,
 	.TSMR =			0xb0,
 	.XPOSR =		0xb4,
@@ -589,6 +590,21 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
 	return mask & GENMASK(st->soc_info.platform->nr_channels, 0);
 }
 
+static void at91_adc_cor(struct at91_adc_state *st,
+			 struct iio_chan_spec const *chan)
+{
+	u32 cor, cur_cor;
+
+	cor = (BIT(chan->channel) | BIT(chan->channel2));
+
+	cur_cor = at91_adc_readl(st, COR);
+	cor <<= st->soc_info.platform->layout->COR_diff_offset;
+	if (chan->differential)
+		at91_adc_writel(st, COR, cur_cor | cor);
+	else
+		at91_adc_writel(st, COR, cur_cor & ~cor);
+}
+
 static void at91_adc_irq_status(struct at91_adc_state *st, u32 *status,
 				u32 *eoc)
 {
@@ -1033,8 +1049,6 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
 			 indio_dev->num_channels) {
 		struct iio_chan_spec const *chan =
 					at91_adc_chan_get(indio_dev, bit);
-		u32 cor;
-
 		if (!chan)
 			continue;
 		/* these channel types cannot be handled by this trigger */
@@ -1042,16 +1056,7 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
 		    chan->type == IIO_PRESSURE)
 			continue;
 
-		cor = at91_adc_readl(st, COR);
-
-		if (chan->differential)
-			cor |= (BIT(chan->channel) | BIT(chan->channel2)) <<
-				AT91_SAMA5D2_COR_DIFF_OFFSET;
-		else
-			cor &= ~(BIT(chan->channel) <<
-			       AT91_SAMA5D2_COR_DIFF_OFFSET);
-
-		at91_adc_writel(st, COR, cor);
+		at91_adc_cor(st, chan);
 
 		at91_adc_writel(st, CHER, BIT(chan->channel));
 	}
@@ -1439,7 +1444,6 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
 				  struct iio_chan_spec const *chan, int *val)
 {
 	struct at91_adc_state *st = iio_priv(indio_dev);
-	u32 cor = 0;
 	u16 tmp_val;
 	int ret;
 
@@ -1485,11 +1489,7 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
 
 	st->chan = chan;
 
-	if (chan->differential)
-		cor = (BIT(chan->channel) | BIT(chan->channel2)) <<
-		      AT91_SAMA5D2_COR_DIFF_OFFSET;
-
-	at91_adc_writel(st, COR, cor);
+	at91_adc_cor(st, chan);
 	at91_adc_writel(st, CHER, BIT(chan->channel));
 	at91_adc_eoc_ena(st, chan->channel);
 	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
-- 
2.25.1


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

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

* [PATCH v2 07/10] iio: adc: at91-sama5d2_adc: add support for sama7g5 device
  2021-08-24 11:54 ` Eugen Hristev
@ 2021-08-24 11:54   ` Eugen Hristev
  -1 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev

Add support to sama7g5 ADC which is similar with sama5d2/sam9x60 device.
Differences are highlighted by compatible.
Main differences include 16 channels instead of 12 and missing
resistive touchscreen.

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 77 ++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index bb4e5e1e3ce4..f3f5230eac54 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -261,6 +261,38 @@ static const struct at91_adc_reg_layout sama5d2_layout = {
 	.VERSION =		0xfc,
 };
 
+static const struct at91_adc_reg_layout sama7g5_layout = {
+	.CR =			0x00,
+	.MR =			0x04,
+	.SEQR1 =		0x08,
+	.SEQR2 =		0x0c,
+	.CHER =			0x10,
+	.CHDR =			0x14,
+	.CHSR =			0x18,
+	.LCDR =			0x20,
+	.IER =			0x24,
+	.IDR =			0x28,
+	.IMR =			0x2c,
+	.ISR =			0x30,
+	.EOC_IER =		0x34,
+	.EOC_IDR =		0x38,
+	.EOC_IMR =		0x3c,
+	.EOC_ISR =		0x40,
+	.OVER =			0x4c,
+	.EMR =			0x50,
+	.CWR =			0x54,
+	.COR =			0x5c,
+	.COR_diff_offset =	0,
+	.ACR =			0xe0,
+	.TRGR =			0x100,
+	.COSR =			0x104,
+	.CVR =			0x108,
+	.CECR =			0x10c,
+	.WPMR =			0x118,
+	.WPSR =			0x11c,
+	.VERSION =		0x130,
+};
+
 #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
 #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
 
@@ -527,6 +559,34 @@ static const struct iio_chan_spec at91_sama5d2_adc_channels[] = {
 	AT91_SAMA5D2_CHAN_PRESSURE(21, "pressure"),
 };
 
+static const struct iio_chan_spec at91_sama7g5_adc_channels[] = {
+	AT91_SAMA5D2_CHAN_SINGLE(0, 0, 0x60),
+	AT91_SAMA5D2_CHAN_SINGLE(1, 1, 0x64),
+	AT91_SAMA5D2_CHAN_SINGLE(2, 2, 0x68),
+	AT91_SAMA5D2_CHAN_SINGLE(3, 3, 0x6c),
+	AT91_SAMA5D2_CHAN_SINGLE(4, 4, 0x70),
+	AT91_SAMA5D2_CHAN_SINGLE(5, 5, 0x74),
+	AT91_SAMA5D2_CHAN_SINGLE(6, 6, 0x78),
+	AT91_SAMA5D2_CHAN_SINGLE(7, 7, 0x7c),
+	AT91_SAMA5D2_CHAN_SINGLE(8, 8, 0x80),
+	AT91_SAMA5D2_CHAN_SINGLE(9, 9, 0x84),
+	AT91_SAMA5D2_CHAN_SINGLE(10, 10, 0x88),
+	AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x8c),
+	AT91_SAMA5D2_CHAN_SINGLE(12, 12, 0x90),
+	AT91_SAMA5D2_CHAN_SINGLE(13, 13, 0x94),
+	AT91_SAMA5D2_CHAN_SINGLE(14, 14, 0x98),
+	AT91_SAMA5D2_CHAN_SINGLE(15, 15, 0x9c),
+	AT91_SAMA5D2_CHAN_DIFF(16, 0, 1, 0x60),
+	AT91_SAMA5D2_CHAN_DIFF(17, 2, 3, 0x68),
+	AT91_SAMA5D2_CHAN_DIFF(18, 4, 5, 0x70),
+	AT91_SAMA5D2_CHAN_DIFF(19, 6, 7, 0x78),
+	AT91_SAMA5D2_CHAN_DIFF(20, 8, 9, 0x80),
+	AT91_SAMA5D2_CHAN_DIFF(21, 10, 11, 0x88),
+	AT91_SAMA5D2_CHAN_DIFF(22, 12, 13, 0x90),
+	AT91_SAMA5D2_CHAN_DIFF(23, 14, 15, 0x98),
+	IIO_CHAN_SOFT_TIMESTAMP(24),
+};
+
 static const struct at91_adc_platform sama5d2_platform = {
 	.layout = &sama5d2_layout,
 	.adc_channels = &at91_sama5d2_adc_channels,
@@ -547,6 +607,20 @@ static const struct at91_adc_platform sama5d2_platform = {
 	.hw_trig_cnt = AT91_SAMA5D2_HW_TRIG_CNT,
 };
 
+static const struct at91_adc_platform sama7g5_platform = {
+	.layout = &sama7g5_layout,
+	.adc_channels = &at91_sama7g5_adc_channels,
+#define AT91_SAMA7G5_SINGLE_CHAN_CNT	16
+#define AT91_SAMA7G5_DIFF_CHAN_CNT	8
+	.nr_channels = AT91_SAMA7G5_SINGLE_CHAN_CNT +
+		       AT91_SAMA7G5_DIFF_CHAN_CNT,
+#define AT91_SAMA7G5_MAX_CHAN_IDX	(AT91_SAMA7G5_SINGLE_CHAN_CNT + \
+					AT91_SAMA7G5_DIFF_CHAN_CNT)
+	.max_channels = ARRAY_SIZE(at91_sama7g5_adc_channels),
+#define AT91_SAMA7G5_HW_TRIG_CNT	3
+	.hw_trig_cnt = AT91_SAMA7G5_HW_TRIG_CNT,
+};
+
 static int at91_adc_chan_xlate(struct iio_dev *indio_dev, int chan)
 {
 	int i;
@@ -2094,6 +2168,9 @@ static const struct of_device_id at91_adc_dt_match[] = {
 	{
 		.compatible = "atmel,sama5d2-adc",
 		.data = (const void *)&sama5d2_platform,
+	}, {
+		.compatible = "microchip,sama7g5-adc",
+		.data = (const void *)&sama7g5_platform,
 	}, {
 		/* sentinel */
 	}
-- 
2.25.1


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

* [PATCH v2 07/10] iio: adc: at91-sama5d2_adc: add support for sama7g5 device
@ 2021-08-24 11:54   ` Eugen Hristev
  0 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev

Add support to sama7g5 ADC which is similar with sama5d2/sam9x60 device.
Differences are highlighted by compatible.
Main differences include 16 channels instead of 12 and missing
resistive touchscreen.

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 77 ++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index bb4e5e1e3ce4..f3f5230eac54 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -261,6 +261,38 @@ static const struct at91_adc_reg_layout sama5d2_layout = {
 	.VERSION =		0xfc,
 };
 
+static const struct at91_adc_reg_layout sama7g5_layout = {
+	.CR =			0x00,
+	.MR =			0x04,
+	.SEQR1 =		0x08,
+	.SEQR2 =		0x0c,
+	.CHER =			0x10,
+	.CHDR =			0x14,
+	.CHSR =			0x18,
+	.LCDR =			0x20,
+	.IER =			0x24,
+	.IDR =			0x28,
+	.IMR =			0x2c,
+	.ISR =			0x30,
+	.EOC_IER =		0x34,
+	.EOC_IDR =		0x38,
+	.EOC_IMR =		0x3c,
+	.EOC_ISR =		0x40,
+	.OVER =			0x4c,
+	.EMR =			0x50,
+	.CWR =			0x54,
+	.COR =			0x5c,
+	.COR_diff_offset =	0,
+	.ACR =			0xe0,
+	.TRGR =			0x100,
+	.COSR =			0x104,
+	.CVR =			0x108,
+	.CECR =			0x10c,
+	.WPMR =			0x118,
+	.WPSR =			0x11c,
+	.VERSION =		0x130,
+};
+
 #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
 #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
 
@@ -527,6 +559,34 @@ static const struct iio_chan_spec at91_sama5d2_adc_channels[] = {
 	AT91_SAMA5D2_CHAN_PRESSURE(21, "pressure"),
 };
 
+static const struct iio_chan_spec at91_sama7g5_adc_channels[] = {
+	AT91_SAMA5D2_CHAN_SINGLE(0, 0, 0x60),
+	AT91_SAMA5D2_CHAN_SINGLE(1, 1, 0x64),
+	AT91_SAMA5D2_CHAN_SINGLE(2, 2, 0x68),
+	AT91_SAMA5D2_CHAN_SINGLE(3, 3, 0x6c),
+	AT91_SAMA5D2_CHAN_SINGLE(4, 4, 0x70),
+	AT91_SAMA5D2_CHAN_SINGLE(5, 5, 0x74),
+	AT91_SAMA5D2_CHAN_SINGLE(6, 6, 0x78),
+	AT91_SAMA5D2_CHAN_SINGLE(7, 7, 0x7c),
+	AT91_SAMA5D2_CHAN_SINGLE(8, 8, 0x80),
+	AT91_SAMA5D2_CHAN_SINGLE(9, 9, 0x84),
+	AT91_SAMA5D2_CHAN_SINGLE(10, 10, 0x88),
+	AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x8c),
+	AT91_SAMA5D2_CHAN_SINGLE(12, 12, 0x90),
+	AT91_SAMA5D2_CHAN_SINGLE(13, 13, 0x94),
+	AT91_SAMA5D2_CHAN_SINGLE(14, 14, 0x98),
+	AT91_SAMA5D2_CHAN_SINGLE(15, 15, 0x9c),
+	AT91_SAMA5D2_CHAN_DIFF(16, 0, 1, 0x60),
+	AT91_SAMA5D2_CHAN_DIFF(17, 2, 3, 0x68),
+	AT91_SAMA5D2_CHAN_DIFF(18, 4, 5, 0x70),
+	AT91_SAMA5D2_CHAN_DIFF(19, 6, 7, 0x78),
+	AT91_SAMA5D2_CHAN_DIFF(20, 8, 9, 0x80),
+	AT91_SAMA5D2_CHAN_DIFF(21, 10, 11, 0x88),
+	AT91_SAMA5D2_CHAN_DIFF(22, 12, 13, 0x90),
+	AT91_SAMA5D2_CHAN_DIFF(23, 14, 15, 0x98),
+	IIO_CHAN_SOFT_TIMESTAMP(24),
+};
+
 static const struct at91_adc_platform sama5d2_platform = {
 	.layout = &sama5d2_layout,
 	.adc_channels = &at91_sama5d2_adc_channels,
@@ -547,6 +607,20 @@ static const struct at91_adc_platform sama5d2_platform = {
 	.hw_trig_cnt = AT91_SAMA5D2_HW_TRIG_CNT,
 };
 
+static const struct at91_adc_platform sama7g5_platform = {
+	.layout = &sama7g5_layout,
+	.adc_channels = &at91_sama7g5_adc_channels,
+#define AT91_SAMA7G5_SINGLE_CHAN_CNT	16
+#define AT91_SAMA7G5_DIFF_CHAN_CNT	8
+	.nr_channels = AT91_SAMA7G5_SINGLE_CHAN_CNT +
+		       AT91_SAMA7G5_DIFF_CHAN_CNT,
+#define AT91_SAMA7G5_MAX_CHAN_IDX	(AT91_SAMA7G5_SINGLE_CHAN_CNT + \
+					AT91_SAMA7G5_DIFF_CHAN_CNT)
+	.max_channels = ARRAY_SIZE(at91_sama7g5_adc_channels),
+#define AT91_SAMA7G5_HW_TRIG_CNT	3
+	.hw_trig_cnt = AT91_SAMA7G5_HW_TRIG_CNT,
+};
+
 static int at91_adc_chan_xlate(struct iio_dev *indio_dev, int chan)
 {
 	int i;
@@ -2094,6 +2168,9 @@ static const struct of_device_id at91_adc_dt_match[] = {
 	{
 		.compatible = "atmel,sama5d2-adc",
 		.data = (const void *)&sama5d2_platform,
+	}, {
+		.compatible = "microchip,sama7g5-adc",
+		.data = (const void *)&sama7g5_platform,
 	}, {
 		/* sentinel */
 	}
-- 
2.25.1


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

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

* [PATCH v2 08/10] iio: adc: at91-sama5d2_adc: update copyright and authors information
  2021-08-24 11:54 ` Eugen Hristev
@ 2021-08-24 11:54   ` Eugen Hristev
  -1 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev

Update copyright and authors information (corrected e-mail address), and
add myself as one of the authors.

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index f3f5230eac54..d2bce04a5caf 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -4,6 +4,8 @@
  *
  * Copyright (C) 2015 Atmel,
  *               2015 Ludovic Desroches <ludovic.desroches@atmel.com>
+ *		 2021 Microchip Technology, Inc. and its subsidiaries
+ *		 2021 Eugen Hristev <eugen.hristev@microchip.com>
  */
 
 #include <linux/bitops.h>
@@ -2188,6 +2190,7 @@ static struct platform_driver at91_adc_driver = {
 };
 module_platform_driver(at91_adc_driver)
 
-MODULE_AUTHOR("Ludovic Desroches <ludovic.desroches@atmel.com>");
+MODULE_AUTHOR("Ludovic Desroches <ludovic.desroches@microchip.com>");
+MODULE_AUTHOR("Eugen Hristev <eugen.hristev@microchip.com");
 MODULE_DESCRIPTION("Atmel AT91 SAMA5D2 ADC");
 MODULE_LICENSE("GPL v2");
-- 
2.25.1


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

* [PATCH v2 08/10] iio: adc: at91-sama5d2_adc: update copyright and authors information
@ 2021-08-24 11:54   ` Eugen Hristev
  0 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev

Update copyright and authors information (corrected e-mail address), and
add myself as one of the authors.

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index f3f5230eac54..d2bce04a5caf 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -4,6 +4,8 @@
  *
  * Copyright (C) 2015 Atmel,
  *               2015 Ludovic Desroches <ludovic.desroches@atmel.com>
+ *		 2021 Microchip Technology, Inc. and its subsidiaries
+ *		 2021 Eugen Hristev <eugen.hristev@microchip.com>
  */
 
 #include <linux/bitops.h>
@@ -2188,6 +2190,7 @@ static struct platform_driver at91_adc_driver = {
 };
 module_platform_driver(at91_adc_driver)
 
-MODULE_AUTHOR("Ludovic Desroches <ludovic.desroches@atmel.com>");
+MODULE_AUTHOR("Ludovic Desroches <ludovic.desroches@microchip.com>");
+MODULE_AUTHOR("Eugen Hristev <eugen.hristev@microchip.com");
 MODULE_DESCRIPTION("Atmel AT91 SAMA5D2 ADC");
 MODULE_LICENSE("GPL v2");
-- 
2.25.1


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

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

* [PATCH v2 09/10] ARM: dts: at91: sama7g5: add node for the ADC
  2021-08-24 11:54 ` Eugen Hristev
@ 2021-08-24 11:54   ` Eugen Hristev
  -1 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev

Add node for the ADC controller in sama7g5 SoC.

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 arch/arm/boot/dts/sama7g5.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi
index f9ad5365862f..de960519c72a 100644
--- a/arch/arm/boot/dts/sama7g5.dtsi
+++ b/arch/arm/boot/dts/sama7g5.dtsi
@@ -137,6 +137,22 @@ ps_wdt: watchdog@e001d180 {
 			clocks = <&clk32k 0>;
 		};
 
+		adc: adc@e1000000 {
+			compatible = "microchip,sama7g5-adc";
+			reg = <0xe1000000 0x200>;
+			interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&pmc PMC_TYPE_GCK 26>;
+			assigned-clocks = <&pmc PMC_TYPE_GCK 26>;
+			assigned-clock-rates = <100000000>;
+			clock-names = "adc_clk";
+			dmas = <&dma0 AT91_XDMAC_DT_PERID(0)>;
+			dma-names = "rx";
+			atmel,min-sample-rate-hz = <200000>;
+			atmel,max-sample-rate-hz = <20000000>;
+			atmel,startup-time-ms = <4>;
+			status = "disabled";
+		};
+
 		sdmmc0: mmc@e1204000 {
 			compatible = "microchip,sama7g5-sdhci", "microchip,sam9x60-sdhci";
 			reg = <0xe1204000 0x4000>;
-- 
2.25.1


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

* [PATCH v2 09/10] ARM: dts: at91: sama7g5: add node for the ADC
@ 2021-08-24 11:54   ` Eugen Hristev
  0 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev

Add node for the ADC controller in sama7g5 SoC.

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 arch/arm/boot/dts/sama7g5.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi
index f9ad5365862f..de960519c72a 100644
--- a/arch/arm/boot/dts/sama7g5.dtsi
+++ b/arch/arm/boot/dts/sama7g5.dtsi
@@ -137,6 +137,22 @@ ps_wdt: watchdog@e001d180 {
 			clocks = <&clk32k 0>;
 		};
 
+		adc: adc@e1000000 {
+			compatible = "microchip,sama7g5-adc";
+			reg = <0xe1000000 0x200>;
+			interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&pmc PMC_TYPE_GCK 26>;
+			assigned-clocks = <&pmc PMC_TYPE_GCK 26>;
+			assigned-clock-rates = <100000000>;
+			clock-names = "adc_clk";
+			dmas = <&dma0 AT91_XDMAC_DT_PERID(0)>;
+			dma-names = "rx";
+			atmel,min-sample-rate-hz = <200000>;
+			atmel,max-sample-rate-hz = <20000000>;
+			atmel,startup-time-ms = <4>;
+			status = "disabled";
+		};
+
 		sdmmc0: mmc@e1204000 {
 			compatible = "microchip,sama7g5-sdhci", "microchip,sam9x60-sdhci";
 			reg = <0xe1204000 0x4000>;
-- 
2.25.1


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

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

* [PATCH v2 10/10] ARM: dts: at91: sama7g5ek: enable ADC on the board
  2021-08-24 11:54 ` Eugen Hristev
@ 2021-08-24 11:54   ` Eugen Hristev
  -1 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev

The ADC controller on the board is fed by a 2.5V reference voltage.
By default the channels #14 and #15 are dedicated to analog input
(marked AN on the board), on the connectors mikrobus1 and mikrobus2.

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 arch/arm/boot/dts/at91-sama7g5ek.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/at91-sama7g5ek.dts b/arch/arm/boot/dts/at91-sama7g5ek.dts
index 4cbed98cc2f4..c46be165f2ba 100644
--- a/arch/arm/boot/dts/at91-sama7g5ek.dts
+++ b/arch/arm/boot/dts/at91-sama7g5ek.dts
@@ -122,6 +122,14 @@ spdif_out: spdif-out {
 	};
 };
 
+&adc {
+	vddana-supply = <&vddout25>;
+	vref-supply = <&vddout25>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_mikrobus1_an_default &pinctrl_mikrobus2_an_default>;
+	status = "okay";
+};
+
 &cpu0 {
 	cpu-supply = <&vddcpu>;
 };
-- 
2.25.1


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

* [PATCH v2 10/10] ARM: dts: at91: sama7g5ek: enable ADC on the board
@ 2021-08-24 11:54   ` Eugen Hristev
  0 siblings, 0 replies; 44+ messages in thread
From: Eugen Hristev @ 2021-08-24 11:54 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, ludovic.desroches,
	Eugen Hristev

The ADC controller on the board is fed by a 2.5V reference voltage.
By default the channels #14 and #15 are dedicated to analog input
(marked AN on the board), on the connectors mikrobus1 and mikrobus2.

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
 arch/arm/boot/dts/at91-sama7g5ek.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/at91-sama7g5ek.dts b/arch/arm/boot/dts/at91-sama7g5ek.dts
index 4cbed98cc2f4..c46be165f2ba 100644
--- a/arch/arm/boot/dts/at91-sama7g5ek.dts
+++ b/arch/arm/boot/dts/at91-sama7g5ek.dts
@@ -122,6 +122,14 @@ spdif_out: spdif-out {
 	};
 };
 
+&adc {
+	vddana-supply = <&vddout25>;
+	vref-supply = <&vddout25>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_mikrobus1_an_default &pinctrl_mikrobus2_an_default>;
+	status = "okay";
+};
+
 &cpu0 {
 	cpu-supply = <&vddcpu>;
 };
-- 
2.25.1


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

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

* Re: [PATCH v2 06/10] iio: adc: at91-sama5d2_adc: add helper for COR register
  2021-08-24 11:54   ` Eugen Hristev
@ 2021-08-30 12:18     ` Jonathan Cameron
  -1 siblings, 0 replies; 44+ messages in thread
From: Jonathan Cameron @ 2021-08-30 12:18 UTC (permalink / raw)
  To: Eugen Hristev
  Cc: linux-iio, devicetree, nicolas.ferre, linux-arm-kernel,
	linux-kernel, robh+dt, ludovic.desroches

On Tue, 24 Aug 2021 14:54:37 +0300
Eugen Hristev <eugen.hristev@microchip.com> wrote:

> Add helper for the COR register. This helper allows to modify the COR
> register, removes duplicate code and improves readability.
> The COR offset is now part of the register layout. This will allow
> different platform with a different offset to use the same helper.
> 
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
Nitpick inline.  If this is all I find in the series I'll tidy it up whilst
applying.

J

> ---
>  drivers/iio/adc/at91-sama5d2_adc.c | 40 +++++++++++++++---------------
>  1 file changed, 20 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> index 23be7cec063e..bb4e5e1e3ce4 100644
> --- a/drivers/iio/adc/at91-sama5d2_adc.c
> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> @@ -151,8 +151,8 @@ struct at91_adc_reg_layout {
>  	u16				CGR;
>  /* Channel Offset Register */
>  	u16				COR;
> -#define AT91_SAMA5D2_COR_DIFF_OFFSET	16
> -
> +/* Channel Offset Register differential offset - constant, not a register */
> +	u16				COR_diff_offset;
>  /* Analog Control Register */
>  	u16				ACR;
>  /* Analog Control Register - Pen detect sensitivity mask */
> @@ -246,6 +246,7 @@ static const struct at91_adc_reg_layout sama5d2_layout = {
>  	.CWR =			0x44,
>  	.CGR =			0x48,
>  	.COR =			0x4c,
> +	.COR_diff_offset =	16,
>  	.ACR =			0x94,
>  	.TSMR =			0xb0,
>  	.XPOSR =		0xb4,
> @@ -589,6 +590,21 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
>  	return mask & GENMASK(st->soc_info.platform->nr_channels, 0);
>  }
>  
> +static void at91_adc_cor(struct at91_adc_state *st,
> +			 struct iio_chan_spec const *chan)
> +{
> +	u32 cor, cur_cor;
> +
> +	cor = (BIT(chan->channel) | BIT(chan->channel2));

Excessive brackets.


> +
> +	cur_cor = at91_adc_readl(st, COR);
> +	cor <<= st->soc_info.platform->layout->COR_diff_offset;
> +	if (chan->differential)
> +		at91_adc_writel(st, COR, cur_cor | cor);
> +	else
> +		at91_adc_writel(st, COR, cur_cor & ~cor);
> +}
> +
>  static void at91_adc_irq_status(struct at91_adc_state *st, u32 *status,
>  				u32 *eoc)
>  {
> @@ -1033,8 +1049,6 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
>  			 indio_dev->num_channels) {
>  		struct iio_chan_spec const *chan =
>  					at91_adc_chan_get(indio_dev, bit);
> -		u32 cor;
> -
>  		if (!chan)
>  			continue;
>  		/* these channel types cannot be handled by this trigger */
> @@ -1042,16 +1056,7 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
>  		    chan->type == IIO_PRESSURE)
>  			continue;
>  
> -		cor = at91_adc_readl(st, COR);
> -
> -		if (chan->differential)
> -			cor |= (BIT(chan->channel) | BIT(chan->channel2)) <<
> -				AT91_SAMA5D2_COR_DIFF_OFFSET;
> -		else
> -			cor &= ~(BIT(chan->channel) <<
> -			       AT91_SAMA5D2_COR_DIFF_OFFSET);
> -
> -		at91_adc_writel(st, COR, cor);
> +		at91_adc_cor(st, chan);
>  
>  		at91_adc_writel(st, CHER, BIT(chan->channel));
>  	}
> @@ -1439,7 +1444,6 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
>  				  struct iio_chan_spec const *chan, int *val)
>  {
>  	struct at91_adc_state *st = iio_priv(indio_dev);
> -	u32 cor = 0;
>  	u16 tmp_val;
>  	int ret;
>  
> @@ -1485,11 +1489,7 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
>  
>  	st->chan = chan;
>  
> -	if (chan->differential)
> -		cor = (BIT(chan->channel) | BIT(chan->channel2)) <<
> -		      AT91_SAMA5D2_COR_DIFF_OFFSET;
> -
> -	at91_adc_writel(st, COR, cor);
> +	at91_adc_cor(st, chan);
>  	at91_adc_writel(st, CHER, BIT(chan->channel));
>  	at91_adc_eoc_ena(st, chan->channel);
>  	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);


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

* Re: [PATCH v2 06/10] iio: adc: at91-sama5d2_adc: add helper for COR register
@ 2021-08-30 12:18     ` Jonathan Cameron
  0 siblings, 0 replies; 44+ messages in thread
From: Jonathan Cameron @ 2021-08-30 12:18 UTC (permalink / raw)
  To: Eugen Hristev
  Cc: devicetree, linux-iio, linux-kernel, ludovic.desroches, robh+dt,
	linux-arm-kernel

On Tue, 24 Aug 2021 14:54:37 +0300
Eugen Hristev <eugen.hristev@microchip.com> wrote:

> Add helper for the COR register. This helper allows to modify the COR
> register, removes duplicate code and improves readability.
> The COR offset is now part of the register layout. This will allow
> different platform with a different offset to use the same helper.
> 
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
Nitpick inline.  If this is all I find in the series I'll tidy it up whilst
applying.

J

> ---
>  drivers/iio/adc/at91-sama5d2_adc.c | 40 +++++++++++++++---------------
>  1 file changed, 20 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> index 23be7cec063e..bb4e5e1e3ce4 100644
> --- a/drivers/iio/adc/at91-sama5d2_adc.c
> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> @@ -151,8 +151,8 @@ struct at91_adc_reg_layout {
>  	u16				CGR;
>  /* Channel Offset Register */
>  	u16				COR;
> -#define AT91_SAMA5D2_COR_DIFF_OFFSET	16
> -
> +/* Channel Offset Register differential offset - constant, not a register */
> +	u16				COR_diff_offset;
>  /* Analog Control Register */
>  	u16				ACR;
>  /* Analog Control Register - Pen detect sensitivity mask */
> @@ -246,6 +246,7 @@ static const struct at91_adc_reg_layout sama5d2_layout = {
>  	.CWR =			0x44,
>  	.CGR =			0x48,
>  	.COR =			0x4c,
> +	.COR_diff_offset =	16,
>  	.ACR =			0x94,
>  	.TSMR =			0xb0,
>  	.XPOSR =		0xb4,
> @@ -589,6 +590,21 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
>  	return mask & GENMASK(st->soc_info.platform->nr_channels, 0);
>  }
>  
> +static void at91_adc_cor(struct at91_adc_state *st,
> +			 struct iio_chan_spec const *chan)
> +{
> +	u32 cor, cur_cor;
> +
> +	cor = (BIT(chan->channel) | BIT(chan->channel2));

Excessive brackets.


> +
> +	cur_cor = at91_adc_readl(st, COR);
> +	cor <<= st->soc_info.platform->layout->COR_diff_offset;
> +	if (chan->differential)
> +		at91_adc_writel(st, COR, cur_cor | cor);
> +	else
> +		at91_adc_writel(st, COR, cur_cor & ~cor);
> +}
> +
>  static void at91_adc_irq_status(struct at91_adc_state *st, u32 *status,
>  				u32 *eoc)
>  {
> @@ -1033,8 +1049,6 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
>  			 indio_dev->num_channels) {
>  		struct iio_chan_spec const *chan =
>  					at91_adc_chan_get(indio_dev, bit);
> -		u32 cor;
> -
>  		if (!chan)
>  			continue;
>  		/* these channel types cannot be handled by this trigger */
> @@ -1042,16 +1056,7 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
>  		    chan->type == IIO_PRESSURE)
>  			continue;
>  
> -		cor = at91_adc_readl(st, COR);
> -
> -		if (chan->differential)
> -			cor |= (BIT(chan->channel) | BIT(chan->channel2)) <<
> -				AT91_SAMA5D2_COR_DIFF_OFFSET;
> -		else
> -			cor &= ~(BIT(chan->channel) <<
> -			       AT91_SAMA5D2_COR_DIFF_OFFSET);
> -
> -		at91_adc_writel(st, COR, cor);
> +		at91_adc_cor(st, chan);
>  
>  		at91_adc_writel(st, CHER, BIT(chan->channel));
>  	}
> @@ -1439,7 +1444,6 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
>  				  struct iio_chan_spec const *chan, int *val)
>  {
>  	struct at91_adc_state *st = iio_priv(indio_dev);
> -	u32 cor = 0;
>  	u16 tmp_val;
>  	int ret;
>  
> @@ -1485,11 +1489,7 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
>  
>  	st->chan = chan;
>  
> -	if (chan->differential)
> -		cor = (BIT(chan->channel) | BIT(chan->channel2)) <<
> -		      AT91_SAMA5D2_COR_DIFF_OFFSET;
> -
> -	at91_adc_writel(st, COR, cor);
> +	at91_adc_cor(st, chan);
>  	at91_adc_writel(st, CHER, BIT(chan->channel));
>  	at91_adc_eoc_ena(st, chan->channel);
>  	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);


_______________________________________________
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] 44+ messages in thread

* Re: [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform specific data structures
  2021-08-24 11:54   ` Eugen Hristev
@ 2021-08-30 12:21     ` Jonathan Cameron
  -1 siblings, 0 replies; 44+ messages in thread
From: Jonathan Cameron @ 2021-08-30 12:21 UTC (permalink / raw)
  To: Eugen Hristev
  Cc: linux-iio, devicetree, nicolas.ferre, linux-arm-kernel,
	linux-kernel, robh+dt, ludovic.desroches

On Tue, 24 Aug 2021 14:54:35 +0300
Eugen Hristev <eugen.hristev@microchip.com> wrote:

> Convert the driver to platform specific structures. This means:
> - create a register layout struct that will hold offsets for registers
> - create a platform struct that will hold platform information (number of
> channels, indexes for different channels and pointer to layout struct)
> - convert specific macros that are platform dependent into platform variables
> 
> This step is in fact a no-op, but allows the driver to be more flexible
> and for future enhancement including adding new platforms that are partly
> compatible with the current driver and differ slightly in register layout
> or capabilities for example.
> 
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> ---
>  drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
>  1 file changed, 247 insertions(+), 163 deletions(-)
> 
> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> index 9d71dcffcf93..8ede18b8d789 100644
> --- a/drivers/iio/adc/at91-sama5d2_adc.c
> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> @@ -27,8 +27,9 @@
>  #include <linux/pinctrl/consumer.h>
>  #include <linux/regulator/consumer.h>
>  
> +struct at91_adc_reg_layout {
>  /* Control Register */
> -#define AT91_SAMA5D2_CR		0x00
> +	u16				CR;
>  /* Software Reset */
>  #define	AT91_SAMA5D2_CR_SWRST		BIT(0)
>  /* Start Conversion */
> @@ -39,7 +40,7 @@
>  #define	AT91_SAMA5D2_CR_CMPRST		BIT(4)
>  
>  /* Mode Register */
> -#define AT91_SAMA5D2_MR		0x04
> +	u16				MR;
>  /* Trigger Selection */
>  #define	AT91_SAMA5D2_MR_TRGSEL(v)	((v) << 1)
>  /* ADTRG */
> @@ -82,19 +83,19 @@
>  #define	AT91_SAMA5D2_MR_USEQ		BIT(31)
>  
>  /* Channel Sequence Register 1 */
> -#define AT91_SAMA5D2_SEQR1	0x08
> +	u16				SEQR1;
>  /* Channel Sequence Register 2 */
> -#define AT91_SAMA5D2_SEQR2	0x0c
> +	u16				SEQR2;
>  /* Channel Enable Register */
> -#define AT91_SAMA5D2_CHER	0x10
> +	u16				CHER;
>  /* Channel Disable Register */
> -#define AT91_SAMA5D2_CHDR	0x14
> +	u16				CHDR;
>  /* Channel Status Register */
> -#define AT91_SAMA5D2_CHSR	0x18
> +	u16				CHSR;
>  /* Last Converted Data Register */
> -#define AT91_SAMA5D2_LCDR	0x20
> +	u16				LCDR;
>  /* Interrupt Enable Register */
> -#define AT91_SAMA5D2_IER	0x24
> +	u16				IER;
>  /* Interrupt Enable Register - TS X measurement ready */
>  #define AT91_SAMA5D2_IER_XRDY   BIT(20)
>  /* Interrupt Enable Register - TS Y measurement ready */
> @@ -109,22 +110,23 @@
>  #define AT91_SAMA5D2_IER_PEN    BIT(29)
>  /* Interrupt Enable Register - No pen detect */
>  #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
> +
>  /* Interrupt Disable Register */
> -#define AT91_SAMA5D2_IDR	0x28
> +	u16				IDR;
>  /* Interrupt Mask Register */
> -#define AT91_SAMA5D2_IMR	0x2c
> +	u16				IMR;
>  /* Interrupt Status Register */
> -#define AT91_SAMA5D2_ISR	0x30
> +	u16				ISR;
>  /* Interrupt Status Register - Pen touching sense status */
>  #define AT91_SAMA5D2_ISR_PENS   BIT(31)
>  /* Last Channel Trigger Mode Register */
> -#define AT91_SAMA5D2_LCTMR	0x34
> +	u16				LCTMR;
>  /* Last Channel Compare Window Register */
> -#define AT91_SAMA5D2_LCCWR	0x38
> +	u16				LCCWR;
>  /* Overrun Status Register */
> -#define AT91_SAMA5D2_OVER	0x3c
> +	u16				OVER;
>  /* Extended Mode Register */
> -#define AT91_SAMA5D2_EMR	0x40
> +	u16				EMR;
>  /* Extended Mode Register - Oversampling rate */
>  #define AT91_SAMA5D2_EMR_OSR(V)			((V) << 16)
>  #define AT91_SAMA5D2_EMR_OSR_MASK		GENMASK(17, 16)
> @@ -134,22 +136,22 @@
>  
>  /* Extended Mode Register - Averaging on single trigger event */
>  #define AT91_SAMA5D2_EMR_ASTE(V)		((V) << 20)
> +
>  /* Compare Window Register */
> -#define AT91_SAMA5D2_CWR	0x44
> +	u16				CWR;
>  /* Channel Gain Register */
> -#define AT91_SAMA5D2_CGR	0x48
> -
> +	u16				CGR;
>  /* Channel Offset Register */
> -#define AT91_SAMA5D2_COR	0x4c
> +	u16				COR;
>  #define AT91_SAMA5D2_COR_DIFF_OFFSET	16
>  
>  /* Analog Control Register */
> -#define AT91_SAMA5D2_ACR	0x94
> +	u16				ACR;
>  /* Analog Control Register - Pen detect sensitivity mask */
>  #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
>  
>  /* Touchscreen Mode Register */
> -#define AT91_SAMA5D2_TSMR	0xb0
> +	u16				TSMR;
>  /* Touchscreen Mode Register - No touch mode */
>  #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
>  /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
> @@ -178,13 +180,13 @@
>  #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
>  
>  /* Touchscreen X Position Register */
> -#define AT91_SAMA5D2_XPOSR	0xb4
> +	u16				XPOSR;
>  /* Touchscreen Y Position Register */
> -#define AT91_SAMA5D2_YPOSR	0xb8
> +	u16				YPOSR;
>  /* Touchscreen Pressure Register */
> -#define AT91_SAMA5D2_PRESSR	0xbc
> +	u16				PRESSR;
>  /* Trigger Register */
> -#define AT91_SAMA5D2_TRGR	0xc0
> +	u16				TRGR;
>  /* Mask for TRGMOD field of TRGR register */
>  #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
>  /* No trigger, only software trigger can start conversions */
> @@ -203,30 +205,52 @@
>  #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
>  
>  /* Correction Select Register */
> -#define AT91_SAMA5D2_COSR	0xd0
> +	u16				COSR;
>  /* Correction Value Register */
> -#define AT91_SAMA5D2_CVR	0xd4
> +	u16				CVR;
>  /* Channel Error Correction Register */
> -#define AT91_SAMA5D2_CECR	0xd8
> +	u16				CECR;
>  /* Write Protection Mode Register */
> -#define AT91_SAMA5D2_WPMR	0xe4
> +	u16				WPMR;
>  /* Write Protection Status Register */
> -#define AT91_SAMA5D2_WPSR	0xe8
> +	u16				WPSR;
>  /* Version Register */
> -#define AT91_SAMA5D2_VERSION	0xfc
> -
> -#define AT91_SAMA5D2_HW_TRIG_CNT 3
> -#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
> -#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
> -
> -#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> -					 AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
> +	u16				VERSION;
> +};
>  
> -#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> -					 AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
> -#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
> -#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
> -#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
> +static const struct at91_adc_reg_layout sama5d2_layout = {
> +	.CR =			0x00,
> +	.MR =			0x04,
> +	.SEQR1 =		0x08,
> +	.SEQR2 =		0x0c,
> +	.CHER =			0x10,
> +	.CHDR =			0x14,
> +	.CHSR =			0x18,
> +	.LCDR =			0x20,
> +	.IER =			0x24,
> +	.IDR =			0x28,
> +	.IMR =			0x2c,
> +	.ISR =			0x30,
> +	.LCTMR =		0x34,
> +	.LCCWR =		0x38,
> +	.OVER =			0x3c,
> +	.EMR =			0x40,
> +	.CWR =			0x44,
> +	.CGR =			0x48,
> +	.COR =			0x4c,
> +	.ACR =			0x94,
> +	.TSMR =			0xb0,
> +	.XPOSR =		0xb4,
> +	.YPOSR =		0xb8,
> +	.PRESSR =		0xbc,
> +	.TRGR =			0xc0,
> +	.COSR =			0xd0,
> +	.CVR =			0xd4,
> +	.CECR =			0xd8,
> +	.WPMR =			0xe4,
> +	.WPSR =			0xe8,
> +	.VERSION =		0xfc,
> +};
>  
>  #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
>  #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
> @@ -235,18 +259,6 @@
>  
>  #define AT91_SAMA5D2_MAX_POS_BITS			12
>  
> -/*
> - * Maximum number of bytes to hold conversion from all channels
> - * without the timestamp.
> - */
> -#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> -					 AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
> -
> -/* This total must also include the timestamp */
> -#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
> -
> -#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
> -
>  #define AT91_HWFIFO_MAX_SIZE_STR	"128"
>  #define AT91_HWFIFO_MAX_SIZE		128
>  
> @@ -255,12 +267,12 @@
>  #define AT91_OSR_4SAMPLES		4
>  #define AT91_OSR_16SAMPLES		16
>  
> -#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)				\
> +#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)			\
>  	{								\
>  		.type = IIO_VOLTAGE,					\
>  		.channel = num,						\
>  		.address = addr,					\
> -		.scan_index = num,					\
> +		.scan_index = index,					\
>  		.scan_type = {						\
>  			.sign = 'u',					\
>  			.realbits = 14,					\
> @@ -274,14 +286,14 @@
>  		.indexed = 1,						\
>  	}
>  
> -#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)				\
> +#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)			\
>  	{								\
>  		.type = IIO_VOLTAGE,					\
>  		.differential = 1,					\
>  		.channel = num,						\
>  		.channel2 = num2,					\
>  		.address = addr,					\
> -		.scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,	\
> +		.scan_index = index,					\
>  		.scan_type = {						\
>  			.sign = 's',					\
>  			.realbits = 14,					\
> @@ -328,13 +340,48 @@
>  		.datasheet_name = name,					\
>  	}
>  
> -#define at91_adc_readl(st, reg)		readl_relaxed(st->base + reg)
> -#define at91_adc_writel(st, reg, val)	writel_relaxed(val, st->base + reg)
> +#define at91_adc_readl(st, reg)						\
> +	readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
I was a bit in two minds about whether this should be in capitals to make it clear
macro magic is going on, or whether lowercase is fine.  In the end I couldn't make
up my mind so will accept it like this! :)


Jonathan

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

* Re: [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform specific data structures
@ 2021-08-30 12:21     ` Jonathan Cameron
  0 siblings, 0 replies; 44+ messages in thread
From: Jonathan Cameron @ 2021-08-30 12:21 UTC (permalink / raw)
  To: Eugen Hristev
  Cc: devicetree, linux-iio, linux-kernel, ludovic.desroches, robh+dt,
	linux-arm-kernel

On Tue, 24 Aug 2021 14:54:35 +0300
Eugen Hristev <eugen.hristev@microchip.com> wrote:

> Convert the driver to platform specific structures. This means:
> - create a register layout struct that will hold offsets for registers
> - create a platform struct that will hold platform information (number of
> channels, indexes for different channels and pointer to layout struct)
> - convert specific macros that are platform dependent into platform variables
> 
> This step is in fact a no-op, but allows the driver to be more flexible
> and for future enhancement including adding new platforms that are partly
> compatible with the current driver and differ slightly in register layout
> or capabilities for example.
> 
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> ---
>  drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
>  1 file changed, 247 insertions(+), 163 deletions(-)
> 
> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> index 9d71dcffcf93..8ede18b8d789 100644
> --- a/drivers/iio/adc/at91-sama5d2_adc.c
> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> @@ -27,8 +27,9 @@
>  #include <linux/pinctrl/consumer.h>
>  #include <linux/regulator/consumer.h>
>  
> +struct at91_adc_reg_layout {
>  /* Control Register */
> -#define AT91_SAMA5D2_CR		0x00
> +	u16				CR;
>  /* Software Reset */
>  #define	AT91_SAMA5D2_CR_SWRST		BIT(0)
>  /* Start Conversion */
> @@ -39,7 +40,7 @@
>  #define	AT91_SAMA5D2_CR_CMPRST		BIT(4)
>  
>  /* Mode Register */
> -#define AT91_SAMA5D2_MR		0x04
> +	u16				MR;
>  /* Trigger Selection */
>  #define	AT91_SAMA5D2_MR_TRGSEL(v)	((v) << 1)
>  /* ADTRG */
> @@ -82,19 +83,19 @@
>  #define	AT91_SAMA5D2_MR_USEQ		BIT(31)
>  
>  /* Channel Sequence Register 1 */
> -#define AT91_SAMA5D2_SEQR1	0x08
> +	u16				SEQR1;
>  /* Channel Sequence Register 2 */
> -#define AT91_SAMA5D2_SEQR2	0x0c
> +	u16				SEQR2;
>  /* Channel Enable Register */
> -#define AT91_SAMA5D2_CHER	0x10
> +	u16				CHER;
>  /* Channel Disable Register */
> -#define AT91_SAMA5D2_CHDR	0x14
> +	u16				CHDR;
>  /* Channel Status Register */
> -#define AT91_SAMA5D2_CHSR	0x18
> +	u16				CHSR;
>  /* Last Converted Data Register */
> -#define AT91_SAMA5D2_LCDR	0x20
> +	u16				LCDR;
>  /* Interrupt Enable Register */
> -#define AT91_SAMA5D2_IER	0x24
> +	u16				IER;
>  /* Interrupt Enable Register - TS X measurement ready */
>  #define AT91_SAMA5D2_IER_XRDY   BIT(20)
>  /* Interrupt Enable Register - TS Y measurement ready */
> @@ -109,22 +110,23 @@
>  #define AT91_SAMA5D2_IER_PEN    BIT(29)
>  /* Interrupt Enable Register - No pen detect */
>  #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
> +
>  /* Interrupt Disable Register */
> -#define AT91_SAMA5D2_IDR	0x28
> +	u16				IDR;
>  /* Interrupt Mask Register */
> -#define AT91_SAMA5D2_IMR	0x2c
> +	u16				IMR;
>  /* Interrupt Status Register */
> -#define AT91_SAMA5D2_ISR	0x30
> +	u16				ISR;
>  /* Interrupt Status Register - Pen touching sense status */
>  #define AT91_SAMA5D2_ISR_PENS   BIT(31)
>  /* Last Channel Trigger Mode Register */
> -#define AT91_SAMA5D2_LCTMR	0x34
> +	u16				LCTMR;
>  /* Last Channel Compare Window Register */
> -#define AT91_SAMA5D2_LCCWR	0x38
> +	u16				LCCWR;
>  /* Overrun Status Register */
> -#define AT91_SAMA5D2_OVER	0x3c
> +	u16				OVER;
>  /* Extended Mode Register */
> -#define AT91_SAMA5D2_EMR	0x40
> +	u16				EMR;
>  /* Extended Mode Register - Oversampling rate */
>  #define AT91_SAMA5D2_EMR_OSR(V)			((V) << 16)
>  #define AT91_SAMA5D2_EMR_OSR_MASK		GENMASK(17, 16)
> @@ -134,22 +136,22 @@
>  
>  /* Extended Mode Register - Averaging on single trigger event */
>  #define AT91_SAMA5D2_EMR_ASTE(V)		((V) << 20)
> +
>  /* Compare Window Register */
> -#define AT91_SAMA5D2_CWR	0x44
> +	u16				CWR;
>  /* Channel Gain Register */
> -#define AT91_SAMA5D2_CGR	0x48
> -
> +	u16				CGR;
>  /* Channel Offset Register */
> -#define AT91_SAMA5D2_COR	0x4c
> +	u16				COR;
>  #define AT91_SAMA5D2_COR_DIFF_OFFSET	16
>  
>  /* Analog Control Register */
> -#define AT91_SAMA5D2_ACR	0x94
> +	u16				ACR;
>  /* Analog Control Register - Pen detect sensitivity mask */
>  #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
>  
>  /* Touchscreen Mode Register */
> -#define AT91_SAMA5D2_TSMR	0xb0
> +	u16				TSMR;
>  /* Touchscreen Mode Register - No touch mode */
>  #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
>  /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
> @@ -178,13 +180,13 @@
>  #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
>  
>  /* Touchscreen X Position Register */
> -#define AT91_SAMA5D2_XPOSR	0xb4
> +	u16				XPOSR;
>  /* Touchscreen Y Position Register */
> -#define AT91_SAMA5D2_YPOSR	0xb8
> +	u16				YPOSR;
>  /* Touchscreen Pressure Register */
> -#define AT91_SAMA5D2_PRESSR	0xbc
> +	u16				PRESSR;
>  /* Trigger Register */
> -#define AT91_SAMA5D2_TRGR	0xc0
> +	u16				TRGR;
>  /* Mask for TRGMOD field of TRGR register */
>  #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
>  /* No trigger, only software trigger can start conversions */
> @@ -203,30 +205,52 @@
>  #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
>  
>  /* Correction Select Register */
> -#define AT91_SAMA5D2_COSR	0xd0
> +	u16				COSR;
>  /* Correction Value Register */
> -#define AT91_SAMA5D2_CVR	0xd4
> +	u16				CVR;
>  /* Channel Error Correction Register */
> -#define AT91_SAMA5D2_CECR	0xd8
> +	u16				CECR;
>  /* Write Protection Mode Register */
> -#define AT91_SAMA5D2_WPMR	0xe4
> +	u16				WPMR;
>  /* Write Protection Status Register */
> -#define AT91_SAMA5D2_WPSR	0xe8
> +	u16				WPSR;
>  /* Version Register */
> -#define AT91_SAMA5D2_VERSION	0xfc
> -
> -#define AT91_SAMA5D2_HW_TRIG_CNT 3
> -#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
> -#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
> -
> -#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> -					 AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
> +	u16				VERSION;
> +};
>  
> -#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> -					 AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
> -#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
> -#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
> -#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
> +static const struct at91_adc_reg_layout sama5d2_layout = {
> +	.CR =			0x00,
> +	.MR =			0x04,
> +	.SEQR1 =		0x08,
> +	.SEQR2 =		0x0c,
> +	.CHER =			0x10,
> +	.CHDR =			0x14,
> +	.CHSR =			0x18,
> +	.LCDR =			0x20,
> +	.IER =			0x24,
> +	.IDR =			0x28,
> +	.IMR =			0x2c,
> +	.ISR =			0x30,
> +	.LCTMR =		0x34,
> +	.LCCWR =		0x38,
> +	.OVER =			0x3c,
> +	.EMR =			0x40,
> +	.CWR =			0x44,
> +	.CGR =			0x48,
> +	.COR =			0x4c,
> +	.ACR =			0x94,
> +	.TSMR =			0xb0,
> +	.XPOSR =		0xb4,
> +	.YPOSR =		0xb8,
> +	.PRESSR =		0xbc,
> +	.TRGR =			0xc0,
> +	.COSR =			0xd0,
> +	.CVR =			0xd4,
> +	.CECR =			0xd8,
> +	.WPMR =			0xe4,
> +	.WPSR =			0xe8,
> +	.VERSION =		0xfc,
> +};
>  
>  #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
>  #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
> @@ -235,18 +259,6 @@
>  
>  #define AT91_SAMA5D2_MAX_POS_BITS			12
>  
> -/*
> - * Maximum number of bytes to hold conversion from all channels
> - * without the timestamp.
> - */
> -#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> -					 AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
> -
> -/* This total must also include the timestamp */
> -#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
> -
> -#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
> -
>  #define AT91_HWFIFO_MAX_SIZE_STR	"128"
>  #define AT91_HWFIFO_MAX_SIZE		128
>  
> @@ -255,12 +267,12 @@
>  #define AT91_OSR_4SAMPLES		4
>  #define AT91_OSR_16SAMPLES		16
>  
> -#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)				\
> +#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)			\
>  	{								\
>  		.type = IIO_VOLTAGE,					\
>  		.channel = num,						\
>  		.address = addr,					\
> -		.scan_index = num,					\
> +		.scan_index = index,					\
>  		.scan_type = {						\
>  			.sign = 'u',					\
>  			.realbits = 14,					\
> @@ -274,14 +286,14 @@
>  		.indexed = 1,						\
>  	}
>  
> -#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)				\
> +#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)			\
>  	{								\
>  		.type = IIO_VOLTAGE,					\
>  		.differential = 1,					\
>  		.channel = num,						\
>  		.channel2 = num2,					\
>  		.address = addr,					\
> -		.scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,	\
> +		.scan_index = index,					\
>  		.scan_type = {						\
>  			.sign = 's',					\
>  			.realbits = 14,					\
> @@ -328,13 +340,48 @@
>  		.datasheet_name = name,					\
>  	}
>  
> -#define at91_adc_readl(st, reg)		readl_relaxed(st->base + reg)
> -#define at91_adc_writel(st, reg, val)	writel_relaxed(val, st->base + reg)
> +#define at91_adc_readl(st, reg)						\
> +	readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
I was a bit in two minds about whether this should be in capitals to make it clear
macro magic is going on, or whether lowercase is fine.  In the end I couldn't make
up my mind so will accept it like this! :)


Jonathan

_______________________________________________
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] 44+ messages in thread

* Re: [PATCH v2 00/10] iio: adc: at91-sama5d2_adc: add support for sama7g5
  2021-08-24 11:54 ` Eugen Hristev
@ 2021-08-30 12:26   ` Jonathan Cameron
  -1 siblings, 0 replies; 44+ messages in thread
From: Jonathan Cameron @ 2021-08-30 12:26 UTC (permalink / raw)
  To: Eugen Hristev
  Cc: linux-iio, devicetree, nicolas.ferre, linux-arm-kernel,
	linux-kernel, robh+dt, ludovic.desroches

On Tue, 24 Aug 2021 14:54:31 +0300
Eugen Hristev <eugen.hristev@microchip.com> wrote:

> Hi,
> 
> This series adds support for sama7g5.
> 
> The sama7g5 is slightly different from sama5d2, but has the same basic
> operations. The register map is a bit different, so, I added some primitives
> to differentiate between the two classes of hardware blocks (sama5d2-sam9x60
> and sama7g5).
> 
> Sama7g5 has 16 channels ADC, no resistive touch, and extra features
> (FIFOs, better oversampling , not implemented yet).
> 
> It is a rework of the series initially sent here:
> https://marc.info/?l=linux-iio&m=161461656807826&w=2
> 
> I reworked this according to review by Jonathan, meaning that first I created
> a no-op patch that will convert the driver to a more platform specific data
> dedicated type of driver. This adds various structures that hold things like
> register layout and channel information.
> After this I created few patches that implement the main differences between
> sama7g5 and older products: the end-of-conversion new register. I added
> helper functions to make code more easy to read and more simple.
> One the last patches adds the layout and channels for sama7g5.
> At this moment in linux-next, the DT for sama7g5 and sama7g5ek is present,
> and the last patches add and enable this node in DT for this board.
> 
> Eugen
0-8 applied with the minor tweak mentioned in a reply to relevant patch.

I'll assume 9-10 will got via normal soc related tree.

Note that I'm queuing these up for the merge window after this one now
(5.16).

Thanks,

Jonathan

> 
> 
> 
> Eugen Hristev (10):
>   dt-bindings: iio: adc: at91-sama5d2: add compatible for sama7g5-adc
>   iio: adc: at91-sama5d2_adc: initialize hardware after clock is started
>   iio: adc: at91-sama5d2_adc: remove unused definition
>   iio: adc: at91-sama5d2_adc: convert to platform specific data
>     structures
>   iio: adc: at91-sama5d2-adc: add support for separate end of conversion
>     registers
>   iio: adc: at91-sama5d2_adc: add helper for COR register
>   iio: adc: at91-sama5d2_adc: add support for sama7g5 device
>   iio: adc: at91-sama5d2_adc: update copyright and authors information
>   ARM: dts: at91: sama7g5: add node for the ADC
>   ARM: dts: at91: sama7g5ek: enable ADC on the board
> 
>  .../bindings/iio/adc/atmel,sama5d2-adc.yaml   |   1 +
>  arch/arm/boot/dts/at91-sama7g5ek.dts          |   8 +
>  arch/arm/boot/dts/sama7g5.dtsi                |  16 +
>  drivers/iio/adc/at91-sama5d2_adc.c            | 586 ++++++++++++------
>  4 files changed, 425 insertions(+), 186 deletions(-)
> 


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

* Re: [PATCH v2 00/10] iio: adc: at91-sama5d2_adc: add support for sama7g5
@ 2021-08-30 12:26   ` Jonathan Cameron
  0 siblings, 0 replies; 44+ messages in thread
From: Jonathan Cameron @ 2021-08-30 12:26 UTC (permalink / raw)
  To: Eugen Hristev
  Cc: devicetree, linux-iio, linux-kernel, ludovic.desroches, robh+dt,
	linux-arm-kernel

On Tue, 24 Aug 2021 14:54:31 +0300
Eugen Hristev <eugen.hristev@microchip.com> wrote:

> Hi,
> 
> This series adds support for sama7g5.
> 
> The sama7g5 is slightly different from sama5d2, but has the same basic
> operations. The register map is a bit different, so, I added some primitives
> to differentiate between the two classes of hardware blocks (sama5d2-sam9x60
> and sama7g5).
> 
> Sama7g5 has 16 channels ADC, no resistive touch, and extra features
> (FIFOs, better oversampling , not implemented yet).
> 
> It is a rework of the series initially sent here:
> https://marc.info/?l=linux-iio&m=161461656807826&w=2
> 
> I reworked this according to review by Jonathan, meaning that first I created
> a no-op patch that will convert the driver to a more platform specific data
> dedicated type of driver. This adds various structures that hold things like
> register layout and channel information.
> After this I created few patches that implement the main differences between
> sama7g5 and older products: the end-of-conversion new register. I added
> helper functions to make code more easy to read and more simple.
> One the last patches adds the layout and channels for sama7g5.
> At this moment in linux-next, the DT for sama7g5 and sama7g5ek is present,
> and the last patches add and enable this node in DT for this board.
> 
> Eugen
0-8 applied with the minor tweak mentioned in a reply to relevant patch.

I'll assume 9-10 will got via normal soc related tree.

Note that I'm queuing these up for the merge window after this one now
(5.16).

Thanks,

Jonathan

> 
> 
> 
> Eugen Hristev (10):
>   dt-bindings: iio: adc: at91-sama5d2: add compatible for sama7g5-adc
>   iio: adc: at91-sama5d2_adc: initialize hardware after clock is started
>   iio: adc: at91-sama5d2_adc: remove unused definition
>   iio: adc: at91-sama5d2_adc: convert to platform specific data
>     structures
>   iio: adc: at91-sama5d2-adc: add support for separate end of conversion
>     registers
>   iio: adc: at91-sama5d2_adc: add helper for COR register
>   iio: adc: at91-sama5d2_adc: add support for sama7g5 device
>   iio: adc: at91-sama5d2_adc: update copyright and authors information
>   ARM: dts: at91: sama7g5: add node for the ADC
>   ARM: dts: at91: sama7g5ek: enable ADC on the board
> 
>  .../bindings/iio/adc/atmel,sama5d2-adc.yaml   |   1 +
>  arch/arm/boot/dts/at91-sama7g5ek.dts          |   8 +
>  arch/arm/boot/dts/sama7g5.dtsi                |  16 +
>  drivers/iio/adc/at91-sama5d2_adc.c            | 586 ++++++++++++------
>  4 files changed, 425 insertions(+), 186 deletions(-)
> 


_______________________________________________
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] 44+ messages in thread

* Re: [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform specific data structures
  2021-08-30 12:21     ` Jonathan Cameron
@ 2021-08-30 12:28       ` Eugen.Hristev
  -1 siblings, 0 replies; 44+ messages in thread
From: Eugen.Hristev @ 2021-08-30 12:28 UTC (permalink / raw)
  To: jic23
  Cc: linux-iio, devicetree, Nicolas.Ferre, linux-arm-kernel,
	linux-kernel, robh+dt, Ludovic.Desroches

On 8/30/21 3:21 PM, Jonathan Cameron wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Tue, 24 Aug 2021 14:54:35 +0300
> Eugen Hristev <eugen.hristev@microchip.com> wrote:
> 
>> Convert the driver to platform specific structures. This means:
>> - create a register layout struct that will hold offsets for registers
>> - create a platform struct that will hold platform information (number of
>> channels, indexes for different channels and pointer to layout struct)
>> - convert specific macros that are platform dependent into platform variables
>>
>> This step is in fact a no-op, but allows the driver to be more flexible
>> and for future enhancement including adding new platforms that are partly
>> compatible with the current driver and differ slightly in register layout
>> or capabilities for example.
>>
>> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
>> ---
>>   drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
>>   1 file changed, 247 insertions(+), 163 deletions(-)
>>
>> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
>> index 9d71dcffcf93..8ede18b8d789 100644
>> --- a/drivers/iio/adc/at91-sama5d2_adc.c
>> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
>> @@ -27,8 +27,9 @@
>>   #include <linux/pinctrl/consumer.h>
>>   #include <linux/regulator/consumer.h>
>>
>> +struct at91_adc_reg_layout {
>>   /* Control Register */
>> -#define AT91_SAMA5D2_CR              0x00
>> +     u16                             CR;
>>   /* Software Reset */
>>   #define      AT91_SAMA5D2_CR_SWRST           BIT(0)
>>   /* Start Conversion */
>> @@ -39,7 +40,7 @@
>>   #define      AT91_SAMA5D2_CR_CMPRST          BIT(4)
>>
>>   /* Mode Register */
>> -#define AT91_SAMA5D2_MR              0x04
>> +     u16                             MR;
>>   /* Trigger Selection */
>>   #define      AT91_SAMA5D2_MR_TRGSEL(v)       ((v) << 1)
>>   /* ADTRG */
>> @@ -82,19 +83,19 @@
>>   #define      AT91_SAMA5D2_MR_USEQ            BIT(31)
>>
>>   /* Channel Sequence Register 1 */
>> -#define AT91_SAMA5D2_SEQR1   0x08
>> +     u16                             SEQR1;
>>   /* Channel Sequence Register 2 */
>> -#define AT91_SAMA5D2_SEQR2   0x0c
>> +     u16                             SEQR2;
>>   /* Channel Enable Register */
>> -#define AT91_SAMA5D2_CHER    0x10
>> +     u16                             CHER;
>>   /* Channel Disable Register */
>> -#define AT91_SAMA5D2_CHDR    0x14
>> +     u16                             CHDR;
>>   /* Channel Status Register */
>> -#define AT91_SAMA5D2_CHSR    0x18
>> +     u16                             CHSR;
>>   /* Last Converted Data Register */
>> -#define AT91_SAMA5D2_LCDR    0x20
>> +     u16                             LCDR;
>>   /* Interrupt Enable Register */
>> -#define AT91_SAMA5D2_IER     0x24
>> +     u16                             IER;
>>   /* Interrupt Enable Register - TS X measurement ready */
>>   #define AT91_SAMA5D2_IER_XRDY   BIT(20)
>>   /* Interrupt Enable Register - TS Y measurement ready */
>> @@ -109,22 +110,23 @@
>>   #define AT91_SAMA5D2_IER_PEN    BIT(29)
>>   /* Interrupt Enable Register - No pen detect */
>>   #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
>> +
>>   /* Interrupt Disable Register */
>> -#define AT91_SAMA5D2_IDR     0x28
>> +     u16                             IDR;
>>   /* Interrupt Mask Register */
>> -#define AT91_SAMA5D2_IMR     0x2c
>> +     u16                             IMR;
>>   /* Interrupt Status Register */
>> -#define AT91_SAMA5D2_ISR     0x30
>> +     u16                             ISR;
>>   /* Interrupt Status Register - Pen touching sense status */
>>   #define AT91_SAMA5D2_ISR_PENS   BIT(31)
>>   /* Last Channel Trigger Mode Register */
>> -#define AT91_SAMA5D2_LCTMR   0x34
>> +     u16                             LCTMR;
>>   /* Last Channel Compare Window Register */
>> -#define AT91_SAMA5D2_LCCWR   0x38
>> +     u16                             LCCWR;
>>   /* Overrun Status Register */
>> -#define AT91_SAMA5D2_OVER    0x3c
>> +     u16                             OVER;
>>   /* Extended Mode Register */
>> -#define AT91_SAMA5D2_EMR     0x40
>> +     u16                             EMR;
>>   /* Extended Mode Register - Oversampling rate */
>>   #define AT91_SAMA5D2_EMR_OSR(V)                      ((V) << 16)
>>   #define AT91_SAMA5D2_EMR_OSR_MASK            GENMASK(17, 16)
>> @@ -134,22 +136,22 @@
>>
>>   /* Extended Mode Register - Averaging on single trigger event */
>>   #define AT91_SAMA5D2_EMR_ASTE(V)             ((V) << 20)
>> +
>>   /* Compare Window Register */
>> -#define AT91_SAMA5D2_CWR     0x44
>> +     u16                             CWR;
>>   /* Channel Gain Register */
>> -#define AT91_SAMA5D2_CGR     0x48
>> -
>> +     u16                             CGR;
>>   /* Channel Offset Register */
>> -#define AT91_SAMA5D2_COR     0x4c
>> +     u16                             COR;
>>   #define AT91_SAMA5D2_COR_DIFF_OFFSET 16
>>
>>   /* Analog Control Register */
>> -#define AT91_SAMA5D2_ACR     0x94
>> +     u16                             ACR;
>>   /* Analog Control Register - Pen detect sensitivity mask */
>>   #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
>>
>>   /* Touchscreen Mode Register */
>> -#define AT91_SAMA5D2_TSMR    0xb0
>> +     u16                             TSMR;
>>   /* Touchscreen Mode Register - No touch mode */
>>   #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
>>   /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
>> @@ -178,13 +180,13 @@
>>   #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
>>
>>   /* Touchscreen X Position Register */
>> -#define AT91_SAMA5D2_XPOSR   0xb4
>> +     u16                             XPOSR;
>>   /* Touchscreen Y Position Register */
>> -#define AT91_SAMA5D2_YPOSR   0xb8
>> +     u16                             YPOSR;
>>   /* Touchscreen Pressure Register */
>> -#define AT91_SAMA5D2_PRESSR  0xbc
>> +     u16                             PRESSR;
>>   /* Trigger Register */
>> -#define AT91_SAMA5D2_TRGR    0xc0
>> +     u16                             TRGR;
>>   /* Mask for TRGMOD field of TRGR register */
>>   #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
>>   /* No trigger, only software trigger can start conversions */
>> @@ -203,30 +205,52 @@
>>   #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
>>
>>   /* Correction Select Register */
>> -#define AT91_SAMA5D2_COSR    0xd0
>> +     u16                             COSR;
>>   /* Correction Value Register */
>> -#define AT91_SAMA5D2_CVR     0xd4
>> +     u16                             CVR;
>>   /* Channel Error Correction Register */
>> -#define AT91_SAMA5D2_CECR    0xd8
>> +     u16                             CECR;
>>   /* Write Protection Mode Register */
>> -#define AT91_SAMA5D2_WPMR    0xe4
>> +     u16                             WPMR;
>>   /* Write Protection Status Register */
>> -#define AT91_SAMA5D2_WPSR    0xe8
>> +     u16                             WPSR;
>>   /* Version Register */
>> -#define AT91_SAMA5D2_VERSION 0xfc
>> -
>> -#define AT91_SAMA5D2_HW_TRIG_CNT 3
>> -#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
>> -#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
>> -
>> -#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
>> -                                      AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
>> +     u16                             VERSION;
>> +};
>>
>> -#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
>> -                                      AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
>> -#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
>> -#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
>> -#define AT91_SAMA5D2_MAX_CHAN_IDX    AT91_SAMA5D2_TOUCH_P_CHAN_IDX
>> +static const struct at91_adc_reg_layout sama5d2_layout = {
>> +     .CR =                   0x00,
>> +     .MR =                   0x04,
>> +     .SEQR1 =                0x08,
>> +     .SEQR2 =                0x0c,
>> +     .CHER =                 0x10,
>> +     .CHDR =                 0x14,
>> +     .CHSR =                 0x18,
>> +     .LCDR =                 0x20,
>> +     .IER =                  0x24,
>> +     .IDR =                  0x28,
>> +     .IMR =                  0x2c,
>> +     .ISR =                  0x30,
>> +     .LCTMR =                0x34,
>> +     .LCCWR =                0x38,
>> +     .OVER =                 0x3c,
>> +     .EMR =                  0x40,
>> +     .CWR =                  0x44,
>> +     .CGR =                  0x48,
>> +     .COR =                  0x4c,
>> +     .ACR =                  0x94,
>> +     .TSMR =                 0xb0,
>> +     .XPOSR =                0xb4,
>> +     .YPOSR =                0xb8,
>> +     .PRESSR =               0xbc,
>> +     .TRGR =                 0xc0,
>> +     .COSR =                 0xd0,
>> +     .CVR =                  0xd4,
>> +     .CECR =                 0xd8,
>> +     .WPMR =                 0xe4,
>> +     .WPSR =                 0xe8,
>> +     .VERSION =              0xfc,
>> +};
>>
>>   #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
>>   #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
>> @@ -235,18 +259,6 @@
>>
>>   #define AT91_SAMA5D2_MAX_POS_BITS                    12
>>
>> -/*
>> - * Maximum number of bytes to hold conversion from all channels
>> - * without the timestamp.
>> - */
>> -#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
>> -                                      AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
>> -
>> -/* This total must also include the timestamp */
>> -#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
>> -
>> -#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
>> -
>>   #define AT91_HWFIFO_MAX_SIZE_STR     "128"
>>   #define AT91_HWFIFO_MAX_SIZE         128
>>
>> @@ -255,12 +267,12 @@
>>   #define AT91_OSR_4SAMPLES            4
>>   #define AT91_OSR_16SAMPLES           16
>>
>> -#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)                          \
>> +#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)                   \
>>        {                                                               \
>>                .type = IIO_VOLTAGE,                                    \
>>                .channel = num,                                         \
>>                .address = addr,                                        \
>> -             .scan_index = num,                                      \
>> +             .scan_index = index,                                    \
>>                .scan_type = {                                          \
>>                        .sign = 'u',                                    \
>>                        .realbits = 14,                                 \
>> @@ -274,14 +286,14 @@
>>                .indexed = 1,                                           \
>>        }
>>
>> -#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)                              \
>> +#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)                       \
>>        {                                                               \
>>                .type = IIO_VOLTAGE,                                    \
>>                .differential = 1,                                      \
>>                .channel = num,                                         \
>>                .channel2 = num2,                                       \
>>                .address = addr,                                        \
>> -             .scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,       \
>> +             .scan_index = index,                                    \
>>                .scan_type = {                                          \
>>                        .sign = 's',                                    \
>>                        .realbits = 14,                                 \
>> @@ -328,13 +340,48 @@
>>                .datasheet_name = name,                                 \
>>        }
>>
>> -#define at91_adc_readl(st, reg)              readl_relaxed(st->base + reg)
>> -#define at91_adc_writel(st, reg, val)        writel_relaxed(val, st->base + reg)
>> +#define at91_adc_readl(st, reg)                                              \
>> +     readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
> I was a bit in two minds about whether this should be in capitals to make it clear
> macro magic is going on, or whether lowercase is fine.  In the end I couldn't make
> up my mind so will accept it like this! :)
> 
> 
> Jonathan
> 


I was doubting as well when I wrote this... but what convinced me was 
the much cleaner calls to the reg read and writes.
Has some drawbacks sometimes (like the XPOSR and YPOSR writes), but they 
are not all over the code, so I guess it's fine.

Thanks for reviewing !

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

* Re: [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform specific data structures
@ 2021-08-30 12:28       ` Eugen.Hristev
  0 siblings, 0 replies; 44+ messages in thread
From: Eugen.Hristev @ 2021-08-30 12:28 UTC (permalink / raw)
  To: jic23
  Cc: devicetree, linux-iio, linux-kernel, Ludovic.Desroches, robh+dt,
	linux-arm-kernel

On 8/30/21 3:21 PM, Jonathan Cameron wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Tue, 24 Aug 2021 14:54:35 +0300
> Eugen Hristev <eugen.hristev@microchip.com> wrote:
> 
>> Convert the driver to platform specific structures. This means:
>> - create a register layout struct that will hold offsets for registers
>> - create a platform struct that will hold platform information (number of
>> channels, indexes for different channels and pointer to layout struct)
>> - convert specific macros that are platform dependent into platform variables
>>
>> This step is in fact a no-op, but allows the driver to be more flexible
>> and for future enhancement including adding new platforms that are partly
>> compatible with the current driver and differ slightly in register layout
>> or capabilities for example.
>>
>> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
>> ---
>>   drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
>>   1 file changed, 247 insertions(+), 163 deletions(-)
>>
>> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
>> index 9d71dcffcf93..8ede18b8d789 100644
>> --- a/drivers/iio/adc/at91-sama5d2_adc.c
>> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
>> @@ -27,8 +27,9 @@
>>   #include <linux/pinctrl/consumer.h>
>>   #include <linux/regulator/consumer.h>
>>
>> +struct at91_adc_reg_layout {
>>   /* Control Register */
>> -#define AT91_SAMA5D2_CR              0x00
>> +     u16                             CR;
>>   /* Software Reset */
>>   #define      AT91_SAMA5D2_CR_SWRST           BIT(0)
>>   /* Start Conversion */
>> @@ -39,7 +40,7 @@
>>   #define      AT91_SAMA5D2_CR_CMPRST          BIT(4)
>>
>>   /* Mode Register */
>> -#define AT91_SAMA5D2_MR              0x04
>> +     u16                             MR;
>>   /* Trigger Selection */
>>   #define      AT91_SAMA5D2_MR_TRGSEL(v)       ((v) << 1)
>>   /* ADTRG */
>> @@ -82,19 +83,19 @@
>>   #define      AT91_SAMA5D2_MR_USEQ            BIT(31)
>>
>>   /* Channel Sequence Register 1 */
>> -#define AT91_SAMA5D2_SEQR1   0x08
>> +     u16                             SEQR1;
>>   /* Channel Sequence Register 2 */
>> -#define AT91_SAMA5D2_SEQR2   0x0c
>> +     u16                             SEQR2;
>>   /* Channel Enable Register */
>> -#define AT91_SAMA5D2_CHER    0x10
>> +     u16                             CHER;
>>   /* Channel Disable Register */
>> -#define AT91_SAMA5D2_CHDR    0x14
>> +     u16                             CHDR;
>>   /* Channel Status Register */
>> -#define AT91_SAMA5D2_CHSR    0x18
>> +     u16                             CHSR;
>>   /* Last Converted Data Register */
>> -#define AT91_SAMA5D2_LCDR    0x20
>> +     u16                             LCDR;
>>   /* Interrupt Enable Register */
>> -#define AT91_SAMA5D2_IER     0x24
>> +     u16                             IER;
>>   /* Interrupt Enable Register - TS X measurement ready */
>>   #define AT91_SAMA5D2_IER_XRDY   BIT(20)
>>   /* Interrupt Enable Register - TS Y measurement ready */
>> @@ -109,22 +110,23 @@
>>   #define AT91_SAMA5D2_IER_PEN    BIT(29)
>>   /* Interrupt Enable Register - No pen detect */
>>   #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
>> +
>>   /* Interrupt Disable Register */
>> -#define AT91_SAMA5D2_IDR     0x28
>> +     u16                             IDR;
>>   /* Interrupt Mask Register */
>> -#define AT91_SAMA5D2_IMR     0x2c
>> +     u16                             IMR;
>>   /* Interrupt Status Register */
>> -#define AT91_SAMA5D2_ISR     0x30
>> +     u16                             ISR;
>>   /* Interrupt Status Register - Pen touching sense status */
>>   #define AT91_SAMA5D2_ISR_PENS   BIT(31)
>>   /* Last Channel Trigger Mode Register */
>> -#define AT91_SAMA5D2_LCTMR   0x34
>> +     u16                             LCTMR;
>>   /* Last Channel Compare Window Register */
>> -#define AT91_SAMA5D2_LCCWR   0x38
>> +     u16                             LCCWR;
>>   /* Overrun Status Register */
>> -#define AT91_SAMA5D2_OVER    0x3c
>> +     u16                             OVER;
>>   /* Extended Mode Register */
>> -#define AT91_SAMA5D2_EMR     0x40
>> +     u16                             EMR;
>>   /* Extended Mode Register - Oversampling rate */
>>   #define AT91_SAMA5D2_EMR_OSR(V)                      ((V) << 16)
>>   #define AT91_SAMA5D2_EMR_OSR_MASK            GENMASK(17, 16)
>> @@ -134,22 +136,22 @@
>>
>>   /* Extended Mode Register - Averaging on single trigger event */
>>   #define AT91_SAMA5D2_EMR_ASTE(V)             ((V) << 20)
>> +
>>   /* Compare Window Register */
>> -#define AT91_SAMA5D2_CWR     0x44
>> +     u16                             CWR;
>>   /* Channel Gain Register */
>> -#define AT91_SAMA5D2_CGR     0x48
>> -
>> +     u16                             CGR;
>>   /* Channel Offset Register */
>> -#define AT91_SAMA5D2_COR     0x4c
>> +     u16                             COR;
>>   #define AT91_SAMA5D2_COR_DIFF_OFFSET 16
>>
>>   /* Analog Control Register */
>> -#define AT91_SAMA5D2_ACR     0x94
>> +     u16                             ACR;
>>   /* Analog Control Register - Pen detect sensitivity mask */
>>   #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
>>
>>   /* Touchscreen Mode Register */
>> -#define AT91_SAMA5D2_TSMR    0xb0
>> +     u16                             TSMR;
>>   /* Touchscreen Mode Register - No touch mode */
>>   #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
>>   /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
>> @@ -178,13 +180,13 @@
>>   #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
>>
>>   /* Touchscreen X Position Register */
>> -#define AT91_SAMA5D2_XPOSR   0xb4
>> +     u16                             XPOSR;
>>   /* Touchscreen Y Position Register */
>> -#define AT91_SAMA5D2_YPOSR   0xb8
>> +     u16                             YPOSR;
>>   /* Touchscreen Pressure Register */
>> -#define AT91_SAMA5D2_PRESSR  0xbc
>> +     u16                             PRESSR;
>>   /* Trigger Register */
>> -#define AT91_SAMA5D2_TRGR    0xc0
>> +     u16                             TRGR;
>>   /* Mask for TRGMOD field of TRGR register */
>>   #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
>>   /* No trigger, only software trigger can start conversions */
>> @@ -203,30 +205,52 @@
>>   #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
>>
>>   /* Correction Select Register */
>> -#define AT91_SAMA5D2_COSR    0xd0
>> +     u16                             COSR;
>>   /* Correction Value Register */
>> -#define AT91_SAMA5D2_CVR     0xd4
>> +     u16                             CVR;
>>   /* Channel Error Correction Register */
>> -#define AT91_SAMA5D2_CECR    0xd8
>> +     u16                             CECR;
>>   /* Write Protection Mode Register */
>> -#define AT91_SAMA5D2_WPMR    0xe4
>> +     u16                             WPMR;
>>   /* Write Protection Status Register */
>> -#define AT91_SAMA5D2_WPSR    0xe8
>> +     u16                             WPSR;
>>   /* Version Register */
>> -#define AT91_SAMA5D2_VERSION 0xfc
>> -
>> -#define AT91_SAMA5D2_HW_TRIG_CNT 3
>> -#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
>> -#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
>> -
>> -#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
>> -                                      AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
>> +     u16                             VERSION;
>> +};
>>
>> -#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
>> -                                      AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
>> -#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
>> -#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
>> -#define AT91_SAMA5D2_MAX_CHAN_IDX    AT91_SAMA5D2_TOUCH_P_CHAN_IDX
>> +static const struct at91_adc_reg_layout sama5d2_layout = {
>> +     .CR =                   0x00,
>> +     .MR =                   0x04,
>> +     .SEQR1 =                0x08,
>> +     .SEQR2 =                0x0c,
>> +     .CHER =                 0x10,
>> +     .CHDR =                 0x14,
>> +     .CHSR =                 0x18,
>> +     .LCDR =                 0x20,
>> +     .IER =                  0x24,
>> +     .IDR =                  0x28,
>> +     .IMR =                  0x2c,
>> +     .ISR =                  0x30,
>> +     .LCTMR =                0x34,
>> +     .LCCWR =                0x38,
>> +     .OVER =                 0x3c,
>> +     .EMR =                  0x40,
>> +     .CWR =                  0x44,
>> +     .CGR =                  0x48,
>> +     .COR =                  0x4c,
>> +     .ACR =                  0x94,
>> +     .TSMR =                 0xb0,
>> +     .XPOSR =                0xb4,
>> +     .YPOSR =                0xb8,
>> +     .PRESSR =               0xbc,
>> +     .TRGR =                 0xc0,
>> +     .COSR =                 0xd0,
>> +     .CVR =                  0xd4,
>> +     .CECR =                 0xd8,
>> +     .WPMR =                 0xe4,
>> +     .WPSR =                 0xe8,
>> +     .VERSION =              0xfc,
>> +};
>>
>>   #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
>>   #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
>> @@ -235,18 +259,6 @@
>>
>>   #define AT91_SAMA5D2_MAX_POS_BITS                    12
>>
>> -/*
>> - * Maximum number of bytes to hold conversion from all channels
>> - * without the timestamp.
>> - */
>> -#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
>> -                                      AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
>> -
>> -/* This total must also include the timestamp */
>> -#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
>> -
>> -#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
>> -
>>   #define AT91_HWFIFO_MAX_SIZE_STR     "128"
>>   #define AT91_HWFIFO_MAX_SIZE         128
>>
>> @@ -255,12 +267,12 @@
>>   #define AT91_OSR_4SAMPLES            4
>>   #define AT91_OSR_16SAMPLES           16
>>
>> -#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)                          \
>> +#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)                   \
>>        {                                                               \
>>                .type = IIO_VOLTAGE,                                    \
>>                .channel = num,                                         \
>>                .address = addr,                                        \
>> -             .scan_index = num,                                      \
>> +             .scan_index = index,                                    \
>>                .scan_type = {                                          \
>>                        .sign = 'u',                                    \
>>                        .realbits = 14,                                 \
>> @@ -274,14 +286,14 @@
>>                .indexed = 1,                                           \
>>        }
>>
>> -#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)                              \
>> +#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)                       \
>>        {                                                               \
>>                .type = IIO_VOLTAGE,                                    \
>>                .differential = 1,                                      \
>>                .channel = num,                                         \
>>                .channel2 = num2,                                       \
>>                .address = addr,                                        \
>> -             .scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,       \
>> +             .scan_index = index,                                    \
>>                .scan_type = {                                          \
>>                        .sign = 's',                                    \
>>                        .realbits = 14,                                 \
>> @@ -328,13 +340,48 @@
>>                .datasheet_name = name,                                 \
>>        }
>>
>> -#define at91_adc_readl(st, reg)              readl_relaxed(st->base + reg)
>> -#define at91_adc_writel(st, reg, val)        writel_relaxed(val, st->base + reg)
>> +#define at91_adc_readl(st, reg)                                              \
>> +     readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
> I was a bit in two minds about whether this should be in capitals to make it clear
> macro magic is going on, or whether lowercase is fine.  In the end I couldn't make
> up my mind so will accept it like this! :)
> 
> 
> Jonathan
> 


I was doubting as well when I wrote this... but what convinced me was 
the much cleaner calls to the reg read and writes.
Has some drawbacks sometimes (like the XPOSR and YPOSR writes), but they 
are not all over the code, so I guess it's fine.

Thanks for reviewing !
_______________________________________________
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] 44+ messages in thread

* Re: [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform specific data structures
  2021-08-24 11:54   ` Eugen Hristev
@ 2021-08-30 12:31     ` Eugen.Hristev
  -1 siblings, 0 replies; 44+ messages in thread
From: Eugen.Hristev @ 2021-08-30 12:31 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, Nicolas.Ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, Ludovic.Desroches

On 8/24/21 2:54 PM, Eugen Hristev wrote:
> Convert the driver to platform specific structures. This means:
> - create a register layout struct that will hold offsets for registers
> - create a platform struct that will hold platform information (number of
> channels, indexes for different channels and pointer to layout struct)
> - convert specific macros that are platform dependent into platform variables
> 
> This step is in fact a no-op, but allows the driver to be more flexible
> and for future enhancement including adding new platforms that are partly
> compatible with the current driver and differ slightly in register layout
> or capabilities for example.
> 
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> ---
>   drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
>   1 file changed, 247 insertions(+), 163 deletions(-)
> 
> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> index 9d71dcffcf93..8ede18b8d789 100644
> --- a/drivers/iio/adc/at91-sama5d2_adc.c
> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> @@ -27,8 +27,9 @@
>   #include <linux/pinctrl/consumer.h>
>   #include <linux/regulator/consumer.h>
>   
> +struct at91_adc_reg_layout {
>   /* Control Register */
> -#define AT91_SAMA5D2_CR		0x00
> +	u16				CR;
>   /* Software Reset */
>   #define	AT91_SAMA5D2_CR_SWRST		BIT(0)
>   /* Start Conversion */
> @@ -39,7 +40,7 @@
>   #define	AT91_SAMA5D2_CR_CMPRST		BIT(4)
>   
>   /* Mode Register */
> -#define AT91_SAMA5D2_MR		0x04
> +	u16				MR;
>   /* Trigger Selection */
>   #define	AT91_SAMA5D2_MR_TRGSEL(v)	((v) << 1)
>   /* ADTRG */
> @@ -82,19 +83,19 @@
>   #define	AT91_SAMA5D2_MR_USEQ		BIT(31)
>   
>   /* Channel Sequence Register 1 */
> -#define AT91_SAMA5D2_SEQR1	0x08
> +	u16				SEQR1;
>   /* Channel Sequence Register 2 */
> -#define AT91_SAMA5D2_SEQR2	0x0c
> +	u16				SEQR2;
>   /* Channel Enable Register */
> -#define AT91_SAMA5D2_CHER	0x10
> +	u16				CHER;
>   /* Channel Disable Register */
> -#define AT91_SAMA5D2_CHDR	0x14
> +	u16				CHDR;
>   /* Channel Status Register */
> -#define AT91_SAMA5D2_CHSR	0x18
> +	u16				CHSR;
>   /* Last Converted Data Register */
> -#define AT91_SAMA5D2_LCDR	0x20
> +	u16				LCDR;
>   /* Interrupt Enable Register */
> -#define AT91_SAMA5D2_IER	0x24
> +	u16				IER;
>   /* Interrupt Enable Register - TS X measurement ready */
>   #define AT91_SAMA5D2_IER_XRDY   BIT(20)
>   /* Interrupt Enable Register - TS Y measurement ready */
> @@ -109,22 +110,23 @@
>   #define AT91_SAMA5D2_IER_PEN    BIT(29)
>   /* Interrupt Enable Register - No pen detect */
>   #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
> +
>   /* Interrupt Disable Register */
> -#define AT91_SAMA5D2_IDR	0x28
> +	u16				IDR;
>   /* Interrupt Mask Register */
> -#define AT91_SAMA5D2_IMR	0x2c
> +	u16				IMR;
>   /* Interrupt Status Register */
> -#define AT91_SAMA5D2_ISR	0x30
> +	u16				ISR;
>   /* Interrupt Status Register - Pen touching sense status */
>   #define AT91_SAMA5D2_ISR_PENS   BIT(31)
>   /* Last Channel Trigger Mode Register */
> -#define AT91_SAMA5D2_LCTMR	0x34
> +	u16				LCTMR;
>   /* Last Channel Compare Window Register */
> -#define AT91_SAMA5D2_LCCWR	0x38
> +	u16				LCCWR;
>   /* Overrun Status Register */
> -#define AT91_SAMA5D2_OVER	0x3c
> +	u16				OVER;
>   /* Extended Mode Register */
> -#define AT91_SAMA5D2_EMR	0x40
> +	u16				EMR;
>   /* Extended Mode Register - Oversampling rate */
>   #define AT91_SAMA5D2_EMR_OSR(V)			((V) << 16)
>   #define AT91_SAMA5D2_EMR_OSR_MASK		GENMASK(17, 16)
> @@ -134,22 +136,22 @@
>   
>   /* Extended Mode Register - Averaging on single trigger event */
>   #define AT91_SAMA5D2_EMR_ASTE(V)		((V) << 20)
> +
>   /* Compare Window Register */
> -#define AT91_SAMA5D2_CWR	0x44
> +	u16				CWR;
>   /* Channel Gain Register */
> -#define AT91_SAMA5D2_CGR	0x48
> -
> +	u16				CGR;
>   /* Channel Offset Register */
> -#define AT91_SAMA5D2_COR	0x4c
> +	u16				COR;
>   #define AT91_SAMA5D2_COR_DIFF_OFFSET	16
>   
>   /* Analog Control Register */
> -#define AT91_SAMA5D2_ACR	0x94
> +	u16				ACR;
>   /* Analog Control Register - Pen detect sensitivity mask */
>   #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
>   
>   /* Touchscreen Mode Register */
> -#define AT91_SAMA5D2_TSMR	0xb0
> +	u16				TSMR;
>   /* Touchscreen Mode Register - No touch mode */
>   #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
>   /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
> @@ -178,13 +180,13 @@
>   #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
>   
>   /* Touchscreen X Position Register */
> -#define AT91_SAMA5D2_XPOSR	0xb4
> +	u16				XPOSR;
>   /* Touchscreen Y Position Register */
> -#define AT91_SAMA5D2_YPOSR	0xb8
> +	u16				YPOSR;
>   /* Touchscreen Pressure Register */
> -#define AT91_SAMA5D2_PRESSR	0xbc
> +	u16				PRESSR;
>   /* Trigger Register */
> -#define AT91_SAMA5D2_TRGR	0xc0
> +	u16				TRGR;
>   /* Mask for TRGMOD field of TRGR register */
>   #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
>   /* No trigger, only software trigger can start conversions */
> @@ -203,30 +205,52 @@
>   #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
>   
>   /* Correction Select Register */
> -#define AT91_SAMA5D2_COSR	0xd0
> +	u16				COSR;
>   /* Correction Value Register */
> -#define AT91_SAMA5D2_CVR	0xd4
> +	u16				CVR;
>   /* Channel Error Correction Register */
> -#define AT91_SAMA5D2_CECR	0xd8
> +	u16				CECR;
>   /* Write Protection Mode Register */
> -#define AT91_SAMA5D2_WPMR	0xe4
> +	u16				WPMR;
>   /* Write Protection Status Register */
> -#define AT91_SAMA5D2_WPSR	0xe8
> +	u16				WPSR;
>   /* Version Register */
> -#define AT91_SAMA5D2_VERSION	0xfc
> -
> -#define AT91_SAMA5D2_HW_TRIG_CNT 3
> -#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
> -#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
> -
> -#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> -					 AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
> +	u16				VERSION;
> +};
>   
> -#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> -					 AT91_SAMA5D2_DIFF_CHAN_CNT * 2)

Hi Jonathan,

While we are here, regarding the above line, I cannot tell why did I 
multiply by two the differential channel count. This makes some gaps in 
the number of channels when we put them all in the same table.

I did not change this as it would break the ABI regarding the bindings 
for the touchscreen #adc-cells phandle references.

However, I am thinking if there was a reason for it or it was a slip 
when I initially wrote this.

Do you think there is any reason to change it and tighten the holes in 
the indexes list ?


Eugen

> -#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
> -#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
> -#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
> +static const struct at91_adc_reg_layout sama5d2_layout = {
> +	.CR =			0x00,
> +	.MR =			0x04,
> +	.SEQR1 =		0x08,
> +	.SEQR2 =		0x0c,
> +	.CHER =			0x10,
> +	.CHDR =			0x14,
> +	.CHSR =			0x18,
> +	.LCDR =			0x20,
> +	.IER =			0x24,
> +	.IDR =			0x28,
> +	.IMR =			0x2c,
> +	.ISR =			0x30,
> +	.LCTMR =		0x34,
> +	.LCCWR =		0x38,
> +	.OVER =			0x3c,
> +	.EMR =			0x40,
> +	.CWR =			0x44,
> +	.CGR =			0x48,
> +	.COR =			0x4c,
> +	.ACR =			0x94,
> +	.TSMR =			0xb0,
> +	.XPOSR =		0xb4,
> +	.YPOSR =		0xb8,
> +	.PRESSR =		0xbc,
> +	.TRGR =			0xc0,
> +	.COSR =			0xd0,
> +	.CVR =			0xd4,
> +	.CECR =			0xd8,
> +	.WPMR =			0xe4,
> +	.WPSR =			0xe8,
> +	.VERSION =		0xfc,
> +};
>   
>   #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
>   #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
> @@ -235,18 +259,6 @@
>   
>   #define AT91_SAMA5D2_MAX_POS_BITS			12
>   
> -/*
> - * Maximum number of bytes to hold conversion from all channels
> - * without the timestamp.
> - */
> -#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> -					 AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
> -
> -/* This total must also include the timestamp */
> -#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
> -
> -#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
> -
>   #define AT91_HWFIFO_MAX_SIZE_STR	"128"
>   #define AT91_HWFIFO_MAX_SIZE		128
>   
> @@ -255,12 +267,12 @@
>   #define AT91_OSR_4SAMPLES		4
>   #define AT91_OSR_16SAMPLES		16
>   
> -#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)				\
> +#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)			\
>   	{								\
>   		.type = IIO_VOLTAGE,					\
>   		.channel = num,						\
>   		.address = addr,					\
> -		.scan_index = num,					\
> +		.scan_index = index,					\
>   		.scan_type = {						\
>   			.sign = 'u',					\
>   			.realbits = 14,					\
> @@ -274,14 +286,14 @@
>   		.indexed = 1,						\
>   	}
>   
> -#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)				\
> +#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)			\
>   	{								\
>   		.type = IIO_VOLTAGE,					\
>   		.differential = 1,					\
>   		.channel = num,						\
>   		.channel2 = num2,					\
>   		.address = addr,					\
> -		.scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,	\
> +		.scan_index = index,					\
>   		.scan_type = {						\
>   			.sign = 's',					\
>   			.realbits = 14,					\
> @@ -328,13 +340,48 @@
>   		.datasheet_name = name,					\
>   	}
>   
> -#define at91_adc_readl(st, reg)		readl_relaxed(st->base + reg)
> -#define at91_adc_writel(st, reg, val)	writel_relaxed(val, st->base + reg)
> +#define at91_adc_readl(st, reg)						\
> +	readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
> +#define at91_adc_read_chan(st, reg)					\
> +	readl_relaxed((st)->base + reg)
> +#define at91_adc_writel(st, reg, val)					\
> +	writel_relaxed(val, (st)->base + (st)->soc_info.platform->layout->reg)
> +
> +/**
> + * struct at91_adc_platform - at91-sama5d2 platform information struct
> + * @layout:		pointer to the reg layout struct
> + * @adc_channels:	pointer to an array of channels for registering in
> + *			the iio subsystem
> + * @nr_channels:	number of physical channels available
> + * @touch_chan_x:	index of the touchscreen X channel
> + * @touch_chan_y:	index of the touchscreen Y channel
> + * @touch_chan_p:	index of the touchscreen P channel
> + * @max_channels:	number of total channels
> + * @hw_trig_cnt:	number of possible hardware triggers
> + */
> +struct at91_adc_platform {
> +	const struct at91_adc_reg_layout	*layout;
> +	const struct iio_chan_spec		(*adc_channels)[];
> +	unsigned int				nr_channels;
> +	unsigned int				touch_chan_x;
> +	unsigned int				touch_chan_y;
> +	unsigned int				touch_chan_p;
> +	unsigned int				max_channels;
> +	unsigned int				hw_trig_cnt;
> +};
>   
> +/**
> + * struct at91_adc_soc_info - at91-sama5d2 soc information struct
> + * @startup_time:	device startup time
> + * @min_sample_rate:	minimum sample rate in Hz
> + * @max_sample_rate:	maximum sample rate in Hz
> + * @platform:		pointer to the platform structure
> + */
>   struct at91_adc_soc_info {
>   	unsigned			startup_time;
>   	unsigned			min_sample_rate;
>   	unsigned			max_sample_rate;
> +	const struct at91_adc_platform	*platform;
>   };
>   
>   struct at91_adc_trigger {
> @@ -382,6 +429,15 @@ struct at91_adc_touch {
>   	struct work_struct		workq;
>   };
>   
> +/*
> + * Buffer size requirements:
> + * No channels * bytes_per_channel(2) + timestamp bytes (8)
> + * Divided by 2 because we need half words.
> + * We assume 32 channels for now, has to be increased if needed.
> + * Nobody minds a buffer being too big.
> + */
> +#define AT91_BUFFER_MAX_HWORDS ((32 * 2 + 8) / 2)
> +
>   struct at91_adc_state {
>   	void __iomem			*base;
>   	int				irq;
> @@ -437,29 +493,49 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = {
>   	},
>   };
>   
> -static const struct iio_chan_spec at91_adc_channels[] = {
> -	AT91_SAMA5D2_CHAN_SINGLE(0, 0x50),
> -	AT91_SAMA5D2_CHAN_SINGLE(1, 0x54),
> -	AT91_SAMA5D2_CHAN_SINGLE(2, 0x58),
> -	AT91_SAMA5D2_CHAN_SINGLE(3, 0x5c),
> -	AT91_SAMA5D2_CHAN_SINGLE(4, 0x60),
> -	AT91_SAMA5D2_CHAN_SINGLE(5, 0x64),
> -	AT91_SAMA5D2_CHAN_SINGLE(6, 0x68),
> -	AT91_SAMA5D2_CHAN_SINGLE(7, 0x6c),
> -	AT91_SAMA5D2_CHAN_SINGLE(8, 0x70),
> -	AT91_SAMA5D2_CHAN_SINGLE(9, 0x74),
> -	AT91_SAMA5D2_CHAN_SINGLE(10, 0x78),
> -	AT91_SAMA5D2_CHAN_SINGLE(11, 0x7c),
> -	AT91_SAMA5D2_CHAN_DIFF(0, 1, 0x50),
> -	AT91_SAMA5D2_CHAN_DIFF(2, 3, 0x58),
> -	AT91_SAMA5D2_CHAN_DIFF(4, 5, 0x60),
> -	AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68),
> -	AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70),
> -	AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78),
> -	IIO_CHAN_SOFT_TIMESTAMP(AT91_SAMA5D2_TIMESTAMP_CHAN_IDX),
> -	AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_X_CHAN_IDX, "x", IIO_MOD_X),
> -	AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, "y", IIO_MOD_Y),
> -	AT91_SAMA5D2_CHAN_PRESSURE(AT91_SAMA5D2_TOUCH_P_CHAN_IDX, "pressure"),
> +static const struct iio_chan_spec at91_sama5d2_adc_channels[] = {
> +	AT91_SAMA5D2_CHAN_SINGLE(0, 0, 0x50),
> +	AT91_SAMA5D2_CHAN_SINGLE(1, 1, 0x54),
> +	AT91_SAMA5D2_CHAN_SINGLE(2, 2, 0x58),
> +	AT91_SAMA5D2_CHAN_SINGLE(3, 3, 0x5c),
> +	AT91_SAMA5D2_CHAN_SINGLE(4, 4, 0x60),
> +	AT91_SAMA5D2_CHAN_SINGLE(5, 5, 0x64),
> +	AT91_SAMA5D2_CHAN_SINGLE(6, 6, 0x68),
> +	AT91_SAMA5D2_CHAN_SINGLE(7, 7, 0x6c),
> +	AT91_SAMA5D2_CHAN_SINGLE(8, 8, 0x70),
> +	AT91_SAMA5D2_CHAN_SINGLE(9, 9, 0x74),
> +	AT91_SAMA5D2_CHAN_SINGLE(10, 10, 0x78),
> +	AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x7c),
> +	AT91_SAMA5D2_CHAN_DIFF(12, 0, 1, 0x50),
> +	AT91_SAMA5D2_CHAN_DIFF(13, 2, 3, 0x58),
> +	AT91_SAMA5D2_CHAN_DIFF(14, 4, 5, 0x60),
> +	AT91_SAMA5D2_CHAN_DIFF(15, 6, 7, 0x68),
> +	AT91_SAMA5D2_CHAN_DIFF(16, 8, 9, 0x70),
> +	AT91_SAMA5D2_CHAN_DIFF(17, 10, 11, 0x78),
> +	IIO_CHAN_SOFT_TIMESTAMP(18),
> +	AT91_SAMA5D2_CHAN_TOUCH(19, "x", IIO_MOD_X),
> +	AT91_SAMA5D2_CHAN_TOUCH(20, "y", IIO_MOD_Y),
> +	AT91_SAMA5D2_CHAN_PRESSURE(21, "pressure"),
> +};
> +
> +static const struct at91_adc_platform sama5d2_platform = {
> +	.layout = &sama5d2_layout,
> +	.adc_channels = &at91_sama5d2_adc_channels,
> +#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
> +#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
> +	.nr_channels = AT91_SAMA5D2_SINGLE_CHAN_CNT +
> +		       AT91_SAMA5D2_DIFF_CHAN_CNT,
> +#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX	(AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> +					AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
> +	.touch_chan_x = AT91_SAMA5D2_TOUCH_X_CHAN_IDX,
> +#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX	(AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
> +	.touch_chan_y = AT91_SAMA5D2_TOUCH_Y_CHAN_IDX,
> +#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX	(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
> +	.touch_chan_p = AT91_SAMA5D2_TOUCH_P_CHAN_IDX,
> +#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
> +	.max_channels = ARRAY_SIZE(at91_sama5d2_adc_channels),
> +#define AT91_SAMA5D2_HW_TRIG_CNT	3
> +	.hw_trig_cnt = AT91_SAMA5D2_HW_TRIG_CNT,
>   };
>   
>   static int at91_adc_chan_xlate(struct iio_dev *indio_dev, int chan)
> @@ -493,6 +569,7 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
>   {
>   	u32 mask = 0;
>   	u8 bit;
> +	struct at91_adc_state *st = iio_priv(indio_dev);
>   
>   	for_each_set_bit(bit, indio_dev->active_scan_mask,
>   			 indio_dev->num_channels) {
> @@ -501,13 +578,13 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
>   		mask |= BIT(chan->channel);
>   	}
>   
> -	return mask & GENMASK(11, 0);
> +	return mask & GENMASK(st->soc_info.platform->nr_channels, 0);
>   }
>   
>   static void at91_adc_config_emr(struct at91_adc_state *st)
>   {
>   	/* configure the extended mode register */
> -	unsigned int emr = at91_adc_readl(st, AT91_SAMA5D2_EMR);
> +	unsigned int emr = at91_adc_readl(st, EMR);
>   
>   	/* select oversampling per single trigger event */
>   	emr |= AT91_SAMA5D2_EMR_ASTE(1);
> @@ -531,7 +608,7 @@ static void at91_adc_config_emr(struct at91_adc_state *st)
>   		break;
>   	}
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_EMR, emr);
> +	at91_adc_writel(st, EMR, emr);
>   }
>   
>   static int at91_adc_adjust_val_osr(struct at91_adc_state *st, int *val)
> @@ -584,9 +661,9 @@ static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
>   
>   	if (!state) {
>   		/* disabling touch IRQs and setting mode to no touch enabled */
> -		at91_adc_writel(st, AT91_SAMA5D2_IDR,
> +		at91_adc_writel(st, IDR,
>   				AT91_SAMA5D2_IER_PEN | AT91_SAMA5D2_IER_NOPEN);
> -		at91_adc_writel(st, AT91_SAMA5D2_TSMR, 0);
> +		at91_adc_writel(st, TSMR, 0);
>   		return 0;
>   	}
>   	/*
> @@ -612,19 +689,19 @@ static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
>   	tsmr |= AT91_SAMA5D2_TSMR_PENDET_ENA;
>   	tsmr |= AT91_SAMA5D2_TSMR_TSFREQ(2) & AT91_SAMA5D2_TSMR_TSFREQ_MASK;
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_TSMR, tsmr);
> +	at91_adc_writel(st, TSMR, tsmr);
>   
> -	acr =  at91_adc_readl(st, AT91_SAMA5D2_ACR);
> +	acr =  at91_adc_readl(st, ACR);
>   	acr &= ~AT91_SAMA5D2_ACR_PENDETSENS_MASK;
>   	acr |= 0x02 & AT91_SAMA5D2_ACR_PENDETSENS_MASK;
> -	at91_adc_writel(st, AT91_SAMA5D2_ACR, acr);
> +	at91_adc_writel(st, ACR, acr);
>   
>   	/* Sample Period Time = (TRGPER + 1) / ADCClock */
>   	st->touch_st.sample_period_val =
>   				 round_up((AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US *
>   				 clk_khz / 1000) - 1, 1);
>   	/* enable pen detect IRQ */
> -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
> +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_PEN);
>   
>   	return 0;
>   }
> @@ -640,7 +717,11 @@ static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
>   	 * max = 2^AT91_SAMA5D2_MAX_POS_BITS - 1
>   	 */
>   	/* first half of register is the x or y, second half is the scale */
> -	val = at91_adc_readl(st, reg);
> +	if (reg == st->soc_info.platform->layout->XPOSR)
> +		val = at91_adc_readl(st, XPOSR);
> +	else if (reg == st->soc_info.platform->layout->YPOSR)
> +		val = at91_adc_readl(st, YPOSR);
> +
>   	if (!val)
>   		dev_dbg(&st->indio_dev->dev, "pos is 0\n");
>   
> @@ -658,13 +739,13 @@ static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
>   
>   static u16 at91_adc_touch_x_pos(struct at91_adc_state *st)
>   {
> -	st->touch_st.x_pos = at91_adc_touch_pos(st, AT91_SAMA5D2_XPOSR);
> +	st->touch_st.x_pos = at91_adc_touch_pos(st, st->soc_info.platform->layout->XPOSR);
>   	return st->touch_st.x_pos;
>   }
>   
>   static u16 at91_adc_touch_y_pos(struct at91_adc_state *st)
>   {
> -	return at91_adc_touch_pos(st, AT91_SAMA5D2_YPOSR);
> +	return at91_adc_touch_pos(st, st->soc_info.platform->layout->YPOSR);
>   }
>   
>   static u16 at91_adc_touch_pressure(struct at91_adc_state *st)
> @@ -676,7 +757,7 @@ static u16 at91_adc_touch_pressure(struct at91_adc_state *st)
>   	u32 factor = 1000;
>   
>   	/* calculate the pressure */
> -	val = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
> +	val = at91_adc_readl(st, PRESSR);
>   	z1 = val & AT91_SAMA5D2_XYZ_MASK;
>   	z2 = (val >> 16) & AT91_SAMA5D2_XYZ_MASK;
>   
> @@ -700,9 +781,9 @@ static int at91_adc_read_position(struct at91_adc_state *st, int chan, u16 *val)
>   	*val = 0;
>   	if (!st->touch_st.touching)
>   		return -ENODATA;
> -	if (chan == AT91_SAMA5D2_TOUCH_X_CHAN_IDX)
> +	if (chan == st->soc_info.platform->touch_chan_x)
>   		*val = at91_adc_touch_x_pos(st);
> -	else if (chan == AT91_SAMA5D2_TOUCH_Y_CHAN_IDX)
> +	else if (chan == st->soc_info.platform->touch_chan_y)
>   		*val = at91_adc_touch_y_pos(st);
>   	else
>   		return -ENODATA;
> @@ -715,7 +796,7 @@ static int at91_adc_read_pressure(struct at91_adc_state *st, int chan, u16 *val)
>   	*val = 0;
>   	if (!st->touch_st.touching)
>   		return -ENODATA;
> -	if (chan == AT91_SAMA5D2_TOUCH_P_CHAN_IDX)
> +	if (chan == st->soc_info.platform->touch_chan_y)
>   		*val = at91_adc_touch_pressure(st);
>   	else
>   		return -ENODATA;
> @@ -727,7 +808,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
>   {
>   	struct iio_dev *indio = iio_trigger_get_drvdata(trig);
>   	struct at91_adc_state *st = iio_priv(indio);
> -	u32 status = at91_adc_readl(st, AT91_SAMA5D2_TRGR);
> +	u32 status = at91_adc_readl(st, TRGR);
>   
>   	/* clear TRGMOD */
>   	status &= ~AT91_SAMA5D2_TRGR_TRGMOD_MASK;
> @@ -736,7 +817,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
>   		status |= st->selected_trig->trgmod_value;
>   
>   	/* set/unset hw trigger */
> -	at91_adc_writel(st, AT91_SAMA5D2_TRGR, status);
> +	at91_adc_writel(st, TRGR, status);
>   
>   	return 0;
>   }
> @@ -753,7 +834,7 @@ static void at91_adc_reenable_trigger(struct iio_trigger *trig)
>   	enable_irq(st->irq);
>   
>   	/* Needed to ACK the DRDY interruption */
> -	at91_adc_readl(st, AT91_SAMA5D2_LCDR);
> +	at91_adc_readl(st, LCDR);
>   }
>   
>   static const struct iio_trigger_ops at91_adc_trigger_ops = {
> @@ -848,7 +929,7 @@ static int at91_adc_dma_start(struct iio_dev *indio_dev)
>   	}
>   
>   	/* enable general overrun error signaling */
> -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_GOVRE);
> +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_GOVRE);
>   	/* Issue pending DMA requests */
>   	dma_async_issue_pending(st->dma_st.dma_chan);
>   
> @@ -878,7 +959,7 @@ static bool at91_adc_current_chan_is_touch(struct iio_dev *indio_dev)
>   
>   	return !!bitmap_subset(indio_dev->active_scan_mask,
>   			       &st->touch_st.channels_bitmask,
> -			       AT91_SAMA5D2_MAX_CHAN_IDX + 1);
> +			       st->soc_info.platform->max_channels + 1);
>   }
>   
>   static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
> @@ -915,7 +996,7 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
>   		    chan->type == IIO_PRESSURE)
>   			continue;
>   
> -		cor = at91_adc_readl(st, AT91_SAMA5D2_COR);
> +		cor = at91_adc_readl(st, COR);
>   
>   		if (chan->differential)
>   			cor |= (BIT(chan->channel) | BIT(chan->channel2)) <<
> @@ -924,13 +1005,13 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
>   			cor &= ~(BIT(chan->channel) <<
>   			       AT91_SAMA5D2_COR_DIFF_OFFSET);
>   
> -		at91_adc_writel(st, AT91_SAMA5D2_COR, cor);
> +		at91_adc_writel(st, COR, cor);
>   
> -		at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel));
> +		at91_adc_writel(st, CHER, BIT(chan->channel));
>   	}
>   
>   	if (at91_adc_buffer_check_use_irq(indio_dev, st))
> -		at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_DRDY);
> +		at91_adc_writel(st, IER, AT91_SAMA5D2_IER_DRDY);
>   
>   	return 0;
>   }
> @@ -966,17 +1047,17 @@ static int at91_adc_buffer_postdisable(struct iio_dev *indio_dev)
>   		    chan->type == IIO_PRESSURE)
>   			continue;
>   
> -		at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
> +		at91_adc_writel(st, CHDR, BIT(chan->channel));
>   
>   		if (st->dma_st.dma_chan)
> -			at91_adc_readl(st, chan->address);
> +			at91_adc_read_chan(st, chan->address);
>   	}
>   
>   	if (at91_adc_buffer_check_use_irq(indio_dev, st))
> -		at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_DRDY);
> +		at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_DRDY);
>   
>   	/* read overflow register to clear possible overflow status */
> -	at91_adc_readl(st, AT91_SAMA5D2_OVER);
> +	at91_adc_readl(st, OVER);
>   
>   	/* if we are using DMA we must clear registers and end DMA */
>   	if (st->dma_st.dma_chan)
> @@ -1024,7 +1105,7 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
>   	 * Check if the conversion is ready. If not, wait a little bit, and
>   	 * in case of timeout exit with an error.
>   	 */
> -	while ((at91_adc_readl(st, AT91_SAMA5D2_ISR) & mask) != mask &&
> +	while ((at91_adc_readl(st, ISR) & mask) != mask &&
>   	       timeout) {
>   		usleep_range(50, 100);
>   		timeout--;
> @@ -1052,7 +1133,7 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
>   		 * Thus, emit a warning.
>   		 */
>   		if (chan->type == IIO_VOLTAGE) {
> -			val = at91_adc_readl(st, chan->address);
> +			val = at91_adc_read_chan(st, chan->address);
>   			at91_adc_adjust_val_osr(st, &val);
>   			st->buffer[i] = val;
>   		} else {
> @@ -1073,7 +1154,7 @@ static void at91_adc_trigger_handler_dma(struct iio_dev *indio_dev)
>   	s64 interval;
>   	int sample_index = 0, sample_count, sample_size;
>   
> -	u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
> +	u32 status = at91_adc_readl(st, ISR);
>   	/* if we reached this point, we cannot sample faster */
>   	if (status & AT91_SAMA5D2_IER_GOVRE)
>   		pr_info_ratelimited("%s: conversion overrun detected\n",
> @@ -1125,7 +1206,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
>   	 * actually polling the trigger now.
>   	 */
>   	if (iio_trigger_validate_own_device(indio_dev->trig, indio_dev))
> -		at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START);
> +		at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
>   
>   	if (st->dma_st.dma_chan)
>   		at91_adc_trigger_handler_dma(indio_dev);
> @@ -1172,11 +1253,11 @@ static void at91_adc_setup_samp_freq(struct iio_dev *indio_dev, unsigned freq)
>   	startup = at91_adc_startup_time(st->soc_info.startup_time,
>   					freq / 1000);
>   
> -	mr = at91_adc_readl(st, AT91_SAMA5D2_MR);
> +	mr = at91_adc_readl(st, MR);
>   	mr &= ~(AT91_SAMA5D2_MR_STARTUP_MASK | AT91_SAMA5D2_MR_PRESCAL_MASK);
>   	mr |= AT91_SAMA5D2_MR_STARTUP(startup);
>   	mr |= AT91_SAMA5D2_MR_PRESCAL(prescal);
> -	at91_adc_writel(st, AT91_SAMA5D2_MR, mr);
> +	at91_adc_writel(st, MR, mr);
>   
>   	dev_dbg(&indio_dev->dev, "freq: %u, startup: %u, prescal: %u\n",
>   		freq, startup, prescal);
> @@ -1196,7 +1277,7 @@ static void at91_adc_touch_data_handler(struct iio_dev *indio_dev)
>   	int i = 0;
>   
>   	for_each_set_bit(bit, indio_dev->active_scan_mask,
> -			 AT91_SAMA5D2_MAX_CHAN_IDX + 1) {
> +			 st->soc_info.platform->max_channels + 1) {
>   		struct iio_chan_spec const *chan =
>   					 at91_adc_chan_get(indio_dev, bit);
>   
> @@ -1222,12 +1303,11 @@ static void at91_adc_touch_data_handler(struct iio_dev *indio_dev)
>   
>   static void at91_adc_pen_detect_interrupt(struct at91_adc_state *st)
>   {
> -	at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_PEN);
> -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_NOPEN |
> +	at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_PEN);
> +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_NOPEN |
>   			AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
>   			AT91_SAMA5D2_IER_PRDY);
> -	at91_adc_writel(st, AT91_SAMA5D2_TRGR,
> -			AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC |
> +	at91_adc_writel(st, TRGR, AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC |
>   			AT91_SAMA5D2_TRGR_TRGPER(st->touch_st.sample_period_val));
>   	st->touch_st.touching = true;
>   }
> @@ -1236,16 +1316,15 @@ static void at91_adc_no_pen_detect_interrupt(struct iio_dev *indio_dev)
>   {
>   	struct at91_adc_state *st = iio_priv(indio_dev);
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_TRGR,
> -			AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER);
> -	at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_NOPEN |
> +	at91_adc_writel(st, TRGR, AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER);
> +	at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_NOPEN |
>   			AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
>   			AT91_SAMA5D2_IER_PRDY);
>   	st->touch_st.touching = false;
>   
>   	at91_adc_touch_data_handler(indio_dev);
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
> +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_PEN);
>   }
>   
>   static void at91_adc_workq_handler(struct work_struct *workq)
> @@ -1263,8 +1342,8 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
>   {
>   	struct iio_dev *indio = private;
>   	struct at91_adc_state *st = iio_priv(indio);
> -	u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
> -	u32 imr = at91_adc_readl(st, AT91_SAMA5D2_IMR);
> +	u32 status = at91_adc_readl(st, ISR);
> +	u32 imr = at91_adc_readl(st, IMR);
>   	u32 rdy_mask = AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
>   			AT91_SAMA5D2_IER_PRDY;
>   
> @@ -1285,9 +1364,9 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
>   		 * touching, but the measurements are not ready yet.
>   		 * read and ignore.
>   		 */
> -		status = at91_adc_readl(st, AT91_SAMA5D2_XPOSR);
> -		status = at91_adc_readl(st, AT91_SAMA5D2_YPOSR);
> -		status = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
> +		status = at91_adc_readl(st, XPOSR);
> +		status = at91_adc_readl(st, YPOSR);
> +		status = at91_adc_readl(st, PRESSR);
>   	} else if (iio_buffer_enabled(indio) &&
>   		   (status & AT91_SAMA5D2_IER_DRDY)) {
>   		/* triggered buffer without DMA */
> @@ -1299,7 +1378,7 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
>   		WARN(true, "Unexpected irq occurred\n");
>   	} else if (!iio_buffer_enabled(indio)) {
>   		/* software requested conversion */
> -		st->conversion_value = at91_adc_readl(st, st->chan->address);
> +		st->conversion_value = at91_adc_read_chan(st, st->chan->address);
>   		st->conversion_done = true;
>   		wake_up_interruptible(&st->wq_data_available);
>   	}
> @@ -1360,10 +1439,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
>   		cor = (BIT(chan->channel) | BIT(chan->channel2)) <<
>   		      AT91_SAMA5D2_COR_DIFF_OFFSET;
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_COR, cor);
> -	at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel));
> -	at91_adc_writel(st, AT91_SAMA5D2_IER, BIT(chan->channel));
> -	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START);
> +	at91_adc_writel(st, COR, cor);
> +	at91_adc_writel(st, CHER, BIT(chan->channel));
> +	at91_adc_writel(st, IER, BIT(chan->channel));
> +	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
>   
>   	ret = wait_event_interruptible_timeout(st->wq_data_available,
>   					       st->conversion_done,
> @@ -1379,11 +1458,11 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
>   		st->conversion_done = false;
>   	}
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_IDR, BIT(chan->channel));
> -	at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
> +	at91_adc_writel(st, IDR, BIT(chan->channel));
> +	at91_adc_writel(st, CHDR, BIT(chan->channel));
>   
>   	/* Needed to ACK the DRDY interruption */
> -	at91_adc_readl(st, AT91_SAMA5D2_LCDR);
> +	at91_adc_readl(st, LCDR);
>   
>   	mutex_unlock(&st->lock);
>   
> @@ -1455,14 +1534,15 @@ static void at91_adc_dma_init(struct platform_device *pdev)
>   	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>   	struct at91_adc_state *st = iio_priv(indio_dev);
>   	struct dma_slave_config config = {0};
> +	/* we have 2 bytes for each channel */
> +	unsigned int sample_size = st->soc_info.platform->nr_channels * 2;
>   	/*
>   	 * We make the buffer double the size of the fifo,
>   	 * such that DMA uses one half of the buffer (full fifo size)
>   	 * and the software uses the other half to read/write.
>   	 */
>   	unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
> -					  AT91_BUFFER_MAX_CONVERSION_BYTES * 2,
> -					  PAGE_SIZE);
> +					  sample_size * 2, PAGE_SIZE);
>   
>   	if (st->dma_st.dma_chan)
>   		return;
> @@ -1486,7 +1566,7 @@ static void at91_adc_dma_init(struct platform_device *pdev)
>   	/* Configure DMA channel to read data register */
>   	config.direction = DMA_DEV_TO_MEM;
>   	config.src_addr = (phys_addr_t)(st->dma_st.phys_addr
> -			  + AT91_SAMA5D2_LCDR);
> +			  + st->soc_info.platform->layout->LCDR);
>   	config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
>   	config.src_maxburst = 1;
>   	config.dst_maxburst = 1;
> @@ -1515,9 +1595,10 @@ static void at91_adc_dma_disable(struct platform_device *pdev)
>   {
>   	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>   	struct at91_adc_state *st = iio_priv(indio_dev);
> +	/* we have 2 bytes for each channel */
> +	unsigned int sample_size = st->soc_info.platform->nr_channels * 2;
>   	unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
> -					  AT91_BUFFER_MAX_CONVERSION_BYTES * 2,
> -					  PAGE_SIZE);
> +					  sample_size * 2, PAGE_SIZE);
>   
>   	/* if we are not using DMA, just return */
>   	if (!st->dma_st.dma_chan)
> @@ -1578,14 +1659,14 @@ static int at91_adc_update_scan_mode(struct iio_dev *indio_dev,
>   	struct at91_adc_state *st = iio_priv(indio_dev);
>   
>   	if (bitmap_subset(scan_mask, &st->touch_st.channels_bitmask,
> -			  AT91_SAMA5D2_MAX_CHAN_IDX + 1))
> +			  st->soc_info.platform->max_channels + 1))
>   		return 0;
>   	/*
>   	 * if the new bitmap is a combination of touchscreen and regular
>   	 * channels, then we are not fine
>   	 */
>   	if (bitmap_intersects(&st->touch_st.channels_bitmask, scan_mask,
> -			      AT91_SAMA5D2_MAX_CHAN_IDX + 1))
> +			      st->soc_info.platform->max_channels + 1))
>   		return -EINVAL;
>   	return 0;
>   }
> @@ -1594,13 +1675,13 @@ static void at91_adc_hw_init(struct iio_dev *indio_dev)
>   {
>   	struct at91_adc_state *st = iio_priv(indio_dev);
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
> -	at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff);
> +	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
> +	at91_adc_writel(st, IDR, 0xffffffff);
>   	/*
>   	 * Transfer field must be set to 2 according to the datasheet and
>   	 * allows different analog settings for each channel.
>   	 */
> -	at91_adc_writel(st, AT91_SAMA5D2_MR,
> +	at91_adc_writel(st, MR,
>   			AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH);
>   
>   	at91_adc_setup_samp_freq(indio_dev, st->soc_info.min_sample_rate);
> @@ -1716,21 +1797,23 @@ static int at91_adc_probe(struct platform_device *pdev)
>   	if (!indio_dev)
>   		return -ENOMEM;
>   
> +	st = iio_priv(indio_dev);
> +	st->indio_dev = indio_dev;
> +
> +	st->soc_info.platform = of_device_get_match_data(&pdev->dev);
> +
>   	indio_dev->name = dev_name(&pdev->dev);
>   	indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
>   	indio_dev->info = &at91_adc_info;
> -	indio_dev->channels = at91_adc_channels;
> -	indio_dev->num_channels = ARRAY_SIZE(at91_adc_channels);
> -
> -	st = iio_priv(indio_dev);
> -	st->indio_dev = indio_dev;
> +	indio_dev->channels = *st->soc_info.platform->adc_channels;
> +	indio_dev->num_channels = st->soc_info.platform->max_channels;
>   
>   	bitmap_set(&st->touch_st.channels_bitmask,
> -		   AT91_SAMA5D2_TOUCH_X_CHAN_IDX, 1);
> +		   st->soc_info.platform->touch_chan_x, 1);
>   	bitmap_set(&st->touch_st.channels_bitmask,
> -		   AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, 1);
> +		   st->soc_info.platform->touch_chan_y, 1);
>   	bitmap_set(&st->touch_st.channels_bitmask,
> -		   AT91_SAMA5D2_TOUCH_P_CHAN_IDX, 1);
> +		   st->soc_info.platform->touch_chan_p, 1);
>   
>   	st->oversampling_ratio = AT91_OSR_1SAMPLES;
>   
> @@ -1770,7 +1853,7 @@ static int at91_adc_probe(struct platform_device *pdev)
>   	st->selected_trig = NULL;
>   
>   	/* find the right trigger, or no trigger at all */
> -	for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT + 1; i++)
> +	for (i = 0; i < st->soc_info.platform->hw_trig_cnt + 1; i++)
>   		if (at91_adc_trigger_list[i].edge_type == edge_type) {
>   			st->selected_trig = &at91_adc_trigger_list[i];
>   			break;
> @@ -1855,7 +1938,7 @@ static int at91_adc_probe(struct platform_device *pdev)
>   			 st->selected_trig->name);
>   
>   	dev_info(&pdev->dev, "version: %x\n",
> -		 readl_relaxed(st->base + AT91_SAMA5D2_VERSION));
> +		 readl_relaxed(st->base + st->soc_info.platform->layout->VERSION));
>   
>   	return 0;
>   
> @@ -1898,7 +1981,7 @@ static __maybe_unused int at91_adc_suspend(struct device *dev)
>   	 * and can be used by for other devices.
>   	 * Otherwise, ADC will hog them and we can't go to suspend mode.
>   	 */
> -	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
> +	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
>   
>   	clk_disable_unprepare(st->per_clk);
>   	regulator_disable(st->vref);
> @@ -1958,6 +2041,7 @@ static SIMPLE_DEV_PM_OPS(at91_adc_pm_ops, at91_adc_suspend, at91_adc_resume);
>   static const struct of_device_id at91_adc_dt_match[] = {
>   	{
>   		.compatible = "atmel,sama5d2-adc",
> +		.data = (const void *)&sama5d2_platform,
>   	}, {
>   		/* sentinel */
>   	}
> 


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

* Re: [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform specific data structures
@ 2021-08-30 12:31     ` Eugen.Hristev
  0 siblings, 0 replies; 44+ messages in thread
From: Eugen.Hristev @ 2021-08-30 12:31 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, Nicolas.Ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, Ludovic.Desroches

On 8/24/21 2:54 PM, Eugen Hristev wrote:
> Convert the driver to platform specific structures. This means:
> - create a register layout struct that will hold offsets for registers
> - create a platform struct that will hold platform information (number of
> channels, indexes for different channels and pointer to layout struct)
> - convert specific macros that are platform dependent into platform variables
> 
> This step is in fact a no-op, but allows the driver to be more flexible
> and for future enhancement including adding new platforms that are partly
> compatible with the current driver and differ slightly in register layout
> or capabilities for example.
> 
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> ---
>   drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
>   1 file changed, 247 insertions(+), 163 deletions(-)
> 
> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> index 9d71dcffcf93..8ede18b8d789 100644
> --- a/drivers/iio/adc/at91-sama5d2_adc.c
> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> @@ -27,8 +27,9 @@
>   #include <linux/pinctrl/consumer.h>
>   #include <linux/regulator/consumer.h>
>   
> +struct at91_adc_reg_layout {
>   /* Control Register */
> -#define AT91_SAMA5D2_CR		0x00
> +	u16				CR;
>   /* Software Reset */
>   #define	AT91_SAMA5D2_CR_SWRST		BIT(0)
>   /* Start Conversion */
> @@ -39,7 +40,7 @@
>   #define	AT91_SAMA5D2_CR_CMPRST		BIT(4)
>   
>   /* Mode Register */
> -#define AT91_SAMA5D2_MR		0x04
> +	u16				MR;
>   /* Trigger Selection */
>   #define	AT91_SAMA5D2_MR_TRGSEL(v)	((v) << 1)
>   /* ADTRG */
> @@ -82,19 +83,19 @@
>   #define	AT91_SAMA5D2_MR_USEQ		BIT(31)
>   
>   /* Channel Sequence Register 1 */
> -#define AT91_SAMA5D2_SEQR1	0x08
> +	u16				SEQR1;
>   /* Channel Sequence Register 2 */
> -#define AT91_SAMA5D2_SEQR2	0x0c
> +	u16				SEQR2;
>   /* Channel Enable Register */
> -#define AT91_SAMA5D2_CHER	0x10
> +	u16				CHER;
>   /* Channel Disable Register */
> -#define AT91_SAMA5D2_CHDR	0x14
> +	u16				CHDR;
>   /* Channel Status Register */
> -#define AT91_SAMA5D2_CHSR	0x18
> +	u16				CHSR;
>   /* Last Converted Data Register */
> -#define AT91_SAMA5D2_LCDR	0x20
> +	u16				LCDR;
>   /* Interrupt Enable Register */
> -#define AT91_SAMA5D2_IER	0x24
> +	u16				IER;
>   /* Interrupt Enable Register - TS X measurement ready */
>   #define AT91_SAMA5D2_IER_XRDY   BIT(20)
>   /* Interrupt Enable Register - TS Y measurement ready */
> @@ -109,22 +110,23 @@
>   #define AT91_SAMA5D2_IER_PEN    BIT(29)
>   /* Interrupt Enable Register - No pen detect */
>   #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
> +
>   /* Interrupt Disable Register */
> -#define AT91_SAMA5D2_IDR	0x28
> +	u16				IDR;
>   /* Interrupt Mask Register */
> -#define AT91_SAMA5D2_IMR	0x2c
> +	u16				IMR;
>   /* Interrupt Status Register */
> -#define AT91_SAMA5D2_ISR	0x30
> +	u16				ISR;
>   /* Interrupt Status Register - Pen touching sense status */
>   #define AT91_SAMA5D2_ISR_PENS   BIT(31)
>   /* Last Channel Trigger Mode Register */
> -#define AT91_SAMA5D2_LCTMR	0x34
> +	u16				LCTMR;
>   /* Last Channel Compare Window Register */
> -#define AT91_SAMA5D2_LCCWR	0x38
> +	u16				LCCWR;
>   /* Overrun Status Register */
> -#define AT91_SAMA5D2_OVER	0x3c
> +	u16				OVER;
>   /* Extended Mode Register */
> -#define AT91_SAMA5D2_EMR	0x40
> +	u16				EMR;
>   /* Extended Mode Register - Oversampling rate */
>   #define AT91_SAMA5D2_EMR_OSR(V)			((V) << 16)
>   #define AT91_SAMA5D2_EMR_OSR_MASK		GENMASK(17, 16)
> @@ -134,22 +136,22 @@
>   
>   /* Extended Mode Register - Averaging on single trigger event */
>   #define AT91_SAMA5D2_EMR_ASTE(V)		((V) << 20)
> +
>   /* Compare Window Register */
> -#define AT91_SAMA5D2_CWR	0x44
> +	u16				CWR;
>   /* Channel Gain Register */
> -#define AT91_SAMA5D2_CGR	0x48
> -
> +	u16				CGR;
>   /* Channel Offset Register */
> -#define AT91_SAMA5D2_COR	0x4c
> +	u16				COR;
>   #define AT91_SAMA5D2_COR_DIFF_OFFSET	16
>   
>   /* Analog Control Register */
> -#define AT91_SAMA5D2_ACR	0x94
> +	u16				ACR;
>   /* Analog Control Register - Pen detect sensitivity mask */
>   #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
>   
>   /* Touchscreen Mode Register */
> -#define AT91_SAMA5D2_TSMR	0xb0
> +	u16				TSMR;
>   /* Touchscreen Mode Register - No touch mode */
>   #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
>   /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
> @@ -178,13 +180,13 @@
>   #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
>   
>   /* Touchscreen X Position Register */
> -#define AT91_SAMA5D2_XPOSR	0xb4
> +	u16				XPOSR;
>   /* Touchscreen Y Position Register */
> -#define AT91_SAMA5D2_YPOSR	0xb8
> +	u16				YPOSR;
>   /* Touchscreen Pressure Register */
> -#define AT91_SAMA5D2_PRESSR	0xbc
> +	u16				PRESSR;
>   /* Trigger Register */
> -#define AT91_SAMA5D2_TRGR	0xc0
> +	u16				TRGR;
>   /* Mask for TRGMOD field of TRGR register */
>   #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
>   /* No trigger, only software trigger can start conversions */
> @@ -203,30 +205,52 @@
>   #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
>   
>   /* Correction Select Register */
> -#define AT91_SAMA5D2_COSR	0xd0
> +	u16				COSR;
>   /* Correction Value Register */
> -#define AT91_SAMA5D2_CVR	0xd4
> +	u16				CVR;
>   /* Channel Error Correction Register */
> -#define AT91_SAMA5D2_CECR	0xd8
> +	u16				CECR;
>   /* Write Protection Mode Register */
> -#define AT91_SAMA5D2_WPMR	0xe4
> +	u16				WPMR;
>   /* Write Protection Status Register */
> -#define AT91_SAMA5D2_WPSR	0xe8
> +	u16				WPSR;
>   /* Version Register */
> -#define AT91_SAMA5D2_VERSION	0xfc
> -
> -#define AT91_SAMA5D2_HW_TRIG_CNT 3
> -#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
> -#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
> -
> -#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> -					 AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
> +	u16				VERSION;
> +};
>   
> -#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> -					 AT91_SAMA5D2_DIFF_CHAN_CNT * 2)

Hi Jonathan,

While we are here, regarding the above line, I cannot tell why did I 
multiply by two the differential channel count. This makes some gaps in 
the number of channels when we put them all in the same table.

I did not change this as it would break the ABI regarding the bindings 
for the touchscreen #adc-cells phandle references.

However, I am thinking if there was a reason for it or it was a slip 
when I initially wrote this.

Do you think there is any reason to change it and tighten the holes in 
the indexes list ?


Eugen

> -#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
> -#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
> -#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
> +static const struct at91_adc_reg_layout sama5d2_layout = {
> +	.CR =			0x00,
> +	.MR =			0x04,
> +	.SEQR1 =		0x08,
> +	.SEQR2 =		0x0c,
> +	.CHER =			0x10,
> +	.CHDR =			0x14,
> +	.CHSR =			0x18,
> +	.LCDR =			0x20,
> +	.IER =			0x24,
> +	.IDR =			0x28,
> +	.IMR =			0x2c,
> +	.ISR =			0x30,
> +	.LCTMR =		0x34,
> +	.LCCWR =		0x38,
> +	.OVER =			0x3c,
> +	.EMR =			0x40,
> +	.CWR =			0x44,
> +	.CGR =			0x48,
> +	.COR =			0x4c,
> +	.ACR =			0x94,
> +	.TSMR =			0xb0,
> +	.XPOSR =		0xb4,
> +	.YPOSR =		0xb8,
> +	.PRESSR =		0xbc,
> +	.TRGR =			0xc0,
> +	.COSR =			0xd0,
> +	.CVR =			0xd4,
> +	.CECR =			0xd8,
> +	.WPMR =			0xe4,
> +	.WPSR =			0xe8,
> +	.VERSION =		0xfc,
> +};
>   
>   #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
>   #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
> @@ -235,18 +259,6 @@
>   
>   #define AT91_SAMA5D2_MAX_POS_BITS			12
>   
> -/*
> - * Maximum number of bytes to hold conversion from all channels
> - * without the timestamp.
> - */
> -#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> -					 AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
> -
> -/* This total must also include the timestamp */
> -#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
> -
> -#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
> -
>   #define AT91_HWFIFO_MAX_SIZE_STR	"128"
>   #define AT91_HWFIFO_MAX_SIZE		128
>   
> @@ -255,12 +267,12 @@
>   #define AT91_OSR_4SAMPLES		4
>   #define AT91_OSR_16SAMPLES		16
>   
> -#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)				\
> +#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)			\
>   	{								\
>   		.type = IIO_VOLTAGE,					\
>   		.channel = num,						\
>   		.address = addr,					\
> -		.scan_index = num,					\
> +		.scan_index = index,					\
>   		.scan_type = {						\
>   			.sign = 'u',					\
>   			.realbits = 14,					\
> @@ -274,14 +286,14 @@
>   		.indexed = 1,						\
>   	}
>   
> -#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)				\
> +#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)			\
>   	{								\
>   		.type = IIO_VOLTAGE,					\
>   		.differential = 1,					\
>   		.channel = num,						\
>   		.channel2 = num2,					\
>   		.address = addr,					\
> -		.scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,	\
> +		.scan_index = index,					\
>   		.scan_type = {						\
>   			.sign = 's',					\
>   			.realbits = 14,					\
> @@ -328,13 +340,48 @@
>   		.datasheet_name = name,					\
>   	}
>   
> -#define at91_adc_readl(st, reg)		readl_relaxed(st->base + reg)
> -#define at91_adc_writel(st, reg, val)	writel_relaxed(val, st->base + reg)
> +#define at91_adc_readl(st, reg)						\
> +	readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
> +#define at91_adc_read_chan(st, reg)					\
> +	readl_relaxed((st)->base + reg)
> +#define at91_adc_writel(st, reg, val)					\
> +	writel_relaxed(val, (st)->base + (st)->soc_info.platform->layout->reg)
> +
> +/**
> + * struct at91_adc_platform - at91-sama5d2 platform information struct
> + * @layout:		pointer to the reg layout struct
> + * @adc_channels:	pointer to an array of channels for registering in
> + *			the iio subsystem
> + * @nr_channels:	number of physical channels available
> + * @touch_chan_x:	index of the touchscreen X channel
> + * @touch_chan_y:	index of the touchscreen Y channel
> + * @touch_chan_p:	index of the touchscreen P channel
> + * @max_channels:	number of total channels
> + * @hw_trig_cnt:	number of possible hardware triggers
> + */
> +struct at91_adc_platform {
> +	const struct at91_adc_reg_layout	*layout;
> +	const struct iio_chan_spec		(*adc_channels)[];
> +	unsigned int				nr_channels;
> +	unsigned int				touch_chan_x;
> +	unsigned int				touch_chan_y;
> +	unsigned int				touch_chan_p;
> +	unsigned int				max_channels;
> +	unsigned int				hw_trig_cnt;
> +};
>   
> +/**
> + * struct at91_adc_soc_info - at91-sama5d2 soc information struct
> + * @startup_time:	device startup time
> + * @min_sample_rate:	minimum sample rate in Hz
> + * @max_sample_rate:	maximum sample rate in Hz
> + * @platform:		pointer to the platform structure
> + */
>   struct at91_adc_soc_info {
>   	unsigned			startup_time;
>   	unsigned			min_sample_rate;
>   	unsigned			max_sample_rate;
> +	const struct at91_adc_platform	*platform;
>   };
>   
>   struct at91_adc_trigger {
> @@ -382,6 +429,15 @@ struct at91_adc_touch {
>   	struct work_struct		workq;
>   };
>   
> +/*
> + * Buffer size requirements:
> + * No channels * bytes_per_channel(2) + timestamp bytes (8)
> + * Divided by 2 because we need half words.
> + * We assume 32 channels for now, has to be increased if needed.
> + * Nobody minds a buffer being too big.
> + */
> +#define AT91_BUFFER_MAX_HWORDS ((32 * 2 + 8) / 2)
> +
>   struct at91_adc_state {
>   	void __iomem			*base;
>   	int				irq;
> @@ -437,29 +493,49 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = {
>   	},
>   };
>   
> -static const struct iio_chan_spec at91_adc_channels[] = {
> -	AT91_SAMA5D2_CHAN_SINGLE(0, 0x50),
> -	AT91_SAMA5D2_CHAN_SINGLE(1, 0x54),
> -	AT91_SAMA5D2_CHAN_SINGLE(2, 0x58),
> -	AT91_SAMA5D2_CHAN_SINGLE(3, 0x5c),
> -	AT91_SAMA5D2_CHAN_SINGLE(4, 0x60),
> -	AT91_SAMA5D2_CHAN_SINGLE(5, 0x64),
> -	AT91_SAMA5D2_CHAN_SINGLE(6, 0x68),
> -	AT91_SAMA5D2_CHAN_SINGLE(7, 0x6c),
> -	AT91_SAMA5D2_CHAN_SINGLE(8, 0x70),
> -	AT91_SAMA5D2_CHAN_SINGLE(9, 0x74),
> -	AT91_SAMA5D2_CHAN_SINGLE(10, 0x78),
> -	AT91_SAMA5D2_CHAN_SINGLE(11, 0x7c),
> -	AT91_SAMA5D2_CHAN_DIFF(0, 1, 0x50),
> -	AT91_SAMA5D2_CHAN_DIFF(2, 3, 0x58),
> -	AT91_SAMA5D2_CHAN_DIFF(4, 5, 0x60),
> -	AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68),
> -	AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70),
> -	AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78),
> -	IIO_CHAN_SOFT_TIMESTAMP(AT91_SAMA5D2_TIMESTAMP_CHAN_IDX),
> -	AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_X_CHAN_IDX, "x", IIO_MOD_X),
> -	AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, "y", IIO_MOD_Y),
> -	AT91_SAMA5D2_CHAN_PRESSURE(AT91_SAMA5D2_TOUCH_P_CHAN_IDX, "pressure"),
> +static const struct iio_chan_spec at91_sama5d2_adc_channels[] = {
> +	AT91_SAMA5D2_CHAN_SINGLE(0, 0, 0x50),
> +	AT91_SAMA5D2_CHAN_SINGLE(1, 1, 0x54),
> +	AT91_SAMA5D2_CHAN_SINGLE(2, 2, 0x58),
> +	AT91_SAMA5D2_CHAN_SINGLE(3, 3, 0x5c),
> +	AT91_SAMA5D2_CHAN_SINGLE(4, 4, 0x60),
> +	AT91_SAMA5D2_CHAN_SINGLE(5, 5, 0x64),
> +	AT91_SAMA5D2_CHAN_SINGLE(6, 6, 0x68),
> +	AT91_SAMA5D2_CHAN_SINGLE(7, 7, 0x6c),
> +	AT91_SAMA5D2_CHAN_SINGLE(8, 8, 0x70),
> +	AT91_SAMA5D2_CHAN_SINGLE(9, 9, 0x74),
> +	AT91_SAMA5D2_CHAN_SINGLE(10, 10, 0x78),
> +	AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x7c),
> +	AT91_SAMA5D2_CHAN_DIFF(12, 0, 1, 0x50),
> +	AT91_SAMA5D2_CHAN_DIFF(13, 2, 3, 0x58),
> +	AT91_SAMA5D2_CHAN_DIFF(14, 4, 5, 0x60),
> +	AT91_SAMA5D2_CHAN_DIFF(15, 6, 7, 0x68),
> +	AT91_SAMA5D2_CHAN_DIFF(16, 8, 9, 0x70),
> +	AT91_SAMA5D2_CHAN_DIFF(17, 10, 11, 0x78),
> +	IIO_CHAN_SOFT_TIMESTAMP(18),
> +	AT91_SAMA5D2_CHAN_TOUCH(19, "x", IIO_MOD_X),
> +	AT91_SAMA5D2_CHAN_TOUCH(20, "y", IIO_MOD_Y),
> +	AT91_SAMA5D2_CHAN_PRESSURE(21, "pressure"),
> +};
> +
> +static const struct at91_adc_platform sama5d2_platform = {
> +	.layout = &sama5d2_layout,
> +	.adc_channels = &at91_sama5d2_adc_channels,
> +#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
> +#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
> +	.nr_channels = AT91_SAMA5D2_SINGLE_CHAN_CNT +
> +		       AT91_SAMA5D2_DIFF_CHAN_CNT,
> +#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX	(AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> +					AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
> +	.touch_chan_x = AT91_SAMA5D2_TOUCH_X_CHAN_IDX,
> +#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX	(AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
> +	.touch_chan_y = AT91_SAMA5D2_TOUCH_Y_CHAN_IDX,
> +#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX	(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
> +	.touch_chan_p = AT91_SAMA5D2_TOUCH_P_CHAN_IDX,
> +#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
> +	.max_channels = ARRAY_SIZE(at91_sama5d2_adc_channels),
> +#define AT91_SAMA5D2_HW_TRIG_CNT	3
> +	.hw_trig_cnt = AT91_SAMA5D2_HW_TRIG_CNT,
>   };
>   
>   static int at91_adc_chan_xlate(struct iio_dev *indio_dev, int chan)
> @@ -493,6 +569,7 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
>   {
>   	u32 mask = 0;
>   	u8 bit;
> +	struct at91_adc_state *st = iio_priv(indio_dev);
>   
>   	for_each_set_bit(bit, indio_dev->active_scan_mask,
>   			 indio_dev->num_channels) {
> @@ -501,13 +578,13 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
>   		mask |= BIT(chan->channel);
>   	}
>   
> -	return mask & GENMASK(11, 0);
> +	return mask & GENMASK(st->soc_info.platform->nr_channels, 0);
>   }
>   
>   static void at91_adc_config_emr(struct at91_adc_state *st)
>   {
>   	/* configure the extended mode register */
> -	unsigned int emr = at91_adc_readl(st, AT91_SAMA5D2_EMR);
> +	unsigned int emr = at91_adc_readl(st, EMR);
>   
>   	/* select oversampling per single trigger event */
>   	emr |= AT91_SAMA5D2_EMR_ASTE(1);
> @@ -531,7 +608,7 @@ static void at91_adc_config_emr(struct at91_adc_state *st)
>   		break;
>   	}
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_EMR, emr);
> +	at91_adc_writel(st, EMR, emr);
>   }
>   
>   static int at91_adc_adjust_val_osr(struct at91_adc_state *st, int *val)
> @@ -584,9 +661,9 @@ static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
>   
>   	if (!state) {
>   		/* disabling touch IRQs and setting mode to no touch enabled */
> -		at91_adc_writel(st, AT91_SAMA5D2_IDR,
> +		at91_adc_writel(st, IDR,
>   				AT91_SAMA5D2_IER_PEN | AT91_SAMA5D2_IER_NOPEN);
> -		at91_adc_writel(st, AT91_SAMA5D2_TSMR, 0);
> +		at91_adc_writel(st, TSMR, 0);
>   		return 0;
>   	}
>   	/*
> @@ -612,19 +689,19 @@ static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
>   	tsmr |= AT91_SAMA5D2_TSMR_PENDET_ENA;
>   	tsmr |= AT91_SAMA5D2_TSMR_TSFREQ(2) & AT91_SAMA5D2_TSMR_TSFREQ_MASK;
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_TSMR, tsmr);
> +	at91_adc_writel(st, TSMR, tsmr);
>   
> -	acr =  at91_adc_readl(st, AT91_SAMA5D2_ACR);
> +	acr =  at91_adc_readl(st, ACR);
>   	acr &= ~AT91_SAMA5D2_ACR_PENDETSENS_MASK;
>   	acr |= 0x02 & AT91_SAMA5D2_ACR_PENDETSENS_MASK;
> -	at91_adc_writel(st, AT91_SAMA5D2_ACR, acr);
> +	at91_adc_writel(st, ACR, acr);
>   
>   	/* Sample Period Time = (TRGPER + 1) / ADCClock */
>   	st->touch_st.sample_period_val =
>   				 round_up((AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US *
>   				 clk_khz / 1000) - 1, 1);
>   	/* enable pen detect IRQ */
> -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
> +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_PEN);
>   
>   	return 0;
>   }
> @@ -640,7 +717,11 @@ static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
>   	 * max = 2^AT91_SAMA5D2_MAX_POS_BITS - 1
>   	 */
>   	/* first half of register is the x or y, second half is the scale */
> -	val = at91_adc_readl(st, reg);
> +	if (reg == st->soc_info.platform->layout->XPOSR)
> +		val = at91_adc_readl(st, XPOSR);
> +	else if (reg == st->soc_info.platform->layout->YPOSR)
> +		val = at91_adc_readl(st, YPOSR);
> +
>   	if (!val)
>   		dev_dbg(&st->indio_dev->dev, "pos is 0\n");
>   
> @@ -658,13 +739,13 @@ static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
>   
>   static u16 at91_adc_touch_x_pos(struct at91_adc_state *st)
>   {
> -	st->touch_st.x_pos = at91_adc_touch_pos(st, AT91_SAMA5D2_XPOSR);
> +	st->touch_st.x_pos = at91_adc_touch_pos(st, st->soc_info.platform->layout->XPOSR);
>   	return st->touch_st.x_pos;
>   }
>   
>   static u16 at91_adc_touch_y_pos(struct at91_adc_state *st)
>   {
> -	return at91_adc_touch_pos(st, AT91_SAMA5D2_YPOSR);
> +	return at91_adc_touch_pos(st, st->soc_info.platform->layout->YPOSR);
>   }
>   
>   static u16 at91_adc_touch_pressure(struct at91_adc_state *st)
> @@ -676,7 +757,7 @@ static u16 at91_adc_touch_pressure(struct at91_adc_state *st)
>   	u32 factor = 1000;
>   
>   	/* calculate the pressure */
> -	val = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
> +	val = at91_adc_readl(st, PRESSR);
>   	z1 = val & AT91_SAMA5D2_XYZ_MASK;
>   	z2 = (val >> 16) & AT91_SAMA5D2_XYZ_MASK;
>   
> @@ -700,9 +781,9 @@ static int at91_adc_read_position(struct at91_adc_state *st, int chan, u16 *val)
>   	*val = 0;
>   	if (!st->touch_st.touching)
>   		return -ENODATA;
> -	if (chan == AT91_SAMA5D2_TOUCH_X_CHAN_IDX)
> +	if (chan == st->soc_info.platform->touch_chan_x)
>   		*val = at91_adc_touch_x_pos(st);
> -	else if (chan == AT91_SAMA5D2_TOUCH_Y_CHAN_IDX)
> +	else if (chan == st->soc_info.platform->touch_chan_y)
>   		*val = at91_adc_touch_y_pos(st);
>   	else
>   		return -ENODATA;
> @@ -715,7 +796,7 @@ static int at91_adc_read_pressure(struct at91_adc_state *st, int chan, u16 *val)
>   	*val = 0;
>   	if (!st->touch_st.touching)
>   		return -ENODATA;
> -	if (chan == AT91_SAMA5D2_TOUCH_P_CHAN_IDX)
> +	if (chan == st->soc_info.platform->touch_chan_y)
>   		*val = at91_adc_touch_pressure(st);
>   	else
>   		return -ENODATA;
> @@ -727,7 +808,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
>   {
>   	struct iio_dev *indio = iio_trigger_get_drvdata(trig);
>   	struct at91_adc_state *st = iio_priv(indio);
> -	u32 status = at91_adc_readl(st, AT91_SAMA5D2_TRGR);
> +	u32 status = at91_adc_readl(st, TRGR);
>   
>   	/* clear TRGMOD */
>   	status &= ~AT91_SAMA5D2_TRGR_TRGMOD_MASK;
> @@ -736,7 +817,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
>   		status |= st->selected_trig->trgmod_value;
>   
>   	/* set/unset hw trigger */
> -	at91_adc_writel(st, AT91_SAMA5D2_TRGR, status);
> +	at91_adc_writel(st, TRGR, status);
>   
>   	return 0;
>   }
> @@ -753,7 +834,7 @@ static void at91_adc_reenable_trigger(struct iio_trigger *trig)
>   	enable_irq(st->irq);
>   
>   	/* Needed to ACK the DRDY interruption */
> -	at91_adc_readl(st, AT91_SAMA5D2_LCDR);
> +	at91_adc_readl(st, LCDR);
>   }
>   
>   static const struct iio_trigger_ops at91_adc_trigger_ops = {
> @@ -848,7 +929,7 @@ static int at91_adc_dma_start(struct iio_dev *indio_dev)
>   	}
>   
>   	/* enable general overrun error signaling */
> -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_GOVRE);
> +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_GOVRE);
>   	/* Issue pending DMA requests */
>   	dma_async_issue_pending(st->dma_st.dma_chan);
>   
> @@ -878,7 +959,7 @@ static bool at91_adc_current_chan_is_touch(struct iio_dev *indio_dev)
>   
>   	return !!bitmap_subset(indio_dev->active_scan_mask,
>   			       &st->touch_st.channels_bitmask,
> -			       AT91_SAMA5D2_MAX_CHAN_IDX + 1);
> +			       st->soc_info.platform->max_channels + 1);
>   }
>   
>   static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
> @@ -915,7 +996,7 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
>   		    chan->type == IIO_PRESSURE)
>   			continue;
>   
> -		cor = at91_adc_readl(st, AT91_SAMA5D2_COR);
> +		cor = at91_adc_readl(st, COR);
>   
>   		if (chan->differential)
>   			cor |= (BIT(chan->channel) | BIT(chan->channel2)) <<
> @@ -924,13 +1005,13 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
>   			cor &= ~(BIT(chan->channel) <<
>   			       AT91_SAMA5D2_COR_DIFF_OFFSET);
>   
> -		at91_adc_writel(st, AT91_SAMA5D2_COR, cor);
> +		at91_adc_writel(st, COR, cor);
>   
> -		at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel));
> +		at91_adc_writel(st, CHER, BIT(chan->channel));
>   	}
>   
>   	if (at91_adc_buffer_check_use_irq(indio_dev, st))
> -		at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_DRDY);
> +		at91_adc_writel(st, IER, AT91_SAMA5D2_IER_DRDY);
>   
>   	return 0;
>   }
> @@ -966,17 +1047,17 @@ static int at91_adc_buffer_postdisable(struct iio_dev *indio_dev)
>   		    chan->type == IIO_PRESSURE)
>   			continue;
>   
> -		at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
> +		at91_adc_writel(st, CHDR, BIT(chan->channel));
>   
>   		if (st->dma_st.dma_chan)
> -			at91_adc_readl(st, chan->address);
> +			at91_adc_read_chan(st, chan->address);
>   	}
>   
>   	if (at91_adc_buffer_check_use_irq(indio_dev, st))
> -		at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_DRDY);
> +		at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_DRDY);
>   
>   	/* read overflow register to clear possible overflow status */
> -	at91_adc_readl(st, AT91_SAMA5D2_OVER);
> +	at91_adc_readl(st, OVER);
>   
>   	/* if we are using DMA we must clear registers and end DMA */
>   	if (st->dma_st.dma_chan)
> @@ -1024,7 +1105,7 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
>   	 * Check if the conversion is ready. If not, wait a little bit, and
>   	 * in case of timeout exit with an error.
>   	 */
> -	while ((at91_adc_readl(st, AT91_SAMA5D2_ISR) & mask) != mask &&
> +	while ((at91_adc_readl(st, ISR) & mask) != mask &&
>   	       timeout) {
>   		usleep_range(50, 100);
>   		timeout--;
> @@ -1052,7 +1133,7 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
>   		 * Thus, emit a warning.
>   		 */
>   		if (chan->type == IIO_VOLTAGE) {
> -			val = at91_adc_readl(st, chan->address);
> +			val = at91_adc_read_chan(st, chan->address);
>   			at91_adc_adjust_val_osr(st, &val);
>   			st->buffer[i] = val;
>   		} else {
> @@ -1073,7 +1154,7 @@ static void at91_adc_trigger_handler_dma(struct iio_dev *indio_dev)
>   	s64 interval;
>   	int sample_index = 0, sample_count, sample_size;
>   
> -	u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
> +	u32 status = at91_adc_readl(st, ISR);
>   	/* if we reached this point, we cannot sample faster */
>   	if (status & AT91_SAMA5D2_IER_GOVRE)
>   		pr_info_ratelimited("%s: conversion overrun detected\n",
> @@ -1125,7 +1206,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
>   	 * actually polling the trigger now.
>   	 */
>   	if (iio_trigger_validate_own_device(indio_dev->trig, indio_dev))
> -		at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START);
> +		at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
>   
>   	if (st->dma_st.dma_chan)
>   		at91_adc_trigger_handler_dma(indio_dev);
> @@ -1172,11 +1253,11 @@ static void at91_adc_setup_samp_freq(struct iio_dev *indio_dev, unsigned freq)
>   	startup = at91_adc_startup_time(st->soc_info.startup_time,
>   					freq / 1000);
>   
> -	mr = at91_adc_readl(st, AT91_SAMA5D2_MR);
> +	mr = at91_adc_readl(st, MR);
>   	mr &= ~(AT91_SAMA5D2_MR_STARTUP_MASK | AT91_SAMA5D2_MR_PRESCAL_MASK);
>   	mr |= AT91_SAMA5D2_MR_STARTUP(startup);
>   	mr |= AT91_SAMA5D2_MR_PRESCAL(prescal);
> -	at91_adc_writel(st, AT91_SAMA5D2_MR, mr);
> +	at91_adc_writel(st, MR, mr);
>   
>   	dev_dbg(&indio_dev->dev, "freq: %u, startup: %u, prescal: %u\n",
>   		freq, startup, prescal);
> @@ -1196,7 +1277,7 @@ static void at91_adc_touch_data_handler(struct iio_dev *indio_dev)
>   	int i = 0;
>   
>   	for_each_set_bit(bit, indio_dev->active_scan_mask,
> -			 AT91_SAMA5D2_MAX_CHAN_IDX + 1) {
> +			 st->soc_info.platform->max_channels + 1) {
>   		struct iio_chan_spec const *chan =
>   					 at91_adc_chan_get(indio_dev, bit);
>   
> @@ -1222,12 +1303,11 @@ static void at91_adc_touch_data_handler(struct iio_dev *indio_dev)
>   
>   static void at91_adc_pen_detect_interrupt(struct at91_adc_state *st)
>   {
> -	at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_PEN);
> -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_NOPEN |
> +	at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_PEN);
> +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_NOPEN |
>   			AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
>   			AT91_SAMA5D2_IER_PRDY);
> -	at91_adc_writel(st, AT91_SAMA5D2_TRGR,
> -			AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC |
> +	at91_adc_writel(st, TRGR, AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC |
>   			AT91_SAMA5D2_TRGR_TRGPER(st->touch_st.sample_period_val));
>   	st->touch_st.touching = true;
>   }
> @@ -1236,16 +1316,15 @@ static void at91_adc_no_pen_detect_interrupt(struct iio_dev *indio_dev)
>   {
>   	struct at91_adc_state *st = iio_priv(indio_dev);
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_TRGR,
> -			AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER);
> -	at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_NOPEN |
> +	at91_adc_writel(st, TRGR, AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER);
> +	at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_NOPEN |
>   			AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
>   			AT91_SAMA5D2_IER_PRDY);
>   	st->touch_st.touching = false;
>   
>   	at91_adc_touch_data_handler(indio_dev);
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
> +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_PEN);
>   }
>   
>   static void at91_adc_workq_handler(struct work_struct *workq)
> @@ -1263,8 +1342,8 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
>   {
>   	struct iio_dev *indio = private;
>   	struct at91_adc_state *st = iio_priv(indio);
> -	u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
> -	u32 imr = at91_adc_readl(st, AT91_SAMA5D2_IMR);
> +	u32 status = at91_adc_readl(st, ISR);
> +	u32 imr = at91_adc_readl(st, IMR);
>   	u32 rdy_mask = AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
>   			AT91_SAMA5D2_IER_PRDY;
>   
> @@ -1285,9 +1364,9 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
>   		 * touching, but the measurements are not ready yet.
>   		 * read and ignore.
>   		 */
> -		status = at91_adc_readl(st, AT91_SAMA5D2_XPOSR);
> -		status = at91_adc_readl(st, AT91_SAMA5D2_YPOSR);
> -		status = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
> +		status = at91_adc_readl(st, XPOSR);
> +		status = at91_adc_readl(st, YPOSR);
> +		status = at91_adc_readl(st, PRESSR);
>   	} else if (iio_buffer_enabled(indio) &&
>   		   (status & AT91_SAMA5D2_IER_DRDY)) {
>   		/* triggered buffer without DMA */
> @@ -1299,7 +1378,7 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
>   		WARN(true, "Unexpected irq occurred\n");
>   	} else if (!iio_buffer_enabled(indio)) {
>   		/* software requested conversion */
> -		st->conversion_value = at91_adc_readl(st, st->chan->address);
> +		st->conversion_value = at91_adc_read_chan(st, st->chan->address);
>   		st->conversion_done = true;
>   		wake_up_interruptible(&st->wq_data_available);
>   	}
> @@ -1360,10 +1439,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
>   		cor = (BIT(chan->channel) | BIT(chan->channel2)) <<
>   		      AT91_SAMA5D2_COR_DIFF_OFFSET;
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_COR, cor);
> -	at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel));
> -	at91_adc_writel(st, AT91_SAMA5D2_IER, BIT(chan->channel));
> -	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START);
> +	at91_adc_writel(st, COR, cor);
> +	at91_adc_writel(st, CHER, BIT(chan->channel));
> +	at91_adc_writel(st, IER, BIT(chan->channel));
> +	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
>   
>   	ret = wait_event_interruptible_timeout(st->wq_data_available,
>   					       st->conversion_done,
> @@ -1379,11 +1458,11 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
>   		st->conversion_done = false;
>   	}
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_IDR, BIT(chan->channel));
> -	at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
> +	at91_adc_writel(st, IDR, BIT(chan->channel));
> +	at91_adc_writel(st, CHDR, BIT(chan->channel));
>   
>   	/* Needed to ACK the DRDY interruption */
> -	at91_adc_readl(st, AT91_SAMA5D2_LCDR);
> +	at91_adc_readl(st, LCDR);
>   
>   	mutex_unlock(&st->lock);
>   
> @@ -1455,14 +1534,15 @@ static void at91_adc_dma_init(struct platform_device *pdev)
>   	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>   	struct at91_adc_state *st = iio_priv(indio_dev);
>   	struct dma_slave_config config = {0};
> +	/* we have 2 bytes for each channel */
> +	unsigned int sample_size = st->soc_info.platform->nr_channels * 2;
>   	/*
>   	 * We make the buffer double the size of the fifo,
>   	 * such that DMA uses one half of the buffer (full fifo size)
>   	 * and the software uses the other half to read/write.
>   	 */
>   	unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
> -					  AT91_BUFFER_MAX_CONVERSION_BYTES * 2,
> -					  PAGE_SIZE);
> +					  sample_size * 2, PAGE_SIZE);
>   
>   	if (st->dma_st.dma_chan)
>   		return;
> @@ -1486,7 +1566,7 @@ static void at91_adc_dma_init(struct platform_device *pdev)
>   	/* Configure DMA channel to read data register */
>   	config.direction = DMA_DEV_TO_MEM;
>   	config.src_addr = (phys_addr_t)(st->dma_st.phys_addr
> -			  + AT91_SAMA5D2_LCDR);
> +			  + st->soc_info.platform->layout->LCDR);
>   	config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
>   	config.src_maxburst = 1;
>   	config.dst_maxburst = 1;
> @@ -1515,9 +1595,10 @@ static void at91_adc_dma_disable(struct platform_device *pdev)
>   {
>   	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>   	struct at91_adc_state *st = iio_priv(indio_dev);
> +	/* we have 2 bytes for each channel */
> +	unsigned int sample_size = st->soc_info.platform->nr_channels * 2;
>   	unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
> -					  AT91_BUFFER_MAX_CONVERSION_BYTES * 2,
> -					  PAGE_SIZE);
> +					  sample_size * 2, PAGE_SIZE);
>   
>   	/* if we are not using DMA, just return */
>   	if (!st->dma_st.dma_chan)
> @@ -1578,14 +1659,14 @@ static int at91_adc_update_scan_mode(struct iio_dev *indio_dev,
>   	struct at91_adc_state *st = iio_priv(indio_dev);
>   
>   	if (bitmap_subset(scan_mask, &st->touch_st.channels_bitmask,
> -			  AT91_SAMA5D2_MAX_CHAN_IDX + 1))
> +			  st->soc_info.platform->max_channels + 1))
>   		return 0;
>   	/*
>   	 * if the new bitmap is a combination of touchscreen and regular
>   	 * channels, then we are not fine
>   	 */
>   	if (bitmap_intersects(&st->touch_st.channels_bitmask, scan_mask,
> -			      AT91_SAMA5D2_MAX_CHAN_IDX + 1))
> +			      st->soc_info.platform->max_channels + 1))
>   		return -EINVAL;
>   	return 0;
>   }
> @@ -1594,13 +1675,13 @@ static void at91_adc_hw_init(struct iio_dev *indio_dev)
>   {
>   	struct at91_adc_state *st = iio_priv(indio_dev);
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
> -	at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff);
> +	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
> +	at91_adc_writel(st, IDR, 0xffffffff);
>   	/*
>   	 * Transfer field must be set to 2 according to the datasheet and
>   	 * allows different analog settings for each channel.
>   	 */
> -	at91_adc_writel(st, AT91_SAMA5D2_MR,
> +	at91_adc_writel(st, MR,
>   			AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH);
>   
>   	at91_adc_setup_samp_freq(indio_dev, st->soc_info.min_sample_rate);
> @@ -1716,21 +1797,23 @@ static int at91_adc_probe(struct platform_device *pdev)
>   	if (!indio_dev)
>   		return -ENOMEM;
>   
> +	st = iio_priv(indio_dev);
> +	st->indio_dev = indio_dev;
> +
> +	st->soc_info.platform = of_device_get_match_data(&pdev->dev);
> +
>   	indio_dev->name = dev_name(&pdev->dev);
>   	indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
>   	indio_dev->info = &at91_adc_info;
> -	indio_dev->channels = at91_adc_channels;
> -	indio_dev->num_channels = ARRAY_SIZE(at91_adc_channels);
> -
> -	st = iio_priv(indio_dev);
> -	st->indio_dev = indio_dev;
> +	indio_dev->channels = *st->soc_info.platform->adc_channels;
> +	indio_dev->num_channels = st->soc_info.platform->max_channels;
>   
>   	bitmap_set(&st->touch_st.channels_bitmask,
> -		   AT91_SAMA5D2_TOUCH_X_CHAN_IDX, 1);
> +		   st->soc_info.platform->touch_chan_x, 1);
>   	bitmap_set(&st->touch_st.channels_bitmask,
> -		   AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, 1);
> +		   st->soc_info.platform->touch_chan_y, 1);
>   	bitmap_set(&st->touch_st.channels_bitmask,
> -		   AT91_SAMA5D2_TOUCH_P_CHAN_IDX, 1);
> +		   st->soc_info.platform->touch_chan_p, 1);
>   
>   	st->oversampling_ratio = AT91_OSR_1SAMPLES;
>   
> @@ -1770,7 +1853,7 @@ static int at91_adc_probe(struct platform_device *pdev)
>   	st->selected_trig = NULL;
>   
>   	/* find the right trigger, or no trigger at all */
> -	for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT + 1; i++)
> +	for (i = 0; i < st->soc_info.platform->hw_trig_cnt + 1; i++)
>   		if (at91_adc_trigger_list[i].edge_type == edge_type) {
>   			st->selected_trig = &at91_adc_trigger_list[i];
>   			break;
> @@ -1855,7 +1938,7 @@ static int at91_adc_probe(struct platform_device *pdev)
>   			 st->selected_trig->name);
>   
>   	dev_info(&pdev->dev, "version: %x\n",
> -		 readl_relaxed(st->base + AT91_SAMA5D2_VERSION));
> +		 readl_relaxed(st->base + st->soc_info.platform->layout->VERSION));
>   
>   	return 0;
>   
> @@ -1898,7 +1981,7 @@ static __maybe_unused int at91_adc_suspend(struct device *dev)
>   	 * and can be used by for other devices.
>   	 * Otherwise, ADC will hog them and we can't go to suspend mode.
>   	 */
> -	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
> +	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
>   
>   	clk_disable_unprepare(st->per_clk);
>   	regulator_disable(st->vref);
> @@ -1958,6 +2041,7 @@ static SIMPLE_DEV_PM_OPS(at91_adc_pm_ops, at91_adc_suspend, at91_adc_resume);
>   static const struct of_device_id at91_adc_dt_match[] = {
>   	{
>   		.compatible = "atmel,sama5d2-adc",
> +		.data = (const void *)&sama5d2_platform,
>   	}, {
>   		/* sentinel */
>   	}
> 

_______________________________________________
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] 44+ messages in thread

* Re: [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform specific data structures
  2021-08-30 12:31     ` Eugen.Hristev
@ 2021-08-30 14:44       ` Jonathan Cameron
  -1 siblings, 0 replies; 44+ messages in thread
From: Jonathan Cameron @ 2021-08-30 14:44 UTC (permalink / raw)
  To: Eugen.Hristev
  Cc: linux-iio, devicetree, Nicolas.Ferre, linux-arm-kernel,
	linux-kernel, robh+dt, Ludovic.Desroches

On Mon, 30 Aug 2021 12:31:46 +0000
<Eugen.Hristev@microchip.com> wrote:

> On 8/24/21 2:54 PM, Eugen Hristev wrote:
> > Convert the driver to platform specific structures. This means:
> > - create a register layout struct that will hold offsets for registers
> > - create a platform struct that will hold platform information (number of
> > channels, indexes for different channels and pointer to layout struct)
> > - convert specific macros that are platform dependent into platform variables
> > 
> > This step is in fact a no-op, but allows the driver to be more flexible
> > and for future enhancement including adding new platforms that are partly
> > compatible with the current driver and differ slightly in register layout
> > or capabilities for example.
> > 
> > Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> > ---
> >   drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
> >   1 file changed, 247 insertions(+), 163 deletions(-)
> > 
> > diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> > index 9d71dcffcf93..8ede18b8d789 100644
> > --- a/drivers/iio/adc/at91-sama5d2_adc.c
> > +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> > @@ -27,8 +27,9 @@
> >   #include <linux/pinctrl/consumer.h>
> >   #include <linux/regulator/consumer.h>
> >   
> > +struct at91_adc_reg_layout {
> >   /* Control Register */
> > -#define AT91_SAMA5D2_CR		0x00
> > +	u16				CR;
> >   /* Software Reset */
> >   #define	AT91_SAMA5D2_CR_SWRST		BIT(0)
> >   /* Start Conversion */
> > @@ -39,7 +40,7 @@
> >   #define	AT91_SAMA5D2_CR_CMPRST		BIT(4)
> >   
> >   /* Mode Register */
> > -#define AT91_SAMA5D2_MR		0x04
> > +	u16				MR;
> >   /* Trigger Selection */
> >   #define	AT91_SAMA5D2_MR_TRGSEL(v)	((v) << 1)
> >   /* ADTRG */
> > @@ -82,19 +83,19 @@
> >   #define	AT91_SAMA5D2_MR_USEQ		BIT(31)
> >   
> >   /* Channel Sequence Register 1 */
> > -#define AT91_SAMA5D2_SEQR1	0x08
> > +	u16				SEQR1;
> >   /* Channel Sequence Register 2 */
> > -#define AT91_SAMA5D2_SEQR2	0x0c
> > +	u16				SEQR2;
> >   /* Channel Enable Register */
> > -#define AT91_SAMA5D2_CHER	0x10
> > +	u16				CHER;
> >   /* Channel Disable Register */
> > -#define AT91_SAMA5D2_CHDR	0x14
> > +	u16				CHDR;
> >   /* Channel Status Register */
> > -#define AT91_SAMA5D2_CHSR	0x18
> > +	u16				CHSR;
> >   /* Last Converted Data Register */
> > -#define AT91_SAMA5D2_LCDR	0x20
> > +	u16				LCDR;
> >   /* Interrupt Enable Register */
> > -#define AT91_SAMA5D2_IER	0x24
> > +	u16				IER;
> >   /* Interrupt Enable Register - TS X measurement ready */
> >   #define AT91_SAMA5D2_IER_XRDY   BIT(20)
> >   /* Interrupt Enable Register - TS Y measurement ready */
> > @@ -109,22 +110,23 @@
> >   #define AT91_SAMA5D2_IER_PEN    BIT(29)
> >   /* Interrupt Enable Register - No pen detect */
> >   #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
> > +
> >   /* Interrupt Disable Register */
> > -#define AT91_SAMA5D2_IDR	0x28
> > +	u16				IDR;
> >   /* Interrupt Mask Register */
> > -#define AT91_SAMA5D2_IMR	0x2c
> > +	u16				IMR;
> >   /* Interrupt Status Register */
> > -#define AT91_SAMA5D2_ISR	0x30
> > +	u16				ISR;
> >   /* Interrupt Status Register - Pen touching sense status */
> >   #define AT91_SAMA5D2_ISR_PENS   BIT(31)
> >   /* Last Channel Trigger Mode Register */
> > -#define AT91_SAMA5D2_LCTMR	0x34
> > +	u16				LCTMR;
> >   /* Last Channel Compare Window Register */
> > -#define AT91_SAMA5D2_LCCWR	0x38
> > +	u16				LCCWR;
> >   /* Overrun Status Register */
> > -#define AT91_SAMA5D2_OVER	0x3c
> > +	u16				OVER;
> >   /* Extended Mode Register */
> > -#define AT91_SAMA5D2_EMR	0x40
> > +	u16				EMR;
> >   /* Extended Mode Register - Oversampling rate */
> >   #define AT91_SAMA5D2_EMR_OSR(V)			((V) << 16)
> >   #define AT91_SAMA5D2_EMR_OSR_MASK		GENMASK(17, 16)
> > @@ -134,22 +136,22 @@
> >   
> >   /* Extended Mode Register - Averaging on single trigger event */
> >   #define AT91_SAMA5D2_EMR_ASTE(V)		((V) << 20)
> > +
> >   /* Compare Window Register */
> > -#define AT91_SAMA5D2_CWR	0x44
> > +	u16				CWR;
> >   /* Channel Gain Register */
> > -#define AT91_SAMA5D2_CGR	0x48
> > -
> > +	u16				CGR;
> >   /* Channel Offset Register */
> > -#define AT91_SAMA5D2_COR	0x4c
> > +	u16				COR;
> >   #define AT91_SAMA5D2_COR_DIFF_OFFSET	16
> >   
> >   /* Analog Control Register */
> > -#define AT91_SAMA5D2_ACR	0x94
> > +	u16				ACR;
> >   /* Analog Control Register - Pen detect sensitivity mask */
> >   #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
> >   
> >   /* Touchscreen Mode Register */
> > -#define AT91_SAMA5D2_TSMR	0xb0
> > +	u16				TSMR;
> >   /* Touchscreen Mode Register - No touch mode */
> >   #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
> >   /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
> > @@ -178,13 +180,13 @@
> >   #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
> >   
> >   /* Touchscreen X Position Register */
> > -#define AT91_SAMA5D2_XPOSR	0xb4
> > +	u16				XPOSR;
> >   /* Touchscreen Y Position Register */
> > -#define AT91_SAMA5D2_YPOSR	0xb8
> > +	u16				YPOSR;
> >   /* Touchscreen Pressure Register */
> > -#define AT91_SAMA5D2_PRESSR	0xbc
> > +	u16				PRESSR;
> >   /* Trigger Register */
> > -#define AT91_SAMA5D2_TRGR	0xc0
> > +	u16				TRGR;
> >   /* Mask for TRGMOD field of TRGR register */
> >   #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
> >   /* No trigger, only software trigger can start conversions */
> > @@ -203,30 +205,52 @@
> >   #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
> >   
> >   /* Correction Select Register */
> > -#define AT91_SAMA5D2_COSR	0xd0
> > +	u16				COSR;
> >   /* Correction Value Register */
> > -#define AT91_SAMA5D2_CVR	0xd4
> > +	u16				CVR;
> >   /* Channel Error Correction Register */
> > -#define AT91_SAMA5D2_CECR	0xd8
> > +	u16				CECR;
> >   /* Write Protection Mode Register */
> > -#define AT91_SAMA5D2_WPMR	0xe4
> > +	u16				WPMR;
> >   /* Write Protection Status Register */
> > -#define AT91_SAMA5D2_WPSR	0xe8
> > +	u16				WPSR;
> >   /* Version Register */
> > -#define AT91_SAMA5D2_VERSION	0xfc
> > -
> > -#define AT91_SAMA5D2_HW_TRIG_CNT 3
> > -#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
> > -#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
> > -
> > -#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> > -					 AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
> > +	u16				VERSION;
> > +};
> >   
> > -#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> > -					 AT91_SAMA5D2_DIFF_CHAN_CNT * 2)  
> 
> Hi Jonathan,
> 
> While we are here, regarding the above line, I cannot tell why did I 
> multiply by two the differential channel count. This makes some gaps in 
> the number of channels when we put them all in the same table.
> 
> I did not change this as it would break the ABI regarding the bindings 
> for the touchscreen #adc-cells phandle references.

Really?  Xlate is based off scan_index, not these values I think...

> 
> However, I am thinking if there was a reason for it or it was a slip 
> when I initially wrote this.

I've no idea :)  I can't immediately see why we'd need the padding.

> 
> Do you think there is any reason to change it and tighten the holes in 
> the indexes list ?

I don't think it matters. As far as I can tell they are used mostly (possibly
entirely) for internal management and not exposed to any of the ABIs etc.

Jonathan

> 
> 
> Eugen
> 
> > -#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
> > -#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
> > -#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
> > +static const struct at91_adc_reg_layout sama5d2_layout = {
> > +	.CR =			0x00,
> > +	.MR =			0x04,
> > +	.SEQR1 =		0x08,
> > +	.SEQR2 =		0x0c,
> > +	.CHER =			0x10,
> > +	.CHDR =			0x14,
> > +	.CHSR =			0x18,
> > +	.LCDR =			0x20,
> > +	.IER =			0x24,
> > +	.IDR =			0x28,
> > +	.IMR =			0x2c,
> > +	.ISR =			0x30,
> > +	.LCTMR =		0x34,
> > +	.LCCWR =		0x38,
> > +	.OVER =			0x3c,
> > +	.EMR =			0x40,
> > +	.CWR =			0x44,
> > +	.CGR =			0x48,
> > +	.COR =			0x4c,
> > +	.ACR =			0x94,
> > +	.TSMR =			0xb0,
> > +	.XPOSR =		0xb4,
> > +	.YPOSR =		0xb8,
> > +	.PRESSR =		0xbc,
> > +	.TRGR =			0xc0,
> > +	.COSR =			0xd0,
> > +	.CVR =			0xd4,
> > +	.CECR =			0xd8,
> > +	.WPMR =			0xe4,
> > +	.WPSR =			0xe8,
> > +	.VERSION =		0xfc,
> > +};
> >   
> >   #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
> >   #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
> > @@ -235,18 +259,6 @@
> >   
> >   #define AT91_SAMA5D2_MAX_POS_BITS			12
> >   
> > -/*
> > - * Maximum number of bytes to hold conversion from all channels
> > - * without the timestamp.
> > - */
> > -#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> > -					 AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
> > -
> > -/* This total must also include the timestamp */
> > -#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
> > -
> > -#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
> > -
> >   #define AT91_HWFIFO_MAX_SIZE_STR	"128"
> >   #define AT91_HWFIFO_MAX_SIZE		128
> >   
> > @@ -255,12 +267,12 @@
> >   #define AT91_OSR_4SAMPLES		4
> >   #define AT91_OSR_16SAMPLES		16
> >   
> > -#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)				\
> > +#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)			\
> >   	{								\
> >   		.type = IIO_VOLTAGE,					\
> >   		.channel = num,						\
> >   		.address = addr,					\
> > -		.scan_index = num,					\
> > +		.scan_index = index,					\
> >   		.scan_type = {						\
> >   			.sign = 'u',					\
> >   			.realbits = 14,					\
> > @@ -274,14 +286,14 @@
> >   		.indexed = 1,						\
> >   	}
> >   
> > -#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)				\
> > +#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)			\
> >   	{								\
> >   		.type = IIO_VOLTAGE,					\
> >   		.differential = 1,					\
> >   		.channel = num,						\
> >   		.channel2 = num2,					\
> >   		.address = addr,					\
> > -		.scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,	\
> > +		.scan_index = index,					\
> >   		.scan_type = {						\
> >   			.sign = 's',					\
> >   			.realbits = 14,					\
> > @@ -328,13 +340,48 @@
> >   		.datasheet_name = name,					\
> >   	}
> >   
> > -#define at91_adc_readl(st, reg)		readl_relaxed(st->base + reg)
> > -#define at91_adc_writel(st, reg, val)	writel_relaxed(val, st->base + reg)
> > +#define at91_adc_readl(st, reg)						\
> > +	readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
> > +#define at91_adc_read_chan(st, reg)					\
> > +	readl_relaxed((st)->base + reg)
> > +#define at91_adc_writel(st, reg, val)					\
> > +	writel_relaxed(val, (st)->base + (st)->soc_info.platform->layout->reg)
> > +
> > +/**
> > + * struct at91_adc_platform - at91-sama5d2 platform information struct
> > + * @layout:		pointer to the reg layout struct
> > + * @adc_channels:	pointer to an array of channels for registering in
> > + *			the iio subsystem
> > + * @nr_channels:	number of physical channels available
> > + * @touch_chan_x:	index of the touchscreen X channel
> > + * @touch_chan_y:	index of the touchscreen Y channel
> > + * @touch_chan_p:	index of the touchscreen P channel
> > + * @max_channels:	number of total channels
> > + * @hw_trig_cnt:	number of possible hardware triggers
> > + */
> > +struct at91_adc_platform {
> > +	const struct at91_adc_reg_layout	*layout;
> > +	const struct iio_chan_spec		(*adc_channels)[];
> > +	unsigned int				nr_channels;
> > +	unsigned int				touch_chan_x;
> > +	unsigned int				touch_chan_y;
> > +	unsigned int				touch_chan_p;
> > +	unsigned int				max_channels;
> > +	unsigned int				hw_trig_cnt;
> > +};
> >   
> > +/**
> > + * struct at91_adc_soc_info - at91-sama5d2 soc information struct
> > + * @startup_time:	device startup time
> > + * @min_sample_rate:	minimum sample rate in Hz
> > + * @max_sample_rate:	maximum sample rate in Hz
> > + * @platform:		pointer to the platform structure
> > + */
> >   struct at91_adc_soc_info {
> >   	unsigned			startup_time;
> >   	unsigned			min_sample_rate;
> >   	unsigned			max_sample_rate;
> > +	const struct at91_adc_platform	*platform;
> >   };
> >   
> >   struct at91_adc_trigger {
> > @@ -382,6 +429,15 @@ struct at91_adc_touch {
> >   	struct work_struct		workq;
> >   };
> >   
> > +/*
> > + * Buffer size requirements:
> > + * No channels * bytes_per_channel(2) + timestamp bytes (8)
> > + * Divided by 2 because we need half words.
> > + * We assume 32 channels for now, has to be increased if needed.
> > + * Nobody minds a buffer being too big.
> > + */
> > +#define AT91_BUFFER_MAX_HWORDS ((32 * 2 + 8) / 2)
> > +
> >   struct at91_adc_state {
> >   	void __iomem			*base;
> >   	int				irq;
> > @@ -437,29 +493,49 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = {
> >   	},
> >   };
> >   
> > -static const struct iio_chan_spec at91_adc_channels[] = {
> > -	AT91_SAMA5D2_CHAN_SINGLE(0, 0x50),
> > -	AT91_SAMA5D2_CHAN_SINGLE(1, 0x54),
> > -	AT91_SAMA5D2_CHAN_SINGLE(2, 0x58),
> > -	AT91_SAMA5D2_CHAN_SINGLE(3, 0x5c),
> > -	AT91_SAMA5D2_CHAN_SINGLE(4, 0x60),
> > -	AT91_SAMA5D2_CHAN_SINGLE(5, 0x64),
> > -	AT91_SAMA5D2_CHAN_SINGLE(6, 0x68),
> > -	AT91_SAMA5D2_CHAN_SINGLE(7, 0x6c),
> > -	AT91_SAMA5D2_CHAN_SINGLE(8, 0x70),
> > -	AT91_SAMA5D2_CHAN_SINGLE(9, 0x74),
> > -	AT91_SAMA5D2_CHAN_SINGLE(10, 0x78),
> > -	AT91_SAMA5D2_CHAN_SINGLE(11, 0x7c),
> > -	AT91_SAMA5D2_CHAN_DIFF(0, 1, 0x50),
> > -	AT91_SAMA5D2_CHAN_DIFF(2, 3, 0x58),
> > -	AT91_SAMA5D2_CHAN_DIFF(4, 5, 0x60),
> > -	AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68),
> > -	AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70),
> > -	AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78),
> > -	IIO_CHAN_SOFT_TIMESTAMP(AT91_SAMA5D2_TIMESTAMP_CHAN_IDX),
> > -	AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_X_CHAN_IDX, "x", IIO_MOD_X),
> > -	AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, "y", IIO_MOD_Y),
> > -	AT91_SAMA5D2_CHAN_PRESSURE(AT91_SAMA5D2_TOUCH_P_CHAN_IDX, "pressure"),
> > +static const struct iio_chan_spec at91_sama5d2_adc_channels[] = {
> > +	AT91_SAMA5D2_CHAN_SINGLE(0, 0, 0x50),
> > +	AT91_SAMA5D2_CHAN_SINGLE(1, 1, 0x54),
> > +	AT91_SAMA5D2_CHAN_SINGLE(2, 2, 0x58),
> > +	AT91_SAMA5D2_CHAN_SINGLE(3, 3, 0x5c),
> > +	AT91_SAMA5D2_CHAN_SINGLE(4, 4, 0x60),
> > +	AT91_SAMA5D2_CHAN_SINGLE(5, 5, 0x64),
> > +	AT91_SAMA5D2_CHAN_SINGLE(6, 6, 0x68),
> > +	AT91_SAMA5D2_CHAN_SINGLE(7, 7, 0x6c),
> > +	AT91_SAMA5D2_CHAN_SINGLE(8, 8, 0x70),
> > +	AT91_SAMA5D2_CHAN_SINGLE(9, 9, 0x74),
> > +	AT91_SAMA5D2_CHAN_SINGLE(10, 10, 0x78),
> > +	AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x7c),
> > +	AT91_SAMA5D2_CHAN_DIFF(12, 0, 1, 0x50),
> > +	AT91_SAMA5D2_CHAN_DIFF(13, 2, 3, 0x58),
> > +	AT91_SAMA5D2_CHAN_DIFF(14, 4, 5, 0x60),
> > +	AT91_SAMA5D2_CHAN_DIFF(15, 6, 7, 0x68),
> > +	AT91_SAMA5D2_CHAN_DIFF(16, 8, 9, 0x70),
> > +	AT91_SAMA5D2_CHAN_DIFF(17, 10, 11, 0x78),
> > +	IIO_CHAN_SOFT_TIMESTAMP(18),
> > +	AT91_SAMA5D2_CHAN_TOUCH(19, "x", IIO_MOD_X),
> > +	AT91_SAMA5D2_CHAN_TOUCH(20, "y", IIO_MOD_Y),
> > +	AT91_SAMA5D2_CHAN_PRESSURE(21, "pressure"),
> > +};
> > +
> > +static const struct at91_adc_platform sama5d2_platform = {
> > +	.layout = &sama5d2_layout,
> > +	.adc_channels = &at91_sama5d2_adc_channels,
> > +#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
> > +#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
> > +	.nr_channels = AT91_SAMA5D2_SINGLE_CHAN_CNT +
> > +		       AT91_SAMA5D2_DIFF_CHAN_CNT,
> > +#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX	(AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> > +					AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
> > +	.touch_chan_x = AT91_SAMA5D2_TOUCH_X_CHAN_IDX,
> > +#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX	(AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
> > +	.touch_chan_y = AT91_SAMA5D2_TOUCH_Y_CHAN_IDX,
> > +#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX	(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
> > +	.touch_chan_p = AT91_SAMA5D2_TOUCH_P_CHAN_IDX,
> > +#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
> > +	.max_channels = ARRAY_SIZE(at91_sama5d2_adc_channels),
> > +#define AT91_SAMA5D2_HW_TRIG_CNT	3
> > +	.hw_trig_cnt = AT91_SAMA5D2_HW_TRIG_CNT,
> >   };
> >   
> >   static int at91_adc_chan_xlate(struct iio_dev *indio_dev, int chan)
> > @@ -493,6 +569,7 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
> >   {
> >   	u32 mask = 0;
> >   	u8 bit;
> > +	struct at91_adc_state *st = iio_priv(indio_dev);
> >   
> >   	for_each_set_bit(bit, indio_dev->active_scan_mask,
> >   			 indio_dev->num_channels) {
> > @@ -501,13 +578,13 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
> >   		mask |= BIT(chan->channel);
> >   	}
> >   
> > -	return mask & GENMASK(11, 0);
> > +	return mask & GENMASK(st->soc_info.platform->nr_channels, 0);
> >   }
> >   
> >   static void at91_adc_config_emr(struct at91_adc_state *st)
> >   {
> >   	/* configure the extended mode register */
> > -	unsigned int emr = at91_adc_readl(st, AT91_SAMA5D2_EMR);
> > +	unsigned int emr = at91_adc_readl(st, EMR);
> >   
> >   	/* select oversampling per single trigger event */
> >   	emr |= AT91_SAMA5D2_EMR_ASTE(1);
> > @@ -531,7 +608,7 @@ static void at91_adc_config_emr(struct at91_adc_state *st)
> >   		break;
> >   	}
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_EMR, emr);
> > +	at91_adc_writel(st, EMR, emr);
> >   }
> >   
> >   static int at91_adc_adjust_val_osr(struct at91_adc_state *st, int *val)
> > @@ -584,9 +661,9 @@ static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
> >   
> >   	if (!state) {
> >   		/* disabling touch IRQs and setting mode to no touch enabled */
> > -		at91_adc_writel(st, AT91_SAMA5D2_IDR,
> > +		at91_adc_writel(st, IDR,
> >   				AT91_SAMA5D2_IER_PEN | AT91_SAMA5D2_IER_NOPEN);
> > -		at91_adc_writel(st, AT91_SAMA5D2_TSMR, 0);
> > +		at91_adc_writel(st, TSMR, 0);
> >   		return 0;
> >   	}
> >   	/*
> > @@ -612,19 +689,19 @@ static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
> >   	tsmr |= AT91_SAMA5D2_TSMR_PENDET_ENA;
> >   	tsmr |= AT91_SAMA5D2_TSMR_TSFREQ(2) & AT91_SAMA5D2_TSMR_TSFREQ_MASK;
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_TSMR, tsmr);
> > +	at91_adc_writel(st, TSMR, tsmr);
> >   
> > -	acr =  at91_adc_readl(st, AT91_SAMA5D2_ACR);
> > +	acr =  at91_adc_readl(st, ACR);
> >   	acr &= ~AT91_SAMA5D2_ACR_PENDETSENS_MASK;
> >   	acr |= 0x02 & AT91_SAMA5D2_ACR_PENDETSENS_MASK;
> > -	at91_adc_writel(st, AT91_SAMA5D2_ACR, acr);
> > +	at91_adc_writel(st, ACR, acr);
> >   
> >   	/* Sample Period Time = (TRGPER + 1) / ADCClock */
> >   	st->touch_st.sample_period_val =
> >   				 round_up((AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US *
> >   				 clk_khz / 1000) - 1, 1);
> >   	/* enable pen detect IRQ */
> > -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
> > +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_PEN);
> >   
> >   	return 0;
> >   }
> > @@ -640,7 +717,11 @@ static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
> >   	 * max = 2^AT91_SAMA5D2_MAX_POS_BITS - 1
> >   	 */
> >   	/* first half of register is the x or y, second half is the scale */
> > -	val = at91_adc_readl(st, reg);
> > +	if (reg == st->soc_info.platform->layout->XPOSR)
> > +		val = at91_adc_readl(st, XPOSR);
> > +	else if (reg == st->soc_info.platform->layout->YPOSR)
> > +		val = at91_adc_readl(st, YPOSR);
> > +
> >   	if (!val)
> >   		dev_dbg(&st->indio_dev->dev, "pos is 0\n");
> >   
> > @@ -658,13 +739,13 @@ static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
> >   
> >   static u16 at91_adc_touch_x_pos(struct at91_adc_state *st)
> >   {
> > -	st->touch_st.x_pos = at91_adc_touch_pos(st, AT91_SAMA5D2_XPOSR);
> > +	st->touch_st.x_pos = at91_adc_touch_pos(st, st->soc_info.platform->layout->XPOSR);
> >   	return st->touch_st.x_pos;
> >   }
> >   
> >   static u16 at91_adc_touch_y_pos(struct at91_adc_state *st)
> >   {
> > -	return at91_adc_touch_pos(st, AT91_SAMA5D2_YPOSR);
> > +	return at91_adc_touch_pos(st, st->soc_info.platform->layout->YPOSR);
> >   }
> >   
> >   static u16 at91_adc_touch_pressure(struct at91_adc_state *st)
> > @@ -676,7 +757,7 @@ static u16 at91_adc_touch_pressure(struct at91_adc_state *st)
> >   	u32 factor = 1000;
> >   
> >   	/* calculate the pressure */
> > -	val = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
> > +	val = at91_adc_readl(st, PRESSR);
> >   	z1 = val & AT91_SAMA5D2_XYZ_MASK;
> >   	z2 = (val >> 16) & AT91_SAMA5D2_XYZ_MASK;
> >   
> > @@ -700,9 +781,9 @@ static int at91_adc_read_position(struct at91_adc_state *st, int chan, u16 *val)
> >   	*val = 0;
> >   	if (!st->touch_st.touching)
> >   		return -ENODATA;
> > -	if (chan == AT91_SAMA5D2_TOUCH_X_CHAN_IDX)
> > +	if (chan == st->soc_info.platform->touch_chan_x)
> >   		*val = at91_adc_touch_x_pos(st);
> > -	else if (chan == AT91_SAMA5D2_TOUCH_Y_CHAN_IDX)
> > +	else if (chan == st->soc_info.platform->touch_chan_y)
> >   		*val = at91_adc_touch_y_pos(st);
> >   	else
> >   		return -ENODATA;
> > @@ -715,7 +796,7 @@ static int at91_adc_read_pressure(struct at91_adc_state *st, int chan, u16 *val)
> >   	*val = 0;
> >   	if (!st->touch_st.touching)
> >   		return -ENODATA;
> > -	if (chan == AT91_SAMA5D2_TOUCH_P_CHAN_IDX)
> > +	if (chan == st->soc_info.platform->touch_chan_y)
> >   		*val = at91_adc_touch_pressure(st);
> >   	else
> >   		return -ENODATA;
> > @@ -727,7 +808,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
> >   {
> >   	struct iio_dev *indio = iio_trigger_get_drvdata(trig);
> >   	struct at91_adc_state *st = iio_priv(indio);
> > -	u32 status = at91_adc_readl(st, AT91_SAMA5D2_TRGR);
> > +	u32 status = at91_adc_readl(st, TRGR);
> >   
> >   	/* clear TRGMOD */
> >   	status &= ~AT91_SAMA5D2_TRGR_TRGMOD_MASK;
> > @@ -736,7 +817,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
> >   		status |= st->selected_trig->trgmod_value;
> >   
> >   	/* set/unset hw trigger */
> > -	at91_adc_writel(st, AT91_SAMA5D2_TRGR, status);
> > +	at91_adc_writel(st, TRGR, status);
> >   
> >   	return 0;
> >   }
> > @@ -753,7 +834,7 @@ static void at91_adc_reenable_trigger(struct iio_trigger *trig)
> >   	enable_irq(st->irq);
> >   
> >   	/* Needed to ACK the DRDY interruption */
> > -	at91_adc_readl(st, AT91_SAMA5D2_LCDR);
> > +	at91_adc_readl(st, LCDR);
> >   }
> >   
> >   static const struct iio_trigger_ops at91_adc_trigger_ops = {
> > @@ -848,7 +929,7 @@ static int at91_adc_dma_start(struct iio_dev *indio_dev)
> >   	}
> >   
> >   	/* enable general overrun error signaling */
> > -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_GOVRE);
> > +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_GOVRE);
> >   	/* Issue pending DMA requests */
> >   	dma_async_issue_pending(st->dma_st.dma_chan);
> >   
> > @@ -878,7 +959,7 @@ static bool at91_adc_current_chan_is_touch(struct iio_dev *indio_dev)
> >   
> >   	return !!bitmap_subset(indio_dev->active_scan_mask,
> >   			       &st->touch_st.channels_bitmask,
> > -			       AT91_SAMA5D2_MAX_CHAN_IDX + 1);
> > +			       st->soc_info.platform->max_channels + 1);
> >   }
> >   
> >   static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
> > @@ -915,7 +996,7 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
> >   		    chan->type == IIO_PRESSURE)
> >   			continue;
> >   
> > -		cor = at91_adc_readl(st, AT91_SAMA5D2_COR);
> > +		cor = at91_adc_readl(st, COR);
> >   
> >   		if (chan->differential)
> >   			cor |= (BIT(chan->channel) | BIT(chan->channel2)) <<
> > @@ -924,13 +1005,13 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
> >   			cor &= ~(BIT(chan->channel) <<
> >   			       AT91_SAMA5D2_COR_DIFF_OFFSET);
> >   
> > -		at91_adc_writel(st, AT91_SAMA5D2_COR, cor);
> > +		at91_adc_writel(st, COR, cor);
> >   
> > -		at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel));
> > +		at91_adc_writel(st, CHER, BIT(chan->channel));
> >   	}
> >   
> >   	if (at91_adc_buffer_check_use_irq(indio_dev, st))
> > -		at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_DRDY);
> > +		at91_adc_writel(st, IER, AT91_SAMA5D2_IER_DRDY);
> >   
> >   	return 0;
> >   }
> > @@ -966,17 +1047,17 @@ static int at91_adc_buffer_postdisable(struct iio_dev *indio_dev)
> >   		    chan->type == IIO_PRESSURE)
> >   			continue;
> >   
> > -		at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
> > +		at91_adc_writel(st, CHDR, BIT(chan->channel));
> >   
> >   		if (st->dma_st.dma_chan)
> > -			at91_adc_readl(st, chan->address);
> > +			at91_adc_read_chan(st, chan->address);
> >   	}
> >   
> >   	if (at91_adc_buffer_check_use_irq(indio_dev, st))
> > -		at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_DRDY);
> > +		at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_DRDY);
> >   
> >   	/* read overflow register to clear possible overflow status */
> > -	at91_adc_readl(st, AT91_SAMA5D2_OVER);
> > +	at91_adc_readl(st, OVER);
> >   
> >   	/* if we are using DMA we must clear registers and end DMA */
> >   	if (st->dma_st.dma_chan)
> > @@ -1024,7 +1105,7 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
> >   	 * Check if the conversion is ready. If not, wait a little bit, and
> >   	 * in case of timeout exit with an error.
> >   	 */
> > -	while ((at91_adc_readl(st, AT91_SAMA5D2_ISR) & mask) != mask &&
> > +	while ((at91_adc_readl(st, ISR) & mask) != mask &&
> >   	       timeout) {
> >   		usleep_range(50, 100);
> >   		timeout--;
> > @@ -1052,7 +1133,7 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
> >   		 * Thus, emit a warning.
> >   		 */
> >   		if (chan->type == IIO_VOLTAGE) {
> > -			val = at91_adc_readl(st, chan->address);
> > +			val = at91_adc_read_chan(st, chan->address);
> >   			at91_adc_adjust_val_osr(st, &val);
> >   			st->buffer[i] = val;
> >   		} else {
> > @@ -1073,7 +1154,7 @@ static void at91_adc_trigger_handler_dma(struct iio_dev *indio_dev)
> >   	s64 interval;
> >   	int sample_index = 0, sample_count, sample_size;
> >   
> > -	u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
> > +	u32 status = at91_adc_readl(st, ISR);
> >   	/* if we reached this point, we cannot sample faster */
> >   	if (status & AT91_SAMA5D2_IER_GOVRE)
> >   		pr_info_ratelimited("%s: conversion overrun detected\n",
> > @@ -1125,7 +1206,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
> >   	 * actually polling the trigger now.
> >   	 */
> >   	if (iio_trigger_validate_own_device(indio_dev->trig, indio_dev))
> > -		at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START);
> > +		at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
> >   
> >   	if (st->dma_st.dma_chan)
> >   		at91_adc_trigger_handler_dma(indio_dev);
> > @@ -1172,11 +1253,11 @@ static void at91_adc_setup_samp_freq(struct iio_dev *indio_dev, unsigned freq)
> >   	startup = at91_adc_startup_time(st->soc_info.startup_time,
> >   					freq / 1000);
> >   
> > -	mr = at91_adc_readl(st, AT91_SAMA5D2_MR);
> > +	mr = at91_adc_readl(st, MR);
> >   	mr &= ~(AT91_SAMA5D2_MR_STARTUP_MASK | AT91_SAMA5D2_MR_PRESCAL_MASK);
> >   	mr |= AT91_SAMA5D2_MR_STARTUP(startup);
> >   	mr |= AT91_SAMA5D2_MR_PRESCAL(prescal);
> > -	at91_adc_writel(st, AT91_SAMA5D2_MR, mr);
> > +	at91_adc_writel(st, MR, mr);
> >   
> >   	dev_dbg(&indio_dev->dev, "freq: %u, startup: %u, prescal: %u\n",
> >   		freq, startup, prescal);
> > @@ -1196,7 +1277,7 @@ static void at91_adc_touch_data_handler(struct iio_dev *indio_dev)
> >   	int i = 0;
> >   
> >   	for_each_set_bit(bit, indio_dev->active_scan_mask,
> > -			 AT91_SAMA5D2_MAX_CHAN_IDX + 1) {
> > +			 st->soc_info.platform->max_channels + 1) {
> >   		struct iio_chan_spec const *chan =
> >   					 at91_adc_chan_get(indio_dev, bit);
> >   
> > @@ -1222,12 +1303,11 @@ static void at91_adc_touch_data_handler(struct iio_dev *indio_dev)
> >   
> >   static void at91_adc_pen_detect_interrupt(struct at91_adc_state *st)
> >   {
> > -	at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_PEN);
> > -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_NOPEN |
> > +	at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_PEN);
> > +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_NOPEN |
> >   			AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
> >   			AT91_SAMA5D2_IER_PRDY);
> > -	at91_adc_writel(st, AT91_SAMA5D2_TRGR,
> > -			AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC |
> > +	at91_adc_writel(st, TRGR, AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC |
> >   			AT91_SAMA5D2_TRGR_TRGPER(st->touch_st.sample_period_val));
> >   	st->touch_st.touching = true;
> >   }
> > @@ -1236,16 +1316,15 @@ static void at91_adc_no_pen_detect_interrupt(struct iio_dev *indio_dev)
> >   {
> >   	struct at91_adc_state *st = iio_priv(indio_dev);
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_TRGR,
> > -			AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER);
> > -	at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_NOPEN |
> > +	at91_adc_writel(st, TRGR, AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER);
> > +	at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_NOPEN |
> >   			AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
> >   			AT91_SAMA5D2_IER_PRDY);
> >   	st->touch_st.touching = false;
> >   
> >   	at91_adc_touch_data_handler(indio_dev);
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
> > +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_PEN);
> >   }
> >   
> >   static void at91_adc_workq_handler(struct work_struct *workq)
> > @@ -1263,8 +1342,8 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
> >   {
> >   	struct iio_dev *indio = private;
> >   	struct at91_adc_state *st = iio_priv(indio);
> > -	u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
> > -	u32 imr = at91_adc_readl(st, AT91_SAMA5D2_IMR);
> > +	u32 status = at91_adc_readl(st, ISR);
> > +	u32 imr = at91_adc_readl(st, IMR);
> >   	u32 rdy_mask = AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
> >   			AT91_SAMA5D2_IER_PRDY;
> >   
> > @@ -1285,9 +1364,9 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
> >   		 * touching, but the measurements are not ready yet.
> >   		 * read and ignore.
> >   		 */
> > -		status = at91_adc_readl(st, AT91_SAMA5D2_XPOSR);
> > -		status = at91_adc_readl(st, AT91_SAMA5D2_YPOSR);
> > -		status = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
> > +		status = at91_adc_readl(st, XPOSR);
> > +		status = at91_adc_readl(st, YPOSR);
> > +		status = at91_adc_readl(st, PRESSR);
> >   	} else if (iio_buffer_enabled(indio) &&
> >   		   (status & AT91_SAMA5D2_IER_DRDY)) {
> >   		/* triggered buffer without DMA */
> > @@ -1299,7 +1378,7 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
> >   		WARN(true, "Unexpected irq occurred\n");
> >   	} else if (!iio_buffer_enabled(indio)) {
> >   		/* software requested conversion */
> > -		st->conversion_value = at91_adc_readl(st, st->chan->address);
> > +		st->conversion_value = at91_adc_read_chan(st, st->chan->address);
> >   		st->conversion_done = true;
> >   		wake_up_interruptible(&st->wq_data_available);
> >   	}
> > @@ -1360,10 +1439,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
> >   		cor = (BIT(chan->channel) | BIT(chan->channel2)) <<
> >   		      AT91_SAMA5D2_COR_DIFF_OFFSET;
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_COR, cor);
> > -	at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel));
> > -	at91_adc_writel(st, AT91_SAMA5D2_IER, BIT(chan->channel));
> > -	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START);
> > +	at91_adc_writel(st, COR, cor);
> > +	at91_adc_writel(st, CHER, BIT(chan->channel));
> > +	at91_adc_writel(st, IER, BIT(chan->channel));
> > +	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
> >   
> >   	ret = wait_event_interruptible_timeout(st->wq_data_available,
> >   					       st->conversion_done,
> > @@ -1379,11 +1458,11 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
> >   		st->conversion_done = false;
> >   	}
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_IDR, BIT(chan->channel));
> > -	at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
> > +	at91_adc_writel(st, IDR, BIT(chan->channel));
> > +	at91_adc_writel(st, CHDR, BIT(chan->channel));
> >   
> >   	/* Needed to ACK the DRDY interruption */
> > -	at91_adc_readl(st, AT91_SAMA5D2_LCDR);
> > +	at91_adc_readl(st, LCDR);
> >   
> >   	mutex_unlock(&st->lock);
> >   
> > @@ -1455,14 +1534,15 @@ static void at91_adc_dma_init(struct platform_device *pdev)
> >   	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> >   	struct at91_adc_state *st = iio_priv(indio_dev);
> >   	struct dma_slave_config config = {0};
> > +	/* we have 2 bytes for each channel */
> > +	unsigned int sample_size = st->soc_info.platform->nr_channels * 2;
> >   	/*
> >   	 * We make the buffer double the size of the fifo,
> >   	 * such that DMA uses one half of the buffer (full fifo size)
> >   	 * and the software uses the other half to read/write.
> >   	 */
> >   	unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
> > -					  AT91_BUFFER_MAX_CONVERSION_BYTES * 2,
> > -					  PAGE_SIZE);
> > +					  sample_size * 2, PAGE_SIZE);
> >   
> >   	if (st->dma_st.dma_chan)
> >   		return;
> > @@ -1486,7 +1566,7 @@ static void at91_adc_dma_init(struct platform_device *pdev)
> >   	/* Configure DMA channel to read data register */
> >   	config.direction = DMA_DEV_TO_MEM;
> >   	config.src_addr = (phys_addr_t)(st->dma_st.phys_addr
> > -			  + AT91_SAMA5D2_LCDR);
> > +			  + st->soc_info.platform->layout->LCDR);
> >   	config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
> >   	config.src_maxburst = 1;
> >   	config.dst_maxburst = 1;
> > @@ -1515,9 +1595,10 @@ static void at91_adc_dma_disable(struct platform_device *pdev)
> >   {
> >   	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> >   	struct at91_adc_state *st = iio_priv(indio_dev);
> > +	/* we have 2 bytes for each channel */
> > +	unsigned int sample_size = st->soc_info.platform->nr_channels * 2;
> >   	unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
> > -					  AT91_BUFFER_MAX_CONVERSION_BYTES * 2,
> > -					  PAGE_SIZE);
> > +					  sample_size * 2, PAGE_SIZE);
> >   
> >   	/* if we are not using DMA, just return */
> >   	if (!st->dma_st.dma_chan)
> > @@ -1578,14 +1659,14 @@ static int at91_adc_update_scan_mode(struct iio_dev *indio_dev,
> >   	struct at91_adc_state *st = iio_priv(indio_dev);
> >   
> >   	if (bitmap_subset(scan_mask, &st->touch_st.channels_bitmask,
> > -			  AT91_SAMA5D2_MAX_CHAN_IDX + 1))
> > +			  st->soc_info.platform->max_channels + 1))
> >   		return 0;
> >   	/*
> >   	 * if the new bitmap is a combination of touchscreen and regular
> >   	 * channels, then we are not fine
> >   	 */
> >   	if (bitmap_intersects(&st->touch_st.channels_bitmask, scan_mask,
> > -			      AT91_SAMA5D2_MAX_CHAN_IDX + 1))
> > +			      st->soc_info.platform->max_channels + 1))
> >   		return -EINVAL;
> >   	return 0;
> >   }
> > @@ -1594,13 +1675,13 @@ static void at91_adc_hw_init(struct iio_dev *indio_dev)
> >   {
> >   	struct at91_adc_state *st = iio_priv(indio_dev);
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
> > -	at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff);
> > +	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
> > +	at91_adc_writel(st, IDR, 0xffffffff);
> >   	/*
> >   	 * Transfer field must be set to 2 according to the datasheet and
> >   	 * allows different analog settings for each channel.
> >   	 */
> > -	at91_adc_writel(st, AT91_SAMA5D2_MR,
> > +	at91_adc_writel(st, MR,
> >   			AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH);
> >   
> >   	at91_adc_setup_samp_freq(indio_dev, st->soc_info.min_sample_rate);
> > @@ -1716,21 +1797,23 @@ static int at91_adc_probe(struct platform_device *pdev)
> >   	if (!indio_dev)
> >   		return -ENOMEM;
> >   
> > +	st = iio_priv(indio_dev);
> > +	st->indio_dev = indio_dev;
> > +
> > +	st->soc_info.platform = of_device_get_match_data(&pdev->dev);
> > +
> >   	indio_dev->name = dev_name(&pdev->dev);
> >   	indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
> >   	indio_dev->info = &at91_adc_info;
> > -	indio_dev->channels = at91_adc_channels;
> > -	indio_dev->num_channels = ARRAY_SIZE(at91_adc_channels);
> > -
> > -	st = iio_priv(indio_dev);
> > -	st->indio_dev = indio_dev;
> > +	indio_dev->channels = *st->soc_info.platform->adc_channels;
> > +	indio_dev->num_channels = st->soc_info.platform->max_channels;
> >   
> >   	bitmap_set(&st->touch_st.channels_bitmask,
> > -		   AT91_SAMA5D2_TOUCH_X_CHAN_IDX, 1);
> > +		   st->soc_info.platform->touch_chan_x, 1);
> >   	bitmap_set(&st->touch_st.channels_bitmask,
> > -		   AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, 1);
> > +		   st->soc_info.platform->touch_chan_y, 1);
> >   	bitmap_set(&st->touch_st.channels_bitmask,
> > -		   AT91_SAMA5D2_TOUCH_P_CHAN_IDX, 1);
> > +		   st->soc_info.platform->touch_chan_p, 1);
> >   
> >   	st->oversampling_ratio = AT91_OSR_1SAMPLES;
> >   
> > @@ -1770,7 +1853,7 @@ static int at91_adc_probe(struct platform_device *pdev)
> >   	st->selected_trig = NULL;
> >   
> >   	/* find the right trigger, or no trigger at all */
> > -	for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT + 1; i++)
> > +	for (i = 0; i < st->soc_info.platform->hw_trig_cnt + 1; i++)
> >   		if (at91_adc_trigger_list[i].edge_type == edge_type) {
> >   			st->selected_trig = &at91_adc_trigger_list[i];
> >   			break;
> > @@ -1855,7 +1938,7 @@ static int at91_adc_probe(struct platform_device *pdev)
> >   			 st->selected_trig->name);
> >   
> >   	dev_info(&pdev->dev, "version: %x\n",
> > -		 readl_relaxed(st->base + AT91_SAMA5D2_VERSION));
> > +		 readl_relaxed(st->base + st->soc_info.platform->layout->VERSION));
> >   
> >   	return 0;
> >   
> > @@ -1898,7 +1981,7 @@ static __maybe_unused int at91_adc_suspend(struct device *dev)
> >   	 * and can be used by for other devices.
> >   	 * Otherwise, ADC will hog them and we can't go to suspend mode.
> >   	 */
> > -	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
> > +	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
> >   
> >   	clk_disable_unprepare(st->per_clk);
> >   	regulator_disable(st->vref);
> > @@ -1958,6 +2041,7 @@ static SIMPLE_DEV_PM_OPS(at91_adc_pm_ops, at91_adc_suspend, at91_adc_resume);
> >   static const struct of_device_id at91_adc_dt_match[] = {
> >   	{
> >   		.compatible = "atmel,sama5d2-adc",
> > +		.data = (const void *)&sama5d2_platform,
> >   	}, {
> >   		/* sentinel */
> >   	}
> >   
> 


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

* Re: [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform specific data structures
@ 2021-08-30 14:44       ` Jonathan Cameron
  0 siblings, 0 replies; 44+ messages in thread
From: Jonathan Cameron @ 2021-08-30 14:44 UTC (permalink / raw)
  To: Eugen.Hristev
  Cc: devicetree, linux-iio, linux-kernel, Ludovic.Desroches, robh+dt,
	linux-arm-kernel

On Mon, 30 Aug 2021 12:31:46 +0000
<Eugen.Hristev@microchip.com> wrote:

> On 8/24/21 2:54 PM, Eugen Hristev wrote:
> > Convert the driver to platform specific structures. This means:
> > - create a register layout struct that will hold offsets for registers
> > - create a platform struct that will hold platform information (number of
> > channels, indexes for different channels and pointer to layout struct)
> > - convert specific macros that are platform dependent into platform variables
> > 
> > This step is in fact a no-op, but allows the driver to be more flexible
> > and for future enhancement including adding new platforms that are partly
> > compatible with the current driver and differ slightly in register layout
> > or capabilities for example.
> > 
> > Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> > ---
> >   drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
> >   1 file changed, 247 insertions(+), 163 deletions(-)
> > 
> > diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> > index 9d71dcffcf93..8ede18b8d789 100644
> > --- a/drivers/iio/adc/at91-sama5d2_adc.c
> > +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> > @@ -27,8 +27,9 @@
> >   #include <linux/pinctrl/consumer.h>
> >   #include <linux/regulator/consumer.h>
> >   
> > +struct at91_adc_reg_layout {
> >   /* Control Register */
> > -#define AT91_SAMA5D2_CR		0x00
> > +	u16				CR;
> >   /* Software Reset */
> >   #define	AT91_SAMA5D2_CR_SWRST		BIT(0)
> >   /* Start Conversion */
> > @@ -39,7 +40,7 @@
> >   #define	AT91_SAMA5D2_CR_CMPRST		BIT(4)
> >   
> >   /* Mode Register */
> > -#define AT91_SAMA5D2_MR		0x04
> > +	u16				MR;
> >   /* Trigger Selection */
> >   #define	AT91_SAMA5D2_MR_TRGSEL(v)	((v) << 1)
> >   /* ADTRG */
> > @@ -82,19 +83,19 @@
> >   #define	AT91_SAMA5D2_MR_USEQ		BIT(31)
> >   
> >   /* Channel Sequence Register 1 */
> > -#define AT91_SAMA5D2_SEQR1	0x08
> > +	u16				SEQR1;
> >   /* Channel Sequence Register 2 */
> > -#define AT91_SAMA5D2_SEQR2	0x0c
> > +	u16				SEQR2;
> >   /* Channel Enable Register */
> > -#define AT91_SAMA5D2_CHER	0x10
> > +	u16				CHER;
> >   /* Channel Disable Register */
> > -#define AT91_SAMA5D2_CHDR	0x14
> > +	u16				CHDR;
> >   /* Channel Status Register */
> > -#define AT91_SAMA5D2_CHSR	0x18
> > +	u16				CHSR;
> >   /* Last Converted Data Register */
> > -#define AT91_SAMA5D2_LCDR	0x20
> > +	u16				LCDR;
> >   /* Interrupt Enable Register */
> > -#define AT91_SAMA5D2_IER	0x24
> > +	u16				IER;
> >   /* Interrupt Enable Register - TS X measurement ready */
> >   #define AT91_SAMA5D2_IER_XRDY   BIT(20)
> >   /* Interrupt Enable Register - TS Y measurement ready */
> > @@ -109,22 +110,23 @@
> >   #define AT91_SAMA5D2_IER_PEN    BIT(29)
> >   /* Interrupt Enable Register - No pen detect */
> >   #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
> > +
> >   /* Interrupt Disable Register */
> > -#define AT91_SAMA5D2_IDR	0x28
> > +	u16				IDR;
> >   /* Interrupt Mask Register */
> > -#define AT91_SAMA5D2_IMR	0x2c
> > +	u16				IMR;
> >   /* Interrupt Status Register */
> > -#define AT91_SAMA5D2_ISR	0x30
> > +	u16				ISR;
> >   /* Interrupt Status Register - Pen touching sense status */
> >   #define AT91_SAMA5D2_ISR_PENS   BIT(31)
> >   /* Last Channel Trigger Mode Register */
> > -#define AT91_SAMA5D2_LCTMR	0x34
> > +	u16				LCTMR;
> >   /* Last Channel Compare Window Register */
> > -#define AT91_SAMA5D2_LCCWR	0x38
> > +	u16				LCCWR;
> >   /* Overrun Status Register */
> > -#define AT91_SAMA5D2_OVER	0x3c
> > +	u16				OVER;
> >   /* Extended Mode Register */
> > -#define AT91_SAMA5D2_EMR	0x40
> > +	u16				EMR;
> >   /* Extended Mode Register - Oversampling rate */
> >   #define AT91_SAMA5D2_EMR_OSR(V)			((V) << 16)
> >   #define AT91_SAMA5D2_EMR_OSR_MASK		GENMASK(17, 16)
> > @@ -134,22 +136,22 @@
> >   
> >   /* Extended Mode Register - Averaging on single trigger event */
> >   #define AT91_SAMA5D2_EMR_ASTE(V)		((V) << 20)
> > +
> >   /* Compare Window Register */
> > -#define AT91_SAMA5D2_CWR	0x44
> > +	u16				CWR;
> >   /* Channel Gain Register */
> > -#define AT91_SAMA5D2_CGR	0x48
> > -
> > +	u16				CGR;
> >   /* Channel Offset Register */
> > -#define AT91_SAMA5D2_COR	0x4c
> > +	u16				COR;
> >   #define AT91_SAMA5D2_COR_DIFF_OFFSET	16
> >   
> >   /* Analog Control Register */
> > -#define AT91_SAMA5D2_ACR	0x94
> > +	u16				ACR;
> >   /* Analog Control Register - Pen detect sensitivity mask */
> >   #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
> >   
> >   /* Touchscreen Mode Register */
> > -#define AT91_SAMA5D2_TSMR	0xb0
> > +	u16				TSMR;
> >   /* Touchscreen Mode Register - No touch mode */
> >   #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
> >   /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
> > @@ -178,13 +180,13 @@
> >   #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
> >   
> >   /* Touchscreen X Position Register */
> > -#define AT91_SAMA5D2_XPOSR	0xb4
> > +	u16				XPOSR;
> >   /* Touchscreen Y Position Register */
> > -#define AT91_SAMA5D2_YPOSR	0xb8
> > +	u16				YPOSR;
> >   /* Touchscreen Pressure Register */
> > -#define AT91_SAMA5D2_PRESSR	0xbc
> > +	u16				PRESSR;
> >   /* Trigger Register */
> > -#define AT91_SAMA5D2_TRGR	0xc0
> > +	u16				TRGR;
> >   /* Mask for TRGMOD field of TRGR register */
> >   #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
> >   /* No trigger, only software trigger can start conversions */
> > @@ -203,30 +205,52 @@
> >   #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
> >   
> >   /* Correction Select Register */
> > -#define AT91_SAMA5D2_COSR	0xd0
> > +	u16				COSR;
> >   /* Correction Value Register */
> > -#define AT91_SAMA5D2_CVR	0xd4
> > +	u16				CVR;
> >   /* Channel Error Correction Register */
> > -#define AT91_SAMA5D2_CECR	0xd8
> > +	u16				CECR;
> >   /* Write Protection Mode Register */
> > -#define AT91_SAMA5D2_WPMR	0xe4
> > +	u16				WPMR;
> >   /* Write Protection Status Register */
> > -#define AT91_SAMA5D2_WPSR	0xe8
> > +	u16				WPSR;
> >   /* Version Register */
> > -#define AT91_SAMA5D2_VERSION	0xfc
> > -
> > -#define AT91_SAMA5D2_HW_TRIG_CNT 3
> > -#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
> > -#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
> > -
> > -#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> > -					 AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
> > +	u16				VERSION;
> > +};
> >   
> > -#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> > -					 AT91_SAMA5D2_DIFF_CHAN_CNT * 2)  
> 
> Hi Jonathan,
> 
> While we are here, regarding the above line, I cannot tell why did I 
> multiply by two the differential channel count. This makes some gaps in 
> the number of channels when we put them all in the same table.
> 
> I did not change this as it would break the ABI regarding the bindings 
> for the touchscreen #adc-cells phandle references.

Really?  Xlate is based off scan_index, not these values I think...

> 
> However, I am thinking if there was a reason for it or it was a slip 
> when I initially wrote this.

I've no idea :)  I can't immediately see why we'd need the padding.

> 
> Do you think there is any reason to change it and tighten the holes in 
> the indexes list ?

I don't think it matters. As far as I can tell they are used mostly (possibly
entirely) for internal management and not exposed to any of the ABIs etc.

Jonathan

> 
> 
> Eugen
> 
> > -#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
> > -#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
> > -#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
> > +static const struct at91_adc_reg_layout sama5d2_layout = {
> > +	.CR =			0x00,
> > +	.MR =			0x04,
> > +	.SEQR1 =		0x08,
> > +	.SEQR2 =		0x0c,
> > +	.CHER =			0x10,
> > +	.CHDR =			0x14,
> > +	.CHSR =			0x18,
> > +	.LCDR =			0x20,
> > +	.IER =			0x24,
> > +	.IDR =			0x28,
> > +	.IMR =			0x2c,
> > +	.ISR =			0x30,
> > +	.LCTMR =		0x34,
> > +	.LCCWR =		0x38,
> > +	.OVER =			0x3c,
> > +	.EMR =			0x40,
> > +	.CWR =			0x44,
> > +	.CGR =			0x48,
> > +	.COR =			0x4c,
> > +	.ACR =			0x94,
> > +	.TSMR =			0xb0,
> > +	.XPOSR =		0xb4,
> > +	.YPOSR =		0xb8,
> > +	.PRESSR =		0xbc,
> > +	.TRGR =			0xc0,
> > +	.COSR =			0xd0,
> > +	.CVR =			0xd4,
> > +	.CECR =			0xd8,
> > +	.WPMR =			0xe4,
> > +	.WPSR =			0xe8,
> > +	.VERSION =		0xfc,
> > +};
> >   
> >   #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
> >   #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
> > @@ -235,18 +259,6 @@
> >   
> >   #define AT91_SAMA5D2_MAX_POS_BITS			12
> >   
> > -/*
> > - * Maximum number of bytes to hold conversion from all channels
> > - * without the timestamp.
> > - */
> > -#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> > -					 AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
> > -
> > -/* This total must also include the timestamp */
> > -#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
> > -
> > -#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
> > -
> >   #define AT91_HWFIFO_MAX_SIZE_STR	"128"
> >   #define AT91_HWFIFO_MAX_SIZE		128
> >   
> > @@ -255,12 +267,12 @@
> >   #define AT91_OSR_4SAMPLES		4
> >   #define AT91_OSR_16SAMPLES		16
> >   
> > -#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)				\
> > +#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)			\
> >   	{								\
> >   		.type = IIO_VOLTAGE,					\
> >   		.channel = num,						\
> >   		.address = addr,					\
> > -		.scan_index = num,					\
> > +		.scan_index = index,					\
> >   		.scan_type = {						\
> >   			.sign = 'u',					\
> >   			.realbits = 14,					\
> > @@ -274,14 +286,14 @@
> >   		.indexed = 1,						\
> >   	}
> >   
> > -#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)				\
> > +#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)			\
> >   	{								\
> >   		.type = IIO_VOLTAGE,					\
> >   		.differential = 1,					\
> >   		.channel = num,						\
> >   		.channel2 = num2,					\
> >   		.address = addr,					\
> > -		.scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,	\
> > +		.scan_index = index,					\
> >   		.scan_type = {						\
> >   			.sign = 's',					\
> >   			.realbits = 14,					\
> > @@ -328,13 +340,48 @@
> >   		.datasheet_name = name,					\
> >   	}
> >   
> > -#define at91_adc_readl(st, reg)		readl_relaxed(st->base + reg)
> > -#define at91_adc_writel(st, reg, val)	writel_relaxed(val, st->base + reg)
> > +#define at91_adc_readl(st, reg)						\
> > +	readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
> > +#define at91_adc_read_chan(st, reg)					\
> > +	readl_relaxed((st)->base + reg)
> > +#define at91_adc_writel(st, reg, val)					\
> > +	writel_relaxed(val, (st)->base + (st)->soc_info.platform->layout->reg)
> > +
> > +/**
> > + * struct at91_adc_platform - at91-sama5d2 platform information struct
> > + * @layout:		pointer to the reg layout struct
> > + * @adc_channels:	pointer to an array of channels for registering in
> > + *			the iio subsystem
> > + * @nr_channels:	number of physical channels available
> > + * @touch_chan_x:	index of the touchscreen X channel
> > + * @touch_chan_y:	index of the touchscreen Y channel
> > + * @touch_chan_p:	index of the touchscreen P channel
> > + * @max_channels:	number of total channels
> > + * @hw_trig_cnt:	number of possible hardware triggers
> > + */
> > +struct at91_adc_platform {
> > +	const struct at91_adc_reg_layout	*layout;
> > +	const struct iio_chan_spec		(*adc_channels)[];
> > +	unsigned int				nr_channels;
> > +	unsigned int				touch_chan_x;
> > +	unsigned int				touch_chan_y;
> > +	unsigned int				touch_chan_p;
> > +	unsigned int				max_channels;
> > +	unsigned int				hw_trig_cnt;
> > +};
> >   
> > +/**
> > + * struct at91_adc_soc_info - at91-sama5d2 soc information struct
> > + * @startup_time:	device startup time
> > + * @min_sample_rate:	minimum sample rate in Hz
> > + * @max_sample_rate:	maximum sample rate in Hz
> > + * @platform:		pointer to the platform structure
> > + */
> >   struct at91_adc_soc_info {
> >   	unsigned			startup_time;
> >   	unsigned			min_sample_rate;
> >   	unsigned			max_sample_rate;
> > +	const struct at91_adc_platform	*platform;
> >   };
> >   
> >   struct at91_adc_trigger {
> > @@ -382,6 +429,15 @@ struct at91_adc_touch {
> >   	struct work_struct		workq;
> >   };
> >   
> > +/*
> > + * Buffer size requirements:
> > + * No channels * bytes_per_channel(2) + timestamp bytes (8)
> > + * Divided by 2 because we need half words.
> > + * We assume 32 channels for now, has to be increased if needed.
> > + * Nobody minds a buffer being too big.
> > + */
> > +#define AT91_BUFFER_MAX_HWORDS ((32 * 2 + 8) / 2)
> > +
> >   struct at91_adc_state {
> >   	void __iomem			*base;
> >   	int				irq;
> > @@ -437,29 +493,49 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = {
> >   	},
> >   };
> >   
> > -static const struct iio_chan_spec at91_adc_channels[] = {
> > -	AT91_SAMA5D2_CHAN_SINGLE(0, 0x50),
> > -	AT91_SAMA5D2_CHAN_SINGLE(1, 0x54),
> > -	AT91_SAMA5D2_CHAN_SINGLE(2, 0x58),
> > -	AT91_SAMA5D2_CHAN_SINGLE(3, 0x5c),
> > -	AT91_SAMA5D2_CHAN_SINGLE(4, 0x60),
> > -	AT91_SAMA5D2_CHAN_SINGLE(5, 0x64),
> > -	AT91_SAMA5D2_CHAN_SINGLE(6, 0x68),
> > -	AT91_SAMA5D2_CHAN_SINGLE(7, 0x6c),
> > -	AT91_SAMA5D2_CHAN_SINGLE(8, 0x70),
> > -	AT91_SAMA5D2_CHAN_SINGLE(9, 0x74),
> > -	AT91_SAMA5D2_CHAN_SINGLE(10, 0x78),
> > -	AT91_SAMA5D2_CHAN_SINGLE(11, 0x7c),
> > -	AT91_SAMA5D2_CHAN_DIFF(0, 1, 0x50),
> > -	AT91_SAMA5D2_CHAN_DIFF(2, 3, 0x58),
> > -	AT91_SAMA5D2_CHAN_DIFF(4, 5, 0x60),
> > -	AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68),
> > -	AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70),
> > -	AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78),
> > -	IIO_CHAN_SOFT_TIMESTAMP(AT91_SAMA5D2_TIMESTAMP_CHAN_IDX),
> > -	AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_X_CHAN_IDX, "x", IIO_MOD_X),
> > -	AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, "y", IIO_MOD_Y),
> > -	AT91_SAMA5D2_CHAN_PRESSURE(AT91_SAMA5D2_TOUCH_P_CHAN_IDX, "pressure"),
> > +static const struct iio_chan_spec at91_sama5d2_adc_channels[] = {
> > +	AT91_SAMA5D2_CHAN_SINGLE(0, 0, 0x50),
> > +	AT91_SAMA5D2_CHAN_SINGLE(1, 1, 0x54),
> > +	AT91_SAMA5D2_CHAN_SINGLE(2, 2, 0x58),
> > +	AT91_SAMA5D2_CHAN_SINGLE(3, 3, 0x5c),
> > +	AT91_SAMA5D2_CHAN_SINGLE(4, 4, 0x60),
> > +	AT91_SAMA5D2_CHAN_SINGLE(5, 5, 0x64),
> > +	AT91_SAMA5D2_CHAN_SINGLE(6, 6, 0x68),
> > +	AT91_SAMA5D2_CHAN_SINGLE(7, 7, 0x6c),
> > +	AT91_SAMA5D2_CHAN_SINGLE(8, 8, 0x70),
> > +	AT91_SAMA5D2_CHAN_SINGLE(9, 9, 0x74),
> > +	AT91_SAMA5D2_CHAN_SINGLE(10, 10, 0x78),
> > +	AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x7c),
> > +	AT91_SAMA5D2_CHAN_DIFF(12, 0, 1, 0x50),
> > +	AT91_SAMA5D2_CHAN_DIFF(13, 2, 3, 0x58),
> > +	AT91_SAMA5D2_CHAN_DIFF(14, 4, 5, 0x60),
> > +	AT91_SAMA5D2_CHAN_DIFF(15, 6, 7, 0x68),
> > +	AT91_SAMA5D2_CHAN_DIFF(16, 8, 9, 0x70),
> > +	AT91_SAMA5D2_CHAN_DIFF(17, 10, 11, 0x78),
> > +	IIO_CHAN_SOFT_TIMESTAMP(18),
> > +	AT91_SAMA5D2_CHAN_TOUCH(19, "x", IIO_MOD_X),
> > +	AT91_SAMA5D2_CHAN_TOUCH(20, "y", IIO_MOD_Y),
> > +	AT91_SAMA5D2_CHAN_PRESSURE(21, "pressure"),
> > +};
> > +
> > +static const struct at91_adc_platform sama5d2_platform = {
> > +	.layout = &sama5d2_layout,
> > +	.adc_channels = &at91_sama5d2_adc_channels,
> > +#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
> > +#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
> > +	.nr_channels = AT91_SAMA5D2_SINGLE_CHAN_CNT +
> > +		       AT91_SAMA5D2_DIFF_CHAN_CNT,
> > +#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX	(AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> > +					AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
> > +	.touch_chan_x = AT91_SAMA5D2_TOUCH_X_CHAN_IDX,
> > +#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX	(AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
> > +	.touch_chan_y = AT91_SAMA5D2_TOUCH_Y_CHAN_IDX,
> > +#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX	(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
> > +	.touch_chan_p = AT91_SAMA5D2_TOUCH_P_CHAN_IDX,
> > +#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
> > +	.max_channels = ARRAY_SIZE(at91_sama5d2_adc_channels),
> > +#define AT91_SAMA5D2_HW_TRIG_CNT	3
> > +	.hw_trig_cnt = AT91_SAMA5D2_HW_TRIG_CNT,
> >   };
> >   
> >   static int at91_adc_chan_xlate(struct iio_dev *indio_dev, int chan)
> > @@ -493,6 +569,7 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
> >   {
> >   	u32 mask = 0;
> >   	u8 bit;
> > +	struct at91_adc_state *st = iio_priv(indio_dev);
> >   
> >   	for_each_set_bit(bit, indio_dev->active_scan_mask,
> >   			 indio_dev->num_channels) {
> > @@ -501,13 +578,13 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
> >   		mask |= BIT(chan->channel);
> >   	}
> >   
> > -	return mask & GENMASK(11, 0);
> > +	return mask & GENMASK(st->soc_info.platform->nr_channels, 0);
> >   }
> >   
> >   static void at91_adc_config_emr(struct at91_adc_state *st)
> >   {
> >   	/* configure the extended mode register */
> > -	unsigned int emr = at91_adc_readl(st, AT91_SAMA5D2_EMR);
> > +	unsigned int emr = at91_adc_readl(st, EMR);
> >   
> >   	/* select oversampling per single trigger event */
> >   	emr |= AT91_SAMA5D2_EMR_ASTE(1);
> > @@ -531,7 +608,7 @@ static void at91_adc_config_emr(struct at91_adc_state *st)
> >   		break;
> >   	}
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_EMR, emr);
> > +	at91_adc_writel(st, EMR, emr);
> >   }
> >   
> >   static int at91_adc_adjust_val_osr(struct at91_adc_state *st, int *val)
> > @@ -584,9 +661,9 @@ static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
> >   
> >   	if (!state) {
> >   		/* disabling touch IRQs and setting mode to no touch enabled */
> > -		at91_adc_writel(st, AT91_SAMA5D2_IDR,
> > +		at91_adc_writel(st, IDR,
> >   				AT91_SAMA5D2_IER_PEN | AT91_SAMA5D2_IER_NOPEN);
> > -		at91_adc_writel(st, AT91_SAMA5D2_TSMR, 0);
> > +		at91_adc_writel(st, TSMR, 0);
> >   		return 0;
> >   	}
> >   	/*
> > @@ -612,19 +689,19 @@ static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
> >   	tsmr |= AT91_SAMA5D2_TSMR_PENDET_ENA;
> >   	tsmr |= AT91_SAMA5D2_TSMR_TSFREQ(2) & AT91_SAMA5D2_TSMR_TSFREQ_MASK;
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_TSMR, tsmr);
> > +	at91_adc_writel(st, TSMR, tsmr);
> >   
> > -	acr =  at91_adc_readl(st, AT91_SAMA5D2_ACR);
> > +	acr =  at91_adc_readl(st, ACR);
> >   	acr &= ~AT91_SAMA5D2_ACR_PENDETSENS_MASK;
> >   	acr |= 0x02 & AT91_SAMA5D2_ACR_PENDETSENS_MASK;
> > -	at91_adc_writel(st, AT91_SAMA5D2_ACR, acr);
> > +	at91_adc_writel(st, ACR, acr);
> >   
> >   	/* Sample Period Time = (TRGPER + 1) / ADCClock */
> >   	st->touch_st.sample_period_val =
> >   				 round_up((AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US *
> >   				 clk_khz / 1000) - 1, 1);
> >   	/* enable pen detect IRQ */
> > -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
> > +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_PEN);
> >   
> >   	return 0;
> >   }
> > @@ -640,7 +717,11 @@ static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
> >   	 * max = 2^AT91_SAMA5D2_MAX_POS_BITS - 1
> >   	 */
> >   	/* first half of register is the x or y, second half is the scale */
> > -	val = at91_adc_readl(st, reg);
> > +	if (reg == st->soc_info.platform->layout->XPOSR)
> > +		val = at91_adc_readl(st, XPOSR);
> > +	else if (reg == st->soc_info.platform->layout->YPOSR)
> > +		val = at91_adc_readl(st, YPOSR);
> > +
> >   	if (!val)
> >   		dev_dbg(&st->indio_dev->dev, "pos is 0\n");
> >   
> > @@ -658,13 +739,13 @@ static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
> >   
> >   static u16 at91_adc_touch_x_pos(struct at91_adc_state *st)
> >   {
> > -	st->touch_st.x_pos = at91_adc_touch_pos(st, AT91_SAMA5D2_XPOSR);
> > +	st->touch_st.x_pos = at91_adc_touch_pos(st, st->soc_info.platform->layout->XPOSR);
> >   	return st->touch_st.x_pos;
> >   }
> >   
> >   static u16 at91_adc_touch_y_pos(struct at91_adc_state *st)
> >   {
> > -	return at91_adc_touch_pos(st, AT91_SAMA5D2_YPOSR);
> > +	return at91_adc_touch_pos(st, st->soc_info.platform->layout->YPOSR);
> >   }
> >   
> >   static u16 at91_adc_touch_pressure(struct at91_adc_state *st)
> > @@ -676,7 +757,7 @@ static u16 at91_adc_touch_pressure(struct at91_adc_state *st)
> >   	u32 factor = 1000;
> >   
> >   	/* calculate the pressure */
> > -	val = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
> > +	val = at91_adc_readl(st, PRESSR);
> >   	z1 = val & AT91_SAMA5D2_XYZ_MASK;
> >   	z2 = (val >> 16) & AT91_SAMA5D2_XYZ_MASK;
> >   
> > @@ -700,9 +781,9 @@ static int at91_adc_read_position(struct at91_adc_state *st, int chan, u16 *val)
> >   	*val = 0;
> >   	if (!st->touch_st.touching)
> >   		return -ENODATA;
> > -	if (chan == AT91_SAMA5D2_TOUCH_X_CHAN_IDX)
> > +	if (chan == st->soc_info.platform->touch_chan_x)
> >   		*val = at91_adc_touch_x_pos(st);
> > -	else if (chan == AT91_SAMA5D2_TOUCH_Y_CHAN_IDX)
> > +	else if (chan == st->soc_info.platform->touch_chan_y)
> >   		*val = at91_adc_touch_y_pos(st);
> >   	else
> >   		return -ENODATA;
> > @@ -715,7 +796,7 @@ static int at91_adc_read_pressure(struct at91_adc_state *st, int chan, u16 *val)
> >   	*val = 0;
> >   	if (!st->touch_st.touching)
> >   		return -ENODATA;
> > -	if (chan == AT91_SAMA5D2_TOUCH_P_CHAN_IDX)
> > +	if (chan == st->soc_info.platform->touch_chan_y)
> >   		*val = at91_adc_touch_pressure(st);
> >   	else
> >   		return -ENODATA;
> > @@ -727,7 +808,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
> >   {
> >   	struct iio_dev *indio = iio_trigger_get_drvdata(trig);
> >   	struct at91_adc_state *st = iio_priv(indio);
> > -	u32 status = at91_adc_readl(st, AT91_SAMA5D2_TRGR);
> > +	u32 status = at91_adc_readl(st, TRGR);
> >   
> >   	/* clear TRGMOD */
> >   	status &= ~AT91_SAMA5D2_TRGR_TRGMOD_MASK;
> > @@ -736,7 +817,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
> >   		status |= st->selected_trig->trgmod_value;
> >   
> >   	/* set/unset hw trigger */
> > -	at91_adc_writel(st, AT91_SAMA5D2_TRGR, status);
> > +	at91_adc_writel(st, TRGR, status);
> >   
> >   	return 0;
> >   }
> > @@ -753,7 +834,7 @@ static void at91_adc_reenable_trigger(struct iio_trigger *trig)
> >   	enable_irq(st->irq);
> >   
> >   	/* Needed to ACK the DRDY interruption */
> > -	at91_adc_readl(st, AT91_SAMA5D2_LCDR);
> > +	at91_adc_readl(st, LCDR);
> >   }
> >   
> >   static const struct iio_trigger_ops at91_adc_trigger_ops = {
> > @@ -848,7 +929,7 @@ static int at91_adc_dma_start(struct iio_dev *indio_dev)
> >   	}
> >   
> >   	/* enable general overrun error signaling */
> > -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_GOVRE);
> > +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_GOVRE);
> >   	/* Issue pending DMA requests */
> >   	dma_async_issue_pending(st->dma_st.dma_chan);
> >   
> > @@ -878,7 +959,7 @@ static bool at91_adc_current_chan_is_touch(struct iio_dev *indio_dev)
> >   
> >   	return !!bitmap_subset(indio_dev->active_scan_mask,
> >   			       &st->touch_st.channels_bitmask,
> > -			       AT91_SAMA5D2_MAX_CHAN_IDX + 1);
> > +			       st->soc_info.platform->max_channels + 1);
> >   }
> >   
> >   static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
> > @@ -915,7 +996,7 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
> >   		    chan->type == IIO_PRESSURE)
> >   			continue;
> >   
> > -		cor = at91_adc_readl(st, AT91_SAMA5D2_COR);
> > +		cor = at91_adc_readl(st, COR);
> >   
> >   		if (chan->differential)
> >   			cor |= (BIT(chan->channel) | BIT(chan->channel2)) <<
> > @@ -924,13 +1005,13 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
> >   			cor &= ~(BIT(chan->channel) <<
> >   			       AT91_SAMA5D2_COR_DIFF_OFFSET);
> >   
> > -		at91_adc_writel(st, AT91_SAMA5D2_COR, cor);
> > +		at91_adc_writel(st, COR, cor);
> >   
> > -		at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel));
> > +		at91_adc_writel(st, CHER, BIT(chan->channel));
> >   	}
> >   
> >   	if (at91_adc_buffer_check_use_irq(indio_dev, st))
> > -		at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_DRDY);
> > +		at91_adc_writel(st, IER, AT91_SAMA5D2_IER_DRDY);
> >   
> >   	return 0;
> >   }
> > @@ -966,17 +1047,17 @@ static int at91_adc_buffer_postdisable(struct iio_dev *indio_dev)
> >   		    chan->type == IIO_PRESSURE)
> >   			continue;
> >   
> > -		at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
> > +		at91_adc_writel(st, CHDR, BIT(chan->channel));
> >   
> >   		if (st->dma_st.dma_chan)
> > -			at91_adc_readl(st, chan->address);
> > +			at91_adc_read_chan(st, chan->address);
> >   	}
> >   
> >   	if (at91_adc_buffer_check_use_irq(indio_dev, st))
> > -		at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_DRDY);
> > +		at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_DRDY);
> >   
> >   	/* read overflow register to clear possible overflow status */
> > -	at91_adc_readl(st, AT91_SAMA5D2_OVER);
> > +	at91_adc_readl(st, OVER);
> >   
> >   	/* if we are using DMA we must clear registers and end DMA */
> >   	if (st->dma_st.dma_chan)
> > @@ -1024,7 +1105,7 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
> >   	 * Check if the conversion is ready. If not, wait a little bit, and
> >   	 * in case of timeout exit with an error.
> >   	 */
> > -	while ((at91_adc_readl(st, AT91_SAMA5D2_ISR) & mask) != mask &&
> > +	while ((at91_adc_readl(st, ISR) & mask) != mask &&
> >   	       timeout) {
> >   		usleep_range(50, 100);
> >   		timeout--;
> > @@ -1052,7 +1133,7 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
> >   		 * Thus, emit a warning.
> >   		 */
> >   		if (chan->type == IIO_VOLTAGE) {
> > -			val = at91_adc_readl(st, chan->address);
> > +			val = at91_adc_read_chan(st, chan->address);
> >   			at91_adc_adjust_val_osr(st, &val);
> >   			st->buffer[i] = val;
> >   		} else {
> > @@ -1073,7 +1154,7 @@ static void at91_adc_trigger_handler_dma(struct iio_dev *indio_dev)
> >   	s64 interval;
> >   	int sample_index = 0, sample_count, sample_size;
> >   
> > -	u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
> > +	u32 status = at91_adc_readl(st, ISR);
> >   	/* if we reached this point, we cannot sample faster */
> >   	if (status & AT91_SAMA5D2_IER_GOVRE)
> >   		pr_info_ratelimited("%s: conversion overrun detected\n",
> > @@ -1125,7 +1206,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
> >   	 * actually polling the trigger now.
> >   	 */
> >   	if (iio_trigger_validate_own_device(indio_dev->trig, indio_dev))
> > -		at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START);
> > +		at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
> >   
> >   	if (st->dma_st.dma_chan)
> >   		at91_adc_trigger_handler_dma(indio_dev);
> > @@ -1172,11 +1253,11 @@ static void at91_adc_setup_samp_freq(struct iio_dev *indio_dev, unsigned freq)
> >   	startup = at91_adc_startup_time(st->soc_info.startup_time,
> >   					freq / 1000);
> >   
> > -	mr = at91_adc_readl(st, AT91_SAMA5D2_MR);
> > +	mr = at91_adc_readl(st, MR);
> >   	mr &= ~(AT91_SAMA5D2_MR_STARTUP_MASK | AT91_SAMA5D2_MR_PRESCAL_MASK);
> >   	mr |= AT91_SAMA5D2_MR_STARTUP(startup);
> >   	mr |= AT91_SAMA5D2_MR_PRESCAL(prescal);
> > -	at91_adc_writel(st, AT91_SAMA5D2_MR, mr);
> > +	at91_adc_writel(st, MR, mr);
> >   
> >   	dev_dbg(&indio_dev->dev, "freq: %u, startup: %u, prescal: %u\n",
> >   		freq, startup, prescal);
> > @@ -1196,7 +1277,7 @@ static void at91_adc_touch_data_handler(struct iio_dev *indio_dev)
> >   	int i = 0;
> >   
> >   	for_each_set_bit(bit, indio_dev->active_scan_mask,
> > -			 AT91_SAMA5D2_MAX_CHAN_IDX + 1) {
> > +			 st->soc_info.platform->max_channels + 1) {
> >   		struct iio_chan_spec const *chan =
> >   					 at91_adc_chan_get(indio_dev, bit);
> >   
> > @@ -1222,12 +1303,11 @@ static void at91_adc_touch_data_handler(struct iio_dev *indio_dev)
> >   
> >   static void at91_adc_pen_detect_interrupt(struct at91_adc_state *st)
> >   {
> > -	at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_PEN);
> > -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_NOPEN |
> > +	at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_PEN);
> > +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_NOPEN |
> >   			AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
> >   			AT91_SAMA5D2_IER_PRDY);
> > -	at91_adc_writel(st, AT91_SAMA5D2_TRGR,
> > -			AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC |
> > +	at91_adc_writel(st, TRGR, AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC |
> >   			AT91_SAMA5D2_TRGR_TRGPER(st->touch_st.sample_period_val));
> >   	st->touch_st.touching = true;
> >   }
> > @@ -1236,16 +1316,15 @@ static void at91_adc_no_pen_detect_interrupt(struct iio_dev *indio_dev)
> >   {
> >   	struct at91_adc_state *st = iio_priv(indio_dev);
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_TRGR,
> > -			AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER);
> > -	at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_NOPEN |
> > +	at91_adc_writel(st, TRGR, AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER);
> > +	at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_NOPEN |
> >   			AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
> >   			AT91_SAMA5D2_IER_PRDY);
> >   	st->touch_st.touching = false;
> >   
> >   	at91_adc_touch_data_handler(indio_dev);
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
> > +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_PEN);
> >   }
> >   
> >   static void at91_adc_workq_handler(struct work_struct *workq)
> > @@ -1263,8 +1342,8 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
> >   {
> >   	struct iio_dev *indio = private;
> >   	struct at91_adc_state *st = iio_priv(indio);
> > -	u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
> > -	u32 imr = at91_adc_readl(st, AT91_SAMA5D2_IMR);
> > +	u32 status = at91_adc_readl(st, ISR);
> > +	u32 imr = at91_adc_readl(st, IMR);
> >   	u32 rdy_mask = AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
> >   			AT91_SAMA5D2_IER_PRDY;
> >   
> > @@ -1285,9 +1364,9 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
> >   		 * touching, but the measurements are not ready yet.
> >   		 * read and ignore.
> >   		 */
> > -		status = at91_adc_readl(st, AT91_SAMA5D2_XPOSR);
> > -		status = at91_adc_readl(st, AT91_SAMA5D2_YPOSR);
> > -		status = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
> > +		status = at91_adc_readl(st, XPOSR);
> > +		status = at91_adc_readl(st, YPOSR);
> > +		status = at91_adc_readl(st, PRESSR);
> >   	} else if (iio_buffer_enabled(indio) &&
> >   		   (status & AT91_SAMA5D2_IER_DRDY)) {
> >   		/* triggered buffer without DMA */
> > @@ -1299,7 +1378,7 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
> >   		WARN(true, "Unexpected irq occurred\n");
> >   	} else if (!iio_buffer_enabled(indio)) {
> >   		/* software requested conversion */
> > -		st->conversion_value = at91_adc_readl(st, st->chan->address);
> > +		st->conversion_value = at91_adc_read_chan(st, st->chan->address);
> >   		st->conversion_done = true;
> >   		wake_up_interruptible(&st->wq_data_available);
> >   	}
> > @@ -1360,10 +1439,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
> >   		cor = (BIT(chan->channel) | BIT(chan->channel2)) <<
> >   		      AT91_SAMA5D2_COR_DIFF_OFFSET;
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_COR, cor);
> > -	at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel));
> > -	at91_adc_writel(st, AT91_SAMA5D2_IER, BIT(chan->channel));
> > -	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START);
> > +	at91_adc_writel(st, COR, cor);
> > +	at91_adc_writel(st, CHER, BIT(chan->channel));
> > +	at91_adc_writel(st, IER, BIT(chan->channel));
> > +	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
> >   
> >   	ret = wait_event_interruptible_timeout(st->wq_data_available,
> >   					       st->conversion_done,
> > @@ -1379,11 +1458,11 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
> >   		st->conversion_done = false;
> >   	}
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_IDR, BIT(chan->channel));
> > -	at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
> > +	at91_adc_writel(st, IDR, BIT(chan->channel));
> > +	at91_adc_writel(st, CHDR, BIT(chan->channel));
> >   
> >   	/* Needed to ACK the DRDY interruption */
> > -	at91_adc_readl(st, AT91_SAMA5D2_LCDR);
> > +	at91_adc_readl(st, LCDR);
> >   
> >   	mutex_unlock(&st->lock);
> >   
> > @@ -1455,14 +1534,15 @@ static void at91_adc_dma_init(struct platform_device *pdev)
> >   	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> >   	struct at91_adc_state *st = iio_priv(indio_dev);
> >   	struct dma_slave_config config = {0};
> > +	/* we have 2 bytes for each channel */
> > +	unsigned int sample_size = st->soc_info.platform->nr_channels * 2;
> >   	/*
> >   	 * We make the buffer double the size of the fifo,
> >   	 * such that DMA uses one half of the buffer (full fifo size)
> >   	 * and the software uses the other half to read/write.
> >   	 */
> >   	unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
> > -					  AT91_BUFFER_MAX_CONVERSION_BYTES * 2,
> > -					  PAGE_SIZE);
> > +					  sample_size * 2, PAGE_SIZE);
> >   
> >   	if (st->dma_st.dma_chan)
> >   		return;
> > @@ -1486,7 +1566,7 @@ static void at91_adc_dma_init(struct platform_device *pdev)
> >   	/* Configure DMA channel to read data register */
> >   	config.direction = DMA_DEV_TO_MEM;
> >   	config.src_addr = (phys_addr_t)(st->dma_st.phys_addr
> > -			  + AT91_SAMA5D2_LCDR);
> > +			  + st->soc_info.platform->layout->LCDR);
> >   	config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
> >   	config.src_maxburst = 1;
> >   	config.dst_maxburst = 1;
> > @@ -1515,9 +1595,10 @@ static void at91_adc_dma_disable(struct platform_device *pdev)
> >   {
> >   	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> >   	struct at91_adc_state *st = iio_priv(indio_dev);
> > +	/* we have 2 bytes for each channel */
> > +	unsigned int sample_size = st->soc_info.platform->nr_channels * 2;
> >   	unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
> > -					  AT91_BUFFER_MAX_CONVERSION_BYTES * 2,
> > -					  PAGE_SIZE);
> > +					  sample_size * 2, PAGE_SIZE);
> >   
> >   	/* if we are not using DMA, just return */
> >   	if (!st->dma_st.dma_chan)
> > @@ -1578,14 +1659,14 @@ static int at91_adc_update_scan_mode(struct iio_dev *indio_dev,
> >   	struct at91_adc_state *st = iio_priv(indio_dev);
> >   
> >   	if (bitmap_subset(scan_mask, &st->touch_st.channels_bitmask,
> > -			  AT91_SAMA5D2_MAX_CHAN_IDX + 1))
> > +			  st->soc_info.platform->max_channels + 1))
> >   		return 0;
> >   	/*
> >   	 * if the new bitmap is a combination of touchscreen and regular
> >   	 * channels, then we are not fine
> >   	 */
> >   	if (bitmap_intersects(&st->touch_st.channels_bitmask, scan_mask,
> > -			      AT91_SAMA5D2_MAX_CHAN_IDX + 1))
> > +			      st->soc_info.platform->max_channels + 1))
> >   		return -EINVAL;
> >   	return 0;
> >   }
> > @@ -1594,13 +1675,13 @@ static void at91_adc_hw_init(struct iio_dev *indio_dev)
> >   {
> >   	struct at91_adc_state *st = iio_priv(indio_dev);
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
> > -	at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff);
> > +	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
> > +	at91_adc_writel(st, IDR, 0xffffffff);
> >   	/*
> >   	 * Transfer field must be set to 2 according to the datasheet and
> >   	 * allows different analog settings for each channel.
> >   	 */
> > -	at91_adc_writel(st, AT91_SAMA5D2_MR,
> > +	at91_adc_writel(st, MR,
> >   			AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH);
> >   
> >   	at91_adc_setup_samp_freq(indio_dev, st->soc_info.min_sample_rate);
> > @@ -1716,21 +1797,23 @@ static int at91_adc_probe(struct platform_device *pdev)
> >   	if (!indio_dev)
> >   		return -ENOMEM;
> >   
> > +	st = iio_priv(indio_dev);
> > +	st->indio_dev = indio_dev;
> > +
> > +	st->soc_info.platform = of_device_get_match_data(&pdev->dev);
> > +
> >   	indio_dev->name = dev_name(&pdev->dev);
> >   	indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
> >   	indio_dev->info = &at91_adc_info;
> > -	indio_dev->channels = at91_adc_channels;
> > -	indio_dev->num_channels = ARRAY_SIZE(at91_adc_channels);
> > -
> > -	st = iio_priv(indio_dev);
> > -	st->indio_dev = indio_dev;
> > +	indio_dev->channels = *st->soc_info.platform->adc_channels;
> > +	indio_dev->num_channels = st->soc_info.platform->max_channels;
> >   
> >   	bitmap_set(&st->touch_st.channels_bitmask,
> > -		   AT91_SAMA5D2_TOUCH_X_CHAN_IDX, 1);
> > +		   st->soc_info.platform->touch_chan_x, 1);
> >   	bitmap_set(&st->touch_st.channels_bitmask,
> > -		   AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, 1);
> > +		   st->soc_info.platform->touch_chan_y, 1);
> >   	bitmap_set(&st->touch_st.channels_bitmask,
> > -		   AT91_SAMA5D2_TOUCH_P_CHAN_IDX, 1);
> > +		   st->soc_info.platform->touch_chan_p, 1);
> >   
> >   	st->oversampling_ratio = AT91_OSR_1SAMPLES;
> >   
> > @@ -1770,7 +1853,7 @@ static int at91_adc_probe(struct platform_device *pdev)
> >   	st->selected_trig = NULL;
> >   
> >   	/* find the right trigger, or no trigger at all */
> > -	for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT + 1; i++)
> > +	for (i = 0; i < st->soc_info.platform->hw_trig_cnt + 1; i++)
> >   		if (at91_adc_trigger_list[i].edge_type == edge_type) {
> >   			st->selected_trig = &at91_adc_trigger_list[i];
> >   			break;
> > @@ -1855,7 +1938,7 @@ static int at91_adc_probe(struct platform_device *pdev)
> >   			 st->selected_trig->name);
> >   
> >   	dev_info(&pdev->dev, "version: %x\n",
> > -		 readl_relaxed(st->base + AT91_SAMA5D2_VERSION));
> > +		 readl_relaxed(st->base + st->soc_info.platform->layout->VERSION));
> >   
> >   	return 0;
> >   
> > @@ -1898,7 +1981,7 @@ static __maybe_unused int at91_adc_suspend(struct device *dev)
> >   	 * and can be used by for other devices.
> >   	 * Otherwise, ADC will hog them and we can't go to suspend mode.
> >   	 */
> > -	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
> > +	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
> >   
> >   	clk_disable_unprepare(st->per_clk);
> >   	regulator_disable(st->vref);
> > @@ -1958,6 +2041,7 @@ static SIMPLE_DEV_PM_OPS(at91_adc_pm_ops, at91_adc_suspend, at91_adc_resume);
> >   static const struct of_device_id at91_adc_dt_match[] = {
> >   	{
> >   		.compatible = "atmel,sama5d2-adc",
> > +		.data = (const void *)&sama5d2_platform,
> >   	}, {
> >   		/* sentinel */
> >   	}
> >   
> 


_______________________________________________
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] 44+ messages in thread

* Re: [PATCH v2 05/10] iio: adc: at91-sama5d2-adc: add support for separate end of conversion registers
  2021-08-24 11:54   ` Eugen Hristev
@ 2021-08-31  6:45     ` Eugen.Hristev
  -1 siblings, 0 replies; 44+ messages in thread
From: Eugen.Hristev @ 2021-08-31  6:45 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, Nicolas.Ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, Ludovic.Desroches

On 8/24/21 2:54 PM, Eugen Hristev wrote:
> Some platforms have separated the end-of-conversion information from the
> usual ISR/IMR/IER/IDR registers, into EOC_ISR/EOC_IMR/EOC_IER/EOC_IDR.
> To cope with both variants, helpers are being added, that will make
> code more clear and more easy to read.
> 
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> ---

Hi Jonathan,

If you can still make changes on your testing branch, I noticed a typo 
in the shortcommit of this patch : 'at91-sama5d2-adc' instead of 
'at91-sama5d2_adc' , grepping through commits in the future might miss 
this patch, so maybe you can change it ?

Thanks,
Eugen

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

* Re: [PATCH v2 05/10] iio: adc: at91-sama5d2-adc: add support for separate end of conversion registers
@ 2021-08-31  6:45     ` Eugen.Hristev
  0 siblings, 0 replies; 44+ messages in thread
From: Eugen.Hristev @ 2021-08-31  6:45 UTC (permalink / raw)
  To: jic23, linux-iio, devicetree, Nicolas.Ferre
  Cc: linux-arm-kernel, linux-kernel, robh+dt, Ludovic.Desroches

On 8/24/21 2:54 PM, Eugen Hristev wrote:
> Some platforms have separated the end-of-conversion information from the
> usual ISR/IMR/IER/IDR registers, into EOC_ISR/EOC_IMR/EOC_IER/EOC_IDR.
> To cope with both variants, helpers are being added, that will make
> code more clear and more easy to read.
> 
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> ---

Hi Jonathan,

If you can still make changes on your testing branch, I noticed a typo 
in the shortcommit of this patch : 'at91-sama5d2-adc' instead of 
'at91-sama5d2_adc' , grepping through commits in the future might miss 
this patch, so maybe you can change it ?

Thanks,
Eugen
_______________________________________________
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] 44+ messages in thread

* Re: [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform specific data structures
  2021-08-30 14:44       ` Jonathan Cameron
@ 2021-08-31 11:50         ` Eugen.Hristev
  -1 siblings, 0 replies; 44+ messages in thread
From: Eugen.Hristev @ 2021-08-31 11:50 UTC (permalink / raw)
  To: jic23
  Cc: linux-iio, devicetree, Nicolas.Ferre, linux-arm-kernel,
	linux-kernel, robh+dt, Ludovic.Desroches

On 8/30/21 5:44 PM, Jonathan Cameron wrote:
> On Mon, 30 Aug 2021 12:31:46 +0000
> <Eugen.Hristev@microchip.com> wrote:
> 
>> On 8/24/21 2:54 PM, Eugen Hristev wrote:
>>> Convert the driver to platform specific structures. This means:
>>> - create a register layout struct that will hold offsets for registers
>>> - create a platform struct that will hold platform information (number of
>>> channels, indexes for different channels and pointer to layout struct)
>>> - convert specific macros that are platform dependent into platform variables
>>>
>>> This step is in fact a no-op, but allows the driver to be more flexible
>>> and for future enhancement including adding new platforms that are partly
>>> compatible with the current driver and differ slightly in register layout
>>> or capabilities for example.
>>>
>>> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
>>> ---
>>>    drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
>>>    1 file changed, 247 insertions(+), 163 deletions(-)
>>>
>>> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
>>> index 9d71dcffcf93..8ede18b8d789 100644
>>> --- a/drivers/iio/adc/at91-sama5d2_adc.c
>>> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
>>> @@ -27,8 +27,9 @@
>>>    #include <linux/pinctrl/consumer.h>
>>>    #include <linux/regulator/consumer.h>
>>>
>>> +struct at91_adc_reg_layout {
>>>    /* Control Register */
>>> -#define AT91_SAMA5D2_CR            0x00
>>> +   u16                             CR;
>>>    /* Software Reset */
>>>    #define   AT91_SAMA5D2_CR_SWRST           BIT(0)
>>>    /* Start Conversion */
>>> @@ -39,7 +40,7 @@
>>>    #define   AT91_SAMA5D2_CR_CMPRST          BIT(4)
>>>
>>>    /* Mode Register */
>>> -#define AT91_SAMA5D2_MR            0x04
>>> +   u16                             MR;
>>>    /* Trigger Selection */
>>>    #define   AT91_SAMA5D2_MR_TRGSEL(v)       ((v) << 1)
>>>    /* ADTRG */
>>> @@ -82,19 +83,19 @@
>>>    #define   AT91_SAMA5D2_MR_USEQ            BIT(31)
>>>
>>>    /* Channel Sequence Register 1 */
>>> -#define AT91_SAMA5D2_SEQR1 0x08
>>> +   u16                             SEQR1;
>>>    /* Channel Sequence Register 2 */
>>> -#define AT91_SAMA5D2_SEQR2 0x0c
>>> +   u16                             SEQR2;
>>>    /* Channel Enable Register */
>>> -#define AT91_SAMA5D2_CHER  0x10
>>> +   u16                             CHER;
>>>    /* Channel Disable Register */
>>> -#define AT91_SAMA5D2_CHDR  0x14
>>> +   u16                             CHDR;
>>>    /* Channel Status Register */
>>> -#define AT91_SAMA5D2_CHSR  0x18
>>> +   u16                             CHSR;
>>>    /* Last Converted Data Register */
>>> -#define AT91_SAMA5D2_LCDR  0x20
>>> +   u16                             LCDR;
>>>    /* Interrupt Enable Register */
>>> -#define AT91_SAMA5D2_IER   0x24
>>> +   u16                             IER;
>>>    /* Interrupt Enable Register - TS X measurement ready */
>>>    #define AT91_SAMA5D2_IER_XRDY   BIT(20)
>>>    /* Interrupt Enable Register - TS Y measurement ready */
>>> @@ -109,22 +110,23 @@
>>>    #define AT91_SAMA5D2_IER_PEN    BIT(29)
>>>    /* Interrupt Enable Register - No pen detect */
>>>    #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
>>> +
>>>    /* Interrupt Disable Register */
>>> -#define AT91_SAMA5D2_IDR   0x28
>>> +   u16                             IDR;
>>>    /* Interrupt Mask Register */
>>> -#define AT91_SAMA5D2_IMR   0x2c
>>> +   u16                             IMR;
>>>    /* Interrupt Status Register */
>>> -#define AT91_SAMA5D2_ISR   0x30
>>> +   u16                             ISR;
>>>    /* Interrupt Status Register - Pen touching sense status */
>>>    #define AT91_SAMA5D2_ISR_PENS   BIT(31)
>>>    /* Last Channel Trigger Mode Register */
>>> -#define AT91_SAMA5D2_LCTMR 0x34
>>> +   u16                             LCTMR;
>>>    /* Last Channel Compare Window Register */
>>> -#define AT91_SAMA5D2_LCCWR 0x38
>>> +   u16                             LCCWR;
>>>    /* Overrun Status Register */
>>> -#define AT91_SAMA5D2_OVER  0x3c
>>> +   u16                             OVER;
>>>    /* Extended Mode Register */
>>> -#define AT91_SAMA5D2_EMR   0x40
>>> +   u16                             EMR;
>>>    /* Extended Mode Register - Oversampling rate */
>>>    #define AT91_SAMA5D2_EMR_OSR(V)                   ((V) << 16)
>>>    #define AT91_SAMA5D2_EMR_OSR_MASK         GENMASK(17, 16)
>>> @@ -134,22 +136,22 @@
>>>
>>>    /* Extended Mode Register - Averaging on single trigger event */
>>>    #define AT91_SAMA5D2_EMR_ASTE(V)          ((V) << 20)
>>> +
>>>    /* Compare Window Register */
>>> -#define AT91_SAMA5D2_CWR   0x44
>>> +   u16                             CWR;
>>>    /* Channel Gain Register */
>>> -#define AT91_SAMA5D2_CGR   0x48
>>> -
>>> +   u16                             CGR;
>>>    /* Channel Offset Register */
>>> -#define AT91_SAMA5D2_COR   0x4c
>>> +   u16                             COR;
>>>    #define AT91_SAMA5D2_COR_DIFF_OFFSET      16
>>>
>>>    /* Analog Control Register */
>>> -#define AT91_SAMA5D2_ACR   0x94
>>> +   u16                             ACR;
>>>    /* Analog Control Register - Pen detect sensitivity mask */
>>>    #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
>>>
>>>    /* Touchscreen Mode Register */
>>> -#define AT91_SAMA5D2_TSMR  0xb0
>>> +   u16                             TSMR;
>>>    /* Touchscreen Mode Register - No touch mode */
>>>    #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
>>>    /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
>>> @@ -178,13 +180,13 @@
>>>    #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
>>>
>>>    /* Touchscreen X Position Register */
>>> -#define AT91_SAMA5D2_XPOSR 0xb4
>>> +   u16                             XPOSR;
>>>    /* Touchscreen Y Position Register */
>>> -#define AT91_SAMA5D2_YPOSR 0xb8
>>> +   u16                             YPOSR;
>>>    /* Touchscreen Pressure Register */
>>> -#define AT91_SAMA5D2_PRESSR        0xbc
>>> +   u16                             PRESSR;
>>>    /* Trigger Register */
>>> -#define AT91_SAMA5D2_TRGR  0xc0
>>> +   u16                             TRGR;
>>>    /* Mask for TRGMOD field of TRGR register */
>>>    #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
>>>    /* No trigger, only software trigger can start conversions */
>>> @@ -203,30 +205,52 @@
>>>    #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
>>>
>>>    /* Correction Select Register */
>>> -#define AT91_SAMA5D2_COSR  0xd0
>>> +   u16                             COSR;
>>>    /* Correction Value Register */
>>> -#define AT91_SAMA5D2_CVR   0xd4
>>> +   u16                             CVR;
>>>    /* Channel Error Correction Register */
>>> -#define AT91_SAMA5D2_CECR  0xd8
>>> +   u16                             CECR;
>>>    /* Write Protection Mode Register */
>>> -#define AT91_SAMA5D2_WPMR  0xe4
>>> +   u16                             WPMR;
>>>    /* Write Protection Status Register */
>>> -#define AT91_SAMA5D2_WPSR  0xe8
>>> +   u16                             WPSR;
>>>    /* Version Register */
>>> -#define AT91_SAMA5D2_VERSION       0xfc
>>> -
>>> -#define AT91_SAMA5D2_HW_TRIG_CNT 3
>>> -#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
>>> -#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
>>> -
>>> -#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
>>> -                                    AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
>>> +   u16                             VERSION;
>>> +};
>>>
>>> -#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
>>> -                                    AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
>>
>> Hi Jonathan,
>>
>> While we are here, regarding the above line, I cannot tell why did I
>> multiply by two the differential channel count. This makes some gaps in
>> the number of channels when we put them all in the same table.
>>
>> I did not change this as it would break the ABI regarding the bindings
>> for the touchscreen #adc-cells phandle references.
> 
> Really?  Xlate is based off scan_index, not these values I think...

I figured it out.

We have 12 single channels [0..11] then 6 differential [12, 14, 16, 18, 
20, 22] spaced by two, a timestamp [23], then we have the X channel 
index at 24, Y at 25 and pressure are 26.

These are reflected in this file :

https://elixir.bootlin.com/linux/latest/source/include/dt-bindings/iio/adc/at91-sama5d2_adc.h

And the resistive touchscreen connects to the adc with these indexes.

And I realised why we have the padding/spaces.
It was the original design of the driver, in the line which I 
highlighted now below in the patch : (and I never changed this since 
working on this driver, because it was a break of the ABI in channel 
numbers ...)


> 
>>
>> However, I am thinking if there was a reason for it or it was a slip
>> when I initially wrote this.
> 
> I've no idea :)  I can't immediately see why we'd need the padding.
> 
>>
>> Do you think there is any reason to change it and tighten the holes in
>> the indexes list ?
> 
> I don't think it matters. As far as I can tell they are used mostly (possibly
> entirely) for internal management and not exposed to any of the ABIs etc.
> 
> Jonathan
> 
>>
>>
>> Eugen
>>
>>> -#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
>>> -#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
>>> -#define AT91_SAMA5D2_MAX_CHAN_IDX  AT91_SAMA5D2_TOUCH_P_CHAN_IDX
>>> +static const struct at91_adc_reg_layout sama5d2_layout = {
>>> +   .CR =                   0x00,
>>> +   .MR =                   0x04,
>>> +   .SEQR1 =                0x08,
>>> +   .SEQR2 =                0x0c,
>>> +   .CHER =                 0x10,
>>> +   .CHDR =                 0x14,
>>> +   .CHSR =                 0x18,
>>> +   .LCDR =                 0x20,
>>> +   .IER =                  0x24,
>>> +   .IDR =                  0x28,
>>> +   .IMR =                  0x2c,
>>> +   .ISR =                  0x30,
>>> +   .LCTMR =                0x34,
>>> +   .LCCWR =                0x38,
>>> +   .OVER =                 0x3c,
>>> +   .EMR =                  0x40,
>>> +   .CWR =                  0x44,
>>> +   .CGR =                  0x48,
>>> +   .COR =                  0x4c,
>>> +   .ACR =                  0x94,
>>> +   .TSMR =                 0xb0,
>>> +   .XPOSR =                0xb4,
>>> +   .YPOSR =                0xb8,
>>> +   .PRESSR =               0xbc,
>>> +   .TRGR =                 0xc0,
>>> +   .COSR =                 0xd0,
>>> +   .CVR =                  0xd4,
>>> +   .CECR =                 0xd8,
>>> +   .WPMR =                 0xe4,
>>> +   .WPSR =                 0xe8,
>>> +   .VERSION =              0xfc,
>>> +};
>>>
>>>    #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
>>>    #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
>>> @@ -235,18 +259,6 @@
>>>
>>>    #define AT91_SAMA5D2_MAX_POS_BITS                 12
>>>
>>> -/*
>>> - * Maximum number of bytes to hold conversion from all channels
>>> - * without the timestamp.
>>> - */
>>> -#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
>>> -                                    AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
>>> -
>>> -/* This total must also include the timestamp */
>>> -#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
>>> -
>>> -#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
>>> -
>>>    #define AT91_HWFIFO_MAX_SIZE_STR  "128"
>>>    #define AT91_HWFIFO_MAX_SIZE              128
>>>
>>> @@ -255,12 +267,12 @@
>>>    #define AT91_OSR_4SAMPLES         4
>>>    #define AT91_OSR_16SAMPLES                16
>>>
>>> -#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)                                \
>>> +#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)                 \
>>>      {                                                               \
>>>              .type = IIO_VOLTAGE,                                    \
>>>              .channel = num,                                         \
>>>              .address = addr,                                        \
>>> -           .scan_index = num,                                      \
>>> +           .scan_index = index,                                    \
>>>              .scan_type = {                                          \
>>>                      .sign = 'u',                                    \
>>>                      .realbits = 14,                                 \
>>> @@ -274,14 +286,14 @@
>>>              .indexed = 1,                                           \
>>>      }
>>>
>>> -#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)                            \
>>> +#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)                     \
>>>      {                                                               \
>>>              .type = IIO_VOLTAGE,                                    \
>>>              .differential = 1,                                      \
>>>              .channel = num,                                         \
>>>              .channel2 = num2,                                       \
>>>              .address = addr,                                        \
>>> -           .scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,       \

Here it is: we always added num to the single channel count, but num 
goes incrementally in steps of two : 0, 2, 4, 6, 8, 10

>>> +           .scan_index = index,                                    \
>>>              .scan_type = {                                          \
>>>                      .sign = 's',                                    \
>>>                      .realbits = 14,                                 \
>>> @@ -328,13 +340,48 @@
>>>              .datasheet_name = name,                                 \
>>>      }
>>>
>>> -#define at91_adc_readl(st, reg)            readl_relaxed(st->base + reg)
>>> -#define at91_adc_writel(st, reg, val)      writel_relaxed(val, st->base + reg)
>>> +#define at91_adc_readl(st, reg)                                            \
>>> +   readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
>>> +#define at91_adc_read_chan(st, reg)                                        \
>>> +   readl_relaxed((st)->base + reg)
>>> +#define at91_adc_writel(st, reg, val)                                      \
>>> +   writel_relaxed(val, (st)->base + (st)->soc_info.platform->layout->reg)
>>> +
>>> +/**
>>> + * struct at91_adc_platform - at91-sama5d2 platform information struct
>>> + * @layout:                pointer to the reg layout struct
>>> + * @adc_channels:  pointer to an array of channels for registering in
>>> + *                 the iio subsystem
>>> + * @nr_channels:   number of physical channels available
>>> + * @touch_chan_x:  index of the touchscreen X channel
>>> + * @touch_chan_y:  index of the touchscreen Y channel
>>> + * @touch_chan_p:  index of the touchscreen P channel
>>> + * @max_channels:  number of total channels
>>> + * @hw_trig_cnt:   number of possible hardware triggers
>>> + */
>>> +struct at91_adc_platform {
>>> +   const struct at91_adc_reg_layout        *layout;
>>> +   const struct iio_chan_spec              (*adc_channels)[];
>>> +   unsigned int                            nr_channels;
>>> +   unsigned int                            touch_chan_x;
>>> +   unsigned int                            touch_chan_y;
>>> +   unsigned int                            touch_chan_p;
>>> +   unsigned int                            max_channels;
>>> +   unsigned int                            hw_trig_cnt;
>>> +};
>>>
>>> +/**
>>> + * struct at91_adc_soc_info - at91-sama5d2 soc information struct
>>> + * @startup_time:  device startup time
>>> + * @min_sample_rate:       minimum sample rate in Hz
>>> + * @max_sample_rate:       maximum sample rate in Hz
>>> + * @platform:              pointer to the platform structure
>>> + */
>>>    struct at91_adc_soc_info {
>>>      unsigned                        startup_time;
>>>      unsigned                        min_sample_rate;
>>>      unsigned                        max_sample_rate;
>>> +   const struct at91_adc_platform  *platform;
>>>    };
>>>
>>>    struct at91_adc_trigger {
>>> @@ -382,6 +429,15 @@ struct at91_adc_touch {
>>>      struct work_struct              workq;
>>>    };
>>>
>>> +/*
>>> + * Buffer size requirements:
>>> + * No channels * bytes_per_channel(2) + timestamp bytes (8)
>>> + * Divided by 2 because we need half words.
>>> + * We assume 32 channels for now, has to be increased if needed.
>>> + * Nobody minds a buffer being too big.
>>> + */
>>> +#define AT91_BUFFER_MAX_HWORDS ((32 * 2 + 8) / 2)
>>> +
>>>    struct at91_adc_state {
>>>      void __iomem                    *base;
>>>      int                             irq;
>>> @@ -437,29 +493,49 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = {
>>>      },
>>>    };
>>>
>>> -static const struct iio_chan_spec at91_adc_channels[] = {
>>> -   AT91_SAMA5D2_CHAN_SINGLE(0, 0x50),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(1, 0x54),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(2, 0x58),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(3, 0x5c),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(4, 0x60),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(5, 0x64),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(6, 0x68),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(7, 0x6c),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(8, 0x70),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(9, 0x74),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(10, 0x78),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(11, 0x7c),
>>> -   AT91_SAMA5D2_CHAN_DIFF(0, 1, 0x50),
>>> -   AT91_SAMA5D2_CHAN_DIFF(2, 3, 0x58),
>>> -   AT91_SAMA5D2_CHAN_DIFF(4, 5, 0x60),
>>> -   AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68),
>>> -   AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70),
>>> -   AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78),

you can see it here,

>>> -   IIO_CHAN_SOFT_TIMESTAMP(AT91_SAMA5D2_TIMESTAMP_CHAN_IDX),
>>> -   AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_X_CHAN_IDX, "x", IIO_MOD_X),
>>> -   AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, "y", IIO_MOD_Y),
>>> -   AT91_SAMA5D2_CHAN_PRESSURE(AT91_SAMA5D2_TOUCH_P_CHAN_IDX, "pressure"),
>>> +static const struct iio_chan_spec at91_sama5d2_adc_channels[] = {
>>> +   AT91_SAMA5D2_CHAN_SINGLE(0, 0, 0x50),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(1, 1, 0x54),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(2, 2, 0x58),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(3, 3, 0x5c),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(4, 4, 0x60),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(5, 5, 0x64),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(6, 6, 0x68),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(7, 7, 0x6c),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(8, 8, 0x70),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(9, 9, 0x74),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(10, 10, 0x78),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x7c),
>>> +   AT91_SAMA5D2_CHAN_DIFF(12, 0, 1, 0x50),
>>> +   AT91_SAMA5D2_CHAN_DIFF(13, 2, 3, 0x58),
>>> +   AT91_SAMA5D2_CHAN_DIFF(14, 4, 5, 0x60),
>>> +   AT91_SAMA5D2_CHAN_DIFF(15, 6, 7, 0x68),
>>> +   AT91_SAMA5D2_CHAN_DIFF(16, 8, 9, 0x70),
>>> +   AT91_SAMA5D2_CHAN_DIFF(17, 10, 11, 0x78),
>>> +   IIO_CHAN_SOFT_TIMESTAMP(18),
>>> +   AT91_SAMA5D2_CHAN_TOUCH(19, "x", IIO_MOD_X),
>>> +   AT91_SAMA5D2_CHAN_TOUCH(20, "y", IIO_MOD_Y),
>>> +   AT91_SAMA5D2_CHAN_PRESSURE(21, "pressure"),

And I have to come up with a new version of the patch to fix this.

It should be like this:


 >>> +   AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x7c),
 >>> +   AT91_SAMA5D2_CHAN_DIFF(12, 0, 1, 0x50),
 >>> +   AT91_SAMA5D2_CHAN_DIFF(14, 2, 3, 0x58),
 >>> +   AT91_SAMA5D2_CHAN_DIFF(16, 4, 5, 0x60),
 >>> +   AT91_SAMA5D2_CHAN_DIFF(18, 6, 7, 0x68),
 >>> +   AT91_SAMA5D2_CHAN_DIFF(20, 8, 9, 0x70),
 >>> +   AT91_SAMA5D2_CHAN_DIFF(22, 10, 11, 0x78),
 >>> +   IIO_CHAN_SOFT_TIMESTAMP(23),
 >>> +   AT91_SAMA5D2_CHAN_TOUCH(24, "x", IIO_MOD_X),
 >>> +   AT91_SAMA5D2_CHAN_TOUCH(25, "y", IIO_MOD_Y),
 >>> +   AT91_SAMA5D2_CHAN_PRESSURE(26, "pressure"),


Sorry about this. Do you want me to resend the whole series together 
with the fixes found by robots ?

I can redo the series, retest it, and send it tomorrow as a v3.


Thanks,
Eugen

>>> +};
>>> +
[snip]

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

* Re: [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform specific data structures
@ 2021-08-31 11:50         ` Eugen.Hristev
  0 siblings, 0 replies; 44+ messages in thread
From: Eugen.Hristev @ 2021-08-31 11:50 UTC (permalink / raw)
  To: jic23
  Cc: devicetree, linux-iio, linux-kernel, Ludovic.Desroches, robh+dt,
	linux-arm-kernel

On 8/30/21 5:44 PM, Jonathan Cameron wrote:
> On Mon, 30 Aug 2021 12:31:46 +0000
> <Eugen.Hristev@microchip.com> wrote:
> 
>> On 8/24/21 2:54 PM, Eugen Hristev wrote:
>>> Convert the driver to platform specific structures. This means:
>>> - create a register layout struct that will hold offsets for registers
>>> - create a platform struct that will hold platform information (number of
>>> channels, indexes for different channels and pointer to layout struct)
>>> - convert specific macros that are platform dependent into platform variables
>>>
>>> This step is in fact a no-op, but allows the driver to be more flexible
>>> and for future enhancement including adding new platforms that are partly
>>> compatible with the current driver and differ slightly in register layout
>>> or capabilities for example.
>>>
>>> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
>>> ---
>>>    drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
>>>    1 file changed, 247 insertions(+), 163 deletions(-)
>>>
>>> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
>>> index 9d71dcffcf93..8ede18b8d789 100644
>>> --- a/drivers/iio/adc/at91-sama5d2_adc.c
>>> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
>>> @@ -27,8 +27,9 @@
>>>    #include <linux/pinctrl/consumer.h>
>>>    #include <linux/regulator/consumer.h>
>>>
>>> +struct at91_adc_reg_layout {
>>>    /* Control Register */
>>> -#define AT91_SAMA5D2_CR            0x00
>>> +   u16                             CR;
>>>    /* Software Reset */
>>>    #define   AT91_SAMA5D2_CR_SWRST           BIT(0)
>>>    /* Start Conversion */
>>> @@ -39,7 +40,7 @@
>>>    #define   AT91_SAMA5D2_CR_CMPRST          BIT(4)
>>>
>>>    /* Mode Register */
>>> -#define AT91_SAMA5D2_MR            0x04
>>> +   u16                             MR;
>>>    /* Trigger Selection */
>>>    #define   AT91_SAMA5D2_MR_TRGSEL(v)       ((v) << 1)
>>>    /* ADTRG */
>>> @@ -82,19 +83,19 @@
>>>    #define   AT91_SAMA5D2_MR_USEQ            BIT(31)
>>>
>>>    /* Channel Sequence Register 1 */
>>> -#define AT91_SAMA5D2_SEQR1 0x08
>>> +   u16                             SEQR1;
>>>    /* Channel Sequence Register 2 */
>>> -#define AT91_SAMA5D2_SEQR2 0x0c
>>> +   u16                             SEQR2;
>>>    /* Channel Enable Register */
>>> -#define AT91_SAMA5D2_CHER  0x10
>>> +   u16                             CHER;
>>>    /* Channel Disable Register */
>>> -#define AT91_SAMA5D2_CHDR  0x14
>>> +   u16                             CHDR;
>>>    /* Channel Status Register */
>>> -#define AT91_SAMA5D2_CHSR  0x18
>>> +   u16                             CHSR;
>>>    /* Last Converted Data Register */
>>> -#define AT91_SAMA5D2_LCDR  0x20
>>> +   u16                             LCDR;
>>>    /* Interrupt Enable Register */
>>> -#define AT91_SAMA5D2_IER   0x24
>>> +   u16                             IER;
>>>    /* Interrupt Enable Register - TS X measurement ready */
>>>    #define AT91_SAMA5D2_IER_XRDY   BIT(20)
>>>    /* Interrupt Enable Register - TS Y measurement ready */
>>> @@ -109,22 +110,23 @@
>>>    #define AT91_SAMA5D2_IER_PEN    BIT(29)
>>>    /* Interrupt Enable Register - No pen detect */
>>>    #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
>>> +
>>>    /* Interrupt Disable Register */
>>> -#define AT91_SAMA5D2_IDR   0x28
>>> +   u16                             IDR;
>>>    /* Interrupt Mask Register */
>>> -#define AT91_SAMA5D2_IMR   0x2c
>>> +   u16                             IMR;
>>>    /* Interrupt Status Register */
>>> -#define AT91_SAMA5D2_ISR   0x30
>>> +   u16                             ISR;
>>>    /* Interrupt Status Register - Pen touching sense status */
>>>    #define AT91_SAMA5D2_ISR_PENS   BIT(31)
>>>    /* Last Channel Trigger Mode Register */
>>> -#define AT91_SAMA5D2_LCTMR 0x34
>>> +   u16                             LCTMR;
>>>    /* Last Channel Compare Window Register */
>>> -#define AT91_SAMA5D2_LCCWR 0x38
>>> +   u16                             LCCWR;
>>>    /* Overrun Status Register */
>>> -#define AT91_SAMA5D2_OVER  0x3c
>>> +   u16                             OVER;
>>>    /* Extended Mode Register */
>>> -#define AT91_SAMA5D2_EMR   0x40
>>> +   u16                             EMR;
>>>    /* Extended Mode Register - Oversampling rate */
>>>    #define AT91_SAMA5D2_EMR_OSR(V)                   ((V) << 16)
>>>    #define AT91_SAMA5D2_EMR_OSR_MASK         GENMASK(17, 16)
>>> @@ -134,22 +136,22 @@
>>>
>>>    /* Extended Mode Register - Averaging on single trigger event */
>>>    #define AT91_SAMA5D2_EMR_ASTE(V)          ((V) << 20)
>>> +
>>>    /* Compare Window Register */
>>> -#define AT91_SAMA5D2_CWR   0x44
>>> +   u16                             CWR;
>>>    /* Channel Gain Register */
>>> -#define AT91_SAMA5D2_CGR   0x48
>>> -
>>> +   u16                             CGR;
>>>    /* Channel Offset Register */
>>> -#define AT91_SAMA5D2_COR   0x4c
>>> +   u16                             COR;
>>>    #define AT91_SAMA5D2_COR_DIFF_OFFSET      16
>>>
>>>    /* Analog Control Register */
>>> -#define AT91_SAMA5D2_ACR   0x94
>>> +   u16                             ACR;
>>>    /* Analog Control Register - Pen detect sensitivity mask */
>>>    #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
>>>
>>>    /* Touchscreen Mode Register */
>>> -#define AT91_SAMA5D2_TSMR  0xb0
>>> +   u16                             TSMR;
>>>    /* Touchscreen Mode Register - No touch mode */
>>>    #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
>>>    /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
>>> @@ -178,13 +180,13 @@
>>>    #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
>>>
>>>    /* Touchscreen X Position Register */
>>> -#define AT91_SAMA5D2_XPOSR 0xb4
>>> +   u16                             XPOSR;
>>>    /* Touchscreen Y Position Register */
>>> -#define AT91_SAMA5D2_YPOSR 0xb8
>>> +   u16                             YPOSR;
>>>    /* Touchscreen Pressure Register */
>>> -#define AT91_SAMA5D2_PRESSR        0xbc
>>> +   u16                             PRESSR;
>>>    /* Trigger Register */
>>> -#define AT91_SAMA5D2_TRGR  0xc0
>>> +   u16                             TRGR;
>>>    /* Mask for TRGMOD field of TRGR register */
>>>    #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
>>>    /* No trigger, only software trigger can start conversions */
>>> @@ -203,30 +205,52 @@
>>>    #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
>>>
>>>    /* Correction Select Register */
>>> -#define AT91_SAMA5D2_COSR  0xd0
>>> +   u16                             COSR;
>>>    /* Correction Value Register */
>>> -#define AT91_SAMA5D2_CVR   0xd4
>>> +   u16                             CVR;
>>>    /* Channel Error Correction Register */
>>> -#define AT91_SAMA5D2_CECR  0xd8
>>> +   u16                             CECR;
>>>    /* Write Protection Mode Register */
>>> -#define AT91_SAMA5D2_WPMR  0xe4
>>> +   u16                             WPMR;
>>>    /* Write Protection Status Register */
>>> -#define AT91_SAMA5D2_WPSR  0xe8
>>> +   u16                             WPSR;
>>>    /* Version Register */
>>> -#define AT91_SAMA5D2_VERSION       0xfc
>>> -
>>> -#define AT91_SAMA5D2_HW_TRIG_CNT 3
>>> -#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
>>> -#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
>>> -
>>> -#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
>>> -                                    AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
>>> +   u16                             VERSION;
>>> +};
>>>
>>> -#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
>>> -                                    AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
>>
>> Hi Jonathan,
>>
>> While we are here, regarding the above line, I cannot tell why did I
>> multiply by two the differential channel count. This makes some gaps in
>> the number of channels when we put them all in the same table.
>>
>> I did not change this as it would break the ABI regarding the bindings
>> for the touchscreen #adc-cells phandle references.
> 
> Really?  Xlate is based off scan_index, not these values I think...

I figured it out.

We have 12 single channels [0..11] then 6 differential [12, 14, 16, 18, 
20, 22] spaced by two, a timestamp [23], then we have the X channel 
index at 24, Y at 25 and pressure are 26.

These are reflected in this file :

https://elixir.bootlin.com/linux/latest/source/include/dt-bindings/iio/adc/at91-sama5d2_adc.h

And the resistive touchscreen connects to the adc with these indexes.

And I realised why we have the padding/spaces.
It was the original design of the driver, in the line which I 
highlighted now below in the patch : (and I never changed this since 
working on this driver, because it was a break of the ABI in channel 
numbers ...)


> 
>>
>> However, I am thinking if there was a reason for it or it was a slip
>> when I initially wrote this.
> 
> I've no idea :)  I can't immediately see why we'd need the padding.
> 
>>
>> Do you think there is any reason to change it and tighten the holes in
>> the indexes list ?
> 
> I don't think it matters. As far as I can tell they are used mostly (possibly
> entirely) for internal management and not exposed to any of the ABIs etc.
> 
> Jonathan
> 
>>
>>
>> Eugen
>>
>>> -#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
>>> -#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
>>> -#define AT91_SAMA5D2_MAX_CHAN_IDX  AT91_SAMA5D2_TOUCH_P_CHAN_IDX
>>> +static const struct at91_adc_reg_layout sama5d2_layout = {
>>> +   .CR =                   0x00,
>>> +   .MR =                   0x04,
>>> +   .SEQR1 =                0x08,
>>> +   .SEQR2 =                0x0c,
>>> +   .CHER =                 0x10,
>>> +   .CHDR =                 0x14,
>>> +   .CHSR =                 0x18,
>>> +   .LCDR =                 0x20,
>>> +   .IER =                  0x24,
>>> +   .IDR =                  0x28,
>>> +   .IMR =                  0x2c,
>>> +   .ISR =                  0x30,
>>> +   .LCTMR =                0x34,
>>> +   .LCCWR =                0x38,
>>> +   .OVER =                 0x3c,
>>> +   .EMR =                  0x40,
>>> +   .CWR =                  0x44,
>>> +   .CGR =                  0x48,
>>> +   .COR =                  0x4c,
>>> +   .ACR =                  0x94,
>>> +   .TSMR =                 0xb0,
>>> +   .XPOSR =                0xb4,
>>> +   .YPOSR =                0xb8,
>>> +   .PRESSR =               0xbc,
>>> +   .TRGR =                 0xc0,
>>> +   .COSR =                 0xd0,
>>> +   .CVR =                  0xd4,
>>> +   .CECR =                 0xd8,
>>> +   .WPMR =                 0xe4,
>>> +   .WPSR =                 0xe8,
>>> +   .VERSION =              0xfc,
>>> +};
>>>
>>>    #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
>>>    #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
>>> @@ -235,18 +259,6 @@
>>>
>>>    #define AT91_SAMA5D2_MAX_POS_BITS                 12
>>>
>>> -/*
>>> - * Maximum number of bytes to hold conversion from all channels
>>> - * without the timestamp.
>>> - */
>>> -#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
>>> -                                    AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
>>> -
>>> -/* This total must also include the timestamp */
>>> -#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
>>> -
>>> -#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
>>> -
>>>    #define AT91_HWFIFO_MAX_SIZE_STR  "128"
>>>    #define AT91_HWFIFO_MAX_SIZE              128
>>>
>>> @@ -255,12 +267,12 @@
>>>    #define AT91_OSR_4SAMPLES         4
>>>    #define AT91_OSR_16SAMPLES                16
>>>
>>> -#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)                                \
>>> +#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)                 \
>>>      {                                                               \
>>>              .type = IIO_VOLTAGE,                                    \
>>>              .channel = num,                                         \
>>>              .address = addr,                                        \
>>> -           .scan_index = num,                                      \
>>> +           .scan_index = index,                                    \
>>>              .scan_type = {                                          \
>>>                      .sign = 'u',                                    \
>>>                      .realbits = 14,                                 \
>>> @@ -274,14 +286,14 @@
>>>              .indexed = 1,                                           \
>>>      }
>>>
>>> -#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)                            \
>>> +#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)                     \
>>>      {                                                               \
>>>              .type = IIO_VOLTAGE,                                    \
>>>              .differential = 1,                                      \
>>>              .channel = num,                                         \
>>>              .channel2 = num2,                                       \
>>>              .address = addr,                                        \
>>> -           .scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,       \

Here it is: we always added num to the single channel count, but num 
goes incrementally in steps of two : 0, 2, 4, 6, 8, 10

>>> +           .scan_index = index,                                    \
>>>              .scan_type = {                                          \
>>>                      .sign = 's',                                    \
>>>                      .realbits = 14,                                 \
>>> @@ -328,13 +340,48 @@
>>>              .datasheet_name = name,                                 \
>>>      }
>>>
>>> -#define at91_adc_readl(st, reg)            readl_relaxed(st->base + reg)
>>> -#define at91_adc_writel(st, reg, val)      writel_relaxed(val, st->base + reg)
>>> +#define at91_adc_readl(st, reg)                                            \
>>> +   readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
>>> +#define at91_adc_read_chan(st, reg)                                        \
>>> +   readl_relaxed((st)->base + reg)
>>> +#define at91_adc_writel(st, reg, val)                                      \
>>> +   writel_relaxed(val, (st)->base + (st)->soc_info.platform->layout->reg)
>>> +
>>> +/**
>>> + * struct at91_adc_platform - at91-sama5d2 platform information struct
>>> + * @layout:                pointer to the reg layout struct
>>> + * @adc_channels:  pointer to an array of channels for registering in
>>> + *                 the iio subsystem
>>> + * @nr_channels:   number of physical channels available
>>> + * @touch_chan_x:  index of the touchscreen X channel
>>> + * @touch_chan_y:  index of the touchscreen Y channel
>>> + * @touch_chan_p:  index of the touchscreen P channel
>>> + * @max_channels:  number of total channels
>>> + * @hw_trig_cnt:   number of possible hardware triggers
>>> + */
>>> +struct at91_adc_platform {
>>> +   const struct at91_adc_reg_layout        *layout;
>>> +   const struct iio_chan_spec              (*adc_channels)[];
>>> +   unsigned int                            nr_channels;
>>> +   unsigned int                            touch_chan_x;
>>> +   unsigned int                            touch_chan_y;
>>> +   unsigned int                            touch_chan_p;
>>> +   unsigned int                            max_channels;
>>> +   unsigned int                            hw_trig_cnt;
>>> +};
>>>
>>> +/**
>>> + * struct at91_adc_soc_info - at91-sama5d2 soc information struct
>>> + * @startup_time:  device startup time
>>> + * @min_sample_rate:       minimum sample rate in Hz
>>> + * @max_sample_rate:       maximum sample rate in Hz
>>> + * @platform:              pointer to the platform structure
>>> + */
>>>    struct at91_adc_soc_info {
>>>      unsigned                        startup_time;
>>>      unsigned                        min_sample_rate;
>>>      unsigned                        max_sample_rate;
>>> +   const struct at91_adc_platform  *platform;
>>>    };
>>>
>>>    struct at91_adc_trigger {
>>> @@ -382,6 +429,15 @@ struct at91_adc_touch {
>>>      struct work_struct              workq;
>>>    };
>>>
>>> +/*
>>> + * Buffer size requirements:
>>> + * No channels * bytes_per_channel(2) + timestamp bytes (8)
>>> + * Divided by 2 because we need half words.
>>> + * We assume 32 channels for now, has to be increased if needed.
>>> + * Nobody minds a buffer being too big.
>>> + */
>>> +#define AT91_BUFFER_MAX_HWORDS ((32 * 2 + 8) / 2)
>>> +
>>>    struct at91_adc_state {
>>>      void __iomem                    *base;
>>>      int                             irq;
>>> @@ -437,29 +493,49 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = {
>>>      },
>>>    };
>>>
>>> -static const struct iio_chan_spec at91_adc_channels[] = {
>>> -   AT91_SAMA5D2_CHAN_SINGLE(0, 0x50),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(1, 0x54),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(2, 0x58),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(3, 0x5c),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(4, 0x60),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(5, 0x64),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(6, 0x68),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(7, 0x6c),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(8, 0x70),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(9, 0x74),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(10, 0x78),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(11, 0x7c),
>>> -   AT91_SAMA5D2_CHAN_DIFF(0, 1, 0x50),
>>> -   AT91_SAMA5D2_CHAN_DIFF(2, 3, 0x58),
>>> -   AT91_SAMA5D2_CHAN_DIFF(4, 5, 0x60),
>>> -   AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68),
>>> -   AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70),
>>> -   AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78),

you can see it here,

>>> -   IIO_CHAN_SOFT_TIMESTAMP(AT91_SAMA5D2_TIMESTAMP_CHAN_IDX),
>>> -   AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_X_CHAN_IDX, "x", IIO_MOD_X),
>>> -   AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, "y", IIO_MOD_Y),
>>> -   AT91_SAMA5D2_CHAN_PRESSURE(AT91_SAMA5D2_TOUCH_P_CHAN_IDX, "pressure"),
>>> +static const struct iio_chan_spec at91_sama5d2_adc_channels[] = {
>>> +   AT91_SAMA5D2_CHAN_SINGLE(0, 0, 0x50),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(1, 1, 0x54),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(2, 2, 0x58),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(3, 3, 0x5c),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(4, 4, 0x60),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(5, 5, 0x64),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(6, 6, 0x68),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(7, 7, 0x6c),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(8, 8, 0x70),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(9, 9, 0x74),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(10, 10, 0x78),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x7c),
>>> +   AT91_SAMA5D2_CHAN_DIFF(12, 0, 1, 0x50),
>>> +   AT91_SAMA5D2_CHAN_DIFF(13, 2, 3, 0x58),
>>> +   AT91_SAMA5D2_CHAN_DIFF(14, 4, 5, 0x60),
>>> +   AT91_SAMA5D2_CHAN_DIFF(15, 6, 7, 0x68),
>>> +   AT91_SAMA5D2_CHAN_DIFF(16, 8, 9, 0x70),
>>> +   AT91_SAMA5D2_CHAN_DIFF(17, 10, 11, 0x78),
>>> +   IIO_CHAN_SOFT_TIMESTAMP(18),
>>> +   AT91_SAMA5D2_CHAN_TOUCH(19, "x", IIO_MOD_X),
>>> +   AT91_SAMA5D2_CHAN_TOUCH(20, "y", IIO_MOD_Y),
>>> +   AT91_SAMA5D2_CHAN_PRESSURE(21, "pressure"),

And I have to come up with a new version of the patch to fix this.

It should be like this:


 >>> +   AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x7c),
 >>> +   AT91_SAMA5D2_CHAN_DIFF(12, 0, 1, 0x50),
 >>> +   AT91_SAMA5D2_CHAN_DIFF(14, 2, 3, 0x58),
 >>> +   AT91_SAMA5D2_CHAN_DIFF(16, 4, 5, 0x60),
 >>> +   AT91_SAMA5D2_CHAN_DIFF(18, 6, 7, 0x68),
 >>> +   AT91_SAMA5D2_CHAN_DIFF(20, 8, 9, 0x70),
 >>> +   AT91_SAMA5D2_CHAN_DIFF(22, 10, 11, 0x78),
 >>> +   IIO_CHAN_SOFT_TIMESTAMP(23),
 >>> +   AT91_SAMA5D2_CHAN_TOUCH(24, "x", IIO_MOD_X),
 >>> +   AT91_SAMA5D2_CHAN_TOUCH(25, "y", IIO_MOD_Y),
 >>> +   AT91_SAMA5D2_CHAN_PRESSURE(26, "pressure"),


Sorry about this. Do you want me to resend the whole series together 
with the fixes found by robots ?

I can redo the series, retest it, and send it tomorrow as a v3.


Thanks,
Eugen

>>> +};
>>> +
[snip]
_______________________________________________
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] 44+ messages in thread

* Re: [PATCH v2 00/10] iio: adc: at91-sama5d2_adc: add support for sama7g5
  2021-08-30 12:26   ` Jonathan Cameron
@ 2021-09-01  9:47     ` Nicolas Ferre
  -1 siblings, 0 replies; 44+ messages in thread
From: Nicolas Ferre @ 2021-09-01  9:47 UTC (permalink / raw)
  To: Jonathan Cameron, Eugen Hristev
  Cc: linux-iio, devicetree, linux-arm-kernel, linux-kernel, robh+dt,
	ludovic.desroches

On 30/08/2021 at 14:26, Jonathan Cameron wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Tue, 24 Aug 2021 14:54:31 +0300
> Eugen Hristev <eugen.hristev@microchip.com> wrote:
> 
>> Hi,
>>
>> This series adds support for sama7g5.
>>
>> The sama7g5 is slightly different from sama5d2, but has the same basic
>> operations. The register map is a bit different, so, I added some primitives
>> to differentiate between the two classes of hardware blocks (sama5d2-sam9x60
>> and sama7g5).
>>
>> Sama7g5 has 16 channels ADC, no resistive touch, and extra features
>> (FIFOs, better oversampling , not implemented yet).
>>
>> It is a rework of the series initially sent here:
>> https://marc.info/?l=linux-iio&m=161461656807826&w=2
>>
>> I reworked this according to review by Jonathan, meaning that first I created
>> a no-op patch that will convert the driver to a more platform specific data
>> dedicated type of driver. This adds various structures that hold things like
>> register layout and channel information.
>> After this I created few patches that implement the main differences between
>> sama7g5 and older products: the end-of-conversion new register. I added
>> helper functions to make code more easy to read and more simple.
>> One the last patches adds the layout and channels for sama7g5.
>> At this moment in linux-next, the DT for sama7g5 and sama7g5ek is present,
>> and the last patches add and enable this node in DT for this board.
>>
>> Eugen
> 0-8 applied with the minor tweak mentioned in a reply to relevant patch.
> 
> I'll assume 9-10 will got via normal soc related tree.

Yep, we'll take them through at91 -> arm-soc trees...

> 
> Note that I'm queuing these up for the merge window after this one now
> (5.16).

Yes, soc/dt parts will be queued for 5.16 too.

Thanks Eugen, thanks Jonathan, best regards,
   Nicolas

>> Eugen Hristev (10):
>>    dt-bindings: iio: adc: at91-sama5d2: add compatible for sama7g5-adc
>>    iio: adc: at91-sama5d2_adc: initialize hardware after clock is started
>>    iio: adc: at91-sama5d2_adc: remove unused definition
>>    iio: adc: at91-sama5d2_adc: convert to platform specific data
>>      structures
>>    iio: adc: at91-sama5d2-adc: add support for separate end of conversion
>>      registers
>>    iio: adc: at91-sama5d2_adc: add helper for COR register
>>    iio: adc: at91-sama5d2_adc: add support for sama7g5 device
>>    iio: adc: at91-sama5d2_adc: update copyright and authors information
>>    ARM: dts: at91: sama7g5: add node for the ADC
>>    ARM: dts: at91: sama7g5ek: enable ADC on the board
>>
>>   .../bindings/iio/adc/atmel,sama5d2-adc.yaml   |   1 +
>>   arch/arm/boot/dts/at91-sama7g5ek.dts          |   8 +
>>   arch/arm/boot/dts/sama7g5.dtsi                |  16 +
>>   drivers/iio/adc/at91-sama5d2_adc.c            | 586 ++++++++++++------
>>   4 files changed, 425 insertions(+), 186 deletions(-)
>>
> 


-- 
Nicolas Ferre

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

* Re: [PATCH v2 00/10] iio: adc: at91-sama5d2_adc: add support for sama7g5
@ 2021-09-01  9:47     ` Nicolas Ferre
  0 siblings, 0 replies; 44+ messages in thread
From: Nicolas Ferre @ 2021-09-01  9:47 UTC (permalink / raw)
  To: Jonathan Cameron, Eugen Hristev
  Cc: linux-iio, devicetree, linux-arm-kernel, linux-kernel, robh+dt,
	ludovic.desroches

On 30/08/2021 at 14:26, Jonathan Cameron wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Tue, 24 Aug 2021 14:54:31 +0300
> Eugen Hristev <eugen.hristev@microchip.com> wrote:
> 
>> Hi,
>>
>> This series adds support for sama7g5.
>>
>> The sama7g5 is slightly different from sama5d2, but has the same basic
>> operations. The register map is a bit different, so, I added some primitives
>> to differentiate between the two classes of hardware blocks (sama5d2-sam9x60
>> and sama7g5).
>>
>> Sama7g5 has 16 channels ADC, no resistive touch, and extra features
>> (FIFOs, better oversampling , not implemented yet).
>>
>> It is a rework of the series initially sent here:
>> https://marc.info/?l=linux-iio&m=161461656807826&w=2
>>
>> I reworked this according to review by Jonathan, meaning that first I created
>> a no-op patch that will convert the driver to a more platform specific data
>> dedicated type of driver. This adds various structures that hold things like
>> register layout and channel information.
>> After this I created few patches that implement the main differences between
>> sama7g5 and older products: the end-of-conversion new register. I added
>> helper functions to make code more easy to read and more simple.
>> One the last patches adds the layout and channels for sama7g5.
>> At this moment in linux-next, the DT for sama7g5 and sama7g5ek is present,
>> and the last patches add and enable this node in DT for this board.
>>
>> Eugen
> 0-8 applied with the minor tweak mentioned in a reply to relevant patch.
> 
> I'll assume 9-10 will got via normal soc related tree.

Yep, we'll take them through at91 -> arm-soc trees...

> 
> Note that I'm queuing these up for the merge window after this one now
> (5.16).

Yes, soc/dt parts will be queued for 5.16 too.

Thanks Eugen, thanks Jonathan, best regards,
   Nicolas

>> Eugen Hristev (10):
>>    dt-bindings: iio: adc: at91-sama5d2: add compatible for sama7g5-adc
>>    iio: adc: at91-sama5d2_adc: initialize hardware after clock is started
>>    iio: adc: at91-sama5d2_adc: remove unused definition
>>    iio: adc: at91-sama5d2_adc: convert to platform specific data
>>      structures
>>    iio: adc: at91-sama5d2-adc: add support for separate end of conversion
>>      registers
>>    iio: adc: at91-sama5d2_adc: add helper for COR register
>>    iio: adc: at91-sama5d2_adc: add support for sama7g5 device
>>    iio: adc: at91-sama5d2_adc: update copyright and authors information
>>    ARM: dts: at91: sama7g5: add node for the ADC
>>    ARM: dts: at91: sama7g5ek: enable ADC on the board
>>
>>   .../bindings/iio/adc/atmel,sama5d2-adc.yaml   |   1 +
>>   arch/arm/boot/dts/at91-sama7g5ek.dts          |   8 +
>>   arch/arm/boot/dts/sama7g5.dtsi                |  16 +
>>   drivers/iio/adc/at91-sama5d2_adc.c            | 586 ++++++++++++------
>>   4 files changed, 425 insertions(+), 186 deletions(-)
>>
> 


-- 
Nicolas Ferre

_______________________________________________
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] 44+ messages in thread

* Re: [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform specific data structures
  2021-08-31 11:50         ` Eugen.Hristev
@ 2021-09-05 10:08           ` Jonathan Cameron
  -1 siblings, 0 replies; 44+ messages in thread
From: Jonathan Cameron @ 2021-09-05 10:08 UTC (permalink / raw)
  To: Eugen.Hristev
  Cc: linux-iio, devicetree, Nicolas.Ferre, linux-arm-kernel,
	linux-kernel, robh+dt, Ludovic.Desroches

On Tue, 31 Aug 2021 11:50:00 +0000
<Eugen.Hristev@microchip.com> wrote:

> On 8/30/21 5:44 PM, Jonathan Cameron wrote:
> > On Mon, 30 Aug 2021 12:31:46 +0000
> > <Eugen.Hristev@microchip.com> wrote:
> >   
> >> On 8/24/21 2:54 PM, Eugen Hristev wrote:  
> >>> Convert the driver to platform specific structures. This means:
> >>> - create a register layout struct that will hold offsets for registers
> >>> - create a platform struct that will hold platform information (number of
> >>> channels, indexes for different channels and pointer to layout struct)
> >>> - convert specific macros that are platform dependent into platform variables
> >>>
> >>> This step is in fact a no-op, but allows the driver to be more flexible
> >>> and for future enhancement including adding new platforms that are partly
> >>> compatible with the current driver and differ slightly in register layout
> >>> or capabilities for example.
> >>>
> >>> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> >>> ---
> >>>    drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
> >>>    1 file changed, 247 insertions(+), 163 deletions(-)
> >>>
> >>> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> >>> index 9d71dcffcf93..8ede18b8d789 100644
> >>> --- a/drivers/iio/adc/at91-sama5d2_adc.c
> >>> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> >>> @@ -27,8 +27,9 @@
> >>>    #include <linux/pinctrl/consumer.h>
> >>>    #include <linux/regulator/consumer.h>
> >>>
> >>> +struct at91_adc_reg_layout {
> >>>    /* Control Register */
> >>> -#define AT91_SAMA5D2_CR            0x00
> >>> +   u16                             CR;
> >>>    /* Software Reset */
> >>>    #define   AT91_SAMA5D2_CR_SWRST           BIT(0)
> >>>    /* Start Conversion */
> >>> @@ -39,7 +40,7 @@
> >>>    #define   AT91_SAMA5D2_CR_CMPRST          BIT(4)
> >>>
> >>>    /* Mode Register */
> >>> -#define AT91_SAMA5D2_MR            0x04
> >>> +   u16                             MR;
> >>>    /* Trigger Selection */
> >>>    #define   AT91_SAMA5D2_MR_TRGSEL(v)       ((v) << 1)
> >>>    /* ADTRG */
> >>> @@ -82,19 +83,19 @@
> >>>    #define   AT91_SAMA5D2_MR_USEQ            BIT(31)
> >>>
> >>>    /* Channel Sequence Register 1 */
> >>> -#define AT91_SAMA5D2_SEQR1 0x08
> >>> +   u16                             SEQR1;
> >>>    /* Channel Sequence Register 2 */
> >>> -#define AT91_SAMA5D2_SEQR2 0x0c
> >>> +   u16                             SEQR2;
> >>>    /* Channel Enable Register */
> >>> -#define AT91_SAMA5D2_CHER  0x10
> >>> +   u16                             CHER;
> >>>    /* Channel Disable Register */
> >>> -#define AT91_SAMA5D2_CHDR  0x14
> >>> +   u16                             CHDR;
> >>>    /* Channel Status Register */
> >>> -#define AT91_SAMA5D2_CHSR  0x18
> >>> +   u16                             CHSR;
> >>>    /* Last Converted Data Register */
> >>> -#define AT91_SAMA5D2_LCDR  0x20
> >>> +   u16                             LCDR;
> >>>    /* Interrupt Enable Register */
> >>> -#define AT91_SAMA5D2_IER   0x24
> >>> +   u16                             IER;
> >>>    /* Interrupt Enable Register - TS X measurement ready */
> >>>    #define AT91_SAMA5D2_IER_XRDY   BIT(20)
> >>>    /* Interrupt Enable Register - TS Y measurement ready */
> >>> @@ -109,22 +110,23 @@
> >>>    #define AT91_SAMA5D2_IER_PEN    BIT(29)
> >>>    /* Interrupt Enable Register - No pen detect */
> >>>    #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
> >>> +
> >>>    /* Interrupt Disable Register */
> >>> -#define AT91_SAMA5D2_IDR   0x28
> >>> +   u16                             IDR;
> >>>    /* Interrupt Mask Register */
> >>> -#define AT91_SAMA5D2_IMR   0x2c
> >>> +   u16                             IMR;
> >>>    /* Interrupt Status Register */
> >>> -#define AT91_SAMA5D2_ISR   0x30
> >>> +   u16                             ISR;
> >>>    /* Interrupt Status Register - Pen touching sense status */
> >>>    #define AT91_SAMA5D2_ISR_PENS   BIT(31)
> >>>    /* Last Channel Trigger Mode Register */
> >>> -#define AT91_SAMA5D2_LCTMR 0x34
> >>> +   u16                             LCTMR;
> >>>    /* Last Channel Compare Window Register */
> >>> -#define AT91_SAMA5D2_LCCWR 0x38
> >>> +   u16                             LCCWR;
> >>>    /* Overrun Status Register */
> >>> -#define AT91_SAMA5D2_OVER  0x3c
> >>> +   u16                             OVER;
> >>>    /* Extended Mode Register */
> >>> -#define AT91_SAMA5D2_EMR   0x40
> >>> +   u16                             EMR;
> >>>    /* Extended Mode Register - Oversampling rate */
> >>>    #define AT91_SAMA5D2_EMR_OSR(V)                   ((V) << 16)
> >>>    #define AT91_SAMA5D2_EMR_OSR_MASK         GENMASK(17, 16)
> >>> @@ -134,22 +136,22 @@
> >>>
> >>>    /* Extended Mode Register - Averaging on single trigger event */
> >>>    #define AT91_SAMA5D2_EMR_ASTE(V)          ((V) << 20)
> >>> +
> >>>    /* Compare Window Register */
> >>> -#define AT91_SAMA5D2_CWR   0x44
> >>> +   u16                             CWR;
> >>>    /* Channel Gain Register */
> >>> -#define AT91_SAMA5D2_CGR   0x48
> >>> -
> >>> +   u16                             CGR;
> >>>    /* Channel Offset Register */
> >>> -#define AT91_SAMA5D2_COR   0x4c
> >>> +   u16                             COR;
> >>>    #define AT91_SAMA5D2_COR_DIFF_OFFSET      16
> >>>
> >>>    /* Analog Control Register */
> >>> -#define AT91_SAMA5D2_ACR   0x94
> >>> +   u16                             ACR;
> >>>    /* Analog Control Register - Pen detect sensitivity mask */
> >>>    #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
> >>>
> >>>    /* Touchscreen Mode Register */
> >>> -#define AT91_SAMA5D2_TSMR  0xb0
> >>> +   u16                             TSMR;
> >>>    /* Touchscreen Mode Register - No touch mode */
> >>>    #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
> >>>    /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
> >>> @@ -178,13 +180,13 @@
> >>>    #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
> >>>
> >>>    /* Touchscreen X Position Register */
> >>> -#define AT91_SAMA5D2_XPOSR 0xb4
> >>> +   u16                             XPOSR;
> >>>    /* Touchscreen Y Position Register */
> >>> -#define AT91_SAMA5D2_YPOSR 0xb8
> >>> +   u16                             YPOSR;
> >>>    /* Touchscreen Pressure Register */
> >>> -#define AT91_SAMA5D2_PRESSR        0xbc
> >>> +   u16                             PRESSR;
> >>>    /* Trigger Register */
> >>> -#define AT91_SAMA5D2_TRGR  0xc0
> >>> +   u16                             TRGR;
> >>>    /* Mask for TRGMOD field of TRGR register */
> >>>    #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
> >>>    /* No trigger, only software trigger can start conversions */
> >>> @@ -203,30 +205,52 @@
> >>>    #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
> >>>
> >>>    /* Correction Select Register */
> >>> -#define AT91_SAMA5D2_COSR  0xd0
> >>> +   u16                             COSR;
> >>>    /* Correction Value Register */
> >>> -#define AT91_SAMA5D2_CVR   0xd4
> >>> +   u16                             CVR;
> >>>    /* Channel Error Correction Register */
> >>> -#define AT91_SAMA5D2_CECR  0xd8
> >>> +   u16                             CECR;
> >>>    /* Write Protection Mode Register */
> >>> -#define AT91_SAMA5D2_WPMR  0xe4
> >>> +   u16                             WPMR;
> >>>    /* Write Protection Status Register */
> >>> -#define AT91_SAMA5D2_WPSR  0xe8
> >>> +   u16                             WPSR;
> >>>    /* Version Register */
> >>> -#define AT91_SAMA5D2_VERSION       0xfc
> >>> -
> >>> -#define AT91_SAMA5D2_HW_TRIG_CNT 3
> >>> -#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
> >>> -#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
> >>> -
> >>> -#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> >>> -                                    AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
> >>> +   u16                             VERSION;
> >>> +};
> >>>
> >>> -#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> >>> -                                    AT91_SAMA5D2_DIFF_CHAN_CNT * 2)  
> >>
> >> Hi Jonathan,
> >>
> >> While we are here, regarding the above line, I cannot tell why did I
> >> multiply by two the differential channel count. This makes some gaps in
> >> the number of channels when we put them all in the same table.
> >>
> >> I did not change this as it would break the ABI regarding the bindings
> >> for the touchscreen #adc-cells phandle references.  
> > 
> > Really?  Xlate is based off scan_index, not these values I think...  
> 
> I figured it out.
> 
> We have 12 single channels [0..11] then 6 differential [12, 14, 16, 18, 
> 20, 22] spaced by two, a timestamp [23], then we have the X channel 
> index at 24, Y at 25 and pressure are 26.
> 
> These are reflected in this file :
> 
> https://elixir.bootlin.com/linux/latest/source/include/dt-bindings/iio/adc/at91-sama5d2_adc.h
> 
> And the resistive touchscreen connects to the adc with these indexes.
> 
> And I realised why we have the padding/spaces.
> It was the original design of the driver, in the line which I 
> highlighted now below in the patch : (and I never changed this since 
> working on this driver, because it was a break of the ABI in channel 
> numbers ...)
> 
> 
> >   
> >>
> >> However, I am thinking if there was a reason for it or it was a slip
> >> when I initially wrote this.  
> > 
> > I've no idea :)  I can't immediately see why we'd need the padding.
> >   
> >>
> >> Do you think there is any reason to change it and tighten the holes in
> >> the indexes list ?  
> > 
> > I don't think it matters. As far as I can tell they are used mostly (possibly
> > entirely) for internal management and not exposed to any of the ABIs etc.
> > 
> > Jonathan
> >   
> >>
> >>
> >> Eugen
> >>  
> >>> -#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
> >>> -#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
> >>> -#define AT91_SAMA5D2_MAX_CHAN_IDX  AT91_SAMA5D2_TOUCH_P_CHAN_IDX
> >>> +static const struct at91_adc_reg_layout sama5d2_layout = {
> >>> +   .CR =                   0x00,
> >>> +   .MR =                   0x04,
> >>> +   .SEQR1 =                0x08,
> >>> +   .SEQR2 =                0x0c,
> >>> +   .CHER =                 0x10,
> >>> +   .CHDR =                 0x14,
> >>> +   .CHSR =                 0x18,
> >>> +   .LCDR =                 0x20,
> >>> +   .IER =                  0x24,
> >>> +   .IDR =                  0x28,
> >>> +   .IMR =                  0x2c,
> >>> +   .ISR =                  0x30,
> >>> +   .LCTMR =                0x34,
> >>> +   .LCCWR =                0x38,
> >>> +   .OVER =                 0x3c,
> >>> +   .EMR =                  0x40,
> >>> +   .CWR =                  0x44,
> >>> +   .CGR =                  0x48,
> >>> +   .COR =                  0x4c,
> >>> +   .ACR =                  0x94,
> >>> +   .TSMR =                 0xb0,
> >>> +   .XPOSR =                0xb4,
> >>> +   .YPOSR =                0xb8,
> >>> +   .PRESSR =               0xbc,
> >>> +   .TRGR =                 0xc0,
> >>> +   .COSR =                 0xd0,
> >>> +   .CVR =                  0xd4,
> >>> +   .CECR =                 0xd8,
> >>> +   .WPMR =                 0xe4,
> >>> +   .WPSR =                 0xe8,
> >>> +   .VERSION =              0xfc,
> >>> +};
> >>>
> >>>    #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
> >>>    #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
> >>> @@ -235,18 +259,6 @@
> >>>
> >>>    #define AT91_SAMA5D2_MAX_POS_BITS                 12
> >>>
> >>> -/*
> >>> - * Maximum number of bytes to hold conversion from all channels
> >>> - * without the timestamp.
> >>> - */
> >>> -#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> >>> -                                    AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
> >>> -
> >>> -/* This total must also include the timestamp */
> >>> -#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
> >>> -
> >>> -#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
> >>> -
> >>>    #define AT91_HWFIFO_MAX_SIZE_STR  "128"
> >>>    #define AT91_HWFIFO_MAX_SIZE              128
> >>>
> >>> @@ -255,12 +267,12 @@
> >>>    #define AT91_OSR_4SAMPLES         4
> >>>    #define AT91_OSR_16SAMPLES                16
> >>>
> >>> -#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)                                \
> >>> +#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)                 \
> >>>      {                                                               \
> >>>              .type = IIO_VOLTAGE,                                    \
> >>>              .channel = num,                                         \
> >>>              .address = addr,                                        \
> >>> -           .scan_index = num,                                      \
> >>> +           .scan_index = index,                                    \
> >>>              .scan_type = {                                          \
> >>>                      .sign = 'u',                                    \
> >>>                      .realbits = 14,                                 \
> >>> @@ -274,14 +286,14 @@
> >>>              .indexed = 1,                                           \
> >>>      }
> >>>
> >>> -#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)                            \
> >>> +#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)                     \
> >>>      {                                                               \
> >>>              .type = IIO_VOLTAGE,                                    \
> >>>              .differential = 1,                                      \
> >>>              .channel = num,                                         \
> >>>              .channel2 = num2,                                       \
> >>>              .address = addr,                                        \
> >>> -           .scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,       \  
> 
> Here it is: we always added num to the single channel count, but num 
> goes incrementally in steps of two : 0, 2, 4, 6, 8, 10

Ah. That makes sense.  Of course with a separate index value passed in we could
have broken that connection but meh it doesn't matter.  The ABI has always
allowed holes in scan_index so everything should just work even it if seems
a bit inelegant!

> 
> >>> +           .scan_index = index,                                    \
> >>>              .scan_type = {                                          \
> >>>                      .sign = 's',                                    \
> >>>                      .realbits = 14,                                 \
> >>> @@ -328,13 +340,48 @@
> >>>              .datasheet_name = name,                                 \
> >>>      }
> >>>
> >>> -#define at91_adc_readl(st, reg)            readl_relaxed(st->base + reg)
> >>> -#define at91_adc_writel(st, reg, val)      writel_relaxed(val, st->base + reg)
> >>> +#define at91_adc_readl(st, reg)                                            \
> >>> +   readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
> >>> +#define at91_adc_read_chan(st, reg)                                        \
> >>> +   readl_relaxed((st)->base + reg)
> >>> +#define at91_adc_writel(st, reg, val)                                      \
> >>> +   writel_relaxed(val, (st)->base + (st)->soc_info.platform->layout->reg)
> >>> +
> >>> +/**
> >>> + * struct at91_adc_platform - at91-sama5d2 platform information struct
> >>> + * @layout:                pointer to the reg layout struct
> >>> + * @adc_channels:  pointer to an array of channels for registering in
> >>> + *                 the iio subsystem
> >>> + * @nr_channels:   number of physical channels available
> >>> + * @touch_chan_x:  index of the touchscreen X channel
> >>> + * @touch_chan_y:  index of the touchscreen Y channel
> >>> + * @touch_chan_p:  index of the touchscreen P channel
> >>> + * @max_channels:  number of total channels
> >>> + * @hw_trig_cnt:   number of possible hardware triggers
> >>> + */
> >>> +struct at91_adc_platform {
> >>> +   const struct at91_adc_reg_layout        *layout;
> >>> +   const struct iio_chan_spec              (*adc_channels)[];
> >>> +   unsigned int                            nr_channels;
> >>> +   unsigned int                            touch_chan_x;
> >>> +   unsigned int                            touch_chan_y;
> >>> +   unsigned int                            touch_chan_p;
> >>> +   unsigned int                            max_channels;
> >>> +   unsigned int                            hw_trig_cnt;
> >>> +};
> >>>
> >>> +/**
> >>> + * struct at91_adc_soc_info - at91-sama5d2 soc information struct
> >>> + * @startup_time:  device startup time
> >>> + * @min_sample_rate:       minimum sample rate in Hz
> >>> + * @max_sample_rate:       maximum sample rate in Hz
> >>> + * @platform:              pointer to the platform structure
> >>> + */
> >>>    struct at91_adc_soc_info {
> >>>      unsigned                        startup_time;
> >>>      unsigned                        min_sample_rate;
> >>>      unsigned                        max_sample_rate;
> >>> +   const struct at91_adc_platform  *platform;
> >>>    };
> >>>
> >>>    struct at91_adc_trigger {
> >>> @@ -382,6 +429,15 @@ struct at91_adc_touch {
> >>>      struct work_struct              workq;
> >>>    };
> >>>
> >>> +/*
> >>> + * Buffer size requirements:
> >>> + * No channels * bytes_per_channel(2) + timestamp bytes (8)
> >>> + * Divided by 2 because we need half words.
> >>> + * We assume 32 channels for now, has to be increased if needed.
> >>> + * Nobody minds a buffer being too big.
> >>> + */
> >>> +#define AT91_BUFFER_MAX_HWORDS ((32 * 2 + 8) / 2)
> >>> +
> >>>    struct at91_adc_state {
> >>>      void __iomem                    *base;
> >>>      int                             irq;
> >>> @@ -437,29 +493,49 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = {
> >>>      },
> >>>    };
> >>>
> >>> -static const struct iio_chan_spec at91_adc_channels[] = {
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(0, 0x50),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(1, 0x54),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(2, 0x58),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(3, 0x5c),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(4, 0x60),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(5, 0x64),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(6, 0x68),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(7, 0x6c),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(8, 0x70),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(9, 0x74),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(10, 0x78),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(11, 0x7c),
> >>> -   AT91_SAMA5D2_CHAN_DIFF(0, 1, 0x50),
> >>> -   AT91_SAMA5D2_CHAN_DIFF(2, 3, 0x58),
> >>> -   AT91_SAMA5D2_CHAN_DIFF(4, 5, 0x60),
> >>> -   AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68),
> >>> -   AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70),
> >>> -   AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78),  
> 
> you can see it here,
> 
> >>> -   IIO_CHAN_SOFT_TIMESTAMP(AT91_SAMA5D2_TIMESTAMP_CHAN_IDX),
> >>> -   AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_X_CHAN_IDX, "x", IIO_MOD_X),
> >>> -   AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, "y", IIO_MOD_Y),
> >>> -   AT91_SAMA5D2_CHAN_PRESSURE(AT91_SAMA5D2_TOUCH_P_CHAN_IDX, "pressure"),
> >>> +static const struct iio_chan_spec at91_sama5d2_adc_channels[] = {
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(0, 0, 0x50),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(1, 1, 0x54),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(2, 2, 0x58),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(3, 3, 0x5c),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(4, 4, 0x60),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(5, 5, 0x64),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(6, 6, 0x68),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(7, 7, 0x6c),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(8, 8, 0x70),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(9, 9, 0x74),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(10, 10, 0x78),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x7c),
> >>> +   AT91_SAMA5D2_CHAN_DIFF(12, 0, 1, 0x50),
> >>> +   AT91_SAMA5D2_CHAN_DIFF(13, 2, 3, 0x58),
> >>> +   AT91_SAMA5D2_CHAN_DIFF(14, 4, 5, 0x60),
> >>> +   AT91_SAMA5D2_CHAN_DIFF(15, 6, 7, 0x68),
> >>> +   AT91_SAMA5D2_CHAN_DIFF(16, 8, 9, 0x70),
> >>> +   AT91_SAMA5D2_CHAN_DIFF(17, 10, 11, 0x78),
> >>> +   IIO_CHAN_SOFT_TIMESTAMP(18),
> >>> +   AT91_SAMA5D2_CHAN_TOUCH(19, "x", IIO_MOD_X),
> >>> +   AT91_SAMA5D2_CHAN_TOUCH(20, "y", IIO_MOD_Y),
> >>> +   AT91_SAMA5D2_CHAN_PRESSURE(21, "pressure"),  
> 
> And I have to come up with a new version of the patch to fix this.
> 
> It should be like this:
> 
> 
>  >>> +   AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x7c),
>  >>> +   AT91_SAMA5D2_CHAN_DIFF(12, 0, 1, 0x50),
>  >>> +   AT91_SAMA5D2_CHAN_DIFF(14, 2, 3, 0x58),
>  >>> +   AT91_SAMA5D2_CHAN_DIFF(16, 4, 5, 0x60),
>  >>> +   AT91_SAMA5D2_CHAN_DIFF(18, 6, 7, 0x68),
>  >>> +   AT91_SAMA5D2_CHAN_DIFF(20, 8, 9, 0x70),
>  >>> +   AT91_SAMA5D2_CHAN_DIFF(22, 10, 11, 0x78),
>  >>> +   IIO_CHAN_SOFT_TIMESTAMP(23),
>  >>> +   AT91_SAMA5D2_CHAN_TOUCH(24, "x", IIO_MOD_X),
>  >>> +   AT91_SAMA5D2_CHAN_TOUCH(25, "y", IIO_MOD_Y),
>  >>> +   AT91_SAMA5D2_CHAN_PRESSURE(26, "pressure"),  
> 
> 
> Sorry about this. Do you want me to resend the whole series together 
> with the fixes found by robots ?
> 
> I can redo the series, retest it, and send it tomorrow as a v3.

Please do (looks like you already did ;) 
> 
> 
> Thanks,
> Eugen
> 
> >>> +};
> >>> +  
> [snip]


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

* Re: [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform specific data structures
@ 2021-09-05 10:08           ` Jonathan Cameron
  0 siblings, 0 replies; 44+ messages in thread
From: Jonathan Cameron @ 2021-09-05 10:08 UTC (permalink / raw)
  To: Eugen.Hristev
  Cc: devicetree, linux-iio, linux-kernel, Ludovic.Desroches, robh+dt,
	linux-arm-kernel

On Tue, 31 Aug 2021 11:50:00 +0000
<Eugen.Hristev@microchip.com> wrote:

> On 8/30/21 5:44 PM, Jonathan Cameron wrote:
> > On Mon, 30 Aug 2021 12:31:46 +0000
> > <Eugen.Hristev@microchip.com> wrote:
> >   
> >> On 8/24/21 2:54 PM, Eugen Hristev wrote:  
> >>> Convert the driver to platform specific structures. This means:
> >>> - create a register layout struct that will hold offsets for registers
> >>> - create a platform struct that will hold platform information (number of
> >>> channels, indexes for different channels and pointer to layout struct)
> >>> - convert specific macros that are platform dependent into platform variables
> >>>
> >>> This step is in fact a no-op, but allows the driver to be more flexible
> >>> and for future enhancement including adding new platforms that are partly
> >>> compatible with the current driver and differ slightly in register layout
> >>> or capabilities for example.
> >>>
> >>> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> >>> ---
> >>>    drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
> >>>    1 file changed, 247 insertions(+), 163 deletions(-)
> >>>
> >>> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> >>> index 9d71dcffcf93..8ede18b8d789 100644
> >>> --- a/drivers/iio/adc/at91-sama5d2_adc.c
> >>> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> >>> @@ -27,8 +27,9 @@
> >>>    #include <linux/pinctrl/consumer.h>
> >>>    #include <linux/regulator/consumer.h>
> >>>
> >>> +struct at91_adc_reg_layout {
> >>>    /* Control Register */
> >>> -#define AT91_SAMA5D2_CR            0x00
> >>> +   u16                             CR;
> >>>    /* Software Reset */
> >>>    #define   AT91_SAMA5D2_CR_SWRST           BIT(0)
> >>>    /* Start Conversion */
> >>> @@ -39,7 +40,7 @@
> >>>    #define   AT91_SAMA5D2_CR_CMPRST          BIT(4)
> >>>
> >>>    /* Mode Register */
> >>> -#define AT91_SAMA5D2_MR            0x04
> >>> +   u16                             MR;
> >>>    /* Trigger Selection */
> >>>    #define   AT91_SAMA5D2_MR_TRGSEL(v)       ((v) << 1)
> >>>    /* ADTRG */
> >>> @@ -82,19 +83,19 @@
> >>>    #define   AT91_SAMA5D2_MR_USEQ            BIT(31)
> >>>
> >>>    /* Channel Sequence Register 1 */
> >>> -#define AT91_SAMA5D2_SEQR1 0x08
> >>> +   u16                             SEQR1;
> >>>    /* Channel Sequence Register 2 */
> >>> -#define AT91_SAMA5D2_SEQR2 0x0c
> >>> +   u16                             SEQR2;
> >>>    /* Channel Enable Register */
> >>> -#define AT91_SAMA5D2_CHER  0x10
> >>> +   u16                             CHER;
> >>>    /* Channel Disable Register */
> >>> -#define AT91_SAMA5D2_CHDR  0x14
> >>> +   u16                             CHDR;
> >>>    /* Channel Status Register */
> >>> -#define AT91_SAMA5D2_CHSR  0x18
> >>> +   u16                             CHSR;
> >>>    /* Last Converted Data Register */
> >>> -#define AT91_SAMA5D2_LCDR  0x20
> >>> +   u16                             LCDR;
> >>>    /* Interrupt Enable Register */
> >>> -#define AT91_SAMA5D2_IER   0x24
> >>> +   u16                             IER;
> >>>    /* Interrupt Enable Register - TS X measurement ready */
> >>>    #define AT91_SAMA5D2_IER_XRDY   BIT(20)
> >>>    /* Interrupt Enable Register - TS Y measurement ready */
> >>> @@ -109,22 +110,23 @@
> >>>    #define AT91_SAMA5D2_IER_PEN    BIT(29)
> >>>    /* Interrupt Enable Register - No pen detect */
> >>>    #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
> >>> +
> >>>    /* Interrupt Disable Register */
> >>> -#define AT91_SAMA5D2_IDR   0x28
> >>> +   u16                             IDR;
> >>>    /* Interrupt Mask Register */
> >>> -#define AT91_SAMA5D2_IMR   0x2c
> >>> +   u16                             IMR;
> >>>    /* Interrupt Status Register */
> >>> -#define AT91_SAMA5D2_ISR   0x30
> >>> +   u16                             ISR;
> >>>    /* Interrupt Status Register - Pen touching sense status */
> >>>    #define AT91_SAMA5D2_ISR_PENS   BIT(31)
> >>>    /* Last Channel Trigger Mode Register */
> >>> -#define AT91_SAMA5D2_LCTMR 0x34
> >>> +   u16                             LCTMR;
> >>>    /* Last Channel Compare Window Register */
> >>> -#define AT91_SAMA5D2_LCCWR 0x38
> >>> +   u16                             LCCWR;
> >>>    /* Overrun Status Register */
> >>> -#define AT91_SAMA5D2_OVER  0x3c
> >>> +   u16                             OVER;
> >>>    /* Extended Mode Register */
> >>> -#define AT91_SAMA5D2_EMR   0x40
> >>> +   u16                             EMR;
> >>>    /* Extended Mode Register - Oversampling rate */
> >>>    #define AT91_SAMA5D2_EMR_OSR(V)                   ((V) << 16)
> >>>    #define AT91_SAMA5D2_EMR_OSR_MASK         GENMASK(17, 16)
> >>> @@ -134,22 +136,22 @@
> >>>
> >>>    /* Extended Mode Register - Averaging on single trigger event */
> >>>    #define AT91_SAMA5D2_EMR_ASTE(V)          ((V) << 20)
> >>> +
> >>>    /* Compare Window Register */
> >>> -#define AT91_SAMA5D2_CWR   0x44
> >>> +   u16                             CWR;
> >>>    /* Channel Gain Register */
> >>> -#define AT91_SAMA5D2_CGR   0x48
> >>> -
> >>> +   u16                             CGR;
> >>>    /* Channel Offset Register */
> >>> -#define AT91_SAMA5D2_COR   0x4c
> >>> +   u16                             COR;
> >>>    #define AT91_SAMA5D2_COR_DIFF_OFFSET      16
> >>>
> >>>    /* Analog Control Register */
> >>> -#define AT91_SAMA5D2_ACR   0x94
> >>> +   u16                             ACR;
> >>>    /* Analog Control Register - Pen detect sensitivity mask */
> >>>    #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
> >>>
> >>>    /* Touchscreen Mode Register */
> >>> -#define AT91_SAMA5D2_TSMR  0xb0
> >>> +   u16                             TSMR;
> >>>    /* Touchscreen Mode Register - No touch mode */
> >>>    #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
> >>>    /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
> >>> @@ -178,13 +180,13 @@
> >>>    #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
> >>>
> >>>    /* Touchscreen X Position Register */
> >>> -#define AT91_SAMA5D2_XPOSR 0xb4
> >>> +   u16                             XPOSR;
> >>>    /* Touchscreen Y Position Register */
> >>> -#define AT91_SAMA5D2_YPOSR 0xb8
> >>> +   u16                             YPOSR;
> >>>    /* Touchscreen Pressure Register */
> >>> -#define AT91_SAMA5D2_PRESSR        0xbc
> >>> +   u16                             PRESSR;
> >>>    /* Trigger Register */
> >>> -#define AT91_SAMA5D2_TRGR  0xc0
> >>> +   u16                             TRGR;
> >>>    /* Mask for TRGMOD field of TRGR register */
> >>>    #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
> >>>    /* No trigger, only software trigger can start conversions */
> >>> @@ -203,30 +205,52 @@
> >>>    #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
> >>>
> >>>    /* Correction Select Register */
> >>> -#define AT91_SAMA5D2_COSR  0xd0
> >>> +   u16                             COSR;
> >>>    /* Correction Value Register */
> >>> -#define AT91_SAMA5D2_CVR   0xd4
> >>> +   u16                             CVR;
> >>>    /* Channel Error Correction Register */
> >>> -#define AT91_SAMA5D2_CECR  0xd8
> >>> +   u16                             CECR;
> >>>    /* Write Protection Mode Register */
> >>> -#define AT91_SAMA5D2_WPMR  0xe4
> >>> +   u16                             WPMR;
> >>>    /* Write Protection Status Register */
> >>> -#define AT91_SAMA5D2_WPSR  0xe8
> >>> +   u16                             WPSR;
> >>>    /* Version Register */
> >>> -#define AT91_SAMA5D2_VERSION       0xfc
> >>> -
> >>> -#define AT91_SAMA5D2_HW_TRIG_CNT 3
> >>> -#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
> >>> -#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
> >>> -
> >>> -#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> >>> -                                    AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
> >>> +   u16                             VERSION;
> >>> +};
> >>>
> >>> -#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> >>> -                                    AT91_SAMA5D2_DIFF_CHAN_CNT * 2)  
> >>
> >> Hi Jonathan,
> >>
> >> While we are here, regarding the above line, I cannot tell why did I
> >> multiply by two the differential channel count. This makes some gaps in
> >> the number of channels when we put them all in the same table.
> >>
> >> I did not change this as it would break the ABI regarding the bindings
> >> for the touchscreen #adc-cells phandle references.  
> > 
> > Really?  Xlate is based off scan_index, not these values I think...  
> 
> I figured it out.
> 
> We have 12 single channels [0..11] then 6 differential [12, 14, 16, 18, 
> 20, 22] spaced by two, a timestamp [23], then we have the X channel 
> index at 24, Y at 25 and pressure are 26.
> 
> These are reflected in this file :
> 
> https://elixir.bootlin.com/linux/latest/source/include/dt-bindings/iio/adc/at91-sama5d2_adc.h
> 
> And the resistive touchscreen connects to the adc with these indexes.
> 
> And I realised why we have the padding/spaces.
> It was the original design of the driver, in the line which I 
> highlighted now below in the patch : (and I never changed this since 
> working on this driver, because it was a break of the ABI in channel 
> numbers ...)
> 
> 
> >   
> >>
> >> However, I am thinking if there was a reason for it or it was a slip
> >> when I initially wrote this.  
> > 
> > I've no idea :)  I can't immediately see why we'd need the padding.
> >   
> >>
> >> Do you think there is any reason to change it and tighten the holes in
> >> the indexes list ?  
> > 
> > I don't think it matters. As far as I can tell they are used mostly (possibly
> > entirely) for internal management and not exposed to any of the ABIs etc.
> > 
> > Jonathan
> >   
> >>
> >>
> >> Eugen
> >>  
> >>> -#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
> >>> -#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
> >>> -#define AT91_SAMA5D2_MAX_CHAN_IDX  AT91_SAMA5D2_TOUCH_P_CHAN_IDX
> >>> +static const struct at91_adc_reg_layout sama5d2_layout = {
> >>> +   .CR =                   0x00,
> >>> +   .MR =                   0x04,
> >>> +   .SEQR1 =                0x08,
> >>> +   .SEQR2 =                0x0c,
> >>> +   .CHER =                 0x10,
> >>> +   .CHDR =                 0x14,
> >>> +   .CHSR =                 0x18,
> >>> +   .LCDR =                 0x20,
> >>> +   .IER =                  0x24,
> >>> +   .IDR =                  0x28,
> >>> +   .IMR =                  0x2c,
> >>> +   .ISR =                  0x30,
> >>> +   .LCTMR =                0x34,
> >>> +   .LCCWR =                0x38,
> >>> +   .OVER =                 0x3c,
> >>> +   .EMR =                  0x40,
> >>> +   .CWR =                  0x44,
> >>> +   .CGR =                  0x48,
> >>> +   .COR =                  0x4c,
> >>> +   .ACR =                  0x94,
> >>> +   .TSMR =                 0xb0,
> >>> +   .XPOSR =                0xb4,
> >>> +   .YPOSR =                0xb8,
> >>> +   .PRESSR =               0xbc,
> >>> +   .TRGR =                 0xc0,
> >>> +   .COSR =                 0xd0,
> >>> +   .CVR =                  0xd4,
> >>> +   .CECR =                 0xd8,
> >>> +   .WPMR =                 0xe4,
> >>> +   .WPSR =                 0xe8,
> >>> +   .VERSION =              0xfc,
> >>> +};
> >>>
> >>>    #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
> >>>    #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
> >>> @@ -235,18 +259,6 @@
> >>>
> >>>    #define AT91_SAMA5D2_MAX_POS_BITS                 12
> >>>
> >>> -/*
> >>> - * Maximum number of bytes to hold conversion from all channels
> >>> - * without the timestamp.
> >>> - */
> >>> -#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> >>> -                                    AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
> >>> -
> >>> -/* This total must also include the timestamp */
> >>> -#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
> >>> -
> >>> -#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
> >>> -
> >>>    #define AT91_HWFIFO_MAX_SIZE_STR  "128"
> >>>    #define AT91_HWFIFO_MAX_SIZE              128
> >>>
> >>> @@ -255,12 +267,12 @@
> >>>    #define AT91_OSR_4SAMPLES         4
> >>>    #define AT91_OSR_16SAMPLES                16
> >>>
> >>> -#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)                                \
> >>> +#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)                 \
> >>>      {                                                               \
> >>>              .type = IIO_VOLTAGE,                                    \
> >>>              .channel = num,                                         \
> >>>              .address = addr,                                        \
> >>> -           .scan_index = num,                                      \
> >>> +           .scan_index = index,                                    \
> >>>              .scan_type = {                                          \
> >>>                      .sign = 'u',                                    \
> >>>                      .realbits = 14,                                 \
> >>> @@ -274,14 +286,14 @@
> >>>              .indexed = 1,                                           \
> >>>      }
> >>>
> >>> -#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)                            \
> >>> +#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)                     \
> >>>      {                                                               \
> >>>              .type = IIO_VOLTAGE,                                    \
> >>>              .differential = 1,                                      \
> >>>              .channel = num,                                         \
> >>>              .channel2 = num2,                                       \
> >>>              .address = addr,                                        \
> >>> -           .scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,       \  
> 
> Here it is: we always added num to the single channel count, but num 
> goes incrementally in steps of two : 0, 2, 4, 6, 8, 10

Ah. That makes sense.  Of course with a separate index value passed in we could
have broken that connection but meh it doesn't matter.  The ABI has always
allowed holes in scan_index so everything should just work even it if seems
a bit inelegant!

> 
> >>> +           .scan_index = index,                                    \
> >>>              .scan_type = {                                          \
> >>>                      .sign = 's',                                    \
> >>>                      .realbits = 14,                                 \
> >>> @@ -328,13 +340,48 @@
> >>>              .datasheet_name = name,                                 \
> >>>      }
> >>>
> >>> -#define at91_adc_readl(st, reg)            readl_relaxed(st->base + reg)
> >>> -#define at91_adc_writel(st, reg, val)      writel_relaxed(val, st->base + reg)
> >>> +#define at91_adc_readl(st, reg)                                            \
> >>> +   readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
> >>> +#define at91_adc_read_chan(st, reg)                                        \
> >>> +   readl_relaxed((st)->base + reg)
> >>> +#define at91_adc_writel(st, reg, val)                                      \
> >>> +   writel_relaxed(val, (st)->base + (st)->soc_info.platform->layout->reg)
> >>> +
> >>> +/**
> >>> + * struct at91_adc_platform - at91-sama5d2 platform information struct
> >>> + * @layout:                pointer to the reg layout struct
> >>> + * @adc_channels:  pointer to an array of channels for registering in
> >>> + *                 the iio subsystem
> >>> + * @nr_channels:   number of physical channels available
> >>> + * @touch_chan_x:  index of the touchscreen X channel
> >>> + * @touch_chan_y:  index of the touchscreen Y channel
> >>> + * @touch_chan_p:  index of the touchscreen P channel
> >>> + * @max_channels:  number of total channels
> >>> + * @hw_trig_cnt:   number of possible hardware triggers
> >>> + */
> >>> +struct at91_adc_platform {
> >>> +   const struct at91_adc_reg_layout        *layout;
> >>> +   const struct iio_chan_spec              (*adc_channels)[];
> >>> +   unsigned int                            nr_channels;
> >>> +   unsigned int                            touch_chan_x;
> >>> +   unsigned int                            touch_chan_y;
> >>> +   unsigned int                            touch_chan_p;
> >>> +   unsigned int                            max_channels;
> >>> +   unsigned int                            hw_trig_cnt;
> >>> +};
> >>>
> >>> +/**
> >>> + * struct at91_adc_soc_info - at91-sama5d2 soc information struct
> >>> + * @startup_time:  device startup time
> >>> + * @min_sample_rate:       minimum sample rate in Hz
> >>> + * @max_sample_rate:       maximum sample rate in Hz
> >>> + * @platform:              pointer to the platform structure
> >>> + */
> >>>    struct at91_adc_soc_info {
> >>>      unsigned                        startup_time;
> >>>      unsigned                        min_sample_rate;
> >>>      unsigned                        max_sample_rate;
> >>> +   const struct at91_adc_platform  *platform;
> >>>    };
> >>>
> >>>    struct at91_adc_trigger {
> >>> @@ -382,6 +429,15 @@ struct at91_adc_touch {
> >>>      struct work_struct              workq;
> >>>    };
> >>>
> >>> +/*
> >>> + * Buffer size requirements:
> >>> + * No channels * bytes_per_channel(2) + timestamp bytes (8)
> >>> + * Divided by 2 because we need half words.
> >>> + * We assume 32 channels for now, has to be increased if needed.
> >>> + * Nobody minds a buffer being too big.
> >>> + */
> >>> +#define AT91_BUFFER_MAX_HWORDS ((32 * 2 + 8) / 2)
> >>> +
> >>>    struct at91_adc_state {
> >>>      void __iomem                    *base;
> >>>      int                             irq;
> >>> @@ -437,29 +493,49 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = {
> >>>      },
> >>>    };
> >>>
> >>> -static const struct iio_chan_spec at91_adc_channels[] = {
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(0, 0x50),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(1, 0x54),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(2, 0x58),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(3, 0x5c),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(4, 0x60),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(5, 0x64),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(6, 0x68),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(7, 0x6c),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(8, 0x70),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(9, 0x74),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(10, 0x78),
> >>> -   AT91_SAMA5D2_CHAN_SINGLE(11, 0x7c),
> >>> -   AT91_SAMA5D2_CHAN_DIFF(0, 1, 0x50),
> >>> -   AT91_SAMA5D2_CHAN_DIFF(2, 3, 0x58),
> >>> -   AT91_SAMA5D2_CHAN_DIFF(4, 5, 0x60),
> >>> -   AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68),
> >>> -   AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70),
> >>> -   AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78),  
> 
> you can see it here,
> 
> >>> -   IIO_CHAN_SOFT_TIMESTAMP(AT91_SAMA5D2_TIMESTAMP_CHAN_IDX),
> >>> -   AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_X_CHAN_IDX, "x", IIO_MOD_X),
> >>> -   AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, "y", IIO_MOD_Y),
> >>> -   AT91_SAMA5D2_CHAN_PRESSURE(AT91_SAMA5D2_TOUCH_P_CHAN_IDX, "pressure"),
> >>> +static const struct iio_chan_spec at91_sama5d2_adc_channels[] = {
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(0, 0, 0x50),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(1, 1, 0x54),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(2, 2, 0x58),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(3, 3, 0x5c),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(4, 4, 0x60),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(5, 5, 0x64),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(6, 6, 0x68),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(7, 7, 0x6c),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(8, 8, 0x70),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(9, 9, 0x74),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(10, 10, 0x78),
> >>> +   AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x7c),
> >>> +   AT91_SAMA5D2_CHAN_DIFF(12, 0, 1, 0x50),
> >>> +   AT91_SAMA5D2_CHAN_DIFF(13, 2, 3, 0x58),
> >>> +   AT91_SAMA5D2_CHAN_DIFF(14, 4, 5, 0x60),
> >>> +   AT91_SAMA5D2_CHAN_DIFF(15, 6, 7, 0x68),
> >>> +   AT91_SAMA5D2_CHAN_DIFF(16, 8, 9, 0x70),
> >>> +   AT91_SAMA5D2_CHAN_DIFF(17, 10, 11, 0x78),
> >>> +   IIO_CHAN_SOFT_TIMESTAMP(18),
> >>> +   AT91_SAMA5D2_CHAN_TOUCH(19, "x", IIO_MOD_X),
> >>> +   AT91_SAMA5D2_CHAN_TOUCH(20, "y", IIO_MOD_Y),
> >>> +   AT91_SAMA5D2_CHAN_PRESSURE(21, "pressure"),  
> 
> And I have to come up with a new version of the patch to fix this.
> 
> It should be like this:
> 
> 
>  >>> +   AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x7c),
>  >>> +   AT91_SAMA5D2_CHAN_DIFF(12, 0, 1, 0x50),
>  >>> +   AT91_SAMA5D2_CHAN_DIFF(14, 2, 3, 0x58),
>  >>> +   AT91_SAMA5D2_CHAN_DIFF(16, 4, 5, 0x60),
>  >>> +   AT91_SAMA5D2_CHAN_DIFF(18, 6, 7, 0x68),
>  >>> +   AT91_SAMA5D2_CHAN_DIFF(20, 8, 9, 0x70),
>  >>> +   AT91_SAMA5D2_CHAN_DIFF(22, 10, 11, 0x78),
>  >>> +   IIO_CHAN_SOFT_TIMESTAMP(23),
>  >>> +   AT91_SAMA5D2_CHAN_TOUCH(24, "x", IIO_MOD_X),
>  >>> +   AT91_SAMA5D2_CHAN_TOUCH(25, "y", IIO_MOD_Y),
>  >>> +   AT91_SAMA5D2_CHAN_PRESSURE(26, "pressure"),  
> 
> 
> Sorry about this. Do you want me to resend the whole series together 
> with the fixes found by robots ?
> 
> I can redo the series, retest it, and send it tomorrow as a v3.

Please do (looks like you already did ;) 
> 
> 
> Thanks,
> Eugen
> 
> >>> +};
> >>> +  
> [snip]


_______________________________________________
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] 44+ messages in thread

* Re: [PATCH v2 05/10] iio: adc: at91-sama5d2-adc: add support for separate end of conversion registers
  2021-08-31  6:45     ` Eugen.Hristev
@ 2021-09-05 10:12       ` Jonathan Cameron
  -1 siblings, 0 replies; 44+ messages in thread
From: Jonathan Cameron @ 2021-09-05 10:12 UTC (permalink / raw)
  To: Eugen.Hristev
  Cc: linux-iio, devicetree, Nicolas.Ferre, linux-arm-kernel,
	linux-kernel, robh+dt, Ludovic.Desroches

On Tue, 31 Aug 2021 06:45:01 +0000
<Eugen.Hristev@microchip.com> wrote:

> On 8/24/21 2:54 PM, Eugen Hristev wrote:
> > Some platforms have separated the end-of-conversion information from the
> > usual ISR/IMR/IER/IDR registers, into EOC_ISR/EOC_IMR/EOC_IER/EOC_IDR.
> > To cope with both variants, helpers are being added, that will make
> > code more clear and more easy to read.
> > 
> > Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> > ---  
> 
> Hi Jonathan,
> 
> If you can still make changes on your testing branch, I noticed a typo 
> in the shortcommit of this patch : 'at91-sama5d2-adc' instead of 
> 'at91-sama5d2_adc' , grepping through commits in the future might miss 
> this patch, so maybe you can change it ?
Testing is very much rebaseable.  I won't push the tree out as something
I'm not happy to rebase until I have a stable base for it (after rc1).

So dropped v2. I'll get to v3 a bit later today probably.

Jonathan

> 
> Thanks,
> Eugen


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

* Re: [PATCH v2 05/10] iio: adc: at91-sama5d2-adc: add support for separate end of conversion registers
@ 2021-09-05 10:12       ` Jonathan Cameron
  0 siblings, 0 replies; 44+ messages in thread
From: Jonathan Cameron @ 2021-09-05 10:12 UTC (permalink / raw)
  To: Eugen.Hristev
  Cc: devicetree, linux-iio, linux-kernel, Ludovic.Desroches, robh+dt,
	linux-arm-kernel

On Tue, 31 Aug 2021 06:45:01 +0000
<Eugen.Hristev@microchip.com> wrote:

> On 8/24/21 2:54 PM, Eugen Hristev wrote:
> > Some platforms have separated the end-of-conversion information from the
> > usual ISR/IMR/IER/IDR registers, into EOC_ISR/EOC_IMR/EOC_IER/EOC_IDR.
> > To cope with both variants, helpers are being added, that will make
> > code more clear and more easy to read.
> > 
> > Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> > ---  
> 
> Hi Jonathan,
> 
> If you can still make changes on your testing branch, I noticed a typo 
> in the shortcommit of this patch : 'at91-sama5d2-adc' instead of 
> 'at91-sama5d2_adc' , grepping through commits in the future might miss 
> this patch, so maybe you can change it ?
Testing is very much rebaseable.  I won't push the tree out as something
I'm not happy to rebase until I have a stable base for it (after rc1).

So dropped v2. I'll get to v3 a bit later today probably.

Jonathan

> 
> Thanks,
> Eugen


_______________________________________________
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] 44+ messages in thread

end of thread, other threads:[~2021-09-05 10:11 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-24 11:54 [PATCH v2 00/10] iio: adc: at91-sama5d2_adc: add support for sama7g5 Eugen Hristev
2021-08-24 11:54 ` Eugen Hristev
2021-08-24 11:54 ` [PATCH v2 01/10] dt-bindings: iio: adc: at91-sama5d2: add compatible for sama7g5-adc Eugen Hristev
2021-08-24 11:54   ` Eugen Hristev
2021-08-24 11:54 ` [PATCH v2 02/10] iio: adc: at91-sama5d2_adc: initialize hardware after clock is started Eugen Hristev
2021-08-24 11:54   ` Eugen Hristev
2021-08-24 11:54 ` [PATCH v2 03/10] iio: adc: at91-sama5d2_adc: remove unused definition Eugen Hristev
2021-08-24 11:54   ` Eugen Hristev
2021-08-24 11:54 ` [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform specific data structures Eugen Hristev
2021-08-24 11:54   ` Eugen Hristev
2021-08-30 12:21   ` Jonathan Cameron
2021-08-30 12:21     ` Jonathan Cameron
2021-08-30 12:28     ` Eugen.Hristev
2021-08-30 12:28       ` Eugen.Hristev
2021-08-30 12:31   ` Eugen.Hristev
2021-08-30 12:31     ` Eugen.Hristev
2021-08-30 14:44     ` Jonathan Cameron
2021-08-30 14:44       ` Jonathan Cameron
2021-08-31 11:50       ` Eugen.Hristev
2021-08-31 11:50         ` Eugen.Hristev
2021-09-05 10:08         ` Jonathan Cameron
2021-09-05 10:08           ` Jonathan Cameron
2021-08-24 11:54 ` [PATCH v2 05/10] iio: adc: at91-sama5d2-adc: add support for separate end of conversion registers Eugen Hristev
2021-08-24 11:54   ` Eugen Hristev
2021-08-31  6:45   ` Eugen.Hristev
2021-08-31  6:45     ` Eugen.Hristev
2021-09-05 10:12     ` Jonathan Cameron
2021-09-05 10:12       ` Jonathan Cameron
2021-08-24 11:54 ` [PATCH v2 06/10] iio: adc: at91-sama5d2_adc: add helper for COR register Eugen Hristev
2021-08-24 11:54   ` Eugen Hristev
2021-08-30 12:18   ` Jonathan Cameron
2021-08-30 12:18     ` Jonathan Cameron
2021-08-24 11:54 ` [PATCH v2 07/10] iio: adc: at91-sama5d2_adc: add support for sama7g5 device Eugen Hristev
2021-08-24 11:54   ` Eugen Hristev
2021-08-24 11:54 ` [PATCH v2 08/10] iio: adc: at91-sama5d2_adc: update copyright and authors information Eugen Hristev
2021-08-24 11:54   ` Eugen Hristev
2021-08-24 11:54 ` [PATCH v2 09/10] ARM: dts: at91: sama7g5: add node for the ADC Eugen Hristev
2021-08-24 11:54   ` Eugen Hristev
2021-08-24 11:54 ` [PATCH v2 10/10] ARM: dts: at91: sama7g5ek: enable ADC on the board Eugen Hristev
2021-08-24 11:54   ` Eugen Hristev
2021-08-30 12:26 ` [PATCH v2 00/10] iio: adc: at91-sama5d2_adc: add support for sama7g5 Jonathan Cameron
2021-08-30 12:26   ` Jonathan Cameron
2021-09-01  9:47   ` Nicolas Ferre
2021-09-01  9:47     ` Nicolas Ferre

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.