0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/usb.h>
0011 #include <linux/slab.h>
0012 #include <linux/module.h>
0013 #include <sound/core.h>
0014 #include <sound/control.h>
0015 #include <sound/pcm.h>
0016
0017 #include "driver.h"
0018 #include "pcm.h"
0019
0020 #define PODHD_STARTUP_DELAY 500
0021
0022 enum {
0023 LINE6_PODHD300,
0024 LINE6_PODHD400,
0025 LINE6_PODHD500,
0026 LINE6_PODX3,
0027 LINE6_PODX3LIVE,
0028 LINE6_PODHD500X,
0029 LINE6_PODHDDESKTOP
0030 };
0031
0032 struct usb_line6_podhd {
0033
0034 struct usb_line6 line6;
0035
0036
0037 u32 serial_number;
0038
0039
0040 int firmware_version;
0041
0042
0043 int monitor_level;
0044 };
0045
0046 #define line6_to_podhd(x) container_of(x, struct usb_line6_podhd, line6)
0047
0048 static const struct snd_ratden podhd_ratden = {
0049 .num_min = 48000,
0050 .num_max = 48000,
0051 .num_step = 1,
0052 .den = 1,
0053 };
0054
0055 static struct line6_pcm_properties podhd_pcm_properties = {
0056 .playback_hw = {
0057 .info = (SNDRV_PCM_INFO_MMAP |
0058 SNDRV_PCM_INFO_INTERLEAVED |
0059 SNDRV_PCM_INFO_BLOCK_TRANSFER |
0060 SNDRV_PCM_INFO_MMAP_VALID |
0061 SNDRV_PCM_INFO_PAUSE |
0062 SNDRV_PCM_INFO_SYNC_START),
0063 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
0064 .rates = SNDRV_PCM_RATE_48000,
0065 .rate_min = 48000,
0066 .rate_max = 48000,
0067 .channels_min = 2,
0068 .channels_max = 2,
0069 .buffer_bytes_max = 60000,
0070 .period_bytes_min = 64,
0071 .period_bytes_max = 8192,
0072 .periods_min = 1,
0073 .periods_max = 1024},
0074 .capture_hw = {
0075 .info = (SNDRV_PCM_INFO_MMAP |
0076 SNDRV_PCM_INFO_INTERLEAVED |
0077 SNDRV_PCM_INFO_BLOCK_TRANSFER |
0078 SNDRV_PCM_INFO_MMAP_VALID |
0079 SNDRV_PCM_INFO_SYNC_START),
0080 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
0081 .rates = SNDRV_PCM_RATE_48000,
0082 .rate_min = 48000,
0083 .rate_max = 48000,
0084 .channels_min = 2,
0085 .channels_max = 2,
0086 .buffer_bytes_max = 60000,
0087 .period_bytes_min = 64,
0088 .period_bytes_max = 8192,
0089 .periods_min = 1,
0090 .periods_max = 1024},
0091 .rates = {
0092 .nrats = 1,
0093 .rats = &podhd_ratden},
0094 .bytes_per_channel = 3
0095 };
0096
0097 static struct line6_pcm_properties podx3_pcm_properties = {
0098 .playback_hw = {
0099 .info = (SNDRV_PCM_INFO_MMAP |
0100 SNDRV_PCM_INFO_INTERLEAVED |
0101 SNDRV_PCM_INFO_BLOCK_TRANSFER |
0102 SNDRV_PCM_INFO_MMAP_VALID |
0103 SNDRV_PCM_INFO_PAUSE |
0104 SNDRV_PCM_INFO_SYNC_START),
0105 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
0106 .rates = SNDRV_PCM_RATE_48000,
0107 .rate_min = 48000,
0108 .rate_max = 48000,
0109 .channels_min = 2,
0110 .channels_max = 2,
0111 .buffer_bytes_max = 60000,
0112 .period_bytes_min = 64,
0113 .period_bytes_max = 8192,
0114 .periods_min = 1,
0115 .periods_max = 1024},
0116 .capture_hw = {
0117 .info = (SNDRV_PCM_INFO_MMAP |
0118 SNDRV_PCM_INFO_INTERLEAVED |
0119 SNDRV_PCM_INFO_BLOCK_TRANSFER |
0120 SNDRV_PCM_INFO_MMAP_VALID |
0121 SNDRV_PCM_INFO_SYNC_START),
0122 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
0123 .rates = SNDRV_PCM_RATE_48000,
0124 .rate_min = 48000,
0125 .rate_max = 48000,
0126
0127
0128
0129 .channels_min = 8,
0130 .channels_max = 8,
0131 .buffer_bytes_max = 60000,
0132 .period_bytes_min = 64,
0133 .period_bytes_max = 8192,
0134 .periods_min = 1,
0135 .periods_max = 1024},
0136 .rates = {
0137 .nrats = 1,
0138 .rats = &podhd_ratden},
0139 .bytes_per_channel = 3
0140 };
0141 static struct usb_driver podhd_driver;
0142
0143 static ssize_t serial_number_show(struct device *dev,
0144 struct device_attribute *attr, char *buf)
0145 {
0146 struct snd_card *card = dev_to_snd_card(dev);
0147 struct usb_line6_podhd *pod = card->private_data;
0148
0149 return sysfs_emit(buf, "%u\n", pod->serial_number);
0150 }
0151
0152 static ssize_t firmware_version_show(struct device *dev,
0153 struct device_attribute *attr, char *buf)
0154 {
0155 struct snd_card *card = dev_to_snd_card(dev);
0156 struct usb_line6_podhd *pod = card->private_data;
0157
0158 return sysfs_emit(buf, "%06x\n", pod->firmware_version);
0159 }
0160
0161 static DEVICE_ATTR_RO(firmware_version);
0162 static DEVICE_ATTR_RO(serial_number);
0163
0164 static struct attribute *podhd_dev_attrs[] = {
0165 &dev_attr_firmware_version.attr,
0166 &dev_attr_serial_number.attr,
0167 NULL
0168 };
0169
0170 static const struct attribute_group podhd_dev_attr_group = {
0171 .name = "podhd",
0172 .attrs = podhd_dev_attrs,
0173 };
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183 static int podhd_dev_start(struct usb_line6_podhd *pod)
0184 {
0185 int ret;
0186 u8 init_bytes[8];
0187 int i;
0188 struct usb_device *usbdev = pod->line6.usbdev;
0189
0190 ret = usb_control_msg_send(usbdev, 0,
0191 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
0192 0x11, 0,
0193 NULL, 0, LINE6_TIMEOUT, GFP_KERNEL);
0194 if (ret) {
0195 dev_err(pod->line6.ifcdev, "read request failed (error %d)\n", ret);
0196 goto exit;
0197 }
0198
0199
0200 ret = usb_control_msg_recv(usbdev, 0, 0x67,
0201 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
0202 0x11, 0x0,
0203 init_bytes, 3, LINE6_TIMEOUT, GFP_KERNEL);
0204 if (ret) {
0205 dev_err(pod->line6.ifcdev,
0206 "receive length failed (error %d)\n", ret);
0207 goto exit;
0208 }
0209
0210 pod->firmware_version =
0211 (init_bytes[0] << 16) | (init_bytes[1] << 8) | (init_bytes[2] << 0);
0212
0213 for (i = 0; i <= 16; i++) {
0214 ret = line6_read_data(&pod->line6, 0xf000 + 0x08 * i, init_bytes, 8);
0215 if (ret < 0)
0216 goto exit;
0217 }
0218
0219 ret = usb_control_msg_send(usbdev, 0,
0220 USB_REQ_SET_FEATURE,
0221 USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_DIR_OUT,
0222 1, 0,
0223 NULL, 0, LINE6_TIMEOUT, GFP_KERNEL);
0224 exit:
0225 return ret;
0226 }
0227
0228 static void podhd_startup(struct usb_line6 *line6)
0229 {
0230 struct usb_line6_podhd *pod = line6_to_podhd(line6);
0231
0232 podhd_dev_start(pod);
0233 line6_read_serial_number(&pod->line6, &pod->serial_number);
0234 if (snd_card_register(line6->card))
0235 dev_err(line6->ifcdev, "Failed to register POD HD card.\n");
0236 }
0237
0238 static void podhd_disconnect(struct usb_line6 *line6)
0239 {
0240 struct usb_line6_podhd *pod = line6_to_podhd(line6);
0241
0242 if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO) {
0243 struct usb_interface *intf;
0244
0245 intf = usb_ifnum_to_if(line6->usbdev,
0246 pod->line6.properties->ctrl_if);
0247 if (intf)
0248 usb_driver_release_interface(&podhd_driver, intf);
0249 }
0250 }
0251
0252 static const unsigned int float_zero_to_one_lookup[] = {
0253 0x00000000, 0x3c23d70a, 0x3ca3d70a, 0x3cf5c28f, 0x3d23d70a, 0x3d4ccccd,
0254 0x3d75c28f, 0x3d8f5c29, 0x3da3d70a, 0x3db851ec, 0x3dcccccd, 0x3de147ae,
0255 0x3df5c28f, 0x3e051eb8, 0x3e0f5c29, 0x3e19999a, 0x3e23d70a, 0x3e2e147b,
0256 0x3e3851ec, 0x3e428f5c, 0x3e4ccccd, 0x3e570a3d, 0x3e6147ae, 0x3e6b851f,
0257 0x3e75c28f, 0x3e800000, 0x3e851eb8, 0x3e8a3d71, 0x3e8f5c29, 0x3e947ae1,
0258 0x3e99999a, 0x3e9eb852, 0x3ea3d70a, 0x3ea8f5c3, 0x3eae147b, 0x3eb33333,
0259 0x3eb851ec, 0x3ebd70a4, 0x3ec28f5c, 0x3ec7ae14, 0x3ecccccd, 0x3ed1eb85,
0260 0x3ed70a3d, 0x3edc28f6, 0x3ee147ae, 0x3ee66666, 0x3eeb851f, 0x3ef0a3d7,
0261 0x3ef5c28f, 0x3efae148, 0x3f000000, 0x3f028f5c, 0x3f051eb8, 0x3f07ae14,
0262 0x3f0a3d71, 0x3f0ccccd, 0x3f0f5c29, 0x3f11eb85, 0x3f147ae1, 0x3f170a3d,
0263 0x3f19999a, 0x3f1c28f6, 0x3f1eb852, 0x3f2147ae, 0x3f23d70a, 0x3f266666,
0264 0x3f28f5c3, 0x3f2b851f, 0x3f2e147b, 0x3f30a3d7, 0x3f333333, 0x3f35c28f,
0265 0x3f3851ec, 0x3f3ae148, 0x3f3d70a4, 0x3f400000, 0x3f428f5c, 0x3f451eb8,
0266 0x3f47ae14, 0x3f4a3d71, 0x3f4ccccd, 0x3f4f5c29, 0x3f51eb85, 0x3f547ae1,
0267 0x3f570a3d, 0x3f59999a, 0x3f5c28f6, 0x3f5eb852, 0x3f6147ae, 0x3f63d70a,
0268 0x3f666666, 0x3f68f5c3, 0x3f6b851f, 0x3f6e147b, 0x3f70a3d7, 0x3f733333,
0269 0x3f75c28f, 0x3f7851ec, 0x3f7ae148, 0x3f7d70a4, 0x3f800000
0270 };
0271
0272 static void podhd_set_monitor_level(struct usb_line6_podhd *podhd, int value)
0273 {
0274 unsigned int fl;
0275 static const unsigned char msg[16] = {
0276
0277 0x0c, 0x00,
0278
0279 0x01, 0x00,
0280
0281 0x02, 0x00,
0282
0283 0x04, 0x41,
0284
0285 0x04, 0x00, 0x13, 0x00,
0286
0287 0x00, 0x00, 0x00, 0x00
0288 };
0289 unsigned char *buf;
0290
0291 buf = kmemdup(msg, sizeof(msg), GFP_KERNEL);
0292 if (!buf)
0293 return;
0294
0295 if (value < 0)
0296 value = 0;
0297
0298 if (value >= ARRAY_SIZE(float_zero_to_one_lookup))
0299 value = ARRAY_SIZE(float_zero_to_one_lookup) - 1;
0300
0301 fl = float_zero_to_one_lookup[value];
0302
0303 buf[12] = (fl >> 0) & 0xff;
0304 buf[13] = (fl >> 8) & 0xff;
0305 buf[14] = (fl >> 16) & 0xff;
0306 buf[15] = (fl >> 24) & 0xff;
0307
0308 line6_send_raw_message(&podhd->line6, buf, sizeof(msg));
0309 kfree(buf);
0310
0311 podhd->monitor_level = value;
0312 }
0313
0314
0315 static int snd_podhd_control_monitor_info(struct snd_kcontrol *kcontrol,
0316 struct snd_ctl_elem_info *uinfo)
0317 {
0318 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0319 uinfo->count = 1;
0320 uinfo->value.integer.min = 0;
0321 uinfo->value.integer.max = 100;
0322 uinfo->value.integer.step = 1;
0323 return 0;
0324 }
0325
0326
0327 static int snd_podhd_control_monitor_get(struct snd_kcontrol *kcontrol,
0328 struct snd_ctl_elem_value *ucontrol)
0329 {
0330 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
0331 struct usb_line6_podhd *podhd = line6_to_podhd(line6pcm->line6);
0332
0333 ucontrol->value.integer.value[0] = podhd->monitor_level;
0334 return 0;
0335 }
0336
0337
0338 static int snd_podhd_control_monitor_put(struct snd_kcontrol *kcontrol,
0339 struct snd_ctl_elem_value *ucontrol)
0340 {
0341 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
0342 struct usb_line6_podhd *podhd = line6_to_podhd(line6pcm->line6);
0343
0344 if (ucontrol->value.integer.value[0] == podhd->monitor_level)
0345 return 0;
0346
0347 podhd_set_monitor_level(podhd, ucontrol->value.integer.value[0]);
0348 return 1;
0349 }
0350
0351
0352 static const struct snd_kcontrol_new podhd_control_monitor = {
0353 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0354 .name = "Monitor Playback Volume",
0355 .index = 0,
0356 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0357 .info = snd_podhd_control_monitor_info,
0358 .get = snd_podhd_control_monitor_get,
0359 .put = snd_podhd_control_monitor_put
0360 };
0361
0362
0363
0364
0365 static int podhd_init(struct usb_line6 *line6,
0366 const struct usb_device_id *id)
0367 {
0368 int err;
0369 struct usb_line6_podhd *pod = line6_to_podhd(line6);
0370 struct usb_interface *intf;
0371
0372 line6->disconnect = podhd_disconnect;
0373 line6->startup = podhd_startup;
0374
0375 if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
0376
0377 intf = usb_ifnum_to_if(line6->usbdev,
0378 pod->line6.properties->ctrl_if);
0379 if (!intf) {
0380 dev_err(pod->line6.ifcdev, "interface %d not found\n",
0381 pod->line6.properties->ctrl_if);
0382 return -ENODEV;
0383 }
0384
0385 err = usb_driver_claim_interface(&podhd_driver, intf, NULL);
0386 if (err != 0) {
0387 dev_err(pod->line6.ifcdev, "can't claim interface %d, error %d\n",
0388 pod->line6.properties->ctrl_if, err);
0389 return err;
0390 }
0391 }
0392
0393 if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO) {
0394
0395 err = snd_card_add_dev_attr(line6->card, &podhd_dev_attr_group);
0396 if (err < 0)
0397 return err;
0398 }
0399
0400 if (pod->line6.properties->capabilities & LINE6_CAP_PCM) {
0401
0402 err = line6_init_pcm(line6,
0403 (id->driver_info == LINE6_PODX3 ||
0404 id->driver_info == LINE6_PODX3LIVE) ? &podx3_pcm_properties :
0405 &podhd_pcm_properties);
0406 if (err < 0)
0407 return err;
0408 }
0409
0410 if (pod->line6.properties->capabilities & LINE6_CAP_HWMON_CTL) {
0411 podhd_set_monitor_level(pod, 100);
0412 err = snd_ctl_add(line6->card,
0413 snd_ctl_new1(&podhd_control_monitor,
0414 line6->line6pcm));
0415 if (err < 0)
0416 return err;
0417 }
0418
0419 if (!(pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO)) {
0420
0421 return snd_card_register(line6->card);
0422 }
0423
0424
0425 schedule_delayed_work(&line6->startup_work,
0426 msecs_to_jiffies(PODHD_STARTUP_DELAY));
0427 return 0;
0428 }
0429
0430 #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
0431 #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
0432
0433
0434 static const struct usb_device_id podhd_id_table[] = {
0435
0436 { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 },
0437 { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 },
0438 { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500 },
0439 { LINE6_IF_NUM(0x414A, 0), .driver_info = LINE6_PODX3 },
0440 { LINE6_IF_NUM(0x414B, 0), .driver_info = LINE6_PODX3LIVE },
0441 { LINE6_IF_NUM(0x4159, 0), .driver_info = LINE6_PODHD500X },
0442 { LINE6_IF_NUM(0x4156, 0), .driver_info = LINE6_PODHDDESKTOP },
0443 {}
0444 };
0445
0446 MODULE_DEVICE_TABLE(usb, podhd_id_table);
0447
0448 static const struct line6_properties podhd_properties_table[] = {
0449 [LINE6_PODHD300] = {
0450 .id = "PODHD300",
0451 .name = "POD HD300",
0452 .capabilities = LINE6_CAP_PCM
0453 | LINE6_CAP_HWMON,
0454 .altsetting = 5,
0455 .ep_ctrl_r = 0x84,
0456 .ep_ctrl_w = 0x03,
0457 .ep_audio_r = 0x82,
0458 .ep_audio_w = 0x01,
0459 },
0460 [LINE6_PODHD400] = {
0461 .id = "PODHD400",
0462 .name = "POD HD400",
0463 .capabilities = LINE6_CAP_PCM
0464 | LINE6_CAP_HWMON,
0465 .altsetting = 5,
0466 .ep_ctrl_r = 0x84,
0467 .ep_ctrl_w = 0x03,
0468 .ep_audio_r = 0x82,
0469 .ep_audio_w = 0x01,
0470 },
0471 [LINE6_PODHD500] = {
0472 .id = "PODHD500",
0473 .name = "POD HD500",
0474 .capabilities = LINE6_CAP_PCM | LINE6_CAP_CONTROL
0475 | LINE6_CAP_HWMON | LINE6_CAP_HWMON_CTL,
0476 .altsetting = 1,
0477 .ctrl_if = 1,
0478 .ep_ctrl_r = 0x81,
0479 .ep_ctrl_w = 0x01,
0480 .ep_audio_r = 0x86,
0481 .ep_audio_w = 0x02,
0482 },
0483 [LINE6_PODX3] = {
0484 .id = "PODX3",
0485 .name = "POD X3",
0486 .capabilities = LINE6_CAP_CONTROL | LINE6_CAP_CONTROL_INFO
0487 | LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT,
0488 .altsetting = 1,
0489 .ep_ctrl_r = 0x81,
0490 .ep_ctrl_w = 0x01,
0491 .ctrl_if = 1,
0492 .ep_audio_r = 0x86,
0493 .ep_audio_w = 0x02,
0494 },
0495 [LINE6_PODX3LIVE] = {
0496 .id = "PODX3LIVE",
0497 .name = "POD X3 LIVE",
0498 .capabilities = LINE6_CAP_CONTROL | LINE6_CAP_CONTROL_INFO
0499 | LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT,
0500 .altsetting = 1,
0501 .ep_ctrl_r = 0x81,
0502 .ep_ctrl_w = 0x01,
0503 .ctrl_if = 1,
0504 .ep_audio_r = 0x86,
0505 .ep_audio_w = 0x02,
0506 },
0507 [LINE6_PODHD500X] = {
0508 .id = "PODHD500X",
0509 .name = "POD HD500X",
0510 .capabilities = LINE6_CAP_CONTROL
0511 | LINE6_CAP_PCM | LINE6_CAP_HWMON,
0512 .altsetting = 1,
0513 .ep_ctrl_r = 0x81,
0514 .ep_ctrl_w = 0x01,
0515 .ctrl_if = 1,
0516 .ep_audio_r = 0x86,
0517 .ep_audio_w = 0x02,
0518 },
0519 [LINE6_PODHDDESKTOP] = {
0520 .id = "PODHDDESKTOP",
0521 .name = "POD HDDESKTOP",
0522 .capabilities = LINE6_CAP_CONTROL
0523 | LINE6_CAP_PCM | LINE6_CAP_HWMON,
0524 .altsetting = 1,
0525 .ep_ctrl_r = 0x81,
0526 .ep_ctrl_w = 0x01,
0527 .ctrl_if = 1,
0528 .ep_audio_r = 0x86,
0529 .ep_audio_w = 0x02,
0530 },
0531 };
0532
0533
0534
0535
0536 static int podhd_probe(struct usb_interface *interface,
0537 const struct usb_device_id *id)
0538 {
0539 return line6_probe(interface, id, "Line6-PODHD",
0540 &podhd_properties_table[id->driver_info],
0541 podhd_init, sizeof(struct usb_line6_podhd));
0542 }
0543
0544 static struct usb_driver podhd_driver = {
0545 .name = KBUILD_MODNAME,
0546 .probe = podhd_probe,
0547 .disconnect = line6_disconnect,
0548 #ifdef CONFIG_PM
0549 .suspend = line6_suspend,
0550 .resume = line6_resume,
0551 .reset_resume = line6_resume,
0552 #endif
0553 .id_table = podhd_id_table,
0554 };
0555
0556 module_usb_driver(podhd_driver);
0557
0558 MODULE_DESCRIPTION("Line 6 PODHD USB driver");
0559 MODULE_LICENSE("GPL");