diff options
-rw-r--r-- | sound/firewire/amdtp.c | 4 | ||||
-rw-r--r-- | sound/pci/asihpi/asihpi.c | 9 | ||||
-rw-r--r-- | sound/pci/au88x0/au88x0_synth.c | 29 | ||||
-rw-r--r-- | sound/pci/azt3328.c | 14 | ||||
-rw-r--r-- | sound/pci/ctxfi/ctdaio.c | 4 | ||||
-rw-r--r-- | sound/pci/hda/patch_ca0132.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 146 | ||||
-rw-r--r-- | sound/pci/rme9652/hdspm.c | 5 | ||||
-rw-r--r-- | sound/usb/caiaq/control.c | 92 | ||||
-rw-r--r-- | sound/usb/caiaq/device.c | 25 | ||||
-rw-r--r-- | sound/usb/caiaq/device.h | 5 | ||||
-rw-r--r-- | sound/usb/card.c | 9 | ||||
-rw-r--r-- | sound/usb/card.h | 12 | ||||
-rw-r--r-- | sound/usb/endpoint.c | 139 | ||||
-rw-r--r-- | sound/usb/endpoint.h | 4 | ||||
-rw-r--r-- | sound/usb/helper.c | 1 | ||||
-rw-r--r-- | sound/usb/mixer.c | 4 | ||||
-rw-r--r-- | sound/usb/pcm.c | 40 | ||||
-rw-r--r-- | sound/usb/usbaudio.h | 1 |
19 files changed, 347 insertions, 198 deletions
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index ea995af6d04..4b08b25a4db 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c @@ -268,7 +268,7 @@ static void amdtp_write_s32(struct amdtp_out_stream *s, channels = s->pcm_channels; src = (void *)runtime->dma_area + - s->pcm_buffer_pointer * (runtime->frame_bits / 8); + frames_to_bytes(runtime, s->pcm_buffer_pointer); remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; frame_step = s->data_block_quadlets - channels; @@ -294,7 +294,7 @@ static void amdtp_write_s16(struct amdtp_out_stream *s, channels = s->pcm_channels; src = (void *)runtime->dma_area + - s->pcm_buffer_pointer * (runtime->frame_bits / 8); + frames_to_bytes(runtime, s->pcm_buffer_pointer); remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; frame_step = s->data_block_quadlets - channels; diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index dc632cdc387..5f2acd35dcb 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -1913,6 +1913,7 @@ static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol, struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol); */ u32 h_control = kcontrol->private_value; + unsigned int idx; u16 band; u16 tuner_bands[HPI_TUNER_BAND_LAST]; u32 num_bands = 0; @@ -1920,7 +1921,10 @@ static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol, num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands, HPI_TUNER_BAND_LAST); - band = tuner_bands[ucontrol->value.enumerated.item[0]]; + idx = ucontrol->value.enumerated.item[0]; + if (idx >= ARRAY_SIZE(tuner_bands)) + idx = ARRAY_SIZE(tuner_bands) - 1; + band = tuner_bands[idx]; hpi_handle_error(hpi_tuner_set_band(h_control, band)); return 1; @@ -2383,7 +2387,8 @@ static int snd_asihpi_clksrc_put(struct snd_kcontrol *kcontrol, struct snd_card_asihpi *asihpi = (struct snd_card_asihpi *)(kcontrol->private_data); struct clk_cache *clkcache = &asihpi->cc; - int change, item; + unsigned int item; + int change; u32 h_control = kcontrol->private_value; change = 1; diff --git a/sound/pci/au88x0/au88x0_synth.c b/sound/pci/au88x0/au88x0_synth.c index 8bef47311e4..922a84bba2e 100644 --- a/sound/pci/au88x0/au88x0_synth.c +++ b/sound/pci/au88x0/au88x0_synth.c @@ -219,7 +219,6 @@ vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, */ hwwrite(vortex->mmio, WT_RUN(wt), val); return 0xc; - break; case 1: /* param 0 */ /* printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", @@ -227,7 +226,6 @@ vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, */ hwwrite(vortex->mmio, WT_PARM(wt, 0), val); return 0xc; - break; case 2: /* param 1 */ /* printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", @@ -235,7 +233,6 @@ vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, */ hwwrite(vortex->mmio, WT_PARM(wt, 1), val); return 0xc; - break; case 3: /* param 2 */ /* printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", @@ -243,7 +240,6 @@ vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, */ hwwrite(vortex->mmio, WT_PARM(wt, 2), val); return 0xc; - break; case 4: /* param 3 */ /* printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", @@ -251,7 +247,6 @@ vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, */ hwwrite(vortex->mmio, WT_PARM(wt, 3), val); return 0xc; - break; case 6: /* mute */ /* printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", @@ -259,20 +254,17 @@ vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, */ hwwrite(vortex->mmio, WT_MUTE(wt), val); return 0xc; - break; case 0xb: - { /* delay */ - /* - printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", - WT_DELAY(wt,0), (int)val); - */ - hwwrite(vortex->mmio, WT_DELAY(wt, 3), val); - hwwrite(vortex->mmio, WT_DELAY(wt, 2), val); - hwwrite(vortex->mmio, WT_DELAY(wt, 1), val); - hwwrite(vortex->mmio, WT_DELAY(wt, 0), val); - return 0xc; - } - break; + /* delay */ + /* + printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", + WT_DELAY(wt,0), (int)val); + */ + hwwrite(vortex->mmio, WT_DELAY(wt, 3), val); + hwwrite(vortex->mmio, WT_DELAY(wt, 2), val); + hwwrite(vortex->mmio, WT_DELAY(wt, 1), val); + hwwrite(vortex->mmio, WT_DELAY(wt, 0), val); + return 0xc; /* Global WT block parameters */ case 5: /* sramp */ ecx = WT_SRAMP(wt); @@ -291,7 +283,6 @@ vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, break; default: return 0; - break; } /* printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", ecx, (int)val); diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index c8e12161159..1aef7128f7c 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -715,14 +715,14 @@ snd_azf3328_mixer_ac97_read(struct snd_ac97 *ac97, unsigned short reg_ac97) const struct snd_azf3328 *chip = ac97->private_data; unsigned short reg_azf = snd_azf3328_mixer_ac97_map_reg_idx(reg_ac97); unsigned short reg_val = 0; - bool unsupported = 0; + bool unsupported = false; snd_azf3328_dbgmixer( "snd_azf3328_mixer_ac97_read reg_ac97 %u\n", reg_ac97 ); if (reg_azf & AZF_AC97_REG_UNSUPPORTED) - unsupported = 1; + unsupported = true; else { if (reg_azf & AZF_AC97_REG_REAL_IO_READ) reg_val = snd_azf3328_mixer_inw(chip, @@ -759,7 +759,7 @@ snd_azf3328_mixer_ac97_read(struct snd_ac97 *ac97, unsigned short reg_ac97) reg_val = azf_emulated_ac97_vendor_id & 0xffff; break; default: - unsupported = 1; + unsupported = true; break; } } @@ -776,14 +776,14 @@ snd_azf3328_mixer_ac97_write(struct snd_ac97 *ac97, { const struct snd_azf3328 *chip = ac97->private_data; unsigned short reg_azf = snd_azf3328_mixer_ac97_map_reg_idx(reg_ac97); - bool unsupported = 0; + bool unsupported = false; snd_azf3328_dbgmixer( "snd_azf3328_mixer_ac97_write reg_ac97 %u val %u\n", reg_ac97, val ); if (reg_azf & AZF_AC97_REG_UNSUPPORTED) - unsupported = 1; + unsupported = true; else { if (reg_azf & AZF_AC97_REG_REAL_IO_WRITE) snd_azf3328_mixer_outw( @@ -808,7 +808,7 @@ snd_azf3328_mixer_ac97_write(struct snd_ac97 *ac97, */ break; default: - unsupported = 1; + unsupported = true; break; } } @@ -1559,7 +1559,7 @@ snd_azf3328_pcm_trigger(struct snd_pcm_substream *substream, int cmd) struct snd_azf3328_codec_data *codec = runtime->private_data; int result = 0; u16 flags1; - bool previously_muted = 0; + bool previously_muted = false; bool is_main_mixer_playback_codec = (AZF_CODEC_PLAYBACK == codec->type); snd_azf3328_dbgcalls("snd_azf3328_pcm_trigger cmd %d\n", cmd); diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c index 0c00eb4088e..84f86bf63b8 100644 --- a/sound/pci/ctxfi/ctdaio.c +++ b/sound/pci/ctxfi/ctdaio.c @@ -33,7 +33,7 @@ struct daio_rsc_idx { unsigned short right; }; -struct daio_rsc_idx idx_20k1[NUM_DAIOTYP] = { +static struct daio_rsc_idx idx_20k1[NUM_DAIOTYP] = { [LINEO1] = {.left = 0x00, .right = 0x01}, [LINEO2] = {.left = 0x18, .right = 0x19}, [LINEO3] = {.left = 0x08, .right = 0x09}, @@ -44,7 +44,7 @@ struct daio_rsc_idx idx_20k1[NUM_DAIOTYP] = { [SPDIFI1] = {.left = 0x95, .right = 0x9d}, }; -struct daio_rsc_idx idx_20k2[NUM_DAIOTYP] = { +static struct daio_rsc_idx idx_20k2[NUM_DAIOTYP] = { [LINEO1] = {.left = 0x40, .right = 0x41}, [LINEO2] = {.left = 0x60, .right = 0x61}, [LINEO3] = {.left = 0x50, .right = 0x51}, diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 6e9876f27d9..54d14793725 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -759,7 +759,7 @@ struct ca0132_spec { /* * CA0132 codec access */ -unsigned int codec_send_command(struct hda_codec *codec, hda_nid_t nid, +static unsigned int codec_send_command(struct hda_codec *codec, hda_nid_t nid, unsigned int verb, unsigned int parm, unsigned int *res) { unsigned int response; diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 50173d412ac..b899eba6f27 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -63,6 +63,7 @@ struct hdmi_spec_per_pin { hda_nid_t pin_nid; int num_mux_nids; hda_nid_t mux_nids[HDA_MAX_CONNECTIONS]; + hda_nid_t cvt_nid; struct hda_codec *codec; struct hdmi_eld sink_eld; @@ -595,25 +596,35 @@ static void hdmi_std_setup_channel_mapping(struct hda_codec *codec, bool non_pcm, int ca) { + struct cea_channel_speaker_allocation *ch_alloc; int i; int err; int order; int non_pcm_mapping[8]; order = get_channel_allocation_order(ca); + ch_alloc = &channel_allocations[order]; if (hdmi_channel_mapping[ca][1] == 0) { - for (i = 0; i < channel_allocations[order].channels; i++) - hdmi_channel_mapping[ca][i] = i | (i << 4); - for (; i < 8; i++) - hdmi_channel_mapping[ca][i] = 0xf | (i << 4); + int hdmi_slot = 0; + /* fill actual channel mappings in ALSA channel (i) order */ + for (i = 0; i < ch_alloc->channels; i++) { + while (!ch_alloc->speakers[7 - hdmi_slot] && !WARN_ON(hdmi_slot >= 8)) + hdmi_slot++; /* skip zero slots */ + + hdmi_channel_mapping[ca][i] = (i << 4) | hdmi_slot++; + } + /* fill the rest of the slots with ALSA channel 0xf */ + for (hdmi_slot = 0; hdmi_slot < 8; hdmi_slot++) + if (!ch_alloc->speakers[7 - hdmi_slot]) + hdmi_channel_mapping[ca][i++] = (0xf << 4) | hdmi_slot; } if (non_pcm) { - for (i = 0; i < channel_allocations[order].channels; i++) - non_pcm_mapping[i] = i | (i << 4); + for (i = 0; i < ch_alloc->channels; i++) + non_pcm_mapping[i] = (i << 4) | i; for (; i < 8; i++) - non_pcm_mapping[i] = 0xf | (i << 4); + non_pcm_mapping[i] = (0xf << 4) | i; } for (i = 0; i < 8; i++) { @@ -626,25 +637,31 @@ static void hdmi_std_setup_channel_mapping(struct hda_codec *codec, break; } } - - hdmi_debug_channel_mapping(codec, pin_nid); } struct channel_map_table { unsigned char map; /* ALSA API channel map position */ - unsigned char cea_slot; /* CEA slot value */ int spk_mask; /* speaker position bit mask */ }; static struct channel_map_table map_tables[] = { - { SNDRV_CHMAP_FL, 0x00, FL }, - { SNDRV_CHMAP_FR, 0x01, FR }, - { SNDRV_CHMAP_RL, 0x04, RL }, - { SNDRV_CHMAP_RR, 0x05, RR }, - { SNDRV_CHMAP_LFE, 0x02, LFE }, - { SNDRV_CHMAP_FC, 0x03, FC }, - { SNDRV_CHMAP_RLC, 0x06, RLC }, - { SNDRV_CHMAP_RRC, 0x07, RRC }, + { SNDRV_CHMAP_FL, FL }, + { SNDRV_CHMAP_FR, FR }, + { SNDRV_CHMAP_RL, RL }, + { SNDRV_CHMAP_RR, RR }, + { SNDRV_CHMAP_LFE, LFE }, + { SNDRV_CHMAP_FC, FC }, + { SNDRV_CHMAP_RLC, RLC }, + { SNDRV_CHMAP_RRC, RRC }, + { SNDRV_CHMAP_RC, RC }, + { SNDRV_CHMAP_FLC, FLC }, + { SNDRV_CHMAP_FRC, FRC }, + { SNDRV_CHMAP_FLH, FLH }, + { SNDRV_CHMAP_FRH, FRH }, + { SNDRV_CHMAP_FLW, FLW }, + { SNDRV_CHMAP_FRW, FRW }, + { SNDRV_CHMAP_TC, TC }, + { SNDRV_CHMAP_FCH, FCH }, {} /* terminator */ }; @@ -660,25 +677,19 @@ static int to_spk_mask(unsigned char c) } /* from ALSA API channel position to CEA slot */ -static int to_cea_slot(unsigned char c) +static int to_cea_slot(int ordered_ca, unsigned char pos) { - struct channel_map_table *t = map_tables; - for (; t->map; t++) { - if (t->map == c) - return t->cea_slot; - } - return 0x0f; -} + int mask = to_spk_mask(pos); + int i; -/* from CEA slot to ALSA API channel position */ -static int from_cea_slot(unsigned char c) -{ - struct channel_map_table *t = map_tables; - for (; t->map; t++) { - if (t->cea_slot == c) - return t->map; + if (mask) { + for (i = 0; i < 8; i++) { + if (channel_allocations[ordered_ca].speakers[7 - i] == mask) + return i; + } } - return 0; + + return -1; } /* from speaker bit mask to ALSA API channel position */ @@ -692,6 +703,14 @@ static int spk_to_chmap(int spk) return 0; } +/* from CEA slot to ALSA API channel position */ +static int from_cea_slot(int ordered_ca, unsigned char slot) +{ + int mask = channel_allocations[ordered_ca].speakers[7 - slot]; + + return spk_to_chmap(mask); +} + /* get the CA index corresponding to the given ALSA API channel map */ static int hdmi_manual_channel_allocation(int chs, unsigned char *map) { @@ -718,16 +737,27 @@ static int hdmi_manual_channel_allocation(int chs, unsigned char *map) /* set up the channel slots for the given ALSA API channel map */ static int hdmi_manual_setup_channel_mapping(struct hda_codec *codec, hda_nid_t pin_nid, - int chs, unsigned char *map) + int chs, unsigned char *map, + int ca) { - int i; - for (i = 0; i < 8; i++) { + int ordered_ca = get_channel_allocation_order(ca); + int alsa_pos, hdmi_slot; + int assignments[8] = {[0 ... 7] = 0xf}; + + for (alsa_pos = 0; alsa_pos < chs; alsa_pos++) { + + hdmi_slot = to_cea_slot(ordered_ca, map[alsa_pos]); + + if (hdmi_slot < 0) + continue; /* unassigned channel */ + + assignments[hdmi_slot] = alsa_pos; + } + + for (hdmi_slot = 0; hdmi_slot < 8; hdmi_slot++) { int val, err; - if (i < chs) - val = to_cea_slot(map[i]); - else - val = 0xf; - val |= (i << 4); + + val = (assignments[hdmi_slot] << 4) | hdmi_slot; err = snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_CHAN_SLOT, val); if (err) @@ -740,9 +770,10 @@ static int hdmi_manual_setup_channel_mapping(struct hda_codec *codec, static void hdmi_setup_fake_chmap(unsigned char *map, int ca) { int i; + int ordered_ca = get_channel_allocation_order(ca); for (i = 0; i < 8; i++) { - if (i < channel_allocations[ca].channels) - map[i] = from_cea_slot((hdmi_channel_mapping[ca][i] >> 4) & 0x0f); + if (i < channel_allocations[ordered_ca].channels) + map[i] = from_cea_slot(ordered_ca, hdmi_channel_mapping[ca][i] & 0x0f); else map[i] = 0; } @@ -755,11 +786,13 @@ static void hdmi_setup_channel_mapping(struct hda_codec *codec, { if (!non_pcm && chmap_set) { hdmi_manual_setup_channel_mapping(codec, pin_nid, - channels, map); + channels, map, ca); } else { hdmi_std_setup_channel_mapping(codec, pin_nid, non_pcm, ca); hdmi_setup_fake_chmap(map, ca); } + + hdmi_debug_channel_mapping(codec, pin_nid); } /* @@ -889,8 +922,9 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, { hda_nid_t pin_nid = per_pin->pin_nid; int channels = per_pin->channels; + int active_channels; struct hdmi_eld *eld; - int ca; + int ca, ordered_ca; union audio_infoframe ai; if (!channels) @@ -912,6 +946,11 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, if (ca < 0) ca = 0; + ordered_ca = get_channel_allocation_order(ca); + active_channels = channel_allocations[ordered_ca].channels; + + hdmi_set_channel_count(codec, per_pin->cvt_nid, active_channels); + memset(&ai, 0, sizeof(ai)); if (eld->info.conn_type == 0) { /* HDMI */ struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi; @@ -919,7 +958,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hdmi_ai->type = 0x84; hdmi_ai->ver = 0x01; hdmi_ai->len = 0x0a; - hdmi_ai->CC02_CT47 = channels - 1; + hdmi_ai->CC02_CT47 = active_channels - 1; hdmi_ai->CA = ca; hdmi_checksum_audio_infoframe(hdmi_ai); } else if (eld->info.conn_type == 1) { /* DisplayPort */ @@ -928,7 +967,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, dp_ai->type = 0x84; dp_ai->len = 0x1b; dp_ai->ver = 0x11 << 2; - dp_ai->CC02_CT47 = channels - 1; + dp_ai->CC02_CT47 = active_channels - 1; dp_ai->CA = ca; } else { snd_printd("HDMI: unknown connection type at pin %d\n", @@ -952,9 +991,9 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, if (!hdmi_infoframe_uptodate(codec, pin_nid, ai.bytes, sizeof(ai))) { snd_printdd("hdmi_setup_audio_infoframe: " - "pin=%d channels=%d\n", + "pin=%d channels=%d ca=0x%02x\n", pin_nid, - channels); + active_channels, ca); hdmi_stop_infoframe_trans(codec, pin_nid); hdmi_fill_audio_infoframe(codec, pin_nid, ai.bytes, sizeof(ai)); @@ -1217,6 +1256,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, per_cvt = get_cvt(spec, cvt_idx); /* Claim converter */ per_cvt->assigned = 1; + per_pin->cvt_nid = per_cvt->cvt_nid; hinfo->nid = per_cvt->cvt_nid; snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0, @@ -1539,8 +1579,6 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, per_pin->channels = substream->runtime->channels; per_pin->setup = true; - hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels); - hdmi_setup_audio_infoframe(codec, per_pin, non_pcm); return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); @@ -1618,8 +1656,6 @@ static int hdmi_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag, struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); struct hda_codec *codec = info->private_data; struct hdmi_spec *spec = codec->spec; - const unsigned int valid_mask = - FL | FR | RL | RR | LFE | FC | RLC | RRC; unsigned int __user *dst; int chs, count = 0; @@ -1637,8 +1673,6 @@ static int hdmi_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag, int chs_bytes = chs * 4; if (cap->channels != chs) continue; - if (cap->spk_mask & ~valid_mask) - continue; if (size < 8) return -ENOMEM; if (put_user(SNDRV_CTL_TLVT_CHMAP_VAR, dst) || diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 3cde55b753e..2907e68150c 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -3996,7 +3996,6 @@ static int hdspm_tco_sync_check(struct hdspm *hdspm) return 1; } return 0; - break; case AES32: status = hdspm_read(hdspm, HDSPM_statusRegister); if (status & HDSPM_tcoLockAes) { @@ -4006,9 +4005,6 @@ static int hdspm_tco_sync_check(struct hdspm *hdspm) return 1; } return 0; - - break; - case RayDAT: case AIO: status = hdspm_read(hdspm, HDSPM_RD_STATUS_1); @@ -4018,7 +4014,6 @@ static int hdspm_tco_sync_check(struct hdspm *hdspm) if (status & 0x4000000) return 1; /* Lock */ return 0; /* No signal */ - break; default: break; diff --git a/sound/usb/caiaq/control.c b/sound/usb/caiaq/control.c index ae6b50f9ed5..f65fc0987cf 100644 --- a/sound/usb/caiaq/control.c +++ b/sound/usb/caiaq/control.c @@ -28,6 +28,7 @@ #include "control.h" #define CNT_INTVAL 0x10000 +#define MASCHINE_BANK_SIZE 32 static int control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) @@ -105,6 +106,10 @@ static int control_put(struct snd_kcontrol *kcontrol, USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1)) cmd = EP1_CMD_DIMM_LEDS; + if (cdev->chip.usb_id == + USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER)) + cmd = EP1_CMD_DIMM_LEDS; + if (pos & CNT_INTVAL) { int i = pos & ~CNT_INTVAL; @@ -121,6 +126,20 @@ static int control_put(struct snd_kcontrol *kcontrol, usb_sndbulkpipe(cdev->chip.dev, 8), cdev->ep8_out_buf, sizeof(cdev->ep8_out_buf), &actual_len, 200); + } else if (cdev->chip.usb_id == + USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER)) { + + int bank = 0; + int offset = 0; + + if (i >= MASCHINE_BANK_SIZE) { + bank = 0x1e; + offset = MASCHINE_BANK_SIZE; + } + + snd_usb_caiaq_send_command_bank(cdev, cmd, bank, + cdev->control_state + offset, + MASCHINE_BANK_SIZE); } else { snd_usb_caiaq_send_command(cdev, cmd, cdev->control_state, sizeof(cdev->control_state)); @@ -490,6 +509,74 @@ static struct caiaq_controller kontrols4_controller[] = { { "LED: FX2: Mode", 133 | CNT_INTVAL }, }; +static struct caiaq_controller maschine_controller[] = { + { "LED: Pad 1", 3 | CNT_INTVAL }, + { "LED: Pad 2", 2 | CNT_INTVAL }, + { "LED: Pad 3", 1 | CNT_INTVAL }, + { "LED: Pad 4", 0 | CNT_INTVAL }, + { "LED: Pad 5", 7 | CNT_INTVAL }, + { "LED: Pad 6", 6 | CNT_INTVAL }, + { "LED: Pad 7", 5 | CNT_INTVAL }, + { "LED: Pad 8", 4 | CNT_INTVAL }, + { "LED: Pad 9", 11 | CNT_INTVAL }, + { "LED: Pad 10", 10 | CNT_INTVAL }, + { "LED: Pad 11", 9 | CNT_INTVAL }, + { "LED: Pad 12", 8 | CNT_INTVAL }, + { "LED: Pad 13", 15 | CNT_INTVAL }, + { "LED: Pad 14", 14 | CNT_INTVAL }, + { "LED: Pad 15", 13 | CNT_INTVAL }, + { "LED: Pad 16", 12 | CNT_INTVAL }, + + { "LED: Mute", 16 | CNT_INTVAL }, + { "LED: Solo", 17 | CNT_INTVAL }, + { "LED: Select", 18 | CNT_INTVAL }, + { "LED: Duplicate", 19 | CNT_INTVAL }, + { "LED: Navigate", 20 | CNT_INTVAL }, + { "LED: Pad Mode", 21 | CNT_INTVAL }, + { "LED: Pattern", 22 | CNT_INTVAL }, + { "LED: Scene", 23 | CNT_INTVAL }, + + { "LED: Shift", 24 | CNT_INTVAL }, + { "LED: Erase", 25 | CNT_INTVAL }, + { "LED: Grid", 26 | CNT_INTVAL }, + { "LED: Right Bottom", 27 | CNT_INTVAL }, + { "LED: Rec", 28 | CNT_INTVAL }, + { "LED: Play", 29 | CNT_INTVAL }, + { "LED: Left Bottom", 32 | CNT_INTVAL }, + { "LED: Restart", 33 | CNT_INTVAL }, + + { "LED: Group A", 41 | CNT_INTVAL }, + { "LED: Group B", 40 | CNT_INTVAL }, + { "LED: Group C", 37 | CNT_INTVAL }, + { "LED: Group D", 36 | CNT_INTVAL }, + { "LED: Group E", 39 | CNT_INTVAL }, + { "LED: Group F", 38 | CNT_INTVAL }, + { "LED: Group G", 35 | CNT_INTVAL }, + { "LED: Group H", 34 | CNT_INTVAL }, + + { "LED: Auto Write", 42 | CNT_INTVAL }, + { "LED: Snap", 43 | CNT_INTVAL }, + { "LED: Right Top", 44 | CNT_INTVAL }, + { "LED: Left Top", 45 | CNT_INTVAL }, + { "LED: Sampling", 46 | CNT_INTVAL }, + { "LED: Browse", 47 | CNT_INTVAL }, + { "LED: Step", 48 | CNT_INTVAL }, + { "LED: Control", 49 | CNT_INTVAL }, + + { "LED: Top Button 1", 57 | CNT_INTVAL }, + { "LED: Top Button 2", 56 | CNT_INTVAL }, + { "LED: Top Button 3", 55 | CNT_INTVAL }, + { "LED: Top Button 4", 54 | CNT_INTVAL }, + { "LED: Top Button 5", 53 | CNT_INTVAL }, + { "LED: Top Button 6", 52 | CNT_INTVAL }, + { "LED: Top Button 7", 51 | CNT_INTVAL }, + { "LED: Top Button 8", 50 | CNT_INTVAL }, + + { "LED: Note Repeat", 58 | CNT_INTVAL }, + + { "Backlight Display", 59 | CNT_INTVAL } +}; + static int add_controls(struct caiaq_controller *c, int num, struct snd_usb_caiaqdev *cdev) { @@ -553,6 +640,11 @@ int snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *cdev) ret = add_controls(kontrols4_controller, ARRAY_SIZE(kontrols4_controller), cdev); break; + + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): + ret = add_controls(maschine_controller, + ARRAY_SIZE(maschine_controller), cdev); + break; } return ret; diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index 1a61dd12fe3..bc55f708a69 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c @@ -235,6 +235,31 @@ int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *cdev, cdev->ep1_out_buf, len+1, &actual_len, 200); } +int snd_usb_caiaq_send_command_bank(struct snd_usb_caiaqdev *cdev, + unsigned char command, + unsigned char bank, + const unsigned char *buffer, + int len) +{ + int actual_len; + struct usb_device *usb_dev = cdev->chip.dev; + + if (!usb_dev) + return -EIO; + + if (len > EP1_BUFSIZE - 2) + len = EP1_BUFSIZE - 2; + + if (buffer && len > 0) + memcpy(cdev->ep1_out_buf+2, buffer, len); + + cdev->ep1_out_buf[0] = command; + cdev->ep1_out_buf[1] = bank; + + return usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, 1), + cdev->ep1_out_buf, len+2, &actual_len, 200); +} + int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *cdev, int rate, int depth, int bpp) { diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h index ad102fac694..ab0f7520a99 100644 --- a/sound/usb/caiaq/device.h +++ b/sound/usb/caiaq/device.h @@ -128,5 +128,10 @@ int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *cdev, unsigned char command, const unsigned char *buffer, int len); +int snd_usb_caiaq_send_command_bank(struct snd_usb_caiaqdev *cdev, + unsigned char command, + unsigned char bank, + const unsigned char *buffer, + int len); #endif /* CAIAQ_DEVICE_H */ diff --git a/sound/usb/card.c b/sound/usb/card.c index 64952e2d3ed..9d9de8d5346 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -79,7 +79,6 @@ static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card * /* Vendor/product IDs for this card */ static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; -static int nrpacks = 8; /* max. number of packets per urb */ static int device_setup[SNDRV_CARDS]; /* device parameter for this card */ static bool ignore_ctl_error; static bool autoclock = true; @@ -94,8 +93,6 @@ module_param_array(vid, int, NULL, 0444); MODULE_PARM_DESC(vid, "Vendor ID for the USB audio device."); module_param_array(pid, int, NULL, 0444); MODULE_PARM_DESC(pid, "Product ID for the USB audio device."); -module_param(nrpacks, int, 0644); -MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB."); module_param_array(device_setup, int, NULL, 0444); MODULE_PARM_DESC(device_setup, "Specific device setup (if needed)."); module_param(ignore_ctl_error, bool, 0444); @@ -349,6 +346,7 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx, case USB_SPEED_LOW: case USB_SPEED_FULL: case USB_SPEED_HIGH: + case USB_SPEED_WIRELESS: case USB_SPEED_SUPER: break; default: @@ -374,7 +372,6 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx, chip->dev = dev; chip->card = card; chip->setup = device_setup[idx]; - chip->nrpacks = nrpacks; chip->autoclock = autoclock; chip->probing = 1; @@ -756,10 +753,6 @@ static struct usb_driver usb_audio_driver = { static int __init snd_usb_audio_init(void) { - if (nrpacks < 1 || nrpacks > MAX_PACKS) { - printk(KERN_WARNING "invalid nrpacks value.\n"); - return -EINVAL; - } return usb_register(&usb_audio_driver); } diff --git a/sound/usb/card.h b/sound/usb/card.h index 5ecacaa90b5..9867ab86685 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h @@ -2,11 +2,11 @@ #define __USBAUDIO_CARD_H #define MAX_NR_RATES 1024 -#define MAX_PACKS 20 +#define MAX_PACKS 6 /* per URB */ #define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */ -#define MAX_URBS 8 +#define MAX_URBS 12 #define SYNC_URBS 4 /* always four urbs for sync */ -#define MAX_QUEUE 24 /* try not to exceed this queue length, in ms */ +#define MAX_QUEUE 18 /* try not to exceed this queue length, in ms */ struct audioformat { struct list_head list; @@ -87,6 +87,7 @@ struct snd_usb_endpoint { unsigned int phase; /* phase accumulator */ unsigned int maxpacksize; /* max packet size in bytes */ unsigned int maxframesize; /* max packet size in frames */ + unsigned int max_urb_frames; /* max URB size in frames */ unsigned int curpacksize; /* current packet size in bytes (for capture) */ unsigned int curframesize; /* current packet size in frames (for capture) */ unsigned int syncmaxsize; /* sync endpoint packet size */ @@ -95,7 +96,7 @@ struct snd_usb_endpoint { unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */ unsigned char silence_value; unsigned int stride; - int iface, alt_idx; + int iface, altsetting; int skip_packets; /* quirks for devices to ignore the first n packets in a stream */ @@ -116,6 +117,8 @@ struct snd_usb_substream { unsigned int channels_max; /* max channels in the all audiofmts */ unsigned int cur_rate; /* current rate (for hw_params callback) */ unsigned int period_bytes; /* current period bytes (for hw_params callback) */ + unsigned int period_frames; /* current frames per period */ + unsigned int buffer_periods; /* current periods per buffer */ unsigned int altset_idx; /* USB data format: index of alternate setting */ unsigned int txfr_quirk:1; /* allow sub-frame alignment */ unsigned int fmt_type; /* USB audio format type (1-3) */ @@ -125,6 +128,7 @@ struct snd_usb_substream { unsigned int hwptr_done; /* processed byte position in the buffer */ unsigned int transfer_done; /* processed frames since last period update */ + unsigned int frame_limit; /* limits number of packets in URB */ /* data and sync endpoints for this stream */ unsigned int ep_num; /* the endpoint number */ diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 93e970f2b3c..b9ba0fcc45d 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -33,7 +33,6 @@ #include "pcm.h" #include "quirks.h" -#define EP_FLAG_ACTIVATED 0 #define EP_FLAG_RUNNING 1 #define EP_FLAG_STOPPING 2 @@ -426,9 +425,9 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, list_for_each_entry(ep, &chip->ep_list, list) { if (ep->ep_num == ep_num && ep->iface == alts->desc.bInterfaceNumber && - ep->alt_idx == alts->desc.bAlternateSetting) { + ep->altsetting == alts->desc.bAlternateSetting) { snd_printdd(KERN_DEBUG "Re-using EP %x in iface %d,%d @%p\n", - ep_num, ep->iface, ep->alt_idx, ep); + ep_num, ep->iface, ep->altsetting, ep); goto __exit_unlock; } } @@ -447,7 +446,7 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, ep->type = type; ep->ep_num = ep_num; ep->iface = alts->desc.bInterfaceNumber; - ep->alt_idx = alts->desc.bAlternateSetting; + ep->altsetting = alts->desc.bAlternateSetting; INIT_LIST_HEAD(&ep->ready_playback_urbs); ep_num &= USB_ENDPOINT_NUMBER_MASK; @@ -574,11 +573,14 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, snd_pcm_format_t pcm_format, unsigned int channels, unsigned int period_bytes, + unsigned int frames_per_period, + unsigned int periods_per_buffer, struct audioformat *fmt, struct snd_usb_endpoint *sync_ep) { - unsigned int maxsize, i, urb_packs, total_packs, packs_per_ms; - int is_playback = usb_pipeout(ep->pipe); + unsigned int maxsize, minsize, packs_per_ms, max_packs_per_urb; + unsigned int max_packs_per_period, urbs_per_period, urb_packs; + unsigned int max_urbs, i; int frame_bits = snd_pcm_format_physical_width(pcm_format) * channels; if (pcm_format == SNDRV_PCM_FORMAT_DSD_U16_LE && fmt->dsd_dop) { @@ -611,58 +613,67 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, else ep->curpacksize = maxsize; - if (snd_usb_get_speed(ep->chip->dev) != USB_SPEED_FULL) + if (snd_usb_get_speed(ep->chip->dev) != USB_SPEED_FULL) { packs_per_ms = 8 >> ep->datainterval; - else - packs_per_ms = 1; - - if (is_playback && !snd_usb_endpoint_implicit_feedback_sink(ep)) { - urb_packs = max(ep->chip->nrpacks, 1); - urb_packs = min(urb_packs, (unsigned int) MAX_PACKS); + max_packs_per_urb = MAX_PACKS_HS; } else { - urb_packs = 1; + packs_per_ms = 1; + max_packs_per_urb = MAX_PACKS; } + if (sync_ep && !snd_usb_endpoint_implicit_feedback_sink(ep)) + max_packs_per_urb = min(max_packs_per_urb, + 1U << sync_ep->syncinterval); + max_packs_per_urb = max(1u, max_packs_per_urb >> ep->datainterval); - urb_packs *= packs_per_ms; + /* + * Capture endpoints need to use small URBs because there's no way + * to tell in advance where the next period will end, and we don't + * want the next URB to complete much after the period ends. + * + * Playback endpoints with implicit sync much use the same parameters + * as their corresponding capture endpoint. + */ + if (usb_pipein(ep->pipe) || + snd_usb_endpoint_implicit_feedback_sink(ep)) { - if (sync_ep && !snd_usb_endpoint_implicit_feedback_sink(ep)) - urb_packs = min(urb_packs, 1U << sync_ep->syncinterval); + /* make capture URBs <= 1 ms and smaller than a period */ + urb_packs = min(max_packs_per_urb, packs_per_ms); + while (urb_packs > 1 && urb_packs * maxsize >= period_bytes) + urb_packs >>= 1; + ep->nurbs = MAX_URBS; - /* decide how many packets to be used */ - if (is_playback && !snd_usb_endpoint_implicit_feedback_sink(ep)) { - unsigned int minsize, maxpacks; + /* + * Playback endpoints without implicit sync are adjusted so that + * a period fits as evenly as possible in the smallest number of + * URBs. The total number of URBs is adjusted to the size of the + * ALSA buffer, subject to the MAX_URBS and MAX_QUEUE limits. + */ + } else { /* determine how small a packet can be */ - minsize = (ep->freqn >> (16 - ep->datainterval)) - * (frame_bits >> 3); + minsize = (ep->freqn >> (16 - ep->datainterval)) * + (frame_bits >> 3); /* with sync from device, assume it can be 12% lower */ if (sync_ep) minsize -= minsize >> 3; minsize = max(minsize, 1u); - total_packs = (period_bytes + minsize - 1) / minsize; - /* we need at least two URBs for queueing */ - if (total_packs < 2) { - total_packs = 2; - } else { - /* and we don't want too long a queue either */ - maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2); - total_packs = min(total_packs, maxpacks); - } - } else { - while (urb_packs > 1 && urb_packs * maxsize >= period_bytes) - urb_packs >>= 1; - total_packs = MAX_URBS * urb_packs; - } - ep->nurbs = (total_packs + urb_packs - 1) / urb_packs; - if (ep->nurbs > MAX_URBS) { - /* too much... */ - ep->nurbs = MAX_URBS; - total_packs = MAX_URBS * urb_packs; - } else if (ep->nurbs < 2) { - /* too little - we need at least two packets - * to ensure contiguous playback/capture - */ - ep->nurbs = 2; + /* how many packets will contain an entire ALSA period? */ + max_packs_per_period = DIV_ROUND_UP(period_bytes, minsize); + + /* how many URBs will contain a period? */ + urbs_per_period = DIV_ROUND_UP(max_packs_per_period, + max_packs_per_urb); + /* how many packets are needed in each URB? */ + urb_packs = DIV_ROUND_UP(max_packs_per_period, urbs_per_period); + + /* limit the number of frames in a single URB */ + ep->max_urb_frames = DIV_ROUND_UP(frames_per_period, + urbs_per_period); + + /* try to use enough URBs to contain an entire ALSA buffer */ + max_urbs = min((unsigned) MAX_URBS, + MAX_QUEUE * packs_per_ms / urb_packs); + ep->nurbs = min(max_urbs, urbs_per_period * periods_per_buffer); } /* allocate and initialize data urbs */ @@ -670,8 +681,7 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, struct snd_urb_ctx *u = &ep->urb[i]; u->index = i; u->ep = ep; - u->packets = (i + 1) * total_packs / ep->nurbs - - i * total_packs / ep->nurbs; + u->packets = urb_packs; u->buffer_size = maxsize * u->packets; if (fmt->fmt_type == UAC_FORMAT_TYPE_II) @@ -703,8 +713,7 @@ out_of_memory: /* * configure a sync endpoint */ -static int sync_ep_set_params(struct snd_usb_endpoint *ep, - struct audioformat *fmt) +static int sync_ep_set_params(struct snd_usb_endpoint *ep) { int i; @@ -748,6 +757,8 @@ out_of_memory: * @pcm_format: the audio fomat. * @channels: the number of audio channels. * @period_bytes: the number of bytes in one alsa period. + * @period_frames: the number of frames in one alsa period. + * @buffer_periods: the number of periods in one alsa buffer. * @rate: the frame rate. * @fmt: the USB audio format information * @sync_ep: the sync endpoint to use, if any @@ -760,6 +771,8 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, snd_pcm_format_t pcm_format, unsigned int channels, unsigned int period_bytes, + unsigned int period_frames, + unsigned int buffer_periods, unsigned int rate, struct audioformat *fmt, struct snd_usb_endpoint *sync_ep) @@ -793,10 +806,11 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, switch (ep->type) { case SND_USB_ENDPOINT_TYPE_DATA: err = data_ep_set_params(ep, pcm_format, channels, - period_bytes, fmt, sync_ep); + period_bytes, period_frames, + buffer_periods, fmt, sync_ep); break; case SND_USB_ENDPOINT_TYPE_SYNC: - err = sync_ep_set_params(ep, fmt); + err = sync_ep_set_params(ep); break; default: err = -EINVAL; @@ -931,28 +945,21 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep) * * @ep: the endpoint to deactivate * - * If the endpoint is not currently in use, this functions will select the - * alternate interface setting 0 for the interface of this endpoint. + * If the endpoint is not currently in use, this functions will + * deactivate its associated URBs. * * In case of any active users, this functions does nothing. - * - * Returns an error if usb_set_interface() failed, 0 in all other - * cases. */ -int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep) +void snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep) { if (!ep) - return -EINVAL; - - deactivate_urbs(ep, true); - wait_clear_urbs(ep); + return; if (ep->use_count != 0) - return 0; - - clear_bit(EP_FLAG_ACTIVATED, &ep->flags); + return; - return 0; + deactivate_urbs(ep, true); + wait_clear_urbs(ep); } /** diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h index 2287adf5ca5..1c7e8ee48ab 100644 --- a/sound/usb/endpoint.h +++ b/sound/usb/endpoint.h @@ -12,6 +12,8 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, snd_pcm_format_t pcm_format, unsigned int channels, unsigned int period_bytes, + unsigned int period_frames, + unsigned int buffer_periods, unsigned int rate, struct audioformat *fmt, struct snd_usb_endpoint *sync_ep); @@ -20,7 +22,7 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep); void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep); void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep); int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); -int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); +void snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); void snd_usb_endpoint_free(struct list_head *head); int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep); diff --git a/sound/usb/helper.c b/sound/usb/helper.c index 620902463c6..51ed1ac825f 100644 --- a/sound/usb/helper.c +++ b/sound/usb/helper.c @@ -118,6 +118,7 @@ unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip, { switch (snd_usb_get_speed(chip->dev)) { case USB_SPEED_HIGH: + case USB_SPEED_WIRELESS: case USB_SPEED_SUPER: if (get_endpoint(alts, 0)->bInterval >= 1 && get_endpoint(alts, 0)->bInterval <= 4) diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 95558ef4a7a..44b0ba4feab 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1151,14 +1151,14 @@ static void check_no_speaker_on_headset(struct snd_kcontrol *kctl, const char *names_to_check[] = { "Headset", "headset", "Headphone", "headphone", NULL}; const char **s; - bool found = 0; + bool found = false; if (strcmp("Speaker", kctl->id.name)) return; for (s = names_to_check; *s; s++) if (strstr(card->shortname, *s)) { - found = 1; + found = true; break; } diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index b375d58871e..ca3256d6fde 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -241,16 +241,17 @@ static int start_endpoints(struct snd_usb_substream *subs, bool can_sleep) struct snd_usb_endpoint *ep = subs->sync_endpoint; if (subs->data_endpoint->iface != subs->sync_endpoint->iface || - subs->data_endpoint->alt_idx != subs->sync_endpoint->alt_idx) { + subs->data_endpoint->altsetting != subs->sync_endpoint->altsetting) { err = usb_set_interface(subs->dev, subs->sync_endpoint->iface, - subs->sync_endpoint->alt_idx); + subs->sync_endpoint->altsetting); if (err < 0) { + clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags); snd_printk(KERN_ERR "%d:%d:%d: cannot set interface (%d)\n", subs->dev->devnum, subs->sync_endpoint->iface, - subs->sync_endpoint->alt_idx, err); + subs->sync_endpoint->altsetting, err); return -EIO; } } @@ -282,22 +283,6 @@ static void stop_endpoints(struct snd_usb_substream *subs, bool wait) } } -static int deactivate_endpoints(struct snd_usb_substream *subs) -{ - int reta, retb; - - reta = snd_usb_endpoint_deactivate(subs->sync_endpoint); - retb = snd_usb_endpoint_deactivate(subs->data_endpoint); - - if (reta < 0) - return reta; - - if (retb < 0) - return retb; - - return 0; -} - static int search_roland_implicit_fb(struct usb_device *dev, int ifnum, unsigned int altsetting, struct usb_host_interface **alts, @@ -595,6 +580,7 @@ static int configure_sync_endpoint(struct snd_usb_substream *subs) subs->pcm_format, subs->channels, subs->period_bytes, + 0, 0, subs->cur_rate, subs->cur_audiofmt, NULL); @@ -631,6 +617,7 @@ static int configure_sync_endpoint(struct snd_usb_substream *subs) subs->pcm_format, sync_fp->channels, sync_period_bytes, + 0, 0, subs->cur_rate, sync_fp, NULL); @@ -653,6 +640,8 @@ static int configure_endpoint(struct snd_usb_substream *subs) subs->pcm_format, subs->channels, subs->period_bytes, + subs->period_frames, + subs->buffer_periods, subs->cur_rate, subs->cur_audiofmt, subs->sync_endpoint); @@ -689,6 +678,8 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, subs->pcm_format = params_format(hw_params); subs->period_bytes = params_period_bytes(hw_params); + subs->period_frames = params_period_size(hw_params); + subs->buffer_periods = params_periods(hw_params); subs->channels = params_channels(hw_params); subs->cur_rate = params_rate(hw_params); @@ -730,7 +721,8 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream) down_read(&subs->stream->chip->shutdown_rwsem); if (!subs->stream->chip->shutdown) { stop_endpoints(subs, true); - deactivate_endpoints(subs); + snd_usb_endpoint_deactivate(subs->sync_endpoint); + snd_usb_endpoint_deactivate(subs->data_endpoint); } up_read(&subs->stream->chip->shutdown_rwsem); return snd_pcm_lib_free_vmalloc_buffer(substream); @@ -1363,6 +1355,7 @@ static void prepare_playback_urb(struct snd_usb_substream *subs, frames = 0; urb->number_of_packets = 0; spin_lock_irqsave(&subs->lock, flags); + subs->frame_limit += ep->max_urb_frames; for (i = 0; i < ctx->packets; i++) { if (ctx->packet_size[i]) counts = ctx->packet_size[i]; @@ -1377,6 +1370,7 @@ static void prepare_playback_urb(struct snd_usb_substream *subs, subs->transfer_done += counts; if (subs->transfer_done >= runtime->period_size) { subs->transfer_done -= runtime->period_size; + subs->frame_limit = 0; period_elapsed = 1; if (subs->fmt_type == UAC_FORMAT_TYPE_II) { if (subs->transfer_done > 0) { @@ -1399,8 +1393,10 @@ static void prepare_playback_urb(struct snd_usb_substream *subs, break; } } - if (period_elapsed && - !snd_usb_endpoint_implicit_feedback_sink(subs->data_endpoint)) /* finish at the period boundary */ + /* finish at the period boundary or after enough frames */ + if ((period_elapsed || + subs->transfer_done >= subs->frame_limit) && + !snd_usb_endpoint_implicit_feedback_sink(ep)) break; } bytes = frames * ep->stride; diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index caabe9b3af4..5d2fe053074 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -55,7 +55,6 @@ struct snd_usb_audio { struct list_head mixer_list; /* list of mixer interfaces */ int setup; /* from the 'device_setup' module param */ - int nrpacks; /* from the 'nrpacks' module param */ bool autoclock; /* from the 'autoclock' module param */ struct usb_host_interface *ctrl_intf; /* the audio control interface */ |