summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/firewire/dice/dice-midi.c8
-rw-r--r--sound/firewire/dice/dice-pcm.c34
-rw-r--r--sound/firewire/dice/dice-stream.c54
-rw-r--r--sound/firewire/dice/dice.h31
4 files changed, 79 insertions, 48 deletions
diff --git a/sound/firewire/dice/dice-midi.c b/sound/firewire/dice/dice-midi.c
index 2461311e695a..a040617505a7 100644
--- a/sound/firewire/dice/dice-midi.c
+++ b/sound/firewire/dice/dice-midi.c
@@ -52,10 +52,10 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
spin_lock_irqsave(&dice->lock, flags);
if (up)
- amdtp_am824_midi_trigger(&dice->tx_stream,
+ amdtp_am824_midi_trigger(&dice->tx_stream[0],
substrm->number, substrm);
else
- amdtp_am824_midi_trigger(&dice->tx_stream,
+ amdtp_am824_midi_trigger(&dice->tx_stream[0],
substrm->number, NULL);
spin_unlock_irqrestore(&dice->lock, flags);
@@ -69,10 +69,10 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
spin_lock_irqsave(&dice->lock, flags);
if (up)
- amdtp_am824_midi_trigger(&dice->rx_stream,
+ amdtp_am824_midi_trigger(&dice->rx_stream[0],
substrm->number, substrm);
else
- amdtp_am824_midi_trigger(&dice->rx_stream,
+ amdtp_am824_midi_trigger(&dice->rx_stream[0],
substrm->number, NULL);
spin_unlock_irqrestore(&dice->lock, flags);
diff --git a/sound/firewire/dice/dice-pcm.c b/sound/firewire/dice/dice-pcm.c
index a5c9b58655ef..e25294910736 100644
--- a/sound/firewire/dice/dice-pcm.c
+++ b/sound/firewire/dice/dice-pcm.c
@@ -22,7 +22,7 @@ static int limit_channels_and_rates(struct snd_dice *dice,
* Retrieve current Multi Bit Linear Audio data channel and limit to
* it.
*/
- if (stream == &dice->tx_stream) {
+ if (stream == &dice->tx_stream[0]) {
err = snd_dice_transaction_read_tx(dice, TX_NUMBER_AUDIO,
reg, sizeof(reg));
} else {
@@ -74,10 +74,10 @@ static int init_hw_info(struct snd_dice *dice,
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
hw->formats = AM824_IN_PCM_FORMAT_BITS;
- stream = &dice->tx_stream;
+ stream = &dice->tx_stream[0];
} else {
hw->formats = AM824_OUT_PCM_FORMAT_BITS;
- stream = &dice->rx_stream;
+ stream = &dice->rx_stream[0];
}
err = limit_channels_and_rates(dice, runtime, stream);
@@ -122,6 +122,7 @@ static int capture_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
{
struct snd_dice *dice = substream->private_data;
+ struct amdtp_stream *stream = &dice->tx_stream[0];
int err;
err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
@@ -135,7 +136,7 @@ static int capture_hw_params(struct snd_pcm_substream *substream,
mutex_unlock(&dice->mutex);
}
- amdtp_am824_set_pcm_format(&dice->tx_stream, params_format(hw_params));
+ amdtp_am824_set_pcm_format(stream, params_format(hw_params));
return 0;
}
@@ -143,6 +144,7 @@ static int playback_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
{
struct snd_dice *dice = substream->private_data;
+ struct amdtp_stream *stream = &dice->rx_stream[0];
int err;
err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
@@ -156,7 +158,7 @@ static int playback_hw_params(struct snd_pcm_substream *substream,
mutex_unlock(&dice->mutex);
}
- amdtp_am824_set_pcm_format(&dice->rx_stream, params_format(hw_params));
+ amdtp_am824_set_pcm_format(stream, params_format(hw_params));
return 0;
}
@@ -196,26 +198,28 @@ static int playback_hw_free(struct snd_pcm_substream *substream)
static int capture_prepare(struct snd_pcm_substream *substream)
{
struct snd_dice *dice = substream->private_data;
+ struct amdtp_stream *stream = &dice->tx_stream[0];
int err;
mutex_lock(&dice->mutex);
err = snd_dice_stream_start_duplex(dice, substream->runtime->rate);
mutex_unlock(&dice->mutex);
if (err >= 0)
- amdtp_stream_pcm_prepare(&dice->tx_stream);
+ amdtp_stream_pcm_prepare(stream);
return 0;
}
static int playback_prepare(struct snd_pcm_substream *substream)
{
struct snd_dice *dice = substream->private_data;
+ struct amdtp_stream *stream = &dice->rx_stream[0];
int err;
mutex_lock(&dice->mutex);
err = snd_dice_stream_start_duplex(dice, substream->runtime->rate);
mutex_unlock(&dice->mutex);
if (err >= 0)
- amdtp_stream_pcm_prepare(&dice->rx_stream);
+ amdtp_stream_pcm_prepare(stream);
return err;
}
@@ -223,13 +227,14 @@ static int playback_prepare(struct snd_pcm_substream *substream)
static int capture_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_dice *dice = substream->private_data;
+ struct amdtp_stream *stream = &dice->tx_stream[0];
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- amdtp_stream_pcm_trigger(&dice->tx_stream, substream);
+ amdtp_stream_pcm_trigger(stream, substream);
break;
case SNDRV_PCM_TRIGGER_STOP:
- amdtp_stream_pcm_trigger(&dice->tx_stream, NULL);
+ amdtp_stream_pcm_trigger(stream, NULL);
break;
default:
return -EINVAL;
@@ -240,13 +245,14 @@ static int capture_trigger(struct snd_pcm_substream *substream, int cmd)
static int playback_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_dice *dice = substream->private_data;
+ struct amdtp_stream *stream = &dice->rx_stream[0];
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- amdtp_stream_pcm_trigger(&dice->rx_stream, substream);
+ amdtp_stream_pcm_trigger(stream, substream);
break;
case SNDRV_PCM_TRIGGER_STOP:
- amdtp_stream_pcm_trigger(&dice->rx_stream, NULL);
+ amdtp_stream_pcm_trigger(stream, NULL);
break;
default:
return -EINVAL;
@@ -258,14 +264,16 @@ static int playback_trigger(struct snd_pcm_substream *substream, int cmd)
static snd_pcm_uframes_t capture_pointer(struct snd_pcm_substream *substream)
{
struct snd_dice *dice = substream->private_data;
+ struct amdtp_stream *stream = &dice->tx_stream[0];
- return amdtp_stream_pcm_pointer(&dice->tx_stream);
+ return amdtp_stream_pcm_pointer(stream);
}
static snd_pcm_uframes_t playback_pointer(struct snd_pcm_substream *substream)
{
struct snd_dice *dice = substream->private_data;
+ struct amdtp_stream *stream = &dice->rx_stream[0];
- return amdtp_stream_pcm_pointer(&dice->rx_stream);
+ return amdtp_stream_pcm_pointer(stream);
}
int snd_dice_create_pcm(struct snd_dice *dice)
diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c
index df035b1dd44a..15d581de5cae 100644
--- a/sound/firewire/dice/dice-stream.c
+++ b/sound/firewire/dice/dice-stream.c
@@ -72,7 +72,7 @@ static void release_resources(struct snd_dice *dice,
/* Reset channel number */
channel = cpu_to_be32((u32)-1);
- if (resources == &dice->tx_resources)
+ if (resources == &dice->tx_resources[0])
snd_dice_transaction_write_tx(dice, TX_ISOCHRONOUS,
&channel, sizeof(channel));
else
@@ -96,7 +96,7 @@ static int keep_resources(struct snd_dice *dice,
/* Set channel number */
channel = cpu_to_be32(resources->channel);
- if (resources == &dice->tx_resources)
+ if (resources == &dice->tx_resources[0])
err = snd_dice_transaction_write_tx(dice, TX_ISOCHRONOUS,
&channel, sizeof(channel));
else
@@ -113,10 +113,10 @@ static void stop_stream(struct snd_dice *dice, struct amdtp_stream *stream)
amdtp_stream_pcm_abort(stream);
amdtp_stream_stop(stream);
- if (stream == &dice->tx_stream)
- release_resources(dice, &dice->tx_resources);
+ if (stream == &dice->tx_stream[0])
+ release_resources(dice, &dice->tx_resources[0]);
else
- release_resources(dice, &dice->rx_resources);
+ release_resources(dice, &dice->rx_resources[0]);
}
static int start_stream(struct snd_dice *dice, struct amdtp_stream *stream,
@@ -128,12 +128,12 @@ static int start_stream(struct snd_dice *dice, struct amdtp_stream *stream,
bool double_pcm_frames;
int err;
- if (stream == &dice->tx_stream) {
- resources = &dice->tx_resources;
+ if (stream == &dice->tx_stream[0]) {
+ resources = &dice->tx_resources[0];
err = snd_dice_transaction_read_tx(dice, TX_NUMBER_AUDIO,
reg, sizeof(reg));
} else {
- resources = &dice->rx_resources;
+ resources = &dice->rx_resources[0];
err = snd_dice_transaction_read_rx(dice, RX_NUMBER_AUDIO,
reg, sizeof(reg));
}
@@ -200,8 +200,8 @@ int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate)
if (dice->substreams_counter == 0)
goto end;
- master = &dice->rx_stream;
- slave = &dice->tx_stream;
+ master = &dice->rx_stream[0];
+ slave = &dice->tx_stream[0];
/* Some packet queueing errors. */
if (amdtp_streaming_error(master) || amdtp_streaming_error(slave))
@@ -275,8 +275,8 @@ void snd_dice_stream_stop_duplex(struct snd_dice *dice)
snd_dice_transaction_clear_enable(dice);
- stop_stream(dice, &dice->tx_stream);
- stop_stream(dice, &dice->rx_stream);
+ stop_stream(dice, &dice->tx_stream[0]);
+ stop_stream(dice, &dice->rx_stream[0]);
}
static int init_stream(struct snd_dice *dice, struct amdtp_stream *stream)
@@ -285,11 +285,11 @@ static int init_stream(struct snd_dice *dice, struct amdtp_stream *stream)
struct fw_iso_resources *resources;
enum amdtp_stream_direction dir;
- if (stream == &dice->tx_stream) {
- resources = &dice->tx_resources;
+ if (stream == &dice->tx_stream[0]) {
+ resources = &dice->tx_resources[0];
dir = AMDTP_IN_STREAM;
} else {
- resources = &dice->rx_resources;
+ resources = &dice->rx_resources[0];
dir = AMDTP_OUT_STREAM;
}
@@ -315,10 +315,10 @@ static void destroy_stream(struct snd_dice *dice, struct amdtp_stream *stream)
{
struct fw_iso_resources *resources;
- if (stream == &dice->tx_stream)
- resources = &dice->tx_resources;
+ if (stream == &dice->tx_stream[0])
+ resources = &dice->tx_resources[0];
else
- resources = &dice->rx_resources;
+ resources = &dice->rx_resources[0];
amdtp_stream_destroy(stream);
fw_iso_resources_destroy(resources);
@@ -330,13 +330,13 @@ int snd_dice_stream_init_duplex(struct snd_dice *dice)
dice->substreams_counter = 0;
- err = init_stream(dice, &dice->tx_stream);
+ err = init_stream(dice, &dice->tx_stream[0]);
if (err < 0)
goto end;
- err = init_stream(dice, &dice->rx_stream);
+ err = init_stream(dice, &dice->rx_stream[0]);
if (err < 0)
- destroy_stream(dice, &dice->tx_stream);
+ destroy_stream(dice, &dice->tx_stream[0]);
end:
return err;
}
@@ -345,8 +345,8 @@ void snd_dice_stream_destroy_duplex(struct snd_dice *dice)
{
snd_dice_transaction_clear_enable(dice);
- destroy_stream(dice, &dice->tx_stream);
- destroy_stream(dice, &dice->rx_stream);
+ destroy_stream(dice, &dice->tx_stream[0]);
+ destroy_stream(dice, &dice->rx_stream[0]);
dice->substreams_counter = 0;
}
@@ -363,11 +363,11 @@ void snd_dice_stream_update_duplex(struct snd_dice *dice)
*/
dice->global_enabled = false;
- stop_stream(dice, &dice->rx_stream);
- stop_stream(dice, &dice->tx_stream);
+ stop_stream(dice, &dice->rx_stream[0]);
+ stop_stream(dice, &dice->tx_stream[0]);
- fw_iso_resources_update(&dice->rx_resources);
- fw_iso_resources_update(&dice->tx_resources);
+ fw_iso_resources_update(&dice->rx_resources[0]);
+ fw_iso_resources_update(&dice->tx_resources[0]);
}
static void dice_lock_changed(struct snd_dice *dice)
diff --git a/sound/firewire/dice/dice.h b/sound/firewire/dice/dice.h
index 423cdba99726..8fba87d83810 100644
--- a/sound/firewire/dice/dice.h
+++ b/sound/firewire/dice/dice.h
@@ -39,6 +39,29 @@
#include "../lib.h"
#include "dice-interface.h"
+/*
+ * This module support maximum 2 pairs of tx/rx isochronous streams for
+ * our convinience.
+ *
+ * In documents for ASICs called with a name of 'DICE':
+ * - ASIC for DICE II:
+ * - Maximum 2 tx and 4 rx are supported.
+ * - A packet supports maximum 16 data channels.
+ * - TCD2210/2210-E (so-called 'Dice Mini'):
+ * - Maximum 2 tx and 2 rx are supported.
+ * - A packet supports maximum 16 data channels.
+ * - TCD2220/2220-E (so-called 'Dice Jr.')
+ * - 2 tx and 2 rx are supported.
+ * - A packet supports maximum 16 data channels.
+ * - TCD3070-CH (so-called 'Dice III')
+ * - Maximum 2 tx and 2 rx are supported.
+ * - A packet supports maximum 32 data channels.
+ *
+ * For the above, MIDI conformant data channel is just on the first isochronous
+ * stream.
+ */
+#define MAX_STREAMS 2
+
struct snd_dice {
struct snd_card *card;
struct fw_unit *unit;
@@ -67,10 +90,10 @@ struct snd_dice {
wait_queue_head_t hwdep_wait;
/* For streaming */
- struct fw_iso_resources tx_resources;
- struct fw_iso_resources rx_resources;
- struct amdtp_stream tx_stream;
- struct amdtp_stream rx_stream;
+ struct fw_iso_resources tx_resources[MAX_STREAMS];
+ struct fw_iso_resources rx_resources[MAX_STREAMS];
+ struct amdtp_stream tx_stream[MAX_STREAMS];
+ struct amdtp_stream rx_stream[MAX_STREAMS];
bool global_enabled;
struct completion clock_accepted;
unsigned int substreams_counter;