Index: src/sys/dev/sound/pci/atiixp.c =================================================================== RCS file: /home/ncvs/src/sys/dev/sound/pci/atiixp.c,v retrieving revision 1.2.2.2 diff -u -r1.2.2.2 atiixp.c --- src/sys/dev/sound/pci/atiixp.c 29 Jan 2006 02:33:17 -0000 1.2.2.2 +++ src/sys/dev/sound/pci/atiixp.c 1 Mar 2006 23:31:39 -0000 @@ -30,12 +30,14 @@ * Features * * 16bit playback / recording * * 32bit native playback - yay! + * * 32bit native recording (seems broken on few hardwares) * * Issues / TODO: * * SPDIF * * Support for more than 2 channels. * * VRA ? VRM ? DRA ? - * * 32bit native recording (seems broken, disabled) + * * 32bit native recording seems broken on few hardwares, most + * probably because of incomplete VRA/DRA cleanup. * * * Thanks goes to: @@ -65,10 +67,10 @@ struct atiixp_dma_op { - uint32_t addr; - uint16_t status; - uint16_t size; - uint32_t next; + volatile uint32_t addr; + volatile uint16_t status; + volatile uint16_t size; + volatile uint32_t next; }; struct atiixp_info; @@ -468,8 +470,7 @@ if (ch->dir == PCMDIR_REC) { value = atiixp_rd(sc, ATI_REG_CMD); value &= ~ATI_REG_CMD_INTERLEAVE_IN; - if (ch->caps_32bit == 0 || - (format & (AFMT_8BIT|AFMT_16BIT)) != 0) + if ((format & AFMT_32BIT) == 0) value |= ATI_REG_CMD_INTERLEAVE_IN; atiixp_wr(sc, ATI_REG_CMD, value); } else { @@ -482,8 +483,7 @@ atiixp_wr(sc, ATI_REG_OUT_DMA_SLOT, value); value = atiixp_rd(sc, ATI_REG_CMD); value &= ~ATI_REG_CMD_INTERLEAVE_OUT; - if (ch->caps_32bit == 0 || - (format & (AFMT_8BIT|AFMT_16BIT)) != 0) + if ((format & AFMT_32BIT) == 0) value |= ATI_REG_CMD_INTERLEAVE_OUT; atiixp_wr(sc, ATI_REG_CMD, value); value = atiixp_rd(sc, ATI_REG_6CH_REORDER); @@ -585,13 +585,36 @@ { struct atiixp_chinfo *ch = data; struct atiixp_info *sc = ch->parent; - uint32_t ptr; + uint32_t addr, align, retry, sz; + volatile uint32_t ptr; + + addr = sndbuf_getbufaddr(ch->buffer); + align = (ch->fmt & AFMT_32BIT) ? 7 : 3; + retry = 100; + sz = sndbuf_getblksz(ch->buffer) * ch->dma_segs; atiixp_lock(sc); - ptr = atiixp_rd(sc, ch->dma_dt_cur_bit); + do { + ptr = atiixp_rd(sc, ch->dma_dt_cur_bit); + if (ptr < addr) + continue; + ptr -= addr; + if (ptr < sz && !(ptr & align)) + break; + } while (--retry); atiixp_unlock(sc); - return ptr; +#if 0 + if (retry != 100) { + device_printf(sc->dev, + "%saligned hwptr: dir=PCMDIR_%s ptr=%u fmt=0x%08x retry=%d\n", + (ptr & align) ? "un" : "", + (ch->dir == PCMDIR_PLAY) ? "PLAY" : "REC", ptr, + ch->fmt, 100 - retry); + } +#endif + + return (retry > 0) ? ptr : 0; } static struct pcmchan_caps * @@ -709,6 +732,7 @@ atiixp_chip_post_init(void *arg) { struct atiixp_info *sc = (struct atiixp_info *)arg; + uint32_t subdev; int i, timeout, found; char status[SND_STATUSLEN]; @@ -776,6 +800,15 @@ if (sc->codec == NULL) goto postinitbad; + subdev = (pci_get_subdevice(sc->dev) << 16) | pci_get_subvendor(sc->dev); + switch (subdev) { + case 0x2043161f: /* Maxselect x710s - http://maxselect.ru/ */ + ac97_setflags(sc->codec, ac97_getflags(sc->codec) | AC97_F_EAPD_INV); + break; + default: + break; + } + mixer_init(sc->dev, ac97_getmixerclass(), sc->codec); if (pcm_register(sc->dev, sc, ATI_IXP_NPCHAN, ATI_IXP_NRCHAN)) @@ -893,14 +926,25 @@ i = ATI_IXP_DMA_CHSEGS_MIN; if (i > ATI_IXP_DMA_CHSEGS_MAX) i = ATI_IXP_DMA_CHSEGS_MAX; - /* round the value */ - sc->dma_segs = i & ~1; + sc->dma_segs = i; } /* + * round the value to the nearest ^2 + */ + i = 0; + while (sc->dma_segs >> i) + i++; + sc->dma_segs = 1 << (i - 1); + if (sc->dma_segs < ATI_IXP_DMA_CHSEGS_MIN) + sc->dma_segs = ATI_IXP_DMA_CHSEGS_MIN; + else if (sc->dma_segs > ATI_IXP_DMA_CHSEGS_MAX) + sc->dma_segs = ATI_IXP_DMA_CHSEGS_MAX; + + /* * DMA tag for scatter-gather buffers and link pointers */ - if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, + if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/sc->bufsz, /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, Index: src/sys/dev/sound/pci/atiixp.h =================================================================== RCS file: /home/ncvs/src/sys/dev/sound/pci/atiixp.h,v retrieving revision 1.1.2.1 diff -u -r1.1.2.1 atiixp.h --- src/sys/dev/sound/pci/atiixp.h 30 Dec 2005 19:55:53 -0000 1.1.2.1 +++ src/sys/dev/sound/pci/atiixp.h 1 Mar 2006 23:31:39 -0000 @@ -46,7 +46,7 @@ #define ATI_IXP_DMA_CHSEGS_MIN 2 #define ATI_IXP_DMA_CHSEGS_MAX 256 -#define ATI_IXP_DEFAULT_BUFSZ (1 << 12) /* 4096 */ +#define ATI_IXP_DEFAULT_BUFSZ (1 << 13) /* 8192 */ #define ATI_VENDOR_ID 0x1002 /* ATI Technologies */ #define ATI_IXP_200_ID 0x4341 Index: src/sys/dev/sound/pci/ich.c =================================================================== RCS file: /home/ncvs/src/sys/dev/sound/pci/ich.c,v retrieving revision 1.53.2.3 diff -u -r1.53.2.3 ich.c --- src/sys/dev/sound/pci/ich.c 17 Jan 2006 05:13:37 -0000 1.53.2.3 +++ src/sys/dev/sound/pci/ich.c 1 Mar 2006 23:31:40 -0000 @@ -677,7 +677,6 @@ ich_init(struct sc_info *sc) { u_int32_t stat; - int sz; ich_wr(sc, ICH_REG_GLOB_CNT, ICH_GLOB_CTL_COLD, 4); DELAY(600000); @@ -701,15 +700,6 @@ if (sc->hasmic && ich_resetchan(sc, 2)) return ENXIO; - if (bus_dmamem_alloc(sc->dmat, (void **)&sc->dtbl, BUS_DMA_NOWAIT, &sc->dtmap)) - return ENOSPC; - - sz = sizeof(struct ich_desc) * ICH_DTBL_LENGTH * 3; - if (bus_dmamap_load(sc->dmat, sc->dtmap, sc->dtbl, sz, ich_setmap, sc, 0)) { - bus_dmamem_free(sc->dmat, (void **)&sc->dtbl, sc->dtmap); - return ENOSPC; - } - return 0; } @@ -828,6 +818,15 @@ goto bad; } + if (bus_dmamem_alloc(sc->dmat, (void **)&sc->dtbl, + BUS_DMA_NOWAIT, &sc->dtmap)) + goto bad; + + if (bus_dmamap_load(sc->dmat, sc->dtmap, sc->dtbl, + sizeof(struct ich_desc) * ICH_DTBL_LENGTH * 3, + ich_setmap, sc, 0)) + goto bad; + sc->codec = AC97_CREATE(dev, sc, ich_ac97); if (sc->codec == NULL) goto bad; @@ -895,6 +894,10 @@ if (sc->nabmbar) bus_release_resource(dev, sc->regtype, sc->nabmbarid, sc->nabmbar); + if (sc->dtmap) + bus_dmamap_unload(sc->dmat, sc->dtmap); + if (sc->dmat) + bus_dma_tag_destroy(sc->dmat); if (sc->ich_lock) snd_mtxfree(sc->ich_lock); free(sc, M_DEVBUF); @@ -916,6 +919,7 @@ bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); bus_release_resource(dev, sc->regtype, sc->nambarid, sc->nambar); bus_release_resource(dev, sc->regtype, sc->nabmbarid, sc->nabmbar); + bus_dmamap_unload(sc->dmat, sc->dtmap); bus_dma_tag_destroy(sc->dmat); snd_mtxfree(sc->ich_lock); free(sc, M_DEVBUF); @@ -987,24 +991,21 @@ } /* Reinit mixer */ ich_pci_codec_reset(sc); + ICH_UNLOCK(sc); ac97_setextmode(sc->codec, sc->hasvra | sc->hasvrm); if (mixer_reinit(dev) == -1) { device_printf(dev, "unable to reinitialize the mixer\n"); - ICH_UNLOCK(sc); return ENXIO; } /* Re-start DMA engines */ for (i = 0 ; i < 3; i++) { struct sc_chinfo *ch = &sc->ch[i]; if (sc->ch[i].run_save) { - ICH_UNLOCK(sc); ichchan_setblocksize(0, ch, ch->blksz); ichchan_setspeed(0, ch, ch->spd); ichchan_trigger(0, ch, PCMTRIG_START); - ICH_LOCK(sc); } } - ICH_UNLOCK(sc); return 0; }