static int init_fdma_nand(struct stm_nand_emi *data)
{
	const char *dmac_id[] = {STM_DMAC_ID, NULL};
	const char *cap_channel[] = {STM_DMA_CAP_LOW_BW,
				     STM_DMA_CAP_HIGH_BW, NULL};
	int i;

	/* Request DMA channel for NAND transactions */
	data->dma_chan = request_dma_bycap(dmac_id, cap_channel, NAME);
	if (data->dma_chan < 0) {
		printk(KERN_ERR NAME ": request_dma_bycap failed!\n");
		return -EBUSY;
	}

	/* Initialise DMA paramters */
	for (i = 0; i < 2; i++) {
		dma_params_init(&data->dma_params[i], MODE_FREERUNNING,
				STM_DMA_LIST_OPEN);
		dma_params_DIM_1_x_1(&data->dma_params[i]);
		dma_params_err_cb(&data->dma_params[i], fdma_err, 0,
				  STM_DMA_CB_CONTEXT_TASKLET);
	}

	printk(KERN_INFO NAME ": %s assigned %s(%d)\n",
	       data->mtd.name, get_dma_info(data->dma_chan)->name,
	       data->dma_chan);

	return 0;
}
Esempio n. 2
0
int ksnd_pcm_streaming_start(ksnd_pcm_streaming_t *handle,
                             ksnd_pcm_t *capture, ksnd_pcm_t *playback)
{
    int result;
    struct ksnd_pcm_streaming *streaming;
    const char *fdmac_id[] = { STM_DMAC_ID, NULL };
    const char *lb_cap[] = { STM_DMA_CAP_LOW_BW, NULL };
    const char *hb_cap[] = { STM_DMA_CAP_HIGH_BW, NULL };

    // Allocate and clean streaming structure

    streaming = kzalloc(sizeof(*streaming), GFP_KERNEL);
    if (streaming == NULL) {
        ERROR("Can't get memory for streaming structure!\n");
        return -ENOMEM;
    }

    // Prepare description

    streaming->capture_handle = capture;
    streaming->playback_handle = playback;
    streaming->magic = magic_good;

    // Initialize FDMA

    streaming->fdma_channel = request_dma_bycap(fdmac_id, lb_cap, "KSOUND_STREAMING");
    if (streaming->fdma_channel < 0) {
        streaming->fdma_channel = request_dma_bycap(fdmac_id, hb_cap, "KSOUND_STREAMING");
        if (streaming->fdma_channel < 0) {
            ERROR("Can't allocate FDMA channel!\n");
            kfree(streaming);
            return -EBUSY;
        }
    }

    dma_params_init(&streaming->fdma_params, MODE_FREERUNNING, STM_DMA_LIST_OPEN);

    dma_params_comp_cb(&streaming->fdma_params, transfer_done_callback,
                       (unsigned long)streaming, STM_DMA_CB_CONTEXT_TASKLET);

    dma_params_err_cb(&streaming->fdma_params, transfer_error_callback,
                      (unsigned long)streaming, STM_DMA_CB_CONTEXT_TASKLET);

    dma_params_DIM_1_x_1(&streaming->fdma_params);

    result = dma_compile_list(streaming->fdma_channel, &streaming->fdma_params, GFP_KERNEL);
    if (result < 0) {
        ERROR("Can't compile FDMA parameters!\n");
        free_dma(streaming->fdma_channel);
        kfree(streaming);
        return -EFAULT;
    }

    // Initialize ALSA

    capture->substream->runtime->transfer_ack_end = period_captured_callback;
    BUG_ON(capture->substream->runtime->private_data != NULL);  // It used to be not used ;-)
    capture->substream->runtime->private_data = streaming;

    ksnd_pcm_start(capture);

    // Return handle

    *handle = streaming;

    return 0;
}