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