40#ifdef HAVE_KERNEL_OPTION_HEADERS
49#include <sys/sysctl.h>
55#define VIA8233_PCI_ID 0x30591106
57#define VIA8233_REV_ID_8233PRE 0x10
58#define VIA8233_REV_ID_8233C 0x20
59#define VIA8233_REV_ID_8233 0x30
60#define VIA8233_REV_ID_8233A 0x40
61#define VIA8233_REV_ID_8235 0x50
62#define VIA8233_REV_ID_8237 0x60
63#define VIA8233_REV_ID_8251 0x70
65#define SEGS_PER_CHAN 2
69#define NCHANS (NWRCHANS + NDXSCHANS + NMSGDCHANS)
70#define NSEGS NCHANS * SEGS_PER_CHAN
72#define VIA_SEGS_MAX 64
73#define VIA_SEGS_DEFAULT 2
75#define VIA_BLK_ALIGN (~(VIA_BLK_MIN - 1))
77#define VIA_DEFAULT_BUFSZ 0x1000
81 volatile uint32_t
ptr;
83#define VIA_DMAOP_EOL 0x80000000
84#define VIA_DMAOP_FLAG 0x40000000
85#define VIA_DMAOP_STOP 0x20000000
86#define VIA_DMAOP_COUNT(x) ((x)&0x00FFFFFF)
106 bus_space_handle_t
sh;
167 dev = oidp->oid_arg1;
173 err = sysctl_handle_int(oidp, &new_en, 0,
req);
175 if (err ||
req->newptr == NULL)
177 if (new_en < 0 || new_en > 1)
198 dev = oidp->oid_arg1;
203 err = sysctl_handle_int(oidp, &
val, 0,
req);
205 if (err ||
req->newptr == NULL)
207 if (val < 0 || val > 1)
224 dev = oidp->oid_arg1;
231 err = sysctl_handle_int(oidp, &
val, 0,
req);
233 if (err ||
req->newptr == NULL)
235 if (val < 0 || val > 1)
259 SYSCTL_ADD_PROC(device_get_sysctl_ctx(
dev),
260 SYSCTL_CHILDREN(device_get_sysctl_tree(
dev)), OID_AUTO,
261 "spdif_enabled", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
263 "Enable S/PDIF output on primary playback channel");
264 SYSCTL_ADD_PROC(device_get_sysctl_ctx(
dev),
265 SYSCTL_CHILDREN(device_get_sysctl_tree(
dev)), OID_AUTO,
266 "dxs_src", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
268 "Enable VIA DXS Sample Rate Converter");
269 SYSCTL_ADD_PROC(device_get_sysctl_ctx(
dev),
270 SYSCTL_CHILDREN(device_get_sysctl_tree(
dev)), OID_AUTO,
271 "polling", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
275static __inline uint32_t
280 return (bus_space_read_1(via->
st, via->
sh,
regno));
282 return (bus_space_read_2(via->
st, via->
sh,
regno));
284 return (bus_space_read_4(via->
st, via->
sh,
regno));
316 for (i = 0; i < 1000; i++) {
321 device_printf(via->
dev,
"%s: codec busy\n", __func__);
331 for (i = 0; i < 1000; i++) {
336 device_printf(via->
dev,
"%s: codec invalid\n", __func__);
387 uint32_t phys_addr, flag;
392 for (i = 0; i < ch->
blkcnt; i++) {
451 uint32_t s = 0xff000000;
494 v =
via_rd(via,
r, 4) & ~VIA8233_DXS_RATEFMT_48K;
594 device_printf(via->
dev,
"%s: failed blksz=%u blkcnt=%u\n",
629 count = v & 0x00ffffff;
766 device_printf(via->
dev,
767 "%s: failed to set dxs volume "
768 "(dxs base 0x%02x).\n", __func__, ch->
rbase);
787 count = v & 0x00ffffff;
790 ptr &= ~(ch->
blksz - 1);
792 delta = (sz + ptr - ch->
prevptr) % sz;
794 if (delta < ch->
blksz)
806 uint32_t ptrigger = 0, rtrigger = 0;
833 if (ptrigger & (1 << i))
837 if (rtrigger & (1 << i))
854 pollticks = ((uint64_t)hz * ch->
blksz) /
870 pollticks = ((uint64_t)hz * ch->
blksz) /
904 pollticks = ((uint64_t)hz * ch->
blksz) /
916 printf(
"%s: pollticks=%d\n",
917 __func__, pollticks);
920 "pollticks %d -> %d\n",
949 printf(
"%s: pollticks "
1013 uint32_t ptrigger = 0, rtrigger = 0;
1056 if (ptrigger & (1 << i))
1060 if (rtrigger & (1 << i))
1071 switch(pci_get_devid(
dev)) {
1073 switch(pci_get_revid(
dev)) {
1075 device_set_desc(
dev,
"VIA VT8233 (pre)");
1076 return (BUS_PROBE_DEFAULT);
1078 device_set_desc(
dev,
"VIA VT8233C");
1079 return (BUS_PROBE_DEFAULT);
1081 device_set_desc(
dev,
"VIA VT8233");
1082 return (BUS_PROBE_DEFAULT);
1084 device_set_desc(
dev,
"VIA VT8233A");
1085 return (BUS_PROBE_DEFAULT);
1087 device_set_desc(
dev,
"VIA VT8235");
1088 return (BUS_PROBE_DEFAULT);
1090 device_set_desc(
dev,
"VIA VT8237");
1091 return (BUS_PROBE_DEFAULT);
1093 device_set_desc(
dev,
"VIA VT8251");
1094 return (BUS_PROBE_DEFAULT);
1096 device_set_desc(
dev,
"VIA VT8233X");
1097 return (BUS_PROBE_DEFAULT);
1104dma_cb(
void *p, bus_dma_segment_t *bds,
int a,
int b)
1155 for (cnt = 0; cnt < 2000; cnt++) {
1161 device_printf(
dev,
"primary codec not ready (cnt = 0x%02x)\n", cnt);
1170 int i, via_dxs_disabled, via_dxs_src, via_dxs_chnum, via_sgd_chnum;
1174 via = malloc(
sizeof *via, M_DEVBUF, M_WAITOK | M_ZERO);
1176 "snd_via8233 softc");
1182 if (resource_int_value(device_get_name(
dev),
1183 device_get_unit(
dev),
"polling", &i) == 0 && i != 0)
1188 pci_set_powerstate(
dev, PCI_POWERSTATE_D0);
1189 pci_enable_busmaster(
dev);
1192 via->
reg = bus_alloc_resource_any(
dev, SYS_RES_IOPORT, &via->
regid,
1195 device_printf(
dev,
"cannot allocate bus resource.");
1198 via->
st = rman_get_bustag(via->
reg);
1199 via->
sh = rman_get_bushandle(via->
reg);
1202 via->
irq = bus_alloc_resource_any(
dev, SYS_RES_IRQ, &via->
irqid,
1203 RF_ACTIVE | RF_SHAREABLE);
1207 device_printf(
dev,
"unable to map interrupt\n");
1212 if (resource_int_value(device_get_name(
dev),
1213 device_get_unit(
dev),
"blocksize", &i) == 0 && i > 0) {
1221 via->
blkcnt = 1 << (i - 1);
1251 via_dxs_disabled = 1;
1252 }
else if (resource_int_value(device_get_name(
dev),
1253 device_get_unit(
dev),
"via_dxs_disabled",
1254 &via_dxs_disabled) == 0)
1255 via_dxs_disabled = (via_dxs_disabled > 0) ? 1 : 0;
1257 via_dxs_disabled = 0;
1259 if (via_dxs_disabled) {
1263 if (resource_int_value(device_get_name(
dev),
1264 device_get_unit(
dev),
"via_dxs_channels",
1265 &via_dxs_chnum) != 0)
1267 if (resource_int_value(device_get_name(
dev),
1268 device_get_unit(
dev),
"via_sgd_channels",
1269 &via_sgd_chnum) != 0)
1274 else if (via_dxs_chnum < 0)
1278 else if (via_sgd_chnum < 0)
1280 if (via_dxs_chnum + via_sgd_chnum < 1) {
1285 if (via_dxs_chnum > 0 && resource_int_value(device_get_name(
dev),
1286 device_get_unit(
dev),
"via_dxs_src", &via_dxs_src) == 0)
1287 via->
dxs_src = (via_dxs_src > 0) ? 1 : 0;
1294 if (bus_dma_tag_create(bus_get_dma_tag(
dev), 2,
1296 BUS_SPACE_MAXADDR_32BIT,
1299 via->
bufsz, 1, 0x3ffff,
1302 device_printf(
dev,
"unable to create dma tag\n");
1311 if (bus_dma_tag_create(bus_get_dma_tag(
dev), 2,
1313 BUS_SPACE_MAXADDR_32BIT,
1320 device_printf(
dev,
"unable to create dma tag\n");
1348 ext &= ~AC97_EXTCAP_DRA;
1353 rman_get_start(via->
reg), rman_get_start(via->
irq),
1359 for (i = 0; i < via_dxs_chnum; i++)
1361 for (i = 0; i < via_sgd_chnum; i++)
1365 if (via_dxs_chnum > 0)
1367 device_printf(
dev,
"<VIA DXS %sabled: DXS%s %d / SGD %d / REC %d>\n",
1368 (via_dxs_chnum > 0) ?
"En" :
"Dis", (via->
dxs_src) ?
"(SRC)" :
"",
1369 via_dxs_chnum, via_sgd_chnum,
NWRCHANS);
1378 bus_release_resource(
dev, SYS_RES_IOPORT, via->
regid, via->
reg);
1380 bus_teardown_intr(
dev, via->
irq, via->
ih);
1382 bus_release_resource(
dev, SYS_RES_IRQ, via->
irqid, via->
irq);
1390 bus_dma_tag_destroy(via->
sgd_dmat);
1394 free(via, M_DEVBUF);
1418 bus_release_resource(
dev, SYS_RES_IOPORT, via->
regid, via->
reg);
1419 bus_teardown_intr(
dev, via->
irq, via->
ih);
1420 bus_release_resource(
dev, SYS_RES_IRQ, via->
irqid, via->
irq);
1424 bus_dma_tag_destroy(via->
sgd_dmat);
1426 free(via, M_DEVBUF);
u_int16_t ac97_getextmode(struct ac97_info *codec)
int ac97_setextmode(struct ac97_info *codec, u_int16_t mode)
u_int16_t ac97_getextcaps(struct ac97_info *codec)
kobj_class_t ac97_getmixerclass(void)
void ac97_destroy(struct ac97_info *codec)
int ac97_setrate(struct ac97_info *codec, int which, int rate)
#define AC97_CREATE(dev, devinfo, cls)
#define AC97_REGEXT_FDACRATE
#define AC97_REGEXT_LADCRATE
unsigned int sndbuf_getspd(struct snd_dbuf *b)
int sndbuf_alloc(struct snd_dbuf *b, bus_dma_tag_t dmatag, int dmaflags, unsigned int size)
unsigned int sndbuf_getblkcnt(struct snd_dbuf *b)
bus_addr_t sndbuf_getbufaddr(struct snd_dbuf *buf)
unsigned int sndbuf_getalign(struct snd_dbuf *b)
unsigned int sndbuf_getblksz(struct snd_dbuf *b)
unsigned int sndbuf_getmaxsize(struct snd_dbuf *b)
int sndbuf_resize(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz)
void chn_intr(struct pcm_channel *c)
#define PCMTRIG_COMMON(x)
int mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
void * snd_mtxcreate(const char *desc, const char *type)
void * pcm_getdevinfo(device_t dev)
int pcm_setstatus(device_t dev, char *str)
void snd_mtxfree(void *m)
int pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo)
int pcm_unregister(device_t dev)
int pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
int snd_setup_intr(device_t dev, struct resource *res, int flags, driver_intr_t hand, void *param, void **cookiep)
unsigned int pcm_getbuffersize(device_t dev, unsigned int minbufsz, unsigned int deflt, unsigned int maxbufsz)
#define SND_FORMAT(f, c, e)
struct via_dma_op * sgd_table
struct pcm_channel * channel
uint16_t n_dxs_registered
struct via_chinfo rch[NWRCHANS]
struct via_dma_op * sgd_table
struct callout poll_timer
struct via_chinfo pch[NDXSCHANS+NMSGDCHANS]
bus_dma_tag_t parent_dmat
static uint32_t via8233dxs_setspeed(kobj_t obj, void *data, uint32_t speed)
#define VIA_DEFAULT_BUFSZ
static uint32_t via8233wr_setspeed(kobj_t obj, void *data, uint32_t speed)
#define VIA8233_REV_ID_8233
static int via8233dxs_setformat(kobj_t obj, void *data, uint32_t format)
static uint32_t via8233chan_setblocksize(kobj_t obj, void *data, uint32_t blksz)
static __inline uint32_t via_rd(struct via_info *via, int regno, int size)
static int via8233wr_setformat(kobj_t obj, void *data, uint32_t format)
static __inline int via_chan_active(struct via_info *via)
static void * via8233wr_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
static int via_waitvalid_codec(struct via_info *via)
static uint32_t via8233msgd_setspeed(kobj_t obj, void *data, uint32_t speed)
static device_method_t via_methods[]
static void via_init_sysctls(device_t dev)
static driver_t via_driver
static void dma_cb(void *p, bus_dma_segment_t *bds, int a, int b)
static void via8233chan_reset(struct via_info *via, struct via_chinfo *ch)
#define VIA8233_REV_ID_8237
static void * via8233dxs_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
static struct pcmchan_caps * via8233dxs_getcaps(kobj_t obj, void *data)
static void via_poll_callback(void *arg)
#define VIA8233_REV_ID_8233PRE
static int via8233msgd_setformat(kobj_t obj, void *data, uint32_t format)
static int via_waitready_codec(struct via_info *via)
static int via_attach(device_t dev)
MODULE_VERSION(snd_via8233, 1)
static kobj_method_t via8233wr_methods[]
static __inline int via_poll_channel(struct via_chinfo *ch)
static int via_buildsgdt(struct via_chinfo *ch)
static uint32_t via8233chan_getptr(kobj_t obj, void *data)
CHANNEL_DECLARE(via8233wr)
static struct pcmchan_caps * via8233wr_getcaps(kobj_t obj, void *data)
static struct pcmchan_caps via_vracaps
DRIVER_MODULE(snd_via8233, pci, via_driver, pcm_devclass, 0, 0)
MODULE_DEPEND(snd_via8233, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER)
static int sysctl_via8233_spdif_enable(SYSCTL_HANDLER_ARGS)
static int via_read_codec(kobj_t obj, void *addr, int reg)
static int via_detach(device_t dev)
SND_DECLARE_FILE("$FreeBSD$")
static struct pcmchan_caps * via8233msgd_getcaps(kobj_t obj, void *data)
static int via8233chan_setfragments(kobj_t obj, void *data, uint32_t blksz, uint32_t blkcnt)
static uint32_t via_fmt[]
#define VIA8233_REV_ID_8235
static int via8233chan_trigger(kobj_t obj, void *data, int go)
static kobj_method_t via8233dxs_methods[]
static int via_poll_ticks(struct via_info *via)
static int via_write_codec(kobj_t obj, void *addr, int reg, uint32_t val)
static __inline void via_wr(struct via_info *via, int regno, uint32_t data, int size)
static void via_intr(void *p)
static int via_chip_init(device_t dev)
static void * via8233msgd_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
#define VIA8233_REV_ID_8251
#define VIA8233_REV_ID_8233C
static kobj_method_t via_ac97_methods[]
static kobj_method_t via8233msgd_methods[]
static void via8233chan_mute(struct via_info *via, struct via_chinfo *ch, int muted)
static void via8233chan_sgdinit(struct via_info *via, struct via_chinfo *ch, int chnum)
static int sysctl_via8233_dxs_src(SYSCTL_HANDLER_ARGS)
static int via_probe(device_t dev)
static int sysctl_via_polling(SYSCTL_HANDLER_ARGS)
static struct pcmchan_caps via_caps
#define VIA8233_REV_ID_8233A
#define MC_SGD_CHANNELS(x)
#define VIA8233_DXS_RATEFMT_16BIT
#define WR_FORMAT_STOP_INDEX
#define VIA_MC_SGD_FORMAT
#define SGD_CONTROL_AUTOSTART
#define VIA8233_RP_DXS_LVOL
#define VIA8233_DXS_RATEFMT_48K
#define VIA_RP_CURRENT_COUNT
#define VIA8233_DXS_RATEFMT_STEREO
#define VIA_MC_SLOT_SELECT
#define VIA_PCI_ACLINK_NRST
#define VIA_WR_RP_SGD_FORMAT
#define SGD_STATUS_ACTIVE
#define SGD_CONTROL_I_FLAG
#define VIA_PCI_ACLINK_C00_READY
#define VIA_PCI_ACLINK_STAT
#define VIA_AC97_INDEX(x)
#define VIA8233_RP_DXS_RATEFMT
#define SGD_CONTROL_I_EOL
#define SGD_CONTROL_START
#define BASE_IS_VIA_DXS_REG(x)
#define VIA_MC_SGD_STATUS
#define VIA_AC97_CODEC00_VALID
#define VIA_PCI_ACLINK_SYNC
#define VIA_PCI_ACLINK_EN
#define VIA8233_RP_DXS_RVOL
#define VIA_PCI_ACLINK_DESIRED
#define VIA_PCI_ACLINK_CTRL