• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Line6 Linux USB driver - 0.9.1beta
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 <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	/* 24bit audio (stereo) */
24 
25 /* *INDENT-OFF* */
26 
27 enum {
28 	POD_SYSEX_SAVE      = 0x24,
29 	POD_SYSEX_SYSTEM    = 0x56,
30 	POD_SYSEX_SYSTEMREQ = 0x57,
31 	/* POD_SYSEX_UPDATE    = 0x6c, */  /* software update! */
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 	/* dumps entire internal memory of PODxt Pro */
39 	/* POD_SYSEX_DUMPMEM2  = 0x76 */
40 };
41 
42 enum {
43 	POD_MONITOR_LEVEL  = 0x04,
44 	POD_SYSTEM_INVALID = 0x10000
45 };
46 
47 /* *INDENT-ON* */
48 
49 enum {
50 	POD_DUMP_MEMORY = 2
51 };
52 
53 enum {
54 	POD_BUSY_READ,
55 	POD_BUSY_WRITE,
56 	POD_CHANNEL_DIRTY,
57 	POD_SAVE_PRESSED,
58 	POD_BUSY_MIDISEND
59 };
60 
61 static struct snd_ratden pod_ratden = {
62 	.num_min = 78125,
63 	.num_max = 78125,
64 	.num_step = 1,
65 	.den = 2
66 };
67 
68 static struct line6_pcm_properties pod_pcm_properties = {
69 	.snd_line6_playback_hw = {
70 				  .info = (SNDRV_PCM_INFO_MMAP |
71 					   SNDRV_PCM_INFO_INTERLEAVED |
72 					   SNDRV_PCM_INFO_BLOCK_TRANSFER |
73 					   SNDRV_PCM_INFO_MMAP_VALID |
74 					   SNDRV_PCM_INFO_PAUSE |
75 #ifdef CONFIG_PM
76 					   SNDRV_PCM_INFO_RESUME |
77 #endif
78 					   SNDRV_PCM_INFO_SYNC_START),
79 				  .formats = SNDRV_PCM_FMTBIT_S24_3LE,
80 				  .rates = SNDRV_PCM_RATE_KNOT,
81 				  .rate_min = 39062,
82 				  .rate_max = 39063,
83 				  .channels_min = 2,
84 				  .channels_max = 2,
85 				  .buffer_bytes_max = 60000,
86 				  .period_bytes_min = 64,
87 				  .period_bytes_max = 8192,
88 				  .periods_min = 1,
89 				  .periods_max = 1024},
90 	.snd_line6_capture_hw = {
91 				 .info = (SNDRV_PCM_INFO_MMAP |
92 					  SNDRV_PCM_INFO_INTERLEAVED |
93 					  SNDRV_PCM_INFO_BLOCK_TRANSFER |
94 					  SNDRV_PCM_INFO_MMAP_VALID |
95 #ifdef CONFIG_PM
96 					  SNDRV_PCM_INFO_RESUME |
97 #endif
98 					  SNDRV_PCM_INFO_SYNC_START),
99 				 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
100 				 .rates = SNDRV_PCM_RATE_KNOT,
101 				 .rate_min = 39062,
102 				 .rate_max = 39063,
103 				 .channels_min = 2,
104 				 .channels_max = 2,
105 				 .buffer_bytes_max = 60000,
106 				 .period_bytes_min = 64,
107 				 .period_bytes_max = 8192,
108 				 .periods_min = 1,
109 				 .periods_max = 1024},
110 	.snd_line6_rates = {
111 			    .nrats = 1,
112 			    .rats = &pod_ratden},
113 	.bytes_per_frame = POD_BYTES_PER_FRAME
114 };
115 
116 static const char pod_version_header[] = {
117 	0xf2, 0x7e, 0x7f, 0x06, 0x02
118 };
119 
120 /* forward declarations: */
121 static void pod_startup2(unsigned long data);
122 static void pod_startup3(struct usb_line6_pod *pod);
123 
pod_alloc_sysex_buffer(struct usb_line6_pod * pod,int code,int size)124 static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
125 				    int size)
126 {
127 	return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code,
128 					size);
129 }
130 
131 /*
132 	Process a completely received message.
133 */
line6_pod_process_message(struct usb_line6_pod * pod)134 void line6_pod_process_message(struct usb_line6_pod *pod)
135 {
136 	const unsigned char *buf = pod->line6.buffer_message;
137 
138 	if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) {
139 		pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15];
140 		pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) |
141 				 (int) buf[10];
142 		pod_startup3(pod);
143 		return;
144 	}
145 
146 	/* Only look for sysex messages from this device */
147 	if (buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE) &&
148 	    buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN)) {
149 		return;
150 	}
151 	if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) != 0)
152 		return;
153 
154 	if (buf[5] == POD_SYSEX_SYSTEM && buf[6] == POD_MONITOR_LEVEL) {
155 		short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) |
156 			      ((int)buf[9] << 4) | (int)buf[10];
157 		pod->monitor_level = value;
158 	}
159 }
160 
161 /*
162 	Transmit PODxt Pro control parameter.
163 */
line6_pod_transmit_parameter(struct usb_line6_pod * pod,int param,u8 value)164 void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param,
165 				  u8 value)
166 {
167 	line6_transmit_parameter(&pod->line6, param, value);
168 }
169 
170 /*
171 	Send system parameter (from integer).
172 */
pod_set_system_param_int(struct usb_line6_pod * pod,int value,int code)173 static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
174 				    int code)
175 {
176 	char *sysex;
177 	static const int size = 5;
178 
179 	sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
180 	if (!sysex)
181 		return -ENOMEM;
182 	sysex[SYSEX_DATA_OFS] = code;
183 	sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
184 	sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
185 	sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
186 	sysex[SYSEX_DATA_OFS + 4] = (value) & 0x0f;
187 	line6_send_sysex_message(&pod->line6, sysex, size);
188 	kfree(sysex);
189 	return 0;
190 }
191 
192 /*
193 	"read" request on "serial_number" special file.
194 */
serial_number_show(struct device * dev,struct device_attribute * attr,char * buf)195 static ssize_t serial_number_show(struct device *dev,
196 				  struct device_attribute *attr, char *buf)
197 {
198 	struct usb_interface *interface = to_usb_interface(dev);
199 	struct usb_line6_pod *pod = usb_get_intfdata(interface);
200 
201 	return sprintf(buf, "%d\n", pod->serial_number);
202 }
203 
204 /*
205 	"read" request on "firmware_version" special file.
206 */
firmware_version_show(struct device * dev,struct device_attribute * attr,char * buf)207 static ssize_t firmware_version_show(struct device *dev,
208 				     struct device_attribute *attr, char *buf)
209 {
210 	struct usb_interface *interface = to_usb_interface(dev);
211 	struct usb_line6_pod *pod = usb_get_intfdata(interface);
212 
213 	return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
214 		       pod->firmware_version % 100);
215 }
216 
217 /*
218 	"read" request on "device_id" special file.
219 */
device_id_show(struct device * dev,struct device_attribute * attr,char * buf)220 static ssize_t device_id_show(struct device *dev,
221 			      struct device_attribute *attr, char *buf)
222 {
223 	struct usb_interface *interface = to_usb_interface(dev);
224 	struct usb_line6_pod *pod = usb_get_intfdata(interface);
225 
226 	return sprintf(buf, "%d\n", pod->device_id);
227 }
228 
229 /*
230 	POD startup procedure.
231 	This is a sequence of functions with special requirements (e.g., must
232 	not run immediately after initialization, must not run in interrupt
233 	context). After the last one has finished, the device is ready to use.
234 */
235 
pod_startup1(struct usb_line6_pod * pod)236 static void pod_startup1(struct usb_line6_pod *pod)
237 {
238 	CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
239 
240 	/* delay startup procedure: */
241 	line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
242 			  (unsigned long)pod);
243 }
244 
pod_startup2(unsigned long data)245 static void pod_startup2(unsigned long data)
246 {
247 	struct usb_line6_pod *pod = (struct usb_line6_pod *)data;
248 	struct usb_line6 *line6 = &pod->line6;
249 
250 	CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
251 
252 	/* request firmware version: */
253 	line6_version_request_async(line6);
254 }
255 
pod_startup3(struct usb_line6_pod * pod)256 static void pod_startup3(struct usb_line6_pod *pod)
257 {
258 	CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
259 
260 	/* schedule work for global work queue: */
261 	schedule_work(&pod->startup_work);
262 }
263 
pod_startup4(struct work_struct * work)264 static void pod_startup4(struct work_struct *work)
265 {
266 	struct usb_line6_pod *pod =
267 	    container_of(work, struct usb_line6_pod, startup_work);
268 	struct usb_line6 *line6 = &pod->line6;
269 
270 	CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
271 
272 	/* serial number: */
273 	line6_read_serial_number(&pod->line6, &pod->serial_number);
274 
275 	/* ALSA audio interface: */
276 	line6_register_audio(line6);
277 }
278 
279 /* POD special files: */
280 static DEVICE_ATTR_RO(device_id);
281 static DEVICE_ATTR_RO(firmware_version);
282 static DEVICE_ATTR_RO(serial_number);
283 
284 /* control info callback */
snd_pod_control_monitor_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)285 static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
286 					struct snd_ctl_elem_info *uinfo)
287 {
288 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
289 	uinfo->count = 1;
290 	uinfo->value.integer.min = 0;
291 	uinfo->value.integer.max = 65535;
292 	return 0;
293 }
294 
295 /* control get callback */
snd_pod_control_monitor_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)296 static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
297 				       struct snd_ctl_elem_value *ucontrol)
298 {
299 	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
300 	struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
301 
302 	ucontrol->value.integer.value[0] = pod->monitor_level;
303 	return 0;
304 }
305 
306 /* control put callback */
snd_pod_control_monitor_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)307 static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
308 				       struct snd_ctl_elem_value *ucontrol)
309 {
310 	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
311 	struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
312 
313 	if (ucontrol->value.integer.value[0] == pod->monitor_level)
314 		return 0;
315 
316 	pod->monitor_level = ucontrol->value.integer.value[0];
317 	pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
318 				 POD_MONITOR_LEVEL);
319 	return 1;
320 }
321 
322 /* control definition */
323 static struct snd_kcontrol_new pod_control_monitor = {
324 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
325 	.name = "Monitor Playback Volume",
326 	.index = 0,
327 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
328 	.info = snd_pod_control_monitor_info,
329 	.get = snd_pod_control_monitor_get,
330 	.put = snd_pod_control_monitor_put
331 };
332 
333 /*
334 	POD destructor.
335 */
pod_destruct(struct usb_interface * interface)336 static void pod_destruct(struct usb_interface *interface)
337 {
338 	struct usb_line6_pod *pod = usb_get_intfdata(interface);
339 
340 	if (pod == NULL)
341 		return;
342 	line6_cleanup_audio(&pod->line6);
343 
344 	del_timer(&pod->startup_timer);
345 	cancel_work_sync(&pod->startup_work);
346 }
347 
348 /*
349 	Create sysfs entries.
350 */
pod_create_files2(struct device * dev)351 static int pod_create_files2(struct device *dev)
352 {
353 	int err;
354 
355 	CHECK_RETURN(device_create_file(dev, &dev_attr_device_id));
356 	CHECK_RETURN(device_create_file(dev, &dev_attr_firmware_version));
357 	CHECK_RETURN(device_create_file(dev, &dev_attr_serial_number));
358 	return 0;
359 }
360 
361 /*
362 	 Try to init POD device.
363 */
pod_try_init(struct usb_interface * interface,struct usb_line6_pod * pod)364 static int pod_try_init(struct usb_interface *interface,
365 			struct usb_line6_pod *pod)
366 {
367 	int err;
368 	struct usb_line6 *line6 = &pod->line6;
369 
370 	init_timer(&pod->startup_timer);
371 	INIT_WORK(&pod->startup_work, pod_startup4);
372 
373 	if ((interface == NULL) || (pod == NULL))
374 		return -ENODEV;
375 
376 	/* create sysfs entries: */
377 	err = pod_create_files2(&interface->dev);
378 	if (err < 0)
379 		return err;
380 
381 	/* initialize audio system: */
382 	err = line6_init_audio(line6);
383 	if (err < 0)
384 		return err;
385 
386 	/* initialize MIDI subsystem: */
387 	err = line6_init_midi(line6);
388 	if (err < 0)
389 		return err;
390 
391 	/* initialize PCM subsystem: */
392 	err = line6_init_pcm(line6, &pod_pcm_properties);
393 	if (err < 0)
394 		return err;
395 
396 	/* register monitor control: */
397 	err = snd_ctl_add(line6->card,
398 			  snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
399 	if (err < 0)
400 		return err;
401 
402 	/*
403 	   When the sound card is registered at this point, the PODxt Live
404 	   displays "Invalid Code Error 07", so we do it later in the event
405 	   handler.
406 	 */
407 
408 	if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) {
409 		pod->monitor_level = POD_SYSTEM_INVALID;
410 
411 		/* initiate startup procedure: */
412 		pod_startup1(pod);
413 	}
414 
415 	return 0;
416 }
417 
418 /*
419 	 Init POD device (and clean up in case of failure).
420 */
line6_pod_init(struct usb_interface * interface,struct usb_line6_pod * pod)421 int line6_pod_init(struct usb_interface *interface, struct usb_line6_pod *pod)
422 {
423 	int err = pod_try_init(interface, pod);
424 
425 	if (err < 0)
426 		pod_destruct(interface);
427 
428 	return err;
429 }
430 
431 /*
432 	POD device disconnected.
433 */
line6_pod_disconnect(struct usb_interface * interface)434 void line6_pod_disconnect(struct usb_interface *interface)
435 {
436 	struct usb_line6_pod *pod;
437 
438 	if (interface == NULL)
439 		return;
440 	pod = usb_get_intfdata(interface);
441 
442 	if (pod != NULL) {
443 		struct snd_line6_pcm *line6pcm = pod->line6.line6pcm;
444 		struct device *dev = &interface->dev;
445 
446 		if (line6pcm != NULL)
447 			line6_pcm_disconnect(line6pcm);
448 
449 		if (dev != NULL) {
450 			/* remove sysfs entries: */
451 			device_remove_file(dev, &dev_attr_device_id);
452 			device_remove_file(dev, &dev_attr_firmware_version);
453 			device_remove_file(dev, &dev_attr_serial_number);
454 		}
455 	}
456 
457 	pod_destruct(interface);
458 }
459