pod.c 14.6 KB
Newer Older
M
Markus Grabner 已提交
1
/*
2
 * Line 6 Linux USB driver
M
Markus Grabner 已提交
3
 *
4
 * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
M
Markus Grabner 已提交
5 6 7 8 9 10 11
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License as
 *	published by the Free Software Foundation, version 2.
 *
 */

12
#include <linux/slab.h>
13
#include <linux/wait.h>
T
Takashi Iwai 已提交
14 15 16 17 18
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/usb.h>

#include <sound/core.h>
19
#include <sound/control.h>
20

M
Markus Grabner 已提交
21
#include "capture.h"
22
#include "driver.h"
M
Markus Grabner 已提交
23
#include "playback.h"
T
Takashi Iwai 已提交
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
#include "usbdefs.h"

/*
	Locate name in binary program dump
*/
#define	POD_NAME_OFFSET 0
#define	POD_NAME_LENGTH 16

/*
	Other constants
*/
#define POD_CONTROL_SIZE 0x80
#define POD_BUFSIZE_DUMPREQ 7
#define POD_STARTUP_DELAY 1000

/*
	Stages of POD startup procedure
*/
enum {
	POD_STARTUP_INIT = 1,
	POD_STARTUP_VERSIONREQ,
	POD_STARTUP_WORKQUEUE,
	POD_STARTUP_SETUP,
	POD_STARTUP_LAST = POD_STARTUP_SETUP - 1
};

enum {
	LINE6_BASSPODXT,
	LINE6_BASSPODXTLIVE,
	LINE6_BASSPODXTPRO,
	LINE6_POCKETPOD,
	LINE6_PODXT,
	LINE6_PODXTLIVE_POD,
	LINE6_PODXTPRO,
};

struct usb_line6_pod {
	/**
62
		Generic Line 6 USB data.
T
Takashi Iwai 已提交
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
	*/
	struct usb_line6 line6;

	/**
		Instrument monitor level.
	*/
	int monitor_level;

	/**
		Timer for device initializaton.
	*/
	struct timer_list startup_timer;

	/**
		Work handler for device initializaton.
	*/
	struct work_struct startup_work;

	/**
		Current progress in startup procedure.
	*/
	int startup_progress;

	/**
		Serial number of device.
	*/
	int serial_number;

	/**
		Firmware version (x 100).
	*/
	int firmware_version;

	/**
		Device ID.
	*/
	int device_id;
};
M
Markus Grabner 已提交
101 102

#define POD_SYSEX_CODE 3
103
#define POD_BYTES_PER_FRAME 6	/* 24bit audio (stereo) */
M
Markus Grabner 已提交
104

105
/* *INDENT-OFF* */
M
Markus Grabner 已提交
106 107 108 109 110 111 112 113 114 115 116

enum {
	POD_SYSEX_SAVE      = 0x24,
	POD_SYSEX_SYSTEM    = 0x56,
	POD_SYSEX_SYSTEMREQ = 0x57,
	/* POD_SYSEX_UPDATE    = 0x6c, */  /* software update! */
	POD_SYSEX_STORE     = 0x71,
	POD_SYSEX_FINISH    = 0x72,
	POD_SYSEX_DUMPMEM   = 0x73,
	POD_SYSEX_DUMP      = 0x74,
	POD_SYSEX_DUMPREQ   = 0x75
117 118 119

	/* dumps entire internal memory of PODxt Pro */
	/* POD_SYSEX_DUMPMEM2  = 0x76 */
M
Markus Grabner 已提交
120 121 122
};

enum {
123 124
	POD_MONITOR_LEVEL  = 0x04,
	POD_SYSTEM_INVALID = 0x10000
M
Markus Grabner 已提交
125 126
};

127 128
/* *INDENT-ON* */

M
Markus Grabner 已提交
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
enum {
	POD_DUMP_MEMORY = 2
};

enum {
	POD_BUSY_READ,
	POD_BUSY_WRITE,
	POD_CHANNEL_DIRTY,
	POD_SAVE_PRESSED,
	POD_BUSY_MIDISEND
};

static struct snd_ratden pod_ratden = {
	.num_min = 78125,
	.num_max = 78125,
	.num_step = 1,
	.den = 2
};

