Example #1
0
int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct tegra_runtime_data *prtd = runtime->private_data;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct tegra_pcm_dma_params * dmap;
	int i;

	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);

	/* Limit dma_req_count to period count */
	if (prtd->dma_req_count > params_periods(params))
		prtd->dma_req_count = params_periods(params);
	dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
	if (dmap) {
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
			for (i = 0; i < prtd->dma_req_count; i++)
				setup_dma_tx_request(&prtd->dma_req[i], dmap);
		} else {
			for (i = 0; i < prtd->dma_req_count; i++)
				setup_dma_rx_request(&prtd->dma_req[i], dmap);
		}
	}
	for (i = 0; i < prtd->dma_req_count; i++)
		prtd->dma_req[i].size = params_period_bytes(params);

	return 0;
}
Example #2
0
/*
 * hw_params callback
 */
static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
			      struct snd_pcm_hw_params *hw_params)
{
	struct cx23885_audio_dev *chip = snd_pcm_substream_chip(substream);
	struct cx23885_audio_buffer *buf;
	int ret;

	if (substream->runtime->dma_area) {
		dsp_buffer_free(chip);
		substream->runtime->dma_area = NULL;
	}

	chip->period_size = params_period_bytes(hw_params);
	chip->num_periods = params_periods(hw_params);
	chip->dma_size = chip->period_size * params_periods(hw_params);

	BUG_ON(!chip->dma_size);
	BUG_ON(chip->num_periods & (chip->num_periods-1));

	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
	if (NULL == buf)
		return -ENOMEM;

	buf->bpl = chip->period_size;
	chip->buf = buf;

	ret = cx23885_alsa_dma_init(chip,
			(PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT));
	if (ret < 0)
		goto error;

	ret = cx23885_alsa_dma_map(chip);
	if (ret < 0)
		goto error;

	ret = cx23885_risc_databuffer(chip->pci, &buf->risc, buf->sglist,
				   chip->period_size, chip->num_periods, 1);
	if (ret < 0)
		goto error;

	/* Loop back to start of program */
	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP|RISC_IRQ1|RISC_CNT_INC);
	buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
	buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */

	substream->runtime->dma_area = chip->buf->vaddr;
	substream->runtime->dma_bytes = chip->dma_size;
	substream->runtime->dma_addr = 0;

	return 0;

error:
	kfree(buf);
	chip->buf = NULL;
	return ret;
}
static int s3c_idma_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct lpam_i2s_pdata *prtd = substream->runtime->private_data;
	unsigned long idma_totbytes;

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

	idma_totbytes = params_buffer_bytes(params);
	prtd->end = LP_TXBUFF_ADDR + idma_totbytes;
	prtd->period = params_periods(params);
	s3c_idma.dma_end    = prtd->end;
	s3c_idma.period_val = prtd->period;

	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
	memset(runtime->dma_area, 0, LP_BUFSIZE);

	runtime->dma_bytes = idma_totbytes;

	s3c_idma_setcallbk(s3c_idma_done, params_period_bytes(params));

	prtd->start = runtime->dma_addr;
	prtd->pos = prtd->start;
	prtd->end = prtd->start + idma_totbytes;

	printk("DmaAddr=@%x Total=%lubytes PrdSz=%u #Prds=%u\n",
			prtd->start, idma_totbytes, params_period_bytes(params), prtd->period);

	return 0;
}
static int snd_atiixp_pcm_hw_params(struct snd_pcm_substream *substream,
				   struct snd_pcm_hw_params *hw_params)
{
	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
	struct atiixp_dma *dma = substream->runtime->private_data;
	int err;
	int i;

	err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
	if (err < 0)
		return err;
	dma->buf_addr = substream->runtime->dma_addr;
	dma->buf_bytes = params_buffer_bytes(hw_params);

	err = atiixp_build_dma_packets(chip, dma, substream,
				       params_periods(hw_params),
				       params_period_bytes(hw_params));
	if (err < 0)
		return err;

	/*                   */
	for (i = 0; i < NUM_ATI_CODECS; i++) {
		if (! chip->ac97[i])
			continue;
		snd_ac97_write(chip->ac97[i], AC97_LINE1_RATE, params_rate(hw_params));
		snd_ac97_write(chip->ac97[i], AC97_LINE1_LEVEL, 0);
	}

	return err;
}
Example #5
0
static int txx9aclc_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 snd_soc_device *socdev = rtd->socdev;
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct txx9aclc_dmadata *dmadata = runtime->private_data;
	int ret;

	ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
	if (ret < 0)
		return ret;

	dev_dbg(socdev->dev,
		"runtime->dma_area = %#lx dma_addr = %#lx dma_bytes = %zd "
		"runtime->min_align %ld\n",
		(unsigned long)runtime->dma_area,
		(unsigned long)runtime->dma_addr, runtime->dma_bytes,
		runtime->min_align);
	dev_dbg(socdev->dev,
		"periods %d period_bytes %d stream %d\n",
		params_periods(params), params_period_bytes(params),
		substream->stream);

	dmadata->substream = substream;
	dmadata->pos = 0;
	return 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;
}
Example #7
0
static int idma_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct idma_ctrl *prtd = substream->runtime->private_data;
	u32 ahb = readl(idma.regs + I2SAHB);

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

	ahb |= (AHB_DMARLD | AHB_INTMASK);
	writel(ahb, idma.regs + I2SAHB);

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

	prtd->start = prtd->pos = runtime->dma_addr;
	prtd->period = params_periods(params);
	prtd->periodsz = params_period_bytes(params);
	prtd->end = prtd->start + runtime->dma_bytes;

	idma_setcallbk(substream, idma_done);
#ifndef PRODUCT_SHIP
	pr_info("I:%s:DmaAddr=@%x Total=%d PrdSz=%d #Prds=%d dma_area=0x%x\n",
		(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? "P" : "C",
		prtd->start, runtime->dma_bytes, prtd->periodsz,
		prtd->period, (unsigned int)runtime->dma_area);
#endif

	return 0;
}
Example #8
0
static int idma_hw_params(struct snd_pcm_substream *substream,
                          struct snd_pcm_hw_params *params)
{
    struct snd_pcm_runtime *runtime = substream->runtime;
    struct idma_ctrl *prtd = substream->runtime->private_data;
    u32 mod = readl(idma.regs + I2SMOD);
    u32 ahb = readl(idma.regs + I2SAHB);

    ahb |= (AHB_DMARLD | AHB_INTMASK);
    mod |= MOD_TXS_IDMA;
    writel(ahb, idma.regs + I2SAHB);
    writel(mod, idma.regs + I2SMOD);

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

    prtd->start = prtd->pos = runtime->dma_addr;
    prtd->period = params_periods(params);
    prtd->periodsz = params_period_bytes(params);
    prtd->end = runtime->dma_addr + runtime->dma_bytes;

    idma_setcallbk(substream, idma_done);

    return 0;
}
Example #9
0
static int smi2021_pcm_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *hw_params)
{
	int size, rc;
	size = params_period_bytes(hw_params) * params_periods(hw_params);

	rc = pcm_buffer_alloc(substream, size);
	if (rc < 0)
		return rc;


	return 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;
	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;
}
Example #11
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;
}
Example #12
0
/*
 * PCM operations
 */
static int lpc313x_pcm_hw_params(struct snd_pcm_substream *substream,
			         struct snd_pcm_hw_params *params)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct lpc313x_dma_data *prtd = runtime->private_data;

	/* this may get called several times by oss emulation
	 * with different params
	 */
	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
	runtime->dma_bytes = params_buffer_bytes(params);

	prtd->dma_buffer = runtime->dma_addr;
	prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes;
	prtd->period_size = params_period_bytes(params);
	prtd->num_periods = params_periods(params);

	return 0;
}
Example #13
0
static int snd_cs5535audio_hw_params(struct snd_pcm_substream *substream,
				     struct snd_pcm_hw_params *hw_params)
{
	struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
	struct cs5535audio_dma *dma = substream->runtime->private_data;
	int err;

	err = snd_pcm_lib_malloc_pages(substream,
					params_buffer_bytes(hw_params));
	if (err < 0)
		return err;
	dma->buf_addr = substream->runtime->dma_addr;
	dma->buf_bytes = params_buffer_bytes(hw_params);

