[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(-)
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 brent.lu@intel.com --- 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)
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)
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?
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
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 brent.lu@intel.com --- 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;
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 brent.lu@intel.com --- 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,
participants (3)
-
Brent Lu
-
Cezary Rojewski
-
Pierre-Louis Bossart