static struct line6_pcm_properties pod_pcm_properties = {
149
	.snd_line6_playback_hw = {
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
				  .info = (SNDRV_PCM_INFO_MMAP |
					   SNDRV_PCM_INFO_INTERLEAVED |
					   SNDRV_PCM_INFO_BLOCK_TRANSFER |
					   SNDRV_PCM_INFO_MMAP_VALID |
					   SNDRV_PCM_INFO_PAUSE |
					   SNDRV_PCM_INFO_SYNC_START),
				  .formats = SNDRV_PCM_FMTBIT_S24_3LE,
				  .rates = SNDRV_PCM_RATE_KNOT,
				  .rate_min = 39062,
				  .rate_max = 39063,
				  .channels_min = 2,
				  .channels_max = 2,
				  .buffer_bytes_max = 60000,
				  .period_bytes_min = 64,
				  .period_bytes_max = 8192,
				  .periods_min = 1,
				  .periods_max = 1024},
167
	.snd_line6_capture_hw = {
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
				 .info = (SNDRV_PCM_INFO_MMAP |
					  SNDRV_PCM_INFO_INTERLEAVED |
					  SNDRV_PCM_INFO_BLOCK_TRANSFER |
					  SNDRV_PCM_INFO_MMAP_VALID |
					  SNDRV_PCM_INFO_SYNC_START),
				 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
				 .rates = SNDRV_PCM_RATE_KNOT,
				 .rate_min = 39062,
				 .rate_max = 39063,
				 .channels_min = 2,
				 .channels_max = 2,
				 .buffer_bytes_max = 60000,
				 .period_bytes_min = 64,
				 .period_bytes_max = 8192,
				 .periods_min = 1,
				 .periods_max = 1024},
M
Markus Grabner 已提交
184
	.snd_line6_rates = {
185 186
			    .nrats = 1,
			    .rats = &pod_ratden},
M
Markus Grabner 已提交
187 188 189
	.bytes_per_frame = POD_BYTES_PER_FRAME
};

190
static const char pod_version_header[] = {
191 192 193 194 195 196
	0xf2, 0x7e, 0x7f, 0x06, 0x02
};

/* forward declarations: */
static void pod_startup2(unsigned long data);
static void pod_startup3(struct usb_line6_pod *pod);
M
Markus Grabner 已提交
197

198 199
static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
				    int size)
M
Markus Grabner 已提交
200
{
201 202
	return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code,
					size);
M
Markus Grabner 已提交
203 204 205 206 207
}

/*
	Process a completely received message.
*/
208
static void line6_pod_process_message(struct usb_line6 *line6)
M
Markus Grabner 已提交
209
{
210
	struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
M
Markus Grabner 已提交
211 212
	const unsigned char *buf = pod->line6.buffer_message;

213 214 215 216 217 218
	if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) {
		pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15];
		pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) |
				 (int) buf[10];
		pod_startup3(pod);
		return;
M
Markus Grabner 已提交
219 220
	}

221 222 223 224 225
	/* Only look for sysex messages from this device */
	if (buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE) &&
	    buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN)) {
		return;
	}
226
	if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) != 0)
227 228 229 230 231 232
		return;

	if (buf[5] == POD_SYSEX_SYSTEM && buf[6] == POD_MONITOR_LEVEL) {
		short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) |
			      ((int)buf[9] << 4) | (int)buf[10];
		pod->monitor_level = value;
M
Markus Grabner 已提交
233 234 235 236
	}
}

/*
237
	Send system parameter (from integer).
M
Markus Grabner 已提交
238
*/
239 240
static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
				    int code)
M
Markus Grabner 已提交
241 242 243 244 245
{
	char *sysex;
	static const int size = 5;

	sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
246
	if (!sysex)
247
		return -ENOMEM;
M
Markus Grabner 已提交
248 249
	sysex[SYSEX_DATA_OFS] = code;
	sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
250 251 252
	sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
	sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
	sysex[SYSEX_DATA_OFS + 4] = (value) & 0x0f;
M
Markus Grabner 已提交
253 254
	line6_send_sysex_message(&pod->line6, sysex, size);
	kfree(sysex);
255 256 257
	return 0;
}

