diff mbox series

ALSA: firewire-motu: add support for MOTU 896HD

Message ID 20210823085741.33864-1-o-takashi@sakamocchi.jp
State Accepted
Commit 23c671be97b9e49846d03ceb0bce3731f4b869ac
Headers show
Series ALSA: firewire-motu: add support for MOTU 896HD | expand

Commit Message

Takashi Sakamoto Aug. 23, 2021, 8:57 a.m. UTC
Mark of the Unicorn (MOTU) shipped 896HD 2003 as one of models in second
generation of its FireWire series, and already discontinued it. The model
consists of below ICs:

 * Texas Instruments TSB41AB2
 * Phillips Semiconductors PDI1394L40
 * Altera cyclone EP1C3
 * Texas Instruments TMS320VC5402

It supports sampling transmission frequency up to 192.0 kHz. The packet
format differs depending on both of sampling transfer frequency and enabling
ADAT channels. The model doesn't support MIDI message transmission.

This commit adds support for it.

$ python3 crpp < /sys/bus/firewire/devices/fw1/config_rom
               ROM header and bus information block
               -----------------------------------------------------------------
400  04101b66  bus_info_length 4, crc_length 16, crc 7014
404  31333934  bus_name "1394"
408  20001000  irmc 0, cmc 0, isc 1, bmc 0, cyc_clk_acc 0, max_rec 1 (4)
40c  0001f200  company_id 0001f2     |
410  0001dbce  device_id 000001dbce  | EUI-64 0001f2000001dbce

               root directory
               -----------------------------------------------------------------
414  0004c65c  directory_length 4, crc 50780
418  030001f2  vendor
41c  0c0083c0  node capabilities per IEEE 1394
420  8d000006  --> eui-64 leaf at 438
424  d1000001  --> unit directory at 428

               unit directory at 428
               -----------------------------------------------------------------
428  0003dcc1  directory_length 3, crc 56513
42c  120001f2  specifier id
430  13000005  version
434  17102800  model

               eui-64 leaf at 438
               -----------------------------------------------------------------
438  000264f2  leaf_length 2, crc 25842
43c  0001f200  company_id 0001f2     |
440  0001dbce  device_id 000001dbce  | EUI-64 0001f2000001dbce

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 sound/firewire/motu/motu-protocol-v2.c | 22 ++++++++++++++++++----
 sound/firewire/motu/motu.c             |  1 +
 sound/firewire/motu/motu.h             |  1 +
 3 files changed, 20 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c
index 93d5df1ae550..2bd4485e4bc7 100644
--- a/sound/firewire/motu/motu-protocol-v2.c
+++ b/sound/firewire/motu/motu-protocol-v2.c
@@ -12,11 +12,11 @@ 
 #define  V2_CLOCK_RATE_SHIFT			3
 #define  V2_CLOCK_SRC_MASK			0x00000007
 #define  V2_CLOCK_SRC_SHIFT			0
-#define   V2_CLOCK_SRC_AESEBU_ON_XLR		0x07
+#define   V2_CLOCK_SRC_AESEBU_ON_XLR		0x07	// In Traveler.
 #define   V2_CLOCK_SRC_ADAT_ON_DSUB		0x05
 #define   V2_CLOCK_SRC_WORD_ON_BNC		0x04
 #define   V2_CLOCK_SRC_SPH			0x03
-#define   V2_CLOCK_SRC_SPDIF			0x02	// on either coaxial or optical
+#define   V2_CLOCK_SRC_SPDIF			0x02	// on either coaxial or optical. AES/EBU in 896HD.
 #define   V2_CLOCK_SRC_ADAT_ON_OPT		0x01
 #define   V2_CLOCK_SRC_INTERNAL			0x00
 #define  V2_CLOCK_FETCH_ENABLE			0x02000000
@@ -100,7 +100,9 @@  static int get_clock_source(struct snd_motu *motu, u32 data,
 		bool support_iec60958_on_opt = (motu->spec == &snd_motu_spec_828mk2 ||
 						motu->spec == &snd_motu_spec_traveler);
 
-		if (!support_iec60958_on_opt) {
+		if (motu->spec == &snd_motu_spec_896hd) {
+			*src = SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR;
+		} else if (!support_iec60958_on_opt) {
 			*src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX;
 		} else {
 			__be32 reg;
@@ -129,6 +131,7 @@  static int get_clock_source(struct snd_motu *motu, u32 data,
 		*src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB;
 		break;
 	case V2_CLOCK_SRC_AESEBU_ON_XLR:
+		// For Traveler.
 		*src = SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR;
 		break;
 	default:
@@ -153,7 +156,7 @@  int snd_motu_protocol_v2_get_clock_source(struct snd_motu *motu,
 	return get_clock_source(motu, be32_to_cpu(reg), src);
 }
 
-// Expected for Traveler and 896HD, which implements Altera Cyclone EP1C3.
+// Expected for Traveler, which implements Altera Cyclone EP1C3.
 static int switch_fetching_mode_cyclone(struct snd_motu *motu, u32 *data,
 					bool enable)
 {
@@ -190,6 +193,9 @@  int snd_motu_protocol_v2_switch_fetching_mode(struct snd_motu *motu,
 	if (motu->spec == &snd_motu_spec_828mk2) {
 		// 828mkII implements Altera ACEX 1K EP1K30. Nothing to do.
 		return 0;
+	} else if (motu->spec == &snd_motu_spec_896hd) {
+		// 896HD implements Altera Cyclone EP1C3 but nothing to do.
+		return 0;
 	} else {
 		__be32 reg;
 		u32 data;
@@ -274,6 +280,14 @@  const struct snd_motu_spec snd_motu_spec_828mk2 = {
 	.rx_fixed_pcm_chunks = {14, 14, 0},
 };
 
+const struct snd_motu_spec snd_motu_spec_896hd = {
+	.name = "896HD",
+	.protocol_version = SND_MOTU_PROTOCOL_V2,
+	// No support for MIDI.
+	.tx_fixed_pcm_chunks = {14, 14, 8},
+	.rx_fixed_pcm_chunks = {14, 14, 8},
+};
+
 const struct snd_motu_spec snd_motu_spec_traveler = {
 	.name = "Traveler",
 	.protocol_version = SND_MOTU_PROTOCOL_V2,
diff --git a/sound/firewire/motu/motu.c b/sound/firewire/motu/motu.c
index 543136578c70..f65426238d4c 100644
--- a/sound/firewire/motu/motu.c
+++ b/sound/firewire/motu/motu.c
@@ -153,6 +153,7 @@  static const struct ieee1394_device_id motu_id_table[] = {
 	SND_MOTU_DEV_ENTRY(0x000001, &snd_motu_spec_828),
 	SND_MOTU_DEV_ENTRY(0x000002, &snd_motu_spec_896),
 	SND_MOTU_DEV_ENTRY(0x000003, &snd_motu_spec_828mk2),
+	SND_MOTU_DEV_ENTRY(0x000005, &snd_motu_spec_896hd),
 	SND_MOTU_DEV_ENTRY(0x000009, &snd_motu_spec_traveler),
 	SND_MOTU_DEV_ENTRY(0x00000d, &snd_motu_spec_ultralite),
 	SND_MOTU_DEV_ENTRY(0x00000f, &snd_motu_spec_8pre),
diff --git a/sound/firewire/motu/motu.h b/sound/firewire/motu/motu.h
index 73f36d1be515..f1a830b358d4 100644
--- a/sound/firewire/motu/motu.h
+++ b/sound/firewire/motu/motu.h
@@ -126,6 +126,7 @@  extern const struct snd_motu_spec snd_motu_spec_828;
 extern const struct snd_motu_spec snd_motu_spec_896;
 
 extern const struct snd_motu_spec snd_motu_spec_828mk2;
+extern const struct snd_motu_spec snd_motu_spec_896hd;
 extern const struct snd_motu_spec snd_motu_spec_traveler;
 extern const struct snd_motu_spec snd_motu_spec_ultralite;
 extern const struct snd_motu_spec snd_motu_spec_8pre;