aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/ak4xxx-adda.h2
-rw-r--r--sound/i2c/other/ak4xxx-adda.c85
-rw-r--r--sound/pci/ice1712/revo.c10
3 files changed, 94 insertions, 3 deletions
diff --git a/include/sound/ak4xxx-adda.h b/include/sound/ak4xxx-adda.h
index d0deca669b92..d01d53528015 100644
--- a/include/sound/ak4xxx-adda.h
+++ b/include/sound/ak4xxx-adda.h
@@ -50,6 +50,8 @@ struct snd_akm4xxx_adc_channel {
50 char *name; /* capture gain volume label */ 50 char *name; /* capture gain volume label */
51 char *switch_name; /* capture switch */ 51 char *switch_name; /* capture switch */
52 unsigned int num_channels; 52 unsigned int num_channels;
53 char *selector_name; /* capture source select label */
54 const char **input_names; /* capture source names (NULL terminated) */
53}; 55};
54 56
55struct snd_akm4xxx { 57struct snd_akm4xxx {
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c
index 5da49e2eb350..fe61b92f4e47 100644
--- a/sound/i2c/other/ak4xxx-adda.c
+++ b/sound/i2c/other/ak4xxx-adda.c
@@ -513,6 +513,66 @@ static int ak4xxx_switch_put(struct snd_kcontrol *kcontrol,
513 return change; 513 return change;
514} 514}
515 515
516#define AK5365_NUM_INPUTS 5
517
518static int ak4xxx_capture_source_info(struct snd_kcontrol *kcontrol,
519 struct snd_ctl_elem_info *uinfo)
520{
521 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
522 int mixer_ch = AK_GET_SHIFT(kcontrol->private_value);
523 const char **input_names;
524 int num_names, idx;
525
526 input_names = ak->adc_info[mixer_ch].input_names;
527
528 num_names = 0;
529 while (num_names < AK5365_NUM_INPUTS && input_names[num_names])
530 ++num_names;
531
532 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
533 uinfo->count = 1;
534 uinfo->value.enumerated.items = num_names;
535 idx = uinfo->value.enumerated.item;
536 if (idx >= num_names)
537 return -EINVAL;
538 strncpy(uinfo->value.enumerated.name, input_names[idx],
539 sizeof(uinfo->value.enumerated.name));
540 return 0;
541}
542
543static int ak4xxx_capture_source_get(struct snd_kcontrol *kcontrol,
544 struct snd_ctl_elem_value *ucontrol)
545{
546 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
547 int chip = AK_GET_CHIP(kcontrol->private_value);
548 int addr = AK_GET_ADDR(kcontrol->private_value);
549 int mask = AK_GET_MASK(kcontrol->private_value);
550 unsigned char val;
551
552 val = snd_akm4xxx_get(ak, chip, addr) & mask;
553 ucontrol->value.enumerated.item[0] = val;
554 return 0;
555}
556
557static int ak4xxx_capture_source_put(struct snd_kcontrol *kcontrol,
558 struct snd_ctl_elem_value *ucontrol)
559{
560 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
561 int chip = AK_GET_CHIP(kcontrol->private_value);
562 int addr = AK_GET_ADDR(kcontrol->private_value);
563 int mask = AK_GET_MASK(kcontrol->private_value);
564 unsigned char oval, val;
565
566 oval = snd_akm4xxx_get(ak, chip, addr);
567 val = oval & ~mask;
568 val |= ucontrol->value.enumerated.item[0] & mask;
569 if (val != oval) {
570 snd_akm4xxx_write(ak, chip, addr, val);
571 return 1;
572 }
573 return 0;
574}
575
516/* 576/*
517 * build AK4xxx controls 577 * build AK4xxx controls
518 */ 578 */
@@ -647,9 +707,10 @@ static int build_adc_controls(struct snd_akm4xxx *ak)
647 707
648 if (ak->type == SND_AK5365 && (idx % 2) == 0) { 708 if (ak->type == SND_AK5365 && (idx % 2) == 0) {
649 if (! ak->adc_info || 709 if (! ak->adc_info ||
650 ! ak->adc_info[mixer_ch].switch_name) 710 ! ak->adc_info[mixer_ch].switch_name) {
651 knew.name = "Capture Switch"; 711 knew.name = "Capture Switch";
652 else 712 knew.index = mixer_ch + ak->idx_offset * 2;
713 } else
653 knew.name = ak->adc_info[mixer_ch].switch_name; 714 knew.name = ak->adc_info[mixer_ch].switch_name;
654 knew.info = ak4xxx_switch_info; 715 knew.info = ak4xxx_switch_info;
655 knew.get = ak4xxx_switch_get; 716 knew.get = ak4xxx_switch_get;
@@ -662,6 +723,26 @@ static int build_adc_controls(struct snd_akm4xxx *ak)
662 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak)); 723 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
663 if (err < 0) 724 if (err < 0)
664 return err; 725 return err;
726
727 memset(&knew, 0, sizeof(knew));
728 knew.name = ak->adc_info[mixer_ch].selector_name;
729 if (!knew.name) {
730 knew.name = "Capture Channel";
731 knew.index = mixer_ch + ak->idx_offset * 2;
732 }
733
734 knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
735 knew.info = ak4xxx_capture_source_info;
736 knew.get = ak4xxx_capture_source_get;
737 knew.put = ak4xxx_capture_source_put;
738 knew.access = 0;
739 /* input selector control: reg. 1, bits 0-2.
740 * mis-use 'shift' to pass mixer_ch */
741 knew.private_value
742 = AK_COMPOSE(idx/2, 1, mixer_ch, 0x07);
743 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
744 if (err < 0)
745 return err;
665 } 746 }
666 747
667 idx += num_stereo; 748 idx += num_stereo;
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c
index bf98ea34feb0..d556de59b9ae 100644
--- a/sound/pci/ice1712/revo.c
+++ b/sound/pci/ice1712/revo.c
@@ -107,11 +107,19 @@ static struct snd_akm4xxx_dac_channel revo51_dac[] = {
107 AK_DAC("PCM Rear Playback Volume", 2), 107 AK_DAC("PCM Rear Playback Volume", 2),
108}; 108};
109 109
110static const char *revo51_adc_input_names[] = {
111 "Mic",
112 "Line",
113 "CD",
114 NULL
115};
116
110static struct snd_akm4xxx_adc_channel revo51_adc[] = { 117static struct snd_akm4xxx_adc_channel revo51_adc[] = {
111 { 118 {
112 .name = "PCM Capture Volume", 119 .name = "PCM Capture Volume",
113 .switch_name = "PCM Capture Switch", 120 .switch_name = "PCM Capture Switch",
114 .num_channels = 2 121 .num_channels = 2,
122 .input_names = revo51_adc_input_names
115 }, 123 },
116}; 124};
117 125