Commit 5f9f982d authored by Stefan Binding's avatar Stefan Binding Committed by Takashi Iwai

ALSA: hda: cs35l41: Fix missing Speaker ID GPIO description in _DSD

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: default avatarStefan Binding <sbinding@opensource.cirrus.com>
Link: https://patch.msgid.link/20240703140802.27688-1-sbinding@opensource.cirrus.comSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent d712c58c
...@@ -1753,38 +1753,14 @@ int cs35l41_get_speaker_id(struct device *dev, int amp_index, int num_amps, int ...@@ -1753,38 +1753,14 @@ int cs35l41_get_speaker_id(struct device *dev, int amp_index, int num_amps, int
return speaker_id; 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; struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
u32 values[HDA_MAX_COMPONENTS]; u32 values[HDA_MAX_COMPONENTS];
struct acpi_device *adev;
struct device *physdev;
struct spi_device *spi;
const char *sub;
char *property; char *property;
size_t nval; size_t nval;
int i, ret; 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"; property = "cirrus,dev-index";
ret = device_property_count_u32(physdev, property); ret = device_property_count_u32(physdev, property);
if (ret <= 0) if (ret <= 0)
...@@ -1816,8 +1792,9 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i ...@@ -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 /* 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 * 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, cs35l41->reset_gpio = fwnode_gpiod_get_index(acpi_fwnode_handle(cs35l41->dacpi), "reset",
GPIOD_OUT_LOW, "cs35l41-reset"); cs35l41->index, GPIOD_OUT_LOW,
"cs35l41-reset");
property = "cirrus,speaker-position"; property = "cirrus,speaker-position";
ret = device_property_read_u32_array(physdev, property, values, nval); 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 ...@@ -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->bst_type = CS35L41_EXT_BOOST;
hw_cfg->valid = true; 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: out:
put_device(physdev); put_device(physdev);
...@@ -1888,16 +1910,6 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i ...@@ -1888,16 +1910,6 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
} }
return 0; 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, int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq,
......
...@@ -104,5 +104,6 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i ...@@ -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); struct regmap *regmap, enum control_bus control_bus);
void cs35l41_hda_remove(struct device *dev); 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_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__*/ #endif /*__CS35L41_HDA_H__*/
...@@ -428,6 +428,20 @@ static int lenovo_legion_no_acpi(struct cs35l41_hda *cs35l41, struct device *phy ...@@ -428,6 +428,20 @@ static int lenovo_legion_no_acpi(struct cs35l41_hda *cs35l41, struct device *phy
return 0; 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 { struct cs35l41_prop_model {
const char *hid; const char *hid;
const char *ssid; const char *ssid;
...@@ -501,6 +515,7 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = { ...@@ -501,6 +515,7 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
{ "CSC3551", "104317F3", generic_dsd_config }, { "CSC3551", "104317F3", generic_dsd_config },
{ "CSC3551", "10431863", generic_dsd_config }, { "CSC3551", "10431863", generic_dsd_config },
{ "CSC3551", "104318D3", generic_dsd_config }, { "CSC3551", "104318D3", generic_dsd_config },
{ "CSC3551", "10431A63", missing_speaker_id_gpio2 },
{ "CSC3551", "10431A83", generic_dsd_config }, { "CSC3551", "10431A83", generic_dsd_config },
{ "CSC3551", "10431B93", generic_dsd_config }, { "CSC3551", "10431B93", generic_dsd_config },
{ "CSC3551", "10431C9F", generic_dsd_config }, { "CSC3551", "10431C9F", generic_dsd_config },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment