[stage: 8/9]

Implement CHANNEL_SETFRAGMENTS() for snd_atiixp, snd_es137x, snd_hda
and snd_via8233. CHANNEL_SETBLOCKSIZE() will basically call
CHANNEL_SETFRAGMENTS() internally using conservative blocksize /
blockcount hints. Other drivers will be converted later.
This commit is contained in:
Ariff Abdullah 2007-03-16 17:18:17 +00:00
parent 7d9022b422
commit 1042342ad8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=167648
4 changed files with 229 additions and 85 deletions

View file

@ -65,11 +65,14 @@
SND_DECLARE_FILE("$FreeBSD$");
#define ATI_IXP_DMA_RETRY_MAX 100
#define ATI_IXP_DMA_RETRY_MAX 100
#define ATI_IXP_BUFSZ_MIN 4096
#define ATI_IXP_BUFSZ_MAX 65536
#define ATI_IXP_BUFSZ_DEFAULT 16384
#define ATI_IXP_BUFSZ_MIN 4096
#define ATI_IXP_BUFSZ_MAX 65536
#define ATI_IXP_BUFSZ_DEFAULT 16384
#define ATI_IXP_BLK_MIN 32
#define ATI_IXP_BLK_ALIGN (~(ATI_IXP_BLK_MIN - 1))
struct atiixp_dma_op {
volatile uint32_t addr;
@ -180,6 +183,7 @@ static void *atiixp_chan_init(kobj_t, void *, struct snd_dbuf *,
struct pcm_channel *, int);
static int atiixp_chan_setformat(kobj_t, void *, uint32_t);
static int atiixp_chan_setspeed(kobj_t, void *, uint32_t);
static int atiixp_chan_setfragments(kobj_t, void *, uint32_t, uint32_t);
static int atiixp_chan_setblocksize(kobj_t, void *, uint32_t);
static void atiixp_buildsgdt(struct atiixp_chinfo *);
static int atiixp_chan_trigger(kobj_t, void *, int);
@ -460,8 +464,8 @@ atiixp_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
atiixp_lock(sc);
num = sc->registered_channels++;
ch->sgd_table = &sc->sgd_table[num * ch->blkcnt];
ch->sgd_addr = sc->sgd_addr + (num * ch->blkcnt *
ch->sgd_table = &sc->sgd_table[num * ATI_IXP_DMA_CHSEGS_MAX];
ch->sgd_addr = sc->sgd_addr + (num * ATI_IXP_DMA_CHSEGS_MAX *
sizeof(struct atiixp_dma_op));
atiixp_disable_dma(ch);
atiixp_unlock(sc);
@ -513,22 +517,52 @@ atiixp_chan_setspeed(kobj_t obj, void *data, uint32_t spd)
return (ATI_IXP_BASE_RATE);
}
static int
atiixp_chan_setfragments(kobj_t obj, void *data,
uint32_t blksz, uint32_t blkcnt)
{
struct atiixp_chinfo *ch = data;
struct atiixp_info *sc = ch->parent;
blksz &= ATI_IXP_BLK_ALIGN;
if (blksz > (sndbuf_getmaxsize(ch->buffer) / ATI_IXP_DMA_CHSEGS_MIN))
blksz = sndbuf_getmaxsize(ch->buffer) / ATI_IXP_DMA_CHSEGS_MIN;
if (blksz < ATI_IXP_BLK_MIN)
blksz = ATI_IXP_BLK_MIN;
if (blkcnt > ATI_IXP_DMA_CHSEGS_MAX)
blkcnt = ATI_IXP_DMA_CHSEGS_MAX;
if (blkcnt < ATI_IXP_DMA_CHSEGS_MIN)
blkcnt = ATI_IXP_DMA_CHSEGS_MIN;
while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->buffer)) {
if ((blkcnt >> 1) >= ATI_IXP_DMA_CHSEGS_MIN)
blkcnt >>= 1;
else if ((blksz >> 1) >= ATI_IXP_BLK_MIN)
blksz >>= 1;
else
break;
}
if ((sndbuf_getblksz(ch->buffer) != blksz ||
sndbuf_getblkcnt(ch->buffer) != blkcnt) &&
sndbuf_resize(ch->buffer, blkcnt, blksz) != 0)
device_printf(sc->dev, "%s: failed blksz=%u blkcnt=%u\n",
__func__, blksz, blkcnt);
ch->blksz = sndbuf_getblksz(ch->buffer);
ch->blkcnt = sndbuf_getblkcnt(ch->buffer);
return (1);
}
static int
atiixp_chan_setblocksize(kobj_t obj, void *data, uint32_t blksz)
{
struct atiixp_chinfo *ch = data;
struct atiixp_info *sc = ch->parent;
if ((blksz * ch->blkcnt) > sndbuf_getmaxsize(ch->buffer))
blksz = sndbuf_getmaxsize(ch->buffer) / ch->blkcnt;
if ((sndbuf_getblksz(ch->buffer) != blksz ||
sndbuf_getblkcnt(ch->buffer) != ch->blkcnt) &&
sndbuf_resize(ch->buffer, ch->blkcnt, blksz) != 0)
device_printf(sc->dev, "%s: failed blksz=%u blkcnt=%u\n",
__func__, blksz, ch->blkcnt);
ch->blksz = sndbuf_getblksz(ch->buffer);
atiixp_chan_setfragments(obj, data, blksz, sc->blkcnt);
return (ch->blksz);
}
@ -807,6 +841,7 @@ static kobj_method_t atiixp_chan_methods[] = {
KOBJMETHOD(channel_setformat, atiixp_chan_setformat),
KOBJMETHOD(channel_setspeed, atiixp_chan_setspeed),
KOBJMETHOD(channel_setblocksize, atiixp_chan_setblocksize),
KOBJMETHOD(channel_setfragments, atiixp_chan_setfragments),
KOBJMETHOD(channel_trigger, atiixp_chan_trigger),
KOBJMETHOD(channel_getptr, atiixp_chan_getptr),
KOBJMETHOD(channel_getcaps, atiixp_chan_getcaps),
@ -1179,6 +1214,9 @@ atiixp_pci_attach(device_t dev)
*/
if (resource_int_value(device_get_name(dev),
device_get_unit(dev), "blocksize", &i) == 0 && i > 0) {
i &= ATI_IXP_BLK_ALIGN;
if (i < ATI_IXP_BLK_MIN)
i = ATI_IXP_BLK_MIN;
sc->blkcnt = sc->bufsz / i;
i = 0;
while (sc->blkcnt >> i)
@ -1212,7 +1250,7 @@ atiixp_pci_attach(device_t dev)
/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
/*highaddr*/BUS_SPACE_MAXADDR,
/*filter*/NULL, /*filterarg*/NULL,
/*maxsize*/sc->blkcnt * ATI_IXP_NCHANS *
/*maxsize*/ATI_IXP_DMA_CHSEGS_MAX * ATI_IXP_NCHANS *
sizeof(struct atiixp_dma_op),
/*nsegments*/1, /*maxsegz*/0x3ffff,
/*flags*/0, /*lockfunc*/NULL,
@ -1226,8 +1264,8 @@ atiixp_pci_attach(device_t dev)
goto bad;
if (bus_dmamap_load(sc->sgd_dmat, sc->sgd_dmamap, sc->sgd_table,
sc->blkcnt * ATI_IXP_NCHANS * sizeof(struct atiixp_dma_op),
atiixp_dma_cb, sc, 0))
ATI_IXP_DMA_CHSEGS_MAX * ATI_IXP_NCHANS *
sizeof(struct atiixp_dma_op), atiixp_dma_cb, sc, 0))
goto bad;

View file

@ -93,6 +93,11 @@ SND_DECLARE_FILE("$FreeBSD$");
#define ES_ADC 2
#define ES_NCHANS 3
#define ES_DMA_SEGS_MIN 2
#define ES_DMA_SEGS_MAX 256
#define ES_BLK_MIN 64
#define ES_BLK_ALIGN (~(ES_BLK_MIN - 1))
#define ES1370_DAC1_MINSPEED 5512
#define ES1370_DAC1_MAXSPEED 44100
@ -593,27 +598,52 @@ eschan1371_setspeed(kobj_t obj, void *data, uint32_t speed)
return (i);
}
static int
eschan_setfragments(kobj_t obj, void *data, uint32_t blksz, uint32_t blkcnt)
{
struct es_chinfo *ch = data;
struct es_info *es = ch->parent;
blksz &= ES_BLK_ALIGN;
if (blksz > (sndbuf_getmaxsize(ch->buffer) / ES_DMA_SEGS_MIN))
blksz = sndbuf_getmaxsize(ch->buffer) / ES_DMA_SEGS_MIN;
if (blksz < ES_BLK_MIN)
blksz = ES_BLK_MIN;
if (blkcnt > ES_DMA_SEGS_MAX)
blkcnt = ES_DMA_SEGS_MAX;
if (blkcnt < ES_DMA_SEGS_MIN)
blkcnt = ES_DMA_SEGS_MIN;
while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->buffer)) {
if ((blkcnt >> 1) >= ES_DMA_SEGS_MIN)
blkcnt >>= 1;
else if ((blksz >> 1) >= ES_BLK_MIN)
blksz >>= 1;
else
break;
}
if ((sndbuf_getblksz(ch->buffer) != blksz ||
sndbuf_getblkcnt(ch->buffer) != blkcnt) &&
sndbuf_resize(ch->buffer, blkcnt, blksz) != 0)
device_printf(es->dev, "%s: failed blksz=%u blkcnt=%u\n",
__func__, blksz, blkcnt);
ch->bufsz = sndbuf_getsize(ch->buffer);
ch->blksz = sndbuf_getblksz(ch->buffer);
ch->blkcnt = sndbuf_getblkcnt(ch->buffer);
return (1);
}
static int
eschan_setblocksize(kobj_t obj, void *data, uint32_t blksz)
{
struct es_chinfo *ch = data;
struct es_info *es = ch->parent;
blksz &= ~0x3f;
if (blksz < 0x40)
blksz = 0x40;
if ((blksz * ch->blkcnt) > sndbuf_getmaxsize(ch->buffer))
blksz = sndbuf_getmaxsize(ch->buffer) / ch->blkcnt;
if ((sndbuf_getblksz(ch->buffer) != blksz ||
sndbuf_getblkcnt(ch->buffer) != ch->blkcnt) &&
sndbuf_resize(ch->buffer, ch->blkcnt, blksz) != 0)
device_printf(es->dev, "%s: failed blksz=%u blkcnt=%u\n",
__func__, blksz, ch->blkcnt);
ch->bufsz = sndbuf_getsize(ch->buffer);
ch->blksz = sndbuf_getblksz(ch->buffer);
eschan_setfragments(obj, data, blksz, es->blkcnt);
return (ch->blksz);
}
@ -813,7 +843,7 @@ eschan_getptr(kobj_t obj, void *data)
}
ES_UNLOCK(es);
cnt &= ~0x3f;
cnt &= ES_BLK_ALIGN;
return (cnt);
}
@ -831,6 +861,7 @@ static kobj_method_t eschan1370_methods[] = {
KOBJMETHOD(channel_setformat, eschan_setformat),
KOBJMETHOD(channel_setspeed, eschan1370_setspeed),
KOBJMETHOD(channel_setblocksize, eschan_setblocksize),
KOBJMETHOD(channel_setfragments, eschan_setfragments),
KOBJMETHOD(channel_trigger, eschan_trigger),
KOBJMETHOD(channel_getptr, eschan_getptr),
KOBJMETHOD(channel_getcaps, eschan_getcaps),
@ -843,6 +874,7 @@ static kobj_method_t eschan1371_methods[] = {
KOBJMETHOD(channel_setformat, eschan_setformat),
KOBJMETHOD(channel_setspeed, eschan1371_setspeed),
KOBJMETHOD(channel_setblocksize, eschan_setblocksize),
KOBJMETHOD(channel_setfragments, eschan_setfragments),
KOBJMETHOD(channel_trigger, eschan_trigger),
KOBJMETHOD(channel_getptr, eschan_getptr),
KOBJMETHOD(channel_getcaps, eschan_getcaps),
@ -1049,9 +1081,10 @@ es1371_wrcd(kobj_t obj, void *s, int addr, uint32_t data)
uint32_t t, x, orig;
struct es_info *es = (struct es_info*)s;
for (t = 0; t < 0x1000; t++)
for (t = 0; t < 0x1000; t++) {
if (!es_rd(es, ES1371_REG_CODEC & CODEC_WIP, 4))
break;
}
/* save the current state for later */
x = orig = es_rd(es, ES1371_REG_SMPRATE, 4);
/* enable SRC state data in SRC mux */
@ -1571,10 +1604,10 @@ es_init_sysctls(device_t dev)
revid = pci_get_revid(dev);
es = pcm_getdevinfo(dev);
if ((devid == ES1371_PCI_ID && revid == ES1371REV_ES1373_8) ||
(devid == ES1371_PCI_ID && revid == ES1371REV_CT5880_A) ||
(devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_C) ||
(devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_D) ||
(devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_E)) {
(devid == ES1371_PCI_ID && revid == ES1371REV_CT5880_A) ||
(devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_C) ||
(devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_D) ||
(devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_E)) {
/* XXX: an user should be able to set this with a control tool,
if not done before 7.0-RELEASE, this needs to be converted
to a device specific sysctl "dev.pcm.X.yyy" via
@ -1699,18 +1732,18 @@ es_pci_attach(device_t dev)
es->bufsz = pcm_getbuffersize(dev, 4096, ES_DEFAULT_BUFSZ, 65536);
if (resource_int_value(device_get_name(dev),
device_get_unit(dev), "blocksize", &i) == 0 && i > 0) {
i &= ~0x3f;
if (i < 0x40)
i = 0x40;
i &= ES_BLK_ALIGN;
if (i < ES_BLK_MIN)
i = ES_BLK_MIN;
es->blkcnt = es->bufsz / i;
i = 0;
while (es->blkcnt >> i)
i++;
es->blkcnt = 1 << (i - 1);
if (es->blkcnt < 2)
es->blkcnt = 2;
else if (es->blkcnt > 256)
es->blkcnt = 256;
if (es->blkcnt < ES_DMA_SEGS_MIN)
es->blkcnt = ES_DMA_SEGS_MIN;
else if (es->blkcnt > ES_DMA_SEGS_MAX)
es->blkcnt = ES_DMA_SEGS_MAX;
} else
es->blkcnt = 2;

View file

@ -80,7 +80,7 @@
#include "mixer_if.h"
#define HDA_DRV_TEST_REV "20070316_0041"
#define HDA_DRV_TEST_REV "20070317_0042"
#define HDA_WIDGET_PARSER_REV 1
SND_DECLARE_FILE("$FreeBSD$");
@ -201,6 +201,7 @@ SND_DECLARE_FILE("$FreeBSD$");
#define ASUS_P1AH2_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x81cb)
#define ASUS_A7M_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x1323)
#define ASUS_A7T_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x13c2)
#define ASUS_W6F_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x1263)
#define ASUS_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0xffff)
/* IBM / Lenovo */
@ -301,6 +302,9 @@ static const struct {
#define HDA_BDL_MAX 256
#define HDA_BDL_DEFAULT HDA_BDL_MIN
#define HDA_BLK_MIN 128
#define HDA_BLK_ALIGN (~(HDA_BLK_MIN - 1))
#define HDA_BUFSZ_MIN 4096
#define HDA_BUFSZ_MAX 65536
#define HDA_BUFSZ_DEFAULT 16384
@ -2763,26 +2767,52 @@ hdac_stream_setup(struct hdac_chan *ch)
}
}
static int
hdac_channel_setfragments(kobj_t obj, void *data,
uint32_t blksz, uint32_t blkcnt)
{
struct hdac_chan *ch = data;
struct hdac_softc *sc = ch->devinfo->codec->sc;
blksz &= HDA_BLK_ALIGN;
if (blksz > (sndbuf_getmaxsize(ch->b) / HDA_BDL_MIN))
blksz = sndbuf_getmaxsize(ch->b) / HDA_BDL_MIN;
if (blksz < HDA_BLK_MIN)
blksz = HDA_BLK_MIN;
if (blkcnt > HDA_BDL_MAX)
blkcnt = HDA_BDL_MAX;
if (blkcnt < HDA_BDL_MIN)
blkcnt = HDA_BDL_MIN;
while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->b)) {
if ((blkcnt >> 1) >= HDA_BDL_MIN)
blkcnt >>= 1;
else if ((blksz >> 1) >= HDA_BLK_MIN)
blksz >>= 1;
else
break;
}
if ((sndbuf_getblksz(ch->b) != blksz ||
sndbuf_getblkcnt(ch->b) != blkcnt) &&
sndbuf_resize(ch->b, blkcnt, blksz) != 0)
device_printf(sc->dev, "%s: failed blksz=%u blkcnt=%u\n",
__func__, blksz, blkcnt);
ch->blksz = sndbuf_getblksz(ch->b);
ch->blkcnt = sndbuf_getblkcnt(ch->b);
return (1);
}
static int
hdac_channel_setblocksize(kobj_t obj, void *data, uint32_t blksz)
{
struct hdac_chan *ch = data;
struct hdac_softc *sc = ch->devinfo->codec->sc;
blksz &= ~0x7f;
if (blksz < 0x80)
blksz = 0x80;
if ((blksz * ch->blkcnt) > sndbuf_getmaxsize(ch->b))
blksz = sndbuf_getmaxsize(ch->b) / ch->blkcnt;
if ((sndbuf_getblksz(ch->b) != blksz ||
sndbuf_getblkcnt(ch->b) != ch->blkcnt) &&
sndbuf_resize(ch->b, ch->blkcnt, blksz) != 0)
device_printf(sc->dev, "%s: failed blksz=%u blkcnt=%u\n",
__func__, blksz, ch->blkcnt);
ch->blksz = sndbuf_getblksz(ch->b);
hdac_channel_setfragments(obj, data, blksz, sc->chan_blkcnt);
return (ch->blksz);
}
@ -2857,7 +2887,7 @@ hdac_channel_getptr(kobj_t obj, void *data)
* Round to available space and force 128 bytes aligment.
*/
ptr %= ch->blksz * ch->blkcnt;
ptr &= ~0x7f;
ptr &= HDA_BLK_ALIGN;
return (ptr);
}
@ -2873,6 +2903,7 @@ static kobj_method_t hdac_channel_methods[] = {
KOBJMETHOD(channel_setformat, hdac_channel_setformat),
KOBJMETHOD(channel_setspeed, hdac_channel_setspeed),
KOBJMETHOD(channel_setblocksize, hdac_channel_setblocksize),
KOBJMETHOD(channel_setfragments, hdac_channel_setfragments),
KOBJMETHOD(channel_trigger, hdac_channel_trigger),
KOBJMETHOD(channel_getptr, hdac_channel_getptr),
KOBJMETHOD(channel_getcaps, hdac_channel_getcaps),
@ -3259,9 +3290,9 @@ hdac_attach(device_t dev)
if (resource_int_value(device_get_name(sc->dev),
device_get_unit(sc->dev), "blocksize", &i) == 0 && i > 0) {
i &= ~0x7f;
if (i < 0x80)
i = 0x80;
i &= HDA_BLK_ALIGN;
if (i < HDA_BLK_MIN)
i = HDA_BLK_MIN;
sc->chan_blkcnt = sc->chan_size / i;
i = 0;
while (sc->chan_blkcnt >> i)

View file

@ -65,6 +65,8 @@ SND_DECLARE_FILE("$FreeBSD$");
#define VIA_SEGS_MIN 2
#define VIA_SEGS_MAX 64
#define VIA_SEGS_DEFAULT 2
#define VIA_BLK_MIN 32
#define VIA_BLK_ALIGN (~(VIA_BLK_MIN - 1))
#define VIA_DEFAULT_BUFSZ 0x1000
@ -92,6 +94,8 @@ struct via_chinfo {
};
struct via_info {
device_t dev;
bus_space_tag_t st;
bus_space_handle_t sh;
bus_dma_tag_t parent_dmat;
@ -312,7 +316,7 @@ via_waitready_codec(struct via_info *via)
return (0);
DELAY(1);
}
printf("via: codec busy\n");
device_printf(via->dev, "%s: codec busy\n", __func__);
return (1);
}
@ -327,7 +331,7 @@ via_waitvalid_codec(struct via_info *via)
return (0);
DELAY(1);
}
printf("via: codec invalid\n");
device_printf(via->dev, "%s: codec invalid\n", __func__);
return (1);
}
@ -555,21 +559,52 @@ via8233msgd_getcaps(kobj_t obj, void *data)
/* -------------------------------------------------------------------- */
/* Common functions */
static int
via8233chan_setfragments(kobj_t obj, void *data,
uint32_t blksz, uint32_t blkcnt)
{
struct via_chinfo *ch = data;
struct via_info *via = ch->parent;
blksz &= VIA_BLK_ALIGN;
if (blksz > (sndbuf_getmaxsize(ch->buffer) / VIA_SEGS_MIN))
blksz = sndbuf_getmaxsize(ch->buffer) / VIA_SEGS_MIN;
if (blksz < VIA_BLK_MIN)
blksz = VIA_BLK_MIN;
if (blkcnt > VIA_SEGS_MAX)
blkcnt = VIA_SEGS_MAX;
if (blkcnt < VIA_SEGS_MIN)
blkcnt = VIA_SEGS_MIN;
while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->buffer)) {
if ((blkcnt >> 1) >= VIA_SEGS_MIN)
blkcnt >>= 1;
else if ((blksz >> 1) >= VIA_BLK_MIN)
blksz >>= 1;
else
break;
}
if ((sndbuf_getblksz(ch->buffer) != blksz ||
sndbuf_getblkcnt(ch->buffer) != blkcnt) &&
sndbuf_resize(ch->buffer, blkcnt, blksz) != 0)
device_printf(via->dev, "%s: failed blksz=%u blkcnt=%u\n",
__func__, blksz, blkcnt);
ch->blksz = sndbuf_getblksz(ch->buffer);
ch->blkcnt = sndbuf_getblkcnt(ch->buffer);
return (1);
}
static int
via8233chan_setblocksize(kobj_t obj, void *data, uint32_t blksz)
{
struct via_chinfo *ch = data;
struct via_info *via = ch->parent;
if ((blksz * ch->blkcnt) > sndbuf_getmaxsize(ch->buffer))
blksz = sndbuf_getmaxsize(ch->buffer) / ch->blkcnt;
if ((sndbuf_getblksz(ch->buffer) != blksz ||
sndbuf_getblkcnt(ch->buffer) != ch->blkcnt) &&
sndbuf_resize(ch->buffer, ch->blkcnt, blksz) != 0)
printf("via: %s: failed blksz=%u blkcnt=%u\n",
__func__, blksz, ch->blkcnt);
ch->blksz = sndbuf_getblksz(ch->buffer);
via8233chan_setfragments(obj, data, blksz, via->blkcnt);
return (ch->blksz);
}
@ -613,8 +648,8 @@ via8233chan_reset(struct via_info *via, struct via_chinfo *ch)
static void
via8233chan_sgdinit(struct via_info *via, struct via_chinfo *ch, int chnum)
{
ch->sgd_table = &via->sgd_table[chnum * via->blkcnt];
ch->sgd_addr = via->sgd_addr + chnum * via->blkcnt *
ch->sgd_table = &via->sgd_table[chnum * VIA_SEGS_MAX];
ch->sgd_addr = via->sgd_addr + chnum * VIA_SEGS_MAX *
sizeof(struct via_dma_op);
}
@ -716,10 +751,10 @@ via8233chan_mute(struct via_info *via, struct via_chinfo *ch, int muted)
via_wr(via, ch->rbase + VIA8233_RP_DXS_RVOL, muted, 1);
r = via_rd(via, ch->rbase + VIA8233_RP_DXS_LVOL, 1) &
VIA8233_DXS_MUTE;
if (r != muted) {
printf("via: failed to set dxs volume "
"(dxs base 0x%02x).\n", ch->rbase);
}
if (r != muted)
device_printf(via->dev,
"%s: failed to set dxs volume "
"(dxs base 0x%02x).\n", __func__, ch->rbase);
}
}
@ -922,6 +957,7 @@ static kobj_method_t via8233wr_methods[] = {
KOBJMETHOD(channel_setspeed, via8233wr_setspeed),
KOBJMETHOD(channel_getcaps, via8233wr_getcaps),
KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize),
KOBJMETHOD(channel_setfragments, via8233chan_setfragments),
KOBJMETHOD(channel_trigger, via8233chan_trigger),
KOBJMETHOD(channel_getptr, via8233chan_getptr),
{ 0, 0 }
@ -934,6 +970,7 @@ static kobj_method_t via8233dxs_methods[] = {
KOBJMETHOD(channel_setspeed, via8233dxs_setspeed),
KOBJMETHOD(channel_getcaps, via8233dxs_getcaps),
KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize),
KOBJMETHOD(channel_setfragments, via8233chan_setfragments),
KOBJMETHOD(channel_trigger, via8233chan_trigger),
KOBJMETHOD(channel_getptr, via8233chan_getptr),
{ 0, 0 }
@ -946,6 +983,7 @@ static kobj_method_t via8233msgd_methods[] = {
KOBJMETHOD(channel_setspeed, via8233msgd_setspeed),
KOBJMETHOD(channel_getcaps, via8233msgd_getcaps),
KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize),
KOBJMETHOD(channel_setfragments, via8233chan_setfragments),
KOBJMETHOD(channel_trigger, via8233chan_trigger),
KOBJMETHOD(channel_getptr, via8233chan_getptr),
{ 0, 0 }
@ -1125,6 +1163,7 @@ via_attach(device_t dev)
}
via->lock = snd_mtxcreate(device_get_nameunit(dev),
"snd_via8233 softc");
via->dev = dev;
callout_init(&via->poll_timer, CALLOUT_MPSAFE);
via->poll_ticks = 1;
@ -1161,6 +1200,9 @@ via_attach(device_t dev)
via->bufsz = pcm_getbuffersize(dev, 4096, VIA_DEFAULT_BUFSZ, 65536);
if (resource_int_value(device_get_name(dev),
device_get_unit(dev), "blocksize", &i) == 0 && i > 0) {
i &= VIA_BLK_ALIGN;
if (i < VIA_BLK_MIN)
i = VIA_BLK_MIN;
via->blkcnt = via->bufsz / i;
i = 0;
while (via->blkcnt >> i)
@ -1235,7 +1277,7 @@ via_attach(device_t dev)
else
via->dxs_src = 0;
nsegs = (via_dxs_chnum + via_sgd_chnum + NWRCHANS) * via->blkcnt;
nsegs = (via_dxs_chnum + via_sgd_chnum + NWRCHANS) * VIA_SEGS_MAX;
/* DMA tag for buffers */
if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2,