Beispiel #1
0
static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *params,
                                 struct snd_soc_dai *cpu_dai)
{
    struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai);
    struct s3c_dma_params *dma_data;
    u32 iismod;

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

    if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
        dma_data = i2s->dma_playback;
    else
        dma_data = i2s->dma_capture;

    snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);

    iismod = readl(i2s->regs + S3C2412_IISMOD);
    pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);

    switch (params_format(params)) {
    case SNDRV_PCM_FORMAT_S8:
        iismod |= S3C2412_IISMOD_8BIT;
        break;
    case SNDRV_PCM_FORMAT_S16_LE:
        iismod &= ~S3C2412_IISMOD_8BIT;
        break;
    }

    writel(iismod, i2s->regs + S3C2412_IISMOD);
    pr_debug("%s: w: IISMOD: %x\n", __func__, iismod);

    return 0;
}
Beispiel #2
0
static int pxa3xx_ssp_startup(struct snd_pcm_substream *substream,
	struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
	struct ssp_device *ssp;
	int ret = 0;
	u32 sscr0;

	if (!cpu_dai->active) {
		ret = ssp_init(&ssp_dev[cpu_dai->id], cpu_dai->id + 1,
				SSP_NO_IRQ);
		if(ret)
			return ret;
		ssp = ssp_dev[cpu_dai->id].ssp; 
		sscr0 = __raw_readl(ssp->mmio_base + SSCR0);
		sscr0 &= ~SSCR0_SSE;
		__raw_writel(sscr0, ssp->mmio_base + SSCR0);

		cpu_dai->private_data = ssp;
	}

	kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
	snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);

	return ret;
}
Beispiel #3
0
static int au1xpsc_i2s_startup(struct snd_pcm_substream *substream,
			       struct snd_soc_dai *dai)
{
	struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
	snd_soc_dai_set_dma_data(dai, substream, &pscdata->dmaids[0]);
	return 0;
}
static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream,
				    struct snd_pcm_hw_params *params,
				    struct snd_soc_dai *dai)
{
	int err = 0;

	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		omap_hdmi_dai_dma_params.packet_size = 16;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		omap_hdmi_dai_dma_params.packet_size = 32;
		break;
	default:
		err = -EINVAL;
	}

	omap_hdmi_dai_dma_params.data_type = OMAP_DMA_DATA_TYPE_S32;

	snd_soc_dai_set_dma_data(dai, substream,
				 &omap_hdmi_dai_dma_params);

	err = hdmi_lib_start_acr_wa();
	if (err)
		pr_warning("Failed to start ACR workaround[%d]]\n", err);

	return err;
}
Beispiel #5
0
static int hdmi_dai_startup(struct snd_pcm_substream *substream,
			    struct snd_soc_dai *dai)
{
	struct hdmi_audio_data *ad = card_drvdata_substream(substream);
	int ret;
	/*
	 * Make sure that the period bytes are multiple of the DMA packet size.
	 * Largest packet size we use is 32 32-bit words = 128 bytes
	 */
	ret = snd_pcm_hw_constraint_step(substream->runtime, 0,
					 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 128);
	if (ret < 0) {
		dev_err(dai->dev, "could not apply constraint\n");
		return ret;
	}

	snd_soc_dai_set_dma_data(dai, substream, &ad->dma_data);

	mutex_lock(&ad->current_stream_lock);
	ad->current_stream = substream;
	mutex_unlock(&ad->current_stream_lock);

	ret = ad->ops->audio_startup(ad->dssdev, hdmi_dai_abort);

	if (ret) {
		mutex_lock(&ad->current_stream_lock);
		ad->current_stream = NULL;
		mutex_unlock(&ad->current_stream_lock);
	}

