xref: /OK3568_Linux_fs/kernel/sound/usb/line6/driver.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Line 6 Linux USB driver
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <linux/kernel.h>
9*4882a593Smuzhiyun #include <linux/module.h>
10*4882a593Smuzhiyun #include <linux/export.h>
11*4882a593Smuzhiyun #include <linux/slab.h>
12*4882a593Smuzhiyun #include <linux/usb.h>
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #include <sound/core.h>
15*4882a593Smuzhiyun #include <sound/initval.h>
16*4882a593Smuzhiyun #include <sound/hwdep.h>
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #include "capture.h"
19*4882a593Smuzhiyun #include "driver.h"
20*4882a593Smuzhiyun #include "midi.h"
21*4882a593Smuzhiyun #include "playback.h"
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #define DRIVER_AUTHOR  "Markus Grabner <grabner@icg.tugraz.at>"
24*4882a593Smuzhiyun #define DRIVER_DESC    "Line 6 USB Driver"
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun /*
27*4882a593Smuzhiyun 	This is Line 6's MIDI manufacturer ID.
28*4882a593Smuzhiyun */
29*4882a593Smuzhiyun const unsigned char line6_midi_id[3] = {
30*4882a593Smuzhiyun 	0x00, 0x01, 0x0c
31*4882a593Smuzhiyun };
32*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(line6_midi_id);
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun /*
35*4882a593Smuzhiyun 	Code to request version of POD, Variax interface
36*4882a593Smuzhiyun 	(and maybe other devices).
37*4882a593Smuzhiyun */
38*4882a593Smuzhiyun static const char line6_request_version[] = {
39*4882a593Smuzhiyun 	0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7
40*4882a593Smuzhiyun };
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun /*
43*4882a593Smuzhiyun 	 Class for asynchronous messages.
44*4882a593Smuzhiyun */
45*4882a593Smuzhiyun struct message {
46*4882a593Smuzhiyun 	struct usb_line6 *line6;
47*4882a593Smuzhiyun 	const char *buffer;
48*4882a593Smuzhiyun 	int size;
49*4882a593Smuzhiyun 	int done;
50*4882a593Smuzhiyun };
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun /*
53*4882a593Smuzhiyun 	Forward declarations.
54*4882a593Smuzhiyun */
55*4882a593Smuzhiyun static void line6_data_received(struct urb *urb);
56*4882a593Smuzhiyun static int line6_send_raw_message_async_part(struct message *msg,
57*4882a593Smuzhiyun 					     struct urb *urb);
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun /*
60*4882a593Smuzhiyun 	Start to listen on endpoint.
61*4882a593Smuzhiyun */
line6_start_listen(struct usb_line6 * line6)62*4882a593Smuzhiyun static int line6_start_listen(struct usb_line6 *line6)
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun 	int err;
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	if (line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI) {
67*4882a593Smuzhiyun 		usb_fill_int_urb(line6->urb_listen, line6->usbdev,
68*4882a593Smuzhiyun 			usb_rcvintpipe(line6->usbdev, line6->properties->ep_ctrl_r),
69*4882a593Smuzhiyun 			line6->buffer_listen, LINE6_BUFSIZE_LISTEN,
70*4882a593Smuzhiyun 			line6_data_received, line6, line6->interval);
71*4882a593Smuzhiyun 	} else {
72*4882a593Smuzhiyun 		usb_fill_bulk_urb(line6->urb_listen, line6->usbdev,
73*4882a593Smuzhiyun 			usb_rcvbulkpipe(line6->usbdev, line6->properties->ep_ctrl_r),
74*4882a593Smuzhiyun 			line6->buffer_listen, LINE6_BUFSIZE_LISTEN,
75*4882a593Smuzhiyun 			line6_data_received, line6);
76*4882a593Smuzhiyun 	}
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	/* sanity checks of EP before actually submitting */
79*4882a593Smuzhiyun 	if (usb_urb_ep_type_check(line6->urb_listen)) {
80*4882a593Smuzhiyun 		dev_err(line6->ifcdev, "invalid control EP\n");
81*4882a593Smuzhiyun 		return -EINVAL;
82*4882a593Smuzhiyun 	}
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun 	line6->urb_listen->actual_length = 0;
85*4882a593Smuzhiyun 	err = usb_submit_urb(line6->urb_listen, GFP_ATOMIC);
86*4882a593Smuzhiyun 	return err;
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun /*
90*4882a593Smuzhiyun 	Stop listening on endpoint.
91*4882a593Smuzhiyun */
line6_stop_listen(struct usb_line6 * line6)92*4882a593Smuzhiyun static void line6_stop_listen(struct usb_line6 *line6)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun 	usb_kill_urb(line6->urb_listen);
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun /*
98*4882a593Smuzhiyun 	Send raw message in pieces of wMaxPacketSize bytes.
99*4882a593Smuzhiyun */
line6_send_raw_message(struct usb_line6 * line6,const char * buffer,int size)100*4882a593Smuzhiyun int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
101*4882a593Smuzhiyun 				  int size)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun 	int i, done = 0;
104*4882a593Smuzhiyun 	const struct line6_properties *properties = line6->properties;
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 	for (i = 0; i < size; i += line6->max_packet_size) {
107*4882a593Smuzhiyun 		int partial;
108*4882a593Smuzhiyun 		const char *frag_buf = buffer + i;
109*4882a593Smuzhiyun 		int frag_size = min(line6->max_packet_size, size - i);
110*4882a593Smuzhiyun 		int retval;
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 		if (properties->capabilities & LINE6_CAP_CONTROL_MIDI) {
113*4882a593Smuzhiyun 			retval = usb_interrupt_msg(line6->usbdev,
114*4882a593Smuzhiyun 						usb_sndintpipe(line6->usbdev, properties->ep_ctrl_w),
115*4882a593Smuzhiyun 						(char *)frag_buf, frag_size,
116*4882a593Smuzhiyun 						&partial, LINE6_TIMEOUT);
117*4882a593Smuzhiyun 		} else {
118*4882a593Smuzhiyun 			retval = usb_bulk_msg(line6->usbdev,
119*4882a593Smuzhiyun 						usb_sndbulkpipe(line6->usbdev, properties->ep_ctrl_w),
120*4882a593Smuzhiyun 						(char *)frag_buf, frag_size,
121*4882a593Smuzhiyun 						&partial, LINE6_TIMEOUT);
122*4882a593Smuzhiyun 		}
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 		if (retval) {
125*4882a593Smuzhiyun 			dev_err(line6->ifcdev,
126*4882a593Smuzhiyun 				"usb_bulk_msg failed (%d)\n", retval);
127*4882a593Smuzhiyun 			break;
128*4882a593Smuzhiyun 		}
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 		done += frag_size;
131*4882a593Smuzhiyun 	}
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	return done;
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(line6_send_raw_message);
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun /*
138*4882a593Smuzhiyun 	Notification of completion of asynchronous request transmission.
139*4882a593Smuzhiyun */
line6_async_request_sent(struct urb * urb)140*4882a593Smuzhiyun static void line6_async_request_sent(struct urb *urb)
141*4882a593Smuzhiyun {
142*4882a593Smuzhiyun 	struct message *msg = (struct message *)urb->context;
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 	if (msg->done >= msg->size) {
145*4882a593Smuzhiyun 		usb_free_urb(urb);
146*4882a593Smuzhiyun 		kfree(msg);
147*4882a593Smuzhiyun 	} else
148*4882a593Smuzhiyun 		line6_send_raw_message_async_part(msg, urb);
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun /*
152*4882a593Smuzhiyun 	Asynchronously send part of a raw message.
153*4882a593Smuzhiyun */
line6_send_raw_message_async_part(struct message * msg,struct urb * urb)154*4882a593Smuzhiyun static int line6_send_raw_message_async_part(struct message *msg,
155*4882a593Smuzhiyun 					     struct urb *urb)
156*4882a593Smuzhiyun {
157*4882a593Smuzhiyun 	int retval;
158*4882a593Smuzhiyun 	struct usb_line6 *line6 = msg->line6;
159*4882a593Smuzhiyun 	int done = msg->done;
160*4882a593Smuzhiyun 	int bytes = min(msg->size - done, line6->max_packet_size);
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	if (line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI) {
163*4882a593Smuzhiyun 		usb_fill_int_urb(urb, line6->usbdev,
164*4882a593Smuzhiyun 			usb_sndintpipe(line6->usbdev, line6->properties->ep_ctrl_w),
165*4882a593Smuzhiyun 			(char *)msg->buffer + done, bytes,
166*4882a593Smuzhiyun 			line6_async_request_sent, msg, line6->interval);
167*4882a593Smuzhiyun 	} else {
168*4882a593Smuzhiyun 		usb_fill_bulk_urb(urb, line6->usbdev,
169*4882a593Smuzhiyun 			usb_sndbulkpipe(line6->usbdev, line6->properties->ep_ctrl_w),
170*4882a593Smuzhiyun 			(char *)msg->buffer + done, bytes,
171*4882a593Smuzhiyun 			line6_async_request_sent, msg);
172*4882a593Smuzhiyun 	}
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun 	msg->done += bytes;
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	/* sanity checks of EP before actually submitting */
177*4882a593Smuzhiyun 	retval = usb_urb_ep_type_check(urb);
178*4882a593Smuzhiyun 	if (retval < 0)
179*4882a593Smuzhiyun 		goto error;
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	retval = usb_submit_urb(urb, GFP_ATOMIC);
182*4882a593Smuzhiyun 	if (retval < 0)
183*4882a593Smuzhiyun 		goto error;
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	return 0;
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun  error:
188*4882a593Smuzhiyun 	dev_err(line6->ifcdev, "%s: usb_submit_urb failed (%d)\n",
189*4882a593Smuzhiyun 		__func__, retval);
190*4882a593Smuzhiyun 	usb_free_urb(urb);
191*4882a593Smuzhiyun 	kfree(msg);
192*4882a593Smuzhiyun 	return retval;
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun /*
196*4882a593Smuzhiyun 	Asynchronously send raw message.
197*4882a593Smuzhiyun */
line6_send_raw_message_async(struct usb_line6 * line6,const char * buffer,int size)198*4882a593Smuzhiyun int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer,
199*4882a593Smuzhiyun 				 int size)
200*4882a593Smuzhiyun {
201*4882a593Smuzhiyun 	struct message *msg;
202*4882a593Smuzhiyun 	struct urb *urb;
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun 	/* create message: */
205*4882a593Smuzhiyun 	msg = kmalloc(sizeof(struct message), GFP_ATOMIC);
206*4882a593Smuzhiyun 	if (msg == NULL)
207*4882a593Smuzhiyun 		return -ENOMEM;
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun 	/* create URB: */
210*4882a593Smuzhiyun 	urb = usb_alloc_urb(0, GFP_ATOMIC);
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 	if (urb == NULL) {
213*4882a593Smuzhiyun 		kfree(msg);
214*4882a593Smuzhiyun 		return -ENOMEM;
215*4882a593Smuzhiyun 	}
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	/* set message data: */
218*4882a593Smuzhiyun 	msg->line6 = line6;
219*4882a593Smuzhiyun 	msg->buffer = buffer;
220*4882a593Smuzhiyun 	msg->size = size;
221*4882a593Smuzhiyun 	msg->done = 0;
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	/* start sending: */
224*4882a593Smuzhiyun 	return line6_send_raw_message_async_part(msg, urb);
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(line6_send_raw_message_async);
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun /*
229*4882a593Smuzhiyun 	Send asynchronous device version request.
230*4882a593Smuzhiyun */
line6_version_request_async(struct usb_line6 * line6)231*4882a593Smuzhiyun int line6_version_request_async(struct usb_line6 *line6)
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun 	char *buffer;
234*4882a593Smuzhiyun 	int retval;
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 	buffer = kmemdup(line6_request_version,
237*4882a593Smuzhiyun 			sizeof(line6_request_version), GFP_ATOMIC);
238*4882a593Smuzhiyun 	if (buffer == NULL)
239*4882a593Smuzhiyun 		return -ENOMEM;
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	retval = line6_send_raw_message_async(line6, buffer,
242*4882a593Smuzhiyun 					      sizeof(line6_request_version));
243*4882a593Smuzhiyun 	kfree(buffer);
244*4882a593Smuzhiyun 	return retval;
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(line6_version_request_async);
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun /*
249*4882a593Smuzhiyun 	Send sysex message in pieces of wMaxPacketSize bytes.
250*4882a593Smuzhiyun */
line6_send_sysex_message(struct usb_line6 * line6,const char * buffer,int size)251*4882a593Smuzhiyun int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer,
252*4882a593Smuzhiyun 			     int size)
253*4882a593Smuzhiyun {
254*4882a593Smuzhiyun 	return line6_send_raw_message(line6, buffer,
255*4882a593Smuzhiyun 				      size + SYSEX_EXTRA_SIZE) -
256*4882a593Smuzhiyun 	    SYSEX_EXTRA_SIZE;
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(line6_send_sysex_message);
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun /*
261*4882a593Smuzhiyun 	Allocate buffer for sysex message and prepare header.
262*4882a593Smuzhiyun 	@param code sysex message code
263*4882a593Smuzhiyun 	@param size number of bytes between code and sysex end
264*4882a593Smuzhiyun */
line6_alloc_sysex_buffer(struct usb_line6 * line6,int code1,int code2,int size)265*4882a593Smuzhiyun char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2,
266*4882a593Smuzhiyun 			       int size)
267*4882a593Smuzhiyun {
268*4882a593Smuzhiyun 	char *buffer = kmalloc(size + SYSEX_EXTRA_SIZE, GFP_ATOMIC);
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	if (!buffer)
271*4882a593Smuzhiyun 		return NULL;
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun 	buffer[0] = LINE6_SYSEX_BEGIN;
274*4882a593Smuzhiyun 	memcpy(buffer + 1, line6_midi_id, sizeof(line6_midi_id));
275*4882a593Smuzhiyun 	buffer[sizeof(line6_midi_id) + 1] = code1;
276*4882a593Smuzhiyun 	buffer[sizeof(line6_midi_id) + 2] = code2;
277*4882a593Smuzhiyun 	buffer[sizeof(line6_midi_id) + 3 + size] = LINE6_SYSEX_END;
278*4882a593Smuzhiyun 	return buffer;
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(line6_alloc_sysex_buffer);
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun /*
283*4882a593Smuzhiyun 	Notification of data received from the Line 6 device.
284*4882a593Smuzhiyun */
line6_data_received(struct urb * urb)285*4882a593Smuzhiyun static void line6_data_received(struct urb *urb)
286*4882a593Smuzhiyun {
287*4882a593Smuzhiyun 	struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
288*4882a593Smuzhiyun 	struct midi_buffer *mb = &line6->line6midi->midibuf_in;
289*4882a593Smuzhiyun 	int done;
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun 	if (urb->status == -ESHUTDOWN)
292*4882a593Smuzhiyun 		return;
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 	if (line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI) {
295*4882a593Smuzhiyun 		done =
296*4882a593Smuzhiyun 			line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length);
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 		if (done < urb->actual_length) {
299*4882a593Smuzhiyun 			line6_midibuf_ignore(mb, done);
300*4882a593Smuzhiyun 			dev_dbg(line6->ifcdev, "%d %d buffer overflow - message skipped\n",
301*4882a593Smuzhiyun 				done, urb->actual_length);
302*4882a593Smuzhiyun 		}
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun 		for (;;) {
305*4882a593Smuzhiyun 			done =
306*4882a593Smuzhiyun 				line6_midibuf_read(mb, line6->buffer_message,
307*4882a593Smuzhiyun 						LINE6_MIDI_MESSAGE_MAXLEN);
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 			if (done <= 0)
310*4882a593Smuzhiyun 				break;
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 			line6->message_length = done;
313*4882a593Smuzhiyun 			line6_midi_receive(line6, line6->buffer_message, done);
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 			if (line6->process_message)
316*4882a593Smuzhiyun 				line6->process_message(line6);
317*4882a593Smuzhiyun 		}
318*4882a593Smuzhiyun 	} else {
319*4882a593Smuzhiyun 		line6->buffer_message = urb->transfer_buffer;
320*4882a593Smuzhiyun 		line6->message_length = urb->actual_length;
321*4882a593Smuzhiyun 		if (line6->process_message)
322*4882a593Smuzhiyun 			line6->process_message(line6);
323*4882a593Smuzhiyun 		line6->buffer_message = NULL;
324*4882a593Smuzhiyun 	}
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun 	line6_start_listen(line6);
327*4882a593Smuzhiyun }
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun #define LINE6_READ_WRITE_STATUS_DELAY 2  /* milliseconds */
330*4882a593Smuzhiyun #define LINE6_READ_WRITE_MAX_RETRIES 50
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun /*
333*4882a593Smuzhiyun 	Read data from device.
334*4882a593Smuzhiyun */
line6_read_data(struct usb_line6 * line6,unsigned address,void * data,unsigned datalen)335*4882a593Smuzhiyun int line6_read_data(struct usb_line6 *line6, unsigned address, void *data,
336*4882a593Smuzhiyun 		    unsigned datalen)
337*4882a593Smuzhiyun {
338*4882a593Smuzhiyun 	struct usb_device *usbdev = line6->usbdev;
339*4882a593Smuzhiyun 	int ret;
340*4882a593Smuzhiyun 	u8 len;
341*4882a593Smuzhiyun 	unsigned count;
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun 	if (address > 0xffff || datalen > 0xff)
344*4882a593Smuzhiyun 		return -EINVAL;
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun 	/* query the serial number: */
347*4882a593Smuzhiyun 	ret = usb_control_msg_send(usbdev, 0, 0x67,
348*4882a593Smuzhiyun 				   USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
349*4882a593Smuzhiyun 				   (datalen << 8) | 0x21, address, NULL, 0,
350*4882a593Smuzhiyun 				   LINE6_TIMEOUT, GFP_KERNEL);
351*4882a593Smuzhiyun 	if (ret) {
352*4882a593Smuzhiyun 		dev_err(line6->ifcdev, "read request failed (error %d)\n", ret);
353*4882a593Smuzhiyun 		goto exit;
354*4882a593Smuzhiyun 	}
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 	/* Wait for data length. We'll get 0xff until length arrives. */
357*4882a593Smuzhiyun 	for (count = 0; count < LINE6_READ_WRITE_MAX_RETRIES; count++) {
358*4882a593Smuzhiyun 		mdelay(LINE6_READ_WRITE_STATUS_DELAY);
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun 		ret = usb_control_msg_recv(usbdev, 0, 0x67,
361*4882a593Smuzhiyun 					   USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
362*4882a593Smuzhiyun 					   0x0012, 0x0000, &len, 1,
363*4882a593Smuzhiyun 					   LINE6_TIMEOUT, GFP_KERNEL);
364*4882a593Smuzhiyun 		if (ret) {
365*4882a593Smuzhiyun 			dev_err(line6->ifcdev,
366*4882a593Smuzhiyun 				"receive length failed (error %d)\n", ret);
367*4882a593Smuzhiyun 			goto exit;
368*4882a593Smuzhiyun 		}
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun 		if (len != 0xff)
371*4882a593Smuzhiyun 			break;
372*4882a593Smuzhiyun 	}
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun 	ret = -EIO;
375*4882a593Smuzhiyun 	if (len == 0xff) {
376*4882a593Smuzhiyun 		dev_err(line6->ifcdev, "read failed after %d retries\n",
377*4882a593Smuzhiyun 			count);
378*4882a593Smuzhiyun 		goto exit;
379*4882a593Smuzhiyun 	} else if (len != datalen) {
380*4882a593Smuzhiyun 		/* should be equal or something went wrong */
381*4882a593Smuzhiyun 		dev_err(line6->ifcdev,
382*4882a593Smuzhiyun 			"length mismatch (expected %d, got %d)\n",
383*4882a593Smuzhiyun 			(int)datalen, len);
384*4882a593Smuzhiyun 		goto exit;
385*4882a593Smuzhiyun 	}
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun 	/* receive the result: */
388*4882a593Smuzhiyun 	ret = usb_control_msg_recv(usbdev, 0, 0x67,
389*4882a593Smuzhiyun 				   USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
390*4882a593Smuzhiyun 				   0x0013, 0x0000, data, datalen, LINE6_TIMEOUT,
391*4882a593Smuzhiyun 				   GFP_KERNEL);
392*4882a593Smuzhiyun 	if (ret)
393*4882a593Smuzhiyun 		dev_err(line6->ifcdev, "read failed (error %d)\n", ret);
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun exit:
396*4882a593Smuzhiyun 	return ret;
397*4882a593Smuzhiyun }
398*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(line6_read_data);
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun /*
401*4882a593Smuzhiyun 	Write data to device.
402*4882a593Smuzhiyun */
line6_write_data(struct usb_line6 * line6,unsigned address,void * data,unsigned datalen)403*4882a593Smuzhiyun int line6_write_data(struct usb_line6 *line6, unsigned address, void *data,
404*4882a593Smuzhiyun 		     unsigned datalen)
405*4882a593Smuzhiyun {
406*4882a593Smuzhiyun 	struct usb_device *usbdev = line6->usbdev;
407*4882a593Smuzhiyun 	int ret;
408*4882a593Smuzhiyun 	unsigned char *status;
409*4882a593Smuzhiyun 	int count;
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun 	if (address > 0xffff || datalen > 0xffff)
412*4882a593Smuzhiyun 		return -EINVAL;
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun 	status = kmalloc(1, GFP_KERNEL);
415*4882a593Smuzhiyun 	if (!status)
416*4882a593Smuzhiyun 		return -ENOMEM;
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun 	ret = usb_control_msg_send(usbdev, 0, 0x67,
419*4882a593Smuzhiyun 				   USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
420*4882a593Smuzhiyun 				   0x0022, address, data, datalen, LINE6_TIMEOUT,
421*4882a593Smuzhiyun 				   GFP_KERNEL);
422*4882a593Smuzhiyun 	if (ret) {
423*4882a593Smuzhiyun 		dev_err(line6->ifcdev,
424*4882a593Smuzhiyun 			"write request failed (error %d)\n", ret);
425*4882a593Smuzhiyun 		goto exit;
426*4882a593Smuzhiyun 	}
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun 	for (count = 0; count < LINE6_READ_WRITE_MAX_RETRIES; count++) {
429*4882a593Smuzhiyun 		mdelay(LINE6_READ_WRITE_STATUS_DELAY);
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun 		ret = usb_control_msg_recv(usbdev, 0, 0x67,
432*4882a593Smuzhiyun 					   USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
433*4882a593Smuzhiyun 					   0x0012, 0x0000, status, 1, LINE6_TIMEOUT,
434*4882a593Smuzhiyun 					   GFP_KERNEL);
435*4882a593Smuzhiyun 		if (ret) {
436*4882a593Smuzhiyun 			dev_err(line6->ifcdev,
437*4882a593Smuzhiyun 				"receiving status failed (error %d)\n", ret);
438*4882a593Smuzhiyun 			goto exit;
439*4882a593Smuzhiyun 		}
440*4882a593Smuzhiyun 
441*4882a593Smuzhiyun 		if (*status != 0xff)
442*4882a593Smuzhiyun 			break;
443*4882a593Smuzhiyun 	}
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun 	if (*status == 0xff) {
446*4882a593Smuzhiyun 		dev_err(line6->ifcdev, "write failed after %d retries\n",
447*4882a593Smuzhiyun 			count);
448*4882a593Smuzhiyun 		ret = -EIO;
449*4882a593Smuzhiyun 	} else if (*status != 0) {
450*4882a593Smuzhiyun 		dev_err(line6->ifcdev, "write failed (error %d)\n", ret);
451*4882a593Smuzhiyun 		ret = -EIO;
452*4882a593Smuzhiyun 	}
453*4882a593Smuzhiyun exit:
454*4882a593Smuzhiyun 	kfree(status);
455*4882a593Smuzhiyun 	return ret;
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(line6_write_data);
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun /*
460*4882a593Smuzhiyun 	Read Line 6 device serial number.
461*4882a593Smuzhiyun 	(POD, TonePort, GuitarPort)
462*4882a593Smuzhiyun */
line6_read_serial_number(struct usb_line6 * line6,u32 * serial_number)463*4882a593Smuzhiyun int line6_read_serial_number(struct usb_line6 *line6, u32 *serial_number)
464*4882a593Smuzhiyun {
465*4882a593Smuzhiyun 	return line6_read_data(line6, 0x80d0, serial_number,
466*4882a593Smuzhiyun 			       sizeof(*serial_number));
467*4882a593Smuzhiyun }
468*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(line6_read_serial_number);
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun /*
471*4882a593Smuzhiyun 	Card destructor.
472*4882a593Smuzhiyun */
line6_destruct(struct snd_card * card)473*4882a593Smuzhiyun static void line6_destruct(struct snd_card *card)
474*4882a593Smuzhiyun {
475*4882a593Smuzhiyun 	struct usb_line6 *line6 = card->private_data;
476*4882a593Smuzhiyun 	struct usb_device *usbdev = line6->usbdev;
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun 	/* Free buffer memory first. We cannot depend on the existence of private
479*4882a593Smuzhiyun 	 * data from the (podhd) module, it may be gone already during this call
480*4882a593Smuzhiyun 	 */
481*4882a593Smuzhiyun 	kfree(line6->buffer_message);
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun 	kfree(line6->buffer_listen);
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun 	/* then free URBs: */
486*4882a593Smuzhiyun 	usb_free_urb(line6->urb_listen);
487*4882a593Smuzhiyun 	line6->urb_listen = NULL;
488*4882a593Smuzhiyun 
489*4882a593Smuzhiyun 	/* decrement reference counters: */
490*4882a593Smuzhiyun 	usb_put_dev(usbdev);
491*4882a593Smuzhiyun }
492*4882a593Smuzhiyun 
line6_get_usb_properties(struct usb_line6 * line6)493*4882a593Smuzhiyun static void line6_get_usb_properties(struct usb_line6 *line6)
494*4882a593Smuzhiyun {
495*4882a593Smuzhiyun 	struct usb_device *usbdev = line6->usbdev;
496*4882a593Smuzhiyun 	const struct line6_properties *properties = line6->properties;
497*4882a593Smuzhiyun 	int pipe;
498*4882a593Smuzhiyun 	struct usb_host_endpoint *ep = NULL;
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun 	if (properties->capabilities & LINE6_CAP_CONTROL) {
501*4882a593Smuzhiyun 		if (properties->capabilities & LINE6_CAP_CONTROL_MIDI) {
502*4882a593Smuzhiyun 			pipe = usb_rcvintpipe(line6->usbdev,
503*4882a593Smuzhiyun 				line6->properties->ep_ctrl_r);
504*4882a593Smuzhiyun 		} else {
505*4882a593Smuzhiyun 			pipe = usb_rcvbulkpipe(line6->usbdev,
506*4882a593Smuzhiyun 				line6->properties->ep_ctrl_r);
507*4882a593Smuzhiyun 		}
508*4882a593Smuzhiyun 		ep = usbdev->ep_in[usb_pipeendpoint(pipe)];
509*4882a593Smuzhiyun 	}
510*4882a593Smuzhiyun 
511*4882a593Smuzhiyun 	/* Control data transfer properties */
512*4882a593Smuzhiyun 	if (ep) {
513*4882a593Smuzhiyun 		line6->interval = ep->desc.bInterval;
514*4882a593Smuzhiyun 		line6->max_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
515*4882a593Smuzhiyun 	} else {
516*4882a593Smuzhiyun 		if (properties->capabilities & LINE6_CAP_CONTROL) {
517*4882a593Smuzhiyun 			dev_err(line6->ifcdev,
518*4882a593Smuzhiyun 				"endpoint not available, using fallback values");
519*4882a593Smuzhiyun 		}
520*4882a593Smuzhiyun 		line6->interval = LINE6_FALLBACK_INTERVAL;
521*4882a593Smuzhiyun 		line6->max_packet_size = LINE6_FALLBACK_MAXPACKETSIZE;
522*4882a593Smuzhiyun 	}
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun 	/* Isochronous transfer properties */
525*4882a593Smuzhiyun 	if (usbdev->speed == USB_SPEED_LOW) {
526*4882a593Smuzhiyun 		line6->intervals_per_second = USB_LOW_INTERVALS_PER_SECOND;
527*4882a593Smuzhiyun 		line6->iso_buffers = USB_LOW_ISO_BUFFERS;
528*4882a593Smuzhiyun 	} else {
529*4882a593Smuzhiyun 		line6->intervals_per_second = USB_HIGH_INTERVALS_PER_SECOND;
530*4882a593Smuzhiyun 		line6->iso_buffers = USB_HIGH_ISO_BUFFERS;
531*4882a593Smuzhiyun 	}
532*4882a593Smuzhiyun }
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun /* Enable buffering of incoming messages, flush the buffer */
line6_hwdep_open(struct snd_hwdep * hw,struct file * file)535*4882a593Smuzhiyun static int line6_hwdep_open(struct snd_hwdep *hw, struct file *file)
536*4882a593Smuzhiyun {
537*4882a593Smuzhiyun 	struct usb_line6 *line6 = hw->private_data;
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun 	/* NOTE: hwdep layer provides atomicity here */
540*4882a593Smuzhiyun 
541*4882a593Smuzhiyun 	line6->messages.active = 1;
542*4882a593Smuzhiyun 	line6->messages.nonblock = file->f_flags & O_NONBLOCK ? 1 : 0;
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun 	return 0;
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun /* Stop buffering */
line6_hwdep_release(struct snd_hwdep * hw,struct file * file)548*4882a593Smuzhiyun static int line6_hwdep_release(struct snd_hwdep *hw, struct file *file)
549*4882a593Smuzhiyun {
550*4882a593Smuzhiyun 	struct usb_line6 *line6 = hw->private_data;
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun 	line6->messages.active = 0;
553*4882a593Smuzhiyun 
554*4882a593Smuzhiyun 	return 0;
555*4882a593Smuzhiyun }
556*4882a593Smuzhiyun 
557*4882a593Smuzhiyun /* Read from circular buffer, return to user */
558*4882a593Smuzhiyun static long
line6_hwdep_read(struct snd_hwdep * hwdep,char __user * buf,long count,loff_t * offset)559*4882a593Smuzhiyun line6_hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
560*4882a593Smuzhiyun 					loff_t *offset)
561*4882a593Smuzhiyun {
562*4882a593Smuzhiyun 	struct usb_line6 *line6 = hwdep->private_data;
563*4882a593Smuzhiyun 	long rv = 0;
564*4882a593Smuzhiyun 	unsigned int out_count;
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun 	if (mutex_lock_interruptible(&line6->messages.read_lock))
567*4882a593Smuzhiyun 		return -ERESTARTSYS;
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun 	while (kfifo_len(&line6->messages.fifo) == 0) {
570*4882a593Smuzhiyun 		mutex_unlock(&line6->messages.read_lock);
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun 		if (line6->messages.nonblock)
573*4882a593Smuzhiyun 			return -EAGAIN;
574*4882a593Smuzhiyun 
575*4882a593Smuzhiyun 		rv = wait_event_interruptible(
576*4882a593Smuzhiyun 			line6->messages.wait_queue,
577*4882a593Smuzhiyun 			kfifo_len(&line6->messages.fifo) != 0);
578*4882a593Smuzhiyun 		if (rv < 0)
579*4882a593Smuzhiyun 			return rv;
580*4882a593Smuzhiyun 
581*4882a593Smuzhiyun 		if (mutex_lock_interruptible(&line6->messages.read_lock))
582*4882a593Smuzhiyun 			return -ERESTARTSYS;
583*4882a593Smuzhiyun 	}
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun 	if (kfifo_peek_len(&line6->messages.fifo) > count) {
586*4882a593Smuzhiyun 		/* Buffer too small; allow re-read of the current item... */
587*4882a593Smuzhiyun 		rv = -EINVAL;
588*4882a593Smuzhiyun 	} else {
589*4882a593Smuzhiyun 		rv = kfifo_to_user(&line6->messages.fifo, buf, count, &out_count);
590*4882a593Smuzhiyun 		if (rv == 0)
591*4882a593Smuzhiyun 			rv = out_count;
592*4882a593Smuzhiyun 	}
593*4882a593Smuzhiyun 
594*4882a593Smuzhiyun 	mutex_unlock(&line6->messages.read_lock);
595*4882a593Smuzhiyun 	return rv;
596*4882a593Smuzhiyun }
597*4882a593Smuzhiyun 
598*4882a593Smuzhiyun /* Write directly (no buffering) to device by user*/
599*4882a593Smuzhiyun static long
line6_hwdep_write(struct snd_hwdep * hwdep,const char __user * data,long count,loff_t * offset)600*4882a593Smuzhiyun line6_hwdep_write(struct snd_hwdep *hwdep, const char __user *data, long count,
601*4882a593Smuzhiyun 					loff_t *offset)
602*4882a593Smuzhiyun {
603*4882a593Smuzhiyun 	struct usb_line6 *line6 = hwdep->private_data;
604*4882a593Smuzhiyun 	int rv;
605*4882a593Smuzhiyun 	char *data_copy;
606*4882a593Smuzhiyun 
607*4882a593Smuzhiyun 	if (count > line6->max_packet_size * LINE6_RAW_MESSAGES_MAXCOUNT) {
608*4882a593Smuzhiyun 		/* This is an arbitrary limit - still better than nothing... */
609*4882a593Smuzhiyun 		return -EINVAL;
610*4882a593Smuzhiyun 	}
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun 	data_copy = memdup_user(data, count);
613*4882a593Smuzhiyun 	if (IS_ERR(data_copy))
614*4882a593Smuzhiyun 		return PTR_ERR(data_copy);
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun 	rv = line6_send_raw_message(line6, data_copy, count);
617*4882a593Smuzhiyun 
618*4882a593Smuzhiyun 	kfree(data_copy);
619*4882a593Smuzhiyun 	return rv;
620*4882a593Smuzhiyun }
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun static __poll_t
line6_hwdep_poll(struct snd_hwdep * hwdep,struct file * file,poll_table * wait)623*4882a593Smuzhiyun line6_hwdep_poll(struct snd_hwdep *hwdep, struct file *file, poll_table *wait)
624*4882a593Smuzhiyun {
625*4882a593Smuzhiyun 	__poll_t rv;
626*4882a593Smuzhiyun 	struct usb_line6 *line6 = hwdep->private_data;
627*4882a593Smuzhiyun 
628*4882a593Smuzhiyun 	poll_wait(file, &line6->messages.wait_queue, wait);
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun 	mutex_lock(&line6->messages.read_lock);
631*4882a593Smuzhiyun 	rv = kfifo_len(&line6->messages.fifo) == 0 ? 0 : EPOLLIN | EPOLLRDNORM;
632*4882a593Smuzhiyun 	mutex_unlock(&line6->messages.read_lock);
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun 	return rv;
635*4882a593Smuzhiyun }
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun static const struct snd_hwdep_ops hwdep_ops = {
638*4882a593Smuzhiyun 	.open    = line6_hwdep_open,
639*4882a593Smuzhiyun 	.release = line6_hwdep_release,
640*4882a593Smuzhiyun 	.read    = line6_hwdep_read,
641*4882a593Smuzhiyun 	.write   = line6_hwdep_write,
642*4882a593Smuzhiyun 	.poll    = line6_hwdep_poll,
643*4882a593Smuzhiyun };
644*4882a593Smuzhiyun 
645*4882a593Smuzhiyun /* Insert into circular buffer */
line6_hwdep_push_message(struct usb_line6 * line6)646*4882a593Smuzhiyun static void line6_hwdep_push_message(struct usb_line6 *line6)
647*4882a593Smuzhiyun {
648*4882a593Smuzhiyun 	if (!line6->messages.active)
649*4882a593Smuzhiyun 		return;
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 	if (kfifo_avail(&line6->messages.fifo) >= line6->message_length) {
652*4882a593Smuzhiyun 		/* No race condition here, there's only one writer */
653*4882a593Smuzhiyun 		kfifo_in(&line6->messages.fifo,
654*4882a593Smuzhiyun 			line6->buffer_message, line6->message_length);
655*4882a593Smuzhiyun 	} /* else TODO: signal overflow */
656*4882a593Smuzhiyun 
657*4882a593Smuzhiyun 	wake_up_interruptible(&line6->messages.wait_queue);
658*4882a593Smuzhiyun }
659*4882a593Smuzhiyun 
line6_hwdep_init(struct usb_line6 * line6)660*4882a593Smuzhiyun static int line6_hwdep_init(struct usb_line6 *line6)
661*4882a593Smuzhiyun {
662*4882a593Smuzhiyun 	int err;
663*4882a593Smuzhiyun 	struct snd_hwdep *hwdep;
664*4882a593Smuzhiyun 
665*4882a593Smuzhiyun 	/* TODO: usb_driver_claim_interface(); */
666*4882a593Smuzhiyun 	line6->process_message = line6_hwdep_push_message;
667*4882a593Smuzhiyun 	line6->messages.active = 0;
668*4882a593Smuzhiyun 	init_waitqueue_head(&line6->messages.wait_queue);
669*4882a593Smuzhiyun 	mutex_init(&line6->messages.read_lock);
670*4882a593Smuzhiyun 	INIT_KFIFO(line6->messages.fifo);
671*4882a593Smuzhiyun 
672*4882a593Smuzhiyun 	err = snd_hwdep_new(line6->card, "config", 0, &hwdep);
673*4882a593Smuzhiyun 	if (err < 0)
674*4882a593Smuzhiyun 		goto end;
675*4882a593Smuzhiyun 	strcpy(hwdep->name, "config");
676*4882a593Smuzhiyun 	hwdep->iface = SNDRV_HWDEP_IFACE_LINE6;
677*4882a593Smuzhiyun 	hwdep->ops = hwdep_ops;
678*4882a593Smuzhiyun 	hwdep->private_data = line6;
679*4882a593Smuzhiyun 	hwdep->exclusive = true;
680*4882a593Smuzhiyun 
681*4882a593Smuzhiyun end:
682*4882a593Smuzhiyun 	return err;
683*4882a593Smuzhiyun }
684*4882a593Smuzhiyun 
line6_init_cap_control(struct usb_line6 * line6)685*4882a593Smuzhiyun static int line6_init_cap_control(struct usb_line6 *line6)
686*4882a593Smuzhiyun {
687*4882a593Smuzhiyun 	int ret;
688*4882a593Smuzhiyun 
689*4882a593Smuzhiyun 	/* initialize USB buffers: */
690*4882a593Smuzhiyun 	line6->buffer_listen = kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);
691*4882a593Smuzhiyun 	if (!line6->buffer_listen)
692*4882a593Smuzhiyun 		return -ENOMEM;
693*4882a593Smuzhiyun 
694*4882a593Smuzhiyun 	line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL);
695*4882a593Smuzhiyun 	if (!line6->urb_listen)
696*4882a593Smuzhiyun 		return -ENOMEM;
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun 	if (line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI) {
699*4882a593Smuzhiyun 		line6->buffer_message = kmalloc(LINE6_MIDI_MESSAGE_MAXLEN, GFP_KERNEL);
700*4882a593Smuzhiyun 		if (!line6->buffer_message)
701*4882a593Smuzhiyun 			return -ENOMEM;
702*4882a593Smuzhiyun 
703*4882a593Smuzhiyun 		ret = line6_init_midi(line6);
704*4882a593Smuzhiyun 		if (ret < 0)
705*4882a593Smuzhiyun 			return ret;
706*4882a593Smuzhiyun 	} else {
707*4882a593Smuzhiyun 		ret = line6_hwdep_init(line6);
708*4882a593Smuzhiyun 		if (ret < 0)
709*4882a593Smuzhiyun 			return ret;
710*4882a593Smuzhiyun 	}
711*4882a593Smuzhiyun 
712*4882a593Smuzhiyun 	ret = line6_start_listen(line6);
713*4882a593Smuzhiyun 	if (ret < 0) {
714*4882a593Smuzhiyun 		dev_err(line6->ifcdev, "cannot start listening: %d\n", ret);
715*4882a593Smuzhiyun 		return ret;
716*4882a593Smuzhiyun 	}
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun 	return 0;
719*4882a593Smuzhiyun }
720*4882a593Smuzhiyun 
line6_startup_work(struct work_struct * work)721*4882a593Smuzhiyun static void line6_startup_work(struct work_struct *work)
722*4882a593Smuzhiyun {
723*4882a593Smuzhiyun 	struct usb_line6 *line6 =
724*4882a593Smuzhiyun 		container_of(work, struct usb_line6, startup_work.work);
725*4882a593Smuzhiyun 
726*4882a593Smuzhiyun 	if (line6->startup)
727*4882a593Smuzhiyun 		line6->startup(line6);
728*4882a593Smuzhiyun }
729*4882a593Smuzhiyun 
730*4882a593Smuzhiyun /*
731*4882a593Smuzhiyun 	Probe USB device.
732*4882a593Smuzhiyun */
line6_probe(struct usb_interface * interface,const struct usb_device_id * id,const char * driver_name,const struct line6_properties * properties,int (* private_init)(struct usb_line6 *,const struct usb_device_id * id),size_t data_size)733*4882a593Smuzhiyun int line6_probe(struct usb_interface *interface,
734*4882a593Smuzhiyun 		const struct usb_device_id *id,
735*4882a593Smuzhiyun 		const char *driver_name,
736*4882a593Smuzhiyun 		const struct line6_properties *properties,
737*4882a593Smuzhiyun 		int (*private_init)(struct usb_line6 *, const struct usb_device_id *id),
738*4882a593Smuzhiyun 		size_t data_size)
739*4882a593Smuzhiyun {
740*4882a593Smuzhiyun 	struct usb_device *usbdev = interface_to_usbdev(interface);
741*4882a593Smuzhiyun 	struct snd_card *card;
742*4882a593Smuzhiyun 	struct usb_line6 *line6;
743*4882a593Smuzhiyun 	int interface_number;
744*4882a593Smuzhiyun 	int ret;
745*4882a593Smuzhiyun 
746*4882a593Smuzhiyun 	if (WARN_ON(data_size < sizeof(*line6)))
747*4882a593Smuzhiyun 		return -EINVAL;
748*4882a593Smuzhiyun 
749*4882a593Smuzhiyun 	/* we don't handle multiple configurations */
750*4882a593Smuzhiyun 	if (usbdev->descriptor.bNumConfigurations != 1)
751*4882a593Smuzhiyun 		return -ENODEV;
752*4882a593Smuzhiyun 
753*4882a593Smuzhiyun 	ret = snd_card_new(&interface->dev,
754*4882a593Smuzhiyun 			   SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
755*4882a593Smuzhiyun 			   THIS_MODULE, data_size, &card);
756*4882a593Smuzhiyun 	if (ret < 0)
757*4882a593Smuzhiyun 		return ret;
758*4882a593Smuzhiyun 
759*4882a593Smuzhiyun 	/* store basic data: */
760*4882a593Smuzhiyun 	line6 = card->private_data;
761*4882a593Smuzhiyun 	line6->card = card;
762*4882a593Smuzhiyun 	line6->properties = properties;
763*4882a593Smuzhiyun 	line6->usbdev = usbdev;
764*4882a593Smuzhiyun 	line6->ifcdev = &interface->dev;
765*4882a593Smuzhiyun 	INIT_DELAYED_WORK(&line6->startup_work, line6_startup_work);
766*4882a593Smuzhiyun 
767*4882a593Smuzhiyun 	strcpy(card->id, properties->id);
768*4882a593Smuzhiyun 	strcpy(card->driver, driver_name);
769*4882a593Smuzhiyun 	strcpy(card->shortname, properties->name);
770*4882a593Smuzhiyun 	sprintf(card->longname, "Line 6 %s at USB %s", properties->name,
771*4882a593Smuzhiyun 		dev_name(line6->ifcdev));
772*4882a593Smuzhiyun 	card->private_free = line6_destruct;
773*4882a593Smuzhiyun 
774*4882a593Smuzhiyun 	usb_set_intfdata(interface, line6);
775*4882a593Smuzhiyun 
776*4882a593Smuzhiyun 	/* increment reference counters: */
777*4882a593Smuzhiyun 	usb_get_dev(usbdev);
778*4882a593Smuzhiyun 
779*4882a593Smuzhiyun 	/* initialize device info: */
780*4882a593Smuzhiyun 	dev_info(&interface->dev, "Line 6 %s found\n", properties->name);
781*4882a593Smuzhiyun 
782*4882a593Smuzhiyun 	/* query interface number */
783*4882a593Smuzhiyun 	interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
784*4882a593Smuzhiyun 
785*4882a593Smuzhiyun 	/* TODO reserves the bus bandwidth even without actual transfer */
786*4882a593Smuzhiyun 	ret = usb_set_interface(usbdev, interface_number,
787*4882a593Smuzhiyun 				properties->altsetting);
788*4882a593Smuzhiyun 	if (ret < 0) {
789*4882a593Smuzhiyun 		dev_err(&interface->dev, "set_interface failed\n");
790*4882a593Smuzhiyun 		goto error;
791*4882a593Smuzhiyun 	}
792*4882a593Smuzhiyun 
793*4882a593Smuzhiyun 	line6_get_usb_properties(line6);
794*4882a593Smuzhiyun 
795*4882a593Smuzhiyun 	if (properties->capabilities & LINE6_CAP_CONTROL) {
796*4882a593Smuzhiyun 		ret = line6_init_cap_control(line6);
797*4882a593Smuzhiyun 		if (ret < 0)
798*4882a593Smuzhiyun 			goto error;
799*4882a593Smuzhiyun 	}
800*4882a593Smuzhiyun 
801*4882a593Smuzhiyun 	/* initialize device data based on device: */
802*4882a593Smuzhiyun 	ret = private_init(line6, id);
803*4882a593Smuzhiyun 	if (ret < 0)
804*4882a593Smuzhiyun 		goto error;
805*4882a593Smuzhiyun 
806*4882a593Smuzhiyun 	/* creation of additional special files should go here */
807*4882a593Smuzhiyun 
808*4882a593Smuzhiyun 	dev_info(&interface->dev, "Line 6 %s now attached\n",
809*4882a593Smuzhiyun 		 properties->name);
810*4882a593Smuzhiyun 
811*4882a593Smuzhiyun 	return 0;
812*4882a593Smuzhiyun 
813*4882a593Smuzhiyun  error:
814*4882a593Smuzhiyun 	/* we can call disconnect callback here because no close-sync is
815*4882a593Smuzhiyun 	 * needed yet at this point
816*4882a593Smuzhiyun 	 */
817*4882a593Smuzhiyun 	line6_disconnect(interface);
818*4882a593Smuzhiyun 	return ret;
819*4882a593Smuzhiyun }
820*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(line6_probe);
821*4882a593Smuzhiyun 
822*4882a593Smuzhiyun /*
823*4882a593Smuzhiyun 	Line 6 device disconnected.
824*4882a593Smuzhiyun */
line6_disconnect(struct usb_interface * interface)825*4882a593Smuzhiyun void line6_disconnect(struct usb_interface *interface)
826*4882a593Smuzhiyun {
827*4882a593Smuzhiyun 	struct usb_line6 *line6 = usb_get_intfdata(interface);
828*4882a593Smuzhiyun 	struct usb_device *usbdev = interface_to_usbdev(interface);
829*4882a593Smuzhiyun 
830*4882a593Smuzhiyun 	if (!line6)
831*4882a593Smuzhiyun 		return;
832*4882a593Smuzhiyun 
833*4882a593Smuzhiyun 	if (WARN_ON(usbdev != line6->usbdev))
834*4882a593Smuzhiyun 		return;
835*4882a593Smuzhiyun 
836*4882a593Smuzhiyun 	cancel_delayed_work_sync(&line6->startup_work);
837*4882a593Smuzhiyun 
838*4882a593Smuzhiyun 	if (line6->urb_listen != NULL)
839*4882a593Smuzhiyun 		line6_stop_listen(line6);
840*4882a593Smuzhiyun 
841*4882a593Smuzhiyun 	snd_card_disconnect(line6->card);
842*4882a593Smuzhiyun 	if (line6->line6pcm)
843*4882a593Smuzhiyun 		line6_pcm_disconnect(line6->line6pcm);
844*4882a593Smuzhiyun 	if (line6->disconnect)
845*4882a593Smuzhiyun 		line6->disconnect(line6);
846*4882a593Smuzhiyun 
847*4882a593Smuzhiyun 	dev_info(&interface->dev, "Line 6 %s now disconnected\n",
848*4882a593Smuzhiyun 		 line6->properties->name);
849*4882a593Smuzhiyun 
850*4882a593Smuzhiyun 	/* make sure the device isn't destructed twice: */
851*4882a593Smuzhiyun 	usb_set_intfdata(interface, NULL);
852*4882a593Smuzhiyun 
853*4882a593Smuzhiyun 	snd_card_free_when_closed(line6->card);
854*4882a593Smuzhiyun }
855*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(line6_disconnect);
856*4882a593Smuzhiyun 
857*4882a593Smuzhiyun #ifdef CONFIG_PM
858*4882a593Smuzhiyun 
859*4882a593Smuzhiyun /*
860*4882a593Smuzhiyun 	Suspend Line 6 device.
861*4882a593Smuzhiyun */
line6_suspend(struct usb_interface * interface,pm_message_t message)862*4882a593Smuzhiyun int line6_suspend(struct usb_interface *interface, pm_message_t message)
863*4882a593Smuzhiyun {
864*4882a593Smuzhiyun 	struct usb_line6 *line6 = usb_get_intfdata(interface);
865*4882a593Smuzhiyun 	struct snd_line6_pcm *line6pcm = line6->line6pcm;
866*4882a593Smuzhiyun 
867*4882a593Smuzhiyun 	snd_power_change_state(line6->card, SNDRV_CTL_POWER_D3hot);
868*4882a593Smuzhiyun 
869*4882a593Smuzhiyun 	if (line6->properties->capabilities & LINE6_CAP_CONTROL)
870*4882a593Smuzhiyun 		line6_stop_listen(line6);
871*4882a593Smuzhiyun 
872*4882a593Smuzhiyun 	if (line6pcm != NULL)
873*4882a593Smuzhiyun 		line6pcm->flags = 0;
874*4882a593Smuzhiyun 
875*4882a593Smuzhiyun 	return 0;
876*4882a593Smuzhiyun }
877*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(line6_suspend);
878*4882a593Smuzhiyun 
879*4882a593Smuzhiyun /*
880*4882a593Smuzhiyun 	Resume Line 6 device.
881*4882a593Smuzhiyun */
line6_resume(struct usb_interface * interface)882*4882a593Smuzhiyun int line6_resume(struct usb_interface *interface)
883*4882a593Smuzhiyun {
884*4882a593Smuzhiyun 	struct usb_line6 *line6 = usb_get_intfdata(interface);
885*4882a593Smuzhiyun 
886*4882a593Smuzhiyun 	if (line6->properties->capabilities & LINE6_CAP_CONTROL)
887*4882a593Smuzhiyun 		line6_start_listen(line6);
888*4882a593Smuzhiyun 
889*4882a593Smuzhiyun 	snd_power_change_state(line6->card, SNDRV_CTL_POWER_D0);
890*4882a593Smuzhiyun 	return 0;
891*4882a593Smuzhiyun }
892*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(line6_resume);
893*4882a593Smuzhiyun 
894*4882a593Smuzhiyun #endif /* CONFIG_PM */
895*4882a593Smuzhiyun 
896*4882a593Smuzhiyun MODULE_AUTHOR(DRIVER_AUTHOR);
897*4882a593Smuzhiyun MODULE_DESCRIPTION(DRIVER_DESC);
898*4882a593Smuzhiyun MODULE_LICENSE("GPL");
899*4882a593Smuzhiyun 
900