aboutsummaryrefslogtreecommitdiffstats
path: root/sound/firewire
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2014-12-08 10:10:42 -0500
committerTakashi Iwai <tiwai@suse.de>2014-12-10 04:47:37 -0500
commit5cd1d3f47a6321612a51ab88ffe8ef65120fcbe0 (patch)
treef2f537e9ec9185754441c37f7896788a76795312 /sound/firewire
parent5b59d8098d2a3fa8ea4ad07b96f62c00c3b3e8d3 (diff)
ALSA: oxfw: Change the way to make PCM rules/constraints
In previous commit, this driver can get to know stream formations at each supported sampling rates. This commit uses it to make PCM rules/constraints and obsoletes hard-coded rules/constraints. For this purpose, this commit adds 'struct snd_oxfw_stream_formation' and snd_oxfw_stream_parse_format() to parse data channel formation of data block. According to datasheet of OXFW970/971, they support 32.0kHz to 196.0kHz. As long as developers investigate, some devices are confirmed to have several formats for the same sampling rate. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Acked-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/firewire')
-rw-r--r--sound/firewire/oxfw/oxfw-pcm.c197
-rw-r--r--sound/firewire/oxfw/oxfw-stream.c268
-rw-r--r--sound/firewire/oxfw/oxfw.c10
-rw-r--r--sound/firewire/oxfw/oxfw.h21
4 files changed, 410 insertions, 86 deletions
diff --git a/sound/firewire/oxfw/oxfw-pcm.c b/sound/firewire/oxfw/oxfw-pcm.c
index d39f17a8f8c0..0c0be984edce 100644
--- a/sound/firewire/oxfw/oxfw-pcm.c
+++ b/sound/firewire/oxfw/oxfw-pcm.c
@@ -7,117 +7,152 @@
7 7
8#include "oxfw.h" 8#include "oxfw.h"
9 9
10static int firewave_rate_constraint(struct snd_pcm_hw_params *params, 10static int hw_rule_rate(struct snd_pcm_hw_params *params,
11 struct snd_pcm_hw_rule *rule) 11 struct snd_pcm_hw_rule *rule)
12{ 12{
13 static unsigned int stereo_rates[] = { 48000, 96000 }; 13 u8 **formats = rule->private;
14 struct snd_interval *channels = 14 struct snd_interval *r =
15 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 15 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
16 struct snd_interval *rate = 16 const struct snd_interval *c =
17 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 17 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);
18 18 struct snd_interval t = {
19 /* two channels work only at 48/96 kHz */ 19 .min = UINT_MAX, .max = 0, .integer = 1
20 if (snd_interval_max(channels) < 6) 20 };
21 return snd_interval_list(rate, 2, stereo_rates, 0); 21 struct snd_oxfw_stream_formation formation;
22 return 0; 22 unsigned int i, err;
23
24 for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
25 if (formats[i] == NULL)
26 continue;
27
28 err = snd_oxfw_stream_parse_format(formats[i], &formation);
29 if (err < 0)
30 continue;
31 if (!snd_interval_test(c, formation.pcm))
32 continue;
33
34 t.min = min(t.min, formation.rate);
35 t.max = max(t.max, formation.rate);
36
37 }
38 return snd_interval_refine(r, &t);
23} 39}
24 40
25static int firewave_channels_constraint(struct snd_pcm_hw_params *params, 41static int hw_rule_channels(struct snd_pcm_hw_params *params,
26 struct snd_pcm_hw_rule *rule) 42 struct snd_pcm_hw_rule *rule)
27{ 43{
28 static const struct snd_interval all_channels = { .min = 6, .max = 6 }; 44 u8 **formats = rule->private;
29 struct snd_interval *rate = 45 struct snd_interval *c =
30 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 46 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
31 struct snd_interval *channels = 47 const struct snd_interval *r =
32 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 48 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
33 49 struct snd_oxfw_stream_formation formation;
34 /* 32/44.1 kHz work only with all six channels */ 50 unsigned int i, j, err;
35 if (snd_interval_max(rate) < 48000) 51 unsigned int count, list[SND_OXFW_STREAM_FORMAT_ENTRIES] = {0};
36 return snd_interval_refine(channels, &all_channels); 52
37 return 0; 53 count = 0;
54 for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
55 if (formats[i] == NULL)
56 break;
57
58 err = snd_oxfw_stream_parse_format(formats[i], &formation);
59 if (err < 0)
60 continue;
61 if (!snd_interval_test(r, formation.rate))
62 continue;
63 if (list[count] == formation.pcm)
64 continue;
65
66 for (j = 0; j < ARRAY_SIZE(list); j++) {
67 if (list[j] == formation.pcm)
68 break;
69 }
70 if (j == ARRAY_SIZE(list)) {
71 list[count] = formation.pcm;
72 if (++count == ARRAY_SIZE(list))
73 break;
74 }
75 }
76
77 return snd_interval_list(c, count, list, 0);
38} 78}
39 79
40int firewave_constraints(struct snd_pcm_runtime *runtime) 80static void limit_channels_and_rates(struct snd_pcm_hardware *hw, u8 **formats)
41{ 81{
42 static unsigned int channels_list[] = { 2, 6 }; 82 struct snd_oxfw_stream_formation formation;
43 static struct snd_pcm_hw_constraint_list channels_list_constraint = { 83 unsigned int i, err;
44 .count = 2,
45 .list = channels_list,
46 };
47 int err;
48 84
49 runtime->hw.rates = SNDRV_PCM_RATE_32000 | 85 hw->channels_min = UINT_MAX;
50 SNDRV_PCM_RATE_44100 | 86 hw->channels_max = 0;
51 SNDRV_PCM_RATE_48000 |
52 SNDRV_PCM_RATE_96000;
53 runtime->hw.channels_max = 6;
54 87
55 err = snd_pcm_hw_constraint_list(runtime, 0, 88 hw->rate_min = UINT_MAX;
56 SNDRV_PCM_HW_PARAM_CHANNELS, 89 hw->rate_max = 0;
57 &channels_list_constraint); 90 hw->rates = 0;
58 if (err < 0)
59 return err;
60 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
61 firewave_rate_constraint, NULL,
62 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
63 if (err < 0)
64 return err;
65 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
66 firewave_channels_constraint, NULL,
67 SNDRV_PCM_HW_PARAM_RATE, -1);
68 if (err < 0)
69 return err;
70 91
71 return 0; 92 for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
93 if (formats[i] == NULL)
94 break;
95
96 err = snd_oxfw_stream_parse_format(formats[i], &formation);
97 if (err < 0)
98 continue;
99
100 hw->channels_min = min(hw->channels_min, formation.pcm);
101 hw->channels_max = max(hw->channels_max, formation.pcm);
102
103 hw->rate_min = min(hw->rate_min, formation.rate);
104 hw->rate_max = max(hw->rate_max, formation.rate);
105 hw->rates |= snd_pcm_rate_to_rate_bit(formation.rate);
106 }
72} 107}
73 108
74int lacie_speakers_constraints(struct snd_pcm_runtime *runtime) 109static void limit_period_and_buffer(struct snd_pcm_hardware *hw)
75{ 110{
76 runtime->hw.rates = SNDRV_PCM_RATE_32000 | 111 hw->periods_min = 2; /* SNDRV_PCM_INFO_BATCH */
77 SNDRV_PCM_RATE_44100 | 112 hw->periods_max = UINT_MAX;
78 SNDRV_PCM_RATE_48000 |
79 SNDRV_PCM_RATE_88200 |
80 SNDRV_PCM_RATE_96000;
81 113
82 return 0; 114 hw->period_bytes_min = 4 * hw->channels_max; /* bytes for a frame */
115
116 /* Just to prevent from allocating much pages. */
117 hw->period_bytes_max = hw->period_bytes_min * 2048;
118 hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min;
83} 119}
84 120
85static int pcm_open(struct snd_pcm_substream *substream) 121static int pcm_open(struct snd_pcm_substream *substream)
86{ 122{
87 static const struct snd_pcm_hardware hardware = {
88 .info = SNDRV_PCM_INFO_MMAP |
89 SNDRV_PCM_INFO_MMAP_VALID |
90 SNDRV_PCM_INFO_BATCH |
91 SNDRV_PCM_INFO_INTERLEAVED |
92 SNDRV_PCM_INFO_BLOCK_TRANSFER,
93 .formats = AMDTP_OUT_PCM_FORMAT_BITS,
94 .channels_min = 2,
95 .channels_max = 2,
96 .buffer_bytes_max = 4 * 1024 * 1024,
97 .period_bytes_min = 1,
98 .period_bytes_max = UINT_MAX,
99 .periods_min = 1,
100 .periods_max = UINT_MAX,
101 };
102 struct snd_oxfw *oxfw = substream->private_data; 123 struct snd_oxfw *oxfw = substream->private_data;
103 struct snd_pcm_runtime *runtime = substream->runtime; 124 struct snd_pcm_runtime *runtime = substream->runtime;
104 bool used; 125 u8 **formats;
105 int err; 126 int err;
106 127
107 err = cmp_connection_check_used(&oxfw->in_conn, &used); 128 formats = oxfw->rx_stream_formats;
108 if ((err < 0) || used) 129
109 goto end; 130 runtime->hw.info = SNDRV_PCM_INFO_BATCH |
131 SNDRV_PCM_INFO_BLOCK_TRANSFER |
132 SNDRV_PCM_INFO_INTERLEAVED |
133 SNDRV_PCM_INFO_MMAP |
134 SNDRV_PCM_INFO_MMAP_VALID;
110 135
111 runtime->hw = hardware; 136 limit_channels_and_rates(&runtime->hw, formats);
137 limit_period_and_buffer(&runtime->hw);
112 138
113 err = oxfw->device_info->pcm_constraints(runtime); 139 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
140 hw_rule_channels, formats,
141 SNDRV_PCM_HW_PARAM_RATE, -1);
114 if (err < 0) 142 if (err < 0)
115 goto end; 143 goto end;
116 err = snd_pcm_limit_hw_rates(runtime); 144
145 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
146 hw_rule_rate, formats,
147 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
117 if (err < 0) 148 if (err < 0)
118 goto end; 149 goto end;
119 150
120 err = amdtp_stream_add_pcm_hw_constraints(&oxfw->rx_stream, runtime); 151 err = amdtp_stream_add_pcm_hw_constraints(&oxfw->rx_stream, runtime);
152 if (err < 0)
153 goto end;
154
155 snd_pcm_set_sync(substream);
121end: 156end:
122 return err; 157 return err;
123} 158}
diff --git a/sound/firewire/oxfw/oxfw-stream.c b/sound/firewire/oxfw/oxfw-stream.c
index ebd156f3e29d..17e3802e6ac2 100644
--- a/sound/firewire/oxfw/oxfw-stream.c
+++ b/sound/firewire/oxfw/oxfw-stream.c
@@ -8,6 +8,35 @@
8 8
9#include "oxfw.h" 9#include "oxfw.h"
10 10
11#define AVC_GENERIC_FRAME_MAXIMUM_BYTES 512
12
13/*
14 * According to datasheet of Oxford Semiconductor:
15 * OXFW970: 32.0/44.1/48.0/96.0 Khz, 8 audio channels I/O
16 * OXFW971: 32.0/44.1/48.0/88.2/96.0/192.0 kHz, 16 audio channels I/O, MIDI I/O
17 */
18static const unsigned int oxfw_rate_table[] = {
19 [0] = 32000,
20 [1] = 44100,
21 [2] = 48000,
22 [3] = 88200,
23 [4] = 96000,
24 [5] = 192000,
25};
26
27/*
28 * See Table 5.7 – Sampling frequency for Multi-bit Audio
29 * in AV/C Stream Format Information Specification 1.1 (Apr 2005, 1394TA)
30 */
31static const unsigned int avc_stream_rate_table[] = {
32 [0] = 0x02,
33 [1] = 0x03,
34 [2] = 0x04,
35 [3] = 0x0a,
36 [4] = 0x05,
37 [5] = 0x07,
38};
39
11int snd_oxfw_stream_init_simplex(struct snd_oxfw *oxfw) 40int snd_oxfw_stream_init_simplex(struct snd_oxfw *oxfw)
12{ 41{
13 int err; 42 int err;
@@ -78,3 +107,242 @@ void snd_oxfw_stream_update_simplex(struct snd_oxfw *oxfw)
78 else 107 else
79 amdtp_stream_update(&oxfw->rx_stream); 108 amdtp_stream_update(&oxfw->rx_stream);
80} 109}
110
111/*
112 * See Table 6.16 - AM824 Stream Format
113 * Figure 6.19 - format_information field for AM824 Compound
114 * in AV/C Stream Format Information Specification 1.1 (Apr 2005, 1394TA)
115 * Also 'Clause 12 AM824 sequence adaption layers' in IEC 61883-6:2005
116 */
117int snd_oxfw_stream_parse_format(u8 *format,
118 struct snd_oxfw_stream_formation *formation)
119{
120 unsigned int i, e, channels, type;
121
122 memset(formation, 0, sizeof(struct snd_oxfw_stream_formation));
123
124 /*
125 * this module can support a hierarchy combination that:
126 * Root: Audio and Music (0x90)
127 * Level 1: AM824 Compound (0x40)
128 */
129 if ((format[0] != 0x90) || (format[1] != 0x40))
130 return -ENOSYS;
131
132 /* check the sampling rate */
133 for (i = 0; i < ARRAY_SIZE(avc_stream_rate_table); i++) {
134 if (format[2] == avc_stream_rate_table[i])
135 break;
136 }
137 if (i == ARRAY_SIZE(avc_stream_rate_table))
138 return -ENOSYS;
139
140 formation->rate = oxfw_rate_table[i];
141
142 for (e = 0; e < format[4]; e++) {
143 channels = format[5 + e * 2];
144 type = format[6 + e * 2];
145
146 switch (type) {
147 /* IEC 60958 Conformant, currently handled as MBLA */
148 case 0x00:
149 /* Multi Bit Linear Audio (Raw) */
150 case 0x06:
151 formation->pcm += channels;
152 break;
153 /* MIDI Conformant */
154 case 0x0d:
155 formation->midi = channels;
156 break;
157 /* IEC 61937-3 to 7 */
158 case 0x01:
159 case 0x02:
160 case 0x03:
161 case 0x04:
162 case 0x05:
163 /* Multi Bit Linear Audio */
164 case 0x07: /* DVD-Audio */
165 case 0x0c: /* High Precision */
166 /* One Bit Audio */
167 case 0x08: /* (Plain) Raw */
168 case 0x09: /* (Plain) SACD */
169 case 0x0a: /* (Encoded) Raw */
170 case 0x0b: /* (Encoded) SACD */
171 /* SMPTE Time-Code conformant */
172 case 0x0e:
173 /* Sample Count */
174 case 0x0f:
175 /* Anciliary Data */
176 case 0x10:
177 /* Synchronization Stream (Stereo Raw audio) */
178 case 0x40:
179 /* Don't care */
180 case 0xff:
181 default:
182 return -ENOSYS; /* not supported */
183 }
184 }
185
186 if (formation->pcm > AMDTP_MAX_CHANNELS_FOR_PCM ||
187 formation->midi > AMDTP_MAX_CHANNELS_FOR_MIDI)
188 return -ENOSYS;
189
190 return 0;
191}
192
193static int
194assume_stream_formats(struct snd_oxfw *oxfw, enum avc_general_plug_dir dir,
195 unsigned int pid, u8 *buf, unsigned int *len,
196 u8 **formats)
197{
198 struct snd_oxfw_stream_formation formation;
199 unsigned int i, eid;
200 int err;
201
202 /* get format at current sampling rate */
203 err = avc_stream_get_format_single(oxfw->unit, dir, pid, buf, len);
204 if (err < 0) {
205 dev_err(&oxfw->unit->device,
206 "fail to get current stream format for isoc %s plug %d:%d\n",
207 (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
208 pid, err);
209 goto end;
210 }
211
212 /* parse and set stream format */
213 eid = 0;
214 err = snd_oxfw_stream_parse_format(buf, &formation);
215 if (err < 0)
216 goto end;
217
218 formats[eid] = kmalloc(*len, GFP_KERNEL);
219 if (formats[eid] == NULL) {
220 err = -ENOMEM;
221 goto end;
222 }
223 memcpy(formats[eid], buf, *len);
224
225 /* apply the format for each available sampling rate */
226 for (i = 0; i < ARRAY_SIZE(oxfw_rate_table); i++) {
227 if (formation.rate == oxfw_rate_table[i])
228 continue;
229
230 err = avc_general_inquiry_sig_fmt(oxfw->unit,
231 oxfw_rate_table[i],
232 dir, pid);
233 if (err < 0)
234 continue;
235
236 eid++;
237 formats[eid] = kmalloc(*len, GFP_KERNEL);
238 if (formats[eid] == NULL) {
239 err = -ENOMEM;
240 goto end;
241 }
242 memcpy(formats[eid], buf, *len);
243 formats[eid][2] = avc_stream_rate_table[i];
244 }
245
246 err = 0;
247 oxfw->assumed = true;
248end:
249 return err;
250}
251
252static int fill_stream_formats(struct snd_oxfw *oxfw,
253 enum avc_general_plug_dir dir,
254 unsigned short pid)
255{
256 u8 *buf, **formats;
257 unsigned int len, eid = 0;
258 struct snd_oxfw_stream_formation dummy;
259 int err;
260
261 buf = kmalloc(AVC_GENERIC_FRAME_MAXIMUM_BYTES, GFP_KERNEL);
262 if (buf == NULL)
263 return -ENOMEM;
264
265 formats = oxfw->rx_stream_formats;
266
267 /* get first entry */
268 len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
269 err = avc_stream_get_format_list(oxfw->unit, dir, 0, buf, &len, 0);
270 if (err == -ENOSYS) {
271 /* LIST subfunction is not implemented */
272 len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
273 err = assume_stream_formats(oxfw, dir, pid, buf, &len,
274 formats);
275 goto end;
276 } else if (err < 0) {
277 dev_err(&oxfw->unit->device,
278 "fail to get stream format %d for isoc %s plug %d:%d\n",
279 eid, (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
280 pid, err);
281 goto end;
282 }
283
284 /* LIST subfunction is implemented */
285 while (eid < SND_OXFW_STREAM_FORMAT_ENTRIES) {
286 /* The format is too short. */
287 if (len < 3) {
288 err = -EIO;
289 break;
290 }
291
292 /* parse and set stream format */
293 err = snd_oxfw_stream_parse_format(buf, &dummy);
294 if (err < 0)
295 break;
296
297 formats[eid] = kmalloc(len, GFP_KERNEL);
298 if (formats[eid] == NULL) {
299 err = -ENOMEM;
300 break;
301 }
302 memcpy(formats[eid], buf, len);
303
304 /* get next entry */
305 len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
306 err = avc_stream_get_format_list(oxfw->unit, dir, 0,
307 buf, &len, ++eid);
308 /* No entries remained. */
309 if (err == -EINVAL) {
310 err = 0;
311 break;
312 } else if (err < 0) {
313 dev_err(&oxfw->unit->device,
314 "fail to get stream format %d for isoc %s plug %d:%d\n",
315 eid, (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" :
316 "out",
317 pid, err);
318 break;
319 }
320 }
321end:
322 kfree(buf);
323 return err;
324}
325
326int snd_oxfw_stream_discover(struct snd_oxfw *oxfw)
327{
328 u8 plugs[AVC_PLUG_INFO_BUF_BYTES];
329 int err;
330
331 /* the number of plugs for isoc in/out, ext in/out */
332 err = avc_general_get_plug_info(oxfw->unit, 0x1f, 0x07, 0x00, plugs);
333 if (err < 0) {
334 dev_err(&oxfw->unit->device,
335 "fail to get info for isoc/external in/out plugs: %d\n",
336 err);
337 goto end;
338 } else if (plugs[0] == 0) {
339 err = -ENOSYS;
340 goto end;
341 }
342
343 /* use iPCR[0] if exists */
344 if (plugs[0] > 0)
345 err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_IN, 0);
346end:
347 return err;
348}
diff --git a/sound/firewire/oxfw/oxfw.c b/sound/firewire/oxfw/oxfw.c
index dd576bf61c37..a8f9062b2884 100644
--- a/sound/firewire/oxfw/oxfw.c
+++ b/sound/firewire/oxfw/oxfw.c
@@ -58,6 +58,10 @@ end:
58static void oxfw_card_free(struct snd_card *card) 58static void oxfw_card_free(struct snd_card *card)
59{ 59{
60 struct snd_oxfw *oxfw = card->private_data; 60 struct snd_oxfw *oxfw = card->private_data;
61 unsigned int i;
62
63 for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++)
64 kfree(oxfw->rx_stream_formats[i]);
61 65
62 mutex_destroy(&oxfw->mutex); 66 mutex_destroy(&oxfw->mutex);
63} 67}
@@ -81,6 +85,10 @@ static int oxfw_probe(struct fw_unit *unit,
81 oxfw->unit = unit; 85 oxfw->unit = unit;
82 oxfw->device_info = (const struct device_info *)id->driver_data; 86 oxfw->device_info = (const struct device_info *)id->driver_data;
83 87
88 err = snd_oxfw_stream_discover(oxfw);
89 if (err < 0)
90 goto error;
91
84 err = name_card(oxfw); 92 err = name_card(oxfw);
85 if (err < 0) 93 if (err < 0)
86 goto error; 94 goto error;
@@ -136,7 +144,6 @@ static const struct device_info griffin_firewave = {
136 .driver_name = "FireWave", 144 .driver_name = "FireWave",
137 .vendor_name = "Griffin", 145 .vendor_name = "Griffin",
138 .model_name = "FireWave", 146 .model_name = "FireWave",
139 .pcm_constraints = firewave_constraints,
140 .mixer_channels = 6, 147 .mixer_channels = 6,
141 .mute_fb_id = 0x01, 148 .mute_fb_id = 0x01,
142 .volume_fb_id = 0x02, 149 .volume_fb_id = 0x02,
@@ -146,7 +153,6 @@ static const struct device_info lacie_speakers = {
146 .driver_name = "FWSpeakers", 153 .driver_name = "FWSpeakers",
147 .vendor_name = "LaCie", 154 .vendor_name = "LaCie",
148 .model_name = "FireWire Speakers", 155 .model_name = "FireWire Speakers",
149 .pcm_constraints = lacie_speakers_constraints,
150 .mixer_channels = 1, 156 .mixer_channels = 1,
151 .mute_fb_id = 0x01, 157 .mute_fb_id = 0x01,
152 .volume_fb_id = 0x01, 158 .volume_fb_id = 0x01,
diff --git a/sound/firewire/oxfw/oxfw.h b/sound/firewire/oxfw/oxfw.h
index a7031d414441..9c3d3e352665 100644
--- a/sound/firewire/oxfw/oxfw.h
+++ b/sound/firewire/oxfw/oxfw.h
@@ -30,19 +30,24 @@ struct device_info {
30 const char *driver_name; 30 const char *driver_name;
31 const char *vendor_name; 31 const char *vendor_name;
32 const char *model_name; 32 const char *model_name;
33 int (*pcm_constraints)(struct snd_pcm_runtime *runtime);
34 unsigned int mixer_channels; 33 unsigned int mixer_channels;
35 u8 mute_fb_id; 34 u8 mute_fb_id;
36 u8 volume_fb_id; 35 u8 volume_fb_id;
37}; 36};
38 37
38/* This is an arbitrary number for convinience. */
39#define SND_OXFW_STREAM_FORMAT_ENTRIES 10
39struct snd_oxfw { 40struct snd_oxfw {
40 struct snd_card *card; 41 struct snd_card *card;
41 struct fw_unit *unit; 42 struct fw_unit *unit;
42 const struct device_info *device_info; 43 const struct device_info *device_info;
43 struct mutex mutex; 44 struct mutex mutex;
45
46 u8 *rx_stream_formats[SND_OXFW_STREAM_FORMAT_ENTRIES];
47 bool assumed;
44 struct cmp_connection in_conn; 48 struct cmp_connection in_conn;
45 struct amdtp_stream rx_stream; 49 struct amdtp_stream rx_stream;
50
46 bool mute; 51 bool mute;
47 s16 volume[6]; 52 s16 volume[6];
48 s16 volume_min; 53 s16 volume_min;
@@ -88,8 +93,18 @@ void snd_oxfw_stream_stop_simplex(struct snd_oxfw *oxfw);
88void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw); 93void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw);
89void snd_oxfw_stream_update_simplex(struct snd_oxfw *oxfw); 94void snd_oxfw_stream_update_simplex(struct snd_oxfw *oxfw);
90 95
91int firewave_constraints(struct snd_pcm_runtime *runtime); 96struct snd_oxfw_stream_formation {
92int lacie_speakers_constraints(struct snd_pcm_runtime *runtime); 97 unsigned int rate;
98 unsigned int pcm;
99 unsigned int midi;
100};
101int snd_oxfw_stream_parse_format(u8 *format,
102 struct snd_oxfw_stream_formation *formation);
103int snd_oxfw_stream_get_current_formation(struct snd_oxfw *oxfw,
104 enum avc_general_plug_dir dir,
105 struct snd_oxfw_stream_formation *formation);
106int snd_oxfw_stream_discover(struct snd_oxfw *oxfw);
107
93int snd_oxfw_create_pcm(struct snd_oxfw *oxfw); 108int snd_oxfw_create_pcm(struct snd_oxfw *oxfw);
94 109
95int snd_oxfw_create_mixer(struct snd_oxfw *oxfw); 110int snd_oxfw_create_mixer(struct snd_oxfw *oxfw);