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