Beispiel #1
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;
}
Beispiel #2
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;
}
Beispiel #3
0
static void ak4613_dummy_write(struct work_struct *work)
{
	struct ak4613_priv *priv = container_of(work,
						struct ak4613_priv,
						dummy_write_work);
	struct snd_soc_component *component = priv->component;
	unsigned int mgmt1;
	unsigned int mgmt3;

	/*
	 * PW_MGMT1 / PW_MGMT3 needs dummy write at least after 5 LR clocks
	 *
	 * Note
	 *
	 * To avoid extra delay, we want to avoid preemption here,
	 * but we can't. Because it uses I2C access which is using IRQ
	 * and sleep. Thus, delay might be more than 5 LR clocks
	 * see also
	 *	ak4613_dai_trigger()
	 */
	udelay(5000000 / priv->rate);

	snd_soc_component_read(component, PW_MGMT1, &mgmt1);
	snd_soc_component_read(component, PW_MGMT3, &mgmt3);

	snd_soc_component_write(component, PW_MGMT1, mgmt1);
	snd_soc_component_write(component, PW_MGMT3, mgmt3);
}
Beispiel #4
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;
}
Beispiel #5
0
static int wm8728_mute(struct snd_soc_dai *dai, int mute)
{
	struct snd_soc_component *component = dai->component;
	u16 mute_reg = snd_soc_component_read32(component, WM8728_DACCTL);

	if (mute)
		snd_soc_component_write(component, WM8728_DACCTL, mute_reg | 1);
	else
		snd_soc_component_write(component, WM8728_DACCTL, mute_reg & ~1);

	return 0;
}
Beispiel #6
0
static int wm8711_mute(struct snd_soc_dai *dai, int mute)
{
	struct snd_soc_component *component = dai->component;
	u16 mute_reg = snd_soc_component_read32(component, WM8711_APDIGI) & 0xfff7;

	if (mute)
		snd_soc_component_write(component, WM8711_APDIGI, mute_reg | 0x8);
	else
		snd_soc_component_write(component, WM8711_APDIGI, mute_reg);

	return 0;
}
Beispiel #7
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;
}
Beispiel #8
0
static int wm8728_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;
	u16 dac = snd_soc_component_read32(component, WM8728_DACCTL);

	dac &= ~0x18;

	switch (params_width(params)) {
	case 16:
		break;
	case 20:
		dac |= 0x10;
		break;
	case 24:
		dac |= 0x08;
		break;
	default:
		return -EINVAL;
	}

	snd_soc_component_write(component, WM8728_DACCTL, dac);

	return 0;
}
Beispiel #9
0
static int aic32x4_set_mfp2_gpio(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	u8 val;
	u8 gpio_check;

	val = snd_soc_component_read32(component, AIC32X4_DOUTCTL);
	gpio_check = (val & AIC32X4_MFP_GPIO_ENABLED);
	if (gpio_check != AIC32X4_MFP_GPIO_ENABLED) {
		printk(KERN_ERR "%s: MFP2 is not configure as a GPIO output\n",
			__func__);
		return -EINVAL;
	}

	if (ucontrol->value.integer.value[0] == (val & AIC32X4_MFP2_GPIO_OUT_HIGH))
		return 0;

	if (ucontrol->value.integer.value[0])
		val |= ucontrol->value.integer.value[0];
	else
		val &= ~AIC32X4_MFP2_GPIO_OUT_HIGH;

	snd_soc_component_write(component, AIC32X4_DOUTCTL, val);

	return 0;
};
Beispiel #10
0
static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai,
		unsigned int fmt)
{
	struct snd_soc_component *component = codec_dai->component;
	u16 iface = snd_soc_component_read32(component, WM8711_IFACE) & 0x000c;

	/* set master/slave audio interface */
	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBM_CFM:
		iface |= 0x0040;
		break;
	case SND_SOC_DAIFMT_CBS_CFS:
		break;
	default:
		return -EINVAL;
	}

	/* interface format */
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		iface |= 0x0002;
		break;
	case SND_SOC_DAIFMT_RIGHT_J:
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		iface |= 0x0001;
		break;
	case SND_SOC_DAIFMT_DSP_A:
		iface |= 0x0003;
		break;
	case SND_SOC_DAIFMT_DSP_B:
		iface |= 0x0013;
		break;
	default:
		return -EINVAL;
	}

	/* clock inversion */
	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_NB_NF:
		break;
	case SND_SOC_DAIFMT_IB_IF:
		iface |= 0x0090;
		break;
	case SND_SOC_DAIFMT_IB_NF:
		iface |= 0x0080;
		break;
	case SND_SOC_DAIFMT_NB_IF:
		iface |= 0x0010;
		break;
	default:
		return -EINVAL;
	}

	/* set iface */
	snd_soc_component_write(component, WM8711_IFACE, iface);
	return 0;
}
Beispiel #11
0
static int wm9712_set_bias_level(struct snd_soc_component *component,
				 enum snd_soc_bias_level level)
{
	switch (level) {
	case SND_SOC_BIAS_ON:
	case SND_SOC_BIAS_PREPARE:
		break;
	case SND_SOC_BIAS_STANDBY:
		snd_soc_component_write(component, AC97_POWERDOWN, 0x0000);
		break;
	case SND_SOC_BIAS_OFF:
		/* disable everything including AC link */
		snd_soc_component_write(component, AC97_EXTENDED_MSTATUS, 0xffff);
		snd_soc_component_write(component, AC97_POWERDOWN, 0xffff);
		break;
	}
	return 0;
}
Beispiel #12
0
static int wm8711_pcm_prepare(struct snd_pcm_substream *substream,
			      struct snd_soc_dai *dai)
{
	struct snd_soc_component *component = dai->component;