M
Markus Grabner 已提交
258 259 260
/*
	"read" request on "serial_number" special file.
*/
261 262
static ssize_t serial_number_show(struct device *dev,
				  struct device_attribute *attr, char *buf)
M
Markus Grabner 已提交
263 264 265
{
	struct usb_interface *interface = to_usb_interface(dev);
	struct usb_line6_pod *pod = usb_get_intfdata(interface);
266

M
Markus Grabner 已提交
267 268 269 270 271 272
	return sprintf(buf, "%d\n", pod->serial_number);
}

/*
	"read" request on "firmware_version" special file.
*/
273 274
static ssize_t firmware_version_show(struct device *dev,
				     struct device_attribute *attr, char *buf)
M
Markus Grabner 已提交
275 276 277
{
	struct usb_interface *interface = to_usb_interface(dev);
	struct usb_line6_pod *pod = usb_get_intfdata(interface);
278

279 280
	return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
		       pod->firmware_version % 100);
M
Markus Grabner 已提交
281 282 283 284 285
}

/*
	"read" request on "device_id" special file.
*/
286 287
static ssize_t device_id_show(struct device *dev,
			      struct device_attribute *attr, char *buf)
M
Markus Grabner 已提交
288 289 290
{
	struct usb_interface *interface = to_usb_interface(dev);
	struct usb_line6_pod *pod = usb_get_intfdata(interface);
291

M
Markus Grabner 已提交
292 293 294
	return sprintf(buf, "%d\n", pod->device_id);
}

295 296 297 298 299 300 301 302 303
/*
	POD startup procedure.
	This is a sequence of functions with special requirements (e.g., must
	not run immediately after initialization, must not run in interrupt
	context). After the last one has finished, the device is ready to use.
*/

static void pod_startup1(struct usb_line6_pod *pod)
{
304
	CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
305 306

	/* delay startup procedure: */
307 308
	line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
			  (unsigned long)pod);
309 310 311 312 313 314
}

static void pod_startup2(unsigned long data)
{
	struct usb_line6_pod *pod = (struct usb_line6_pod *)data;
	struct usb_line6 *line6 = &pod->line6;
315

316
	CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
317 318 319

	/* request firmware version: */
	line6_version_request_async(line6);
M
Markus Grabner 已提交
320 321
}

322
static void pod_startup3(struct usb_line6_pod *pod)
323
{
324
	CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
325 326 327 328 329

	/* schedule work for global work queue: */
	schedule_work(&pod->startup_work);
}

330
static void pod_startup4(struct work_struct *work)
331
{
332 333
	struct usb_line6_pod *pod =
	    container_of(work, struct usb_line6_pod, startup_work);
334 335
	struct usb_line6 *line6 = &pod->line6;

336
	CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
337 338 339 340 341

	/* serial number: */
	line6_read_serial_number(&pod->line6, &pod->serial_number);

	/* ALSA audio interface: */
342
	snd_card_register(line6->card);
343 344
}

M
Markus Grabner 已提交
345
/* POD special files: */
346 347 348
static DEVICE_ATTR_RO(device_id);
static DEVICE_ATTR_RO(firmware_version);
static DEVICE_ATTR_RO(serial_number);
M
Markus Grabner 已提交
349

350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
/* control info callback */
static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 1;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = 65535;
	return 0;
}

/* control get callback */
static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_value *ucontrol)
{
	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
	struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
367

368
	ucontrol->value.integer.value[0] = pod->monitor_level;
369 370 371 372 373 374 375 376 377 378
	return 0;
}

/* control put callback */
static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_value *ucontrol)
{
	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
	struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;

379
	if (ucontrol->value.integer.value[0] == pod->monitor_level)
380 381
		return 0;

382
	pod->monitor_level = ucontrol->value.integer.value[0];
383
	pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
384
				 POD_MONITOR_LEVEL);
385 386 387 388 389 390 391 392 393 394 395 396 397 398
	return 1;
}

