aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorDaniel Mack <daniel@caiaq.de>2007-11-22 05:40:04 -0500
committerJaroslav Kysela <perex@perex.cz>2008-01-31 11:29:28 -0500
commit8e3cd08ed8e590952aa9a656758cb24d4ba898f8 (patch)
tree162fa11dcaff39a1f5e2fff6f7f03670321a558d /sound
parente5f73e2ae813aa216b480728548e5ffbebcc170a (diff)
[ALSA] caiaq - add control API and more input features
- added support for all input controllers on Native Instrument's 'Kore controller'. - added ALSA controls to switch LEDs on 'RigKontrol 2', 'RigKontrol3', 'Audio Kontrol 1' and 'Kore controller'. - added ALSA controls to switch input mode, software lock and ground lift features on 'Audio 8 DJ'. Signed-off-by: Daniel Mack <daniel@caiaq.de> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound')
-rw-r--r--sound/usb/Kconfig1
-rw-r--r--sound/usb/caiaq/Makefile2
-rw-r--r--sound/usb/caiaq/caiaq-audio.c2
-rw-r--r--sound/usb/caiaq/caiaq-control.c315
-rw-r--r--sound/usb/caiaq/caiaq-control.h6
-rw-r--r--sound/usb/caiaq/caiaq-device.c65
-rw-r--r--sound/usb/caiaq/caiaq-device.h11
-rw-r--r--sound/usb/caiaq/caiaq-input.c108
8 files changed, 482 insertions, 28 deletions
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 1c07c65c1cdd..ccbf72e1a479 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -58,6 +58,7 @@ config SND_USB_CAIAQ_INPUT
58 58
59 * Native Instruments RigKontrol2 59 * Native Instruments RigKontrol2
60 * Native Instruments RigKontrol3 60 * Native Instruments RigKontrol3
61 * Native Instruments Kore Controller
61 * Native Instruments Audio Kontrol 1 62 * Native Instruments Audio Kontrol 1
62 63
63endmenu 64endmenu
diff --git a/sound/usb/caiaq/Makefile b/sound/usb/caiaq/Makefile
index 455c8c58a1bd..345a965386a7 100644
--- a/sound/usb/caiaq/Makefile
+++ b/sound/usb/caiaq/Makefile
@@ -1,3 +1,3 @@
1snd-usb-caiaq-objs := caiaq-device.o caiaq-audio.o caiaq-midi.o caiaq-input.o 1snd-usb-caiaq-objs := caiaq-device.o caiaq-audio.o caiaq-midi.o caiaq-input.o caiaq-control.o
2 2
3obj-$(CONFIG_SND_USB_CAIAQ) += snd-usb-caiaq.o 3obj-$(CONFIG_SND_USB_CAIAQ) += snd-usb-caiaq.o
diff --git a/sound/usb/caiaq/caiaq-audio.c b/sound/usb/caiaq/caiaq-audio.c
index 0666908a2361..bf551c08c2ec 100644
--- a/sound/usb/caiaq/caiaq-audio.c
+++ b/sound/usb/caiaq/caiaq-audio.c
@@ -27,9 +27,7 @@
27#include <sound/initval.h> 27#include <sound/initval.h>
28#include <sound/pcm.h> 28#include <sound/pcm.h>
29#include <sound/rawmidi.h> 29#include <sound/rawmidi.h>
30#ifdef CONFIG_SND_USB_CAIAQ_INPUT
31#include <linux/input.h> 30#include <linux/input.h>
32#endif
33 31
34#include "caiaq-device.h" 32#include "caiaq-device.h"
35#include "caiaq-audio.h" 33#include "caiaq-audio.h"
diff --git a/sound/usb/caiaq/caiaq-control.c b/sound/usb/caiaq/caiaq-control.c
new file mode 100644
index 000000000000..14e8e32de925
--- /dev/null
+++ b/sound/usb/caiaq/caiaq-control.c
@@ -0,0 +1,315 @@
1/*
2 * Copyright (c) 2007 Daniel Mack
3 * friendly supported by NI.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <sound/driver.h>
21#include <linux/init.h>
22#include <linux/interrupt.h>
23#include <linux/usb.h>
24#include <sound/core.h>
25#include <sound/initval.h>
26#include <sound/pcm.h>
27#include <sound/rawmidi.h>
28#include <sound/control.h>
29#include <linux/input.h>
30
31#include "caiaq-device.h"
32#include "caiaq-control.h"
33
34#define CNT_INTVAL 0x10000
35
36static int control_info(struct snd_kcontrol *kcontrol,
37 struct snd_ctl_elem_info *uinfo)
38{
39 struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol);
40 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
41 int pos = kcontrol->private_value;
42 int is_intval = pos & CNT_INTVAL;
43
44 uinfo->count = 1;
45 pos &= ~CNT_INTVAL;
46
47 if (dev->chip.usb_id ==
48 USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ)
49 && (pos == 0)) {
50 /* current input mode of A8DJ */
51 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
52 uinfo->value.integer.min = 0;
53 uinfo->value.integer.max = 2;
54 return 0;
55 }
56
57 if (is_intval) {
58 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
59 uinfo->value.integer.min = 0;
60 uinfo->value.integer.max = 64;
61 } else {
62 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
63 uinfo->value.integer.min = 0;
64 uinfo->value.integer.max = 1;
65 }
66
67 return 0;
68}
69
70static int control_get(struct snd_kcontrol *kcontrol,
71 struct snd_ctl_elem_value *ucontrol)
72{
73 struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol);
74 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
75 int pos = kcontrol->private_value;
76
77 if (pos & CNT_INTVAL)
78 ucontrol->value.integer.value[0]
79 = dev->control_state[pos & ~CNT_INTVAL];
80 else
81 ucontrol->value.integer.value[0]
82 = !!(dev->control_state[pos / 8] & (1 << pos % 8));
83
84 return 0;
85}
86
87static int control_put(struct snd_kcontrol *kcontrol,
88 struct snd_ctl_elem_value *ucontrol)
89{
90 struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol);
91 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
92 int pos = kcontrol->private_value;
93
94 if (pos & CNT_INTVAL) {
95 dev->control_state[pos & ~CNT_INTVAL]
96 = ucontrol->value.integer.value[0];
97 snd_usb_caiaq_send_command(dev, EP1_CMD_DIMM_LEDS,
98 dev->control_state, sizeof(dev->control_state));
99 } else {
100 if (ucontrol->value.integer.value[0])
101 dev->control_state[pos / 8] |= 1 << (pos % 8);
102 else
103 dev->control_state[pos / 8] &= ~(1 << (pos % 8));
104
105 snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO,
106 dev->control_state, sizeof(dev->control_state));
107 }
108
109 return 1;
110}
111
112static struct snd_kcontrol_new kcontrol_template __devinitdata = {
113 .iface = SNDRV_CTL_ELEM_IFACE_HWDEP,
114 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
115 .index = 0,
116 .info = control_info,
117 .get = control_get,
118 .put = control_put,
119 /* name and private_value filled later */
120};
121
122struct caiaq_controller {
123 char *name;
124 int index;
125};
126
127static struct caiaq_controller ak1_controller[] = {
128 { "LED left", 2 },
129 { "LED middle", 1 },
130 { "LED right", 0 },
131 { "LED ring", 3 }
132};
133
134static struct caiaq_controller rk2_controller[] = {
135 { "LED 1", 5 },
136 { "LED 2", 4 },
137 { "LED 3", 3 },
138 { "LED 4", 2 },
139 { "LED 5", 1 },
140 { "LED 6", 0 },
141 { "LED pedal", 6 },
142 { "LED 7seg_1b", 8 },
143 { "LED 7seg_1c", 9 },
144 { "LED 7seg_2a", 10 },
145 { "LED 7seg_2b", 11 },
146 { "LED 7seg_2c", 12 },
147 { "LED 7seg_2d", 13 },
148 { "LED 7seg_2e", 14 },
149 { "LED 7seg_2f", 15 },
150 { "LED 7seg_2g", 16 },
151 { "LED 7seg_3a", 17 },
152 { "LED 7seg_3b", 18 },
153 { "LED 7seg_3c", 19 },
154 { "LED 7seg_3d", 20 },
155 { "LED 7seg_3e", 21 },
156 { "LED 7seg_3f", 22 },
157 { "LED 7seg_3g", 23 }
158};
159
160static struct caiaq_controller rk3_controller[] = {
161 { "LED 7seg_1a", 0 + 0 },
162 { "LED 7seg_1b", 0 + 1 },
163 { "LED 7seg_1c", 0 + 2 },
164 { "LED 7seg_1d", 0 + 3 },
165 { "LED 7seg_1e", 0 + 4 },
166 { "LED 7seg_1f", 0 + 5 },
167 { "LED 7seg_1g", 0 + 6 },
168 { "LED 7seg_1p", 0 + 7 },
169
170 { "LED 7seg_2a", 8 + 0 },
171 { "LED 7seg_2b", 8 + 1 },
172 { "LED 7seg_2c", 8 + 2 },
173 { "LED 7seg_2d", 8 + 3 },
174 { "LED 7seg_2e", 8 + 4 },
175 { "LED 7seg_2f", 8 + 5 },
176 { "LED 7seg_2g", 8 + 6 },
177 { "LED 7seg_2p", 8 + 7 },
178
179 { "LED 7seg_3a", 16 + 0 },
180 { "LED 7seg_3b", 16 + 1 },
181 { "LED 7seg_3c", 16 + 2 },
182 { "LED 7seg_3d", 16 + 3 },
183 { "LED 7seg_3e", 16 + 4 },
184 { "LED 7seg_3f", 16 + 5 },
185 { "LED 7seg_3g", 16 + 6 },
186 { "LED 7seg_3p", 16 + 7 },
187
188 { "LED 7seg_4a", 24 + 0 },
189 { "LED 7seg_4b", 24 + 1 },
190 { "LED 7seg_4c", 24 + 2 },
191 { "LED 7seg_4d", 24 + 3 },
192 { "LED 7seg_4e", 24 + 4 },
193 { "LED 7seg_4f", 24 + 5 },
194 { "LED 7seg_4g", 24 + 6 },
195 { "LED 7seg_4p", 24 + 7 },
196
197 { "LED 1", 32 + 0 },
198 { "LED 2", 32 + 1 },
199 { "LED 3", 32 + 2 },
200 { "LED 4", 32 + 3 },
201 { "LED 5", 32 + 4 },
202 { "LED 6", 32 + 5 },
203 { "LED 7", 32 + 6 },
204 { "LED 8", 32 + 7 },
205 { "LED pedal", 32 + 8 }
206};
207
208static struct caiaq_controller kore_controller[] = {
209 { "LED F1", 8 | CNT_INTVAL },
210 { "LED F2", 12 | CNT_INTVAL },
211 { "LED F3", 0 | CNT_INTVAL },
212 { "LED F4", 4 | CNT_INTVAL },
213 { "LED F5", 11 | CNT_INTVAL },
214 { "LED F6", 15 | CNT_INTVAL },
215 { "LED F7", 3 | CNT_INTVAL },
216 { "LED F8", 7 | CNT_INTVAL },
217 { "LED touch1", 10 | CNT_INTVAL },
218 { "LED touch2", 14 | CNT_INTVAL },
219 { "LED touch3", 2 | CNT_INTVAL },
220 { "LED touch4", 6 | CNT_INTVAL },
221 { "LED touch5", 9 | CNT_INTVAL },
222 { "LED touch6", 13 | CNT_INTVAL },
223 { "LED touch7", 1 | CNT_INTVAL },
224 { "LED touch8", 5 | CNT_INTVAL },
225 { "LED left", 18 | CNT_INTVAL },
226 { "LED right", 22 | CNT_INTVAL },
227 { "LED up", 16 | CNT_INTVAL },
228 { "LED down", 20 | CNT_INTVAL },
229 { "LED stop", 23 | CNT_INTVAL },
230 { "LED play", 21 | CNT_INTVAL },
231 { "LED record", 19 | CNT_INTVAL },
232 { "LED listen", 17 | CNT_INTVAL },
233 { "LED lcd", 30 | CNT_INTVAL },
234 { "LED menu", 28 | CNT_INTVAL },
235 { "LED sound", 31 | CNT_INTVAL },
236 { "LED esc", 29 | CNT_INTVAL },
237 { "LED view", 27 | CNT_INTVAL },
238 { "LED enter", 24 | CNT_INTVAL },
239 { "LED control", 26 | CNT_INTVAL }
240};
241
242static struct caiaq_controller a8dj_controller[] = {
243 { "Current input mode", 0 | CNT_INTVAL },
244 { "GND lift for TC Vinyl mode", 24 + 0 },
245 { "GND lift for TC CD/Line mode", 24 + 1 },
246 { "GND lift for phono mode", 24 + 2 },
247 { "GND lift for TC Vinyl mode", 24 + 3 },
248 { "Software lock", 40 }
249};
250
251int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev)
252{
253 int i;
254 struct snd_kcontrol *kc;
255
256 switch (dev->chip.usb_id) {
257 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
258 for (i = 0; i < ARRAY_SIZE(ak1_controller); i++) {
259 struct caiaq_controller *c = ak1_controller + i;
260 kcontrol_template.name = c->name;
261 kcontrol_template.private_value = c->index;
262 kc = snd_ctl_new1(&kcontrol_template, dev);
263 snd_ctl_add(dev->chip.card, kc);
264 }
265
266 break;
267
268 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
269 for (i = 0; i < ARRAY_SIZE(rk2_controller); i++) {
270 struct caiaq_controller *c = rk2_controller + i;
271 kcontrol_template.name = c->name;
272 kcontrol_template.private_value = c->index;
273 kc = snd_ctl_new1(&kcontrol_template, dev);
274 snd_ctl_add(dev->chip.card, kc);
275 }
276
277 break;
278
279 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
280 for (i = 0; i < ARRAY_SIZE(rk3_controller); i++) {
281 struct caiaq_controller *c = rk3_controller + i;
282 kcontrol_template.name = c->name;
283 kcontrol_template.private_value = c->index;
284 kc = snd_ctl_new1(&kcontrol_template, dev);
285 snd_ctl_add(dev->chip.card, kc);
286 }
287
288 break;
289
290 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
291 for (i = 0; i < ARRAY_SIZE(kore_controller); i++) {
292 struct caiaq_controller *c = kore_controller + i;
293 kcontrol_template.name = c->name;
294 kcontrol_template.private_value = c->index;
295 kc = snd_ctl_new1(&kcontrol_template, dev);
296 snd_ctl_add(dev->chip.card, kc);
297 }
298
299 break;
300
301 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
302 for (i = 0; i < ARRAY_SIZE(a8dj_controller); i++) {
303 struct caiaq_controller *c = a8dj_controller + i;
304 kcontrol_template.name = c->name;
305 kcontrol_template.private_value = c->index;
306 kc = snd_ctl_new1(&kcontrol_template, dev);
307 snd_ctl_add(dev->chip.card, kc);
308 }
309
310 break;
311 }
312
313 return 0;
314}
315
diff --git a/sound/usb/caiaq/caiaq-control.h b/sound/usb/caiaq/caiaq-control.h
new file mode 100644
index 000000000000..2e7ab1aa4fb3
--- /dev/null
+++ b/sound/usb/caiaq/caiaq-control.h
@@ -0,0 +1,6 @@
1#ifndef CAIAQ_CONTROL_H
2#define CAIAQ_CONTROL_H
3
4int snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev);
5
6#endif /* CAIAQ_CONTROL_H */
diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c
index 58af8142c571..dc2e7f7fef0f 100644
--- a/sound/usb/caiaq/caiaq-device.c
+++ b/sound/usb/caiaq/caiaq-device.c
@@ -31,17 +31,19 @@
31#include <sound/initval.h> 31#include <sound/initval.h>
32#include <sound/pcm.h> 32#include <sound/pcm.h>
33#include <sound/rawmidi.h> 33#include <sound/rawmidi.h>
34#include <sound/control.h>
34 35
35#include "caiaq-device.h" 36#include "caiaq-device.h"
36#include "caiaq-audio.h" 37#include "caiaq-audio.h"
37#include "caiaq-midi.h" 38#include "caiaq-midi.h"
39#include "caiaq-control.h"
38 40
39#ifdef CONFIG_SND_USB_CAIAQ_INPUT 41#ifdef CONFIG_SND_USB_CAIAQ_INPUT
40#include "caiaq-input.h" 42#include "caiaq-input.h"
41#endif 43#endif
42 44
43MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); 45MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
44MODULE_DESCRIPTION("caiaq USB audio, version 1.2.0"); 46MODULE_DESCRIPTION("caiaq USB audio, version 1.3.0");
45MODULE_LICENSE("GPL"); 47MODULE_LICENSE("GPL");
46MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," 48MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
47 "{Native Instruments, RigKontrol3}," 49 "{Native Instruments, RigKontrol3},"
@@ -140,14 +142,21 @@ static void usb_ep1_command_reply_dispatch (struct urb* urb)
140 case EP1_CMD_MIDI_READ: 142 case EP1_CMD_MIDI_READ:
141 snd_usb_caiaq_midi_handle_input(dev, buf[1], buf + 3, buf[2]); 143 snd_usb_caiaq_midi_handle_input(dev, buf[1], buf + 3, buf[2]);
142 break; 144 break;
143 145 case EP1_CMD_READ_IO:
146 if (dev->chip.usb_id ==
147 USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ)) {
148 if (urb->actual_length > sizeof(dev->control_state))
149 urb->actual_length = sizeof(dev->control_state);
150 memcpy(dev->control_state, buf + 1, urb->actual_length);
151 wake_up(&dev->ep1_wait_queue);
152 break;
153 }
144#ifdef CONFIG_SND_USB_CAIAQ_INPUT 154#ifdef CONFIG_SND_USB_CAIAQ_INPUT
145 case EP1_CMD_READ_ERP: 155 case EP1_CMD_READ_ERP:
146 case EP1_CMD_READ_ANALOG: 156 case EP1_CMD_READ_ANALOG:
147 case EP1_CMD_READ_IO:
148 snd_usb_caiaq_input_dispatch(dev, buf, urb->actual_length); 157 snd_usb_caiaq_input_dispatch(dev, buf, urb->actual_length);
149 break;
150#endif 158#endif
159 break;
151 } 160 }
152 161
153 dev->ep1_in_urb.actual_length = 0; 162 dev->ep1_in_urb.actual_length = 0;
@@ -156,10 +165,10 @@ static void usb_ep1_command_reply_dispatch (struct urb* urb)
156 log("unable to submit urb. OOM!?\n"); 165 log("unable to submit urb. OOM!?\n");
157} 166}
158 167
159static int send_command (struct snd_usb_caiaqdev *dev, 168int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *dev,
160 unsigned char command, 169 unsigned char command,
161 const unsigned char *buffer, 170 const unsigned char *buffer,
162 int len) 171 int len)
163{ 172{
164 int actual_len; 173 int actual_len;
165 struct usb_device *usb_dev = dev->chip.dev; 174 struct usb_device *usb_dev = dev->chip.dev;
@@ -207,7 +216,8 @@ int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev,
207 rate, depth, bpp); 216 rate, depth, bpp);
208 217
209 dev->audio_parm_answer = -1; 218 dev->audio_parm_answer = -1;
210 ret = send_command(dev, EP1_CMD_AUDIO_PARAMS, tmp, sizeof(tmp)); 219 ret = snd_usb_caiaq_send_command(dev, EP1_CMD_AUDIO_PARAMS,
220 tmp, sizeof(tmp));
211 221
212 if (ret) 222 if (ret)
213 return ret; 223 return ret;
@@ -226,7 +236,8 @@ int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev,
226 int digital, int analog, int erp) 236 int digital, int analog, int erp)
227{ 237{
228 char tmp[3] = { digital, analog, erp }; 238 char tmp[3] = { digital, analog, erp };
229 return send_command(dev, EP1_CMD_AUTO_MSG, tmp, sizeof(tmp)); 239 return snd_usb_caiaq_send_command(dev, EP1_CMD_AUTO_MSG,
240 tmp, sizeof(tmp));
230} 241}
231 242
232static void setup_card(struct snd_usb_caiaqdev *dev) 243static void setup_card(struct snd_usb_caiaqdev *dev)
@@ -241,7 +252,7 @@ static void setup_card(struct snd_usb_caiaqdev *dev)
241 val[0] = 0x00; 252 val[0] = 0x00;
242 val[1] = 0x00; 253 val[1] = 0x00;
243 val[2] = 0x01; 254 val[2] = 0x01;
244 send_command(dev, EP1_CMD_WRITE_IO, val, 3); 255 snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, val, 3);
245 break; 256 break;
246 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): 257 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
247 /* RigKontrol2 - display two centered dashes ('--') */ 258 /* RigKontrol2 - display two centered dashes ('--') */
@@ -249,12 +260,34 @@ static void setup_card(struct snd_usb_caiaqdev *dev)
249 val[1] = 0x40; 260 val[1] = 0x40;
250 val[2] = 0x40; 261 val[2] = 0x40;
251 val[3] = 0x00; 262 val[3] = 0x00;
252 send_command(dev, EP1_CMD_WRITE_IO, val, 4); 263 snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, val, 4);
253 break; 264 break;
254 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): 265 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
255 /* Audio Kontrol 1 - make USB-LED stop blinking */ 266 /* Audio Kontrol 1 - make USB-LED stop blinking */
256 val[0] = 0x00; 267 val[0] = 0x00;
257 send_command(dev, EP1_CMD_WRITE_IO, val, 1); 268 snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, val, 1);
269 break;
270 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
271 /* Audio 8 DJ - trigger read of current settings */
272 dev->control_state[0] = 0xff;
273 snd_usb_caiaq_set_auto_msg(dev, 1, 0, 0);
274 snd_usb_caiaq_send_command(dev, EP1_CMD_READ_IO, NULL, 0);
275
276 if (!wait_event_timeout(dev->ep1_wait_queue,
277 dev->control_state[0] != 0xff, HZ))
278 return;
279
280 /* fix up some defaults */
281 if ((dev->control_state[1] != 2) ||
282 (dev->control_state[2] != 3) ||
283 (dev->control_state[4] != 2)) {
284 dev->control_state[1] = 2;
285 dev->control_state[2] = 3;
286 dev->control_state[4] = 2;
287 snd_usb_caiaq_send_command(dev,
288 EP1_CMD_WRITE_IO, dev->control_state, 6);
289 }
290
258 break; 291 break;
259 } 292 }
260 293
@@ -278,6 +311,10 @@ static void setup_card(struct snd_usb_caiaqdev *dev)
278 log("snd_card_register() returned %d\n", ret); 311 log("snd_card_register() returned %d\n", ret);
279 snd_card_free(dev->chip.card); 312 snd_card_free(dev->chip.card);
280 } 313 }
314
315 ret = snd_usb_caiaq_control_init(dev);
316 if (ret < 0)
317 log("Unable to set up control system (ret=%d)\n", ret);
281} 318}
282 319
283static struct snd_card* create_card(struct usb_device* usb_dev) 320static struct snd_card* create_card(struct usb_device* usb_dev)
@@ -340,7 +377,7 @@ static int init_card(struct snd_usb_caiaqdev *dev)
340 if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0) 377 if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0)
341 return -EIO; 378 return -EIO;
342 379
343 err = send_command(dev, EP1_CMD_GET_DEVICE_INFO, NULL, 0); 380 err = snd_usb_caiaq_send_command(dev, EP1_CMD_GET_DEVICE_INFO, NULL, 0);
344 if (err) 381 if (err)
345 return err; 382 return err;
346 383
diff --git a/sound/usb/caiaq/caiaq-device.h b/sound/usb/caiaq/caiaq-device.h
index 685761279f1a..310b10ebb605 100644
--- a/sound/usb/caiaq/caiaq-device.h
+++ b/sound/usb/caiaq/caiaq-device.h
@@ -35,6 +35,7 @@
35#define EP1_CMD_MIDI_WRITE 0x7 35#define EP1_CMD_MIDI_WRITE 0x7
36#define EP1_CMD_AUDIO_PARAMS 0x9 36#define EP1_CMD_AUDIO_PARAMS 0x9
37#define EP1_CMD_AUTO_MSG 0xb 37#define EP1_CMD_AUTO_MSG 0xb
38#define EP1_CMD_DIMM_LEDS 0xc
38 39
39struct caiaq_device_spec { 40struct caiaq_device_spec {
40 unsigned short fw_version; 41 unsigned short fw_version;
@@ -90,11 +91,14 @@ struct snd_usb_caiaqdev {
90 struct snd_pcm_substream *sub_playback[MAX_STREAMS]; 91 struct snd_pcm_substream *sub_playback[MAX_STREAMS];
91 struct snd_pcm_substream *sub_capture[MAX_STREAMS]; 92 struct snd_pcm_substream *sub_capture[MAX_STREAMS];
92 93
94 /* Controls */
95 unsigned char control_state[64];
96
93 /* Linux input */ 97 /* Linux input */
94#ifdef CONFIG_SND_USB_CAIAQ_INPUT 98#ifdef CONFIG_SND_USB_CAIAQ_INPUT
95 struct input_dev *input_dev; 99 struct input_dev *input_dev;
96 char phys[64]; /* physical device path */ 100 char phys[64]; /* physical device path */
97 unsigned short keycode[10]; 101 unsigned short keycode[64];
98#endif 102#endif
99 103
100 /* ALSA */ 104 /* ALSA */
@@ -114,6 +118,9 @@ struct snd_usb_caiaq_cb_info {
114 118
115int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, int rate, int depth, int bbp); 119int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, int rate, int depth, int bbp);
116int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev, int digital, int analog, int erp); 120int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev, int digital, int analog, int erp);
117 121int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *dev,
122 unsigned char command,
123 const unsigned char *buffer,
124 int len);
118 125
119#endif /* CAIAQ_DEVICE_H */ 126#endif /* CAIAQ_DEVICE_H */
diff --git a/sound/usb/caiaq/caiaq-input.c b/sound/usb/caiaq/caiaq-input.c
index 03bf4c63b5ef..00846b1f92b2 100644
--- a/sound/usb/caiaq/caiaq-input.c
+++ b/sound/usb/caiaq/caiaq-input.c
@@ -38,6 +38,41 @@ static unsigned short keycode_rk2[] = { KEY_1, KEY_2, KEY_3, KEY_4,
38static unsigned short keycode_rk3[] = { KEY_1, KEY_2, KEY_3, KEY_4, 38static unsigned short keycode_rk3[] = { KEY_1, KEY_2, KEY_3, KEY_4,
39 KEY_5, KEY_6, KEY_7, KEY_5, KEY_6 }; 39 KEY_5, KEY_6, KEY_7, KEY_5, KEY_6 };
40 40
41static unsigned short keycode_kore[] = {
42 KEY_FN_F1, /* "menu" */
43 KEY_FN_F7, /* "lcd backlight */
44 KEY_FN_F2, /* "control" */
45 KEY_FN_F3, /* "enter" */
46 KEY_FN_F4, /* "view" */
47 KEY_FN_F5, /* "esc" */
48 KEY_FN_F6, /* "sound" */
49 KEY_FN_F8, /* array spacer, never triggered. */
50 KEY_RIGHT,
51 KEY_DOWN,
52 KEY_UP,
53 KEY_LEFT,
54 KEY_SOUND, /* "listen" */
55 KEY_RECORD,
56 KEY_PLAYPAUSE,
57 KEY_STOP,
58 BTN_4, /* 8 softkeys */
59 BTN_3,
60 BTN_2,
61 BTN_1,
62 BTN_8,
63 BTN_7,
64 BTN_6,
65 BTN_5,
66 KEY_BRL_DOT4, /* touch sensitive knobs */
67 KEY_BRL_DOT3,
68 KEY_BRL_DOT2,
69 KEY_BRL_DOT1,
70 KEY_BRL_DOT8,
71 KEY_BRL_DOT7,
72 KEY_BRL_DOT6,
73 KEY_BRL_DOT5
74};
75
41#define DEG90 (range / 2) 76#define DEG90 (range / 2)
42#define DEG180 (range) 77#define DEG180 (range)
43#define DEG270 (DEG90 + DEG180) 78#define DEG270 (DEG90 + DEG180)
@@ -115,14 +150,20 @@ static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev,
115{ 150{
116 struct input_dev *input_dev = dev->input_dev; 151 struct input_dev *input_dev = dev->input_dev;
117 152
118 switch (input_dev->id.product) { 153 switch (dev->chip.usb_id) {
119 case USB_PID_RIGKONTROL2: 154 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
120 input_report_abs(input_dev, ABS_X, (buf[4] << 8) | buf[5]); 155 input_report_abs(input_dev, ABS_X, (buf[4] << 8) | buf[5]);
121 input_report_abs(input_dev, ABS_Y, (buf[0] << 8) | buf[1]); 156 input_report_abs(input_dev, ABS_Y, (buf[0] << 8) | buf[1]);
122 input_report_abs(input_dev, ABS_Z, (buf[2] << 8) | buf[3]); 157 input_report_abs(input_dev, ABS_Z, (buf[2] << 8) | buf[3]);
123 input_sync(input_dev); 158 input_sync(input_dev);
124 break; 159 break;
125 case USB_PID_RIGKONTROL3: 160 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
161 input_report_abs(input_dev, ABS_X, (buf[0] << 8) | buf[1]);
162 input_report_abs(input_dev, ABS_Y, (buf[2] << 8) | buf[3]);
163 input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]);
164 input_sync(input_dev);
165 break;
166 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
126 input_report_abs(input_dev, ABS_X, (buf[0] << 8) | buf[1]); 167 input_report_abs(input_dev, ABS_X, (buf[0] << 8) | buf[1]);
127 input_report_abs(input_dev, ABS_Y, (buf[2] << 8) | buf[3]); 168 input_report_abs(input_dev, ABS_Y, (buf[2] << 8) | buf[3]);
128 input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]); 169 input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]);
@@ -137,12 +178,31 @@ static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev,
137 struct input_dev *input_dev = dev->input_dev; 178 struct input_dev *input_dev = dev->input_dev;
138 int i; 179 int i;
139 180
140 switch (input_dev->id.product) { 181 switch (dev->chip.usb_id) {
141 case USB_PID_AK1: 182 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
142 i = decode_erp(buf[0], buf[1]); 183 i = decode_erp(buf[0], buf[1]);
143 input_report_abs(input_dev, ABS_X, i); 184 input_report_abs(input_dev, ABS_X, i);
144 input_sync(input_dev); 185 input_sync(input_dev);
145 break; 186 break;
187 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
188 i = decode_erp(buf[7], buf[5]);
189 input_report_abs(input_dev, ABS_HAT0X, i);
190 i = decode_erp(buf[12], buf[14]);
191 input_report_abs(input_dev, ABS_HAT0Y, i);
192 i = decode_erp(buf[15], buf[13]);
193 input_report_abs(input_dev, ABS_HAT1X, i);
194 i = decode_erp(buf[0], buf[2]);
195 input_report_abs(input_dev, ABS_HAT1Y, i);
196 i = decode_erp(buf[3], buf[1]);
197 input_report_abs(input_dev, ABS_HAT2X, i);
198 i = decode_erp(buf[8], buf[10]);
199 input_report_abs(input_dev, ABS_HAT2Y, i);
200 i = decode_erp(buf[11], buf[9]);
201 input_report_abs(input_dev, ABS_HAT3X, i);
202 i = decode_erp(buf[4], buf[6]);
203 input_report_abs(input_dev, ABS_HAT3Y, i);
204 input_sync(input_dev);
205 break;
146 } 206 }
147} 207}
148 208
@@ -160,10 +220,14 @@ static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev,
160 for (i = 0; i < len; i++) 220 for (i = 0; i < len; i++)
161 buf[i] = ~buf[i]; 221 buf[i] = ~buf[i];
162 222
163 for (i = 0; i < input_dev->keycodemax && i < len; i++) 223 for (i = 0; i < input_dev->keycodemax && i < len * 8; i++)
164 input_report_key(input_dev, keycode[i], 224 input_report_key(input_dev, keycode[i],
165 buf[i / 8] & (1 << (i % 8))); 225 buf[i / 8] & (1 << (i % 8)));
166 226
227 if (dev->chip.usb_id ==
228 USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER))
229 input_report_abs(dev->input_dev, ABS_MISC, 255 - buf[4]);
230
167 input_sync(input_dev); 231 input_sync(input_dev);
168} 232}
169 233
@@ -218,10 +282,10 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
218 input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10); 282 input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10);
219 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0); 283 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0);
220 break; 284 break;
221
222 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): 285 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
223 input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); 286 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
224 input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_Z); 287 input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
288 BIT_MASK(ABS_Z);
225 BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_rk3)); 289 BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_rk3));
226 memcpy(dev->keycode, keycode_rk3, sizeof(keycode_rk3)); 290 memcpy(dev->keycode, keycode_rk3, sizeof(keycode_rk3));
227 input->keycodemax = ARRAY_SIZE(keycode_rk3); 291 input->keycodemax = ARRAY_SIZE(keycode_rk3);
@@ -239,6 +303,32 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
239 input_set_abs_params(input, ABS_X, 0, 999, 0, 10); 303 input_set_abs_params(input, ABS_X, 0, 999, 0, 10);
240 snd_usb_caiaq_set_auto_msg(dev, 1, 0, 5); 304 snd_usb_caiaq_set_auto_msg(dev, 1, 0, 5);
241 break; 305 break;
306 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
307 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
308 input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
309 BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) |
310 BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) |
311 BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) |
312 BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
313 BIT_MASK(ABS_Z);
314 input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
315 BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_kore));
316 memcpy(dev->keycode, keycode_kore, sizeof(keycode_kore));
317 input->keycodemax = ARRAY_SIZE(keycode_kore);
318 input_set_abs_params(input, ABS_HAT0X, 0, 999, 0, 10);
319 input_set_abs_params(input, ABS_HAT0Y, 0, 999, 0, 10);
320 input_set_abs_params(input, ABS_HAT1X, 0, 999, 0, 10);
321 input_set_abs_params(input, ABS_HAT1Y, 0, 999, 0, 10);
322 input_set_abs_params(input, ABS_HAT2X, 0, 999, 0, 10);
323 input_set_abs_params(input, ABS_HAT2Y, 0, 999, 0, 10);
324 input_set_abs_params(input, ABS_HAT3X, 0, 999, 0, 10);
325 input_set_abs_params(input, ABS_HAT3Y, 0, 999, 0, 10);
326 input_set_abs_params(input, ABS_X, 0, 4096, 0, 10);
327 input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10);
328 input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10);
329 input_set_abs_params(input, ABS_MISC, 0, 255, 0, 1);
330 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
331 break;
242 default: 332 default:
243 /* no input methods supported on this device */ 333 /* no input methods supported on this device */
244 input_free_device(input); 334 input_free_device(input);