2019-05-30 07:57:59 +08:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
2017-03-22 20:30:11 +08:00
|
|
|
/*
|
|
|
|
* motu.h - a part of driver for MOTU FireWire series
|
|
|
|
*
|
|
|
|
* Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SOUND_FIREWIRE_MOTU_H_INCLUDED
|
|
|
|
#define SOUND_FIREWIRE_MOTU_H_INCLUDED
|
|
|
|
|
|
|
|
#include <linux/device.h>
|
|
|
|
#include <linux/firewire.h>
|
|
|
|
#include <linux/firewire-constants.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/mod_devicetable.h>
|
|
|
|
#include <linux/mutex.h>
|
|
|
|
#include <linux/slab.h>
|
2017-03-22 20:30:24 +08:00
|
|
|
#include <linux/compat.h>
|
|
|
|
#include <linux/sched/signal.h>
|
2017-03-22 20:30:11 +08:00
|
|
|
|
|
|
|
#include <sound/control.h>
|
|
|
|
#include <sound/core.h>
|
ALSA: firewire-motu: add MOTU specific protocol layer
MOTU FireWire series uses blocking transmission for AMDTP packet streaming.
They transmit/receive 8,000 packets per second, to handle the same number
of data blocks as current sampling transmission frequency. Thus,
IEC 61883-1/6 packet streaming engine of ALSA firewire stack is available
for them.
However, the sequence of packet and data blocks includes some quirks.
Below sample is a sequence of CIP headers of packets received by 828mk2,
at 44.1kHz of sampling transmission frequency.
quads CIP1 CIP2
488 0x020F04E8 0x8222FFFF
8 0x020F04F8 0x8222FFFF
488 0x020F0400 0x8222FFFF
488 0x020F0408 0x8222FFFF
8 0x020F04E8 0x8222FFFF
488 0x020F04F0 0x8222FFFF
488 0x020F04F8 0x8222FFFF
The SID (source node ID), DBS (data block size), SPH (source packet header),
FMT (format ID), FDF (format dependent field) and SYT (time stamp) fields
are in IEC 61883-1. Especially, FMT is 0x02, FDF is 0x22 and SYT is 0xffff
to define MOTU specific protocol. In an aspect of dbc field, the value
represents accumulated number of data blocks included the packet. This
is against IEC 61883-1, because according to the specification this value
should be the number of data blocks already transferred.
In ALSA IEC 61883-1/6 engine, this quirk is already supported by
CIP_DBC_IS_END_EVENT flag, because Echo Audio Fireworks has.
Each data block includes SPH as its first quadlet field, to represent its
presentation time stamp. Actual value of SPH is compliant to IEC 61883-1;
lower 25 bits of 32 bits width consists of 13 bits cycle count and 12 bits
cycle offset.
The rest of each data block consists of 24 bit chunks. All of PCM samples,
MIDI messages, status and control messages are transferred by the chunks.
This is similar to '24-bit * 4 Audio Pack' in IEC 61883-6. The position of
each kind of data depends on generations of each model. The number of
whole chunks in a data block is a multiple of 4, to consists of
quadlet-aligned packets.
This commit adds data block processing layer specific for the MOTU
protocol. The remarkable point is the way to generate SPH header. Time
stamps for each data blocks are generated by below calculation:
* Using pre-computed table for the number of ticks per event
* 44,1kHz: (557 + 123/441)
* 48.0kHz: (512 + 0/441)
* 88.2kHz: (278 + 282/441)
* 96.0kHz: (256 + 0/441)
* 176.4kHz: (139 + 141/441)
* 192.0kHz: (128 + 0/441)
* Accumulate the ticks and set the value to SPH for every events.
* This way makes sense only for blocking transmission because this mode
transfers fixed number or none of events.
This calculation assumes that each data block has a PCM frame which is
sampled according to event timing clock. Current packet streaming layer
has the same assumption.
Although this sequence works fine for MOTU FireWire series at sampling
transmission frequency based on 48.0kHz, it is not enough at the frequency
based on 44.1kHz. The units generate choppy noise every few seconds.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-22 20:30:18 +08:00
|
|
|
#include <sound/pcm.h>
|
2017-03-22 20:30:21 +08:00
|
|
|
#include <sound/info.h>
|
2017-03-22 20:30:23 +08:00
|
|
|
#include <sound/rawmidi.h>
|
2017-03-22 20:30:24 +08:00
|
|
|
#include <sound/firewire.h>
|
|
|
|
#include <sound/hwdep.h>
|
2017-03-22 20:30:11 +08:00
|
|
|
|
2017-03-22 20:30:12 +08:00
|
|
|
#include "../lib.h"
|
ALSA: firewire-motu: add MOTU specific protocol layer
MOTU FireWire series uses blocking transmission for AMDTP packet streaming.
They transmit/receive 8,000 packets per second, to handle the same number
of data blocks as current sampling transmission frequency. Thus,
IEC 61883-1/6 packet streaming engine of ALSA firewire stack is available
for them.
However, the sequence of packet and data blocks includes some quirks.
Below sample is a sequence of CIP headers of packets received by 828mk2,
at 44.1kHz of sampling transmission frequency.
quads CIP1 CIP2
488 0x020F04E8 0x8222FFFF
8 0x020F04F8 0x8222FFFF
488 0x020F0400 0x8222FFFF
488 0x020F0408 0x8222FFFF
8 0x020F04E8 0x8222FFFF
488 0x020F04F0 0x8222FFFF
488 0x020F04F8 0x8222FFFF
The SID (source node ID), DBS (data block size), SPH (source packet header),
FMT (format ID), FDF (format dependent field) and SYT (time stamp) fields
are in IEC 61883-1. Especially, FMT is 0x02, FDF is 0x22 and SYT is 0xffff
to define MOTU specific protocol. In an aspect of dbc field, the value
represents accumulated number of data blocks included the packet. This
is against IEC 61883-1, because according to the specification this value
should be the number of data blocks already transferred.
In ALSA IEC 61883-1/6 engine, this quirk is already supported by
CIP_DBC_IS_END_EVENT flag, because Echo Audio Fireworks has.
Each data block includes SPH as its first quadlet field, to represent its
presentation time stamp. Actual value of SPH is compliant to IEC 61883-1;
lower 25 bits of 32 bits width consists of 13 bits cycle count and 12 bits
cycle offset.
The rest of each data block consists of 24 bit chunks. All of PCM samples,
MIDI messages, status and control messages are transferred by the chunks.
This is similar to '24-bit * 4 Audio Pack' in IEC 61883-6. The position of
each kind of data depends on generations of each model. The number of
whole chunks in a data block is a multiple of 4, to consists of
quadlet-aligned packets.
This commit adds data block processing layer specific for the MOTU
protocol. The remarkable point is the way to generate SPH header. Time
stamps for each data blocks are generated by below calculation:
* Using pre-computed table for the number of ticks per event
* 44,1kHz: (557 + 123/441)
* 48.0kHz: (512 + 0/441)
* 88.2kHz: (278 + 282/441)
* 96.0kHz: (256 + 0/441)
* 176.4kHz: (139 + 141/441)
* 192.0kHz: (128 + 0/441)
* Accumulate the ticks and set the value to SPH for every events.
* This way makes sense only for blocking transmission because this mode
transfers fixed number or none of events.
This calculation assumes that each data block has a PCM frame which is
sampled according to event timing clock. Current packet streaming layer
has the same assumption.
Although this sequence works fine for MOTU FireWire series at sampling
transmission frequency based on 48.0kHz, it is not enough at the frequency
based on 44.1kHz. The units generate choppy noise every few seconds.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-22 20:30:18 +08:00
|
|
|
#include "../amdtp-stream.h"
|
2017-03-22 20:30:20 +08:00
|
|
|
#include "../iso-resources.h"
|
2017-03-22 20:30:12 +08:00
|
|
|
|
ALSA: firewire-motu: add an abstraction layer for three types of protocols
In an aspect of used protocols to communicate, models of MOTU FireWire
units are categorized to three generations.
This commit adds an abstraction layer of the protocols for features
related to packet streaming functionality. This layer includes 5
operations.
When configuring packet streaming functionality with sampling rate and
sampling transmission frequency, .get_clock_rate and .set_clock_rate are
called with proper arguments. MOTU FireWire series supports up to 192.0kHz.
When checking current source of sampling clock (not clock for packetization
layer), .get_clock_source is used. Enumeration is added to represent the
sources supported by this series. This operation can be used to expose
available sampling rate to user space applications when the unit is
configured to use any input signal as source of clock instead of crystal
clock.
In the protocols, the path between packet processing layer and digital
signal processing layer can be controlled. This looks a functionality to
'mute' the unit. For this feature, .switch_fetching_mode is added. This
can be used to suppress noises every time packet streaming starts/stops.
In a point of the size of data blocks at a certain sampling transmission
frequency, the most units accept several modes. This is due to usage of
optical interfaces. The size differs depending on which modes are
configured to the interfaces; None, S/PDIF and ADAT. Additionally, format
of packet is different depending on protocols. To cache current size of
data blocks and its format, .cache_packet_formats is added. This is used
by PCM functionality, packet streaming functionality and data block
processing layer.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-22 20:30:14 +08:00
|
|
|
struct snd_motu_packet_format {
|
2017-03-22 20:30:23 +08:00
|
|
|
unsigned char midi_flag_offset;
|
|
|
|
unsigned char midi_byte_offset;
|
ALSA: firewire-motu: add an abstraction layer for three types of protocols
In an aspect of used protocols to communicate, models of MOTU FireWire
units are categorized to three generations.
This commit adds an abstraction layer of the protocols for features
related to packet streaming functionality. This layer includes 5
operations.
When configuring packet streaming functionality with sampling rate and
sampling transmission frequency, .get_clock_rate and .set_clock_rate are
called with proper arguments. MOTU FireWire series supports up to 192.0kHz.
When checking current source of sampling clock (not clock for packetization
layer), .get_clock_source is used. Enumeration is added to represent the
sources supported by this series. This operation can be used to expose
available sampling rate to user space applications when the unit is
configured to use any input signal as source of clock instead of crystal
clock.
In the protocols, the path between packet processing layer and digital
signal processing layer can be controlled. This looks a functionality to
'mute' the unit. For this feature, .switch_fetching_mode is added. This
can be used to suppress noises every time packet streaming starts/stops.
In a point of the size of data blocks at a certain sampling transmission
frequency, the most units accept several modes. This is due to usage of
optical interfaces. The size differs depending on which modes are
configured to the interfaces; None, S/PDIF and ADAT. Additionally, format
of packet is different depending on protocols. To cache current size of
data blocks and its format, .cache_packet_formats is added. This is used
by PCM functionality, packet streaming functionality and data block
processing layer.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-22 20:30:14 +08:00
|
|
|
unsigned char pcm_byte_offset;
|
|
|
|
|
|
|
|
unsigned char msg_chunks;
|
2020-05-19 19:16:34 +08:00
|
|
|
unsigned char pcm_chunks[3];
|
ALSA: firewire-motu: add an abstraction layer for three types of protocols
In an aspect of used protocols to communicate, models of MOTU FireWire
units are categorized to three generations.
This commit adds an abstraction layer of the protocols for features
related to packet streaming functionality. This layer includes 5
operations.
When configuring packet streaming functionality with sampling rate and
sampling transmission frequency, .get_clock_rate and .set_clock_rate are
called with proper arguments. MOTU FireWire series supports up to 192.0kHz.
When checking current source of sampling clock (not clock for packetization
layer), .get_clock_source is used. Enumeration is added to represent the
sources supported by this series. This operation can be used to expose
available sampling rate to user space applications when the unit is
configured to use any input signal as source of clock instead of crystal
clock.
In the protocols, the path between packet processing layer and digital
signal processing layer can be controlled. This looks a functionality to
'mute' the unit. For this feature, .switch_fetching_mode is added. This
can be used to suppress noises every time packet streaming starts/stops.
In a point of the size of data blocks at a certain sampling transmission
frequency, the most units accept several modes. This is due to usage of
optical interfaces. The size differs depending on which modes are
configured to the interfaces; None, S/PDIF and ADAT. Additionally, format
of packet is different depending on protocols. To cache current size of
data blocks and its format, .cache_packet_formats is added. This is used
by PCM functionality, packet streaming functionality and data block
processing layer.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-22 20:30:14 +08:00
|
|
|
};
|
|
|
|
|
2017-03-22 20:30:11 +08:00
|
|
|
struct snd_motu {
|
|
|
|
struct snd_card *card;
|
|
|
|
struct fw_unit *unit;
|
|
|
|
struct mutex mutex;
|
2017-03-22 20:30:23 +08:00
|
|
|
spinlock_t lock;
|
2017-03-22 20:30:12 +08:00
|
|
|
|
|
|
|
bool registered;
|
|
|
|
struct delayed_work dwork;
|
2017-03-22 20:30:13 +08:00
|
|
|
|
|
|
|
/* Model dependent information. */
|
|
|
|
const struct snd_motu_spec *spec;
|
ALSA: firewire-motu: add an abstraction layer for three types of protocols
In an aspect of used protocols to communicate, models of MOTU FireWire
units are categorized to three generations.
This commit adds an abstraction layer of the protocols for features
related to packet streaming functionality. This layer includes 5
operations.
When configuring packet streaming functionality with sampling rate and
sampling transmission frequency, .get_clock_rate and .set_clock_rate are
called with proper arguments. MOTU FireWire series supports up to 192.0kHz.
When checking current source of sampling clock (not clock for packetization
layer), .get_clock_source is used. Enumeration is added to represent the
sources supported by this series. This operation can be used to expose
available sampling rate to user space applications when the unit is
configured to use any input signal as source of clock instead of crystal
clock.
In the protocols, the path between packet processing layer and digital
signal processing layer can be controlled. This looks a functionality to
'mute' the unit. For this feature, .switch_fetching_mode is added. This
can be used to suppress noises every time packet streaming starts/stops.
In a point of the size of data blocks at a certain sampling transmission
frequency, the most units accept several modes. This is due to usage of
optical interfaces. The size differs depending on which modes are
configured to the interfaces; None, S/PDIF and ADAT. Additionally, format
of packet is different depending on protocols. To cache current size of
data blocks and its format, .cache_packet_formats is added. This is used
by PCM functionality, packet streaming functionality and data block
processing layer.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-22 20:30:14 +08:00
|
|
|
|
|
|
|
/* For packet streaming */
|
|
|
|
struct snd_motu_packet_format tx_packet_formats;
|
|
|
|
struct snd_motu_packet_format rx_packet_formats;
|
ALSA: firewire-motu: add MOTU specific protocol layer
MOTU FireWire series uses blocking transmission for AMDTP packet streaming.
They transmit/receive 8,000 packets per second, to handle the same number
of data blocks as current sampling transmission frequency. Thus,
IEC 61883-1/6 packet streaming engine of ALSA firewire stack is available
for them.
However, the sequence of packet and data blocks includes some quirks.
Below sample is a sequence of CIP headers of packets received by 828mk2,
at 44.1kHz of sampling transmission frequency.
quads CIP1 CIP2
488 0x020F04E8 0x8222FFFF
8 0x020F04F8 0x8222FFFF
488 0x020F0400 0x8222FFFF
488 0x020F0408 0x8222FFFF
8 0x020F04E8 0x8222FFFF
488 0x020F04F0 0x8222FFFF
488 0x020F04F8 0x8222FFFF
The SID (source node ID), DBS (data block size), SPH (source packet header),
FMT (format ID), FDF (format dependent field) and SYT (time stamp) fields
are in IEC 61883-1. Especially, FMT is 0x02, FDF is 0x22 and SYT is 0xffff
to define MOTU specific protocol. In an aspect of dbc field, the value
represents accumulated number of data blocks included the packet. This
is against IEC 61883-1, because according to the specification this value
should be the number of data blocks already transferred.
In ALSA IEC 61883-1/6 engine, this quirk is already supported by
CIP_DBC_IS_END_EVENT flag, because Echo Audio Fireworks has.
Each data block includes SPH as its first quadlet field, to represent its
presentation time stamp. Actual value of SPH is compliant to IEC 61883-1;
lower 25 bits of 32 bits width consists of 13 bits cycle count and 12 bits
cycle offset.
The rest of each data block consists of 24 bit chunks. All of PCM samples,
MIDI messages, status and control messages are transferred by the chunks.
This is similar to '24-bit * 4 Audio Pack' in IEC 61883-6. The position of
each kind of data depends on generations of each model. The number of
whole chunks in a data block is a multiple of 4, to consists of
quadlet-aligned packets.
This commit adds data block processing layer specific for the MOTU
protocol. The remarkable point is the way to generate SPH header. Time
stamps for each data blocks are generated by below calculation:
* Using pre-computed table for the number of ticks per event
* 44,1kHz: (557 + 123/441)
* 48.0kHz: (512 + 0/441)
* 88.2kHz: (278 + 282/441)
* 96.0kHz: (256 + 0/441)
* 176.4kHz: (139 + 141/441)
* 192.0kHz: (128 + 0/441)
* Accumulate the ticks and set the value to SPH for every events.
* This way makes sense only for blocking transmission because this mode
transfers fixed number or none of events.
This calculation assumes that each data block has a PCM frame which is
sampled according to event timing clock. Current packet streaming layer
has the same assumption.
Although this sequence works fine for MOTU FireWire series at sampling
transmission frequency based on 48.0kHz, it is not enough at the frequency
based on 44.1kHz. The units generate choppy noise every few seconds.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-22 20:30:18 +08:00
|
|
|
struct amdtp_stream tx_stream;
|
|
|
|
struct amdtp_stream rx_stream;
|
2017-03-22 20:30:20 +08:00
|
|
|
struct fw_iso_resources tx_resources;
|
|
|
|
struct fw_iso_resources rx_resources;
|
2019-06-17 16:15:01 +08:00
|
|
|
unsigned int substreams_counter;
|
2017-03-22 20:30:19 +08:00
|
|
|
|
|
|
|
/* For notification. */
|
|
|
|
struct fw_address_handler async_handler;
|
|
|
|
u32 msg;
|
2017-03-22 20:30:24 +08:00
|
|
|
|
|
|
|
/* For uapi */
|
|
|
|
int dev_lock_count;
|
|
|
|
bool dev_lock_changed;
|
|
|
|
wait_queue_head_t hwdep_wait;
|
2019-08-04 14:21:36 +08:00
|
|
|
|
|
|
|
struct amdtp_domain domain;
|
2017-03-22 20:30:13 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
enum snd_motu_spec_flags {
|
2020-05-19 19:16:38 +08:00
|
|
|
SND_MOTU_SPEC_RX_MIDI_2ND_Q = 0x0001,
|
|
|
|
SND_MOTU_SPEC_RX_MIDI_3RD_Q = 0x0002,
|
|
|
|
SND_MOTU_SPEC_TX_MIDI_2ND_Q = 0x0004,
|
|
|
|
SND_MOTU_SPEC_TX_MIDI_3RD_Q = 0x0008,
|
2017-03-22 20:30:13 +08:00
|
|
|
};
|
|
|
|
|
ALSA: firewire-motu: add an abstraction layer for three types of protocols
In an aspect of used protocols to communicate, models of MOTU FireWire
units are categorized to three generations.
This commit adds an abstraction layer of the protocols for features
related to packet streaming functionality. This layer includes 5
operations.
When configuring packet streaming functionality with sampling rate and
sampling transmission frequency, .get_clock_rate and .set_clock_rate are
called with proper arguments. MOTU FireWire series supports up to 192.0kHz.
When checking current source of sampling clock (not clock for packetization
layer), .get_clock_source is used. Enumeration is added to represent the
sources supported by this series. This operation can be used to expose
available sampling rate to user space applications when the unit is
configured to use any input signal as source of clock instead of crystal
clock.
In the protocols, the path between packet processing layer and digital
signal processing layer can be controlled. This looks a functionality to
'mute' the unit. For this feature, .switch_fetching_mode is added. This
can be used to suppress noises every time packet streaming starts/stops.
In a point of the size of data blocks at a certain sampling transmission
frequency, the most units accept several modes. This is due to usage of
optical interfaces. The size differs depending on which modes are
configured to the interfaces; None, S/PDIF and ADAT. Additionally, format
of packet is different depending on protocols. To cache current size of
data blocks and its format, .cache_packet_formats is added. This is used
by PCM functionality, packet streaming functionality and data block
processing layer.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-22 20:30:14 +08:00
|
|
|
#define SND_MOTU_CLOCK_RATE_COUNT 6
|
|
|
|
extern const unsigned int snd_motu_clock_rates[SND_MOTU_CLOCK_RATE_COUNT];
|
|
|
|
|
|
|
|
enum snd_motu_clock_source {
|
|
|
|
SND_MOTU_CLOCK_SOURCE_INTERNAL,
|
|
|
|
SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB,
|
|
|
|
SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT,
|
|
|
|
SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_A,
|
|
|
|
SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_B,
|
|
|
|
SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT,
|
|
|
|
SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_A,
|
|
|
|
SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_B,
|
|
|
|
SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX,
|
|
|
|
SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR,
|
|
|
|
SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC,
|
2019-10-30 16:06:41 +08:00
|
|
|
SND_MOTU_CLOCK_SOURCE_SPH,
|
ALSA: firewire-motu: add an abstraction layer for three types of protocols
In an aspect of used protocols to communicate, models of MOTU FireWire
units are categorized to three generations.
This commit adds an abstraction layer of the protocols for features
related to packet streaming functionality. This layer includes 5
operations.
When configuring packet streaming functionality with sampling rate and
sampling transmission frequency, .get_clock_rate and .set_clock_rate are
called with proper arguments. MOTU FireWire series supports up to 192.0kHz.
When checking current source of sampling clock (not clock for packetization
layer), .get_clock_source is used. Enumeration is added to represent the
sources supported by this series. This operation can be used to expose
available sampling rate to user space applications when the unit is
configured to use any input signal as source of clock instead of crystal
clock.
In the protocols, the path between packet processing layer and digital
signal processing layer can be controlled. This looks a functionality to
'mute' the unit. For this feature, .switch_fetching_mode is added. This
can be used to suppress noises every time packet streaming starts/stops.
In a point of the size of data blocks at a certain sampling transmission
frequency, the most units accept several modes. This is due to usage of
optical interfaces. The size differs depending on which modes are
configured to the interfaces; None, S/PDIF and ADAT. Additionally, format
of packet is different depending on protocols. To cache current size of
data blocks and its format, .cache_packet_formats is added. This is used
by PCM functionality, packet streaming functionality and data block
processing layer.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-22 20:30:14 +08:00
|
|
|
SND_MOTU_CLOCK_SOURCE_UNKNOWN,
|
|
|
|
};
|
|
|
|
|
2020-05-19 19:16:30 +08:00
|
|
|
enum snd_motu_protocol_version {
|
|
|
|
SND_MOTU_PROTOCOL_V2,
|
|
|
|
SND_MOTU_PROTOCOL_V3,
|
|
|
|
};
|
|
|
|
|
2017-03-22 20:30:13 +08:00
|
|
|
struct snd_motu_spec {
|
|
|
|
const char *const name;
|
2020-05-19 19:16:30 +08:00
|
|
|
enum snd_motu_protocol_version protocol_version;
|
2017-03-22 20:30:13 +08:00
|
|
|
enum snd_motu_spec_flags flags;
|
|
|
|
|
2020-05-19 19:16:33 +08:00
|
|
|
unsigned char tx_fixed_pcm_chunks[3];
|
|
|
|
unsigned char rx_fixed_pcm_chunks[3];
|
2017-03-22 20:30:11 +08:00
|
|
|
};
|
|
|
|
|
2019-10-30 16:06:43 +08:00
|
|
|
extern const struct snd_motu_spec snd_motu_spec_828mk2;
|
2020-05-19 19:16:28 +08:00
|
|
|
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;
|
ALSA: firewire-motu: add support for Motu Traveler
This commit adds support for MOTU Traveler, launched in 2005, discontinued
quite before. As a result, transmission of PCM frame and MIDI messages is
available via ALSA PCM and RawMIDI/Sequencer interfaces.
This model supports sampling transmission frequency up to 192.0 kHz, and
AES/EBU on XLR interface and ADAT on optical interface. Unlike
Motu 828MkII, Windows driver can switch fetching mode for DSP, like
mute/unmute feature.
Although this commit enables high sampling transmission frequency, actual
sound from this model is not good. As long as I tested, it's silence at
176.4 kHz, and it includes hissing noise at 192.0 kHz. In my opinion, as I
reported at 3526ce7f9ba7 ('ALSA: firewire-motu: add MOTU specific protocol
layer'), timestamping on source packet header (SPH) may not still be good
for this model as well.
$ python2 crpp < /sys/bus/firewire/devices/fw1/config_rom
ROM header and bus information block
-----------------------------------------------------------------
400 04106505 bus_info_length 4, crc_length 16, crc 25861
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 0001f32f device_id 000001f32f | EUI-64 0001f2000001f32f
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 00035955 directory_length 3, crc 22869
42c 120001f2 specifier id
430 13000009 version
434 17107800 model
eui-64 leaf at 438
-----------------------------------------------------------------
438 000206b2 leaf_length 2, crc 1714
43c 0001f200 company_id 0001f2 |
440 0001f32f device_id 000001f32f | EUI-64 0001f2000001f32f
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-06-18 20:07:55 +08:00
|
|
|
|
2020-05-19 19:16:29 +08:00
|
|
|
extern const struct snd_motu_spec snd_motu_spec_828mk3;
|
ALSA: firewire-motu: add support for MOTU UltraLite-mk3 (FireWire only model)
UltraLite-mk3 was shipped 2008 by MOTU. This model has two lineups;
FireWire-only and FireWire/USB2.0 Hybrid model. Additionally, the latter
has two variants in respect of the type of IEEE 1394 connector; alpha
and beta connector.
This commit adds support for the FireWire-only model, which is already
discontinued.
$ python3 crpp < /sys/bus/firewire/devices/fw1/config_rom
ROM header and bus information block
-----------------------------------------------------------------
400 0410353a bus_info_length 4, crc_length 16, crc 13626
404 31333934 bus_name "1394"
408 20ff7000 irmc 0, cmc 0, isc 1, bmc 0, cyc_clk_acc 255, max_rec 7 (256)
40c 0001f200 company_id 0001f2 |
410 000902c7 device_id 00000902c7 | EUI-64 0001f200000902c7
root directory
-----------------------------------------------------------------
414 0004ef04 directory_length 4, crc 61188
418 030001f2 vendor
41c 0c0083c0 node capabilities per IEEE 1394
420 d1000002 --> unit directory at 428
424 8d000005 --> eui-64 leaf at 438
unit directory at 428
-----------------------------------------------------------------
428 00035556 directory_length 3, crc 21846
42c 120001f2 specifier id
430 13000019 version
434 17100800 model
eui-64 leaf at 438
-----------------------------------------------------------------
438 0002f3c5 leaf_length 2, crc 62405
43c 0001f200 company_id 0001f2 |
440 000902c7 device_id 00000902c7 | EUI-64 0001f200000902c7
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Link: https://lore.kernel.org/r/20200523071733.170129-1-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2020-05-23 15:17:33 +08:00
|
|
|
extern const struct snd_motu_spec snd_motu_spec_ultralite_mk3;
|
2020-05-19 19:16:29 +08:00
|
|
|
extern const struct snd_motu_spec snd_motu_spec_audio_express;
|
|
|
|
extern const struct snd_motu_spec snd_motu_spec_4pre;
|
|
|
|
|
ALSA: firewire-motu: add MOTU specific protocol layer
MOTU FireWire series uses blocking transmission for AMDTP packet streaming.
They transmit/receive 8,000 packets per second, to handle the same number
of data blocks as current sampling transmission frequency. Thus,
IEC 61883-1/6 packet streaming engine of ALSA firewire stack is available
for them.
However, the sequence of packet and data blocks includes some quirks.
Below sample is a sequence of CIP headers of packets received by 828mk2,
at 44.1kHz of sampling transmission frequency.
quads CIP1 CIP2
488 0x020F04E8 0x8222FFFF
8 0x020F04F8 0x8222FFFF
488 0x020F0400 0x8222FFFF
488 0x020F0408 0x8222FFFF
8 0x020F04E8 0x8222FFFF
488 0x020F04F0 0x8222FFFF
488 0x020F04F8 0x8222FFFF
The SID (source node ID), DBS (data block size), SPH (source packet header),
FMT (format ID), FDF (format dependent field) and SYT (time stamp) fields
are in IEC 61883-1. Especially, FMT is 0x02, FDF is 0x22 and SYT is 0xffff
to define MOTU specific protocol. In an aspect of dbc field, the value
represents accumulated number of data blocks included the packet. This
is against IEC 61883-1, because according to the specification this value
should be the number of data blocks already transferred.
In ALSA IEC 61883-1/6 engine, this quirk is already supported by
CIP_DBC_IS_END_EVENT flag, because Echo Audio Fireworks has.
Each data block includes SPH as its first quadlet field, to represent its
presentation time stamp. Actual value of SPH is compliant to IEC 61883-1;
lower 25 bits of 32 bits width consists of 13 bits cycle count and 12 bits
cycle offset.
The rest of each data block consists of 24 bit chunks. All of PCM samples,
MIDI messages, status and control messages are transferred by the chunks.
This is similar to '24-bit * 4 Audio Pack' in IEC 61883-6. The position of
each kind of data depends on generations of each model. The number of
whole chunks in a data block is a multiple of 4, to consists of
quadlet-aligned packets.
This commit adds data block processing layer specific for the MOTU
protocol. The remarkable point is the way to generate SPH header. Time
stamps for each data blocks are generated by below calculation:
* Using pre-computed table for the number of ticks per event
* 44,1kHz: (557 + 123/441)
* 48.0kHz: (512 + 0/441)
* 88.2kHz: (278 + 282/441)
* 96.0kHz: (256 + 0/441)
* 176.4kHz: (139 + 141/441)
* 192.0kHz: (128 + 0/441)
* Accumulate the ticks and set the value to SPH for every events.
* This way makes sense only for blocking transmission because this mode
transfers fixed number or none of events.
This calculation assumes that each data block has a PCM frame which is
sampled according to event timing clock. Current packet streaming layer
has the same assumption.
Although this sequence works fine for MOTU FireWire series at sampling
transmission frequency based on 48.0kHz, it is not enough at the frequency
based on 44.1kHz. The units generate choppy noise every few seconds.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-22 20:30:18 +08:00
|
|
|
int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit,
|
|
|
|
enum amdtp_stream_direction dir,
|
2020-05-19 19:16:30 +08:00
|
|
|
const struct snd_motu_spec *spec);
|
ALSA: firewire-motu: add MOTU specific protocol layer
MOTU FireWire series uses blocking transmission for AMDTP packet streaming.
They transmit/receive 8,000 packets per second, to handle the same number
of data blocks as current sampling transmission frequency. Thus,
IEC 61883-1/6 packet streaming engine of ALSA firewire stack is available
for them.
However, the sequence of packet and data blocks includes some quirks.
Below sample is a sequence of CIP headers of packets received by 828mk2,
at 44.1kHz of sampling transmission frequency.
quads CIP1 CIP2
488 0x020F04E8 0x8222FFFF
8 0x020F04F8 0x8222FFFF
488 0x020F0400 0x8222FFFF
488 0x020F0408 0x8222FFFF
8 0x020F04E8 0x8222FFFF
488 0x020F04F0 0x8222FFFF
488 0x020F04F8 0x8222FFFF
The SID (source node ID), DBS (data block size), SPH (source packet header),
FMT (format ID), FDF (format dependent field) and SYT (time stamp) fields
are in IEC 61883-1. Especially, FMT is 0x02, FDF is 0x22 and SYT is 0xffff
to define MOTU specific protocol. In an aspect of dbc field, the value
represents accumulated number of data blocks included the packet. This
is against IEC 61883-1, because according to the specification this value
should be the number of data blocks already transferred.
In ALSA IEC 61883-1/6 engine, this quirk is already supported by
CIP_DBC_IS_END_EVENT flag, because Echo Audio Fireworks has.
Each data block includes SPH as its first quadlet field, to represent its
presentation time stamp. Actual value of SPH is compliant to IEC 61883-1;
lower 25 bits of 32 bits width consists of 13 bits cycle count and 12 bits
cycle offset.
The rest of each data block consists of 24 bit chunks. All of PCM samples,
MIDI messages, status and control messages are transferred by the chunks.
This is similar to '24-bit * 4 Audio Pack' in IEC 61883-6. The position of
each kind of data depends on generations of each model. The number of
whole chunks in a data block is a multiple of 4, to consists of
quadlet-aligned packets.
This commit adds data block processing layer specific for the MOTU
protocol. The remarkable point is the way to generate SPH header. Time
stamps for each data blocks are generated by below calculation:
* Using pre-computed table for the number of ticks per event
* 44,1kHz: (557 + 123/441)
* 48.0kHz: (512 + 0/441)
* 88.2kHz: (278 + 282/441)
* 96.0kHz: (256 + 0/441)
* 176.4kHz: (139 + 141/441)
* 192.0kHz: (128 + 0/441)
* Accumulate the ticks and set the value to SPH for every events.
* This way makes sense only for blocking transmission because this mode
transfers fixed number or none of events.
This calculation assumes that each data block has a PCM frame which is
sampled according to event timing clock. Current packet streaming layer
has the same assumption.
Although this sequence works fine for MOTU FireWire series at sampling
transmission frequency based on 48.0kHz, it is not enough at the frequency
based on 44.1kHz. The units generate choppy noise every few seconds.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-22 20:30:18 +08:00
|
|
|
int amdtp_motu_set_parameters(struct amdtp_stream *s, unsigned int rate,
|
2017-03-22 20:30:23 +08:00
|
|
|
unsigned int midi_ports,
|
ALSA: firewire-motu: add MOTU specific protocol layer
MOTU FireWire series uses blocking transmission for AMDTP packet streaming.
They transmit/receive 8,000 packets per second, to handle the same number
of data blocks as current sampling transmission frequency. Thus,
IEC 61883-1/6 packet streaming engine of ALSA firewire stack is available
for them.
However, the sequence of packet and data blocks includes some quirks.
Below sample is a sequence of CIP headers of packets received by 828mk2,
at 44.1kHz of sampling transmission frequency.
quads CIP1 CIP2
488 0x020F04E8 0x8222FFFF
8 0x020F04F8 0x8222FFFF
488 0x020F0400 0x8222FFFF
488 0x020F0408 0x8222FFFF
8 0x020F04E8 0x8222FFFF
488 0x020F04F0 0x8222FFFF
488 0x020F04F8 0x8222FFFF
The SID (source node ID), DBS (data block size), SPH (source packet header),
FMT (format ID), FDF (format dependent field) and SYT (time stamp) fields
are in IEC 61883-1. Especially, FMT is 0x02, FDF is 0x22 and SYT is 0xffff
to define MOTU specific protocol. In an aspect of dbc field, the value
represents accumulated number of data blocks included the packet. This
is against IEC 61883-1, because according to the specification this value
should be the number of data blocks already transferred.
In ALSA IEC 61883-1/6 engine, this quirk is already supported by
CIP_DBC_IS_END_EVENT flag, because Echo Audio Fireworks has.
Each data block includes SPH as its first quadlet field, to represent its
presentation time stamp. Actual value of SPH is compliant to IEC 61883-1;
lower 25 bits of 32 bits width consists of 13 bits cycle count and 12 bits
cycle offset.
The rest of each data block consists of 24 bit chunks. All of PCM samples,
MIDI messages, status and control messages are transferred by the chunks.
This is similar to '24-bit * 4 Audio Pack' in IEC 61883-6. The position of
each kind of data depends on generations of each model. The number of
whole chunks in a data block is a multiple of 4, to consists of
quadlet-aligned packets.
This commit adds data block processing layer specific for the MOTU
protocol. The remarkable point is the way to generate SPH header. Time
stamps for each data blocks are generated by below calculation:
* Using pre-computed table for the number of ticks per event
* 44,1kHz: (557 + 123/441)
* 48.0kHz: (512 + 0/441)
* 88.2kHz: (278 + 282/441)
* 96.0kHz: (256 + 0/441)
* 176.4kHz: (139 + 141/441)
* 192.0kHz: (128 + 0/441)
* Accumulate the ticks and set the value to SPH for every events.
* This way makes sense only for blocking transmission because this mode
transfers fixed number or none of events.
This calculation assumes that each data block has a PCM frame which is
sampled according to event timing clock. Current packet streaming layer
has the same assumption.
Although this sequence works fine for MOTU FireWire series at sampling
transmission frequency based on 48.0kHz, it is not enough at the frequency
based on 44.1kHz. The units generate choppy noise every few seconds.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-22 20:30:18 +08:00
|
|
|
struct snd_motu_packet_format *formats);
|
|
|
|
int amdtp_motu_add_pcm_hw_constraints(struct amdtp_stream *s,
|
|
|
|
struct snd_pcm_runtime *runtime);
|
2017-03-22 20:30:23 +08:00
|
|
|
void amdtp_motu_midi_trigger(struct amdtp_stream *s, unsigned int port,
|
|
|
|
struct snd_rawmidi_substream *midi);
|
2017-03-22 20:30:19 +08:00
|
|
|
|
|
|
|
int snd_motu_transaction_read(struct snd_motu *motu, u32 offset, __be32 *reg,
|
|
|
|
size_t size);
|
|
|
|
int snd_motu_transaction_write(struct snd_motu *motu, u32 offset, __be32 *reg,
|
|
|
|
size_t size);
|
|
|
|
int snd_motu_transaction_register(struct snd_motu *motu);
|
|
|
|
int snd_motu_transaction_reregister(struct snd_motu *motu);
|
|
|
|
void snd_motu_transaction_unregister(struct snd_motu *motu);
|
2017-03-22 20:30:20 +08:00
|
|
|
|
|
|
|
int snd_motu_stream_init_duplex(struct snd_motu *motu);
|
|
|
|
void snd_motu_stream_destroy_duplex(struct snd_motu *motu);
|
2017-08-20 20:25:03 +08:00
|
|
|
int snd_motu_stream_cache_packet_formats(struct snd_motu *motu);
|
2019-10-07 19:05:23 +08:00
|
|
|
int snd_motu_stream_reserve_duplex(struct snd_motu *motu, unsigned int rate,
|
2019-10-17 23:54:20 +08:00
|
|
|
unsigned int frames_per_period,
|
|
|
|
unsigned int frames_per_buffer);
|
2019-06-17 16:15:08 +08:00
|
|
|
int snd_motu_stream_start_duplex(struct snd_motu *motu);
|
2017-03-22 20:30:20 +08:00
|
|
|
void snd_motu_stream_stop_duplex(struct snd_motu *motu);
|
2017-03-22 20:30:24 +08:00
|
|
|
int snd_motu_stream_lock_try(struct snd_motu *motu);
|
|
|
|
void snd_motu_stream_lock_release(struct snd_motu *motu);
|
2017-03-22 20:30:21 +08:00
|
|
|
|
|
|
|
void snd_motu_proc_init(struct snd_motu *motu);
|
2017-03-22 20:30:22 +08:00
|
|
|
|
|
|
|
int snd_motu_create_pcm_devices(struct snd_motu *motu);
|
2017-03-22 20:30:23 +08:00
|
|
|
|
|
|
|
int snd_motu_create_midi_devices(struct snd_motu *motu);
|
2017-03-22 20:30:24 +08:00
|
|
|
|
|
|
|
int snd_motu_create_hwdep_device(struct snd_motu *motu);
|
2020-05-19 19:16:31 +08:00
|
|
|
|
|
|
|
int snd_motu_protocol_v2_get_clock_rate(struct snd_motu *motu,
|
|
|
|
unsigned int *rate);
|
|
|
|
int snd_motu_protocol_v2_set_clock_rate(struct snd_motu *motu,
|
|
|
|
unsigned int rate);
|
|
|
|
int snd_motu_protocol_v2_get_clock_source(struct snd_motu *motu,
|
|
|
|
enum snd_motu_clock_source *src);
|
|
|
|
int snd_motu_protocol_v2_switch_fetching_mode(struct snd_motu *motu,
|
|
|
|
bool enable);
|
|
|
|
int snd_motu_protocol_v2_cache_packet_formats(struct snd_motu *motu);
|
|
|
|
|
|
|
|
int snd_motu_protocol_v3_get_clock_rate(struct snd_motu *motu,
|
|
|
|
unsigned int *rate);
|
|
|
|
int snd_motu_protocol_v3_set_clock_rate(struct snd_motu *motu,
|
|
|
|
unsigned int rate);
|
|
|
|
int snd_motu_protocol_v3_get_clock_source(struct snd_motu *motu,
|
|
|
|
enum snd_motu_clock_source *src);
|
|
|
|
int snd_motu_protocol_v3_switch_fetching_mode(struct snd_motu *motu,
|
|
|
|
bool enable);
|
|
|
|
int snd_motu_protocol_v3_cache_packet_formats(struct snd_motu *motu);
|
|
|
|
|
|
|
|
static inline int snd_motu_protocol_get_clock_rate(struct snd_motu *motu,
|
|
|
|
unsigned int *rate)
|
|
|
|
{
|
|
|
|
if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
|
|
|
|
return snd_motu_protocol_v2_get_clock_rate(motu, rate);
|
|
|
|
else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
|
|
|
|
return snd_motu_protocol_v3_get_clock_rate(motu, rate);
|
|
|
|
else
|
|
|
|
return -ENXIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int snd_motu_protocol_set_clock_rate(struct snd_motu *motu,
|
|
|
|
unsigned int rate)
|
|
|
|
{
|
|
|
|
if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
|
|
|
|
return snd_motu_protocol_v2_set_clock_rate(motu, rate);
|
|
|
|
else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
|
|
|
|
return snd_motu_protocol_v3_set_clock_rate(motu, rate);
|
|
|
|
else
|
|
|
|
return -ENXIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int snd_motu_protocol_get_clock_source(struct snd_motu *motu,
|
|
|
|
enum snd_motu_clock_source *source)
|
|
|
|
{
|
|
|
|
if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
|
|
|
|
return snd_motu_protocol_v2_get_clock_source(motu, source);
|
|
|
|
else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
|
|
|
|
return snd_motu_protocol_v3_get_clock_source(motu, source);
|
|
|
|
else
|
|
|
|
return -ENXIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int snd_motu_protocol_switch_fetching_mode(struct snd_motu *motu,
|
|
|
|
bool enable)
|
|
|
|
{
|
|
|
|
if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
|
|
|
|
return snd_motu_protocol_v2_switch_fetching_mode(motu, enable);
|
|
|
|
else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
|
|
|
|
return snd_motu_protocol_v3_switch_fetching_mode(motu, enable);
|
|
|
|
else
|
|
|
|
return -ENXIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int snd_motu_protocol_cache_packet_formats(struct snd_motu *motu)
|
|
|
|
{
|
|
|
|
if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
|
|
|
|
return snd_motu_protocol_v2_cache_packet_formats(motu);
|
|
|
|
else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
|
|
|
|
return snd_motu_protocol_v3_cache_packet_formats(motu);
|
|
|
|
else
|
|
|
|
return -ENXIO;
|
|
|
|
}
|
|
|
|
|
2017-03-22 20:30:11 +08:00
|
|
|
#endif
|