/* control definition */
static struct snd_kcontrol_new pod_control_monitor = {
	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
	.name = "Monitor Playback Volume",
	.index = 0,
	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
	.info = snd_pod_control_monitor_info,
	.get = snd_pod_control_monitor_get,
	.put = snd_pod_control_monitor_put
};

399 400 401 402 403
/*
	POD device disconnected.
*/
static void line6_pod_disconnect(struct usb_interface *interface)
{
404 405
	struct usb_line6_pod *pod = usb_get_intfdata(interface);
	struct device *dev = &interface->dev;
406

407 408 409 410
	/* remove sysfs entries: */
	device_remove_file(dev, &dev_attr_device_id);
	device_remove_file(dev, &dev_attr_firmware_version);
	device_remove_file(dev, &dev_attr_serial_number);
411

412 413
	del_timer_sync(&pod->startup_timer);
	cancel_work_sync(&pod->startup_work);
414 415
}

M
Markus Grabner 已提交
416 417 418
/*
	Create sysfs entries.
*/
419
static int pod_create_files2(struct device *dev)
M
Markus Grabner 已提交
420 421 422
{
	int err;

423 424 425 426 427 428 429 430 431
	err = device_create_file(dev, &dev_attr_device_id);
	if (err < 0)
		return err;
	err = device_create_file(dev, &dev_attr_firmware_version);
	if (err < 0)
		return err;
	err = device_create_file(dev, &dev_attr_serial_number);
	if (err < 0)
		return err;
M
Markus Grabner 已提交
432 433 434 435
	return 0;
}

/*
436
	 Try to init POD device.
M
Markus Grabner 已提交
437
*/
438 439
static int pod_init(struct usb_interface *interface,
		    struct usb_line6 *line6)
M
Markus Grabner 已提交
440 441
{
	int err;
442
	struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
M
Markus Grabner 已提交
443

444
	line6->process_message = line6_pod_process_message;
445
	line6->disconnect = line6_pod_disconnect;
446

447
	init_timer(&pod->startup_timer);
448
	INIT_WORK(&pod->startup_work, pod_startup4);
449

M
Markus Grabner 已提交
450
	/* create sysfs entries: */
451
	err = pod_create_files2(&interface->dev);
452
	if (err < 0)
M
Markus Grabner 已提交
453 454 455
		return err;

	/* initialize MIDI subsystem: */
456
	err = line6_init_midi(line6);
457
	if (err < 0)
M
Markus Grabner 已提交
458 459 460
		return err;

	/* initialize PCM subsystem: */
461
	err = line6_init_pcm(line6, &pod_pcm_properties);
462
	if (err < 0)
M
Markus Grabner 已提交
463 464
		return err;

465
	/* register monitor control: */
466 467 468
	err = snd_ctl_add(line6->card,
			  snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
	if (err < 0)
M
Markus Grabner 已提交
469 470
		return err;

471
	/*
472 473 474 475
	   When the sound card is registered at this point, the PODxt Live
	   displays "Invalid Code Error 07", so we do it later in the event
	   handler.
	 */
476

477
	if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
478
		pod->monitor_level = POD_SYSTEM_INVALID;
479 480 481

		/* initiate startup procedure: */
		pod_startup1(pod);
M
Markus Grabner 已提交
482 483 484 485 486
	}

	return 0;
}

T
Takashi Iwai 已提交
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598
#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)

/* table of devices that work with this driver */
static const struct usb_device_id pod_id_table[] = {
	{ LINE6_DEVICE(0x4250),    .driver_info = LINE6_BASSPODXT },
	{ LINE6_DEVICE(0x4642),    .driver_info = LINE6_BASSPODXTLIVE },
	{ LINE6_DEVICE(0x4252),    .driver_info = LINE6_BASSPODXTPRO },
	{ LINE6_IF_NUM(0x5051, 1), .driver_info = LINE6_POCKETPOD },
	{ LINE6_DEVICE(0x5044),    .driver_info = LINE6_PODXT },
	{ LINE6_IF_NUM(0x4650, 0), .driver_info = LINE6_PODXTLIVE_POD },
	{ LINE6_DEVICE(0x5050),    .driver_info = LINE6_PODXTPRO },
	{}
};

MODULE_DEVICE_TABLE(usb, pod_id_table);

