On Tue, 23 Nov 2021 17:31:48 +0100, Lucas Tanure wrote: > > --- a/sound/pci/hda/Makefile > +++ b/sound/pci/hda/Makefile > @@ -13,25 +13,27 @@ snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o > CFLAGS_hda_controller.o := -I$(src) > CFLAGS_hda_intel.o := -I$(src) > > -snd-hda-codec-generic-objs := hda_generic.o > -snd-hda-codec-realtek-objs := patch_realtek.o > -snd-hda-codec-cmedia-objs := patch_cmedia.o > -snd-hda-codec-analog-objs := patch_analog.o > -snd-hda-codec-idt-objs := patch_sigmatel.o > -snd-hda-codec-si3054-objs := patch_si3054.o > -snd-hda-codec-cirrus-objs := patch_cirrus.o > -snd-hda-codec-cs8409-objs := patch_cs8409.o patch_cs8409-tables.o > -snd-hda-codec-ca0110-objs := patch_ca0110.o > -snd-hda-codec-ca0132-objs := patch_ca0132.o > -snd-hda-codec-conexant-objs := patch_conexant.o > -snd-hda-codec-via-objs := patch_via.o > -snd-hda-codec-hdmi-objs := patch_hdmi.o hda_eld.o > +snd-hda-codec-generic-objs := hda_generic.o You don't need to change other lines because of the newly added driver below... > +snd-hda-codec-cs35l41-i2c-objs := cs35l41_hda_i2c.o cs35l41_hda.o ../../soc/codecs/cs35l41-lib.o Linking the object in a different level of directory is too ugly and would be problematic if multiple drivers want the cs35l41-lib stuff. IMO, it's better to make symbols in cs35l41-lib exported and select the corresponding Kconfig from HD-audio driver. And, snd-hda-codec-cs35l41-i2c is not really a codec driver. It's rather some bridge for i2c over HD-audio. So, better to avoid snd-hda-codec-* but have some different name. Otherwise people may misunderstand. > --- a/sound/pci/hda/patch_realtek.c > +++ b/sound/pci/hda/patch_realtek.c (snip) > @@ -6497,6 +6502,98 @@ static void alc287_fixup_legion_15imhg05_speakers(struct hda_codec *codec, > } > } > > +static int comp_match_dev_name(struct device *dev, void *data) > +{ > + if (strcmp(dev_name(dev), data) == 0) > + return 1; > + > + return 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 *codec = dev_to_hda_codec(dev); > + struct alc_spec *spec = codec->spec; > + > + return component_bind_all(dev, spec->comps); > +} > + > +static void comp_unbind(struct device *dev) > +{ > + struct hda_codec *codec = dev_to_hda_codec(dev); > + struct alc_spec *spec = codec->spec; > + > + component_unbind_all(dev, spec->comps); > +} > + > +static const struct component_master_ops comp_master_ops = { > + .bind = comp_bind, > + .unbind = comp_unbind, > +}; > + > +void alc287_legion_16achg6_playback_hook(struct hda_pcm_stream *hinfo, struct hda_codec *codec, > + struct snd_pcm_substream *sub, int action) > +{ > + struct alc_spec *spec = codec->spec; > + unsigned int rx_slot; > + int i = 0; > + > + 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; > + } > + > + 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_fixup_legion_16achg6_speakers(struct hda_codec *codec, > + const struct hda_fixup *fix, int action) > +{ > + struct device *dev = hda_codec_dev(codec); > + struct alc_spec *spec = codec->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(codec, "Fail to register component aggregator %d\n", ret); > + else > + spec->gen.pcm_playback_hook = alc287_legion_16achg6_playback_hook; > + break; > + } > +} > + Those are needed only if the new cs35l41 stuff is enabled, so they can be wrapped with #if IS_REACHABLE(xxx). thanks, Takashi