| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * ff.h - a part of driver for RME Fireface series |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) 2015-2017 Takashi Sakamoto |
|---|
| 5 | | - * |
|---|
| 6 | | - * Licensed under the terms of the GNU General Public License, version 2. |
|---|
| 7 | 6 | */ |
|---|
| 8 | 7 | |
|---|
| 9 | 8 | #ifndef SOUND_FIREFACE_H_INCLUDED |
|---|
| .. | .. |
|---|
| 31 | 30 | #include "../amdtp-stream.h" |
|---|
| 32 | 31 | #include "../iso-resources.h" |
|---|
| 33 | 32 | |
|---|
| 34 | | -#define SND_FF_STREAM_MODES 3 |
|---|
| 35 | | - |
|---|
| 36 | 33 | #define SND_FF_MAXIMIM_MIDI_QUADS 9 |
|---|
| 37 | 34 | #define SND_FF_IN_MIDI_PORTS 2 |
|---|
| 38 | 35 | #define SND_FF_OUT_MIDI_PORTS 2 |
|---|
| 39 | 36 | |
|---|
| 37 | +enum snd_ff_unit_version { |
|---|
| 38 | + SND_FF_UNIT_VERSION_FF800 = 0x000001, |
|---|
| 39 | + SND_FF_UNIT_VERSION_FF400 = 0x000002, |
|---|
| 40 | + SND_FF_UNIT_VERSION_UFX = 0x000003, |
|---|
| 41 | + SND_FF_UNIT_VERSION_UCX = 0x000004, |
|---|
| 42 | + SND_FF_UNIT_VERSION_802 = 0x000005, |
|---|
| 43 | +}; |
|---|
| 44 | + |
|---|
| 45 | +enum snd_ff_stream_mode { |
|---|
| 46 | + SND_FF_STREAM_MODE_LOW = 0, |
|---|
| 47 | + SND_FF_STREAM_MODE_MID, |
|---|
| 48 | + SND_FF_STREAM_MODE_HIGH, |
|---|
| 49 | + SND_FF_STREAM_MODE_COUNT, |
|---|
| 50 | +}; |
|---|
| 51 | + |
|---|
| 40 | 52 | struct snd_ff_protocol; |
|---|
| 41 | 53 | struct snd_ff_spec { |
|---|
| 42 | | - const char *const name; |
|---|
| 43 | | - |
|---|
| 44 | | - const unsigned int pcm_capture_channels[SND_FF_STREAM_MODES]; |
|---|
| 45 | | - const unsigned int pcm_playback_channels[SND_FF_STREAM_MODES]; |
|---|
| 54 | + const unsigned int pcm_capture_channels[SND_FF_STREAM_MODE_COUNT]; |
|---|
| 55 | + const unsigned int pcm_playback_channels[SND_FF_STREAM_MODE_COUNT]; |
|---|
| 46 | 56 | |
|---|
| 47 | 57 | unsigned int midi_in_ports; |
|---|
| 48 | 58 | unsigned int midi_out_ports; |
|---|
| 49 | 59 | |
|---|
| 50 | 60 | const struct snd_ff_protocol *protocol; |
|---|
| 61 | + u64 midi_high_addr; |
|---|
| 62 | + u8 midi_addr_range; |
|---|
| 63 | + u64 midi_rx_addrs[SND_FF_OUT_MIDI_PORTS]; |
|---|
| 51 | 64 | }; |
|---|
| 52 | 65 | |
|---|
| 53 | 66 | struct snd_ff { |
|---|
| .. | .. |
|---|
| 59 | 72 | bool registered; |
|---|
| 60 | 73 | struct delayed_work dwork; |
|---|
| 61 | 74 | |
|---|
| 75 | + enum snd_ff_unit_version unit_version; |
|---|
| 62 | 76 | const struct snd_ff_spec *spec; |
|---|
| 63 | 77 | |
|---|
| 64 | 78 | /* To handle MIDI tx. */ |
|---|
| .. | .. |
|---|
| 67 | 81 | |
|---|
| 68 | 82 | /* TO handle MIDI rx. */ |
|---|
| 69 | 83 | struct snd_rawmidi_substream *rx_midi_substreams[SND_FF_OUT_MIDI_PORTS]; |
|---|
| 70 | | - u8 running_status[SND_FF_OUT_MIDI_PORTS]; |
|---|
| 84 | + bool on_sysex[SND_FF_OUT_MIDI_PORTS]; |
|---|
| 71 | 85 | __le32 msg_buf[SND_FF_OUT_MIDI_PORTS][SND_FF_MAXIMIM_MIDI_QUADS]; |
|---|
| 72 | 86 | struct work_struct rx_midi_work[SND_FF_OUT_MIDI_PORTS]; |
|---|
| 73 | 87 | struct fw_transaction transactions[SND_FF_OUT_MIDI_PORTS]; |
|---|
| .. | .. |
|---|
| 84 | 98 | int dev_lock_count; |
|---|
| 85 | 99 | bool dev_lock_changed; |
|---|
| 86 | 100 | wait_queue_head_t hwdep_wait; |
|---|
| 101 | + |
|---|
| 102 | + struct amdtp_domain domain; |
|---|
| 87 | 103 | }; |
|---|
| 88 | 104 | |
|---|
| 89 | 105 | enum snd_ff_clock_src { |
|---|
| 90 | 106 | SND_FF_CLOCK_SRC_INTERNAL, |
|---|
| 91 | 107 | SND_FF_CLOCK_SRC_SPDIF, |
|---|
| 92 | | - SND_FF_CLOCK_SRC_ADAT, |
|---|
| 108 | + SND_FF_CLOCK_SRC_ADAT1, |
|---|
| 109 | + SND_FF_CLOCK_SRC_ADAT2, |
|---|
| 93 | 110 | SND_FF_CLOCK_SRC_WORD, |
|---|
| 94 | 111 | SND_FF_CLOCK_SRC_LTC, |
|---|
| 95 | | - /* TODO: perhaps ADAT2 and TCO exists. */ |
|---|
| 112 | + /* TODO: perhaps TCO exists. */ |
|---|
| 96 | 113 | }; |
|---|
| 97 | 114 | |
|---|
| 98 | 115 | struct snd_ff_protocol { |
|---|
| 116 | + void (*handle_midi_msg)(struct snd_ff *ff, unsigned int offset, |
|---|
| 117 | + __le32 *buf, size_t length); |
|---|
| 118 | + int (*fill_midi_msg)(struct snd_ff *ff, |
|---|
| 119 | + struct snd_rawmidi_substream *substream, |
|---|
| 120 | + unsigned int port); |
|---|
| 99 | 121 | int (*get_clock)(struct snd_ff *ff, unsigned int *rate, |
|---|
| 100 | 122 | enum snd_ff_clock_src *src); |
|---|
| 123 | + int (*switch_fetching_mode)(struct snd_ff *ff, bool enable); |
|---|
| 124 | + int (*allocate_resources)(struct snd_ff *ff, unsigned int rate); |
|---|
| 101 | 125 | int (*begin_session)(struct snd_ff *ff, unsigned int rate); |
|---|
| 102 | 126 | void (*finish_session)(struct snd_ff *ff); |
|---|
| 103 | | - int (*switch_fetching_mode)(struct snd_ff *ff, bool enable); |
|---|
| 104 | | - |
|---|
| 105 | | - void (*dump_sync_status)(struct snd_ff *ff, |
|---|
| 106 | | - struct snd_info_buffer *buffer); |
|---|
| 107 | | - void (*dump_clock_config)(struct snd_ff *ff, |
|---|
| 108 | | - struct snd_info_buffer *buffer); |
|---|
| 109 | | - |
|---|
| 110 | | - u64 midi_high_addr_reg; |
|---|
| 111 | | - u64 midi_rx_port_0_reg; |
|---|
| 112 | | - u64 midi_rx_port_1_reg; |
|---|
| 127 | + void (*dump_status)(struct snd_ff *ff, struct snd_info_buffer *buffer); |
|---|
| 113 | 128 | }; |
|---|
| 114 | 129 | |
|---|
| 130 | +extern const struct snd_ff_protocol snd_ff_protocol_ff800; |
|---|
| 115 | 131 | extern const struct snd_ff_protocol snd_ff_protocol_ff400; |
|---|
| 132 | +extern const struct snd_ff_protocol snd_ff_protocol_latter; |
|---|
| 116 | 133 | |
|---|
| 117 | 134 | int snd_ff_transaction_register(struct snd_ff *ff); |
|---|
| 118 | 135 | int snd_ff_transaction_reregister(struct snd_ff *ff); |
|---|
| .. | .. |
|---|
| 125 | 142 | int amdtp_ff_init(struct amdtp_stream *s, struct fw_unit *unit, |
|---|
| 126 | 143 | enum amdtp_stream_direction dir); |
|---|
| 127 | 144 | |
|---|
| 145 | +int snd_ff_stream_get_multiplier_mode(enum cip_sfc sfc, |
|---|
| 146 | + enum snd_ff_stream_mode *mode); |
|---|
| 128 | 147 | int snd_ff_stream_init_duplex(struct snd_ff *ff); |
|---|
| 129 | 148 | void snd_ff_stream_destroy_duplex(struct snd_ff *ff); |
|---|
| 149 | +int snd_ff_stream_reserve_duplex(struct snd_ff *ff, unsigned int rate, |
|---|
| 150 | + unsigned int frames_per_period, |
|---|
| 151 | + unsigned int frames_per_buffer); |
|---|
| 130 | 152 | int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate); |
|---|
| 131 | 153 | void snd_ff_stream_stop_duplex(struct snd_ff *ff); |
|---|
| 132 | 154 | void snd_ff_stream_update_duplex(struct snd_ff *ff); |
|---|
| .. | .. |
|---|
| 136 | 158 | void snd_ff_stream_lock_release(struct snd_ff *ff); |
|---|
| 137 | 159 | |
|---|
| 138 | 160 | void snd_ff_proc_init(struct snd_ff *ff); |
|---|
| 161 | +const char *snd_ff_proc_get_clk_label(enum snd_ff_clock_src src); |
|---|
| 139 | 162 | |
|---|
| 140 | 163 | int snd_ff_create_midi_devices(struct snd_ff *ff); |
|---|
| 141 | 164 | |
|---|