summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/firewire/amdtp-stream.c80
-rw-r--r--sound/firewire/amdtp-stream.h3
-rw-r--r--sound/firewire/bebob/bebob_stream.c21
3 files changed, 23 insertions, 81 deletions
diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c
index 35925c9666fc..48ed9612407f 100644
--- a/sound/firewire/amdtp-stream.c
+++ b/sound/firewire/amdtp-stream.c
@@ -1199,12 +1199,16 @@ static void amdtp_stream_first_callback(struct fw_iso_context *context,
}
if (stream_count == callbacked_count) {
+ unsigned int next_cycle;
+
list_for_each_entry(s, &d->streams, list) {
if (s->direction != AMDTP_IN_STREAM)
continue;
- if (compare_ohci_cycle_count(s->next_cycle, cycle) > 0)
- cycle = s->next_cycle;
+ next_cycle = increment_ohci_cycle_count(s->next_cycle,
+ d->processing_cycle.tx_init_skip);
+ if (compare_ohci_cycle_count(next_cycle, cycle) > 0)
+ cycle = next_cycle;
s->context->callback.sc = process_tx_packets_intermediately;
}
@@ -1533,36 +1537,13 @@ int amdtp_domain_add_stream(struct amdtp_domain *d, struct amdtp_stream *s,
}
EXPORT_SYMBOL_GPL(amdtp_domain_add_stream);
-static int get_current_cycle_time(struct fw_card *fw_card, int *cur_cycle)
-{
- int generation;
- int rcode;
- __be32 reg;
- u32 data;
-
- // This is a request to local 1394 OHCI controller and expected to
- // complete without any event waiting.
- generation = fw_card->generation;
- smp_rmb(); // node_id vs. generation.
- rcode = fw_run_transaction(fw_card, TCODE_READ_QUADLET_REQUEST,
- fw_card->node_id, generation, SCODE_100,
- CSR_REGISTER_BASE + CSR_CYCLE_TIME,
- &reg, sizeof(reg));
- if (rcode != RCODE_COMPLETE)
- return -EIO;
-
- data = be32_to_cpu(reg);
- *cur_cycle = data >> 12;
-
- return 0;
-}
-
/**
* amdtp_domain_start - start sending packets for isoc context in the domain.
* @d: the AMDTP domain.
- * @ir_delay_cycle: the cycle delay to start all IR contexts.
+ * @tx_init_skip_cycles: the number of cycles to skip processing packets at initial stage of IR
+ * contexts.
*/
-int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle)
+int amdtp_domain_start(struct amdtp_domain *d, unsigned int tx_init_skip_cycles)
{
static const struct {
unsigned int data_block;
@@ -1581,7 +1562,6 @@ int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle)
unsigned int idle_irq_interval;
unsigned int queue_size;
struct amdtp_stream *s;
- int cycle;
int err;
// Select an IT context as IRQ target.
@@ -1593,6 +1573,8 @@ int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle)
return -ENXIO;
d->irq_target = s;
+ d->processing_cycle.tx_init_skip = tx_init_skip_cycles;
+
// This is a case that AMDTP streams in domain run just for MIDI
// substream. Use the number of events equivalent to 10 msec as
// interval of hardware IRQ.
@@ -1615,48 +1597,12 @@ int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle)
d->syt_offset_state = entry->syt_offset;
d->last_syt_offset = TICKS_PER_CYCLE;
- if (ir_delay_cycle > 0) {
- struct fw_card *fw_card = fw_parent_device(s->unit)->card;
-
- err = get_current_cycle_time(fw_card, &cycle);
- if (err < 0)
- goto error;
-
- // No need to care overflow in cycle field because of enough
- // width.
- cycle += ir_delay_cycle;
-
- // Round up to sec field.
- if ((cycle & 0x00001fff) >= CYCLES_PER_SECOND) {
- unsigned int sec;
-
- // The sec field can overflow.
- sec = (cycle & 0xffffe000) >> 13;
- cycle = (++sec << 13) |
- ((cycle & 0x00001fff) / CYCLES_PER_SECOND);
- }
-
- // In OHCI 1394 specification, lower 2 bits are available for
- // sec field.
- cycle &= 0x00007fff;
- } else {
- cycle = -1;
- }
-
list_for_each_entry(s, &d->streams, list) {
- int cycle_match;
-
- if (s->direction == AMDTP_IN_STREAM) {
- cycle_match = cycle;
- } else {
- // IT context starts immediately.
- cycle_match = -1;
+ if (s->direction == AMDTP_OUT_STREAM)
s->ctx_data.rx.seq_index = 0;
- }
if (s != d->irq_target) {
- err = amdtp_stream_start(s, s->channel, s->speed,
- cycle_match, queue_size, 0);
+ err = amdtp_stream_start(s, s->channel, s->speed, -1, queue_size, 0);
if (err < 0)
goto error;
}
diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h
index 6fad113188fe..ebd040560791 100644
--- a/sound/firewire/amdtp-stream.h
+++ b/sound/firewire/amdtp-stream.h
@@ -289,6 +289,7 @@ struct amdtp_domain {
struct amdtp_stream *irq_target;
struct {
+ unsigned int tx_init_skip;
unsigned int tx_start;
} processing_cycle;
@@ -309,7 +310,7 @@ void amdtp_domain_destroy(struct amdtp_domain *d);
int amdtp_domain_add_stream(struct amdtp_domain *d, struct amdtp_stream *s,
int channel, int speed);
-int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle);
+int amdtp_domain_start(struct amdtp_domain *d, unsigned int tx_init_skip_cycles);
void amdtp_domain_stop(struct amdtp_domain *d);
static inline int amdtp_domain_set_events_per_period(struct amdtp_domain *d,
diff --git a/sound/firewire/bebob/bebob_stream.c b/sound/firewire/bebob/bebob_stream.c
index b612ee3e33b6..8053d02b68f0 100644
--- a/sound/firewire/bebob/bebob_stream.c
+++ b/sound/firewire/bebob/bebob_stream.c
@@ -626,7 +626,7 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob)
enum snd_bebob_clock_type src;
struct amdtp_stream *master, *slave;
unsigned int curr_rate;
- unsigned int ir_delay_cycle;
+ unsigned int tx_init_skip_cycles;
if (bebob->maudio_special_quirk) {
err = bebob->spec->rate->get(bebob, &curr_rate);
@@ -654,20 +654,13 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob)
if (err < 0)
goto error;
- // The device postpones start of transmission mostly for 1 sec
- // after receives packets firstly. For safe, IR context starts
- // 0.4 sec (=3200 cycles) later to version 1 or 2 firmware,
- // 2.0 sec (=16000 cycles) for version 3 firmware. This is
- // within 2.5 sec (=CALLBACK_TIMEOUT).
- // Furthermore, some devices transfer isoc packets with
- // discontinuous counter in the beginning of packet streaming.
- // The delay has an effect to avoid detection of this
- // discontinuity.
+ // Some devices transfer isoc packets with discontinuous counter in the beginning
+ // of packet streaming.
if (bebob->version < 2)
- ir_delay_cycle = 3200;
+ tx_init_skip_cycles = 3200;
else
- ir_delay_cycle = 16000;
- err = amdtp_domain_start(&bebob->domain, ir_delay_cycle);
+ tx_init_skip_cycles = 16000;
+ err = amdtp_domain_start(&bebob->domain, tx_init_skip_cycles);
if (err < 0)
goto error;
@@ -684,6 +677,8 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob)
}
}
+ // Some devices postpone start of transmission mostly for 1 sec after receives
+ // packets firstly.
if (!amdtp_stream_wait_callback(&bebob->rx_stream,
CALLBACK_TIMEOUT) ||
!amdtp_stream_wait_callback(&bebob->tx_stream,