aboutsummaryrefslogtreecommitdiffstats
path: root/sound/firewire/dice
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2014-11-28 10:59:14 -0500
committerTakashi Iwai <tiwai@suse.de>2014-11-29 14:07:33 -0500
commit6eb6c81eee2a6270b39ca02a446f3ccece24b6f8 (patch)
tree6efd40876f0512948be02e153c77afe3917e24a7 /sound/firewire/dice
parent7c2d4c0cf5bacb42bc3079e61d299dfaa3dbdde5 (diff)
ALSA: dice: Split stream functionality into a file
This commit adds a file with some helper functions for streaming, and move some codes into the file with some arrangements. Well-known CMP is not used to start/stop streams for Dice chipset. It's achieved by writing to specific address. We call this way as 'enable'. When devices are 'enabled', streaming starts in registered isochronous channel. Some helper functions are already implemented in previous commit. Basically, the stream is compliant to IEC 61883-6, so-called as AMDTP. But Dice has a specific quirk, so called-as 'Dual Wire'. This quirk is applied at 176.4/192.0kHz. In this mode, each packet includes double number of events than number in the specification, and stream runs at a half of sampling rate. There is another quirk at bus reset. Dice chipset handles drivers' request but don't re-enable streaming. So stream should be stopped. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/firewire/dice')
-rw-r--r--sound/firewire/dice/Makefile2
-rw-r--r--sound/firewire/dice/dice-stream.c206
-rw-r--r--sound/firewire/dice/dice.c299
-rw-r--r--sound/firewire/dice/dice.h14
4 files changed, 288 insertions, 233 deletions
diff --git a/sound/firewire/dice/Makefile b/sound/firewire/dice/Makefile
index 9f473cb7abf1..867864ca514f 100644
--- a/sound/firewire/dice/Makefile
+++ b/sound/firewire/dice/Makefile
@@ -1,2 +1,2 @@
1snd-dice-objs := dice-transaction.o dice.o 1snd-dice-objs := dice-transaction.o dice-stream.o dice.o
2obj-m += snd-dice.o 2obj-m += snd-dice.o
diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c
new file mode 100644
index 000000000000..c25b9fb39d1f
--- /dev/null
+++ b/sound/firewire/dice/dice-stream.c
@@ -0,0 +1,206 @@
1/*
2 * dice_stream.c - a part of driver for DICE based devices
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Copyright (c) 2014 Takashi Sakamoto <o-takashi@sakamocchi.jp>
6 *
7 * Licensed under the terms of the GNU General Public License, version 2.
8 */
9
10#include "dice.h"
11
12const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT] = {
13 /* mode 0 */
14 [0] = 32000,
15 [1] = 44100,
16 [2] = 48000,
17 /* mode 1 */
18 [3] = 88200,
19 [4] = 96000,
20 /* mode 2 */
21 [5] = 176400,
22 [6] = 192000,
23};
24
25int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate,
26 unsigned int *mode)
27{
28 int i;
29
30 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); i++) {
31 if (!(dice->clock_caps & BIT(i)))
32 continue;
33 if (snd_dice_rates[i] != rate)
34 continue;
35
36 *mode = (i - 1) / 2;
37 return 0;
38 }
39 return -EINVAL;
40}
41
42int snd_dice_stream_start_packets(struct snd_dice *dice)
43{
44 int err;
45
46 if (amdtp_stream_running(&dice->rx_stream))
47 return 0;
48
49 err = amdtp_stream_start(&dice->rx_stream, dice->rx_resources.channel,
50 fw_parent_device(dice->unit)->max_speed);
51 if (err < 0)
52 return err;
53
54 err = snd_dice_transaction_set_enable(dice);
55 if (err < 0) {
56 amdtp_stream_stop(&dice->rx_stream);
57 return err;
58 }
59
60 return 0;
61}
62
63int snd_dice_stream_start(struct snd_dice *dice)
64{
65 __be32 channel;
66 int err;
67
68 if (!dice->rx_resources.allocated) {
69 err = fw_iso_resources_allocate(&dice->rx_resources,
70 amdtp_stream_get_max_payload(&dice->rx_stream),
71 fw_parent_device(dice->unit)->max_speed);
72 if (err < 0)
73 goto error;
74
75 channel = cpu_to_be32(dice->rx_resources.channel);
76 err = snd_dice_transaction_write_tx(dice, RX_ISOCHRONOUS,
77 &channel, 4);
78 if (err < 0)
79 goto err_resources;
80 }
81
82 err = snd_dice_stream_start_packets(dice);
83 if (err < 0)
84 goto err_rx_channel;
85
86 return 0;
87
88err_rx_channel:
89 channel = cpu_to_be32((u32)-1);
90 snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS, &channel, 4);
91err_resources:
92 fw_iso_resources_free(&dice->rx_resources);
93error:
94 return err;
95}
96
97void snd_dice_stream_stop_packets(struct snd_dice *dice)
98{
99 if (amdtp_stream_running(&dice->rx_stream)) {
100 snd_dice_transaction_clear_enable(dice);
101 amdtp_stream_stop(&dice->rx_stream);
102 }
103}
104
105void snd_dice_stream_stop(struct snd_dice *dice)
106{
107 __be32 channel;
108
109 snd_dice_stream_stop_packets(dice);
110
111 if (!dice->rx_resources.allocated)
112 return;
113
114 channel = cpu_to_be32((u32)-1);
115 snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS, &channel, 4);
116
117 fw_iso_resources_free(&dice->rx_resources);
118}
119
120int snd_dice_stream_init(struct snd_dice *dice)
121{
122 int err;
123
124 err = fw_iso_resources_init(&dice->rx_resources, dice->unit);
125 if (err < 0)
126 goto end;
127 dice->rx_resources.channels_mask = 0x00000000ffffffffuLL;
128
129 err = amdtp_stream_init(&dice->rx_stream, dice->unit, AMDTP_OUT_STREAM,
130 CIP_BLOCKING);
131 if (err < 0)
132 goto error;
133
134 err = snd_dice_transaction_set_clock_source(dice, CLOCK_SOURCE_ARX1);
135 if (err < 0)
136 goto error;
137end:
138 return err;
139error:
140 amdtp_stream_destroy(&dice->rx_stream);
141 fw_iso_resources_destroy(&dice->rx_resources);
142 return err;
143}
144
145void snd_dice_stream_destroy(struct snd_dice *dice)
146{
147 amdtp_stream_pcm_abort(&dice->rx_stream);
148 snd_dice_stream_stop(dice);
149 amdtp_stream_destroy(&dice->rx_stream);
150 fw_iso_resources_destroy(&dice->rx_resources);
151}
152
153void snd_dice_stream_update(struct snd_dice *dice)
154{
155 /*
156 * On a bus reset, the DICE firmware disables streaming and then goes
157 * off contemplating its own navel for hundreds of milliseconds before
158 * it can react to any of our attempts to reenable streaming. This
159 * means that we lose synchronization anyway, so we force our streams
160 * to stop so that the application can restart them in an orderly
161 * manner.
162 */
163 dice->global_enabled = false;
164
165 amdtp_stream_pcm_abort(&dice->rx_stream);
166 snd_dice_stream_stop_packets(dice);
167 fw_iso_resources_update(&dice->rx_resources);
168}
169
170static void dice_lock_changed(struct snd_dice *dice)
171{
172 dice->dev_lock_changed = true;
173 wake_up(&dice->hwdep_wait);
174}
175
176int snd_dice_stream_lock_try(struct snd_dice *dice)
177{
178 int err;
179
180 spin_lock_irq(&dice->lock);
181
182 if (dice->dev_lock_count < 0) {
183 err = -EBUSY;
184 goto out;
185 }
186
187 if (dice->dev_lock_count++ == 0)
188 dice_lock_changed(dice);
189 err = 0;
190out:
191 spin_unlock_irq(&dice->lock);
192 return err;
193}
194
195void snd_dice_stream_lock_release(struct snd_dice *dice)
196{
197 spin_lock_irq(&dice->lock);
198
199 if (WARN_ON(dice->dev_lock_count <= 0))
200 goto out;
201
202 if (--dice->dev_lock_count == 0)
203 dice_lock_changed(dice);
204out:
205 spin_unlock_irq(&dice->lock);
206}
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c
index dd62316ea8b3..e032b1caa776 100644
--- a/sound/firewire/dice/dice.c
+++ b/sound/firewire/dice/dice.c
@@ -11,127 +11,62 @@ MODULE_DESCRIPTION("DICE driver");
11MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 11MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
12MODULE_LICENSE("GPL v2"); 12MODULE_LICENSE("GPL v2");
13 13
14const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT] = {
15 /* mode 0 */
16 [0] = 32000,
17 [1] = 44100,
18 [2] = 48000,
19 /* mode 1 */
20 [3] = 88200,
21 [4] = 96000,
22 /* mode 2 */
23 [5] = 176400,
24 [6] = 192000,
25};
26
27static unsigned int rate_to_index(unsigned int rate)
28{
29 unsigned int i;
30
31 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i)
32 if (snd_dice_rates[i] == rate)
33 return i;
34
35 return 0;
36}
37
38static unsigned int rate_index_to_mode(unsigned int rate_index)
39{
40 return ((int)rate_index - 1) / 2;
41}
42
43static void dice_lock_changed(struct snd_dice *dice)
44{
45 dice->dev_lock_changed = true;
46 wake_up(&dice->hwdep_wait);
47}
48
49static int dice_try_lock(struct snd_dice *dice)
50{
51 int err;
52
53 spin_lock_irq(&dice->lock);
54
55 if (dice->dev_lock_count < 0) {
56 err = -EBUSY;
57 goto out;
58 }
59
60 if (dice->dev_lock_count++ == 0)
61 dice_lock_changed(dice);
62 err = 0;
63
64out:
65 spin_unlock_irq(&dice->lock);
66
67 return err;
68}
69
70static void dice_unlock(struct snd_dice *dice)
71{
72 spin_lock_irq(&dice->lock);
73
74 if (WARN_ON(dice->dev_lock_count <= 0))
75 goto out;
76
77 if (--dice->dev_lock_count == 0)
78 dice_lock_changed(dice);
79
80out:
81 spin_unlock_irq(&dice->lock);
82}
83
84static int dice_rate_constraint(struct snd_pcm_hw_params *params, 14static int dice_rate_constraint(struct snd_pcm_hw_params *params,
85 struct snd_pcm_hw_rule *rule) 15 struct snd_pcm_hw_rule *rule)
86{ 16{
87 struct snd_dice *dice = rule->private; 17 struct snd_dice *dice = rule->private;
88 const struct snd_interval *channels = 18
19 const struct snd_interval *c =
89 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS); 20 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);
90 struct snd_interval *rate = 21 struct snd_interval *r =
91 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 22 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
92 struct snd_interval allowed_rates = { 23 struct snd_interval rates = {
93 .min = UINT_MAX, .max = 0, .integer = 1 24 .min = UINT_MAX, .max = 0, .integer = 1
94 }; 25 };
95 unsigned int i, mode; 26 unsigned int i, rate, mode, *pcm_channels = dice->rx_channels;
96 27
97 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) { 28 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
98 mode = rate_index_to_mode(i); 29 rate = snd_dice_rates[i];
99 if ((dice->clock_caps & (1 << i)) && 30 if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
100 snd_interval_test(channels, dice->rx_channels[mode])) { 31 continue;
101 allowed_rates.min = min(allowed_rates.min, 32
102 snd_dice_rates[i]); 33 if (!snd_interval_test(c, pcm_channels[mode]))
103 allowed_rates.max = max(allowed_rates.max, 34 continue;
104 snd_dice_rates[i]); 35
105 } 36 rates.min = min(rates.min, rate);
37 rates.max = max(rates.max, rate);
106 } 38 }
107 39
108 return snd_interval_refine(rate, &allowed_rates); 40 return snd_interval_refine(r, &rates);
109} 41}
110 42
111static int dice_channels_constraint(struct snd_pcm_hw_params *params, 43static int dice_channels_constraint(struct snd_pcm_hw_params *params,
112 struct snd_pcm_hw_rule *rule) 44 struct snd_pcm_hw_rule *rule)
113{ 45{
114 struct snd_dice *dice = rule->private; 46 struct snd_dice *dice = rule->private;
115 const struct snd_interval *rate = 47
48 const struct snd_interval *r =
116 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE); 49 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
117 struct snd_interval *channels = 50 struct snd_interval *c =
118 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 51 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
119 struct snd_interval allowed_channels = { 52 struct snd_interval channels = {
120 .min = UINT_MAX, .max = 0, .integer = 1 53 .min = UINT_MAX, .max = 0, .integer = 1
121 }; 54 };
122 unsigned int i, mode; 55 unsigned int i, rate, mode, *pcm_channels = dice->rx_channels;
123 56
124 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) 57 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
125 if ((dice->clock_caps & (1 << i)) && 58 rate = snd_dice_rates[i];
126 snd_interval_test(rate, snd_dice_rates[i])) { 59 if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
127 mode = rate_index_to_mode(i); 60 continue;
128 allowed_channels.min = min(allowed_channels.min,
129 dice->rx_channels[mode]);
130 allowed_channels.max = max(allowed_channels.max,
131 dice->rx_channels[mode]);
132 }
133 61
134 return snd_interval_refine(channels, &allowed_channels); 62 if (!snd_interval_test(r, rate))
63 continue;
64
65 channels.min = min(channels.min, pcm_channels[mode]);
66 channels.max = max(channels.max, pcm_channels[mode]);
67 }
68
69 return snd_interval_refine(c, &channels);
135} 70}
136 71
137static int dice_open(struct snd_pcm_substream *substream) 72static int dice_open(struct snd_pcm_substream *substream)
@@ -156,7 +91,7 @@ static int dice_open(struct snd_pcm_substream *substream)
156 unsigned int i; 91 unsigned int i;
157 int err; 92 int err;
158 93
159 err = dice_try_lock(dice); 94 err = snd_dice_stream_lock_try(dice);
160 if (err < 0) 95 if (err < 0)
161 goto error; 96 goto error;
162 97
@@ -194,7 +129,7 @@ static int dice_open(struct snd_pcm_substream *substream)
194 return 0; 129 return 0;
195 130
196err_lock: 131err_lock:
197 dice_unlock(dice); 132 snd_dice_stream_lock_release(dice);
198error: 133error:
199 return err; 134 return err;
200} 135}
@@ -203,98 +138,20 @@ static int dice_close(struct snd_pcm_substream *substream)
203{ 138{
204 struct snd_dice *dice = substream->private_data; 139 struct snd_dice *dice = substream->private_data;
205 140
206 dice_unlock(dice); 141 snd_dice_stream_lock_release(dice);
207 142
208 return 0; 143 return 0;
209} 144}
210 145
211static int dice_stream_start_packets(struct snd_dice *dice)
212{
213 int err;
214
215 if (amdtp_stream_running(&dice->rx_stream))
216 return 0;
217
218 err = amdtp_stream_start(&dice->rx_stream, dice->rx_resources.channel,
219 fw_parent_device(dice->unit)->max_speed);
220 if (err < 0)
221 return err;
222
223 err = snd_dice_transaction_set_enable(dice);
224 if (err < 0) {
225 amdtp_stream_stop(&dice->rx_stream);
226 return err;
227 }
228
229 return 0;
230}
231
232static int dice_stream_start(struct snd_dice *dice)
233{
234 __be32 channel;
235 int err;
236
237 if (!dice->rx_resources.allocated) {
238 err = fw_iso_resources_allocate(&dice->rx_resources,
239 amdtp_stream_get_max_payload(&dice->rx_stream),
240 fw_parent_device(dice->unit)->max_speed);
241 if (err < 0)
242 goto error;
243
244 channel = cpu_to_be32(dice->rx_resources.channel);
245 err = snd_dice_transaction_write_tx(dice, TX_ISOCHRONOUS,
246 &channel, 4);
247 if (err < 0)
248 goto err_resources;
249 }
250
251 err = dice_stream_start_packets(dice);
252 if (err < 0)
253 goto err_rx_channel;
254
255 return 0;
256
257err_rx_channel:
258 channel = cpu_to_be32((u32)-1);
259 snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS, &channel, 4);
260err_resources:
261 fw_iso_resources_free(&dice->rx_resources);
262error:
263 return err;
264}
265
266static void dice_stream_stop_packets(struct snd_dice *dice)
267{
268 if (amdtp_stream_running(&dice->rx_stream)) {
269 snd_dice_transaction_clear_enable(dice);
270 amdtp_stream_stop(&dice->rx_stream);
271 }
272}
273
274static void dice_stream_stop(struct snd_dice *dice)
275{
276 __be32 channel;
277
278 dice_stream_stop_packets(dice);
279
280 if (!dice->rx_resources.allocated)
281 return;
282
283 channel = cpu_to_be32((u32)-1);
284 snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS, &channel, 4);
285
286 fw_iso_resources_free(&dice->rx_resources);
287}
288
289static int dice_hw_params(struct snd_pcm_substream *substream, 146static int dice_hw_params(struct snd_pcm_substream *substream,
290 struct snd_pcm_hw_params *hw_params) 147 struct snd_pcm_hw_params *hw_params)
291{ 148{
292 struct snd_dice *dice = substream->private_data; 149 struct snd_dice *dice = substream->private_data;
293 unsigned int rate_index, mode, rate, channels, i; 150 unsigned int mode, rate, channels, i;
294 int err; 151 int err;
295 152
296 mutex_lock(&dice->mutex); 153 mutex_lock(&dice->mutex);
297 dice_stream_stop(dice); 154 snd_dice_stream_stop(dice);
298 mutex_unlock(&dice->mutex); 155 mutex_unlock(&dice->mutex);
299 156
300 err = snd_pcm_lib_alloc_vmalloc_buffer(substream, 157 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
@@ -307,6 +164,10 @@ static int dice_hw_params(struct snd_pcm_substream *substream,
307 if (err < 0) 164 if (err < 0)
308 return err; 165 return err;
309 166
167 err = snd_dice_stream_get_rate_mode(dice, rate, &mode);
168 if (err < 0)
169 return err;
170
310 /* 171 /*
311 * At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in 172 * At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in
312 * one data block of AMDTP packet. Thus sampling transfer frequency is 173 * one data block of AMDTP packet. Thus sampling transfer frequency is
@@ -318,8 +179,7 @@ static int dice_hw_params(struct snd_pcm_substream *substream,
318 * be aligned to SYT_INTERVAL. 179 * be aligned to SYT_INTERVAL.
319 */ 180 */
320 channels = params_channels(hw_params); 181 channels = params_channels(hw_params);
321 rate_index = rate_to_index(rate); 182 if (mode > 1) {
322 if (rate_index > 4) {
323 if (channels > AMDTP_MAX_CHANNELS_FOR_PCM / 2) { 183 if (channels > AMDTP_MAX_CHANNELS_FOR_PCM / 2) {
324 err = -ENOSYS; 184 err = -ENOSYS;
325 return err; 185 return err;
@@ -332,10 +192,9 @@ static int dice_hw_params(struct snd_pcm_substream *substream,
332 dice->rx_stream.double_pcm_frames = false; 192 dice->rx_stream.double_pcm_frames = false;
333 } 193 }
334 194
335 mode = rate_index_to_mode(rate_index);
336 amdtp_stream_set_parameters(&dice->rx_stream, rate, channels, 195 amdtp_stream_set_parameters(&dice->rx_stream, rate, channels,
337 dice->rx_midi_ports[mode]); 196 dice->rx_midi_ports[mode]);
338 if (rate_index > 4) { 197 if (mode > 4) {
339 channels /= 2; 198 channels /= 2;
340 199
341 for (i = 0; i < channels; i++) { 200 for (i = 0; i < channels; i++) {
@@ -355,7 +214,7 @@ static int dice_hw_free(struct snd_pcm_substream *substream)
355 struct snd_dice *dice = substream->private_data; 214 struct snd_dice *dice = substream->private_data;
356 215
357 mutex_lock(&dice->mutex); 216 mutex_lock(&dice->mutex);
358 dice_stream_stop(dice); 217 snd_dice_stream_stop(dice);
359 mutex_unlock(&dice->mutex); 218 mutex_unlock(&dice->mutex);
360 219
361 return snd_pcm_lib_free_vmalloc_buffer(substream); 220 return snd_pcm_lib_free_vmalloc_buffer(substream);
@@ -369,9 +228,9 @@ static int dice_prepare(struct snd_pcm_substream *substream)
369 mutex_lock(&dice->mutex); 228 mutex_lock(&dice->mutex);
370 229
371 if (amdtp_streaming_error(&dice->rx_stream)) 230 if (amdtp_streaming_error(&dice->rx_stream))
372 dice_stream_stop_packets(dice); 231 snd_dice_stream_stop_packets(dice);
373 232
374 err = dice_stream_start(dice); 233 err = snd_dice_stream_start(dice);
375 if (err < 0) { 234 if (err < 0) {
376 mutex_unlock(&dice->mutex); 235 mutex_unlock(&dice->mutex);
377 return err; 236 return err;
@@ -966,31 +825,37 @@ end:
966 return err; 825 return err;
967} 826}
968 827
969static int highest_supported_mode_rate(struct snd_dice *dice, unsigned int mode) 828static int highest_supported_mode_rate(struct snd_dice *dice,
829 unsigned int mode, unsigned int *rate)
970{ 830{
971 int i; 831 unsigned int i, m;
972 832
973 for (i = ARRAY_SIZE(snd_dice_rates) - 1; i >= 0; --i) 833 for (i = ARRAY_SIZE(snd_dice_rates); i > 0; i--) {
974 if ((dice->clock_caps & (1 << i)) && 834 *rate = snd_dice_rates[i - 1];
975 rate_index_to_mode(i) == mode) 835 if (snd_dice_stream_get_rate_mode(dice, *rate, &m) < 0)
976 return i; 836 continue;
837 if (mode == m)
838 break;
839 }
840 if (i == 0)
841 return -EINVAL;
977 842
978 return -1; 843 return 0;
979} 844}
980 845
981static int dice_read_mode_params(struct snd_dice *dice, unsigned int mode) 846static int dice_read_mode_params(struct snd_dice *dice, unsigned int mode)
982{ 847{
983 __be32 values[2]; 848 __be32 values[2];
984 int rate_index, err; 849 unsigned int rate;
850 int err;
985 851
986 rate_index = highest_supported_mode_rate(dice, mode); 852 if (highest_supported_mode_rate(dice, mode, &rate) < 0) {
987 if (rate_index < 0) {
988 dice->rx_channels[mode] = 0; 853 dice->rx_channels[mode] = 0;
989 dice->rx_midi_ports[mode] = 0; 854 dice->rx_midi_ports[mode] = 0;
990 return 0; 855 return 0;
991 } 856 }
992 857
993 err = snd_dice_transaction_set_rate(dice, snd_dice_rates[rate_index]); 858 err = snd_dice_transaction_set_rate(dice, rate);
994 if (err < 0) 859 if (err < 0)
995 return err; 860 return err;
996 861
@@ -1113,10 +978,6 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
1113 978
1114 dice_card_strings(dice); 979 dice_card_strings(dice);
1115 980
1116 err = snd_dice_transaction_set_clock_source(dice, CLOCK_SOURCE_ARX1);
1117 if (err < 0)
1118 goto error;
1119
1120 err = dice_create_pcm(dice); 981 err = dice_create_pcm(dice);
1121 if (err < 0) 982 if (err < 0)
1122 goto error; 983 goto error;
@@ -1127,22 +988,13 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
1127 988
1128 dice_create_proc(dice); 989 dice_create_proc(dice);
1129 990
1130 err = fw_iso_resources_init(&dice->rx_resources, unit); 991 err = snd_dice_stream_init(dice);
1131 if (err < 0) 992 if (err < 0)
1132 goto error; 993 goto error;
1133 dice->rx_resources.channels_mask = 0x00000000ffffffffuLL;
1134
1135 err = amdtp_stream_init(&dice->rx_stream, unit, AMDTP_OUT_STREAM,
1136 CIP_BLOCKING);
1137 if (err < 0) {
1138 fw_iso_resources_destroy(&dice->rx_resources);
1139 goto error;
1140 }
1141 994
1142 err = snd_card_register(card); 995 err = snd_card_register(card);
1143 if (err < 0) { 996 if (err < 0) {
1144 amdtp_stream_destroy(&dice->rx_stream); 997 snd_dice_stream_destroy(dice);
1145 fw_iso_resources_destroy(&dice->rx_resources);
1146 goto error; 998 goto error;
1147 } 999 }
1148 1000
@@ -1158,13 +1010,11 @@ static void dice_remove(struct fw_unit *unit)
1158{ 1010{
1159 struct snd_dice *dice = dev_get_drvdata(&unit->device); 1011 struct snd_dice *dice = dev_get_drvdata(&unit->device);
1160 1012
1161 amdtp_stream_pcm_abort(&dice->rx_stream);
1162
1163 snd_card_disconnect(dice->card); 1013 snd_card_disconnect(dice->card);
1164 1014
1165 mutex_lock(&dice->mutex); 1015 mutex_lock(&dice->mutex);
1166 1016
1167 dice_stream_stop(dice); 1017 snd_dice_stream_destroy(dice);
1168 1018
1169 mutex_unlock(&dice->mutex); 1019 mutex_unlock(&dice->mutex);
1170 1020
@@ -1178,23 +1028,8 @@ static void dice_bus_reset(struct fw_unit *unit)
1178 /* The handler address register becomes initialized. */ 1028 /* The handler address register becomes initialized. */
1179 snd_dice_transaction_reinit(dice); 1029 snd_dice_transaction_reinit(dice);
1180 1030
1181 /*
1182 * On a bus reset, the DICE firmware disables streaming and then goes
1183 * off contemplating its own navel for hundreds of milliseconds before
1184 * it can react to any of our attempts to reenable streaming. This
1185 * means that we lose synchronization anyway, so we force our streams
1186 * to stop so that the application can restart them in an orderly
1187 * manner.
1188 */
1189 amdtp_stream_pcm_abort(&dice->rx_stream);
1190
1191 mutex_lock(&dice->mutex); 1031 mutex_lock(&dice->mutex);
1192 1032 snd_dice_stream_update(dice);
1193 dice->global_enabled = false;
1194
1195 dice_stream_stop_packets(dice);
1196 fw_iso_resources_update(&dice->rx_resources);
1197
1198 mutex_unlock(&dice->mutex); 1033 mutex_unlock(&dice->mutex);
1199} 1034}
1200 1035
diff --git a/sound/firewire/dice/dice.h b/sound/firewire/dice/dice.h
index c756e62ea4ec..ca4090d881e6 100644
--- a/sound/firewire/dice/dice.h
+++ b/sound/firewire/dice/dice.h
@@ -157,4 +157,18 @@ void snd_dice_transaction_destroy(struct snd_dice *dice);
157#define SND_DICE_RATES_COUNT 7 157#define SND_DICE_RATES_COUNT 7
158extern const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT]; 158extern const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT];
159 159
160int snd_dice_stream_get_rate_mode(struct snd_dice *dice,
161 unsigned int rate, unsigned int *mode);
162
163int snd_dice_stream_start_packets(struct snd_dice *dice);
164int snd_dice_stream_start(struct snd_dice *dice);
165void snd_dice_stream_stop_packets(struct snd_dice *dice);
166void snd_dice_stream_stop(struct snd_dice *dice);
167int snd_dice_stream_init(struct snd_dice *dice);
168void snd_dice_stream_destroy(struct snd_dice *dice);
169void snd_dice_stream_update(struct snd_dice *dice);
170
171int snd_dice_stream_lock_try(struct snd_dice *dice);
172void snd_dice_stream_lock_release(struct snd_dice *dice);
173
160#endif 174#endif