	/* set active */
	snd_soc_component_write(component, WM8711_ACTIVE, 0x0001);

	return 0;
}
Beispiel #13
0
static int ak4642_dai_startup(struct snd_pcm_substream *substream,
			      struct snd_soc_dai *dai)
{
	int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
	struct snd_soc_component *component = dai->component;

	if (is_play) {
		/*
		 * start headphone output
		 *
		 * PLL, Master Mode
		 * Audio I/F Format :MSB justified (ADC & DAC)
		 * Bass Boost Level : Middle
		 *
		 * This operation came from example code of
		 * "ASAHI KASEI AK4642" (japanese) manual p97.
		 */
		snd_soc_component_write(component, L_IVC, 0x91); /* volume */
		snd_soc_component_write(component, R_IVC, 0x91); /* volume */
	} else {
		/*
		 * start stereo input
		 *
		 * PLL Master Mode
		 * Audio I/F Format:MSB justified (ADC & DAC)
		 * Pre MIC AMP:+20dB
		 * MIC Power On
		 * ALC setting:Refer to Table 35
		 * ALC bit=“1”
		 *
		 * This operation came from example code of
		 * "ASAHI KASEI AK4642" (japanese) manual p94.
		 */
		snd_soc_component_update_bits(component, SG_SL1, PMMP | MGAIN0, PMMP | MGAIN0);
		snd_soc_component_write(component, TIMER, ZTM(0x3) | WTM(0x3));
		snd_soc_component_write(component, ALC_CTL1, ALC | LMTH0);
		snd_soc_component_update_bits(component, PW_MGMT1, PMADL, PMADL);
		snd_soc_component_update_bits(component, PW_MGMT3, PMADR, PMADR);
	}

	return 0;
}
Beispiel #14
0
static void wm8711_shutdown(struct snd_pcm_substream *substream,
			    struct snd_soc_dai *dai)
{
	struct snd_soc_component *component = dai->component;

	/* deactivate */
	if (!snd_soc_component_is_active(component)) {
		udelay(50);
		snd_soc_component_write(component, WM8711_ACTIVE, 0x0);
	}
}
Beispiel #15
0
static int eqmode_put(struct snd_kcontrol *kcontrol,
		      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
	unsigned int regpwr2, regpwr3;
	unsigned int reg_eq;

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

	reg_eq = snd_soc_component_read32(component, WM8983_EQ1_LOW_SHELF);
	switch ((reg_eq & WM8983_EQ3DMODE) >> WM8983_EQ3DMODE_SHIFT) {
	case 0:
		if (!ucontrol->value.enumerated.item[0])
			return 0;
		break;
	case 1:
		if (ucontrol->value.enumerated.item[0])
			return 0;
		break;
	}

	regpwr2 = snd_soc_component_read32(component, WM8983_POWER_MANAGEMENT_2);
	regpwr3 = snd_soc_component_read32(component, WM8983_POWER_MANAGEMENT_3);
	/* disable the DACs and ADCs */
	snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_2,
			    WM8983_ADCENR_MASK | WM8983_ADCENL_MASK, 0);
	snd_soc_component_update_bits(component, WM8983_POWER_MANAGEMENT_3,
			    WM8983_DACENR_MASK | WM8983_DACENL_MASK, 0);
	/* set the desired eqmode */
	snd_soc_component_update_bits(component, WM8983_EQ1_LOW_SHELF,
			    WM8983_EQ3DMODE_MASK,
			    ucontrol->value.enumerated.item[0]
			    << WM8983_EQ3DMODE_SHIFT);
	/* restore DAC/ADC configuration */
	snd_soc_component_write(component, WM8983_POWER_MANAGEMENT_2, regpwr2);
	snd_soc_component_write(component, WM8983_POWER_MANAGEMENT_3, regpwr3);
	return 0;
}
Beispiel #16
0
static int wm8900_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;
	u16 reg;

	reg = snd_soc_component_read32(component, WM8900_REG_AUDIO1) & ~0x60;

	switch (params_width(params)) {
	case 16:
		break;
	case 20:
		reg |= 0x20;
		break;
	case 24:
		reg |= 0x40;
		break;
	case 32:
		reg |= 0x60;
		break;
	default:
		return -EINVAL;
	}

	snd_soc_component_write(component, WM8900_REG_AUDIO1, reg);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		reg = snd_soc_component_read32(component, WM8900_REG_DACCTRL);

		if (params_rate(params) <= 24000)
			reg |= WM8900_REG_DACCTRL_DAC_SB_FILT;
		else
			reg &= ~WM8900_REG_DACCTRL_DAC_SB_FILT;

		snd_soc_component_write(component, WM8900_REG_DACCTRL, reg);
	}

	return 0;
}
Beispiel #17
0
static int wm8770_set_bias_level(struct snd_soc_component *component,
				 enum snd_soc_bias_level level)
{
	int ret;
	struct wm8770_priv *wm8770;

	wm8770 = snd_soc_component_get_drvdata(component);

	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) {
			ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies),
						    wm8770->supplies);
			if (ret) {
				dev_err(component->dev,
					"Failed to enable supplies: %d\n",
					ret);
				return ret;
			}

			regcache_sync(wm8770->regmap);

			/* global powerup */
			snd_soc_component_write(component, WM8770_PWDNCTRL, 0);
		}
		break;
	case SND_SOC_BIAS_OFF:
		/* global powerdown */
		snd_soc_component_write(component, WM8770_PWDNCTRL, 1);
		regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies),
				       wm8770->supplies);
		break;
	}

	return 0;
}
Beispiel #18
0
static int ac97_aux_prepare(struct snd_pcm_substream *substream,
			    struct snd_soc_dai *dai)
{
	struct snd_soc_component *component = dai->component;
	struct snd_pcm_runtime *runtime = substream->runtime;

	snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x1, 0x1);
	snd_soc_component_update_bits(component, AC97_PCI_SID, 0x8000, 0x8000);

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

	return snd_soc_component_write(component, AC97_PCM_SURR_DAC_RATE, runtime->rate);
}
Beispiel #19
0
static int ak4642_set_bias_level(struct snd_soc_component *component,
				 enum snd_soc_bias_level level)
{
	switch (level) {
	case SND_SOC_BIAS_OFF:
		snd_soc_component_write(component, PW_MGMT1, 0x00);
		break;
	default:
		snd_soc_component_update_bits(component, PW_MGMT1, PMVCM, PMVCM);
		break;
	}

	return 0;
}
Beispiel #20
0
static int cq93vc_set_bias_level(struct snd_soc_component *component,
				enum snd_soc_bias_level level)
{
	switch (level) {
	case SND_SOC_BIAS_ON:
		snd_soc_component_write(component, DAVINCI_VC_REG12,
			     DAVINCI_VC_REG12_POWER_ALL_ON);
		break;
	case SND_SOC_BIAS_PREPARE:
		break;
	case SND_SOC_BIAS_STANDBY:
		snd_soc_component_write(component, DAVINCI_VC_REG12,
			     DAVINCI_VC_REG12_POWER_ALL_OFF);
		break;
	case SND_SOC_BIAS_OFF:
		/* force all power off */
		snd_soc_component_write(component, DAVINCI_VC_REG12,
			     DAVINCI_VC_REG12_POWER_ALL_OFF);
		break;
	}

	return 0;
}
Beispiel #21
0
static int ac97_prepare(struct snd_pcm_substream *substream,
			struct snd_soc_dai *dai)
{
	struct snd_soc_component *component = dai->component;
	int reg;
	struct snd_pcm_runtime *runtime = substream->runtime;

	snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x1, 0x1);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		reg = AC97_PCM_FRONT_DAC_RATE;
	else
		reg = AC97_PCM_LR_ADC_RATE;

	return snd_soc_component_write(component, reg, runtime->rate);
}
Beispiel #22
0
static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai,
		unsigned int fmt)
{
	struct snd_soc_component *component = codec_dai->component;
	u16 iface = snd_soc_component_read32(component, WM8728_IFCTL);

	/* Currently only I2S is supported by the driver, though the
	 * hardware is more flexible.
	 */
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		iface |= 1;
		break;
	default:
		return -EINVAL;
	}

	/* The hardware only support full slave mode */
	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBS_CFS:
		break;
	default:
		return -EINVAL;
	}

	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_NB_NF:
		iface &= ~0x22;
		break;
	case SND_SOC_DAIFMT_IB_NF:
		iface |=  0x20;
		iface &= ~0x02;
		break;
	case SND_SOC_DAIFMT_NB_IF:
		iface |= 0x02;
		iface &= ~0x20;
		break;
	case SND_SOC_DAIFMT_IB_IF:
		iface |= 0x22;
		break;
	default:
		return -EINVAL;
	}

	snd_soc_component_write(component, WM8728_IFCTL, iface);
	return 0;
}
Beispiel #23
0
/**
 * cs4270_dai_mute - enable/disable the CS4270 external mute
 * @dai: the SOC DAI
 * @mute: 0 = disable mute, 1 = enable mute
 *
 * This function toggles the mute bits in the MUTE register.  The CS4270's
 * mute capability is intended for external muting circuitry, so if the
 * board does not have the MUTEA or MUTEB pins connected to such circuitry,
 * then this function will do nothing.
 */
static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute)
{
	struct snd_soc_component *component = dai->component;
	struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
	int reg6;

	reg6 = snd_soc_component_read32(component, CS4270_MUTE);

	if (mute)
		reg6 |= CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B;
	else {
		reg6 &= ~(CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B);
		reg6 |= cs4270->manual_mute;
	}

	return snd_soc_component_write(component, CS4270_MUTE, reg6);
}
Beispiel #24
0
static int ad1980_soc_probe(struct snd_soc_component *component)
{
	struct snd_ac97 *ac97;
	struct regmap *regmap;
	int ret;
	u16 vendor_id2;
	u16 ext_status;

	ac97 = snd_soc_new_ac97_component(component, 0, 0);
	if (IS_ERR(ac97)) {
		ret = PTR_ERR(ac97);
		dev_err(component->dev, "Failed to register AC97 component: %d\n", ret);
		return ret;
	}

	regmap = regmap_init_ac97(ac97, &ad1980_regmap_config);
	if (IS_ERR(regmap)) {
		ret = PTR_ERR(regmap);
		goto err_free_ac97;
	}

	snd_soc_component_init_regmap(component, regmap);
	snd_soc_component_set_drvdata(component, ac97);

	ret = ad1980_reset(component, 0);
	if (ret < 0)
		goto reset_err;

	vendor_id2 = snd_soc_component_read32(component, AC97_VENDOR_ID2);
	if (vendor_id2 == 0x5374) {
		dev_warn(component->dev,
			"Found AD1981 - only 2/2 IN/OUT Channels supported\n");
	}

	/* unmute captures and playbacks volume */
	snd_soc_component_write(component, AC97_MASTER, 0x0000);
	snd_soc_component_write(component, AC97_PCM, 0x0000);
	snd_soc_component_write(component, AC97_REC_GAIN, 0x0000);
	snd_soc_component_write(component, AC97_CENTER_LFE_MASTER, 0x0000);
	snd_soc_component_write(component, AC97_SURROUND_MASTER, 0x0000);

	/*power on LFE/CENTER/Surround DACs*/
	ext_status = snd_soc_component_read32(component, AC97_EXTENDED_STATUS);
	snd_soc_component_write(component, AC97_EXTENDED_STATUS, ext_status&~0x3800);

	return 0;

reset_err:
	snd_soc_component_exit_regmap(component);
err_free_ac97:
	snd_soc_free_ac97_component(ac97);
	return ret;
}
Beispiel #25
0
static int cs4270_soc_suspend(struct snd_soc_component *component)
{
	struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
	int reg, ret;

	reg = snd_soc_component_read32(component, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
	if (reg < 0)
		return reg;

	ret = snd_soc_component_write(component, CS4270_PWRCTL, reg);
	if (ret < 0)
		return ret;

	regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies),
			       cs4270->supplies);

	return 0;
}
Beispiel #26
0
static int cs4270_soc_resume(struct snd_soc_component *component)
{
	struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
	int reg, ret;

	ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
				    cs4270->supplies);
	if (ret != 0)
		return ret;

	/* In case the device was put to hard reset during sleep, we need to
	 * wait 500ns here before any I2C communication. */
	ndelay(500);

	/* first restore the entire register cache ... */
	regcache_sync(cs4270->regmap);

	/* ... then disable the power-down bits */
	reg = snd_soc_component_read32(component, CS4270_PWRCTL);
	reg &= ~CS4270_PWRCTL_PDN_ALL;

	return snd_soc_component_write(component, CS4270_PWRCTL, reg);
}
Beispiel #27
0
static int ak4642_set_mcko(struct snd_soc_component *component,
			   u32 frequency)
{
	static const u32 fs_list[] = {
		[0] = 8000,
		[1] = 12000,
		[2] = 16000,
		[3] = 24000,
		[4] = 7350,
		[5] = 11025,
		[6] = 14700,
		[7] = 22050,
		[10] = 32000,
		[11] = 48000,
		[14] = 29400,
		[15] = 44100,
	};
	static const u32 ps_list[] = {
		[0] = 256,
		[1] = 128,
		[2] = 64,
		[3] = 32
	};
	int ps, fs;

	for (ps = 0; ps < ARRAY_SIZE(ps_list); ps++) {
		for (fs = 0; fs < ARRAY_SIZE(fs_list); fs++) {
			if (frequency == ps_list[ps] * fs_list[fs]) {
				snd_soc_component_write(component, MD_CTL2,
					      PSs(ps) | FSs(fs));
				return 0;
			}
		}
	}

	return 0;
}
Beispiel #28
0
static int ak4613_set_bias_level(struct snd_soc_component *component,
				 enum snd_soc_bias_level level)
{
	u8 mgmt1 = 0;

