Il 17/05/23 01:00, Shreeya Patel ha scritto:
Refactor conversion operation to support rk3588 saradc and
add separate start, read, powerdown in respective hooks.
Signed-off-by: Simon Xue <xxm@xxxxxxxxxxxxxx>
Signed-off-by: Shreeya Patel <shreeya.patel@xxxxxxxxxxxxx>
---
drivers/iio/adc/rockchip_saradc.c | 127 +++++++++++++++++++++++++++---
1 file changed, 115 insertions(+), 12 deletions(-)
diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c
index 79448c5ffc2a..ac6fdf8e673b 100644
--- a/drivers/iio/adc/rockchip_saradc.c
+++ b/drivers/iio/adc/rockchip_saradc.c
@@ -38,10 +38,29 @@
#define SARADC_TIMEOUT msecs_to_jiffies(100)
#define SARADC_MAX_CHANNELS 8
+/* v2 registers */
+#define SARADC2_CONV_CON 0x0
+#define SARADC_T_PD_SOC 0x4
+#define SARADC_T_DAS_SOC 0xc
+#define SARADC2_END_INT_EN 0x104
+#define SARADC2_ST_CON 0x108
+#define SARADC2_STATUS 0x10c
+#define SARADC2_END_INT_ST 0x110
+#define SARADC2_DATA_BASE 0x120
+
+#define SARADC2_EN_END_INT BIT(0)
+#define SARADC2_START BIT(4)
+#define SARADC2_SINGLE_MODE BIT(5)
+
+struct rockchip_saradc;
+
struct rockchip_saradc_data {
const struct iio_chan_spec *channels;
int num_channels;
unsigned long clk_rate;
+ void (*start)(struct rockchip_saradc *info, int chn);
+ int (*read)(struct rockchip_saradc *info);
+ void (*power_down)(struct rockchip_saradc *info);
};
struct rockchip_saradc {
@@ -60,27 +79,77 @@ struct rockchip_saradc {
struct notifier_block nb;
};
-static void rockchip_saradc_power_down(struct rockchip_saradc *info)
+static void rockchip_saradc_reset_controller(struct reset_control *reset);
+
+static void rockchip_saradc_start_v1(struct rockchip_saradc *info, int chn)
+{
+ /* 8 clock periods as delay between power up and start cmd */
+ writel_relaxed(8, info->regs + SARADC_DLY_PU_SOC);
+ /* Select the channel to be used and trigger conversion */
+ writel(SARADC_CTRL_POWER_CTRL | (chn & SARADC_CTRL_CHN_MASK) |
+ SARADC_CTRL_IRQ_ENABLE, info->regs + SARADC_CTRL);
+}
+
+static void rockchip_saradc_start_v2(struct rockchip_saradc *info, int chn)
+{
+ int val;
+
+ if (info->reset)
+ rockchip_saradc_reset_controller(info->reset);
+
+ writel_relaxed(0xc, info->regs + SARADC_T_DAS_SOC);
+ writel_relaxed(0x20, info->regs + SARADC_T_PD_SOC);
+ val = SARADC2_EN_END_INT << 16 | SARADC2_EN_END_INT;
What about using bitfield macros?
/* "LO" and "HI" may get a better name, if there's any possible one! */
#define SARADC2_EN_END_INT_LO BIT(0)
#define SARADC2_EN_END_INT_HI BIT(16)
val = FIELD_PREP(SARADC_EN_END_INT_LO, 1);
val |= FIELD_PREP(SARADC_EN_END_INT_HI, 1);
writel ....
Otherwise, if it's about two really "specular" instances, you can probably
keep the current definition as SARADC2_EN_END_INT and do
val = FIELD_PREP(SARADC_EN_END_INT, 1);
val |= val << 16;
writel ...
/* note: high, low bits are unknown to me, I assumed it's 16 bits :-) */
#define SARADC2_CONV_CHANNELS GENMASK(15, 0)
val = FIELD_PREP(SARADC2_START, 1);
val |= FIELD_PREP(SARADC2_SINGLE_MODE, 1);
val |= FIELD_PREP(SARADC2_CONV_CHANNELS, chn);
val |= val << 16;
writel ...
+ writel_relaxed(val, info->regs + SARADC2_END_INT_EN);
+ val = SARADC2_START | SARADC2_SINGLE_MODE | chn;
+ writel(val << 16 | val, info->regs + SARADC2_CONV_CON);
+}
+
Cheers,
Angelo