Lines Matching +full:dac +full:- +full:mode +full:- +full:mask

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
51 unsigned mask:1; /* use only masked bits */ member
96 [SOUND_MIXER_IGAIN] = { -AC97_MIX_MIC, 1, 6, 0, 0, 0, 1, 1 },
100 [SOUND_MIXER_RECLEV] = { -AC97_MIX_RGAIN, 4, 0, 1, 1, 0, 0, 1 }
109 { 0x434d4900, "C-Media Electronics" },
180 { 0x43585430, 0x00, 0, "CX20468-21", 0 },
285 "18 bit DAC",
286 "20 bit DAC",
298 "center DAC",
299 "surround DAC",
300 "LFE DAC",
311 if (codec->flags & AC97_F_RDCD_BUG) { in ac97_rdcd()
314 i[0] = AC97_READ(codec->methods, codec->devinfo, reg); in ac97_rdcd()
315 i[1] = AC97_READ(codec->methods, codec->devinfo, reg); in ac97_rdcd()
317 i[j-- & 1] = AC97_READ(codec->methods, codec->devinfo, reg); in ac97_rdcd()
320 device_printf(codec->dev, "%s(): Inconsistent register value at" in ac97_rdcd()
321 " 0x%08x (retry: %d)\n", __func__, reg, 100 - j); in ac97_rdcd()
326 return AC97_READ(codec->methods, codec->devinfo, reg); in ac97_rdcd()
332 AC97_WRITE(codec->methods, codec->devinfo, reg, val); in ac97_wrcd()
346 device_printf(codec->dev, "AC97 reset timed out.\n"); in ac97_reset()
363 return -1; in ac97_setrate()
366 snd_mtxlock(codec->lock); in ac97_setrate()
369 if (codec->extstat & AC97_EXTCAP_DRA) in ac97_setrate()
374 if (codec->extstat & AC97_EXTCAP_DRA) in ac97_setrate()
376 snd_mtxunlock(codec->lock); in ac97_setrate()
381 ac97_setextmode(struct ac97_info *codec, u_int16_t mode) in ac97_setextmode() argument
383 mode &= AC97_EXTCAPS; in ac97_setextmode()
384 if ((mode & ~codec->extcaps) != 0) { in ac97_setextmode()
385 device_printf(codec->dev, "ac97 invalid mode set 0x%04x\n", in ac97_setextmode()
386 mode); in ac97_setextmode()
387 return -1; in ac97_setextmode()
389 snd_mtxlock(codec->lock); in ac97_setextmode()
390 ac97_wrcd(codec, AC97_REGEXT_STAT, mode); in ac97_setextmode()
391 codec->extstat = ac97_rdcd(codec, AC97_REGEXT_STAT) & AC97_EXTCAPS; in ac97_setextmode()
392 snd_mtxunlock(codec->lock); in ac97_setextmode()
393 return (mode == codec->extstat)? 0 : -1; in ac97_setextmode()
399 return codec->extstat; in ac97_getextmode()
405 return codec->extcaps; in ac97_getextcaps()
411 return codec->caps; in ac97_getcaps()
417 return codec->subvendor; in ac97_getsubvendor()
423 struct ac97mixtable_entry *e = &codec->mix[channel]; in ac97_setrecsrc()
425 if (e->recidx > 0) { in ac97_setrecsrc()
426 int val = e->recidx - 1; in ac97_setrecsrc()
428 snd_mtxlock(codec->lock); in ac97_setrecsrc()
430 snd_mtxunlock(codec->lock); in ac97_setrecsrc()
433 return -1; in ac97_setrecsrc()
439 struct ac97mixtable_entry *e = &codec->mix[channel]; in ac97_setmixer()
441 if (e->reg && e->enable && e->bits) { in ac97_setmixer()
442 int mask, max, val, reg; in ac97_setmixer() local
444 reg = (e->reg >= 0) ? e->reg : -e->reg; /* AC97 register */ in ac97_setmixer()
445 max = (1 << e->bits) - 1; /* actual range */ in ac97_setmixer()
446 mask = (max << 8) | max; /* bits of interest */ in ac97_setmixer()
448 if (!e->stereo) in ac97_setmixer()
453 * then scale to 0..max-1 to compute the value to in ac97_setmixer()
457 if (e->reg > 0) { in ac97_setmixer()
458 left = 100 - left; in ac97_setmixer()
459 right = 100 - right; in ac97_setmixer()
470 if (e->reg > 0) { in ac97_setmixer()
471 left = 100 - left; in ac97_setmixer()
472 right = 100 - right; in ac97_setmixer()
476 * For mono controls, trim val and mask, also taking in ac97_setmixer()
477 * care of e->ofs (offset of control field). in ac97_setmixer()
479 if (e->ofs) { in ac97_setmixer()
481 val <<= e->ofs; in ac97_setmixer()
482 mask = (max << e->ofs); in ac97_setmixer()
486 * If we have a mute bit, add it to the mask and in ac97_setmixer()
490 if (e->mute == 1) { in ac97_setmixer()
491 mask |= AC97_MUTE; in ac97_setmixer()
497 * If the mask bit is set, do not alter the other bits. in ac97_setmixer()
499 snd_mtxlock(codec->lock); in ac97_setmixer()
500 if (e->mask) { in ac97_setmixer()
502 val |= cur & ~(mask); in ac97_setmixer()
505 snd_mtxunlock(codec->lock); in ac97_setmixer()
509 printf("ac97_setmixer: reg=%d, bits=%d, enable=%d\n", e->reg, e->bits, e->enable); in ac97_setmixer()
511 return -1; in ac97_setmixer()
533 * 2. 4-Channel Out in ac97_fix_auxout()
538 if (codec->extcaps & AC97_EXTCAP_SDAC && in ac97_fix_auxout()
540 codec->mix[SOUND_MIXER_OGAIN].reg = AC97_MIXEXT_SURROUND; in ac97_fix_auxout()
545 bzero(&codec->mix[SOUND_MIXER_OGAIN], in ac97_fix_auxout()
546 sizeof(codec->mix[SOUND_MIXER_OGAIN])); in ac97_fix_auxout()
557 switch (codec->id) { in ac97_fix_tone()
560 codec->caps |= AC97_CAP_TONE; in ac97_fix_tone()
561 codec->se |= 0x04; in ac97_fix_tone()
564 codec->se |= 0x04; in ac97_fix_tone()
571 if ((codec->caps & AC97_CAP_TONE) == 0) { in ac97_fix_tone()
572 bzero(&codec->mix[SOUND_MIXER_BASS], in ac97_fix_tone()
573 sizeof(codec->mix[SOUND_MIXER_BASS])); in ac97_fix_tone()
574 bzero(&codec->mix[SOUND_MIXER_TREBLE], in ac97_fix_tone()
575 sizeof(codec->mix[SOUND_MIXER_TREBLE])); in ac97_fix_tone()
608 snd_mtxlock(codec->lock); in ac97_initmixer()
609 codec->count = AC97_INIT(codec->methods, codec->devinfo); in ac97_initmixer()
610 if (codec->count == 0) { in ac97_initmixer()
611 device_printf(codec->dev, "ac97 codec init failed\n"); in ac97_initmixer()
612 snd_mtxunlock(codec->lock); in ac97_initmixer()
616 ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000); in ac97_initmixer()
618 ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000); in ac97_initmixer()
629 codec->flags |= AC97_F_RDCD_BUG; in ac97_initmixer()
632 codec->caps = i & 0x03ff; in ac97_initmixer()
633 codec->se = (i & 0x7c00) >> 10; in ac97_initmixer()
637 device_printf(codec->dev, "ac97 codec invalid or not present (id == %x)\n", id); in ac97_initmixer()
638 snd_mtxunlock(codec->lock); in ac97_initmixer()
642 pdev = codec->dev; in ac97_initmixer()
644 /* find the top-level PCI device handler */ in ac97_initmixer()
647 codec->id = id; in ac97_initmixer()
648 codec->subvendor = (u_int32_t)pci_get_subdevice(pdev) << 16; in ac97_initmixer()
649 codec->subvendor |= (u_int32_t)pci_get_subvendor(pdev) & in ac97_initmixer()
651 codec->noext = 0; in ac97_initmixer()
658 codec->noext = ac97codecid[i].noext; in ac97_initmixer()
673 codec->extcaps = 0; in ac97_initmixer()
674 codec->extid = 0; in ac97_initmixer()
675 codec->extstat = 0; in ac97_initmixer()
676 if (!codec->noext) { in ac97_initmixer()
679 codec->extcaps = i & 0x3fff; in ac97_initmixer()
680 codec->extid = (i & 0xc000) >> 14; in ac97_initmixer()
681 codec->extstat = ac97_rdcd(codec, AC97_REGEXT_STAT) & AC97_EXTCAPS; in ac97_initmixer()
686 codec->mix[i] = ac97mixtable_default[i]; in ac97_initmixer()
694 k = codec->noext? codec->mix[i].enable : 1; in ac97_initmixer()
695 reg = codec->mix[i].reg; in ac97_initmixer()
697 reg = -reg; in ac97_initmixer()
704 if (codec->mix[i].mute) { in ac97_initmixer()
719 bit = codec->mix[i].bits; in ac97_initmixer()
722 j = ((1 << bit) - 1) << codec->mix[i].ofs; in ac97_initmixer()
724 j | (codec->mix[i].mute ? 0x8000 : 0)); in ac97_initmixer()
726 k >>= codec->mix[i].ofs; in ac97_initmixer()
734 device_printf(codec->dev, "%2d: [ac97_rdcd() = %d] [Testbit = %d] %d -> %d\n", in ac97_initmixer()
735 i, k, bit, codec->mix[i].bits, j); in ac97_initmixer()
737 codec->mix[i].enable = 1; in ac97_initmixer()
738 codec->mix[i].bits = j; in ac97_initmixer()
741 * Few codec such as CX20468-21 does in ac97_initmixer()
745 codec->mix[i].enable = 1; in ac97_initmixer()
747 codec->mix[i].enable = 0; in ac97_initmixer()
749 codec->mix[i].enable = 0; in ac97_initmixer()
753 printf("mixch %d, en=%d, b=%d\n", i, codec->mix[i].enable, codec->mix[i].bits); in ac97_initmixer()
757 device_printf(codec->dev, "<%s>\n", in ac97_initmixer()
758 ac97_hw_desc(codec->id, vname, cname, desc)); in ac97_initmixer()
761 if (codec->flags & AC97_F_RDCD_BUG) in ac97_initmixer()
762 device_printf(codec->dev, "Buggy AC97 Codec: aggressive ac97_rdcd() workaround enabled\n"); in ac97_initmixer()
763 device_printf(codec->dev, "Codec features "); in ac97_initmixer()
765 if (codec->caps & (1 << i)) in ac97_initmixer()
767 printf("%s%d bit master volume", j++? ", " : "", codec->mix[SOUND_MIXER_VOLUME].bits); in ac97_initmixer()
768 printf("%s%s\n", j? ", " : "", ac97enhancement[codec->se]); in ac97_initmixer()
770 if (codec->extcaps != 0 || codec->extid) { in ac97_initmixer()
771 device_printf(codec->dev, "%s codec", in ac97_initmixer()
772 codec->extid? "Secondary" : "Primary"); in ac97_initmixer()
773 if (codec->extcaps) in ac97_initmixer()
776 if (codec->extcaps & (1 << i)) in ac97_initmixer()
785 device_printf(codec->dev, "ac97 codec reports dac not ready\n"); in ac97_initmixer()
791 device_printf(codec->dev, "ac97 codec dac ready count: %d\n", i); in ac97_initmixer()
792 snd_mtxunlock(codec->lock); in ac97_initmixer()
799 snd_mtxlock(codec->lock); in ac97_reinitmixer()
800 codec->count = AC97_INIT(codec->methods, codec->devinfo); in ac97_reinitmixer()
801 if (codec->count == 0) { in ac97_reinitmixer()
802 device_printf(codec->dev, "ac97 codec init failed\n"); in ac97_reinitmixer()
803 snd_mtxunlock(codec->lock); in ac97_reinitmixer()
807 ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000); in ac97_reinitmixer()
809 ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000); in ac97_reinitmixer()
811 if (!codec->noext) { in ac97_reinitmixer()
812 ac97_wrcd(codec, AC97_REGEXT_STAT, codec->extstat); in ac97_reinitmixer()
814 != codec->extstat) in ac97_reinitmixer()
815 device_printf(codec->dev, "ac97 codec failed to reset extended mode (%x, got %x)\n", in ac97_reinitmixer()
816 codec->extstat, in ac97_reinitmixer()
822 device_printf(codec->dev, "ac97 codec reports dac not ready\n"); in ac97_reinitmixer()
823 snd_mtxunlock(codec->lock); in ac97_reinitmixer()
834 snprintf(codec->name, sizeof(codec->name), "%s:ac97", in ac97_create()
836 codec->lock = snd_mtxcreate(codec->name, "ac97 codec"); in ac97_create()
837 codec->methods = kobj_create(cls, M_AC97, M_WAITOK | M_ZERO); in ac97_create()
838 codec->dev = dev; in ac97_create()
839 codec->devinfo = devinfo; in ac97_create()
840 codec->flags = 0; in ac97_create()
844 codec->flags |= AC97_F_EAPD_INV; in ac97_create()
856 snd_mtxlock(codec->lock); in ac97_destroy()
857 if (codec->methods != NULL) in ac97_destroy()
858 kobj_delete(codec->methods, M_AC97); in ac97_destroy()
859 snd_mtxfree(codec->lock); in ac97_destroy()
866 codec->flags = val; in ac97_setflags()
872 return codec->flags; in ac97_getflags()
875 /* -------------------------------------------------------------------- */
884 codec = oidp->oid_arg1; in sysctl_hw_snd_ac97_eapd()
885 if (codec == NULL || codec->id == 0 || codec->lock == NULL) in sysctl_hw_snd_ac97_eapd()
887 snd_mtxlock(codec->lock); in sysctl_hw_snd_ac97_eapd()
889 inv = (codec->flags & AC97_F_EAPD_INV) ? 0 : 1; in sysctl_hw_snd_ac97_eapd()
891 snd_mtxunlock(codec->lock); in sysctl_hw_snd_ac97_eapd()
893 if (err == 0 && req->newptr != NULL) { in sysctl_hw_snd_ac97_eapd()
897 snd_mtxlock(codec->lock); in sysctl_hw_snd_ac97_eapd()
899 snd_mtxunlock(codec->lock); in sysctl_hw_snd_ac97_eapd()
910 if (codec == NULL || codec->dev == NULL) in ac97_init_sysctl()
912 snd_mtxlock(codec->lock); in ac97_init_sysctl()
917 snd_mtxunlock(codec->lock); in ac97_init_sysctl()
920 SYSCTL_ADD_PROC(device_get_sysctl_ctx(codec->dev), in ac97_init_sysctl()
921 SYSCTL_CHILDREN(device_get_sysctl_tree(codec->dev)), in ac97_init_sysctl()
932 u_int32_t i, mask; in ac97mix_init() local
935 return -1; in ac97mix_init()
938 return -1; in ac97mix_init()
940 switch (codec->id) { in ac97mix_init()
942 switch (codec->subvendor) { in ac97mix_init()
951 mask = 0; in ac97mix_init()
952 if (codec->mix[SOUND_MIXER_OGAIN].enable) in ac97mix_init()
953 mask |= SOUND_MASK_OGAIN; in ac97mix_init()
954 if (codec->mix[SOUND_MIXER_PHONEOUT].enable) in ac97mix_init()
955 mask |= SOUND_MASK_PHONEOUT; in ac97mix_init()
956 if (codec->mix[SOUND_MIXER_VOLUME].enable) in ac97mix_init()
958 mask); in ac97mix_init()
961 mask); in ac97mix_init()
976 codec->mix[SOUND_MIXER_OGAIN].enable = 1; in ac97mix_init()
977 codec->mix[SOUND_MIXER_PHONEOUT].enable = 1; in ac97mix_init()
994 bzero(&codec->mix[SOUND_MIXER_PCM], in ac97mix_init()
995 sizeof(codec->mix[SOUND_MIXER_PCM])); in ac97mix_init()
996 pcm_setflags(codec->dev, pcm_getflags(codec->dev) | in ac97mix_init()
1004 if (pcm_getflags(codec->dev) & SD_F_SOFTPCMVOL) in ac97mix_init()
1014 mask = 0; in ac97mix_init()
1016 mask |= codec->mix[i].enable? 1 << i : 0; in ac97mix_init()
1017 mix_setdevs(m, mask); in ac97mix_init()
1019 mask = 0; in ac97mix_init()
1021 mask |= codec->mix[i].recidx? 1 << i : 0; in ac97mix_init()
1022 mix_setrecdevs(m, mask); in ac97mix_init()
1035 return -1; in ac97mix_uninit()
1038 return -1; in ac97mix_uninit()
1050 return -1; in ac97mix_reinit()
1060 return -1; in ac97mix_set()
1071 return -1; in ac97mix_setrecsrc()
1088 /* -------------------------------------------------------------------- */