Merge branch 'for-linus' into for-next
authorTakashi Iwai <tiwai@suse.de>
Mon, 14 Dec 2020 08:05:24 +0000 (09:05 +0100)
committerTakashi Iwai <tiwai@suse.de>
Mon, 14 Dec 2020 08:05:29 +0000 (09:05 +0100)
Signed-off-by: Takashi Iwai <tiwai@suse.de>
12 files changed:
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_generic.h
sound/pci/hda/patch_realtek.c
sound/soc/codecs/rt5682.c
sound/soc/codecs/wm_adsp.c
sound/soc/intel/boards/bytcr_rt5640.c
sound/soc/qcom/lpass-cpu.c
sound/soc/qcom/lpass-lpaif-reg.h
sound/soc/qcom/lpass-platform.c
sound/soc/qcom/lpass.h
sound/usb/mixer_us16x08.c
sound/usb/stream.c

index bbb1748..8060cc8 100644 (file)
@@ -1364,16 +1364,20 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs,
                struct nid_path *path;
                hda_nid_t pin = pins[i];
 
-               path = snd_hda_get_path_from_idx(codec, path_idx[i]);
-               if (path) {
-                       badness += assign_out_path_ctls(codec, path);
-                       continue;
+               if (!spec->obey_preferred_dacs) {
+                       path = snd_hda_get_path_from_idx(codec, path_idx[i]);
+                       if (path) {
+                               badness += assign_out_path_ctls(codec, path);
+                               continue;
+                       }
                }
 
                dacs[i] = get_preferred_dac(codec, pin);
                if (dacs[i]) {
                        if (is_dac_already_used(codec, dacs[i]))
                                badness += bad->shared_primary;
+               } else if (spec->obey_preferred_dacs) {
+                       badness += BAD_NO_PRIMARY_DAC;
                }
 
                if (!dacs[i])
index a43f0bb..0886bc8 100644 (file)
@@ -237,6 +237,7 @@ struct hda_gen_spec {
        unsigned int power_down_unused:1; /* power down unused widgets */
        unsigned int dac_min_mute:1; /* minimal = mute for DACs */
        unsigned int suppress_vmaster:1; /* don't create vmaster kctls */
+       unsigned int obey_preferred_dacs:1; /* obey preferred_dacs assignment */
 
        /* other internal flags */
        unsigned int no_analog:1; /* digital I/O only */
index 739dbaf..41cc640 100644 (file)
@@ -119,6 +119,7 @@ struct alc_spec {
        unsigned int no_shutup_pins:1;
        unsigned int ultra_low_power:1;
        unsigned int has_hs_key:1;
+       unsigned int no_internal_mic_pin:1;
 
        /* for PLL fix */
        hda_nid_t pll_nid;
@@ -445,6 +446,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
                        alc_update_coef_idx(codec, 0x7, 1<<5, 0);
                break;
        case 0x10ec0892:
+       case 0x10ec0897:
                alc_update_coef_idx(codec, 0x7, 1<<5, 0);
                break;
        case 0x10ec0899:
@@ -3102,6 +3104,7 @@ static void alc_disable_headset_jack_key(struct hda_codec *codec)
        case 0x10ec0215:
        case 0x10ec0225:
        case 0x10ec0285:
+       case 0x10ec0287:
        case 0x10ec0295:
        case 0x10ec0289:
        case 0x10ec0299:
@@ -3128,6 +3131,7 @@ static void alc_enable_headset_jack_key(struct hda_codec *codec)
        case 0x10ec0215:
        case 0x10ec0225:
        case 0x10ec0285:
+       case 0x10ec0287:
        case 0x10ec0295:
        case 0x10ec0289:
        case 0x10ec0299:
@@ -4523,6 +4527,7 @@ static const struct coef_fw alc225_pre_hsmode[] = {
 
 static void alc_headset_mode_unplugged(struct hda_codec *codec)
 {
+       struct alc_spec *spec = codec->spec;
        static const struct coef_fw coef0255[] = {
                WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
                WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
@@ -4597,6 +4602,11 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
                {}
        };
 
+       if (spec->no_internal_mic_pin) {
+               alc_update_coef_idx(codec, 0x45, 0xf<<12 | 1<<10, 5<<12);
+               return;
+       }
+
        switch (codec->core.vendor_id) {
        case 0x10ec0255:
                alc_process_coef_fw(codec, coef0255);
@@ -5163,6 +5173,11 @@ static void alc_determine_headset_type(struct hda_codec *codec)
                {}
        };
 
+       if (spec->no_internal_mic_pin) {
+               alc_update_coef_idx(codec, 0x45, 0xf<<12 | 1<<10, 5<<12);
+               return;
+       }
+
        switch (codec->core.vendor_id) {
        case 0x10ec0255:
                alc_process_coef_fw(codec, coef0255);
@@ -6014,6 +6029,21 @@ static void alc274_fixup_bind_dacs(struct hda_codec *codec,
        codec->power_save_node = 0;
 }
 
+/* avoid DAC 0x06 for bass speaker 0x17; it has no volume control */
+static void alc289_fixup_asus_ga401(struct hda_codec *codec,
+                                   const struct hda_fixup *fix, int action)
+{
+       static const hda_nid_t preferred_pairs[] = {
+               0x14, 0x02, 0x17, 0x02, 0x21, 0x03, 0
+       };
+       struct alc_spec *spec = codec->spec;
+
+       if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+               spec->gen.preferred_dacs = preferred_pairs;
+               spec->gen.obey_preferred_dacs = 1;
+       }
+}
+
 /* The DAC of NID 0x3 will introduce click/pop noise on headphones, so invalidate it */
 static void alc285_fixup_invalidate_dacs(struct hda_codec *codec,
                              const struct hda_fixup *fix, int action)
@@ -6121,6 +6151,23 @@ static void alc274_fixup_hp_headset_mic(struct hda_codec *codec,
        }
 }
 
+static void alc_fixup_no_int_mic(struct hda_codec *codec,
+                                   const struct hda_fixup *fix, int action)
+{
+       struct alc_spec *spec = codec->spec;
+
+       switch (action) {
+       case HDA_FIXUP_ACT_PRE_PROBE:
+               /* Mic RING SLEEVE swap for combo jack */
+               alc_update_coef_idx(codec, 0x45, 0xf<<12 | 1<<10, 5<<12);
+               spec->no_internal_mic_pin = true;
+               break;
+       case HDA_FIXUP_ACT_INIT:
+               alc_combo_jack_hp_jd_restart(codec);
+               break;
+       }
+}
+
 /* for hda_fixup_thinkpad_acpi() */
 #include "thinkpad_helper.c"
 
@@ -6320,6 +6367,7 @@ enum {
        ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK,
        ALC287_FIXUP_HP_GPIO_LED,
        ALC256_FIXUP_HP_HEADSET_MIC,
+       ALC236_FIXUP_DELL_AIO_HEADSET_MIC,
 };
 
 static const struct hda_fixup alc269_fixups[] = {
@@ -7569,11 +7617,10 @@ static const struct hda_fixup alc269_fixups[] = {
                .chain_id = ALC269_FIXUP_HEADSET_MIC
        },
        [ALC289_FIXUP_ASUS_GA401] = {
-               .type = HDA_FIXUP_PINS,
-               .v.pins = (const struct hda_pintbl[]) {
-                       { 0x19, 0x03a11020 }, /* headset mic with jack detect */
-                       { }
-               },
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc289_fixup_asus_ga401,
+               .chained = true,
+               .chain_id = ALC289_FIXUP_ASUS_GA502,
        },
        [ALC289_FIXUP_ASUS_GA502] = {
                .type = HDA_FIXUP_PINS,
@@ -7697,7 +7744,7 @@ static const struct hda_fixup alc269_fixups[] = {
                        { }
                },
                .chained = true,
-               .chain_id = ALC289_FIXUP_ASUS_GA401
+               .chain_id = ALC289_FIXUP_ASUS_GA502
        },
        [ALC274_FIXUP_HP_MIC] = {
                .type = HDA_FIXUP_VERBS,
@@ -7738,6 +7785,12 @@ static const struct hda_fixup alc269_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc274_fixup_hp_headset_mic,
        },
+       [ALC236_FIXUP_DELL_AIO_HEADSET_MIC] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc_fixup_no_int_mic,
+               .chained = true,
+               .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -7815,6 +7868,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x097d, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
        SND_PCI_QUIRK(0x1028, 0x098d, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x09bf, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x0a2e, "Dell", ALC236_FIXUP_DELL_AIO_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1028, 0x0a30, "Dell", ALC236_FIXUP_DELL_AIO_HEADSET_MIC),
        SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
@@ -7881,6 +7936,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
        SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
        SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
+       SND_PCI_QUIRK(0x103c, 0x827f, "HP x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
        SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
@@ -7902,6 +7958,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1043, 0x1271, "ASUS X430UN", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
@@ -7922,6 +7979,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
        SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+       SND_PCI_QUIRK(0x1043, 0x125e, "ASUS Q524UQK", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
        SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE),
        SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502),
@@ -8353,6 +8411,8 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
                {0x19, 0x02a11020},
                {0x1a, 0x02a11030},
                {0x21, 0x0221101f}),
+       SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC236_FIXUP_DELL_AIO_HEADSET_MIC,
+               {0x21, 0x02211010}),
        SND_HDA_PIN_QUIRK(0x10ec0236, 0x103c, "HP", ALC256_FIXUP_HP_HEADSET_MIC,
                {0x14, 0x90170110},
                {0x19, 0x02a11020},
@@ -8517,11 +8577,20 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
                {0x12, 0x90a60130},
                {0x19, 0x03a11020},
                {0x21, 0x0321101f}),
+       SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK,
+               {0x14, 0x90170110},
+               {0x19, 0x04a11040},
+               {0x21, 0x04211020}),
        SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
                {0x12, 0x90a60130},
                {0x14, 0x90170110},
                {0x19, 0x04a11040},
                {0x21, 0x04211020}),
+       SND_HDA_PIN_QUIRK(0x10ec0287, 0x17aa, "Lenovo", ALC285_FIXUP_THINKPAD_HEADSET_JACK,
+               {0x14, 0x90170110},
+               {0x17, 0x90170111},
+               {0x19, 0x03a11030},
+               {0x21, 0x03211020}),
        SND_HDA_PIN_QUIRK(0x10ec0286, 0x1025, "Acer", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
                {0x12, 0x90a60130},
                {0x17, 0x90170110},
@@ -8585,6 +8654,9 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
        SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
                ALC292_STANDARD_PINS,
                {0x13, 0x90a60140}),
+       SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_HPE,
+               {0x17, 0x90170110},
+               {0x21, 0x04211020}),
        SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_MIC,
                {0x14, 0x90170110},
                {0x1b, 0x90a70130},
