FreeBSD/sys/arm/ti/ti_sdma.c
/**
 *	ti_sdma_activate_channel - activates a DMA channel
 *	@ch: upon return contains the channel allocated
 *	@callback: a callback function to associate with the channel
 *	@data: optional data supplied when the callback is called
 *
 *	Simply activates a channel be enabling and writing default values to the
 *	channel's register set.  It doesn't start a transaction, just populates the
 *	internal data structures and sets defaults.
 *
 *	Note this function doesn't enable interrupts, for that you need to call
 *	ti_sdma_enable_channel_irq(). If not using IRQ to detect the end of the
 *	transfer, you can use ti_sdma_status_poll() to detect a change in the
 *	status.
 *
 *	A channel must be activated before any of the other DMA functions can be
 *	called on it.
 *
 *	LOCKING:
 *	DMA registers protected by internal mutex
 *
 *	RETURNS:
 *	0 on success, otherwise an error code
 */
activates a DMA channel
@ch: upon return contains the channel allocated
@callback: a callback function to associate with the channel
@data: optional data supplied when the callback is called

Simply activates a channel be enabling and writing default values to the
channel's register set.  It doesn't start a transaction, just populates the
internal data structures and sets defaults.

Note this function doesn't enable interrupts, for that you need to call
ti_sdma_enable_channel_irq(). If not using IRQ to detect the end of the
transfer, you can use ti_sdma_status_poll() to detect a change in the
status.

A channel must be activated before any of the other DMA functions can be
called on it.

DMA registers protected by internal mutex

