blob: 503b2d763595fb02c55b5a5d4bd234463e1164cf [file] [log] [blame]
Markus Grabner705ecec2009-02-27 19:43:04 -08001/*
Markus Grabnere1a164d2010-08-23 01:08:25 +02002 * Line6 Linux USB driver - 0.9.1beta
Markus Grabner705ecec2009-02-27 19:43:04 -08003 *
Markus Grabner1027f4762010-08-12 01:35:30 +02004 * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
Markus Grabner705ecec2009-02-27 19:43:04 -08005 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
Markus Grabner705ecec2009-02-27 19:43:04 -080012#include <linux/kernel.h>
13#include <linux/module.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090014#include <linux/slab.h>
Markus Grabner705ecec2009-02-27 19:43:04 -080015#include <linux/usb.h>
16
17#include "audio.h"
18#include "capture.h"
Markus Grabner1027f4762010-08-12 01:35:30 +020019#include "driver.h"
Markus Grabner705ecec2009-02-27 19:43:04 -080020#include "midi.h"
21#include "playback.h"
22#include "pod.h"
Stefan Hajnoczi16dc1042011-11-23 08:20:42 +000023#include "podhd.h"
Markus Grabner705ecec2009-02-27 19:43:04 -080024#include "revision.h"
25#include "toneport.h"
26#include "usbdefs.h"
27#include "variax.h"
28
Markus Grabner705ecec2009-02-27 19:43:04 -080029#define DRIVER_AUTHOR "Markus Grabner <grabner@icg.tugraz.at>"
30#define DRIVER_DESC "Line6 USB Driver"
Markus Grabnere1a164d2010-08-23 01:08:25 +020031#define DRIVER_VERSION "0.9.1beta" DRIVER_REVISION
Markus Grabner705ecec2009-02-27 19:43:04 -080032
33/* table of devices that work with this driver */
Németh Mártona4577322010-01-10 00:18:34 +010034static const struct usb_device_id line6_id_table[] = {
Markus Grabnere1a164d2010-08-23 01:08:25 +020035 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXT)},
36 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTLIVE)},
37 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO)},
38 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_GUITARPORT)},
39 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_POCKETPOD)},
Markus Grabner4c6fb5f2011-12-05 23:51:53 +010040 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODHD300)},
Chris Bajumpaa1785faa2013-12-21 17:51:24 -050041 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODHD400)},
Markus Grabner4c6fb5f2011-12-05 23:51:53 +010042 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODHD500)},
Markus Grabnere1a164d2010-08-23 01:08:25 +020043 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_GX)},
44 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX1)},
45 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX2)},
46 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3)},
47 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3LIVE)},
48 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXT)},
49 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTLIVE)},
50 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTPRO)},
51 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_GX)},
52 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX1)},
53 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX2)},
54 {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_VARIAX)},
55 {},
Markus Grabner705ecec2009-02-27 19:43:04 -080056};
Markus Grabnere1a164d2010-08-23 01:08:25 +020057
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -080058MODULE_DEVICE_TABLE(usb, line6_id_table);
Markus Grabner705ecec2009-02-27 19:43:04 -080059
Davide Berardiba79e522014-03-17 03:34:41 +010060#define L6PROP(dev_bit, dev_id, dev_name, dev_cap)\
61 {.device_bit = LINE6_BIT_##dev_bit, .id = dev_id,\
62 .name = dev_name, .capabilities = LINE6_BIT_##dev_cap}
63
Markus Grabnere1a164d2010-08-23 01:08:25 +020064/* *INDENT-OFF* */
Davide Berardiba79e522014-03-17 03:34:41 +010065static const struct line6_properties line6_properties_table[] = {
66 L6PROP(BASSPODXT, "BassPODxt", "BassPODxt", CTRL_PCM_HW),
67 L6PROP(BASSPODXTLIVE, "BassPODxtLive", "BassPODxt Live", CTRL_PCM_HW),
68 L6PROP(BASSPODXTPRO, "BassPODxtPro", "BassPODxt Pro", CTRL_PCM_HW),
69 L6PROP(GUITARPORT, "GuitarPort", "GuitarPort", PCM),
70 L6PROP(POCKETPOD, "PocketPOD", "Pocket POD", CONTROL),
71 L6PROP(PODHD300, "PODHD300", "POD HD300", CTRL_PCM_HW),
72 L6PROP(PODHD400, "PODHD400", "POD HD400", CTRL_PCM_HW),
73 L6PROP(PODHD500, "PODHD500", "POD HD500", CTRL_PCM_HW),
74 L6PROP(PODSTUDIO_GX, "PODStudioGX", "POD Studio GX", PCM),
75 L6PROP(PODSTUDIO_UX1, "PODStudioUX1", "POD Studio UX1", PCM),
76 L6PROP(PODSTUDIO_UX2, "PODStudioUX2", "POD Studio UX2", PCM),
77 L6PROP(PODX3, "PODX3", "POD X3", PCM),
78 L6PROP(PODX3LIVE, "PODX3Live", "POD X3 Live", PCM),
79 L6PROP(PODXT, "PODxt", "PODxt", CTRL_PCM_HW),
80 L6PROP(PODXTLIVE, "PODxtLive", "PODxt Live", CTRL_PCM_HW),
81 L6PROP(PODXTPRO, "PODxtPro", "PODxt Pro", CTRL_PCM_HW),
82 L6PROP(TONEPORT_GX, "TonePortGX", "TonePort GX", PCM),
83 L6PROP(TONEPORT_UX1, "TonePortUX1", "TonePort UX1", PCM),
84 L6PROP(TONEPORT_UX2, "TonePortUX2", "TonePort UX2", PCM),
85 L6PROP(VARIAX, "Variax", "Variax Workbench", CONTROL),
Markus Grabner705ecec2009-02-27 19:43:04 -080086};
Markus Grabnere1a164d2010-08-23 01:08:25 +020087/* *INDENT-ON* */
Markus Grabner705ecec2009-02-27 19:43:04 -080088
89/*
90 This is Line6's MIDI manufacturer ID.
91*/
Markus Grabner1027f4762010-08-12 01:35:30 +020092const unsigned char line6_midi_id[] = {
93 0x00, 0x01, 0x0c
94};
95
96/*
97 Code to request version of POD, Variax interface
98 (and maybe other devices).
99*/
Greg Kroah-Hartmanc46b8a62012-04-23 16:09:56 -0700100static const char line6_request_version[] = {
Markus Grabner1027f4762010-08-12 01:35:30 +0200101 0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7
102};
103
Markus Grabner705ecec2009-02-27 19:43:04 -0800104/**
105 Class for asynchronous messages.
106*/
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800107struct message {
Markus Grabner705ecec2009-02-27 19:43:04 -0800108 struct usb_line6 *line6;
109 const char *buffer;
110 int size;
111 int done;
112};
113
Markus Grabner705ecec2009-02-27 19:43:04 -0800114/*
115 Forward declarations.
116*/
Greg Kroah-Hartman0c7ab152009-02-27 20:28:04 -0800117static void line6_data_received(struct urb *urb);
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800118static int line6_send_raw_message_async_part(struct message *msg,
119 struct urb *urb);
Markus Grabner705ecec2009-02-27 19:43:04 -0800120
Markus Grabner705ecec2009-02-27 19:43:04 -0800121/*
122 Start to listen on endpoint.
123*/
124static int line6_start_listen(struct usb_line6 *line6)
125{
Markus Grabner1027f4762010-08-12 01:35:30 +0200126 int err;
Fabian Mewesa6b46992014-03-24 23:46:31 +0100127
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800128 usb_fill_int_urb(line6->urb_listen, line6->usbdev,
129 usb_rcvintpipe(line6->usbdev, line6->ep_control_read),
130 line6->buffer_listen, LINE6_BUFSIZE_LISTEN,
131 line6_data_received, line6, line6->interval);
Markus Grabner705ecec2009-02-27 19:43:04 -0800132 line6->urb_listen->actual_length = 0;
Markus Grabnere1a164d2010-08-23 01:08:25 +0200133 err = usb_submit_urb(line6->urb_listen, GFP_ATOMIC);
Markus Grabner1027f4762010-08-12 01:35:30 +0200134 return err;
Markus Grabner705ecec2009-02-27 19:43:04 -0800135}
136
Markus Grabner1027f4762010-08-12 01:35:30 +0200137/*
138 Stop listening on endpoint.
139*/
140static void line6_stop_listen(struct usb_line6 *line6)
141{
142 usb_kill_urb(line6->urb_listen);
143}
144
Markus Grabner705ecec2009-02-27 19:43:04 -0800145/*
Markus Grabner1027f4762010-08-12 01:35:30 +0200146 Send raw message in pieces of wMaxPacketSize bytes.
Markus Grabner705ecec2009-02-27 19:43:04 -0800147*/
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800148int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
149 int size)
Markus Grabner705ecec2009-02-27 19:43:04 -0800150{
151 int i, done = 0;
152
Markus Grabner1027f4762010-08-12 01:35:30 +0200153 for (i = 0; i < size; i += line6->max_packet_size) {
154 int partial;
Markus Grabner705ecec2009-02-27 19:43:04 -0800155 const char *frag_buf = buffer + i;
156 int frag_size = min(line6->max_packet_size, size - i);
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800157 int retval;
Markus Grabner705ecec2009-02-27 19:43:04 -0800158
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800159 retval = usb_interrupt_msg(line6->usbdev,
Davide Berardiba79e522014-03-17 03:34:41 +0100160 usb_sndintpipe(line6->usbdev,
161 line6->ep_control_write),
162 (char *)frag_buf, frag_size,
163 &partial, LINE6_TIMEOUT * HZ);
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800164
165 if (retval) {
166 dev_err(line6->ifcdev,
167 "usb_interrupt_msg failed (%d)\n", retval);
Markus Grabner705ecec2009-02-27 19:43:04 -0800168 break;
169 }
170
Markus Grabner1027f4762010-08-12 01:35:30 +0200171 done += frag_size;
Markus Grabner705ecec2009-02-27 19:43:04 -0800172 }
173
174 return done;
175}
176
177/*
178 Notification of completion of asynchronous request transmission.
179*/
Greg Kroah-Hartman0c7ab152009-02-27 20:28:04 -0800180static void line6_async_request_sent(struct urb *urb)
Markus Grabner705ecec2009-02-27 19:43:04 -0800181{
182 struct message *msg = (struct message *)urb->context;
183
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800184 if (msg->done >= msg->size) {
Markus Grabner705ecec2009-02-27 19:43:04 -0800185 usb_free_urb(urb);
186 kfree(msg);
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800187 } else
Markus Grabner705ecec2009-02-27 19:43:04 -0800188 line6_send_raw_message_async_part(msg, urb);
189}
190
191/*
192 Asynchronously send part of a raw message.
193*/
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800194static int line6_send_raw_message_async_part(struct message *msg,
195 struct urb *urb)
Markus Grabner705ecec2009-02-27 19:43:04 -0800196{
197 int retval;
198 struct usb_line6 *line6 = msg->line6;
199 int done = msg->done;
200 int bytes = min(msg->size - done, line6->max_packet_size);
201
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800202 usb_fill_int_urb(urb, line6->usbdev,
203 usb_sndintpipe(line6->usbdev, line6->ep_control_write),
204 (char *)msg->buffer + done, bytes,
205 line6_async_request_sent, msg, line6->interval);
Markus Grabner705ecec2009-02-27 19:43:04 -0800206
Markus Grabner705ecec2009-02-27 19:43:04 -0800207 msg->done += bytes;
208 retval = usb_submit_urb(urb, GFP_ATOMIC);
209
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800210 if (retval < 0) {
211 dev_err(line6->ifcdev, "%s: usb_submit_urb failed (%d)\n",
212 __func__, retval);
Markus Grabner705ecec2009-02-27 19:43:04 -0800213 usb_free_urb(urb);
214 kfree(msg);
Ashvini Varatharaj056e0af2013-10-19 22:01:22 +0530215 return retval;
Markus Grabner705ecec2009-02-27 19:43:04 -0800216 }
217
218 return 0;
219}
220
221/*
Markus Grabner1027f4762010-08-12 01:35:30 +0200222 Setup and start timer.
223*/
224void line6_start_timer(struct timer_list *timer, unsigned int msecs,
Monam Agarwal1cad6082014-02-27 21:05:18 +0530225 void (*function)(unsigned long), unsigned long data)
Markus Grabner1027f4762010-08-12 01:35:30 +0200226{
227 setup_timer(timer, function, data);
228 timer->expires = jiffies + msecs * HZ / 1000;
229 add_timer(timer);
230}
231
232/*
Markus Grabner705ecec2009-02-27 19:43:04 -0800233 Asynchronously send raw message.
234*/
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800235int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer,
236 int size)
Markus Grabner705ecec2009-02-27 19:43:04 -0800237{
238 struct message *msg;
239 struct urb *urb;
240
241 /* create message: */
242 msg = kmalloc(sizeof(struct message), GFP_ATOMIC);
Joe Perches78110bb2013-02-11 09:41:29 -0800243 if (msg == NULL)
Markus Grabner705ecec2009-02-27 19:43:04 -0800244 return -ENOMEM;
Markus Grabner705ecec2009-02-27 19:43:04 -0800245
246 /* create URB: */
247 urb = usb_alloc_urb(0, GFP_ATOMIC);
248
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800249 if (urb == NULL) {
Markus Grabner705ecec2009-02-27 19:43:04 -0800250 kfree(msg);
251 dev_err(line6->ifcdev, "Out of memory\n");
252 return -ENOMEM;
253 }
254
255 /* set message data: */
256 msg->line6 = line6;
257 msg->buffer = buffer;
258 msg->size = size;
259 msg->done = 0;
260
261 /* start sending: */
262 return line6_send_raw_message_async_part(msg, urb);
263}
264
265/*
Markus Grabner1027f4762010-08-12 01:35:30 +0200266 Send asynchronous device version request.
267*/
268int line6_version_request_async(struct usb_line6 *line6)
269{
Greg Kroah-Hartmanc46b8a62012-04-23 16:09:56 -0700270 char *buffer;
271 int retval;
272
Laurent Navet77ecb6f2012-12-03 14:20:25 +0100273 buffer = kmemdup(line6_request_version,
274 sizeof(line6_request_version), GFP_ATOMIC);
Greg Kroah-Hartmanc46b8a62012-04-23 16:09:56 -0700275 if (buffer == NULL) {
276 dev_err(line6->ifcdev, "Out of memory");
277 return -ENOMEM;
278 }
279
Greg Kroah-Hartmanc46b8a62012-04-23 16:09:56 -0700280 retval = line6_send_raw_message_async(line6, buffer,
281 sizeof(line6_request_version));
282 kfree(buffer);
283 return retval;
Markus Grabner1027f4762010-08-12 01:35:30 +0200284}
285
286/*
Markus Grabner705ecec2009-02-27 19:43:04 -0800287 Send sysex message in pieces of wMaxPacketSize bytes.
288*/
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800289int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer,
290 int size)
Markus Grabner705ecec2009-02-27 19:43:04 -0800291{
Markus Grabnere1a164d2010-08-23 01:08:25 +0200292 return line6_send_raw_message(line6, buffer,
293 size + SYSEX_EXTRA_SIZE) -
294 SYSEX_EXTRA_SIZE;
Markus Grabner705ecec2009-02-27 19:43:04 -0800295}
296
297/*
298 Allocate buffer for sysex message and prepare header.
299 @param code sysex message code
300 @param size number of bytes between code and sysex end
301*/
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800302char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2,
303 int size)
Markus Grabner705ecec2009-02-27 19:43:04 -0800304{
Markus Grabner1027f4762010-08-12 01:35:30 +0200305 char *buffer = kmalloc(size + SYSEX_EXTRA_SIZE, GFP_ATOMIC);
Markus Grabner705ecec2009-02-27 19:43:04 -0800306
Joe Perches78110bb2013-02-11 09:41:29 -0800307 if (!buffer)
Greg Kroah-Hartman536165d2009-02-27 20:49:46 -0800308 return NULL;
Markus Grabner705ecec2009-02-27 19:43:04 -0800309
310 buffer[0] = LINE6_SYSEX_BEGIN;
311 memcpy(buffer + 1, line6_midi_id, sizeof(line6_midi_id));
312 buffer[sizeof(line6_midi_id) + 1] = code1;
313 buffer[sizeof(line6_midi_id) + 2] = code2;
314 buffer[sizeof(line6_midi_id) + 3 + size] = LINE6_SYSEX_END;
315 return buffer;
316}
317
318/*
319 Notification of data received from the Line6 device.
320*/
Greg Kroah-Hartman0c7ab152009-02-27 20:28:04 -0800321static void line6_data_received(struct urb *urb)
Markus Grabner705ecec2009-02-27 19:43:04 -0800322{
323 struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
Stefan Hajnoczi269edc82013-01-11 23:08:09 +0100324 struct midi_buffer *mb = &line6->line6midi->midibuf_in;
Markus Grabner705ecec2009-02-27 19:43:04 -0800325 int done;
326
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800327 if (urb->status == -ESHUTDOWN)
Markus Grabner705ecec2009-02-27 19:43:04 -0800328 return;
329
Markus Grabnere1a164d2010-08-23 01:08:25 +0200330 done =
331 line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length);
Markus Grabner705ecec2009-02-27 19:43:04 -0800332
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800333 if (done < urb->actual_length) {
Markus Grabner1027f4762010-08-12 01:35:30 +0200334 line6_midibuf_ignore(mb, done);
Stefan Hajnoczie00d33c2012-11-11 13:52:24 +0100335 dev_dbg(line6->ifcdev, "%d %d buffer overflow - message skipped\n",
336 done, urb->actual_length);
Markus Grabner705ecec2009-02-27 19:43:04 -0800337 }
338
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800339 for (;;) {
Markus Grabnere1a164d2010-08-23 01:08:25 +0200340 done =
341 line6_midibuf_read(mb, line6->buffer_message,
342 LINE6_MESSAGE_MAXLEN);
Markus Grabner705ecec2009-02-27 19:43:04 -0800343
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800344 if (done == 0)
Markus Grabner705ecec2009-02-27 19:43:04 -0800345 break;
346
Markus Grabner705ecec2009-02-27 19:43:04 -0800347 line6->message_length = done;
Markus Grabner705ecec2009-02-27 19:43:04 -0800348 line6_midi_receive(line6, line6->buffer_message, done);
349
Rashika Kheria5a083bd2013-10-26 17:12:57 +0530350 switch (le16_to_cpu(line6->usbdev->descriptor.idProduct)) {
Markus Grabner705ecec2009-02-27 19:43:04 -0800351 case LINE6_DEVID_BASSPODXT:
352 case LINE6_DEVID_BASSPODXTLIVE:
353 case LINE6_DEVID_BASSPODXTPRO:
354 case LINE6_DEVID_PODXT:
355 case LINE6_DEVID_PODXTPRO:
356 case LINE6_DEVID_POCKETPOD:
Markus Grabnere1a164d2010-08-23 01:08:25 +0200357 line6_pod_process_message((struct usb_line6_pod *)
358 line6);
Markus Grabner705ecec2009-02-27 19:43:04 -0800359 break;
360
Stefan Hajnoczi16dc1042011-11-23 08:20:42 +0000361 case LINE6_DEVID_PODHD300:
Chris Bajumpaa1785faa2013-12-21 17:51:24 -0500362 case LINE6_DEVID_PODHD400:
Markus Grabner4c6fb5f2011-12-05 23:51:53 +0100363 case LINE6_DEVID_PODHD500:
Stefan Hajnoczi16dc1042011-11-23 08:20:42 +0000364 break; /* let userspace handle MIDI */
365
Markus Grabner705ecec2009-02-27 19:43:04 -0800366 case LINE6_DEVID_PODXTLIVE:
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800367 switch (line6->interface_number) {
Markus Grabner705ecec2009-02-27 19:43:04 -0800368 case PODXTLIVE_INTERFACE_POD:
Markus Grabnere1a164d2010-08-23 01:08:25 +0200369 line6_pod_process_message((struct usb_line6_pod
370 *)line6);
Markus Grabner705ecec2009-02-27 19:43:04 -0800371 break;
372
373 case PODXTLIVE_INTERFACE_VARIAX:
Markus Grabnere1a164d2010-08-23 01:08:25 +0200374 line6_variax_process_message((struct
375 usb_line6_variax
376 *)line6);
Markus Grabner705ecec2009-02-27 19:43:04 -0800377 break;
378
379 default:
Markus Grabnere1a164d2010-08-23 01:08:25 +0200380 dev_err(line6->ifcdev,
381 "PODxt Live interface %d not supported\n",
382 line6->interface_number);
Markus Grabner705ecec2009-02-27 19:43:04 -0800383 }
384 break;
385
386 case LINE6_DEVID_VARIAX:
Markus Grabnere1a164d2010-08-23 01:08:25 +0200387 line6_variax_process_message((struct usb_line6_variax *)
388 line6);
Markus Grabner705ecec2009-02-27 19:43:04 -0800389 break;
390
391 default:
392 MISSING_CASE;
393 }
394 }
395
396 line6_start_listen(line6);
397}
398
399/*
400 Send channel number (i.e., switch to a different sound).
401*/
Johannes Thumshirn317e1882012-06-27 21:25:58 +0200402int line6_send_program(struct usb_line6 *line6, u8 value)
Markus Grabner705ecec2009-02-27 19:43:04 -0800403{
Markus Grabner1027f4762010-08-12 01:35:30 +0200404 int retval;
Markus Grabner705ecec2009-02-27 19:43:04 -0800405 unsigned char *buffer;
Markus Grabner1027f4762010-08-12 01:35:30 +0200406 int partial;
Markus Grabner705ecec2009-02-27 19:43:04 -0800407
Markus Grabner1027f4762010-08-12 01:35:30 +0200408 buffer = kmalloc(2, GFP_KERNEL);
Joe Perches78110bb2013-02-11 09:41:29 -0800409 if (!buffer)
Markus Grabner705ecec2009-02-27 19:43:04 -0800410 return -ENOMEM;
Markus Grabner705ecec2009-02-27 19:43:04 -0800411
412 buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST;
413 buffer[1] = value;
414
Markus Grabner1027f4762010-08-12 01:35:30 +0200415 retval = usb_interrupt_msg(line6->usbdev,
416 usb_sndintpipe(line6->usbdev,
417 line6->ep_control_write),
418 buffer, 2, &partial, LINE6_TIMEOUT * HZ);
419
420 if (retval)
Markus Grabnere1a164d2010-08-23 01:08:25 +0200421 dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n",
422 retval);
Markus Grabner1027f4762010-08-12 01:35:30 +0200423
424 kfree(buffer);
425 return retval;
Markus Grabner705ecec2009-02-27 19:43:04 -0800426}
427
428/*
429 Transmit Line6 control parameter.
430*/
Johannes Thumshirn2471c092012-06-27 21:25:55 +0200431int line6_transmit_parameter(struct usb_line6 *line6, int param, u8 value)
Markus Grabner705ecec2009-02-27 19:43:04 -0800432{
Markus Grabner1027f4762010-08-12 01:35:30 +0200433 int retval;
Markus Grabner705ecec2009-02-27 19:43:04 -0800434 unsigned char *buffer;
Markus Grabner1027f4762010-08-12 01:35:30 +0200435 int partial;
Markus Grabner705ecec2009-02-27 19:43:04 -0800436
Markus Grabner1027f4762010-08-12 01:35:30 +0200437 buffer = kmalloc(3, GFP_KERNEL);
Joe Perches78110bb2013-02-11 09:41:29 -0800438 if (!buffer)
Markus Grabner705ecec2009-02-27 19:43:04 -0800439 return -ENOMEM;
Markus Grabner705ecec2009-02-27 19:43:04 -0800440
441 buffer[0] = LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST;
442 buffer[1] = param;
443 buffer[2] = value;
444
Markus Grabner1027f4762010-08-12 01:35:30 +0200445 retval = usb_interrupt_msg(line6->usbdev,
Markus Grabnere1a164d2010-08-23 01:08:25 +0200446 usb_sndintpipe(line6->usbdev,
447 line6->ep_control_write),
Markus Grabner1027f4762010-08-12 01:35:30 +0200448 buffer, 3, &partial, LINE6_TIMEOUT * HZ);
449
450 if (retval)
Markus Grabnere1a164d2010-08-23 01:08:25 +0200451 dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n",
452 retval);
Markus Grabner1027f4762010-08-12 01:35:30 +0200453
454 kfree(buffer);
455 return retval;
Markus Grabner705ecec2009-02-27 19:43:04 -0800456}
457
458/*
459 Read data from device.
460*/
Markus Grabnere1a164d2010-08-23 01:08:25 +0200461int line6_read_data(struct usb_line6 *line6, int address, void *data,
462 size_t datalen)
Markus Grabner705ecec2009-02-27 19:43:04 -0800463{
464 struct usb_device *usbdev = line6->usbdev;
465 int ret;
466 unsigned char len;
467
468 /* query the serial number: */
469 ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
Markus Grabner1027f4762010-08-12 01:35:30 +0200470 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
471 (datalen << 8) | 0x21, address,
472 NULL, 0, LINE6_TIMEOUT * HZ);
Markus Grabner705ecec2009-02-27 19:43:04 -0800473
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800474 if (ret < 0) {
Markus Grabner705ecec2009-02-27 19:43:04 -0800475 dev_err(line6->ifcdev, "read request failed (error %d)\n", ret);
476 return ret;
477 }
478
Stefan Hajnoczibc776f22013-01-11 23:08:10 +0100479 /* Wait for data length. We'll get 0xff until length arrives. */
Markus Grabner705ecec2009-02-27 19:43:04 -0800480 do {
481 ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800482 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
483 USB_DIR_IN,
484 0x0012, 0x0000, &len, 1,
485 LINE6_TIMEOUT * HZ);
486 if (ret < 0) {
487 dev_err(line6->ifcdev,
488 "receive length failed (error %d)\n", ret);
Markus Grabner705ecec2009-02-27 19:43:04 -0800489 return ret;
490 }
Frederik Deweerdtd722a512009-09-15 09:29:43 +0000491 } while (len == 0xff);
Markus Grabner705ecec2009-02-27 19:43:04 -0800492
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800493 if (len != datalen) {
494 /* should be equal or something went wrong */
495 dev_err(line6->ifcdev,
496 "length mismatch (expected %d, got %d)\n",
497 (int)datalen, (int)len);
Markus Grabner705ecec2009-02-27 19:43:04 -0800498 return -EINVAL;
499 }
500
501 /* receive the result: */
502 ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800503 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
504 0x0013, 0x0000, data, datalen,
505 LINE6_TIMEOUT * HZ);
Markus Grabner705ecec2009-02-27 19:43:04 -0800506
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800507 if (ret < 0) {
Markus Grabner705ecec2009-02-27 19:43:04 -0800508 dev_err(line6->ifcdev, "read failed (error %d)\n", ret);
509 return ret;
510 }
511
512 return 0;
513}
514
515/*
516 Write data to device.
517*/
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800518int line6_write_data(struct usb_line6 *line6, int address, void *data,
519 size_t datalen)
Markus Grabner705ecec2009-02-27 19:43:04 -0800520{
521 struct usb_device *usbdev = line6->usbdev;
522 int ret;
523 unsigned char status;
524
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800525 ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
526 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
527 0x0022, address, data, datalen,
528 LINE6_TIMEOUT * HZ);
Markus Grabner705ecec2009-02-27 19:43:04 -0800529
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800530 if (ret < 0) {
531 dev_err(line6->ifcdev,
532 "write request failed (error %d)\n", ret);
Markus Grabner705ecec2009-02-27 19:43:04 -0800533 return ret;
534 }
535
536 do {
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800537 ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
538 0x67,
539 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
540 USB_DIR_IN,
541 0x0012, 0x0000,
542 &status, 1, LINE6_TIMEOUT * HZ);
Markus Grabner705ecec2009-02-27 19:43:04 -0800543
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800544 if (ret < 0) {
545 dev_err(line6->ifcdev,
546 "receiving status failed (error %d)\n", ret);
Markus Grabner705ecec2009-02-27 19:43:04 -0800547 return ret;
548 }
Greg Kroah-Hartman027360c2010-09-21 16:58:00 -0700549 } while (status == 0xff);
Markus Grabner705ecec2009-02-27 19:43:04 -0800550
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800551 if (status != 0) {
Markus Grabner705ecec2009-02-27 19:43:04 -0800552 dev_err(line6->ifcdev, "write failed (error %d)\n", ret);
553 return -EINVAL;
554 }
555
556 return 0;
557}
558
559/*
560 Read Line6 device serial number.
561 (POD, TonePort, GuitarPort)
562*/
563int line6_read_serial_number(struct usb_line6 *line6, int *serial_number)
564{
Markus Grabnere1a164d2010-08-23 01:08:25 +0200565 return line6_read_data(line6, 0x80d0, serial_number,
566 sizeof(*serial_number));
Markus Grabner705ecec2009-02-27 19:43:04 -0800567}
568
569/*
570 No operation (i.e., unsupported).
571*/
Greg Kroah-Hartman77491e52009-02-27 20:25:43 -0800572ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr,
573 char *buf)
Markus Grabner705ecec2009-02-27 19:43:04 -0800574{
575 return 0;
576}
577
578/*
Markus Grabner705ecec2009-02-27 19:43:04 -0800579 Generic destructor.
580*/
581static void line6_destruct(struct usb_interface *interface)
582{
583 struct usb_line6 *line6;
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800584
585 if (interface == NULL)
586 return;
Markus Grabner705ecec2009-02-27 19:43:04 -0800587 line6 = usb_get_intfdata(interface);
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800588 if (line6 == NULL)
589 return;
Markus Grabner705ecec2009-02-27 19:43:04 -0800590
591 /* free buffer memory first: */
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800592 kfree(line6->buffer_message);
593 kfree(line6->buffer_listen);
Markus Grabner705ecec2009-02-27 19:43:04 -0800594
595 /* then free URBs: */
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800596 usb_free_urb(line6->urb_listen);
Markus Grabner705ecec2009-02-27 19:43:04 -0800597
598 /* make sure the device isn't destructed twice: */
599 usb_set_intfdata(interface, NULL);
600
601 /* free interface data: */
602 kfree(line6);
603}
604
Markus Grabner705ecec2009-02-27 19:43:04 -0800605/*
606 Probe USB device.
607*/
Markus Grabnere1a164d2010-08-23 01:08:25 +0200608static int line6_probe(struct usb_interface *interface,
609 const struct usb_device_id *id)
Markus Grabner705ecec2009-02-27 19:43:04 -0800610{
611 int devtype;
Dan Carpenter4bd8b4d2011-11-30 11:43:41 +0300612 struct usb_device *usbdev;
613 struct usb_line6 *line6;
Markus Grabner705ecec2009-02-27 19:43:04 -0800614 const struct line6_properties *properties;
Markus Grabner705ecec2009-02-27 19:43:04 -0800615 int interface_number, alternate = 0;
616 int product;
617 int size = 0;
618 int ep_read = 0, ep_write = 0;
619 int ret;
620
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800621 if (interface == NULL)
622 return -ENODEV;
Markus Grabner705ecec2009-02-27 19:43:04 -0800623 usbdev = interface_to_usbdev(interface);
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800624 if (usbdev == NULL)
625 return -ENODEV;
Markus Grabner705ecec2009-02-27 19:43:04 -0800626
Markus Grabner705ecec2009-02-27 19:43:04 -0800627 /* we don't handle multiple configurations */
Kulikov Vasiliyab366c12010-07-13 15:22:46 +0400628 if (usbdev->descriptor.bNumConfigurations != 1) {
629 ret = -ENODEV;
630 goto err_put;
631 }
Markus Grabner705ecec2009-02-27 19:43:04 -0800632
633 /* check vendor and product id */
Frederik Deweerdtd722a512009-09-15 09:29:43 +0000634 for (devtype = ARRAY_SIZE(line6_id_table) - 1; devtype--;) {
Greg Kroah-Hartman1e18c0d2010-05-04 22:45:08 -0700635 u16 idVendor = le16_to_cpu(usbdev->descriptor.idVendor);
636 u16 idProduct = le16_to_cpu(usbdev->descriptor.idProduct);
Frederik Deweerdtd722a512009-09-15 09:29:43 +0000637
Markus Grabner1027f4762010-08-12 01:35:30 +0200638 if (idVendor == line6_id_table[devtype].idVendor &&
639 idProduct == line6_id_table[devtype].idProduct)
Markus Grabner705ecec2009-02-27 19:43:04 -0800640 break;
Frederik Deweerdtd722a512009-09-15 09:29:43 +0000641 }
Markus Grabner705ecec2009-02-27 19:43:04 -0800642
Kulikov Vasiliyab366c12010-07-13 15:22:46 +0400643 if (devtype < 0) {
644 ret = -ENODEV;
645 goto err_put;
646 }
Markus Grabner705ecec2009-02-27 19:43:04 -0800647
Markus Grabner705ecec2009-02-27 19:43:04 -0800648 /* initialize device info: */
649 properties = &line6_properties_table[devtype];
650 dev_info(&interface->dev, "Line6 %s found\n", properties->name);
651 product = le16_to_cpu(usbdev->descriptor.idProduct);
652
653 /* query interface number */
654 interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
655
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800656 switch (product) {
Markus Grabner705ecec2009-02-27 19:43:04 -0800657 case LINE6_DEVID_BASSPODXTLIVE:
Markus Grabner705ecec2009-02-27 19:43:04 -0800658 case LINE6_DEVID_PODXTLIVE:
659 case LINE6_DEVID_VARIAX:
660 alternate = 1;
661 break;
662
Markus Grabner1027f4762010-08-12 01:35:30 +0200663 case LINE6_DEVID_POCKETPOD:
664 switch (interface_number) {
665 case 0:
Alexey Khoroshilovc7f268d2014-06-11 00:22:50 +0400666 return -ENODEV; /* this interface has no endpoints */
Markus Grabner1027f4762010-08-12 01:35:30 +0200667 case 1:
668 alternate = 0;
669 break;
670 default:
671 MISSING_CASE;
672 }
673 break;
674
Markus Grabner4c6fb5f2011-12-05 23:51:53 +0100675 case LINE6_DEVID_PODHD500:
Markus Grabner705ecec2009-02-27 19:43:04 -0800676 case LINE6_DEVID_PODX3:
677 case LINE6_DEVID_PODX3LIVE:
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800678 switch (interface_number) {
679 case 0:
680 alternate = 1;
681 break;
682 case 1:
683 alternate = 0;
684 break;
685 default:
686 MISSING_CASE;
Markus Grabner705ecec2009-02-27 19:43:04 -0800687 }
688 break;
689
690 case LINE6_DEVID_BASSPODXT:
691 case LINE6_DEVID_BASSPODXTPRO:
692 case LINE6_DEVID_PODXT:
693 case LINE6_DEVID_PODXTPRO:
Stefan Hajnoczi16dc1042011-11-23 08:20:42 +0000694 case LINE6_DEVID_PODHD300:
Chris Bajumpaa1785faa2013-12-21 17:51:24 -0500695 case LINE6_DEVID_PODHD400:
Markus Grabner705ecec2009-02-27 19:43:04 -0800696 alternate = 5;
697 break;
698
Markus Grabner705ecec2009-02-27 19:43:04 -0800699 case LINE6_DEVID_GUITARPORT:
Markus Grabner1027f4762010-08-12 01:35:30 +0200700 case LINE6_DEVID_PODSTUDIO_GX:
701 case LINE6_DEVID_PODSTUDIO_UX1:
702 case LINE6_DEVID_TONEPORT_GX:
703 case LINE6_DEVID_TONEPORT_UX1:
Markus Grabnere1a164d2010-08-23 01:08:25 +0200704 alternate = 2; /* 1..4 seem to be ok */
Markus Grabner705ecec2009-02-27 19:43:04 -0800705 break;
706
Markus Grabner705ecec2009-02-27 19:43:04 -0800707 case LINE6_DEVID_TONEPORT_UX2:
Markus Grabner1027f4762010-08-12 01:35:30 +0200708 case LINE6_DEVID_PODSTUDIO_UX2:
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800709 switch (interface_number) {
710 case 0:
711 /* defaults to 44.1kHz, 16-bit */
712 alternate = 2;
713 break;
714 case 1:
Markus Grabner1027f4762010-08-12 01:35:30 +0200715 /* don't know yet what this is ...
Markus Grabnere1a164d2010-08-23 01:08:25 +0200716 alternate = 1;
717 break;
718 */
Markus Grabner1027f4762010-08-12 01:35:30 +0200719 return -ENODEV;
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800720 default:
721 MISSING_CASE;
Markus Grabner705ecec2009-02-27 19:43:04 -0800722 }
723 break;
724
725 default:
726 MISSING_CASE;
Kulikov Vasiliyab366c12010-07-13 15:22:46 +0400727 ret = -ENODEV;
728 goto err_put;
Markus Grabner705ecec2009-02-27 19:43:04 -0800729 }
730
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800731 ret = usb_set_interface(usbdev, interface_number, alternate);
732 if (ret < 0) {
Markus Grabner705ecec2009-02-27 19:43:04 -0800733 dev_err(&interface->dev, "set_interface failed\n");
Kulikov Vasiliyab366c12010-07-13 15:22:46 +0400734 goto err_put;
Markus Grabner705ecec2009-02-27 19:43:04 -0800735 }
736
737 /* initialize device data based on product id: */
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800738 switch (product) {
Markus Grabner705ecec2009-02-27 19:43:04 -0800739 case LINE6_DEVID_BASSPODXT:
740 case LINE6_DEVID_BASSPODXTLIVE:
741 case LINE6_DEVID_BASSPODXTPRO:
Markus Grabner705ecec2009-02-27 19:43:04 -0800742 case LINE6_DEVID_PODXT:
743 case LINE6_DEVID_PODXTPRO:
744 size = sizeof(struct usb_line6_pod);
Markus Grabnere1a164d2010-08-23 01:08:25 +0200745 ep_read = 0x84;
Markus Grabner705ecec2009-02-27 19:43:04 -0800746 ep_write = 0x03;
747 break;
748
Stefan Hajnoczi16dc1042011-11-23 08:20:42 +0000749 case LINE6_DEVID_PODHD300:
Chris Bajumpaa1785faa2013-12-21 17:51:24 -0500750 case LINE6_DEVID_PODHD400:
Stefan Hajnoczi16dc1042011-11-23 08:20:42 +0000751 size = sizeof(struct usb_line6_podhd);
752 ep_read = 0x84;
753 ep_write = 0x03;
754 break;
755
Markus Grabner4c6fb5f2011-12-05 23:51:53 +0100756 case LINE6_DEVID_PODHD500:
757 size = sizeof(struct usb_line6_podhd);
758 ep_read = 0x81;
759 ep_write = 0x01;
760 break;
761
Markus Grabner1027f4762010-08-12 01:35:30 +0200762 case LINE6_DEVID_POCKETPOD:
763 size = sizeof(struct usb_line6_pod);
Markus Grabnere1a164d2010-08-23 01:08:25 +0200764 ep_read = 0x82;
Markus Grabner1027f4762010-08-12 01:35:30 +0200765 ep_write = 0x02;
766 break;
767
Markus Grabner705ecec2009-02-27 19:43:04 -0800768 case LINE6_DEVID_PODX3:
769 case LINE6_DEVID_PODX3LIVE:
770 /* currently unused! */
771 size = sizeof(struct usb_line6_pod);
Markus Grabnere1a164d2010-08-23 01:08:25 +0200772 ep_read = 0x81;
Markus Grabner705ecec2009-02-27 19:43:04 -0800773 ep_write = 0x01;
774 break;
775
Markus Grabner1027f4762010-08-12 01:35:30 +0200776 case LINE6_DEVID_PODSTUDIO_GX:
777 case LINE6_DEVID_PODSTUDIO_UX1:
778 case LINE6_DEVID_PODSTUDIO_UX2:
Markus Grabner705ecec2009-02-27 19:43:04 -0800779 case LINE6_DEVID_TONEPORT_GX:
780 case LINE6_DEVID_TONEPORT_UX1:
781 case LINE6_DEVID_TONEPORT_UX2:
782 case LINE6_DEVID_GUITARPORT:
783 size = sizeof(struct usb_line6_toneport);
784 /* these don't have a control channel */
785 break;
786
787 case LINE6_DEVID_PODXTLIVE:
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800788 switch (interface_number) {
Markus Grabner705ecec2009-02-27 19:43:04 -0800789 case PODXTLIVE_INTERFACE_POD:
790 size = sizeof(struct usb_line6_pod);
Markus Grabnere1a164d2010-08-23 01:08:25 +0200791 ep_read = 0x84;
Markus Grabner705ecec2009-02-27 19:43:04 -0800792 ep_write = 0x03;
793 break;
794
795 case PODXTLIVE_INTERFACE_VARIAX:
796 size = sizeof(struct usb_line6_variax);
Markus Grabnere1a164d2010-08-23 01:08:25 +0200797 ep_read = 0x86;
Markus Grabner705ecec2009-02-27 19:43:04 -0800798 ep_write = 0x05;
799 break;
800
801 default:
Kulikov Vasiliyab366c12010-07-13 15:22:46 +0400802 ret = -ENODEV;
803 goto err_put;
Markus Grabner705ecec2009-02-27 19:43:04 -0800804 }
805 break;
806
807 case LINE6_DEVID_VARIAX:
808 size = sizeof(struct usb_line6_variax);
Markus Grabnere1a164d2010-08-23 01:08:25 +0200809 ep_read = 0x82;
Markus Grabner705ecec2009-02-27 19:43:04 -0800810 ep_write = 0x01;
811 break;
812
813 default:
814 MISSING_CASE;
Kulikov Vasiliyab366c12010-07-13 15:22:46 +0400815 ret = -ENODEV;
816 goto err_put;
Markus Grabner705ecec2009-02-27 19:43:04 -0800817 }
818
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800819 if (size == 0) {
Dan Carpenter4bd8b4d2011-11-30 11:43:41 +0300820 dev_err(&interface->dev,
Markus Grabnere1a164d2010-08-23 01:08:25 +0200821 "driver bug: interface data size not set\n");
Kulikov Vasiliyab366c12010-07-13 15:22:46 +0400822 ret = -ENODEV;
823 goto err_put;
Markus Grabner705ecec2009-02-27 19:43:04 -0800824 }
825
826 line6 = kzalloc(size, GFP_KERNEL);
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800827 if (line6 == NULL) {
Kulikov Vasiliyab366c12010-07-13 15:22:46 +0400828 ret = -ENODEV;
829 goto err_put;
Markus Grabner705ecec2009-02-27 19:43:04 -0800830 }
831
832 /* store basic data: */
833 line6->interface_number = interface_number;
834 line6->properties = properties;
835 line6->usbdev = usbdev;
836 line6->ifcdev = &interface->dev;
837 line6->ep_control_read = ep_read;
838 line6->ep_control_write = ep_write;
839 line6->product = product;
840
841 /* get data from endpoint descriptor (see usb_maxpacket): */
842 {
843 struct usb_host_endpoint *ep;
Markus Grabnere1a164d2010-08-23 01:08:25 +0200844 unsigned epnum =
845 usb_pipeendpoint(usb_rcvintpipe(usbdev, ep_read));
Markus Grabner705ecec2009-02-27 19:43:04 -0800846 ep = usbdev->ep_in[epnum];
847
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800848 if (ep != NULL) {
Markus Grabner705ecec2009-02-27 19:43:04 -0800849 line6->interval = ep->desc.bInterval;
Markus Grabnere1a164d2010-08-23 01:08:25 +0200850 line6->max_packet_size =
851 le16_to_cpu(ep->desc.wMaxPacketSize);
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800852 } else {
Markus Grabner705ecec2009-02-27 19:43:04 -0800853 line6->interval = LINE6_FALLBACK_INTERVAL;
854 line6->max_packet_size = LINE6_FALLBACK_MAXPACKETSIZE;
Markus Grabnere1a164d2010-08-23 01:08:25 +0200855 dev_err(line6->ifcdev,
856 "endpoint not available, using fallback values");
Markus Grabner705ecec2009-02-27 19:43:04 -0800857 }
858 }
859
860 usb_set_intfdata(interface, line6);
861
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800862 if (properties->capabilities & LINE6_BIT_CONTROL) {
Markus Grabner705ecec2009-02-27 19:43:04 -0800863 /* initialize USB buffers: */
Markus Grabnere1a164d2010-08-23 01:08:25 +0200864 line6->buffer_listen =
865 kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800866 if (line6->buffer_listen == NULL) {
Kulikov Vasiliyab366c12010-07-13 15:22:46 +0400867 ret = -ENOMEM;
868 goto err_destruct;
Markus Grabner705ecec2009-02-27 19:43:04 -0800869 }
870
Markus Grabnere1a164d2010-08-23 01:08:25 +0200871 line6->buffer_message =
872 kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL);
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800873 if (line6->buffer_message == NULL) {
Kulikov Vasiliyab366c12010-07-13 15:22:46 +0400874 ret = -ENOMEM;
875 goto err_destruct;
Markus Grabner705ecec2009-02-27 19:43:04 -0800876 }
877
878 line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL);
879
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800880 if (line6->urb_listen == NULL) {
Markus Grabner705ecec2009-02-27 19:43:04 -0800881 dev_err(&interface->dev, "Out of memory\n");
882 line6_destruct(interface);
Kulikov Vasiliyab366c12010-07-13 15:22:46 +0400883 ret = -ENOMEM;
884 goto err_destruct;
Markus Grabner705ecec2009-02-27 19:43:04 -0800885 }
886
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800887 ret = line6_start_listen(line6);
888 if (ret < 0) {
889 dev_err(&interface->dev, "%s: usb_submit_urb failed\n",
890 __func__);
Kulikov Vasiliyab366c12010-07-13 15:22:46 +0400891 goto err_destruct;
Markus Grabner705ecec2009-02-27 19:43:04 -0800892 }
893 }
894
895 /* initialize device data based on product id: */
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800896 switch (product) {
Markus Grabner705ecec2009-02-27 19:43:04 -0800897 case LINE6_DEVID_BASSPODXT:
898 case LINE6_DEVID_BASSPODXTLIVE:
899 case LINE6_DEVID_BASSPODXTPRO:
900 case LINE6_DEVID_POCKETPOD:
901 case LINE6_DEVID_PODX3:
902 case LINE6_DEVID_PODX3LIVE:
903 case LINE6_DEVID_PODXT:
904 case LINE6_DEVID_PODXTPRO:
Markus Grabner1027f4762010-08-12 01:35:30 +0200905 ret = line6_pod_init(interface, (struct usb_line6_pod *)line6);
Markus Grabner705ecec2009-02-27 19:43:04 -0800906 break;
907
Stefan Hajnoczi16dc1042011-11-23 08:20:42 +0000908 case LINE6_DEVID_PODHD300:
Chris Bajumpaa1785faa2013-12-21 17:51:24 -0500909 case LINE6_DEVID_PODHD400:
Markus Grabner4c6fb5f2011-12-05 23:51:53 +0100910 case LINE6_DEVID_PODHD500:
Stefan Hajnoczi16dc1042011-11-23 08:20:42 +0000911 ret = line6_podhd_init(interface,
912 (struct usb_line6_podhd *)line6);
913 break;
914
Markus Grabner705ecec2009-02-27 19:43:04 -0800915 case LINE6_DEVID_PODXTLIVE:
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800916 switch (interface_number) {
Markus Grabner705ecec2009-02-27 19:43:04 -0800917 case PODXTLIVE_INTERFACE_POD:
Markus Grabnere1a164d2010-08-23 01:08:25 +0200918 ret =
919 line6_pod_init(interface,
920 (struct usb_line6_pod *)line6);
Markus Grabner705ecec2009-02-27 19:43:04 -0800921 break;
922
923 case PODXTLIVE_INTERFACE_VARIAX:
Markus Grabnere1a164d2010-08-23 01:08:25 +0200924 ret =
925 line6_variax_init(interface,
926 (struct usb_line6_variax *)line6);
Markus Grabner705ecec2009-02-27 19:43:04 -0800927 break;
928
929 default:
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800930 dev_err(&interface->dev,
931 "PODxt Live interface %d not supported\n",
932 interface_number);
Markus Grabner705ecec2009-02-27 19:43:04 -0800933 ret = -ENODEV;
934 }
935
936 break;
937
938 case LINE6_DEVID_VARIAX:
Markus Grabnere1a164d2010-08-23 01:08:25 +0200939 ret =
940 line6_variax_init(interface,
941 (struct usb_line6_variax *)line6);
Markus Grabner705ecec2009-02-27 19:43:04 -0800942 break;
943
Markus Grabner1027f4762010-08-12 01:35:30 +0200944 case LINE6_DEVID_PODSTUDIO_GX:
945 case LINE6_DEVID_PODSTUDIO_UX1:
946 case LINE6_DEVID_PODSTUDIO_UX2:
Markus Grabner705ecec2009-02-27 19:43:04 -0800947 case LINE6_DEVID_TONEPORT_GX:
948 case LINE6_DEVID_TONEPORT_UX1:
949 case LINE6_DEVID_TONEPORT_UX2:
950 case LINE6_DEVID_GUITARPORT:
Markus Grabnere1a164d2010-08-23 01:08:25 +0200951 ret =
952 line6_toneport_init(interface,
953 (struct usb_line6_toneport *)line6);
Markus Grabner705ecec2009-02-27 19:43:04 -0800954 break;
955
956 default:
957 MISSING_CASE;
958 ret = -ENODEV;
959 }
960
Kulikov Vasiliyab366c12010-07-13 15:22:46 +0400961 if (ret < 0)
962 goto err_destruct;
Markus Grabner705ecec2009-02-27 19:43:04 -0800963
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800964 ret = sysfs_create_link(&interface->dev.kobj, &usbdev->dev.kobj,
965 "usb_device");
Kulikov Vasiliyab366c12010-07-13 15:22:46 +0400966 if (ret < 0)
967 goto err_destruct;
Markus Grabner705ecec2009-02-27 19:43:04 -0800968
Markus Grabner1027f4762010-08-12 01:35:30 +0200969 /* creation of additional special files should go here */
970
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -0800971 dev_info(&interface->dev, "Line6 %s now attached\n",
972 line6->properties->name);
Markus Grabner1027f4762010-08-12 01:35:30 +0200973
Markus Grabnere1a164d2010-08-23 01:08:25 +0200974 switch (product) {
Markus Grabner1027f4762010-08-12 01:35:30 +0200975 case LINE6_DEVID_PODX3:
976 case LINE6_DEVID_PODX3LIVE:
Markus Grabnere1a164d2010-08-23 01:08:25 +0200977 dev_info(&interface->dev,
978 "NOTE: the Line6 %s is detected, but not yet supported\n",
Markus Grabner1027f4762010-08-12 01:35:30 +0200979 line6->properties->name);
980 }
981
982 /* increment reference counters: */
983 usb_get_intf(interface);
984 usb_get_dev(usbdev);
985
Kulikov Vasiliyab366c12010-07-13 15:22:46 +0400986 return 0;
987
988err_destruct:
989 line6_destruct(interface);
990err_put:
Markus Grabner705ecec2009-02-27 19:43:04 -0800991 return ret;
992}
993
994/*
995 Line6 device disconnected.
996*/
997static void line6_disconnect(struct usb_interface *interface)
998{
999 struct usb_line6 *line6;
1000 struct usb_device *usbdev;
Stefan Hajnoczib430b3d2012-10-15 20:26:46 +02001001 int interface_number;
Markus Grabner705ecec2009-02-27 19:43:04 -08001002
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -08001003 if (interface == NULL)
1004 return;
Markus Grabner705ecec2009-02-27 19:43:04 -08001005 usbdev = interface_to_usbdev(interface);
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -08001006 if (usbdev == NULL)
1007 return;
Markus Grabner705ecec2009-02-27 19:43:04 -08001008
Markus Grabner1027f4762010-08-12 01:35:30 +02001009 /* removal of additional special files should go here */
1010
Markus Grabner705ecec2009-02-27 19:43:04 -08001011 sysfs_remove_link(&interface->dev.kobj, "usb_device");
1012
1013 interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
1014 line6 = usb_get_intfdata(interface);
1015
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -08001016 if (line6 != NULL) {
1017 if (line6->urb_listen != NULL)
Markus Grabner1027f4762010-08-12 01:35:30 +02001018 line6_stop_listen(line6);
Markus Grabner705ecec2009-02-27 19:43:04 -08001019
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -08001020 if (usbdev != line6->usbdev)
1021 dev_err(line6->ifcdev,
1022 "driver bug: inconsistent usb device\n");
Markus Grabner705ecec2009-02-27 19:43:04 -08001023
Rashika Kheria5a083bd2013-10-26 17:12:57 +05301024 switch (le16_to_cpu(line6->usbdev->descriptor.idProduct)) {
Markus Grabner705ecec2009-02-27 19:43:04 -08001025 case LINE6_DEVID_BASSPODXT:
1026 case LINE6_DEVID_BASSPODXTLIVE:
1027 case LINE6_DEVID_BASSPODXTPRO:
1028 case LINE6_DEVID_POCKETPOD:
1029 case LINE6_DEVID_PODX3:
1030 case LINE6_DEVID_PODX3LIVE:
1031 case LINE6_DEVID_PODXT:
1032 case LINE6_DEVID_PODXTPRO:
Markus Grabner1027f4762010-08-12 01:35:30 +02001033 line6_pod_disconnect(interface);
Markus Grabner705ecec2009-02-27 19:43:04 -08001034 break;
1035
Stefan Hajnoczi16dc1042011-11-23 08:20:42 +00001036 case LINE6_DEVID_PODHD300:
Chris Bajumpaa1785faa2013-12-21 17:51:24 -05001037 case LINE6_DEVID_PODHD400:
Markus Grabner4c6fb5f2011-12-05 23:51:53 +01001038 case LINE6_DEVID_PODHD500:
Stefan Hajnoczi16dc1042011-11-23 08:20:42 +00001039 line6_podhd_disconnect(interface);
1040 break;
1041
Markus Grabner705ecec2009-02-27 19:43:04 -08001042 case LINE6_DEVID_PODXTLIVE:
Greg Kroah-Hartman36445bc2009-02-27 22:42:18 -08001043 switch (interface_number) {
Markus Grabner705ecec2009-02-27 19:43:04 -08001044 case PODXTLIVE_INTERFACE_POD:
Markus Grabner1027f4762010-08-12 01:35:30 +02001045 line6_pod_disconnect(interface);
Markus Grabner705ecec2009-02-27 19:43:04 -08001046 break;
1047
1048 case PODXTLIVE_INTERFACE_VARIAX:
Markus Grabner1027f4762010-08-12 01:35:30 +02001049 line6_variax_disconnect(interface);
Markus Grabner705ecec2009-02-27 19:43:04 -08001050 break;
1051 }
1052
1053 break;
1054
1055 case LINE6_DEVID_VARIAX:
Markus Grabner1027f4762010-08-12 01:35:30 +02001056 line6_variax_disconnect(interface);
Markus Grabner705ecec2009-02-27 19:43:04 -08001057 break;
1058
Markus Grabner1027f4762010-08-12 01:35:30 +02001059 case LINE6_DEVID_PODSTUDIO_GX:
1060 case LINE6_DEVID_PODSTUDIO_UX1:
1061 case LINE6_DEVID_PODSTUDIO_UX2:
Markus Grabner705ecec2009-02-27 19:43:04 -08001062 case LINE6_DEVID_TONEPORT_GX:
1063 case LINE6_DEVID_TONEPORT_UX1:
1064 case LINE6_DEVID_TONEPORT_UX2:
1065 case LINE6_DEVID_GUITARPORT:
Markus Grabner1027f4762010-08-12 01:35:30 +02001066 line6_toneport_disconnect(interface);
Markus Grabner705ecec2009-02-27 19:43:04 -08001067 break;
1068
1069 default:
1070 MISSING_CASE;
1071 }
1072
Markus Grabnere1a164d2010-08-23 01:08:25 +02001073 dev_info(&interface->dev, "Line6 %s now disconnected\n",
1074 line6->properties->name);
Markus Grabner705ecec2009-02-27 19:43:04 -08001075 }
1076
1077 line6_destruct(interface);
1078
1079 /* decrement reference counters: */
1080 usb_put_intf(interface);
1081 usb_put_dev(usbdev);
Markus Grabner705ecec2009-02-27 19:43:04 -08001082}
1083
Markus Grabner1027f4762010-08-12 01:35:30 +02001084#ifdef CONFIG_PM
1085
1086/*
1087 Suspend Line6 device.
1088*/
1089static int line6_suspend(struct usb_interface *interface, pm_message_t message)
1090{
1091 struct usb_line6 *line6 = usb_get_intfdata(interface);
1092 struct snd_line6_pcm *line6pcm = line6->line6pcm;
1093
1094 snd_power_change_state(line6->card, SNDRV_CTL_POWER_D3hot);
1095
1096 if (line6->properties->capabilities & LINE6_BIT_CONTROL)
1097 line6_stop_listen(line6);
1098
1099 if (line6pcm != NULL) {
1100 snd_pcm_suspend_all(line6pcm->pcm);
1101 line6_pcm_disconnect(line6pcm);
1102 line6pcm->flags = 0;
1103 }
1104
1105 return 0;
1106}
1107
1108/*
1109 Resume Line6 device.
1110*/
1111static int line6_resume(struct usb_interface *interface)
1112{
1113 struct usb_line6 *line6 = usb_get_intfdata(interface);
1114
1115 if (line6->properties->capabilities & LINE6_BIT_CONTROL)
1116 line6_start_listen(line6);
1117
1118 snd_power_change_state(line6->card, SNDRV_CTL_POWER_D0);
1119 return 0;
1120}
1121
1122/*
1123 Resume Line6 device after reset.
1124*/
1125static int line6_reset_resume(struct usb_interface *interface)
1126{
1127 struct usb_line6 *line6 = usb_get_intfdata(interface);
1128
Rashika Kheria5a083bd2013-10-26 17:12:57 +05301129 switch (le16_to_cpu(line6->usbdev->descriptor.idProduct)) {
Markus Grabner1027f4762010-08-12 01:35:30 +02001130 case LINE6_DEVID_PODSTUDIO_GX:
1131 case LINE6_DEVID_PODSTUDIO_UX1:
1132 case LINE6_DEVID_PODSTUDIO_UX2:
1133 case LINE6_DEVID_TONEPORT_GX:
1134 case LINE6_DEVID_TONEPORT_UX1:
1135 case LINE6_DEVID_TONEPORT_UX2:
1136 case LINE6_DEVID_GUITARPORT:
1137 line6_toneport_reset_resume((struct usb_line6_toneport *)line6);
1138 }
1139
1140 return line6_resume(interface);
1141}
1142
Markus Grabnere1a164d2010-08-23 01:08:25 +02001143#endif /* CONFIG_PM */
Markus Grabner1027f4762010-08-12 01:35:30 +02001144
Markus Grabner705ecec2009-02-27 19:43:04 -08001145static struct usb_driver line6_driver = {
Markus Grabner705ecec2009-02-27 19:43:04 -08001146 .name = DRIVER_NAME,
1147 .probe = line6_probe,
1148 .disconnect = line6_disconnect,
Markus Grabner1027f4762010-08-12 01:35:30 +02001149#ifdef CONFIG_PM
1150 .suspend = line6_suspend,
1151 .resume = line6_resume,
1152 .reset_resume = line6_reset_resume,
1153#endif
Markus Grabner705ecec2009-02-27 19:43:04 -08001154 .id_table = line6_id_table,
1155};
1156
Greg Kroah-Hartman4a631362012-04-23 16:13:19 -07001157module_usb_driver(line6_driver);
Markus Grabner705ecec2009-02-27 19:43:04 -08001158
1159MODULE_AUTHOR(DRIVER_AUTHOR);
1160MODULE_DESCRIPTION(DRIVER_DESC);
1161MODULE_LICENSE("GPL");
1162MODULE_VERSION(DRIVER_VERSION);