xref: /openbmc/linux/sound/usb/line6/pod.c (revision 4a3fad70)
1 /*
2  * Line 6 Linux USB driver
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 <linux/interrupt.h>
15 #include <linux/module.h>
16 #include <linux/usb.h>
17 
18 #include <sound/core.h>
19 #include <sound/control.h>
20 
21 #include "capture.h"
22 #include "driver.h"
23 #include "playback.h"
24 
25 /*
26 	Locate name in binary program dump
27 */
28 #define	POD_NAME_OFFSET 0
29 #define	POD_NAME_LENGTH 16
30 
31 /*
32 	Other constants
33 */
34 #define POD_CONTROL_SIZE 0x80
35 #define POD_BUFSIZE_DUMPREQ 7
36 #define POD_STARTUP_DELAY 1000
37 
38 /*
39 	Stages of POD startup procedure
40 */
41 enum {
42 	POD_STARTUP_INIT = 1,
43 	POD_STARTUP_VERSIONREQ,
44 	POD_STARTUP_WORKQUEUE,
45 	POD_STARTUP_SETUP,
46 	POD_STARTUP_LAST = POD_STARTUP_SETUP - 1
47 };
48 
49 enum {
50 	LINE6_BASSPODXT,
51 	LINE6_BASSPODXTLIVE,
52 	LINE6_BASSPODXTPRO,
53 	LINE6_POCKETPOD,
54 	LINE6_PODXT,
55 	LINE6_PODXTLIVE_POD,
56 	LINE6_PODXTPRO,
57 };
58 
59 struct usb_line6_pod {
60 	/* Generic Line 6 USB data */
61 	struct usb_line6 line6;
62 
63 	/* Instrument monitor level */
64 	int monitor_level;
65 
66 	/* Timer for device initialization */
67 	struct timer_list startup_timer;
68 
69 	/* Work handler for device initialization */
70 	struct work_struct startup_work;
71 
72 	/* Current progress in startup procedure */
73 	int startup_progress;
74 
75 	/* Serial number of device */
76 	u32 serial_number;
77 
78 	/* Firmware version (x 100) */
79 	int firmware_version;
80 
81 	/* Device ID */
82 	int device_id;
83 };
84 
85 #define POD_SYSEX_CODE 3
86 
87 /* *INDENT-OFF* */
88 
89 enum {
90 	POD_SYSEX_SAVE      = 0x24,
91 	POD_SYSEX_SYSTEM    = 0x56,
92 	POD_SYSEX_SYSTEMREQ = 0x57,
93 	/* POD_SYSEX_UPDATE    = 0x6c, */  /* software update! */
94 	POD_SYSEX_STORE     = 0x71,
95 	POD_SYSEX_FINISH    = 0x72,
96 	POD_SYSEX_DUMPMEM   = 0x73,
97 	POD_SYSEX_DUMP      = 0x74,
98 	POD_SYSEX_DUMPREQ   = 0x75
99 
100 	/* dumps entire internal memory of PODxt Pro */
101 	/* POD_SYSEX_DUMPMEM2  = 0x76 */
102 };
103 
104 enum {
105 	POD_MONITOR_LEVEL  = 0x04,
106 	POD_SYSTEM_INVALID = 0x10000
107 };
108 
109 /* *INDENT-ON* */
110 
111 enum {
112 	POD_DUMP_MEMORY = 2
113 };
114 
115 enum {
116 	POD_BUSY_READ,
117 	POD_BUSY_WRITE,
118 	POD_CHANNEL_DIRTY,
119 	POD_SAVE_PRESSED,
120 	POD_BUSY_MIDISEND
121 };
122 
123 static struct snd_ratden pod_ratden = {
124 	.num_min = 78125,
125 	.num_max = 78125,
126 	.num_step = 1,
127 	.den = 2
128 };
129 
130 static struct line6_pcm_properties pod_pcm_properties = {
131 	.playback_hw = {
132 				  .info = (SNDRV_PCM_INFO_MMAP |
133 					   SNDRV_PCM_INFO_INTERLEAVED |
134 					   SNDRV_PCM_INFO_BLOCK_TRANSFER |
135 					   SNDRV_PCM_INFO_MMAP_VALID |
136 					   SNDRV_PCM_INFO_PAUSE |
137 					   SNDRV_PCM_INFO_SYNC_START),
138 				  .formats = SNDRV_PCM_FMTBIT_S24_3LE,
139 				  .rates = SNDRV_PCM_RATE_KNOT,
140 				  .rate_min = 39062,
141 				  .rate_max = 39063,
142 				  .channels_min = 2,
143 				  .channels_max = 2,
144 				  .buffer_bytes_max = 60000,
145 				  .period_bytes_min = 64,
146 				  .period_bytes_max = 8192,
147 				  .periods_min = 1,
148 				  .periods_max = 1024},
149 	.capture_hw = {
150 				 .info = (SNDRV_PCM_INFO_MMAP |
151 					  SNDRV_PCM_INFO_INTERLEAVED |
152 					  SNDRV_PCM_INFO_BLOCK_TRANSFER |
153 					  SNDRV_PCM_INFO_MMAP_VALID |
154 					  SNDRV_PCM_INFO_SYNC_START),
155 				 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
156 				 .rates = SNDRV_PCM_RATE_KNOT,
157 				 .rate_min = 39062,
158 				 .rate_max = 39063,
159 				 .channels_min = 2,
160 				 .channels_max = 2,
161 				 .buffer_bytes_max = 60000,
162 				 .period_bytes_min = 64,
163 				 .period_bytes_max = 8192,
164 				 .periods_min = 1,
165 				 .periods_max = 1024},
166 	.rates = {
167 			    .nrats = 1,
168 			    .rats = &pod_ratden},
169 	.bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
170 };
171 
172 static const char pod_version_header[] = {
173 	0xf2, 0x7e, 0x7f, 0x06, 0x02
174 };
175 
176 /* forward declarations: */
177 static void pod_startup2(struct timer_list *t);
178 static void pod_startup3(struct usb_line6_pod *pod);
179 
180 static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
181 				    int size)
182 {
183 	return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code,
184 					size);
185 }
186 
187 /*
188 	Process a completely received message.
189 */
190 static void line6_pod_process_message(struct usb_line6 *line6)
191 {
192 	struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
193 	const unsigned char *buf = pod->line6.buffer_message;
194 
195 	if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) {
196 		pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15];
197 		pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) |
198 				 (int) buf[10];
199 		pod_startup3(pod);
200 		return;
201 	}
202 
203 	/* Only look for sysex messages from this device */
204 	if (buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE) &&
205 	    buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN)) {
206 		return;
207 	}
208 	if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) != 0)
209 		return;
210 
211 	if (buf[5] == POD_SYSEX_SYSTEM && buf[6] == POD_MONITOR_LEVEL) {
212 		short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) |
213 			      ((int)buf[9] << 4) | (int)buf[10];
214 		pod->monitor_level = value;
215 	}
216 }
217 
218 /*
219 	Send system parameter (from integer).
220 */
221 static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
222 				    int code)
223 {
224 	char *sysex;
225 	static const int size = 5;
226 
227 	sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
228 	if (!sysex)
229 		return -ENOMEM;
230 	sysex[SYSEX_DATA_OFS] = code;
231 	sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
232 	sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
233 	sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
234 	sysex[SYSEX_DATA_OFS + 4] = (value) & 0x0f;
235 	line6_send_sysex_message(&pod->line6, sysex, size);
236 	kfree(sysex);
237 	return 0;
238 }
239 
240 /*
241 	"read" request on "serial_number" special file.
242 */
243 static ssize_t serial_number_show(struct device *dev,
244 				  struct device_attribute *attr, char *buf)
245 {
246 	struct snd_card *card = dev_to_snd_card(dev);
247 	struct usb_line6_pod *pod = card->private_data;
248 
249 	return sprintf(buf, "%u\n", pod->serial_number);
250 }
251 
252 /*
253 	"read" request on "firmware_version" special file.
254 */
255 static ssize_t firmware_version_show(struct device *dev,
256 				     struct device_attribute *attr, char *buf)
257 {
258 	struct snd_card *card = dev_to_snd_card(dev);
259 	struct usb_line6_pod *pod = card->private_data;
260 
261 	return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
262 		       pod->firmware_version % 100);
263 }
264 
265 /*
266 	"read" request on "device_id" special file.
267 */
268 static ssize_t device_id_show(struct device *dev,
269 			      struct device_attribute *attr, char *buf)
270 {
271 	struct snd_card *card = dev_to_snd_card(dev);
272 	struct usb_line6_pod *pod = card->private_data;
273 
274 	return sprintf(buf, "%d\n", pod->device_id);
275 }
276 
277 /*
278 	POD startup procedure.
279 	This is a sequence of functions with special requirements (e.g., must
280 	not run immediately after initialization, must not run in interrupt
281 	context). After the last one has finished, the device is ready to use.
282 */
283 
284 static void pod_startup1(struct usb_line6_pod *pod)
285 {
286 	CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
287 
288 	/* delay startup procedure: */
289 	line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2);
290 }
291 
292 static void pod_startup2(struct timer_list *t)
293 {
294 	struct usb_line6_pod *pod = from_timer(pod, t, startup_timer);
295 	struct usb_line6 *line6 = &pod->line6;
296 
297 	CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
298 
299 	/* request firmware version: */
300 	line6_version_request_async(line6);
301 }
302 
303 static void pod_startup3(struct usb_line6_pod *pod)
304 {
305 	CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
306 
307 	/* schedule work for global work queue: */
308 	schedule_work(&pod->startup_work);
309 }
310 
311 static void pod_startup4(struct work_struct *work)
312 {
313 	struct usb_line6_pod *pod =
314 	    container_of(work, struct usb_line6_pod, startup_work);
315 	struct usb_line6 *line6 = &pod->line6;
316 
317 	CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
318 
319 	/* serial number: */
320 	line6_read_serial_number(&pod->line6, &pod->serial_number);
321 
322 	/* ALSA audio interface: */
323 	snd_card_register(line6->card);
324 }
325 
326 /* POD special files: */
327 static DEVICE_ATTR_RO(device_id);
328 static DEVICE_ATTR_RO(firmware_version);
329 static DEVICE_ATTR_RO(serial_number);
330 
331 static struct attribute *pod_dev_attrs[] = {
332 	&dev_attr_device_id.attr,
333 	&dev_attr_firmware_version.attr,
334 	&dev_attr_serial_number.attr,
335 	NULL
336 };
337 
338 static const struct attribute_group pod_dev_attr_group = {
339 	.name = "pod",
340 	.attrs = pod_dev_attrs,
341 };
342 
343 /* control info callback */
344 static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
345 					struct snd_ctl_elem_info *uinfo)
346 {
347 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
348 	uinfo->count = 1;
349 	uinfo->value.integer.min = 0;
350 	uinfo->value.integer.max = 65535;
351 	return 0;
352 }
353 
354 /* control get callback */
355 static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
356 				       struct snd_ctl_elem_value *ucontrol)
357 {
358 	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
359 	struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
360 
361 	ucontrol->value.integer.value[0] = pod->monitor_level;
362 	return 0;
363 }
364 
365 /* control put callback */
366 static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
367 				       struct snd_ctl_elem_value *ucontrol)
368 {
369 	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
370 	struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
371 
372 	if (ucontrol->value.integer.value[0] == pod->monitor_level)
373 		return 0;
374 
375 	pod->monitor_level = ucontrol->value.integer.value[0];
376 	pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
377 				 POD_MONITOR_LEVEL);
378 	return 1;
379 }
380 
381 /* control definition */
382 static const struct snd_kcontrol_new pod_control_monitor = {
383 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
384 	.name = "Monitor Playback Volume",
385 	.index = 0,
386 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
387 	.info = snd_pod_control_monitor_info,
388 	.get = snd_pod_control_monitor_get,
389 	.put = snd_pod_control_monitor_put
390 };
391 
392 /*
393 	POD device disconnected.
394 */
395 static void line6_pod_disconnect(struct usb_line6 *line6)
396 {
397 	struct usb_line6_pod *pod = (struct usb_line6_pod *)line6;
398 
399 	del_timer_sync(&pod->startup_timer);
400 	cancel_work_sync(&pod->startup_work);
401 }
402 
403 /*
404 	 Try to init POD device.
405 */
406 static int pod_init(struct usb_line6 *line6,
407 		    const struct usb_device_id *id)
408 {
409 	int err;
410 	struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
411 
412 	line6->process_message = line6_pod_process_message;
413 	line6->disconnect = line6_pod_disconnect;
414 
415 	timer_setup(&pod->startup_timer, NULL, 0);
416 	INIT_WORK(&pod->startup_work, pod_startup4);
417 
418 	/* create sysfs entries: */
419 	err = snd_card_add_dev_attr(line6->card, &pod_dev_attr_group);
420 	if (err < 0)
421 		return err;
422 
423 	/* initialize MIDI subsystem: */
424 	err = line6_init_midi(line6);
425 	if (err < 0)
426 		return err;
427 
428 	/* initialize PCM subsystem: */
429 	err = line6_init_pcm(line6, &pod_pcm_properties);
430 	if (err < 0)
431 		return err;
432 
433 	/* register monitor control: */
434 	err = snd_ctl_add(line6->card,
435 			  snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
436 	if (err < 0)
437 		return err;
438 
439 	/*
440 	   When the sound card is registered at this point, the PODxt Live
441 	   displays "Invalid Code Error 07", so we do it later in the event
442 	   handler.
443 	 */
444 
445 	if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
446 		pod->monitor_level = POD_SYSTEM_INVALID;
447 
448 		/* initiate startup procedure: */
449 		pod_startup1(pod);
450 	}
451 
452 	return 0;
453 }
454 
455 #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
456 #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
457 
458 /* table of devices that work with this driver */
459 static const struct usb_device_id pod_id_table[] = {
460 	{ LINE6_DEVICE(0x4250),    .driver_info = LINE6_BASSPODXT },
461 	{ LINE6_DEVICE(0x4642),    .driver_info = LINE6_BASSPODXTLIVE },
462 	{ LINE6_DEVICE(0x4252),    .driver_info = LINE6_BASSPODXTPRO },
463 	{ LINE6_IF_NUM(0x5051, 1), .driver_info = LINE6_POCKETPOD },
464 	{ LINE6_DEVICE(0x5044),    .driver_info = LINE6_PODXT },
465 	{ LINE6_IF_NUM(0x4650, 0), .driver_info = LINE6_PODXTLIVE_POD },
466 	{ LINE6_DEVICE(0x5050),    .driver_info = LINE6_PODXTPRO },
467 	{}
468 };
469 
470 MODULE_DEVICE_TABLE(usb, pod_id_table);
471 
472 static const struct line6_properties pod_properties_table[] = {
473 	[LINE6_BASSPODXT] = {
474 		.id = "BassPODxt",
475 		.name = "BassPODxt",
476 		.capabilities	= LINE6_CAP_CONTROL
477 				| LINE6_CAP_CONTROL_MIDI
478 				| LINE6_CAP_PCM
479 				| LINE6_CAP_HWMON,
480 		.altsetting = 5,
481 		.ep_ctrl_r = 0x84,
482 		.ep_ctrl_w = 0x03,
483 		.ep_audio_r = 0x82,
484 		.ep_audio_w = 0x01,
485 	},
486 	[LINE6_BASSPODXTLIVE] = {
487 		.id = "BassPODxtLive",
488 		.name = "BassPODxt Live",
489 		.capabilities	= LINE6_CAP_CONTROL
490 				| LINE6_CAP_CONTROL_MIDI
491 				| LINE6_CAP_PCM
492 				| LINE6_CAP_HWMON,
493 		.altsetting = 1,
494 		.ep_ctrl_r = 0x84,
495 		.ep_ctrl_w = 0x03,
496 		.ep_audio_r = 0x82,
497 		.ep_audio_w = 0x01,
498 	},
499 	[LINE6_BASSPODXTPRO] = {
500 		.id = "BassPODxtPro",
501 		.name = "BassPODxt Pro",
502 		.capabilities	= LINE6_CAP_CONTROL
503 				| LINE6_CAP_CONTROL_MIDI
504 				| LINE6_CAP_PCM
505 				| LINE6_CAP_HWMON,
506 		.altsetting = 5,
507 		.ep_ctrl_r = 0x84,
508 		.ep_ctrl_w = 0x03,
509 		.ep_audio_r = 0x82,
510 		.ep_audio_w = 0x01,
511 	},
512 	[LINE6_POCKETPOD] = {
513 		.id = "PocketPOD",
514 		.name = "Pocket POD",
515 		.capabilities	= LINE6_CAP_CONTROL
516 				| LINE6_CAP_CONTROL_MIDI,
517 		.altsetting = 0,
518 		.ep_ctrl_r = 0x82,
519 		.ep_ctrl_w = 0x02,
520 		/* no audio channel */
521 	},
522 	[LINE6_PODXT] = {
523 		.id = "PODxt",
524 		.name = "PODxt",
525 		.capabilities	= LINE6_CAP_CONTROL
526 				| LINE6_CAP_CONTROL_MIDI
527 				| LINE6_CAP_PCM
528 				| LINE6_CAP_HWMON,
529 		.altsetting = 5,
530 		.ep_ctrl_r = 0x84,
531 		.ep_ctrl_w = 0x03,
532 		.ep_audio_r = 0x82,
533 		.ep_audio_w = 0x01,
534 	},
535 	[LINE6_PODXTLIVE_POD] = {
536 		.id = "PODxtLive",
537 		.name = "PODxt Live",
538 		.capabilities	= LINE6_CAP_CONTROL
539 				| LINE6_CAP_CONTROL_MIDI
540 				| LINE6_CAP_PCM
541 				| LINE6_CAP_HWMON,
542 		.altsetting = 1,
543 		.ep_ctrl_r = 0x84,
544 		.ep_ctrl_w = 0x03,
545 		.ep_audio_r = 0x82,
546 		.ep_audio_w = 0x01,
547 	},
548 	[LINE6_PODXTPRO] = {
549 		.id = "PODxtPro",
550 		.name = "PODxt Pro",
551 		.capabilities	= LINE6_CAP_CONTROL
552 				| LINE6_CAP_CONTROL_MIDI
553 				| LINE6_CAP_PCM
554 				| LINE6_CAP_HWMON,
555 		.altsetting = 5,
556 		.ep_ctrl_r = 0x84,
557 		.ep_ctrl_w = 0x03,
558 		.ep_audio_r = 0x82,
559 		.ep_audio_w = 0x01,
560 	},
561 };
562 
563 /*
564 	Probe USB device.
565 */
566 static int pod_probe(struct usb_interface *interface,
567 		     const struct usb_device_id *id)
568 {
569 	return line6_probe(interface, id, "Line6-POD",
570 			   &pod_properties_table[id->driver_info],
571 			   pod_init, sizeof(struct usb_line6_pod));
572 }
573 
574 static struct usb_driver pod_driver = {
575 	.name = KBUILD_MODNAME,
576 	.probe = pod_probe,
577 	.disconnect = line6_disconnect,
578 #ifdef CONFIG_PM
579 	.suspend = line6_suspend,
580 	.resume = line6_resume,
581 	.reset_resume = line6_resume,
582 #endif
583 	.id_table = pod_id_table,
584 };
585 
586 module_usb_driver(pod_driver);
587 
588 MODULE_DESCRIPTION("Line 6 POD USB driver");
589 MODULE_LICENSE("GPL");
590