0 on success, otherwise an error code
activates a DMA channel @ch : upon return contains the channel allocated @callback : a callback function to associate with the channel @data : optional data supplied when the callback is called Simply activates a channel be enabling and writing default values to the channel ' s register set . It doesn ' t start a transaction just populates the internal data structures and sets defaults . Note this function doesn ' t enable interrupts for that you need to call ti_sdma_enable_channel_irq () . If not using IRQ to detect the end of the transfer you can use ti_sdma_status_poll () to detect a change in the status . A channel must be activated before any of the other DMA functions can be called on it . DMA registers protected by internal mutex 0 on success otherwise an error code
int
ti_sdma_activate_channel(unsigned int *ch,
                          void (*callback)(unsigned int ch, uint32_t status, void *data),
                          void *data)
{
	struct ti_sdma_softc *sc = ti_sdma_sc;
	struct ti_sdma_channel *channel = NULL;
	uint32_t addr;
	unsigned int i;
	if (sc == NULL)
		return (ENOMEM);
	if (ch == NULL)
		return (EINVAL);
	TI_SDMA_LOCK(sc);
	if (sc->sc_active_channels == 0xffffffff) {
		TI_SDMA_UNLOCK(sc);
		return (ENOMEM);
	}
	for (i = 0; i < NUM_DMA_CHANNELS; i++) {
		if (!(sc->sc_active_channels & (0x1 << i))) {
			sc->sc_active_channels |= (0x1 << i);
			*ch = i;
			break;
		}
	}
	channel = &sc->sc_channel[*ch];
	channel->callback = callback;
	channel->callback_data = data;
	channel->need_reg_write = 1;
	channel->reg_csdp = DMA4_CSDP_DATA_TYPE(0x2)
		| DMA4_CSDP_SRC_BURST_MODE(0)
		| DMA4_CSDP_DST_BURST_MODE(0)
		| DMA4_CSDP_SRC_ENDIANISM(0)
		| DMA4_CSDP_DST_ENDIANISM(0)
		| DMA4_CSDP_WRITE_MODE(0)
		| DMA4_CSDP_SRC_PACKED(0)
		| DMA4_CSDP_DST_PACKED(0);
	channel->reg_ccr = DMA4_CCR_DST_ADDRESS_MODE(1)
		| DMA4_CCR_SRC_ADDRESS_MODE(1)
		| DMA4_CCR_READ_PRIORITY(0)
		| DMA4_CCR_WRITE_PRIORITY(0)
		| DMA4_CCR_SYNC_TRIGGER(0)
		| DMA4_CCR_FRAME_SYNC(0)
		| DMA4_CCR_BLOCK_SYNC(0);
	channel->reg_cicr = DMA4_CICR_TRANS_ERR_IE
		| DMA4_CICR_SECURE_ERR_IE
		| DMA4_CICR_SUPERVISOR_ERR_IE
		| DMA4_CICR_MISALIGNED_ADRS_ERR_IE;
	for (addr = DMA4_CCR(*ch); addr <= DMA4_COLOR(*ch); addr += 4)
		ti_sdma_write_4(sc, addr, 0x00000000);
	TI_SDMA_UNLOCK(sc);
	return 0;
}
int ti_sdma_activate_channel ( unsigned int * ch , void ( * callback ) ( unsigned int ch , uint32_t status , void * data ) , void * data ) { struct ti_sdma_softc * sc = ti_sdma_sc ; struct ti_sdma_channel * channel = NULL ; uint32_t addr ; unsigned int i ; if ( sc == NULL ) return ( ENOMEM ) ; if ( ch == NULL ) return ( EINVAL ) ; TI_SDMA_LOCK ( sc ) ; if ( sc -> sc_active_channels == 0xffffffff ) { TI_SDMA_UNLOCK ( sc ) ; return ( ENOMEM ) ; } for ( i = 0 ; i < NUM_DMA_CHANNELS ; i ++ ) { if ( ! ( sc -> sc_active_channels & ( 0x1 << i ) ) ) { sc -> sc_active_channels |= ( 0x1 << i ) ; * ch = i ; break ; } } channel = & sc -> sc_channel [ * ch ] ; channel -> callback = callback ; channel -> callback_data = data ; channel -> need_reg_write = 1 ; channel -> reg_csdp = DMA4_CSDP_DATA_TYPE ( 0x2 ) | DMA4_CSDP_SRC_BURST_MODE ( 0 ) | DMA4_CSDP_DST_BURST_MODE ( 0 ) | DMA4_CSDP_SRC_ENDIANISM ( 0 ) | DMA4_CSDP_DST_ENDIANISM ( 0 ) | DMA4_CSDP_WRITE_MODE ( 0 ) | DMA4_CSDP_SRC_PACKED ( 0 ) | DMA4_CSDP_DST_PACKED ( 0 ) ; channel -> reg_ccr = DMA4_CCR_DST_ADDRESS_MODE ( 1 ) | DMA4_CCR_SRC_ADDRESS_MODE ( 1 ) | DMA4_CCR_READ_PRIORITY ( 0 ) | DMA4_CCR_WRITE_PRIORITY ( 0 ) | DMA4_CCR_SYNC_TRIGGER ( 0 ) | DMA4_CCR_FRAME_SYNC ( 0 ) | DMA4_CCR_BLOCK_SYNC ( 0 ) ; channel -> reg_cicr = DMA4_CICR_TRANS_ERR_IE | DMA4_CICR_SECURE_ERR_IE | DMA4_CICR_SUPERVISOR_ERR_IE | DMA4_CICR_MISALIGNED_ADRS_ERR_IE ; for ( addr = DMA4_CCR ( * ch ) ; addr <= DMA4_COLOR ( * ch ) ; addr += 4 ) ti_sdma_write_4 ( sc , addr , 0x00000000 ) ; TI_SDMA_UNLOCK ( sc ) ; return 0 ; }
ti_sdma_activate_channel - activates a DMA channel
      @ch: upon return contains the channel allocated
      @callback: a callback function to associate with the channel
      @data: optional data supplied when the callback is called
ti_sdma_activate_channel - activates a DMA channel @ch : upon return contains the channel allocated @callback : a callback function to associate with the channel @data : optional data supplied when the callback is called
/* Sanity check */ /* Check to see if all channels are in use */ /* Find the first non-active channel */ /* Get the channel struct and populate the fields */ /* Set the default configuration for the DMA channel */ /* Clear all the channel registers, this should abort any transaction */