summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2022-11-30 23:33:13 +0900
committerTakashi Iwai <tiwai@suse.de>2022-11-30 16:16:38 +0100
commit2133dc91d6658242009177b564ac47c49e08668a (patch)
treeba06de21b3ff0b7444ddb95784742894f57a2b8c /sound
parentb310092e3eec6e7be36ed2436577f406a1e5e8de (diff)
downloadlinux-2133dc91d6658242009177b564ac47c49e08668a.tar.gz
linux-2133dc91d6658242009177b564ac47c49e08668a.tar.bz2
linux-2133dc91d6658242009177b564ac47c49e08668a.zip
ALSA: dice: add support for Focusrite Saffire Pro 40 with TCD3070 ASIC
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> Link: https://lore.kernel.org/r/20221130143313.43880-1-o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/firewire/dice/Makefile2
-rw-r--r--sound/firewire/dice/dice-focusrite.c25
-rw-r--r--sound/firewire/dice/dice.c10
-rw-r--r--sound/firewire/dice/dice.h1
4 files changed, 37 insertions, 1 deletions
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