0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/device.h>
0009 #include <linux/firewire.h>
0010 #include <linux/firewire-constants.h>
0011 #include <linux/module.h>
0012 #include <linux/mod_devicetable.h>
0013 #include <linux/mutex.h>
0014 #include <linux/slab.h>
0015 #include <linux/compat.h>
0016 #include <linux/sched/signal.h>
0017
0018 #include <sound/control.h>
0019 #include <sound/core.h>
0020 #include <sound/initval.h>
0021 #include <sound/pcm.h>
0022 #include <sound/pcm_params.h>
0023 #include <sound/info.h>
0024 #include <sound/rawmidi.h>
0025 #include <sound/firewire.h>
0026 #include <sound/hwdep.h>
0027
0028 #include "../lib.h"
0029 #include "../fcp.h"
0030 #include "../packets-buffer.h"
0031 #include "../iso-resources.h"
0032 #include "../amdtp-am824.h"
0033 #include "../cmp.h"
0034
0035 enum snd_oxfw_quirk {
0036
0037
0038 SND_OXFW_QUIRK_JUMBO_PAYLOAD = 0x01,
0039
0040 SND_OXFW_QUIRK_WRONG_DBS = 0x02,
0041
0042 SND_OXFW_QUIRK_BLOCKING_TRANSMISSION = 0x04,
0043
0044 SND_OXFW_QUIRK_SCS_TRANSACTION = 0x08,
0045
0046
0047
0048
0049 SND_OXFW_QUIRK_IGNORE_NO_INFO_PACKET = 0x10,
0050
0051
0052
0053
0054 SND_OXFW_QUIRK_VOLUNTARY_RECOVERY = 0x20,
0055 };
0056
0057
0058 #define SND_OXFW_STREAM_FORMAT_ENTRIES 10
0059 struct snd_oxfw {
0060 struct snd_card *card;
0061 struct fw_unit *unit;
0062 struct mutex mutex;
0063 spinlock_t lock;
0064
0065
0066 unsigned int quirks;
0067 bool has_output;
0068 bool has_input;
0069 u8 *tx_stream_formats[SND_OXFW_STREAM_FORMAT_ENTRIES];
0070 u8 *rx_stream_formats[SND_OXFW_STREAM_FORMAT_ENTRIES];
0071 bool assumed;
0072 struct cmp_connection out_conn;
0073 struct cmp_connection in_conn;
0074 struct amdtp_stream tx_stream;
0075 struct amdtp_stream rx_stream;
0076 unsigned int substreams_count;
0077
0078 unsigned int midi_input_ports;
0079 unsigned int midi_output_ports;
0080
0081 int dev_lock_count;
0082 bool dev_lock_changed;
0083 wait_queue_head_t hwdep_wait;
0084
0085 void *spec;
0086
0087 struct amdtp_domain domain;
0088 };
0089
0090
0091
0092
0093
0094 int avc_stream_set_format(struct fw_unit *unit, enum avc_general_plug_dir dir,
0095 unsigned int pid, u8 *format, unsigned int len);
0096 int avc_stream_get_format(struct fw_unit *unit,
0097 enum avc_general_plug_dir dir, unsigned int pid,
0098 u8 *buf, unsigned int *len, unsigned int eid);
0099 static inline int
0100 avc_stream_get_format_single(struct fw_unit *unit,
0101 enum avc_general_plug_dir dir, unsigned int pid,
0102 u8 *buf, unsigned int *len)
0103 {
0104 return avc_stream_get_format(unit, dir, pid, buf, len, 0xff);
0105 }
0106 static inline int
0107 avc_stream_get_format_list(struct fw_unit *unit,
0108 enum avc_general_plug_dir dir, unsigned int pid,
0109 u8 *buf, unsigned int *len,
0110 unsigned int eid)
0111 {
0112 return avc_stream_get_format(unit, dir, pid, buf, len, eid);
0113 }
0114
0115
0116
0117
0118
0119 int avc_general_inquiry_sig_fmt(struct fw_unit *unit, unsigned int rate,
0120 enum avc_general_plug_dir dir,
0121 unsigned short pid);
0122
0123 int snd_oxfw_stream_init_duplex(struct snd_oxfw *oxfw);
0124 int snd_oxfw_stream_reserve_duplex(struct snd_oxfw *oxfw,
0125 struct amdtp_stream *stream,
0126 unsigned int rate, unsigned int pcm_channels,
0127 unsigned int frames_per_period,
0128 unsigned int frames_per_buffer);
0129 int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw);
0130 void snd_oxfw_stream_stop_duplex(struct snd_oxfw *oxfw);
0131 void snd_oxfw_stream_destroy_duplex(struct snd_oxfw *oxfw);
0132 void snd_oxfw_stream_update_duplex(struct snd_oxfw *oxfw);
0133
0134 struct snd_oxfw_stream_formation {
0135 unsigned int rate;
0136 unsigned int pcm;
0137 unsigned int midi;
0138 };
0139 int snd_oxfw_stream_parse_format(u8 *format,
0140 struct snd_oxfw_stream_formation *formation);
0141 int snd_oxfw_stream_get_current_formation(struct snd_oxfw *oxfw,
0142 enum avc_general_plug_dir dir,
0143 struct snd_oxfw_stream_formation *formation);
0144
0145 int snd_oxfw_stream_discover(struct snd_oxfw *oxfw);
0146
0147 void snd_oxfw_stream_lock_changed(struct snd_oxfw *oxfw);
0148 int snd_oxfw_stream_lock_try(struct snd_oxfw *oxfw);
0149 void snd_oxfw_stream_lock_release(struct snd_oxfw *oxfw);
0150
0151 int snd_oxfw_create_pcm(struct snd_oxfw *oxfw);
0152
0153 void snd_oxfw_proc_init(struct snd_oxfw *oxfw);
0154
0155 int snd_oxfw_create_midi(struct snd_oxfw *oxfw);
0156
0157 int snd_oxfw_create_hwdep(struct snd_oxfw *oxfw);
0158
0159 int snd_oxfw_add_spkr(struct snd_oxfw *oxfw, bool is_lacie);
0160 int snd_oxfw_scs1x_add(struct snd_oxfw *oxfw);
0161 void snd_oxfw_scs1x_update(struct snd_oxfw *oxfw);