2 * Linux driver for TerraTec DMX 6Fire USB
6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011
8 * Copyright: (C) Torsten Schenk
11 * - Holger Ruckdeschel: he found out how to control individual channel
12 * volumes and introduced mute switch
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
20 #include <linux/interrupt.h>
21 #include <sound/control.h>
22 #include <sound/tlv.h>
28 static char *opt_coax_texts
[2] = { "Optical", "Coax" };
29 static char *line_phono_texts
[2] = { "Line", "Phono" };
32 * data that needs to be sent to device. sets up card internal stuff.
33 * values dumped from windows driver and filtered by trial'n'error.
41 { 0x22, 0x00, 0x00 }, { 0x20, 0x00, 0x08 }, { 0x22, 0x01, 0x01 },
42 { 0x20, 0x01, 0x08 }, { 0x22, 0x02, 0x00 }, { 0x20, 0x02, 0x08 },
43 { 0x22, 0x03, 0x00 }, { 0x20, 0x03, 0x08 }, { 0x22, 0x04, 0x00 },
44 { 0x20, 0x04, 0x08 }, { 0x22, 0x05, 0x01 }, { 0x20, 0x05, 0x08 },
45 { 0x22, 0x04, 0x01 }, { 0x12, 0x04, 0x00 }, { 0x12, 0x05, 0x00 },
46 { 0x12, 0x0d, 0x38 }, { 0x12, 0x21, 0x82 }, { 0x12, 0x22, 0x80 },
47 { 0x12, 0x23, 0x00 }, { 0x12, 0x06, 0x02 }, { 0x12, 0x03, 0x00 },
48 { 0x12, 0x02, 0x00 }, { 0x22, 0x03, 0x01 },
49 { 0 } /* TERMINATING ENTRY */
52 static const int rates_altsetting
[] = { 1, 1, 2, 2, 3, 3 };
53 /* values to write to soundcard register for all samplerates */
54 static const u16 rates_6fire_vl
[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01};
55 static const u16 rates_6fire_vh
[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00};
57 static DECLARE_TLV_DB_MINMAX(tlv_output
, -9000, 0);
58 static DECLARE_TLV_DB_MINMAX(tlv_input
, -1500, 1500);
61 DIGITAL_THRU_ONLY_SAMPLERATE
= 3
64 static void usb6fire_control_output_vol_update(struct control_runtime
*rt
)
66 struct comm_runtime
*comm_rt
= rt
->chip
->comm
;
70 for (i
= 0; i
< 6; i
++)
71 if (!(rt
->ovol_updated
& (1 << i
))) {
72 comm_rt
->write8(comm_rt
, 0x12, 0x0f + i
,
73 180 - rt
->output_vol
[i
]);
74 rt
->ovol_updated
|= 1 << i
;
78 static void usb6fire_control_output_mute_update(struct control_runtime
*rt
)
80 struct comm_runtime
*comm_rt
= rt
->chip
->comm
;
83 comm_rt
->write8(comm_rt
, 0x12, 0x0e, ~rt
->output_mute
);
86 static void usb6fire_control_input_vol_update(struct control_runtime
*rt
)
88 struct comm_runtime
*comm_rt
= rt
->chip
->comm
;
92 for (i
= 0; i
< 2; i
++)
93 if (!(rt
->ivol_updated
& (1 << i
))) {
94 comm_rt
->write8(comm_rt
, 0x12, 0x1c + i
,
95 rt
->input_vol
[i
] & 0x3f);
96 rt
->ivol_updated
|= 1 << i
;
100 static void usb6fire_control_line_phono_update(struct control_runtime
*rt
)
102 struct comm_runtime
*comm_rt
= rt
->chip
->comm
;
104 comm_rt
->write8(comm_rt
, 0x22, 0x02, rt
->line_phono_switch
);
105 comm_rt
->write8(comm_rt
, 0x21, 0x02, rt
->line_phono_switch
);
109 static void usb6fire_control_opt_coax_update(struct control_runtime
*rt
)
111 struct comm_runtime
*comm_rt
= rt
->chip
->comm
;
113 comm_rt
->write8(comm_rt
, 0x22, 0x00, rt
->opt_coax_switch
);
114 comm_rt
->write8(comm_rt
, 0x21, 0x00, rt
->opt_coax_switch
);
118 static int usb6fire_control_set_rate(struct control_runtime
*rt
, int rate
)
121 struct usb_device
*device
= rt
->chip
->dev
;
122 struct comm_runtime
*comm_rt
= rt
->chip
->comm
;
124 if (rate
< 0 || rate
>= CONTROL_N_RATES
)
127 ret
= usb_set_interface(device
, 1, rates_altsetting
[rate
]);
131 /* set soundcard clock */
132 ret
= comm_rt
->write16(comm_rt
, 0x02, 0x01, rates_6fire_vl
[rate
],
133 rates_6fire_vh
[rate
]);
140 static int usb6fire_control_set_channels(
141 struct control_runtime
*rt
, int n_analog_out
,
142 int n_analog_in
, bool spdif_out
, bool spdif_in
)
145 struct comm_runtime
*comm_rt
= rt
->chip
->comm
;
147 /* enable analog inputs and outputs
148 * (one bit per stereo-channel) */
149 ret
= comm_rt
->write16(comm_rt
, 0x02, 0x02,
150 (1 << (n_analog_out
/ 2)) - 1,
151 (1 << (n_analog_in
/ 2)) - 1);
155 /* disable digital inputs and outputs */
156 /* TODO: use spdif_x to enable/disable digital channels */
157 ret
= comm_rt
->write16(comm_rt
, 0x02, 0x03, 0x00, 0x00);
164 static int usb6fire_control_streaming_update(struct control_runtime
*rt
)
166 struct comm_runtime
*comm_rt
= rt
->chip
->comm
;
169 if (!rt
->usb_streaming
&& rt
->digital_thru_switch
)
170 usb6fire_control_set_rate(rt
,
171 DIGITAL_THRU_ONLY_SAMPLERATE
);
172 return comm_rt
->write16(comm_rt
, 0x02, 0x00, 0x00,
173 (rt
->usb_streaming
? 0x01 : 0x00) |
174 (rt
->digital_thru_switch
? 0x08 : 0x00));
179 static int usb6fire_control_output_vol_info(struct snd_kcontrol
*kcontrol
,
180 struct snd_ctl_elem_info
*uinfo
)
182 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
184 uinfo
->value
.integer
.min
= 0;
185 uinfo
->value
.integer
.max
= 180;
189 static int usb6fire_control_output_vol_put(struct snd_kcontrol
*kcontrol
,
190 struct snd_ctl_elem_value
*ucontrol
)
192 struct control_runtime
*rt
= snd_kcontrol_chip(kcontrol
);
193 unsigned int ch
= kcontrol
->private_value
;
197 snd_printk(KERN_ERR PREFIX
"Invalid channel in volume control.");
201 if (rt
->output_vol
[ch
] != ucontrol
->value
.integer
.value
[0]) {
202 rt
->output_vol
[ch
] = ucontrol
->value
.integer
.value
[0];
203 rt
->ovol_updated
&= ~(1 << ch
);
206 if (rt
->output_vol
[ch
+ 1] != ucontrol
->value
.integer
.value
[1]) {
207 rt
->output_vol
[ch
+ 1] = ucontrol
->value
.integer
.value
[1];
208 rt
->ovol_updated
&= ~(2 << ch
);
213 usb6fire_control_output_vol_update(rt
);
218 static int usb6fire_control_output_vol_get(struct snd_kcontrol
*kcontrol
,
219 struct snd_ctl_elem_value
*ucontrol
)
221 struct control_runtime
*rt
= snd_kcontrol_chip(kcontrol
);
222 unsigned int ch
= kcontrol
->private_value
;
225 snd_printk(KERN_ERR PREFIX
"Invalid channel in volume control.");
229 ucontrol
->value
.integer
.value
[0] = rt
->output_vol
[ch
];
230 ucontrol
->value
.integer
.value
[1] = rt
->output_vol
[ch
+ 1];
234 static int usb6fire_control_output_mute_put(struct snd_kcontrol
*kcontrol
,
235 struct snd_ctl_elem_value
*ucontrol
)
237 struct control_runtime
*rt
= snd_kcontrol_chip(kcontrol
);
238 unsigned int ch
= kcontrol
->private_value
;
239 u8 old
= rt
->output_mute
;
243 snd_printk(KERN_ERR PREFIX
"Invalid channel in volume control.");
247 rt
->output_mute
&= ~(3 << ch
);
248 if (ucontrol
->value
.integer
.value
[0])
250 if (ucontrol
->value
.integer
.value
[1])
252 rt
->output_mute
|= value
<< ch
;
254 if (rt
->output_mute
!= old
)
255 usb6fire_control_output_mute_update(rt
);
257 return rt
->output_mute
!= old
;
260 static int usb6fire_control_output_mute_get(struct snd_kcontrol
*kcontrol
,
261 struct snd_ctl_elem_value
*ucontrol
)
263 struct control_runtime
*rt
= snd_kcontrol_chip(kcontrol
);
264 unsigned int ch
= kcontrol
->private_value
;
265 u8 value
= rt
->output_mute
>> ch
;
268 snd_printk(KERN_ERR PREFIX
"Invalid channel in volume control.");
272 ucontrol
->value
.integer
.value
[0] = 1 & value
;
274 ucontrol
->value
.integer
.value
[1] = 1 & value
;
279 static int usb6fire_control_input_vol_info(struct snd_kcontrol
*kcontrol
,
280 struct snd_ctl_elem_info
*uinfo
)
282 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
284 uinfo
->value
.integer
.min
= 0;
285 uinfo
->value
.integer
.max
= 30;
289 static int usb6fire_control_input_vol_put(struct snd_kcontrol
*kcontrol
,
290 struct snd_ctl_elem_value
*ucontrol
)
292 struct control_runtime
*rt
= snd_kcontrol_chip(kcontrol
);
295 if (rt
->input_vol
[0] != ucontrol
->value
.integer
.value
[0]) {
296 rt
->input_vol
[0] = ucontrol
->value
.integer
.value
[0] - 15;
297 rt
->ivol_updated
&= ~(1 << 0);
300 if (rt
->input_vol
[1] != ucontrol
->value
.integer
.value
[1]) {
301 rt
->input_vol
[1] = ucontrol
->value
.integer
.value
[1] - 15;
302 rt
->ivol_updated
&= ~(1 << 1);
307 usb6fire_control_input_vol_update(rt
);
312 static int usb6fire_control_input_vol_get(struct snd_kcontrol
*kcontrol
,
313 struct snd_ctl_elem_value
*ucontrol
)
315 struct control_runtime
*rt
= snd_kcontrol_chip(kcontrol
);
317 ucontrol
->value
.integer
.value
[0] = rt
->input_vol
[0] + 15;
318 ucontrol
->value
.integer
.value
[1] = rt
->input_vol
[1] + 15;
323 static int usb6fire_control_line_phono_info(struct snd_kcontrol
*kcontrol
,
324 struct snd_ctl_elem_info
*uinfo
)
326 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
328 uinfo
->value
.enumerated
.items
= 2;
329 if (uinfo
->value
.enumerated
.item
> 1)
330 uinfo
->value
.enumerated
.item
= 1;
331 strcpy(uinfo
->value
.enumerated
.name
,
332 line_phono_texts
[uinfo
->value
.enumerated
.item
]);
336 static int usb6fire_control_line_phono_put(struct snd_kcontrol
*kcontrol
,
337 struct snd_ctl_elem_value
*ucontrol
)
339 struct control_runtime
*rt
= snd_kcontrol_chip(kcontrol
);
341 if (rt
->line_phono_switch
!= ucontrol
->value
.integer
.value
[0]) {
342 rt
->line_phono_switch
= ucontrol
->value
.integer
.value
[0];
343 usb6fire_control_line_phono_update(rt
);
349 static int usb6fire_control_line_phono_get(struct snd_kcontrol
*kcontrol
,
350 struct snd_ctl_elem_value
*ucontrol
)
352 struct control_runtime
*rt
= snd_kcontrol_chip(kcontrol
);
353 ucontrol
->value
.integer
.value
[0] = rt
->line_phono_switch
;
357 static int usb6fire_control_opt_coax_info(struct snd_kcontrol
*kcontrol
,
358 struct snd_ctl_elem_info
*uinfo
)
360 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
362 uinfo
->value
.enumerated
.items
= 2;
363 if (uinfo
->value
.enumerated
.item
> 1)
364 uinfo
->value
.enumerated
.item
= 1;
365 strcpy(uinfo
->value
.enumerated
.name
,
366 opt_coax_texts
[uinfo
->value
.enumerated
.item
]);
370 static int usb6fire_control_opt_coax_put(struct snd_kcontrol
*kcontrol
,
371 struct snd_ctl_elem_value
*ucontrol
)
373 struct control_runtime
*rt
= snd_kcontrol_chip(kcontrol
);
376 if (rt
->opt_coax_switch
!= ucontrol
->value
.enumerated
.item
[0]) {
377 rt
->opt_coax_switch
= ucontrol
->value
.enumerated
.item
[0];
378 usb6fire_control_opt_coax_update(rt
);
384 static int usb6fire_control_opt_coax_get(struct snd_kcontrol
*kcontrol
,
385 struct snd_ctl_elem_value
*ucontrol
)
387 struct control_runtime
*rt
= snd_kcontrol_chip(kcontrol
);
388 ucontrol
->value
.enumerated
.item
[0] = rt
->opt_coax_switch
;
392 static int usb6fire_control_digital_thru_put(struct snd_kcontrol
*kcontrol
,
393 struct snd_ctl_elem_value
*ucontrol
)
395 struct control_runtime
*rt
= snd_kcontrol_chip(kcontrol
);
398 if (rt
->digital_thru_switch
!= ucontrol
->value
.integer
.value
[0]) {
399 rt
->digital_thru_switch
= ucontrol
->value
.integer
.value
[0];
400 usb6fire_control_streaming_update(rt
);
406 static int usb6fire_control_digital_thru_get(struct snd_kcontrol
*kcontrol
,
407 struct snd_ctl_elem_value
*ucontrol
)
409 struct control_runtime
*rt
= snd_kcontrol_chip(kcontrol
);
410 ucontrol
->value
.integer
.value
[0] = rt
->digital_thru_switch
;
414 static struct snd_kcontrol_new vol_elements
[] = {
416 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
417 .name
= "Analog Playback Volume",
420 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
|
421 SNDRV_CTL_ELEM_ACCESS_TLV_READ
,
422 .info
= usb6fire_control_output_vol_info
,
423 .get
= usb6fire_control_output_vol_get
,
424 .put
= usb6fire_control_output_vol_put
,
425 .tlv
= { .p
= tlv_output
}
428 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
429 .name
= "Analog Playback Volume",
432 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
|
433 SNDRV_CTL_ELEM_ACCESS_TLV_READ
,
434 .info
= usb6fire_control_output_vol_info
,
435 .get
= usb6fire_control_output_vol_get
,
436 .put
= usb6fire_control_output_vol_put
,
437 .tlv
= { .p
= tlv_output
}
440 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
441 .name
= "Analog Playback Volume",
444 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
|
445 SNDRV_CTL_ELEM_ACCESS_TLV_READ
,
446 .info
= usb6fire_control_output_vol_info
,
447 .get
= usb6fire_control_output_vol_get
,
448 .put
= usb6fire_control_output_vol_put
,
449 .tlv
= { .p
= tlv_output
}
454 static struct snd_kcontrol_new mute_elements
[] = {
456 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
457 .name
= "Analog Playback Switch",
460 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
,
461 .info
= snd_ctl_boolean_stereo_info
,
462 .get
= usb6fire_control_output_mute_get
,
463 .put
= usb6fire_control_output_mute_put
,
466 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
467 .name
= "Analog Playback Switch",
470 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
,
471 .info
= snd_ctl_boolean_stereo_info
,
472 .get
= usb6fire_control_output_mute_get
,
473 .put
= usb6fire_control_output_mute_put
,
476 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
477 .name
= "Analog Playback Switch",
480 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
,
481 .info
= snd_ctl_boolean_stereo_info
,
482 .get
= usb6fire_control_output_mute_get
,
483 .put
= usb6fire_control_output_mute_put
,
488 static struct snd_kcontrol_new elements
[] = {
490 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
491 .name
= "Line/Phono Capture Route",
493 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
,
494 .info
= usb6fire_control_line_phono_info
,
495 .get
= usb6fire_control_line_phono_get
,
496 .put
= usb6fire_control_line_phono_put
499 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
500 .name
= "Opt/Coax Capture Route",
502 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
,
503 .info
= usb6fire_control_opt_coax_info
,
504 .get
= usb6fire_control_opt_coax_get
,
505 .put
= usb6fire_control_opt_coax_put
508 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
509 .name
= "Digital Thru Playback Route",
511 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
,
512 .info
= snd_ctl_boolean_mono_info
,
513 .get
= usb6fire_control_digital_thru_get
,
514 .put
= usb6fire_control_digital_thru_put
517 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
518 .name
= "Analog Capture Volume",
520 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
|
521 SNDRV_CTL_ELEM_ACCESS_TLV_READ
,
522 .info
= usb6fire_control_input_vol_info
,
523 .get
= usb6fire_control_input_vol_get
,
524 .put
= usb6fire_control_input_vol_put
,
525 .tlv
= { .p
= tlv_input
}
530 static int usb6fire_control_add_virtual(
531 struct control_runtime
*rt
,
532 struct snd_card
*card
,
534 struct snd_kcontrol_new
*elems
)
538 struct snd_kcontrol
*vmaster
=
539 snd_ctl_make_virtual_master(name
, tlv_output
);
540 struct snd_kcontrol
*control
;
544 ret
= snd_ctl_add(card
, vmaster
);
549 while (elems
[i
].name
) {
550 control
= snd_ctl_new1(&elems
[i
], rt
);
553 ret
= snd_ctl_add(card
, control
);
556 ret
= snd_ctl_add_slave(vmaster
, control
);
564 int usb6fire_control_init(struct sfire_chip
*chip
)
568 struct control_runtime
*rt
= kzalloc(sizeof(struct control_runtime
),
570 struct comm_runtime
*comm_rt
= chip
->comm
;
576 rt
->update_streaming
= usb6fire_control_streaming_update
;
577 rt
->set_rate
= usb6fire_control_set_rate
;
578 rt
->set_channels
= usb6fire_control_set_channels
;
581 while (init_data
[i
].type
) {
582 comm_rt
->write8(comm_rt
, init_data
[i
].type
, init_data
[i
].reg
,
587 usb6fire_control_opt_coax_update(rt
);
588 usb6fire_control_line_phono_update(rt
);
589 usb6fire_control_output_vol_update(rt
);
590 usb6fire_control_output_mute_update(rt
);
591 usb6fire_control_input_vol_update(rt
);
592 usb6fire_control_streaming_update(rt
);
594 ret
= usb6fire_control_add_virtual(rt
, chip
->card
,
595 "Master Playback Volume", vol_elements
);
597 snd_printk(KERN_ERR PREFIX
"cannot add control.\n");
601 ret
= usb6fire_control_add_virtual(rt
, chip
->card
,
602 "Master Playback Switch", mute_elements
);
604 snd_printk(KERN_ERR PREFIX
"cannot add control.\n");
610 while (elements
[i
].name
) {
611 ret
= snd_ctl_add(chip
->card
, snd_ctl_new1(&elements
[i
], rt
));
614 snd_printk(KERN_ERR PREFIX
"cannot add control.\n");
624 void usb6fire_control_abort(struct sfire_chip
*chip
)
627 void usb6fire_control_destroy(struct sfire_chip
*chip
)
629 kfree(chip
->control
);
630 chip
->control
= NULL
;