Пример #1
0
static int mxs_pcm_dma_request(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct mxs_runtime_data *prtd = runtime->private_data;
	struct mxs_pcm_dma_params *dma_data =
		snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
	int desc_num = mxs_pcm_hardware.periods_max;
	int desc;
	int ret;

	if (!dma_data)
		return -ENODEV;

	prtd->params = dma_data;
	prtd->dma_ch = dma_data->dma_ch;

	ret = mxs_dma_request(prtd->dma_ch, mxs_pcm_dev,
				   prtd->params->name);
	if (ret) {
		printk(KERN_ERR "%s: Failed to request DMA channel (%d:%d)\n",
		       __func__, dma_data->dma_bus, dma_data->dma_ch);
		return ret;
	}

	/* Allocate memory for data and pio DMA descriptors */
	for (desc = 0; desc < desc_num; desc++) {
		prtd->dma_desc_array[desc] = mxs_dma_alloc_desc();
		if (prtd->dma_desc_array[desc] == NULL) {
			printk(KERN_ERR"%s Unable to allocate DMA command %d\n",
			       __func__, desc);
			goto err;
		}
	}

	ret = request_irq(prtd->params->irq, mxs_pcm_dma_irq, 0,
			  "MXS PCM DMA", substream);
	if (ret) {
		printk(KERN_ERR "%s: Unable to request DMA irq %d\n", __func__,
		       prtd->params->irq);
		goto err;
	}
	/* Enable completion interrupt */
	mxs_dma_ack_irq(prtd->dma_ch);
	mxs_dma_enable_irq(prtd->dma_ch, 1);

	return 0;

err:
	while (--desc >= 0)
		mxs_dma_free_desc(prtd->dma_desc_array[desc]);
	mxs_dma_release(prtd->dma_ch, mxs_pcm_dev);

	return ret;
}
Пример #2
0
static int __devinit mxs_hsadc_probe(struct platform_device *pdev)
{
	struct mxs_hsadc_data *pd;
	struct resource *res;
	int rlevel = 0;

	pd = kzalloc(sizeof(*pd), GFP_KERNEL);
	if (pd)
		rlevel++;
	else
		goto quit;

	pd->dev = &pdev->dev;
	platform_set_drvdata(pdev, pd);
	pd->pdev = pdev;
	rlevel++;
	
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL)
		goto quit;
	pd->hsadc_base = ioremap(res->start, res->end - res->start);
	if (pd->hsadc_base)
		rlevel++;
	else
		goto quit;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (res == NULL)
		goto quit;
	pd->pwm_base = ioremap(res->start, res->end - res->start);
	if (pd->pwm_base)
		rlevel++;
	else
		goto quit;

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (res)
		pd->dev_irq = res->start;
	else
		goto quit;

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
	if (res)
		pd->dma_irq = res->start;
	else
		goto quit;

	res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
	if (res)
		pd->dma_ch = res->start;
	else
		goto quit;

	pd->ref_hsadc_clk = clk_get(NULL, "ref_hsadc");
	if (pd->ref_hsadc_clk)
		rlevel++;
	else
		goto quit;

	pd->hsadc_clk = clk_get(NULL, "hsadc");
	if (pd->hsadc_clk)
		rlevel++;
	else
		goto quit;

	pd->pwm_clk = clk_get(NULL, "pwm");
	if (pd->pwm_clk)
		rlevel++;
	else
		goto quit;

	clk_enable(pd->ref_hsadc_clk);
	clk_enable(pd->hsadc_clk);
	clk_enable(pd->pwm_clk);
	rlevel++;

	clk_set_rate(pd->ref_hsadc_clk, REF_HSADC_FREQ);
	clk_set_rate(pd->hsadc_clk, HSADC_FREQ);

    if (request_irq(pd->dma_irq, hsadc_dma_isr, 0, "hsadc dma", pd))
		goto quit;
	else
		rlevel++;

	if (request_irq(pd->dev_irq, hsadc_isr, 0, "hsadc irq", pd))
		goto quit;
	else
		rlevel++;

	if (mxs_dma_request(pd->dma_ch, pd->dev, "hsadc"))
		goto quit;
	else
		rlevel++;

	mxs_dma_disable(pd->dma_ch);

	pd->desc = mxs_dma_alloc_desc();
	if (pd->desc==NULL)
		goto quit;
	
	memset(&pd->desc->cmd, 0, sizeof(pd->desc->cmd));
	rlevel++;

	pd->buf = dma_alloc_coherent(NULL, DMA_BUF_SIZE, &pd->buf_phy, GFP_KERNEL);
	if(!pd->buf)
		goto quit;
	
	rlevel++;

	if(hsadc_init_cdev(pd))
		goto quit;

#if HSADC_DEBUG
	printk(KERN_INFO "%s> probe successed.\n", HSADC_DEVICE_NAME);
#endif

	return 0;

quit:
	pr_err("%s quit at rlevel %d\n", __func__, rlevel);
	switch (rlevel) {
	case 14:
		hsadc_cleanup_cdev(pd);
	case 13:
		if (pd->buf_phy)
			dma_free_coherent(NULL, DMA_BUF_SIZE, pd->buf, pd->buf_phy);
	case 12:
		if (pd->desc)
			mxs_dma_free_desc(pd->desc);
	case 11:
		mxs_dma_release(pd->dma_ch, pd->dev);
	case 10:
		free_irq(pd->dev_irq, pd);
	case 9:
		free_irq(pd->dma_irq, pd);
	case 8:
		clk_disable(pd->pwm_clk);
		clk_disable(pd->hsadc_clk);
		clk_disable(pd->ref_hsadc_clk);
	case 7:
		clk_put(pd->pwm_clk);
	case 6:
		clk_put(pd->hsadc_clk);
	case 5:
		clk_put(pd->ref_hsadc_clk);
	case 4:
		iounmap(pd->pwm_base);
	case 3:
		iounmap(pd->hsadc_base);
	case 2:
		platform_set_drvdata(pdev, NULL);
	case 1:
		kfree(pd);
	case 0:
	default:
		return -ENODEV;
	}
}