	switch (level) {
	case SND_SOC_BIAS_ON:
		mgmt1 |= RSTN;
		/* fall through */
	case SND_SOC_BIAS_PREPARE:
		mgmt1 |= PMADC | PMDAC;
		/* fall through */
	case SND_SOC_BIAS_STANDBY:
		mgmt1 |= PMVR;
		/* fall through */
	case SND_SOC_BIAS_OFF:
	default:
		break;
	}

	snd_soc_component_write(component, PW_MGMT1, mgmt1);

	return 0;
}
Beispiel #29
0
static int wm8770_reset(struct snd_soc_component *component)
{
	return snd_soc_component_write(component, WM8770_RESET, 0);
}
Beispiel #30
0
/**
 * cs4270_hw_params - program the CS4270 with the given hardware parameters.
 * @substream: the audio stream
 * @params: the hardware parameters to set
 * @dai: the SOC DAI (ignored)
 *
 * This function programs the hardware with the values provided.
 * Specifically, the sample rate and the data format.
 *
 * The .ops functions are used to provide board-specific data, like input
 * frequencies, to this driver.  This function takes that information,
 * combines it with the hardware parameters provided, and programs the
 * hardware accordingly.
 */
static int cs4270_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 cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
	int ret;
	unsigned int i;
	unsigned int rate;
	unsigned int ratio;
	int reg;

	/* Figure out which MCLK/LRCK ratio to use */

	rate = params_rate(params);	/* Sampling rate, in Hz */
	ratio = cs4270->mclk / rate;	/* MCLK/LRCK ratio */

	for (i = 0; i < NUM_MCLK_RATIOS; i++) {
		if (cs4270_mode_ratios[i].ratio == ratio)
			break;
	}

	if (i == NUM_MCLK_RATIOS) {
		/* We did not find a matching ratio */
		dev_err(component->dev, "could not find matching ratio\n");
		return -EINVAL;
	}

	/* Set the sample rate */

	reg = snd_soc_component_read32(component, CS4270_MODE);
	reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK);
	reg |= cs4270_mode_ratios[i].mclk;

	if (cs4270->slave_mode)
		reg |= CS4270_MODE_SLAVE;
	else
		reg |= cs4270_mode_ratios[i].speed_mode;

	ret = snd_soc_component_write(component, CS4270_MODE, reg);
	if (ret < 0) {
		dev_err(component->dev, "i2c write failed\n");
		return ret;
	}

	/* Set the DAI format */

	reg = snd_soc_component_read32(component, CS4270_FORMAT);
	reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK);

	switch (cs4270->mode) {
	case SND_SOC_DAIFMT_I2S:
		reg |= CS4270_FORMAT_DAC_I2S | CS4270_FORMAT_ADC_I2S;
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		reg |= CS4270_FORMAT_DAC_LJ | CS4270_FORMAT_ADC_LJ;
		break;
	default:
		dev_err(component->dev, "unknown dai format\n");
		return -EINVAL;
	}

	ret = snd_soc_component_write(component, CS4270_FORMAT, reg);
	if (ret < 0) {
		dev_err(component->dev, "i2c write failed\n");
		return ret;
	}

	return ret;
}