Exemplo n.º 1
0
static int sst_byt_pcm_open(struct snd_pcm_substream *substream)
{
    struct snd_soc_pcm_runtime *rtd = substream->private_data;
    struct sst_byt_priv_data *pdata =
        snd_soc_platform_get_drvdata(rtd->platform);
    struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];
    struct sst_byt *byt = pdata->byt;

    dev_dbg(rtd->dev, "PCM: open\n");

    mutex_lock(&pcm_data->mutex);

    pcm_data->substream = substream;

    snd_soc_set_runtime_hwparams(substream, &sst_byt_pcm_hardware);

    pcm_data->stream = sst_byt_stream_new(byt, substream->stream + 1,
                                          byt_notify_pointer, pcm_data);
    if (pcm_data->stream == NULL) {
        dev_err(rtd->dev, "failed to create stream\n");
        mutex_unlock(&pcm_data->mutex);
        return -EINVAL;
    }

    mutex_unlock(&pcm_data->mutex);
    return 0;
}
static int hi3630_srcup_normal_new(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_card *card = rtd->card->snd_card;
	struct snd_pcm  *pcm  = rtd->pcm;
	struct hi3630_srcup_data *pdata =
		(struct hi3630_srcup_data *)snd_soc_platform_get_drvdata(rtd->platform);
	int ret = 0;

	BUG_ON(NULL == card);
	BUG_ON(NULL == pcm);
	BUG_ON(NULL == pdata);

	if (!card->dev->dma_mask)
		card->dev->dma_mask = &hi3630_pcm_dmamask;
	if (!card->dev->coherent_dma_mask)
		card->dev->coherent_dma_mask = DMA_BIT_MASK(32);

	if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
		ret = hi3630_pcm_preallocate_dma_buffer(pcm,
			SNDRV_PCM_STREAM_PLAYBACK);
		if (ret) {
			loge("preallocate dma buffer error, error No. = %d\n", ret);
			return ret;
		}
	}

	return ret;
}
Exemplo n.º 3
0
static snd_pcm_uframes_t lpass_platform_pcmops_pointer(
		struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
	struct lpass_data *drvdata =
			snd_soc_platform_get_drvdata(soc_runtime->platform);
	unsigned int base_addr, curr_addr;
	int ret;

	ret = regmap_read(drvdata->lpaif_map,
			LPAIF_RDMABASE_REG(LPAIF_RDMA_CHAN_MI2S), &base_addr);
	if (ret) {
		dev_err(soc_runtime->dev, "%s() error reading from rdmabase reg: %d\n",
				__func__, ret);
		return ret;
	}

	ret = regmap_read(drvdata->lpaif_map,
			LPAIF_RDMACURR_REG(LPAIF_RDMA_CHAN_MI2S), &curr_addr);
	if (ret) {
		dev_err(soc_runtime->dev, "%s() error reading from rdmacurr reg: %d\n",
				__func__, ret);
		return ret;
	}

	return bytes_to_frames(substream->runtime, curr_addr - base_addr);
}
Exemplo n.º 4
0
static int hsw_pcm_open(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct hsw_priv_data *pdata =
		snd_soc_platform_get_drvdata(rtd->platform);
	struct hsw_pcm_data *pcm_data;
	struct sst_hsw *hsw = pdata->hsw;

	pcm_data = &pdata->pcm[rtd->cpu_dai->id];

	mutex_lock(&pcm_data->mutex);

	snd_soc_pcm_set_drvdata(rtd, pcm_data);
	pcm_data->substream = substream;

	snd_soc_set_runtime_hwparams(substream, &hsw_pcm_hardware);

	pcm_data->stream = sst_hsw_stream_new(hsw, rtd->cpu_dai->id,
		hsw_notify_pointer, pcm_data);
	if (pcm_data->stream == NULL) {
		dev_err(rtd->dev, "error: failed to create stream\n");
		mutex_unlock(&pcm_data->mutex);
		return -EINVAL;
	}

	/* Set previous saved volume */
	sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0,
			0, pcm_data->volume[0]);
	sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0,
			1, pcm_data->volume[1]);

	mutex_unlock(&pcm_data->mutex);
	return 0;
}
Exemplo n.º 5
0
static int hsw_pcm_close(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct hsw_priv_data *pdata =
		snd_soc_platform_get_drvdata(rtd->platform);
	struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
	struct sst_hsw *hsw = pdata->hsw;
	int ret;

	mutex_lock(&pcm_data->mutex);
	ret = sst_hsw_stream_reset(hsw, pcm_data->stream);
	if (ret < 0) {
		dev_dbg(rtd->dev, "error: reset stream failed %d\n", ret);
		goto out;
	}

	ret = sst_hsw_stream_free(hsw, pcm_data->stream);
	if (ret < 0) {
		dev_dbg(rtd->dev, "error: free stream failed %d\n", ret);
		goto out;
	}
	pcm_data->stream = NULL;

out:
	mutex_unlock(&pcm_data->mutex);
	return ret;
}
Exemplo n.º 6
0
static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol);
	struct soc_mixer_control *mc =
		(struct soc_mixer_control *)kcontrol->private_value;
	struct hsw_priv_data *pdata =
		snd_soc_platform_get_drvdata(platform);
	struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg];
	struct sst_hsw *hsw = pdata->hsw;
	u32 volume;

	mutex_lock(&pcm_data->mutex);

	if (!pcm_data->stream) {
		ucontrol->value.integer.value[0] =
			hsw_ipc_to_mixer(pcm_data->volume[0]);
		ucontrol->value.integer.value[1] =
			hsw_ipc_to_mixer(pcm_data->volume[1]);
		mutex_unlock(&pcm_data->mutex);
		return 0;
	}

	sst_hsw_stream_get_volume(hsw, pcm_data->stream, 0, 0, &volume);
	ucontrol->value.integer.value[0] = hsw_ipc_to_mixer(volume);
	sst_hsw_stream_get_volume(hsw, pcm_data->stream, 0, 1, &volume);
	ucontrol->value.integer.value[1] = hsw_ipc_to_mixer(volume);
	mutex_unlock(&pcm_data->mutex);

	return 0;
}
Exemplo n.º 7
0
static int hsw_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct hsw_priv_data *pdata =
		snd_soc_platform_get_drvdata(rtd->platform);
	struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
	struct sst_hsw *hsw = pdata->hsw;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		sst_hsw_stream_resume(hsw, pcm_data->stream, 0);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		sst_hsw_stream_pause(hsw, pcm_data->stream, 0);
		break;
	default:
		break;
	}

	return 0;
}
Exemplo n.º 8
0
static int sst_soc_probe(struct snd_soc_platform *platform)
{
	struct sst_data *ctx = snd_soc_platform_get_drvdata(platform);
	struct soft_platform_id spid;
	int ret = 0;

	memcpy(&spid, ctx->pdata->spid, sizeof(spid));
	pr_debug("Enter:%s\n", __func__);
	if (INTEL_MID_BOARD(1, PHONE, CLVTP) ||
	    INTEL_MID_BOARD(1, TABLET, CLVT) ||
	    INTEL_MID_BOARD(1, TABLET, BYT))
		return sst_platform_clv_init(platform);
	if (INTEL_MID_BOARD(1, PHONE, MRFL) ||
			INTEL_MID_BOARD(1, TABLET, MRFL) ||
			INTEL_MID_BOARD(1, PHONE, MOFD) ||
			INTEL_MID_BOARD(1, TABLET, MOFD)) {
#if IS_BUILTIN(CONFIG_SST_MRFLD_DPCM)
		ret = sst_dsp_init_v2_dpcm(platform);
#else
		ret = sst_dsp_init(platform);
#endif
		if (ret)
			return ret;
		ret = snd_soc_register_effect(platform->card, &effects_ops);
	}
	if (INTEL_MID_BOARD(1, TABLET, CHT)) {
		ret = sst_dsp_init(platform);
		if (ret)
			pr_err("Dsp init failed: %d\n", ret);
	}
	return ret;
}
Exemplo n.º 9
0
static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct sst_byt_priv_data *pdata =
		snd_soc_platform_get_drvdata(rtd->platform);
	struct sst_byt_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
	struct sst_byt *byt = pdata->byt;

	dev_dbg(rtd->dev, "PCM: trigger %d\n", cmd);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		sst_byt_stream_start(byt, pcm_data->stream);
		break;
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		sst_byt_stream_resume(byt, pcm_data->stream);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		sst_byt_stream_stop(byt, pcm_data->stream);
		break;
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		sst_byt_stream_pause(byt, pcm_data->stream);
		break;
	default:
		break;
	}

	return 0;
}
Exemplo n.º 10
0
static int lpe_mixer_headset_set(struct snd_kcontrol *kcontrol,
                                 struct snd_ctl_elem_value *ucontrol)
{
    int mixer_input_stream;
    struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol);
    struct sst_data *sst = snd_soc_platform_get_drvdata(platform);

    switch (ucontrol->value.integer.value[0]) {
    case 0:
        pr_debug("input is None\n");
        mixer_input_stream = SST_STREAM_DEVICE_HS
                             | SST_INPUT_STREAM_NONE;
        break;
    case 1:
        pr_debug("input is PCM stream\n");
        mixer_input_stream = SST_STREAM_DEVICE_HS
                             | SST_INPUT_STREAM_PCM;
        break;
    case 2:
        pr_debug("input is Compress  stream\n");
        mixer_input_stream = SST_STREAM_DEVICE_HS
                             | SST_INPUT_STREAM_COMPRESS;
        break;
    case 3:
        pr_debug("input is Mixed stream\n");
        mixer_input_stream = SST_STREAM_DEVICE_HS
                             | SST_INPUT_STREAM_MIXED;
        break;
    default:
        pr_err("Invalid Input:%ld\n", ucontrol->value.integer.value[0]);
        return -EINVAL;
    }
    sst->lpe_mixer_input_hs  = ucontrol->value.integer.value[0];
    return sst_set_mixer_param(mixer_input_stream);
}
Exemplo n.º 11
0
static int ath79_pcm_close(struct snd_pcm_substream *ss)
{
	struct snd_soc_pcm_runtime *runtime = ss->private_data;
	struct snd_soc_platform *platform = runtime->platform;
	struct ath79_pcm_pltfm_priv *prdata = snd_soc_platform_get_drvdata(platform);
	struct ath79_pcm_rt_priv *rtpriv;

	if (!prdata)
		return 0;

	if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		prdata->playback = NULL;
	} else {
		prdata->capture = NULL;
	}

	if (!prdata->playback && !prdata->capture) {
		free_irq(ATH79_MISC_IRQ(7), prdata);
		kfree(prdata);
		snd_soc_platform_set_drvdata(platform, NULL);
	}
	rtpriv = ss->runtime->private_data;
	kfree(rtpriv);

	return 0;
}
/* TODO: we have to use the shift value atm to represent register
 * id due to current HAL ID MACROS not being unique.
 */
