Exemplo n.º 1
0
static int psc_i2s_hw_params(struct snd_pcm_substream *substream,
				 struct snd_pcm_hw_params *params,
				 struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data;
	u32 mode;

	dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i"
		" periods=%i buffer_size=%i  buffer_bytes=%i\n",
		__func__, substream, params_period_size(params),
		params_period_bytes(params), params_periods(params),
		params_buffer_size(params), params_buffer_bytes(params));

	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S8:
		mode = MPC52xx_PSC_SICR_SIM_CODEC_8;
		break;
	case SNDRV_PCM_FORMAT_S16_BE:
		mode = MPC52xx_PSC_SICR_SIM_CODEC_16;
		break;
	case SNDRV_PCM_FORMAT_S24_BE:
		mode = MPC52xx_PSC_SICR_SIM_CODEC_24;
		break;
	case SNDRV_PCM_FORMAT_S32_BE:
		mode = MPC52xx_PSC_SICR_SIM_CODEC_32;
		break;
	default:
		dev_dbg(psc_dma->dev, "invalid format\n");
		return -EINVAL;
	}
	out_be32(&psc_dma->psc_regs->sicr, psc_dma->sicr | mode);

	return 0;
}
Exemplo n.º 2
0
static int tcc_i2s_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
    struct snd_soc_pcm_runtime *rtd = substream->private_data;
    struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
    struct tcc_pcm_dma_params *dma_data;

    if (substream->pcm->device == __I2S_DEV_NUM__) {
        if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
            dma_data = &tcc_i2s_pcm_stereo_out;
        }
        else if(substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
            dma_data = &tcc_i2s_pcm_stereo_in;
        }
        snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);

        // Set DAI clock
        tcc_i2s_set_clock(params_rate(params));
    }

alsa_dbg("=====================\n");
alsa_dbg("= rate        : %d\n", params_rate(params));
alsa_dbg("= channels    : %d\n", params_channels(params));
alsa_dbg("= period_size : %d\n", params_period_size(params));

    return 0;
}
Exemplo n.º 3
0
static int nusmart_pcm_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *params)
{
    struct snd_pcm_runtime *runtime = substream->runtime;
    struct nusmart_runtime_data *rtd_prv = runtime->private_data;
    size_t totsize = params_buffer_bytes(params);

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

    rtd_prv->rcv_bytes_count = 0;
    rtd_prv->tran_bytes_count = 0;
    rtd_prv->rate = params_rate(params);
    rtd_prv->fmt = params_format(params);

    DBG_PRINT("buffer_bytes  = 0x%x, perd_bytes = 0x%x, perd_size = %d, ch = %d, fmt = %d, rate = %d \n",
              params_buffer_bytes(params),
              params_period_bytes(params),
              params_period_size(params),
              params_channels(params),
              params_format(params),
              params_rate(params)
             );
    return 0;
}
Exemplo n.º 4
0
static int jz_pcm_hw_params(struct snd_pcm_substream *substream,
		struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
	struct jz_pcm_runtime_data *prtd = substream->runtime->private_data;
	struct jz_pcm_dma_params *dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
	struct dma_slave_config slave_config;
	int ret;

	DMA_SUBSTREAM_MSG(substream, "%s enter\n", __func__);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		slave_config.direction = DMA_TO_DEVICE;
		slave_config.dst_addr = dma_params->dma_addr;
	} else {
		slave_config.direction = DMA_FROM_DEVICE;
		slave_config.src_addr = dma_params->dma_addr;
	}
	slave_config.dst_addr_width = dma_params->buswidth;
	slave_config.dst_maxburst = dma_params->max_burst;
	slave_config.src_addr_width = dma_params->buswidth;	/*jz dmaengine needed*/
	slave_config.src_maxburst = dma_params->max_burst;
	ret = dmaengine_slave_config(prtd->dma_chan, &slave_config);
	if (ret)
		return ret;

#ifdef CONFIG_JZ_ASOC_DMA_HRTIMER_MODE
	{
		unsigned long long time_ns;
		time_ns = 1000LL * 1000 * 1000 * params_period_size(params);
		do_div(time_ns, params_rate(params));
		prtd->expires = ns_to_ktime(time_ns);
	}
#else
	prtd->delayed_jiffies =  2 * (params_period_size(params) * HZ /params_rate(params));
#endif
	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
}
static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct imx_pcm_runtime_data *iprtd = runtime->private_data;
	int i;
	unsigned long dma_addr;

	imx_ssi_dma_alloc(substream);

	iprtd->size = params_buffer_bytes(params);
	iprtd->periods = params_periods(params);
	iprtd->period = params_period_bytes(params);
	iprtd->offset = 0;
	iprtd->period_time = HZ / (params_rate(params) /
			params_period_size(params));

	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);

	if (iprtd->sg_count != iprtd->periods) {
		kfree(iprtd->sg_list);

		iprtd->sg_list = kcalloc(iprtd->periods + 1,
				sizeof(struct scatterlist), GFP_KERNEL);
		if (!iprtd->sg_list)
			return -ENOMEM;
		iprtd->sg_count = iprtd->periods + 1;
	}

	sg_init_table(iprtd->sg_list, iprtd->sg_count);
	dma_addr = runtime->dma_addr;

	for (i = 0; i < iprtd->periods; i++) {
		iprtd->sg_list[i].page_link = 0;
		iprtd->sg_list[i].offset = 0;
		iprtd->sg_list[i].dma_address = dma_addr;
		iprtd->sg_list[i].length = iprtd->period;
		dma_addr += iprtd->period;
	}

	/* close the loop */
	iprtd->sg_list[iprtd->sg_count - 1].offset = 0;
	iprtd->sg_list[iprtd->sg_count - 1].length = 0;
	iprtd->sg_list[iprtd->sg_count - 1].page_link =
			((unsigned long) iprtd->sg_list | 0x01) & ~0x02;
	return 0;
}
Exemplo n.º 6
0
static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct imx_pcm_runtime_data *iprtd = runtime->private_data;

	iprtd->size = params_buffer_bytes(params);
	iprtd->periods = params_periods(params);
	iprtd->period = params_period_bytes(params) ;
	iprtd->offset = 0;
	iprtd->last_offset = 0;
	iprtd->poll_time = HZ / (params_rate(params) / params_period_size(params));

	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);

	return 0;
}
Exemplo n.º 7
0
static int snd_ali_playback_hw_params(struct snd_pcm_substream *substream,
				      struct snd_pcm_hw_params *hw_params)
{
	struct snd_ali *codec = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_ali_voice *pvoice = runtime->private_data;
	struct snd_ali_voice *evoice = pvoice->extra;
	int err;

	err = snd_pcm_lib_malloc_pages(substream,
				       params_buffer_bytes(hw_params));
	if (err < 0)
		return err;
	
	/* voice management */

	if (params_buffer_size(hw_params) / 2 !=
	    params_period_size(hw_params)) {
		if (!evoice) {
			evoice = snd_ali_alloc_voice(codec,
						     SNDRV_ALI_VOICE_TYPE_PCM,
						     0, -1);
			if (!evoice)
				return -ENOMEM;
			pvoice->extra = evoice;
			evoice->substream = substream;
		}
	} else {
		if (evoice) {
			snd_ali_free_voice(codec, evoice);
			pvoice->extra = evoice = NULL;
		}
	}

	return 0;
}
Exemplo n.º 8
0
static int snd_mvf_pcm_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct mvf_pcm_runtime_data *iprtd = runtime->private_data;
	struct imx_pcm_dma_params *dma_params;
	int ret;

	dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
	ret = mvf_sai_dma_alloc(substream, params);
	if (ret)
		return ret;

	iprtd->size = params_buffer_bytes(params);
	iprtd->periods = params_periods(params);
	iprtd->period_bytes = params_period_bytes(params);
	iprtd->offset = 0;
	iprtd->period_time = HZ / (params_rate(params) /
			params_period_size(params));

	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
	return 0;
}
Exemplo n.º 9
0
static int s5pc1xx_12s1_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params,
				 struct snd_soc_dai *socdai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai_link *dai = rtd->dai;
	struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai);

	unsigned long iismod;

	if(g_spdif_out) return s5pc1xx_spdif_hw_params(substream, params, socdai);
	else 	s5pc1xx_spdif_power_off();

	s3cdbg("Entered %s\n", __FUNCTION__);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		dai->cpu_dai->dma_data = i2s->dma_playback;
	} else {
		dai->cpu_dai->dma_data = i2s->dma_capture;
	}

	/* Working copies of registers */
	iismod = readl(i2s->regs + S5PC1XX_IISMOD);
	iismod &= ~S5PC1XX_IISMOD_BLCMASK;

	/* Multi channel enable */
	switch (params_channels(params)) {
	case 1:
		s3cdbg("s3c i2s: 1 channel\n");
		break;
	case 2:
		s3cdbg("s3c i2s: 2 channel\n");
		break;
	case 4:
		s3cdbg("s3c i2s: 4 channel\n");
		break;
	case 6:
		s3cdbg("s3c i2s: 6 channel\n");
		break;
	default:
		printk(KERN_ERR "s3c-i2s-v32: %d channels unsupported\n",
		       params_channels(params));
		return -EINVAL;
	}

	/* Set the bit rate */
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S8:
		iismod |= S5PC1XX_IISMOD_BLC8BIT;
		break;
	case SNDRV_PCM_FORMAT_S16_LE:
		iismod |= S5PC1XX_IISMOD_BLC16BIT;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		iismod |= S5PC1XX_IISMOD_BLC24BIT;
		break;
	default:
		return -EINVAL;
	}

	writel(iismod, i2s->regs + S5PC1XX_IISMOD);
	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
		s3cdbg("%s : IISMOD [0x%08x]\n",__FUNCTION__, readl(i2s->regs + S5PC1XX_IISMOD));

	s3cdbg("s3c: params_channels %d\n", params_channels(params));
	s3cdbg("s3c: params_format %d\n", params_format(params));
	s3cdbg("s3c: params_subformat %d\n", params_subformat(params));
	s3cdbg("s3c: params_period_size %d\n", params_period_size(params));
	s3cdbg("s3c: params_period_bytes %d\n", params_period_bytes(params));
	s3cdbg("s3c: params_periods %d\n", params_periods(params));
	s3cdbg("s3c: params_buffer_size %d\n", params_buffer_size(params));
	s3cdbg("s3c: params_buffer_bytes %d\n", params_buffer_bytes(params));

	return 0;
}
Exemplo n.º 10
0
static int bcm947xx_pcm_hw_params(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *params)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct bcm947xx_runtime_data *brtd = runtime->private_data;
	//struct bcm947xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	bcm947xx_i2s_info_t *snd_bcm = rtd->dai->cpu_dai->private_data;
	unsigned long totbytes;
	unsigned int dma_ofs;
	unsigned long flags;

	DBG("%s %s\n", __FUNCTION__, bcm947xx_direction_str(substream));

	/* RX DMA requires a data offset due to the RX status header.
	 * Although there is a register setting to make the status header offset
	 * zero, it doesn't seem to work with 4709.
	*/
	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
		dma_ofs = BCM947XX_DMA_RXOFS_BYTES;
	} else {
		dma_ofs = 0;
	}

	/* Total bytes in the DMA buffer (excluding period fragement), including unused and
	 * header bytes.
	*/
	totbytes  = params_buffer_bytes(params);
	totbytes += params_periods(params) * (BCM947XX_DMA_DATA_BYTES_MAX - params_period_bytes(params));

	/* Account for period fragment. */
	if (params_buffer_bytes(params) > params_periods(params) * params_period_bytes(params)) {
		totbytes += dma_ofs;
	}

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

	spin_lock_irqsave(&brtd->lock, flags);

	brtd->dma_limit = params_periods(params); //runtime->hw.periods_min;
	brtd->dma_period = params_period_bytes(params);

	/* Virtual address of our runtime buffer */
	brtd->dma_start = (dma_addr_t)runtime->dma_area;
	brtd->dma_end = brtd->dma_start + totbytes;

	brtd->dma_ofs = dma_ofs;

	if (!(snd_bcm->in_use & ~(1 << substream->stream))) {
		/* Other stream not in-use (we own the settings). */
		/* It's safe to set the joint settings and mark as in-use. */
		bcm947xx_pcm_set_joint_duplex_settings(snd_bcm, params);
		snd_bcm->in_use |= (1 << substream->stream);

	} else if (!bcm947xx_pcm_joint_duplex_settings_equal(snd_bcm, params)) {
		/* Joint settings don't match; therefore, we're not in-use; bail. */
		DBG("%s joint duplex settings not equal\n", __FUNCTION__);
		snd_pcm_set_runtime_buffer(substream, NULL);
		snd_bcm->in_use &= ~(1 << substream->stream);
		return -EBUSY;

	} else {
		/* Joint settings matched, and perhaps our first time; mark as in-use! */
		snd_bcm->in_use |= (1 << substream->stream);
	}

	spin_unlock_irqrestore(&brtd->lock, flags);

	if (BCM947XX_PCM_DEBUG_ON)
	{
		size_t buffer_size = params_buffer_size(params);
		size_t buffer_bytes = params_buffer_bytes(params);
		size_t period_size = params_period_size(params);
		size_t period_bytes = params_period_bytes(params);
		size_t periods = params_periods(params);

		DBG("%s: dma_limit %d dma_ofs %d dma_addr %p dma_bytes %d dma_start %p dma_end %p\n",
			__FUNCTION__, brtd->dma_limit, brtd->dma_ofs, (void *)runtime->dma_addr, runtime->dma_bytes,
			(void *)brtd->dma_start, (void *)brtd->dma_end);
		DBG("%s: buffer_size %d buffer_bytes %d\n", __FUNCTION__, buffer_size, buffer_bytes);
		DBG("%s: period_size %d period_bytes %d periods %d\n", __FUNCTION__, period_size, period_bytes, periods);
	}

	return 0;
}
Exemplo n.º 11
0
static int s3c_i2s_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;

	unsigned long iiscon;
	unsigned long iismod;
	unsigned long iisfcon;
	s3cdbg("Entered %s\n", __FUNCTION__);

	writel((readl(S3C2410_MISCCR) & ~(7<<8))|(1<<8), S3C2410_MISCCR);

	/*Set I2C port to controll WM8753 codec*/
	s3c2410_gpio_pullup(S3C2410_GPE15, 0);
	s3c2410_gpio_pullup(S3C2410_GPE14, 0);
	s3c2410_gpio_cfgpin(S3C2410_GPE15, S3C2410_GPE15_IICSDA);
	s3c2410_gpio_cfgpin(S3C2410_GPE14, S3C2410_GPE14_IICSCL);

