diff options
author | Takashi Iwai <tiwai@suse.de> | 2015-01-23 10:10:57 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-01-28 01:21:18 -0500 |
commit | ad0119abe29fe3d506486a789de4c4619fa7602c (patch) | |
tree | ebbb5c893a11998437fba5bbfd0b22a63f70fe71 /sound/usb/line6 | |
parent | ab5cdcbab2efb833b4c199d0b0a6603af080eaa2 (diff) |
ALSA: line6: Rearrange PCM structure
Introduce a new line6_pcm_stream structure and group individual
fields of snd_line6_pcm struct to playback and capture groups.
This patch itself just does rename and nothing else. More
meaningful cleanups based on these fields shuffling will follow.
Tested-by: Chris Rorvick <chris@rorvick.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/line6')
-rw-r--r-- | sound/usb/line6/capture.c | 64 | ||||
-rw-r--r-- | sound/usb/line6/pcm.c | 50 | ||||
-rw-r--r-- | sound/usb/line6/pcm.h | 158 | ||||
-rw-r--r-- | sound/usb/line6/playback.c | 78 |
4 files changed, 142 insertions, 208 deletions
diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c index bad1b5b02786..439f1941eb56 100644 --- a/sound/usb/line6/capture.c +++ b/sound/usb/line6/capture.c | |||
@@ -29,17 +29,17 @@ static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm) | |||
29 | int ret; | 29 | int ret; |
30 | struct urb *urb_in; | 30 | struct urb *urb_in; |
31 | 31 | ||
32 | spin_lock_irqsave(&line6pcm->lock_audio_in, flags); | 32 | spin_lock_irqsave(&line6pcm->in.lock, flags); |
33 | index = | 33 | index = |
34 | find_first_zero_bit(&line6pcm->active_urb_in, LINE6_ISO_BUFFERS); | 34 | find_first_zero_bit(&line6pcm->in.active_urbs, LINE6_ISO_BUFFERS); |
35 | 35 | ||
36 | if (index < 0 || index >= LINE6_ISO_BUFFERS) { | 36 | if (index < 0 || index >= LINE6_ISO_BUFFERS) { |
37 | spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags); | 37 | spin_unlock_irqrestore(&line6pcm->in.lock, flags); |
38 | dev_err(line6pcm->line6->ifcdev, "no free URB found\n"); | 38 | dev_err(line6pcm->line6->ifcdev, "no free URB found\n"); |
39 | return -EINVAL; | 39 | return -EINVAL; |
40 | } | 40 | } |
41 | 41 | ||
42 | urb_in = line6pcm->urb_audio_in[index]; | 42 | urb_in = line6pcm->in.urbs[index]; |
43 | urb_size = 0; | 43 | urb_size = 0; |
44 | 44 | ||
45 | for (i = 0; i < LINE6_ISO_PACKETS; ++i) { | 45 | for (i = 0; i < LINE6_ISO_PACKETS; ++i) { |
@@ -51,7 +51,7 @@ static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm) | |||
51 | } | 51 | } |
52 | 52 | ||
53 | urb_in->transfer_buffer = | 53 | urb_in->transfer_buffer = |
54 | line6pcm->buffer_in + | 54 | line6pcm->in.buffer + |
55 | index * LINE6_ISO_PACKETS * line6pcm->max_packet_size; | 55 | index * LINE6_ISO_PACKETS * line6pcm->max_packet_size; |
56 | urb_in->transfer_buffer_length = urb_size; | 56 | urb_in->transfer_buffer_length = urb_size; |
57 | urb_in->context = line6pcm; | 57 | urb_in->context = line6pcm; |
@@ -59,12 +59,12 @@ static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm) | |||
59 | ret = usb_submit_urb(urb_in, GFP_ATOMIC); | 59 | ret = usb_submit_urb(urb_in, GFP_ATOMIC); |
60 | 60 | ||
61 | if (ret == 0) | 61 | if (ret == 0) |
62 | set_bit(index, &line6pcm->active_urb_in); | 62 | set_bit(index, &line6pcm->in.active_urbs); |
63 | else | 63 | else |
64 | dev_err(line6pcm->line6->ifcdev, | 64 | dev_err(line6pcm->line6->ifcdev, |
65 | "URB in #%d submission failed (%d)\n", index, ret); | 65 | "URB in #%d submission failed (%d)\n", index, ret); |
66 | 66 | ||
67 | spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags); | 67 | spin_unlock_irqrestore(&line6pcm->in.lock, flags); |
68 | return 0; | 68 | return 0; |
69 | } | 69 | } |
70 | 70 | ||
@@ -92,9 +92,9 @@ void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm) | |||
92 | unsigned int i; | 92 | unsigned int i; |
93 | 93 | ||
94 | for (i = 0; i < LINE6_ISO_BUFFERS; i++) { | 94 | for (i = 0; i < LINE6_ISO_BUFFERS; i++) { |
95 | if (test_bit(i, &line6pcm->active_urb_in)) { | 95 | if (test_bit(i, &line6pcm->in.active_urbs)) { |
96 | if (!test_and_set_bit(i, &line6pcm->unlink_urb_in)) { | 96 | if (!test_and_set_bit(i, &line6pcm->in.unlink_urbs)) { |
97 | struct urb *u = line6pcm->urb_audio_in[i]; | 97 | struct urb *u = line6pcm->in.urbs[i]; |
98 | 98 | ||
99 | usb_unlink_urb(u); | 99 | usb_unlink_urb(u); |
100 | } | 100 | } |
@@ -115,7 +115,7 @@ void line6_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm) | |||
115 | do { | 115 | do { |
116 | alive = 0; | 116 | alive = 0; |
117 | for (i = 0; i < LINE6_ISO_BUFFERS; i++) { | 117 | for (i = 0; i < LINE6_ISO_BUFFERS; i++) { |
118 | if (test_bit(i, &line6pcm->active_urb_in)) | 118 | if (test_bit(i, &line6pcm->in.active_urbs)) |
119 | alive++; | 119 | alive++; |
120 | } | 120 | } |
121 | if (!alive) | 121 | if (!alive) |
@@ -150,18 +150,18 @@ void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, int fsize) | |||
150 | if (runtime == NULL) | 150 | if (runtime == NULL) |
151 | return; | 151 | return; |
152 | 152 | ||
153 | if (line6pcm->pos_in_done + frames > runtime->buffer_size) { | 153 | if (line6pcm->in.pos_done + frames > runtime->buffer_size) { |
154 | /* | 154 | /* |
155 | The transferred area goes over buffer boundary, | 155 | The transferred area goes over buffer boundary, |
156 | copy two separate chunks. | 156 | copy two separate chunks. |
157 | */ | 157 | */ |
158 | int len; | 158 | int len; |
159 | 159 | ||
160 | len = runtime->buffer_size - line6pcm->pos_in_done; | 160 | len = runtime->buffer_size - line6pcm->in.pos_done; |
161 | 161 | ||
162 | if (len > 0) { | 162 | if (len > 0) { |
163 | memcpy(runtime->dma_area + | 163 | memcpy(runtime->dma_area + |
164 | line6pcm->pos_in_done * bytes_per_frame, fbuf, | 164 | line6pcm->in.pos_done * bytes_per_frame, fbuf, |
165 | len * bytes_per_frame); | 165 | len * bytes_per_frame); |
166 | memcpy(runtime->dma_area, fbuf + len * bytes_per_frame, | 166 | memcpy(runtime->dma_area, fbuf + len * bytes_per_frame, |
167 | (frames - len) * bytes_per_frame); | 167 | (frames - len) * bytes_per_frame); |
@@ -173,12 +173,12 @@ void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, int fsize) | |||
173 | } else { | 173 | } else { |
174 | /* copy single chunk */ | 174 | /* copy single chunk */ |
175 | memcpy(runtime->dma_area + | 175 | memcpy(runtime->dma_area + |
176 | line6pcm->pos_in_done * bytes_per_frame, fbuf, fsize); | 176 | line6pcm->in.pos_done * bytes_per_frame, fbuf, fsize); |
177 | } | 177 | } |
178 | 178 | ||
179 | line6pcm->pos_in_done += frames; | 179 | line6pcm->in.pos_done += frames; |
180 | if (line6pcm->pos_in_done >= runtime->buffer_size) | 180 | if (line6pcm->in.pos_done >= runtime->buffer_size) |
181 | line6pcm->pos_in_done -= runtime->buffer_size; | 181 | line6pcm->in.pos_done -= runtime->buffer_size; |
182 | } | 182 | } |
183 | 183 | ||
184 | void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length) | 184 | void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length) |
@@ -186,17 +186,17 @@ void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length) | |||
186 | struct snd_pcm_substream *substream = | 186 | struct snd_pcm_substream *substream = |
187 | get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE); | 187 | get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE); |
188 | 188 | ||
189 | line6pcm->bytes_in += length; | 189 | line6pcm->in.bytes += length; |
190 | if (line6pcm->bytes_in >= line6pcm->period_in) { | 190 | if (line6pcm->in.bytes >= line6pcm->in.period) { |
191 | line6pcm->bytes_in %= line6pcm->period_in; | 191 | line6pcm->in.bytes %= line6pcm->in.period; |
192 | snd_pcm_period_elapsed(substream); | 192 | snd_pcm_period_elapsed(substream); |
193 | } | 193 | } |
194 | } | 194 | } |
195 | 195 | ||
196 | void line6_free_capture_buffer(struct snd_line6_pcm *line6pcm) | 196 | void line6_free_capture_buffer(struct snd_line6_pcm *line6pcm) |
197 | { | 197 | { |
198 | kfree(line6pcm->buffer_in); | 198 | kfree(line6pcm->in.buffer); |
199 | line6pcm->buffer_in = NULL; | 199 | line6pcm->in.buffer = NULL; |
200 | } | 200 | } |
201 | 201 | ||
202 | /* | 202 | /* |
@@ -209,14 +209,14 @@ static void audio_in_callback(struct urb *urb) | |||
209 | 209 | ||
210 | struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context; | 210 | struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context; |
211 | 211 | ||
212 | line6pcm->last_frame_in = urb->start_frame; | 212 | line6pcm->in.last_frame = urb->start_frame; |
213 | 213 | ||
214 | /* find index of URB */ | 214 | /* find index of URB */ |
215 | for (index = 0; index < LINE6_ISO_BUFFERS; ++index) | 215 | for (index = 0; index < LINE6_ISO_BUFFERS; ++index) |
216 | if (urb == line6pcm->urb_audio_in[index]) | 216 | if (urb == line6pcm->in.urbs[index]) |
217 | break; | 217 | break; |
218 | 218 | ||
219 | spin_lock_irqsave(&line6pcm->lock_audio_in, flags); | 219 | spin_lock_irqsave(&line6pcm->in.lock, flags); |
220 | 220 | ||
221 | for (i = 0; i < LINE6_ISO_PACKETS; ++i) { | 221 | for (i = 0; i < LINE6_ISO_PACKETS; ++i) { |
222 | char *fbuf; | 222 | char *fbuf; |
@@ -249,12 +249,12 @@ static void audio_in_callback(struct urb *urb) | |||
249 | line6_capture_copy(line6pcm, fbuf, fsize); | 249 | line6_capture_copy(line6pcm, fbuf, fsize); |
250 | } | 250 | } |
251 | 251 | ||
252 | clear_bit(index, &line6pcm->active_urb_in); | 252 | clear_bit(index, &line6pcm->in.active_urbs); |
253 | 253 | ||
254 | if (test_and_clear_bit(index, &line6pcm->unlink_urb_in)) | 254 | if (test_and_clear_bit(index, &line6pcm->in.unlink_urbs)) |
255 | shutdown = 1; | 255 | shutdown = 1; |
256 | 256 | ||
257 | spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags); | 257 | spin_unlock_irqrestore(&line6pcm->in.lock, flags); |
258 | 258 | ||
259 | if (!shutdown) { | 259 | if (!shutdown) { |
260 | submit_audio_in_urb(line6pcm); | 260 | submit_audio_in_urb(line6pcm); |
@@ -309,7 +309,7 @@ static int snd_line6_capture_hw_params(struct snd_pcm_substream *substream, | |||
309 | return ret; | 309 | return ret; |
310 | } | 310 | } |
311 | 311 | ||
312 | line6pcm->period_in = params_period_bytes(hw_params); | 312 | line6pcm->in.period = params_period_bytes(hw_params); |
313 | return 0; | 313 | return 0; |
314 | } | 314 | } |
315 | 315 | ||
@@ -361,7 +361,7 @@ snd_line6_capture_pointer(struct snd_pcm_substream *substream) | |||
361 | { | 361 | { |
362 | struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); | 362 | struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); |
363 | 363 | ||
364 | return line6pcm->pos_in_done; | 364 | return line6pcm->in.pos_done; |
365 | } | 365 | } |
366 | 366 | ||
367 | /* capture operators */ | 367 | /* capture operators */ |
@@ -386,7 +386,7 @@ int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm) | |||
386 | struct urb *urb; | 386 | struct urb *urb; |
387 | 387 | ||
388 | /* URB for audio in: */ | 388 | /* URB for audio in: */ |
389 | urb = line6pcm->urb_audio_in[i] = | 389 | urb = line6pcm->in.urbs[i] = |
390 | usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL); | 390 | usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL); |
391 | 391 | ||
392 | if (urb == NULL) | 392 | if (urb == NULL) |
diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c index 43474c4ebb6b..738bfd82cecd 100644 --- a/sound/usb/line6/pcm.c +++ b/sound/usb/line6/pcm.c | |||
@@ -112,11 +112,11 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels) | |||
112 | 112 | ||
113 | if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_BUFFER)) { | 113 | if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_BUFFER)) { |
114 | /* Invoked multiple times in a row so allocate once only */ | 114 | /* Invoked multiple times in a row so allocate once only */ |
115 | if (!line6pcm->buffer_in) { | 115 | if (!line6pcm->in.buffer) { |
116 | line6pcm->buffer_in = | 116 | line6pcm->in.buffer = |
117 | kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * | 117 | kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * |
118 | line6pcm->max_packet_size, GFP_KERNEL); | 118 | line6pcm->max_packet_size, GFP_KERNEL); |
119 | if (!line6pcm->buffer_in) { | 119 | if (!line6pcm->in.buffer) { |
120 | err = -ENOMEM; | 120 | err = -ENOMEM; |
121 | goto pcm_acquire_error; | 121 | goto pcm_acquire_error; |
122 | } | 122 | } |
@@ -131,13 +131,13 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels) | |||
131 | a bug, we therefore report an error if capturing is restarted | 131 | a bug, we therefore report an error if capturing is restarted |
132 | too soon. | 132 | too soon. |
133 | */ | 133 | */ |
134 | if (line6pcm->active_urb_in || line6pcm->unlink_urb_in) { | 134 | if (line6pcm->in.active_urbs || line6pcm->in.unlink_urbs) { |
135 | dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n"); | 135 | dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n"); |
136 | err = -EBUSY; | 136 | err = -EBUSY; |
137 | goto pcm_acquire_error; | 137 | goto pcm_acquire_error; |
138 | } | 138 | } |
139 | 139 | ||
140 | line6pcm->count_in = 0; | 140 | line6pcm->in.count = 0; |
141 | line6pcm->prev_fsize = 0; | 141 | line6pcm->prev_fsize = 0; |
142 | err = line6_submit_audio_in_all_urbs(line6pcm); | 142 | err = line6_submit_audio_in_all_urbs(line6pcm); |
143 | 143 | ||
@@ -149,11 +149,11 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels) | |||
149 | 149 | ||
150 | if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_BUFFER)) { | 150 | if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_BUFFER)) { |
151 | /* Invoked multiple times in a row so allocate once only */ | 151 | /* Invoked multiple times in a row so allocate once only */ |
152 | if (!line6pcm->buffer_out) { | 152 | if (!line6pcm->out.buffer) { |
153 | line6pcm->buffer_out = | 153 | line6pcm->out.buffer = |
154 | kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * | 154 | kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * |
155 | line6pcm->max_packet_size, GFP_KERNEL); | 155 | line6pcm->max_packet_size, GFP_KERNEL); |
156 | if (!line6pcm->buffer_out) { | 156 | if (!line6pcm->out.buffer) { |
157 | err = -ENOMEM; | 157 | err = -ENOMEM; |
158 | goto pcm_acquire_error; | 158 | goto pcm_acquire_error; |
159 | } | 159 | } |
@@ -166,12 +166,12 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels) | |||
166 | /* | 166 | /* |
167 | See comment above regarding PCM restart. | 167 | See comment above regarding PCM restart. |
168 | */ | 168 | */ |
169 | if (line6pcm->active_urb_out || line6pcm->unlink_urb_out) { | 169 | if (line6pcm->out.active_urbs || line6pcm->out.unlink_urbs) { |
170 | dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n"); | 170 | dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n"); |
171 | return -EBUSY; | 171 | return -EBUSY; |
172 | } | 172 | } |
173 | 173 | ||
174 | line6pcm->count_out = 0; | 174 | line6pcm->out.count = 0; |
175 | err = line6_submit_audio_out_all_urbs(line6pcm); | 175 | err = line6_submit_audio_out_all_urbs(line6pcm); |
176 | 176 | ||
177 | if (err < 0) | 177 | if (err < 0) |
@@ -331,13 +331,13 @@ static void line6_cleanup_pcm(struct snd_pcm *pcm) | |||
331 | struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm); | 331 | struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm); |
332 | 332 | ||
333 | for (i = 0; i < LINE6_ISO_BUFFERS; i++) { | 333 | for (i = 0; i < LINE6_ISO_BUFFERS; i++) { |
334 | if (line6pcm->urb_audio_out[i]) { | 334 | if (line6pcm->out.urbs[i]) { |
335 | usb_kill_urb(line6pcm->urb_audio_out[i]); | 335 | usb_kill_urb(line6pcm->out.urbs[i]); |
336 | usb_free_urb(line6pcm->urb_audio_out[i]); | 336 | usb_free_urb(line6pcm->out.urbs[i]); |
337 | } | 337 | } |
338 | if (line6pcm->urb_audio_in[i]) { | 338 | if (line6pcm->in.urbs[i]) { |
339 | usb_kill_urb(line6pcm->urb_audio_in[i]); | 339 | usb_kill_urb(line6pcm->in.urbs[i]); |
340 | usb_free_urb(line6pcm->urb_audio_in[i]); | 340 | usb_free_urb(line6pcm->in.urbs[i]); |
341 | } | 341 | } |
342 | } | 342 | } |
343 | kfree(line6pcm); | 343 | kfree(line6pcm); |
@@ -415,8 +415,8 @@ int line6_init_pcm(struct usb_line6 *line6, | |||
415 | usb_maxpacket(line6->usbdev, | 415 | usb_maxpacket(line6->usbdev, |
416 | usb_sndisocpipe(line6->usbdev, ep_write), 1)); | 416 | usb_sndisocpipe(line6->usbdev, ep_write), 1)); |
417 | 417 | ||
418 | spin_lock_init(&line6pcm->lock_audio_out); | 418 | spin_lock_init(&line6pcm->out.lock); |
419 | spin_lock_init(&line6pcm->lock_audio_in); | 419 | spin_lock_init(&line6pcm->in.lock); |
420 | line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD; | 420 | line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD; |
421 | 421 | ||
422 | line6->line6pcm = line6pcm; | 422 | line6->line6pcm = line6pcm; |
@@ -464,13 +464,13 @@ int snd_line6_prepare(struct snd_pcm_substream *substream) | |||
464 | } | 464 | } |
465 | 465 | ||
466 | if (!test_and_set_bit(LINE6_INDEX_PREPARED, &line6pcm->flags)) { | 466 | if (!test_and_set_bit(LINE6_INDEX_PREPARED, &line6pcm->flags)) { |
467 | line6pcm->count_out = 0; | 467 | line6pcm->out.count = 0; |
468 | line6pcm->pos_out = 0; | 468 | line6pcm->out.pos = 0; |
469 | line6pcm->pos_out_done = 0; | 469 | line6pcm->out.pos_done = 0; |
470 | line6pcm->bytes_out = 0; | 470 | line6pcm->out.bytes = 0; |
471 | line6pcm->count_in = 0; | 471 | line6pcm->in.count = 0; |
472 | line6pcm->pos_in_done = 0; | 472 | line6pcm->in.pos_done = 0; |
473 | line6pcm->bytes_in = 0; | 473 | line6pcm->in.bytes = 0; |
474 | } | 474 | } |
475 | 475 | ||
476 | return 0; | 476 | return 0; |
diff --git a/sound/usb/line6/pcm.h b/sound/usb/line6/pcm.h index a84753ee0fa2..4c74f4e85074 100644 --- a/sound/usb/line6/pcm.h +++ b/sound/usb/line6/pcm.h | |||
@@ -165,115 +165,78 @@ struct line6_pcm_properties { | |||
165 | int bytes_per_frame; | 165 | int bytes_per_frame; |
166 | }; | 166 | }; |
167 | 167 | ||
168 | struct snd_line6_pcm { | 168 | struct line6_pcm_stream { |
169 | /** | 169 | /* allocated URBs */ |
170 | Pointer back to the Line 6 driver data structure. | 170 | struct urb *urbs[LINE6_ISO_BUFFERS]; |
171 | */ | ||
172 | struct usb_line6 *line6; | ||
173 | 171 | ||
174 | /** | 172 | /* Temporary buffer; |
175 | Properties. | 173 | * Since the packet size is not known in advance, this buffer is |
176 | */ | 174 | * large enough to store maximum size packets. |
177 | struct line6_pcm_properties *properties; | 175 | */ |
176 | unsigned char *buffer; | ||
178 | 177 | ||
179 | /** | 178 | /* Free frame position in the buffer. */ |
180 | ALSA pcm stream | 179 | snd_pcm_uframes_t pos; |
181 | */ | ||
182 | struct snd_pcm *pcm; | ||
183 | 180 | ||
184 | /** | 181 | /* Count processed bytes; |
185 | URBs for audio playback. | 182 | * This is modulo period size (to determine when a period is finished). |
186 | */ | 183 | */ |
187 | struct urb *urb_audio_out[LINE6_ISO_BUFFERS]; | 184 | unsigned bytes; |
188 | 185 | ||
189 | /** | 186 | /* Counter to create desired sample rate */ |
190 | URBs for audio capture. | 187 | unsigned count; |
191 | */ | ||
192 | struct urb *urb_audio_in[LINE6_ISO_BUFFERS]; | ||
193 | 188 | ||
194 | /** | 189 | /* period size in bytes */ |
195 | Temporary buffer for playback. | 190 | unsigned period; |
196 | Since the packet size is not known in advance, this buffer is | ||
197 | large enough to store maximum size packets. | ||
198 | */ | ||
199 | unsigned char *buffer_out; | ||
200 | 191 | ||
201 | /** | 192 | /* Processed frame position in the buffer; |
202 | Temporary buffer for capture. | 193 | * The contents of the ring buffer have been consumed by the USB |
203 | Since the packet size is not known in advance, this buffer is | 194 | * subsystem (i.e., sent to the USB device) up to this position. |
204 | large enough to store maximum size packets. | 195 | */ |
205 | */ | 196 | snd_pcm_uframes_t pos_done; |
206 | unsigned char *buffer_in; | ||
207 | 197 | ||
208 | /** | 198 | /* Bit mask of active URBs */ |
209 | Previously captured frame (for software monitoring). | 199 | unsigned long active_urbs; |
210 | */ | ||
211 | unsigned char *prev_fbuf; | ||
212 | 200 | ||
213 | /** | 201 | /* Bit mask of URBs currently being unlinked */ |
214 | Size of previously captured frame (for software monitoring). | 202 | unsigned long unlink_urbs; |
215 | */ | ||
216 | int prev_fsize; | ||
217 | |||
218 | /** | ||
219 | Free frame position in the playback buffer. | ||
220 | */ | ||
221 | snd_pcm_uframes_t pos_out; | ||
222 | 203 | ||
223 | /** | 204 | /* Spin lock to protect updates of the buffer positions (not contents) |
224 | Count processed bytes for playback. | 205 | */ |
225 | This is modulo period size (to determine when a period is | 206 | spinlock_t lock; |
226 | finished). | ||
227 | */ | ||
228 | unsigned bytes_out; | ||
229 | 207 | ||
230 | /** | 208 | int last_frame; |
231 | Counter to create desired playback sample rate. | 209 | }; |
232 | */ | ||
233 | unsigned count_out; | ||
234 | |||
235 | /** | ||
236 | Playback period size in bytes | ||
237 | */ | ||
238 | unsigned period_out; | ||
239 | 210 | ||
211 | struct snd_line6_pcm { | ||
240 | /** | 212 | /** |
241 | Processed frame position in the playback buffer. | 213 | Pointer back to the Line 6 driver data structure. |
242 | The contents of the output ring buffer have been consumed by | ||
243 | the USB subsystem (i.e., sent to the USB device) up to this | ||
244 | position. | ||
245 | */ | 214 | */ |
246 | snd_pcm_uframes_t pos_out_done; | 215 | struct usb_line6 *line6; |
247 | 216 | ||
248 | /** | 217 | /** |
249 | Count processed bytes for capture. | 218 | Properties. |
250 | This is modulo period size (to determine when a period is | ||
251 | finished). | ||
252 | */ | 219 | */ |
253 | unsigned bytes_in; | 220 | struct line6_pcm_properties *properties; |
254 | 221 | ||
255 | /** | 222 | /** |
256 | Counter to create desired capture sample rate. | 223 | ALSA pcm stream |
257 | */ | 224 | */ |
258 | unsigned count_in; | 225 | struct snd_pcm *pcm; |
259 | 226 | ||
260 | /** | 227 | /* Capture and playback streams */ |
261 | Capture period size in bytes | 228 | struct line6_pcm_stream in; |
262 | */ | 229 | struct line6_pcm_stream out; |
263 | unsigned period_in; | ||
264 | 230 | ||
265 | /** | 231 | /** |
266 | Processed frame position in the capture buffer. | 232 | Previously captured frame (for software monitoring). |
267 | The contents of the output ring buffer have been consumed by | ||
268 | the USB subsystem (i.e., sent to the USB device) up to this | ||
269 | position. | ||
270 | */ | 233 | */ |
271 | snd_pcm_uframes_t pos_in_done; | 234 | unsigned char *prev_fbuf; |
272 | 235 | ||
273 | /** | 236 | /** |
274 | Bit mask of active playback URBs. | 237 | Size of previously captured frame (for software monitoring). |
275 | */ | 238 | */ |
276 | unsigned long active_urb_out; | 239 | int prev_fsize; |
277 | 240 | ||
278 | /** | 241 | /** |
279 | Maximum size of USB packet. | 242 | Maximum size of USB packet. |
@@ -281,33 +244,6 @@ struct snd_line6_pcm { | |||
281 | int max_packet_size; | 244 | int max_packet_size; |
282 | 245 | ||
283 | /** | 246 | /** |
284 | Bit mask of active capture URBs. | ||
285 | */ | ||
286 | unsigned long active_urb_in; | ||
287 | |||
288 | /** | ||
289 | Bit mask of playback URBs currently being unlinked. | ||
290 | */ | ||
291 | unsigned long unlink_urb_out; | ||
292 | |||
293 | /** | ||
294 | Bit mask of capture URBs currently being unlinked. | ||
295 | */ | ||
296 | unsigned long unlink_urb_in; | ||
297 | |||
298 | /** | ||
299 | Spin lock to protect updates of the playback buffer positions (not | ||
300 | contents!) | ||
301 | */ | ||
302 | spinlock_t lock_audio_out; | ||
303 | |||
304 | /** | ||
305 | Spin lock to protect updates of the capture buffer positions (not | ||
306 | contents!) | ||
307 | */ | ||
308 | spinlock_t lock_audio_in; | ||
309 | |||
310 | /** | ||
311 | PCM playback volume (left and right). | 247 | PCM playback volume (left and right). |
312 | */ | 248 | */ |
313 | int volume_playback[2]; | 249 | int volume_playback[2]; |
@@ -336,8 +272,6 @@ struct snd_line6_pcm { | |||
336 | Several status bits (see LINE6_BIT_*). | 272 | Several status bits (see LINE6_BIT_*). |
337 | */ | 273 | */ |
338 | unsigned long flags; | 274 | unsigned long flags; |
339 | |||
340 | int last_frame_in, last_frame_out; | ||
341 | }; | 275 | }; |
342 | 276 | ||
343 | extern int line6_init_pcm(struct usb_line6 *line6, | 277 | extern int line6_init_pcm(struct usb_line6 *line6, |
diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c index 7e031b1761aa..d619c1718306 100644 --- a/sound/usb/line6/playback.c +++ b/sound/usb/line6/playback.c | |||
@@ -145,17 +145,17 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) | |||
145 | (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL); | 145 | (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL); |
146 | struct urb *urb_out; | 146 | struct urb *urb_out; |
147 | 147 | ||
148 | spin_lock_irqsave(&line6pcm->lock_audio_out, flags); | 148 | spin_lock_irqsave(&line6pcm->out.lock, flags); |
149 | index = | 149 | index = |
150 | find_first_zero_bit(&line6pcm->active_urb_out, LINE6_ISO_BUFFERS); | 150 | find_first_zero_bit(&line6pcm->out.active_urbs, LINE6_ISO_BUFFERS); |
151 | 151 | ||
152 | if (index < 0 || index >= LINE6_ISO_BUFFERS) { | 152 | if (index < 0 || index >= LINE6_ISO_BUFFERS) { |
153 | spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags); | 153 | spin_unlock_irqrestore(&line6pcm->out.lock, flags); |
154 | dev_err(line6pcm->line6->ifcdev, "no free URB found\n"); | 154 | dev_err(line6pcm->line6->ifcdev, "no free URB found\n"); |
155 | return -EINVAL; | 155 | return -EINVAL; |
156 | } | 156 | } |
157 | 157 | ||
158 | urb_out = line6pcm->urb_audio_out[index]; | 158 | urb_out = line6pcm->out.urbs[index]; |
159 | urb_size = 0; | 159 | urb_size = 0; |
160 | 160 | ||
161 | for (i = 0; i < LINE6_ISO_PACKETS; ++i) { | 161 | for (i = 0; i < LINE6_ISO_PACKETS; ++i) { |
@@ -170,9 +170,9 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) | |||
170 | if (fsize == 0) { | 170 | if (fsize == 0) { |
171 | int n; | 171 | int n; |
172 | 172 | ||
173 | line6pcm->count_out += frame_increment; | 173 | line6pcm->out.count += frame_increment; |
174 | n = line6pcm->count_out / frame_factor; | 174 | n = line6pcm->out.count / frame_factor; |
175 | line6pcm->count_out -= n * frame_factor; | 175 | line6pcm->out.count -= n * frame_factor; |
176 | fsize = n * bytes_per_frame; | 176 | fsize = n * bytes_per_frame; |
177 | } | 177 | } |
178 | 178 | ||
@@ -183,14 +183,14 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) | |||
183 | 183 | ||
184 | if (urb_size == 0) { | 184 | if (urb_size == 0) { |
185 | /* can't determine URB size */ | 185 | /* can't determine URB size */ |
186 | spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags); | 186 | spin_unlock_irqrestore(&line6pcm->out.lock, flags); |
187 | dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n"); | 187 | dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n"); |
188 | return -EINVAL; | 188 | return -EINVAL; |
189 | } | 189 | } |
190 | 190 | ||
191 | urb_frames = urb_size / bytes_per_frame; | 191 | urb_frames = urb_size / bytes_per_frame; |
192 | urb_out->transfer_buffer = | 192 | urb_out->transfer_buffer = |
193 | line6pcm->buffer_out + | 193 | line6pcm->out.buffer + |
194 | index * LINE6_ISO_PACKETS * line6pcm->max_packet_size; | 194 | index * LINE6_ISO_PACKETS * line6pcm->max_packet_size; |
195 | urb_out->transfer_buffer_length = urb_size; | 195 | urb_out->transfer_buffer_length = urb_size; |
196 | urb_out->context = line6pcm; | 196 | urb_out->context = line6pcm; |
@@ -200,19 +200,19 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) | |||
200 | struct snd_pcm_runtime *runtime = | 200 | struct snd_pcm_runtime *runtime = |
201 | get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK)->runtime; | 201 | get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK)->runtime; |
202 | 202 | ||
203 | if (line6pcm->pos_out + urb_frames > runtime->buffer_size) { | 203 | if (line6pcm->out.pos + urb_frames > runtime->buffer_size) { |
204 | /* | 204 | /* |
205 | The transferred area goes over buffer boundary, | 205 | The transferred area goes over buffer boundary, |
206 | copy the data to the temp buffer. | 206 | copy the data to the temp buffer. |
207 | */ | 207 | */ |
208 | int len; | 208 | int len; |
209 | 209 | ||
210 | len = runtime->buffer_size - line6pcm->pos_out; | 210 | len = runtime->buffer_size - line6pcm->out.pos; |
211 | 211 | ||
212 | if (len > 0) { | 212 | if (len > 0) { |
213 | memcpy(urb_out->transfer_buffer, | 213 | memcpy(urb_out->transfer_buffer, |
214 | runtime->dma_area + | 214 | runtime->dma_area + |
215 | line6pcm->pos_out * bytes_per_frame, | 215 | line6pcm->out.pos * bytes_per_frame, |
216 | len * bytes_per_frame); | 216 | len * bytes_per_frame); |
217 | memcpy(urb_out->transfer_buffer + | 217 | memcpy(urb_out->transfer_buffer + |
218 | len * bytes_per_frame, runtime->dma_area, | 218 | len * bytes_per_frame, runtime->dma_area, |
@@ -223,13 +223,13 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) | |||
223 | } else { | 223 | } else { |
224 | memcpy(urb_out->transfer_buffer, | 224 | memcpy(urb_out->transfer_buffer, |
225 | runtime->dma_area + | 225 | runtime->dma_area + |
226 | line6pcm->pos_out * bytes_per_frame, | 226 | line6pcm->out.pos * bytes_per_frame, |
227 | urb_out->transfer_buffer_length); | 227 | urb_out->transfer_buffer_length); |
228 | } | 228 | } |
229 | 229 | ||
230 | line6pcm->pos_out += urb_frames; | 230 | line6pcm->out.pos += urb_frames; |
231 | if (line6pcm->pos_out >= runtime->buffer_size) | 231 | if (line6pcm->out.pos >= runtime->buffer_size) |
232 | line6pcm->pos_out -= runtime->buffer_size; | 232 | line6pcm->out.pos -= runtime->buffer_size; |
233 | } else { | 233 | } else { |
234 | memset(urb_out->transfer_buffer, 0, | 234 | memset(urb_out->transfer_buffer, 0, |
235 | urb_out->transfer_buffer_length); | 235 | urb_out->transfer_buffer_length); |
@@ -265,12 +265,12 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) | |||
265 | ret = usb_submit_urb(urb_out, GFP_ATOMIC); | 265 | ret = usb_submit_urb(urb_out, GFP_ATOMIC); |
266 | 266 | ||
267 | if (ret == 0) | 267 | if (ret == 0) |
268 | set_bit(index, &line6pcm->active_urb_out); | 268 | set_bit(index, &line6pcm->out.active_urbs); |
269 | else | 269 | else |
270 | dev_err(line6pcm->line6->ifcdev, | 270 | dev_err(line6pcm->line6->ifcdev, |
271 | "URB out #%d submission failed (%d)\n", index, ret); | 271 | "URB out #%d submission failed (%d)\n", index, ret); |
272 | 272 | ||
273 | spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags); | 273 | spin_unlock_irqrestore(&line6pcm->out.lock, flags); |
274 | return 0; | 274 | return 0; |
275 | } | 275 | } |
276 | 276 | ||
@@ -298,9 +298,9 @@ void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm) | |||
298 | unsigned int i; | 298 | unsigned int i; |
299 | 299 | ||
300 | for (i = 0; i < LINE6_ISO_BUFFERS; i++) { | 300 | for (i = 0; i < LINE6_ISO_BUFFERS; i++) { |
301 | if (test_bit(i, &line6pcm->active_urb_out)) { | 301 | if (test_bit(i, &line6pcm->out.active_urbs)) { |
302 | if (!test_and_set_bit(i, &line6pcm->unlink_urb_out)) { | 302 | if (!test_and_set_bit(i, &line6pcm->out.unlink_urbs)) { |
303 | struct urb *u = line6pcm->urb_audio_out[i]; | 303 | struct urb *u = line6pcm->out.urbs[i]; |
304 | 304 | ||
305 | usb_unlink_urb(u); | 305 | usb_unlink_urb(u); |
306 | } | 306 | } |
@@ -321,7 +321,7 @@ void line6_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm) | |||
321 | do { | 321 | do { |
322 | alive = 0; | 322 | alive = 0; |
323 | for (i = 0; i < LINE6_ISO_BUFFERS; i++) { | 323 | for (i = 0; i < LINE6_ISO_BUFFERS; i++) { |
324 | if (test_bit(i, &line6pcm->active_urb_out)) | 324 | if (test_bit(i, &line6pcm->out.active_urbs)) |
325 | alive++; | 325 | alive++; |
326 | } | 326 | } |
327 | if (!alive) | 327 | if (!alive) |
@@ -344,8 +344,8 @@ void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm) | |||
344 | 344 | ||
345 | void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm) | 345 | void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm) |
346 | { | 346 | { |
347 | kfree(line6pcm->buffer_out); | 347 | kfree(line6pcm->out.buffer); |
348 | line6pcm->buffer_out = NULL; | 348 | line6pcm->out.buffer = NULL; |
349 | } | 349 | } |
350 | 350 | ||
351 | /* | 351 | /* |
@@ -363,11 +363,11 @@ static void audio_out_callback(struct urb *urb) | |||
363 | memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); | 363 | memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); |
364 | #endif | 364 | #endif |
365 | 365 | ||
366 | line6pcm->last_frame_out = urb->start_frame; | 366 | line6pcm->out.last_frame = urb->start_frame; |
367 | 367 | ||
368 | /* find index of URB */ | 368 | /* find index of URB */ |
369 | for (index = 0; index < LINE6_ISO_BUFFERS; index++) | 369 | for (index = 0; index < LINE6_ISO_BUFFERS; index++) |
370 | if (urb == line6pcm->urb_audio_out[index]) | 370 | if (urb == line6pcm->out.urbs[index]) |
371 | break; | 371 | break; |
372 | 372 | ||
373 | if (index >= LINE6_ISO_BUFFERS) | 373 | if (index >= LINE6_ISO_BUFFERS) |
@@ -376,19 +376,19 @@ static void audio_out_callback(struct urb *urb) | |||
376 | for (i = 0; i < LINE6_ISO_PACKETS; i++) | 376 | for (i = 0; i < LINE6_ISO_PACKETS; i++) |
377 | length += urb->iso_frame_desc[i].length; | 377 | length += urb->iso_frame_desc[i].length; |
378 | 378 | ||
379 | spin_lock_irqsave(&line6pcm->lock_audio_out, flags); | 379 | spin_lock_irqsave(&line6pcm->out.lock, flags); |
380 | 380 | ||
381 | if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, &line6pcm->flags)) { | 381 | if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, &line6pcm->flags)) { |
382 | struct snd_pcm_runtime *runtime = substream->runtime; | 382 | struct snd_pcm_runtime *runtime = substream->runtime; |
383 | 383 | ||
384 | line6pcm->pos_out_done += | 384 | line6pcm->out.pos_done += |
385 | length / line6pcm->properties->bytes_per_frame; | 385 | length / line6pcm->properties->bytes_per_frame; |
386 | 386 | ||
387 | if (line6pcm->pos_out_done >= runtime->buffer_size) | 387 | if (line6pcm->out.pos_done >= runtime->buffer_size) |
388 | line6pcm->pos_out_done -= runtime->buffer_size; | 388 | line6pcm->out.pos_done -= runtime->buffer_size; |
389 | } | 389 | } |
390 | 390 | ||
391 | clear_bit(index, &line6pcm->active_urb_out); | 391 | clear_bit(index, &line6pcm->out.active_urbs); |
392 | 392 | ||
393 | for (i = 0; i < LINE6_ISO_PACKETS; i++) | 393 | for (i = 0; i < LINE6_ISO_PACKETS; i++) |
394 | if (urb->iso_frame_desc[i].status == -EXDEV) { | 394 | if (urb->iso_frame_desc[i].status == -EXDEV) { |
@@ -396,19 +396,19 @@ static void audio_out_callback(struct urb *urb) | |||
396 | break; | 396 | break; |
397 | } | 397 | } |
398 | 398 | ||
399 | if (test_and_clear_bit(index, &line6pcm->unlink_urb_out)) | 399 | if (test_and_clear_bit(index, &line6pcm->out.unlink_urbs)) |
400 | shutdown = 1; | 400 | shutdown = 1; |
401 | 401 | ||
402 | spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags); | 402 | spin_unlock_irqrestore(&line6pcm->out.lock, flags); |
403 | 403 | ||
404 | if (!shutdown) { | 404 | if (!shutdown) { |
405 | submit_audio_out_urb(line6pcm); | 405 | submit_audio_out_urb(line6pcm); |
406 | 406 | ||
407 | if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, | 407 | if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, |
408 | &line6pcm->flags)) { | 408 | &line6pcm->flags)) { |
409 | line6pcm->bytes_out += length; | 409 | line6pcm->out.bytes += length; |
410 | if (line6pcm->bytes_out >= line6pcm->period_out) { | 410 | if (line6pcm->out.bytes >= line6pcm->out.period) { |
411 | line6pcm->bytes_out %= line6pcm->period_out; | 411 | line6pcm->out.bytes %= line6pcm->out.period; |
412 | snd_pcm_period_elapsed(substream); | 412 | snd_pcm_period_elapsed(substream); |
413 | } | 413 | } |
414 | } | 414 | } |
@@ -457,7 +457,7 @@ static int snd_line6_playback_hw_params(struct snd_pcm_substream *substream, | |||
457 | return ret; | 457 | return ret; |
458 | } | 458 | } |
459 | 459 | ||
460 | line6pcm->period_out = params_period_bytes(hw_params); | 460 | line6pcm->out.period = params_period_bytes(hw_params); |
461 | return 0; | 461 | return 0; |
462 | } | 462 | } |
463 | 463 | ||
@@ -517,7 +517,7 @@ snd_line6_playback_pointer(struct snd_pcm_substream *substream) | |||
517 | { | 517 | { |
518 | struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); | 518 | struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); |
519 | 519 | ||
520 | return line6pcm->pos_out_done; | 520 | return line6pcm->out.pos_done; |
521 | } | 521 | } |
522 | 522 | ||
523 | /* playback operators */ | 523 | /* playback operators */ |
@@ -542,7 +542,7 @@ int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm) | |||
542 | struct urb *urb; | 542 | struct urb *urb; |
543 | 543 | ||
544 | /* URB for audio out: */ | 544 | /* URB for audio out: */ |
545 | urb = line6pcm->urb_audio_out[i] = | 545 | urb = line6pcm->out.urbs[i] = |
546 | usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL); | 546 | usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL); |
547 | 547 | ||
548 | if (urb == NULL) | 548 | if (urb == NULL) |