Merge tag 'asoc-fix-v6.9-rc2' of https://git.kernel.org/pub/scm/linux/kernel/git...
authorTakashi Iwai <tiwai@suse.de>
Fri, 5 Apr 2024 06:48:12 +0000 (08:48 +0200)
committerTakashi Iwai <tiwai@suse.de>
Fri, 5 Apr 2024 06:48:12 +0000 (08:48 +0200)
ASoC: Fixes for v6.9

A relatively large set of fixes here, the biggest piece of it is a
series correcting some problems with the delay reporting for Intel SOF
cards but there's a bunch of other things.  Everything here is driver
specific except for a fix in the core for an issue with sign extension
handling volume controls.

15 files changed:
include/sound/intel-nhlt.h
include/sound/tas2781-tlv.h
sound/aoa/soundbus/i2sbus/core.c
sound/hda/intel-nhlt.c
sound/oss/dmasound/dmasound_paula.c
sound/pci/emu10k1/emu10k1_callback.c
sound/pci/hda/cs35l41_hda_property.c
sound/pci/hda/cs35l56_hda.c
sound/pci/hda/cs35l56_hda_i2c.c
sound/pci/hda/cs35l56_hda_spi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/tas2781_hda_i2c.c
sound/sh/aica.c
sound/soc/sof/ipc4-topology.c
sound/usb/line6/driver.c

index 53470d6a28d659db09e9e58e85e24ffe5e862db5..24dbe16684ae3349bae5a7f74ac5c80fd16e6211 100644 (file)
@@ -143,6 +143,9 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt,
                             u32 bus_id, u8 link_type, u8 vbps, u8 bps,
                             u8 num_ch, u32 rate, u8 dir, u8 dev_type);
 
+int intel_nhlt_ssp_device_type(struct device *dev, struct nhlt_acpi_table *nhlt,
+                              u8 virtual_bus_id);
+
 #else
 
 static inline struct nhlt_acpi_table *intel_nhlt_init(struct device *dev)
@@ -184,6 +187,13 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt,
        return NULL;
 }
 
+static inline int intel_nhlt_ssp_device_type(struct device *dev,
+                                            struct nhlt_acpi_table *nhlt,
+                                            u8 virtual_bus_id)
+{
+       return -EINVAL;
+}
+
 #endif
 
 #endif
index 4038dd421150a3f03182be5d1f0a503812029c15..1dc59005d241fbe683fb98d62d86e8c04f3708eb 100644 (file)
@@ -15,7 +15,7 @@
 #ifndef __TAS2781_TLV_H__
 #define __TAS2781_TLV_H__
 
-static const DECLARE_TLV_DB_SCALE(dvc_tlv, -10000, 100, 0);
+static const __maybe_unused DECLARE_TLV_DB_SCALE(dvc_tlv, -10000, 100, 0);
 static const DECLARE_TLV_DB_SCALE(amp_vol_tlv, 1100, 50, 0);
 
 #endif
index b8ff5cccd0c811fd76050be0f9cf50efa899a3cc..5431d2c49421067e0185158f9aa3e004f619c91e 100644 (file)
@@ -158,7 +158,7 @@ static int i2sbus_add_dev(struct macio_dev *macio,
        struct device_node *child, *sound = NULL;
        struct resource *r;
        int i, layout = 0, rlen, ok = force;
-       char node_name[6];
+       char node_name[8];
        static const char *rnames[] = { "i2sbus: %pOFn (control)",
                                        "i2sbus: %pOFn (tx)",
                                        "i2sbus: %pOFn (rx)" };
index 696a958d93e9c336dea68748e59685e4c0569ee9..088cff799e0bee5003f8d09ae0cb0087cc46ab33 100644 (file)
@@ -343,3 +343,29 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt,
        return NULL;
 }
 EXPORT_SYMBOL(intel_nhlt_get_endpoint_blob);
+
+int intel_nhlt_ssp_device_type(struct device *dev, struct nhlt_acpi_table *nhlt,
+                              u8 virtual_bus_id)
+{
+       struct nhlt_endpoint *epnt;
+       int i;
+
+       if (!nhlt)
+               return -EINVAL;
+
+       epnt = (struct nhlt_endpoint *)nhlt->desc;
+       for (i = 0; i < nhlt->endpoint_count; i++) {
+               /* for SSP link the virtual bus id is the SSP port number */
+               if (epnt->linktype == NHLT_LINK_SSP &&
+                   epnt->virtual_bus_id == virtual_bus_id) {
+                       dev_dbg(dev, "SSP%d: dev_type=%d\n", virtual_bus_id,
+                               epnt->device_type);
+                       return epnt->device_type;
+               }
+
+               epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length);
+       }
+
+       return -EINVAL;
+}
+EXPORT_SYMBOL(intel_nhlt_ssp_device_type);
index 0ba8f0c4cd99a27aaff1d3b43edd306daf0ad857..3a593da09280dca9e5b59dc96c6c2cb27cac6b6b 100644 (file)
@@ -725,7 +725,13 @@ static void __exit amiga_audio_remove(struct platform_device *pdev)
        dmasound_deinit();
 }
 
-static struct platform_driver amiga_audio_driver = {
+/*
+ * amiga_audio_remove() lives in .exit.text. For drivers registered via
+ * module_platform_driver_probe() this is ok because they cannot get unbound at
+ * runtime. So mark the driver struct with __refdata to prevent modpost
+ * triggering a section mismatch warning.
+ */
+static struct platform_driver amiga_audio_driver __refdata = {
        .remove_new = __exit_p(amiga_audio_remove),
        .driver = {
                .name   = "amiga-audio",
index d36234b88fb4219fec68e3f68103d01ee4c224ab..941bfbf812ed305bbfb368771d66134703ba8bea 100644 (file)
@@ -255,7 +255,7 @@ lookup_voices(struct snd_emux *emu, struct snd_emu10k1 *hw,
                /* check if sample is finished playing (non-looping only) */
                if (bp != best + V_OFF && bp != best + V_FREE &&
                    (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_SINGLESHOT)) {
-                       val = snd_emu10k1_ptr_read(hw, CCCA_CURRADDR, vp->ch) - 64;
+                       val = snd_emu10k1_ptr_read(hw, CCCA_CURRADDR, vp->ch);
                        if (val >= vp->reg.loopstart)
                                bp = best + V_OFF;
                }
@@ -362,7 +362,7 @@ start_voice(struct snd_emux_voice *vp)
 
        map = (hw->silent_page.addr << hw->address_mode) | (hw->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
 
-       addr = vp->reg.start + 64;
+       addr = vp->reg.start;
        temp = vp->reg.parm.filterQ;
        ccca = (temp << 28) | addr;
        if (vp->apitch < 0xe400)
@@ -430,9 +430,6 @@ start_voice(struct snd_emux_voice *vp)
                /* Q & current address (Q 4bit value, MSB) */
                CCCA, ccca,
 
-               /* cache */
-               CCR, REG_VAL_PUT(CCR_CACHEINVALIDSIZE, 64),
-
                /* reset volume */
                VTFT, vtarget | vp->ftarget,
                CVCF, vtarget | CVCF_CURRENTFILTER_MASK,
index 72ec872afb8d27de1d2b23288988bf4a5e4f4b88..8fb688e4141485cdf1d29ba73ed25ddc17a2a936 100644 (file)
@@ -108,7 +108,10 @@ static const struct cs35l41_config cs35l41_config_table[] = {
        { "10431F12", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
        { "10431F1F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 },
        { "10431F62", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
+       { "10433A60", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
        { "17AA386F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 },
+       { "17AA3877", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
+       { "17AA3878", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
        { "17AA38A9", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 2, -1, 0, 0, 0 },
        { "17AA38AB", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 2, -1, 0, 0, 0 },
        { "17AA38B4", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
@@ -496,7 +499,10 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
        { "CSC3551", "10431F12", generic_dsd_config },
        { "CSC3551", "10431F1F", generic_dsd_config },
        { "CSC3551", "10431F62", generic_dsd_config },
+       { "CSC3551", "10433A60", generic_dsd_config },
        { "CSC3551", "17AA386F", generic_dsd_config },
+       { "CSC3551", "17AA3877", generic_dsd_config },
+       { "CSC3551", "17AA3878", generic_dsd_config },
        { "CSC3551", "17AA38A9", generic_dsd_config },
        { "CSC3551", "17AA38AB", generic_dsd_config },
        { "CSC3551", "17AA38B4", generic_dsd_config },
index 41974b3897a723ccd429a8e51032245d35ec2e48..1a3f84599cb584331f9766ca6bd5b00bacaa580d 100644 (file)
@@ -1024,8 +1024,8 @@ int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int hid, int id)
                goto err;
        }
 
-       dev_dbg(cs35l56->base.dev, "DSP system name: '%s', amp name: '%s'\n",
-               cs35l56->system_name, cs35l56->amp_name);
+       dev_info(cs35l56->base.dev, "DSP system name: '%s', amp name: '%s'\n",
+                cs35l56->system_name, cs35l56->amp_name);
 
        regmap_multi_reg_write(cs35l56->base.regmap, cs35l56_hda_dai_config,
                               ARRAY_SIZE(cs35l56_hda_dai_config));
@@ -1045,14 +1045,14 @@ int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int hid, int id)
        pm_runtime_mark_last_busy(cs35l56->base.dev);
        pm_runtime_enable(cs35l56->base.dev);
 
+       cs35l56->base.init_done = true;
+
        ret = component_add(cs35l56->base.dev, &cs35l56_hda_comp_ops);
        if (ret) {
                dev_err(cs35l56->base.dev, "Register component failed: %d\n", ret);
                goto pm_err;
        }
 
-       cs35l56->base.init_done = true;
-
        return 0;
 
 pm_err:
index 13beee807308f1763145cc1f9c1590e427236dc6..40f2f97944d54c916d58279a94f84e6be69b5bba 100644 (file)
@@ -56,10 +56,19 @@ static const struct i2c_device_id cs35l56_hda_i2c_id[] = {
        {}
 };
 
+static const struct acpi_device_id cs35l56_acpi_hda_match[] = {
+       { "CSC3554", 0 },
+       { "CSC3556", 0 },
+       { "CSC3557", 0 },
+       {}
+};
+MODULE_DEVICE_TABLE(acpi, cs35l56_acpi_hda_match);
+
 static struct i2c_driver cs35l56_hda_i2c_driver = {
        .driver = {
-               .name           = "cs35l56-hda",
-               .pm             = &cs35l56_hda_pm_ops,
+               .name             = "cs35l56-hda",
+               .acpi_match_table = cs35l56_acpi_hda_match,
+               .pm               = &cs35l56_hda_pm_ops,
        },
        .id_table       = cs35l56_hda_i2c_id,
        .probe          = cs35l56_hda_i2c_probe,
index a3b2fa76663d3685cf404e59785cdc00c502e493..7f02155fe61e3cd529e4c688bf6d734848baf45d 100644 (file)
@@ -56,10 +56,19 @@ static const struct spi_device_id cs35l56_hda_spi_id[] = {
        {}
 };
 
+static const struct acpi_device_id cs35l56_acpi_hda_match[] = {
+       { "CSC3554", 0 },
+       { "CSC3556", 0 },
+       { "CSC3557", 0 },
+       {}
+};
+MODULE_DEVICE_TABLE(acpi, cs35l56_acpi_hda_match);
+
 static struct spi_driver cs35l56_hda_spi_driver = {
        .driver = {
-               .name           = "cs35l56-hda",
-               .pm             = &cs35l56_hda_pm_ops,
+               .name             = "cs35l56-hda",
+               .acpi_match_table = cs35l56_acpi_hda_match,
+               .pm               = &cs35l56_hda_pm_ops,
        },
        .id_table       = cs35l56_hda_spi_id,
        .probe          = cs35l56_hda_spi_probe,
index a17c36a36aa5375fd8295911a2ffc707cb14263e..cdcb28aa9d7bf028d429aeea0016cec7c6bc0c22 100644 (file)
@@ -6875,11 +6875,38 @@ static void alc287_fixup_legion_16ithg6_speakers(struct hda_codec *cdc, const st
        comp_generic_fixup(cdc, action, "i2c", "CLSA0101", "-%s:00-cs35l41-hda.%d", 2);
 }
 
+static void cs35l56_fixup_i2c_two(struct hda_codec *cdc, const struct hda_fixup *fix, int action)
+{
+       comp_generic_fixup(cdc, action, "i2c", "CSC3556", "-%s:00-cs35l56-hda.%d", 2);
+}
+
+static void cs35l56_fixup_i2c_four(struct hda_codec *cdc, const struct hda_fixup *fix, int action)
+{
+       comp_generic_fixup(cdc, action, "i2c", "CSC3556", "-%s:00-cs35l56-hda.%d", 4);
+}
+
+static void cs35l56_fixup_spi_two(struct hda_codec *cdc, const struct hda_fixup *fix, int action)
+{
+       comp_generic_fixup(cdc, action, "spi", "CSC3556", "-%s:00-cs35l56-hda.%d", 2);
+}
+
 static void cs35l56_fixup_spi_four(struct hda_codec *cdc, const struct hda_fixup *fix, int action)
 {
        comp_generic_fixup(cdc, action, "spi", "CSC3556", "-%s:00-cs35l56-hda.%d", 4);
 }
 
+static void alc285_fixup_asus_ga403u(struct hda_codec *cdc, const struct hda_fixup *fix, int action)
+{
+       /*
+        * The same SSID has been re-used in different hardware, they have
+        * different codecs and the newer GA403U has a ALC285.
+        */
+       if (cdc->core.vendor_id == 0x10ec0285)
+               cs35l56_fixup_i2c_two(cdc, fix, action);
+       else
+               alc_fixup_inv_dmic(cdc, fix, action);
+}
+
 static void tas2781_fixup_i2c(struct hda_codec *cdc,
        const struct hda_fixup *fix, int action)
 {
@@ -7436,6 +7463,10 @@ enum {
        ALC256_FIXUP_ACER_SFG16_MICMUTE_LED,
        ALC256_FIXUP_HEADPHONE_AMP_VOL,
        ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX,
+       ALC285_FIXUP_CS35L56_SPI_2,
+       ALC285_FIXUP_CS35L56_I2C_2,
+       ALC285_FIXUP_CS35L56_I2C_4,
+       ALC285_FIXUP_ASUS_GA403U,
 };
 
 /* A special fixup for Lenovo C940 and Yoga Duet 7;
@@ -9643,6 +9674,22 @@ static const struct hda_fixup alc269_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc245_fixup_hp_spectre_x360_eu0xxx,
        },
+       [ALC285_FIXUP_CS35L56_SPI_2] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = cs35l56_fixup_spi_two,
+       },
+       [ALC285_FIXUP_CS35L56_I2C_2] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = cs35l56_fixup_i2c_two,
+       },
+       [ALC285_FIXUP_CS35L56_I2C_4] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = cs35l56_fixup_i2c_four,
+       },
+       [ALC285_FIXUP_ASUS_GA403U] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc285_fixup_asus_ga403u,
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -10096,7 +10143,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1a83, "ASUS UM5302LA", ALC294_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x1043, 0x1a8f, "ASUS UX582ZS", ALC245_FIXUP_CS35L41_SPI_2),
        SND_PCI_QUIRK(0x1043, 0x1b11, "ASUS UX431DA", ALC294_FIXUP_ASUS_COEF_1B),
-       SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
+       SND_PCI_QUIRK(0x1043, 0x1b13, "ASUS U41SV/GA403U", ALC285_FIXUP_ASUS_GA403U),
        SND_PCI_QUIRK(0x1043, 0x1b93, "ASUS G614JVR/JIR", ALC245_FIXUP_CS35L41_SPI_2),
        SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1043, 0x1c03, "ASUS UM3406HA", ALC287_FIXUP_CS35L41_I2C_2),
@@ -10104,6 +10151,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1c33, "ASUS UX5304MA", ALC245_FIXUP_CS35L41_SPI_2),
        SND_PCI_QUIRK(0x1043, 0x1c43, "ASUS UX8406MA", ALC245_FIXUP_CS35L41_SPI_2),
        SND_PCI_QUIRK(0x1043, 0x1c62, "ASUS GU603", ALC289_FIXUP_ASUS_GA401),
+       SND_PCI_QUIRK(0x1043, 0x1c63, "ASUS GU605M", ALC285_FIXUP_CS35L56_SPI_2),
        SND_PCI_QUIRK(0x1043, 0x1c92, "ASUS ROG Strix G15", ALC285_FIXUP_ASUS_G533Z_PINS),
        SND_PCI_QUIRK(0x1043, 0x1c9f, "ASUS G614JU/JV/JI", ALC285_FIXUP_ASUS_HEADSET_MIC),
        SND_PCI_QUIRK(0x1043, 0x1caf, "ASUS G634JY/JZ/JI/JG", ALC285_FIXUP_ASUS_SPI_REAR_SPEAKERS),
@@ -10115,11 +10163,14 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401),
        SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE),
        SND_PCI_QUIRK(0x1043, 0x1da2, "ASUS UP6502ZA/ZD", ALC245_FIXUP_CS35L41_SPI_2),
+       SND_PCI_QUIRK(0x1043, 0x1df3, "ASUS UM5606", ALC285_FIXUP_CS35L56_I2C_4),
        SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402ZA", ALC245_FIXUP_CS35L41_SPI_2),
        SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502),
        SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS),
        SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS),
+       SND_PCI_QUIRK(0x1043, 0x1e63, "ASUS H7606W", ALC285_FIXUP_CS35L56_I2C_2),
+       SND_PCI_QUIRK(0x1043, 0x1e83, "ASUS GA605W", ALC285_FIXUP_CS35L56_I2C_2),
        SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
        SND_PCI_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401),
@@ -10133,7 +10184,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x3a30, "ASUS G814JVR/JIR", ALC245_FIXUP_CS35L41_SPI_2),
        SND_PCI_QUIRK(0x1043, 0x3a40, "ASUS G814JZR", ALC245_FIXUP_CS35L41_SPI_2),
        SND_PCI_QUIRK(0x1043, 0x3a50, "ASUS G834JYR/JZR", ALC245_FIXUP_CS35L41_SPI_2),
-       SND_PCI_QUIRK(0x1043, 0x3a60, "ASUS G634JYR/JZR", ALC245_FIXUP_CS35L41_SPI_2),
+       SND_PCI_QUIRK(0x1043, 0x3a60, "ASUS G634JYR/JZR", ALC285_FIXUP_ASUS_SPI_REAR_SPEAKERS),
        SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
@@ -10159,7 +10210,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x10ec, 0x1254, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
        SND_PCI_QUIRK(0x10ec, 0x12cc, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
        SND_PCI_QUIRK(0x10ec, 0x12f6, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
-       SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE),
+       SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
        SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
        SND_PCI_QUIRK(0x144d, 0xc169, "Samsung Notebook 9 Pen (NP930SBE-K01US)", ALC298_FIXUP_SAMSUNG_AMP),
        SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_AMP),
@@ -10333,6 +10384,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
        SND_PCI_QUIRK(0x17aa, 0x386f, "Legion 7i 16IAX7", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x17aa, 0x3870, "Lenovo Yoga 7 14ARB7", ALC287_FIXUP_YOGA7_14ARB7_I2C),
+       SND_PCI_QUIRK(0x17aa, 0x3877, "Lenovo Legion 7 Slim 16ARHA7", ALC287_FIXUP_CS35L41_I2C_2),
+       SND_PCI_QUIRK(0x17aa, 0x3878, "Lenovo Legion 7 Slim 16ARHA7", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x17aa, 0x387d, "Yoga S780-16 pro Quad AAC", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x387e, "Yoga S780-16 pro Quad YC", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x3881, "YB9 dual power mode2 YC", ALC287_FIXUP_TAS2781_I2C),
@@ -10403,6 +10456,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1d05, 0x1147, "TongFang GMxTGxx", ALC269_FIXUP_NO_SHUTUP),
        SND_PCI_QUIRK(0x1d05, 0x115c, "TongFang GMxTGxx", ALC269_FIXUP_NO_SHUTUP),
        SND_PCI_QUIRK(0x1d05, 0x121b, "TongFang GMxAGxx", ALC269_FIXUP_NO_SHUTUP),
+       SND_PCI_QUIRK(0x1d05, 0x1387, "TongFang GMxIXxx", ALC2XX_FIXUP_HEADSET_MIC),
        SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
        SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
index 4475cea8e9f70382113c3e6f496eebc854c92b40..48dae3339305048fca2262821e5ebfea6bcf237a 100644 (file)
@@ -89,7 +89,7 @@ struct tas2781_hda {
        struct snd_kcontrol *dsp_prog_ctl;
        struct snd_kcontrol *dsp_conf_ctl;
        struct snd_kcontrol *prof_ctl;
-       struct snd_kcontrol *snd_ctls[3];
+       struct snd_kcontrol *snd_ctls[2];
 };
 
 static int tas2781_get_i2c_res(struct acpi_resource *ares, void *data)
@@ -161,8 +161,6 @@ static void tas2781_hda_playback_hook(struct device *dev, int action)
                pm_runtime_put_autosuspend(dev);
                break;
        default:
-               dev_dbg(tas_hda->dev, "Playback action not supported: %d\n",
-                       action);
                break;
        }
 }
@@ -185,8 +183,15 @@ static int tasdevice_get_profile_id(struct snd_kcontrol *kcontrol,
 {
        struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
 
+       mutex_lock(&tas_priv->codec_lock);
+
        ucontrol->value.integer.value[0] = tas_priv->rcabin.profile_cfg_id;
 
+       dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n",
+               __func__, kcontrol->id.name, tas_priv->rcabin.profile_cfg_id);
+
+       mutex_unlock(&tas_priv->codec_lock);
+
        return 0;
 }
 
@@ -200,11 +205,19 @@ static int tasdevice_set_profile_id(struct snd_kcontrol *kcontrol,
 
        val = clamp(nr_profile, 0, max);
 
+       mutex_lock(&tas_priv->codec_lock);
+
+       dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n",
+               __func__, kcontrol->id.name,
+               tas_priv->rcabin.profile_cfg_id, val);
+
        if (tas_priv->rcabin.profile_cfg_id != val) {
                tas_priv->rcabin.profile_cfg_id = val;
                ret = 1;
        }
 
+       mutex_unlock(&tas_priv->codec_lock);
+
        return ret;
 }
 
@@ -241,8 +254,15 @@ static int tasdevice_program_get(struct snd_kcontrol *kcontrol,
 {
        struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
 
+       mutex_lock(&tas_priv->codec_lock);
+
        ucontrol->value.integer.value[0] = tas_priv->cur_prog;
 
+       dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n",
+               __func__, kcontrol->id.name, tas_priv->cur_prog);
+
+       mutex_unlock(&tas_priv->codec_lock);
+
        return 0;
 }
 
@@ -257,11 +277,18 @@ static int tasdevice_program_put(struct snd_kcontrol *kcontrol,
 
        val = clamp(nr_program, 0, max);
 
+       mutex_lock(&tas_priv->codec_lock);
+
+       dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n",
+               __func__, kcontrol->id.name, tas_priv->cur_prog, val);
+
        if (tas_priv->cur_prog != val) {
                tas_priv->cur_prog = val;
                ret = 1;
        }
 
+       mutex_unlock(&tas_priv->codec_lock);
+
        return ret;
 }
 
@@ -270,8 +297,15 @@ static int tasdevice_config_get(struct snd_kcontrol *kcontrol,
 {
        struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
 
+       mutex_lock(&tas_priv->codec_lock);
+
        ucontrol->value.integer.value[0] = tas_priv->cur_conf;
 
+       dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n",
+               __func__, kcontrol->id.name, tas_priv->cur_conf);
+
+       mutex_unlock(&tas_priv->codec_lock);
+
        return 0;
 }
 
@@ -286,54 +320,39 @@ static int tasdevice_config_put(struct snd_kcontrol *kcontrol,
 
        val = clamp(nr_config, 0, max);
 
+       mutex_lock(&tas_priv->codec_lock);
+
+       dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n",
+               __func__, kcontrol->id.name, tas_priv->cur_conf, val);
+
        if (tas_priv->cur_conf != val) {
                tas_priv->cur_conf = val;
                ret = 1;
        }
 
+       mutex_unlock(&tas_priv->codec_lock);
+
        return ret;
 }
 
-/*
- * tas2781_digital_getvol - get the volum control
- * @kcontrol: control pointer
- * @ucontrol: User data
- * Customer Kcontrol for tas2781 is primarily for regmap booking, paging
- * depends on internal regmap mechanism.
- * tas2781 contains book and page two-level register map, especially
- * book switching will set the register BXXP00R7F, after switching to the
- * correct book, then leverage the mechanism for paging to access the
- * register.
- */
-static int tas2781_digital_getvol(struct snd_kcontrol *kcontrol,
+static int tas2781_amp_getvol(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
        struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
+       int ret;
 
-       return tasdevice_digital_getvol(tas_priv, ucontrol, mc);
-}
+       mutex_lock(&tas_priv->codec_lock);
 
-static int tas2781_amp_getvol(struct snd_kcontrol *kcontrol,
-       struct snd_ctl_elem_value *ucontrol)
-{
-       struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
-       struct soc_mixer_control *mc =
-               (struct soc_mixer_control *)kcontrol->private_value;
+       ret = tasdevice_amp_getvol(tas_priv, ucontrol, mc);
 
-       return tasdevice_amp_getvol(tas_priv, ucontrol, mc);
-}
+       dev_dbg(tas_priv->dev, "%s: kcontrol %s: %ld\n",
+               __func__, kcontrol->id.name, ucontrol->value.integer.value[0]);
 
-static int tas2781_digital_putvol(struct snd_kcontrol *kcontrol,
-       struct snd_ctl_elem_value *ucontrol)
-{
-       struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
-       struct soc_mixer_control *mc =
-               (struct soc_mixer_control *)kcontrol->private_value;
+       mutex_unlock(&tas_priv->codec_lock);
 
-       /* The check of the given value is in tasdevice_digital_putvol. */
-       return tasdevice_digital_putvol(tas_priv, ucontrol, mc);
+       return ret;
 }
 
 static int tas2781_amp_putvol(struct snd_kcontrol *kcontrol,
@@ -342,9 +361,19 @@ static int tas2781_amp_putvol(struct snd_kcontrol *kcontrol,
        struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
+       int ret;
+
+       mutex_lock(&tas_priv->codec_lock);
+
+       dev_dbg(tas_priv->dev, "%s: kcontrol %s: -> %ld\n",
+               __func__, kcontrol->id.name, ucontrol->value.integer.value[0]);
 
        /* The check of the given value is in tasdevice_amp_putvol. */
-       return tasdevice_amp_putvol(tas_priv, ucontrol, mc);
+       ret = tasdevice_amp_putvol(tas_priv, ucontrol, mc);
+
+       mutex_unlock(&tas_priv->codec_lock);
+
+       return ret;
 }
 
 static int tas2781_force_fwload_get(struct snd_kcontrol *kcontrol,
@@ -352,9 +381,13 @@ static int tas2781_force_fwload_get(struct snd_kcontrol *kcontrol,
 {
        struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
 
+       mutex_lock(&tas_priv->codec_lock);
+
        ucontrol->value.integer.value[0] = (int)tas_priv->force_fwload_status;
-       dev_dbg(tas_priv->dev, "%s : Force FWload %s\n", __func__,
-                       tas_priv->force_fwload_status ? "ON" : "OFF");
+       dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n",
+               __func__, kcontrol->id.name, tas_priv->force_fwload_status);
+
+       mutex_unlock(&tas_priv->codec_lock);
 
        return 0;
 }
@@ -365,14 +398,20 @@ static int tas2781_force_fwload_put(struct snd_kcontrol *kcontrol,
        struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
        bool change, val = (bool)ucontrol->value.integer.value[0];
 
+       mutex_lock(&tas_priv->codec_lock);
+
+       dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n",
+               __func__, kcontrol->id.name,
+               tas_priv->force_fwload_status, val);
+
        if (tas_priv->force_fwload_status == val)
                change = false;
        else {
                change = true;
                tas_priv->force_fwload_status = val;
        }
-       dev_dbg(tas_priv->dev, "%s : Force FWload %s\n", __func__,
-               tas_priv->force_fwload_status ? "ON" : "OFF");
+
+       mutex_unlock(&tas_priv->codec_lock);
 
        return change;
 }
@@ -381,9 +420,6 @@ static const struct snd_kcontrol_new tas2781_snd_controls[] = {
        ACARD_SINGLE_RANGE_EXT_TLV("Speaker Analog Gain", TAS2781_AMP_LEVEL,
                1, 0, 20, 0, tas2781_amp_getvol,
                tas2781_amp_putvol, amp_vol_tlv),
-       ACARD_SINGLE_RANGE_EXT_TLV("Speaker Digital Gain", TAS2781_DVC_LVL,
-               0, 0, 200, 1, tas2781_digital_getvol,
-               tas2781_digital_putvol, dvc_tlv),
        ACARD_SINGLE_BOOL_EXT("Speaker Force Firmware Load", 0,
                tas2781_force_fwload_get, tas2781_force_fwload_put),
 };
index 320ac792c7fe2459b10024afd05719af2082772d..3182c634464d4288dd1bb8faca39481b5806e85e 100644 (file)
@@ -278,7 +278,8 @@ static void run_spu_dma(struct work_struct *work)
                dreamcastcard->clicks++;
                if (unlikely(dreamcastcard->clicks >= AICA_PERIOD_NUMBER))
                        dreamcastcard->clicks %= AICA_PERIOD_NUMBER;
-               mod_timer(&dreamcastcard->timer, jiffies + 1);
+               if (snd_pcm_running(dreamcastcard->substream))
+                       mod_timer(&dreamcastcard->timer, jiffies + 1);
        }
 }
 
@@ -290,6 +291,8 @@ static void aica_period_elapsed(struct timer_list *t)
        /*timer function - so cannot sleep */
        int play_period;
        struct snd_pcm_runtime *runtime;
+       if (!snd_pcm_running(substream))
+               return;
        runtime = substream->runtime;
        dreamcastcard = substream->pcm->private_data;
        /* Have we played out an additional period? */
@@ -350,12 +353,19 @@ static int snd_aicapcm_pcm_open(struct snd_pcm_substream
        return 0;
 }
 
+static int snd_aicapcm_pcm_sync_stop(struct snd_pcm_substream *substream)
+{
+       struct snd_card_aica *dreamcastcard = substream->pcm->private_data;
+
+       del_timer_sync(&dreamcastcard->timer);
+       cancel_work_sync(&dreamcastcard->spu_dma_work);
+       return 0;
+}
+
 static int snd_aicapcm_pcm_close(struct snd_pcm_substream
                                 *substream)
 {
        struct snd_card_aica *dreamcastcard = substream->pcm->private_data;
-       flush_work(&(dreamcastcard->spu_dma_work));
-       del_timer(&dreamcastcard->timer);
        dreamcastcard->substream = NULL;
        kfree(dreamcastcard->channel);
        spu_disable();
@@ -401,6 +411,7 @@ static const struct snd_pcm_ops snd_aicapcm_playback_ops = {
        .prepare = snd_aicapcm_pcm_prepare,
        .trigger = snd_aicapcm_pcm_trigger,
        .pointer = snd_aicapcm_pcm_pointer,
+       .sync_stop = snd_aicapcm_pcm_sync_stop,
 };
 
 /* TO DO: set up to handle more than one pcm instance */
index bb4cf6dd1e1894ec39d1602579ff55e23d162b52..5cca058421260978dd18e992b09dfff58b44bbdb 100644 (file)
@@ -1376,6 +1376,7 @@ static int snd_sof_get_nhlt_endpoint_data(struct snd_sof_dev *sdev, struct snd_s
        int sample_rate, channel_count;
        int bit_depth, ret;
        u32 nhlt_type;
+       int dev_type = 0;
 
        /* convert to NHLT type */
        switch (linktype) {
@@ -1391,18 +1392,30 @@ static int snd_sof_get_nhlt_endpoint_data(struct snd_sof_dev *sdev, struct snd_s
                                                   &bit_depth);
                if (ret < 0)
                        return ret;
+
+               /*
+                * We need to know the type of the external device attached to a SSP
+                * port to retrieve the blob from NHLT. However, device type is not
+                * specified in topology.
+                * Query the type for the port and then pass that information back
+                * to the blob lookup function.
+                */
+               dev_type = intel_nhlt_ssp_device_type(sdev->dev, ipc4_data->nhlt,
+                                                     dai_index);
+               if (dev_type < 0)
+                       return dev_type;
                break;
        default:
                return 0;
        }
 
-       dev_dbg(sdev->dev, "dai index %d nhlt type %d direction %d\n",
-               dai_index, nhlt_type, dir);
+       dev_dbg(sdev->dev, "dai index %d nhlt type %d direction %d dev type %d\n",
+               dai_index, nhlt_type, dir, dev_type);
 
        /* find NHLT blob with matching params */
        cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt, dai_index, nhlt_type,
                                           bit_depth, bit_depth, channel_count, sample_rate,
-                                          dir, 0);
+                                          dir, dev_type);
 
        if (!cfg) {
                dev_err(sdev->dev,
index b67617b68e509d2c86d78058f7796a64aab00f41..f4437015d43a7500b809a303f175b211662d500f 100644 (file)
@@ -202,7 +202,7 @@ int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer,
        struct urb *urb;
 
        /* create message: */
-       msg = kmalloc(sizeof(struct message), GFP_ATOMIC);
+       msg = kzalloc(sizeof(struct message), GFP_ATOMIC);
        if (msg == NULL)
                return -ENOMEM;
 
@@ -688,7 +688,7 @@ static int line6_init_cap_control(struct usb_line6 *line6)
        int ret;
 
        /* initialize USB buffers: */
-       line6->buffer_listen = kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);
+       line6->buffer_listen = kzalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);
        if (!line6->buffer_listen)
                return -ENOMEM;
 
@@ -697,7 +697,7 @@ static int line6_init_cap_control(struct usb_line6 *line6)
                return -ENOMEM;
 
        if (line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI) {
-               line6->buffer_message = kmalloc(LINE6_MIDI_MESSAGE_MAXLEN, GFP_KERNEL);
+               line6->buffer_message = kzalloc(LINE6_MIDI_MESSAGE_MAXLEN, GFP_KERNEL);
                if (!line6->buffer_message)
                        return -ENOMEM;