ALSA: line6: Drop MISSING_CASE macro
[deliverable/linux.git] / sound / usb / line6 / toneport.c
CommitLineData
705ececd 1/*
e1a164d7 2 * Line6 Linux USB driver - 0.9.1beta
705ececd 3 *
1027f476 4 * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
705ececd
MG
5 * Emil Myhrman (emil.myhrman@gmail.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2.
10 *
11 */
12
1027f476 13#include <linux/wait.h>
ccddbe4a
TI
14#include <linux/usb.h>
15#include <linux/slab.h>
16#include <linux/module.h>
17#include <sound/core.h>
1027f476 18#include <sound/control.h>
705ececd 19
705ececd 20#include "capture.h"
1027f476 21#include "driver.h"
705ececd 22#include "playback.h"
ccddbe4a
TI
23#include "usbdefs.h"
24
25enum line6_device_type {
26 LINE6_GUITARPORT,
27 LINE6_PODSTUDIO_GX,
28 LINE6_PODSTUDIO_UX1,
29 LINE6_PODSTUDIO_UX2,
30 LINE6_TONEPORT_GX,
31 LINE6_TONEPORT_UX1,
32 LINE6_TONEPORT_UX2,
33};
34
35struct usb_line6_toneport {
36 /**
37 Generic Line6 USB data.
38 */
39 struct usb_line6 line6;
40
41 /**
42 Source selector.
43 */
44 int source;
45
46 /**
47 Serial number of device.
48 */
49 int serial_number;
50
51 /**
52 Firmware version (x 100).
53 */
54 int firmware_version;
55
56 /**
57 Timer for delayed PCM startup.
58 */
59 struct timer_list timer;
60
61 /**
62 Device type.
63 */
64 enum line6_device_type type;
65};
705ececd 66
705ececd
MG
67static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2);
68
1027f476
MG
69#define TONEPORT_PCM_DELAY 1
70
705ececd
MG
71static struct snd_ratden toneport_ratden = {
72 .num_min = 44100,
73 .num_max = 44100,
74 .num_step = 1,
75 .den = 1
76};
77
78static struct line6_pcm_properties toneport_pcm_properties = {
63a4a8ba 79 .snd_line6_playback_hw = {
e1a164d7
MG
80 .info = (SNDRV_PCM_INFO_MMAP |
81 SNDRV_PCM_INFO_INTERLEAVED |
82 SNDRV_PCM_INFO_BLOCK_TRANSFER |
83 SNDRV_PCM_INFO_MMAP_VALID |
84 SNDRV_PCM_INFO_PAUSE |
e1a164d7
MG
85 SNDRV_PCM_INFO_SYNC_START),
86 .formats = SNDRV_PCM_FMTBIT_S16_LE,
87 .rates = SNDRV_PCM_RATE_KNOT,
88 .rate_min = 44100,
89 .rate_max = 44100,
90 .channels_min = 2,
91 .channels_max = 2,
92 .buffer_bytes_max = 60000,
93 .period_bytes_min = 64,
94 .period_bytes_max = 8192,
95 .periods_min = 1,
96 .periods_max = 1024},
63a4a8ba 97 .snd_line6_capture_hw = {
e1a164d7
MG
98 .info = (SNDRV_PCM_INFO_MMAP |
99 SNDRV_PCM_INFO_INTERLEAVED |
100 SNDRV_PCM_INFO_BLOCK_TRANSFER |
101 SNDRV_PCM_INFO_MMAP_VALID |
e1a164d7
MG
102 SNDRV_PCM_INFO_SYNC_START),
103 .formats = SNDRV_PCM_FMTBIT_S16_LE,
104 .rates = SNDRV_PCM_RATE_KNOT,
105 .rate_min = 44100,
106 .rate_max = 44100,
107 .channels_min = 2,
108 .channels_max = 2,
109 .buffer_bytes_max = 60000,
110 .period_bytes_min = 64,
111 .period_bytes_max = 8192,
112 .periods_min = 1,
113 .periods_max = 1024},
705ececd 114 .snd_line6_rates = {
e1a164d7
MG
115 .nrats = 1,
116 .rats = &toneport_ratden},
705ececd
MG
117 .bytes_per_frame = 4
118};
119
120/*
121 For the led on Guitarport.
6353773b
GKH
122 Brightness goes from 0x00 to 0x26. Set a value above this to have led
123 blink.
705ececd
MG
124 (void cmd_0x02(byte red, byte green)
125*/
126static int led_red = 0x00;
127static int led_green = 0x26;
128
709b2fae 129static const struct {
1027f476
MG
130 const char *name;
131 int code;
709b2fae 132} toneport_source_info[] = {
e1a164d7
MG
133 {"Microphone", 0x0a01},
134 {"Line", 0x0801},
135 {"Instrument", 0x0b01},
136 {"Inst & Mic", 0x0901}
1027f476
MG
137};
138
a23a8bff 139static bool toneport_has_led(enum line6_device_type type)
1027f476
MG
140{
141 return
a23a8bff
CR
142 (type == LINE6_GUITARPORT) ||
143 (type == LINE6_TONEPORT_GX);
1027f476
MG
144 /* add your device here if you are missing support for the LEDs */
145}
146
6353773b
GKH
147static void toneport_update_led(struct device *dev)
148{
149 struct usb_interface *interface = to_usb_interface(dev);
150 struct usb_line6_toneport *tp = usb_get_intfdata(interface);
151 struct usb_line6 *line6;
705ececd 152
6353773b
GKH
153 if (!tp)
154 return;
155
156 line6 = &tp->line6;
157 if (line6)
158 toneport_send_cmd(line6->usbdev, (led_red << 8) | 0x0002,
159 led_green);
705ececd 160}
6353773b 161
77491e52
GKH
162static ssize_t toneport_set_led_red(struct device *dev,
163 struct device_attribute *attr,
6353773b
GKH
164 const char *buf, size_t count)
165{
bb950a16 166 int retval;
bb950a16 167
b07d9452 168 retval = kstrtoint(buf, 10, &led_red);
bb950a16
SB
169 if (retval)
170 return retval;
171
705ececd
MG
172 toneport_update_led(dev);
173 return count;
174}
6353773b 175
77491e52
GKH
176static ssize_t toneport_set_led_green(struct device *dev,
177 struct device_attribute *attr,
6353773b
GKH
178 const char *buf, size_t count)
179{
bb950a16 180 int retval;
bb950a16 181
b07d9452 182 retval = kstrtoint(buf, 10, &led_green);
bb950a16
SB
183 if (retval)
184 return retval;
185
705ececd
MG
186 toneport_update_led(dev);
187 return count;
188}
189
a3a972a0 190static DEVICE_ATTR(led_red, S_IWUSR | S_IRUGO, line6_nop_read,
63a4a8ba 191 toneport_set_led_red);
a3a972a0 192static DEVICE_ATTR(led_green, S_IWUSR | S_IRUGO, line6_nop_read,
63a4a8ba 193 toneport_set_led_green);
705ececd
MG
194
195static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
196{
197 int ret;
705ececd 198
6353773b
GKH
199 ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
200 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
201 cmd1, cmd2, NULL, 0, LINE6_TIMEOUT * HZ);
202
203 if (ret < 0) {
d86938fb 204 dev_err(&usbdev->dev, "send failed (error %d)\n", ret);
705ececd
MG
205 return ret;
206 }
207
208 return 0;
209}
210
1027f476
MG
211/* monitor info callback */
212static int snd_toneport_monitor_info(struct snd_kcontrol *kcontrol,
213 struct snd_ctl_elem_info *uinfo)
214{
215 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
216 uinfo->count = 1;
217 uinfo->value.integer.min = 0;
218 uinfo->value.integer.max = 256;
219 return 0;
220}
221
222/* monitor get callback */
223static int snd_toneport_monitor_get(struct snd_kcontrol *kcontrol,
224 struct snd_ctl_elem_value *ucontrol)
225{
226 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
f3c5261e 227
1027f476
MG
228 ucontrol->value.integer.value[0] = line6pcm->volume_monitor;
229 return 0;
230}
231
232/* monitor put callback */
233static int snd_toneport_monitor_put(struct snd_kcontrol *kcontrol,
234 struct snd_ctl_elem_value *ucontrol)
235{
236 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
237
e1a164d7 238 if (ucontrol->value.integer.value[0] == line6pcm->volume_monitor)
1027f476
MG
239 return 0;
240
241 line6pcm->volume_monitor = ucontrol->value.integer.value[0];
e1a164d7
MG
242
243 if (line6pcm->volume_monitor > 0)
0ca54888 244 line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_MONITOR);
e1a164d7 245 else
0ca54888 246 line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR);
e1a164d7 247
1027f476
MG
248 return 1;
249}
250
251/* source info callback */
252static int snd_toneport_source_info(struct snd_kcontrol *kcontrol,
253 struct snd_ctl_elem_info *uinfo)
254{
255 const int size = ARRAY_SIZE(toneport_source_info);
a6b4699d 256
1027f476
MG
257 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
258 uinfo->count = 1;
259 uinfo->value.enumerated.items = size;
260
e1a164d7 261 if (uinfo->value.enumerated.item >= size)
1027f476
MG
262 uinfo->value.enumerated.item = size - 1;
263
264 strcpy(uinfo->value.enumerated.name,
265 toneport_source_info[uinfo->value.enumerated.item].name);
266
267 return 0;
268}
269
270/* source get callback */
271static int snd_toneport_source_get(struct snd_kcontrol *kcontrol,
272 struct snd_ctl_elem_value *ucontrol)
273{
274 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
e1a164d7
MG
275 struct usb_line6_toneport *toneport =
276 (struct usb_line6_toneport *)line6pcm->line6;
1027f476
MG
277 ucontrol->value.enumerated.item[0] = toneport->source;
278 return 0;
279}
280
281/* source put callback */
282static int snd_toneport_source_put(struct snd_kcontrol *kcontrol,
283 struct snd_ctl_elem_value *ucontrol)
284{
285 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
e1a164d7
MG
286 struct usb_line6_toneport *toneport =
287 (struct usb_line6_toneport *)line6pcm->line6;
c3cb718a 288 unsigned int source;
1027f476 289
c3cb718a
DC
290 source = ucontrol->value.enumerated.item[0];
291 if (source >= ARRAY_SIZE(toneport_source_info))
292 return -EINVAL;
293 if (source == toneport->source)
1027f476
MG
294 return 0;
295
c3cb718a 296 toneport->source = source;
e1a164d7 297 toneport_send_cmd(toneport->line6.usbdev,
c3cb718a 298 toneport_source_info[source].code, 0x0000);
1027f476
MG
299 return 1;
300}
301
302static void toneport_start_pcm(unsigned long arg)
303{
304 struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)arg;
305 struct usb_line6 *line6 = &toneport->line6;
f3c5261e 306
0ca54888 307 line6_pcm_acquire(line6->line6pcm, LINE6_BITS_PCM_MONITOR);
1027f476
MG
308}
309
310/* control definition */
311static struct snd_kcontrol_new toneport_control_monitor = {
312 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
313 .name = "Monitor Playback Volume",
314 .index = 0,
315 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
316 .info = snd_toneport_monitor_info,
317 .get = snd_toneport_monitor_get,
318 .put = snd_toneport_monitor_put
319};
320
321/* source selector definition */
322static struct snd_kcontrol_new toneport_control_source = {
323 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
324 .name = "PCM Capture Source",
325 .index = 0,
326 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
327 .info = snd_toneport_source_info,
328 .get = snd_toneport_source_get,
329 .put = snd_toneport_source_put
330};
331
705ececd 332/*
1027f476 333 Setup Toneport device.
705ececd 334*/
1027f476 335static void toneport_setup(struct usb_line6_toneport *toneport)
705ececd 336{
1027f476 337 int ticks;
705ececd 338 struct usb_line6 *line6 = &toneport->line6;
1027f476
MG
339 struct usb_device *usbdev = line6->usbdev;
340
341 /* sync time on device with host: */
342 ticks = (int)get_seconds();
343 line6_write_data(line6, 0x80c6, &ticks, 4);
344
345 /* enable device: */
346 toneport_send_cmd(usbdev, 0x0301, 0x0000);
347
348 /* initialize source select: */
ccddbe4a 349 switch (toneport->type) {
a23a8bff
CR
350 case LINE6_TONEPORT_UX1:
351 case LINE6_TONEPORT_UX2:
352 case LINE6_PODSTUDIO_UX1:
353 case LINE6_PODSTUDIO_UX2:
e1a164d7
MG
354 toneport_send_cmd(usbdev,
355 toneport_source_info[toneport->source].code,
356 0x0000);
a23a8bff
CR
357 default:
358 break;
1027f476
MG
359 }
360
ccddbe4a 361 if (toneport_has_led(toneport->type))
1027f476
MG
362 toneport_update_led(&usbdev->dev);
363}
364
d29b854f
CR
365/*
366 Toneport device disconnected.
367*/
368static void line6_toneport_disconnect(struct usb_interface *interface)
369{
370 struct usb_line6_toneport *toneport;
371 u16 idProduct;
372
373 if (interface == NULL)
374 return;
375
376 toneport = usb_get_intfdata(interface);
377 del_timer_sync(&toneport->timer);
378 idProduct = le16_to_cpu(toneport->line6.usbdev->descriptor.idProduct);
379
380 if (toneport_has_led(idProduct)) {
381 device_remove_file(&interface->dev, &dev_attr_led_red);
382 device_remove_file(&interface->dev, &dev_attr_led_green);
383 }
d29b854f
CR
384}
385
386
1027f476
MG
387/*
388 Try to init Toneport device.
389*/
85a9339b
TI
390static int toneport_init(struct usb_interface *interface,
391 struct usb_line6 *line6)
1027f476
MG
392{
393 int err;
a221dd45 394 struct usb_line6_toneport *toneport = (struct usb_line6_toneport *) line6;
705ececd 395
6353773b 396 if ((interface == NULL) || (toneport == NULL))
705ececd
MG
397 return -ENODEV;
398
a46c4672
CR
399 line6->disconnect = line6_toneport_disconnect;
400
705ececd 401 /* initialize PCM subsystem: */
6353773b 402 err = line6_init_pcm(line6, &toneport_pcm_properties);
027360c5 403 if (err < 0)
705ececd 404 return err;
705ececd 405
1027f476 406 /* register monitor control: */
027360c5
GKH
407 err = snd_ctl_add(line6->card,
408 snd_ctl_new1(&toneport_control_monitor,
409 line6->line6pcm));
410 if (err < 0)
1027f476 411 return err;
1027f476
MG
412
413 /* register source select control: */
ccddbe4a 414 switch (toneport->type) {
a23a8bff
CR
415 case LINE6_TONEPORT_UX1:
416 case LINE6_TONEPORT_UX2:
417 case LINE6_PODSTUDIO_UX1:
418 case LINE6_PODSTUDIO_UX2:
e1a164d7
MG
419 err =
420 snd_ctl_add(line6->card,
421 snd_ctl_new1(&toneport_control_source,
422 line6->line6pcm));
027360c5 423 if (err < 0)
1027f476 424 return err;
a23a8bff
CR
425
426 default:
427 break;
1027f476
MG
428 }
429
705ececd
MG
430 line6_read_serial_number(line6, &toneport->serial_number);
431 line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1);
432
ccddbe4a 433 if (toneport_has_led(toneport->type)) {
e1a164d7
MG
434 CHECK_RETURN(device_create_file
435 (&interface->dev, &dev_attr_led_red));
436 CHECK_RETURN(device_create_file
437 (&interface->dev, &dev_attr_led_green));
1027f476 438 }
705ececd 439
1027f476 440 toneport_setup(toneport);
705ececd 441
0f2524b3
TI
442 setup_timer(&toneport->timer, toneport_start_pcm,
443 (unsigned long)toneport);
444 mod_timer(&toneport->timer, jiffies + TONEPORT_PCM_DELAY * HZ);
705ececd 445
85a9339b
TI
446 /* register audio system: */
447 return snd_card_register(line6->card);
1027f476
MG
448}
449
ccddbe4a 450#ifdef CONFIG_PM
1027f476
MG
451/*
452 Resume Toneport device after reset.
453*/
ccddbe4a 454static int toneport_reset_resume(struct usb_interface *interface)
1027f476 455{
ccddbe4a
TI
456 toneport_setup(usb_get_intfdata(interface));
457 return line6_resume(interface);
1027f476 458}
ccddbe4a
TI
459#endif
460
461#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
462#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
463
464/* table of devices that work with this driver */
465static const struct usb_device_id toneport_id_table[] = {
466 { LINE6_DEVICE(0x4750), .driver_info = LINE6_GUITARPORT },
467 { LINE6_DEVICE(0x4153), .driver_info = LINE6_PODSTUDIO_GX },
468 { LINE6_DEVICE(0x4150), .driver_info = LINE6_PODSTUDIO_UX1 },
469 { LINE6_IF_NUM(0x4151, 0), .driver_info = LINE6_PODSTUDIO_UX2 },
470 { LINE6_DEVICE(0x4147), .driver_info = LINE6_TONEPORT_GX },
471 { LINE6_DEVICE(0x4141), .driver_info = LINE6_TONEPORT_UX1 },
472 { LINE6_IF_NUM(0x4142, 0), .driver_info = LINE6_TONEPORT_UX2 },
473 {}
474};
475
476MODULE_DEVICE_TABLE(usb, toneport_id_table);
477
478static const struct line6_properties toneport_properties_table[] = {
479 [LINE6_GUITARPORT] = {
480 .id = "GuitarPort",
481 .name = "GuitarPort",
482 .capabilities = LINE6_CAP_PCM,
483 .altsetting = 2, /* 1..4 seem to be ok */
484 /* no control channel */
485 .ep_audio_r = 0x82,
486 .ep_audio_w = 0x01,
487 },
488 [LINE6_PODSTUDIO_GX] = {
489 .id = "PODStudioGX",
490 .name = "POD Studio GX",
491 .capabilities = LINE6_CAP_PCM,
492 .altsetting = 2, /* 1..4 seem to be ok */
493 /* no control channel */
494 .ep_audio_r = 0x82,
495 .ep_audio_w = 0x01,
496 },
497 [LINE6_PODSTUDIO_UX1] = {
498 .id = "PODStudioUX1",
499 .name = "POD Studio UX1",
500 .capabilities = LINE6_CAP_PCM,
501 .altsetting = 2, /* 1..4 seem to be ok */
502 /* no control channel */
503 .ep_audio_r = 0x82,
504 .ep_audio_w = 0x01,
505 },
506 [LINE6_PODSTUDIO_UX2] = {
507 .id = "PODStudioUX2",
508 .name = "POD Studio UX2",
509 .capabilities = LINE6_CAP_PCM,
510 .altsetting = 2, /* defaults to 44.1kHz, 16-bit */
511 /* no control channel */
512 .ep_audio_r = 0x82,
513 .ep_audio_w = 0x01,
514 },
515 [LINE6_TONEPORT_GX] = {
516 .id = "TonePortGX",
517 .name = "TonePort GX",
518 .capabilities = LINE6_CAP_PCM,
519 .altsetting = 2, /* 1..4 seem to be ok */
520 /* no control channel */
521 .ep_audio_r = 0x82,
522 .ep_audio_w = 0x01,
523 },
524 [LINE6_TONEPORT_UX1] = {
525 .id = "TonePortUX1",
526 .name = "TonePort UX1",
527 .capabilities = LINE6_CAP_PCM,
528 .altsetting = 2, /* 1..4 seem to be ok */
529 /* no control channel */
530 .ep_audio_r = 0x82,
531 .ep_audio_w = 0x01,
532 },
533 [LINE6_TONEPORT_UX2] = {
534 .id = "TonePortUX2",
535 .name = "TonePort UX2",
536 .capabilities = LINE6_CAP_PCM,
537 .altsetting = 2, /* defaults to 44.1kHz, 16-bit */
538 /* no control channel */
539 .ep_audio_r = 0x82,
540 .ep_audio_w = 0x01,
541 },
542};
543
544/*
545 Probe USB device.
546*/
547static int toneport_probe(struct usb_interface *interface,
548 const struct usb_device_id *id)
549{
550 struct usb_line6_toneport *toneport;
ccddbe4a
TI
551
552 toneport = kzalloc(sizeof(*toneport), GFP_KERNEL);
553 if (!toneport)
554 return -ENODEV;
555 toneport->type = id->driver_info;
85a9339b
TI
556 return line6_probe(interface, &toneport->line6,
557 &toneport_properties_table[id->driver_info],
558 toneport_init);
ccddbe4a
TI
559}
560
561static struct usb_driver toneport_driver = {
562 .name = KBUILD_MODNAME,
563 .probe = toneport_probe,
564 .disconnect = line6_disconnect,
565#ifdef CONFIG_PM
566 .suspend = line6_suspend,
567 .resume = line6_resume,
568 .reset_resume = toneport_reset_resume,
569#endif
570 .id_table = toneport_id_table,
571};
572
573module_usb_driver(toneport_driver);
574
575MODULE_DESCRIPTION("TonePort USB driver");
576MODULE_LICENSE("GPL");
This page took 0.518022 seconds and 5 git commands to generate.