staging: line6: drop pod prog_data buffers
[firefly-linux-kernel-4.4.55.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_request_channel[] = {
115         0xf0, 0x00, 0x01, 0x0c, 0x03, 0x75, 0xf7
116 };
117
118 static const char pod_version_header[] = {
119         0xf2, 0x7e, 0x7f, 0x06, 0x02
120 };
121
122 /* forward declarations: */
123 static void pod_startup2(unsigned long data);
124 static void pod_startup3(struct usb_line6_pod *pod);
125 static void pod_startup4(struct usb_line6_pod *pod);
126
127 static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
128                                     int size)
129 {
130         return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code,
131                                         size);
132 }
133
134 /*
135         Handle SAVE button.
136 */
137 static void pod_save_button_pressed(struct usb_line6_pod *pod, int type,
138                                     int index)
139 {
140         set_bit(POD_SAVE_PRESSED, &pod->atomic_flags);
141 }
142
143 /*
144         Process a completely received message.
145 */
146 void line6_pod_process_message(struct usb_line6_pod *pod)
147 {
148         const unsigned char *buf = pod->line6.buffer_message;
149
150         /* filter messages by type */
151         switch (buf[0] & 0xf0) {
152         case LINE6_PARAM_CHANGE:
153         case LINE6_PROGRAM_CHANGE:
154         case LINE6_SYSEX_BEGIN:
155                 break;          /* handle these further down */
156
157         default:
158                 return;         /* ignore all others */
159         }
160
161         /* process all remaining messages */
162         switch (buf[0]) {
163         case LINE6_PARAM_CHANGE | LINE6_CHANNEL_DEVICE:
164         case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
165                 break;
166
167         case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
168         case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
169                 set_bit(POD_CHANNEL_DIRTY, &pod->atomic_flags);
170                 line6_dump_request_async(&pod->dumpreq, &pod->line6, 0,
171                                          LINE6_DUMP_CURRENT);
172                 break;
173
174         case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE:
175         case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN:
176                 if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) == 0) {
177                         switch (buf[5]) {
178                         case POD_SYSEX_DUMP:
179                                 line6_dump_finished(&pod->dumpreq);
180                                 pod_startup3(pod);
181                                 break;
182
183                         case POD_SYSEX_SYSTEM:{
184                                         short value =
185                                             ((int)buf[7] << 12) | ((int)buf[8]
186                                                                    << 8) |
187                                             ((int)buf[9] << 4) | (int)buf[10];
188
189                                         if (buf[6] == POD_monitor_level)
190                                                 pod->monitor_level = value;
191                                         break;
192                                 }
193
194                         case POD_SYSEX_FINISH:
195                                 /* do we need to respond to this? */
196                                 break;
197
198                         case POD_SYSEX_SAVE:
199                                 pod_save_button_pressed(pod, buf[6], buf[7]);
200                                 break;
201
202                         case POD_SYSEX_STORE:
203                                 dev_dbg(pod->line6.ifcdev,
204                                         "message %02X not yet implemented\n",
205                                         buf[5]);
206                                 break;
207
208                         default:
209                                 dev_dbg(pod->line6.ifcdev,
210                                         "unknown sysex message %02X\n",
211                                         buf[5]);
212                         }
213                 } else
214                     if (memcmp
215                         (buf, pod_version_header,
216                          sizeof(pod_version_header)) == 0) {
217                         pod->firmware_version =
218                             buf[13] * 100 + buf[14] * 10 + buf[15];
219                         pod->device_id =
220                             ((int)buf[8] << 16) | ((int)buf[9] << 8) | (int)
221                             buf[10];
222                         pod_startup4(pod);
223                 } else
224                         dev_dbg(pod->line6.ifcdev, "unknown sysex header\n");
225
226                 break;
227
228         case LINE6_SYSEX_END:
229                 break;
230
231         default:
232                 dev_dbg(pod->line6.ifcdev, "POD: unknown message %02X\n",
233                         buf[0]);
234         }
235 }
236
237 /*
238         Transmit PODxt Pro control parameter.
239 */
240 void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param,
241                                   u8 value)
242 {
243         line6_transmit_parameter(&pod->line6, param, value);
244 }
245
246 /*
247         Send system parameter (from integer).
248 */
249 static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
250                                     int code)
251 {
252         char *sysex;
253         static const int size = 5;
254
255         sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
256         if (!sysex)
257                 return -ENOMEM;
258         sysex[SYSEX_DATA_OFS] = code;
259         sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
260         sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
261         sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
262         sysex[SYSEX_DATA_OFS + 4] = (value) & 0x0f;
263         line6_send_sysex_message(&pod->line6, sysex, size);
264         kfree(sysex);
265         return 0;
266 }
267
268 /*
269         "read" request on "serial_number" special file.
270 */
271 static ssize_t pod_get_serial_number(struct device *dev,
272                                      struct device_attribute *attr, char *buf)
273 {
274         struct usb_interface *interface = to_usb_interface(dev);
275         struct usb_line6_pod *pod = usb_get_intfdata(interface);
276         return sprintf(buf, "%d\n", pod->serial_number);
277 }
278
279 /*
280         "read" request on "firmware_version" special file.
281 */
282 static ssize_t pod_get_firmware_version(struct device *dev,
283                                         struct device_attribute *attr,
284                                         char *buf)
285 {
286         struct usb_interface *interface = to_usb_interface(dev);
287         struct usb_line6_pod *pod = usb_get_intfdata(interface);
288         return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
289                        pod->firmware_version % 100);
290 }
291
292 /*
293         "read" request on "device_id" special file.
294 */
295 static ssize_t pod_get_device_id(struct device *dev,
296                                  struct device_attribute *attr, char *buf)
297 {
298         struct usb_interface *interface = to_usb_interface(dev);
299         struct usb_line6_pod *pod = usb_get_intfdata(interface);
300         return sprintf(buf, "%d\n", pod->device_id);
301 }
302
303 /*
304         POD startup procedure.
305         This is a sequence of functions with special requirements (e.g., must
306         not run immediately after initialization, must not run in interrupt
307         context). After the last one has finished, the device is ready to use.
308 */
309
310 static void pod_startup1(struct usb_line6_pod *pod)
311 {
312         CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
313
314         /* delay startup procedure: */
315         line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
316                           (unsigned long)pod);
317 }
318
319 static void pod_startup2(unsigned long data)
320 {
321         struct usb_line6_pod *pod = (struct usb_line6_pod *)data;
322
323         /* schedule another startup procedure until startup is complete: */
324         if (pod->startup_progress >= POD_STARTUP_LAST)
325                 return;
326
327         pod->startup_progress = POD_STARTUP_DUMPREQ;
328         line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
329                           (unsigned long)pod);
330
331         /* current channel dump: */
332         line6_dump_request_async(&pod->dumpreq, &pod->line6, 0,
333                                  LINE6_DUMP_CURRENT);
334 }
335
336 static void pod_startup3(struct usb_line6_pod *pod)
337 {
338         struct usb_line6 *line6 = &pod->line6;
339         CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
340
341         /* request firmware version: */
342         line6_version_request_async(line6);
343 }
344
345 static void pod_startup4(struct usb_line6_pod *pod)
346 {
347         CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
348
349         /* schedule work for global work queue: */
350         schedule_work(&pod->startup_work);
351 }
352
353 static void pod_startup5(struct work_struct *work)
354 {
355         struct usb_line6_pod *pod =
356             container_of(work, struct usb_line6_pod, startup_work);
357         struct usb_line6 *line6 = &pod->line6;
358
359         CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
360
361         /* serial number: */
362         line6_read_serial_number(&pod->line6, &pod->serial_number);
363
364         /* ALSA audio interface: */
365         line6_register_audio(line6);
366 }
367
368 /* POD special files: */
369 static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
370 static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version,
371                    line6_nop_write);
372 static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number,
373                    line6_nop_write);
374
375 /* control info callback */
376 static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
377                                         struct snd_ctl_elem_info *uinfo)
378 {
379         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
380         uinfo->count = 1;
381         uinfo->value.integer.min = 0;
382         uinfo->value.integer.max = 65535;
383         return 0;
384 }
385
386 /* control get callback */
387 static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
388                                        struct snd_ctl_elem_value *ucontrol)
389 {
390         struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
391         struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
392         ucontrol->value.integer.value[0] = pod->monitor_level;
393         return 0;
394 }
395
396 /* control put callback */
397 static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
398                                        struct snd_ctl_elem_value *ucontrol)
399 {
400         struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
401         struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
402
403         if (ucontrol->value.integer.value[0] == pod->monitor_level)
404                 return 0;
405
406         pod->monitor_level = ucontrol->value.integer.value[0];
407         pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
408                                  POD_monitor_level);
409         return 1;
410 }
411
412 /* control definition */
413 static struct snd_kcontrol_new pod_control_monitor = {
414         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
415         .name = "Monitor Playback Volume",
416         .index = 0,
417         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
418         .info = snd_pod_control_monitor_info,
419         .get = snd_pod_control_monitor_get,
420         .put = snd_pod_control_monitor_put
421 };
422
423 /*
424         POD destructor.
425 */
426 static void pod_destruct(struct usb_interface *interface)
427 {
428         struct usb_line6_pod *pod = usb_get_intfdata(interface);
429
430         if (pod == NULL)
431                 return;
432         line6_cleanup_audio(&pod->line6);
433
434         del_timer(&pod->startup_timer);
435         cancel_work_sync(&pod->startup_work);
436
437         /* free dump request data: */
438         line6_dumpreq_destruct(&pod->dumpreq);
439 }
440
441 /*
442         Create sysfs entries.
443 */
444 static int pod_create_files2(struct device *dev)
445 {
446         int err;
447
448         CHECK_RETURN(device_create_file(dev, &dev_attr_device_id));
449         CHECK_RETURN(device_create_file(dev, &dev_attr_firmware_version));
450         CHECK_RETURN(device_create_file(dev, &dev_attr_serial_number));
451         return 0;
452 }
453
454 /*
455          Try to init POD device.
456 */
457 static int pod_try_init(struct usb_interface *interface,
458                         struct usb_line6_pod *pod)
459 {
460         int err;
461         struct usb_line6 *line6 = &pod->line6;
462
463         init_timer(&pod->startup_timer);
464         INIT_WORK(&pod->startup_work, pod_startup5);
465
466         if ((interface == NULL) || (pod == NULL))
467                 return -ENODEV;
468
469         /* initialize USB buffers: */
470         err = line6_dumpreq_init(&pod->dumpreq, pod_request_channel,
471                                  sizeof(pod_request_channel));
472         if (err < 0) {
473                 dev_err(&interface->dev, "Out of memory\n");
474                 return -ENOMEM;
475         }
476
477         /* create sysfs entries: */
478         err = pod_create_files2(&interface->dev);
479         if (err < 0)
480                 return err;
481
482         /* initialize audio system: */
483         err = line6_init_audio(line6);
484         if (err < 0)
485                 return err;
486
487         /* initialize MIDI subsystem: */
488         err = line6_init_midi(line6);
489         if (err < 0)
490                 return err;
491
492         /* initialize PCM subsystem: */
493         err = line6_init_pcm(line6, &pod_pcm_properties);
494         if (err < 0)
495                 return err;
496
497         /* register monitor control: */
498         err = snd_ctl_add(line6->card,
499                           snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
500         if (err < 0)
501                 return err;
502
503         /*
504            When the sound card is registered at this point, the PODxt Live
505            displays "Invalid Code Error 07", so we do it later in the event
506            handler.
507          */
508
509         if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) {
510                 pod->monitor_level = POD_system_invalid;
511
512                 /* initiate startup procedure: */
513                 pod_startup1(pod);
514         }
515
516         return 0;
517 }
518
519 /*
520          Init POD device (and clean up in case of failure).
521 */
522 int line6_pod_init(struct usb_interface *interface, struct usb_line6_pod *pod)
523 {
524         int err = pod_try_init(interface, pod);
525
526         if (err < 0)
527                 pod_destruct(interface);
528
529         return err;
530 }
531
532 /*
533         POD device disconnected.
534 */
535 void line6_pod_disconnect(struct usb_interface *interface)
536 {
537         struct usb_line6_pod *pod;
538
539         if (interface == NULL)
540                 return;
541         pod = usb_get_intfdata(interface);
542
543         if (pod != NULL) {
544                 struct snd_line6_pcm *line6pcm = pod->line6.line6pcm;
545                 struct device *dev = &interface->dev;
546
547                 if (line6pcm != NULL)
548                         line6_pcm_disconnect(line6pcm);
549
550                 if (dev != NULL) {
551                         /* remove sysfs entries: */
552                         device_remove_file(dev, &dev_attr_device_id);
553                         device_remove_file(dev, &dev_attr_firmware_version);
554                         device_remove_file(dev, &dev_attr_serial_number);
555                 }
556         }
557
558         pod_destruct(interface);
559 }