staging: line6: drop monitor_level sysfs attr
[deliverable/linux.git] / drivers / staging / line6 / pod.c
CommitLineData
705ececd 1/*
e1a164d7 2 * Line6 Linux USB driver - 0.9.1beta
705ececd 3 *
1027f476 4 * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
705ececd
MG
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
5a0e3ad6 12#include <linux/slab.h>
1027f476
MG
13#include <linux/wait.h>
14#include <sound/control.h>
5a0e3ad6 15
705ececd
MG
16#include "audio.h"
17#include "capture.h"
18#include "control.h"
1027f476 19#include "driver.h"
705ececd
MG
20#include "playback.h"
21#include "pod.h"
22
705ececd 23#define POD_SYSEX_CODE 3
e1a164d7 24#define POD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */
705ececd 25
e1a164d7 26/* *INDENT-OFF* */
705ececd
MG
27
28enum {
705ececd
MG
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
41enum {
42 POD_monitor_level = 0x04,
43 POD_routing = 0x05,
44 POD_tuner_mute = 0x13,
45 POD_tuner_freq = 0x15,
46 POD_tuner_note = 0x16,
47 POD_tuner_pitch = 0x17,
1027f476 48 POD_system_invalid = 0x10000
705ececd
MG
49};
50
e1a164d7
MG
51/* *INDENT-ON* */
52
705ececd
MG
53enum {
54 POD_DUMP_MEMORY = 2
55};
56
57enum {
58 POD_BUSY_READ,
59 POD_BUSY_WRITE,
60 POD_CHANNEL_DIRTY,
61 POD_SAVE_PRESSED,
62 POD_BUSY_MIDISEND
63};
64
705ececd
MG
65static struct snd_ratden pod_ratden = {
66 .num_min = 78125,
67 .num_max = 78125,
68 .num_step = 1,
69 .den = 2
70};
71
72static struct line6_pcm_properties pod_pcm_properties = {
1027f476 73 .snd_line6_playback_hw = {
e1a164d7
MG
74 .info = (SNDRV_PCM_INFO_MMAP |
75 SNDRV_PCM_INFO_INTERLEAVED |
76 SNDRV_PCM_INFO_BLOCK_TRANSFER |
77 SNDRV_PCM_INFO_MMAP_VALID |
78 SNDRV_PCM_INFO_PAUSE |
1027f476 79#ifdef CONFIG_PM
e1a164d7 80 SNDRV_PCM_INFO_RESUME |
1027f476 81#endif
e1a164d7
MG
82 SNDRV_PCM_INFO_SYNC_START),
83 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
84 .rates = SNDRV_PCM_RATE_KNOT,
85 .rate_min = 39062,
86 .rate_max = 39063,
87 .channels_min = 2,
88 .channels_max = 2,
89 .buffer_bytes_max = 60000,
90 .period_bytes_min = 64,
91 .period_bytes_max = 8192,
92 .periods_min = 1,
93 .periods_max = 1024},
1027f476 94 .snd_line6_capture_hw = {
e1a164d7
MG
95 .info = (SNDRV_PCM_INFO_MMAP |
96 SNDRV_PCM_INFO_INTERLEAVED |
97 SNDRV_PCM_INFO_BLOCK_TRANSFER |
98 SNDRV_PCM_INFO_MMAP_VALID |
1027f476 99#ifdef CONFIG_PM
e1a164d7 100 SNDRV_PCM_INFO_RESUME |
1027f476 101#endif
e1a164d7
MG
102 SNDRV_PCM_INFO_SYNC_START),
103 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
104 .rates = SNDRV_PCM_RATE_KNOT,
105 .rate_min = 39062,
106 .rate_max = 39063,
107 .channels_min = 2,
108 .channels_max = 2,
109 .buffer_bytes_max = 60000,
110 .period_bytes_min = 64,
111 .period_bytes_max = 8192,
112 .periods_min = 1,
113 .periods_max = 1024},
705ececd 114 .snd_line6_rates = {
e1a164d7
MG
115 .nrats = 1,
116 .rats = &pod_ratden},
705ececd
MG
117 .bytes_per_frame = POD_BYTES_PER_FRAME
118};
119
1027f476
MG
120static const char pod_request_channel[] = {
121 0xf0, 0x00, 0x01, 0x0c, 0x03, 0x75, 0xf7
122};
123
e1a164d7 124static const char pod_version_header[] = {
1027f476
MG
125 0xf2, 0x7e, 0x7f, 0x06, 0x02
126};
127
1027f476
MG
128/* forward declarations: */
129static void pod_startup2(unsigned long data);
130static void pod_startup3(struct usb_line6_pod *pod);
131static void pod_startup4(struct usb_line6_pod *pod);
705ececd 132
e1a164d7
MG
133static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
134 int size)
705ececd 135{
e1a164d7
MG
136 return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code,
137 size);
705ececd
MG
138}
139
705ececd 140/*
b772fe9e 141 Store parameter value in driver memory.
705ececd
MG
142*/
143static void pod_store_parameter(struct usb_line6_pod *pod, int param, int value)
144{
145 pod->prog_data.control[param] = value;
705ececd
MG
146}
147
148/*
1027f476 149 Handle SAVE button.
705ececd 150*/
e1a164d7
MG
151static void pod_save_button_pressed(struct usb_line6_pod *pod, int type,
152 int index)
705ececd 153{
705ececd
MG
154 set_bit(POD_SAVE_PRESSED, &pod->atomic_flags);
155}
156
157/*
158 Process a completely received message.
159*/
1027f476 160void line6_pod_process_message(struct usb_line6_pod *pod)
705ececd
MG
161{
162 const unsigned char *buf = pod->line6.buffer_message;
163
164 /* filter messages by type */
0fdef36a 165 switch (buf[0] & 0xf0) {
705ececd
MG
166 case LINE6_PARAM_CHANGE:
167 case LINE6_PROGRAM_CHANGE:
168 case LINE6_SYSEX_BEGIN:
e1a164d7 169 break; /* handle these further down */
705ececd
MG
170
171 default:
e1a164d7 172 return; /* ignore all others */
705ececd
MG
173 }
174
175 /* process all remaining messages */
0fdef36a 176 switch (buf[0]) {
705ececd
MG
177 case LINE6_PARAM_CHANGE | LINE6_CHANNEL_DEVICE:
178 pod_store_parameter(pod, buf[1], buf[2]);
179 /* intentionally no break here! */
180
181 case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
0fdef36a
GKH
182 if ((buf[1] == POD_amp_model_setup) ||
183 (buf[1] == POD_effect_setup))
184 /* these also affect other settings */
e1a164d7
MG
185 line6_dump_request_async(&pod->dumpreq, &pod->line6, 0,
186 LINE6_DUMP_CURRENT);
705ececd
MG
187
188 break;
189
190 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
191 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
705ececd 192 set_bit(POD_CHANNEL_DIRTY, &pod->atomic_flags);
e1a164d7
MG
193 line6_dump_request_async(&pod->dumpreq, &pod->line6, 0,
194 LINE6_DUMP_CURRENT);
705ececd
MG
195 break;
196
197 case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE:
198 case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN:
0fdef36a
GKH
199 if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) == 0) {
200 switch (buf[5]) {
705ececd 201 case POD_SYSEX_DUMP:
e1a164d7
MG
202 if (pod->line6.message_length ==
203 sizeof(pod->prog_data) + 7) {
0fdef36a 204 switch (pod->dumpreq.in_progress) {
705ececd 205 case LINE6_DUMP_CURRENT:
e1a164d7
MG
206 memcpy(&pod->prog_data, buf + 7,
207 sizeof(pod->prog_data));
705ececd
MG
208 break;
209
210 case POD_DUMP_MEMORY:
e1a164d7
MG
211 memcpy(&pod->prog_data_buf,
212 buf + 7,
213 sizeof
214 (pod->prog_data_buf));
705ececd
MG
215 break;
216
217 default:
e00d33cb
SH
218 dev_dbg(pod->line6.ifcdev,
219 "unknown dump code %02X\n",
220 pod->dumpreq.in_progress);
705ececd
MG
221 }
222
223 line6_dump_finished(&pod->dumpreq);
1027f476 224 pod_startup3(pod);
0fdef36a 225 } else
e00d33cb
SH
226 dev_dbg(pod->line6.ifcdev,
227 "wrong size of channel dump message (%d instead of %d)\n",
228 pod->line6.message_length,
229 (int)sizeof(pod->prog_data) +
230 7);
705ececd
MG
231
232 break;
233
e1a164d7
MG
234 case POD_SYSEX_SYSTEM:{
235 short value =
236 ((int)buf[7] << 12) | ((int)buf[8]
237 << 8) |
238 ((int)buf[9] << 4) | (int)buf[10];
705ececd
MG
239
240#define PROCESS_SYSTEM_PARAM(x) \
241 case POD_ ## x: \
242 pod->x.value = value; \
1027f476 243 wake_up(&pod->x.wait); \
705ececd
MG
244 break;
245
e1a164d7 246 switch (buf[6]) {
410cefa7
SH
247 case POD_monitor_level:
248 pod->monitor_level.value = value;
249 break;
250
e1a164d7
MG
251 PROCESS_SYSTEM_PARAM(routing);
252 PROCESS_SYSTEM_PARAM
253 (tuner_mute);
254 PROCESS_SYSTEM_PARAM
255 (tuner_freq);
256 PROCESS_SYSTEM_PARAM
257 (tuner_note);
258 PROCESS_SYSTEM_PARAM
259 (tuner_pitch);
705ececd
MG
260
261#undef PROCESS_SYSTEM_PARAM
262
e1a164d7 263 default:
e00d33cb
SH
264 dev_dbg(pod->line6.ifcdev,
265 "unknown tuner/system response %02X\n",
266 buf[6]);
e1a164d7 267 }
705ececd 268
e1a164d7
MG
269 break;
270 }
705ececd
MG
271
272 case POD_SYSEX_FINISH:
273 /* do we need to respond to this? */
274 break;
275
276 case POD_SYSEX_SAVE:
277 pod_save_button_pressed(pod, buf[6], buf[7]);
278 break;
279
705ececd 280 case POD_SYSEX_STORE:
e00d33cb
SH
281 dev_dbg(pod->line6.ifcdev,
282 "message %02X not yet implemented\n",
283 buf[5]);
705ececd
MG
284 break;
285
286 default:
e00d33cb
SH
287 dev_dbg(pod->line6.ifcdev,
288 "unknown sysex message %02X\n",
289 buf[5]);
705ececd 290 }
e1a164d7
MG
291 } else
292 if (memcmp
293 (buf, pod_version_header,
294 sizeof(pod_version_header)) == 0) {
295 pod->firmware_version =
296 buf[13] * 100 + buf[14] * 10 + buf[15];
297 pod->device_id =
298 ((int)buf[8] << 16) | ((int)buf[9] << 8) | (int)
299 buf[10];
1027f476 300 pod_startup4(pod);
0fdef36a 301 } else
e00d33cb 302 dev_dbg(pod->line6.ifcdev, "unknown sysex header\n");
705ececd
MG
303
304 break;
305
306 case LINE6_SYSEX_END:
307 break;
308
309 default:
e00d33cb
SH
310 dev_dbg(pod->line6.ifcdev, "POD: unknown message %02X\n",
311 buf[0]);
705ececd
MG
312 }
313}
314
315/*
316 Detect some cases that require a channel dump after sending a command to the
317 device. Important notes:
318 *) The actual dump request can not be sent here since we are not allowed to
319 wait for the completion of the first message in this context, and sending
320 the dump request before completion of the previous message leaves the POD
321 in an undefined state. The dump request will be sent when the echoed
322 commands are received.
323 *) This method fails if a param change message is "chopped" after the first
324 byte.
325*/
e1a164d7
MG
326void line6_pod_midi_postprocess(struct usb_line6_pod *pod, unsigned char *data,
327 int length)
705ececd
MG
328{
329 int i;
330
0fdef36a 331 if (!pod->midi_postprocess)
705ececd
MG
332 return;
333
0fdef36a
GKH
334 for (i = 0; i < length; ++i) {
335 if (data[i] == (LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST)) {
705ececd
MG
336 line6_invalidate_current(&pod->dumpreq);
337 break;
e1a164d7
MG
338 } else
339 if ((data[i] == (LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST))
340 && (i < length - 1))
341 if ((data[i + 1] == POD_amp_model_setup)
342 || (data[i + 1] == POD_effect_setup)) {
705ececd
MG
343 line6_invalidate_current(&pod->dumpreq);
344 break;
345 }
346 }
347}
348
705ececd
MG
349/*
350 Transmit PODxt Pro control parameter.
351*/
e1a164d7 352void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param,
5b9bd2ad 353 u8 value)
705ececd 354{
0fdef36a 355 if (line6_transmit_parameter(&pod->line6, param, value) == 0)
705ececd
MG
356 pod_store_parameter(pod, param, value);
357
e1a164d7 358 if ((param == POD_amp_model_setup) || (param == POD_effect_setup)) /* these also affect other settings */
705ececd
MG
359 line6_invalidate_current(&pod->dumpreq);
360}
361
362/*
363 Resolve value to memory location.
364*/
e1a164d7
MG
365static int pod_resolve(const char *buf, short block0, short block1,
366 unsigned char *location)
705ececd 367{
1d0e834d 368 u8 value;
7e4d5c13
SB
369 short block;
370 int ret;
371
1d0e834d 372 ret = kstrtou8(buf, 10, &value);
7e4d5c13
SB
373 if (ret)
374 return ret;
375
376 block = (value < 0x40) ? block0 : block1;
705ececd
MG
377 value &= 0x3f;
378 location[0] = block >> 7;
379 location[1] = value | (block & 0x7f);
7e4d5c13 380 return 0;
705ececd
MG
381}
382
383/*
384 Send command to store channel/effects setup/amp setup to PODxt Pro.
385*/
e1a164d7
MG
386static ssize_t pod_send_store_command(struct device *dev, const char *buf,
387 size_t count, short block0, short block1)
705ececd
MG
388{
389 struct usb_interface *interface = to_usb_interface(dev);
390 struct usb_line6_pod *pod = usb_get_intfdata(interface);
7e4d5c13 391 int ret;
705ececd
MG
392 int size = 3 + sizeof(pod->prog_data_buf);
393 char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_STORE, size);
7e4d5c13 394
0fdef36a
GKH
395 if (!sysex)
396 return 0;
705ececd 397
980688f9
SH
398 /* Don't know what this is good for, but PODxt Pro transmits it, so we
399 * also do... */
400 sysex[SYSEX_DATA_OFS] = 5;
7e4d5c13
SB
401 ret = pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS + 1);
402 if (ret) {
403 kfree(sysex);
404 return ret;
405 }
406
e1a164d7
MG
407 memcpy(sysex + SYSEX_DATA_OFS + 3, &pod->prog_data_buf,
408 sizeof(pod->prog_data_buf));
705ececd
MG
409
410 line6_send_sysex_message(&pod->line6, sysex, size);
411 kfree(sysex);
412 /* needs some delay here on AMD64 platform */
413 return count;
414}
415
416/*
417 Send command to retrieve channel/effects setup/amp setup to PODxt Pro.
418*/
e1a164d7
MG
419static ssize_t pod_send_retrieve_command(struct device *dev, const char *buf,
420 size_t count, short block0,
421 short block1)
705ececd
MG
422{
423 struct usb_interface *interface = to_usb_interface(dev);
424 struct usb_line6_pod *pod = usb_get_intfdata(interface);
7e4d5c13 425 int ret;
705ececd
MG
426 int size = 4;
427 char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_DUMPMEM, size);
0fdef36a
GKH
428
429 if (!sysex)
430 return 0;
705ececd 431
7e4d5c13
SB
432 ret = pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS);
433 if (ret) {
434 kfree(sysex);
435 return ret;
436 }
705ececd
MG
437 sysex[SYSEX_DATA_OFS + 2] = 0;
438 sysex[SYSEX_DATA_OFS + 3] = 0;
439 line6_dump_started(&pod->dumpreq, POD_DUMP_MEMORY);
440
0fdef36a 441 if (line6_send_sysex_message(&pod->line6, sysex, size) < size)
705ececd
MG
442 line6_dump_finished(&pod->dumpreq);
443
444 kfree(sysex);
445 /* needs some delay here on AMD64 platform */
446 return count;
447}
448
449/*
450 Generic get name function.
451*/
e1a164d7
MG
452static ssize_t get_name_generic(struct usb_line6_pod *pod, const char *str,
453 char *buf)
705ececd
MG
454{
455 int length = 0;
456 const char *p1;
457 char *p2;
458 char *last_non_space = buf;
459
1027f476 460 int retval = line6_dump_wait_interruptible(&pod->dumpreq);
0fdef36a
GKH
461 if (retval < 0)
462 return retval;
705ececd 463
0fdef36a 464 for (p1 = str, p2 = buf; *p1; ++p1, ++p2) {
705ececd 465 *p2 = *p1;
0fdef36a
GKH
466 if (*p2 != ' ')
467 last_non_space = p2;
468 if (++length == POD_NAME_LENGTH)
469 break;
705ececd
MG
470 }
471
472 *(last_non_space + 1) = '\n';
473 return last_non_space - buf + 2;
474}
475
705ececd
MG
476/*
477 "read" request on "name" special file.
478*/
77491e52
GKH
479static ssize_t pod_get_name(struct device *dev, struct device_attribute *attr,
480 char *buf)
705ececd
MG
481{
482 struct usb_interface *interface = to_usb_interface(dev);
483 struct usb_line6_pod *pod = usb_get_intfdata(interface);
e1a164d7
MG
484 return get_name_generic(pod, pod->prog_data.header + POD_NAME_OFFSET,
485 buf);
705ececd
MG
486}
487
488/*
489 "read" request on "name" special file.
490*/
77491e52
GKH
491static ssize_t pod_get_name_buf(struct device *dev,
492 struct device_attribute *attr, char *buf)
705ececd
MG
493{
494 struct usb_interface *interface = to_usb_interface(dev);
495 struct usb_line6_pod *pod = usb_get_intfdata(interface);
e1a164d7
MG
496 return get_name_generic(pod,
497 pod->prog_data_buf.header + POD_NAME_OFFSET,
498 buf);
705ececd
MG
499}
500
705ececd 501/*
1027f476
MG
502 Identify system parameters related to the tuner.
503*/
504static bool pod_is_tuner(int code)
505{
506 return
e1a164d7
MG
507 (code == POD_tuner_mute) ||
508 (code == POD_tuner_freq) ||
509 (code == POD_tuner_note) || (code == POD_tuner_pitch);
1027f476
MG
510}
511
512/*
513 Get system parameter (as integer).
705ececd
MG
514 @param tuner non-zero, if code refers to a tuner parameter
515*/
e1a164d7
MG
516static int pod_get_system_param_int(struct usb_line6_pod *pod, int *value,
517 int code, struct ValueWait *param, int sign)
705ececd
MG
518{
519 char *sysex;
705ececd
MG
520 static const int size = 1;
521 int retval = 0;
705ececd 522
e1a164d7
MG
523 if (((pod->prog_data.control[POD_tuner] & 0x40) == 0)
524 && pod_is_tuner(code))
705ececd
MG
525 return -ENODEV;
526
1027f476 527 /* send value request to device: */
705ececd
MG
528 param->value = POD_system_invalid;
529 sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEMREQ, size);
1027f476 530
0fdef36a 531 if (!sysex)
1027f476
MG
532 return -ENOMEM;
533
705ececd
MG
534 sysex[SYSEX_DATA_OFS] = code;
535 line6_send_sysex_message(&pod->line6, sysex, size);
536 kfree(sysex);
537
1027f476 538 /* wait for device to respond: */
e1a164d7
MG
539 retval =
540 wait_event_interruptible(param->wait,
541 param->value != POD_system_invalid);
705ececd 542
1027f476
MG
543 if (retval < 0)
544 return retval;
705ececd 545
e1a164d7
MG
546 *value = sign ? (int)(signed short)param->value : (int)(unsigned short)
547 param->value;
705ececd 548
e1a164d7
MG
549 if (*value == POD_system_invalid)
550 *value = 0; /* don't report uninitialized values */
1027f476
MG
551
552 return 0;
553}
554
555/*
556 Get system parameter (as string).
557 @param tuner non-zero, if code refers to a tuner parameter
558*/
e1a164d7
MG
559static ssize_t pod_get_system_param_string(struct usb_line6_pod *pod, char *buf,
560 int code, struct ValueWait *param,
561 int sign)
1027f476
MG
562{
563 int retval, value = 0;
564 retval = pod_get_system_param_int(pod, &value, code, param, sign);
565
e1a164d7 566 if (retval < 0)
705ececd
MG
567 return retval;
568
705ececd
MG
569 return sprintf(buf, "%d\n", value);
570}
571
572/*
1027f476 573 Send system parameter (from integer).
705ececd
MG
574 @param tuner non-zero, if code refers to a tuner parameter
575*/
e1a164d7
MG
576static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
577 int code)
705ececd
MG
578{
579 char *sysex;
580 static const int size = 5;
705ececd 581
e1a164d7
MG
582 if (((pod->prog_data.control[POD_tuner] & 0x40) == 0)
583 && pod_is_tuner(code))
705ececd
MG
584 return -EINVAL;
585
586 /* send value to tuner: */
587 sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
0fdef36a 588 if (!sysex)
1027f476 589 return -ENOMEM;
705ececd
MG
590 sysex[SYSEX_DATA_OFS] = code;
591 sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
e1a164d7
MG
592 sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
593 sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
594 sysex[SYSEX_DATA_OFS + 4] = (value) & 0x0f;
705ececd
MG
595 line6_send_sysex_message(&pod->line6, sysex, size);
596 kfree(sysex);
1027f476
MG
597 return 0;
598}
599
600/*
601 Send system parameter (from string).
602 @param tuner non-zero, if code refers to a tuner parameter
603*/
e1a164d7
MG
604static ssize_t pod_set_system_param_string(struct usb_line6_pod *pod,
605 const char *buf, int count, int code,
606 unsigned short mask)
1027f476
MG
607{
608 int retval;
609 unsigned short value = simple_strtoul(buf, NULL, 10) & mask;
610 retval = pod_set_system_param_int(pod, value, code);
611 return (retval < 0) ? retval : count;
705ececd
MG
612}
613
705ececd
MG
614/*
615 "write" request on "finish" special file.
616*/
77491e52
GKH
617static ssize_t pod_set_finish(struct device *dev,
618 struct device_attribute *attr,
619 const char *buf, size_t count)
705ececd
MG
620{
621 struct usb_interface *interface = to_usb_interface(dev);
622 struct usb_line6_pod *pod = usb_get_intfdata(interface);
623 int size = 0;
624 char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_FINISH, size);
0fdef36a
GKH
625 if (!sysex)
626 return 0;
705ececd
MG
627 line6_send_sysex_message(&pod->line6, sysex, size);
628 kfree(sysex);
629 return count;
630}
631
632/*
633 "write" request on "store_channel" special file.
634*/
77491e52
GKH
635static ssize_t pod_set_store_channel(struct device *dev,
636 struct device_attribute *attr,
637 const char *buf, size_t count)
705ececd
MG
638{
639 return pod_send_store_command(dev, buf, count, 0x0000, 0x00c0);
640}
641
642/*
643 "write" request on "store_effects_setup" special file.
644*/
77491e52
GKH
645static ssize_t pod_set_store_effects_setup(struct device *dev,
646 struct device_attribute *attr,
647 const char *buf, size_t count)
705ececd
MG
648{
649 return pod_send_store_command(dev, buf, count, 0x0080, 0x0080);
650}
651
652/*
653 "write" request on "store_amp_setup" special file.
654*/
77491e52
GKH
655static ssize_t pod_set_store_amp_setup(struct device *dev,
656 struct device_attribute *attr,
657 const char *buf, size_t count)
705ececd
MG
658{
659 return pod_send_store_command(dev, buf, count, 0x0040, 0x0100);
660}
661
662/*
663 "write" request on "retrieve_channel" special file.
664*/
77491e52
GKH
665static ssize_t pod_set_retrieve_channel(struct device *dev,
666 struct device_attribute *attr,
667 const char *buf, size_t count)
705ececd
MG
668{
669 return pod_send_retrieve_command(dev, buf, count, 0x0000, 0x00c0);
670}
671
672/*
673 "write" request on "retrieve_effects_setup" special file.
674*/
77491e52
GKH
675static ssize_t pod_set_retrieve_effects_setup(struct device *dev,
676 struct device_attribute *attr,
677 const char *buf, size_t count)
705ececd
MG
678{
679 return pod_send_retrieve_command(dev, buf, count, 0x0080, 0x0080);
680}
681
682/*
683 "write" request on "retrieve_amp_setup" special file.
684*/
77491e52
GKH
685static ssize_t pod_set_retrieve_amp_setup(struct device *dev,
686 struct device_attribute *attr,
687 const char *buf, size_t count)
705ececd
MG
688{
689 return pod_send_retrieve_command(dev, buf, count, 0x0040, 0x0100);
690}
691
705ececd
MG
692/*
693 "read" request on "midi_postprocess" special file.
694*/
77491e52
GKH
695static ssize_t pod_get_midi_postprocess(struct device *dev,
696 struct device_attribute *attr,
697 char *buf)
705ececd
MG
698{
699 struct usb_interface *interface = to_usb_interface(dev);
700 struct usb_line6_pod *pod = usb_get_intfdata(interface);
701 return sprintf(buf, "%d\n", pod->midi_postprocess);
702}
703
704/*
705 "write" request on "midi_postprocess" special file.
706*/
77491e52
GKH
707static ssize_t pod_set_midi_postprocess(struct device *dev,
708 struct device_attribute *attr,
709 const char *buf, size_t count)
705ececd
MG
710{
711 struct usb_interface *interface = to_usb_interface(dev);
712 struct usb_line6_pod *pod = usb_get_intfdata(interface);
06501787 713 u8 value;
7e4d5c13
SB
714 int ret;
715
06501787 716 ret = kstrtou8(buf, 10, &value);
7e4d5c13
SB
717 if (ret)
718 return ret;
719
705ececd
MG
720 pod->midi_postprocess = value ? 1 : 0;
721 return count;
722}
723
724/*
725 "read" request on "serial_number" special file.
726*/
77491e52
GKH
727static ssize_t pod_get_serial_number(struct device *dev,
728 struct device_attribute *attr, char *buf)
705ececd
MG
729{
730 struct usb_interface *interface = to_usb_interface(dev);
731 struct usb_line6_pod *pod = usb_get_intfdata(interface);
732 return sprintf(buf, "%d\n", pod->serial_number);
733}
734
735/*
736 "read" request on "firmware_version" special file.
737*/
77491e52
GKH
738static ssize_t pod_get_firmware_version(struct device *dev,
739 struct device_attribute *attr,
740 char *buf)
705ececd
MG
741{
742 struct usb_interface *interface = to_usb_interface(dev);
743 struct usb_line6_pod *pod = usb_get_intfdata(interface);
0fdef36a
GKH
744 return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
745 pod->firmware_version % 100);
705ececd
MG
746}
747
748/*
749 "read" request on "device_id" special file.
750*/
77491e52
GKH
751static ssize_t pod_get_device_id(struct device *dev,
752 struct device_attribute *attr, char *buf)
705ececd
MG
753{
754 struct usb_interface *interface = to_usb_interface(dev);
755 struct usb_line6_pod *pod = usb_get_intfdata(interface);
756 return sprintf(buf, "%d\n", pod->device_id);
757}
758
1027f476
MG
759/*
760 POD startup procedure.
761 This is a sequence of functions with special requirements (e.g., must
762 not run immediately after initialization, must not run in interrupt
763 context). After the last one has finished, the device is ready to use.
764*/
765
766static void pod_startup1(struct usb_line6_pod *pod)
767{
e1a164d7 768 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
1027f476
MG
769
770 /* delay startup procedure: */
e1a164d7
MG
771 line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
772 (unsigned long)pod);
1027f476
MG
773}
774
775static void pod_startup2(unsigned long data)
776{
777 struct usb_line6_pod *pod = (struct usb_line6_pod *)data;
e1a164d7
MG
778
779 /* schedule another startup procedure until startup is complete: */
780 if (pod->startup_progress >= POD_STARTUP_LAST)
781 return;
782
783 pod->startup_progress = POD_STARTUP_DUMPREQ;
784 line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
785 (unsigned long)pod);
1027f476
MG
786
787 /* current channel dump: */
e1a164d7
MG
788 line6_dump_request_async(&pod->dumpreq, &pod->line6, 0,
789 LINE6_DUMP_CURRENT);
1027f476
MG
790}
791
792static void pod_startup3(struct usb_line6_pod *pod)
793{
794 struct usb_line6 *line6 = &pod->line6;
e1a164d7 795 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
1027f476
MG
796
797 /* request firmware version: */
798 line6_version_request_async(line6);
705ececd
MG
799}
800
1027f476
MG
801static void pod_startup4(struct usb_line6_pod *pod)
802{
e1a164d7 803 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
1027f476
MG
804
805 /* schedule work for global work queue: */
806 schedule_work(&pod->startup_work);
807}
808
809static void pod_startup5(struct work_struct *work)
810{
e1a164d7
MG
811 struct usb_line6_pod *pod =
812 container_of(work, struct usb_line6_pod, startup_work);
1027f476
MG
813 struct usb_line6 *line6 = &pod->line6;
814
e1a164d7 815 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
1027f476
MG
816
817 /* serial number: */
818 line6_read_serial_number(&pod->line6, &pod->serial_number);
819
820 /* ALSA audio interface: */
821 line6_register_audio(line6);
822
823 /* device files: */
e1a164d7
MG
824 line6_pod_create_files(pod->firmware_version,
825 line6->properties->device_bit, line6->ifcdev);
1027f476
MG
826}
827
828#define POD_GET_SYSTEM_PARAM(code, sign) \
77491e52
GKH
829static ssize_t pod_get_ ## code(struct device *dev, \
830 struct device_attribute *attr, char *buf) \
705ececd
MG
831{ \
832 struct usb_interface *interface = to_usb_interface(dev); \
833 struct usb_line6_pod *pod = usb_get_intfdata(interface); \
1027f476
MG
834 return pod_get_system_param_string(pod, buf, POD_ ## code, \
835 &pod->code, sign); \
705ececd
MG
836}
837
1027f476
MG
838#define POD_GET_SET_SYSTEM_PARAM(code, mask, sign) \
839POD_GET_SYSTEM_PARAM(code, sign) \
77491e52 840static ssize_t pod_set_ ## code(struct device *dev, \
0fdef36a
GKH
841 struct device_attribute *attr, \
842 const char *buf, size_t count) \
705ececd
MG
843{ \
844 struct usb_interface *interface = to_usb_interface(dev); \
845 struct usb_line6_pod *pod = usb_get_intfdata(interface); \
1027f476 846 return pod_set_system_param_string(pod, buf, count, POD_ ## code, mask); \
705ececd
MG
847}
848
1027f476
MG
849POD_GET_SET_SYSTEM_PARAM(routing, 0x0003, 0);
850POD_GET_SET_SYSTEM_PARAM(tuner_mute, 0x0001, 0);
851POD_GET_SET_SYSTEM_PARAM(tuner_freq, 0xffff, 0);
852POD_GET_SYSTEM_PARAM(tuner_note, 1);
853POD_GET_SYSTEM_PARAM(tuner_pitch, 1);
705ececd
MG
854
855#undef GET_SET_SYSTEM_PARAM
856#undef GET_SYSTEM_PARAM
857
858/* POD special files: */
705ececd 859static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
a3a972a0 860static DEVICE_ATTR(finish, S_IWUSR, line6_nop_read, pod_set_finish);
e1a164d7
MG
861static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version,
862 line6_nop_write);
a3a972a0 863static DEVICE_ATTR(midi_postprocess, S_IWUSR | S_IRUGO,
e1a164d7 864 pod_get_midi_postprocess, pod_set_midi_postprocess);
705ececd
MG
865static DEVICE_ATTR(name, S_IRUGO, pod_get_name, line6_nop_write);
866static DEVICE_ATTR(name_buf, S_IRUGO, pod_get_name_buf, line6_nop_write);
a3a972a0 867static DEVICE_ATTR(retrieve_amp_setup, S_IWUSR, line6_nop_read,
e1a164d7 868 pod_set_retrieve_amp_setup);
a3a972a0 869static DEVICE_ATTR(retrieve_channel, S_IWUSR, line6_nop_read,
e1a164d7 870 pod_set_retrieve_channel);
a3a972a0 871static DEVICE_ATTR(retrieve_effects_setup, S_IWUSR, line6_nop_read,
e1a164d7 872 pod_set_retrieve_effects_setup);
a3a972a0 873static DEVICE_ATTR(routing, S_IWUSR | S_IRUGO, pod_get_routing,
e1a164d7
MG
874 pod_set_routing);
875static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number,
876 line6_nop_write);
a3a972a0 877static DEVICE_ATTR(store_amp_setup, S_IWUSR, line6_nop_read,
e1a164d7 878 pod_set_store_amp_setup);
a3a972a0 879static DEVICE_ATTR(store_channel, S_IWUSR, line6_nop_read,
e1a164d7 880 pod_set_store_channel);
a3a972a0 881static DEVICE_ATTR(store_effects_setup, S_IWUSR, line6_nop_read,
e1a164d7 882 pod_set_store_effects_setup);
a3a972a0 883static DEVICE_ATTR(tuner_freq, S_IWUSR | S_IRUGO, pod_get_tuner_freq,
e1a164d7 884 pod_set_tuner_freq);
a3a972a0 885static DEVICE_ATTR(tuner_mute, S_IWUSR | S_IRUGO, pod_get_tuner_mute,
e1a164d7 886 pod_set_tuner_mute);
705ececd
MG
887static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write);
888static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write);
889
1027f476 890#ifdef CONFIG_LINE6_USB_RAW
a3a972a0 891static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw);
705ececd
MG
892#endif
893
1027f476
MG
894/* control info callback */
895static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
896 struct snd_ctl_elem_info *uinfo)
897{
898 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
899 uinfo->count = 1;
900 uinfo->value.integer.min = 0;
901 uinfo->value.integer.max = 65535;
902 return 0;
903}
904
905/* control get callback */
906static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
907 struct snd_ctl_elem_value *ucontrol)
908{
909 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
910 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
911 ucontrol->value.integer.value[0] = pod->monitor_level.value;
912 return 0;
913}
914
915/* control put callback */
916static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
917 struct snd_ctl_elem_value *ucontrol)
918{
919 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
920 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
921
e1a164d7 922 if (ucontrol->value.integer.value[0] == pod->monitor_level.value)
1027f476
MG
923 return 0;
924
925 pod->monitor_level.value = ucontrol->value.integer.value[0];
e1a164d7
MG
926 pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
927 POD_monitor_level);
1027f476
MG
928 return 1;
929}
930
931/* control definition */
932static struct snd_kcontrol_new pod_control_monitor = {
933 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
934 .name = "Monitor Playback Volume",
935 .index = 0,
936 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
937 .info = snd_pod_control_monitor_info,
938 .get = snd_pod_control_monitor_get,
939 .put = snd_pod_control_monitor_put
940};
941
705ececd
MG
942/*
943 POD destructor.
944*/
945static void pod_destruct(struct usb_interface *interface)
946{
947 struct usb_line6_pod *pod = usb_get_intfdata(interface);
705ececd 948
0fdef36a
GKH
949 if (pod == NULL)
950 return;
188e6645 951 line6_cleanup_audio(&pod->line6);
705ececd 952
e1a164d7
MG
953 del_timer(&pod->startup_timer);
954 cancel_work_sync(&pod->startup_work);
955
705ececd
MG
956 /* free dump request data: */
957 line6_dumpreq_destruct(&pod->dumpreq);
705ececd
MG
958}
959
960/*
961 Create sysfs entries.
962*/
b702ed25 963static int pod_create_files2(struct device *dev)
705ececd
MG
964{
965 int err;
966
705ececd 967 CHECK_RETURN(device_create_file(dev, &dev_attr_device_id));
705ececd
MG
968 CHECK_RETURN(device_create_file(dev, &dev_attr_finish));
969 CHECK_RETURN(device_create_file(dev, &dev_attr_firmware_version));
970 CHECK_RETURN(device_create_file(dev, &dev_attr_midi_postprocess));
705ececd
MG
971 CHECK_RETURN(device_create_file(dev, &dev_attr_name));
972 CHECK_RETURN(device_create_file(dev, &dev_attr_name_buf));
973 CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_amp_setup));
974 CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_channel));
975 CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_effects_setup));
976 CHECK_RETURN(device_create_file(dev, &dev_attr_routing));
977 CHECK_RETURN(device_create_file(dev, &dev_attr_serial_number));
978 CHECK_RETURN(device_create_file(dev, &dev_attr_store_amp_setup));
979 CHECK_RETURN(device_create_file(dev, &dev_attr_store_channel));
980 CHECK_RETURN(device_create_file(dev, &dev_attr_store_effects_setup));
981 CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_freq));
982 CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_mute));
983 CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_note));
984 CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_pitch));
985
1027f476 986#ifdef CONFIG_LINE6_USB_RAW
705ececd
MG
987 CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
988#endif
989
990 return 0;
991}
992
993/*
1027f476 994 Try to init POD device.
705ececd 995*/
e1a164d7
MG
996static int pod_try_init(struct usb_interface *interface,
997 struct usb_line6_pod *pod)
705ececd
MG
998{
999 int err;
1000 struct usb_line6 *line6 = &pod->line6;
1001
e1a164d7
MG
1002 init_timer(&pod->startup_timer);
1003 INIT_WORK(&pod->startup_work, pod_startup5);
1004
0fdef36a
GKH
1005 if ((interface == NULL) || (pod == NULL))
1006 return -ENODEV;
705ececd 1007
705ececd 1008 /* initialize wait queues: */
705ececd
MG
1009 init_waitqueue_head(&pod->routing.wait);
1010 init_waitqueue_head(&pod->tuner_mute.wait);
1011 init_waitqueue_head(&pod->tuner_freq.wait);
1012 init_waitqueue_head(&pod->tuner_note.wait);
1013 init_waitqueue_head(&pod->tuner_pitch.wait);
705ececd 1014
705ececd 1015 /* initialize USB buffers: */
0fdef36a
GKH
1016 err = line6_dumpreq_init(&pod->dumpreq, pod_request_channel,
1017 sizeof(pod_request_channel));
1018 if (err < 0) {
705ececd 1019 dev_err(&interface->dev, "Out of memory\n");
705ececd
MG
1020 return -ENOMEM;
1021 }
1022
705ececd 1023 /* create sysfs entries: */
0fdef36a 1024 err = pod_create_files2(&interface->dev);
027360c5 1025 if (err < 0)
705ececd 1026 return err;
705ececd
MG
1027
1028 /* initialize audio system: */
0fdef36a 1029 err = line6_init_audio(line6);
027360c5 1030 if (err < 0)
705ececd 1031 return err;
705ececd
MG
1032
1033 /* initialize MIDI subsystem: */
0fdef36a 1034 err = line6_init_midi(line6);
027360c5 1035 if (err < 0)
705ececd 1036 return err;
705ececd
MG
1037
1038 /* initialize PCM subsystem: */
0fdef36a 1039 err = line6_init_pcm(line6, &pod_pcm_properties);
027360c5 1040 if (err < 0)
705ececd 1041 return err;
705ececd 1042
1027f476 1043 /* register monitor control: */
027360c5
GKH
1044 err = snd_ctl_add(line6->card,
1045 snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
1046 if (err < 0)
705ececd 1047 return err;
705ececd 1048
1027f476 1049 /*
e1a164d7
MG
1050 When the sound card is registered at this point, the PODxt Live
1051 displays "Invalid Code Error 07", so we do it later in the event
1052 handler.
1053 */
1027f476 1054
0fdef36a 1055 if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) {
1027f476
MG
1056 pod->monitor_level.value = POD_system_invalid;
1057
1058 /* initiate startup procedure: */
1059 pod_startup1(pod);
705ececd
MG
1060 }
1061
1062 return 0;
1063}
1064
1027f476
MG
1065/*
1066 Init POD device (and clean up in case of failure).
1067*/
1068int line6_pod_init(struct usb_interface *interface, struct usb_line6_pod *pod)
1069{
1070 int err = pod_try_init(interface, pod);
1071
027360c5 1072 if (err < 0)
1027f476 1073 pod_destruct(interface);
1027f476
MG
1074
1075 return err;
1076}
1077
705ececd
MG
1078/*
1079 POD device disconnected.
1080*/
1027f476 1081void line6_pod_disconnect(struct usb_interface *interface)
705ececd
MG
1082{
1083 struct usb_line6_pod *pod;
1084
0fdef36a
GKH
1085 if (interface == NULL)
1086 return;
705ececd
MG
1087 pod = usb_get_intfdata(interface);
1088
0fdef36a 1089 if (pod != NULL) {
705ececd
MG
1090 struct snd_line6_pcm *line6pcm = pod->line6.line6pcm;
1091 struct device *dev = &interface->dev;
1092
027360c5 1093 if (line6pcm != NULL)
1027f476 1094 line6_pcm_disconnect(line6pcm);
705ececd 1095
0fdef36a 1096 if (dev != NULL) {
705ececd 1097 /* remove sysfs entries: */
e1a164d7
MG
1098 line6_pod_remove_files(pod->firmware_version,
1099 pod->line6.
1100 properties->device_bit, dev);
705ececd 1101
705ececd 1102 device_remove_file(dev, &dev_attr_device_id);
705ececd
MG
1103 device_remove_file(dev, &dev_attr_finish);
1104 device_remove_file(dev, &dev_attr_firmware_version);
1105 device_remove_file(dev, &dev_attr_midi_postprocess);
705ececd
MG
1106 device_remove_file(dev, &dev_attr_name);
1107 device_remove_file(dev, &dev_attr_name_buf);
1108 device_remove_file(dev, &dev_attr_retrieve_amp_setup);
1109 device_remove_file(dev, &dev_attr_retrieve_channel);
e1a164d7
MG
1110 device_remove_file(dev,
1111 &dev_attr_retrieve_effects_setup);
705ececd
MG
1112 device_remove_file(dev, &dev_attr_routing);
1113 device_remove_file(dev, &dev_attr_serial_number);
1114 device_remove_file(dev, &dev_attr_store_amp_setup);
1115 device_remove_file(dev, &dev_attr_store_channel);
1116 device_remove_file(dev, &dev_attr_store_effects_setup);
1117 device_remove_file(dev, &dev_attr_tuner_freq);
1118 device_remove_file(dev, &dev_attr_tuner_mute);
1119 device_remove_file(dev, &dev_attr_tuner_note);
1120 device_remove_file(dev, &dev_attr_tuner_pitch);
1121
1027f476 1122#ifdef CONFIG_LINE6_USB_RAW
705ececd
MG
1123 device_remove_file(dev, &dev_attr_raw);
1124#endif
1125 }
1126 }
1127
1128 pod_destruct(interface);
1129}
This page took 0.531868 seconds and 5 git commands to generate.