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.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJTCXkuAAoJELSic+t+oim99LEP/3o0MTeminJkA0ks+edRN32I
 zlbPd1iv38Rh20J85zJ8lHhZlkDVPpwYVEDziCClfG3QbWiwh18HEreOhi5xswxi
 qSIk+4chXvBpdWaopLq+MEZSEqFLaHDeWPifzNs8tjQ2F8+RPZ5aOtmeBrwFQZVR
 fJmuJ8KnOvjcH8WGNKIepZENqNIU7NuwMmzB7mHwyANKuan30u9Vx5r7OZBEkA1h
 n6vNa48i2HKrdFwajm7Y/o8s5Qrnseiz6NepaO4hTHQhlFhsU9mjCeYvmzhvc1Jv
 NAC3x2yUIrff95IwzMQi/jwJHJN+VXIqvsp1MWNm4rOucZ5kxw+dtFmmXtvsedI1
 HO1gWPqvsYENs5L4cGbi1An/T7vSWOjsbs/2QwRRqduRHVJxnnoADswoQG2AGhOy
 z1uJsebt72eAsoCxrPmaysa4irNwkDLwpFEjTpEGpgWo3j5d+UfEUScc/1B3ia7g
 a/Oq9q/Q71ogdKSrMpYc66eK7y1XGF2XZNl4x3g/ZwswibM4aIwBr6ZekpoPPOYq
 KT3zEecKJ+lbPxl2rUQgm9ivAuC1XKJoBRLRgHXGtzZI54SFUkFD/dVL6GFfR6bS
 V8RHeGqOmoD/w6WpfXC4w9yhfNhJPbOKOaSFUdCyU5D2bgb7AOcwZOXRavXtJwJP
 //gsmzui+ikt4scli8a/
 =Ty2j
 -----END PGP SIGNATURE-----

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.
This commit is contained in:
Takashi Iwai 2014-02-27 07:16:15 +01:00
Родитель fce0a0c726 57374bb491
Коммит e2755cf9a4
11 изменённых файлов: 324 добавлений и 215 удалений

Просмотреть файл

@ -222,27 +222,19 @@ static void arizona_extcon_pulse_micbias(struct arizona_extcon_info *info)
struct snd_soc_dapm_context *dapm = arizona->dapm;
int ret;
mutex_lock(&dapm->card->dapm_mutex);
ret = snd_soc_dapm_force_enable_pin(dapm, widget);
if (ret != 0)
dev_warn(arizona->dev, "Failed to enable %s: %d\n",
widget, ret);
mutex_unlock(&dapm->card->dapm_mutex);
snd_soc_dapm_sync(dapm);
if (!arizona->pdata.micd_force_micbias) {
mutex_lock(&dapm->card->dapm_mutex);
ret = snd_soc_dapm_disable_pin(arizona->dapm, widget);
if (ret != 0)
dev_warn(arizona->dev, "Failed to disable %s: %d\n",
widget, ret);
mutex_unlock(&dapm->card->dapm_mutex);
snd_soc_dapm_sync(dapm);
}
}
@ -304,16 +296,12 @@ static void arizona_stop_mic(struct arizona_extcon_info *info)
ARIZONA_MICD_ENA, 0,
&change);
mutex_lock(&dapm->card->dapm_mutex);
ret = snd_soc_dapm_disable_pin(dapm, widget);
if (ret != 0)
dev_warn(arizona->dev,
"Failed to disable %s: %d\n",
widget, ret);
mutex_unlock(&dapm->card->dapm_mutex);
snd_soc_dapm_sync(dapm);
if (info->micd_reva) {

Просмотреть файл

@ -37,7 +37,6 @@ static void arizona_haptics_work(struct work_struct *work)
struct arizona_haptics,
work);
struct arizona *arizona = haptics->arizona;
struct mutex *dapm_mutex = &arizona->dapm->card->dapm_mutex;
int ret;
if (!haptics->arizona->dapm) {
@ -67,13 +66,10 @@ static void arizona_haptics_work(struct work_struct *work)
return;
}
mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
ret = snd_soc_dapm_enable_pin(arizona->dapm, "HAPTICS");
if (ret != 0) {
dev_err(arizona->dev, "Failed to start HAPTICS: %d\n",
ret);
mutex_unlock(dapm_mutex);
return;
}
@ -81,21 +77,14 @@ static void arizona_haptics_work(struct work_struct *work)
if (ret != 0) {
dev_err(arizona->dev, "Failed to sync DAPM: %d\n",
ret);
mutex_unlock(dapm_mutex);
return;
}
mutex_unlock(dapm_mutex);
} else {
/* 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");
if (ret != 0) {
dev_err(arizona->dev, "Failed to disable HAPTICS: %d\n",
ret);
mutex_unlock(dapm_mutex);
return;
}
@ -103,12 +92,9 @@ static void arizona_haptics_work(struct work_struct *work)
if (ret != 0) {
dev_err(arizona->dev, "Failed to sync DAPM: %d\n",
ret);
mutex_unlock(dapm_mutex);
return;
}
mutex_unlock(dapm_mutex);
ret = regmap_update_bits(arizona->regmap,
ARIZONA_HAPTICS_CONTROL_1,
ARIZONA_HAP_CTRL_MASK,
@ -155,16 +141,11 @@ static int arizona_haptics_play(struct input_dev *input, void *data,
static void arizona_haptics_close(struct input_dev *input)
{
struct arizona_haptics *haptics = input_get_drvdata(input);
struct mutex *dapm_mutex = &haptics->arizona->dapm->card->dapm_mutex;
cancel_work_sync(&haptics->work);
mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
if (haptics->arizona->dapm)
snd_soc_dapm_disable_pin(haptics->arizona->dapm, "HAPTICS");
mutex_unlock(dapm_mutex);
}
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,
/* dapm audio pin control and status */
int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm,
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,
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_unlocked(struct snd_soc_dapm_context *dapm,
const char *pin);
int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm,
const char *pin);
int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm);
int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
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,
const char *pin);
void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec);