	err = cs5535audio_build_dma_packets(cs5535au, dma, substream,
					    params_periods(hw_params),
					    params_period_bytes(hw_params));
	return err;
}
Example #14
0
/*
 * hw_params callback:
 * allocate the buffer and build up the buffer description table
 */
static int snd_via82xx_hw_params(struct snd_pcm_substream *substream,
				 struct snd_pcm_hw_params *hw_params)
{
	struct via82xx_modem *chip = snd_pcm_substream_chip(substream);
	struct viadev *viadev = substream->runtime->private_data;
	int err;

	err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
	if (err < 0)
		return err;
	err = build_via_table(viadev, substream, chip->pci,
			      params_periods(hw_params),
			      params_period_bytes(hw_params));
	if (err < 0)
		return err;

	snd_ac97_write(chip->ac97, AC97_LINE1_RATE, params_rate(hw_params));
	snd_ac97_write(chip->ac97, AC97_LINE1_LEVEL, 0);

	return 0;
}
Example #15
0
/*
 * hw_params - allocate the buffer and set up buffer descriptors
 */
static int snd_atiixp_pcm_hw_params(snd_pcm_substream_t *substream,
                                    snd_pcm_hw_params_t *hw_params)
{
    atiixp_t *chip = snd_pcm_substream_chip(substream);
    atiixp_dma_t *dma = (atiixp_dma_t *)substream->runtime->private_data;
    int err;

    err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
    if (err < 0)
        return err;
    dma->buf_addr = substream->runtime->dma_addr;
    dma->buf_bytes = params_buffer_bytes(hw_params);

    err = atiixp_build_dma_packets(chip, dma, substream,
                                   params_periods(hw_params),
                                   params_period_bytes(hw_params));
    if (err < 0)
        return err;

    if (dma->ac97_pcm_type >= 0) {
        struct ac97_pcm *pcm = chip->pcms[dma->ac97_pcm_type];
        /* PCM is bound to AC97 codec(s)
         * set up the AC97 codecs
         */
        if (dma->pcm_open_flag) {
            snd_ac97_pcm_close(pcm);
            dma->pcm_open_flag = 0;
        }
        err = snd_ac97_pcm_open(pcm, params_rate(hw_params),
                                params_channels(hw_params),
                                pcm->r[0].slots);
        if (err >= 0)
            dma->pcm_open_flag = 1;
    }

    return err;
}
static int s3c_idma_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct lpam_i2s_pdata *prtd = substream->runtime->private_data;

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

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

	prtd->start = prtd->pos = runtime->dma_addr;
	prtd->period = params_periods(params);
	prtd->periodsz = params_period_bytes(params);
	prtd->end = LP_TXBUFF_ADDR + runtime->dma_bytes;

	s3c_idma_setcallbk(substream, s3c_idma_done);

	pr_info("DmaAddr=@%x Total=%dbytes PrdSz=%d #Prds=%d dma_area=0x%x\n",
			prtd->start, runtime->dma_bytes, prtd->periodsz,
			prtd->period, (unsigned int)runtime->dma_area);
	return 0;
}
Example #17
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;
}
Example #18
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;
}
Example #19
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;
}
Example #20
0
static int rockchip_pcm_hw_params(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *params)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct rockchip_runtime_data *prtd = runtime->private_data;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
	struct rockchip_pcm_dma_params *dma = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
	struct rockchip_pcm_dma_params *dma = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
#else
	struct rockchip_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data;
