示例#1
0
文件: wm9712.c 项目: Lyude/linux
static int wm9712_soc_probe(struct snd_soc_component *component)
{
	struct wm9712_priv *wm9712 = snd_soc_component_get_drvdata(component);
	struct regmap *regmap;
	int ret;

	if (wm9712->mfd_pdata) {
		wm9712->ac97 = wm9712->mfd_pdata->ac97;
		regmap = wm9712->mfd_pdata->regmap;
	} else {
#ifdef CONFIG_SND_SOC_AC97_BUS
		wm9712->ac97 = snd_soc_new_ac97_component(component, WM9712_VENDOR_ID,
						      WM9712_VENDOR_ID_MASK);
		if (IS_ERR(wm9712->ac97)) {
			ret = PTR_ERR(wm9712->ac97);
			dev_err(component->dev,
				"Failed to register AC97 codec: %d\n", ret);
			return ret;
		}

		regmap = regmap_init_ac97(wm9712->ac97, &wm9712_regmap_config);
		if (IS_ERR(regmap)) {
			snd_soc_free_ac97_component(wm9712->ac97);
			return PTR_ERR(regmap);
		}
#endif
	}

	snd_soc_component_init_regmap(component, regmap);

	/* set alc mux to none */
	snd_soc_component_update_bits(component, AC97_VIDEO, 0x3000, 0x3000);

	return 0;
}
示例#2
0
文件: cs4270.c 项目: krzk/linux
/**
 * cs4270_set_dai_fmt - configure the codec for the selected audio format
 * @codec_dai: the codec DAI
 * @format: a SND_SOC_DAIFMT_x value indicating the data format
 *
 * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the
 * codec accordingly.
 *
 * Currently, this function only supports SND_SOC_DAIFMT_I2S and
 * SND_SOC_DAIFMT_LEFT_J.  The CS4270 codec also supports right-justified
 * data for playback only, but ASoC currently does not support different
 * formats for playback vs. record.
 */
static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
			      unsigned int format)
{
	struct snd_soc_component *component = codec_dai->component;
	struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);

	/* set DAI format */
	switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
	case SND_SOC_DAIFMT_LEFT_J:
		cs4270->mode = format & SND_SOC_DAIFMT_FORMAT_MASK;
		break;
	default:
		dev_err(component->dev, "invalid dai format\n");
		return -EINVAL;
	}

	/* set master/slave audio interface */
	switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBS_CFS:
		cs4270->slave_mode = 1;
		break;
	case SND_SOC_DAIFMT_CBM_CFM:
		cs4270->slave_mode = 0;
		break;
	default:
		/* all other modes are unsupported by the hardware */
		dev_err(component->dev, "Unknown master/slave configuration\n");
		return -EINVAL;
	}

	return 0;
}
示例#3
0
static int wm8711_hw_params(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *params,
	struct snd_soc_dai *dai)
{
	struct snd_soc_component *component = dai->component;
	struct wm8711_priv *wm8711 =  snd_soc_component_get_drvdata(component);
	u16 iface = snd_soc_component_read32(component, WM8711_IFACE) & 0xfff3;
	int i = get_coeff(wm8711->sysclk, params_rate(params));
	u16 srate = (coeff_div[i].sr << 2) |
		(coeff_div[i].bosr << 1) | coeff_div[i].usb;

	snd_soc_component_write(component, WM8711_SRATE, srate);

	/* bit size */
	switch (params_width(params)) {
	case 16:
		break;
	case 20:
		iface |= 0x0004;
		break;
	case 24:
		iface |= 0x0008;
		break;
	}

	snd_soc_component_write(component, WM8711_IFACE, iface);
	return 0;
}
示例#4
0
static void mc13783_remove(struct snd_soc_component *component)
{
	struct mc13783_priv *priv = snd_soc_component_get_drvdata(component);

	/* Make sure VAUDIOON is off */
	mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_RX0, 0x3, 0);
}
示例#5
0
static int tas571x_hw_params(struct snd_pcm_substream *substream,
			     struct snd_pcm_hw_params *params,
			     struct snd_soc_dai *dai)
{
	struct tas571x_private *priv = snd_soc_component_get_drvdata(dai->component);
	u32 val;

	switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_RIGHT_J:
		val = 0x00;
		break;
	case SND_SOC_DAIFMT_I2S:
		val = 0x03;
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		val = 0x06;
		break;
	default:
		return -EINVAL;
	}

	if (params_width(params) >= 24)
		val += 2;
	else if (params_width(params) >= 20)
		val += 1;

	return regmap_update_bits(priv->regmap, TAS571X_SDI_REG,
				  TAS571X_SDI_FMT_MASK, val);
}
示例#6
0
文件: cs35l33.c 项目: Lyude/linux
static int cs35l33_pcm_hw_params(struct snd_pcm_substream *substream,
				 struct snd_pcm_hw_params *params,
				 struct snd_soc_dai *dai)
{
	struct snd_soc_component *component = dai->component;
	struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
	int sample_size = params_width(params);
	int coeff = cs35l33_get_mclk_coeff(priv->mclk_int, params_rate(params));

	if (coeff < 0)
		return coeff;

	regmap_update_bits(priv->regmap, CS35L33_CLK_CTL,
		CS35L33_ADSP_FS | CS35L33_INT_FS_RATE,
		cs35l33_mclk_coeffs[coeff].int_fs_ratio
		| cs35l33_mclk_coeffs[coeff].adsp_rate);

	if (priv->is_tdm_mode) {
		sample_size = (sample_size / 8) - 1;
		if (sample_size > 2)
			sample_size = 2;
		regmap_update_bits(priv->regmap, CS35L33_RX_AUD,
			CS35L33_AUDIN_RX_DEPTH,
			sample_size << CS35L33_AUDIN_RX_DEPTH_SHIFT);
	}

	dev_dbg(component->dev, "sample rate=%d, bits per sample=%d\n",
		params_rate(params), params_width(params));

	return 0;
}
示例#7
0
文件: cs35l33.c 项目: Lyude/linux
static int cs35l33_set_bst_ipk(struct snd_soc_component *component, unsigned int bst)
{
	struct cs35l33_private *cs35l33 = snd_soc_component_get_drvdata(component);
	int ret = 0, steps = 0;

	/* Boost current in uA */
	if (bst > 3600000 || bst < 1850000) {
		dev_err(component->dev, "Invalid boost current %d\n", bst);
		ret = -EINVAL;
		goto err;
	}

	if (bst % 15625) {
		dev_err(component->dev, "Current not a multiple of 15625uA (%d)\n",
			bst);
		ret = -EINVAL;
		goto err;
	}

	while (bst > 1850000) {
		bst -= 15625;
		steps++;
	}

	regmap_write(cs35l33->regmap, CS35L33_BST_PEAK_CTL,
		steps+0x70);

err:
	return ret;
}
示例#8
0
文件: ak5558.c 项目: Lyude/linux
static int ak5558_hw_params(struct snd_pcm_substream *substream,
			    struct snd_pcm_hw_params *params,
			    struct snd_soc_dai *dai)
{
	struct snd_soc_component *component = dai->component;
	struct ak5558_priv *ak5558 = snd_soc_component_get_drvdata(component);
	u8 bits;
	int pcm_width = max(params_physical_width(params), ak5558->slot_width);

	/* set master/slave audio interface */
	bits = snd_soc_component_read32(component, AK5558_02_CONTROL1);
	bits &= ~AK5558_BITS;

	switch (pcm_width) {
	case 16:
		bits |= AK5558_DIF_24BIT_MODE;
		break;
	case 32:
		bits |= AK5558_DIF_32BIT_MODE;
		break;
	default:
		return -EINVAL;
	}

	snd_soc_component_update_bits(component, AK5558_02_CONTROL1, AK5558_BITS, bits);

