]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ALSA: hda: cs35l41: Set Channel Index correctly when system is missing _DSD
authorStefan Binding <sbinding@opensource.cirrus.com>
Fri, 26 Jan 2024 16:40:02 +0000 (16:40 +0000)
committerSasha Levin <sashal@kernel.org>
Tue, 26 Mar 2024 22:17:01 +0000 (18:17 -0400)
[ Upstream commit 135096ebfab656823d0037102a00776f3914fee3 ]

Current method to set Channel Index when the system is missing _DSD
assumes that the channels alternate, which is not guaranteed.
Instead use the same methodology as the main driver does when _DSD
exists.

Fixes: 8c4c216db8fb ("ALSA: hda: cs35l41: Add config table to support many laptops without _DSD")
Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20240126164005.367021-2-sbinding@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
sound/pci/hda/cs35l41_hda_property.c

index e436d4dab317f05c20a8a806f14e07580bfcb2de..86ddaff915de11768f736916fda241aa40b0d135 100644 (file)
@@ -210,6 +210,7 @@ static int generic_dsd_config(struct cs35l41_hda *cs35l41, struct device *physde
        struct spi_device *spi;
        bool dsd_found;
        int ret;
+       int i;
 
        for (cfg = cs35l41_config_table; cfg->ssid; cfg++) {
                if (!strcasecmp(cfg->ssid, cs35l41->acpi_subsystem_id))
@@ -295,16 +296,6 @@ static int generic_dsd_config(struct cs35l41_hda *cs35l41, struct device *physde
                        cs35l41->index = id == 0x40 ? 0 : 1;
        }
 
-       if (cfg->num_amps == 3)
-               /* 3 amps means a center channel, so no duplicate channels */
-               cs35l41->channel_index = 0;
-       else
-               /*
-                * if 4 amps, there are duplicate channels, so they need different indexes
-                * if 2 amps, no duplicate channels, channel_index would be 0
-                */
-               cs35l41->channel_index = cs35l41->index / 2;
-
        cs35l41->reset_gpio = fwnode_gpiod_get_index(acpi_fwnode_handle(cs35l41->dacpi), "reset",
                                                     cs35l41->index, GPIOD_OUT_LOW,
                                                     "cs35l41-reset");
@@ -312,6 +303,11 @@ static int generic_dsd_config(struct cs35l41_hda *cs35l41, struct device *physde
 
        hw_cfg->spk_pos = cfg->channel[cs35l41->index];
 
+       cs35l41->channel_index = 0;
+       for (i = 0; i < cs35l41->index; i++)
+               if (cfg->channel[i] == hw_cfg->spk_pos)
+                       cs35l41->channel_index++;
+
        if (cfg->boost_type == INTERNAL) {
                hw_cfg->bst_type = CS35L41_INT_BOOST;
                hw_cfg->bst_ind = cfg->boost_ind_nanohenry;