#endif
	unsigned long totbytes = params_buffer_bytes(params);
	int ret = 0;

	DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
	/* return if this is a bufferless transfer e.g.
	 * codec <--> BT codec or GSM modem -- lg FIXME */
	if (!dma)
		return 0;

	/* this may get called several times by oss emulation
	 * with different params -HW */
	if (prtd->params == NULL) {
		/* prepare DMA */
		prtd->params = dma;
#ifdef CONFIG_SND_I2S_DMA_EVENT_DYNAMIC
		DBG("params %p, client %p, channel %d\n", prtd->params,prtd->params->client, prtd->params->channel);
		ret = rk29_dma_request(prtd->params->channel, prtd->params->client, NULL);
		DBG("Enter::%s, %d, ret=%d, Channel=%d\n", __FUNCTION__, __LINE__, ret, prtd->params->channel);
		if (ret) {
			DBG(KERN_ERR "failed to get dma channel\n");
			return ret;
		}
#endif
	}

	ret = rk29_dma_set_buffdone_fn(prtd->params->channel, rk29_audio_buffdone);
	if(ret < 0){
		DBG(KERN_ERR "failed to rk29_dma_set_buffdone_fn\n");
		return ret;
	}
	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);

	runtime->dma_bytes = totbytes;

	spin_lock_irq(&prtd->lock);
	prtd->dma_loaded = 0;
	prtd->dma_limit = params_periods(params);//runtime->hw.periods_min;
	prtd->dma_period = params_period_bytes(params);
	prtd->dma_start = runtime->dma_addr;
	prtd->dma_pos = prtd->dma_start;
	prtd->dma_end = prtd->dma_start + prtd->dma_limit*prtd->dma_period;
	prtd->transfer_first = 1;
	prtd->curr = NULL;
	prtd->next = NULL;
	prtd->end = NULL;
	spin_unlock_irq(&prtd->lock);
	printk(KERN_DEBUG "i2s dma info:periodsize(%ld),limit(%d),buffersize(%d),over(%d)\n",
			prtd->dma_period,prtd->dma_limit,totbytes,totbytes-(prtd->dma_period*prtd->dma_limit));
	return ret;
}
Example #21
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;
}
Example #22
0
static int s5p_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;
	unsigned long idma_totbytes;

    if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
#ifdef CONFIG_S5P64XX_LPAUDIO
        idma_totbytes = params_buffer_bytes(params) * CONFIG_ANDROID_BUF_NUM;
        s3c_i2s.idma_end = LP_TXBUFF_ADDR + idma_totbytes;
        s3c_i2s.idma_period = params_periods(params);
#endif
		rtd->dai->cpu_dai->dma_data = &s3c_i2s_pcm_stereo_out;
	}
	else
		rtd->dai->cpu_dai->dma_data = &s3c_i2s_pcm_stereo_in;

	/* Working copies of register */
	iismod = readl(s3c_i2s.regs + S3C_IISMOD);
#ifdef CONFIG_SND_S5P_RP
	iismod &= ~(S3C_IISMOD_BLCMASK | S3C_IISMOD_BLCPMASK | S3C_IISMOD_BLCSMASK);
#else
	iismod &= ~(S3C_IISMOD_BLCMASK | S3C_IISMOD_BLCMASK_LP);
#endif

	/* 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;
	}

	/* RFS & BFS are set by dai_link(machine specific) code via set_clkdiv */
#ifdef CONFIG_SND_S5P_RP
	/* Set same pcm format for primary & secondary port */
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S8:
		iismod |= S3C_IISMOD_8BIT | S3C_IISMOD_S8BIT | S3C_IISMOD_P8BIT;
 		break;
 	case SNDRV_PCM_FORMAT_S16_LE:
 		iismod |= S3C_IISMOD_16BIT | S3C_IISMOD_S16BIT | S3C_IISMOD_P16BIT;
 		break;
 	case SNDRV_PCM_FORMAT_S24_LE:
 		iismod |= S3C_IISMOD_24BIT | S3C_IISMOD_S24BIT | S3C_IISMOD_P24BIT;
 		break;
	default:
		return -EINVAL;
 	}
#else
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S8:
		iismod |= S3C_IISMOD_8BIT | S3C_IISMOD_8BIT_LP;
 		break;
 	case SNDRV_PCM_FORMAT_S16_LE:
 		iismod |= S3C_IISMOD_16BIT | S3C_IISMOD_16BIT_LP;
 		break;
 	case SNDRV_PCM_FORMAT_S24_LE:
 		iismod |= S3C_IISMOD_24BIT | S3C_IISMOD_24BIT_LP;
 		break;
	default:
		return -EINVAL;
 	}
#endif
	writel(iismod, s3c_i2s.regs + S3C_IISMOD);

	return 0;
}
Example #23
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;

}
/* hw_params callback */
static int
snd_vortex_pcm_hw_params(snd_pcm_substream_t * substream,
			 snd_pcm_hw_params_t * hw_params)
{
	chip_t *chip = snd_pcm_substream_chip(substream);
	stream_t *stream = (stream_t *) (substream->runtime->private_data);
	snd_pcm_sgbuf_t *sgbuf;
	int err;

	// Alloc buffer memory.
	err =
	    snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
	if (err < 0) {
		printk(KERN_ERR "Vortex: pcm page alloc failed!\n");
		return err;
	}
	//sgbuf = (snd_pcm_sgbuf_t *) substream->runtime->dma_private;
	sgbuf = snd_pcm_substream_sgbuf(substream);
	/*
	   printk(KERN_INFO "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params),
	   params_period_bytes(hw_params), params_channels(hw_params));
	 */
	// Make audio routes and config buffer DMA.
	if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
		int dma, type = VORTEX_PCM_TYPE(substream->pcm);
		/* Dealloc any routes. */
		if (stream != NULL)
			vortex_adb_allocroute(chip, stream->dma,
					      stream->nr_ch, stream->dir,
					      stream->type);
		/* Alloc routes. */
		dma =
		    vortex_adb_allocroute(chip, -1,
					  params_channels(hw_params),
					  substream->stream, type);
		if (dma < 0)
			return dma;
		stream = substream->runtime->private_data = &chip->dma_adb[dma];
		stream->substream = substream;
		/* Setup Buffers. */
		vortex_adbdma_setbuffers(chip, dma, sgbuf,
					 params_period_bytes(hw_params),
					 params_periods(hw_params));
	}
#ifndef CHIP_AU8810
	else {
		/* if (stream != NULL)
		   vortex_wt_allocroute(chip, substream->number, 0); */
		vortex_wt_allocroute(chip, substream->number,
				     params_channels(hw_params));
		stream = substream->runtime->private_data =
		    &chip->dma_wt[substream->number];
		stream->dma = substream->number;
		stream->substream = substream;
		vortex_wtdma_setbuffers(chip, substream->number, sgbuf,
					params_period_bytes(hw_params),
					params_periods(hw_params));
	}
#endif
	return 0;
}
static int dma_hw_params(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *params)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct runtime_data *prtd = runtime->private_data;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	unsigned long totbytes = params_buffer_bytes(params);
	struct s3c_dma_params *dma =
		snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
	struct samsung_dma_req req;
	struct samsung_dma_config config;

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

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

	/* this may get called several times by oss emulation
	 * with different params -HW */
	if (prtd->params == NULL) {
		/* prepare DMA */
		prtd->params = dma;

		pr_debug("params %p, client %p, channel %d\n", prtd->params,
			prtd->params->client, prtd->params->channel);

		prtd->params->ops = samsung_dma_get_ops();

		req.cap = (samsung_dma_has_circular() ?
			DMA_CYCLIC : DMA_SLAVE);
		req.client = prtd->params->client;
		config.direction =
			(substream->stream == SNDRV_PCM_STREAM_PLAYBACK
			? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM);
		config.width = prtd->params->dma_size;
		config.maxburst = 1;
		config.fifo = prtd->params->dma_addr;
		prtd->params->ch = prtd->params->ops->request(
				prtd->params->channel, &req);
		prtd->params->ops->config(prtd->params->ch, &config);
	}

	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);

	runtime->dma_bytes = totbytes;

	spin_lock_irq(&prtd->lock);
	prtd->dma_loaded = 0;
	prtd->dma_period = params_period_bytes(params);
	prtd->dma_start = runtime->dma_addr;
	prtd->dma_pos = prtd->dma_start;
	prtd->dma_end = prtd->dma_start + totbytes;

	if (runtime->dma_addr > EXYNOS_PA_AUDSS)
		prtd->dram_used = true;
	else
		prtd->dram_used = false;
	spin_unlock_irq(&prtd->lock);

	pr_debug("ADMA:%s:DmaAddr=@%x Total=%d PrdSz=%d #Prds=%d dma_area=0x%x\n",
		(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? "P" : "C",
		prtd->dma_start, runtime->dma_bytes,
		params_period_bytes(params), params_periods(params),
		(unsigned int)runtime->dma_area);

	return 0;
}
Example #26
0
/* hw_params callback */
static int
snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
			 struct snd_pcm_hw_params *hw_params)
{
	vortex_t *chip = snd_pcm_substream_chip(substream);
	stream_t *stream = (stream_t *) (substream->runtime->private_data);
	int err;

