2021-10-07 13:39:00

by Brent Lu

[permalink] [raw]
Subject: [PATCH v2 0/3] Multiple headphone codec driver support

Support multiple headphone drivers in same machine driver. In this
case, both rt5682 and rt5682s are supported and enumerated by different
ACPI HID "10EC5682" and "RTL5682".

V2 Changes:
- remove useless 'NULL', 'false' in if-condition
- can use 'comp_ids' field alone to enumerate driver
- add comma to the end of entry in structure initialization
- keep the table of byt/cht/cml/icl untouched

Brent Lu (3):
ASoC: soc-acpi: add comp_ids field for machine driver matching
ASoC: Intel: sof_rt5682: detect codec variant in probe function
ASoC: Intel: sof_rt5682: use comp_ids to enumerate rt5682s

include/sound/soc-acpi.h | 2 ++
sound/soc/intel/boards/sof_rt5682.c | 34 +++---------------
.../intel/common/soc-acpi-intel-adl-match.c | 11 ++++--
.../intel/common/soc-acpi-intel-jsl-match.c | 35 +++++--------------
.../intel/common/soc-acpi-intel-tgl-match.c | 11 ++++--
sound/soc/soc-acpi.c | 24 +++++++++++--
6 files changed, 52 insertions(+), 65 deletions(-)

--
2.25.1


2021-10-07 13:39:31

by Brent Lu

[permalink] [raw]
Subject: [PATCH v2 1/3] ASoC: soc-acpi: add comp_ids field for machine driver matching

A machine driver needs to be enumerated by more than one ACPI HID if
it supports second headphone driver (i.e. rt5682 and rt5682s).
However, the id field in snd_soc_acpi_mach structure could contain
only one HID. By adding a 'comp_ids' field which can contain several
HIDs, we can enumerate a machine driver by multiple ACPI HIDs.

