Commit 45d39cbf authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branch 'asoc/fix/dapm' into asoc-linus

parents d9fb50e4 11391100
...@@ -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);
......
...@@ -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