diff options
Diffstat (limited to 'drivers/media/video/cx88/cx88-alsa.c')
-rw-r--r-- | drivers/media/video/cx88/cx88-alsa.c | 86 |
1 files changed, 73 insertions, 13 deletions
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index 141dadf7cf1b..40ffd7a5579a 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <sound/pcm_params.h> | 39 | #include <sound/pcm_params.h> |
40 | #include <sound/control.h> | 40 | #include <sound/control.h> |
41 | #include <sound/initval.h> | 41 | #include <sound/initval.h> |
42 | #include <sound/tlv.h> | ||
42 | 43 | ||
43 | #include "cx88.h" | 44 | #include "cx88.h" |
44 | #include "cx88-reg.h" | 45 | #include "cx88-reg.h" |
@@ -82,6 +83,7 @@ typedef struct cx88_audio_dev snd_cx88_card_t; | |||
82 | 83 | ||
83 | 84 | ||
84 | 85 | ||
86 | |||
85 | /**************************************************************************** | 87 | /**************************************************************************** |
86 | Module global static vars | 88 | Module global static vars |
87 | ****************************************************************************/ | 89 | ****************************************************************************/ |
@@ -545,8 +547,8 @@ static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name) | |||
545 | /**************************************************************************** | 547 | /**************************************************************************** |
546 | CONTROL INTERFACE | 548 | CONTROL INTERFACE |
547 | ****************************************************************************/ | 549 | ****************************************************************************/ |
548 | static int snd_cx88_capture_volume_info(struct snd_kcontrol *kcontrol, | 550 | static int snd_cx88_volume_info(struct snd_kcontrol *kcontrol, |
549 | struct snd_ctl_elem_info *info) | 551 | struct snd_ctl_elem_info *info) |
550 | { | 552 | { |
551 | info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 553 | info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
552 | info->count = 2; | 554 | info->count = 2; |
@@ -556,9 +558,8 @@ static int snd_cx88_capture_volume_info(struct snd_kcontrol *kcontrol, | |||
556 | return 0; | 558 | return 0; |
557 | } | 559 | } |
558 | 560 | ||
559 | /* OK - TODO: test it */ | 561 | static int snd_cx88_volume_get(struct snd_kcontrol *kcontrol, |
560 | static int snd_cx88_capture_volume_get(struct snd_kcontrol *kcontrol, | 562 | struct snd_ctl_elem_value *value) |
561 | struct snd_ctl_elem_value *value) | ||
562 | { | 563 | { |
563 | snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); | 564 | snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); |
564 | struct cx88_core *core=chip->core; | 565 | struct cx88_core *core=chip->core; |
@@ -573,8 +574,8 @@ static int snd_cx88_capture_volume_get(struct snd_kcontrol *kcontrol, | |||
573 | } | 574 | } |
574 | 575 | ||
575 | /* OK - TODO: test it */ | 576 | /* OK - TODO: test it */ |
576 | static int snd_cx88_capture_volume_put(struct snd_kcontrol *kcontrol, | 577 | static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol, |
577 | struct snd_ctl_elem_value *value) | 578 | struct snd_ctl_elem_value *value) |
578 | { | 579 | { |
579 | snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); | 580 | snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); |
580 | struct cx88_core *core=chip->core; | 581 | struct cx88_core *core=chip->core; |
@@ -605,14 +606,67 @@ static int snd_cx88_capture_volume_put(struct snd_kcontrol *kcontrol, | |||
605 | return changed; | 606 | return changed; |
606 | } | 607 | } |
607 | 608 | ||
608 | static struct snd_kcontrol_new snd_cx88_capture_volume = { | 609 | static const DECLARE_TLV_DB_SCALE(snd_cx88_db_scale, -6300, 100, 0); |
610 | |||
611 | static struct snd_kcontrol_new snd_cx88_volume = { | ||
612 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
613 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
614 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, | ||
615 | .name = "Playback Volume", | ||
616 | .info = snd_cx88_volume_info, | ||
617 | .get = snd_cx88_volume_get, | ||
618 | .put = snd_cx88_volume_put, | ||
619 | .tlv.p = snd_cx88_db_scale, | ||
620 | }; | ||
621 | |||
622 | static int snd_cx88_switch_get(struct snd_kcontrol *kcontrol, | ||
623 | struct snd_ctl_elem_value *value) | ||
624 | { | ||
625 | snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); | ||
626 | struct cx88_core *core = chip->core; | ||
627 | u32 bit = kcontrol->private_value; | ||
628 | |||
629 | value->value.integer.value[0] = !(cx_read(AUD_VOL_CTL) & bit); | ||
630 | return 0; | ||
631 | } | ||
632 | |||
633 | static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol, | ||
634 | struct snd_ctl_elem_value *value) | ||
635 | { | ||
636 | snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); | ||
637 | struct cx88_core *core = chip->core; | ||
638 | u32 bit = kcontrol->private_value; | ||
639 | int ret = 0; | ||
640 | u32 vol; | ||
641 | |||
642 | spin_lock_irq(&chip->reg_lock); | ||
643 | vol = cx_read(AUD_VOL_CTL); | ||
644 | if (value->value.integer.value[0] != !(vol & bit)) { | ||
645 | vol ^= bit; | ||
646 | cx_write(AUD_VOL_CTL, vol); | ||
647 | ret = 1; | ||
648 | } | ||
649 | spin_unlock_irq(&chip->reg_lock); | ||
650 | return ret; | ||
651 | } | ||
652 | |||
653 | static struct snd_kcontrol_new snd_cx88_dac_switch = { | ||
609 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 654 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
610 | .name = "Capture Volume", | 655 | .name = "Playback Switch", |
611 | .info = snd_cx88_capture_volume_info, | 656 | .info = snd_ctl_boolean_mono_info, |
612 | .get = snd_cx88_capture_volume_get, | 657 | .get = snd_cx88_switch_get, |
613 | .put = snd_cx88_capture_volume_put, | 658 | .put = snd_cx88_switch_put, |
659 | .private_value = (1<<8), | ||
614 | }; | 660 | }; |
615 | 661 | ||
662 | static struct snd_kcontrol_new snd_cx88_source_switch = { | ||
663 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
664 | .name = "Capture Switch", | ||
665 | .info = snd_ctl_boolean_mono_info, | ||
666 | .get = snd_cx88_switch_get, | ||
667 | .put = snd_cx88_switch_put, | ||
668 | .private_value = (1<<6), | ||
669 | }; | ||
616 | 670 | ||
617 | /**************************************************************************** | 671 | /**************************************************************************** |
618 | Basic Flow for Sound Devices | 672 | Basic Flow for Sound Devices |
@@ -762,7 +816,13 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci, | |||
762 | if (err < 0) | 816 | if (err < 0) |
763 | goto error; | 817 | goto error; |
764 | 818 | ||
765 | err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_capture_volume, chip)); | 819 | err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_volume, chip)); |
820 | if (err < 0) | ||
821 | goto error; | ||
822 | err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_dac_switch, chip)); | ||
823 | if (err < 0) | ||
824 | goto error; | ||
825 | err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_source_switch, chip)); | ||
766 | if (err < 0) | 826 | if (err < 0) |
767 | goto error; | 827 | goto error; |
768 | 828 | ||