Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[ALSA] Enable capture from line-in and CD on Revolution 5.1

Enable capture from line-in and CD on the Revolution 5.1 card.
This patch adds support for switching between the 5 input channels of
the AK5365 ADC and modifies the Revolution 5.1 driver to make use of
this facility. Previously the capture channel was fixed to channel 0
(microphone on the Revolution 5.1 card).

Signed-off-by: Jochen Voss <voss@seehuhn.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>

authored by

Jochen Voss and committed by
Jaroslav Kysela
a58e7cb1 e4f8e656

+94 -3
+2
include/sound/ak4xxx-adda.h
··· 50 50 char *name; /* capture gain volume label */ 51 51 char *switch_name; /* capture switch */ 52 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 55 57 struct snd_akm4xxx {
+83 -2
sound/i2c/other/ak4xxx-adda.c
··· 513 513 return change; 514 514 } 515 515 516 + #define AK5365_NUM_INPUTS 5 517 + 518 + static 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 + 543 + static 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 + 557 + static 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 577 * build AK4xxx controls 518 578 */ ··· 707 647 708 648 if (ak->type == SND_AK5365 && (idx % 2) == 0) { 709 649 if (! ak->adc_info || 710 - ! ak->adc_info[mixer_ch].switch_name) 650 + ! ak->adc_info[mixer_ch].switch_name) { 711 651 knew.name = "Capture Switch"; 712 - else 652 + knew.index = mixer_ch + ak->idx_offset * 2; 653 + } else 713 654 knew.name = ak->adc_info[mixer_ch].switch_name; 714 655 knew.info = ak4xxx_switch_info; 715 656 knew.get = ak4xxx_switch_get; ··· 720 659 1 = mute */ 721 660 knew.private_value = 722 661 AK_COMPOSE(idx/2, 2, 0, 0) | AK_INVERT; 662 + err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak)); 663 + if (err < 0) 664 + return err; 665 + 666 + memset(&knew, 0, sizeof(knew)); 667 + knew.name = ak->adc_info[mixer_ch].selector_name; 668 + if (!knew.name) { 669 + knew.name = "Capture Channel"; 670 + knew.index = mixer_ch + ak->idx_offset * 2; 671 + } 672 + 673 + knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 674 + knew.info = ak4xxx_capture_source_info; 675 + knew.get = ak4xxx_capture_source_get; 676 + knew.put = ak4xxx_capture_source_put; 677 + knew.access = 0; 678 + /* input selector control: reg. 1, bits 0-2. 679 + * mis-use 'shift' to pass mixer_ch */ 680 + knew.private_value 681 + = AK_COMPOSE(idx/2, 1, mixer_ch, 0x07); 723 682 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak)); 724 683 if (err < 0) 725 684 return err;
+9 -1
sound/pci/ice1712/revo.c
··· 107 107 AK_DAC("PCM Rear Playback Volume", 2), 108 108 }; 109 109 110 + static const char *revo51_adc_input_names[] = { 111 + "Mic", 112 + "Line", 113 + "CD", 114 + NULL 115 + }; 116 + 110 117 static struct snd_akm4xxx_adc_channel revo51_adc[] = { 111 118 { 112 119 .name = "PCM Capture Volume", 113 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