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