Esempio n. 1
0
static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
			       struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct s3c_i2sv2_info *i2s = to_info(rtd->cpu_dai);
	int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
	unsigned long irqs;
	int ret = 0;

	pr_debug("Entered %s\n", __func__);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		/* On start, ensure that the FIFOs are cleared and reset. */

		writel(capture ? S3C2412_IISFIC_RXFLUSH : S3C2412_IISFIC_TXFLUSH,
		       i2s->regs + S3C2412_IISFIC);

		/* clear again, just in case */
		writel(0x0, i2s->regs + S3C2412_IISFIC);

	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		if (!i2s->master) {
			ret = s3c2412_snd_lrsync(i2s);
			if (ret)
				goto exit_err;
		}

		local_irq_save(irqs);

		if (capture)
			s3c2412_snd_rxctrl(i2s, 1);
		else
			s3c2412_snd_txctrl(i2s, 1);

		local_irq_restore(irqs);

		break;

	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		local_irq_save(irqs);

		if (capture)
			s3c2412_snd_rxctrl(i2s, 0);
		else
			s3c2412_snd_txctrl(i2s, 0);

		local_irq_restore(irqs);
		break;
	default:
		ret = -EINVAL;
		break;
	}

exit_err:
	return ret;
}
Esempio n. 2
0
static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
{
	int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
	unsigned long irqs;
	int ret = 0;

	DBG("Entered %s\n", __func__);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		/* On start, ensure that the FIFOs are cleared and reset. */

		writel(capture ? S3C2412_IISFIC_RXFLUSH : S3C2412_IISFIC_TXFLUSH,
		       s3c2412_i2s.regs + S3C2412_IISFIC);

		/* clear again, just in case */
		writel(0x0, s3c2412_i2s.regs + S3C2412_IISFIC);

	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		if (!s3c2412_snd_is_clkmaster()) {
			ret = s3c2412_snd_lrsync();
			if (ret)
				goto exit_err;
		}

		local_irq_save(irqs);

		if (capture)
			s3c2412_snd_rxctrl(1);
		else
			s3c2412_snd_txctrl(1);

		local_irq_restore(irqs);
		break;

	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		local_irq_save(irqs);

		if (capture)
			s3c2412_snd_rxctrl(0);
		else
			s3c2412_snd_txctrl(0);

		local_irq_restore(irqs);
		break;
	default:
		ret = -EINVAL;
		break;
	}

exit_err:
	return ret;
}
Esempio n. 3
0
int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
			       struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct s3c_i2sv2_info *i2s = to_info(rtd->dai->cpu_dai);
	int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
	unsigned long irqs;
	int ret = 0;

	pr_debug("Entered %s\n", __func__);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		if (!i2s->master) {
			ret = s3c2412_snd_lrsync(i2s);
			if (ret)
				goto exit_err;
		}

		local_irq_save(irqs);

		if (capture) {
			s3c2412_snd_rxctrl(i2s, 1);
			//printk("rxctrl(1)\n");
		} else {
			s3c2412_snd_txctrl(i2s, 1);
		}
		local_irq_restore(irqs);
		break;

	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		local_irq_save(irqs);

		if (capture) {
			//JY.Lai
			s3c2412_snd_rxctrl(i2s, 0);
			//printk("rxctrl(0)\n");
		} else {
			s3c2412_snd_txctrl(i2s, 0);
		}
		local_irq_restore(irqs);
		break;
	default:
		ret = -EINVAL;
		break;
	}