@@ -10171,6 +10243,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
        HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
        HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
        HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
+       HDA_CODEC_ENTRY(0x10ec0897, "ALC897", patch_alc662),
        HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
        HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
        HDA_CODEC_ENTRY(0x10ec0b00, "ALCS1200A", patch_alc882),
index a9acce7..d987817 100644 (file)
@@ -43,6 +43,7 @@ static const struct reg_sequence patch_list[] = {
        {RT5682_DAC_ADC_DIG_VOL1, 0xa020},
        {RT5682_I2C_CTRL, 0x000f},
        {RT5682_PLL2_INTERNAL, 0x8266},
+       {RT5682_SAR_IL_CMD_3, 0x8365},
 };
 
 void rt5682_apply_patch_list(struct rt5682_priv *rt5682, struct device *dev)
index bcf18bf..e61d004 100644 (file)
@@ -1937,6 +1937,7 @@ static int wm_adsp_load(struct wm_adsp *dsp)
                        mem = wm_adsp_find_region(dsp, type);
                        if (!mem) {
                                adsp_err(dsp, "No region of type: %x\n", type);
+                               ret = -EINVAL;
                                goto out_fw;
                        }
 
index 9dadf65..f790514 100644 (file)
@@ -520,10 +520,10 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
                .driver_data = (void *)(BYT_RT5640_IN1_MAP |
                                        BYT_RT5640_MCLK_EN),
        },
-       {       /* HP Pavilion x2 10-n000nd */
+       {       /* HP Pavilion x2 10-k0XX, 10-n0XX */
                .matches = {
-                       DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
                },
                .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
                                        BYT_RT5640_JD_SRC_JD2_IN4N |
@@ -532,6 +532,17 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
                                        BYT_RT5640_SSP0_AIF1 |
                                        BYT_RT5640_MCLK_EN),
        },
+       {       /* HP Pavilion x2 10-p0XX */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"),
+               },
+               .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
+                                       BYT_RT5640_JD_SRC_JD1_IN4P |
+                                       BYT_RT5640_OVCD_TH_1500UA |
+                                       BYT_RT5640_OVCD_SF_0P75 |
+                                       BYT_RT5640_MCLK_EN),
+       },
        {       /* HP Stream 7 */
                .matches = {
                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
index 9d17c87..426235a 100644 (file)
@@ -263,28 +263,6 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static int lpass_cpu_daiops_prepare(struct snd_pcm_substream *substream,
-               struct snd_soc_dai *dai)
-{
-       struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
-       struct lpaif_i2sctl *i2sctl = drvdata->i2sctl;
-       unsigned int id = dai->driver->id;
-       int ret;
-
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               ret = regmap_fields_write(i2sctl->spken, id,
-                                        LPAIF_I2SCTL_SPKEN_ENABLE);
-       } else {
-               ret = regmap_fields_write(i2sctl->micen, id,
-                                        LPAIF_I2SCTL_MICEN_ENABLE);
-       }
-
-       if (ret)
-               dev_err(dai->dev, "error writing to i2sctl enable: %d\n", ret);
-
-       return ret;
-}
-
 static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
                int cmd, struct snd_soc_dai *dai)
 {
@@ -292,6 +270,18 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
        struct lpaif_i2sctl *i2sctl = drvdata->i2sctl;
        unsigned int id = dai->driver->id;
        int ret = -EINVAL;
+       unsigned int val = 0;
+
+       ret = regmap_read(drvdata->lpaif_map,
+                               LPAIF_I2SCTL_REG(drvdata->variant, dai->driver->id), &val);
+       if (ret) {
+               dev_err(dai->dev, "error reading from i2sctl reg: %d\n", ret);
+               return ret;
+       }
+       if (val == LPAIF_I2SCTL_RESET_STATE) {
+               dev_err(dai->dev, "error in i2sctl register state\n");
+               return -ENOTRECOVERABLE;
+       }
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
@@ -308,11 +298,14 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
                        dev_err(dai->dev, "error writing to i2sctl reg: %d\n",
                                ret);
 
-               ret = clk_enable(drvdata->mi2s_bit_clk[id]);
-               if (ret) {
-                       dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret);
-                       clk_disable(drvdata->mi2s_osr_clk[id]);
-                       return ret;
+               if (drvdata->bit_clk_state[id] == LPAIF_BIT_CLK_DISABLE) {
+                       ret = clk_enable(drvdata->mi2s_bit_clk[id]);
+                       if (ret) {
+                               dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret);
+                               clk_disable(drvdata->mi2s_osr_clk[id]);
+                               return ret;
+                       }
+                       drvdata->bit_clk_state[id] = LPAIF_BIT_CLK_ENABLE;
                }
 
                break;
@@ -329,7 +322,10 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
                if (ret)
                        dev_err(dai->dev, "error writing to i2sctl reg: %d\n",
                                ret);
-               clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]);
+               if (drvdata->bit_clk_state[id] == LPAIF_BIT_CLK_ENABLE) {
+                       clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]);
+                       drvdata->bit_clk_state[id] = LPAIF_BIT_CLK_DISABLE;
+               }
                break;
        }
 
@@ -341,7 +337,6 @@ const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops = {
        .startup        = lpass_cpu_daiops_startup,
        .shutdown       = lpass_cpu_daiops_shutdown,
        .hw_params      = lpass_cpu_daiops_hw_params,
-       .prepare        = lpass_cpu_daiops_prepare,
        .trigger        = lpass_cpu_daiops_trigger,
 };
 EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_dai_ops);
@@ -459,16 +454,20 @@ static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg)
        struct lpass_variant *v = drvdata->variant;
        int i;
 
+       for (i = 0; i < v->i2s_ports; ++i)
+               if (reg == LPAIF_I2SCTL_REG(v, i))
+                       return true;
        for (i = 0; i < v->irq_ports; ++i)
                if (reg == LPAIF_IRQSTAT_REG(v, i))
                        return true;
 
        for (i = 0; i < v->rdma_channels; ++i)
-               if (reg == LPAIF_RDMACURR_REG(v, i))
+               if (reg == LPAIF_RDMACURR_REG(v, i) || reg == LPAIF_RDMACTL_REG(v, i))
                        return true;
 
        for (i = 0; i < v->wrdma_channels; ++i)
-               if (reg == LPAIF_WRDMACURR_REG(v, i + v->wrdma_channel_start))
+               if (reg == LPAIF_WRDMACURR_REG(v, i + v->wrdma_channel_start) ||
+                       reg == LPAIF_WRDMACTL_REG(v, i + v->wrdma_channel_start))
                        return true;
 
        return false;
@@ -861,6 +860,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
                                PTR_ERR(drvdata->mi2s_bit_clk[dai_id]));
                        return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]);
                }
+               drvdata->bit_clk_state[dai_id] = LPAIF_BIT_CLK_DISABLE;
        }
 
        /* Allocation for i2sctl regmap fields */
