xref: /openbmc/linux/sound/usb/line6/toneport.c (revision 61864d844c296933d40c02683252bbea5193b101)
1*61864d84STakashi Iwai /*
2*61864d84STakashi Iwai  * Line6 Linux USB driver - 0.9.1beta
3*61864d84STakashi Iwai  *
4*61864d84STakashi Iwai  * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
5*61864d84STakashi Iwai  *                         Emil Myhrman (emil.myhrman@gmail.com)
6*61864d84STakashi Iwai  *
7*61864d84STakashi Iwai  *	This program is free software; you can redistribute it and/or
8*61864d84STakashi Iwai  *	modify it under the terms of the GNU General Public License as
9*61864d84STakashi Iwai  *	published by the Free Software Foundation, version 2.
10*61864d84STakashi Iwai  *
11*61864d84STakashi Iwai  */
12*61864d84STakashi Iwai 
13*61864d84STakashi Iwai #include <linux/wait.h>
14*61864d84STakashi Iwai #include <sound/control.h>
15*61864d84STakashi Iwai 
16*61864d84STakashi Iwai #include "audio.h"
17*61864d84STakashi Iwai #include "capture.h"
18*61864d84STakashi Iwai #include "driver.h"
19*61864d84STakashi Iwai #include "playback.h"
20*61864d84STakashi Iwai #include "toneport.h"
21*61864d84STakashi Iwai 
22*61864d84STakashi Iwai static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2);
23*61864d84STakashi Iwai 
24*61864d84STakashi Iwai #define TONEPORT_PCM_DELAY 1
25*61864d84STakashi Iwai 
26*61864d84STakashi Iwai static struct snd_ratden toneport_ratden = {
27*61864d84STakashi Iwai 	.num_min = 44100,
28*61864d84STakashi Iwai 	.num_max = 44100,
29*61864d84STakashi Iwai 	.num_step = 1,
30*61864d84STakashi Iwai 	.den = 1
31*61864d84STakashi Iwai };
32*61864d84STakashi Iwai 
33*61864d84STakashi Iwai static struct line6_pcm_properties toneport_pcm_properties = {
34*61864d84STakashi Iwai 	.snd_line6_playback_hw = {
35*61864d84STakashi Iwai 				  .info = (SNDRV_PCM_INFO_MMAP |
36*61864d84STakashi Iwai 					   SNDRV_PCM_INFO_INTERLEAVED |
37*61864d84STakashi Iwai 					   SNDRV_PCM_INFO_BLOCK_TRANSFER |
38*61864d84STakashi Iwai 					   SNDRV_PCM_INFO_MMAP_VALID |
39*61864d84STakashi Iwai 					   SNDRV_PCM_INFO_PAUSE |
40*61864d84STakashi Iwai #ifdef CONFIG_PM
41*61864d84STakashi Iwai 					   SNDRV_PCM_INFO_RESUME |
42*61864d84STakashi Iwai #endif
43*61864d84STakashi Iwai 					   SNDRV_PCM_INFO_SYNC_START),
44*61864d84STakashi Iwai 				  .formats = SNDRV_PCM_FMTBIT_S16_LE,
45*61864d84STakashi Iwai 				  .rates = SNDRV_PCM_RATE_KNOT,
46*61864d84STakashi Iwai 				  .rate_min = 44100,
47*61864d84STakashi Iwai 				  .rate_max = 44100,
48*61864d84STakashi Iwai 				  .channels_min = 2,
49*61864d84STakashi Iwai 				  .channels_max = 2,
50*61864d84STakashi Iwai 				  .buffer_bytes_max = 60000,
51*61864d84STakashi Iwai 				  .period_bytes_min = 64,
52*61864d84STakashi Iwai 				  .period_bytes_max = 8192,
53*61864d84STakashi Iwai 				  .periods_min = 1,
54*61864d84STakashi Iwai 				  .periods_max = 1024},
55*61864d84STakashi Iwai 	.snd_line6_capture_hw = {
56*61864d84STakashi Iwai 				 .info = (SNDRV_PCM_INFO_MMAP |
57*61864d84STakashi Iwai 					  SNDRV_PCM_INFO_INTERLEAVED |
58*61864d84STakashi Iwai 					  SNDRV_PCM_INFO_BLOCK_TRANSFER |
59*61864d84STakashi Iwai 					  SNDRV_PCM_INFO_MMAP_VALID |
60*61864d84STakashi Iwai #ifdef CONFIG_PM
61*61864d84STakashi Iwai 					  SNDRV_PCM_INFO_RESUME |
62*61864d84STakashi Iwai #endif
63*61864d84STakashi Iwai 					  SNDRV_PCM_INFO_SYNC_START),
64*61864d84STakashi Iwai 				 .formats = SNDRV_PCM_FMTBIT_S16_LE,
65*61864d84STakashi Iwai 				 .rates = SNDRV_PCM_RATE_KNOT,
66*61864d84STakashi Iwai 				 .rate_min = 44100,
67*61864d84STakashi Iwai 				 .rate_max = 44100,
68*61864d84STakashi Iwai 				 .channels_min = 2,
69*61864d84STakashi Iwai 				 .channels_max = 2,
70*61864d84STakashi Iwai 				 .buffer_bytes_max = 60000,
71*61864d84STakashi Iwai 				 .period_bytes_min = 64,
72*61864d84STakashi Iwai 				 .period_bytes_max = 8192,
73*61864d84STakashi Iwai 				 .periods_min = 1,
74*61864d84STakashi Iwai 				 .periods_max = 1024},
75*61864d84STakashi Iwai 	.snd_line6_rates = {
76*61864d84STakashi Iwai 			    .nrats = 1,
77*61864d84STakashi Iwai 			    .rats = &toneport_ratden},
78*61864d84STakashi Iwai 	.bytes_per_frame = 4
79*61864d84STakashi Iwai };
80*61864d84STakashi Iwai 
81*61864d84STakashi Iwai /*
82*61864d84STakashi Iwai 	For the led on Guitarport.
83*61864d84STakashi Iwai 	Brightness goes from 0x00 to 0x26. Set a value above this to have led
84*61864d84STakashi Iwai 	blink.
85*61864d84STakashi Iwai 	(void cmd_0x02(byte red, byte green)
86*61864d84STakashi Iwai */
87*61864d84STakashi Iwai static int led_red = 0x00;
88*61864d84STakashi Iwai static int led_green = 0x26;
89*61864d84STakashi Iwai 
90*61864d84STakashi Iwai static const struct {
91*61864d84STakashi Iwai 	const char *name;
92*61864d84STakashi Iwai 	int code;
93*61864d84STakashi Iwai } toneport_source_info[] = {
94*61864d84STakashi Iwai 	{"Microphone", 0x0a01},
95*61864d84STakashi Iwai 	{"Line", 0x0801},
96*61864d84STakashi Iwai 	{"Instrument", 0x0b01},
97*61864d84STakashi Iwai 	{"Inst & Mic", 0x0901}
98*61864d84STakashi Iwai };
99*61864d84STakashi Iwai 
100*61864d84STakashi Iwai static bool toneport_has_led(enum line6_device_type type)
101*61864d84STakashi Iwai {
102*61864d84STakashi Iwai 	return
103*61864d84STakashi Iwai 	    (type == LINE6_GUITARPORT) ||
104*61864d84STakashi Iwai 	    (type == LINE6_TONEPORT_GX);
105*61864d84STakashi Iwai 	/* add your device here if you are missing support for the LEDs */
106*61864d84STakashi Iwai }
107*61864d84STakashi Iwai 
108*61864d84STakashi Iwai static void toneport_update_led(struct device *dev)
109*61864d84STakashi Iwai {
110*61864d84STakashi Iwai 	struct usb_interface *interface = to_usb_interface(dev);
111*61864d84STakashi Iwai 	struct usb_line6_toneport *tp = usb_get_intfdata(interface);
112*61864d84STakashi Iwai 	struct usb_line6 *line6;
113*61864d84STakashi Iwai 
114*61864d84STakashi Iwai 	if (!tp)
115*61864d84STakashi Iwai 		return;
116*61864d84STakashi Iwai 
117*61864d84STakashi Iwai 	line6 = &tp->line6;
118*61864d84STakashi Iwai 	if (line6)
119*61864d84STakashi Iwai 		toneport_send_cmd(line6->usbdev, (led_red << 8) | 0x0002,
120*61864d84STakashi Iwai 				  led_green);
121*61864d84STakashi Iwai }
122*61864d84STakashi Iwai 
123*61864d84STakashi Iwai static ssize_t toneport_set_led_red(struct device *dev,
124*61864d84STakashi Iwai 				    struct device_attribute *attr,
125*61864d84STakashi Iwai 				    const char *buf, size_t count)
126*61864d84STakashi Iwai {
127*61864d84STakashi Iwai 	int retval;
128*61864d84STakashi Iwai 
129*61864d84STakashi Iwai 	retval = kstrtoint(buf, 10, &led_red);
130*61864d84STakashi Iwai 	if (retval)
131*61864d84STakashi Iwai 		return retval;
132*61864d84STakashi Iwai 
133*61864d84STakashi Iwai 	toneport_update_led(dev);
134*61864d84STakashi Iwai 	return count;
135*61864d84STakashi Iwai }
136*61864d84STakashi Iwai 
137*61864d84STakashi Iwai static ssize_t toneport_set_led_green(struct device *dev,
138*61864d84STakashi Iwai 				      struct device_attribute *attr,
139*61864d84STakashi Iwai 				      const char *buf, size_t count)
140*61864d84STakashi Iwai {
141*61864d84STakashi Iwai 	int retval;
142*61864d84STakashi Iwai 
143*61864d84STakashi Iwai 	retval = kstrtoint(buf, 10, &led_green);
144*61864d84STakashi Iwai 	if (retval)
145*61864d84STakashi Iwai 		return retval;
146*61864d84STakashi Iwai 
147*61864d84STakashi Iwai 	toneport_update_led(dev);
148*61864d84STakashi Iwai 	return count;
149*61864d84STakashi Iwai }
150*61864d84STakashi Iwai 
151*61864d84STakashi Iwai static DEVICE_ATTR(led_red, S_IWUSR | S_IRUGO, line6_nop_read,
152*61864d84STakashi Iwai 		   toneport_set_led_red);
153*61864d84STakashi Iwai static DEVICE_ATTR(led_green, S_IWUSR | S_IRUGO, line6_nop_read,
154*61864d84STakashi Iwai 		   toneport_set_led_green);
155*61864d84STakashi Iwai 
156*61864d84STakashi Iwai static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
157*61864d84STakashi Iwai {
158*61864d84STakashi Iwai 	int ret;
159*61864d84STakashi Iwai 
160*61864d84STakashi Iwai 	ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
161*61864d84STakashi Iwai 			      USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
162*61864d84STakashi Iwai 			      cmd1, cmd2, NULL, 0, LINE6_TIMEOUT * HZ);
163*61864d84STakashi Iwai 
164*61864d84STakashi Iwai 	if (ret < 0) {
165*61864d84STakashi Iwai 		dev_err(&usbdev->dev, "send failed (error %d)\n", ret);
166*61864d84STakashi Iwai 		return ret;
167*61864d84STakashi Iwai 	}
168*61864d84STakashi Iwai 
169*61864d84STakashi Iwai 	return 0;
170*61864d84STakashi Iwai }
171*61864d84STakashi Iwai 
172*61864d84STakashi Iwai /* monitor info callback */
173*61864d84STakashi Iwai static int snd_toneport_monitor_info(struct snd_kcontrol *kcontrol,
174*61864d84STakashi Iwai 				     struct snd_ctl_elem_info *uinfo)
175*61864d84STakashi Iwai {
176*61864d84STakashi Iwai 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
177*61864d84STakashi Iwai 	uinfo->count = 1;
178*61864d84STakashi Iwai 	uinfo->value.integer.min = 0;
179*61864d84STakashi Iwai 	uinfo->value.integer.max = 256;
180*61864d84STakashi Iwai 	return 0;
181*61864d84STakashi Iwai }
182*61864d84STakashi Iwai 
183*61864d84STakashi Iwai /* monitor get callback */
184*61864d84STakashi Iwai static int snd_toneport_monitor_get(struct snd_kcontrol *kcontrol,
185*61864d84STakashi Iwai 				    struct snd_ctl_elem_value *ucontrol)
186*61864d84STakashi Iwai {
187*61864d84STakashi Iwai 	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
188*61864d84STakashi Iwai 
189*61864d84STakashi Iwai 	ucontrol->value.integer.value[0] = line6pcm->volume_monitor;
190*61864d84STakashi Iwai 	return 0;
191*61864d84STakashi Iwai }
192*61864d84STakashi Iwai 
193*61864d84STakashi Iwai /* monitor put callback */
194*61864d84STakashi Iwai static int snd_toneport_monitor_put(struct snd_kcontrol *kcontrol,
195*61864d84STakashi Iwai 				    struct snd_ctl_elem_value *ucontrol)
196*61864d84STakashi Iwai {
197*61864d84STakashi Iwai 	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
198*61864d84STakashi Iwai 
199*61864d84STakashi Iwai 	if (ucontrol->value.integer.value[0] == line6pcm->volume_monitor)
200*61864d84STakashi Iwai 		return 0;
201*61864d84STakashi Iwai 
202*61864d84STakashi Iwai 	line6pcm->volume_monitor = ucontrol->value.integer.value[0];
203*61864d84STakashi Iwai 
204*61864d84STakashi Iwai 	if (line6pcm->volume_monitor > 0)
205*61864d84STakashi Iwai 		line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_MONITOR);
206*61864d84STakashi Iwai 	else
207*61864d84STakashi Iwai 		line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR);
208*61864d84STakashi Iwai 
209*61864d84STakashi Iwai 	return 1;
210*61864d84STakashi Iwai }
211*61864d84STakashi Iwai 
212*61864d84STakashi Iwai /* source info callback */
213*61864d84STakashi Iwai static int snd_toneport_source_info(struct snd_kcontrol *kcontrol,
214*61864d84STakashi Iwai 				    struct snd_ctl_elem_info *uinfo)
215*61864d84STakashi Iwai {
216*61864d84STakashi Iwai 	const int size = ARRAY_SIZE(toneport_source_info);
217*61864d84STakashi Iwai 
218*61864d84STakashi Iwai 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
219*61864d84STakashi Iwai 	uinfo->count = 1;
220*61864d84STakashi Iwai 	uinfo->value.enumerated.items = size;
221*61864d84STakashi Iwai 
222*61864d84STakashi Iwai 	if (uinfo->value.enumerated.item >= size)
223*61864d84STakashi Iwai 		uinfo->value.enumerated.item = size - 1;
224*61864d84STakashi Iwai 
225*61864d84STakashi Iwai 	strcpy(uinfo->value.enumerated.name,
226*61864d84STakashi Iwai 	       toneport_source_info[uinfo->value.enumerated.item].name);
227*61864d84STakashi Iwai 
228*61864d84STakashi Iwai 	return 0;
229*61864d84STakashi Iwai }
230*61864d84STakashi Iwai 
231*61864d84STakashi Iwai /* source get callback */
232*61864d84STakashi Iwai static int snd_toneport_source_get(struct snd_kcontrol *kcontrol,
233*61864d84STakashi Iwai 				   struct snd_ctl_elem_value *ucontrol)
234*61864d84STakashi Iwai {
235*61864d84STakashi Iwai 	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
236*61864d84STakashi Iwai 	struct usb_line6_toneport *toneport =
237*61864d84STakashi Iwai 	    (struct usb_line6_toneport *)line6pcm->line6;
238*61864d84STakashi Iwai 	ucontrol->value.enumerated.item[0] = toneport->source;
239*61864d84STakashi Iwai 	return 0;
240*61864d84STakashi Iwai }
241*61864d84STakashi Iwai 
242*61864d84STakashi Iwai /* source put callback */
243*61864d84STakashi Iwai static int snd_toneport_source_put(struct snd_kcontrol *kcontrol,
244*61864d84STakashi Iwai 				   struct snd_ctl_elem_value *ucontrol)
245*61864d84STakashi Iwai {
246*61864d84STakashi Iwai 	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
247*61864d84STakashi Iwai 	struct usb_line6_toneport *toneport =
248*61864d84STakashi Iwai 	    (struct usb_line6_toneport *)line6pcm->line6;
249*61864d84STakashi Iwai 	unsigned int source;
250*61864d84STakashi Iwai 
251*61864d84STakashi Iwai 	source = ucontrol->value.enumerated.item[0];
252*61864d84STakashi Iwai 	if (source >= ARRAY_SIZE(toneport_source_info))
253*61864d84STakashi Iwai 		return -EINVAL;
254*61864d84STakashi Iwai 	if (source == toneport->source)
255*61864d84STakashi Iwai 		return 0;
256*61864d84STakashi Iwai 
257*61864d84STakashi Iwai 	toneport->source = source;
258*61864d84STakashi Iwai 	toneport_send_cmd(toneport->line6.usbdev,
259*61864d84STakashi Iwai 			  toneport_source_info[source].code, 0x0000);
260*61864d84STakashi Iwai 	return 1;
261*61864d84STakashi Iwai }
262*61864d84STakashi Iwai 
263*61864d84STakashi Iwai static void toneport_start_pcm(unsigned long arg)
264*61864d84STakashi Iwai {
265*61864d84STakashi Iwai 	struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)arg;
266*61864d84STakashi Iwai 	struct usb_line6 *line6 = &toneport->line6;
267*61864d84STakashi Iwai 
268*61864d84STakashi Iwai 	line6_pcm_acquire(line6->line6pcm, LINE6_BITS_PCM_MONITOR);
269*61864d84STakashi Iwai }
270*61864d84STakashi Iwai 
271*61864d84STakashi Iwai /* control definition */
272*61864d84STakashi Iwai static struct snd_kcontrol_new toneport_control_monitor = {
273*61864d84STakashi Iwai 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
274*61864d84STakashi Iwai 	.name = "Monitor Playback Volume",
275*61864d84STakashi Iwai 	.index = 0,
276*61864d84STakashi Iwai 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
277*61864d84STakashi Iwai 	.info = snd_toneport_monitor_info,
278*61864d84STakashi Iwai 	.get = snd_toneport_monitor_get,
279*61864d84STakashi Iwai 	.put = snd_toneport_monitor_put
280*61864d84STakashi Iwai };
281*61864d84STakashi Iwai 
282*61864d84STakashi Iwai /* source selector definition */
283*61864d84STakashi Iwai static struct snd_kcontrol_new toneport_control_source = {
284*61864d84STakashi Iwai 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
285*61864d84STakashi Iwai 	.name = "PCM Capture Source",
286*61864d84STakashi Iwai 	.index = 0,
287*61864d84STakashi Iwai 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
288*61864d84STakashi Iwai 	.info = snd_toneport_source_info,
289*61864d84STakashi Iwai 	.get = snd_toneport_source_get,
290*61864d84STakashi Iwai 	.put = snd_toneport_source_put
291*61864d84STakashi Iwai };
292*61864d84STakashi Iwai 
293*61864d84STakashi Iwai /*
294*61864d84STakashi Iwai 	Toneport destructor.
295*61864d84STakashi Iwai */
296*61864d84STakashi Iwai static void toneport_destruct(struct usb_interface *interface)
297*61864d84STakashi Iwai {
298*61864d84STakashi Iwai 	struct usb_line6_toneport *toneport = usb_get_intfdata(interface);
299*61864d84STakashi Iwai 
300*61864d84STakashi Iwai 	if (toneport == NULL)
301*61864d84STakashi Iwai 		return;
302*61864d84STakashi Iwai 	line6_cleanup_audio(&toneport->line6);
303*61864d84STakashi Iwai }
304*61864d84STakashi Iwai 
305*61864d84STakashi Iwai /*
306*61864d84STakashi Iwai 	Setup Toneport device.
307*61864d84STakashi Iwai */
308*61864d84STakashi Iwai static void toneport_setup(struct usb_line6_toneport *toneport)
309*61864d84STakashi Iwai {
310*61864d84STakashi Iwai 	int ticks;
311*61864d84STakashi Iwai 	struct usb_line6 *line6 = &toneport->line6;
312*61864d84STakashi Iwai 	struct usb_device *usbdev = line6->usbdev;
313*61864d84STakashi Iwai 
314*61864d84STakashi Iwai 	/* sync time on device with host: */
315*61864d84STakashi Iwai 	ticks = (int)get_seconds();
316*61864d84STakashi Iwai 	line6_write_data(line6, 0x80c6, &ticks, 4);
317*61864d84STakashi Iwai 
318*61864d84STakashi Iwai 	/* enable device: */
319*61864d84STakashi Iwai 	toneport_send_cmd(usbdev, 0x0301, 0x0000);
320*61864d84STakashi Iwai 
321*61864d84STakashi Iwai 	/* initialize source select: */
322*61864d84STakashi Iwai 	switch (line6->type) {
323*61864d84STakashi Iwai 	case LINE6_TONEPORT_UX1:
324*61864d84STakashi Iwai 	case LINE6_TONEPORT_UX2:
325*61864d84STakashi Iwai 	case LINE6_PODSTUDIO_UX1:
326*61864d84STakashi Iwai 	case LINE6_PODSTUDIO_UX2:
327*61864d84STakashi Iwai 		toneport_send_cmd(usbdev,
328*61864d84STakashi Iwai 				  toneport_source_info[toneport->source].code,
329*61864d84STakashi Iwai 				  0x0000);
330*61864d84STakashi Iwai 	default:
331*61864d84STakashi Iwai 		break;
332*61864d84STakashi Iwai 	}
333*61864d84STakashi Iwai 
334*61864d84STakashi Iwai 	if (toneport_has_led(line6->type))
335*61864d84STakashi Iwai 		toneport_update_led(&usbdev->dev);
336*61864d84STakashi Iwai }
337*61864d84STakashi Iwai 
338*61864d84STakashi Iwai /*
339*61864d84STakashi Iwai 	Toneport device disconnected.
340*61864d84STakashi Iwai */
341*61864d84STakashi Iwai static void line6_toneport_disconnect(struct usb_interface *interface)
342*61864d84STakashi Iwai {
343*61864d84STakashi Iwai 	struct usb_line6_toneport *toneport;
344*61864d84STakashi Iwai 	u16 idProduct;
345*61864d84STakashi Iwai 
346*61864d84STakashi Iwai 	if (interface == NULL)
347*61864d84STakashi Iwai 		return;
348*61864d84STakashi Iwai 
349*61864d84STakashi Iwai 	toneport = usb_get_intfdata(interface);
350*61864d84STakashi Iwai 	del_timer_sync(&toneport->timer);
351*61864d84STakashi Iwai 	idProduct = le16_to_cpu(toneport->line6.usbdev->descriptor.idProduct);
352*61864d84STakashi Iwai 
353*61864d84STakashi Iwai 	if (toneport_has_led(idProduct)) {
354*61864d84STakashi Iwai 		device_remove_file(&interface->dev, &dev_attr_led_red);
355*61864d84STakashi Iwai 		device_remove_file(&interface->dev, &dev_attr_led_green);
356*61864d84STakashi Iwai 	}
357*61864d84STakashi Iwai 
358*61864d84STakashi Iwai 	if (toneport != NULL) {
359*61864d84STakashi Iwai 		struct snd_line6_pcm *line6pcm = toneport->line6.line6pcm;
360*61864d84STakashi Iwai 
361*61864d84STakashi Iwai 		if (line6pcm != NULL) {
362*61864d84STakashi Iwai 			line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR);
363*61864d84STakashi Iwai 			line6_pcm_disconnect(line6pcm);
364*61864d84STakashi Iwai 		}
365*61864d84STakashi Iwai 	}
366*61864d84STakashi Iwai 
367*61864d84STakashi Iwai 	toneport_destruct(interface);
368*61864d84STakashi Iwai }
369*61864d84STakashi Iwai 
370*61864d84STakashi Iwai 
371*61864d84STakashi Iwai /*
372*61864d84STakashi Iwai 	 Try to init Toneport device.
373*61864d84STakashi Iwai */
374*61864d84STakashi Iwai static int toneport_try_init(struct usb_interface *interface,
375*61864d84STakashi Iwai 			     struct usb_line6 *line6)
376*61864d84STakashi Iwai {
377*61864d84STakashi Iwai 	int err;
378*61864d84STakashi Iwai 	struct usb_line6_toneport *toneport =  (struct usb_line6_toneport *) line6;
379*61864d84STakashi Iwai 
380*61864d84STakashi Iwai 	if ((interface == NULL) || (toneport == NULL))
381*61864d84STakashi Iwai 		return -ENODEV;
382*61864d84STakashi Iwai 
383*61864d84STakashi Iwai 	line6->disconnect = line6_toneport_disconnect;
384*61864d84STakashi Iwai 
385*61864d84STakashi Iwai 	/* initialize audio system: */
386*61864d84STakashi Iwai 	err = line6_init_audio(line6);
387*61864d84STakashi Iwai 	if (err < 0)
388*61864d84STakashi Iwai 		return err;
389*61864d84STakashi Iwai 
390*61864d84STakashi Iwai 	/* initialize PCM subsystem: */
391*61864d84STakashi Iwai 	err = line6_init_pcm(line6, &toneport_pcm_properties);
392*61864d84STakashi Iwai 	if (err < 0)
393*61864d84STakashi Iwai 		return err;
394*61864d84STakashi Iwai 
395*61864d84STakashi Iwai 	/* register monitor control: */
396*61864d84STakashi Iwai 	err = snd_ctl_add(line6->card,
397*61864d84STakashi Iwai 			  snd_ctl_new1(&toneport_control_monitor,
398*61864d84STakashi Iwai 				       line6->line6pcm));
399*61864d84STakashi Iwai 	if (err < 0)
400*61864d84STakashi Iwai 		return err;
401*61864d84STakashi Iwai 
402*61864d84STakashi Iwai 	/* register source select control: */
403*61864d84STakashi Iwai 	switch (line6->type) {
404*61864d84STakashi Iwai 	case LINE6_TONEPORT_UX1:
405*61864d84STakashi Iwai 	case LINE6_TONEPORT_UX2:
406*61864d84STakashi Iwai 	case LINE6_PODSTUDIO_UX1:
407*61864d84STakashi Iwai 	case LINE6_PODSTUDIO_UX2:
408*61864d84STakashi Iwai 		err =
409*61864d84STakashi Iwai 		    snd_ctl_add(line6->card,
410*61864d84STakashi Iwai 				snd_ctl_new1(&toneport_control_source,
411*61864d84STakashi Iwai 					     line6->line6pcm));
412*61864d84STakashi Iwai 		if (err < 0)
413*61864d84STakashi Iwai 			return err;
414*61864d84STakashi Iwai 
415*61864d84STakashi Iwai 	default:
416*61864d84STakashi Iwai 		break;
417*61864d84STakashi Iwai 	}
418*61864d84STakashi Iwai 
419*61864d84STakashi Iwai 	/* register audio system: */
420*61864d84STakashi Iwai 	err = line6_register_audio(line6);
421*61864d84STakashi Iwai 	if (err < 0)
422*61864d84STakashi Iwai 		return err;
423*61864d84STakashi Iwai 
424*61864d84STakashi Iwai 	line6_read_serial_number(line6, &toneport->serial_number);
425*61864d84STakashi Iwai 	line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1);
426*61864d84STakashi Iwai 
427*61864d84STakashi Iwai 	if (toneport_has_led(line6->type)) {
428*61864d84STakashi Iwai 		CHECK_RETURN(device_create_file
429*61864d84STakashi Iwai 			     (&interface->dev, &dev_attr_led_red));
430*61864d84STakashi Iwai 		CHECK_RETURN(device_create_file
431*61864d84STakashi Iwai 			     (&interface->dev, &dev_attr_led_green));
432*61864d84STakashi Iwai 	}
433*61864d84STakashi Iwai 
434*61864d84STakashi Iwai 	toneport_setup(toneport);
435*61864d84STakashi Iwai 
436*61864d84STakashi Iwai 	init_timer(&toneport->timer);
437*61864d84STakashi Iwai 	toneport->timer.expires = jiffies + TONEPORT_PCM_DELAY * HZ;
438*61864d84STakashi Iwai 	toneport->timer.function = toneport_start_pcm;
439*61864d84STakashi Iwai 	toneport->timer.data = (unsigned long)toneport;
440*61864d84STakashi Iwai 	add_timer(&toneport->timer);
441*61864d84STakashi Iwai 
442*61864d84STakashi Iwai 	return 0;
443*61864d84STakashi Iwai }
444*61864d84STakashi Iwai 
445*61864d84STakashi Iwai /*
446*61864d84STakashi Iwai 	 Init Toneport device (and clean up in case of failure).
447*61864d84STakashi Iwai */
448*61864d84STakashi Iwai int line6_toneport_init(struct usb_interface *interface,
449*61864d84STakashi Iwai 			struct usb_line6 *line6)
450*61864d84STakashi Iwai {
451*61864d84STakashi Iwai 	int err = toneport_try_init(interface, line6);
452*61864d84STakashi Iwai 
453*61864d84STakashi Iwai 	if (err < 0)
454*61864d84STakashi Iwai 		toneport_destruct(interface);
455*61864d84STakashi Iwai 
456*61864d84STakashi Iwai 	return err;
457*61864d84STakashi Iwai }
458*61864d84STakashi Iwai 
459*61864d84STakashi Iwai /*
460*61864d84STakashi Iwai 	Resume Toneport device after reset.
461*61864d84STakashi Iwai */
462*61864d84STakashi Iwai void line6_toneport_reset_resume(struct usb_line6_toneport *toneport)
463*61864d84STakashi Iwai {
464*61864d84STakashi Iwai 	toneport_setup(toneport);
465*61864d84STakashi Iwai }
466