	return ret;
}
static int mxs_spdif_startup(struct snd_pcm_substream *substream,
				  struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
	int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0;
	int irq;
	int ret;

	if (playback) {
		irq = IRQ_SPDIF_ERROR;
		snd_soc_dai_set_dma_data(cpu_dai, substream, &mxs_spdif);
	}

	ret = request_irq(irq, mxs_err_irq, 0, "Mxs SPDIF Error",
			  substream);
	if (ret) {
		printk(KERN_ERR "%s: Unable to request SPDIF error irq %d\n",
		       __func__, IRQ_SPDIF_ERROR);
		return ret;
	}

	/* Enable error interrupt */
	if (playback) {
		__raw_writel(BM_SPDIF_CTRL_FIFO_OVERFLOW_IRQ,
				REGS_SPDIF_BASE + HW_SPDIF_CTRL_CLR);
		__raw_writel(BM_SPDIF_CTRL_FIFO_UNDERFLOW_IRQ,
				REGS_SPDIF_BASE + HW_SPDIF_CTRL_CLR);
		__raw_writel(BM_SPDIF_CTRL_FIFO_ERROR_IRQ_EN,
				REGS_SPDIF_BASE + HW_SPDIF_CTRL_SET);
	}

	return 0;
}
Beispiel #7
0
static int skl_link_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params,
				struct snd_soc_dai *dai)
{
	struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev);
	struct hdac_ext_stream *link_dev;
	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
	struct hdac_ext_dma_params *dma_params;
	struct snd_soc_dai *codec_dai = rtd->codec_dai;
	struct skl_pipe_params p_params = {0};

	link_dev = snd_hdac_ext_stream_assign(ebus, substream,
					HDAC_EXT_STREAM_TYPE_LINK);
	if (!link_dev)
		return -EBUSY;

	snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);

	/* set the stream tag in the codec dai dma params  */
	dma_params = snd_soc_dai_get_dma_data(codec_dai, substream);
	if (dma_params)
		dma_params->stream_tag =  hdac_stream(link_dev)->stream_tag;

	p_params.s_fmt = snd_pcm_format_width(params_format(params));
	p_params.ch = params_channels(params);
	p_params.s_freq = params_rate(params);
	p_params.stream = substream->stream;
	p_params.link_dma_id = hdac_stream(link_dev)->stream_tag - 1;

	return skl_tplg_be_update_params(dai, &p_params);
}
Beispiel #8
0
static void skl_pcm_close(struct snd_pcm_substream *substream,
		struct snd_soc_dai *dai)
{
	struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
	struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev);
	struct skl_dma_params *dma_params = NULL;
	struct skl *skl = ebus_to_skl(ebus);

	dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);

	snd_hdac_ext_stream_release(stream, skl_get_host_stream_type(ebus));

	dma_params = snd_soc_dai_get_dma_data(dai, substream);
	/*
	 * now we should set this to NULL as we are freeing by the
	 * dma_params
	 */
	snd_soc_dai_set_dma_data(dai, substream, NULL);
	skl_set_suspend_active(substream, dai, false);

	/*
	 * check if close is for "Reference Pin" and set back the
	 * CGCTL.MISCBDCGE if disabled by driver
	 */
	if (!strncmp(dai->name, "Reference Pin", 13) &&
			skl->skl_sst->miscbdcg_disabled) {
		skl->skl_sst->enable_miscbdcge(dai->dev, true);
		skl->skl_sst->miscbdcg_disabled = false;
	}

	kfree(dma_params);
}
Beispiel #9
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;
}
static int alchemy_ac97c_startup(struct snd_pcm_substream *substream,
				 struct snd_soc_dai *dai)
{
	struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
	snd_soc_dai_set_dma_data(dai, substream, &ctx->dmaids[0]);
	return 0;
}
Beispiel #11
0
static int sunxi_hdmiaudio_hw_params(struct snd_pcm_substream *substream,
                                     struct snd_pcm_hw_params *params,
                                     struct snd_soc_dai *dai)
{
    struct snd_soc_pcm_runtime *rtd 	= NULL;
    struct sunxi_dma_params *dma_data 	= NULL;
    u32 reg_val = 0;

