aboutsummaryrefslogtreecommitdiffstats
path: root/sound/firewire
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2014-11-28 10:59:15 -0500
committerTakashi Iwai <tiwai@suse.de>2014-11-29 14:07:47 -0500
commitc50fb91f53626e3bdae3ffebfee586786f970f7c (patch)
treeb22892f33dca379202cdffad945c8fb7fb1c8203 /sound/firewire
parent6eb6c81eee2a6270b39ca02a446f3ccece24b6f8 (diff)
ALSA: dice: Split PCM functionality into a file
This commit adds a file and move some codes related to PCM functionality. Currently PCM playback is supported. PCM capture will be supported in followed commits. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/firewire')
-rw-r--r--sound/firewire/dice/Makefile2
-rw-r--r--sound/firewire/dice/dice-pcm.c296
-rw-r--r--sound/firewire/dice/dice-stream.c9
-rw-r--r--sound/firewire/dice/dice.c288
-rw-r--r--sound/firewire/dice/dice.h2
5 files changed, 305 insertions, 292 deletions
diff --git a/sound/firewire/dice/Makefile b/sound/firewire/dice/Makefile
index 867864ca514f..1ddaeca9a137 100644
--- a/sound/firewire/dice/Makefile
+++ b/sound/firewire/dice/Makefile
@@ -1,2 +1,2 @@
1snd-dice-objs := dice-transaction.o dice-stream.o dice.o 1snd-dice-objs := dice-transaction.o dice-stream.o dice-pcm.o dice.o
2obj-m += snd-dice.o 2obj-m += snd-dice.o
diff --git a/sound/firewire/dice/dice-pcm.c b/sound/firewire/dice/dice-pcm.c
new file mode 100644
index 000000000000..deacb537eb81
--- /dev/null
+++ b/sound/firewire/dice/dice-pcm.c
@@ -0,0 +1,296 @@
1/*
2 * dice_pcm.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
12static int dice_rate_constraint(struct snd_pcm_hw_params *params,
13 struct snd_pcm_hw_rule *rule)
14{
15 struct snd_dice *dice = rule->private;
16
17 const struct snd_interval *c =
18 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);
19 struct snd_interval *r =
20 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
21 struct snd_interval rates = {
22 .min = UINT_MAX, .max = 0, .integer = 1
23 };
24 unsigned int i, rate, mode, *pcm_channels = dice->rx_channels;
25
26 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
27 rate = snd_dice_rates[i];
28 if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
29 continue;
30
31 if (!snd_interval_test(c, pcm_channels[mode]))
32 continue;
33
34 rates.min = min(rates.min, rate);
35 rates.max = max(rates.max, rate);
36 }
37
38 return snd_interval_refine(r, &rates);
39}
40
41static int dice_channels_constraint(struct snd_pcm_hw_params *params,
42 struct snd_pcm_hw_rule *rule)
43{
44 struct snd_dice *dice = rule->private;
45
46 const struct snd_interval *r =
47 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
48 struct snd_interval *c =
49 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
50 struct snd_interval channels = {
51 .min = UINT_MAX, .max = 0, .integer = 1
52 };
53 unsigned int i, rate, mode, *pcm_channels = dice->rx_channels;
54
55 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
56 rate = snd_dice_rates[i];
57 if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
58 continue;
59
60 if (!snd_interval_test(r, rate))
61 continue;
62
63 channels.min = min(channels.min, pcm_channels[mode]);
64 channels.max = max(channels.max, pcm_channels[mode]);
65 }
66
67 return snd_interval_refine(c, &channels);
68}
69
70
71static int pcm_open(struct snd_pcm_substream *substream)
72{
73 static const struct snd_pcm_hardware hardware = {
74 .info = SNDRV_PCM_INFO_MMAP |
75 SNDRV_PCM_INFO_MMAP_VALID |
76 SNDRV_PCM_INFO_BATCH |
77 SNDRV_PCM_INFO_INTERLEAVED |
78 SNDRV_PCM_INFO_BLOCK_TRANSFER,
79 .formats = AMDTP_OUT_PCM_FORMAT_BITS,
80 .channels_min = UINT_MAX,
81 .channels_max = 0,
82 .buffer_bytes_max = 16 * 1024 * 1024,
83 .period_bytes_min = 1,
84 .period_bytes_max = UINT_MAX,
85 .periods_min = 1,
86 .periods_max = UINT_MAX,
87 };
88 struct snd_dice *dice = substream->private_data;
89 struct snd_pcm_runtime *runtime = substream->runtime;
90 unsigned int i;
91 int err;
92
93 err = snd_dice_stream_lock_try(dice);
94 if (err < 0)
95 goto error;
96
97 runtime->hw = hardware;
98
99 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
100 if (dice->clock_caps & (1 << i))
101 runtime->hw.rates |=
102 snd_pcm_rate_to_rate_bit(snd_dice_rates[i]);
103 }
104 snd_pcm_limit_hw_rates(runtime);
105
106 for (i = 0; i < 3; ++i) {
107 if (dice->rx_channels[i]) {
108 runtime->hw.channels_min = min(runtime->hw.channels_min,
109 dice->rx_channels[i]);
110 runtime->hw.channels_max = max(runtime->hw.channels_max,
111 dice->rx_channels[i]);
112 }
113 }
114
115 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
116 dice_rate_constraint, dice,
117 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
118 if (err < 0)
119 goto err_lock;
120 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
121 dice_channels_constraint, dice,
122 SNDRV_PCM_HW_PARAM_RATE, -1);
123 if (err < 0)
124 goto err_lock;
125
126 err = amdtp_stream_add_pcm_hw_constraints(&dice->rx_stream, runtime);
127 if (err < 0)
128 goto err_lock;
129
130 return 0;
131
132err_lock:
133 snd_dice_stream_lock_release(dice);
134error:
135 return err;
136}
137
138static int pcm_close(struct snd_pcm_substream *substream)
139{
140 struct snd_dice *dice = substream->private_data;
141
142 snd_dice_stream_lock_release(dice);
143
144 return 0;
145}
146
147static int playback_hw_params(struct snd_pcm_substream *substream,
148 struct snd_pcm_hw_params *hw_params)
149{
150 struct snd_dice *dice = substream->private_data;
151 unsigned int mode, rate, channels, i;
152 int err;
153
154 mutex_lock(&dice->mutex);
155 snd_dice_stream_stop(dice);
156 mutex_unlock(&dice->mutex);
157
158 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
159 params_buffer_bytes(hw_params));
160 if (err < 0)
161 return err;
162
163 rate = params_rate(hw_params);
164 err = snd_dice_transaction_set_rate(dice, rate);
165 if (err < 0)
166 return err;
167
168 if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
169 return err;
170
171 /*
172 * At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in
173 * one data block of AMDTP packet. Thus sampling transfer frequency is
174 * a half of PCM sampling frequency, i.e. PCM frames at 192.0 kHz are
175 * transferred on AMDTP packets at 96 kHz. Two successive samples of a
176 * channel are stored consecutively in the packet. This quirk is called
177 * as 'Dual Wire'.
178 * For this quirk, blocking mode is required and PCM buffer size should
179 * be aligned to SYT_INTERVAL.
180 */
181 channels = params_channels(hw_params);
182 if (mode > 1) {
183 if (channels > AMDTP_MAX_CHANNELS_FOR_PCM / 2) {
184 err = -ENOSYS;
185 return err;
186 }
187
188 rate /= 2;
189 channels *= 2;
190 dice->rx_stream.double_pcm_frames = true;
191 } else {
192 dice->rx_stream.double_pcm_frames = false;
193 }
194
195 amdtp_stream_set_parameters(&dice->rx_stream, rate, channels,
196 dice->rx_midi_ports[mode]);
197 if (mode > 1) {
198 channels /= 2;
199
200 for (i = 0; i < channels; i++) {
201 dice->rx_stream.pcm_positions[i] = i * 2;
202 dice->rx_stream.pcm_positions[i + channels] = i * 2 + 1;
203 }
204 }
205
206 amdtp_stream_set_pcm_format(&dice->rx_stream,
207 params_format(hw_params));
208
209 return 0;
210}
211
212static int playback_hw_free(struct snd_pcm_substream *substream)
213{
214 struct snd_dice *dice = substream->private_data;
215
216 mutex_lock(&dice->mutex);
217 snd_dice_stream_stop(dice);
218 mutex_unlock(&dice->mutex);
219
220 return snd_pcm_lib_free_vmalloc_buffer(substream);
221}
222
223static int playback_prepare(struct snd_pcm_substream *substream)
224{
225 struct snd_dice *dice = substream->private_data;
226 int err;
227
228 mutex_lock(&dice->mutex);
229
230 if (amdtp_streaming_error(&dice->rx_stream))
231 snd_dice_stream_stop_packets(dice);
232
233 err = snd_dice_stream_start(dice);
234 if (err < 0) {
235 mutex_unlock(&dice->mutex);
236 return err;
237 }
238
239 mutex_unlock(&dice->mutex);
240
241 amdtp_stream_pcm_prepare(&dice->rx_stream);
242
243 return 0;
244}
245
246static int playback_trigger(struct snd_pcm_substream *substream, int cmd)
247{
248 struct snd_dice *dice = substream->private_data;
249
250 switch (cmd) {
251 case SNDRV_PCM_TRIGGER_START:
252 amdtp_stream_pcm_trigger(&dice->rx_stream, substream);
253 break;
254 case SNDRV_PCM_TRIGGER_STOP:
255 amdtp_stream_pcm_trigger(&dice->rx_stream, NULL);
256 break;
257 default:
258 return -EINVAL;
259 }
260
261 return 0;
262}
263
264static snd_pcm_uframes_t playback_pointer(struct snd_pcm_substream *substream)
265{
266 struct snd_dice *dice = substream->private_data;
267
268 return amdtp_stream_pcm_pointer(&dice->rx_stream);
269}
270
271int snd_dice_create_pcm(struct snd_dice *dice)
272{
273 static struct snd_pcm_ops playback_ops = {
274 .open = pcm_open,
275 .close = pcm_close,
276 .ioctl = snd_pcm_lib_ioctl,
277 .hw_params = playback_hw_params,
278 .hw_free = playback_hw_free,
279 .prepare = playback_prepare,
280 .trigger = playback_trigger,
281 .pointer = playback_pointer,
282 .page = snd_pcm_lib_get_vmalloc_page,
283 .mmap = snd_pcm_lib_mmap_vmalloc,
284 };
285 struct snd_pcm *pcm;
286 int err;
287
288 err = snd_pcm_new(dice->card, "DICE", 0, 1, 0, &pcm);
289 if (err < 0)
290 return err;
291 pcm->private_data = dice;
292 strcpy(pcm->name, dice->card->shortname);
293 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);
294
295 return 0;
296}
diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c
index c25b9fb39d1f..4c4c4fff6272 100644
--- a/sound/firewire/dice/dice-stream.c
+++ b/sound/firewire/dice/dice-stream.c
@@ -96,10 +96,11 @@ error:
96 96
97void snd_dice_stream_stop_packets(struct snd_dice *dice) 97void snd_dice_stream_stop_packets(struct snd_dice *dice)
98{ 98{
99 if (amdtp_stream_running(&dice->rx_stream)) { 99 if (!amdtp_stream_running(&dice->rx_stream))
100 snd_dice_transaction_clear_enable(dice); 100 return;
101 amdtp_stream_stop(&dice->rx_stream); 101
102 } 102 snd_dice_transaction_clear_enable(dice);
103 amdtp_stream_stop(&dice->rx_stream);
103} 104}
104 105
105void snd_dice_stream_stop(struct snd_dice *dice) 106void snd_dice_stream_stop(struct snd_dice *dice)
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c
index e032b1caa776..b76ed06e5c4d 100644
--- a/sound/firewire/dice/dice.c
+++ b/sound/firewire/dice/dice.c
@@ -11,292 +11,6 @@ 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
14static int dice_rate_constraint(struct snd_pcm_hw_params *params,
15 struct snd_pcm_hw_rule *rule)
16{
17 struct snd_dice *dice = rule->private;
18
19 const struct snd_interval *c =
20 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);
21 struct snd_interval *r =
22 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
23 struct snd_interval rates = {
24 .min = UINT_MAX, .max = 0, .integer = 1
25 };
26 unsigned int i, rate, mode, *pcm_channels = dice->rx_channels;
27
28 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
29 rate = snd_dice_rates[i];
30 if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
31 continue;
32
33 if (!snd_interval_test(c, pcm_channels[mode]))
34 continue;
35
36 rates.min = min(rates.min, rate);
37 rates.max = max(rates.max, rate);
38 }
39
40 return snd_interval_refine(r, &rates);
41}
42
43static int dice_channels_constraint(struct snd_pcm_hw_params *params,
44 struct snd_pcm_hw_rule *rule)
45{
46 struct snd_dice *dice = rule->private;
47
48 const struct snd_interval *r =
49 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
50 struct snd_interval *c =
51 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
52 struct snd_interval channels = {
53 .min = UINT_MAX, .max = 0, .integer = 1
54 };
55 unsigned int i, rate, mode, *pcm_channels = dice->rx_channels;
56
57 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
58 rate = snd_dice_rates[i];
59 if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
60 continue;
61
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);
70}
71
72static int dice_open(struct snd_pcm_substream *substream)
73{
74 static const struct snd_pcm_hardware hardware = {
75 .info = SNDRV_PCM_INFO_MMAP |
76 SNDRV_PCM_INFO_MMAP_VALID |
77 SNDRV_PCM_INFO_BATCH |
78 SNDRV_PCM_INFO_INTERLEAVED |
79 SNDRV_PCM_INFO_BLOCK_TRANSFER,
80 .formats = AMDTP_OUT_PCM_FORMAT_BITS,
81 .channels_min = UINT_MAX,
82 .channels_max = 0,
83 .buffer_bytes_max = 16 * 1024 * 1024,
84 .period_bytes_min = 1,
85 .period_bytes_max = UINT_MAX,
86 .periods_min = 1,
87 .periods_max = UINT_MAX,
88 };
89 struct snd_dice *dice = substream->private_data;
90 struct snd_pcm_runtime *runtime = substream->runtime;
91 unsigned int i;
92 int err;
93
94 err = snd_dice_stream_lock_try(dice);
95 if (err < 0)
96 goto error;
97
98 runtime->hw = hardware;
99
100 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i)
101 if (dice->clock_caps & (1 << i))
102 runtime->hw.rates |=
103 snd_pcm_rate_to_rate_bit(snd_dice_rates[i]);
104 snd_pcm_limit_hw_rates(runtime);
105
106 for (i = 0; i < 3; ++i)
107 if (dice->rx_channels[i]) {
108 runtime->hw.channels_min = min(runtime->hw.channels_min,
109 dice->rx_channels[i]);
110 runtime->hw.channels_max = max(runtime->hw.channels_max,
111 dice->rx_channels[i]);
112 }
113
114 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
115 dice_rate_constraint, dice,
116 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
117 if (err < 0)
118 goto err_lock;
119 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
120 dice_channels_constraint, dice,
121 SNDRV_PCM_HW_PARAM_RATE, -1);
122 if (err < 0)
123 goto err_lock;
124
125 err = amdtp_stream_add_pcm_hw_constraints(&dice->rx_stream, runtime);
126 if (err < 0)
127 goto err_lock;
128
129 return 0;
130
131err_lock:
132 snd_dice_stream_lock_release(dice);
133error:
134 return err;
135}
136
137static int dice_close(struct snd_pcm_substream *substream)
138{
139 struct snd_dice *dice = substream->private_data;
140
141 snd_dice_stream_lock_release(dice);
142
143 return 0;
144}
145
146static int dice_hw_params(struct snd_pcm_substream *substream,
147 struct snd_pcm_hw_params *hw_params)
148{
149 struct snd_dice *dice = substream->private_data;
150 unsigned int mode, rate, channels, i;
151 int err;
152
153 mutex_lock(&dice->mutex);
154 snd_dice_stream_stop(dice);
155 mutex_unlock(&dice->mutex);
156
157 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
158 params_buffer_bytes(hw_params));
159 if (err < 0)
160 return err;
161
162 rate = params_rate(hw_params);
163 err = snd_dice_transaction_set_rate(dice, rate);
164 if (err < 0)
165 return err;
166
167 err = snd_dice_stream_get_rate_mode(dice, rate, &mode);
168 if (err < 0)
169 return err;
170
171 /*
172 * At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in
173 * one data block of AMDTP packet. Thus sampling transfer frequency is
174 * a half of PCM sampling frequency, i.e. PCM frames at 192.0 kHz are
175 * transferred on AMDTP packets at 96 kHz. Two successive samples of a
176 * channel are stored consecutively in the packet. This quirk is called
177 * as 'Dual Wire'.
178 * For this quirk, blocking mode is required and PCM buffer size should
179 * be aligned to SYT_INTERVAL.
180 */
181 channels = params_channels(hw_params);
182 if (mode > 1) {
183 if (channels > AMDTP_MAX_CHANNELS_FOR_PCM / 2) {
184 err = -ENOSYS;
185 return err;
186 }
187
188 rate /= 2;
189 channels *= 2;
190 dice->rx_stream.double_pcm_frames = true;
191 } else {
192 dice->rx_stream.double_pcm_frames = false;
193 }
194
195 amdtp_stream_set_parameters(&dice->rx_stream, rate, channels,
196 dice->rx_midi_ports[mode]);
197 if (mode > 4) {
198 channels /= 2;
199
200 for (i = 0; i < channels; i++) {
201 dice->rx_stream.pcm_positions[i] = i * 2;
202 dice->rx_stream.pcm_positions[i + channels] = i * 2 + 1;
203 }
204 }
205
206 amdtp_stream_set_pcm_format(&dice->rx_stream,
207 params_format(hw_params));
208
209 return 0;
210}
211
212static int dice_hw_free(struct snd_pcm_substream *substream)
213{
214 struct snd_dice *dice = substream->private_data;
215
216 mutex_lock(&dice->mutex);
217 snd_dice_stream_stop(dice);
218 mutex_unlock(&dice->mutex);
219
220 return snd_pcm_lib_free_vmalloc_buffer(substream);
221}
222
223static int dice_prepare(struct snd_pcm_substream *substream)
224{
225 struct snd_dice *dice = substream->private_data;
226 int err;
227
228 mutex_lock(&dice->mutex);
229
230 if (amdtp_streaming_error(&dice->rx_stream))
231 snd_dice_stream_stop_packets(dice);
232
233 err = snd_dice_stream_start(dice);
234 if (err < 0) {
235 mutex_unlock(&dice->mutex);
236 return err;
237 }
238
239 mutex_unlock(&dice->mutex);
240
241 amdtp_stream_pcm_prepare(&dice->rx_stream);
242
243 return 0;
244}
245
246static int dice_trigger(struct snd_pcm_substream *substream, int cmd)
247{
248 struct snd_dice *dice = substream->private_data;
249 struct snd_pcm_substream *pcm;
250
251 switch (cmd) {
252 case SNDRV_PCM_TRIGGER_START:
253 pcm = substream;
254 break;
255 case SNDRV_PCM_TRIGGER_STOP:
256 pcm = NULL;
257 break;
258 default:
259 return -EINVAL;
260 }
261 amdtp_stream_pcm_trigger(&dice->rx_stream, pcm);
262
263 return 0;
264}
265
266static snd_pcm_uframes_t dice_pointer(struct snd_pcm_substream *substream)
267{
268 struct snd_dice *dice = substream->private_data;
269
270 return amdtp_stream_pcm_pointer(&dice->rx_stream);
271}
272
273static int dice_create_pcm(struct snd_dice *dice)
274{
275 static struct snd_pcm_ops ops = {
276 .open = dice_open,
277 .close = dice_close,
278 .ioctl = snd_pcm_lib_ioctl,
279 .hw_params = dice_hw_params,
280 .hw_free = dice_hw_free,
281 .prepare = dice_prepare,
282 .trigger = dice_trigger,
283 .pointer = dice_pointer,
284 .page = snd_pcm_lib_get_vmalloc_page,
285 .mmap = snd_pcm_lib_mmap_vmalloc,
286 };
287 struct snd_pcm *pcm;
288 int err;
289
290 err = snd_pcm_new(dice->card, "DICE", 0, 1, 0, &pcm);
291 if (err < 0)
292 return err;
293 pcm->private_data = dice;
294 strcpy(pcm->name, dice->card->shortname);
295 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->ops = &ops;
296
297 return 0;
298}
299
300static long dice_hwdep_read(struct snd_hwdep *hwdep, char __user *buf, 14static long dice_hwdep_read(struct snd_hwdep *hwdep, char __user *buf,
301 long count, loff_t *offset) 15 long count, loff_t *offset)
302{ 16{
@@ -978,7 +692,7 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
978 692
979 dice_card_strings(dice); 693 dice_card_strings(dice);
980 694
981 err = dice_create_pcm(dice); 695 err = snd_dice_create_pcm(dice);
982 if (err < 0) 696 if (err < 0)
983 goto error; 697 goto error;
984 698
diff --git a/sound/firewire/dice/dice.h b/sound/firewire/dice/dice.h
index ca4090d881e6..4d9e55ba895b 100644
--- a/sound/firewire/dice/dice.h
+++ b/sound/firewire/dice/dice.h
@@ -171,4 +171,6 @@ void snd_dice_stream_update(struct snd_dice *dice);
171int snd_dice_stream_lock_try(struct snd_dice *dice); 171int snd_dice_stream_lock_try(struct snd_dice *dice);
172void snd_dice_stream_lock_release(struct snd_dice *dice); 172void snd_dice_stream_lock_release(struct snd_dice *dice);
173 173
174int snd_dice_create_pcm(struct snd_dice *dice);
175
174#endif 176#endif