Lines Matching full:codec

40 static MALLOC_DEFINE(M_AC97, "ac97", "ac97 codec");
242 * XXX This is a fluke, really! The real codec
316 ac97_rdcd(struct ac97_info *codec, int reg)
318 if (codec->flags & AC97_F_RDCD_BUG) {
321 i[0] = AC97_READ(codec->methods, codec->devinfo, reg);
322 i[1] = AC97_READ(codec->methods, codec->devinfo, reg);
324 i[j-- & 1] = AC97_READ(codec->methods, codec->devinfo, reg);
327 return AC97_READ(codec->methods, codec->devinfo, reg);
331 ac97_wrcd(struct ac97_info *codec, int reg, u_int16_t val)
333 AC97_WRITE(codec->methods, codec->devinfo, reg, val);
337 ac97_reset(struct ac97_info *codec)
340 ac97_wrcd(codec, AC97_REG_RESET, 0);
342 ps = ac97_rdcd(codec, AC97_REG_POWER) & AC97_POWER_STATUS;
347 device_printf(codec->dev, "AC97 reset timed out.\n");
351 ac97_setrate(struct ac97_info *codec, int which, int rate)
367 snd_mtxlock(codec->lock);
370 if (codec->extstat & AC97_EXTCAP_DRA)
372 ac97_wrcd(codec, which, v);
374 v = ac97_rdcd(codec, which);
375 if (codec->extstat & AC97_EXTCAP_DRA)
377 snd_mtxunlock(codec->lock);
382 ac97_setextmode(struct ac97_info *codec, u_int16_t mode)
385 if ((mode & ~codec->extcaps) != 0) {
386 device_printf(codec->dev, "ac97 invalid mode set 0x%04x\n",
390 snd_mtxlock(codec->lock);
391 ac97_wrcd(codec, AC97_REGEXT_STAT, mode);
392 codec->extstat = ac97_rdcd(codec, AC97_REGEXT_STAT) & AC97_EXTCAPS;
393 snd_mtxunlock(codec->lock);
394 return (mode == codec->extstat)? 0 : -1;
398 ac97_getextmode(struct ac97_info *codec)
400 return codec->extstat;
404 ac97_getextcaps(struct ac97_info *codec)
406 return codec->extcaps;
410 ac97_getcaps(struct ac97_info *codec)
412 return codec->caps;
416 ac97_getsubvendor(struct ac97_info *codec)
418 return codec->subvendor;
422 ac97_setrecsrc(struct ac97_info *codec, int channel)
424 struct ac97mixtable_entry *e = &codec->mix[channel];
429 snd_mtxlock(codec->lock);
430 ac97_wrcd(codec, AC97_REG_RECSEL, val);
431 snd_mtxunlock(codec->lock);
438 ac97_setmixer(struct ac97_info *codec, unsigned channel, unsigned left, unsigned right)
440 struct ac97mixtable_entry *e = &codec->mix[channel];
455 * write into the codec, and scale back to 0..100
500 snd_mtxlock(codec->lock);
502 int cur = ac97_rdcd(codec, reg);
505 ac97_wrcd(codec, reg, val);
506 snd_mtxunlock(codec->lock);
514 ac97_fix_auxout(struct ac97_info *codec)
525 keep_ogain = ac97_rdcd(codec, AC97_MIX_AUXOUT) & 0x8000;
536 if (codec->extcaps & AC97_EXTCAP_SDAC &&
537 ac97_rdcd(codec, AC97_MIXEXT_SURROUND) == 0x8080) {
538 codec->mix[SOUND_MIXER_OGAIN].reg = AC97_MIXEXT_SURROUND;
543 bzero(&codec->mix[SOUND_MIXER_OGAIN],
544 sizeof(codec->mix[SOUND_MIXER_OGAIN]));
549 ac97_fix_tone(struct ac97_info *codec)
555 switch (codec->id) {
558 codec->caps |= AC97_CAP_TONE;
559 codec->se |= 0x04;
562 codec->se |= 0x04;
569 if ((codec->caps & AC97_CAP_TONE) == 0) {
570 bzero(&codec->mix[SOUND_MIXER_BASS],
571 sizeof(codec->mix[SOUND_MIXER_BASS]));
572 bzero(&codec->mix[SOUND_MIXER_TREBLE],
573 sizeof(codec->mix[SOUND_MIXER_TREBLE]));
581 sprintf(buf, "Unknown AC97 Codec (id = 0x%08x)", id);
588 sprintf(buf, "%s %s AC97 Codec (id = 0x%08x)", vname, cname, id);
590 sprintf(buf, "%s %s AC97 Codec", vname, cname);
596 ac97_initmixer(struct ac97_info *codec)
606 snd_mtxlock(codec->lock);
607 codec->count = AC97_INIT(codec->methods, codec->devinfo);
608 if (codec->count == 0) {
609 device_printf(codec->dev, "ac97 codec init failed\n");
610 snd_mtxunlock(codec->lock);
614 ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000);
615 ac97_reset(codec);
616 ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000);
618 i = ac97_rdcd(codec, AC97_REG_RESET);
619 j = ac97_rdcd(codec, AC97_REG_RESET);
620 k = ac97_rdcd(codec, AC97_REG_RESET);
622 * Let see if this codec can return consistent value.
627 codec->flags |= AC97_F_RDCD_BUG;
628 i = ac97_rdcd(codec, AC97_REG_RESET);
630 codec->caps = i & 0x03ff;
631 codec->se = (i & 0x7c00) >> 10;
633 id = (ac97_rdcd(codec, AC97_REG_ID1) << 16) | ac97_rdcd(codec, AC97_REG_ID2);
635 device_printf(codec->dev, "ac97 codec invalid or not present (id == %x)\n", id);
636 snd_mtxunlock(codec->lock);
640 pdev = codec->dev;
645 codec->id = id;
646 codec->subvendor = (u_int32_t)pci_get_subdevice(pdev) << 16;
647 codec->subvendor |= (u_int32_t)pci_get_subvendor(pdev) &
649 codec->noext = 0;
656 codec->noext = ac97codecid[i].noext;
671 codec->extcaps = 0;
672 codec->extid = 0;
673 codec->extstat = 0;
674 if (!codec->noext) {
675 i = ac97_rdcd(codec, AC97_REGEXT_ID);
677 codec->extcaps = i & 0x3fff;
678 codec->extid = (i & 0xc000) >> 14;
679 codec->extstat = ac97_rdcd(codec, AC97_REGEXT_STAT) & AC97_EXTCAPS;
684 codec->mix[i] = ac97mixtable_default[i];
686 ac97_fix_auxout(codec);
687 ac97_fix_tone(codec);
689 codec_patch(codec);
692 k = codec->noext? codec->mix[i].enable : 1;
693 reg = codec->mix[i].reg;
697 j = old = ac97_rdcd(codec, reg);
702 if (codec->mix[i].mute) {
703 ac97_wrcd(codec, reg, j | 0x8000);
704 j = ac97_rdcd(codec, reg);
717 bit = codec->mix[i].bits;
720 j = ((1 << bit) - 1) << codec->mix[i].ofs;
721 ac97_wrcd(codec, reg,
722 j | (codec->mix[i].mute ? 0x8000 : 0));
723 k = ac97_rdcd(codec, reg) & j;
724 k >>= codec->mix[i].ofs;
731 codec->mix[i].enable = 1;
732 codec->mix[i].bits = j;
735 * Few codec such as CX20468-21 does
739 codec->mix[i].enable = 1;
741 codec->mix[i].enable = 0;
743 codec->mix[i].enable = 0;
744 ac97_wrcd(codec, reg, old);
748 device_printf(codec->dev, "<%s>\n",
749 ac97_hw_desc(codec->id, vname, cname, desc));
752 if (codec->flags & AC97_F_RDCD_BUG)
753 device_printf(codec->dev, "Buggy AC97 Codec: aggressive ac97_rdcd() workaround enabled\n");
754 device_printf(codec->dev, "Codec features ");
756 if (codec->caps & (1 << i))
758 printf("%s%d bit master volume", j++? ", " : "", codec->mix[SOUND_MIXER_VOLUME].bits);
759 printf("%s%s\n", j? ", " : "", ac97enhancement[codec->se]);
761 if (codec->extcaps != 0 || codec->extid) {
762 device_printf(codec->dev, "%s codec",
763 codec->extid? "Secondary" : "Primary");
764 if (codec->extcaps)
767 if (codec->extcaps & (1 << i))
774 while ((ac97_rdcd(codec, AC97_REG_POWER) & 2) == 0) {
776 device_printf(codec->dev, "ac97 codec reports dac not ready\n");
782 device_printf(codec->dev, "ac97 codec dac ready count: %d\n", i);
783 snd_mtxunlock(codec->lock);
788 ac97_reinitmixer(struct ac97_info *codec)
790 snd_mtxlock(codec->lock);
791 codec->count = AC97_INIT(codec->methods, codec->devinfo);
792 if (codec->count == 0) {
793 device_printf(codec->dev, "ac97 codec init failed\n");
794 snd_mtxunlock(codec->lock);
798 ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000);
799 ac97_reset(codec);
800 ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000);
802 if (!codec->noext) {
803 ac97_wrcd(codec, AC97_REGEXT_STAT, codec->extstat);
804 if ((ac97_rdcd(codec, AC97_REGEXT_STAT) & AC97_EXTCAPS)
805 != codec->extstat)
806 device_printf(codec->dev, "ac97 codec failed to reset extended mode (%x, got %x)\n",
807 codec->extstat,
808 ac97_rdcd(codec, AC97_REGEXT_STAT) &
812 if ((ac97_rdcd(codec, AC97_REG_POWER) & 2) == 0)
813 device_printf(codec->dev, "ac97 codec reports dac not ready\n");
814 snd_mtxunlock(codec->lock);
821 struct ac97_info *codec;
824 codec = malloc(sizeof(*codec), M_AC97, M_WAITOK | M_ZERO);
825 snprintf(codec->name, sizeof(codec->name), "%s:ac97",
827 codec->lock = snd_mtxcreate(codec->name, "ac97 codec");
828 codec->methods = kobj_create(cls, M_AC97, M_WAITOK | M_ZERO);
829 codec->dev = dev;
830 codec->devinfo = devinfo;
831 codec->flags = 0;
835 codec->flags |= AC97_F_EAPD_INV;
841 return codec;
845 ac97_destroy(struct ac97_info *codec)
847 snd_mtxlock(codec->lock);
848 if (codec->methods != NULL)
849 kobj_delete(codec->methods, M_AC97);
850 snd_mtxfree(codec->lock);
851 free(codec, M_AC97);
855 ac97_setflags(struct ac97_info *codec, u_int32_t val)
857 codec->flags = val;
861 ac97_getflags(struct ac97_info *codec)
863 return codec->flags;
867 ad1886_patch(struct ac97_info *codec)
876 ac97_wrcd(codec, AC97_AD_JACK_SPDIF, 0x0010);
880 ad198x_patch(struct ac97_info *codec)
882 switch (ac97_getsubvendor(codec)) {
886 ac97_wrcd(codec, 0x76, ac97_rdcd(codec, 0x76) | 0x0420);
892 ad1981b_patch(struct ac97_info *codec)
897 switch (ac97_getsubvendor(codec)) {
900 ac97_wrcd(codec, AC97_AD_JACK_SPDIF,
901 ac97_rdcd(codec, AC97_AD_JACK_SPDIF) | 0x0800);
909 cmi9739_patch(struct ac97_info *codec)
915 switch (ac97_getsubvendor(codec)) {
917 ac97_wrcd(codec, AC97_REG_POWER, 0x000f);
918 ac97_wrcd(codec, AC97_MIXEXT_CLFE, 0x0000);
919 ac97_wrcd(codec, 0x64, 0x7110);
927 alc655_patch(struct ac97_info *codec)
932 switch (ac97_getsubvendor(codec)) {
937 ac97_wrcd(codec, 0x7a, ac97_rdcd(codec, 0x7a) & 0xfffd);
946 ac97_wrcd(codec, 0x6a, ac97_rdcd(codec, 0x6a) | 0x0001);
958 struct ac97_info *codec;
962 codec = oidp->oid_arg1;
963 if (codec == NULL || codec->id == 0 || codec->lock == NULL)
965 snd_mtxlock(codec->lock);
966 val = ac97_rdcd(codec, AC97_REG_POWER);
967 inv = (codec->flags & AC97_F_EAPD_INV) ? 0 : 1;
969 snd_mtxunlock(codec->lock);
975 snd_mtxlock(codec->lock);
976 ac97_wrcd(codec, AC97_REG_POWER, val ^ 0x8000);
977 snd_mtxunlock(codec->lock);
984 ac97_init_sysctl(struct ac97_info *codec)
988 if (codec == NULL || codec->dev == NULL)
990 snd_mtxlock(codec->lock);
991 orig = ac97_rdcd(codec, AC97_REG_POWER);
992 ac97_wrcd(codec, AC97_REG_POWER, orig ^ 0x8000);
993 val = ac97_rdcd(codec, AC97_REG_POWER);
994 ac97_wrcd(codec, AC97_REG_POWER, orig);
995 snd_mtxunlock(codec->lock);
998 SYSCTL_ADD_PROC(device_get_sysctl_ctx(codec->dev),
999 SYSCTL_CHILDREN(device_get_sysctl_tree(codec->dev)),
1002 codec, sizeof(codec), sysctl_hw_snd_ac97_eapd,
1009 struct ac97_info *codec = mix_getdevinfo(m);
1012 if (codec == NULL)
1015 if (ac97_initmixer(codec))
1018 switch (codec->id) {
1020 switch (codec->subvendor) {
1030 if (codec->mix[SOUND_MIXER_OGAIN].enable)
1032 if (codec->mix[SOUND_MIXER_PHONEOUT].enable)
1034 if (codec->mix[SOUND_MIXER_VOLUME].enable)
1054 codec->mix[SOUND_MIXER_OGAIN].enable = 1;
1055 codec->mix[SOUND_MIXER_PHONEOUT].enable = 1;
1072 bzero(&codec->mix[SOUND_MIXER_PCM],
1073 sizeof(codec->mix[SOUND_MIXER_PCM]));
1074 pcm_setflags(codec->dev, pcm_getflags(codec->dev) |
1082 if (pcm_getflags(codec->dev) & SD_F_SOFTPCMVOL)
1083 ac97_wrcd(codec, AC97_MIX_PCM, 0);
1087 mask |= codec->mix[i].enable? 1 << i : 0;
1092 mask |= codec->mix[i].recidx? 1 << i : 0;
1095 ac97_init_sysctl(codec);
1103 struct ac97_info *codec = mix_getdevinfo(m);
1105 if (codec == NULL)
1108 if (ac97_uninitmixer(codec))
1111 ac97_destroy(codec);
1118 struct ac97_info *codec = mix_getdevinfo(m);
1120 if (codec == NULL)
1122 return ac97_reinitmixer(codec);
1128 struct ac97_info *codec = mix_getdevinfo(m);
1130 if (codec == NULL || dev >= AC97_MIXER_SIZE)
1132 return ac97_setmixer(codec, dev, left, right);
1139 struct ac97_info *codec = mix_getdevinfo(m);
1141 if (codec == NULL)
1146 return (ac97_setrecsrc(codec, i) == 0)? 1U << i : 0xffffffffU;