Merge tag 'regulator-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie...
[pandora-kernel.git] / drivers / staging / line6 / pod.c
1 /*
2  * Line6 Linux USB driver - 0.9.1beta
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/wait.h>
14 #include <sound/control.h>
15
16 #include "audio.h"
17 #include "capture.h"
18 #include "driver.h"
19 #include "playback.h"
20 #include "pod.h"
21
22 #define POD_SYSEX_CODE 3
23 #define POD_BYTES_PER_FRAME 6   /* 24bit audio (stereo) */
24
25 /* *INDENT-OFF* */
26
27 enum {
28         POD_SYSEX_SAVE      = 0x24,
29         POD_SYSEX_SYSTEM    = 0x56,
30         POD_SYSEX_SYSTEMREQ = 0x57,
31         /* POD_SYSEX_UPDATE    = 0x6c, */  /* software update! */
32         POD_SYSEX_STORE     = 0x71,
33         POD_SYSEX_FINISH    = 0x72,
34         POD_SYSEX_DUMPMEM   = 0x73,
35         POD_SYSEX_DUMP      = 0x74,
36         POD_SYSEX_DUMPREQ   = 0x75
37         /* POD_SYSEX_DUMPMEM2  = 0x76 */   /* dumps entire internal memory of PODxt Pro */
38 };
39
40 enum {
41         POD_monitor_level  = 0x04,
42         POD_system_invalid = 0x10000
43 };
44
45 /* *INDENT-ON* */
46
47 enum {
48         POD_DUMP_MEMORY = 2
49 };
50
51 enum {
52         POD_BUSY_READ,
53         POD_BUSY_WRITE,
54         POD_CHANNEL_DIRTY,
55         POD_SAVE_PRESSED,
56         POD_BUSY_MIDISEND
57 };
58
59 static struct snd_ratden pod_ratden = {
60         .num_min = 78125,
61         .num_max = 78125,
62         .num_step = 1,
63         .den = 2
64 };
65
66 static struct line6_pcm_properties pod_pcm_properties = {
67         .snd_line6_playback_hw = {
68                                   .info = (SNDRV_PCM_INFO_MMAP |
69                                            SNDRV_PCM_INFO_INTERLEAVED |
70                                            SNDRV_PCM_INFO_BLOCK_TRANSFER |
71                                            SNDRV_PCM_INFO_MMAP_VALID |
72                                            SNDRV_PCM_INFO_PAUSE |
73 #ifdef CONFIG_PM
74                                            SNDRV_PCM_INFO_RESUME |
75 #endif
76                                            SNDRV_PCM_INFO_SYNC_START),
77                                   .formats = SNDRV_PCM_FMTBIT_S24_3LE,
78                                   .rates = SNDRV_PCM_RATE_KNOT,
79                                   .rate_min = 39062,
80                                   .rate_max = 39063,
81                                   .channels_min = 2,
82                                   .channels_max = 2,
83                                   .buffer_bytes_max = 60000,
84                                   .period_bytes_min = 64,
85                                   .period_bytes_max = 8192,
86                                   .periods_min = 1,
87                                   .periods_max = 1024},
88         .snd_line6_capture_hw = {
89                                  .info = (SNDRV_PCM_INFO_MMAP |
90                                           SNDRV_PCM_INFO_INTERLEAVED |
91                                           SNDRV_PCM_INFO_BLOCK_TRANSFER |
92                                           SNDRV_PCM_INFO_MMAP_VALID |
93 #ifdef CONFIG_PM
94                                           SNDRV_PCM_INFO_RESUME |
95 #endif
96                                           SNDRV_PCM_INFO_SYNC_START),
97                                  .formats = SNDRV_PCM_FMTBIT_S24_3LE,
98                                  .rates = SNDRV_PCM_RATE_KNOT,
99                                  .rate_min = 39062,
100                                  .rate_max = 39063,
101                                  .channels_min = 2,
102                                  .channels_max = 2,
103                                  .buffer_bytes_max = 60000,
104                                  .period_bytes_min = 64,
105                                  .period_bytes_max = 8192,
106                                  .periods_min = 1,
107                                  .periods_max = 1024},
108         .snd_line6_rates = {
109                             .nrats = 1,
110                             .rats = &pod_ratden},
111         .bytes_per_frame = POD_BYTES_PER_FRAME
112 };
113
114 static const char pod_version_header[] = {
115         0xf2, 0x7e, 0x7f, 0x06, 0x02
116 };
117
118 /* forward declarations: */
119 static void pod_startup2(unsigned long data);
120 static void pod_startup3(struct usb_line6_pod *pod);
121
122 static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
123                                     int size)
124 {
125         return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code,
126                                         size);
127 }
128
129 /*
130         Process a completely received message.
131 */
132 void line6_pod_process_message(struct usb_line6_pod *pod)
133 {
134         const unsigned char *buf = pod->line6.buffer_message;
135
136         /* filter messages by type */
137         switch (buf[0] & 0xf0) {
138         case LINE6_PARAM_CHANGE:
139         case LINE6_PROGRAM_CHANGE:
140         case LINE6_SYSEX_BEGIN:
141                 break;          /* handle these further down */
142
143         default:
144                 return;         /* ignore all others */
145         }
146
147         /* process all remaining messages */
148         switch (buf[0]) {
149         case LINE6_PARAM_CHANGE | LINE6_CHANNEL_DEVICE:
150         case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
151                 break;
152
153         case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
154         case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
155                 break;
156
157         case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE:
158         case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN:
159                 if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) == 0) {
160                         switch (buf[5]) {
161                         case POD_SYSEX_DUMP:
162                                 break;
163
164                         case POD_SYSEX_SYSTEM:{
165                                         short value =
166                                             ((int)buf[7] << 12) | ((int)buf[8]
167                                                                    << 8) |
168                                             ((int)buf[9] << 4) | (int)buf[10];
169
170                                         if (buf[6] == POD_monitor_level)
171                                                 pod->monitor_level = value;
172                                         break;
173                                 }
174
175                         case POD_SYSEX_FINISH:
176                                 /* do we need to respond to this? */
177                                 break;
178
179                         case POD_SYSEX_SAVE:
180                                 break;
181
182                         case POD_SYSEX_STORE:
183                                 dev_dbg(pod->line6.ifcdev,
184                                         "message %02X not yet implemented\n",
185                                         buf[5]);
186                                 break;
187
188                         default:
189                                 dev_dbg(pod->line6.ifcdev,
190                                         "unknown sysex message %02X\n",
191                                         buf[5]);
192                         }
193                 } else
194                     if (memcmp
195                         (buf, pod_version_header,
196                          sizeof(pod_version_header)) == 0) {
197                         pod->firmware_version =
198                             buf[13] * 100 + buf[14] * 10 + buf[15];
199                         pod->device_id =
200                             ((int)buf[8] << 16) | ((int)buf[9] << 8) | (int)
201                             buf[10];
202                         pod_startup3(pod);
203                 } else
204                         dev_dbg(pod->line6.ifcdev, "unknown sysex header\n");
205
206                 break;
207
208         case LINE6_SYSEX_END:
209                 break;
210
211         default:
212                 dev_dbg(pod->line6.ifcdev, "POD: unknown message %02X\n",
213                         buf[0]);
214         }
215 }
216
217 /*
218         Transmit PODxt Pro control parameter.
219 */
220 void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param,
221                                   u8 value)
222 {
223         line6_transmit_parameter(&pod->line6, param, value);
224 }
225
226 /*
227         Send system parameter (from integer).
228 */
229 static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
230                                     int code)
231 {
232         char *sysex;
233         static const int size = 5;
234
235         sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
236         if (!sysex)
237                 return -ENOMEM;
238         sysex[SYSEX_DATA_OFS] = code;
239         sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
240         sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
241         sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
242         sysex[SYSEX_DATA_OFS + 4] = (value) & 0x0f;
243         line6_send_sysex_message(&pod->line6, sysex, size);
244         kfree(sysex);
245         return 0;
246 }
247
248 /*
249         "read" request on "serial_number" special file.
250 */
251 static ssize_t pod_get_serial_number(struct device *dev,
252                                      struct device_attribute *attr, char *buf)
253 {
254         struct usb_interface *interface = to_usb_interface(dev);
255         struct usb_line6_pod *pod = usb_get_intfdata(interface);
256         return sprintf(buf, "%d\n", pod->serial_number);
257 }
258
259 /*
260         "read" request on "firmware_version" special file.
261 */
262 static ssize_t pod_get_firmware_version(struct device *dev,
263                                         struct device_attribute *attr,
264                                         char *buf)
265 {
266         struct usb_interface *interface = to_usb_interface(dev);
267         struct usb_line6_pod *pod = usb_get_intfdata(interface);
268         return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
269                        pod->firmware_version % 100);
270 }
271
272 /*
273         "read" request on "device_id" special file.
274 */
275 static ssize_t pod_get_device_id(struct device *dev,
276                                  struct device_attribute *attr, char *buf)
277 {
278         struct usb_interface *interface = to_usb_interface(dev);
279         struct usb_line6_pod *pod = usb_get_intfdata(interface);
280         return sprintf(buf, "%d\n", pod->device_id);
281 }
282
283 /*
284         POD startup procedure.
285         This is a sequence of functions with special requirements (e.g., must
286         not run immediately after initialization, must not run in interrupt
287         context). After the last one has finished, the device is ready to use.
288 */
289
290 static void pod_startup1(struct usb_line6_pod *pod)
291 {
292         CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
293
294         /* delay startup procedure: */
295         line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
296                           (unsigned long)pod);
297 }
298
299 static void pod_startup2(unsigned long data)
300 {
301         struct usb_line6_pod *pod = (struct usb_line6_pod *)data;
302         struct usb_line6 *line6 = &pod->line6;
303         CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
304
305         /* request firmware version: */
306         line6_version_request_async(line6);
307 }
308
309 static void pod_startup3(struct usb_line6_pod *pod)
310 {
311         CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
312
313         /* schedule work for global work queue: */
314         schedule_work(&pod->startup_work);
315 }
316
317 static void pod_startup4(struct work_struct *work)
318 {
319         struct usb_line6_pod *pod =
320             container_of(work, struct usb_line6_pod, startup_work);
321         struct usb_line6 *line6 = &pod->line6;
322
323         CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
324
325         /* serial number: */
326         line6_read_serial_number(&pod->line6, &pod->serial_number);
327
328         /* ALSA audio interface: */
329         line6_register_audio(line6);
330 }
331
332 /* POD special files: */
333 static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
334 static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version,
335                    line6_nop_write);
336 static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number,
337                    line6_nop_write);
338
339 /* control info callback */
340 static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
341                                         struct snd_ctl_elem_info *uinfo)
342 {
343         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
344         uinfo->count = 1;
345         uinfo->value.integer.min = 0;
346         uinfo->value.integer.max = 65535;
347         return 0;
348 }
349
350 /* control get callback */
351 static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
352                                        struct snd_ctl_elem_value *ucontrol)
353 {
354         struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
355         struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
356         ucontrol->value.integer.value[0] = pod->monitor_level;
357         return 0;
358 }
359
360 /* control put callback */
361 static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
362                                        struct snd_ctl_elem_value *ucontrol)
363 {
364         struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
365         struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
366
367         if (ucontrol->value.integer.value[0] == pod->monitor_level)
368                 return 0;
369
370         pod->monitor_level = ucontrol->value.integer.value[0];
371         pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
372                                  POD_monitor_level);
373         return 1;
374 }
375
376 /* control definition */
377 static struct snd_kcontrol_new pod_control_monitor = {
378         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
379         .name = "Monitor Playback Volume",
380         .index = 0,
381         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
382         .info = snd_pod_control_monitor_info,
383         .get = snd_pod_control_monitor_get,
384         .put = snd_pod_control_monitor_put
385 };
386
387 /*
388         POD destructor.
389 */
390 static void pod_destruct(struct usb_interface *interface)
391 {
392         struct usb_line6_pod *pod = usb_get_intfdata(interface);
393
394         if (pod == NULL)
395                 return;
396         line6_cleanup_audio(&pod->line6);
397
398         del_timer(&pod->startup_timer);
399         cancel_work_sync(&pod->startup_work);
400 }
401
402 /*
403         Create sysfs entries.
404 */
405 static int pod_create_files2(struct device *dev)
406 {
407         int err;
408
409         CHECK_RETURN(device_create_file(dev, &dev_attr_device_id));
410         CHECK_RETURN(device_create_file(dev, &dev_attr_firmware_version));
411         CHECK_RETURN(device_create_file(dev, &dev_attr_serial_number));
412         return 0;
413 }
414
415 /*
416          Try to init POD device.
417 */
418 static int pod_try_init(struct usb_interface *interface,
419                         struct usb_line6_pod *pod)
420 {
421         int err;
422         struct usb_line6 *line6 = &pod->line6;
423
424         init_timer(&pod->startup_timer);
425         INIT_WORK(&pod->startup_work, pod_startup4);
426
427         if ((interface == NULL) || (pod == NULL))
428                 return -ENODEV;
429
430         /* create sysfs entries: */
431         err = pod_create_files2(&interface->dev);
432         if (err < 0)
433                 return err;
434
435         /* initialize audio system: */
436         err = line6_init_audio(line6);
437         if (err < 0)
438                 return err;
439
440         /* initialize MIDI subsystem: */
441         err = line6_init_midi(line6);
442         if (err < 0)
443                 return err;
444
445         /* initialize PCM subsystem: */
446         err = line6_init_pcm(line6, &pod_pcm_properties);
447         if (err < 0)
448                 return err;
449
450         /* register monitor control: */
451         err = snd_ctl_add(line6->card,
452                           snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
453         if (err < 0)
454                 return err;
455
456         /*
457            When the sound card is registered at this point, the PODxt Live
458            displays "Invalid Code Error 07", so we do it later in the event
459            handler.
460          */
461
462         if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) {
463                 pod->monitor_level = POD_system_invalid;
464
465                 /* initiate startup procedure: */
466                 pod_startup1(pod);
467         }
468
469         return 0;
470 }
471
472 /*
473          Init POD device (and clean up in case of failure).
474 */
475 int line6_pod_init(struct usb_interface *interface, struct usb_line6_pod *pod)
476 {
477         int err = pod_try_init(interface, pod);
478
479         if (err < 0)
480                 pod_destruct(interface);
481
482         return err;
483 }
484
485 /*
486         POD device disconnected.
487 */
488 void line6_pod_disconnect(struct usb_interface *interface)
489 {
490         struct usb_line6_pod *pod;
491
492         if (interface == NULL)
493                 return;
494         pod = usb_get_intfdata(interface);
495
496         if (pod != NULL) {
497                 struct snd_line6_pcm *line6pcm = pod->line6.line6pcm;
498                 struct device *dev = &interface->dev;
499
500                 if (line6pcm != NULL)
501                         line6_pcm_disconnect(line6pcm);
502
503                 if (dev != NULL) {
504                         /* remove sysfs entries: */
505                         device_remove_file(dev, &dev_attr_device_id);
506                         device_remove_file(dev, &dev_attr_firmware_version);
507                         device_remove_file(dev, &dev_attr_serial_number);
508                 }
509         }
510
511         pod_destruct(interface);
512 }