linux-sg2042/sound/firewire/fireface/ff.h

153 lines
4.4 KiB
C
Raw Normal View History

/*
* ff.h - a part of driver for RME Fireface series
*
* Copyright (c) 2015-2017 Takashi Sakamoto
*
* Licensed under the terms of the GNU General Public License, version 2.
*/
#ifndef SOUND_FIREFACE_H_INCLUDED
#define SOUND_FIREFACE_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>
#include <linux/compat.h>
#include <linux/sched/signal.h>
#include <sound/core.h>
ALSA: fireface: add an abstraction layer for model-specific protocols As of 2016, RME discontinued its Fireface series, thus it's OK for us to focus on released firmwares to drive known units. As long as investigating Fireface 400 with Windows driver and comparing the result to FFADO implementation, I can see these firmwares have different register assignments. On the other hand, according to manuals of each models, features relevant to packet streaming seem to be common, because GUIs for these models have the same options. It's reasonable to assume an abstraction layer of protocols to communicate to each models. This commit adds the abstraction layer for the protocols. This layer includes some functions to operate common features of models in this series. In IEC 61883-1/6, the sequence of packet can transfer timing information to synchronize receivers to transmitters. Units of each node on IEEE 1394 bus can generate transmitter's timing clock by handling value of SYT field in CIP header with high-precision clock. For audio and music units on IEEE 1394 bus, this recovered clock is designed to used for sampling clock to capture/generate PCM frames on DSP/ADC/DAC. (Actually, in this world, there's no units to implement this specification as is, as long as I know). Fireface series doesn't use this mechanism. Besides, It doesn't use isochronous packet with CIP header. It uses internal crystal unit as its initial sampling clock. When detecting input signals which can be available for sampling clock (e.g. ADAT input), drivers can configure units to use the signals as source of sampling clock. When something goes wrong, e.g. frequency mismatching between the signal and configured value, units fallback to the other detected signals alternatively. When detecting no alternatives, internal crystal unit is used as source of sampling clock. On manual of Fireface 400, this mechanism is described as 'Autosync'. On the units, packet streaming is controlled by write transactions to certain registers. Format of the packet, e.g. the number of data channels in a data block, is also configured by the same manner. For this purpose, .begin_session and .finish_session is added. The remarkable point of this protocol is to allow drivers to configure arbitrary sampling transmission frequency; e.g. 12.345 Hz. As long as I know, there's no actual DAC/ADC chips which support this kind of capability. I think a pair of packet streaming layer and data block processing layer is isolated from sampling data processing layer in a point of governed clock. In short, between these parts, resampling layer exists. Actually, for Fireface 400, write transactions to 0x'0000'8010'051c has an effect to change sampling clock frequency with base frequencies (32.0/44.1/48.0 kHz) and its multipliers (x2/x4), regardless of sampling transmission frequency. For this reason, the abstraction layer doesn't handle parameters for sampling clock. Instead, each implementation of .begin_session is expected to configure sampling transmission frequency. For packet streaming layer, it's enough to get current selection of source signals for the sampling clock and its frequency. In the abstraction layer, when internal crystal is selected, drivers can sets arbitrary sampling frequency, else they should follow configured frequency. For this purpose, .get_clock is added. Drivers are allows to bank up data fetching from a pair of packet streaming/data block processing layer and sampling data processing layer. This feature seems to suppress noises at starting/stopping packet streaming. For this purpose, .switch_fetching_mode is added. As I described in the above, units have remarkable mechanism to manage sampling clock and process sampling data. For debugging purpose, .dump_sync_status and .dump_clock_config are added. I don't have a need to common interface to represent the status and configuration, developers can add actual implementation of the abstraction layer as they like. Unlike PCM frames, MIDI messages are transferred by asynchronous communication over IEEE 1394 bus, thus target addresses are important for this feature. The .midi_high_addr_reg, .midi_rx_port_0_reg and .midi_rx_port_1_reg are for this purpose. I'll describe them in following commit. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-31 21:06:02 +08:00
#include <sound/info.h>
ALSA: fireface: add transaction support As long as investigating Fireface 400, MIDI messages are transferred by asynchronous communication over IEEE 1394 bus. Fireface 400 receives MIDI messages by write transactions to two addresses; 0x'0000'0801'8000 and 0x'0000'0801'9000. Each of two seems to correspond to MIDI port 1 and 2. Fireface 400 transfers MIDI messages by write transactions to certain addresses which configured by drivers. The drivers can decide upper 4 byte of the addresses by write transactions to 0x'0000'0801'03f4. For the rest part of the address, drivers can select from below options: * 0x'0000'0000 * 0x'0000'0080 * 0x'0000'0100 * 0x'0000'0180 Selected options are represented in register 0x'0000'0801'051c as bit flags. Due to this mechanism, drivers are restricted to use addresses on 'Memory space' of IEEE 1222, even if transactions to the address have some side effects. This commit adds transaction support for MIDI messaging, based on my assumption that the similar mechanism is used on the other protocols. To receive asynchronous transactions, the driver allocates a range of address in 'Memory space'. I apply a strategy to use 0x'0000'0000 as lower 4 byte of the address. When getting failure from Linux FireWire subsystem, this driver retries to allocate addresses. Unfortunately, read transaction to address 0x'0000'0801'051c returns zero always, however write transactions have effects to the other features such as status of sampling clock. For this reason, this commit delegates a task to configure this register to user space applications. The applications should set 3rd bit in LSB in little endian order. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-31 21:06:03 +08:00
#include <sound/rawmidi.h>
ALSA: fireface: add support for PCM functionality This commit adds PCM functionality to transmit/receive PCM frames on isochronous packet streaming. This commit enables userspace applications to start/stop packet streaming via ALSA PCM interface. Sampling rate requested by applications is used as sampling transmission frequency of IEC 61883-1/6packet streaming. As I described in followed commits, units in this series manages sampling clock frequency independently of sampling transmission frequency, and they supports resampling between their packet streaming/data block processing layer and sampling data processing layer. This commit take this driver to utilize these features for usability. When internal clock is selected as source signal of sampling clock, this driver allows user space applications to start PCM substreams at any rate which packet streaming engine supports as sampling transmission frequency. In this case, this driver expects units to perform resampling PCM frames for rx/tx packets when sampling clock frequency and sampling transmission frequency are mismatched. This is for daily use cases. When any external clock is selected as the source signal, this driver gets configured sampling rate from units, then restricts available sampling rate to the rate for PCM applications. This is for studio use cases. Models in this series supports 64.0/128.0 kHz of sampling rate, however these frequencies are not supported by IEC 61883-6 as sampling transmission frequency. Therefore, packet streaming engine of ALSA firewire stack can't handle them. When units are configured to use any external clock as source signal of sampling clock and one of these unsupported rate is configured as rate of the sampling clock, this driver returns EIO to user space applications. Anyway, this driver doesn't voluntarily configure parameters of sampling clock. It's better for users to work with appropriate user space implementations to configure the parameters in advance of usage. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-31 21:06:10 +08:00
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/hwdep.h>
#include <sound/firewire.h>
#include "../lib.h"
ALSA: fireface: add unique data processing layer As long as investigating Fireface 400, format of payload of each isochronous packet is not IEC 61883-1/6, thus its format of data block is not AM824. The remarkable points of the format are: * The payload just consists of some data channels of quadlet size without CIP header. * Each data channels includes data aligned to little endian order. * One data channel consists of two parts; 8 bit ancillary field and 24 bit PCM frame. Due to lack of CIP headers, rx/tx packets include no CIP headers and different way to check packet discontinuity. For tx packet, the ancillary field is used for counter. However, the way of counting is different depending on positions of data channels. At 44.1 kHz, ancillary field in: * 1st/6th/9th/10th/14th/17th data channels: not used for this purpose. * 2nd/18th data channels: incremented every data block (0x00-0xff). * 3rd/4th/5th/11th/12th/13th data channels: incremented every 256 data blocks (0x00-0x07). * 7th/8th/15th/16th data channels: incremented per the number of data blocks in a packet. The increment can occur per packet (0x00-0xff). For tx packet, tag of each isochronous packet is used for this purpose. The value of tag cyclically changes between 0, 1, 2 and 3 in this order. The interval is different depending on sampling transmission frequency. At 44.1/48.0 kHz, it's 256 data blocks. At 88.2 kHz, it's 96 data blocks. The number of data blocks in tx packet is exactly the same as SYT_INTERVAL. There's no empty packet or no-data packet, thus the throughput is not 8,000 packets per sec. On the other hand, the one in rx packet is 8,000 packets per sec, thus the number of data blocks is different between each packet, depending on sampling transmission frequency: * 44.1 kHz: 5 or 6 * 48.0 kHz: 5 or 6 or 7 * 88.2 kHz: 10 or 11 or 12 This commit adds data processing layer to satisfy the above specification in a policy of 'best effort'. Although PCM frames are handled for intermediate buffer to user space, the ancillary data is not handled at all to reduce CPU usage, thus counter is not checked. 0 is always used for tag of isochronous packet. Furthermore, the packet streaming layer is responsible for calculation of the number of data blocks for each packet, thus it's not exactly the same sequence from the above observation. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-31 21:06:08 +08:00
#include "../amdtp-stream.h"
#include "../iso-resources.h"
ALSA: fireface: add transaction support As long as investigating Fireface 400, MIDI messages are transferred by asynchronous communication over IEEE 1394 bus. Fireface 400 receives MIDI messages by write transactions to two addresses; 0x'0000'0801'8000 and 0x'0000'0801'9000. Each of two seems to correspond to MIDI port 1 and 2. Fireface 400 transfers MIDI messages by write transactions to certain addresses which configured by drivers. The drivers can decide upper 4 byte of the addresses by write transactions to 0x'0000'0801'03f4. For the rest part of the address, drivers can select from below options: * 0x'0000'0000 * 0x'0000'0080 * 0x'0000'0100 * 0x'0000'0180 Selected options are represented in register 0x'0000'0801'051c as bit flags. Due to this mechanism, drivers are restricted to use addresses on 'Memory space' of IEEE 1222, even if transactions to the address have some side effects. This commit adds transaction support for MIDI messaging, based on my assumption that the similar mechanism is used on the other protocols. To receive asynchronous transactions, the driver allocates a range of address in 'Memory space'. I apply a strategy to use 0x'0000'0000 as lower 4 byte of the address. When getting failure from Linux FireWire subsystem, this driver retries to allocate addresses. Unfortunately, read transaction to address 0x'0000'0801'051c returns zero always, however write transactions have effects to the other features such as status of sampling clock. For this reason, this commit delegates a task to configure this register to user space applications. The applications should set 3rd bit in LSB in little endian order. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-31 21:06:03 +08:00
#define SND_FF_MAXIMIM_MIDI_QUADS 9
#define SND_FF_IN_MIDI_PORTS 2
#define SND_FF_OUT_MIDI_PORTS 2
/* For block write request. */
#define SND_FF_REG_FETCH_PCM_FRAMES 0x0000801c0000ull
#define SND_FF_REG_CLOCK_CONFIG 0x0000801c0004ull
enum snd_ff_stream_mode {
SND_FF_STREAM_MODE_LOW = 0,
SND_FF_STREAM_MODE_MID,
SND_FF_STREAM_MODE_HIGH,
SND_FF_STREAM_MODE_COUNT,
};
ALSA: fireface: add an abstraction layer for model-specific protocols As of 2016, RME discontinued its Fireface series, thus it's OK for us to focus on released firmwares to drive known units. As long as investigating Fireface 400 with Windows driver and comparing the result to FFADO implementation, I can see these firmwares have different register assignments. On the other hand, according to manuals of each models, features relevant to packet streaming seem to be common, because GUIs for these models have the same options. It's reasonable to assume an abstraction layer of protocols to communicate to each models. This commit adds the abstraction layer for the protocols. This layer includes some functions to operate common features of models in this series. In IEC 61883-1/6, the sequence of packet can transfer timing information to synchronize receivers to transmitters. Units of each node on IEEE 1394 bus can generate transmitter's timing clock by handling value of SYT field in CIP header with high-precision clock. For audio and music units on IEEE 1394 bus, this recovered clock is designed to used for sampling clock to capture/generate PCM frames on DSP/ADC/DAC. (Actually, in this world, there's no units to implement this specification as is, as long as I know). Fireface series doesn't use this mechanism. Besides, It doesn't use isochronous packet with CIP header. It uses internal crystal unit as its initial sampling clock. When detecting input signals which can be available for sampling clock (e.g. ADAT input), drivers can configure units to use the signals as source of sampling clock. When something goes wrong, e.g. frequency mismatching between the signal and configured value, units fallback to the other detected signals alternatively. When detecting no alternatives, internal crystal unit is used as source of sampling clock. On manual of Fireface 400, this mechanism is described as 'Autosync'. On the units, packet streaming is controlled by write transactions to certain registers. Format of the packet, e.g. the number of data channels in a data block, is also configured by the same manner. For this purpose, .begin_session and .finish_session is added. The remarkable point of this protocol is to allow drivers to configure arbitrary sampling transmission frequency; e.g. 12.345 Hz. As long as I know, there's no actual DAC/ADC chips which support this kind of capability. I think a pair of packet streaming layer and data block processing layer is isolated from sampling data processing layer in a point of governed clock. In short, between these parts, resampling layer exists. Actually, for Fireface 400, write transactions to 0x'0000'8010'051c has an effect to change sampling clock frequency with base frequencies (32.0/44.1/48.0 kHz) and its multipliers (x2/x4), regardless of sampling transmission frequency. For this reason, the abstraction layer doesn't handle parameters for sampling clock. Instead, each implementation of .begin_session is expected to configure sampling transmission frequency. For packet streaming layer, it's enough to get current selection of source signals for the sampling clock and its frequency. In the abstraction layer, when internal crystal is selected, drivers can sets arbitrary sampling frequency, else they should follow configured frequency. For this purpose, .get_clock is added. Drivers are allows to bank up data fetching from a pair of packet streaming/data block processing layer and sampling data processing layer. This feature seems to suppress noises at starting/stopping packet streaming. For this purpose, .switch_fetching_mode is added. As I described in the above, units have remarkable mechanism to manage sampling clock and process sampling data. For debugging purpose, .dump_sync_status and .dump_clock_config are added. I don't have a need to common interface to represent the status and configuration, developers can add actual implementation of the abstraction layer as they like. Unlike PCM frames, MIDI messages are transferred by asynchronous communication over IEEE 1394 bus, thus target addresses are important for this feature. The .midi_high_addr_reg, .midi_rx_port_0_reg and .midi_rx_port_1_reg are for this purpose. I'll describe them in following commit. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-31 21:06:02 +08:00
struct snd_ff_protocol;
struct snd_ff_spec {
const char *const name;
const unsigned int pcm_capture_channels[SND_FF_STREAM_MODE_COUNT];
const unsigned int pcm_playback_channels[SND_FF_STREAM_MODE_COUNT];
unsigned int midi_in_ports;
unsigned int midi_out_ports;
ALSA: fireface: add an abstraction layer for model-specific protocols As of 2016, RME discontinued its Fireface series, thus it's OK for us to focus on released firmwares to drive known units. As long as investigating Fireface 400 with Windows driver and comparing the result to FFADO implementation, I can see these firmwares have different register assignments. On the other hand, according to manuals of each models, features relevant to packet streaming seem to be common, because GUIs for these models have the same options. It's reasonable to assume an abstraction layer of protocols to communicate to each models. This commit adds the abstraction layer for the protocols. This layer includes some functions to operate common features of models in this series. In IEC 61883-1/6, the sequence of packet can transfer timing information to synchronize receivers to transmitters. Units of each node on IEEE 1394 bus can generate transmitter's timing clock by handling value of SYT field in CIP header with high-precision clock. For audio and music units on IEEE 1394 bus, this recovered clock is designed to used for sampling clock to capture/generate PCM frames on DSP/ADC/DAC. (Actually, in this world, there's no units to implement this specification as is, as long as I know). Fireface series doesn't use this mechanism. Besides, It doesn't use isochronous packet with CIP header. It uses internal crystal unit as its initial sampling clock. When detecting input signals which can be available for sampling clock (e.g. ADAT input), drivers can configure units to use the signals as source of sampling clock. When something goes wrong, e.g. frequency mismatching between the signal and configured value, units fallback to the other detected signals alternatively. When detecting no alternatives, internal crystal unit is used as source of sampling clock. On manual of Fireface 400, this mechanism is described as 'Autosync'. On the units, packet streaming is controlled by write transactions to certain registers. Format of the packet, e.g. the number of data channels in a data block, is also configured by the same manner. For this purpose, .begin_session and .finish_session is added. The remarkable point of this protocol is to allow drivers to configure arbitrary sampling transmission frequency; e.g. 12.345 Hz. As long as I know, there's no actual DAC/ADC chips which support this kind of capability. I think a pair of packet streaming layer and data block processing layer is isolated from sampling data processing layer in a point of governed clock. In short, between these parts, resampling layer exists. Actually, for Fireface 400, write transactions to 0x'0000'8010'051c has an effect to change sampling clock frequency with base frequencies (32.0/44.1/48.0 kHz) and its multipliers (x2/x4), regardless of sampling transmission frequency. For this reason, the abstraction layer doesn't handle parameters for sampling clock. Instead, each implementation of .begin_session is expected to configure sampling transmission frequency. For packet streaming layer, it's enough to get current selection of source signals for the sampling clock and its frequency. In the abstraction layer, when internal crystal is selected, drivers can sets arbitrary sampling frequency, else they should follow configured frequency. For this purpose, .get_clock is added. Drivers are allows to bank up data fetching from a pair of packet streaming/data block processing layer and sampling data processing layer. This feature seems to suppress noises at starting/stopping packet streaming. For this purpose, .switch_fetching_mode is added. As I described in the above, units have remarkable mechanism to manage sampling clock and process sampling data. For debugging purpose, .dump_sync_status and .dump_clock_config are added. I don't have a need to common interface to represent the status and configuration, developers can add actual implementation of the abstraction layer as they like. Unlike PCM frames, MIDI messages are transferred by asynchronous communication over IEEE 1394 bus, thus target addresses are important for this feature. The .midi_high_addr_reg, .midi_rx_port_0_reg and .midi_rx_port_1_reg are for this purpose. I'll describe them in following commit. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-31 21:06:02 +08:00
const struct snd_ff_protocol *protocol;
u64 midi_high_addr;
};
struct snd_ff {
struct snd_card *card;
struct fw_unit *unit;
struct mutex mutex;
spinlock_t lock;
bool registered;
struct delayed_work dwork;
const struct snd_ff_spec *spec;
ALSA: fireface: add transaction support As long as investigating Fireface 400, MIDI messages are transferred by asynchronous communication over IEEE 1394 bus. Fireface 400 receives MIDI messages by write transactions to two addresses; 0x'0000'0801'8000 and 0x'0000'0801'9000. Each of two seems to correspond to MIDI port 1 and 2. Fireface 400 transfers MIDI messages by write transactions to certain addresses which configured by drivers. The drivers can decide upper 4 byte of the addresses by write transactions to 0x'0000'0801'03f4. For the rest part of the address, drivers can select from below options: * 0x'0000'0000 * 0x'0000'0080 * 0x'0000'0100 * 0x'0000'0180 Selected options are represented in register 0x'0000'0801'051c as bit flags. Due to this mechanism, drivers are restricted to use addresses on 'Memory space' of IEEE 1222, even if transactions to the address have some side effects. This commit adds transaction support for MIDI messaging, based on my assumption that the similar mechanism is used on the other protocols. To receive asynchronous transactions, the driver allocates a range of address in 'Memory space'. I apply a strategy to use 0x'0000'0000 as lower 4 byte of the address. When getting failure from Linux FireWire subsystem, this driver retries to allocate addresses. Unfortunately, read transaction to address 0x'0000'0801'051c returns zero always, however write transactions have effects to the other features such as status of sampling clock. For this reason, this commit delegates a task to configure this register to user space applications. The applications should set 3rd bit in LSB in little endian order. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-31 21:06:03 +08:00
/* To handle MIDI tx. */
struct snd_rawmidi_substream *tx_midi_substreams[SND_FF_IN_MIDI_PORTS];
struct fw_address_handler async_handler;
/* TO handle MIDI rx. */
struct snd_rawmidi_substream *rx_midi_substreams[SND_FF_OUT_MIDI_PORTS];
u8 running_status[SND_FF_OUT_MIDI_PORTS];
__le32 msg_buf[SND_FF_OUT_MIDI_PORTS][SND_FF_MAXIMIM_MIDI_QUADS];
struct work_struct rx_midi_work[SND_FF_OUT_MIDI_PORTS];
struct fw_transaction transactions[SND_FF_OUT_MIDI_PORTS];
ktime_t next_ktime[SND_FF_OUT_MIDI_PORTS];
bool rx_midi_error[SND_FF_OUT_MIDI_PORTS];
unsigned int rx_bytes[SND_FF_OUT_MIDI_PORTS];
unsigned int substreams_counter;
struct amdtp_stream tx_stream;
struct amdtp_stream rx_stream;
struct fw_iso_resources tx_resources;
struct fw_iso_resources rx_resources;
int dev_lock_count;
bool dev_lock_changed;
wait_queue_head_t hwdep_wait;
};
ALSA: fireface: add an abstraction layer for model-specific protocols As of 2016, RME discontinued its Fireface series, thus it's OK for us to focus on released firmwares to drive known units. As long as investigating Fireface 400 with Windows driver and comparing the result to FFADO implementation, I can see these firmwares have different register assignments. On the other hand, according to manuals of each models, features relevant to packet streaming seem to be common, because GUIs for these models have the same options. It's reasonable to assume an abstraction layer of protocols to communicate to each models. This commit adds the abstraction layer for the protocols. This layer includes some functions to operate common features of models in this series. In IEC 61883-1/6, the sequence of packet can transfer timing information to synchronize receivers to transmitters. Units of each node on IEEE 1394 bus can generate transmitter's timing clock by handling value of SYT field in CIP header with high-precision clock. For audio and music units on IEEE 1394 bus, this recovered clock is designed to used for sampling clock to capture/generate PCM frames on DSP/ADC/DAC. (Actually, in this world, there's no units to implement this specification as is, as long as I know). Fireface series doesn't use this mechanism. Besides, It doesn't use isochronous packet with CIP header. It uses internal crystal unit as its initial sampling clock. When detecting input signals which can be available for sampling clock (e.g. ADAT input), drivers can configure units to use the signals as source of sampling clock. When something goes wrong, e.g. frequency mismatching between the signal and configured value, units fallback to the other detected signals alternatively. When detecting no alternatives, internal crystal unit is used as source of sampling clock. On manual of Fireface 400, this mechanism is described as 'Autosync'. On the units, packet streaming is controlled by write transactions to certain registers. Format of the packet, e.g. the number of data channels in a data block, is also configured by the same manner. For this purpose, .begin_session and .finish_session is added. The remarkable point of this protocol is to allow drivers to configure arbitrary sampling transmission frequency; e.g. 12.345 Hz. As long as I know, there's no actual DAC/ADC chips which support this kind of capability. I think a pair of packet streaming layer and data block processing layer is isolated from sampling data processing layer in a point of governed clock. In short, between these parts, resampling layer exists. Actually, for Fireface 400, write transactions to 0x'0000'8010'051c has an effect to change sampling clock frequency with base frequencies (32.0/44.1/48.0 kHz) and its multipliers (x2/x4), regardless of sampling transmission frequency. For this reason, the abstraction layer doesn't handle parameters for sampling clock. Instead, each implementation of .begin_session is expected to configure sampling transmission frequency. For packet streaming layer, it's enough to get current selection of source signals for the sampling clock and its frequency. In the abstraction layer, when internal crystal is selected, drivers can sets arbitrary sampling frequency, else they should follow configured frequency. For this purpose, .get_clock is added. Drivers are allows to bank up data fetching from a pair of packet streaming/data block processing layer and sampling data processing layer. This feature seems to suppress noises at starting/stopping packet streaming. For this purpose, .switch_fetching_mode is added. As I described in the above, units have remarkable mechanism to manage sampling clock and process sampling data. For debugging purpose, .dump_sync_status and .dump_clock_config are added. I don't have a need to common interface to represent the status and configuration, developers can add actual implementation of the abstraction layer as they like. Unlike PCM frames, MIDI messages are transferred by asynchronous communication over IEEE 1394 bus, thus target addresses are important for this feature. The .midi_high_addr_reg, .midi_rx_port_0_reg and .midi_rx_port_1_reg are for this purpose. I'll describe them in following commit. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-31 21:06:02 +08:00
enum snd_ff_clock_src {
SND_FF_CLOCK_SRC_INTERNAL,
SND_FF_CLOCK_SRC_SPDIF,
SND_FF_CLOCK_SRC_ADAT1,
SND_FF_CLOCK_SRC_ADAT2,
ALSA: fireface: add an abstraction layer for model-specific protocols As of 2016, RME discontinued its Fireface series, thus it's OK for us to focus on released firmwares to drive known units. As long as investigating Fireface 400 with Windows driver and comparing the result to FFADO implementation, I can see these firmwares have different register assignments. On the other hand, according to manuals of each models, features relevant to packet streaming seem to be common, because GUIs for these models have the same options. It's reasonable to assume an abstraction layer of protocols to communicate to each models. This commit adds the abstraction layer for the protocols. This layer includes some functions to operate common features of models in this series. In IEC 61883-1/6, the sequence of packet can transfer timing information to synchronize receivers to transmitters. Units of each node on IEEE 1394 bus can generate transmitter's timing clock by handling value of SYT field in CIP header with high-precision clock. For audio and music units on IEEE 1394 bus, this recovered clock is designed to used for sampling clock to capture/generate PCM frames on DSP/ADC/DAC. (Actually, in this world, there's no units to implement this specification as is, as long as I know). Fireface series doesn't use this mechanism. Besides, It doesn't use isochronous packet with CIP header. It uses internal crystal unit as its initial sampling clock. When detecting input signals which can be available for sampling clock (e.g. ADAT input), drivers can configure units to use the signals as source of sampling clock. When something goes wrong, e.g. frequency mismatching between the signal and configured value, units fallback to the other detected signals alternatively. When detecting no alternatives, internal crystal unit is used as source of sampling clock. On manual of Fireface 400, this mechanism is described as 'Autosync'. On the units, packet streaming is controlled by write transactions to certain registers. Format of the packet, e.g. the number of data channels in a data block, is also configured by the same manner. For this purpose, .begin_session and .finish_session is added. The remarkable point of this protocol is to allow drivers to configure arbitrary sampling transmission frequency; e.g. 12.345 Hz. As long as I know, there's no actual DAC/ADC chips which support this kind of capability. I think a pair of packet streaming layer and data block processing layer is isolated from sampling data processing layer in a point of governed clock. In short, between these parts, resampling layer exists. Actually, for Fireface 400, write transactions to 0x'0000'8010'051c has an effect to change sampling clock frequency with base frequencies (32.0/44.1/48.0 kHz) and its multipliers (x2/x4), regardless of sampling transmission frequency. For this reason, the abstraction layer doesn't handle parameters for sampling clock. Instead, each implementation of .begin_session is expected to configure sampling transmission frequency. For packet streaming layer, it's enough to get current selection of source signals for the sampling clock and its frequency. In the abstraction layer, when internal crystal is selected, drivers can sets arbitrary sampling frequency, else they should follow configured frequency. For this purpose, .get_clock is added. Drivers are allows to bank up data fetching from a pair of packet streaming/data block processing layer and sampling data processing layer. This feature seems to suppress noises at starting/stopping packet streaming. For this purpose, .switch_fetching_mode is added. As I described in the above, units have remarkable mechanism to manage sampling clock and process sampling data. For debugging purpose, .dump_sync_status and .dump_clock_config are added. I don't have a need to common interface to represent the status and configuration, developers can add actual implementation of the abstraction layer as they like. Unlike PCM frames, MIDI messages are transferred by asynchronous communication over IEEE 1394 bus, thus target addresses are important for this feature. The .midi_high_addr_reg, .midi_rx_port_0_reg and .midi_rx_port_1_reg are for this purpose. I'll describe them in following commit. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-31 21:06:02 +08:00
SND_FF_CLOCK_SRC_WORD,
SND_FF_CLOCK_SRC_LTC,
/* TODO: perhaps TCO exists. */
ALSA: fireface: add an abstraction layer for model-specific protocols As of 2016, RME discontinued its Fireface series, thus it's OK for us to focus on released firmwares to drive known units. As long as investigating Fireface 400 with Windows driver and comparing the result to FFADO implementation, I can see these firmwares have different register assignments. On the other hand, according to manuals of each models, features relevant to packet streaming seem to be common, because GUIs for these models have the same options. It's reasonable to assume an abstraction layer of protocols to communicate to each models. This commit adds the abstraction layer for the protocols. This layer includes some functions to operate common features of models in this series. In IEC 61883-1/6, the sequence of packet can transfer timing information to synchronize receivers to transmitters. Units of each node on IEEE 1394 bus can generate transmitter's timing clock by handling value of SYT field in CIP header with high-precision clock. For audio and music units on IEEE 1394 bus, this recovered clock is designed to used for sampling clock to capture/generate PCM frames on DSP/ADC/DAC. (Actually, in this world, there's no units to implement this specification as is, as long as I know). Fireface series doesn't use this mechanism. Besides, It doesn't use isochronous packet with CIP header. It uses internal crystal unit as its initial sampling clock. When detecting input signals which can be available for sampling clock (e.g. ADAT input), drivers can configure units to use the signals as source of sampling clock. When something goes wrong, e.g. frequency mismatching between the signal and configured value, units fallback to the other detected signals alternatively. When detecting no alternatives, internal crystal unit is used as source of sampling clock. On manual of Fireface 400, this mechanism is described as 'Autosync'. On the units, packet streaming is controlled by write transactions to certain registers. Format of the packet, e.g. the number of data channels in a data block, is also configured by the same manner. For this purpose, .begin_session and .finish_session is added. The remarkable point of this protocol is to allow drivers to configure arbitrary sampling transmission frequency; e.g. 12.345 Hz. As long as I know, there's no actual DAC/ADC chips which support this kind of capability. I think a pair of packet streaming layer and data block processing layer is isolated from sampling data processing layer in a point of governed clock. In short, between these parts, resampling layer exists. Actually, for Fireface 400, write transactions to 0x'0000'8010'051c has an effect to change sampling clock frequency with base frequencies (32.0/44.1/48.0 kHz) and its multipliers (x2/x4), regardless of sampling transmission frequency. For this reason, the abstraction layer doesn't handle parameters for sampling clock. Instead, each implementation of .begin_session is expected to configure sampling transmission frequency. For packet streaming layer, it's enough to get current selection of source signals for the sampling clock and its frequency. In the abstraction layer, when internal crystal is selected, drivers can sets arbitrary sampling frequency, else they should follow configured frequency. For this purpose, .get_clock is added. Drivers are allows to bank up data fetching from a pair of packet streaming/data block processing layer and sampling data processing layer. This feature seems to suppress noises at starting/stopping packet streaming. For this purpose, .switch_fetching_mode is added. As I described in the above, units have remarkable mechanism to manage sampling clock and process sampling data. For debugging purpose, .dump_sync_status and .dump_clock_config are added. I don't have a need to common interface to represent the status and configuration, developers can add actual implementation of the abstraction layer as they like. Unlike PCM frames, MIDI messages are transferred by asynchronous communication over IEEE 1394 bus, thus target addresses are important for this feature. The .midi_high_addr_reg, .midi_rx_port_0_reg and .midi_rx_port_1_reg are for this purpose. I'll describe them in following commit. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-31 21:06:02 +08:00
};
struct snd_ff_protocol {
void (*handle_midi_msg)(struct snd_ff *ff, __le32 *buf, size_t length);
ALSA: fireface: add an abstraction layer for model-specific protocols As of 2016, RME discontinued its Fireface series, thus it's OK for us to focus on released firmwares to drive known units. As long as investigating Fireface 400 with Windows driver and comparing the result to FFADO implementation, I can see these firmwares have different register assignments. On the other hand, according to manuals of each models, features relevant to packet streaming seem to be common, because GUIs for these models have the same options. It's reasonable to assume an abstraction layer of protocols to communicate to each models. This commit adds the abstraction layer for the protocols. This layer includes some functions to operate common features of models in this series. In IEC 61883-1/6, the sequence of packet can transfer timing information to synchronize receivers to transmitters. Units of each node on IEEE 1394 bus can generate transmitter's timing clock by handling value of SYT field in CIP header with high-precision clock. For audio and music units on IEEE 1394 bus, this recovered clock is designed to used for sampling clock to capture/generate PCM frames on DSP/ADC/DAC. (Actually, in this world, there's no units to implement this specification as is, as long as I know). Fireface series doesn't use this mechanism. Besides, It doesn't use isochronous packet with CIP header. It uses internal crystal unit as its initial sampling clock. When detecting input signals which can be available for sampling clock (e.g. ADAT input), drivers can configure units to use the signals as source of sampling clock. When something goes wrong, e.g. frequency mismatching between the signal and configured value, units fallback to the other detected signals alternatively. When detecting no alternatives, internal crystal unit is used as source of sampling clock. On manual of Fireface 400, this mechanism is described as 'Autosync'. On the units, packet streaming is controlled by write transactions to certain registers. Format of the packet, e.g. the number of data channels in a data block, is also configured by the same manner. For this purpose, .begin_session and .finish_session is added. The remarkable point of this protocol is to allow drivers to configure arbitrary sampling transmission frequency; e.g. 12.345 Hz. As long as I know, there's no actual DAC/ADC chips which support this kind of capability. I think a pair of packet streaming layer and data block processing layer is isolated from sampling data processing layer in a point of governed clock. In short, between these parts, resampling layer exists. Actually, for Fireface 400, write transactions to 0x'0000'8010'051c has an effect to change sampling clock frequency with base frequencies (32.0/44.1/48.0 kHz) and its multipliers (x2/x4), regardless of sampling transmission frequency. For this reason, the abstraction layer doesn't handle parameters for sampling clock. Instead, each implementation of .begin_session is expected to configure sampling transmission frequency. For packet streaming layer, it's enough to get current selection of source signals for the sampling clock and its frequency. In the abstraction layer, when internal crystal is selected, drivers can sets arbitrary sampling frequency, else they should follow configured frequency. For this purpose, .get_clock is added. Drivers are allows to bank up data fetching from a pair of packet streaming/data block processing layer and sampling data processing layer. This feature seems to suppress noises at starting/stopping packet streaming. For this purpose, .switch_fetching_mode is added. As I described in the above, units have remarkable mechanism to manage sampling clock and process sampling data. For debugging purpose, .dump_sync_status and .dump_clock_config are added. I don't have a need to common interface to represent the status and configuration, developers can add actual implementation of the abstraction layer as they like. Unlike PCM frames, MIDI messages are transferred by asynchronous communication over IEEE 1394 bus, thus target addresses are important for this feature. The .midi_high_addr_reg, .midi_rx_port_0_reg and .midi_rx_port_1_reg are for this purpose. I'll describe them in following commit. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-31 21:06:02 +08:00
int (*begin_session)(struct snd_ff *ff, unsigned int rate);
void (*finish_session)(struct snd_ff *ff);
void (*dump_status)(struct snd_ff *ff, struct snd_info_buffer *buffer);
ALSA: fireface: add an abstraction layer for model-specific protocols As of 2016, RME discontinued its Fireface series, thus it's OK for us to focus on released firmwares to drive known units. As long as investigating Fireface 400 with Windows driver and comparing the result to FFADO implementation, I can see these firmwares have different register assignments. On the other hand, according to manuals of each models, features relevant to packet streaming seem to be common, because GUIs for these models have the same options. It's reasonable to assume an abstraction layer of protocols to communicate to each models. This commit adds the abstraction layer for the protocols. This layer includes some functions to operate common features of models in this series. In IEC 61883-1/6, the sequence of packet can transfer timing information to synchronize receivers to transmitters. Units of each node on IEEE 1394 bus can generate transmitter's timing clock by handling value of SYT field in CIP header with high-precision clock. For audio and music units on IEEE 1394 bus, this recovered clock is designed to used for sampling clock to capture/generate PCM frames on DSP/ADC/DAC. (Actually, in this world, there's no units to implement this specification as is, as long as I know). Fireface series doesn't use this mechanism. Besides, It doesn't use isochronous packet with CIP header. It uses internal crystal unit as its initial sampling clock. When detecting input signals which can be available for sampling clock (e.g. ADAT input), drivers can configure units to use the signals as source of sampling clock. When something goes wrong, e.g. frequency mismatching between the signal and configured value, units fallback to the other detected signals alternatively. When detecting no alternatives, internal crystal unit is used as source of sampling clock. On manual of Fireface 400, this mechanism is described as 'Autosync'. On the units, packet streaming is controlled by write transactions to certain registers. Format of the packet, e.g. the number of data channels in a data block, is also configured by the same manner. For this purpose, .begin_session and .finish_session is added. The remarkable point of this protocol is to allow drivers to configure arbitrary sampling transmission frequency; e.g. 12.345 Hz. As long as I know, there's no actual DAC/ADC chips which support this kind of capability. I think a pair of packet streaming layer and data block processing layer is isolated from sampling data processing layer in a point of governed clock. In short, between these parts, resampling layer exists. Actually, for Fireface 400, write transactions to 0x'0000'8010'051c has an effect to change sampling clock frequency with base frequencies (32.0/44.1/48.0 kHz) and its multipliers (x2/x4), regardless of sampling transmission frequency. For this reason, the abstraction layer doesn't handle parameters for sampling clock. Instead, each implementation of .begin_session is expected to configure sampling transmission frequency. For packet streaming layer, it's enough to get current selection of source signals for the sampling clock and its frequency. In the abstraction layer, when internal crystal is selected, drivers can sets arbitrary sampling frequency, else they should follow configured frequency. For this purpose, .get_clock is added. Drivers are allows to bank up data fetching from a pair of packet streaming/data block processing layer and sampling data processing layer. This feature seems to suppress noises at starting/stopping packet streaming. For this purpose, .switch_fetching_mode is added. As I described in the above, units have remarkable mechanism to manage sampling clock and process sampling data. For debugging purpose, .dump_sync_status and .dump_clock_config are added. I don't have a need to common interface to represent the status and configuration, developers can add actual implementation of the abstraction layer as they like. Unlike PCM frames, MIDI messages are transferred by asynchronous communication over IEEE 1394 bus, thus target addresses are important for this feature. The .midi_high_addr_reg, .midi_rx_port_0_reg and .midi_rx_port_1_reg are for this purpose. I'll describe them in following commit. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-31 21:06:02 +08:00
};
extern const struct snd_ff_protocol snd_ff_protocol_ff800;
extern const struct snd_ff_protocol snd_ff_protocol_ff400;
ALSA: fireface: add support for Fireface 400 Fireface 400 is a second model of RME Fireface series, released in 2006. This commit adds support for this model. This model supports 8 analog channels, 2 S/PDIF channels and 8 ADAT channels in both of tx/rx packet. The number of ADAT channels differs depending on each mode of sampling transmission frequency. $ python2 linux-firewire-utils/src/crpp < /sys/bus/firewire/devices/fw1/config_rom ROM header and bus information block ----------------------------------------------------------------- 400 04107768 bus_info_length 4, crc_length 16, crc 30568 (should be 61311) 404 31333934 bus_name "1394" 408 20009002 irmc 0, cmc 0, isc 1, bmc 0, cyc_clk_acc 0, max_rec 9 (1024) 40c 000a3501 company_id 000a35 | 410 1bd0862a device_id 011bd0862a | EUI-64 000a35011bd0862a root directory ----------------------------------------------------------------- 414 000485ec directory_length 4, crc 34284 418 03000a35 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 000314c4 directory_length 3, crc 5316 42c 12000a35 specifier id 430 13000002 version 434 17101800 model eui-64 leaf at 438 ----------------------------------------------------------------- 438 000261a8 leaf_length 2, crc 25000 43c 000a3501 company_id 000a35 | 440 1bd0862a device_id 011bd0862a | EUI-64 000a35011bd0862a Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-31 21:06:12 +08:00
int snd_ff_transaction_get_clock(struct snd_ff *ff, unsigned int *rate,
enum snd_ff_clock_src *src);
ALSA: fireface: add transaction support As long as investigating Fireface 400, MIDI messages are transferred by asynchronous communication over IEEE 1394 bus. Fireface 400 receives MIDI messages by write transactions to two addresses; 0x'0000'0801'8000 and 0x'0000'0801'9000. Each of two seems to correspond to MIDI port 1 and 2. Fireface 400 transfers MIDI messages by write transactions to certain addresses which configured by drivers. The drivers can decide upper 4 byte of the addresses by write transactions to 0x'0000'0801'03f4. For the rest part of the address, drivers can select from below options: * 0x'0000'0000 * 0x'0000'0080 * 0x'0000'0100 * 0x'0000'0180 Selected options are represented in register 0x'0000'0801'051c as bit flags. Due to this mechanism, drivers are restricted to use addresses on 'Memory space' of IEEE 1222, even if transactions to the address have some side effects. This commit adds transaction support for MIDI messaging, based on my assumption that the similar mechanism is used on the other protocols. To receive asynchronous transactions, the driver allocates a range of address in 'Memory space'. I apply a strategy to use 0x'0000'0000 as lower 4 byte of the address. When getting failure from Linux FireWire subsystem, this driver retries to allocate addresses. Unfortunately, read transaction to address 0x'0000'0801'051c returns zero always, however write transactions have effects to the other features such as status of sampling clock. For this reason, this commit delegates a task to configure this register to user space applications. The applications should set 3rd bit in LSB in little endian order. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-31 21:06:03 +08:00
int snd_ff_transaction_register(struct snd_ff *ff);
int snd_ff_transaction_reregister(struct snd_ff *ff);
void snd_ff_transaction_unregister(struct snd_ff *ff);
ALSA: fireface: add unique data processing layer As long as investigating Fireface 400, format of payload of each isochronous packet is not IEC 61883-1/6, thus its format of data block is not AM824. The remarkable points of the format are: * The payload just consists of some data channels of quadlet size without CIP header. * Each data channels includes data aligned to little endian order. * One data channel consists of two parts; 8 bit ancillary field and 24 bit PCM frame. Due to lack of CIP headers, rx/tx packets include no CIP headers and different way to check packet discontinuity. For tx packet, the ancillary field is used for counter. However, the way of counting is different depending on positions of data channels. At 44.1 kHz, ancillary field in: * 1st/6th/9th/10th/14th/17th data channels: not used for this purpose. * 2nd/18th data channels: incremented every data block (0x00-0xff). * 3rd/4th/5th/11th/12th/13th data channels: incremented every 256 data blocks (0x00-0x07). * 7th/8th/15th/16th data channels: incremented per the number of data blocks in a packet. The increment can occur per packet (0x00-0xff). For tx packet, tag of each isochronous packet is used for this purpose. The value of tag cyclically changes between 0, 1, 2 and 3 in this order. The interval is different depending on sampling transmission frequency. At 44.1/48.0 kHz, it's 256 data blocks. At 88.2 kHz, it's 96 data blocks. The number of data blocks in tx packet is exactly the same as SYT_INTERVAL. There's no empty packet or no-data packet, thus the throughput is not 8,000 packets per sec. On the other hand, the one in rx packet is 8,000 packets per sec, thus the number of data blocks is different between each packet, depending on sampling transmission frequency: * 44.1 kHz: 5 or 6 * 48.0 kHz: 5 or 6 or 7 * 88.2 kHz: 10 or 11 or 12 This commit adds data processing layer to satisfy the above specification in a policy of 'best effort'. Although PCM frames are handled for intermediate buffer to user space, the ancillary data is not handled at all to reduce CPU usage, thus counter is not checked. 0 is always used for tag of isochronous packet. Furthermore, the packet streaming layer is responsible for calculation of the number of data blocks for each packet, thus it's not exactly the same sequence from the above observation. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-31 21:06:08 +08:00
int amdtp_ff_set_parameters(struct amdtp_stream *s, unsigned int rate,
unsigned int pcm_channels);
int amdtp_ff_add_pcm_hw_constraints(struct amdtp_stream *s,
struct snd_pcm_runtime *runtime);
int amdtp_ff_init(struct amdtp_stream *s, struct fw_unit *unit,
enum amdtp_stream_direction dir);
int snd_ff_stream_get_multiplier_mode(enum cip_sfc sfc,
enum snd_ff_stream_mode *mode);
int snd_ff_stream_init_duplex(struct snd_ff *ff);
void snd_ff_stream_destroy_duplex(struct snd_ff *ff);
int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate);
void snd_ff_stream_stop_duplex(struct snd_ff *ff);
void snd_ff_stream_update_duplex(struct snd_ff *ff);
void snd_ff_stream_lock_changed(struct snd_ff *ff);
int snd_ff_stream_lock_try(struct snd_ff *ff);
void snd_ff_stream_lock_release(struct snd_ff *ff);
void snd_ff_proc_init(struct snd_ff *ff);
int snd_ff_create_midi_devices(struct snd_ff *ff);
ALSA: fireface: add support for PCM functionality This commit adds PCM functionality to transmit/receive PCM frames on isochronous packet streaming. This commit enables userspace applications to start/stop packet streaming via ALSA PCM interface. Sampling rate requested by applications is used as sampling transmission frequency of IEC 61883-1/6packet streaming. As I described in followed commits, units in this series manages sampling clock frequency independently of sampling transmission frequency, and they supports resampling between their packet streaming/data block processing layer and sampling data processing layer. This commit take this driver to utilize these features for usability. When internal clock is selected as source signal of sampling clock, this driver allows user space applications to start PCM substreams at any rate which packet streaming engine supports as sampling transmission frequency. In this case, this driver expects units to perform resampling PCM frames for rx/tx packets when sampling clock frequency and sampling transmission frequency are mismatched. This is for daily use cases. When any external clock is selected as the source signal, this driver gets configured sampling rate from units, then restricts available sampling rate to the rate for PCM applications. This is for studio use cases. Models in this series supports 64.0/128.0 kHz of sampling rate, however these frequencies are not supported by IEC 61883-6 as sampling transmission frequency. Therefore, packet streaming engine of ALSA firewire stack can't handle them. When units are configured to use any external clock as source signal of sampling clock and one of these unsupported rate is configured as rate of the sampling clock, this driver returns EIO to user space applications. Anyway, this driver doesn't voluntarily configure parameters of sampling clock. It's better for users to work with appropriate user space implementations to configure the parameters in advance of usage. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-03-31 21:06:10 +08:00
int snd_ff_create_pcm_devices(struct snd_ff *ff);
int snd_ff_create_hwdep_devices(struct snd_ff *ff);
#endif