diff options
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/6fire/pcm.c | 10 | ||||
-rw-r--r-- | sound/usb/caiaq/audio.c | 7 | ||||
-rw-r--r-- | sound/usb/card.h | 1 | ||||
-rw-r--r-- | sound/usb/format.c | 10 | ||||
-rw-r--r-- | sound/usb/line6/capture.c | 4 | ||||
-rw-r--r-- | sound/usb/line6/pcm.c | 6 | ||||
-rw-r--r-- | sound/usb/line6/playback.c | 4 | ||||
-rw-r--r-- | sound/usb/mixer.c | 47 | ||||
-rw-r--r-- | sound/usb/pcm.c | 2 | ||||
-rw-r--r-- | sound/usb/quirks-table.h | 5 | ||||
-rw-r--r-- | sound/usb/quirks.c | 19 | ||||
-rw-r--r-- | sound/usb/usx2y/usbusx2y.c | 4 | ||||
-rw-r--r-- | sound/usb/usx2y/usbusx2yaudio.c | 7 |
13 files changed, 87 insertions, 39 deletions
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c index 224a6a5d1c0e..2dd2518a71d3 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c @@ -591,12 +591,14 @@ static int usb6fire_pcm_buffers_init(struct pcm_runtime *rt) int i; for (i = 0; i < PCM_N_URBS; i++) { - rt->out_urbs[i].buffer = kzalloc(PCM_N_PACKETS_PER_URB - * PCM_MAX_PACKET_SIZE, GFP_KERNEL); + rt->out_urbs[i].buffer = kcalloc(PCM_MAX_PACKET_SIZE, + PCM_N_PACKETS_PER_URB, + GFP_KERNEL); if (!rt->out_urbs[i].buffer) return -ENOMEM; - rt->in_urbs[i].buffer = kzalloc(PCM_N_PACKETS_PER_URB - * PCM_MAX_PACKET_SIZE, GFP_KERNEL); + rt->in_urbs[i].buffer = kcalloc(PCM_MAX_PACKET_SIZE, + PCM_N_PACKETS_PER_URB, + GFP_KERNEL); if (!rt->in_urbs[i].buffer) return -ENOMEM; } diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c index fb1c1eac0b5e..f35d29f49ffe 100644 --- a/sound/usb/caiaq/audio.c +++ b/sound/usb/caiaq/audio.c @@ -728,7 +728,7 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *cdev, int dir, int *ret) usb_sndisocpipe(usb_dev, ENDPOINT_PLAYBACK) : usb_rcvisocpipe(usb_dev, ENDPOINT_CAPTURE); - urbs = kmalloc(N_URBS * sizeof(*urbs), GFP_KERNEL); + urbs = kmalloc_array(N_URBS, sizeof(*urbs), GFP_KERNEL); if (!urbs) { *ret = -ENOMEM; return NULL; @@ -742,7 +742,8 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *cdev, int dir, int *ret) } urbs[i]->transfer_buffer = - kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL); + kmalloc_array(BYTES_PER_FRAME, FRAMES_PER_URB, + GFP_KERNEL); if (!urbs[i]->transfer_buffer) { *ret = -ENOMEM; return urbs; @@ -857,7 +858,7 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *cdev) &snd_usb_caiaq_ops); cdev->data_cb_info = - kmalloc(sizeof(struct snd_usb_caiaq_cb_info) * N_URBS, + kmalloc_array(N_URBS, sizeof(struct snd_usb_caiaq_cb_info), GFP_KERNEL); if (!cdev->data_cb_info) diff --git a/sound/usb/card.h b/sound/usb/card.h index 1406292d50ec..9b41b7dda84f 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h @@ -32,6 +32,7 @@ struct audioformat { struct snd_pcm_chmap_elem *chmap; /* (optional) channel map */ bool dsd_dop; /* add DOP headers in case of DSD samples */ bool dsd_bitrev; /* reverse the bits of each DSD sample */ + bool dsd_raw; /* altsetting is raw DSD */ }; struct snd_usb_substream; diff --git a/sound/usb/format.c b/sound/usb/format.c index 49e7ec6d2399..fd13ac11b136 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c @@ -64,8 +64,11 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, sample_width = fmt->bBitResolution; sample_bytes = fmt->bSubslotSize; - if (format & UAC2_FORMAT_TYPE_I_RAW_DATA) + if (format & UAC2_FORMAT_TYPE_I_RAW_DATA) { pcm_formats |= SNDRV_PCM_FMTBIT_SPECIAL; + /* flag potentially raw DSD capable altsettings */ + fp->dsd_raw = true; + } format <<= 1; break; @@ -188,7 +191,8 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof */ int r, idx; - fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); + fp->rate_table = kmalloc_array(nr_rates, sizeof(int), + GFP_KERNEL); if (fp->rate_table == NULL) return -ENOMEM; @@ -362,7 +366,7 @@ static int parse_audio_format_rates_v2v3(struct snd_usb_audio *chip, goto err_free; } - fp->rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL); + fp->rate_table = kmalloc_array(fp->nr_rates, sizeof(int), GFP_KERNEL); if (!fp->rate_table) { ret = -ENOMEM; goto err_free; diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c index 947d6168f24a..d8a14d769f48 100644 --- a/sound/usb/line6/capture.c +++ b/sound/usb/line6/capture.c @@ -264,8 +264,8 @@ int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm) struct usb_line6 *line6 = line6pcm->line6; int i; - line6pcm->in.urbs = kzalloc( - sizeof(struct urb *) * line6->iso_buffers, GFP_KERNEL); + line6pcm->in.urbs = kcalloc(line6->iso_buffers, sizeof(struct urb *), + GFP_KERNEL); if (line6pcm->in.urbs == NULL) return -ENOMEM; diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c index b3854f8c0c67..72c6f8e82a7e 100644 --- a/sound/usb/line6/pcm.c +++ b/sound/usb/line6/pcm.c @@ -158,8 +158,10 @@ static int line6_buffer_acquire(struct snd_line6_pcm *line6pcm, /* Invoked multiple times in a row so allocate once only */ if (!test_and_set_bit(type, &pstr->opened) && !pstr->buffer) { - pstr->buffer = kmalloc(line6pcm->line6->iso_buffers * - LINE6_ISO_PACKETS * pkt_size, GFP_KERNEL); + pstr->buffer = + kmalloc(array3_size(line6pcm->line6->iso_buffers, + LINE6_ISO_PACKETS, pkt_size), + GFP_KERNEL); if (!pstr->buffer) return -ENOMEM; } diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c index 819e9b2d1d6e..dec89d2beb57 100644 --- a/sound/usb/line6/playback.c +++ b/sound/usb/line6/playback.c @@ -409,8 +409,8 @@ int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm) struct usb_line6 *line6 = line6pcm->line6; int i; - line6pcm->out.urbs = kzalloc( - sizeof(struct urb *) * line6->iso_buffers, GFP_KERNEL); + line6pcm->out.urbs = kcalloc(line6->iso_buffers, sizeof(struct urb *), + GFP_KERNEL); if (line6pcm->out.urbs == NULL) return -ENOMEM; diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 898afd3001ea..ca963e94ec03 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1653,11 +1653,11 @@ static void build_feature_ctl_badd(struct usb_mixer_interface *mixer, NULL, NULL, unitid, 0, 0); } -static void get_connector_control_name(struct mixer_build *state, +static void get_connector_control_name(struct usb_mixer_interface *mixer, struct usb_audio_term *term, bool is_input, char *name, int name_size) { - int name_len = get_term_name(state->chip, term, name, name_size, 0); + int name_len = get_term_name(mixer->chip, term, name, name_size, 0); if (name_len == 0) strlcpy(name, "Unknown", name_size); @@ -1674,7 +1674,7 @@ static void get_connector_control_name(struct mixer_build *state, } /* Build a mixer control for a UAC connector control (jack-detect) */ -static void build_connector_control(struct mixer_build *state, +static void build_connector_control(struct usb_mixer_interface *mixer, struct usb_audio_term *term, bool is_input) { struct snd_kcontrol *kctl; @@ -1683,7 +1683,7 @@ static void build_connector_control(struct mixer_build *state, cval = kzalloc(sizeof(*cval), GFP_KERNEL); if (!cval) return; - snd_usb_mixer_elem_init_std(&cval->head, state->mixer, term->id); + snd_usb_mixer_elem_init_std(&cval->head, mixer, term->id); /* * UAC2: The first byte from reading the UAC2_TE_CONNECTOR control returns the * number of channels connected. @@ -1694,7 +1694,7 @@ static void build_connector_control(struct mixer_build *state, * This boolean ctl will simply report if any channels are connected * or not. */ - if (state->mixer->protocol == UAC_VERSION_2) + if (mixer->protocol == UAC_VERSION_2) cval->control = UAC2_TE_CONNECTOR; else /* UAC_VERSION_3 */ cval->control = UAC3_TE_INSERTION; @@ -1705,11 +1705,11 @@ static void build_connector_control(struct mixer_build *state, cval->max = 1; kctl = snd_ctl_new1(&usb_connector_ctl_ro, cval); if (!kctl) { - usb_audio_err(state->chip, "cannot malloc kcontrol\n"); + usb_audio_err(mixer->chip, "cannot malloc kcontrol\n"); kfree(cval); return; } - get_connector_control_name(state, term, is_input, kctl->id.name, + get_connector_control_name(mixer, term, is_input, kctl->id.name, sizeof(kctl->id.name)); kctl->private_free = snd_usb_mixer_elem_free; snd_usb_mixer_add_control(&cval->head, kctl); @@ -2042,7 +2042,7 @@ static int parse_audio_input_terminal(struct mixer_build *state, int unitid, /* Check for jack detection. */ if (uac_v2v3_control_is_readable(bmctls, control)) - build_connector_control(state, &iterm, true); + build_connector_control(state->mixer, &iterm, true); return 0; } @@ -2515,7 +2515,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, cval->control = (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR) ? UAC2_CX_CLOCK_SELECTOR : UAC2_SU_SELECTOR; - namelist = kmalloc(sizeof(char *) * desc->bNrInPins, GFP_KERNEL); + namelist = kmalloc_array(desc->bNrInPins, sizeof(char *), GFP_KERNEL); if (!namelist) { kfree(cval); return -ENOMEM; @@ -2918,6 +2918,23 @@ static int snd_usb_mixer_controls_badd(struct usb_mixer_interface *mixer, UAC3_BADD_FU_ID7, map->map); } + /* Insertion Control */ + if (f->subclass == UAC3_FUNCTION_SUBCLASS_HEADSET_ADAPTER) { + struct usb_audio_term iterm, oterm; + + /* Input Term - Insertion control */ + memset(&iterm, 0, sizeof(iterm)); + iterm.id = UAC3_BADD_IT_ID4; + iterm.type = UAC_BIDIR_TERMINAL_HEADSET; + build_connector_control(mixer, &iterm, true); + + /* Output Term - Insertion control */ + memset(&oterm, 0, sizeof(oterm)); + oterm.id = UAC3_BADD_OT_ID3; + oterm.type = UAC_BIDIR_TERMINAL_HEADSET; + build_connector_control(mixer, &oterm, false); + } + return 0; } @@ -2990,7 +3007,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) if (uac_v2v3_control_is_readable(le16_to_cpu(desc->bmControls), UAC2_TE_CONNECTOR)) { - build_connector_control(&state, &state.oterm, + build_connector_control(state.mixer, &state.oterm, false); } } else { /* UAC_VERSION_3 */ @@ -3017,7 +3034,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) if (uac_v2v3_control_is_readable(le32_to_cpu(desc->bmControls), UAC3_TE_INSERTION)) { - build_connector_control(&state, &state.oterm, + build_connector_control(state.mixer, &state.oterm, false); } } @@ -3321,10 +3338,12 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, err = snd_usb_mixer_controls(mixer); if (err < 0) goto _error; - err = snd_usb_mixer_status_create(mixer); - if (err < 0) - goto _error; } + + err = snd_usb_mixer_status_create(mixer); + if (err < 0) + goto _error; + err = create_keep_iface_ctl(mixer); if (err < 0) goto _error; diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 78d1cad08a0a..160f52c4871b 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -1123,7 +1123,7 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime, return 0; subs->rate_list.list = rate_list = - kmalloc(sizeof(int) * count, GFP_KERNEL); + kmalloc_array(count, sizeof(int), GFP_KERNEL); if (!subs->rate_list.list) return -ENOMEM; subs->rate_list.count = count; diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 0e37e358ca97..8aac48f9c322 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -3277,6 +3277,10 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"), } }, +/* disabled due to regression for other devices; + * see https://bugzilla.kernel.org/show_bug.cgi?id=199905 + */ +#if 0 { /* * Nura's first gen headphones use Cambridge Silicon Radio's vendor @@ -3324,6 +3328,7 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"), } } }, +#endif /* disabled */ { /* diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index f4b69173682c..02b6cc02767f 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1362,16 +1362,12 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, case USB_ID(0x1511, 0x0037): /* AURALiC VEGA */ case USB_ID(0x20b1, 0x0002): /* Wyred 4 Sound DAC-2 DSD */ case USB_ID(0x20b1, 0x2004): /* Matrix Audio X-SPDIF 2 */ - case USB_ID(0x20b1, 0x3008): /* iFi Audio micro/nano iDSD */ case USB_ID(0x20b1, 0x2008): /* Matrix Audio X-Sabre */ case USB_ID(0x20b1, 0x300a): /* Matrix Audio Mini-i Pro */ case USB_ID(0x22d9, 0x0416): /* OPPO HA-1 */ case USB_ID(0x22d9, 0x0436): /* OPPO Sonica */ case USB_ID(0x22d9, 0x0461): /* OPPO UDP-205 */ case USB_ID(0x2522, 0x0012): /* LH Labs VI DAC Infinity */ - case USB_ID(0x25ce, 0x001f): /* Mytek Brooklyn DAC */ - case USB_ID(0x25ce, 0x0021): /* Mytek Manhattan DAC */ - case USB_ID(0x25ce, 0x8025): /* Mytek Brooklyn DAC+ */ case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */ if (fp->altsetting == 2) return SNDRV_PCM_FMTBIT_DSD_U32_BE; @@ -1389,7 +1385,6 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, case USB_ID(0x20b1, 0x3021): /* Eastern El. MiniMax Tube DAC Supreme */ case USB_ID(0x20b1, 0x3023): /* Aune X1S 32BIT/384 DSD DAC */ case USB_ID(0x20b1, 0x302d): /* Unison Research Unico CD Due */ - case USB_ID(0x20b1, 0x3036): /* Holo Springs Level 3 R2R DAC */ case USB_ID(0x20b1, 0x307b): /* CH Precision C1 DAC */ case USB_ID(0x20b1, 0x3086): /* Singxer F-1 converter board */ case USB_ID(0x22d9, 0x0426): /* OPPO HA-2 */ @@ -1443,6 +1438,20 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, return SNDRV_PCM_FMTBIT_DSD_U32_BE; } + /* Mostly generic method to detect many DSD-capable implementations - + * from XMOS/Thesycon + */ + switch (USB_ID_VENDOR(chip->usb_id)) { + case 0x20b1: /* XMOS based devices */ + case 0x25ce: /* Mytek devices */ + if (fp->dsd_raw) + return SNDRV_PCM_FMTBIT_DSD_U32_BE; + break; + default: + break; + + } + return 0; } diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c index 0ddf29267d70..da4a5a541512 100644 --- a/sound/usb/usx2y/usbusx2y.c +++ b/sound/usb/usx2y/usbusx2y.c @@ -266,7 +266,9 @@ int usX2Y_AsyncSeq04_init(struct usX2Ydev *usX2Y) int err = 0, i; - if (NULL == (usX2Y->AS04.buffer = kmalloc(URB_DataLen_AsyncSeq*URBS_AsyncSeq, GFP_KERNEL))) { + usX2Y->AS04.buffer = kmalloc_array(URBS_AsyncSeq, + URB_DataLen_AsyncSeq, GFP_KERNEL); + if (NULL == usX2Y->AS04.buffer) { err = -ENOMEM; } else for (i = 0; i < URBS_AsyncSeq; ++i) { diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c index 345e439aa95b..2b833054e3b0 100644 --- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c @@ -436,7 +436,9 @@ static int usX2Y_urbs_allocate(struct snd_usX2Y_substream *subs) } if (!is_playback && !(*purb)->transfer_buffer) { /* allocate a capture buffer per urb */ - (*purb)->transfer_buffer = kmalloc(subs->maxpacksize * nr_of_packs(), GFP_KERNEL); + (*purb)->transfer_buffer = + kmalloc_array(subs->maxpacksize, + nr_of_packs(), GFP_KERNEL); if (NULL == (*purb)->transfer_buffer) { usX2Y_urbs_release(subs); return -ENOMEM; @@ -662,7 +664,8 @@ static int usX2Y_rate_set(struct usX2Ydev *usX2Y, int rate) err = -ENOMEM; goto cleanup; } - usbdata = kmalloc(sizeof(int) * NOOF_SETRATE_URBS, GFP_KERNEL); + usbdata = kmalloc_array(NOOF_SETRATE_URBS, sizeof(int), + GFP_KERNEL); if (NULL == usbdata) { err = -ENOMEM; goto cleanup; |