xref: /openbmc/linux/sound/usb/line6/podhd.c (revision 3fc41476)
1 /*
2  * Line 6 Pod HD
3  *
4  * Copyright (C) 2011 Stefan Hajnoczi <stefanha@gmail.com>
5  * Copyright (C) 2015 Andrej Krutak <dev@andree.sk>
6  * Copyright (C) 2017 Hans P. Moller <hmoller@uc.cl>
7  *
8  *	This program is free software; you can redistribute it and/or
9  *	modify it under the terms of the GNU General Public License as
10  *	published by the Free Software Foundation, version 2.
11  *
12  */
13 
14 #include <linux/usb.h>
15 #include <linux/slab.h>
16 #include <linux/module.h>
17 #include <sound/core.h>
18 #include <sound/pcm.h>
19 
20 #include "driver.h"
21 #include "pcm.h"
22 
23 #define PODHD_STARTUP_DELAY 500
24 
25 enum {
26 	LINE6_PODHD300,
27 	LINE6_PODHD400,
28 	LINE6_PODHD500_0,
29 	LINE6_PODHD500_1,
30 	LINE6_PODX3,
31 	LINE6_PODX3LIVE,
32 	LINE6_PODHD500X,
33 	LINE6_PODHDDESKTOP
34 };
35 
36 struct usb_line6_podhd {
37 	/* Generic Line 6 USB data */
38 	struct usb_line6 line6;
39 
40 	/* Serial number of device */
41 	u32 serial_number;
42 
43 	/* Firmware version */
44 	int firmware_version;
45 };
46 
47 #define line6_to_podhd(x)	container_of(x, struct usb_line6_podhd, line6)
48 
49 static struct snd_ratden podhd_ratden = {
50 	.num_min = 48000,
51 	.num_max = 48000,
52 	.num_step = 1,
53 	.den = 1,
54 };
55 
56 static struct line6_pcm_properties podhd_pcm_properties = {
57 	.playback_hw = {
58 				  .info = (SNDRV_PCM_INFO_MMAP |
59 					   SNDRV_PCM_INFO_INTERLEAVED |
60 					   SNDRV_PCM_INFO_BLOCK_TRANSFER |
61 					   SNDRV_PCM_INFO_MMAP_VALID |
62 					   SNDRV_PCM_INFO_PAUSE |
63 					   SNDRV_PCM_INFO_SYNC_START),
64 				  .formats = SNDRV_PCM_FMTBIT_S24_3LE,
65 				  .rates = SNDRV_PCM_RATE_48000,
66 				  .rate_min = 48000,
67 				  .rate_max = 48000,
68 				  .channels_min = 2,
69 				  .channels_max = 2,
70 				  .buffer_bytes_max = 60000,
71 				  .period_bytes_min = 64,
72 				  .period_bytes_max = 8192,
73 				  .periods_min = 1,
74 				  .periods_max = 1024},
75 	.capture_hw = {
76 				 .info = (SNDRV_PCM_INFO_MMAP |
77 					  SNDRV_PCM_INFO_INTERLEAVED |
78 					  SNDRV_PCM_INFO_BLOCK_TRANSFER |
79 					  SNDRV_PCM_INFO_MMAP_VALID |
80 					  SNDRV_PCM_INFO_SYNC_START),
81 				 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
82 				 .rates = SNDRV_PCM_RATE_48000,
83 				 .rate_min = 48000,
84 				 .rate_max = 48000,
85 				 .channels_min = 2,
86 				 .channels_max = 2,
87 				 .buffer_bytes_max = 60000,
88 				 .period_bytes_min = 64,
89 				 .period_bytes_max = 8192,
90 				 .periods_min = 1,
91 				 .periods_max = 1024},
92 	.rates = {
93 			    .nrats = 1,
94 			    .rats = &podhd_ratden},
95 	.bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
96 };
97 
98 static struct line6_pcm_properties podx3_pcm_properties = {
99 	.playback_hw = {
100 				  .info = (SNDRV_PCM_INFO_MMAP |
101 					   SNDRV_PCM_INFO_INTERLEAVED |
102 					   SNDRV_PCM_INFO_BLOCK_TRANSFER |
103 					   SNDRV_PCM_INFO_MMAP_VALID |
104 					   SNDRV_PCM_INFO_PAUSE |
105 					   SNDRV_PCM_INFO_SYNC_START),
106 				  .formats = SNDRV_PCM_FMTBIT_S24_3LE,
107 				  .rates = SNDRV_PCM_RATE_48000,
108 				  .rate_min = 48000,
109 				  .rate_max = 48000,
110 				  .channels_min = 2,
111 				  .channels_max = 2,
112 				  .buffer_bytes_max = 60000,
113 				  .period_bytes_min = 64,
114 				  .period_bytes_max = 8192,
115 				  .periods_min = 1,
116 				  .periods_max = 1024},
117 	.capture_hw = {
118 				 .info = (SNDRV_PCM_INFO_MMAP |
119 					  SNDRV_PCM_INFO_INTERLEAVED |
120 					  SNDRV_PCM_INFO_BLOCK_TRANSFER |
121 					  SNDRV_PCM_INFO_MMAP_VALID |
122 					  SNDRV_PCM_INFO_SYNC_START),
123 				 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
124 				 .rates = SNDRV_PCM_RATE_48000,
125 				 .rate_min = 48000,
126 				 .rate_max = 48000,
127 				 /* 1+2: Main signal (out), 3+4: Tone 1,
128 				  * 5+6: Tone 2, 7+8: raw
129 				  */
130 				 .channels_min = 8,
131 				 .channels_max = 8,
132 				 .buffer_bytes_max = 60000,
133 				 .period_bytes_min = 64,
134 				 .period_bytes_max = 8192,
135 				 .periods_min = 1,
136 				 .periods_max = 1024},
137 	.rates = {
138 			    .nrats = 1,
139 			    .rats = &podhd_ratden},
140 	.bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
141 };
142 static struct usb_driver podhd_driver;
143 
144 static ssize_t serial_number_show(struct device *dev,
145 				  struct device_attribute *attr, char *buf)
146 {
147 	struct snd_card *card = dev_to_snd_card(dev);
148 	struct usb_line6_podhd *pod = card->private_data;
149 
150 	return sprintf(buf, "%u\n", pod->serial_number);
151 }
152 
153 static ssize_t firmware_version_show(struct device *dev,
154 				     struct device_attribute *attr, char *buf)
155 {
156 	struct snd_card *card = dev_to_snd_card(dev);
157 	struct usb_line6_podhd *pod = card->private_data;
158 
159 	return sprintf(buf, "%06x\n", pod->firmware_version);
160 }
161 
162 static DEVICE_ATTR_RO(firmware_version);
163 static DEVICE_ATTR_RO(serial_number);
164 
165 static struct attribute *podhd_dev_attrs[] = {
166 	&dev_attr_firmware_version.attr,
167 	&dev_attr_serial_number.attr,
168 	NULL
169 };
170 
171 static const struct attribute_group podhd_dev_attr_group = {
172 	.name = "podhd",
173 	.attrs = podhd_dev_attrs,
174 };
175 
176 /*
177  * POD X3 startup procedure.
178  *
179  * May be compatible with other POD HD's, since it's also similar to the
180  * previous POD setup. In any case, it doesn't seem to be required for the
181  * audio nor bulk interfaces to work.
182  */
183 
184 static int podhd_dev_start(struct usb_line6_podhd *pod)
185 {
186 	int ret;
187 	u8 *init_bytes;
188 	int i;
189 	struct usb_device *usbdev = pod->line6.usbdev;
190 
191 	init_bytes = kmalloc(8, GFP_KERNEL);
192 	if (!init_bytes)
193 		return -ENOMEM;
194 
195 	ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0),
196 					0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
197 					0x11, 0,
198 					NULL, 0, LINE6_TIMEOUT * HZ);
199 	if (ret < 0) {
200 		dev_err(pod->line6.ifcdev, "read request failed (error %d)\n", ret);
201 		goto exit;
202 	}
203 
204 	/* NOTE: looks like some kind of ping message */
205 	ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
206 					USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
207 					0x11, 0x0,
208 					init_bytes, 3, LINE6_TIMEOUT * HZ);
209 	if (ret < 0) {
210 		dev_err(pod->line6.ifcdev,
211 			"receive length failed (error %d)\n", ret);
212 		goto exit;
213 	}
214 
215 	pod->firmware_version =
216 		(init_bytes[0] << 16) | (init_bytes[1] << 8) | (init_bytes[2] << 0);
217 
218 	for (i = 0; i <= 16; i++) {
219 		ret = line6_read_data(&pod->line6, 0xf000 + 0x08 * i, init_bytes, 8);
220 		if (ret < 0)
221 			goto exit;
222 	}
223 
224 	ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0),
225 					USB_REQ_SET_FEATURE,
226 					USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_DIR_OUT,
227 					1, 0,
228 					NULL, 0, LINE6_TIMEOUT * HZ);
229 exit:
230 	kfree(init_bytes);
231 	return ret;
232 }
233 
234 static void podhd_startup(struct usb_line6 *line6)
235 {
236 	struct usb_line6_podhd *pod = line6_to_podhd(line6);
237 
238 	podhd_dev_start(pod);
239 	line6_read_serial_number(&pod->line6, &pod->serial_number);
240 	if (snd_card_register(line6->card))
241 		dev_err(line6->ifcdev, "Failed to register POD HD card.\n");
242 }
243 
244 static void podhd_disconnect(struct usb_line6 *line6)
245 {
246 	struct usb_line6_podhd *pod = line6_to_podhd(line6);
247 
248 	if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO) {
249 		struct usb_interface *intf;
250 
251 		intf = usb_ifnum_to_if(line6->usbdev,
252 					pod->line6.properties->ctrl_if);
253 		if (intf)
254 			usb_driver_release_interface(&podhd_driver, intf);
255 	}
256 }
257 
258 /*
259 	Try to init POD HD device.
260 */
261 static int podhd_init(struct usb_line6 *line6,
262 		      const struct usb_device_id *id)
263 {
264 	int err;
265 	struct usb_line6_podhd *pod = line6_to_podhd(line6);
266 	struct usb_interface *intf;
267 
268 	line6->disconnect = podhd_disconnect;
269 	line6->startup = podhd_startup;
270 
271 	if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
272 		/* claim the data interface */
273 		intf = usb_ifnum_to_if(line6->usbdev,
274 					pod->line6.properties->ctrl_if);
275 		if (!intf) {
276 			dev_err(pod->line6.ifcdev, "interface %d not found\n",
277 				pod->line6.properties->ctrl_if);
278 			return -ENODEV;
279 		}
280 
281 		err = usb_driver_claim_interface(&podhd_driver, intf, NULL);
282 		if (err != 0) {
283 			dev_err(pod->line6.ifcdev, "can't claim interface %d, error %d\n",
284 				pod->line6.properties->ctrl_if, err);
285 			return err;
286 		}
287 	}
288 
289 	if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO) {
290 		/* create sysfs entries: */
291 		err = snd_card_add_dev_attr(line6->card, &podhd_dev_attr_group);
292 		if (err < 0)
293 			return err;
294 	}
295 
296 	if (pod->line6.properties->capabilities & LINE6_CAP_PCM) {
297 		/* initialize PCM subsystem: */
298 		err = line6_init_pcm(line6,
299 			(id->driver_info == LINE6_PODX3 ||
300 			id->driver_info == LINE6_PODX3LIVE) ? &podx3_pcm_properties :
301 			&podhd_pcm_properties);
302 		if (err < 0)
303 			return err;
304 	}
305 
306 	if (!(pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO)) {
307 		/* register USB audio system directly */
308 		return snd_card_register(line6->card);
309 	}
310 
311 	/* init device and delay registering */
312 	schedule_delayed_work(&line6->startup_work,
313 			      msecs_to_jiffies(PODHD_STARTUP_DELAY));
314 	return 0;
315 }
316 
317 #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
318 #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
319 
320 /* table of devices that work with this driver */
321 static const struct usb_device_id podhd_id_table[] = {
322 	/* TODO: no need to alloc data interfaces when only audio is used */
323 	{ LINE6_DEVICE(0x5057),    .driver_info = LINE6_PODHD300 },
324 	{ LINE6_DEVICE(0x5058),    .driver_info = LINE6_PODHD400 },
325 	{ LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 },
326 	{ LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 },
327 	{ LINE6_IF_NUM(0x414A, 0), .driver_info = LINE6_PODX3 },
328 	{ LINE6_IF_NUM(0x414B, 0), .driver_info = LINE6_PODX3LIVE },
329 	{ LINE6_IF_NUM(0x4159, 0), .driver_info = LINE6_PODHD500X },
330 	{ LINE6_IF_NUM(0x4156, 0), .driver_info = LINE6_PODHDDESKTOP },
331 	{}
332 };
333 
334 MODULE_DEVICE_TABLE(usb, podhd_id_table);
335 
336 static const struct line6_properties podhd_properties_table[] = {
337 	[LINE6_PODHD300] = {
338 		.id = "PODHD300",
339 		.name = "POD HD300",
340 		.capabilities	= LINE6_CAP_PCM
341 				| LINE6_CAP_HWMON,
342 		.altsetting = 5,
343 		.ep_ctrl_r = 0x84,
344 		.ep_ctrl_w = 0x03,
345 		.ep_audio_r = 0x82,
346 		.ep_audio_w = 0x01,
347 	},
348 	[LINE6_PODHD400] = {
349 		.id = "PODHD400",
350 		.name = "POD HD400",
351 		.capabilities	= LINE6_CAP_PCM
352 				| LINE6_CAP_HWMON,
353 		.altsetting = 5,
354 		.ep_ctrl_r = 0x84,
355 		.ep_ctrl_w = 0x03,
356 		.ep_audio_r = 0x82,
357 		.ep_audio_w = 0x01,
358 	},
359 	[LINE6_PODHD500_0] = {
360 		.id = "PODHD500",
361 		.name = "POD HD500",
362 		.capabilities	= LINE6_CAP_PCM
363 				| LINE6_CAP_HWMON,
364 		.altsetting = 1,
365 		.ep_ctrl_r = 0x81,
366 		.ep_ctrl_w = 0x01,
367 		.ep_audio_r = 0x86,
368 		.ep_audio_w = 0x02,
369 	},
370 	[LINE6_PODHD500_1] = {
371 		.id = "PODHD500",
372 		.name = "POD HD500",
373 		.capabilities	= LINE6_CAP_PCM
374 				| LINE6_CAP_HWMON,
375 		.altsetting = 1,
376 		.ep_ctrl_r = 0x81,
377 		.ep_ctrl_w = 0x01,
378 		.ep_audio_r = 0x86,
379 		.ep_audio_w = 0x02,
380 	},
381 	[LINE6_PODX3] = {
382 		.id = "PODX3",
383 		.name = "POD X3",
384 		.capabilities	= LINE6_CAP_CONTROL | LINE6_CAP_CONTROL_INFO
385 				| LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT,
386 		.altsetting = 1,
387 		.ep_ctrl_r = 0x81,
388 		.ep_ctrl_w = 0x01,
389 		.ctrl_if = 1,
390 		.ep_audio_r = 0x86,
391 		.ep_audio_w = 0x02,
392 	},
393 	[LINE6_PODX3LIVE] = {
394 		.id = "PODX3LIVE",
395 		.name = "POD X3 LIVE",
396 		.capabilities	= LINE6_CAP_CONTROL | LINE6_CAP_CONTROL_INFO
397 				| LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT,
398 		.altsetting = 1,
399 		.ep_ctrl_r = 0x81,
400 		.ep_ctrl_w = 0x01,
401 		.ctrl_if = 1,
402 		.ep_audio_r = 0x86,
403 		.ep_audio_w = 0x02,
404 	},
405 	[LINE6_PODHD500X] = {
406 		.id = "PODHD500X",
407 		.name = "POD HD500X",
408 		.capabilities	= LINE6_CAP_CONTROL
409 				| LINE6_CAP_PCM | LINE6_CAP_HWMON,
410 		.altsetting = 1,
411 		.ep_ctrl_r = 0x81,
412 		.ep_ctrl_w = 0x01,
413 		.ctrl_if = 1,
414 		.ep_audio_r = 0x86,
415 		.ep_audio_w = 0x02,
416 	},
417 	[LINE6_PODHDDESKTOP] = {
418 		.id = "PODHDDESKTOP",
419 		.name = "POD HDDESKTOP",
420 		.capabilities    = LINE6_CAP_CONTROL
421 			| LINE6_CAP_PCM | LINE6_CAP_HWMON,
422 		.altsetting = 1,
423 		.ep_ctrl_r = 0x81,
424 		.ep_ctrl_w = 0x01,
425 		.ctrl_if = 1,
426 		.ep_audio_r = 0x86,
427 		.ep_audio_w = 0x02,
428 	},
429 };
430 
431 /*
432 	Probe USB device.
433 */
434 static int podhd_probe(struct usb_interface *interface,
435 		       const struct usb_device_id *id)
436 {
437 	return line6_probe(interface, id, "Line6-PODHD",
438 			   &podhd_properties_table[id->driver_info],
439 			   podhd_init, sizeof(struct usb_line6_podhd));
440 }
441 
442 static struct usb_driver podhd_driver = {
443 	.name = KBUILD_MODNAME,
444 	.probe = podhd_probe,
445 	.disconnect = line6_disconnect,
446 #ifdef CONFIG_PM
447 	.suspend = line6_suspend,
448 	.resume = line6_resume,
449 	.reset_resume = line6_resume,
450 #endif
451 	.id_table = podhd_id_table,
452 };
453 
454 module_usb_driver(podhd_driver);
455 
456 MODULE_DESCRIPTION("Line 6 PODHD USB driver");
457 MODULE_LICENSE("GPL");
458