Skip to content

Commit

Permalink
ALSA: hda: cs35l41: Support CLSA0101
Browse files Browse the repository at this point in the history
Add support for Intel version of Legion 7 laptop.

Signed-off-by: Lucas Tanure <tanureal@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220727095924.80884-3-tanureal@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Lucas Tanure authored and Takashi Iwai committed Jul 28, 2022
1 parent f81ee57 commit 1e24881
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 26 deletions.
66 changes: 40 additions & 26 deletions sound/pci/hda/cs35l41_hda.c
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,45 @@ static int cs35l41_get_speaker_id(struct device *dev, int amp_index,
return speaker_id;
}

/*
* Device CLSA010(0/1) doesn't have _DSD so a gpiod_get by the label reset won't work.
* And devices created by serial-multi-instantiate don't have their device struct
* pointing to the correct fwnode, so acpi_dev must be used here.
* And devm functions expect that the device requesting the resource has the correct
* fwnode.
*/
static int cs35l41_no_acpi_dsd(struct cs35l41_hda *cs35l41, struct device *physdev, int id,
const char *hid)
{
struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;

/* check I2C address to assign the index */
cs35l41->index = id == 0x40 ? 0 : 1;
cs35l41->channel_index = 0;
cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH);
cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, 2);
hw_cfg->spk_pos = cs35l41->index;
hw_cfg->gpio2.func = CS35L41_INTERRUPT;
hw_cfg->gpio2.valid = true;
hw_cfg->valid = true;
put_device(physdev);

if (strncmp(hid, "CLSA0100", 8) == 0) {
hw_cfg->bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH;
} else if (strncmp(hid, "CLSA0101", 8) == 0) {
hw_cfg->bst_type = CS35L41_EXT_BOOST;
hw_cfg->gpio1.func = CS35l41_VSPK_SWITCH;
hw_cfg->gpio1.valid = true;
} else {
hw_cfg->valid = false;
hw_cfg->gpio1.valid = false;
hw_cfg->gpio2.valid = false;
return -EINVAL;
}

return 0;
}

static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id)
{
struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
Expand Down Expand Up @@ -1161,7 +1200,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
property = "cirrus,dev-index";
ret = device_property_count_u32(physdev, property);
if (ret <= 0)
goto no_acpi_dsd;
return cs35l41_no_acpi_dsd(cs35l41, physdev, id, hid);

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

return ret;

no_acpi_dsd:
/*
* Device CLSA0100 doesn't have _DSD so a gpiod_get by the label reset won't work.
* And devices created by serial-multi-instantiate don't have their device struct
* pointing to the correct fwnode, so acpi_dev must be used here.
* And devm functions expect that the device requesting the resource has the correct
* fwnode.
*/
if (strncmp(hid, "CLSA0100", 8) != 0)
return -EINVAL;

/* check I2C address to assign the index */
cs35l41->index = id == 0x40 ? 0 : 1;
cs35l41->hw_cfg.spk_pos = cs35l41->index;
cs35l41->channel_index = 0;
cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH);
cs35l41->hw_cfg.bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH;
cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, 2);
hw_cfg->gpio2.func = CS35L41_INTERRUPT;
hw_cfg->gpio2.valid = true;
cs35l41->hw_cfg.valid = true;
put_device(physdev);

return 0;
}

int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq,
Expand Down
3 changes: 3 additions & 0 deletions sound/pci/hda/cs35l41_hda_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ static int cs35l41_hda_i2c_probe(struct i2c_client *clt, const struct i2c_device
*/
if (strstr(dev_name(&clt->dev), "CLSA0100"))
device_name = "CLSA0100";
else if (strstr(dev_name(&clt->dev), "CLSA0101"))
device_name = "CLSA0101";
else if (strstr(dev_name(&clt->dev), "CSC3551"))
device_name = "CSC3551";
else
Expand All @@ -45,6 +47,7 @@ static const struct i2c_device_id cs35l41_hda_i2c_id[] = {

static const struct acpi_device_id cs35l41_acpi_hda_match[] = {
{"CLSA0100", 0 },
{"CLSA0101", 0 },
{"CSC3551", 0 },
{}
};
Expand Down
12 changes: 12 additions & 0 deletions sound/pci/hda/patch_realtek.c
Original file line number Diff line number Diff line change
Expand Up @@ -6710,6 +6710,12 @@ static void alc287_fixup_legion_16achg6_speakers(struct hda_codec *cdc, const st
cs35l41_generic_fixup(cdc, action, "i2c", "CLSA0100", 2);
}

static void alc287_fixup_legion_16ithg6_speakers(struct hda_codec *cdc, const struct hda_fixup *fix,
int action)
{
cs35l41_generic_fixup(cdc, action, "i2c", "CLSA0101", 2);
}

/* for alc295_fixup_hp_top_speakers */
#include "hp_x360_helper.c"

Expand Down Expand Up @@ -7047,6 +7053,7 @@ enum {
ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED,
ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED,
ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE,
ALC287_FIXUP_LEGION_16ITHG6,
};

/* A special fixup for Lenovo C940 and Yoga Duet 7;
Expand Down Expand Up @@ -8889,6 +8896,10 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
},
[ALC287_FIXUP_LEGION_16ITHG6] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc287_fixup_legion_16ithg6_speakers,
},
};

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

0 comments on commit 1e24881

Please sign in to comment.