Thread (22 messages) 22 messages, 3 authors, 2021-09-05

Re: [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform specific data structures

From: <hidden>
Date: 2021-08-31 11:50:07
Also in: linux-devicetree, linux-iio, lkml

On 8/30/21 5:44 PM, Jonathan Cameron wrote:
On Mon, 30 Aug 2021 12:31:46 +0000
[off-list ref] wrote:
quoted
On 8/24/21 2:54 PM, Eugen Hristev wrote:
quoted
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 <redacted>
---
   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 ...)

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

Eugen
quoted
-#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
quoted
quoted
+           .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,
quoted
quoted
-   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
quoted
quoted
+};
+
[snip]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help