    switch (params_format(params))
    {
    case SNDRV_PCM_FORMAT_S16_LE:
        sample_resolution = 16;
        break;
    case SNDRV_PCM_FORMAT_S20_3LE:
        sample_resolution = 24;
        break;
    case SNDRV_PCM_FORMAT_S24_LE:
        sample_resolution = 24;
        break;
    case SNDRV_PCM_FORMAT_S32_LE:
        sample_resolution = 24;
        break;
    default:
        return -EINVAL;
    }

    if (!substream) {
        printk("error:%s,line:%d\n", __func__, __LINE__);
        return -EAGAIN;
    }

    reg_val = readl(sunxi_i2s1.regs + SUNXI_I2S1FAT0);
    sunxi_i2s1.samp_res = sample_resolution;
    reg_val &= ~SUNXI_I2S1FAT0_SR_RVD;
    if(sunxi_i2s1.samp_res == 16)
        reg_val |= SUNXI_I2S1FAT0_SR_16BIT;
    else if(sunxi_i2s1.samp_res == 20)
        reg_val |= SUNXI_I2S1FAT0_SR_20BIT;
    else
        reg_val |= SUNXI_I2S1FAT0_SR_24BIT;
    writel(reg_val, sunxi_i2s1.regs + SUNXI_I2S1FAT0);

    rtd = substream->private_data;
    if (sample_resolution == 24) {
        reg_val = readl(sunxi_i2s1.regs + SUNXI_I2S1FCTL);
        reg_val &= ~(0x1<<2);
        writel(reg_val, sunxi_i2s1.regs + SUNXI_I2S1FCTL);
    }

    if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
        dma_data = &sunxi_hdmiaudio_pcm_stereo_out;
    } else {
        printk("error:hdmiaudio can't support capture:%s,line:%d\n", __func__, __LINE__);
    }

    snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data);

    return 0;
}
Beispiel #12
0
static int jz_spdif_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
	int channels = params_channels(params);
	int fmt_width = snd_pcm_format_width(params_format(params));
	struct jz_spdif *jz_spdif = dev_get_drvdata(dai->dev);
	struct device *aic = jz_spdif->aic;
	struct jz_aic *jz_aic = dev_get_drvdata(aic);
	enum dma_slave_buswidth buswidth;
	int trigger;
	unsigned long sample_rate = params_rate(params);

	spdif_DEBUG_MSG("enter %s, substream = %s\n", __func__,
			(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? "playback" : "capture");

	if (!((1 << params_format(params)) & JZ_SPDIF_FORMATS) || channels > 2) {
		dev_err(dai->dev, "hw params not inval channel %d params %x\n",
				channels, params_format(params));
		return -EINVAL;
	}

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		__i2s_channel(aic, channels);
		/* format */
		if (fmt_width == 16){
			buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
			__spdif_set_max_wl(aic,0);
			__spdif_set_sample_size(aic,1);
		}else if(fmt_width == 24){
			buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
			__spdif_set_max_wl(aic,1);
			__spdif_set_sample_size(aic,5);
		}else{
			return -EINVAL;
		}

		jz_spdif->tx_dma_data.buswidth = buswidth;
		jz_spdif->tx_dma_data.max_burst = (SPDIF_TFIFO_DEPTH * buswidth)/2;
		trigger = SPDIF_TFIFO_DEPTH - (jz_spdif->tx_dma_data.max_burst/(int)buswidth);
		__i2s_set_transmit_trigger(aic,trigger/2);
		snd_soc_dai_set_dma_data(dai, substream, (void *)&jz_spdif->tx_dma_data);

	} else {
		printk("spdif is not a capture device!\n");
		return -EINVAL;
	}

	/* sample rate */
	unsigned long tmp_rate = 0;
	tmp_rate = jz_spdif_set_rate(aic,jz_aic,sample_rate);
	if(tmp_rate < 0)
		printk("set spdif clk failed!!\n");
	/* signed transfer */
	if(snd_pcm_format_signed(params_format(params)))
		__spdif_clear_signn(aic);
	else
		__spdif_set_signn(aic);
	return 0;
}
static int davinci_i2s_startup(struct snd_pcm_substream *substream,
			       struct snd_soc_dai *dai)
{
	struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);

	snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
	return 0;
}
Beispiel #14
0
static int kirkwood_i2s_startup(struct snd_pcm_substream *substream,
                                struct snd_soc_dai *dai)
{
    struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);

    snd_soc_dai_set_dma_data(dai, substream, priv);
    return 0;
}
Beispiel #15
0
/*
 * Set the SSPA audio DMA parameters and sample size.
 * Can be called multiple times by oss emulation.
 */
