34#ifdef HAVE_KERNEL_OPTION_HEADERS
43#include <isa/isavar.h>
49#define ESS_BUFFSIZE (4096)
50#define ABS(x) (((x) < 0)? -(x) : (x))
56#define ESS18XX_NEWSPEED
157 return bus_space_read_1(rman_get_bustag(port),
158 rman_get_bushandle(port),
165 bus_space_write_1(rman_get_bustag(port),
166 rman_get_bushandle(port),
193 for (i = 0; i < 1000; i++) {
198 if (i > 10) DELAY((i > 100)? 1000 : 10);
200 printf(
"ess_dspwr(0x%02x) timed out.\n",
val);
208 printf(
"ess_cmd: %x\n",
val);
217 printf(
"ess_cmd1: %x, %x\n", cmd,
val);
227 DEB(printf(
"ess_setmixer: reg=%x, val=%x\n", port,
value);)
251 for (i = 1000; i > 0; i--) {
279 DEB(printf(
"ess_reset_dsp 0x%lx failed\n",
292 bus_teardown_intr(
dev, sc->
irq, sc->
ih);
293 bus_release_resource(
dev, SYS_RES_IRQ, 0, sc->
irq);
297 isa_dma_release(rman_get_start(sc->
drq1));
298 bus_release_resource(
dev, SYS_RES_DRQ, 0, sc->
drq1);
302 isa_dma_release(rman_get_start(sc->
drq2));
303 bus_release_resource(
dev, SYS_RES_DRQ, 1, sc->
drq2);
307 bus_release_resource(
dev, SYS_RES_IOPORT, 0, sc->
io_base);
324 sc->
io_base = bus_alloc_resource_any(
dev, SYS_RES_IOPORT,
328 sc->
irq = bus_alloc_resource_any(
dev, SYS_RES_IRQ,
332 sc->
drq1 = bus_alloc_resource_any(
dev, SYS_RES_DRQ,
336 sc->
drq2 = bus_alloc_resource_any(
dev, SYS_RES_DRQ,
340 isa_dma_acquire(rman_get_start(sc->
drq1));
341 isa_dmainit(rman_get_start(sc->
drq1), sc->
bufsize);
344 isa_dma_acquire(rman_get_start(sc->
drq2));
345 isa_dmainit(rman_get_start(sc->
drq2), sc->
bufsize);
362 if (
ess_rd(sc, 0x0c) & 0x01)
365 pirq = (
src & sc->pch.hwch)? 1 : 0;
374 if (sc->pch.stopping) {
377 sc->pch.stopping = 0;
378 if (sc->pch.hwch == 1)
416 speed = (795500 + t / 2) / t;
417 t = (256 - t) | 0x80;
420 speed = (397700 + t / 2) / t;
424 return t & 0x000000ff;
430 int speed, s0, s1, use0;
436 t0 = 128 - (793800 /
speed);
437 s0 = 793800 / (128 - t0);
439 t1 = 128 - (768000 /
speed);
440 s1 = 768000 / (128 - t1);
445 *
spd = use0? s0 : s1;
446 return use0? t0 : t1;
456 cutoff = (
spd * 9 * 82) / 20;
457 return (256 - (7160000 / cutoff));
466 int unsign = (
fmt == AFMT_U8 ||
fmt == AFMT_U16_LE)? 1 : 0;
467 u_int8_t spdval, fmtval;
479 ess_write(sc, 0xb8, 0x04 | (play? 0x00 : 0x0a));
490 ess_write(sc, 0xb6, unsign? 0x80 : 0x00);
492 ess_write(sc, 0xb7, 0x51 | (unsign? 0x00 : 0x20));
494 ess_write(sc, 0xb7, 0x90 | (unsign? 0x00 : 0x20) |
501 }
else if (ch == 2) {
509 fmtval = b16 | (
stereo << 1) | (unsign << 2);
674 mix_setdevs(
m, SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_LINE |
675 SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_VOLUME |
676 SOUND_MASK_LINE1 | SOUND_MASK_SPEAKER);
687 int preg = 0, rreg = 0, l,
r;
689 l = (
left * 15) / 100;
692 case SOUND_MIXER_SYNTH:
697 case SOUND_MIXER_PCM:
702 case SOUND_MIXER_LINE:
707 case SOUND_MIXER_MIC:
712 case SOUND_MIXER_LINE1:
722 case SOUND_MIXER_SPEAKER:
726 case SOUND_MIXER_VOLUME:
731 left = (l == 64)? 0 : (l * 100) / 63;
732 right = (
r == 64)? 0 : (
r * 100) / 63;
741 left = (l * 100) / 15;
758 case SOUND_MASK_LINE:
762 case SOUND_MASK_IMIX:
769 src = SOUND_MASK_MIC;
791 uintptr_t
func, ver,
r, f;
794 r = BUS_READ_IVAR(device_get_parent(
dev),
dev, 0, &
func);
798 r = BUS_READ_IVAR(device_get_parent(
dev),
dev, 1, &ver);
799 f = (ver & 0xffff0000) >> 16;
803 device_set_desc(
dev,
"ESS 18xx DSP");
815 gone_in_dev(
dev, 14,
"ISA sound driver");
816 sc = malloc(
sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
829 snprintf(
buf,
sizeof buf,
"ESS %x DSP", ver);
830 device_set_desc_copy(
dev,
buf);
832 device_printf(
dev,
"ESS%x detected", ver);
840#ifdef ESS18XX_NEWSPEED
846 printf(
"%s%s\n", sc->
duplex?
", duplex" :
"",
856 if (bus_dma_tag_create(bus_get_dma_tag(
dev), 2,
858 BUS_SPACE_MAXADDR_24BIT,
865 device_printf(
dev,
"unable to create dma tag\n");
875 rman_get_start(sc->
io_base), rman_get_start(sc->
irq),
915 device_printf(
dev,
"unable to reset DSP at resume\n");
920 device_printf(
dev,
"unable to reinitialize mixer at resume\n");
952 {0x06007316,
"ESS Control"},
975 io = bus_alloc_resource_any(
dev, SYS_RES_IOPORT, &
rid, RF_ACTIVE);
977 for (i = 0; i < 0x100; i++) {
981 printf(
"%3.3x: ", i);
983 if ((i & 0x0f) == 0x0f)
986 bus_release_resource(
dev, SYS_RES_IOPORT, 0, io);
int sndbuf_alloc(struct snd_dbuf *b, bus_dma_tag_t dmatag, int dmaflags, unsigned int size)
void chn_intr(struct pcm_channel *c)
#define PCMTRIG_COMMON(x)
struct pcmchan_matrix * m
static int ess_resume(device_t dev)
static kobj_method_t esschan_methods[]
static int ess_attach(device_t dev)
static void * esschan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
static int essmix_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
static int ess_reset_dsp(struct ess_info *sc)
static int esscontrol_detach(device_t dev)
static int ess_start(struct ess_chinfo *ch)
static int ess_probe(device_t dev)
static struct pcmchan_caps * esschan_getcaps(kobj_t obj, void *data)
static u_int8_t ess_calcspeed9(int *spd)
static int ess_detach(device_t dev)
static int ess_getmixer(struct ess_info *sc, u_int port)
static int ess_stop(struct ess_chinfo *ch)
static void ess_intr(void *arg)
static int esschan_setformat(kobj_t obj, void *data, u_int32_t format)
static int port_rd(struct resource *port, int off)
static int ess_write(struct ess_info *sc, u_char reg, int val)
static u_int32_t essmix_setrecsrc(struct snd_mixer *m, u_int32_t src)
static void ess_release_resources(struct ess_info *sc, device_t dev)
static u_int32_t esschan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
MODULE_VERSION(snd_ess, 1)
static u_int32_t ess_pfmt[]
static devclass_t esscontrol_devclass
static int ess_dspwr(struct ess_info *sc, u_char val)
static u_int8_t ess_calcfilter(int spd)
static device_method_t ess_methods[]
static int ess_read(struct ess_info *sc, u_char reg)
static void ess_lock(struct ess_info *sc)
static int esschan_trigger(kobj_t obj, void *data, int go)
SND_DECLARE_FILE("$FreeBSD$")
static void ess_unlock(struct ess_info *sc)
static kobj_method_t essmixer_methods[]
static int esscontrol_probe(device_t dev)
static void port_wr(struct resource *port, int off, u_int8_t data)
static int ess_cmd(struct ess_info *sc, u_char val)
DRIVER_MODULE(snd_ess, sbc, ess_driver, pcm_devclass, 0, 0)
static int ess_get_byte(struct ess_info *sc)
static u_int32_t esschan_setspeed(kobj_t obj, void *data, u_int32_t speed)
static u_int32_t esschan_getptr(kobj_t obj, void *data)
static int ess_setupch(struct ess_info *sc, int ch, int dir, int spd, u_int32_t fmt, int len)
static struct pcmchan_caps ess_reccaps
static int ess_cmd1(struct ess_info *sc, u_char cmd, int val)
static int ess_rd(struct ess_info *sc, int reg)
static driver_t ess_driver
static u_int32_t ess_rfmt[]
static device_method_t esscontrol_methods[]
static int ess_dspready(struct ess_info *sc)
static driver_t esscontrol_driver
static int essmix_init(struct snd_mixer *m)
static int esscontrol_attach(device_t dev)
static u_int8_t ess_calcspeed8(int *spd)
static struct isa_pnp_id essc_ids[]
static struct pcmchan_caps ess_playcaps
static int ess_alloc_resources(struct ess_info *sc, device_t dev)
static void ess_wr(struct ess_info *sc, int reg, u_int8_t val)
MODULE_DEPEND(snd_ess, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER)
static void ess_setmixer(struct ess_info *sc, u_int port, u_int value)
static int mixer_setrecsrc(struct snd_mixer *mixer, u_int32_t src)
int mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
static int mixer_set(struct snd_mixer *m, u_int dev, u_int32_t muted, u_int lev)
void mix_setdevs(struct snd_mixer *m, u_int32_t v)
int mixer_reinit(device_t dev)
void * mix_getdevinfo(struct snd_mixer *m)
void mix_setrecdevs(struct snd_mixer *m, u_int32_t v)
Record mask of available recording devices.
void sbc_unlock(struct sbc_softc *)
void sbc_lock(struct sbc_softc *)
int sndbuf_dmasetup(struct snd_dbuf *b, struct resource *drq)
void sndbuf_dma(struct snd_dbuf *b, int go)
int sndbuf_dmaptr(struct snd_dbuf *b)
void pcm_setflags(device_t dev, uint32_t val)
void * pcm_getdevinfo(device_t dev)
uint32_t pcm_getflags(device_t dev)
int pcm_setstatus(device_t dev, char *str)
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 pcm_channel * channel
struct resource * io_base
bus_dma_tag_t parent_dmat
struct ess_chinfo pch rch