iio: adc: rockchip_saradc: add support dma mode

Change-Id: I0bac2454c71948d9f753472fb72c3117efa8a16d
Signed-off-by: Simon Xue <xxm@rock-chips.com>
This commit is contained in:
Simon Xue
2025-04-07 15:56:13 +08:00
parent e67c62194c
commit fd00c9eece

View File

@@ -21,6 +21,7 @@
#include <linux/iio/iio.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/dma-mapping.h>
#define SARADC_DATA 0x00
@@ -43,6 +44,7 @@
#define SARADC2_CONV_CON 0x0
#define SARADC_T_PD_SOC 0x4
#define SARADC_T_DAS_SOC 0xc
#define SARADC_T_SEL_SOC 0x10
#define SARADC2_END_INT_EN 0x104
#define SARADC2_ST_CON 0x108
#define SARADC2_STATUS 0x10c
@@ -55,6 +57,19 @@
#define SARADC2_CONV_CHANNELS GENMASK(3, 0)
#define SARADC3_AUTO_CH_EN 0x160
#define SARADC3_FIFO_CON 0x18c
#define SARADC3_PADDR_BASE_H 0x190
#define SARADC3_PADDR_BASE_L 0x194
#define SARADC3_PADDR_OFF_MAX 0x198
#define SARADC3_PADDR_OFF_WK 0x200
#define SARADC3_EN_END_MAX_INT BIT(3)
#define SARADC3_AUTO_MODE BIT(6)
#define SARADC3_PMASTER_EN BIT(3)
#define SARADC3_PADDR_MAX_INT_ST BIT(3)
struct rockchip_saradc;
struct rockchip_saradc_data {
@@ -82,6 +97,9 @@ struct rockchip_saradc {
const struct iio_chan_spec *last_chan;
struct notifier_block nb;
bool suspended;
bool dma_mode;
void *dma_base;
dma_addr_t dma_phys;
#ifdef CONFIG_ROCKCHIP_SARADC_TEST_CHN
bool test;
u32 test_chn;
@@ -91,6 +109,8 @@ struct rockchip_saradc {
#endif
};
#define SARADC3_DMA_SIZE SZ_4K
static void rockchip_saradc_reset_controller(struct reset_control *reset);
static void rockchip_saradc_start_v1(struct rockchip_saradc *info,
@@ -131,6 +151,53 @@ static void rockchip_saradc_start_v2(struct rockchip_saradc *info,
writel(val, info->regs + SARADC2_CONV_CON);
}
static void rockchip_saradc_start_v3_dma(struct rockchip_saradc *info,
int chn)
{
int val;
if (info->reset)
rockchip_saradc_reset_controller(info->reset);
writel_relaxed(0x20, info->regs + SARADC_T_PD_SOC);
writel_relaxed(0x11, info->regs + SARADC_T_DAS_SOC);
writel_relaxed(0x0, info->regs + SARADC_T_SEL_SOC);
val = FIELD_PREP(SARADC3_PMASTER_EN, 1);
val |= SARADC3_PMASTER_EN << 16;
writel_relaxed(val, info->regs + SARADC3_FIFO_CON);
writel_relaxed((u64)info->dma_phys >> 32,
info->regs + SARADC3_PADDR_BASE_H);
writel_relaxed(((u32)info->dma_phys) >> 2,
info->regs + SARADC3_PADDR_BASE_L);
writel_relaxed((SARADC3_DMA_SIZE >> 2) - 1,
info->regs + SARADC3_PADDR_OFF_MAX);
val = FIELD_PREP(SARADC3_EN_END_MAX_INT, 1);
val |= SARADC3_EN_END_MAX_INT << 16;
writel_relaxed(val, info->regs + SARADC2_END_INT_EN);
val = BIT(chn) << 16 | BIT(chn);
writel_relaxed(val, info->regs + SARADC3_AUTO_CH_EN);
val = FIELD_PREP(SARADC2_START, 1) |
FIELD_PREP(SARADC3_AUTO_MODE, 1) |
FIELD_PREP(SARADC2_CONV_CHANNELS, chn);
val |= (SARADC2_START | SARADC3_AUTO_MODE | SARADC2_CONV_CHANNELS) << 16;
writel(val, info->regs + SARADC2_CONV_CON);
}
/* V3 is compatible with V2 */
static void rockchip_saradc_start_v3(struct rockchip_saradc *info,
int chn)
{
if (info->dma_mode)
rockchip_saradc_start_v3_dma(info, chn);
else
rockchip_saradc_start_v2(info, chn);
}
static void rockchip_saradc_start(struct rockchip_saradc *info,
int chn)
{
@@ -164,6 +231,22 @@ static int rockchip_saradc_read_v2(struct rockchip_saradc *info)
return readl_relaxed(info->regs + offset);
}
static int rockchip_saradc_read_v3(struct rockchip_saradc *info)
{
int val;
/* Clear max int and disable dma write function */
if (info->dma_mode) {
writel_relaxed(SARADC3_PADDR_MAX_INT_ST,
info->regs + SARADC2_END_INT_ST);
val = FIELD_PREP(SARADC3_PMASTER_EN, 0);
val |= SARADC3_PMASTER_EN << 16;
writel_relaxed(val, info->regs + SARADC3_FIFO_CON);
}
return rockchip_saradc_read_v2(info);
}
static int rockchip_saradc_read(struct rockchip_saradc *info)
{
return info->data->read(info);
@@ -439,8 +522,8 @@ static const struct rockchip_saradc_data rv1126b_saradc_data = {
.channels = rockchip_rv1126b_saradc_iio_channels,
.num_channels = ARRAY_SIZE(rockchip_rv1126b_saradc_iio_channels),
.clk_rate = 24000000,
.start = rockchip_saradc_start_v2,
.read = rockchip_saradc_read_v2,
.start = rockchip_saradc_start_v3,
.read = rockchip_saradc_read_v3,
.das_soc_data = 0x14,
};
@@ -819,6 +902,17 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
#endif
mutex_init(&info->lock);
info->dma_mode = device_property_read_bool(&pdev->dev, "rockchip,dma");
if (info->dma_mode) {
dma_set_mask_and_coherent(&pdev->dev, 40);
info->dma_base = dmam_alloc_coherent(&pdev->dev, SARADC3_DMA_SIZE,
&info->dma_phys, GFP_KERNEL);
if (!info->dma_base) {
dev_err(&pdev->dev, "failed to alloc memory for dma\n");
return -ENOMEM;
}
}
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return dev_err_probe(&pdev->dev, irq, "failed to get irq\n");