Exemple #1
0
/*
 * Initializes the NFC hardware.
 */
int mxs_nand_init(struct mxs_nand_info *info)
{
	struct mxs_gpmi_regs *gpmi_regs =
		(struct mxs_gpmi_regs *)MXS_GPMI_BASE;
	struct mxs_bch_regs *bch_regs =
		(struct mxs_bch_regs *)MXS_BCH_BASE;
	int i = 0, j, ret = 0;

	info->desc = malloc(sizeof(struct mxs_dma_desc *) *
				MXS_NAND_DMA_DESCRIPTOR_COUNT);
	if (!info->desc) {
		ret = -ENOMEM;
		goto err1;
	}

	/* Allocate the DMA descriptors. */
	for (i = 0; i < MXS_NAND_DMA_DESCRIPTOR_COUNT; i++) {
		info->desc[i] = mxs_dma_desc_alloc();
		if (!info->desc[i]) {
			ret = -ENOMEM;
			goto err2;
		}
	}

	/* Init the DMA controller. */
	mxs_dma_init();
	for (j = MXS_DMA_CHANNEL_AHB_APBH_GPMI0;
		j <= MXS_DMA_CHANNEL_AHB_APBH_GPMI7; j++) {
		ret = mxs_dma_init_channel(j);
		if (ret)
			goto err3;
	}

	/* Reset the GPMI block. */
	mxs_reset_block(&gpmi_regs->hw_gpmi_ctrl0_reg);
	mxs_reset_block(&bch_regs->hw_bch_ctrl_reg);

	/*
	 * Choose NAND mode, set IRQ polarity, disable write protection and
	 * select BCH ECC.
	 */
	clrsetbits_le32(&gpmi_regs->hw_gpmi_ctrl1,
			GPMI_CTRL1_GPMI_MODE,
			GPMI_CTRL1_ATA_IRQRDY_POLARITY | GPMI_CTRL1_DEV_RESET |
			GPMI_CTRL1_BCH_MODE);

	return 0;

err3:
	for (--j; j >= MXS_DMA_CHANNEL_AHB_APBH_GPMI0; j--)
		mxs_dma_release(j);
err2:
	for (--i; i >= 0; i--)
		mxs_dma_desc_free(info->desc[i]);
	free(info->desc);
err1:
	if (ret == -ENOMEM)
		printf("MXS NAND: Unable to allocate DMA descriptors\n");
	return ret;
}
Exemple #2
0
static int mxs_pcm_close(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct mxs_runtime_data *prtd = runtime->private_data;
	int desc_num = mxs_pcm_hardware.periods_max;
	int desc;
	int timeo = 20;

	static LIST_HEAD(list);
	mxs_dma_disable(prtd->dma_ch);

	/* Wait until the DMA chain is finished. */
	while (mxs_dma_read_semaphore(prtd->dma_ch)) {
		if (!timeo--)
			break;
		pr_debug("The sema is not zero now\n");
		msleep(10);
	}
	if (timeo <= 0)
		pr_warn("Is the DMA channel dead?\n");

	/* Free DMA irq */
	free_irq(prtd->params->irq, substream);
	mxs_dma_get_cooked(prtd->dma_ch, &list);
	/* Free DMA channel*/
	for (desc = 0; desc < desc_num; desc++)
		mxs_dma_free_desc(prtd->dma_desc_array[desc]);
	mxs_dma_release(prtd->dma_ch, mxs_pcm_dev);

	/* Free private runtime data */
	kfree(prtd);
	return 0;
}
Exemple #3
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;
}
/*
 * Initializes the NFC hardware.
 */
int mxs_nand_init(struct mxs_nand_info *info)
{
	int ret;
	int i;

	info->desc = malloc(sizeof(struct mxs_dma_desc *) *
				MXS_NAND_DMA_DESCRIPTOR_COUNT);
	if (!info->desc) {
		printf("MXS NAND: Unable to allocate DMA descriptor table\n");
		ret = -ENOMEM;
		goto err1;
	}

	mxs_dma_init();

	/* Allocate the DMA descriptors. */
	for (i = 0; i < MXS_NAND_DMA_DESCRIPTOR_COUNT; i++) {
		info->desc[i] = mxs_dma_desc_alloc();
		if (!info->desc[i]) {
			printf("MXS NAND: Unable to allocate DMA descriptors\n");
			ret = -ENOMEM;
			goto err2;
		}
	}

	/* Init the DMA controller. */
	for (i = 0; i < CONFIG_SYS_NAND_MAX_CHIPS; i++) {
		const int chan = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + i;

		ret = mxs_dma_init_channel(chan);
		if (ret) {
			printf("Failed to initialize DMA channel %d\n", chan);
			goto err3;
		}
	}

	ret = mxs_nand_gpmi_init();
	if (ret)
		goto err3;

	return 0;

err3:
	for (--i; i >= 0; i--)
		mxs_dma_release(i + MXS_DMA_CHANNEL_AHB_APBH_GPMI0);
	i = MXS_NAND_DMA_DESCRIPTOR_COUNT - 1;
err2:
	free(info->desc);
	for (--i; i >= 0; i--)
		mxs_dma_desc_free(info->desc[i]);
err1:
	return ret;
}
Exemple #5
0
static int __devexit mxs_hsadc_remove(struct platform_device *pdev)
{
	struct mxs_hsadc_data *pd = platform_get_drvdata(pdev);
	u32 ctrl = 0;

	hsadc_cleanup_cdev(pd); // clean cdev interface

	if (pd->buf_phy)
		dma_free_coherent(NULL, DMA_BUF_SIZE, pd->buf, pd->buf_phy);

	if (pd->desc)
		mxs_dma_free_desc(pd->desc);
	
	mxs_dma_enable_irq(pd->dma_ch, 0);
	ctrl = readl(pd->hsadc_base + HSADC_CTRL1);
	ctrl &= ~(1<<31 | 1<<30 | 1<<29); // disable irq
	writel(ctrl, pd->hsadc_base + HSADC_CTRL1);
	mxs_dma_disable(pd->dma_ch);
	
	mxs_dma_release(pd->dma_ch, pd->dev);
	free_irq(pd->dev_irq, pd);
	free_irq(pd->dma_irq, pd);

	clk_disable(pd->hsadc_clk);
	clk_disable(pd->pwm_clk);
	clk_disable(pd->ref_hsadc_clk);

	clk_put(pd->hsadc_clk);
	clk_put(pd->pwm_clk);
	clk_put(pd->ref_hsadc_clk);

	iounmap(pd->pwm_base);
	iounmap(pd->hsadc_base);
	
	platform_set_drvdata(pdev, NULL);
	kfree(pd);

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

	return 0;
}
Exemple #6
0
static int mxs_pcm_close(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct mxs_runtime_data *prtd = runtime->private_data;
	int desc_num = mxs_pcm_hardware.periods_max;
	int desc;

	static LIST_HEAD(list);
	mxs_dma_disable(prtd->dma_ch);
	/* Free DMA irq */
	free_irq(prtd->params->irq, substream);
	mxs_dma_get_cooked(prtd->dma_ch, &list);
	/* Free DMA channel*/
	for (desc = 0; desc < desc_num; desc++)
		mxs_dma_free_desc(prtd->dma_desc_array[desc]);
	mxs_dma_release(prtd->dma_ch, mxs_pcm_dev);

	/* Free private runtime data */
	kfree(prtd);
	return 0;
}
Exemple #7
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;
	}
}