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