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