diff mbox series

ALSA: dice: add support for Focusrite Saffire Pro 40 with TCD3070 ASIC

Message ID 20221130143313.43880-1-o-takashi@sakamocchi.jp
State Accepted
Commit 2133dc91d6658242009177b564ac47c49e08668a
Headers show
Series ALSA: dice: add support for Focusrite Saffire Pro 40 with TCD3070 ASIC | expand

Commit Message

Takashi Sakamoto Nov. 30, 2022, 2:33 p.m. UTC
TC Applied Technologies (TCAT) produces TCD3070 as final DICE ASIC for
communication in IEEE 1394 bus for IEC 61883-1/6 protocol. As long as I
know, latter model of Focusrite Saffire Pro 40 is an application of the
ASIC and only in the market for consumers.

This patchset adds support for the device. The device has several
remarkable points.

1. No support for extended synchronization information section in TCAT
general protocol. The value of GLOBAL_EXTENDED_STATUS register is always
zero. Additionally, NOTIFY_EXT_STATUS message is never emitted.

2. No support for TCAT protocol extension. Hard coding is required for
format of CIP payload.

3. During several seconds after changing sampling rate, the block to
process PCM frames is under disfunction. When starting packet streaming
during the state, the block is never function till configuring different
sampling rate and several seconds.

This commit adds support for the device. The item 1 and 2 can be
adaptable, while item 3 is not. It's not preferable that user process
is forced to sleep during the disfunction in the call of ioctl(2) with
SNDRV_PCM_IOCTL_HW_PARAMS or SNDRV_PCM_IOCTL_PREPARE request. It's
inconvenient but let user configure preferable sampling rate in advance
of starting PCM substream.

The content of configuration ROM in the device I used is available at:
 * https://github.com/takaswie/am-config-roms/

I note that any mixer control operation is implemented by unique
transaction. The frame of request consists of 16 bytes header followed
by payload.

header (4 quadlets):
1st: the type of request, prefixed with 0x8000
2nd: counter at 2 bytes in MSB side, the length of data at 2 bytes in LSB
     side
3rd: parameter 0
4th: parameter 1

payload (variable length if need):
5th-: data according to parameters

The request frame is sent by block write request to 0x'ffff'e040'01c0.

The frame of response is similar to the frame of request, but it is
header only, thus fixed to 16 bytes. The response frame is sent to the
address which is registered by lock transaction to 0x'ffff'e040'0008.

If the operation results in batch of data, the 2nd quadlet of header
includes the length of data like request. The data is itself readable
by read block request to 0x'ffff'e040'0030, which includes both
header and payload for data, thus the length to read should be the
length of data plus 16 bytes for header

The actual value of request, parameter 0, parameter 1, and data is
unclear yet.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 sound/firewire/dice/Makefile         |  2 +-
 sound/firewire/dice/dice-focusrite.c | 25 +++++++++++++++++++++++++
 sound/firewire/dice/dice.c           | 10 ++++++++++
 sound/firewire/dice/dice.h           |  1 +
 4 files changed, 37 insertions(+), 1 deletion(-)
 create mode 100644 sound/firewire/dice/dice-focusrite.c
diff mbox series

Patch

diff --git a/sound/firewire/dice/Makefile b/sound/firewire/dice/Makefile
index 9bf7b960a720..a5f3fbf28b8c 100644
--- a/sound/firewire/dice/Makefile
+++ b/sound/firewire/dice/Makefile
@@ -2,5 +2,5 @@ 
 snd-dice-objs := dice-transaction.o dice-stream.o dice-proc.o dice-midi.o \
 		 dice-pcm.o dice-hwdep.o dice.o dice-tcelectronic.o \
 		 dice-alesis.o dice-extension.o dice-mytek.o dice-presonus.o \
-		 dice-harman.o
+		 dice-harman.o dice-focusrite.o
 obj-$(CONFIG_SND_DICE) += snd-dice.o
diff --git a/sound/firewire/dice/dice-focusrite.c b/sound/firewire/dice/dice-focusrite.c
new file mode 100644
index 000000000000..caf9f620c5d0
--- /dev/null
+++ b/sound/firewire/dice/dice-focusrite.c
@@ -0,0 +1,25 @@ 
+// SPDX-License-Identifier: GPL-2.0
+// dice-focusrite.c - a part of driver for DICE based devices
+//
+// Copyright (c) 2022 Takashi Sakamoto
+//
+// Licensed under the terms of the GNU General Public License, version 2.
+
+#include "dice.h"
+
+int snd_dice_detect_focusrite_pro40_tcd3070_formats(struct snd_dice *dice)
+{
+	// Focusrite shipped several variants of Saffire Pro 40. One of them is based on TCD3070-CH
+	// apart from the others with TCD2220. It doesn't support TCAT protocol extension.
+	dice->tx_pcm_chs[0][0] = 20;
+	dice->tx_midi_ports[0] = 1;
+	dice->rx_pcm_chs[0][0] = 20;
+	dice->rx_midi_ports[0] = 1;
+
+	dice->tx_pcm_chs[0][1] = 16;
+	dice->tx_midi_ports[1] = 1;
+	dice->rx_pcm_chs[0][1] = 16;
+	dice->rx_midi_ports[1] = 1;
+
+	return 0;
+}
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c
index f75902bc8e74..6036a5edbcb8 100644
--- a/sound/firewire/dice/dice.c
+++ b/sound/firewire/dice/dice.c
@@ -382,6 +382,16 @@  static const struct ieee1394_device_id dice_id_table[] = {
 		.model_id	= 0x000001,
 		.driver_data	= (kernel_ulong_t)snd_dice_detect_harman_formats,
 	},
+	// Focusrite Saffire Pro 40 with TCD3070-CH.
+	// The model has quirk in its GUID, in which model field is 0x000013 and different from
+	// model ID (0x0000de) in its root/unit directory.
+	{
+		.match_flags	= IEEE1394_MATCH_VENDOR_ID |
+				  IEEE1394_MATCH_MODEL_ID,
+		.vendor_id	= OUI_FOCUSRITE,
+		.model_id	= 0x0000de,
+		.driver_data	= (kernel_ulong_t)snd_dice_detect_focusrite_pro40_tcd3070_formats,
+	},
 	{
 		.match_flags = IEEE1394_MATCH_VERSION,
 		.version     = DICE_INTERFACE,
diff --git a/sound/firewire/dice/dice.h b/sound/firewire/dice/dice.h
index fd440cc625f9..674f7d552c2e 100644
--- a/sound/firewire/dice/dice.h
+++ b/sound/firewire/dice/dice.h
@@ -231,5 +231,6 @@  int snd_dice_detect_extension_formats(struct snd_dice *dice);
 int snd_dice_detect_mytek_formats(struct snd_dice *dice);
 int snd_dice_detect_presonus_formats(struct snd_dice *dice);
 int snd_dice_detect_harman_formats(struct snd_dice *dice);
+int snd_dice_detect_focusrite_pro40_tcd3070_formats(struct snd_dice *dice);
 
 #endif