Signed-off-by: Brent Lu <[email protected]>
---
include/sound/soc-acpi.h | 2 ++
sound/soc/soc-acpi.c | 24 ++++++++++++++++++++++--
2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/include/sound/soc-acpi.h b/include/sound/soc-acpi.h
index 2f3fa385c092..43cf520f145e 100644
--- a/include/sound/soc-acpi.h
+++ b/include/sound/soc-acpi.h
@@ -129,6 +129,7 @@ struct snd_soc_acpi_link_adr {
* all firmware/topology related fields.
*
* @id: ACPI ID (usually the codec's) used to find a matching machine driver.
+ * @comp_ids: a list of audio codecs also used to find a matching machine driver.
* @link_mask: describes required board layout, e.g. for SoundWire.
* @links: array of link _ADR descriptors, null terminated.
* @drv_name: machine driver name
@@ -146,6 +147,7 @@ struct snd_soc_acpi_link_adr {
/* Descriptor for SST ASoC machine driver */
struct snd_soc_acpi_mach {
const u8 id[ACPI_ID_LEN];
+ struct snd_soc_acpi_codecs *comp_ids;
const u32 link_mask;
const struct snd_soc_acpi_link_adr *links;
const char *drv_name;
diff --git a/sound/soc/soc-acpi.c b/sound/soc/soc-acpi.c
index 395229bf5c51..aca7c2020567 100644
--- a/sound/soc/soc-acpi.c
+++ b/sound/soc/soc-acpi.c
@@ -8,14 +8,34 @@
#include <linux/module.h>
#include <sound/soc-acpi.h>

+static bool snd_soc_acpi_id_present(struct snd_soc_acpi_mach *machine)
+{
+ struct snd_soc_acpi_codecs *comp_ids = machine->comp_ids;
+ int i;
+
+ if (machine->id[0]) {
+ if (acpi_dev_present(machine->id, NULL, -1))
+ return true;
+ }
+
+ if (comp_ids) {
+ for (i = 0; i < comp_ids->num_codecs; i++) {
+ if (acpi_dev_present(comp_ids->codecs[i], NULL, -1))
+ return true;
+ }
+ }
+
+ return false;
+}
+
struct snd_soc_acpi_mach *
snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines)
{
struct snd_soc_acpi_mach *mach;
struct snd_soc_acpi_mach *mach_alt;

- for (mach = machines; mach->id[0]; mach++) {
- if (acpi_dev_present(mach->id, NULL, -1)) {
+ for (mach = machines; mach->id[0] || mach->comp_ids; mach++) {
+ if (snd_soc_acpi_id_present(mach)) {
if (mach->machine_quirk) {
mach_alt = mach->machine_quirk(mach);
if (!mach_alt)
--
2.25.1

2021-10-07 13:40:07

by Brent Lu

[permalink] [raw]
Subject: [PATCH v2 2/3] ASoC: Intel: sof_rt5682: detect codec variant in probe function

Detect whether the headphone codec is ALC5682I-VS or not in probe
function so we don't need to duplicate all board configs for this new
variant.

Signed-off-by: Brent Lu <[email protected]>
---
sound/soc/intel/boards/sof_rt5682.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c
index 613662eedd0d..c41c584379d9 100644
--- a/sound/soc/intel/boards/sof_rt5682.c
+++ b/sound/soc/intel/boards/sof_rt5682.c
@@ -864,6 +864,10 @@ static int sof_audio_probe(struct platform_device *pdev)
if ((sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) && !mach->quirk_data)
sof_rt5682_quirk &= ~SOF_SPEAKER_AMP_PRESENT;

+ /* Detect the headset codec variant */
+ if (acpi_dev_present("RTL5682", NULL, -1))
+ sof_rt5682_quirk |= SOF_RT5682S_HEADPHONE_CODEC_PRESENT;
+
if (soc_intel_is_byt() || soc_intel_is_cht()) {
is_legacy_cpu = 1;
dmic_be_num = 0;
--
2.25.1

2021-10-07 15:45:32

by Brent Lu

[permalink] [raw]
Subject: [PATCH v2 3/3] ASoC: Intel: sof_rt5682: use comp_ids to enumerate rt5682s

Use comp_ids field to enumerate rt5682/rt5682s headphone codec for
JSL/TGL/ADL devices and remove redundant entries in tables.

Signed-off-by: Brent Lu <[email protected]>
---
sound/soc/intel/boards/sof_rt5682.c | 30 ----------------
.../intel/common/soc-acpi-intel-adl-match.c | 11 ++++--
.../intel/common/soc-acpi-intel-jsl-match.c | 35 +++++--------------
.../intel/common/soc-acpi-intel-tgl-match.c | 11 ++++--
4 files changed, 24 insertions(+), 63 deletions(-)

diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c
index c41c584379d9..c41f386b4138 100644
--- a/sound/soc/intel/boards/sof_rt5682.c
+++ b/sound/soc/intel/boards/sof_rt5682.c
@@ -1050,36 +1050,6 @@ static const struct platform_device_id board_ids[] = {
SOF_RT5682_SSP_AMP(2) |
SOF_RT5682_NUM_HDMIDEV(4)),
},
- {
- .name = "jsl_rt5682s_rt1015",
- .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
- SOF_RT5682_MCLK_24MHZ |
- SOF_RT5682_SSP_CODEC(0) |
- SOF_RT5682S_HEADPHONE_CODEC_PRESENT |
- SOF_SPEAKER_AMP_PRESENT |
- SOF_RT1015_SPEAKER_AMP_PRESENT |
- SOF_RT5682_SSP_AMP(1)),
- },
- {
- .name = "jsl_rt5682s_rt1015p",
- .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
- SOF_RT5682_MCLK_24MHZ |
- SOF_RT5682_SSP_CODEC(0) |
- SOF_RT5682S_HEADPHONE_CODEC_PRESENT |
- SOF_SPEAKER_AMP_PRESENT |
- SOF_RT1015P_SPEAKER_AMP_PRESENT |
- SOF_RT5682_SSP_AMP(1)),
- },
- {
- .name = "jsl_rt5682s_mx98360",
- .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
- SOF_RT5682_MCLK_24MHZ |
- SOF_RT5682_SSP_CODEC(0) |
- SOF_RT5682S_HEADPHONE_CODEC_PRESENT |
- SOF_SPEAKER_AMP_PRESENT |
- SOF_MAX98360A_SPEAKER_AMP_PRESENT |
- SOF_RT5682_SSP_AMP(1)),
- },
{
.name = "adl_mx98360_rt5682",
.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
diff --git a/sound/soc/intel/common/soc-acpi-intel-adl-match.c b/sound/soc/intel/common/soc-acpi-intel-adl-match.c
index f5b21a95d222..7c6a79fedf61 100644
--- a/sound/soc/intel/common/soc-acpi-intel-adl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-adl-match.c
@@ -285,9 +285,14 @@ static const struct snd_soc_acpi_codecs adl_max98360a_amp = {
.codecs = {"MX98360A"}
};

+static struct snd_soc_acpi_codecs adl_rt5682_rt5682s_hp = {
+ .num_codecs = 2,
+ .codecs = {"10EC5682", "RTL5682"},
+};
+
struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = {
{
- .id = "10EC5682",
+ .comp_ids = &adl_rt5682_rt5682s_hp,
.drv_name = "adl_mx98373_rt5682",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &adl_max98373_amp,
@@ -295,7 +300,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = {
.sof_tplg_filename = "sof-adl-max98373-rt5682.tplg",
},
{
- .id = "10EC5682",
+ .comp_ids = &adl_rt5682_rt5682s_hp,
.drv_name = "adl_mx98357_rt5682",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &adl_max98357a_amp,
@@ -303,7 +308,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = {
.sof_tplg_filename = "sof-adl-max98357a-rt5682.tplg",
},
{
- .id = "10EC5682",
+ .comp_ids = &adl_rt5682_rt5682s_hp,
.drv_name = "adl_mx98360_rt5682",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &adl_max98360a_amp,
diff --git a/sound/soc/intel/common/soc-acpi-intel-jsl-match.c b/sound/soc/intel/common/soc-acpi-intel-jsl-match.c
index 20fd9dcc74af..253c1e320b97 100644
--- a/sound/soc/intel/common/soc-acpi-intel-jsl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-jsl-match.c
@@ -29,6 +29,11 @@ static struct snd_soc_acpi_codecs mx98360a_spk = {
.codecs = {"MX98360A"}
};

+static struct snd_soc_acpi_codecs rt5682_rt5682s_hp = {
+ .num_codecs = 2,
+ .codecs = {"10EC5682", "RTL5682"},
+};
+
/*
* When adding new entry to the snd_soc_acpi_intel_jsl_machines array,
* use .quirk_data member to distinguish different machine driver,
@@ -50,7 +55,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[] = {
.sof_tplg_filename = "sof-jsl-da7219-mx98360a.tplg",
},
{
- .id = "10EC5682",
+ .comp_ids = &rt5682_rt5682s_hp,
.drv_name = "jsl_rt5682_rt1015",
.sof_fw_filename = "sof-jsl.ri",
.machine_quirk = snd_soc_acpi_codec_list,
@@ -58,7 +63,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[] = {
.sof_tplg_filename = "sof-jsl-rt5682-rt1015.tplg",
},
{
- .id = "10EC5682",
+ .comp_ids = &rt5682_rt5682s_hp,
.drv_name = "jsl_rt5682_rt1015p",
.sof_fw_filename = "sof-jsl.ri",
.machine_quirk = snd_soc_acpi_codec_list,
@@ -66,7 +71,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[] = {
.sof_tplg_filename = "sof-jsl-rt5682-rt1015.tplg",
},
{
- .id = "10EC5682",
+ .comp_ids = &rt5682_rt5682s_hp,
.drv_name = "jsl_rt5682_mx98360",
.sof_fw_filename = "sof-jsl.ri",
.machine_quirk = snd_soc_acpi_codec_list,
@@ -81,30 +86,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[] = {
.quirk_data = &mx98360a_spk,
.sof_tplg_filename = "sof-jsl-cs42l42-mx98360a.tplg",
},
- {
- .id = "RTL5682",
- .drv_name = "jsl_rt5682s_rt1015",
- .sof_fw_filename = "sof-jsl.ri",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &rt1015_spk,
- .sof_tplg_filename = "sof-jsl-rt5682-rt1015.tplg",
- },
- {
- .id = "RTL5682",
- .drv_name = "jsl_rt5682s_rt1015p",
- .sof_fw_filename = "sof-jsl.ri",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &rt1015p_spk,
- .sof_tplg_filename = "sof-jsl-rt5682-rt1015.tplg",
- },
- {
- .id = "RTL5682",
- .drv_name = "jsl_rt5682s_mx98360",
- .sof_fw_filename = "sof-jsl.ri",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &mx98360a_spk,
- .sof_tplg_filename = "sof-jsl-rt5682-mx98360a.tplg",
- },
{},
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_jsl_machines);
diff --git a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c
index 9d89f01d6b84..39cdd4c04179 100644
--- a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c
@@ -358,9 +358,14 @@ static const struct snd_soc_acpi_codecs tgl_rt1011_amp = {
.codecs = {"10EC1011"}
};

+static struct snd_soc_acpi_codecs tgl_rt5682_rt5682s_hp = {
+ .num_codecs = 2,
+ .codecs = {"10EC5682", "RTL5682"},
+};
+
struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[] = {
{
- .id = "10EC5682",
+ .comp_ids = &tgl_rt5682_rt5682s_hp,
.drv_name = "tgl_mx98357_rt5682",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &tgl_codecs,
@@ -368,7 +373,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[] = {
.sof_tplg_filename = "sof-tgl-max98357a-rt5682.tplg",
},
{
- .id = "10EC5682",
+ .comp_ids = &tgl_rt5682_rt5682s_hp,
.drv_name = "tgl_mx98373_rt5682",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &tgl_max98373_amp,
@@ -376,7 +381,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[] = {
.sof_tplg_filename = "sof-tgl-max98373-rt5682.tplg",
},
{
- .id = "10EC5682",
+ .comp_ids = &tgl_rt5682_rt5682s_hp,
.drv_name = "tgl_rt1011_rt5682",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &tgl_rt1011_amp,
--
2.25.1

2021-10-07 17:11:13

by Cezary Rojewski

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] ASoC: soc-acpi: add comp_ids field for machine driver matching

On 2021-10-07 3:35 PM, Brent Lu wrote:

...

>
> +static bool snd_soc_acpi_id_present(struct snd_soc_acpi_mach *machine)
> +{
> + struct snd_soc_acpi_codecs *comp_ids = machine->comp_ids;
> + int i;
> +
> + if (machine->id[0]) {
> + if (acpi_dev_present(machine->id, NULL, -1))
> + return true;
> + }
> +
> + if (comp_ids) {
> + for (i = 0; i < comp_ids->num_codecs; i++) {
> + if (acpi_dev_present(comp_ids->codecs[i], NULL, -1))
> + return true;
> + }
> + }
> +
> + return false;
> +}

In cover letter you mention:
"- can use 'comp_ids' field alone to enumerate driver"

which leads me to an opinion that field 'id' should be removed,
entirely. With 'comp_ids' added, 'id' is basically rendered
optional/redundant.

> +
> struct snd_soc_acpi_mach *
> snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines)
> {
> struct snd_soc_acpi_mach *mach;
> struct snd_soc_acpi_mach *mach_alt;
>
> - for (mach = machines; mach->id[0]; mach++) {
> - if (acpi_dev_present(mach->id, NULL, -1)) {
> + for (mach = machines; mach->id[0] || mach->comp_ids; mach++) {

Such loops are hard to maintain i.e. 'comp_ids' acts here like a flex
array that follows 'id'. Removal of 'id' field and streamlining code to
only use 'comp_ids' should make this loop more intuitive.

> + if (snd_soc_acpi_id_present(mach)) {
> if (mach->machine_quirk) {
> mach_alt = mach->machine_quirk(mach);
> if (!mach_alt)
>

2021-10-07 18:49:13

by Cezary Rojewski

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] ASoC: soc-acpi: add comp_ids field for machine driver matching

On 2021-10-07 7:27 PM, Pierre-Louis Bossart wrote:
>
>>>   struct snd_soc_acpi_mach *
>>>   snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines)
>>>   {
>>>       struct snd_soc_acpi_mach *mach;
>>>       struct snd_soc_acpi_mach *mach_alt;
>>>   -    for (mach = machines; mach->id[0]; mach++) {
>>> -        if (acpi_dev_present(mach->id, NULL, -1)) {
>>> +    for (mach = machines; mach->id[0] || mach->comp_ids; mach++) {
>>
>> Such loops are hard to maintain i.e. 'comp_ids' acts here like a flex
>> array that follows 'id'. Removal of 'id' field and streamlining code to
>> only use 'comp_ids' should make this loop more intuitive.
>
> Changing all the tables adds more noise IMHO. There are 15 files and
> about 100 ids.
>
> This patch provides an opportunity to reduce duplication, that's good,
> but let's leave all the existing unique table entries alone, shall we?
>

Well, we could have mentioned files updated in the follow up patches
i.e. treat this patch as a 'preparation step'. In the long run, having
two places for id initialization will cost us more than updating all
those files.

Have no problem with leaving current patch as is if the end goal is
removal of 'id' field. In some future series I guess..

Czarek

2021-10-07 19:45:01

by Pierre-Louis Bossart

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] ASoC: soc-acpi: add comp_ids field for machine driver matching


>>   struct snd_soc_acpi_mach *
>>   snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines)
>>   {
>>       struct snd_soc_acpi_mach *mach;
>>       struct snd_soc_acpi_mach *mach_alt;
>>   -    for (mach = machines; mach->id[0]; mach++) {
>> -        if (acpi_dev_present(mach->id, NULL, -1)) {
>> +    for (mach = machines; mach->id[0] || mach->comp_ids; mach++) {
>
> Such loops are hard to maintain i.e. 'comp_ids' acts here like a flex
> array that follows 'id'. Removal of 'id' field and streamlining code to
> only use 'comp_ids' should make this loop more intuitive.

Changing all the tables adds more noise IMHO. There are 15 files and
about 100 ids.

This patch provides an opportunity to reduce duplication, that's good,
but let's leave all the existing unique table entries alone, shall we?