static int put_mixer(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
	struct snd_soc_platform *platform = widget->platform;
	struct omap_abe *abe = snd_soc_platform_get_drvdata(platform);
	struct soc_mixer_control *mc =
		(struct soc_mixer_control *)kcontrol->private_value;

	abe_dsp_pm_get(abe);

	if (ucontrol->value.integer.value[0]) {
		abe->opp.widget[mc->reg] |= ucontrol->value.integer.value[0]<<mc->shift;
		snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
		omap_aess_enable_gain(abe->aess, mc->reg);
	} else {
		abe->opp.widget[mc->reg] &= ~(0x1<<mc->shift);
		snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
		omap_aess_disable_gain(abe->aess, mc->reg);
	}

	pm_runtime_put_sync(abe->dev);
	return 1;
}
Exemplo n.º 13
0
static snd_pcm_uframes_t mtk_afe_pcm_pointer
			 (struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
	struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
	const struct mtk_base_memif_data *memif_data = memif->data;
	struct regmap *regmap = afe->regmap;
	struct device *dev = afe->dev;
	int reg_ofs_base = memif_data->reg_ofs_base;
	int reg_ofs_cur = memif_data->reg_ofs_cur;
	unsigned int hw_ptr = 0, hw_base = 0;
	int ret, pcm_ptr_bytes;

	ret = regmap_read(regmap, reg_ofs_cur, &hw_ptr);
	if (ret || hw_ptr == 0) {
		dev_err(dev, "%s hw_ptr err\n", __func__);
		pcm_ptr_bytes = 0;
		goto POINTER_RETURN_FRAMES;
	}

	ret = regmap_read(regmap, reg_ofs_base, &hw_base);
	if (ret || hw_base == 0) {
		dev_err(dev, "%s hw_ptr err\n", __func__);
		pcm_ptr_bytes = 0;
		goto POINTER_RETURN_FRAMES;
	}

	pcm_ptr_bytes = hw_ptr - hw_base;

POINTER_RETURN_FRAMES:
	return bytes_to_frames(substream->runtime, pcm_ptr_bytes);
}
static int ul_mux_get_route(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
	struct snd_soc_platform *platform = widget->platform;
	struct omap_abe *abe = snd_soc_platform_get_drvdata(platform);
	struct soc_enum *e =
		(struct soc_enum *)kcontrol->private_value;
	int reg = e->reg - OMAP_ABE_MUX(0), i, rval = 0;

	/* TODO: remove the gap */
	if (reg < 8) {
		/* 0  .. 9   = MM_UL */
		rval = abe->mixer.route_ul[reg];
	} else if (reg < 12) {
		/* 10 .. 11  = MM_UL2 */
		/* 12 .. 13  = VX_UL */
		rval = abe->mixer.route_ul[reg + 2];
	}

	for (i = 0; i < ARRAY_SIZE(router); i++) {
		if (router[i] == rval) {
			ucontrol->value.integer.value[0] = i;
			return 0;
		}
	}

	return 1;
}
Exemplo n.º 15
0
/* set optimum DL1 output path gain for ABE -> McPDM -> twl6040 */
static int omap_abe_set_pdm_dl1_gains(struct snd_soc_dapm_context *dapm)
{
	int gain_dB = 0, gain;
	struct snd_soc_card *card = dapm->card;
	struct omap_abe_data *abe_data = snd_soc_card_get_drvdata(card);
	struct snd_soc_codec *codec = abe_data->twl6040_codec;
	struct snd_soc_platform *platform = abe_data->abe_platform;
	struct omap_abe *abe = snd_soc_platform_get_drvdata(platform);

	if (codec) {
#if !defined(CONFIG_SND_OMAP_SOC_ABE_DL2)
		gain_dB = twl6040_get_dl2_gain(codec);
#endif
		if (!gain_dB)
			gain_dB = twl6040_get_dl1_gain(codec);
	}

	switch (gain_dB) {
	case -8:
		gain = GAIN_M8dB;
		break;
	case -7:
		gain = GAIN_M7dB;
		break;
	case -1:
		gain = GAIN_M1dB;
		break;
	default:
		gain = GAIN_0dB;
		break;
	}
	omap_aess_write_gain(abe->aess, OMAP_AESS_GAIN_DL1_LEFT, gain);
	omap_aess_write_gain(abe->aess, OMAP_AESS_GAIN_DL1_RIGHT, gain);
	return 0;
}
static int mt_pcm_mrgrx_close(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct mt_pcm_mrgrx_priv *priv = snd_soc_platform_get_drvdata(rtd->platform);

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

	mtk_wcn_cmb_stub_audio_ctrl((CMB_STUB_AIF_X) CMB_STUB_AIF_0);

	mt_afe_disable_memory_path(MT_AFE_DIGITAL_BLOCK_MRG_I2S_OUT);
	if (mt_afe_get_memory_path_state(MT_AFE_DIGITAL_BLOCK_MRG_I2S_OUT) == false)
		mt_afe_disable_merge_i2s();

	mt_afe_disable_memory_path(MT_AFE_DIGITAL_BLOCK_I2S_OUT_DAC);
	if (mt_afe_get_memory_path_state(MT_AFE_DIGITAL_BLOCK_I2S_OUT_DAC) == false)
		mt_afe_disable_i2s_dac();

	mt_afe_set_connection(INTER_DISCONNECT, INTER_CONN_I15, INTER_CONN_O13);
	mt_afe_set_connection(INTER_DISCONNECT, INTER_CONN_I16, INTER_CONN_O14);

	mt_afe_set_connection(INTER_DISCONNECT, INTER_CONN_I10, INTER_CONN_O03);
	mt_afe_set_connection(INTER_DISCONNECT, INTER_CONN_I11, INTER_CONN_O04);

	mt_afe_enable_afe(false);

	mt_afe_dac_clk_off();
	mt_afe_main_clk_off();
	priv->prepare_done = false;
	return 0;
}
static int msm_compr_volume_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol);
	unsigned long fe_id = kcontrol->private_value;
	struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
			snd_soc_platform_get_drvdata(platform);
	struct snd_compr_stream *cstream = NULL;
	uint32_t *volume = NULL;

	if (fe_id >= MSM_FRONTEND_DAI_MAX) {
		pr_err("%s Received out of bounds fe_id %lu\n",
			__func__, fe_id);
		return -EINVAL;
	}

	cstream = pdata->cstream[fe_id];
	volume = pdata->volume[fe_id];

	volume[0] = ucontrol->value.integer.value[0];
	volume[1] = ucontrol->value.integer.value[1];
	pr_debug("%s: fe_id %lu left_vol %d right_vol %d\n",
		 __func__, fe_id, volume[0], volume[1]);
	if (cstream)
		msm_compr_set_volume(cstream, volume[0], volume[1]);
	return 0;
}
Exemplo n.º 18
0
static int aess_close(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_platform *platform = rtd->platform;
	struct omap_abe *abe = snd_soc_platform_get_drvdata(platform);
	struct snd_soc_dai *dai = rtd->cpu_dai;

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

	mutex_lock(&abe->mutex);

	if (!--abe->active) {
		omap_aess_disable_irq(abe->aess);
		abe_pm_save_context(abe);
		omap_abe_pm_shutdown(platform);
	} else {
		/* Only scale OPP level
		 * if ABE is still active */
		abe_opp_recalc_level(abe);
	}
	omap_abe_pm_runtime_put_sync(abe);

	mutex_unlock(&abe->mutex);
	return 0;
}
Exemplo n.º 19
0
/*
 * cpe_get_private_data: obtain ASoC platform driver private data
 * @substream: ASoC substream for which private data to be obtained
 */
