sound fixes for 6.8-rc5
A collection of device-specific fixes. It became a bit bigger than wished, but all look reasonably small and safe to apply. - A few Cirrus Logic CS35L56 and CS42L43 driver fixes - ASoC SOF fixes and workarounds - Various ASoC Intel fixes - Lots of HD-, USB-audio and AMD ACP quirks -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmXPayMOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE8wnhAAvJIP/ZCsVnOKkTPcns9shxcI8zaFKWOdOOny mfL2M44glIxbcdUBDM2Ic1MX2lK6WVpDDXo+leAbbITLN985MFFwhg/NzS7QbEQu ZRi28Keubbh2zqPzBOajiS1s10ELlQtiIGGEHccspElMEesitNqu0Hmd4NSWnTCX iTsx4JwDQiiO1cOdanJ7134Jngp6q05nFVM3Y47wmqYLkP9z9/2hCRsq8scZ2f40 Blc7oEfqT10HFqXCqVZsHbLioDC03eCD9AoiUkkqDb/Hz21wemmyeiXT4OmbAIFp ritzPz1RpeJhsOURyiE3KM2kQluh+JBK5Rq3eJ1tmxJbIWEAwbYRXs+yRHr2i6Xi oOBVBc9Dq2RwKV7RnWIcV3+ZxrERJp80a4TKMSpQyECkDGiwZLyS/nGfM2+fJKg8 c66ofk+TfsnYZfKaonXwVf+HVqoMLsAo6bxle/0gLT6S3G6DvSGj3pWGqF8uZQJt vpUbqSJBEI0JZTLngkWZRHPrLcCu+W+9/QrkTRYdwZUh5DfS9wbzXVz2Jm3cXpnB os3v+lfJwXS6FBT51zCbO8BKbXPlaIQbLwPRW2+5zI2MaoEocAm0lSU1SXGcOuJY 6N5t6hHHNn7g7Gv8oimHQCKvzOUjnyVCDAn7P7/ILjoV47oQH9QRoNmHNNLjSzj1 4xr4yCg= =PlQh -----END PGP SIGNATURE----- Merge tag 'sound-6.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "A collection of device-specific fixes. It became a bit bigger than wished, but all look reasonably small and safe to apply. - A few Cirrus Logic CS35L56 and CS42L43 driver fixes - ASoC SOF fixes and workarounds - Various ASoC Intel fixes - Lots of HD-, USB-audio and AMD ACP quirks" * tag 'sound-6.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (33 commits) ALSA: usb-audio: More relaxed check of MIDI jack names ALSA: hda/realtek: fix mute/micmute LED For HP mt645 ALSA: hda/realtek: cs35l41: Fix order and duplicates in quirks table ALSA: hda/realtek: cs35l41: Fix device ID / model name ALSA: hda/realtek: cs35l41: Add internal speaker support for ASUS UM3402 with missing DSD ASoC: cs35l56: Workaround for ACPI with broken spk-id-gpios property ALSA: hda: Add Lenovo Legion 7i gen7 sound quirk ASoC: SOF: IPC3: fix message bounds on ipc ops ASoC: SOF: ipc4-pcm: Workaround for crashed firmware on system suspend ASoC: q6dsp: fix event handler prototype ASoC: SOF: Intel: pci-lnl: Change the topology path to intel/sof-ipc4-tplg ASoC: SOF: Intel: pci-tgl: Change the default paths and firmware names ASoC: amd: yc: Fix non-functional mic on Lenovo 82UU ASoC: rt5645: Add DMI quirk for inverted jack-detect on MeeGoPad T8 ASoC: rt5645: Make LattePanda board DMI match more precise ASoC: SOF: amd: Fix locking in ACP IRQ handler ASoC: rt5645: Fix deadlock in rt5645_jack_detect_work() ASoC: Intel: cht_bsw_rt5645: Cleanup codec_name handling ASoC: Intel: Boards: Fix NULL pointer deref in BYT/CHT boards ASoC: cs35l56: Remove default from IRQ1_CFG register ...
This commit is contained in:
commit
0f1dd5e91e
@ -7,7 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: Google SC7280-Herobrine ASoC sound card driver
|
||||
|
||||
maintainers:
|
||||
- Srinivasa Rao Mandadapu <srivasam@codeaurora.org>
|
||||
- Judy Hsiao <judyhsiao@chromium.org>
|
||||
|
||||
description:
|
||||
|
@ -142,6 +142,7 @@ struct tasdevice_priv {
|
||||
|
||||
void tas2781_reset(struct tasdevice_priv *tas_dev);
|
||||
int tascodec_init(struct tasdevice_priv *tas_priv, void *codec,
|
||||
struct module *module,
|
||||
void (*cont)(const struct firmware *fw, void *context));
|
||||
struct tasdevice_priv *tasdevice_kzalloc(struct i2c_client *i2c);
|
||||
int tasdevice_init(struct tasdevice_priv *tas_priv);
|
||||
|
@ -156,7 +156,7 @@ config SND_HDA_SCODEC_CS35L56_I2C
|
||||
depends on I2C
|
||||
depends on ACPI || COMPILE_TEST
|
||||
depends on SND_SOC
|
||||
select CS_DSP
|
||||
select FW_CS_DSP
|
||||
select SND_HDA_GENERIC
|
||||
select SND_SOC_CS35L56_SHARED
|
||||
select SND_HDA_SCODEC_CS35L56
|
||||
@ -171,7 +171,7 @@ config SND_HDA_SCODEC_CS35L56_SPI
|
||||
depends on SPI_MASTER
|
||||
depends on ACPI || COMPILE_TEST
|
||||
depends on SND_SOC
|
||||
select CS_DSP
|
||||
select FW_CS_DSP
|
||||
select SND_HDA_GENERIC
|
||||
select SND_SOC_CS35L56_SHARED
|
||||
select SND_HDA_SCODEC_CS35L56
|
||||
|
@ -91,10 +91,12 @@ static const struct cs35l41_config cs35l41_config_table[] = {
|
||||
{ "10431D1F", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431DA2", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
|
||||
{ "10431E02", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
|
||||
{ "10431E12", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
|
||||
{ "10431EE2", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 },
|
||||
{ "10431F12", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431F1F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 },
|
||||
{ "10431F62", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
|
||||
{ "17AA386F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 },
|
||||
{ "17AA38B4", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
|
||||
{ "17AA38B5", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
|
||||
{ "17AA38B6", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
|
||||
@ -427,10 +429,12 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
|
||||
{ "CSC3551", "10431D1F", generic_dsd_config },
|
||||
{ "CSC3551", "10431DA2", generic_dsd_config },
|
||||
{ "CSC3551", "10431E02", generic_dsd_config },
|
||||
{ "CSC3551", "10431E12", generic_dsd_config },
|
||||
{ "CSC3551", "10431EE2", generic_dsd_config },
|
||||
{ "CSC3551", "10431F12", generic_dsd_config },
|
||||
{ "CSC3551", "10431F1F", generic_dsd_config },
|
||||
{ "CSC3551", "10431F62", generic_dsd_config },
|
||||
{ "CSC3551", "17AA386F", generic_dsd_config },
|
||||
{ "CSC3551", "17AA38B4", generic_dsd_config },
|
||||
{ "CSC3551", "17AA38B5", generic_dsd_config },
|
||||
{ "CSC3551", "17AA38B6", generic_dsd_config },
|
||||
|
@ -344,6 +344,7 @@ enum {
|
||||
CXT_FIXUP_HP_ZBOOK_MUTE_LED,
|
||||
CXT_FIXUP_HEADSET_MIC,
|
||||
CXT_FIXUP_HP_MIC_NO_PRESENCE,
|
||||
CXT_PINCFG_SWS_JS201D,
|
||||
};
|
||||
|
||||
/* for hda_fixup_thinkpad_acpi() */
|
||||
@ -841,6 +842,17 @@ static const struct hda_pintbl cxt_pincfg_lemote[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
/* SuoWoSi/South-holding JS201D with sn6140 */
|
||||
static const struct hda_pintbl cxt_pincfg_sws_js201d[] = {
|
||||
{ 0x16, 0x03211040 }, /* hp out */
|
||||
{ 0x17, 0x91170110 }, /* SPK/Class_D */
|
||||
{ 0x18, 0x95a70130 }, /* Internal mic */
|
||||
{ 0x19, 0x03a11020 }, /* Headset Mic */
|
||||
{ 0x1a, 0x40f001f0 }, /* Not used */
|
||||
{ 0x21, 0x40f001f0 }, /* Not used */
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct hda_fixup cxt_fixups[] = {
|
||||
[CXT_PINCFG_LENOVO_X200] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
@ -996,6 +1008,10 @@ static const struct hda_fixup cxt_fixups[] = {
|
||||
.chained = true,
|
||||
.chain_id = CXT_FIXUP_HEADSET_MIC,
|
||||
},
|
||||
[CXT_PINCFG_SWS_JS201D] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = cxt_pincfg_sws_js201d,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_pci_quirk cxt5045_fixups[] = {
|
||||
@ -1069,6 +1085,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x8457, "HP Z2 G4 mini", CXT_FIXUP_HP_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x103c, 0x8458, "HP Z2 G4 mini premium", CXT_FIXUP_HP_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN),
|
||||
SND_PCI_QUIRK(0x14f1, 0x0265, "SWS JS201D", CXT_PINCFG_SWS_JS201D),
|
||||
SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO),
|
||||
SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
|
||||
SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410),
|
||||
@ -1109,6 +1126,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = {
|
||||
{ .id = CXT_FIXUP_HP_ZBOOK_MUTE_LED, .name = "hp-zbook-mute-led" },
|
||||
{ .id = CXT_FIXUP_HP_MIC_NO_PRESENCE, .name = "hp-mic-fix" },
|
||||
{ .id = CXT_PINCFG_LENOVO_NOTEBOOK, .name = "lenovo-20149" },
|
||||
{ .id = CXT_PINCFG_SWS_JS201D, .name = "sws-js201d" },
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -9737,7 +9737,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1028, 0x0b71, "Dell Inspiron 16 Plus 7620", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
|
||||
SND_PCI_QUIRK(0x1028, 0x0beb, "Dell XPS 15 9530 (2023)", ALC289_FIXUP_DELL_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1028, 0x0c03, "Dell Precision 5340", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0c0b, "Dell Oasis 14 RPL-P", ALC289_FIXUP_RTK_AMP_DUAL_SPK),
|
||||
SND_PCI_QUIRK(0x1028, 0x0c0d, "Dell Oasis", ALC289_FIXUP_RTK_AMP_DUAL_SPK),
|
||||
SND_PCI_QUIRK(0x1028, 0x0c0e, "Dell Oasis 16", ALC289_FIXUP_RTK_AMP_DUAL_SPK),
|
||||
SND_PCI_QUIRK(0x1028, 0x0c19, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS),
|
||||
SND_PCI_QUIRK(0x1028, 0x0c1a, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS),
|
||||
SND_PCI_QUIRK(0x1028, 0x0c1b, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS),
|
||||
@ -9928,6 +9930,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x8abb, "HP ZBook Firefly 14 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8ad1, "HP EliteBook 840 14 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b0f, "HP Elite mt645 G7 Mobile Thin Client U81", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b2f, "HP 255 15.6 inch G10 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b42, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b43, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
||||
@ -9935,6 +9938,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x8b45, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b46, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b47, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b59, "HP Elite mt645 G7 Mobile Thin Client U89", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b5d, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b5e, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b63, "HP Elite Dragonfly 13.5 inch G4", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED),
|
||||
@ -10003,6 +10007,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK),
|
||||
SND_PCI_QUIRK(0x1043, 0x1663, "ASUS GU603ZI/ZJ/ZQ/ZU/ZV", ALC285_FIXUP_ASUS_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1683, "ASUS UM3402YAR", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS UX3402VA", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401),
|
||||
SND_PCI_QUIRK(0x1043, 0x16d3, "ASUS UX5304VA", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
|
||||
@ -10046,14 +10051,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE),
|
||||
SND_PCI_QUIRK(0x1043, 0x1da2, "ASUS UP6502ZA/ZD", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402ZA", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS UX3402VA", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1f62, "ASUS UX7602ZM", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502),
|
||||
SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM6702RA/RC", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS),
|
||||
SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS),
|
||||
SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
|
||||
SND_PCI_QUIRK(0x1043, 0x1ee2, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401),
|
||||
SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401),
|
||||
SND_PCI_QUIRK(0x1043, 0x1f12, "ASUS UM5302", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
@ -10260,6 +10263,7 @@ 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, 0x386f, "Legion 7i 16IAX7", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x17aa, 0x3870, "Lenovo Yoga 7 14ARB7", ALC287_FIXUP_YOGA7_14ARB7_I2C),
|
||||
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),
|
||||
|
@ -710,7 +710,7 @@ static int tas2781_hda_bind(struct device *dev, struct device *master,
|
||||
|
||||
strscpy(comps->name, dev_name(dev), sizeof(comps->name));
|
||||
|
||||
ret = tascodec_init(tas_hda->priv, codec, tasdev_fw_ready);
|
||||
ret = tascodec_init(tas_hda->priv, codec, THIS_MODULE, tasdev_fw_ready);
|
||||
if (!ret)
|
||||
comps->playback_hook = tas2781_hda_playback_hook;
|
||||
|
||||
|
@ -234,6 +234,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "82UG"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "82UU"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
@ -248,6 +255,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "82YM"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "83AS"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
|
@ -51,7 +51,6 @@ static const struct reg_default cs35l56_reg_defaults[] = {
|
||||
{ CS35L56_SWIRE_DP3_CH2_INPUT, 0x00000019 },
|
||||
{ CS35L56_SWIRE_DP3_CH3_INPUT, 0x00000029 },
|
||||
{ CS35L56_SWIRE_DP3_CH4_INPUT, 0x00000028 },
|
||||
{ CS35L56_IRQ1_CFG, 0x00000000 },
|
||||
{ CS35L56_IRQ1_MASK_1, 0x83ffffff },
|
||||
{ CS35L56_IRQ1_MASK_2, 0xffff7fff },
|
||||
{ CS35L56_IRQ1_MASK_4, 0xe0ffffff },
|
||||
|
@ -5,6 +5,7 @@
|
||||
// Copyright (C) 2023 Cirrus Logic, Inc. and
|
||||
// Cirrus Logic International Semiconductor Ltd.
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/delay.h>
|
||||
@ -15,6 +16,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
@ -68,6 +70,66 @@ static const char * const cs35l56_asp1_mux_control_names[] = {
|
||||
"ASP1 TX1 Source", "ASP1 TX2 Source", "ASP1 TX3 Source", "ASP1 TX4 Source"
|
||||
};
|
||||
|
||||
static int cs35l56_sync_asp1_mixer_widgets_with_firmware(struct cs35l56_private *cs35l56)
|
||||
{
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cs35l56->component);
|
||||
const char *prefix = cs35l56->component->name_prefix;
|
||||
char full_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
||||
const char *name;
|
||||
struct snd_kcontrol *kcontrol;
|
||||
struct soc_enum *e;
|
||||
unsigned int val[4];
|
||||
int i, item, ret;
|
||||
|
||||
if (cs35l56->asp1_mixer_widgets_initialized)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Resume so we can read the registers from silicon if the regmap
|
||||
* cache has not yet been populated.
|
||||
*/
|
||||
ret = pm_runtime_resume_and_get(cs35l56->base.dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Wait for firmware download and reboot */
|
||||
cs35l56_wait_dsp_ready(cs35l56);
|
||||
|
||||
ret = regmap_bulk_read(cs35l56->base.regmap, CS35L56_ASP1TX1_INPUT,
|
||||
val, ARRAY_SIZE(val));
|
||||
|
||||
pm_runtime_mark_last_busy(cs35l56->base.dev);
|
||||
pm_runtime_put_autosuspend(cs35l56->base.dev);
|
||||
|
||||
if (ret) {
|
||||
dev_err(cs35l56->base.dev, "Failed to read ASP1 mixer regs: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cs35l56_asp1_mux_control_names); ++i) {
|
||||
name = cs35l56_asp1_mux_control_names[i];
|
||||
|
||||
if (prefix) {
|
||||
snprintf(full_name, sizeof(full_name), "%s %s", prefix, name);
|
||||
name = full_name;
|
||||
}
|
||||
|
||||
kcontrol = snd_soc_card_get_kcontrol(dapm->card, name);
|
||||
if (!kcontrol) {
|
||||
dev_warn(cs35l56->base.dev, "Could not find control %s\n", name);
|
||||
continue;
|
||||
}
|
||||
|
||||
e = (struct soc_enum *)kcontrol->private_value;
|
||||
item = snd_soc_enum_val_to_item(e, val[i] & CS35L56_ASP_TXn_SRC_MASK);
|
||||
snd_soc_dapm_mux_update_power(dapm, kcontrol, item, e, NULL);
|
||||
}
|
||||
|
||||
cs35l56->asp1_mixer_widgets_initialized = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs35l56_dspwait_asp1tx_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
@ -78,9 +140,9 @@ static int cs35l56_dspwait_asp1tx_get(struct snd_kcontrol *kcontrol,
|
||||
unsigned int addr, val;
|
||||
int ret;
|
||||
|
||||
/* Wait for mux to be initialized */
|
||||
cs35l56_wait_dsp_ready(cs35l56);
|
||||
flush_work(&cs35l56->mux_init_work);
|
||||
ret = cs35l56_sync_asp1_mixer_widgets_with_firmware(cs35l56);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
addr = cs35l56_asp1_mixer_regs[index];
|
||||
ret = regmap_read(cs35l56->base.regmap, addr, &val);
|
||||
@ -106,16 +168,16 @@ static int cs35l56_dspwait_asp1tx_put(struct snd_kcontrol *kcontrol,
|
||||
bool changed;
|
||||
int ret;
|
||||
|
||||
/* Wait for mux to be initialized */
|
||||
cs35l56_wait_dsp_ready(cs35l56);
|
||||
flush_work(&cs35l56->mux_init_work);
|
||||
ret = cs35l56_sync_asp1_mixer_widgets_with_firmware(cs35l56);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
addr = cs35l56_asp1_mixer_regs[index];
|
||||
val = snd_soc_enum_item_to_val(e, item);
|
||||
|
||||
ret = regmap_update_bits_check(cs35l56->base.regmap, addr,
|
||||
CS35L56_ASP_TXn_SRC_MASK, val, &changed);
|
||||
if (!ret)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (changed)
|
||||
@ -124,70 +186,6 @@ static int cs35l56_dspwait_asp1tx_put(struct snd_kcontrol *kcontrol,
|
||||
return changed;
|
||||
}
|
||||
|
||||
static void cs35l56_mark_asp1_mixer_widgets_dirty(struct cs35l56_private *cs35l56)
|
||||
{
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cs35l56->component);
|
||||
const char *prefix = cs35l56->component->name_prefix;
|
||||
char full_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
||||
const char *name;
|
||||
struct snd_kcontrol *kcontrol;
|
||||
struct soc_enum *e;
|
||||
unsigned int val[4];
|
||||
int i, item, ret;
|
||||
|
||||
/*
|
||||
* Resume so we can read the registers from silicon if the regmap
|
||||
* cache has not yet been populated.
|
||||
*/
|
||||
ret = pm_runtime_resume_and_get(cs35l56->base.dev);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
ret = regmap_bulk_read(cs35l56->base.regmap, CS35L56_ASP1TX1_INPUT,
|
||||
val, ARRAY_SIZE(val));
|
||||
|
||||
pm_runtime_mark_last_busy(cs35l56->base.dev);
|
||||
pm_runtime_put_autosuspend(cs35l56->base.dev);
|
||||
|
||||
if (ret) {
|
||||
dev_err(cs35l56->base.dev, "Failed to read ASP1 mixer regs: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
snd_soc_card_mutex_lock(dapm->card);
|
||||
WARN_ON(!dapm->card->instantiated);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cs35l56_asp1_mux_control_names); ++i) {
|
||||
name = cs35l56_asp1_mux_control_names[i];
|
||||
|
||||
if (prefix) {
|
||||
snprintf(full_name, sizeof(full_name), "%s %s", prefix, name);
|
||||
name = full_name;
|
||||
}
|
||||
|
||||
kcontrol = snd_soc_card_get_kcontrol(dapm->card, name);
|
||||
if (!kcontrol) {
|
||||
dev_warn(cs35l56->base.dev, "Could not find control %s\n", name);
|
||||
continue;
|
||||
}
|
||||
|
||||
e = (struct soc_enum *)kcontrol->private_value;
|
||||
item = snd_soc_enum_val_to_item(e, val[i] & CS35L56_ASP_TXn_SRC_MASK);
|
||||
snd_soc_dapm_mux_update_power(dapm, kcontrol, item, e, NULL);
|
||||
}
|
||||
|
||||
snd_soc_card_mutex_unlock(dapm->card);
|
||||
}
|
||||
|
||||
static void cs35l56_mux_init_work(struct work_struct *work)
|
||||
{
|
||||
struct cs35l56_private *cs35l56 = container_of(work,
|
||||
struct cs35l56_private,
|
||||
mux_init_work);
|
||||
|
||||
cs35l56_mark_asp1_mixer_widgets_dirty(cs35l56);
|
||||
}
|
||||
|
||||
static DECLARE_TLV_DB_SCALE(vol_tlv, -10000, 25, 0);
|
||||
|
||||
static const struct snd_kcontrol_new cs35l56_controls[] = {
|
||||
@ -936,14 +934,6 @@ static void cs35l56_dsp_work(struct work_struct *work)
|
||||
else
|
||||
cs35l56_patch(cs35l56, firmware_missing);
|
||||
|
||||
|
||||
/*
|
||||
* Set starting value of ASP1 mux widgets. Updating a mux takes
|
||||
* the DAPM mutex. Post this to a separate job so that DAPM
|
||||
* power-up can wait for dsp_work to complete without deadlocking
|
||||
* on the DAPM mutex.
|
||||
*/
|
||||
queue_work(cs35l56->dsp_wq, &cs35l56->mux_init_work);
|
||||
err:
|
||||
pm_runtime_mark_last_busy(cs35l56->base.dev);
|
||||
pm_runtime_put_autosuspend(cs35l56->base.dev);
|
||||
@ -989,6 +979,13 @@ static int cs35l56_component_probe(struct snd_soc_component *component)
|
||||
debugfs_create_bool("can_hibernate", 0444, debugfs_root, &cs35l56->base.can_hibernate);
|
||||
debugfs_create_bool("fw_patched", 0444, debugfs_root, &cs35l56->base.fw_patched);
|
||||
|
||||
/*
|
||||
* The widgets for the ASP1TX mixer can't be initialized
|
||||
* until the firmware has been downloaded and rebooted.
|
||||
*/
|
||||
regcache_drop_region(cs35l56->base.regmap, CS35L56_ASP1TX1_INPUT, CS35L56_ASP1TX4_INPUT);
|
||||
cs35l56->asp1_mixer_widgets_initialized = false;
|
||||
|
||||
queue_work(cs35l56->dsp_wq, &cs35l56->dsp_work);
|
||||
|
||||
return 0;
|
||||
@ -999,7 +996,6 @@ static void cs35l56_component_remove(struct snd_soc_component *component)
|
||||
struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
cancel_work_sync(&cs35l56->dsp_work);
|
||||
cancel_work_sync(&cs35l56->mux_init_work);
|
||||
|
||||
if (cs35l56->dsp.cs_dsp.booted)
|
||||
wm_adsp_power_down(&cs35l56->dsp);
|
||||
@ -1070,10 +1066,8 @@ int cs35l56_system_suspend(struct device *dev)
|
||||
|
||||
dev_dbg(dev, "system_suspend\n");
|
||||
|
||||
if (cs35l56->component) {
|
||||
if (cs35l56->component)
|
||||
flush_work(&cs35l56->dsp_work);
|
||||
cancel_work_sync(&cs35l56->mux_init_work);
|
||||
}
|
||||
|
||||
/*
|
||||
* The interrupt line is normally shared, but after we start suspending
|
||||
@ -1224,7 +1218,6 @@ static int cs35l56_dsp_init(struct cs35l56_private *cs35l56)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_WORK(&cs35l56->dsp_work, cs35l56_dsp_work);
|
||||
INIT_WORK(&cs35l56->mux_init_work, cs35l56_mux_init_work);
|
||||
|
||||
dsp = &cs35l56->dsp;
|
||||
cs35l56_init_cs_dsp(&cs35l56->base, &dsp->cs_dsp);
|
||||
@ -1269,6 +1262,94 @@ static int cs35l56_get_firmware_uid(struct cs35l56_private *cs35l56)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some SoundWire laptops have a spk-id-gpios property but it points to
|
||||
* the wrong ACPI Device node so can't be used to get the GPIO. Try to
|
||||
* find the SDCA node containing the GpioIo resource and add a GPIO
|
||||
* mapping to it.
|
||||
*/
|
||||
static const struct acpi_gpio_params cs35l56_af01_first_gpio = { 0, 0, false };
|
||||
static const struct acpi_gpio_mapping cs35l56_af01_spkid_gpios_mapping[] = {
|
||||
{ "spk-id-gpios", &cs35l56_af01_first_gpio, 1 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static void cs35l56_acpi_dev_release_driver_gpios(void *adev)
|
||||
{
|
||||
acpi_dev_remove_driver_gpios(adev);
|
||||
}
|
||||
|
||||
static int cs35l56_try_get_broken_sdca_spkid_gpio(struct cs35l56_private *cs35l56)
|
||||
{
|
||||
struct fwnode_handle *af01_fwnode;
|
||||
const union acpi_object *obj;
|
||||
struct gpio_desc *desc;
|
||||
int ret;
|
||||
|
||||
/* Find the SDCA node containing the GpioIo */
|
||||
af01_fwnode = device_get_named_child_node(cs35l56->base.dev, "AF01");
|
||||
if (!af01_fwnode) {
|
||||
dev_dbg(cs35l56->base.dev, "No AF01 node\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ret = acpi_dev_get_property(ACPI_COMPANION(cs35l56->base.dev),
|
||||
"spk-id-gpios", ACPI_TYPE_PACKAGE, &obj);
|
||||
if (ret) {
|
||||
dev_dbg(cs35l56->base.dev, "Could not get spk-id-gpios package: %d\n", ret);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* The broken properties we can handle are a 4-element package (one GPIO) */
|
||||
if (obj->package.count != 4) {
|
||||
dev_warn(cs35l56->base.dev, "Unexpected spk-id element count %d\n",
|
||||
obj->package.count);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Add a GPIO mapping if it doesn't already have one */
|
||||
if (!fwnode_property_present(af01_fwnode, "spk-id-gpios")) {
|
||||
struct acpi_device *adev = to_acpi_device_node(af01_fwnode);
|
||||
|
||||
/*
|
||||
* Can't use devm_acpi_dev_add_driver_gpios() because the
|
||||
* mapping isn't being added to the node pointed to by
|
||||
* ACPI_COMPANION().
|
||||
*/
|
||||
ret = acpi_dev_add_driver_gpios(adev, cs35l56_af01_spkid_gpios_mapping);
|
||||
if (ret) {
|
||||
return dev_err_probe(cs35l56->base.dev, ret,
|
||||
"Failed to add gpio mapping to AF01\n");
|
||||
}
|
||||
|
||||
ret = devm_add_action_or_reset(cs35l56->base.dev,
|
||||
cs35l56_acpi_dev_release_driver_gpios,
|
||||
adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_dbg(cs35l56->base.dev, "Added spk-id-gpios mapping to AF01\n");
|
||||
}
|
||||
|
||||
desc = fwnode_gpiod_get_index(af01_fwnode, "spk-id", 0, GPIOD_IN, NULL);
|
||||
if (IS_ERR(desc)) {
|
||||
ret = PTR_ERR(desc);
|
||||
return dev_err_probe(cs35l56->base.dev, ret, "Get GPIO from AF01 failed\n");
|
||||
}
|
||||
|
||||
ret = gpiod_get_value_cansleep(desc);
|
||||
gpiod_put(desc);
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err_probe(cs35l56->base.dev, ret, "Error reading spk-id GPIO\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_info(cs35l56->base.dev, "Got spk-id from AF01\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cs35l56_common_probe(struct cs35l56_private *cs35l56)
|
||||
{
|
||||
int ret;
|
||||
@ -1313,6 +1394,9 @@ int cs35l56_common_probe(struct cs35l56_private *cs35l56)
|
||||
}
|
||||
|
||||
ret = cs35l56_get_speaker_id(&cs35l56->base);
|
||||
if (ACPI_COMPANION(cs35l56->base.dev) && cs35l56->sdw_peripheral && (ret == -ENOENT))
|
||||
ret = cs35l56_try_get_broken_sdca_spkid_gpio(cs35l56);
|
||||
|
||||
if ((ret < 0) && (ret != -ENOENT))
|
||||
goto err;
|
||||
|
||||
|
@ -34,7 +34,6 @@ struct cs35l56_private {
|
||||
struct wm_adsp dsp; /* must be first member */
|
||||
struct cs35l56_base base;
|
||||
struct work_struct dsp_work;
|
||||
struct work_struct mux_init_work;
|
||||
struct workqueue_struct *dsp_wq;
|
||||
struct snd_soc_component *component;
|
||||
struct regulator_bulk_data supplies[CS35L56_NUM_BULK_SUPPLIES];
|
||||
@ -52,6 +51,7 @@ struct cs35l56_private {
|
||||
u8 asp_slot_count;
|
||||
bool tdm_mode;
|
||||
bool sysclk_set;
|
||||
bool asp1_mixer_widgets_initialized;
|
||||
u8 old_sdw_clock_scale;
|
||||
};
|
||||
|
||||
|
@ -2257,7 +2257,10 @@ static int cs42l43_codec_probe(struct platform_device *pdev)
|
||||
pm_runtime_use_autosuspend(priv->dev);
|
||||
pm_runtime_set_active(priv->dev);
|
||||
pm_runtime_get_noresume(priv->dev);
|
||||
devm_pm_runtime_enable(priv->dev);
|
||||
|
||||
ret = devm_pm_runtime_enable(priv->dev);
|
||||
if (ret)
|
||||
goto err_pm;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cs42l43_irqs); i++) {
|
||||
ret = cs42l43_request_irq(priv, dom, cs42l43_irqs[i].name,
|
||||
@ -2333,8 +2336,47 @@ static int cs42l43_codec_runtime_resume(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEFINE_RUNTIME_DEV_PM_OPS(cs42l43_codec_pm_ops, NULL,
|
||||
cs42l43_codec_runtime_resume, NULL);
|
||||
static int cs42l43_codec_suspend(struct device *dev)
|
||||
{
|
||||
struct cs42l43 *cs42l43 = dev_get_drvdata(dev);
|
||||
|
||||
disable_irq(cs42l43->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs42l43_codec_suspend_noirq(struct device *dev)
|
||||
{
|
||||
struct cs42l43 *cs42l43 = dev_get_drvdata(dev);
|
||||
|
||||
enable_irq(cs42l43->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs42l43_codec_resume(struct device *dev)
|
||||
{
|
||||
struct cs42l43 *cs42l43 = dev_get_drvdata(dev);
|
||||
|
||||
enable_irq(cs42l43->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs42l43_codec_resume_noirq(struct device *dev)
|
||||
{
|
||||
struct cs42l43 *cs42l43 = dev_get_drvdata(dev);
|
||||
|
||||
disable_irq(cs42l43->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops cs42l43_codec_pm_ops = {
|
||||
SYSTEM_SLEEP_PM_OPS(cs42l43_codec_suspend, cs42l43_codec_resume)
|
||||
NOIRQ_SYSTEM_SLEEP_PM_OPS(cs42l43_codec_suspend_noirq, cs42l43_codec_resume_noirq)
|
||||
RUNTIME_PM_OPS(NULL, cs42l43_codec_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
static const struct platform_device_id cs42l43_codec_id_table[] = {
|
||||
{ "cs42l43-codec", },
|
||||
|
@ -3317,6 +3317,7 @@ static void rt5645_jack_detect_work(struct work_struct *work)
|
||||
report, SND_JACK_HEADPHONE);
|
||||
snd_soc_jack_report(rt5645->mic_jack,
|
||||
report, SND_JACK_MICROPHONE);
|
||||
mutex_unlock(&rt5645->jd_mutex);
|
||||
return;
|
||||
case 4:
|
||||
val = snd_soc_component_read(rt5645->component, RT5645_A_JD_CTRL1) & 0x0020;
|
||||
@ -3692,6 +3693,11 @@ static const struct rt5645_platform_data jd_mode3_monospk_platform_data = {
|
||||
.mono_speaker = true,
|
||||
};
|
||||
|
||||
static const struct rt5645_platform_data jd_mode3_inv_data = {
|
||||
.jd_mode = 3,
|
||||
.inv_jd1_1 = true,
|
||||
};
|
||||
|
||||
static const struct rt5645_platform_data jd_mode3_platform_data = {
|
||||
.jd_mode = 3,
|
||||
};
|
||||
@ -3837,6 +3843,16 @@ static const struct dmi_system_id dmi_platform_data[] = {
|
||||
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
|
||||
DMI_EXACT_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
|
||||
DMI_EXACT_MATCH(DMI_BOARD_VERSION, "Default string"),
|
||||
/*
|
||||
* Above strings are too generic, LattePanda BIOS versions for
|
||||
* all 4 hw revisions are:
|
||||
* DF-BI-7-S70CR100-*
|
||||
* DF-BI-7-S70CR110-*
|
||||
* DF-BI-7-S70CR200-*
|
||||
* LP-BS-7-S70CR700-*
|
||||
* Do a partial match for S70CR to avoid false positive matches.
|
||||
*/
|
||||
DMI_MATCH(DMI_BIOS_VERSION, "S70CR"),
|
||||
},
|
||||
.driver_data = (void *)&lattepanda_board_platform_data,
|
||||
},
|
||||
@ -3871,6 +3887,16 @@ static const struct dmi_system_id dmi_platform_data[] = {
|
||||
},
|
||||
.driver_data = (void *)&intel_braswell_platform_data,
|
||||
},
|
||||
{
|
||||
.ident = "Meegopad T08",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Default string"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "T3 MRD"),
|
||||
DMI_MATCH(DMI_BOARD_VERSION, "V1.1"),
|
||||
},
|
||||
.driver_data = (void *)&jd_mode3_inv_data,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -267,6 +267,7 @@ void tas2781_reset(struct tasdevice_priv *tas_dev)
|
||||
EXPORT_SYMBOL_GPL(tas2781_reset);
|
||||
|
||||
int tascodec_init(struct tasdevice_priv *tas_priv, void *codec,
|
||||
struct module *module,
|
||||
void (*cont)(const struct firmware *fw, void *context))
|
||||
{
|
||||
int ret = 0;
|
||||
@ -280,7 +281,7 @@ int tascodec_init(struct tasdevice_priv *tas_priv, void *codec,
|
||||
tas_priv->dev_name, tas_priv->ndev);
|
||||
crc8_populate_msb(tas_priv->crc8_lkp_tbl, TASDEVICE_CRC8_POLYNOMIAL);
|
||||
tas_priv->codec = codec;
|
||||
ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT,
|
||||
ret = request_firmware_nowait(module, FW_ACTION_UEVENT,
|
||||
tas_priv->rca_binaryname, tas_priv->dev, GFP_KERNEL, tas_priv,
|
||||
cont);
|
||||
if (ret)
|
||||
|
@ -566,7 +566,7 @@ static int tasdevice_codec_probe(struct snd_soc_component *codec)
|
||||
{
|
||||
struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(codec);
|
||||
|
||||
return tascodec_init(tas_priv, codec, tasdevice_fw_ready);
|
||||
return tascodec_init(tas_priv, codec, THIS_MODULE, tasdevice_fw_ready);
|
||||
}
|
||||
|
||||
static void tasdevice_deinit(void *context)
|
||||
|
@ -477,6 +477,9 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
|
||||
return 0;
|
||||
|
||||
err_i915_init:
|
||||
pci_free_irq(pci, 0, adev);
|
||||
pci_free_irq(pci, 0, bus);
|
||||
pci_free_irq_vectors(pci);
|
||||
pci_clear_master(pci);
|
||||
pci_set_drvdata(pci, NULL);
|
||||
err_acquire_irq:
|
||||
|
@ -857,7 +857,7 @@ assign_copier_gtw_instance(struct snd_soc_component *comp, struct avs_tplg_modcf
|
||||
}
|
||||
|
||||
/* If topology sets value don't overwrite it */
|
||||
if (cfg->copier.vindex.i2s.instance)
|
||||
if (cfg->copier.vindex.val)
|
||||
return;
|
||||
|
||||
mach = dev_get_platdata(comp->card->dev);
|
||||
|
@ -241,7 +241,8 @@ static int snd_byt_cht_cx2072x_probe(struct platform_device *pdev)
|
||||
|
||||
/* fix index of codec dai */
|
||||
for (i = 0; i < ARRAY_SIZE(byt_cht_cx2072x_dais); i++) {
|
||||
if (!strcmp(byt_cht_cx2072x_dais[i].codecs->name,
|
||||
if (byt_cht_cx2072x_dais[i].codecs->name &&
|
||||
!strcmp(byt_cht_cx2072x_dais[i].codecs->name,
|
||||
"i2c-14F10720:00")) {
|
||||
dai_index = i;
|
||||
break;
|
||||
|
@ -245,7 +245,8 @@ static int bytcht_da7213_probe(struct platform_device *pdev)
|
||||
|
||||
/* fix index of codec dai */
|
||||
for (i = 0; i < ARRAY_SIZE(dailink); i++) {
|
||||
if (!strcmp(dailink[i].codecs->name, "i2c-DLGS7213:00")) {
|
||||
if (dailink[i].codecs->name &&
|
||||
!strcmp(dailink[i].codecs->name, "i2c-DLGS7213:00")) {
|
||||
dai_index = i;
|
||||
break;
|
||||
}
|
||||
|
@ -546,7 +546,8 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
|
||||
|
||||
/* fix index of codec dai */
|
||||
for (i = 0; i < ARRAY_SIZE(byt_cht_es8316_dais); i++) {
|
||||
if (!strcmp(byt_cht_es8316_dais[i].codecs->name,
|
||||
if (byt_cht_es8316_dais[i].codecs->name &&
|
||||
!strcmp(byt_cht_es8316_dais[i].codecs->name,
|
||||
"i2c-ESSX8316:00")) {
|
||||
dai_index = i;
|
||||
break;
|
||||
|
@ -1652,7 +1652,8 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
|
||||
|
||||
/* fix index of codec dai */
|
||||
for (i = 0; i < ARRAY_SIZE(byt_rt5640_dais); i++) {
|
||||
if (!strcmp(byt_rt5640_dais[i].codecs->name,
|
||||
if (byt_rt5640_dais[i].codecs->name &&
|
||||
!strcmp(byt_rt5640_dais[i].codecs->name,
|
||||
"i2c-10EC5640:00")) {
|
||||
dai_index = i;
|
||||
break;
|
||||
|
@ -910,7 +910,8 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
|
||||
|
||||
/* fix index of codec dai */
|
||||
for (i = 0; i < ARRAY_SIZE(byt_rt5651_dais); i++) {
|
||||
if (!strcmp(byt_rt5651_dais[i].codecs->name,
|
||||
if (byt_rt5651_dais[i].codecs->name &&
|
||||
!strcmp(byt_rt5651_dais[i].codecs->name,
|
||||
"i2c-10EC5651:00")) {
|
||||
dai_index = i;
|
||||
break;
|
||||
|
@ -605,7 +605,8 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev)
|
||||
|
||||
/* find index of codec dai */
|
||||
for (i = 0; i < ARRAY_SIZE(byt_wm5102_dais); i++) {
|
||||
if (!strcmp(byt_wm5102_dais[i].codecs->name,
|
||||
if (byt_wm5102_dais[i].codecs->name &&
|
||||
!strcmp(byt_wm5102_dais[i].codecs->name,
|
||||
"wm5102-codec")) {
|
||||
dai_index = i;
|
||||
break;
|
||||
|
@ -40,7 +40,6 @@ struct cht_acpi_card {
|
||||
struct cht_mc_private {
|
||||
struct snd_soc_jack jack;
|
||||
struct cht_acpi_card *acpi_card;
|
||||
char codec_name[SND_ACPI_I2C_ID_LEN];
|
||||
struct clk *mclk;
|
||||
};
|
||||
|
||||
@ -567,14 +566,14 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
card->dev = &pdev->dev;
|
||||
sprintf(drv->codec_name, "i2c-%s:00", drv->acpi_card->codec_id);
|
||||
|
||||
/* set correct codec name */
|
||||
for (i = 0; i < ARRAY_SIZE(cht_dailink); i++)
|
||||
if (!strcmp(card->dai_link[i].codecs->name,
|
||||
if (cht_dailink[i].codecs->name &&
|
||||
!strcmp(cht_dailink[i].codecs->name,
|
||||
"i2c-10EC5645:00")) {
|
||||
card->dai_link[i].codecs->name = drv->codec_name;
|
||||
dai_index = i;
|
||||
break;
|
||||
}
|
||||
|
||||
/* fixup codec name based on HID */
|
||||
|
@ -466,7 +466,8 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
|
||||
|
||||
/* find index of codec dai */
|
||||
for (i = 0; i < ARRAY_SIZE(cht_dailink); i++) {
|
||||
if (!strcmp(cht_dailink[i].codecs->name, RT5672_I2C_DEFAULT)) {
|
||||
if (cht_dailink[i].codecs->name &&
|
||||
!strcmp(cht_dailink[i].codecs->name, RT5672_I2C_DEFAULT)) {
|
||||
dai_index = i;
|
||||
break;
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ static struct snd_pcm_hardware q6apm_dai_hardware_playback = {
|
||||
.fifo_size = 0,
|
||||
};
|
||||
|
||||
static void event_handler(uint32_t opcode, uint32_t token, uint32_t *payload, void *priv)
|
||||
static void event_handler(uint32_t opcode, uint32_t token, void *payload, void *priv)
|
||||
{
|
||||
struct q6apm_dai_rtd *prtd = priv;
|
||||
struct snd_pcm_substream *substream = prtd->substream;
|
||||
@ -157,7 +157,7 @@ static void event_handler(uint32_t opcode, uint32_t token, uint32_t *payload, vo
|
||||
}
|
||||
|
||||
static void event_handler_compr(uint32_t opcode, uint32_t token,
|
||||
uint32_t *payload, void *priv)
|
||||
void *payload, void *priv)
|
||||
{
|
||||
struct q6apm_dai_rtd *prtd = priv;
|
||||
struct snd_compr_stream *substream = prtd->cstream;
|
||||
@ -352,7 +352,7 @@ static int q6apm_dai_open(struct snd_soc_component *component,
|
||||
|
||||
spin_lock_init(&prtd->lock);
|
||||
prtd->substream = substream;
|
||||
prtd->graph = q6apm_graph_open(dev, (q6apm_cb)event_handler, prtd, graph_id);
|
||||
prtd->graph = q6apm_graph_open(dev, event_handler, prtd, graph_id);
|
||||
if (IS_ERR(prtd->graph)) {
|
||||
dev_err(dev, "%s: Could not allocate memory\n", __func__);
|
||||
ret = PTR_ERR(prtd->graph);
|
||||
@ -496,7 +496,7 @@ static int q6apm_dai_compr_open(struct snd_soc_component *component,
|
||||
return -ENOMEM;
|
||||
|
||||
prtd->cstream = stream;
|
||||
prtd->graph = q6apm_graph_open(dev, (q6apm_cb)event_handler_compr, prtd, graph_id);
|
||||
prtd->graph = q6apm_graph_open(dev, event_handler_compr, prtd, graph_id);
|
||||
if (IS_ERR(prtd->graph)) {
|
||||
ret = PTR_ERR(prtd->graph);
|
||||
kfree(prtd);
|
||||
|
@ -188,11 +188,13 @@ irqreturn_t acp_sof_ipc_irq_thread(int irq, void *context)
|
||||
|
||||
dsp_ack = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_ack_write);
|
||||
if (dsp_ack) {
|
||||
spin_lock_irq(&sdev->ipc_lock);
|
||||
/* handle immediate reply from DSP core */
|
||||
acp_dsp_ipc_get_reply(sdev);
|
||||
snd_sof_ipc_reply(sdev, 0);
|
||||
/* set the done bit */
|
||||
acp_dsp_ipc_dsp_done(sdev);
|
||||
spin_unlock_irq(&sdev->ipc_lock);
|
||||
ipc_irq = true;
|
||||
}
|
||||
|
||||
|
@ -355,21 +355,20 @@ static irqreturn_t acp_irq_thread(int irq, void *context)
|
||||
unsigned int count = ACP_HW_SEM_RETRY_COUNT;
|
||||
|
||||
spin_lock_irq(&sdev->ipc_lock);
|
||||
while (snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->hw_semaphore_offset)) {
|
||||
/* Wait until acquired HW Semaphore lock or timeout */
|
||||
count--;
|
||||
while (snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->hw_semaphore_offset) && --count)
|
||||
;
|
||||
spin_unlock_irq(&sdev->ipc_lock);
|
||||
|
||||
if (!count) {
|
||||
dev_err(sdev->dev, "%s: Failed to acquire HW lock\n", __func__);
|
||||
spin_unlock_irq(&sdev->ipc_lock);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
sof_ops(sdev)->irq_thread(irq, sdev);
|
||||
/* Unlock or Release HW Semaphore */
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->hw_semaphore_offset, 0x0);
|
||||
|
||||
spin_unlock_irq(&sdev->ipc_lock);
|
||||
return IRQ_HANDLED;
|
||||
};
|
||||
|
||||
|
@ -36,7 +36,7 @@ static const struct sof_dev_desc lnl_desc = {
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4/lnl",
|
||||
},
|
||||
.default_tplg_path = {
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ace-tplg",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg",
|
||||
},
|
||||
.default_fw_filename = {
|
||||
[SOF_IPC_TYPE_4] = "sof-lnl.ri",
|
||||
|
@ -33,18 +33,18 @@ static const struct sof_dev_desc tgl_desc = {
|
||||
.dspless_mode_supported = true, /* Only supported for HDaudio */
|
||||
.default_fw_path = {
|
||||
[SOF_IPC_TYPE_3] = "intel/sof",
|
||||
[SOF_IPC_TYPE_4] = "intel/avs/tgl",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4/tgl",
|
||||
},
|
||||
.default_lib_path = {
|
||||
[SOF_IPC_TYPE_4] = "intel/avs-lib/tgl",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/tgl",
|
||||
},
|
||||
.default_tplg_path = {
|
||||
[SOF_IPC_TYPE_3] = "intel/sof-tplg",
|
||||
[SOF_IPC_TYPE_4] = "intel/avs-tplg",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg",
|
||||
},
|
||||
.default_fw_filename = {
|
||||
[SOF_IPC_TYPE_3] = "sof-tgl.ri",
|
||||
[SOF_IPC_TYPE_4] = "dsp_basefw.bin",
|
||||
[SOF_IPC_TYPE_4] = "sof-tgl.ri",
|
||||
},
|
||||
.nocodec_tplg_filename = "sof-tgl-nocodec.tplg",
|
||||
.ops = &sof_tgl_ops,
|
||||
@ -66,18 +66,18 @@ static const struct sof_dev_desc tglh_desc = {
|
||||
.dspless_mode_supported = true, /* Only supported for HDaudio */
|
||||
.default_fw_path = {
|
||||
[SOF_IPC_TYPE_3] = "intel/sof",
|
||||
[SOF_IPC_TYPE_4] = "intel/avs/tgl-h",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4/tgl-h",
|
||||
},
|
||||
.default_lib_path = {
|
||||
[SOF_IPC_TYPE_4] = "intel/avs-lib/tgl-h",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/tgl-h",
|
||||
},
|
||||
.default_tplg_path = {
|
||||
[SOF_IPC_TYPE_3] = "intel/sof-tplg",
|
||||
[SOF_IPC_TYPE_4] = "intel/avs-tplg",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg",
|
||||
},
|
||||
.default_fw_filename = {
|
||||
[SOF_IPC_TYPE_3] = "sof-tgl-h.ri",
|
||||
[SOF_IPC_TYPE_4] = "dsp_basefw.bin",
|
||||
[SOF_IPC_TYPE_4] = "sof-tgl-h.ri",
|
||||
},
|
||||
.nocodec_tplg_filename = "sof-tgl-nocodec.tplg",
|
||||
.ops = &sof_tgl_ops,
|
||||
@ -98,18 +98,18 @@ static const struct sof_dev_desc ehl_desc = {
|
||||
.dspless_mode_supported = true, /* Only supported for HDaudio */
|
||||
.default_fw_path = {
|
||||
[SOF_IPC_TYPE_3] = "intel/sof",
|
||||
[SOF_IPC_TYPE_4] = "intel/avs/ehl",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4/ehl",
|
||||
},
|
||||
.default_lib_path = {
|
||||
[SOF_IPC_TYPE_4] = "intel/avs-lib/ehl",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/ehl",
|
||||
},
|
||||
.default_tplg_path = {
|
||||
[SOF_IPC_TYPE_3] = "intel/sof-tplg",
|
||||
[SOF_IPC_TYPE_4] = "intel/avs-tplg",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg",
|
||||
},
|
||||
.default_fw_filename = {
|
||||
[SOF_IPC_TYPE_3] = "sof-ehl.ri",
|
||||
[SOF_IPC_TYPE_4] = "dsp_basefw.bin",
|
||||
[SOF_IPC_TYPE_4] = "sof-ehl.ri",
|
||||
},
|
||||
.nocodec_tplg_filename = "sof-ehl-nocodec.tplg",
|
||||
.ops = &sof_tgl_ops,
|
||||
@ -131,18 +131,18 @@ static const struct sof_dev_desc adls_desc = {
|
||||
.dspless_mode_supported = true, /* Only supported for HDaudio */
|
||||
.default_fw_path = {
|
||||
[SOF_IPC_TYPE_3] = "intel/sof",
|
||||
[SOF_IPC_TYPE_4] = "intel/avs/adl-s",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4/adl-s",
|
||||
},
|
||||
.default_lib_path = {
|
||||
[SOF_IPC_TYPE_4] = "intel/avs-lib/adl-s",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/adl-s",
|
||||
},
|
||||
.default_tplg_path = {
|
||||
[SOF_IPC_TYPE_3] = "intel/sof-tplg",
|
||||
[SOF_IPC_TYPE_4] = "intel/avs-tplg",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg",
|
||||
},
|
||||
.default_fw_filename = {
|
||||
[SOF_IPC_TYPE_3] = "sof-adl-s.ri",
|
||||
[SOF_IPC_TYPE_4] = "dsp_basefw.bin",
|
||||
[SOF_IPC_TYPE_4] = "sof-adl-s.ri",
|
||||
},
|
||||
.nocodec_tplg_filename = "sof-adl-nocodec.tplg",
|
||||
.ops = &sof_tgl_ops,
|
||||
@ -164,18 +164,18 @@ static const struct sof_dev_desc adl_desc = {
|
||||
.dspless_mode_supported = true, /* Only supported for HDaudio */
|
||||
.default_fw_path = {
|
||||
[SOF_IPC_TYPE_3] = "intel/sof",
|
||||
[SOF_IPC_TYPE_4] = "intel/avs/adl",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4/adl",
|
||||
},
|
||||
.default_lib_path = {
|
||||
[SOF_IPC_TYPE_4] = "intel/avs-lib/adl",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/adl",
|
||||
},
|
||||
.default_tplg_path = {
|
||||
[SOF_IPC_TYPE_3] = "intel/sof-tplg",
|
||||
[SOF_IPC_TYPE_4] = "intel/avs-tplg",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg",
|
||||
},
|
||||
.default_fw_filename = {
|
||||
[SOF_IPC_TYPE_3] = "sof-adl.ri",
|
||||
[SOF_IPC_TYPE_4] = "dsp_basefw.bin",
|
||||
[SOF_IPC_TYPE_4] = "sof-adl.ri",
|
||||
},
|
||||
.nocodec_tplg_filename = "sof-adl-nocodec.tplg",
|
||||
.ops = &sof_tgl_ops,
|
||||
@ -197,18 +197,18 @@ static const struct sof_dev_desc adl_n_desc = {
|
||||
.dspless_mode_supported = true, /* Only supported for HDaudio */
|
||||
.default_fw_path = {
|
||||
[SOF_IPC_TYPE_3] = "intel/sof",
|
||||
[SOF_IPC_TYPE_4] = "intel/avs/adl-n",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4/adl-n",
|
||||
},
|
||||
.default_lib_path = {
|
||||
[SOF_IPC_TYPE_4] = "intel/avs-lib/adl-n",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/adl-n",
|
||||
},
|
||||
.default_tplg_path = {
|
||||
[SOF_IPC_TYPE_3] = "intel/sof-tplg",
|
||||
[SOF_IPC_TYPE_4] = "intel/avs-tplg",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg",
|
||||
},
|
||||
.default_fw_filename = {
|
||||
[SOF_IPC_TYPE_3] = "sof-adl-n.ri",
|
||||
[SOF_IPC_TYPE_4] = "dsp_basefw.bin",
|
||||
[SOF_IPC_TYPE_4] = "sof-adl-n.ri",
|
||||
},
|
||||
.nocodec_tplg_filename = "sof-adl-nocodec.tplg",
|
||||
.ops = &sof_tgl_ops,
|
||||
@ -230,18 +230,18 @@ static const struct sof_dev_desc rpls_desc = {
|
||||
.dspless_mode_supported = true, /* Only supported for HDaudio */
|
||||
.default_fw_path = {
|
||||
[SOF_IPC_TYPE_3] = "intel/sof",
|
||||
[SOF_IPC_TYPE_4] = "intel/avs/rpl-s",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4/rpl-s",
|
||||
},
|
||||
.default_lib_path = {
|
||||
[SOF_IPC_TYPE_4] = "intel/avs-lib/rpl-s",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/rpl-s",
|
||||
},
|
||||
.default_tplg_path = {
|
||||
[SOF_IPC_TYPE_3] = "intel/sof-tplg",
|
||||
[SOF_IPC_TYPE_4] = "intel/avs-tplg",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg",
|
||||
},
|
||||
.default_fw_filename = {
|
||||
[SOF_IPC_TYPE_3] = "sof-rpl-s.ri",
|
||||
[SOF_IPC_TYPE_4] = "dsp_basefw.bin",
|
||||
[SOF_IPC_TYPE_4] = "sof-rpl-s.ri",
|
||||
},
|
||||
.nocodec_tplg_filename = "sof-rpl-nocodec.tplg",
|
||||
.ops = &sof_tgl_ops,
|
||||
@ -263,18 +263,18 @@ static const struct sof_dev_desc rpl_desc = {
|
||||
.dspless_mode_supported = true, /* Only supported for HDaudio */
|
||||
.default_fw_path = {
|
||||
[SOF_IPC_TYPE_3] = "intel/sof",
|
||||
[SOF_IPC_TYPE_4] = "intel/avs/rpl",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4/rpl",
|
||||
},
|
||||
.default_lib_path = {
|
||||
[SOF_IPC_TYPE_4] = "intel/avs-lib/rpl",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/rpl",
|
||||
},
|
||||
.default_tplg_path = {
|
||||
[SOF_IPC_TYPE_3] = "intel/sof-tplg",
|
||||
[SOF_IPC_TYPE_4] = "intel/avs-tplg",
|
||||
[SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg",
|
||||
},
|
||||
.default_fw_filename = {
|
||||
[SOF_IPC_TYPE_3] = "sof-rpl.ri",
|
||||
[SOF_IPC_TYPE_4] = "dsp_basefw.bin",
|
||||
[SOF_IPC_TYPE_4] = "sof-rpl.ri",
|
||||
},
|
||||
.nocodec_tplg_filename = "sof-rpl-nocodec.tplg",
|
||||
.ops = &sof_tgl_ops,
|
||||
|
@ -2360,6 +2360,44 @@ static int sof_tear_down_left_over_pipelines(struct snd_sof_dev *sdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sof_ipc3_free_widgets_in_list(struct snd_sof_dev *sdev, bool include_scheduler,
|
||||
bool *dyn_widgets, bool verify)
|
||||
{
|
||||
struct sof_ipc_fw_version *v = &sdev->fw_ready.version;
|
||||
struct snd_sof_widget *swidget;
|
||||
int ret;
|
||||
|
||||
list_for_each_entry(swidget, &sdev->widget_list, list) {
|
||||
if (swidget->dynamic_pipeline_widget) {
|
||||
*dyn_widgets = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Do not free widgets for static pipelines with FW older than SOF2.2 */
|
||||
if (!verify && !swidget->dynamic_pipeline_widget &&
|
||||
SOF_FW_VER(v->major, v->minor, v->micro) < SOF_FW_VER(2, 2, 0)) {
|
||||
mutex_lock(&swidget->setup_mutex);
|
||||
swidget->use_count = 0;
|
||||
mutex_unlock(&swidget->setup_mutex);
|
||||
if (swidget->spipe)
|
||||
swidget->spipe->complete = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (include_scheduler && swidget->id != snd_soc_dapm_scheduler)
|
||||
continue;
|
||||
|
||||
if (!include_scheduler && swidget->id == snd_soc_dapm_scheduler)
|
||||
continue;
|
||||
|
||||
ret = sof_widget_free(sdev, swidget);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* For older firmware, this function doesn't free widgets for static pipelines during suspend.
|
||||
* It only resets use_count for all widgets.
|
||||
@ -2376,29 +2414,18 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif
|
||||
* This function is called during suspend and for one-time topology verification during
|
||||
* first boot. In both cases, there is no need to protect swidget->use_count and
|
||||
* sroute->setup because during suspend all running streams are suspended and during
|
||||
* topology loading the sound card unavailable to open PCMs.
|
||||
* topology loading the sound card unavailable to open PCMs. Do not free the scheduler
|
||||
* widgets yet so that the secondary cores do not get powered down before all the widgets
|
||||
* associated with the scheduler are freed.
|
||||
*/
|
||||
list_for_each_entry(swidget, &sdev->widget_list, list) {
|
||||
if (swidget->dynamic_pipeline_widget) {
|
||||
dyn_widgets = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Do not free widgets for static pipelines with FW older than SOF2.2 */
|
||||
if (!verify && !swidget->dynamic_pipeline_widget &&
|
||||
SOF_FW_VER(v->major, v->minor, v->micro) < SOF_FW_VER(2, 2, 0)) {
|
||||
mutex_lock(&swidget->setup_mutex);
|
||||
swidget->use_count = 0;
|
||||
mutex_unlock(&swidget->setup_mutex);
|
||||
if (swidget->spipe)
|
||||
swidget->spipe->complete = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = sof_widget_free(sdev, swidget);
|
||||
ret = sof_ipc3_free_widgets_in_list(sdev, false, &dyn_widgets, verify);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* free all the scheduler widgets now */
|
||||
ret = sof_ipc3_free_widgets_in_list(sdev, true, &dyn_widgets, verify);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tear down all pipelines associated with PCMs that did not get suspended
|
||||
|
@ -1067,7 +1067,7 @@ static void sof_ipc3_rx_msg(struct snd_sof_dev *sdev)
|
||||
return;
|
||||
}
|
||||
|
||||
if (hdr.size < sizeof(hdr)) {
|
||||
if (hdr.size < sizeof(hdr) || hdr.size > SOF_IPC_MSG_MAX_SIZE) {
|
||||
dev_err(sdev->dev, "The received message size is invalid\n");
|
||||
return;
|
||||
}
|
||||
|
@ -413,7 +413,18 @@ skip_pause_transition:
|
||||
ret = sof_ipc4_set_multi_pipeline_state(sdev, state, trigger_list);
|
||||
if (ret < 0) {
|
||||
dev_err(sdev->dev, "failed to set final state %d for all pipelines\n", state);
|
||||
/*
|
||||
* workaround: if the firmware is crashed while setting the
|
||||
* pipelines to reset state we must ignore the error code and
|
||||
* reset it to 0.
|
||||
* Since the firmware is crashed we will not send IPC messages
|
||||
* and we are going to see errors printed, but the state of the
|
||||
* widgets will be correct for the next boot.
|
||||
*/
|
||||
if (sdev->fw_state != SOF_FW_CRASHED || state != SOF_IPC4_PIPE_RESET)
|
||||
goto free;
|
||||
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
/* update RUNNING/RESET state for all pipelines that were just triggered */
|
||||
|
@ -1742,50 +1742,44 @@ static void snd_usbmidi_get_port_info(struct snd_rawmidi *rmidi, int number,
|
||||
}
|
||||
}
|
||||
|
||||
static struct usb_midi_in_jack_descriptor *find_usb_in_jack_descriptor(
|
||||
struct usb_host_interface *hostif, uint8_t jack_id)
|
||||
/* return iJack for the corresponding jackID */
|
||||
static int find_usb_ijack(struct usb_host_interface *hostif, uint8_t jack_id)
|
||||
{
|
||||
unsigned char *extra = hostif->extra;
|
||||
int extralen = hostif->extralen;
|
||||
struct usb_descriptor_header *h;
|
||||
struct usb_midi_out_jack_descriptor *outjd;
|
||||
struct usb_midi_in_jack_descriptor *injd;
|
||||
size_t sz;
|
||||
|
||||
while (extralen > 4) {
|
||||
struct usb_midi_in_jack_descriptor *injd =
|
||||
(struct usb_midi_in_jack_descriptor *)extra;
|
||||
h = (struct usb_descriptor_header *)extra;
|
||||
if (h->bDescriptorType != USB_DT_CS_INTERFACE)
|
||||
goto next;
|
||||
|
||||
outjd = (struct usb_midi_out_jack_descriptor *)h;
|
||||
if (h->bLength >= sizeof(*outjd) &&
|
||||
outjd->bDescriptorSubtype == UAC_MIDI_OUT_JACK &&
|
||||
outjd->bJackID == jack_id) {
|
||||
sz = USB_DT_MIDI_OUT_SIZE(outjd->bNrInputPins);
|
||||
if (outjd->bLength < sz)
|
||||
goto next;
|
||||
return *(extra + sz - 1);
|
||||
}
|
||||
|
||||
injd = (struct usb_midi_in_jack_descriptor *)h;
|
||||
if (injd->bLength >= sizeof(*injd) &&
|
||||
injd->bDescriptorType == USB_DT_CS_INTERFACE &&
|
||||
injd->bDescriptorSubtype == UAC_MIDI_IN_JACK &&
|
||||
injd->bJackID == jack_id)
|
||||
return injd;
|
||||
return injd->iJack;
|
||||
|
||||
next:
|
||||
if (!extra[0])
|
||||
break;
|
||||
extralen -= extra[0];
|
||||
extra += extra[0];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct usb_midi_out_jack_descriptor *find_usb_out_jack_descriptor(
|
||||
struct usb_host_interface *hostif, uint8_t jack_id)
|
||||
{
|
||||
unsigned char *extra = hostif->extra;
|
||||
int extralen = hostif->extralen;
|
||||
|
||||
while (extralen > 4) {
|
||||
struct usb_midi_out_jack_descriptor *outjd =
|
||||
(struct usb_midi_out_jack_descriptor *)extra;
|
||||
|
||||
if (outjd->bLength >= sizeof(*outjd) &&
|
||||
outjd->bDescriptorType == USB_DT_CS_INTERFACE &&
|
||||
outjd->bDescriptorSubtype == UAC_MIDI_OUT_JACK &&
|
||||
outjd->bJackID == jack_id)
|
||||
return outjd;
|
||||
if (!extra[0])
|
||||
break;
|
||||
extralen -= extra[0];
|
||||
extra += extra[0];
|
||||
}
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void snd_usbmidi_init_substream(struct snd_usb_midi *umidi,
|
||||
@ -1796,13 +1790,10 @@ static void snd_usbmidi_init_substream(struct snd_usb_midi *umidi,
|
||||
const char *name_format;
|
||||
struct usb_interface *intf;
|
||||
struct usb_host_interface *hostif;
|
||||
struct usb_midi_in_jack_descriptor *injd;
|
||||
struct usb_midi_out_jack_descriptor *outjd;
|
||||
uint8_t jack_name_buf[32];
|
||||
uint8_t *default_jack_name = "MIDI";
|
||||
uint8_t *jack_name = default_jack_name;
|
||||
uint8_t iJack;
|
||||
size_t sz;
|
||||
int res;
|
||||
|
||||
struct snd_rawmidi_substream *substream =
|
||||
@ -1816,21 +1807,7 @@ static void snd_usbmidi_init_substream(struct snd_usb_midi *umidi,
|
||||
intf = umidi->iface;
|
||||
if (intf && jack_id >= 0) {
|
||||
hostif = intf->cur_altsetting;
|
||||
iJack = 0;
|
||||
if (stream != SNDRV_RAWMIDI_STREAM_OUTPUT) {
|
||||
/* in jacks connect to outs */
|
||||
outjd = find_usb_out_jack_descriptor(hostif, jack_id);
|
||||
if (outjd) {
|
||||
sz = USB_DT_MIDI_OUT_SIZE(outjd->bNrInputPins);
|
||||
if (outjd->bLength >= sz)
|
||||
iJack = *(((uint8_t *) outjd) + sz - sizeof(uint8_t));
|
||||
}
|
||||
} else {
|
||||
/* and out jacks connect to ins */
|
||||
injd = find_usb_in_jack_descriptor(hostif, jack_id);
|
||||
if (injd)
|
||||
iJack = injd->iJack;
|
||||
}
|
||||
iJack = find_usb_ijack(hostif, jack_id);
|
||||
if (iJack != 0) {
|
||||
res = usb_string(umidi->dev, iJack, jack_name_buf,
|
||||
ARRAY_SIZE(jack_name_buf));
|
||||
|
Loading…
Reference in New Issue
Block a user