sound fixes for 5.14-rc5
Here is a collection of small fixes: - A few regression fixes (PCM core fixes, USB-audio fixes) - Follow up fixes for the USB-audio mixer changes in this cycle - A long-standing ALSA sequencer race bug fix - Usual device-specific quirks for HD- and USB-audio -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmEL5joOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE+VMg/+J0k0bRrUDW+2STr2/iUqM7g8hfgp1f5Xf2Np CRxMHpcEQb/8AcT/9A2MdX5bgcAeOzUmO0Ym4qE5a889fuAqTLSifHWceE28+6oX bT0fCiGsZ+JjL2vOCSWQfsLeEnwBZHgMFEccYCv+SbjsEcOVtDm5F6Wzuy3TN5gF BsxFYalaaFwHdP55tIcxNvEoh1OkuE6vJninD48OQCRXYsBe+ntIHJ8Ak6B2f2QV JYS8JWrcQNBeEkhrj9femFqVQ4pDzXr6Gnm1E32Fjpl8E77cHWbSPi6+nY+XOyoI eQ2tZFmQnz9p7T+otxB6LnOpKtCZECVITO57dPgYLDepuRrn6luYaOdsfroWoJX1 u3qmNsPdbr2HAsJ9G+xeZOs6//+tiVfw2TT4HIQbcA1VN0yxPGkdbw0DNB3l7yk4 dakJFmSIu5lAymeXK5ix3hlXJR69JxyKKg8lunDUnKQP1YWruzvnujdo1eAP5b9v BMQgFTSFuLd77HTWHeDs3EG1fqFlYRKIXJwZcaoEgGTDqaVuuWTk7AkjcNA3fIRM FW/37NSb++JGd5bY0M3j9imP+NG3aVItgKlLBMImdeQ6o/2N9Mgv2/J5Xpxw38j8 Km6WQvXthUr+F/K8skTgZPoVRy+DWRb8CxWSm9gAxgA5FBUrou6/ZWk+/9NT+4YA yKFSIq0= =umHe -----END PGP SIGNATURE----- Merge tag 'sound-5.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "A collection of small fixes: - A few regression fixes (PCM core fixes, USB-audio fixes) - Follow up fixes for the USB-audio mixer changes in this cycle - A long-standing ALSA sequencer race bug fix - Usual device-specific quirks for HD- and USB-audio" * tag 'sound-5.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: seq: Fix racy deletion of subscriber ALSA: memalloc: Fix regression with SNDRV_DMA_TYPE_CONTINUOUS ALSA: pcm - fix mmap capability check for the snd-dummy driver ALSA: usb-audio: Avoid unnecessary or invalid connector selection at resume ALSA: hda/realtek: add mic quirk for Acer SF314-42 ALSA: usb-audio: Add registration quirk for JBL Quantum 600 ALSA: hda/realtek: Fix headset mic for Acer SWIFT SF314-56 (ALC256) ALSA: usb-audio: Fix superfluous autosuspend recovery ALSA: usb-audio: fix incorrect clock source setting ALSA: scarlett2: Fix line out/speaker switching notifications ALSA: scarlett2: Correct channel mute status after mute button pressed ALSA: scarlett2: Fix Direct Monitor control name for 2i2 ALSA: scarlett2: Fix Mute/Dim/MSD Mode control names
This commit is contained in:
Коммит
484faec8f1
|
@ -215,7 +215,7 @@ static int snd_dma_continuous_mmap(struct snd_dma_buffer *dmab,
|
|||
struct vm_area_struct *area)
|
||||
{
|
||||
return remap_pfn_range(area, area->vm_start,
|
||||
dmab->addr >> PAGE_SHIFT,
|
||||
page_to_pfn(virt_to_page(dmab->area)),
|
||||
area->vm_end - area->vm_start,
|
||||
area->vm_page_prot);
|
||||
}
|
||||
|
|
|
@ -246,7 +246,7 @@ static bool hw_support_mmap(struct snd_pcm_substream *substream)
|
|||
if (!(substream->runtime->hw.info & SNDRV_PCM_INFO_MMAP))
|
||||
return false;
|
||||
|
||||
if (substream->ops->mmap)
|
||||
if (substream->ops->mmap || substream->ops->page)
|
||||
return true;
|
||||
|
||||
switch (substream->dma_buffer.dev.type) {
|
||||
|
|
|
@ -514,7 +514,8 @@ static int check_and_subscribe_port(struct snd_seq_client *client,
|
|||
return err;
|
||||
}
|
||||
|
||||
static void delete_and_unsubscribe_port(struct snd_seq_client *client,
|
||||
/* called with grp->list_mutex held */
|
||||
static void __delete_and_unsubscribe_port(struct snd_seq_client *client,
|
||||
struct snd_seq_client_port *port,
|
||||
struct snd_seq_subscribers *subs,
|
||||
bool is_src, bool ack)
|
||||
|
@ -525,7 +526,6 @@ static void delete_and_unsubscribe_port(struct snd_seq_client *client,
|
|||
|
||||
grp = is_src ? &port->c_src : &port->c_dest;
|
||||
list = is_src ? &subs->src_list : &subs->dest_list;
|
||||
down_write(&grp->list_mutex);
|
||||
write_lock_irq(&grp->list_lock);
|
||||
empty = list_empty(list);
|
||||
if (!empty)
|
||||
|
@ -535,6 +535,18 @@ static void delete_and_unsubscribe_port(struct snd_seq_client *client,
|
|||
|
||||
if (!empty)
|
||||
unsubscribe_port(client, port, grp, &subs->info, ack);
|
||||
}
|
||||
|
||||
static void delete_and_unsubscribe_port(struct snd_seq_client *client,
|
||||
struct snd_seq_client_port *port,
|
||||
struct snd_seq_subscribers *subs,
|
||||
bool is_src, bool ack)
|
||||
{
|
||||
struct snd_seq_port_subs_info *grp;
|
||||
|
||||
grp = is_src ? &port->c_src : &port->c_dest;
|
||||
down_write(&grp->list_mutex);
|
||||
__delete_and_unsubscribe_port(client, port, subs, is_src, ack);
|
||||
up_write(&grp->list_mutex);
|
||||
}
|
||||
|
||||
|
@ -590,27 +602,30 @@ int snd_seq_port_disconnect(struct snd_seq_client *connector,
|
|||
struct snd_seq_client_port *dest_port,
|
||||
struct snd_seq_port_subscribe *info)
|
||||
{
|
||||
struct snd_seq_port_subs_info *src = &src_port->c_src;
|
||||
struct snd_seq_port_subs_info *dest = &dest_port->c_dest;
|
||||
struct snd_seq_subscribers *subs;
|
||||
int err = -ENOENT;
|
||||
|
||||
down_write(&src->list_mutex);
|
||||
/* always start from deleting the dest port for avoiding concurrent
|
||||
* deletions
|
||||
*/
|
||||
down_write(&dest->list_mutex);
|
||||
/* look for the connection */
|
||||
list_for_each_entry(subs, &src->list_head, src_list) {
|
||||
list_for_each_entry(subs, &dest->list_head, dest_list) {
|
||||
if (match_subs_info(info, &subs->info)) {
|
||||
atomic_dec(&subs->ref_count); /* mark as not ready */
|
||||
__delete_and_unsubscribe_port(dest_client, dest_port,
|
||||
subs, false,
|
||||
connector->number != dest_client->number);
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
up_write(&src->list_mutex);
|
||||
up_write(&dest->list_mutex);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
delete_and_unsubscribe_port(src_client, src_port, subs, true,
|
||||
connector->number != src_client->number);
|
||||
delete_and_unsubscribe_port(dest_client, dest_port, subs, false,
|
||||
connector->number != dest_client->number);
|
||||
kfree(subs);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -8274,9 +8274,11 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1025, 0x129c, "Acer SWIFT SF314-55", ALC256_FIXUP_ACER_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1025, 0x1300, "Acer SWIFT SF314-56", ALC256_FIXUP_ACER_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1025, 0x142b, "Acer Swift SF314-42", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1025, 0x1430, "Acer TravelMate B311R-31", ALC256_FIXUP_ACER_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1025, 0x1466, "Acer Aspire A515-56", ALC255_FIXUP_ACER_HEADPHONE_AND_MIC),
|
||||
SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
|
||||
|
|
|
@ -907,7 +907,7 @@ static void usb_audio_disconnect(struct usb_interface *intf)
|
|||
}
|
||||
}
|
||||
|
||||
if (chip->quirk_type & QUIRK_SETUP_DISABLE_AUTOSUSPEND)
|
||||
if (chip->quirk_type == QUIRK_SETUP_DISABLE_AUTOSUSPEND)
|
||||
usb_enable_autosuspend(interface_to_usbdev(intf));
|
||||
|
||||
chip->num_interfaces--;
|
||||
|
|
|
@ -324,6 +324,12 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
|
|||
sources[ret - 1],
|
||||
visited, validate);
|
||||
if (ret > 0) {
|
||||
/*
|
||||
* For Samsung USBC Headset (AKG), setting clock selector again
|
||||
* will result in incorrect default clock setting problems
|
||||
*/
|
||||
if (chip->usb_id == USB_ID(0x04e8, 0xa051))
|
||||
return ret;
|
||||
err = uac_clock_selector_set_val(chip, entity_id, cur);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
|
|
@ -1816,6 +1816,15 @@ static void get_connector_control_name(struct usb_mixer_interface *mixer,
|
|||
strlcat(name, " - Output Jack", name_size);
|
||||
}
|
||||
|
||||
/* get connector value to "wake up" the USB audio */
|
||||
static int connector_mixer_resume(struct usb_mixer_elem_list *list)
|
||||
{
|
||||
struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list);
|
||||
|
||||
get_connector_value(cval, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Build a mixer control for a UAC connector control (jack-detect) */
|
||||
static void build_connector_control(struct usb_mixer_interface *mixer,
|
||||
const struct usbmix_name_map *imap,
|
||||
|
@ -1833,6 +1842,10 @@ static void build_connector_control(struct usb_mixer_interface *mixer,
|
|||
if (!cval)
|
||||
return;
|
||||
snd_usb_mixer_elem_init_std(&cval->head, mixer, term->id);
|
||||
|
||||
/* set up a specific resume callback */
|
||||
cval->head.resume = connector_mixer_resume;
|
||||
|
||||
/*
|
||||
* UAC2: The first byte from reading the UAC2_TE_CONNECTOR control returns the
|
||||
* number of channels connected.
|
||||
|
@ -3642,23 +3655,15 @@ static int restore_mixer_value(struct usb_mixer_elem_list *list)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int default_mixer_resume(struct usb_mixer_elem_list *list)
|
||||
{
|
||||
struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list);
|
||||
|
||||
/* get connector value to "wake up" the USB audio */
|
||||
if (cval->val_type == USB_MIXER_BOOLEAN && cval->channels == 1)
|
||||
get_connector_value(cval, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int default_mixer_reset_resume(struct usb_mixer_elem_list *list)
|
||||
{
|
||||
int err = default_mixer_resume(list);
|
||||
int err;
|
||||
|
||||
if (list->resume) {
|
||||
err = list->resume(list);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
return restore_mixer_value(list);
|
||||
}
|
||||
|
||||
|
@ -3697,7 +3702,7 @@ void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list,
|
|||
list->id = unitid;
|
||||
list->dump = snd_usb_mixer_dump_cval;
|
||||
#ifdef CONFIG_PM
|
||||
list->resume = default_mixer_resume;
|
||||
list->resume = NULL;
|
||||
list->reset_resume = default_mixer_reset_resume;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -228,7 +228,7 @@ enum {
|
|||
};
|
||||
|
||||
static const char *const scarlett2_dim_mute_names[SCARLETT2_DIM_MUTE_COUNT] = {
|
||||
"Mute", "Dim"
|
||||
"Mute Playback Switch", "Dim Playback Switch"
|
||||
};
|
||||
|
||||
/* Description of each hardware port type:
|
||||
|
@ -1856,9 +1856,15 @@ static int scarlett2_mute_ctl_get(struct snd_kcontrol *kctl,
|
|||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct usb_mixer_elem_info *elem = kctl->private_data;
|
||||
struct scarlett2_data *private = elem->head.mixer->private_data;
|
||||
struct usb_mixer_interface *mixer = elem->head.mixer;
|
||||
struct scarlett2_data *private = mixer->private_data;
|
||||
int index = line_out_remap(private, elem->control);
|
||||
|
||||
mutex_lock(&private->data_mutex);
|
||||
if (private->vol_updated)
|
||||
scarlett2_update_volumes(mixer);
|
||||
mutex_unlock(&private->data_mutex);
|
||||
|
||||
ucontrol->value.integer.value[0] = private->mute_switch[index];
|
||||
return 0;
|
||||
}
|
||||
|
@ -1955,10 +1961,12 @@ static void scarlett2_vol_ctl_set_writable(struct usb_mixer_interface *mixer,
|
|||
~SNDRV_CTL_ELEM_ACCESS_WRITE;
|
||||
}
|
||||
|
||||
/* Notify of write bit change */
|
||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO,
|
||||
/* Notify of write bit and possible value change */
|
||||
snd_ctl_notify(card,
|
||||
SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO,
|
||||
&private->vol_ctls[index]->id);
|
||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO,
|
||||
snd_ctl_notify(card,
|
||||
SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO,
|
||||
&private->mute_ctls[index]->id);
|
||||
}
|
||||
|
||||
|
@ -2530,14 +2538,18 @@ static int scarlett2_add_direct_monitor_ctl(struct usb_mixer_interface *mixer)
|
|||
{
|
||||
struct scarlett2_data *private = mixer->private_data;
|
||||
const struct scarlett2_device_info *info = private->info;
|
||||
const char *s;
|
||||
|
||||
if (!info->direct_monitor)
|
||||
return 0;
|
||||
|
||||
s = info->direct_monitor == 1
|
||||
? "Direct Monitor Playback Switch"
|
||||
: "Direct Monitor Playback Enum";
|
||||
|
||||
return scarlett2_add_new_ctl(
|
||||
mixer, &scarlett2_direct_monitor_ctl[info->direct_monitor - 1],
|
||||
0, 1, "Direct Monitor Playback Switch",
|
||||
&private->direct_monitor_ctl);
|
||||
0, 1, s, &private->direct_monitor_ctl);
|
||||
}
|
||||
|
||||
/*** Speaker Switching Control ***/
|
||||
|
@ -2589,7 +2601,9 @@ static int scarlett2_speaker_switch_enable(struct usb_mixer_interface *mixer)
|
|||
|
||||
/* disable the line out SW/HW switch */
|
||||
scarlett2_sw_hw_ctl_ro(private, i);
|
||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO,
|
||||
snd_ctl_notify(card,
|
||||
SNDRV_CTL_EVENT_MASK_VALUE |
|
||||
SNDRV_CTL_EVENT_MASK_INFO,
|
||||
&private->sw_hw_ctls[i]->id);
|
||||
}
|
||||
|
||||
|
@ -2913,7 +2927,7 @@ static int scarlett2_dim_mute_ctl_put(struct snd_kcontrol *kctl,
|
|||
if (private->vol_sw_hw_switch[line_index]) {
|
||||
private->mute_switch[line_index] = val;
|
||||
snd_ctl_notify(mixer->chip->card,
|
||||
SNDRV_CTL_EVENT_MASK_INFO,
|
||||
SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&private->mute_ctls[i]->id);
|
||||
}
|
||||
}
|
||||
|
@ -3455,7 +3469,7 @@ static int scarlett2_add_msd_ctl(struct usb_mixer_interface *mixer)
|
|||
|
||||
/* Add MSD control */
|
||||
return scarlett2_add_new_ctl(mixer, &scarlett2_msd_ctl,
|
||||
0, 1, "MSD Mode", NULL);
|
||||
0, 1, "MSD Mode Switch", NULL);
|
||||
}
|
||||
|
||||
/*** Cleanup/Suspend Callbacks ***/
|
||||
|
|
|
@ -1899,6 +1899,7 @@ static const struct registration_quirk registration_quirks[] = {
|
|||
REG_QUIRK_ENTRY(0x0951, 0x16ea, 2), /* Kingston HyperX Cloud Flight S */
|
||||
REG_QUIRK_ENTRY(0x0ecb, 0x1f46, 2), /* JBL Quantum 600 */
|
||||
REG_QUIRK_ENTRY(0x0ecb, 0x2039, 2), /* JBL Quantum 400 */
|
||||
REG_QUIRK_ENTRY(0x0ecb, 0x203c, 2), /* JBL Quantum 600 */
|
||||
REG_QUIRK_ENTRY(0x0ecb, 0x203e, 2), /* JBL Quantum 800 */
|
||||
{ 0 } /* terminator */
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче