Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp3609630pxb; Wed, 13 Oct 2021 09:18:49 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxEOijMlzlAjRvHK4pKJbxB2ZwLxKee7kIw+GLJ1QbqRsxIiBzVVioer7fH4z+0w/4L+57y X-Received: by 2002:a05:6a00:ac1:b0:44c:4dc6:b897 with SMTP id c1-20020a056a000ac100b0044c4dc6b897mr276542pfl.25.1634141929741; Wed, 13 Oct 2021 09:18:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1634141929; cv=none; d=google.com; s=arc-20160816; b=quZ/UeHVFocWEFnpQetiXFi4MT734r4noLFkLzZFnr9x0mban/N2JNrpYWb0aKk2t8 JV8G7YPbEpWqzCq/+YmtY23fApLpfebSmb5zDett77J61h7MC3RzHjyrdCRNa25ta0su CYPWGHMDETYpDnxfaP7huucZwFJOEwXxstvW7hTaWTy5Wus9X0H8WjPu7MxDyHouz4wv JuiP6h0JolxqUEnRdetDWJH0TlAm9jwdtOIgcdCXnc4tb/COms/x5wnlUTTr/XOGUSK1 OC4evsvMms24MLD7S1UBOOEWLgpvX3tSIMNPNkIaaGq3qoY5fDkoBN601LpUQzdryjeN rEGg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:user-agent:references:in-reply-to :subject:cc:to:from:message-id:date:dkim-signature:dkim-signature; bh=rJWMwps84J6beE+MBxyqt7lDeN8ENM40jh/cD8Lj87g=; b=o4ed1dEenjEKH5eryCzfakNQad7AxUiZl07DacL4p7PeBz96c5/x3XIB1BKe8fSe7r 6HMdHB9WA4JGkxmGBVQg8yFPJ5Dxz4A1Cjg940ozls5YFXrrZdfmCthfqBJUQAuhRN4r PyOfBIJEHZuZV6Rsfc051Ro5j4YDiLrYfFJXx5WhD4ZqrylgRLyzhylqWjkY0XzLPs34 SILxEZhg+9queFj+5rSImAhvqxJdMVNuYlIl5cp6H6W8pV8zqILBXufbk+sGyeBVu/Dw xoHCPdm/xUwFDHaeLLH9qatlLRJVU2KZyW7g+1UAOddgoiWQMEN4pGRLr+qN2TGdFOVx lotQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@suse.de header.s=susede2_rsa header.b=UXvj6YnW; dkim=neutral (no key) header.i=@suse.de header.s=susede2_ed25519 header.b="s/Ny/1xh"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=suse.de Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id r200si21006507pgr.481.2021.10.13.09.18.02; Wed, 13 Oct 2021 09:18:49 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@suse.de header.s=susede2_rsa header.b=UXvj6YnW; dkim=neutral (no key) header.i=@suse.de header.s=susede2_ed25519 header.b="s/Ny/1xh"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=suse.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229963AbhJMQRZ (ORCPT + 99 others); Wed, 13 Oct 2021 12:17:25 -0400 Received: from smtp-out2.suse.de ([195.135.220.29]:36508 "EHLO smtp-out2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229529AbhJMQRX (ORCPT ); Wed, 13 Oct 2021 12:17:23 -0400 Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id 7071D2014A; Wed, 13 Oct 2021 16:15:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1634141717; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=rJWMwps84J6beE+MBxyqt7lDeN8ENM40jh/cD8Lj87g=; b=UXvj6YnW/loICppyOFq6Md1lHhQd7X8ZTWXedyQzB2NUeVBSZ6RN9qI5L+pPuMZzs6LSLo 7eXK4ugFxsUMpWqtlRmIU22Fjv5SjlVUzb5dgiXqKs/DWyXLaZlnjWq1hGhroo6RnYJ5qT ZTt7Y8th+dYBV+AHWUFCSL4v6jx6dMM= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1634141717; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=rJWMwps84J6beE+MBxyqt7lDeN8ENM40jh/cD8Lj87g=; b=s/Ny/1xhJDDb+sAEZoeETi4KdXm+puS5eiU0w4nasVpMoy23lMQ6Xo1993q0Q1kB6liglm CF3aZGO2v9MoEdAg== Received: from alsa1.suse.de (alsa1.suse.de [10.160.4.42]) by relay2.suse.de (Postfix) with ESMTP id 59AA6A3B83; Wed, 13 Oct 2021 16:15:17 +0000 (UTC) Date: Wed, 13 Oct 2021 18:15:17 +0200 Message-ID: From: Takashi Iwai To: Lucas Tanure Cc: Mark Brown , Takashi Iwai , "Jaroslav Kysela" , Len Brown , David Rhodes , Liam Girdwood , "Rafael J . Wysocki" , , , , Subject: Re: [RFC] sound: cs35l41: Add support for Legion 7 16ACHg6 laptop In-Reply-To: References: <20211008111902.103473-1-tanureal@opensource.cirrus.com> User-Agent: Wanderlust/2.15.9 (Almost Unreal) SEMI/1.14.6 (Maruoka) FLIM/1.14.9 (=?UTF-8?B?R29qxY0=?=) APEL/10.8 Emacs/25.3 (x86_64-suse-linux-gnu) MULE/6.0 (HANACHIRUSATO) MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, 12 Oct 2021 22:22:07 +0200, Takashi Iwai wrote: > > On Fri, 08 Oct 2021 13:19:02 +0200, > Lucas Tanure wrote: > > > > Hi, > > > > I would like to get some guidance about this solution to > > support the 16ACHg6 laptop. > > > > Hardware: > > - The 16ACHg6 laptop has two CS35L41 amplifiers, connected > > to Realtek ALC287 by an I2S bus and by and direct I2C to the CPU. > > - The ALC287 codec is connected to the CPU by an HDA bus. > > - The CS35L41 has a DSP which will require firmware to be loaded. > > > > Architecture: > > - To load the firmware for CS35L41, this solution will require > > the wm_adsp library, which requires regmap, header definitions and > > register tables. > > - To minimize the duplication of the code, the HDA functions will > > be placed inside the ASoC CS35L41 driver. > > - Finally, HDA patch_realtek will access exposed functions from > > ASoC CS35L41 driver to initialize the amplifiers, start and stop > > streams and load firmware. > > Through a very quick glance, a potential problem is that this design > would make the HD-audio codec driver dependent on those other ASoC > ones. As the Realtek HD-audio codec driver is used by quite many > other people, we'd like to reduce such dependency mess. > > Maybe a dynamic binding with component framework can be used? > > Alternatively, we may build up a stuff on top of ASoC like what SOF > driver did. It'll be another lot of work, though. Or, yet another (and easier) alternative would be to create a new codec driver that is specific to vendor+subsystem pair. We'll need to extend the hda_device_id and its matching mechanism, and the realtek codec driver needs to exclude the matching with the given SSID explicitly. A patch below is an example. Takashi --- diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index ae2e75d15b21..5558f2ba2fcf 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -248,6 +248,7 @@ struct serio_device_id { struct hda_device_id { __u32 vendor_id; + __u32 subsystem_id; __u32 rev_id; __u8 api_version; const char *name; diff --git a/include/sound/hda_codec.h b/include/sound/hda_codec.h index 0e45963bb767..3e316a798361 100644 --- a/include/sound/hda_codec.h +++ b/include/sound/hda_codec.h @@ -79,10 +79,12 @@ typedef int (*hda_codec_patch_t)(struct hda_codec *); #define HDA_CODEC_ID_GENERIC_HDMI 0x00000101 #define HDA_CODEC_ID_GENERIC 0x00000201 -#define HDA_CODEC_REV_ENTRY(_vid, _rev, _name, _patch) \ - { .vendor_id = (_vid), .rev_id = (_rev), .name = (_name), \ - .api_version = HDA_DEV_LEGACY, \ +#define HDA_CODEC_FULL_ENTRY(_vid, _subsystem, _rev, _name, _patch) \ + { .vendor_id = (_vid), .subsystem_id = (_subsystem), .rev_id = (_rev), \ + .name = (_name), .api_version = HDA_DEV_LEGACY, \ .driver_data = (unsigned long)(_patch) } +#define HDA_CODEC_REV_ENTRY(_vid, _rev, _name, _patch) \ + HDA_CODEC_FULL_ENTRY(_vid, 0, _rev, _name, _patch) #define HDA_CODEC_ENTRY(_vid, _name, _patch) \ HDA_CODEC_REV_ENTRY(_vid, 0, _name, _patch) diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index cc3625617a0e..641b4f9bb2be 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c @@ -211,6 +211,7 @@ int main(void) DEVID(hda_device_id); DEVID_FIELD(hda_device_id, vendor_id); + DEVID_FIELD(hda_device_id, subsystem_id); DEVID_FIELD(hda_device_id, rev_id); DEVID_FIELD(hda_device_id, api_version); diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 49aba862073e..d8faf0065c95 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1255,15 +1255,17 @@ static int do_ulpi_entry(const char *filename, void *symval, return 1; } -/* Looks like: hdaudio:vNrNaN */ +/* Looks like: hdaudio:vNsNrNaN */ static int do_hda_entry(const char *filename, void *symval, char *alias) { DEF_FIELD(symval, hda_device_id, vendor_id); + DEF_FIELD(symval, hda_device_id, subsystem_id); DEF_FIELD(symval, hda_device_id, rev_id); DEF_FIELD(symval, hda_device_id, api_version); strcpy(alias, "hdaudio:"); ADD(alias, "v", vendor_id != 0, vendor_id); + ADD(alias, "s", subsystem_id != 0, subsystem_id); ADD(alias, "r", rev_id != 0, rev_id); ADD(alias, "a", api_version != 0, api_version); diff --git a/sound/hda/hdac_device.c b/sound/hda/hdac_device.c index 3e9e9ac804f6..662abd40ca6a 100644 --- a/sound/hda/hdac_device.c +++ b/sound/hda/hdac_device.c @@ -206,8 +206,9 @@ EXPORT_SYMBOL_GPL(snd_hdac_device_set_chip_name); */ int snd_hdac_codec_modalias(struct hdac_device *codec, char *buf, size_t size) { - return scnprintf(buf, size, "hdaudio:v%08Xr%08Xa%02X\n", - codec->vendor_id, codec->revision_id, codec->type); + return scnprintf(buf, size, "hdaudio:v%08Xs%08Xr%08Xa%02X\n", + codec->vendor_id, codec->subsystem_id, + codec->revision_id, codec->type); } EXPORT_SYMBOL_GPL(snd_hdac_codec_modalias); diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index b8fa682ce66a..9f559773bf99 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile @@ -15,6 +15,7 @@ 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-test-objs := patch_test.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 @@ -32,7 +33,7 @@ obj-$(CONFIG_SND_HDA) := snd-hda-codec.o # codec drivers obj-$(CONFIG_SND_HDA_GENERIC) += snd-hda-codec-generic.o -obj-$(CONFIG_SND_HDA_CODEC_REALTEK) += snd-hda-codec-realtek.o +obj-$(CONFIG_SND_HDA_CODEC_REALTEK) += snd-hda-codec-realtek.o snd-hda-codec-test.o obj-$(CONFIG_SND_HDA_CODEC_CMEDIA) += snd-hda-codec-cmedia.o obj-$(CONFIG_SND_HDA_CODEC_ANALOG) += snd-hda-codec-analog.o obj-$(CONFIG_SND_HDA_CODEC_SIGMATEL) += snd-hda-codec-idt.o diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c index 1c8bffc3eec6..367f220ec91e 100644 --- a/sound/pci/hda/hda_bind.c +++ b/sound/pci/hda/hda_bind.c @@ -200,7 +200,7 @@ static inline bool codec_probed(struct hda_codec *codec) static void request_codec_module(struct hda_codec *codec) { #ifdef MODULE - char modalias[32]; + char modalias[64]; const char *mod = NULL; switch (codec->probe_id) { diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 22d27b12c4e7..993b49554457 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -9510,7 +9511,7 @@ static void alc269_fill_coef(struct hda_codec *codec) /* */ -static int patch_alc269(struct hda_codec *codec) +int snd_hda_codec_realtek_alc269_probe(struct hda_codec *codec) { struct alc_spec *spec; int err; @@ -9667,6 +9668,9 @@ static int patch_alc269(struct hda_codec *codec) alc_pre_init(codec); + if (codec->fixup_id != HDA_FIXUP_ID_NOT_SET) + goto skip_pick_fixup; + snd_hda_pick_fixup(codec, alc269_fixup_models, alc269_fixup_tbl, alc269_fixups); /* FIXME: both TX300 and ROG Strix G17 have the same SSID, and @@ -9683,6 +9687,8 @@ static int patch_alc269(struct hda_codec *codec) snd_hda_pick_pin_fixup(codec, alc269_fallback_pin_fixup_tbl, alc269_fixups, false); snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl, alc269_fixups); + + skip_pick_fixup: snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); alc_auto_parse_customize_define(codec); @@ -9709,6 +9715,18 @@ static int patch_alc269(struct hda_codec *codec) alc_free(codec); return err; } +EXPORT_SYMBOL(snd_hda_codec_realtek_alc269_probe); + +static int patch_alc269(struct hda_codec *codec) +{ + if (codec->core.vendor_id == 0x10ec0298 && + codec->core.subsystem_id == 0x102806e5) { + pr_info("XXX realtek codec driver: skipping\n"); + return -ENODEV; + } + + return snd_hda_codec_realtek_alc269_probe(codec); +} /* * ALC861 diff --git a/sound/pci/hda/patch_test.c b/sound/pci/hda/patch_test.c new file mode 100644 index 000000000000..9070cc075af0 --- /dev/null +++ b/sound/pci/hda/patch_test.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include + +int snd_hda_codec_realtek_alc269_probe(struct hda_codec *codec); + +// static const struct hda_fixup test_fixup = { ... }; + +static int test_probe(struct hda_codec *codec) +{ + pr_info("XXX forked driver\n"); + // codec->fixup_id = 0; + // codec->fixup_list = &test_fixup; + return snd_hda_codec_realtek_alc269_probe(codec); +} + +static const struct hda_device_id snd_hda_id_test[] = { + HDA_CODEC_FULL_ENTRY(0x10ec0298, 0x102806e5, 0, test_probe), + {} /* terminator */ +}; +MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_test); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Test HD-audio codec"); + +static struct hda_codec_driver test_driver = { + .id = snd_hda_id_test, +}; + +module_hda_codec_driver(test_driver); -- 2.31.1