control.c (f90ffbf3c68a69714b4273b203d4deb5ae81d8d6) control.c (d97c735a1047fa06165e55da32154cf0e6b9419c)
1/*
2 * Linux driver for TerraTec DMX 6Fire USB
3 *
4 * Mixer control
5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011
8 * Copyright: (C) Torsten Schenk

--- 60 unchanged lines hidden (view full) ---

69 for (i = 0; i < 6; i++)
70 if (!(rt->ovol_updated & (1 << i))) {
71 comm_rt->write8(comm_rt, 0x12, 0x0f + i,
72 180 - rt->output_vol[i]);
73 rt->ovol_updated |= 1 << i;
74 }
75}
76
1/*
2 * Linux driver for TerraTec DMX 6Fire USB
3 *
4 * Mixer control
5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011
8 * Copyright: (C) Torsten Schenk

--- 60 unchanged lines hidden (view full) ---

69 for (i = 0; i < 6; i++)
70 if (!(rt->ovol_updated & (1 << i))) {
71 comm_rt->write8(comm_rt, 0x12, 0x0f + i,
72 180 - rt->output_vol[i]);
73 rt->ovol_updated |= 1 << i;
74 }
75}
76
77static void usb6fire_control_output_mute_update(struct control_runtime *rt)
78{
79 struct comm_runtime *comm_rt = rt->chip->comm;
80
81 if (comm_rt)
82 comm_rt->write8(comm_rt, 0x12, 0x0e, ~rt->output_mute);
83}
84
77static void usb6fire_control_line_phono_update(struct control_runtime *rt)
78{
79 struct comm_runtime *comm_rt = rt->chip->comm;
80 if (comm_rt) {
81 comm_rt->write8(comm_rt, 0x22, 0x02, rt->line_phono_switch);
82 comm_rt->write8(comm_rt, 0x21, 0x02, rt->line_phono_switch);
83 }
84}

--- 118 unchanged lines hidden (view full) ---

203 return -EINVAL;
204 }
205
206 ucontrol->value.integer.value[0] = rt->output_vol[ch];
207 ucontrol->value.integer.value[1] = rt->output_vol[ch + 1];
208 return 0;
209}
210
85static void usb6fire_control_line_phono_update(struct control_runtime *rt)
86{
87 struct comm_runtime *comm_rt = rt->chip->comm;
88 if (comm_rt) {
89 comm_rt->write8(comm_rt, 0x22, 0x02, rt->line_phono_switch);
90 comm_rt->write8(comm_rt, 0x21, 0x02, rt->line_phono_switch);
91 }
92}

--- 118 unchanged lines hidden (view full) ---

211 return -EINVAL;
212 }
213
214 ucontrol->value.integer.value[0] = rt->output_vol[ch];
215 ucontrol->value.integer.value[1] = rt->output_vol[ch + 1];
216 return 0;
217}
218
219static int usb6fire_control_output_mute_put(struct snd_kcontrol *kcontrol,
220 struct snd_ctl_elem_value *ucontrol)
221{
222 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
223 unsigned int ch = kcontrol->private_value;
224 u8 old = rt->output_mute;
225 u8 value = 0;
226
227 if (ch > 4) {
228 snd_printk(KERN_ERR PREFIX "Invalid channel in volume control.");
229 return -EINVAL;
230 }
231
232 rt->output_mute &= ~(3 << ch);
233 if (ucontrol->value.integer.value[0])
234 value |= 1;
235 if (ucontrol->value.integer.value[1])
236 value |= 2;
237 rt->output_mute |= value << ch;
238
239 if (rt->output_mute != old)
240 usb6fire_control_output_mute_update(rt);
241
242 return rt->output_mute != old;
243}
244
245static int usb6fire_control_output_mute_get(struct snd_kcontrol *kcontrol,
246 struct snd_ctl_elem_value *ucontrol)
247{
248 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
249 unsigned int ch = kcontrol->private_value;
250 u8 value = rt->output_mute >> ch;
251
252 if (ch > 4) {
253 snd_printk(KERN_ERR PREFIX "Invalid channel in volume control.");
254 return -EINVAL;
255 }
256
257 ucontrol->value.integer.value[0] = 1 & value;
258 value >>= 1;
259 ucontrol->value.integer.value[1] = 1 & value;
260
261 return 0;
262}
263
211static int usb6fire_control_line_phono_info(struct snd_kcontrol *kcontrol,
212 struct snd_ctl_elem_info *uinfo)
213{
214 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
215 uinfo->count = 1;
216 uinfo->value.enumerated.items = 2;
217 if (uinfo->value.enumerated.item > 1)
218 uinfo->value.enumerated.item = 1;

--- 115 unchanged lines hidden (view full) ---

334 .info = usb6fire_control_output_vol_info,
335 .get = usb6fire_control_output_vol_get,
336 .put = usb6fire_control_output_vol_put,
337 .tlv = { .p = tlv_output }
338 },
339 {}
340};
341
264static int usb6fire_control_line_phono_info(struct snd_kcontrol *kcontrol,
265 struct snd_ctl_elem_info *uinfo)
266{
267 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
268 uinfo->count = 1;
269 uinfo->value.enumerated.items = 2;
270 if (uinfo->value.enumerated.item > 1)
271 uinfo->value.enumerated.item = 1;

--- 115 unchanged lines hidden (view full) ---

387 .info = usb6fire_control_output_vol_info,
388 .get = usb6fire_control_output_vol_get,
389 .put = usb6fire_control_output_vol_put,
390 .tlv = { .p = tlv_output }
391 },
392 {}
393};
394
395static struct __devinitdata snd_kcontrol_new mute_elements[] = {
396 {
397 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
398 .name = "Analog Playback Switch",
399 .index = 0,
400 .private_value = 0,
401 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
402 .info = snd_ctl_boolean_stereo_info,
403 .get = usb6fire_control_output_mute_get,
404 .put = usb6fire_control_output_mute_put,
405 },
406 {
407 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
408 .name = "Analog Playback Switch",
409 .index = 1,
410 .private_value = 2,
411 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
412 .info = snd_ctl_boolean_stereo_info,
413 .get = usb6fire_control_output_mute_get,
414 .put = usb6fire_control_output_mute_put,
415 },
416 {
417 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
418 .name = "Analog Playback Switch",
419 .index = 2,
420 .private_value = 4,
421 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
422 .info = snd_ctl_boolean_stereo_info,
423 .get = usb6fire_control_output_mute_get,
424 .put = usb6fire_control_output_mute_put,
425 },
426 {}
427};
428
342static struct __devinitdata snd_kcontrol_new elements[] = {
343 {
344 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
345 .name = "Line/Phono Capture Route",
346 .index = 0,
347 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
348 .info = usb6fire_control_line_phono_info,
349 .get = usb6fire_control_line_phono_get,

--- 75 unchanged lines hidden (view full) ---

425 comm_rt->write8(comm_rt, init_data[i].type, init_data[i].reg,
426 init_data[i].value);
427 i++;
428 }
429
430 usb6fire_control_opt_coax_update(rt);
431 usb6fire_control_line_phono_update(rt);
432 usb6fire_control_output_vol_update(rt);
429static struct __devinitdata snd_kcontrol_new elements[] = {
430 {
431 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
432 .name = "Line/Phono Capture Route",
433 .index = 0,
434 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
435 .info = usb6fire_control_line_phono_info,
436 .get = usb6fire_control_line_phono_get,

--- 75 unchanged lines hidden (view full) ---

512 comm_rt->write8(comm_rt, init_data[i].type, init_data[i].reg,
513 init_data[i].value);
514 i++;
515 }
516
517 usb6fire_control_opt_coax_update(rt);
518 usb6fire_control_line_phono_update(rt);
519 usb6fire_control_output_vol_update(rt);
520 usb6fire_control_output_mute_update(rt);
433 usb6fire_control_streaming_update(rt);
434
435 ret = usb6fire_control_add_virtual(rt, chip->card,
436 "Master Playback Volume", vol_elements);
437 if (ret) {
521 usb6fire_control_streaming_update(rt);
522
523 ret = usb6fire_control_add_virtual(rt, chip->card,
524 "Master Playback Volume", vol_elements);
525 if (ret) {
526 snd_printk(KERN_ERR PREFIX "cannot add control.\n");
438 kfree(rt);
527 kfree(rt);
528 return ret;
529 }
530 ret = usb6fire_control_add_virtual(rt, chip->card,
531 "Master Playback Switch", mute_elements);
532 if (ret) {
439 snd_printk(KERN_ERR PREFIX "cannot add control.\n");
533 snd_printk(KERN_ERR PREFIX "cannot add control.\n");
534 kfree(rt);
440 return ret;
441 }
442
443 i = 0;
444 while (elements[i].name) {
445 ret = snd_ctl_add(chip->card, snd_ctl_new1(&elements[i], rt));
446 if (ret < 0) {
447 kfree(rt);

--- 18 unchanged lines hidden ---
535 return ret;
536 }
537
538 i = 0;
539 while (elements[i].name) {
540 ret = snd_ctl_add(chip->card, snd_ctl_new1(&elements[i], rt));
541 if (ret < 0) {
542 kfree(rt);

--- 18 unchanged lines hidden ---