blob: 614e9dc2ad19d8d732e1db87756a43c05c0f7450 [file] [log] [blame]
Markus Grabner705ecec2009-02-27 19:43:04 -08001/*
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 "audio.h"
15#include "capture.h"
16#include "control.h"
17#include "playback.h"
18#include "pod.h"
19
20
21#define POD_SYSEX_CODE 3
22#define POD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */
23
24
25enum {
26 POD_SYSEX_CLIP = 0x0f,
27 POD_SYSEX_SAVE = 0x24,
28 POD_SYSEX_SYSTEM = 0x56,
29 POD_SYSEX_SYSTEMREQ = 0x57,
30 /* POD_SYSEX_UPDATE = 0x6c, */ /* software update! */
31 POD_SYSEX_STORE = 0x71,
32 POD_SYSEX_FINISH = 0x72,
33 POD_SYSEX_DUMPMEM = 0x73,
34 POD_SYSEX_DUMP = 0x74,
35 POD_SYSEX_DUMPREQ = 0x75
36 /* POD_SYSEX_DUMPMEM2 = 0x76 */ /* dumps entire internal memory of PODxt Pro */
37};
38
39enum {
40 POD_monitor_level = 0x04,
41 POD_routing = 0x05,
42 POD_tuner_mute = 0x13,
43 POD_tuner_freq = 0x15,
44 POD_tuner_note = 0x16,
45 POD_tuner_pitch = 0x17,
46 POD_system_invalid = 0x7fff
47};
48
49enum {
50 POD_DUMP_MEMORY = 2
51};
52
53enum {
54 POD_BUSY_READ,
55 POD_BUSY_WRITE,
56 POD_CHANNEL_DIRTY,
57 POD_SAVE_PRESSED,
58 POD_BUSY_MIDISEND
59};
60
61
62static struct snd_ratden pod_ratden = {
63 .num_min = 78125,
64 .num_max = 78125,
65 .num_step = 1,
66 .den = 2
67};
68
69static struct line6_pcm_properties pod_pcm_properties = {
70 .snd_line6_playback_hw = {
71 .info = (SNDRV_PCM_INFO_MMAP |
72 SNDRV_PCM_INFO_INTERLEAVED |
73 SNDRV_PCM_INFO_BLOCK_TRANSFER |
74 SNDRV_PCM_INFO_MMAP_VALID |
75 SNDRV_PCM_INFO_PAUSE |
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 = LINE6_ISO_PACKET_SIZE_MAX * POD_BYTES_PER_FRAME, /* at least one URB must fit into one period */
85 .period_bytes_max = 8192,
86 .periods_min = 1,
87 .periods_max = 1024
88 },
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 SNDRV_PCM_INFO_SYNC_START),
95 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
96 .rates = SNDRV_PCM_RATE_KNOT,
97 .rate_min = 39062,
98 .rate_max = 39063,
99 .channels_min = 2,
100 .channels_max = 2,
101 .buffer_bytes_max = 60000,
102 .period_bytes_min = LINE6_ISO_PACKET_SIZE_MAX * POD_BYTES_PER_FRAME, /* at least one URB must fit into one period */
103 .period_bytes_max = 8192,
104 .periods_min = 1,
105 .periods_max = 1024
106 },
107 .snd_line6_rates = {
108 .nrats = 1,
109 .rats = &pod_ratden
110 },
111 .bytes_per_frame = POD_BYTES_PER_FRAME
112};
113
114static const char pod_request_version[] = { 0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7 };
115static const char pod_request_channel[] = { 0xf0, 0x00, 0x01, 0x0c, 0x03, 0x75, 0xf7 };
116static const char pod_version_header [] = { 0xf2, 0x7e, 0x7f, 0x06, 0x02 };
117
118
119/*
120 Mark all parameters as dirty and notify waiting processes.
121*/
122static void pod_mark_batch_all_dirty(struct usb_line6_pod *pod)
123{
124 int i;
125
126 for(i = POD_CONTROL_SIZE; i--;)
127 set_bit(i, pod->param_dirty);
128}
129
130/*
131 Send an asynchronous request for the POD firmware version and device ID.
132*/
133static int pod_version_request_async(struct usb_line6_pod *pod)
134{
135 return line6_send_raw_message_async(&pod->line6, pod->buffer_versionreq, sizeof(pod_request_version));
136}
137
Markus Grabner705ecec2009-02-27 19:43:04 -0800138static void pod_create_files_work(struct work_struct *work)
139{
140 struct usb_line6_pod *pod = container_of(work, struct usb_line6_pod, create_files_work);
Markus Grabner705ecec2009-02-27 19:43:04 -0800141
142 pod_create_files(pod->firmware_version, pod->line6.properties->device_bit, pod->line6.ifcdev);
143}
144
145static void pod_startup_timeout(unsigned long arg)
146{
147 enum {
148 REQUEST_NONE,
149 REQUEST_DUMP,
150 REQUEST_VERSION
151 };
152
153 int request = REQUEST_NONE;
154 struct usb_line6_pod *pod = (struct usb_line6_pod *)arg;
155
156 if(pod->dumpreq.ok) {
157 if(!pod->versionreq_ok)
158 request = REQUEST_VERSION;
159 }
160 else {
161 if(pod->versionreq_ok)
162 request = REQUEST_DUMP;
163 else if(pod->startup_count++ & 1)
164 request = REQUEST_DUMP;
165 else
166 request = REQUEST_VERSION;
167 }
168
169 switch(request) {
170 case REQUEST_DUMP:
171 line6_dump_request_async(&pod->dumpreq, &pod->line6, 0);
172 break;
173
174 case REQUEST_VERSION:
175 pod_version_request_async(pod);
176 break;
177
178 default:
179 return;
180 }
181
182 line6_startup_delayed(&pod->dumpreq, 1, pod_startup_timeout, pod);
183}
184
185static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code, int size)
186{
187 return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code, size);
188}
189
190/*
191 Send channel dump data to the PODxt Pro.
192*/
193static void pod_dump(struct usb_line6_pod *pod, const unsigned char *data)
194{
195 int size = 1 + sizeof(pod->prog_data);
196 char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_DUMP, size);
197 if(!sysex) return;
198 sysex[SYSEX_DATA_OFS] = 5; /* Don't know what this is good for, but PODxt Pro transmits it, so we also do... */
199 memcpy(sysex + SYSEX_DATA_OFS + 1, data, sizeof(pod->prog_data));
200 line6_send_sysex_message(&pod->line6, sysex, size);
201 memcpy(&pod->prog_data, data, sizeof(pod->prog_data));
202 pod_mark_batch_all_dirty(pod);
203 kfree(sysex);
204}
205
206/*
207 Store parameter value in driver memory and mark it as dirty.
208*/
209static void pod_store_parameter(struct usb_line6_pod *pod, int param, int value)
210{
211 pod->prog_data.control[param] = value;
212 set_bit(param, pod->param_dirty);
213 pod->dirty = 1;
214}
215
216/*
217 Handle SAVE button
218*/
219static void pod_save_button_pressed(struct usb_line6_pod *pod, int type, int index)
220{
221 pod->dirty = 0;
222 set_bit(POD_SAVE_PRESSED, &pod->atomic_flags);
223}
224
225/*
226 Process a completely received message.
227*/
228void pod_process_message(struct usb_line6_pod *pod)
229{
230 const unsigned char *buf = pod->line6.buffer_message;
231
232 /* filter messages by type */
233 switch(buf[0] & 0xf0) {
234 case LINE6_PARAM_CHANGE:
235 case LINE6_PROGRAM_CHANGE:
236 case LINE6_SYSEX_BEGIN:
237 break; /* handle these further down */
238
239 default:
240 return; /* ignore all others */
241 }
242
243 /* process all remaining messages */
244 switch(buf[0]) {
245 case LINE6_PARAM_CHANGE | LINE6_CHANNEL_DEVICE:
246 pod_store_parameter(pod, buf[1], buf[2]);
247 /* intentionally no break here! */
248
249 case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
250 if((buf[1] == POD_amp_model_setup) || (buf[1] == POD_effect_setup)) /* these also affect other settings */
251 line6_dump_request_async(&pod->dumpreq, &pod->line6, 0);
252
253 break;
254
255 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
256 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
257 pod->channel_num = buf[1];
258 pod->dirty = 0;
259 set_bit(POD_CHANNEL_DIRTY, &pod->atomic_flags);
260 line6_dump_request_async(&pod->dumpreq, &pod->line6, 0);
261 break;
262
263 case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE:
264 case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN:
265 if(memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) == 0) {
266 switch(buf[5]) {
267 case POD_SYSEX_DUMP:
268 if(pod->line6.message_length == sizeof(pod->prog_data) + 7) {
269 switch(pod->dumpreq.in_progress) {
270 case LINE6_DUMP_CURRENT:
271 memcpy(&pod->prog_data, buf + 7, sizeof(pod->prog_data));
272 pod_mark_batch_all_dirty(pod);
273 pod->dumpreq.ok = 1;
274 break;
275
276 case POD_DUMP_MEMORY:
277 memcpy(&pod->prog_data_buf, buf + 7, sizeof(pod->prog_data_buf));
278 break;
279
280 default:
281 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown dump code %02X\n", pod->dumpreq.in_progress));
282 }
283
284 line6_dump_finished(&pod->dumpreq);
285 }
286 else
287 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "wrong size of channel dump message (%d instead of %d)\n",
288 pod->line6.message_length, (int)sizeof(pod->prog_data) + 7));
289
290 break;
291
292 case POD_SYSEX_SYSTEM: {
293 short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) | ((int)buf[9] << 4) | (int)buf[10];
294
295#define PROCESS_SYSTEM_PARAM(x) \
296 case POD_ ## x: \
297 pod->x.value = value; \
298 wake_up_interruptible(&pod->x.wait); \
299 break;
300
301 switch(buf[6]) {
302 PROCESS_SYSTEM_PARAM(monitor_level);
303 PROCESS_SYSTEM_PARAM(routing);
304 PROCESS_SYSTEM_PARAM(tuner_mute);
305 PROCESS_SYSTEM_PARAM(tuner_freq);
306 PROCESS_SYSTEM_PARAM(tuner_note);
307 PROCESS_SYSTEM_PARAM(tuner_pitch);
308
309#undef PROCESS_SYSTEM_PARAM
310
311 default:
312 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown tuner/system response %02X\n", buf[6]));
313 }
314
315 break;
316 }
317
318 case POD_SYSEX_FINISH:
319 /* do we need to respond to this? */
320 break;
321
322 case POD_SYSEX_SAVE:
323 pod_save_button_pressed(pod, buf[6], buf[7]);
324 break;
325
326 case POD_SYSEX_CLIP:
327 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "audio clipped\n"));
328 pod->clipping.value = 1;
329 wake_up_interruptible(&pod->clipping.wait);
330 break;
331
332 case POD_SYSEX_STORE:
333 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "message %02X not yet implemented\n", buf[5]));
334 break;
335
336 default:
337 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown sysex message %02X\n", buf[5]));
338 }
339 }
340 else if(memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) {
341 if(pod->versionreq_ok == 0) {
342 pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15];
343 pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) | (int)buf[10];
344 pod->versionreq_ok = 1;
345
346 /* Now we know the firmware version, so we schedule a bottom half
347 handler to create the special files: */
Markus Grabner705ecec2009-02-27 19:43:04 -0800348 INIT_WORK(&pod->create_files_work, pod_create_files_work);
Markus Grabner705ecec2009-02-27 19:43:04 -0800349 queue_work(line6_workqueue, &pod->create_files_work);
350 }
351 else
352 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "multiple firmware version message\n"));
353 }
354 else
355 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown sysex header\n"));
356
357 break;
358
359 case LINE6_SYSEX_END:
360 break;
361
362 default:
363 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "POD: unknown message %02X\n", buf[0]));
364 }
365}
366
367/*
368 Detect some cases that require a channel dump after sending a command to the
369 device. Important notes:
370 *) The actual dump request can not be sent here since we are not allowed to
371 wait for the completion of the first message in this context, and sending
372 the dump request before completion of the previous message leaves the POD
373 in an undefined state. The dump request will be sent when the echoed
374 commands are received.
375 *) This method fails if a param change message is "chopped" after the first
376 byte.
377*/
378void pod_midi_postprocess(struct usb_line6_pod *pod, unsigned char *data, int length)
379{
380 int i;
381
382 if(!pod->midi_postprocess)
383 return;
384
385 for(i = 0; i < length; ++i) {
386 if(data[i] == (LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST)) {
387 line6_invalidate_current(&pod->dumpreq);
388 break;
389 }
390 else if((data[i] == (LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST)) && (i < length - 1))
391 if((data[i + 1] == POD_amp_model_setup) || (data[i + 1] == POD_effect_setup)) {
392 line6_invalidate_current(&pod->dumpreq);
393 break;
394 }
395 }
396}
397
398/*
399 Send channel number (i.e., switch to a different sound).
400*/
Greg Kroah-Hartmanb702ed252009-02-27 20:45:03 -0800401static void pod_send_channel(struct usb_line6_pod *pod, int value)
Markus Grabner705ecec2009-02-27 19:43:04 -0800402{
403 line6_invalidate_current(&pod->dumpreq);
404
405 if(line6_send_program(&pod->line6, value) == 0)
406 pod->channel_num = value;
407 else
408 line6_dump_finished(&pod->dumpreq);
409}
410
411/*
412 Transmit PODxt Pro control parameter.
413*/
414void pod_transmit_parameter(struct usb_line6_pod *pod, int param, int value)
415{
416 if(line6_transmit_parameter(&pod->line6, param, value) == 0)
417 pod_store_parameter(pod, param, value);
418
419 if((param == POD_amp_model_setup) || (param == POD_effect_setup)) /* these also affect other settings */
420 line6_invalidate_current(&pod->dumpreq);
421}
422
423/*
424 Resolve value to memory location.
425*/
426static void pod_resolve(const char *buf, short block0, short block1, unsigned char *location)
427{
428 int value = simple_strtoul(buf, NULL, 10);
429 short block = (value < 0x40) ? block0 : block1;
430 value &= 0x3f;
431 location[0] = block >> 7;
432 location[1] = value | (block & 0x7f);
433}
434
435/*
436 Send command to store channel/effects setup/amp setup to PODxt Pro.
437*/
438static ssize_t pod_send_store_command(struct device *dev, const char *buf, size_t count, short block0, short block1)
439{
440 struct usb_interface *interface = to_usb_interface(dev);
441 struct usb_line6_pod *pod = usb_get_intfdata(interface);
442
443 int size = 3 + sizeof(pod->prog_data_buf);
444 char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_STORE, size);
445 if(!sysex) return 0;
446
447 sysex[SYSEX_DATA_OFS] = 5; /* see pod_dump() */
448 pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS + 1);
449 memcpy(sysex + SYSEX_DATA_OFS + 3, &pod->prog_data_buf, sizeof(pod->prog_data_buf));
450
451 line6_send_sysex_message(&pod->line6, sysex, size);
452 kfree(sysex);
453 /* needs some delay here on AMD64 platform */
454 return count;
455}
456
457/*
458 Send command to retrieve channel/effects setup/amp setup to PODxt Pro.
459*/
460static ssize_t pod_send_retrieve_command(struct device *dev, const char *buf, size_t count, short block0, short block1)
461{
462 struct usb_interface *interface = to_usb_interface(dev);
463 struct usb_line6_pod *pod = usb_get_intfdata(interface);
464
465 int size = 4;
466 char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_DUMPMEM, size);
467 if(!sysex) return 0;
468
469 pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS);
470 sysex[SYSEX_DATA_OFS + 2] = 0;
471 sysex[SYSEX_DATA_OFS + 3] = 0;
472 line6_dump_started(&pod->dumpreq, POD_DUMP_MEMORY);
473
474 if(line6_send_sysex_message(&pod->line6, sysex, size) < size)
475 line6_dump_finished(&pod->dumpreq);
476
477 kfree(sysex);
478 /* needs some delay here on AMD64 platform */
479 return count;
480}
481
482/*
483 Generic get name function.
484*/
485static ssize_t get_name_generic(struct usb_line6_pod *pod, const char *str, char *buf)
486{
487 int length = 0;
488 const char *p1;
489 char *p2;
490 char *last_non_space = buf;
491
492 int retval = line6_wait_dump(&pod->dumpreq, 0);
493 if(retval < 0) return retval;
494
495 for(p1 = str, p2 = buf; *p1; ++p1, ++p2) {
496 *p2 = *p1;
497 if(*p2 != ' ') last_non_space = p2;
498 if(++length == POD_NAME_LENGTH) break;
499 }
500
501 *(last_non_space + 1) = '\n';
502 return last_non_space - buf + 2;
503}
504
505/*
506 "read" request on "channel" special file.
507*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800508static ssize_t pod_get_channel(struct device *dev,
509 struct device_attribute *attr, char *buf)
Markus Grabner705ecec2009-02-27 19:43:04 -0800510{
511 struct usb_interface *interface = to_usb_interface(dev);
512 struct usb_line6_pod *pod = usb_get_intfdata(interface);
513 return sprintf(buf, "%d\n", pod->channel_num);
514}
515
516/*
517 "write" request on "channel" special file.
518*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800519static ssize_t pod_set_channel(struct device *dev,
520 struct device_attribute *attr,
521 const char *buf, size_t count)
Markus Grabner705ecec2009-02-27 19:43:04 -0800522{
523 struct usb_interface *interface = to_usb_interface(dev);
524 struct usb_line6_pod *pod = usb_get_intfdata(interface);
525 int value = simple_strtoul(buf, NULL, 10);
526 pod_send_channel(pod, value);
527 return count;
528}
529
530/*
531 "read" request on "name" special file.
532*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800533static ssize_t pod_get_name(struct device *dev, struct device_attribute *attr,
534 char *buf)
Markus Grabner705ecec2009-02-27 19:43:04 -0800535{
536 struct usb_interface *interface = to_usb_interface(dev);
537 struct usb_line6_pod *pod = usb_get_intfdata(interface);
538 return get_name_generic(pod, pod->prog_data.header + POD_NAME_OFFSET, buf);
539}
540
541/*
542 "read" request on "name" special file.
543*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800544static ssize_t pod_get_name_buf(struct device *dev,
545 struct device_attribute *attr, char *buf)
Markus Grabner705ecec2009-02-27 19:43:04 -0800546{
547 struct usb_interface *interface = to_usb_interface(dev);
548 struct usb_line6_pod *pod = usb_get_intfdata(interface);
549 return get_name_generic(pod, pod->prog_data_buf.header + POD_NAME_OFFSET, buf);
550}
551
552/*
553 "read" request on "dump" special file.
554*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800555static ssize_t pod_get_dump(struct device *dev, struct device_attribute *attr,
556 char *buf)
Markus Grabner705ecec2009-02-27 19:43:04 -0800557{
558 struct usb_interface *interface = to_usb_interface(dev);
559 struct usb_line6_pod *pod = usb_get_intfdata(interface);
560 int retval = line6_wait_dump(&pod->dumpreq, 0);
561 if(retval < 0) return retval;
562 memcpy(buf, &pod->prog_data, sizeof(pod->prog_data));
563 return sizeof(pod->prog_data);
564}
565
566/*
567 "write" request on "dump" special file.
568*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800569static ssize_t pod_set_dump(struct device *dev, struct device_attribute *attr,
570 const char *buf, size_t count)
Markus Grabner705ecec2009-02-27 19:43:04 -0800571{
572 struct usb_interface *interface = to_usb_interface(dev);
573 struct usb_line6_pod *pod = usb_get_intfdata(interface);
574
575 if(count != sizeof(pod->prog_data)) {
576 dev_err(pod->line6.ifcdev,
577 "data block must be exactly %d bytes\n",
578 (int)sizeof(pod->prog_data));
579 return -EINVAL;
580 }
581
582 pod_dump(pod, buf);
583 return sizeof(pod->prog_data);
584}
585
586/*
587 Request system parameter.
588 @param tuner non-zero, if code refers to a tuner parameter
589*/
590static ssize_t pod_get_system_param(struct usb_line6_pod *pod, char *buf, int code, struct ValueWait *param, int tuner, int sign)
591{
592 char *sysex;
593 int value;
594 static const int size = 1;
595 int retval = 0;
596 DECLARE_WAITQUEUE(wait, current);
597
598 if(((pod->prog_data.control[POD_tuner] & 0x40) == 0) && tuner)
599 return -ENODEV;
600
601 /* send value request to tuner: */
602 param->value = POD_system_invalid;
603 sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEMREQ, size);
604 if(!sysex) return 0;
605 sysex[SYSEX_DATA_OFS] = code;
606 line6_send_sysex_message(&pod->line6, sysex, size);
607 kfree(sysex);
608
609 /* wait for tuner to respond: */
610 add_wait_queue(&param->wait, &wait);
611 current->state = TASK_INTERRUPTIBLE;
612
613 while(param->value == POD_system_invalid) {
614 if(signal_pending(current)) {
615 retval = -ERESTARTSYS;
616 break;
617 }
618 else
619 schedule();
620 }
621
622 current->state = TASK_RUNNING;
623 remove_wait_queue(&param->wait, &wait);
624
625 if(retval < 0)
626 return retval;
627
628 value = sign ? (int)(signed short)param->value : (int)(unsigned short)param->value;
629 return sprintf(buf, "%d\n", value);
630}
631
632/*
633 Send system parameter.
634 @param tuner non-zero, if code refers to a tuner parameter
635*/
636static ssize_t pod_set_system_param(struct usb_line6_pod *pod, const char *buf, int count, int code, unsigned short mask, int tuner)
637{
638 char *sysex;
639 static const int size = 5;
640 unsigned short value;
641
642 if(((pod->prog_data.control[POD_tuner] & 0x40) == 0) && tuner)
643 return -EINVAL;
644
645 /* send value to tuner: */
646 sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
647 if(!sysex) return 0;
648 value = simple_strtoul(buf, NULL, 10) & mask;
649 sysex[SYSEX_DATA_OFS] = code;
650 sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
651 sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
652 sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
653 sysex[SYSEX_DATA_OFS + 4] = (value ) & 0x0f;
654 line6_send_sysex_message(&pod->line6, sysex, size);
655 kfree(sysex);
656 return count;
657}
658
659/*
660 "read" request on "dump_buf" special file.
661*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800662static ssize_t pod_get_dump_buf(struct device *dev,
663 struct device_attribute *attr, char *buf)
Markus Grabner705ecec2009-02-27 19:43:04 -0800664{
665 struct usb_interface *interface = to_usb_interface(dev);
666 struct usb_line6_pod *pod = usb_get_intfdata(interface);
667 int retval = line6_wait_dump(&pod->dumpreq, 0);
668 if(retval < 0) return retval;
669 memcpy(buf, &pod->prog_data_buf, sizeof(pod->prog_data_buf));
670 return sizeof(pod->prog_data_buf);
671}
672
673/*
674 "write" request on "dump_buf" special file.
675*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800676static ssize_t pod_set_dump_buf(struct device *dev,
677 struct device_attribute *attr,
678 const char *buf, size_t count)
Markus Grabner705ecec2009-02-27 19:43:04 -0800679{
680 struct usb_interface *interface = to_usb_interface(dev);
681 struct usb_line6_pod *pod = usb_get_intfdata(interface);
682
683 if(count != sizeof(pod->prog_data)) {
684 dev_err(pod->line6.ifcdev,
685 "data block must be exactly %d bytes\n",
686 (int)sizeof(pod->prog_data));
687 return -EINVAL;
688 }
689
690 memcpy(&pod->prog_data_buf, buf, sizeof(pod->prog_data));
691 return sizeof(pod->prog_data);
692}
693
694/*
695 "write" request on "finish" special file.
696*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800697static ssize_t pod_set_finish(struct device *dev,
698 struct device_attribute *attr,
699 const char *buf, size_t count)
Markus Grabner705ecec2009-02-27 19:43:04 -0800700{
701 struct usb_interface *interface = to_usb_interface(dev);
702 struct usb_line6_pod *pod = usb_get_intfdata(interface);
703 int size = 0;
704 char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_FINISH, size);
705 if(!sysex) return 0;
706 line6_send_sysex_message(&pod->line6, sysex, size);
707 kfree(sysex);
708 return count;
709}
710
711/*
712 "write" request on "store_channel" special file.
713*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800714static ssize_t pod_set_store_channel(struct device *dev,
715 struct device_attribute *attr,
716 const char *buf, size_t count)
Markus Grabner705ecec2009-02-27 19:43:04 -0800717{
718 return pod_send_store_command(dev, buf, count, 0x0000, 0x00c0);
719}
720
721/*
722 "write" request on "store_effects_setup" special file.
723*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800724static ssize_t pod_set_store_effects_setup(struct device *dev,
725 struct device_attribute *attr,
726 const char *buf, size_t count)
Markus Grabner705ecec2009-02-27 19:43:04 -0800727{
728 return pod_send_store_command(dev, buf, count, 0x0080, 0x0080);
729}
730
731/*
732 "write" request on "store_amp_setup" special file.
733*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800734static ssize_t pod_set_store_amp_setup(struct device *dev,
735 struct device_attribute *attr,
736 const char *buf, size_t count)
Markus Grabner705ecec2009-02-27 19:43:04 -0800737{
738 return pod_send_store_command(dev, buf, count, 0x0040, 0x0100);
739}
740
741/*
742 "write" request on "retrieve_channel" special file.
743*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800744static ssize_t pod_set_retrieve_channel(struct device *dev,
745 struct device_attribute *attr,
746 const char *buf, size_t count)
Markus Grabner705ecec2009-02-27 19:43:04 -0800747{
748 return pod_send_retrieve_command(dev, buf, count, 0x0000, 0x00c0);
749}
750
751/*
752 "write" request on "retrieve_effects_setup" special file.
753*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800754static ssize_t pod_set_retrieve_effects_setup(struct device *dev,
755 struct device_attribute *attr,
756 const char *buf, size_t count)
Markus Grabner705ecec2009-02-27 19:43:04 -0800757{
758 return pod_send_retrieve_command(dev, buf, count, 0x0080, 0x0080);
759}
760
761/*
762 "write" request on "retrieve_amp_setup" special file.
763*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800764static ssize_t pod_set_retrieve_amp_setup(struct device *dev,
765 struct device_attribute *attr,
766 const char *buf, size_t count)
Markus Grabner705ecec2009-02-27 19:43:04 -0800767{
768 return pod_send_retrieve_command(dev, buf, count, 0x0040, 0x0100);
769}
770
771/*
772 "read" request on "dirty" special file.
773*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800774static ssize_t pod_get_dirty(struct device *dev, struct device_attribute *attr,
775 char *buf)
Markus Grabner705ecec2009-02-27 19:43:04 -0800776{
777 struct usb_interface *interface = to_usb_interface(dev);
778 struct usb_line6_pod *pod = usb_get_intfdata(interface);
779 buf[0] = pod->dirty ? '1' : '0';
780 buf[1] = '\n';
781 return 2;
782}
783
784/*
785 "read" request on "midi_postprocess" special file.
786*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800787static ssize_t pod_get_midi_postprocess(struct device *dev,
788 struct device_attribute *attr,
789 char *buf)
Markus Grabner705ecec2009-02-27 19:43:04 -0800790{
791 struct usb_interface *interface = to_usb_interface(dev);
792 struct usb_line6_pod *pod = usb_get_intfdata(interface);
793 return sprintf(buf, "%d\n", pod->midi_postprocess);
794}
795
796/*
797 "write" request on "midi_postprocess" special file.
798*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800799static ssize_t pod_set_midi_postprocess(struct device *dev,
800 struct device_attribute *attr,
801 const char *buf, size_t count)
Markus Grabner705ecec2009-02-27 19:43:04 -0800802{
803 struct usb_interface *interface = to_usb_interface(dev);
804 struct usb_line6_pod *pod = usb_get_intfdata(interface);
805 int value = simple_strtoul(buf, NULL, 10);
806 pod->midi_postprocess = value ? 1 : 0;
807 return count;
808}
809
810/*
811 "read" request on "serial_number" special file.
812*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800813static ssize_t pod_get_serial_number(struct device *dev,
814 struct device_attribute *attr, char *buf)
Markus Grabner705ecec2009-02-27 19:43:04 -0800815{
816 struct usb_interface *interface = to_usb_interface(dev);
817 struct usb_line6_pod *pod = usb_get_intfdata(interface);
818 return sprintf(buf, "%d\n", pod->serial_number);
819}
820
821/*
822 "read" request on "firmware_version" special file.
823*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800824static ssize_t pod_get_firmware_version(struct device *dev,
825 struct device_attribute *attr,
826 char *buf)
Markus Grabner705ecec2009-02-27 19:43:04 -0800827{
828 struct usb_interface *interface = to_usb_interface(dev);
829 struct usb_line6_pod *pod = usb_get_intfdata(interface);
830 return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100, pod->firmware_version % 100);
831}
832
833/*
834 "read" request on "device_id" special file.
835*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800836static ssize_t pod_get_device_id(struct device *dev,
837 struct device_attribute *attr, char *buf)
Markus Grabner705ecec2009-02-27 19:43:04 -0800838{
839 struct usb_interface *interface = to_usb_interface(dev);
840 struct usb_line6_pod *pod = usb_get_intfdata(interface);
841 return sprintf(buf, "%d\n", pod->device_id);
842}
843
844/*
845 "read" request on "clip" special file.
846*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800847static ssize_t pod_wait_for_clip(struct device *dev,
848 struct device_attribute *attr, char *buf)
Markus Grabner705ecec2009-02-27 19:43:04 -0800849{
850 struct usb_interface *interface = to_usb_interface(dev);
851 struct usb_line6_pod *pod = usb_get_intfdata(interface);
852 int err = 0;
853 DECLARE_WAITQUEUE(wait, current);
854 pod->clipping.value = 0;
855 add_wait_queue(&pod->clipping.wait, &wait);
856 current->state = TASK_INTERRUPTIBLE;
857
858 while(pod->clipping.value == 0) {
859 if(signal_pending(current)) {
860 err = -ERESTARTSYS;
861 break;
862 }
863 else
864 schedule();
865 }
866
867 current->state = TASK_RUNNING;
868 remove_wait_queue(&pod->clipping.wait, &wait);
869 return err;
870}
871
872#define POD_GET_SYSTEM_PARAM(code, tuner, sign) \
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800873static ssize_t pod_get_ ## code(struct device *dev, \
874 struct device_attribute *attr, char *buf) \
Markus Grabner705ecec2009-02-27 19:43:04 -0800875{ \
876 struct usb_interface *interface = to_usb_interface(dev); \
877 struct usb_line6_pod *pod = usb_get_intfdata(interface); \
878 return pod_get_system_param(pod, buf, POD_ ## code, &pod->code, tuner, sign); \
879}
880
881#define POD_GET_SET_SYSTEM_PARAM(code, mask, tuner, sign) \
882POD_GET_SYSTEM_PARAM(code, tuner, sign) \
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800883static ssize_t pod_set_ ## code(struct device *dev, \
884 struct device_attribute *attr, const char *buf, \
885 size_t count) \
Markus Grabner705ecec2009-02-27 19:43:04 -0800886{ \
887 struct usb_interface *interface = to_usb_interface(dev); \
888 struct usb_line6_pod *pod = usb_get_intfdata(interface); \
889 return pod_set_system_param(pod, buf, count, POD_ ## code, mask, tuner); \
890}
891
892POD_GET_SET_SYSTEM_PARAM(monitor_level, 0xffff, 0, 0);
893POD_GET_SET_SYSTEM_PARAM(routing, 0x0003, 0, 0);
894POD_GET_SET_SYSTEM_PARAM(tuner_mute, 0x0001, 1, 0);
895POD_GET_SET_SYSTEM_PARAM(tuner_freq, 0xffff, 1, 0);
896POD_GET_SYSTEM_PARAM(tuner_note, 1, 1);
897POD_GET_SYSTEM_PARAM(tuner_pitch, 1, 1);
898
899#undef GET_SET_SYSTEM_PARAM
900#undef GET_SYSTEM_PARAM
901
902/* POD special files: */
903static DEVICE_ATTR(channel, S_IWUGO | S_IRUGO, pod_get_channel, pod_set_channel);
904static DEVICE_ATTR(clip, S_IRUGO, pod_wait_for_clip, line6_nop_write);
905static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
906static DEVICE_ATTR(dirty, S_IRUGO, pod_get_dirty, line6_nop_write);
907static DEVICE_ATTR(dump, S_IWUGO | S_IRUGO, pod_get_dump, pod_set_dump);
908static DEVICE_ATTR(dump_buf, S_IWUGO | S_IRUGO, pod_get_dump_buf, pod_set_dump_buf);
909static DEVICE_ATTR(finish, S_IWUGO, line6_nop_read, pod_set_finish);
910static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version, line6_nop_write);
911static DEVICE_ATTR(midi_postprocess, S_IWUGO | S_IRUGO, pod_get_midi_postprocess, pod_set_midi_postprocess);
912static DEVICE_ATTR(monitor_level, S_IWUGO | S_IRUGO, pod_get_monitor_level, pod_set_monitor_level);
913static DEVICE_ATTR(name, S_IRUGO, pod_get_name, line6_nop_write);
914static DEVICE_ATTR(name_buf, S_IRUGO, pod_get_name_buf, line6_nop_write);
915static DEVICE_ATTR(retrieve_amp_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_amp_setup);
916static DEVICE_ATTR(retrieve_channel, S_IWUGO, line6_nop_read, pod_set_retrieve_channel);
917static DEVICE_ATTR(retrieve_effects_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_effects_setup);
918static DEVICE_ATTR(routing, S_IWUGO | S_IRUGO, pod_get_routing, pod_set_routing);
919static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number, line6_nop_write);
920static DEVICE_ATTR(store_amp_setup, S_IWUGO, line6_nop_read, pod_set_store_amp_setup);
921static DEVICE_ATTR(store_channel, S_IWUGO, line6_nop_read, pod_set_store_channel);
922static DEVICE_ATTR(store_effects_setup, S_IWUGO, line6_nop_read, pod_set_store_effects_setup);
923static DEVICE_ATTR(tuner_freq, S_IWUGO | S_IRUGO, pod_get_tuner_freq, pod_set_tuner_freq);
924static DEVICE_ATTR(tuner_mute, S_IWUGO | S_IRUGO, pod_get_tuner_mute, pod_set_tuner_mute);
925static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write);
926static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write);
927
928#if CREATE_RAW_FILE
929static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
930#endif
931
932/*
933 POD destructor.
934*/
935static void pod_destruct(struct usb_interface *interface)
936{
937 struct usb_line6_pod *pod = usb_get_intfdata(interface);
938 struct usb_line6 *line6;
939
940 if(pod == NULL) return;
941 line6 = &pod->line6;
942 if(line6 == NULL) return;
943 line6_cleanup_audio(line6);
944
945 /* free dump request data: */
946 line6_dumpreq_destruct(&pod->dumpreq);
947
948 if(pod->buffer_versionreq) kfree(pod->buffer_versionreq);
949}
950
951/*
952 Create sysfs entries.
953*/
Greg Kroah-Hartmanb702ed252009-02-27 20:45:03 -0800954static int pod_create_files2(struct device *dev)
Markus Grabner705ecec2009-02-27 19:43:04 -0800955{
956 int err;
957
958 CHECK_RETURN(device_create_file(dev, &dev_attr_channel));
959 CHECK_RETURN(device_create_file(dev, &dev_attr_clip));
960 CHECK_RETURN(device_create_file(dev, &dev_attr_device_id));
961 CHECK_RETURN(device_create_file(dev, &dev_attr_dirty));
962 CHECK_RETURN(device_create_file(dev, &dev_attr_dump));
963 CHECK_RETURN(device_create_file(dev, &dev_attr_dump_buf));
964 CHECK_RETURN(device_create_file(dev, &dev_attr_finish));
965 CHECK_RETURN(device_create_file(dev, &dev_attr_firmware_version));
966 CHECK_RETURN(device_create_file(dev, &dev_attr_midi_postprocess));
967 CHECK_RETURN(device_create_file(dev, &dev_attr_monitor_level));
968 CHECK_RETURN(device_create_file(dev, &dev_attr_name));
969 CHECK_RETURN(device_create_file(dev, &dev_attr_name_buf));
970 CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_amp_setup));
971 CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_channel));
972 CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_effects_setup));
973 CHECK_RETURN(device_create_file(dev, &dev_attr_routing));
974 CHECK_RETURN(device_create_file(dev, &dev_attr_serial_number));
975 CHECK_RETURN(device_create_file(dev, &dev_attr_store_amp_setup));
976 CHECK_RETURN(device_create_file(dev, &dev_attr_store_channel));
977 CHECK_RETURN(device_create_file(dev, &dev_attr_store_effects_setup));
978 CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_freq));
979 CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_mute));
980 CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_note));
981 CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_pitch));
982
983#if CREATE_RAW_FILE
984 CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
985#endif
986
987 return 0;
988}
989
990/*
991 Init POD device.
992*/
993int pod_init(struct usb_interface *interface, struct usb_line6_pod *pod)
994{
995 int err;
996 struct usb_line6 *line6 = &pod->line6;
997
998 if((interface == NULL) || (pod == NULL)) return -ENODEV;
999
1000 pod->channel_num = 255;
1001
1002 /* initialize wait queues: */
1003 init_waitqueue_head(&pod->monitor_level.wait);
1004 init_waitqueue_head(&pod->routing.wait);
1005 init_waitqueue_head(&pod->tuner_mute.wait);
1006 init_waitqueue_head(&pod->tuner_freq.wait);
1007 init_waitqueue_head(&pod->tuner_note.wait);
1008 init_waitqueue_head(&pod->tuner_pitch.wait);
1009 init_waitqueue_head(&pod->clipping.wait);
1010
1011 memset(pod->param_dirty, 0xff, sizeof(pod->param_dirty));
1012
1013 /* initialize USB buffers: */
1014 err = line6_dumpreq_init(&pod->dumpreq, pod_request_channel, sizeof(pod_request_channel));
1015
1016 if(err < 0) {
1017 dev_err(&interface->dev, "Out of memory\n");
1018 pod_destruct(interface);
1019 return -ENOMEM;
1020 }
1021
1022 pod->buffer_versionreq = kmalloc(sizeof(pod_request_version), GFP_KERNEL);
1023
1024 if(pod->buffer_versionreq == NULL) {
1025 dev_err(&interface->dev, "Out of memory\n");
1026 pod_destruct(interface);
1027 return -ENOMEM;
1028 }
1029
1030 memcpy(pod->buffer_versionreq, pod_request_version, sizeof(pod_request_version));
1031
1032 /* create sysfs entries: */
1033 if((err = pod_create_files2(&interface->dev)) < 0) {
1034 pod_destruct(interface);
1035 return err;
1036 }
1037
1038 /* initialize audio system: */
1039 if((err = line6_init_audio(line6)) < 0) {
1040 pod_destruct(interface);
1041 return err;
1042 }
1043
1044 /* initialize MIDI subsystem: */
1045 if((err = line6_init_midi(line6)) < 0) {
1046 pod_destruct(interface);
1047 return err;
1048 }
1049
1050 /* initialize PCM subsystem: */
1051 if((err = line6_init_pcm(line6, &pod_pcm_properties)) < 0) {
1052 pod_destruct(interface);
1053 return err;
1054 }
1055
1056 /* register audio system: */
1057 if((err = line6_register_audio(line6)) < 0) {
1058 pod_destruct(interface);
1059 return err;
1060 }
1061
1062 if(pod->line6.properties->capabilities & LINE6_BIT_CONTROL) {
1063 /* query some data: */
1064 line6_startup_delayed(&pod->dumpreq, POD_STARTUP_DELAY, pod_startup_timeout, pod);
1065 line6_read_serial_number(&pod->line6, &pod->serial_number);
1066 }
1067
1068 return 0;
1069}
1070
1071/*
1072 POD device disconnected.
1073*/
1074void pod_disconnect(struct usb_interface *interface)
1075{
1076 struct usb_line6_pod *pod;
1077
1078 if(interface == NULL) return;
1079 pod = usb_get_intfdata(interface);
1080
1081 if(pod != NULL) {
1082 struct snd_line6_pcm *line6pcm = pod->line6.line6pcm;
1083 struct device *dev = &interface->dev;
1084
1085 if(line6pcm != NULL) {
1086 unlink_wait_clear_audio_out_urbs(line6pcm);
1087 unlink_wait_clear_audio_in_urbs(line6pcm);
1088 }
1089
1090 if(dev != NULL) {
1091 /* remove sysfs entries: */
1092 if(pod->versionreq_ok)
1093 pod_remove_files(pod->firmware_version, pod->line6.properties->device_bit, dev);
1094
1095 device_remove_file(dev, &dev_attr_channel);
1096 device_remove_file(dev, &dev_attr_clip);
1097 device_remove_file(dev, &dev_attr_device_id);
1098 device_remove_file(dev, &dev_attr_dirty);
1099 device_remove_file(dev, &dev_attr_dump);
1100 device_remove_file(dev, &dev_attr_dump_buf);
1101 device_remove_file(dev, &dev_attr_finish);
1102 device_remove_file(dev, &dev_attr_firmware_version);
1103 device_remove_file(dev, &dev_attr_midi_postprocess);
1104 device_remove_file(dev, &dev_attr_monitor_level);
1105 device_remove_file(dev, &dev_attr_name);
1106 device_remove_file(dev, &dev_attr_name_buf);
1107 device_remove_file(dev, &dev_attr_retrieve_amp_setup);
1108 device_remove_file(dev, &dev_attr_retrieve_channel);
1109 device_remove_file(dev, &dev_attr_retrieve_effects_setup);
1110 device_remove_file(dev, &dev_attr_routing);
1111 device_remove_file(dev, &dev_attr_serial_number);
1112 device_remove_file(dev, &dev_attr_store_amp_setup);
1113 device_remove_file(dev, &dev_attr_store_channel);
1114 device_remove_file(dev, &dev_attr_store_effects_setup);
1115 device_remove_file(dev, &dev_attr_tuner_freq);
1116 device_remove_file(dev, &dev_attr_tuner_mute);
1117 device_remove_file(dev, &dev_attr_tuner_note);
1118 device_remove_file(dev, &dev_attr_tuner_pitch);
1119
1120#if CREATE_RAW_FILE
1121 device_remove_file(dev, &dev_attr_raw);
1122#endif
1123 }
1124 }
1125
1126 pod_destruct(interface);
1127}