0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "ac97_local.h"
0012 #include "ac97_patch.h"
0013
0014
0015
0016
0017
0018 static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97,
0019 const char *name);
0020 static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name,
0021 const unsigned int *tlv,
0022 const char * const *followers);
0023
0024
0025
0026
0027
0028 static int patch_build_controls(struct snd_ac97 * ac97, const struct snd_kcontrol_new *controls, int count)
0029 {
0030 int idx, err;
0031
0032 for (idx = 0; idx < count; idx++) {
0033 err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&controls[idx], ac97));
0034 if (err < 0)
0035 return err;
0036 }
0037 return 0;
0038 }
0039
0040
0041 static void reset_tlv(struct snd_ac97 *ac97, const char *name,
0042 const unsigned int *tlv)
0043 {
0044 struct snd_ctl_elem_id sid;
0045 struct snd_kcontrol *kctl;
0046 memset(&sid, 0, sizeof(sid));
0047 strcpy(sid.name, name);
0048 sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
0049 kctl = snd_ctl_find_id(ac97->bus->card, &sid);
0050 if (kctl && kctl->tlv.p)
0051 kctl->tlv.p = tlv;
0052 }
0053
0054
0055 static int ac97_update_bits_page(struct snd_ac97 *ac97, unsigned short reg, unsigned short mask, unsigned short value, unsigned short page)
0056 {
0057 unsigned short page_save;
0058 int ret;
0059
0060 mutex_lock(&ac97->page_mutex);
0061 page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
0062 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page);
0063 ret = snd_ac97_update_bits(ac97, reg, mask, value);
0064 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save);
0065 mutex_unlock(&ac97->page_mutex);
0066 return ret;
0067 }
0068
0069
0070
0071
0072 static int ac97_surround_jack_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
0073 {
0074 static const char * const texts[] = { "Shared", "Independent" };
0075
0076 return snd_ctl_enum_info(uinfo, 1, 2, texts);
0077 }
0078
0079 static int ac97_surround_jack_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0080 {
0081 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
0082
0083 ucontrol->value.enumerated.item[0] = ac97->indep_surround;
0084 return 0;
0085 }
0086
0087 static int ac97_surround_jack_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0088 {
0089 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
0090 unsigned char indep = !!ucontrol->value.enumerated.item[0];
0091
0092 if (indep != ac97->indep_surround) {
0093 ac97->indep_surround = indep;
0094 if (ac97->build_ops->update_jacks)
0095 ac97->build_ops->update_jacks(ac97);
0096 return 1;
0097 }
0098 return 0;
0099 }
0100
0101 static int ac97_channel_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
0102 {
0103 static const char * const texts[] = { "2ch", "4ch", "6ch", "8ch" };
0104
0105 return snd_ctl_enum_info(uinfo, 1, kcontrol->private_value, texts);
0106 }
0107
0108 static int ac97_channel_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0109 {
0110 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
0111
0112 ucontrol->value.enumerated.item[0] = ac97->channel_mode;
0113 return 0;
0114 }
0115
0116 static int ac97_channel_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0117 {
0118 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
0119 unsigned char mode = ucontrol->value.enumerated.item[0];
0120
0121 if (mode >= kcontrol->private_value)
0122 return -EINVAL;
0123
0124 if (mode != ac97->channel_mode) {
0125 ac97->channel_mode = mode;
0126 if (ac97->build_ops->update_jacks)
0127 ac97->build_ops->update_jacks(ac97);
0128 return 1;
0129 }
0130 return 0;
0131 }
0132
0133 #define AC97_SURROUND_JACK_MODE_CTL \
0134 { \
0135 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
0136 .name = "Surround Jack Mode", \
0137 .info = ac97_surround_jack_mode_info, \
0138 .get = ac97_surround_jack_mode_get, \
0139 .put = ac97_surround_jack_mode_put, \
0140 }
0141
0142 #define AC97_CHANNEL_MODE_CTL \
0143 { \
0144 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
0145 .name = "Channel Mode", \
0146 .info = ac97_channel_mode_info, \
0147 .get = ac97_channel_mode_get, \
0148 .put = ac97_channel_mode_put, \
0149 .private_value = 3, \
0150 }
0151
0152 #define AC97_CHANNEL_MODE_4CH_CTL \
0153 { \
0154 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
0155 .name = "Channel Mode", \
0156 .info = ac97_channel_mode_info, \
0157 .get = ac97_channel_mode_get, \
0158 .put = ac97_channel_mode_put, \
0159 .private_value = 2, \
0160 }
0161
0162 #define AC97_CHANNEL_MODE_8CH_CTL \
0163 { \
0164 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
0165 .name = "Channel Mode", \
0166 .info = ac97_channel_mode_info, \
0167 .get = ac97_channel_mode_get, \
0168 .put = ac97_channel_mode_put, \
0169 .private_value = 4, \
0170 }
0171
0172 static inline int is_surround_on(struct snd_ac97 *ac97)
0173 {
0174 return ac97->channel_mode >= 1;
0175 }
0176
0177 static inline int is_clfe_on(struct snd_ac97 *ac97)
0178 {
0179 return ac97->channel_mode >= 2;
0180 }
0181
0182
0183 static inline int is_shared_surrout(struct snd_ac97 *ac97)
0184 {
0185 return !ac97->indep_surround && is_surround_on(ac97);
0186 }
0187
0188
0189 static inline int is_shared_clfeout(struct snd_ac97 *ac97)
0190 {
0191 return !ac97->indep_surround && is_clfe_on(ac97);
0192 }
0193
0194
0195 static inline int is_shared_linein(struct snd_ac97 *ac97)
0196 {
0197 return !ac97->indep_surround && !is_surround_on(ac97);
0198 }
0199
0200
0201 static inline int is_shared_micin(struct snd_ac97 *ac97)
0202 {
0203 return !ac97->indep_surround && !is_clfe_on(ac97);
0204 }
0205
0206 static inline int alc850_is_aux_back_surround(struct snd_ac97 *ac97)
0207 {
0208 return is_surround_on(ac97);
0209 }
0210
0211
0212
0213
0214
0215
0216
0217 static int snd_ac97_ymf7x3_info_speaker(struct snd_kcontrol *kcontrol,
0218 struct snd_ctl_elem_info *uinfo)
0219 {
0220 static const char * const texts[3] = {
0221 "Standard", "Small", "Smaller"
0222 };
0223
0224 return snd_ctl_enum_info(uinfo, 1, 3, texts);
0225 }
0226
0227 static int snd_ac97_ymf7x3_get_speaker(struct snd_kcontrol *kcontrol,
0228 struct snd_ctl_elem_value *ucontrol)
0229 {
0230 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
0231 unsigned short val;
0232
0233 val = ac97->regs[AC97_YMF7X3_3D_MODE_SEL];
0234 val = (val >> 10) & 3;
0235 if (val > 0)
0236 val--;
0237 ucontrol->value.enumerated.item[0] = val;
0238 return 0;
0239 }
0240
0241 static int snd_ac97_ymf7x3_put_speaker(struct snd_kcontrol *kcontrol,
0242 struct snd_ctl_elem_value *ucontrol)
0243 {
0244 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
0245 unsigned short val;
0246
0247 if (ucontrol->value.enumerated.item[0] > 2)
0248 return -EINVAL;
0249 val = (ucontrol->value.enumerated.item[0] + 1) << 10;
0250 return snd_ac97_update(ac97, AC97_YMF7X3_3D_MODE_SEL, val);
0251 }
0252
0253 static const struct snd_kcontrol_new snd_ac97_ymf7x3_controls_speaker =
0254 {
0255 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0256 .name = "3D Control - Speaker",
0257 .info = snd_ac97_ymf7x3_info_speaker,
0258 .get = snd_ac97_ymf7x3_get_speaker,
0259 .put = snd_ac97_ymf7x3_put_speaker,
0260 };
0261
0262
0263
0264 static int snd_ac97_ymf7x3_spdif_source_info(struct snd_kcontrol *kcontrol,
0265 struct snd_ctl_elem_info *uinfo)
0266 {
0267 static const char * const texts[2] = { "AC-Link", "A/D Converter" };
0268
0269 return snd_ctl_enum_info(uinfo, 1, 2, texts);
0270 }
0271
0272 static int snd_ac97_ymf7x3_spdif_source_get(struct snd_kcontrol *kcontrol,
0273 struct snd_ctl_elem_value *ucontrol)
0274 {
0275 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
0276 unsigned short val;
0277
0278 val = ac97->regs[AC97_YMF7X3_DIT_CTRL];
0279 ucontrol->value.enumerated.item[0] = (val >> 1) & 1;
0280 return 0;
0281 }
0282
0283 static int snd_ac97_ymf7x3_spdif_source_put(struct snd_kcontrol *kcontrol,
0284 struct snd_ctl_elem_value *ucontrol)
0285 {
0286 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
0287 unsigned short val;
0288
0289 if (ucontrol->value.enumerated.item[0] > 1)
0290 return -EINVAL;
0291 val = ucontrol->value.enumerated.item[0] << 1;
0292 return snd_ac97_update_bits(ac97, AC97_YMF7X3_DIT_CTRL, 0x0002, val);
0293 }
0294
0295 static int patch_yamaha_ymf7x3_3d(struct snd_ac97 *ac97)
0296 {
0297 struct snd_kcontrol *kctl;
0298 int err;
0299
0300 kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97);
0301 err = snd_ctl_add(ac97->bus->card, kctl);
0302 if (err < 0)
0303 return err;
0304 strcpy(kctl->id.name, "3D Control - Wide");
0305 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 9, 7, 0);
0306 snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
0307 err = snd_ctl_add(ac97->bus->card,
0308 snd_ac97_cnew(&snd_ac97_ymf7x3_controls_speaker,
0309 ac97));
0310 if (err < 0)
0311 return err;
0312 snd_ac97_write_cache(ac97, AC97_YMF7X3_3D_MODE_SEL, 0x0c00);
0313 return 0;
0314 }
0315
0316 static const struct snd_kcontrol_new snd_ac97_yamaha_ymf743_controls_spdif[3] =
0317 {
0318 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
0319 AC97_YMF7X3_DIT_CTRL, 0, 1, 0),
0320 {
0321 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0322 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Source",
0323 .info = snd_ac97_ymf7x3_spdif_source_info,
0324 .get = snd_ac97_ymf7x3_spdif_source_get,
0325 .put = snd_ac97_ymf7x3_spdif_source_put,
0326 },
0327 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE, NONE) "Mute",
0328 AC97_YMF7X3_DIT_CTRL, 2, 1, 1)
0329 };
0330
0331 static int patch_yamaha_ymf743_build_spdif(struct snd_ac97 *ac97)
0332 {
0333 int err;
0334
0335 err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3);
0336 if (err < 0)
0337 return err;
0338 err = patch_build_controls(ac97,
0339 snd_ac97_yamaha_ymf743_controls_spdif, 3);
0340 if (err < 0)
0341 return err;
0342
0343
0344 snd_ac97_write_cache(ac97, AC97_YMF7X3_DIT_CTRL, 0xa201);
0345 return 0;
0346 }
0347
0348 static const struct snd_ac97_build_ops patch_yamaha_ymf743_ops = {
0349 .build_spdif = patch_yamaha_ymf743_build_spdif,
0350 .build_3d = patch_yamaha_ymf7x3_3d,
0351 };
0352
0353 static int patch_yamaha_ymf743(struct snd_ac97 *ac97)
0354 {
0355 ac97->build_ops = &patch_yamaha_ymf743_ops;
0356 ac97->caps |= AC97_BC_BASS_TREBLE;
0357 ac97->caps |= 0x04 << 10;
0358 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000;
0359 ac97->ext_id |= AC97_EI_SPDIF;
0360 return 0;
0361 }
0362
0363
0364
0365
0366
0367 static int snd_ac97_ymf753_spdif_output_pin_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
0368 {
0369 static const char * const texts[3] = { "Disabled", "Pin 43", "Pin 48" };
0370
0371 return snd_ctl_enum_info(uinfo, 1, 3, texts);
0372 }
0373
0374 static int snd_ac97_ymf753_spdif_output_pin_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0375 {
0376 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
0377 unsigned short val;
0378
0379 val = ac97->regs[AC97_YMF7X3_DIT_CTRL];
0380 ucontrol->value.enumerated.item[0] = (val & 0x0008) ? 2 : (val & 0x0020) ? 1 : 0;
0381 return 0;
0382 }
0383
0384 static int snd_ac97_ymf753_spdif_output_pin_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0385 {
0386 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
0387 unsigned short val;
0388
0389 if (ucontrol->value.enumerated.item[0] > 2)
0390 return -EINVAL;
0391 val = (ucontrol->value.enumerated.item[0] == 2) ? 0x0008 :
0392 (ucontrol->value.enumerated.item[0] == 1) ? 0x0020 : 0;
0393 return snd_ac97_update_bits(ac97, AC97_YMF7X3_DIT_CTRL, 0x0028, val);
0394
0395
0396 }
0397
0398 static const struct snd_kcontrol_new snd_ac97_ymf753_controls_spdif[3] = {
0399 {
0400 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0401 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
0402 .info = snd_ac97_ymf7x3_spdif_source_info,
0403 .get = snd_ac97_ymf7x3_spdif_source_get,
0404 .put = snd_ac97_ymf7x3_spdif_source_put,
0405 },
0406 {
0407 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0408 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Output Pin",
0409 .info = snd_ac97_ymf753_spdif_output_pin_info,
0410 .get = snd_ac97_ymf753_spdif_output_pin_get,
0411 .put = snd_ac97_ymf753_spdif_output_pin_put,
0412 },
0413 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE, NONE) "Mute",
0414 AC97_YMF7X3_DIT_CTRL, 2, 1, 1)
0415 };
0416
0417 static int patch_yamaha_ymf753_post_spdif(struct snd_ac97 * ac97)
0418 {
0419 int err;
0420
0421 err = patch_build_controls(ac97, snd_ac97_ymf753_controls_spdif, ARRAY_SIZE(snd_ac97_ymf753_controls_spdif));
0422 if (err < 0)
0423 return err;
0424 return 0;
0425 }
0426
0427 static const struct snd_ac97_build_ops patch_yamaha_ymf753_ops = {
0428 .build_3d = patch_yamaha_ymf7x3_3d,
0429 .build_post_spdif = patch_yamaha_ymf753_post_spdif
0430 };
0431
0432 static int patch_yamaha_ymf753(struct snd_ac97 * ac97)
0433 {
0434
0435
0436
0437
0438
0439
0440
0441 ac97->build_ops = &patch_yamaha_ymf753_ops;
0442 ac97->caps |= AC97_BC_BASS_TREBLE;
0443 ac97->caps |= 0x04 << 10;
0444 return 0;
0445 }
0446
0447
0448
0449
0450
0451
0452
0453 static const struct snd_kcontrol_new wm97xx_snd_ac97_controls[] = {
0454 AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1),
0455 AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1),
0456 };
0457
0458 static int patch_wolfson_wm9703_specific(struct snd_ac97 * ac97)
0459 {
0460
0461
0462
0463
0464 int err, i;
0465
0466 for (i = 0; i < ARRAY_SIZE(wm97xx_snd_ac97_controls); i++) {
0467 err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm97xx_snd_ac97_controls[i], ac97));
0468 if (err < 0)
0469 return err;
0470 }
0471 snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808);
0472 return 0;
0473 }
0474
0475 static const struct snd_ac97_build_ops patch_wolfson_wm9703_ops = {
0476 .build_specific = patch_wolfson_wm9703_specific,
0477 };
0478
0479 static int patch_wolfson03(struct snd_ac97 * ac97)
0480 {
0481 ac97->build_ops = &patch_wolfson_wm9703_ops;
0482 return 0;
0483 }
0484
0485 static const struct snd_kcontrol_new wm9704_snd_ac97_controls[] = {
0486 AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1),
0487 AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1),
0488 AC97_DOUBLE("Rear Playback Volume", AC97_WM9704_RMIXER_VOL, 8, 0, 31, 1),
0489 AC97_SINGLE("Rear Playback Switch", AC97_WM9704_RMIXER_VOL, 15, 1, 1),
0490 AC97_DOUBLE("Rear DAC Volume", AC97_WM9704_RPCM_VOL, 8, 0, 31, 1),
0491 AC97_DOUBLE("Surround Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1),
0492 };
0493
0494 static int patch_wolfson_wm9704_specific(struct snd_ac97 * ac97)
0495 {
0496 int err, i;
0497 for (i = 0; i < ARRAY_SIZE(wm9704_snd_ac97_controls); i++) {
0498 err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9704_snd_ac97_controls[i], ac97));
0499 if (err < 0)
0500 return err;
0501 }
0502
0503 snd_ac97_write_cache(ac97, AC97_WM9704_TEST, 0x0200);
0504 return 0;
0505 }
0506
0507 static const struct snd_ac97_build_ops patch_wolfson_wm9704_ops = {
0508 .build_specific = patch_wolfson_wm9704_specific,
0509 };
0510
0511 static int patch_wolfson04(struct snd_ac97 * ac97)
0512 {
0513
0514 ac97->build_ops = &patch_wolfson_wm9704_ops;
0515 return 0;
0516 }
0517
0518 static int patch_wolfson05(struct snd_ac97 * ac97)
0519 {
0520
0521 ac97->build_ops = &patch_wolfson_wm9703_ops;
0522 #ifdef CONFIG_TOUCHSCREEN_WM9705
0523
0524 ac97->flags |= AC97_HAS_NO_VIDEO | AC97_HAS_NO_AUX;
0525 #endif
0526 return 0;
0527 }
0528
0529 static const char* wm9711_alc_select[] = {"None", "Left", "Right", "Stereo"};
0530 static const char* wm9711_alc_mix[] = {"Stereo", "Right", "Left", "None"};
0531 static const char* wm9711_out3_src[] = {"Left", "VREF", "Left + Right", "Mono"};
0532 static const char* wm9711_out3_lrsrc[] = {"Master Mix", "Headphone Mix"};
0533 static const char* wm9711_rec_adc[] = {"Stereo", "Left", "Right", "Mute"};
0534 static const char* wm9711_base[] = {"Linear Control", "Adaptive Boost"};
0535 static const char* wm9711_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"};
0536 static const char* wm9711_mic[] = {"Mic 1", "Differential", "Mic 2", "Stereo"};
0537 static const char* wm9711_rec_sel[] =
0538 {"Mic 1", "NC", "NC", "Master Mix", "Line", "Headphone Mix", "Phone Mix", "Phone"};
0539 static const char* wm9711_ng_type[] = {"Constant Gain", "Mute"};
0540
0541 static const struct ac97_enum wm9711_enum[] = {
0542 AC97_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9711_alc_select),
0543 AC97_ENUM_SINGLE(AC97_VIDEO, 10, 4, wm9711_alc_mix),
0544 AC97_ENUM_SINGLE(AC97_AUX, 9, 4, wm9711_out3_src),
0545 AC97_ENUM_SINGLE(AC97_AUX, 8, 2, wm9711_out3_lrsrc),
0546 AC97_ENUM_SINGLE(AC97_REC_SEL, 12, 4, wm9711_rec_adc),
0547 AC97_ENUM_SINGLE(AC97_MASTER_TONE, 15, 2, wm9711_base),
0548 AC97_ENUM_DOUBLE(AC97_REC_GAIN, 14, 6, 2, wm9711_rec_gain),
0549 AC97_ENUM_SINGLE(AC97_MIC, 5, 4, wm9711_mic),
0550 AC97_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 8, wm9711_rec_sel),
0551 AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9711_ng_type),
0552 };
0553
0554 static const struct snd_kcontrol_new wm9711_snd_ac97_controls[] = {
0555 AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0),
0556 AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0),
0557 AC97_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0),
0558 AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0),
0559 AC97_ENUM("ALC Function", wm9711_enum[0]),
0560 AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 1),
0561 AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 1),
0562 AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0),
0563 AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0),
0564 AC97_ENUM("ALC NG Type", wm9711_enum[9]),
0565 AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 1),
0566
0567 AC97_SINGLE("Side Tone Switch", AC97_VIDEO, 15, 1, 1),
0568 AC97_SINGLE("Side Tone Volume", AC97_VIDEO, 12, 7, 1),
0569 AC97_ENUM("ALC Headphone Mux", wm9711_enum[1]),
0570 AC97_SINGLE("ALC Headphone Volume", AC97_VIDEO, 7, 7, 1),
0571
0572 AC97_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1),
0573 AC97_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 0),
0574 AC97_ENUM("Out3 Mux", wm9711_enum[2]),
0575 AC97_ENUM("Out3 LR Mux", wm9711_enum[3]),
0576 AC97_SINGLE("Out3 Volume", AC97_AUX, 0, 31, 1),
0577
0578 AC97_SINGLE("Beep to Headphone Switch", AC97_PC_BEEP, 15, 1, 1),
0579 AC97_SINGLE("Beep to Headphone Volume", AC97_PC_BEEP, 12, 7, 1),
0580 AC97_SINGLE("Beep to Side Tone Switch", AC97_PC_BEEP, 11, 1, 1),
0581 AC97_SINGLE("Beep to Side Tone Volume", AC97_PC_BEEP, 8, 7, 1),
0582 AC97_SINGLE("Beep to Phone Switch", AC97_PC_BEEP, 7, 1, 1),
0583 AC97_SINGLE("Beep to Phone Volume", AC97_PC_BEEP, 4, 7, 1),
0584
0585 AC97_SINGLE("Aux to Headphone Switch", AC97_CD, 15, 1, 1),
0586 AC97_SINGLE("Aux to Headphone Volume", AC97_CD, 12, 7, 1),
0587 AC97_SINGLE("Aux to Side Tone Switch", AC97_CD, 11, 1, 1),
0588 AC97_SINGLE("Aux to Side Tone Volume", AC97_CD, 8, 7, 1),
0589 AC97_SINGLE("Aux to Phone Switch", AC97_CD, 7, 1, 1),
0590 AC97_SINGLE("Aux to Phone Volume", AC97_CD, 4, 7, 1),
0591
0592 AC97_SINGLE("Phone to Headphone Switch", AC97_PHONE, 15, 1, 1),
0593 AC97_SINGLE("Phone to Master Switch", AC97_PHONE, 14, 1, 1),
0594
0595 AC97_SINGLE("Line to Headphone Switch", AC97_LINE, 15, 1, 1),
0596 AC97_SINGLE("Line to Master Switch", AC97_LINE, 14, 1, 1),
0597 AC97_SINGLE("Line to Phone Switch", AC97_LINE, 13, 1, 1),
0598
0599 AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PCM, 15, 1, 1),
0600 AC97_SINGLE("PCM Playback to Master Switch", AC97_PCM, 14, 1, 1),
0601 AC97_SINGLE("PCM Playback to Phone Switch", AC97_PCM, 13, 1, 1),
0602
0603 AC97_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL, 14, 1, 0),
0604 AC97_ENUM("Capture to Phone Mux", wm9711_enum[4]),
0605 AC97_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL, 11, 1, 1),
0606 AC97_ENUM("Capture Select", wm9711_enum[8]),
0607
0608 AC97_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1),
0609 AC97_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1),
0610
0611 AC97_ENUM("Bass Control", wm9711_enum[5]),
0612 AC97_SINGLE("Bass Cut-off Switch", AC97_MASTER_TONE, 12, 1, 1),
0613 AC97_SINGLE("Tone Cut-off Switch", AC97_MASTER_TONE, 4, 1, 1),
0614 AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0),
0615
0616 AC97_SINGLE("ADC Switch", AC97_REC_GAIN, 15, 1, 1),
0617 AC97_ENUM("Capture Volume Steps", wm9711_enum[6]),
0618 AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1),
0619 AC97_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0),
0620
0621 AC97_SINGLE("Mic 1 to Phone Switch", AC97_MIC, 14, 1, 1),
0622 AC97_SINGLE("Mic 2 to Phone Switch", AC97_MIC, 13, 1, 1),
0623 AC97_ENUM("Mic Select Source", wm9711_enum[7]),
0624 AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1),
0625 AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1),
0626 AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0),
0627
0628 AC97_SINGLE("Master Left Inv Switch", AC97_MASTER, 6, 1, 0),
0629 AC97_SINGLE("Master ZC Switch", AC97_MASTER, 7, 1, 0),
0630 AC97_SINGLE("Headphone ZC Switch", AC97_HEADPHONE, 7, 1, 0),
0631 AC97_SINGLE("Mono ZC Switch", AC97_MASTER_MONO, 7, 1, 0),
0632 };
0633
0634 static int patch_wolfson_wm9711_specific(struct snd_ac97 * ac97)
0635 {
0636 int err, i;
0637
0638 for (i = 0; i < ARRAY_SIZE(wm9711_snd_ac97_controls); i++) {
0639 err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9711_snd_ac97_controls[i], ac97));
0640 if (err < 0)
0641 return err;
0642 }
0643 snd_ac97_write_cache(ac97, AC97_CODEC_CLASS_REV, 0x0808);
0644 snd_ac97_write_cache(ac97, AC97_PCI_SVID, 0x0808);
0645 snd_ac97_write_cache(ac97, AC97_VIDEO, 0x0808);
0646 snd_ac97_write_cache(ac97, AC97_AUX, 0x0808);
0647 snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808);
0648 snd_ac97_write_cache(ac97, AC97_CD, 0x0000);
0649 return 0;
0650 }
0651
0652 static const struct snd_ac97_build_ops patch_wolfson_wm9711_ops = {
0653 .build_specific = patch_wolfson_wm9711_specific,
0654 };
0655
0656 static int patch_wolfson11(struct snd_ac97 * ac97)
0657 {
0658
0659 ac97->build_ops = &patch_wolfson_wm9711_ops;
0660
0661 ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_MIC |
0662 AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD;
0663
0664 return 0;
0665 }
0666
0667 static const char* wm9713_mic_mixer[] = {"Stereo", "Mic 1", "Mic 2", "Mute"};
0668 static const char* wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"};
0669 static const char* wm9713_rec_src[] =
0670 {"Mic 1", "Mic 2", "Line", "Mono In", "Headphone Mix", "Master Mix",
0671 "Mono Mix", "Zh"};
0672 static const char* wm9713_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"};
0673 static const char* wm9713_alc_select[] = {"None", "Left", "Right", "Stereo"};
0674 static const char* wm9713_mono_pga[] = {"Vmid", "Zh", "Mono Mix", "Inv 1"};
0675 static const char* wm9713_spk_pga[] =
0676 {"Vmid", "Zh", "Headphone Mix", "Master Mix", "Inv", "NC", "NC", "NC"};
0677 static const char* wm9713_hp_pga[] = {"Vmid", "Zh", "Headphone Mix", "NC"};
0678 static const char* wm9713_out3_pga[] = {"Vmid", "Zh", "Inv 1", "NC"};
0679 static const char* wm9713_out4_pga[] = {"Vmid", "Zh", "Inv 2", "NC"};
0680 static const char* wm9713_dac_inv[] =
0681 {"Off", "Mono Mix", "Master Mix", "Headphone Mix L", "Headphone Mix R",
0682 "Headphone Mix Mono", "NC", "Vmid"};
0683 static const char* wm9713_base[] = {"Linear Control", "Adaptive Boost"};
0684 static const char* wm9713_ng_type[] = {"Constant Gain", "Mute"};
0685
0686 static const struct ac97_enum wm9713_enum[] = {
0687 AC97_ENUM_SINGLE(AC97_LINE, 3, 4, wm9713_mic_mixer),
0688 AC97_ENUM_SINGLE(AC97_VIDEO, 14, 4, wm9713_rec_mux),
0689 AC97_ENUM_SINGLE(AC97_VIDEO, 9, 4, wm9713_rec_mux),
0690 AC97_ENUM_DOUBLE(AC97_VIDEO, 3, 0, 8, wm9713_rec_src),
0691 AC97_ENUM_DOUBLE(AC97_CD, 14, 6, 2, wm9713_rec_gain),
0692 AC97_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9713_alc_select),
0693 AC97_ENUM_SINGLE(AC97_REC_GAIN, 14, 4, wm9713_mono_pga),
0694 AC97_ENUM_DOUBLE(AC97_REC_GAIN, 11, 8, 8, wm9713_spk_pga),
0695 AC97_ENUM_DOUBLE(AC97_REC_GAIN, 6, 4, 4, wm9713_hp_pga),
0696 AC97_ENUM_SINGLE(AC97_REC_GAIN, 2, 4, wm9713_out3_pga),
0697 AC97_ENUM_SINGLE(AC97_REC_GAIN, 0, 4, wm9713_out4_pga),
0698 AC97_ENUM_DOUBLE(AC97_REC_GAIN_MIC, 13, 10, 8, wm9713_dac_inv),
0699 AC97_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, wm9713_base),
0700 AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9713_ng_type),
0701 };
0702
0703 static const struct snd_kcontrol_new wm13_snd_ac97_controls[] = {
0704 AC97_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1),
0705 AC97_SINGLE("Line In to Headphone Switch", AC97_PC_BEEP, 15, 1, 1),
0706 AC97_SINGLE("Line In to Master Switch", AC97_PC_BEEP, 14, 1, 1),
0707 AC97_SINGLE("Line In to Mono Switch", AC97_PC_BEEP, 13, 1, 1),
0708
0709 AC97_DOUBLE("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1),
0710 AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PHONE, 15, 1, 1),
0711 AC97_SINGLE("PCM Playback to Master Switch", AC97_PHONE, 14, 1, 1),
0712 AC97_SINGLE("PCM Playback to Mono Switch", AC97_PHONE, 13, 1, 1),
0713
0714 AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1),
0715 AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1),
0716 AC97_SINGLE("Mic 1 to Mono Switch", AC97_LINE, 7, 1, 1),
0717 AC97_SINGLE("Mic 2 to Mono Switch", AC97_LINE, 6, 1, 1),
0718 AC97_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0),
0719 AC97_ENUM("Mic to Headphone Mux", wm9713_enum[0]),
0720 AC97_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1),
0721
0722 AC97_SINGLE("Capture Switch", AC97_CD, 15, 1, 1),
0723 AC97_ENUM("Capture Volume Steps", wm9713_enum[4]),
0724 AC97_DOUBLE("Capture Volume", AC97_CD, 8, 0, 15, 0),
0725 AC97_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0),
0726
0727 AC97_ENUM("Capture to Headphone Mux", wm9713_enum[1]),
0728 AC97_SINGLE("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1),
0729 AC97_ENUM("Capture to Mono Mux", wm9713_enum[2]),
0730 AC97_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0),
0731 AC97_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0),
0732 AC97_ENUM("Capture Select", wm9713_enum[3]),
0733
0734 AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0),
0735 AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0),
0736 AC97_SINGLE("ALC Decay Time ", AC97_CODEC_CLASS_REV, 4, 15, 0),
0737 AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0),
0738 AC97_ENUM("ALC Function", wm9713_enum[5]),
0739 AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0),
0740 AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 0),
0741 AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0),
0742 AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0),
0743 AC97_ENUM("ALC NG Type", wm9713_enum[13]),
0744 AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 0),
0745
0746 AC97_DOUBLE("Master ZC Switch", AC97_MASTER, 14, 6, 1, 0),
0747 AC97_DOUBLE("Headphone ZC Switch", AC97_HEADPHONE, 14, 6, 1, 0),
0748 AC97_DOUBLE("Out3/4 ZC Switch", AC97_MASTER_MONO, 14, 6, 1, 0),
0749 AC97_SINGLE("Master Right Switch", AC97_MASTER, 7, 1, 1),
0750 AC97_SINGLE("Headphone Right Switch", AC97_HEADPHONE, 7, 1, 1),
0751 AC97_SINGLE("Out3/4 Right Switch", AC97_MASTER_MONO, 7, 1, 1),
0752
0753 AC97_SINGLE("Mono In to Headphone Switch", AC97_MASTER_TONE, 15, 1, 1),
0754 AC97_SINGLE("Mono In to Master Switch", AC97_MASTER_TONE, 14, 1, 1),
0755 AC97_SINGLE("Mono In Volume", AC97_MASTER_TONE, 8, 31, 1),
0756 AC97_SINGLE("Mono Switch", AC97_MASTER_TONE, 7, 1, 1),
0757 AC97_SINGLE("Mono ZC Switch", AC97_MASTER_TONE, 6, 1, 0),
0758 AC97_SINGLE("Mono Volume", AC97_MASTER_TONE, 0, 31, 1),
0759
0760 AC97_SINGLE("Beep to Headphone Switch", AC97_AUX, 15, 1, 1),
0761 AC97_SINGLE("Beep to Headphone Volume", AC97_AUX, 12, 7, 1),
0762 AC97_SINGLE("Beep to Master Switch", AC97_AUX, 11, 1, 1),
0763 AC97_SINGLE("Beep to Master Volume", AC97_AUX, 8, 7, 1),
0764 AC97_SINGLE("Beep to Mono Switch", AC97_AUX, 7, 1, 1),
0765 AC97_SINGLE("Beep to Mono Volume", AC97_AUX, 4, 7, 1),
0766
0767 AC97_SINGLE("Voice to Headphone Switch", AC97_PCM, 15, 1, 1),
0768 AC97_SINGLE("Voice to Headphone Volume", AC97_PCM, 12, 7, 1),
0769 AC97_SINGLE("Voice to Master Switch", AC97_PCM, 11, 1, 1),
0770 AC97_SINGLE("Voice to Master Volume", AC97_PCM, 8, 7, 1),
0771 AC97_SINGLE("Voice to Mono Switch", AC97_PCM, 7, 1, 1),
0772 AC97_SINGLE("Voice to Mono Volume", AC97_PCM, 4, 7, 1),
0773
0774 AC97_SINGLE("Aux to Headphone Switch", AC97_REC_SEL, 15, 1, 1),
0775 AC97_SINGLE("Aux to Headphone Volume", AC97_REC_SEL, 12, 7, 1),
0776 AC97_SINGLE("Aux to Master Switch", AC97_REC_SEL, 11, 1, 1),
0777 AC97_SINGLE("Aux to Master Volume", AC97_REC_SEL, 8, 7, 1),
0778 AC97_SINGLE("Aux to Mono Switch", AC97_REC_SEL, 7, 1, 1),
0779 AC97_SINGLE("Aux to Mono Volume", AC97_REC_SEL, 4, 7, 1),
0780
0781 AC97_ENUM("Mono Input Mux", wm9713_enum[6]),
0782 AC97_ENUM("Master Input Mux", wm9713_enum[7]),
0783 AC97_ENUM("Headphone Input Mux", wm9713_enum[8]),
0784 AC97_ENUM("Out 3 Input Mux", wm9713_enum[9]),
0785 AC97_ENUM("Out 4 Input Mux", wm9713_enum[10]),
0786
0787 AC97_ENUM("Bass Control", wm9713_enum[12]),
0788 AC97_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1),
0789 AC97_SINGLE("Tone Cut-off Switch", AC97_GENERAL_PURPOSE, 4, 1, 1),
0790 AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_GENERAL_PURPOSE, 6, 1, 0),
0791 AC97_SINGLE("Bass Volume", AC97_GENERAL_PURPOSE, 8, 15, 1),
0792 AC97_SINGLE("Tone Volume", AC97_GENERAL_PURPOSE, 0, 15, 1),
0793 };
0794
0795 static const struct snd_kcontrol_new wm13_snd_ac97_controls_3d[] = {
0796 AC97_ENUM("Inv Input Mux", wm9713_enum[11]),
0797 AC97_SINGLE("3D Upper Cut-off Switch", AC97_REC_GAIN_MIC, 5, 1, 0),
0798 AC97_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0),
0799 AC97_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1),
0800 };
0801
0802 static int patch_wolfson_wm9713_3d (struct snd_ac97 * ac97)
0803 {
0804 int err, i;
0805
0806 for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_3d); i++) {
0807 err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_3d[i], ac97));
0808 if (err < 0)
0809 return err;
0810 }
0811 return 0;
0812 }
0813
0814 static int patch_wolfson_wm9713_specific(struct snd_ac97 * ac97)
0815 {
0816 int err, i;
0817
0818 for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls); i++) {
0819 err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls[i], ac97));
0820 if (err < 0)
0821 return err;
0822 }
0823 snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808);
0824 snd_ac97_write_cache(ac97, AC97_PHONE, 0x0808);
0825 snd_ac97_write_cache(ac97, AC97_MIC, 0x0808);
0826 snd_ac97_write_cache(ac97, AC97_LINE, 0x00da);
0827 snd_ac97_write_cache(ac97, AC97_CD, 0x0808);
0828 snd_ac97_write_cache(ac97, AC97_VIDEO, 0xd612);
0829 snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x1ba0);
0830 return 0;
0831 }
0832
0833 #ifdef CONFIG_PM
0834 static void patch_wolfson_wm9713_suspend (struct snd_ac97 * ac97)
0835 {
0836 snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xfeff);
0837 snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0xffff);
0838 }
0839
0840 static void patch_wolfson_wm9713_resume (struct snd_ac97 * ac97)
0841 {
0842 snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00);
0843 snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810);
0844 snd_ac97_write_cache(ac97, AC97_POWERDOWN, 0x0);
0845 }
0846 #endif
0847
0848 static const struct snd_ac97_build_ops patch_wolfson_wm9713_ops = {
0849 .build_specific = patch_wolfson_wm9713_specific,
0850 .build_3d = patch_wolfson_wm9713_3d,
0851 #ifdef CONFIG_PM
0852 .suspend = patch_wolfson_wm9713_suspend,
0853 .resume = patch_wolfson_wm9713_resume
0854 #endif
0855 };
0856
0857 static int patch_wolfson13(struct snd_ac97 * ac97)
0858 {
0859
0860 ac97->build_ops = &patch_wolfson_wm9713_ops;
0861
0862 ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_PHONE |
0863 AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD | AC97_HAS_NO_TONE |
0864 AC97_HAS_NO_STD_PCM;
0865 ac97->scaps &= ~AC97_SCAP_MODEM;
0866
0867 snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00);
0868 snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810);
0869 snd_ac97_write_cache(ac97, AC97_POWERDOWN, 0x0);
0870
0871 return 0;
0872 }
0873
0874
0875
0876
0877 static int patch_tritech_tr28028(struct snd_ac97 * ac97)
0878 {
0879 snd_ac97_write_cache(ac97, 0x26, 0x0300);
0880 snd_ac97_write_cache(ac97, 0x26, 0x0000);
0881 snd_ac97_write_cache(ac97, AC97_SURROUND_MASTER, 0x0000);
0882 snd_ac97_write_cache(ac97, AC97_SPDIF, 0x0000);
0883 return 0;
0884 }
0885
0886
0887
0888
0889 static int patch_sigmatel_stac9700_3d(struct snd_ac97 * ac97)
0890 {
0891 struct snd_kcontrol *kctl;
0892 int err;
0893
0894 err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97));
0895 if (err < 0)
0896 return err;
0897 strcpy(kctl->id.name, "3D Control Sigmatel - Depth");
0898 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 2, 3, 0);
0899 snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
0900 return 0;
0901 }
0902
0903 static int patch_sigmatel_stac9708_3d(struct snd_ac97 * ac97)
0904 {
0905 struct snd_kcontrol *kctl;
0906 int err;
0907
0908 kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97);
0909 err = snd_ctl_add(ac97->bus->card, kctl);
0910 if (err < 0)
0911 return err;
0912 strcpy(kctl->id.name, "3D Control Sigmatel - Depth");
0913 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 0, 3, 0);
0914 kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97);
0915 err = snd_ctl_add(ac97->bus->card, kctl);
0916 if (err < 0)
0917 return err;
0918 strcpy(kctl->id.name, "3D Control Sigmatel - Rear Depth");
0919 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 2, 3, 0);
0920 snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
0921 return 0;
0922 }
0923
0924 static const struct snd_kcontrol_new snd_ac97_sigmatel_4speaker =
0925 AC97_SINGLE("Sigmatel 4-Speaker Stereo Playback Switch",
0926 AC97_SIGMATEL_DAC2INVERT, 2, 1, 0);
0927
0928
0929 static const struct snd_kcontrol_new snd_ac97_sigmatel_phaseinvert =
0930 AC97_SINGLE("Surround Phase Inversion Playback Switch",
0931 AC97_SIGMATEL_DAC2INVERT, 3, 1, 0);
0932
0933 static const struct snd_kcontrol_new snd_ac97_sigmatel_controls[] = {
0934 AC97_SINGLE("Sigmatel DAC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 1, 1, 0),
0935 AC97_SINGLE("Sigmatel ADC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 0, 1, 0)
0936 };
0937
0938 static int patch_sigmatel_stac97xx_specific(struct snd_ac97 * ac97)
0939 {
0940 int err;
0941
0942 snd_ac97_write_cache(ac97, AC97_SIGMATEL_ANALOG, snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) & ~0x0003);
0943 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_ANALOG, 1)) {
0944 err = patch_build_controls(ac97, &snd_ac97_sigmatel_controls[0], 1);
0945 if (err < 0)
0946 return err;
0947 }
0948 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_ANALOG, 0)) {
0949 err = patch_build_controls(ac97, &snd_ac97_sigmatel_controls[1], 1);
0950 if (err < 0)
0951 return err;
0952 }
0953 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_DAC2INVERT, 2)) {
0954 err = patch_build_controls(ac97, &snd_ac97_sigmatel_4speaker, 1);
0955 if (err < 0)
0956 return err;
0957 }
0958 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_DAC2INVERT, 3)) {
0959 err = patch_build_controls(ac97, &snd_ac97_sigmatel_phaseinvert, 1);
0960 if (err < 0)
0961 return err;
0962 }
0963 return 0;
0964 }
0965
0966 static const struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = {
0967 .build_3d = patch_sigmatel_stac9700_3d,
0968 .build_specific = patch_sigmatel_stac97xx_specific
0969 };
0970
0971 static int patch_sigmatel_stac9700(struct snd_ac97 * ac97)
0972 {
0973 ac97->build_ops = &patch_sigmatel_stac9700_ops;
0974 return 0;
0975 }
0976
0977 static int snd_ac97_stac9708_put_bias(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0978 {
0979 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
0980 int err;
0981
0982 mutex_lock(&ac97->page_mutex);
0983 snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
0984 err = snd_ac97_update_bits(ac97, AC97_SIGMATEL_BIAS2, 0x0010,
0985 (ucontrol->value.integer.value[0] & 1) << 4);
0986 snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0);
0987 mutex_unlock(&ac97->page_mutex);
0988 return err;
0989 }
0990
0991 static const struct snd_kcontrol_new snd_ac97_stac9708_bias_control = {
0992 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0993 .name = "Sigmatel Output Bias Switch",
0994 .info = snd_ac97_info_volsw,
0995 .get = snd_ac97_get_volsw,
0996 .put = snd_ac97_stac9708_put_bias,
0997 .private_value = AC97_SINGLE_VALUE(AC97_SIGMATEL_BIAS2, 4, 1, 0),
0998 };
0999
1000 static int patch_sigmatel_stac9708_specific(struct snd_ac97 *ac97)
1001 {
1002 int err;
1003
1004
1005 snd_ac97_remove_ctl(ac97, "PCM Out Path & Mute", NULL);
1006
1007 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Sigmatel Surround Playback");
1008 err = patch_build_controls(ac97, &snd_ac97_stac9708_bias_control, 1);
1009 if (err < 0)
1010 return err;
1011 return patch_sigmatel_stac97xx_specific(ac97);
1012 }
1013
1014 static const struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = {
1015 .build_3d = patch_sigmatel_stac9708_3d,
1016 .build_specific = patch_sigmatel_stac9708_specific
1017 };
1018
1019 static int patch_sigmatel_stac9708(struct snd_ac97 * ac97)
1020 {
1021 unsigned int codec72, codec6c;
1022
1023 ac97->build_ops = &patch_sigmatel_stac9708_ops;
1024 ac97->caps |= 0x10;
1025
1026 codec72 = snd_ac97_read(ac97, AC97_SIGMATEL_BIAS2) & 0x8000;
1027 codec6c = snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG);
1028
1029 if ((codec72==0) && (codec6c==0)) {
1030 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
1031 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x1000);
1032 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
1033 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0007);
1034 } else if ((codec72==0x8000) && (codec6c==0)) {
1035 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
1036 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x1001);
1037 snd_ac97_write_cache(ac97, AC97_SIGMATEL_DAC2INVERT, 0x0008);
1038 } else if ((codec72==0x8000) && (codec6c==0x0080)) {
1039
1040 }
1041 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);
1042 return 0;
1043 }
1044
1045 static int patch_sigmatel_stac9721(struct snd_ac97 * ac97)
1046 {
1047 ac97->build_ops = &patch_sigmatel_stac9700_ops;
1048 if (snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) == 0) {
1049
1050 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
1051 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x4000);
1052 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
1053 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002);
1054 }
1055 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);
1056 return 0;
1057 }
1058
1059 static int patch_sigmatel_stac9744(struct snd_ac97 * ac97)
1060 {
1061
1062 ac97->build_ops = &patch_sigmatel_stac9700_ops;
1063 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
1064 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x0000);
1065 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
1066 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002);
1067 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);
1068 return 0;
1069 }
1070
1071 static int patch_sigmatel_stac9756(struct snd_ac97 * ac97)
1072 {
1073
1074 ac97->build_ops = &patch_sigmatel_stac9700_ops;
1075 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
1076 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x0000);
1077 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
1078 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002);
1079 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);
1080 return 0;
1081 }
1082
1083 static int snd_ac97_stac9758_output_jack_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1084 {
1085 static const char * const texts[5] = {
1086 "Input/Disabled", "Front Output",
1087 "Rear Output", "Center/LFE Output", "Mixer Output" };
1088
1089 return snd_ctl_enum_info(uinfo, 1, 5, texts);
1090 }
1091
1092 static int snd_ac97_stac9758_output_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1093 {
1094 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1095 int shift = kcontrol->private_value;
1096 unsigned short val;
1097
1098 val = ac97->regs[AC97_SIGMATEL_OUTSEL] >> shift;
1099 if (!(val & 4))
1100 ucontrol->value.enumerated.item[0] = 0;
1101 else
1102 ucontrol->value.enumerated.item[0] = 1 + (val & 3);
1103 return 0;
1104 }
1105
1106 static int snd_ac97_stac9758_output_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1107 {
1108 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1109 int shift = kcontrol->private_value;
1110 unsigned short val;
1111
1112 if (ucontrol->value.enumerated.item[0] > 4)
1113 return -EINVAL;
1114 if (ucontrol->value.enumerated.item[0] == 0)
1115 val = 0;
1116 else
1117 val = 4 | (ucontrol->value.enumerated.item[0] - 1);
1118 return ac97_update_bits_page(ac97, AC97_SIGMATEL_OUTSEL,
1119 7 << shift, val << shift, 0);
1120 }
1121
1122 static int snd_ac97_stac9758_input_jack_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1123 {
1124 static const char * const texts[7] = {
1125 "Mic2 Jack", "Mic1 Jack", "Line In Jack",
1126 "Front Jack", "Rear Jack", "Center/LFE Jack", "Mute" };
1127
1128 return snd_ctl_enum_info(uinfo, 1, 7, texts);
1129 }
1130
1131 static int snd_ac97_stac9758_input_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1132 {
1133 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1134 int shift = kcontrol->private_value;
1135 unsigned short val;
1136
1137 val = ac97->regs[AC97_SIGMATEL_INSEL];
1138 ucontrol->value.enumerated.item[0] = (val >> shift) & 7;
1139 return 0;
1140 }
1141
1142 static int snd_ac97_stac9758_input_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1143 {
1144 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1145 int shift = kcontrol->private_value;
1146
1147 return ac97_update_bits_page(ac97, AC97_SIGMATEL_INSEL, 7 << shift,
1148 ucontrol->value.enumerated.item[0] << shift, 0);
1149 }
1150
1151 static int snd_ac97_stac9758_phonesel_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1152 {
1153 static const char * const texts[3] = {
1154 "None", "Front Jack", "Rear Jack"
1155 };
1156
1157 return snd_ctl_enum_info(uinfo, 1, 3, texts);
1158 }
1159
1160 static int snd_ac97_stac9758_phonesel_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1161 {
1162 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1163
1164 ucontrol->value.enumerated.item[0] = ac97->regs[AC97_SIGMATEL_IOMISC] & 3;
1165 return 0;
1166 }
1167
1168 static int snd_ac97_stac9758_phonesel_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1169 {
1170 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1171
1172 return ac97_update_bits_page(ac97, AC97_SIGMATEL_IOMISC, 3,
1173 ucontrol->value.enumerated.item[0], 0);
1174 }
1175
1176 #define STAC9758_OUTPUT_JACK(xname, shift) \
1177 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1178 .info = snd_ac97_stac9758_output_jack_info, \
1179 .get = snd_ac97_stac9758_output_jack_get, \
1180 .put = snd_ac97_stac9758_output_jack_put, \
1181 .private_value = shift }
1182 #define STAC9758_INPUT_JACK(xname, shift) \
1183 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1184 .info = snd_ac97_stac9758_input_jack_info, \
1185 .get = snd_ac97_stac9758_input_jack_get, \
1186 .put = snd_ac97_stac9758_input_jack_put, \
1187 .private_value = shift }
1188 static const struct snd_kcontrol_new snd_ac97_sigmatel_stac9758_controls[] = {
1189 STAC9758_OUTPUT_JACK("Mic1 Jack", 1),
1190 STAC9758_OUTPUT_JACK("LineIn Jack", 4),
1191 STAC9758_OUTPUT_JACK("Front Jack", 7),
1192 STAC9758_OUTPUT_JACK("Rear Jack", 10),
1193 STAC9758_OUTPUT_JACK("Center/LFE Jack", 13),
1194 STAC9758_INPUT_JACK("Mic Input Source", 0),
1195 STAC9758_INPUT_JACK("Line Input Source", 8),
1196 {
1197 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1198 .name = "Headphone Amp",
1199 .info = snd_ac97_stac9758_phonesel_info,
1200 .get = snd_ac97_stac9758_phonesel_get,
1201 .put = snd_ac97_stac9758_phonesel_put
1202 },
1203 AC97_SINGLE("Exchange Center/LFE", AC97_SIGMATEL_IOMISC, 4, 1, 0),
1204 AC97_SINGLE("Headphone +3dB Boost", AC97_SIGMATEL_IOMISC, 8, 1, 0)
1205 };
1206
1207 static int patch_sigmatel_stac9758_specific(struct snd_ac97 *ac97)
1208 {
1209 int err;
1210
1211 err = patch_sigmatel_stac97xx_specific(ac97);
1212 if (err < 0)
1213 return err;
1214 err = patch_build_controls(ac97, snd_ac97_sigmatel_stac9758_controls,
1215 ARRAY_SIZE(snd_ac97_sigmatel_stac9758_controls));
1216 if (err < 0)
1217 return err;
1218
1219 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Front Playback");
1220
1221
1222
1223 snd_ac97_rename_vol_ctl(ac97, "Video Playback", "Surround Mix Playback");
1224
1225
1226 return 0;
1227 }
1228
1229 static const struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = {
1230 .build_3d = patch_sigmatel_stac9700_3d,
1231 .build_specific = patch_sigmatel_stac9758_specific
1232 };
1233
1234 static int patch_sigmatel_stac9758(struct snd_ac97 * ac97)
1235 {
1236 static const unsigned short regs[4] = {
1237 AC97_SIGMATEL_OUTSEL,
1238 AC97_SIGMATEL_IOMISC,
1239 AC97_SIGMATEL_INSEL,
1240 AC97_SIGMATEL_VARIOUS
1241 };
1242 static const unsigned short def_regs[4] = {
1243 0xd794,
1244 0x2001,
1245 0x0201,
1246 0x0040
1247 };
1248 static const unsigned short m675_regs[4] = {
1249 0xfc70,
1250 0x2102,
1251 0x0203,
1252 0x0041
1253 };
1254 const unsigned short *pregs = def_regs;
1255 int i;
1256
1257
1258 if (ac97->pci &&
1259 ac97->subsystem_vendor == 0x107b &&
1260 ac97->subsystem_device == 0x0601)
1261 pregs = m675_regs;
1262
1263
1264 ac97->build_ops = &patch_sigmatel_stac9758_ops;
1265
1266 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR);
1267 for (i = 0; i < 4; i++)
1268 snd_ac97_write_cache(ac97, regs[i], pregs[i]);
1269
1270 ac97->flags |= AC97_STEREO_MUTES;
1271 return 0;
1272 }
1273
1274
1275
1276
1277 static const struct snd_kcontrol_new snd_ac97_cirrus_controls_spdif[2] = {
1278 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), AC97_CSR_SPDIF, 15, 1, 0),
1279 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "AC97-SPSA", AC97_CSR_ACMODE, 0, 3, 0)
1280 };
1281
1282 static int patch_cirrus_build_spdif(struct snd_ac97 * ac97)
1283 {
1284 int err;
1285
1286
1287 err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3);
1288 if (err < 0)
1289 return err;
1290
1291 err = patch_build_controls(ac97, &snd_ac97_cirrus_controls_spdif[0], 1);
1292 if (err < 0)
1293 return err;
1294 switch (ac97->id & AC97_ID_CS_MASK) {
1295 case AC97_ID_CS4205:
1296 err = patch_build_controls(ac97, &snd_ac97_cirrus_controls_spdif[1], 1);
1297 if (err < 0)
1298 return err;
1299 break;
1300 }
1301
1302
1303 snd_ac97_write_cache(ac97, AC97_CSR_SPDIF, 0x0a20);
1304 return 0;
1305 }
1306
1307 static const struct snd_ac97_build_ops patch_cirrus_ops = {
1308 .build_spdif = patch_cirrus_build_spdif
1309 };
1310
1311 static int patch_cirrus_spdif(struct snd_ac97 * ac97)
1312 {
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324 ac97->build_ops = &patch_cirrus_ops;
1325 ac97->flags |= AC97_CS_SPDIF;
1326 ac97->rates[AC97_RATES_SPDIF] &= ~SNDRV_PCM_RATE_32000;
1327 ac97->ext_id |= AC97_EI_SPDIF;
1328 snd_ac97_write_cache(ac97, AC97_CSR_ACMODE, 0x0080);
1329 return 0;
1330 }
1331
1332 static int patch_cirrus_cs4299(struct snd_ac97 * ac97)
1333 {
1334
1335 ac97->flags |= AC97_HAS_PC_BEEP;
1336
1337 return patch_cirrus_spdif(ac97);
1338 }
1339
1340
1341
1342
1343 static const struct snd_kcontrol_new snd_ac97_conexant_controls_spdif[1] = {
1344 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), AC97_CXR_AUDIO_MISC, 3, 1, 0),
1345 };
1346
1347 static int patch_conexant_build_spdif(struct snd_ac97 * ac97)
1348 {
1349 int err;
1350
1351
1352 err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3);
1353 if (err < 0)
1354 return err;
1355
1356 err = patch_build_controls(ac97, &snd_ac97_conexant_controls_spdif[0], 1);
1357 if (err < 0)
1358 return err;
1359
1360
1361 snd_ac97_write_cache(ac97, AC97_CXR_AUDIO_MISC,
1362 snd_ac97_read(ac97, AC97_CXR_AUDIO_MISC) & ~(AC97_CXR_SPDIFEN|AC97_CXR_COPYRGT|AC97_CXR_SPDIF_MASK));
1363 return 0;
1364 }
1365
1366 static const struct snd_ac97_build_ops patch_conexant_ops = {
1367 .build_spdif = patch_conexant_build_spdif
1368 };
1369
1370 static int patch_conexant(struct snd_ac97 * ac97)
1371 {
1372 ac97->build_ops = &patch_conexant_ops;
1373 ac97->flags |= AC97_CX_SPDIF;
1374 ac97->ext_id |= AC97_EI_SPDIF;
1375 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000;
1376 return 0;
1377 }
1378
1379 static int patch_cx20551(struct snd_ac97 *ac97)
1380 {
1381 snd_ac97_update_bits(ac97, 0x5c, 0x01, 0x01);
1382 return 0;
1383 }
1384
1385
1386
1387
1388 #ifdef CONFIG_PM
1389 static void ad18xx_resume(struct snd_ac97 *ac97)
1390 {
1391 static const unsigned short setup_regs[] = {
1392 AC97_AD_MISC, AC97_AD_SERIAL_CFG, AC97_AD_JACK_SPDIF,
1393 };
1394 int i, codec;
1395
1396 for (i = 0; i < (int)ARRAY_SIZE(setup_regs); i++) {
1397 unsigned short reg = setup_regs[i];
1398 if (test_bit(reg, ac97->reg_accessed)) {
1399 snd_ac97_write(ac97, reg, ac97->regs[reg]);
1400 snd_ac97_read(ac97, reg);
1401 }
1402 }
1403
1404 if (! (ac97->flags & AC97_AD_MULTI))
1405
1406 snd_ac97_restore_status(ac97);
1407 else {
1408
1409 for (codec = 0; codec < 3; codec++) {
1410 if (! ac97->spec.ad18xx.id[codec])
1411 continue;
1412
1413 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
1414 ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]);
1415 ac97->bus->ops->write(ac97, AC97_AD_CODEC_CFG, ac97->spec.ad18xx.codec_cfg[codec]);
1416 }
1417
1418 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
1419
1420
1421 for (i = 2; i < 0x7c ; i += 2) {
1422 if (i == AC97_POWERDOWN || i == AC97_EXTENDED_ID)
1423 continue;
1424 if (test_bit(i, ac97->reg_accessed)) {
1425
1426 if (i == AC97_PCM) {
1427 for (codec = 0; codec < 3; codec++) {
1428 if (! ac97->spec.ad18xx.id[codec])
1429 continue;
1430
1431 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
1432 ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]);
1433
1434 ac97->bus->ops->write(ac97, AC97_PCM, ac97->spec.ad18xx.pcmreg[codec]);
1435 }
1436
1437 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
1438 continue;
1439 } else if (i == AC97_AD_TEST ||
1440 i == AC97_AD_CODEC_CFG ||
1441 i == AC97_AD_SERIAL_CFG)
1442 continue;
1443 }
1444 snd_ac97_write(ac97, i, ac97->regs[i]);
1445 snd_ac97_read(ac97, i);
1446 }
1447 }
1448
1449 snd_ac97_restore_iec958(ac97);
1450 }
1451
1452 static void ad1888_resume(struct snd_ac97 *ac97)
1453 {
1454 ad18xx_resume(ac97);
1455 snd_ac97_write_cache(ac97, AC97_CODEC_CLASS_REV, 0x8080);
1456 }
1457
1458 #endif
1459
1460 static const struct snd_ac97_res_table ad1819_restbl[] = {
1461 { AC97_PHONE, 0x9f1f },
1462 { AC97_MIC, 0x9f1f },
1463 { AC97_LINE, 0x9f1f },
1464 { AC97_CD, 0x9f1f },
1465 { AC97_VIDEO, 0x9f1f },
1466 { AC97_AUX, 0x9f1f },
1467 { AC97_PCM, 0x9f1f },
1468 { }
1469 };
1470
1471 static int patch_ad1819(struct snd_ac97 * ac97)
1472 {
1473 unsigned short scfg;
1474
1475
1476 scfg = snd_ac97_read(ac97, AC97_AD_SERIAL_CFG);
1477 snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, scfg | 0x7000);
1478 ac97->res_table = ad1819_restbl;
1479 return 0;
1480 }
1481
1482 static unsigned short patch_ad1881_unchained(struct snd_ac97 * ac97, int idx, unsigned short mask)
1483 {
1484 unsigned short val;
1485
1486
1487 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, mask);
1488 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0000);
1489 val = snd_ac97_read(ac97, AC97_VENDOR_ID2);
1490 if ((val & 0xff40) != 0x5340)
1491 return 0;
1492 ac97->spec.ad18xx.unchained[idx] = mask;
1493 ac97->spec.ad18xx.id[idx] = val;
1494 ac97->spec.ad18xx.codec_cfg[idx] = 0x0000;
1495 return mask;
1496 }
1497
1498 static int patch_ad1881_chained1(struct snd_ac97 * ac97, int idx, unsigned short codec_bits)
1499 {
1500 static const int cfg_bits[3] = { 1<<12, 1<<14, 1<<13 };
1501 unsigned short val;
1502
1503 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, cfg_bits[idx]);
1504 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0004);
1505 val = snd_ac97_read(ac97, AC97_VENDOR_ID2);
1506 if ((val & 0xff40) != 0x5340)
1507 return 0;
1508 if (codec_bits)
1509 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, codec_bits);
1510 ac97->spec.ad18xx.chained[idx] = cfg_bits[idx];
1511 ac97->spec.ad18xx.id[idx] = val;
1512 ac97->spec.ad18xx.codec_cfg[idx] = codec_bits ? codec_bits : 0x0004;
1513 return 1;
1514 }
1515
1516 static void patch_ad1881_chained(struct snd_ac97 * ac97, int unchained_idx, int cidx1, int cidx2)
1517 {
1518
1519 if (ac97->spec.ad18xx.unchained[cidx1] || ac97->spec.ad18xx.chained[cidx1])
1520 cidx1 = -1;
1521 if (ac97->spec.ad18xx.unchained[cidx2] || ac97->spec.ad18xx.chained[cidx2])
1522 cidx2 = -1;
1523 if (cidx1 < 0 && cidx2 < 0)
1524 return;
1525
1526 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
1527 ac97->spec.ad18xx.unchained[unchained_idx]);
1528 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0002);
1529 ac97->spec.ad18xx.codec_cfg[unchained_idx] = 0x0002;
1530 if (cidx1 >= 0) {
1531 if (cidx2 < 0)
1532 patch_ad1881_chained1(ac97, cidx1, 0);
1533 else if (patch_ad1881_chained1(ac97, cidx1, 0x0006))
1534 patch_ad1881_chained1(ac97, cidx2, 0);
1535 else if (patch_ad1881_chained1(ac97, cidx2, 0x0006))
1536 patch_ad1881_chained1(ac97, cidx1, 0);
1537 } else if (cidx2 >= 0) {
1538 patch_ad1881_chained1(ac97, cidx2, 0);
1539 }
1540 }
1541
1542 static const struct snd_ac97_build_ops patch_ad1881_build_ops = {
1543 #ifdef CONFIG_PM
1544 .resume = ad18xx_resume
1545 #endif
1546 };
1547
1548 static int patch_ad1881(struct snd_ac97 * ac97)
1549 {
1550 static const char cfg_idxs[3][2] = {
1551 {2, 1},
1552 {0, 2},
1553 {0, 1}
1554 };
1555
1556
1557 unsigned short codecs[3];
1558 unsigned short val;
1559 int idx, num;
1560
1561 val = snd_ac97_read(ac97, AC97_AD_SERIAL_CFG);
1562 snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, val);
1563 codecs[0] = patch_ad1881_unchained(ac97, 0, (1<<12));
1564 codecs[1] = patch_ad1881_unchained(ac97, 1, (1<<14));
1565 codecs[2] = patch_ad1881_unchained(ac97, 2, (1<<13));
1566
1567 if (! (codecs[0] || codecs[1] || codecs[2]))
1568 goto __end;
1569
1570 for (idx = 0; idx < 3; idx++)
1571 if (ac97->spec.ad18xx.unchained[idx])
1572 patch_ad1881_chained(ac97, idx, cfg_idxs[idx][0], cfg_idxs[idx][1]);
1573
1574 if (ac97->spec.ad18xx.id[1]) {
1575 ac97->flags |= AC97_AD_MULTI;
1576 ac97->scaps |= AC97_SCAP_SURROUND_DAC;
1577 }
1578 if (ac97->spec.ad18xx.id[2]) {
1579 ac97->flags |= AC97_AD_MULTI;
1580 ac97->scaps |= AC97_SCAP_CENTER_LFE_DAC;
1581 }
1582
1583 __end:
1584
1585 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
1586
1587 for (idx = num = 0; idx < 3; idx++)
1588 if (ac97->spec.ad18xx.id[idx])
1589 num++;
1590 if (num == 1) {
1591
1592 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0000);
1593 ac97->spec.ad18xx.codec_cfg[0] =
1594 ac97->spec.ad18xx.codec_cfg[1] =
1595 ac97->spec.ad18xx.codec_cfg[2] = 0x0000;
1596 }
1597
1598 ac97->ext_id = snd_ac97_read(ac97, AC97_EXTENDED_ID);
1599 if (ac97->spec.ad18xx.id[0]) {
1600 ac97->id &= 0xffff0000;
1601 ac97->id |= ac97->spec.ad18xx.id[0];
1602 }
1603 ac97->build_ops = &patch_ad1881_build_ops;
1604 return 0;
1605 }
1606
1607 static const struct snd_kcontrol_new snd_ac97_controls_ad1885[] = {
1608 AC97_SINGLE("Digital Mono Direct", AC97_AD_MISC, 11, 1, 0),
1609
1610 AC97_SINGLE("Low Power Mixer", AC97_AD_MISC, 14, 1, 0),
1611 AC97_SINGLE("Zero Fill DAC", AC97_AD_MISC, 15, 1, 0),
1612 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 9, 1, 1),
1613 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 8, 1, 1),
1614 };
1615
1616 static const DECLARE_TLV_DB_SCALE(db_scale_6bit_6db_max, -8850, 150, 0);
1617
1618 static int patch_ad1885_specific(struct snd_ac97 * ac97)
1619 {
1620 int err;
1621
1622 err = patch_build_controls(ac97, snd_ac97_controls_ad1885, ARRAY_SIZE(snd_ac97_controls_ad1885));
1623 if (err < 0)
1624 return err;
1625 reset_tlv(ac97, "Headphone Playback Volume",
1626 db_scale_6bit_6db_max);
1627 return 0;
1628 }
1629
1630 static const struct snd_ac97_build_ops patch_ad1885_build_ops = {
1631 .build_specific = &patch_ad1885_specific,
1632 #ifdef CONFIG_PM
1633 .resume = ad18xx_resume
1634 #endif
1635 };
1636
1637 static int patch_ad1885(struct snd_ac97 * ac97)
1638 {
1639 patch_ad1881(ac97);
1640
1641
1642
1643
1644 snd_ac97_write_cache(ac97, AC97_AD_MISC, 0x0404);
1645
1646 ac97->build_ops = &patch_ad1885_build_ops;
1647 return 0;
1648 }
1649
1650 static int patch_ad1886_specific(struct snd_ac97 * ac97)
1651 {
1652 reset_tlv(ac97, "Headphone Playback Volume",
1653 db_scale_6bit_6db_max);
1654 return 0;
1655 }
1656
1657 static const struct snd_ac97_build_ops patch_ad1886_build_ops = {
1658 .build_specific = &patch_ad1886_specific,
1659 #ifdef CONFIG_PM
1660 .resume = ad18xx_resume
1661 #endif
1662 };
1663
1664 static int patch_ad1886(struct snd_ac97 * ac97)
1665 {
1666 patch_ad1881(ac97);
1667
1668
1669 snd_ac97_write_cache(ac97, AC97_AD_JACK_SPDIF, 0x0010);
1670 ac97->build_ops = &patch_ad1886_build_ops;
1671 return 0;
1672 }
1673
1674
1675 #define AC97_AD198X_MBC 0x0003
1676 #define AC97_AD198X_MBC_20 0x0000
1677 #define AC97_AD198X_MBC_10 0x0001
1678 #define AC97_AD198X_MBC_30 0x0002
1679 #define AC97_AD198X_VREFD 0x0004
1680 #define AC97_AD198X_VREFH 0x0008
1681 #define AC97_AD198X_VREF_0 0x000c
1682 #define AC97_AD198X_VREF_MASK (AC97_AD198X_VREFH | AC97_AD198X_VREFD)
1683 #define AC97_AD198X_VREF_SHIFT 2
1684 #define AC97_AD198X_SRU 0x0010
1685 #define AC97_AD198X_LOSEL 0x0020
1686 #define AC97_AD198X_2MIC 0x0040
1687 #define AC97_AD198X_SPRD 0x0080
1688 #define AC97_AD198X_DMIX0 0x0100
1689
1690 #define AC97_AD198X_DMIX1 0x0200
1691 #define AC97_AD198X_HPSEL 0x0400
1692 #define AC97_AD198X_CLDIS 0x0800
1693 #define AC97_AD198X_LODIS 0x1000
1694 #define AC97_AD198X_MSPLT 0x2000
1695 #define AC97_AD198X_AC97NC 0x4000
1696 #define AC97_AD198X_DACZ 0x8000
1697
1698
1699 #define AC97_AD1986_MBC 0x0003
1700 #define AC97_AD1986_MBC_20 0x0000
1701 #define AC97_AD1986_MBC_10 0x0001
1702 #define AC97_AD1986_MBC_30 0x0002
1703 #define AC97_AD1986_LISEL0 0x0004
1704 #define AC97_AD1986_LISEL1 0x0008
1705 #define AC97_AD1986_LISEL_MASK (AC97_AD1986_LISEL1 | AC97_AD1986_LISEL0)
1706 #define AC97_AD1986_LISEL_LI 0x0000
1707 #define AC97_AD1986_LISEL_SURR 0x0004
1708 #define AC97_AD1986_LISEL_MIC 0x0008
1709 #define AC97_AD1986_SRU 0x0010
1710 #define AC97_AD1986_SOSEL 0x0020
1711 #define AC97_AD1986_2MIC 0x0040
1712 #define AC97_AD1986_SPRD 0x0080
1713 #define AC97_AD1986_DMIX0 0x0100
1714
1715 #define AC97_AD1986_DMIX1 0x0200
1716 #define AC97_AD1986_CLDIS 0x0800
1717 #define AC97_AD1986_SODIS 0x1000
1718 #define AC97_AD1986_MSPLT 0x2000
1719 #define AC97_AD1986_AC97NC 0x4000
1720 #define AC97_AD1986_DACZ 0x8000
1721
1722
1723 #define AC97_AD_MISC2 0x70
1724
1725 #define AC97_AD1986_CVREF0 0x0004
1726 #define AC97_AD1986_CVREF1 0x0008
1727 #define AC97_AD1986_CVREF2 0x0010
1728 #define AC97_AD1986_CVREF_MASK \
1729 (AC97_AD1986_CVREF2 | AC97_AD1986_CVREF1 | AC97_AD1986_CVREF0)
1730 #define AC97_AD1986_JSMAP 0x0020
1731 #define AC97_AD1986_MMDIS 0x0080
1732 #define AC97_AD1986_MVREF0 0x0400
1733 #define AC97_AD1986_MVREF1 0x0800
1734 #define AC97_AD1986_MVREF2 0x1000
1735 #define AC97_AD1986_MVREF_MASK \
1736 (AC97_AD1986_MVREF2 | AC97_AD1986_MVREF1 | AC97_AD1986_MVREF0)
1737
1738
1739 #define AC97_AD_MISC3 0x7a
1740
1741 #define AC97_AD1986_MMIX 0x0004
1742 #define AC97_AD1986_GPO 0x0008
1743 #define AC97_AD1986_LOHPEN 0x0010
1744 #define AC97_AD1986_LVREF0 0x0100
1745 #define AC97_AD1986_LVREF1 0x0200
1746 #define AC97_AD1986_LVREF2 0x0400
1747 #define AC97_AD1986_LVREF_MASK \
1748 (AC97_AD1986_LVREF2 | AC97_AD1986_LVREF1 | AC97_AD1986_LVREF0)
1749 #define AC97_AD1986_JSINVA 0x0800
1750 #define AC97_AD1986_LOSEL 0x1000
1751 #define AC97_AD1986_HPSEL0 0x2000
1752
1753 #define AC97_AD1986_HPSEL1 0x4000
1754
1755 #define AC97_AD1986_JSINVB 0x8000
1756
1757
1758 #define AC97_AD1986_OMS0 0x0100
1759 #define AC97_AD1986_OMS1 0x0200
1760 #define AC97_AD1986_OMS2 0x0400
1761 #define AC97_AD1986_OMS_MASK \
1762 (AC97_AD1986_OMS2 | AC97_AD1986_OMS1 | AC97_AD1986_OMS0)
1763 #define AC97_AD1986_OMS_M 0x0000
1764 #define AC97_AD1986_OMS_L 0x0100
1765 #define AC97_AD1986_OMS_C 0x0200
1766 #define AC97_AD1986_OMS_MC 0x0400
1767
1768 #define AC97_AD1986_OMS_ML 0x0500
1769
1770 #define AC97_AD1986_OMS_LC 0x0600
1771
1772 #define AC97_AD1986_OMS_MLC 0x0700
1773
1774
1775
1776 static int snd_ac97_ad198x_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1777 {
1778 static const char * const texts[2] = { "AC-Link", "A/D Converter" };
1779
1780 return snd_ctl_enum_info(uinfo, 1, 2, texts);
1781 }
1782
1783 static int snd_ac97_ad198x_spdif_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1784 {
1785 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1786 unsigned short val;
1787
1788 val = ac97->regs[AC97_AD_SERIAL_CFG];
1789 ucontrol->value.enumerated.item[0] = (val >> 2) & 1;
1790 return 0;
1791 }
1792
1793 static int snd_ac97_ad198x_spdif_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1794 {
1795 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1796 unsigned short val;
1797
1798 if (ucontrol->value.enumerated.item[0] > 1)
1799 return -EINVAL;
1800 val = ucontrol->value.enumerated.item[0] << 2;
1801 return snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x0004, val);
1802 }
1803
1804 static const struct snd_kcontrol_new snd_ac97_ad198x_spdif_source = {
1805 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1806 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1807 .info = snd_ac97_ad198x_spdif_source_info,
1808 .get = snd_ac97_ad198x_spdif_source_get,
1809 .put = snd_ac97_ad198x_spdif_source_put,
1810 };
1811
1812 static int patch_ad198x_post_spdif(struct snd_ac97 * ac97)
1813 {
1814 return patch_build_controls(ac97, &snd_ac97_ad198x_spdif_source, 1);
1815 }
1816
1817 static const struct snd_kcontrol_new snd_ac97_ad1981x_jack_sense[] = {
1818 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 11, 1, 0),
1819 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
1820 };
1821
1822
1823
1824
1825 static const unsigned int ad1981_jacks_denylist[] = {
1826 0x10140523,
1827 0x10140534,
1828 0x10140537,
1829 0x1014053e,
1830 0x10140554,
1831 0x10140567,
1832 0x10140581,
1833 0x10280160,
1834 0x104380b0,
1835 0x11790241,
1836 0x1179ff10,
1837 0x144dc01a,
1838 0
1839 };
1840
1841 static int check_list(struct snd_ac97 *ac97, const unsigned int *list)
1842 {
1843 u32 subid = ((u32)ac97->subsystem_vendor << 16) | ac97->subsystem_device;
1844 for (; *list; list++)
1845 if (*list == subid)
1846 return 1;
1847 return 0;
1848 }
1849
1850 static int patch_ad1981a_specific(struct snd_ac97 * ac97)
1851 {
1852 if (check_list(ac97, ad1981_jacks_denylist))
1853 return 0;
1854 return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense,
1855 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
1856 }
1857
1858 static const struct snd_ac97_build_ops patch_ad1981a_build_ops = {
1859 .build_post_spdif = patch_ad198x_post_spdif,
1860 .build_specific = patch_ad1981a_specific,
1861 #ifdef CONFIG_PM
1862 .resume = ad18xx_resume
1863 #endif
1864 };
1865
1866
1867
1868
1869 static const unsigned int ad1981_jacks_allowlist[] = {
1870 0x0e11005a,
1871 0x103c0890,
1872 0x103c0938,
1873 0x103c099c,
1874 0x103c0944,
1875 0x103c0934,
1876 0x103c006d,
1877 0x103c300d,
1878 0x17340088,
1879 0
1880 };
1881
1882 static void check_ad1981_hp_jack_sense(struct snd_ac97 *ac97)
1883 {
1884 if (check_list(ac97, ad1981_jacks_allowlist))
1885
1886 snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11);
1887 }
1888
1889 static int patch_ad1981a(struct snd_ac97 *ac97)
1890 {
1891 patch_ad1881(ac97);
1892 ac97->build_ops = &patch_ad1981a_build_ops;
1893 snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT);
1894 ac97->flags |= AC97_STEREO_MUTES;
1895 check_ad1981_hp_jack_sense(ac97);
1896 return 0;
1897 }
1898
1899 static const struct snd_kcontrol_new snd_ac97_ad198x_2cmic =
1900 AC97_SINGLE("Stereo Mic", AC97_AD_MISC, 6, 1, 0);
1901
1902 static int patch_ad1981b_specific(struct snd_ac97 *ac97)
1903 {
1904 int err;
1905
1906 err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1);
1907 if (err < 0)
1908 return err;
1909 if (check_list(ac97, ad1981_jacks_denylist))
1910 return 0;
1911 return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense,
1912 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
1913 }
1914
1915 static const struct snd_ac97_build_ops patch_ad1981b_build_ops = {
1916 .build_post_spdif = patch_ad198x_post_spdif,
1917 .build_specific = patch_ad1981b_specific,
1918 #ifdef CONFIG_PM
1919 .resume = ad18xx_resume
1920 #endif
1921 };
1922
1923 static int patch_ad1981b(struct snd_ac97 *ac97)
1924 {
1925 patch_ad1881(ac97);
1926 ac97->build_ops = &patch_ad1981b_build_ops;
1927 snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT);
1928 ac97->flags |= AC97_STEREO_MUTES;
1929 check_ad1981_hp_jack_sense(ac97);
1930 return 0;
1931 }
1932
1933 #define snd_ac97_ad1888_lohpsel_info snd_ctl_boolean_mono_info
1934
1935 static int snd_ac97_ad1888_lohpsel_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1936 {
1937 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1938 unsigned short val;
1939
1940 val = ac97->regs[AC97_AD_MISC];
1941 ucontrol->value.integer.value[0] = !(val & AC97_AD198X_LOSEL);
1942 if (ac97->spec.ad18xx.lo_as_master)
1943 ucontrol->value.integer.value[0] =
1944 !ucontrol->value.integer.value[0];
1945 return 0;
1946 }
1947
1948 static int snd_ac97_ad1888_lohpsel_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1949 {
1950 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1951 unsigned short val;
1952
1953 val = !ucontrol->value.integer.value[0];
1954 if (ac97->spec.ad18xx.lo_as_master)
1955 val = !val;
1956 val = val ? (AC97_AD198X_LOSEL | AC97_AD198X_HPSEL) : 0;
1957 return snd_ac97_update_bits(ac97, AC97_AD_MISC,
1958 AC97_AD198X_LOSEL | AC97_AD198X_HPSEL, val);
1959 }
1960
1961 static int snd_ac97_ad1888_downmix_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1962 {
1963 static const char * const texts[3] = {"Off", "6 -> 4", "6 -> 2"};
1964
1965 return snd_ctl_enum_info(uinfo, 1, 3, texts);
1966 }
1967
1968 static int snd_ac97_ad1888_downmix_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1969 {
1970 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1971 unsigned short val;
1972
1973 val = ac97->regs[AC97_AD_MISC];
1974 if (!(val & AC97_AD198X_DMIX1))
1975 ucontrol->value.enumerated.item[0] = 0;
1976 else
1977 ucontrol->value.enumerated.item[0] = 1 + ((val >> 8) & 1);
1978 return 0;
1979 }
1980
1981 static int snd_ac97_ad1888_downmix_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1982 {
1983 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1984 unsigned short val;
1985
1986 if (ucontrol->value.enumerated.item[0] > 2)
1987 return -EINVAL;
1988 if (ucontrol->value.enumerated.item[0] == 0)
1989 val = 0;
1990 else
1991 val = AC97_AD198X_DMIX1 |
1992 ((ucontrol->value.enumerated.item[0] - 1) << 8);
1993 return snd_ac97_update_bits(ac97, AC97_AD_MISC,
1994 AC97_AD198X_DMIX0 | AC97_AD198X_DMIX1, val);
1995 }
1996
1997 static void ad1888_update_jacks(struct snd_ac97 *ac97)
1998 {
1999 unsigned short val = 0;
2000
2001 if (!ac97->spec.ad18xx.lo_as_master && is_shared_linein(ac97))
2002 val |= (1 << 12);
2003
2004 if (is_shared_micin(ac97))
2005 val |= (1 << 11);
2006
2007 snd_ac97_update_bits(ac97, AC97_AD_MISC, (1 << 11) | (1 << 12), val);
2008 }
2009
2010 static const struct snd_kcontrol_new snd_ac97_ad1888_controls[] = {
2011 {
2012 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2013 .name = "Exchange Front/Surround",
2014 .info = snd_ac97_ad1888_lohpsel_info,
2015 .get = snd_ac97_ad1888_lohpsel_get,
2016 .put = snd_ac97_ad1888_lohpsel_put
2017 },
2018 AC97_SINGLE("V_REFOUT Enable", AC97_AD_MISC, AC97_AD_VREFD_SHIFT, 1, 1),
2019 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2,
2020 AC97_AD_HPFD_SHIFT, 1, 1),
2021 AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC, 7, 1, 0),
2022 {
2023 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2024 .name = "Downmix",
2025 .info = snd_ac97_ad1888_downmix_info,
2026 .get = snd_ac97_ad1888_downmix_get,
2027 .put = snd_ac97_ad1888_downmix_put
2028 },
2029 AC97_SURROUND_JACK_MODE_CTL,
2030 AC97_CHANNEL_MODE_CTL,
2031
2032 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0),
2033 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
2034 };
2035
2036 static int patch_ad1888_specific(struct snd_ac97 *ac97)
2037 {
2038 if (!ac97->spec.ad18xx.lo_as_master) {
2039
2040 snd_ac97_rename_vol_ctl(ac97, "Master Playback",
2041 "Master Surround Playback");
2042 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback",
2043 "Master Playback");
2044 }
2045 return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls));
2046 }
2047
2048 static const struct snd_ac97_build_ops patch_ad1888_build_ops = {
2049 .build_post_spdif = patch_ad198x_post_spdif,
2050 .build_specific = patch_ad1888_specific,
2051 #ifdef CONFIG_PM
2052 .resume = ad1888_resume,
2053 #endif
2054 .update_jacks = ad1888_update_jacks,
2055 };
2056
2057 static int patch_ad1888(struct snd_ac97 * ac97)
2058 {
2059 unsigned short misc;
2060
2061 patch_ad1881(ac97);
2062 ac97->build_ops = &patch_ad1888_build_ops;
2063
2064
2065
2066
2067
2068 if (ac97->subsystem_vendor == 0x1043 &&
2069 ac97->subsystem_device == 0x1193)
2070 ac97->spec.ad18xx.lo_as_master = 1;
2071
2072 misc = snd_ac97_read(ac97, AC97_AD_MISC);
2073
2074
2075 misc |= AC97_AD198X_MSPLT | AC97_AD198X_AC97NC;
2076 if (!ac97->spec.ad18xx.lo_as_master)
2077
2078
2079
2080
2081 misc |= AC97_AD198X_LOSEL | AC97_AD198X_HPSEL;
2082
2083 snd_ac97_write_cache(ac97, AC97_AD_MISC, misc);
2084 ac97->flags |= AC97_STEREO_MUTES;
2085 return 0;
2086 }
2087
2088 static int patch_ad1980_specific(struct snd_ac97 *ac97)
2089 {
2090 int err;
2091
2092 err = patch_ad1888_specific(ac97);
2093 if (err < 0)
2094 return err;
2095 return patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1);
2096 }
2097
2098 static const struct snd_ac97_build_ops patch_ad1980_build_ops = {
2099 .build_post_spdif = patch_ad198x_post_spdif,
2100 .build_specific = patch_ad1980_specific,
2101 #ifdef CONFIG_PM
2102 .resume = ad18xx_resume,
2103 #endif
2104 .update_jacks = ad1888_update_jacks,
2105 };
2106
2107 static int patch_ad1980(struct snd_ac97 * ac97)
2108 {
2109 patch_ad1888(ac97);
2110 ac97->build_ops = &patch_ad1980_build_ops;
2111 return 0;
2112 }
2113
2114 static int snd_ac97_ad1985_vrefout_info(struct snd_kcontrol *kcontrol,
2115 struct snd_ctl_elem_info *uinfo)
2116 {
2117 static const char * const texts[4] = {
2118 "High-Z", "3.7 V", "2.25 V", "0 V"
2119 };
2120
2121 return snd_ctl_enum_info(uinfo, 1, 4, texts);
2122 }
2123
2124 static int snd_ac97_ad1985_vrefout_get(struct snd_kcontrol *kcontrol,
2125 struct snd_ctl_elem_value *ucontrol)
2126 {
2127 static const int reg2ctrl[4] = {2, 0, 1, 3};
2128 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2129 unsigned short val;
2130 val = (ac97->regs[AC97_AD_MISC] & AC97_AD198X_VREF_MASK)
2131 >> AC97_AD198X_VREF_SHIFT;
2132 ucontrol->value.enumerated.item[0] = reg2ctrl[val];
2133 return 0;
2134 }
2135
2136 static int snd_ac97_ad1985_vrefout_put(struct snd_kcontrol *kcontrol,
2137 struct snd_ctl_elem_value *ucontrol)
2138 {
2139 static const int ctrl2reg[4] = {1, 2, 0, 3};
2140 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2141 unsigned short val;
2142
2143 if (ucontrol->value.enumerated.item[0] > 3)
2144 return -EINVAL;
2145 val = ctrl2reg[ucontrol->value.enumerated.item[0]]
2146 << AC97_AD198X_VREF_SHIFT;
2147 return snd_ac97_update_bits(ac97, AC97_AD_MISC,
2148 AC97_AD198X_VREF_MASK, val);
2149 }
2150
2151 static const struct snd_kcontrol_new snd_ac97_ad1985_controls[] = {
2152 AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0),
2153 {
2154 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2155 .name = "Exchange Front/Surround",
2156 .info = snd_ac97_ad1888_lohpsel_info,
2157 .get = snd_ac97_ad1888_lohpsel_get,
2158 .put = snd_ac97_ad1888_lohpsel_put
2159 },
2160 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2, 12, 1, 1),
2161 AC97_SINGLE("Spread Front to Surround and Center/LFE",
2162 AC97_AD_MISC, 7, 1, 0),
2163 {
2164 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2165 .name = "Downmix",
2166 .info = snd_ac97_ad1888_downmix_info,
2167 .get = snd_ac97_ad1888_downmix_get,
2168 .put = snd_ac97_ad1888_downmix_put
2169 },
2170 {
2171 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2172 .name = "V_REFOUT",
2173 .info = snd_ac97_ad1985_vrefout_info,
2174 .get = snd_ac97_ad1985_vrefout_get,
2175 .put = snd_ac97_ad1985_vrefout_put
2176 },
2177 AC97_SURROUND_JACK_MODE_CTL,
2178 AC97_CHANNEL_MODE_CTL,
2179
2180 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0),
2181 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
2182 };
2183
2184 static void ad1985_update_jacks(struct snd_ac97 *ac97)
2185 {
2186 ad1888_update_jacks(ac97);
2187
2188 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 1 << 9,
2189 is_shared_micin(ac97) ? 1 << 9 : 0);
2190 }
2191
2192 static int patch_ad1985_specific(struct snd_ac97 *ac97)
2193 {
2194 int err;
2195
2196
2197 snd_ac97_rename_vol_ctl(ac97, "Master Playback",
2198 "Master Surround Playback");
2199 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback");
2200
2201 err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1);
2202 if (err < 0)
2203 return err;
2204
2205 return patch_build_controls(ac97, snd_ac97_ad1985_controls,
2206 ARRAY_SIZE(snd_ac97_ad1985_controls));
2207 }
2208
2209 static const struct snd_ac97_build_ops patch_ad1985_build_ops = {
2210 .build_post_spdif = patch_ad198x_post_spdif,
2211 .build_specific = patch_ad1985_specific,
2212 #ifdef CONFIG_PM
2213 .resume = ad18xx_resume,
2214 #endif
2215 .update_jacks = ad1985_update_jacks,
2216 };
2217
2218 static int patch_ad1985(struct snd_ac97 * ac97)
2219 {
2220 unsigned short misc;
2221
2222 patch_ad1881(ac97);
2223 ac97->build_ops = &patch_ad1985_build_ops;
2224 misc = snd_ac97_read(ac97, AC97_AD_MISC);
2225
2226
2227
2228 snd_ac97_write_cache(ac97, AC97_AD_MISC, misc |
2229 AC97_AD198X_LOSEL |
2230 AC97_AD198X_HPSEL |
2231 AC97_AD198X_MSPLT |
2232 AC97_AD198X_AC97NC);
2233 ac97->flags |= AC97_STEREO_MUTES;
2234
2235
2236 ad1985_update_jacks(ac97);
2237
2238
2239 ac97->ext_id = (ac97->ext_id & ~AC97_EI_REV_MASK) | AC97_EI_REV_23;
2240 return 0;
2241 }
2242
2243 #define snd_ac97_ad1986_bool_info snd_ctl_boolean_mono_info
2244
2245 static int snd_ac97_ad1986_lososel_get(struct snd_kcontrol *kcontrol,
2246 struct snd_ctl_elem_value *ucontrol)
2247 {
2248 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2249 unsigned short val;
2250
2251 val = ac97->regs[AC97_AD_MISC3];
2252 ucontrol->value.integer.value[0] = (val & AC97_AD1986_LOSEL) != 0;
2253 return 0;
2254 }
2255
2256 static int snd_ac97_ad1986_lososel_put(struct snd_kcontrol *kcontrol,
2257 struct snd_ctl_elem_value *ucontrol)
2258 {
2259 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2260 int ret0;
2261 int ret1;
2262 int sprd = (ac97->regs[AC97_AD_MISC] & AC97_AD1986_SPRD) != 0;
2263
2264 ret0 = snd_ac97_update_bits(ac97, AC97_AD_MISC3, AC97_AD1986_LOSEL,
2265 ucontrol->value.integer.value[0] != 0
2266 ? AC97_AD1986_LOSEL : 0);
2267 if (ret0 < 0)
2268 return ret0;
2269
2270
2271 ret1 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SOSEL,
2272 (ucontrol->value.integer.value[0] != 0
2273 || sprd)
2274 ? AC97_AD1986_SOSEL : 0);
2275 if (ret1 < 0)
2276 return ret1;
2277
2278 return (ret0 > 0 || ret1 > 0) ? 1 : 0;
2279 }
2280
2281 static int snd_ac97_ad1986_spread_get(struct snd_kcontrol *kcontrol,
2282 struct snd_ctl_elem_value *ucontrol)
2283 {
2284 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2285 unsigned short val;
2286
2287 val = ac97->regs[AC97_AD_MISC];
2288 ucontrol->value.integer.value[0] = (val & AC97_AD1986_SPRD) != 0;
2289 return 0;
2290 }
2291
2292 static int snd_ac97_ad1986_spread_put(struct snd_kcontrol *kcontrol,
2293 struct snd_ctl_elem_value *ucontrol)
2294 {
2295 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2296 int ret0;
2297 int ret1;
2298 int sprd = (ac97->regs[AC97_AD_MISC3] & AC97_AD1986_LOSEL) != 0;
2299
2300 ret0 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SPRD,
2301 ucontrol->value.integer.value[0] != 0
2302 ? AC97_AD1986_SPRD : 0);
2303 if (ret0 < 0)
2304 return ret0;
2305
2306
2307 ret1 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SOSEL,
2308 (ucontrol->value.integer.value[0] != 0
2309 || sprd)
2310 ? AC97_AD1986_SOSEL : 0);
2311 if (ret1 < 0)
2312 return ret1;
2313
2314 return (ret0 > 0 || ret1 > 0) ? 1 : 0;
2315 }
2316
2317 static int snd_ac97_ad1986_miclisel_get(struct snd_kcontrol *kcontrol,
2318 struct snd_ctl_elem_value *ucontrol)
2319 {
2320 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2321
2322 ucontrol->value.integer.value[0] = ac97->spec.ad18xx.swap_mic_linein;
2323 return 0;
2324 }
2325
2326 static int snd_ac97_ad1986_miclisel_put(struct snd_kcontrol *kcontrol,
2327 struct snd_ctl_elem_value *ucontrol)
2328 {
2329 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2330 unsigned char swap = ucontrol->value.integer.value[0] != 0;
2331
2332 if (swap != ac97->spec.ad18xx.swap_mic_linein) {
2333 ac97->spec.ad18xx.swap_mic_linein = swap;
2334 if (ac97->build_ops->update_jacks)
2335 ac97->build_ops->update_jacks(ac97);
2336 return 1;
2337 }
2338 return 0;
2339 }
2340
2341 static int snd_ac97_ad1986_vrefout_get(struct snd_kcontrol *kcontrol,
2342 struct snd_ctl_elem_value *ucontrol)
2343 {
2344
2345 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2346 unsigned short val;
2347 unsigned short reg = ac97->regs[AC97_AD_MISC2];
2348 if ((reg & AC97_AD1986_MVREF0) != 0)
2349 val = 2;
2350 else if ((reg & AC97_AD1986_MVREF1) != 0)
2351 val = 3;
2352 else if ((reg & AC97_AD1986_MVREF2) != 0)
2353 val = 1;
2354 else
2355 val = 0;
2356 ucontrol->value.enumerated.item[0] = val;
2357 return 0;
2358 }
2359
2360 static int snd_ac97_ad1986_vrefout_put(struct snd_kcontrol *kcontrol,
2361 struct snd_ctl_elem_value *ucontrol)
2362 {
2363 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2364 unsigned short cval;
2365 unsigned short lval;
2366 unsigned short mval;
2367 int cret;
2368 int lret;
2369 int mret;
2370
2371 switch (ucontrol->value.enumerated.item[0])
2372 {
2373 case 0:
2374 cval = 0;
2375 lval = 0;
2376 mval = 0;
2377 break;
2378 case 1:
2379 cval = AC97_AD1986_CVREF2;
2380 lval = AC97_AD1986_LVREF2;
2381 mval = AC97_AD1986_MVREF2;
2382 break;
2383 case 2:
2384 cval = AC97_AD1986_CVREF0;
2385 lval = AC97_AD1986_LVREF0;
2386 mval = AC97_AD1986_MVREF0;
2387 break;
2388 case 3:
2389 cval = AC97_AD1986_CVREF1;
2390 lval = AC97_AD1986_LVREF1;
2391 mval = AC97_AD1986_MVREF1;
2392 break;
2393 default:
2394 return -EINVAL;
2395 }
2396
2397 cret = snd_ac97_update_bits(ac97, AC97_AD_MISC2,
2398 AC97_AD1986_CVREF_MASK, cval);
2399 if (cret < 0)
2400 return cret;
2401 lret = snd_ac97_update_bits(ac97, AC97_AD_MISC3,
2402 AC97_AD1986_LVREF_MASK, lval);
2403 if (lret < 0)
2404 return lret;
2405 mret = snd_ac97_update_bits(ac97, AC97_AD_MISC2,
2406 AC97_AD1986_MVREF_MASK, mval);
2407 if (mret < 0)
2408 return mret;
2409
2410 return (cret > 0 || lret > 0 || mret > 0) ? 1 : 0;
2411 }
2412
2413 static const struct snd_kcontrol_new snd_ac97_ad1986_controls[] = {
2414 AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0),
2415 {
2416 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2417 .name = "Exchange Front/Surround",
2418 .info = snd_ac97_ad1986_bool_info,
2419 .get = snd_ac97_ad1986_lososel_get,
2420 .put = snd_ac97_ad1986_lososel_put
2421 },
2422 {
2423 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2424 .name = "Exchange Mic/Line In",
2425 .info = snd_ac97_ad1986_bool_info,
2426 .get = snd_ac97_ad1986_miclisel_get,
2427 .put = snd_ac97_ad1986_miclisel_put
2428 },
2429 {
2430 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2431 .name = "Spread Front to Surround and Center/LFE",
2432 .info = snd_ac97_ad1986_bool_info,
2433 .get = snd_ac97_ad1986_spread_get,
2434 .put = snd_ac97_ad1986_spread_put
2435 },
2436 {
2437 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2438 .name = "Downmix",
2439 .info = snd_ac97_ad1888_downmix_info,
2440 .get = snd_ac97_ad1888_downmix_get,
2441 .put = snd_ac97_ad1888_downmix_put
2442 },
2443 {
2444 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2445 .name = "V_REFOUT",
2446 .info = snd_ac97_ad1985_vrefout_info,
2447 .get = snd_ac97_ad1986_vrefout_get,
2448 .put = snd_ac97_ad1986_vrefout_put
2449 },
2450 AC97_SURROUND_JACK_MODE_CTL,
2451 AC97_CHANNEL_MODE_CTL,
2452
2453 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0),
2454 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0)
2455 };
2456
2457 static void ad1986_update_jacks(struct snd_ac97 *ac97)
2458 {
2459 unsigned short misc_val = 0;
2460 unsigned short ser_val;
2461
2462
2463 if (!is_surround_on(ac97))
2464 misc_val |= AC97_AD1986_SODIS;
2465 if (!is_clfe_on(ac97))
2466 misc_val |= AC97_AD1986_CLDIS;
2467
2468
2469 if (is_shared_linein(ac97))
2470 misc_val |= AC97_AD1986_LISEL_SURR;
2471 else if (ac97->spec.ad18xx.swap_mic_linein != 0)
2472 misc_val |= AC97_AD1986_LISEL_MIC;
2473 snd_ac97_update_bits(ac97, AC97_AD_MISC,
2474 AC97_AD1986_SODIS | AC97_AD1986_CLDIS |
2475 AC97_AD1986_LISEL_MASK,
2476 misc_val);
2477
2478
2479 if (is_shared_micin(ac97))
2480 ser_val = AC97_AD1986_OMS_C;
2481 else if (ac97->spec.ad18xx.swap_mic_linein != 0)
2482 ser_val = AC97_AD1986_OMS_L;
2483 else
2484 ser_val = AC97_AD1986_OMS_M;
2485 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG,
2486 AC97_AD1986_OMS_MASK,
2487 ser_val);
2488 }
2489
2490 static int patch_ad1986_specific(struct snd_ac97 *ac97)
2491 {
2492 int err;
2493
2494 err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1);
2495 if (err < 0)
2496 return err;
2497
2498 return patch_build_controls(ac97, snd_ac97_ad1986_controls,
2499 ARRAY_SIZE(snd_ac97_ad1985_controls));
2500 }
2501
2502 static const struct snd_ac97_build_ops patch_ad1986_build_ops = {
2503 .build_post_spdif = patch_ad198x_post_spdif,
2504 .build_specific = patch_ad1986_specific,
2505 #ifdef CONFIG_PM
2506 .resume = ad18xx_resume,
2507 #endif
2508 .update_jacks = ad1986_update_jacks,
2509 };
2510
2511 static int patch_ad1986(struct snd_ac97 * ac97)
2512 {
2513 patch_ad1881(ac97);
2514 ac97->build_ops = &patch_ad1986_build_ops;
2515 ac97->flags |= AC97_STEREO_MUTES;
2516
2517
2518 ad1986_update_jacks(ac97);
2519
2520 return 0;
2521 }
2522
2523
2524
2525
2526 static int patch_alc203(struct snd_ac97 *ac97)
2527 {
2528 snd_ac97_update_bits(ac97, 0x7a, 0x400, 0x400);
2529 return 0;
2530 }
2531
2532
2533
2534
2535 static void alc650_update_jacks(struct snd_ac97 *ac97)
2536 {
2537 int shared;
2538
2539
2540 shared = is_shared_surrout(ac97);
2541 snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 9,
2542 shared ? (1 << 9) : 0);
2543
2544 shared = is_shared_clfeout(ac97);
2545
2546 snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12,
2547 shared ? (1 << 12) : 0);
2548
2549 snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 10,
2550 shared ? (1 << 10) : 0);
2551
2552 snd_ac97_update_bits(ac97, AC97_ALC650_GPIO_STATUS, 0x100,
2553 shared ? 0 : 0x100);
2554 }
2555
2556 static int alc650_swap_surround_put(struct snd_kcontrol *kcontrol,
2557 struct snd_ctl_elem_value *ucontrol)
2558 {
2559 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2560 struct snd_pcm_chmap *map = ac97->chmaps[SNDRV_PCM_STREAM_PLAYBACK];
2561
2562 if (map) {
2563 if (ucontrol->value.integer.value[0])
2564 map->chmap = snd_pcm_std_chmaps;
2565 else
2566 map->chmap = snd_pcm_alt_chmaps;
2567 }
2568 return snd_ac97_put_volsw(kcontrol, ucontrol);
2569 }
2570
2571 static const struct snd_kcontrol_new snd_ac97_controls_alc650[] = {
2572 AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0),
2573 AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH, 1, 1, 0),
2574 AC97_SINGLE("Center/LFE Down Mix", AC97_ALC650_MULTICH, 2, 1, 0),
2575 AC97_SINGLE("Exchange Center/LFE", AC97_ALC650_MULTICH, 3, 1, 0),
2576
2577
2578
2579
2580
2581
2582
2583
2584 {
2585 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2586 .name = "Swap Surround Slot",
2587 .info = snd_ac97_info_volsw,
2588 .get = snd_ac97_get_volsw,
2589 .put = alc650_swap_surround_put,
2590 .private_value = AC97_SINGLE_VALUE(AC97_ALC650_MULTICH, 14, 1, 0),
2591 },
2592 #if 0
2593 AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK, 0, 1, 0),
2594 AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK, 1, 1, 0),
2595 AC97_SINGLE("Surround DAC Switch", AC97_ALC650_SURR_DAC_VOL, 15, 1, 1),
2596 AC97_DOUBLE("Surround DAC Volume", AC97_ALC650_SURR_DAC_VOL, 8, 0, 31, 1),
2597 AC97_SINGLE("Center/LFE DAC Switch", AC97_ALC650_LFE_DAC_VOL, 15, 1, 1),
2598 AC97_DOUBLE("Center/LFE DAC Volume", AC97_ALC650_LFE_DAC_VOL, 8, 0, 31, 1),
2599 #endif
2600 AC97_SURROUND_JACK_MODE_CTL,
2601 AC97_CHANNEL_MODE_CTL,
2602 };
2603
2604 static const struct snd_kcontrol_new snd_ac97_spdif_controls_alc650[] = {
2605 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_ALC650_MULTICH, 11, 1, 0),
2606 AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH, 12, 1, 0),
2607
2608
2609 };
2610
2611 static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_max, -4350, 150, 0);
2612
2613 static int patch_alc650_specific(struct snd_ac97 * ac97)
2614 {
2615 int err;
2616
2617 err = patch_build_controls(ac97, snd_ac97_controls_alc650, ARRAY_SIZE(snd_ac97_controls_alc650));
2618 if (err < 0)
2619 return err;
2620 if (ac97->ext_id & AC97_EI_SPDIF) {
2621 err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc650, ARRAY_SIZE(snd_ac97_spdif_controls_alc650));
2622 if (err < 0)
2623 return err;
2624 }
2625 if (ac97->id != AC97_ID_ALC650F)
2626 reset_tlv(ac97, "Master Playback Volume",
2627 db_scale_5bit_3db_max);
2628 return 0;
2629 }
2630
2631 static const struct snd_ac97_build_ops patch_alc650_ops = {
2632 .build_specific = patch_alc650_specific,
2633 .update_jacks = alc650_update_jacks
2634 };
2635
2636 static int patch_alc650(struct snd_ac97 * ac97)
2637 {
2638 unsigned short val;
2639
2640 ac97->build_ops = &patch_alc650_ops;
2641
2642
2643 val = snd_ac97_read(ac97, AC97_ALC650_REVISION) & 0x3f;
2644 if (val < 3)
2645 ac97->id = 0x414c4720;
2646 else if (val < 0x10)
2647 ac97->id = 0x414c4721;
2648 else if (val < 0x20)
2649 ac97->id = 0x414c4722;
2650 else if (val < 0x30)
2651 ac97->id = 0x414c4723;
2652
2653
2654
2655 ac97->spec.dev_flags = (ac97->id == 0x414c4722 ||
2656 ac97->id == 0x414c4723);
2657
2658
2659 snd_ac97_write_cache(ac97, AC97_ALC650_GPIO_STATUS,
2660 snd_ac97_read(ac97, AC97_ALC650_GPIO_STATUS) | 0x8000);
2661
2662
2663 val = snd_ac97_read(ac97, AC97_ALC650_CLOCK);
2664
2665 if (ac97->spec.dev_flags &&
2666
2667 ! (ac97->subsystem_vendor == 0x1043 &&
2668 ac97->subsystem_device == 0x1103))
2669 val |= 0x03;
2670 else
2671 val &= ~0x03;
2672 snd_ac97_write_cache(ac97, AC97_ALC650_CLOCK, val);
2673
2674
2675
2676
2677
2678
2679 snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 0);
2680
2681
2682
2683 snd_ac97_write_cache(ac97, AC97_ALC650_GPIO_SETUP,
2684 snd_ac97_read(ac97, AC97_ALC650_GPIO_SETUP) | 0x01);
2685 snd_ac97_write_cache(ac97, AC97_ALC650_GPIO_STATUS,
2686 (snd_ac97_read(ac97, AC97_ALC650_GPIO_STATUS) | 0x100) & ~0x10);
2687
2688
2689 snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808);
2690 snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808);
2691 return 0;
2692 }
2693
2694 static void alc655_update_jacks(struct snd_ac97 *ac97)
2695 {
2696 int shared;
2697
2698
2699 shared = is_shared_surrout(ac97);
2700 ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 9,
2701 shared ? (1 << 9) : 0, 0);
2702
2703 shared = is_shared_clfeout(ac97);
2704
2705 snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12,
2706 shared ? (1 << 12) : 0);
2707 ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 10,
2708 shared ? (1 << 10) : 0, 0);
2709 }
2710
2711 static const struct snd_kcontrol_new snd_ac97_controls_alc655[] = {
2712 AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0),
2713 AC97_SURROUND_JACK_MODE_CTL,
2714 AC97_CHANNEL_MODE_CTL,
2715 };
2716
2717 static int alc655_iec958_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
2718 {
2719 static const char * const texts_655[3] = {
2720 "PCM", "Analog In", "IEC958 In"
2721 };
2722 static const char * const texts_658[4] = {
2723 "PCM", "Analog1 In", "Analog2 In", "IEC958 In"
2724 };
2725 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2726
2727 if (ac97->spec.dev_flags)
2728 return snd_ctl_enum_info(uinfo, 1, 4, texts_658);
2729 else
2730 return snd_ctl_enum_info(uinfo, 1, 3, texts_655);
2731 }
2732
2733 static int alc655_iec958_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2734 {
2735 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2736 unsigned short val;
2737
2738 val = ac97->regs[AC97_ALC650_MULTICH];
2739 val = (val >> 12) & 3;
2740 if (ac97->spec.dev_flags && val == 3)
2741 val = 0;
2742 ucontrol->value.enumerated.item[0] = val;
2743 return 0;
2744 }
2745
2746 static int alc655_iec958_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2747 {
2748 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2749
2750 return ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 3 << 12,
2751 (unsigned short)ucontrol->value.enumerated.item[0] << 12,
2752 0);
2753 }
2754
2755 static const struct snd_kcontrol_new snd_ac97_spdif_controls_alc655[] = {
2756 AC97_PAGE_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_ALC650_MULTICH, 11, 1, 0, 0),
2757
2758
2759 {
2760 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2761 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
2762 .info = alc655_iec958_route_info,
2763 .get = alc655_iec958_route_get,
2764 .put = alc655_iec958_route_put,
2765 },
2766 };
2767
2768 static int patch_alc655_specific(struct snd_ac97 * ac97)
2769 {
2770 int err;
2771
2772 err = patch_build_controls(ac97, snd_ac97_controls_alc655, ARRAY_SIZE(snd_ac97_controls_alc655));
2773 if (err < 0)
2774 return err;
2775 if (ac97->ext_id & AC97_EI_SPDIF) {
2776 err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc655, ARRAY_SIZE(snd_ac97_spdif_controls_alc655));
2777 if (err < 0)
2778 return err;
2779 }
2780 return 0;
2781 }
2782
2783 static const struct snd_ac97_build_ops patch_alc655_ops = {
2784 .build_specific = patch_alc655_specific,
2785 .update_jacks = alc655_update_jacks
2786 };
2787
2788 static int patch_alc655(struct snd_ac97 * ac97)
2789 {
2790 unsigned int val;
2791
2792 if (ac97->id == AC97_ID_ALC658) {
2793 ac97->spec.dev_flags = 1;
2794 if ((snd_ac97_read(ac97, AC97_ALC650_REVISION) & 0x3f) == 2) {
2795 ac97->id = AC97_ID_ALC658D;
2796 ac97->spec.dev_flags = 2;
2797 }
2798 }
2799
2800 ac97->build_ops = &patch_alc655_ops;
2801
2802
2803 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR);
2804
2805
2806 val = snd_ac97_read(ac97, 0x7a);
2807 if (ac97->spec.dev_flags)
2808 val &= ~(1 << 1);
2809 else {
2810 if (ac97->subsystem_vendor == 0x1462 &&
2811 (ac97->subsystem_device == 0x0131 ||
2812 ac97->subsystem_device == 0x0161 ||
2813 ac97->subsystem_device == 0x0351 ||
2814 ac97->subsystem_device == 0x0471 ||
2815 ac97->subsystem_device == 0x0061))
2816 val &= ~(1 << 1);
2817 else
2818 val |= (1 << 1);
2819
2820 ac97->ext_id |= AC97_EI_SPDIF;
2821 }
2822 val &= ~(1 << 12);
2823 snd_ac97_write_cache(ac97, 0x7a, val);
2824
2825
2826
2827
2828
2829 snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 1<<15);
2830
2831
2832 snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808);
2833 snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808);
2834
2835
2836 if (ac97->id == AC97_ID_ALC658D)
2837 snd_ac97_update_bits(ac97, 0x74, 0x0800, 0x0800);
2838
2839 return 0;
2840 }
2841
2842
2843 #define AC97_ALC850_JACK_SELECT 0x76
2844 #define AC97_ALC850_MISC1 0x7a
2845 #define AC97_ALC850_MULTICH 0x6a
2846
2847 static void alc850_update_jacks(struct snd_ac97 *ac97)
2848 {
2849 int shared;
2850 int aux_is_back_surround;
2851
2852
2853 shared = is_shared_surrout(ac97);
2854
2855 snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<4)|(1<<5),
2856 shared ? (1<<5) : (1<<4));
2857
2858 snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 12,
2859 shared ? (2<<12) : (0<<12));
2860
2861 shared = is_shared_clfeout(ac97);
2862
2863 snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<12)|(1<<13),
2864 shared ? (1<<12) : (1<<13));
2865
2866 snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 4,
2867 shared ? (5<<4) : (1<<4));
2868
2869 aux_is_back_surround = alc850_is_aux_back_surround(ac97);
2870
2871 snd_ac97_update_bits(ac97, AC97_ALC850_MULTICH, 1 << 10,
2872 aux_is_back_surround ? (1<<10) : (0<<10));
2873 }
2874
2875 static const struct snd_kcontrol_new snd_ac97_controls_alc850[] = {
2876 AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0),
2877 AC97_SINGLE("Mic Front Input Switch", AC97_ALC850_JACK_SELECT, 15, 1, 1),
2878 AC97_SURROUND_JACK_MODE_CTL,
2879 AC97_CHANNEL_MODE_8CH_CTL,
2880 };
2881
2882 static int patch_alc850_specific(struct snd_ac97 *ac97)
2883 {
2884 int err;
2885
2886 err = patch_build_controls(ac97, snd_ac97_controls_alc850, ARRAY_SIZE(snd_ac97_controls_alc850));
2887 if (err < 0)
2888 return err;
2889 if (ac97->ext_id & AC97_EI_SPDIF) {
2890 err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc655, ARRAY_SIZE(snd_ac97_spdif_controls_alc655));
2891 if (err < 0)
2892 return err;
2893 }
2894 return 0;
2895 }
2896
2897 static const struct snd_ac97_build_ops patch_alc850_ops = {
2898 .build_specific = patch_alc850_specific,
2899 .update_jacks = alc850_update_jacks
2900 };
2901
2902 static int patch_alc850(struct snd_ac97 *ac97)
2903 {
2904 ac97->build_ops = &patch_alc850_ops;
2905
2906 ac97->spec.dev_flags = 0;
2907 ac97->flags |= AC97_HAS_8CH;
2908
2909
2910 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR);
2911
2912
2913
2914
2915
2916
2917
2918
2919 snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 1<<15);
2920
2921
2922
2923 snd_ac97_write_cache(ac97, 0x7a, (1<<1)|(1<<4)|(0<<5)|(1<<6)|
2924 (1<<7)|(0<<12)|(1<<13)|(0<<14));
2925
2926
2927
2928 snd_ac97_write_cache(ac97, 0x76, (0<<0)|(0<<2)|(1<<4)|(1<<7)|(2<<8)|
2929 (1<<11)|(0<<12)|(1<<15));
2930
2931
2932 snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808);
2933 snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808);
2934 return 0;
2935 }
2936
2937 static int patch_aztech_azf3328_specific(struct snd_ac97 *ac97)
2938 {
2939 struct snd_kcontrol *kctl_3d_center =
2940 snd_ac97_find_mixer_ctl(ac97, "3D Control - Center");
2941 struct snd_kcontrol *kctl_3d_depth =
2942 snd_ac97_find_mixer_ctl(ac97, "3D Control - Depth");
2943
2944
2945
2946
2947
2948 if (kctl_3d_center) {
2949 kctl_3d_center->private_value =
2950 AC97_SINGLE_VALUE(AC97_3D_CONTROL, 1, 0x07, 0);
2951 snd_ac97_rename_vol_ctl(ac97,
2952 "3D Control - Center", "3D Control - Width"
2953 );
2954 }
2955 if (kctl_3d_depth)
2956 kctl_3d_depth->private_value =
2957 AC97_SINGLE_VALUE(AC97_3D_CONTROL, 8, 0x03, 0);
2958
2959
2960
2961 snd_ac97_rename_vol_ctl(ac97,
2962 "Master Mono Playback", "Modem Playback"
2963 );
2964 snd_ac97_rename_vol_ctl(ac97,
2965 "Headphone Playback", "FM Synth Playback"
2966 );
2967
2968 return 0;
2969 }
2970
2971 static const struct snd_ac97_build_ops patch_aztech_azf3328_ops = {
2972 .build_specific = patch_aztech_azf3328_specific
2973 };
2974
2975 static int patch_aztech_azf3328(struct snd_ac97 *ac97)
2976 {
2977 ac97->build_ops = &patch_aztech_azf3328_ops;
2978 return 0;
2979 }
2980
2981
2982
2983
2984 static void cm9738_update_jacks(struct snd_ac97 *ac97)
2985 {
2986
2987 snd_ac97_update_bits(ac97, AC97_CM9738_VENDOR_CTRL, 1 << 10,
2988 is_shared_surrout(ac97) ? (1 << 10) : 0);
2989 }
2990
2991 static const struct snd_kcontrol_new snd_ac97_cm9738_controls[] = {
2992 AC97_SINGLE("Duplicate Front", AC97_CM9738_VENDOR_CTRL, 13, 1, 0),
2993 AC97_SURROUND_JACK_MODE_CTL,
2994 AC97_CHANNEL_MODE_4CH_CTL,
2995 };
2996
2997 static int patch_cm9738_specific(struct snd_ac97 * ac97)
2998 {
2999 return patch_build_controls(ac97, snd_ac97_cm9738_controls, ARRAY_SIZE(snd_ac97_cm9738_controls));
3000 }
3001
3002 static const struct snd_ac97_build_ops patch_cm9738_ops = {
3003 .build_specific = patch_cm9738_specific,
3004 .update_jacks = cm9738_update_jacks
3005 };
3006
3007 static int patch_cm9738(struct snd_ac97 * ac97)
3008 {
3009 ac97->build_ops = &patch_cm9738_ops;
3010
3011
3012 ac97->flags |= AC97_HAS_NO_PCM_VOL;
3013 snd_ac97_write_cache(ac97, AC97_PCM, 0x8000);
3014
3015 return 0;
3016 }
3017
3018 static int snd_ac97_cmedia_spdif_playback_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
3019 {
3020 static const char * const texts[] = { "Analog", "Digital" };
3021
3022 return snd_ctl_enum_info(uinfo, 1, 2, texts);
3023 }
3024
3025 static int snd_ac97_cmedia_spdif_playback_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3026 {
3027 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
3028 unsigned short val;
3029
3030 val = ac97->regs[AC97_CM9739_SPDIF_CTRL];
3031 ucontrol->value.enumerated.item[0] = (val >> 1) & 0x01;
3032 return 0;
3033 }
3034
3035 static int snd_ac97_cmedia_spdif_playback_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3036 {
3037 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
3038
3039 return snd_ac97_update_bits(ac97, AC97_CM9739_SPDIF_CTRL,
3040 0x01 << 1,
3041 (ucontrol->value.enumerated.item[0] & 0x01) << 1);
3042 }
3043
3044 static const struct snd_kcontrol_new snd_ac97_cm9739_controls_spdif[] = {
3045
3046 {
3047 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3048 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3049 .info = snd_ac97_cmedia_spdif_playback_source_info,
3050 .get = snd_ac97_cmedia_spdif_playback_source_get,
3051 .put = snd_ac97_cmedia_spdif_playback_source_put,
3052 },
3053
3054 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Valid Switch", AC97_CM9739_SPDIF_CTRL, 2, 1, 0),
3055
3056 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Monitor", AC97_CM9739_SPDIF_CTRL, 3, 1, 0),
3057
3058 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_CM9739_SPDIF_CTRL, 4, 1, 0),
3059
3060 };
3061
3062 static void cm9739_update_jacks(struct snd_ac97 *ac97)
3063 {
3064
3065 snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 1 << 10,
3066 is_shared_surrout(ac97) ? (1 << 10) : 0);
3067
3068 snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x3000,
3069 is_shared_clfeout(ac97) ? 0x1000 : 0x2000);
3070 }
3071
3072 static const struct snd_kcontrol_new snd_ac97_cm9739_controls[] = {
3073 AC97_SURROUND_JACK_MODE_CTL,
3074 AC97_CHANNEL_MODE_CTL,
3075 };
3076
3077 static int patch_cm9739_specific(struct snd_ac97 * ac97)
3078 {
3079 return patch_build_controls(ac97, snd_ac97_cm9739_controls, ARRAY_SIZE(snd_ac97_cm9739_controls));
3080 }
3081
3082 static int patch_cm9739_post_spdif(struct snd_ac97 * ac97)
3083 {
3084 return patch_build_controls(ac97, snd_ac97_cm9739_controls_spdif, ARRAY_SIZE(snd_ac97_cm9739_controls_spdif));
3085 }
3086
3087 static const struct snd_ac97_build_ops patch_cm9739_ops = {
3088 .build_specific = patch_cm9739_specific,
3089 .build_post_spdif = patch_cm9739_post_spdif,
3090 .update_jacks = cm9739_update_jacks
3091 };
3092
3093 static int patch_cm9739(struct snd_ac97 * ac97)
3094 {
3095 unsigned short val;
3096
3097 ac97->build_ops = &patch_cm9739_ops;
3098
3099
3100 ac97->flags |= AC97_HAS_NO_MASTER_VOL | AC97_HAS_NO_PCM_VOL;
3101 snd_ac97_write_cache(ac97, AC97_MASTER, 0x8000);
3102 snd_ac97_write_cache(ac97, AC97_PCM, 0x8000);
3103
3104
3105 val = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
3106 if (val & AC97_EA_SPCV) {
3107
3108 snd_ac97_write_cache(ac97, AC97_CM9739_SPDIF_CTRL,
3109 snd_ac97_read(ac97, AC97_CM9739_SPDIF_CTRL) | 0x01);
3110 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000;
3111 } else {
3112 ac97->ext_id &= ~AC97_EI_SPDIF;
3113 ac97->rates[AC97_RATES_SPDIF] = 0;
3114 }
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125 val = snd_ac97_read(ac97, AC97_CM9739_MULTI_CHAN) & (1 << 4);
3126 val |= (1 << 3);
3127 val |= (1 << 13);
3128 if (! (ac97->ext_id & AC97_EI_SPDIF))
3129 val |= (1 << 14);
3130 snd_ac97_write_cache(ac97, AC97_CM9739_MULTI_CHAN, val);
3131
3132
3133 snd_ac97_write_cache(ac97, 0x70, 0x0100);
3134 snd_ac97_write_cache(ac97, 0x72, 0x0020);
3135
3136 if (ac97->pci &&
3137 ac97->subsystem_vendor == 0x1043 &&
3138 ac97->subsystem_device == 0x1843) {
3139 snd_ac97_write_cache(ac97, AC97_CM9739_SPDIF_CTRL,
3140 snd_ac97_read(ac97, AC97_CM9739_SPDIF_CTRL) & ~0x01);
3141 snd_ac97_write_cache(ac97, AC97_CM9739_MULTI_CHAN,
3142 snd_ac97_read(ac97, AC97_CM9739_MULTI_CHAN) | (1 << 14));
3143 }
3144
3145 return 0;
3146 }
3147
3148 #define AC97_CM9761_MULTI_CHAN 0x64
3149 #define AC97_CM9761_FUNC 0x66
3150 #define AC97_CM9761_SPDIF_CTRL 0x6c
3151
3152 static void cm9761_update_jacks(struct snd_ac97 *ac97)
3153 {
3154
3155
3156
3157 static const unsigned short surr_on[3][2] = {
3158 { 0x0008, 0x0000 },
3159 { 0x0000, 0x0008 },
3160 { 0x0000, 0x0008 },
3161 };
3162 static const unsigned short clfe_on[3][2] = {
3163 { 0x0000, 0x1000 },
3164 { 0x1000, 0x0000 },
3165 { 0x0000, 0x1000 },
3166 };
3167 static const unsigned short surr_shared[3][2] = {
3168 { 0x0000, 0x0400 },
3169 { 0x0000, 0x0400 },
3170 { 0x0000, 0x0400 },
3171 };
3172 static const unsigned short clfe_shared[3][2] = {
3173 { 0x2000, 0x0880 },
3174 { 0x0000, 0x2880 },
3175 { 0x2000, 0x0800 },
3176 };
3177 unsigned short val = 0;
3178
3179 val |= surr_on[ac97->spec.dev_flags][is_surround_on(ac97)];
3180 val |= clfe_on[ac97->spec.dev_flags][is_clfe_on(ac97)];
3181 val |= surr_shared[ac97->spec.dev_flags][is_shared_surrout(ac97)];
3182 val |= clfe_shared[ac97->spec.dev_flags][is_shared_clfeout(ac97)];
3183
3184 snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3c88, val);
3185 }
3186
3187 static const struct snd_kcontrol_new snd_ac97_cm9761_controls[] = {
3188 AC97_SURROUND_JACK_MODE_CTL,
3189 AC97_CHANNEL_MODE_CTL,
3190 };
3191
3192 static int cm9761_spdif_out_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
3193 {
3194 static const char * const texts[] = { "AC-Link", "ADC", "SPDIF-In" };
3195
3196 return snd_ctl_enum_info(uinfo, 1, 3, texts);
3197 }
3198
3199 static int cm9761_spdif_out_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3200 {
3201 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
3202
3203 if (ac97->regs[AC97_CM9761_FUNC] & 0x1)
3204 ucontrol->value.enumerated.item[0] = 2;
3205 else if (ac97->regs[AC97_CM9761_SPDIF_CTRL] & 0x2)
3206 ucontrol->value.enumerated.item[0] = 1;
3207 else
3208 ucontrol->value.enumerated.item[0] = 0;
3209 return 0;
3210 }
3211
3212 static int cm9761_spdif_out_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3213 {
3214 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
3215
3216 if (ucontrol->value.enumerated.item[0] == 2)
3217 return snd_ac97_update_bits(ac97, AC97_CM9761_FUNC, 0x1, 0x1);
3218 snd_ac97_update_bits(ac97, AC97_CM9761_FUNC, 0x1, 0);
3219 return snd_ac97_update_bits(ac97, AC97_CM9761_SPDIF_CTRL, 0x2,
3220 ucontrol->value.enumerated.item[0] == 1 ? 0x2 : 0);
3221 }
3222
3223 static const char * const cm9761_dac_clock[] = {
3224 "AC-Link", "SPDIF-In", "Both"
3225 };
3226 static const struct ac97_enum cm9761_dac_clock_enum =
3227 AC97_ENUM_SINGLE(AC97_CM9761_SPDIF_CTRL, 9, 3, cm9761_dac_clock);
3228
3229 static const struct snd_kcontrol_new snd_ac97_cm9761_controls_spdif[] = {
3230 {
3231 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3232 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3233 .info = cm9761_spdif_out_source_info,
3234 .get = cm9761_spdif_out_source_get,
3235 .put = cm9761_spdif_out_source_put,
3236 },
3237
3238 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Valid Switch", AC97_CM9761_SPDIF_CTRL, 2, 1, 0),
3239
3240 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Monitor", AC97_CM9761_SPDIF_CTRL, 3, 1, 0),
3241
3242 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_CM9761_SPDIF_CTRL, 4, 1, 0),
3243
3244 AC97_ENUM("DAC Clock Source", cm9761_dac_clock_enum),
3245 };
3246
3247 static int patch_cm9761_post_spdif(struct snd_ac97 * ac97)
3248 {
3249 return patch_build_controls(ac97, snd_ac97_cm9761_controls_spdif, ARRAY_SIZE(snd_ac97_cm9761_controls_spdif));
3250 }
3251
3252 static int patch_cm9761_specific(struct snd_ac97 * ac97)
3253 {
3254 return patch_build_controls(ac97, snd_ac97_cm9761_controls, ARRAY_SIZE(snd_ac97_cm9761_controls));
3255 }
3256
3257 static const struct snd_ac97_build_ops patch_cm9761_ops = {
3258 .build_specific = patch_cm9761_specific,
3259 .build_post_spdif = patch_cm9761_post_spdif,
3260 .update_jacks = cm9761_update_jacks
3261 };
3262
3263 static int patch_cm9761(struct snd_ac97 *ac97)
3264 {
3265 unsigned short val;
3266
3267
3268
3269
3270
3271 ac97->flags |= AC97_HAS_NO_PCM_VOL;
3272 snd_ac97_write_cache(ac97, AC97_MASTER, 0x8808);
3273 snd_ac97_write_cache(ac97, AC97_PCM, 0x8808);
3274
3275 ac97->spec.dev_flags = 0;
3276 if (ac97->id == AC97_ID_CM9761_82) {
3277 unsigned short tmp;
3278
3279 val = snd_ac97_read(ac97, AC97_INT_PAGING);
3280 snd_ac97_write_cache(ac97, AC97_INT_PAGING, (val & ~0x0f) | 0x01);
3281 tmp = snd_ac97_read(ac97, 0x60);
3282 ac97->spec.dev_flags = tmp & 1;
3283 snd_ac97_write_cache(ac97, AC97_INT_PAGING, val);
3284 } else if (ac97->id == AC97_ID_CM9761_83)
3285 ac97->spec.dev_flags = 2;
3286
3287 ac97->build_ops = &patch_cm9761_ops;
3288
3289
3290
3291 ac97->ext_id |= AC97_EI_SPDIF;
3292
3293 snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, 0x05c0);
3294
3295 snd_ac97_write_cache(ac97, AC97_CM9761_SPDIF_CTRL, 0x0001);
3296 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000;
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316 #if 0
3317 if (ac97->spec.dev_flags)
3318 val = 0x0214;
3319 else
3320 val = 0x321c;
3321 #endif
3322 val = snd_ac97_read(ac97, AC97_CM9761_MULTI_CHAN);
3323 val |= (1 << 4);
3324 snd_ac97_write_cache(ac97, AC97_CM9761_MULTI_CHAN, val);
3325
3326
3327 snd_ac97_write_cache(ac97, 0x70, 0x0100);
3328 snd_ac97_write_cache(ac97, 0x72, 0x0020);
3329
3330 return 0;
3331 }
3332
3333 #define AC97_CM9780_SIDE 0x60
3334 #define AC97_CM9780_JACK 0x62
3335 #define AC97_CM9780_MIXER 0x64
3336 #define AC97_CM9780_MULTI_CHAN 0x66
3337 #define AC97_CM9780_SPDIF 0x6c
3338
3339 static const char * const cm9780_ch_select[] = {
3340 "Front", "Side", "Center/LFE", "Rear"
3341 };
3342 static const struct ac97_enum cm9780_ch_select_enum =
3343 AC97_ENUM_SINGLE(AC97_CM9780_MULTI_CHAN, 6, 4, cm9780_ch_select);
3344 static const struct snd_kcontrol_new cm9780_controls[] = {
3345 AC97_DOUBLE("Side Playback Switch", AC97_CM9780_SIDE, 15, 7, 1, 1),
3346 AC97_DOUBLE("Side Playback Volume", AC97_CM9780_SIDE, 8, 0, 31, 0),
3347 AC97_ENUM("Side Playback Route", cm9780_ch_select_enum),
3348 };
3349
3350 static int patch_cm9780_specific(struct snd_ac97 *ac97)
3351 {
3352 return patch_build_controls(ac97, cm9780_controls, ARRAY_SIZE(cm9780_controls));
3353 }
3354
3355 static const struct snd_ac97_build_ops patch_cm9780_ops = {
3356 .build_specific = patch_cm9780_specific,
3357 .build_post_spdif = patch_cm9761_post_spdif
3358 };
3359
3360 static int patch_cm9780(struct snd_ac97 *ac97)
3361 {
3362 unsigned short val;
3363
3364 ac97->build_ops = &patch_cm9780_ops;
3365
3366
3367 if (ac97->ext_id & AC97_EI_SPDIF) {
3368 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000;
3369 val = snd_ac97_read(ac97, AC97_CM9780_SPDIF);
3370 val |= 0x1;
3371 snd_ac97_write_cache(ac97, AC97_CM9780_SPDIF, val);
3372 }
3373
3374 return 0;
3375 }
3376
3377
3378
3379
3380 static const struct snd_kcontrol_new snd_ac97_controls_vt1613[] = {
3381 AC97_SINGLE("DC Offset removal", 0x5a, 10, 1, 0),
3382 };
3383
3384 static int patch_vt1613_specific(struct snd_ac97 *ac97)
3385 {
3386 return patch_build_controls(ac97, &snd_ac97_controls_vt1613[0],
3387 ARRAY_SIZE(snd_ac97_controls_vt1613));
3388 };
3389
3390 static const struct snd_ac97_build_ops patch_vt1613_ops = {
3391 .build_specific = patch_vt1613_specific
3392 };
3393
3394 static int patch_vt1613(struct snd_ac97 *ac97)
3395 {
3396 ac97->build_ops = &patch_vt1613_ops;
3397
3398 ac97->flags |= AC97_HAS_NO_VIDEO;
3399 ac97->caps |= AC97_BC_HEADPHONE;
3400
3401 return 0;
3402 }
3403
3404
3405
3406
3407 static const struct snd_kcontrol_new snd_ac97_controls_vt1616[] = {
3408 AC97_SINGLE("DC Offset removal", 0x5a, 10, 1, 0),
3409 AC97_SINGLE("Alternate Level to Surround Out", 0x5a, 15, 1, 0),
3410 AC97_SINGLE("Downmix LFE and Center to Front", 0x5a, 12, 1, 0),
3411 AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0),
3412 };
3413
3414 static const char * const follower_vols_vt1616[] = {
3415 "Front Playback Volume",
3416 "Surround Playback Volume",
3417 "Center Playback Volume",
3418 "LFE Playback Volume",
3419 NULL
3420 };
3421
3422 static const char * const follower_sws_vt1616[] = {
3423 "Front Playback Switch",
3424 "Surround Playback Switch",
3425 "Center Playback Switch",
3426 "LFE Playback Switch",
3427 NULL
3428 };
3429
3430
3431 static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97,
3432 const char *name)
3433 {
3434 struct snd_ctl_elem_id id;
3435 memset(&id, 0, sizeof(id));
3436 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
3437 strcpy(id.name, name);
3438 return snd_ctl_find_id(ac97->bus->card, &id);
3439 }
3440
3441
3442 static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name,
3443 const unsigned int *tlv,
3444 const char * const *followers)
3445 {
3446 struct snd_kcontrol *kctl;
3447 const char * const *s;
3448 int err;
3449
3450 kctl = snd_ctl_make_virtual_master(name, tlv);
3451 if (!kctl)
3452 return -ENOMEM;
3453 err = snd_ctl_add(ac97->bus->card, kctl);
3454 if (err < 0)
3455 return err;
3456
3457 for (s = followers; *s; s++) {
3458 struct snd_kcontrol *sctl;
3459
3460 sctl = snd_ac97_find_mixer_ctl(ac97, *s);
3461 if (!sctl) {
3462 dev_dbg(ac97->bus->card->dev,
3463 "Cannot find follower %s, skipped\n", *s);
3464 continue;
3465 }
3466 err = snd_ctl_add_follower(kctl, sctl);
3467 if (err < 0)
3468 return err;
3469 }
3470 return 0;
3471 }
3472
3473 static int patch_vt1616_specific(struct snd_ac97 * ac97)
3474 {
3475 struct snd_kcontrol *kctl;
3476 int err;
3477
3478 if (snd_ac97_try_bit(ac97, 0x5a, 9)) {
3479 err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[0], 1);
3480 if (err < 0)
3481 return err;
3482 }
3483 err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[1], ARRAY_SIZE(snd_ac97_controls_vt1616) - 1);
3484 if (err < 0)
3485 return err;
3486
3487
3488 kctl = snd_ac97_find_mixer_ctl(ac97, "Master Playback Volume");
3489 if (!kctl)
3490 return -EINVAL;
3491
3492 snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Front Playback");
3493
3494 err = snd_ac97_add_vmaster(ac97, "Master Playback Volume",
3495 kctl->tlv.p, follower_vols_vt1616);
3496 if (err < 0)
3497 return err;
3498
3499 err = snd_ac97_add_vmaster(ac97, "Master Playback Switch",
3500 NULL, follower_sws_vt1616);
3501 if (err < 0)
3502 return err;
3503
3504 return 0;
3505 }
3506
3507 static const struct snd_ac97_build_ops patch_vt1616_ops = {
3508 .build_specific = patch_vt1616_specific
3509 };
3510
3511 static int patch_vt1616(struct snd_ac97 * ac97)
3512 {
3513 ac97->build_ops = &patch_vt1616_ops;
3514 return 0;
3515 }
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532 static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol *kcontrol,
3533 struct snd_ctl_elem_info *uinfo)
3534 {
3535
3536
3537
3538
3539
3540 static const char * const texts[] = {"LineIn Mic1", "LineIn Mic1 Mic3",
3541 "Surr LFE/C Mic3", "LineIn LFE/C Mic3",
3542 "LineIn Mic2", "LineIn Mic2 Mic1",
3543 "Surr LFE Mic1", "Surr LFE Mic1 Mic2"};
3544
3545 return snd_ctl_enum_info(uinfo, 1, 8, texts);
3546 }
3547
3548 static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol,
3549 struct snd_ctl_elem_value *ucontrol)
3550 {
3551 ushort usSM51, usMS;
3552
3553 struct snd_ac97 *pac97;
3554
3555 pac97 = snd_kcontrol_chip(kcontrol);
3556
3557
3558
3559
3560 usSM51 = snd_ac97_read(pac97, 0x7a) >> 14;
3561 usMS = snd_ac97_read(pac97, 0x20) >> 8;
3562
3563 ucontrol->value.enumerated.item[0] = (usSM51 << 1) + usMS;
3564
3565 return 0;
3566 }
3567
3568 static int snd_ac97_vt1617a_smart51_put(struct snd_kcontrol *kcontrol,
3569 struct snd_ctl_elem_value *ucontrol)
3570 {
3571 ushort usSM51, usMS, usReg;
3572
3573 struct snd_ac97 *pac97;
3574
3575 pac97 = snd_kcontrol_chip(kcontrol);
3576
3577 usSM51 = ucontrol->value.enumerated.item[0] >> 1;
3578 usMS = ucontrol->value.enumerated.item[0] & 1;
3579
3580
3581
3582
3583 usReg = snd_ac97_read(pac97, 0x7a);
3584 snd_ac97_write_cache(pac97, 0x7a, (usReg & 0x3FFF) + (usSM51 << 14));
3585 usReg = snd_ac97_read(pac97, 0x20);
3586 snd_ac97_write_cache(pac97, 0x20, (usReg & 0xFEFF) + (usMS << 8));
3587
3588 return 0;
3589 }
3590
3591 static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = {
3592
3593 AC97_SINGLE("Center/LFE Exchange", 0x5a, 8, 1, 0),
3594
3595
3596
3597
3598 {
3599 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3600 .name = "Smart 5.1 Select",
3601 .info = snd_ac97_vt1617a_smart51_info,
3602 .get = snd_ac97_vt1617a_smart51_get,
3603 .put = snd_ac97_vt1617a_smart51_put,
3604 },
3605 };
3606
3607 static int patch_vt1617a(struct snd_ac97 * ac97)
3608 {
3609 int err = 0;
3610 int val;
3611
3612
3613
3614
3615 err = patch_build_controls(ac97, &snd_ac97_controls_vt1617a[0],
3616 ARRAY_SIZE(snd_ac97_controls_vt1617a));
3617
3618
3619
3620
3621
3622
3623
3624 val = snd_ac97_read(ac97, 0x5c);
3625 if (!(val & 0x20))
3626 snd_ac97_write_cache(ac97, 0x5c, 0x20);
3627
3628 ac97->ext_id |= AC97_EI_SPDIF;
3629 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
3630 ac97->build_ops = &patch_vt1616_ops;
3631
3632 return err;
3633 }
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671 struct vt1618_uaj_item {
3672 unsigned short mask;
3673 unsigned short shift;
3674 const char * const items[4];
3675 };
3676
3677
3678
3679 static const struct vt1618_uaj_item vt1618_uaj[3] = {
3680 {
3681
3682 .mask = 0x03,
3683 .shift = 0,
3684 .items = {
3685 "Speaker Out", "DAC Unmixed Out", "Line In", "Mic In"
3686 }
3687 },
3688 {
3689
3690 .mask = 0x0c,
3691 .shift = 2,
3692 .items = {
3693 "Surround Out", "DAC Unmixed Out", "Line In", "Mic In"
3694 }
3695 },
3696 {
3697
3698 .mask = 0x30,
3699 .shift = 4,
3700 .items = {
3701 "Center LFE Out", "DAC Unmixed Out", "Line In", "Mic In"
3702 },
3703 },
3704 };
3705
3706 static int snd_ac97_vt1618_UAJ_info(struct snd_kcontrol *kcontrol,
3707 struct snd_ctl_elem_info *uinfo)
3708 {
3709 return snd_ctl_enum_info(uinfo, 1, 4,
3710 vt1618_uaj[kcontrol->private_value].items);
3711 }
3712
3713
3714
3715
3716
3717 static int snd_ac97_vt1618_UAJ_get(struct snd_kcontrol *kcontrol,
3718 struct snd_ctl_elem_value *ucontrol)
3719 {
3720 unsigned short datpag, uaj;
3721 struct snd_ac97 *pac97 = snd_kcontrol_chip(kcontrol);
3722
3723 mutex_lock(&pac97->page_mutex);
3724
3725 datpag = snd_ac97_read(pac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
3726 snd_ac97_update_bits(pac97, AC97_INT_PAGING, AC97_PAGE_MASK, 0);
3727
3728 uaj = snd_ac97_read(pac97, 0x60) &
3729 vt1618_uaj[kcontrol->private_value].mask;
3730
3731 snd_ac97_update_bits(pac97, AC97_INT_PAGING, AC97_PAGE_MASK, datpag);
3732 mutex_unlock(&pac97->page_mutex);
3733
3734 ucontrol->value.enumerated.item[0] = uaj >>
3735 vt1618_uaj[kcontrol->private_value].shift;
3736
3737 return 0;
3738 }
3739
3740 static int snd_ac97_vt1618_UAJ_put(struct snd_kcontrol *kcontrol,
3741 struct snd_ctl_elem_value *ucontrol)
3742 {
3743 return ac97_update_bits_page(snd_kcontrol_chip(kcontrol), 0x60,
3744 vt1618_uaj[kcontrol->private_value].mask,
3745 ucontrol->value.enumerated.item[0]<<
3746 vt1618_uaj[kcontrol->private_value].shift,
3747 0);
3748 }
3749
3750
3751
3752 static int snd_ac97_vt1618_aux_info(struct snd_kcontrol *kcontrol,
3753 struct snd_ctl_elem_info *uinfo)
3754 {
3755 static const char * const txt_aux[] = {"Aux In", "Back Surr Out"};
3756
3757 return snd_ctl_enum_info(uinfo, 1, 2, txt_aux);
3758 }
3759
3760 static int snd_ac97_vt1618_aux_get(struct snd_kcontrol *kcontrol,
3761 struct snd_ctl_elem_value *ucontrol)
3762 {
3763 ucontrol->value.enumerated.item[0] =
3764 (snd_ac97_read(snd_kcontrol_chip(kcontrol), 0x5c) & 0x0008)>>3;
3765 return 0;
3766 }
3767
3768 static int snd_ac97_vt1618_aux_put(struct snd_kcontrol *kcontrol,
3769 struct snd_ctl_elem_value *ucontrol)
3770 {
3771
3772
3773 snd_ac97_update_bits(snd_kcontrol_chip(kcontrol), 0x5c, 0x0008,
3774 ucontrol->value.enumerated.item[0] << 3);
3775
3776
3777
3778 return snd_ac97_update_bits(snd_kcontrol_chip(kcontrol), 0x76, 0x0008,
3779 ucontrol->value.enumerated.item[0] << 3);
3780 }
3781
3782 static const struct snd_kcontrol_new snd_ac97_controls_vt1618[] = {
3783 AC97_SINGLE("Exchange Center/LFE", 0x5a, 8, 1, 0),
3784 AC97_SINGLE("DC Offset", 0x5a, 10, 1, 0),
3785 AC97_SINGLE("Soft Mute", 0x5c, 0, 1, 1),
3786 AC97_SINGLE("Headphone Amp", 0x5c, 5, 1, 1),
3787 AC97_DOUBLE("Back Surr Volume", 0x5e, 8, 0, 31, 1),
3788 AC97_SINGLE("Back Surr Switch", 0x5e, 15, 1, 1),
3789 {
3790 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3791 .name = "Speaker Jack Mode",
3792 .info = snd_ac97_vt1618_UAJ_info,
3793 .get = snd_ac97_vt1618_UAJ_get,
3794 .put = snd_ac97_vt1618_UAJ_put,
3795 .private_value = 0
3796 },
3797 {
3798 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3799 .name = "Line Jack Mode",
3800 .info = snd_ac97_vt1618_UAJ_info,
3801 .get = snd_ac97_vt1618_UAJ_get,
3802 .put = snd_ac97_vt1618_UAJ_put,
3803 .private_value = 1
3804 },
3805 {
3806 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3807 .name = "Mic Jack Mode",
3808 .info = snd_ac97_vt1618_UAJ_info,
3809 .get = snd_ac97_vt1618_UAJ_get,
3810 .put = snd_ac97_vt1618_UAJ_put,
3811 .private_value = 2
3812 },
3813 {
3814 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3815 .name = "Aux Jack Mode",
3816 .info = snd_ac97_vt1618_aux_info,
3817 .get = snd_ac97_vt1618_aux_get,
3818 .put = snd_ac97_vt1618_aux_put,
3819 }
3820 };
3821
3822 static int patch_vt1618(struct snd_ac97 *ac97)
3823 {
3824 return patch_build_controls(ac97, snd_ac97_controls_vt1618,
3825 ARRAY_SIZE(snd_ac97_controls_vt1618));
3826 }
3827
3828
3829
3830 static void it2646_update_jacks(struct snd_ac97 *ac97)
3831 {
3832
3833 snd_ac97_update_bits(ac97, 0x76, 1 << 9,
3834 is_shared_surrout(ac97) ? (1<<9) : 0);
3835
3836 snd_ac97_update_bits(ac97, 0x76, 1 << 10,
3837 is_shared_clfeout(ac97) ? (1<<10) : 0);
3838 }
3839
3840 static const struct snd_kcontrol_new snd_ac97_controls_it2646[] = {
3841 AC97_SURROUND_JACK_MODE_CTL,
3842 AC97_CHANNEL_MODE_CTL,
3843 };
3844
3845 static const struct snd_kcontrol_new snd_ac97_spdif_controls_it2646[] = {
3846 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0x76, 11, 1, 0),
3847 AC97_SINGLE("Analog to IEC958 Output", 0x76, 12, 1, 0),
3848 AC97_SINGLE("IEC958 Input Monitor", 0x76, 13, 1, 0),
3849 };
3850
3851 static int patch_it2646_specific(struct snd_ac97 * ac97)
3852 {
3853 int err;
3854 err = patch_build_controls(ac97, snd_ac97_controls_it2646, ARRAY_SIZE(snd_ac97_controls_it2646));
3855 if (err < 0)
3856 return err;
3857 err = patch_build_controls(ac97, snd_ac97_spdif_controls_it2646, ARRAY_SIZE(snd_ac97_spdif_controls_it2646));
3858 if (err < 0)
3859 return err;
3860 return 0;
3861 }
3862
3863 static const struct snd_ac97_build_ops patch_it2646_ops = {
3864 .build_specific = patch_it2646_specific,
3865 .update_jacks = it2646_update_jacks
3866 };
3867
3868 static int patch_it2646(struct snd_ac97 * ac97)
3869 {
3870 ac97->build_ops = &patch_it2646_ops;
3871
3872 snd_ac97_write_cache(ac97, 0x5E, 0x0808);
3873 snd_ac97_write_cache(ac97, 0x7A, 0x0808);
3874 return 0;
3875 }
3876
3877
3878
3879
3880
3881 #define AC97_SI3036_CHIP_ID 0x5a
3882 #define AC97_SI3036_LINE_CFG 0x5c
3883
3884 static const struct snd_kcontrol_new snd_ac97_controls_si3036[] = {
3885 AC97_DOUBLE("Modem Speaker Volume", 0x5c, 14, 12, 3, 1)
3886 };
3887
3888 static int patch_si3036_specific(struct snd_ac97 * ac97)
3889 {
3890 int idx, err;
3891 for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_si3036); idx++) {
3892 err = snd_ctl_add(ac97->bus->card, snd_ctl_new1(&snd_ac97_controls_si3036[idx], ac97));
3893 if (err < 0)
3894 return err;
3895 }
3896 return 0;
3897 }
3898
3899 static const struct snd_ac97_build_ops patch_si3036_ops = {
3900 .build_specific = patch_si3036_specific,
3901 };
3902
3903 static int mpatch_si3036(struct snd_ac97 * ac97)
3904 {
3905 ac97->build_ops = &patch_si3036_ops;
3906 snd_ac97_write_cache(ac97, 0x5c, 0xf210 );
3907 snd_ac97_write_cache(ac97, 0x68, 0);
3908 return 0;
3909 }
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919 static const struct snd_ac97_res_table lm4550_restbl[] = {
3920 { AC97_MASTER, 0x1f1f },
3921 { AC97_HEADPHONE, 0x1f1f },
3922 { AC97_MASTER_MONO, 0x001f },
3923 { AC97_PC_BEEP, 0x001f },
3924 { AC97_PHONE, 0x001f },
3925 { AC97_MIC, 0x001f },
3926 { AC97_LINE, 0x1f1f },
3927 { AC97_CD, 0x1f1f },
3928 { AC97_VIDEO, 0x1f1f },
3929 { AC97_AUX, 0x1f1f },
3930 { AC97_PCM, 0x1f1f },
3931 { AC97_REC_GAIN, 0x0f0f },
3932 { }
3933 };
3934
3935 static int patch_lm4550(struct snd_ac97 *ac97)
3936 {
3937 ac97->res_table = lm4550_restbl;
3938 return 0;
3939 }
3940
3941
3942
3943
3944 static const struct snd_kcontrol_new snd_ac97_controls_ucb1400[] = {
3945
3946
3947
3948 AC97_SINGLE("Headphone Driver", 0x6a, 6, 1, 0),
3949
3950
3951 AC97_SINGLE("DC Filter", 0x6a, 4, 1, 0),
3952
3953
3954 AC97_SINGLE("Smart Low Power Mode", 0x6c, 4, 3, 0),
3955 };
3956
3957 static int patch_ucb1400_specific(struct snd_ac97 * ac97)
3958 {
3959 int idx, err;
3960 for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_ucb1400); idx++) {
3961 err = snd_ctl_add(ac97->bus->card, snd_ctl_new1(&snd_ac97_controls_ucb1400[idx], ac97));
3962 if (err < 0)
3963 return err;
3964 }
3965 return 0;
3966 }
3967
3968 static const struct snd_ac97_build_ops patch_ucb1400_ops = {
3969 .build_specific = patch_ucb1400_specific,
3970 };
3971
3972 static int patch_ucb1400(struct snd_ac97 * ac97)
3973 {
3974 ac97->build_ops = &patch_ucb1400_ops;
3975
3976 snd_ac97_write_cache(ac97, 0x6a, 0x0050);
3977 snd_ac97_write_cache(ac97, 0x6c, 0x0030);
3978 return 0;
3979 }