static struct cpe_priv *cpe_get_private_data(
	struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_platform *platform = rtd->platform;

	return snd_soc_platform_get_drvdata(platform);
}
Exemplo n.º 20
0
static int lpe_mixer_headset_get(struct snd_kcontrol *kcontrol,
                                 struct snd_ctl_elem_value *ucontrol)
{
    struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol);
    struct sst_data *sst = snd_soc_platform_get_drvdata(platform);

    ucontrol->value.integer.value[0] = sst->lpe_mixer_input_hs;
    return 0;
}
Exemplo n.º 21
0
int sst_platform_clv_init(struct snd_soc_platform *platform)
{
    struct sst_data *ctx = snd_soc_platform_get_drvdata(platform);
    ctx->lpe_mixer_input_hs = 0;
    ctx->lpe_mixer_input_ihf = 0;
    snd_soc_add_platform_controls(platform, sst_controls_clv,
                                  ARRAY_SIZE(sst_controls_clv));
    return 0;
}
static int abe_get_equalizer(struct snd_kcontrol *kcontrol,
			struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol);
	struct omap_abe *abe = snd_soc_platform_get_drvdata(platform);
	struct soc_enum *eqc = (struct soc_enum *)kcontrol->private_value;

	ucontrol->value.integer.value[0] = abe->equ.profile[eqc->reg];
	return 0;
}
int abe_mixer_write(struct snd_soc_platform *platform, unsigned int reg,
		unsigned int val)
{
	struct omap_abe *abe = snd_soc_platform_get_drvdata(platform);

	BUG_ON(reg > OMAP_ABE_NUM_DAPM_REG);
	abe->opp.widget[reg] = val;
	dev_dbg(platform->dev, "write R%d (Ox%x) = 0x%x\n", reg, reg, val);
	return 0;
}
/* TODO: map IO directly into ABE memories */
unsigned int abe_mixer_read(struct snd_soc_platform *platform,
		unsigned int reg)
{
	struct omap_abe *abe = snd_soc_platform_get_drvdata(platform);

	BUG_ON(reg > OMAP_ABE_NUM_DAPM_REG);
	dev_dbg(platform->dev, "read R%d (Ox%x) = 0x%x\n",
			reg, reg, abe->opp.widget[reg]);
	return abe->opp.widget[reg];
}
Exemplo n.º 25
0
static int aess_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 snd_soc_platform *platform = rtd->platform;
	struct omap_abe *abe = snd_soc_platform_get_drvdata(platform);
	struct snd_soc_dai *dai = rtd->cpu_dai;
	struct omap_aess_data_format format;
	size_t period_size;
	u32 dst, param[2];
	int ret = 0;

	mutex_lock(&abe->mutex);

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

	if (dai->id != OMAP_ABE_FRONTEND_DAI_LP_MEDIA)
		goto out;

	format.f = params_rate(params);
	if (params_format(params) == SNDRV_PCM_FORMAT_S32_LE)
		format.samp_format = STEREO_MSB;
	else
		format.samp_format = STEREO_16_16;

	period_size = params_period_bytes(params);

	param[0] = (u32)substream;
	param[1] = (u32)abe;

	/* Adding ping pong buffer subroutine */
	omap_aess_plug_subroutine(abe->aess, &abe->aess->seq.irq_pingpong_player_id,
				(abe_subroutine2) abe_irq_pingpong_subroutine,
				2, param);

	/* Connect a Ping-Pong cache-flush protocol to MM_DL port */
	omap_aess_connect_irq_ping_pong_port(abe->aess, OMAP_ABE_MM_DL_PORT, &format,
				abe->aess->seq.irq_pingpong_player_id,
				period_size, &dst,
				PING_PONG_WITH_MCU_IRQ);

	/* Memory mapping for hw params */
	runtime->dma_area  = abe->io_base[0] + dst;
	runtime->dma_addr  = 0;
	runtime->dma_bytes = period_size * 4;

	/* Need to set the first buffer in order to get interrupt */
	omap_aess_set_ping_pong_buffer(abe->aess, OMAP_ABE_MM_DL_PORT, period_size);
	abe->mmap.first_irq = 1;

out:
	mutex_unlock(&abe->mutex);
	return ret;
}
Exemplo n.º 26
0
static int mtk_afe_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
	size_t size;
	struct snd_card *card = rtd->card->snd_card;
	struct snd_pcm *pcm = rtd->pcm;
	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);

	size = afe->mtk_afe_hardware->buffer_bytes_max;
	return snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
						     card->dev, size, size);
}
static int abe_get_mono_mixer(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol);
	struct omap_abe *abe = snd_soc_platform_get_drvdata(platform);
	struct soc_mixer_control *mc =
		(struct soc_mixer_control *)kcontrol->private_value;
	int id = mc->shift - MIX_DL1_MONO;

	ucontrol->value.integer.value[0] = abe->mixer.mono[id];
	return 0;
}
Exemplo n.º 28
0
static int aess_open(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_platform *platform = rtd->platform;
	struct omap_abe *abe = snd_soc_platform_get_drvdata(platform);
	struct snd_soc_dai *dai = rtd->cpu_dai;
	int ret = 0;

	mutex_lock(&abe->mutex);

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

	switch (dai->id) {
	case OMAP_ABE_FRONTEND_DAI_MODEM:
		break;
	case OMAP_ABE_FRONTEND_DAI_LP_MEDIA:
		snd_soc_set_runtime_hwparams(substream, &omap_abe_hardware);
		ret = snd_pcm_hw_constraint_step(substream->runtime, 0,
					 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1024);
		break;
	default:
		/*
		 * Period size must be aligned with the Audio Engine
		 * processing loop which is 250 us long
		 */
		ret = snd_pcm_hw_rule_add(substream->runtime, 0,
					SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
					omap_abe_hwrule_period_step,
					NULL,
					SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -1);
		break;
	}

	if (ret < 0) {
		dev_err(abe->dev, "failed to set period constraints for DAI %d\n",
			dai->id);
		goto out;
	}

	omap_abe_pm_runtime_get_sync(abe);

	if (!abe->active++) {
		abe->opp.level = 0;
		ret = abe_pm_restore_context(abe);
		if (ret)
			goto out;
		omap_aess_wakeup(abe->aess);
	}

out:
	mutex_unlock(&abe->mutex);
	return ret;
}
Exemplo n.º 29
0
static snd_pcm_uframes_t sst_byt_pcm_pointer(struct snd_pcm_substream *substream)
{
    struct snd_soc_pcm_runtime *rtd = substream->private_data;
    struct snd_pcm_runtime *runtime = substream->runtime;
    struct sst_byt_priv_data *pdata =
        snd_soc_platform_get_drvdata(rtd->platform);
    struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];

    dev_dbg(rtd->dev, "PCM: DMA pointer %u bytes\n", pcm_data->hw_ptr);

    return bytes_to_frames(runtime, pcm_data->hw_ptr);
}
void omap_abe_dc_set_hf_offset(struct snd_soc_platform *platform,
	int left, int right)
{
	struct omap_abe *abe = snd_soc_platform_get_drvdata(platform);

	if (left >= 8)
		left -= 16;
	abe->dc_offset.hfl = OMAP_ABE_HF_DC_OFFSET_STEP * left;

	if (right >= 8)
		right -= 16;
	abe->dc_offset.hfr = OMAP_ABE_HF_DC_OFFSET_STEP * right;
}