aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorTakashi Sakamoto2017-03-22 21:30:25 +0900
committerTakashi Iwai2017-03-28 12:34:06 +0200
commit5aaab1bf37ede45df4f5d13d735faf824edf3ec8 (patch)
treeb1c358629796556f57cf52faf832d226b7b2338d /sound
parent71c3797779d3cd8378767f5b2d8cfd3b2f88c5c1 (diff)
ALSA: firewire-motu: enable to read transaction cache via hwdep interface
MOTU FireWire series can transfer messages to registered address. These messages are transferred for the status of internal clock synchronization just after starting streams. When the synchronization is stable, it's 0x01ffffff. Else, it's 0x05ffffff. This commit adds a functionality for user space applications to receive content of the message. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/firewire/motu/motu-hwdep.c10
-rw-r--r--sound/firewire/motu/motu-transaction.c20
2 files changed, 28 insertions, 2 deletions
diff --git a/sound/firewire/motu/motu-hwdep.c b/sound/firewire/motu/motu-hwdep.c
index e795a5219a21..b87ccb69d597 100644
--- a/sound/firewire/motu/motu-hwdep.c
+++ b/sound/firewire/motu/motu-hwdep.c
@@ -26,7 +26,7 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
spin_lock_irq(&motu->lock);
- while (!motu->dev_lock_changed) {
+ while (!motu->dev_lock_changed && motu->msg == 0) {
prepare_to_wait(&motu->hwdep_wait, &wait, TASK_INTERRUPTIBLE);
spin_unlock_irq(&motu->lock);
schedule();
@@ -43,6 +43,12 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
motu->dev_lock_changed = false;
count = min_t(long, count, sizeof(event.lock_status));
+ } else {
+ event.motu_notification.type = SNDRV_FIREWIRE_EVENT_MOTU_NOTIFICATION;
+ event.motu_notification.message = motu->msg;
+ motu->msg = 0;
+
+ count = min_t(long, count, sizeof(event.motu_notification));
}
spin_unlock_irq(&motu->lock);
@@ -62,7 +68,7 @@ static unsigned int hwdep_poll(struct snd_hwdep *hwdep, struct file *file,
poll_wait(file, &motu->hwdep_wait, wait);
spin_lock_irq(&motu->lock);
- if (motu->dev_lock_changed)
+ if (motu->dev_lock_changed || motu->msg)
events = POLLIN | POLLRDNORM;
else
events = 0;
diff --git a/sound/firewire/motu/motu-transaction.c b/sound/firewire/motu/motu-transaction.c
index 416dd9833896..7fc30091e0de 100644
--- a/sound/firewire/motu/motu-transaction.c
+++ b/sound/firewire/motu/motu-transaction.c
@@ -50,7 +50,27 @@ static void handle_message(struct fw_card *card, struct fw_request *request,
int generation, unsigned long long offset,
void *data, size_t length, void *callback_data)
{
+ struct snd_motu *motu = callback_data;
+ __be32 *buf = (__be32 *)data;
+ unsigned long flags;
+
+ if (tcode != TCODE_WRITE_QUADLET_REQUEST) {
+ fw_send_response(card, request, RCODE_COMPLETE);
+ return;
+ }
+
+ if (offset != motu->async_handler.offset || length != 4) {
+ fw_send_response(card, request, RCODE_ADDRESS_ERROR);
+ return;
+ }
+
+ spin_lock_irqsave(&motu->lock, flags);
+ motu->msg = be32_to_cpu(*buf);
+ spin_unlock_irqrestore(&motu->lock, flags);
+
fw_send_response(card, request, RCODE_COMPLETE);
+
+ wake_up(&motu->hwdep_wait);
}
int snd_motu_transaction_reregister(struct snd_motu *motu)