Commit e2755cf9 authored by Takashi Iwai's avatar Takashi Iwai

Merge tag 'asoc-v3.14-rc4' of...

Merge tag 'asoc-v3.14-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: Fixes for v3.14

A somewhat large set of fixes here due to the identification of some
systematic problems with hard to use APIs in the subsystem.  Takashi did
a lot of work to address the enumeration API which uncovered a number of
off by one bugs caused by confusing APIs while Charles addressed issues
in the locking around DAPM.
parents fce0a0c7 57374bb4
...@@ -222,27 +222,19 @@ static void arizona_extcon_pulse_micbias(struct arizona_extcon_info *info) ...@@ -222,27 +222,19 @@ static void arizona_extcon_pulse_micbias(struct arizona_extcon_info *info)
struct snd_soc_dapm_context *dapm = arizona->dapm; struct snd_soc_dapm_context *dapm = arizona->dapm;
int ret; int ret;
mutex_lock(&dapm->card->dapm_mutex);
ret = snd_soc_dapm_force_enable_pin(dapm, widget); ret = snd_soc_dapm_force_enable_pin(dapm, widget);
if (ret != 0) if (ret != 0)
dev_warn(arizona->dev, "Failed to enable %s: %d\n", dev_warn(arizona->dev, "Failed to enable %s: %d\n",
widget, ret); widget, ret);
mutex_unlock(&dapm->card->dapm_mutex);
snd_soc_dapm_sync(dapm); snd_soc_dapm_sync(dapm);
if (!arizona->pdata.micd_force_micbias) { if (!arizona->pdata.micd_force_micbias) {
mutex_lock(&dapm->card->dapm_mutex);
ret = snd_soc_dapm_disable_pin(arizona->dapm, widget); ret = snd_soc_dapm_disable_pin(arizona->dapm, widget);
if (ret != 0) if (ret != 0)
dev_warn(arizona->dev, "Failed to disable %s: %d\n", dev_warn(arizona->dev, "Failed to disable %s: %d\n",
widget, ret); widget, ret);
mutex_unlock(&dapm->card->dapm_mutex);
snd_soc_dapm_sync(dapm); snd_soc_dapm_sync(dapm);
} }
} }
...@@ -304,16 +296,12 @@ static void arizona_stop_mic(struct arizona_extcon_info *info) ...@@ -304,16 +296,12 @@ static void arizona_stop_mic(struct arizona_extcon_info *info)
ARIZONA_MICD_ENA, 0, ARIZONA_MICD_ENA, 0,
&change); &change);
mutex_lock(&dapm->card->dapm_mutex);
ret = snd_soc_dapm_disable_pin(dapm, widget); ret = snd_soc_dapm_disable_pin(dapm, widget);
if (ret != 0) if (ret != 0)
dev_warn(arizona->dev, dev_warn(arizona->dev,
"Failed to disable %s: %d\n", "Failed to disable %s: %d\n",
widget, ret); widget, ret);
mutex_unlock(&dapm->card->dapm_mutex);
snd_soc_dapm_sync(dapm); snd_soc_dapm_sync(dapm);
if (info->micd_reva) { if (info->micd_reva) {
......
...@@ -37,7 +37,6 @@ static void arizona_haptics_work(struct work_struct *work) ...@@ -37,7 +37,6 @@ static void arizona_haptics_work(struct work_struct *work)
struct arizona_haptics, struct arizona_haptics,
work); work);
struct arizona *arizona = haptics->arizona; struct arizona *arizona = haptics->arizona;
struct mutex *dapm_mutex = &arizona->dapm->card->dapm_mutex;
int ret; int ret;
if (!haptics->arizona->dapm) { if (!haptics->arizona->dapm) {
...@@ -67,13 +66,10 @@ static void arizona_haptics_work(struct work_struct *work) ...@@ -67,13 +66,10 @@ static void arizona_haptics_work(struct work_struct *work)
return; return;
} }
mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
ret = snd_soc_dapm_enable_pin(arizona->dapm, "HAPTICS"); ret = snd_soc_dapm_enable_pin(arizona->dapm, "HAPTICS");
if (ret != 0) { if (ret != 0) {
dev_err(arizona->dev, "Failed to start HAPTICS: %d\n", dev_err(arizona->dev, "Failed to start HAPTICS: %d\n",
ret); ret);
mutex_unlock(dapm_mutex);
return; return;
} }
...@@ -81,21 +77,14 @@ static void arizona_haptics_work(struct work_struct *work) ...@@ -81,21 +77,14 @@ static void arizona_haptics_work(struct work_struct *work)
if (ret != 0) { if (ret != 0) {
dev_err(arizona->dev, "Failed to sync DAPM: %d\n", dev_err(arizona->dev, "Failed to sync DAPM: %d\n",
ret); ret);
mutex_unlock(dapm_mutex);
return; return;
} }
mutex_unlock(dapm_mutex);
} else { } else {
/* This disable sequence will be a noop if already enabled */ /* This disable sequence will be a noop if already enabled */
mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
ret = snd_soc_dapm_disable_pin(arizona->dapm, "HAPTICS"); ret = snd_soc_dapm_disable_pin(arizona->dapm, "HAPTICS");
if (ret != 0) { if (ret != 0) {
dev_err(arizona->dev, "Failed to disable HAPTICS: %d\n", dev_err(arizona->dev, "Failed to disable HAPTICS: %d\n",
ret); ret);
mutex_unlock(dapm_mutex);
return; return;
} }
...@@ -103,12 +92,9 @@ static void arizona_haptics_work(struct work_struct *work) ...@@ -103,12 +92,9 @@ static void arizona_haptics_work(struct work_struct *work)
if (ret != 0) { if (ret != 0) {
dev_err(arizona->dev, "Failed to sync DAPM: %d\n", dev_err(arizona->dev, "Failed to sync DAPM: %d\n",
ret); ret);
mutex_unlock(dapm_mutex);
return; return;
} }
mutex_unlock(dapm_mutex);
ret = regmap_update_bits(arizona->regmap, ret = regmap_update_bits(arizona->regmap,
ARIZONA_HAPTICS_CONTROL_1, ARIZONA_HAPTICS_CONTROL_1,
ARIZONA_HAP_CTRL_MASK, ARIZONA_HAP_CTRL_MASK,
...@@ -155,16 +141,11 @@ static int arizona_haptics_play(struct input_dev *input, void *data, ...@@ -155,16 +141,11 @@ static int arizona_haptics_play(struct input_dev *input, void *data,
static void arizona_haptics_close(struct input_dev *input) static void arizona_haptics_close(struct input_dev *input)
{ {
struct arizona_haptics *haptics = input_get_drvdata(input); struct arizona_haptics *haptics = input_get_drvdata(input);
struct mutex *dapm_mutex = &haptics->arizona->dapm->card->dapm_mutex;
cancel_work_sync(&haptics->work); cancel_work_sync(&haptics->work);
mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
if (haptics->arizona->dapm) if (haptics->arizona->dapm)
snd_soc_dapm_disable_pin(haptics->arizona->dapm, "HAPTICS"); snd_soc_dapm_disable_pin(haptics->arizona->dapm, "HAPTICS");
mutex_unlock(dapm_mutex);
} }
static int arizona_haptics_probe(struct platform_device *pdev) static int arizona_haptics_probe(struct platform_device *pdev)
......
...@@ -449,14 +449,22 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm, ...@@ -449,14 +449,22 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
/* dapm audio pin control and status */ /* dapm audio pin control and status */
int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm,
const char *pin); const char *pin);
int snd_soc_dapm_enable_pin_unlocked(struct snd_soc_dapm_context *dapm,
const char *pin);
int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm,
const char *pin); const char *pin);
int snd_soc_dapm_disable_pin_unlocked(struct snd_soc_dapm_context *dapm,
const char *pin);
int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin); int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin);
int snd_soc_dapm_nc_pin_unlocked(struct snd_soc_dapm_context *dapm,
const char *pin);
int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm, int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm,
const char *pin); const char *pin);
int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm); int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm);
int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
const char *pin); const char *pin);
int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm,
const char *pin);
int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
const char *pin); const char *pin);
void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec); void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec);
......
...@@ -57,8 +57,8 @@ static const u16 ad1980_reg[] = { ...@@ -57,8 +57,8 @@ static const u16 ad1980_reg[] = {
static const char *ad1980_rec_sel[] = {"Mic", "CD", "NC", "AUX", "Line", static const char *ad1980_rec_sel[] = {"Mic", "CD", "NC", "AUX", "Line",
"Stereo Mix", "Mono Mix", "Phone"}; "Stereo Mix", "Mono Mix", "Phone"};
static const struct soc_enum ad1980_cap_src = static SOC_ENUM_DOUBLE_DECL(ad1980_cap_src,
SOC_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 7, ad1980_rec_sel); AC97_REC_SEL, 8, 0, ad1980_rec_sel);
static const struct snd_kcontrol_new ad1980_snd_ac97_controls[] = { static const struct snd_kcontrol_new ad1980_snd_ac97_controls[] = {
SOC_DOUBLE("Master Playback Volume", AC97_MASTER, 8, 0, 31, 1), SOC_DOUBLE("Master Playback Volume", AC97_MASTER, 8, 0, 31, 1),
......
...@@ -140,13 +140,17 @@ static const char *isabelle_rx1_texts[] = {"VRX1", "ARX1"}; ...@@ -140,13 +140,17 @@ static const char *isabelle_rx1_texts[] = {"VRX1", "ARX1"};
static const char *isabelle_rx2_texts[] = {"VRX2", "ARX2"}; static const char *isabelle_rx2_texts[] = {"VRX2", "ARX2"};
static const struct soc_enum isabelle_rx1_enum[] = { static const struct soc_enum isabelle_rx1_enum[] = {
SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 3, 1, isabelle_rx1_texts), SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 3,
SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 5, 1, isabelle_rx1_texts), ARRAY_SIZE(isabelle_rx1_texts), isabelle_rx1_texts),
SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 5,
ARRAY_SIZE(isabelle_rx1_texts), isabelle_rx1_texts),
}; };
static const struct soc_enum isabelle_rx2_enum[] = { static const struct soc_enum isabelle_rx2_enum[] = {
SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 2, 1, isabelle_rx2_texts), SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 2,
SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 4, 1, isabelle_rx2_texts), ARRAY_SIZE(isabelle_rx2_texts), isabelle_rx2_texts),
SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 4,
ARRAY_SIZE(isabelle_rx2_texts), isabelle_rx2_texts),
}; };
/* Headset DAC playback switches */ /* Headset DAC playback switches */
...@@ -161,13 +165,17 @@ static const char *isabelle_atx_texts[] = {"AMIC1", "DMIC"}; ...@@ -161,13 +165,17 @@ static const char *isabelle_atx_texts[] = {"AMIC1", "DMIC"};
static const char *isabelle_vtx_texts[] = {"AMIC2", "DMIC"}; static const char *isabelle_vtx_texts[] = {"AMIC2", "DMIC"};
static const struct soc_enum isabelle_atx_enum[] = { static const struct soc_enum isabelle_atx_enum[] = {
SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 7, 1, isabelle_atx_texts), SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 7,
SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_atx_texts), ARRAY_SIZE(isabelle_atx_texts), isabelle_atx_texts),
SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0,
ARRAY_SIZE(isabelle_atx_texts), isabelle_atx_texts),
}; };
static const struct soc_enum isabelle_vtx_enum[] = { static const struct soc_enum isabelle_vtx_enum[] = {
SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 6, 1, isabelle_vtx_texts), SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 6,
SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_vtx_texts), ARRAY_SIZE(isabelle_vtx_texts), isabelle_vtx_texts),
SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0,
ARRAY_SIZE(isabelle_vtx_texts), isabelle_vtx_texts),
}; };
static const struct snd_kcontrol_new atx_mux_controls = static const struct snd_kcontrol_new atx_mux_controls =
...@@ -183,17 +191,13 @@ static const char *isabelle_amic1_texts[] = { ...@@ -183,17 +191,13 @@ static const char *isabelle_amic1_texts[] = {
/* Left analog microphone selection */ /* Left analog microphone selection */
static const char *isabelle_amic2_texts[] = {"Sub Mic", "Aux/FM Right"}; static const char *isabelle_amic2_texts[] = {"Sub Mic", "Aux/FM Right"};
static const struct soc_enum isabelle_amic1_enum[] = { static SOC_ENUM_SINGLE_DECL(isabelle_amic1_enum,
SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 5, ISABELLE_AMIC_CFG_REG, 5,
ARRAY_SIZE(isabelle_amic1_texts), isabelle_amic1_texts);
isabelle_amic1_texts),
};
static const struct soc_enum isabelle_amic2_enum[] = { static SOC_ENUM_SINGLE_DECL(isabelle_amic2_enum,
SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 4, ISABELLE_AMIC_CFG_REG, 4,
ARRAY_SIZE(isabelle_amic2_texts), isabelle_amic2_texts);
isabelle_amic2_texts),
};
static const struct snd_kcontrol_new amic1_control = static const struct snd_kcontrol_new amic1_control =
SOC_DAPM_ENUM("Route", isabelle_amic1_enum); SOC_DAPM_ENUM("Route", isabelle_amic1_enum);
...@@ -206,16 +210,20 @@ static const char *isabelle_st_audio_texts[] = {"ATX1", "ATX2"}; ...@@ -206,16 +210,20 @@ static const char *isabelle_st_audio_texts[] = {"ATX1", "ATX2"};
static const char *isabelle_st_voice_texts[] = {"VTX1", "VTX2"}; static const char *isabelle_st_voice_texts[] = {"VTX1", "VTX2"};
static const struct soc_enum isabelle_st_audio_enum[] = { static const struct soc_enum isabelle_st_audio_enum[] = {
SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA1_CFG_REG, 7, 1, SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA1_CFG_REG, 7,
ARRAY_SIZE(isabelle_st_audio_texts),
isabelle_st_audio_texts), isabelle_st_audio_texts),
SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA2_CFG_REG, 7, 1, SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA2_CFG_REG, 7,
ARRAY_SIZE(isabelle_st_audio_texts),
isabelle_st_audio_texts), isabelle_st_audio_texts),
}; };
static const struct soc_enum isabelle_st_voice_enum[] = { static const struct soc_enum isabelle_st_voice_enum[] = {
SOC_ENUM_SINGLE(ISABELLE_VTX_STPGA1_CFG_REG, 7, 1, SOC_ENUM_SINGLE(ISABELLE_VTX_STPGA1_CFG_REG, 7,
ARRAY_SIZE(isabelle_st_voice_texts),
isabelle_st_voice_texts), isabelle_st_voice_texts),
SOC_ENUM_SINGLE(ISABELLE_VTX2_STPGA2_CFG_REG, 7, 1, SOC_ENUM_SINGLE(ISABELLE_VTX2_STPGA2_CFG_REG, 7,
ARRAY_SIZE(isabelle_st_voice_texts),
isabelle_st_voice_texts), isabelle_st_voice_texts),
}; };
......
...@@ -187,42 +187,42 @@ static const unsigned int sta32x_limiter_drc_release_tlv[] = { ...@@ -187,42 +187,42 @@ static const unsigned int sta32x_limiter_drc_release_tlv[] = {
13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0), 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0),
}; };
static const struct soc_enum sta32x_drc_ac_enum = static SOC_ENUM_SINGLE_DECL(sta32x_drc_ac_enum,
SOC_ENUM_SINGLE(STA32X_CONFD, STA32X_CONFD_DRC_SHIFT, STA32X_CONFD, STA32X_CONFD_DRC_SHIFT,
2, sta32x_drc_ac); sta32x_drc_ac);
static const struct soc_enum sta32x_auto_eq_enum = static SOC_ENUM_SINGLE_DECL(sta32x_auto_eq_enum,
SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT, STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT,
3, sta32x_auto_eq_mode); sta32x_auto_eq_mode);
static const struct soc_enum sta32x_auto_gc_enum = static SOC_ENUM_SINGLE_DECL(sta32x_auto_gc_enum,
SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT, STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT,
4, sta32x_auto_gc_mode); sta32x_auto_gc_mode);
static const struct soc_enum sta32x_auto_xo_enum = static SOC_ENUM_SINGLE_DECL(sta32x_auto_xo_enum,
SOC_ENUM_SINGLE(STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT, STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT,
16, sta32x_auto_xo_mode); sta32x_auto_xo_mode);
static const struct soc_enum sta32x_preset_eq_enum = static SOC_ENUM_SINGLE_DECL(sta32x_preset_eq_enum,
SOC_ENUM_SINGLE(STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT, STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT,
32, sta32x_preset_eq_mode); sta32x_preset_eq_mode);
static const struct soc_enum sta32x_limiter_ch1_enum = static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch1_enum,
SOC_ENUM_SINGLE(STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT, STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT,
3, sta32x_limiter_select); sta32x_limiter_select);
static const struct soc_enum sta32x_limiter_ch2_enum = static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch2_enum,
SOC_ENUM_SINGLE(STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT, STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT,
3, sta32x_limiter_select); sta32x_limiter_select);
static const struct soc_enum sta32x_limiter_ch3_enum = static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch3_enum,
SOC_ENUM_SINGLE(STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT, STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT,
3, sta32x_limiter_select); sta32x_limiter_select);
static const struct soc_enum sta32x_limiter1_attack_rate_enum = static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_attack_rate_enum,
SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxA_SHIFT, STA32X_L1AR, STA32X_LxA_SHIFT,
16, sta32x_limiter_attack_rate); sta32x_limiter_attack_rate);
static const struct soc_enum sta32x_limiter2_attack_rate_enum = static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_attack_rate_enum,
SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxA_SHIFT, STA32X_L2AR, STA32X_LxA_SHIFT,
16, sta32x_limiter_attack_rate); sta32x_limiter_attack_rate);
static const struct soc_enum sta32x_limiter1_release_rate_enum = static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_release_rate_enum,
SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxR_SHIFT, STA32X_L1AR, STA32X_LxR_SHIFT,
16, sta32x_limiter_release_rate); sta32x_limiter_release_rate);
static const struct soc_enum sta32x_limiter2_release_rate_enum = static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_release_rate_enum,
SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxR_SHIFT, STA32X_L2AR, STA32X_LxR_SHIFT,
16, sta32x_limiter_release_rate); sta32x_limiter_release_rate);
/* byte array controls for setting biquad, mixer, scaling coefficients; /* byte array controls for setting biquad, mixer, scaling coefficients;
* for biquads all five coefficients need to be set in one go, * for biquads all five coefficients need to be set in one go,
...@@ -331,7 +331,7 @@ static int sta32x_sync_coef_shadow(struct snd_soc_codec *codec) ...@@ -331,7 +331,7 @@ static int sta32x_sync_coef_shadow(struct snd_soc_codec *codec)
static int sta32x_cache_sync(struct snd_soc_codec *codec) static int sta32x_cache_sync(struct snd_soc_codec *codec)
{ {
struct sta32x_priv *sta32x = codec->control_data; struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
unsigned int mute; unsigned int mute;
int rc; int rc;
......
...@@ -117,19 +117,23 @@ static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, ...@@ -117,19 +117,23 @@ static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
static const char *wm8400_digital_sidetone[] = static const char *wm8400_digital_sidetone[] =
{"None", "Left ADC", "Right ADC", "Reserved"}; {"None", "Left ADC", "Right ADC", "Reserved"};
static const struct soc_enum wm8400_left_digital_sidetone_enum = static SOC_ENUM_SINGLE_DECL(wm8400_left_digital_sidetone_enum,
SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE, WM8400_DIGITAL_SIDE_TONE,
WM8400_ADC_TO_DACL_SHIFT, 2, wm8400_digital_sidetone); WM8400_ADC_TO_DACL_SHIFT,
wm8400_digital_sidetone);
static const struct soc_enum wm8400_right_digital_sidetone_enum = static SOC_ENUM_SINGLE_DECL(wm8400_right_digital_sidetone_enum,
SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE, WM8400_DIGITAL_SIDE_TONE,
WM8400_ADC_TO_DACR_SHIFT, 2, wm8400_digital_sidetone); WM8400_ADC_TO_DACR_SHIFT,
wm8400_digital_sidetone);
static const char *wm8400_adcmode[] = static const char *wm8400_adcmode[] =
{"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"}; {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"};
static const struct soc_enum wm8400_right_adcmode_enum = static SOC_ENUM_SINGLE_DECL(wm8400_right_adcmode_enum,
SOC_ENUM_SINGLE(WM8400_ADC_CTRL, WM8400_ADC_HPF_CUT_SHIFT, 3, wm8400_adcmode); WM8400_ADC_CTRL,
WM8400_ADC_HPF_CUT_SHIFT,
wm8400_adcmode);
static const struct snd_kcontrol_new wm8400_snd_controls[] = { static const struct snd_kcontrol_new wm8400_snd_controls[] = {
/* INMIXL */ /* INMIXL */
...@@ -422,9 +426,10 @@ SOC_DAPM_SINGLE("RINPGA34 Switch", WM8400_INPUT_MIXER3, WM8400_L34MNB_SHIFT, ...@@ -422,9 +426,10 @@ SOC_DAPM_SINGLE("RINPGA34 Switch", WM8400_INPUT_MIXER3, WM8400_L34MNB_SHIFT,
static const char *wm8400_ainlmux[] = static const char *wm8400_ainlmux[] =
{"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"}; {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"};
static const struct soc_enum wm8400_ainlmux_enum = static SOC_ENUM_SINGLE_DECL(wm8400_ainlmux_enum,
SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINLMODE_SHIFT, WM8400_INPUT_MIXER1,
ARRAY_SIZE(wm8400_ainlmux), wm8400_ainlmux); WM8400_AINLMODE_SHIFT,
wm8400_ainlmux);
static const struct snd_kcontrol_new wm8400_dapm_ainlmux_controls = static const struct snd_kcontrol_new wm8400_dapm_ainlmux_controls =
SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum); SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum);
...@@ -435,9 +440,10 @@ SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum); ...@@ -435,9 +440,10 @@ SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum);
static const char *wm8400_ainrmux[] = static const char *wm8400_ainrmux[] =
{"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"}; {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"};
static const struct soc_enum wm8400_ainrmux_enum = static SOC_ENUM_SINGLE_DECL(wm8400_ainrmux_enum,
SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINRMODE_SHIFT, WM8400_INPUT_MIXER1,
ARRAY_SIZE(wm8400_ainrmux), wm8400_ainrmux); WM8400_AINRMODE_SHIFT,
wm8400_ainrmux);
static const struct snd_kcontrol_new wm8400_dapm_ainrmux_controls = static const struct snd_kcontrol_new wm8400_dapm_ainrmux_controls =
SOC_DAPM_ENUM("Route", wm8400_ainrmux_enum); SOC_DAPM_ENUM("Route", wm8400_ainrmux_enum);
......
...@@ -196,8 +196,8 @@ static const char *ain_text[] = { ...@@ -196,8 +196,8 @@ static const char *ain_text[] = {
"AIN5", "AIN6", "AIN7", "AIN8" "AIN5", "AIN6", "AIN7", "AIN8"
}; };
static const struct soc_enum ain_enum = static SOC_ENUM_DOUBLE_DECL(ain_enum,
SOC_ENUM_DOUBLE(WM8770_ADCMUX, 0, 4, 8, ain_text); WM8770_ADCMUX, 0, 4, ain_text);
static const struct snd_kcontrol_new ain_mux = static const struct snd_kcontrol_new ain_mux =
SOC_DAPM_ENUM("Capture Mux", ain_enum); SOC_DAPM_ENUM("Capture Mux", ain_enum);
......
...@@ -304,53 +304,53 @@ static const DECLARE_TLV_DB_SCALE(adc_tlv, -7200, 75, 1); ...@@ -304,53 +304,53 @@ static const DECLARE_TLV_DB_SCALE(adc_tlv, -7200, 75, 1);
static const char *mic_bias_level_txt[] = { "0.9*AVDD", "0.65*AVDD" }; static const char *mic_bias_level_txt[] = { "0.9*AVDD", "0.65*AVDD" };
static const struct soc_enum mic_bias_level = static SOC_ENUM_SINGLE_DECL(mic_bias_level,
SOC_ENUM_SINGLE(WM8900_REG_INCTL, 8, 2, mic_bias_level_txt); WM8900_REG_INCTL, 8, mic_bias_level_txt);
static const char *dac_mute_rate_txt[] = { "Fast", "Slow" }; static const char *dac_mute_rate_txt[] = { "Fast", "Slow" };
static const struct soc_enum dac_mute_rate = static SOC_ENUM_SINGLE_DECL(dac_mute_rate,
SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 7, 2, dac_mute_rate_txt); WM8900_REG_DACCTRL, 7, dac_mute_rate_txt);
static const char *dac_deemphasis_txt[] = { static const char *dac_deemphasis_txt[] = {
"Disabled", "32kHz", "44.1kHz", "48kHz" "Disabled", "32kHz", "44.1kHz", "48kHz"
}; };
static const struct soc_enum dac_deemphasis = static SOC_ENUM_SINGLE_DECL(dac_deemphasis,
SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 4, 4, dac_deemphasis_txt); WM8900_REG_DACCTRL, 4, dac_deemphasis_txt);
static const char *adc_hpf_cut_txt[] = { static const char *adc_hpf_cut_txt[] = {
"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3" "Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"
}; };
static const struct soc_enum adc_hpf_cut = static SOC_ENUM_SINGLE_DECL(adc_hpf_cut,
SOC_ENUM_SINGLE(WM8900_REG_ADCCTRL, 5, 4, adc_hpf_cut_txt); WM8900_REG_ADCCTRL, 5, adc_hpf_cut_txt);
static const char *lr_txt[] = { static const char *lr_txt[] = {
"Left", "Right" "Left", "Right"
}; };
static const struct soc_enum aifl_src = static SOC_ENUM_SINGLE_DECL(aifl_src,
SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 15, 2, lr_txt); WM8900_REG_AUDIO1, 15, lr_txt);
static const struct soc_enum aifr_src = static SOC_ENUM_SINGLE_DECL(aifr_src,
SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 14, 2, lr_txt); WM8900_REG_AUDIO1, 14, lr_txt);
static const struct soc_enum dacl_src = static SOC_ENUM_SINGLE_DECL(dacl_src,
SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 15, 2, lr_txt); WM8900_REG_AUDIO2, 15, lr_txt);
static const struct soc_enum dacr_src = static SOC_ENUM_SINGLE_DECL(dacr_src,
SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 14, 2, lr_txt); WM8900_REG_AUDIO2, 14, lr_txt);
static const char *sidetone_txt[] = { static const char *sidetone_txt[] = {
"Disabled", "Left ADC", "Right ADC" "Disabled", "Left ADC", "Right ADC"
}; };
static const struct soc_enum dacl_sidetone = static SOC_ENUM_SINGLE_DECL(dacl_sidetone,
SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 2, 3, sidetone_txt); WM8900_REG_SIDETONE, 2, sidetone_txt);
static const struct soc_enum dacr_sidetone = static SOC_ENUM_SINGLE_DECL(dacr_sidetone,
SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 0, 3, sidetone_txt); WM8900_REG_SIDETONE, 0, sidetone_txt);
static const struct snd_kcontrol_new wm8900_snd_controls[] = { static const struct snd_kcontrol_new wm8900_snd_controls[] = {
SOC_ENUM("Mic Bias Level", mic_bias_level), SOC_ENUM("Mic Bias Level", mic_bias_level),
...@@ -496,8 +496,8 @@ SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INCTL, 0, 1, 0), ...@@ -496,8 +496,8 @@ SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INCTL, 0, 1, 0),
static const char *wm8900_lp_mux[] = { "Disabled", "Enabled" }; static const char *wm8900_lp_mux[] = { "Disabled", "Enabled" };
static const struct soc_enum wm8900_lineout2_lp_mux = static SOC_ENUM_SINGLE_DECL(wm8900_lineout2_lp_mux,
SOC_ENUM_SINGLE(WM8900_REG_LOUTMIXCTL1, 1, 2, wm8900_lp_mux); WM8900_REG_LOUTMIXCTL1, 1, wm8900_lp_mux);
static const struct snd_kcontrol_new wm8900_lineout2_lp = static const struct snd_kcontrol_new wm8900_lineout2_lp =
SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux); SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux);
......
...@@ -265,21 +265,21 @@ static const char *sidetone_hpf_text[] = { ...@@ -265,21 +265,21 @@ static const char *sidetone_hpf_text[] = {
"2.7kHz", "1.35kHz", "675Hz", "370Hz", "180Hz", "90Hz", "45Hz" "2.7kHz", "1.35kHz", "675Hz", "370Hz", "180Hz", "90Hz", "45Hz"
}; };
static const struct soc_enum sidetone_hpf = static SOC_ENUM_SINGLE_DECL(sidetone_hpf,
SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text); WM8994_SIDETONE, 7, sidetone_hpf_text);
static const char *adc_hpf_text[] = { static const char *adc_hpf_text[] = {
"HiFi", "Voice 1", "Voice 2", "Voice 3" "HiFi", "Voice 1", "Voice 2", "Voice 3"
}; };
static const struct soc_enum aif1adc1_hpf = static SOC_ENUM_SINGLE_DECL(aif1adc1_hpf,
SOC_ENUM_SINGLE(WM8994_AIF1_ADC1_FILTERS, 13, 4, adc_hpf_text); WM8994_AIF1_ADC1_FILTERS, 13, adc_hpf_text);
static const struct soc_enum aif1adc2_hpf = static SOC_ENUM_SINGLE_DECL(aif1adc2_hpf,
SOC_ENUM_SINGLE(WM8994_AIF1_ADC2_FILTERS, 13, 4, adc_hpf_text); WM8994_AIF1_ADC2_FILTERS, 13, adc_hpf_text);
static const struct soc_enum aif2adc_hpf = static SOC_ENUM_SINGLE_DECL(aif2adc_hpf,
SOC_ENUM_SINGLE(WM8994_AIF2_ADC_FILTERS, 13, 4, adc_hpf_text); WM8994_AIF2_ADC_FILTERS, 13, adc_hpf_text);
static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0); static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0);
static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
...@@ -501,39 +501,39 @@ static const char *aif_chan_src_text[] = { ...@@ -501,39 +501,39 @@ static const char *aif_chan_src_text[] = {
"Left", "Right" "Left", "Right"
}; };
static const struct soc_enum aif1adcl_src = static SOC_ENUM_SINGLE_DECL(aif1adcl_src,
SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 15, 2, aif_chan_src_text); WM8994_AIF1_CONTROL_1, 15, aif_chan_src_text);
static const struct soc_enum aif1adcr_src = static SOC_ENUM_SINGLE_DECL(aif1adcr_src,
SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 14, 2, aif_chan_src_text); WM8994_AIF1_CONTROL_1, 14, aif_chan_src_text);
static const struct soc_enum aif2adcl_src = static SOC_ENUM_SINGLE_DECL(aif2adcl_src,
SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 15, 2, aif_chan_src_text); WM8994_AIF2_CONTROL_1, 15, aif_chan_src_text);
static const struct soc_enum aif2adcr_src = static SOC_ENUM_SINGLE_DECL(aif2adcr_src,
SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 14, 2, aif_chan_src_text); WM8994_AIF2_CONTROL_1, 14, aif_chan_src_text);
static const struct soc_enum aif1dacl_src = static SOC_ENUM_SINGLE_DECL(aif1dacl_src,
SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 15, 2, aif_chan_src_text); WM8994_AIF1_CONTROL_2, 15, aif_chan_src_text);
static const struct soc_enum aif1dacr_src = static SOC_ENUM_SINGLE_DECL(aif1dacr_src,
SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 14, 2, aif_chan_src_text); WM8994_AIF1_CONTROL_2, 14, aif_chan_src_text);
static const struct soc_enum aif2dacl_src = static SOC_ENUM_SINGLE_DECL(aif2dacl_src,
SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 15, 2, aif_chan_src_text); WM8994_AIF2_CONTROL_2, 15, aif_chan_src_text);
static const struct soc_enum aif2dacr_src = static SOC_ENUM_SINGLE_DECL(aif2dacr_src,
SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aif_chan_src_text); WM8994_AIF2_CONTROL_2, 14, aif_chan_src_text);
static const char *osr_text[] = { static const char *osr_text[] = {
"Low Power", "High Performance", "Low Power", "High Performance",
}; };
static const struct soc_enum dac_osr = static SOC_ENUM_SINGLE_DECL(dac_osr,
SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 0, 2, osr_text); WM8994_OVERSAMPLING, 0, osr_text);
static const struct soc_enum adc_osr = static SOC_ENUM_SINGLE_DECL(adc_osr,
SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text); WM8994_OVERSAMPLING, 1, osr_text);
static const struct snd_kcontrol_new wm8994_snd_controls[] = { static const struct snd_kcontrol_new wm8994_snd_controls[] = {
SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME,
...@@ -690,17 +690,20 @@ static const char *wm8958_ng_text[] = { ...@@ -690,17 +690,20 @@ static const char *wm8958_ng_text[] = {
"30ms", "125ms", "250ms", "500ms", "30ms", "125ms", "250ms", "500ms",
}; };
static const struct soc_enum wm8958_aif1dac1_ng_hold = static SOC_ENUM_SINGLE_DECL(wm8958_aif1dac1_ng_hold,
SOC_ENUM_SINGLE(WM8958_AIF1_DAC1_NOISE_GATE, WM8958_AIF1_DAC1_NOISE_GATE,
WM8958_AIF1DAC1_NG_THR_SHIFT, 4, wm8958_ng_text); WM8958_AIF1DAC1_NG_THR_SHIFT,
wm8958_ng_text);
static const struct soc_enum wm8958_aif1dac2_ng_hold = static SOC_ENUM_SINGLE_DECL(wm8958_aif1dac2_ng_hold,
SOC_ENUM_SINGLE(WM8958_AIF1_DAC2_NOISE_GATE, WM8958_AIF1_DAC2_NOISE_GATE,
WM8958_AIF1DAC2_NG_THR_SHIFT, 4, wm8958_ng_text); WM8958_AIF1DAC2_NG_THR_SHIFT,
wm8958_ng_text);
static const struct soc_enum wm8958_aif2dac_ng_hold = static SOC_ENUM_SINGLE_DECL(wm8958_aif2dac_ng_hold,
SOC_ENUM_SINGLE(WM8958_AIF2_DAC_NOISE_GATE, WM8958_AIF2_DAC_NOISE_GATE,
WM8958_AIF2DAC_NG_THR_SHIFT, 4, wm8958_ng_text); WM8958_AIF2DAC_NG_THR_SHIFT,
wm8958_ng_text);
static const struct snd_kcontrol_new wm8958_snd_controls[] = { static const struct snd_kcontrol_new wm8958_snd_controls[] = {
SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv), SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv),
...@@ -1341,8 +1344,8 @@ static const char *adc_mux_text[] = { ...@@ -1341,8 +1344,8 @@ static const char *adc_mux_text[] = {
"DMIC", "DMIC",
}; };
static const struct soc_enum adc_enum = static SOC_ENUM_SINGLE_DECL(adc_enum,
SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text); 0, 0, adc_mux_text);
static const struct snd_kcontrol_new adcl_mux = static const struct snd_kcontrol_new adcl_mux =
SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum);
...@@ -1478,14 +1481,14 @@ static const char *sidetone_text[] = { ...@@ -1478,14 +1481,14 @@ static const char *sidetone_text[] = {
"ADC/DMIC1", "DMIC2", "ADC/DMIC1", "DMIC2",
}; };
static const struct soc_enum sidetone1_enum = static SOC_ENUM_SINGLE_DECL(sidetone1_enum,
SOC_ENUM_SINGLE(WM8994_SIDETONE, 0, 2, sidetone_text); WM8994_SIDETONE, 0, sidetone_text);
static const struct snd_kcontrol_new sidetone1_mux = static const struct snd_kcontrol_new sidetone1_mux =
SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum); SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum);
static const struct soc_enum sidetone2_enum = static SOC_ENUM_SINGLE_DECL(sidetone2_enum,
SOC_ENUM_SINGLE(WM8994_SIDETONE, 1, 2, sidetone_text); WM8994_SIDETONE, 1, sidetone_text);
static const struct snd_kcontrol_new sidetone2_mux = static const struct snd_kcontrol_new sidetone2_mux =
SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum); SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum);
...@@ -1498,22 +1501,24 @@ static const char *loopback_text[] = { ...@@ -1498,22 +1501,24 @@ static const char *loopback_text[] = {
"None", "ADCDAT", "None", "ADCDAT",
}; };
static const struct soc_enum aif1_loopback_enum = static SOC_ENUM_SINGLE_DECL(aif1_loopback_enum,
SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, WM8994_AIF1_LOOPBACK_SHIFT, 2, WM8994_AIF1_CONTROL_2,
WM8994_AIF1_LOOPBACK_SHIFT,
loopback_text); loopback_text);
static const struct snd_kcontrol_new aif1_loopback = static const struct snd_kcontrol_new aif1_loopback =
SOC_DAPM_ENUM("AIF1 Loopback", aif1_loopback_enum); SOC_DAPM_ENUM("AIF1 Loopback", aif1_loopback_enum);
static const struct soc_enum aif2_loopback_enum = static SOC_ENUM_SINGLE_DECL(aif2_loopback_enum,
SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, WM8994_AIF2_LOOPBACK_SHIFT, 2, WM8994_AIF2_CONTROL_2,
WM8994_AIF2_LOOPBACK_SHIFT,
loopback_text); loopback_text);
static const struct snd_kcontrol_new aif2_loopback = static const struct snd_kcontrol_new aif2_loopback =
SOC_DAPM_ENUM("AIF2 Loopback", aif2_loopback_enum); SOC_DAPM_ENUM("AIF2 Loopback", aif2_loopback_enum);
static const struct soc_enum aif1dac_enum = static SOC_ENUM_SINGLE_DECL(aif1dac_enum,
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 0, 2, aif1dac_text); WM8994_POWER_MANAGEMENT_6, 0, aif1dac_text);
static const struct snd_kcontrol_new aif1dac_mux = static const struct snd_kcontrol_new aif1dac_mux =
SOC_DAPM_ENUM("AIF1DAC Mux", aif1dac_enum); SOC_DAPM_ENUM("AIF1DAC Mux", aif1dac_enum);
...@@ -1522,8 +1527,8 @@ static const char *aif2dac_text[] = { ...@@ -1522,8 +1527,8 @@ static const char *aif2dac_text[] = {
"AIF2DACDAT", "AIF3DACDAT", "AIF2DACDAT", "AIF3DACDAT",
}; };
static const struct soc_enum aif2dac_enum = static SOC_ENUM_SINGLE_DECL(aif2dac_enum,
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 1, 2, aif2dac_text); WM8994_POWER_MANAGEMENT_6, 1, aif2dac_text);
static const struct snd_kcontrol_new aif2dac_mux = static const struct snd_kcontrol_new aif2dac_mux =
SOC_DAPM_ENUM("AIF2DAC Mux", aif2dac_enum); SOC_DAPM_ENUM("AIF2DAC Mux", aif2dac_enum);
...@@ -1532,8 +1537,8 @@ static const char *aif2adc_text[] = { ...@@ -1532,8 +1537,8 @@ static const char *aif2adc_text[] = {
"AIF2ADCDAT", "AIF3DACDAT", "AIF2ADCDAT", "AIF3DACDAT",
}; };
static const struct soc_enum aif2adc_enum = static SOC_ENUM_SINGLE_DECL(aif2adc_enum,
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 2, 2, aif2adc_text); WM8994_POWER_MANAGEMENT_6, 2, aif2adc_text);
static const struct snd_kcontrol_new aif2adc_mux = static const struct snd_kcontrol_new aif2adc_mux =
SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum); SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum);
...@@ -1542,14 +1547,14 @@ static const char *aif3adc_text[] = { ...@@ -1542,14 +1547,14 @@ static const char *aif3adc_text[] = {
"AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", "Mono PCM", "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", "Mono PCM",
}; };
static const struct soc_enum wm8994_aif3adc_enum = static SOC_ENUM_SINGLE_DECL(wm8994_aif3adc_enum,
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text); WM8994_POWER_MANAGEMENT_6, 3, aif3adc_text);
static const struct snd_kcontrol_new wm8994_aif3adc_mux = static const struct snd_kcontrol_new wm8994_aif3adc_mux =
SOC_DAPM_ENUM("AIF3ADC Mux", wm8994_aif3adc_enum); SOC_DAPM_ENUM("AIF3ADC Mux", wm8994_aif3adc_enum);
static const struct soc_enum wm8958_aif3adc_enum = static SOC_ENUM_SINGLE_DECL(wm8958_aif3adc_enum,
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 4, aif3adc_text); WM8994_POWER_MANAGEMENT_6, 3, aif3adc_text);
static const struct snd_kcontrol_new wm8958_aif3adc_mux = static const struct snd_kcontrol_new wm8958_aif3adc_mux =
SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum); SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum);
...@@ -1558,8 +1563,8 @@ static const char *mono_pcm_out_text[] = { ...@@ -1558,8 +1563,8 @@ static const char *mono_pcm_out_text[] = {
"None", "AIF2ADCL", "AIF2ADCR", "None", "AIF2ADCL", "AIF2ADCR",
}; };
static const struct soc_enum mono_pcm_out_enum = static SOC_ENUM_SINGLE_DECL(mono_pcm_out_enum,
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 9, 3, mono_pcm_out_text); WM8994_POWER_MANAGEMENT_6, 9, mono_pcm_out_text);
static const struct snd_kcontrol_new mono_pcm_out_mux = static const struct snd_kcontrol_new mono_pcm_out_mux =
SOC_DAPM_ENUM("Mono PCM Out Mux", mono_pcm_out_enum); SOC_DAPM_ENUM("Mono PCM Out Mux", mono_pcm_out_enum);
...@@ -1569,14 +1574,14 @@ static const char *aif2dac_src_text[] = { ...@@ -1569,14 +1574,14 @@ static const char *aif2dac_src_text[] = {
}; };
/* Note that these two control shouldn't be simultaneously switched to AIF3 */ /* Note that these two control shouldn't be simultaneously switched to AIF3 */
static const struct soc_enum aif2dacl_src_enum = static SOC_ENUM_SINGLE_DECL(aif2dacl_src_enum,
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 7, 2, aif2dac_src_text); WM8994_POWER_MANAGEMENT_6, 7, aif2dac_src_text);
static const struct snd_kcontrol_new aif2dacl_src_mux = static const struct snd_kcontrol_new aif2dacl_src_mux =
SOC_DAPM_ENUM("AIF2DACL Mux", aif2dacl_src_enum); SOC_DAPM_ENUM("AIF2DACL Mux", aif2dacl_src_enum);
static const struct soc_enum aif2dacr_src_enum = static SOC_ENUM_SINGLE_DECL(aif2dacr_src_enum,
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 8, 2, aif2dac_src_text); WM8994_POWER_MANAGEMENT_6, 8, aif2dac_src_text);
static const struct snd_kcontrol_new aif2dacr_src_mux = static const struct snd_kcontrol_new aif2dacr_src_mux =
SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum); SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum);
......
...@@ -1218,7 +1218,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, ...@@ -1218,7 +1218,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
ret = regulator_allow_bypass(w->regulator, false); ret = regulator_allow_bypass(w->regulator, false);
if (ret != 0) if (ret != 0)
dev_warn(w->dapm->dev, dev_warn(w->dapm->dev,
"ASoC: Failed to bypass %s: %d\n", "ASoC: Failed to unbypass %s: %d\n",
w->name, ret); w->name, ret);
} }
...@@ -1228,7 +1228,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, ...@@ -1228,7 +1228,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
ret = regulator_allow_bypass(w->regulator, true); ret = regulator_allow_bypass(w->regulator, true);
if (ret != 0) if (ret != 0)
dev_warn(w->dapm->dev, dev_warn(w->dapm->dev,
"ASoC: Failed to unbypass %s: %d\n", "ASoC: Failed to bypass %s: %d\n",
w->name, ret); w->name, ret);
} }
...@@ -3210,15 +3210,11 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, ...@@ -3210,15 +3210,11 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
const char *pin = (const char *)kcontrol->private_value; const char *pin = (const char *)kcontrol->private_value;
mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
if (ucontrol->value.integer.value[0]) if (ucontrol->value.integer.value[0])
snd_soc_dapm_enable_pin(&card->dapm, pin); snd_soc_dapm_enable_pin(&card->dapm, pin);
else else
snd_soc_dapm_disable_pin(&card->dapm, pin); snd_soc_dapm_disable_pin(&card->dapm, pin);
mutex_unlock(&card->dapm_mutex);
snd_soc_dapm_sync(&card->dapm); snd_soc_dapm_sync(&card->dapm);
return 0; return 0;
} }
...@@ -3248,7 +3244,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, ...@@ -3248,7 +3244,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
ret = regulator_allow_bypass(w->regulator, true); ret = regulator_allow_bypass(w->regulator, true);
if (ret != 0) if (ret != 0)
dev_warn(w->dapm->dev, dev_warn(w->dapm->dev,
"ASoC: Failed to unbypass %s: %d\n", "ASoC: Failed to bypass %s: %d\n",
w->name, ret); w->name, ret);
} }
break; break;
...@@ -3766,6 +3762,26 @@ void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, ...@@ -3766,6 +3762,26 @@ void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
mutex_unlock(&card->dapm_mutex); mutex_unlock(&card->dapm_mutex);
} }
/**
* snd_soc_dapm_enable_pin_unlocked - enable pin.
* @dapm: DAPM context
* @pin: pin name
*
* Enables input/output pin and its parents or children widgets iff there is
* a valid audio route and active audio stream.
*
* Requires external locking.
*
* NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
* do any widget power switching.
*/
int snd_soc_dapm_enable_pin_unlocked(struct snd_soc_dapm_context *dapm,
const char *pin)
{
return snd_soc_dapm_set_pin(dapm, pin, 1);
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin_unlocked);
/** /**
* snd_soc_dapm_enable_pin - enable pin. * snd_soc_dapm_enable_pin - enable pin.
* @dapm: DAPM context * @dapm: DAPM context
...@@ -3773,17 +3789,26 @@ void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, ...@@ -3773,17 +3789,26 @@ void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
* *
* Enables input/output pin and its parents or children widgets iff there is * Enables input/output pin and its parents or children widgets iff there is
* a valid audio route and active audio stream. * a valid audio route and active audio stream.
*
* NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
* do any widget power switching. * do any widget power switching.
*/ */
int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin) int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin)
{ {
return snd_soc_dapm_set_pin(dapm, pin, 1); int ret;
mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
ret = snd_soc_dapm_set_pin(dapm, pin, 1);
mutex_unlock(&dapm->card->dapm_mutex);
return ret;
} }
EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
/** /**
* snd_soc_dapm_force_enable_pin - force a pin to be enabled * snd_soc_dapm_force_enable_pin_unlocked - force a pin to be enabled
* @dapm: DAPM context * @dapm: DAPM context
* @pin: pin name * @pin: pin name
* *
...@@ -3791,10 +3816,12 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); ...@@ -3791,10 +3816,12 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
* intended for use with microphone bias supplies used in microphone * intended for use with microphone bias supplies used in microphone
* jack detection. * jack detection.
* *
* Requires external locking.
*
* NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
* do any widget power switching. * do any widget power switching.
*/ */
int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm,
const char *pin) const char *pin)
{ {
struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
...@@ -3811,24 +3838,102 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, ...@@ -3811,24 +3838,102 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin_unlocked);
/**
* snd_soc_dapm_force_enable_pin - force a pin to be enabled
* @dapm: DAPM context
* @pin: pin name
*
* Enables input/output pin regardless of any other state. This is
* intended for use with microphone bias supplies used in microphone
* jack detection.
*
* NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
* do any widget power switching.
*/
int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
const char *pin)
{
int ret;
mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, pin);
mutex_unlock(&dapm->card->dapm_mutex);
return ret;
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin); EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin);
/**
* snd_soc_dapm_disable_pin_unlocked - disable pin.
* @dapm: DAPM context
* @pin: pin name
*
* Disables input/output pin and its parents or children widgets.
*
* Requires external locking.
*
* NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
* do any widget power switching.
*/
int snd_soc_dapm_disable_pin_unlocked(struct snd_soc_dapm_context *dapm,
const char *pin)
{
return snd_soc_dapm_set_pin(dapm, pin, 0);
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin_unlocked);
/** /**
* snd_soc_dapm_disable_pin - disable pin. * snd_soc_dapm_disable_pin - disable pin.
* @dapm: DAPM context * @dapm: DAPM context
* @pin: pin name * @pin: pin name
* *
* Disables input/output pin and its parents or children widgets. * Disables input/output pin and its parents or children widgets.
*
* NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
* do any widget power switching. * do any widget power switching.
*/ */
int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm,
const char *pin) const char *pin)
{ {
return snd_soc_dapm_set_pin(dapm, pin, 0); int ret;
mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
ret = snd_soc_dapm_set_pin(dapm, pin, 0);
mutex_unlock(&dapm->card->dapm_mutex);
return ret;
} }
EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
/**
* snd_soc_dapm_nc_pin_unlocked - permanently disable pin.
* @dapm: DAPM context
* @pin: pin name
*
* Marks the specified pin as being not connected, disabling it along
* any parent or child widgets. At present this is identical to
* snd_soc_dapm_disable_pin() but in future it will be extended to do
* additional things such as disabling controls which only affect
* paths through the pin.
*
* Requires external locking.
*
* NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
* do any widget power switching.
*/
int snd_soc_dapm_nc_pin_unlocked(struct snd_soc_dapm_context *dapm,
const char *pin)
{
return snd_soc_dapm_set_pin(dapm, pin, 0);
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin_unlocked);
/** /**
* snd_soc_dapm_nc_pin - permanently disable pin. * snd_soc_dapm_nc_pin - permanently disable pin.
* @dapm: DAPM context * @dapm: DAPM context
...@@ -3845,7 +3950,15 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); ...@@ -3845,7 +3950,15 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
*/ */
int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin) int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin)
{ {
return snd_soc_dapm_set_pin(dapm, pin, 0); int ret;
mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
ret = snd_soc_dapm_set_pin(dapm, pin, 0);
mutex_unlock(&dapm->card->dapm_mutex);
return ret;
} }
EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin); EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment