xref: /linux/sound/usb/line6/podhd.c (revision d30c1683aaecb93d2ab95685dc4300a33d3cea7a)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Line 6 Pod HD
4  *
5  * Copyright (C) 2011 Stefan Hajnoczi <stefanha@gmail.com>
6  * Copyright (C) 2015 Andrej Krutak <dev@andree.sk>
7  * Copyright (C) 2017 Hans P. Moller <hmoller@uc.cl>
8  */
9 
10 #include <linux/usb.h>
11 #include <linux/slab.h>
12 #include <linux/module.h>
13 #include <sound/core.h>
14 #include <sound/control.h>
15 #include <sound/pcm.h>
16 
17 #include "driver.h"
18 #include "pcm.h"
19 
20 #define PODHD_STARTUP_DELAY 500
21 
22 enum {
23 	LINE6_PODHD300,
24 	LINE6_PODHD400,
25 	LINE6_PODHD500,
26 	LINE6_PODX3,
27 	LINE6_PODX3LIVE,
28 	LINE6_PODHD500X,
29 	LINE6_PODHDDESKTOP,
30 	LINE6_PODHDPROX,
31 };
32 
33 struct usb_line6_podhd {
34 	/* Generic Line 6 USB data */
35 	struct usb_line6 line6;
36 
37 	/* Serial number of device */
38 	u32 serial_number;
39 
40 	/* Firmware version */
41 	int firmware_version;
42 
43 	/* Monitor level */
44 	int monitor_level;
45 };
46 
47 #define line6_to_podhd(x)	container_of(x, struct usb_line6_podhd, line6)
48 
49 static const 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 sysfs_emit(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 sysfs_emit(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[8];
188 	int i;
189 	struct usb_device *usbdev = pod->line6.usbdev;
190 
191 	ret = usb_control_msg_send(usbdev, 0,
192 					0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
193 					0x11, 0,
194 					NULL, 0, LINE6_TIMEOUT, GFP_KERNEL);
195 	if (ret) {
196 		dev_err(pod->line6.ifcdev, "read request failed (error %d)\n", ret);
197 		goto exit;
198 	}
199 
200 	/* NOTE: looks like some kind of ping message */
201 	ret = usb_control_msg_recv(usbdev, 0, 0x67,
202 					USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
203 					0x11, 0x0,
204 					init_bytes, 3, LINE6_TIMEOUT, GFP_KERNEL);
205 	if (ret) {
206 		dev_err(pod->line6.ifcdev,
207 			"receive length failed (error %d)\n", ret);
208 		goto exit;
209 	}
210 
211 	pod->firmware_version =
212 		(init_bytes[0] << 16) | (init_bytes[1] << 8) | (init_bytes[2] << 0);
213 
214 	for (i = 0; i <= 16; i++) {
215 		ret = line6_read_data(&pod->line6, 0xf000 + 0x08 * i, init_bytes, 8);
216 		if (ret < 0)
217 			goto exit;
218 	}
219 
220 	ret = usb_control_msg_send(usbdev, 0,
221 					USB_REQ_SET_FEATURE,
222 					USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_DIR_OUT,
223 					1, 0,
224 					NULL, 0, LINE6_TIMEOUT, GFP_KERNEL);
225 exit:
226 	return ret;
227 }
228 
229 static void podhd_startup(struct usb_line6 *line6)
230 {
231 	struct usb_line6_podhd *pod = line6_to_podhd(line6);
232 
233 	podhd_dev_start(pod);
234 	line6_read_serial_number(&pod->line6, &pod->serial_number);
235 	if (snd_card_register(line6->card))
236 		dev_err(line6->ifcdev, "Failed to register POD HD card.\n");
237 }
238 
239 static void podhd_disconnect(struct usb_line6 *line6)
240 {
241 	struct usb_line6_podhd *pod = line6_to_podhd(line6);
242 
243 	if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO) {
244 		struct usb_interface *intf;
245 
246 		intf = usb_ifnum_to_if(line6->usbdev,
247 					pod->line6.properties->ctrl_if);
248 		if (intf)
249 			usb_driver_release_interface(&podhd_driver, intf);
250 	}
251 }
252 
253 static const unsigned int float_zero_to_one_lookup[] = {
254 0x00000000, 0x3c23d70a, 0x3ca3d70a, 0x3cf5c28f, 0x3d23d70a, 0x3d4ccccd,
255 0x3d75c28f, 0x3d8f5c29, 0x3da3d70a, 0x3db851ec, 0x3dcccccd, 0x3de147ae,
256 0x3df5c28f, 0x3e051eb8, 0x3e0f5c29, 0x3e19999a, 0x3e23d70a, 0x3e2e147b,
257 0x3e3851ec, 0x3e428f5c, 0x3e4ccccd, 0x3e570a3d, 0x3e6147ae, 0x3e6b851f,
258 0x3e75c28f, 0x3e800000, 0x3e851eb8, 0x3e8a3d71, 0x3e8f5c29, 0x3e947ae1,
259 0x3e99999a, 0x3e9eb852, 0x3ea3d70a, 0x3ea8f5c3, 0x3eae147b, 0x3eb33333,
260 0x3eb851ec, 0x3ebd70a4, 0x3ec28f5c, 0x3ec7ae14, 0x3ecccccd, 0x3ed1eb85,
261 0x3ed70a3d, 0x3edc28f6, 0x3ee147ae, 0x3ee66666, 0x3eeb851f, 0x3ef0a3d7,
262 0x3ef5c28f, 0x3efae148, 0x3f000000, 0x3f028f5c, 0x3f051eb8, 0x3f07ae14,
263 0x3f0a3d71, 0x3f0ccccd, 0x3f0f5c29, 0x3f11eb85, 0x3f147ae1, 0x3f170a3d,
264 0x3f19999a, 0x3f1c28f6, 0x3f1eb852, 0x3f2147ae, 0x3f23d70a, 0x3f266666,
265 0x3f28f5c3, 0x3f2b851f, 0x3f2e147b, 0x3f30a3d7, 0x3f333333, 0x3f35c28f,
266 0x3f3851ec, 0x3f3ae148, 0x3f3d70a4, 0x3f400000, 0x3f428f5c, 0x3f451eb8,
267 0x3f47ae14, 0x3f4a3d71, 0x3f4ccccd, 0x3f4f5c29, 0x3f51eb85, 0x3f547ae1,
268 0x3f570a3d, 0x3f59999a, 0x3f5c28f6, 0x3f5eb852, 0x3f6147ae, 0x3f63d70a,
269 0x3f666666, 0x3f68f5c3, 0x3f6b851f, 0x3f6e147b, 0x3f70a3d7, 0x3f733333,
270 0x3f75c28f, 0x3f7851ec, 0x3f7ae148, 0x3f7d70a4, 0x3f800000
271 };
272 
273 static void podhd_set_monitor_level(struct usb_line6_podhd *podhd, int value)
274 {
275 	unsigned int fl;
276 	static const unsigned char msg[16] = {
277 		/* Chunk is 0xc bytes (without first word) */
278 		0x0c, 0x00,
279 		/* First chunk in the message */
280 		0x01, 0x00,
281 		/* Message size is 2 4-byte words */
282 		0x02, 0x00,
283 		/* Unknown */
284 		0x04, 0x41,
285 		/* Unknown */
286 		0x04, 0x00, 0x13, 0x00,
287 		/* Volume, LE float32, 0.0 - 1.0 */
288 		0x00, 0x00, 0x00, 0x00
289 	};
290 	unsigned char *buf;
291 
292 	buf = kmemdup(msg, sizeof(msg), GFP_KERNEL);
293 	if (!buf)
294 		return;
295 
296 	if (value < 0)
297 		value = 0;
298 
299 	if (value >= ARRAY_SIZE(float_zero_to_one_lookup))
300 		value = ARRAY_SIZE(float_zero_to_one_lookup) - 1;
301 
302 	fl = float_zero_to_one_lookup[value];
303 
304 	buf[12] = (fl >> 0) & 0xff;
305 	buf[13] = (fl >> 8) & 0xff;
306 	buf[14] = (fl >> 16) & 0xff;
307 	buf[15] = (fl >> 24) & 0xff;
308 
309 	line6_send_raw_message(&podhd->line6, buf, sizeof(msg));
310 	kfree(buf);
311 
312 	podhd->monitor_level = value;
313 }
314 
315 /* control info callback */
316 static int snd_podhd_control_monitor_info(struct snd_kcontrol *kcontrol,
317 					struct snd_ctl_elem_info *uinfo)
318 {
319 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
320 	uinfo->count = 1;
321 	uinfo->value.integer.min = 0;
322 	uinfo->value.integer.max = 100;
323 	uinfo->value.integer.step = 1;
324 	return 0;
325 }
326 
327 /* control get callback */
328 static int snd_podhd_control_monitor_get(struct snd_kcontrol *kcontrol,
329 				       struct snd_ctl_elem_value *ucontrol)
330 {
331 	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
332 	struct usb_line6_podhd *podhd = line6_to_podhd(line6pcm->line6);
333 
334 	ucontrol->value.integer.value[0] = podhd->monitor_level;
335 	return 0;
336 }
337 
338 /* control put callback */
339 static int snd_podhd_control_monitor_put(struct snd_kcontrol *kcontrol,
340 				       struct snd_ctl_elem_value *ucontrol)
341 {
342 	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
343 	struct usb_line6_podhd *podhd = line6_to_podhd(line6pcm->line6);
344 
345 	if (ucontrol->value.integer.value[0] == podhd->monitor_level)
346 		return 0;
347 
348 	podhd_set_monitor_level(podhd, ucontrol->value.integer.value[0]);
349 	return 1;
350 }
351 
352 /* control definition */
353 static const struct snd_kcontrol_new podhd_control_monitor = {
354 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
355 	.name = "Monitor Playback Volume",
356 	.index = 0,
357 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
358 	.info = snd_podhd_control_monitor_info,
359 	.get = snd_podhd_control_monitor_get,
360 	.put = snd_podhd_control_monitor_put
361 };
362 
363 /*
364 	Try to init POD HD device.
365 */
366 static int podhd_init(struct usb_line6 *line6,
367 		      const struct usb_device_id *id)
368 {
369 	int err;
370 	struct usb_line6_podhd *pod = line6_to_podhd(line6);
371 	struct usb_interface *intf;
372 
373 	line6->disconnect = podhd_disconnect;
374 	line6->startup = podhd_startup;
375 
376 	if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
377 		/* claim the data interface */
378 		intf = usb_ifnum_to_if(line6->usbdev,
379 					pod->line6.properties->ctrl_if);
380 		if (!intf) {
381 			dev_err(pod->line6.ifcdev, "interface %d not found\n",
382 				pod->line6.properties->ctrl_if);
383 			return -ENODEV;
384 		}
385 
386 		err = usb_driver_claim_interface(&podhd_driver, intf, NULL);
387 		if (err != 0) {
388 			dev_err(pod->line6.ifcdev, "can't claim interface %d, error %d\n",
389 				pod->line6.properties->ctrl_if, err);
390 			return err;
391 		}
392 	}
393 
394 	if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO) {
395 		/* create sysfs entries: */
396 		err = snd_card_add_dev_attr(line6->card, &podhd_dev_attr_group);
397 		if (err < 0)
398 			return err;
399 	}
400 
401 	if (pod->line6.properties->capabilities & LINE6_CAP_PCM) {
402 		/* initialize PCM subsystem: */
403 		err = line6_init_pcm(line6,
404 			(id->driver_info == LINE6_PODX3 ||
405 			id->driver_info == LINE6_PODX3LIVE) ? &podx3_pcm_properties :
406 			&podhd_pcm_properties);
407 		if (err < 0)
408 			return err;
409 	}
410 
411 	if (pod->line6.properties->capabilities & LINE6_CAP_HWMON_CTL) {
412 		podhd_set_monitor_level(pod, 100);
413 		err = snd_ctl_add(line6->card,
414 				  snd_ctl_new1(&podhd_control_monitor,
415 					       line6->line6pcm));
416 		if (err < 0)
417 			return err;
418 	}
419 
420 	if (!(pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO)) {
421 		/* register USB audio system directly */
422 		return snd_card_register(line6->card);
423 	}
424 
425 	/* init device and delay registering */
426 	schedule_delayed_work(&line6->startup_work,
427 			      msecs_to_jiffies(PODHD_STARTUP_DELAY));
428 	return 0;
429 }
430 
431 #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
432 #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
433 
434 /* table of devices that work with this driver */
435 static const struct usb_device_id podhd_id_table[] = {
436 	/* TODO: no need to alloc data interfaces when only audio is used */
437 	{ LINE6_DEVICE(0x5057),    .driver_info = LINE6_PODHD300 },
438 	{ LINE6_DEVICE(0x5058),    .driver_info = LINE6_PODHD400 },
439 	{ LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500 },
440 	{ LINE6_IF_NUM(0x414A, 0), .driver_info = LINE6_PODX3 },
441 	{ LINE6_IF_NUM(0x414B, 0), .driver_info = LINE6_PODX3LIVE },
442 	{ LINE6_IF_NUM(0x4159, 0), .driver_info = LINE6_PODHD500X },
443 	{ LINE6_IF_NUM(0x4156, 0), .driver_info = LINE6_PODHDDESKTOP },
444 	{ LINE6_IF_NUM(0x415A, 0), .driver_info = LINE6_PODHDPROX },
445 	{}
446 };
447 
448 MODULE_DEVICE_TABLE(usb, podhd_id_table);
449 
450 static const struct line6_properties podhd_properties_table[] = {
451 	[LINE6_PODHD300] = {
452 		.id = "PODHD300",
453 		.name = "POD HD300",
454 		.capabilities	= LINE6_CAP_PCM
455 				| LINE6_CAP_HWMON,
456 		.altsetting = 5,
457 		.ep_ctrl_r = 0x84,
458 		.ep_ctrl_w = 0x03,
459 		.ep_audio_r = 0x82,
460 		.ep_audio_w = 0x01,
461 	},
462 	[LINE6_PODHD400] = {
463 		.id = "PODHD400",
464 		.name = "POD HD400",
465 		.capabilities	= 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_PODHD500] = {
474 		.id = "PODHD500",
475 		.name = "POD HD500",
476 		.capabilities	= LINE6_CAP_PCM | LINE6_CAP_CONTROL
477 				| LINE6_CAP_HWMON | LINE6_CAP_HWMON_CTL,
478 		.altsetting = 1,
479 		.ctrl_if = 1,
480 		.ep_ctrl_r = 0x81,
481 		.ep_ctrl_w = 0x01,
482 		.ep_audio_r = 0x86,
483 		.ep_audio_w = 0x02,
484 	},
485 	[LINE6_PODX3] = {
486 		.id = "PODX3",
487 		.name = "POD X3",
488 		.capabilities	= LINE6_CAP_CONTROL | LINE6_CAP_CONTROL_INFO
489 				| LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT,
490 		.altsetting = 1,
491 		.ep_ctrl_r = 0x81,
492 		.ep_ctrl_w = 0x01,
493 		.ctrl_if = 1,
494 		.ep_audio_r = 0x86,
495 		.ep_audio_w = 0x02,
496 	},
497 	[LINE6_PODX3LIVE] = {
498 		.id = "PODX3LIVE",
499 		.name = "POD X3 LIVE",
500 		.capabilities	= LINE6_CAP_CONTROL | LINE6_CAP_CONTROL_INFO
501 				| LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT,
502 		.altsetting = 1,
503 		.ep_ctrl_r = 0x81,
504 		.ep_ctrl_w = 0x01,
505 		.ctrl_if = 1,
506 		.ep_audio_r = 0x86,
507 		.ep_audio_w = 0x02,
508 	},
509 	[LINE6_PODHD500X] = {
510 		.id = "PODHD500X",
511 		.name = "POD HD500X",
512 		.capabilities	= LINE6_CAP_CONTROL | LINE6_CAP_HWMON_CTL
513 				| LINE6_CAP_PCM | LINE6_CAP_HWMON,
514 		.altsetting = 1,
515 		.ep_ctrl_r = 0x81,
516 		.ep_ctrl_w = 0x01,
517 		.ctrl_if = 1,
518 		.ep_audio_r = 0x86,
519 		.ep_audio_w = 0x02,
520 	},
521 	[LINE6_PODHDDESKTOP] = {
522 		.id = "PODHDDESKTOP",
523 		.name = "POD HDDESKTOP",
524 		.capabilities    = LINE6_CAP_CONTROL
525 			| LINE6_CAP_PCM | LINE6_CAP_HWMON,
526 		.altsetting = 1,
527 		.ep_ctrl_r = 0x81,
528 		.ep_ctrl_w = 0x01,
529 		.ctrl_if = 1,
530 		.ep_audio_r = 0x86,
531 		.ep_audio_w = 0x02,
532 	},
533 	[LINE6_PODHDPROX] = {
534 		.id = "PODHDPROX",
535 		.name = "POD HD Pro X",
536 		.capabilities	= LINE6_CAP_CONTROL | LINE6_CAP_CONTROL_INFO
537 				| LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT,
538 		.altsetting = 1,
539 		.ctrl_if = 1,
540 		.ep_ctrl_r = 0x81,
541 		.ep_ctrl_w = 0x01,
542 		.ep_audio_r = 0x86,
543 		.ep_audio_w = 0x02,
544 	},
545 };
546 
547 /*
548 	Probe USB device.
549 */
550 static int podhd_probe(struct usb_interface *interface,
551 		       const struct usb_device_id *id)
552 {
553 	return line6_probe(interface, id, "Line6-PODHD",
554 			   &podhd_properties_table[id->driver_info],
555 			   podhd_init, sizeof(struct usb_line6_podhd));
556 }
557 
558 static struct usb_driver podhd_driver = {
559 	.name = KBUILD_MODNAME,
560 	.probe = podhd_probe,
561 	.disconnect = line6_disconnect,
562 #ifdef CONFIG_PM
563 	.suspend = line6_suspend,
564 	.resume = line6_resume,
565 	.reset_resume = line6_resume,
566 #endif
567 	.id_table = podhd_id_table,
568 };
569 
570 module_usb_driver(podhd_driver);
571 
572 MODULE_DESCRIPTION("Line 6 PODHD USB driver");
573 MODULE_LICENSE("GPL");
574