summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/cs42l42.c22
-rw-r--r--sound/soc/codecs/cs42l42.h2
2 files changed, 24 insertions, 0 deletions
diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c
index 0c4303547fd8..43d98bdb5b5b 100644
--- a/sound/soc/codecs/cs42l42.c
+++ b/sound/soc/codecs/cs42l42.c
@@ -549,8 +549,25 @@ static int cs42l42_set_jack(struct snd_soc_component *component, struct snd_soc_
{
struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
+ /* Prevent race with interrupt handler */
+ mutex_lock(&cs42l42->jack_detect_mutex);
cs42l42->jack = jk;
+ if (jk) {
+ switch (cs42l42->hs_type) {
+ case CS42L42_PLUG_CTIA:
+ case CS42L42_PLUG_OMTP:
+ snd_soc_jack_report(jk, SND_JACK_HEADSET, SND_JACK_HEADSET);
+ break;
+ case CS42L42_PLUG_HEADPHONE:
+ snd_soc_jack_report(jk, SND_JACK_HEADPHONE, SND_JACK_HEADPHONE);
+ break;
+ default:
+ break;
+ }
+ }
+ mutex_unlock(&cs42l42->jack_detect_mutex);
+
return 0;
}
@@ -1618,6 +1635,8 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data)
CS42L42_M_DETECT_FT_MASK |
CS42L42_M_HSBIAS_HIZ_MASK);
+ mutex_lock(&cs42l42->jack_detect_mutex);
+
/* Check auto-detect status */
if ((~masks[5]) & irq_params_table[5].mask) {
if (stickies[5] & CS42L42_HSDET_AUTO_DONE_MASK) {
@@ -1686,6 +1705,8 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data)
}
}
+ mutex_unlock(&cs42l42->jack_detect_mutex);
+
return IRQ_HANDLED;
}
@@ -2033,6 +2054,7 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client,
cs42l42->dev = &i2c_client->dev;
i2c_set_clientdata(i2c_client, cs42l42);
+ mutex_init(&cs42l42->jack_detect_mutex);
cs42l42->regmap = devm_regmap_init_i2c(i2c_client, &cs42l42_regmap);
if (IS_ERR(cs42l42->regmap)) {
diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h
index 75ade987d0db..9fff183dce8e 100644
--- a/sound/soc/codecs/cs42l42.h
+++ b/sound/soc/codecs/cs42l42.h
@@ -12,6 +12,7 @@
#ifndef __CS42L42_H__
#define __CS42L42_H__
+#include <linux/mutex.h>
#include <sound/jack.h>
#define CS42L42_PAGE_REGISTER 0x00 /* Page Select Register */
@@ -841,6 +842,7 @@ struct cs42l42_private {
struct gpio_desc *reset_gpio;
struct completion pdn_done;
struct snd_soc_jack *jack;
+ struct mutex jack_detect_mutex;
int pll_config;
int bclk;
u32 sclk;