xref: /linux/sound/usb/line6/podhd.c (revision 1fe93b2a2ace9bba2cb90920f9300834e537665c)
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 	LINE6_PODHDPRO,
32 };
33 
34 struct usb_line6_podhd {
35 	/* Generic Line 6 USB data */
36 	struct usb_line6 line6;
37 
38 	/* Serial number of device */
39 	u32 serial_number;
40 
41 	/* Firmware version */
42 	int firmware_version;
43 
44 	/* Monitor level */
45 	int monitor_level;
46 };
47 
48 #define line6_to_podhd(x)	container_of(x, struct usb_line6_podhd, line6)
49 
50 static const struct snd_ratden podhd_ratden = {
51 	.num_min = 48000,
52 	.num_max = 48000,
53 	.num_step = 1,
54 	.den = 1,
55 };
56 
57 static struct line6_pcm_properties podhd_pcm_properties = {
58 	.playback_hw = {
59 				  .info = (SNDRV_PCM_INFO_MMAP |
60 					   SNDRV_PCM_INFO_INTERLEAVED |
61 					   SNDRV_PCM_INFO_BLOCK_TRANSFER |
62 					   SNDRV_PCM_INFO_MMAP_VALID |
63 					   SNDRV_PCM_INFO_PAUSE |
64 					   SNDRV_PCM_INFO_SYNC_START),
65 				  .formats = SNDRV_PCM_FMTBIT_S24_3LE,
66 				  .rates = SNDRV_PCM_RATE_48000,
67 				  .rate_min = 48000,
68 				  .rate_max = 48000,
69 				  .channels_min = 2,
70 				  .channels_max = 2,
71 				  .buffer_bytes_max = 60000,
72 				  .period_bytes_min = 64,
73 				  .period_bytes_max = 8192,
74 				  .periods_min = 1,
75 				  .periods_max = 1024},
76 	.capture_hw = {
77 				 .info = (SNDRV_PCM_INFO_MMAP |
78 					  SNDRV_PCM_INFO_INTERLEAVED |
79 					  SNDRV_PCM_INFO_BLOCK_TRANSFER |
80 					  SNDRV_PCM_INFO_MMAP_VALID |
81 					  SNDRV_PCM_INFO_SYNC_START),
82 				 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
83 				 .rates = SNDRV_PCM_RATE_48000,
84 				 .rate_min = 48000,
85 				 .rate_max = 48000,
86 				 .channels_min = 2,
87 				 .channels_max = 2,
88 				 .buffer_bytes_max = 60000,
89 				 .period_bytes_min = 64,
90 				 .period_bytes_max = 8192,
91 				 .periods_min = 1,
92 				 .periods_max = 1024},
93 	.rates = {
94 			    .nrats = 1,
95 			    .rats = &podhd_ratden},
96 	.bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
97 };
98 
99 static struct line6_pcm_properties podx3_pcm_properties = {
100 	.playback_hw = {
101 				  .info = (SNDRV_PCM_INFO_MMAP |
102 					   SNDRV_PCM_INFO_INTERLEAVED |
103 					   SNDRV_PCM_INFO_BLOCK_TRANSFER |
104 					   SNDRV_PCM_INFO_MMAP_VALID |
105 					   SNDRV_PCM_INFO_PAUSE |
106 					   SNDRV_PCM_INFO_SYNC_START),
107 				  .formats = SNDRV_PCM_FMTBIT_S24_3LE,
108 				  .rates = SNDRV_PCM_RATE_48000,
109 				  .rate_min = 48000,
110 				  .rate_max = 48000,
111 				  .channels_min = 2,
112 				  .channels_max = 2,
113 				  .buffer_bytes_max = 60000,
114 				  .period_bytes_min = 64,
115 				  .period_bytes_max = 8192,
116 				  .periods_min = 1,
117 				  .periods_max = 1024},
118 	.capture_hw = {
119 				 .info = (SNDRV_PCM_INFO_MMAP |
120 					  SNDRV_PCM_INFO_INTERLEAVED |
121 					  SNDRV_PCM_INFO_BLOCK_TRANSFER |
122 					  SNDRV_PCM_INFO_MMAP_VALID |
123 					  SNDRV_PCM_INFO_SYNC_START),
124 				 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
125 				 .rates = SNDRV_PCM_RATE_48000,
126 				 .rate_min = 48000,
127 				 .rate_max = 48000,
128 				 /* 1+2: Main signal (out), 3+4: Tone 1,
129 				  * 5+6: Tone 2, 7+8: raw
130 				  */
131 				 .channels_min = 8,
132 				 .channels_max = 8,
133 				 .buffer_bytes_max = 60000,
134 				 .period_bytes_min = 64,
135 				 .period_bytes_max = 8192,
136 				 .periods_min = 1,
137 				 .periods_max = 1024},
138 	.rates = {
139 			    .nrats = 1,
140 			    .rats = &podhd_ratden},
141 	.bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
142 };
143 static struct usb_driver podhd_driver;
144 
serial_number_show(struct device * dev,struct device_attribute * attr,char * buf)145 static ssize_t serial_number_show(struct device *dev,
146 				  struct device_attribute *attr, char *buf)
147 {
148 	struct snd_card *card = dev_to_snd_card(dev);
149 	struct usb_line6_podhd *pod = card->private_data;
150 
151 	return sysfs_emit(buf, "%u\n", pod->serial_number);
152 }
153 
firmware_version_show(struct device * dev,struct device_attribute * attr,char * buf)154 static ssize_t firmware_version_show(struct device *dev,
155 				     struct device_attribute *attr, char *buf)
156 {
157 	struct snd_card *card = dev_to_snd_card(dev);
158 	struct usb_line6_podhd *pod = card->private_data;
159 
160 	return sysfs_emit(buf, "%06x\n", pod->firmware_version);
161 }
162 
163 static DEVICE_ATTR_RO(firmware_version);
164 static DEVICE_ATTR_RO(serial_number);
165 
166 static struct attribute *podhd_dev_attrs[] = {
167 	&dev_attr_firmware_version.attr,
168 	&dev_attr_serial_number.attr,
169 	NULL
170 };
171 
172 static const struct attribute_group podhd_dev_attr_group = {
173 	.name = "podhd",
174 	.attrs = podhd_dev_attrs,
175 };
176 
177 /*
178  * POD X3 startup procedure.
179  *
180  * May be compatible with other POD HD's, since it's also similar to the
181  * previous POD setup. In any case, it doesn't seem to be required for the
182  * audio nor bulk interfaces to work.
183  */
184 
podhd_dev_start(struct usb_line6_podhd * pod)185 static int podhd_dev_start(struct usb_line6_podhd *pod)
186 {
187 	int ret;
188 	u8 init_bytes[8];
189 	int i;
190 	struct usb_device *usbdev = pod->line6.usbdev;
191 
192 	ret = usb_control_msg_send(usbdev, 0,
193 					0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
194 					0x11, 0,
195 					NULL, 0, LINE6_TIMEOUT, GFP_KERNEL);
196 	if (ret) {
197 		dev_err(pod->line6.ifcdev, "read request failed (error %d)\n", ret);
198 		goto exit;
199 	}
200 
201 	/* NOTE: looks like some kind of ping message */
202 	ret = usb_control_msg_recv(usbdev, 0, 0x67,
203 					USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
204 					0x11, 0x0,
205 					init_bytes, 3, LINE6_TIMEOUT, GFP_KERNEL);
206 	if (ret) {
207 		dev_err(pod->line6.ifcdev,
208 			"receive length failed (error %d)\n", ret);
209 		goto exit;
210 	}
211 
212 	pod->firmware_version =
213 		(init_bytes[0] << 16) | (init_bytes[1] << 8) | (init_bytes[2] << 0);
214 
215 	for (i = 0; i <= 16; i++) {
216 		ret = line6_read_data(&pod->line6, 0xf000 + 0x08 * i, init_bytes, 8);
217 		if (ret < 0)
218 			goto exit;
219 	}
220 
221 	ret = usb_control_msg_send(usbdev, 0,
222 					USB_REQ_SET_FEATURE,
223 					USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_DIR_OUT,
224 					1, 0,
225 					NULL, 0, LINE6_TIMEOUT, GFP_KERNEL);
226 exit:
227 	return ret;
228 }
229 
podhd_startup(struct usb_line6 * line6)230 static void podhd_startup(struct usb_line6 *line6)
231 {
232 	struct usb_line6_podhd *pod = line6_to_podhd(line6);
233 
234 	podhd_dev_start(pod);
235 	line6_read_serial_number(&pod->line6, &pod->serial_number);
236 	if (snd_card_register(line6->card))
237 		dev_err(line6->ifcdev, "Failed to register POD HD card.\n");
238 }
239 
podhd_disconnect(struct usb_line6 * line6)240 static void podhd_disconnect(struct usb_line6 *line6)
241 {
242 	struct usb_line6_podhd *pod = line6_to_podhd(line6);
243 
244 	if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO) {
245 		struct usb_interface *intf;
246 
247 		intf = usb_ifnum_to_if(line6->usbdev,
248 					pod->line6.properties->ctrl_if);
249 		if (intf)
250 			usb_driver_release_interface(&podhd_driver, intf);
251 	}
252 }
253 
254 static const unsigned int float_zero_to_one_lookup[] = {
255 0x00000000, 0x3c23d70a, 0x3ca3d70a, 0x3cf5c28f, 0x3d23d70a, 0x3d4ccccd,
256 0x3d75c28f, 0x3d8f5c29, 0x3da3d70a, 0x3db851ec, 0x3dcccccd, 0x3de147ae,
257 0x3df5c28f, 0x3e051eb8, 0x3e0f5c29, 0x3e19999a, 0x3e23d70a, 0x3e2e147b,
258 0x3e3851ec, 0x3e428f5c, 0x3e4ccccd, 0x3e570a3d, 0x3e6147ae, 0x3e6b851f,
259 0x3e75c28f, 0x3e800000, 0x3e851eb8, 0x3e8a3d71, 0x3e8f5c29, 0x3e947ae1,
260 0x3e99999a, 0x3e9eb852, 0x3ea3d70a, 0x3ea8f5c3, 0x3eae147b, 0x3eb33333,
261 0x3eb851ec, 0x3ebd70a4, 0x3ec28f5c, 0x3ec7ae14, 0x3ecccccd, 0x3ed1eb85,
262 0x3ed70a3d, 0x3edc28f6, 0x3ee147ae, 0x3ee66666, 0x3eeb851f, 0x3ef0a3d7,
263 0x3ef5c28f, 0x3efae148, 0x3f000000, 0x3f028f5c, 0x3f051eb8, 0x3f07ae14,
264 0x3f0a3d71, 0x3f0ccccd, 0x3f0f5c29, 0x3f11eb85, 0x3f147ae1, 0x3f170a3d,
265 0x3f19999a, 0x3f1c28f6, 0x3f1eb852, 0x3f2147ae, 0x3f23d70a, 0x3f266666,
266 0x3f28f5c3, 0x3f2b851f, 0x3f2e147b, 0x3f30a3d7, 0x3f333333, 0x3f35c28f,
267 0x3f3851ec, 0x3f3ae148, 0x3f3d70a4, 0x3f400000, 0x3f428f5c, 0x3f451eb8,
268 0x3f47ae14, 0x3f4a3d71, 0x3f4ccccd, 0x3f4f5c29, 0x3f51eb85, 0x3f547ae1,
269 0x3f570a3d, 0x3f59999a, 0x3f5c28f6, 0x3f5eb852, 0x3f6147ae, 0x3f63d70a,
270 0x3f666666, 0x3f68f5c3, 0x3f6b851f, 0x3f6e147b, 0x3f70a3d7, 0x3f733333,
271 0x3f75c28f, 0x3f7851ec, 0x3f7ae148, 0x3f7d70a4, 0x3f800000
272 };
273 
podhd_set_monitor_level(struct usb_line6_podhd * podhd,int value)274 static void podhd_set_monitor_level(struct usb_line6_podhd *podhd, int value)
275 {
276 	unsigned int fl;
277 	static const unsigned char msg[16] = {
278 		/* Chunk is 0xc bytes (without first word) */
279 		0x0c, 0x00,
280 		/* First chunk in the message */
281 		0x01, 0x00,
282 		/* Message size is 2 4-byte words */
283 		0x02, 0x00,
284 		/* Unknown */
285 		0x04, 0x41,
286 		/* Unknown */
287 		0x04, 0x00, 0x13, 0x00,
288 		/* Volume, LE float32, 0.0 - 1.0 */
289 		0x00, 0x00, 0x00, 0x00
290 	};
291 	unsigned char *buf;
292 
293 	buf = kmemdup(msg, sizeof(msg), GFP_KERNEL);
294 	if (!buf)
295 		return;
296 
297 	if (value < 0)
298 		value = 0;
299 
300 	if (value >= ARRAY_SIZE(float_zero_to_one_lookup))
301 		value = ARRAY_SIZE(float_zero_to_one_lookup) - 1;
302 
303 	fl = float_zero_to_one_lookup[value];
304 
305 	buf[12] = (fl >> 0) & 0xff;
306 	buf[13] = (fl >> 8) & 0xff;
307 	buf[14] = (fl >> 16) & 0xff;
308 	buf[15] = (fl >> 24) & 0xff;
309 
310 	line6_send_raw_message(&podhd->line6, buf, sizeof(msg));
311 	kfree(buf);
312 
313 	podhd->monitor_level = value;
314 }
315 
316 /* control info callback */
snd_podhd_control_monitor_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)317 static int snd_podhd_control_monitor_info(struct snd_kcontrol *kcontrol,
318 					struct snd_ctl_elem_info *uinfo)
319 {
320 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
321 	uinfo->count = 1;
322 	uinfo->value.integer.min = 0;
323 	uinfo->value.integer.max = 100;
324 	uinfo->value.integer.step = 1;
325 	return 0;
326 }
327 
328 /* control get callback */
snd_podhd_control_monitor_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)329 static int snd_podhd_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_podhd *podhd = line6_to_podhd(line6pcm->line6);
334 
335 	ucontrol->value.integer.value[0] = podhd->monitor_level;
336 	return 0;
337 }
338 
339 /* control put callback */
snd_podhd_control_monitor_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)340 static int snd_podhd_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_podhd *podhd = line6_to_podhd(line6pcm->line6);
345 
346 	if (ucontrol->value.integer.value[0] == podhd->monitor_level)
347 		return 0;
348 
349 	podhd_set_monitor_level(podhd, ucontrol->value.integer.value[0]);
350 	return 1;
351 }
352 
353 /* control definition */
354 static const struct snd_kcontrol_new podhd_control_monitor = {
355 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
356 	.name = "Monitor Playback Volume",
357 	.index = 0,
358 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
359 	.info = snd_podhd_control_monitor_info,
360 	.get = snd_podhd_control_monitor_get,
361 	.put = snd_podhd_control_monitor_put
362 };
363 
364 /*
365 	Try to init POD HD device.
366 */
podhd_init(struct usb_line6 * line6,const struct usb_device_id * id)367 static int podhd_init(struct usb_line6 *line6,
368 		      const struct usb_device_id *id)
369 {
370 	int err;
371 	struct usb_line6_podhd *pod = line6_to_podhd(line6);
372 	struct usb_interface *intf;
373 
374 	line6->disconnect = podhd_disconnect;
375 	line6->startup = podhd_startup;
376 
377 	if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
378 		/* claim the data interface */
379 		intf = usb_ifnum_to_if(line6->usbdev,
380 					pod->line6.properties->ctrl_if);
381 		if (!intf) {
382 			dev_err(pod->line6.ifcdev, "interface %d not found\n",
383 				pod->line6.properties->ctrl_if);
384 			return -ENODEV;
385 		}
386 
387 		err = usb_driver_claim_interface(&podhd_driver, intf, NULL);
388 		if (err != 0) {
389 			dev_err(pod->line6.ifcdev, "can't claim interface %d, error %d\n",
390 				pod->line6.properties->ctrl_if, err);
391 			return err;
392 		}
393 	}
394 
395 	if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO) {
396 		/* create sysfs entries: */
397 		err = snd_card_add_dev_attr(line6->card, &podhd_dev_attr_group);
398 		if (err < 0)
399 			return err;
400 	}
401 
402 	if (pod->line6.properties->capabilities & LINE6_CAP_PCM) {
403 		/* initialize PCM subsystem: */
404 		err = line6_init_pcm(line6,
405 			(id->driver_info == LINE6_PODX3 ||
406 			id->driver_info == LINE6_PODX3LIVE) ? &podx3_pcm_properties :
407 			&podhd_pcm_properties);
408 		if (err < 0)
409 			return err;
410 	}
411 
412 	if (pod->line6.properties->capabilities & LINE6_CAP_HWMON_CTL) {
413 		podhd_set_monitor_level(pod, 100);
414 		err = snd_ctl_add(line6->card,
415 				  snd_ctl_new1(&podhd_control_monitor,
416 					       line6->line6pcm));
417 		if (err < 0)
418 			return err;
419 	}
420 
421 	if (!(pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO)) {
422 		/* register USB audio system directly */
423 		return snd_card_register(line6->card);
424 	}
425 
426 	/* init device and delay registering */
427 	schedule_delayed_work(&line6->startup_work,
428 			      msecs_to_jiffies(PODHD_STARTUP_DELAY));
429 	return 0;
430 }
431 
432 #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
433 #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
434 
435 /* table of devices that work with this driver */
436 static const struct usb_device_id podhd_id_table[] = {
437 	/* TODO: no need to alloc data interfaces when only audio is used */
438 	{ LINE6_DEVICE(0x5057),    .driver_info = LINE6_PODHD300 },
439 	{ LINE6_DEVICE(0x5058),    .driver_info = LINE6_PODHD400 },
440 	{ LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500 },
441 	{ LINE6_IF_NUM(0x414A, 0), .driver_info = LINE6_PODX3 },
442 	{ LINE6_IF_NUM(0x414B, 0), .driver_info = LINE6_PODX3LIVE },
443 	{ LINE6_IF_NUM(0x4159, 0), .driver_info = LINE6_PODHD500X },
444 	{ LINE6_IF_NUM(0x4156, 0), .driver_info = LINE6_PODHDDESKTOP },
445 	{ LINE6_IF_NUM(0x415A, 0), .driver_info = LINE6_PODHDPROX },
446 	{ LINE6_IF_NUM(0x4157, 0), .driver_info = LINE6_PODHDPRO },
447 	{}
448 };
449 
450 MODULE_DEVICE_TABLE(usb, podhd_id_table);
451 
452 static const struct line6_properties podhd_properties_table[] = {
453 	[LINE6_PODHD300] = {
454 		.id = "PODHD300",
455 		.name = "POD HD300",
456 		.capabilities	= LINE6_CAP_PCM
457 				| LINE6_CAP_HWMON,
458 		.altsetting = 5,
459 		.ep_ctrl_r = 0x84,
460 		.ep_ctrl_w = 0x03,
461 		.ep_audio_r = 0x82,
462 		.ep_audio_w = 0x01,
463 	},
464 	[LINE6_PODHD400] = {
465 		.id = "PODHD400",
466 		.name = "POD HD400",
467 		.capabilities	= LINE6_CAP_PCM
468 				| LINE6_CAP_HWMON,
469 		.altsetting = 5,
470 		.ep_ctrl_r = 0x84,
471 		.ep_ctrl_w = 0x03,
472 		.ep_audio_r = 0x82,
473 		.ep_audio_w = 0x01,
474 	},
475 	[LINE6_PODHD500] = {
476 		.id = "PODHD500",
477 		.name = "POD HD500",
478 		.capabilities	= LINE6_CAP_PCM | LINE6_CAP_CONTROL
479 				| LINE6_CAP_HWMON | LINE6_CAP_HWMON_CTL,
480 		.altsetting = 1,
481 		.ctrl_if = 1,
482 		.ep_ctrl_r = 0x81,
483 		.ep_ctrl_w = 0x01,
484 		.ep_audio_r = 0x86,
485 		.ep_audio_w = 0x02,
486 	},
487 	[LINE6_PODX3] = {
488 		.id = "PODX3",
489 		.name = "POD X3",
490 		.capabilities	= LINE6_CAP_CONTROL | LINE6_CAP_CONTROL_INFO
491 				| LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT,
492 		.altsetting = 1,
493 		.ep_ctrl_r = 0x81,
494 		.ep_ctrl_w = 0x01,
495 		.ctrl_if = 1,
496 		.ep_audio_r = 0x86,
497 		.ep_audio_w = 0x02,
498 	},
499 	[LINE6_PODX3LIVE] = {
500 		.id = "PODX3LIVE",
501 		.name = "POD X3 LIVE",
502 		.capabilities	= LINE6_CAP_CONTROL | LINE6_CAP_CONTROL_INFO
503 				| LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT,
504 		.altsetting = 1,
505 		.ep_ctrl_r = 0x81,
506 		.ep_ctrl_w = 0x01,
507 		.ctrl_if = 1,
508 		.ep_audio_r = 0x86,
509 		.ep_audio_w = 0x02,
510 	},
511 	[LINE6_PODHD500X] = {
512 		.id = "PODHD500X",
513 		.name = "POD HD500X",
514 		.capabilities	= LINE6_CAP_CONTROL | LINE6_CAP_HWMON_CTL
515 				| LINE6_CAP_PCM | LINE6_CAP_HWMON,
516 		.altsetting = 1,
517 		.ep_ctrl_r = 0x81,
518 		.ep_ctrl_w = 0x01,
519 		.ctrl_if = 1,
520 		.ep_audio_r = 0x86,
521 		.ep_audio_w = 0x02,
522 	},
523 	[LINE6_PODHDDESKTOP] = {
524 		.id = "PODHDDESKTOP",
525 		.name = "POD HDDESKTOP",
526 		.capabilities    = LINE6_CAP_CONTROL
527 			| LINE6_CAP_PCM | LINE6_CAP_HWMON,
528 		.altsetting = 1,
529 		.ep_ctrl_r = 0x81,
530 		.ep_ctrl_w = 0x01,
531 		.ctrl_if = 1,
532 		.ep_audio_r = 0x86,
533 		.ep_audio_w = 0x02,
534 	},
535 	[LINE6_PODHDPROX] = {
536 		.id = "PODHDPROX",
537 		.name = "POD HD Pro X",
538 		.capabilities	= LINE6_CAP_CONTROL | LINE6_CAP_CONTROL_INFO
539 				| LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT,
540 		.altsetting = 1,
541 		.ctrl_if = 1,
542 		.ep_ctrl_r = 0x81,
543 		.ep_ctrl_w = 0x01,
544 		.ep_audio_r = 0x86,
545 		.ep_audio_w = 0x02,
546 	},
547 	[LINE6_PODHDPRO] = {
548 		.id = "PODHDPRO",
549 		.name = "POD HD PRO",
550 		.capabilities	= LINE6_CAP_PCM | LINE6_CAP_CONTROL
551 				| LINE6_CAP_HWMON | LINE6_CAP_HWMON_CTL | LINE6_CAP_IN_NEEDS_OUT,
552 		.altsetting = 1,
553 		.ctrl_if = 1,
554 		.ep_ctrl_r = 0x81,
555 		.ep_ctrl_w = 0x01,
556 		.ep_audio_r = 0x86,
557 		.ep_audio_w = 0x02,
558 	},
559 };
560 
561 /*
562 	Probe USB device.
563 */
podhd_probe(struct usb_interface * interface,const struct usb_device_id * id)564 static int podhd_probe(struct usb_interface *interface,
565 		       const struct usb_device_id *id)
566 {
567 	return line6_probe(interface, id, "Line6-PODHD",
568 			   &podhd_properties_table[id->driver_info],
569 			   podhd_init, sizeof(struct usb_line6_podhd));
570 }
571 
572 static struct usb_driver podhd_driver = {
573 	.name = KBUILD_MODNAME,
574 	.probe = podhd_probe,
575 	.disconnect = line6_disconnect,
576 #ifdef CONFIG_PM
577 	.suspend = line6_suspend,
578 	.resume = line6_resume,
579 	.reset_resume = line6_resume,
580 #endif
581 	.id_table = podhd_id_table,
582 };
583 
584 module_usb_driver(podhd_driver);
585 
586 MODULE_DESCRIPTION("Line 6 PODHD USB driver");
587 MODULE_LICENSE("GPL");
588