Просмотреть файл

@ -57,8 +57,8 @@ static const u16 ad1980_reg[] = {
static const char *ad1980_rec_sel[] = {"Mic", "CD", "NC", "AUX", "Line",
"Stereo Mix", "Mono Mix", "Phone"};
static const struct soc_enum ad1980_cap_src =
SOC_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 7, ad1980_rec_sel);
static SOC_ENUM_DOUBLE_DECL(ad1980_cap_src,
AC97_REC_SEL, 8, 0, ad1980_rec_sel);
static const struct snd_kcontrol_new ad1980_snd_ac97_controls[] = {
SOC_DOUBLE("Master Playback Volume", AC97_MASTER, 8, 0, 31, 1),

Просмотреть файл

@ -140,13 +140,17 @@ static const char *isabelle_rx1_texts[] = {"VRX1", "ARX1"};
static const char *isabelle_rx2_texts[] = {"VRX2", "ARX2"};
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_AUDIO_HPF_CFG_REG, 5, 1, isabelle_rx1_texts),
SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 3,
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[] = {
SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 2, 1, isabelle_rx2_texts),
SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 4, 1, isabelle_rx2_texts),
SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 2,
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 */
@ -161,13 +165,17 @@ static const char *isabelle_atx_texts[] = {"AMIC1", "DMIC"};
static const char *isabelle_vtx_texts[] = {"AMIC2", "DMIC"};
static const struct soc_enum isabelle_atx_enum[] = {
SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 7, 1, isabelle_atx_texts),
SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_atx_texts),
SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 7,
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[] = {
SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 6, 1, isabelle_vtx_texts),
SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_vtx_texts),
SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 6,
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 =
@ -183,17 +191,13 @@ static const char *isabelle_amic1_texts[] = {
/* Left analog microphone selection */
static const char *isabelle_amic2_texts[] = {"Sub Mic", "Aux/FM Right"};
static const struct soc_enum isabelle_amic1_enum[] = {
SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 5,
ARRAY_SIZE(isabelle_amic1_texts),
isabelle_amic1_texts),
};
static SOC_ENUM_SINGLE_DECL(isabelle_amic1_enum,
ISABELLE_AMIC_CFG_REG, 5,
isabelle_amic1_texts);
static const struct soc_enum isabelle_amic2_enum[] = {
SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 4,
ARRAY_SIZE(isabelle_amic2_texts),
isabelle_amic2_texts),
};
static SOC_ENUM_SINGLE_DECL(isabelle_amic2_enum,
ISABELLE_AMIC_CFG_REG, 4,
isabelle_amic2_texts);
static const struct snd_kcontrol_new amic1_control =
SOC_DAPM_ENUM("Route", isabelle_amic1_enum);
@ -206,16 +210,20 @@ static const char *isabelle_st_audio_texts[] = {"ATX1", "ATX2"};
static const char *isabelle_st_voice_texts[] = {"VTX1", "VTX2"};
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),
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),
};
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),
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),
};

