diff options
Diffstat (limited to 'sound/pci/oxygen/oxygen_mixer.c')
-rw-r--r-- | sound/pci/oxygen/oxygen_mixer.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 0993c29e62f1..6b7420fdd026 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c | |||
@@ -408,6 +408,37 @@ static int spdif_input_default_get(struct snd_kcontrol *ctl, | |||
408 | return 0; | 408 | return 0; |
409 | } | 409 | } |
410 | 410 | ||
411 | static int spdif_loopback_get(struct snd_kcontrol *ctl, | ||
412 | struct snd_ctl_elem_value *value) | ||
413 | { | ||
414 | struct oxygen *chip = ctl->private_data; | ||
415 | |||
416 | value->value.integer.value[0] = | ||
417 | !!(oxygen_read32(chip, OXYGEN_SPDIF_CONTROL) | ||
418 | & OXYGEN_SPDIF_LOOPBACK); | ||
419 | return 0; | ||
420 | } | ||
421 | |||
422 | static int spdif_loopback_put(struct snd_kcontrol *ctl, | ||
423 | struct snd_ctl_elem_value *value) | ||
424 | { | ||
425 | struct oxygen *chip = ctl->private_data; | ||
426 | u32 oldreg, newreg; | ||
427 | int changed; | ||
428 | |||
429 | spin_lock_irq(&chip->reg_lock); | ||
430 | oldreg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL); | ||
431 | if (value->value.integer.value[0]) | ||
432 | newreg = oldreg | OXYGEN_SPDIF_LOOPBACK; | ||
433 | else | ||
434 | newreg = oldreg & ~OXYGEN_SPDIF_LOOPBACK; | ||
435 | changed = newreg != oldreg; | ||
436 | if (changed) | ||
437 | oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, newreg); | ||
438 | spin_unlock_irq(&chip->reg_lock); | ||
439 | return changed; | ||
440 | } | ||
441 | |||
411 | static int ac97_switch_get(struct snd_kcontrol *ctl, | 442 | static int ac97_switch_get(struct snd_kcontrol *ctl, |
412 | struct snd_ctl_elem_value *value) | 443 | struct snd_ctl_elem_value *value) |
413 | { | 444 | { |
@@ -620,6 +651,13 @@ static const struct snd_kcontrol_new controls[] = { | |||
620 | .info = spdif_info, | 651 | .info = spdif_info, |
621 | .get = spdif_input_default_get, | 652 | .get = spdif_input_default_get, |
622 | }, | 653 | }, |
654 | { | ||
655 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
656 | .name = SNDRV_CTL_NAME_IEC958("Loopback ", NONE, SWITCH), | ||
657 | .info = snd_ctl_boolean_mono_info, | ||
658 | .get = spdif_loopback_get, | ||
659 | .put = spdif_loopback_put, | ||
660 | }, | ||
623 | }; | 661 | }; |
624 | 662 | ||
625 | static const struct snd_kcontrol_new ac97_controls[] = { | 663 | static const struct snd_kcontrol_new ac97_controls[] = { |