]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - sound/soc/codecs/max98090.c
Merge remote-tracking branches 'asoc/topic/max98090' and 'asoc/topic/max98095' into...
[karo-tx-linux.git] / sound / soc / codecs / max98090.c
index 8857be798f3b221e2e2e9bb4374c3ac81c638cea..f5fccc7a8e89b59b42911fb5684d8ab31b775b52 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
@@ -257,6 +258,7 @@ static struct reg_default max98090_reg[] = {
 static bool max98090_volatile_register(struct device *dev, unsigned int reg)
 {
        switch (reg) {
+       case M98090_REG_SOFTWARE_RESET:
        case M98090_REG_DEVICE_STATUS:
        case M98090_REG_JACK_STATUS:
        case M98090_REG_REVISION_ID:
@@ -391,6 +393,7 @@ static const DECLARE_TLV_DB_SCALE(max98090_alc_tlv, -1500, 100, 0);
 static const DECLARE_TLV_DB_SCALE(max98090_alcmakeup_tlv, 0, 100, 0);
 static const DECLARE_TLV_DB_SCALE(max98090_alccomp_tlv, -3100, 100, 0);
 static const DECLARE_TLV_DB_SCALE(max98090_drcexp_tlv, -6600, 100, 0);
+static const DECLARE_TLV_DB_SCALE(max98090_sdg_tlv, 50, 200, 0);
 
 static const unsigned int max98090_mixout_tlv[] = {
        TLV_DB_RANGE_HEAD(2),
@@ -428,7 +431,7 @@ static const unsigned int max98090_rcv_lout_tlv[] = {
 static int max98090_get_enab_tlv(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
@@ -468,7 +471,7 @@ static int max98090_get_enab_tlv(struct snd_kcontrol *kcontrol,
 static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
@@ -667,7 +670,7 @@ static const struct snd_kcontrol_new max98090_snd_controls[] = {
        SOC_SINGLE_EXT_TLV("Digital Sidetone Volume",
                M98090_REG_ADC_SIDETONE, M98090_DVST_SHIFT,
                M98090_DVST_NUM - 1, 1, max98090_get_enab_tlv,
-               max98090_put_enab_tlv, max98090_micboost_tlv),
+               max98090_put_enab_tlv, max98090_sdg_tlv),
        SOC_SINGLE_TLV("Digital Coarse Volume", M98090_REG_DAI_PLAYBACK_LEVEL,
                M98090_DVG_SHIFT, M98090_DVG_NUM - 1, 0,
                max98090_dvg_tlv),
@@ -877,7 +880,7 @@ static const char *dmic_mux_text[] = { "ADC", "DMIC" };
 static SOC_ENUM_SINGLE_VIRT_DECL(dmic_mux_enum, dmic_mux_text);
 
 static const struct snd_kcontrol_new max98090_dmic_mux =
-       SOC_DAPM_ENUM_VIRT("DMIC Mux", dmic_mux_enum);
+       SOC_DAPM_ENUM("DMIC Mux", dmic_mux_enum);
 
 static const char *max98090_micpre_text[] = { "Off", "On" };
 
@@ -1177,8 +1180,7 @@ static const struct snd_soc_dapm_widget max98090_dapm_widgets[] = {
        SND_SOC_DAPM_MUX("MIC2 Mux", SND_SOC_NOPM,
                0, 0, &max98090_mic2_mux),
 
-       SND_SOC_DAPM_VIRT_MUX("DMIC Mux", SND_SOC_NOPM,
-               0, 0, &max98090_dmic_mux),
+       SND_SOC_DAPM_MUX("DMIC Mux", SND_SOC_NOPM, 0, 0, &max98090_dmic_mux),
 
        SND_SOC_DAPM_PGA_E("MIC1 Input", M98090_REG_MIC1_INPUT_LEVEL,
                M98090_MIC_PA1EN_SHIFT, 0, NULL, 0, max98090_micinput_event,
@@ -2409,6 +2411,8 @@ static int max98090_runtime_resume(struct device *dev)
 
        regcache_cache_only(max98090->regmap, false);
 
+       max98090_reset(max98090);
+
        regcache_sync(max98090->regmap);
 
        return 0;
@@ -2424,9 +2428,34 @@ static int max98090_runtime_suspend(struct device *dev)
 }
 #endif
 
+#ifdef CONFIG_PM
+static int max98090_resume(struct device *dev)
+{
+       struct max98090_priv *max98090 = dev_get_drvdata(dev);
+       unsigned int status;
+
+       regcache_mark_dirty(max98090->regmap);
+
+       max98090_reset(max98090);
+
+       /* clear IRQ status */
+       regmap_read(max98090->regmap, M98090_REG_DEVICE_STATUS, &status);
+
+       regcache_sync(max98090->regmap);
+
+       return 0;
+}
+
+static int max98090_suspend(struct device *dev)
+{
+       return 0;
+}
+#endif
+
 static const struct dev_pm_ops max98090_pm = {
        SET_RUNTIME_PM_OPS(max98090_runtime_suspend,
                max98090_runtime_resume, NULL)
+       SET_SYSTEM_SLEEP_PM_OPS(max98090_suspend, max98090_resume)
 };
 
 static const struct i2c_device_id max98090_i2c_id[] = {