aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2007-07-27 13:02:40 -0400
committerJaroslav Kysela <perex@perex.cz>2007-10-16 09:58:11 -0400
commit532d5381793f3c824f8ff68d7067fab8c76bb811 (patch)
tree41a27e08a905c28576167b711ccc2b06ea234a9f
parent2807314d467e7dd929c42050031aabbd28e78f0b (diff)
[ALSA] hda-codec - Add a generic bind-control helper
Added callbacks for a generic bind-control of mixer elements. This can be used for creating a mixer element controlling multiple widgets at the same time. Two macros, HDA_BIND_VOL() and HDA_BIND_SW(), are introduced for creating bind-volume and bind-switch, respectively. It taks the mixer element name and struct hda_bind_ctls pointer, which contains the real control callbacks in ops field and long array for private_value of each bound widget. All widgets have to be the same type (i.e. the same amp capability). Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
-rw-r--r--sound/pci/hda/hda_codec.c87
-rw-r--r--sound/pci/hda/hda_local.h47
-rw-r--r--sound/pci/hda/patch_analog.c177
-rw-r--r--sound/pci/hda/patch_realtek.c28
4 files changed, 184 insertions, 155 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index e7843ffeeb2f..36879a93eac4 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1006,6 +1006,93 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
1006} 1006}
1007 1007
1008/* 1008/*
1009 * generic bound volume/swtich controls
1010 */
1011int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
1012 struct snd_ctl_elem_info *uinfo)
1013{
1014 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1015 struct hda_bind_ctls *c;
1016 int err;
1017
1018 c = (struct hda_bind_ctls *)kcontrol->private_value;
1019 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1020 kcontrol->private_value = *c->values;
1021 err = c->ops->info(kcontrol, uinfo);
1022 kcontrol->private_value = (long)c;
1023 mutex_unlock(&codec->spdif_mutex);
1024 return err;
1025}
1026
1027int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
1028 struct snd_ctl_elem_value *ucontrol)
1029{
1030 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1031 struct hda_bind_ctls *c;
1032 int err;
1033
1034 c = (struct hda_bind_ctls *)kcontrol->private_value;
1035 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1036 kcontrol->private_value = *c->values;
1037 err = c->ops->get(kcontrol, ucontrol);
1038 kcontrol->private_value = (long)c;
1039 mutex_unlock(&codec->spdif_mutex);
1040 return err;
1041}
1042
1043int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
1044 struct snd_ctl_elem_value *ucontrol)
1045{
1046 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1047 struct hda_bind_ctls *c;
1048 unsigned long *vals;
1049 int err = 0, change = 0;
1050
1051 c = (struct hda_bind_ctls *)kcontrol->private_value;
1052 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1053 for (vals = c->values; *vals; vals++) {
1054 kcontrol->private_value = *vals;
1055 err = c->ops->put(kcontrol, ucontrol);
1056 if (err < 0)
1057 break;
1058 change |= err;
1059 }
1060 kcontrol->private_value = (long)c;
1061 mutex_unlock(&codec->spdif_mutex);
1062 return err < 0 ? err : change;
1063}
1064
1065int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1066 unsigned int size, unsigned int __user *tlv)
1067{
1068 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1069 struct hda_bind_ctls *c;
1070 int err;
1071
1072 c = (struct hda_bind_ctls *)kcontrol->private_value;
1073 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1074 kcontrol->private_value = *c->values;
1075 err = c->ops->tlv(kcontrol, op_flag, size, tlv);
1076 kcontrol->private_value = (long)c;
1077 mutex_unlock(&codec->spdif_mutex);
1078 return err;
1079}
1080
1081struct hda_ctl_ops snd_hda_bind_vol = {
1082 .info = snd_hda_mixer_amp_volume_info,
1083 .get = snd_hda_mixer_amp_volume_get,
1084 .put = snd_hda_mixer_amp_volume_put,
1085 .tlv = snd_hda_mixer_amp_tlv
1086};
1087
1088struct hda_ctl_ops snd_hda_bind_sw = {
1089 .info = snd_hda_mixer_amp_switch_info,
1090 .get = snd_hda_mixer_amp_switch_get,
1091 .put = snd_hda_mixer_amp_switch_put,
1092 .tlv = snd_hda_mixer_amp_tlv
1093};
1094
1095/*
1009 * SPDIF out controls 1096 * SPDIF out controls
1010 */ 1097 */
1011 1098
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 12428a67eb2a..fafcffe6fc79 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -102,6 +102,53 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,
102int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, 102int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
103 struct snd_ctl_elem_value *ucontrol); 103 struct snd_ctl_elem_value *ucontrol);
104 104
105/* more generic bound controls */
106struct hda_ctl_ops {
107 snd_kcontrol_info_t *info;
108 snd_kcontrol_get_t *get;
109 snd_kcontrol_put_t *put;
110 snd_kcontrol_tlv_rw_t *tlv;
111};
112
113extern struct hda_ctl_ops snd_hda_bind_vol; /* for bind-volume with TLV */
114extern struct hda_ctl_ops snd_hda_bind_sw; /* for bind-switch */
115
116struct hda_bind_ctls {
117 struct hda_ctl_ops *ops;
118 long values[];
119};
120
121int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
122 struct snd_ctl_elem_info *uinfo);
123int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
124 struct snd_ctl_elem_value *ucontrol);
125int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
126 struct snd_ctl_elem_value *ucontrol);
127int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
128 unsigned int size, unsigned int __user *tlv);
129
130#define HDA_BIND_VOL(xname, bindrec) \
131 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
132 .name = xname, \
133 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
134 SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
135 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,\
136 .info = snd_hda_mixer_bind_ctls_info,\
137 .get = snd_hda_mixer_bind_ctls_get,\
138 .put = snd_hda_mixer_bind_ctls_put,\
139 .tlv = { .c = snd_hda_mixer_bind_tlv },\
140 .private_value = (long) (bindrec) }
141#define HDA_BIND_SW(xname, bindrec) \
142 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\
143 .name = xname, \
144 .info = snd_hda_mixer_bind_ctls_info,\
145 .get = snd_hda_mixer_bind_ctls_get,\
146 .put = snd_hda_mixer_bind_ctls_put,\
147 .private_value = (long) (bindrec) }
148
149/*
150 * SPDIF I/O
151 */
105int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid); 152int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid);
106int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid); 153int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
107 154
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 488724f2e304..cc2e944cc59f 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -422,94 +422,36 @@ static struct hda_input_mux ad1986a_capture_source = {
422 }, 422 },
423}; 423};
424 424
425/*
426 * PCM control
427 *
428 * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
429 */
430
431#define ad1986a_pcm_amp_vol_info snd_hda_mixer_amp_volume_info
432
433static int ad1986a_pcm_amp_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
434{
435 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
436 struct ad198x_spec *ad = codec->spec;
437
438 mutex_lock(&ad->amp_mutex);
439 snd_hda_mixer_amp_volume_get(kcontrol, ucontrol);
440 mutex_unlock(&ad->amp_mutex);
441 return 0;
442}
443 425
444static int ad1986a_pcm_amp_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 426static struct hda_bind_ctls ad1986a_bind_pcm_vol = {
445{ 427 .ops = &snd_hda_bind_vol,
446 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 428 .values = {
447 struct ad198x_spec *ad = codec->spec; 429 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
448 int i, change = 0; 430 HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
449 431 HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
450 mutex_lock(&ad->amp_mutex); 432 0
451 for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) { 433 },
452 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT); 434};
453 change |= snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
454 }
455 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT);
456 mutex_unlock(&ad->amp_mutex);
457 return change;
458}
459
460#define ad1986a_pcm_amp_sw_info snd_hda_mixer_amp_switch_info
461
462static int ad1986a_pcm_amp_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
463{
464 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
465 struct ad198x_spec *ad = codec->spec;
466
467 mutex_lock(&ad->amp_mutex);
468 snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
469 mutex_unlock(&ad->amp_mutex);
470 return 0;
471}
472
473static int ad1986a_pcm_amp_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
474{
475 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
476 struct ad198x_spec *ad = codec->spec;
477 int i, change = 0;
478 435
479 mutex_lock(&ad->amp_mutex); 436static struct hda_bind_ctls ad1986a_bind_pcm_sw = {
480 for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) { 437 .ops = &snd_hda_bind_sw,
481 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT); 438 .values = {
482 change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); 439 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
483 } 440 HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
484 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT); 441 HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
485 mutex_unlock(&ad->amp_mutex); 442 0
486 return change; 443 },
487} 444};
488 445
489/* 446/*
490 * mixers 447 * mixers
491 */ 448 */
492static struct snd_kcontrol_new ad1986a_mixers[] = { 449static struct snd_kcontrol_new ad1986a_mixers[] = {
493 { 450 /*
494 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 451 * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
495 .name = "PCM Playback Volume", 452 */
496 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 453 HDA_BIND_VOL("PCM Playback Volume", &ad1986a_bind_pcm_vol),
497 SNDRV_CTL_ELEM_ACCESS_TLV_READ | 454 HDA_BIND_SW("PCM Playback Switch", &ad1986a_bind_pcm_sw),
498 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
499 .info = ad1986a_pcm_amp_vol_info,
500 .get = ad1986a_pcm_amp_vol_get,
501 .put = ad1986a_pcm_amp_vol_put,
502 .tlv = { .c = snd_hda_mixer_amp_tlv },
503 .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
504 },
505 {
506 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
507 .name = "PCM Playback Switch",
508 .info = ad1986a_pcm_amp_sw_info,
509 .get = ad1986a_pcm_amp_sw_get,
510 .put = ad1986a_pcm_amp_sw_put,
511 .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
512 },
513 HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 455 HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
514 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 456 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
515 HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT), 457 HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
@@ -596,41 +538,23 @@ static struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
596/* laptop-eapd model - 2ch only */ 538/* laptop-eapd model - 2ch only */
597 539
598/* master controls both pins 0x1a and 0x1b */ 540/* master controls both pins 0x1a and 0x1b */
599static int ad1986a_laptop_master_vol_put(struct snd_kcontrol *kcontrol, 541static struct hda_bind_ctls ad1986a_laptop_master_vol = {
600 struct snd_ctl_elem_value *ucontrol) 542 .ops = &snd_hda_bind_vol,
601{ 543 .values = {
602 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 544 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
603 long *valp = ucontrol->value.integer.value; 545 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
604 int change; 546 0,
605 547 },
606 change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, 548};
607 0x7f, valp[0] & 0x7f);
608 change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0,
609 0x7f, valp[1] & 0x7f);
610 snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
611 0x7f, valp[0] & 0x7f);
612 snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
613 0x7f, valp[1] & 0x7f);
614 return change;
615}
616
617static int ad1986a_laptop_master_sw_put(struct snd_kcontrol *kcontrol,
618 struct snd_ctl_elem_value *ucontrol)
619{
620 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
621 long *valp = ucontrol->value.integer.value;
622 int change;
623 549
624 change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, 550static struct hda_bind_ctls ad1986a_laptop_master_sw = {
625 0x80, valp[0] ? 0 : 0x80); 551 .ops = &snd_hda_bind_sw,
626 change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, 552 .values = {
627 0x80, valp[1] ? 0 : 0x80); 553 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
628 snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, 554 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
629 0x80, valp[0] ? 0 : 0x80); 555 0,
630 snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, 556 },
631 0x80, valp[1] ? 0 : 0x80); 557};
632 return change;
633}
634 558
635static struct hda_input_mux ad1986a_laptop_eapd_capture_source = { 559static struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
636 .num_items = 3, 560 .num_items = 3,
@@ -642,23 +566,8 @@ static struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
642}; 566};
643 567
644static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { 568static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
645 { 569 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
646 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 570 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
647 .name = "Master Playback Volume",
648 .info = snd_hda_mixer_amp_volume_info,
649 .get = snd_hda_mixer_amp_volume_get,
650 .put = ad1986a_laptop_master_vol_put,
651 .tlv = { .c = snd_hda_mixer_amp_tlv },
652 .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
653 },
654 {
655 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
656 .name = "Master Playback Switch",
657 .info = snd_hda_mixer_amp_switch_info,
658 .get = snd_hda_mixer_amp_switch_get,
659 .put = ad1986a_laptop_master_sw_put,
660 .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
661 },
662 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), 571 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
663 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), 572 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
664 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT), 573 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT),
@@ -856,7 +765,6 @@ static int patch_ad1986a(struct hda_codec *codec)
856 if (spec == NULL) 765 if (spec == NULL)
857 return -ENOMEM; 766 return -ENOMEM;
858 767
859 mutex_init(&spec->amp_mutex);
860 codec->spec = spec; 768 codec->spec = spec;
861 769
862 spec->multiout.max_channels = 6; 770 spec->multiout.max_channels = 6;
@@ -1064,7 +972,6 @@ static int patch_ad1983(struct hda_codec *codec)
1064 if (spec == NULL) 972 if (spec == NULL)
1065 return -ENOMEM; 973 return -ENOMEM;
1066 974
1067 mutex_init(&spec->amp_mutex);
1068 codec->spec = spec; 975 codec->spec = spec;
1069 976
1070 spec->multiout.max_channels = 2; 977 spec->multiout.max_channels = 2;
@@ -1466,7 +1373,6 @@ static int patch_ad1981(struct hda_codec *codec)
1466 if (spec == NULL) 1373 if (spec == NULL)
1467 return -ENOMEM; 1374 return -ENOMEM;
1468 1375
1469 mutex_init(&spec->amp_mutex);
1470 codec->spec = spec; 1376 codec->spec = spec;
1471 1377
1472 spec->multiout.max_channels = 2; 1378 spec->multiout.max_channels = 2;
@@ -2672,7 +2578,6 @@ static int patch_ad1988(struct hda_codec *codec)
2672 if (spec == NULL) 2578 if (spec == NULL)
2673 return -ENOMEM; 2579 return -ENOMEM;
2674 2580
2675 mutex_init(&spec->amp_mutex);
2676 codec->spec = spec; 2581 codec->spec = spec;
2677 2582
2678 if (is_rev2(codec)) 2583 if (is_rev2(codec))
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index d839d567f8e4..f27e073d22b1 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -7140,28 +7140,18 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7140 { } /* end */ 7140 { } /* end */
7141}; 7141};
7142 7142
7143static int alc262_sony_sw_put(struct snd_kcontrol *kcontrol, 7143static struct hda_bind_ctls alc262_sony_bind_sw = {
7144 struct snd_ctl_elem_value *ucontrol) 7144 .ops = &snd_hda_bind_sw,
7145{ 7145 .values = {
7146 unsigned long private_save = kcontrol->private_value; 7146 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7147 int change; 7147 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7148 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT); 7148 0,
7149 change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); 7149 },
7150 kcontrol->private_value = private_save; 7150};
7151 change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
7152 return change;
7153}
7154 7151
7155static struct snd_kcontrol_new alc262_sony_mixer[] = { 7152static struct snd_kcontrol_new alc262_sony_mixer[] = {
7156 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7153 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7157 { 7154 HDA_BIND_SW("Front Playback Switch", &alc262_sony_bind_sw),
7158 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7159 .name = "Front Playback Switch",
7160 .info = snd_hda_mixer_amp_switch_info,
7161 .get = snd_hda_mixer_amp_switch_get,
7162 .put = alc262_sony_sw_put,
7163 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7164 },
7165 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7155 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7166 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7156 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7167 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7157 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),