static int mmp_sspa_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 sspa_priv *sspa_priv = snd_soc_dai_get_drvdata(dai);
	struct ssp_device *sspa = sspa_priv->sspa;
	struct snd_dmaengine_dai_dma_data *dma_params;
	u32 sspa_ctrl;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		sspa_ctrl = mmp_sspa_read_reg(sspa, SSPA_TXCTL);
	else
		sspa_ctrl = mmp_sspa_read_reg(sspa, SSPA_RXCTL);

	sspa_ctrl &= ~SSPA_CTL_XFRLEN1_MASK;
	sspa_ctrl |= SSPA_CTL_XFRLEN1(params_channels(params) - 1);
	sspa_ctrl &= ~SSPA_CTL_XWDLEN1_MASK;
	sspa_ctrl |= SSPA_CTL_XWDLEN1(SSPA_CTL_32_BITS);
	sspa_ctrl &= ~SSPA_CTL_XSSZ1_MASK;

	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S8:
		sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_8_BITS);
		break;
	case SNDRV_PCM_FORMAT_S16_LE:
		sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_16_BITS);
		break;
	case SNDRV_PCM_FORMAT_S20_3LE:
		sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_20_BITS);
		break;
	case SNDRV_PCM_FORMAT_S24_3LE:
		sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_24_BITS);
		break;
	case SNDRV_PCM_FORMAT_S32_LE:
		sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_32_BITS);
		break;
	default:
		return -EINVAL;
	}

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		mmp_sspa_write_reg(sspa, SSPA_TXCTL, sspa_ctrl);
		mmp_sspa_write_reg(sspa, SSPA_TXFIFO_LL, 0x1);
	} else {
		mmp_sspa_write_reg(sspa, SSPA_RXCTL, sspa_ctrl);
		mmp_sspa_write_reg(sspa, SSPA_RXFIFO_UL, 0x0);
	}

	dma_params = &sspa_priv->dma_params[substream->stream];
	dma_params->addr = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
				(sspa->phys_base + SSPA_TXD) :
				(sspa->phys_base + SSPA_RXD);
	snd_soc_dai_set_dma_data(cpu_dai, substream, dma_params);
	return 0;
}
Beispiel #16
0
/*
 * snd_soc_dai_ops
 */
static int  nxp_spdif_startup(struct snd_pcm_substream *substream,
				struct snd_soc_dai *dai)
{
	struct nxp_spdif_snd_param *par = snd_soc_dai_get_drvdata(dai);
	struct nxp_pcm_dma_param *dmap = &par->dma;

	snd_soc_dai_set_dma_data(dai, substream, dmap);
	return 0;
}
Beispiel #17
0
static int s3c_i2sv4_hw_params(struct snd_pcm_substream *substream,
				 struct snd_pcm_hw_params *params,
				 struct snd_soc_dai *cpu_dai)
{
	struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
	struct s3c_dma_params *dma_data;
	u32 iismod;
	u32 dma_tsfr_size = 0;

	dev_dbg(cpu_dai->dev, "Entered %s\n", __func__);

	/* TODO */
	switch (params_channels(params)) {
		case 1:
			dma_tsfr_size = 2;
			break;
		case 2:
			dma_tsfr_size = 4;
			break;
		case 4:
			break;
		case 6:
			break;
		default:
			break;
	}

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

	snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);

	iismod = readl(i2s->regs + S3C2412_IISMOD);
	dev_dbg(cpu_dai->dev, "%s: r: IISMOD: %x\n", __func__, iismod);

	iismod &= ~S3C64XX_IISMOD_BLC_MASK;
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S8:
		iismod |= S3C64XX_IISMOD_BLC_8BIT;
		break;
	case SNDRV_PCM_FORMAT_S16_LE:
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		iismod |= S3C64XX_IISMOD_BLC_24BIT;
		break;
	}

	writel(iismod, i2s->regs + S3C2412_IISMOD);
	dev_dbg(cpu_dai->dev, "%s: w: IISMOD: %x\n", __func__, iismod);

	return 0;
}
Beispiel #18
0
static int jz_pcm_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
	struct device *dev = dai->dev;
	struct jz_pcm *jz_pcm = dev_get_drvdata(dai->dev);
	int fmt_width = snd_pcm_format_width(params_format(params));
	enum dma_slave_buswidth buswidth;
	int trigger;

	PCM_DEBUG_MSG("enter %s, substream = %s\n",
			__func__,
			(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? "playback" : "capture");

	if (!((1 << params_format(params)) & JZ_PCM_FORMATS) ||
			params_channels(params) != 1 ||
			params_rate(params) != 8000) {
		dev_err(dai->dev, "hw params not inval channel %d params %x\n",
				params_channels(params), params_format(params));
		return -EINVAL;
	}

	/* format 8 bit or 16 bit*/
	if (fmt_width == 8)
		buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
	else
		buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		jz_pcm->tx_dma_data.buswidth = buswidth;
		jz_pcm->tx_dma_data.max_burst = (PCM_TFIFO_DEPTH * buswidth)/2;
		trigger = PCM_TFIFO_DEPTH - (jz_pcm->tx_dma_data.max_burst/(int)buswidth);
		__pcm_set_oss_sample_size(dev, fmt_width == 8 ? 0 : 1);
		__pcm_set_transmit_trigger(dev, trigger);
		snd_soc_dai_set_dma_data(dai, substream, (void *)&jz_pcm->tx_dma_data);
	} else {
		jz_pcm->rx_dma_data.buswidth = buswidth;
		jz_pcm->rx_dma_data.max_burst = (PCM_RFIFO_DEPTH * buswidth)/2;
		trigger = jz_pcm->rx_dma_data.max_burst/(int)buswidth;
		__pcm_set_iss_sample_size(dev, fmt_width == 8 ? 0 : 1);
		__pcm_set_receive_trigger(dev, trigger);
		snd_soc_dai_set_dma_data(dai, substream, (void *)&jz_pcm->rx_dma_data);
	}
	return 0;
}
Beispiel #19
0
int sunxi_daudio0_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 sunxi_dma_params *dma_data;

	u32 reg_val = 0;

	switch (params_format(params))
	{
		case SNDRV_PCM_FORMAT_S16_LE:
		sample_resolution = 16;
		break;
	case SNDRV_PCM_FORMAT_S20_3LE:
		sample_resolution = 24;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		sample_resolution = 24;
		break;
	case SNDRV_PCM_FORMAT_S32_LE:
		sample_resolution = 24;
		break;
	default:
		return -EINVAL;
	}
	reg_val = sunxi_smc_readl(sunxi_daudio.regs + SUNXI_DAUDIOFAT0);
	sunxi_daudio.samp_res = sample_resolution;
	reg_val &= ~SUNXI_DAUDIOFAT0_SR;
	if(sample_resolution == 16)
		reg_val |= (3<<4);
	else if(sample_resolution == 20)
		reg_val |= (4<<4);
	else
		reg_val |= (5<<4);
	sunxi_smc_writel(reg_val, sunxi_daudio.regs + SUNXI_DAUDIOFAT0);

	if (sample_resolution == 24) {
		reg_val = sunxi_smc_readl(sunxi_daudio.regs + SUNXI_DAUDIOFCTL);
		reg_val &= ~(0x1<<2);
		sunxi_smc_writel(reg_val, sunxi_daudio.regs + SUNXI_DAUDIOFCTL);
	} else {
		reg_val = sunxi_smc_readl(sunxi_daudio.regs + SUNXI_DAUDIOFCTL);
		reg_val |= SUNXI_DAUDIOFCTL_TXIM;
		sunxi_smc_writel(reg_val, sunxi_daudio.regs + SUNXI_DAUDIOFCTL);
	}

	/* play or record */
	if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		dma_data = &sunxi_daudio_pcm_stereo_out;
	else
		dma_data = &sunxi_daudio_pcm_stereo_in;

	snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data);
	return 0;
}
static int s3c2412_i2s_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);
	struct s3c_dma_params *dma_data;
	u32 iismod;

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

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		dma_data = i2s->dma_playback;
	else
		dma_data = i2s->dma_capture;

	snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data);

	/* Working copies of register */
	iismod = readl(i2s->regs + S3C2412_IISMOD);
	pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);

#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S8:
		iismod |= S3C2412_IISMOD_8BIT;
		break;
	case SNDRV_PCM_FORMAT_S16_LE:
		iismod &= ~S3C2412_IISMOD_8BIT;
		break;
	}
#endif

#ifdef CONFIG_PLAT_S3C64XX
	iismod &= ~(S3C64XX_IISMOD_BLC_MASK | S3C2412_IISMOD_BCLK_MASK);
	/* Sample size */
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S8:
		/* 8 bit sample, 16fs BCLK */
		iismod |= (S3C64XX_IISMOD_BLC_8BIT | S3C2412_IISMOD_BCLK_16FS);
		break;
	case SNDRV_PCM_FORMAT_S16_LE:
		/* 16 bit sample, 32fs BCLK */
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		/* 24 bit sample, 48fs BCLK */
		iismod |= (S3C64XX_IISMOD_BLC_24BIT | S3C2412_IISMOD_BCLK_48FS);
		break;
	}
#endif

	writel(iismod, i2s->regs + S3C2412_IISMOD);
	pr_debug("%s: w: IISMOD: %x\n", __func__, iismod);
	return 0;
}
Beispiel #21
0
static int pxa2xx_ac97_mic_startup(struct snd_pcm_substream *substream,
				   struct snd_soc_dai *cpu_dai)
{
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		return -ENODEV;
	snd_soc_dai_set_dma_data(cpu_dai, substream,
				 &pxa2xx_ac97_pcm_mic_mono_in);

	return 0;
}
static int spdif_in_startup(struct snd_pcm_substream *substream,
		struct snd_soc_dai *cpu_dai)
{
	struct spdif_in_dev *host = snd_soc_dai_get_drvdata(cpu_dai);

	if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
		return -EINVAL;

	snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)&host->dma_params);
	return 0;
}
static void spdif_in_shutdown(struct snd_pcm_substream *substream,
		struct snd_soc_dai *dai)
{
	struct spdif_in_dev *host = snd_soc_dai_get_drvdata(dai);

	if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
		return;

	writel(0x0, host->io_base + SPDIF_IN_IRQ_MASK);
	snd_soc_dai_set_dma_data(dai, substream, NULL);
}
static void spdif_out_shutdown(struct snd_pcm_substream *substream,
		struct snd_soc_dai *dai)
{
	struct spdif_out_dev *host = snd_soc_dai_get_drvdata(dai);

	if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
		return;

