]> www.infradead.org Git - users/hch/configfs.git/commitdiff
ALSA: hda: cs35l41: Fix missing Speaker ID GPIO description in _DSD
authorStefan Binding <sbinding@opensource.cirrus.com>
Wed, 3 Jul 2024 14:07:28 +0000 (15:07 +0100)
committerTakashi Iwai <tiwai@suse.de>
Thu, 4 Jul 2024 12:47:12 +0000 (14:47 +0200)
Laptop 10431A63 contains valid _DSD, but missing Speaker ID
description. Add this discription, but keep the rest of the _DSD to
ensure the correct firmware and tuning is loaded for this laptop.

Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com>
Link: https://patch.msgid.link/20240703140802.27688-1-sbinding@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/cs35l41_hda.c
sound/pci/hda/cs35l41_hda.h
sound/pci/hda/cs35l41_hda_property.c

index ee9f83b737de8dbb78873dc2c928dafe236d515c..4b411ed8c3fe0e794a86c13f33351cb7be27b2b1 100644 (file)
@@ -1753,38 +1753,14 @@ int cs35l41_get_speaker_id(struct device *dev, int amp_index, int num_amps, int
        return speaker_id;
 }
 
-static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id)
+int cs35l41_hda_parse_acpi(struct cs35l41_hda *cs35l41, struct device *physdev, int id)
 {
        struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
        u32 values[HDA_MAX_COMPONENTS];
-       struct acpi_device *adev;
-       struct device *physdev;
-       struct spi_device *spi;
-       const char *sub;
        char *property;
        size_t nval;
        int i, ret;
 
-       adev = acpi_dev_get_first_match_dev(hid, NULL, -1);
-       if (!adev) {
-               dev_err(cs35l41->dev, "Failed to find an ACPI device for %s\n", hid);
-               return -ENODEV;
-       }
-
-       cs35l41->dacpi = adev;
-       physdev = get_device(acpi_get_first_physical_node(adev));
-
-       sub = acpi_get_subsystem_id(ACPI_HANDLE(physdev));
-       if (IS_ERR(sub))
-               sub = NULL;
-       cs35l41->acpi_subsystem_id = sub;
-
-       ret = cs35l41_add_dsd_properties(cs35l41, physdev, id, hid);
-       if (!ret) {
-               dev_info(cs35l41->dev, "Using extra _DSD properties, bypassing _DSD in ACPI\n");
-               goto out;
-       }
-
        property = "cirrus,dev-index";
        ret = device_property_count_u32(physdev, property);
        if (ret <= 0)
@@ -1816,8 +1792,9 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
        /* To use the same release code for all laptop variants we can't use devm_ version of
         * gpiod_get here, as CLSA010* don't have a fully functional bios with an _DSD node
         */
-       cs35l41->reset_gpio = fwnode_gpiod_get_index(acpi_fwnode_handle(adev), "reset", cs35l41->index,
-                                                    GPIOD_OUT_LOW, "cs35l41-reset");
+       cs35l41->reset_gpio = fwnode_gpiod_get_index(acpi_fwnode_handle(cs35l41->dacpi), "reset",
+                                                    cs35l41->index, GPIOD_OUT_LOW,
+                                                    "cs35l41-reset");
 
        property = "cirrus,speaker-position";
        ret = device_property_read_u32_array(physdev, property, values, nval);
@@ -1873,6 +1850,51 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
                hw_cfg->bst_type = CS35L41_EXT_BOOST;
 
        hw_cfg->valid = true;
+
+       return 0;
+err:
+       dev_err(cs35l41->dev, "Failed property %s: %d\n", property, ret);
+       hw_cfg->valid = false;
+       hw_cfg->gpio1.valid = false;
+       hw_cfg->gpio2.valid = false;
+       acpi_dev_put(cs35l41->dacpi);
+
+       return ret;
+}
+
+static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id)
+{
+       struct acpi_device *adev;
+       struct device *physdev;
+       struct spi_device *spi;
+       const char *sub;
+       int ret;
+
+       adev = acpi_dev_get_first_match_dev(hid, NULL, -1);
+       if (!adev) {
+               dev_err(cs35l41->dev, "Failed to find an ACPI device for %s\n", hid);
+               return -ENODEV;
+       }
+
+       cs35l41->dacpi = adev;
+       physdev = get_device(acpi_get_first_physical_node(adev));
+
+       sub = acpi_get_subsystem_id(ACPI_HANDLE(physdev));
+       if (IS_ERR(sub))
+               sub = NULL;
+       cs35l41->acpi_subsystem_id = sub;
+
+       ret = cs35l41_add_dsd_properties(cs35l41, physdev, id, hid);
+       if (!ret) {
+               dev_info(cs35l41->dev, "Using extra _DSD properties, bypassing _DSD in ACPI\n");
+               goto out;
+       }
+
+       ret = cs35l41_hda_parse_acpi(cs35l41, physdev, id);
+       if (ret) {
+               put_device(physdev);
+               return ret;
+       }
 out:
        put_device(physdev);
 
@@ -1888,16 +1910,6 @@ out:
        }
 
        return 0;
-
-err:
-       dev_err(cs35l41->dev, "Failed property %s: %d\n", property, ret);
-       hw_cfg->valid = false;
-       hw_cfg->gpio1.valid = false;
-       hw_cfg->gpio2.valid = false;
-       acpi_dev_put(cs35l41->dacpi);
-       put_device(physdev);
-
-       return ret;
 }
 
 int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq,
index b0bebb7784623052a63349f7f6d1301f37792952..c730b335158944f4aef86cfc3da60b90752d08af 100644 (file)
@@ -104,5 +104,6 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
                      struct regmap *regmap, enum control_bus control_bus);
 void cs35l41_hda_remove(struct device *dev);
 int cs35l41_get_speaker_id(struct device *dev, int amp_index, int num_amps, int fixed_gpio_id);
+int cs35l41_hda_parse_acpi(struct cs35l41_hda *cs35l41, struct device *physdev, int id);
 
 #endif /*__CS35L41_HDA_H__*/
index 51998d1c72ff11c221ad196e82fdcf71709cc154..5860379a0412b0de5579acb9f95f153a3c0ace2a 100644 (file)
@@ -428,6 +428,20 @@ static int lenovo_legion_no_acpi(struct cs35l41_hda *cs35l41, struct device *phy
        return 0;
 }
 
+static int missing_speaker_id_gpio2(struct cs35l41_hda *cs35l41, struct device *physdev, int id,
+                                   const char *hid)
+{
+       int ret;
+
+       ret = cs35l41_add_gpios(cs35l41, physdev, -1, 2, -1, 2);
+       if (ret) {
+               dev_err(cs35l41->dev, "Error adding GPIO mapping: %d\n", ret);
+               return ret;
+       }
+
+       return cs35l41_hda_parse_acpi(cs35l41, physdev, id);
+}
+
 struct cs35l41_prop_model {
        const char *hid;
        const char *ssid;
@@ -501,6 +515,7 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
        { "CSC3551", "104317F3", generic_dsd_config },
        { "CSC3551", "10431863", generic_dsd_config },
        { "CSC3551", "104318D3", generic_dsd_config },
+       { "CSC3551", "10431A63", missing_speaker_id_gpio2 },
        { "CSC3551", "10431A83", generic_dsd_config },
        { "CSC3551", "10431B93", generic_dsd_config },
        { "CSC3551", "10431C9F", generic_dsd_config },