1 // SPDX-License-Identifier: GPL-2.0-only
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>
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>
20 #define PODHD_STARTUP_DELAY 500
32 struct usb_line6_podhd
{
33 /* Generic Line 6 USB data */
34 struct usb_line6 line6
;
36 /* Serial number of device */
39 /* Firmware version */
46 #define line6_to_podhd(x) container_of(x, struct usb_line6_podhd, line6)
48 static const struct snd_ratden podhd_ratden
= {
55 static struct line6_pcm_properties podhd_pcm_properties
= {
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
,
69 .buffer_bytes_max
= 60000,
70 .period_bytes_min
= 64,
71 .period_bytes_max
= 8192,
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
,
86 .buffer_bytes_max
= 60000,
87 .period_bytes_min
= 64,
88 .period_bytes_max
= 8192,
93 .rats
= &podhd_ratden
},
94 .bytes_per_channel
= 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
97 static struct line6_pcm_properties podx3_pcm_properties
= {
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
,
111 .buffer_bytes_max
= 60000,
112 .period_bytes_min
= 64,
113 .period_bytes_max
= 8192,
115 .periods_max
= 1024},
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
,
126 /* 1+2: Main signal (out), 3+4: Tone 1,
127 * 5+6: Tone 2, 7+8: raw
131 .buffer_bytes_max
= 60000,
132 .period_bytes_min
= 64,
133 .period_bytes_max
= 8192,
135 .periods_max
= 1024},
138 .rats
= &podhd_ratden
},
139 .bytes_per_channel
= 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
141 static struct usb_driver podhd_driver
;
143 static ssize_t
serial_number_show(struct device
*dev
,
144 struct device_attribute
*attr
, char *buf
)
146 struct snd_card
*card
= dev_to_snd_card(dev
);
147 struct usb_line6_podhd
*pod
= card
->private_data
;
149 return sprintf(buf
, "%u\n", pod
->serial_number
);
152 static ssize_t
firmware_version_show(struct device
*dev
,
153 struct device_attribute
*attr
, char *buf
)
155 struct snd_card
*card
= dev_to_snd_card(dev
);
156 struct usb_line6_podhd
*pod
= card
->private_data
;
158 return sprintf(buf
, "%06x\n", pod
->firmware_version
);
161 static DEVICE_ATTR_RO(firmware_version
);
162 static DEVICE_ATTR_RO(serial_number
);
164 static struct attribute
*podhd_dev_attrs
[] = {
165 &dev_attr_firmware_version
.attr
,
166 &dev_attr_serial_number
.attr
,
170 static const struct attribute_group podhd_dev_attr_group
= {
172 .attrs
= podhd_dev_attrs
,
176 * POD X3 startup procedure.
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.
183 static int podhd_dev_start(struct usb_line6_podhd
*pod
)
188 struct usb_device
*usbdev
= pod
->line6
.usbdev
;
190 init_bytes
= kmalloc(8, GFP_KERNEL
);
194 ret
= usb_control_msg(usbdev
, usb_sndctrlpipe(usbdev
, 0),
195 0x67, USB_TYPE_VENDOR
| USB_RECIP_DEVICE
| USB_DIR_OUT
,
197 NULL
, 0, LINE6_TIMEOUT
* HZ
);
199 dev_err(pod
->line6
.ifcdev
, "read request failed (error %d)\n", ret
);
203 /* NOTE: looks like some kind of ping message */
204 ret
= usb_control_msg(usbdev
, usb_rcvctrlpipe(usbdev
, 0), 0x67,
205 USB_TYPE_VENDOR
| USB_RECIP_DEVICE
| USB_DIR_IN
,
207 init_bytes
, 3, LINE6_TIMEOUT
* HZ
);
209 dev_err(pod
->line6
.ifcdev
,
210 "receive length failed (error %d)\n", ret
);
214 pod
->firmware_version
=
215 (init_bytes
[0] << 16) | (init_bytes
[1] << 8) | (init_bytes
[2] << 0);
217 for (i
= 0; i
<= 16; i
++) {
218 ret
= line6_read_data(&pod
->line6
, 0xf000 + 0x08 * i
, init_bytes
, 8);
223 ret
= usb_control_msg(usbdev
, usb_sndctrlpipe(usbdev
, 0),
225 USB_TYPE_STANDARD
| USB_RECIP_DEVICE
| USB_DIR_OUT
,
227 NULL
, 0, LINE6_TIMEOUT
* HZ
);
233 static void podhd_startup(struct usb_line6
*line6
)
235 struct usb_line6_podhd
*pod
= line6_to_podhd(line6
);
237 podhd_dev_start(pod
);
238 line6_read_serial_number(&pod
->line6
, &pod
->serial_number
);
239 if (snd_card_register(line6
->card
))
240 dev_err(line6
->ifcdev
, "Failed to register POD HD card.\n");
243 static void podhd_disconnect(struct usb_line6
*line6
)
245 struct usb_line6_podhd
*pod
= line6_to_podhd(line6
);
247 if (pod
->line6
.properties
->capabilities
& LINE6_CAP_CONTROL_INFO
) {
248 struct usb_interface
*intf
;
250 intf
= usb_ifnum_to_if(line6
->usbdev
,
251 pod
->line6
.properties
->ctrl_if
);
253 usb_driver_release_interface(&podhd_driver
, intf
);
257 static const unsigned int float_zero_to_one_lookup
[] = {
258 0x00000000, 0x3c23d70a, 0x3ca3d70a, 0x3cf5c28f, 0x3d23d70a, 0x3d4ccccd,
259 0x3d75c28f, 0x3d8f5c29, 0x3da3d70a, 0x3db851ec, 0x3dcccccd, 0x3de147ae,
260 0x3df5c28f, 0x3e051eb8, 0x3e0f5c29, 0x3e19999a, 0x3e23d70a, 0x3e2e147b,
261 0x3e3851ec, 0x3e428f5c, 0x3e4ccccd, 0x3e570a3d, 0x3e6147ae, 0x3e6b851f,
262 0x3e75c28f, 0x3e800000, 0x3e851eb8, 0x3e8a3d71, 0x3e8f5c29, 0x3e947ae1,
263 0x3e99999a, 0x3e9eb852, 0x3ea3d70a, 0x3ea8f5c3, 0x3eae147b, 0x3eb33333,
264 0x3eb851ec, 0x3ebd70a4, 0x3ec28f5c, 0x3ec7ae14, 0x3ecccccd, 0x3ed1eb85,
265 0x3ed70a3d, 0x3edc28f6, 0x3ee147ae, 0x3ee66666, 0x3eeb851f, 0x3ef0a3d7,
266 0x3ef5c28f, 0x3efae148, 0x3f000000, 0x3f028f5c, 0x3f051eb8, 0x3f07ae14,
267 0x3f0a3d71, 0x3f0ccccd, 0x3f0f5c29, 0x3f11eb85, 0x3f147ae1, 0x3f170a3d,
268 0x3f19999a, 0x3f1c28f6, 0x3f1eb852, 0x3f2147ae, 0x3f23d70a, 0x3f266666,
269 0x3f28f5c3, 0x3f2b851f, 0x3f2e147b, 0x3f30a3d7, 0x3f333333, 0x3f35c28f,
270 0x3f3851ec, 0x3f3ae148, 0x3f3d70a4, 0x3f400000, 0x3f428f5c, 0x3f451eb8,
271 0x3f47ae14, 0x3f4a3d71, 0x3f4ccccd, 0x3f4f5c29, 0x3f51eb85, 0x3f547ae1,
272 0x3f570a3d, 0x3f59999a, 0x3f5c28f6, 0x3f5eb852, 0x3f6147ae, 0x3f63d70a,
273 0x3f666666, 0x3f68f5c3, 0x3f6b851f, 0x3f6e147b, 0x3f70a3d7, 0x3f733333,
274 0x3f75c28f, 0x3f7851ec, 0x3f7ae148, 0x3f7d70a4, 0x3f800000
277 static void podhd_set_monitor_level(struct usb_line6_podhd
*podhd
, int value
)
280 static const unsigned char msg
[16] = {
281 /* Chunk is 0xc bytes (without first word) */
283 /* First chunk in the message */
285 /* Message size is 2 4-byte words */
290 0x04, 0x00, 0x13, 0x00,
291 /* Volume, LE float32, 0.0 - 1.0 */
292 0x00, 0x00, 0x00, 0x00
296 buf
= kmemdup(msg
, sizeof(msg
), GFP_KERNEL
);
303 if (value
>= ARRAY_SIZE(float_zero_to_one_lookup
))
304 value
= ARRAY_SIZE(float_zero_to_one_lookup
) - 1;
306 fl
= float_zero_to_one_lookup
[value
];
308 buf
[12] = (fl
>> 0) & 0xff;
309 buf
[13] = (fl
>> 8) & 0xff;
310 buf
[14] = (fl
>> 16) & 0xff;
311 buf
[15] = (fl
>> 24) & 0xff;
313 line6_send_raw_message(&podhd
->line6
, buf
, sizeof(msg
));
316 podhd
->monitor_level
= value
;
319 /* control info callback */
320 static int snd_podhd_control_monitor_info(struct snd_kcontrol
*kcontrol
,
321 struct snd_ctl_elem_info
*uinfo
)
323 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
325 uinfo
->value
.integer
.min
= 0;
326 uinfo
->value
.integer
.max
= 100;
327 uinfo
->value
.integer
.step
= 1;
331 /* control get callback */
332 static int snd_podhd_control_monitor_get(struct snd_kcontrol
*kcontrol
,
333 struct snd_ctl_elem_value
*ucontrol
)
335 struct snd_line6_pcm
*line6pcm
= snd_kcontrol_chip(kcontrol
);
336 struct usb_line6_podhd
*podhd
= line6_to_podhd(line6pcm
->line6
);
338 ucontrol
->value
.integer
.value
[0] = podhd
->monitor_level
;
342 /* control put callback */
343 static int snd_podhd_control_monitor_put(struct snd_kcontrol
*kcontrol
,
344 struct snd_ctl_elem_value
*ucontrol
)
346 struct snd_line6_pcm
*line6pcm
= snd_kcontrol_chip(kcontrol
);
347 struct usb_line6_podhd
*podhd
= line6_to_podhd(line6pcm
->line6
);
349 if (ucontrol
->value
.integer
.value
[0] == podhd
->monitor_level
)
352 podhd_set_monitor_level(podhd
, ucontrol
->value
.integer
.value
[0]);
356 /* control definition */
357 static const struct snd_kcontrol_new podhd_control_monitor
= {
358 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
359 .name
= "Monitor Playback Volume",
361 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
,
362 .info
= snd_podhd_control_monitor_info
,
363 .get
= snd_podhd_control_monitor_get
,
364 .put
= snd_podhd_control_monitor_put
368 Try to init POD HD device.
370 static int podhd_init(struct usb_line6
*line6
,
371 const struct usb_device_id
*id
)
374 struct usb_line6_podhd
*pod
= line6_to_podhd(line6
);
375 struct usb_interface
*intf
;
377 line6
->disconnect
= podhd_disconnect
;
378 line6
->startup
= podhd_startup
;
380 if (pod
->line6
.properties
->capabilities
& LINE6_CAP_CONTROL
) {
381 /* claim the data interface */
382 intf
= usb_ifnum_to_if(line6
->usbdev
,
383 pod
->line6
.properties
->ctrl_if
);
385 dev_err(pod
->line6
.ifcdev
, "interface %d not found\n",
386 pod
->line6
.properties
->ctrl_if
);
390 err
= usb_driver_claim_interface(&podhd_driver
, intf
, NULL
);
392 dev_err(pod
->line6
.ifcdev
, "can't claim interface %d, error %d\n",
393 pod
->line6
.properties
->ctrl_if
, err
);
398 if (pod
->line6
.properties
->capabilities
& LINE6_CAP_CONTROL_INFO
) {
399 /* create sysfs entries: */
400 err
= snd_card_add_dev_attr(line6
->card
, &podhd_dev_attr_group
);
405 if (pod
->line6
.properties
->capabilities
& LINE6_CAP_PCM
) {
406 /* initialize PCM subsystem: */
407 err
= line6_init_pcm(line6
,
408 (id
->driver_info
== LINE6_PODX3
||
409 id
->driver_info
== LINE6_PODX3LIVE
) ? &podx3_pcm_properties
:
410 &podhd_pcm_properties
);
415 if (pod
->line6
.properties
->capabilities
& LINE6_CAP_HWMON_CTL
) {
416 podhd_set_monitor_level(pod
, 100);
417 err
= snd_ctl_add(line6
->card
,
418 snd_ctl_new1(&podhd_control_monitor
,
424 if (!(pod
->line6
.properties
->capabilities
& LINE6_CAP_CONTROL_INFO
)) {
425 /* register USB audio system directly */
426 return snd_card_register(line6
->card
);
429 /* init device and delay registering */
430 schedule_delayed_work(&line6
->startup_work
,
431 msecs_to_jiffies(PODHD_STARTUP_DELAY
));
435 #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
436 #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
438 /* table of devices that work with this driver */
439 static const struct usb_device_id podhd_id_table
[] = {
440 /* TODO: no need to alloc data interfaces when only audio is used */
441 { LINE6_DEVICE(0x5057), .driver_info
= LINE6_PODHD300
},
442 { LINE6_DEVICE(0x5058), .driver_info
= LINE6_PODHD400
},
443 { LINE6_IF_NUM(0x414D, 0), .driver_info
= LINE6_PODHD500
},
444 { LINE6_IF_NUM(0x414A, 0), .driver_info
= LINE6_PODX3
},
445 { LINE6_IF_NUM(0x414B, 0), .driver_info
= LINE6_PODX3LIVE
},
446 { LINE6_IF_NUM(0x4159, 0), .driver_info
= LINE6_PODHD500X
},
447 { LINE6_IF_NUM(0x4156, 0), .driver_info
= LINE6_PODHDDESKTOP
},
451 MODULE_DEVICE_TABLE(usb
, podhd_id_table
);
453 static const struct line6_properties podhd_properties_table
[] = {
457 .capabilities
= LINE6_CAP_PCM
468 .capabilities
= LINE6_CAP_PCM
479 .capabilities
= LINE6_CAP_PCM
| LINE6_CAP_CONTROL
480 | LINE6_CAP_HWMON
| LINE6_CAP_HWMON_CTL
,
491 .capabilities
= LINE6_CAP_CONTROL
| LINE6_CAP_CONTROL_INFO
492 | LINE6_CAP_PCM
| LINE6_CAP_HWMON
| LINE6_CAP_IN_NEEDS_OUT
,
500 [LINE6_PODX3LIVE
] = {
502 .name
= "POD X3 LIVE",
503 .capabilities
= LINE6_CAP_CONTROL
| LINE6_CAP_CONTROL_INFO
504 | LINE6_CAP_PCM
| LINE6_CAP_HWMON
| LINE6_CAP_IN_NEEDS_OUT
,
512 [LINE6_PODHD500X
] = {
514 .name
= "POD HD500X",
515 .capabilities
= LINE6_CAP_CONTROL
516 | LINE6_CAP_PCM
| LINE6_CAP_HWMON
,
524 [LINE6_PODHDDESKTOP
] = {
525 .id
= "PODHDDESKTOP",
526 .name
= "POD HDDESKTOP",
527 .capabilities
= LINE6_CAP_CONTROL
528 | LINE6_CAP_PCM
| LINE6_CAP_HWMON
,
541 static int podhd_probe(struct usb_interface
*interface
,
542 const struct usb_device_id
*id
)
544 return line6_probe(interface
, id
, "Line6-PODHD",
545 &podhd_properties_table
[id
->driver_info
],
546 podhd_init
, sizeof(struct usb_line6_podhd
));
549 static struct usb_driver podhd_driver
= {
550 .name
= KBUILD_MODNAME
,
551 .probe
= podhd_probe
,
552 .disconnect
= line6_disconnect
,
554 .suspend
= line6_suspend
,
555 .resume
= line6_resume
,
556 .reset_resume
= line6_resume
,
558 .id_table
= podhd_id_table
,
561 module_usb_driver(podhd_driver
);
563 MODULE_DESCRIPTION("Line 6 PODHD USB driver");
564 MODULE_LICENSE("GPL");