xref: /openbmc/linux/sound/usb/line6/pod.c (revision 02cc53e2)
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 	if (snd_card_register(line6->card))
324 		dev_err(line6->ifcdev, "Failed to register POD card.\n");
325 }
326 
327 /* POD special files: */
328 static DEVICE_ATTR_RO(device_id);
329 static DEVICE_ATTR_RO(firmware_version);
330 static DEVICE_ATTR_RO(serial_number);
331 
332 static struct attribute *pod_dev_attrs[] = {
333 	&dev_attr_device_id.attr,
334 	&dev_attr_firmware_version.attr,
335 	&dev_attr_serial_number.attr,
336 	NULL
337 };
338 
339 static const struct attribute_group pod_dev_attr_group = {
340 	.name = "pod",
341 	.attrs = pod_dev_attrs,
342 };
343 
344 /* control info callback */
345 static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
346 					struct snd_ctl_elem_info *uinfo)
347 {
348 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
349 	uinfo->count = 1;
350 	uinfo->value.integer.min = 0;
351 	uinfo->value.integer.max = 65535;
352 	return 0;
353 }
354 
355 /* control get callback */
356 static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
357 				       struct snd_ctl_elem_value *ucontrol)
358 {
359 	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
360 	struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
361 
362 	ucontrol->value.integer.value[0] = pod->monitor_level;
363 	return 0;
364 }
365 
366 /* control put callback */
367 static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
368 				       struct snd_ctl_elem_value *ucontrol)
369 {
370 	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
371 	struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
372 
373 	if (ucontrol->value.integer.value[0] == pod->monitor_level)
374 		return 0;
375 
376 	pod->monitor_level = ucontrol->value.integer.value[0];
377 	pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
378 				 POD_MONITOR_LEVEL);
379 	return 1;
380 }
381 
382 /* control definition */
383 static const struct snd_kcontrol_new pod_control_monitor = {
384 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
385 	.name = "Monitor Playback Volume",
386 	.index = 0,
387 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
388 	.info = snd_pod_control_monitor_info,
389 	.get = snd_pod_control_monitor_get,
390 	.put = snd_pod_control_monitor_put
391 };
392 
393 /*
394 	POD device disconnected.
395 */
396 static void line6_pod_disconnect(struct usb_line6 *line6)
397 {
398 	struct usb_line6_pod *pod = (struct usb_line6_pod *)line6;
399 
400 	del_timer_sync(&pod->startup_timer);
401 	cancel_work_sync(&pod->startup_work);
402 }
403 
404 /*
405 	 Try to init POD device.
406 */
407 static int pod_init(struct usb_line6 *line6,
408 		    const struct usb_device_id *id)
409 {
410 	int err;
411 	struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
412 
413 	line6->process_message = line6_pod_process_message;
414 	line6->disconnect = line6_pod_disconnect;
415 
416 	timer_setup(&pod->startup_timer, NULL, 0);
417 	INIT_WORK(&pod->startup_work, pod_startup4);
418 
419 	/* create sysfs entries: */
420 	err = snd_card_add_dev_attr(line6->card, &pod_dev_attr_group);
421 	if (err < 0)
422 		return err;
423 
424 	/* initialize MIDI subsystem: */
425 	err = line6_init_midi(line6);
426 	if (err < 0)
427 		return err;
428 
429 	/* initialize PCM subsystem: */
430 	err = line6_init_pcm(line6, &pod_pcm_properties);
431 	if (err < 0)
432 		return err;
433 
434 	/* register monitor control: */
435 	err = snd_ctl_add(line6->card,
436 			  snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
437 	if (err < 0)
438 		return err;
439 
440 	/*
441 	   When the sound card is registered at this point, the PODxt Live
442 	   displays "Invalid Code Error 07", so we do it later in the event
443 	   handler.
444 	 */
445 
446 	if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
447 		pod->monitor_level = POD_SYSTEM_INVALID;
448 
449 		/* initiate startup procedure: */
450 		pod_startup1(pod);
451 	}
452 
453 	return 0;
454 }
455 
456 #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
457 #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
458 
459 /* table of devices that work with this driver */
460 static const struct usb_device_id pod_id_table[] = {
461 	{ LINE6_DEVICE(0x4250),    .driver_info = LINE6_BASSPODXT },
462 	{ LINE6_DEVICE(0x4642),    .driver_info = LINE6_BASSPODXTLIVE },
463 	{ LINE6_DEVICE(0x4252),    .driver_info = LINE6_BASSPODXTPRO },
464 	{ LINE6_IF_NUM(0x5051, 1), .driver_info = LINE6_POCKETPOD },
465 	{ LINE6_DEVICE(0x5044),    .driver_info = LINE6_PODXT },
466 	{ LINE6_IF_NUM(0x4650, 0), .driver_info = LINE6_PODXTLIVE_POD },
467 	{ LINE6_DEVICE(0x5050),    .driver_info = LINE6_PODXTPRO },
468 	{}
469 };
470 
471 MODULE_DEVICE_TABLE(usb, pod_id_table);
472 
473 static const struct line6_properties pod_properties_table[] = {
474 	[LINE6_BASSPODXT] = {
475 		.id = "BassPODxt",
476 		.name = "BassPODxt",
477 		.capabilities	= LINE6_CAP_CONTROL
478 				| LINE6_CAP_CONTROL_MIDI
479 				| LINE6_CAP_PCM
480 				| LINE6_CAP_HWMON,
481 		.altsetting = 5,
482 		.ep_ctrl_r = 0x84,
483 		.ep_ctrl_w = 0x03,
484 		.ep_audio_r = 0x82,
485 		.ep_audio_w = 0x01,
486 	},
487 	[LINE6_BASSPODXTLIVE] = {
488 		.id = "BassPODxtLive",
489 		.name = "BassPODxt Live",
490 		.capabilities	= LINE6_CAP_CONTROL
491 				| LINE6_CAP_CONTROL_MIDI
492 				| LINE6_CAP_PCM
493 				| LINE6_CAP_HWMON,
494 		.altsetting = 1,
495 		.ep_ctrl_r = 0x84,
496 		.ep_ctrl_w = 0x03,
497 		.ep_audio_r = 0x82,
498 		.ep_audio_w = 0x01,
499 	},
500 	[LINE6_BASSPODXTPRO] = {
501 		.id = "BassPODxtPro",
502 		.name = "BassPODxt Pro",
503 		.capabilities	= LINE6_CAP_CONTROL
504 				| LINE6_CAP_CONTROL_MIDI
505 				| LINE6_CAP_PCM
506 				| LINE6_CAP_HWMON,
507 		.altsetting = 5,
508 		.ep_ctrl_r = 0x84,
509 		.ep_ctrl_w = 0x03,
510 		.ep_audio_r = 0x82,
511 		.ep_audio_w = 0x01,
512 	},
513 	[LINE6_POCKETPOD] = {
514 		.id = "PocketPOD",
515 		.name = "Pocket POD",
516 		.capabilities	= LINE6_CAP_CONTROL
517 				| LINE6_CAP_CONTROL_MIDI,
518 		.altsetting = 0,
519 		.ep_ctrl_r = 0x82,
520 		.ep_ctrl_w = 0x02,
521 		/* no audio channel */
522 	},
523 	[LINE6_PODXT] = {
524 		.id = "PODxt",
525 		.name = "PODxt",
526 		.capabilities	= LINE6_CAP_CONTROL
527 				| LINE6_CAP_CONTROL_MIDI
528 				| LINE6_CAP_PCM
529 				| LINE6_CAP_HWMON,
530 		.altsetting = 5,
531 		.ep_ctrl_r = 0x84,
532 		.ep_ctrl_w = 0x03,
533 		.ep_audio_r = 0x82,
534 		.ep_audio_w = 0x01,
535 	},
536 	[LINE6_PODXTLIVE_POD] = {
537 		.id = "PODxtLive",
538 		.name = "PODxt Live",
539 		.capabilities	= LINE6_CAP_CONTROL
540 				| LINE6_CAP_CONTROL_MIDI
541 				| LINE6_CAP_PCM
542 				| LINE6_CAP_HWMON,
543 		.altsetting = 1,
544 		.ep_ctrl_r = 0x84,
545 		.ep_ctrl_w = 0x03,
546 		.ep_audio_r = 0x82,
547 		.ep_audio_w = 0x01,
548 	},
549 	[LINE6_PODXTPRO] = {
550 		.id = "PODxtPro",
551 		.name = "PODxt Pro",
552 		.capabilities	= LINE6_CAP_CONTROL
553 				| LINE6_CAP_CONTROL_MIDI
554 				| LINE6_CAP_PCM
555 				| LINE6_CAP_HWMON,
556 		.altsetting = 5,
557 		.ep_ctrl_r = 0x84,
558 		.ep_ctrl_w = 0x03,
559 		.ep_audio_r = 0x82,
560 		.ep_audio_w = 0x01,
561 	},
562 };
563 
564 /*
565 	Probe USB device.
566 */
567 static int pod_probe(struct usb_interface *interface,
568 		     const struct usb_device_id *id)
569 {
570 	return line6_probe(interface, id, "Line6-POD",
571 			   &pod_properties_table[id->driver_info],
572 			   pod_init, sizeof(struct usb_line6_pod));
573 }
574 
575 static struct usb_driver pod_driver = {
576 	.name = KBUILD_MODNAME,
577 	.probe = pod_probe,
578 	.disconnect = line6_disconnect,
579 #ifdef CONFIG_PM
580 	.suspend = line6_suspend,
581 	.resume = line6_resume,
582 	.reset_resume = line6_resume,
583 #endif
584 	.id_table = pod_id_table,
585 };
586 
587 module_usb_driver(pod_driver);
588 
589 MODULE_DESCRIPTION("Line 6 POD USB driver");
590 MODULE_LICENSE("GPL");
591