diff options
Diffstat (limited to 'sound/firewire/fireface')
-rw-r--r-- | sound/firewire/fireface/amdtp-ff.c | 2 | ||||
-rw-r--r-- | sound/firewire/fireface/ff-stream.c | 13 | ||||
-rw-r--r-- | sound/firewire/fireface/ff.c | 90 | ||||
-rw-r--r-- | sound/firewire/fireface/ff.h | 3 |
4 files changed, 36 insertions, 72 deletions
diff --git a/sound/firewire/fireface/amdtp-ff.c b/sound/firewire/fireface/amdtp-ff.c index 119c0076b17a..98177b0666d3 100644 --- a/sound/firewire/fireface/amdtp-ff.c +++ b/sound/firewire/fireface/amdtp-ff.c @@ -168,6 +168,6 @@ int amdtp_ff_init(struct amdtp_stream *s, struct fw_unit *unit, else process_ctx_payloads = process_it_ctx_payloads; - return amdtp_stream_init(s, unit, dir, CIP_NO_HEADER, 0, + return amdtp_stream_init(s, unit, dir, CIP_BLOCKING | CIP_UNAWARE_SYT | CIP_NO_HEADER, 0, process_ctx_payloads, sizeof(struct amdtp_ff)); } diff --git a/sound/firewire/fireface/ff-stream.c b/sound/firewire/fireface/ff-stream.c index 5452115c0ef9..95bf405adb3d 100644 --- a/sound/firewire/fireface/ff-stream.c +++ b/sound/firewire/fireface/ff-stream.c @@ -7,7 +7,7 @@ #include "ff.h" -#define CALLBACK_TIMEOUT_MS 200 +#define READY_TIMEOUT_MS 200 int snd_ff_stream_get_multiplier_mode(enum cip_sfc sfc, enum snd_ff_stream_mode *mode) @@ -199,14 +199,15 @@ int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate) if (err < 0) goto error; - err = amdtp_domain_start(&ff->domain, 0); + // NOTE: The device doesn't transfer packets unless receiving any packet. The + // sequence of tx packets includes cycle skip corresponding to empty packet or + // NODATA packet in IEC 61883-1/6. The sequence of the number of data blocks per + // packet is important for media clock recovery. + err = amdtp_domain_start(&ff->domain, 0, true, true); if (err < 0) goto error; - if (!amdtp_stream_wait_callback(&ff->rx_stream, - CALLBACK_TIMEOUT_MS) || - !amdtp_stream_wait_callback(&ff->tx_stream, - CALLBACK_TIMEOUT_MS)) { + if (!amdtp_domain_wait_ready(&ff->domain, READY_TIMEOUT_MS)) { err = -ETIMEDOUT; goto error; } diff --git a/sound/firewire/fireface/ff.c b/sound/firewire/fireface/ff.c index bc39269415d2..7bf51d062021 100644 --- a/sound/firewire/fireface/ff.c +++ b/sound/firewire/fireface/ff.c @@ -42,22 +42,33 @@ static void ff_card_free(struct snd_card *card) snd_ff_stream_destroy_duplex(ff); snd_ff_transaction_unregister(ff); + + mutex_destroy(&ff->mutex); + fw_unit_put(ff->unit); } -static void do_registration(struct work_struct *work) +static int snd_ff_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry) { - struct snd_ff *ff = container_of(work, struct snd_ff, dwork.work); + struct snd_card *card; + struct snd_ff *ff; int err; - if (ff->registered) - return; - - err = snd_card_new(&ff->unit->device, -1, NULL, THIS_MODULE, 0, - &ff->card); + err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, sizeof(*ff), &card); if (err < 0) - return; - ff->card->private_free = ff_card_free; - ff->card->private_data = ff; + return err; + card->private_free = ff_card_free; + + ff = card->private_data; + ff->unit = fw_unit_get(unit); + dev_set_drvdata(&unit->device, ff); + ff->card = card; + + mutex_init(&ff->mutex); + spin_lock_init(&ff->lock); + init_waitqueue_head(&ff->hwdep_wait); + + ff->unit_version = entry->version; + ff->spec = (const struct snd_ff_spec *)entry->driver_data; err = snd_ff_transaction_register(ff); if (err < 0) @@ -83,76 +94,31 @@ static void do_registration(struct work_struct *work) if (err < 0) goto error; - err = snd_card_register(ff->card); + err = snd_card_register(card); if (err < 0) goto error; - ff->registered = true; - - return; -error: - snd_card_free(ff->card); - dev_info(&ff->unit->device, - "Sound card registration failed: %d\n", err); -} - -static int snd_ff_probe(struct fw_unit *unit, - const struct ieee1394_device_id *entry) -{ - struct snd_ff *ff; - - ff = devm_kzalloc(&unit->device, sizeof(struct snd_ff), GFP_KERNEL); - if (!ff) - return -ENOMEM; - ff->unit = fw_unit_get(unit); - dev_set_drvdata(&unit->device, ff); - - mutex_init(&ff->mutex); - spin_lock_init(&ff->lock); - init_waitqueue_head(&ff->hwdep_wait); - - ff->unit_version = entry->version; - ff->spec = (const struct snd_ff_spec *)entry->driver_data; - - /* Register this sound card later. */ - INIT_DEFERRABLE_WORK(&ff->dwork, do_registration); - snd_fw_schedule_registration(unit, &ff->dwork); - return 0; +error: + snd_card_free(card); + return err; } static void snd_ff_update(struct fw_unit *unit) { struct snd_ff *ff = dev_get_drvdata(&unit->device); - /* Postpone a workqueue for deferred registration. */ - if (!ff->registered) - snd_fw_schedule_registration(unit, &ff->dwork); - snd_ff_transaction_reregister(ff); - if (ff->registered) - snd_ff_stream_update_duplex(ff); + snd_ff_stream_update_duplex(ff); } static void snd_ff_remove(struct fw_unit *unit) { struct snd_ff *ff = dev_get_drvdata(&unit->device); - /* - * Confirm to stop the work for registration before the sound card is - * going to be released. The work is not scheduled again because bus - * reset handler is not called anymore. - */ - cancel_work_sync(&ff->dwork.work); - - if (ff->registered) { - // Block till all of ALSA character devices are released. - snd_card_free(ff->card); - } - - mutex_destroy(&ff->mutex); - fw_unit_put(ff->unit); + // Block till all of ALSA character devices are released. + snd_card_free(ff->card); } static const struct snd_ff_spec spec_ff800 = { diff --git a/sound/firewire/fireface/ff.h b/sound/firewire/fireface/ff.h index 705e7df4f929..0535f0b58b67 100644 --- a/sound/firewire/fireface/ff.h +++ b/sound/firewire/fireface/ff.h @@ -69,9 +69,6 @@ struct snd_ff { struct mutex mutex; spinlock_t lock; - bool registered; - struct delayed_work dwork; - enum snd_ff_unit_version unit_version; const struct snd_ff_spec *spec; |