exit_err:
	return ret;
}
Esempio n. 4
0
int s3c_i2sv2_probe(struct snd_soc_dai *dai,
		    struct s3c_i2sv2_info *i2s,
		    unsigned long base)
{
	struct device *dev = dai->dev;
	unsigned int iismod;

	i2s->dev = dev;

	/* record our i2s structure for later use in the callbacks */
	snd_soc_dai_set_drvdata(dai, i2s);

	i2s->iis_pclk = clk_get(dev, "iis");
	if (IS_ERR(i2s->iis_pclk)) {
		dev_err(dev, "failed to get iis_clock\n");
		iounmap(i2s->regs);
		return -ENOENT;
	}

	clk_enable(i2s->iis_pclk);

	/* Mark ourselves as in TXRX mode so we can run through our cleanup
	 * process without warnings. */
	iismod = readl(i2s->regs + S3C2412_IISMOD);
	iismod |= S3C2412_IISMOD_MODE_TXRX;
	writel(iismod, i2s->regs + S3C2412_IISMOD);
	s3c2412_snd_txctrl(i2s, 0);
	s3c2412_snd_rxctrl(i2s, 0);

	return 0;
}
Esempio n. 5
0
int s3c_i2sv2_probe(struct platform_device *pdev,
                    struct snd_soc_dai *dai,
                    struct s3c_i2sv2_info *i2s,
                    unsigned long base)
{
    struct device *dev = &pdev->dev;
    unsigned int iismod;

    i2s->dev = dev;

    /* record our i2s structure for later use in the callbacks */
    dai->private_data = i2s;

    if (!base) {
        struct resource *res = platform_get_resource(pdev,
                               IORESOURCE_MEM,
                               0);
        if (!res) {
            dev_err(dev, "Unable to get register resource\n");
            return -ENXIO;
        }

        if (!request_mem_region(res->start, resource_size(res),
                                "s3c64xx-i2s-v4")) {
            dev_err(dev, "Unable to request register region\n");
            return -EBUSY;
        }

        base = res->start;
    }

    i2s->regs = ioremap(base, 0x100);
    if (i2s->regs == NULL) {
        dev_err(dev, "cannot ioremap registers\n");
        return -ENXIO;
    }

    i2s->iis_pclk = clk_get(dev, "iis");
    if (IS_ERR(i2s->iis_pclk)) {
        dev_err(dev, "failed to get iis_clock\n");
        iounmap(i2s->regs);
        return -ENOENT;
    }

    clk_enable(i2s->iis_pclk);

    /* Mark ourselves as in TXRX mode so we can run through our cleanup
     * process without warnings. */
    iismod = readl(i2s->regs + S3C2412_IISMOD);
    iismod |= S3C2412_IISMOD_MODE_TXRX;
    writel(iismod, i2s->regs + S3C2412_IISMOD);
    s3c2412_snd_txctrl(i2s, 0);
    s3c2412_snd_rxctrl(i2s, 0);

    return 0;
}
Esempio n. 6
0
static int s3c2412_i2s_probe(struct platform_device *pdev)
{
	DBG("Entered %s\n", __func__);

	s3c2412_i2s.dev = &pdev->dev;

	s3c2412_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100);
	if (s3c2412_i2s.regs == NULL)
		return -ENXIO;

	s3c2412_i2s.iis_pclk = clk_get(&pdev->dev, "iis");
	if (s3c2412_i2s.iis_pclk == NULL) {
		DBG("failed to get iis_clock\n");
		iounmap(s3c2412_i2s.regs);
		return -ENODEV;
	}

	s3c2412_i2s.iis_cclk = clk_get(&pdev->dev, "i2sclk");
	if (s3c2412_i2s.iis_cclk == NULL) {
		DBG("failed to get i2sclk clock\n");
		iounmap(s3c2412_i2s.regs);
		return -ENODEV;
	}

	clk_set_parent(s3c2412_i2s.iis_cclk, clk_get(NULL, "mpll"));

	clk_enable(s3c2412_i2s.iis_pclk);
	clk_enable(s3c2412_i2s.iis_cclk);

	s3c2412_i2s.iis_clk = s3c2412_i2s.iis_pclk;

	/* Configure the I2S pins in correct mode */
	s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK);
	s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2410_GPE1_I2SSCLK);
	s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2410_GPE2_CDCLK);
	s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI);
	s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO);

	s3c2412_snd_txctrl(0);
	s3c2412_snd_rxctrl(0);

	return 0;
}
Esempio n. 7
0
int s3c_i2sv2_probe(struct platform_device *pdev,
		    struct snd_soc_dai *dai,
		    struct s3c_i2sv2_info *i2s,
		    unsigned long base)
{
	struct device *dev = &pdev->dev;
	unsigned int iismod;

	i2s->dev = dev;

	/* record our i2s structure for later use in the callbacks */
	dai->private_data = i2s;

	i2s->regs = ioremap(base, 0x100);
	if (i2s->regs == NULL) {
		dev_err(dev, "cannot ioremap registers\n");
		return -ENXIO;
	}

	i2s->iis_pclk = clk_get(dev, "iis");
	if (IS_ERR(i2s->iis_pclk)) {
		dev_err(dev, "failed to get iis_clock\n");
		iounmap(i2s->regs);
		return -ENOENT;
	}

	clk_enable(i2s->iis_pclk);

#if defined(CONFIG_PLAT_S5P)
	writel(((1<<0)|(1<<31)), i2s->regs + S3C2412_IISCON);
#endif

	/* Mark ourselves as in TXRX mode so we can run through our cleanup
	 * process without warnings. */
	iismod = readl(i2s->regs + S3C2412_IISMOD);
	iismod |= S3C2412_IISMOD_MODE_TXRX;
	writel(iismod, i2s->regs + S3C2412_IISMOD);
	s3c2412_snd_txctrl(i2s, 0);
	s3c2412_snd_rxctrl(i2s, 0);

	return 0;
}
Esempio n. 8
0
static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
			       struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct s3c_i2sv2_info *i2s = to_info(rtd->cpu_dai);
	int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
	unsigned long irqs;
	int ret = 0;
	struct s3c_dma_params *dma_data =
		snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);

	pr_debug("Entered %s\n", __func__);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		/* On start, ensure that the FIFOs are cleared and reset. */

		writel(capture ? S3C2412_IISFIC_RXFLUSH : S3C2412_IISFIC_TXFLUSH,
		       i2s->regs + S3C2412_IISFIC);

		/* clear again, just in case */
		writel(0x0, i2s->regs + S3C2412_IISFIC);

	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		if (!i2s->master) {
			ret = s3c2412_snd_lrsync(i2s);
			if (ret)
				goto exit_err;
		}

		local_irq_save(irqs);

		if (capture)
			s3c2412_snd_rxctrl(i2s, 1);
		else
			s3c2412_snd_txctrl(i2s, 1);

		local_irq_restore(irqs);

		/*
		 * Load the next buffer to DMA to meet the reqirement
		 * of the auto reload mechanism of S3C24XX.
		 * This call won't bother S3C64XX.
		 */
		s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);

		break;

	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		local_irq_save(irqs);

		if (capture)
			s3c2412_snd_rxctrl(i2s, 0);
		else
			s3c2412_snd_txctrl(i2s, 0);

		local_irq_restore(irqs);
		break;
	default:
		ret = -EINVAL;
		break;
	}

exit_err:
	return ret;
}