#if defined CONFIG_SND_SOC_I2S_V40
	/* Configure the I2S pins in correct mode */
	writel(0x0, S3C2450_GPESEL);

	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);

	writel(readl(S3C2410_GPEUP)| 0x3ff, S3C2410_GPEUP);

	writel(readl(S3C2450_GPBSEL)|(0x3<<3), S3C2450_GPBSEL);
	writel(readl(S3C2410_GPBUP)|(0xF<<18), S3C2410_GPBUP);

#elif defined CONFIG_SND_SOC_I2S_V32
	/* Configure the I2S pins in correct mode */
	writel(0x0, S3C2450_GPLSEL);

	s3c2410_gpio_cfgpin(S3C2410_GPL4, S3C2450_GPL4_I2S1_SCLK);
	s3c2410_gpio_cfgpin(S3C2410_GPL5, S3C2450_GPL5_I2S1_CDCLK);
	s3c2410_gpio_cfgpin(S3C2410_GPL6, S3C2450_GPL6_I2S1_SDI);
	s3c2410_gpio_cfgpin(S3C2410_GPL7, S3C2450_GPL7_I2S1_SDO);
	s3c2410_gpio_cfgpin(S3C2443_GPJ13, S3C2450_GPJ13_I2S1_LRCK);

	writel(readl(S3C2410_GPLUP)| (0xf<<4), S3C2410_GPLUP);
	writel(readl(S3C2443_GPJDN)| (0x3<<26), S3C2443_GPJDN);

#else
	printk("Error: S3C2450 I2S configration \n",);