	return 0;
}
示例#9
0
文件: ak5558.c 项目: Lyude/linux
static int ak5558_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
			       unsigned int rx_mask, int slots,
			       int slot_width)
{
	struct snd_soc_component *component = dai->component;
	struct ak5558_priv *ak5558 = snd_soc_component_get_drvdata(component);
	int tdm_mode;

	ak5558->slots = slots;
	ak5558->slot_width = slot_width;

	switch (slots * slot_width) {
	case 128:
		tdm_mode = AK5558_MODE_TDM128;
		break;
	case 256:
		tdm_mode = AK5558_MODE_TDM256;
		break;
	case 512:
		tdm_mode = AK5558_MODE_TDM512;
		break;
	default:
		tdm_mode = AK5558_MODE_NORMAL;
		break;
	}

	snd_soc_component_update_bits(component, AK5558_03_CONTROL2, AK5558_MODE_BITS,
			    tdm_mode);
	return 0;
}
示例#10
0
static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai,
			       unsigned int fmt)
{
	struct snd_soc_component *component = codec_dai->component;
	struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component);

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

	/* codec supports only full slave mode */
	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
		printk(KERN_ERR "%s unsupported slave mode\n", __func__);
		return -EINVAL;
	}

	/* no support for clock inversion */
	if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) {
		printk(KERN_ERR "%s unsupported clock inversion\n", __func__);
		return -EINVAL;
	}

	/* We can't setup DAI format here as it depends on the word bit num */
	/* so let's just store the value for later */
	uda134x->dai_fmt = fmt;

	return 0;
}
示例#11
0
static int uda134x_set_bias_level(struct snd_soc_component *component,
				  enum snd_soc_bias_level level)
{
	struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component);
	struct uda134x_platform_data *pd = uda134x->pd;
	pr_debug("%s bias level %d\n", __func__, level);

	switch (level) {
	case SND_SOC_BIAS_ON:
		break;
	case SND_SOC_BIAS_PREPARE:
		/* power on */
		if (pd->power) {
			pd->power(1);
			regcache_sync(uda134x->regmap);
		}
		break;
	case SND_SOC_BIAS_STANDBY:
		break;
	case SND_SOC_BIAS_OFF:
		/* power off */
		if (pd->power) {
			pd->power(0);
			regcache_mark_dirty(uda134x->regmap);
		}
		break;
	}
	return 0;
}
示例#12
0
static int uda134x_startup(struct snd_pcm_substream *substream,
	struct snd_soc_dai *dai)
{
	struct snd_soc_component *component = dai->component;
	struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component);
	struct snd_pcm_runtime *master_runtime;

	if (uda134x->master_substream) {
		master_runtime = uda134x->master_substream->runtime;

		pr_debug("%s constraining to %d bits at %d\n", __func__,
			 master_runtime->sample_bits,
			 master_runtime->rate);

		snd_pcm_hw_constraint_single(substream->runtime,
					     SNDRV_PCM_HW_PARAM_RATE,
					     master_runtime->rate);

		snd_pcm_hw_constraint_single(substream->runtime,
					     SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
					     master_runtime->sample_bits);

		uda134x->slave_substream = substream;
	} else
		uda134x->master_substream = substream;

	return 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 snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
	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);
}
示例#14
0
static int sta529_set_bias_level(struct snd_soc_component *component, enum
		snd_soc_bias_level level)
{
	struct sta529 *sta529 = snd_soc_component_get_drvdata(component);

	switch (level) {
	case SND_SOC_BIAS_ON:
	case SND_SOC_BIAS_PREPARE:
		snd_soc_component_update_bits(component, STA529_FFXCFG0, POWER_CNTLMSAK,
				POWER_UP);
		snd_soc_component_update_bits(component, STA529_MISC,	FFX_CLK_MSK,
				FFX_CLK_ENB);
		break;
	case SND_SOC_BIAS_STANDBY:
		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
			regcache_sync(sta529->regmap);
		snd_soc_component_update_bits(component, STA529_FFXCFG0,
					POWER_CNTLMSAK, POWER_STDBY);
		/* Making FFX output to zero */
		snd_soc_component_update_bits(component, STA529_FFXCFG0, FFX_MASK,
				FFX_OFF);
		snd_soc_component_update_bits(component, STA529_MISC, FFX_CLK_MSK,
				FFX_CLK_DIS);
		break;
	case SND_SOC_BIAS_OFF:
		break;
	}

	return 0;

}
示例#15
0
文件: cs35l33.c 项目: Lyude/linux
static int cs35l33_spkrdrv_event(struct snd_soc_dapm_widget *w,
	struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
	struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);

	switch (event) {
	case SND_SOC_DAPM_POST_PMU:
		if (!priv->amp_cal) {
			usleep_range(8000, 9000);
			priv->amp_cal = true;
			regmap_update_bits(priv->regmap, CS35L33_CLASSD_CTL,
				    CS35L33_AMP_CAL, 0);
			dev_dbg(component->dev, "Amp calibration done\n");
		}
		dev_dbg(component->dev, "Amp turned on\n");
		break;
	case SND_SOC_DAPM_POST_PMD:
		dev_dbg(component->dev, "Amp turned off\n");
		break;
	default:
		dev_err(component->dev, "Invalid event = 0x%x\n", event);
		break;
	}

	return 0;
}
示例#16
0
文件: ak5558.c 项目: Lyude/linux
static int ak5558_probe(struct snd_soc_component *component)
{
	struct ak5558_priv *ak5558 = snd_soc_component_get_drvdata(component);

	ak5558_power_on(ak5558);
	return ak5558_set_mcki(component);
}
示例#17
0
文件: cs35l33.c 项目: Lyude/linux
static int cs35l33_set_bias_level(struct snd_soc_component *component,
				  enum snd_soc_bias_level level)
{
	unsigned int val;
	struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);

	switch (level) {
	case SND_SOC_BIAS_ON:
		break;
	case SND_SOC_BIAS_PREPARE:
		regmap_update_bits(priv->regmap, CS35L33_PWRCTL1,
				    CS35L33_PDN_ALL, 0);
		regmap_update_bits(priv->regmap, CS35L33_CLK_CTL,
				    CS35L33_MCLKDIS, 0);
		break;
	case SND_SOC_BIAS_STANDBY:
		regmap_update_bits(priv->regmap, CS35L33_PWRCTL1,
				    CS35L33_PDN_ALL, CS35L33_PDN_ALL);
		regmap_read(priv->regmap, CS35L33_INT_STATUS_2, &val);
		usleep_range(1000, 1100);
		if (val & CS35L33_PDN_DONE)
			regmap_update_bits(priv->regmap, CS35L33_CLK_CTL,
					    CS35L33_MCLKDIS, CS35L33_MCLKDIS);
		break;
	case SND_SOC_BIAS_OFF:
		break;
	default:
		return -EINVAL;
	}

	return 0;
}
示例#18
0
static int wm8728_set_bias_level(struct snd_soc_component *component,
				 enum snd_soc_bias_level level)
{
	struct wm8728_priv *wm8728 = snd_soc_component_get_drvdata(component);
	u16 reg;

