Exemple #1
0
/* this may get called several times by oss emulation */
static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
			      struct snd_pcm_hw_params *params)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct omap_runtime_data *prtd = runtime->private_data;
	struct omap_pcm_dma_data *dma_data = rtd->dai->cpu_dai->dma_data;
	int err = 0;

	if (!dma_data)
		return -ENODEV;

	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
	runtime->dma_bytes = params_buffer_bytes(params);

	if (prtd->dma_data)
		return 0;
	prtd->dma_data = dma_data;
	err = omap_request_dma(dma_data->dma_req, dma_data->name,
			       omap_pcm_dma_irq, substream, &prtd->dma_ch);
	if (!err && !cpu_is_omap1510()) {
		/*
		 * Link channel with itself so DMA doesn't need any
		 * reprogramming while looping the buffer
		 */
		omap_dma_link_lch(prtd->dma_ch, prtd->dma_ch);
	}

	return err;
}
Exemple #2
0
/* this may get called several times by oss emulation */
static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
			      struct snd_pcm_hw_params *params)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct omap_runtime_data *prtd = runtime->private_data;
	struct omap_pcm_dma_data *dma_data;
	int err = 0;

	dma_data = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);

	/* return if this is a bufferless transfer e.g.
	 * codec <--> BT codec or GSM modem -- lg FIXME */
	if (!dma_data)
		return 0;

	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
	runtime->dma_bytes = params_buffer_bytes(params);

	if (prtd->dma_data)
		return 0;
	prtd->dma_data = dma_data;
	err = omap_request_dma(dma_data->dma_req, dma_data->name,
			       omap_pcm_dma_irq, substream, &prtd->dma_ch);
	if (!err) {
		/*
		 * Link channel with itself so DMA doesn't need any
		 * reprogramming while looping the buffer
		 */
		omap_dma_link_lch(prtd->dma_ch, prtd->dma_ch);
	}

	return err;
}
static int abe_dbg_start_dma(struct omap_abe *abe, int circular)
{
    struct omap_dma_channel_params dma_params;
    int err;

    /* start the DMA in either :-
     *
     * 1) circular buffer mode where the DMA will restart when it get to
     *    the end of the buffer.
     * 2) default mode, where DMA stops at the end of the buffer.
     */

    abe->debugfs.dma_req = OMAP44XX_DMA_ABE_REQ_7;
    err = omap_request_dma(abe->debugfs.dma_req, "ABE debug",
                           abe_dbg_dma_irq, abe, &abe->debugfs.dma_ch);
    if (abe->debugfs.circular) {
        /*
         * Link channel with itself so DMA doesn't need any
         * reprogramming while looping the buffer
         */
        omap_dma_link_lch(abe->debugfs.dma_ch, abe->debugfs.dma_ch);
    }

    memset(&dma_params, 0, sizeof(dma_params));
    dma_params.data_type = OMAP_DMA_DATA_TYPE_S32;
    dma_params.trigger = abe->debugfs.dma_req;
    dma_params.sync_mode = OMAP_DMA_SYNC_FRAME;
    dma_params.src_amode = OMAP_DMA_AMODE_DOUBLE_IDX;
    dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC;
    dma_params.src_or_dst_synch = OMAP_DMA_SRC_SYNC;
    dma_params.src_start = OMAP_ABE_D_DEBUG_FIFO_ADDR + ABE_DEFAULT_BASE_ADDRESS_L3 + ABE_DMEM_BASE_OFFSET_MPU;
    dma_params.dst_start = abe->debugfs.buffer_addr;
    dma_params.src_port = OMAP_DMA_PORT_MPUI;
    dma_params.src_ei = 1;
    dma_params.src_fi = 1 - abe->debugfs.elem_bytes;

    /* 128 bytes shifted into words */
    dma_params.elem_count = abe->debugfs.elem_bytes >> 2;
    dma_params.frame_count =
        abe->debugfs.buffer_bytes / abe->debugfs.elem_bytes;
    omap_set_dma_params(abe->debugfs.dma_ch, &dma_params);

    omap_enable_dma_irq(abe->debugfs.dma_ch, OMAP_DMA_FRAME_IRQ);
    omap_set_dma_src_burst_mode(abe->debugfs.dma_ch, OMAP_DMA_DATA_BURST_16);
    omap_set_dma_dest_burst_mode(abe->debugfs.dma_ch, OMAP_DMA_DATA_BURST_16);

    abe->debugfs.reader_offset = 0;

    pm_runtime_get_sync(abe->dev);
    omap_start_dma(abe->debugfs.dma_ch);
    return 0;
}
Exemple #4
0
/***************************************************************************************
 *
 * DMA channel requests
 *
 **************************************************************************************/
