OSDN Git Service

ALSA: line6: Consolidate URB unlink and sync helpers
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / sound / usb / line6 / pcm.c
1 /*
2  * Line 6 Linux USB driver
3  *
4  * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
5  *
6  *      This program is free software; you can redistribute it and/or
7  *      modify it under the terms of the GNU General Public License as
8  *      published by the Free Software Foundation, version 2.
9  *
10  */
11
12 #include <linux/slab.h>
13 #include <linux/export.h>
14 #include <sound/core.h>
15 #include <sound/control.h>
16 #include <sound/pcm.h>
17 #include <sound/pcm_params.h>
18
19 #include "capture.h"
20 #include "driver.h"
21 #include "playback.h"
22
23 /* impulse response volume controls */
24 static int snd_line6_impulse_volume_info(struct snd_kcontrol *kcontrol,
25                                          struct snd_ctl_elem_info *uinfo)
26 {
27         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
28         uinfo->count = 1;
29         uinfo->value.integer.min = 0;
30         uinfo->value.integer.max = 255;
31         return 0;
32 }
33
34 static int snd_line6_impulse_volume_get(struct snd_kcontrol *kcontrol,
35                                         struct snd_ctl_elem_value *ucontrol)
36 {
37         struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
38
39         ucontrol->value.integer.value[0] = line6pcm->impulse_volume;
40         return 0;
41 }
42
43 static int snd_line6_impulse_volume_put(struct snd_kcontrol *kcontrol,
44                                         struct snd_ctl_elem_value *ucontrol)
45 {
46         struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
47         int value = ucontrol->value.integer.value[0];
48
49         if (line6pcm->impulse_volume == value)
50                 return 0;
51
52         line6pcm->impulse_volume = value;
53         if (value > 0)
54                 line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_IMPULSE);
55         else
56                 line6_pcm_release(line6pcm, LINE6_BITS_PCM_IMPULSE);
57         return 1;
58 }
59
60 /* impulse response period controls */
61 static int snd_line6_impulse_period_info(struct snd_kcontrol *kcontrol,
62                                          struct snd_ctl_elem_info *uinfo)
63 {
64         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
65         uinfo->count = 1;
66         uinfo->value.integer.min = 0;
67         uinfo->value.integer.max = 2000;
68         return 0;
69 }
70
71 static int snd_line6_impulse_period_get(struct snd_kcontrol *kcontrol,
72                                         struct snd_ctl_elem_value *ucontrol)
73 {
74         struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
75
76         ucontrol->value.integer.value[0] = line6pcm->impulse_period;
77         return 0;
78 }
79
80 static int snd_line6_impulse_period_put(struct snd_kcontrol *kcontrol,
81                                         struct snd_ctl_elem_value *ucontrol)
82 {
83         struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
84         int value = ucontrol->value.integer.value[0];
85
86         if (line6pcm->impulse_period == value)
87                 return 0;
88
89         line6pcm->impulse_period = value;
90         return 1;
91 }
92
93 /*
94         Unlink all currently active URBs.
95 */
96 static void line6_unlink_audio_urbs(struct snd_line6_pcm *line6pcm,
97                                     struct line6_pcm_stream *pcms)
98 {
99         int i;
100
101         for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
102                 if (test_bit(i, &pcms->active_urbs)) {
103                         if (!test_and_set_bit(i, &pcms->unlink_urbs))
104                                 usb_unlink_urb(pcms->urbs[i]);
105                 }
106         }
107 }
108
109 /*
110         Wait until unlinking of all currently active URBs has been finished.
111 */
112 static void line6_wait_clear_audio_urbs(struct snd_line6_pcm *line6pcm,
113                                         struct line6_pcm_stream *pcms)
114 {
115         int timeout = HZ;
116         int i;
117         int alive;
118
119         do {
120                 alive = 0;
121                 for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
122                         if (test_bit(i, &pcms->active_urbs))
123                                 alive++;
124                 }
125                 if (!alive)
126                         break;
127                 set_current_state(TASK_UNINTERRUPTIBLE);
128                 schedule_timeout(1);
129         } while (--timeout > 0);
130         if (alive)
131                 snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
132 }
133
134 static bool test_flags(unsigned long flags0, unsigned long flags1,
135                        unsigned long mask)
136 {
137         return ((flags0 & mask) == 0) && ((flags1 & mask) != 0);
138 }
139
140 int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels)
141 {
142         unsigned long flags_old, flags_new, flags_final;
143         int err;
144
145         do {
146                 flags_old = ACCESS_ONCE(line6pcm->flags);
147                 flags_new = flags_old | channels;
148         } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old);
149
150         flags_final = 0;
151
152         line6pcm->prev_fbuf = NULL;
153
154         if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_BUFFER)) {
155                 /* Invoked multiple times in a row so allocate once only */
156                 if (!line6pcm->in.buffer) {
157                         line6pcm->in.buffer =
158                                 kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
159                                         line6pcm->max_packet_size, GFP_KERNEL);
160                         if (!line6pcm->in.buffer) {
161                                 err = -ENOMEM;
162                                 goto pcm_acquire_error;
163                         }
164                 }
165
166                 flags_final |= channels & LINE6_BITS_CAPTURE_BUFFER;
167         }
168
169         if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_STREAM)) {
170                 /*
171                    Waiting for completion of active URBs in the stop handler is
172                    a bug, we therefore report an error if capturing is restarted
173                    too soon.
174                  */
175                 if (line6pcm->in.active_urbs || line6pcm->in.unlink_urbs) {
176                         dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n");
177                         err = -EBUSY;
178                         goto pcm_acquire_error;
179                 }
180
181                 line6pcm->in.count = 0;
182                 line6pcm->prev_fsize = 0;
183                 err = line6_submit_audio_in_all_urbs(line6pcm);
184
185                 if (err < 0)
186                         goto pcm_acquire_error;
187
188                 flags_final |= channels & LINE6_BITS_CAPTURE_STREAM;
189         }
190
191         if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_BUFFER)) {
192                 /* Invoked multiple times in a row so allocate once only */
193                 if (!line6pcm->out.buffer) {
194                         line6pcm->out.buffer =
195                                 kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
196                                         line6pcm->max_packet_size, GFP_KERNEL);
197                         if (!line6pcm->out.buffer) {
198                                 err = -ENOMEM;
199                                 goto pcm_acquire_error;
200                         }
201                 }
202
203                 flags_final |= channels & LINE6_BITS_PLAYBACK_BUFFER;
204         }
205
206         if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_STREAM)) {
207                 /*
208                   See comment above regarding PCM restart.
209                 */
210                 if (line6pcm->out.active_urbs || line6pcm->out.unlink_urbs) {
211                         dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n");
212                         return -EBUSY;
213                 }
214
215                 line6pcm->out.count = 0;
216                 err = line6_submit_audio_out_all_urbs(line6pcm);
217
218                 if (err < 0)
219                         goto pcm_acquire_error;
220
221                 flags_final |= channels & LINE6_BITS_PLAYBACK_STREAM;
222         }
223
224         return 0;
225
226 pcm_acquire_error:
227         /*
228            If not all requested resources/streams could be obtained, release
229            those which were successfully obtained (if any).
230         */
231         line6_pcm_release(line6pcm, flags_final);
232         return err;
233 }
234 EXPORT_SYMBOL_GPL(line6_pcm_acquire);
235
236 int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels)
237 {
238         unsigned long flags_old, flags_new;
239
240         do {
241                 flags_old = ACCESS_ONCE(line6pcm->flags);
242                 flags_new = flags_old & ~channels;
243         } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old);
244
245         if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_STREAM))
246                 line6_unlink_audio_urbs(line6pcm, &line6pcm->in);
247
248         if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_BUFFER)) {
249                 line6_wait_clear_audio_urbs(line6pcm, &line6pcm->in);
250                 line6_free_capture_buffer(line6pcm);
251         }
252
253         if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_STREAM))
254                 line6_unlink_audio_urbs(line6pcm, &line6pcm->out);
255
256         if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_BUFFER)) {
257                 line6_wait_clear_audio_urbs(line6pcm, &line6pcm->out);
258                 line6_free_playback_buffer(line6pcm);
259         }
260
261         return 0;
262 }
263 EXPORT_SYMBOL_GPL(line6_pcm_release);
264
265 /* trigger callback */
266 int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
267 {
268         struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
269         struct snd_pcm_substream *s;
270         int err = 0;
271
272         clear_bit(LINE6_INDEX_PREPARED, &line6pcm->flags);
273
274         snd_pcm_group_for_each_entry(s, substream) {
275                 if (s->pcm->card != substream->pcm->card)
276                         continue;
277                 switch (s->stream) {
278                 case SNDRV_PCM_STREAM_PLAYBACK:
279                         err = snd_line6_playback_trigger(line6pcm, cmd);
280                         break;
281
282                 case SNDRV_PCM_STREAM_CAPTURE:
283                         err = snd_line6_capture_trigger(line6pcm, cmd);
284                         break;
285
286                 default:
287                         dev_err(line6pcm->line6->ifcdev,
288                                 "Unknown stream direction %d\n", s->stream);
289                         err = -EINVAL;
290                         break;
291                 }
292                 if (err < 0)
293                         break;
294         }
295
296         return err;
297 }
298
299 /* control info callback */
300 static int snd_line6_control_playback_info(struct snd_kcontrol *kcontrol,
301                                            struct snd_ctl_elem_info *uinfo)
302 {
303         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
304         uinfo->count = 2;
305         uinfo->value.integer.min = 0;
306         uinfo->value.integer.max = 256;
307         return 0;
308 }
309
310 /* control get callback */
311 static int snd_line6_control_playback_get(struct snd_kcontrol *kcontrol,
312                                           struct snd_ctl_elem_value *ucontrol)
313 {
314         int i;
315         struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
316
317         for (i = 0; i < 2; i++)
318                 ucontrol->value.integer.value[i] = line6pcm->volume_playback[i];
319
320         return 0;
321 }
322
323 /* control put callback */
324 static int snd_line6_control_playback_put(struct snd_kcontrol *kcontrol,
325                                           struct snd_ctl_elem_value *ucontrol)
326 {
327         int i, changed = 0;
328         struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
329
330         for (i = 0; i < 2; i++)
331                 if (line6pcm->volume_playback[i] !=
332                     ucontrol->value.integer.value[i]) {
333                         line6pcm->volume_playback[i] =
334                             ucontrol->value.integer.value[i];
335                         changed = 1;
336                 }
337
338         return changed;
339 }
340
341 /* control definition */
342 static struct snd_kcontrol_new line6_controls[] = {
343         {
344                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
345                 .name = "PCM Playback Volume",
346                 .info = snd_line6_control_playback_info,
347                 .get = snd_line6_control_playback_get,
348                 .put = snd_line6_control_playback_put
349         },
350         {
351                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
352                 .name = "Impulse Response Volume",
353                 .info = snd_line6_impulse_volume_info,
354                 .get = snd_line6_impulse_volume_get,
355                 .put = snd_line6_impulse_volume_put
356         },
357         {
358                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
359                 .name = "Impulse Response Period",
360                 .info = snd_line6_impulse_period_info,
361                 .get = snd_line6_impulse_period_get,
362                 .put = snd_line6_impulse_period_put
363         },
364 };
365
366 /*
367         Cleanup the PCM device.
368 */
369 static void cleanup_urbs(struct line6_pcm_stream *pcms)
370 {
371         int i;
372
373         for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
374                 if (pcms->urbs[i]) {
375                         usb_kill_urb(pcms->urbs[i]);
376                         usb_free_urb(pcms->urbs[i]);
377                 }
378         }
379 }
380
381 static void line6_cleanup_pcm(struct snd_pcm *pcm)
382 {
383         struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
384
385         cleanup_urbs(&line6pcm->out);
386         cleanup_urbs(&line6pcm->in);
387         kfree(line6pcm);
388 }
389
390 /* create a PCM device */
391 static int snd_line6_new_pcm(struct usb_line6 *line6, struct snd_pcm **pcm_ret)
392 {
393         struct snd_pcm *pcm;
394         int err;
395
396         err = snd_pcm_new(line6->card, (char *)line6->properties->name,
397                           0, 1, 1, pcm_ret);
398         if (err < 0)
399                 return err;
400         pcm = *pcm_ret;
401         strcpy(pcm->name, line6->properties->name);
402
403         /* set operators */
404         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
405                         &snd_line6_playback_ops);
406         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_line6_capture_ops);
407
408         /* pre-allocation of buffers */
409         snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
410                                               snd_dma_continuous_data
411                                               (GFP_KERNEL), 64 * 1024,
412                                               128 * 1024);
413         return 0;
414 }
415
416 /*
417         Sync with PCM stream stops.
418 */
419 void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm)
420 {
421         line6_unlink_audio_urbs(line6pcm, &line6pcm->out);
422         line6_unlink_audio_urbs(line6pcm, &line6pcm->in);
423         line6_wait_clear_audio_urbs(line6pcm, &line6pcm->out);
424         line6_wait_clear_audio_urbs(line6pcm, &line6pcm->in);
425 }
426
427 /*
428         Create and register the PCM device and mixer entries.
429         Create URBs for playback and capture.
430 */
431 int line6_init_pcm(struct usb_line6 *line6,
432                    struct line6_pcm_properties *properties)
433 {
434         int i, err;
435         unsigned ep_read = line6->properties->ep_audio_r;
436         unsigned ep_write = line6->properties->ep_audio_w;
437         struct snd_pcm *pcm;
438         struct snd_line6_pcm *line6pcm;
439
440         if (!(line6->properties->capabilities & LINE6_CAP_PCM))
441                 return 0;       /* skip PCM initialization and report success */
442
443         err = snd_line6_new_pcm(line6, &pcm);
444         if (err < 0)
445                 return err;
446
447         line6pcm = kzalloc(sizeof(*line6pcm), GFP_KERNEL);
448         if (!line6pcm)
449                 return -ENOMEM;
450
451         line6pcm->pcm = pcm;
452         line6pcm->properties = properties;
453         line6pcm->volume_playback[0] = line6pcm->volume_playback[1] = 255;
454         line6pcm->volume_monitor = 255;
455         line6pcm->line6 = line6;
456
457         /* Read and write buffers are sized identically, so choose minimum */
458         line6pcm->max_packet_size = min(
459                         usb_maxpacket(line6->usbdev,
460                                 usb_rcvisocpipe(line6->usbdev, ep_read), 0),
461                         usb_maxpacket(line6->usbdev,
462                                 usb_sndisocpipe(line6->usbdev, ep_write), 1));
463
464         spin_lock_init(&line6pcm->out.lock);
465         spin_lock_init(&line6pcm->in.lock);
466         line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD;
467
468         line6->line6pcm = line6pcm;
469
470         pcm->private_data = line6pcm;
471         pcm->private_free = line6_cleanup_pcm;
472
473         err = line6_create_audio_out_urbs(line6pcm);
474         if (err < 0)
475                 return err;
476
477         err = line6_create_audio_in_urbs(line6pcm);
478         if (err < 0)
479                 return err;
480
481         /* mixer: */
482         for (i = 0; i < ARRAY_SIZE(line6_controls); i++) {
483                 err = snd_ctl_add(line6->card,
484                                   snd_ctl_new1(&line6_controls[i], line6pcm));
485                 if (err < 0)
486                         return err;
487         }
488
489         return 0;
490 }
491 EXPORT_SYMBOL_GPL(line6_init_pcm);
492
493 /* prepare pcm callback */
494 int snd_line6_prepare(struct snd_pcm_substream *substream)
495 {
496         struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
497
498         switch (substream->stream) {
499         case SNDRV_PCM_STREAM_PLAYBACK:
500                 if ((line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM) == 0) {
501                         line6_unlink_audio_urbs(line6pcm, &line6pcm->out);
502                         line6_wait_clear_audio_urbs(line6pcm, &line6pcm->out);
503                 }
504                 break;
505
506         case SNDRV_PCM_STREAM_CAPTURE:
507                 if ((line6pcm->flags & LINE6_BITS_CAPTURE_STREAM) == 0) {
508                         line6_unlink_audio_urbs(line6pcm, &line6pcm->in);
509                         line6_wait_clear_audio_urbs(line6pcm, &line6pcm->in);
510                 }
511                 break;
512         }
513
514         if (!test_and_set_bit(LINE6_INDEX_PREPARED, &line6pcm->flags)) {
515                 line6pcm->out.count = 0;
516                 line6pcm->out.pos = 0;
517                 line6pcm->out.pos_done = 0;
518                 line6pcm->out.bytes = 0;
519                 line6pcm->in.count = 0;
520                 line6pcm->in.pos_done = 0;
521                 line6pcm->in.bytes = 0;
522         }
523
524         return 0;
525 }