diff options
Diffstat (limited to 'sound/i2c/other')
-rw-r--r-- | sound/i2c/other/ak4xxx-adda.c | 72 |
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 | ||
475 | static 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 | |||
485 | static 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 | |||
501 | static 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) |