- fix compatibility with newer versions of FreeBSD

- fix all warnings during compilation
- fix obvious bugs
- add support for more cards

Now supported:
 - M-Audio Delta Dio 2496
 - M-Audio Audiophile 2496
 - Terratec DMX 6fire

Known bugs (detected by Nokolas and Stefan):
 - $ kldunload snd_ak452x.ko
   Warning: memory type ak452x leaked memory on destroy (1 allocations,
   64 bytes leaked).
 - No sound in KDE: Everything works fine at the console but when I load KDE
   (3.5.3) the sound stutters and plays at less then 1/2 speed.
 - 'mixer: WRITE_MIXER: Device not configured' The message repeats x
   times at system startup, x = whatever hw.snd.maxautovchans is set to.
   (this is because only vol, pcm and line are supported, but the driver
   shows more than those mixer devices and setting those additional mixers
   results in this error message)
 - vchans don't work
 - 24 bit playback not supported (only 16/32 bit)
 - after kld(un)loading some times, the card fails to be probed until reboot

Datasheets are available from:
	http://www.nbritton.org/uploads/envy24/
	http://www.asahi-kasei.co.jp/akm/en/product/ak4528/ak4528_f01e.pdf
	http://www.asahi-kasei.co.jp/akm/en/product/ak4528/ekd4528-01.pdf
	http://www.asahi-kasei.co.jp/akm/en/product/ak4524/ak4524_f03e.pdf
	http://www.asahi-kasei.co.jp/akm/en/product/ak4524/ekd4524.pdf
	http://www.wolfson.co.uk/uploads/documents/en/WM8728.pdf
	http://www.richtech.co.kr/down/richtek/RT9131.pdf
	http://xkodi.svobodno.com/xkodi/space71.html
	http://people.freebsd.org/~lofi/envy24.pdf
	http://people.freebsd.org/~lofi/4524.pdf

Submitted by:	Konstantin Dimitrov <kosio.dimitrov@gmail.com>
Tested by:	Nikolas Britton <nikolas.britton@gmail.com>
		Stefan Ehmann <shoesoft@gmx.net>
This commit is contained in:
Alexander Leidinger 2006-06-17 15:11:36 +00:00
parent 12ab72d345
commit ce356b7017
4 changed files with 184 additions and 58 deletions

View File

