X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/4533b3dcd0ad69a1f0db39c2c1debe4b84b8baf3..a7fde8a1434b865dfc27f25e681530a49a4645cc:/sys/dev/sound/pcm/ac97.c?ds=sidebyside diff --git a/sys/dev/sound/pcm/ac97.c b/sys/dev/sound/pcm/ac97.c index c92585b947..3edbe41b55 100644 --- a/sys/dev/sound/pcm/ac97.c +++ b/sys/dev/sound/pcm/ac97.c @@ -23,8 +23,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/sound/pcm/ac97.c,v 1.53.2.5 2007/05/13 20:53:39 ariff Exp $ - * $DragonFly: src/sys/dev/sound/pcm/ac97.c,v 1.25 2007/06/16 20:07:22 dillon Exp $ + * $FreeBSD: src/sys/dev/sound/pcm/ac97.c,v 1.53.2.6 2007/10/31 04:00:07 ariff Exp $ + * $DragonFly: src/sys/dev/sound/pcm/ac97.c,v 1.26 2007/11/30 07:59:56 hasso Exp $ */ #include @@ -35,7 +35,7 @@ #include "mixer_if.h" -SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pcm/ac97.c,v 1.25 2007/06/16 20:07:22 dillon Exp $"); +SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pcm/ac97.c,v 1.26 2007/11/30 07:59:56 hasso Exp $"); MALLOC_DEFINE(M_AC97, "ac97", "ac97 codec"); @@ -574,38 +574,6 @@ ac97_fix_tone(struct ac97_info *codec) } } -static void -ac97_fix_volume(struct ac97_info *codec) -{ - struct snddev_info *d = device_get_softc(codec->dev); - -#if 0 - /* XXX For the sake of debugging purposes */ - ac97_wrcd(codec, AC97_MIX_PCM, 0); - bzero(&codec->mix[SOUND_MIXER_PCM], - sizeof(codec->mix[SOUND_MIXER_PCM])); - if (d) - d->flags |= SD_F_SOFTPCMVOL; - return; -#endif - switch (codec->id) { - case 0x434d4941: /* CMI9738 */ - case 0x434d4961: /* CMI9739 */ - case 0x434d4978: /* CMI9761 */ - case 0x434d4982: /* CMI9761 */ - case 0x434d4983: /* CMI9761 */ - ac97_wrcd(codec, AC97_MIX_PCM, 0); - break; - default: - return; - break; - } - bzero(&codec->mix[SOUND_MIXER_PCM], - sizeof(codec->mix[SOUND_MIXER_PCM])); - if (d) - d->flags |= SD_F_SOFTPCMVOL; -} - static const char* ac97_hw_desc(u_int32_t id, const char* vname, const char* cname, char* buf) { @@ -714,7 +682,6 @@ ac97_initmixer(struct ac97_info *codec) } ac97_fix_auxout(codec); ac97_fix_tone(codec); - ac97_fix_volume(codec); if (codec_patch) codec_patch(codec); @@ -911,6 +878,79 @@ ac97mix_init(struct snd_mixer *m) if (ac97_initmixer(codec)) return -1; + switch (codec->id) { + case 0x41445374: /* AD1981B */ + switch (codec->subvendor) { + case 0x02d91014: + /* + * IBM Thinkcentre: + * + * Tie "ogain" and "phout" to "vol" since its + * master volume is basically useless and can't + * control anything. + */ + mask = 0; + if (codec->mix[SOUND_MIXER_OGAIN].enable) + mask |= SOUND_MASK_OGAIN; + if (codec->mix[SOUND_MIXER_PHONEOUT].enable) + mask |= SOUND_MASK_PHONEOUT; + if (codec->mix[SOUND_MIXER_VOLUME].enable) + mix_setparentchild(m, SOUND_MIXER_VOLUME, + mask); + else { + mix_setparentchild(m, SOUND_MIXER_VOLUME, + mask); + mix_setrealdev(m, SOUND_MIXER_VOLUME, + SOUND_MIXER_NONE); + } + break; + case 0x099c103c: + /* + * HP nx6110: + * + * By default, "vol" is controlling internal speakers + * (not a master volume!) and "ogain" is controlling + * headphone. Enable dummy "phout" so it can be + * remapped to internal speakers and virtualize + * "vol" to control both. + */ + codec->mix[SOUND_MIXER_OGAIN].enable = 1; + codec->mix[SOUND_MIXER_PHONEOUT].enable = 1; + mix_setrealdev(m, SOUND_MIXER_PHONEOUT, + SOUND_MIXER_VOLUME); + mix_setrealdev(m, SOUND_MIXER_VOLUME, + SOUND_MIXER_NONE); + mix_setparentchild(m, SOUND_MIXER_VOLUME, + SOUND_MASK_OGAIN | SOUND_MASK_PHONEOUT); + break; + default: + break; + } + break; + case 0x434d4941: /* CMI9738 */ + case 0x434d4961: /* CMI9739 */ + case 0x434d4978: /* CMI9761 */ + case 0x434d4982: /* CMI9761 */ + case 0x434d4983: /* CMI9761 */ + ac97_wrcd(codec, AC97_MIX_PCM, 0); + bzero(&codec->mix[SOUND_MIXER_PCM], + sizeof(codec->mix[SOUND_MIXER_PCM])); + pcm_setflags(codec->dev, pcm_getflags(codec->dev) | + SD_F_SOFTPCMVOL); + /* XXX How about master volume ? */ + break; + default: + break; + } + +#if 0 + /* XXX For the sake of debugging purposes */ + mix_setparentchild(m, SOUND_MIXER_VOLUME, + SOUND_MASK_PCM | SOUND_MASK_CD); + mix_setrealdev(m, SOUND_MIXER_VOLUME, SOUND_MIXER_NONE); + ac97_wrcd(codec, AC97_MIX_MASTER, 0); +#endif + mask = 0; for (i = 0; i < 32; i++) mask |= codec->mix[i].enable? 1 << i : 0;