diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-12-06 11:46:39 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-12-06 11:46:39 -0800 |
commit | 2b90dcd599b62ccaaa367947037235de8e6bc3a7 (patch) | |
tree | fb0e33b9b3ac46ad3efb04bd23c1b7175634c711 | |
parent | d9e15b25161e0783def5f852179db38d817c957c (diff) | |
parent | c34e9ab9a612ee8b18273398ef75c207b01f516d (diff) |
Merge tag 'sound-6.13-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai:
"A collection of small fixes that have been gathered in the week.
- Fix the missing XRUN handling in USB-audio low latency mode
- Fix regression by the previous USB-audio hadening change
- Clean up old SH sound driver to use the standard helpers
- A few further fixes for MIDI 2.0 UMP handling
- Various HD-audio and USB-audio quirks
- Fix jack handling at PM on ASoC Intel AVS
- Misc small fixes for ASoC SOF and Mediatek"
* tag 'sound-6.13-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
ALSA: hda/realtek: Fix spelling mistake "Firelfy" -> "Firefly"
ASoC: mediatek: mt8188-mt6359: Remove hardcoded dmic codec
ALSA: hda/realtek: fix micmute LEDs don't work on HP Laptops
ALSA: usb-audio: Add extra PID for RME Digiface USB
ALSA: usb-audio: Fix a DMA to stack memory bug
ASoC: SOF: ipc3-topology: fix resource leaks in sof_ipc3_widget_setup_comp_dai()
ALSA: hda/realtek: Add support for Samsung Galaxy Book3 360 (NP730QFG)
ASoC: Intel: avs: da7219: Remove suspend_pre() and resume_post()
ALSA: hda/tas2781: Fix error code tas2781_read_acpi()
ALSA: hda/realtek: Enable mute and micmute LED on HP ProBook 430 G8
ALSA: usb-audio: add mixer mapping for Corsair HS80
ALSA: ump: Shut up truncated string warning
ALSA: sh: Use standard helper for buffer accesses
ALSA: usb-audio: Notify xrun for low-latency mode
ALSA: hda/conexant: fix Z60MR100 startup pop issue
ALSA: ump: Update legacy substream names upon FB info update
ALSA: ump: Indicate the inactive group in legacy substream names
ALSA: ump: Don't open legacy substream for an inactive group
ALSA: seq: ump: Fix seq port updates per FB info notify
-rw-r--r-- | sound/core/seq/seq_ump_client.c | 6 | ||||
-rw-r--r-- | sound/core/ump.c | 26 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 28 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 8 | ||||
-rw-r--r-- | sound/pci/hda/tas2781_hda_i2c.c | 1 | ||||
-rw-r--r-- | sound/sh/sh_dac_audio.c | 5 | ||||
-rw-r--r-- | sound/soc/intel/avs/boards/da7219.c | 17 | ||||
-rw-r--r-- | sound/soc/mediatek/mt8188/mt8188-mt6359.c | 4 | ||||
-rw-r--r-- | sound/soc/sof/ipc3-topology.c | 7 | ||||
-rw-r--r-- | sound/usb/endpoint.c | 14 | ||||
-rw-r--r-- | sound/usb/mixer_maps.c | 10 | ||||
-rw-r--r-- | sound/usb/mixer_quirks.c | 1 | ||||
-rw-r--r-- | sound/usb/quirks-table.h | 341 | ||||
-rw-r--r-- | sound/usb/quirks.c | 44 |
14 files changed, 291 insertions, 221 deletions
diff --git a/sound/core/seq/seq_ump_client.c b/sound/core/seq/seq_ump_client.c index e5d3f4d206bf..e956f17f3792 100644 --- a/sound/core/seq/seq_ump_client.c +++ b/sound/core/seq/seq_ump_client.c @@ -257,12 +257,12 @@ static void update_port_infos(struct seq_ump_client *client) continue; old->addr.client = client->seq_client; - old->addr.port = i; + old->addr.port = ump_group_to_seq_port(i); err = snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_GET_PORT_INFO, old); if (err < 0) - return; + continue; fill_port_info(new, client, &client->ump->groups[i]); if (old->capability == new->capability && !strcmp(old->name, new->name)) @@ -271,7 +271,7 @@ static void update_port_infos(struct seq_ump_client *client) SNDRV_SEQ_IOCTL_SET_PORT_INFO, new); if (err < 0) - return; + continue; /* notify to system port */ snd_seq_system_client_ev_port_change(client->seq_client, i); } diff --git a/sound/core/ump.c b/sound/core/ump.c index 6d0aac6c763f..fe4d39ae1159 100644 --- a/sound/core/ump.c +++ b/sound/core/ump.c @@ -37,6 +37,7 @@ static int process_legacy_output(struct snd_ump_endpoint *ump, u32 *buffer, int count); static void process_legacy_input(struct snd_ump_endpoint *ump, const u32 *src, int words); +static void update_legacy_names(struct snd_ump_endpoint *ump); #else static inline int process_legacy_output(struct snd_ump_endpoint *ump, u32 *buffer, int count) @@ -47,6 +48,9 @@ static inline void process_legacy_input(struct snd_ump_endpoint *ump, const u32 *src, int words) { } +static inline void update_legacy_names(struct snd_ump_endpoint *ump) +{ +} #endif static const struct snd_rawmidi_global_ops snd_ump_rawmidi_ops = { @@ -861,6 +865,7 @@ static int ump_handle_fb_info_msg(struct snd_ump_endpoint *ump, fill_fb_info(ump, &fb->info, buf); if (ump->parsed) { snd_ump_update_group_attrs(ump); + update_legacy_names(ump); seq_notify_fb_change(ump, fb); } } @@ -893,6 +898,7 @@ static int ump_handle_fb_name_msg(struct snd_ump_endpoint *ump, /* notify the FB name update to sequencer, too */ if (ret > 0 && ump->parsed) { snd_ump_update_group_attrs(ump); + update_legacy_names(ump); seq_notify_fb_change(ump, fb); } return ret; @@ -1087,6 +1093,8 @@ static int snd_ump_legacy_open(struct snd_rawmidi_substream *substream) guard(mutex)(&ump->open_mutex); if (ump->legacy_substreams[dir][group]) return -EBUSY; + if (!ump->groups[group].active) + return -ENODEV; if (dir == SNDRV_RAWMIDI_STREAM_OUTPUT) { if (!ump->legacy_out_opens) { err = snd_rawmidi_kernel_open(&ump->core, 0, @@ -1254,11 +1262,20 @@ static void fill_substream_names(struct snd_ump_endpoint *ump, name = ump->groups[idx].name; if (!*name) name = ump->info.name; - snprintf(s->name, sizeof(s->name), "Group %d (%.16s)", - idx + 1, name); + scnprintf(s->name, sizeof(s->name), "Group %d (%.16s)%s", + idx + 1, name, + ump->groups[idx].active ? "" : " [Inactive]"); } } +static void update_legacy_names(struct snd_ump_endpoint *ump) +{ + struct snd_rawmidi *rmidi = ump->legacy_rmidi; + + fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_INPUT); + fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT); +} + int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump, char *id, int device) { @@ -1295,10 +1312,7 @@ int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump, rmidi->ops = &snd_ump_legacy_ops; rmidi->private_data = ump; ump->legacy_rmidi = rmidi; - if (input) - fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_INPUT); - if (output) - fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT); + update_legacy_names(ump); ump_dbg(ump, "Created a legacy rawmidi #%d (%s)\n", device, id); return 0; diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 2e9f817b948e..538c37a78a56 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -307,6 +307,7 @@ enum { CXT_FIXUP_HP_MIC_NO_PRESENCE, CXT_PINCFG_SWS_JS201D, CXT_PINCFG_TOP_SPEAKER, + CXT_FIXUP_HP_A_U, }; /* for hda_fixup_thinkpad_acpi() */ @@ -774,6 +775,18 @@ static void cxt_setup_mute_led(struct hda_codec *codec, } } +static void cxt_setup_gpio_unmute(struct hda_codec *codec, + unsigned int gpio_mute_mask) +{ + if (gpio_mute_mask) { + // set gpio data to 0. + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, gpio_mute_mask); + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION, gpio_mute_mask); + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_STICKY_MASK, 0); + } +} + static void cxt_fixup_mute_led_gpio(struct hda_codec *codec, const struct hda_fixup *fix, int action) { @@ -788,6 +801,15 @@ static void cxt_fixup_hp_zbook_mute_led(struct hda_codec *codec, cxt_setup_mute_led(codec, 0x10, 0x20); } +static void cxt_fixup_hp_a_u(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + // Init vers in BIOS mute the spk/hp by set gpio high to avoid pop noise, + // so need to unmute once by clearing the gpio data when runs into the system. + if (action == HDA_FIXUP_ACT_INIT) + cxt_setup_gpio_unmute(codec, 0x2); +} + /* ThinkPad X200 & co with cxt5051 */ static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = { { 0x16, 0x042140ff }, /* HP (seq# overridden) */ @@ -998,6 +1020,10 @@ static const struct hda_fixup cxt_fixups[] = { { } }, }, + [CXT_FIXUP_HP_A_U] = { + .type = HDA_FIXUP_FUNC, + .v.func = cxt_fixup_hp_a_u, + }, }; static const struct hda_quirk cxt5045_fixups[] = { @@ -1072,6 +1098,7 @@ static const struct hda_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, 0x0252, "MBX-Z60MR100", CXT_FIXUP_HP_A_U), 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), @@ -1117,6 +1144,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = { { .id = CXT_PINCFG_LENOVO_NOTEBOOK, .name = "lenovo-20149" }, { .id = CXT_PINCFG_SWS_JS201D, .name = "sws-js201d" }, { .id = CXT_PINCFG_TOP_SPEAKER, .name = "sirius-top-speaker" }, + { .id = CXT_FIXUP_HP_A_U, .name = "HP-U-support" }, {} }; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4ba9e647250b..17392b21d5bf 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10340,6 +10340,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x87b7, "HP Laptop 14-fq0xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), SND_PCI_QUIRK(0x103c, 0x87c8, "HP", ALC287_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x87d3, "HP Laptop 15-gw0xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x87df, "HP ProBook 430 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x87e5, "HP ProBook 440 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x87e7, "HP ProBook 450 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x87f1, "HP ProBook 630 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), @@ -10521,7 +10522,13 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8cdf, "HP SnowWhite", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8ce0, "HP SnowWhite", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8cf5, "HP ZBook Studio 16", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8d01, "HP ZBook Power 14 G12", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8d84, "HP EliteBook X G1i", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8d91, "HP ZBook Firefly 14 G12", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8d92, "HP ZBook Firefly 16 G12", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8e18, "HP ZBook Firefly 14 G12A", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8e19, "HP ZBook Firefly 14 G12A", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8e1a, "HP ZBook Firefly 14 G12A", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), @@ -10676,6 +10683,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x144d, 0xc830, "Samsung Galaxy Book Ion (NT950XCJ-X716A)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc832, "Samsung Galaxy Book Flex Alpha (NP730QCJ)", ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), SND_PCI_QUIRK(0x144d, 0xca03, "Samsung Galaxy Book2 Pro 360 (NP930QED)", ALC298_FIXUP_SAMSUNG_AMP), + SND_PCI_QUIRK(0x144d, 0xca06, "Samsung Galaxy Book3 360 (NP730QFG)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), SND_PCI_QUIRK(0x144d, 0xc868, "Samsung Galaxy Book2 Pro (NP930XED)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc870, "Samsung Galaxy Book2 Pro (NP950XED)", ALC298_FIXUP_SAMSUNG_AMP_V2_2_AMPS), SND_PCI_QUIRK(0x144d, 0xc872, "Samsung Galaxy Book2 Pro (NP950XEE)", ALC298_FIXUP_SAMSUNG_AMP_V2_2_AMPS), diff --git a/sound/pci/hda/tas2781_hda_i2c.c b/sound/pci/hda/tas2781_hda_i2c.c index db05659c0af8..0af015806aba 100644 --- a/sound/pci/hda/tas2781_hda_i2c.c +++ b/sound/pci/hda/tas2781_hda_i2c.c @@ -143,6 +143,7 @@ static int tas2781_read_acpi(struct tasdevice_priv *p, const char *hid) sub = acpi_get_subsystem_id(ACPI_HANDLE(physdev)); if (IS_ERR(sub)) { dev_err(p->dev, "Failed to get SUBSYS ID.\n"); + ret = PTR_ERR(sub); goto err; } /* Speaker id was needed for ASUS projects. */ diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c index e7b80328f0ef..a4d07438ad64 100644 --- a/sound/sh/sh_dac_audio.c +++ b/sound/sh/sh_dac_audio.c @@ -163,7 +163,7 @@ static int snd_sh_dac_pcm_copy(struct snd_pcm_substream *substream, /* channel is not used (interleaved data) */ struct snd_sh_dac *chip = snd_pcm_substream_chip(substream); - if (copy_from_iter_toio(chip->data_buffer + pos, src, count)) + if (copy_from_iter(chip->data_buffer + pos, src, count) != count) return -EFAULT; chip->buffer_end = chip->data_buffer + pos + count; @@ -182,7 +182,7 @@ static int snd_sh_dac_pcm_silence(struct snd_pcm_substream *substream, /* channel is not used (interleaved data) */ struct snd_sh_dac *chip = snd_pcm_substream_chip(substream); - memset_io(chip->data_buffer + pos, 0, count); + memset(chip->data_buffer + pos, 0, count); chip->buffer_end = chip->data_buffer + pos + count; if (chip->empty) { @@ -211,7 +211,6 @@ static const struct snd_pcm_ops snd_sh_dac_pcm_ops = { .pointer = snd_sh_dac_pcm_pointer, .copy = snd_sh_dac_pcm_copy, .fill_silence = snd_sh_dac_pcm_silence, - .mmap = snd_pcm_lib_mmap_iomem, }; static int snd_sh_dac_pcm(struct snd_sh_dac *chip, int device) diff --git a/sound/soc/intel/avs/boards/da7219.c b/sound/soc/intel/avs/boards/da7219.c index 93eba4fd2771..76078a7005b0 100644 --- a/sound/soc/intel/avs/boards/da7219.c +++ b/sound/soc/intel/avs/boards/da7219.c @@ -209,21 +209,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in return 0; } -static int avs_card_suspend_pre(struct snd_soc_card *card) -{ - struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, DA7219_DAI_NAME); - - return snd_soc_component_set_jack(codec_dai->component, NULL, NULL); -} - -static int avs_card_resume_post(struct snd_soc_card *card) -{ - struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, DA7219_DAI_NAME); - struct snd_soc_jack *jack = snd_soc_card_get_drvdata(card); - - return snd_soc_component_set_jack(codec_dai->component, jack, NULL); -} - static int avs_da7219_probe(struct platform_device *pdev) { struct snd_soc_dai_link *dai_link; @@ -255,8 +240,6 @@ static int avs_da7219_probe(struct platform_device *pdev) card->name = "avs_da7219"; card->dev = dev; card->owner = THIS_MODULE; - card->suspend_pre = avs_card_suspend_pre; - card->resume_post = avs_card_resume_post; card->dai_link = dai_link; card->num_links = 1; card->controls = card_controls; diff --git a/sound/soc/mediatek/mt8188/mt8188-mt6359.c b/sound/soc/mediatek/mt8188/mt8188-mt6359.c index e04b88a57535..2d0d04e0232d 100644 --- a/sound/soc/mediatek/mt8188/mt8188-mt6359.c +++ b/sound/soc/mediatek/mt8188/mt8188-mt6359.c @@ -188,9 +188,7 @@ SND_SOC_DAILINK_DEFS(pcm1, SND_SOC_DAILINK_DEFS(ul_src, DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC")), DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound", - "mt6359-snd-codec-aif1"), - COMP_CODEC("dmic-codec", - "dmic-hifi")), + "mt6359-snd-codec-aif1")), DAILINK_COMP_ARRAY(COMP_EMPTY())); SND_SOC_DAILINK_DEFS(AFE_SOF_DL2, diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index c2fce554a674..e98b53b67d12 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -1588,14 +1588,14 @@ static int sof_ipc3_widget_setup_comp_dai(struct snd_sof_widget *swidget) ret = sof_update_ipc_object(scomp, comp_dai, SOF_DAI_TOKENS, swidget->tuples, swidget->num_tuples, sizeof(*comp_dai), 1); if (ret < 0) - goto free; + goto free_comp; /* update comp_tokens */ ret = sof_update_ipc_object(scomp, &comp_dai->config, SOF_COMP_TOKENS, swidget->tuples, swidget->num_tuples, sizeof(comp_dai->config), 1); if (ret < 0) - goto free; + goto free_comp; /* Subtract the base to match the FW dai index. */ if (comp_dai->type == SOF_DAI_INTEL_ALH) { @@ -1603,7 +1603,8 @@ static int sof_ipc3_widget_setup_comp_dai(struct snd_sof_widget *swidget) dev_err(sdev->dev, "Invalid ALH dai index %d, only Pin numbers >= %d can be used\n", comp_dai->dai_index, INTEL_ALH_DAI_INDEX_BASE); - return -EINVAL; + ret = -EINVAL; + goto free_comp; } comp_dai->dai_index -= INTEL_ALH_DAI_INDEX_BASE; } diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 568099467dbb..a29f28eb7d0c 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -403,10 +403,15 @@ static int prepare_inbound_urb(struct snd_usb_endpoint *ep, static void notify_xrun(struct snd_usb_endpoint *ep) { struct snd_usb_substream *data_subs; + struct snd_pcm_substream *psubs; data_subs = READ_ONCE(ep->data_subs); - if (data_subs && data_subs->pcm_substream) - snd_pcm_stop_xrun(data_subs->pcm_substream); + if (!data_subs) + return; + psubs = data_subs->pcm_substream; + if (psubs && psubs->runtime && + psubs->runtime->state == SNDRV_PCM_STATE_RUNNING) + snd_pcm_stop_xrun(psubs); } static struct snd_usb_packet_info * @@ -562,7 +567,10 @@ static void snd_complete_urb(struct urb *urb) push_back_to_ready_list(ep, ctx); clear_bit(ctx->index, &ep->active_mask); snd_usb_queue_pending_output_urbs(ep, false); - atomic_dec(&ep->submitted_urbs); /* decrement at last */ + /* decrement at last, and check xrun */ + if (atomic_dec_and_test(&ep->submitted_urbs) && + !snd_usb_endpoint_implicit_feedback_sink(ep)) + notify_xrun(ep); return; } diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index 23260aa1919d..0e9b5431a47f 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c @@ -621,6 +621,16 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = { .id = USB_ID(0x1b1c, 0x0a42), .map = corsair_virtuoso_map, }, + { + /* Corsair HS80 RGB Wireless (wired mode) */ + .id = USB_ID(0x1b1c, 0x0a6a), + .map = corsair_virtuoso_map, + }, + { + /* Corsair HS80 RGB Wireless (wireless mode) */ + .id = USB_ID(0x1b1c, 0x0a6b), + .map = corsair_virtuoso_map, + }, { /* Gigabyte TRX40 Aorus Master (rear panel + front mic) */ .id = USB_ID(0x0414, 0xa001), .map = aorus_master_alc1220vb_map, diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 8bbf070b3676..23fcd680167d 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -4116,6 +4116,7 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) err = snd_bbfpro_controls_create(mixer); break; case USB_ID(0x2a39, 0x3f8c): /* RME Digiface USB */ + case USB_ID(0x2a39, 0x3fa0): /* RME Digiface USB (alternate) */ err = snd_rme_digiface_controls_create(mixer); break; case USB_ID(0x2b73, 0x0017): /* Pioneer DJ DJM-250MK2 */ diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index c49383e64678..8954be23325c 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -3673,176 +3673,181 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, -{ - /* Only claim interface 0 */ - .match_flags = USB_DEVICE_ID_MATCH_VENDOR | - USB_DEVICE_ID_MATCH_PRODUCT | - USB_DEVICE_ID_MATCH_INT_CLASS | - USB_DEVICE_ID_MATCH_INT_NUMBER, - .idVendor = 0x2a39, - .idProduct = 0x3f8c, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceNumber = 0, - QUIRK_DRIVER_INFO { - QUIRK_DATA_COMPOSITE { +#define QUIRK_RME_DIGIFACE(pid) \ +{ \ + /* Only claim interface 0 */ \ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR | \ + USB_DEVICE_ID_MATCH_PRODUCT | \ + USB_DEVICE_ID_MATCH_INT_CLASS | \ + USB_DEVICE_ID_MATCH_INT_NUMBER, \ + .idVendor = 0x2a39, \ + .idProduct = pid, \ + .bInterfaceClass = USB_CLASS_VENDOR_SPEC, \ + .bInterfaceNumber = 0, \ + QUIRK_DRIVER_INFO { \ + QUIRK_DATA_COMPOSITE { \ /* * Three modes depending on sample rate band, * with different channel counts for in/out - */ - { QUIRK_DATA_STANDARD_MIXER(0) }, - { - QUIRK_DATA_AUDIOFORMAT(0) { - .formats = SNDRV_PCM_FMTBIT_S32_LE, - .channels = 34, // outputs - .fmt_bits = 24, - .iface = 0, - .altsetting = 1, - .altset_idx = 1, - .endpoint = 0x02, - .ep_idx = 1, - .ep_attr = USB_ENDPOINT_XFER_ISOC | - USB_ENDPOINT_SYNC_ASYNC, - .rates = SNDRV_PCM_RATE_32000 | - SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000, - .rate_min = 32000, - .rate_max = 48000, - .nr_rates = 3, - .rate_table = (unsigned int[]) { - 32000, 44100, 48000, - }, - .sync_ep = 0x81, - .sync_iface = 0, - .sync_altsetting = 1, - .sync_ep_idx = 0, - .implicit_fb = 1, - }, - }, - { - QUIRK_DATA_AUDIOFORMAT(0) { - .formats = SNDRV_PCM_FMTBIT_S32_LE, - .channels = 18, // outputs - .fmt_bits = 24, - .iface = 0, - .altsetting = 1, - .altset_idx = 1, - .endpoint = 0x02, - .ep_idx = 1, - .ep_attr = USB_ENDPOINT_XFER_ISOC | - USB_ENDPOINT_SYNC_ASYNC, - .rates = SNDRV_PCM_RATE_64000 | - SNDRV_PCM_RATE_88200 | - SNDRV_PCM_RATE_96000, - .rate_min = 64000, - .rate_max = 96000, - .nr_rates = 3, - .rate_table = (unsigned int[]) { - 64000, 88200, 96000, - }, - .sync_ep = 0x81, - .sync_iface = 0, - .sync_altsetting = 1, - .sync_ep_idx = 0, - .implicit_fb = 1, - }, - }, - { - QUIRK_DATA_AUDIOFORMAT(0) { - .formats = SNDRV_PCM_FMTBIT_S32_LE, - .channels = 10, // outputs - .fmt_bits = 24, - .iface = 0, - .altsetting = 1, - .altset_idx = 1, - .endpoint = 0x02, - .ep_idx = 1, - .ep_attr = USB_ENDPOINT_XFER_ISOC | - USB_ENDPOINT_SYNC_ASYNC, - .rates = SNDRV_PCM_RATE_KNOT | - SNDRV_PCM_RATE_176400 | - SNDRV_PCM_RATE_192000, - .rate_min = 128000, - .rate_max = 192000, - .nr_rates = 3, - .rate_table = (unsigned int[]) { - 128000, 176400, 192000, - }, - .sync_ep = 0x81, - .sync_iface = 0, - .sync_altsetting = 1, - .sync_ep_idx = 0, - .implicit_fb = 1, - }, - }, - { - QUIRK_DATA_AUDIOFORMAT(0) { - .formats = SNDRV_PCM_FMTBIT_S32_LE, - .channels = 32, // inputs - .fmt_bits = 24, - .iface = 0, - .altsetting = 1, - .altset_idx = 1, - .endpoint = 0x81, - .ep_attr = USB_ENDPOINT_XFER_ISOC | - USB_ENDPOINT_SYNC_ASYNC, - .rates = SNDRV_PCM_RATE_32000 | - SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000, - .rate_min = 32000, - .rate_max = 48000, - .nr_rates = 3, - .rate_table = (unsigned int[]) { - 32000, 44100, 48000, - } - } - }, - { - QUIRK_DATA_AUDIOFORMAT(0) { - .formats = SNDRV_PCM_FMTBIT_S32_LE, - .channels = 16, // inputs - .fmt_bits = 24, - .iface = 0, - .altsetting = 1, - .altset_idx = 1, - .endpoint = 0x81, - .ep_attr = USB_ENDPOINT_XFER_ISOC | - USB_ENDPOINT_SYNC_ASYNC, - .rates = SNDRV_PCM_RATE_64000 | - SNDRV_PCM_RATE_88200 | - SNDRV_PCM_RATE_96000, - .rate_min = 64000, - .rate_max = 96000, - .nr_rates = 3, - .rate_table = (unsigned int[]) { - 64000, 88200, 96000, - } - } - }, - { - QUIRK_DATA_AUDIOFORMAT(0) { - .formats = SNDRV_PCM_FMTBIT_S32_LE, - .channels = 8, // inputs - .fmt_bits = 24, - .iface = 0, - .altsetting = 1, - .altset_idx = 1, - .endpoint = 0x81, - .ep_attr = USB_ENDPOINT_XFER_ISOC | - USB_ENDPOINT_SYNC_ASYNC, - .rates = SNDRV_PCM_RATE_KNOT | - SNDRV_PCM_RATE_176400 | - SNDRV_PCM_RATE_192000, - .rate_min = 128000, - .rate_max = 192000, - .nr_rates = 3, - .rate_table = (unsigned int[]) { - 128000, 176400, 192000, - } - } - }, - QUIRK_COMPOSITE_END - } - } -}, + */ \ + { QUIRK_DATA_STANDARD_MIXER(0) }, \ + { \ + QUIRK_DATA_AUDIOFORMAT(0) { \ + .formats = SNDRV_PCM_FMTBIT_S32_LE, \ + .channels = 34, /* outputs */ \ + .fmt_bits = 24, \ + .iface = 0, \ + .altsetting = 1, \ + .altset_idx = 1, \ + .endpoint = 0x02, \ + .ep_idx = 1, \ + .ep_attr = USB_ENDPOINT_XFER_ISOC | \ + USB_ENDPOINT_SYNC_ASYNC, \ + .rates = SNDRV_PCM_RATE_32000 | \ + SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000, \ + .rate_min = 32000, \ + .rate_max = 48000, \ + .nr_rates = 3, \ + .rate_table = (unsigned int[]) { \ + 32000, 44100, 48000, \ + }, \ + .sync_ep = 0x81, \ + .sync_iface = 0, \ + .sync_altsetting = 1, \ + .sync_ep_idx = 0, \ + .implicit_fb = 1, \ + }, \ + }, \ + { \ + QUIRK_DATA_AUDIOFORMAT(0) { \ + .formats = SNDRV_PCM_FMTBIT_S32_LE, \ + .channels = 18, /* outputs */ \ + .fmt_bits = 24, \ + .iface = 0, \ + .altsetting = 1, \ + .altset_idx = 1, \ + .endpoint = 0x02, \ + .ep_idx = 1, \ + .ep_attr = USB_ENDPOINT_XFER_ISOC | \ + USB_ENDPOINT_SYNC_ASYNC, \ + .rates = SNDRV_PCM_RATE_64000 | \ + SNDRV_PCM_RATE_88200 | \ + SNDRV_PCM_RATE_96000, \ + .rate_min = 64000, \ + .rate_max = 96000, \ + .nr_rates = 3, \ + .rate_table = (unsigned int[]) { \ + 64000, 88200, 96000, \ + }, \ + .sync_ep = 0x81, \ + .sync_iface = 0, \ + .sync_altsetting = 1, \ + .sync_ep_idx = 0, \ + .implicit_fb = 1, \ + }, \ + }, \ + { \ + QUIRK_DATA_AUDIOFORMAT(0) { \ + .formats = SNDRV_PCM_FMTBIT_S32_LE, \ + .channels = 10, /* outputs */ \ + .fmt_bits = 24, \ + .iface = 0, \ + .altsetting = 1, \ + .altset_idx = 1, \ + .endpoint = 0x02, \ + .ep_idx = 1, \ + .ep_attr = USB_ENDPOINT_XFER_ISOC | \ + USB_ENDPOINT_SYNC_ASYNC, \ + .rates = SNDRV_PCM_RATE_KNOT | \ + SNDRV_PCM_RATE_176400 | \ + SNDRV_PCM_RATE_192000, \ + .rate_min = 128000, \ + .rate_max = 192000, \ + .nr_rates = 3, \ + .rate_table = (unsigned int[]) { \ + 128000, 176400, 192000, \ + }, \ + .sync_ep = 0x81, \ + .sync_iface = 0, \ + .sync_altsetting = 1, \ + .sync_ep_idx = 0, \ + .implicit_fb = 1, \ + }, \ + }, \ + { \ + QUIRK_DATA_AUDIOFORMAT(0) { \ + .formats = SNDRV_PCM_FMTBIT_S32_LE, \ + .channels = 32, /* inputs */ \ + .fmt_bits = 24, \ + .iface = 0, \ + .altsetting = 1, \ + .altset_idx = 1, \ + .endpoint = 0x81, \ + .ep_attr = USB_ENDPOINT_XFER_ISOC | \ + USB_ENDPOINT_SYNC_ASYNC, \ + .rates = SNDRV_PCM_RATE_32000 | \ + SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000, \ + .rate_min = 32000, \ + .rate_max = 48000, \ + .nr_rates = 3, \ + .rate_table = (unsigned int[]) { \ + 32000, 44100, 48000, \ + } \ + } \ + }, \ + { \ + QUIRK_DATA_AUDIOFORMAT(0) { \ + .formats = SNDRV_PCM_FMTBIT_S32_LE, \ + .channels = 16, /* inputs */ \ + .fmt_bits = 24, \ + .iface = 0, \ + .altsetting = 1, \ + .altset_idx = 1, \ + .endpoint = 0x81, \ + .ep_attr = USB_ENDPOINT_XFER_ISOC | \ + USB_ENDPOINT_SYNC_ASYNC, \ + .rates = SNDRV_PCM_RATE_64000 | \ + SNDRV_PCM_RATE_88200 | \ + SNDRV_PCM_RATE_96000, \ + .rate_min = 64000, \ + .rate_max = 96000, \ + .nr_rates = 3, \ + .rate_table = (unsigned int[]) { \ + 64000, 88200, 96000, \ + } \ + } \ + }, \ + { \ + QUIRK_DATA_AUDIOFORMAT(0) { \ + .formats = SNDRV_PCM_FMTBIT_S32_LE, \ + .channels = 8, /* inputs */ \ + .fmt_bits = 24, \ + .iface = 0, \ + .altsetting = 1, \ + .altset_idx = 1, \ + .endpoint = 0x81, \ + .ep_attr = USB_ENDPOINT_XFER_ISOC | \ + USB_ENDPOINT_SYNC_ASYNC, \ + .rates = SNDRV_PCM_RATE_KNOT | \ + SNDRV_PCM_RATE_176400 | \ + SNDRV_PCM_RATE_192000, \ + .rate_min = 128000, \ + .rate_max = 192000, \ + .nr_rates = 3, \ + .rate_table = (unsigned int[]) { \ + 128000, 176400, 192000, \ + } \ + } \ + }, \ + QUIRK_COMPOSITE_END \ + } \ + } \ +} + +QUIRK_RME_DIGIFACE(0x3f8c), +QUIRK_RME_DIGIFACE(0x3fa0), + #undef USB_DEVICE_VENDOR_SPEC #undef USB_AUDIO_DEVICE diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 8bc959b60be3..00101875d9a8 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -555,7 +555,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip, static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interface *intf) { struct usb_host_config *config = dev->actconfig; - struct usb_device_descriptor new_device_descriptor; + struct usb_device_descriptor *new_device_descriptor __free(kfree) = NULL; int err; if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD || @@ -566,15 +566,19 @@ static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interfac 0x10, 0x43, 0x0001, 0x000a, NULL, 0); if (err < 0) dev_dbg(&dev->dev, "error sending boot message: %d\n", err); + + new_device_descriptor = kmalloc(sizeof(*new_device_descriptor), GFP_KERNEL); + if (!new_device_descriptor) + return -ENOMEM; err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, - &new_device_descriptor, sizeof(new_device_descriptor)); + new_device_descriptor, sizeof(*new_device_descriptor)); if (err < 0) dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err); - if (new_device_descriptor.bNumConfigurations > dev->descriptor.bNumConfigurations) + if (new_device_descriptor->bNumConfigurations > dev->descriptor.bNumConfigurations) dev_dbg(&dev->dev, "error too large bNumConfigurations: %d\n", - new_device_descriptor.bNumConfigurations); + new_device_descriptor->bNumConfigurations); else - memcpy(&dev->descriptor, &new_device_descriptor, sizeof(dev->descriptor)); + memcpy(&dev->descriptor, new_device_descriptor, sizeof(dev->descriptor)); err = usb_reset_configuration(dev); if (err < 0) dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err); @@ -906,7 +910,7 @@ static void mbox2_setup_48_24_magic(struct usb_device *dev) static int snd_usb_mbox2_boot_quirk(struct usb_device *dev) { struct usb_host_config *config = dev->actconfig; - struct usb_device_descriptor new_device_descriptor; + struct usb_device_descriptor *new_device_descriptor __free(kfree) = NULL; int err; u8 bootresponse[0x12]; int fwsize; @@ -941,15 +945,19 @@ static int snd_usb_mbox2_boot_quirk(struct usb_device *dev) dev_dbg(&dev->dev, "device initialised!\n"); + new_device_descriptor = kmalloc(sizeof(*new_device_descriptor), GFP_KERNEL); + if (!new_device_descriptor) + return -ENOMEM; + err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, - &new_device_descriptor, sizeof(new_device_descriptor)); + new_device_descriptor, sizeof(*new_device_descriptor)); if (err < 0) dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err); - if (new_device_descriptor.bNumConfigurations > dev->descriptor.bNumConfigurations) + if (new_device_descriptor->bNumConfigurations > dev->descriptor.bNumConfigurations) dev_dbg(&dev->dev, "error too large bNumConfigurations: %d\n", - new_device_descriptor.bNumConfigurations); + new_device_descriptor->bNumConfigurations); else - memcpy(&dev->descriptor, &new_device_descriptor, sizeof(dev->descriptor)); + memcpy(&dev->descriptor, new_device_descriptor, sizeof(dev->descriptor)); err = usb_reset_configuration(dev); if (err < 0) @@ -1259,7 +1267,7 @@ static void mbox3_setup_defaults(struct usb_device *dev) static int snd_usb_mbox3_boot_quirk(struct usb_device *dev) { struct usb_host_config *config = dev->actconfig; - struct usb_device_descriptor new_device_descriptor; + struct usb_device_descriptor *new_device_descriptor __free(kfree) = NULL; int err; int descriptor_size; @@ -1272,15 +1280,19 @@ static int snd_usb_mbox3_boot_quirk(struct usb_device *dev) dev_dbg(&dev->dev, "MBOX3: device initialised!\n"); + new_device_descriptor = kmalloc(sizeof(*new_device_descriptor), GFP_KERNEL); + if (!new_device_descriptor) + return -ENOMEM; + err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, - &new_device_descriptor, sizeof(new_device_descriptor)); + new_device_descriptor, sizeof(*new_device_descriptor)); if (err < 0) dev_dbg(&dev->dev, "MBOX3: error usb_get_descriptor: %d\n", err); - if (new_device_descriptor.bNumConfigurations > dev->descriptor.bNumConfigurations) + if (new_device_descriptor->bNumConfigurations > dev->descriptor.bNumConfigurations) dev_dbg(&dev->dev, "MBOX3: error too large bNumConfigurations: %d\n", - new_device_descriptor.bNumConfigurations); + new_device_descriptor->bNumConfigurations); else - memcpy(&dev->descriptor, &new_device_descriptor, sizeof(dev->descriptor)); + memcpy(&dev->descriptor, new_device_descriptor, sizeof(dev->descriptor)); err = usb_reset_configuration(dev); if (err < 0) @@ -1653,6 +1665,7 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev, return snd_usb_motu_microbookii_boot_quirk(dev); break; case USB_ID(0x2a39, 0x3f8c): /* RME Digiface USB */ + case USB_ID(0x2a39, 0x3fa0): /* RME Digiface USB (alternate) */ return snd_usb_rme_digiface_boot_quirk(dev); } @@ -1866,6 +1879,7 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs, mbox3_set_format_quirk(subs, fmt); /* Digidesign Mbox 3 */ break; case USB_ID(0x2a39, 0x3f8c): /* RME Digiface USB */ + case USB_ID(0x2a39, 0x3fa0): /* RME Digiface USB (alternate) */ rme_digiface_set_format_quirk(subs); break; } |