diff options
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/ac97/ac97_patch.c | 70 |
1 files changed, 43 insertions, 27 deletions
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 630c961895dc..075ac4e14bcb 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c | |||
@@ -205,8 +205,11 @@ static inline int is_shared_micin(struct snd_ac97 *ac97) | |||
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 | 207 | ||
208 | /* It is possible to indicate to the Yamaha YMF753 the type of speakers being used. */ | 208 | /* It is possible to indicate to the Yamaha YMF7x3 the type of |
209 | static int snd_ac97_ymf753_info_speaker(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 209 | speakers being used. */ |
210 | |||
211 | static int snd_ac97_ymf7x3_info_speaker(struct snd_kcontrol *kcontrol, | ||
212 | struct snd_ctl_elem_info *uinfo) | ||
210 | { | 213 | { |
211 | static char *texts[3] = { | 214 | static char *texts[3] = { |
212 | "Standard", "Small", "Smaller" | 215 | "Standard", "Small", "Smaller" |
@@ -221,12 +224,13 @@ static int snd_ac97_ymf753_info_speaker(struct snd_kcontrol *kcontrol, struct sn | |||
221 | return 0; | 224 | return 0; |
222 | } | 225 | } |
223 | 226 | ||
224 | static int snd_ac97_ymf753_get_speaker(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 227 | static int snd_ac97_ymf7x3_get_speaker(struct snd_kcontrol *kcontrol, |
228 | struct snd_ctl_elem_value *ucontrol) | ||
225 | { | 229 | { |
226 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | 230 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); |
227 | unsigned short val; | 231 | unsigned short val; |
228 | 232 | ||
229 | val = ac97->regs[AC97_YMF753_3D_MODE_SEL]; | 233 | val = ac97->regs[AC97_YMF7X3_3D_MODE_SEL]; |
230 | val = (val >> 10) & 3; | 234 | val = (val >> 10) & 3; |
231 | if (val > 0) /* 0 = invalid */ | 235 | if (val > 0) /* 0 = invalid */ |
232 | val--; | 236 | val--; |
@@ -234,7 +238,8 @@ static int snd_ac97_ymf753_get_speaker(struct snd_kcontrol *kcontrol, struct snd | |||
234 | return 0; | 238 | return 0; |
235 | } | 239 | } |
236 | 240 | ||
237 | static int snd_ac97_ymf753_put_speaker(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 241 | static int snd_ac97_ymf7x3_put_speaker(struct snd_kcontrol *kcontrol, |
242 | struct snd_ctl_elem_value *ucontrol) | ||
238 | { | 243 | { |
239 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | 244 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); |
240 | unsigned short val; | 245 | unsigned short val; |
@@ -242,20 +247,22 @@ static int snd_ac97_ymf753_put_speaker(struct snd_kcontrol *kcontrol, struct snd | |||
242 | if (ucontrol->value.enumerated.item[0] > 2) | 247 | if (ucontrol->value.enumerated.item[0] > 2) |
243 | return -EINVAL; | 248 | return -EINVAL; |
244 | val = (ucontrol->value.enumerated.item[0] + 1) << 10; | 249 | val = (ucontrol->value.enumerated.item[0] + 1) << 10; |
245 | return snd_ac97_update(ac97, AC97_YMF753_3D_MODE_SEL, val); | 250 | return snd_ac97_update(ac97, AC97_YMF7X3_3D_MODE_SEL, val); |
246 | } | 251 | } |
247 | 252 | ||
248 | static const struct snd_kcontrol_new snd_ac97_ymf753_controls_speaker = | 253 | static const struct snd_kcontrol_new snd_ac97_ymf7x3_controls_speaker = |
249 | { | 254 | { |
250 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 255 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
251 | .name = "3D Control - Speaker", | 256 | .name = "3D Control - Speaker", |
252 | .info = snd_ac97_ymf753_info_speaker, | 257 | .info = snd_ac97_ymf7x3_info_speaker, |
253 | .get = snd_ac97_ymf753_get_speaker, | 258 | .get = snd_ac97_ymf7x3_get_speaker, |
254 | .put = snd_ac97_ymf753_put_speaker, | 259 | .put = snd_ac97_ymf7x3_put_speaker, |
255 | }; | 260 | }; |
256 | 261 | ||
257 | /* It is possible to indicate to the Yamaha YMF753 the source to direct to the S/PDIF output. */ | 262 | /* It is possible to indicate to the Yamaha YMF7x3 the source to |
258 | static int snd_ac97_ymf753_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 263 | direct to the S/PDIF output. */ |
264 | static int snd_ac97_ymf7x3_spdif_source_info(struct snd_kcontrol *kcontrol, | ||
265 | struct snd_ctl_elem_info *uinfo) | ||
259 | { | 266 | { |
260 | static char *texts[2] = { "AC-Link", "A/D Converter" }; | 267 | static char *texts[2] = { "AC-Link", "A/D Converter" }; |
261 | 268 | ||
@@ -268,17 +275,19 @@ static int snd_ac97_ymf753_spdif_source_info(struct snd_kcontrol *kcontrol, stru | |||
268 | return 0; | 275 | return 0; |
269 | } | 276 | } |
270 | 277 | ||
271 | static int snd_ac97_ymf753_spdif_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 278 | static int snd_ac97_ymf7x3_spdif_source_get(struct snd_kcontrol *kcontrol, |
279 | struct snd_ctl_elem_value *ucontrol) | ||
272 | { | 280 | { |
273 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | 281 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); |
274 | unsigned short val; | 282 | unsigned short val; |
275 | 283 | ||
276 | val = ac97->regs[AC97_YMF753_DIT_CTRL2]; | 284 | val = ac97->regs[AC97_YMF7X3_DIT_CTRL]; |
277 | ucontrol->value.enumerated.item[0] = (val >> 1) & 1; | 285 | ucontrol->value.enumerated.item[0] = (val >> 1) & 1; |
278 | return 0; | 286 | return 0; |
279 | } | 287 | } |
280 | 288 | ||
281 | static int snd_ac97_ymf753_spdif_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 289 | static int snd_ac97_ymf7x3_spdif_source_put(struct snd_kcontrol *kcontrol, |
290 | struct snd_ctl_elem_value *ucontrol) | ||
282 | { | 291 | { |
283 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | 292 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); |
284 | unsigned short val; | 293 | unsigned short val; |
@@ -286,7 +295,7 @@ static int snd_ac97_ymf753_spdif_source_put(struct snd_kcontrol *kcontrol, struc | |||
286 | if (ucontrol->value.enumerated.item[0] > 1) | 295 | if (ucontrol->value.enumerated.item[0] > 1) |
287 | return -EINVAL; | 296 | return -EINVAL; |
288 | val = ucontrol->value.enumerated.item[0] << 1; | 297 | val = ucontrol->value.enumerated.item[0] << 1; |
289 | return snd_ac97_update_bits(ac97, AC97_YMF753_DIT_CTRL2, 0x0002, val); | 298 | return snd_ac97_update_bits(ac97, AC97_YMF7X3_DIT_CTRL, 0x0002, val); |
290 | } | 299 | } |
291 | 300 | ||
292 | /* The AC'97 spec states that the S/PDIF signal is to be output at pin 48. | 301 | /* The AC'97 spec states that the S/PDIF signal is to be output at pin 48. |
@@ -311,7 +320,7 @@ static int snd_ac97_ymf753_spdif_output_pin_get(struct snd_kcontrol *kcontrol, s | |||
311 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | 320 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); |
312 | unsigned short val; | 321 | unsigned short val; |
313 | 322 | ||
314 | val = ac97->regs[AC97_YMF753_DIT_CTRL2]; | 323 | val = ac97->regs[AC97_YMF7X3_DIT_CTRL]; |
315 | ucontrol->value.enumerated.item[0] = (val & 0x0008) ? 2 : (val & 0x0020) ? 1 : 0; | 324 | ucontrol->value.enumerated.item[0] = (val & 0x0008) ? 2 : (val & 0x0020) ? 1 : 0; |
316 | return 0; | 325 | return 0; |
317 | } | 326 | } |
@@ -325,7 +334,7 @@ static int snd_ac97_ymf753_spdif_output_pin_put(struct snd_kcontrol *kcontrol, s | |||
325 | return -EINVAL; | 334 | return -EINVAL; |
326 | val = (ucontrol->value.enumerated.item[0] == 2) ? 0x0008 : | 335 | val = (ucontrol->value.enumerated.item[0] == 2) ? 0x0008 : |
327 | (ucontrol->value.enumerated.item[0] == 1) ? 0x0020 : 0; | 336 | (ucontrol->value.enumerated.item[0] == 1) ? 0x0020 : 0; |
328 | return snd_ac97_update_bits(ac97, AC97_YMF753_DIT_CTRL2, 0x0028, val); | 337 | 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). | 338 | /* 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); */ | 339 | snd_ac97_write_cache(ac97, 0x62, snd_ac97_read(ac97, 0x62) | 0x0008); */ |
331 | } | 340 | } |
@@ -334,9 +343,9 @@ static const struct snd_kcontrol_new snd_ac97_ymf753_controls_spdif[3] = { | |||
334 | { | 343 | { |
335 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 344 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
336 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", | 345 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", |
337 | .info = snd_ac97_ymf753_spdif_source_info, | 346 | .info = snd_ac97_ymf7x3_spdif_source_info, |
338 | .get = snd_ac97_ymf753_spdif_source_get, | 347 | .get = snd_ac97_ymf7x3_spdif_source_get, |
339 | .put = snd_ac97_ymf753_spdif_source_put, | 348 | .put = snd_ac97_ymf7x3_spdif_source_put, |
340 | }, | 349 | }, |
341 | { | 350 | { |
342 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 351 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -345,22 +354,29 @@ static const struct snd_kcontrol_new snd_ac97_ymf753_controls_spdif[3] = { | |||
345 | .get = snd_ac97_ymf753_spdif_output_pin_get, | 354 | .get = snd_ac97_ymf753_spdif_output_pin_get, |
346 | .put = snd_ac97_ymf753_spdif_output_pin_put, | 355 | .put = snd_ac97_ymf753_spdif_output_pin_put, |
347 | }, | 356 | }, |
348 | AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",NONE,NONE) "Mute", AC97_YMF753_DIT_CTRL2, 2, 1, 1) | 357 | AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE, NONE) "Mute", |
358 | AC97_YMF7X3_DIT_CTRL, 2, 1, 1) | ||
349 | }; | 359 | }; |
350 | 360 | ||
351 | static int patch_yamaha_ymf753_3d(struct snd_ac97 * ac97) | 361 | static int patch_yamaha_ymf7x3_3d(struct snd_ac97 *ac97) |
352 | { | 362 | { |
353 | struct snd_kcontrol *kctl; | 363 | struct snd_kcontrol *kctl; |
354 | int err; | 364 | int err; |
355 | 365 | ||
356 | if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0) | 366 | kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97); |
367 | err = snd_ctl_add(ac97->bus->card, kctl); | ||
368 | if (err < 0) | ||
357 | return err; | 369 | return err; |
358 | strcpy(kctl->id.name, "3D Control - Wide"); | 370 | strcpy(kctl->id.name, "3D Control - Wide"); |
359 | kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 9, 7, 0); | 371 | kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 9, 7, 0); |
360 | snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000); | 372 | 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) | 373 | |
374 | err = snd_ctl_add(ac97->bus->card, | ||
375 | snd_ac97_cnew(&snd_ac97_ymf7x3_controls_speaker, | ||
376 | ac97)); | ||
377 | if (err < 0) | ||
362 | return err; | 378 | return err; |
363 | snd_ac97_write_cache(ac97, AC97_YMF753_3D_MODE_SEL, 0x0c00); | 379 | snd_ac97_write_cache(ac97, AC97_YMF7X3_3D_MODE_SEL, 0x0c00); |
364 | return 0; | 380 | return 0; |
365 | } | 381 | } |
366 | 382 | ||
@@ -374,7 +390,7 @@ static int patch_yamaha_ymf753_post_spdif(struct snd_ac97 * ac97) | |||
374 | } | 390 | } |
375 | 391 | ||
376 | static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = { | 392 | static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = { |
377 | .build_3d = patch_yamaha_ymf753_3d, | 393 | .build_3d = patch_yamaha_ymf7x3_3d, |
378 | .build_post_spdif = patch_yamaha_ymf753_post_spdif | 394 | .build_post_spdif = patch_yamaha_ymf753_post_spdif |
379 | }; | 395 | }; |
380 | 396 | ||