-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ALSA: firewire-motu: handle transactions specific for MOTU FireWire m…
…odels All models of MOTU FireWire series can be controlled by write transaction to addresses in a range from 0x'ffff'f0000'0b00 to 0x'ffff'f000'0cff. The models support asynchronous notification. This notification has 32 bit field data, and is transferred when status of clock changes. Meaning of the value is not enough clear yet. Drivers can register its address to receive the notification. Write transaction to 0x'ffff'f000'0b04 registers higher 16 bits of the address. Write transaction to 0x'ffff'f0000'0b08 registers the rest of bits. The address includes node ID, thus it should be registered every time of bus reset. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
- Loading branch information
Takashi Sakamoto
authored and
Takashi Iwai
committed
Mar 28, 2017
1 parent
4641c93
commit 2e76701
Showing
4 changed files
with
140 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
snd-firewire-motu-objs := motu.o amdtp-motu.o | ||
snd-firewire-motu-objs := motu.o amdtp-motu.o motu-transaction.o | ||
obj-$(CONFIG_SND_FIREWIRE_MOTU) += snd-firewire-motu.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/* | ||
* motu-transaction.c - a part of driver for MOTU FireWire series | ||
* | ||
* Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp> | ||
* | ||
* Licensed under the terms of the GNU General Public License, version 2. | ||
*/ | ||
|
||
|
||
#include "motu.h" | ||
|
||
#define SND_MOTU_ADDR_BASE 0xfffff0000000ULL | ||
#define ASYNC_ADDR_HI 0x0b04 | ||
#define ASYNC_ADDR_LO 0x0b08 | ||
|
||
int snd_motu_transaction_read(struct snd_motu *motu, u32 offset, __be32 *reg, | ||
size_t size) | ||
{ | ||
int tcode; | ||
|
||
if (size % sizeof(__be32) > 0 || size <= 0) | ||
return -EINVAL; | ||
if (size == sizeof(__be32)) | ||
tcode = TCODE_READ_QUADLET_REQUEST; | ||
else | ||
tcode = TCODE_READ_BLOCK_REQUEST; | ||
|
||
return snd_fw_transaction(motu->unit, tcode, | ||
SND_MOTU_ADDR_BASE + offset, reg, size, 0); | ||
} | ||
|
||
int snd_motu_transaction_write(struct snd_motu *motu, u32 offset, __be32 *reg, | ||
size_t size) | ||
{ | ||
int tcode; | ||
|
||
if (size % sizeof(__be32) > 0 || size <= 0) | ||
return -EINVAL; | ||
if (size == sizeof(__be32)) | ||
tcode = TCODE_WRITE_QUADLET_REQUEST; | ||
else | ||
tcode = TCODE_WRITE_BLOCK_REQUEST; | ||
|
||
return snd_fw_transaction(motu->unit, tcode, | ||
SND_MOTU_ADDR_BASE + offset, reg, size, 0); | ||
} | ||
|
||
static void handle_message(struct fw_card *card, struct fw_request *request, | ||
int tcode, int destination, int source, | ||
int generation, unsigned long long offset, | ||
void *data, size_t length, void *callback_data) | ||
{ | ||
fw_send_response(card, request, RCODE_COMPLETE); | ||
} | ||
|
||
int snd_motu_transaction_reregister(struct snd_motu *motu) | ||
{ | ||
struct fw_device *device = fw_parent_device(motu->unit); | ||
__be32 data; | ||
int err; | ||
|
||
if (motu->async_handler.callback_data == NULL) | ||
return -EINVAL; | ||
|
||
/* Register messaging address. Block transaction is not allowed. */ | ||
data = cpu_to_be32((device->card->node_id << 16) | | ||
(motu->async_handler.offset >> 32)); | ||
err = snd_motu_transaction_write(motu, ASYNC_ADDR_HI, &data, | ||
sizeof(data)); | ||
if (err < 0) | ||
return err; | ||
|
||
data = cpu_to_be32(motu->async_handler.offset); | ||
return snd_motu_transaction_write(motu, ASYNC_ADDR_LO, &data, | ||
sizeof(data)); | ||
} | ||
|
||
int snd_motu_transaction_register(struct snd_motu *motu) | ||
{ | ||
static const struct fw_address_region resp_register_region = { | ||
.start = 0xffffe0000000ull, | ||
.end = 0xffffe000ffffull, | ||
}; | ||
int err; | ||
|
||
/* Perhaps, 4 byte messages are transferred. */ | ||
motu->async_handler.length = 4; | ||
motu->async_handler.address_callback = handle_message; | ||
motu->async_handler.callback_data = motu; | ||
|
||
err = fw_core_add_address_handler(&motu->async_handler, | ||
&resp_register_region); | ||
if (err < 0) | ||
return err; | ||
|
||
err = snd_motu_transaction_reregister(motu); | ||
if (err < 0) { | ||
fw_core_remove_address_handler(&motu->async_handler); | ||
motu->async_handler.address_callback = NULL; | ||
} | ||
|
||
return err; | ||
} | ||
|
||
void snd_motu_transaction_unregister(struct snd_motu *motu) | ||
{ | ||
__be32 data; | ||
|
||
if (motu->async_handler.address_callback != NULL) | ||
fw_core_remove_address_handler(&motu->async_handler); | ||
motu->async_handler.address_callback = NULL; | ||
|
||
/* Unregister the address. */ | ||
data = cpu_to_be32(0x00000000); | ||
snd_motu_transaction_write(motu, ASYNC_ADDR_HI, &data, sizeof(data)); | ||
snd_motu_transaction_write(motu, ASYNC_ADDR_LO, &data, sizeof(data)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters