diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-01-21 03:37:25 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-01-21 03:37:25 -0500 |
| commit | 5eb11d6b3f55eb4d28c51ea7f641c0e5e255a70f (patch) | |
| tree | de03ecad50a4d2633e13d972a321e2c05ed0ad93 | |
| parent | 479459a86ca554e1dee39bda767b13664c70eeb4 (diff) | |
| parent | 6455931186bff407493135e74c5f32efd30860e2 (diff) | |
Merge tag 'sound-3.19-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai:
"This batch contains two fixes for FireWire lib module and a quirk for
yet another Logitech WebCam. The former is the fixes for MIDI
handling I forgot to pick up during the merge window. All the fixed
code is pretty local and shouldn't give any regressions"
* tag 'sound-3.19-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
ALSA: usb-audio: Add mic volume fix quirk for Logitech Webcam C210
ALSA: firewire-lib: limit the MIDI data rate
ALSA: firewire-lib: remove rx_blocks_for_midi quirk
| -rw-r--r-- | sound/firewire/amdtp.c | 71 | ||||
| -rw-r--r-- | sound/firewire/amdtp.h | 5 | ||||
| -rw-r--r-- | sound/firewire/bebob/bebob_stream.c | 7 | ||||
| -rw-r--r-- | sound/firewire/fireworks/fireworks_stream.c | 5 | ||||
| -rw-r--r-- | sound/usb/mixer.c | 1 |
5 files changed, 65 insertions, 24 deletions
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index 3badc70124ab..0d580186ef1a 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c | |||
| @@ -21,7 +21,19 @@ | |||
| 21 | #define CYCLES_PER_SECOND 8000 | 21 | #define CYCLES_PER_SECOND 8000 |
| 22 | #define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND) | 22 | #define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND) |
| 23 | 23 | ||
| 24 | #define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 µs */ | 24 | /* |
| 25 | * Nominally 3125 bytes/second, but the MIDI port's clock might be | ||
| 26 | * 1% too slow, and the bus clock 100 ppm too fast. | ||
| 27 | */ | ||
| 28 | #define MIDI_BYTES_PER_SECOND 3093 | ||
| 29 | |||
| 30 | /* | ||
| 31 | * Several devices look only at the first eight data blocks. | ||
| 32 | * In any case, this is more than enough for the MIDI data rate. | ||
| 33 | */ | ||
| 34 | #define MAX_MIDI_RX_BLOCKS 8 | ||
| 35 | |||
| 36 | #define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 µs */ | ||
| 25 | 37 | ||
| 26 | /* isochronous header parameters */ | 38 | /* isochronous header parameters */ |
| 27 | #define ISO_DATA_LENGTH_SHIFT 16 | 39 | #define ISO_DATA_LENGTH_SHIFT 16 |
| @@ -78,8 +90,6 @@ int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, | |||
| 78 | s->callbacked = false; | 90 | s->callbacked = false; |
| 79 | s->sync_slave = NULL; | 91 | s->sync_slave = NULL; |
| 80 | 92 | ||
| 81 | s->rx_blocks_for_midi = UINT_MAX; | ||
| 82 | |||
| 83 | return 0; | 93 | return 0; |
| 84 | } | 94 | } |
| 85 | EXPORT_SYMBOL(amdtp_stream_init); | 95 | EXPORT_SYMBOL(amdtp_stream_init); |
| @@ -222,6 +232,14 @@ sfc_found: | |||
| 222 | for (i = 0; i < pcm_channels; i++) | 232 | for (i = 0; i < pcm_channels; i++) |
| 223 | s->pcm_positions[i] = i; | 233 | s->pcm_positions[i] = i; |
| 224 | s->midi_position = s->pcm_channels; | 234 | s->midi_position = s->pcm_channels; |
| 235 | |||
| 236 | /* | ||
| 237 | * We do not know the actual MIDI FIFO size of most devices. Just | ||
| 238 | * assume two bytes, i.e., one byte can be received over the bus while | ||
| 239 | * the previous one is transmitted over MIDI. | ||
| 240 | * (The value here is adjusted for midi_ratelimit_per_packet().) | ||
| 241 | */ | ||
| 242 | s->midi_fifo_limit = rate - MIDI_BYTES_PER_SECOND * s->syt_interval + 1; | ||
| 225 | } | 243 | } |
| 226 | EXPORT_SYMBOL(amdtp_stream_set_parameters); | 244 | EXPORT_SYMBOL(amdtp_stream_set_parameters); |
| 227 | 245 | ||
| @@ -463,6 +481,36 @@ static void amdtp_fill_pcm_silence(struct amdtp_stream *s, | |||
| 463 | } | 481 | } |
| 464 | } | 482 | } |
| 465 | 483 | ||
| 484 | /* | ||
| 485 | * To avoid sending MIDI bytes at too high a rate, assume that the receiving | ||
| 486 | * device has a FIFO, and track how much it is filled. This values increases | ||
| 487 | * by one whenever we send one byte in a packet, but the FIFO empties at | ||
| 488 | * a constant rate independent of our packet rate. One packet has syt_interval | ||
| 489 | * samples, so the number of bytes that empty out of the FIFO, per packet(!), | ||
| 490 | * is MIDI_BYTES_PER_SECOND * syt_interval / sample_rate. To avoid storing | ||
| 491 | * fractional values, the values in midi_fifo_used[] are measured in bytes | ||
| 492 | * multiplied by the sample rate. | ||
| 493 | */ | ||
| 494 | static bool midi_ratelimit_per_packet(struct amdtp_stream *s, unsigned int port) | ||
| 495 | { | ||
| 496 | int used; | ||
| 497 | |||
| 498 | used = s->midi_fifo_used[port]; | ||
| 499 | if (used == 0) /* common shortcut */ | ||
| 500 | return true; | ||
| 501 | |||
| 502 | used -= MIDI_BYTES_PER_SECOND * s->syt_interval; | ||
| 503 | used = max(used, 0); | ||
| 504 | s->midi_fifo_used[port] = used; | ||
| 505 | |||
| 506 | return used < s->midi_fifo_limit; | ||
| 507 | } | ||
| 508 | |||
| 509 | static void midi_rate_use_one_byte(struct amdtp_stream *s, unsigned int port) | ||
| 510 | { | ||
| 511 | s->midi_fifo_used[port] += amdtp_rate_table[s->sfc]; | ||
| 512 | } | ||
| 513 | |||
| 466 | static void amdtp_fill_midi(struct amdtp_stream *s, | 514 | static void amdtp_fill_midi(struct amdtp_stream *s, |
| 467 | __be32 *buffer, unsigned int frames) | 515 | __be32 *buffer, unsigned int frames) |
| 468 | { | 516 | { |
| @@ -470,16 +518,21 @@ static void amdtp_fill_midi(struct amdtp_stream *s, | |||
| 470 | u8 *b; | 518 | u8 *b; |
| 471 | 519 | ||
| 472 | for (f = 0; f < frames; f++) { | 520 | for (f = 0; f < frames; f++) { |
| 473 | buffer[s->midi_position] = 0; | ||
| 474 | b = (u8 *)&buffer[s->midi_position]; | 521 | b = (u8 *)&buffer[s->midi_position]; |
| 475 | 522 | ||
| 476 | port = (s->data_block_counter + f) % 8; | 523 | port = (s->data_block_counter + f) % 8; |
| 477 | if ((f >= s->rx_blocks_for_midi) || | 524 | if (f < MAX_MIDI_RX_BLOCKS && |
| 478 | (s->midi[port] == NULL) || | 525 | midi_ratelimit_per_packet(s, port) && |
| 479 | (snd_rawmidi_transmit(s->midi[port], b + 1, 1) <= 0)) | 526 | s->midi[port] != NULL && |
| 480 | b[0] = 0x80; | 527 | snd_rawmidi_transmit(s->midi[port], &b[1], 1) == 1) { |
| 481 | else | 528 | midi_rate_use_one_byte(s, port); |
| 482 | b[0] = 0x81; | 529 | b[0] = 0x81; |
| 530 | } else { | ||
| 531 | b[0] = 0x80; | ||
| 532 | b[1] = 0; | ||
| 533 | } | ||
| 534 | b[2] = 0; | ||
| 535 | b[3] = 0; | ||
| 483 | 536 | ||
| 484 | buffer += s->data_block_quadlets; | 537 | buffer += s->data_block_quadlets; |
| 485 | } | 538 | } |
diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h index e6e8926275b0..8a03a91e728b 100644 --- a/sound/firewire/amdtp.h +++ b/sound/firewire/amdtp.h | |||
| @@ -148,13 +148,12 @@ struct amdtp_stream { | |||
| 148 | bool double_pcm_frames; | 148 | bool double_pcm_frames; |
| 149 | 149 | ||
| 150 | struct snd_rawmidi_substream *midi[AMDTP_MAX_CHANNELS_FOR_MIDI * 8]; | 150 | struct snd_rawmidi_substream *midi[AMDTP_MAX_CHANNELS_FOR_MIDI * 8]; |
| 151 | int midi_fifo_limit; | ||
| 152 | int midi_fifo_used[AMDTP_MAX_CHANNELS_FOR_MIDI * 8]; | ||
| 151 | 153 | ||
| 152 | /* quirk: fixed interval of dbc between previos/current packets. */ | 154 | /* quirk: fixed interval of dbc between previos/current packets. */ |
| 153 | unsigned int tx_dbc_interval; | 155 | unsigned int tx_dbc_interval; |
| 154 | 156 | ||
| 155 | /* quirk: the first count of data blocks in an rx packet for MIDI */ | ||
| 156 | unsigned int rx_blocks_for_midi; | ||
| 157 | |||
| 158 | bool callbacked; | 157 | bool callbacked; |
| 159 | wait_queue_head_t callback_wait; | 158 | wait_queue_head_t callback_wait; |
| 160 | struct amdtp_stream *sync_slave; | 159 | struct amdtp_stream *sync_slave; |
diff --git a/sound/firewire/bebob/bebob_stream.c b/sound/firewire/bebob/bebob_stream.c index 1aab0a32870c..0ebcabfdc7ce 100644 --- a/sound/firewire/bebob/bebob_stream.c +++ b/sound/firewire/bebob/bebob_stream.c | |||
| @@ -484,13 +484,6 @@ int snd_bebob_stream_init_duplex(struct snd_bebob *bebob) | |||
| 484 | amdtp_stream_destroy(&bebob->rx_stream); | 484 | amdtp_stream_destroy(&bebob->rx_stream); |
| 485 | destroy_both_connections(bebob); | 485 | destroy_both_connections(bebob); |
| 486 | } | 486 | } |
| 487 | /* | ||
| 488 | * The firmware for these devices ignore MIDI messages in more than | ||
| 489 | * first 8 data blocks of an received AMDTP packet. | ||
| 490 | */ | ||
| 491 | if (bebob->spec == &maudio_fw410_spec || | ||
| 492 | bebob->spec == &maudio_special_spec) | ||
| 493 | bebob->rx_stream.rx_blocks_for_midi = 8; | ||
| 494 | end: | 487 | end: |
| 495 | return err; | 488 | return err; |
| 496 | } | 489 | } |
diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c index b985fc5ebdc6..4f440e163667 100644 --- a/sound/firewire/fireworks/fireworks_stream.c +++ b/sound/firewire/fireworks/fireworks_stream.c | |||
| @@ -179,11 +179,6 @@ int snd_efw_stream_init_duplex(struct snd_efw *efw) | |||
| 179 | destroy_stream(efw, &efw->tx_stream); | 179 | destroy_stream(efw, &efw->tx_stream); |
| 180 | goto end; | 180 | goto end; |
| 181 | } | 181 | } |
| 182 | /* | ||
| 183 | * Fireworks ignores MIDI messages in more than first 8 data | ||
| 184 | * blocks of an received AMDTP packet. | ||
| 185 | */ | ||
| 186 | efw->rx_stream.rx_blocks_for_midi = 8; | ||
| 187 | 182 | ||
| 188 | /* set IEC61883 compliant mode (actually not fully compliant...) */ | 183 | /* set IEC61883 compliant mode (actually not fully compliant...) */ |
| 189 | err = snd_efw_command_set_tx_mode(efw, SND_EFW_TRANSPORT_MODE_IEC61883); | 184 | err = snd_efw_command_set_tx_mode(efw, SND_EFW_TRANSPORT_MODE_IEC61883); |
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 41650d5b93b7..3e2ef61c627b 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
| @@ -913,6 +913,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, | |||
| 913 | case USB_ID(0x046d, 0x0807): /* Logitech Webcam C500 */ | 913 | case USB_ID(0x046d, 0x0807): /* Logitech Webcam C500 */ |
| 914 | case USB_ID(0x046d, 0x0808): | 914 | case USB_ID(0x046d, 0x0808): |
| 915 | case USB_ID(0x046d, 0x0809): | 915 | case USB_ID(0x046d, 0x0809): |
| 916 | case USB_ID(0x046d, 0x0819): /* Logitech Webcam C210 */ | ||
| 916 | case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */ | 917 | case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */ |
| 917 | case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ | 918 | case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ |
| 918 | case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */ | 919 | case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */ |
