summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/max98090.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-12-18 08:54:15 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2019-12-18 08:54:15 -0800
commit80a0c2e511a97e11d82e0ec11564e2c3fe624b0d (patch)
tree0a59b0aff00abe3ae71badcb8fd65d376bb4f51b /sound/soc/codecs/max98090.c
parent2187f215ebaac73ddbd814696d7c7fa34f0c3de0 (diff)
parent7c497d799267134786afdf719d9230b7d6f77d84 (diff)
Merge tag 'sound-5.5-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai: "A slightly high amount at this time, but all good and small fixes: - A PCM core fix that initializes the buffer properly for avoiding information leaks; it is a long-standing minor problem, but good to fix better now - A few ASoC core fixes for the init / cleanup ordering issues that surfaced after the recent refactoring - Lots of SOF and topology-related fixes went in, as usual as such hot topics - Several ASoC codec and platform-specific small fixes: wm89xx, realtek, and max98090, AMD, Intel-SST - A fix for the previous incomplete regression of HD-audio, now hitting Nvidia HDMI - A few HD-audio CA0132 codec fixes" * tag 'sound-5.5-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (27 commits) ALSA: hda - Downgrade error message for single-cmd fallback ASoC: wm8962: fix lambda value ALSA: hda: Fix regression by strip mask fix ALSA: hda/ca0132 - Fix work handling in delayed HP detection ALSA: hda/ca0132 - Avoid endless loop ALSA: hda/ca0132 - Keep power on during processing DSP response ALSA: pcm: Avoid possible info leaks from PCM stream buffers ASoC: Intel: common: work-around incorrect ACPI HID for CML boards ASoC: SOF: Intel: split cht and byt debug window sizes ASoC: SOF: loader: fix snd_sof_fw_parse_ext_data ASoC: SOF: loader: snd_sof_fw_parse_ext_data log warning on unknown header ASoC: simple-card: Don't create separate link when platform is present ASoC: topology: Check return value for soc_tplg_pcm_create() ASoC: topology: Check return value for snd_soc_add_dai_link() ASoC: core: only flush inited work during free ASoC: Intel: bytcr_rt5640: Update quirk for Teclast X89 ASoC: core: Init pcm runtime work early to avoid warnings ASoC: Intel: sst: Add missing include <linux/io.h> ASoC: max98090: fix possible race conditions ASoC: max98090: exit workaround earlier if PLL is locked ...
Diffstat (limited to 'sound/soc/codecs/max98090.c')
-rw-r--r--sound/soc/codecs/max98090.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index f6bf4cfbea23..e46b6ada13b1 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -2103,26 +2103,40 @@ static void max98090_pll_det_disable_work(struct work_struct *work)
M98090_IULK_MASK, 0);
}
-static void max98090_pll_work(struct work_struct *work)
+static void max98090_pll_work(struct max98090_priv *max98090)
{
- struct max98090_priv *max98090 =
- container_of(work, struct max98090_priv, pll_work);
struct snd_soc_component *component = max98090->component;
+ unsigned int pll;
+ int i;
if (!snd_soc_component_is_active(component))
return;
dev_info_ratelimited(component->dev, "PLL unlocked\n");
+ /*
+ * As the datasheet suggested, the maximum PLL lock time should be
+ * 7 msec. The workaround resets the codec softly by toggling SHDN
+ * off and on if PLL failed to lock for 10 msec. Notably, there is
+ * no suggested hold time for SHDN off.
+ */
+
/* Toggle shutdown OFF then ON */
snd_soc_component_update_bits(component, M98090_REG_DEVICE_SHUTDOWN,
M98090_SHDNN_MASK, 0);
- msleep(10);
snd_soc_component_update_bits(component, M98090_REG_DEVICE_SHUTDOWN,
M98090_SHDNN_MASK, M98090_SHDNN_MASK);
- /* Give PLL time to lock */
- msleep(10);
+ for (i = 0; i < 10; ++i) {
+ /* Give PLL time to lock */
+ usleep_range(1000, 1200);
+
+ /* Check lock status */
+ pll = snd_soc_component_read32(
+ component, M98090_REG_DEVICE_STATUS);
+ if (!(pll & M98090_ULK_MASK))
+ break;
+ }
}
static void max98090_jack_work(struct work_struct *work)
@@ -2259,7 +2273,7 @@ static irqreturn_t max98090_interrupt(int irq, void *data)
if (active & M98090_ULK_MASK) {
dev_dbg(component->dev, "M98090_ULK_MASK\n");
- schedule_work(&max98090->pll_work);
+ max98090_pll_work(max98090);
}
if (active & M98090_JDET_MASK) {
@@ -2422,7 +2436,6 @@ static int max98090_probe(struct snd_soc_component *component)
max98090_pll_det_enable_work);
INIT_WORK(&max98090->pll_det_disable_work,
max98090_pll_det_disable_work);
- INIT_WORK(&max98090->pll_work, max98090_pll_work);
/* Enable jack detection */
snd_soc_component_write(component, M98090_REG_JACK_DETECT,
@@ -2475,7 +2488,6 @@ static void max98090_remove(struct snd_soc_component *component)
cancel_delayed_work_sync(&max98090->jack_work);
cancel_delayed_work_sync(&max98090->pll_det_enable_work);
cancel_work_sync(&max98090->pll_det_disable_work);
- cancel_work_sync(&max98090->pll_work);
max98090->component = NULL;
}