aboutsummaryrefslogtreecommitdiffstats
path: root/sound/firewire/dice.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/firewire/dice.c')
-rw-r--r--sound/firewire/dice.c33
1 files changed, 27 insertions, 6 deletions
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