void ac97_attach(ac97_dev **_dev, codec_reg_read reg_read, codec_reg_write reg_write, void *cookie) { ac97_dev *dev; codec_table *codec; *_dev = dev = (ac97_dev *) malloc(sizeof(ac97_dev)); dev->cookie = cookie; dev->reg_read = reg_read; dev->reg_write = reg_write; dev->codec_id = (reg_read(cookie, AC97_VENDOR_ID1) << 16) | reg_read(cookie, AC97_VENDOR_ID2); codec = find_codec_table(dev->codec_id); dev->codec_info = codec->info; dev->init = codec->init; dev->set_rate = 0; dev->get_rate = 0; dev->clock = 48000; /* default clock on non-broken motherboards */ dev->min_vsr = 0x0001; dev->max_vsr = 0xffff; dev->reversed_eamp_polarity = false; /* reset the codec */ LOG(("codec reset\n")); ac97_reg_uncached_write(dev, AC97_RESET, 0x0000); snooze(50000); // 50 ms /* setup register cache */ ac97_update_register_cache(dev); dev->codec_3d_stereo_enhancement = stereo_enhancement_technique[(ac97_reg_cached_read(dev, AC97_RESET) >> 10) & 31]; dev->capabilities = 0; ac97_reg_update_bits(dev, AC97_EXTENDED_STAT_CTRL, 1, 1); // enable variable rate audio ac97_detect_capabilities(dev); dev->init(dev); ac97_amp_enable(dev, true); /* set mixer defaults, enabled Line-out sources are PCM-out, CD-in, Line-in */ ac97_reg_update(dev, AC97_CENTER_LFE_VOLUME, 0x0000); /* set LFE & center volume 0dB */ ac97_reg_update(dev, AC97_SURR_VOLUME, 0x0000); /* set surround volume 0dB */ ac97_reg_update(dev, AC97_MASTER_VOLUME, 0x0000); /* set master output 0dB */ ac97_reg_update(dev, AC97_AUX_OUT_VOLUME, 0x0000); /* set aux output 0dB */ ac97_reg_update(dev, AC97_MONO_VOLUME, 0x0000); /* set mono output 0dB */ ac97_reg_update(dev, AC97_PCM_OUT_VOLUME, 0x0808); /* enable pcm-out */ ac97_reg_update(dev, AC97_CD_VOLUME, 0x0808); /* enable cd-in */ ac97_reg_update(dev, AC97_LINE_IN_VOLUME, 0x0808); /* enable line-in */ ac97_dump_capabilities(dev); }
void ac97_detach(ac97_dev *dev) { /* Mute everything */ ac97_reg_update_bits(dev, AC97_CENTER_LFE_VOLUME, 0x8000, 0x8000); ac97_reg_update_bits(dev, AC97_SURR_VOLUME, 0x8000, 0x8000); ac97_reg_update_bits(dev, AC97_MASTER_VOLUME, 0x8000, 0x8000); ac97_reg_update_bits(dev, AC97_AUX_OUT_VOLUME, 0x8000, 0x8000); ac97_reg_update_bits(dev, AC97_MONO_VOLUME, 0x8000, 0x8000); ac97_reg_update_bits(dev, AC97_PCM_OUT_VOLUME, 0x8000, 0x8000); ac97_reg_update_bits(dev, AC97_CD_VOLUME, 0x8000, 0x8000); ac97_reg_update_bits(dev, AC97_LINE_IN_VOLUME, 0x8000, 0x8000); ac97_amp_enable(dev, false); free(dev); }
void ac97_resume(ac97_dev *dev) { ac97_amp_enable(dev, true); }
void ac97_suspend(ac97_dev *dev) { ac97_amp_enable(dev, false); }
void ac97_attach(ac97_dev **_dev, codec_reg_read reg_read, codec_reg_write reg_write, void *cookie, ushort subvendor_id, ushort subsystem_id) { ac97_dev *dev; codec_table *codec; int i; *_dev = dev = (ac97_dev *) malloc(sizeof(ac97_dev)); dev->cookie = cookie; dev->reg_read = reg_read; dev->reg_write = reg_write; dev->set_rate = 0; dev->get_rate = 0; dev->clock = 48000; /* default clock on non-broken motherboards */ dev->min_vsr = 0x0001; dev->max_vsr = 0xffff; dev->reversed_eamp_polarity = false; dev->capabilities = 0; dev->subsystem = (subvendor_id << 16) | subsystem_id; if (dev->subsystem == 0x161f202f || dev->subsystem == 0x161f203a || dev->subsystem == 0x161f203e || dev->subsystem == 0x161f204c || dev->subsystem == 0x104d8144 || dev->subsystem == 0x104d8197 || dev->subsystem == 0x104d81c0 || dev->subsystem == 0x104d81c5 || dev->subsystem == 0x103c3089 || dev->subsystem == 0x103c309a || dev->subsystem == 0x10338213 || dev->subsystem == 0x103382be) { dev->reversed_eamp_polarity = true; } /* reset the codec */ LOG(("codec reset\n")); ac97_reg_uncached_write(dev, AC97_RESET, 0x0000); for (i = 0; i < 500; i++) { if ((ac97_reg_uncached_read(dev, AC97_POWERDOWN) & 0xf) == 0xf) break; snooze(1000); } dev->codec_id = ((uint32)reg_read(cookie, AC97_VENDOR_ID1) << 16) | reg_read(cookie, AC97_VENDOR_ID2); codec = find_codec_table(dev->codec_id); dev->codec_info = codec->info; dev->init = codec->init; dev->codec_3d_stereo_enhancement = stereo_enhancement_technique[(ac97_reg_cached_read(dev, AC97_RESET) >> 10) & 31]; /* setup register cache */ ac97_update_register_cache(dev); ac97_reg_update_bits(dev, AC97_EXTENDED_STAT_CTRL, 1, 1); // enable variable rate audio ac97_detect_capabilities(dev); dev->init(dev); ac97_amp_enable(dev, true); /* set mixer defaults, enabled Line-out sources are PCM-out, CD-in, Line-in */ ac97_reg_update(dev, AC97_CENTER_LFE_VOLUME, 0x0000); /* set LFE & center volume 0dB */ ac97_reg_update(dev, AC97_SURR_VOLUME, 0x0000); /* set surround volume 0dB */ ac97_reg_update(dev, AC97_MASTER_VOLUME, 0x0000); /* set master output 0dB */ ac97_reg_update(dev, AC97_AUX_OUT_VOLUME, 0x0000); /* set aux output 0dB */ ac97_reg_update(dev, AC97_MONO_VOLUME, 0x0000); /* set mono output 0dB */ ac97_reg_update(dev, AC97_PCM_OUT_VOLUME, 0x0808); /* enable pcm-out */ ac97_reg_update(dev, AC97_CD_VOLUME, 0x0808); /* enable cd-in */ ac97_reg_update(dev, AC97_LINE_IN_VOLUME, 0x0808); /* enable line-in */ /* set record line in */ ac97_reg_update(dev, AC97_RECORD_SELECT, 0x0404); LOG(("codec vendor id = %#08lx\n", dev->codec_id)); LOG(("codec description = %s\n", dev->codec_info)); LOG(("codec 3d enhancement = %s\n", dev->codec_3d_stereo_enhancement)); ac97_dump_capabilities(dev); }