#endif

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_out;
	} else {
		rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_in;
	}

	/* Working copies of registers */
	iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON);
	iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
	iisfcon = readl(s3c24xx_i2s.regs + S3C2443_IISFIC);

	iiscon |= S3C_IIS0CON_TXDMACTIVE;
	iiscon |= S3C_IIS0CON_RXDMACTIVE;

	iismod &= ~S3C_IIS0MOD_CLK_MASK;
	iismod |= S3C_IIS0MOD_IMS_EXTERNAL_MASTER| S3C_IIS0MOD_INTERNAL_CLK;
	iismod &= ~S3C_IIS0MOD_MODE_MASK;
	iismod |= S3C_IIS0MOD_TXRXMODE;

	/* Multi channel enable */
	iismod &= ~S3C_IIS0MOD_DCE_MASK;
	switch (params_channels(params)) {
	case 6:
		printk("s3c i2s: 5.1channel\n");
		iismod |= S3C_IIS0MOD_DCE_SD1;
		iismod |= S3C_IIS0MOD_DCE_SD2;
		break;
	case 4:
		printk("s3c i2s: 4 channel\n");
		iismod |= S3C_IIS0MOD_DCE_SD1;
		break;
	case 2:
		printk("s3c i2s: 2 channel\n");
		break;
	default:
		printk(KERN_ERR "s3c-i2s-v40: %d channels unsupported\n",
		       params_channels(params));
		return -EINVAL;
	}

	/* Set the bit rate */
#if 0
	iismod &= ~0x6000;
