aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ac97/ac97_patch.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/ac97/ac97_patch.c')
-rw-r--r--sound/pci/ac97/ac97_patch.c162
1 files changed, 105 insertions, 57 deletions
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 581ebba4d1a7..98c8b727b62b 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz> 2 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
3 * Universal interface for Audio Codec '97 3 * Universal interface for Audio Codec '97
4 * 4 *
5 * For more details look to AC '97 component specification revision 2.2 5 * For more details look to AC '97 component specification revision 2.2
@@ -204,9 +204,13 @@ static inline int is_shared_micin(struct snd_ac97 *ac97)
204 204
205 205
206/* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */ 206/* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */
207/* Modified for YMF743 by Keita Maehara <maehara@debian.org> */
207 208
208/* It is possible to indicate to the Yamaha YMF753 the type of speakers being used. */ 209/* It is possible to indicate to the Yamaha YMF7x3 the type of
209static int snd_ac97_ymf753_info_speaker(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 210 speakers being used. */
211
212static int snd_ac97_ymf7x3_info_speaker(struct snd_kcontrol *kcontrol,
213 struct snd_ctl_elem_info *uinfo)
210{ 214{
211 static char *texts[3] = { 215 static char *texts[3] = {
212 "Standard", "Small", "Smaller" 216 "Standard", "Small", "Smaller"
@@ -221,12 +225,13 @@ static int snd_ac97_ymf753_info_speaker(struct snd_kcontrol *kcontrol, struct sn
221 return 0; 225 return 0;
222} 226}
223 227
224static int snd_ac97_ymf753_get_speaker(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 228static int snd_ac97_ymf7x3_get_speaker(struct snd_kcontrol *kcontrol,
229 struct snd_ctl_elem_value *ucontrol)
225{ 230{
226 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 231 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
227 unsigned short val; 232 unsigned short val;
228 233
229 val = ac97->regs[AC97_YMF753_3D_MODE_SEL]; 234 val = ac97->regs[AC97_YMF7X3_3D_MODE_SEL];
230 val = (val >> 10) & 3; 235 val = (val >> 10) & 3;
231 if (val > 0) /* 0 = invalid */ 236 if (val > 0) /* 0 = invalid */
232 val--; 237 val--;
@@ -234,7 +239,8 @@ static int snd_ac97_ymf753_get_speaker(struct snd_kcontrol *kcontrol, struct snd
234 return 0; 239 return 0;
235} 240}
236 241
237static int snd_ac97_ymf753_put_speaker(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 242static int snd_ac97_ymf7x3_put_speaker(struct snd_kcontrol *kcontrol,
243 struct snd_ctl_elem_value *ucontrol)
238{ 244{
239 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 245 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
240 unsigned short val; 246 unsigned short val;
@@ -242,20 +248,22 @@ static int snd_ac97_ymf753_put_speaker(struct snd_kcontrol *kcontrol, struct snd
242 if (ucontrol->value.enumerated.item[0] > 2) 248 if (ucontrol->value.enumerated.item[0] > 2)
243 return -EINVAL; 249 return -EINVAL;
244 val = (ucontrol->value.enumerated.item[0] + 1) << 10; 250 val = (ucontrol->value.enumerated.item[0] + 1) << 10;
245 return snd_ac97_update(ac97, AC97_YMF753_3D_MODE_SEL, val); 251 return snd_ac97_update(ac97, AC97_YMF7X3_3D_MODE_SEL, val);
246} 252}
247 253
248static const struct snd_kcontrol_new snd_ac97_ymf753_controls_speaker = 254static const struct snd_kcontrol_new snd_ac97_ymf7x3_controls_speaker =
249{ 255{
250 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 256 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
251 .name = "3D Control - Speaker", 257 .name = "3D Control - Speaker",
252 .info = snd_ac97_ymf753_info_speaker, 258 .info = snd_ac97_ymf7x3_info_speaker,
253 .get = snd_ac97_ymf753_get_speaker, 259 .get = snd_ac97_ymf7x3_get_speaker,
254 .put = snd_ac97_ymf753_put_speaker, 260 .put = snd_ac97_ymf7x3_put_speaker,
255}; 261};
256 262
257/* It is possible to indicate to the Yamaha YMF753 the source to direct to the S/PDIF output. */ 263/* It is possible to indicate to the Yamaha YMF7x3 the source to
258static int snd_ac97_ymf753_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 264 direct to the S/PDIF output. */
265static int snd_ac97_ymf7x3_spdif_source_info(struct snd_kcontrol *kcontrol,
266 struct snd_ctl_elem_info *uinfo)
259{ 267{
260 static char *texts[2] = { "AC-Link", "A/D Converter" }; 268 static char *texts[2] = { "AC-Link", "A/D Converter" };
261 269
@@ -268,17 +276,19 @@ static int snd_ac97_ymf753_spdif_source_info(struct snd_kcontrol *kcontrol, stru
268 return 0; 276 return 0;
269} 277}
270 278
271static int snd_ac97_ymf753_spdif_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 279static int snd_ac97_ymf7x3_spdif_source_get(struct snd_kcontrol *kcontrol,
280 struct snd_ctl_elem_value *ucontrol)
272{ 281{
273 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 282 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
274 unsigned short val; 283 unsigned short val;
275 284
276 val = ac97->regs[AC97_YMF753_DIT_CTRL2]; 285 val = ac97->regs[AC97_YMF7X3_DIT_CTRL];
277 ucontrol->value.enumerated.item[0] = (val >> 1) & 1; 286 ucontrol->value.enumerated.item[0] = (val >> 1) & 1;
278 return 0; 287 return 0;
279} 288}
280 289
281static int snd_ac97_ymf753_spdif_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 290static int snd_ac97_ymf7x3_spdif_source_put(struct snd_kcontrol *kcontrol,
291 struct snd_ctl_elem_value *ucontrol)
282{ 292{
283 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 293 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
284 unsigned short val; 294 unsigned short val;
@@ -286,7 +296,75 @@ static int snd_ac97_ymf753_spdif_source_put(struct snd_kcontrol *kcontrol, struc
286 if (ucontrol->value.enumerated.item[0] > 1) 296 if (ucontrol->value.enumerated.item[0] > 1)
287 return -EINVAL; 297 return -EINVAL;
288 val = ucontrol->value.enumerated.item[0] << 1; 298 val = ucontrol->value.enumerated.item[0] << 1;
289 return snd_ac97_update_bits(ac97, AC97_YMF753_DIT_CTRL2, 0x0002, val); 299 return snd_ac97_update_bits(ac97, AC97_YMF7X3_DIT_CTRL, 0x0002, val);
300}
301
302static int patch_yamaha_ymf7x3_3d(struct snd_ac97 *ac97)
303{
304 struct snd_kcontrol *kctl;
305 int err;
306
307 kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97);
308 err = snd_ctl_add(ac97->bus->card, kctl);
309 if (err < 0)
310 return err;
311 strcpy(kctl->id.name, "3D Control - Wide");
312 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 9, 7, 0);
313 snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
314 err = snd_ctl_add(ac97->bus->card,
315 snd_ac97_cnew(&snd_ac97_ymf7x3_controls_speaker,
316 ac97));
317 if (err < 0)
318 return err;
319 snd_ac97_write_cache(ac97, AC97_YMF7X3_3D_MODE_SEL, 0x0c00);
320 return 0;
321}
322
323static const struct snd_kcontrol_new snd_ac97_yamaha_ymf743_controls_spdif[3] =
324{
325 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
326 AC97_YMF7X3_DIT_CTRL, 0, 1, 0),
327 {
328 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
329 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Source",
330 .info = snd_ac97_ymf7x3_spdif_source_info,
331 .get = snd_ac97_ymf7x3_spdif_source_get,
332 .put = snd_ac97_ymf7x3_spdif_source_put,
333 },
334 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE, NONE) "Mute",
335 AC97_YMF7X3_DIT_CTRL, 2, 1, 1)
336};
337
338static int patch_yamaha_ymf743_build_spdif(struct snd_ac97 *ac97)
339{
340 int err;
341
342 err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3);
343 if (err < 0)
344 return err;
345 err = patch_build_controls(ac97,
346 snd_ac97_yamaha_ymf743_controls_spdif, 3);
347 if (err < 0)
348 return err;
349 /* set default PCM S/PDIF params */
350 /* PCM audio,no copyright,no preemphasis,PCM coder,original */
351 snd_ac97_write_cache(ac97, AC97_YMF7X3_DIT_CTRL, 0xa201);
352 return 0;
353}
354
355static struct snd_ac97_build_ops patch_yamaha_ymf743_ops = {
356 .build_spdif = patch_yamaha_ymf743_build_spdif,
357 .build_3d = patch_yamaha_ymf7x3_3d,
358};
359
360static int patch_yamaha_ymf743(struct snd_ac97 *ac97)
361{
362 ac97->build_ops = &patch_yamaha_ymf743_ops;
363 ac97->caps |= AC97_BC_BASS_TREBLE;
364 ac97->caps |= 0x04 << 10; /* Yamaha 3D enhancement */
365 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */
366 ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */
367 return 0;
290} 368}
291 369
292/* The AC'97 spec states that the S/PDIF signal is to be output at pin 48. 370/* The AC'97 spec states that the S/PDIF signal is to be output at pin 48.
@@ -311,7 +389,7 @@ static int snd_ac97_ymf753_spdif_output_pin_get(struct snd_kcontrol *kcontrol, s
311 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 389 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
312 unsigned short val; 390 unsigned short val;
313 391
314 val = ac97->regs[AC97_YMF753_DIT_CTRL2]; 392 val = ac97->regs[AC97_YMF7X3_DIT_CTRL];
315 ucontrol->value.enumerated.item[0] = (val & 0x0008) ? 2 : (val & 0x0020) ? 1 : 0; 393 ucontrol->value.enumerated.item[0] = (val & 0x0008) ? 2 : (val & 0x0020) ? 1 : 0;
316 return 0; 394 return 0;
317} 395}
@@ -325,7 +403,7 @@ static int snd_ac97_ymf753_spdif_output_pin_put(struct snd_kcontrol *kcontrol, s
325 return -EINVAL; 403 return -EINVAL;
326 val = (ucontrol->value.enumerated.item[0] == 2) ? 0x0008 : 404 val = (ucontrol->value.enumerated.item[0] == 2) ? 0x0008 :
327 (ucontrol->value.enumerated.item[0] == 1) ? 0x0020 : 0; 405 (ucontrol->value.enumerated.item[0] == 1) ? 0x0020 : 0;
328 return snd_ac97_update_bits(ac97, AC97_YMF753_DIT_CTRL2, 0x0028, val); 406 return snd_ac97_update_bits(ac97, AC97_YMF7X3_DIT_CTRL, 0x0028, val);
329 /* The following can be used to direct S/PDIF output to pin 47 (EAPD). 407 /* The following can be used to direct S/PDIF output to pin 47 (EAPD).
330 snd_ac97_write_cache(ac97, 0x62, snd_ac97_read(ac97, 0x62) | 0x0008); */ 408 snd_ac97_write_cache(ac97, 0x62, snd_ac97_read(ac97, 0x62) | 0x0008); */
331} 409}
@@ -334,9 +412,9 @@ static const struct snd_kcontrol_new snd_ac97_ymf753_controls_spdif[3] = {
334 { 412 {
335 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 413 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
336 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 414 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
337 .info = snd_ac97_ymf753_spdif_source_info, 415 .info = snd_ac97_ymf7x3_spdif_source_info,
338 .get = snd_ac97_ymf753_spdif_source_get, 416 .get = snd_ac97_ymf7x3_spdif_source_get,
339 .put = snd_ac97_ymf753_spdif_source_put, 417 .put = snd_ac97_ymf7x3_spdif_source_put,
340 }, 418 },
341 { 419 {
342 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 420 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -345,25 +423,10 @@ static const struct snd_kcontrol_new snd_ac97_ymf753_controls_spdif[3] = {
345 .get = snd_ac97_ymf753_spdif_output_pin_get, 423 .get = snd_ac97_ymf753_spdif_output_pin_get,
346 .put = snd_ac97_ymf753_spdif_output_pin_put, 424 .put = snd_ac97_ymf753_spdif_output_pin_put,
347 }, 425 },
348 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",NONE,NONE) "Mute", AC97_YMF753_DIT_CTRL2, 2, 1, 1) 426 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE, NONE) "Mute",
427 AC97_YMF7X3_DIT_CTRL, 2, 1, 1)
349}; 428};
350 429
351static int patch_yamaha_ymf753_3d(struct snd_ac97 * ac97)
352{
353 struct snd_kcontrol *kctl;
354 int err;
355
356 if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
357 return err;
358 strcpy(kctl->id.name, "3D Control - Wide");
359 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 9, 7, 0);
360 snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
361 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&snd_ac97_ymf753_controls_speaker, ac97))) < 0)
362 return err;
363 snd_ac97_write_cache(ac97, AC97_YMF753_3D_MODE_SEL, 0x0c00);
364 return 0;
365}
366
367static int patch_yamaha_ymf753_post_spdif(struct snd_ac97 * ac97) 430static int patch_yamaha_ymf753_post_spdif(struct snd_ac97 * ac97)
368{ 431{
369 int err; 432 int err;
@@ -374,7 +437,7 @@ static int patch_yamaha_ymf753_post_spdif(struct snd_ac97 * ac97)
374} 437}
375 438
376static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = { 439static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = {
377 .build_3d = patch_yamaha_ymf753_3d, 440 .build_3d = patch_yamaha_ymf7x3_3d,
378 .build_post_spdif = patch_yamaha_ymf753_post_spdif 441 .build_post_spdif = patch_yamaha_ymf753_post_spdif
379}; 442};
380 443
@@ -1880,14 +1943,7 @@ static int patch_ad1981b(struct snd_ac97 *ac97)
1880 return 0; 1943 return 0;
1881} 1944}
1882 1945
1883static int snd_ac97_ad1888_lohpsel_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1946#define snd_ac97_ad1888_lohpsel_info snd_ctl_boolean_mono_info
1884{
1885 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1886 uinfo->count = 1;
1887 uinfo->value.integer.min = 0;
1888 uinfo->value.integer.max = 1;
1889 return 0;
1890}
1891 1947
1892static int snd_ac97_ad1888_lohpsel_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1948static int snd_ac97_ad1888_lohpsel_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1893{ 1949{
@@ -2186,15 +2242,7 @@ static int patch_ad1985(struct snd_ac97 * ac97)
2186 return 0; 2242 return 0;
2187} 2243}
2188 2244
2189static int snd_ac97_ad1986_bool_info(struct snd_kcontrol *kcontrol, 2245#define snd_ac97_ad1986_bool_info snd_ctl_boolean_mono_info
2190 struct snd_ctl_elem_info *uinfo)
2191{
2192 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2193 uinfo->count = 1;
2194 uinfo->value.integer.min = 0;
2195 uinfo->value.integer.max = 1;
2196 return 0;
2197}
2198 2246
2199static int snd_ac97_ad1986_lososel_get(struct snd_kcontrol *kcontrol, 2247static int snd_ac97_ad1986_lososel_get(struct snd_kcontrol *kcontrol,
2200 struct snd_ctl_elem_value *ucontrol) 2248 struct snd_ctl_elem_value *ucontrol)