aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/usb/line6/Kconfig2
-rw-r--r--sound/usb/line6/toneport.c163
2 files changed, 91 insertions, 74 deletions
diff --git a/sound/usb/line6/Kconfig b/sound/usb/line6/Kconfig
index af20947e0bda..f4585d378ef3 100644
--- a/sound/usb/line6/Kconfig
+++ b/sound/usb/line6/Kconfig
@@ -29,6 +29,8 @@ config SND_USB_PODHD
29config SND_USB_TONEPORT 29config SND_USB_TONEPORT
30 tristate "TonePort GX, UX1 and UX2 USB support" 30 tristate "TonePort GX, UX1 and UX2 USB support"
31 select SND_USB_LINE6 31 select SND_USB_LINE6
32 select NEW_LEDS
33 select LEDS_CLASS
32 help 34 help
33 This is a driver for TonePort GX, UX1 and UX2 devices. 35 This is a driver for TonePort GX, UX1 and UX2 devices.
34 36
diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c
index 9a4f5403569e..9a769463f7bf 100644
--- a/sound/usb/line6/toneport.c
+++ b/sound/usb/line6/toneport.c
@@ -14,6 +14,7 @@
14#include <linux/usb.h> 14#include <linux/usb.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/leds.h>
17#include <sound/core.h> 18#include <sound/core.h>
18#include <sound/control.h> 19#include <sound/control.h>
19 20
@@ -32,6 +33,15 @@ enum line6_device_type {
32 LINE6_TONEPORT_UX2, 33 LINE6_TONEPORT_UX2,
33}; 34};
34 35
36struct usb_line6_toneport;
37
38struct toneport_led {
39 struct led_classdev dev;
40 char name[64];
41 struct usb_line6_toneport *toneport;
42 bool registered;
43};
44
35struct usb_line6_toneport { 45struct usb_line6_toneport {
36 /** 46 /**
37 Generic Line 6 USB data. 47 Generic Line 6 USB data.
@@ -62,6 +72,9 @@ struct usb_line6_toneport {
62 Device type. 72 Device type.
63 */ 73 */
64 enum line6_device_type type; 74 enum line6_device_type type;
75
76 /* LED instances */
77 struct toneport_led leds[2];
65}; 78};
66 79
67static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2); 80static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2);
@@ -117,15 +130,6 @@ static struct line6_pcm_properties toneport_pcm_properties = {
117 .bytes_per_frame = 4 130 .bytes_per_frame = 4
118}; 131};
119 132
120/*
121 For the led on Guitarport.
122 Brightness goes from 0x00 to 0x26. Set a value above this to have led
123 blink.
124 (void cmd_0x02(byte red, byte green)
125*/
126static int led_red = 0x00;
127static int led_green = 0x26;
128
129static const struct { 133static const struct {
130 const char *name; 134 const char *name;
131 int code; 135 int code;
@@ -136,62 +140,6 @@ static const struct {
136 {"Inst & Mic", 0x0901} 140 {"Inst & Mic", 0x0901}
137}; 141};
138 142
139static bool toneport_has_led(enum line6_device_type type)
140{
141 return
142 (type == LINE6_GUITARPORT) ||
143 (type == LINE6_TONEPORT_GX);
144 /* add your device here if you are missing support for the LEDs */
145}
146
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;
152
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);
160}
161
162static ssize_t toneport_set_led_red(struct device *dev,
163 struct device_attribute *attr,
164 const char *buf, size_t count)
165{
166 int retval;
167
168 retval = kstrtoint(buf, 10, &led_red);
169 if (retval)
170 return retval;
171
172 toneport_update_led(dev);
173 return count;
174}
175
176static ssize_t toneport_set_led_green(struct device *dev,
177 struct device_attribute *attr,
178 const char *buf, size_t count)
179{
180 int retval;
181
182 retval = kstrtoint(buf, 10, &led_green);
183 if (retval)
184 return retval;
185
186 toneport_update_led(dev);
187 return count;
188}
189
190static DEVICE_ATTR(led_red, S_IWUSR | S_IRUGO, line6_nop_read,
191 toneport_set_led_red);
192static DEVICE_ATTR(led_green, S_IWUSR | S_IRUGO, line6_nop_read,
193 toneport_set_led_green);
194
195static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2) 143static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
196{ 144{
197 int ret; 145 int ret;
@@ -330,6 +278,78 @@ static struct snd_kcontrol_new toneport_control_source = {
330}; 278};
331 279
332/* 280/*
281 For the led on Guitarport.
282 Brightness goes from 0x00 to 0x26. Set a value above this to have led
283 blink.
284 (void cmd_0x02(byte red, byte green)
285*/
286
287static bool toneport_has_led(enum line6_device_type type)
288{
289 return
290 (type == LINE6_GUITARPORT) ||
291 (type == LINE6_TONEPORT_GX);
292 /* add your device here if you are missing support for the LEDs */
293}
294
295static const char * const led_colors[2] = { "red", "green" };
296static const int led_init_vals[2] = { 0x00, 0x26 };
297
298static void toneport_update_led(struct usb_line6_toneport *toneport)
299{
300 toneport_send_cmd(toneport->line6.usbdev,
301 (toneport->leds[0].dev.brightness << 8) | 0x0002,
302 toneport->leds[1].dev.brightness);
303}
304
305static void toneport_led_brightness_set(struct led_classdev *led_cdev,
306 enum led_brightness brightness)
307{
308 struct toneport_led *leds =
309 container_of(led_cdev, struct toneport_led, dev);
310 toneport_update_led(leds->toneport);
311}
312
313static int toneport_init_leds(struct usb_line6_toneport *toneport)
314{
315 struct device *dev = &toneport->line6.usbdev->dev;
316 int i, err;
317
318 for (i = 0; i < 2; i++) {
319 struct toneport_led *led = &toneport->leds[i];
320 struct led_classdev *leddev = &led->dev;
321
322 led->toneport = toneport;
323 snprintf(led->name, sizeof(led->name), "%s::%s",
324 dev_name(dev), led_colors[i]);
325 leddev->name = led->name;
326 leddev->brightness = led_init_vals[i];
327 leddev->max_brightness = 0x26;
328 leddev->brightness_set = toneport_led_brightness_set;
329 err = led_classdev_register(dev, leddev);
330 if (err)
331 return err;
332 led->registered = true;
333 }
334
335 return 0;
336}
337
338static void toneport_remove_leds(struct usb_line6_toneport *toneport)
339{
340 struct toneport_led *led;
341 int i;
342
343 for (i = 0; i < 2; i++) {
344 led = &toneport->leds[i];
345 if (!led->registered)
346 break;
347 led_classdev_unregister(&led->dev);
348 led->registered = false;
349 }
350}
351
352/*
333 Setup Toneport device. 353 Setup Toneport device.
334*/ 354*/
335static void toneport_setup(struct usb_line6_toneport *toneport) 355static void toneport_setup(struct usb_line6_toneport *toneport)
@@ -359,7 +379,7 @@ static void toneport_setup(struct usb_line6_toneport *toneport)
359 } 379 }
360 380
361 if (toneport_has_led(toneport->type)) 381 if (toneport_has_led(toneport->type))
362 toneport_update_led(&usbdev->dev); 382 toneport_update_led(toneport);
363 383
364 mod_timer(&toneport->timer, jiffies + TONEPORT_PCM_DELAY * HZ); 384 mod_timer(&toneport->timer, jiffies + TONEPORT_PCM_DELAY * HZ);
365} 385}
@@ -374,10 +394,8 @@ static void line6_toneport_disconnect(struct usb_interface *interface)
374 toneport = usb_get_intfdata(interface); 394 toneport = usb_get_intfdata(interface);
375 del_timer_sync(&toneport->timer); 395 del_timer_sync(&toneport->timer);
376 396
377 if (toneport_has_led(toneport->type)) { 397 if (toneport_has_led(toneport->type))
378 device_remove_file(&interface->dev, &dev_attr_led_red); 398 toneport_remove_leds(toneport);
379 device_remove_file(&interface->dev, &dev_attr_led_green);
380 }
381} 399}
382 400
383 401
@@ -428,10 +446,7 @@ static int toneport_init(struct usb_interface *interface,
428 line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1); 446 line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1);
429 447
430 if (toneport_has_led(toneport->type)) { 448 if (toneport_has_led(toneport->type)) {
431 err = device_create_file(&interface->dev, &dev_attr_led_red); 449 err = toneport_init_leds(toneport);
432 if (err < 0)
433 return err;
434 err = device_create_file(&interface->dev, &dev_attr_led_green);
435 if (err < 0) 450 if (err < 0)
436 return err; 451 return err;
437 } 452 }