@ -119,7 +119,7 @@ ak452x_create(device_t dev, void *devinfo, int num, ak452x_ctrl ctrl)
return NULL;
snprintf(codec->name, AK452X_NAMELEN, "%s:ak452x%d", device_get_nameunit(dev), num);
codec->lock = snd_mtxcreate(codec->name);
codec->lock = snd_mtxcreate(codec->name, codec->name);
codec->dev = dev;
codec->ctrl = ctrl;
codec->devinfo = devinfo;
@ -167,7 +167,7 @@ void
ak452x_setdvc(struct ak452x_info *codec, unsigned int dvc)
{
snd_mtxlock(codec->lock);
codec->type = dvc;
codec->dvc = dvc;
snd_mtxunlock(codec->lock);
}
@ -243,5 +243,5 @@ ak452x_set(struct ak452x_info *codec, int dir, unsigned int left, unsigned int r
snd_mtxunlock(codec->lock);
}
MODULE_DEPEND(snd_ak452x, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER);
MODULE_DEPEND(snd_ak452x, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
MODULE_VERSION(snd_ak452x, 1);

View File

@ -31,8 +31,8 @@
#include <dev/sound/pci/ak452x.h>
#include <dev/sound/pci/envy24.h>
#include <pci/pcireg.h>
#include <pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include "mixer_if.h"
@ -54,7 +54,11 @@ struct sc_info;
#define ENVY24_NAMELEN 32
typedef volatile u_int32_t sample32_t;
struct envy24_sample {
volatile u_int32_t buffer;
};
typedef struct envy24_sample sample32_t;
/* channel registers */
struct sc_chinfo {
@ -96,6 +100,7 @@ struct cfg_info {
u_int16_t subvendor, subdevice;
u_int8_t scfg, acl, i2s, spdif;
u_int8_t gpiomask, gpiostate, gpiodir;
u_int8_t cdti, cclk, cs, cif, type;
u_int8_t free;
struct codec_entry *codec;
};
@ -266,19 +271,39 @@ static struct codec_entry delta_codec = {
static struct cfg_info cfg_table[] = {
{
"Envy24 audio(M Audio Delta Dio 2496)",
"Envy24 audio (M Audio Delta Dio 2496)",
0x1412, 0xd631,
0x10, 0x80, 0xf0, 0x03,
0xff, 0x00, 0x00,
0,
0x10, 0x20, 0x40, 0x00, 0x00,
0x00,
&delta_codec,
},
{
"Envy24 audio(Generic)",
"Envy24 audio (Terratec DMX 6fire)",
0x153b, 0x1138,
0x2f, 0x80, 0xf0, 0x03,
0xc0, 0xff, 0x7f,
0x10, 0x20, 0x01, 0x01, 0x00,
0x00,
&delta_codec,
},
{
"Envy24 audio (M Audio Audiophile 2496)",
0x1412, 0xd634,
0x10, 0x80, 0x72, 0x03,
0x04, 0xfe, 0xfb,
0x08, 0x02, 0x20, 0x00, 0x01,
0x00,
&delta_codec,
},
{
"Envy24 audio (Generic)",
0, 0,
0x0f, 0x00, 0x01, 0x03,
0xff, 0x00, 0x00,
0,
0x10, 0x20, 0x40, 0x00, 0x00,
0x00,
&delta_codec, /* default codec routines */
}
};
@ -439,6 +464,7 @@ envy24_rdi2c(struct sc_info *sc, u_int32_t dev, u_int32_t addr)
return (int)data;
}
#if 0
static int
envy24_wri2c(struct sc_info *sc, u_int32_t dev, u_int32_t addr, u_int32_t data)
{
@ -473,6 +499,7 @@ envy24_wri2c(struct sc_info *sc, u_int32_t dev, u_int32_t addr, u_int32_t data)
return 0;
}
#endif
static int
envy24_rdrom(struct sc_info *sc, u_int32_t addr)
@ -554,6 +581,7 @@ envy24_cfgfree(struct cfg_info *cfg) {
/* AC'97 codec access routines */
#if 0
static int
envy24_coldcd(struct sc_info *sc)
{
@ -576,6 +604,7 @@ envy24_coldcd(struct sc_info *sc)
return -1;
}
#endif
static int
envy24_slavecd(struct sc_info *sc)
@ -601,6 +630,7 @@ envy24_slavecd(struct sc_info *sc)
return -1;
}
#if 0
static int
envy24_rdcd(kobj_t obj, void *devinfo, int regno)
{
@ -654,6 +684,7 @@ static kobj_method_t envy24_ac97_methods[] = {
{0, 0}
};
AC97_DECLARE(envy24_ac97);
#endif
/* -------------------------------------------------------------------- */
@ -676,11 +707,13 @@ envy24_gpiowr(struct sc_info *sc, u_int32_t data)
return;
}
#if 0
static u_int32_t
envy24_gpiogetmask(struct sc_info *sc)
{
return envy24_rdci(sc, ENVY24_CCI_GPIOMASK);
}
#endif
static void
envy24_gpiosetmask(struct sc_info *sc, u_int32_t mask)
@ -689,11 +722,13 @@ envy24_gpiosetmask(struct sc_info *sc, u_int32_t mask)
return;
}
#if 0
static u_int32_t
envy24_gpiogetdir(struct sc_info *sc)
{
return envy24_rdci(sc, ENVY24_CCI_GPIOCTL);
}
#endif
static void
envy24_gpiosetdir(struct sc_info *sc, u_int32_t dir)
@ -789,7 +824,9 @@ envy24_delta_ak4524_destroy(void *codec)
static void
envy24_delta_ak4524_init(void *codec)
{
#if 0
u_int32_t gpiomask, gpiodir;
#endif
struct envy24_delta_ak4524_codec *ptr = codec;
if (ptr == NULL)
return;
@ -805,6 +842,8 @@ envy24_delta_ak4524_init(void *codec)
gpiodir |= ENVY24_GPIO_AK4524_CDTI | ENVY24_GPIO_AK4524_CCLK | ENVY24_GPIO_AK4524_CS0 | ENVY24_GPIO_AK4524_CS1;
envy24_gpiosetdir(ptr->parent, gpiodir);
*/
ptr->cs = ptr->parent->cfg->cs;
#if 0
envy24_gpiosetmask(ptr->parent, ENVY24_GPIO_CS8414_STATUS);
envy24_gpiosetdir(ptr->parent, ~ENVY24_GPIO_CS8414_STATUS);
if (ptr->num == 0)
@ -812,9 +851,20 @@ envy24_delta_ak4524_init(void *codec)
else
ptr->cs = ENVY24_GPIO_AK4524_CS1;
ptr->cclk = ENVY24_GPIO_AK4524_CCLK;
#endif
ptr->cclk = ptr->parent->cfg->cclk;
#if 0
ptr->cdti = ENVY24_GPIO_AK4524_CDTI;
#endif
ptr->cdti = ptr->parent->cfg->cdti;
#if 0
ak452x_settype(ptr->info, AK452X_TYPE_4524);
#endif
ak452x_settype(ptr->info, ptr->parent->cfg->type);
#if 0
ak452x_setcif(ptr->info, ENVY24_DELTA_AK4524_CIF);
#endif
ak452x_setcif(ptr->info, ptr->parent->cfg->cif);
ak452x_setformat(ptr->info,
AK452X_FORMAT_I2S | AK452X_FORMAT_256FSN | AK452X_FORMAT_1X);
ak452x_setdvc(ptr->info, 0);
@ -926,6 +976,13 @@ envy24_setvolume(struct sc_info *sc, unsigned ch)
#if(0)
device_printf(sc->dev, "envy24_setvolume(sc, %d)\n", ch);
#endif
if (sc->cfg->subvendor==0x153b && sc->cfg->subdevice==0x1138 ) {
envy24_wrmt(sc, ENVY24_MT_VOLIDX, 16, 1);
envy24_wrmt(sc, ENVY24_MT_VOLUME, 0x7f7f, 2);
envy24_wrmt(sc, ENVY24_MT_VOLIDX, 17, 1);
envy24_wrmt(sc, ENVY24_MT_VOLUME, 0x7f7f, 2);
}
envy24_wrmt(sc, ENVY24_MT_VOLIDX, ch * 2, 1);
envy24_wrmt(sc, ENVY24_MT_VOLUME, 0x7f00 | sc->left[ch], 2);
envy24_wrmt(sc, ENVY24_MT_VOLIDX, ch * 2 + 1, 1);
@ -1027,6 +1084,7 @@ envy24_updintr(struct sc_info *sc, int dir)
return;
}
#if 0
static void
envy24_maskintr(struct sc_info *sc, int dir)
{
@ -1044,6 +1102,7 @@ envy24_maskintr(struct sc_info *sc, int dir)
return;
}
#endif
static int
envy24_checkintr(struct sc_info *sc, int dir)
@ -1193,8 +1252,8 @@ envy24_p32sl(struct sc_chinfo *ch)
slot = ch->num * 2;
for (i = 0; i < length; i++) {
dmabuf[dst * ENVY24_PLAY_CHNUM + slot] = data[src];
dmabuf[dst * ENVY24_PLAY_CHNUM + slot + 1] = data[src + 1];
dmabuf[dst * ENVY24_PLAY_CHNUM + slot].buffer = data[src];
dmabuf[dst * ENVY24_PLAY_CHNUM + slot + 1].buffer = data[src + 1];
dst++;
dst %= dsize;
src += 2;
@ -1229,8 +1288,8 @@ envy24_p16sl(struct sc_chinfo *ch)
#endif
for (i = 0; i < length; i++) {
dmabuf[dst * ENVY24_PLAY_CHNUM + slot] = (u_int32_t)data[src] << 16;
dmabuf[dst * ENVY24_PLAY_CHNUM + slot + 1] = (u_int32_t)data[src + 1] << 16;
dmabuf[dst * ENVY24_PLAY_CHNUM + slot].buffer = (u_int32_t)data[src] << 16;
dmabuf[dst * ENVY24_PLAY_CHNUM + slot + 1].buffer = (u_int32_t)data[src + 1] << 16;
#if(0)
if (i < 16) {
printf("%08x", dmabuf[dst * ENVY24_PLAY_CHNUM + slot]);
@ -1268,8 +1327,8 @@ envy24_p8u(struct sc_chinfo *ch)
slot = ch->num * 2;
for (i = 0; i < length; i++) {
dmabuf[dst * ENVY24_PLAY_CHNUM + slot] = ((u_int32_t)data[src] ^ 0x80) << 24;
dmabuf[dst * ENVY24_PLAY_CHNUM + slot + 1] = ((u_int32_t)data[src + 1] ^ 0x80) << 24;
dmabuf[dst * ENVY24_PLAY_CHNUM + slot].buffer = ((u_int32_t)data[src] ^ 0x80) << 24;
dmabuf[dst * ENVY24_PLAY_CHNUM + slot + 1].buffer = ((u_int32_t)data[src + 1] ^ 0x80) << 24;
dst++;
dst %= dsize;
src += 2;
@ -1298,8 +1357,8 @@ envy24_r32sl(struct sc_chinfo *ch)
slot = (ch->num - ENVY24_CHAN_REC_ADC1) * 2;
for (i = 0; i < length; i++) {
data[dst] = dmabuf[src * ENVY24_REC_CHNUM + slot];
data[dst + 1] = dmabuf[src * ENVY24_REC_CHNUM + slot + 1];
data[dst] = dmabuf[src * ENVY24_REC_CHNUM + slot].buffer;
data[dst + 1] = dmabuf[src * ENVY24_REC_CHNUM + slot + 1].buffer;
dst += 2;
dst %= dsize;
src++;
@ -1314,7 +1373,7 @@ envy24_r16sl(struct sc_chinfo *ch)
{
int length;
sample32_t *dmabuf;
u_int32_t *data;
u_int16_t *data;
int src, dst, ssize, dsize, slot;
int i;
@ -1328,8 +1387,8 @@ envy24_r16sl(struct sc_chinfo *ch)
slot = (ch->num - ENVY24_CHAN_REC_ADC1) * 2;
for (i = 0; i < length; i++) {
data[dst] = dmabuf[src * ENVY24_REC_CHNUM + slot];
data[dst + 1] = dmabuf[src * ENVY24_REC_CHNUM + slot + 1];
data[dst] = dmabuf[src * ENVY24_REC_CHNUM + slot].buffer;
data[dst + 1] = dmabuf[src * ENVY24_REC_CHNUM + slot + 1].buffer;
dst += 2;
dst %= dsize;
src++;
@ -2045,7 +2104,7 @@ envy24_dmainit(struct sc_info *sc)
static void
envy24_putcfg(struct sc_info *sc)
{
device_printf(sc->dev, "system configuration\n", sc->adcn, sc->dacn);
device_printf(sc->dev, "system configuration\n");
printf(" SubVendorID: 0x%04x, SubDeviceID: 0x%04x\n",
sc->cfg->subvendor, sc->cfg->subdevice);
printf(" XIN2 Clock Source: ");
@ -2279,7 +2338,8 @@ envy24_alloc_resource(struct sc_info *sc)
/*filter*/NULL, /*filterarg*/NULL,
/*maxsize*/BUS_SPACE_MAXSIZE_ENVY24,
/*nsegments*/1, /*maxsegsz*/0x3ffff,
/*flags*/0, &sc->dmat) != 0) {
/*flags*/0, /*lockfunc*/busdma_lock_mutex,
/*lockarg*/&Giant, &sc->dmat) != 0) {
device_printf(sc->dev, "unable to create dma tag\n");
return ENXIO;
}
@ -2308,7 +2368,7 @@ envy24_pci_attach(device_t dev)
bzero(sc, sizeof(*sc));
snprintf(name, ENVY24_NAMELEN, "%s:envy24", device_get_nameunit(dev));
sc->lock = snd_mtxcreate(name);
sc->lock = snd_mtxcreate(name, name);
sc->dev = dev;
/* initialize PCI interface */
@ -2318,13 +2378,15 @@ envy24_pci_attach(device_t dev)
data = pci_read_config(dev, PCIR_COMMAND, 2);
/* allocate resources */
if (err = envy24_alloc_resource(sc)) {
err = envy24_alloc_resource(sc);
if (err) {
device_printf(dev, "unable to allocate system resources\n");
goto bad;
}
/* initialize card */
if (err = envy24_init(sc)) {
err = envy24_init(sc);
if (err) {
device_printf(dev, "unable to initialize the card\n");
goto bad;
}
@ -2333,7 +2395,8 @@ envy24_pci_attach(device_t dev)
mixer_init(dev, &envy24mixer_class, sc);
/* set channel information */
if (err = pcm_register(dev, sc, 5, 2 + sc->adc))
err = pcm_register(dev, sc, 5, 2 + sc->adcn);
if (err)
goto bad;
sc->chnum = 0;
for (i = 0; i < 5; i++) {
@ -2440,6 +2503,6 @@ static driver_t envy24_driver = {
};
DRIVER_MODULE(snd_envy24, pci, envy24_driver, pcm_devclass, 0, 0);
MODULE_DEPEND(snd_envy24, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER);
MODULE_DEPEND(snd_envy24, snd_ak452x, PCM_MINVER, PCM_PREFVER, PCM_MAXVER);
MODULE_DEPEND(snd_envy24, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
MODULE_DEPEND(snd_envy24, snd_ak452x, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
MODULE_VERSION(snd_envy24, 1);

View File

@ -31,8 +31,8 @@
#include <dev/sound/pci/ak452x.h>
#include <dev/sound/pci/envy24.h>
#include <pci/pcireg.h>
#include <pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include "mixer_if.h"
@ -54,7 +54,11 @@ struct sc_info;
#define ENVY24_NAMELEN 32
typedef volatile u_int32_t sample32_t;
struct envy24_sample {
volatile u_int32_t buffer;
};
typedef struct envy24_sample sample32_t;
/* channel registers */
struct sc_chinfo {
@ -96,6 +100,7 @@ struct cfg_info {
u_int16_t subvendor, subdevice;
u_int8_t scfg, acl, i2s, spdif;
u_int8_t gpiomask, gpiostate, gpiodir;
u_int8_t cdti, cclk, cs, cif, type;
u_int8_t free;
struct codec_entry *codec;
};
@ -266,19 +271,39 @@ static struct codec_entry delta_codec = {
static struct cfg_info cfg_table[] = {
{
"Envy24 audio(M Audio Delta Dio 2496)",
"Envy24 audio (M Audio Delta Dio 2496)",
0x1412, 0xd631,
0x10, 0x80, 0xf0, 0x03,
0xff, 0x00, 0x00,
0,
0x10, 0x20, 0x40, 0x00, 0x00,
0x00,
&delta_codec,
},
{
"Envy24 audio(Generic)",
"Envy24 audio (Terratec DMX 6fire)",
0x153b, 0x1138,
0x2f, 0x80, 0xf0, 0x03,
0xc0, 0xff, 0x7f,
0x10, 0x20, 0x01, 0x01, 0x00,
0x00,
&delta_codec,
},
{
"Envy24 audio (M Audio Audiophile 2496)",
0x1412, 0xd634,
0x10, 0x80, 0x72, 0x03,
0x04, 0xfe, 0xfb,
0x08, 0x02, 0x20, 0x00, 0x01,
0x00,
&delta_codec,
},
{
"Envy24 audio (Generic)",
0, 0,
0x0f, 0x00, 0x01, 0x03,
0xff, 0x00, 0x00,
0,
0x10, 0x20, 0x40, 0x00, 0x00,
0x00,
&delta_codec, /* default codec routines */
}
};
@ -439,6 +464,7 @@ envy24_rdi2c(struct sc_info *sc, u_int32_t dev, u_int32_t addr)
return (int)data;
}
#if 0
static int
envy24_wri2c(struct sc_info *sc, u_int32_t dev, u_int32_t addr, u_int32_t data)
{
@ -473,6 +499,7 @@ envy24_wri2c(struct sc_info *sc, u_int32_t dev, u_int32_t addr, u_int32_t data)
return 0;
}
#endif
static int
envy24_rdrom(struct sc_info *sc, u_int32_t addr)
@ -554,6 +581,7 @@ envy24_cfgfree(struct cfg_info *cfg) {
/* AC'97 codec access routines */
#if 0
static int
envy24_coldcd(struct sc_info *sc)
{
@ -576,6 +604,7 @@ envy24_coldcd(struct sc_info *sc)
return -1;
}
#endif
static int
envy24_slavecd(struct sc_info *sc)
@ -601,6 +630,7 @@ envy24_slavecd(struct sc_info *sc)
return -1;
}
#if 0
static int
envy24_rdcd(kobj_t obj, void *devinfo, int regno)
{
@ -654,6 +684,7 @@ static kobj_method_t envy24_ac97_methods[] = {
{0, 0}
};
AC97_DECLARE(envy24_ac97);
#endif
/* -------------------------------------------------------------------- */
@ -676,11 +707,13 @@ envy24_gpiowr(struct sc_info *sc, u_int32_t data)
return;
}
#if 0
static u_int32_t
envy24_gpiogetmask(struct sc_info *sc)
{
return envy24_rdci(sc, ENVY24_CCI_GPIOMASK);
}
#endif
static void
envy24_gpiosetmask(struct sc_info *sc, u_int32_t mask)
@ -689,11 +722,13 @@ envy24_gpiosetmask(struct sc_info *sc, u_int32_t mask)
return;
}
#if 0
static u_int32_t
envy24_gpiogetdir(struct sc_info *sc)
{
return envy24_rdci(sc, ENVY24_CCI_GPIOCTL);
}
#endif
static void
envy24_gpiosetdir(struct sc_info *sc, u_int32_t dir)
@ -789,7 +824,9 @@ envy24_delta_ak4524_destroy(void *codec)
static void
envy24_delta_ak4524_init(void *codec)
{
#if 0
u_int32_t gpiomask, gpiodir;
#endif
struct envy24_delta_ak4524_codec *ptr = codec;
if (ptr == NULL)
return;
@ -805,6 +842,8 @@ envy24_delta_ak4524_init(void *codec)
gpiodir |= ENVY24_GPIO_AK4524_CDTI | ENVY24_GPIO_AK4524_CCLK | ENVY24_GPIO_AK4524_CS0 | ENVY24_GPIO_AK4524_CS1;
envy24_gpiosetdir(ptr->parent, gpiodir);
*/
ptr->cs = ptr->parent->cfg->cs;
#if 0
envy24_gpiosetmask(ptr->parent, ENVY24_GPIO_CS8414_STATUS);
envy24_gpiosetdir(ptr->parent, ~ENVY24_GPIO_CS8414_STATUS);
if (ptr->num == 0)
@ -812,9 +851,20 @@ envy24_delta_ak4524_init(void *codec)
else
ptr->cs = ENVY24_GPIO_AK4524_CS1;
ptr->cclk = ENVY24_GPIO_AK4524_CCLK;
#endif
ptr->cclk = ptr->parent->cfg->cclk;
#if 0
ptr->cdti = ENVY24_GPIO_AK4524_CDTI;
#endif
ptr->cdti = ptr->parent->cfg->cdti;
#if 0
ak452x_settype(ptr->info, AK452X_TYPE_4524);
#endif
ak452x_settype(ptr->info, ptr->parent->cfg->type);
#if 0
ak452x_setcif(ptr->info, ENVY24_DELTA_AK4524_CIF);
#endif
ak452x_setcif(ptr->info, ptr->parent->cfg->cif);
ak452x_setformat(ptr->info,
AK452X_FORMAT_I2S | AK452X_FORMAT_256FSN | AK452X_FORMAT_1X);
ak452x_setdvc(ptr->info, 0);
@ -926,6 +976,13 @@ envy24_setvolume(struct sc_info *sc, unsigned ch)
#if(0)
device_printf(sc->dev, "envy24_setvolume(sc, %d)\n", ch);
#endif
if (sc->cfg->subvendor==0x153b && sc->cfg->subdevice==0x1138 ) {
envy24_wrmt(sc, ENVY24_MT_VOLIDX, 16, 1);
envy24_wrmt(sc, ENVY24_MT_VOLUME, 0x7f7f, 2);
envy24_wrmt(sc, ENVY24_MT_VOLIDX, 17, 1);
envy24_wrmt(sc, ENVY24_MT_VOLUME, 0x7f7f, 2);
}
envy24_wrmt(sc, ENVY24_MT_VOLIDX, ch * 2, 1);
envy24_wrmt(sc, ENVY24_MT_VOLUME, 0x7f00 | sc->left[ch], 2);
envy24_wrmt(sc, ENVY24_MT_VOLIDX, ch * 2 + 1, 1);
@ -1027,6 +1084,7 @@ envy24_updintr(struct sc_info *sc, int dir)
return;
}
#if 0
static void
envy24_maskintr(struct sc_info *sc, int dir)
{
@ -1044,6 +1102,7 @@ envy24_maskintr(struct sc_info *sc, int dir)
return;
}
#endif
static int
envy24_checkintr(struct sc_info *sc, int dir)
@ -1193,8 +1252,8 @@ envy24_p32sl(struct sc_chinfo *ch)
slot = ch->num * 2;
for (i = 0; i < length; i++) {
dmabuf[dst * ENVY24_PLAY_CHNUM + slot] = data[src];
dmabuf[dst * ENVY24_PLAY_CHNUM + slot + 1] = data[src + 1];
dmabuf[dst * ENVY24_PLAY_CHNUM + slot].buffer = data[src];
dmabuf[dst * ENVY24_PLAY_CHNUM + slot + 1].buffer = data[src + 1];
dst++;
dst %= dsize;
src += 2;
@ -1229,8 +1288,8 @@ envy24_p16sl(struct sc_chinfo *ch)
#endif
for (i = 0; i < length; i++) {
dmabuf[dst * ENVY24_PLAY_CHNUM + slot] = (u_int32_t)data[src] << 16;
dmabuf[dst * ENVY24_PLAY_CHNUM + slot + 1] = (u_int32_t)data[src + 1] << 16;
dmabuf[dst * ENVY24_PLAY_CHNUM + slot].buffer = (u_int32_t)data[src] << 16;
dmabuf[dst * ENVY24_PLAY_CHNUM + slot + 1].buffer = (u_int32_t)data[src + 1] << 16;
#if(0)
if (i < 16) {
printf("%08x", dmabuf[dst * ENVY24_PLAY_CHNUM + slot]);
@ -1268,8 +1327,8 @@ envy24_p8u(struct sc_chinfo *ch)
slot = ch->num * 2;
for (i = 0; i < length; i++) {
dmabuf[dst * ENVY24_PLAY_CHNUM + slot] = ((u_int32_t)data[src] ^ 0x80) << 24;
dmabuf[dst * ENVY24_PLAY_CHNUM + slot + 1] = ((u_int32_t)data[src + 1] ^ 0x80) << 24;
dmabuf[dst * ENVY24_PLAY_CHNUM + slot].buffer = ((u_int32_t)data[src] ^ 0x80) << 24;
dmabuf[dst * ENVY24_PLAY_CHNUM + slot + 1].buffer = ((u_int32_t)data[src + 1] ^ 0x80) << 24;
dst++;
dst %= dsize;
src += 2;
@ -1298,8 +1357,8 @@ envy24_r32sl(struct sc_chinfo *ch)
slot = (ch->num - ENVY24_CHAN_REC_ADC1) * 2;
for (i = 0; i < length; i++) {
data[dst] = dmabuf[src * ENVY24_REC_CHNUM + slot];
data[dst + 1] = dmabuf[src * ENVY24_REC_CHNUM + slot + 1];
data[dst] = dmabuf[src * ENVY24_REC_CHNUM + slot].buffer;
data[dst + 1] = dmabuf[src * ENVY24_REC_CHNUM + slot + 1].buffer;
dst += 2;
dst %= dsize;
src++;
@ -1314,7 +1373,7 @@ envy24_r16sl(struct sc_chinfo *ch)
{
int length;
sample32_t *dmabuf;
u_int32_t *data;
u_int16_t *data;
int src, dst, ssize, dsize, slot;
int i;
@ -1328,8 +1387,8 @@ envy24_r16sl(struct sc_chinfo *ch)
slot = (ch->num - ENVY24_CHAN_REC_ADC1) * 2;
for (i = 0; i < length; i++) {
data[dst] = dmabuf[src * ENVY24_REC_CHNUM + slot];
data[dst + 1] = dmabuf[src * ENVY24_REC_CHNUM + slot + 1];
data[dst] = dmabuf[src * ENVY24_REC_CHNUM + slot].buffer;
data[dst + 1] = dmabuf[src * ENVY24_REC_CHNUM + slot + 1].buffer;
dst += 2;
dst %= dsize;
src++;
@ -2045,7 +2104,7 @@ envy24_dmainit(struct sc_info *sc)
static void
envy24_putcfg(struct sc_info *sc)
{
device_printf(sc->dev, "system configuration\n", sc->adcn, sc->dacn);
device_printf(sc->dev, "system configuration\n");
printf(" SubVendorID: 0x%04x, SubDeviceID: 0x%04x\n",
sc->cfg->subvendor, sc->cfg->subdevice);
printf(" XIN2 Clock Source: ");
@ -2279,7 +2338,8 @@ envy24_alloc_resource(struct sc_info *sc)
/*filter*/NULL, /*filterarg*/NULL,
/*maxsize*/BUS_SPACE_MAXSIZE_ENVY24,
/*nsegments*/1, /*maxsegsz*/0x3ffff,
/*flags*/0, &sc->dmat) != 0) {
/*flags*/0, /*lockfunc*/busdma_lock_mutex,
/*lockarg*/&Giant, &sc->dmat) != 0) {
device_printf(sc->dev, "unable to create dma tag\n");
return ENXIO;
}
@ -2308,7 +2368,7 @@ envy24_pci_attach(device_t dev)
bzero(sc, sizeof(*sc));
snprintf(name, ENVY24_NAMELEN, "%s:envy24", device_get_nameunit(dev));
sc->lock = snd_mtxcreate(name);
sc->lock = snd_mtxcreate(name, name);
sc->dev = dev;
/* initialize PCI interface */
@ -2318,13 +2378,15 @@ envy24_pci_attach(device_t dev)
data = pci_read_config(dev, PCIR_COMMAND, 2);
/* allocate resources */
if (err = envy24_alloc_resource(sc)) {
err = envy24_alloc_resource(sc);
if (err) {
device_printf(dev, "unable to allocate system resources\n");
goto bad;
}
/* initialize card */
if (err = envy24_init(sc)) {
err = envy24_init(sc);
if (err) {
device_printf(dev, "unable to initialize the card\n");
goto bad;
}
@ -2333,7 +2395,8 @@ envy24_pci_attach(device_t dev)
mixer_init(dev, &envy24mixer_class, sc);
/* set channel information */
if (err = pcm_register(dev, sc, 5, 2 + sc->adc))
err = pcm_register(dev, sc, 5, 2 + sc->adcn);
if (err)
goto bad;
sc->chnum = 0;
for (i = 0; i < 5; i++) {
@ -2440,6 +2503,6 @@ static driver_t envy24_driver = {
};
DRIVER_MODULE(snd_envy24, pci, envy24_driver, pcm_devclass, 0, 0);
MODULE_DEPEND(snd_envy24, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER);
MODULE_DEPEND(snd_envy24, snd_ak452x, PCM_MINVER, PCM_PREFVER, PCM_MAXVER);
MODULE_DEPEND(snd_envy24, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
MODULE_DEPEND(snd_envy24, snd_ak452x, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
MODULE_VERSION(snd_envy24, 1);

View File

@ -119,7 +119,7 @@ ak452x_create(device_t dev, void *devinfo, int num, ak452x_ctrl ctrl)
return NULL;
snprintf(codec->name, AK452X_NAMELEN, "%s:ak452x%d", device_get_nameunit(dev), num);
codec->lock = snd_mtxcreate(codec->name);
codec->lock = snd_mtxcreate(codec->name, codec->name);
codec->dev = dev;
codec->ctrl = ctrl;
codec->devinfo = devinfo;
@ -167,7 +167,7 @@ void
ak452x_setdvc(struct ak452x_info *codec, unsigned int dvc)
{
snd_mtxlock(codec->lock);
codec->type = dvc;
codec->dvc = dvc;
snd_mtxunlock(codec->lock);
}
@ -243,5 +243,5 @@ ak452x_set(struct ak452x_info *codec, int dir, unsigned int left, unsigned int r
snd_mtxunlock(codec->lock);
}
MODULE_DEPEND(snd_ak452x, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER);
MODULE_DEPEND(snd_ak452x, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
MODULE_VERSION(snd_ak452x, 1);