summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/sound/pci/atiixp.c68
-rw-r--r--sys/dev/sound/pci/es137x.c79
-rw-r--r--sys/dev/sound/pci/hda/hdac.c61
-rw-r--r--sys/dev/sound/pci/via8233.c74
4 files changed, 213 insertions, 69 deletions
diff --git a/sys/dev/sound/pci/atiixp.c b/sys/dev/sound/pci/atiixp.c
index d3e988a..46cca88 100644
--- a/sys/dev/sound/pci/atiixp.c
+++ b/sys/dev/sound/pci/atiixp.c
@@ -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);
@@ -514,21 +518,51 @@ atiixp_chan_setspeed(kobj_t obj, void *data, uint32_t spd)
}
static int
-atiixp_chan_setblocksize(kobj_t obj, void *data, uint32_t blksz)
+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;
- if ((blksz * ch->blkcnt) > sndbuf_getmaxsize(ch->buffer))
- blksz = sndbuf_getmaxsize(ch->buffer) / ch->blkcnt;
+ 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) != ch->blkcnt) &&
- sndbuf_resize(ch->buffer, ch->blkcnt, blksz) != 0)
+ 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, ch->blkcnt);
+ __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;
+
+ 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;
diff --git a/sys/dev/sound/pci/es137x.c b/sys/dev/sound/pci/es137x.c
index 261e9b7..5bd90da 100644
--- a/sys/dev/sound/pci/es137x.c
+++ b/sys/dev/sound/pci/es137x.c
@@ -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
@@ -594,26 +599,51 @@ eschan1371_setspeed(kobj_t obj, void *data, uint32_t speed)
}
static int
-eschan_setblocksize(kobj_t obj, void *data, uint32_t blksz)
+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 &= ~0x3f;
- if (blksz < 0x40)
- blksz = 0x40;
-
- if ((blksz * ch->blkcnt) > sndbuf_getmaxsize(ch->buffer))
- blksz = sndbuf_getmaxsize(ch->buffer) / ch->blkcnt;
+ 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) != ch->blkcnt) &&
- sndbuf_resize(ch->buffer, ch->blkcnt, blksz) != 0)
+ 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, ch->blkcnt);
+ __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;
+
+ 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;
diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c
index 1158eec..ad0c256 100644
--- a/sys/dev/sound/pci/hda/hdac.c
+++ b/sys/dev/sound/pci/hda/hdac.c
@@ -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
@@ -2764,25 +2768,51 @@ hdac_stream_setup(struct hdac_chan *ch)
}
static int
-hdac_channel_setblocksize(kobj_t obj, void *data, uint32_t blksz)
+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 &= ~0x7f;
- if (blksz < 0x80)
- blksz = 0x80;
-
- if ((blksz * ch->blkcnt) > sndbuf_getmaxsize(ch->b))
- blksz = sndbuf_getmaxsize(ch->b) / ch->blkcnt;
+ 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) != ch->blkcnt) &&
- sndbuf_resize(ch->b, ch->blkcnt, blksz) != 0)
+ 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, ch->blkcnt);
+ __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;
+
+ 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)
diff --git a/sys/dev/sound/pci/via8233.c b/sys/dev/sound/pci/via8233.c
index eca8d11..2e0df87 100644
--- a/sys/dev/sound/pci/via8233.c
+++ b/sys/dev/sound/pci/via8233.c
@@ -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);
}
@@ -556,20 +560,51 @@ via8233msgd_getcaps(kobj_t obj, void *data)
/* Common functions */
static int
-via8233chan_setblocksize(kobj_t obj, void *data, uint32_t blksz)
+via8233chan_setfragments(kobj_t obj, void *data,
+ uint32_t blksz, uint32_t blkcnt)
{
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;
+ 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) != ch->blkcnt) &&
- sndbuf_resize(ch->buffer, ch->blkcnt, blksz) != 0)
- printf("via: %s: failed blksz=%u blkcnt=%u\n",
- __func__, blksz, ch->blkcnt);
+ 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;
+
+ 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,
OpenPOWER on IntegriCloud