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 ...
Unified · Split
| @@ -7,7 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | |||
| 7 | title: Google SC7280-Herobrine ASoC sound card driver | 7 | title: Google SC7280-Herobrine ASoC sound card driver |
| 8 | 8 | ||
| 9 | maintainers: | 9 | maintainers: |
| 10 | - Srinivasa Rao Mandadapu <srivasam@codeaurora.org> | ||
| 11 | - Judy Hsiao <judyhsiao@chromium.org> | 10 | - Judy Hsiao <judyhsiao@chromium.org> |
| 12 | 11 | ||
| 13 | description: | 12 | description: |
| @@ -142,6 +142,7 @@ struct tasdevice_priv { · 141 unmodified lines | |||
| 142 | 142 | ||
| 143 | void tas2781_reset(struct tasdevice_priv *tas_dev); | 143 | void tas2781_reset(struct tasdevice_priv *tas_dev); |
| 144 | int tascodec_init(struct tasdevice_priv *tas_priv, void *codec, | 144 | int tascodec_init(struct tasdevice_priv *tas_priv, void *codec, |
| 145 | struct module *module, | ||
| 145 | void (*cont)(const struct firmware *fw, void *context)); | 146 | void (*cont)(const struct firmware *fw, void *context)); |
| 146 | struct tasdevice_priv *tasdevice_kzalloc(struct i2c_client *i2c); | 147 | struct tasdevice_priv *tasdevice_kzalloc(struct i2c_client *i2c); |
| 147 | int tasdevice_init(struct tasdevice_priv *tas_priv); | 148 | int tasdevice_init(struct tasdevice_priv *tas_priv); |
| @@ -156,7 +156,7 @@ config SND_HDA_SCODEC_CS35L56_I2C · 155 unmodified lines | |||
| 156 | depends on I2C | 156 | depends on I2C |
| 157 | depends on ACPI || COMPILE_TEST | 157 | depends on ACPI || COMPILE_TEST |
| 158 | depends on SND_SOC | 158 | depends on SND_SOC |
| 159 | select CS_DSP | 159 | select FW_CS_DSP |
| 160 | select SND_HDA_GENERIC | 160 | select SND_HDA_GENERIC |
| 161 | select SND_SOC_CS35L56_SHARED | 161 | select SND_SOC_CS35L56_SHARED |
| 162 | select SND_HDA_SCODEC_CS35L56 | 162 | select SND_HDA_SCODEC_CS35L56 |
| @@ -171,7 +171,7 @@ config SND_HDA_SCODEC_CS35L56_SPI · 8 unmodified lines | |||
| 171 | depends on SPI_MASTER | 171 | depends on SPI_MASTER |
| 172 | depends on ACPI || COMPILE_TEST | 172 | depends on ACPI || COMPILE_TEST |
| 173 | depends on SND_SOC | 173 | depends on SND_SOC |
| 174 | select CS_DSP | 174 | select FW_CS_DSP |
| 175 | select SND_HDA_GENERIC | 175 | select SND_HDA_GENERIC |
| 176 | select SND_SOC_CS35L56_SHARED | 176 | select SND_SOC_CS35L56_SHARED |
| 177 | select SND_HDA_SCODEC_CS35L56 | 177 | select SND_HDA_SCODEC_CS35L56 |
| @@ -91,10 +91,12 @@ static const struct cs35l41_config cs35l41_config_table[] = { · 90 unmodified lines | |||
| 91 | { "10431D1F", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 }, | 91 | { "10431D1F", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 }, |
| 92 | { "10431DA2", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 }, | 92 | { "10431DA2", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 }, |
| 93 | { "10431E02", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 }, | 93 | { "10431E02", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 }, |
| 94 | { "10431E12", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 }, | ||
| 94 | { "10431EE2", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 }, | 95 | { "10431EE2", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 }, |
| 95 | { "10431F12", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 }, | 96 | { "10431F12", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 }, |
| 96 | { "10431F1F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 }, | 97 | { "10431F1F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 }, |
| 97 | { "10431F62", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 }, | 98 | { "10431F62", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 }, |
| 99 | { "17AA386F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 }, | ||
| 98 | { "17AA38B4", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 }, | 100 | { "17AA38B4", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 }, |
| 99 | { "17AA38B5", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 }, | 101 | { "17AA38B5", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 }, |
| 100 | { "17AA38B6", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 }, | 102 | { "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[] = { · 326 unmodified lines | |||
| 427 | { "CSC3551", "10431D1F", generic_dsd_config }, | 429 | { "CSC3551", "10431D1F", generic_dsd_config }, |
| 428 | { "CSC3551", "10431DA2", generic_dsd_config }, | 430 | { "CSC3551", "10431DA2", generic_dsd_config }, |
| 429 | { "CSC3551", "10431E02", generic_dsd_config }, | 431 | { "CSC3551", "10431E02", generic_dsd_config }, |
| 432 | { "CSC3551", "10431E12", generic_dsd_config }, | ||
| 430 | { "CSC3551", "10431EE2", generic_dsd_config }, | 433 | { "CSC3551", "10431EE2", generic_dsd_config }, |
| 431 | { "CSC3551", "10431F12", generic_dsd_config }, | 434 | { "CSC3551", "10431F12", generic_dsd_config }, |
| 432 | { "CSC3551", "10431F1F", generic_dsd_config }, | 435 | { "CSC3551", "10431F1F", generic_dsd_config }, |
| 433 | { "CSC3551", "10431F62", generic_dsd_config }, | 436 | { "CSC3551", "10431F62", generic_dsd_config }, |
| 437 | { "CSC3551", "17AA386F", generic_dsd_config }, | ||
| 434 | { "CSC3551", "17AA38B4", generic_dsd_config }, | 438 | { "CSC3551", "17AA38B4", generic_dsd_config }, |
| 435 | { "CSC3551", "17AA38B5", generic_dsd_config }, | 439 | { "CSC3551", "17AA38B5", generic_dsd_config }, |
| 436 | { "CSC3551", "17AA38B6", generic_dsd_config }, | 440 | { "CSC3551", "17AA38B6", generic_dsd_config }, |
| @@ -344,6 +344,7 @@ enum { · 343 unmodified lines | |||
| 344 | CXT_FIXUP_HP_ZBOOK_MUTE_LED, | 344 | CXT_FIXUP_HP_ZBOOK_MUTE_LED, |
| 345 | CXT_FIXUP_HEADSET_MIC, | 345 | CXT_FIXUP_HEADSET_MIC, |
| 346 | CXT_FIXUP_HP_MIC_NO_PRESENCE, | 346 | CXT_FIXUP_HP_MIC_NO_PRESENCE, |
| 347 | CXT_PINCFG_SWS_JS201D, | ||
| 347 | }; | 348 | }; |
| 348 | 349 | ||
| 349 | /* for hda_fixup_thinkpad_acpi() */ | 350 | /* for hda_fixup_thinkpad_acpi() */ |
| @@ -841,6 +842,17 @@ static const struct hda_pintbl cxt_pincfg_lemote[] = { · 491 unmodified lines | |||
| 841 | {} | 842 | {} |
| 842 | }; | 843 | }; |
| 843 | 844 | ||
| 845 | /* SuoWoSi/South-holding JS201D with sn6140 */ | ||
| 846 | static const struct hda_pintbl cxt_pincfg_sws_js201d[] = { | ||
| 847 | { 0x16, 0x03211040 }, /* hp out */ | ||
| 848 | { 0x17, 0x91170110 }, /* SPK/Class_D */ | ||
| 849 | { 0x18, 0x95a70130 }, /* Internal mic */ | ||
| 850 | { 0x19, 0x03a11020 }, /* Headset Mic */ | ||
| 851 | { 0x1a, 0x40f001f0 }, /* Not used */ | ||
| 852 | { 0x21, 0x40f001f0 }, /* Not used */ | ||
| 853 | {} | ||
| 854 | }; | ||
| 855 | |||
| 844 | static const struct hda_fixup cxt_fixups[] = { | 856 | static const struct hda_fixup cxt_fixups[] = { |
| 845 | [CXT_PINCFG_LENOVO_X200] = { | 857 | [CXT_PINCFG_LENOVO_X200] = { |
| 846 | .type = HDA_FIXUP_PINS, | 858 | .type = HDA_FIXUP_PINS, |
| @@ -996,6 +1008,10 @@ static const struct hda_fixup cxt_fixups[] = { · 149 unmodified lines | |||
| 996 | .chained = true, | 1008 | .chained = true, |
| 997 | .chain_id = CXT_FIXUP_HEADSET_MIC, | 1009 | .chain_id = CXT_FIXUP_HEADSET_MIC, |
| 998 | }, | 1010 | }, |
| 1011 | [CXT_PINCFG_SWS_JS201D] = { | ||
| 1012 | .type = HDA_FIXUP_PINS, | ||
| 1013 | .v.pins = cxt_pincfg_sws_js201d, | ||
| 1014 | }, | ||
| 999 | }; | 1015 | }; |
| 1000 | 1016 | ||
| 1001 | static const struct snd_pci_quirk cxt5045_fixups[] = { | 1017 | static const struct snd_pci_quirk cxt5045_fixups[] = { |
| @@ -1069,6 +1085,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { · 67 unmodified lines | |||
| 1069 | SND_PCI_QUIRK(0x103c, 0x8457, "HP Z2 G4 mini", CXT_FIXUP_HP_MIC_NO_PRESENCE), | 1085 | SND_PCI_QUIRK(0x103c, 0x8457, "HP Z2 G4 mini", CXT_FIXUP_HP_MIC_NO_PRESENCE), |
| 1070 | SND_PCI_QUIRK(0x103c, 0x8458, "HP Z2 G4 mini premium", CXT_FIXUP_HP_MIC_NO_PRESENCE), | 1086 | SND_PCI_QUIRK(0x103c, 0x8458, "HP Z2 G4 mini premium", CXT_FIXUP_HP_MIC_NO_PRESENCE), |
| 1071 | SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), | 1087 | SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), |
| 1088 | SND_PCI_QUIRK(0x14f1, 0x0265, "SWS JS201D", CXT_PINCFG_SWS_JS201D), | ||
| 1072 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), | 1089 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), |
| 1073 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), | 1090 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), |
| 1074 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410), | 1091 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410), |
| @@ -1109,6 +1126,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = { · 34 unmodified lines | |||
| 1109 | { .id = CXT_FIXUP_HP_ZBOOK_MUTE_LED, .name = "hp-zbook-mute-led" }, | 1126 | { .id = CXT_FIXUP_HP_ZBOOK_MUTE_LED, .name = "hp-zbook-mute-led" }, |
| 1110 | { .id = CXT_FIXUP_HP_MIC_NO_PRESENCE, .name = "hp-mic-fix" }, | 1127 | { .id = CXT_FIXUP_HP_MIC_NO_PRESENCE, .name = "hp-mic-fix" }, |
| 1111 | { .id = CXT_PINCFG_LENOVO_NOTEBOOK, .name = "lenovo-20149" }, | 1128 | { .id = CXT_PINCFG_LENOVO_NOTEBOOK, .name = "lenovo-20149" }, |
| 1129 | { .id = CXT_PINCFG_SWS_JS201D, .name = "sws-js201d" }, | ||
| 1112 | {} | 1130 | {} |
| 1113 | }; | 1131 | }; |
| 1114 | 1132 | ||
| @@ -9737,7 +9737,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 9736 unmodified lines | |||
| 9737 | SND_PCI_QUIRK(0x1028, 0x0b71, "Dell Inspiron 16 Plus 7620", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS), | 9737 | SND_PCI_QUIRK(0x1028, 0x0b71, "Dell Inspiron 16 Plus 7620", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS), |
| 9738 | SND_PCI_QUIRK(0x1028, 0x0beb, "Dell XPS 15 9530 (2023)", ALC289_FIXUP_DELL_CS35L41_SPI_2), | 9738 | SND_PCI_QUIRK(0x1028, 0x0beb, "Dell XPS 15 9530 (2023)", ALC289_FIXUP_DELL_CS35L41_SPI_2), |
| 9739 | SND_PCI_QUIRK(0x1028, 0x0c03, "Dell Precision 5340", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE), | 9739 | SND_PCI_QUIRK(0x1028, 0x0c03, "Dell Precision 5340", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE), |
| 9740 | SND_PCI_QUIRK(0x1028, 0x0c0b, "Dell Oasis 14 RPL-P", ALC289_FIXUP_RTK_AMP_DUAL_SPK), | ||
| 9740 | SND_PCI_QUIRK(0x1028, 0x0c0d, "Dell Oasis", ALC289_FIXUP_RTK_AMP_DUAL_SPK), | 9741 | SND_PCI_QUIRK(0x1028, 0x0c0d, "Dell Oasis", ALC289_FIXUP_RTK_AMP_DUAL_SPK), |
| 9742 | SND_PCI_QUIRK(0x1028, 0x0c0e, "Dell Oasis 16", ALC289_FIXUP_RTK_AMP_DUAL_SPK), | ||
| 9741 | SND_PCI_QUIRK(0x1028, 0x0c19, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS), | 9743 | SND_PCI_QUIRK(0x1028, 0x0c19, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS), |
| 9742 | SND_PCI_QUIRK(0x1028, 0x0c1a, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS), | 9744 | SND_PCI_QUIRK(0x1028, 0x0c1a, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS), |
| 9743 | SND_PCI_QUIRK(0x1028, 0x0c1b, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS), | 9745 | 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[] = { · 184 unmodified lines | |||
| 9928 | SND_PCI_QUIRK(0x103c, 0x8abb, "HP ZBook Firefly 14 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), | 9930 | SND_PCI_QUIRK(0x103c, 0x8abb, "HP ZBook Firefly 14 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), |
| 9929 | SND_PCI_QUIRK(0x103c, 0x8ad1, "HP EliteBook 840 14 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), | 9931 | SND_PCI_QUIRK(0x103c, 0x8ad1, "HP EliteBook 840 14 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), |
| 9930 | SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), | 9932 | SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), |
| 9933 | SND_PCI_QUIRK(0x103c, 0x8b0f, "HP Elite mt645 G7 Mobile Thin Client U81", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), | ||
| 9931 | SND_PCI_QUIRK(0x103c, 0x8b2f, "HP 255 15.6 inch G10 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), | 9934 | SND_PCI_QUIRK(0x103c, 0x8b2f, "HP 255 15.6 inch G10 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), |
| 9932 | SND_PCI_QUIRK(0x103c, 0x8b42, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), | 9935 | SND_PCI_QUIRK(0x103c, 0x8b42, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), |
| 9933 | SND_PCI_QUIRK(0x103c, 0x8b43, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), | 9936 | 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[] = { · 1 unmodified line | |||
| 9935 | SND_PCI_QUIRK(0x103c, 0x8b45, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), | 9938 | SND_PCI_QUIRK(0x103c, 0x8b45, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), |
| 9936 | SND_PCI_QUIRK(0x103c, 0x8b46, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), | 9939 | SND_PCI_QUIRK(0x103c, 0x8b46, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), |
| 9937 | SND_PCI_QUIRK(0x103c, 0x8b47, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), | 9940 | SND_PCI_QUIRK(0x103c, 0x8b47, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), |
| 9941 | SND_PCI_QUIRK(0x103c, 0x8b59, "HP Elite mt645 G7 Mobile Thin Client U89", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), | ||
| 9938 | SND_PCI_QUIRK(0x103c, 0x8b5d, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), | 9942 | SND_PCI_QUIRK(0x103c, 0x8b5d, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), |
| 9939 | SND_PCI_QUIRK(0x103c, 0x8b5e, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), | 9943 | SND_PCI_QUIRK(0x103c, 0x8b5e, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), |
| 9940 | SND_PCI_QUIRK(0x103c, 0x8b63, "HP Elite Dragonfly 13.5 inch G4", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), | 9944 | 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[] = { · 62 unmodified lines | |||
| 10003 | SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK), | 10007 | SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK), |
| 10004 | SND_PCI_QUIRK(0x1043, 0x1663, "ASUS GU603ZI/ZJ/ZQ/ZU/ZV", ALC285_FIXUP_ASUS_HEADSET_MIC), | 10008 | SND_PCI_QUIRK(0x1043, 0x1663, "ASUS GU603ZI/ZJ/ZQ/ZU/ZV", ALC285_FIXUP_ASUS_HEADSET_MIC), |
| 10005 | SND_PCI_QUIRK(0x1043, 0x1683, "ASUS UM3402YAR", ALC287_FIXUP_CS35L41_I2C_2), | 10009 | SND_PCI_QUIRK(0x1043, 0x1683, "ASUS UM3402YAR", ALC287_FIXUP_CS35L41_I2C_2), |
| 10010 | SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS UX3402VA", ALC245_FIXUP_CS35L41_SPI_2), | ||
| 10006 | SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401), | 10011 | SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401), |
| 10007 | SND_PCI_QUIRK(0x1043, 0x16d3, "ASUS UX5304VA", ALC245_FIXUP_CS35L41_SPI_2), | 10012 | SND_PCI_QUIRK(0x1043, 0x16d3, "ASUS UX5304VA", ALC245_FIXUP_CS35L41_SPI_2), |
| 10008 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), | 10013 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), |
| @@ -10046,14 +10051,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 37 unmodified lines | |||
| 10046 | SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), | 10051 | SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), |
| 10047 | SND_PCI_QUIRK(0x1043, 0x1da2, "ASUS UP6502ZA/ZD", ALC245_FIXUP_CS35L41_SPI_2), | 10052 | SND_PCI_QUIRK(0x1043, 0x1da2, "ASUS UP6502ZA/ZD", ALC245_FIXUP_CS35L41_SPI_2), |
| 10048 | SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402ZA", ALC245_FIXUP_CS35L41_SPI_2), | 10053 | SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402ZA", ALC245_FIXUP_CS35L41_SPI_2), |
| 10049 | SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS UX3402VA", ALC245_FIXUP_CS35L41_SPI_2), | ||
| 10050 | SND_PCI_QUIRK(0x1043, 0x1f62, "ASUS UX7602ZM", ALC245_FIXUP_CS35L41_SPI_2), | ||
| 10051 | SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502), | 10054 | SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502), |
| 10052 | SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM6702RA/RC", ALC287_FIXUP_CS35L41_I2C_2), | 10055 | SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2), |
| 10053 | SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS), | 10056 | SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS), |
| 10054 | SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS), | 10057 | SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS), |
| 10055 | SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401), | 10058 | SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401), |
| 10056 | SND_PCI_QUIRK(0x1043, 0x1ee2, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2), | 10059 | SND_PCI_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC287_FIXUP_CS35L41_I2C_2), |
| 10057 | SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401), | 10060 | SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401), |
| 10058 | SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401), | 10061 | SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401), |
| 10059 | SND_PCI_QUIRK(0x1043, 0x1f12, "ASUS UM5302", ALC287_FIXUP_CS35L41_I2C_2), | 10062 | 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[] = { · 200 unmodified lines | |||
| 10260 | SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), | 10263 | SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), |
| 10261 | SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6), | 10264 | SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6), |
| 10262 | SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), | 10265 | SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), |
| 10266 | SND_PCI_QUIRK(0x17aa, 0x386f, "Legion 7i 16IAX7", ALC287_FIXUP_CS35L41_I2C_2), | ||
| 10263 | SND_PCI_QUIRK(0x17aa, 0x3870, "Lenovo Yoga 7 14ARB7", ALC287_FIXUP_YOGA7_14ARB7_I2C), | 10267 | SND_PCI_QUIRK(0x17aa, 0x3870, "Lenovo Yoga 7 14ARB7", ALC287_FIXUP_YOGA7_14ARB7_I2C), |
| 10264 | SND_PCI_QUIRK(0x17aa, 0x387d, "Yoga S780-16 pro Quad AAC", ALC287_FIXUP_TAS2781_I2C), | 10268 | SND_PCI_QUIRK(0x17aa, 0x387d, "Yoga S780-16 pro Quad AAC", ALC287_FIXUP_TAS2781_I2C), |
| 10265 | SND_PCI_QUIRK(0x17aa, 0x387e, "Yoga S780-16 pro Quad YC", ALC287_FIXUP_TAS2781_I2C), | 10269 | 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, · 709 unmodified lines | |||
| 710 | 710 | ||
| 711 | strscpy(comps->name, dev_name(dev), sizeof(comps->name)); | 711 | strscpy(comps->name, dev_name(dev), sizeof(comps->name)); |
| 712 | 712 | ||
| 713 | ret = tascodec_init(tas_hda->priv, codec, tasdev_fw_ready); | 713 | ret = tascodec_init(tas_hda->priv, codec, THIS_MODULE, tasdev_fw_ready); |
| 714 | if (!ret) | 714 | if (!ret) |
| 715 | comps->playback_hook = tas2781_hda_playback_hook; | 715 | comps->playback_hook = tas2781_hda_playback_hook; |
| 716 | 716 | ||
| @@ -234,6 +234,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { · 233 unmodified lines | |||
| 234 | DMI_MATCH(DMI_PRODUCT_NAME, "82UG"), | 234 | DMI_MATCH(DMI_PRODUCT_NAME, "82UG"), |
| 235 | } | 235 | } |
| 236 | }, | 236 | }, |
| 237 | { | ||
| 238 | .driver_data = &acp6x_card, | ||
| 239 | .matches = { | ||
| 240 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | ||
| 241 | DMI_MATCH(DMI_PRODUCT_NAME, "82UU"), | ||
| 242 | } | ||
| 243 | }, | ||
| 237 | { | 244 | { |
| 238 | .driver_data = &acp6x_card, | 245 | .driver_data = &acp6x_card, |
| 239 | .matches = { | 246 | .matches = { |
| @@ -248,6 +255,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { · 8 unmodified lines | |||
| 248 | DMI_MATCH(DMI_PRODUCT_NAME, "82YM"), | 255 | DMI_MATCH(DMI_PRODUCT_NAME, "82YM"), |
| 249 | } | 256 | } |
| 250 | }, | 257 | }, |
| 258 | { | ||
| 259 | .driver_data = &acp6x_card, | ||
| 260 | .matches = { | ||
| 261 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | ||
| 262 | DMI_MATCH(DMI_PRODUCT_NAME, "83AS"), | ||
| 263 | } | ||
| 264 | }, | ||
| 251 | { | 265 | { |
| 252 | .driver_data = &acp6x_card, | 266 | .driver_data = &acp6x_card, |
| 253 | .matches = { | 267 | .matches = { |
| @@ -51,7 +51,6 @@ static const struct reg_default cs35l56_reg_defaults[] = { · 50 unmodified lines | |||
| 51 | { CS35L56_SWIRE_DP3_CH2_INPUT, 0x00000019 }, | 51 | { CS35L56_SWIRE_DP3_CH2_INPUT, 0x00000019 }, |
| 52 | { CS35L56_SWIRE_DP3_CH3_INPUT, 0x00000029 }, | 52 | { CS35L56_SWIRE_DP3_CH3_INPUT, 0x00000029 }, |
| 53 | { CS35L56_SWIRE_DP3_CH4_INPUT, 0x00000028 }, | 53 | { CS35L56_SWIRE_DP3_CH4_INPUT, 0x00000028 }, |
| 54 | { CS35L56_IRQ1_CFG, 0x00000000 }, | ||
| 55 | { CS35L56_IRQ1_MASK_1, 0x83ffffff }, | 54 | { CS35L56_IRQ1_MASK_1, 0x83ffffff }, |
| 56 | { CS35L56_IRQ1_MASK_2, 0xffff7fff }, | 55 | { CS35L56_IRQ1_MASK_2, 0xffff7fff }, |
| 57 | { CS35L56_IRQ1_MASK_4, 0xe0ffffff }, | 56 | { CS35L56_IRQ1_MASK_4, 0xe0ffffff }, |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | |||
| 5 | // Copyright (C) 2023 Cirrus Logic, Inc. and | 5 | // Copyright (C) 2023 Cirrus Logic, Inc. and |
| 6 | // Cirrus Logic International Semiconductor Ltd. | 6 | // Cirrus Logic International Semiconductor Ltd. |
| 7 | 7 | ||
| 8 | #include <linux/acpi.h> | ||
| 8 | #include <linux/completion.h> | 9 | #include <linux/completion.h> |
| 9 | #include <linux/debugfs.h> | 10 | #include <linux/debugfs.h> |
| 10 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
| @@ -15,6 +16,7 @@ · 4 unmodified lines | |||
| 15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 16 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
| 17 | #include <linux/pm_runtime.h> | 18 | #include <linux/pm_runtime.h> |
| 19 | #include <linux/property.h> | ||
| 18 | #include <linux/regmap.h> | 20 | #include <linux/regmap.h> |
| 19 | #include <linux/regulator/consumer.h> | 21 | #include <linux/regulator/consumer.h> |
| 20 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| @@ -68,63 +70,7 @@ static const char * const cs35l56_asp1_mux_control_names[] = { · 47 unmodified lines | |||
| 68 | "ASP1 TX1 Source", "ASP1 TX2 Source", "ASP1 TX3 Source", "ASP1 TX4 Source" | 70 | "ASP1 TX1 Source", "ASP1 TX2 Source", "ASP1 TX3 Source", "ASP1 TX4 Source" |
| 69 | }; | 71 | }; |
| 70 | 72 | ||
| 71 | static int cs35l56_dspwait_asp1tx_get(struct snd_kcontrol *kcontrol, | 73 | static int cs35l56_sync_asp1_mixer_widgets_with_firmware(struct cs35l56_private *cs35l56) |
| 72 | struct snd_ctl_elem_value *ucontrol) | ||
| 73 | { | ||
| 74 | struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); | ||
| 75 | struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component); | ||
| 76 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | ||
| 77 | int index = e->shift_l; | ||
| 78 | unsigned int addr, val; | ||
| 79 | int ret; | ||
| 80 | |||
| 81 | /* Wait for mux to be initialized */ | ||
| 82 | cs35l56_wait_dsp_ready(cs35l56); | ||
| 83 | flush_work(&cs35l56->mux_init_work); | ||
| 84 | |||
| 85 | addr = cs35l56_asp1_mixer_regs[index]; | ||
| 86 | ret = regmap_read(cs35l56->base.regmap, addr, &val); | ||
| 87 | if (ret) | ||
| 88 | return ret; | ||
| 89 | |||
| 90 | val &= CS35L56_ASP_TXn_SRC_MASK; | ||
| 91 | ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(e, val); | ||
| 92 | |||
| 93 | return 0; | ||
| 94 | } | ||
| 95 | |||
| 96 | static int cs35l56_dspwait_asp1tx_put(struct snd_kcontrol *kcontrol, | ||
| 97 | struct snd_ctl_elem_value *ucontrol) | ||
| 98 | { | ||
| 99 | struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); | ||
| 100 | struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); | ||
| 101 | struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component); | ||
| 102 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | ||
| 103 | int item = ucontrol->value.enumerated.item[0]; | ||
| 104 | int index = e->shift_l; | ||
| 105 | unsigned int addr, val; | ||
| 106 | bool changed; | ||
| 107 | int ret; | ||
| 108 | |||
| 109 | /* Wait for mux to be initialized */ | ||
| 110 | cs35l56_wait_dsp_ready(cs35l56); | ||
| 111 | flush_work(&cs35l56->mux_init_work); | ||
| 112 | |||
| 113 | addr = cs35l56_asp1_mixer_regs[index]; | ||
| 114 | val = snd_soc_enum_item_to_val(e, item); | ||
| 115 | |||
| 116 | ret = regmap_update_bits_check(cs35l56->base.regmap, addr, | ||
| 117 | CS35L56_ASP_TXn_SRC_MASK, val, &changed); | ||
| 118 | if (!ret) | ||
| 119 | return ret; | ||
| 120 | |||
| 121 | if (changed) | ||
| 122 | snd_soc_dapm_mux_update_power(dapm, kcontrol, item, e, NULL); | ||
| 123 | |||
| 124 | return changed; | ||
| 125 | } | ||
| 126 | |||
| 127 | static void cs35l56_mark_asp1_mixer_widgets_dirty(struct cs35l56_private *cs35l56) | ||
| 128 | { | 74 | { |
| 129 | struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cs35l56->component); | 75 | struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cs35l56->component); |
| 130 | const char *prefix = cs35l56->component->name_prefix; | 76 | const char *prefix = cs35l56->component->name_prefix; |
| @@ -135,13 +81,19 @@ static void cs35l56_mark_asp1_mixer_widgets_dirty(struct cs35l56_private *cs35l5 · 4 unmodified lines | |||
| 135 | unsigned int val[4]; | 81 | unsigned int val[4]; |
| 136 | int i, item, ret; | 82 | int i, item, ret; |
| 137 | 83 | ||
| 84 | if (cs35l56->asp1_mixer_widgets_initialized) | ||
| 85 | return 0; | ||
| 86 | |||
| 138 | /* | 87 | /* |
| 139 | * Resume so we can read the registers from silicon if the regmap | 88 | * Resume so we can read the registers from silicon if the regmap |
| 140 | * cache has not yet been populated. | 89 | * cache has not yet been populated. |
| 141 | */ | 90 | */ |
| 142 | ret = pm_runtime_resume_and_get(cs35l56->base.dev); | 91 | ret = pm_runtime_resume_and_get(cs35l56->base.dev); |
| 143 | if (ret < 0) | 92 | if (ret < 0) |
| 144 | return; | 93 | return ret; |
| 94 | |||
| 95 | /* Wait for firmware download and reboot */ | ||
| 96 | cs35l56_wait_dsp_ready(cs35l56); | ||
| 145 | 97 | ||
| 146 | ret = regmap_bulk_read(cs35l56->base.regmap, CS35L56_ASP1TX1_INPUT, | 98 | ret = regmap_bulk_read(cs35l56->base.regmap, CS35L56_ASP1TX1_INPUT, |
| 147 | val, ARRAY_SIZE(val)); | 99 | val, ARRAY_SIZE(val)); |
| @@ -151,12 +103,9 @@ static void cs35l56_mark_asp1_mixer_widgets_dirty(struct cs35l56_private *cs35l5 · 3 unmodified lines | |||
| 151 | 103 | ||
| 152 | if (ret) { | 104 | if (ret) { |
| 153 | dev_err(cs35l56->base.dev, "Failed to read ASP1 mixer regs: %d\n", ret); | 105 | dev_err(cs35l56->base.dev, "Failed to read ASP1 mixer regs: %d\n", ret); |
| 154 | return; | 106 | return ret; |
| 155 | } | 107 | } |
| 156 | 108 | ||
| 157 | snd_soc_card_mutex_lock(dapm->card); | ||
| 158 | WARN_ON(!dapm->card->instantiated); | ||
| 159 | |||
| 160 | for (i = 0; i < ARRAY_SIZE(cs35l56_asp1_mux_control_names); ++i) { | 109 | for (i = 0; i < ARRAY_SIZE(cs35l56_asp1_mux_control_names); ++i) { |
| 161 | name = cs35l56_asp1_mux_control_names[i]; | 110 | name = cs35l56_asp1_mux_control_names[i]; |
| 162 | 111 | ||
| @@ -176,16 +125,65 @@ static void cs35l56_mark_asp1_mixer_widgets_dirty(struct cs35l56_private *cs35l5 · 13 unmodified lines | |||
| 176 | snd_soc_dapm_mux_update_power(dapm, kcontrol, item, e, NULL); | 125 | snd_soc_dapm_mux_update_power(dapm, kcontrol, item, e, NULL); |
| 177 | } | 126 | } |
| 178 | 127 | ||
| 179 | snd_soc_card_mutex_unlock(dapm->card); | 128 | cs35l56->asp1_mixer_widgets_initialized = true; |
| 129 | |||
| 130 | return 0; | ||
| 180 | } | 131 | } |
| 181 | 132 | ||
| 182 | static void cs35l56_mux_init_work(struct work_struct *work) | 133 | static int cs35l56_dspwait_asp1tx_get(struct snd_kcontrol *kcontrol, |
| 134 | struct snd_ctl_elem_value *ucontrol) | ||
| 183 | { | 135 | { |
| 184 | struct cs35l56_private *cs35l56 = container_of(work, | 136 | struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); |
| 185 | struct cs35l56_private, | 137 | struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component); |
| 186 | mux_init_work); | 138 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
| 139 | int index = e->shift_l; | ||
| 140 | unsigned int addr, val; | ||
| 141 | int ret; | ||
| 142 | |||
| 143 | ret = cs35l56_sync_asp1_mixer_widgets_with_firmware(cs35l56); | ||
| 144 | if (ret) | ||
| 145 | return ret; | ||
| 146 | |||
| 147 | addr = cs35l56_asp1_mixer_regs[index]; | ||
| 148 | ret = regmap_read(cs35l56->base.regmap, addr, &val); | ||
| 149 | if (ret) | ||
| 150 | return ret; | ||
| 151 | |||
| 152 | val &= CS35L56_ASP_TXn_SRC_MASK; | ||
| 153 | ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(e, val); | ||
| 154 | |||
| 155 | return 0; | ||
| 156 | } | ||
| 157 | |||
| 158 | static int cs35l56_dspwait_asp1tx_put(struct snd_kcontrol *kcontrol, | ||
| 159 | struct snd_ctl_elem_value *ucontrol) | ||
| 160 | { | ||
| 161 | struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); | ||
| 162 | struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); | ||
| 163 | struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component); | ||
| 164 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | ||
| 165 | int item = ucontrol->value.enumerated.item[0]; | ||
| 166 | int index = e->shift_l; | ||
| 167 | unsigned int addr, val; | ||
| 168 | bool changed; | ||
| 169 | int ret; | ||
| 187 | 170 | ||
| 188 | cs35l56_mark_asp1_mixer_widgets_dirty(cs35l56); | 171 | ret = cs35l56_sync_asp1_mixer_widgets_with_firmware(cs35l56); |
| 172 | if (ret) | ||
| 173 | return ret; | ||
| 174 | |||
| 175 | addr = cs35l56_asp1_mixer_regs[index]; | ||
| 176 | val = snd_soc_enum_item_to_val(e, item); | ||
| 177 | |||
| 178 | ret = regmap_update_bits_check(cs35l56->base.regmap, addr, | ||
| 179 | CS35L56_ASP_TXn_SRC_MASK, val, &changed); | ||
| 180 | if (ret) | ||
| 181 | return ret; | ||
| 182 | |||
| 183 | if (changed) | ||
| 184 | snd_soc_dapm_mux_update_power(dapm, kcontrol, item, e, NULL); | ||
| 185 | |||
| 186 | return changed; | ||
| 189 | } | 187 | } |
| 190 | 188 | ||
| 191 | static DECLARE_TLV_DB_SCALE(vol_tlv, -10000, 25, 0); | 189 | static DECLARE_TLV_DB_SCALE(vol_tlv, -10000, 25, 0); |
| @@ -936,14 +934,6 @@ static void cs35l56_dsp_work(struct work_struct *work) · 744 unmodified lines | |||
| 936 | else | 934 | else |
| 937 | cs35l56_patch(cs35l56, firmware_missing); | 935 | cs35l56_patch(cs35l56, firmware_missing); |
| 938 | 936 | ||
| 939 | |||
| 940 | /* | ||
| 941 | * Set starting value of ASP1 mux widgets. Updating a mux takes | ||
| 942 | * the DAPM mutex. Post this to a separate job so that DAPM | ||
| 943 | * power-up can wait for dsp_work to complete without deadlocking | ||
| 944 | * on the DAPM mutex. | ||
| 945 | */ | ||
| 946 | queue_work(cs35l56->dsp_wq, &cs35l56->mux_init_work); | ||
| 947 | err: | 937 | err: |
| 948 | pm_runtime_mark_last_busy(cs35l56->base.dev); | 938 | pm_runtime_mark_last_busy(cs35l56->base.dev); |
| 949 | pm_runtime_put_autosuspend(cs35l56->base.dev); | 939 | pm_runtime_put_autosuspend(cs35l56->base.dev); |
| @@ -989,6 +979,13 @@ static int cs35l56_component_probe(struct snd_soc_component *component) · 39 unmodified lines | |||
| 989 | debugfs_create_bool("can_hibernate", 0444, debugfs_root, &cs35l56->base.can_hibernate); | 979 | debugfs_create_bool("can_hibernate", 0444, debugfs_root, &cs35l56->base.can_hibernate); |
| 990 | debugfs_create_bool("fw_patched", 0444, debugfs_root, &cs35l56->base.fw_patched); | 980 | debugfs_create_bool("fw_patched", 0444, debugfs_root, &cs35l56->base.fw_patched); |
| 991 | 981 | ||
| 982 | /* | ||
| 983 | * The widgets for the ASP1TX mixer can't be initialized | ||
| 984 | * until the firmware has been downloaded and rebooted. | ||
| 985 | */ | ||
| 986 | regcache_drop_region(cs35l56->base.regmap, CS35L56_ASP1TX1_INPUT, CS35L56_ASP1TX4_INPUT); | ||
| 987 | cs35l56->asp1_mixer_widgets_initialized = false; | ||
| 988 | |||
| 992 | queue_work(cs35l56->dsp_wq, &cs35l56->dsp_work); | 989 | queue_work(cs35l56->dsp_wq, &cs35l56->dsp_work); |
| 993 | 990 | ||
| 994 | return 0; | 991 | return 0; |
| @@ -999,7 +996,6 @@ static void cs35l56_component_remove(struct snd_soc_component *component) · 4 unmodified lines | |||
| 999 | struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component); | 996 | struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component); |
| 1000 | 997 | ||
| 1001 | cancel_work_sync(&cs35l56->dsp_work); | 998 | cancel_work_sync(&cs35l56->dsp_work); |
| 1002 | cancel_work_sync(&cs35l56->mux_init_work); | ||
| 1003 | 999 | ||
| 1004 | if (cs35l56->dsp.cs_dsp.booted) | 1000 | if (cs35l56->dsp.cs_dsp.booted) |
| 1005 | wm_adsp_power_down(&cs35l56->dsp); | 1001 | wm_adsp_power_down(&cs35l56->dsp); |
| @@ -1070,10 +1066,8 @@ int cs35l56_system_suspend(struct device *dev) · 64 unmodified lines | |||
| 1070 | 1066 | ||
| 1071 | dev_dbg(dev, "system_suspend\n"); | 1067 | dev_dbg(dev, "system_suspend\n"); |
| 1072 | 1068 | ||
| 1073 | if (cs35l56->component) { | 1069 | if (cs35l56->component) |
| 1074 | flush_work(&cs35l56->dsp_work); | 1070 | flush_work(&cs35l56->dsp_work); |
| 1075 | cancel_work_sync(&cs35l56->mux_init_work); | ||
| 1076 | } | ||
| 1077 | 1071 | ||
| 1078 | /* | 1072 | /* |
| 1079 | * The interrupt line is normally shared, but after we start suspending | 1073 | * The interrupt line is normally shared, but after we start suspending |
| @@ -1224,7 +1218,6 @@ static int cs35l56_dsp_init(struct cs35l56_private *cs35l56) · 144 unmodified lines | |||
| 1224 | return -ENOMEM; | 1218 | return -ENOMEM; |
| 1225 | 1219 | ||
| 1226 | INIT_WORK(&cs35l56->dsp_work, cs35l56_dsp_work); | 1220 | INIT_WORK(&cs35l56->dsp_work, cs35l56_dsp_work); |
| 1227 | INIT_WORK(&cs35l56->mux_init_work, cs35l56_mux_init_work); | ||
| 1228 | 1221 | ||
| 1229 | dsp = &cs35l56->dsp; | 1222 | dsp = &cs35l56->dsp; |
| 1230 | cs35l56_init_cs_dsp(&cs35l56->base, &dsp->cs_dsp); | 1223 | cs35l56_init_cs_dsp(&cs35l56->base, &dsp->cs_dsp); |
| @@ -1269,6 +1262,94 @@ static int cs35l56_get_firmware_uid(struct cs35l56_private *cs35l56) · 38 unmodified lines | |||
| 1269 | return 0; | 1262 | return 0; |
| 1270 | } | 1263 | } |
| 1271 | 1264 | ||
| 1265 | /* | ||
| 1266 | * Some SoundWire laptops have a spk-id-gpios property but it points to | ||
| 1267 | * the wrong ACPI Device node so can't be used to get the GPIO. Try to | ||
| 1268 | * find the SDCA node containing the GpioIo resource and add a GPIO | ||
| 1269 | * mapping to it. | ||
| 1270 | */ | ||
| 1271 | static const struct acpi_gpio_params cs35l56_af01_first_gpio = { 0, 0, false }; | ||
| 1272 | static const struct acpi_gpio_mapping cs35l56_af01_spkid_gpios_mapping[] = { | ||
| 1273 | { "spk-id-gpios", &cs35l56_af01_first_gpio, 1 }, | ||
| 1274 | { } | ||
| 1275 | }; | ||
| 1276 | |||
| 1277 | static void cs35l56_acpi_dev_release_driver_gpios(void *adev) | ||
| 1278 | { | ||
| 1279 | acpi_dev_remove_driver_gpios(adev); | ||
| 1280 | } | ||
| 1281 | |||
| 1282 | static int cs35l56_try_get_broken_sdca_spkid_gpio(struct cs35l56_private *cs35l56) | ||
| 1283 | { | ||
| 1284 | struct fwnode_handle *af01_fwnode; | ||
| 1285 | const union acpi_object *obj; | ||
| 1286 | struct gpio_desc *desc; | ||
| 1287 | int ret; | ||
| 1288 | |||
| 1289 | /* Find the SDCA node containing the GpioIo */ | ||
| 1290 | af01_fwnode = device_get_named_child_node(cs35l56->base.dev, "AF01"); | ||
| 1291 | if (!af01_fwnode) { | ||
| 1292 | dev_dbg(cs35l56->base.dev, "No AF01 node\n"); | ||
| 1293 | return -ENOENT; | ||
| 1294 | } | ||
| 1295 | |||
| 1296 | ret = acpi_dev_get_property(ACPI_COMPANION(cs35l56->base.dev), | ||
| 1297 | "spk-id-gpios", ACPI_TYPE_PACKAGE, &obj); | ||
| 1298 | if (ret) { | ||
| 1299 | dev_dbg(cs35l56->base.dev, "Could not get spk-id-gpios package: %d\n", ret); | ||
| 1300 | return -ENOENT; | ||
| 1301 | } | ||
| 1302 | |||
| 1303 | /* The broken properties we can handle are a 4-element package (one GPIO) */ | ||
| 1304 | if (obj->package.count != 4) { | ||
| 1305 | dev_warn(cs35l56->base.dev, "Unexpected spk-id element count %d\n", | ||
| 1306 | obj->package.count); | ||
| 1307 | return -ENOENT; | ||
| 1308 | } | ||
| 1309 | |||
| 1310 | /* Add a GPIO mapping if it doesn't already have one */ | ||
| 1311 | if (!fwnode_property_present(af01_fwnode, "spk-id-gpios")) { | ||
| 1312 | struct acpi_device *adev = to_acpi_device_node(af01_fwnode); | ||
| 1313 | |||
| 1314 | /* | ||
| 1315 | * Can't use devm_acpi_dev_add_driver_gpios() because the | ||
| 1316 | * mapping isn't being added to the node pointed to by | ||
| 1317 | * ACPI_COMPANION(). | ||
| 1318 | */ | ||
| 1319 | ret = acpi_dev_add_driver_gpios(adev, cs35l56_af01_spkid_gpios_mapping); | ||
| 1320 | if (ret) { | ||
| 1321 | return dev_err_probe(cs35l56->base.dev, ret, | ||
| 1322 | "Failed to add gpio mapping to AF01\n"); | ||
| 1323 | } | ||
| 1324 | |||
| 1325 | ret = devm_add_action_or_reset(cs35l56->base.dev, | ||
| 1326 | cs35l56_acpi_dev_release_driver_gpios, | ||
| 1327 | adev); | ||
| 1328 | if (ret) | ||
| 1329 | return ret; | ||
| 1330 | |||
| 1331 | dev_dbg(cs35l56->base.dev, "Added spk-id-gpios mapping to AF01\n"); | ||
| 1332 | } | ||
| 1333 | |||
| 1334 | desc = fwnode_gpiod_get_index(af01_fwnode, "spk-id", 0, GPIOD_IN, NULL); | ||
| 1335 | if (IS_ERR(desc)) { | ||
| 1336 | ret = PTR_ERR(desc); | ||
| 1337 | return dev_err_probe(cs35l56->base.dev, ret, "Get GPIO from AF01 failed\n"); | ||
| 1338 | } | ||
| 1339 | |||
| 1340 | ret = gpiod_get_value_cansleep(desc); | ||
| 1341 | gpiod_put(desc); | ||
| 1342 | |||
| 1343 | if (ret < 0) { | ||
| 1344 | dev_err_probe(cs35l56->base.dev, ret, "Error reading spk-id GPIO\n"); | ||
| 1345 | return ret; | ||
| 1346 | } | ||
| 1347 | |||
| 1348 | dev_info(cs35l56->base.dev, "Got spk-id from AF01\n"); | ||
| 1349 | |||
| 1350 | return ret; | ||
| 1351 | } | ||
| 1352 | |||
| 1272 | int cs35l56_common_probe(struct cs35l56_private *cs35l56) | 1353 | int cs35l56_common_probe(struct cs35l56_private *cs35l56) |
| 1273 | { | 1354 | { |
| 1274 | int ret; | 1355 | int ret; |
| @@ -1313,6 +1394,9 @@ int cs35l56_common_probe(struct cs35l56_private *cs35l56) · 38 unmodified lines | |||
| 1313 | } | 1394 | } |
| 1314 | 1395 | ||
| 1315 | ret = cs35l56_get_speaker_id(&cs35l56->base); | 1396 | ret = cs35l56_get_speaker_id(&cs35l56->base); |
| 1397 | if (ACPI_COMPANION(cs35l56->base.dev) && cs35l56->sdw_peripheral && (ret == -ENOENT)) | ||
| 1398 | ret = cs35l56_try_get_broken_sdca_spkid_gpio(cs35l56); | ||
| 1399 | |||
| 1316 | if ((ret < 0) && (ret != -ENOENT)) | 1400 | if ((ret < 0) && (ret != -ENOENT)) |
| 1317 | goto err; | 1401 | goto err; |
| 1318 | 1402 | ||
| @@ -34,7 +34,6 @@ struct cs35l56_private { · 33 unmodified lines | |||
| 34 | struct wm_adsp dsp; /* must be first member */ | 34 | struct wm_adsp dsp; /* must be first member */ |
| 35 | struct cs35l56_base base; | 35 | struct cs35l56_base base; |
| 36 | struct work_struct dsp_work; | 36 | struct work_struct dsp_work; |
| 37 | struct work_struct mux_init_work; | ||
| 38 | struct workqueue_struct *dsp_wq; | 37 | struct workqueue_struct *dsp_wq; |
| 39 | struct snd_soc_component *component; | 38 | struct snd_soc_component *component; |
| 40 | struct regulator_bulk_data supplies[CS35L56_NUM_BULK_SUPPLIES]; | 39 | struct regulator_bulk_data supplies[CS35L56_NUM_BULK_SUPPLIES]; |
| @@ -52,6 +51,7 @@ struct cs35l56_private { · 11 unmodified lines | |||
| 52 | u8 asp_slot_count; | 51 | u8 asp_slot_count; |
| 53 | bool tdm_mode; | 52 | bool tdm_mode; |
| 54 | bool sysclk_set; | 53 | bool sysclk_set; |
| 54 | bool asp1_mixer_widgets_initialized; | ||
| 55 | u8 old_sdw_clock_scale; | 55 | u8 old_sdw_clock_scale; |
| 56 | }; | 56 | }; |
| 57 | 57 | ||
| @@ -2257,7 +2257,10 @@ static int cs42l43_codec_probe(struct platform_device *pdev) · 2256 unmodified lines | |||
| 2257 | pm_runtime_use_autosuspend(priv->dev); | 2257 | pm_runtime_use_autosuspend(priv->dev); |
| 2258 | pm_runtime_set_active(priv->dev); | 2258 | pm_runtime_set_active(priv->dev); |
| 2259 | pm_runtime_get_noresume(priv->dev); | 2259 | pm_runtime_get_noresume(priv->dev); |
| 2260 | devm_pm_runtime_enable(priv->dev); | 2260 | |
| 2261 | ret = devm_pm_runtime_enable(priv->dev); | ||
| 2262 | if (ret) | ||
| 2263 | goto err_pm; | ||
| 2261 | 2264 | ||
| 2262 | for (i = 0; i < ARRAY_SIZE(cs42l43_irqs); i++) { | 2265 | for (i = 0; i < ARRAY_SIZE(cs42l43_irqs); i++) { |
| 2263 | ret = cs42l43_request_irq(priv, dom, cs42l43_irqs[i].name, | 2266 | ret = cs42l43_request_irq(priv, dom, cs42l43_irqs[i].name, |
| @@ -2333,8 +2336,47 @@ static int cs42l43_codec_runtime_resume(struct device *dev) · 69 unmodified lines | |||
| 2333 | return 0; | 2336 | return 0; |
| 2334 | } | 2337 | } |
| 2335 | 2338 | ||
| 2336 | static DEFINE_RUNTIME_DEV_PM_OPS(cs42l43_codec_pm_ops, NULL, | 2339 | static int cs42l43_codec_suspend(struct device *dev) |
| 2337 | cs42l43_codec_runtime_resume, NULL); | 2340 | { |
| 2341 | struct cs42l43 *cs42l43 = dev_get_drvdata(dev); | ||
| 2342 | |||
| 2343 | disable_irq(cs42l43->irq); | ||
| 2344 | |||
| 2345 | return 0; | ||
| 2346 | } | ||
| 2347 | |||
| 2348 | static int cs42l43_codec_suspend_noirq(struct device *dev) | ||
| 2349 | { | ||
| 2350 | struct cs42l43 *cs42l43 = dev_get_drvdata(dev); | ||
| 2351 | |||
| 2352 | enable_irq(cs42l43->irq); | ||
| 2353 | |||
| 2354 | return 0; | ||
| 2355 | } | ||
| 2356 | |||
| 2357 | static int cs42l43_codec_resume(struct device *dev) | ||
| 2358 | { | ||
| 2359 | struct cs42l43 *cs42l43 = dev_get_drvdata(dev); | ||
| 2360 | |||
| 2361 | enable_irq(cs42l43->irq); | ||
| 2362 | |||
| 2363 | return 0; | ||
| 2364 | } | ||
| 2365 | |||
| 2366 | static int cs42l43_codec_resume_noirq(struct device *dev) | ||
| 2367 | { | ||
| 2368 | struct cs42l43 *cs42l43 = dev_get_drvdata(dev); | ||
| 2369 | |||
| 2370 | disable_irq(cs42l43->irq); | ||
| 2371 | |||
| 2372 | return 0; | ||
| 2373 | } | ||
| 2374 | |||
| 2375 | static const struct dev_pm_ops cs42l43_codec_pm_ops = { | ||
| 2376 | SYSTEM_SLEEP_PM_OPS(cs42l43_codec_suspend, cs42l43_codec_resume) | ||
| 2377 | NOIRQ_SYSTEM_SLEEP_PM_OPS(cs42l43_codec_suspend_noirq, cs42l43_codec_resume_noirq) | ||
| 2378 | RUNTIME_PM_OPS(NULL, cs42l43_codec_runtime_resume, NULL) | ||
| 2379 | }; | ||
| 2338 | 2380 | ||
| 2339 | static const struct platform_device_id cs42l43_codec_id_table[] = { | 2381 | static const struct platform_device_id cs42l43_codec_id_table[] = { |
| 2340 | { "cs42l43-codec", }, | 2382 | { "cs42l43-codec", }, |
| @@ -3317,6 +3317,7 @@ static void rt5645_jack_detect_work(struct work_struct *work) · 3316 unmodified lines | |||
| 3317 | report, SND_JACK_HEADPHONE); | 3317 | report, SND_JACK_HEADPHONE); |
| 3318 | snd_soc_jack_report(rt5645->mic_jack, | 3318 | snd_soc_jack_report(rt5645->mic_jack, |
| 3319 | report, SND_JACK_MICROPHONE); | 3319 | report, SND_JACK_MICROPHONE); |
| 3320 | mutex_unlock(&rt5645->jd_mutex); | ||
| 3320 | return; | 3321 | return; |
| 3321 | case 4: | 3322 | case 4: |
| 3322 | val = snd_soc_component_read(rt5645->component, RT5645_A_JD_CTRL1) & 0x0020; | 3323 | 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 = { · 369 unmodified lines | |||
| 3692 | .mono_speaker = true, | 3693 | .mono_speaker = true, |
| 3693 | }; | 3694 | }; |
| 3694 | 3695 | ||
| 3696 | static const struct rt5645_platform_data jd_mode3_inv_data = { | ||
| 3697 | .jd_mode = 3, | ||
| 3698 | .inv_jd1_1 = true, | ||
| 3699 | }; | ||
| 3700 | |||
| 3695 | static const struct rt5645_platform_data jd_mode3_platform_data = { | 3701 | static const struct rt5645_platform_data jd_mode3_platform_data = { |
| 3696 | .jd_mode = 3, | 3702 | .jd_mode = 3, |
| 3697 | }; | 3703 | }; |
| @@ -3837,6 +3843,16 @@ static const struct dmi_system_id dmi_platform_data[] = { · 139 unmodified lines | |||
| 3837 | DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), | 3843 | DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), |
| 3838 | DMI_EXACT_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"), | 3844 | DMI_EXACT_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"), |
| 3839 | DMI_EXACT_MATCH(DMI_BOARD_VERSION, "Default string"), | 3845 | DMI_EXACT_MATCH(DMI_BOARD_VERSION, "Default string"), |
| 3846 | /* | ||
| 3847 | * Above strings are too generic, LattePanda BIOS versions for | ||
| 3848 | * all 4 hw revisions are: | ||
| 3849 | * DF-BI-7-S70CR100-* | ||
| 3850 | * DF-BI-7-S70CR110-* | ||
| 3851 | * DF-BI-7-S70CR200-* | ||
| 3852 | * LP-BS-7-S70CR700-* | ||
| 3853 | * Do a partial match for S70CR to avoid false positive matches. | ||
| 3854 | */ | ||
| 3855 | DMI_MATCH(DMI_BIOS_VERSION, "S70CR"), | ||
| 3840 | }, | 3856 | }, |
| 3841 | .driver_data = (void *)&lattepanda_board_platform_data, | 3857 | .driver_data = (void *)&lattepanda_board_platform_data, |
| 3842 | }, | 3858 | }, |
| @@ -3871,6 +3887,16 @@ static const struct dmi_system_id dmi_platform_data[] = { · 28 unmodified lines | |||
| 3871 | }, | 3887 | }, |
| 3872 | .driver_data = (void *)&intel_braswell_platform_data, | 3888 | .driver_data = (void *)&intel_braswell_platform_data, |
| 3873 | }, | 3889 | }, |
| 3890 | { | ||
| 3891 | .ident = "Meegopad T08", | ||
| 3892 | .matches = { | ||
| 3893 | DMI_MATCH(DMI_SYS_VENDOR, "Default string"), | ||
| 3894 | DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), | ||
| 3895 | DMI_MATCH(DMI_BOARD_NAME, "T3 MRD"), | ||
| 3896 | DMI_MATCH(DMI_BOARD_VERSION, "V1.1"), | ||
| 3897 | }, | ||
| 3898 | .driver_data = (void *)&jd_mode3_inv_data, | ||
| 3899 | }, | ||
| 3874 | { } | 3900 | { } |
| 3875 | }; | 3901 | }; |
| 3876 | 3902 | ||
| @@ -267,6 +267,7 @@ void tas2781_reset(struct tasdevice_priv *tas_dev) · 266 unmodified lines | |||
| 267 | EXPORT_SYMBOL_GPL(tas2781_reset); | 267 | EXPORT_SYMBOL_GPL(tas2781_reset); |
| 268 | 268 | ||
| 269 | int tascodec_init(struct tasdevice_priv *tas_priv, void *codec, | 269 | int tascodec_init(struct tasdevice_priv *tas_priv, void *codec, |
| 270 | struct module *module, | ||
| 270 | void (*cont)(const struct firmware *fw, void *context)) | 271 | void (*cont)(const struct firmware *fw, void *context)) |
| 271 | { | 272 | { |
| 272 | int ret = 0; | 273 | int ret = 0; |
| @@ -280,7 +281,7 @@ int tascodec_init(struct tasdevice_priv *tas_priv, void *codec, · 7 unmodified lines | |||
| 280 | tas_priv->dev_name, tas_priv->ndev); | 281 | tas_priv->dev_name, tas_priv->ndev); |
| 281 | crc8_populate_msb(tas_priv->crc8_lkp_tbl, TASDEVICE_CRC8_POLYNOMIAL); | 282 | crc8_populate_msb(tas_priv->crc8_lkp_tbl, TASDEVICE_CRC8_POLYNOMIAL); |
| 282 | tas_priv->codec = codec; | 283 | tas_priv->codec = codec; |
| 283 | ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT, | 284 | ret = request_firmware_nowait(module, FW_ACTION_UEVENT, |
| 284 | tas_priv->rca_binaryname, tas_priv->dev, GFP_KERNEL, tas_priv, | 285 | tas_priv->rca_binaryname, tas_priv->dev, GFP_KERNEL, tas_priv, |
| 285 | cont); | 286 | cont); |
| 286 | if (ret) | 287 | if (ret) |
| @@ -566,7 +566,7 @@ static int tasdevice_codec_probe(struct snd_soc_component *codec) · 565 unmodified lines | |||
| 566 | { | 566 | { |
| 567 | struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(codec); | 567 | struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(codec); |
| 568 | 568 | ||
| 569 | return tascodec_init(tas_priv, codec, tasdevice_fw_ready); | 569 | return tascodec_init(tas_priv, codec, THIS_MODULE, tasdevice_fw_ready); |
| 570 | } | 570 | } |
| 571 | 571 | ||
| 572 | static void tasdevice_deinit(void *context) | 572 | 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) · 476 unmodified lines | |||
| 477 | return 0; | 477 | return 0; |
| 478 | 478 | ||
| 479 | err_i915_init: | 479 | err_i915_init: |
| 480 | pci_free_irq(pci, 0, adev); | ||
| 481 | pci_free_irq(pci, 0, bus); | ||
| 482 | pci_free_irq_vectors(pci); | ||
| 480 | pci_clear_master(pci); | 483 | pci_clear_master(pci); |
| 481 | pci_set_drvdata(pci, NULL); | 484 | pci_set_drvdata(pci, NULL); |
| 482 | err_acquire_irq: | 485 | err_acquire_irq: |
| @@ -857,7 +857,7 @@ assign_copier_gtw_instance(struct snd_soc_component *comp, struct avs_tplg_modcf · 856 unmodified lines | |||
| 857 | } | 857 | } |
| 858 | 858 | ||
| 859 | /* If topology sets value don't overwrite it */ | 859 | /* If topology sets value don't overwrite it */ |
| 860 | if (cfg->copier.vindex.i2s.instance) | 860 | if (cfg->copier.vindex.val) |
| 861 | return; | 861 | return; |
| 862 | 862 | ||
| 863 | mach = dev_get_platdata(comp->card->dev); | 863 | mach = dev_get_platdata(comp->card->dev); |
| @@ -241,7 +241,8 @@ static int snd_byt_cht_cx2072x_probe(struct platform_device *pdev) · 240 unmodified lines | |||
| 241 | 241 | ||
| 242 | /* fix index of codec dai */ | 242 | /* fix index of codec dai */ |
| 243 | for (i = 0; i < ARRAY_SIZE(byt_cht_cx2072x_dais); i++) { | 243 | for (i = 0; i < ARRAY_SIZE(byt_cht_cx2072x_dais); i++) { |
| 244 | if (!strcmp(byt_cht_cx2072x_dais[i].codecs->name, | 244 | if (byt_cht_cx2072x_dais[i].codecs->name && |
| 245 | !strcmp(byt_cht_cx2072x_dais[i].codecs->name, | ||
| 245 | "i2c-14F10720:00")) { | 246 | "i2c-14F10720:00")) { |
| 246 | dai_index = i; | 247 | dai_index = i; |
| 247 | break; | 248 | break; |
| @@ -245,7 +245,8 @@ static int bytcht_da7213_probe(struct platform_device *pdev) · 244 unmodified lines | |||
| 245 | 245 | ||
| 246 | /* fix index of codec dai */ | 246 | /* fix index of codec dai */ |
| 247 | for (i = 0; i < ARRAY_SIZE(dailink); i++) { | 247 | for (i = 0; i < ARRAY_SIZE(dailink); i++) { |
| 248 | if (!strcmp(dailink[i].codecs->name, "i2c-DLGS7213:00")) { | 248 | if (dailink[i].codecs->name && |
| 249 | !strcmp(dailink[i].codecs->name, "i2c-DLGS7213:00")) { | ||
| 249 | dai_index = i; | 250 | dai_index = i; |
| 250 | break; | 251 | break; |
| 251 | } | 252 | } |
| @@ -546,7 +546,8 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) · 545 unmodified lines | |||
| 546 | 546 | ||
| 547 | /* fix index of codec dai */ | 547 | /* fix index of codec dai */ |
| 548 | for (i = 0; i < ARRAY_SIZE(byt_cht_es8316_dais); i++) { | 548 | for (i = 0; i < ARRAY_SIZE(byt_cht_es8316_dais); i++) { |
| 549 | if (!strcmp(byt_cht_es8316_dais[i].codecs->name, | 549 | if (byt_cht_es8316_dais[i].codecs->name && |
| 550 | !strcmp(byt_cht_es8316_dais[i].codecs->name, | ||
| 550 | "i2c-ESSX8316:00")) { | 551 | "i2c-ESSX8316:00")) { |
| 551 | dai_index = i; | 552 | dai_index = i; |
| 552 | break; | 553 | break; |
| @@ -1652,7 +1652,8 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) · 1651 unmodified lines | |||
| 1652 | 1652 | ||
| 1653 | /* fix index of codec dai */ | 1653 | /* fix index of codec dai */ |
| 1654 | for (i = 0; i < ARRAY_SIZE(byt_rt5640_dais); i++) { | 1654 | for (i = 0; i < ARRAY_SIZE(byt_rt5640_dais); i++) { |
| 1655 | if (!strcmp(byt_rt5640_dais[i].codecs->name, | 1655 | if (byt_rt5640_dais[i].codecs->name && |
| 1656 | !strcmp(byt_rt5640_dais[i].codecs->name, | ||
| 1656 | "i2c-10EC5640:00")) { | 1657 | "i2c-10EC5640:00")) { |
| 1657 | dai_index = i; | 1658 | dai_index = i; |
| 1658 | break; | 1659 | break; |
| @@ -910,7 +910,8 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) · 909 unmodified lines | |||
| 910 | 910 | ||
| 911 | /* fix index of codec dai */ | 911 | /* fix index of codec dai */ |
| 912 | for (i = 0; i < ARRAY_SIZE(byt_rt5651_dais); i++) { | 912 | for (i = 0; i < ARRAY_SIZE(byt_rt5651_dais); i++) { |
| 913 | if (!strcmp(byt_rt5651_dais[i].codecs->name, | 913 | if (byt_rt5651_dais[i].codecs->name && |
| 914 | !strcmp(byt_rt5651_dais[i].codecs->name, | ||
| 914 | "i2c-10EC5651:00")) { | 915 | "i2c-10EC5651:00")) { |
| 915 | dai_index = i; | 916 | dai_index = i; |
| 916 | break; | 917 | break; |
| @@ -605,7 +605,8 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) · 604 unmodified lines | |||
| 605 | 605 | ||
| 606 | /* find index of codec dai */ | 606 | /* find index of codec dai */ |
| 607 | for (i = 0; i < ARRAY_SIZE(byt_wm5102_dais); i++) { | 607 | for (i = 0; i < ARRAY_SIZE(byt_wm5102_dais); i++) { |
| 608 | if (!strcmp(byt_wm5102_dais[i].codecs->name, | 608 | if (byt_wm5102_dais[i].codecs->name && |
| 609 | !strcmp(byt_wm5102_dais[i].codecs->name, | ||
| 609 | "wm5102-codec")) { | 610 | "wm5102-codec")) { |
| 610 | dai_index = i; | 611 | dai_index = i; |
| 611 | break; | 612 | break; |
| @@ -40,7 +40,6 @@ struct cht_acpi_card { · 39 unmodified lines | |||
| 40 | struct cht_mc_private { | 40 | struct cht_mc_private { |
| 41 | struct snd_soc_jack jack; | 41 | struct snd_soc_jack jack; |
| 42 | struct cht_acpi_card *acpi_card; | 42 | struct cht_acpi_card *acpi_card; |
| 43 | char codec_name[SND_ACPI_I2C_ID_LEN]; | ||
| 44 | struct clk *mclk; | 43 | struct clk *mclk; |
| 45 | }; | 44 | }; |
| 46 | 45 | ||
| @@ -567,14 +566,14 @@ static int snd_cht_mc_probe(struct platform_device *pdev) · 520 unmodified lines | |||
| 567 | } | 566 | } |
| 568 | 567 | ||
| 569 | card->dev = &pdev->dev; | 568 | card->dev = &pdev->dev; |
| 570 | sprintf(drv->codec_name, "i2c-%s:00", drv->acpi_card->codec_id); | ||
| 571 | 569 | ||
| 572 | /* set correct codec name */ | 570 | /* set correct codec name */ |
| 573 | for (i = 0; i < ARRAY_SIZE(cht_dailink); i++) | 571 | for (i = 0; i < ARRAY_SIZE(cht_dailink); i++) |
| 574 | if (!strcmp(card->dai_link[i].codecs->name, | 572 | if (cht_dailink[i].codecs->name && |
| 573 | !strcmp(cht_dailink[i].codecs->name, | ||
| 575 | "i2c-10EC5645:00")) { | 574 | "i2c-10EC5645:00")) { |
| 576 | card->dai_link[i].codecs->name = drv->codec_name; | ||
| 577 | dai_index = i; | 575 | dai_index = i; |
| 576 | break; | ||
| 578 | } | 577 | } |
| 579 | 578 | ||
| 580 | /* fixup codec name based on HID */ | 579 | /* fixup codec name based on HID */ |
| @@ -466,7 +466,8 @@ static int snd_cht_mc_probe(struct platform_device *pdev) · 465 unmodified lines | |||
| 466 | 466 | ||
| 467 | /* find index of codec dai */ | 467 | /* find index of codec dai */ |
| 468 | for (i = 0; i < ARRAY_SIZE(cht_dailink); i++) { | 468 | for (i = 0; i < ARRAY_SIZE(cht_dailink); i++) { |
| 469 | if (!strcmp(cht_dailink[i].codecs->name, RT5672_I2C_DEFAULT)) { | 469 | if (cht_dailink[i].codecs->name && |
| 470 | !strcmp(cht_dailink[i].codecs->name, RT5672_I2C_DEFAULT)) { | ||
| 470 | dai_index = i; | 471 | dai_index = i; |
| 471 | break; | 472 | break; |
| 472 | } | 473 | } |
| @@ -123,7 +123,7 @@ static struct snd_pcm_hardware q6apm_dai_hardware_playback = { · 122 unmodified lines | |||
| 123 | .fifo_size = 0, | 123 | .fifo_size = 0, |
| 124 | }; | 124 | }; |
| 125 | 125 | ||
| 126 | static void event_handler(uint32_t opcode, uint32_t token, uint32_t *payload, void *priv) | 126 | static void event_handler(uint32_t opcode, uint32_t token, void *payload, void *priv) |
| 127 | { | 127 | { |
| 128 | struct q6apm_dai_rtd *prtd = priv; | 128 | struct q6apm_dai_rtd *prtd = priv; |
| 129 | struct snd_pcm_substream *substream = prtd->substream; | 129 | 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 · 27 unmodified lines | |||
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | static void event_handler_compr(uint32_t opcode, uint32_t token, | 159 | static void event_handler_compr(uint32_t opcode, uint32_t token, |
| 160 | uint32_t *payload, void *priv) | 160 | void *payload, void *priv) |
| 161 | { | 161 | { |
| 162 | struct q6apm_dai_rtd *prtd = priv; | 162 | struct q6apm_dai_rtd *prtd = priv; |
| 163 | struct snd_compr_stream *substream = prtd->cstream; | 163 | struct snd_compr_stream *substream = prtd->cstream; |
| @@ -352,7 +352,7 @@ static int q6apm_dai_open(struct snd_soc_component *component, · 188 unmodified lines | |||
| 352 | 352 | ||
| 353 | spin_lock_init(&prtd->lock); | 353 | spin_lock_init(&prtd->lock); |
| 354 | prtd->substream = substream; | 354 | prtd->substream = substream; |
| 355 | prtd->graph = q6apm_graph_open(dev, (q6apm_cb)event_handler, prtd, graph_id); | 355 | prtd->graph = q6apm_graph_open(dev, event_handler, prtd, graph_id); |
| 356 | if (IS_ERR(prtd->graph)) { | 356 | if (IS_ERR(prtd->graph)) { |
| 357 | dev_err(dev, "%s: Could not allocate memory\n", __func__); | 357 | dev_err(dev, "%s: Could not allocate memory\n", __func__); |
| 358 | ret = PTR_ERR(prtd->graph); | 358 | ret = PTR_ERR(prtd->graph); |
| @@ -496,7 +496,7 @@ static int q6apm_dai_compr_open(struct snd_soc_component *component, · 137 unmodified lines | |||
| 496 | return -ENOMEM; | 496 | return -ENOMEM; |
| 497 | 497 | ||
| 498 | prtd->cstream = stream; | 498 | prtd->cstream = stream; |
| 499 | prtd->graph = q6apm_graph_open(dev, (q6apm_cb)event_handler_compr, prtd, graph_id); | 499 | prtd->graph = q6apm_graph_open(dev, event_handler_compr, prtd, graph_id); |
| 500 | if (IS_ERR(prtd->graph)) { | 500 | if (IS_ERR(prtd->graph)) { |
| 501 | ret = PTR_ERR(prtd->graph); | 501 | ret = PTR_ERR(prtd->graph); |
| 502 | kfree(prtd); | 502 | kfree(prtd); |
| @@ -188,11 +188,13 @@ irqreturn_t acp_sof_ipc_irq_thread(int irq, void *context) · 187 unmodified lines | |||
| 188 | 188 | ||
| 189 | dsp_ack = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_ack_write); | 189 | dsp_ack = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_ack_write); |
| 190 | if (dsp_ack) { | 190 | if (dsp_ack) { |
| 191 | spin_lock_irq(&sdev->ipc_lock); | ||
| 191 | /* handle immediate reply from DSP core */ | 192 | /* handle immediate reply from DSP core */ |
| 192 | acp_dsp_ipc_get_reply(sdev); | 193 | acp_dsp_ipc_get_reply(sdev); |
| 193 | snd_sof_ipc_reply(sdev, 0); | 194 | snd_sof_ipc_reply(sdev, 0); |
| 194 | /* set the done bit */ | 195 | /* set the done bit */ |
| 195 | acp_dsp_ipc_dsp_done(sdev); | 196 | acp_dsp_ipc_dsp_done(sdev); |
| 197 | spin_unlock_irq(&sdev->ipc_lock); | ||
| 196 | ipc_irq = true; | 198 | ipc_irq = true; |
| 197 | } | 199 | } |
| 198 | 200 | ||
| @@ -355,21 +355,20 @@ static irqreturn_t acp_irq_thread(int irq, void *context) · 354 unmodified lines | |||
| 355 | unsigned int count = ACP_HW_SEM_RETRY_COUNT; | 355 | unsigned int count = ACP_HW_SEM_RETRY_COUNT; |
| 356 | 356 | ||
| 357 | spin_lock_irq(&sdev->ipc_lock); | 357 | spin_lock_irq(&sdev->ipc_lock); |
| 358 | while (snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->hw_semaphore_offset)) { | 358 | /* Wait until acquired HW Semaphore lock or timeout */ |
| 359 | /* Wait until acquired HW Semaphore lock or timeout */ | 359 | while (snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->hw_semaphore_offset) && --count) |
| 360 | count--; | 360 | ; |
| 361 | if (!count) { | 361 | spin_unlock_irq(&sdev->ipc_lock); |
| 362 | dev_err(sdev->dev, "%s: Failed to acquire HW lock\n", __func__); | 362 | |
| 363 | spin_unlock_irq(&sdev->ipc_lock); | 363 | if (!count) { |
| 364 | return IRQ_NONE; | 364 | dev_err(sdev->dev, "%s: Failed to acquire HW lock\n", __func__); |
| 365 | } | 365 | return IRQ_NONE; |
| 366 | } | 366 | } |
| 367 | 367 | ||
| 368 | sof_ops(sdev)->irq_thread(irq, sdev); | 368 | sof_ops(sdev)->irq_thread(irq, sdev); |
| 369 | /* Unlock or Release HW Semaphore */ | 369 | /* Unlock or Release HW Semaphore */ |
| 370 | snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->hw_semaphore_offset, 0x0); | 370 | snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->hw_semaphore_offset, 0x0); |
| 371 | 371 | ||
| 372 | spin_unlock_irq(&sdev->ipc_lock); | ||
| 373 | return IRQ_HANDLED; | 372 | return IRQ_HANDLED; |
| 374 | }; | 373 | }; |
| 375 | 374 | ||
| @@ -36,7 +36,7 @@ static const struct sof_dev_desc lnl_desc = { · 35 unmodified lines | |||
| 36 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4/lnl", | 36 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4/lnl", |
| 37 | }, | 37 | }, |
| 38 | .default_tplg_path = { | 38 | .default_tplg_path = { |
| 39 | [SOF_IPC_TYPE_4] = "intel/sof-ace-tplg", | 39 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg", |
| 40 | }, | 40 | }, |
| 41 | .default_fw_filename = { | 41 | .default_fw_filename = { |
| 42 | [SOF_IPC_TYPE_4] = "sof-lnl.ri", | 42 | [SOF_IPC_TYPE_4] = "sof-lnl.ri", |
| @@ -33,18 +33,18 @@ static const struct sof_dev_desc tgl_desc = { · 32 unmodified lines | |||
| 33 | .dspless_mode_supported = true, /* Only supported for HDaudio */ | 33 | .dspless_mode_supported = true, /* Only supported for HDaudio */ |
| 34 | .default_fw_path = { | 34 | .default_fw_path = { |
| 35 | [SOF_IPC_TYPE_3] = "intel/sof", | 35 | [SOF_IPC_TYPE_3] = "intel/sof", |
| 36 | [SOF_IPC_TYPE_4] = "intel/avs/tgl", | 36 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4/tgl", |
| 37 | }, | 37 | }, |
| 38 | .default_lib_path = { | 38 | .default_lib_path = { |
| 39 | [SOF_IPC_TYPE_4] = "intel/avs-lib/tgl", | 39 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/tgl", |
| 40 | }, | 40 | }, |
| 41 | .default_tplg_path = { | 41 | .default_tplg_path = { |
| 42 | [SOF_IPC_TYPE_3] = "intel/sof-tplg", | 42 | [SOF_IPC_TYPE_3] = "intel/sof-tplg", |
| 43 | [SOF_IPC_TYPE_4] = "intel/avs-tplg", | 43 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg", |
| 44 | }, | 44 | }, |
| 45 | .default_fw_filename = { | 45 | .default_fw_filename = { |
| 46 | [SOF_IPC_TYPE_3] = "sof-tgl.ri", | 46 | [SOF_IPC_TYPE_3] = "sof-tgl.ri", |
| 47 | [SOF_IPC_TYPE_4] = "dsp_basefw.bin", | 47 | [SOF_IPC_TYPE_4] = "sof-tgl.ri", |
| 48 | }, | 48 | }, |
| 49 | .nocodec_tplg_filename = "sof-tgl-nocodec.tplg", | 49 | .nocodec_tplg_filename = "sof-tgl-nocodec.tplg", |
| 50 | .ops = &sof_tgl_ops, | 50 | .ops = &sof_tgl_ops, |
| @@ -66,18 +66,18 @@ static const struct sof_dev_desc tglh_desc = { · 15 unmodified lines | |||
| 66 | .dspless_mode_supported = true, /* Only supported for HDaudio */ | 66 | .dspless_mode_supported = true, /* Only supported for HDaudio */ |
| 67 | .default_fw_path = { | 67 | .default_fw_path = { |
| 68 | [SOF_IPC_TYPE_3] = "intel/sof", | 68 | [SOF_IPC_TYPE_3] = "intel/sof", |
| 69 | [SOF_IPC_TYPE_4] = "intel/avs/tgl-h", | 69 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4/tgl-h", |
| 70 | }, | 70 | }, |
| 71 | .default_lib_path = { | 71 | .default_lib_path = { |
| 72 | [SOF_IPC_TYPE_4] = "intel/avs-lib/tgl-h", | 72 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/tgl-h", |
| 73 | }, | 73 | }, |
| 74 | .default_tplg_path = { | 74 | .default_tplg_path = { |
| 75 | [SOF_IPC_TYPE_3] = "intel/sof-tplg", | 75 | [SOF_IPC_TYPE_3] = "intel/sof-tplg", |
| 76 | [SOF_IPC_TYPE_4] = "intel/avs-tplg", | 76 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg", |
| 77 | }, | 77 | }, |
| 78 | .default_fw_filename = { | 78 | .default_fw_filename = { |
| 79 | [SOF_IPC_TYPE_3] = "sof-tgl-h.ri", | 79 | [SOF_IPC_TYPE_3] = "sof-tgl-h.ri", |
| 80 | [SOF_IPC_TYPE_4] = "dsp_basefw.bin", | 80 | [SOF_IPC_TYPE_4] = "sof-tgl-h.ri", |
| 81 | }, | 81 | }, |
| 82 | .nocodec_tplg_filename = "sof-tgl-nocodec.tplg", | 82 | .nocodec_tplg_filename = "sof-tgl-nocodec.tplg", |
| 83 | .ops = &sof_tgl_ops, | 83 | .ops = &sof_tgl_ops, |
| @@ -98,18 +98,18 @@ static const struct sof_dev_desc ehl_desc = { · 14 unmodified lines | |||
| 98 | .dspless_mode_supported = true, /* Only supported for HDaudio */ | 98 | .dspless_mode_supported = true, /* Only supported for HDaudio */ |
| 99 | .default_fw_path = { | 99 | .default_fw_path = { |
| 100 | [SOF_IPC_TYPE_3] = "intel/sof", | 100 | [SOF_IPC_TYPE_3] = "intel/sof", |
| 101 | [SOF_IPC_TYPE_4] = "intel/avs/ehl", | 101 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4/ehl", |
| 102 | }, | 102 | }, |
| 103 | .default_lib_path = { | 103 | .default_lib_path = { |
| 104 | [SOF_IPC_TYPE_4] = "intel/avs-lib/ehl", | 104 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/ehl", |
| 105 | }, | 105 | }, |
| 106 | .default_tplg_path = { | 106 | .default_tplg_path = { |
| 107 | [SOF_IPC_TYPE_3] = "intel/sof-tplg", | 107 | [SOF_IPC_TYPE_3] = "intel/sof-tplg", |
| 108 | [SOF_IPC_TYPE_4] = "intel/avs-tplg", | 108 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg", |
| 109 | }, | 109 | }, |
| 110 | .default_fw_filename = { | 110 | .default_fw_filename = { |
| 111 | [SOF_IPC_TYPE_3] = "sof-ehl.ri", | 111 | [SOF_IPC_TYPE_3] = "sof-ehl.ri", |
| 112 | [SOF_IPC_TYPE_4] = "dsp_basefw.bin", | 112 | [SOF_IPC_TYPE_4] = "sof-ehl.ri", |
| 113 | }, | 113 | }, |
| 114 | .nocodec_tplg_filename = "sof-ehl-nocodec.tplg", | 114 | .nocodec_tplg_filename = "sof-ehl-nocodec.tplg", |
| 115 | .ops = &sof_tgl_ops, | 115 | .ops = &sof_tgl_ops, |
| @@ -131,18 +131,18 @@ static const struct sof_dev_desc adls_desc = { · 15 unmodified lines | |||
| 131 | .dspless_mode_supported = true, /* Only supported for HDaudio */ | 131 | .dspless_mode_supported = true, /* Only supported for HDaudio */ |
| 132 | .default_fw_path = { | 132 | .default_fw_path = { |
| 133 | [SOF_IPC_TYPE_3] = "intel/sof", | 133 | [SOF_IPC_TYPE_3] = "intel/sof", |
| 134 | [SOF_IPC_TYPE_4] = "intel/avs/adl-s", | 134 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4/adl-s", |
| 135 | }, | 135 | }, |
| 136 | .default_lib_path = { | 136 | .default_lib_path = { |
| 137 | [SOF_IPC_TYPE_4] = "intel/avs-lib/adl-s", | 137 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/adl-s", |
| 138 | }, | 138 | }, |
| 139 | .default_tplg_path = { | 139 | .default_tplg_path = { |
| 140 | [SOF_IPC_TYPE_3] = "intel/sof-tplg", | 140 | [SOF_IPC_TYPE_3] = "intel/sof-tplg", |
| 141 | [SOF_IPC_TYPE_4] = "intel/avs-tplg", | 141 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg", |
| 142 | }, | 142 | }, |
| 143 | .default_fw_filename = { | 143 | .default_fw_filename = { |
| 144 | [SOF_IPC_TYPE_3] = "sof-adl-s.ri", | 144 | [SOF_IPC_TYPE_3] = "sof-adl-s.ri", |
| 145 | [SOF_IPC_TYPE_4] = "dsp_basefw.bin", | 145 | [SOF_IPC_TYPE_4] = "sof-adl-s.ri", |
| 146 | }, | 146 | }, |
| 147 | .nocodec_tplg_filename = "sof-adl-nocodec.tplg", | 147 | .nocodec_tplg_filename = "sof-adl-nocodec.tplg", |
| 148 | .ops = &sof_tgl_ops, | 148 | .ops = &sof_tgl_ops, |
| @@ -164,18 +164,18 @@ static const struct sof_dev_desc adl_desc = { · 15 unmodified lines | |||
| 164 | .dspless_mode_supported = true, /* Only supported for HDaudio */ | 164 | .dspless_mode_supported = true, /* Only supported for HDaudio */ |
| 165 | .default_fw_path = { | 165 | .default_fw_path = { |
| 166 | [SOF_IPC_TYPE_3] = "intel/sof", | 166 | [SOF_IPC_TYPE_3] = "intel/sof", |
| 167 | [SOF_IPC_TYPE_4] = "intel/avs/adl", | 167 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4/adl", |
| 168 | }, | 168 | }, |
| 169 | .default_lib_path = { | 169 | .default_lib_path = { |
| 170 | [SOF_IPC_TYPE_4] = "intel/avs-lib/adl", | 170 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/adl", |
| 171 | }, | 171 | }, |
| 172 | .default_tplg_path = { | 172 | .default_tplg_path = { |
| 173 | [SOF_IPC_TYPE_3] = "intel/sof-tplg", | 173 | [SOF_IPC_TYPE_3] = "intel/sof-tplg", |
| 174 | [SOF_IPC_TYPE_4] = "intel/avs-tplg", | 174 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg", |
| 175 | }, | 175 | }, |
| 176 | .default_fw_filename = { | 176 | .default_fw_filename = { |
| 177 | [SOF_IPC_TYPE_3] = "sof-adl.ri", | 177 | [SOF_IPC_TYPE_3] = "sof-adl.ri", |
| 178 | [SOF_IPC_TYPE_4] = "dsp_basefw.bin", | 178 | [SOF_IPC_TYPE_4] = "sof-adl.ri", |
| 179 | }, | 179 | }, |
| 180 | .nocodec_tplg_filename = "sof-adl-nocodec.tplg", | 180 | .nocodec_tplg_filename = "sof-adl-nocodec.tplg", |
| 181 | .ops = &sof_tgl_ops, | 181 | .ops = &sof_tgl_ops, |
| @@ -197,18 +197,18 @@ static const struct sof_dev_desc adl_n_desc = { · 15 unmodified lines | |||
| 197 | .dspless_mode_supported = true, /* Only supported for HDaudio */ | 197 | .dspless_mode_supported = true, /* Only supported for HDaudio */ |
| 198 | .default_fw_path = { | 198 | .default_fw_path = { |
| 199 | [SOF_IPC_TYPE_3] = "intel/sof", | 199 | [SOF_IPC_TYPE_3] = "intel/sof", |
| 200 | [SOF_IPC_TYPE_4] = "intel/avs/adl-n", | 200 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4/adl-n", |
| 201 | }, | 201 | }, |
| 202 | .default_lib_path = { | 202 | .default_lib_path = { |
| 203 | [SOF_IPC_TYPE_4] = "intel/avs-lib/adl-n", | 203 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/adl-n", |
| 204 | }, | 204 | }, |
| 205 | .default_tplg_path = { | 205 | .default_tplg_path = { |
| 206 | [SOF_IPC_TYPE_3] = "intel/sof-tplg", | 206 | [SOF_IPC_TYPE_3] = "intel/sof-tplg", |
| 207 | [SOF_IPC_TYPE_4] = "intel/avs-tplg", | 207 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg", |
| 208 | }, | 208 | }, |
| 209 | .default_fw_filename = { | 209 | .default_fw_filename = { |
| 210 | [SOF_IPC_TYPE_3] = "sof-adl-n.ri", | 210 | [SOF_IPC_TYPE_3] = "sof-adl-n.ri", |
| 211 | [SOF_IPC_TYPE_4] = "dsp_basefw.bin", | 211 | [SOF_IPC_TYPE_4] = "sof-adl-n.ri", |
| 212 | }, | 212 | }, |
| 213 | .nocodec_tplg_filename = "sof-adl-nocodec.tplg", | 213 | .nocodec_tplg_filename = "sof-adl-nocodec.tplg", |
| 214 | .ops = &sof_tgl_ops, | 214 | .ops = &sof_tgl_ops, |
| @@ -230,18 +230,18 @@ static const struct sof_dev_desc rpls_desc = { · 15 unmodified lines | |||
| 230 | .dspless_mode_supported = true, /* Only supported for HDaudio */ | 230 | .dspless_mode_supported = true, /* Only supported for HDaudio */ |
| 231 | .default_fw_path = { | 231 | .default_fw_path = { |
| 232 | [SOF_IPC_TYPE_3] = "intel/sof", | 232 | [SOF_IPC_TYPE_3] = "intel/sof", |
| 233 | [SOF_IPC_TYPE_4] = "intel/avs/rpl-s", | 233 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4/rpl-s", |
| 234 | }, | 234 | }, |
| 235 | .default_lib_path = { | 235 | .default_lib_path = { |
| 236 | [SOF_IPC_TYPE_4] = "intel/avs-lib/rpl-s", | 236 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/rpl-s", |
| 237 | }, | 237 | }, |
| 238 | .default_tplg_path = { | 238 | .default_tplg_path = { |
| 239 | [SOF_IPC_TYPE_3] = "intel/sof-tplg", | 239 | [SOF_IPC_TYPE_3] = "intel/sof-tplg", |
| 240 | [SOF_IPC_TYPE_4] = "intel/avs-tplg", | 240 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg", |
| 241 | }, | 241 | }, |
| 242 | .default_fw_filename = { | 242 | .default_fw_filename = { |
| 243 | [SOF_IPC_TYPE_3] = "sof-rpl-s.ri", | 243 | [SOF_IPC_TYPE_3] = "sof-rpl-s.ri", |
| 244 | [SOF_IPC_TYPE_4] = "dsp_basefw.bin", | 244 | [SOF_IPC_TYPE_4] = "sof-rpl-s.ri", |
| 245 | }, | 245 | }, |
| 246 | .nocodec_tplg_filename = "sof-rpl-nocodec.tplg", | 246 | .nocodec_tplg_filename = "sof-rpl-nocodec.tplg", |
| 247 | .ops = &sof_tgl_ops, | 247 | .ops = &sof_tgl_ops, |
| @@ -263,18 +263,18 @@ static const struct sof_dev_desc rpl_desc = { · 15 unmodified lines | |||
| 263 | .dspless_mode_supported = true, /* Only supported for HDaudio */ | 263 | .dspless_mode_supported = true, /* Only supported for HDaudio */ |
| 264 | .default_fw_path = { | 264 | .default_fw_path = { |
| 265 | [SOF_IPC_TYPE_3] = "intel/sof", | 265 | [SOF_IPC_TYPE_3] = "intel/sof", |
| 266 | [SOF_IPC_TYPE_4] = "intel/avs/rpl", | 266 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4/rpl", |
| 267 | }, | 267 | }, |
| 268 | .default_lib_path = { | 268 | .default_lib_path = { |
| 269 | [SOF_IPC_TYPE_4] = "intel/avs-lib/rpl", | 269 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/rpl", |
| 270 | }, | 270 | }, |
| 271 | .default_tplg_path = { | 271 | .default_tplg_path = { |
| 272 | [SOF_IPC_TYPE_3] = "intel/sof-tplg", | 272 | [SOF_IPC_TYPE_3] = "intel/sof-tplg", |
| 273 | [SOF_IPC_TYPE_4] = "intel/avs-tplg", | 273 | [SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg", |
| 274 | }, | 274 | }, |
| 275 | .default_fw_filename = { | 275 | .default_fw_filename = { |
| 276 | [SOF_IPC_TYPE_3] = "sof-rpl.ri", | 276 | [SOF_IPC_TYPE_3] = "sof-rpl.ri", |
| 277 | [SOF_IPC_TYPE_4] = "dsp_basefw.bin", | 277 | [SOF_IPC_TYPE_4] = "sof-rpl.ri", |
| 278 | }, | 278 | }, |
| 279 | .nocodec_tplg_filename = "sof-rpl-nocodec.tplg", | 279 | .nocodec_tplg_filename = "sof-rpl-nocodec.tplg", |
| 280 | .ops = &sof_tgl_ops, | 280 | .ops = &sof_tgl_ops, |
| @@ -2360,27 +2360,16 @@ static int sof_tear_down_left_over_pipelines(struct snd_sof_dev *sdev) · 2359 unmodified lines | |||
| 2360 | return 0; | 2360 | return 0; |
| 2361 | } | 2361 | } |
| 2362 | 2362 | ||
| 2363 | /* | 2363 | static int sof_ipc3_free_widgets_in_list(struct snd_sof_dev *sdev, bool include_scheduler, |
| 2364 | * For older firmware, this function doesn't free widgets for static pipelines during suspend. | 2364 | bool *dyn_widgets, bool verify) |
| 2365 | * It only resets use_count for all widgets. | ||
| 2366 | */ | ||
| 2367 | static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verify) | ||
| 2368 | { | 2365 | { |
| 2369 | struct sof_ipc_fw_version *v = &sdev->fw_ready.version; | 2366 | struct sof_ipc_fw_version *v = &sdev->fw_ready.version; |
| 2370 | struct snd_sof_widget *swidget; | 2367 | struct snd_sof_widget *swidget; |
| 2371 | struct snd_sof_route *sroute; | ||
| 2372 | bool dyn_widgets = false; | ||
| 2373 | int ret; | 2368 | int ret; |
| 2374 | 2369 | ||
| 2375 | /* | ||
| 2376 | * This function is called during suspend and for one-time topology verification during | ||
| 2377 | * first boot. In both cases, there is no need to protect swidget->use_count and | ||
| 2378 | * sroute->setup because during suspend all running streams are suspended and during | ||
| 2379 | * topology loading the sound card unavailable to open PCMs. | ||
| 2380 | */ | ||
| 2381 | list_for_each_entry(swidget, &sdev->widget_list, list) { | 2370 | list_for_each_entry(swidget, &sdev->widget_list, list) { |
| 2382 | if (swidget->dynamic_pipeline_widget) { | 2371 | if (swidget->dynamic_pipeline_widget) { |
| 2383 | dyn_widgets = true; | 2372 | *dyn_widgets = true; |
| 2384 | continue; | 2373 | continue; |
| 2385 | } | 2374 | } |
| 2386 | 2375 | ||
| @@ -2395,11 +2384,49 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif · 8 unmodified lines | |||
| 2395 | continue; | 2384 | continue; |
| 2396 | } | 2385 | } |
| 2397 | 2386 | ||
| 2387 | if (include_scheduler && swidget->id != snd_soc_dapm_scheduler) | ||
| 2388 | continue; | ||
| 2389 | |||
| 2390 | if (!include_scheduler && swidget->id == snd_soc_dapm_scheduler) | ||
| 2391 | continue; | ||
| 2392 | |||
| 2398 | ret = sof_widget_free(sdev, swidget); | 2393 | ret = sof_widget_free(sdev, swidget); |
| 2399 | if (ret < 0) | 2394 | if (ret < 0) |
| 2400 | return ret; | 2395 | return ret; |
| 2401 | } | 2396 | } |
| 2402 | 2397 | ||
| 2398 | return 0; | ||
| 2399 | } | ||
| 2400 | |||
| 2401 | /* | ||
| 2402 | * For older firmware, this function doesn't free widgets for static pipelines during suspend. | ||
| 2403 | * It only resets use_count for all widgets. | ||
| 2404 | */ | ||
| 2405 | static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verify) | ||
| 2406 | { | ||
| 2407 | struct sof_ipc_fw_version *v = &sdev->fw_ready.version; | ||
| 2408 | struct snd_sof_widget *swidget; | ||
| 2409 | struct snd_sof_route *sroute; | ||
| 2410 | bool dyn_widgets = false; | ||
| 2411 | int ret; | ||
| 2412 | |||
| 2413 | /* | ||
| 2414 | * This function is called during suspend and for one-time topology verification during | ||
| 2415 | * first boot. In both cases, there is no need to protect swidget->use_count and | ||
| 2416 | * sroute->setup because during suspend all running streams are suspended and during | ||
| 2417 | * topology loading the sound card unavailable to open PCMs. Do not free the scheduler | ||
| 2418 | * widgets yet so that the secondary cores do not get powered down before all the widgets | ||
| 2419 | * associated with the scheduler are freed. | ||
| 2420 | */ | ||
| 2421 | ret = sof_ipc3_free_widgets_in_list(sdev, false, &dyn_widgets, verify); | ||
| 2422 | if (ret < 0) | ||
| 2423 | return ret; | ||
| 2424 | |||
| 2425 | /* free all the scheduler widgets now */ | ||
| 2426 | ret = sof_ipc3_free_widgets_in_list(sdev, true, &dyn_widgets, verify); | ||
| 2427 | if (ret < 0) | ||
| 2428 | return ret; | ||
| 2429 | |||
| 2403 | /* | 2430 | /* |
| 2404 | * Tear down all pipelines associated with PCMs that did not get suspended | 2431 | * Tear down all pipelines associated with PCMs that did not get suspended |
| 2405 | * and unset the prepare flag so that they can be set up again during resume. | 2432 | * and unset the prepare flag so that they can be set up again during resume. |
| @@ -1067,7 +1067,7 @@ static void sof_ipc3_rx_msg(struct snd_sof_dev *sdev) · 1066 unmodified lines | |||
| 1067 | return; | 1067 | return; |
| 1068 | } | 1068 | } |
| 1069 | 1069 | ||
| 1070 | if (hdr.size < sizeof(hdr)) { | 1070 | if (hdr.size < sizeof(hdr) || hdr.size > SOF_IPC_MSG_MAX_SIZE) { |
| 1071 | dev_err(sdev->dev, "The received message size is invalid\n"); | 1071 | dev_err(sdev->dev, "The received message size is invalid\n"); |
| 1072 | return; | 1072 | return; |
| 1073 | } | 1073 | } |
| @@ -413,7 +413,18 @@ skip_pause_transition: · 412 unmodified lines | |||
| 413 | ret = sof_ipc4_set_multi_pipeline_state(sdev, state, trigger_list); | 413 | ret = sof_ipc4_set_multi_pipeline_state(sdev, state, trigger_list); |
| 414 | if (ret < 0) { | 414 | if (ret < 0) { |
| 415 | dev_err(sdev->dev, "failed to set final state %d for all pipelines\n", state); | 415 | dev_err(sdev->dev, "failed to set final state %d for all pipelines\n", state); |
| 416 | goto free; | 416 | /* |
| 417 | * workaround: if the firmware is crashed while setting the | ||
| 418 | * pipelines to reset state we must ignore the error code and | ||
| 419 | * reset it to 0. | ||
| 420 | * Since the firmware is crashed we will not send IPC messages | ||
| 421 | * and we are going to see errors printed, but the state of the | ||
| 422 | * widgets will be correct for the next boot. | ||
| 423 | */ | ||
| 424 | if (sdev->fw_state != SOF_FW_CRASHED || state != SOF_IPC4_PIPE_RESET) | ||
| 425 | goto free; | ||
| 426 | |||
| 427 | ret = 0; | ||
| 417 | } | 428 | } |
| 418 | 429 | ||
| 419 | /* update RUNNING/RESET state for all pipelines that were just triggered */ | 430 | /* 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, · 1741 unmodified lines | |||
| 1742 | } | 1742 | } |
| 1743 | } | 1743 | } |
| 1744 | 1744 | ||
| 1745 | static struct usb_midi_in_jack_descriptor *find_usb_in_jack_descriptor( | 1745 | /* return iJack for the corresponding jackID */ |
| 1746 | struct usb_host_interface *hostif, uint8_t jack_id) | 1746 | static int find_usb_ijack(struct usb_host_interface *hostif, uint8_t jack_id) |
| 1747 | { | 1747 | { |
| 1748 | unsigned char *extra = hostif->extra; | 1748 | unsigned char *extra = hostif->extra; |
| 1749 | int extralen = hostif->extralen; | 1749 | int extralen = hostif->extralen; |
| 1750 | struct usb_descriptor_header *h; | ||
| 1751 | struct usb_midi_out_jack_descriptor *outjd; | ||
| 1752 | struct usb_midi_in_jack_descriptor *injd; | ||
| 1753 | size_t sz; | ||
| 1750 | 1754 | ||
| 1751 | while (extralen > 4) { | 1755 | while (extralen > 4) { |
| 1752 | struct usb_midi_in_jack_descriptor *injd = | 1756 | h = (struct usb_descriptor_header *)extra; |
| 1753 | (struct usb_midi_in_jack_descriptor *)extra; | 1757 | if (h->bDescriptorType != USB_DT_CS_INTERFACE) |
| 1758 | goto next; | ||
| 1754 | 1759 | ||
| 1760 | outjd = (struct usb_midi_out_jack_descriptor *)h; | ||
| 1761 | if (h->bLength >= sizeof(*outjd) && | ||
| 1762 | outjd->bDescriptorSubtype == UAC_MIDI_OUT_JACK && | ||
| 1763 | outjd->bJackID == jack_id) { | ||
| 1764 | sz = USB_DT_MIDI_OUT_SIZE(outjd->bNrInputPins); | ||
| 1765 | if (outjd->bLength < sz) | ||
| 1766 | goto next; | ||
| 1767 | return *(extra + sz - 1); | ||
| 1768 | } | ||
| 1769 | |||
| 1770 | injd = (struct usb_midi_in_jack_descriptor *)h; | ||
| 1755 | if (injd->bLength >= sizeof(*injd) && | 1771 | if (injd->bLength >= sizeof(*injd) && |
| 1756 | injd->bDescriptorType == USB_DT_CS_INTERFACE && | ||
| 1757 | injd->bDescriptorSubtype == UAC_MIDI_IN_JACK && | 1772 | injd->bDescriptorSubtype == UAC_MIDI_IN_JACK && |
| 1758 | injd->bJackID == jack_id) | 1773 | injd->bJackID == jack_id) |
| 1759 | return injd; | 1774 | return injd->iJack; |
| 1760 | if (!extra[0]) | ||
| 1761 | break; | ||
| 1762 | extralen -= extra[0]; | ||
| 1763 | extra += extra[0]; | ||
| 1764 | } | ||
| 1765 | return NULL; | ||
| 1766 | } | ||
| 1767 | |||
| 1768 | static struct usb_midi_out_jack_descriptor *find_usb_out_jack_descriptor( | ||
| 1769 | struct usb_host_interface *hostif, uint8_t jack_id) | ||
| 1770 | { | ||
| 1771 | unsigned char *extra = hostif->extra; | ||
| 1772 | int extralen = hostif->extralen; | ||
| 1773 | 1775 | ||
| 1774 | while (extralen > 4) { | 1776 | next: |
| 1775 | struct usb_midi_out_jack_descriptor *outjd = | ||
| 1776 | (struct usb_midi_out_jack_descriptor *)extra; | ||
| 1777 | |||
| 1778 | if (outjd->bLength >= sizeof(*outjd) && | ||
| 1779 | outjd->bDescriptorType == USB_DT_CS_INTERFACE && | ||
| 1780 | outjd->bDescriptorSubtype == UAC_MIDI_OUT_JACK && | ||
| 1781 | outjd->bJackID == jack_id) | ||
| 1782 | return outjd; | ||
| 1783 | if (!extra[0]) | 1777 | if (!extra[0]) |
| 1784 | break; | 1778 | break; |
| 1785 | extralen -= extra[0]; | 1779 | extralen -= extra[0]; |
| 1786 | extra += extra[0]; | 1780 | extra += extra[0]; |
| 1787 | } | 1781 | } |
| 1788 | return NULL; | 1782 | return 0; |
| 1789 | } | 1783 | } |
| 1790 | 1784 | ||
| 1791 | static void snd_usbmidi_init_substream(struct snd_usb_midi *umidi, | 1785 | 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, · 4 unmodified lines | |||
| 1796 | const char *name_format; | 1790 | const char *name_format; |
| 1797 | struct usb_interface *intf; | 1791 | struct usb_interface *intf; |
| 1798 | struct usb_host_interface *hostif; | 1792 | struct usb_host_interface *hostif; |
| 1799 | struct usb_midi_in_jack_descriptor *injd; | ||
| 1800 | struct usb_midi_out_jack_descriptor *outjd; | ||
| 1801 | uint8_t jack_name_buf[32]; | 1793 | uint8_t jack_name_buf[32]; |
| 1802 | uint8_t *default_jack_name = "MIDI"; | 1794 | uint8_t *default_jack_name = "MIDI"; |
| 1803 | uint8_t *jack_name = default_jack_name; | 1795 | uint8_t *jack_name = default_jack_name; |
| 1804 | uint8_t iJack; | 1796 | uint8_t iJack; |
| 1805 | size_t sz; | ||
| 1806 | int res; | 1797 | int res; |
| 1807 | 1798 | ||
| 1808 | struct snd_rawmidi_substream *substream = | 1799 | struct snd_rawmidi_substream *substream = |
| @@ -1816,21 +1807,7 @@ static void snd_usbmidi_init_substream(struct snd_usb_midi *umidi, · 7 unmodified lines | |||
| 1816 | intf = umidi->iface; | 1807 | intf = umidi->iface; |
| 1817 | if (intf && jack_id >= 0) { | 1808 | if (intf && jack_id >= 0) { |
| 1818 | hostif = intf->cur_altsetting; | 1809 | hostif = intf->cur_altsetting; |
| 1819 | iJack = 0; | 1810 | iJack = find_usb_ijack(hostif, jack_id); |
| 1820 | if (stream != SNDRV_RAWMIDI_STREAM_OUTPUT) { | ||
| 1821 | /* in jacks connect to outs */ | ||
| 1822 | outjd = find_usb_out_jack_descriptor(hostif, jack_id); | ||
| 1823 | if (outjd) { | ||
| 1824 | sz = USB_DT_MIDI_OUT_SIZE(outjd->bNrInputPins); | ||
| 1825 | if (outjd->bLength >= sz) | ||
| 1826 | iJack = *(((uint8_t *) outjd) + sz - sizeof(uint8_t)); | ||
| 1827 | } | ||
| 1828 | } else { | ||
| 1829 | /* and out jacks connect to ins */ | ||
| 1830 | injd = find_usb_in_jack_descriptor(hostif, jack_id); | ||
| 1831 | if (injd) | ||
| 1832 | iJack = injd->iJack; | ||
| 1833 | } | ||
| 1834 | if (iJack != 0) { | 1811 | if (iJack != 0) { |
| 1835 | res = usb_string(umidi->dev, iJack, jack_name_buf, | 1812 | res = usb_string(umidi->dev, iJack, jack_name_buf, |
| 1836 | ARRAY_SIZE(jack_name_buf)); | 1813 | ARRAY_SIZE(jack_name_buf)); |