index 08f3fe5..4055428 100644 (file)
 #define LPAIF_I2SCTL_BITWIDTH_24       1
 #define LPAIF_I2SCTL_BITWIDTH_32       2
 
+#define LPAIF_BIT_CLK_DISABLE          0
+#define LPAIF_BIT_CLK_ENABLE           1
+
+#define LPAIF_I2SCTL_RESET_STATE       0x003C0004
+#define LPAIF_DMACTL_RESET_STATE       0x00200000
+
+
 /* LPAIF IRQ */
 #define LPAIF_IRQ_REG_ADDR(v, addr, port) \
        (v->irq_reg_base + (addr) + v->irq_reg_stride * (port))
index 7a3fdf8..80b09de 100644 (file)
@@ -110,6 +110,7 @@ static int lpass_platform_pcmops_open(struct snd_soc_component *component,
        struct regmap *map;
        unsigned int dai_id = cpu_dai->driver->id;
 
+       component->id = dai_id;
        data = kzalloc(sizeof(*data), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
@@ -451,19 +452,34 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
        unsigned int reg_irqclr = 0, val_irqclr = 0;
        unsigned int  reg_irqen = 0, val_irqen = 0, val_mask = 0;
        unsigned int dai_id = cpu_dai->driver->id;
+       unsigned int dma_ctrl_reg = 0;
 
        ch = pcm_data->dma_ch;
        if (dir ==  SNDRV_PCM_STREAM_PLAYBACK) {
                id = pcm_data->dma_ch;
-               if (dai_id == LPASS_DP_RX)
+               if (dai_id == LPASS_DP_RX) {
                        dmactl = drvdata->hdmi_rd_dmactl;
-               else
+                       map = drvdata->hdmiif_map;
+               } else {
                        dmactl = drvdata->rd_dmactl;
+                       map = drvdata->lpaif_map;
+               }
        } else {
                dmactl = drvdata->wr_dmactl;
                id = pcm_data->dma_ch - v->wrdma_channel_start;
+               map = drvdata->lpaif_map;
+       }
+       ret = regmap_read(map, LPAIF_DMACTL_REG(v, ch, dir, dai_id), &dma_ctrl_reg);
+       if (ret) {
+               dev_err(soc_runtime->dev, "error reading from rdmactl reg: %d\n", ret);
+               return ret;
        }
 
+       if (dma_ctrl_reg == LPAIF_DMACTL_RESET_STATE ||
+               dma_ctrl_reg == LPAIF_DMACTL_RESET_STATE + 1) {
+               dev_err(soc_runtime->dev, "error in rdmactl register state\n");
+               return -ENOTRECOVERABLE;
+       }
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
        case SNDRV_PCM_TRIGGER_RESUME:
index b4830f3..bccd1a0 100644 (file)
@@ -68,6 +68,7 @@ struct lpass_data {
        unsigned int mi2s_playback_sd_mode[LPASS_MAX_MI2S_PORTS];
        unsigned int mi2s_capture_sd_mode[LPASS_MAX_MI2S_PORTS];
        int hdmi_port_enable;
+       int bit_clk_state[LPASS_MAX_MI2S_PORTS];
 
        /* low-power audio interface (LPAIF) registers */
        void __iomem *lpaif;
index 92b1a6d..bd63a9c 100644 (file)
@@ -607,7 +607,7 @@ static int snd_us16x08_eq_put(struct snd_kcontrol *kcontrol,
 static int snd_us16x08_meter_info(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_info *uinfo)
 {
-       uinfo->count = 1;
+       uinfo->count = 34;
        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
        uinfo->value.integer.max = 0x7FFF;
        uinfo->value.integer.min = 0;
index 7f58c76..ee9aa1d 100644 (file)
@@ -192,16 +192,16 @@ static int usb_chmap_ctl_get(struct snd_kcontrol *kcontrol,
        struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
        struct snd_usb_substream *subs = info->private_data;
        struct snd_pcm_chmap_elem *chmap = NULL;
-       int i;
+       int i = 0;
 
-       memset(ucontrol->value.integer.value, 0,
-              sizeof(ucontrol->value.integer.value));
        if (subs->cur_audiofmt)
                chmap = subs->cur_audiofmt->chmap;
        if (chmap) {
                for (i = 0; i < chmap->channels; i++)
                        ucontrol->value.integer.value[i] = chmap->map[i];
        }
+       for (; i < subs->channels_max; i++)
+               ucontrol->value.integer.value[i] = 0;
        return 0;
 }