aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/firewire/dice/dice-pcm.c75
-rw-r--r--sound/firewire/dice/dice-stream.c191
-rw-r--r--sound/firewire/dice/dice.c4
-rw-r--r--sound/firewire/dice/dice.h4
4 files changed, 143 insertions, 131 deletions
diff --git a/sound/firewire/dice/dice-pcm.c b/sound/firewire/dice/dice-pcm.c
index 2e531bd30e28..b185391dc021 100644
--- a/sound/firewire/dice/dice-pcm.c
+++ b/sound/firewire/dice/dice-pcm.c
@@ -169,65 +169,11 @@ static int playback_hw_params(struct snd_pcm_substream *substream,
169 struct snd_pcm_hw_params *hw_params) 169 struct snd_pcm_hw_params *hw_params)
170{ 170{
171 struct snd_dice *dice = substream->private_data; 171 struct snd_dice *dice = substream->private_data;
172 unsigned int mode, rate, channels, i;
173 int err;
174
175 mutex_lock(&dice->mutex);
176 snd_dice_stream_stop(dice);
177 mutex_unlock(&dice->mutex);
178
179 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
180 params_buffer_bytes(hw_params));
181 if (err < 0)
182 return err;
183
184 rate = params_rate(hw_params);
185 err = snd_dice_transaction_set_rate(dice, rate);
186 if (err < 0)
187 return err;
188
189 if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
190 return err;
191
192 /*
193 * At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in
194 * one data block of AMDTP packet. Thus sampling transfer frequency is
195 * a half of PCM sampling frequency, i.e. PCM frames at 192.0 kHz are
196 * transferred on AMDTP packets at 96 kHz. Two successive samples of a
197 * channel are stored consecutively in the packet. This quirk is called
198 * as 'Dual Wire'.
199 * For this quirk, blocking mode is required and PCM buffer size should
200 * be aligned to SYT_INTERVAL.
201 */
202 channels = params_channels(hw_params);
203 if (mode > 1) {
204 if (channels > AMDTP_MAX_CHANNELS_FOR_PCM / 2) {
205 err = -ENOSYS;
206 return err;
207 }
208
209 rate /= 2;
210 channels *= 2;
211 dice->rx_stream.double_pcm_frames = true;
212 } else {
213 dice->rx_stream.double_pcm_frames = false;
214 }
215
216 amdtp_stream_set_parameters(&dice->rx_stream, rate, channels,
217 dice->rx_midi_ports[mode]);
218 if (mode > 1) {
219 channels /= 2;
220
221 for (i = 0; i < channels; i++) {
222 dice->rx_stream.pcm_positions[i] = i * 2;
223 dice->rx_stream.pcm_positions[i + channels] = i * 2 + 1;
224 }
225 }
226
227 amdtp_stream_set_pcm_format(&dice->rx_stream, 172 amdtp_stream_set_pcm_format(&dice->rx_stream,
228 params_format(hw_params)); 173 params_format(hw_params));
229 174
230 return 0; 175 return snd_pcm_lib_alloc_vmalloc_buffer(substream,
176 params_buffer_bytes(hw_params));
231} 177}
232 178
233static int playback_hw_free(struct snd_pcm_substream *substream) 179static int playback_hw_free(struct snd_pcm_substream *substream)
@@ -247,21 +193,12 @@ static int playback_prepare(struct snd_pcm_substream *substream)
247 int err; 193 int err;
248 194
249 mutex_lock(&dice->mutex); 195 mutex_lock(&dice->mutex);
250 196 err = snd_dice_stream_start(dice, substream->runtime->rate);
251 if (amdtp_streaming_error(&dice->rx_stream))
252 snd_dice_stream_stop_packets(dice);
253
254 err = snd_dice_stream_start(dice);
255 if (err < 0) {
256 mutex_unlock(&dice->mutex);
257 return err;
258 }
259
260 mutex_unlock(&dice->mutex); 197 mutex_unlock(&dice->mutex);
198 if (err >= 0)
199 amdtp_stream_pcm_prepare(&dice->rx_stream);
261 200
262 amdtp_stream_pcm_prepare(&dice->rx_stream); 201 return err;
263
264 return 0;
265} 202}
266 203
267static int playback_trigger(struct snd_pcm_substream *substream, int cmd) 204static int playback_trigger(struct snd_pcm_substream *substream, int cmd)
diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c
index 4c4c4fff6272..b9d7a4846459 100644
--- a/sound/firewire/dice/dice-stream.c
+++ b/sound/firewire/dice/dice-stream.c
@@ -9,6 +9,8 @@
9 9
10#include "dice.h" 10#include "dice.h"
11 11
12#define CALLBACK_TIMEOUT 200
13
12const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT] = { 14const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT] = {
13 /* mode 0 */ 15 /* mode 0 */
14 [0] = 32000, 16 [0] = 32000,
@@ -39,83 +41,162 @@ int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate,
39 return -EINVAL; 41 return -EINVAL;
40} 42}
41 43
42int snd_dice_stream_start_packets(struct snd_dice *dice) 44static void release_resources(struct snd_dice *dice)
43{ 45{
44 int err; 46 unsigned int channel;
45 47
46 if (amdtp_stream_running(&dice->rx_stream)) 48 /* Reset channel number */
47 return 0; 49 channel = cpu_to_be32((u32)-1);
48 50 snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS, &channel, 4);
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 51
60 return 0; 52 fw_iso_resources_free(&dice->rx_resources);
61} 53}
62 54
63int snd_dice_stream_start(struct snd_dice *dice) 55static int keep_resources(struct snd_dice *dice, unsigned int max_payload_bytes)
64{ 56{
65 __be32 channel; 57 unsigned int channel;
66 int err; 58 int err;
67 59
68 if (!dice->rx_resources.allocated) { 60 err = fw_iso_resources_allocate(&dice->rx_resources, max_payload_bytes,
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); 61 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) 62 if (err < 0)
84 goto err_rx_channel; 63 goto end;
85
86 return 0;
87 64
88err_rx_channel: 65 /* Set channel number */
89 channel = cpu_to_be32((u32)-1); 66 channel = cpu_to_be32(dice->rx_resources.channel);
90 snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS, &channel, 4); 67 err = snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS,
91err_resources: 68 &channel, 4);
92 fw_iso_resources_free(&dice->rx_resources); 69 if (err < 0)
93error: 70 release_resources(dice);
71end:
94 return err; 72 return err;
95} 73}
96 74
97void snd_dice_stream_stop_packets(struct snd_dice *dice) 75static void stop_stream(struct snd_dice *dice)
98{ 76{
99 if (!amdtp_stream_running(&dice->rx_stream)) 77 if (!amdtp_stream_running(&dice->rx_stream))
100 return; 78 return;
101 79
102 snd_dice_transaction_clear_enable(dice); 80 amdtp_stream_pcm_abort(&dice->rx_stream);
103 amdtp_stream_stop(&dice->rx_stream); 81 amdtp_stream_stop(&dice->rx_stream);
82 release_resources(dice);
104} 83}
105 84
106void snd_dice_stream_stop(struct snd_dice *dice) 85static int start_stream(struct snd_dice *dice, unsigned int rate)
107{ 86{
108 __be32 channel; 87 unsigned int i, mode, pcm_chs, midi_ports;
88 int err;
109 89
110 snd_dice_stream_stop_packets(dice); 90 err = snd_dice_stream_get_rate_mode(dice, rate, &mode);
91 if (err < 0)
92 goto end;
111 93
112 if (!dice->rx_resources.allocated) 94 /*
113 return; 95 * At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in
96 * one data block of AMDTP packet. Thus sampling transfer frequency is
97 * a half of PCM sampling frequency, i.e. PCM frames at 192.0 kHz are
98 * transferred on AMDTP packets at 96 kHz. Two successive samples of a
99 * channel are stored consecutively in the packet. This quirk is called
100 * as 'Dual Wire'.
101 * For this quirk, blocking mode is required and PCM buffer size should
102 * be aligned to SYT_INTERVAL.
103 */
104 pcm_chs = dice->rx_channels[mode];
105 midi_ports = dice->rx_midi_ports[mode];
106 if (mode > 1) {
107 rate /= 2;
108 pcm_chs *= 2;
109 dice->rx_stream.double_pcm_frames = true;
110 } else {
111 dice->rx_stream.double_pcm_frames = false;
112 }
114 113
115 channel = cpu_to_be32((u32)-1); 114 amdtp_stream_set_parameters(&dice->rx_stream, rate,
116 snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS, &channel, 4); 115 pcm_chs, midi_ports);
116 if (mode > 1) {
117 pcm_chs /= 2;
117 118
118 fw_iso_resources_free(&dice->rx_resources); 119 for (i = 0; i < pcm_chs; i++) {
120 dice->rx_stream.pcm_positions[i] = i * 2;
121 dice->rx_stream.pcm_positions[i + pcm_chs] = i * 2 + 1;
122 }
123 }
124
125 err = keep_resources(dice,
126 amdtp_stream_get_max_payload(&dice->rx_stream));
127 if (err < 0) {
128 dev_err(&dice->unit->device,
129 "fail to keep isochronous resources\n");
130 goto end;
131 }
132
133 err = amdtp_stream_start(&dice->rx_stream, dice->rx_resources.channel,
134 fw_parent_device(dice->unit)->max_speed);
135 if (err < 0)
136 release_resources(dice);
137end:
138 return err;
139}
140
141int snd_dice_stream_start(struct snd_dice *dice, unsigned int rate)
142{
143 unsigned int curr_rate;
144 int err;
145
146 /* Some packet queueing errors. */
147 if (amdtp_streaming_error(&dice->rx_stream))
148 stop_stream(dice);
149
150 /* Stop stream if rate is different. */
151 err = snd_dice_transaction_get_rate(dice, &curr_rate);
152 if (err < 0) {
153 dev_err(&dice->unit->device,
154 "fail to get sampling rate\n");
155 goto end;
156 }
157 if (rate != curr_rate)
158 stop_stream(dice);
159
160 if (!amdtp_stream_running(&dice->rx_stream)) {
161 snd_dice_transaction_clear_enable(dice);
162
163 err = snd_dice_transaction_set_rate(dice, rate);
164 if (err < 0) {
165 dev_err(&dice->unit->device,
166 "fail to set sampling rate\n");
167 goto end;
168 }
169
170 /* Start stream. */
171 err = start_stream(dice, rate);
172 if (err < 0) {
173 dev_err(&dice->unit->device,
174 "fail to start AMDTP stream\n");
175 goto end;
176 }
177 err = snd_dice_transaction_set_enable(dice);
178 if (err < 0) {
179 dev_err(&dice->unit->device,
180 "fail to enable interface\n");
181 stop_stream(dice);
182 goto end;
183 }
184
185 if (!amdtp_stream_wait_callback(&dice->rx_stream,
186 CALLBACK_TIMEOUT)) {
187 snd_dice_transaction_clear_enable(dice);
188 stop_stream(dice);
189 err = -ETIMEDOUT;
190 }
191 }
192end:
193 return err;
194}
195
196void snd_dice_stream_stop(struct snd_dice *dice)
197{
198 snd_dice_transaction_clear_enable(dice);
199 stop_stream(dice);
119} 200}
120 201
121int snd_dice_stream_init(struct snd_dice *dice) 202int snd_dice_stream_init(struct snd_dice *dice)
@@ -145,8 +226,8 @@ error:
145 226
146void snd_dice_stream_destroy(struct snd_dice *dice) 227void snd_dice_stream_destroy(struct snd_dice *dice)
147{ 228{
148 amdtp_stream_pcm_abort(&dice->rx_stream); 229 snd_dice_transaction_clear_enable(dice);
149 snd_dice_stream_stop(dice); 230 stop_stream(dice);
150 amdtp_stream_destroy(&dice->rx_stream); 231 amdtp_stream_destroy(&dice->rx_stream);
151 fw_iso_resources_destroy(&dice->rx_resources); 232 fw_iso_resources_destroy(&dice->rx_resources);
152} 233}
@@ -163,8 +244,8 @@ void snd_dice_stream_update(struct snd_dice *dice)
163 */ 244 */
164 dice->global_enabled = false; 245 dice->global_enabled = false;
165 246
166 amdtp_stream_pcm_abort(&dice->rx_stream); 247 stop_stream(dice);
167 snd_dice_stream_stop_packets(dice); 248
168 fw_iso_resources_update(&dice->rx_resources); 249 fw_iso_resources_update(&dice->rx_resources);
169} 250}
170 251
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c
index 8e2c172de8a7..03a7988871b6 100644
--- a/sound/firewire/dice/dice.c
+++ b/sound/firewire/dice/dice.c
@@ -304,12 +304,8 @@ static void dice_remove(struct fw_unit *unit)
304 304
305 snd_card_disconnect(dice->card); 305 snd_card_disconnect(dice->card);
306 306
307 mutex_lock(&dice->mutex);
308
309 snd_dice_stream_destroy(dice); 307 snd_dice_stream_destroy(dice);
310 308
311 mutex_unlock(&dice->mutex);
312
313 snd_card_free_when_closed(dice->card); 309 snd_card_free_when_closed(dice->card);
314} 310}
315 311
diff --git a/sound/firewire/dice/dice.h b/sound/firewire/dice/dice.h
index 969189a6604f..8be530fe1c34 100644
--- a/sound/firewire/dice/dice.h
+++ b/sound/firewire/dice/dice.h
@@ -160,9 +160,7 @@ extern const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT];
160int snd_dice_stream_get_rate_mode(struct snd_dice *dice, 160int snd_dice_stream_get_rate_mode(struct snd_dice *dice,
161 unsigned int rate, unsigned int *mode); 161 unsigned int rate, unsigned int *mode);
162 162
163int snd_dice_stream_start_packets(struct snd_dice *dice); 163int snd_dice_stream_start(struct snd_dice *dice, unsigned int rate);
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); 164void snd_dice_stream_stop(struct snd_dice *dice);
167int snd_dice_stream_init(struct snd_dice *dice); 165int snd_dice_stream_init(struct snd_dice *dice);
168void snd_dice_stream_destroy(struct snd_dice *dice); 166void snd_dice_stream_destroy(struct snd_dice *dice);