static const struct line6_properties pod_properties_table[] = {
	[LINE6_BASSPODXT] = {
		.id = "BassPODxt",
		.name = "BassPODxt",
		.capabilities	= LINE6_CAP_CONTROL
				| LINE6_CAP_PCM
				| LINE6_CAP_HWMON,
		.altsetting = 5,
		.ep_ctrl_r = 0x84,
		.ep_ctrl_w = 0x03,
		.ep_audio_r = 0x82,
		.ep_audio_w = 0x01,
	},
	[LINE6_BASSPODXTLIVE] = {
		.id = "BassPODxtLive",
		.name = "BassPODxt Live",
		.capabilities	= LINE6_CAP_CONTROL
				| LINE6_CAP_PCM
				| LINE6_CAP_HWMON,
		.altsetting = 1,
		.ep_ctrl_r = 0x84,
		.ep_ctrl_w = 0x03,
		.ep_audio_r = 0x82,
		.ep_audio_w = 0x01,
	},
	[LINE6_BASSPODXTPRO] = {
		.id = "BassPODxtPro",
		.name = "BassPODxt Pro",
		.capabilities	= LINE6_CAP_CONTROL
				| LINE6_CAP_PCM
				| LINE6_CAP_HWMON,
		.altsetting = 5,
		.ep_ctrl_r = 0x84,
		.ep_ctrl_w = 0x03,
		.ep_audio_r = 0x82,
		.ep_audio_w = 0x01,
	},
	[LINE6_POCKETPOD] = {
		.id = "PocketPOD",
		.name = "Pocket POD",
		.capabilities	= LINE6_CAP_CONTROL,
		.altsetting = 0,
		.ep_ctrl_r = 0x82,
		.ep_ctrl_w = 0x02,
		/* no audio channel */
	},
	[LINE6_PODXT] = {
		.id = "PODxt",
		.name = "PODxt",
		.capabilities	= LINE6_CAP_CONTROL
				| LINE6_CAP_PCM
				| LINE6_CAP_HWMON,
		.altsetting = 5,
		.ep_ctrl_r = 0x84,
		.ep_ctrl_w = 0x03,
		.ep_audio_r = 0x82,
		.ep_audio_w = 0x01,
	},
	[LINE6_PODXTLIVE_POD] = {
		.id = "PODxtLive",
		.name = "PODxt Live",
		.capabilities	= LINE6_CAP_CONTROL
				| LINE6_CAP_PCM
				| LINE6_CAP_HWMON,
		.altsetting = 1,
		.ep_ctrl_r = 0x84,
		.ep_ctrl_w = 0x03,
		.ep_audio_r = 0x82,
		.ep_audio_w = 0x01,
	},
	[LINE6_PODXTPRO] = {
		.id = "PODxtPro",
		.name = "PODxt Pro",
		.capabilities	= LINE6_CAP_CONTROL
				| LINE6_CAP_PCM
				| LINE6_CAP_HWMON,
		.altsetting = 5,
		.ep_ctrl_r = 0x84,
		.ep_ctrl_w = 0x03,
		.ep_audio_r = 0x82,
		.ep_audio_w = 0x01,
	},
};

/*
	Probe USB device.
*/
static int pod_probe(struct usb_interface *interface,
		     const struct usb_device_id *id)
{
	struct usb_line6_pod *pod;

	pod = kzalloc(sizeof(*pod), GFP_KERNEL);
	if (!pod)
		return -ENODEV;
599 600 601
	return line6_probe(interface, &pod->line6,
			   &pod_properties_table[id->driver_info],
			   pod_init);
T
Takashi Iwai 已提交
602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617
}

static struct usb_driver pod_driver = {
	.name = KBUILD_MODNAME,
	.probe = pod_probe,
	.disconnect = line6_disconnect,
#ifdef CONFIG_PM
	.suspend = line6_suspend,
	.resume = line6_resume,
	.reset_resume = line6_resume,
#endif
	.id_table = pod_id_table,
};

module_usb_driver(pod_driver);

618
MODULE_DESCRIPTION("Line 6 POD USB driver");
T
Takashi Iwai 已提交
619
MODULE_LICENSE("GPL");