mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-22 04:03:58 +08:00
ALSA: hda/realtek: Add support for Legion 7 16ACHg6 laptop
Add Support for CS35L41 using the component binding method [ corrected the quirk entry position by tiwai ] Signed-off-by: Lucas Tanure <tanureal@opensource.cirrus.com> Link: https://lore.kernel.org/r/20211217115708.882525-10-tanureal@opensource.cirrus.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
7b2f3eb492
commit
d3dca02637
@ -25,6 +25,7 @@
|
||||
#include "hda_auto_parser.h"
|
||||
#include "hda_jack.h"
|
||||
#include "hda_generic.h"
|
||||
#include "hda_component.h"
|
||||
|
||||
/* keep halting ALC5505 DSP, for power saving */
|
||||
#define HALT_REALTEK_ALC5505
|
||||
@ -126,6 +127,10 @@ struct alc_spec {
|
||||
unsigned int coef0;
|
||||
struct input_dev *kb_dev;
|
||||
u8 alc_mute_keycode_map[1];
|
||||
|
||||
/* component binding */
|
||||
struct component_match *match;
|
||||
struct hda_component comps[HDA_MAX_COMPONENTS];
|
||||
};
|
||||
|
||||
/*
|
||||
@ -6525,6 +6530,102 @@ static void alc287_fixup_legion_15imhg05_speakers(struct hda_codec *codec,
|
||||
}
|
||||
}
|
||||
|
||||
static int comp_match_dev_name(struct device *dev, void *data)
|
||||
{
|
||||
return strcmp(dev_name(dev), data) == 0;
|
||||
}
|
||||
|
||||
static int find_comp_by_dev_name(struct alc_spec *spec, const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < HDA_MAX_COMPONENTS; i++) {
|
||||
if (strcmp(spec->comps[i].name, name) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int comp_bind(struct device *dev)
|
||||
{
|
||||
struct hda_codec *cdc = dev_to_hda_codec(dev);
|
||||
struct alc_spec *spec = cdc->spec;
|
||||
|
||||
return component_bind_all(dev, spec->comps);
|
||||
}
|
||||
|
||||
static void comp_unbind(struct device *dev)
|
||||
{
|
||||
struct hda_codec *cdc = dev_to_hda_codec(dev);
|
||||
struct alc_spec *spec = cdc->spec;
|
||||
|
||||
component_unbind_all(dev, spec->comps);
|
||||
}
|
||||
|
||||
static const struct component_master_ops comp_master_ops = {
|
||||
.bind = comp_bind,
|
||||
.unbind = comp_unbind,
|
||||
};
|
||||
|
||||
static void comp_generic_playback_hook(struct hda_pcm_stream *hinfo, struct hda_codec *cdc,
|
||||
struct snd_pcm_substream *sub, int action)
|
||||
{
|
||||
struct alc_spec *spec = cdc->spec;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < HDA_MAX_COMPONENTS; i++) {
|
||||
if (spec->comps[i].dev)
|
||||
spec->comps[i].playback_hook(spec->comps[i].dev, action);
|
||||
}
|
||||
}
|
||||
|
||||
static void alc287_legion_16achg6_playback_hook(struct hda_pcm_stream *hinfo, struct hda_codec *cdc,
|
||||
struct snd_pcm_substream *sub, int action)
|
||||
{
|
||||
struct alc_spec *spec = cdc->spec;
|
||||
unsigned int rx_slot;
|
||||
int i;
|
||||
|
||||
switch (action) {
|
||||
case HDA_GEN_PCM_ACT_PREPARE:
|
||||
rx_slot = 0;
|
||||
i = find_comp_by_dev_name(spec, "i2c-CLSA0100:00-cs35l41-hda.0");
|
||||
if (i >= 0)
|
||||
spec->comps[i].set_channel_map(spec->comps[i].dev, 0, NULL, 1, &rx_slot);
|
||||
|
||||
rx_slot = 1;
|
||||
i = find_comp_by_dev_name(spec, "i2c-CLSA0100:00-cs35l41-hda.1");
|
||||
if (i >= 0)
|
||||
spec->comps[i].set_channel_map(spec->comps[i].dev, 0, NULL, 1, &rx_slot);
|
||||
break;
|
||||
}
|
||||
|
||||
comp_generic_playback_hook(hinfo, cdc, sub, action);
|
||||
}
|
||||
|
||||
static void alc287_fixup_legion_16achg6_speakers(struct hda_codec *cdc, const struct hda_fixup *fix,
|
||||
int action)
|
||||
{
|
||||
struct device *dev = hda_codec_dev(cdc);
|
||||
struct alc_spec *spec = cdc->spec;
|
||||
int ret;
|
||||
|
||||
switch (action) {
|
||||
case HDA_FIXUP_ACT_PRE_PROBE:
|
||||
component_match_add(dev, &spec->match, comp_match_dev_name,
|
||||
"i2c-CLSA0100:00-cs35l41-hda.0");
|
||||
component_match_add(dev, &spec->match, comp_match_dev_name,
|
||||
"i2c-CLSA0100:00-cs35l41-hda.1");
|
||||
ret = component_master_add_with_match(dev, &comp_master_ops, spec->match);
|
||||
if (ret)
|
||||
codec_err(cdc, "Fail to register component aggregator %d\n", ret);
|
||||
else
|
||||
spec->gen.pcm_playback_hook = alc287_legion_16achg6_playback_hook;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* for alc295_fixup_hp_top_speakers */
|
||||
#include "hp_x360_helper.c"
|
||||
|
||||
@ -6814,6 +6915,7 @@ enum {
|
||||
ALC256_FIXUP_MIC_NO_PRESENCE_AND_RESUME,
|
||||
ALC285_FIXUP_LEGION_Y9000X_SPEAKERS,
|
||||
ALC285_FIXUP_LEGION_Y9000X_AUTOMUTE,
|
||||
ALC287_FIXUP_LEGION_16ACHG6,
|
||||
};
|
||||
|
||||
static const struct hda_fixup alc269_fixups[] = {
|
||||
@ -8556,6 +8658,10 @@ static const struct hda_fixup alc269_fixups[] = {
|
||||
.chained = true,
|
||||
.chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
|
||||
},
|
||||
[ALC287_FIXUP_LEGION_16ACHG6] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc287_fixup_legion_16achg6_speakers,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
@ -8970,6 +9076,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x17aa, 0x3824, "Legion Y9000X 2020", ALC285_FIXUP_LEGION_Y9000X_SPEAKERS),
|
||||
SND_PCI_QUIRK(0x17aa, 0x3827, "Ideapad S740", ALC285_FIXUP_IDEAPAD_S740_COEF),
|
||||
SND_PCI_QUIRK(0x17aa, 0x3843, "Yoga 9i", ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP),
|
||||
SND_PCI_QUIRK(0x17aa, 0x3847, "Legion 7 16ACHG6", ALC287_FIXUP_LEGION_16ACHG6),
|
||||
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),
|
||||
|
Loading…
Reference in New Issue
Block a user