Просмотреть файл

@ -187,42 +187,42 @@ static const unsigned int sta32x_limiter_drc_release_tlv[] = {
13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0),
};
static const struct soc_enum sta32x_drc_ac_enum =
SOC_ENUM_SINGLE(STA32X_CONFD, STA32X_CONFD_DRC_SHIFT,
2, sta32x_drc_ac);
static const struct soc_enum sta32x_auto_eq_enum =
SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT,
3, sta32x_auto_eq_mode);
static const struct soc_enum sta32x_auto_gc_enum =
SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT,
4, sta32x_auto_gc_mode);
static const struct soc_enum sta32x_auto_xo_enum =
SOC_ENUM_SINGLE(STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT,
16, sta32x_auto_xo_mode);
static const struct soc_enum sta32x_preset_eq_enum =
SOC_ENUM_SINGLE(STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT,
32, sta32x_preset_eq_mode);
static const struct soc_enum sta32x_limiter_ch1_enum =
SOC_ENUM_SINGLE(STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT,
3, sta32x_limiter_select);
static const struct soc_enum sta32x_limiter_ch2_enum =
SOC_ENUM_SINGLE(STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT,
3, sta32x_limiter_select);
static const struct soc_enum sta32x_limiter_ch3_enum =
SOC_ENUM_SINGLE(STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT,
3, sta32x_limiter_select);
static const struct soc_enum sta32x_limiter1_attack_rate_enum =
SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxA_SHIFT,
16, sta32x_limiter_attack_rate);
static const struct soc_enum sta32x_limiter2_attack_rate_enum =
SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxA_SHIFT,
16, sta32x_limiter_attack_rate);
static const struct soc_enum sta32x_limiter1_release_rate_enum =
SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxR_SHIFT,
16, sta32x_limiter_release_rate);
static const struct soc_enum sta32x_limiter2_release_rate_enum =
SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxR_SHIFT,
16, sta32x_limiter_release_rate);
static SOC_ENUM_SINGLE_DECL(sta32x_drc_ac_enum,
STA32X_CONFD, STA32X_CONFD_DRC_SHIFT,
sta32x_drc_ac);
static SOC_ENUM_SINGLE_DECL(sta32x_auto_eq_enum,
STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT,
sta32x_auto_eq_mode);
static SOC_ENUM_SINGLE_DECL(sta32x_auto_gc_enum,
STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT,
sta32x_auto_gc_mode);
static SOC_ENUM_SINGLE_DECL(sta32x_auto_xo_enum,
STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT,
sta32x_auto_xo_mode);
static SOC_ENUM_SINGLE_DECL(sta32x_preset_eq_enum,
STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT,
sta32x_preset_eq_mode);
static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch1_enum,
STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT,
sta32x_limiter_select);
static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch2_enum,
STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT,
sta32x_limiter_select);
static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch3_enum,
STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT,
sta32x_limiter_select);
static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_attack_rate_enum,
STA32X_L1AR, STA32X_LxA_SHIFT,
sta32x_limiter_attack_rate);
static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_attack_rate_enum,
STA32X_L2AR, STA32X_LxA_SHIFT,
sta32x_limiter_attack_rate);
static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_release_rate_enum,
STA32X_L1AR, STA32X_LxR_SHIFT,
sta32x_limiter_release_rate);
static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_release_rate_enum,
STA32X_L2AR, STA32X_LxR_SHIFT,
sta32x_limiter_release_rate);
/* byte array controls for setting biquad, mixer, scaling coefficients;
* 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)
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;
int rc;

Просмотреть файл

@ -117,19 +117,23 @@ static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
static const char *wm8400_digital_sidetone[] =
{"None", "Left ADC", "Right ADC", "Reserved"};
static const struct soc_enum wm8400_left_digital_sidetone_enum =
SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE,
WM8400_ADC_TO_DACL_SHIFT, 2, wm8400_digital_sidetone);
static SOC_ENUM_SINGLE_DECL(wm8400_left_digital_sidetone_enum,
WM8400_DIGITAL_SIDE_TONE,
WM8400_ADC_TO_DACL_SHIFT,
wm8400_digital_sidetone);
static const struct soc_enum wm8400_right_digital_sidetone_enum =
SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE,
WM8400_ADC_TO_DACR_SHIFT, 2, wm8400_digital_sidetone);
static SOC_ENUM_SINGLE_DECL(wm8400_right_digital_sidetone_enum,
WM8400_DIGITAL_SIDE_TONE,
WM8400_ADC_TO_DACR_SHIFT,
wm8400_digital_sidetone);
static const char *wm8400_adcmode[] =
{"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"};
static const struct soc_enum wm8400_right_adcmode_enum =
SOC_ENUM_SINGLE(WM8400_ADC_CTRL, WM8400_ADC_HPF_CUT_SHIFT, 3, wm8400_adcmode);
static SOC_ENUM_SINGLE_DECL(wm8400_right_adcmode_enum,
WM8400_ADC_CTRL,
WM8400_ADC_HPF_CUT_SHIFT,
wm8400_adcmode);
static const struct snd_kcontrol_new wm8400_snd_controls[] = {
/* INMIXL */
@ -422,9 +426,10 @@ SOC_DAPM_SINGLE("RINPGA34 Switch", WM8400_INPUT_MIXER3, WM8400_L34MNB_SHIFT,
static const char *wm8400_ainlmux[] =
{"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"};
static const struct soc_enum wm8400_ainlmux_enum =
SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINLMODE_SHIFT,
ARRAY_SIZE(wm8400_ainlmux), wm8400_ainlmux);
static SOC_ENUM_SINGLE_DECL(wm8400_ainlmux_enum,
WM8400_INPUT_MIXER1,
WM8400_AINLMODE_SHIFT,
wm8400_ainlmux);
static const struct snd_kcontrol_new wm8400_dapm_ainlmux_controls =
SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum);
@ -435,9 +440,10 @@ SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum);
static const char *wm8400_ainrmux[] =
{"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"};
static const struct soc_enum wm8400_ainrmux_enum =
SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINRMODE_SHIFT,
ARRAY_SIZE(wm8400_ainrmux), wm8400_ainrmux);
static SOC_ENUM_SINGLE_DECL(wm8400_ainrmux_enum,
WM8400_INPUT_MIXER1,
WM8400_AINRMODE_SHIFT,
wm8400_ainrmux);
static const struct snd_kcontrol_new wm8400_dapm_ainrmux_controls =
SOC_DAPM_ENUM("Route", wm8400_ainrmux_enum);

