Skip to content

Commit 1e24881

Browse files
Lucas Tanuretiwai
authored andcommitted
ALSA: hda: cs35l41: Support CLSA0101
Add support for Intel version of Legion 7 laptop. Signed-off-by: Lucas Tanure <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent f81ee57 commit 1e24881

File tree

3 files changed

+55
-26
lines changed

3 files changed

+55
-26
lines changed

sound/pci/hda/cs35l41_hda.c

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,6 +1133,45 @@ static int cs35l41_get_speaker_id(struct device *dev, int amp_index,
11331133
return speaker_id;
11341134
}
11351135

1136+
/*
1137+
* Device CLSA010(0/1) doesn't have _DSD so a gpiod_get by the label reset won't work.
1138+
* And devices created by serial-multi-instantiate don't have their device struct
1139+
* pointing to the correct fwnode, so acpi_dev must be used here.
1140+
* And devm functions expect that the device requesting the resource has the correct
1141+
* fwnode.
1142+
*/
1143+
static int cs35l41_no_acpi_dsd(struct cs35l41_hda *cs35l41, struct device *physdev, int id,
1144+
const char *hid)
1145+
{
1146+
struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
1147+
1148+
/* check I2C address to assign the index */
1149+
cs35l41->index = id == 0x40 ? 0 : 1;
1150+
cs35l41->channel_index = 0;
1151+
cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH);
1152+
cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, 2);
1153+
hw_cfg->spk_pos = cs35l41->index;
1154+
hw_cfg->gpio2.func = CS35L41_INTERRUPT;
1155+
hw_cfg->gpio2.valid = true;
1156+
hw_cfg->valid = true;
1157+
put_device(physdev);
1158+
1159+
if (strncmp(hid, "CLSA0100", 8) == 0) {
1160+
hw_cfg->bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH;
1161+
} else if (strncmp(hid, "CLSA0101", 8) == 0) {
1162+
hw_cfg->bst_type = CS35L41_EXT_BOOST;
1163+
hw_cfg->gpio1.func = CS35l41_VSPK_SWITCH;
1164+
hw_cfg->gpio1.valid = true;
1165+
} else {
1166+
hw_cfg->valid = false;
1167+
hw_cfg->gpio1.valid = false;
1168+
hw_cfg->gpio2.valid = false;
1169+
return -EINVAL;
1170+
}
1171+
1172+
return 0;
1173+
}
1174+
11361175
static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id)
11371176
{
11381177
struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
@@ -1161,7 +1200,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
11611200
property = "cirrus,dev-index";
11621201
ret = device_property_count_u32(physdev, property);
11631202
if (ret <= 0)
1164-
goto no_acpi_dsd;
1203+
return cs35l41_no_acpi_dsd(cs35l41, physdev, id, hid);
11651204

11661205
if (ret > ARRAY_SIZE(values)) {
11671206
ret = -EINVAL;
@@ -1255,31 +1294,6 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
12551294
dev_err(cs35l41->dev, "Failed property %s: %d\n", property, ret);
12561295

12571296
return ret;
1258-
1259-
no_acpi_dsd:
1260-
/*
1261-
* Device CLSA0100 doesn't have _DSD so a gpiod_get by the label reset won't work.
1262-
* And devices created by serial-multi-instantiate don't have their device struct
1263-
* pointing to the correct fwnode, so acpi_dev must be used here.
1264-
* And devm functions expect that the device requesting the resource has the correct
1265-
* fwnode.
1266-
*/
1267-
if (strncmp(hid, "CLSA0100", 8) != 0)
1268-
return -EINVAL;
1269-
1270-
/* check I2C address to assign the index */
1271-
cs35l41->index = id == 0x40 ? 0 : 1;
1272-
cs35l41->hw_cfg.spk_pos = cs35l41->index;
1273-
cs35l41->channel_index = 0;
1274-
cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH);
1275-
cs35l41->hw_cfg.bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH;
1276-
cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, 2);
1277-
hw_cfg->gpio2.func = CS35L41_INTERRUPT;
1278-
hw_cfg->gpio2.valid = true;
1279-
cs35l41->hw_cfg.valid = true;
1280-
put_device(physdev);
1281-
1282-
return 0;
12831297
}
12841298

12851299
int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq,

sound/pci/hda/cs35l41_hda_i2c.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ static int cs35l41_hda_i2c_probe(struct i2c_client *clt, const struct i2c_device
2222
*/
2323
if (strstr(dev_name(&clt->dev), "CLSA0100"))
2424
device_name = "CLSA0100";
25+
else if (strstr(dev_name(&clt->dev), "CLSA0101"))
26+
device_name = "CLSA0101";
2527
else if (strstr(dev_name(&clt->dev), "CSC3551"))
2628
device_name = "CSC3551";
2729
else
@@ -45,6 +47,7 @@ static const struct i2c_device_id cs35l41_hda_i2c_id[] = {
4547

4648
static const struct acpi_device_id cs35l41_acpi_hda_match[] = {
4749
{"CLSA0100", 0 },
50+
{"CLSA0101", 0 },
4851
{"CSC3551", 0 },
4952
{}
5053
};

sound/pci/hda/patch_realtek.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6710,6 +6710,12 @@ static void alc287_fixup_legion_16achg6_speakers(struct hda_codec *cdc, const st
67106710
cs35l41_generic_fixup(cdc, action, "i2c", "CLSA0100", 2);
67116711
}
67126712

6713+
static void alc287_fixup_legion_16ithg6_speakers(struct hda_codec *cdc, const struct hda_fixup *fix,
6714+
int action)
6715+
{
6716+
cs35l41_generic_fixup(cdc, action, "i2c", "CLSA0101", 2);
6717+
}
6718+
67136719
/* for alc295_fixup_hp_top_speakers */
67146720
#include "hp_x360_helper.c"
67156721

@@ -7047,6 +7053,7 @@ enum {
70477053
ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED,
70487054
ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED,
70497055
ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE,
7056+
ALC287_FIXUP_LEGION_16ITHG6,
70507057
};
70517058

70527059
/* A special fixup for Lenovo C940 and Yoga Duet 7;
@@ -8889,6 +8896,10 @@ static const struct hda_fixup alc269_fixups[] = {
88898896
.chained = true,
88908897
.chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
88918898
},
8899+
[ALC287_FIXUP_LEGION_16ITHG6] = {
8900+
.type = HDA_FIXUP_FUNC,
8901+
.v.func = alc287_fixup_legion_16ithg6_speakers,
8902+
},
88928903
};
88938904

88948905
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -9355,6 +9366,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
93559366
SND_PCI_QUIRK(0x17aa, 0x384a, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
93569367
SND_PCI_QUIRK(0x17aa, 0x3852, "Lenovo Yoga 7 14ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
93579368
SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
9369+
SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6),
93589370
SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
93599371
SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
93609372
SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),

0 commit comments

Comments
 (0)