diff options
author | Mark Brown <broonie@kernel.org> | 2014-10-06 07:48:44 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2014-10-06 07:48:44 -0400 |
commit | fd7aff54ff6862cde82db8a7d55166a2f0a34b9c (patch) | |
tree | d5c9f3c32f32e04876d8bdb17f38435d67782d8c | |
parent | bfe01a5ba2490f299e1d2d5508cbbbadd897bbe9 (diff) | |
parent | 5e3905f62b2eb25d4421117e62f9d0434c0b6563 (diff) |
Merge tag 'asoc-v3.17-rc4' into asoc-linus
ASoC: Fixes for v3.17
Another round of again fairly unexciting fixes - several driver fixes,
an e-mail address change and a fix for error handling with DPCM.
# gpg: Signature made Wed 10 Sep 2014 12:26:54 BST using RSA key ID 5D5487D0
# gpg: Good signature from "Mark Brown <broonie@sirena.org.uk>"
# gpg: aka "Mark Brown <broonie@debian.org>"
# gpg: aka "Mark Brown <broonie@kernel.org>"
# gpg: aka "Mark Brown <broonie@tardis.ed.ac.uk>"
# gpg: aka "Mark Brown <broonie@linaro.org>"
# gpg: aka "Mark Brown <Mark.Brown@linaro.org>"
-rw-r--r-- | sound/soc/codecs/max98090.c | 111 | ||||
-rw-r--r-- | sound/soc/codecs/max98090.h | 3 |
2 files changed, 112 insertions, 2 deletions
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 4a063fa88526..f1543653a699 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c | |||
@@ -1972,6 +1972,102 @@ static int max98090_dai_digital_mute(struct snd_soc_dai *codec_dai, int mute) | |||
1972 | return 0; | 1972 | return 0; |
1973 | } | 1973 | } |
1974 | 1974 | ||
1975 | static int max98090_dai_trigger(struct snd_pcm_substream *substream, int cmd, | ||
1976 | struct snd_soc_dai *dai) | ||
1977 | { | ||
1978 | struct snd_soc_codec *codec = dai->codec; | ||
1979 | struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); | ||
1980 | |||
1981 | switch (cmd) { | ||
1982 | case SNDRV_PCM_TRIGGER_START: | ||
1983 | case SNDRV_PCM_TRIGGER_RESUME: | ||
1984 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
1985 | if (!max98090->master && dai->active == 1) | ||
1986 | queue_delayed_work(system_power_efficient_wq, | ||
1987 | &max98090->pll_det_enable_work, | ||
1988 | msecs_to_jiffies(10)); | ||
1989 | break; | ||
1990 | case SNDRV_PCM_TRIGGER_STOP: | ||
1991 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
1992 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
1993 | if (!max98090->master && dai->active == 1) | ||
1994 | schedule_work(&max98090->pll_det_disable_work); | ||
1995 | break; | ||
1996 | default: | ||
1997 | break; | ||
1998 | } | ||
1999 | |||
2000 | return 0; | ||
2001 | } | ||
2002 | |||
2003 | static void max98090_pll_det_enable_work(struct work_struct *work) | ||
2004 | { | ||
2005 | struct max98090_priv *max98090 = | ||
2006 | container_of(work, struct max98090_priv, | ||
2007 | pll_det_enable_work.work); | ||
2008 | struct snd_soc_codec *codec = max98090->codec; | ||
2009 | unsigned int status, mask; | ||
2010 | |||
2011 | /* | ||
2012 | * Clear status register in order to clear possibly already occurred | ||
2013 | * PLL unlock. If PLL hasn't still locked, the status will be set | ||
2014 | * again and PLL unlock interrupt will occur. | ||
2015 | * Note this will clear all status bits | ||
2016 | */ | ||
2017 | regmap_read(max98090->regmap, M98090_REG_DEVICE_STATUS, &status); | ||
2018 | |||
2019 | /* | ||
2020 | * Queue jack work in case jack state has just changed but handler | ||
2021 | * hasn't run yet | ||
2022 | */ | ||
2023 | regmap_read(max98090->regmap, M98090_REG_INTERRUPT_S, &mask); | ||
2024 | status &= mask; | ||
2025 | if (status & M98090_JDET_MASK) | ||
2026 | queue_delayed_work(system_power_efficient_wq, | ||
2027 | &max98090->jack_work, | ||
2028 | msecs_to_jiffies(100)); | ||
2029 | |||
2030 | /* Enable PLL unlock interrupt */ | ||
2031 | snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S, | ||
2032 | M98090_IULK_MASK, | ||
2033 | 1 << M98090_IULK_SHIFT); | ||
2034 | } | ||
2035 | |||
2036 | static void max98090_pll_det_disable_work(struct work_struct *work) | ||
2037 | { | ||
2038 | struct max98090_priv *max98090 = | ||
2039 | container_of(work, struct max98090_priv, pll_det_disable_work); | ||
2040 | struct snd_soc_codec *codec = max98090->codec; | ||
2041 | |||
2042 | cancel_delayed_work_sync(&max98090->pll_det_enable_work); | ||
2043 | |||
2044 | /* Disable PLL unlock interrupt */ | ||
2045 | snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S, | ||
2046 | M98090_IULK_MASK, 0); | ||
2047 | } | ||
2048 | |||
2049 | static void max98090_pll_work(struct work_struct *work) | ||
2050 | { | ||
2051 | struct max98090_priv *max98090 = | ||
2052 | container_of(work, struct max98090_priv, pll_work); | ||
2053 | struct snd_soc_codec *codec = max98090->codec; | ||
2054 | |||
2055 | if (!snd_soc_codec_is_active(codec)) | ||
2056 | return; | ||
2057 | |||
2058 | dev_info(codec->dev, "PLL unlocked\n"); | ||
2059 | |||
2060 | /* Toggle shutdown OFF then ON */ | ||
2061 | snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN, | ||
2062 | M98090_SHDNN_MASK, 0); | ||
2063 | msleep(10); | ||
2064 | snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN, | ||
2065 | M98090_SHDNN_MASK, M98090_SHDNN_MASK); | ||
2066 | |||
2067 | /* Give PLL time to lock */ | ||
2068 | msleep(10); | ||
2069 | } | ||
2070 | |||
1975 | static void max98090_jack_work(struct work_struct *work) | 2071 | static void max98090_jack_work(struct work_struct *work) |
1976 | { | 2072 | { |
1977 | struct max98090_priv *max98090 = container_of(work, | 2073 | struct max98090_priv *max98090 = container_of(work, |
@@ -2103,8 +2199,10 @@ static irqreturn_t max98090_interrupt(int irq, void *data) | |||
2103 | if (active & M98090_SLD_MASK) | 2199 | if (active & M98090_SLD_MASK) |
2104 | dev_dbg(codec->dev, "M98090_SLD_MASK\n"); | 2200 | dev_dbg(codec->dev, "M98090_SLD_MASK\n"); |
2105 | 2201 | ||
2106 | if (active & M98090_ULK_MASK) | 2202 | if (active & M98090_ULK_MASK) { |
2107 | dev_err(codec->dev, "M98090_ULK_MASK\n"); | 2203 | dev_dbg(codec->dev, "M98090_ULK_MASK\n"); |
2204 | schedule_work(&max98090->pll_work); | ||
2205 | } | ||
2108 | 2206 | ||
2109 | if (active & M98090_JDET_MASK) { | 2207 | if (active & M98090_JDET_MASK) { |
2110 | dev_dbg(codec->dev, "M98090_JDET_MASK\n"); | 2208 | dev_dbg(codec->dev, "M98090_JDET_MASK\n"); |
@@ -2177,6 +2275,7 @@ static struct snd_soc_dai_ops max98090_dai_ops = { | |||
2177 | .set_tdm_slot = max98090_set_tdm_slot, | 2275 | .set_tdm_slot = max98090_set_tdm_slot, |
2178 | .hw_params = max98090_dai_hw_params, | 2276 | .hw_params = max98090_dai_hw_params, |
2179 | .digital_mute = max98090_dai_digital_mute, | 2277 | .digital_mute = max98090_dai_digital_mute, |
2278 | .trigger = max98090_dai_trigger, | ||
2180 | }; | 2279 | }; |
2181 | 2280 | ||
2182 | static struct snd_soc_dai_driver max98090_dai[] = { | 2281 | static struct snd_soc_dai_driver max98090_dai[] = { |
@@ -2258,6 +2357,11 @@ static int max98090_probe(struct snd_soc_codec *codec) | |||
2258 | max98090->jack_state = M98090_JACK_STATE_NO_HEADSET; | 2357 | max98090->jack_state = M98090_JACK_STATE_NO_HEADSET; |
2259 | 2358 | ||
2260 | INIT_DELAYED_WORK(&max98090->jack_work, max98090_jack_work); | 2359 | INIT_DELAYED_WORK(&max98090->jack_work, max98090_jack_work); |
2360 | INIT_DELAYED_WORK(&max98090->pll_det_enable_work, | ||
2361 | max98090_pll_det_enable_work); | ||
2362 | INIT_WORK(&max98090->pll_det_disable_work, | ||
2363 | max98090_pll_det_disable_work); | ||
2364 | INIT_WORK(&max98090->pll_work, max98090_pll_work); | ||
2261 | 2365 | ||
2262 | /* Enable jack detection */ | 2366 | /* Enable jack detection */ |
2263 | snd_soc_write(codec, M98090_REG_JACK_DETECT, | 2367 | snd_soc_write(codec, M98090_REG_JACK_DETECT, |
@@ -2310,6 +2414,9 @@ static int max98090_remove(struct snd_soc_codec *codec) | |||
2310 | struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); | 2414 | struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); |
2311 | 2415 | ||
2312 | cancel_delayed_work_sync(&max98090->jack_work); | 2416 | cancel_delayed_work_sync(&max98090->jack_work); |
2417 | cancel_delayed_work_sync(&max98090->pll_det_enable_work); | ||
2418 | cancel_work_sync(&max98090->pll_det_disable_work); | ||
2419 | cancel_work_sync(&max98090->pll_work); | ||
2313 | 2420 | ||
2314 | return 0; | 2421 | return 0; |
2315 | } | 2422 | } |
diff --git a/sound/soc/codecs/max98090.h b/sound/soc/codecs/max98090.h index cf1b6062ba8c..14427a566f41 100644 --- a/sound/soc/codecs/max98090.h +++ b/sound/soc/codecs/max98090.h | |||
@@ -1532,6 +1532,9 @@ struct max98090_priv { | |||
1532 | int irq; | 1532 | int irq; |
1533 | int jack_state; | 1533 | int jack_state; |
1534 | struct delayed_work jack_work; | 1534 | struct delayed_work jack_work; |
1535 | struct delayed_work pll_det_enable_work; | ||
1536 | struct work_struct pll_det_disable_work; | ||
1537 | struct work_struct pll_work; | ||
1535 | struct snd_soc_jack *jack; | 1538 | struct snd_soc_jack *jack; |
1536 | unsigned int dai_fmt; | 1539 | unsigned int dai_fmt; |
1537 | int tdm_slots; | 1540 | int tdm_slots; |