Просмотреть файл

@ -196,8 +196,8 @@ static const char *ain_text[] = {
"AIN5", "AIN6", "AIN7", "AIN8"
};
static const struct soc_enum ain_enum =
SOC_ENUM_DOUBLE(WM8770_ADCMUX, 0, 4, 8, ain_text);
static SOC_ENUM_DOUBLE_DECL(ain_enum,
WM8770_ADCMUX, 0, 4, ain_text);
static const struct snd_kcontrol_new ain_mux =
SOC_DAPM_ENUM("Capture Mux", ain_enum);

Просмотреть файл

@ -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 struct soc_enum mic_bias_level =
SOC_ENUM_SINGLE(WM8900_REG_INCTL, 8, 2, mic_bias_level_txt);
static SOC_ENUM_SINGLE_DECL(mic_bias_level,
WM8900_REG_INCTL, 8, mic_bias_level_txt);
static const char *dac_mute_rate_txt[] = { "Fast", "Slow" };
static const struct soc_enum dac_mute_rate =
SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 7, 2, dac_mute_rate_txt);
static SOC_ENUM_SINGLE_DECL(dac_mute_rate,
WM8900_REG_DACCTRL, 7, dac_mute_rate_txt);
static const char *dac_deemphasis_txt[] = {
"Disabled", "32kHz", "44.1kHz", "48kHz"
};
static const struct soc_enum dac_deemphasis =
SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 4, 4, dac_deemphasis_txt);
static SOC_ENUM_SINGLE_DECL(dac_deemphasis,
WM8900_REG_DACCTRL, 4, dac_deemphasis_txt);
static const char *adc_hpf_cut_txt[] = {
"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"
};
static const struct soc_enum adc_hpf_cut =
SOC_ENUM_SINGLE(WM8900_REG_ADCCTRL, 5, 4, adc_hpf_cut_txt);
static SOC_ENUM_SINGLE_DECL(adc_hpf_cut,
WM8900_REG_ADCCTRL, 5, adc_hpf_cut_txt);
static const char *lr_txt[] = {
"Left", "Right"
};
static const struct soc_enum aifl_src =
SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 15, 2, lr_txt);
static SOC_ENUM_SINGLE_DECL(aifl_src,
WM8900_REG_AUDIO1, 15, lr_txt);
static const struct soc_enum aifr_src =
SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 14, 2, lr_txt);
static SOC_ENUM_SINGLE_DECL(aifr_src,
WM8900_REG_AUDIO1, 14, lr_txt);
static const struct soc_enum dacl_src =
SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 15, 2, lr_txt);
static SOC_ENUM_SINGLE_DECL(dacl_src,
WM8900_REG_AUDIO2, 15, lr_txt);
static const struct soc_enum dacr_src =
SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 14, 2, lr_txt);
static SOC_ENUM_SINGLE_DECL(dacr_src,
WM8900_REG_AUDIO2, 14, lr_txt);
static const char *sidetone_txt[] = {
"Disabled", "Left ADC", "Right ADC"
};
static const struct soc_enum dacl_sidetone =
SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 2, 3, sidetone_txt);
static SOC_ENUM_SINGLE_DECL(dacl_sidetone,
WM8900_REG_SIDETONE, 2, sidetone_txt);
static const struct soc_enum dacr_sidetone =
SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 0, 3, sidetone_txt);
static SOC_ENUM_SINGLE_DECL(dacr_sidetone,
WM8900_REG_SIDETONE, 0, sidetone_txt);
static const struct snd_kcontrol_new wm8900_snd_controls[] = {
SOC_ENUM("Mic Bias Level", mic_bias_level),
@ -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 struct soc_enum wm8900_lineout2_lp_mux =
SOC_ENUM_SINGLE(WM8900_REG_LOUTMIXCTL1, 1, 2, wm8900_lp_mux);
static SOC_ENUM_SINGLE_DECL(wm8900_lineout2_lp_mux,
WM8900_REG_LOUTMIXCTL1, 1, wm8900_lp_mux);
static const struct snd_kcontrol_new wm8900_lineout2_lp =
SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux);

Просмотреть файл

@ -265,21 +265,21 @@ static const char *sidetone_hpf_text[] = {
"2.7kHz", "1.35kHz", "675Hz", "370Hz", "180Hz", "90Hz", "45Hz"
};
static const struct soc_enum sidetone_hpf =
SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text);
static SOC_ENUM_SINGLE_DECL(sidetone_hpf,
WM8994_SIDETONE, 7, sidetone_hpf_text);
static const char *adc_hpf_text[] = {
"HiFi", "Voice 1", "Voice 2", "Voice 3"
};
static const struct soc_enum aif1adc1_hpf =
SOC_ENUM_SINGLE(WM8994_AIF1_ADC1_FILTERS, 13, 4, adc_hpf_text);
static SOC_ENUM_SINGLE_DECL(aif1adc1_hpf,
WM8994_AIF1_ADC1_FILTERS, 13, adc_hpf_text);
static const struct soc_enum aif1adc2_hpf =
SOC_ENUM_SINGLE(WM8994_AIF1_ADC2_FILTERS, 13, 4, adc_hpf_text);
static SOC_ENUM_SINGLE_DECL(aif1adc2_hpf,
WM8994_AIF1_ADC2_FILTERS, 13, adc_hpf_text);
static const struct soc_enum aif2adc_hpf =
SOC_ENUM_SINGLE(WM8994_AIF2_ADC_FILTERS, 13, 4, adc_hpf_text);
static SOC_ENUM_SINGLE_DECL(aif2adc_hpf,
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(digital_tlv, -7200, 75, 1);
@ -501,39 +501,39 @@ static const char *aif_chan_src_text[] = {
"Left", "Right"
};
static const struct soc_enum aif1adcl_src =
SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 15, 2, aif_chan_src_text);
static SOC_ENUM_SINGLE_DECL(aif1adcl_src,
WM8994_AIF1_CONTROL_1, 15, aif_chan_src_text);
static const struct soc_enum aif1adcr_src =
SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 14, 2, aif_chan_src_text);
static SOC_ENUM_SINGLE_DECL(aif1adcr_src,
WM8994_AIF1_CONTROL_1, 14, aif_chan_src_text);
static const struct soc_enum aif2adcl_src =
SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 15, 2, aif_chan_src_text);
static SOC_ENUM_SINGLE_DECL(aif2adcl_src,
WM8994_AIF2_CONTROL_1, 15, aif_chan_src_text);
static const struct soc_enum aif2adcr_src =
SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 14, 2, aif_chan_src_text);
static SOC_ENUM_SINGLE_DECL(aif2adcr_src,
WM8994_AIF2_CONTROL_1, 14, aif_chan_src_text);
static const struct soc_enum aif1dacl_src =
SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 15, 2, aif_chan_src_text);
static SOC_ENUM_SINGLE_DECL(aif1dacl_src,
WM8994_AIF1_CONTROL_2, 15, aif_chan_src_text);
static const struct soc_enum aif1dacr_src =
SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 14, 2, aif_chan_src_text);
static SOC_ENUM_SINGLE_DECL(aif1dacr_src,
WM8994_AIF1_CONTROL_2, 14, aif_chan_src_text);
static const struct soc_enum aif2dacl_src =
SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 15, 2, aif_chan_src_text);
static SOC_ENUM_SINGLE_DECL(aif2dacl_src,
WM8994_AIF2_CONTROL_2, 15, aif_chan_src_text);
static const struct soc_enum aif2dacr_src =
SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aif_chan_src_text);
static SOC_ENUM_SINGLE_DECL(aif2dacr_src,
WM8994_AIF2_CONTROL_2, 14, aif_chan_src_text);
static const char *osr_text[] = {
"Low Power", "High Performance",
};
static const struct soc_enum dac_osr =
SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 0, 2, osr_text);
static SOC_ENUM_SINGLE_DECL(dac_osr,
WM8994_OVERSAMPLING, 0, osr_text);
static const struct soc_enum adc_osr =
SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text);
static SOC_ENUM_SINGLE_DECL(adc_osr,
WM8994_OVERSAMPLING, 1, osr_text);
static const struct snd_kcontrol_new wm8994_snd_controls[] = {
SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME,
@ -690,17 +690,20 @@ static const char *wm8958_ng_text[] = {
"30ms", "125ms", "250ms", "500ms",
};
static const struct soc_enum wm8958_aif1dac1_ng_hold =
SOC_ENUM_SINGLE(WM8958_AIF1_DAC1_NOISE_GATE,
WM8958_AIF1DAC1_NG_THR_SHIFT, 4, wm8958_ng_text);
static SOC_ENUM_SINGLE_DECL(wm8958_aif1dac1_ng_hold,
WM8958_AIF1_DAC1_NOISE_GATE,
WM8958_AIF1DAC1_NG_THR_SHIFT,
wm8958_ng_text);
static const struct soc_enum wm8958_aif1dac2_ng_hold =
SOC_ENUM_SINGLE(WM8958_AIF1_DAC2_NOISE_GATE,
WM8958_AIF1DAC2_NG_THR_SHIFT, 4, wm8958_ng_text);
static SOC_ENUM_SINGLE_DECL(wm8958_aif1dac2_ng_hold,
WM8958_AIF1_DAC2_NOISE_GATE,
WM8958_AIF1DAC2_NG_THR_SHIFT,
wm8958_ng_text);
static const struct soc_enum wm8958_aif2dac_ng_hold =
SOC_ENUM_SINGLE(WM8958_AIF2_DAC_NOISE_GATE,
WM8958_AIF2DAC_NG_THR_SHIFT, 4, wm8958_ng_text);
static SOC_ENUM_SINGLE_DECL(wm8958_aif2dac_ng_hold,
WM8958_AIF2_DAC_NOISE_GATE,
WM8958_AIF2DAC_NG_THR_SHIFT,
wm8958_ng_text);
static const struct snd_kcontrol_new wm8958_snd_controls[] = {
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[] = {
"DMIC",
};
static const struct soc_enum adc_enum =
SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text);
static SOC_ENUM_SINGLE_DECL(adc_enum,
0, 0, adc_mux_text);
static const struct snd_kcontrol_new adcl_mux =
SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum);
@ -1478,14 +1481,14 @@ static const char *sidetone_text[] = {
"ADC/DMIC1", "DMIC2",
};
static const struct soc_enum sidetone1_enum =
SOC_ENUM_SINGLE(WM8994_SIDETONE, 0, 2, sidetone_text);
static SOC_ENUM_SINGLE_DECL(sidetone1_enum,
WM8994_SIDETONE, 0, sidetone_text);
static const struct snd_kcontrol_new sidetone1_mux =
SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum);
static const struct soc_enum sidetone2_enum =
SOC_ENUM_SINGLE(WM8994_SIDETONE, 1, 2, sidetone_text);
static SOC_ENUM_SINGLE_DECL(sidetone2_enum,
WM8994_SIDETONE, 1, sidetone_text);
static const struct snd_kcontrol_new sidetone2_mux =
SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum);
@ -1498,22 +1501,24 @@ static const char *loopback_text[] = {
"None", "ADCDAT",
};
static const struct soc_enum aif1_loopback_enum =
SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, WM8994_AIF1_LOOPBACK_SHIFT, 2,
loopback_text);
static SOC_ENUM_SINGLE_DECL(aif1_loopback_enum,
WM8994_AIF1_CONTROL_2,
WM8994_AIF1_LOOPBACK_SHIFT,
loopback_text);
static const struct snd_kcontrol_new aif1_loopback =
SOC_DAPM_ENUM("AIF1 Loopback", aif1_loopback_enum);
static const struct soc_enum aif2_loopback_enum =
SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, WM8994_AIF2_LOOPBACK_SHIFT, 2,
loopback_text);
static SOC_ENUM_SINGLE_DECL(aif2_loopback_enum,
WM8994_AIF2_CONTROL_2,
WM8994_AIF2_LOOPBACK_SHIFT,
loopback_text);
static const struct snd_kcontrol_new aif2_loopback =
SOC_DAPM_ENUM("AIF2 Loopback", aif2_loopback_enum);
static const struct soc_enum aif1dac_enum =
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 0, 2, aif1dac_text);
static SOC_ENUM_SINGLE_DECL(aif1dac_enum,
WM8994_POWER_MANAGEMENT_6, 0, aif1dac_text);
static const struct snd_kcontrol_new aif1dac_mux =
SOC_DAPM_ENUM("AIF1DAC Mux", aif1dac_enum);
@ -1522,8 +1527,8 @@ static const char *aif2dac_text[] = {
"AIF2DACDAT", "AIF3DACDAT",
};
static const struct soc_enum aif2dac_enum =
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 1, 2, aif2dac_text);
static SOC_ENUM_SINGLE_DECL(aif2dac_enum,
WM8994_POWER_MANAGEMENT_6, 1, aif2dac_text);
static const struct snd_kcontrol_new aif2dac_mux =
SOC_DAPM_ENUM("AIF2DAC Mux", aif2dac_enum);
@ -1532,8 +1537,8 @@ static const char *aif2adc_text[] = {
"AIF2ADCDAT", "AIF3DACDAT",
};
static const struct soc_enum aif2adc_enum =
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 2, 2, aif2adc_text);
static SOC_ENUM_SINGLE_DECL(aif2adc_enum,
WM8994_POWER_MANAGEMENT_6, 2, aif2adc_text);
static const struct snd_kcontrol_new aif2adc_mux =
SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum);
@ -1542,14 +1547,14 @@ static const char *aif3adc_text[] = {
"AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", "Mono PCM",
};
static const struct soc_enum wm8994_aif3adc_enum =
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text);
static SOC_ENUM_SINGLE_DECL(wm8994_aif3adc_enum,
WM8994_POWER_MANAGEMENT_6, 3, aif3adc_text);
static const struct snd_kcontrol_new wm8994_aif3adc_mux =
SOC_DAPM_ENUM("AIF3ADC Mux", wm8994_aif3adc_enum);
static const struct soc_enum wm8958_aif3adc_enum =
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 4, aif3adc_text);
static SOC_ENUM_SINGLE_DECL(wm8958_aif3adc_enum,
WM8994_POWER_MANAGEMENT_6, 3, aif3adc_text);
static const struct snd_kcontrol_new wm8958_aif3adc_mux =
SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum);
@ -1558,8 +1563,8 @@ static const char *mono_pcm_out_text[] = {
"None", "AIF2ADCL", "AIF2ADCR",
};
static const struct soc_enum mono_pcm_out_enum =
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 9, 3, mono_pcm_out_text);
static SOC_ENUM_SINGLE_DECL(mono_pcm_out_enum,
WM8994_POWER_MANAGEMENT_6, 9, mono_pcm_out_text);
static const struct snd_kcontrol_new mono_pcm_out_mux =
SOC_DAPM_ENUM("Mono PCM Out Mux", mono_pcm_out_enum);
@ -1569,14 +1574,14 @@ static const char *aif2dac_src_text[] = {
};
/* Note that these two control shouldn't be simultaneously switched to AIF3 */
static const struct soc_enum aif2dacl_src_enum =
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 7, 2, aif2dac_src_text);
static SOC_ENUM_SINGLE_DECL(aif2dacl_src_enum,
WM8994_POWER_MANAGEMENT_6, 7, aif2dac_src_text);
static const struct snd_kcontrol_new aif2dacl_src_mux =
SOC_DAPM_ENUM("AIF2DACL Mux", aif2dacl_src_enum);
static const struct soc_enum aif2dacr_src_enum =
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 8, 2, aif2dac_src_text);
static SOC_ENUM_SINGLE_DECL(aif2dacr_src_enum,
WM8994_POWER_MANAGEMENT_6, 8, aif2dac_src_text);
static const struct snd_kcontrol_new aif2dacr_src_mux =
SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum);

Просмотреть файл

@ -1218,7 +1218,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
ret = regulator_allow_bypass(w->regulator, false);
if (ret != 0)
dev_warn(w->dapm->dev,
"ASoC: Failed to bypass %s: %d\n",
"ASoC: Failed to unbypass %s: %d\n",
w->name, ret);
}
@ -1228,7 +1228,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
ret = regulator_allow_bypass(w->regulator, true);
if (ret != 0)
dev_warn(w->dapm->dev,
"ASoC: Failed to unbypass %s: %d\n",
"ASoC: Failed to bypass %s: %d\n",
w->name, ret);
}
@ -3210,15 +3210,11 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
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])
snd_soc_dapm_enable_pin(&card->dapm, pin);
else
snd_soc_dapm_disable_pin(&card->dapm, pin);
mutex_unlock(&card->dapm_mutex);
snd_soc_dapm_sync(&card->dapm);
return 0;
}
@ -3248,7 +3244,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
ret = regulator_allow_bypass(w->regulator, true);
if (ret != 0)
dev_warn(w->dapm->dev,
"ASoC: Failed to unbypass %s: %d\n",
"ASoC: Failed to bypass %s: %d\n",
w->name, ret);
}
break;
@ -3766,6 +3762,26 @@ void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
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.
* @dapm: DAPM context
@ -3773,15 +3789,57 @@ 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
* a valid audio route and active audio stream.
*
* 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(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);
/**
* snd_soc_dapm_force_enable_pin_unlocked - 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.
*
* 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_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm,
const char *pin)
{
struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
if (!w) {
dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin);
return -EINVAL;
}
dev_dbg(w->dapm->dev, "ASoC: force enable pin %s\n", pin);
w->connected = 1;
w->force = 1;
dapm_mark_dirty(w, "force enable");
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
@ -3797,38 +3855,85 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
const char *pin)
{
struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
int ret;
if (!w) {
dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin);
return -EINVAL;
}
mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
dev_dbg(w->dapm->dev, "ASoC: force enable pin %s\n", pin);
w->connected = 1;
w->force = 1;
dapm_mark_dirty(w, "force enable");
ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, pin);
return 0;
mutex_unlock(&dapm->card->dapm_mutex);
return ret;
}
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.
* @dapm: DAPM context
* @pin: pin name
*
* Disables input/output pin and its parents or children widgets.
*
* 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(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_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.
* @dapm: DAPM context
@ -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)
{
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);