^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Line 6 Linux USB driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "driver.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define VARIAX_STARTUP_DELAY1 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define VARIAX_STARTUP_DELAY3 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define VARIAX_STARTUP_DELAY4 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) Stages of Variax startup procedure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) VARIAX_STARTUP_VERSIONREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) VARIAX_STARTUP_ACTIVATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) VARIAX_STARTUP_SETUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) LINE6_PODXTLIVE_VARIAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) LINE6_VARIAX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct usb_line6_variax {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* Generic Line 6 USB data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct usb_line6 line6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* Buffer for activation code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) unsigned char *buffer_activate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* Current progress in startup procedure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) int startup_progress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define line6_to_variax(x) container_of(x, struct usb_line6_variax, line6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define VARIAX_OFFSET_ACTIVATE 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) This message is sent by the device during initialization and identifies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) the connected guitar version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static const char variax_init_version[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) 0xf0, 0x7e, 0x7f, 0x06, 0x02, 0x00, 0x01, 0x0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 0x07, 0x00, 0x00, 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) This message is the last one sent by the device during initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static const char variax_init_done[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static const char variax_activate[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x2a, 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 0xf7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static void variax_activate_async(struct usb_line6_variax *variax, int a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) sizeof(variax_activate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) Variax startup procedure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) This is a sequence of functions with special requirements (e.g., must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) not run immediately after initialization, must not run in interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) context). After the last one has finished, the device is ready to use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static void variax_startup(struct usb_line6 *line6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct usb_line6_variax *variax = line6_to_variax(line6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) switch (variax->startup_progress) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) case VARIAX_STARTUP_VERSIONREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /* repeat request until getting the response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) schedule_delayed_work(&line6->startup_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) msecs_to_jiffies(VARIAX_STARTUP_DELAY1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* request firmware version: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) line6_version_request_async(line6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) case VARIAX_STARTUP_ACTIVATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* activate device: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) variax_activate_async(variax, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) variax->startup_progress = VARIAX_STARTUP_SETUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) schedule_delayed_work(&line6->startup_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) msecs_to_jiffies(VARIAX_STARTUP_DELAY4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) case VARIAX_STARTUP_SETUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* ALSA audio interface: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) snd_card_register(variax->line6.card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) Process a completely received message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static void line6_variax_process_message(struct usb_line6 *line6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct usb_line6_variax *variax = line6_to_variax(line6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) const unsigned char *buf = variax->line6.buffer_message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) switch (buf[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) case LINE6_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) dev_info(variax->line6.ifcdev, "VARIAX reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) case LINE6_SYSEX_BEGIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (memcmp(buf + 1, variax_init_version + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) sizeof(variax_init_version) - 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (variax->startup_progress >= VARIAX_STARTUP_ACTIVATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) variax->startup_progress = VARIAX_STARTUP_ACTIVATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) cancel_delayed_work(&line6->startup_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) schedule_delayed_work(&line6->startup_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) msecs_to_jiffies(VARIAX_STARTUP_DELAY3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) } else if (memcmp(buf + 1, variax_init_done + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) sizeof(variax_init_done) - 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* notify of complete initialization: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (variax->startup_progress >= VARIAX_STARTUP_SETUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) cancel_delayed_work(&line6->startup_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) schedule_delayed_work(&line6->startup_work, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) Variax destructor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static void line6_variax_disconnect(struct usb_line6 *line6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct usb_line6_variax *variax = line6_to_variax(line6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) kfree(variax->buffer_activate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) Try to init workbench device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static int variax_init(struct usb_line6 *line6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct usb_line6_variax *variax = line6_to_variax(line6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) line6->process_message = line6_variax_process_message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) line6->disconnect = line6_variax_disconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) line6->startup = variax_startup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* initialize USB buffers: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) variax->buffer_activate = kmemdup(variax_activate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) sizeof(variax_activate), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (variax->buffer_activate == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* initiate startup procedure: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) schedule_delayed_work(&line6->startup_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) msecs_to_jiffies(VARIAX_STARTUP_DELAY1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* table of devices that work with this driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static const struct usb_device_id variax_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) { LINE6_IF_NUM(0x4650, 1), .driver_info = LINE6_PODXTLIVE_VARIAX },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) { LINE6_DEVICE(0x534d), .driver_info = LINE6_VARIAX },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) MODULE_DEVICE_TABLE(usb, variax_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static const struct line6_properties variax_properties_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) [LINE6_PODXTLIVE_VARIAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) .id = "PODxtLive",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .name = "PODxt Live",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) .capabilities = LINE6_CAP_CONTROL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) | LINE6_CAP_CONTROL_MIDI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) .altsetting = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) .ep_ctrl_r = 0x86,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) .ep_ctrl_w = 0x05,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) .ep_audio_r = 0x82,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) .ep_audio_w = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) [LINE6_VARIAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) .id = "Variax",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) .name = "Variax Workbench",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) .capabilities = LINE6_CAP_CONTROL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) | LINE6_CAP_CONTROL_MIDI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .altsetting = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .ep_ctrl_r = 0x82,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .ep_ctrl_w = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /* no audio channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) Probe USB device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static int variax_probe(struct usb_interface *interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return line6_probe(interface, id, "Line6-Variax",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) &variax_properties_table[id->driver_info],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) variax_init, sizeof(struct usb_line6_variax));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static struct usb_driver variax_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) .name = KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .probe = variax_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) .disconnect = line6_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) .suspend = line6_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) .resume = line6_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .reset_resume = line6_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) .id_table = variax_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) module_usb_driver(variax_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) MODULE_DESCRIPTION("Variax Workbench USB driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) MODULE_LICENSE("GPL");