aboutsummaryrefslogtreecommitdiffstats
path: root/sound/i2c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/i2c')
-rw-r--r--sound/i2c/other/ak4xxx-adda.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c
index 7d562f084207..d76d8b078a81 100644
--- a/sound/i2c/other/ak4xxx-adda.c
+++ b/sound/i2c/other/ak4xxx-adda.c
@@ -472,6 +472,57 @@ static int snd_akm4xxx_deemphasis_put(struct snd_kcontrol *kcontrol,
472 return change; 472 return change;
473} 473}
474 474
475static int ak4xxx_switch_info(struct snd_kcontrol *kcontrol,
476 struct snd_ctl_elem_info *uinfo)
477{
478 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
479 uinfo->count = 1;
480 uinfo->value.integer.min = 0;
481 uinfo->value.integer.max = 1;
482 return 0;
483}
484
485static int ak4xxx_switch_get(struct snd_kcontrol *kcontrol,
486 struct snd_ctl_elem_value *ucontrol)
487{
488 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
489 int chip = AK_GET_CHIP(kcontrol->private_value);
490 int addr = AK_GET_ADDR(kcontrol->private_value);
491 int shift = AK_GET_SHIFT(kcontrol->private_value);
492 int invert = AK_GET_INVERT(kcontrol->private_value);
493 unsigned char val = snd_akm4xxx_get(ak, chip, addr);
494
495 if (invert)
496 val = ! val;
497 ucontrol->value.integer.value[0] = (val & (1<<shift)) != 0;
498 return 0;
499}
500
501static int ak4xxx_switch_put(struct snd_kcontrol *kcontrol,
502 struct snd_ctl_elem_value *ucontrol)
503{
504 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
505 int chip = AK_GET_CHIP(kcontrol->private_value);
506 int addr = AK_GET_ADDR(kcontrol->private_value);
507 int shift = AK_GET_SHIFT(kcontrol->private_value);
508 int invert = AK_GET_INVERT(kcontrol->private_value);
509 long flag = ucontrol->value.integer.value[0];
510 unsigned char val, oval;
511 int change;
512
513 if (invert)
514 flag = ! flag;
515 oval = snd_akm4xxx_get(ak, chip, addr);
516 if (flag)
517 val = oval | (1<<shift);
518 else
519 val = oval & ~(1<<shift);
520 change = (oval != val);
521 if (change)
522 snd_akm4xxx_write(ak, chip, addr, val);
523 return change;
524}
525
475/* 526/*
476 * build AK4xxx controls 527 * build AK4xxx controls
477 */ 528 */
@@ -621,6 +672,27 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak)
621 SNDRV_CTL_ELEM_ACCESS_WRITE)); 672 SNDRV_CTL_ELEM_ACCESS_WRITE));
622 if (err < 0) 673 if (err < 0)
623 goto __error; 674 goto __error;
675
676 memset(ctl, 0, sizeof(*ctl));
677 if (ak->channel_names == NULL)
678 strcpy(ctl->id.name, "Capture Switch");
679 else
680 strcpy(ctl->id.name, ak->channel_names[1]);
681 ctl->id.index = ak->idx_offset * 2;
682 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
683 ctl->count = 1;
684 ctl->info = ak4xxx_switch_info;
685 ctl->get = ak4xxx_switch_get;
686 ctl->put = ak4xxx_switch_put;
687 /* register 2, bit 0 (SMUTE): 0 = normal operation, 1 = mute */
688 ctl->private_value =
689 AK_COMPOSE(0, 2, 0, 0) | AK_INVERT;
690 ctl->private_data = ak;
691 err = snd_ctl_add(ak->card,
692 snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|
693 SNDRV_CTL_ELEM_ACCESS_WRITE));
694 if (err < 0)
695 goto __error;
624 } 696 }
625 697
626 if (ak->type == SND_AK4355 || ak->type == SND_AK4358) 698 if (ak->type == SND_AK4355 || ak->type == SND_AK4358)