Lines Matching +full:enable +full:- +full:channel
4 * SPDX-License-Identifier: Apache-2.0
31 /* DMA channel configuration */
53 const struct sam_xdmac_dev_cfg *const dev_cfg = dev->config; in sam_xdmac_isr()
54 struct sam_xdmac_dev_data *const dev_data = dev->data; in sam_xdmac_isr()
56 Xdmac * const xdmac = dev_cfg->regs; in sam_xdmac_isr()
62 isr_status = xdmac->XDMAC_GIS; in sam_xdmac_isr()
64 for (int channel = 0; channel < DMA_CHANNELS_NO; channel++) { in sam_xdmac_isr() local
65 if (!(isr_status & (1 << channel))) { in sam_xdmac_isr()
69 channel_cfg = &dev_data->dma_channels[channel]; in sam_xdmac_isr()
71 /* Get channel errors */ in sam_xdmac_isr()
72 err = xdmac->XDMAC_CHID[channel].XDMAC_CIS & XDMAC_INT_ERR; in sam_xdmac_isr()
75 if (channel_cfg->callback) { in sam_xdmac_isr()
76 channel_cfg->callback(dev, channel_cfg->user_data, in sam_xdmac_isr()
77 channel, err); in sam_xdmac_isr()
82 int sam_xdmac_channel_configure(const struct device *dev, uint32_t channel, in sam_xdmac_channel_configure() argument
85 const struct sam_xdmac_dev_cfg *const dev_cfg = dev->config; in sam_xdmac_channel_configure()
87 Xdmac * const xdmac = dev_cfg->regs; in sam_xdmac_channel_configure()
89 if (channel >= DMA_CHANNELS_NO) { in sam_xdmac_channel_configure()
90 return -EINVAL; in sam_xdmac_channel_configure()
93 /* Check if the channel is enabled */ in sam_xdmac_channel_configure()
94 if (xdmac->XDMAC_GS & (XDMAC_GS_ST0 << channel)) { in sam_xdmac_channel_configure()
95 return -EBUSY; in sam_xdmac_channel_configure()
98 /* Disable all channel interrupts */ in sam_xdmac_channel_configure()
99 xdmac->XDMAC_CHID[channel].XDMAC_CID = 0xFF; in sam_xdmac_channel_configure()
101 (void)xdmac->XDMAC_CHID[channel].XDMAC_CIS; in sam_xdmac_channel_configure()
104 * Setting channel configuration is not required for linked list view 2 in sam_xdmac_channel_configure()
109 /* Set channel configuration */ in sam_xdmac_channel_configure()
110 xdmac->XDMAC_CHID[channel].XDMAC_CC = param->cfg; in sam_xdmac_channel_configure()
113 xdmac->XDMAC_CHID[channel].XDMAC_CDS_MSP = param->ds_msp; in sam_xdmac_channel_configure()
115 xdmac->XDMAC_CHID[channel].XDMAC_CSUS = param->sus; in sam_xdmac_channel_configure()
117 xdmac->XDMAC_CHID[channel].XDMAC_CDUS = param->dus; in sam_xdmac_channel_configure()
119 /* Enable selected channel interrupts */ in sam_xdmac_channel_configure()
120 xdmac->XDMAC_CHID[channel].XDMAC_CIE = param->cie; in sam_xdmac_channel_configure()
125 int sam_xdmac_transfer_configure(const struct device *dev, uint32_t channel, in sam_xdmac_transfer_configure() argument
128 const struct sam_xdmac_dev_cfg *const dev_cfg = dev->config; in sam_xdmac_transfer_configure()
130 Xdmac * const xdmac = dev_cfg->regs; in sam_xdmac_transfer_configure()
132 if (channel >= DMA_CHANNELS_NO) { in sam_xdmac_transfer_configure()
133 return -EINVAL; in sam_xdmac_transfer_configure()
136 /* Check if the channel is enabled */ in sam_xdmac_transfer_configure()
137 if (xdmac->XDMAC_GS & (XDMAC_GS_ST0 << channel)) { in sam_xdmac_transfer_configure()
138 return -EBUSY; in sam_xdmac_transfer_configure()
148 xdmac->XDMAC_CHID[channel].XDMAC_CSA = param->sa; in sam_xdmac_transfer_configure()
150 xdmac->XDMAC_CHID[channel].XDMAC_CDA = param->da; in sam_xdmac_transfer_configure()
152 if ((param->ndc & XDMAC_CNDC_NDE) == XDMAC_CNDC_NDE_DSCR_FETCH_DIS) { in sam_xdmac_transfer_configure()
159 xdmac->XDMAC_CHID[channel].XDMAC_CUBC = param->ublen; in sam_xdmac_transfer_configure()
161 xdmac->XDMAC_CHID[channel].XDMAC_CBC = param->blen; in sam_xdmac_transfer_configure()
169 xdmac->XDMAC_CHID[channel].XDMAC_CNDA = param->nda; in sam_xdmac_transfer_configure()
173 xdmac->XDMAC_CHID[channel].XDMAC_CNDC = param->ndc; in sam_xdmac_transfer_configure()
178 static int sam_xdmac_config(const struct device *dev, uint32_t channel, in sam_xdmac_config() argument
181 struct sam_xdmac_dev_data *const dev_data = dev->data; in sam_xdmac_config()
188 if (channel >= DMA_CHANNELS_NO) { in sam_xdmac_config()
189 return -EINVAL; in sam_xdmac_config()
192 __ASSERT_NO_MSG(cfg->source_data_size == cfg->dest_data_size); in sam_xdmac_config()
193 __ASSERT_NO_MSG(cfg->source_burst_length == cfg->dest_burst_length); in sam_xdmac_config()
195 if (cfg->source_data_size != 1U && cfg->source_data_size != 2U && in sam_xdmac_config()
196 cfg->source_data_size != 4U) { in sam_xdmac_config()
198 return -EINVAL; in sam_xdmac_config()
201 if (cfg->block_count != 1U) { in sam_xdmac_config()
204 return -EINVAL; in sam_xdmac_config()
207 burst_size = find_msb_set(cfg->source_burst_length) - 1; in sam_xdmac_config()
209 data_size = find_msb_set(cfg->source_data_size) - 1; in sam_xdmac_config()
210 dev_data->dma_channels[channel].data_size = data_size; in sam_xdmac_config()
215 if (cfg->head_block->source_addr_adj == DMA_ADDR_ADJ_INCREMENT in sam_xdmac_config()
216 && cfg->channel_direction == MEMORY_TO_PERIPHERAL) { in sam_xdmac_config()
222 if (cfg->head_block->dest_addr_adj == DMA_ADDR_ADJ_INCREMENT in sam_xdmac_config()
223 && cfg->channel_direction == PERIPHERAL_TO_MEMORY) { in sam_xdmac_config()
229 switch (cfg->channel_direction) { in sam_xdmac_config()
233 | XDMAC_CC_MBSIZE(burst_size == 0U ? 0 : burst_size - 1) in sam_xdmac_config()
253 cfg->channel_direction); in sam_xdmac_config()
254 return -EINVAL; in sam_xdmac_config()
261 | XDMAC_CC_PERID(cfg->dma_slot); in sam_xdmac_config()
266 (cfg->complete_callback_en ? XDMAC_CIE_BIE : XDMAC_CIE_LIE) in sam_xdmac_config()
267 | (cfg->error_callback_dis ? 0 : XDMAC_INT_ERR); in sam_xdmac_config()
269 ret = sam_xdmac_channel_configure(dev, channel, &channel_cfg); in sam_xdmac_config()
274 dev_data->dma_channels[channel].callback = cfg->dma_callback; in sam_xdmac_config()
275 dev_data->dma_channels[channel].user_data = cfg->user_data; in sam_xdmac_config()
278 transfer_cfg.sa = cfg->head_block->source_address; in sam_xdmac_config()
279 transfer_cfg.da = cfg->head_block->dest_address; in sam_xdmac_config()
280 transfer_cfg.ublen = cfg->head_block->block_size >> data_size; in sam_xdmac_config()
282 ret = sam_xdmac_transfer_configure(dev, channel, &transfer_cfg); in sam_xdmac_config()
287 static int sam_xdmac_transfer_reload(const struct device *dev, uint32_t channel, in sam_xdmac_transfer_reload() argument
290 struct sam_xdmac_dev_data *const dev_data = dev->data; in sam_xdmac_transfer_reload()
294 .ublen = size >> dev_data->dma_channels[channel].data_size, in sam_xdmac_transfer_reload()
297 return sam_xdmac_transfer_configure(dev, channel, &transfer_cfg); in sam_xdmac_transfer_reload()
300 int sam_xdmac_transfer_start(const struct device *dev, uint32_t channel) in sam_xdmac_transfer_start() argument
302 const struct sam_xdmac_dev_cfg *config = dev->config; in sam_xdmac_transfer_start()
304 Xdmac * const xdmac = config->regs; in sam_xdmac_transfer_start()
306 if (channel >= DMA_CHANNELS_NO) { in sam_xdmac_transfer_start()
307 LOG_DBG("Channel %d out of range", channel); in sam_xdmac_transfer_start()
308 return -EINVAL; in sam_xdmac_transfer_start()
311 /* Check if the channel is enabled */ in sam_xdmac_transfer_start()
312 if (xdmac->XDMAC_GS & (XDMAC_GS_ST0 << channel)) { in sam_xdmac_transfer_start()
313 LOG_DBG("Channel %d already enabled", channel); in sam_xdmac_transfer_start()
314 return -EBUSY; in sam_xdmac_transfer_start()
317 /* Enable channel interrupt */ in sam_xdmac_transfer_start()
318 xdmac->XDMAC_GIE = XDMAC_GIE_IE0 << channel; in sam_xdmac_transfer_start()
319 /* Enable channel */ in sam_xdmac_transfer_start()
320 xdmac->XDMAC_GE = XDMAC_GE_EN0 << channel; in sam_xdmac_transfer_start()
325 int sam_xdmac_transfer_stop(const struct device *dev, uint32_t channel) in sam_xdmac_transfer_stop() argument
327 const struct sam_xdmac_dev_cfg *config = dev->config; in sam_xdmac_transfer_stop()
329 Xdmac * const xdmac = config->regs; in sam_xdmac_transfer_stop()
331 if (channel >= DMA_CHANNELS_NO) { in sam_xdmac_transfer_stop()
332 return -EINVAL; in sam_xdmac_transfer_stop()
335 /* Check if the channel is enabled */ in sam_xdmac_transfer_stop()
336 if (!(xdmac->XDMAC_GS & (XDMAC_GS_ST0 << channel))) { in sam_xdmac_transfer_stop()
340 /* Disable channel */ in sam_xdmac_transfer_stop()
341 xdmac->XDMAC_GD = XDMAC_GD_DI0 << channel; in sam_xdmac_transfer_stop()
342 /* Disable channel interrupt */ in sam_xdmac_transfer_stop()
343 xdmac->XDMAC_GID = XDMAC_GID_ID0 << channel; in sam_xdmac_transfer_stop()
344 /* Disable all channel interrupts */ in sam_xdmac_transfer_stop()
345 xdmac->XDMAC_CHID[channel].XDMAC_CID = 0xFF; in sam_xdmac_transfer_stop()
347 (void)xdmac->XDMAC_CHID[channel].XDMAC_CIS; in sam_xdmac_transfer_stop()
354 const struct sam_xdmac_dev_cfg *const dev_cfg = dev->config; in sam_xdmac_initialize()
356 Xdmac * const xdmac = dev_cfg->regs; in sam_xdmac_initialize()
359 dev_cfg->irq_config(); in sam_xdmac_initialize()
361 /* Enable XDMAC clock in PMC */ in sam_xdmac_initialize()
363 (clock_control_subsys_t)&dev_cfg->clock_cfg); in sam_xdmac_initialize()
366 xdmac->XDMAC_GD = UINT32_MAX; in sam_xdmac_initialize()
367 /* Disable all channel interrupts */ in sam_xdmac_initialize()
368 xdmac->XDMAC_GID = UINT32_MAX; in sam_xdmac_initialize()
370 /* Enable module's IRQ */ in sam_xdmac_initialize()
371 irq_enable(dev_cfg->irq_id); in sam_xdmac_initialize()
373 LOG_INF("Device %s initialized", dev->name); in sam_xdmac_initialize()
378 static int sam_xdmac_get_status(const struct device *dev, uint32_t channel, in sam_xdmac_get_status() argument
381 const struct sam_xdmac_dev_cfg *const dev_cfg = dev->config; in sam_xdmac_get_status()
383 Xdmac * const xdmac = dev_cfg->regs; in sam_xdmac_get_status()
384 uint32_t chan_cfg = xdmac->XDMAC_CHID[channel].XDMAC_CC; in sam_xdmac_get_status()
385 uint32_t ublen = xdmac->XDMAC_CHID[channel].XDMAC_CUBC; in sam_xdmac_get_status()
389 status->dir = MEMORY_TO_MEMORY; in sam_xdmac_get_status()
391 status->dir = MEMORY_TO_PERIPHERAL; in sam_xdmac_get_status()
393 status->dir = PERIPHERAL_TO_MEMORY; in sam_xdmac_get_status()
396 status->busy = ((chan_cfg & XDMAC_CC_INITD_Msk) != 0) || (ublen > 0); in sam_xdmac_get_status()
397 status->pending_length = ublen; in sam_xdmac_get_status()