diff options
author | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2014-04-25 09:44:51 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2014-05-26 08:15:10 -0400 |
commit | 10550bea44a8d7cec8a503c8f91fb6014e7849e9 (patch) | |
tree | 9542b85416d83cbbbb58635c479e5a8c8fa9b2dd | |
parent | 77d2a8a4f61c158ca34db167e5a9d57ceec0f0df (diff) |
ALSA: dice/firewire-lib: Keep dualwire mode but obsolete CIP_HI_DUALWIRE
In previous commit, AMDTP functionality in firewire-lib supports mapping
for PCM data channels. With this mapping, firewire-lib can obsolete
a flag, CIP_HI_DUALWIRE, but Dice driver still keeps dual wire mode.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/firewire/amdtp.c | 151 | ||||
-rw-r--r-- | sound/firewire/amdtp.h | 8 | ||||
-rw-r--r-- | sound/firewire/dice.c | 33 |
3 files changed, 34 insertions, 158 deletions
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index 9cf81b2b4298..3475b76b3304 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c | |||
@@ -145,14 +145,7 @@ void amdtp_stream_set_parameters(struct amdtp_stream *s, | |||
145 | return; | 145 | return; |
146 | 146 | ||
147 | sfc_found: | 147 | sfc_found: |
148 | s->dual_wire = (s->flags & CIP_HI_DUALWIRE) && sfc > CIP_SFC_96000; | 148 | s->pcm_channels = pcm_channels; |
149 | if (s->dual_wire) { | ||
150 | sfc -= 2; | ||
151 | rate /= 2; | ||
152 | s->pcm_channels = pcm_channels * 2; | ||
153 | } else { | ||
154 | s->pcm_channels = pcm_channels; | ||
155 | } | ||
156 | s->sfc = sfc; | 149 | s->sfc = sfc; |
157 | s->data_block_quadlets = s->pcm_channels + midi_channels; | 150 | s->data_block_quadlets = s->pcm_channels + midi_channels; |
158 | s->midi_ports = midi_ports; | 151 | s->midi_ports = midi_ports; |
@@ -191,18 +184,9 @@ static void amdtp_write_s16(struct amdtp_stream *s, | |||
191 | static void amdtp_write_s32(struct amdtp_stream *s, | 184 | static void amdtp_write_s32(struct amdtp_stream *s, |
192 | struct snd_pcm_substream *pcm, | 185 | struct snd_pcm_substream *pcm, |
193 | __be32 *buffer, unsigned int frames); | 186 | __be32 *buffer, unsigned int frames); |
194 | static void amdtp_write_s16_dualwire(struct amdtp_stream *s, | ||
195 | struct snd_pcm_substream *pcm, | ||
196 | __be32 *buffer, unsigned int frames); | ||
197 | static void amdtp_write_s32_dualwire(struct amdtp_stream *s, | ||
198 | struct snd_pcm_substream *pcm, | ||
199 | __be32 *buffer, unsigned int frames); | ||
200 | static void amdtp_read_s32(struct amdtp_stream *s, | 187 | static void amdtp_read_s32(struct amdtp_stream *s, |
201 | struct snd_pcm_substream *pcm, | 188 | struct snd_pcm_substream *pcm, |
202 | __be32 *buffer, unsigned int frames); | 189 | __be32 *buffer, unsigned int frames); |
203 | static void amdtp_read_s32_dualwire(struct amdtp_stream *s, | ||
204 | struct snd_pcm_substream *pcm, | ||
205 | __be32 *buffer, unsigned int frames); | ||
206 | 190 | ||
207 | /** | 191 | /** |
208 | * amdtp_stream_set_pcm_format - set the PCM format | 192 | * amdtp_stream_set_pcm_format - set the PCM format |
@@ -225,26 +209,16 @@ void amdtp_stream_set_pcm_format(struct amdtp_stream *s, | |||
225 | /* fall through */ | 209 | /* fall through */ |
226 | case SNDRV_PCM_FORMAT_S16: | 210 | case SNDRV_PCM_FORMAT_S16: |
227 | if (s->direction == AMDTP_OUT_STREAM) { | 211 | if (s->direction == AMDTP_OUT_STREAM) { |
228 | if (s->dual_wire) | 212 | s->transfer_samples = amdtp_write_s16; |
229 | s->transfer_samples = amdtp_write_s16_dualwire; | ||
230 | else | ||
231 | s->transfer_samples = amdtp_write_s16; | ||
232 | break; | 213 | break; |
233 | } | 214 | } |
234 | WARN_ON(1); | 215 | WARN_ON(1); |
235 | /* fall through */ | 216 | /* fall through */ |
236 | case SNDRV_PCM_FORMAT_S32: | 217 | case SNDRV_PCM_FORMAT_S32: |
237 | if (s->direction == AMDTP_OUT_STREAM) { | 218 | if (s->direction == AMDTP_OUT_STREAM) |
238 | if (s->dual_wire) | 219 | s->transfer_samples = amdtp_write_s32; |
239 | s->transfer_samples = amdtp_write_s32_dualwire; | 220 | else |
240 | else | 221 | s->transfer_samples = amdtp_read_s32; |
241 | s->transfer_samples = amdtp_write_s32; | ||
242 | } else { | ||
243 | if (s->dual_wire) | ||
244 | s->transfer_samples = amdtp_read_s32_dualwire; | ||
245 | else | ||
246 | s->transfer_samples = amdtp_read_s32; | ||
247 | } | ||
248 | break; | 222 | break; |
249 | } | 223 | } |
250 | } | 224 | } |
@@ -393,68 +367,6 @@ static void amdtp_write_s16(struct amdtp_stream *s, | |||
393 | } | 367 | } |
394 | } | 368 | } |
395 | 369 | ||
396 | static void amdtp_write_s32_dualwire(struct amdtp_stream *s, | ||
397 | struct snd_pcm_substream *pcm, | ||
398 | __be32 *buffer, unsigned int frames) | ||
399 | { | ||
400 | struct snd_pcm_runtime *runtime = pcm->runtime; | ||
401 | unsigned int channels, remaining_frames, i, c; | ||
402 | const u32 *src; | ||
403 | |||
404 | src = (void *)runtime->dma_area + | ||
405 | frames_to_bytes(runtime, s->pcm_buffer_pointer); | ||
406 | remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; | ||
407 | channels = s->pcm_channels / 2; | ||
408 | |||
409 | for (i = 0; i < frames; ++i) { | ||
410 | for (c = 0; c < channels; ++c) { | ||
411 | buffer[s->pcm_positions[c] * 2] = | ||
412 | cpu_to_be32((*src >> 8) | 0x40000000); | ||
413 | src++; | ||
414 | } | ||
415 | buffer += 1; | ||
416 | for (c = 0; c < channels; ++c) { | ||
417 | buffer[s->pcm_positions[c] * 2] = | ||
418 | cpu_to_be32((*src >> 8) | 0x40000000); | ||
419 | src++; | ||
420 | } | ||
421 | buffer += s->data_block_quadlets - 1; | ||
422 | if (--remaining_frames == 0) | ||
423 | src = (void *)runtime->dma_area; | ||
424 | } | ||
425 | } | ||
426 | |||
427 | static void amdtp_write_s16_dualwire(struct amdtp_stream *s, | ||
428 | struct snd_pcm_substream *pcm, | ||
429 | __be32 *buffer, unsigned int frames) | ||
430 | { | ||
431 | struct snd_pcm_runtime *runtime = pcm->runtime; | ||
432 | unsigned int channels, remaining_frames, i, c; | ||
433 | const u16 *src; | ||
434 | |||
435 | src = (void *)runtime->dma_area + | ||
436 | frames_to_bytes(runtime, s->pcm_buffer_pointer); | ||
437 | remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; | ||
438 | channels = s->pcm_channels / 2; | ||
439 | |||
440 | for (i = 0; i < frames; ++i) { | ||
441 | for (c = 0; c < channels; ++c) { | ||
442 | buffer[s->pcm_positions[c] * 2] = | ||
443 | cpu_to_be32((*src << 8) | 0x40000000); | ||
444 | src++; | ||
445 | } | ||
446 | buffer += 1; | ||
447 | for (c = 0; c < channels; ++c) { | ||
448 | buffer[s->pcm_positions[c] * 2] = | ||
449 | cpu_to_be32((*src << 8) | 0x40000000); | ||
450 | src++; | ||
451 | } | ||
452 | buffer += s->data_block_quadlets - 1; | ||
453 | if (--remaining_frames == 0) | ||
454 | src = (void *)runtime->dma_area; | ||
455 | } | ||
456 | } | ||
457 | |||
458 | static void amdtp_read_s32(struct amdtp_stream *s, | 370 | static void amdtp_read_s32(struct amdtp_stream *s, |
459 | struct snd_pcm_substream *pcm, | 371 | struct snd_pcm_substream *pcm, |
460 | __be32 *buffer, unsigned int frames) | 372 | __be32 *buffer, unsigned int frames) |
@@ -479,37 +391,6 @@ static void amdtp_read_s32(struct amdtp_stream *s, | |||
479 | } | 391 | } |
480 | } | 392 | } |
481 | 393 | ||
482 | static void amdtp_read_s32_dualwire(struct amdtp_stream *s, | ||
483 | struct snd_pcm_substream *pcm, | ||
484 | __be32 *buffer, unsigned int frames) | ||
485 | { | ||
486 | struct snd_pcm_runtime *runtime = pcm->runtime; | ||
487 | unsigned int channels, remaining_frames, i, c; | ||
488 | u32 *dst; | ||
489 | |||
490 | dst = (void *)runtime->dma_area + | ||
491 | frames_to_bytes(runtime, s->pcm_buffer_pointer); | ||
492 | remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; | ||
493 | channels = s->pcm_channels / 2; | ||
494 | |||
495 | for (i = 0; i < frames; ++i) { | ||
496 | for (c = 0; c < channels; ++c) { | ||
497 | *dst = | ||
498 | be32_to_cpu(buffer[s->pcm_positions[c] * 2]) << 8; | ||
499 | dst++; | ||
500 | } | ||
501 | buffer += 1; | ||
502 | for (c = 0; c < channels; ++c) { | ||
503 | *dst = | ||
504 | be32_to_cpu(buffer[s->pcm_positions[c] * 2]) << 8; | ||
505 | dst++; | ||
506 | } | ||
507 | buffer += s->data_block_quadlets - 1; | ||
508 | if (--remaining_frames == 0) | ||
509 | dst = (void *)runtime->dma_area; | ||
510 | } | ||
511 | } | ||
512 | |||
513 | static void amdtp_fill_pcm_silence(struct amdtp_stream *s, | 394 | static void amdtp_fill_pcm_silence(struct amdtp_stream *s, |
514 | __be32 *buffer, unsigned int frames) | 395 | __be32 *buffer, unsigned int frames) |
515 | { | 396 | { |
@@ -522,21 +403,6 @@ static void amdtp_fill_pcm_silence(struct amdtp_stream *s, | |||
522 | } | 403 | } |
523 | } | 404 | } |
524 | 405 | ||
525 | static void amdtp_fill_pcm_silence_dualwire(struct amdtp_stream *s, | ||
526 | __be32 *buffer, unsigned int frames) | ||
527 | { | ||
528 | unsigned int i, c, channels; | ||
529 | |||
530 | channels = s->pcm_channels / 2; | ||
531 | for (i = 0; i < frames; ++i) { | ||
532 | for (c = 0; c < channels; ++c) { | ||
533 | buffer[s->pcm_positions[c] * 2] = | ||
534 | buffer[s->pcm_positions[c] * 2 + 1] = | ||
535 | cpu_to_be32(0x40000000); | ||
536 | } | ||
537 | buffer += s->data_block_quadlets; | ||
538 | } | ||
539 | } | ||
540 | static void amdtp_fill_midi(struct amdtp_stream *s, | 406 | static void amdtp_fill_midi(struct amdtp_stream *s, |
541 | __be32 *buffer, unsigned int frames) | 407 | __be32 *buffer, unsigned int frames) |
542 | { | 408 | { |
@@ -582,9 +448,6 @@ static void update_pcm_pointers(struct amdtp_stream *s, | |||
582 | unsigned int frames) | 448 | unsigned int frames) |
583 | { unsigned int ptr; | 449 | { unsigned int ptr; |
584 | 450 | ||
585 | if (s->dual_wire) | ||
586 | frames *= 2; | ||
587 | |||
588 | ptr = s->pcm_buffer_pointer + frames; | 451 | ptr = s->pcm_buffer_pointer + frames; |
589 | if (ptr >= pcm->runtime->buffer_size) | 452 | if (ptr >= pcm->runtime->buffer_size) |
590 | ptr -= pcm->runtime->buffer_size; | 453 | ptr -= pcm->runtime->buffer_size; |
@@ -674,8 +537,6 @@ static void handle_out_packet(struct amdtp_stream *s, unsigned int syt) | |||
674 | pcm = ACCESS_ONCE(s->pcm); | 537 | pcm = ACCESS_ONCE(s->pcm); |
675 | if (pcm) | 538 | if (pcm) |
676 | s->transfer_samples(s, pcm, buffer, data_blocks); | 539 | s->transfer_samples(s, pcm, buffer, data_blocks); |
677 | else if (s->dual_wire) | ||
678 | amdtp_fill_pcm_silence_dualwire(s, buffer, data_blocks); | ||
679 | else | 540 | else |
680 | amdtp_fill_pcm_silence(s, buffer, data_blocks); | 541 | amdtp_fill_pcm_silence(s, buffer, data_blocks); |
681 | if (s->midi_ports) | 542 | if (s->midi_ports) |
diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h index e8d62ace6fff..db60425f2781 100644 --- a/sound/firewire/amdtp.h +++ b/sound/firewire/amdtp.h | |||
@@ -16,18 +16,13 @@ | |||
16 | * @CIP_BLOCKING: In blocking mode, each packet contains either zero or | 16 | * @CIP_BLOCKING: In blocking mode, each packet contains either zero or |
17 | * SYT_INTERVAL samples, with these two types alternating so that | 17 | * SYT_INTERVAL samples, with these two types alternating so that |
18 | * the overall sample rate comes out right. | 18 | * the overall sample rate comes out right. |
19 | * @CIP_HI_DUALWIRE: At rates above 96 kHz, pretend that the stream runs | ||
20 | * at half the actual sample rate with twice the number of channels; | ||
21 | * two samples of a channel are stored consecutively in the packet. | ||
22 | * Requires blocking mode and SYT_INTERVAL-aligned PCM buffer size. | ||
23 | * @CIP_SYNC_TO_DEVICE: In sync to device mode, time stamp in out packets is | 19 | * @CIP_SYNC_TO_DEVICE: In sync to device mode, time stamp in out packets is |
24 | * generated by in packets. Defaultly this driver generates timestamp. | 20 | * generated by in packets. Defaultly this driver generates timestamp. |
25 | */ | 21 | */ |
26 | enum cip_flags { | 22 | enum cip_flags { |
27 | CIP_NONBLOCKING = 0x00, | 23 | CIP_NONBLOCKING = 0x00, |
28 | CIP_BLOCKING = 0x01, | 24 | CIP_BLOCKING = 0x01, |
29 | CIP_HI_DUALWIRE = 0x02, | 25 | CIP_SYNC_TO_DEVICE = 0x02, |
30 | CIP_SYNC_TO_DEVICE = 0x04, | ||
31 | }; | 26 | }; |
32 | 27 | ||
33 | /** | 28 | /** |
@@ -84,7 +79,6 @@ struct amdtp_stream { | |||
84 | struct mutex mutex; | 79 | struct mutex mutex; |
85 | 80 | ||
86 | enum cip_sfc sfc; | 81 | enum cip_sfc sfc; |
87 | bool dual_wire; | ||
88 | unsigned int data_block_quadlets; | 82 | unsigned int data_block_quadlets; |
89 | unsigned int pcm_channels; | 83 | unsigned int pcm_channels; |
90 | unsigned int midi_ports; | 84 | unsigned int midi_ports; |
diff --git a/sound/firewire/dice.c b/sound/firewire/dice.c index 26b2158f87d1..cd4c6b6d072e 100644 --- a/sound/firewire/dice.c +++ b/sound/firewire/dice.c | |||
@@ -563,7 +563,7 @@ static int dice_hw_params(struct snd_pcm_substream *substream, | |||
563 | struct snd_pcm_hw_params *hw_params) | 563 | struct snd_pcm_hw_params *hw_params) |
564 | { | 564 | { |
565 | struct dice *dice = substream->private_data; | 565 | struct dice *dice = substream->private_data; |
566 | unsigned int rate_index, mode; | 566 | unsigned int rate_index, mode, rate, channels, i; |
567 | int err; | 567 | int err; |
568 | 568 | ||
569 | mutex_lock(&dice->mutex); | 569 | mutex_lock(&dice->mutex); |
@@ -575,15 +575,36 @@ static int dice_hw_params(struct snd_pcm_substream *substream, | |||
575 | if (err < 0) | 575 | if (err < 0) |
576 | return err; | 576 | return err; |
577 | 577 | ||
578 | rate_index = rate_to_index(params_rate(hw_params)); | 578 | rate = params_rate(hw_params); |
579 | rate_index = rate_to_index(rate); | ||
579 | err = dice_change_rate(dice, rate_index << CLOCK_RATE_SHIFT); | 580 | err = dice_change_rate(dice, rate_index << CLOCK_RATE_SHIFT); |
580 | if (err < 0) | 581 | if (err < 0) |
581 | return err; | 582 | return err; |
582 | 583 | ||
584 | /* | ||
585 | * At rates above 96 kHz, pretend that the stream runs at half the | ||
586 | * actual sample rate with twice the number of channels; two samples | ||
587 | * of a channel are stored consecutively in the packet. Requires | ||
588 | * blocking mode and PCM buffer size should be aligned to SYT_INTERVAL. | ||
589 | */ | ||
590 | channels = params_channels(hw_params); | ||
591 | if (rate_index > 4) { | ||
592 | if (channels > AMDTP_MAX_CHANNELS_FOR_PCM / 2) { | ||
593 | err = -ENOSYS; | ||
594 | return err; | ||
595 | } | ||
596 | |||
597 | for (i = 0; i < channels; i++) { | ||
598 | dice->stream.pcm_positions[i * 2] = i; | ||
599 | dice->stream.pcm_positions[i * 2 + 1] = i + channels; | ||
600 | } | ||
601 | |||
602 | rate /= 2; | ||
603 | channels *= 2; | ||
604 | } | ||
605 | |||
583 | mode = rate_index_to_mode(rate_index); | 606 | mode = rate_index_to_mode(rate_index); |
584 | amdtp_stream_set_parameters(&dice->stream, | 607 | amdtp_stream_set_parameters(&dice->stream, rate, channels, |
585 | params_rate(hw_params), | ||
586 | params_channels(hw_params), | ||
587 | dice->rx_midi_ports[mode]); | 608 | dice->rx_midi_ports[mode]); |
588 | amdtp_stream_set_pcm_format(&dice->stream, | 609 | amdtp_stream_set_pcm_format(&dice->stream, |
589 | params_format(hw_params)); | 610 | params_format(hw_params)); |
@@ -1361,7 +1382,7 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) | |||
1361 | dice->resources.channels_mask = 0x00000000ffffffffuLL; | 1382 | dice->resources.channels_mask = 0x00000000ffffffffuLL; |
1362 | 1383 | ||
1363 | err = amdtp_stream_init(&dice->stream, unit, AMDTP_OUT_STREAM, | 1384 | err = amdtp_stream_init(&dice->stream, unit, AMDTP_OUT_STREAM, |
1364 | CIP_BLOCKING | CIP_HI_DUALWIRE); | 1385 | CIP_BLOCKING); |
1365 | if (err < 0) | 1386 | if (err < 0) |
1366 | goto err_resources; | 1387 | goto err_resources; |
1367 | 1388 | ||