	clk_disable(host->clk);
	host->running = false;
	snd_soc_dai_set_dma_data(dai, substream, NULL);
}
Beispiel #25
0
static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai,
				struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params)
{
	struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
	int cr1, cr1_mask, ret;
	int fth = STM_SAI_FIFO_TH_HALF;

	/* FIFO config */
	regmap_update_bits(sai->regmap, STM_SAI_CR2_REGX,
			   SAI_XCR2_FFLUSH | SAI_XCR2_FTH_MASK,
			   SAI_XCR2_FFLUSH | SAI_XCR2_FTH_SET(fth));

	/* Mode, data format and channel config */
	cr1 = SAI_XCR1_PRTCFG_SET(SAI_FREE_PROTOCOL);
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S8:
		cr1 |= SAI_XCR1_DS_SET(SAI_DATASIZE_8);
		break;
	case SNDRV_PCM_FORMAT_S16_LE:
		cr1 |= SAI_XCR1_DS_SET(SAI_DATASIZE_16);
		break;
	case SNDRV_PCM_FORMAT_S32_LE:
		cr1 |= SAI_XCR1_DS_SET(SAI_DATASIZE_32);
		break;
	default:
		dev_err(cpu_dai->dev, "Data format not supported");
		return -EINVAL;
	}
	cr1_mask = SAI_XCR1_DS_MASK | SAI_XCR1_PRTCFG_MASK;

	cr1_mask |= SAI_XCR1_RX_TX;
	if (STM_SAI_IS_CAPTURE(sai))
		cr1 |= SAI_XCR1_RX_TX;

	cr1_mask |= SAI_XCR1_MONO;
	if ((sai->slots == 2) && (params_channels(params) == 1))
		cr1 |= SAI_XCR1_MONO;

	ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1);
	if (ret < 0) {
		dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
		return ret;
	}

	/* DMA config */
	sai->dma_params.maxburst = STM_SAI_FIFO_SIZE * fth / sizeof(u32);
	snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)&sai->dma_params);

	return 0;
}
Beispiel #26
0
static int pxa2xx_ac97_aux_startup(struct snd_pcm_substream *substream,
				   struct snd_soc_dai *cpu_dai)
{
	struct snd_dmaengine_dai_dma_data *dma_data;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		dma_data = &pxa2xx_ac97_pcm_aux_mono_out;
	else
		dma_data = &pxa2xx_ac97_pcm_aux_mono_in;

	snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);

	return 0;
}
Beispiel #27
0
static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
			     struct snd_soc_dai *cpu_dai)
{
	struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
	struct ssp_device *ssp = priv->ssp;

	if (!cpu_dai->active) {
		pxa_ssp_disable(ssp);
		clk_disable(ssp->clk);
	}

	kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
	snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
}
static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
	enum jz4740_dma_width dma_width;
	struct jz4740_pcm_config *pcm_config;
	unsigned int sample_size;
	uint32_t ctrl;

	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);

	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S8:
		sample_size = 0;
		dma_width = JZ4740_DMA_WIDTH_8BIT;
		break;
	case SNDRV_PCM_FORMAT_S16:
		sample_size = 1;
		dma_width = JZ4740_DMA_WIDTH_16BIT;
		break;
	default:
		return -EINVAL;
	}

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		ctrl &= ~JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK;
		ctrl |= sample_size << JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_OFFSET;
		if (params_channels(params) == 1)
			ctrl |= JZ_AIC_CTRL_MONO_TO_STEREO;
		else
			ctrl &= ~JZ_AIC_CTRL_MONO_TO_STEREO;

		pcm_config = &i2s->pcm_config_playback;
		pcm_config->dma_config.dst_width = dma_width;

	} else {
		ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK;
		ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;

		pcm_config = &i2s->pcm_config_capture;
		pcm_config->dma_config.src_width = dma_width;
	}

	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);

	snd_soc_dai_set_dma_data(dai, substream, pcm_config);

	return 0;
}
Beispiel #29
0
static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
				     struct snd_pcm_hw_params *params,
				     struct snd_soc_dai *cpu_dai)
{
	struct pxa2xx_pcm_dma_params *dma_data;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		dma_data = &pxa2xx_ac97_pcm_aux_mono_out;
	else
		dma_data = &pxa2xx_ac97_pcm_aux_mono_in;

	snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);

	return 0;
}
Beispiel #30
0
static int sun6i_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 sun6i_dma_params *dma_data;
	
	/* play or record */
	if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		dma_data = &sun6i_i2s_pcm_stereo_out;
	else
		dma_data = &sun6i_i2s_pcm_stereo_in;

	snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data);
	return 0;
}