include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / staging / line6 / pcm.c
1 /*
2  * Line6 Linux USB driver - 0.8.0
3  *
4  * Copyright (C) 2004-2009 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 "driver.h"
13
14 #include <linux/slab.h>
15
16 #include <sound/core.h>
17 #include <sound/control.h>
18 #include <sound/pcm.h>
19 #include <sound/pcm_params.h>
20
21 #include "audio.h"
22 #include "capture.h"
23 #include "playback.h"
24 #include "pod.h"
25
26
27 /* trigger callback */
28 int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
29 {
30         struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
31         struct snd_pcm_substream *s;
32         int err;
33         unsigned long flags;
34
35         spin_lock_irqsave(&line6pcm->lock_trigger, flags);
36         clear_bit(BIT_PREPARED, &line6pcm->flags);
37
38         snd_pcm_group_for_each_entry(s, substream) {
39                 switch (s->stream) {
40                 case SNDRV_PCM_STREAM_PLAYBACK:
41                         err = snd_line6_playback_trigger(s, cmd);
42
43                         if (err < 0) {
44                                 spin_unlock_irqrestore(&line6pcm->lock_trigger,
45                                                        flags);
46                                 return err;
47                         }
48
49                         break;
50
51                 case SNDRV_PCM_STREAM_CAPTURE:
52                         err = snd_line6_capture_trigger(s, cmd);
53
54                         if (err < 0) {
55                                 spin_unlock_irqrestore(&line6pcm->lock_trigger,
56                                                        flags);
57                                 return err;
58                         }
59
60                         break;
61
62                 default:
63                         dev_err(s2m(substream), "Unknown stream direction %d\n",
64                                 s->stream);
65                 }
66         }
67
68         spin_unlock_irqrestore(&line6pcm->lock_trigger, flags);
69         return 0;
70 }
71
72 /* control info callback */
73 static int snd_line6_control_info(struct snd_kcontrol *kcontrol,
74                                   struct snd_ctl_elem_info *uinfo)
75 {
76         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
77         uinfo->count = 2;
78         uinfo->value.integer.min = 0;
79         uinfo->value.integer.max = 256;
80         return 0;
81 }
82
83 /* control get callback */
84 static int snd_line6_control_get(struct snd_kcontrol *kcontrol,
85                                  struct snd_ctl_elem_value *ucontrol)
86 {
87         int i;
88         struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
89
90         for (i = 2; i--;)
91                 ucontrol->value.integer.value[i] = line6pcm->volume[i];
92
93         return 0;
94 }
95
96 /* control put callback */
97 static int snd_line6_control_put(struct snd_kcontrol *kcontrol,
98                                  struct snd_ctl_elem_value *ucontrol)
99 {
100         int i, changed = 0;
101         struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
102
103         for (i = 2; i--;)
104                 if (line6pcm->volume[i] != ucontrol->value.integer.value[i]) {
105                         line6pcm->volume[i] = ucontrol->value.integer.value[i];
106                         changed = 1;
107                 }
108
109         return changed;
110 }
111
112 /* control definition */
113 static struct snd_kcontrol_new line6_control = {
114         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
115         .name = "PCM Playback Volume",
116         .index = 0,
117         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
118         .info = snd_line6_control_info,
119         .get = snd_line6_control_get,
120         .put = snd_line6_control_put
121 };
122
123 /*
124         Cleanup the PCM device.
125 */
126 static void line6_cleanup_pcm(struct snd_pcm *pcm)
127 {
128         int i;
129         struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
130
131         for (i = LINE6_ISO_BUFFERS; i--;) {
132                 if (line6pcm->urb_audio_out[i]) {
133                         usb_kill_urb(line6pcm->urb_audio_out[i]);
134                         usb_free_urb(line6pcm->urb_audio_out[i]);
135                 }
136                 if (line6pcm->urb_audio_in[i]) {
137                         usb_kill_urb(line6pcm->urb_audio_in[i]);
138                         usb_free_urb(line6pcm->urb_audio_in[i]);
139                 }
140         }
141 }
142
143 /* create a PCM device */
144 static int snd_line6_new_pcm(struct snd_line6_pcm *line6pcm)
145 {
146         struct snd_pcm *pcm;
147         int err;
148
149         err = snd_pcm_new(line6pcm->line6->card,
150                          (char *)line6pcm->line6->properties->name,
151                          0, 1, 1, &pcm);
152         if (err < 0)
153                 return err;
154
155         pcm->private_data = line6pcm;
156         pcm->private_free = line6_cleanup_pcm;
157         line6pcm->pcm = pcm;
158         strcpy(pcm->name, line6pcm->line6->properties->name);
159
160         /* set operators */
161         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
162                         &snd_line6_playback_ops);
163         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_line6_capture_ops);
164
165         /* pre-allocation of buffers */
166         snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
167                                         snd_dma_continuous_data(GFP_KERNEL),
168                                         64 * 1024, 128 * 1024);
169
170         return 0;
171 }
172
173 /* PCM device destructor */
174 static int snd_line6_pcm_free(struct snd_device *device)
175 {
176         return 0;
177 }
178
179 /*
180         Create and register the PCM device and mixer entries.
181         Create URBs for playback and capture.
182 */
183 int line6_init_pcm(struct usb_line6 *line6,
184                    struct line6_pcm_properties *properties)
185 {
186         static struct snd_device_ops pcm_ops = {
187                 .dev_free = snd_line6_pcm_free,
188         };
189
190         int err;
191         int ep_read = 0, ep_write = 0;
192         struct snd_line6_pcm *line6pcm;
193
194         if (!(line6->properties->capabilities & LINE6_BIT_PCM))
195                 return 0;  /* skip PCM initialization and report success */
196
197         /* initialize PCM subsystem based on product id: */
198         switch (line6->product) {
199         case LINE6_DEVID_BASSPODXT:
200         case LINE6_DEVID_BASSPODXTLIVE:
201         case LINE6_DEVID_BASSPODXTPRO:
202         case LINE6_DEVID_PODXT:
203         case LINE6_DEVID_PODXTLIVE:
204         case LINE6_DEVID_PODXTPRO:
205                 ep_read  = 0x82;
206                 ep_write = 0x01;
207                 break;
208
209         case LINE6_DEVID_PODX3:
210         case LINE6_DEVID_PODX3LIVE:
211                 ep_read  = 0x86;
212                 ep_write = 0x02;
213                 break;
214
215         case LINE6_DEVID_POCKETPOD:
216                 ep_read  = 0x82;
217                 ep_write = 0x02;
218                 break;
219
220         case LINE6_DEVID_GUITARPORT:
221         case LINE6_DEVID_TONEPORT_GX:
222                 ep_read  = 0x82;
223                 ep_write = 0x01;
224                 break;
225
226         case LINE6_DEVID_TONEPORT_UX1:
227                 ep_read  = 0x00;
228                 ep_write = 0x00;
229                 break;
230
231         case LINE6_DEVID_TONEPORT_UX2:
232                 ep_read  = 0x87;
233                 ep_write = 0x00;
234                 break;
235
236         default:
237                 MISSING_CASE;
238         }
239
240         line6pcm = kzalloc(sizeof(struct snd_line6_pcm), GFP_KERNEL);
241
242         if (line6pcm == NULL)
243                 return -ENOMEM;
244
245         line6pcm->volume[0] = line6pcm->volume[1] = 128;
246         line6pcm->line6 = line6;
247         line6pcm->ep_audio_read = ep_read;
248         line6pcm->ep_audio_write = ep_write;
249         line6pcm->max_packet_size = usb_maxpacket(line6->usbdev,
250                                                  usb_rcvintpipe(line6->usbdev,
251                                                                 ep_read),
252                                                   0);
253         line6pcm->properties = properties;
254         line6->line6pcm = line6pcm;
255
256         /* PCM device: */
257         err = snd_device_new(line6->card, SNDRV_DEV_PCM, line6, &pcm_ops);
258         if (err < 0)
259                 return err;
260
261         snd_card_set_dev(line6->card, line6->ifcdev);
262
263         err = snd_line6_new_pcm(line6pcm);
264         if (err < 0)
265                 return err;
266
267         spin_lock_init(&line6pcm->lock_audio_out);
268         spin_lock_init(&line6pcm->lock_audio_in);
269         spin_lock_init(&line6pcm->lock_trigger);
270
271         err = create_audio_out_urbs(line6pcm);
272         if (err < 0)
273                 return err;
274
275         err = create_audio_in_urbs(line6pcm);
276         if (err < 0)
277                 return err;
278
279         /* mixer: */
280         err = snd_ctl_add(line6->card, snd_ctl_new1(&line6_control, line6pcm));
281         if (err < 0)
282                 return err;
283
284         return 0;
285 }
286
287 /* prepare pcm callback */
288 int snd_line6_prepare(struct snd_pcm_substream *substream)
289 {
290         struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
291
292         if (!test_and_set_bit(BIT_PREPARED, &line6pcm->flags)) {
293                 unlink_wait_clear_audio_out_urbs(line6pcm);
294                 line6pcm->pos_out = 0;
295                 line6pcm->pos_out_done = 0;
296
297                 unlink_wait_clear_audio_in_urbs(line6pcm);
298                 line6pcm->bytes_out = 0;
299                 line6pcm->pos_in_done = 0;
300                 line6pcm->bytes_in = 0;
301         }
302
303         return 0;
304 }