From 64e02021ee5b1daa3b86db4d103f4c7b4698d59f Mon Sep 17 00:00:00 2001 From: Derek Hageman Date: Tue, 7 May 2019 18:15:41 -0600 Subject: [PATCH] drivers: dma: sam0: Implement get_status API Implement the get_status DMA API for the SAM0 DMA controller. The busy field is set only when the selected channel is actively transferring data (i.e. both enabled and selected by the arbiter). The direction field is left unset, since that information is not normally retained by the DMA controller. Signed-off-by: Derek Hageman --- drivers/dma/dma_sam0.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/dma/dma_sam0.c b/drivers/dma/dma_sam0.c index df36ed42408..fe51c4ce36e 100644 --- a/drivers/dma/dma_sam0.c +++ b/drivers/dma/dma_sam0.c @@ -356,6 +356,43 @@ inval: return -EINVAL; } +static int dma_sam0_get_status(struct device *dev, u32_t channel, + struct dma_status *stat) +{ + struct dma_sam0_data *data = DEV_DATA(dev); + u32_t act; + + if (channel >= DMAC_CH_NUM || stat == NULL) { + return -EINVAL; + } + + act = DMA_REGS->ACTIVE.reg; + if ((act & DMAC_ACTIVE_ABUSY) && + ((act & DMAC_ACTIVE_ID_Msk) >> DMAC_ACTIVE_ID_Pos) == channel) { + stat->busy = true; + stat->pending_length = (act & DMAC_ACTIVE_BTCNT_Msk) >> + DMAC_ACTIVE_BTCNT_Pos; + } else { + stat->busy = false; + stat->pending_length = data->descriptors_wb[channel].BTCNT.reg; + } + + switch (data->descriptors[channel].BTCTRL.bit.BEATSIZE) { + case DMAC_BTCTRL_BEATSIZE_BYTE_Val: + break; + case DMAC_BTCTRL_BEATSIZE_HWORD_Val: + stat->pending_length *= 2U; + break; + case DMAC_BTCTRL_BEATSIZE_WORD_Val: + stat->pending_length *= 4U; + break; + default: + return -EINVAL; + } + + return 0; +} + DEVICE_DECLARE(dma_sam0_0); #define DMA_SAM0_IRQ_CONNECT(n) \ @@ -416,6 +453,7 @@ static const struct dma_driver_api dma_sam0_api = { .start = dma_sam0_start, .stop = dma_sam0_stop, .reload = dma_sam0_reload, + .get_status = dma_sam0_get_status, }; DEVICE_AND_API_INIT(dma_sam0_0, CONFIG_DMA_0_NAME, &dma_sam0_init,