At Wed, 19 Sep 2007 20:28:22 +0900, Keita Maehara wrote:
Okay, here it is.
And this is the second part.
From: Keita Maehara maehara@debian.org
These patches enable a few YMF743 controls (Tone/3D/IEC958) that won't be detected with the current version of ALSA.
Signed-off-by: Keita Maehara maehara@debian.org
---
The second one contains following changes:
- A chip-specific SPDIF support for YMF743 (It doesn't have AC97 standard SPDIF registers seen on YMF753).
- The implementation for "IEC958 Playback Source" and "IEC958 Mute" are identical to the ones for YMF753. But there is no "IEC958 Output Pin" for YMF743.
diff -r a543470c3455 pci/ac97/ac97_codec.c --- a/pci/ac97/ac97_codec.c Wed Sep 19 07:52:08 2007 +0900 +++ b/pci/ac97/ac97_codec.c Wed Sep 19 07:52:14 2007 +0900 @@ -176,7 +176,7 @@ static const struct ac97_codec_id snd_ac { 0x574d4C09, 0xffffffff, "WM9709", NULL, NULL}, { 0x574d4C12, 0xffffffff, "WM9711,WM9712", patch_wolfson11, NULL}, { 0x574d4c13, 0xffffffff, "WM9713,WM9714", patch_wolfson13, NULL, AC97_DEFAULT_POWER_OFF}, -{ 0x594d4800, 0xffffffff, "YMF743", NULL, NULL }, +{ 0x594d4800, 0xffffffff, "YMF743", patch_yamaha_ymf743, NULL }, { 0x594d4802, 0xffffffff, "YMF752", NULL, NULL }, { 0x594d4803, 0xffffffff, "YMF753", patch_yamaha_ymf753, NULL }, { 0x83847600, 0xffffffff, "STAC9700,83,84", patch_sigmatel_stac9700, NULL }, @@ -779,6 +779,12 @@ static int snd_ac97_spdif_default_put(st change |= snd_ac97_update_bits_nolock(ac97, AC97_CXR_AUDIO_MISC, AC97_CXR_SPDIF_MASK | AC97_CXR_COPYRGT, v); + } else if (ac97->id == AC97_ID_YMF743) { + change |= snd_ac97_update_bits_nolock(ac97, + AC97_YMF7X3_DIT_CTRL, + 0xff38, + ((val << 4) & 0xff00) | + ((val << 2) & 0x0038)); } else { unsigned short extst = snd_ac97_read_cache(ac97, AC97_EXTENDED_STATUS); snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* turn off */ @@ -1375,7 +1381,8 @@ static int snd_ac97_mixer_build(struct s for (idx = 0; idx < 2; idx++) { if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_tone[idx], ac97))) < 0) return err; - if (ac97->id == AC97_ID_YMF753) { + if (ac97->id == AC97_ID_YMF743 || + ac97->id == AC97_ID_YMF753) { kctl->private_value &= ~(0xff << 16); kctl->private_value |= 7 << 16; } diff -r a543470c3455 pci/ac97/ac97_id.h --- a/pci/ac97/ac97_id.h Wed Sep 19 07:52:08 2007 +0900 +++ b/pci/ac97/ac97_id.h Wed Sep 19 07:52:14 2007 +0900 @@ -54,6 +54,7 @@ #define AC97_ID_ALC658 0x414c4780 #define AC97_ID_ALC658D 0x414c4781 #define AC97_ID_ALC850 0x414c4790 +#define AC97_ID_YMF743 0x594d4800 #define AC97_ID_YMF753 0x594d4803 #define AC97_ID_VT1616 0x49434551 #define AC97_ID_CM9738 0x434d4941 diff -r a543470c3455 pci/ac97/ac97_patch.c --- a/pci/ac97/ac97_patch.c Wed Sep 19 07:52:08 2007 +0900 +++ b/pci/ac97/ac97_patch.c Wed Sep 19 07:52:39 2007 +0900 @@ -204,6 +204,7 @@ static inline int is_shared_micin(struct
/* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */ +/* Modified for YMF743 by Keita Maehara maehara@debian.org */
/* It is possible to indicate to the Yamaha YMF7x3 the type of speakers being used. */ @@ -296,6 +297,74 @@ static int snd_ac97_ymf7x3_spdif_source_ return -EINVAL; val = ucontrol->value.enumerated.item[0] << 1; return snd_ac97_update_bits(ac97, AC97_YMF7X3_DIT_CTRL, 0x0002, val); +} + +static int patch_yamaha_ymf7x3_3d(struct snd_ac97 *ac97) +{ + struct snd_kcontrol *kctl; + int err; + + kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97); + err = snd_ctl_add(ac97->bus->card, kctl); + if (err < 0) + return err; + strcpy(kctl->id.name, "3D Control - Wide"); + kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 9, 7, 0); + snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000); + err = snd_ctl_add(ac97->bus->card, + snd_ac97_cnew(&snd_ac97_ymf7x3_controls_speaker, + ac97)); + if (err < 0) + return err; + snd_ac97_write_cache(ac97, AC97_YMF7X3_3D_MODE_SEL, 0x0c00); + return 0; +} + +static const struct snd_kcontrol_new snd_ac97_yamaha_ymf743_controls_spdif[3] = +{ + AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH), + AC97_YMF7X3_DIT_CTRL, 0, 1, 0), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Source", + .info = snd_ac97_ymf7x3_spdif_source_info, + .get = snd_ac97_ymf7x3_spdif_source_get, + .put = snd_ac97_ymf7x3_spdif_source_put, + }, + AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE, NONE) "Mute", + AC97_YMF7X3_DIT_CTRL, 2, 1, 1) +}; + +static int patch_yamaha_ymf743_build_spdif(struct snd_ac97 *ac97) +{ + int err; + + err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3); + if (err < 0) + return err; + err = patch_build_controls(ac97, + snd_ac97_yamaha_ymf743_controls_spdif, 3); + if (err < 0) + return err; + /* set default PCM S/PDIF params */ + /* PCM audio,no copyright,no preemphasis,PCM coder,original */ + snd_ac97_write_cache(ac97, AC97_YMF7X3_DIT_CTRL, 0xa201); + return 0; +} + +static struct snd_ac97_build_ops patch_yamaha_ymf743_ops = { + .build_spdif = patch_yamaha_ymf743_build_spdif, + .build_3d = patch_yamaha_ymf7x3_3d, +}; + +static int patch_yamaha_ymf743(struct snd_ac97 *ac97) +{ + ac97->build_ops = &patch_yamaha_ymf743_ops; + ac97->caps |= AC97_BC_BASS_TREBLE; + ac97->caps |= 0x04 << 10; /* Yamaha 3D enhancement */ + ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */ + ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ + return 0; }
/* The AC'97 spec states that the S/PDIF signal is to be output at pin 48. @@ -357,28 +426,6 @@ static const struct snd_kcontrol_new snd AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE, NONE) "Mute", AC97_YMF7X3_DIT_CTRL, 2, 1, 1) }; - -static int patch_yamaha_ymf7x3_3d(struct snd_ac97 *ac97) -{ - struct snd_kcontrol *kctl; - int err; - - kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97); - err = snd_ctl_add(ac97->bus->card, kctl); - if (err < 0) - return err; - strcpy(kctl->id.name, "3D Control - Wide"); - kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 9, 7, 0); - snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000); - - err = snd_ctl_add(ac97->bus->card, - snd_ac97_cnew(&snd_ac97_ymf7x3_controls_speaker, - ac97)); - if (err < 0) - return err; - snd_ac97_write_cache(ac97, AC97_YMF7X3_3D_MODE_SEL, 0x0c00); - return 0; -}
static int patch_yamaha_ymf753_post_spdif(struct snd_ac97 * ac97) { diff -r a543470c3455 pci/ac97/ac97_proc.c --- a/pci/ac97/ac97_proc.c Wed Sep 19 07:52:08 2007 +0900 +++ b/pci/ac97/ac97_proc.c Wed Sep 19 07:52:14 2007 +0900 @@ -236,10 +236,14 @@ static void snd_ac97_proc_read_main(stru val = snd_ac97_read(ac97, AC97_PCM_MIC_ADC_RATE); snd_iprintf(buffer, "PCM MIC ADC : %iHz\n", val); } - if ((ext & AC97_EI_SPDIF) || (ac97->flags & AC97_CS_SPDIF)) { + if ((ext & AC97_EI_SPDIF) || (ac97->flags & AC97_CS_SPDIF) || + (ac97->id == AC97_ID_YMF743)) { if (ac97->flags & AC97_CS_SPDIF) val = snd_ac97_read(ac97, AC97_CSR_SPDIF); - else + else if (ac97->id == AC97_ID_YMF743) { + val = snd_ac97_read(ac97, AC97_YMF7X3_DIT_CTRL); + val = 0x2000 | (val & 0xff00) >> 4 | (val & 0x38) >> 2; + } else val = snd_ac97_read(ac97, AC97_SPDIF);
snd_iprintf(buffer, "SPDIF Control :%s%s%s%s Category=0x%x Generation=%i%s%s%s\n",