Integrate tas2781 configs for Lenovo Laptops. All of the tas2781s in the
laptop will be aggregated as one speaker. The code support realtek as the
primary codec.
Signed-off-by: Shenghao Ding <[email protected]>
---
Changes in v1:
- remove white space at the end of the line in alc_fixup_headset_mode_alc255_no_hp_mic
- Add [email protected] into Cc list
- remove useless index
- combine ALC287_FIXUP_TAS2781_I2C_2 and ALC287_FIXUP_TAS2781_I2C_4 together as
ALC287_FIXUP_TAS2781_I2C, The code view all the tas2781s in the laptop as one instance.
- delete the white space at the end of the line in alc_fixup_headset_mode_alc255_no_hp_mic
- fix Laptop 0x17aa38be get the wrong fixup_id and enter into the wrong entry.
---
sound/pci/hda/patch_realtek.c | 114 ++++++++++++++++++++++++++++++++--
1 file changed, 110 insertions(+), 4 deletions(-)
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index afe8253f9a4f..2e5354a5decf 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -5883,7 +5883,7 @@ static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
struct alc_spec *spec = codec->spec;
spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
alc255_set_default_jack_type(codec);
- }
+ }
else
alc_fixup_headset_mode(codec, fix, action);
}
@@ -6705,7 +6705,7 @@ static void comp_generic_playback_hook(struct hda_pcm_stream *hinfo, struct hda_
}
}
-struct cs35l41_dev_name {
+struct scodec_dev_name {
const char *bus;
const char *hid;
int index;
@@ -6714,7 +6714,7 @@ struct cs35l41_dev_name {
/* match the device name in a slightly relaxed manner */
static int comp_match_cs35l41_dev_name(struct device *dev, void *data)
{
- struct cs35l41_dev_name *p = data;
+ struct scodec_dev_name *p = data;
const char *d = dev_name(dev);
int n = strlen(p->bus);
char tmp[32];
@@ -6730,12 +6730,32 @@ static int comp_match_cs35l41_dev_name(struct device *dev, void *data)
return !strcmp(d + n, tmp);
}
+static int comp_match_tas2781_dev_name(struct device *dev,
+ void *data)
+{
+ struct scodec_dev_name *p = data;
+ const char *d = dev_name(dev);
+ int n = strlen(p->bus);
+ char tmp[32];
+
+ /* check the bus name */
+ if (strncmp(d, p->bus, n))
+ return 0;
+ /* skip the bus number */
+ if (isdigit(d[n]))
+ n++;
+ /* the rest must be exact matching */
+ snprintf(tmp, sizeof(tmp), "-%s:00", p->hid);
+
+ return !strcmp(d + n, tmp);
+}
+
static void cs35l41_generic_fixup(struct hda_codec *cdc, int action, const char *bus,
const char *hid, int count)
{
struct device *dev = hda_codec_dev(cdc);
struct alc_spec *spec = cdc->spec;
- struct cs35l41_dev_name *rec;
+ struct scodec_dev_name *rec;
int ret, i;
switch (action) {
@@ -6763,6 +6783,41 @@ static void cs35l41_generic_fixup(struct hda_codec *cdc, int action, const char
}
}
+static void tas2781_generic_fixup(struct hda_codec *cdc, int action,
+ const char *bus, const char *hid)
+{
+ struct device *dev = hda_codec_dev(cdc);
+ struct alc_spec *spec = cdc->spec;
+ struct scodec_dev_name *rec;
+ int ret;
+
+ switch (action) {
+ case HDA_FIXUP_ACT_PRE_PROBE:
+ rec = devm_kmalloc(dev, sizeof(*rec), GFP_KERNEL);
+ if (!rec)
+ return;
+ rec->bus = bus;
+ rec->hid = hid;
+ rec->index = 0;
+ spec->comps[0].codec = cdc;
+ component_match_add(dev, &spec->match,
+ comp_match_tas2781_dev_name, rec);
+ 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 =
+ comp_generic_playback_hook;
+ break;
+ case HDA_FIXUP_ACT_FREE:
+ component_master_del(dev, &comp_master_ops);
+ break;
+ }
+}
+
static void cs35l41_fixup_i2c_two(struct hda_codec *cdc, const struct hda_fixup *fix, int action)
{
cs35l41_generic_fixup(cdc, action, "i2c", "CSC3551", 2);
@@ -6790,6 +6845,12 @@ static void alc287_fixup_legion_16ithg6_speakers(struct hda_codec *cdc, const st
cs35l41_generic_fixup(cdc, action, "i2c", "CLSA0101", 2);
}
+static void tas2781_fixup_i2c(struct hda_codec *cdc,
+ const struct hda_fixup *fix, int action)
+{
+ tas2781_generic_fixup(cdc, action, "i2c", "TIAS2781");
+}
+
/* for alc295_fixup_hp_top_speakers */
#include "hp_x360_helper.c"
@@ -7210,6 +7271,7 @@ enum {
ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN,
ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS,
ALC236_FIXUP_DELL_DUAL_CODECS,
+ ALC287_FIXUP_TAS2781_I2C,
};
/* A special fixup for Lenovo C940 and Yoga Duet 7;
@@ -9255,6 +9317,12 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
},
+ [ALC287_FIXUP_TAS2781_I2C] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = tas2781_fixup_i2c,
+ .chained = true,
+ .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
+ },
};
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -9813,6 +9881,33 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6),
SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
+ SND_PCI_QUIRK(0x17aa, 0x387d, "Yoga S780-16 pro Quad AAC",
+ ALC287_FIXUP_TAS2781_I2C),
+ SND_PCI_QUIRK(0x17aa, 0x387e, "Yoga S780-16 pro Quad YC",
+ ALC287_FIXUP_TAS2781_I2C),
+ SND_PCI_QUIRK(0x17aa, 0x3881, "YB9 dual powe mode2 YC",
+ ALC287_FIXUP_TAS2781_I2C),
+ SND_PCI_QUIRK(0x17aa, 0x3884, "Y780 YG DUAL",
+ ALC287_FIXUP_TAS2781_I2C),
+ SND_PCI_QUIRK(0x17aa, 0x3886, "Y780 VECO DUAL",
+ ALC287_FIXUP_TAS2781_I2C),
+ SND_PCI_QUIRK(0x17aa, 0x38a7, "Y780P AMD YG dual",
+ ALC287_FIXUP_TAS2781_I2C),
+ SND_PCI_QUIRK(0x17aa, 0x38a8, "Y780P AMD VECO dual",
+ ALC287_FIXUP_TAS2781_I2C),
+ SND_PCI_QUIRK(0x17aa, 0x38ba, "Yoga S780-14.5 Air AMD quad YC",
+ ALC287_FIXUP_TAS2781_I2C),
+ SND_PCI_QUIRK(0x17aa, 0x38bb, "Yoga S780-14.5 Air AMD quad AAC",
+ ALC287_FIXUP_TAS2781_I2C),
+ SND_PCI_QUIRK(0x17aa, 0x38be, "Yoga S980-14.5 proX YC Dual",
+ ALC287_FIXUP_TAS2781_I2C),
+ SND_PCI_QUIRK(0x17aa, 0x38bf, "Yoga S980-14.5 proX LX Dual",
+ ALC287_FIXUP_TAS2781_I2C),
+ SND_PCI_QUIRK(0x17aa, 0x38c3, "Y980 DUAL", ALC287_FIXUP_TAS2781_I2C),
+ SND_PCI_QUIRK(0x17aa, 0x38cb, "Y790 YG DUAL",
+ ALC287_FIXUP_TAS2781_I2C),
+ SND_PCI_QUIRK(0x17aa, 0x38cd, "Y790 VECO DUAL",
+ ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
@@ -10728,6 +10823,17 @@ static int patch_alc269(struct hda_codec *codec)
codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
}
+ /* FIXME: Laptop 0x17aa38be will get the wrong fixup_id and
+ * enter into the wrong entry.
+ * Correct the wrong entry.
+ */
+ if (codec->fixup_id == ALC287_FIXUP_YOGA7_14ITL_SPEAKERS &&
+ codec->core.vendor_id == 0x10ec0287 &&
+ codec->core.subsystem_id == 0x17aa38be) {
+ codec_dbg(codec, "Clear wrong fixup for 17aa38be\n");
+ codec->fixup_id = ALC287_FIXUP_TAS2781_I2C;
+ }
+
snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups, true);
snd_hda_pick_pin_fixup(codec, alc269_fallback_pin_fixup_tbl, alc269_fixups, false);
snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
--
2.34.1
Add the MAINTAINERS entries for TEXAS INSTRUMENTS AUDIO (ASoC/HDA) DRIVERS.
Signed-off-by: Shenghao Ding <[email protected]>
---
MAINTAINERS | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index a6621aec58f9..16deb2a1fd89 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21040,6 +21040,38 @@ S: Maintained
F: Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml
F: sound/soc/ti/
+TEXAS INSTRUMENTS AUDIO (ASoC/HDA) DRIVERS
+M: Shenghao Ding <[email protected]>
+M: Kevin Lu <[email protected]>
+L: [email protected] (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/sound/tas2552.txt
+F: Documentation/devicetree/bindings/sound/tas2562.yaml
+F: Documentation/devicetree/bindings/sound/tas2770.yaml
+F: Documentation/devicetree/bindings/sound/tas27xx.yaml
+F: Documentation/devicetree/bindings/sound/ti,pcm1681.txt
+F: Documentation/devicetree/bindings/sound/ti,pcm3168a.yaml
+F: Documentation/devicetree/bindings/sound/ti,tlv320*.yaml
+F: Documentation/devicetree/bindings/sound/tlv320adcx140.yaml
+F: Documentation/devicetree/bindings/sound/tlv320aic31xx.txt
+F: Documentation/devicetree/bindings/sound/tpa6130a2.txt
+F: include/sound/tas2*.h
+F: include/sound/tlv320*.h
+F: include/sound/tpa6130a2-plat.h
+F: sound/pci/hda/tas2781_hda_i2c.c
+F: sound/soc/codecs/pcm1681.c
+F: sound/soc/codecs/pcm1789*.*
+F: sound/soc/codecs/pcm179x*.*
+F: sound/soc/codecs/pcm186x*.*
+F: sound/soc/codecs/pcm3008.*
+F: sound/soc/codecs/pcm3060*.*
+F: sound/soc/codecs/pcm3168a*.*
+F: sound/soc/codecs/pcm5102a.c
+F: sound/soc/codecs/pcm512x*.*
+F: sound/soc/codecs/tas2*.*
+F: sound/soc/codecs/tlv320*.*
+F: sound/soc/codecs/tpa6130a2.*
+
TEXAS INSTRUMENTS DMA DRIVERS
M: Peter Ujfalusi <[email protected]>
L: [email protected]
--
2.34.1
On Sun, 02 Jul 2023 10:18:55 +0200,
Shenghao Ding wrote:
>
> Integrate tas2781 configs for Lenovo Laptops. All of the tas2781s in the
> laptop will be aggregated as one speaker. The code support realtek as the
> primary codec.
It's not only that -- you changed the struct name used in the code,
too. Please describe it, too.
> @@ -5883,7 +5883,7 @@ static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
> struct alc_spec *spec = codec->spec;
> spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
> alc255_set_default_jack_type(codec);
> - }
> + }
> else
> alc_fixup_headset_mode(codec, fix, action);
> }
This change is irrelevant with your code, and should be fixed
individually. Please drop the hunk.
> @@ -9255,6 +9317,12 @@ static const struct hda_fixup alc269_fixups[] = {
> .chained = true,
> .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
> },
> + [ALC287_FIXUP_TAS2781_I2C] = {
> + .type = HDA_FIXUP_FUNC,
> + .v.func = tas2781_fixup_i2c,
> + .chained = true,
> + .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
> + },
So this is supposed to be Lenovo-specific, and maybe better to rename,
e.g. ALC287_FIXUP_LENOVO_TAS2781_I2C or such?
> @@ -9813,6 +9881,33 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
> SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
> SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6),
> SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
> + SND_PCI_QUIRK(0x17aa, 0x387d, "Yoga S780-16 pro Quad AAC",
> + ALC287_FIXUP_TAS2781_I2C),
> + SND_PCI_QUIRK(0x17aa, 0x387e, "Yoga S780-16 pro Quad YC",
> + ALC287_FIXUP_TAS2781_I2C),
> + SND_PCI_QUIRK(0x17aa, 0x3881, "YB9 dual powe mode2 YC",
> + ALC287_FIXUP_TAS2781_I2C),
> + SND_PCI_QUIRK(0x17aa, 0x3884, "Y780 YG DUAL",
> + ALC287_FIXUP_TAS2781_I2C),
> + SND_PCI_QUIRK(0x17aa, 0x3886, "Y780 VECO DUAL",
> + ALC287_FIXUP_TAS2781_I2C),
> + SND_PCI_QUIRK(0x17aa, 0x38a7, "Y780P AMD YG dual",
> + ALC287_FIXUP_TAS2781_I2C),
> + SND_PCI_QUIRK(0x17aa, 0x38a8, "Y780P AMD VECO dual",
> + ALC287_FIXUP_TAS2781_I2C),
> + SND_PCI_QUIRK(0x17aa, 0x38ba, "Yoga S780-14.5 Air AMD quad YC",
> + ALC287_FIXUP_TAS2781_I2C),
> + SND_PCI_QUIRK(0x17aa, 0x38bb, "Yoga S780-14.5 Air AMD quad AAC",
> + ALC287_FIXUP_TAS2781_I2C),
> + SND_PCI_QUIRK(0x17aa, 0x38be, "Yoga S980-14.5 proX YC Dual",
> + ALC287_FIXUP_TAS2781_I2C),
> + SND_PCI_QUIRK(0x17aa, 0x38bf, "Yoga S980-14.5 proX LX Dual",
> + ALC287_FIXUP_TAS2781_I2C),
> + SND_PCI_QUIRK(0x17aa, 0x38c3, "Y980 DUAL", ALC287_FIXUP_TAS2781_I2C),
> + SND_PCI_QUIRK(0x17aa, 0x38cb, "Y790 YG DUAL",
> + ALC287_FIXUP_TAS2781_I2C),
> + SND_PCI_QUIRK(0x17aa, 0x38cd, "Y790 VECO DUAL",
> + ALC287_FIXUP_TAS2781_I2C),
Please keep one entry per line. Let's ignore the checkpatch
complaints.
> @@ -10728,6 +10823,17 @@ static int patch_alc269(struct hda_codec *codec)
> codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
> }
>
> + /* FIXME: Laptop 0x17aa38be will get the wrong fixup_id and
> + * enter into the wrong entry.
> + * Correct the wrong entry.
> + */
> + if (codec->fixup_id == ALC287_FIXUP_YOGA7_14ITL_SPEAKERS &&
> + codec->core.vendor_id == 0x10ec0287 &&
> + codec->core.subsystem_id == 0x17aa38be) {
> + codec_dbg(codec, "Clear wrong fixup for 17aa38be\n");
> + codec->fixup_id = ALC287_FIXUP_TAS2781_I2C;
> + }
Why this is needed at all? IOW, which entry causes this wrong
attribute?
thanks,
Takashi