	// Alloc buffer memory.
	err =
	    snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
	if (err < 0) {
		dev_err(chip->card->dev, "Vortex: pcm page alloc failed!\n");
		return err;
	}
	/*
	   pr_info( "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params),
	   params_period_bytes(hw_params), params_channels(hw_params));
	 */
	spin_lock_irq(&chip->lock);
	// Make audio routes and config buffer DMA.
	if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
		int dma, type = VORTEX_PCM_TYPE(substream->pcm);
		/* Dealloc any routes. */
		if (stream != NULL)
			vortex_adb_allocroute(chip, stream->dma,
					      stream->nr_ch, stream->dir,
					      stream->type,
					      substream->number);
		/* Alloc routes. */
		dma =
		    vortex_adb_allocroute(chip, -1,
					  params_channels(hw_params),
					  substream->stream, type,
					  substream->number);
		if (dma < 0) {
			spin_unlock_irq(&chip->lock);
			return dma;
		}
		stream = substream->runtime->private_data = &chip->dma_adb[dma];
		stream->substream = substream;
		/* Setup Buffers. */
		vortex_adbdma_setbuffers(chip, dma,
					 params_period_bytes(hw_params),
					 params_periods(hw_params));
		if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
			chip->pcm_vol[substream->number].active = 1;
			vortex_notify_pcm_vol_change(chip->card,
				chip->pcm_vol[substream->number].kctl, 1);
		}
	}
#ifndef CHIP_AU8810
	else {
		/* if (stream != NULL)
		   vortex_wt_allocroute(chip, substream->number, 0); */
		vortex_wt_allocroute(chip, substream->number,
				     params_channels(hw_params));
		stream = substream->runtime->private_data =
		    &chip->dma_wt[substream->number];
		stream->dma = substream->number;
		stream->substream = substream;
		vortex_wtdma_setbuffers(chip, substream->number,
					params_period_bytes(hw_params),
					params_periods(hw_params));
	}
#endif
	spin_unlock_irq(&chip->lock);
	return 0;
}
static int msm_afe_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_dma_buffer *dma_buf = &substream->dma_buffer;
	struct pcm_afe_info *prtd = runtime->private_data;
	struct afe_audio_buffer *buf;
	int dir, rc;

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

	mutex_lock(&prtd->lock);
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		dir = IN;
	else
		dir = OUT;

	rc = q6afe_audio_client_buf_alloc_contiguous(dir,
		prtd->audio_client,
		(params_buffer_bytes(params) / params_periods(params)),
		params_periods(params));
	pr_debug("params_buffer_bytes(params) = %d\n",
			(params_buffer_bytes(params)));
	pr_debug("params_periods(params) = %d\n",
			(params_periods(params)));
	pr_debug("params_periodsize(params) = %d\n",
		(params_buffer_bytes(params) / params_periods(params)));

	if (rc < 0) {
		pr_err("Audio Start: Buffer Allocation failed rc = %d\n", rc);
		mutex_unlock(&prtd->lock);
		return -ENOMEM;
	}
	buf = prtd->audio_client->port[dir].buf;

	if (buf == NULL || buf[0].data == NULL) {
		mutex_unlock(&prtd->lock);
		return -ENOMEM;
	}

	pr_debug("%s:buf = %p\n", __func__, buf);
	dma_buf->dev.type = SNDRV_DMA_TYPE_DEV;
	dma_buf->dev.dev = substream->pcm->card->dev;
	dma_buf->private_data = NULL;
	dma_buf->area = buf[0].data;
	dma_buf->addr = buf[0].phys;

	dma_buf->bytes = params_buffer_bytes(params);

	if (!dma_buf->area) {
		pr_err("%s:MSM AFE physical memory allocation failed\n",
							__func__);
		mutex_unlock(&prtd->lock);
		return -ENOMEM;
	}

	memset(dma_buf->area, 0,  params_buffer_bytes(params));

	prtd->dma_addr = (u32) dma_buf->addr;

	mutex_unlock(&prtd->lock);

	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);

	rc = afe_memory_map(dma_buf->addr, dma_buf->bytes, prtd->audio_client);
	if (rc < 0)
		pr_err("fail to map memory to DSP\n");

	return rc;
}
Example #28
0
static int dma_hw_params(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *params)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct runtime_data *prtd = runtime->private_data;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	unsigned long totbytes = params_buffer_bytes(params);
	struct s3c_dma_params *dma =
		snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
	int ret = 0;


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

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

	/* this may get called several times by oss emulation
	 * with different params -HW */
	if (prtd->params == NULL) {
		/* prepare DMA */
		prtd->params = dma;

		pr_debug("params %p, client %p, channel %d\n", prtd->params,
			prtd->params->client, prtd->params->channel);

		ret = s3c2410_dma_request(prtd->params->channel,
					  prtd->params->client, NULL);

		if (ret < 0) {
			printk(KERN_ERR "failed to get dma channel\n");
			return ret;
		}

		/* use the circular buffering if we have it available. */
		if (s3c_dma_has_circular())
			s3c2410_dma_setflags(prtd->params->channel,
					     S3C2410_DMAF_CIRCULAR);
	}

	s3c2410_dma_set_buffdone_fn(prtd->params->channel,
				    audio_buffdone);

	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);

	runtime->dma_bytes = totbytes;

	spin_lock_irq(&prtd->lock);
	prtd->dma_loaded = 0;
	prtd->dma_limit = runtime->hw.periods_min;
	prtd->dma_period = params_period_bytes(params);
	prtd->dma_start = runtime->dma_addr;
	prtd->dma_pos = prtd->dma_start;
	prtd->dma_end = prtd->dma_start + totbytes;

	pr_debug("G:%s:DmaAddr=@%x Total=%d PrdSz=%d #Prds=%d dma_area=0x%x\n",
		(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? "P" : "C",
		prtd->dma_start, runtime->dma_bytes,
		params_period_bytes(params), params_periods(params),
		(unsigned int)runtime->dma_area);

	spin_unlock_irq(&prtd->lock);

	return 0;
}
static int s3c_dma_hw_params(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *params)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct s3c24xx_runtime_data *prtd = runtime->private_data;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct s3c_dma_params *dma = rtd->dai->cpu_dai->dma_data;
	unsigned long totbytes = params_buffer_bytes(params);
	unsigned int  periods  = params_periods(params);
	int ret = 0;

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

	if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		totbytes *= CONFIG_ANDROID_BUF_NUM;
	}

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

	/* this may get called several times by oss emulation
	 * with different params -HW */
	if (prtd->params == NULL) {
		/* prepare DMA */
		prtd->params = dma;

		pr_debug("params %p, client %p, channel %d\n", prtd->params,
				prtd->params->client, prtd->params->channel);

		ret = s3c2410_dma_request(prtd->params->channel,
				prtd->params->client, NULL);

		if (ret < 0) {
			printk(KERN_ERR "failed to get dma channel\n");
			return ret;
		}

		/* use the circular buffering if we have it available. */
		/*		if (s3c_dma_has_circular())
				s3c2410_dma_setflags(prtd->params->channel,
				S3C2410_DMAF_CIRCULAR);*/ //sayanta commented..need to check fucntionality
	} 

	s3c2410_dma_set_buffdone_fn(prtd->params->channel,
			s3c24xx_audio_buffdone);

	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);

	runtime->dma_bytes = totbytes;

	spin_lock_irq(&prtd->lock);
	prtd->dma_loaded = 0;
	prtd->dma_limit = runtime->hw.periods_min;
	prtd->dma_period = params_period_bytes(params);
	prtd->dma_start = runtime->dma_addr;
	prtd->dma_pos = prtd->dma_start;
	prtd->dma_end = prtd->dma_start + totbytes;
	spin_unlock_irq(&prtd->lock);
	printk("%s: DmaAddr=@%x Total=%lubytes PrdSz=%u #Prds=%u, dmaEnd 0x%x\n",
			__func__, runtime->dma_addr, totbytes, params_period_bytes(params), periods, prtd->dma_end);

	//	pr_debug("Finishing %s ..dma_period=%u..dma_bytes=%lu..dma_limit=%d..\n",__func__,prtd->dma_period,totbytes,prtd->dma_limit);
	return 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;
}