#endif
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S8:
		iismod |= S3C_IIS0MOD_8BIT;
		iismod &= ~S3C_IIS0MOD_BFS_MASK;
		iismod |= S3C_IIS0MOD_32FS;
		iismod &= ~S3C_IIS0MOD_FS_MASK;
		iismod |= S3C_IIS0MOD_384FS;
		break;
	case SNDRV_PCM_FORMAT_S16_LE:
		iismod &= ~S3C_IIS0MOD_FS_MASK;
		iismod &= ~S3C_IIS0MOD_BFS_MASK;
		iismod |= S3C_IIS0MOD_384FS | S3C_IIS0MOD_32FS;
		iismod &= ~S3C_IIS0MOD_BLC_MASK;
		iismod |= S3C_IIS0MOD_16BIT;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		iismod &= ~S3C_IIS0MOD_FS_MASK;
		iismod &= ~S3C_IIS0MOD_BFS_MASK;
		iismod |= S3C_IIS0MOD_384FS | S3C_IIS0MOD_48FS;
		iismod &= ~S3C_IIS0MOD_BLC_MASK;
		iismod |= S3C_IIS0MOD_24BIT;
		break;
	default:
		return -EINVAL;
	}


	iisfcon |= S3C_IIS_TX_FLUSH;
	iisfcon |= S3C_IIS_RX_FLUSH;

	writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON);
	iismod &= ~S3C_IIS0MOD_FM_MASK;
	writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
	writel(iisfcon, s3c24xx_i2s.regs + S3C2443_IISFIC);

	/* Tx, Rx fifo flush bit clear */
	iisfcon  &= ~(S3C_IIS_TX_FLUSH | S3C_IIS_RX_FLUSH);
	writel(iisfcon, s3c24xx_i2s.regs + S3C2443_IISFIC);

	s3cdbg("s3c iis mode: 0x%08x\n", readl(s3c24xx_i2s.regs + S3C2410_IISMOD));
	s3cdbg("s3c: params_channels %d\n", params_channels(params));
	s3cdbg("s3c: params_format %d\n", params_format(params));
	s3cdbg("s3c: params_subformat %d\n", params_subformat(params));
	s3cdbg("s3c: params_period_size %d\n", params_period_size(params));
	s3cdbg("s3c: params_period_bytes %d\n", params_period_bytes(params));
	s3cdbg("s3c: params_periods %d\n", params_periods(params));
	s3cdbg("s3c: params_buffer_size %d\n", params_buffer_size(params));
	s3cdbg("s3c: params_buffer_bytes %d\n", params_buffer_bytes(params));
	s3cdbg("s3c: params_tick_time %d\n", params_tick_time(params));

	return 0;
}
Exemplo n.º 12
0
static int s3c_i2s_v50_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;

	unsigned long iiscon;
	unsigned long iismod;
	unsigned long iisfcon;
	
	s3cdbg("Entered %s\n", __FUNCTION__);

	s5pc1xx_i2s.master = 1;
	
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		rtd->dai->cpu_dai->dma_data = &s5pc1xx_i2s_pcm_stereo_out;
	} else {
		rtd->dai->cpu_dai->dma_data = &s5pc1xx_i2s_pcm_stereo_in;
	}

	/* Working copies of registers */
	iiscon = readl(s5pc1xx_i2s.regs + S3C64XX_IIS0CON);
	iismod = readl(s5pc1xx_i2s.regs + S3C64XX_IIS0MOD);
	iisfcon = readl(s5pc1xx_i2s.regs + S3C64XX_IIS0FIC);

	/* is port used by another stream */
	if (!(iiscon & S3C64XX_IIS0CON_I2SACTIVE)) {

		/* Clear BFS field [2:1] */
		iismod &= ~(0x3<<1);
		iismod |= S3C64XX_IIS0MOD_32FS | S3C64XX_IIS0MOD_INTERNAL_CLK;

		if (!s5pc1xx_i2s.master)
			iismod |= S3C64XX_IISMOD_SLAVE;
		else
			iismod |= S3C64XX_IIS0MOD_IMS_EXTERNAL_MASTER;
	}

	iiscon |= S3C64XX_IISCON_FTXURINTEN;
	iiscon |= S3C64XX_IIS0CON_TXDMACTIVE;
	iiscon |= S3C64XX_IIS0CON_RXDMACTIVE;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		iismod |= S3C64XX_IIS0MOD_TXMODE;
		iisfcon |= S3C64XX_IIS_TX_FLUSH;
	} else {
		iismod |= S3C64XX_IIS0MOD_RXMODE;
		iisfcon |= S3C64XX_IIS_RX_FLUSH;
	}

	/* Multi channel enable */
	iismod &= ~S3C64XX_IIS0MOD_DCE_MASK;
	switch (params_channels(params)) {
	case 6:
		printk("s3c i2s: 5.1channel\n");
		iismod |= S3C64XX_IIS0MOD_DCE_SD2;
		iismod |= S3C64XX_IIS0MOD_DCE_SD2;
		break;
	case 4:
		printk("s3c i2s: 4 channel\n");
		iismod |= S3C64XX_IIS0MOD_DCE_SD2;
		break;
	case 2:
		printk("s3c i2s: 2 channel\n");
		break;
	default:
		printk(KERN_ERR "s3c-i2s-v50: %d channels unsupported\n",
		       params_channels(params));
		return -EINVAL;
	}

	/* Set the bit rate */
	iismod &= ~0x6000;
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		iismod &= ~S3C64XX_IIS0MOD_FS_MASK;
		iismod |= S3C64XX_IIS0MOD_256FS | S3C64XX_IIS0MOD_32FS;
		iismod &= ~(0x3<<13);
		iismod |= S3C64XX_IIS0MOD_16BIT;
		break;
	case SNDRV_PCM_FORMAT_S8:
		iismod |= S3C64XX_IIS0MOD_8BIT;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		iismod &= ~S3C64XX_IIS0MOD_FS_MASK;
		iismod |= S3C64XX_IIS0MOD_384FS | S3C64XX_IIS0MOD_48FS;
		iismod &= ~(0x3<<13);
		iismod |= S3C64XX_IIS0MOD_24BIT;
		break;
	default:
		return -EINVAL;
	}

	writel(iisfcon, s5pc1xx_i2s.regs + S3C64XX_IIS0FIC);
	writel(iiscon, s5pc1xx_i2s.regs + S3C64XX_IIS0CON);
	writel(iismod, s5pc1xx_i2s.regs + S3C64XX_IIS0MOD);

	// Tx, Rx fifo flush bit clear
	iisfcon  &= ~(S3C64XX_IIS_TX_FLUSH | S3C64XX_IIS_RX_FLUSH);
	writel(iisfcon, s5pc1xx_i2s.regs + S3C64XX_IIS0FIC);

	s3cdbg("s3c iis mode: 0x%08x\n", readl(s5pc1xx_i2s.regs + S3C64XX_IIS0MOD));
	s3cdbg("s3c: params_channels %d\n", params_channels(params));
	s3cdbg("s3c: params_format %d\n", params_format(params));
	s3cdbg("s3c: params_subformat %d\n", params_subformat(params));
	s3cdbg("s3c: params_period_size %d\n", params_period_size(params));
	s3cdbg("s3c: params_period_bytes %d\n", params_period_bytes(params));
	s3cdbg("s3c: params_periods %d\n", params_periods(params));
	s3cdbg("s3c: params_buffer_size %d\n", params_buffer_size(params));
	s3cdbg("s3c: params_buffer_bytes %d\n", params_buffer_bytes(params));
//	s3cdbg("s3c: params_tick_time %d\n", params_tick_time(params));
	s3cdbg("hw_params: IISCON: %lx IISMOD: %lx\n", iiscon, iismod);

	return 0;

}
Exemplo n.º 13
0
static int s3c_i2s_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params,
				struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	u32 iismod;
	
	debug_msg("%s\n", __FUNCTION__);

#ifdef CONFIG_S3C_DMA_PL080_SOL
	rtd->dai->cpu_dai->dma_data = s3c_i2s_dai.dma_data;
#endif

#ifdef CONFIG_S3C_DMA_PL080	
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		rtd->dai->cpu_dai->dma_data = &s3c_i2s_pcm_stereo_out;
	else
		rtd->dai->cpu_dai->dma_data = &s3c_i2s_pcm_stereo_in;
#endif
	/* Working copies of register */
	iismod = readl(s3c_i2s.regs + S3C_IISMOD);
	iismod &= ~S3C_IISMOD_BLCMASK;

#ifdef CONFIG_S3C_DMA_PL080	
	/* TODO */
	switch(params_channels(params)) {
	case 1:
		s3c_i2s_pcm_stereo_in.dma_size = 2;
		break;
	case 2:
		s3c_i2s_pcm_stereo_in.dma_size = 4;
		break;
	case 4:
		break;
	case 6:
		break;
	default:
		break;
	}
#endif

	/* RFS & BFS are set by dai_link(machine specific) code via set_clkdiv */
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S8:
		iismod |= S3C_IISMOD_8BIT;
 		break;
	case SNDRV_PCM_FORMAT_S16_LE:
 		iismod |= S3C_IISMOD_16BIT;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
 		iismod |= S3C_IISMOD_24BIT;
		break;
	default:
		return -EINVAL;
	}


	writel(iismod, s3c_i2s.regs + S3C_IISMOD);


	debug_msg("s3c iis mode: 0x%08x\n", readl(s3c6410_i2s.regs + S3C64XX_IIS0MOD));
	debug_msg("s3c: params_channels %d\n", params_channels(params));
	debug_msg("s3c: params_format %d\n", params_format(params));
	debug_msg("s3c: params_subformat %d\n", params_subformat(params));
	debug_msg("s3c: params_period_size %d\n", params_period_size(params));
	debug_msg("s3c: params_period_bytes %d\n", params_period_bytes(params));
	debug_msg("s3c: params_periods %d\n", params_periods(params));
	debug_msg("s3c: params_buffer_size %d\n", params_buffer_size(params));
	debug_msg("s3c: params_buffer_bytes %d\n", params_buffer_bytes(params));
	debug_msg("hw_params: IISMOD: %x\n", iismod);

	return 0;
}
Exemplo n.º 14
0
static int spdif_hw_params(struct snd_pcm_substream *
		substream, struct snd_pcm_hw_params *params,
		struct snd_soc_dai *dai)
{
	struct rockchip_spdif_info *spdif = to_info(dai);
	void __iomem *regs = spdif->regs;
	unsigned long flags;
	int cfgr, dmac, intcr, chnsr_byte[5] = {0};
	int data_type, err_flag, data_len, data_info;
	int bs_num, repetition, burst_info;

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

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		dai->playback_dma_data = &spdif->dma_playback;
	} else {
		pr_err("spdif:Capture is not supported\n");
		return -EINVAL;
	}

	spin_lock_irqsave(&spdif->lock, flags);

	cfgr = readl(regs + CFGR) & CFGR_VALID_DATA_MASK;

	cfgr &= ~CFGR_VALID_DATA_MASK;
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		cfgr |= CFGR_VALID_DATA_16bit;
		break;
	case SNDRV_PCM_FORMAT_S20_3LE:
		cfgr |= CFGR_VALID_DATA_20bit;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		cfgr |= CFGR_VALID_DATA_24bit;
		break;
	default:
		goto err;
	}

	cfgr &= ~CFGR_HALFWORD_TX_MASK;
	cfgr |= CFGR_HALFWORD_TX_ENABLE;

	/* set most MCLK:192kHz */
	cfgr &= ~CFGR_CLK_RATE_MASK;
	cfgr |= (1<<16);

	cfgr &= ~CFGR_JUSTIFIED_MASK;
	cfgr |= CFGR_JUSTIFIED_RIGHT;

	cfgr &= ~CFGR_CSE_MASK;
	cfgr |= CFGR_CSE_DISABLE;

	cfgr &= ~CFGR_LINEAR_MASK;
	cfgr |= CFGR_LINEAR_PCM;

	/* stream type*/
	if (!snd_pcm_format_linear(params_format(params)))
		cfgr |= CFGR_NON_LINEAR_PCM;

	cfgr &= ~CFGR_PRE_CHANGE_MASK;
	cfgr |= CFGR_PRE_CHANGE_ENALBLE;

	writel(cfgr, regs + CFGR);

	intcr = readl(regs + INTCR) & INTCR_SDBEIE_MASK;
	intcr |= INTCR_SDBEIE_ENABLE;
	writel(intcr, regs + INTCR);

	dmac = readl(regs + DMACR) & DMACR_TRAN_DMA_MASK &
		(~DMACR_TRAN_DATA_LEVEL_MASK);
	dmac |= 0x10;
	writel(dmac, regs + DMACR);

	/*
	* channel byte 0:
	* Bit 1
	* 1 Main data field represents linear PCM samples.
	* 0 Main data field used for purposes other purposes.
	*/
	chnsr_byte[0] = (0x0) | (0x0 << 1) |
		(0x0 << 2) | (0x0 << 3) |
		(0x00 << 6);
	chnsr_byte[1] = (0x0);
	chnsr_byte[2] = (0x0) | (0x0 << 4) | (0x0 << 6);
	chnsr_byte[3] = (0x00) | (0x00);
	chnsr_byte[4] = (0x0 << 4) | (0x01 << 1 | 0x0);

	/* set stream type */
	if (!snd_pcm_format_linear(params_format(params))) {
		chnsr_byte[0] |= (0x1<<1);
		chnsr_byte[4] = (0x0<<4)|(0x00<<1|0x0);
	}
	writel((chnsr_byte[4] << 16)
			| (chnsr_byte[4]),
			regs + SPDIF_CHNSR02_ADDR);
	writel((chnsr_byte[3] << 24) | (chnsr_byte[2] << 16) |
		(chnsr_byte[3] << 8) | (chnsr_byte[2]),
		regs + SPDIF_CHNSR01_ADDR);
	writel((chnsr_byte[1] << 24) | (chnsr_byte[0] << 16) |
		(chnsr_byte[1] << 8) | (chnsr_byte[0]),
		regs + SPDIF_CHNSR00_ADDR);

	/* set non-linear params */
	if (!snd_pcm_format_linear(params_format(params))) {
		switch (params_format(params)) {
		case SNDRV_NON_LINEAR_PCM_FORMAT_AC3:
			/* bit0:6 AC-3:0x01, DTS-I -II -III:11,12,13 */
			data_type = burst_info_DATA_TYPE_AC3;
			/*
			* repetition:AC-3:1536
			* DTS-I -II -III:512,1024,2048 EAC3:6144
			*/
			repetition = 1536;
			break;
		case SNDRV_NON_LINEAR_PCM_FORMAT_DTS_I:
			data_type = BURST_INFO_DATA_TYPE_DTS_I;
			repetition = 512;
			break;
		case SNDRV_NON_LINEAR_PCM_FORMAT_EAC3:
			data_type = burst_info_DATA_TYPE_EAC3;
			repetition = 6144;
			break;
		default:
			return -EINVAL;
		}
		err_flag = 0x0;
		data_len = params_period_size(params) * 2 * 16;
		data_info = 0;
		bs_num = 0x0;
		burst_info = (data_len << 16) | (bs_num << 13) |
			(data_info << 8) | (err_flag << 7) | data_type;
		writel(burst_info, regs + SPDIF_BURST_INFO);
		writel(repetition, regs + SPDIF_REPETTION);
	}
	spin_unlock_irqrestore(&spdif->lock, flags);

	return 0;
err:
	spin_unlock_irqrestore(&spdif->lock, flags);
	return -EINVAL;
}