static void omap_sound_dma_link_lch(void *data)
{
	audio_stream_t *s = (audio_stream_t *) data;
	int *chan = s->lch;
	int i;

	FN_IN;
	if (s->linked) {
		FN_OUT(1);
		return;
	}
	for (i = 0; i < nr_linked_channels; i++) {
		int cur_chan = chan[i];
		int nex_chan =
		    ((nr_linked_channels - 1 ==
		      i) ? chan[0] : chan[i + 1]);
		omap_dma_link_lch(cur_chan, nex_chan);
	}
	s->linked = 1;
	FN_OUT(0);
}
static int __init omap1_cam_probe(struct platform_device *pdev)
{
	struct omap1_cam_dev *pcdev;
	struct resource *res;
	struct clk *clk;
	void __iomem *base;
	unsigned int irq;
	int err = 0;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	irq = platform_get_irq(pdev, 0);
	if (!res || (int)irq <= 0) {
		err = -ENODEV;
		goto exit;
	}

	clk = clk_get(&pdev->dev, "armper_ck");
	if (IS_ERR(clk)) {
		err = PTR_ERR(clk);
		goto exit;
	}

	pcdev = kzalloc(sizeof(*pcdev) + resource_size(res), GFP_KERNEL);
	if (!pcdev) {
		dev_err(&pdev->dev, "Could not allocate pcdev\n");
		err = -ENOMEM;
		goto exit_put_clk;
	}

	pcdev->res = res;
	pcdev->clk = clk;

	pcdev->pdata = pdev->dev.platform_data;
	pcdev->pflags = pcdev->pdata->flags;

	if (pcdev->pdata)
		pcdev->camexclk = pcdev->pdata->camexclk_khz * 1000;

	switch (pcdev->camexclk) {
	case 6000000:
	case 8000000:
	case 9600000:
	case 12000000:
	case 24000000:
		break;
	default:
		dev_warn(&pdev->dev,
				"Incorrect sensor clock frequency %ld kHz, "
				"should be one of 0, 6, 8, 9.6, 12 or 24 MHz, "
				"please correct your platform data\n",
				pcdev->pdata->camexclk_khz);
		pcdev->camexclk = 0;
	case 0:
		dev_info(&pdev->dev,
				"Not providing sensor clock\n");
	}

	INIT_LIST_HEAD(&pcdev->capture);
	spin_lock_init(&pcdev->lock);

	/*
	 * Request the region.
	 */
	if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) {
		err = -EBUSY;
		goto exit_kfree;
	}

	base = ioremap(res->start, resource_size(res));
	if (!base) {
		err = -ENOMEM;
		goto exit_release;
	}
	pcdev->irq = irq;
	pcdev->base = base;

	sensor_reset(pcdev, true);

	err = omap_request_dma(OMAP_DMA_CAMERA_IF_RX, DRIVER_NAME,
			dma_isr, (void *)pcdev, &pcdev->dma_ch);
	if (err < 0) {
		dev_err(&pdev->dev, "Can't request DMA for OMAP1 Camera\n");
		err = -EBUSY;
		goto exit_iounmap;
	}
	dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_ch);

	/* preconfigure DMA */
	omap_set_dma_src_params(pcdev->dma_ch, OMAP_DMA_PORT_TIPB,
			OMAP_DMA_AMODE_CONSTANT, res->start + REG_CAMDATA,
			0, 0);
	omap_set_dma_dest_burst_mode(pcdev->dma_ch, OMAP_DMA_DATA_BURST_4);
	/* setup DMA autoinitialization */
	omap_dma_link_lch(pcdev->dma_ch, pcdev->dma_ch);

	err = request_irq(pcdev->irq, cam_isr, 0, DRIVER_NAME, pcdev);
	if (err) {
		dev_err(&pdev->dev, "Camera interrupt register failed\n");
		goto exit_free_dma;
	}

	pcdev->soc_host.drv_name	= DRIVER_NAME;
	pcdev->soc_host.ops		= &omap1_host_ops;
	pcdev->soc_host.priv		= pcdev;
	pcdev->soc_host.v4l2_dev.dev	= &pdev->dev;
	pcdev->soc_host.nr		= pdev->id;

	err = soc_camera_host_register(&pcdev->soc_host);
	if (err)
		goto exit_free_irq;

	dev_info(&pdev->dev, "OMAP1 Camera Interface driver loaded\n");

	return 0;

exit_free_irq:
	free_irq(pcdev->irq, pcdev);
exit_free_dma:
	omap_free_dma(pcdev->dma_ch);
exit_iounmap:
	iounmap(base);
exit_release:
	release_mem_region(res->start, resource_size(res));
exit_kfree:
	kfree(pcdev);
exit_put_clk:
	clk_put(clk);
exit:
	return err;
}