1  /* SPDX-License-Identifier: GPL-2.0-only */
2  /*
3   * motu.h - a part of driver for MOTU FireWire series
4   *
5   * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
6   */
7  
8  #ifndef SOUND_FIREWIRE_MOTU_H_INCLUDED
9  #define SOUND_FIREWIRE_MOTU_H_INCLUDED
10  
11  #include <linux/device.h>
12  #include <linux/firewire.h>
13  #include <linux/firewire-constants.h>
14  #include <linux/module.h>
15  #include <linux/mod_devicetable.h>
16  #include <linux/mutex.h>
17  #include <linux/slab.h>
18  #include <linux/compat.h>
19  #include <linux/sched/signal.h>
20  
21  #include <sound/control.h>
22  #include <sound/core.h>
23  #include <sound/pcm.h>
24  #include <sound/info.h>
25  #include <sound/rawmidi.h>
26  #include <sound/firewire.h>
27  #include <sound/hwdep.h>
28  
29  #include "../lib.h"
30  #include "../amdtp-stream.h"
31  #include "../iso-resources.h"
32  
33  struct snd_motu_packet_format {
34  	unsigned char midi_flag_offset;
35  	unsigned char midi_byte_offset;
36  	unsigned char pcm_byte_offset;
37  
38  	unsigned char msg_chunks;
39  	unsigned char pcm_chunks[3];
40  };
41  
42  struct amdtp_motu_cache {
43  	unsigned int *event_offsets;
44  	unsigned int size;
45  	unsigned int tail;
46  	unsigned int tx_cycle_count;
47  	unsigned int head;
48  	unsigned int rx_cycle_count;
49  };
50  
51  struct snd_motu {
52  	struct snd_card *card;
53  	struct fw_unit *unit;
54  	struct mutex mutex;
55  	spinlock_t lock;
56  
57  	/* Model dependent information. */
58  	const struct snd_motu_spec *spec;
59  
60  	/* For packet streaming */
61  	struct snd_motu_packet_format tx_packet_formats;
62  	struct snd_motu_packet_format rx_packet_formats;
63  	struct amdtp_stream tx_stream;
64  	struct amdtp_stream rx_stream;
65  	struct fw_iso_resources tx_resources;
66  	struct fw_iso_resources rx_resources;
67  	unsigned int substreams_counter;
68  
69  	/* For notification. */
70  	struct fw_address_handler async_handler;
71  	u32 msg;
72  
73  	/* For uapi */
74  	int dev_lock_count;
75  	bool dev_lock_changed;
76  	wait_queue_head_t hwdep_wait;
77  	struct snd_hwdep *hwdep;
78  
79  	struct amdtp_domain domain;
80  
81  	struct amdtp_motu_cache cache;
82  
83  	void *message_parser;
84  };
85  
86  enum snd_motu_spec_flags {
87  	SND_MOTU_SPEC_RX_MIDI_2ND_Q	= 0x0001,
88  	SND_MOTU_SPEC_RX_MIDI_3RD_Q	= 0x0002,
89  	SND_MOTU_SPEC_TX_MIDI_2ND_Q	= 0x0004,
90  	SND_MOTU_SPEC_TX_MIDI_3RD_Q	= 0x0008,
91  	SND_MOTU_SPEC_REGISTER_DSP	= 0x0010,
92  	SND_MOTU_SPEC_COMMAND_DSP	= 0x0020,
93  };
94  
95  #define SND_MOTU_CLOCK_RATE_COUNT	6
96  extern const unsigned int snd_motu_clock_rates[SND_MOTU_CLOCK_RATE_COUNT];
97  
98  enum snd_motu_clock_source {
99  	SND_MOTU_CLOCK_SOURCE_INTERNAL,
100  	SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB,
101  	SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT,
102  	SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_A,
103  	SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_B,
104  	SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT,
105  	SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_A,
106  	SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_B,
107  	SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX,
108  	SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR,
109  	SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC,
110  	SND_MOTU_CLOCK_SOURCE_SPH,
111  	SND_MOTU_CLOCK_SOURCE_UNKNOWN,
112  };
113  
114  enum snd_motu_protocol_version {
115  	SND_MOTU_PROTOCOL_V1,
116  	SND_MOTU_PROTOCOL_V2,
117  	SND_MOTU_PROTOCOL_V3,
118  };
119  
120  struct snd_motu_spec {
121  	const char *const name;
122  	enum snd_motu_protocol_version protocol_version;
123  	// The combination of snd_motu_spec_flags enumeration-constants.
124  	unsigned int flags;
125  
126  	unsigned char tx_fixed_pcm_chunks[3];
127  	unsigned char rx_fixed_pcm_chunks[3];
128  };
129  
130  extern const struct snd_motu_spec snd_motu_spec_828;
131  extern const struct snd_motu_spec snd_motu_spec_896;
132  
133  extern const struct snd_motu_spec snd_motu_spec_828mk2;
134  extern const struct snd_motu_spec snd_motu_spec_896hd;
135  extern const struct snd_motu_spec snd_motu_spec_traveler;
136  extern const struct snd_motu_spec snd_motu_spec_ultralite;
137  extern const struct snd_motu_spec snd_motu_spec_8pre;
138  
139  extern const struct snd_motu_spec snd_motu_spec_828mk3_fw;
140  extern const struct snd_motu_spec snd_motu_spec_828mk3_hybrid;
141  extern const struct snd_motu_spec snd_motu_spec_896mk3;
142  extern const struct snd_motu_spec snd_motu_spec_traveler_mk3;
143  extern const struct snd_motu_spec snd_motu_spec_ultralite_mk3;
144  extern const struct snd_motu_spec snd_motu_spec_audio_express;
145  extern const struct snd_motu_spec snd_motu_spec_track16;
146  extern const struct snd_motu_spec snd_motu_spec_4pre;
147  
148  int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit,
149  		    enum amdtp_stream_direction dir,
150  		    const struct snd_motu_spec *spec,
151  		    struct amdtp_motu_cache *cache);
152  int amdtp_motu_set_parameters(struct amdtp_stream *s, unsigned int rate,
153  			      unsigned int midi_ports,
154  			      struct snd_motu_packet_format *formats);
155  int amdtp_motu_add_pcm_hw_constraints(struct amdtp_stream *s,
156  				      struct snd_pcm_runtime *runtime);
157  void amdtp_motu_midi_trigger(struct amdtp_stream *s, unsigned int port,
158  			     struct snd_rawmidi_substream *midi);
159  
160  int snd_motu_transaction_read(struct snd_motu *motu, u32 offset, __be32 *reg,
161  			      size_t size);
162  int snd_motu_transaction_write(struct snd_motu *motu, u32 offset, __be32 *reg,
163  			       size_t size);
164  int snd_motu_transaction_register(struct snd_motu *motu);
165  int snd_motu_transaction_reregister(struct snd_motu *motu);
166  void snd_motu_transaction_unregister(struct snd_motu *motu);
167  
168  int snd_motu_stream_init_duplex(struct snd_motu *motu);
169  void snd_motu_stream_destroy_duplex(struct snd_motu *motu);
170  int snd_motu_stream_cache_packet_formats(struct snd_motu *motu);
171  int snd_motu_stream_reserve_duplex(struct snd_motu *motu, unsigned int rate,
172  				   unsigned int frames_per_period,
173  				   unsigned int frames_per_buffer);
174  int snd_motu_stream_start_duplex(struct snd_motu *motu);
175  void snd_motu_stream_stop_duplex(struct snd_motu *motu);
176  int snd_motu_stream_lock_try(struct snd_motu *motu);
177  void snd_motu_stream_lock_release(struct snd_motu *motu);
178  
179  void snd_motu_proc_init(struct snd_motu *motu);
180  
181  int snd_motu_create_pcm_devices(struct snd_motu *motu);
182  
183  int snd_motu_create_midi_devices(struct snd_motu *motu);
184  
185  int snd_motu_create_hwdep_device(struct snd_motu *motu);
186  
187  int snd_motu_protocol_v1_get_clock_rate(struct snd_motu *motu,
188  					unsigned int *rate);
189  int snd_motu_protocol_v1_set_clock_rate(struct snd_motu *motu,
190  					unsigned int rate);
191  int snd_motu_protocol_v1_get_clock_source(struct snd_motu *motu,
192  					  enum snd_motu_clock_source *src);
193  int snd_motu_protocol_v1_switch_fetching_mode(struct snd_motu *motu,
194  					      bool enable);
195  int snd_motu_protocol_v1_cache_packet_formats(struct snd_motu *motu);
196  
197  int snd_motu_protocol_v2_get_clock_rate(struct snd_motu *motu,
198  					unsigned int *rate);
199  int snd_motu_protocol_v2_set_clock_rate(struct snd_motu *motu,
200  					unsigned int rate);
201  int snd_motu_protocol_v2_get_clock_source(struct snd_motu *motu,
202  					  enum snd_motu_clock_source *src);
203  int snd_motu_protocol_v2_switch_fetching_mode(struct snd_motu *motu,
204  					      bool enable);
205  int snd_motu_protocol_v2_cache_packet_formats(struct snd_motu *motu);
206  
207  int snd_motu_protocol_v3_get_clock_rate(struct snd_motu *motu,
208  					unsigned int *rate);
209  int snd_motu_protocol_v3_set_clock_rate(struct snd_motu *motu,
210  					unsigned int rate);
211  int snd_motu_protocol_v3_get_clock_source(struct snd_motu *motu,
212  					  enum snd_motu_clock_source *src);
213  int snd_motu_protocol_v3_switch_fetching_mode(struct snd_motu *motu,
214  					      bool enable);
215  int snd_motu_protocol_v3_cache_packet_formats(struct snd_motu *motu);
216  
snd_motu_protocol_get_clock_rate(struct snd_motu * motu,unsigned int * rate)217  static inline int snd_motu_protocol_get_clock_rate(struct snd_motu *motu,
218  						   unsigned int *rate)
219  {
220  	if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
221  		return snd_motu_protocol_v2_get_clock_rate(motu, rate);
222  	else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
223  		return snd_motu_protocol_v3_get_clock_rate(motu, rate);
224  	else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
225  		return snd_motu_protocol_v1_get_clock_rate(motu, rate);
226  	else
227  		return -ENXIO;
228  }
229  
snd_motu_protocol_set_clock_rate(struct snd_motu * motu,unsigned int rate)230  static inline int snd_motu_protocol_set_clock_rate(struct snd_motu *motu,
231  						   unsigned int rate)
232  {
233  	if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
234  		return snd_motu_protocol_v2_set_clock_rate(motu, rate);
235  	else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
236  		return snd_motu_protocol_v3_set_clock_rate(motu, rate);
237  	else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
238  		return snd_motu_protocol_v1_set_clock_rate(motu, rate);
239  	else
240  		return -ENXIO;
241  }
242  
snd_motu_protocol_get_clock_source(struct snd_motu * motu,enum snd_motu_clock_source * source)243  static inline int snd_motu_protocol_get_clock_source(struct snd_motu *motu,
244  					enum snd_motu_clock_source *source)
245  {
246  	if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
247  		return snd_motu_protocol_v2_get_clock_source(motu, source);
248  	else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
249  		return snd_motu_protocol_v3_get_clock_source(motu, source);
250  	else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
251  		return snd_motu_protocol_v1_get_clock_source(motu, source);
252  	else
253  		return -ENXIO;
254  }
255  
snd_motu_protocol_switch_fetching_mode(struct snd_motu * motu,bool enable)256  static inline int snd_motu_protocol_switch_fetching_mode(struct snd_motu *motu,
257  							 bool enable)
258  {
259  	if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
260  		return snd_motu_protocol_v2_switch_fetching_mode(motu, enable);
261  	else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
262  		return snd_motu_protocol_v3_switch_fetching_mode(motu, enable);
263  	else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
264  		return snd_motu_protocol_v1_switch_fetching_mode(motu, enable);
265  	else
266  		return -ENXIO;
267  }
268  
snd_motu_protocol_cache_packet_formats(struct snd_motu * motu)269  static inline int snd_motu_protocol_cache_packet_formats(struct snd_motu *motu)
270  {
271  	if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
272  		return snd_motu_protocol_v2_cache_packet_formats(motu);
273  	else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
274  		return snd_motu_protocol_v3_cache_packet_formats(motu);
275  	else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
276  		return snd_motu_protocol_v1_cache_packet_formats(motu);
277  	else
278  		return -ENXIO;
279  }
280  
281  int snd_motu_register_dsp_message_parser_new(struct snd_motu *motu);
282  int snd_motu_register_dsp_message_parser_init(struct snd_motu *motu);
283  void snd_motu_register_dsp_message_parser_parse(const struct amdtp_stream *s,
284  					const struct pkt_desc *descs, unsigned int count);
285  void snd_motu_register_dsp_message_parser_copy_meter(struct snd_motu *motu,
286  					struct snd_firewire_motu_register_dsp_meter *meter);
287  void snd_motu_register_dsp_message_parser_copy_parameter(struct snd_motu *motu,
288  					struct snd_firewire_motu_register_dsp_parameter *params);
289  unsigned int snd_motu_register_dsp_message_parser_count_event(struct snd_motu *motu);
290  bool snd_motu_register_dsp_message_parser_copy_event(struct snd_motu *motu, u32 *event);
291  
292  int snd_motu_command_dsp_message_parser_new(struct snd_motu *motu);
293  int snd_motu_command_dsp_message_parser_init(struct snd_motu *motu, enum cip_sfc sfc);
294  void snd_motu_command_dsp_message_parser_parse(const struct amdtp_stream *s,
295  					const struct pkt_desc *descs, unsigned int count);
296  void snd_motu_command_dsp_message_parser_copy_meter(struct snd_motu *motu,
297  					struct snd_firewire_motu_command_dsp_meter *meter);
298  
299  #endif
300