	switch (level) {
	case SND_SOC_BIAS_ON:
	case SND_SOC_BIAS_PREPARE:
	case SND_SOC_BIAS_STANDBY:
		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
			/* Power everything up... */
			reg = snd_soc_component_read32(component, WM8728_DACCTL);
			snd_soc_component_write(component, WM8728_DACCTL, reg & ~0x4);

			/* ..then sync in the register cache. */
			regcache_sync(wm8728->regmap);
		}
		break;

	case SND_SOC_BIAS_OFF:
		reg = snd_soc_component_read32(component, WM8728_DACCTL);
		snd_soc_component_write(component, WM8728_DACCTL, reg | 0x4);
		break;
	}
	return 0;
}
示例#19
0
文件: cs35l33.c 项目: Lyude/linux
static int cs35l33_component_set_sysclk(struct snd_soc_component *component,
		int clk_id, int source, unsigned int freq, int dir)
{
	struct cs35l33_private *cs35l33 = snd_soc_component_get_drvdata(component);

	switch (freq) {
	case CS35L33_MCLK_5644:
	case CS35L33_MCLK_6:
	case CS35L33_MCLK_6144:
		regmap_update_bits(cs35l33->regmap, CS35L33_CLK_CTL,
			CS35L33_MCLKDIV2, 0);
		cs35l33->mclk_int = freq;
		break;
	case CS35L33_MCLK_11289:
	case CS35L33_MCLK_12:
	case CS35L33_MCLK_12288:
		regmap_update_bits(cs35l33->regmap, CS35L33_CLK_CTL,
			CS35L33_MCLKDIV2, CS35L33_MCLKDIV2);
		cs35l33->mclk_int = freq/2;
		break;
	default:
		cs35l33->mclk_int = 0;
		return -EINVAL;
	}

	dev_dbg(component->dev, "external mclk freq=%d, internal mclk freq=%d\n",
		freq, cs35l33->mclk_int);

	return 0;
}
示例#20
0
文件: adau17x1.c 项目: krzk/linux
static int adau17x1_dsp_mux_enum_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
	struct adau *adau = snd_soc_component_get_drvdata(component);
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	unsigned int stream = e->shift_l;
	unsigned int reg, val;
	int ret;

	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
		reg = ADAU17X1_SERIAL_INPUT_ROUTE;
	else
		reg = ADAU17X1_SERIAL_OUTPUT_ROUTE;

	ret = regmap_read(adau->regmap, reg, &val);
	if (ret)
		return ret;

	if (val != 0)
		val = 1;
	ucontrol->value.enumerated.item[0] = val;

	return 0;
}
示例#21
0
static int mc13783_probe(struct snd_soc_component *component)
{
	struct mc13783_priv *priv = snd_soc_component_get_drvdata(component);

	snd_soc_component_init_regmap(component,
				  dev_get_regmap(component->dev->parent, NULL));

	/* these are the reset values */
	mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX0, 0x25893);
	mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX1, 0x00d35A);
	mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_TX, 0x420000);
	mc13xxx_reg_write(priv->mc13xxx, MC13783_SSI_NETWORK, 0x013060);
	mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_CODEC, 0x180027);
	mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_DAC, 0x0e0004);

	if (priv->adc_ssi_port == MC13783_SSI1_PORT)
		mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_CODEC,
				AUDIO_SSI_SEL, 0);
	else
		mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_CODEC,
				AUDIO_SSI_SEL, AUDIO_SSI_SEL);

	if (priv->dac_ssi_port == MC13783_SSI1_PORT)
		mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_DAC,
				AUDIO_SSI_SEL, 0);
	else
		mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_DAC,
				AUDIO_SSI_SEL, AUDIO_SSI_SEL);

	return 0;
}
示例#22
0
文件: adau17x1.c 项目: krzk/linux
static int adau17x1_pll_event(struct snd_soc_dapm_widget *w,
	struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
	struct adau *adau = snd_soc_component_get_drvdata(component);

	if (SND_SOC_DAPM_EVENT_ON(event)) {
		adau->pll_regs[5] = 1;
	} else {
		adau->pll_regs[5] = 0;
		/* Bypass the PLL when disabled, otherwise registers will become
		 * inaccessible. */
		regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
			ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL, 0);
	}

	/* The PLL register is 6 bytes long and can only be written at once. */
	regmap_raw_write(adau->regmap, ADAU17X1_PLL_CONTROL,
			adau->pll_regs, ARRAY_SIZE(adau->pll_regs));

	if (SND_SOC_DAPM_EVENT_ON(event)) {
		mdelay(5);
		regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
			ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL,
			ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL);
	}

	return 0;
}
示例#23
0
static int sst_byt_pcm_open(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
	struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
	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;
}
示例#24
0
文件: adau17x1.c 项目: krzk/linux
int adau17x1_add_widgets(struct snd_soc_component *component)
{
	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
	struct adau *adau = snd_soc_component_get_drvdata(component);
	int ret;

	ret = snd_soc_add_component_controls(component, adau17x1_controls,
		ARRAY_SIZE(adau17x1_controls));
	if (ret)
		return ret;
	ret = snd_soc_dapm_new_controls(dapm, adau17x1_dapm_widgets,
		ARRAY_SIZE(adau17x1_dapm_widgets));
	if (ret)
		return ret;

	if (adau17x1_has_dsp(adau)) {
		ret = snd_soc_dapm_new_controls(dapm, adau17x1_dsp_dapm_widgets,
			ARRAY_SIZE(adau17x1_dsp_dapm_widgets));
		if (ret)
			return ret;

		if (!adau->sigmadsp)
			return 0;

		ret = sigmadsp_attach(adau->sigmadsp, component);
		if (ret) {
			dev_err(component->dev, "Failed to attach firmware: %d\n",
				ret);
			return ret;
		}
	}

	return 0;
}
示例#25
0
static int tas571x_set_bias_level(struct snd_soc_component *component,
				  enum snd_soc_bias_level level)
{
	struct tas571x_private *priv = snd_soc_component_get_drvdata(component);
	int ret;

	switch (level) {
	case SND_SOC_BIAS_ON:
		break;
	case SND_SOC_BIAS_PREPARE:
		break;
	case SND_SOC_BIAS_STANDBY:
		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
			if (!IS_ERR(priv->mclk)) {
				ret = clk_prepare_enable(priv->mclk);
				if (ret) {
					dev_err(component->dev,
						"Failed to enable master clock: %d\n",
						ret);
					return ret;
				}
			}
		}
		break;
	case SND_SOC_BIAS_OFF:
		if (!IS_ERR(priv->mclk))
			clk_disable_unprepare(priv->mclk);
		break;
	}

	return 0;
}
示例#26
0
static int ad1980_reset(struct snd_soc_component *component, int try_warm)
{
	struct snd_ac97 *ac97 = snd_soc_component_get_drvdata(component);
	unsigned int retry_cnt = 0;
	int ret;

	do {
		ret = snd_ac97_reset(ac97, true, AD1980_VENDOR_ID,
			AD1980_VENDOR_MASK);
		if (ret >= 0)
			return 0;

		/*
		 * Set bit 16slot in register 74h, then every slot will has only
		 * 16 bits. This command is sent out in 20bit mode, in which
		 * case the first nibble of data is eaten by the addr. (Tag is
		 * always 16 bit)
		 */
		snd_soc_component_write(component, AC97_AD_SERIAL_CFG, 0x9900);

	} while (retry_cnt++ < 10);

	dev_err(component->dev, "Failed to reset: AC97 link error\n");

	return -EIO;
}
示例#27
0
文件: cs4270.c 项目: krzk/linux
/**
 * cs4270_probe - ASoC probe function
 * @pdev: platform device
 *
 * This function is called when ASoC has all the pieces it needs to
 * instantiate a sound driver.
 */
static int cs4270_probe(struct snd_soc_component *component)
{
	struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
	int ret;

	/* Disable auto-mute.  This feature appears to be buggy.  In some
	 * situations, auto-mute will not deactivate when it should, so we want
	 * this feature disabled by default.  An application (e.g. alsactl) can
	 * re-enabled it by using the controls.
	 */
	ret = snd_soc_component_update_bits(component, CS4270_MUTE, CS4270_MUTE_AUTO, 0);
	if (ret < 0) {
		dev_err(component->dev, "i2c write failed\n");
		return ret;
	}

	/* Disable automatic volume control.  The hardware enables, and it
	 * causes volume change commands to be delayed, sometimes until after
	 * playback has started.  An application (e.g. alsactl) can
	 * re-enabled it by using the controls.
	 */
	ret = snd_soc_component_update_bits(component, CS4270_TRANS,
		CS4270_TRANS_SOFT | CS4270_TRANS_ZERO, 0);
	if (ret < 0) {
		dev_err(component->dev, "i2c write failed\n");
		return ret;
	}

	ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
				    cs4270->supplies);

	return ret;
}
示例#28
0
static void ad1980_soc_remove(struct snd_soc_component *component)
{
	struct snd_ac97 *ac97 = snd_soc_component_get_drvdata(component);

	snd_soc_component_exit_regmap(component);
	snd_soc_free_ac97_component(ac97);
}
示例#29
0
static int wm8711_set_bias_level(struct snd_soc_component *component,
	enum snd_soc_bias_level level)
{
	struct wm8711_priv *wm8711 = snd_soc_component_get_drvdata(component);
	u16 reg = snd_soc_component_read32(component, WM8711_PWR) & 0xff7f;

	switch (level) {
	case SND_SOC_BIAS_ON:
		snd_soc_component_write(component, WM8711_PWR, reg);
		break;
	case SND_SOC_BIAS_PREPARE:
		break;
	case SND_SOC_BIAS_STANDBY:
		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
			regcache_sync(wm8711->regmap);

		snd_soc_component_write(component, WM8711_PWR, reg | 0x0040);
		break;
	case SND_SOC_BIAS_OFF:
		snd_soc_component_write(component, WM8711_ACTIVE, 0x0);
		snd_soc_component_write(component, WM8711_PWR, 0xffff);
		break;
	}
	return 0;
}
示例#30
0
static int mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget *source,
				    struct snd_soc_dapm_widget *sink)
{
	struct snd_soc_dapm_widget *w = sink;
	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
	struct mtk_afe_i2s_priv *i2s_priv;

	i2s_priv = get_i2s_priv_by_name(afe, sink->name);

	if (!i2s_priv) {
		dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
		return 0;
	}

	if (get_i2s_id_by_name(afe, sink->name) ==
	    get_i2s_id_by_name(afe, source->name))
		return (i2s_priv->mclk_rate > 0) ? 1 : 0;

	/* check if share i2s need mclk */
	if (i2s_priv->share_i2s_id < 0)
		return 0;

	if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))
		return (i2s_priv->mclk_rate > 0) ? 1 : 0;

	return 0;
}