Put on my nuclear-grade asbestos suit and cvs rm the old, broken, sound
drivers (again). These drivers have not compiled for 5-6 months. Now that the new sound code supports MIDI, the major reason we had for reviving it is gone. It is a far better investment polishing the new midi code than trying to keep this on life support. Come 5.0-REL, if there are major shortcomings in the pcm sound driver then maybe we can rethink this, but until then we should focus on pcm. Remember, these have not been compilable since ~April-May this year.
This commit is contained in:
parent
98b829924f
commit
2da5dbec3e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=66522
@ -1815,7 +1815,6 @@ hint.gusc.0.irq="5"
|
||||
hint.gusc.0.drq="1"
|
||||
hint.gusc.0.flags="0x13"
|
||||
|
||||
# Not controlled by `snd'
|
||||
device pca
|
||||
hint.pca.0.at="isa"
|
||||
hint.pca.0.port="0x040"
|
||||
|
@ -156,7 +156,6 @@ gnu/i386/fpemul/wm_shrx.s optional gpl_math_emulate
|
||||
gnu/i386/fpemul/wm_sqrt.s optional gpl_math_emulate
|
||||
gnu/i386/isa/dgb.c count dgb
|
||||
gnu/i386/isa/dgm.c count dgm
|
||||
gnu/i386/isa/sound/awe_wave.c optional awe
|
||||
i386/apm/apm.c count apm
|
||||
i386/i386/atomic.c standard \
|
||||
compile-with "${CC} -c ${CFLAGS} ${DEFINED_PROF:S/^$/-fomit-frame-pointer/} ${.IMPSRC}"
|
||||
@ -269,69 +268,6 @@ i386/isa/prof_machdep.c optional profiling-routine
|
||||
i386/isa/rc.c count rc
|
||||
#i386/isa/rp.c optional rp
|
||||
i386/isa/scd.c count scd
|
||||
i386/isa/sound/ad1848.c optional css
|
||||
i386/isa/sound/ad1848.c optional gus
|
||||
i386/isa/sound/ad1848.c optional gusxvi
|
||||
i386/isa/sound/ad1848.c optional mss
|
||||
i386/isa/sound/ad1848.c optional sscape
|
||||
i386/isa/sound/ad1848.c optional sscape_mss
|
||||
i386/isa/sound/ad1848.c optional trix
|
||||
i386/isa/sound/adlib_card.c optional opl
|
||||
i386/isa/sound/adlib_card.c optional trix
|
||||
i386/isa/sound/audio.c optional snd \
|
||||
warning "The snd drivers are deprecated. Please see pcm/sbc/etc."
|
||||
i386/isa/sound/cs4232.c optional css
|
||||
i386/isa/sound/dev_table.c optional snd
|
||||
i386/isa/sound/dmabuf.c optional snd
|
||||
i386/isa/sound/gus_card.c optional gus
|
||||
i386/isa/sound/gus_midi.c optional gus
|
||||
i386/isa/sound/gus_vol.c optional gus
|
||||
i386/isa/sound/gus_wave.c optional gus
|
||||
i386/isa/sound/ics2101.c optional gus
|
||||
i386/isa/sound/midi_synth.c optional css
|
||||
i386/isa/sound/midi_synth.c optional gus
|
||||
i386/isa/sound/midi_synth.c optional mpu
|
||||
i386/isa/sound/midi_synth.c optional mss
|
||||
i386/isa/sound/midi_synth.c optional pas
|
||||
i386/isa/sound/midi_synth.c optional sb
|
||||
i386/isa/sound/midi_synth.c optional sscape
|
||||
i386/isa/sound/midi_synth.c optional uart
|
||||
i386/isa/sound/midibuf.c optional css
|
||||
i386/isa/sound/midibuf.c optional gus
|
||||
i386/isa/sound/midibuf.c optional mpu
|
||||
i386/isa/sound/midibuf.c optional mss
|
||||
i386/isa/sound/midibuf.c optional pas
|
||||
i386/isa/sound/midibuf.c optional sb
|
||||
i386/isa/sound/midibuf.c optional sscape
|
||||
i386/isa/sound/midibuf.c optional uart
|
||||
i386/isa/sound/mpu401.c optional mpu
|
||||
i386/isa/sound/mpu401.c optional sscape
|
||||
i386/isa/sound/opl3.c optional opl
|
||||
i386/isa/sound/opl3.c optional trix
|
||||
i386/isa/sound/pas2_card.c optional pas
|
||||
i386/isa/sound/pas2_midi.c optional pas
|
||||
i386/isa/sound/pas2_mixer.c optional pas
|
||||
i386/isa/sound/pas2_pcm.c optional pas
|
||||
i386/isa/sound/patmgr.c optional snd
|
||||
i386/isa/sound/sb16_dsp.c optional sbxvi
|
||||
i386/isa/sound/sb16_midi.c optional sbmidi
|
||||
i386/isa/sound/sb_card.c optional sb
|
||||
i386/isa/sound/sb_dsp.c optional sb
|
||||
i386/isa/sound/sb_midi.c optional sb
|
||||
i386/isa/sound/sb_mixer.c optional sb
|
||||
i386/isa/sound/sequencer.c optional snd
|
||||
i386/isa/sound/sound_switch.c optional snd
|
||||
i386/isa/sound/sound_timer.c optional css
|
||||
i386/isa/sound/sound_timer.c optional gus
|
||||
i386/isa/sound/sound_timer.c optional mss
|
||||
i386/isa/sound/sound_timer.c optional mss
|
||||
i386/isa/sound/sound_timer.c optional sscape
|
||||
i386/isa/sound/sound_timer.c optional trix
|
||||
i386/isa/sound/soundcard.c optional snd
|
||||
i386/isa/sound/sscape.c optional sscape
|
||||
i386/isa/sound/sys_timer.c optional snd
|
||||
i386/isa/sound/trix.c optional trix
|
||||
i386/isa/sound/uart6850.c optional uart
|
||||
i386/isa/spigot.c count spigot
|
||||
i386/isa/spkr.c optional speaker
|
||||
i386/isa/stallion.c optional stl
|
||||
|
@ -144,7 +144,6 @@ gnu/i386/fpemul/wm_shrx.s optional gpl_math_emulate
|
||||
gnu/i386/fpemul/wm_sqrt.s optional gpl_math_emulate
|
||||
gnu/i386/isa/dgb.c count dgb
|
||||
gnu/i386/isa/dgm.c count dgm
|
||||
gnu/i386/isa/sound/awe_wave.c optional awe
|
||||
i386/apm/apm.c count apm
|
||||
i386/i386/atomic.c standard \
|
||||
compile-with "${CC} -c ${CFLAGS} ${DEFINED_PROF:S/^$/-fomit-frame-pointer/} ${.IMPSRC}"
|
||||
@ -252,70 +251,6 @@ i386/isa/prof_machdep.c optional profiling-routine
|
||||
i386/isa/rc.c count rc
|
||||
#i386/isa/rp.c optional rp
|
||||
i386/isa/scd.c count scd
|
||||
i386/isa/sound/ad1848.c optional css
|
||||
i386/isa/sound/ad1848.c optional gus
|
||||
i386/isa/sound/ad1848.c optional gusxvi
|
||||
i386/isa/sound/ad1848.c optional mss
|
||||
i386/isa/sound/ad1848.c optional sscape
|
||||
i386/isa/sound/ad1848.c optional sscape_mss
|
||||
i386/isa/sound/ad1848.c optional trix
|
||||
i386/isa/sound/adlib_card.c optional opl
|
||||
i386/isa/sound/adlib_card.c optional trix
|
||||
i386/isa/sound/audio.c optional snd
|
||||
i386/isa/sound/cs4232.c optional css
|
||||
i386/isa/sound/dev_table.c optional snd
|
||||
i386/isa/sound/dmabuf.c optional snd
|
||||
i386/isa/sound/gus_card.c optional gus
|
||||
i386/isa/sound/gus_midi.c optional gus
|
||||
i386/isa/sound/gus_vol.c optional gus
|
||||
i386/isa/sound/gus_wave.c optional gus
|
||||
i386/isa/sound/ics2101.c optional gus
|
||||
i386/isa/sound/midi_synth.c optional css
|
||||
i386/isa/sound/midi_synth.c optional gus
|
||||
i386/isa/sound/midi_synth.c optional mpu
|
||||
i386/isa/sound/midi_synth.c optional mss
|
||||
i386/isa/sound/midi_synth.c optional pas
|
||||
i386/isa/sound/midi_synth.c optional sb
|
||||
i386/isa/sound/midi_synth.c optional sscape
|
||||
i386/isa/sound/midi_synth.c optional uart
|
||||
i386/isa/sound/midibuf.c optional css
|
||||
i386/isa/sound/midibuf.c optional gus
|
||||
i386/isa/sound/midibuf.c optional mpu
|
||||
i386/isa/sound/midibuf.c optional mss
|
||||
i386/isa/sound/midibuf.c optional nss
|
||||
i386/isa/sound/midibuf.c optional pas
|
||||
i386/isa/sound/midibuf.c optional sb
|
||||
i386/isa/sound/midibuf.c optional sscape
|
||||
i386/isa/sound/midibuf.c optional uart
|
||||
i386/isa/sound/mpu401.c optional mpu
|
||||
i386/isa/sound/mpu401.c optional sscape
|
||||
i386/isa/sound/opl3.c optional opl
|
||||
i386/isa/sound/opl3.c optional trix
|
||||
i386/isa/sound/pas2_card.c optional pas
|
||||
i386/isa/sound/pas2_midi.c optional pas
|
||||
i386/isa/sound/pas2_mixer.c optional pas
|
||||
i386/isa/sound/pas2_pcm.c optional pas
|
||||
i386/isa/sound/patmgr.c optional snd
|
||||
i386/isa/sound/pcm86.c optional nss
|
||||
i386/isa/sound/sb16_dsp.c optional sbxvi
|
||||
i386/isa/sound/sb16_midi.c optional sbmidi
|
||||
i386/isa/sound/sb_card.c optional sb
|
||||
i386/isa/sound/sb_dsp.c optional sb
|
||||
i386/isa/sound/sb_midi.c optional sb
|
||||
i386/isa/sound/sb_mixer.c optional sb
|
||||
i386/isa/sound/sequencer.c optional snd
|
||||
i386/isa/sound/sound_switch.c optional snd
|
||||
i386/isa/sound/sound_timer.c optional css
|
||||
i386/isa/sound/sound_timer.c optional gus
|
||||
i386/isa/sound/sound_timer.c optional mss
|
||||
i386/isa/sound/sound_timer.c optional mss
|
||||
i386/isa/sound/sound_timer.c optional sscape
|
||||
i386/isa/sound/sound_timer.c optional trix
|
||||
i386/isa/sound/soundcard.c optional snd
|
||||
i386/isa/sound/sscape.c optional sscape
|
||||
i386/isa/sound/sys_timer.c optional snd
|
||||
i386/isa/sound/trix.c optional trix
|
||||
i386/isa/sound/uart6850.c optional uart
|
||||
i386/isa/spigot.c count spigot
|
||||
i386/isa/stallion.c optional stl
|
||||
i386/isa/tw.c count tw
|
||||
|
@ -1,218 +0,0 @@
|
||||
/*
|
||||
* sound/awe_compat.h
|
||||
*
|
||||
* Compat defines for the AWE32/Sound Blaster 32 wave table synth. driver
|
||||
* version 0.4.2c; Oct. 7, 1997
|
||||
*
|
||||
* Copyright (C) 1996,1997 Takashi Iwai
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* compatibility macros for AWE32 driver
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
/* redefine following macros */
|
||||
#undef IOCTL_IN
|
||||
#undef IOCTL_OUT
|
||||
#undef OUTW
|
||||
#undef COPY_FROM_USER
|
||||
#undef COPY_TO_USER
|
||||
#undef GET_BYTE_FROM_USER
|
||||
#undef GET_SHORT_FROM_USER
|
||||
#undef IOCTL_TO_USER
|
||||
|
||||
#ifdef linux
|
||||
|
||||
/*================================================================
|
||||
* Linux macros
|
||||
*================================================================*/
|
||||
|
||||
/* use inline prefix */
|
||||
#define INLINE inline
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* memory management for linux
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
#ifdef AWE_OBSOLETE_VOXWARE
|
||||
/* old type linux system */
|
||||
|
||||
/* i/o requests; nothing */
|
||||
#define awe_check_port() 0 /* always false */
|
||||
#define awe_request_region() /* nothing */
|
||||
#define awe_release_region() /* nothing */
|
||||
|
||||
static int _mem_start; /* memory pointer for permanent buffers */
|
||||
|
||||
#define my_malloc_init(memptr) _mem_start = (memptr)
|
||||
#define my_malloc_memptr() _mem_start
|
||||
#define my_free(ptr) /* do nothing */
|
||||
#define my_realloc(buf,oldsize,size) NULL /* no realloc */
|
||||
|
||||
static void *my_malloc(int size)
|
||||
{
|
||||
char *ptr;
|
||||
PERMANENT_MALLOC(ptr, char*, size, _mem_start);
|
||||
return (void*)ptr;
|
||||
}
|
||||
|
||||
/* allocate buffer only once */
|
||||
#define INIT_TABLE(buffer,index,nums,type) {\
|
||||
buffer = my_malloc(sizeof(type) * (nums)); index = (nums);\
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define AWE_DYNAMIC_BUFFER
|
||||
|
||||
#define my_malloc_init(ptr) /* nothing */
|
||||
#define my_malloc_memptr() 0
|
||||
#define my_malloc(size) vmalloc(size)
|
||||
#define my_free(ptr) if (ptr) {vfree(ptr);}
|
||||
|
||||
static void *my_realloc(void *buf, int oldsize, int size)
|
||||
{
|
||||
void *ptr;
|
||||
if ((ptr = vmalloc(size)) == NULL)
|
||||
return NULL;
|
||||
memcpy(ptr, buf, ((oldsize < size) ? oldsize : size) );
|
||||
vfree(buf);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* do not allocate buffer at beginning */
|
||||
#define INIT_TABLE(buffer,index,nums,type) {buffer=NULL; index=0;}
|
||||
|
||||
/* old type macro */
|
||||
#define RET_ERROR(err) -err
|
||||
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* i/o interfaces for linux
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
#define OUTW(data,addr) outw(data, addr)
|
||||
|
||||
#ifdef AWE_NEW_KERNEL_INTERFACE
|
||||
#define COPY_FROM_USER(target,source,offs,count) \
|
||||
copy_from_user(target, (source)+(offs), count)
|
||||
#define GET_BYTE_FROM_USER(target,addr,offs) \
|
||||
get_user(target, (unsigned char*)&((addr)[offs]))
|
||||
#define GET_SHORT_FROM_USER(target,addr,offs) \
|
||||
get_user(target, (unsigned short*)&((addr)[offs]))
|
||||
#ifdef AWE_OSS38
|
||||
#define IOCTL_TO_USER(target,offs,source,count) \
|
||||
memcpy(target, (source)+(offs), count)
|
||||
#define IO_WRITE_CHECK(cmd) (_SIOC_DIR(cmd) & _IOC_WRITE)
|
||||
#else
|
||||
#define IOCTL_TO_USER(target,offs,source,count) \
|
||||
copy_to_user(target, (source)+(offs), count)
|
||||
#define IO_WRITE_CHECK(cmd) (_IOC_DIR(cmd) & _IOC_WRITE)
|
||||
#endif /* AWE_OSS38 */
|
||||
#define COPY_TO_USER IOCTL_TO_USER
|
||||
#define IOCTL_IN(arg) (*(int*)(arg))
|
||||
#define IOCTL_OUT(arg,val) (*(int*)(arg) = (val))
|
||||
|
||||
#else /* old type i/o */
|
||||
#define COPY_FROM_USER(target,source,offs,count) \
|
||||
memcpy_fromfs(target, (source)+(offs), (count))
|
||||
#define GET_BYTE_FROM_USER(target,addr,offs) \
|
||||
*((char *)&(target)) = get_fs_byte((addr)+(offs))
|
||||
#define GET_SHORT_FROM_USER(target,addr,offs) \
|
||||
*((short *)&(target)) = get_fs_word((addr)+(offs))
|
||||
#define IOCTL_TO_USER(target,offs,source,count) \
|
||||
memcpy_tofs(target, (source)+(offs), (count))
|
||||
#define COPY_TO_USER IOCTL_TO_USER
|
||||
#define IO_WRITE_CHECK(cmd) (cmd & IOC_IN)
|
||||
#define IOCTL_IN(arg) get_fs_long((long *)(arg))
|
||||
#define IOCTL_OUT(arg,ret) snd_ioctl_return((int *)arg, ret)
|
||||
|
||||
#endif /* AWE_NEW_KERNEL_INTERFACE */
|
||||
|
||||
#define BZERO(target,len) memset(target, 0, len)
|
||||
#define MEMCPY(dst,src,len) memcpy(dst, src, len)
|
||||
|
||||
|
||||
#elif defined(__FreeBSD__)
|
||||
|
||||
/*================================================================
|
||||
* FreeBSD macros
|
||||
*================================================================*/
|
||||
|
||||
/* inline is not checked yet.. maybe it'll work */
|
||||
#define INLINE /*inline*/
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* memory management for freebsd
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
/* i/o requests; nothing */
|
||||
#define awe_check_port() 0 /* always false */
|
||||
#define awe_request_region() /* nothing */
|
||||
#define awe_release_region() /* nothing */
|
||||
|
||||
#define AWE_DYNAMIC_BUFFER
|
||||
|
||||
#define my_malloc_init(ptr) /* nothing */
|
||||
#define my_malloc_memptr() 0
|
||||
#define my_malloc(size) malloc(size, M_TEMP, M_WAITOK)
|
||||
#define my_free(ptr) if (ptr) {free(ptr, M_TEMP);}
|
||||
|
||||
#define INIT_TABLE(buffer,index,nums,type) {buffer=NULL; index=0;}
|
||||
|
||||
/* it should be realloc? */
|
||||
static void *my_realloc(void *buf, int oldsize, int size)
|
||||
{
|
||||
void *ptr;
|
||||
if ((ptr = my_malloc(size)) == NULL)
|
||||
return NULL;
|
||||
memcpy(ptr, buf, ((oldsize < size) ? oldsize : size) );
|
||||
my_free(buf);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* i/o interfaces for freebsd
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
/* according to linux rule; the arguments are swapped */
|
||||
#define OUTW(data,addr) outw(addr, data)
|
||||
|
||||
#define COPY_FROM_USER(target,source,offs,count) \
|
||||
uiomove(((caddr_t)(target)),(count),((struct uio *)(source)))
|
||||
#define COPY_TO_USER(target,source,offs,count) \
|
||||
uiomove(((caddr_t)(source)),(count),((struct uio *)(target)))
|
||||
#define GET_BYTE_FROM_USER(target,addr,offs) \
|
||||
uiomove(((char*)&(target)), 1, ((struct uio *)(addr)))
|
||||
#define GET_SHORT_FROM_USER(target,addr,offs) \
|
||||
uiomove(((char*)&(target)), 2, ((struct uio *)(addr)))
|
||||
#define IOCTL_TO_USER(target,offs,source,count) \
|
||||
memcpy(&((target)[offs]), (source), (count))
|
||||
#define IO_WRITE_CHECK(cmd) (cmd & IOC_IN)
|
||||
#define IOCTL_IN(arg) (*(int*)(arg))
|
||||
#define IOCTL_OUT(arg,val) (*(int*)(arg) = (val))
|
||||
#define BZERO(target,len) bzero((caddr_t)target, len)
|
||||
#define MEMCPY(dst,src,len) bcopy((caddr_t)src, (caddr_t)dst, len)
|
||||
|
||||
#ifndef AWE_OBSOLETE_VOXWARE
|
||||
# define printk printf
|
||||
# define RET_ERROR(err) -err
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,149 +0,0 @@
|
||||
/*
|
||||
* sound/awe_config.h
|
||||
*
|
||||
* Configuration of AWE32 sound driver
|
||||
* version 0.4.2; Sep. 15, 1997
|
||||
*
|
||||
* Copyright (C) 1996 Takashi Iwai
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef AWE_CONFIG_H_DEF
|
||||
#define AWE_CONFIG_H_DEF
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* system configuration
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
/* if you're using obsolete VoxWare 3.0.x on Linux 1.2.x (or pre-Voxware 3.5
|
||||
* versions of FreeBSD), define the following line.
|
||||
*/
|
||||
#undef AWE_OBSOLETE_VOXWARE
|
||||
|
||||
/* if you're using OSS-Lite on Linux 2.1.6 or later, define the
|
||||
* following line.
|
||||
*/
|
||||
#undef AWE_NEW_KERNEL_INTERFACE
|
||||
|
||||
/* if you have lowlevel.h in the lowlevel directory (OSS-Lite), define
|
||||
* the following line.
|
||||
*/
|
||||
#undef HAS_LOWLEVEL_H
|
||||
|
||||
/* if your system doesn't support patch manager (OSS 3.7 or newer),
|
||||
* define the following line.
|
||||
*/
|
||||
#undef AWE_NO_PATCHMGR
|
||||
|
||||
/* if your system has an additional parameter (OSS 3.8b5 or newer),
|
||||
* define this.
|
||||
*/
|
||||
#undef AWE_OSS38
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* AWE32 card configuration:
|
||||
* uncomment the following lines only when auto detection doesn't
|
||||
* work properly on your machine.
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
/*#define AWE_DEFAULT_BASE_ADDR 0x620*/ /* base port address */
|
||||
/*#define AWE_DEFAULT_MEM_SIZE 512*/ /* kbytes */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* maximum size of soundfont list table:
|
||||
* you usually don't need to touch this value.
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
#define AWE_MAX_SF_LISTS 16
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* chunk size of sample and voice tables:
|
||||
* you usually don't need to touch these values.
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
#define AWE_MAX_SAMPLES 400
|
||||
#define AWE_MAX_INFOS 800
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* chorus & reverb effects send for FM chip: from 0 to 0xff
|
||||
* larger numbers often cause weird sounds.
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
#define DEF_FM_CHORUS_DEPTH 0x10
|
||||
#define DEF_FM_REVERB_DEPTH 0x10
|
||||
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* other compile conditions
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
/* initialize FM passthrough even without extended RAM */
|
||||
#undef AWE_ALWAYS_INIT_FM
|
||||
|
||||
/* debug on */
|
||||
#define AWE_DEBUG_ON
|
||||
|
||||
/* GUS compatible mode */
|
||||
#define AWE_HAS_GUS_COMPATIBILITY
|
||||
|
||||
/* accept all notes/sounds off controls */
|
||||
#define AWE_ACCEPT_ALL_SOUNDS_CONTROL
|
||||
|
||||
/* add mixer control of emu8000 equalizer */
|
||||
#define CONFIG_AWE32_MIXER
|
||||
|
||||
/* look up voices according to MIDI channel priority */
|
||||
#define AWE_LOOKUP_MIDI_PRIORITY
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
/* reading configuration of sound driver */
|
||||
|
||||
#ifdef AWE_OBSOLETE_VOXWARE
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
# include <i386/isa/sound/sound_config.h>
|
||||
#else
|
||||
# include "sound_config.h"
|
||||
#endif
|
||||
|
||||
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_AWE32)
|
||||
#define CONFIG_AWE32_SYNTH
|
||||
#endif
|
||||
|
||||
#else /* AWE_OBSOLETE_VOXWARE */
|
||||
|
||||
#ifdef HAS_LOWLEVEL_H
|
||||
#include "lowlevel.h"
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
# include <i386/isa/sound/sound_config.h>
|
||||
# if defined(CONFIGURE_SOUNDCARD) && defined(CONFIG_AWE32)
|
||||
# define CONFIG_AWE32_SYNTH
|
||||
# endif
|
||||
#else
|
||||
# include "../sound_config.h"
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* AWE_OBSOLETE_VOXWARE */
|
||||
|
||||
|
||||
#endif /* AWE_CONFIG_H_DEF */
|
@ -1,100 +0,0 @@
|
||||
/*
|
||||
* sound/awe_hw.h
|
||||
*
|
||||
* Access routines and definitions for the low level driver for the
|
||||
* AWE32/Sound Blaster 32 wave table synth.
|
||||
* version 0.4.2; Sep. 15, 1997
|
||||
*
|
||||
* Copyright (C) 1996,1997 Takashi Iwai
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef AWE_HW_H_DEF
|
||||
#define AWE_HW_H_DEF
|
||||
|
||||
/*
|
||||
* Emu-8000 control registers
|
||||
* name(channel) reg, port
|
||||
*/
|
||||
|
||||
#define awe_cmd_idx(reg,ch) (((reg)<< 5) | (ch))
|
||||
|
||||
#define Data0 0x620 /* doubleword r/w */
|
||||
#define Data1 0xA20 /* doubleword r/w */
|
||||
#define Data2 0xA22 /* word r/w */
|
||||
#define Data3 0xE20 /* word r/w */
|
||||
#define Pointer 0xE22 /* register pointer r/w */
|
||||
|
||||
#define AWE_CPF(ch) awe_cmd_idx(0,ch), Data0 /* DW: current pitch and fractional address */
|
||||
#define AWE_PTRX(ch) awe_cmd_idx(1,ch), Data0 /* DW: pitch target and reverb send */
|
||||
#define AWE_CVCF(ch) awe_cmd_idx(2,ch), Data0 /* DW: current volume and filter cutoff */
|
||||
#define AWE_VTFT(ch) awe_cmd_idx(3,ch), Data0 /* DW: volume and filter cutoff targets */
|
||||
#define AWE_PSST(ch) awe_cmd_idx(6,ch), Data0 /* DW: pan send and loop start address */
|
||||
#define AWE_CSL(ch) awe_cmd_idx(7,ch), Data0 /* DW: chorus send and loop end address */
|
||||
#define AWE_CCCA(ch) awe_cmd_idx(0,ch), Data1 /* DW: Q, control bits, and current address */
|
||||
#define AWE_HWCF4 awe_cmd_idx(1,9), Data1 /* DW: config dw 4 */
|
||||
#define AWE_HWCF5 awe_cmd_idx(1,10), Data1 /* DW: config dw 5 */
|
||||
#define AWE_HWCF6 awe_cmd_idx(1,13), Data1 /* DW: config dw 6 */
|
||||
#define AWE_HWCF7 awe_cmd_idx(1,14), Data1 /* DW: config dw 7? (not documented) */
|
||||
#define AWE_SMALR awe_cmd_idx(1,20), Data1 /* DW: sound memory address for left read */
|
||||
#define AWE_SMARR awe_cmd_idx(1,21), Data1 /* DW: for right read */
|
||||
#define AWE_SMALW awe_cmd_idx(1,22), Data1 /* DW: sound memory address for left write */
|
||||
#define AWE_SMARW awe_cmd_idx(1,23), Data1 /* DW: for right write */
|
||||
#define AWE_SMLD awe_cmd_idx(1,26), Data1 /* W: sound memory left data */
|
||||
#define AWE_SMRD awe_cmd_idx(1,26), Data2 /* W: right data */
|
||||
#define AWE_WC awe_cmd_idx(1,27), Data2 /* W: sample counter */
|
||||
#define AWE_WC_Cmd awe_cmd_idx(1,27)
|
||||
#define AWE_WC_Port Data2
|
||||
#define AWE_HWCF1 awe_cmd_idx(1,29), Data1 /* W: config w 1 */
|
||||
#define AWE_HWCF2 awe_cmd_idx(1,30), Data1 /* W: config w 2 */
|
||||
#define AWE_HWCF3 awe_cmd_idx(1,31), Data1 /* W: config w 3 */
|
||||
#define AWE_INIT1(ch) awe_cmd_idx(2,ch), Data1 /* W: init array 1 */
|
||||
#define AWE_INIT2(ch) awe_cmd_idx(2,ch), Data2 /* W: init array 2 */
|
||||
#define AWE_INIT3(ch) awe_cmd_idx(3,ch), Data1 /* W: init array 3 */
|
||||
#define AWE_INIT4(ch) awe_cmd_idx(3,ch), Data2 /* W: init array 4 */
|
||||
#define AWE_ENVVOL(ch) awe_cmd_idx(4,ch), Data1 /* W: volume envelope delay */
|
||||
#define AWE_DCYSUSV(ch) awe_cmd_idx(5,ch), Data1 /* W: volume envelope sustain and decay */
|
||||
#define AWE_ENVVAL(ch) awe_cmd_idx(6,ch), Data1 /* W: modulation envelope delay */
|
||||
#define AWE_DCYSUS(ch) awe_cmd_idx(7,ch), Data1 /* W: modulation envelope sustain and decay */
|
||||
#define AWE_ATKHLDV(ch) awe_cmd_idx(4,ch), Data2 /* W: volume envelope attack and hold */
|
||||
#define AWE_LFO1VAL(ch) awe_cmd_idx(5,ch), Data2 /* W: LFO#1 Delay */
|
||||
#define AWE_ATKHLD(ch) awe_cmd_idx(6,ch), Data2 /* W: modulation envelope attack and hold */
|
||||
#define AWE_LFO2VAL(ch) awe_cmd_idx(7,ch), Data2 /* W: LFO#2 Delay */
|
||||
#define AWE_IP(ch) awe_cmd_idx(0,ch), Data3 /* W: initial pitch */
|
||||
#define AWE_IFATN(ch) awe_cmd_idx(1,ch), Data3 /* W: initial filter cutoff and attenuation */
|
||||
#define AWE_PEFE(ch) awe_cmd_idx(2,ch), Data3 /* W: pitch and filter envelope heights */
|
||||
#define AWE_FMMOD(ch) awe_cmd_idx(3,ch), Data3 /* W: vibrato and filter modulation freq */
|
||||
#define AWE_TREMFRQ(ch) awe_cmd_idx(4,ch), Data3 /* W: LFO#1 tremolo amount and freq */
|
||||
#define AWE_FM2FRQ2(ch) awe_cmd_idx(5,ch), Data3 /* W: LFO#2 vibrato amount and freq */
|
||||
|
||||
/* used during detection (returns ROM version?; not documented in ADIP) */
|
||||
#define AWE_U1 0xE0, Data3 /* (R)(W) used in initialization */
|
||||
#define AWE_U2(ch) 0xC0+(ch), Data3 /* (W)(W) used in init envelope */
|
||||
|
||||
|
||||
#define AWE_MAX_VOICES 32
|
||||
#define AWE_NORMAL_VOICES 30 /*30&31 are reserved for DRAM refresh*/
|
||||
|
||||
#define AWE_MAX_CHANNELS 32 /* max midi channels (must >= voices) */
|
||||
#define AWE_MAX_LAYERS AWE_MAX_VOICES /* maximum number of multiple layers */
|
||||
|
||||
#define AWE_DRAM_OFFSET 0x200000
|
||||
#define AWE_MAX_DRAM_SIZE (28 * 1024) /* 28 MB is max onboard memory */
|
||||
|
||||
#define AWE_DEFAULT_ATTENUATION 32 /* 12dB below */
|
||||
#define AWE_DEFAULT_MOD_SENSE 18
|
||||
|
||||
#endif
|
@ -1,35 +0,0 @@
|
||||
/*
|
||||
* sound/awe_version.h
|
||||
*
|
||||
* Version defines for the AWE32/Sound Blaster 32 wave table synth driver.
|
||||
* version 0.4.2c; Oct. 7, 1997
|
||||
*
|
||||
* Copyright (C) 1996,1997 Takashi Iwai
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* AWE32 driver version number */
|
||||
|
||||
#ifndef AWE_VERSION_H_DEF
|
||||
#define AWE_VERSION_H_DEF
|
||||
|
||||
#define AWE_VERSION_NUMBER 0x00040203
|
||||
#define AWEDRV_VERSION "0.4.2c"
|
||||
#define AWE_MAJOR_VERSION(id) (((id) >> 16) & 0xff)
|
||||
#define AWE_MINOR_VERSION(id) (((id) >> 8) & 0xff)
|
||||
#define AWE_TINY_VERSION(id) ((id) & 0xff)
|
||||
|
||||
#endif
|
@ -1,490 +0,0 @@
|
||||
/*
|
||||
* sound/awe_voice.h
|
||||
*
|
||||
* Voice information definitions for the low level driver for the
|
||||
* AWE32/Sound Blaster 32 wave table synth.
|
||||
* version 0.4.2c; Oct. 7, 1997
|
||||
*
|
||||
* Copyright (C) 1996,1997 Takashi Iwai
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef AWE_VOICE_H
|
||||
#define AWE_VOICE_H
|
||||
|
||||
#ifndef SAMPLE_TYPE_AWE32
|
||||
#define SAMPLE_TYPE_AWE32 0x20
|
||||
#endif
|
||||
|
||||
#ifndef _PATCHKEY
|
||||
#define _PATCHKEY(id) ((id<<8)|0xfd)
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* patch information record
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
/* patch interface header: 16 bytes */
|
||||
typedef struct awe_patch_info {
|
||||
short key; /* use AWE_PATCH here */
|
||||
#define AWE_PATCH _PATCHKEY(0x07)
|
||||
|
||||
short device_no; /* synthesizer number */
|
||||
unsigned short sf_id; /* file id (should be zero) */
|
||||
short optarg; /* optional argument */
|
||||
int len; /* data length (without this header) */
|
||||
|
||||
short type; /* patch operation type */
|
||||
#define AWE_LOAD_INFO 0 /* awe_voice_rec */
|
||||
#define AWE_LOAD_DATA 1 /* awe_sample_info */
|
||||
#define AWE_OPEN_PATCH 2 /* awe_open_parm */
|
||||
#define AWE_CLOSE_PATCH 3 /* none */
|
||||
#define AWE_UNLOAD_PATCH 4 /* none */
|
||||
#define AWE_REPLACE_DATA 5 /* awe_sample_info (optarg=#channels)*/
|
||||
#define AWE_MAP_PRESET 6 /* awe_voice_map */
|
||||
#define AWE_LOAD_CHORUS_FX 0x10 /* awe_chorus_fx_rec (optarg=mode) */
|
||||
#define AWE_LOAD_REVERB_FX 0x11 /* awe_reverb_fx_rec (optarg=mode) */
|
||||
|
||||
short reserved; /* word alignment data */
|
||||
|
||||
/* the actual patch data begins after this */
|
||||
#if defined(AWE_COMPAT_030) && AWE_COMPAT_030
|
||||
char data[0];
|
||||
#endif
|
||||
} awe_patch_info;
|
||||
|
||||
/*#define AWE_PATCH_INFO_SIZE 16*/
|
||||
#define AWE_PATCH_INFO_SIZE sizeof(awe_patch_info)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* open patch
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
#define AWE_PATCH_NAME_LEN 32
|
||||
|
||||
typedef struct _awe_open_parm {
|
||||
unsigned short type; /* sample type */
|
||||
#define AWE_PAT_TYPE_MISC 0
|
||||
#define AWE_PAT_TYPE_GM 1
|
||||
#define AWE_PAT_TYPE_GS 2
|
||||
#define AWE_PAT_TYPE_MT32 3
|
||||
#define AWE_PAT_TYPE_XG 4
|
||||
#define AWE_PAT_TYPE_SFX 5
|
||||
#define AWE_PAT_TYPE_GUS 6
|
||||
#define AWE_PAT_TYPE_MAP 7
|
||||
|
||||
#define AWE_PAT_LOCKED 0x100 /* lock the samples */
|
||||
|
||||
short reserved;
|
||||
char name[AWE_PATCH_NAME_LEN];
|
||||
} awe_open_parm;
|
||||
|
||||
/*#define AWE_OPEN_PARM_SIZE 28*/
|
||||
#define AWE_OPEN_PARM_SIZE sizeof(awe_open_parm)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* raw voice information record
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
/* wave table envelope & effect parameters to control EMU8000 */
|
||||
typedef struct _awe_voice_parm {
|
||||
unsigned short moddelay; /* modulation delay (0x8000) */
|
||||
unsigned short modatkhld; /* modulation attack & hold time (0x7f7f) */
|
||||
unsigned short moddcysus; /* modulation decay & sustain (0x7f7f) */
|
||||
unsigned short modrelease; /* modulation release time (0x807f) */
|
||||
short modkeyhold, modkeydecay; /* envelope change per key (not used) */
|
||||
unsigned short voldelay; /* volume delay (0x8000) */
|
||||
unsigned short volatkhld; /* volume attack & hold time (0x7f7f) */
|
||||
unsigned short voldcysus; /* volume decay & sustain (0x7f7f) */
|
||||
unsigned short volrelease; /* volume release time (0x807f) */
|
||||
short volkeyhold, volkeydecay; /* envelope change per key (not used) */
|
||||
unsigned short lfo1delay; /* LFO1 delay (0x8000) */
|
||||
unsigned short lfo2delay; /* LFO2 delay (0x8000) */
|
||||
unsigned short pefe; /* modulation pitch & cutoff (0x0000) */
|
||||
unsigned short fmmod; /* LFO1 pitch & cutoff (0x0000) */
|
||||
unsigned short tremfrq; /* LFO1 volume & freq (0x0000) */
|
||||
unsigned short fm2frq2; /* LFO2 pitch & freq (0x0000) */
|
||||
unsigned char cutoff; /* initial cutoff (0xff) */
|
||||
unsigned char filterQ; /* initial filter Q [0-15] (0x0) */
|
||||
unsigned char chorus; /* chorus send (0x00) */
|
||||
unsigned char reverb; /* reverb send (0x00) */
|
||||
unsigned short reserved[4]; /* not used */
|
||||
} awe_voice_parm;
|
||||
|
||||
#define AWE_VOICE_PARM_SIZE 48
|
||||
|
||||
|
||||
/* wave table parameters: 92 bytes */
|
||||
typedef struct _awe_voice_info {
|
||||
unsigned short sf_id; /* file id (should be zero) */
|
||||
unsigned short sample; /* sample id */
|
||||
int start, end; /* sample offset correction */
|
||||
int loopstart, loopend; /* loop offset correction */
|
||||
short rate_offset; /* sample rate pitch offset */
|
||||
unsigned short mode; /* sample mode */
|
||||
#define AWE_MODE_ROMSOUND 0x8000
|
||||
#define AWE_MODE_STEREO 1
|
||||
#define AWE_MODE_LOOPING 2
|
||||
#define AWE_MODE_NORELEASE 4 /* obsolete */
|
||||
#define AWE_MODE_INIT_PARM 8
|
||||
|
||||
short root; /* midi root key */
|
||||
short tune; /* pitch tuning (in cents) */
|
||||
char low, high; /* key note range */
|
||||
char vellow, velhigh; /* velocity range */
|
||||
char fixkey, fixvel; /* fixed key, velocity */
|
||||
char pan, fixpan; /* panning, fixed panning */
|
||||
short exclusiveClass; /* exclusive class (0 = none) */
|
||||
unsigned char amplitude; /* sample volume (127 max) */
|
||||
unsigned char attenuation; /* attenuation (0.375dB) */
|
||||
short scaleTuning; /* pitch scale tuning(%), normally 100 */
|
||||
awe_voice_parm parm; /* voice envelope parameters */
|
||||
short index; /* internal index (set by driver) */
|
||||
} awe_voice_info;
|
||||
|
||||
/*#define AWE_VOICE_INFO_SIZE 92*/
|
||||
#define AWE_VOICE_INFO_SIZE sizeof(awe_voice_info)
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
/* The info entry of awe_voice_rec is changed from 0 to 1
|
||||
* for some compilers refusing zero size array.
|
||||
* Due to this change, sizeof(awe_voice_rec) becomes different
|
||||
* from older versions.
|
||||
* Use AWE_VOICE_REC_SIZE instead.
|
||||
*/
|
||||
|
||||
/* instrument info header: 4 bytes */
|
||||
typedef struct _awe_voice_rec_hdr {
|
||||
unsigned char bank; /* midi bank number */
|
||||
unsigned char instr; /* midi preset number */
|
||||
char nvoices; /* number of voices */
|
||||
char write_mode; /* write mode; normally 0 */
|
||||
#define AWE_WR_APPEND 0 /* append anyway */
|
||||
#define AWE_WR_EXCLUSIVE 1 /* skip if already exists */
|
||||
#define AWE_WR_REPLACE 2 /* replace if already exists */
|
||||
} awe_voice_rec_hdr;
|
||||
|
||||
/*#define AWE_VOICE_REC_SIZE 4*/
|
||||
#define AWE_VOICE_REC_SIZE sizeof(awe_voice_rec_hdr)
|
||||
|
||||
/* the standard patch structure for one sample */
|
||||
typedef struct _awe_voice_rec_patch {
|
||||
awe_patch_info patch;
|
||||
awe_voice_rec_hdr hdr;
|
||||
awe_voice_info info;
|
||||
} awe_voice_rec_patch;
|
||||
|
||||
|
||||
/* obsolete data type */
|
||||
#if defined(AWE_COMPAT_030) && AWE_COMPAT_030
|
||||
#define AWE_INFOARRAY_SIZE 0
|
||||
#else
|
||||
#define AWE_INFOARRAY_SIZE 1
|
||||
#endif
|
||||
|
||||
typedef struct _awe_voice_rec {
|
||||
unsigned char bank; /* midi bank number */
|
||||
unsigned char instr; /* midi preset number */
|
||||
short nvoices; /* number of voices */
|
||||
/* voice information follows here */
|
||||
awe_voice_info info[AWE_INFOARRAY_SIZE];
|
||||
} awe_voice_rec;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* sample wave information
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
/* wave table sample header: 32 bytes */
|
||||
typedef struct awe_sample_info {
|
||||
unsigned short sf_id; /* file id (should be zero) */
|
||||
unsigned short sample; /* sample id */
|
||||
int start, end; /* start & end offset */
|
||||
int loopstart, loopend; /* loop start & end offset */
|
||||
int size; /* size (0 = ROM) */
|
||||
short checksum_flag; /* use check sum = 1 */
|
||||
unsigned short mode_flags; /* mode flags */
|
||||
#define AWE_SAMPLE_8BITS 1 /* wave data is 8bits */
|
||||
#define AWE_SAMPLE_UNSIGNED 2 /* wave data is unsigned */
|
||||
#define AWE_SAMPLE_NO_BLANK 4 /* no blank loop is attached */
|
||||
#define AWE_SAMPLE_SINGLESHOT 8 /* single-shot w/o loop */
|
||||
#define AWE_SAMPLE_BIDIR_LOOP 16 /* bidirectional looping */
|
||||
#define AWE_SAMPLE_STEREO_LEFT 32 /* stereo left sound */
|
||||
#define AWE_SAMPLE_STEREO_RIGHT 64 /* stereo right sound */
|
||||
#define AWE_SAMPLE_REVERSE_LOOP 128 /* reverse looping */
|
||||
unsigned int checksum; /* check sum */
|
||||
#if defined(AWE_COMPAT_030) && AWE_COMPAT_030
|
||||
unsigned short data[0]; /* sample data follows here */
|
||||
#endif
|
||||
} awe_sample_info;
|
||||
|
||||
/*#define AWE_SAMPLE_INFO_SIZE 32*/
|
||||
#define AWE_SAMPLE_INFO_SIZE sizeof(awe_sample_info)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* voice preset mapping
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
typedef struct awe_voice_map {
|
||||
int map_bank, map_instr, map_key; /* key = -1 means all keys */
|
||||
int src_bank, src_instr, src_key;
|
||||
} awe_voice_map;
|
||||
|
||||
#define AWE_VOICE_MAP_SIZE sizeof(awe_voice_map)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* awe hardware controls
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
#define _AWE_DEBUG_MODE 0x00
|
||||
#define _AWE_REVERB_MODE 0x01
|
||||
#define _AWE_CHORUS_MODE 0x02
|
||||
#define _AWE_REMOVE_LAST_SAMPLES 0x03
|
||||
#define _AWE_INITIALIZE_CHIP 0x04
|
||||
#define _AWE_SEND_EFFECT 0x05
|
||||
#define _AWE_TERMINATE_CHANNEL 0x06
|
||||
#define _AWE_TERMINATE_ALL 0x07
|
||||
#define _AWE_INITIAL_VOLUME 0x08
|
||||
#define _AWE_INITIAL_ATTEN _AWE_INITIAL_VOLUME
|
||||
#define _AWE_RESET_CHANNEL 0x09
|
||||
#define _AWE_CHANNEL_MODE 0x0a
|
||||
#define _AWE_DRUM_CHANNELS 0x0b
|
||||
#define _AWE_MISC_MODE 0x0c
|
||||
#define _AWE_RELEASE_ALL 0x0d
|
||||
#define _AWE_NOTEOFF_ALL 0x0e
|
||||
#define _AWE_CHN_PRESSURE 0x0f
|
||||
/*#define _AWE_GET_CURRENT_MODE 0x10*/
|
||||
#define _AWE_EQUALIZER 0x11
|
||||
/*#define _AWE_GET_MISC_MODE 0x12*/
|
||||
/*#define _AWE_GET_FONTINFO 0x13*/
|
||||
|
||||
#define _AWE_MODE_FLAG 0x80
|
||||
#define _AWE_COOKED_FLAG 0x40 /* not supported */
|
||||
#define _AWE_MODE_VALUE_MASK 0x3F
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
#define _AWE_SET_CMD(p,dev,voice,cmd,p1,p2) \
|
||||
{((char*)(p))[0] = SEQ_PRIVATE;\
|
||||
((char*)(p))[1] = dev;\
|
||||
((char*)(p))[2] = _AWE_MODE_FLAG|(cmd);\
|
||||
((char*)(p))[3] = voice;\
|
||||
((unsigned short*)(p))[2] = p1;\
|
||||
((unsigned short*)(p))[3] = p2;}
|
||||
|
||||
/* buffered access */
|
||||
#define _AWE_CMD(dev, voice, cmd, p1, p2) \
|
||||
{_SEQ_NEEDBUF(8);\
|
||||
_AWE_SET_CMD(_seqbuf + _seqbufptr, dev, voice, cmd, p1, p2);\
|
||||
_SEQ_ADVBUF(8);}
|
||||
|
||||
/* direct access */
|
||||
#define _AWE_CMD_NOW(seqfd,dev,voice,cmd,p1,p2) \
|
||||
{struct seq_event_rec tmp;\
|
||||
_AWE_SET_CMD(&tmp, dev, voice, cmd, p1, p2);\
|
||||
ioctl(seqfd, SNDCTL_SEQ_OUTOFBAND, &tmp);}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
/* set debugging mode */
|
||||
#define AWE_DEBUG_MODE(dev,p1) _AWE_CMD(dev, 0, _AWE_DEBUG_MODE, p1, 0)
|
||||
/* set reverb mode; from 0 to 7 */
|
||||
#define AWE_REVERB_MODE(dev,p1) _AWE_CMD(dev, 0, _AWE_REVERB_MODE, p1, 0)
|
||||
/* set chorus mode; from 0 to 7 */
|
||||
#define AWE_CHORUS_MODE(dev,p1) _AWE_CMD(dev, 0, _AWE_CHORUS_MODE, p1, 0)
|
||||
|
||||
/* reset channel */
|
||||
#define AWE_RESET_CHANNEL(dev,ch) _AWE_CMD(dev, ch, _AWE_RESET_CHANNEL, 0, 0)
|
||||
#define AWE_RESET_CONTROL(dev,ch) _AWE_CMD(dev, ch, _AWE_RESET_CHANNEL, 1, 0)
|
||||
|
||||
/* send an effect to all layers */
|
||||
#define AWE_SEND_EFFECT(dev,voice,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,type,value)
|
||||
#define AWE_ADD_EFFECT(dev,voice,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((type)|0x80),value)
|
||||
#define AWE_UNSET_EFFECT(dev,voice,type) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((type)|0x40),0)
|
||||
/* send an effect to a layer */
|
||||
#define AWE_SEND_LAYER_EFFECT(dev,voice,layer,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((layer+1)<<8|(type)),value)
|
||||
#define AWE_ADD_LAYER_EFFECT(dev,voice,layer,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((layer+1)<<8|(type)|0x80),value)
|
||||
#define AWE_UNSET_LAYER_EFFECT(dev,voice,layer,type) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((layer+1)<<8|(type)|0x40),0)
|
||||
|
||||
/* terminate sound on the channel/voice */
|
||||
#define AWE_TERMINATE_CHANNEL(dev,voice) _AWE_CMD(dev,voice,_AWE_TERMINATE_CHANNEL,0,0)
|
||||
/* terminate all sounds */
|
||||
#define AWE_TERMINATE_ALL(dev) _AWE_CMD(dev, 0, _AWE_TERMINATE_ALL, 0, 0)
|
||||
/* release all sounds (w/o sustain effect) */
|
||||
#define AWE_RELEASE_ALL(dev) _AWE_CMD(dev, 0, _AWE_RELEASE_ALL, 0, 0)
|
||||
/* note off all sounds (w sustain effect) */
|
||||
#define AWE_NOTEOFF_ALL(dev) _AWE_CMD(dev, 0, _AWE_NOTEOFF_ALL, 0, 0)
|
||||
|
||||
/* set initial attenuation */
|
||||
#define AWE_INITIAL_VOLUME(dev,atten) _AWE_CMD(dev, 0, _AWE_INITIAL_VOLUME, atten, 0)
|
||||
#define AWE_INITIAL_ATTEN AWE_INITIAL_VOLUME
|
||||
/* relative attenuation */
|
||||
#define AWE_SET_ATTEN(dev,atten) _AWE_CMD(dev, 0, _AWE_INITIAL_VOLUME, atten, 1)
|
||||
|
||||
/* set channel playing mode; mode=0/1/2 */
|
||||
#define AWE_SET_CHANNEL_MODE(dev,mode) _AWE_CMD(dev, 0, _AWE_CHANNEL_MODE, mode, 0)
|
||||
#define AWE_PLAY_INDIRECT 0 /* indirect voice mode (default) */
|
||||
#define AWE_PLAY_MULTI 1 /* multi note voice mode */
|
||||
#define AWE_PLAY_DIRECT 2 /* direct single voice mode */
|
||||
#define AWE_PLAY_MULTI2 3 /* sequencer2 mode; used internally */
|
||||
|
||||
/* set drum channel mask; channels is 32bit long value */
|
||||
#define AWE_DRUM_CHANNELS(dev,channels) _AWE_CMD(dev, 0, _AWE_DRUM_CHANNELS, ((channels) & 0xffff), ((channels) >> 16))
|
||||
|
||||
/* set bass and treble control; values are from 0 to 11 */
|
||||
#define AWE_EQUALIZER(dev,bass,treble) _AWE_CMD(dev, 0, _AWE_EQUALIZER, bass, treble)
|
||||
|
||||
/* remove last loaded samples */
|
||||
#define AWE_REMOVE_LAST_SAMPLES(seqfd,dev) _AWE_CMD_NOW(seqfd, dev, 0, _AWE_REMOVE_LAST_SAMPLES, 0, 0)
|
||||
/* initialize emu8000 chip */
|
||||
#define AWE_INITIALIZE_CHIP(seqfd,dev) _AWE_CMD_NOW(seqfd, dev, 0, _AWE_INITIALIZE_CHIP, 0, 0)
|
||||
|
||||
/* set miscellaneous modes; meta command */
|
||||
#define AWE_MISC_MODE(dev,mode,value) _AWE_CMD(dev, 0, _AWE_MISC_MODE, mode, value)
|
||||
/* exclusive sound off; 1=off */
|
||||
#define AWE_EXCLUSIVE_SOUND(dev,mode) AWE_MISC_MODE(dev,AWE_MD_EXCLUSIVE_SOUND,mode)
|
||||
/* default GUS bank number */
|
||||
#define AWE_SET_GUS_BANK(dev,bank) AWE_MISC_MODE(dev,AWE_MD_GUS_BANK,bank)
|
||||
/* change panning position in realtime; 0=don't 1=do */
|
||||
#define AWE_REALTIME_PAN(dev,mode) AWE_MISC_MODE(dev,AWE_MD_REALTIME_PAN,mode)
|
||||
|
||||
/* extended pressure controls; not portable with other sound drivers */
|
||||
#define AWE_KEY_PRESSURE(dev,ch,note,vel) SEQ_START_NOTE(dev,ch,(note)+128,vel)
|
||||
#define AWE_CHN_PRESSURE(dev,ch,vel) _AWE_CMD(dev,ch,_AWE_CHN_PRESSURE,vel,0)
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
/* reverb mode parameters */
|
||||
#define AWE_REVERB_ROOM1 0
|
||||
#define AWE_REVERB_ROOM2 1
|
||||
#define AWE_REVERB_ROOM3 2
|
||||
#define AWE_REVERB_HALL1 3
|
||||
#define AWE_REVERB_HALL2 4
|
||||
#define AWE_REVERB_PLATE 5
|
||||
#define AWE_REVERB_DELAY 6
|
||||
#define AWE_REVERB_PANNINGDELAY 7
|
||||
#define AWE_REVERB_PREDEFINED 8
|
||||
/* user can define reverb modes up to 32 */
|
||||
#define AWE_REVERB_NUMBERS 32
|
||||
|
||||
typedef struct awe_reverb_fx_rec {
|
||||
unsigned short parms[28];
|
||||
} awe_reverb_fx_rec;
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
/* chorus mode parameters */
|
||||
#define AWE_CHORUS_1 0
|
||||
#define AWE_CHORUS_2 1
|
||||
#define AWE_CHORUS_3 2
|
||||
#define AWE_CHORUS_4 3
|
||||
#define AWE_CHORUS_FEEDBACK 4
|
||||
#define AWE_CHORUS_FLANGER 5
|
||||
#define AWE_CHORUS_SHORTDELAY 6
|
||||
#define AWE_CHORUS_SHORTDELAY2 7
|
||||
#define AWE_CHORUS_PREDEFINED 8
|
||||
/* user can define chorus modes up to 32 */
|
||||
#define AWE_CHORUS_NUMBERS 32
|
||||
|
||||
typedef struct awe_chorus_fx_rec {
|
||||
unsigned short feedback; /* feedback level (0xE600-0xE6FF) */
|
||||
unsigned short delay_offset; /* delay (0-0x0DA3) [1/44100 sec] */
|
||||
unsigned short lfo_depth; /* LFO depth (0xBC00-0xBCFF) */
|
||||
unsigned int delay; /* right delay (0-0xFFFFFFFF) [1/256/44100 sec] */
|
||||
unsigned int lfo_freq; /* LFO freq LFO freq (0-0xFFFFFFFF) */
|
||||
} awe_chorus_fx_rec;
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
/* misc mode types */
|
||||
enum {
|
||||
/* 0*/ AWE_MD_EXCLUSIVE_OFF, /* obsolete */
|
||||
/* 1*/ AWE_MD_EXCLUSIVE_ON, /* obsolete */
|
||||
/* 2*/ AWE_MD_VERSION, /* read only */
|
||||
/* 3*/ AWE_MD_EXCLUSIVE_SOUND, /* ignored */
|
||||
/* 4*/ AWE_MD_REALTIME_PAN, /* 0/1: do realtime pan change (default=1) */
|
||||
/* 5*/ AWE_MD_GUS_BANK, /* bank number for GUS patches (default=0) */
|
||||
/* 6*/ AWE_MD_KEEP_EFFECT, /* 0/1: keep effect values, (default=0) */
|
||||
/* 7*/ AWE_MD_ZERO_ATTEN, /* attenuation of max volume (default=32) */
|
||||
/* 8*/ AWE_MD_CHN_PRIOR, /* 0/1: set MIDI channel priority mode (default=1) */
|
||||
/* 9*/ AWE_MD_MOD_SENSE, /* integer: modwheel sensitivity (def=18) */
|
||||
/*10*/ AWE_MD_DEF_PRESET, /* integer: default preset number (def=0) */
|
||||
/*11*/ AWE_MD_DEF_BANK, /* integer: default bank number (def=0) */
|
||||
/*12*/ AWE_MD_DEF_DRUM, /* integer: default drumset number (def=0) */
|
||||
/*13*/ AWE_MD_TOGGLE_DRUM_BANK, /* 0/1: toggle drum flag with bank# (def=0) */
|
||||
AWE_MD_END,
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
/* effect parameters */
|
||||
enum {
|
||||
|
||||
/* modulation envelope parameters */
|
||||
/* 0*/ AWE_FX_ENV1_DELAY, /* WORD: ENVVAL */
|
||||
/* 1*/ AWE_FX_ENV1_ATTACK, /* BYTE: up ATKHLD */
|
||||
/* 2*/ AWE_FX_ENV1_HOLD, /* BYTE: lw ATKHLD */
|
||||
/* 3*/ AWE_FX_ENV1_DECAY, /* BYTE: lw DCYSUS */
|
||||
/* 4*/ AWE_FX_ENV1_RELEASE, /* BYTE: lw DCYSUS */
|
||||
/* 5*/ AWE_FX_ENV1_SUSTAIN, /* BYTE: up DCYSUS */
|
||||
/* 6*/ AWE_FX_ENV1_PITCH, /* BYTE: up PEFE */
|
||||
/* 7*/ AWE_FX_ENV1_CUTOFF, /* BYTE: lw PEFE */
|
||||
|
||||
/* volume envelope parameters */
|
||||
/* 8*/ AWE_FX_ENV2_DELAY, /* WORD: ENVVOL */
|
||||
/* 9*/ AWE_FX_ENV2_ATTACK, /* BYTE: up ATKHLDV */
|
||||
/*10*/ AWE_FX_ENV2_HOLD, /* BYTE: lw ATKHLDV */
|
||||
/*11*/ AWE_FX_ENV2_DECAY, /* BYTE: lw DCYSUSV */
|
||||
/*12*/ AWE_FX_ENV2_RELEASE, /* BYTE: lw DCYSUSV */
|
||||
/*13*/ AWE_FX_ENV2_SUSTAIN, /* BYTE: up DCYSUSV */
|
||||
|
||||
/* LFO1 (tremolo & vibrato) parameters */
|
||||
/*14*/ AWE_FX_LFO1_DELAY, /* WORD: LFO1VAL */
|
||||
/*15*/ AWE_FX_LFO1_FREQ, /* BYTE: lo TREMFRQ */
|
||||
/*16*/ AWE_FX_LFO1_VOLUME, /* BYTE: up TREMFRQ */
|
||||
/*17*/ AWE_FX_LFO1_PITCH, /* BYTE: up FMMOD */
|
||||
/*18*/ AWE_FX_LFO1_CUTOFF, /* BYTE: lo FMMOD */
|
||||
|
||||
/* LFO2 (vibrato) parameters */
|
||||
/*19*/ AWE_FX_LFO2_DELAY, /* WORD: LFO2VAL */
|
||||
/*20*/ AWE_FX_LFO2_FREQ, /* BYTE: lo FM2FRQ2 */
|
||||
/*21*/ AWE_FX_LFO2_PITCH, /* BYTE: up FM2FRQ2 */
|
||||
|
||||
/* Other overall effect parameters */
|
||||
/*22*/ AWE_FX_INIT_PITCH, /* SHORT: pitch offset */
|
||||
/*23*/ AWE_FX_CHORUS, /* BYTE: chorus effects send (0-255) */
|
||||
/*24*/ AWE_FX_REVERB, /* BYTE: reverb effects send (0-255) */
|
||||
/*25*/ AWE_FX_CUTOFF, /* BYTE: up IFATN */
|
||||
/*26*/ AWE_FX_FILTERQ, /* BYTE: up CCCA */
|
||||
|
||||
/* Sample / loop offset changes */
|
||||
/*27*/ AWE_FX_SAMPLE_START, /* SHORT: offset */
|
||||
/*28*/ AWE_FX_LOOP_START, /* SHORT: offset */
|
||||
/*29*/ AWE_FX_LOOP_END, /* SHORT: offset */
|
||||
/*30*/ AWE_FX_COARSE_SAMPLE_START, /* SHORT: upper word offset */
|
||||
/*31*/ AWE_FX_COARSE_LOOP_START, /* SHORT: upper word offset */
|
||||
/*32*/ AWE_FX_COARSE_LOOP_END, /* SHORT: upper word offset */
|
||||
/*33*/ AWE_FX_ATTEN, /* BYTE: lo IFATN */
|
||||
|
||||
AWE_FX_END,
|
||||
};
|
||||
|
||||
#endif /* AWE_VOICE_H */
|
File diff suppressed because it is too large
Load Diff
@ -1815,7 +1815,6 @@ hint.gusc.0.irq="5"
|
||||
hint.gusc.0.drq="1"
|
||||
hint.gusc.0.flags="0x13"
|
||||
|
||||
# Not controlled by `snd'
|
||||
device pca
|
||||
hint.pca.0.at="isa"
|
||||
hint.pca.0.port="0x040"
|
||||
|
@ -1,122 +0,0 @@
|
||||
#ifndef _ULTRASOUND_H_
|
||||
#define _ULTRASOUND_H_
|
||||
/*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* ultrasound.h - Macros for programming the Gravis Ultrasound
|
||||
* These macros are extremely device dependent
|
||||
* and not portable.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Private events for Gravis Ultrasound (GUS)
|
||||
*
|
||||
* Format:
|
||||
* byte 0 - SEQ_PRIVATE (0xfe)
|
||||
* byte 1 - Synthesizer device number (0-N)
|
||||
* byte 2 - Command (see below)
|
||||
* byte 3 - Voice number (0-31)
|
||||
* bytes 4 and 5 - parameter P1 (unsigned short)
|
||||
* bytes 6 and 7 - parameter P2 (unsigned short)
|
||||
*
|
||||
* Commands:
|
||||
* Each command affects one voice defined in byte 3.
|
||||
* Unused parameters (P1 and/or P2 *MUST* be initialized to zero).
|
||||
* _GUS_NUMVOICES - Sets max. number of concurrent voices (P1=14-31, default 16)
|
||||
* _GUS_VOICESAMPLE- ************ OBSOLETE *************
|
||||
* _GUS_VOICEON - Starts voice (P1=voice mode)
|
||||
* _GUS_VOICEOFF - Stops voice (no parameters)
|
||||
* _GUS_VOICEFADE - Stops the voice smoothly.
|
||||
* _GUS_VOICEMODE - Alters the voice mode, don't start or stop voice (P1=voice mode)
|
||||
* _GUS_VOICEBALA - Sets voice balance (P1, 0=left, 7=middle and 15=right, default 7)
|
||||
* _GUS_VOICEFREQ - Sets voice (sample) playback frequency (P1=Hz)
|
||||
* _GUS_VOICEVOL - Sets voice volume (P1=volume, 0xfff=max, 0xeff=half, 0x000=off)
|
||||
* _GUS_VOICEVOL2 - Sets voice volume (P1=volume, 0xfff=max, 0xeff=half, 0x000=off)
|
||||
* (Like GUS_VOICEVOL but doesn't change the hw
|
||||
* volume. It just updates volume in the voice table).
|
||||
*
|
||||
* _GUS_RAMPRANGE - Sets limits for volume ramping (P1=low volume, P2=high volume)
|
||||
* _GUS_RAMPRATE - Sets the speed for volume ramping (P1=scale, P2=rate)
|
||||
* _GUS_RAMPMODE - Sets the volume ramping mode (P1=ramping mode)
|
||||
* _GUS_RAMPON - Starts volume ramping (no parameters)
|
||||
* _GUS_RAMPOFF - Stops volume ramping (no parameters)
|
||||
* _GUS_VOLUME_SCALE - Changes the volume calculation constants
|
||||
* for all voices.
|
||||
*/
|
||||
|
||||
#define _GUS_NUMVOICES 0x00
|
||||
#define _GUS_VOICESAMPLE 0x01 /* OBSOLETE */
|
||||
#define _GUS_VOICEON 0x02
|
||||
#define _GUS_VOICEOFF 0x03
|
||||
#define _GUS_VOICEMODE 0x04
|
||||
#define _GUS_VOICEBALA 0x05
|
||||
#define _GUS_VOICEFREQ 0x06
|
||||
#define _GUS_VOICEVOL 0x07
|
||||
#define _GUS_RAMPRANGE 0x08
|
||||
#define _GUS_RAMPRATE 0x09
|
||||
#define _GUS_RAMPMODE 0x0a
|
||||
#define _GUS_RAMPON 0x0b
|
||||
#define _GUS_RAMPOFF 0x0c
|
||||
#define _GUS_VOICEFADE 0x0d
|
||||
#define _GUS_VOLUME_SCALE 0x0e
|
||||
#define _GUS_VOICEVOL2 0x0f
|
||||
#define _GUS_VOICE_POS 0x10
|
||||
|
||||
/*
|
||||
* GUS API macros
|
||||
*/
|
||||
|
||||
#define _GUS_CMD(chn, voice, cmd, p1, p2) \
|
||||
{_SEQ_NEEDBUF(8); _seqbuf[_seqbufptr] = SEQ_PRIVATE;\
|
||||
_seqbuf[_seqbufptr+1] = (chn); _seqbuf[_seqbufptr+2] = cmd;\
|
||||
_seqbuf[_seqbufptr+3] = voice;\
|
||||
*(unsigned short*)&_seqbuf[_seqbufptr+4] = p1;\
|
||||
*(unsigned short*)&_seqbuf[_seqbufptr+6] = p2;\
|
||||
_SEQ_ADVBUF(8);}
|
||||
|
||||
#define GUS_NUMVOICES(chn, p1) _GUS_CMD(chn, 0, _GUS_NUMVOICES, (p1), 0)
|
||||
#define GUS_VOICESAMPLE(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICESAMPLE, (p1), 0) /* OBSOLETE */
|
||||
#define GUS_VOICEON(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEON, (p1), 0)
|
||||
#define GUS_VOICEOFF(chn, voice) _GUS_CMD(chn, voice, _GUS_VOICEOFF, 0, 0)
|
||||
#define GUS_VOICEFADE(chn, voice) _GUS_CMD(chn, voice, _GUS_VOICEFADE, 0, 0)
|
||||
#define GUS_VOICEMODE(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEMODE, (p1), 0)
|
||||
#define GUS_VOICEBALA(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEBALA, (p1), 0)
|
||||
#define GUS_VOICEFREQ(chn, voice, p) _GUS_CMD(chn, voice, _GUS_VOICEFREQ, \
|
||||
(p) & 0xffff, ((p) >> 16) & 0xffff)
|
||||
#define GUS_VOICEVOL(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEVOL, (p1), 0)
|
||||
#define GUS_VOICEVOL2(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEVOL2, (p1), 0)
|
||||
#define GUS_RAMPRANGE(chn, voice, low, high) _GUS_CMD(chn, voice, _GUS_RAMPRANGE, (low), (high))
|
||||
#define GUS_RAMPRATE(chn, voice, p1, p2) _GUS_CMD(chn, voice, _GUS_RAMPRATE, (p1), (p2))
|
||||
#define GUS_RAMPMODE(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_RAMPMODE, (p1), 0)
|
||||
#define GUS_RAMPON(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_RAMPON, (p1), 0)
|
||||
#define GUS_RAMPOFF(chn, voice) _GUS_CMD(chn, voice, _GUS_RAMPOFF, 0, 0)
|
||||
#define GUS_VOLUME_SCALE(chn, voice, p1, p2) _GUS_CMD(chn, voice, _GUS_VOLUME_SCALE, (p1), (p2))
|
||||
#define GUS_VOICE_POS(chn, voice, p) _GUS_CMD(chn, voice, _GUS_VOICE_POS, \
|
||||
(p) & 0xffff, ((p) >> 16) & 0xffff)
|
||||
|
||||
#endif
|
@ -1,200 +0,0 @@
|
||||
Changelog for version 3.5-alpha7
|
||||
--------------------------------
|
||||
|
||||
Since 3.5-alpha6
|
||||
- Changed all #ifndef EXCLUDE_xx stuff to #ifdef CONFIG_xx. Modified
|
||||
configure to handle this.
|
||||
- Removed initialization messages from the
|
||||
modularized version. They can be enabled by using init_trace=1 in
|
||||
the insmod command line (insmod sound init_trace=1).
|
||||
- More AIX stuff.
|
||||
- Added support for syncronizing dsp/audio devices with /dev/sequencer.
|
||||
- mmap() support for dsp/audio devices.
|
||||
|
||||
Since 3.5-alpha5
|
||||
- AIX port.
|
||||
- Changed some xxx_PATCH macros in soundcard.h to work with
|
||||
big endian machines.
|
||||
|
||||
Since 3.5-alpha4
|
||||
- Removed the 'setfx' stuff from the version distributed with kernel
|
||||
sources.
|
||||
|
||||
Since 3.5-alpha3
|
||||
- Moved stuff from the 'setfx' program to the AudioTriX Pro driver.
|
||||
|
||||
Since 3.5-alpha2
|
||||
- Modifications to makefile and configure.c. Unnecessary sources
|
||||
are no longer compiled. Newly created local.h is also copied to
|
||||
/etc/soundconf. "make oldconfig" reads /etc/soundconf and produces
|
||||
new local.h which is compatible with current version of the driver.
|
||||
- Some fixes to the SB16 support.
|
||||
- Fixed random protection fault in gus_wave.c
|
||||
|
||||
Since 3.5-alpha1
|
||||
- Modified to work with Linux-1.3.33 and leater
|
||||
- Some minor changes
|
||||
|
||||
Since 3.0.2
|
||||
- Support for CS4232 based PnP cards (AcerMagic S23 etc).
|
||||
- Full duplex support for some CS4231, CS4232 and AD1845 based cards
|
||||
(GUA MAX, AudioTrix Pro, AcerMagic S23 and many MAD16/Mozart cards
|
||||
having a codec mentioned above).
|
||||
- Almost fully rewritten loadable modules support.
|
||||
- Fixed some bugs.
|
||||
- Huge amount of testing (more testing is still required).
|
||||
- mmap() support (works with some cards). Requires much more testing.
|
||||
- Sample/patch/program loading for TB Maui/Tropez. No initialization
|
||||
since TB doesn't allow me to release that code.
|
||||
- Using CS4231 compatible codecs as timer for /dev/music.
|
||||
|
||||
Since 3.0.1
|
||||
- Added allocation of I/O ports, DMA channels and interrupts
|
||||
to the initialization code. This may break modules support since
|
||||
the driver may not free some resources on unload. Should be fixed soon.
|
||||
|
||||
Since 3.0
|
||||
- Some important bug fixes.
|
||||
- select() for /dev/dsp and /dev/audio (Linux only).
|
||||
(To use select() with read, you have to call read() to start
|
||||
the recording. Calling write() kills recording immediately so
|
||||
use select() carefully when you are writing a half duplex app.
|
||||
Full duplex mode is not implemented yet.) Select works also with
|
||||
/dev/sequencer and /dev/music. Maybe with /dev/midi## too.
|
||||
|
||||
Since 3.0-beta2
|
||||
- Minor fixes.
|
||||
- Added Readme.cards
|
||||
|
||||
Since 3.0-beta1
|
||||
- Minor fixes to the modules support.
|
||||
- Eliminated call to sb_free_irq() in ad1848.c
|
||||
- Rewritten MAD16&Mozart support (not tested with MAD16 Pro).
|
||||
- Fix to DMA initialization of PSS cards.
|
||||
- Some fixes to ad1848/cs42xx mixer support (GUS MAX, MSS, etc.)
|
||||
- Fixed some bugs in the PSS driver which caused I/O errors with
|
||||
the MSS mode (/dev/dsp).
|
||||
|
||||
Since 3.0-950506
|
||||
- Recording with GUS MAX fixed. It works when the driver is configured
|
||||
to use two DMA channels with GUS MAX (16 bit ones recommended).
|
||||
|
||||
Since 3.0-94xxxx
|
||||
- Too many changes
|
||||
|
||||
Since 3.0-940818
|
||||
- Fixes for Linux 1.1.4x.
|
||||
- Disables Disney Sound System with SG NX Pro 16 (less noise).
|
||||
|
||||
Since 2.90-2
|
||||
- Fixes to soundcard.h
|
||||
- Non blocking mode to /dev/sequencer
|
||||
- Experimental detection code for Ensoniq Soundscape.
|
||||
|
||||
Since 2.90
|
||||
- Minor and major bug fixes
|
||||
|
||||
Since pre-3.0-940712
|
||||
- GUS MAX support
|
||||
- Partially working MSS/WSS support (could work with some cards).
|
||||
- Hardware u-Law and A-Law support with AD1848/CS4248 and CS4231 codecs
|
||||
(GUS MAX, GUS16, WSS etc). Hardware ADPCM is possible with GUS16 and
|
||||
GUS MAX, but it doesn't work yet.
|
||||
Since pre-3.0-940426
|
||||
- AD1848/CS4248/CS4231 codec support (MSS, GUS MAX, Aztec, Orchid etc).
|
||||
This codec chip is used in various soundcards. This version is developed
|
||||
for the 16 bit daughtercard of GUS. It should work with other cards also
|
||||
if the following requirements are met:
|
||||
- The I/O, IRQ and DMA settings are jumper selectable or
|
||||
the card is initialized by booting DOS before booting Linux (etc.).
|
||||
- You add the IO, IRQ and DMA settings manually to the local.h.
|
||||
(Just define GUS16_BASE, GUS16_IRQ and GUS16_DMA). Note that
|
||||
the base address bust be the base address of the codec chip not the
|
||||
card itself. For the GUS16 these are the same but most MSS compatible
|
||||
cards have the codec located at card_base+4.
|
||||
- Some minor changes
|
||||
|
||||
Since 2.5 (******* MAJOR REWRITE ***********)
|
||||
|
||||
This version is based on v2.3. I have tried to maintain two versions
|
||||
together so that this one should have the same features than v2.5.
|
||||
Something may still be missing. If you notice such things, please let me
|
||||
know.
|
||||
|
||||
The Readme.v30 contains more details.
|
||||
|
||||
- /dev/midi## devices.
|
||||
- /dev/sequencer2
|
||||
|
||||
Since 2.5-beta2
|
||||
- Some fine tuning to the GUS v3.7 mixer code.
|
||||
- Fixed speed limits for the plain SB (1.0 to 2.0).
|
||||
|
||||
Since 2.5-beta
|
||||
- Fixed OPL-3 detection with SB. Caused problems with PAS16.
|
||||
- GUS v3.7 mixer support.
|
||||
|
||||
Since 2.4
|
||||
- Mixer support for Sound Galaxy NX Pro (define __SGNXPRO__ on your local.h).
|
||||
- Fixed truncated sound on /dev/dsp when the device is closed.
|
||||
- Linear volume mode for GUS
|
||||
- Pitch bends larger than +/- 2 octaves.
|
||||
- MIDI recording for SB and SB Pro. (Untested).
|
||||
- Some other fixes.
|
||||
- SB16 MIDI and DSP drivers only initialized if SB16 actually installed.
|
||||
- Implemented better detection for OPL-3. This should be useful if you
|
||||
have an old SB Pro (the non-OPL-3 one) or a SB 2.0 clone which has a OPL-3.
|
||||
- SVR4.2 support by Ian Hartas. Initial ALPHA TEST version (untested).
|
||||
|
||||
Since 2.3b
|
||||
- Fixed bug which made it impossible to make long recordings to disk.
|
||||
Recording was not restarted after a buffer overflow situation.
|
||||
- Limited mixer support for GUS.
|
||||
- Numerous improvements to the GUS driver by Andrew Robinson. Including
|
||||
some click removal etc.
|
||||
|
||||
Since 2.3
|
||||
- Fixed some minor bugs in the SB16 driver.
|
||||
|
||||
Since 2.2b
|
||||
- Full SB16 DSP support. 8/16 bit, mono/stereo
|
||||
- The SCO and FreeBSD versions should be in sync now. There are some
|
||||
problems with SB16 and GUS in the freebsd versions.
|
||||
The DMA buffer allocation of the SCO version has been polished but
|
||||
there could still be some problems. At least it hogs memory.
|
||||
The DMA channel
|
||||
configuration method used in the sco/System is a hack.
|
||||
- Support for the MPU emulation of the SB16.
|
||||
- Some big arrays are now allocated boot time. This makes the bss segment
|
||||
smaller which makes it possible to use the full driver with
|
||||
NetBSD. These arrays are not allocated if no suitable soundcard is available.
|
||||
- Fixed a bug in the compute_and_set_volume in gus_wave.c
|
||||
- Fixed the too fast mono playback problem of SB Pro and PAS16.
|
||||
|
||||
Since 2.2
|
||||
- Stereo recording for SB Pro. Somehow it was missing and nobody
|
||||
had noticed it earlier.
|
||||
- Minor polishing.
|
||||
- Interpreting of boot time arguments (sound=) for Linux.
|
||||
- Breakup of sb_dsp.c. Parts of the code has been moved to
|
||||
sb_mixer.c and sb_midi.c
|
||||
|
||||
Since 2.1
|
||||
- Preliminary support for SB16.
|
||||
- The SB16 mixer is supported in its native mode.
|
||||
- Digitized voice capability up to 44.1 kHz/8 bit/mono
|
||||
(16 bit and stereo support coming in the next release).
|
||||
- Fixed some bugs in the digitized voice driver for PAS16.
|
||||
- Proper initialization of the SB emulation of latest PAS16 models.
|
||||
|
||||
- Significantly improved /dev/dsp and /dev/audio support.
|
||||
- Now supports half duplex mode. It's now possible to record and
|
||||
playback without closing and reopening the device.
|
||||
- It's possible to use smaller buffers than earlier. There is a new
|
||||
ioctl(fd, SNDCTL_DSP_SUBDIVIDE, &n) where n should be 1, 2 or 4.
|
||||
This call instructs the driver to use smaller buffers. The default
|
||||
buffer size (0.5 to 1.0 seconds) is divided by n. Should be called
|
||||
immediately after opening the device.
|
||||
|
||||
Since 2.0
|
||||
Just cosmetic changes.
|
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
@ -1,86 +0,0 @@
|
||||
VoxWare v2.90 release notes
|
||||
--------------------------
|
||||
|
||||
|
||||
This version includes some hidden features which
|
||||
are described in the file experimental.txt
|
||||
Some of these features are not enabled by default. Look at
|
||||
experimental.txt for more info.
|
||||
|
||||
I just decided to release this version with some
|
||||
incompletely implemented features disabled since
|
||||
there are some new features required by a popular
|
||||
application. In addition there is also support
|
||||
for the GUS MAX and the 16 bit sampling option of GUS.
|
||||
|
||||
The MSS/WSS support works now. At least with SG NX Pro 16.
|
||||
|
||||
********* IMPORTANT *****************************************
|
||||
Linux 1.0 or later is required to by this driver version.
|
||||
|
||||
Don't distribute binaries which use /dev/sequencer and are
|
||||
compiled with the soundcard.h of this version. They will
|
||||
not work with version 2.x of the driver.
|
||||
*************************************************************
|
||||
|
||||
|
||||
You will need the snd-util-2.5.tar.gz and snd-data-0.1.tar.Z
|
||||
packages to use this driver. They should be in the same
|
||||
ftp site or BBS from where you got this driver. For
|
||||
example at nic.funet.fi:pub/OS/Linux/*.
|
||||
|
||||
If you are looking for the installation instructions, please
|
||||
look at linux/Readme.
|
||||
|
||||
Compatibility with the earlier versions
|
||||
---------------------------------------
|
||||
|
||||
This version is backward compatible with the version 2.X. All programs
|
||||
compiled with sys/soundcard.h of v2.X should work without problems.
|
||||
PROGRAMS COMPILED WITH THE sys/soundcard.h OF THIS VERSION WILL NOT
|
||||
WORK WITH v2.X DRIVER. BE CAREFUL WHEN DISTRIBUTING BINARIES COMPILED
|
||||
FOR THIS VERSION.
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
This driver contains code by several contributors. In addition several other
|
||||
persons have given useful suggestions. The following is a list of major
|
||||
contributors. (I could have forgotten some names.)
|
||||
|
||||
Craig Metz 1/2 of the PAS16 Mixer and PCM support
|
||||
Rob Hooft Volume computation algorithm for the FM synth.
|
||||
Mika Liljeberg uLaw encoding and decoding routines
|
||||
Greg Lee Volume computation algorithm for the GUS and
|
||||
lot's of valuable suggestions.
|
||||
Andy Warner ISC port
|
||||
Jim Lowe FreeBSD port
|
||||
Anders Baekgaard Bughunting and valuable suggestions.
|
||||
Joerg Schubert SB16 DSP support.
|
||||
Andrew Robinson Improvements to the GUS driver
|
||||
Megens SA MIDI recording for SB and SB Pro.
|
||||
Mikael Nordqvist Linear volume support for GUS.
|
||||
Mikael Nordqvist Linear volume support for GUS.
|
||||
Ian Hartas SVR4.2 port
|
||||
Markus Aroharju and
|
||||
Risto Kankkunen Major contributions to the mixer support
|
||||
of GUS v3.7.
|
||||
Hunyue Yau Mixer support for SG NX Pro.
|
||||
Marc Hoffman PSS support.
|
||||
|
||||
Regards,
|
||||
|
||||
Hannu Savolainen
|
||||
hannu@voxware.pp.fi
|
||||
|
||||
Snail mail: Hannu Savolainen
|
||||
Hiekkalaiturintie 3 A 8
|
||||
00980 Helsinki
|
||||
Finland
|
||||
FAX: +358 0 341 6272 (answers if I have my machine (mgetty) on).
|
||||
|
||||
NOTE! I probably don't answer to Snail mail or FAX messages. Sending answer
|
||||
to each of them is simply too expensive and time consuming. However I
|
||||
try to reply every email message I get (within a week). If you don't
|
||||
get response, please check how your address is written in the message
|
||||
header. I can't answer if I don't have a valid reply address.
|
@ -1,165 +0,0 @@
|
||||
GUSPNP15 8/6//97
|
||||
ftp://rah.star-gate.com/pub/guspnp.tar.gz
|
||||
|
||||
This sound driver is for FreeBSD 3.0-current .
|
||||
|
||||
|
||||
Major enhancement we now support mapping the dma buffer to user
|
||||
space for write operations only. This features is useful for
|
||||
games like xquake . So far the mmap features seems to work
|
||||
with the GUS PnP Pro and with the SB16.
|
||||
|
||||
For xquake you will need:
|
||||
|
||||
1. a few mods to the linux loadable module so just download it and
|
||||
replace yours:
|
||||
cd /sys/i386/
|
||||
tar -xzf linux_ioctl.tar.gz
|
||||
cd /usr/src/lkm/linux
|
||||
make
|
||||
make install
|
||||
modunload -i 0 (if you have the linux up and running)
|
||||
linux
|
||||
ftp://rah.star-gate.com/linux_ioctl.tar.gz
|
||||
|
||||
2. Install the linux lib 2.4 package:
|
||||
pkg_add linux_lib-2.4.tgz
|
||||
|
||||
ftp://ftp.freebsd.org/pub/FreeBSD/packages-current/emulators/linux_lib-2.4.tgz
|
||||
|
||||
If you don't have xquake you can get it from:
|
||||
|
||||
3. ftp://ftp.freebsd.org/pub/idgames/idstuff/unsup/intel_linux_quake101.tgz
|
||||
|
||||
|
||||
A simple test program mmap_test.c is provided in the sound driver directory.
|
||||
So copy it to your home directory or favorite place and compile it.
|
||||
cc -o mmap_test mmap_test.c
|
||||
|
||||
record a sample session:
|
||||
cat /dev/dsp >smpl
|
||||
|
||||
now run mmap_test . You will hear a loud pop thats a test program
|
||||
then the sample stream will loop .
|
||||
|
||||
|
||||
Phew, now back to sound driver land 8)
|
||||
|
||||
|
||||
This is a minor sound driver release for the GUS PnP Pro , GUS MAX,
|
||||
AudioTrix Pro , SB16 and SB16 PnP. There is also an experimental
|
||||
AWE sub model.
|
||||
|
||||
Included Luigi's clean up work . Tnks!
|
||||
|
||||
Randall Hopper's SB16 speed setting fix . Tnks!
|
||||
|
||||
Fixed signal handling throught out the sound driver. The problem
|
||||
first surfaced with the SB16 not generating an interrupt on the
|
||||
last dma request and SB afficionados quickly pointed out the
|
||||
bug in the driver. I had to put back the auto dma feature for
|
||||
xquake :(
|
||||
|
||||
|
||||
NOTE YOU DON'T NEED THE PNP DRIVER FOR THE GUS PNP SINCE THE DRIVER
|
||||
HAS BUILTIN PNP SUPPORT FOR THE GUS.
|
||||
|
||||
My P133 Bios supports PnP. To first figured out what my SB16 PnP
|
||||
was being configured to I booted win95 and checked out what Win95
|
||||
ended up with . Alternatively, if you want to you can also down
|
||||
load Sujal Patel's PnP driver:
|
||||
|
||||
ftp://rah.start-gate.com/pub/FreeBSD-ISA_PnP_June8.tar.gz
|
||||
|
||||
follow the instructions on how to configure your PnP soundcard or
|
||||
ISA device.
|
||||
Lugi also has Sujal's PnP driver .
|
||||
|
||||
|
||||
---
|
||||
|
||||
http://www.iet.unipi.it/~luigi/pnp.c
|
||||
http://www.iet.unipi.it/~luigi/pnp.h
|
||||
|
||||
the two main files. Follow Sujal Patel's instructions
|
||||
for installing pnp support.
|
||||
|
||||
http://www.iet.unipi.it/~luigi/pnpinfo.tgz
|
||||
---
|
||||
|
||||
This is my kernel configuration for my SB16 PnP:
|
||||
|
||||
controller snd0
|
||||
device sb0 at isa? port 0x220 irq 10 conflicts drq 3
|
||||
device sbxvi0 at isa? port? irq? drq 5 conflicts
|
||||
device opl0 at isa? port 0x388 conflicts
|
||||
device sbmidi0 at isa? port 0x300 irq? conflicts
|
||||
|
||||
----
|
||||
|
||||
|
||||
The difference between a GUS PnP and a GUS PnP PRO is that the Pro
|
||||
comes with 512kb. I went out an got a 1mb 60ns 30pin simm and installed
|
||||
it on my GUS PnP. I own a GUS PnP and a GUS PnP PRO.
|
||||
|
||||
|
||||
To unpack:
|
||||
cd /
|
||||
mv /sys/i386/isa/sound /sys/i386/isa/sound.old
|
||||
cd /sys/i386/isa/
|
||||
tar -xzf guspnp15.tar.gz
|
||||
|
||||
|
||||
cd /sys/i386/conf
|
||||
Edit the kernel config file in /sys/i386/conf
|
||||
|
||||
IF YOU HAVE A GUS MAX or GUS add the option NOGUSPNP to the config file
|
||||
OPTIONS NOGUSPNP
|
||||
THEN follow the instructions for NONPNP CONFIGURATION
|
||||
|
||||
|
||||
PNP CONFIGURATION
|
||||
To configure your guspnp PRO if you have a motherboard which supports
|
||||
PnP:
|
||||
|
||||
controller snd0
|
||||
device gus0 at isa?
|
||||
|
||||
NONPNP CONFIGURATION
|
||||
To configure your guspnp PRO if your motherboard does NOT support
|
||||
PnP:
|
||||
|
||||
device gus0 at isa? port 0x220 irq 11 drq 1 flags 0x3
|
||||
|
||||
|
||||
the gus pnp is fully software configurable and the above configuration
|
||||
is setup for full duplex audio. The dma channel settings are:
|
||||
|
||||
drq 1 --- DMA channel for playback
|
||||
|
||||
flags 0x3 --- DMAN channel for recording
|
||||
|
||||
In the event that you have to configure a GUS PnP manually or a GUS MAX:
|
||||
|
||||
Available IRQs for the GUS are:
|
||||
3, 5, 7, 9, 11, 12, 15
|
||||
|
||||
Available DMA channels for the GUS are:
|
||||
1, 3, 5, 6, 7
|
||||
|
||||
|
||||
config <kernel-file>
|
||||
cd /sys/compile/<kernel-file>
|
||||
make
|
||||
make install
|
||||
|
||||
THERE IS NO NEED TO BOOT TO DOS TO CONFIGURE YOUR GUS PNP.
|
||||
THE DRIVER HAS BUILTIN SUPPORT FOR PNP WHICH I GOT
|
||||
FROM THE GRAVIS DRIVER DEVELOPMENT KIT
|
||||
|
||||
Many thanks to Brian Litzinger <brian@MediaCity.com> for
|
||||
porting the sound driver 3.5 to 2.2-current. Well, thats a while
|
||||
ago hence the reference to 2.2.
|
||||
|
||||
Have fun,
|
||||
Amancio
|
@ -1,248 +0,0 @@
|
||||
|
||||
VoxWare v3.5-alpha5 release notes
|
||||
---------------------------------
|
||||
|
||||
IMPORTANT! This version of the driver is compatible only with Linux versions
|
||||
1.3.33 and later. It may work with earlier ones as a loadable
|
||||
module but...
|
||||
|
||||
Also this is an ALPHA test version which has not been tested
|
||||
with all cards. At least AEDSP16 support will not work. PAS16
|
||||
and PSS supports have not been tested. /dev/dsp and /dev/audio
|
||||
playback with standard GUS sounds scrambled. 16 bit mode of
|
||||
SB16 doesn't work.
|
||||
|
||||
Please read the SOUND-HOWTO (available from sunsite.unc.edu and other Linux ftp
|
||||
sites). It contains much more information than this file.
|
||||
|
||||
*****************************************************************
|
||||
* NEW! VoxWare home page is http://personal.eunet.fi/pp/voxware *
|
||||
* The file Readme.cards contains card specific instructions *
|
||||
* about configuring various cards. *
|
||||
*****************************************************************
|
||||
|
||||
There are some programming information (little bit old) in the
|
||||
Hacker's Guide
|
||||
(ftp://nic.funet.fi/pub/OS/Linux/ALPHA/sound/snd-sdk-doc-0.1.ps.gz).
|
||||
Believe me: The file is really there. The directory is just hidden and
|
||||
you have to cd into it before the file is visible. Note: This directory
|
||||
was accidently removed some time ago but it's now back.
|
||||
|
||||
I have got many patches from various persons during last year. Some of
|
||||
them are still on my mailbox and they should be included in versions
|
||||
after v3.0 (I will not add aditional features before v3.0 is ready).
|
||||
|
||||
====================================================
|
||||
- THIS VERSION ____REQUIRES____ Linux 1.3.33 OR LATER.
|
||||
====================================================
|
||||
|
||||
- THIS VERSION MAY NOT WORK WITH Linux VERSIONS RELEASED
|
||||
AFTER end of Nov 1995. If this version doesn't compile with
|
||||
your kernel version, please use the sound driver version
|
||||
included in your kernel.
|
||||
|
||||
You will need the snd-util-3.0.tar.gz and snd-data-0.1.tar.Z
|
||||
packages to use this driver. They should be in the same
|
||||
ftp site or BBS from where you got this driver. For
|
||||
example at nic.funet.fi:pub/OS/Linux/*.
|
||||
|
||||
If you are looking for the installation instructions, please
|
||||
look at linux/Readme.
|
||||
|
||||
Supported soundcards
|
||||
--------------------
|
||||
|
||||
Gravis Ultrasound (GUS)
|
||||
GUS MAX
|
||||
GUS with the 16 bit sampling daughtercard
|
||||
PAS16
|
||||
Windows Sound System compatible soundcards
|
||||
ECHO-PSS (cards based on the PSS architecture by Analog Devices.
|
||||
Including Orchid SW32, Cardinal DSP16 among others).
|
||||
(NOTE! WSS mode may not work (DMA channel setup problem)).
|
||||
MediaTriX AudioTriX Pro (OPL4 and the optional effect daughtercard
|
||||
require special initialization. There is a program (setfx) in
|
||||
the snd-util-3.0.tar.gz package which does it).
|
||||
Ensoniq SoundScape (works but needs some improvements)
|
||||
MV Jazz16 based soundcards (ProSonic, 3D etc).
|
||||
SoundMan Wave (recording may not work, mixer support is limited)
|
||||
Mozart (OAK OTI-601 interface chip) based soundcards.
|
||||
MAD16 (an interface chip by OPTi) based soundcards (TB Tropez ???).
|
||||
(NOTE! The MAD16 looks similar to the Mozart chip. It could be a good
|
||||
idea to configure MAD16 cards as Mozart ones. The MAD16 driver doesn't set
|
||||
up MPU401 which the Mozart one does.
|
||||
CS4232 based cards such as AcerMagic S23.
|
||||
|
||||
|
||||
In addition all Sound Blaster models and clones (up to AWE32) work if
|
||||
you want to use them.
|
||||
|
||||
The Emu synthesizer chip of AWE32 is not and will not be supported. The same is
|
||||
true with the ASP chip also. Creative Technology will not release detailed
|
||||
information about them so it's not possible to support them.
|
||||
|
||||
If you want to get support for AWE32 or ASP, please contact Creative Labs.
|
||||
Ask _politely_ if they are going to support Linux. Maybe they change
|
||||
their policy if there is enough demand.
|
||||
|
||||
===========================================================================
|
||||
If your card is compatible with SB, MPU401 or Windows Sound System, it
|
||||
may work with the driver even if it's not listed in the above list. In this
|
||||
case it may require initialization using DOS. Just start DOS and cold
|
||||
boot to Linux (etc.) by hitting ctrl-alt-del.
|
||||
===========================================================================
|
||||
|
||||
Compatibility with the earlier versions
|
||||
---------------------------------------
|
||||
|
||||
There have been some changes in soundcard.h after v2.5 of the driver
|
||||
(v2.90 is compatible with this one). Binaries compiled with this version
|
||||
of soundcard.h will not work with v2.0 and earlier.
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
This driver contains code by several contributors. In addition several other
|
||||
persons have given usefull suggestions. The following is a list of major
|
||||
contributors. (I could have forgotten some names.)
|
||||
|
||||
Craig Metz 1/2 of the PAS16 Mixer and PCM support
|
||||
Rob Hooft Volume computation algorithm for the FM synth.
|
||||
Mika Liljeberg uLaw encoding and decoding routines
|
||||
Andy Fingerhut New ulaw conversion tables (ulaw.h)
|
||||
Jeff Tranter Linux SOUND HOWTO document
|
||||
Greg Lee Volume computation algorithm for the GUS and
|
||||
lot's of valuable suggestions.
|
||||
Andy Warner ISC port
|
||||
Jim Lowe,
|
||||
Amancio Hasty Jr FreeBSD/NetBSD port
|
||||
Anders Baekgaard Bughunting and valuable suggestions.
|
||||
Joerg Schubert SB16 DSP support.
|
||||
Andrew Robinson Improvements to the GUS driver
|
||||
Megens SA MIDI recording for SB and SB Pro.
|
||||
Mikael Nordqvist Linear volume support for GUS and
|
||||
nonblocking /dev/sequencer.
|
||||
Ian Hartas SVR4.2 port
|
||||
Markus Aroharju and
|
||||
Risto Kankkunen Major contributions to the mixer support
|
||||
of GUS v3.7.
|
||||
Hunyue Yau Mixer support for SG NX Pro.
|
||||
Marc Hoffman PSS support.
|
||||
Rainer Vranken Initialization for Jazz16 (ProSonic, MV3D, SM Wave).
|
||||
Peter Trattler Initial version of loadable module support for Linux.
|
||||
JRA Gibson 16 bit mode for Jazz16
|
||||
Davor Jadrijevic MAD16 support
|
||||
Gregor Hoffleit Mozart support
|
||||
Riccardo Facchetti Audio Excel DSP 16 (aedsp16) support
|
||||
|
||||
There are propably many other names missing. If you have sent me some
|
||||
patches and your name is not in the above list, please inform me.
|
||||
|
||||
Sponsors etc.
|
||||
-------------
|
||||
|
||||
The following companies have greatly helped development of this driver
|
||||
in form of a free copy of their product:
|
||||
|
||||
Novell, Inc. UnixWare personal edition + SDK
|
||||
The Santa Cruz Operation, Inc. A SCO OpenServer + SDK
|
||||
Ensoniq Corp, a SoundScape card and extensive amount of assistance
|
||||
MediaTriX Peripherals Inc, a AudioTriX Pro card + SDK
|
||||
Acer, Inc. a pair of AcerMagic S23 cards.
|
||||
|
||||
In addition the following companies have provided me sufficial amount
|
||||
of technical information at least some of their products (free or $$$):
|
||||
|
||||
Advanced Gravis Computer Technology Ltd.
|
||||
Media Vision Inc.
|
||||
Analog Devices Inc.
|
||||
Logitech Inc.
|
||||
Aztech Labs Inc.
|
||||
Crystal Semiconductor Corporation,
|
||||
Integrated Circuit Systems Inc.
|
||||
OAK Technology
|
||||
OPTi
|
||||
Ad Lib Inc. ($$)
|
||||
Music Quest Inc. ($$)
|
||||
Creative Labs ($$$)
|
||||
|
||||
If you have some problems
|
||||
=========================
|
||||
|
||||
Read the sound HOWTO (sunsite.unc.edu:/pub/Linux/docs/...?).
|
||||
Also look at the home page (http://personal.eunet.fi/pp/voxware). It may
|
||||
contain info about some recent bug fixes.
|
||||
|
||||
It's likely that you have some problems when trying to use the sound driver
|
||||
first time. Soundcards don't have standard configuration so there are no
|
||||
good default configuration to use. Please try to use same I/O, DMA and IRQ
|
||||
values for the soundcard than with DOS.
|
||||
|
||||
If you get an error message when trying to use the driver, please look
|
||||
at /var/adm/messages for more verbose error message.
|
||||
|
||||
|
||||
In general the easiest way to diagnoze problems is to do "cat /dev/sndstat".
|
||||
|
||||
If you get an error message, there are some problems with the driver setup:
|
||||
|
||||
- "No such file or directory" tells that the device files for
|
||||
the sound driver are missing. Use the script at the end of
|
||||
linux/drivers/sound/Readme.linux to create them.
|
||||
|
||||
- "No such device" telss that the sound driver is not in the kernel.
|
||||
You have to reconfigure and recompile the kernel to have the sound
|
||||
driver. Compiling the driver doesn't help alone. You have to boot
|
||||
with the newly compiled one before the driver becomes active.
|
||||
The Linux-HOWTO should help in this step.
|
||||
|
||||
The following errors are likely with /dev/dsp and /dev/audio.
|
||||
|
||||
- "No such device or address". This error message should not happen
|
||||
with /dev/sndstat but it's possible with the other sound devices.
|
||||
This error indicates that there are no suitable hardware for the
|
||||
device file or the sound driver has been compiled without support for
|
||||
this particular device. For example /dev/audio and /dev/dsp will not
|
||||
work if "digitized voice support" was not enabled during "make config".
|
||||
|
||||
- "Device or resource busy". Propably the IRQ (or DMA) channel
|
||||
required by the soundcard is in use by some other device/driver.
|
||||
|
||||
- "I/O error". Almost certainly (99%) it's an IRQ or DMA conflict.
|
||||
Look at the kernel messages in /var/adm/notice for more info.
|
||||
|
||||
- "Invalid argument". The application is calling ioctl()
|
||||
with impossible parameters. Check that the application is
|
||||
for sound driver version 2.X or later.
|
||||
|
||||
In general the printout of of /dev/sndstat should tell what is the problem.
|
||||
It's possible that there are bugs in the sound driver but 99% of the problems
|
||||
reported to me are caused by somehow incorrect setup during "make config".
|
||||
|
||||
For owners of TI TM4000M notebooks
|
||||
----------------------------------
|
||||
|
||||
There appears to be some kind of conflict between the sound support
|
||||
(MV Jazz), mouse port and VoxWare. You could try to configure kernel
|
||||
with the C&T 82C710 mouse port support disabled.
|
||||
|
||||
Hannu
|
||||
|
||||
Regards,
|
||||
|
||||
Hannu Savolainen
|
||||
hannu@voxware.pp.fi
|
||||
(or Hannu.Savolainen@cctap.carel.fi in case the above bounces)
|
||||
|
||||
Snail mail: Hannu Savolainen
|
||||
Hiekkalaiturintie 3 A 8
|
||||
00980 Helsinki
|
||||
Finland
|
||||
|
||||
NOTE! I propably don't answer to Snail mail or FAX messages. Sending answer
|
||||
to each of them is simply too expensive and time consuming. However I
|
||||
try to reply every email message I get (within a week). If you don't
|
||||
get response, please check how your address is written in the message
|
||||
header. I can't answer if I don't have a valid reply address.
|
||||
|
||||
VoxWare home page is http://personal.eunet.fi/pp/voxware
|
@ -1,6 +0,0 @@
|
||||
Informations about Audio Excel DSP 16 can be found in the source
|
||||
file aedsp16.c
|
||||
Please, read the head of the source before using it. It contain useful
|
||||
informations.
|
||||
|
||||
Riccardo
|
@ -1,845 +0,0 @@
|
||||
Configuring VoxWare 3.0 (for Linux) with some most common soundcards
|
||||
====================================================================
|
||||
|
||||
NOTE! This document may contain some error. Please inform me
|
||||
if you find any mistakes.
|
||||
|
||||
Read this before trying to configure the driver
|
||||
-----------------------------------------------
|
||||
|
||||
There are currently many cards that work with VoxWare. Some of the cards
|
||||
have native support while the others work since they emulate some other
|
||||
cards (usually SB, MSS/WSS and/or MPU401). The following cards have native
|
||||
support in VoxWare. Detailed instructions for configuring these cards
|
||||
will be given later in this document.
|
||||
|
||||
Pro Audio Spectrum 16 (PAS16) and compatibles:
|
||||
Pro Audio Spectrum 16
|
||||
Pro Audio Studio 16
|
||||
Logitech Sound Man 16
|
||||
NOTE! The original Pro Audio Spectrum as well as the PAS+ are not
|
||||
and will not be supported by VoxWare.
|
||||
|
||||
Media Vision Jazz16 based cards
|
||||
Pro Sonic 16
|
||||
Logitech SoundMan Wave
|
||||
(Other Jazz based cards should work but I don't have any reports
|
||||
about them).
|
||||
|
||||
Sound Blasters
|
||||
SB 1.0 to 2.0
|
||||
SB Pro
|
||||
SB 16
|
||||
NOTE! The ASP chip and the EMU synth of the AWE32 is not supported
|
||||
since their manufacturer doesn't release information about
|
||||
the card. However both the AB16ASP and the AWE32 work with
|
||||
VoxWare just like a SB16. Also see the comment about some
|
||||
unsupported cards at the end of this file.
|
||||
SB16 compatible cards by other manufacturers than Creative.
|
||||
You have been fooled since there are no SB16 compatible
|
||||
cards in the market (July95). It's likely that your card
|
||||
is compatible just with SB Pro but there is also a non SB
|
||||
compatible 16 bit mode. Usually it's MSS/WSS but could also
|
||||
be a proprietary one like MV Jazz16.
|
||||
|
||||
Gravis Ultrasound (GUS)
|
||||
GUS
|
||||
GUS + the 16 bit option
|
||||
GUS MAX
|
||||
GUS ACE (No MIDI port and audio recording)
|
||||
|
||||
MPU-401 and compatibles
|
||||
The driver works both with the full (intelligent mode) MPU-401
|
||||
cards (such as MPU IPC-T and MQX-32M) and with the UART only
|
||||
dumb MIDI ports. MPU-401 is currently the most common MIDI
|
||||
interface. Most soundcards are compatible with it. However
|
||||
don't enable MPU401 mode blindly. Many cards having native support
|
||||
in VoxWare have their own MPU401 driver. Enabling the standard one
|
||||
will cause a conflict with these cards. So look if your card is
|
||||
in the list of supported cards before enabling MPU401.
|
||||
|
||||
Windows Sound System (MSS/WSS)
|
||||
Even Microsoft has discontinued their own Sound System card, they
|
||||
managed to make a standard. MSS compatible cards are based on a
|
||||
codec chip which is easily available from at least two manufacturers
|
||||
(AD1848 by Analog Devices and CS4231/CS4248 by Crystal Semiconductor).
|
||||
Currently most soundcards are based on one of the MSS compatible codec
|
||||
chip. The CS4231 is used in the high quality cards such as GUS MAX,
|
||||
MediaTriX AudioTriX Pro and TB Tropez (GUS MAX is not MSS compatible).
|
||||
|
||||
Having a AD1848, CS4248 or CS4231 codec chip on the card is a good
|
||||
sign. Even if the card is not MSS compatible, it could be easy to write
|
||||
support for it to VoxWare. Note also that most MSS compatible cards
|
||||
require special boot time initialization which may not be present
|
||||
in VoxWare. Also some MSS compatible cards have native support in
|
||||
VoxWare. Enabling the MSS support with these cards is likely to
|
||||
cause a conflict. So check if your card is listed in this file before
|
||||
enabling the MSS support.
|
||||
|
||||
6850 UART MIDI
|
||||
This UART chip is used in the MIDI interface of some (rare)
|
||||
soundcards. It's supported by VoxWare in case you need it.
|
||||
|
||||
Yamaha FM synthesizers (OPL2, OPL3 and OPL4)
|
||||
Most soundcards have a FM synthesizer chip. The OPL2 is a 2
|
||||
operator chip used in the original AdLib card. Currently it's used
|
||||
only in the cheapest (8 bit mono) cards. The OPL3 is a 4 operator
|
||||
FM chip which provides better sound quality and/or more available
|
||||
voices than the OPL2. The OPL4 is a new chip which has a OPL3 and
|
||||
a wave table synthesizer packed on the same chip. VoxWare supports
|
||||
just the OPL3 mode directly. Most cards having a OPL4 (like
|
||||
SM Wave and AudioTriX Pro) support the OPL4 mode using MPU401
|
||||
emulation. Writing a native OPL4 support to VoxWare is difficult
|
||||
since Yamaha doesn't give information about their sample ROM chip.
|
||||
|
||||
Enable the generic OPL2/OPL3 FM synthesizer support if your
|
||||
card has a FM chip made by Yamaha. Don't enable it if your card
|
||||
has a software (TRS) based FM emulator.
|
||||
|
||||
PSS based cards (AD1848 + ADSP-2115 + Echo ESC614 ASIC)
|
||||
Analog Devices and Echo Speech have together defined a soundcard
|
||||
architecture based on the above chips. The DSP chip is used
|
||||
for emulation of SB Pro, FM and General MIDI/MT32.
|
||||
|
||||
There are several cards based on this architecture. The most known
|
||||
ones are Orchid SW32 and Cardinal DSP16.
|
||||
|
||||
VoxWare supports downloading DSP algorithms to these cards.
|
||||
|
||||
MediaTriX AudioTriX Pro
|
||||
The ATP card is built around a CS4231 codec and a OPL4 synthesizer
|
||||
chips. The OPL4 mode is supported by a microcontroller running a
|
||||
General MIDI emulator. There is also a SB 1.5 compatible playback mode.
|
||||
|
||||
Ensoniq SoundScape and compatibles
|
||||
Ensoniq has designed a soundcard architecture based on the
|
||||
OTTO synthesizer chip used in their professional MIDI synthesizers.
|
||||
Several companies (including Ensoniq, Reveal and Spea) are selling
|
||||
cards based on this architecture.
|
||||
|
||||
MAD16 and Mozart based cards
|
||||
The Mozart (OAK OTI-601) and MAD16 Pro (OPTi 82C929) interface
|
||||
chips are used in many different soundcards, including some
|
||||
cards by Reveal and Turtle Beach (Tropez). Purpose of these
|
||||
chips is to connect other audio components to the PC bus. The
|
||||
interface chip performs address decoding for the other chips.
|
||||
|
||||
Audio Excell DSP16
|
||||
Support for this card is made by Riccardo Faccetti
|
||||
(riccardo@cdc8g5.cdc.polimi.it). See aedsp16.c for more info.
|
||||
|
||||
Crystal CS4232 based cards such as AcerMagic S23
|
||||
CS4232 is a PnP multimedia chip which contains a CS3231A codec,
|
||||
SB and MPU401 emulations. There is support for OPL3 too.
|
||||
(Unfortunately the MPU401 mode doesn't work).
|
||||
|
||||
Turtle Beach Maui and Tropez
|
||||
VoxWare supports sample, parch and program loading commands
|
||||
described in the Maui/Tropez User's manual. There is no initialization
|
||||
code for Maui so it must be initialized using DOS. Audio side of Tropez
|
||||
is based on the MAD16 chip (see above).
|
||||
|
||||
Jumpers and software configuration
|
||||
----------------------------------
|
||||
|
||||
Some of the earliest soundcards were jumper configurable. You have to
|
||||
configure VoxWare to configure VoxWare use I/O, IRQ and DMA settings
|
||||
that match the jumpers. Just few 8 bit cards are fully jumper
|
||||
configurable (SB 1.x/2.x, SB Pro and clones).
|
||||
Some cards made by Aztech have an EEPROM which contains the
|
||||
config info. These cards behave much like hardware jumpered cards.
|
||||
|
||||
Most cards have jumper for the base I/O address but other parameters
|
||||
are software configurable. Sometimes there are few other jumpers too.
|
||||
|
||||
Latest cards are fully software configurable or they are PnP ISA
|
||||
compatible. There are no jumpers on the board.
|
||||
|
||||
VoxWare handles software configurable cards automaticly. Just configure
|
||||
the driver to use I/O, IRQ and DMA settings which are known to work.
|
||||
You could usually use the same values than with DOS and/or Windows.
|
||||
Using different settings is possible but not recommended since it may cause
|
||||
some trouble (for example when warm booting from an OS to another or
|
||||
when installing new hardware to the machine).
|
||||
|
||||
VoxWare sets the soft configurable parameters of the card automaticly
|
||||
during boot. Usually you don't need to run any extra initialization
|
||||
programs when booting Linux but there are some exceptions. See the
|
||||
card specific instructions (below) for more info.
|
||||
|
||||
The drawback of software configuration is that the driver needs to know
|
||||
how the card must be initialized. It cannot initialize unknown cards
|
||||
even if they are otherwise compatible with some other cards (like SB,
|
||||
MPU401 or Windows Sound System).
|
||||
|
||||
What if your card was not listed above?
|
||||
---------------------------------------
|
||||
|
||||
The first thing to do is to look at the major IC chips on the card.
|
||||
Many of the latest soundcards are based on some standard chips. If you
|
||||
are lucky, all of them could be supported by VoxWare. The most common ones
|
||||
are the OPTi MAD16, Mozart, SoundScape (Ensoniq) and the PSS architectures
|
||||
listed above. Also look at the end of this file for list of unsupported
|
||||
cards and the ones which could be supported later.
|
||||
|
||||
The last resort is to send _exact_ name and model information of the card
|
||||
to me together with a list of the major IC chips (manufactured, model) to
|
||||
me. I could then try to check if your card looks like something familiar.
|
||||
|
||||
There are much more cards in the word than listed above. The first thing to
|
||||
do with these cards is to check if they emulate some other card/interface
|
||||
such as SB, MSS and/or MPU401. In this case there is a chance to get the
|
||||
card to work by booting DOS before starting Linux (boot DOS, hit ctrl-alt-del
|
||||
and boot Linux without hard resetting the machine). In this method the
|
||||
DOS based driver initializes the hardware to use a known I/O, IRQ and DMA
|
||||
settings. If VoxWare is configured to use the same settings, everything should
|
||||
work OK.
|
||||
|
||||
|
||||
Configuring VoxWare (with Linux)
|
||||
================================
|
||||
|
||||
VoxWare sound driver is currently a part of Linux kernel distribution. The
|
||||
driver files are located in directory /usr/src/linux/drivers/sound.
|
||||
|
||||
****************************************************************************
|
||||
* VoxWare MUST BE CONFIGURED AND COMPILED WITH THE KERNEL. TRYING *
|
||||
* TO COMPILE IT ALONE WILL _NOT_ WORK. *
|
||||
* *
|
||||
* ALWAYS USE THE SOUND DRIVER VERSION WHICH IS DISTRIBUTED WITH *
|
||||
* THE KERNEL SOURCE PACKAGE YOU ARE USING. SOME ALPHA AND BETA TEST *
|
||||
* VERSIONS CAN BE INSTALLED FROM A SEPARATELY DISTRIBUTED PACKAGE *
|
||||
* BUT CHECK THAT THE PACKAGE IS NOT MUCH OLDER (OR NEWER) THAN THE *
|
||||
* KERNEL YOU ARE USING. IT'S POSSIBLE THAT THE KERNEL/DRIVER *
|
||||
* INTERFACE CHANGES BETWEEN KERNEL RELEASES WHICH MAY CAUSE SOME *
|
||||
* INCOMPATIBILITY PROBLEMS. *
|
||||
* *
|
||||
* IN CASE YOU INSTALL A SEPARATELY DISTRIBUTED SOUND DRIVER VERSION, *
|
||||
* BE SURE TO REMOVE OR RENAME THE OLD SOUND DRIVER DIRECTORY BEFORE *
|
||||
* INSTALLING THE NEW ONE. LEAVING OLD FILES TO THE SOUND DRIVER *
|
||||
* DIRECTORY _WILL_ CAUSE PROBLEMS WHEN THE DRIVER IS USED OR *
|
||||
* COMPILED. *
|
||||
****************************************************************************
|
||||
|
||||
To configure the driver, run "make config" in the kernel source directory
|
||||
(/usr/src/linux). Answer y to the question about Sound card support (after
|
||||
questions about mouse, CD-ROM, ftape, etc. supports). Sound config options
|
||||
will then be asked after some additional questions.
|
||||
|
||||
After configuring the kernel and sound driver, run "make dep" and compile
|
||||
the kernel following instructions in the kernel README.
|
||||
|
||||
The sound driver configuration dialog
|
||||
-------------------------------------
|
||||
|
||||
All config information of the sound driver is written to file
|
||||
linux/drivers/sound/local.h. You may save the old version is this file and
|
||||
use it again in case you want to use the same config later. In this case
|
||||
just answer n to each question made by the sound config program and put
|
||||
the original local.h back before running "make dep".
|
||||
Don't do this if the version number of the sound driver has changed. In this
|
||||
case you have to enter the configuration information again.
|
||||
|
||||
If you already have the sound driver installed, consult printout of
|
||||
"cat /dev/sndstat" when configuring the driver again. It gives the I/O,
|
||||
IRQ and DMA settings you have used earlier.
|
||||
|
||||
|
||||
The sound config program (linux/drivers/sound/configure) starts by making
|
||||
some yes/no questions. Be careful when answering to these questions since
|
||||
answering y to a question may prevent some later ones from being asked. For
|
||||
example don't answer y to the first question (PAS16) if you don't really
|
||||
have a PAS16. Don't enable more cards than you really need since they
|
||||
just consume memory. Also some drivers (like MPU401) may conflict with your
|
||||
SCSI controller and prevent kernel from booting. If you card was in the list
|
||||
of supported cards (above), please look at the card specific config
|
||||
instructions (later in this file) before starting to configure. Some cards
|
||||
must be configured in way which is not obvious.
|
||||
|
||||
So here is the beginning of the config dialog. Answer 'y' or 'n' to these
|
||||
questions. The default answer is shown so that (y/n) means 'y' by default and
|
||||
(n/y) means 'n'. To use the default value, just hit ENTER. But be careful
|
||||
since using the default _doesn't_ guarantee anything.
|
||||
|
||||
Note also that all questions may not be asked. The configuration program
|
||||
may disable some questions dependig on the earlier choices. It may also
|
||||
select some options automaticly as well.
|
||||
|
||||
"ProAudioSpectrum 16 support",
|
||||
- Answer 'y'_ONLY_ if you have a Pro Audio Spectrum _16_,
|
||||
ProAudio Studio 16 or Logitech SoundMan 16 (be sure that
|
||||
you read the above list correctly). Don't answer 'y' if you
|
||||
have some other card made by Media Vision or Logitech since they
|
||||
are not PAS16 compatible.
|
||||
"SoundBlaster support",
|
||||
- Answer 'y' if you have an original SB card made by Creative Labs
|
||||
or a full 100% hardware compatible clone (like Thunderboard or
|
||||
SM Games). If your card was in the list of supported cards (above),
|
||||
please look at the card specific instructions later in this file
|
||||
before answering this question. For an unknown card you may answer
|
||||
'y' if the card claims to be SB compatible.
|
||||
|
||||
Don't enable SB if you have a MAD16 or Mozart compatible card.
|
||||
|
||||
"Generic OPL2/OPL3 FM synthesizer support",
|
||||
- Answer 'y' if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4).
|
||||
Answering 'y' is usually a safe and recommended choice. However some
|
||||
cards may have software (TSR) FM emulation. Enabling FM support
|
||||
with these cards may cause trouble. However I don't currently know
|
||||
such cards.
|
||||
"Gravis Ultrasound support",
|
||||
- Answer 'y' if you have GUS or GUS MAX. Answer 'n' if you don't
|
||||
have GUS since the GUS driver consumes much memory.
|
||||
Currently I don't have experiences with the GUS ACE so I don't
|
||||
know what to answer with it.
|
||||
"MPU-401 support (NOT for SB16)",
|
||||
- Be careful with this question. The MPU401 interface is supported
|
||||
by almost any soundcard today. However some natively supported cards
|
||||
have their own driver for MPU401. Enabling the MPU401 option with
|
||||
these cards wil cause a conflict. Also enabling MPU401 on a system
|
||||
that doesn't really have a MPU401 could cause some trouble. If your
|
||||
card was in the list of supported cards (above), please look at
|
||||
the card specific instructions later in this file.
|
||||
It's safe to answer 'y' if you have a true MPU401 MIDI interface
|
||||
card.
|
||||
"6850 UART Midi support",
|
||||
- It's safe to answer 'n' to this question in all cases. The 6850
|
||||
UART interface is so rarely used.
|
||||
"PSS (ECHO-ADI2111) support",
|
||||
- Answer 'y' only if you have Orchid SW32, Cardinal DSP16 or some
|
||||
other card based on the PSS chipset (AD1848 codec + ADSP-2115
|
||||
DSP chip + Echo ESC614 ASIC CHIP).
|
||||
"16 bit sampling option of GUS (_NOT_ GUS MAX)",
|
||||
- Answer 'y' if you have installed the 16 bit sampling daughtercard
|
||||
to your GUS. Answer 'n' if you have GUS MAX. Enabling this option
|
||||
disables GUS MAX support.
|
||||
"GUS MAX support",
|
||||
- Answer 'y' only if you have a GUS MAX.
|
||||
"Microsoft Sound System support",
|
||||
- Again think carefully before answering 'y' to this question. It's
|
||||
safe to answer 'y' in case you have the original Windows Sound
|
||||
System card made by Microsoft or Aztech SG 16 Pro (or NX16 Pro).
|
||||
Also you may answer 'y' in case your card was not listed earlier
|
||||
in this file. For cards having native support in VoxWare, consult
|
||||
the card specific instructions later in this file. Some drivers
|
||||
have their own MSS support and enabling this option wil cause a
|
||||
conflict.
|
||||
"Ensoniq Soundscape support",
|
||||
- Answer 'y' if you have a soundcard based on the Ensoniq SoundScape
|
||||
chipset. Suach cards are being manufactured at least by Ensoniq,
|
||||
Spea and Reveal (note that Reveal makes other cards also).
|
||||
"MediaTriX AudioTriX Pro support",
|
||||
- Answer 'y' if you have the AudioTriX Pro.
|
||||
"Support for MAD16 and/or Mozart based cards",
|
||||
- Answer y if your card has a Mozart (OAK OTI-601) or MAD16
|
||||
(OPTi 82C928 or 82C929) audio interface chip. These chips are
|
||||
currently quite common so it's possible that many no-name cards
|
||||
have one of them. In addition the MAD16 chip is used in some
|
||||
cards made by known manufacturers such as Turtle Beach (Tropez),
|
||||
Reveal (some models) and Diamond (latest ones).
|
||||
"SoundBlaster Pro support",
|
||||
- Enable this option if your card is SB Pro or SB16. Enable it
|
||||
also with any SB Pro clones. Answering 'n' saves some amount of
|
||||
memory but 'y' is the safe alterative.
|
||||
"SoundBlaster 16 support",
|
||||
- Enable if you have a SB16 (including the AWE32).
|
||||
"Audio Excel DSP 16 initialization support",
|
||||
- Don't know much about this card. Look at aedsp16.c for more info.
|
||||
|
||||
Then the configuration program asks some y/n questions about the higher
|
||||
level services. It's recommended to answer 'y' to each of these questions.
|
||||
Answer 'n' only if you know you will not need the option.
|
||||
|
||||
"/dev/dsp and /dev/audio supports (usually required)",
|
||||
- Answering 'n' disables /dev/dsp and /dev/audio. Answer 'y'.
|
||||
"MIDI interface support",
|
||||
- Answering 'n' disables /dev/midi## devices and access to any
|
||||
MIDI ports using /dev/sequencer and /dev/music. This option
|
||||
also affects any MPU401 and/or General MIDI compatible devices.
|
||||
"FM synthesizer (YM3812/OPL-3) support",
|
||||
- Answer 'y' here.
|
||||
"/dev/sequencer support",
|
||||
- Answering 'n' disables /dev/sequencer and /dev/music.
|
||||
|
||||
Entering the I/O, IRQ and DMA config parameters
|
||||
-----------------------------------------------
|
||||
|
||||
After the above questions the configuration program prompts for the
|
||||
card specific configuration information. Usually just a set of
|
||||
I/O address, IRQ and DMA numbers are asked. With some cards the program
|
||||
asks for some files to be used during initialization of the card. For example
|
||||
many cards have a DSP chip or microprocessor which must be initialized by
|
||||
downloading a program (microcode) file to the card. In some cases this file
|
||||
is written to a .h file by the config program and then included to the driver
|
||||
during compile.
|
||||
|
||||
Instructions for answering these questions are given in the next section.
|
||||
|
||||
|
||||
Card specific information
|
||||
=========================
|
||||
|
||||
This section gives additional instructions about configuring some cards.
|
||||
Please refer manual of your card for valid I/O, IRQ and DMA numbers. Using
|
||||
the same settings with DOS/Windows and VoxWare is recommended. Using
|
||||
different values could cause some problems when switching between
|
||||
different operating systems.
|
||||
|
||||
SoundBlasters (the original ones by Creative)
|
||||
---------------------------------------------
|
||||
|
||||
It's possible to configure these cards to use different I/O, IRQ and
|
||||
DMA settings. Since the available settings have changed between various
|
||||
models, you have to consult manual of your card for the proper ones. It's
|
||||
a good idea to use the same values than with DOS/Windows. With SB and SB Pro
|
||||
it's the only choice. SB16 has software selectable IRQ and DMA channels but
|
||||
using different values with DOS and Linux is likely to cause troubles. The
|
||||
DOS driver is not able to reset the card properly after warm boot from Linux
|
||||
if Linux has used different IRQ or DMA values.
|
||||
|
||||
The original (steam) Sound Blaster (versions 1.x and 2.x) use always
|
||||
DMA1. There is no way to change it.
|
||||
|
||||
The SB16 needs two DMA channels. A 8 bit one (1 or 3) is required for
|
||||
8 bit operation and a 16 bit one (5, 6 or 7) for the 16 bit mode. In theory
|
||||
it's possible to use just one (8 bit) DMA channel by answering the 8 bit
|
||||
one when the configuration program asks for the 16 bit one. This may work
|
||||
in some systems but is likely to cause terrible noise on some other systems.
|
||||
|
||||
NOTE! Don't enable the SM Games option (asked by the configuration program)
|
||||
if you are not 101% sure that your card is a Logitech Soundman Games
|
||||
(not a SM Wave or SM16).
|
||||
|
||||
SB Clones
|
||||
---------
|
||||
|
||||
First of all: There are no SB16 clones. There are SB Pro clones with a
|
||||
16 bit mode which is not SB16 compatible. The most likely alternative is that
|
||||
the 16 bit mode means MSS/WSS.
|
||||
|
||||
There are just few fully 100% hardware SB or SB Pro compatible cards.
|
||||
I know just Thunderboard and SM Games. Other cards require some kind of
|
||||
hardware initialization before they become SB compatible. Check if your card
|
||||
was listed in the beginning of this file. In this case you should follow
|
||||
instructions for your card later in this file.
|
||||
|
||||
For other not fully SB clones yoy may try initialization using DOS in
|
||||
the following way:
|
||||
|
||||
- Boot DOS so that the card specific driver gets run.
|
||||
- Hit ctrl-alt-del (or use loadlin) to boot Linux. Don't
|
||||
switch off power or press the reset button.
|
||||
- If you use the same I/O, IRQ and DMA settings in Linux, the
|
||||
card should work.
|
||||
|
||||
If your card is both SB and MSS compatible, I recommend using the MSS mode.
|
||||
Most cards of this kind are not able to work in the SB and the MSS mode
|
||||
simultaneously. Using the MSS mode provides 16 bit recording and playback.
|
||||
|
||||
ProAudioSpectrum 16 and compatibles
|
||||
-----------------------------------
|
||||
|
||||
There are nothing special with these cards. Just don't enable any
|
||||
other cards in case you don't have them also. The PAS16 has
|
||||
a SB mode so the driver config program will prompt for the SB settings
|
||||
do. Use I/O 0x220 and DMA1 for the SB mode. Ensure that you assign different
|
||||
IRQ numbers for the SB and PAS16 modes.
|
||||
|
||||
With PAS16 you can use two audio device files at the same time. /dev/dsp (and
|
||||
/dev/audio) is connected to the 8/16 bit native codec and the /dev/dsp1 (and
|
||||
/dev/audio1) is connected to the SB emulation (8 bit mono only).
|
||||
|
||||
Gravis Ultrasound
|
||||
-----------------
|
||||
|
||||
There are many different revisions of the Ultrasound card (GUS). The
|
||||
earliest ones (pre 3.7) don't have a hardware mixer. With these cards
|
||||
the driver uses a software emulation for synth and pcm playbacks. It's
|
||||
also possible to switch some of the inputs (line in, mic) off by setting
|
||||
mixer volume of the channel level below 10%. For recording you have
|
||||
to select the channel as a recording source and to use volume above 10%.
|
||||
|
||||
GUS 3.7 has a hardware mixer.
|
||||
|
||||
GUS MAX and the 16 bit sampling daughtercard have a CS4231 codec chip which
|
||||
also contains a mixer.
|
||||
|
||||
Configuring GUS is simple. Just enable the GUS support and GUS MAX or
|
||||
the 16 bit daughtercard if you have them. Note that enabling the daughter
|
||||
card disables GUS MAX driver.
|
||||
|
||||
With just the standard GUS enabled the configuration program prompts
|
||||
for the I/O, IRQ and DMA numbers for the card. Use the same values than
|
||||
with DOS.
|
||||
|
||||
With the daughter card option enabled you will be prompted for the I/O,
|
||||
IRQ and DMA numbers for the daughter card. You have to use different I/O
|
||||
and DMA values than for the standard GUS. The daughter card permits
|
||||
simultaneous recording and playback. Use /dev/dsp (the daughtercard) for
|
||||
recording and /dev/dsp1 (GUS GF1) for playback.
|
||||
|
||||
GUS MAX uses the same I/O address and IRQ settings than the original GUS
|
||||
(GUS MAX = GUS + a CS4231 codec). In addition an extra DMA channel may be used.
|
||||
Using two DMA channels permits simultaneous playback using two devices
|
||||
(dev/dsp0 and /dev/dsp1). The second DMA channel is required for
|
||||
full duplex audio.
|
||||
To enable the second DMA channels, give a valid DMA channel when the config
|
||||
program asks for the GUS MAX DMA (entering -1 disables the second DMA).
|
||||
Using 16 bit DMA channels (5,6 or 7) is recommended.
|
||||
|
||||
If you have problems in recording with GUS MAX, you could try to use
|
||||
just one 8 bit DMA channel. Recording will not work with one DMA
|
||||
channel if it's a 16 bit one.
|
||||
|
||||
|
||||
|
||||
MPU401 and Windows Sound System
|
||||
-------------------------------
|
||||
|
||||
Again. Don't enable these options in case your card is listed
|
||||
somewhere else in this file.
|
||||
|
||||
Configuring these cards is obvious (or it should be). With MSS
|
||||
you should propably enable the OPL3 synth also since
|
||||
most MSS compatible cards have it. However check that this is true
|
||||
before enabling OPL3.
|
||||
|
||||
VoxWare supports more than one MPU401 compatible cards at the same time
|
||||
but the config program asks config info for just the first of them.
|
||||
Adding the second or third MPU interfaces must be done manually by
|
||||
editing sound/local.h (after running the config program). Add defines for
|
||||
MPU2_BASE & MPU2_IRQ (and MPU3_BASE & MPU3_IRQ) to the file.
|
||||
|
||||
CAUTION!
|
||||
|
||||
The default I/O base of Adaptec AHA-1542 SCSI controller is 0x330 which
|
||||
is also the default of the MPU401 driver. Don't configure the sound driver to
|
||||
use 0x330 as the MPU401 base if you have a AHA1542. The kernel will not boot
|
||||
if you make this mistake.
|
||||
|
||||
PSS
|
||||
---
|
||||
|
||||
Even the PSS cards are compatible with SB, MSS and MPU401, you must not
|
||||
enable these options when configuring the driver. The configuration
|
||||
program handles these options itself. (You may use the SB, MPU and MSS options
|
||||
together with PSS if you have another card on the system).
|
||||
|
||||
The PSS driver enables MSS and MPU401 modes of the card. SB is not enabled
|
||||
since it doesn't work concurrently with MSS. The driver loads also a
|
||||
DSP algorithm which is used to for the general MIDI emulation. The
|
||||
algorithm file (.ld) is read by the config program and written to a
|
||||
file included when the pss.c is compiled. For this reason the config
|
||||
program asks if you want to download the file. Use the genmidi.ld file
|
||||
distributed with the DOS/Windows drivers of the card (don't use the mt32.ld).
|
||||
With some cards the file is called 'synth.ld'. You must have access to
|
||||
the file when configuring the driver. The easiest way is to mount the DOS
|
||||
partition containing the file with Linux.
|
||||
|
||||
It's possible to load your own DSP algorithms and run them with the card.
|
||||
Look at the directory sound/pss_test for more info (in the VoxWare-3.0.tar.gz)
|
||||
package.
|
||||
|
||||
AudioTriX Pro
|
||||
-------------
|
||||
|
||||
You have to enable the OPL3 and SB (not SB Pro or SB16) drivers in addition
|
||||
to the native AudioTriX driver. Don't enable MSS or MPU drivers.
|
||||
|
||||
Configuring ATP is little bit tricky since it uses so many I/O, IRQ and
|
||||
DMA numbers. Using the same values than with DOS/Win is a good idea. Don't
|
||||
attemp to use the same IRQ or DMA channels twice.
|
||||
|
||||
The SB mode of ATP is implemented so the the ATP driver just enables SB
|
||||
in the proper address. The SB driver handles the rest. Yoy have to configure
|
||||
both the SB driver and the SB mode of ATP to use the same IRQ, DMA and I/O
|
||||
settings.
|
||||
|
||||
Also the ATP has a microcontroller for the General MIDI emulation (OPL4).
|
||||
For this reason the driver asks for the name of a file containing the
|
||||
microcode (TRXPRO.HEX). This file is usually located in the directory
|
||||
where the DOS drivers were installed. You must have access to this file
|
||||
when configuring the driver.
|
||||
|
||||
If you have the effects daughtercard, it must be initialized by running
|
||||
the setfx program of snd-util-3.0.tar.gz package. This step is not required
|
||||
when using the (future) binary distribution version of the driver.
|
||||
|
||||
Ensoniq SoundScape
|
||||
------------------
|
||||
|
||||
The SoundScape driver handles initialization of MSS and MPU supports
|
||||
itself so you don't need to enable other drivers than SoundScape
|
||||
(enable also the /dev/dsp, /dev/sequencer and MIDI supports).
|
||||
|
||||
SoundScape driver uses the MSS compatible codec of the card. It's important
|
||||
to note that /dev/dsp0 (/dev/dsp is linked to /dev/dsp0 by default)
|
||||
doesn't work with SoundScape (yet). The 'ssinit' program needs /dev/dsp0 so
|
||||
that's the reason why it's there. It's possible that 'primary' pcm channel
|
||||
becomes supported later. Currently the card's firmware doesn't contain
|
||||
support for it.
|
||||
|
||||
With 3.0 of VoxWare you have to change your system to use /dev/dsp1 by default
|
||||
so execute: cd /dev;rm dsp;ln -s dsp1 dsp after you have installed VoxWare
|
||||
3.0 (first time).
|
||||
|
||||
The configuration program asks two DMA channels and two interrupts. One IRQ
|
||||
and one DMA is used by the MSS codec. The second IRQ is required for the
|
||||
MPU401 mode (you have to use different IRQs for both purposes).
|
||||
The second DMA channel is required for initialization of the microcontroller.
|
||||
You have to use separate DMA channels.
|
||||
|
||||
The SoundScape card has a Motorola microcontroller which must initialized
|
||||
_after_ boot (the driver doesn't initialize it during boot).
|
||||
The initialization is done by running the 'ssinit' program which is
|
||||
distributed in the snd-util-3.0.tar.gz package. You have to edit two
|
||||
defines in the ssinit.c and then compile the program. You may run ssinit
|
||||
manually (after each boot) or add it to /etc/rc.d/rc.local.
|
||||
|
||||
The ssinit program needs the microcode file that comes with the DOS/Windows
|
||||
driver of the card. You will need to use version 1.30.00 or later
|
||||
of the microcode file (sndscape.co0 or sndscape.co1 depending on
|
||||
your card model). THE OLD sndscape.cod WILL NOT WORK. IT WILL HANG YOUR
|
||||
MACHINE. The only way to get the new microcode file is to download
|
||||
and install the DOS/Windows driver from ftp://ftp.ensoniq.com/pub.
|
||||
|
||||
Then you have to select the proper microcode file to use: soundscape.co0
|
||||
is the right one for most cards and sndscape.co1 is for few (older) cards
|
||||
made by Reveal and/or Spea. The driver has capability to detect the card
|
||||
version during boot. Look at the boot log messages in /var/adm/messages
|
||||
and locate the sound driver initialization message for the SoundScape
|
||||
card. If the driver displays string <Ensoniq Soundscape (old)>, you have
|
||||
an old card and you will need to use sndscape.co1. For other cards use
|
||||
soundscape.co0.
|
||||
|
||||
Check /var/adm/messages after running ssinit. The driver prints
|
||||
the board version after downloading the microcode file. That version
|
||||
number must match the number in the name of the microcode file (extension).
|
||||
|
||||
Running ssinit with a wrong version of the sndscape.co? file is not
|
||||
dangerous as long as you don't try to use a file called sndscape.cod.
|
||||
If you have initialized the card using a wrong microcode file (sounds
|
||||
are terrible), just modify ssinit.c to use another microcode file and try
|
||||
again. It's possible to use an earlier version of sndscape.co[01] but it
|
||||
may sound wierd.
|
||||
|
||||
Btw, The driver may complain something about "sscapeintr()" after
|
||||
running ssinit. You should just ignore these messages.
|
||||
|
||||
MAD16 (Pro) and Mozart
|
||||
----------------------
|
||||
|
||||
You need to enable just the MAD16 /Mozart support when configuring
|
||||
the driver. _Don't_ enable SB, MPU401 or MSS. However you will need the
|
||||
/dev/audio, /dev/sequencer and MIDI supports.
|
||||
|
||||
Mozart and OPTi 82C928 (the original MAD16) chips don't support
|
||||
MPU401 mode so enter just 0 when the configuration program asks the
|
||||
MPU/MIDI I/O base. The MAD16 Pro (OPTi 82C929) has MPU401 mode.
|
||||
|
||||
TB Tropez is based on the 82C929 chip. It has two MIDI ports.
|
||||
The one connected to the MAD16 chip is the second one (there is a second
|
||||
MIDI connector/pins somewhere??). If you have not connected the second MIDI
|
||||
port, just disable the MIDI port of MAD16. The 'Maui' compatible synth of
|
||||
Tropez is jumper configurable and not connected to the MAD16 chip.
|
||||
It can be used by enabling the stand alone MPU401 support but you have
|
||||
to initialize it by using the MS-DOS SNDSETUP program.
|
||||
|
||||
There are some other OPTi chips which may be used in soundcards such as
|
||||
82C930 and MAC32. These chips are not supported by VoxWare yet. Please
|
||||
contact me if you have a soundcard which uses these chips.
|
||||
|
||||
Some MAD16 based cards may cause feedback, whistle or terrible noise if the
|
||||
line3 mixer channel is turned too high.
|
||||
|
||||
If you have a MAD16 card which have an OPL4 (FM + Wave table) synthesizer
|
||||
chip (_not_ an OPL3), you have to apped line containing #define MAD16_OPL4
|
||||
to the file linux/dirvers/sound/local.h (after running make config).
|
||||
|
||||
MV Jazz (ProSonic)
|
||||
------------------
|
||||
|
||||
The Jazz16 driver is just a hack made to the SB Pro driver. However it works
|
||||
fairly well. You have to enable SB, SB Pro (_not_ SB16) and MPU401 supports
|
||||
when configuring the driver. The configuration program asks later if you
|
||||
want support for MV Jazz16 based cards (after asking SB base address). Answer
|
||||
'y' here and the driver asks the second (16 bit) DMA channel.
|
||||
|
||||
The Jazz16 driver uses the MPU401 driver in a way which will cause
|
||||
problems if you have another MPU401 compatible card. In this case you must
|
||||
give address of the Jazz16 based MPU401 interface when the config
|
||||
program prompts for the MPU401 information. Then look at the MPU401
|
||||
spesific section for instructions about configuring more than one MPU401 cards.
|
||||
|
||||
Logitech Soundman Wave
|
||||
----------------------
|
||||
|
||||
Read the above MV Jazz spesific instructions first.
|
||||
|
||||
The Logitech SoundMan Wave (don't confuse with the SM16 or SM Games) is
|
||||
a MV Jazz based card which has an additional OPL4 based wave table
|
||||
synthesizer. The OPL4 chip is handled by an on board microcontroller
|
||||
which must be initialized during boot. The config program asks if
|
||||
you have a SM Wave immediately after asking the second DMA channel of jazz16.
|
||||
If you answer 'y', the config program will ask name of the file containing
|
||||
code to be loaded to the microcontroller. The file is usually called
|
||||
MIDI0001.BIN and it's located in the DOS/Windows driver directory. The file
|
||||
may also be called as TSUNAMI.BIN or something else (older cards?).
|
||||
|
||||
The OPL4 synth will be inaccessible without loading the microcontroller code.
|
||||
Also remember to enable MPU401 support if you want to use the OPL4 mode.
|
||||
|
||||
NOTE! Don't answer 'y' when the driver asks about SM Games support
|
||||
(the next question after the MIDI0001.BIN name). However
|
||||
aneswering 'y' is not dangerous.
|
||||
|
||||
Sound Galaxies
|
||||
--------------
|
||||
|
||||
There are many different Sound Galaxy cards made by Aztech. The 8 bit
|
||||
ones are fully SB or SB Pro compatible and there should be no problems
|
||||
with them.
|
||||
|
||||
The older 16 bit cards (SG Pro16, SG NX Pro16, Nova and Lyra) have
|
||||
an EEPROM chip for storing the configuration data. There is a microcontroller
|
||||
which initializes the card to match the EEPROM settigs when the machine
|
||||
is powered on. These cards actually behave just like they have jumpers
|
||||
for all of the settings. Configure VoxWare for MSS, MPU, SB/SB Pro and OPL3
|
||||
supports with these cards.
|
||||
|
||||
The config program asks if you want support for the mixer of
|
||||
SG NX Pro. Answer 'y' to these questions if you have one of the above 8 or
|
||||
16 bit Aztech cards.
|
||||
|
||||
There are some new Sound Galaxies in the market. I have no experience with
|
||||
them so read the card's manual carefully.
|
||||
|
||||
|
||||
Reveal cards
|
||||
------------
|
||||
|
||||
There are several different cards made/marketed by Reveal. Some of them
|
||||
are compatible with SoundScape and some use the MAD16 chip. You may have
|
||||
to look at the card and try to identify origin of the card.
|
||||
|
||||
Diamond
|
||||
-------
|
||||
|
||||
The oldest (Sierra Aria based) soundcards made by Diamond are not supported
|
||||
(they may work if the card is initialized using DOS). The recent (LX?)
|
||||
models are based on the MAD16 chip which is supported by VoxWare.
|
||||
|
||||
Audio Excel DSP16
|
||||
-----------------
|
||||
|
||||
See comments in aedsp16.c.
|
||||
|
||||
|
||||
PCMCIA cards
|
||||
------------
|
||||
|
||||
Sorry, can't help. Some cards may work and some don't.
|
||||
|
||||
TI TM4000M notebooks
|
||||
--------------------
|
||||
|
||||
These computers have a built in sound support based on the Jazz chipset.
|
||||
Look at the instructions for MV Jazz (above). It's also important to note
|
||||
that there is something wrong with the mouse port and sound at least on
|
||||
some TM models. Don't enable the "C&T 82C710 mouse port support" when
|
||||
configuring Linux. Having it enabled is likely to cause mysterious problems
|
||||
and kernel failures when sound is used.
|
||||
|
||||
Others?
|
||||
-------
|
||||
|
||||
Since there are so many different soundcards, it's likely that I have
|
||||
forgotten to mention many of them. Please inform me if you know yet another
|
||||
card which works with Linux, please inform me (or is anybody else
|
||||
willing to maintain a database of supported cards (just like in XF86)?).
|
||||
|
||||
Cards not supported yet
|
||||
=======================
|
||||
|
||||
First of all. There is an easy way to make most soundcards to work
|
||||
with Linux. Just use the DOS based driver to initialize the card
|
||||
to a _known_ state. Then ctrl-alt-del to Linux. If Linux is configured
|
||||
to use the sama I/O, IRQ and DMA numbers than DOS, the card could work.
|
||||
|
||||
Don't get fooled with SB compatibility. Most cards are compatible with
|
||||
SB but that may require a TSR which is not possible with Linux. If
|
||||
the card is compatible with MSS, it's a better choise. Some cards
|
||||
don't work in the SB and MSS modes at the same time.
|
||||
|
||||
There are some cards which will be supported by VoxWare sooner or later
|
||||
(currently at least cards based on the ESS chipset). Such cards are
|
||||
so common that there is some idea in writing the driver. Check the
|
||||
VoxWare home page (http://personal.eunet.fi/pp/voxware) for latest
|
||||
information.
|
||||
|
||||
Then there are cards which are no longer manufactured and/or which
|
||||
are relatively rarely used (such as the 8 bit ProAudioSpectrum
|
||||
models). It's extremely unlikely that such cards never get supported.
|
||||
Adding support for a new card requires much work and increases time
|
||||
required in maintaining the driver (some changes need to be done
|
||||
to all low level drivers and be tested too, maybe with multiple
|
||||
operating systems). For this reason I have made a desicion to not support
|
||||
obsolete cards. It's possible that someone else makes a separately
|
||||
distributed driver (diffs) for the card. Version v4.0 will be much more
|
||||
modular so making separately distributed drivers will be easier with it.
|
||||
(The bad news is that v4.0 will not be available before late -96).
|
||||
|
||||
Writing a driver for a new card is not possible if there are no
|
||||
programming information available about the card. If you don't
|
||||
find your new card from this file, look from the home page
|
||||
(http://personal.eunet.fi/pp/voxware). Then please contact
|
||||
manufacturer of the card and ask if they have (or are willing to)
|
||||
released technical details of the card. Do this before contacting me. I
|
||||
can only answer 'no' if there are no programming information available.
|
||||
|
||||
Some companies don't give low level technical information about their
|
||||
products to public or at least their require signing a NDA.
|
||||
|
||||
I have also made decicion to not accept code based on reverse engineering
|
||||
to VoxWare. There are three main reasons: First I don't want to break
|
||||
relationships to sound card manufacturers. The second reason is that
|
||||
maintaining and supporting a driver withoun any specs will be a pain. The
|
||||
third reason is that why shoud we help such companies in selling their
|
||||
products to Linux users when they don't want to sell to Linux users
|
||||
at all?
|
||||
|
||||
Unfortunately many of the leading soundcard manufacturers are not willing
|
||||
to co-operate with Linux/Unix community. For example: Creative Technology
|
||||
doesn't give information about the ASP chip and the Emu synth chip of AWE32
|
||||
and SB32. Turtle Beach don't give information about any of their
|
||||
products. MediaVision requires NDA before they are willing to
|
||||
give information about the Jazz16 chip (fortunately Logitech gave
|
||||
the info about SM Wave).
|
||||
|
||||
So at least the above three companies are out until they are willing to
|
||||
release documentation about their products (the situation is the
|
||||
same with many DOS based freeware/shareware games and utilities). If
|
||||
you want to use Linux/Unix with their cards, please don't try to push
|
||||
me. It's a better idea to contact the manufacturer and explain that
|
||||
you want to use your card with Linux/Unix. You could also try to sell
|
||||
your card to somebody else and then buy a card that is supported by VoxWare.
|
||||
|
||||
However it's possible that things change and a driver gets written
|
||||
for some of the banned cards. Please, don't send me messages asking if
|
||||
there is any plans to write a driver for the cards mentioned above. I
|
||||
will put any news to the VoxWare www home page (see below).
|
||||
|
||||
There are some common audio chipsets that are supported yet. For example
|
||||
the ESS chips and Sierra Aria. It's likely that these architectures
|
||||
get some support in future but I can't make any promises. Just look
|
||||
at the home page for latest info.
|
||||
|
||||
Information about unsupported soundcards and chipsets is welcome as well
|
||||
as free copies of soundcards, SDKs and operating systems.
|
||||
|
||||
If you have any corrections and/or comments, please contact me.
|
||||
|
||||
Hannu Savolainen
|
||||
hannu@voxware.pp.fi
|
||||
VoxWare www home page: http://personal.eunet.fi/pp/voxware
|
||||
|
@ -1,99 +0,0 @@
|
||||
Building a loadable sound driver
|
||||
================================
|
||||
|
||||
Loadable module support in version 3.5 of VoxWare is mostly rewritten since
|
||||
the previous version (3.0.1). This means that some things have changed.
|
||||
|
||||
To compile the sound driver as a loadable module you have to perform
|
||||
the following steps:
|
||||
|
||||
1) Install modules-1.2.8.tar.gz package (or later if available).
|
||||
2a) Check that symbol remap_page_range is defined in linux/init/ksyms.c.
|
||||
Insert a line containing "X(remap_page_range)," if required. The driver will
|
||||
not load if this line is missing.
|
||||
2b) Recompile kernel with soundcard support disabled.
|
||||
3) Boot the new kernel.
|
||||
4) cd to the sound driver source directory (this directory). It's no
|
||||
longer required that the sound driver sources are installed in the
|
||||
kernel source tree (linux/drivers/sound). When installing a separately
|
||||
distributed sound driver you may install the sources for example to
|
||||
/usr/src/sound.
|
||||
5) Execute make in the sound driver source directory. Enter
|
||||
configuration parameters as described in Readme.cards. Then just wait until
|
||||
the driver is compiled OK.
|
||||
6) Copy sound.o to the directory where insmod expects to find it.
|
||||
("make install" copies it to /lib/modules/misc).
|
||||
7) Use command "insmod sound" to load the driver.
|
||||
|
||||
8) The sound driver can be removed using command "rmmod sound".
|
||||
|
||||
|
||||
Parameters accepted by the loadable sound driver
|
||||
================================================
|
||||
|
||||
Setting DMA buffer size
|
||||
-----------------------
|
||||
|
||||
The driver allocates a DMA buffer (or two for full duplex devices)
|
||||
every time the audio device (/dev/dsp or /dev/audio) is opened
|
||||
and frees it when the device is closed. Size of this buffer is defined
|
||||
when the driver is configured (the last question). The buffer size
|
||||
can be redefined when loading the driver if required (note that this is
|
||||
an optional feature which is not normally required). The buffer size
|
||||
is redefined by adding dma_pagesize= parameter to the insmod command line.
|
||||
For example:
|
||||
|
||||
insmod sound dma_buffsize=32768
|
||||
|
||||
Minimum buffer size is 4096 and the maximum depends on the DMA channe.
|
||||
For 8 bit channels (0 to 3) the limit is 64k and for 16 bit ones (5 to 7)
|
||||
it's 128k. Driver selects a suitable buffer size automaticly in case
|
||||
you try to spesify an invalid size.
|
||||
|
||||
Q: What is the right DMA buffer size?
|
||||
|
||||
A: It depends on the sampling rate, machine speed and the load of the system.
|
||||
Large buffers are required on slow machines, when recording/playing CD-quality
|
||||
audio or when there are other processes running on the same system. Also
|
||||
recording to hard disk is likely to require large buffers.
|
||||
|
||||
Very small buffers are sufficient when you are just playing 8kHz audio files
|
||||
on an empty P133 system. Using a 128k byffer just wastes 120k (or 250k)
|
||||
of valuable physical RAM memory.
|
||||
|
||||
The right buffer sice can be easily found by making some experiments
|
||||
with the dma_buffsize= parameter. I use usually 16k buffers on a DX4/100 system
|
||||
and 64k on an old 386 system.
|
||||
|
||||
NOTE! DMA buffers are used only by /dev/audio# and /dev/dsp# devices.
|
||||
Other device files don't use them but there are two exceptions:
|
||||
GUS driver uses DMA buffers when loading samples to the card.
|
||||
Ensoniq SoundScape driver uses them when doanloading the microcode
|
||||
file (sndscape.co[012]) to the card. Using large buffers doesn't
|
||||
increase performance in these cases.
|
||||
|
||||
Configuring device parameters when loading the driver
|
||||
-----------------------------------------------------
|
||||
|
||||
The loadable version of the sound driver accepts now the same
|
||||
sound= parameter that has been available in the LILO command line.
|
||||
In this way it's possible to change I/O port, IRQ and DMA addresses
|
||||
and to enable/disable various cards at load time. Normally
|
||||
the driver uses the configuration parameters entered when compiling
|
||||
and configuring the driver.
|
||||
Look at Readme.linux for more info.
|
||||
|
||||
NOTE! This method is not normally required. You should use it only when
|
||||
you have to use different configuration than normally. The sound=
|
||||
command line parameter is error phrone and not recommended.
|
||||
|
||||
Debugging and tracing
|
||||
---------------------
|
||||
|
||||
Modularized sound driver doesn't display messages during initialization as
|
||||
the kernel compiled one does. This feature can be turned on by adding
|
||||
init_trace=1 to the insmod command line.
|
||||
|
||||
For example:
|
||||
|
||||
insmod sound init_trace=1
|
@ -1,140 +0,0 @@
|
||||
VoxWare v3.0
|
||||
------------
|
||||
|
||||
All features of v2.90-2 should work as earlier. There could be some
|
||||
omissions but they are unintentional. I started this version thread
|
||||
after v2.3 so all features implemented before it are there.
|
||||
|
||||
New features
|
||||
============
|
||||
|
||||
There are now two new device interfaces. The /dev/midi## is a raw
|
||||
tty like interface to MIDI ports. There is a device file for each MIDI
|
||||
port on your system. They are named (/dev/midi00 to /dev/midiNN).
|
||||
The second addition is the /dev/music which is higher level interface
|
||||
than the old /dev/sequencer. It's intended for writing device independent
|
||||
applications like sequencers.
|
||||
|
||||
/dev/midi##
|
||||
-----------
|
||||
|
||||
This interface should be usefull for applications like MIDI sysex librarians.
|
||||
There are (currently) no timing features so making music could be impossible.
|
||||
|
||||
There are as many /dev/midi## devices as there are MIDI ports in the system.
|
||||
The /dev/midi00 is connected to the first one, /dev/midi01 to the second etc.
|
||||
|
||||
These devices work like tty devices in raw mode. Everything written to them is
|
||||
sent out to the MIDI port. There is currently an extra delay of at most
|
||||
1/100th of sec but it will be removed later.
|
||||
|
||||
The reading algorithm is little bit more complicated. There are two different
|
||||
cases:
|
||||
|
||||
1) There is at least one byte in the input buffer.
|
||||
|
||||
The read returns as many bytes as it can without waiting for more bytes.
|
||||
For example when a process reads 100 bytes and there are 10 bytes in the
|
||||
buffer, the read returns just 10 bytes.
|
||||
|
||||
2) The input buffer is empty when the process calls read.
|
||||
|
||||
The read waits for the first byte and then continues as in case 1. By
|
||||
default it waits infinitely but there is an ioctl for setting a timeout
|
||||
for this. The ioctl(fd, SNDCTL_MIDI_PRETIME, &time) changes the timeout.
|
||||
The time is given in 1/10th of seconds (10 means one second).
|
||||
|
||||
Other ioctl calls:
|
||||
|
||||
ioctl(fd, SNDCTL_MIDI_MPUMODE, &mode) is available for full MPU-401
|
||||
compatible devices such as MPU-IPC-T, MQ PC Midi Card or MQX-32.
|
||||
It's not available for the so called MPU UART ports of some soundcards
|
||||
(PAS16, SB16 etc). By default the MIDI port is in UART mode after open.
|
||||
If this ioctl is called with mode=1, the interface is put to the intelligent
|
||||
(coprocessor) mode. NOTE! The MIDI port will be reset when this ioctl is called.
|
||||
It could have some strange effects if not called immediately after open. This
|
||||
vall returns EINVAL if the midi port doesn't support the MPU-401 intelligent
|
||||
mode.
|
||||
|
||||
ioctl(fd, SNDCTL_MIDI_MPUCMD, &cmdstruct) is valid only if the MIDI port
|
||||
is put to the coprocessor mode using ioctl(SNDCTL_MIDI_MPUMODE). It's used to
|
||||
send commands to a MPU-401 compatible MIDI cards. Please refer to the
|
||||
MPU-401 Technical Reference Manual (or Music Quest Technical Reference
|
||||
Manual) for descriptions of the commands.
|
||||
|
||||
The argument of SNDCTL_MIDI_MPUCOMMAND is of type mpu_command_rec. It
|
||||
has the following fields:
|
||||
|
||||
typedef struct {
|
||||
unsigned char cmd;
|
||||
|
||||
char nr_args, nr_returns;
|
||||
unsigned char data[30];
|
||||
} mpu_command_rec;
|
||||
|
||||
where:
|
||||
cmd Contains the command number.
|
||||
nr_args Number of arguments of the command.
|
||||
MUST BE INITIALIZED BEFORE CALL
|
||||
nr_returns Number of bytes returned by the command.
|
||||
MUST BE INITIALIZED BEFORE CALL
|
||||
data Buffer for the command arguments and returned
|
||||
data.
|
||||
|
||||
Be extremely carefull with the nr_args and nr_returns fields. They
|
||||
must match the command. An incorrect value will put the card and
|
||||
the driver out of sync. Refer to the MPU-401/MQX-32M documentation for further
|
||||
datails.
|
||||
|
||||
|
||||
|
||||
/dev/music (/dev/sequencer2)
|
||||
----------------------------
|
||||
|
||||
This device file works much like the /dev/sequencer which has been present
|
||||
since the beginning. The main differences are the following:
|
||||
|
||||
- /dev/sequencer makes the MIDI ports to look like the synth devices. In fact
|
||||
the result is somewhere between the MIDI specification and the synth devices of
|
||||
/dev/sequencer. Both kind of devices are accessed using the SEQ_START_NOTE()
|
||||
like macros. The voice number parameters of the API macros have been redefined
|
||||
to denote MIDI channels. This means that the driver allocates voices for
|
||||
the channels automaticly (this is a responsibility/right of an application
|
||||
with /dev/sequencer). The result is that a SEQ_START_NOTE() macro has
|
||||
similar effects for a synth channel than on a MIDI port. This kind of
|
||||
solution provides better device independence than the /dev/sequencer. The
|
||||
drawback is that the new interface doesn't permit so low level access to the
|
||||
device as the /dev/sequencer does. An application developer must choose between
|
||||
these two interfaces. I think the old /dev/sequencer is better for applications
|
||||
like module players while the new one is better for making generic sequencer
|
||||
programs.
|
||||
|
||||
- There are no separate MIDI devices with the /dev/sequencer2. The
|
||||
ioctl(SNDCTL_SEQ_NRMIDIS) returns always zero. Instead the MIDI ports are
|
||||
shown as synth devices. ioctl(SNDCTL_SEQ_NRSYNTHS) on /dev/sequencer2 will
|
||||
return sum of internal synthesizers (GUS, OPL3) and MIDI ports in the systems.
|
||||
|
||||
- The new interface is used much like the ordinary /dev/sequencer. The
|
||||
event format is new so you have to use the API macros defined in the
|
||||
sys/soundcard.h. The interface is will propably change before the final 3.0
|
||||
release but using the API macros should ensure compatibility in source level.
|
||||
The new event format is not recognized by version 2.X so don't try to
|
||||
distribute binaries compiled with soundcard.h of v3.X.
|
||||
|
||||
- The basic API useage is similar to the current one. There are some new
|
||||
macros but the older ones should work as earlier. The most important
|
||||
incompatibility is that the /dev/sequencer2 driver allocates voices itself.
|
||||
The other one is that the application must send SEQ_START_TIMER() as its
|
||||
first event. Otherwise the timer is not started and the application waits
|
||||
infinitely.
|
||||
|
||||
|
||||
There are several new features but I don't document them here. There are
|
||||
some info in the soundcard.h (near the end). I have also included some
|
||||
sample code in the directory v30. Full documentation will
|
||||
appear in the Hacker's Guide later.
|
||||
|
||||
Don't hesitate to contact me in case you have questions or comments.
|
||||
|
||||
Hannu Savolainen
|
||||
hannu@voxware.pp.fi
|
File diff suppressed because it is too large
Load Diff
@ -1,142 +0,0 @@
|
||||
/*
|
||||
* sound/ad1848_mixer.h
|
||||
*
|
||||
* Definitions for the mixer of AD1848 and compatible codecs.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1994
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* The AD1848 codec has generic input lines called Line, Aux1 and Aux2.
|
||||
* Soundcard manufacturers have connected actual inputs (CD, synth, line,
|
||||
* etc) to these inputs in different order. Therefore it's difficult
|
||||
* to assign mixer channels to to these inputs correctly. The following
|
||||
* contains two alternative mappings. The first one is for GUS MAX and
|
||||
* the second is just a generic one (line1, line2 and line3).
|
||||
* (Actually this is not a mapping but rather some kind of interleaving
|
||||
* solution).
|
||||
*/
|
||||
#define GUSMAX_MIXER
|
||||
#ifdef GUSMAX_MIXER
|
||||
#define MODE1_REC_DEVICES (SOUND_MASK_LINE | SOUND_MASK_MIC | \
|
||||
SOUND_MASK_CD|SOUND_MASK_IMIX)
|
||||
|
||||
#define MODE1_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_MIC | \
|
||||
SOUND_MASK_CD | \
|
||||
SOUND_MASK_IGAIN | \
|
||||
SOUND_MASK_PCM|SOUND_MASK_IMIX)
|
||||
|
||||
#define MODE2_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_LINE | SOUND_MASK_MIC | \
|
||||
SOUND_MASK_CD | SOUND_MASK_SPEAKER | \
|
||||
SOUND_MASK_IGAIN | \
|
||||
SOUND_MASK_PCM | SOUND_MASK_IMIX)
|
||||
#else /* Generic mapping */
|
||||
#define MODE1_REC_DEVICES (SOUND_MASK_LINE3 | SOUND_MASK_MIC | \
|
||||
SOUND_MASK_LINE1|SOUND_MASK_IMIX)
|
||||
|
||||
#define MODE1_MIXER_DEVICES (SOUND_MASK_LINE1 | SOUND_MASK_MIC | \
|
||||
SOUND_MASK_LINE2 | \
|
||||
SOUND_MASK_IGAIN | \
|
||||
SOUND_MASK_PCM | SOUND_MASK_IMIX)
|
||||
|
||||
#define MODE2_MIXER_DEVICES (SOUND_MASK_LINE1 | SOUND_MASK_LINE2 | SOUND_MASK_MIC | \
|
||||
SOUND_MASK_LINE3 | SOUND_MASK_SPEAKER | \
|
||||
SOUND_MASK_IGAIN | \
|
||||
SOUND_MASK_PCM | SOUND_MASK_IMIX)
|
||||
#endif
|
||||
|
||||
struct mixer_def {
|
||||
unsigned int regno: 7;
|
||||
unsigned int polarity:1; /* 0=normal, 1=reversed */
|
||||
unsigned int bitpos:4;
|
||||
unsigned int nbits:4;
|
||||
};
|
||||
|
||||
static char mix_cvt[101] = {
|
||||
0, 0,3,7,10,13,16,19,21,23,26,28,30,32,34,35,37,39,40,42,
|
||||
43,45,46,47,49,50,51,52,53,55,56,57,58,59,60,61,62,63,64,65,
|
||||
65,66,67,68,69,70,70,71,72,73,73,74,75,75,76,77,77,78,79,79,
|
||||
80,81,81,82,82,83,84,84,85,85,86,86,87,87,88,88,89,89,90,90,
|
||||
91,91,92,92,93,93,94,94,95,95,96,96,96,97,97,98,98,98,99,99,
|
||||
100
|
||||
};
|
||||
|
||||
typedef struct mixer_def mixer_ent;
|
||||
|
||||
/*
|
||||
* Most of the mixer entries work in backwards. Setting the polarity field
|
||||
* makes them to work correctly.
|
||||
*
|
||||
* The channel numbering used by individual soundcards is not fixed. Some
|
||||
* cards have assigned different meanings for the AUX1, AUX2 and LINE inputs.
|
||||
* The current version doesn't try to compensate this.
|
||||
*/
|
||||
|
||||
#define MIX_ENT(name, reg_l, pola_l, pos_l, len_l, reg_r, pola_r, pos_r, len_r) \
|
||||
{{reg_l, pola_l, pos_l, len_l}, {reg_r, pola_r, pos_r, len_r}}
|
||||
|
||||
mixer_ent mix_devices[32][2] = { /* As used in GUS MAX */
|
||||
MIX_ENT(SOUND_MIXER_VOLUME, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_SYNTH, 4, 1, 0, 5, 5, 1, 0, 5),
|
||||
MIX_ENT(SOUND_MIXER_PCM, 6, 1, 0, 6, 7, 1, 0, 6),
|
||||
MIX_ENT(SOUND_MIXER_SPEAKER, 26, 1, 0, 4, 0, 0, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_LINE, 18, 1, 0, 5, 19, 1, 0, 5),
|
||||
MIX_ENT(SOUND_MIXER_MIC, 0, 0, 5, 1, 1, 0, 5, 1),
|
||||
MIX_ENT(SOUND_MIXER_CD, 2, 1, 0, 5, 3, 1, 0, 5),
|
||||
MIX_ENT(SOUND_MIXER_IMIX, 13, 1, 2, 6, 0, 0, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_IGAIN, 0, 0, 0, 4, 1, 0, 0, 4),
|
||||
MIX_ENT(SOUND_MIXER_OGAIN, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 0, 5, 3, 1, 0, 5),
|
||||
MIX_ENT(SOUND_MIXER_LINE2, 4, 1, 0, 5, 5, 1, 0, 5),
|
||||
MIX_ENT(SOUND_MIXER_LINE3, 18, 1, 0, 5, 19, 1, 0, 5)
|
||||
};
|
||||
|
||||
static unsigned short default_mixer_levels[SOUND_MIXER_NRDEVICES] =
|
||||
{
|
||||
0x5a5a, /* Master Volume */
|
||||
0x3232, /* Bass */
|
||||
0x3232, /* Treble */
|
||||
0x4b4b, /* FM */
|
||||
0x4040, /* PCM */
|
||||
0x4b4b, /* PC Speaker */
|
||||
/* 0x2020, Ext Line */
|
||||
0x0000, /* Ext Line */
|
||||
0x4040, /* Mic */
|
||||
0x4b4b, /* CD */
|
||||
0x0000, /* Recording monitor */
|
||||
0x4b4b, /* SB PCM */
|
||||
0x4b4b, /* Recording level */
|
||||
0x2525, /* Input gain */
|
||||
0x0000, /* Output gain */
|
||||
/* 0x4040, Line1 */
|
||||
0x0000, /* Line1 */
|
||||
0x0000, /* Line2 */
|
||||
0x1515, /* Line3 (usually line in)*/
|
||||
};
|
||||
|
||||
#define LEFT_CHN 0
|
||||
#define RIGHT_CHN 1
|
||||
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* sound/adlib_card.c
|
||||
*
|
||||
* Detection routine for the AdLib card.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if defined(CONFIG_YM3812)
|
||||
|
||||
void
|
||||
attach_adlib_card(struct address_info * hw_config)
|
||||
{
|
||||
opl3_init(hw_config->io_base, hw_config->osp);
|
||||
}
|
||||
|
||||
int
|
||||
probe_adlib(struct address_info * hw_config)
|
||||
{
|
||||
return opl3_detect(hw_config->io_base, hw_config->osp);
|
||||
}
|
||||
|
||||
#endif
|
@ -1,73 +0,0 @@
|
||||
static unsigned char alaw_linear[] = {
|
||||
45, 214, 122, 133, 0, 255, 107, 149,
|
||||
86, 171, 126, 129, 0, 255, 117, 138,
|
||||
13, 246, 120, 135, 0, 255, 99, 157,
|
||||
70, 187, 124, 131, 0, 255, 113, 142,
|
||||
61, 198, 123, 132, 0, 255, 111, 145,
|
||||
94, 163, 127, 128, 0, 255, 119, 136,
|
||||
29, 230, 121, 134, 0, 255, 103, 153,
|
||||
78, 179, 125, 130, 0, 255, 115, 140,
|
||||
37, 222, 122, 133, 0, 255, 105, 151,
|
||||
82, 175, 126, 129, 0, 255, 116, 139,
|
||||
5, 254, 120, 135, 0, 255, 97, 159,
|
||||
66, 191, 124, 131, 0, 255, 112, 143,
|
||||
53, 206, 123, 132, 0, 255, 109, 147,
|
||||
90, 167, 127, 128, 0, 255, 118, 137,
|
||||
21, 238, 121, 134, 0, 255, 101, 155,
|
||||
74, 183, 125, 130, 0, 255, 114, 141,
|
||||
49, 210, 123, 133, 0, 255, 108, 148,
|
||||
88, 169, 127, 129, 0, 255, 118, 138,
|
||||
17, 242, 121, 135, 0, 255, 100, 156,
|
||||
72, 185, 125, 131, 0, 255, 114, 142,
|
||||
64, 194, 124, 132, 0, 255, 112, 144,
|
||||
96, 161, 128, 128, 1, 255, 120, 136,
|
||||
33, 226, 122, 134, 0, 255, 104, 152,
|
||||
80, 177, 126, 130, 0, 255, 116, 140,
|
||||
41, 218, 122, 133, 0, 255, 106, 150,
|
||||
84, 173, 126, 129, 0, 255, 117, 139,
|
||||
9, 250, 120, 135, 0, 255, 98, 158,
|
||||
68, 189, 124, 131, 0, 255, 113, 143,
|
||||
57, 202, 123, 132, 0, 255, 110, 146,
|
||||
92, 165, 127, 128, 0, 255, 119, 137,
|
||||
25, 234, 121, 134, 0, 255, 102, 154,
|
||||
76, 181, 125, 130, 0, 255, 115, 141,
|
||||
|
||||
};
|
||||
|
||||
#ifndef LINEAR_ALAW_NOT_WANTED
|
||||
static unsigned char linear_alaw[] = {
|
||||
|
||||
252, 172, 172, 172, 172, 80, 80, 80,
|
||||
80, 208, 208, 208, 208, 16, 16, 16,
|
||||
16, 144, 144, 144, 144, 112, 112, 112,
|
||||
112, 240, 240, 240, 240, 48, 48, 48,
|
||||
48, 176, 176, 176, 176, 64, 64, 64,
|
||||
64, 192, 192, 192, 192, 0, 0, 0,
|
||||
0, 128, 128, 128, 128, 96, 96, 96,
|
||||
96, 224, 224, 224, 224, 32, 32, 32,
|
||||
160, 160, 88, 88, 216, 216, 24, 24,
|
||||
152, 152, 120, 120, 248, 248, 56, 56,
|
||||
184, 184, 72, 72, 200, 200, 8, 8,
|
||||
136, 136, 104, 104, 232, 232, 40, 40,
|
||||
168, 86, 214, 22, 150, 118, 246, 54,
|
||||
182, 70, 198, 6, 134, 102, 230, 38,
|
||||
166, 222, 158, 254, 190, 206, 142, 238,
|
||||
210, 242, 194, 226, 218, 250, 202, 234,
|
||||
235, 203, 251, 219, 227, 195, 243, 211,
|
||||
175, 239, 143, 207, 191, 255, 159, 223,
|
||||
167, 39, 231, 103, 135, 7, 199, 71,
|
||||
183, 55, 247, 119, 151, 23, 215, 87,
|
||||
87, 169, 169, 41, 41, 233, 233, 105,
|
||||
105, 137, 137, 9, 9, 201, 201, 73,
|
||||
73, 185, 185, 57, 57, 249, 249, 121,
|
||||
121, 153, 153, 25, 25, 217, 217, 89,
|
||||
89, 89, 161, 161, 161, 161, 33, 33,
|
||||
33, 33, 225, 225, 225, 225, 97, 97,
|
||||
97, 97, 129, 129, 129, 129, 1, 1,
|
||||
1, 1, 193, 193, 193, 193, 65, 65,
|
||||
65, 65, 177, 177, 177, 177, 49, 49,
|
||||
49, 49, 241, 241, 241, 241, 113, 113,
|
||||
113, 113, 145, 145, 145, 145, 17, 17,
|
||||
17, 17, 209, 209, 209, 209, 81, 253,
|
||||
};
|
||||
#endif /* !LINEAR_ALAW_NOT_WANTED */
|
@ -1,440 +0,0 @@
|
||||
/*
|
||||
* sound/audio.c
|
||||
*
|
||||
* Device file manager for /dev/audio
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#ifdef CONFIG_AUDIO
|
||||
|
||||
#include <i386/isa/sound/ulaw.h>
|
||||
#include <i386/isa/sound/coproc.h>
|
||||
|
||||
#define ON 1
|
||||
#define OFF 0
|
||||
int
|
||||
DMAbuf_poll(int dev, struct fileinfo * file, int events, select_table * wait);
|
||||
|
||||
int
|
||||
audio_poll(int dev, struct fileinfo * file, int events, select_table * wait);
|
||||
|
||||
static int wr_buff_no[MAX_AUDIO_DEV];
|
||||
/* != -1, if there is a incomplete output block in the queue. */
|
||||
static int wr_buff_size[MAX_AUDIO_DEV], wr_buff_ptr[MAX_AUDIO_DEV];
|
||||
|
||||
static int audio_mode[MAX_AUDIO_DEV];
|
||||
static int dev_nblock[MAX_AUDIO_DEV]; /* 1 if in noblocking mode */
|
||||
|
||||
#define AM_NONE 0
|
||||
#define AM_WRITE 1
|
||||
#define AM_READ 2
|
||||
|
||||
static char *wr_dma_buf[MAX_AUDIO_DEV];
|
||||
static int audio_format[MAX_AUDIO_DEV];
|
||||
static int local_conversion[MAX_AUDIO_DEV];
|
||||
|
||||
static int
|
||||
set_format(int dev, int fmt)
|
||||
{
|
||||
if (fmt != AFMT_QUERY) {
|
||||
|
||||
local_conversion[dev] = 0;
|
||||
|
||||
if (!(audio_devs[dev]->format_mask & fmt)) { /* Not supported */
|
||||
if (fmt == AFMT_MU_LAW) {
|
||||
fmt = AFMT_U8;
|
||||
local_conversion[dev] = AFMT_MU_LAW;
|
||||
} else
|
||||
fmt = AFMT_U8; /* This is always supported */
|
||||
}
|
||||
audio_format[dev] = DMAbuf_ioctl(dev, SNDCTL_DSP_SETFMT,
|
||||
(ioctl_arg) fmt, 1);
|
||||
}
|
||||
if (local_conversion[dev]) /* This shadows the HW format */
|
||||
return local_conversion[dev];
|
||||
|
||||
return audio_format[dev];
|
||||
}
|
||||
|
||||
int
|
||||
audio_open(int dev, struct fileinfo * file)
|
||||
{
|
||||
int ret;
|
||||
int bits;
|
||||
int dev_type = dev & 0x0f;
|
||||
int mode = file->mode & O_ACCMODE;
|
||||
|
||||
dev = dev >> 4;
|
||||
|
||||
bits = (dev_type == SND_DEV_DSP16) ? 16 : 8 ;
|
||||
|
||||
if ((ret = DMAbuf_open(dev, mode)) < 0)
|
||||
return ret;
|
||||
|
||||
if (audio_devs[dev]->coproc)
|
||||
if ((ret = audio_devs[dev]->coproc->
|
||||
open(audio_devs[dev]->coproc->devc, COPR_PCM)) < 0) {
|
||||
audio_release(dev, file);
|
||||
printf("Sound: Can't access coprocessor device\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
local_conversion[dev] = 0;
|
||||
|
||||
if (DMAbuf_ioctl(dev, SNDCTL_DSP_SETFMT, (ioctl_arg) bits, 1) != bits) {
|
||||
audio_release(dev, file);
|
||||
return -(ENXIO);
|
||||
}
|
||||
|
||||
set_format(dev, (dev_type == SND_DEV_AUDIO) ? AFMT_MU_LAW : bits ) ;
|
||||
|
||||
wr_buff_no[dev] = -1;
|
||||
audio_mode[dev] = AM_NONE;
|
||||
wr_buff_size[dev] = wr_buff_ptr[dev] = 0;
|
||||
dev_nblock[dev] = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
audio_release(int dev, struct fileinfo * file)
|
||||
{
|
||||
int mode;
|
||||
|
||||
dev = dev >> 4;
|
||||
mode = file->mode & O_ACCMODE;
|
||||
|
||||
if (wr_buff_no[dev] >= 0) {
|
||||
DMAbuf_start_output(dev, wr_buff_no[dev], wr_buff_ptr[dev]);
|
||||
wr_buff_no[dev] = -1;
|
||||
}
|
||||
if (audio_devs[dev]->coproc)
|
||||
audio_devs[dev]->coproc->close(audio_devs[dev]->coproc->devc,COPR_PCM);
|
||||
DMAbuf_release(dev, mode);
|
||||
audio_devs[dev]->dmap_out->mapping_flags &= ~DMA_MAP_MAPPED ;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
translate_bytes(const u_char *table, u_char *buff, int n)
|
||||
{
|
||||
u_long i;
|
||||
|
||||
if (n <= 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < n; ++i)
|
||||
buff[i] = table[buff[i]];
|
||||
}
|
||||
|
||||
int
|
||||
audio_write(int dev, struct fileinfo * file, snd_rw_buf * buf, int count)
|
||||
{
|
||||
int c, p, l;
|
||||
int err;
|
||||
|
||||
dev = dev >> 4;
|
||||
|
||||
p = 0;
|
||||
c = count;
|
||||
if ((audio_mode[dev] & AM_READ) &&
|
||||
!(audio_devs[dev]->flags & DMA_DUPLEX)) { /* Direction change */
|
||||
wr_buff_no[dev] = -1;
|
||||
}
|
||||
if (audio_devs[dev]->flags & DMA_DUPLEX)
|
||||
audio_mode[dev] |= AM_WRITE;
|
||||
else
|
||||
audio_mode[dev] = AM_WRITE;
|
||||
|
||||
if (!count) { /* Flush output */
|
||||
if (wr_buff_no[dev] >= 0) {
|
||||
DMAbuf_start_output(dev, wr_buff_no[dev], wr_buff_ptr[dev]);
|
||||
wr_buff_no[dev] = -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
while (c) { /* Perform output blocking */
|
||||
if (wr_buff_no[dev] < 0) {
|
||||
/* There is no incomplete buffers */
|
||||
if ((wr_buff_no[dev] = DMAbuf_getwrbuffer(dev,
|
||||
&wr_dma_buf[dev], &wr_buff_size[dev],
|
||||
dev_nblock[dev])) < 0) {
|
||||
/* Handle nonblocking mode */
|
||||
if (dev_nblock[dev] && wr_buff_no[dev] == -(EAGAIN))
|
||||
return p; /* No more space. Return # of accepted bytes */
|
||||
return wr_buff_no[dev];
|
||||
}
|
||||
wr_buff_ptr[dev] = 0;
|
||||
}
|
||||
l = c;
|
||||
if (l > (wr_buff_size[dev] - wr_buff_ptr[dev]))
|
||||
l = (wr_buff_size[dev] - wr_buff_ptr[dev]);
|
||||
|
||||
if (!audio_devs[dev]->copy_from_user) { /* No device specific
|
||||
* copy routine */
|
||||
|
||||
if (uiomove(&wr_dma_buf[dev][wr_buff_ptr[dev]], l, buf)) {
|
||||
printf("sb: Bad copyin()!\n");
|
||||
};
|
||||
} else
|
||||
audio_devs[dev]->copy_from_user(dev,
|
||||
wr_dma_buf[dev], wr_buff_ptr[dev], buf, p, l);
|
||||
|
||||
|
||||
/*
|
||||
* Insert local processing here
|
||||
*/
|
||||
|
||||
if (local_conversion[dev] == AFMT_MU_LAW) {
|
||||
translate_bytes(ulaw_dsp,
|
||||
(u_char *) &wr_dma_buf[dev][wr_buff_ptr[dev]], l);
|
||||
}
|
||||
c -= l;
|
||||
p += l;
|
||||
wr_buff_ptr[dev] += l;
|
||||
|
||||
if (wr_buff_ptr[dev] >= wr_buff_size[dev]) {
|
||||
if ((err = DMAbuf_start_output(dev, wr_buff_no[dev],
|
||||
wr_buff_ptr[dev])) < 0) {
|
||||
return err;
|
||||
}
|
||||
wr_buff_no[dev] = -1;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int
|
||||
audio_read(int dev, struct fileinfo * file, snd_rw_buf * buf, int count)
|
||||
{
|
||||
int c, p, l;
|
||||
char *dmabuf;
|
||||
int buff_no;
|
||||
|
||||
dev = dev >> 4;
|
||||
p = 0;
|
||||
c = count;
|
||||
if ((audio_mode[dev] & AM_WRITE) &&
|
||||
!(audio_devs[dev]->flags & DMA_DUPLEX)) {
|
||||
if (wr_buff_no[dev] >= 0) {
|
||||
DMAbuf_start_output(dev, wr_buff_no[dev], wr_buff_ptr[dev]);
|
||||
|
||||
if (!(audio_devs[dev]->flags & DMA_DUPLEX))
|
||||
wr_buff_no[dev] = -1;
|
||||
}
|
||||
}
|
||||
if (audio_devs[dev]->flags & DMA_DUPLEX)
|
||||
audio_mode[dev] |= AM_READ;
|
||||
else
|
||||
audio_mode[dev] = AM_READ;
|
||||
|
||||
while (c) {
|
||||
if ((buff_no = DMAbuf_getrdbuffer(dev, &dmabuf, &l,
|
||||
dev_nblock[dev])) < 0) {
|
||||
/*
|
||||
* Nonblocking mode handling. Return current # of bytes
|
||||
*/
|
||||
|
||||
if (dev_nblock[dev] && buff_no == -(EAGAIN))
|
||||
return p;
|
||||
|
||||
return buff_no;
|
||||
}
|
||||
if (l > c)
|
||||
l = c;
|
||||
|
||||
/*
|
||||
* Insert any local processing here.
|
||||
*/
|
||||
|
||||
if (local_conversion[dev] == AFMT_MU_LAW) {
|
||||
translate_bytes(dsp_ulaw, (u_char *) dmabuf, l);
|
||||
}
|
||||
if (uiomove(dmabuf, l, buf)) {
|
||||
printf("sb: Bad copyout()!\n");
|
||||
};
|
||||
|
||||
DMAbuf_rmchars(dev, buff_no, l);
|
||||
|
||||
p += l;
|
||||
c -= l;
|
||||
}
|
||||
return count - c;
|
||||
}
|
||||
|
||||
int
|
||||
audio_ioctl(int dev, struct fileinfo * file, u_int cmd, ioctl_arg arg)
|
||||
{
|
||||
dev = dev >> 4;
|
||||
if (((cmd >> 8) & 0xff) == 'C') {
|
||||
if (audio_devs[dev]->coproc) /* Coprocessor ioctl */
|
||||
return audio_devs[dev]->coproc->ioctl(audio_devs[dev]->coproc->devc, cmd, arg, 0);
|
||||
else
|
||||
printf("/dev/dsp%d: No coprocessor for this device\n", dev);
|
||||
|
||||
return -(ENXIO);
|
||||
} else
|
||||
switch (cmd) {
|
||||
|
||||
case SNDCTL_DSP_SYNC:
|
||||
if (wr_buff_no[dev] >= 0) {
|
||||
DMAbuf_start_output(dev, wr_buff_no[dev], wr_buff_ptr[dev]);
|
||||
wr_buff_no[dev] = -1;
|
||||
}
|
||||
return DMAbuf_ioctl(dev, cmd, arg, 0);
|
||||
break;
|
||||
|
||||
case SNDCTL_DSP_POST:
|
||||
if (wr_buff_no[dev] >= 0) {
|
||||
DMAbuf_start_output(dev, wr_buff_no[dev], wr_buff_ptr[dev]);
|
||||
wr_buff_no[dev] = -1;
|
||||
}
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SNDCTL_DSP_RESET:
|
||||
wr_buff_no[dev] = -1;
|
||||
audio_mode[dev] = AM_NONE;
|
||||
return DMAbuf_ioctl(dev, cmd, arg, 0);
|
||||
break;
|
||||
|
||||
case SNDCTL_DSP_GETFMTS:
|
||||
return *(int *) arg = audio_devs[dev]->format_mask;
|
||||
break;
|
||||
|
||||
case SNDCTL_DSP_SETFMT:
|
||||
return *(int *) arg = set_format(dev, (*(int *) arg));
|
||||
|
||||
case SNDCTL_DSP_GETISPACE:
|
||||
if ((audio_mode[dev] & AM_WRITE) &&
|
||||
!(audio_devs[dev]->flags & DMA_DUPLEX))
|
||||
return -(EBUSY);
|
||||
|
||||
else {
|
||||
audio_buf_info info;
|
||||
int err = DMAbuf_ioctl(dev, cmd, (ioctl_arg) & info, 1);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
bcopy((char *) &info, &(((char *) arg)[0]), sizeof(info));
|
||||
return 0;
|
||||
}
|
||||
|
||||
case SNDCTL_DSP_GETOSPACE:
|
||||
if ((audio_mode[dev] & AM_READ) &&
|
||||
!(audio_devs[dev]->flags & DMA_DUPLEX))
|
||||
return -(EBUSY);
|
||||
else {
|
||||
audio_buf_info info;
|
||||
int err = DMAbuf_ioctl(dev, cmd, (ioctl_arg) & info, 1);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (wr_buff_no[dev] != -1)
|
||||
info.bytes += wr_buff_size[dev] - wr_buff_ptr[dev];
|
||||
|
||||
bcopy((char *) &info, &(((char *) arg)[0]), sizeof(info));
|
||||
return 0;
|
||||
}
|
||||
|
||||
case SNDCTL_DSP_NONBLOCK:
|
||||
dev_nblock[dev] = 1;
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SNDCTL_DSP_GETCAPS:
|
||||
{
|
||||
int info = 1; /* Revision level of this ioctl() */
|
||||
|
||||
if (audio_devs[dev]->flags & DMA_DUPLEX)
|
||||
info |= DSP_CAP_DUPLEX;
|
||||
|
||||
if (audio_devs[dev]->coproc)
|
||||
info |= DSP_CAP_COPROC;
|
||||
|
||||
if (audio_devs[dev]->local_qlen) /* Dev. has hidden buffs */
|
||||
info |= DSP_CAP_BATCH;
|
||||
|
||||
if (audio_devs[dev]->trigger) /* Supports SETTRIGGER */
|
||||
info |= DSP_CAP_TRIGGER;
|
||||
|
||||
info |= DSP_CAP_MMAP;
|
||||
bcopy((char *) &info, &(((char *) arg)[0]), sizeof(info));
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case FIOASYNC:
|
||||
return *(int *) arg = 1;
|
||||
|
||||
case FIONBIO:
|
||||
return *(int *) arg = 1;
|
||||
|
||||
default:
|
||||
return DMAbuf_ioctl(dev, cmd, arg, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ALLOW_POLL
|
||||
/*
|
||||
* XXX should we use spltty() in the select calls ? - lr970714
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
audio_poll(int dev, struct fileinfo * file, int events, select_table * wait)
|
||||
{
|
||||
dev = dev >> 4;
|
||||
|
||||
if (events & (POLLIN | POLLRDNORM)) {
|
||||
if ((audio_mode[dev] & AM_WRITE) &&
|
||||
!(audio_devs[dev]->flags & DMA_DUPLEX))
|
||||
return 0; /* Not recording */
|
||||
|
||||
|
||||
return (DMAbuf_poll(dev, file, events, wait));
|
||||
}
|
||||
|
||||
if (events & (POLLOUT | POLLWRNORM)) {
|
||||
if ((audio_mode[dev] & AM_READ) &&
|
||||
!(audio_devs[dev]->flags & DMA_DUPLEX))
|
||||
return 0; /* Wrong direction */
|
||||
|
||||
if (wr_buff_no[dev] != -1)
|
||||
return 1; /* There is space in the current buffer */
|
||||
|
||||
return ( DMAbuf_poll(dev, file, events, wait) );
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* ALLOW_POLL */
|
||||
|
||||
#endif
|
@ -1,12 +0,0 @@
|
||||
/*
|
||||
* Definitions for various on board processors on the soundcards. For
|
||||
* example DSP processors.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Coprocessor access types
|
||||
*/
|
||||
#define COPR_CUSTOM 0x0001 /* Custom applications */
|
||||
#define COPR_MIDI 0x0002 /* MIDI (MPU-401) emulation */
|
||||
#define COPR_PCM 0x0004 /* Digitized voice applications */
|
||||
#define COPR_SYNTH 0x0008 /* Music synthesis */
|
@ -1,202 +0,0 @@
|
||||
/*
|
||||
* sound/cs4232.c
|
||||
*
|
||||
* The low level driver for Crystal CS4232 based cards. The CS4232 is a PnP
|
||||
* compatible chip which contains a CS4231A codec, SB emulation, a MPU401
|
||||
* compatible MIDI port, joystick and synthesizer and IDE CD-ROM interfaces.
|
||||
* This is just a temporary driver until full PnP support gets inplemented.
|
||||
* Just the WSS codec, FM synth and the MIDI ports are supported. Other
|
||||
* interfaces are left uninitialized.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1995
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if defined(CONFIG_CS4232)
|
||||
|
||||
#define KEY_PORT 0x279 /* Same as LPT1 status port */
|
||||
#define CSN_NUM 0x99 /* Just a random number */
|
||||
|
||||
#define CS_OUT(a) outb( KEY_PORT, a)
|
||||
#define CS_OUT2(a, b) {CS_OUT(a);CS_OUT(b);}
|
||||
#define CS_OUT3(a, b, c) {CS_OUT(a);CS_OUT(b);CS_OUT(c);}
|
||||
|
||||
static int mpu_base = 0, mpu_irq = 0;
|
||||
|
||||
int
|
||||
probe_cs4232_mpu(struct address_info * hw_config)
|
||||
{
|
||||
/*
|
||||
* Just write down the config values.
|
||||
*/
|
||||
|
||||
mpu_base = hw_config->io_base;
|
||||
mpu_irq = hw_config->irq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
attach_cs4232_mpu(struct address_info * hw_config)
|
||||
{
|
||||
}
|
||||
|
||||
static unsigned char crystal_key[] = /* A 32 byte magic key sequence */
|
||||
{
|
||||
0x96, 0x35, 0x9a, 0xcd, 0xe6, 0xf3, 0x79, 0xbc,
|
||||
0x5e, 0xaf, 0x57, 0x2b, 0x15, 0x8a, 0xc5, 0xe2,
|
||||
0xf1, 0xf8, 0x7c, 0x3e, 0x9f, 0x4f, 0x27, 0x13,
|
||||
0x09, 0x84, 0x42, 0xa1, 0xd0, 0x68, 0x34, 0x1a
|
||||
};
|
||||
|
||||
int
|
||||
probe_cs4232(struct address_info * hw_config)
|
||||
{
|
||||
int i;
|
||||
int base = hw_config->io_base, irq = hw_config->irq;
|
||||
int dma1 = hw_config->dma, dma2 = hw_config->dma2;
|
||||
|
||||
/*
|
||||
* Verify that the I/O port range is free.
|
||||
*/
|
||||
|
||||
if (0) {
|
||||
printf("cs4232.c: I/O port 0x%03x not free\n", base);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* This version of the driver doesn't use the PnP method when
|
||||
* configuring the card but a simplified method defined by Crystal.
|
||||
* This means that just one CS4232 compatible device can exist on the
|
||||
* system. Also this method conflicts with possible PnP support in
|
||||
* the OS. For this reason driver is just a temporary kludge.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Wake up the card by sending a 32 byte Crystal key to the key port.
|
||||
*/
|
||||
for (i = 0; i < 32; i++)
|
||||
CS_OUT(crystal_key[i]);
|
||||
|
||||
/*
|
||||
* Now set the CSN (Card Select Number).
|
||||
*/
|
||||
|
||||
CS_OUT2(0x06, CSN_NUM);
|
||||
|
||||
/*
|
||||
* Ensure that there is no other codec using the same address.
|
||||
*/
|
||||
|
||||
CS_OUT2(0x15, 0x00); /* Select logical device 0 (WSS/SB/FM) */
|
||||
CS_OUT2(0x33, 0x00); /* Inactivate logical dev 0 */
|
||||
|
||||
/*
|
||||
* Then set some config bytes. First logical device 0
|
||||
*/
|
||||
|
||||
CS_OUT2(0x15, 0x00); /* Select logical device 0 (WSS/SB/FM) */
|
||||
CS_OUT3(0x47, (base >> 8) & 0xff, base & 0xff); /* WSSbase */
|
||||
|
||||
if (0) /* Not free */
|
||||
CS_OUT3(0x48, 0x00, 0x00) /* FMbase off */
|
||||
else
|
||||
CS_OUT3(0x48, 0x03, 0x88); /* FMbase 0x388 */
|
||||
|
||||
CS_OUT3(0x42, 0x00, 0x00); /* SBbase off */
|
||||
CS_OUT2(0x22, irq); /* SB+WSS IRQ */
|
||||
CS_OUT2(0x2a, dma1); /* SB+WSS DMA */
|
||||
|
||||
if (dma2 != -1)
|
||||
CS_OUT2(0x25, dma2) /* WSS DMA2 */
|
||||
else
|
||||
CS_OUT2(0x25, 4); /* No WSS DMA2 */
|
||||
|
||||
CS_OUT2(0x33, 0x01); /* Activate logical dev 0 */
|
||||
|
||||
/*
|
||||
* Initialize logical device 3 (MPU)
|
||||
*/
|
||||
|
||||
#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
|
||||
if (mpu_base != 0 && mpu_irq != 0) {
|
||||
CS_OUT2(0x15, 0x03); /* Select logical device 3 (MPU) */
|
||||
CS_OUT3(0x47, (mpu_base >> 8) & 0xff, mpu_base & 0xff); /* MPUbase */
|
||||
CS_OUT2(0x22, mpu_irq); /* MPU IRQ */
|
||||
CS_OUT2(0x33, 0x01); /* Activate logical dev 3 */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Finally activate the chip
|
||||
*/
|
||||
CS_OUT(0x79);
|
||||
|
||||
/*
|
||||
* Then try to detect the codec part of the chip
|
||||
*/
|
||||
|
||||
return ad1848_detect(hw_config->io_base, NULL, hw_config->osp);
|
||||
}
|
||||
|
||||
void
|
||||
attach_cs4232(struct address_info * hw_config)
|
||||
{
|
||||
int base = hw_config->io_base, irq = hw_config->irq;
|
||||
int dma1 = hw_config->dma, dma2 = hw_config->dma2;
|
||||
|
||||
if (dma2 == -1)
|
||||
dma2 = dma1;
|
||||
|
||||
ad1848_init("CS4232", base,
|
||||
irq,
|
||||
dma1, /* Playback DMA */
|
||||
dma2, /* Capture DMA */
|
||||
0,
|
||||
hw_config->osp);
|
||||
|
||||
#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
|
||||
if (mpu_base != 0 && mpu_irq != 0) {
|
||||
static struct address_info hw_config2 =
|
||||
{0}; /* Ensure it's initialized */
|
||||
|
||||
hw_config2.io_base = mpu_base;
|
||||
hw_config2.irq = mpu_irq;
|
||||
hw_config2.dma = -1;
|
||||
hw_config2.dma2 = -1;
|
||||
hw_config2.always_detect = 0;
|
||||
hw_config2.name = NULL;
|
||||
hw_config2.card_subtype = 0;
|
||||
hw_config2.osp = hw_config->osp;
|
||||
|
||||
if (probe_mpu401(&hw_config2))
|
||||
attach_mpu401(&hw_config2);
|
||||
else
|
||||
mpu_base = mpu_irq = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
@ -1,259 +0,0 @@
|
||||
/*
|
||||
* sound/dev_table.c
|
||||
*
|
||||
* Device call tables.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define _DEV_TABLE_C_
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if NSND > 0
|
||||
|
||||
int sound_started = 0;
|
||||
|
||||
int sndtable_get_cardcount(void);
|
||||
int snd_find_driver(int type);
|
||||
static void sndtable_init(void);
|
||||
int sndtable_probe(int unit, struct address_info * hw_config);
|
||||
int sndtable_init_card(int unit, struct address_info * hw_config);
|
||||
static void start_services(void);
|
||||
static void start_cards(void);
|
||||
struct address_info *sound_getconf(int card_type);
|
||||
|
||||
int
|
||||
snd_find_driver(int type)
|
||||
{
|
||||
int i, n = num_sound_drivers;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
if (sound_drivers[i].card_type == type)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
start_services()
|
||||
{
|
||||
int soundcards_installed;
|
||||
|
||||
if (!(soundcards_installed = sndtable_get_cardcount()))
|
||||
return ; /* No cards detected */
|
||||
|
||||
#ifdef CONFIG_AUDIO
|
||||
if (num_audiodevs) /* Audio devices present */
|
||||
DMAbuf_init();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MIDI
|
||||
if (num_midis)
|
||||
/* MIDIbuf_init(0) */;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SEQUENCER
|
||||
if (num_midis + num_synths)
|
||||
sequencer_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
start_cards()
|
||||
{
|
||||
int drv, i, n = num_sound_cards;
|
||||
struct card_info *ci = snd_installed_cards ;
|
||||
|
||||
sound_started = 1;
|
||||
if (trace_init)
|
||||
printf("Sound initialization started\n");
|
||||
|
||||
/*
|
||||
* Check the number of cards actually defined in the table
|
||||
*/
|
||||
|
||||
for (i = 0; i < n && snd_installed_cards[i].card_type; i++)
|
||||
num_sound_cards = i + 1;
|
||||
|
||||
for (i = 0; i < n && ci->card_type; ci++, i++)
|
||||
if (ci->enabled) {
|
||||
if ((drv = snd_find_driver(ci->card_type)) == -1) {
|
||||
ci->enabled = 0; /* Mark as not detected */
|
||||
continue;
|
||||
}
|
||||
ci->config.card_subtype = sound_drivers[drv].card_subtype;
|
||||
|
||||
if (sound_drivers[drv].probe(&(ci->config)))
|
||||
sound_drivers[drv].attach(&(ci->config));
|
||||
else
|
||||
ci->enabled = 0; /* Mark as not detected */
|
||||
}
|
||||
if (trace_init)
|
||||
printf("Sound initialization complete\n");
|
||||
}
|
||||
|
||||
static void
|
||||
sndtable_init()
|
||||
{
|
||||
start_cards();
|
||||
}
|
||||
|
||||
/*
|
||||
* sndtable_probe probes a specific device. unit is the voxware unit number.
|
||||
*/
|
||||
|
||||
int
|
||||
sndtable_probe(int unit, struct address_info * hw_config)
|
||||
{
|
||||
int i, sel = -1, n = num_sound_cards;
|
||||
struct card_info *ci = snd_installed_cards ;
|
||||
|
||||
DDB(printf("-- sndtable_probe(%d)\n", unit));
|
||||
|
||||
|
||||
/*
|
||||
* for some reason unit 0 always succeeds ?
|
||||
*/
|
||||
if (!unit)
|
||||
return TRUE;
|
||||
|
||||
sound_started = 1;
|
||||
|
||||
for (i=0; i<n && sel== -1 && ci->card_type; ci++, i++)
|
||||
if ( (ci->enabled) && (ci->card_type == unit) ) {
|
||||
/* DDB(printf("-- found card %d\n", i) ); */
|
||||
sel = i; /* and break */
|
||||
}
|
||||
|
||||
/*
|
||||
* not found. Creates a new entry in the table for this unit.
|
||||
*/
|
||||
if (sel == -1 && num_sound_cards < max_sound_cards) {
|
||||
int i;
|
||||
|
||||
i = sel = (num_sound_cards++);
|
||||
DDB(printf("-- installing card %d\n", i) );
|
||||
|
||||
ci = &snd_installed_cards[sel] ;
|
||||
ci->card_type = unit;
|
||||
ci->enabled = 1;
|
||||
}
|
||||
/* DDB(printf("-- installed card %d\n", sel) ); */
|
||||
if (sel != -1) {
|
||||
int drv;
|
||||
|
||||
ci->config.io_base = hw_config->io_base;
|
||||
ci->config.irq = hw_config->irq;
|
||||
ci->config.dma = hw_config->dma;
|
||||
ci->config.dma2 = hw_config->dma2;
|
||||
ci->config.name = hw_config->name;
|
||||
ci->config.always_detect = hw_config->always_detect;
|
||||
ci->config.card_subtype = hw_config->card_subtype;
|
||||
ci->config.osp = hw_config->osp;
|
||||
|
||||
if ((drv = snd_find_driver(ci->card_type)) == -1) {
|
||||
ci->enabled = 0;
|
||||
DDB(printf("Failed to find driver\n"));
|
||||
return FALSE;
|
||||
}
|
||||
DDB(printf("-- Driver name '%s' probe 0x%08x\n",
|
||||
sound_drivers[drv].name, sound_drivers[drv].probe));
|
||||
|
||||
hw_config->card_subtype =
|
||||
ci->config.card_subtype = sound_drivers[drv].card_subtype;
|
||||
|
||||
if (sound_drivers[drv].probe(hw_config)) {
|
||||
DDB(printf("-- Hardware probed OK\n"));
|
||||
return TRUE;
|
||||
}
|
||||
DDB(printf("-- Failed to find hardware\n"));
|
||||
ci->enabled = 0; /* mark as not detected */
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
sndtable_init_card(int unit, struct address_info * hw_config)
|
||||
{
|
||||
int i, n = num_sound_cards;
|
||||
struct card_info *ci = snd_installed_cards ;
|
||||
|
||||
DDB(printf("sndtable_init_card(%d) entered\n", unit));
|
||||
|
||||
if (!unit) {
|
||||
sndtable_init() ;
|
||||
return TRUE;
|
||||
}
|
||||
for (i = 0; i < n && ci->card_type; ci++, i++)
|
||||
if (ci->card_type == unit) {
|
||||
int drv;
|
||||
|
||||
ci->config.io_base = hw_config->io_base;
|
||||
ci->config.irq = hw_config->irq;
|
||||
ci->config.dma = hw_config->dma;
|
||||
ci->config.dma2 = hw_config->dma2;
|
||||
ci->config.name = hw_config->name;
|
||||
ci->config.always_detect = hw_config->always_detect;
|
||||
ci->config.card_subtype = hw_config->card_subtype;
|
||||
ci->config.osp = hw_config->osp;
|
||||
|
||||
if ((drv = snd_find_driver(ci->card_type)) == -1)
|
||||
ci->enabled = 0; /* Mark not fnd */
|
||||
else {
|
||||
DDB(printf("Located card - calling attach routine\n"));
|
||||
sound_drivers[drv].attach(hw_config) ;
|
||||
DDB(printf("attach routine finished\n"));
|
||||
}
|
||||
start_services();
|
||||
return TRUE;
|
||||
}
|
||||
DDB(printf("sndtable_init_card: No card defined with type=%d, num cards: %d\n",
|
||||
unit, num_sound_cards));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
sndtable_get_cardcount(void)
|
||||
{
|
||||
return num_audiodevs + num_mixers + num_synths + num_midis;
|
||||
}
|
||||
|
||||
struct address_info *
|
||||
sound_getconf(int card_type)
|
||||
{
|
||||
int j, ptr = -1, n = num_sound_cards;
|
||||
|
||||
for (j = 0; j < n && ptr == -1 && snd_installed_cards[j].card_type; j++)
|
||||
if (snd_installed_cards[j].card_type == card_type)
|
||||
ptr = j;
|
||||
|
||||
if (ptr == -1)
|
||||
return (struct address_info *) NULL;
|
||||
|
||||
return &snd_installed_cards[ptr].config;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,604 +0,0 @@
|
||||
/*
|
||||
* dev_table.h
|
||||
*
|
||||
* Global definitions for device call tables
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DEV_TABLE_H_
|
||||
#define _DEV_TABLE_H_
|
||||
|
||||
/*
|
||||
* NOTE! NOTE! NOTE! NOTE!
|
||||
*
|
||||
* If you modify this file, please check the dev_table.c also.
|
||||
*
|
||||
* NOTE! NOTE! NOTE! NOTE!
|
||||
*/
|
||||
|
||||
extern int sound_started;
|
||||
|
||||
struct driver_info {
|
||||
char *driver_id;
|
||||
int card_subtype; /* Driver specific. Usually 0 */
|
||||
int card_type; /* From soundcard.h */
|
||||
char *name;
|
||||
void (*attach) (struct address_info * hw_config);
|
||||
int (*probe) (struct address_info * hw_config);
|
||||
};
|
||||
|
||||
struct card_info {
|
||||
int card_type; /* Link (search key) to the driver list */
|
||||
struct address_info config;
|
||||
int enabled;
|
||||
};
|
||||
|
||||
typedef struct pnp_sounddev {
|
||||
int id;
|
||||
void (*setup) (void *dev);
|
||||
char *driver_name;
|
||||
} pnp_sounddev;
|
||||
|
||||
/*
|
||||
* Device specific parameters (used only by dmabuf.c)
|
||||
*/
|
||||
#define MAX_SUB_BUFFERS (32*MAX_REALTIME_FACTOR)
|
||||
|
||||
#define DMODE_NONE 0
|
||||
#define DMODE_OUTPUT 1
|
||||
#define DMODE_INPUT 2
|
||||
|
||||
struct dma_buffparms {
|
||||
int dma_mode; /* DMODE_INPUT, DMODE_OUTPUT or DMODE_NONE */
|
||||
|
||||
char *raw_buf; /* Pointers to raw buffers */
|
||||
u_long raw_buf_phys;
|
||||
|
||||
/*
|
||||
* Device state tables
|
||||
*/
|
||||
|
||||
u_long flags;
|
||||
#define DMA_BUSY 0x00000001
|
||||
#define DMA_RESTART 0x00000002
|
||||
#define DMA_ACTIVE 0x00000004
|
||||
#define DMA_STARTED 0x00000008
|
||||
#define DMA_ALLOC_DONE 0x00000020
|
||||
|
||||
int open_mode;
|
||||
|
||||
/*
|
||||
* Queue parameters.
|
||||
*/
|
||||
int qlen;
|
||||
int qhead;
|
||||
int qtail;
|
||||
|
||||
int nbufs;
|
||||
int counts[MAX_SUB_BUFFERS];
|
||||
int subdivision;
|
||||
|
||||
int fragment_size;
|
||||
int max_fragments;
|
||||
|
||||
int bytes_in_use;
|
||||
|
||||
int underrun_count;
|
||||
int byte_counter;
|
||||
|
||||
int mapping_flags;
|
||||
#define DMA_MAP_MAPPED 0x00000001
|
||||
char neutral_byte;
|
||||
int dma_chan;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure for use with various microcontrollers and DSP processors in the
|
||||
* recent soundcards.
|
||||
*/
|
||||
typedef struct coproc_operations {
|
||||
char name[32];
|
||||
int (*open) (void *devc, int sub_device);
|
||||
void (*close) (void *devc, int sub_device);
|
||||
int (*ioctl) (void *devc, u_int cmd, ioctl_arg arg, int local);
|
||||
void (*reset) (void *devc);
|
||||
|
||||
void *devc; /* Driver specific info */
|
||||
} coproc_operations;
|
||||
|
||||
struct audio_operations {
|
||||
char name[32];
|
||||
int flags;
|
||||
#define NOTHING_SPECIAL 0
|
||||
#define NEEDS_RESTART 1
|
||||
#define DMA_AUTOMODE 2
|
||||
#define DMA_DUPLEX 4
|
||||
#define DMA_DISABLE 8
|
||||
int format_mask; /* Bitmask for supported audio formats */
|
||||
void *devc; /* Driver specific info */
|
||||
int (*open) (int dev, int mode);
|
||||
void (*close) (int dev);
|
||||
void (*output_block) (int dev, unsigned long buf,
|
||||
int count, int intrflag, int dma_restart);
|
||||
void (*start_input) (int dev, unsigned long buf,
|
||||
int count, int intrflag, int dma_restart);
|
||||
int (*ioctl) (int dev, u_int cmd, ioctl_arg arg, int local);
|
||||
int (*prepare_for_input) (int dev, int bufsize, int nbufs);
|
||||
int (*prepare_for_output) (int dev, int bufsize, int nbufs);
|
||||
void (*reset) (int dev);
|
||||
void (*halt_xfer) (int dev);
|
||||
int (*local_qlen) (int dev);
|
||||
void (*copy_from_user) (int dev, char *localbuf, int localoffs,
|
||||
snd_rw_buf * userbuf, int useroffs, int len);
|
||||
void (*halt_input) (int dev);
|
||||
void (*halt_output) (int dev);
|
||||
void (*trigger) (int dev, int bits);
|
||||
long buffsize;
|
||||
int dmachan1, dmachan2;
|
||||
struct dma_buffparms *dmap_in, *dmap_out;
|
||||
struct coproc_operations *coproc;
|
||||
int mixer_dev;
|
||||
int enable_bits;
|
||||
int open_mode;
|
||||
int go;
|
||||
int otherside;
|
||||
int busy;
|
||||
};
|
||||
|
||||
struct mixer_operations {
|
||||
char name[32];
|
||||
int (*ioctl) (int dev, unsigned int cmd, ioctl_arg arg);
|
||||
};
|
||||
|
||||
struct synth_operations {
|
||||
struct synth_info *info;
|
||||
int midi_dev;
|
||||
int synth_type;
|
||||
int synth_subtype;
|
||||
|
||||
int (*open) (int dev, int mode);
|
||||
void (*close) (int dev);
|
||||
int (*ioctl) (int dev, unsigned int cmd, ioctl_arg arg);
|
||||
int (*kill_note) (int dev, int voice, int note, int velocity);
|
||||
int (*start_note) (int dev, int voice, int note, int velocity);
|
||||
int (*set_instr) (int dev, int voice, int instr);
|
||||
void (*reset) (int dev);
|
||||
void (*hw_control) (int dev, unsigned char *event);
|
||||
int (*load_patch) (int dev, int format, snd_rw_buf * addr,
|
||||
int offs, int count, int pmgr_flag);
|
||||
void (*aftertouch) (int dev, int voice, int pressure);
|
||||
void (*controller) (int dev, int voice, int ctrl_num, int value);
|
||||
void (*panning) (int dev, int voice, int value);
|
||||
void (*volume_method) (int dev, int mode);
|
||||
int (*pmgr_interface) (int dev, struct patmgr_info * info);
|
||||
void (*bender) (int dev, int chn, int value);
|
||||
int (*alloc_voice) (int dev, int chn, int note, struct voice_alloc_info * alloc);
|
||||
void (*setup_voice) (int dev, int voice, int chn);
|
||||
int (*send_sysex) (int dev, unsigned char *bytes, int len);
|
||||
|
||||
struct voice_alloc_info alloc;
|
||||
struct channel_info chn_info[16];
|
||||
};
|
||||
|
||||
struct midi_input_info { /* MIDI input scanner variables */
|
||||
#define MI_MAX 10
|
||||
int m_busy;
|
||||
unsigned char m_buf[MI_MAX];
|
||||
unsigned char m_prev_status; /* For running status */
|
||||
int m_ptr;
|
||||
#define MST_INIT 0
|
||||
#define MST_DATA 1
|
||||
#define MST_SYSEX 2
|
||||
int m_state;
|
||||
int m_left;
|
||||
};
|
||||
|
||||
struct midi_operations {
|
||||
struct midi_info info;
|
||||
struct synth_operations *converter;
|
||||
struct midi_input_info in_info;
|
||||
int (*open) (int dev, int mode,
|
||||
void (*inputintr) (int dev, unsigned char data),
|
||||
void (*outputintr) (int dev) );
|
||||
void (*close) (int dev);
|
||||
int (*ioctl) (int dev, unsigned int cmd, ioctl_arg arg);
|
||||
int (*putc) (int dev, unsigned char data);
|
||||
int (*start_read) (int dev);
|
||||
int (*end_read) (int dev);
|
||||
void (*kick) (int dev);
|
||||
int (*command) (int dev, unsigned char *data);
|
||||
int (*buffer_status) (int dev);
|
||||
int (*prefix_cmd) (int dev, unsigned char status);
|
||||
struct coproc_operations *coproc;
|
||||
};
|
||||
|
||||
struct sound_lowlev_timer {
|
||||
int dev;
|
||||
u_int (*tmr_start) (int dev, unsigned int usecs);
|
||||
void (*tmr_disable) (int dev);
|
||||
void (*tmr_restart) (int dev);
|
||||
};
|
||||
|
||||
struct sound_timer_operations {
|
||||
struct sound_timer_info info;
|
||||
int priority;
|
||||
int devlink;
|
||||
int (*open) (int dev, int mode);
|
||||
void (*close) (int dev);
|
||||
int (*event) (int dev, unsigned char *ev);
|
||||
u_long (*get_time) (int dev);
|
||||
int (*ioctl) (int dev, unsigned int cmd, ioctl_arg arg);
|
||||
void (*arm_timer) (int dev, long time);
|
||||
};
|
||||
|
||||
#ifdef _DEV_TABLE_C_
|
||||
struct audio_operations *audio_devs[MAX_AUDIO_DEV] = {NULL};
|
||||
int num_audiodevs = 0;
|
||||
struct mixer_operations *mixer_devs[MAX_MIXER_DEV] = {NULL};
|
||||
int num_mixers = 0;
|
||||
struct synth_operations *synth_devs[MAX_SYNTH_DEV + MAX_MIDI_DEV] = {NULL};
|
||||
int num_synths = 0;
|
||||
struct midi_operations *midi_devs[MAX_MIDI_DEV] = {NULL};
|
||||
int num_midis = 0;
|
||||
|
||||
#ifdef CONFIG_SEQUENCER
|
||||
extern struct sound_timer_operations default_sound_timer;
|
||||
struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] =
|
||||
{&default_sound_timer, NULL};
|
||||
int num_sound_timers = 1;
|
||||
#else
|
||||
struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] = {NULL};
|
||||
int num_sound_timers = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* List of low level drivers compiled into the kernel.
|
||||
*
|
||||
* remember, each entry contains:
|
||||
|
||||
char *driver_id;
|
||||
int card_subtype; (Driver specific. Usually 0)
|
||||
int card_type; (From soundcard.h)
|
||||
char *name;
|
||||
void (*attach) (struct address_info * hw_config);
|
||||
int (*probe) (struct address_info * hw_config);
|
||||
*
|
||||
*/
|
||||
|
||||
struct driver_info sound_drivers[] = {
|
||||
|
||||
#ifdef CONFIG_PSS
|
||||
{"PSSECHO", 0, SNDCARD_PSS, "Echo Personal Sound System PSS (ESC614)",
|
||||
attach_pss, probe_pss},
|
||||
{"PSSMPU", 0, SNDCARD_PSS_MPU, "PSS-MPU",
|
||||
attach_pss_mpu, probe_pss_mpu},
|
||||
{"PSSMSS", 0, SNDCARD_PSS_MSS, "PSS-MSS",
|
||||
attach_pss_mss, probe_pss_mss},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MSS
|
||||
/* XXX changed type from 0 to 1 -lr 970705 */
|
||||
{"MSS", 1, SNDCARD_MSS, "MS Sound System",
|
||||
attach_mss, probe_mss},
|
||||
/* MSS without IRQ/DMA config registers (for DEC Alphas) */
|
||||
{"PCXBJ", 1, SNDCARD_PSEUDO_MSS, "MS Sound System (AXP)",
|
||||
attach_mss, probe_mss},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MAD16
|
||||
{"MAD16", 0, SNDCARD_MAD16, "MAD16/Mozart (MSS)",
|
||||
attach_mad16, probe_mad16},
|
||||
{"MAD16MPU", 0, SNDCARD_MAD16_MPU, "MAD16/Mozart (MPU)",
|
||||
attach_mad16_mpu, probe_mad16_mpu},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CS4232
|
||||
{"CS4232", 0, SNDCARD_CS4232, "CS4232",
|
||||
attach_cs4232, probe_cs4232},
|
||||
{"CS4232MPU", 0, SNDCARD_CS4232_MPU, "CS4232 MIDI",
|
||||
attach_cs4232_mpu, probe_cs4232_mpu},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_YM3812
|
||||
{"OPL3", 0, SNDCARD_ADLIB, "OPL-2/OPL-3 FM",
|
||||
attach_adlib_card, probe_adlib},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PAS
|
||||
{"PAS16", 0, SNDCARD_PAS, "ProAudioSpectrum",
|
||||
attach_pas_card, probe_pas},
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MPU401) && defined(CONFIG_MIDI)
|
||||
{"MPU401", 0, SNDCARD_MPU401, "Roland MPU-401",
|
||||
attach_mpu401, probe_mpu401},
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MAUI)
|
||||
{"MAUI", 0, SNDCARD_MAUI, "TB Maui",
|
||||
attach_maui, probe_maui},
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_UART6850) && defined(CONFIG_MIDI)
|
||||
{"MIDI6850", 0, SNDCARD_UART6850, "6860 UART Midi",
|
||||
attach_uart6850, probe_uart6850},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SB
|
||||
{"SBLAST", 0, SNDCARD_SB, "SoundBlaster",
|
||||
attach_sb_card, probe_sb},
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SB) && defined(CONFIG_SB16)
|
||||
#ifdef CONFIG_AUDIO
|
||||
{"SB16", 0, SNDCARD_SB16, "SoundBlaster16",
|
||||
sb16_dsp_init, sb16_dsp_detect},
|
||||
#endif
|
||||
#ifdef CONFIG_AWE32
|
||||
{"AWE32", 0, SNDCARD_AWE32, "AWE32 Synth",
|
||||
attach_awe, probe_awe},
|
||||
#endif
|
||||
#ifdef CONFIG_MIDI
|
||||
{"SB16MIDI", 0, SNDCARD_SB16MIDI, "SB16 MIDI",
|
||||
attach_sb16midi, probe_sb16midi},
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_GUS16
|
||||
{"GUS16", 0, SNDCARD_GUS16, "Ultrasound 16-bit opt.",
|
||||
attach_gus_db16, probe_gus_db16},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_GUS
|
||||
{"GUS", 0, SNDCARD_GUS, "Gravis Ultrasound",
|
||||
attach_gus_card, probe_gus},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SSCAPE
|
||||
{"SSCAPE", 0, SNDCARD_SSCAPE, "Ensoniq Soundscape",
|
||||
attach_sscape, probe_sscape},
|
||||
{"SSCAPEMSS", 0, SNDCARD_SSCAPE_MSS, "MS Sound System (SoundScape)",
|
||||
attach_ss_mss, probe_ss_mss},
|
||||
#endif
|
||||
|
||||
#if NTRIX > 0
|
||||
{"TRXPRO", 0, SNDCARD_TRXPRO, "MediaTriX AudioTriX Pro",
|
||||
attach_trix_wss, probe_trix_wss},
|
||||
{"TRXPROSB", 0, SNDCARD_TRXPRO_SB, "AudioTriX (SB mode)",
|
||||
attach_trix_sb, probe_trix_sb},
|
||||
{"TRXPROMPU", 0, SNDCARD_TRXPRO_MPU, "AudioTriX MIDI",
|
||||
attach_trix_mpu, probe_trix_mpu},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
{"AD1848", 0, 500, "PnP MSS",
|
||||
attach_pnp_ad1848, probe_pnp_ad1848},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NSS
|
||||
{"NSS", 0, SNDCARD_NSS, "NEC PC-9801-86 Sound System",
|
||||
attach_nss, probe_nss},
|
||||
#endif
|
||||
|
||||
{NULL, 0, 0, "*?*", NULL, NULL}
|
||||
};
|
||||
|
||||
int num_sound_drivers =
|
||||
sizeof(sound_drivers) / sizeof(struct driver_info);
|
||||
int max_sound_drivers =
|
||||
sizeof(sound_drivers) / sizeof(struct driver_info);
|
||||
|
||||
#define FULL_SOUND
|
||||
|
||||
#ifndef FULL_SOUND
|
||||
/*
|
||||
* List of devices actually configured in the system.
|
||||
*
|
||||
* Note! The detection order is significant. Don't change it.
|
||||
*
|
||||
* remember, the list contains
|
||||
*
|
||||
* int card_type; (Link (search key) to the driver list)
|
||||
* struct address_info config;
|
||||
* io_base, irq, dma, dma2,
|
||||
* always_detect, char *name, struct... *osp
|
||||
* int enabled;
|
||||
* void *for_driver_use;
|
||||
*
|
||||
*/
|
||||
|
||||
struct card_info snd_installed_cards[] = {
|
||||
#ifdef CONFIG_PSS
|
||||
{SNDCARD_PSS, {PSS_BASE, 0, -1, -1}, SND_DEFAULT_ENABLE},
|
||||
#ifdef PSS_MPU_BASE
|
||||
{SNDCARD_PSS_MPU, {PSS_MPU_BASE, PSS_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#ifdef PSS_MSS_BASE
|
||||
{SNDCARD_PSS_MSS, {PSS_MSS_BASE, PSS_MSS_IRQ, PSS_MSS_DMA, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#endif /* config PSS */
|
||||
|
||||
#if NTRIX > 0
|
||||
{SNDCARD_TRXPRO, {TRIX_BASE, TRIX_IRQ, TRIX_DMA, TRIX_DMA2}, SND_DEFAULT_ENABLE},
|
||||
#ifdef TRIX_SB_BASE
|
||||
{SNDCARD_TRXPRO_SB, {TRIX_SB_BASE, TRIX_SB_IRQ, TRIX_SB_DMA, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#ifdef TRIX_MPU_BASE
|
||||
{SNDCARD_TRXPRO_MPU, {TRIX_MPU_BASE, TRIX_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#endif /* NTRIX > 0 */
|
||||
|
||||
#ifdef CONFIG_SSCAPE
|
||||
{SNDCARD_SSCAPE, {SSCAPE_BASE, SSCAPE_IRQ, SSCAPE_DMA, -1}, SND_DEFAULT_ENABLE},
|
||||
{SNDCARD_SSCAPE_MSS, {SSCAPE_MSS_BASE, SSCAPE_MSS_IRQ, SSCAPE_MSS_DMA, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MAD16
|
||||
{SNDCARD_MAD16, {MAD16_BASE, MAD16_IRQ, MAD16_DMA, MAD16_DMA2}, SND_DEFAULT_ENABLE},
|
||||
#ifdef MAD16_MPU_BASE
|
||||
{SNDCARD_MAD16_MPU, {MAD16_MPU_BASE, MAD16_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#endif /* CONFIG_MAD16 */
|
||||
|
||||
#ifdef CONFIG_CS4232
|
||||
#ifdef CS4232_MPU_BASE
|
||||
{SNDCARD_CS4232_MPU, {CS4232_MPU_BASE, CS4232_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
{SNDCARD_CS4232, {CS4232_BASE, CS4232_IRQ, CS4232_DMA, CS4232_DMA2}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MSS
|
||||
#ifdef PSEUDO_MSS
|
||||
{SNDCARD_MSS, {MSS_BASE, MSS_IRQ, MSS_DMA, -1}, SND_DEFAULT_ENABLE},
|
||||
#else
|
||||
{SNDCARD_PSEUDO_MSS, {MSS_BASE, MSS_IRQ, MSS_DMA, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#ifdef MSS2_BASE
|
||||
{SNDCARD_MSS, {MSS2_BASE, MSS2_IRQ, MSS2_DMA, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#endif /* CONFIG_MSS */
|
||||
|
||||
#ifdef CONFIG_PAS
|
||||
{SNDCARD_PAS, {PAS_BASE, PAS_IRQ, PAS_DMA, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SB
|
||||
#ifndef SBC_DMA
|
||||
#define SBC_DMA 1
|
||||
#endif
|
||||
{SNDCARD_SB, {SBC_BASE, SBC_IRQ, SBC_DMA, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MAUI)
|
||||
{SNDCARD_MAUI, {MAUI_BASE, MAUI_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MPU401) && defined(CONFIG_MIDI)
|
||||
{SNDCARD_MPU401, {MPU_BASE, MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
|
||||
#ifdef MPU2_BASE
|
||||
{SNDCARD_MPU401, {MPU2_BASE, MPU2_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#ifdef MPU3_BASE
|
||||
{SNDCARD_MPU401, {MPU3_BASE, MPU2_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_UART6850) && defined(CONFIG_MIDI)
|
||||
{SNDCARD_UART6850, {U6850_BASE, U6850_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SB) && defined(CONFIG_SB16)
|
||||
#ifdef CONFIG_AUDIO
|
||||
{SNDCARD_SB16, {SBC_BASE, SBC_IRQ, SB16_DMA, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#ifdef CONFIG_MIDI
|
||||
{SNDCARD_SB16MIDI, {SB16MIDI_BASE, SBC_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#ifdef CONFIG_AWE32
|
||||
{SNDCARD_AWE32,{AWE32_BASE, 0, 0, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_GUS
|
||||
#ifdef CONFIG_GUS16
|
||||
{SNDCARD_GUS16, {GUS16_BASE, GUS16_IRQ, GUS16_DMA, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
{SNDCARD_GUS, {GUS_BASE, GUS_IRQ, GUS_DMA, GUS_DMA2}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_YM3812
|
||||
{SNDCARD_ADLIB, {FM_MONO, 0, 0, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NSS
|
||||
{SNDCARD_NSS, {NSS_BASE, NSS_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
|
||||
#endif
|
||||
/* Define some expansion space */
|
||||
{0, {0}, 0},
|
||||
{0, {0}, 0},
|
||||
{0, {0}, 0},
|
||||
{0, {0}, 0},
|
||||
{0, {0}, 0}
|
||||
};
|
||||
|
||||
int num_sound_cards = sizeof(snd_installed_cards) / sizeof(struct card_info);
|
||||
int max_sound_cards = sizeof(snd_installed_cards) / sizeof(struct card_info);
|
||||
|
||||
#else
|
||||
int num_sound_cards = 0;
|
||||
struct card_info snd_installed_cards[20] = {{0}};
|
||||
int max_sound_cards = 20;
|
||||
#endif
|
||||
|
||||
#ifdef MODULE
|
||||
int trace_init = 0;
|
||||
#else
|
||||
int trace_init = 1;
|
||||
#endif
|
||||
|
||||
#else
|
||||
extern struct audio_operations *audio_devs[MAX_AUDIO_DEV];
|
||||
extern int num_audiodevs;
|
||||
extern struct mixer_operations *mixer_devs[MAX_MIXER_DEV];
|
||||
extern int num_mixers;
|
||||
extern struct synth_operations *synth_devs[MAX_SYNTH_DEV + MAX_MIDI_DEV];
|
||||
extern int num_synths;
|
||||
extern struct midi_operations *midi_devs[MAX_MIDI_DEV];
|
||||
extern int num_midis;
|
||||
extern struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV];
|
||||
extern int num_sound_timers;
|
||||
|
||||
extern struct driver_info sound_drivers[];
|
||||
extern int num_sound_drivers;
|
||||
extern int max_sound_drivers;
|
||||
extern struct card_info snd_installed_cards[];
|
||||
extern int num_sound_cards;
|
||||
extern int max_sound_cards;
|
||||
|
||||
extern int trace_init;
|
||||
|
||||
void sndtable_init(void);
|
||||
int sndtable_get_cardcount(void);
|
||||
struct address_info *sound_getconf(int card_type);
|
||||
void sound_chconf(int card_type, int ioaddr, int irq, int dma);
|
||||
int snd_find_driver(int type);
|
||||
int sndtable_identify_card(char *name);
|
||||
void sound_setup(char *str, int *ints);
|
||||
|
||||
int sound_alloc_dmap(int dev, struct dma_buffparms * dmap, int chan);
|
||||
void sound_free_dmap(int dev, struct dma_buffparms * dmap);
|
||||
extern int soud_map_buffer(int dev, struct dma_buffparms * dmap, buffmem_desc * info);
|
||||
void install_pnp_sounddrv(struct pnp_sounddev * drv);
|
||||
int sndtable_probe(int unit, struct address_info * hw_config);
|
||||
int sndtable_init_card(int unit, struct address_info * hw_config);
|
||||
void sound_timer_init(struct sound_lowlev_timer * t, char *name);
|
||||
int
|
||||
sound_start_dma(int dev, struct dma_buffparms * dmap, int chan,
|
||||
unsigned long physaddr,
|
||||
int count, int dma_mode, int autoinit);
|
||||
void sound_dma_intr(int dev, struct dma_buffparms * dmap, int chan);
|
||||
|
||||
#endif /* _DEV_TABLE_C_ */
|
||||
#endif /* _DEV_TABLE_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,49 +0,0 @@
|
||||
#ifdef SEQUENCER_C
|
||||
/*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
unsigned short finetune_table[128] =
|
||||
{
|
||||
/* 0 */ 9439, 9447, 9456, 9464, 9473, 9481, 9490, 9499,
|
||||
/* 8 */ 9507, 9516, 9524, 9533, 9542, 9550, 9559, 9567,
|
||||
/* 16 */ 9576, 9585, 9593, 9602, 9611, 9619, 9628, 9637,
|
||||
/* 24 */ 9645, 9654, 9663, 9672, 9680, 9689, 9698, 9707,
|
||||
/* 32 */ 9715, 9724, 9733, 9742, 9750, 9759, 9768, 9777,
|
||||
/* 40 */ 9786, 9795, 9803, 9812, 9821, 9830, 9839, 9848,
|
||||
/* 48 */ 9857, 9866, 9874, 9883, 9892, 9901, 9910, 9919,
|
||||
/* 56 */ 9928, 9937, 9946, 9955, 9964, 9973, 9982, 9991,
|
||||
/* 64 */ 10000, 10009, 10018, 10027, 10036, 10045, 10054, 10063,
|
||||
/* 72 */ 10072, 10082, 10091, 10100, 10109, 10118, 10127, 10136,
|
||||
/* 80 */ 10145, 10155, 10164, 10173, 10182, 10191, 10201, 10210,
|
||||
/* 88 */ 10219, 10228, 10237, 10247, 10256, 10265, 10274, 10284,
|
||||
/* 96 */ 10293, 10302, 10312, 10321, 10330, 10340, 10349, 10358,
|
||||
/* 104 */ 10368, 10377, 10386, 10396, 10405, 10415, 10424, 10433,
|
||||
/* 112 */ 10443, 10452, 10462, 10471, 10481, 10490, 10499, 10509,
|
||||
/* 120 */ 10518, 10528, 10537, 10547, 10556, 10566, 10576, 10585
|
||||
};
|
||||
#else
|
||||
extern unsigned short finetune_table[128];
|
||||
#endif
|
@ -1,188 +0,0 @@
|
||||
/*
|
||||
* sound/gus_card.c
|
||||
*
|
||||
* Detection routine for the Gravis Ultrasound.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if defined(CONFIG_GUS)
|
||||
|
||||
#include <i386/isa/sound/gus_hw.h>
|
||||
#include <i386/isa/sound/iwdefs.h>
|
||||
|
||||
int gus_base, gus_irq, gus_dma;
|
||||
extern int gus_wave_volume;
|
||||
extern int gus_pcm_volume;
|
||||
extern int have_gus_max;
|
||||
extern int gus_timer_enabled;
|
||||
|
||||
static sound_os_info *gus_osp;
|
||||
|
||||
#ifndef NOGUSPNP
|
||||
int IwaveOpen(char voices, char mode, struct address_info * hw);
|
||||
#endif
|
||||
|
||||
void
|
||||
attach_gus_card(struct address_info * hw_config)
|
||||
{
|
||||
int io_addr;
|
||||
|
||||
gus_osp = hw_config->osp;
|
||||
|
||||
snd_set_irq_handler(hw_config->irq, gusintr, hw_config->osp);
|
||||
|
||||
if (gus_wave_detect(hw_config->io_base)) {
|
||||
/* Try first the default */
|
||||
gus_wave_init(hw_config);
|
||||
|
||||
/* 0x10c-> is MAX */
|
||||
|
||||
if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)
|
||||
if (0)
|
||||
printf("gus_card.c: Can't allocate DMA channel2\n");
|
||||
#ifdef CONFIG_MIDI
|
||||
gus_midi_init();
|
||||
#endif
|
||||
return ;
|
||||
}
|
||||
#ifndef EXCLUDE_GUS_IODETECT
|
||||
|
||||
/*
|
||||
* Look at the possible base addresses (0x2X0, X=1, 2, 3, 4, 5, 6)
|
||||
*/
|
||||
|
||||
for (io_addr = 0x210; io_addr <= 0x260; io_addr += 0x10)
|
||||
if ( (io_addr != hw_config->io_base) /* Already tested */
|
||||
&& (gus_wave_detect(io_addr)) ) {
|
||||
hw_config->io_base = io_addr;
|
||||
|
||||
printf(" WARNING! GUS found at %x, config was %x ",
|
||||
io_addr, hw_config->io_base);
|
||||
gus_wave_init(hw_config);
|
||||
/* 0x10c-> is MAX */
|
||||
if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)
|
||||
if (0)
|
||||
printf("gus_card.c: Can't allocate DMA channel2\n");
|
||||
#ifdef CONFIG_MIDI
|
||||
gus_midi_init();
|
||||
#endif
|
||||
return ;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
probe_gus(struct address_info * hw_config)
|
||||
{
|
||||
int io_addr;
|
||||
|
||||
gus_osp = hw_config->osp;
|
||||
#ifndef NOGUSPNP
|
||||
IwaveOpen((char) 32, (char) GUS_MODE, hw_config);
|
||||
#endif
|
||||
if (gus_wave_detect(hw_config->io_base))
|
||||
return 1;
|
||||
printf("oops I didnt find gus \n");
|
||||
#undef EXCLUDE_GUS_IODETECT
|
||||
#ifndef EXCLUDE_GUS_IODETECT
|
||||
|
||||
/*
|
||||
* Look at the possible base addresses (0x2X0, X=1, 2, 3, 4, 5, 6)
|
||||
*/
|
||||
for (io_addr = 0x210; io_addr <= 0x260; io_addr += 0x10)
|
||||
if ( (io_addr != hw_config->io_base) /* Already tested */
|
||||
&& (gus_wave_detect(io_addr)) ) {
|
||||
hw_config->io_base = io_addr;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gusintr(int irq)
|
||||
{
|
||||
u_char src;
|
||||
|
||||
#ifdef CONFIG_GUSMAX
|
||||
if (have_gus_max)
|
||||
ad1848_interrupt(irq);
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
if (!(src = inb(u_IrqStatus)))
|
||||
return;
|
||||
|
||||
if (src & DMA_TC_IRQ)
|
||||
guswave_dma_irq();
|
||||
#ifdef CONFIG_MIDI
|
||||
if (src & (MIDI_TX_IRQ | MIDI_RX_IRQ))
|
||||
gus_midi_interrupt(0);
|
||||
#endif
|
||||
if (src & (GF1_TIMER1_IRQ | GF1_TIMER2_IRQ)) {
|
||||
#ifdef CONFIG_SEQUENCER
|
||||
if (gus_timer_enabled)
|
||||
sound_timer_interrupt();
|
||||
gus_write8(0x45, 0); /* Ack IRQ */
|
||||
gus_timer_command(4, 0x80); /* Reset IRQ flags */
|
||||
#else
|
||||
gus_write8(0x45, 0); /* Stop timers */
|
||||
#endif
|
||||
}
|
||||
if (src & (WAVETABLE_IRQ | ENVELOPE_IRQ))
|
||||
gus_voice_irq();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Some extra code for the 16 bit sampling option
|
||||
*/
|
||||
#if defined(CONFIG_GUS16)
|
||||
|
||||
int
|
||||
probe_gus_db16(struct address_info * hw_config)
|
||||
{
|
||||
return ad1848_detect(hw_config->io_base, NULL, hw_config->osp);
|
||||
}
|
||||
|
||||
void
|
||||
attach_gus_db16(struct address_info * hw_config)
|
||||
{
|
||||
gus_pcm_volume = 100;
|
||||
gus_wave_volume = 90;
|
||||
|
||||
ad1848_init("GUS 16 bit sampling", hw_config->io_base,
|
||||
hw_config->irq,
|
||||
hw_config->dma,
|
||||
hw_config->dma, 0,
|
||||
hw_config->osp);
|
||||
}
|
||||
|
||||
#endif
|
@ -1,50 +0,0 @@
|
||||
|
||||
/*
|
||||
* I/O addresses
|
||||
*/
|
||||
|
||||
#define u_Base (gus_base + 0x000)
|
||||
#define u_Mixer u_Base
|
||||
#define u_Status (gus_base + 0x006)
|
||||
#define u_TimerControl (gus_base + 0x008)
|
||||
#define u_TimerData (gus_base + 0x009)
|
||||
#define u_IRQDMAControl (gus_base + 0x00b)
|
||||
#define u_MidiControl (gus_base + 0x100)
|
||||
#define MIDI_RESET 0x03
|
||||
#define MIDI_ENABLE_XMIT 0x20
|
||||
#define MIDI_ENABLE_RCV 0x80
|
||||
#define u_MidiStatus u_MidiControl
|
||||
#define MIDI_RCV_FULL 0x01
|
||||
#define MIDI_XMIT_EMPTY 0x02
|
||||
#define MIDI_FRAME_ERR 0x10
|
||||
#define MIDI_OVERRUN 0x20
|
||||
#define MIDI_IRQ_PEND 0x80
|
||||
#define u_MidiData (gus_base + 0x101)
|
||||
#define u_Voice (gus_base + 0x102)
|
||||
#define u_Command (gus_base + 0x103)
|
||||
#define u_DataLo (gus_base + 0x104)
|
||||
#define u_DataHi (gus_base + 0x105)
|
||||
#define u_MixData (gus_base + 0x106) /* Rev. 3.7+ mixing */
|
||||
#define u_MixSelect (gus_base + 0x506) /* registers. */
|
||||
#define u_IrqStatus u_Status
|
||||
# define MIDI_TX_IRQ 0x01 /* pending MIDI xmit IRQ */
|
||||
# define MIDI_RX_IRQ 0x02 /* pending MIDI recv IRQ */
|
||||
# define GF1_TIMER1_IRQ 0x04 /* general purpose timer */
|
||||
# define GF1_TIMER2_IRQ 0x08 /* general purpose timer */
|
||||
# define WAVETABLE_IRQ 0x20 /* pending wavetable IRQ */
|
||||
# define ENVELOPE_IRQ 0x40 /* pending volume envelope IRQ */
|
||||
# define DMA_TC_IRQ 0x80 /* pending dma tc IRQ */
|
||||
|
||||
#define ICS2101 1
|
||||
# define ICS_MIXDEVS 6
|
||||
# define DEV_MIC 0
|
||||
# define DEV_LINE 1
|
||||
# define DEV_CD 2
|
||||
# define DEV_GF1 3
|
||||
# define DEV_UNUSED 4
|
||||
# define DEV_VOL 5
|
||||
|
||||
# define CHN_LEFT 0
|
||||
# define CHN_RIGHT 1
|
||||
#define CS4231 2
|
||||
#define u_DRAMIO (gus_base + 0x107)
|
@ -1,18 +0,0 @@
|
||||
static unsigned short gus_linearvol[128] = {
|
||||
0x0000, 0x08ff, 0x09ff, 0x0a80, 0x0aff, 0x0b40, 0x0b80, 0x0bc0,
|
||||
0x0bff, 0x0c20, 0x0c40, 0x0c60, 0x0c80, 0x0ca0, 0x0cc0, 0x0ce0,
|
||||
0x0cff, 0x0d10, 0x0d20, 0x0d30, 0x0d40, 0x0d50, 0x0d60, 0x0d70,
|
||||
0x0d80, 0x0d90, 0x0da0, 0x0db0, 0x0dc0, 0x0dd0, 0x0de0, 0x0df0,
|
||||
0x0dff, 0x0e08, 0x0e10, 0x0e18, 0x0e20, 0x0e28, 0x0e30, 0x0e38,
|
||||
0x0e40, 0x0e48, 0x0e50, 0x0e58, 0x0e60, 0x0e68, 0x0e70, 0x0e78,
|
||||
0x0e80, 0x0e88, 0x0e90, 0x0e98, 0x0ea0, 0x0ea8, 0x0eb0, 0x0eb8,
|
||||
0x0ec0, 0x0ec8, 0x0ed0, 0x0ed8, 0x0ee0, 0x0ee8, 0x0ef0, 0x0ef8,
|
||||
0x0eff, 0x0f04, 0x0f08, 0x0f0c, 0x0f10, 0x0f14, 0x0f18, 0x0f1c,
|
||||
0x0f20, 0x0f24, 0x0f28, 0x0f2c, 0x0f30, 0x0f34, 0x0f38, 0x0f3c,
|
||||
0x0f40, 0x0f44, 0x0f48, 0x0f4c, 0x0f50, 0x0f54, 0x0f58, 0x0f5c,
|
||||
0x0f60, 0x0f64, 0x0f68, 0x0f6c, 0x0f70, 0x0f74, 0x0f78, 0x0f7c,
|
||||
0x0f80, 0x0f84, 0x0f88, 0x0f8c, 0x0f90, 0x0f94, 0x0f98, 0x0f9c,
|
||||
0x0fa0, 0x0fa4, 0x0fa8, 0x0fac, 0x0fb0, 0x0fb4, 0x0fb8, 0x0fbc,
|
||||
0x0fc0, 0x0fc4, 0x0fc8, 0x0fcc, 0x0fd0, 0x0fd4, 0x0fd8, 0x0fdc,
|
||||
0x0fe0, 0x0fe4, 0x0fe8, 0x0fec, 0x0ff0, 0x0ff4, 0x0ff8, 0x0ffc
|
||||
};
|
@ -1,274 +0,0 @@
|
||||
/*
|
||||
* sound/gus2_midi.c
|
||||
*
|
||||
* The low level driver for the GUS Midi Interface.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if defined(CONFIG_GUS) && defined(CONFIG_MIDI)
|
||||
#include <i386/isa/sound/gus_hw.h>
|
||||
|
||||
static int midi_busy = 0, input_opened = 0;
|
||||
static int my_dev;
|
||||
static int output_used = 0;
|
||||
static volatile unsigned char gus_midi_control;
|
||||
|
||||
static void (*midi_input_intr) (int dev, unsigned char data);
|
||||
|
||||
static unsigned char tmp_queue[256];
|
||||
static volatile int qlen;
|
||||
static volatile unsigned char qhead, qtail;
|
||||
extern int gus_base, gus_irq, gus_dma;
|
||||
extern sound_os_info *gus_osp;
|
||||
|
||||
#define GUS_MIDI_STATUS() inb( u_MidiStatus)
|
||||
|
||||
static int
|
||||
gus_midi_open(int dev, int mode,
|
||||
void (*input) (int dev, unsigned char data),
|
||||
void (*output) (int dev)
|
||||
)
|
||||
{
|
||||
|
||||
if (midi_busy) {
|
||||
printf("GUS: Midi busy\n");
|
||||
return -(EBUSY);
|
||||
}
|
||||
outb(u_MidiControl, MIDI_RESET);
|
||||
gus_delay();
|
||||
|
||||
gus_midi_control = 0;
|
||||
input_opened = 0;
|
||||
|
||||
if (mode == OPEN_READ || mode == OPEN_READWRITE) {
|
||||
gus_midi_control |= MIDI_ENABLE_RCV;
|
||||
input_opened = 1;
|
||||
}
|
||||
if (mode == OPEN_WRITE || mode == OPEN_READWRITE) {
|
||||
gus_midi_control |= MIDI_ENABLE_XMIT;
|
||||
}
|
||||
outb(u_MidiControl, gus_midi_control); /* Enable */
|
||||
|
||||
midi_busy = 1;
|
||||
qlen = qhead = qtail = output_used = 0;
|
||||
midi_input_intr = input;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dump_to_midi(unsigned char midi_byte)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ok = 0;
|
||||
|
||||
output_used = 1;
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
if (GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY) {
|
||||
ok = 1;
|
||||
outb(u_MidiData, midi_byte);
|
||||
} else {
|
||||
/*
|
||||
* Enable Midi xmit interrupts (again)
|
||||
*/
|
||||
gus_midi_control |= MIDI_ENABLE_XMIT;
|
||||
outb(u_MidiControl, gus_midi_control);
|
||||
}
|
||||
|
||||
splx(flags);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static void
|
||||
gus_midi_close(int dev)
|
||||
{
|
||||
/*
|
||||
* Reset FIFO pointers, disable intrs
|
||||
*/
|
||||
|
||||
outb(u_MidiControl, MIDI_RESET);
|
||||
midi_busy = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gus_midi_out(int dev, unsigned char midi_byte)
|
||||
{
|
||||
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* Drain the local queue first
|
||||
*/
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
while (qlen && dump_to_midi(tmp_queue[qhead])) {
|
||||
qlen--;
|
||||
qhead++;
|
||||
}
|
||||
|
||||
splx(flags);
|
||||
|
||||
/*
|
||||
* Output the byte if the local queue is empty.
|
||||
*/
|
||||
|
||||
if (!qlen)
|
||||
if (dump_to_midi(midi_byte))
|
||||
return 1; /* OK */
|
||||
|
||||
/*
|
||||
* Put to the local queue
|
||||
*/
|
||||
|
||||
if (qlen >= 256)
|
||||
return 0; /* Local queue full */
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
tmp_queue[qtail] = midi_byte;
|
||||
qlen++;
|
||||
qtail++;
|
||||
|
||||
splx(flags);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
gus_midi_start_read(int dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gus_midi_end_read(int dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gus_midi_ioctl(int dev, unsigned cmd, ioctl_arg arg)
|
||||
{
|
||||
return -(EINVAL);
|
||||
}
|
||||
|
||||
static void
|
||||
gus_midi_kick(int dev)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
gus_midi_buffer_status(int dev)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (!output_used)
|
||||
return 0;
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
if (qlen && dump_to_midi(tmp_queue[qhead])) {
|
||||
qlen--;
|
||||
qhead++;
|
||||
}
|
||||
splx(flags);
|
||||
|
||||
return (qlen > 0) | !(GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY);
|
||||
}
|
||||
|
||||
#define MIDI_SYNTH_NAME "Gravis Ultrasound Midi"
|
||||
#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
|
||||
#include <i386/isa/sound/midi_synth.h>
|
||||
|
||||
static struct midi_operations gus_midi_operations =
|
||||
{
|
||||
{"Gravis UltraSound Midi", 0, 0, SNDCARD_GUS},
|
||||
&std_midi_synth,
|
||||
{0},
|
||||
gus_midi_open,
|
||||
gus_midi_close,
|
||||
gus_midi_ioctl,
|
||||
gus_midi_out,
|
||||
gus_midi_start_read,
|
||||
gus_midi_end_read,
|
||||
gus_midi_kick,
|
||||
NULL, /* command */
|
||||
gus_midi_buffer_status,
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
gus_midi_init()
|
||||
{
|
||||
if (num_midis >= MAX_MIDI_DEV) {
|
||||
printf("Sound: Too many midi devices detected\n");
|
||||
return;
|
||||
}
|
||||
outb(u_MidiControl, MIDI_RESET);
|
||||
|
||||
std_midi_synth.midi_dev = my_dev = num_midis;
|
||||
midi_devs[num_midis++] = &gus_midi_operations;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
gus_midi_interrupt(int dummy)
|
||||
{
|
||||
unsigned char stat, data;
|
||||
unsigned long flags;
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
stat = GUS_MIDI_STATUS();
|
||||
|
||||
if (stat & MIDI_RCV_FULL) {
|
||||
data = inb(u_MidiData);
|
||||
if (input_opened)
|
||||
midi_input_intr(my_dev, data);
|
||||
}
|
||||
if (stat & MIDI_XMIT_EMPTY) {
|
||||
while (qlen && dump_to_midi(tmp_queue[qhead])) {
|
||||
qlen--;
|
||||
qhead++;
|
||||
}
|
||||
|
||||
if (!qlen) {
|
||||
/*
|
||||
* Disable Midi output interrupts, since no data in
|
||||
* the buffer
|
||||
*/
|
||||
gus_midi_control &= ~MIDI_ENABLE_XMIT;
|
||||
outb(u_MidiControl, gus_midi_control);
|
||||
}
|
||||
}
|
||||
splx(flags);
|
||||
}
|
||||
|
||||
#endif
|
@ -1,138 +0,0 @@
|
||||
/*
|
||||
* gus_vol.c - Compute volume for GUS.
|
||||
*
|
||||
* Greg Lee 1993.
|
||||
*/
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#ifdef CONFIG_GUS
|
||||
#include <i386/isa/sound/gus_linearvol.h>
|
||||
|
||||
#define GUS_VOLUME gus_wave_volume
|
||||
|
||||
|
||||
extern int gus_wave_volume;
|
||||
unsigned short gus_adagio_vol(int vel, int mainv, int xpn, int voicev);
|
||||
unsigned short gus_linear_vol(int vol, int mainvol);
|
||||
|
||||
/*
|
||||
* Calculate gus volume from note velocity, main volume, expression, and
|
||||
* intrinsic patch volume given in patch library. Expression is multiplied
|
||||
* in, so it emphasizes differences in note velocity, while main volume is
|
||||
* added in -- I don't know whether this is right, but it seems reasonable to
|
||||
* me. (In the previous stage, main volume controller messages were changed
|
||||
* to expression controller messages, if they were found to be used for
|
||||
* dynamic volume adjustments, so here, main volume can be assumed to be
|
||||
* constant throughout a song.)
|
||||
*
|
||||
* Intrinsic patch volume is added in, but if over 64 is also multiplied in, so
|
||||
* we can give a big boost to very weak voices like nylon guitar and the
|
||||
* basses. The normal value is 64. Strings are assigned lower values.
|
||||
*/
|
||||
unsigned short
|
||||
gus_adagio_vol(int vel, int mainv, int xpn, int voicev)
|
||||
{
|
||||
int i, m, n, x;
|
||||
|
||||
/*
|
||||
* A voice volume of 64 is considered neutral, so adjust the main
|
||||
* volume if something other than this neutral value was assigned in
|
||||
* the patch library.
|
||||
*/
|
||||
x = 256 + 6 * (voicev - 64);
|
||||
|
||||
/*
|
||||
* Boost expression by voice volume above neutral.
|
||||
*/
|
||||
if (voicev > 65)
|
||||
xpn += voicev - 64;
|
||||
xpn += (voicev - 64) / 2;
|
||||
|
||||
/*
|
||||
* Combine multiplicative and level components.
|
||||
*/
|
||||
x = vel * xpn * 6 + (voicev / 4) * x;
|
||||
|
||||
#ifdef GUS_VOLUME
|
||||
/*
|
||||
* Further adjustment by installation-specific master volume control
|
||||
* (default 60).
|
||||
*/
|
||||
x = (x * GUS_VOLUME * GUS_VOLUME) / 10000;
|
||||
#endif
|
||||
|
||||
#ifdef GUS_USE_CHN_MAIN_VOLUME
|
||||
/*
|
||||
* Experimental support for the channel main volume
|
||||
*/
|
||||
|
||||
mainv = (mainv / 2) + 64; /* Scale to 64 to 127 */
|
||||
x = (x * mainv * mainv) / 16384;
|
||||
#endif
|
||||
|
||||
if (x < 2)
|
||||
return (0);
|
||||
else if (x >= 65535)
|
||||
return ((15 << 8) | 255);
|
||||
|
||||
/*
|
||||
* Convert to gus's logarithmic form with 4 bit exponent i and 8 bit
|
||||
* mantissa m.
|
||||
*/
|
||||
n = x;
|
||||
i = 7;
|
||||
if (n < 128) {
|
||||
while (i > 0 && n < (1 << i))
|
||||
i--;
|
||||
} else
|
||||
while (n > 255) {
|
||||
n >>= 1;
|
||||
i++;
|
||||
}
|
||||
/*
|
||||
* Mantissa is part of linear volume not expressed in exponent.
|
||||
* (This is not quite like real logs -- I wonder if it's right.)
|
||||
*/
|
||||
m = x - (1 << i);
|
||||
|
||||
/*
|
||||
* Adjust mantissa to 8 bits.
|
||||
*/
|
||||
if (m > 0) {
|
||||
if (i > 8)
|
||||
m >>= i - 8;
|
||||
else if (i < 8)
|
||||
m <<= 8 - i;
|
||||
}
|
||||
return ((i << 8) + m);
|
||||
}
|
||||
|
||||
/*
|
||||
* Volume-values are interpreted as linear values. Volume is based on the
|
||||
* value supplied with SEQ_START_NOTE(), channel main volume (if compiled in)
|
||||
* and the volume set by the mixer-device (default 60%).
|
||||
*/
|
||||
|
||||
unsigned short
|
||||
gus_linear_vol(int vol, int mainvol)
|
||||
{
|
||||
int mixer_mainvol;
|
||||
|
||||
RANGE (vol, 0, 127) ;
|
||||
|
||||
#ifdef GUS_VOLUME
|
||||
mixer_mainvol = GUS_VOLUME;
|
||||
#else
|
||||
mixer_mainvol = 100;
|
||||
#endif
|
||||
|
||||
#ifdef GUS_USE_CHN_MAIN_VOLUME
|
||||
RANGE (mainvol, 0, 127);
|
||||
#else
|
||||
mainvol = 127;
|
||||
#endif
|
||||
|
||||
return gus_linearvol[(((vol * mainvol) / 127) * mixer_mainvol) / 100];
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,97 +0,0 @@
|
||||
/*
|
||||
* This file is a part of configure.c
|
||||
*
|
||||
* hex2hex reads an input file in Intel HEX format and produces
|
||||
* an (unsigned char) array which contains the bytes and writes it to the
|
||||
* output file using C syntax
|
||||
*/
|
||||
|
||||
#define MAX_SIZE (256*1024)
|
||||
#define ABANDON(why) { \
|
||||
fprintf(stderr, "%s: " why "\n", source); \
|
||||
fclose(inf);fclose(outf);return 0; \
|
||||
}
|
||||
|
||||
int hex2hex(char *source, char *target, char *varline)
|
||||
{
|
||||
FILE *inf, *outf;
|
||||
|
||||
int i,l, c;
|
||||
unsigned char buf[MAX_SIZE];
|
||||
|
||||
if ((inf=fopen(source, "r"))==NULL)
|
||||
{
|
||||
perror(source);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((outf=fopen(target, "w"))==NULL)
|
||||
{
|
||||
perror(target);
|
||||
fclose(inf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
l=0;
|
||||
|
||||
while ((c=getc(inf))!=EOF)
|
||||
{
|
||||
if (c == ':') /* Sync with beginning of line */
|
||||
{
|
||||
int n, check;
|
||||
unsigned char sum;
|
||||
int addr;
|
||||
int linetype;
|
||||
|
||||
if (fscanf(inf, "%02x", &n) != 1)
|
||||
ABANDON("File format error");
|
||||
sum = n;
|
||||
|
||||
if (fscanf(inf, "%04x", &addr) != 1)
|
||||
ABANDON("File format error");
|
||||
sum += addr/256;
|
||||
sum += addr%256;
|
||||
|
||||
if (fscanf(inf, "%02x", &linetype) != 1)
|
||||
ABANDON("File format error");
|
||||
sum += linetype;
|
||||
|
||||
if (linetype != 0)
|
||||
continue;
|
||||
|
||||
for (i=0;i<n;i++)
|
||||
{
|
||||
if (fscanf(inf, "%02x", &c) != 1)
|
||||
ABANDON("File format error");
|
||||
if (addr >= MAX_SIZE)
|
||||
ABANDON("File too large");
|
||||
buf[addr++] = c;
|
||||
if (addr > l)
|
||||
l = addr;
|
||||
sum += c;
|
||||
}
|
||||
|
||||
if (fscanf(inf, "%02x", &check) != 1)
|
||||
ABANDON("File format error");
|
||||
|
||||
sum = ~sum + 1;
|
||||
if (check != sum)
|
||||
ABANDON("Line checksum error");
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(outf, "/*\n *\t Computer generated file. Do not edit.\n */\n");
|
||||
fprintf(outf, "static unsigned char %s[] = {\n", varline);
|
||||
|
||||
for (i=0;i<l;i++)
|
||||
{
|
||||
if (i) fprintf(outf, ",");
|
||||
if (i && !(i % 16)) fprintf(outf, "\n");
|
||||
fprintf(outf, "0x%02x", buf[i]);
|
||||
}
|
||||
|
||||
fprintf(outf, "\n};\n\n");
|
||||
fclose(inf);
|
||||
fclose(outf);
|
||||
return 1;
|
||||
}
|
@ -1,233 +0,0 @@
|
||||
/*
|
||||
* sound/ics2101.c
|
||||
*
|
||||
* Driver for the ICS2101 mixer of GUS v3.7.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1994
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if defined(CONFIG_GUS)
|
||||
|
||||
#include <i386/isa/sound/ultrasound.h>
|
||||
#include <i386/isa/sound/gus_hw.h>
|
||||
|
||||
#define MIX_DEVS (SOUND_MASK_MIC|SOUND_MASK_LINE| \
|
||||
SOUND_MASK_SYNTH| \
|
||||
SOUND_MASK_CD | SOUND_MASK_VOLUME)
|
||||
|
||||
extern sound_os_info *gus_osp;
|
||||
extern int gus_base;
|
||||
static int volumes[ICS_MIXDEVS];
|
||||
static int left_fix[ICS_MIXDEVS] = {1, 1, 1, 2, 1, 2};
|
||||
static int right_fix[ICS_MIXDEVS] = {2, 2, 2, 1, 2, 1};
|
||||
|
||||
static int
|
||||
scale_vol(int vol)
|
||||
{
|
||||
/*
|
||||
* Experimental volume scaling by Risto Kankkunen. This should give
|
||||
* smoother volume response than just a plain multiplication.
|
||||
*/
|
||||
int e;
|
||||
|
||||
RANGE(vol, 0, 100);
|
||||
vol = (31 * vol + 50) / 100;
|
||||
e = 0;
|
||||
if (vol) {
|
||||
while (vol < 16) {
|
||||
vol <<= 1;
|
||||
e--;
|
||||
}
|
||||
vol -= 16;
|
||||
e += 7;
|
||||
}
|
||||
return ((e << 4) + vol);
|
||||
}
|
||||
|
||||
static void
|
||||
write_mix(int dev, int chn, int vol)
|
||||
{
|
||||
int *selector;
|
||||
unsigned long flags;
|
||||
int ctrl_addr = dev << 3;
|
||||
int attn_addr = dev << 3;
|
||||
|
||||
vol = scale_vol(vol);
|
||||
|
||||
if (chn == CHN_LEFT) {
|
||||
selector = left_fix;
|
||||
ctrl_addr |= 0x00;
|
||||
attn_addr |= 0x02;
|
||||
} else {
|
||||
selector = right_fix;
|
||||
ctrl_addr |= 0x01;
|
||||
attn_addr |= 0x03;
|
||||
}
|
||||
|
||||
flags = splhigh();
|
||||
outb(u_MixSelect, ctrl_addr);
|
||||
outb(u_MixData, selector[dev]);
|
||||
outb(u_MixSelect, attn_addr);
|
||||
outb(u_MixData, (unsigned char) vol);
|
||||
splx(flags);
|
||||
}
|
||||
|
||||
static int
|
||||
set_volumes(int dev, int vol)
|
||||
{
|
||||
int left = vol & 0x00ff;
|
||||
int right = (vol >> 8) & 0x00ff;
|
||||
|
||||
RANGE (left, 0, 100);
|
||||
RANGE (right, 0, 100);
|
||||
|
||||
write_mix(dev, CHN_LEFT, left);
|
||||
write_mix(dev, CHN_RIGHT, right);
|
||||
|
||||
vol = left + (right << 8);
|
||||
volumes[dev] = vol;
|
||||
return vol;
|
||||
}
|
||||
|
||||
static int
|
||||
ics2101_mixer_ioctl(int dev, unsigned int cmd, ioctl_arg arg)
|
||||
{
|
||||
if (((cmd >> 8) & 0xff) == 'M') {
|
||||
if (cmd & IOC_IN)
|
||||
switch (cmd & 0xff) {
|
||||
case SOUND_MIXER_RECSRC:
|
||||
return gus_default_mixer_ioctl(dev, cmd, arg);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_MIC:
|
||||
return *(int *) arg = set_volumes(DEV_MIC, (*(int *) arg));
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_CD:
|
||||
return *(int *) arg = set_volumes(DEV_CD, (*(int *) arg));
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_LINE:
|
||||
return *(int *) arg = set_volumes(DEV_LINE, (*(int *) arg));
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_SYNTH:
|
||||
return *(int *) arg = set_volumes(DEV_GF1, (*(int *) arg));
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_VOLUME:
|
||||
return *(int *) arg = set_volumes(DEV_VOL, (*(int *) arg));
|
||||
break;
|
||||
|
||||
default:
|
||||
return -(EINVAL);
|
||||
}
|
||||
else
|
||||
switch (cmd & 0xff) { /* Return parameters */
|
||||
|
||||
case SOUND_MIXER_RECSRC:
|
||||
return gus_default_mixer_ioctl(dev, cmd, arg);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_DEVMASK:
|
||||
return *(int *) arg = MIX_DEVS;
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_STEREODEVS:
|
||||
return *(int *) arg = SOUND_MASK_LINE | SOUND_MASK_CD |
|
||||
SOUND_MASK_SYNTH | SOUND_MASK_VOLUME | SOUND_MASK_MIC;
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_RECMASK:
|
||||
return *(int *) arg = SOUND_MASK_MIC | SOUND_MASK_LINE;
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_CAPS:
|
||||
return *(int *) arg = 0;
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_MIC:
|
||||
return *(int *) arg = volumes[DEV_MIC];
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_LINE:
|
||||
return *(int *) arg = volumes[DEV_LINE];
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_CD:
|
||||
return *(int *) arg = volumes[DEV_CD];
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_VOLUME:
|
||||
return *(int *) arg = volumes[DEV_VOL];
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_SYNTH:
|
||||
return *(int *) arg = volumes[DEV_GF1];
|
||||
break;
|
||||
|
||||
default:
|
||||
return -(EINVAL);
|
||||
}
|
||||
}
|
||||
return -(EINVAL);
|
||||
}
|
||||
|
||||
static struct mixer_operations ics2101_mixer_operations =
|
||||
{
|
||||
"ICS2101 Multimedia Mixer",
|
||||
ics2101_mixer_ioctl
|
||||
};
|
||||
|
||||
void
|
||||
ics2101_mixer_init()
|
||||
{
|
||||
int i;
|
||||
|
||||
if (num_mixers < MAX_MIXER_DEV) {
|
||||
mixer_devs[num_mixers++] = &ics2101_mixer_operations;
|
||||
|
||||
/*
|
||||
* Some GUS v3.7 cards had some channels flipped. Disable the
|
||||
* flipping feature if the model id is other than 5.
|
||||
*/
|
||||
|
||||
if (inb(u_MixSelect) != 5) {
|
||||
for (i = 0; i < ICS_MIXDEVS; i++)
|
||||
left_fix[i] = 1;
|
||||
for (i = 0; i < ICS_MIXDEVS; i++)
|
||||
right_fix[i] = 2;
|
||||
}
|
||||
set_volumes(DEV_GF1, 0x5a5a);
|
||||
set_volumes(DEV_CD, 0x5a5a);
|
||||
set_volumes(DEV_MIC, 0x0000);
|
||||
set_volumes(DEV_LINE, 0x5a5a);
|
||||
set_volumes(DEV_VOL, 0x5a5a);
|
||||
set_volumes(DEV_UNUSED, 0x0000);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,712 +0,0 @@
|
||||
/*#######################################################################*/
|
||||
/* FILE : iwdefs.h*/
|
||||
/**/
|
||||
/* REMARKS: This file contains all defines used by DDK functions. It*/
|
||||
/* should be included by all applications and should be*/
|
||||
/* referenced by programmers to make their code easy to read*/
|
||||
/* and understand.*/
|
||||
/**/
|
||||
/* UPDATE: 3/21/95*/
|
||||
/* 7/10/95 --- added #def DRAM_HOLES*/
|
||||
/*#######################################################################*/
|
||||
#ifndef IWDEFS
|
||||
#define IWDEFS
|
||||
/*#######################################################################*/
|
||||
/**/
|
||||
/* Macros for use in loading Synth Addr Regs*/
|
||||
/**/
|
||||
/*#######################################################################*/
|
||||
#define ADDR_HIGH(x) (short)(x>>7)
|
||||
#define ADDR_LOW(x) (short)(x<<9)
|
||||
/*#######################################################################*/
|
||||
/**/
|
||||
/* Defines for DMA Controllers*/
|
||||
/**/
|
||||
/*#######################################################################*/
|
||||
/* DMA Controler #1 (8-bit controller) */
|
||||
#define DMA1_STAT 0x08 /* read status register */
|
||||
#define DMA1_WCMD 0x08 /* write command register */
|
||||
#define DMA1_WREQ 0x09 /* write request register */
|
||||
#define DMA1_SNGL 0x0A /* write single bit register */
|
||||
#define DMA1_MODE 0x0B /* write mode register */
|
||||
#define DMA1_CLRFF 0x0C /* clear byte ptr flip/flop */
|
||||
#define DMA1_MCLR 0x0D /* master clear register */
|
||||
#define DMA1_CLRM 0x0E /* clear mask register */
|
||||
#define DMA1_WRTALL 0x0F /* write all mask register */
|
||||
|
||||
/* DMA Controler #2 (16-bit controller) */
|
||||
#define DMA2_STAT 0xD0 /* read status register */
|
||||
#define DMA2_WCMD 0xD0 /* write command register */
|
||||
#define DMA2_WREQ 0xD2 /* write request register */
|
||||
#define DMA2_SNGL 0xD4 /* write single bit register */
|
||||
#define DMA2_MODE 0xD6 /* write mode register */
|
||||
#define DMA2_CLRFF 0xD8 /* clear byte ptr flip/flop */
|
||||
#define DMA2_MCLR 0xDA /* master clear register */
|
||||
#define DMA2_CLRM 0xDC /* clear mask register */
|
||||
#define DMA2_WRTALL 0xDE /* write all mask register */
|
||||
|
||||
#define DMA0_ADDR 0x00 /* chan 0 base adddress */
|
||||
#define DMA0_CNT 0x01 /* chan 0 base count */
|
||||
#define DMA1_ADDR 0x02 /* chan 1 base adddress */
|
||||
#define DMA1_CNT 0x03 /* chan 1 base count */
|
||||
#define DMA2_ADDR 0x04 /* chan 2 base adddress */
|
||||
#define DMA2_CNT 0x05 /* chan 2 base count */
|
||||
#define DMA3_ADDR 0x06 /* chan 3 base adddress */
|
||||
#define DMA3_CNT 0x07 /* chan 3 base count */
|
||||
#define DMA4_ADDR 0xC0 /* chan 4 base adddress */
|
||||
#define DMA4_CNT 0xC2 /* chan 4 base count */
|
||||
#define DMA5_ADDR 0xC4 /* chan 5 base adddress */
|
||||
#define DMA5_CNT 0xC6 /* chan 5 base count */
|
||||
#define DMA6_ADDR 0xC8 /* chan 6 base adddress */
|
||||
#define DMA6_CNT 0xCA /* chan 6 base count */
|
||||
#define DMA7_ADDR 0xCC /* chan 7 base adddress */
|
||||
#define DMA7_CNT 0xCE /* chan 7 base count */
|
||||
|
||||
#define DMA0_PAGE 0x87 /* chan 0 page register (refresh)*/
|
||||
#define DMA1_PAGE 0x83 /* chan 1 page register */
|
||||
#define DMA2_PAGE 0x81 /* chan 2 page register */
|
||||
#define DMA3_PAGE 0x82 /* chan 3 page register */
|
||||
#define DMA4_PAGE 0x8F /* chan 4 page register (unusable)*/
|
||||
#define DMA5_PAGE 0x8B /* chan 5 page register */
|
||||
#define DMA6_PAGE 0x89 /* chan 6 page register */
|
||||
#define DMA7_PAGE 0x8A /* chan 7 page register */
|
||||
/*#######################################################################*/
|
||||
/**/
|
||||
/* Defines for register UISR (Interrupt Status)*/
|
||||
/**/
|
||||
/*#######################################################################*/
|
||||
#define MIDI_TX_IRQ 0x01
|
||||
#define MIDI_RX_IRQ 0x02
|
||||
#define ALIB_TIMER1_IRQ 0x04
|
||||
#define ALIB_TIMER2_IRQ 0x08
|
||||
#define _UASBCI 0x45 /* UASBCI index */
|
||||
#define SAMPLE_CONTROL 0x49 /* Not used by IW */
|
||||
#define SET_VOICES 0x0E
|
||||
#define WAVETABLE_IRQ 0x20
|
||||
#define ENVELOPE_IRQ 0x40
|
||||
#define DMA_TC_IRQ 0x80
|
||||
/*#######################################################################*/
|
||||
/**/
|
||||
/* Synthesizer-related defines*/
|
||||
/**/
|
||||
/*#######################################################################*/
|
||||
#define GEN_INDEX 0x03 /* IGIDX offset into p3xr */
|
||||
#define VOICE_SELECT 0x02 /* SVSR offset into p3xr */
|
||||
#define VOICE_IRQS 0x8F /* SVII index (read) */
|
||||
#define _URSTI 0x4C /* URSTI index */
|
||||
#define GF1_SET 0x01 /* URSTI[0] */
|
||||
#define GF1_OUT_ENABLE 0x02 /* URSTI[1] */
|
||||
#define GF1_IRQ_ENABLE 0x04 /* URSTI[2] */
|
||||
#define GF1_RESET 0xFE /* URSTI[0]=0 */
|
||||
#define VOICE_VOLUME_IRQ 0x04 /* SVII[2] */
|
||||
#define VOICE_WAVE_IRQ 0x08 /* SVII[3] */
|
||||
#define VC_IRQ_ENABLE 0x20 /* SACI[5] or SVCI[5]*/
|
||||
#define VOICE_NUMBER 0x1F /* Mask for SVII[4:0] */
|
||||
#define VC_IRQ_PENDING 0x80 /* SACI[7] or SVCI[7] */
|
||||
#define VC_DIRECT 0x40 /* SACI[6] or SVCI[6]*/
|
||||
#define VC_DATA_WIDTH 0x04 /* SACI[2] */
|
||||
#define VOICE_STOP 0x02 /* SACI[1] */
|
||||
#define VOICE_STOPPED 0x01 /* SACI[0] */
|
||||
#define VOLUME_STOP 0x02 /* SVCI[1] */
|
||||
#define VOLUME_STOPPED 0x01 /* SVCI[0] */
|
||||
#define VC_ROLLOVER 0x04 /* SVCI[2] */
|
||||
#define VC_LOOP_ENABLE 0x08 /* SVCI[3] or SACI[3]*/
|
||||
#define VC_BI_LOOP 0x10 /* SVCI[4] or SACI[4]*/
|
||||
#define VOICE_OFFSET 0x20 /* SMSI[5] */
|
||||
#define VOLUME_RATE0 0x00 /* SVRI[7:6]=(0,0) */
|
||||
#define VOLUME_RATE1 0x40 /* SVRI[7:6]=(0,1) */
|
||||
#define VOLUME_RATE2 0x80 /* SVRI[7:6]=(1,0) */
|
||||
#define VOLUME_RATE3 0xC0 /* SVRI[7:6]=(1,1) */
|
||||
/*#######################################################################*/
|
||||
/**/
|
||||
/* Power-Mode Control Defines*/
|
||||
/**/
|
||||
/*#######################################################################*/
|
||||
#define SHUT_DOWN 0x7E /* shuts InterWave down */
|
||||
#define POWER_UP 0xFE /* enables all modules */
|
||||
#define CODEC_PWR_UP 0x81 /* enables Codec Analog Ckts */
|
||||
#define CODEC_PWR_DOWN 0x01 /* disables Codec Analog Ckts */
|
||||
#define CODEC_REC_UP 0x82 /* Enables Record Path */
|
||||
#define CODEC_REC_DOWN 0x02 /* Disables Record Path */
|
||||
#define CODEC_PLAY_UP 0x84 /* Enables Playback Path */
|
||||
#define CODEC_PLAY_DOWN 0x04 /* Disables Playback Path */
|
||||
#define CODEC_IRQ_ENABLE 0x02 /* CEXTI[2] */
|
||||
#define CODEC_TIMER_IRQ 0x40 /* CSR3I[6] */
|
||||
#define CODEC_REC_IRQ 0x20 /* CSR3I[5] */
|
||||
#define CODEC_PLAY_IRQ 0x10 /* CSR3I[4] */
|
||||
#define CODEC_INT 0x01 /* CSR1R[0] */
|
||||
#define MONO_INPUT 0x80 /* CMONOI[7] */
|
||||
#define MONO_OUTPUT 0x40 /* CMONOI[6] */
|
||||
#define MIDI_UP 0x88 /* Enables MIDI ports */
|
||||
#define MIDI_DOWN 0x08 /* Disables MIDI ports */
|
||||
#define SYNTH_UP 0x90 /* Enables Synthesizer */
|
||||
#define SYNTH_DOWN 0x10 /* Disables Synthesizer */
|
||||
#define LMC_UP 0xA0 /* Enables LM Module */
|
||||
#define LMC_DOWN 0x20 /* Disbales LM Module */
|
||||
#define XTAL24_UP 0xC0 /* Enables 24MHz Osc */
|
||||
#define XTAL24_DOWN 0x40 /* Disables 24MHz Osc */
|
||||
#define _PPWRI 0xF2 /* PPWRI index */
|
||||
#define PLAY 0x0F
|
||||
#define REC 0x1F
|
||||
#define LEFT_AUX1_INPUT 0x02
|
||||
#define RIGHT_AUX1_INPUT 0x03
|
||||
#define LEFT_AUX2_INPUT 0x04
|
||||
#define RIGHT_AUX2_INPUT 0x05
|
||||
#define LEFT_LINE_IN 0x12
|
||||
#define RIGHT_LINE_IN 0x13
|
||||
#define LEFT_LINE_OUT 0x19
|
||||
#define RIGHT_LINE_OUT 0x1B
|
||||
#define LEFT_SOURCE 0x00
|
||||
#define RIGHT_SOURCE 0x01
|
||||
#define LINE_IN 0x00
|
||||
#define AUX1_IN 0x40
|
||||
#define MIC_IN 0x80
|
||||
#define MIX_IN 0xC0
|
||||
#define LEFT_DAC 0x06
|
||||
#define RIGHT_DAC 0x07
|
||||
#define LEFT_MIC_IN 0x16
|
||||
#define RIGHT_MIC_IN 0x17
|
||||
#define _CUPCTI 0x0E
|
||||
#define _CLPCTI 0x0F
|
||||
#define _CURCTI 0x1E
|
||||
#define _CLRCTI 0x1F
|
||||
#define _CLAX1I 0x02
|
||||
#define _CRAX1I 0x03
|
||||
#define _CLAX2I 0x04
|
||||
#define _CRAX2I 0x05
|
||||
#define _CLLICI 0x12
|
||||
#define _CRLICI 0x13
|
||||
#define _CLOAI 0x19
|
||||
#define _CROAI 0x1B
|
||||
#define _CLICI 0x00
|
||||
#define _CRICI 0x01
|
||||
#define _CLDACI 0x06
|
||||
#define _CRDACI 0x07
|
||||
#define _CPVFI 0x1D
|
||||
/*#######################################################################*/
|
||||
/**/
|
||||
/* Defines for DMA transfer related operations*/
|
||||
/**/
|
||||
/*#######################################################################*/
|
||||
#define MAX_DMA 0x07
|
||||
#define DMA_DECREMENT 0x20
|
||||
#define AUTO_INIT 0x10
|
||||
#define DMA_READ 0x01
|
||||
#define DMA_WRITE 0x02
|
||||
#define AUTO_READ 0x03
|
||||
#define AUTO_WRITE 0x04
|
||||
#define IDMA_INV 0x0400
|
||||
#define IDMA_WIDTH_16 0x0100
|
||||
/*#######################################################################*/
|
||||
/**/
|
||||
/* Bits for dma flags within a DMA structure.*/
|
||||
/**/
|
||||
/*#######################################################################*/
|
||||
#define DMA_USED 0x0001
|
||||
|
||||
#define DMA_SPLIT 0x0004 /* DMA Controller Page Crossover*/
|
||||
#define CODEC_DMA 0x0008 /* Indicates a Codec DMA*/
|
||||
#define DMA_WAIT 0x0020 /* Wait for DMA xfer to complete*/
|
||||
#define DMA_DOWN 0x0040 /* DMA xfer from PC to InterWave*/
|
||||
#define DRAM_HOLES 0x8000 /* Indicates Non-contiguous RAM configuration*/
|
||||
#define DMA_UP 0xFFBF /* DMA xfer from InterWave to PC */
|
||||
/*#######################################################################*/
|
||||
/**/
|
||||
/* Bits for DMA Control Register (LDMACI)*/
|
||||
/**/
|
||||
/*#######################################################################*/
|
||||
#define _LDMACI 0x41 /* Index */
|
||||
#define DMA_INV 0x80
|
||||
#define DMA_IRQ_ENABLE 0x20
|
||||
#define DMA_IRQ_PENDING 0x40 /* on reads of LDMACI[6] */
|
||||
#define DMA_DATA_16 0x40 /* on writes to LDMACI[6] */
|
||||
#define DMA_WIDTH_16 0x04 /* 1=16-bit, 0=8-bit (DMA channel) */
|
||||
#define DMA_RATE 0x18 /* 00=fastest,...,11=slowest */
|
||||
#define DMA_UPLOAD 0x02 /* From LM to PC */
|
||||
#define DMA_ENABLE 0x01
|
||||
/*#######################################################################*/
|
||||
/**/
|
||||
/* DMA Transfer Rates*/
|
||||
/**/
|
||||
/*#######################################################################*/
|
||||
#define DMA_R0 0xE7 /* Fastest (use ANDing to set) */
|
||||
#define DMA_R1 0x08
|
||||
#define DMA_R2 0x10
|
||||
#define DMA_R3 0x18 /* Slowest */
|
||||
/*#######################################################################*/
|
||||
/**/
|
||||
/* Interrupt Controller Defines*/
|
||||
/**/
|
||||
/*#######################################################################*/
|
||||
#define IW_HANDLERS_ON 0x80 /* Flag for when IVT is modified */
|
||||
#define EOI 0x20
|
||||
#define OCR1 0x20 /* 8259-1 Operation Control Reg. */
|
||||
#define IMR1 0x21 /* 8259-1 Interrupt Mask Reg. */
|
||||
#define OCR2 0xA0 /* 8259-2 Operation Control Reg. */
|
||||
#define IMR2 0xA1 /* 8259-2 Interrupt Mask Reg. */
|
||||
#define IRQ0_UNMASK 0xFE /* Mask to clear bit 0 in IMR */
|
||||
#define IRQ1_UNMASK 0xFD
|
||||
#define IRQ2_UNMASK 0xFB
|
||||
#define IRQ3_UNMASK 0xF7
|
||||
#define IRQ4_UNMASK 0xEF
|
||||
#define IRQ5_UNMASK 0xDF
|
||||
#define IRQ6_UNMASK 0xBF
|
||||
#define IRQ7_UNMASK 0x7F
|
||||
#define IRQ8_UNMASK 0xFE /* Mask to clear bit 0 in IMR */
|
||||
#define IRQ9_UNMASK 0xFD
|
||||
#define IRQ10_UNMASK 0xFB
|
||||
#define IRQ11_UNMASK 0xF7
|
||||
#define IRQ12_UNMASK 0xEF
|
||||
#define IRQ13_UNMASK 0xDF
|
||||
#define IRQ14_UNMASK 0xBF
|
||||
#define IRQ15_UNMASK 0x7F
|
||||
#define IRQ0_EOI 0x60 /* Spec EOI for IRQ0 */
|
||||
#define IRQ1_EOI 0x61
|
||||
#define IRQ2_EOI 0x62
|
||||
#define IRQ3_EOI 0x63
|
||||
#define IRQ4_EOI 0x64
|
||||
#define IRQ5_EOI 0x65
|
||||
#define IRQ6_EOI 0x66
|
||||
#define IRQ7_EOI 0x67
|
||||
#define IRQ8_EOI 0x60 /* Spec EOI for IRQ8 */
|
||||
#define IRQ9_EOI 0x61
|
||||
#define IRQ10_EOI 0x62
|
||||
#define IRQ11_EOI 0x63
|
||||
#define IRQ12_EOI 0x64
|
||||
#define IRQ13_EOI 0x65
|
||||
#define IRQ14_EOI 0x66
|
||||
#define IRQ15_EOI 0x67
|
||||
/*#######################################################################*/
|
||||
/**/
|
||||
/* Generic defines*/
|
||||
/**/
|
||||
/*#######################################################################*/
|
||||
/**/
|
||||
#define MEMBANK0 0L /* Addr of Memory Bank 0*/
|
||||
#define MEMBANK1 4194304L /* Addr of Memory Bank 1*/
|
||||
#define MEMBANK2 8388608L /* Addr of Memory Bank 2*/
|
||||
#define MEMBANK3 12582912L /* Addr of Memory Bank 3*/
|
||||
#define IRQ_UNAVAIL 0x0000
|
||||
#define IRQ_AVAIL 0x0001
|
||||
#define IRQ_USED 0x0002
|
||||
#define MAX_IRQ 16
|
||||
#define NEXT_OFFSET 0L
|
||||
#define PREV_OFFSET 4L
|
||||
#define SIZE_OFFSET 8L
|
||||
#define MEM_HEADER_SIZE 12L
|
||||
#define GF1_POOL (usigned long)(256L*1024L)
|
||||
#define GUS_MODE 0x00 /* SGMI[0]=0*/
|
||||
#define ENH_MODE 0x01 /* SGMI[0]=1*/
|
||||
#define ENABLE_LFOS 0x02 /* SGMI[1]*/
|
||||
#define NO_WAVETABLE 0x04 /* SGMI[2]*/
|
||||
#define RAM_TEST 0x08 /* SGMI[3]*/
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define ON 1
|
||||
#define OFF 0
|
||||
#define AUDIO 0
|
||||
#define EXT 1
|
||||
#define GAME 2
|
||||
#define EMULATION 3
|
||||
#define MPU401 4
|
||||
#define AUDIO_EXT 2
|
||||
#define ALLOC_FAILURE 0xFFFFFFFFL
|
||||
#define MEM_EXHAUSTED 0xFFFFFFFFL
|
||||
#define RAM_MAX 16777216L
|
||||
#define RAM_STEP 65536L
|
||||
#define BANK_MAX 4194304L
|
||||
#define ILLEGAL_SIZE -1
|
||||
#define MEM_INIT 1
|
||||
#define NO_NEXT 0xFFFFFFFFL
|
||||
#define NO_PREV NO_NEXT
|
||||
#define DMA_BAD_ADDR -1
|
||||
#define DMA_ON -1
|
||||
#define DMA_OK 1
|
||||
#define MIDI_TX_IRQ 0x01
|
||||
#define MIDI_RX_IRQ 0x02
|
||||
#define ALIB_TIMER1_IRQ 0x04
|
||||
#define ALIB_TIMER2_IRQ 0x08
|
||||
#define WAVETABLE_IRQ 0x20
|
||||
#define ENVELOPE_IRQ 0x40
|
||||
#define DMA_TC_IRQ 0x80
|
||||
#define DMA_SET_MASK 0x04
|
||||
#define PNP_DATA_RDY 1 /* PRESSI[0] */
|
||||
#define IWAVE_ABSENT 2
|
||||
#define IWAVE_OPEN 4
|
||||
#define IWAVE_OK 5
|
||||
#define BAD_VOICES -1
|
||||
#define PNP_ABSENT 0xFF /* No PNP cards in system */
|
||||
#define DPMI_INT 0x31
|
||||
#define _PCCCI 0x02
|
||||
#define _PCSNI 0x06
|
||||
#define _PIDXR 0x279
|
||||
#define _PNPWRP 0xA79
|
||||
#define _LDSALI 0x42
|
||||
#define _LDSAHI 0x50
|
||||
#define _LMALI 0x43
|
||||
#define _LMAHI 0x44
|
||||
#define _LMCFI 0x52
|
||||
#define _LMCI 0x53
|
||||
#define _LDIBI 0x58
|
||||
#define _LDICI 0x57
|
||||
#define _LMSBAI 0x51
|
||||
#define _SVCI_RD 0x8D
|
||||
#define _SVCI_WR 0x0D
|
||||
#define _SACI_RD 0x80
|
||||
#define _SACI_WR 0x00
|
||||
#define _SALI_RD 0x8B
|
||||
#define _SALI_WR 0x0B
|
||||
#define _SAHI_RD 0x8A
|
||||
#define _SAHI_WR 0x0A
|
||||
#define _SASHI_RD 0x82
|
||||
#define _SASHI_WR 0x02
|
||||
#define _SASLI_RD 0x83
|
||||
#define _SASLI_WR 0x03
|
||||
#define _SAEHI_RD 0x84
|
||||
#define _SAEHI_WR 0x04
|
||||
#define _SAELI_RD 0x85
|
||||
#define _SAELI_WR 0x05
|
||||
#define _SVRI_RD 0x86
|
||||
#define _SVRI_WR 0x06
|
||||
#define _SVSI_RD 0x87
|
||||
#define _SVSI_WR 0x07
|
||||
#define _SVEI_RD 0x88
|
||||
#define _SVEI_WR 0x08
|
||||
#define _SVLI_RD 0x89
|
||||
#define _SVLI_WR 0x09
|
||||
#define _SROI_RD 0x8C
|
||||
#define _SROI_WR 0x0C
|
||||
#define _SLOI_RD 0x93
|
||||
#define _SLOI_WR 0x13
|
||||
#define _SMSI_RD 0x95
|
||||
#define _SMSI_WR 0x15
|
||||
#define _SGMI_RD 0x99
|
||||
#define _SGMI_WR 0x19
|
||||
#define _SFCI_RD 0x81
|
||||
#define _SFCI_WR 0x01
|
||||
#define _SUAI_RD 0x90
|
||||
#define _SUAI_WR 0x10
|
||||
#define _SVII 0x8F
|
||||
#define _CMODEI 0x0C /* index for CMODEI */
|
||||
#define _CFIG3I 0x11
|
||||
#define _CFIG2I 0x10
|
||||
#define _CLTIMI 0x14
|
||||
#define _CUTIMI 0x15
|
||||
#define _CSR3I 0x18 /* Index to CSR3I (Interrupt Status) */
|
||||
#define _CEXTI 0x0A /* Index to External Control Register */
|
||||
#define _CFIG1I 0x09 /* Index to Codec Conf Reg 1 */
|
||||
#define _CSR2I 0x0B /* Index to Codec Stat Reg 2 */
|
||||
#define _CPDFI 0x08 /* Index to Play Data Format Reg */
|
||||
#define _CRDFI 0x1C /* Index to Rec Data Format Reg */
|
||||
#define _CLMICI 0x16 /* Index to Left Mic Input Ctrl Register */
|
||||
#define _CRMICI 0x17 /* Index to Right Mic Input Ctrl Register */
|
||||
#define _CLCI 0x0D /* Index to Loopback Ctrl Register */
|
||||
#define _IVERI 0x5B /* Index to register IVERI */
|
||||
#define CODEC_MODE1 0x00
|
||||
#define CODEC_MODE2 0x40
|
||||
#define CODEC_MODE3 0x6C /* Enhanced Mode */
|
||||
#define CODEC_STATUS1 0x01
|
||||
#define CODEC_STATUS2 0x0B /* Index to CSR2I */
|
||||
#define CODEC_STATUS3 0x18 /* Index to CSR3I */
|
||||
#define PLAYBACK 0x01 /* Enable playback path CFIG1I[0]=1*/
|
||||
#define RECORD 0x02 /* Enable Record path CFIG1I[1]=1*/
|
||||
#define TIMER_ENABLE 0x40 /* CFIG2I[6] */
|
||||
#define CODEC_MCE 0x40 /* CIDXR[6] */
|
||||
#define CALIB_IN_PROGRESS 0x20 /* CSR2I[5] */
|
||||
#define CODEC_INIT 0x80 /* CIDXR[7] */
|
||||
#define BIT16_BIG 0xC0 /* 16-bit signed, big endian */
|
||||
#define IMA_ADPCM 0xA0 /* IMA-compliant ADPCM */
|
||||
#define BIT8_ALAW 0x60 /* 8-bit A-law */
|
||||
#define BIT16_LITTLE 0x40 /* 16-bit signed, lillte endian */
|
||||
#define BIT8_ULAW 0x20 /* 8-bit u-law */
|
||||
#define BIT8_LINEAR 0x00 /* 8-bit unsigned */
|
||||
#define REC_DFORMAT 0x1C
|
||||
#define PLAY_DFORMAT 0x08
|
||||
#define DMA_ACCESS 0x00
|
||||
#define PIO_ACCESS 0xC0
|
||||
#define DMA_SIMPLEX 0x04
|
||||
#define STEREO 0x10 /* CxDFI[4] */
|
||||
#define XTAL1 0x00 /* CxDFI[4]=0 selects 24.5Mhz XTAL */
|
||||
#define XTAL2 0x01 /* CxDFI[4]=1 selects 16.9Mhz XTAL */
|
||||
#define AUTOCALIB 0x08 /* CFIG1I[3] */
|
||||
#define ROM_IO 0x02 /* ROM I/O cycles - LMCI[1]=1 */
|
||||
#define DRAM_IO 0x4D /* DRAM I/O cycles - LMCI[1]=0 */
|
||||
#define AUTOI 0x01 /* LMCI[0]=1 */
|
||||
#define _PLDNI 0x07
|
||||
#define ACTIVATE_DEV 0x30
|
||||
#define _PWAKEI 0x03 /* Index for PWAKEI */
|
||||
#define _PISOCI 0x01 /* Index for PISOCI */
|
||||
#define _PSECI 0xF1 /* Index for PSECI */
|
||||
#define RANGE_IOCHK 0x31 /* PURCI or PRRCI Index */
|
||||
#define MIDI_RESET 0x03
|
||||
#define IO_OK 5 /* No IO conflict flag */
|
||||
#define IO_CONFLICT 6 /* IO Conflict detected */
|
||||
#define IO_0x55 0x01
|
||||
#define IO_0xAA 0xFE
|
||||
/*#######################################################################*/
|
||||
/**/
|
||||
/* Defines for Sound Handlers in "iw".*/
|
||||
/**/
|
||||
/*#######################################################################*/
|
||||
#define PLAY_DMA_HANDLER 0x01
|
||||
#define REC_DMA_HANDLER 0x02
|
||||
#define MIDI_TX_HANDLER 0x03
|
||||
#define MIDI_RX_HANDLER 0x04
|
||||
#define TIMER1_HANDLER 0x05
|
||||
#define TIMER2_HANDLER 0x06
|
||||
#define WAVE_HANDLER 0x07
|
||||
#define VOLUME_HANDLER 0x08
|
||||
#define CODEC_TIMER_HANDLER 0x09
|
||||
#define CODEC_PLAY_HANDLER 0x0A
|
||||
#define CODEC_REC_HANDLER 0x0B
|
||||
#define AUX_HANDLER 0x0C
|
||||
/*#######################################################################*/
|
||||
/**/
|
||||
/* Mapping for System Control Regs.*/
|
||||
/**/
|
||||
/*#######################################################################*/
|
||||
#define UMCR 0x00010000 /* Mix Control Reg.*/
|
||||
#define UISR 0x00020006 /* IRQ Stat Reg. (read) */
|
||||
#define U2X6R 0x00030006 /* SB 2X6 reg */
|
||||
#define UACWR 0x00040008 /* AdLib Command Write Reg */
|
||||
#define UASRR 0x00050008 /* AdLib Stat Read Reg */
|
||||
#define UADR 0x00060009 /* AdLib Data Register */
|
||||
#define UACRR 0x0007000A /* AdLib Cmd Read Reg */
|
||||
#define UASWR 0x0008000A /* AdLib Stat Write Reg */
|
||||
#define UHRDP 0x0009000B /* Hidden Reg Data Port */
|
||||
#define UI2XCR 0x000A000C /* SB IRQ 2xC Reg */
|
||||
#define U2XCR 0x000B000D /* SB 2xC Reg. (No IRQ) */
|
||||
#define U2XER 0x000C000E /* SB 2xE Reg. */
|
||||
#define URCR 0x000D000F /* Reg Control Register */
|
||||
#define USRR 0x000E000F /* Status Read Register */
|
||||
#define UDCI 0x000F000B /* DMA Channel Control Reg */
|
||||
#define UICI 0x0010000B /* Interrupt Ctrl Reg */
|
||||
#define UGP1I 0x0011010B /* GP Reg 1 (Back Door) */
|
||||
#define UGP2I 0x0012020B /* GP Reg 2 (Back Door) */
|
||||
#define UGPA1I 0x0013030B /* GP reg 1 Address */
|
||||
#define UGPA2I 0x0014040B /* GP reg 2 Address */
|
||||
#define UCLRII 0x0015050B /* Clear Interrupt Reg */
|
||||
#define UJMPI 0x0016060B /* Jumper Register */
|
||||
#define UGP1II 0x0017000B /* Gen. Purp Reg 1(Emulation) */
|
||||
#define UGP2II 0x0018000B /* Gen. Purp Reg 2(Emulation) */
|
||||
#define GGCR 0x00190201 /* Game Control Register */
|
||||
#define GMCR 0x001A0000 /* MIDI Control Register */
|
||||
#define GMSR 0x001B0000 /* MIDI Status Reg. */
|
||||
#define GMTDR 0x001C0001 /* MIDI xmit data reg */
|
||||
#define GMRDR 0x001D0001 /* MIDI rcv data reg */
|
||||
#define SVSR 0x001E0002 /* Synth Voice Select Reg */
|
||||
#define IGIDXR 0x001F0003 /* General Index Register */
|
||||
#define I16DP 0x00200004 /* General 16-bit Data Port */
|
||||
#define I8DP 0x00210005 /* General 8-bit Data Port */
|
||||
/*#######################################################################*/
|
||||
/**/
|
||||
/* Synth defines*/
|
||||
/**/
|
||||
/*#######################################################################*/
|
||||
#define SACI 0x00220005 /* Synth Addr Control */
|
||||
#define SFCI 0x00230104 /* Synth Freq Control */
|
||||
#define SASHI 0x00240204 /* Synth Addr Start High */
|
||||
#define SASLI 0x00250304 /* Synth Addr Start Low */
|
||||
#define SAEHI 0x00260404 /* Synth Addr End High */
|
||||
#define SAELI 0x00270504 /* Synth Addr End Low */
|
||||
#define SVRI 0x00280605 /* Synth Volume Rate */
|
||||
#define SVSI 0x00290705 /* Synth Volume Start */
|
||||
#define SVEI 0x002A0805 /* Synth Volume End */
|
||||
#define SVLI 0x002B0904 /* Synth Volume Level */
|
||||
#define SAHI 0x002C0A04 /* Synth Address High */
|
||||
#define SALI 0x002D0B04 /* Synth Address Low */
|
||||
#define SROI 0x002E0C04 /* Synth Right Offset */
|
||||
#define SVCI 0x002F0D05 /* Synth Volume Control */
|
||||
#define SAVI 0x00300E05 /* Synth Active Voices */
|
||||
#define SVII 0x00318F05 /* Synth Voice IRQ */
|
||||
#define SUAI 0x00321005 /* Synth Upper Addr */
|
||||
#define SEAHI 0x00331104 /* Synth Effect Addr High */
|
||||
#define SEALI 0x00341204 /* Synth Effect Addr Low */
|
||||
#define SLOI 0x00351304 /* Synth Left Offset */
|
||||
#define SEASI 0x00361405 /* Synth Effects Accum Sel */
|
||||
#define SMSI 0x00371505 /* Synth Mode Select */
|
||||
#define SEVI 0x00381604 /* Synth Effect Volume */
|
||||
#define SFLFOI 0x00391705 /* Synth Freq LFO */
|
||||
#define SVLFOI 0x003A1805 /* Synth Vol LFO */
|
||||
#define SGMI 0x003B1905 /* Synth Global Mode */
|
||||
#define SLFOBI 0x003C1A04 /* Synth LFO Base Address */
|
||||
#define SROFI 0x003D1B04
|
||||
#define SLOFI 0x003E1C04
|
||||
#define SEVFI 0x003F1D04
|
||||
#define SVIRI 0x00409F05 /* Synth Voice Read IRQ */
|
||||
#define LDMACI 0x00414105 /* DMA Control Reg. */
|
||||
#define LDSALI 0x00424204 /* LMC DMA Start Addr. Low Reg. */
|
||||
#define LMALI 0x00434304 /* LMC Addr Low (I/O) */
|
||||
#define LMAHI 0x00444405 /* LMC Addr High (I/O) */
|
||||
#define UASBCI 0x00454505 /* Adlib-SB Control */
|
||||
#define UAT1I 0x00464605 /* AdLib Timer 1 Count */
|
||||
#define UAT2I 0x00474705 /* AdLib Timer 2 Count */
|
||||
#define USCI 0x00484905 /* Sample Control Reg */
|
||||
#define GJTDI 0x00494B05
|
||||
#define URSTI 0x004A4C05
|
||||
#define LDSAHI 0x004B5005
|
||||
#define LMSBAI 0x004C5104
|
||||
#define LMCFI 0x004D5204
|
||||
#define LMCI 0x004E5305
|
||||
#define LMRFAI 0x004F5404
|
||||
#define LMPFAI 0x00505504
|
||||
#define LMSFI 0x00515604
|
||||
#define LDICI 0x00525704
|
||||
#define LDIBI 0x00535804
|
||||
#define ICMPTI 0x00545905
|
||||
#define IDECI 0x00555A05
|
||||
#define IVERI 0x00565B05
|
||||
#define IEMUAI 0x00575C05
|
||||
#define IEMUBI 0x00585D05
|
||||
#define GMRFAI 0x00595E05
|
||||
#define ITCI 0x005A5F05
|
||||
#define IEIRQI 0x005B6005
|
||||
#define LMBDR 0x005C0007
|
||||
/*##########################################################*/
|
||||
/* Mnemonics for Codec Registers*/
|
||||
/*##########################################################*/
|
||||
#define CIDXR 0x005D0000
|
||||
#define CDATAP 0x005E0001
|
||||
#define CSR1R 0x005F0002
|
||||
#define CPDR 0x00600003
|
||||
#define CRDR 0x00610003
|
||||
#define CLICI 0x00620001
|
||||
#define CRICI 0x00630101
|
||||
#define CLAX1I 0x00640201
|
||||
#define CRAX1I 0x00650301
|
||||
#define CLAX2I 0x00660401
|
||||
#define CRAX2I 0x00670501
|
||||
#define CLDACI 0x00680601
|
||||
#define CRDACI 0x00690701
|
||||
#define CPDFI 0x006A0801
|
||||
#define CFIG1I 0x006B0901
|
||||
#define CEXTI 0x006C0A01
|
||||
#define CSR2I 0x006D0B01
|
||||
#define CMODEI 0x006E0C01
|
||||
#define CLCI 0x006F0D01
|
||||
#define CUPCTI 0x00700E01
|
||||
#define CLPCTI 0x00710F01
|
||||
#define CFIG2I 0x00721001
|
||||
#define CFIG3I 0x00731101
|
||||
#define CLLICI 0x00741201
|
||||
#define CRLICI 0x00751301
|
||||
#define CLTIMI 0x00761401
|
||||
#define CUTIMI 0x00771501
|
||||
#define CLMICI 0x00781601
|
||||
#define CRMICI 0x00791701
|
||||
#define CSR3I 0x007A1801
|
||||
#define CLOAI 0x007B1901
|
||||
#define CMONOI 0x007C1A01
|
||||
#define CROAI 0x007D1B01
|
||||
#define CRDFI 0x007E1C01
|
||||
#define CPVFI 0x007F1D01
|
||||
#define CURCTI 0x00801E01
|
||||
#define CLRCTI 0x00811F01
|
||||
/*##########################################################*/
|
||||
/* Mnemonics for PnP Registers*/
|
||||
/*##########################################################*/
|
||||
#define PCSNBR 0x00820201
|
||||
#define PIDXR 0x00830279
|
||||
#define PNPWRP 0x00840A79
|
||||
#define PNPRDP 0x00850000
|
||||
#define PSRPAI 0x00860000
|
||||
#define PISOCI 0x00870100
|
||||
#define PCCCI 0x00880200
|
||||
#define PWAKEI 0x00890300
|
||||
#define PRESDI 0x008A0400
|
||||
#define PRESSI 0x008B0500
|
||||
#define PCSNI 0x008C0600
|
||||
#define PLDNI 0x008D0700
|
||||
#define PUACTI 0x008E3000
|
||||
#define PURCI 0x008F3100
|
||||
#define P2X0HI 0x00906000
|
||||
#define P2X0LI 0x00916100
|
||||
#define P3X0HI 0x00926200
|
||||
#define P3X0LI 0x00936300
|
||||
#define PHCAI 0x00946400
|
||||
#define PLCAI 0x00956500
|
||||
#define PUI1SI 0x00967000
|
||||
#define PUI1TI 0x00977100
|
||||
#define PUI2SI 0x00987200
|
||||
#define PUI2TI 0x00997300
|
||||
#define PUD1SI 0x009A7400
|
||||
#define PUD2SI 0x009B7500
|
||||
#define PSEENI 0x009CF000
|
||||
#define PSECI 0x009DF100
|
||||
#define PPWRI 0x009EF200
|
||||
#define PRACTI 0x009F3001
|
||||
#define PRRCI 0x00A03101
|
||||
#define PRAHI 0x00A16001
|
||||
#define PRALI 0x00A26101
|
||||
#define PATAHI 0x00A36201
|
||||
#define PATALI 0x00A46301
|
||||
#define PRISI 0x00A57001
|
||||
#define PRITI 0x00A67101
|
||||
#define PRDSI 0x00A77401
|
||||
#define PGACTI 0x00A83002
|
||||
#define PGRCI 0x00A93102
|
||||
#define P201HI 0x00AA6002
|
||||
#define P201LI 0x00AB6102
|
||||
#define PSACTI 0x00AC3003
|
||||
#define PSRCI 0x00AD3103
|
||||
#define P388HI 0x00AE6003
|
||||
#define P388LI 0x00AF6103
|
||||
#define PSBISI 0x00B07003
|
||||
#define PSBITI 0x00B17103
|
||||
#define PMACTI 0x00B23004
|
||||
#define PMRCI 0x00B33104
|
||||
#define P401HI 0x00B46004
|
||||
#define P401LI 0x00B56104
|
||||
#define PMISI 0x00B67004
|
||||
#define PMITI 0x00B77104
|
||||
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short PORT;
|
||||
typedef unsigned long DWORD;
|
||||
typedef unsigned long ADDRESS;
|
||||
typedef int BOOL;
|
||||
typedef int FLAG;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short flags; /* InterWave stat flags */
|
||||
PORT pcodar; /* Base Port for Codec */
|
||||
PORT pcdrar; /* Base Port for Ext Device */
|
||||
PORT p2xr; /* Compatibility Base Port */
|
||||
PORT p3xr; /* MIDI and Synth Base Port */
|
||||
PORT p401ar; /* Gen Purpose Reg. 1 address */
|
||||
PORT p201ar; /* Game Ctrl normally at 0x201 */
|
||||
PORT pataar; /* Base Address for ATAPI I/O Space */
|
||||
PORT p388ar; /* Base Port for AdLib. It should be 388h */
|
||||
PORT pnprdp; /* PNP read data port */
|
||||
PORT igidxr; /* Gen Index Reg at P3XR+0x03 */
|
||||
PORT i16dp; /* 16-bit data port at P3XR+0x04 */
|
||||
PORT i8dp; /* 8-bit data port at P3XR+0x05 */
|
||||
PORT svsr; /* Synth Voice Select at P3XR+0x02 */
|
||||
PORT cdatap; /* Codec Indexed Data Port at PCODAR+0x01 */
|
||||
PORT csr1r; /* Codec Stat Reg 1 at PCODAR+0x02 */
|
||||
PORT cxdr; /* Play or Record Data Reg at PCODAR+0x03 */
|
||||
PORT gmxr; /* GMCR or GMSR at P3XR+0x00 */
|
||||
PORT gmxdr; /* GMTDR or GMRDR at P3XR+0x01 */
|
||||
PORT lmbdr; /* LMBDR at P3XR+0x07 */
|
||||
BYTE csn; /* Card Select Number */
|
||||
BYTE cmode; /* Codec Operation Mode */
|
||||
int dma1_chan; /* DMA channel 1 (local DMA & codec rec) */
|
||||
int dma2_chan; /* DMA channel 2 (codec play) */
|
||||
int ext_chan; /* Ext Dev DMA channel */
|
||||
BYTE voices; /* Number of active voices */
|
||||
DWORD vendor; /* Vendor ID and Product Identifier */
|
||||
int synth_irq; /* Synth IRQ number */
|
||||
int midi_irq; /* MIDI IRQ number */
|
||||
int ext_irq; /* Ext Dev IRQ */
|
||||
int mpu_irq; /* MPU401 Dev IRQ */
|
||||
int emul_irq; /* Sound Blaster/AdLib Dev IRQ */
|
||||
ADDRESS free_mem; /* Address of First Free LM Block */
|
||||
DWORD reserved_mem; /* Amount of LM reserved by app. */
|
||||
BYTE smode; /* Synth Mode */
|
||||
WORD size_mem; /* Total LM in Kbytes */
|
||||
|
||||
} IWAVE;
|
||||
|
||||
#endif
|
@ -1,195 +0,0 @@
|
||||
/*
|
||||
* local.h
|
||||
*
|
||||
* This file was generated by configure. But then HAND-EDITED. It will
|
||||
* probably disappear in future revisions once the configuration process
|
||||
* will become more like that of standard bsd code.
|
||||
* lr 970714
|
||||
*
|
||||
*/
|
||||
|
||||
/* build hex2hex /tmp/foo.x trix_boot.h trix_boot */
|
||||
|
||||
/*
|
||||
* make everything conditioned on NSND>0 so as to detect errors
|
||||
* because of missing "controller snd0" statement
|
||||
*/
|
||||
#define ALLOW_BUFFER_MAPPING 1
|
||||
|
||||
#include "snd.h"
|
||||
#if NSND > 0
|
||||
|
||||
#include "opt_sound.h"
|
||||
|
||||
#define CONFIGURE_SOUNDCARD
|
||||
|
||||
#define CONFIG_SEQUENCER
|
||||
|
||||
#include "gus.h"
|
||||
#if NGUS != 0 && !defined(CONFIG_GUS)
|
||||
#define CONFIG_GUS
|
||||
#define CONFIG_GUSMAX
|
||||
#endif
|
||||
|
||||
#include "sscape.h"
|
||||
#if NSSCAPE != 0 && !defined(CONFIG_SSCAPE)
|
||||
#define CONFIG_SSCAPE
|
||||
#endif
|
||||
|
||||
#include "trix.h"
|
||||
#if NTRIX > 0
|
||||
#define INCLUDE_TRIX_BOOT
|
||||
#define CONFIG_TRIX /* can use NTRIX > 0 instead */
|
||||
#define CONFIG_YM3812
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_GUSMAX) || ( NSSCAPE > 0 ) || ( NTRIX > 0 )
|
||||
#define CONFIG_AD1848
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SEQUENCER) && (NTRIX == 0)
|
||||
#define CONFIG_MIDI
|
||||
#endif
|
||||
|
||||
#include "sb.h"
|
||||
#if NSB > 0
|
||||
#define CONFIG_SB
|
||||
#endif
|
||||
|
||||
#include "mss.h"
|
||||
#if NMSS != 0
|
||||
#define CONFIG_AD1848
|
||||
#define CONFIG_MSS
|
||||
#undef CONFIG_CS4232
|
||||
#endif
|
||||
|
||||
#include "css.h"
|
||||
#if NCSS != 0
|
||||
#define CONFIG_AD1848
|
||||
#undef CONFIG_MSS
|
||||
#define CONFIG_CS4232
|
||||
#endif
|
||||
|
||||
#include "sbxvi.h"
|
||||
#if NSBXVI != 0 && !defined(CONFIG_SB16)
|
||||
#define CONFIG_SB16
|
||||
#define CONFIG_SBPRO /* FIXME: Also needs to be a sep option */
|
||||
#endif
|
||||
|
||||
#include "sbmidi.h"
|
||||
#if NSBMIDI != 0 && !defined(CONFIG_SB16MIDI)
|
||||
#define CONFIG_SB16MIDI
|
||||
#endif
|
||||
|
||||
#include "awe.h"
|
||||
#if NAWE != 0 && !defined(CONFIG_AWE32)
|
||||
#define CONFIG_AWE32
|
||||
#endif
|
||||
|
||||
#include "pas.h"
|
||||
#if NPAS != 0 && !defined(CONFIG_PAS)
|
||||
#define CONFIG_PAS
|
||||
#endif
|
||||
|
||||
#include "mpu.h"
|
||||
#if NMPU != 0 && !defined(CONFIG_MPU401)
|
||||
#define CONFIG_MPU401
|
||||
#endif
|
||||
|
||||
#include "opl.h"
|
||||
#if NOPL != 0 && !defined(CONFIG_YM3812)
|
||||
#define CONFIG_YM3812
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
#include "nss.h"
|
||||
#if NNSS != 0
|
||||
#define CONFIG_NSS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define ALLOW_POLL
|
||||
|
||||
/* #undef CONFIG_PAS */
|
||||
/* #undef CONFIG_ADLIB */
|
||||
/* #define CONFIG_GUS */
|
||||
/* #undef CONFIG_MPU401 */
|
||||
#undef CONFIG_UART6850
|
||||
#undef CONFIG_PSS
|
||||
#undef CONFIG_GUS16
|
||||
/* #undef CONFIG_MSS */
|
||||
/* #undef CONFIG_SSCAPE */
|
||||
#undef CONFIG_MAD16
|
||||
/* #undef CONFIG_CS4232 */
|
||||
#undef CONFIG_MAUI
|
||||
#undef CONFIG_PNP
|
||||
/* #undef CONFIG_SBPRO */
|
||||
/* #undef CONFIG_SB16 */
|
||||
#undef CONFIG_AEDSP16
|
||||
#define CONFIG_AUDIO /* obvious ? */
|
||||
|
||||
#define CONFIG_MPU_EMU
|
||||
|
||||
#ifdef PC98
|
||||
#define DSP_BUFFSIZE 61440
|
||||
#else
|
||||
#define DSP_BUFFSIZE 32768*2
|
||||
#endif
|
||||
/* #define SELECTED_SOUND_OPTIONS 0x0188090a */
|
||||
|
||||
#ifndef TRIX_SB_BASE
|
||||
#define TRIX_SB_BASE 0x220
|
||||
#endif
|
||||
|
||||
#ifndef TRIX_SB_IRQ
|
||||
#define TRIX_SB_IRQ 7
|
||||
#endif
|
||||
|
||||
#ifndef TRIX_SB_DMA
|
||||
#define TRIX_SB_DMA 1
|
||||
#endif
|
||||
|
||||
#ifndef TRIX_BASE
|
||||
#define TRIX_BASE 0x530
|
||||
#endif
|
||||
|
||||
#ifndef TRIX_IRQ
|
||||
#define TRIX_IRQ 9
|
||||
#endif
|
||||
|
||||
#ifndef TRIX_DMA
|
||||
#define TRIX_DMA 3
|
||||
#endif
|
||||
|
||||
#ifndef TRIX_DMA2
|
||||
#define TRIX_DMA2 1
|
||||
#endif
|
||||
|
||||
#ifndef GUS_BASE
|
||||
#define GUS_BASE 0x220
|
||||
#endif
|
||||
|
||||
#ifndef GUS_IRQ
|
||||
#define GUS_IRQ 12
|
||||
#endif
|
||||
|
||||
#ifndef GUS_MIDI_IRQ
|
||||
#define GUS_MIDI_IRQ GUS_IRQ
|
||||
#endif
|
||||
|
||||
#ifndef GUS_DMA
|
||||
#define GUS_DMA 4
|
||||
#endif
|
||||
|
||||
#ifndef GUS_DMA2
|
||||
#define GUS_DMA2 4
|
||||
#endif
|
||||
|
||||
#define SOUND_CONFIG_DATE "Wed Aug 6 22:58:35 PDT 1997"
|
||||
#define SOUND_CONFIG_BY "Amancio Hasty"
|
||||
#define SOUND_CONFIG_HOST "rah"
|
||||
#define SOUND_CONFIG_DOMAIN "star-gate.com"
|
||||
|
||||
#else /* NSND = 0 */
|
||||
#undef CONFIGURE_SOUNDCARD
|
||||
#endif
|
@ -1,524 +0,0 @@
|
||||
/*
|
||||
* sound/mad16.c
|
||||
*
|
||||
* Initialization code for OPTi MAD16 compatible audio chips. Including
|
||||
*
|
||||
* OPTi 82C928 MAD16 (replaced by C929) OAK OTI-601D Mozart
|
||||
* OPTi 82C929 MAD16 Pro
|
||||
*
|
||||
* These audio interface chips don't prduce sound themselves. They just connect
|
||||
* some other components (OPL-[234] and a WSS compatible codec) to the PC bus
|
||||
* and perform I/O, DMA and IRQ address decoding. There is also a UART for
|
||||
* the MPU-401 mode (not 82C928/Mozart). The Mozart chip appears to be
|
||||
* compatible with the 82C928 (can anybody confirm this?).
|
||||
*
|
||||
* NOTE! If you want to set CD-ROM address and/or joystick enable, define
|
||||
* MAD16_CONF in local.h as combination of the following bits:
|
||||
*
|
||||
* 0x01 - joystick disabled
|
||||
*
|
||||
* CD-ROM type selection (select just one): 0x00 - none 0x02 - Sony 31A
|
||||
* 0x04 - Mitsumi 0x06 - Panasonic (type "LaserMate", not
|
||||
* "SoundBlaster") 0x08 - Secondary IDE (address 0x170) 0x0a - Primary
|
||||
* IDE (address 0x1F0)
|
||||
*
|
||||
* For example Mitsumi with joystick disabled = 0x04|0x01 = 0x05 For example
|
||||
* LaserMate (for use with sbpcd) plus joystick = 0x06
|
||||
*
|
||||
* MAD16_CDSEL: This defaults to CD I/O 0x340, no IRQ and DMA3 (DMA5 with
|
||||
* Mitsumi or IDE). If you like to change these, define MAD16_CDSEL with the
|
||||
* following bits:
|
||||
*
|
||||
* CD-ROM port: 0x00=340, 0x40=330, 0x80=360 or 0xc0=320 OPL4 select: 0x20=OPL4,
|
||||
* 0x00=OPL3 CD-ROM irq: 0x00=disabled, 0x04=IRQ5, 0x08=IRQ7, 0x0a=IRQ3,
|
||||
* 0x10=IRQ9, 0x14=IRQ10 and 0x18=IRQ11.
|
||||
*
|
||||
* CD-ROM DMA (Sony or Panasonic): 0x00=DMA3, 0x01=DMA2, 0x02=DMA1 or
|
||||
* 0x03=disabled or CD-ROM DMA (Mitsumi or IDE): 0x00=DMA5, 0x01=DMA6,
|
||||
* 0x02=DMA7 or 0x03=disabled
|
||||
*
|
||||
* For use with sbpcd, address 0x340, set MAD16_CDSEL to 0x03 or 0x23.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1995
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if defined(CONFIG_MAD16)
|
||||
|
||||
static int already_initialized = 0;
|
||||
|
||||
#define C928 1
|
||||
#define MOZART 2
|
||||
#define C929 3
|
||||
|
||||
/*
|
||||
* Registers
|
||||
*
|
||||
* The MAD16 occupies I/O ports 0xf8d to 0xf93 (fixed locations). All ports are
|
||||
* inactive by default. They can be activated by writing 0xE2 or 0xE3 to the
|
||||
* password register. The password is valid only until the next I/O read or
|
||||
* write.
|
||||
*/
|
||||
|
||||
#define MC1_PORT 0xf8d /* SB address, CDROM interface type, joystick */
|
||||
#define MC2_PORT 0xf8e /* CDROM address, IRQ, DMA, plus OPL4 bit */
|
||||
#define MC3_PORT 0xf8f
|
||||
#define PASSWD_REG 0xf8f
|
||||
#define MC4_PORT 0xf90
|
||||
#define MC5_PORT 0xf91
|
||||
#define MC6_PORT 0xf92
|
||||
#define MC7_PORT 0xf93
|
||||
|
||||
static int board_type = C928;
|
||||
|
||||
static sound_os_info *mad16_osp;
|
||||
|
||||
#ifndef DDB
|
||||
#define DDB(x)
|
||||
#endif
|
||||
|
||||
static unsigned char
|
||||
mad_read(int port)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned char tmp;
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
switch (board_type) { /* Output password */
|
||||
case C928:
|
||||
case MOZART:
|
||||
outb(PASSWD_REG, 0xE2);
|
||||
break;
|
||||
|
||||
case C929:
|
||||
outb(PASSWD_REG, 0xE3);
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = inb(port);
|
||||
splx(flags);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static void
|
||||
mad_write(int port, int value)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
switch (board_type) { /* Output password */
|
||||
case C928:
|
||||
case MOZART:
|
||||
outb(PASSWD_REG, 0xE2);
|
||||
break;
|
||||
|
||||
case C929:
|
||||
outb(PASSWD_REG, 0xE3);
|
||||
break;
|
||||
}
|
||||
|
||||
outb(port, (unsigned char) (value & 0xff));
|
||||
splx(flags);
|
||||
}
|
||||
|
||||
static int
|
||||
detect_mad16(void)
|
||||
{
|
||||
unsigned char tmp, tmp2;
|
||||
|
||||
/*
|
||||
* Check that reading a register doesn't return bus float (0xff) when
|
||||
* the card is accessed using password. This may fail in case the
|
||||
* card is in low power mode. Normally at least the power saving mode
|
||||
* bit should be 0.
|
||||
*/
|
||||
if ((tmp = mad_read(MC1_PORT)) == 0xff) {
|
||||
DDB(printf("MC1_PORT returned 0xff\n"));
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Now check that the gate is closed on first I/O after writing the
|
||||
* password. (This is how a MAD16 compatible card works).
|
||||
*/
|
||||
|
||||
if ((tmp2 = inb(MC1_PORT)) == tmp) { /* It didn't close */
|
||||
DDB(printf("MC1_PORT didn't close after read (0x%02x)\n", tmp2));
|
||||
return 0;
|
||||
}
|
||||
mad_write(MC1_PORT, tmp ^ 0x80); /* Togge a bit */
|
||||
|
||||
if ((tmp2 = mad_read(MC1_PORT)) != (tmp ^ 0x80)) { /* Compare the bit */
|
||||
mad_write(MC1_PORT, tmp); /* Restore */
|
||||
DDB(printf("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2));
|
||||
return 0;
|
||||
}
|
||||
mad_write(MC1_PORT, tmp); /* Restore */
|
||||
return 1; /* Bingo */
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
probe_mad16(struct address_info * hw_config)
|
||||
{
|
||||
int i;
|
||||
static int valid_ports[] =
|
||||
{0x530, 0xe80, 0xf40, 0x604};
|
||||
unsigned char tmp;
|
||||
unsigned char cs4231_mode = 0;
|
||||
|
||||
int ad_flags = 0;
|
||||
|
||||
if (already_initialized)
|
||||
return 0;
|
||||
|
||||
mad16_osp = hw_config->osp;
|
||||
/*
|
||||
* Check that all ports return 0xff (bus float) when no password is
|
||||
* written to the password register.
|
||||
*/
|
||||
|
||||
DDB(printf("--- Detecting MAD16 / Mozart ---\n"));
|
||||
|
||||
|
||||
/*
|
||||
* Then try to detect with the old password
|
||||
*/
|
||||
board_type = C928;
|
||||
|
||||
DDB(printf("Detect using password = 0xE2\n"));
|
||||
|
||||
if (!detect_mad16()) { /* No luck. Try different model */
|
||||
board_type = C929;
|
||||
|
||||
DDB(printf("Detect using password = 0xE3\n"));
|
||||
|
||||
if (!detect_mad16())
|
||||
return 0;
|
||||
|
||||
DDB(printf("mad16.c: 82C929 detected\n"));
|
||||
} else {
|
||||
unsigned char model;
|
||||
|
||||
if (((model = mad_read(MC3_PORT)) & 0x03) == 0x03) {
|
||||
DDB(printf("mad16.c: Mozart detected\n"));
|
||||
board_type = MOZART;
|
||||
} else {
|
||||
DDB(printf("mad16.c: 82C928 detected???\n"));
|
||||
board_type = C928;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0xf8d; i <= 0xf93; i++)
|
||||
DDB(printf("port %03x = %03x\n", i, mad_read(i)));
|
||||
|
||||
/*
|
||||
* Set the WSS address
|
||||
*/
|
||||
|
||||
tmp = 0x80; /* Enable WSS, Disable SB */
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (i > 3) { /* Not a valid port */
|
||||
printf("MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base);
|
||||
return 0;
|
||||
}
|
||||
if (valid_ports[i] == hw_config->io_base) {
|
||||
tmp |= i << 4; /* WSS port select bits */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set optional CD-ROM and joystick settings.
|
||||
*/
|
||||
|
||||
#ifdef MAD16_CONF
|
||||
tmp |= ((MAD16_CONF) & 0x0f); /* CD-ROM and joystick bits */
|
||||
#endif
|
||||
mad_write(MC1_PORT, tmp);
|
||||
|
||||
#if defined(MAD16_CONF) && defined(MAD16_CDSEL)
|
||||
tmp = MAD16_CDSEL;
|
||||
#else
|
||||
tmp = 0x03;
|
||||
#endif
|
||||
|
||||
#ifdef MAD16_OPL4
|
||||
tmp |= 0x20; /* Enable OPL4 access */
|
||||
#endif
|
||||
|
||||
mad_write(MC2_PORT, tmp);
|
||||
mad_write(MC3_PORT, 0xf0); /* Disable SB */
|
||||
|
||||
if (!ad1848_detect(hw_config->io_base + 4, &ad_flags, mad16_osp))
|
||||
return 0;
|
||||
|
||||
if (ad_flags & (AD_F_CS4231 | AD_F_CS4248))
|
||||
cs4231_mode = 0x02; /* CS4248/CS4231 sync delay switch */
|
||||
|
||||
if (board_type == C929) {
|
||||
mad_write(MC4_PORT, 0xa2);
|
||||
mad_write(MC5_PORT, 0xA5 | cs4231_mode);
|
||||
mad_write(MC6_PORT, 0x03); /* Disable MPU401 */
|
||||
} else {
|
||||
mad_write(MC4_PORT, 0x02);
|
||||
mad_write(MC5_PORT, 0x30 | cs4231_mode);
|
||||
}
|
||||
|
||||
for (i = 0xf8d; i <= 0xf93; i++)
|
||||
DDB(printf("port %03x after init = %03x\n", i, mad_read(i)));
|
||||
|
||||
/*
|
||||
* Verify the WSS parameters
|
||||
*/
|
||||
|
||||
if (0) {
|
||||
printf("MSS: I/O port conflict\n");
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Check if the IO port returns valid signature. The original MS
|
||||
* Sound system returns 0x04 while some cards (AudioTriX Pro for
|
||||
* example) return 0x00.
|
||||
*/
|
||||
|
||||
if ((inb(hw_config->io_base + 3) & 0x3f) != 0x04 &&
|
||||
(inb(hw_config->io_base + 3) & 0x3f) != 0x00) {
|
||||
DDB(printf("No MSS signature detected on port 0x%x (0x%x)\n",
|
||||
hw_config->io_base, inb(hw_config->io_base + 3)));
|
||||
return 0;
|
||||
}
|
||||
if (hw_config->irq > 11) {
|
||||
printf("MSS: Bad IRQ %d\n", hw_config->irq);
|
||||
return 0;
|
||||
}
|
||||
if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3) {
|
||||
printf("MSS: Bad DMA %d\n", hw_config->dma);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Check that DMA0 is not in use with a 8 bit board.
|
||||
*/
|
||||
|
||||
if (hw_config->dma == 0 && inb(hw_config->io_base + 3) & 0x80) {
|
||||
printf("MSS: Can't use DMA0 with a 8 bit card/slot\n");
|
||||
return 0;
|
||||
}
|
||||
if (hw_config->irq > 7 && hw_config->irq != 9 && inb(hw_config->io_base + 3) & 0x80) {
|
||||
printf("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
attach_mad16(struct address_info * hw_config)
|
||||
{
|
||||
|
||||
static char interrupt_bits[12] =
|
||||
{
|
||||
-1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20
|
||||
};
|
||||
char bits;
|
||||
|
||||
static char dma_bits[4] =
|
||||
{
|
||||
1, 2, 0, 3
|
||||
};
|
||||
|
||||
int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3;
|
||||
int ad_flags = 0, dma = hw_config->dma, dma2 = hw_config->dma2;
|
||||
unsigned char dma2_bit = 0;
|
||||
|
||||
already_initialized = 1;
|
||||
|
||||
if (!ad1848_detect(hw_config->io_base + 4, &ad_flags, mad16_osp))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Set the IRQ and DMA addresses.
|
||||
*/
|
||||
|
||||
bits = interrupt_bits[hw_config->irq];
|
||||
if (bits == -1)
|
||||
return;
|
||||
|
||||
outb(config_port, bits | 0x40);
|
||||
if ((inb(version_port) & 0x40) == 0)
|
||||
printf("[IRQ Conflict?]");
|
||||
|
||||
/*
|
||||
* Handle the capture DMA channel
|
||||
*/
|
||||
|
||||
if (ad_flags & AD_F_CS4231 && dma2 != -1 && dma2 != dma) {
|
||||
if ((dma == 0 && dma2 == 1) ||
|
||||
(dma == 1 && dma2 == 0) ||
|
||||
(dma == 3 && dma2 == 0)) {
|
||||
dma2_bit = 0x04; /* Enable capture DMA */
|
||||
} else {
|
||||
printf("MAD16: Invalid capture DMA\n");
|
||||
dma2 = dma;
|
||||
}
|
||||
} else
|
||||
dma2 = dma;
|
||||
|
||||
outb(config_port, bits | dma_bits[dma] | dma2_bit); /* Write IRQ+DMA setup */
|
||||
|
||||
ad1848_init("MAD16 WSS", hw_config->io_base + 4,
|
||||
hw_config->irq,
|
||||
dma,
|
||||
dma2, 0,
|
||||
hw_config->osp);
|
||||
}
|
||||
|
||||
void
|
||||
attach_mad16_mpu(struct address_info * hw_config)
|
||||
{
|
||||
if (board_type < C929) {/* Early chip. No MPU support. Just SB MIDI */
|
||||
#ifdef CONFIG_MIDI
|
||||
|
||||
if (mad_read(MC1_PORT) & 0x20)
|
||||
hw_config->io_base = 0x240;
|
||||
else
|
||||
hw_config->io_base = 0x220;
|
||||
|
||||
return mad16_sb_dsp_init(hw_config);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
|
||||
if (!already_initialized)
|
||||
return;
|
||||
|
||||
attach_mpu401(hw_config);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
probe_mad16_mpu(struct address_info * hw_config)
|
||||
{
|
||||
#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
|
||||
static int mpu_attached = 0;
|
||||
static int valid_ports[] =
|
||||
{0x330, 0x320, 0x310, 0x300};
|
||||
static short valid_irqs[] =
|
||||
{9, 10, 5, 7};
|
||||
unsigned char tmp;
|
||||
|
||||
int i; /* A variable with secret power */
|
||||
|
||||
if (!already_initialized) /* The MSS port must be initialized
|
||||
* first */
|
||||
return 0;
|
||||
|
||||
if (mpu_attached) /* Don't let them call this twice */
|
||||
return 0;
|
||||
mpu_attached = 1;
|
||||
|
||||
if (board_type < C929) {/* Early chip. No MPU support. Just SB MIDI */
|
||||
|
||||
#ifdef CONFIG_MIDI
|
||||
unsigned char tmp;
|
||||
|
||||
tmp = mad_read(MC3_PORT);
|
||||
|
||||
/*
|
||||
* MAD16 SB base is defined by the WSS base. It cannot be
|
||||
* changed alone. Ignore configured I/O base. Use the active
|
||||
* setting.
|
||||
*/
|
||||
|
||||
if (mad_read(MC1_PORT) & 0x20)
|
||||
hw_config->io_base = 0x240;
|
||||
else
|
||||
hw_config->io_base = 0x220;
|
||||
|
||||
switch (hw_config->irq) {
|
||||
case 5:
|
||||
tmp = (tmp & 0x3f) | 0x80;
|
||||
break;
|
||||
case 7:
|
||||
tmp = (tmp & 0x3f);
|
||||
break;
|
||||
case 11:
|
||||
tmp = (tmp & 0x3f) | 0x40;
|
||||
break;
|
||||
default:
|
||||
printf("mad16/Mozart: Invalid MIDI IRQ\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mad_write(MC3_PORT, tmp | 0x04);
|
||||
return mad16_sb_dsp_detect(hw_config);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
tmp = 0x83; /* MPU-401 enable */
|
||||
|
||||
/*
|
||||
* Set the MPU base bits
|
||||
*/
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (i > 3) { /* Out of array bounds */
|
||||
printf("MAD16 / Mozart: Invalid MIDI port 0x%x\n", hw_config->io_base);
|
||||
return 0;
|
||||
}
|
||||
if (valid_ports[i] == hw_config->io_base) {
|
||||
tmp |= i << 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the MPU IRQ bits
|
||||
*/
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (i > 3) { /* Out of array bounds */
|
||||
printf("MAD16 / Mozart: Invalid MIDI IRQ %d\n", hw_config->irq);
|
||||
return 0;
|
||||
}
|
||||
if (valid_irqs[i] == hw_config->irq) {
|
||||
tmp |= i << 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mad_write(MC6_PORT, tmp); /* Write MPU401 config */
|
||||
|
||||
return probe_mpu401(hw_config);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* That's all folks */
|
||||
#endif
|
@ -1,91 +0,0 @@
|
||||
|
||||
/*
|
||||
* Initialization code for OPTI MAD16 interface chip by
|
||||
* Davor Jadrijevic <davor@emard.pub.hr>
|
||||
* (Included by ad1848.c when MAD16 support is enabled)
|
||||
*
|
||||
* It looks like MAD16 is similar than the Mozart chip (OAK OTI-601).
|
||||
* It could be even possible that these chips are exactly the same. Can
|
||||
* anybody confirm this?
|
||||
*/
|
||||
|
||||
static void wr_a_mad16(int base, int v, int a)
|
||||
{
|
||||
OUTB(a, base + 0xf);
|
||||
OUTB(v, base + 0x11);
|
||||
}
|
||||
|
||||
static void wr_b_mad16(int base, int v, int a)
|
||||
{
|
||||
OUTB(a, base + 0xf);
|
||||
OUTB(v, base + 0xd);
|
||||
}
|
||||
|
||||
/*
|
||||
static int rd_a_mad16(int base, int a)
|
||||
{
|
||||
OUTB(a, base + 0xf);
|
||||
return INB(base + 0x11);
|
||||
}
|
||||
*/
|
||||
|
||||
static int rd_b_mad16(int base, int a)
|
||||
{
|
||||
OUTB(a, base + 0xf);
|
||||
return INB(base + 0xd);
|
||||
}
|
||||
|
||||
/*
|
||||
static int rd_0_mad16(int base, int a)
|
||||
{
|
||||
OUTB(a, base + 0xf);
|
||||
return INB(base + 0xf);
|
||||
}
|
||||
|
||||
static void wr_ad(int base, int v, int a)
|
||||
{
|
||||
OUTB(a, base + 4);
|
||||
OUTB(v, base + 5);
|
||||
}
|
||||
|
||||
static int rd_ad(int base, int a)
|
||||
{
|
||||
OUTB(a, base + 4);
|
||||
return INB(base + 5);
|
||||
}
|
||||
*/
|
||||
|
||||
static int mad16init(int adr)
|
||||
{
|
||||
int j;
|
||||
long i;
|
||||
|
||||
static int ad1848_bases[] =
|
||||
{ 0x220, -1, -1, 0x240, -1, -1, -1, -1, 0x530, 0xE80, 0xF40, 0x604, 0 };
|
||||
|
||||
int mad16_base = 0xf80, ad1848_base;
|
||||
|
||||
|
||||
for(j = 0; (j < 16) && (ad1848_bases[j] != 0); j++)
|
||||
if(adr == ad1848_bases[j])
|
||||
break;
|
||||
|
||||
if( (ad1848_base = ad1848_bases[j]) < 0x530)
|
||||
{
|
||||
printk("Unknown MAD16 setting 0x%3X\n", adr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* printk("OPTi MAD16 WSS at 0x%3X\n", ad1848_base); */
|
||||
|
||||
rd_b_mad16(mad16_base, 0xe2);
|
||||
wr_a_mad16(mad16_base, 0x1a, 0xe2);
|
||||
wr_b_mad16(mad16_base, j * 16 + 1, 0xe2);
|
||||
wr_a_mad16(mad16_base, 0x1a, 0xe2);
|
||||
for( i = 0; i < 10000; i++)
|
||||
if( (INB(ad1848_base+4) & 0x80) == 0 )
|
||||
break;
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
@ -1,285 +0,0 @@
|
||||
/*
|
||||
* sound/mad16_sb_midi.c
|
||||
*
|
||||
* The low level driver for MAD16 SoundBlaster-DS-chip-based MIDI.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993, Aaron Ucko 1995
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if defined(CONFIG_MAD16) && defined(CONFIG_MIDI)
|
||||
|
||||
#define sbc_base mad16_sb_base
|
||||
#include <i386/isa/sound/sb_card.h>
|
||||
|
||||
static int input_opened = 0;
|
||||
static int my_dev;
|
||||
static int mad16_sb_base = 0x220;
|
||||
static int mad16_sb_irq = 0;
|
||||
static int mad16_sb_dsp_ok = 0;
|
||||
static sound_os_info *midi_osp;
|
||||
|
||||
int mad16_sb_midi_mode = NORMAL_MIDI;
|
||||
int mad16_sb_midi_busy = 0;
|
||||
|
||||
int mad16_sb_duplex_midi = 0;
|
||||
volatile int mad16_sb_intr_active = 0;
|
||||
|
||||
void (*midi_input_intr) (int dev, unsigned char data);
|
||||
|
||||
static void mad16_sb_midi_init(int model);
|
||||
|
||||
static int
|
||||
mad16_sb_dsp_command(unsigned char val)
|
||||
{
|
||||
int i;
|
||||
unsigned long limit;
|
||||
|
||||
limit = get_time() + hz / 10; /* The timeout is 0.1 secods */
|
||||
|
||||
/*
|
||||
* Note! the i<500000 is an emergency exit. The
|
||||
* mad16_sb_dsp_command() is sometimes called while interrupts are
|
||||
* disabled. This means that the timer is disabled also. However the
|
||||
* timeout situation is a abnormal condition. Normally the DSP should
|
||||
* be ready to accept commands after just couple of loops.
|
||||
*/
|
||||
|
||||
for (i = 0; i < 500000 && get_time() < limit; i++) {
|
||||
if ((inb(DSP_STATUS) & 0x80) == 0) {
|
||||
outb(DSP_COMMAND, val);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
printf("MAD16 (SBP mode): DSP Command(%x) Timeout.\n", val);
|
||||
printf("IRQ conflict???\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
mad16_sbintr(int irq)
|
||||
{
|
||||
int status;
|
||||
|
||||
unsigned long flags;
|
||||
unsigned char data;
|
||||
|
||||
status = inb(DSP_DATA_AVAIL); /* Clear interrupt */
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
data = inb(DSP_READ);
|
||||
if (input_opened)
|
||||
midi_input_intr(my_dev, data);
|
||||
|
||||
splx(flags);
|
||||
}
|
||||
|
||||
static int
|
||||
mad16_sb_reset_dsp(void)
|
||||
{
|
||||
int loopc;
|
||||
|
||||
outb(DSP_RESET, 1);
|
||||
DELAY(10);
|
||||
outb(DSP_RESET, 0);
|
||||
DELAY(30);
|
||||
|
||||
for (loopc = 0; loopc < 100 && !(inb(DSP_DATA_AVAIL) & 0x80); loopc++)
|
||||
DELAY(10);
|
||||
/* Wait for data available status */
|
||||
|
||||
if (inb(DSP_READ) != 0xAA)
|
||||
return 0; /* Sorry */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
mad16_sb_dsp_detect(struct address_info * hw_config)
|
||||
{
|
||||
mad16_sb_base = hw_config->io_base;
|
||||
mad16_sb_irq = hw_config->irq;
|
||||
midi_osp = hw_config->osp;
|
||||
|
||||
if (mad16_sb_dsp_ok)
|
||||
return 0; /* Already initialized */
|
||||
if (!mad16_sb_reset_dsp())
|
||||
return 0;
|
||||
|
||||
return 1; /* Detected */
|
||||
}
|
||||
|
||||
void
|
||||
mad16_sb_dsp_init(struct address_info * hw_config)
|
||||
/*
|
||||
* this function now just verifies the reported version and calls
|
||||
* mad16_sb_midi_init -- everything else is done elsewhere
|
||||
*/
|
||||
{
|
||||
|
||||
midi_osp = hw_config->osp;
|
||||
if (snd_set_irq_handler(mad16_sb_irq, mad16_sbintr, midi_osp) < 0) {
|
||||
printf("MAD16 SB MIDI: IRQ not free\n");
|
||||
return;
|
||||
}
|
||||
|
||||
conf_printf("MAD16 MIDI (SB mode)", hw_config);
|
||||
mad16_sb_midi_init(2);
|
||||
|
||||
mad16_sb_dsp_ok = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
mad16_sb_midi_open(int dev, int mode,
|
||||
void (*input) (int dev, unsigned char data),
|
||||
void (*output) (int dev)
|
||||
)
|
||||
{
|
||||
|
||||
if (!mad16_sb_dsp_ok) {
|
||||
printf("MAD16_SB Error: MIDI hardware not installed\n");
|
||||
return -(ENXIO);
|
||||
}
|
||||
if (mad16_sb_midi_busy)
|
||||
return -(EBUSY);
|
||||
|
||||
if (mode != OPEN_WRITE && !mad16_sb_duplex_midi) {
|
||||
if (num_midis == 1)
|
||||
printf("MAD16 (SBP mode): Midi input not currently supported\n");
|
||||
return -(EPERM);
|
||||
}
|
||||
mad16_sb_midi_mode = NORMAL_MIDI;
|
||||
if (mode != OPEN_WRITE) {
|
||||
if (mad16_sb_intr_active)
|
||||
return -(EBUSY);
|
||||
mad16_sb_midi_mode = UART_MIDI;
|
||||
}
|
||||
if (mad16_sb_midi_mode == UART_MIDI) {
|
||||
mad16_sb_reset_dsp();
|
||||
|
||||
if (!mad16_sb_dsp_command(0x35))
|
||||
return -(EIO); /* Enter the UART mode */
|
||||
mad16_sb_intr_active = 1;
|
||||
|
||||
input_opened = 1;
|
||||
midi_input_intr = input;
|
||||
}
|
||||
mad16_sb_midi_busy = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mad16_sb_midi_close(int dev)
|
||||
{
|
||||
if (mad16_sb_midi_mode == UART_MIDI) {
|
||||
mad16_sb_reset_dsp(); /* The only way to kill the UART mode */
|
||||
}
|
||||
mad16_sb_intr_active = 0;
|
||||
mad16_sb_midi_busy = 0;
|
||||
input_opened = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mad16_sb_midi_out(int dev, unsigned char midi_byte)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (mad16_sb_midi_mode == NORMAL_MIDI) {
|
||||
flags = splhigh();
|
||||
if (mad16_sb_dsp_command(0x38))
|
||||
mad16_sb_dsp_command(midi_byte);
|
||||
else
|
||||
printf("MAD16_SB Error: Unable to send a MIDI byte\n");
|
||||
splx(flags);
|
||||
} else
|
||||
mad16_sb_dsp_command(midi_byte); /* UART write */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mad16_sb_midi_start_read(int dev)
|
||||
{
|
||||
if (mad16_sb_midi_mode != UART_MIDI) {
|
||||
printf("MAD16 (SBP mode): MIDI input not implemented.\n");
|
||||
return -(EPERM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mad16_sb_midi_end_read(int dev)
|
||||
{
|
||||
if (mad16_sb_midi_mode == UART_MIDI) {
|
||||
mad16_sb_reset_dsp();
|
||||
mad16_sb_intr_active = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mad16_sb_midi_ioctl(int dev, unsigned cmd, ioctl_arg arg)
|
||||
{
|
||||
return -(EPERM);
|
||||
}
|
||||
|
||||
#define MIDI_SYNTH_NAME "pseudo-SoundBlaster Midi"
|
||||
#define MIDI_SYNTH_CAPS 0
|
||||
#include <i386/isa/sound/midi_synth.h>
|
||||
|
||||
static struct midi_operations mad16_sb_midi_operations =
|
||||
{
|
||||
{"MAD16 (SBP mode)", 0, 0, SNDCARD_MAD16},
|
||||
&std_midi_synth,
|
||||
{0},
|
||||
mad16_sb_midi_open,
|
||||
mad16_sb_midi_close,
|
||||
mad16_sb_midi_ioctl,
|
||||
mad16_sb_midi_out,
|
||||
mad16_sb_midi_start_read,
|
||||
mad16_sb_midi_end_read,
|
||||
NULL, /* Kick */
|
||||
NULL, /* command */
|
||||
NULL, /* buffer_status */
|
||||
NULL
|
||||
};
|
||||
|
||||
static void
|
||||
mad16_sb_midi_init(int model)
|
||||
{
|
||||
if (num_midis >= MAX_MIDI_DEV) {
|
||||
printf("Sound: Too many midi devices detected\n");
|
||||
return;
|
||||
}
|
||||
std_midi_synth.midi_dev = num_midis;
|
||||
my_dev = num_midis;
|
||||
midi_devs[num_midis++] = &mad16_sb_midi_operations;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,225 +0,0 @@
|
||||
/*
|
||||
* sound/maui.c
|
||||
*
|
||||
* The low level driver for Turtle Beach Maui and Tropez.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1995
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#define USE_SEQ_MACROS
|
||||
#define USE_SIMPLE_MACROS
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
|
||||
#if defined(CONFIG_MAUI)
|
||||
|
||||
static int maui_base = 0x330;
|
||||
|
||||
static volatile int irq_ok = 0;
|
||||
static sound_os_info *maui_osp;
|
||||
|
||||
#define HOST_DATA_PORT (maui_base + 2)
|
||||
#define HOST_STAT_PORT (maui_base + 3)
|
||||
#define HOST_CTRL_PORT (maui_base + 3)
|
||||
|
||||
#define STAT_TX_INTR 0x40
|
||||
#define STAT_TX_AVAIL 0x20
|
||||
#define STAT_TX_IENA 0x10
|
||||
#define STAT_RX_INTR 0x04
|
||||
#define STAT_RX_AVAIL 0x02
|
||||
#define STAT_RX_IENA 0x01
|
||||
|
||||
static int (*orig_load_patch) (int dev, int format, snd_rw_buf * addr,
|
||||
int offs, int count, int pmgr_flag) = NULL;
|
||||
|
||||
static int
|
||||
maui_read(void)
|
||||
{
|
||||
int timeout;
|
||||
|
||||
for (timeout = 0; timeout < 1000000; timeout++)
|
||||
if (inb(HOST_STAT_PORT) & STAT_RX_AVAIL)
|
||||
return inb(HOST_DATA_PORT);
|
||||
|
||||
printf("Maui: Receive timeout\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
maui_write(u_char data)
|
||||
{
|
||||
int timeout;
|
||||
|
||||
for (timeout = 0; timeout < 10000000; timeout++) {
|
||||
if (inb(HOST_STAT_PORT) & STAT_TX_AVAIL) {
|
||||
outb(HOST_DATA_PORT, data);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Maui: Write timeout\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
mauiintr(int irq)
|
||||
{
|
||||
irq_ok = 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
maui_load_patch(int dev, int format, snd_rw_buf * addr,
|
||||
int offs, int count, int pmgr_flag)
|
||||
{
|
||||
|
||||
struct sysex_info header;
|
||||
u_long left, src_offs;
|
||||
int hdr_size = (u_long) &header.data[0] - (u_long) &header;
|
||||
int i;
|
||||
|
||||
if (format == SYSEX_PATCH) /* Handled by midi_synth.c */
|
||||
return orig_load_patch(dev, format, addr, offs, count, pmgr_flag);
|
||||
|
||||
if (format != MAUI_PATCH) {
|
||||
printf("Maui: Unknown patch format\n");
|
||||
}
|
||||
if (count < hdr_size) {
|
||||
printf("Maui error: Patch header too short\n");
|
||||
return -(EINVAL);
|
||||
}
|
||||
count -= hdr_size;
|
||||
|
||||
/*
|
||||
* Copy the header from user space but ignore the first bytes which
|
||||
* have been transferred already.
|
||||
*/
|
||||
|
||||
if (uiomove(&((char *) &header)[offs], hdr_size - offs, addr)) {
|
||||
printf("sb: Bad copyin()!\n");
|
||||
};
|
||||
|
||||
if (count < header.len) {
|
||||
printf("Maui warning: Host command record too short (%d<%d)\n",
|
||||
count, (int) header.len);
|
||||
header.len = count;
|
||||
}
|
||||
left = header.len;
|
||||
src_offs = 0;
|
||||
|
||||
for (i = 0; i < left; i++) {
|
||||
u_char data;
|
||||
uiomove((char *) &(data), 1, addr);
|
||||
if (i == 0 && !(data & 0x80))
|
||||
return -(EINVAL);
|
||||
|
||||
if (maui_write(data) == -1)
|
||||
return -(EIO);
|
||||
}
|
||||
|
||||
if ((i = maui_read()) != 0x80) {
|
||||
if (i != -1)
|
||||
printf("Maui: Error status %02x\n", i);
|
||||
|
||||
return -(EIO);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
probe_maui(struct address_info * hw_config)
|
||||
{
|
||||
int i;
|
||||
int tmp1, tmp2;
|
||||
|
||||
maui_base = hw_config->io_base;
|
||||
maui_osp = hw_config->osp;
|
||||
|
||||
if (snd_set_irq_handler(hw_config->irq, mauiintr, maui_osp) < 0)
|
||||
return 0;
|
||||
|
||||
if (!maui_write(0xCF)) {/* Report hardware version */
|
||||
/* snd_release_irq(hw_config->irq); */
|
||||
return 0;
|
||||
}
|
||||
if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1) {
|
||||
/* snd_release_irq(hw_config->irq); */
|
||||
return 0;
|
||||
}
|
||||
printf("WaveFront hardware version %d.%d\n", tmp1, tmp2);
|
||||
|
||||
if (!maui_write(0x9F)) /* Report firmware version */
|
||||
return 0;
|
||||
if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1)
|
||||
return 0;
|
||||
printf("WaveFront firmware version %d.%d\n", tmp1, tmp2);
|
||||
|
||||
if (!maui_write(0x85)) /* Report free DRAM */
|
||||
return 0;
|
||||
tmp1 = 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
tmp1 |= maui_read() << (7 * i);
|
||||
}
|
||||
printf("Available DRAM %dk\n", tmp1 / 1024);
|
||||
|
||||
for (i = 0; i < 1000; i++)
|
||||
if (probe_mpu401(hw_config))
|
||||
break;
|
||||
|
||||
return probe_mpu401(hw_config);
|
||||
}
|
||||
|
||||
void
|
||||
attach_maui(struct address_info * hw_config)
|
||||
{
|
||||
int this_dev = num_midis;
|
||||
|
||||
conf_printf("Maui", hw_config);
|
||||
|
||||
hw_config->irq *= -1;
|
||||
attach_mpu401(hw_config);
|
||||
|
||||
if (num_midis > this_dev) { /* The MPU401 driver installed itself */
|
||||
struct synth_operations *synth;
|
||||
|
||||
/*
|
||||
* Intercept patch loading calls so that they canbe handled
|
||||
* by the Maui driver.
|
||||
*/
|
||||
|
||||
synth = midi_devs[this_dev]->converter;
|
||||
|
||||
if (synth != NULL) {
|
||||
orig_load_patch = synth->load_patch;
|
||||
synth->load_patch = &maui_load_patch;
|
||||
} else
|
||||
printf("Maui: Can't install patch loader\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,22 +0,0 @@
|
||||
static unsigned char ctrl_def_values[128] =
|
||||
{
|
||||
0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x40, /* 0 to 7 */
|
||||
0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x40, /* 8 to 15 */
|
||||
0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x40, /* 16 to 23 */
|
||||
0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x40, /* 24 to 31 */
|
||||
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 32 to 39 */
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 40 to 47 */
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 48 to 55 */
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 56 to 63 */
|
||||
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 64 to 71 */
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 72 to 79 */
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 80 to 87 */
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 88 to 95 */
|
||||
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 96 to 103 */
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 104 to 111 */
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 112 to 119 */
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 120 to 127 */
|
||||
};
|
@ -1,675 +0,0 @@
|
||||
/*
|
||||
* sound/midi_synth.c
|
||||
*
|
||||
* High level midi sequencer manager for dumb MIDI interfaces.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#define USE_SEQ_MACROS
|
||||
#define USE_SIMPLE_MACROS
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if defined(CONFIGURE_SOUNDCARD) /* && defined(CONFIG_MIDI) */
|
||||
|
||||
#define _MIDI_SYNTH_C_
|
||||
|
||||
static int *sysex_sleeper = NULL;
|
||||
static volatile struct snd_wait sysex_sleep_flag = {0};
|
||||
|
||||
#include <i386/isa/sound/midi_synth.h>
|
||||
|
||||
static int midi2synth[MAX_MIDI_DEV];
|
||||
static int sysex_state[MAX_MIDI_DEV] =
|
||||
{0};
|
||||
static unsigned char prev_out_status[MAX_MIDI_DEV];
|
||||
|
||||
#ifndef CONFIG_SEQUENCER
|
||||
#define STORE(cmd)
|
||||
#else
|
||||
#define STORE(cmd) { \
|
||||
int len; \
|
||||
unsigned char obuf[8]; \
|
||||
cmd; \
|
||||
seq_input_event(obuf, len); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define _seqbuf obuf
|
||||
#define _seqbufptr 0
|
||||
#define _SEQ_ADVBUF(x) len=x
|
||||
|
||||
void
|
||||
do_midi_msg(int synthno, unsigned char *msg, int mlen)
|
||||
{
|
||||
switch (msg[0] & 0xf0) {
|
||||
case 0x90:
|
||||
if (msg[2] != 0) {
|
||||
STORE(SEQ_START_NOTE(synthno, msg[0] & 0x0f, msg[1], msg[2]));
|
||||
break;
|
||||
}
|
||||
msg[2] = 64;
|
||||
|
||||
case 0x80:
|
||||
STORE(SEQ_STOP_NOTE(synthno, msg[0] & 0x0f, msg[1], msg[2]));
|
||||
break;
|
||||
|
||||
case 0xA0:
|
||||
STORE(SEQ_KEY_PRESSURE(synthno, msg[0] & 0x0f, msg[1], msg[2]));
|
||||
break;
|
||||
|
||||
case 0xB0:
|
||||
STORE(SEQ_CONTROL(synthno, msg[0] & 0x0f, msg[1], msg[2]));
|
||||
break;
|
||||
|
||||
case 0xC0:
|
||||
STORE(SEQ_SET_PATCH(synthno, msg[0] & 0x0f, msg[1]));
|
||||
break;
|
||||
|
||||
case 0xD0:
|
||||
STORE(SEQ_CHN_PRESSURE(synthno, msg[0] & 0x0f, msg[1]));
|
||||
break;
|
||||
|
||||
case 0xE0:
|
||||
STORE(SEQ_BENDER(synthno, msg[0] & 0x0f,
|
||||
(msg[1] % 0x7f) | ((msg[2] & 0x7f) << 7)));
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* printf ("MPU: Unknown midi channel message %02x\n",
|
||||
* msg[0]);
|
||||
*/
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
midi_outc(int midi_dev, int data)
|
||||
{
|
||||
int timeout;
|
||||
|
||||
for (timeout = 0; timeout < 32000; timeout++)
|
||||
if (midi_devs[midi_dev]->putc(midi_dev, (unsigned char) (data & 0xff))) {
|
||||
if (data & 0x80) /* Status byte */
|
||||
prev_out_status[midi_dev] =
|
||||
(unsigned char) (data & 0xff); /* Store for running
|
||||
* status */
|
||||
return; /* Mission complete */
|
||||
}
|
||||
/*
|
||||
* Sorry! No space on buffers.
|
||||
*/
|
||||
printf("Midi send timed out\n");
|
||||
}
|
||||
|
||||
static int
|
||||
prefix_cmd(int midi_dev, unsigned char status)
|
||||
{
|
||||
if ((char *) midi_devs[midi_dev]->prefix_cmd == NULL)
|
||||
return 1;
|
||||
|
||||
return midi_devs[midi_dev]->prefix_cmd(midi_dev, status);
|
||||
}
|
||||
|
||||
static void
|
||||
midi_synth_input(int orig_dev, unsigned char data)
|
||||
{
|
||||
int dev;
|
||||
struct midi_input_info *inc;
|
||||
|
||||
static unsigned char len_tab[] = /* # of data bytes following a status */
|
||||
{
|
||||
2, /* 8x */
|
||||
2, /* 9x */
|
||||
2, /* Ax */
|
||||
2, /* Bx */
|
||||
1, /* Cx */
|
||||
1, /* Dx */
|
||||
2, /* Ex */
|
||||
0 /* Fx */
|
||||
};
|
||||
|
||||
if (orig_dev < 0 || orig_dev > num_midis)
|
||||
return;
|
||||
|
||||
if (data == 0xfe) /* Ignore active sensing */
|
||||
return;
|
||||
|
||||
dev = midi2synth[orig_dev];
|
||||
inc = &midi_devs[orig_dev]->in_info;
|
||||
|
||||
switch (inc->m_state) {
|
||||
case MST_INIT:
|
||||
if (data & 0x80) { /* MIDI status byte */
|
||||
if ((data & 0xf0) == 0xf0) { /* Common message */
|
||||
switch (data) {
|
||||
case 0xf0: /* Sysex */
|
||||
inc->m_state = MST_SYSEX;
|
||||
break; /* Sysex */
|
||||
|
||||
case 0xf1: /* MTC quarter frame */
|
||||
case 0xf3: /* Song select */
|
||||
inc->m_state = MST_DATA;
|
||||
inc->m_ptr = 1;
|
||||
inc->m_left = 1;
|
||||
inc->m_buf[0] = data;
|
||||
break;
|
||||
|
||||
case 0xf2: /* Song position pointer */
|
||||
inc->m_state = MST_DATA;
|
||||
inc->m_ptr = 1;
|
||||
inc->m_left = 2;
|
||||
inc->m_buf[0] = data;
|
||||
break;
|
||||
|
||||
default:
|
||||
inc->m_buf[0] = data;
|
||||
inc->m_ptr = 1;
|
||||
do_midi_msg(dev, inc->m_buf, inc->m_ptr);
|
||||
inc->m_ptr = 0;
|
||||
inc->m_left = 0;
|
||||
}
|
||||
} else {
|
||||
inc->m_state = MST_DATA;
|
||||
inc->m_ptr = 1;
|
||||
inc->m_left = len_tab[(data >> 4) - 8];
|
||||
inc->m_buf[0] = inc->m_prev_status = data;
|
||||
}
|
||||
} else if (inc->m_prev_status & 0x80) { /* Ignore if no previous
|
||||
* status (yet) *//* Data byte (use running status) */
|
||||
inc->m_state = MST_DATA;
|
||||
inc->m_ptr = 2;
|
||||
inc->m_left = len_tab[(data >> 4) - 8] - 1;
|
||||
inc->m_buf[0] = inc->m_prev_status;
|
||||
inc->m_buf[1] = data;
|
||||
}
|
||||
break; /* MST_INIT */
|
||||
|
||||
case MST_DATA:
|
||||
inc->m_buf[inc->m_ptr++] = data;
|
||||
if (--inc->m_left <= 0) {
|
||||
inc->m_state = MST_INIT;
|
||||
do_midi_msg(dev, inc->m_buf, inc->m_ptr);
|
||||
inc->m_ptr = 0;
|
||||
}
|
||||
break; /* MST_DATA */
|
||||
|
||||
case MST_SYSEX:
|
||||
if (data == 0xf7) { /* Sysex end */
|
||||
inc->m_state = MST_INIT;
|
||||
inc->m_left = 0;
|
||||
inc->m_ptr = 0;
|
||||
}
|
||||
break; /* MST_SYSEX */
|
||||
|
||||
default:
|
||||
printf("MIDI%d: Unexpected state %d (%02x)\n", orig_dev, inc->m_state,
|
||||
(int) data);
|
||||
inc->m_state = MST_INIT;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
leave_sysex(int dev)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
int timeout = 0;
|
||||
|
||||
if (!sysex_state[dev])
|
||||
return;
|
||||
|
||||
sysex_state[dev] = 0;
|
||||
|
||||
while (!midi_devs[orig_dev]->putc(orig_dev, 0xf7) && timeout < 1000)
|
||||
timeout++;
|
||||
|
||||
sysex_state[dev] = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
midi_synth_output(int dev)
|
||||
{
|
||||
/*
|
||||
* Currently NOP
|
||||
*/
|
||||
}
|
||||
|
||||
int
|
||||
midi_synth_ioctl(int dev, unsigned int cmd, ioctl_arg arg)
|
||||
{
|
||||
/*
|
||||
* int orig_dev = synth_devs[dev]->midi_dev;
|
||||
*/
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case SNDCTL_SYNTH_INFO:
|
||||
bcopy(synth_devs[dev]->info, &(((char *) arg)[0]), sizeof(struct synth_info));
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SNDCTL_SYNTH_MEMAVL:
|
||||
return 0x7fffffff;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -(EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
midi_synth_kill_note(int dev, int channel, int note, int velocity)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
int msg, chn;
|
||||
|
||||
if (note < 0 || note > 127)
|
||||
return 0;
|
||||
if (channel < 0 || channel > 15)
|
||||
return 0;
|
||||
RANGE (velocity, 0, 127 ) ;
|
||||
leave_sysex(dev);
|
||||
|
||||
msg = prev_out_status[orig_dev] & 0xf0;
|
||||
chn = prev_out_status[orig_dev] & 0x0f;
|
||||
|
||||
if (chn == channel && ((msg == 0x90 && velocity == 64) || msg == 0x80)) { /* Use running status */
|
||||
if (!prefix_cmd(orig_dev, note))
|
||||
return 0;
|
||||
|
||||
midi_outc(orig_dev, note);
|
||||
|
||||
if (msg == 0x90)/* Running status = Note on */
|
||||
midi_outc(orig_dev, 0); /* Note on with velocity 0 == note off */
|
||||
else
|
||||
midi_outc(orig_dev, velocity);
|
||||
} else {
|
||||
if (velocity == 64) {
|
||||
if (!prefix_cmd(orig_dev, 0x90 | (channel & 0x0f)))
|
||||
return 0;
|
||||
midi_outc(orig_dev, 0x90 | (channel & 0x0f)); /* Note on */
|
||||
midi_outc(orig_dev, note);
|
||||
midi_outc(orig_dev, 0); /* Zero G */
|
||||
} else {
|
||||
if (!prefix_cmd(orig_dev, 0x80 | (channel & 0x0f)))
|
||||
return 0;
|
||||
midi_outc(orig_dev, 0x80 | (channel & 0x0f)); /* Note off */
|
||||
midi_outc(orig_dev, note);
|
||||
midi_outc(orig_dev, velocity);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
midi_synth_set_instr(int dev, int channel, int instr_no)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
|
||||
if (instr_no < 0 || instr_no > 127)
|
||||
return 0;
|
||||
if (channel < 0 || channel > 15)
|
||||
return 0;
|
||||
|
||||
leave_sysex(dev);
|
||||
|
||||
if (!prefix_cmd(orig_dev, 0xc0 | (channel & 0x0f)))
|
||||
return 0;
|
||||
midi_outc(orig_dev, 0xc0 | (channel & 0x0f)); /* Program change */
|
||||
midi_outc(orig_dev, instr_no);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
midi_synth_start_note(int dev, int channel, int note, int velocity)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
int msg, chn;
|
||||
|
||||
if (note < 0 || note > 127)
|
||||
return 0;
|
||||
if (channel < 0 || channel > 15)
|
||||
return 0;
|
||||
RANGE (velocity, 0, 127 );
|
||||
leave_sysex(dev);
|
||||
|
||||
msg = prev_out_status[orig_dev] & 0xf0;
|
||||
chn = prev_out_status[orig_dev] & 0x0f;
|
||||
|
||||
if (chn == channel && msg == 0x90) { /* Use running status */
|
||||
if (!prefix_cmd(orig_dev, note))
|
||||
return 0;
|
||||
midi_outc(orig_dev, note);
|
||||
midi_outc(orig_dev, velocity);
|
||||
} else {
|
||||
if (!prefix_cmd(orig_dev, 0x90 | (channel & 0x0f)))
|
||||
return 0;
|
||||
midi_outc(orig_dev, 0x90 | (channel & 0x0f)); /* Note on */
|
||||
midi_outc(orig_dev, note);
|
||||
midi_outc(orig_dev, velocity);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
midi_synth_reset(int dev)
|
||||
{
|
||||
|
||||
leave_sysex(dev);
|
||||
}
|
||||
|
||||
int
|
||||
midi_synth_open(int dev, int mode)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
int err;
|
||||
unsigned long flags;
|
||||
struct midi_input_info *inc;
|
||||
|
||||
if (orig_dev < 0 || orig_dev > num_midis)
|
||||
return -(ENXIO);
|
||||
|
||||
midi2synth[orig_dev] = dev;
|
||||
sysex_state[dev] = 0;
|
||||
prev_out_status[orig_dev] = 0;
|
||||
|
||||
if ((err = midi_devs[orig_dev]->open(orig_dev, mode,
|
||||
midi_synth_input, midi_synth_output)) < 0)
|
||||
return err;
|
||||
|
||||
inc = &midi_devs[orig_dev]->in_info;
|
||||
|
||||
flags = splhigh();
|
||||
inc->m_busy = 0;
|
||||
inc->m_state = MST_INIT;
|
||||
inc->m_ptr = 0;
|
||||
inc->m_left = 0;
|
||||
inc->m_prev_status = 0x00;
|
||||
splx(flags);
|
||||
|
||||
sysex_sleep_flag.aborting = 0;
|
||||
sysex_sleep_flag.mode = WK_NONE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
midi_synth_close(int dev)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
|
||||
leave_sysex(dev);
|
||||
|
||||
/*
|
||||
* Shut up the synths by sending just single active sensing message.
|
||||
*/
|
||||
midi_devs[orig_dev]->putc(orig_dev, 0xfe);
|
||||
|
||||
midi_devs[orig_dev]->close(orig_dev);
|
||||
}
|
||||
|
||||
void
|
||||
midi_synth_hw_control(int dev, unsigned char *event)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
midi_synth_load_patch(int dev, int format, snd_rw_buf * addr,
|
||||
int offs, int count, int pmgr_flag)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
|
||||
struct sysex_info sysex;
|
||||
int i;
|
||||
unsigned long left, src_offs, eox_seen = 0;
|
||||
int first_byte = 1;
|
||||
int hdr_size = offsetof(struct sysex_info, data);
|
||||
|
||||
leave_sysex(dev);
|
||||
|
||||
if (!prefix_cmd(orig_dev, 0xf0))
|
||||
return 0;
|
||||
|
||||
if (format != SYSEX_PATCH) {
|
||||
printf("MIDI Error: Invalid patch format (key) 0x%x\n", format);
|
||||
return -(EINVAL);
|
||||
}
|
||||
if (count < hdr_size) {
|
||||
printf("MIDI Error: Patch header too short\n");
|
||||
return -(EINVAL);
|
||||
}
|
||||
count -= hdr_size;
|
||||
|
||||
/*
|
||||
* Copy the header from user space but ignore the first bytes which
|
||||
* have been transferred already.
|
||||
*/
|
||||
|
||||
|
||||
if (uiomove(&((char *) &sysex)[offs], hdr_size - offs, addr)) {
|
||||
printf("sb: Bad copyin()!\n");
|
||||
};
|
||||
|
||||
if (count < sysex.len) {
|
||||
printf("MIDI Warning: Sysex record too short (%d<%d)\n",
|
||||
count, (int) sysex.len);
|
||||
sysex.len = count;
|
||||
}
|
||||
left = sysex.len;
|
||||
src_offs = 0;
|
||||
|
||||
sysex_sleep_flag.aborting = 0;
|
||||
sysex_sleep_flag.mode = WK_NONE;
|
||||
|
||||
for (i = 0; i < left && !(sysex_sleep_flag.aborting); i++) {
|
||||
unsigned char data;
|
||||
|
||||
uiomove((char *) &(data), 1, addr);
|
||||
|
||||
eox_seen = (i > 0 && data & 0x80); /* End of sysex */
|
||||
|
||||
if (eox_seen && data != 0xf7)
|
||||
data = 0xf7;
|
||||
|
||||
if (i == 0) {
|
||||
if (data != 0xf0) {
|
||||
printf("Error: Sysex start missing\n");
|
||||
return -(EINVAL);
|
||||
}
|
||||
}
|
||||
while (!midi_devs[orig_dev]->putc(orig_dev,
|
||||
(unsigned char) (data & 0xff)) &&
|
||||
!(sysex_sleep_flag.aborting)) {
|
||||
int chn;
|
||||
|
||||
|
||||
sysex_sleeper = &chn;
|
||||
DO_SLEEP(chn, sysex_sleep_flag, 1);
|
||||
|
||||
}; /* Wait for timeout */
|
||||
|
||||
if (!first_byte && data & 0x80)
|
||||
return 0;
|
||||
first_byte = 0;
|
||||
}
|
||||
|
||||
if (!eox_seen)
|
||||
midi_outc(orig_dev, 0xf7);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
midi_synth_panning(int dev, int channel, int pressure)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
midi_synth_aftertouch(int dev, int channel, int pressure)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
int msg, chn;
|
||||
|
||||
if (pressure < 0 || pressure > 127)
|
||||
return;
|
||||
if (channel < 0 || channel > 15)
|
||||
return;
|
||||
|
||||
leave_sysex(dev);
|
||||
|
||||
msg = prev_out_status[orig_dev] & 0xf0;
|
||||
chn = prev_out_status[orig_dev] & 0x0f;
|
||||
|
||||
if (msg != 0xd0 || chn != channel) { /* Test for running status */
|
||||
if (!prefix_cmd(orig_dev, 0xd0 | (channel & 0x0f)))
|
||||
return;
|
||||
midi_outc(orig_dev, 0xd0 | (channel & 0x0f)); /* Channel pressure */
|
||||
} else if (!prefix_cmd(orig_dev, pressure))
|
||||
return;
|
||||
|
||||
midi_outc(orig_dev, pressure);
|
||||
}
|
||||
|
||||
void
|
||||
midi_synth_controller(int dev, int channel, int ctrl_num, int value)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
int chn, msg;
|
||||
|
||||
if (ctrl_num < 1 || ctrl_num > 127)
|
||||
return; /* NOTE! Controller # 0 ignored */
|
||||
if (channel < 0 || channel > 15)
|
||||
return;
|
||||
|
||||
leave_sysex(dev);
|
||||
|
||||
msg = prev_out_status[orig_dev] & 0xf0;
|
||||
chn = prev_out_status[orig_dev] & 0x0f;
|
||||
|
||||
if (msg != 0xb0 || chn != channel) {
|
||||
if (!prefix_cmd(orig_dev, 0xb0 | (channel & 0x0f)))
|
||||
return;
|
||||
midi_outc(orig_dev, 0xb0 | (channel & 0x0f));
|
||||
} else if (!prefix_cmd(orig_dev, ctrl_num))
|
||||
return;
|
||||
|
||||
midi_outc(orig_dev, ctrl_num);
|
||||
midi_outc(orig_dev, value & 0x7f);
|
||||
}
|
||||
|
||||
int
|
||||
midi_synth_patchmgr(int dev, struct patmgr_info * rec)
|
||||
{
|
||||
return -(EINVAL);
|
||||
}
|
||||
|
||||
void
|
||||
midi_synth_bender(int dev, int channel, int value)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
int msg, prev_chn;
|
||||
|
||||
if (channel < 0 || channel > 15)
|
||||
return;
|
||||
|
||||
if (value < 0 || value > 16383)
|
||||
return;
|
||||
|
||||
leave_sysex(dev);
|
||||
|
||||
msg = prev_out_status[orig_dev] & 0xf0;
|
||||
prev_chn = prev_out_status[orig_dev] & 0x0f;
|
||||
|
||||
if (msg != 0xd0 || prev_chn != channel) { /* Test for running status */
|
||||
if (!prefix_cmd(orig_dev, 0xe0 | (channel & 0x0f)))
|
||||
return;
|
||||
midi_outc(orig_dev, 0xe0 | (channel & 0x0f));
|
||||
} else if (!prefix_cmd(orig_dev, value & 0x7f))
|
||||
return;
|
||||
|
||||
midi_outc(orig_dev, value & 0x7f);
|
||||
midi_outc(orig_dev, (value >> 7) & 0x7f);
|
||||
}
|
||||
|
||||
void
|
||||
midi_synth_setup_voice(int dev, int voice, int channel)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
midi_synth_send_sysex(int dev, unsigned char *bytes, int len)
|
||||
{
|
||||
int orig_dev = synth_devs[dev]->midi_dev;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
switch (bytes[i]) {
|
||||
case 0xf0: /* Start sysex */
|
||||
if (!prefix_cmd(orig_dev, 0xf0))
|
||||
return 0;
|
||||
sysex_state[dev] = 1;
|
||||
break;
|
||||
|
||||
case 0xf7: /* End sysex */
|
||||
if (!sysex_state[dev]) /* Orphan sysex end */
|
||||
return 0;
|
||||
sysex_state[dev] = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!sysex_state[dev])
|
||||
return 0;
|
||||
|
||||
if (bytes[i] & 0x80) { /* Error. Another message before sysex end */
|
||||
bytes[i] = 0xf7; /* Sysex end */
|
||||
sysex_state[dev] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!midi_devs[orig_dev]->putc(orig_dev, bytes[i])) {
|
||||
/*
|
||||
* Hardware leve buffer is full. Abort the sysex message.
|
||||
*/
|
||||
|
||||
int timeout = 0;
|
||||
|
||||
bytes[i] = 0xf7;
|
||||
sysex_state[dev] = 0;
|
||||
|
||||
while (!midi_devs[orig_dev]->putc(orig_dev, bytes[i]) &&
|
||||
timeout < 1000)
|
||||
timeout++;
|
||||
}
|
||||
if (!sysex_state[dev])
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
@ -1,49 +0,0 @@
|
||||
int midi_synth_ioctl (int dev,
|
||||
unsigned int cmd, ioctl_arg arg);
|
||||
int midi_synth_kill_note (int dev, int channel, int note, int velocity);
|
||||
int midi_synth_set_instr (int dev, int channel, int instr_no);
|
||||
int midi_synth_start_note (int dev, int channel, int note, int volume);
|
||||
void midi_synth_reset (int dev);
|
||||
int midi_synth_open (int dev, int mode);
|
||||
void midi_synth_close (int dev);
|
||||
void midi_synth_hw_control (int dev, unsigned char *event);
|
||||
int midi_synth_load_patch (int dev, int format, snd_rw_buf * addr,
|
||||
int offs, int count, int pmgr_flag);
|
||||
void midi_synth_panning (int dev, int channel, int pressure);
|
||||
void midi_synth_aftertouch (int dev, int channel, int pressure);
|
||||
void midi_synth_controller (int dev, int channel, int ctrl_num, int value);
|
||||
int midi_synth_patchmgr (int dev, struct patmgr_info *rec);
|
||||
void midi_synth_bender (int dev, int chn, int value);
|
||||
void midi_synth_setup_voice (int dev, int voice, int chn);
|
||||
int midi_synth_send_sysex(int dev, unsigned char *bytes,int len);
|
||||
|
||||
#ifndef _MIDI_SYNTH_C_
|
||||
static struct synth_info std_synth_info =
|
||||
{MIDI_SYNTH_NAME, 0, SYNTH_TYPE_MIDI, 0, 0, 128, 0, 128, MIDI_SYNTH_CAPS};
|
||||
|
||||
static struct synth_operations std_midi_synth =
|
||||
{
|
||||
&std_synth_info,
|
||||
0,
|
||||
SYNTH_TYPE_MIDI,
|
||||
0,
|
||||
midi_synth_open,
|
||||
midi_synth_close,
|
||||
midi_synth_ioctl,
|
||||
midi_synth_kill_note,
|
||||
midi_synth_start_note,
|
||||
midi_synth_set_instr,
|
||||
midi_synth_reset,
|
||||
midi_synth_hw_control,
|
||||
midi_synth_load_patch,
|
||||
midi_synth_aftertouch,
|
||||
midi_synth_controller,
|
||||
midi_synth_panning,
|
||||
NULL,
|
||||
midi_synth_patchmgr,
|
||||
midi_synth_bender,
|
||||
NULL, /* alloc_voice */
|
||||
midi_synth_setup_voice,
|
||||
midi_synth_send_sysex
|
||||
};
|
||||
#endif
|
@ -1,431 +0,0 @@
|
||||
/*
|
||||
* sound/midibuf.c
|
||||
*
|
||||
* Device file manager for /dev/midi#
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
|
||||
#if defined(CONFIG_MIDI)
|
||||
|
||||
#include <sys/select.h>
|
||||
|
||||
/*
|
||||
* Don't make MAX_QUEUE_SIZE larger than 4000
|
||||
*/
|
||||
|
||||
#define MAX_QUEUE_SIZE 4000
|
||||
int
|
||||
MIDIbuf_poll (int dev, struct fileinfo *file, int events, select_table * wait);
|
||||
|
||||
static void
|
||||
drain_midi_queue(int dev);
|
||||
|
||||
static int *midi_sleeper[MAX_MIDI_DEV] = {NULL};
|
||||
static volatile struct snd_wait midi_sleep_flag[MAX_MIDI_DEV] = { {0}};
|
||||
static int *input_sleeper[MAX_MIDI_DEV] = {NULL};
|
||||
static volatile struct snd_wait input_sleep_flag[MAX_MIDI_DEV] = { {0}};
|
||||
|
||||
struct midi_buf {
|
||||
int len, head, tail;
|
||||
u_char queue[MAX_QUEUE_SIZE];
|
||||
};
|
||||
|
||||
struct midi_parms {
|
||||
int prech_timeout; /* Timeout before the first ch */
|
||||
};
|
||||
|
||||
static struct midi_buf *midi_out_buf[MAX_MIDI_DEV] = {NULL};
|
||||
static struct midi_buf *midi_in_buf[MAX_MIDI_DEV] = {NULL};
|
||||
static struct midi_parms parms[MAX_MIDI_DEV];
|
||||
|
||||
static void midi_poll(void *dummy);
|
||||
|
||||
static volatile int open_devs = 0;
|
||||
|
||||
#define DATA_AVAIL(q) (q->len)
|
||||
#define SPACE_AVAIL(q) (MAX_QUEUE_SIZE - q->len)
|
||||
|
||||
#define QUEUE_BYTE(q, data) \
|
||||
if (SPACE_AVAIL(q)) { \
|
||||
u_long flags; \
|
||||
flags = splhigh(); \
|
||||
q->queue[q->tail] = (data); \
|
||||
q->len++; q->tail = (q->tail+1) % MAX_QUEUE_SIZE; \
|
||||
splx(flags); \
|
||||
}
|
||||
|
||||
#define REMOVE_BYTE(q, data) \
|
||||
if (DATA_AVAIL(q)) { \
|
||||
u_long flags; \
|
||||
flags = splhigh(); \
|
||||
data = q->queue[q->head]; \
|
||||
q->len--; q->head = (q->head+1) % MAX_QUEUE_SIZE; \
|
||||
splx(flags); \
|
||||
}
|
||||
|
||||
static void
|
||||
drain_midi_queue(int dev)
|
||||
{
|
||||
|
||||
/*
|
||||
* Give the Midi driver time to drain its output queues
|
||||
*/
|
||||
|
||||
if (midi_devs[dev]->buffer_status != NULL)
|
||||
while (!(PROCESS_ABORTING (midi_sleep_flag[dev])) &&
|
||||
midi_devs[dev]->buffer_status(dev)) {
|
||||
int chn;
|
||||
|
||||
midi_sleeper[dev] = &chn;
|
||||
DO_SLEEP(chn, midi_sleep_flag[dev], hz / 10);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
static void
|
||||
midi_input_intr(int dev, u_char data)
|
||||
{
|
||||
if (midi_in_buf[dev] == NULL)
|
||||
return;
|
||||
|
||||
if (data == 0xfe) /* Active sensing */
|
||||
return; /* Ignore */
|
||||
|
||||
if (SPACE_AVAIL(midi_in_buf[dev])) {
|
||||
QUEUE_BYTE(midi_in_buf[dev], data);
|
||||
if ((input_sleep_flag[dev].mode & WK_SLEEP)) {
|
||||
input_sleep_flag[dev].mode = WK_WAKEUP;
|
||||
wakeup(input_sleeper[dev]);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
midi_output_intr(int dev)
|
||||
{
|
||||
/*
|
||||
* Currently NOP
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
midi_poll(void *dummy)
|
||||
{
|
||||
u_long flags;
|
||||
int dev;
|
||||
|
||||
flags = splhigh();
|
||||
if (open_devs) {
|
||||
for (dev = 0; dev < num_midis; dev++)
|
||||
if (midi_out_buf[dev] != NULL) {
|
||||
while (DATA_AVAIL(midi_out_buf[dev]) &&
|
||||
midi_devs[dev]->putc(dev,
|
||||
midi_out_buf[dev]->queue[midi_out_buf[dev]->head])) {
|
||||
midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
|
||||
midi_out_buf[dev]->len--;
|
||||
}
|
||||
|
||||
if (DATA_AVAIL(midi_out_buf[dev]) < 100 &&
|
||||
(midi_sleep_flag[dev].mode & WK_SLEEP)) {
|
||||
midi_sleep_flag[dev].mode = WK_WAKEUP;
|
||||
wakeup(midi_sleeper[dev]);
|
||||
};
|
||||
}
|
||||
timeout( midi_poll, 0, 1);; /* Come back later */
|
||||
}
|
||||
splx(flags);
|
||||
}
|
||||
|
||||
int
|
||||
MIDIbuf_open(int dev, struct fileinfo * file)
|
||||
{
|
||||
int mode, err;
|
||||
|
||||
dev = dev >> 4;
|
||||
mode = file->mode & O_ACCMODE;
|
||||
|
||||
if (num_midis > MAX_MIDI_DEV) {
|
||||
printf("Sound: FATAL ERROR: Too many midi interfaces\n");
|
||||
num_midis = MAX_MIDI_DEV;
|
||||
}
|
||||
if (dev < 0 || dev >= num_midis) {
|
||||
printf("Sound: Nonexistent MIDI interface %d\n", dev);
|
||||
return -(ENXIO);
|
||||
}
|
||||
/*
|
||||
* Interrupts disabled. Be careful
|
||||
*/
|
||||
|
||||
if ((err = midi_devs[dev]->open(dev, mode,
|
||||
midi_input_intr, midi_output_intr)) < 0) {
|
||||
return err;
|
||||
}
|
||||
parms[dev].prech_timeout = 0;
|
||||
|
||||
midi_in_buf[dev] = (struct midi_buf *) malloc(sizeof(struct midi_buf), M_TEMP, M_WAITOK);
|
||||
|
||||
if (midi_in_buf[dev] == NULL) {
|
||||
printf("midi: Can't allocate buffer\n");
|
||||
midi_devs[dev]->close(dev);
|
||||
return -(EIO);
|
||||
}
|
||||
midi_in_buf[dev]->len = midi_in_buf[dev]->head = midi_in_buf[dev]->tail = 0;
|
||||
|
||||
midi_out_buf[dev] = (struct midi_buf *) malloc(sizeof(struct midi_buf), M_TEMP, M_WAITOK);
|
||||
|
||||
if (midi_out_buf[dev] == NULL) {
|
||||
printf("midi: Can't allocate buffer\n");
|
||||
midi_devs[dev]->close(dev);
|
||||
free(midi_in_buf[dev], M_TEMP);
|
||||
midi_in_buf[dev] = NULL;
|
||||
return -(EIO);
|
||||
}
|
||||
midi_out_buf[dev]->len = midi_out_buf[dev]->head = midi_out_buf[dev]->tail = 0;
|
||||
open_devs++;
|
||||
|
||||
{
|
||||
midi_sleep_flag[dev].aborting = 0;
|
||||
midi_sleep_flag[dev].mode = WK_NONE;
|
||||
};
|
||||
{
|
||||
input_sleep_flag[dev].aborting = 0;
|
||||
input_sleep_flag[dev].mode = WK_NONE;
|
||||
};
|
||||
|
||||
if (open_devs < 2) { /* This was first open */
|
||||
{
|
||||
};
|
||||
|
||||
timeout( midi_poll, 0, 1);; /* Start polling */
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void
|
||||
MIDIbuf_release(int dev, struct fileinfo * file)
|
||||
{
|
||||
int mode;
|
||||
u_long flags;
|
||||
|
||||
dev = dev >> 4;
|
||||
mode = file->mode & O_ACCMODE;
|
||||
|
||||
if (dev < 0 || dev >= num_midis)
|
||||
return;
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
/*
|
||||
* Wait until the queue is empty
|
||||
*/
|
||||
|
||||
if (mode != OPEN_READ) {
|
||||
midi_devs[dev]->putc(dev, 0xfe); /* Active sensing to
|
||||
* shut the devices */
|
||||
|
||||
while (!(PROCESS_ABORTING (midi_sleep_flag[dev])) &&
|
||||
DATA_AVAIL(midi_out_buf[dev])) {
|
||||
int chn;
|
||||
midi_sleeper[dev] = &chn;
|
||||
DO_SLEEP(chn, midi_sleep_flag[dev], 0);
|
||||
|
||||
}; /* Sync */
|
||||
|
||||
drain_midi_queue(dev); /* Ensure the output queues are empty */
|
||||
}
|
||||
splx(flags);
|
||||
|
||||
midi_devs[dev]->close(dev);
|
||||
|
||||
free(midi_in_buf[dev], M_TEMP);
|
||||
free(midi_out_buf[dev], M_TEMP);
|
||||
midi_in_buf[dev] = NULL;
|
||||
midi_out_buf[dev] = NULL;
|
||||
if (open_devs < 2) {
|
||||
};
|
||||
open_devs--;
|
||||
}
|
||||
|
||||
int
|
||||
MIDIbuf_write(int dev, struct fileinfo * file, snd_rw_buf * buf, int count)
|
||||
{
|
||||
u_long flags;
|
||||
int c, n, i;
|
||||
u_char tmp_data;
|
||||
|
||||
dev = dev >> 4;
|
||||
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
c = 0;
|
||||
|
||||
while (c < count) {
|
||||
n = SPACE_AVAIL(midi_out_buf[dev]);
|
||||
|
||||
if (n == 0) { /* No space just now. We have to sleep */
|
||||
|
||||
{
|
||||
int chn;
|
||||
|
||||
midi_sleeper[dev] = &chn;
|
||||
DO_SLEEP(chn, midi_sleep_flag[dev], 0);
|
||||
};
|
||||
|
||||
if (PROCESS_ABORTING(midi_sleep_flag[dev])) {
|
||||
splx(flags);
|
||||
return -(EINTR);
|
||||
}
|
||||
n = SPACE_AVAIL(midi_out_buf[dev]);
|
||||
}
|
||||
if (n > (count - c))
|
||||
n = count - c;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
|
||||
if (uiomove((char *) &tmp_data, 1, buf)) {
|
||||
printf("sb: Bad copyin()!\n");
|
||||
};
|
||||
QUEUE_BYTE(midi_out_buf[dev], tmp_data);
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
splx(flags);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
MIDIbuf_read(int dev, struct fileinfo * file, snd_rw_buf * buf, int count)
|
||||
{
|
||||
int n, c = 0;
|
||||
u_long flags;
|
||||
u_char tmp_data;
|
||||
|
||||
dev = dev >> 4;
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
if (!DATA_AVAIL(midi_in_buf[dev])) { /* No data yet, wait */
|
||||
|
||||
{
|
||||
int chn;
|
||||
|
||||
|
||||
input_sleeper[dev] = &chn;
|
||||
DO_SLEEP(chn, input_sleep_flag[dev],
|
||||
parms[dev].prech_timeout);
|
||||
|
||||
};
|
||||
if (PROCESS_ABORTING(input_sleep_flag[dev]))
|
||||
c = -(EINTR); /* The user is getting restless */
|
||||
}
|
||||
if (c == 0 && DATA_AVAIL(midi_in_buf[dev])) { /* Got some bytes */
|
||||
n = DATA_AVAIL(midi_in_buf[dev]);
|
||||
if (n > count)
|
||||
n = count;
|
||||
c = 0;
|
||||
|
||||
while (c < n) {
|
||||
REMOVE_BYTE(midi_in_buf[dev], tmp_data);
|
||||
|
||||
if (uiomove((char *) &tmp_data, 1, buf)) {
|
||||
printf("sb: Bad copyout()!\n");
|
||||
};
|
||||
c++;
|
||||
}
|
||||
}
|
||||
splx(flags);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
int
|
||||
MIDIbuf_ioctl(int dev, struct fileinfo * file, u_int cmd, ioctl_arg arg)
|
||||
{
|
||||
int val;
|
||||
|
||||
dev = dev >> 4;
|
||||
|
||||
if (((cmd >> 8) & 0xff) == 'C') {
|
||||
if (midi_devs[dev]->coproc) /* Coprocessor ioctl */
|
||||
return midi_devs[dev]->coproc->ioctl(midi_devs[dev]->coproc->devc, cmd, arg, 0);
|
||||
else
|
||||
printf("/dev/midi%d: No coprocessor for this device\n", dev);
|
||||
|
||||
return -(ENXIO);
|
||||
} else
|
||||
switch (cmd) {
|
||||
|
||||
case SNDCTL_MIDI_PRETIME:
|
||||
val = (int) (*(int *) arg);
|
||||
if (val < 0)
|
||||
val = 0;
|
||||
|
||||
val = (hz * val) / 10;
|
||||
parms[dev].prech_timeout = val;
|
||||
return *(int *) arg = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
return midi_devs[dev]->ioctl(dev, cmd, arg);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ALLOW_POLL
|
||||
int
|
||||
MIDIbuf_poll (int dev, struct fileinfo *file, int events, select_table * wait)
|
||||
{
|
||||
int revents = 0;
|
||||
|
||||
dev = dev >> 4;
|
||||
|
||||
if (events & (POLLIN | POLLRDNORM))
|
||||
if (!DATA_AVAIL (midi_in_buf[dev]))
|
||||
selrecord(wait, &selinfo[dev]);
|
||||
else
|
||||
revents |= events & (POLLIN | POLLRDNORM);
|
||||
|
||||
if (events & (POLLOUT | POLLWRNORM))
|
||||
if (SPACE_AVAIL (midi_out_buf[dev]))
|
||||
selrecord(wait, &selinfo[dev]);
|
||||
else
|
||||
revents |= events & (POLLOUT | POLLWRNORM);
|
||||
|
||||
return revents;
|
||||
}
|
||||
|
||||
#endif /* ALLOW_SELECT */
|
||||
|
||||
|
||||
|
||||
#endif
|
@ -1,265 +0,0 @@
|
||||
/*
|
||||
* This is a simple program which demonstrates use of mmapped DMA buffer
|
||||
* of the sound driver directly from application program.
|
||||
*
|
||||
* This sample program works (currently) only with Linux, FreeBSD and BSD/OS
|
||||
* (FreeBSD and BSD/OS require OSS version 3.8-beta16 or later.
|
||||
*
|
||||
* Note! Don't use mmapped DMA buffers (direct audio) unless you have
|
||||
* very good reasons to do it. Programs using this feature will not
|
||||
* work with all soundcards. GUS (GF1) is one of them (GUS MAX works).
|
||||
*
|
||||
* This program requires version 3.5-beta7 or later of OSS
|
||||
* (3.8-beta16 or later in FreeBSD and BSD/OS).
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/soundcard.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
int fd, sz, fsz, tmp, nfrag;
|
||||
int caps;
|
||||
|
||||
int sd, sl=0, sp;
|
||||
|
||||
unsigned char data[500000], *dp = data;
|
||||
|
||||
caddr_t buf;
|
||||
struct timeval tim;
|
||||
|
||||
unsigned char *op;
|
||||
|
||||
struct audio_buf_info info;
|
||||
|
||||
int frag = 0xffff000c; /* Max # fragments of 2^13=8k bytes */
|
||||
|
||||
fd_set writeset;
|
||||
|
||||
close(0);
|
||||
if ((fd=open("/dev/dsp", O_RDWR, 0))==-1)
|
||||
err(1, "/dev/dsp");
|
||||
/*
|
||||
* Then setup sampling parameters. Just sampling rate in this case.
|
||||
*/
|
||||
|
||||
tmp = 8000;
|
||||
ioctl(fd, SNDCTL_DSP_SPEED, &tmp);
|
||||
|
||||
/*
|
||||
* Load some test data.
|
||||
*/
|
||||
|
||||
sl = sp = 0;
|
||||
if ((sd=open("smpl", O_RDONLY, 0))!=-1)
|
||||
{
|
||||
sl = read(sd, data, sizeof(data));
|
||||
printf("%d bytes read from file.\n", sl);
|
||||
close(sd);
|
||||
}
|
||||
else warn("smpl");
|
||||
|
||||
if (ioctl(fd, SNDCTL_DSP_GETCAPS, &caps)==-1)
|
||||
{
|
||||
warn("sorry but your sound driver is too old");
|
||||
err(1, "/dev/dsp");
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the device has capability to do this. Currently just
|
||||
* CS4231 based cards will work.
|
||||
*
|
||||
* The application should also check for DSP_CAP_MMAP bit but this
|
||||
* version of driver doesn't have it yet.
|
||||
*/
|
||||
/* ioctl(fd, SNDCTL_DSP_SETSYNCRO, 0); */
|
||||
|
||||
/*
|
||||
* You need version 3.5-beta7 or later of the sound driver before next
|
||||
* two lines compile. There is no point to modify this program to
|
||||
* compile with older driver versions since they don't have working
|
||||
* mmap() support.
|
||||
*/
|
||||
if (!(caps & DSP_CAP_TRIGGER) ||
|
||||
!(caps & DSP_CAP_MMAP))
|
||||
errx(1, "sorry but your soundcard can't do this");
|
||||
|
||||
/*
|
||||
* Select the fragment size. This is propably important only when
|
||||
* the program uses select(). Fragment size defines how often
|
||||
* select call returns.
|
||||
*/
|
||||
|
||||
ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag);
|
||||
|
||||
/*
|
||||
* Compute total size of the buffer. It's important to use this value
|
||||
* in mmap() call.
|
||||
*/
|
||||
|
||||
if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info)==-1)
|
||||
err(1, "GETOSPACE");
|
||||
|
||||
sz = info.fragstotal * info.fragsize;
|
||||
fsz = info.fragsize;
|
||||
/*
|
||||
* Call mmap().
|
||||
*
|
||||
* IMPORTANT NOTE!!!!!!!!!!!
|
||||
*
|
||||
* Full duplex audio devices have separate input and output buffers.
|
||||
* It is not possible to map both of them at the same mmap() call. The buffer
|
||||
* is selected based on the prot argument in the following way:
|
||||
*
|
||||
* - PROT_READ (alone) selects the input buffer.
|
||||
* - PROT_WRITE (alone) selects the output buffer.
|
||||
* - PROT_WRITE|PROT_READ together select the output buffer. This combination
|
||||
* is required in BSD to make the buffer accessible. With just PROT_WRITE
|
||||
* every attempt to access the returned buffer will result in segmentation/bus
|
||||
* error. PROT_READ|PROT_WRITE is also permitted in Linux with OSS version
|
||||
* 3.8-beta16 and later (earlier versions don't accept it).
|
||||
*
|
||||
* Non duplex devices have just one buffer. When an application wants to do both
|
||||
* input and output it's recommended that the device is closed and re-opened when
|
||||
* switching between modes. PROT_READ|PROT_WRITE can be used to open the buffer
|
||||
* for both input and output (with OSS 3.8-beta16 and later) but the result may be
|
||||
* unpredictable.
|
||||
*/
|
||||
|
||||
if ((buf=mmap(NULL, sz, PROT_WRITE | PROT_READ, MAP_FILE|MAP_SHARED, fd, 0))==(caddr_t)-1)
|
||||
err(1, "mmap (write)");
|
||||
printf("mmap (out) returned %08x\n", buf);
|
||||
op=buf;
|
||||
|
||||
/*
|
||||
* op contains now a pointer to the DMA buffer
|
||||
*/
|
||||
|
||||
/*
|
||||
* Then it's time to start the engine. The driver doesn't allow read() and/or
|
||||
* write() when the buffer is mapped. So the only way to start operation is
|
||||
* to togle device's enable bits. First set them off. Setting them on enables
|
||||
* recording and/or playback.
|
||||
*/
|
||||
|
||||
tmp = 0;
|
||||
ioctl(fd, SNDCTL_DSP_SETTRIGGER, &tmp);
|
||||
|
||||
/*
|
||||
* It might be usefull to write some data to the buffer before starting.
|
||||
*/
|
||||
|
||||
tmp = PCM_ENABLE_OUTPUT;
|
||||
ioctl(fd, SNDCTL_DSP_SETTRIGGER, &tmp);
|
||||
|
||||
/*
|
||||
* The machine is up and running now. Use SNDCTL_DSP_GETOPTR to get the
|
||||
* buffer status.
|
||||
*
|
||||
* NOTE! The driver empties each buffer fragmen after they have been
|
||||
* played. This prevents looping sound if there are some performance problems
|
||||
* in the application side. For similar reasons it recommended that the
|
||||
* application uses some amout of play ahead. It can rewrite the unplayed
|
||||
* data later if necessary.
|
||||
*/
|
||||
|
||||
nfrag = 0;
|
||||
while (1)
|
||||
{
|
||||
struct count_info count;
|
||||
int extra;
|
||||
|
||||
FD_ZERO(&writeset);
|
||||
FD_SET(fd, &writeset);
|
||||
|
||||
tim.tv_sec = 10;
|
||||
tim.tv_usec= 0;
|
||||
|
||||
select(fd+1, &writeset, &writeset, NULL, NULL);
|
||||
/*
|
||||
* SNDCTL_DSP_GETOPTR (and GETIPTR as well) return three items. The
|
||||
* bytes field returns number of bytes played since start. It can be used
|
||||
* as a real time clock.
|
||||
*
|
||||
* The blocks field returns number of fragment transitions (interrupts) since
|
||||
* previous GETOPTR call. It can be used as a method to detect underrun
|
||||
* situations.
|
||||
*
|
||||
* The ptr field is the DMA pointer inside the buffer area (in bytes from
|
||||
* the beginning of total buffer area).
|
||||
*/
|
||||
|
||||
if (ioctl(fd, SNDCTL_DSP_GETOPTR, &count)==-1)
|
||||
err(1, "GETOPTR");
|
||||
if (count.ptr < 0 ) count.ptr = 0;
|
||||
nfrag += count.blocks;
|
||||
|
||||
|
||||
#ifdef VERBOSE
|
||||
|
||||
printf("\rTotal: %09d, Fragment: %03d, Ptr: %06d",
|
||||
count.bytes, nfrag, count.ptr);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Caution! This version doesn't check for bounds of the DMA
|
||||
* memory area. It's possible that the returned pointer value is not aligned
|
||||
* to fragment boundaries. It may be several samples behind the boundary
|
||||
* in case there was extra delay between the actual hardware interrupt and
|
||||
* the time when DSP_GETOPTR was called.
|
||||
*
|
||||
* Don't just call memcpy() with length set to 'fragment_size' without
|
||||
* first checking that the transfer really fits to the buffer area.
|
||||
* A mistake of just one byte causes seg fault. It may be easiest just
|
||||
* to align the returned pointer value to fragment boundary before using it.
|
||||
*
|
||||
* It would be very good idea to write few extra samples to next fragment
|
||||
* too. Otherwise several (uninitialized) samples from next fragment
|
||||
* will get played before your program gets chance to initialize them.
|
||||
* Take in count the fact thaat there are other processes batling about
|
||||
* the same CPU. This effect is likely to be very annoying if fragment
|
||||
* size is decreased too much.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Just a minor clarification to the above. The following line alings
|
||||
* the pointer to fragment boundaries. Note! Don't trust that fragment
|
||||
* size is always a power of 2. It may not be so in future.
|
||||
*/
|
||||
count.ptr = ((count.ptr+16)/fsz )*fsz;
|
||||
#ifdef VERBOSE
|
||||
printf(" memcpy(%6d, %4d)", (dp-data), fsz);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set few bytes in the beginning of next fragment too.
|
||||
*/
|
||||
|
||||
if ((count.ptr+fsz+16) < sz) /* Last fragment? */
|
||||
extra = 16;
|
||||
else
|
||||
extra = 0;
|
||||
memcpy(op+count.ptr, dp, (fsz+extra));
|
||||
dp += fsz;
|
||||
if (dp > (data+sl-fsz))
|
||||
dp = data;
|
||||
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,261 +0,0 @@
|
||||
/*
|
||||
* opl3.h - Definitions of the OPL-3 registers
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The OPL-3 mode is switched on by writing 0x01, to the offset 5
|
||||
* of the right side.
|
||||
*
|
||||
* Another special register at the right side is at offset 4. It contains
|
||||
* a bit mask defining which voices are used as 4 OP voices.
|
||||
*
|
||||
* The percussive mode is implemented in the left side only.
|
||||
*
|
||||
* With the above exeptions the both sides can be operated independently.
|
||||
*
|
||||
* A 4 OP voice can be created by setting the corresponding
|
||||
* bit at offset 4 of the right side.
|
||||
*
|
||||
* For example setting the rightmost bit (0x01) changes the
|
||||
* first voice on the right side to the 4 OP mode. The fourth
|
||||
* voice is made inaccessible.
|
||||
*
|
||||
* If a voice is set to the 2 OP mode, it works like 2 OP modes
|
||||
* of the original YM3812 (AdLib). In addition the voice can
|
||||
* be connected the left, right or both stereo channels. It can
|
||||
* even be left unconnected. This works with 4 OP voices also.
|
||||
*
|
||||
* The stereo connection bits are located in the FEEDBACK_CONNECTION
|
||||
* register of the voice (0xC0-0xC8). In 4 OP voices these bits are
|
||||
* in the second half of the voice.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Register numbers for the global registers
|
||||
*/
|
||||
|
||||
#define TEST_REGISTER 0x01
|
||||
#define ENABLE_WAVE_SELECT 0x20
|
||||
|
||||
#define TIMER1_REGISTER 0x02
|
||||
#define TIMER2_REGISTER 0x03
|
||||
#define TIMER_CONTROL_REGISTER 0x04 /* Left side */
|
||||
#define IRQ_RESET 0x80
|
||||
#define TIMER1_MASK 0x40
|
||||
#define TIMER2_MASK 0x20
|
||||
#define TIMER1_START 0x01
|
||||
#define TIMER2_START 0x02
|
||||
|
||||
#define CONNECTION_SELECT_REGISTER 0x04 /* Right side */
|
||||
#define RIGHT_4OP_0 0x01
|
||||
#define RIGHT_4OP_1 0x02
|
||||
#define RIGHT_4OP_2 0x04
|
||||
#define LEFT_4OP_0 0x08
|
||||
#define LEFT_4OP_1 0x10
|
||||
#define LEFT_4OP_2 0x20
|
||||
|
||||
#define OPL3_MODE_REGISTER 0x05 /* Right side */
|
||||
#define OPL3_ENABLE 0x01
|
||||
#define OPL4_ENABLE 0x02
|
||||
|
||||
#define KBD_SPLIT_REGISTER 0x08 /* Left side */
|
||||
#define COMPOSITE_SINE_WAVE_MODE 0x80 /* Don't use with OPL-3? */
|
||||
#define KEYBOARD_SPLIT 0x40
|
||||
|
||||
#define PERCUSSION_REGISTER 0xbd /* Left side only */
|
||||
#define TREMOLO_DEPTH 0x80
|
||||
#define VIBRATO_DEPTH 0x40
|
||||
#define PERCUSSION_ENABLE 0x20
|
||||
#define BASSDRUM_ON 0x10
|
||||
#define SNAREDRUM_ON 0x08
|
||||
#define TOMTOM_ON 0x04
|
||||
#define CYMBAL_ON 0x02
|
||||
#define HIHAT_ON 0x01
|
||||
|
||||
/*
|
||||
* Offsets to the register banks for operators. To get the
|
||||
* register number just add the operator offset to the bank offset
|
||||
*
|
||||
* AM/VIB/EG/KSR/Multiple (0x20 to 0x35)
|
||||
*/
|
||||
#define AM_VIB 0x20
|
||||
#define TREMOLO_ON 0x80
|
||||
#define VIBRATO_ON 0x40
|
||||
#define SUSTAIN_ON 0x20
|
||||
#define KSR 0x10 /* Key scaling rate */
|
||||
#define MULTIPLE_MASK 0x0f /* Frequency multiplier */
|
||||
|
||||
/*
|
||||
* KSL/Total level (0x40 to 0x55)
|
||||
*/
|
||||
#define KSL_LEVEL 0x40
|
||||
#define KSL_MASK 0xc0 /* Envelope scaling bits */
|
||||
#define TOTAL_LEVEL_MASK 0x3f /* Strength (volume) of OP */
|
||||
|
||||
/*
|
||||
* Attack / Decay rate (0x60 to 0x75)
|
||||
*/
|
||||
#define ATTACK_DECAY 0x60
|
||||
#define ATTACK_MASK 0xf0
|
||||
#define DECAY_MASK 0x0f
|
||||
|
||||
/*
|
||||
* Sustain level / Release rate (0x80 to 0x95)
|
||||
*/
|
||||
#define SUSTAIN_RELEASE 0x80
|
||||
#define SUSTAIN_MASK 0xf0
|
||||
#define RELEASE_MASK 0x0f
|
||||
|
||||
/*
|
||||
* Wave select (0xE0 to 0xF5)
|
||||
*/
|
||||
#define WAVE_SELECT 0xe0
|
||||
|
||||
/*
|
||||
* Offsets to the register banks for voices. Just add to the
|
||||
* voice number to get the register number.
|
||||
*
|
||||
* F-Number low bits (0xA0 to 0xA8).
|
||||
*/
|
||||
#define FNUM_LOW 0xa0
|
||||
|
||||
/*
|
||||
* F-number high bits / Key on / Block (octave) (0xB0 to 0xB8)
|
||||
*/
|
||||
#define KEYON_BLOCK 0xb0
|
||||
#define KEYON_BIT 0x20
|
||||
#define BLOCKNUM_MASK 0x1c
|
||||
#define FNUM_HIGH_MASK 0x03
|
||||
|
||||
/*
|
||||
* Feedback / Connection (0xc0 to 0xc8)
|
||||
*
|
||||
* These registers have two new bits when the OPL-3 mode
|
||||
* is selected. These bits controls connecting the voice
|
||||
* to the stereo channels. For 4 OP voices this bit is
|
||||
* defined in the second half of the voice (add 3 to the
|
||||
* register offset).
|
||||
*
|
||||
* For 4 OP voices the connection bit is used in the
|
||||
* both halfs (gives 4 ways to connect the operators).
|
||||
*/
|
||||
#define FEEDBACK_CONNECTION 0xc0
|
||||
#define FEEDBACK_MASK 0x0e /* Valid just for 1st OP of a voice */
|
||||
#define CONNECTION_BIT 0x01
|
||||
/*
|
||||
* In the 4 OP mode there is four possible configurations how the
|
||||
* operators can be connected together (in 2 OP modes there is just
|
||||
* AM or FM). The 4 OP connection mode is defined by the rightmost
|
||||
* bit of the FEEDBACK_CONNECTION (0xC0-0xC8) on the both halfs.
|
||||
*
|
||||
* First half Second half Mode
|
||||
*
|
||||
* +---+
|
||||
* v |
|
||||
* 0 0 >+-1-+--2--3--4-->
|
||||
*
|
||||
*
|
||||
*
|
||||
* +---+
|
||||
* | |
|
||||
* 0 1 >+-1-+--2-+
|
||||
* |->
|
||||
* >--3----4-+
|
||||
*
|
||||
* +---+
|
||||
* | |
|
||||
* 1 0 >+-1-+-----+
|
||||
* |->
|
||||
* >--2--3--4-+
|
||||
*
|
||||
* +---+
|
||||
* | |
|
||||
* 1 1 >+-1-+--+
|
||||
* |
|
||||
* >--2--3-+->
|
||||
* |
|
||||
* >--4----+
|
||||
*/
|
||||
#define STEREO_BITS 0x30 /* OPL-3 only */
|
||||
#define VOICE_TO_LEFT 0x10
|
||||
#define VOICE_TO_RIGHT 0x20
|
||||
|
||||
/*
|
||||
* Definition table for the physical voices
|
||||
*/
|
||||
|
||||
struct physical_voice_info {
|
||||
unsigned char voice_num;
|
||||
unsigned char voice_mode; /* 0=unavailable, 2=2 OP, 4=4 OP */
|
||||
unsigned short ioaddr; /* I/O port (left or right side) */
|
||||
unsigned char op[4]; /* Operator offsets */
|
||||
};
|
||||
|
||||
/*
|
||||
* There is 18 possible 2 OP voices
|
||||
* (9 in the left and 9 in the right).
|
||||
* The first OP is the modulator and 2nd is the carrier.
|
||||
*
|
||||
* The first three voices in the both sides may be connected
|
||||
* with another voice to a 4 OP voice. For example voice 0
|
||||
* can be connected with voice 3. The operators of voice 3 are
|
||||
* used as operators 3 and 4 of the new 4 OP voice.
|
||||
* In this case the 2 OP voice number 0 is the 'first half' and
|
||||
* voice 3 is the second.
|
||||
*/
|
||||
|
||||
#define USE_LEFT 0
|
||||
#define USE_RIGHT 1
|
||||
|
||||
static struct physical_voice_info pv_map[18] =
|
||||
{
|
||||
/* No Mode Side OP1 OP2 OP3 OP4 */
|
||||
/* --------------------------------------------------- */
|
||||
{ 0, 2, USE_LEFT, {0x00, 0x03, 0x08, 0x0b}},
|
||||
{ 1, 2, USE_LEFT, {0x01, 0x04, 0x09, 0x0c}},
|
||||
{ 2, 2, USE_LEFT, {0x02, 0x05, 0x0a, 0x0d}},
|
||||
|
||||
{ 3, 2, USE_LEFT, {0x08, 0x0b, 0x00, 0x00}},
|
||||
{ 4, 2, USE_LEFT, {0x09, 0x0c, 0x00, 0x00}},
|
||||
{ 5, 2, USE_LEFT, {0x0a, 0x0d, 0x00, 0x00}},
|
||||
|
||||
{ 6, 2, USE_LEFT, {0x10, 0x13, 0x00, 0x00}}, /* Used by percussive voices */
|
||||
{ 7, 2, USE_LEFT, {0x11, 0x14, 0x00, 0x00}}, /* if the percussive mode */
|
||||
{ 8, 2, USE_LEFT, {0x12, 0x15, 0x00, 0x00}}, /* is selected */
|
||||
|
||||
{ 0, 2, USE_RIGHT, {0x00, 0x03, 0x08, 0x0b}},
|
||||
{ 1, 2, USE_RIGHT, {0x01, 0x04, 0x09, 0x0c}},
|
||||
{ 2, 2, USE_RIGHT, {0x02, 0x05, 0x0a, 0x0d}},
|
||||
|
||||
{ 3, 2, USE_RIGHT, {0x08, 0x0b, 0x00, 0x00}},
|
||||
{ 4, 2, USE_RIGHT, {0x09, 0x0c, 0x00, 0x00}},
|
||||
{ 5, 2, USE_RIGHT, {0x0a, 0x0d, 0x00, 0x00}},
|
||||
|
||||
{ 6, 2, USE_RIGHT, {0x10, 0x13, 0x00, 0x00}},
|
||||
{ 7, 2, USE_RIGHT, {0x11, 0x14, 0x00, 0x00}},
|
||||
{ 8, 2, USE_RIGHT, {0x12, 0x15, 0x00, 0x00}}
|
||||
};
|
@ -1,101 +0,0 @@
|
||||
/*
|
||||
* os.h -- only included by sound_config.h right after local.h
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _OS_H_
|
||||
#define _OS_H_
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/filio.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/signalvar.h>
|
||||
|
||||
#include <sys/soundcard.h>
|
||||
|
||||
#include <i386/isa/isa_device.h>
|
||||
|
||||
#undef DELAY
|
||||
#define DELAY(x) tenmicrosec(x)
|
||||
typedef struct uio snd_rw_buf;
|
||||
|
||||
struct snd_wait {
|
||||
int mode;
|
||||
int aborting;
|
||||
};
|
||||
|
||||
|
||||
unsigned long get_time(void);
|
||||
|
||||
#endif /* _OS_H_ */
|
||||
|
||||
typedef caddr_t ioctl_arg;
|
||||
|
||||
typedef struct sound_os_info {
|
||||
int unit;
|
||||
} sound_os_info;
|
||||
|
||||
|
||||
/*
|
||||
* The following macro calls tsleep. It should be implemented such that
|
||||
* the process is resumed if it receives a signal.
|
||||
* The q parameter is a wait_queue defined with DEFINE_WAIT_QUEUE(),
|
||||
* and the second is a workarea parameter. The third is a timeout
|
||||
* in ticks. Zero means no timeout.
|
||||
*/
|
||||
#define DO_SLEEP(q, f, time_limit) \
|
||||
{ \
|
||||
int flag; \
|
||||
f.mode = WK_SLEEP; \
|
||||
flag=tsleep(&q, (PRIBIO-5)|PCATCH, "sndint", time_limit); \
|
||||
f.mode &= ~WK_SLEEP; \
|
||||
if (flag == EWOULDBLOCK) { \
|
||||
f.mode |= WK_TIMEOUT; \
|
||||
f.aborting = 0; \
|
||||
} else \
|
||||
f.aborting = flag; \
|
||||
}
|
||||
|
||||
#define DO_SLEEP1(q, f, time_limit) \
|
||||
{ \
|
||||
int flag; \
|
||||
f.mode = WK_SLEEP; \
|
||||
flag=tsleep(&q, (PRIBIO-5)|PCATCH, "snd1", time_limit); \
|
||||
f.mode &= ~WK_SLEEP; \
|
||||
if (flag == EWOULDBLOCK) { \
|
||||
f.mode |= WK_TIMEOUT; \
|
||||
f.aborting = 0; \
|
||||
} else \
|
||||
f.aborting = flag; \
|
||||
}
|
||||
|
||||
#define DO_SLEEP2(q, f, time_limit) \
|
||||
{ \
|
||||
int flag; \
|
||||
f.mode = WK_SLEEP; \
|
||||
flag=tsleep(&q, (PRIBIO-5)|PCATCH, "snd2", time_limit); \
|
||||
f.mode &= ~WK_SLEEP; \
|
||||
if (flag == EWOULDBLOCK) { \
|
||||
f.mode |= WK_TIMEOUT; \
|
||||
f.aborting = 0; \
|
||||
} else \
|
||||
f.aborting = flag; \
|
||||
}
|
||||
|
||||
#define PROCESS_ABORTING( f) (f.aborting || CURSIG(curproc))
|
||||
#define TIMED_OUT( f) (f.mode & WK_TIMEOUT)
|
||||
|
||||
#ifdef ALLOW_POLL
|
||||
typedef struct proc select_table;
|
||||
extern struct selinfo selinfo[];
|
||||
#endif
|
@ -1,361 +0,0 @@
|
||||
/*
|
||||
* sound/pas2_card.c
|
||||
*
|
||||
* Detection routine for the Pro Audio Spectrum cards.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if defined(CONFIG_PAS)
|
||||
#define _PAS2_CARD_C_
|
||||
|
||||
#define DEFINE_TRANSLATIONS
|
||||
#include <i386/isa/sound/pas_hw.h>
|
||||
|
||||
/*
|
||||
* The Address Translation code is used to convert I/O register addresses to
|
||||
* be relative to the given base -register
|
||||
*/
|
||||
|
||||
int translat_code;
|
||||
static int pas_intr_mask = 0;
|
||||
static int pas_irq = 0;
|
||||
|
||||
static sound_os_info *pas_osp;
|
||||
|
||||
char pas_model;
|
||||
static char *pas_model_names[] =
|
||||
{"", "Pro AudioSpectrum+", "CDPC", "Pro AudioSpectrum 16", "Pro AudioSpectrum 16D"};
|
||||
|
||||
/*
|
||||
* pas_read() and pas_write() are equivalents of inb and outb
|
||||
*/
|
||||
/*
|
||||
* These routines perform the I/O address translation required
|
||||
*/
|
||||
/*
|
||||
* to support other than the default base address
|
||||
*/
|
||||
extern void mix_write(u_char data, int ioaddr);
|
||||
|
||||
u_char
|
||||
pas_read(int ioaddr)
|
||||
{
|
||||
return inb(ioaddr ^ translat_code);
|
||||
}
|
||||
|
||||
void
|
||||
pas_write(u_char data, int ioaddr)
|
||||
{
|
||||
outb(ioaddr ^ translat_code, data);
|
||||
}
|
||||
|
||||
static void
|
||||
pas2_msg(char *foo)
|
||||
{
|
||||
printf(" PAS2: %s.\n", foo);
|
||||
}
|
||||
|
||||
/******************* Begin of the Interrupt Handler ********************/
|
||||
|
||||
void
|
||||
pasintr(int irq)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = pas_read(INTERRUPT_STATUS);
|
||||
pas_write(status, INTERRUPT_STATUS); /* Clear interrupt */
|
||||
|
||||
if (status & I_S_PCM_SAMPLE_BUFFER_IRQ) {
|
||||
#ifdef CONFIG_AUDIO
|
||||
pas_pcm_interrupt(status, 1);
|
||||
#endif
|
||||
status &= ~I_S_PCM_SAMPLE_BUFFER_IRQ;
|
||||
}
|
||||
if (status & I_S_MIDI_IRQ) {
|
||||
#ifdef CONFIG_MIDI
|
||||
pas_midi_interrupt();
|
||||
#endif
|
||||
status &= ~I_S_MIDI_IRQ;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
pas_set_intr(int mask)
|
||||
{
|
||||
if (!mask)
|
||||
return 0;
|
||||
|
||||
pas_intr_mask |= mask;
|
||||
|
||||
pas_write(pas_intr_mask, INTERRUPT_MASK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pas_remove_intr(int mask)
|
||||
{
|
||||
if (!mask)
|
||||
return 0;
|
||||
|
||||
pas_intr_mask &= ~mask;
|
||||
pas_write(pas_intr_mask, INTERRUPT_MASK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************* End of the Interrupt handler **********************/
|
||||
|
||||
/******************* Begin of the Initialization Code ******************/
|
||||
|
||||
static int
|
||||
config_pas_hw(struct address_info * hw_config)
|
||||
{
|
||||
char ok = 1;
|
||||
u_int int_ptrs; /* scsi/sound interrupt pointers */
|
||||
|
||||
pas_irq = hw_config->irq;
|
||||
|
||||
pas_write(0x00, INTERRUPT_MASK);
|
||||
|
||||
pas_write(0x36, SAMPLE_COUNTER_CONTROL); /* Local timer control *
|
||||
* register */
|
||||
|
||||
pas_write(0x36, SAMPLE_RATE_TIMER); /* Sample rate timer (16 bit) */
|
||||
pas_write(0, SAMPLE_RATE_TIMER);
|
||||
|
||||
pas_write(0x74, SAMPLE_COUNTER_CONTROL); /* Local timer control *
|
||||
* register */
|
||||
|
||||
pas_write(0x74, SAMPLE_BUFFER_COUNTER); /* Sample count register (16 *
|
||||
* bit) */
|
||||
pas_write(0, SAMPLE_BUFFER_COUNTER);
|
||||
|
||||
pas_write(F_F_PCM_BUFFER_COUNTER | F_F_PCM_RATE_COUNTER | F_F_MIXER_UNMUTE | 1, FILTER_FREQUENCY);
|
||||
pas_write(P_C_PCM_DMA_ENABLE | P_C_PCM_MONO | P_C_PCM_DAC_MODE | P_C_MIXER_CROSS_L_TO_L | P_C_MIXER_CROSS_R_TO_R, PCM_CONTROL);
|
||||
pas_write(S_M_PCM_RESET | S_M_FM_RESET | S_M_SB_RESET | S_M_MIXER_RESET /* | S_M_OPL3_DUAL_MONO */ , SERIAL_MIXER);
|
||||
|
||||
pas_write(I_C_1_BOOT_RESET_ENABLE
|
||||
#ifdef PAS_JOYSTICK_ENABLE
|
||||
| I_C_1_JOYSTICK_ENABLE
|
||||
#endif
|
||||
,IO_CONFIGURATION_1);
|
||||
|
||||
if (pas_irq < 0 || pas_irq > 15) {
|
||||
printf("PAS2: Invalid IRQ %d", pas_irq);
|
||||
ok = 0;
|
||||
} else {
|
||||
int_ptrs = pas_read(IO_CONFIGURATION_3);
|
||||
int_ptrs |= I_C_3_PCM_IRQ_translate[pas_irq] & 0xf;
|
||||
pas_write(int_ptrs, IO_CONFIGURATION_3);
|
||||
if (!I_C_3_PCM_IRQ_translate[pas_irq]) {
|
||||
printf("PAS2: Invalid IRQ %d", pas_irq);
|
||||
ok = 0;
|
||||
} else {
|
||||
if (snd_set_irq_handler(pas_irq, pasintr, hw_config->osp) < 0)
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (hw_config->dma < 0 || hw_config->dma > 7) {
|
||||
printf("PAS2: Invalid DMA selection %d", hw_config->dma);
|
||||
ok = 0;
|
||||
} else {
|
||||
pas_write(I_C_2_PCM_DMA_translate[hw_config->dma], IO_CONFIGURATION_2);
|
||||
if (!I_C_2_PCM_DMA_translate[hw_config->dma]) {
|
||||
printf("PAS2: Invalid DMA selection %d", hw_config->dma);
|
||||
ok = 0;
|
||||
} else {
|
||||
if (0) {
|
||||
printf("pas2_card.c: Can't allocate DMA channel\n");
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This fixes the timing problems of the PAS due to the Symphony
|
||||
* chipset as per Media Vision. Only define this if your PAS doesn't
|
||||
* work correctly.
|
||||
*/
|
||||
#ifdef SYMPHONY_PAS
|
||||
outb(0xa8, 0x05);
|
||||
outb(0xa9, 0x60);
|
||||
#endif
|
||||
|
||||
#ifdef BROKEN_BUS_CLOCK
|
||||
pas_write(S_C_1_PCS_ENABLE | S_C_1_PCS_STEREO | S_C_1_PCS_REALSOUND | S_C_1_FM_EMULATE_CLOCK, SYSTEM_CONFIGURATION_1);
|
||||
#else
|
||||
/*
|
||||
* pas_write(S_C_1_PCS_ENABLE, SYSTEM_CONFIGURATION_1);
|
||||
*/
|
||||
pas_write(S_C_1_PCS_ENABLE | S_C_1_PCS_STEREO | S_C_1_PCS_REALSOUND, SYSTEM_CONFIGURATION_1);
|
||||
#endif
|
||||
pas_write(0x18, SYSTEM_CONFIGURATION_3); /* ??? */
|
||||
|
||||
pas_write(F_F_MIXER_UNMUTE | 0x01, FILTER_FREQUENCY); /* Sets mute off and *
|
||||
* selects filter rate *
|
||||
* of 17.897 kHz */
|
||||
pas_write(8, PRESCALE_DIVIDER);
|
||||
|
||||
mix_write(P_M_MV508_ADDRESS | 5, PARALLEL_MIXER);
|
||||
mix_write(5, PARALLEL_MIXER);
|
||||
|
||||
#if defined(CONFIG_SB_EMULATION) && defined(CONFIG_SB)
|
||||
|
||||
{
|
||||
struct address_info *sb_config;
|
||||
|
||||
if ((sb_config = sound_getconf(SNDCARD_SB))) {
|
||||
u_char irq_dma;
|
||||
|
||||
/*
|
||||
* Turn on Sound Blaster compatibility
|
||||
*/
|
||||
/*
|
||||
* bit 1 = SB emulation
|
||||
*/
|
||||
/*
|
||||
* bit 0 = MPU401 emulation (CDPC only :-( )
|
||||
*/
|
||||
pas_write(0x02, COMPATIBILITY_ENABLE);
|
||||
|
||||
/*
|
||||
* "Emulation address"
|
||||
*/
|
||||
pas_write((sb_config->io_base >> 4) & 0x0f, EMULATION_ADDRESS);
|
||||
|
||||
if (!E_C_SB_DMA_translate[sb_config->dma])
|
||||
printf("\n\nPAS16 Warning: Invalid SB DMA %d\n\n",
|
||||
sb_config->dma);
|
||||
|
||||
if (!E_C_SB_IRQ_translate[sb_config->irq])
|
||||
printf("\n\nPAS16 Warning: Invalid SB IRQ %d\n\n",
|
||||
sb_config->irq);
|
||||
|
||||
irq_dma = E_C_SB_DMA_translate[sb_config->dma] |
|
||||
E_C_SB_IRQ_translate[sb_config->irq];
|
||||
|
||||
pas_write(irq_dma, EMULATION_CONFIGURATION);
|
||||
}
|
||||
}
|
||||
#else
|
||||
pas_write(0x00, COMPATIBILITY_ENABLE);
|
||||
#endif
|
||||
|
||||
if (!ok)
|
||||
pas2_msg("Driver not enabled");
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int
|
||||
detect_pas_hw(struct address_info * hw_config)
|
||||
{
|
||||
u_char board_id, foo;
|
||||
|
||||
/*
|
||||
* WARNING: Setting an option like W:1 or so that disables warm boot
|
||||
* reset of the card will screw up this detect code something fierce.
|
||||
* Adding code to handle this means possibly interfering with other
|
||||
* cards on the bus if you have something on base port 0x388. SO be
|
||||
* forewarned.
|
||||
*/
|
||||
|
||||
outb(MASTER_DECODE, 0xBC); /* Talk to first board */
|
||||
outb(MASTER_DECODE, hw_config->io_base >> 2); /* Set base address */
|
||||
translat_code = PAS_DEFAULT_BASE ^ hw_config->io_base;
|
||||
pas_write(1, WAIT_STATE); /* One wait-state */
|
||||
|
||||
board_id = pas_read(INTERRUPT_MASK);
|
||||
|
||||
if (board_id == 0xff)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We probably have a PAS-series board, now check for a PAS2-series
|
||||
* board by trying to change the board revision bits. PAS2-series
|
||||
* hardware won't let you do this - the bits are read-only.
|
||||
*/
|
||||
|
||||
foo = board_id ^ 0xe0;
|
||||
|
||||
pas_write(foo, INTERRUPT_MASK);
|
||||
foo = inb(INTERRUPT_MASK);
|
||||
pas_write(board_id, INTERRUPT_MASK);
|
||||
|
||||
if (board_id != foo) /* Not a PAS2 */
|
||||
return 0;
|
||||
|
||||
pas_model = pas_read(CHIP_REV);
|
||||
|
||||
return pas_model;
|
||||
}
|
||||
|
||||
void
|
||||
attach_pas_card(struct address_info * hw_config)
|
||||
{
|
||||
pas_irq = hw_config->irq;
|
||||
pas_osp = hw_config->osp;
|
||||
|
||||
if (detect_pas_hw(hw_config)) {
|
||||
|
||||
if ((pas_model = pas_read(CHIP_REV))) {
|
||||
char temp[100];
|
||||
|
||||
snprintf(temp, sizeof(temp),
|
||||
"%s rev %d", pas_model_names[(int) pas_model],
|
||||
pas_read(BOARD_REV_ID));
|
||||
conf_printf(temp, hw_config);
|
||||
}
|
||||
if (config_pas_hw(hw_config)) {
|
||||
|
||||
#ifdef CONFIG_AUDIO
|
||||
pas_pcm_init(hw_config);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SB_EMULATION) && defined(CONFIG_SB)
|
||||
|
||||
sb_dsp_disable_midi(); /* The SB emulation don't
|
||||
* support * midi */
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_MIDI
|
||||
pas_midi_init();
|
||||
#endif
|
||||
pas_init_mixer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
probe_pas(struct address_info * hw_config)
|
||||
{
|
||||
pas_osp = hw_config->osp;
|
||||
return detect_pas_hw(hw_config);
|
||||
}
|
||||
|
||||
#endif
|
@ -1,285 +0,0 @@
|
||||
/*
|
||||
* sound/pas2_midi.c
|
||||
*
|
||||
* The low level driver for the PAS Midi Interface.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if defined(CONFIG_PAS) && defined(CONFIG_MIDI)
|
||||
#include <i386/isa/sound/pas_hw.h>
|
||||
|
||||
static int midi_busy = 0, input_opened = 0;
|
||||
static int my_dev;
|
||||
static volatile int ofifo_bytes = 0;
|
||||
|
||||
static u_char tmp_queue[256];
|
||||
static volatile int qlen;
|
||||
static volatile u_char qhead, qtail;
|
||||
|
||||
static void (*midi_input_intr) (int dev, u_char data);
|
||||
|
||||
static int
|
||||
pas_midi_open(int dev, int mode,
|
||||
void (*input) (int dev, u_char data),
|
||||
void (*output) (int dev)
|
||||
)
|
||||
{
|
||||
int err;
|
||||
u_long flags;
|
||||
u_char ctrl;
|
||||
|
||||
|
||||
if (midi_busy) {
|
||||
printf("PAS2: Midi busy\n");
|
||||
return -(EBUSY);
|
||||
}
|
||||
/*
|
||||
* Reset input and output FIFO pointers
|
||||
*/
|
||||
pas_write(M_C_RESET_INPUT_FIFO | M_C_RESET_OUTPUT_FIFO,
|
||||
MIDI_CONTROL);
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
if ((err = pas_set_intr(I_M_MIDI_IRQ_ENABLE)) < 0)
|
||||
return err;
|
||||
|
||||
/*
|
||||
* Enable input available and output FIFO empty interrupts
|
||||
*/
|
||||
|
||||
ctrl = 0;
|
||||
input_opened = 0;
|
||||
midi_input_intr = input;
|
||||
|
||||
if (mode == OPEN_READ || mode == OPEN_READWRITE) {
|
||||
ctrl |= M_C_ENA_INPUT_IRQ; /* Enable input */
|
||||
input_opened = 1;
|
||||
}
|
||||
if (mode == OPEN_WRITE || mode == OPEN_READWRITE) {
|
||||
ctrl |= M_C_ENA_OUTPUT_IRQ | /* Enable output */
|
||||
M_C_ENA_OUTPUT_HALF_IRQ;
|
||||
}
|
||||
pas_write(ctrl,
|
||||
MIDI_CONTROL);
|
||||
|
||||
/*
|
||||
* Acknowledge any pending interrupts
|
||||
*/
|
||||
|
||||
pas_write(0xff, MIDI_STATUS);
|
||||
ofifo_bytes = 0;
|
||||
|
||||
splx(flags);
|
||||
|
||||
midi_busy = 1;
|
||||
qlen = qhead = qtail = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pas_midi_close(int dev)
|
||||
{
|
||||
|
||||
/*
|
||||
* Reset FIFO pointers, disable intrs
|
||||
*/
|
||||
pas_write(M_C_RESET_INPUT_FIFO | M_C_RESET_OUTPUT_FIFO, MIDI_CONTROL);
|
||||
|
||||
pas_remove_intr(I_M_MIDI_IRQ_ENABLE);
|
||||
midi_busy = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dump_to_midi(u_char midi_byte)
|
||||
{
|
||||
int fifo_space, x;
|
||||
|
||||
fifo_space = ((x = pas_read(MIDI_FIFO_STATUS)) >> 4) & 0x0f;
|
||||
|
||||
if (fifo_space == 15 || (fifo_space < 2 && ofifo_bytes > 13)) { /* Fifo full */
|
||||
return 0; /* Upper layer will call again */
|
||||
}
|
||||
ofifo_bytes++;
|
||||
|
||||
pas_write(midi_byte, MIDI_DATA);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pas_midi_out(int dev, u_char midi_byte)
|
||||
{
|
||||
|
||||
u_long flags;
|
||||
|
||||
/*
|
||||
* Drain the local queue first
|
||||
*/
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
while (qlen && dump_to_midi(tmp_queue[qhead])) {
|
||||
qlen--;
|
||||
qhead++;
|
||||
}
|
||||
|
||||
splx(flags);
|
||||
|
||||
/*
|
||||
* Output the byte if the local queue is empty.
|
||||
*/
|
||||
|
||||
if (!qlen)
|
||||
if (dump_to_midi(midi_byte))
|
||||
return 1; /* OK */
|
||||
|
||||
/*
|
||||
* Put to the local queue
|
||||
*/
|
||||
|
||||
if (qlen >= 256)
|
||||
return 0; /* Local queue full */
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
tmp_queue[qtail] = midi_byte;
|
||||
qlen++;
|
||||
qtail++;
|
||||
|
||||
splx(flags);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pas_midi_start_read(int dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pas_midi_end_read(int dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pas_midi_ioctl(int dev, u_int cmd, ioctl_arg arg)
|
||||
{
|
||||
return -(EINVAL);
|
||||
}
|
||||
|
||||
static void
|
||||
pas_midi_kick(int dev)
|
||||
{
|
||||
ofifo_bytes = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pas_buffer_status(int dev)
|
||||
{
|
||||
return qlen;
|
||||
}
|
||||
|
||||
#define MIDI_SYNTH_NAME "Pro Audio Spectrum Midi"
|
||||
#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
|
||||
#include <i386/isa/sound/midi_synth.h>
|
||||
|
||||
static struct midi_operations pas_midi_operations =
|
||||
{
|
||||
{"Pro Audio Spectrum", 0, 0, SNDCARD_PAS},
|
||||
&std_midi_synth,
|
||||
{0},
|
||||
pas_midi_open,
|
||||
pas_midi_close,
|
||||
pas_midi_ioctl,
|
||||
pas_midi_out,
|
||||
pas_midi_start_read,
|
||||
pas_midi_end_read,
|
||||
pas_midi_kick,
|
||||
NULL, /* command */
|
||||
pas_buffer_status,
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
pas_midi_init()
|
||||
{
|
||||
if (num_midis >= MAX_MIDI_DEV) {
|
||||
printf("Sound: Too many midi devices detected\n");
|
||||
return;
|
||||
}
|
||||
std_midi_synth.midi_dev = my_dev = num_midis;
|
||||
midi_devs[num_midis++] = &pas_midi_operations;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
pas_midi_interrupt(void)
|
||||
{
|
||||
u_char stat;
|
||||
int i, incount;
|
||||
u_long flags;
|
||||
|
||||
stat = pas_read(MIDI_STATUS);
|
||||
|
||||
if (stat & M_S_INPUT_AVAIL) { /* Input byte available */
|
||||
incount = pas_read(MIDI_FIFO_STATUS) & 0x0f; /* Input FIFO count */
|
||||
if (!incount)
|
||||
incount = 16;
|
||||
|
||||
for (i = 0; i < incount; i++)
|
||||
if (input_opened) {
|
||||
midi_input_intr(my_dev, pas_read(MIDI_DATA));
|
||||
} else
|
||||
pas_read(MIDI_DATA); /* Flush */
|
||||
}
|
||||
if (stat & (M_S_OUTPUT_EMPTY | M_S_OUTPUT_HALF_EMPTY)) {
|
||||
if (!(stat & M_S_OUTPUT_EMPTY)) {
|
||||
ofifo_bytes = 8;
|
||||
} else {
|
||||
ofifo_bytes = 0;
|
||||
}
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
while (qlen && dump_to_midi(tmp_queue[qhead])) {
|
||||
qlen--;
|
||||
qhead++;
|
||||
}
|
||||
|
||||
splx(flags);
|
||||
}
|
||||
if (stat & M_S_OUTPUT_OVERRUN) {
|
||||
printf("MIDI output overrun %x,%x,%d \n", pas_read(MIDI_FIFO_STATUS), stat, ofifo_bytes);
|
||||
ofifo_bytes = 100;
|
||||
}
|
||||
pas_write(stat, MIDI_STATUS); /* Acknowledge interrupts */
|
||||
}
|
||||
|
||||
#endif
|
@ -1,325 +0,0 @@
|
||||
/*
|
||||
* sound/pas2_mixer.c
|
||||
*
|
||||
* Mixer routines for the Pro Audio Spectrum cards.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define _PAS2_MIXER_C_
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if defined(CONFIG_PAS)
|
||||
|
||||
#include <i386/isa/sound/pas_hw.h>
|
||||
|
||||
#define TRACE(what) /* (what) */
|
||||
|
||||
extern int translat_code;
|
||||
extern char pas_model;
|
||||
extern sound_os_info *pas_osp;
|
||||
|
||||
static int rec_devices = (SOUND_MASK_MIC); /* Default recording source */
|
||||
static int mode_control = 0;
|
||||
|
||||
#define POSSIBLE_RECORDING_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | SOUND_MASK_MIC | \
|
||||
SOUND_MASK_CD | SOUND_MASK_ALTPCM)
|
||||
|
||||
#define SUPPORTED_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | SOUND_MASK_MIC | \
|
||||
SOUND_MASK_CD | SOUND_MASK_ALTPCM | SOUND_MASK_IMIX | \
|
||||
SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_RECLEV | \
|
||||
SOUND_MASK_MUTE | SOUND_MASK_ENHANCE | SOUND_MASK_LOUD)
|
||||
|
||||
static u_short levels[SOUND_MIXER_NRDEVICES] =
|
||||
{
|
||||
0x3232, /* Master Volume */
|
||||
0x3232, /* Bass */
|
||||
0x3232, /* Treble */
|
||||
0x5050, /* FM */
|
||||
0x4b4b, /* PCM */
|
||||
0x3232, /* PC Speaker */
|
||||
0x4b4b, /* Ext Line */
|
||||
0x4b4b, /* Mic */
|
||||
0x4b4b, /* CD */
|
||||
0x6464, /* Recording monitor */
|
||||
0x4b4b, /* SB PCM */
|
||||
0x6464 /* Recording level */
|
||||
};
|
||||
|
||||
void mix_write(u_char data, int ioaddr);
|
||||
|
||||
void
|
||||
mix_write(u_char data, int ioaddr)
|
||||
{
|
||||
/*
|
||||
* The Revision D cards have a problem with their MVA508 interface.
|
||||
* The kludge-o-rama fix is to make a 16-bit quantity with identical
|
||||
* LSB and MSBs out of the output byte and to do a 16-bit out to the
|
||||
* mixer port - 1. We need to do this because it isn't timing problem
|
||||
* but chip access sequence problem.
|
||||
*/
|
||||
|
||||
if (pas_model == PAS_16D) {
|
||||
outw((ioaddr ^ translat_code) - 1, data | (data << 8));
|
||||
outb(0, 0x80);
|
||||
} else
|
||||
pas_write(data, ioaddr);
|
||||
}
|
||||
|
||||
static int
|
||||
mixer_output(int right_vol, int left_vol, int div, int bits,
|
||||
int mixer)
|
||||
{ /* Input or output mixer */
|
||||
int left = left_vol * div / 100;
|
||||
int right = right_vol * div / 100;
|
||||
|
||||
|
||||
if (bits & P_M_MV508_MIXER) { /* Select input or output mixer */
|
||||
left |= mixer;
|
||||
right |= mixer;
|
||||
}
|
||||
if (bits == P_M_MV508_BASS || bits == P_M_MV508_TREBLE) { /* Bass and treble are
|
||||
* mono devices */
|
||||
mix_write(P_M_MV508_ADDRESS | bits, PARALLEL_MIXER);
|
||||
mix_write(left, PARALLEL_MIXER);
|
||||
right_vol = left_vol;
|
||||
} else {
|
||||
mix_write(P_M_MV508_ADDRESS | P_M_MV508_LEFT | bits, PARALLEL_MIXER);
|
||||
mix_write(left, PARALLEL_MIXER);
|
||||
mix_write(P_M_MV508_ADDRESS | P_M_MV508_RIGHT | bits, PARALLEL_MIXER);
|
||||
mix_write(right, PARALLEL_MIXER);
|
||||
}
|
||||
|
||||
return (left_vol | (right_vol << 8));
|
||||
}
|
||||
|
||||
static void
|
||||
set_mode(int new_mode)
|
||||
{
|
||||
mix_write(P_M_MV508_ADDRESS | P_M_MV508_MODE, PARALLEL_MIXER);
|
||||
mix_write(new_mode, PARALLEL_MIXER);
|
||||
|
||||
mode_control = new_mode;
|
||||
}
|
||||
|
||||
static int
|
||||
pas_mixer_set(int whichDev, u_int level)
|
||||
{
|
||||
int left, right, devmask, changed, i, mixer = 0;
|
||||
|
||||
TRACE(printf("static int pas_mixer_set(int whichDev = %d, u_int level = %X)\n", whichDev, level));
|
||||
|
||||
left = level & 0x7f;
|
||||
right = (level & 0x7f00) >> 8;
|
||||
|
||||
if (whichDev < SOUND_MIXER_NRDEVICES) {
|
||||
if ((1 << whichDev) & rec_devices)
|
||||
mixer = P_M_MV508_INPUTMIX;
|
||||
else
|
||||
mixer = P_M_MV508_OUTPUTMIX;
|
||||
}
|
||||
switch (whichDev) {
|
||||
case SOUND_MIXER_VOLUME: /* Master volume (0-63) */
|
||||
levels[whichDev] = mixer_output(right, left, 63, P_M_MV508_MASTER_A, 0);
|
||||
break;
|
||||
|
||||
/*
|
||||
* Note! Bass and Treble are mono devices. Will use just the
|
||||
* left channel.
|
||||
*/
|
||||
case SOUND_MIXER_BASS: /* Bass (0-12) */
|
||||
levels[whichDev] = mixer_output(right, left, 12, P_M_MV508_BASS, 0);
|
||||
break;
|
||||
case SOUND_MIXER_TREBLE: /* Treble (0-12) */
|
||||
levels[whichDev] = mixer_output(right, left, 12, P_M_MV508_TREBLE, 0);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_SYNTH:/* Internal synthesizer (0-31) */
|
||||
levels[whichDev] = mixer_output(right, left, 31, P_M_MV508_MIXER | P_M_MV508_FM, mixer);
|
||||
break;
|
||||
case SOUND_MIXER_PCM: /* PAS PCM (0-31) */
|
||||
levels[whichDev] = mixer_output(right, left, 31, P_M_MV508_MIXER | P_M_MV508_PCM, mixer);
|
||||
break;
|
||||
case SOUND_MIXER_ALTPCM: /* SB PCM (0-31) */
|
||||
levels[whichDev] = mixer_output(right, left, 31, P_M_MV508_MIXER | P_M_MV508_SB, mixer);
|
||||
break;
|
||||
case SOUND_MIXER_SPEAKER: /* PC speaker (0-31) */
|
||||
levels[whichDev] = mixer_output(right, left, 31, P_M_MV508_MIXER | P_M_MV508_SPEAKER, mixer);
|
||||
break;
|
||||
case SOUND_MIXER_LINE: /* External line (0-31) */
|
||||
levels[whichDev] = mixer_output(right, left, 31, P_M_MV508_MIXER | P_M_MV508_LINE, mixer);
|
||||
break;
|
||||
case SOUND_MIXER_CD: /* CD (0-31) */
|
||||
levels[whichDev] = mixer_output(right, left, 31, P_M_MV508_MIXER | P_M_MV508_CDROM, mixer);
|
||||
break;
|
||||
case SOUND_MIXER_MIC: /* External microphone (0-31) */
|
||||
levels[whichDev] = mixer_output(right, left, 31, P_M_MV508_MIXER | P_M_MV508_MIC, mixer);
|
||||
break;
|
||||
case SOUND_MIXER_IMIX: /* Recording monitor (0-31) (Output mixer
|
||||
* only) */
|
||||
levels[whichDev] = mixer_output(right, left, 31, P_M_MV508_MIXER | P_M_MV508_IMIXER,
|
||||
P_M_MV508_OUTPUTMIX);
|
||||
break;
|
||||
case SOUND_MIXER_RECLEV: /* Recording level (0-15) */
|
||||
levels[whichDev] = mixer_output(right, left, 15, P_M_MV508_MASTER_B, 0);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_MUTE:
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_ENHANCE:
|
||||
i = 0;
|
||||
level &= 0x7f;
|
||||
if (level)
|
||||
i = (level / 20) - 1;
|
||||
|
||||
mode_control &= ~P_M_MV508_ENHANCE_BITS;
|
||||
mode_control |= P_M_MV508_ENHANCE_BITS;
|
||||
set_mode(mode_control);
|
||||
|
||||
if (i)
|
||||
i = (i + 1) * 20;
|
||||
return i;
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_LOUD:
|
||||
mode_control &= ~P_M_MV508_LOUDNESS;
|
||||
if (level)
|
||||
mode_control |= P_M_MV508_LOUDNESS;
|
||||
set_mode(mode_control);
|
||||
return !!level; /* 0 or 1 */
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_RECSRC:
|
||||
devmask = level & POSSIBLE_RECORDING_DEVICES;
|
||||
|
||||
changed = devmask ^ rec_devices;
|
||||
rec_devices = devmask;
|
||||
|
||||
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
|
||||
if (changed & (1 << i)) {
|
||||
pas_mixer_set(i, levels[i]);
|
||||
}
|
||||
return rec_devices;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -(EINVAL);
|
||||
}
|
||||
|
||||
return (levels[whichDev]);
|
||||
}
|
||||
|
||||
/*****/
|
||||
|
||||
static void
|
||||
pas_mixer_reset(void)
|
||||
{
|
||||
int foo;
|
||||
|
||||
TRACE(printf("pas2_mixer.c: void pas_mixer_reset(void)\n"));
|
||||
|
||||
for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++)
|
||||
pas_mixer_set(foo, levels[foo]);
|
||||
|
||||
set_mode(P_M_MV508_LOUDNESS | P_M_MV508_ENHANCE_40);
|
||||
}
|
||||
|
||||
static int
|
||||
pas_mixer_ioctl(int dev, u_int cmd, ioctl_arg arg)
|
||||
{
|
||||
TRACE(printf("pas2_mixer.c: int pas_mixer_ioctl(u_int cmd = %X, u_int arg = %X)\n", cmd, arg));
|
||||
|
||||
if (((cmd >> 8) & 0xff) == 'M') {
|
||||
if (cmd & IOC_IN)
|
||||
return *(int *) arg = pas_mixer_set(cmd & 0xff, (*(int *) arg));
|
||||
else { /* Read parameters */
|
||||
|
||||
switch (cmd & 0xff) {
|
||||
|
||||
case SOUND_MIXER_RECSRC:
|
||||
return *(int *) arg = rec_devices;
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_STEREODEVS:
|
||||
return *(int *) arg = SUPPORTED_MIXER_DEVICES & ~(SOUND_MASK_BASS | SOUND_MASK_TREBLE);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_DEVMASK:
|
||||
return *(int *) arg = SUPPORTED_MIXER_DEVICES;
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_RECMASK:
|
||||
return *(int *) arg = POSSIBLE_RECORDING_DEVICES & SUPPORTED_MIXER_DEVICES;
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_CAPS:
|
||||
return *(int *) arg = 0; /* No special
|
||||
* capabilities */
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_MUTE:
|
||||
return *(int *) arg = 0; /* No mute yet */
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_ENHANCE:
|
||||
if (!(mode_control & P_M_MV508_ENHANCE_BITS))
|
||||
return *(int *) arg = 0;
|
||||
return *(int *) arg = ((mode_control & P_M_MV508_ENHANCE_BITS) + 1) * 20;
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_LOUD:
|
||||
if (mode_control & P_M_MV508_LOUDNESS)
|
||||
return *(int *) arg = 1;
|
||||
return *(int *) arg = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
return *(int *) arg = levels[cmd & 0xff];
|
||||
}
|
||||
}
|
||||
}
|
||||
return -(EINVAL);
|
||||
}
|
||||
|
||||
static struct mixer_operations pas_mixer_operations =
|
||||
{
|
||||
"Pro Audio Spectrum 16",
|
||||
pas_mixer_ioctl
|
||||
};
|
||||
|
||||
int
|
||||
pas_init_mixer(void)
|
||||
{
|
||||
pas_mixer_reset();
|
||||
|
||||
if (num_mixers < MAX_MIXER_DEV)
|
||||
mixer_devs[num_mixers++] = &pas_mixer_operations;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,449 +0,0 @@
|
||||
#define _PAS2_PCM_C_
|
||||
/*
|
||||
* sound/pas2_pcm.c
|
||||
*
|
||||
* The low level driver for the Pro Audio Spectrum ADC/DAC.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if defined(CONFIG_PAS) && defined(CONFIG_AUDIO)
|
||||
#include <i386/isa/sound/pas_hw.h>
|
||||
|
||||
|
||||
#define TRACE(WHAT) /* * * (WHAT) */
|
||||
|
||||
#define PAS_PCM_INTRBITS (0x08)
|
||||
/*
|
||||
* Sample buffer timer interrupt enable
|
||||
*/
|
||||
|
||||
#define PCM_NON 0
|
||||
#define PCM_DAC 1
|
||||
#define PCM_ADC 2
|
||||
|
||||
static u_long pcm_speed = 0; /* sampling rate */
|
||||
static u_char pcm_channels = 1; /* channels (1 or 2) */
|
||||
static u_char pcm_bits = 8; /* bits/sample (8 or 16) */
|
||||
static u_char pcm_filter = 0; /* filter FLAG */
|
||||
static u_char pcm_mode = PCM_NON;
|
||||
static u_long pcm_count = 0;
|
||||
static u_short pcm_bitsok = 8; /* mask of OK bits */
|
||||
static int my_devnum = 0;
|
||||
static int open_mode = 0;
|
||||
|
||||
static int
|
||||
pcm_set_speed(int arg)
|
||||
{
|
||||
int foo, tmp;
|
||||
u_long flags;
|
||||
|
||||
if (arg > 44100)
|
||||
arg = 44100;
|
||||
if (arg < 5000)
|
||||
arg = 5000;
|
||||
|
||||
foo = (1193180 + (arg / 2)) / arg;
|
||||
arg = 1193180 / foo;
|
||||
|
||||
if (pcm_channels & 2)
|
||||
foo = foo >> 1;
|
||||
|
||||
pcm_speed = arg;
|
||||
|
||||
tmp = pas_read(FILTER_FREQUENCY);
|
||||
|
||||
/*
|
||||
* Set anti-aliasing filters according to sample rate. You reall
|
||||
* *NEED* to enable this feature for all normal recording unless you
|
||||
* want to experiment with aliasing effects. These filters apply to
|
||||
* the selected "recording" source. I (pfw) don't know the encoding
|
||||
* of these 5 bits. The values shown come from the SDK found on
|
||||
* ftp.uwp.edu:/pub/msdos/proaudio/.
|
||||
*/
|
||||
#if !defined NO_AUTO_FILTER_SET
|
||||
tmp &= 0xe0;
|
||||
if (pcm_speed >= 2 * 17897)
|
||||
tmp |= 0x21;
|
||||
else if (pcm_speed >= 2 * 15909)
|
||||
tmp |= 0x22;
|
||||
else if (pcm_speed >= 2 * 11931)
|
||||
tmp |= 0x29;
|
||||
else if (pcm_speed >= 2 * 8948)
|
||||
tmp |= 0x31;
|
||||
else if (pcm_speed >= 2 * 5965)
|
||||
tmp |= 0x39;
|
||||
else if (pcm_speed >= 2 * 2982)
|
||||
tmp |= 0x24;
|
||||
pcm_filter = tmp;
|
||||
#endif
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
pas_write(tmp & ~(F_F_PCM_RATE_COUNTER | F_F_PCM_BUFFER_COUNTER), FILTER_FREQUENCY);
|
||||
pas_write(S_C_C_SAMPLE_RATE | S_C_C_LSB_THEN_MSB | S_C_C_SQUARE_WAVE, SAMPLE_COUNTER_CONTROL);
|
||||
pas_write(foo & 0xff, SAMPLE_RATE_TIMER);
|
||||
pas_write((foo >> 8) & 0xff, SAMPLE_RATE_TIMER);
|
||||
pas_write(tmp, FILTER_FREQUENCY);
|
||||
|
||||
splx(flags);
|
||||
|
||||
return pcm_speed;
|
||||
}
|
||||
|
||||
static int
|
||||
pcm_set_channels(int arg)
|
||||
{
|
||||
|
||||
if ((arg != 1) && (arg != 2))
|
||||
return pcm_channels;
|
||||
|
||||
if (arg != pcm_channels) {
|
||||
pas_write(pas_read(PCM_CONTROL) ^ P_C_PCM_MONO, PCM_CONTROL);
|
||||
|
||||
pcm_channels = arg;
|
||||
pcm_set_speed(pcm_speed); /* The speed must be
|
||||
* reinitialized */
|
||||
}
|
||||
return pcm_channels;
|
||||
}
|
||||
|
||||
static int
|
||||
pcm_set_bits(int arg)
|
||||
{
|
||||
if ((arg & pcm_bitsok) != arg)
|
||||
return pcm_bits;
|
||||
|
||||
if (arg != pcm_bits) {
|
||||
pas_write(pas_read(SYSTEM_CONFIGURATION_2) ^ S_C_2_PCM_16_BIT, SYSTEM_CONFIGURATION_2);
|
||||
|
||||
pcm_bits = arg;
|
||||
}
|
||||
return pcm_bits;
|
||||
}
|
||||
|
||||
static int
|
||||
pas_pcm_ioctl(int dev, u_int cmd, ioctl_arg arg, int local)
|
||||
{
|
||||
TRACE(printf("pas2_pcm.c: static int pas_pcm_ioctl(u_int cmd = %X, u_int arg = %X)\n", cmd, arg));
|
||||
|
||||
switch (cmd) {
|
||||
case SOUND_PCM_WRITE_RATE:
|
||||
if (local)
|
||||
return pcm_set_speed((int) arg);
|
||||
return *(int *) arg = pcm_set_speed((*(int *) arg));
|
||||
break;
|
||||
|
||||
case SOUND_PCM_READ_RATE:
|
||||
if (local)
|
||||
return pcm_speed;
|
||||
return *(int *) arg = pcm_speed;
|
||||
break;
|
||||
|
||||
case SNDCTL_DSP_STEREO:
|
||||
if (local)
|
||||
return pcm_set_channels((int) arg + 1) - 1;
|
||||
return *(int *) arg = pcm_set_channels((*(int *) arg) + 1) - 1;
|
||||
break;
|
||||
|
||||
case SOUND_PCM_WRITE_CHANNELS:
|
||||
if (local)
|
||||
return pcm_set_channels((int) arg);
|
||||
return *(int *) arg = pcm_set_channels((*(int *) arg));
|
||||
break;
|
||||
|
||||
case SOUND_PCM_READ_CHANNELS:
|
||||
if (local)
|
||||
return pcm_channels;
|
||||
return *(int *) arg = pcm_channels;
|
||||
break;
|
||||
|
||||
case SNDCTL_DSP_SETFMT:
|
||||
if (local)
|
||||
return pcm_set_bits((int) arg);
|
||||
return *(int *) arg = pcm_set_bits((*(int *) arg));
|
||||
break;
|
||||
|
||||
case SOUND_PCM_READ_BITS:
|
||||
if (local)
|
||||
return pcm_bits;
|
||||
return *(int *) arg = pcm_bits;
|
||||
|
||||
case SOUND_PCM_WRITE_FILTER: /* NOT YET IMPLEMENTED */
|
||||
if ((*(int *) arg) > 1)
|
||||
return -(EINVAL);
|
||||
pcm_filter = (*(int *) arg);
|
||||
break;
|
||||
|
||||
case SOUND_PCM_READ_FILTER:
|
||||
return *(int *) arg = pcm_filter;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -(EINVAL);
|
||||
}
|
||||
|
||||
return -(EINVAL);
|
||||
}
|
||||
|
||||
static void
|
||||
pas_pcm_reset(int dev)
|
||||
{
|
||||
TRACE(printf("pas2_pcm.c: static void pas_pcm_reset(void)\n"));
|
||||
|
||||
pas_write(pas_read(PCM_CONTROL) & ~P_C_PCM_ENABLE, PCM_CONTROL);
|
||||
}
|
||||
|
||||
static int
|
||||
pas_pcm_open(int dev, int mode)
|
||||
{
|
||||
int err;
|
||||
|
||||
TRACE(printf("pas2_pcm.c: static int pas_pcm_open(int mode = %X)\n", mode));
|
||||
|
||||
if ((err = pas_set_intr(PAS_PCM_INTRBITS)) < 0)
|
||||
return err;
|
||||
|
||||
|
||||
pcm_count = 0;
|
||||
open_mode = mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pas_pcm_close(int dev)
|
||||
{
|
||||
u_long flags;
|
||||
|
||||
TRACE(printf("pas2_pcm.c: static void pas_pcm_close(void)\n"));
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
pas_pcm_reset(dev);
|
||||
pas_remove_intr(PAS_PCM_INTRBITS);
|
||||
pcm_mode = PCM_NON;
|
||||
|
||||
open_mode = 0;
|
||||
|
||||
splx(flags);
|
||||
}
|
||||
|
||||
static void
|
||||
pas_pcm_output_block(int dev, u_long buf, int count,
|
||||
int intrflag, int restart_dma)
|
||||
{
|
||||
u_long flags, cnt;
|
||||
|
||||
TRACE(printf("pas2_pcm.c: static void pas_pcm_output_block(char *buf = %P, int count = %X)\n", buf, count));
|
||||
|
||||
cnt = count;
|
||||
if (audio_devs[dev]->dmachan1 > 3)
|
||||
cnt >>= 1;
|
||||
|
||||
if (audio_devs[dev]->flags & DMA_AUTOMODE &&
|
||||
intrflag &&
|
||||
cnt == pcm_count)
|
||||
return; /* Auto mode on. No need to react */
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
pas_write(pas_read(PCM_CONTROL) & ~P_C_PCM_ENABLE,
|
||||
PCM_CONTROL);
|
||||
|
||||
if (restart_dma)
|
||||
DMAbuf_start_dma(dev, buf, count, 1);
|
||||
|
||||
if (audio_devs[dev]->dmachan1 > 3)
|
||||
count >>= 1;
|
||||
|
||||
if (count != pcm_count) {
|
||||
pas_write(pas_read(FILTER_FREQUENCY) & ~F_F_PCM_BUFFER_COUNTER, FILTER_FREQUENCY);
|
||||
pas_write(S_C_C_SAMPLE_BUFFER | S_C_C_LSB_THEN_MSB | S_C_C_SQUARE_WAVE, SAMPLE_COUNTER_CONTROL);
|
||||
pas_write(count & 0xff, SAMPLE_BUFFER_COUNTER);
|
||||
pas_write((count >> 8) & 0xff, SAMPLE_BUFFER_COUNTER);
|
||||
pas_write(pas_read(FILTER_FREQUENCY) | F_F_PCM_BUFFER_COUNTER, FILTER_FREQUENCY);
|
||||
|
||||
pcm_count = count;
|
||||
}
|
||||
pas_write(pas_read(FILTER_FREQUENCY) | F_F_PCM_BUFFER_COUNTER | F_F_PCM_RATE_COUNTER, FILTER_FREQUENCY);
|
||||
#ifdef NO_TRIGGER
|
||||
pas_write(pas_read(PCM_CONTROL) | P_C_PCM_ENABLE | P_C_PCM_DAC_MODE, PCM_CONTROL);
|
||||
#endif
|
||||
|
||||
pcm_mode = PCM_DAC;
|
||||
|
||||
splx(flags);
|
||||
}
|
||||
|
||||
static void
|
||||
pas_pcm_start_input(int dev, u_long buf, int count,
|
||||
int intrflag, int restart_dma)
|
||||
{
|
||||
u_long flags;
|
||||
int cnt;
|
||||
|
||||
TRACE(printf("pas2_pcm.c: static void pas_pcm_start_input(char *buf = %P, int count = %X)\n", buf, count));
|
||||
|
||||
cnt = count;
|
||||
if (audio_devs[dev]->dmachan1 > 3)
|
||||
cnt >>= 1;
|
||||
|
||||
if (audio_devs[my_devnum]->flags & DMA_AUTOMODE &&
|
||||
intrflag &&
|
||||
cnt == pcm_count)
|
||||
return; /* Auto mode on. No need to react */
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
if (restart_dma)
|
||||
DMAbuf_start_dma(dev, buf, count, 0);
|
||||
|
||||
if (audio_devs[dev]->dmachan1 > 3)
|
||||
count >>= 1;
|
||||
|
||||
if (count != pcm_count) {
|
||||
pas_write(pas_read(FILTER_FREQUENCY) & ~F_F_PCM_BUFFER_COUNTER, FILTER_FREQUENCY);
|
||||
pas_write(S_C_C_SAMPLE_BUFFER | S_C_C_LSB_THEN_MSB | S_C_C_SQUARE_WAVE, SAMPLE_COUNTER_CONTROL);
|
||||
pas_write(count & 0xff, SAMPLE_BUFFER_COUNTER);
|
||||
pas_write((count >> 8) & 0xff, SAMPLE_BUFFER_COUNTER);
|
||||
pas_write(pas_read(FILTER_FREQUENCY) | F_F_PCM_BUFFER_COUNTER, FILTER_FREQUENCY);
|
||||
|
||||
pcm_count = count;
|
||||
}
|
||||
pas_write(pas_read(FILTER_FREQUENCY) | F_F_PCM_BUFFER_COUNTER | F_F_PCM_RATE_COUNTER, FILTER_FREQUENCY);
|
||||
#ifdef NO_TRIGGER
|
||||
pas_write((pas_read(PCM_CONTROL) | P_C_PCM_ENABLE) & ~P_C_PCM_DAC_MODE, PCM_CONTROL);
|
||||
#endif
|
||||
|
||||
pcm_mode = PCM_ADC;
|
||||
|
||||
splx(flags);
|
||||
}
|
||||
#ifndef NO_TRIGGER
|
||||
static void
|
||||
pas_audio_trigger (int dev, int state)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
state &= open_mode;
|
||||
|
||||
if (state & PCM_ENABLE_OUTPUT)
|
||||
pas_write (pas_read (0xF8A) | 0x40 | 0x10, 0xF8A);
|
||||
else if (state & PCM_ENABLE_INPUT)
|
||||
pas_write ((pas_read (0xF8A) | 0x40) & ~0x10, 0xF8A);
|
||||
else
|
||||
pas_write (pas_read (0xF8A) & ~0x40, 0xF8A);
|
||||
|
||||
splx(flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
pas_pcm_prepare_for_input(int dev, int bsize, int bcount)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
pas_pcm_prepare_for_output(int dev, int bsize, int bcount)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct audio_operations pas_pcm_operations =
|
||||
{
|
||||
"Pro Audio Spectrum",
|
||||
DMA_AUTOMODE,
|
||||
AFMT_U8 | AFMT_S16_LE,
|
||||
NULL,
|
||||
pas_pcm_open,
|
||||
pas_pcm_close,
|
||||
pas_pcm_output_block,
|
||||
pas_pcm_start_input,
|
||||
pas_pcm_ioctl,
|
||||
pas_pcm_prepare_for_input,
|
||||
pas_pcm_prepare_for_output,
|
||||
pas_pcm_reset,
|
||||
pas_pcm_reset,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
pas_audio_trigger
|
||||
};
|
||||
|
||||
void
|
||||
pas_pcm_init(struct address_info * hw_config)
|
||||
{
|
||||
pcm_bitsok = 8;
|
||||
if (pas_read(OPERATION_MODE_1) & O_M_1_PCM_TYPE)
|
||||
pcm_bitsok |= 16;
|
||||
|
||||
pcm_set_speed(DSP_DEFAULT_SPEED);
|
||||
|
||||
if (num_audiodevs < MAX_AUDIO_DEV) {
|
||||
audio_devs[my_devnum = num_audiodevs++] = &pas_pcm_operations;
|
||||
audio_devs[my_devnum]->dmachan1 = hw_config->dma;
|
||||
audio_devs[my_devnum]->buffsize = DSP_BUFFSIZE;
|
||||
} else
|
||||
printf("PAS2: Too many PCM devices available\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
pas_pcm_interrupt(u_char status, int cause)
|
||||
{
|
||||
if (cause == 1) { /* PCM buffer done */
|
||||
/*
|
||||
* Halt the PCM first. Otherwise we don't have time to start
|
||||
* a new block before the PCM chip proceeds to the next
|
||||
* sample
|
||||
*/
|
||||
|
||||
if (!(audio_devs[my_devnum]->flags & DMA_AUTOMODE)) {
|
||||
pas_write(pas_read(PCM_CONTROL) & ~P_C_PCM_ENABLE,
|
||||
PCM_CONTROL);
|
||||
}
|
||||
switch (pcm_mode) {
|
||||
|
||||
case PCM_DAC:
|
||||
DMAbuf_outputintr(my_devnum, 1);
|
||||
break;
|
||||
|
||||
case PCM_ADC:
|
||||
DMAbuf_inputintr(my_devnum);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("PAS: Unexpected PCM interrupt\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,250 +0,0 @@
|
||||
/* */
|
||||
/* Port addresses and bit fields for the Media Vision Pro AudioSpectrum second generation sound cards. */
|
||||
/* */
|
||||
/* Feel free to use this header file in any application you create that has support for the Media Vision */
|
||||
/* Pro AudioSpectrum second generation sound cards. Other uses prohibited without prior permission. */
|
||||
/* */
|
||||
/* - cmetz@thor.tjhsst.edu */
|
||||
/* */
|
||||
/* Notes: */
|
||||
/* */
|
||||
/* * All of these ports go into the MVD101 multimedia controller chip, which then signals the other chips to do */
|
||||
/* the actual work. Many ports like the FM ones functionally attach directly to the destination chip though */
|
||||
/* they don't actually have a direct connection. */
|
||||
/* */
|
||||
/* * The PAS2 series cards have an MVD101 multimedia controller chip, the original PAS cards don't. The original */
|
||||
/* PAS cards are pretty defunct now, so no attempt is made here to support them. */
|
||||
/* */
|
||||
/* * The PAS2 series cards are all really different at the hardware level, though the MVD101 hides some of the */
|
||||
/* incompatibilities, there still are differences that need to be accounted for. */
|
||||
/* */
|
||||
/* Card CD-ROM interface PCM chip Mixer chip FM chip */
|
||||
/* PAS Plus Sony proprietary (Crystal?) 8-bit DAC National OPL3 */
|
||||
/* PAS 16 Zilog SCSI MVA416 16-bit Codec MVA508 OPL3 */
|
||||
/* CDPC Sony proprietary Sony 16-bit Codec National OPL3 */
|
||||
/* Fusion CD 16 Sony proprietary MVA416 16-bit Codec MVA508 OPL3 */
|
||||
/* Fusion CD Sony proprietary (Crystal?) 8-bit DAC National OPL3 */
|
||||
/* */
|
||||
#define PAS_DEFAULT_BASE 0x388
|
||||
|
||||
/* Symbolic Name Value R W Subsystem Description */
|
||||
#define SPEAKER_CONTROL 0x61 /* W PC speaker Control register */
|
||||
#define SPEAKER_CONTROL_GHOST 0x738B /* R W PC speaker Control ghost register */
|
||||
#define SPEAKER_TIMER_CONTROL 0x43 /* W PC speaker Timer control register */
|
||||
#define SPEAKER_TIMER_CONTROL_GHOST 0x778B /* R W PC speaker Timer control register ghost */
|
||||
#define SPEAKER_TIMER_DATA 0x42 /* W PC speaker Timer data register */
|
||||
#define SPEAKER_TIMER_DATA_GHOST 0x138A /* R W PC speaker Timer data register ghost */
|
||||
|
||||
#define WARM_BOOT 0x41 /* W Control Used to detect system warm boot */
|
||||
#define WARM_BOOT_GHOST 0x7789 /* ? W Control Use to get the card to fake warm boot */
|
||||
#define MASTER_DECODE 0x9A01 /* W Control Address >> 2 of card base address */
|
||||
#define PRESCALE_DIVIDER 0xBF8A /* R W PCM Ration between Codec clock and master clock */
|
||||
#define WAIT_STATE 0xBF88 /* R W Control Four-bit bus wait-state count (~140ns ea.) */
|
||||
#define BOARD_REV_ID 0x2789 /* R Control Extended Board Revision ID */
|
||||
|
||||
#define CHIP_REV 0xFF88 /* R 0=PAS, 1=PAS+, 2=CDPC, 3=PAS16C, 4=PAS16D */
|
||||
|
||||
#define SYSTEM_CONFIGURATION_1 0x8388 /* R W Control */
|
||||
#define S_C_1_PCS_ENABLE 0x01 /* R W PC speaker 1=enable, 0=disable PC speaker emulation */
|
||||
#define S_C_1_PCM_CLOCK_SELECT 0x02 /* R W PCM 1=14.31818Mhz/12, 0=28.224Mhz master clock */
|
||||
#define S_C_1_FM_EMULATE_CLOCK 0x04 /* R W FM 1=use 28.224Mhz/2, 0=use 14.31818Mhz clock */
|
||||
#define S_C_1_PCS_STEREO 0x10 /* R W PC speaker 1=enable PC speaker stereo effect, 0=disable */
|
||||
#define S_C_1_PCS_REALSOUND 0x20 /* R W PC speaker 1=enable RealSound enhancement, 0=disable */
|
||||
#define S_C_1_FORCE_EXT_RESET 0x40 /* R W Control Force external reset */
|
||||
#define S_C_1_FORCE_INT_RESET 0x80 /* R W Control Force internal reset */
|
||||
#define SYSTEM_CONFIGURATION_2 0x8389 /* R W Control */
|
||||
#define S_C_2_PCM_OVERSAMPLING 0x03 /* R W PCM 00=0x, 01=2x, 10=4x, 11=reserved */
|
||||
#define S_C_2_PCM_16_BIT 0x04 /* R W PCM 1=16-bit, 0=8-bit samples */
|
||||
#define SYSTEM_CONFIGURATION_3 0x838A /* R W Control */
|
||||
#define S_C_3_PCM_CLOCK_SELECT 0x02 /* R W PCM 1=use 1.008Mhz clock for PCM, 0=don't */
|
||||
#define SYSTEM_CONFIGURATION_4 0x838B /* R W Control CD-ROM interface controls */
|
||||
|
||||
#define IO_CONFIGURATION_1 0xF388 /* R W Control */
|
||||
#define I_C_1_BOOT_RESET_ENABLE 0x80 /* R W Control 1=reset board on warm boot, 0=don't */
|
||||
#define I_C_1_JOYSTICK_ENABLE 0x40 /* R W Control 1=enable joystick port, 0=don't */
|
||||
#define IO_CONFIGURATION_2 0xF389 /* R W Control */
|
||||
#define I_C_2_PCM_DMA_DISABLED 0x00 /* R W PCM PCM DMA disabled */
|
||||
#define IO_CONFIGURATION_3 0xF38A /* R W Control */
|
||||
#define I_C_3_PCM_IRQ_DISABLED 0x00 /* R W PCM PCM IRQ disabled */
|
||||
|
||||
#define COMPATIBILITY_ENABLE 0xF788 /* R W Control */
|
||||
#define C_E_MPU401_ENABLE 0x01 /* R W MIDI 1=enable, 0=disable MPU401 MIDI emulation */
|
||||
#define C_E_SB_ENABLE 0x02 /* R W PCM 1=enable, 0=disable Sound Blaster emulation */
|
||||
#define C_E_SB_ACTIVE 0x04 /* R PCM "Sound Blaster Interrupt active" */
|
||||
#define C_E_MPU401_ACTIVE 0x08 /* R MIDI "MPU UART mode active" */
|
||||
#define C_E_PCM_COMPRESSION 0x10 /* R W PCM 1=enable, 0=disabled compression */
|
||||
#define EMULATION_ADDRESS 0xF789 /* R W Control */
|
||||
#define E_A_SB_BASE 0x0f /* R W PCM bits A4-A7 for SB base port */
|
||||
#define E_A_MPU401_BASE 0xf0 /* R W MIDI bits A4-A7 for MPU401 base port */
|
||||
#define EMULATION_CONFIGURATION 0xFB8A /* R W ***** Only valid on newer PAS2 cards (?) ***** */
|
||||
#define E_C_MPU401_IRQ 0x07 /* R W MIDI MPU401 emulation IRQ */
|
||||
#define E_C_SB_IRQ 0x38 /* R W PCM SB emulation IRQ */
|
||||
#define E_C_SB_DMA 0xC0 /* R W PCM SB emulation DMA */
|
||||
|
||||
#define OPERATION_MODE_1 0xEF8B /* R Control */
|
||||
#define O_M_1_CDROM_TYPE 0x03 /* R CD-ROM 3=SCSI, 2=Sony, 0=no CD-ROM interface */
|
||||
#define O_M_1_FM_TYPE 0x04 /* R FM 1=sterero, 0=mono FM chip */
|
||||
#define O_M_1_PCM_TYPE 0x08 /* R PCM 1=16-bit Codec, 0=8-bit DAC */
|
||||
#define OPERATION_MODE_2 0xFF8B /* R Control */
|
||||
#define O_M_2_PCS_ENABLED 0x02 /* R PC speaker PC speaker emulation 1=enabled, 0=disabled */
|
||||
#define O_M_2_BUS_TIMING 0x10 /* R Control 1=AT bus timing, 0=XT bus timing */
|
||||
#define O_M_2_BOARD_REVISION 0xe0 /* R Control Board revision */
|
||||
|
||||
#define INTERRUPT_MASK 0x0B8B /* R W Control */
|
||||
#define I_M_FM_LEFT_IRQ_ENABLE 0x01 /* R W FM Enable FM left interrupt */
|
||||
#define I_M_FM_RIGHT_IRQ_ENABLE 0x02 /* R W FM Enable FM right interrupt */
|
||||
#define I_M_PCM_RATE_IRQ_ENABLE 0x04 /* R W PCM Enable Sample Rate interrupt */
|
||||
#define I_M_PCM_BUFFER_IRQ_ENABLE 0x08 /* R W PCM Enable Sample Buffer interrupt */
|
||||
#define I_M_MIDI_IRQ_ENABLE 0x10 /* R W MIDI Enable MIDI interrupt */
|
||||
#define I_M_BOARD_REV 0xE0 /* R Control Board revision */
|
||||
|
||||
#define INTERRUPT_STATUS 0x0B89 /* R W Control */
|
||||
#define I_S_FM_LEFT_IRQ 0x01 /* R W FM Left FM Interrupt Pending */
|
||||
#define I_S_FM_RIGHT_IRQ 0x02 /* R W FM Right FM Interrupt Pending */
|
||||
#define I_S_PCM_SAMPLE_RATE_IRQ 0x04 /* R W PCM Sample Rate Interrupt Pending */
|
||||
#define I_S_PCM_SAMPLE_BUFFER_IRQ 0x08 /* R W PCM Sample Buffer Interrupt Pending */
|
||||
#define I_S_MIDI_IRQ 0x10 /* R W MIDI MIDI Interrupt Pending */
|
||||
#define I_S_PCM_CHANNEL 0x20 /* R W PCM 1=right, 0=left */
|
||||
#define I_S_RESET_ACTIVE 0x40 /* R W Control Reset is active (Timed pulse not finished) */
|
||||
#define I_S_PCM_CLIPPING 0x80 /* R W PCM Clipping has occurred */
|
||||
|
||||
#define FILTER_FREQUENCY 0x0B8A /* R W Control */
|
||||
#define F_F_FILTER_DISABLED 0x00 /* R W Mixer No filter */
|
||||
#if 0
|
||||
struct { /* R W Mixer Filter translation */
|
||||
unsigned int freq:24;
|
||||
unsigned int value:8;
|
||||
} F_F_FILTER_translate[] =
|
||||
{ { 73500, 0x01 }, /* 73500Hz - divide by 16 */
|
||||
{ 65333, 0x02 }, /* 65333Hz - divide by 18 */
|
||||
{ 49000, 0x09 }, /* 49000Hz - divide by 24 */
|
||||
{ 36750, 0x11 }, /* 36750Hz - divide by 32 */
|
||||
{ 24500, 0x19 }, /* 24500Hz - divide by 48 */
|
||||
{ 18375, 0x07 }, /* 18375Hz - divide by 64 */
|
||||
{ 12783, 0x0f }, /* 12783Hz - divide by 92 */
|
||||
{ 12250, 0x04 }, /* 12250Hz - divide by 96 */
|
||||
{ 9188, 0x17 }, /* 9188Hz - divide by 128 */
|
||||
{ 6125, 0x1f }, /* 6125Hz - divide by 192 */
|
||||
};
|
||||
#endif
|
||||
#define F_F_MIXER_UNMUTE 0x20 /* R W Mixer 1=disable, 0=enable board mute */
|
||||
#define F_F_PCM_RATE_COUNTER 0x40 /* R W PCM 1=enable, 0=disable sample rate counter */
|
||||
#define F_F_PCM_BUFFER_COUNTER 0x80 /* R W PCM 1=enable, 0=disable sample buffer counter */
|
||||
|
||||
#define PAS_NONE 0
|
||||
#define PAS_PLUS 1
|
||||
#define PAS_CDPC 2
|
||||
#define PAS_16 3
|
||||
#define PAS_16D 4
|
||||
|
||||
#ifdef DEFINE_TRANSLATIONS
|
||||
static unsigned char I_C_2_PCM_DMA_translate[] = /* R W PCM PCM DMA channel value translations */
|
||||
{ 4, 1, 2, 3, 0, 5, 6, 7 };
|
||||
static unsigned char I_C_3_PCM_IRQ_translate[] = /* R W PCM PCM IRQ level value translation */
|
||||
{ 0, 0, 1, 2, 3, 4, 5, 6, 0, 1, 7, 8, 9, 0, 10, 11 };
|
||||
#ifdef unused
|
||||
static unsigned char E_C_MPU401_IRQ_translate[] = /* R W MIDI MPU401 emulation IRQ value translation */
|
||||
{ 0x00, 0x00, 0x01, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x01, 0x05, 0x06, 0x07 };
|
||||
#endif
|
||||
static unsigned char E_C_SB_IRQ_translate[] = /* R W PCM SB emulation IRQ translate */
|
||||
{ 0x00, 0x00, 0x08, 0x10, 0x00, 0x18, 0x00, 0x20, 0x00, 0x08, 0x28, 0x30, 0x38, 0, 0 };
|
||||
static unsigned char E_C_SB_DMA_translate[] = /* R W PCM SB emulation DMA translate */
|
||||
{ 0x00, 0x40, 0x80, 0xC0, 0, 0, 0, 0 };
|
||||
#ifdef unused
|
||||
static unsigned char O_M_1_to_card[] = /* R W Control Translate (OM1 & 0x0f) to card type */
|
||||
{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 2, 3 };
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define PARALLEL_MIXER 0x078B /* W Mixer Documented for MVD101 as FM Mono Right decode?? */
|
||||
#define P_M_MV508_ADDRESS 0x80 /* W Mixer MVD508 Address/mixer select */
|
||||
#define P_M_MV508_DATA 0x00
|
||||
#define P_M_MV508_LEFT 0x20 /* W Mixer MVD508 Left channel select */
|
||||
#define P_M_MV508_RIGHT 0x40 /* W Mixer MVD508 Right channel select */
|
||||
#define P_M_MV508_BOTH 0x00 /* W Mixer MVD508 Both channel select */
|
||||
#define P_M_MV508_MIXER 0x10 /* W Mixer MVD508 Select a mixer (rather than a volume) */
|
||||
#define P_M_MV508_VOLUME 0x00
|
||||
|
||||
#define P_M_MV508_INPUTMIX 0x20 /* W Mixer MVD508 Select mixer A */
|
||||
#define P_M_MV508_OUTPUTMIX 0x00 /* W Mixer MVD508 Select mixer B */
|
||||
|
||||
#define P_M_MV508_MASTER_A 0x01 /* W Mixer MVD508 Master volume control A (output) */
|
||||
#define P_M_MV508_MASTER_B 0x02 /* W Mixer MVD508 Master volume control B (DSP input) */
|
||||
#define P_M_MV508_BASS 0x03 /* W Mixer MVD508 Bass control */
|
||||
#define P_M_MV508_TREBLE 0x04 /* W Mixer MVD508 Treble control */
|
||||
#define P_M_MV508_MODE 0x05 /* W Mixer MVD508 Master mode control */
|
||||
|
||||
#define P_M_MV508_LOUDNESS 0x04 /* W Mixer MVD508 Mode control - Loudness filter */
|
||||
#define P_M_MV508_ENHANCE_BITS 0x03
|
||||
#define P_M_MV508_ENHANCE_NONE 0x00 /* W Mixer MVD508 Mode control - No stereo enhancement */
|
||||
#define P_M_MV508_ENHANCE_40 0x01 /* W Mixer MVD508 Mode control - 40% stereo enhancement */
|
||||
#define P_M_MV508_ENHANCE_60 0x02 /* W Mixer MVD508 Mode control - 60% stereo enhancement */
|
||||
#define P_M_MV508_ENHANCE_80 0x03 /* W Mixer MVD508 Mode control - 80% stereo enhancement */
|
||||
|
||||
#define P_M_MV508_FM 0x00 /* W Mixer MVD508 Channel 0 - FM */
|
||||
#define P_M_MV508_IMIXER 0x01 /* W Mixer MVD508 Channel 1 - Input mixer (rec monitor) */
|
||||
#define P_M_MV508_LINE 0x02 /* W Mixer MVD508 Channel 2 - Line in */
|
||||
#define P_M_MV508_CDROM 0x03 /* W Mixer MVD508 Channel 3 - CD-ROM */
|
||||
#define P_M_MV508_MIC 0x04 /* W Mixer MVD508 Channel 4 - Microphone */
|
||||
#define P_M_MV508_PCM 0x05 /* W Mixer MVD508 Channel 5 - PCM */
|
||||
#define P_M_MV508_SPEAKER 0x06 /* W Mixer MVD508 Channel 6 - PC Speaker */
|
||||
#define P_M_MV508_SB 0x07 /* W Mixer MVD508 Channel 7 - SB DSP */
|
||||
|
||||
#define SERIAL_MIXER 0xB88 /* R W Control Serial mixer control (used other ways) */
|
||||
#define S_M_PCM_RESET 0x01 /* R W PCM Codec/DSP reset */
|
||||
#define S_M_FM_RESET 0x02 /* R W FM FM chip reset */
|
||||
#define S_M_SB_RESET 0x04 /* R W PCM SB emulation chip reset */
|
||||
#define S_M_MIXER_RESET 0x10 /* R W Mixer Mixer chip reset */
|
||||
#define S_M_INTEGRATOR_ENABLE 0x40 /* R W Speaker Enable PC speaker integrator (FORCE RealSound) */
|
||||
#define S_M_OPL3_DUAL_MONO 0x80 /* R W FM Set the OPL-3 to dual mono mode */
|
||||
|
||||
#define PCM_CONTROL 0xF8A /* R W PCM PCM Control Register */
|
||||
#define P_C_MIXER_CROSS_FIELD 0x0f
|
||||
#define P_C_MIXER_CROSS_R_TO_R 0x01 /* R W Mixer Connect Right to Right */
|
||||
#define P_C_MIXER_CROSS_L_TO_R 0x02 /* R W Mixer Connect Left to Right */
|
||||
#define P_C_MIXER_CROSS_R_TO_L 0x04 /* R W Mixer Connect Right to Left */
|
||||
#define P_C_MIXER_CROSS_L_TO_L 0x08 /* R W Mixer Connect Left to Left */
|
||||
#define P_C_PCM_DAC_MODE 0x10 /* R W PCM Playback (DAC) mode */
|
||||
#define P_C_PCM_ADC_MODE 0x00 /* R W PCM Record (ADC) mode */
|
||||
#define P_C_PCM_MONO 0x20 /* R W PCM Mono mode */
|
||||
#define P_C_PCM_STEREO 0x00 /* R W PCM Stereo mode */
|
||||
#define P_C_PCM_ENABLE 0x40 /* R W PCM Enable PCM engine */
|
||||
#define P_C_PCM_DMA_ENABLE 0x80 /* R W PCM Enable DRQ */
|
||||
|
||||
#define SAMPLE_COUNTER_CONTROL 0x138B /* R W PCM Sample counter control register */
|
||||
#define S_C_C_SQUARE_WAVE 0x04 /* R W PCM Square wave generator (use for sample rate) */
|
||||
#define S_C_C_RATE 0x06 /* R W PCM Rate generator (use for sample buffer count) */
|
||||
#define S_C_C_LSB_THEN_MSB 0x30 /* R W PCM Change all 16 bits, LSB first, then MSB */
|
||||
|
||||
/* MVD101 and SDK documentations have S_C_C_SAMPLE_RATE and S_C_C_SAMPLE_BUFFER transposed. Only one works :-) */
|
||||
#define S_C_C_SAMPLE_RATE 0x00 /* R W PCM Select sample rate timer */
|
||||
#define S_C_C_SAMPLE_BUFFER 0x40 /* R W PCM Select sample buffer counter */
|
||||
|
||||
#define S_C_C_PC_SPEAKER 0x80 /* R W PCM Select PC speaker counter */
|
||||
|
||||
#define SAMPLE_RATE_TIMER 0x1388 /* W PCM Sample rate timer register (PCM wait interval) */
|
||||
#define SAMPLE_BUFFER_COUNTER 0x1389 /* R W PCM Sample buffer counter (DMA buffer size) */
|
||||
|
||||
#define MIDI_CONTROL 0x178b /* R W MIDI Midi control register */
|
||||
#define M_C_ENA_TSTAMP_IRQ 0x01 /* R W MIDI Enable Time Stamp Interrupts */
|
||||
#define M_C_ENA_TME_COMP_IRQ 0x02 /* R W MIDI Enable time compare interrupts */
|
||||
#define M_C_ENA_INPUT_IRQ 0x04 /* R W MIDI Enable input FIFO interrupts */
|
||||
#define M_C_ENA_OUTPUT_IRQ 0x08 /* R W MIDI Enable output FIFO interrupts */
|
||||
#define M_C_ENA_OUTPUT_HALF_IRQ 0x10 /* R W MIDI Enable output FIFO half full interrupts */
|
||||
#define M_C_RESET_INPUT_FIFO 0x20 /* R W MIDI Reset input FIFO pointer */
|
||||
#define M_C_RESET_OUTPUT_FIFO 0x40 /* R W MIDI Reset output FIFO pointer */
|
||||
#define M_C_ENA_THRU_MODE 0x80 /* R W MIDI Echo input to output (THRU) */
|
||||
|
||||
#define MIDI_STATUS 0x1B88 /* R W MIDI Midi (interrupt) status register */
|
||||
#define M_S_TIMESTAMP 0x01 /* R W MIDI Midi time stamp interrupt occurred */
|
||||
#define M_S_COMPARE 0x02 /* R W MIDI Midi compare time interrupt occurred */
|
||||
#define M_S_INPUT_AVAIL 0x04 /* R W MIDI Midi input data available interrupt occurred */
|
||||
#define M_S_OUTPUT_EMPTY 0x08 /* R W MIDI Midi output FIFO empty interrupt occurred */
|
||||
#define M_S_OUTPUT_HALF_EMPTY 0x10 /* R W MIDI Midi output FIFO half empty interrupt occurred */
|
||||
#define M_S_INPUT_OVERRUN 0x20 /* R W MIDI Midi input overrun error occurred */
|
||||
#define M_S_OUTPUT_OVERRUN 0x40 /* R W MIDI Midi output overrun error occurred */
|
||||
#define M_S_FRAMING_ERROR 0x80 /* R W MIDI Midi input framing error occurred */
|
||||
|
||||
#define MIDI_FIFO_STATUS 0x1B89 /* R W MIDI Midi fifo status */
|
||||
#define MIDI_DATA 0x178A /* R W MIDI Midi data register */
|
||||
#define MIDI_INPUT_AVAILABLE 0x0f /* RW MIDI */
|
@ -1,236 +0,0 @@
|
||||
/* */
|
||||
/* Port addresses and bit fields for the Media Vision Pro AudioSpectrum second generation sound cards. */
|
||||
/* */
|
||||
/* Feel free to use this header file in any application you create that has support for the Media Vision */
|
||||
/* Pro AudioSpectrum second generation sound cards. Other uses prohibited without prior permission. */
|
||||
/* */
|
||||
/* - cmetz@thor.tjhsst.edu */
|
||||
/* */
|
||||
/* Notes: */
|
||||
/* */
|
||||
/* * All of these ports go into the MVD101 multimedia controller chip, which then signals the other chips to do */
|
||||
/* the actual work. Many ports like the FM ones functionally attach directly to the destination chip though */
|
||||
/* they don't actually have a direct connection. */
|
||||
/* */
|
||||
/* * The PAS2 series cards have an MVD101 multimedia controller chip, the original PAS cards don't. The original */
|
||||
/* PAS cards are pretty defunct now, so no attempt is made here to support them. */
|
||||
/* */
|
||||
/* * The PAS2 series cards are all really different at the hardware level, though the MVD101 hides some of the */
|
||||
/* incompatibilities, there still are differences that need to be accounted for. */
|
||||
/* */
|
||||
/* Card CD-ROM interface PCM chip Mixer chip FM chip */
|
||||
/* PAS Plus Sony proprietary (Crystal?) 8-bit DAC National OPL3 */
|
||||
/* PAS 16 Zilog SCSI MVA416 16-bit Codec MVA508 OPL3 */
|
||||
/* CDPC Sony proprietary Sony 16-bit Codec National OPL3 */
|
||||
/* Fusion CD 16 Sony proprietary MVA416 16-bit Codec MVA508 OPL3 */
|
||||
/* Fusion CD Sony proprietary (Crystal?) 8-bit DAC National OPL3 */
|
||||
/* */
|
||||
#define PAS_DEFAULT_BASE 0x388
|
||||
|
||||
/* Symbolic Name Value R W Subsystem Description */
|
||||
#define SPEAKER_CONTROL 0x61 /* W PC speaker Control register */
|
||||
#define SPEAKER_CONTROL_GHOST 0x738B /* R W PC speaker Control ghost register */
|
||||
#define SPEAKER_TIMER_CONTROL 0x43 /* W PC speaker Timer control register */
|
||||
#define SPEAKER_TIMER_CONTROL_GHOST 0x778B /* R W PC speaker Timer control register ghost */
|
||||
#define SPEAKER_TIMER_DATA 0x42 /* W PC speaker Timer data register */
|
||||
#define SPEAKER_TIMER_DATA_GHOST 0x138A /* R W PC speaker Timer data register ghost */
|
||||
|
||||
#define WARM_BOOT 0x41 /* W Control Used to detect system warm boot */
|
||||
#define WARM_BOOT_GHOST 0x7789 /* ? W Control Use to get the card to fake warm boot */
|
||||
#define MASTER_DECODE 0x9A01 /* W Control Address >> 2 of card base address */
|
||||
#define PRESCALE_DIVIDER 0xBF8A /* R W PCM Ration between Codec clock and master clock */
|
||||
#define WAIT_STATE 0xBF88 /* R W Control Four-bit bus wait-state count (~140ns ea.) */
|
||||
#define BOARD_REV_ID 0x2789 /* R Control Extended Board Revision ID */
|
||||
|
||||
#define CHIP_REV 0xFF88 /* R 0=PAS, 1=PAS+, 2=CDPC, 3=PAS16C, 4=PAS16D */
|
||||
|
||||
#define SYSTEM_CONFIGURATION_1 0x8388 /* R W Control */
|
||||
# define S_C_1_PCS_ENABLE 0x01 /* R W PC speaker 1=enable, 0=disable PC speaker emulation */
|
||||
# define S_C_1_PCM_CLOCK_SELECT 0x02 /* R W PCM 1=14.31818Mhz/12, 0=28.224Mhz master clock */
|
||||
# define S_C_1_FM_EMULATE_CLOCK 0x04 /* R W FM 1=use 28.224Mhz/2, 0=use 14.31818Mhz clock */
|
||||
# define S_C_1_PCS_STEREO 0x10 /* R W PC speaker 1=enable PC speaker stereo effect, 0=disable */
|
||||
# define S_C_1_PCS_REALSOUND 0x20 /* R W PC speaker 1=enable RealSound enhancement, 0=disable */
|
||||
# define S_C_1_FORCE_EXT_RESET 0x40 /* R W Control Force external reset */
|
||||
# define S_C_1_FORCE_INT_RESET 0x80 /* R W Control Force internal reset */
|
||||
#define SYSTEM_CONFIGURATION_2 0x8389 /* R W Control */
|
||||
# define S_C_2_PCM_OVERSAMPLING 0x03 /* R W PCM 00=0x, 01=2x, 10=4x, 11=reserved */
|
||||
# define S_C_2_PCM_16_BIT 0x04 /* R W PCM 1=16-bit, 0=8-bit samples */
|
||||
#define SYSTEM_CONFIGURATION_3 0x838A /* R W Control */
|
||||
# define S_C_3_PCM_CLOCK_SELECT 0x02 /* R W PCM 1=use 1.008Mhz clock for PCM, 0=don't */
|
||||
#define SYSTEM_CONFIGURATION_4 0x838B /* R W Control CD-ROM interface controls */
|
||||
|
||||
#define IO_CONFIGURATION_1 0xF388 /* R W Control */
|
||||
# define I_C_1_BOOT_RESET_ENABLE 0x80 /* R W Control 1=reset board on warm boot, 0=don't */
|
||||
# define I_C_1_JOYSTICK_ENABLE 0x40 /* R W Control 1=enable joystick port, 0=don't */
|
||||
#define IO_CONFIGURATION_2 0xF389 /* R W Control */
|
||||
# define I_C_2_PCM_DMA_DISABLED 0x00 /* R W PCM PCM DMA disabled */
|
||||
#define IO_CONFIGURATION_3 0xF38A /* R W Control */
|
||||
# define I_C_3_PCM_IRQ_DISABLED 0x00 /* R W PCM PCM IRQ disabled */
|
||||
|
||||
#define COMPATIBILITY_ENABLE 0xF788 /* R W Control */
|
||||
# define C_E_MPU401_ENABLE 0x01 /* R W MIDI 1=enable, 0=disable MPU401 MIDI emulation */
|
||||
# define C_E_SB_ENABLE 0x02 /* R W PCM 1=enable, 0=disable Sound Blaster emulation */
|
||||
# define C_E_SB_ACTIVE 0x04 /* R PCM "Sound Blaster Interrupt active" */
|
||||
# define C_E_MPU401_ACTIVE 0x08 /* R MIDI "MPU UART mode active" */
|
||||
# define C_E_PCM_COMPRESSION 0x10 /* R W PCM 1=enable, 0=disabled compression */
|
||||
#define EMULATION_ADDRESS 0xF789 /* R W Control */
|
||||
# define E_A_SB_BASE 0x0f /* R W PCM bits A4-A7 for SB base port */
|
||||
# define E_A_MPU401_BASE 0xf0 /* R W MIDI bits A4-A7 for MPU401 base port */
|
||||
#define EMULATION_CONFIGURATION 0xFB8A /* R W ***** Only valid on newer PAS2 cards (?) ***** */
|
||||
# define E_C_MPU401_IRQ 0x07 /* R W MIDI MPU401 emulation IRQ */
|
||||
# define E_C_SB_IRQ 0x38 /* R W PCM SB emulation IRQ */
|
||||
# define E_C_SB_DMA 0xC0 /* R W PCM SB emulation DMA */
|
||||
|
||||
#define OPERATION_MODE_1 0xEF8B /* R Control */
|
||||
# define O_M_1_CDROM_TYPE 0x03 /* R CD-ROM 3=SCSI, 2=Sony, 0=no CD-ROM interface */
|
||||
# define O_M_1_FM_TYPE 0x04 /* R FM 1=sterero, 0=mono FM chip */
|
||||
# define O_M_1_PCM_TYPE 0x08 /* R PCM 1=16-bit Codec, 0=8-bit DAC */
|
||||
#define OPERATION_MODE_2 0xFF8B /* R Control */
|
||||
# define O_M_2_PCS_ENABLED 0x02 /* R PC speaker PC speaker emulation 1=enabled, 0=disabled */
|
||||
# define O_M_2_BUS_TIMING 0x10 /* R Control 1=AT bus timing, 0=XT bus timing */
|
||||
# define O_M_2_BOARD_REVISION 0xe0 /* R Control Board revision */
|
||||
|
||||
#define INTERRUPT_MASK 0x0B8B /* R W Control */
|
||||
# define I_M_FM_LEFT_IRQ_ENABLE 0x01 /* R W FM Enable FM left interrupt */
|
||||
# define I_M_FM_RIGHT_IRQ_ENABLE 0x02 /* R W FM Enable FM right interrupt */
|
||||
# define I_M_PCM_RATE_IRQ_ENABLE 0x04 /* R W PCM Enable Sample Rate interrupt */
|
||||
# define I_M_PCM_BUFFER_IRQ_ENABLE 0x08 /* R W PCM Enable Sample Buffer interrupt */
|
||||
# define I_M_MIDI_IRQ_ENABLE 0x10 /* R W MIDI Enable MIDI interrupt */
|
||||
# define I_M_BOARD_REV 0xE0 /* R Control Board revision */
|
||||
|
||||
#define INTERRUPT_STATUS 0x0B89 /* R W Control */
|
||||
# define I_S_FM_LEFT_IRQ 0x01 /* R W FM Left FM Interrupt Pending */
|
||||
# define I_S_FM_RIGHT_IRQ 0x02 /* R W FM Right FM Interrupt Pending */
|
||||
# define I_S_PCM_SAMPLE_RATE_IRQ 0x04 /* R W PCM Sample Rate Interrupt Pending */
|
||||
# define I_S_PCM_SAMPLE_BUFFER_IRQ 0x08 /* R W PCM Sample Buffer Interrupt Pending */
|
||||
# define I_S_MIDI_IRQ 0x10 /* R W MIDI MIDI Interrupt Pending */
|
||||
# define I_S_PCM_CHANNEL 0x20 /* R W PCM 1=right, 0=left */
|
||||
# define I_S_RESET_ACTIVE 0x40 /* R W Control Reset is active (Timed pulse not finished) */
|
||||
# define I_S_PCM_CLIPPING 0x80 /* R W PCM Clipping has occurred */
|
||||
|
||||
#define FILTER_FREQUENCY 0x0B8A /* R W Control */
|
||||
# define F_F_FILTER_DISABLED 0x00 /* R W Mixer No filter */
|
||||
# define F_F_MIXER_UNMUTE 0x20 /* R W Mixer 1=disable, 0=enable board mute */
|
||||
# define F_F_PCM_RATE_COUNTER 0x40 /* R W PCM 1=enable, 0=disable sample rate counter */
|
||||
# define F_F_PCM_BUFFER_COUNTER 0x80 /* R W PCM 1=enable, 0=disable sample buffer counter */
|
||||
|
||||
#define PAS_NONE 0
|
||||
#define PAS_PLUS 1
|
||||
#define PAS_CDPC 2
|
||||
#define PAS_16 3
|
||||
#define PAS_16D 4
|
||||
|
||||
#ifdef DEFINE_TRANSLATIONS
|
||||
unsigned char I_C_2_PCM_DMA_translate[] = /* R W PCM PCM DMA channel value translations */
|
||||
{ 4, 1, 2, 3, 0, 5, 6, 7 };
|
||||
unsigned char I_C_3_PCM_IRQ_translate[] = /* R W PCM PCM IRQ level value translation */
|
||||
{ 0, 0, 1, 2, 3, 4, 5, 6, 0, 1, 7, 8, 9, 0, 10, 11 };
|
||||
unsigned char E_C_MPU401_IRQ_translate[] = /* R W MIDI MPU401 emulation IRQ value translation */
|
||||
{ 0x00, 0x00, 0x01, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x01, 0x05, 0x06, 0x07 };
|
||||
unsigned char E_C_SB_IRQ_translate[] = /* R W PCM SB emulation IRQ translate */
|
||||
{ 0x00, 0x00, 0x08, 0x10, 0x00, 0x18, 0x00, 0x20, 0x00, 0x08, 0x28, 0x30, 0x38, 0, 0 };
|
||||
unsigned char E_C_SB_DMA_translate[] = /* R W PCM SB emulation DMA translate */
|
||||
{ 0x00, 0x40, 0x80, 0xC0, 0, 0, 0, 0 };
|
||||
unsigned char O_M_1_to_card[] = /* R W Control Translate (OM1 & 0x0f) to card type */
|
||||
{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 2, 3 };
|
||||
#else
|
||||
extern unsigned char I_C_2_PCM_DMA_translate[]; /* R W PCM PCM DMA channel value translations */
|
||||
extern unsigned char I_C_3_PCM_IRQ_translate[]; /* R W PCM PCM IRQ level value translation */
|
||||
extern unsigned char E_C_MPU401_IRQ_translate[]; /* R W MIDI MPU401 emulation IRQ value translation */
|
||||
extern unsigned char E_C_SB_IRQ_translate[]; /* R W PCM SB emulation IRQ translate */
|
||||
extern unsigned char E_C_SB_DMA_translate[]; /* R W PCM SB emulation DMA translate */
|
||||
extern unsigned char O_M_1_to_card[]; /* R W Control Translate (OM1 & 0x0f) to card type */
|
||||
#endif
|
||||
|
||||
#define PARALLEL_MIXER 0x078B /* W Mixer Documented for MVD101 as FM Mono Right decode?? */
|
||||
# define P_M_MV508_ADDRESS 0x80 /* W Mixer MVD508 Address/mixer select */
|
||||
# define P_M_MV508_DATA 0x00
|
||||
# define P_M_MV508_LEFT 0x20 /* W Mixer MVD508 Left channel select */
|
||||
# define P_M_MV508_RIGHT 0x40 /* W Mixer MVD508 Right channel select */
|
||||
# define P_M_MV508_BOTH 0x00 /* W Mixer MVD508 Both channel select */
|
||||
# define P_M_MV508_MIXER 0x10 /* W Mixer MVD508 Select a mixer (rather than a volume) */
|
||||
# define P_M_MV508_VOLUME 0x00
|
||||
|
||||
# define P_M_MV508_INPUTMIX 0x20 /* W Mixer MVD508 Select mixer A */
|
||||
# define P_M_MV508_OUTPUTMIX 0x00 /* W Mixer MVD508 Select mixer B */
|
||||
|
||||
# define P_M_MV508_MASTER_A 0x01 /* W Mixer MVD508 Master volume control A (output) */
|
||||
# define P_M_MV508_MASTER_B 0x02 /* W Mixer MVD508 Master volume control B (DSP input) */
|
||||
# define P_M_MV508_BASS 0x03 /* W Mixer MVD508 Bass control */
|
||||
# define P_M_MV508_TREBLE 0x04 /* W Mixer MVD508 Treble control */
|
||||
# define P_M_MV508_MODE 0x05 /* W Mixer MVD508 Master mode control */
|
||||
|
||||
# define P_M_MV508_LOUDNESS 0x04 /* W Mixer MVD508 Mode control - Loudness filter */
|
||||
# define P_M_MV508_ENHANCE_BITS 0x03
|
||||
# define P_M_MV508_ENHANCE_NONE 0x00 /* W Mixer MVD508 Mode control - No stereo enhancement */
|
||||
# define P_M_MV508_ENHANCE_40 0x01 /* W Mixer MVD508 Mode control - 40% stereo enhancement */
|
||||
# define P_M_MV508_ENHANCE_60 0x02 /* W Mixer MVD508 Mode control - 60% stereo enhancement */
|
||||
# define P_M_MV508_ENHANCE_80 0x03 /* W Mixer MVD508 Mode control - 80% stereo enhancement */
|
||||
|
||||
# define P_M_MV508_FM 0x00 /* W Mixer MVD508 Channel 0 - FM */
|
||||
# define P_M_MV508_IMIXER 0x01 /* W Mixer MVD508 Channel 1 - Input mixer (rec monitor) */
|
||||
# define P_M_MV508_LINE 0x02 /* W Mixer MVD508 Channel 2 - Line in */
|
||||
# define P_M_MV508_CDROM 0x03 /* W Mixer MVD508 Channel 3 - CD-ROM */
|
||||
# define P_M_MV508_MIC 0x04 /* W Mixer MVD508 Channel 4 - Microphone */
|
||||
# define P_M_MV508_PCM 0x05 /* W Mixer MVD508 Channel 5 - PCM */
|
||||
# define P_M_MV508_SPEAKER 0x06 /* W Mixer MVD508 Channel 6 - PC Speaker */
|
||||
# define P_M_MV508_SB 0x07 /* W Mixer MVD508 Channel 7 - SB DSP */
|
||||
|
||||
#define SERIAL_MIXER 0xB88 /* R W Control Serial mixer control (used other ways) */
|
||||
# define S_M_PCM_RESET 0x01 /* R W PCM Codec/DSP reset */
|
||||
# define S_M_FM_RESET 0x02 /* R W FM FM chip reset */
|
||||
# define S_M_SB_RESET 0x04 /* R W PCM SB emulation chip reset */
|
||||
# define S_M_MIXER_RESET 0x10 /* R W Mixer Mixer chip reset */
|
||||
# define S_M_INTEGRATOR_ENABLE 0x40 /* R W Speaker Enable PC speaker integrator (FORCE RealSound) */
|
||||
# define S_M_OPL3_DUAL_MONO 0x80 /* R W FM Set the OPL-3 to dual mono mode */
|
||||
|
||||
#define PCM_CONTROL 0xF8A /* R W PCM PCM Control Register */
|
||||
# define P_C_MIXER_CROSS_FIELD 0x0f
|
||||
# define P_C_MIXER_CROSS_R_TO_R 0x01 /* R W Mixer Connect Right to Right */
|
||||
# define P_C_MIXER_CROSS_L_TO_R 0x02 /* R W Mixer Connect Left to Right */
|
||||
# define P_C_MIXER_CROSS_R_TO_L 0x04 /* R W Mixer Connect Right to Left */
|
||||
# define P_C_MIXER_CROSS_L_TO_L 0x08 /* R W Mixer Connect Left to Left */
|
||||
# define P_C_PCM_DAC_MODE 0x10 /* R W PCM Playback (DAC) mode */
|
||||
# define P_C_PCM_ADC_MODE 0x00 /* R W PCM Record (ADC) mode */
|
||||
# define P_C_PCM_MONO 0x20 /* R W PCM Mono mode */
|
||||
# define P_C_PCM_STEREO 0x00 /* R W PCM Stereo mode */
|
||||
# define P_C_PCM_ENABLE 0x40 /* R W PCM Enable PCM engine */
|
||||
# define P_C_PCM_DMA_ENABLE 0x80 /* R W PCM Enable DRQ */
|
||||
|
||||
#define SAMPLE_COUNTER_CONTROL 0x138B /* R W PCM Sample counter control register */
|
||||
# define S_C_C_SQUARE_WAVE 0x04 /* R W PCM Square wave generator (use for sample rate) */
|
||||
# define S_C_C_RATE 0x06 /* R W PCM Rate generator (use for sample buffer count) */
|
||||
# define S_C_C_LSB_THEN_MSB 0x30 /* R W PCM Change all 16 bits, LSB first, then MSB */
|
||||
|
||||
/* MVD101 and SDK documentations have S_C_C_SAMPLE_RATE and S_C_C_SAMPLE_BUFFER transposed. Only one works :-) */
|
||||
# define S_C_C_SAMPLE_RATE 0x00 /* R W PCM Select sample rate timer */
|
||||
# define S_C_C_SAMPLE_BUFFER 0x40 /* R W PCM Select sample buffer counter */
|
||||
|
||||
# define S_C_C_PC_SPEAKER 0x80 /* R W PCM Select PC speaker counter */
|
||||
|
||||
#define SAMPLE_RATE_TIMER 0x1388 /* W PCM Sample rate timer register (PCM wait interval) */
|
||||
#define SAMPLE_BUFFER_COUNTER 0x1389 /* R W PCM Sample buffer counter (DMA buffer size) */
|
||||
|
||||
#define MIDI_CONTROL 0x178b /* R W MIDI Midi control register */
|
||||
# define M_C_ENA_TSTAMP_IRQ 0x01 /* R W MIDI Enable Time Stamp Interrupts */
|
||||
# define M_C_ENA_TME_COMP_IRQ 0x02 /* R W MIDI Enable time compare interrupts */
|
||||
# define M_C_ENA_INPUT_IRQ 0x04 /* R W MIDI Enable input FIFO interrupts */
|
||||
# define M_C_ENA_OUTPUT_IRQ 0x08 /* R W MIDI Enable output FIFO interrupts */
|
||||
# define M_C_ENA_OUTPUT_HALF_IRQ 0x10 /* R W MIDI Enable output FIFO half full interrupts */
|
||||
# define M_C_RESET_INPUT_FIFO 0x20 /* R W MIDI Reset input FIFO pointer */
|
||||
# define M_C_RESET_OUTPUT_FIFO 0x40 /* R W MIDI Reset output FIFO pointer */
|
||||
# define M_C_ENA_THRU_MODE 0x80 /* R W MIDI Echo input to output (THRU) */
|
||||
|
||||
#define MIDI_STATUS 0x1B88 /* R W MIDI Midi (interrupt) status register */
|
||||
# define M_S_TIMESTAMP 0x01 /* R W MIDI Midi time stamp interrupt occurred */
|
||||
# define M_S_COMPARE 0x02 /* R W MIDI Midi compare time interrupt occurred */
|
||||
# define M_S_INPUT_AVAIL 0x04 /* R W MIDI Midi input data available interrupt occurred */
|
||||
# define M_S_OUTPUT_EMPTY 0x08 /* R W MIDI Midi output FIFO empty interrupt occurred */
|
||||
# define M_S_OUTPUT_HALF_EMPTY 0x10 /* R W MIDI Midi output FIFO half empty interrupt occurred */
|
||||
# define M_S_INPUT_OVERRUN 0x20 /* R W MIDI Midi input overrun error occurred */
|
||||
# define M_S_OUTPUT_OVERRUN 0x40 /* R W MIDI Midi output overrun error occurred */
|
||||
# define M_S_FRAMING_ERROR 0x80 /* R W MIDI Midi input framing error occurred */
|
||||
|
||||
#define MIDI_FIFO_STATUS 0x1B89 /* R W MIDI Midi fifo status */
|
||||
#define MIDI_DATA 0x178A /* R W MIDI Midi data register */
|
||||
#define MIDI_INPUT_AVAILABLE 0x0f /* RW MIDI */
|
@ -1,267 +0,0 @@
|
||||
/*
|
||||
* sound/patmgr.c
|
||||
*
|
||||
* The patch maneger interface for the /dev/sequencer
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#define PATMGR_C
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if defined(CONFIG_SEQUENCER)
|
||||
|
||||
static int *server_procs[MAX_SYNTH_DEV] = {NULL};
|
||||
static volatile struct snd_wait server_wait_flag[MAX_SYNTH_DEV] = { {0}};
|
||||
|
||||
static struct patmgr_info *mbox[MAX_SYNTH_DEV] = {NULL};
|
||||
static volatile int msg_direction[MAX_SYNTH_DEV] = {0};
|
||||
|
||||
static int pmgr_opened[MAX_SYNTH_DEV] = {0};
|
||||
|
||||
#define A_TO_S 1
|
||||
#define S_TO_A 2
|
||||
|
||||
static int *appl_proc = NULL;
|
||||
static volatile struct snd_wait appl_wait_flag =
|
||||
{0};
|
||||
|
||||
int
|
||||
pmgr_open(int dev)
|
||||
{
|
||||
if (dev < 0 || dev >= num_synths)
|
||||
return -(ENXIO);
|
||||
|
||||
if (pmgr_opened[dev])
|
||||
return -(EBUSY);
|
||||
pmgr_opened[dev] = 1;
|
||||
|
||||
server_wait_flag[dev].aborting = 0;
|
||||
server_wait_flag[dev].mode = WK_NONE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
pmgr_release(int dev)
|
||||
{
|
||||
|
||||
if (mbox[dev]) { /* Killed in action. Inform the client */
|
||||
|
||||
mbox[dev]->key = PM_ERROR;
|
||||
mbox[dev]->parm1 = -(EIO);
|
||||
|
||||
if ((appl_wait_flag.mode & WK_SLEEP)) {
|
||||
appl_wait_flag.mode = WK_WAKEUP;
|
||||
wakeup(appl_proc);
|
||||
};
|
||||
}
|
||||
pmgr_opened[dev] = 0;
|
||||
}
|
||||
|
||||
int
|
||||
pmgr_read(int dev, struct fileinfo * file, snd_rw_buf * buf, int count)
|
||||
{
|
||||
u_long flags;
|
||||
int ok = 0;
|
||||
|
||||
if (count != sizeof(struct patmgr_info)) {
|
||||
printf("PATMGR%d: Invalid read count\n", dev);
|
||||
return -(EIO);
|
||||
}
|
||||
while (!ok && !(server_wait_flag[dev].aborting)) {
|
||||
flags = splhigh();
|
||||
|
||||
while (!(mbox[dev] && msg_direction[dev] == A_TO_S) &&
|
||||
!(server_wait_flag[dev].aborting)) {
|
||||
|
||||
int chn;
|
||||
server_procs[dev] = &chn;
|
||||
DO_SLEEP(chn, server_wait_flag[dev], 0);
|
||||
|
||||
}
|
||||
|
||||
if (mbox[dev] && msg_direction[dev] == A_TO_S) {
|
||||
|
||||
if (uiomove((char *) mbox[dev], count, buf)) {
|
||||
printf("sb: Bad copyout()!\n");
|
||||
};
|
||||
msg_direction[dev] = 0;
|
||||
ok = 1;
|
||||
}
|
||||
splx(flags);
|
||||
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
return -(EINTR);
|
||||
return count;
|
||||
}
|
||||
|
||||
int
|
||||
pmgr_write(int dev, struct fileinfo * file, snd_rw_buf * buf, int count)
|
||||
{
|
||||
u_long flags;
|
||||
|
||||
if (count < 4) {
|
||||
printf("PATMGR%d: Write count < 4\n", dev);
|
||||
return -(EIO);
|
||||
}
|
||||
if (uiomove((char *) mbox[dev], 4, buf)) {
|
||||
printf("sb: Bad copyin()!\n");
|
||||
};
|
||||
|
||||
if (*(u_char *) mbox[dev] == SEQ_FULLSIZE) {
|
||||
int tmp_dev;
|
||||
|
||||
tmp_dev = ((u_short *) mbox[dev])[2];
|
||||
if (tmp_dev != dev)
|
||||
return -(ENXIO);
|
||||
|
||||
return synth_devs[dev]->load_patch(dev, *(u_short *) mbox[dev],
|
||||
buf, 4, count, 1);
|
||||
}
|
||||
if (count != sizeof(struct patmgr_info)) {
|
||||
printf("PATMGR%d: Invalid write count\n", dev);
|
||||
return -(EIO);
|
||||
}
|
||||
/*
|
||||
* If everything went OK, there should be a preallocated buffer in
|
||||
* the mailbox and a client waiting.
|
||||
*/
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
if (mbox[dev] && !msg_direction[dev]) {
|
||||
|
||||
if (uiomove(&((char *) mbox[dev])[4], count - 4, buf)) {
|
||||
printf("sb: Bad copyin()!\n");
|
||||
};
|
||||
msg_direction[dev] = S_TO_A;
|
||||
|
||||
if ((appl_wait_flag.mode & WK_SLEEP)) {
|
||||
appl_wait_flag.mode = WK_WAKEUP;
|
||||
wakeup(appl_proc);
|
||||
}
|
||||
}
|
||||
splx(flags);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int
|
||||
pmgr_access(int dev, struct patmgr_info * rec)
|
||||
{
|
||||
u_long flags;
|
||||
int err = 0;
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
if (mbox[dev])
|
||||
printf(" PATMGR: Server %d mbox full. Why?\n", dev);
|
||||
else {
|
||||
int chn;
|
||||
|
||||
rec->key = PM_K_COMMAND;
|
||||
mbox[dev] = rec;
|
||||
msg_direction[dev] = A_TO_S;
|
||||
|
||||
if ((server_wait_flag[dev].mode & WK_SLEEP)) {
|
||||
server_wait_flag[dev].mode = WK_WAKEUP;
|
||||
wakeup(server_procs[dev]);
|
||||
}
|
||||
|
||||
|
||||
appl_proc = &chn;
|
||||
DO_SLEEP(chn, appl_wait_flag, 0);
|
||||
|
||||
if (msg_direction[dev] != S_TO_A) {
|
||||
rec->key = PM_ERROR;
|
||||
rec->parm1 = -(EIO);
|
||||
} else if (rec->key == PM_ERROR) {
|
||||
err = rec->parm1;
|
||||
if (err > 0)
|
||||
err = -err;
|
||||
}
|
||||
mbox[dev] = NULL;
|
||||
msg_direction[dev] = 0;
|
||||
}
|
||||
|
||||
splx(flags);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
pmgr_inform(int dev, int event, u_long p1, u_long p2, u_long p3, u_long p4)
|
||||
{
|
||||
u_long flags;
|
||||
int err = 0;
|
||||
|
||||
struct patmgr_info *tmp_mbox;
|
||||
|
||||
if (!pmgr_opened[dev])
|
||||
return 0;
|
||||
|
||||
tmp_mbox = (struct patmgr_info *) malloc(sizeof(struct patmgr_info), M_TEMP, M_WAITOK);
|
||||
|
||||
if (tmp_mbox == NULL) {
|
||||
printf("pmgr: Couldn't allocate memory for a message\n");
|
||||
return 0;
|
||||
}
|
||||
flags = splhigh();
|
||||
|
||||
if (mbox[dev])
|
||||
printf(" PATMGR: Server %d mbox full. Why?\n", dev);
|
||||
else {
|
||||
int chn;
|
||||
|
||||
mbox[dev] = tmp_mbox;
|
||||
mbox[dev]->key = PM_K_EVENT;
|
||||
mbox[dev]->command = event;
|
||||
mbox[dev]->parm1 = p1;
|
||||
mbox[dev]->parm2 = p2;
|
||||
mbox[dev]->parm3 = p3;
|
||||
msg_direction[dev] = A_TO_S;
|
||||
|
||||
if ((server_wait_flag[dev].mode & WK_SLEEP)) {
|
||||
server_wait_flag[dev].mode = WK_WAKEUP;
|
||||
wakeup(server_procs[dev]);
|
||||
}
|
||||
|
||||
|
||||
appl_proc = &chn;
|
||||
DO_SLEEP(chn, appl_wait_flag, 0);
|
||||
|
||||
mbox[dev] = NULL;
|
||||
msg_direction[dev] = 0;
|
||||
}
|
||||
|
||||
splx(flags);
|
||||
free(tmp_mbox, M_TEMP);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,693 +0,0 @@
|
||||
/*
|
||||
* sound/pss.c
|
||||
*
|
||||
* The low level driver for the Personal Sound System (ECHO ESC614).
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if defined(CONFIG_PSS) && defined(CONFIG_AUDIO)
|
||||
|
||||
/*
|
||||
* PSS registers.
|
||||
*/
|
||||
#define REG(x) (devc->base+x)
|
||||
#define PSS_DATA 0
|
||||
#define PSS_STATUS 2
|
||||
#define PSS_CONTROL 2
|
||||
#define PSS_ID 4
|
||||
#define PSS_IRQACK 4
|
||||
#define PSS_PIO 0x1a
|
||||
|
||||
/*
|
||||
* Config registers
|
||||
*/
|
||||
#define CONF_PSS 0x10
|
||||
#define CONF_WSS 0x12
|
||||
#define CONF_SB 0x13
|
||||
#define CONF_CDROM 0x16
|
||||
#define CONF_MIDI 0x18
|
||||
|
||||
/*
|
||||
* Status bits.
|
||||
*/
|
||||
#define PSS_FLAG3 0x0800
|
||||
#define PSS_FLAG2 0x0400
|
||||
#define PSS_FLAG1 0x1000
|
||||
#define PSS_FLAG0 0x0800
|
||||
#define PSS_WRITE_EMPTY 0x8000
|
||||
#define PSS_READ_FULL 0x4000
|
||||
|
||||
#include "coproc.h"
|
||||
|
||||
#ifdef PSS_HAVE_LD
|
||||
#include "synth-ld.h"
|
||||
#else
|
||||
static int pss_synthLen = 0;
|
||||
static u_char pss_synth[1] =
|
||||
{0};
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct pss_config {
|
||||
int base;
|
||||
int irq;
|
||||
int dma;
|
||||
sound_os_info *osp;
|
||||
} pss_config;
|
||||
|
||||
static pss_config pss_data;
|
||||
static pss_config *devc = &pss_data;
|
||||
|
||||
static int pss_initialized = 0;
|
||||
static int nonstandard_microcode = 0;
|
||||
|
||||
int
|
||||
probe_pss(struct address_info * hw_config)
|
||||
{
|
||||
u_short id;
|
||||
int irq, dma;
|
||||
|
||||
devc->base = hw_config->io_base;
|
||||
irq = devc->irq = hw_config->irq;
|
||||
dma = devc->dma = hw_config->dma;
|
||||
devc->osp = hw_config->osp;
|
||||
|
||||
/* these are the possible addresses */
|
||||
if (devc->base != 0x220 && devc->base != 0x240 &&
|
||||
devc->base != 0x230 && devc->base != 0x250)
|
||||
return 0;
|
||||
|
||||
/* these are the possible irqs */
|
||||
if (irq != 3 && irq != 5 && irq != 7 && irq != 9 &&
|
||||
irq != 10 && irq != 11 && irq != 12)
|
||||
return 0;
|
||||
|
||||
/* and these are the possible dmas */
|
||||
if (dma != 5 && dma != 6 && dma != 7)
|
||||
return 0;
|
||||
|
||||
id = inb(REG(PSS_ID));
|
||||
|
||||
/* XXX the following test cannot possibly succeed! - lr970714 */
|
||||
if ((id >> 8) != 'E') {
|
||||
/*
|
||||
* printf ("No PSS signature detected at 0x%x (0x%x)\n",
|
||||
* devc->base, id);
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
set_irq(pss_config * devc, int dev, int irq)
|
||||
{
|
||||
static u_short irq_bits[16] =
|
||||
{
|
||||
0x0000, 0x0000, 0x0000, 0x0008,
|
||||
0x0000, 0x0010, 0x0000, 0x0018,
|
||||
0x0000, 0x0020, 0x0028, 0x0030,
|
||||
0x0038, 0x0000, 0x0000, 0x0000
|
||||
};
|
||||
|
||||
u_short tmp, bits;
|
||||
|
||||
if (irq < 0 || irq > 15)
|
||||
return 0;
|
||||
|
||||
tmp = inb(REG(dev)) & ~0x38; /* Load confreg, mask IRQ bits out */
|
||||
|
||||
if ((bits = irq_bits[irq]) == 0 && irq != 0) {
|
||||
printf("PSS: Invalid IRQ %d\n", irq);
|
||||
return 0;
|
||||
}
|
||||
outw(REG(dev), tmp | bits);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
set_io_base(pss_config * devc, int dev, int base)
|
||||
{
|
||||
u_short tmp = inb(REG(dev)) & 0x003f;
|
||||
u_short bits = (base & 0x0ffc) << 4;
|
||||
|
||||
outw(REG(dev), bits | tmp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
set_dma(pss_config * devc, int dev, int dma)
|
||||
{
|
||||
static u_short dma_bits[8] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0000, 0x0003,
|
||||
0x0000, 0x0005, 0x0006, 0x0007
|
||||
};
|
||||
|
||||
u_short tmp, bits;
|
||||
|
||||
if (dma < 0 || dma > 7)
|
||||
return 0;
|
||||
|
||||
tmp = inb(REG(dev)) & ~0x07; /* Load confreg, mask DMA bits out */
|
||||
|
||||
if ((bits = dma_bits[dma]) == 0 && dma != 4) {
|
||||
printf("PSS: Invalid DMA %d\n", dma);
|
||||
return 0;
|
||||
}
|
||||
outw(REG(dev), tmp | bits);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pss_reset_dsp(pss_config * devc)
|
||||
{
|
||||
u_long i, limit = get_time() + 10;
|
||||
|
||||
outw(REG(PSS_CONTROL), 0x2000);
|
||||
|
||||
for (i = 0; i < 32768 && get_time() < limit; i++)
|
||||
inb(REG(PSS_CONTROL));
|
||||
|
||||
outw(REG(PSS_CONTROL), 0x0000);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pss_put_dspword(pss_config * devc, u_short word)
|
||||
{
|
||||
int i, val;
|
||||
|
||||
for (i = 0; i < 327680; i++) {
|
||||
val = inb(REG(PSS_STATUS));
|
||||
if (val & PSS_WRITE_EMPTY) {
|
||||
outw(REG(PSS_DATA), word);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pss_get_dspword(pss_config * devc, u_short *word)
|
||||
{
|
||||
int i, val;
|
||||
|
||||
for (i = 0; i < 327680; i++) {
|
||||
val = inb(REG(PSS_STATUS));
|
||||
if (val & PSS_READ_FULL) {
|
||||
*word = inb(REG(PSS_DATA));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pss_download_boot(pss_config * devc, u_char *block, int size, int flags)
|
||||
{
|
||||
int i, limit, val, count;
|
||||
|
||||
if (flags & CPF_FIRST) {
|
||||
/* _____ Warn DSP software that a boot is coming */
|
||||
outw(REG(PSS_DATA), 0x00fe);
|
||||
|
||||
limit = get_time() + 10;
|
||||
|
||||
for (i = 0; i < 32768 && get_time() < limit; i++)
|
||||
if (inb(REG(PSS_DATA)) == 0x5500)
|
||||
break;
|
||||
|
||||
outw(REG(PSS_DATA), *block++);
|
||||
|
||||
pss_reset_dsp(devc);
|
||||
}
|
||||
count = 1;
|
||||
while (1) {
|
||||
int j;
|
||||
|
||||
for (j = 0; j < 327670; j++) {
|
||||
/* _____ Wait for BG to appear */
|
||||
if (inb(REG(PSS_STATUS)) & PSS_FLAG3)
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == 327670) {
|
||||
/* It's ok we timed out when the file was empty */
|
||||
if (count >= size && flags & CPF_LAST)
|
||||
break;
|
||||
else {
|
||||
printf("\nPSS: DownLoad timeout problems, byte %d=%d\n",
|
||||
count, size);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* _____ Send the next byte */
|
||||
outw(REG(PSS_DATA), *block++);
|
||||
count++;
|
||||
}
|
||||
|
||||
if (flags & CPF_LAST) {
|
||||
/* _____ Why */
|
||||
outw(REG(PSS_DATA), 0);
|
||||
|
||||
limit = get_time() + 10;
|
||||
for (i = 0; i < 32768 && get_time() < limit; i++)
|
||||
val = inb(REG(PSS_STATUS));
|
||||
|
||||
limit = get_time() + 10;
|
||||
for (i = 0; i < 32768 && get_time() < limit; i++) {
|
||||
val = inb(REG(PSS_STATUS));
|
||||
if (val & 0x4000)
|
||||
break;
|
||||
}
|
||||
|
||||
/* now read the version */
|
||||
for (i = 0; i < 32000; i++) {
|
||||
val = inb(REG(PSS_STATUS));
|
||||
if (val & PSS_READ_FULL)
|
||||
break;
|
||||
}
|
||||
if (i == 32000)
|
||||
return 0;
|
||||
|
||||
val = inb(REG(PSS_DATA));
|
||||
/*
|
||||
* printf("<PSS: microcode version %d.%d loaded>", val/16,
|
||||
* val % 16);
|
||||
*/
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
attach_pss(struct address_info * hw_config)
|
||||
{
|
||||
u_short id;
|
||||
char tmp[100];
|
||||
|
||||
devc->base = hw_config->io_base;
|
||||
devc->irq = hw_config->irq;
|
||||
devc->dma = hw_config->dma;
|
||||
devc->osp = hw_config->osp;
|
||||
|
||||
if (!probe_pss(hw_config))
|
||||
return;
|
||||
|
||||
id = inb(REG(PSS_ID)) & 0x00ff;
|
||||
|
||||
/*
|
||||
* Disable all emulations. Will be enabled later (if required).
|
||||
*/
|
||||
outw(REG(CONF_PSS), 0x0000);
|
||||
outw(REG(CONF_WSS), 0x0000);
|
||||
outw(REG(CONF_SB), 0x0000);
|
||||
outw(REG(CONF_MIDI), 0x0000);
|
||||
outw(REG(CONF_CDROM), 0x0000);
|
||||
|
||||
#if YOU_REALLY_WANT_TO_ALLOCATE_THESE_RESOURCES
|
||||
if (0) {
|
||||
printf("pss.c: Can't allocate DMA channel\n");
|
||||
return;
|
||||
}
|
||||
if (!set_irq(devc, CONF_PSS, devc->irq)) {
|
||||
printf("PSS: IRQ error\n");
|
||||
return;
|
||||
}
|
||||
if (!set_dma(devc, CONF_PSS, devc->dma)) {
|
||||
printf("PSS: DRQ error\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
pss_initialized = 1;
|
||||
snprintf(tmp, sizeof(tmp), "ECHO-PSS Rev. %d", id);
|
||||
conf_printf(tmp, hw_config);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
probe_pss_mpu(struct address_info * hw_config)
|
||||
{
|
||||
int timeout;
|
||||
|
||||
if (!pss_initialized)
|
||||
return 0;
|
||||
|
||||
if (0) {
|
||||
printf("PSS: MPU I/O port conflict\n");
|
||||
return 0;
|
||||
}
|
||||
if (!set_io_base(devc, CONF_MIDI, hw_config->io_base)) {
|
||||
printf("PSS: MIDI base error.\n");
|
||||
return 0;
|
||||
}
|
||||
if (!set_irq(devc, CONF_MIDI, hw_config->irq)) {
|
||||
printf("PSS: MIDI IRQ error.\n");
|
||||
return 0;
|
||||
}
|
||||
if (!pss_synthLen) {
|
||||
printf("PSS: Can't enable MPU. MIDI synth microcode not available.\n");
|
||||
return 0;
|
||||
}
|
||||
if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST)) {
|
||||
printf("PSS: Unable to load MIDI synth microcode to DSP.\n");
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Finally wait until the DSP algorithm has initialized itself and
|
||||
* deactivates receive interrupt.
|
||||
*/
|
||||
|
||||
for (timeout = 900000; timeout > 0; timeout--) {
|
||||
if ((inb(hw_config->io_base + 1) & 0x80) == 0) /* Input data avail */
|
||||
inb(hw_config->io_base); /* Discard it */
|
||||
else
|
||||
break; /* No more input */
|
||||
}
|
||||
|
||||
#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
|
||||
return probe_mpu401(hw_config);
|
||||
#else
|
||||
return 0
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
pss_coproc_open(void *dev_info, int sub_device)
|
||||
{
|
||||
switch (sub_device) {
|
||||
case COPR_MIDI:
|
||||
|
||||
if (pss_synthLen == 0) {
|
||||
printf("PSS: MIDI synth microcode not available.\n");
|
||||
return -(EIO);
|
||||
}
|
||||
if (nonstandard_microcode)
|
||||
if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST)) {
|
||||
printf("PSS: Unable to load MIDI synth microcode to DSP.\n");
|
||||
return -(EIO);
|
||||
}
|
||||
nonstandard_microcode = 0;
|
||||
break;
|
||||
|
||||
default:;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pss_coproc_close(void *dev_info, int sub_device)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
pss_coproc_reset(void *dev_info)
|
||||
{
|
||||
if (pss_synthLen)
|
||||
if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST)) {
|
||||
printf("PSS: Unable to load MIDI synth microcode to DSP.\n");
|
||||
}
|
||||
nonstandard_microcode = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
download_boot_block(void *dev_info, copr_buffer * buf)
|
||||
{
|
||||
if (buf->len <= 0 || buf->len > sizeof(buf->data))
|
||||
return -(EINVAL);
|
||||
|
||||
if (!pss_download_boot(devc, buf->data, buf->len, buf->flags)) {
|
||||
printf("PSS: Unable to load microcode block to DSP.\n");
|
||||
return -(EIO);
|
||||
}
|
||||
nonstandard_microcode = 1; /* The MIDI microcode has been
|
||||
* overwritten */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pss_coproc_ioctl(void *dev_info, u_int cmd, ioctl_arg arg, int local)
|
||||
{
|
||||
/* printf("PSS coproc ioctl %x %x %d\n", cmd, arg, local); */
|
||||
|
||||
switch (cmd) {
|
||||
case SNDCTL_COPR_RESET:
|
||||
pss_coproc_reset(dev_info);
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SNDCTL_COPR_LOAD:
|
||||
{
|
||||
copr_buffer *buf;
|
||||
int err;
|
||||
|
||||
buf = (copr_buffer *) malloc(sizeof(copr_buffer), M_TEMP, M_WAITOK);
|
||||
if (buf == NULL)
|
||||
return -(ENOSPC);
|
||||
|
||||
bcopy(&(((char *) arg)[0]), (char *) buf, sizeof(*buf));
|
||||
err = download_boot_block(dev_info, buf);
|
||||
free(buf, M_TEMP);
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
|
||||
case SNDCTL_COPR_RDATA:
|
||||
{
|
||||
copr_debug_buf buf;
|
||||
u_long flags;
|
||||
u_short tmp;
|
||||
|
||||
bcopy(&(((char *) arg)[0]), (char *) &buf, sizeof(buf));
|
||||
|
||||
flags = splhigh();
|
||||
if (!pss_put_dspword(devc, 0x00d0)) {
|
||||
splx(flags);
|
||||
return -(EIO);
|
||||
}
|
||||
if (!pss_put_dspword(devc, (u_short) (buf.parm1 & 0xffff))) {
|
||||
splx(flags);
|
||||
return -(EIO);
|
||||
}
|
||||
if (!pss_get_dspword(devc, &tmp)) {
|
||||
splx(flags);
|
||||
return -(EIO);
|
||||
}
|
||||
buf.parm1 = tmp;
|
||||
splx(flags);
|
||||
|
||||
bcopy(&buf, &(((char *) arg)[0]), sizeof(buf));
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SNDCTL_COPR_WDATA:
|
||||
{
|
||||
copr_debug_buf buf;
|
||||
u_long flags;
|
||||
u_short tmp;
|
||||
|
||||
bcopy(&(((char *) arg)[0]), (char *) &buf, sizeof(buf));
|
||||
|
||||
flags = splhigh();
|
||||
if (!pss_put_dspword(devc, 0x00d1)) {
|
||||
splx(flags);
|
||||
return -(EIO);
|
||||
}
|
||||
if (!pss_put_dspword(devc, (u_short) (buf.parm1 & 0xffff))) {
|
||||
splx(flags);
|
||||
return -(EIO);
|
||||
}
|
||||
tmp = (u_int) buf.parm2 & 0xffff;
|
||||
if (!pss_put_dspword(devc, tmp)) {
|
||||
splx(flags);
|
||||
return -(EIO);
|
||||
}
|
||||
splx(flags);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SNDCTL_COPR_WCODE:
|
||||
{
|
||||
copr_debug_buf buf;
|
||||
u_long flags;
|
||||
u_short tmp;
|
||||
|
||||
bcopy(&(((char *) arg)[0]), (char *) &buf, sizeof(buf));
|
||||
|
||||
flags = splhigh();
|
||||
if (!pss_put_dspword(devc, 0x00d3)) {
|
||||
splx(flags);
|
||||
return -(EIO);
|
||||
}
|
||||
if (!pss_put_dspword(devc, (u_short) (buf.parm1 & 0xffff))) {
|
||||
splx(flags);
|
||||
return -(EIO);
|
||||
}
|
||||
tmp = ((u_int) buf.parm2 >> 8) & 0xffff;
|
||||
if (!pss_put_dspword(devc, tmp)) {
|
||||
splx(flags);
|
||||
return -(EIO);
|
||||
}
|
||||
tmp = (u_int) buf.parm2 & 0x00ff;
|
||||
if (!pss_put_dspword(devc, tmp)) {
|
||||
splx(flags);
|
||||
return -(EIO);
|
||||
}
|
||||
splx(flags);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SNDCTL_COPR_RCODE:
|
||||
{
|
||||
copr_debug_buf buf;
|
||||
u_long flags;
|
||||
u_short tmp;
|
||||
|
||||
bcopy(&(((char *) arg)[0]), (char *) &buf, sizeof(buf));
|
||||
|
||||
flags = splhigh();
|
||||
if (!pss_put_dspword(devc, 0x00d2)) {
|
||||
splx(flags);
|
||||
return -(EIO);
|
||||
}
|
||||
if (!pss_put_dspword(devc, (u_short) (buf.parm1 & 0xffff))) {
|
||||
splx(flags);
|
||||
return -(EIO);
|
||||
}
|
||||
if (!pss_get_dspword(devc, &tmp)) { /* Read msb */
|
||||
splx(flags);
|
||||
return -(EIO);
|
||||
}
|
||||
buf.parm1 = tmp << 8;
|
||||
|
||||
if (!pss_get_dspword(devc, &tmp)) { /* Read lsb */
|
||||
splx(flags);
|
||||
return -(EIO);
|
||||
}
|
||||
buf.parm1 |= tmp & 0x00ff;
|
||||
|
||||
splx(flags);
|
||||
|
||||
bcopy(&buf, &(((char *) arg)[0]), sizeof(buf));
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return -(EINVAL);
|
||||
}
|
||||
|
||||
return -(EINVAL);
|
||||
}
|
||||
|
||||
static coproc_operations pss_coproc_operations =
|
||||
{
|
||||
"ADSP-2115",
|
||||
pss_coproc_open,
|
||||
pss_coproc_close,
|
||||
pss_coproc_ioctl,
|
||||
pss_coproc_reset,
|
||||
&pss_data
|
||||
};
|
||||
|
||||
void
|
||||
attach_pss_mpu(struct address_info * hw_config)
|
||||
{
|
||||
int prev_devs;
|
||||
|
||||
#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
|
||||
prev_devs = num_midis;
|
||||
attach_mpu401(hw_config);
|
||||
|
||||
if (num_midis == (prev_devs + 1)) /* The MPU driver installed
|
||||
* itself */
|
||||
midi_devs[prev_devs]->coproc = &pss_coproc_operations;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
probe_pss_mss(struct address_info * hw_config)
|
||||
{
|
||||
int timeout;
|
||||
|
||||
if (!pss_initialized)
|
||||
return 0;
|
||||
|
||||
if (0) {
|
||||
printf("PSS: WSS I/O port conflict\n");
|
||||
return 0;
|
||||
}
|
||||
if (!set_io_base(devc, CONF_WSS, hw_config->io_base)) {
|
||||
printf("PSS: WSS base error.\n");
|
||||
return 0;
|
||||
}
|
||||
if (!set_irq(devc, CONF_WSS, hw_config->irq)) {
|
||||
printf("PSS: WSS IRQ error.\n");
|
||||
return 0;
|
||||
}
|
||||
if (!set_dma(devc, CONF_WSS, hw_config->dma)) {
|
||||
printf("PSS: WSS DRQ error\n");
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* For some reason the card returns 0xff in the WSS status register
|
||||
* immediately after boot. Propably MIDI+SB emulation algorithm
|
||||
* downloaded to the ADSP2115 spends some time initializing the card.
|
||||
* Let's try to wait until it finishes this task.
|
||||
*/
|
||||
for (timeout = 0;
|
||||
timeout < 100000 && (inb(hw_config->io_base + 3) & 0x3f) != 0x04;
|
||||
timeout++);
|
||||
|
||||
return probe_mss(hw_config);
|
||||
}
|
||||
|
||||
void
|
||||
attach_pss_mss(struct address_info * hw_config)
|
||||
{
|
||||
int prev_devs;
|
||||
long ret;
|
||||
|
||||
prev_devs = num_audiodevs;
|
||||
attach_mss(hw_config);
|
||||
|
||||
/* Check if The MSS driver installed itself */
|
||||
if (num_audiodevs == (prev_devs + 1))
|
||||
audio_devs[prev_devs]->coproc = &pss_coproc_operations;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,371 +0,0 @@
|
||||
/******************************************************************************
|
||||
|
||||
def.h
|
||||
|
||||
Version 1.3 11/2/93
|
||||
|
||||
Copyright (c) 1993 Analog Devices Inc. All rights reserved
|
||||
|
||||
******************************************************************************/
|
||||
/* Port offsets from base port for Sound Blaster DSP */
|
||||
#define DSP_PORT_CMSD0 0x00 /* C/MS music voice 1-6 data port, write only */
|
||||
#define DSP_PORT_CMSR0 0x01 /* C/MS music voice 1-6 register port, write only */
|
||||
#define DSP_PORT_CMSD1 0x02 /* C/MS music voice 7-12 data port, write only */
|
||||
#define DSP_PORT_CMSR1 0x03 /* C/MS music voice 7-12 register port, write only */
|
||||
|
||||
#define DSP_PORT_STATUS 0x04 /* DSP Status bits, read only */
|
||||
#define DSP_PORT_CONTROL 0x04 /* DSP Control bits, write only */
|
||||
#define DSP_PORT_DATA_LSB 0x05 /* Read or write LSB of 16 bit data */
|
||||
|
||||
|
||||
#define DSP_PORT_RESET 0x06 /* DSP Reset, write only */
|
||||
#define DSP_PORT_07h 0x07 /* reserved port */
|
||||
|
||||
#define DSP_PORT_FMD0 0x08 /* FM music data/status port, read/write */
|
||||
#define DSP_PORT_FMR0 0x09 /* FM music data/status port, write only */
|
||||
|
||||
#define DSP_PORT_RDDATA 0x0A /* DSP Read data, read only reading signals DSP */
|
||||
#define DSP_PORT_0Bh 0x0B /* reserved port */
|
||||
#define DSP_PORT_WRDATA 0x0C /* DSP Write data or command, write */
|
||||
#define DSP_PORT_WRBUSY 0x0C /* DSP Write buffer status (bit 7), read */
|
||||
#define DSP_PORT_0Dh 0x0D /* reserved port */
|
||||
#define DSP_PORT_DATAAVAIL 0x0E /* DSP Data available status (bit 7), read only */
|
||||
#define DSP_PORT_INTERFACE 0x0E /* Sets DMA Channel and Interrupt, write only */
|
||||
#define DSP_PORT_0Fh 0x0F /* reserved port (used on Pro cards) */
|
||||
|
||||
#define ADDR_MASK 0x003f
|
||||
|
||||
#define INT_MASK 0xffc7
|
||||
#define INT_3_BITS 0x0008
|
||||
#define INT_5_BITS 0x0010
|
||||
#define INT_7_BITS 0x0018
|
||||
#define INT_9_BITS 0x0020
|
||||
#define INT_10_BITS 0x0028
|
||||
#define INT_11_BITS 0x0030
|
||||
#define INT_12_BITS 0x0038
|
||||
|
||||
#define GAME_BIT 0x0400
|
||||
#define GAME_BIT_MASK 0xfbff
|
||||
|
||||
#define INT_TEST_BIT 0x0200
|
||||
#define INT_TEST_PASS 0x0100
|
||||
#define INT_TEST_BIT_MASK 0xFDFF
|
||||
|
||||
#define DMA_MASK 0xfff8
|
||||
#define DMA_0_BITS 0x0001
|
||||
#define DMA_1_BITS 0x0002
|
||||
#define DMA_3_BITS 0x0003
|
||||
#define DMA_5_BITS 0x0004
|
||||
#define DMA_6_BITS 0x0005
|
||||
#define DMA_7_BITS 0x0006
|
||||
|
||||
#define DMA_TEST_BIT 0x0080
|
||||
#define DMA_TEST_PASS 0x0040
|
||||
#define DMA_TEST_BIT_MASK 0xFF7F
|
||||
|
||||
|
||||
/* Echo DSP Flags */
|
||||
|
||||
#define DSP_FLAG3 0x10
|
||||
#define DSP_FLAG2 0x08
|
||||
#define DSP_FLAG1 0x80
|
||||
#define DSP_FLAG0 0x40
|
||||
|
||||
#define PSS_CONFIG 0x10
|
||||
#define PSS_WSS_CONFIG 0x12
|
||||
#define SB_CONFIG 0x14
|
||||
#define MIDI_CONFIG 0x18
|
||||
#define CD_CONFIG 0x16
|
||||
#define UART_CONFIG 0x1a
|
||||
|
||||
#define PSS_DATA 0x00
|
||||
#define PSS_STATUS 0x02
|
||||
#define PSS_CONTROL 0x02
|
||||
#define PSS_ID_VERS 0x04
|
||||
|
||||
#define PSS_FLAG3 0x0800
|
||||
#define PSS_FLAG2 0x0400
|
||||
#define PSS_FLAG1 0x1000
|
||||
#define PSS_FLAG0 0x0800
|
||||
|
||||
/*_____ WSS defines */
|
||||
#define WSS_BASE_ADDRESS 0x530
|
||||
#define WSS_CONFIG 0x0
|
||||
#define WSS_VERSION 0x03
|
||||
#define WSS_SP0 0x04
|
||||
#define WSS_SP1 0x05
|
||||
#define WSS_SP2 0x06
|
||||
#define WSS_SP3 0x07
|
||||
|
||||
/*_____ SoundPort register addresses */
|
||||
|
||||
#define SP_LIN_SOURCE_CTRL 0x00
|
||||
#define SP_RIN_SOURCE_CTRL 0x01
|
||||
#define SP_LIN_GAIN_CTRL 0x10
|
||||
#define SP_RIN_GAIN_CTRL 0x11
|
||||
#define SP_LAUX1_CTRL 0x02
|
||||
#define SP_RAUX1_CTRL 0x03
|
||||
#define SP_LAUX2_CTRL 0x04
|
||||
#define SP_RAUX2_CTRL 0x05
|
||||
#define SP_LOUT_CTRL 0x06
|
||||
#define SP_ROUT_CTRL 0x07
|
||||
#define SP_CLK_FORMAT 0x48
|
||||
#define SP_INT_CONF 0x09
|
||||
#define SP_INT_CONF_MCE 0x49
|
||||
#define SP_PIN_CTRL 0x0a
|
||||
#define SP_TEST_INIT 0x0b
|
||||
#define SP_MISC_CTRL 0x0c
|
||||
#define SP_MIX_CTRL 0x0d
|
||||
#define SP_DMA_UCNT 0x0e
|
||||
#define SP_DMA_LCNT 0x0f
|
||||
|
||||
/*_____ Gain constants */
|
||||
|
||||
#define GAIN_0 0x00
|
||||
#define GAIN_1_5 0x01
|
||||
#define GAIN_3 0x02
|
||||
#define GAIN_4_5 0x03
|
||||
#define GAIN_6 0x04
|
||||
#define GAIN_7_5 0x05
|
||||
#define GAIN_9 0x06
|
||||
#define GAIN_10_5 0x07
|
||||
#define GAIN_12 0x08
|
||||
#define GAIN_13_5 0x09
|
||||
#define GAIN_15 0x0a
|
||||
#define GAIN_16_5 0x0b
|
||||
#define GAIN_18 0x0c
|
||||
#define GAIN_19_5 0x0d
|
||||
#define GAIN_21 0x0e
|
||||
#define GAIN_22_5 0x0f
|
||||
#define MUTE 0XFFFF
|
||||
|
||||
/*_____ Attenuation constants */
|
||||
|
||||
#define ATTEN_0 0x00
|
||||
#define ATTEN_1_5 0x01
|
||||
#define ATTEN_3 0x02
|
||||
#define ATTEN_4_5 0x03
|
||||
#define ATTEN_6 0x04
|
||||
#define ATTEN_7_5 0x05
|
||||
#define ATTEN_9 0x06
|
||||
#define ATTEN_10_5 0x07
|
||||
#define ATTEN_12 0x08
|
||||
#define ATTEN_13_5 0x09
|
||||
#define ATTEN_15 0x0a
|
||||
#define ATTEN_16_5 0x0b
|
||||
#define ATTEN_18 0x0c
|
||||
#define ATTEN_19_5 0x0d
|
||||
#define ATTEN_21 0x0e
|
||||
#define ATTEN_22_5 0x0f
|
||||
|
||||
|
||||
#define PSS_WRITE_EMPTY 0x8000
|
||||
|
||||
#define CD_POL_MASK 0xFFBF
|
||||
#define CD_POL_BIT 0x0040
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
host.h
|
||||
|
||||
Version 1.2 9/27/93
|
||||
|
||||
Copyright (c) 1993 Analog Devices Inc. All rights reserved
|
||||
|
||||
******************************************************************************/
|
||||
#define SB_WRITE_FULL 0x80
|
||||
#define SB_READ_FULL 0x80
|
||||
#define SB_WRITE_STATUS 0x0C
|
||||
#define SB_READ_STATUS 0x0E
|
||||
#define SB_READ_DATA 0x0A
|
||||
#define SB_WRITE_DATA 0x0C
|
||||
|
||||
#define PSS_DATA_REG 0x00
|
||||
#define PSS_STATUS_REG 0x02
|
||||
#define PSS_WRITE_EMPTY 0x8000
|
||||
#define PSS_READ_FULL 0x4000
|
||||
|
||||
/*_____ 1848 Sound Port bit defines */
|
||||
|
||||
#define SP_IN_INIT 0x80
|
||||
#define MODE_CHANGE_ENABLE 0x40
|
||||
#define MODE_CHANGE_MASK 0xbf
|
||||
#define TRANSFER_DISABLE 0x20
|
||||
#define TRANSFER_DISABLE_MASK 0xdf
|
||||
#define ADDRESS_MASK 0xf0
|
||||
|
||||
/*_____ Status bits */
|
||||
#define INTERRUPT_STATUS 0x01
|
||||
#define PLAYBACK_READY 0x02
|
||||
#define PLAYBACK_LEFT 0x04
|
||||
/*_____ pbright is not left */
|
||||
#define PLAYBACK_UPPER 0x08
|
||||
/*_____ bplower is not upper */
|
||||
|
||||
#define SAMPLE_OVERRUN 0x10
|
||||
#define SAMPLE_UNDERRUN 0x10
|
||||
#define CAPTURE_READY 0x20
|
||||
#define CAPTURE_LEFT 0x40
|
||||
/*_____ cpright is not left */
|
||||
#define CAPTURE_UPPER 0x08
|
||||
/*_____ cplower is not upper */
|
||||
|
||||
/*_____ Input & Output regs bits */
|
||||
#define LINE_INPUT 0x80
|
||||
#define AUX_INPUT 0x40
|
||||
#define MIC_INPUT 0x80
|
||||
#define MIXED_DAC_INPUT 0xC0
|
||||
#define INPUT_GAIN_MASK 0xf0
|
||||
#define INPUT_MIC_GAIN_ENABLE 0x20
|
||||
#define INPUT_MIC_GAIN_MASK 0xdf
|
||||
#define INPUT_SOURCE_MASK 0x3f
|
||||
#define AUX_INPUT_ATTEN_MASK 0xf0
|
||||
#define AUX_INPUT_MUTE 0x80
|
||||
#define AUX_INPUT_MUTE_MASK 0x7f
|
||||
#define OUTPUT_MUTE 0x80
|
||||
#define OUTPUT_MUTE_MASK 0x7f
|
||||
#define OUTPUT_ATTEN_MASK 0xc0
|
||||
|
||||
/*_____ Clock and Data format reg bits */
|
||||
#define CLOCK_SELECT_MASK 0xfe
|
||||
#define CLOCK_XTAL2 0x01
|
||||
#define CLOCK_XTAL1 0x00
|
||||
#define CLOCK_FREQ_MASK 0xf1
|
||||
#define STEREO_MONO_MASK 0xef
|
||||
#define STEREO 0x10
|
||||
#define AUDIO_MONO 0x00
|
||||
#define LINEAR_COMP_MASK 0xdf
|
||||
#define LINEAR 0x00
|
||||
#define COMPANDED 0x20
|
||||
#define FORMAT_MASK 0xbf
|
||||
#define PCM 0x00
|
||||
#define ULAW 0x00
|
||||
#define TWOS_COMP 0x40
|
||||
#define ALAW 0x40
|
||||
|
||||
/*_____ Interface Configuration reg bits */
|
||||
#define PLAYBACK_ENABLE 0x01
|
||||
#define PLAYBACK_ENABLE_MASK 0xfe
|
||||
#define CAPTURE_ENABLE 0x02
|
||||
#define CAPTURE_ENABLE_MASK 0xfd
|
||||
#define SINGLE_DMA 0x04
|
||||
#define SINGLE_DMA_MASK 0xfb
|
||||
#define DUAL_DMA 0x00
|
||||
#define AUTO_CAL_ENABLE 0x08
|
||||
#define AUTO_CAL_DISABLE_MASK 0xf7
|
||||
#define PLAYBACK_PIO_ENABLE 0x40
|
||||
#define PLAYBACK_DMA_MASK 0xbf
|
||||
#define CAPTURE_PIO_ENABLE 0x80
|
||||
#define CAPTURE_DMA_MASK 0x7f
|
||||
|
||||
/*_____ Pin control bits */
|
||||
#define INTERRUPT_ENABLE 0x02
|
||||
#define INTERRUPT_MASK 0xfd
|
||||
|
||||
/*_____ Test and init reg bits */
|
||||
#define OVERRANGE_LEFT_MASK 0xfc
|
||||
#define OVERRANGE_RIGHT_MASK 0xf3
|
||||
#define DATA_REQUEST_STATUS 0x10
|
||||
#define AUTO_CAL_IN_PROG 0x20
|
||||
#define PLAYBACK_UNDERRUN 0x40
|
||||
#define CAPTURE_UNDERRUN 0x80
|
||||
|
||||
/*_____ Miscellaneous Control reg bits */
|
||||
#define ID_MASK 0xf0
|
||||
|
||||
/*_____ Digital Mix Control reg bits */
|
||||
#define DIGITAL_MIX1_MUTE_MASK 0xfe
|
||||
#define MIX_ATTEN_MASK 0x03
|
||||
|
||||
/*_____ 1848 Sound Port reg defines */
|
||||
|
||||
#define SP_LEFT_INPUT_CONTROL 0x0
|
||||
#define SP_RIGHT_INPUT_CONTROL 0x1
|
||||
#define SP_LEFT_AUX1_CONTROL 0x2
|
||||
#define SP_RIGHT_AUX1_CONTROL 0x3
|
||||
#define SP_LEFT_AUX2_CONTROL 0x4
|
||||
#define SP_RIGHT_AUX2_CONTROL 0x5
|
||||
#define SP_LEFT_OUTPUT_CONTROL 0x6
|
||||
#define SP_RIGHT_OUTPUT_CONTROL 0x7
|
||||
#define SP_CLOCK_DATA_FORMAT 0x8
|
||||
#define SP_INTERFACE_CONFIG 0x9
|
||||
#define SP_PIN_CONTROL 0xA
|
||||
#define SP_TEST_AND_INIT 0xB
|
||||
#define SP_MISC_INFO 0xC
|
||||
#define SP_DIGITAL_MIX 0xD
|
||||
#define SP_UPPER_BASE_COUNT 0xE
|
||||
#define SP_LOWER_BASE_COUNT 0xF
|
||||
|
||||
#define HOST_SP_ADDR (0x534)
|
||||
#define HOST_SP_DATA (0x535)
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
phillips.h
|
||||
|
||||
Version 1.2 9/27/93
|
||||
|
||||
Copyright (c) 1993 Analog Devices Inc. All rights reserved
|
||||
|
||||
******************************************************************************/
|
||||
/*_____ Phillips control SW defines */
|
||||
|
||||
/*_____ Settings and ranges */
|
||||
#define VOLUME_MAX 6
|
||||
#define VOLUME_MIN (-64)
|
||||
#define VOLUME_RANGE 70
|
||||
#define VOLUME_STEP 2
|
||||
#define BASS_MAX 15
|
||||
#define BASS_MIN (-12)
|
||||
#define BASS_STEP 2
|
||||
#define BASS_RANGE 27
|
||||
#define TREBLE_MAX 12
|
||||
#define TREBLE_MIN (-12)
|
||||
#define TREBLE_STEP 2
|
||||
#define TREBLE_RANGE 24
|
||||
|
||||
#define VOLUME_CONSTANT 252
|
||||
#define BASS_CONSTANT 246
|
||||
#define TREBLE_CONSTANT 246
|
||||
|
||||
/*_____ Software commands */
|
||||
#define SET_MASTER_COMMAND 0x0010
|
||||
#define MASTER_VOLUME_LEFT 0x0000
|
||||
#define MASTER_VOLUME_RIGHT 0x0100
|
||||
#define MASTER_BASS 0x0200
|
||||
#define MASTER_TREBLE 0x0300
|
||||
#define MASTER_SWITCH 0x0800
|
||||
|
||||
#define STEREO_MODE 0x00ce
|
||||
#define PSEUDO_MODE 0x00d6
|
||||
#define SPATIAL_MODE 0x00de
|
||||
#define MONO_MODE 0x00c6
|
||||
|
||||
|
||||
#define PSS_STEREO 0x00ce
|
||||
#define PSS_PSEUDO 0x00d6
|
||||
#define PSS_SPATIAL 0x00de
|
||||
#define PSS_MONO 0x00c6
|
||||
|
||||
#define PHILLIPS_VOL_MIN -64
|
||||
#define PHILLIPS_VOL_MAX 6
|
||||
#define PHILLIPS_VOL_DELTA 70
|
||||
#define PHILLIPS_VOL_INITIAL -20
|
||||
#define PHILLIPS_VOL_CONSTANT 252
|
||||
#define PHILLIPS_VOL_STEP 2
|
||||
#define PHILLIPS_BASS_MIN -12
|
||||
#define PHILLIPS_BASS_MAX 15
|
||||
#define PHILLIPS_BASS_DELTA 27
|
||||
#define PHILLIPS_BASS_INITIAL 0
|
||||
#define PHILLIPS_BASS_CONSTANT 246
|
||||
#define PHILLIPS_BASS_STEP 2
|
||||
#define PHILLIPS_TREBLE_MIN -12
|
||||
#define PHILLIPS_TREBLE_MAX 12
|
||||
#define PHILLIPS_TREBLE_DELTA 24
|
||||
#define PHILLIPS_TREBLE_INITIAL 0
|
||||
#define PHILLIPS_TREBLE_CONSTANT 246
|
||||
#define PHILLIPS_TREBLE_STEP 2
|
||||
|
@ -1,561 +0,0 @@
|
||||
/*
|
||||
* sound/sb16_dsp.c
|
||||
*
|
||||
* The low level driver for the SoundBlaster DSP chip.
|
||||
*
|
||||
* (C) 1993 J. Schubert (jsb@sth.ruhr-uni-bochum.de)
|
||||
*
|
||||
* based on SB-driver by (C) Hannu Savolainen
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
|
||||
#define DEB(x)
|
||||
#define DEB1(x)
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
#include "sb.h"
|
||||
#include <i386/isa/sound/sb_mixer.h>
|
||||
#include <i386/isa/sound/sbcard.h>
|
||||
|
||||
#if defined(CONFIG_SB16) && (NSB > 0) && defined(CONFIG_AUDIO) && defined(CONFIG_SBPRO)
|
||||
|
||||
|
||||
extern sound_os_info *sb_osp;
|
||||
extern int sbc_base;
|
||||
|
||||
static int sb16_dsp_ok = 0;
|
||||
static int dsp_16bit = 0;
|
||||
static int dsp_stereo = 0;
|
||||
static int dsp_current_speed = 8000;
|
||||
static int dsp_busy = 0;
|
||||
static int dma16, dma8;
|
||||
|
||||
|
||||
static int trigger_bits = 0;
|
||||
static u_long dsp_count = 0;
|
||||
|
||||
static int irq_mode = IMODE_NONE;
|
||||
static int my_dev = 0;
|
||||
|
||||
static volatile int intr_active = 0;
|
||||
|
||||
static int sb16_dsp_open(int dev, int mode);
|
||||
static void sb16_dsp_close(int dev);
|
||||
static void sb16_dsp_output_block(int dev, u_long buf, int count, int intrflag, int dma_restart);
|
||||
static void sb16_dsp_start_input(int dev, u_long buf, int count, int intrflag, int dma_restart);
|
||||
static int sb16_dsp_ioctl(int dev, u_int cmd, ioctl_arg arg, int local);
|
||||
static int sb16_dsp_prepare_for_input(int dev, int bsize, int bcount);
|
||||
static int sb16_dsp_prepare_for_output(int dev, int bsize, int bcount);
|
||||
static void sb16_dsp_reset(int dev);
|
||||
static void sb16_dsp_halt(int dev);
|
||||
static void sb16_dsp_trigger(int dev, int bits);
|
||||
static int dsp_set_speed(int);
|
||||
static int dsp_set_stereo(int);
|
||||
static void dsp_cleanup(void);
|
||||
|
||||
static struct audio_operations sb16_dsp_operations =
|
||||
{
|
||||
"SoundBlaster 16",
|
||||
DMA_AUTOMODE,
|
||||
AFMT_U8 | AFMT_S16_LE,
|
||||
NULL,
|
||||
sb16_dsp_open,
|
||||
sb16_dsp_close,
|
||||
sb16_dsp_output_block,
|
||||
sb16_dsp_start_input,
|
||||
sb16_dsp_ioctl,
|
||||
sb16_dsp_prepare_for_input,
|
||||
sb16_dsp_prepare_for_output,
|
||||
sb16_dsp_reset,
|
||||
sb16_dsp_halt,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
sb16_dsp_trigger
|
||||
};
|
||||
|
||||
static int
|
||||
sb_dsp_command01(u_char val)
|
||||
{
|
||||
int i = 1 << 16;
|
||||
|
||||
while (--i & (!inb(DSP_STATUS) & 0x80));
|
||||
if (!i)
|
||||
printf("SB16 sb_dsp_command01 Timeout\n");
|
||||
return sb_dsp_command(val);
|
||||
}
|
||||
|
||||
static int
|
||||
dsp_set_speed(int mode)
|
||||
{
|
||||
DEB(printf("dsp_set_speed(%d)\n", mode));
|
||||
if (mode) {
|
||||
RANGE (mode, 5000, 44100);
|
||||
dsp_current_speed = mode;
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
static int
|
||||
dsp_set_stereo(int mode)
|
||||
{
|
||||
DEB(printf("dsp_set_stereo(%d)\n", mode));
|
||||
dsp_stereo = mode;
|
||||
return mode;
|
||||
}
|
||||
|
||||
static int
|
||||
dsp_set_bits(int arg)
|
||||
{
|
||||
DEB(printf("dsp_set_bits(%d)\n", arg));
|
||||
|
||||
if (arg)
|
||||
dsp_16bit = (arg == 16) ? 1 : 0 ;
|
||||
return dsp_16bit ? 16 : 8;
|
||||
}
|
||||
|
||||
static int
|
||||
sb16_dsp_ioctl(int dev, u_int cmd, ioctl_arg arg, int local)
|
||||
{
|
||||
switch (cmd) {
|
||||
case SOUND_PCM_WRITE_RATE:
|
||||
if (local)
|
||||
return dsp_set_speed((int) arg);
|
||||
return *(int *) arg = dsp_set_speed((*(int *) arg));
|
||||
|
||||
case SOUND_PCM_READ_RATE:
|
||||
if (local)
|
||||
return dsp_current_speed;
|
||||
return *(int *) arg = dsp_current_speed;
|
||||
|
||||
case SNDCTL_DSP_STEREO:
|
||||
if (local)
|
||||
return dsp_set_stereo((int) arg);
|
||||
return *(int *) arg = dsp_set_stereo((*(int *) arg));
|
||||
|
||||
case SOUND_PCM_WRITE_CHANNELS:
|
||||
if (local)
|
||||
return dsp_set_stereo((int) arg - 1) + 1;
|
||||
return *(int *) arg = dsp_set_stereo((*(int *) arg) - 1) + 1;
|
||||
|
||||
case SOUND_PCM_READ_CHANNELS:
|
||||
if (local)
|
||||
return dsp_stereo + 1;
|
||||
return *(int *) arg = dsp_stereo + 1;
|
||||
|
||||
case SNDCTL_DSP_SETFMT:
|
||||
if (local)
|
||||
return dsp_set_bits((int) arg);
|
||||
return *(int *) arg = dsp_set_bits((*(int *) arg));
|
||||
|
||||
case SOUND_PCM_READ_BITS:
|
||||
if (local)
|
||||
return dsp_16bit ? 16 : 8;
|
||||
return *(int *) arg = dsp_16bit ? 16 : 8;
|
||||
|
||||
case SOUND_PCM_WRITE_FILTER: /* NOT YET IMPLEMENTED */
|
||||
if ((*(int *) arg) > 1)
|
||||
return *(int *) arg = -(EINVAL);
|
||||
|
||||
case FIOASYNC:
|
||||
if (local)
|
||||
return 1;
|
||||
return *(int *) arg = 1;
|
||||
|
||||
case FIONBIO:
|
||||
if (local)
|
||||
return 1;
|
||||
return *(int *) arg = 1;
|
||||
|
||||
default:
|
||||
return -(EINVAL);
|
||||
}
|
||||
|
||||
return -(EINVAL);
|
||||
}
|
||||
|
||||
static int
|
||||
sb16_dsp_open(int dev, int mode)
|
||||
{
|
||||
DEB(printf("sb16_dsp_open()\n"));
|
||||
|
||||
if (!sb16_dsp_ok) {
|
||||
printf("SB16 Error: SoundBlaster board not installed\n");
|
||||
return -(ENXIO);
|
||||
}
|
||||
if (intr_active)
|
||||
return -(EBUSY);
|
||||
|
||||
sb_reset_dsp();
|
||||
|
||||
|
||||
irq_mode = IMODE_NONE;
|
||||
dsp_busy = 1;
|
||||
trigger_bits = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
sb16_dsp_close(int dev)
|
||||
{
|
||||
u_long flags;
|
||||
|
||||
DEB(printf("sb16_dsp_close()\n"));
|
||||
sb_dsp_command01(0xd9);
|
||||
sb_dsp_command01(0xd5);
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
audio_devs[dev]->dmachan1 = dma8;
|
||||
|
||||
dsp_cleanup();
|
||||
dsp_busy = 0;
|
||||
|
||||
|
||||
splx(flags);
|
||||
}
|
||||
|
||||
static void
|
||||
sb16_dsp_output_block(int dev, u_long buf, int count, int intrflag, int dma_restart)
|
||||
{
|
||||
u_long flags, cnt;
|
||||
|
||||
|
||||
cnt = count;
|
||||
if (dsp_16bit)
|
||||
cnt >>= 1;
|
||||
cnt--;
|
||||
|
||||
if (audio_devs[dev]->flags & DMA_AUTOMODE && intrflag && cnt==dsp_count) {
|
||||
irq_mode = IMODE_OUTPUT;
|
||||
intr_active = 1;
|
||||
return; /* Auto mode on. No need to react */
|
||||
}
|
||||
flags = splhigh();
|
||||
|
||||
if (dma_restart) {
|
||||
|
||||
sb16_dsp_halt(dev);
|
||||
DMAbuf_start_dma(dev, buf, count, 1);
|
||||
}
|
||||
|
||||
|
||||
sb_dsp_command(0x41);
|
||||
sb_dsp_command((u_char) ((dsp_current_speed >> 8) & 0xff));
|
||||
sb_dsp_command((u_char) (dsp_current_speed & 0xff));
|
||||
sb_dsp_command((u_char) (dsp_16bit ? 0xb6 : 0xc6));
|
||||
dsp_count = cnt;
|
||||
sb_dsp_command((u_char) ((dsp_stereo ? 0x20 : 0) +
|
||||
(dsp_16bit ? 0x10 : 0)));
|
||||
sb_dsp_command((u_char) (cnt & 0xff));
|
||||
sb_dsp_command((u_char) (cnt >> 8));
|
||||
|
||||
irq_mode = IMODE_OUTPUT;
|
||||
intr_active = 1;
|
||||
splx(flags);
|
||||
}
|
||||
|
||||
static void
|
||||
sb16_dsp_start_input(int dev, u_long buf, int count, int intrflag, int dma_restart)
|
||||
{
|
||||
u_long flags, cnt;
|
||||
|
||||
cnt = count;
|
||||
if (dsp_16bit)
|
||||
cnt >>= 1;
|
||||
cnt--;
|
||||
|
||||
if (audio_devs[dev]->flags & DMA_AUTOMODE && intrflag && cnt == dsp_count) {
|
||||
irq_mode = IMODE_INPUT;
|
||||
intr_active = 1;
|
||||
return; /* Auto mode on. No need to react */
|
||||
}
|
||||
flags = splhigh();
|
||||
|
||||
if (dma_restart) {
|
||||
sb_reset_dsp();
|
||||
DMAbuf_start_dma(dev, buf, count, 0);
|
||||
}
|
||||
sb_dsp_command(0x42);
|
||||
sb_dsp_command((u_char) ((dsp_current_speed >> 8) & 0xff));
|
||||
sb_dsp_command((u_char) (dsp_current_speed & 0xff));
|
||||
sb_dsp_command((u_char) (dsp_16bit ? 0xbe : 0xce));
|
||||
dsp_count = cnt;
|
||||
sb_dsp_command((u_char) ((dsp_stereo ? 0x20 : 0) +
|
||||
(dsp_16bit ? 0x10 : 0)));
|
||||
sb_dsp_command01((u_char) (cnt & 0xff));
|
||||
sb_dsp_command((u_char) (cnt >> 8));
|
||||
|
||||
irq_mode = IMODE_INPUT;
|
||||
intr_active = 1;
|
||||
splx(flags);
|
||||
}
|
||||
|
||||
static int
|
||||
sb16_dsp_prepare_for_input(int dev, int bsize, int bcount)
|
||||
{
|
||||
int fudge;
|
||||
struct dma_buffparms *dmap = audio_devs[dev]->dmap_in;
|
||||
|
||||
audio_devs[my_dev]->dmachan2 = dsp_16bit ? dma16 : dma8;
|
||||
|
||||
|
||||
fudge = audio_devs[my_dev]->dmachan2 ;
|
||||
|
||||
if (dmap->dma_chan != fudge ) {
|
||||
isa_dma_release( dmap->dma_chan);
|
||||
isa_dma_acquire(fudge);
|
||||
dmap->dma_chan = fudge;
|
||||
}
|
||||
|
||||
dsp_count = 0;
|
||||
dsp_cleanup();
|
||||
if (dsp_16bit)
|
||||
sb_dsp_command(0xd5); /* Halt DMA until trigger() is called */
|
||||
else
|
||||
sb_dsp_command(0xd0); /* Halt DMA until trigger() is called */
|
||||
|
||||
trigger_bits = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sb16_dsp_prepare_for_output(int dev, int bsize, int bcount)
|
||||
{
|
||||
int fudge = dsp_16bit ? dma16 : dma8;
|
||||
struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
|
||||
|
||||
if (dmap->dma_chan != fudge ) {
|
||||
isa_dma_release( dmap->dma_chan);
|
||||
isa_dma_acquire(fudge);
|
||||
dmap->dma_chan = fudge;
|
||||
}
|
||||
|
||||
audio_devs[my_dev]->dmachan1 = fudge;
|
||||
|
||||
dsp_count = 0;
|
||||
dsp_cleanup();
|
||||
if (dsp_16bit)
|
||||
sb_dsp_command(0xd5); /* Halt DMA until trigger() is called */
|
||||
else
|
||||
sb_dsp_command(0xd0); /* Halt DMA until trigger() is called */
|
||||
|
||||
trigger_bits = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
sb16_dsp_trigger(int dev, int bits)
|
||||
{
|
||||
if (bits != 0)
|
||||
bits = 1;
|
||||
|
||||
if (bits == trigger_bits) /* No change */
|
||||
return;
|
||||
|
||||
trigger_bits = bits;
|
||||
|
||||
if (!bits)
|
||||
sb_dsp_command(0xd0); /* Halt DMA */
|
||||
else if (bits & irq_mode) {
|
||||
if (dsp_16bit)
|
||||
sb_dsp_command(0xd6); /* Continue 16bit DMA */
|
||||
else
|
||||
sb_dsp_command(0xd4); /* Continue 8bit DMA */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dsp_cleanup(void)
|
||||
{
|
||||
irq_mode = IMODE_NONE;
|
||||
intr_active = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
sb16_dsp_reset(int dev)
|
||||
{
|
||||
u_long flags;
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
sb_reset_dsp();
|
||||
dsp_cleanup();
|
||||
|
||||
splx(flags);
|
||||
}
|
||||
|
||||
static void
|
||||
sb16_dsp_halt(int dev)
|
||||
{
|
||||
|
||||
if (dsp_16bit) {
|
||||
sb_dsp_command01(0xd9);
|
||||
sb_dsp_command01(0xd5);
|
||||
} else {
|
||||
sb_dsp_command01(0xda);
|
||||
sb_dsp_command01(0xd0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
set_irq_hw(int level)
|
||||
{
|
||||
int ival;
|
||||
|
||||
switch (level) {
|
||||
#ifdef PC98
|
||||
case 5:
|
||||
ival = 8;
|
||||
break;
|
||||
case 3:
|
||||
ival = 1;
|
||||
break;
|
||||
case 10:
|
||||
ival = 2;
|
||||
break;
|
||||
#else
|
||||
case 5:
|
||||
ival = 2;
|
||||
break;
|
||||
case 7:
|
||||
ival = 4;
|
||||
break;
|
||||
case 9:
|
||||
ival = 1;
|
||||
break;
|
||||
case 10:
|
||||
ival = 8;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf("SB16_IRQ_LEVEL %d does not exist\n", level);
|
||||
return;
|
||||
}
|
||||
sb_setmixer(IRQ_NR, ival);
|
||||
}
|
||||
|
||||
void
|
||||
sb16_dsp_init(struct address_info * hw_config)
|
||||
{
|
||||
if (sbc_major < 4)
|
||||
return; /* Not a SB16 */
|
||||
|
||||
snprintf(sb16_dsp_operations.name, sizeof(sb16_dsp_operations.name),
|
||||
"SoundBlaster 16 %d.%d", sbc_major, sbc_minor);
|
||||
|
||||
conf_printf(sb16_dsp_operations.name, hw_config);
|
||||
|
||||
if (num_audiodevs < MAX_AUDIO_DEV) {
|
||||
audio_devs[my_dev = num_audiodevs++] = &sb16_dsp_operations;
|
||||
audio_devs[my_dev]->dmachan1 = dma8;
|
||||
audio_devs[my_dev]->buffsize = DSP_BUFFSIZE;
|
||||
|
||||
} else
|
||||
printf("SB: Too many DSP devices available\n");
|
||||
sb16_dsp_ok = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
sb16_dsp_detect(struct address_info * hw_config)
|
||||
{
|
||||
struct address_info *sb_config;
|
||||
|
||||
if (sb16_dsp_ok)
|
||||
return 1; /* Can't drive two cards */
|
||||
|
||||
if (!(sb_config = sound_getconf(SNDCARD_SB))) {
|
||||
printf("SB16 Error: Plain SB not configured\n");
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* sb_setmixer(OPSW,0xf); if(sb_getmixer(OPSW)!=0xf) return 0;
|
||||
*/
|
||||
|
||||
if (!sb_reset_dsp())
|
||||
return 0;
|
||||
|
||||
if (sbc_major < 4) /* Set by the plain SB driver */
|
||||
return 0; /* Not a SB16 */
|
||||
|
||||
#ifdef PC98
|
||||
hw_config->dma = sb_config->dma;
|
||||
#else
|
||||
if (hw_config->dma < 4)
|
||||
if (hw_config->dma != sb_config->dma) {
|
||||
printf("SB16 Error: Invalid DMA channel %d/%d\n",
|
||||
sb_config->dma, hw_config->dma);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
dma16 = hw_config->dma;
|
||||
dma8 = sb_config->dma;
|
||||
/* hw_config->irq = 0; sb_config->irq;
|
||||
hw_config->io_base = sb_config->io_base;
|
||||
*/
|
||||
set_irq_hw(sb_config->irq);
|
||||
|
||||
#ifdef PC98
|
||||
sb_setmixer (DMA_NR, hw_config->dma == 0 ? 1 : 2);
|
||||
#else
|
||||
sb_setmixer(DMA_NR, (1 << hw_config->dma) | (1 << sb_config->dma));
|
||||
#endif
|
||||
|
||||
DEB(printf("SoundBlaster 16: IRQ %d DMA %d OK\n",
|
||||
sb_config->irq, hw_config->dma));
|
||||
|
||||
/*
|
||||
* dsp_showmessage(0xe3,99);
|
||||
*/
|
||||
sb16_dsp_ok = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
sb16_dsp_interrupt(int unused)
|
||||
{
|
||||
int data;
|
||||
|
||||
data = inb(DSP_DATA_AVL16); /* Interrupt acknowledge */
|
||||
|
||||
if (intr_active)
|
||||
switch (irq_mode) {
|
||||
case IMODE_OUTPUT:
|
||||
DMAbuf_outputintr(my_dev, 1);
|
||||
break;
|
||||
|
||||
case IMODE_INPUT:
|
||||
DMAbuf_inputintr(my_dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("SoundBlaster: Unexpected interrupt\n");
|
||||
}
|
||||
}
|
||||
#endif
|
@ -1,311 +0,0 @@
|
||||
/*
|
||||
* sound/sb16_midi.c
|
||||
*
|
||||
* The low level driver for the MPU-401 UART emulation of the SB16.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
#include <i386/isa/sound/sbcard.h>
|
||||
|
||||
#if defined(CONFIG_SB) && defined(CONFIG_SB16) && defined(CONFIG_MIDI)
|
||||
|
||||
#include "sb.h"
|
||||
|
||||
#ifdef PC98
|
||||
#define DATAPORT (sb16midi_base)
|
||||
#define COMDPORT (sb16midi_base+0x100)
|
||||
#define STATPORT (sb16midi_base+0x100)
|
||||
#else
|
||||
#define DATAPORT (sb16midi_base)
|
||||
#define COMDPORT (sb16midi_base+1)
|
||||
#define STATPORT (sb16midi_base+1)
|
||||
#endif
|
||||
|
||||
extern sound_os_info *sb_osp;
|
||||
|
||||
#define sb16midi_status() inb( STATPORT)
|
||||
#define input_avail() (!(sb16midi_status()&INPUT_AVAIL))
|
||||
#define output_ready() (!(sb16midi_status()&OUTPUT_READY))
|
||||
#define sb16midi_cmd(cmd) outb( COMDPORT, cmd)
|
||||
#define sb16midi_read() inb( DATAPORT)
|
||||
#define sb16midi_write(byte) outb( DATAPORT, byte)
|
||||
|
||||
#define OUTPUT_READY 0x40
|
||||
#define INPUT_AVAIL 0x80
|
||||
#define MPU_ACK 0xFE
|
||||
#define MPU_RESET 0xFF
|
||||
#define UART_MODE_ON 0x3F
|
||||
|
||||
static int sb16midi_opened = 0;
|
||||
#ifdef PC98
|
||||
static int sb16midi_base = 0x80d2;
|
||||
#else
|
||||
static int sb16midi_base = 0x330;
|
||||
#endif
|
||||
static int sb16midi_detected = 0;
|
||||
static int my_dev;
|
||||
extern int sbc_base;
|
||||
|
||||
static int reset_sb16midi(void);
|
||||
static void (*midi_input_intr) (int dev, u_char data);
|
||||
static volatile u_char input_byte;
|
||||
|
||||
static void
|
||||
sb16midi_input_loop(void)
|
||||
{
|
||||
while (input_avail()) {
|
||||
u_char c = sb16midi_read();
|
||||
|
||||
if (c == MPU_ACK)
|
||||
input_byte = c;
|
||||
else if (sb16midi_opened & OPEN_READ && midi_input_intr)
|
||||
midi_input_intr(my_dev, c);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sb16midiintr(int unit)
|
||||
{
|
||||
if (input_avail())
|
||||
sb16midi_input_loop();
|
||||
}
|
||||
|
||||
static int
|
||||
sb16midi_open(int dev, int mode,
|
||||
void (*input) (int dev, u_char data),
|
||||
void (*output) (int dev)
|
||||
)
|
||||
{
|
||||
if (sb16midi_opened) {
|
||||
return -(EBUSY);
|
||||
}
|
||||
sb16midi_input_loop();
|
||||
|
||||
midi_input_intr = input;
|
||||
sb16midi_opened = mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
sb16midi_close(int dev)
|
||||
{
|
||||
sb16midi_opened = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sb16midi_out(int dev, u_char midi_byte)
|
||||
{
|
||||
int timeout;
|
||||
u_long flags;
|
||||
|
||||
/*
|
||||
* Test for input since pending input seems to block the output.
|
||||
*/
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
if (input_avail())
|
||||
sb16midi_input_loop();
|
||||
|
||||
splx(flags);
|
||||
|
||||
/*
|
||||
* Sometimes it takes about 13000 loops before the output becomes
|
||||
* ready (After reset). Normally it takes just about 10 loops.
|
||||
*/
|
||||
|
||||
for (timeout = 30000; timeout > 0 && !output_ready(); timeout--); /* Wait */
|
||||
|
||||
if (!output_ready()) {
|
||||
printf("MPU-401: Timeout\n");
|
||||
return 0;
|
||||
}
|
||||
sb16midi_write(midi_byte);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
sb16midi_start_read(int dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sb16midi_end_read(int dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sb16midi_ioctl(int dev, u_int cmd, ioctl_arg arg)
|
||||
{
|
||||
return -(EINVAL);
|
||||
}
|
||||
|
||||
static void
|
||||
sb16midi_kick(int dev)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
sb16midi_buffer_status(int dev)
|
||||
{
|
||||
return 0; /* No data in buffers */
|
||||
}
|
||||
|
||||
#define MIDI_SYNTH_NAME "SoundBlaster 16 Midi"
|
||||
#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
|
||||
#include <i386/isa/sound/midi_synth.h>
|
||||
|
||||
static struct midi_operations sb16midi_operations =
|
||||
{
|
||||
{"SoundBlaster 16 Midi", 0, 0, SNDCARD_SB16MIDI},
|
||||
&std_midi_synth,
|
||||
{0},
|
||||
sb16midi_open,
|
||||
sb16midi_close,
|
||||
sb16midi_ioctl,
|
||||
sb16midi_out,
|
||||
sb16midi_start_read,
|
||||
sb16midi_end_read,
|
||||
sb16midi_kick,
|
||||
NULL,
|
||||
sb16midi_buffer_status,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
attach_sb16midi(struct address_info * hw_config)
|
||||
{
|
||||
int ok, timeout;
|
||||
u_long flags;
|
||||
|
||||
sb16midi_base = hw_config->io_base;
|
||||
|
||||
if (!sb16midi_detected)
|
||||
return;
|
||||
|
||||
flags = splhigh();
|
||||
for (timeout = 30000; timeout < 0 && !output_ready(); timeout--); /* Wait */
|
||||
input_byte = 0;
|
||||
sb16midi_cmd(UART_MODE_ON);
|
||||
|
||||
ok = 0;
|
||||
for (timeout = 50000; timeout > 0 && !ok; timeout--)
|
||||
if (input_byte == MPU_ACK)
|
||||
ok = 1;
|
||||
else if (input_avail())
|
||||
if (sb16midi_read() == MPU_ACK)
|
||||
ok = 1;
|
||||
|
||||
splx(flags);
|
||||
|
||||
if (num_midis >= MAX_MIDI_DEV) {
|
||||
printf("Sound: Too many midi devices detected\n");
|
||||
return;
|
||||
}
|
||||
|
||||
conf_printf("SoundBlaster MPU-401", hw_config);
|
||||
std_midi_synth.midi_dev = my_dev = num_midis;
|
||||
midi_devs[num_midis++] = &sb16midi_operations;
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
reset_sb16midi(void)
|
||||
{
|
||||
int ok, timeout, n;
|
||||
|
||||
/*
|
||||
* Send the RESET command. Try again if no success at the first time.
|
||||
*/
|
||||
|
||||
if (inb(STATPORT) == 0xff)
|
||||
return 0;
|
||||
|
||||
ok = 0;
|
||||
|
||||
/* flags = splhigh(); */
|
||||
|
||||
for (n = 0; n < 2 && !ok; n++) {
|
||||
for (timeout = 30000; timeout < 0 && !output_ready(); timeout--); /* Wait */
|
||||
input_byte = 0;
|
||||
sb16midi_cmd(MPU_RESET); /* Send MPU-401 RESET Command */
|
||||
|
||||
/*
|
||||
* Wait at least 25 msec. This method is not accurate so
|
||||
* let's make the loop bit longer. Cannot sleep since this is
|
||||
* called during boot.
|
||||
*/
|
||||
|
||||
for (timeout = 50000; timeout > 0 && !ok; timeout--)
|
||||
if (input_byte == MPU_ACK) /* Interrupt */
|
||||
ok = 1;
|
||||
else if (input_avail())
|
||||
if (sb16midi_read() == MPU_ACK)
|
||||
ok = 1;
|
||||
|
||||
}
|
||||
|
||||
sb16midi_opened = 0;
|
||||
if (ok)
|
||||
sb16midi_input_loop(); /* Flush input before enabling
|
||||
* interrupts */
|
||||
|
||||
/* splx(flags); */
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
probe_sb16midi(struct address_info * hw_config)
|
||||
{
|
||||
int ok = 0;
|
||||
struct address_info *sb_config;
|
||||
|
||||
if (sbc_major < 4)
|
||||
return 0; /* Not a SB16 */
|
||||
|
||||
if (!(sb_config = sound_getconf(SNDCARD_SB))) {
|
||||
printf("SB16 Error: Plain SB not configured\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
sb16midi_base = hw_config->io_base;
|
||||
|
||||
ok = reset_sb16midi();
|
||||
|
||||
sb16midi_detected = ok;
|
||||
return ok;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
* sound/sb_card.c
|
||||
*
|
||||
* Detection routine for the SoundBlaster cards.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Modified: Riccardo Facchetti 24 Mar 1995 - Added the Audio Excel DSP 16
|
||||
* initialization routine.
|
||||
*
|
||||
* Major code cleanup - Luigi Rizzo (luigi@iet.unipi.it) 970711
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if NSB > 0
|
||||
#include <i386/isa/sound/sbcard.h>
|
||||
|
||||
void
|
||||
attach_sb_card(struct address_info * hw_config)
|
||||
{
|
||||
#if defined(CONFIG_AUDIO) || defined(CONFIG_MIDI)
|
||||
|
||||
#if 0
|
||||
/* why do a detect during the attach ? XXX */
|
||||
if (!sb_dsp_detect(hw_config))
|
||||
return ;
|
||||
#endif
|
||||
sb_dsp_init(hw_config);
|
||||
#endif
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
int
|
||||
probe_sb(struct address_info * hw_config)
|
||||
{
|
||||
|
||||
#if defined(CONFIG_AEDSP16) && defined(AEDSP16_SBPRO)
|
||||
/*
|
||||
* Initialize Audio Excel DSP 16 to SBPRO.
|
||||
*/
|
||||
InitAEDSP16_SBPRO(hw_config);
|
||||
#endif
|
||||
return sb_dsp_detect(hw_config);
|
||||
}
|
||||
#endif
|
@ -1,43 +0,0 @@
|
||||
#ifdef PC98
|
||||
#define DSP_RESET (sbc_base + 0x600)
|
||||
#define DSP_READ (sbc_base + 0xA00)
|
||||
#define DSP_WRITE (sbc_base + 0xC00)
|
||||
#define DSP_COMMAND (sbc_base + 0xC00)
|
||||
#define DSP_STATUS (sbc_base + 0xC00)
|
||||
#define DSP_DATA_AVAIL (sbc_base + 0xE00)
|
||||
#define DSP_DATA_AVL16 (sbc_base + 0xF00)
|
||||
#define MIXER_ADDR (sbc_base + 0x400)
|
||||
#define MIXER_DATA (sbc_base + 0x500)
|
||||
#define OPL3_LEFT (sbc_base + 0x000)
|
||||
#define OPL3_RIGHT (sbc_base + 0x200)
|
||||
#define OPL3_BOTH (sbc_base + 0x800)
|
||||
#else
|
||||
#define DSP_RESET (sbc_base + 0x6)
|
||||
#define DSP_READ (sbc_base + 0xA)
|
||||
#define DSP_WRITE (sbc_base + 0xC)
|
||||
#define DSP_COMMAND (sbc_base + 0xC)
|
||||
#define DSP_STATUS (sbc_base + 0xC)
|
||||
#define DSP_DATA_AVAIL (sbc_base + 0xE)
|
||||
#define DSP_DATA_AVL16 (sbc_base + 0xF)
|
||||
#define MIXER_ADDR (sbc_base + 0x4)
|
||||
#define MIXER_DATA (sbc_base + 0x5)
|
||||
#define OPL3_LEFT (sbc_base + 0x0)
|
||||
#define OPL3_RIGHT (sbc_base + 0x2)
|
||||
#define OPL3_BOTH (sbc_base + 0x8)
|
||||
#endif
|
||||
/* DSP Commands */
|
||||
|
||||
#define DSP_CMD_SPKON 0xD1
|
||||
#define DSP_CMD_SPKOFF 0xD3
|
||||
#define DSP_CMD_DMAON 0xD0
|
||||
#define DSP_CMD_DMAOFF 0xD4
|
||||
|
||||
#define IMODE_NONE 0
|
||||
#define IMODE_OUTPUT 1
|
||||
#define IMODE_INPUT 2
|
||||
#define IMODE_INIT 3
|
||||
#define IMODE_MIDI 4
|
||||
|
||||
#define NORMAL_MIDI 0
|
||||
#define UART_MIDI 1
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,211 +0,0 @@
|
||||
/*
|
||||
* sound/sb_dsp.c
|
||||
*
|
||||
* The low level driver for the SoundBlaster DS chips.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if (NSND > 0) && defined(CONFIG_SB) && defined(CONFIG_MIDI)
|
||||
|
||||
#include <i386/isa/sound/sbcard.h>
|
||||
#undef SB_TEST_IRQ
|
||||
|
||||
/*
|
||||
* The DSP channel can be used either for input or output. Variable
|
||||
* 'sb_irq_mode' will be set when the program calls read or write first time
|
||||
* after open. Current version doesn't support mode changes without closing
|
||||
* and reopening the device. Support for this feature may be implemented in a
|
||||
* future version of this driver.
|
||||
*/
|
||||
|
||||
extern int sb_dsp_ok; /* Set to 1 atfer successful initialization */
|
||||
extern int sbc_base;
|
||||
|
||||
extern int sb_midi_mode;
|
||||
extern int sb_midi_busy; /* 1 if the process has output to MIDI */
|
||||
extern int sb_dsp_busy;
|
||||
extern int sb_dsp_highspeed;
|
||||
|
||||
extern volatile int sb_irq_mode;
|
||||
extern int sb_duplex_midi;
|
||||
extern int sb_intr_active;
|
||||
static int input_opened = 0;
|
||||
static int my_dev;
|
||||
|
||||
extern sound_os_info *sb_osp;
|
||||
|
||||
static void (*midi_input_intr) (int dev, u_char data);
|
||||
|
||||
static int
|
||||
sb_midi_open(int dev, int mode, void (*input) (int dev, u_char data),
|
||||
void (*output) (int dev))
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!sb_dsp_ok) {
|
||||
printf("SB Error: MIDI hardware not installed\n");
|
||||
return -(ENXIO);
|
||||
}
|
||||
if (sb_midi_busy)
|
||||
return -(EBUSY);
|
||||
|
||||
if (mode != OPEN_WRITE && !sb_duplex_midi) {
|
||||
if (num_midis == 1)
|
||||
printf("SoundBlaster: Midi input not currently supported\n");
|
||||
return -(EPERM);
|
||||
}
|
||||
sb_midi_mode = NORMAL_MIDI;
|
||||
if (mode != OPEN_WRITE) {
|
||||
if (sb_dsp_busy || sb_intr_active)
|
||||
return -(EBUSY);
|
||||
sb_midi_mode = UART_MIDI;
|
||||
}
|
||||
if (sb_dsp_highspeed) {
|
||||
printf("SB Error: Midi output not possible during stereo or high speed audio\n");
|
||||
return -(EBUSY);
|
||||
}
|
||||
if (sb_midi_mode == UART_MIDI) {
|
||||
sb_irq_mode = IMODE_MIDI;
|
||||
|
||||
sb_reset_dsp();
|
||||
|
||||
if (!sb_dsp_command(0x35))
|
||||
return -(EIO); /* Enter the UART mode */
|
||||
sb_intr_active = 1;
|
||||
|
||||
input_opened = 1;
|
||||
midi_input_intr = input;
|
||||
}
|
||||
sb_midi_busy = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
sb_midi_close(int dev)
|
||||
{
|
||||
if (sb_midi_mode == UART_MIDI) {
|
||||
sb_reset_dsp(); /* The only way to kill the UART mode */
|
||||
}
|
||||
sb_intr_active = 0;
|
||||
sb_midi_busy = 0;
|
||||
input_opened = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sb_midi_out(int dev, u_char midi_byte)
|
||||
{
|
||||
u_long flags;
|
||||
|
||||
if (sb_midi_mode == NORMAL_MIDI) {
|
||||
flags = splhigh();
|
||||
if (sb_dsp_command(0x38))
|
||||
sb_dsp_command(midi_byte);
|
||||
else
|
||||
printf("SB Error: Unable to send a MIDI byte\n");
|
||||
splx(flags);
|
||||
} else
|
||||
sb_dsp_command(midi_byte); /* UART write */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
sb_midi_start_read(int dev)
|
||||
{
|
||||
if (sb_midi_mode != UART_MIDI) {
|
||||
printf("SoundBlaster: MIDI input not implemented.\n");
|
||||
return -(EPERM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sb_midi_end_read(int dev)
|
||||
{
|
||||
if (sb_midi_mode == UART_MIDI) {
|
||||
sb_reset_dsp();
|
||||
sb_intr_active = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sb_midi_ioctl(int dev, u_int cmd, ioctl_arg arg)
|
||||
{
|
||||
return -(EPERM);
|
||||
}
|
||||
|
||||
void
|
||||
sb_midi_interrupt(int dummy)
|
||||
{
|
||||
u_long flags;
|
||||
u_char data;
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
data = inb(DSP_READ);
|
||||
if (input_opened)
|
||||
midi_input_intr(my_dev, data);
|
||||
|
||||
splx(flags);
|
||||
}
|
||||
|
||||
#define MIDI_SYNTH_NAME "SoundBlaster Midi"
|
||||
#define MIDI_SYNTH_CAPS 0
|
||||
#include <i386/isa/sound/midi_synth.h>
|
||||
|
||||
static struct midi_operations sb_midi_operations =
|
||||
{
|
||||
{"SoundBlaster", 0, 0, SNDCARD_SB},
|
||||
&std_midi_synth,
|
||||
{0},
|
||||
sb_midi_open,
|
||||
sb_midi_close,
|
||||
sb_midi_ioctl,
|
||||
sb_midi_out,
|
||||
sb_midi_start_read,
|
||||
sb_midi_end_read,
|
||||
NULL, /* Kick */
|
||||
NULL, /* command */
|
||||
NULL, /* buffer_status */
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
sb_midi_init(int model)
|
||||
{
|
||||
if (num_midis >= MAX_MIDI_DEV) {
|
||||
printf("Sound: Too many midi devices detected\n");
|
||||
return;
|
||||
}
|
||||
std_midi_synth.midi_dev = num_midis;
|
||||
my_dev = num_midis;
|
||||
midi_devs[num_midis++] = &sb_midi_operations;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,529 +0,0 @@
|
||||
/*
|
||||
* sound/sb_mixer.c
|
||||
*
|
||||
* The low level mixer driver for the SoundBlaster Pro and SB16 cards.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1994
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Modified: Hunyue Yau Jan 6 1994 Added code to support the Sound Galaxy
|
||||
* NX Pro mixer.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if (NSB > 0) && defined(CONFIG_SBPRO)
|
||||
#define __SB_MIXER_C__
|
||||
|
||||
#include <i386/isa/sound/sbcard.h>
|
||||
#include <i386/isa/sound/sb_mixer.h>
|
||||
#undef SB_TEST_IRQ
|
||||
|
||||
extern int sbc_base;
|
||||
extern int Jazz16_detected;
|
||||
extern sound_os_info *sb_osp;
|
||||
|
||||
static int mixer_initialized = 0;
|
||||
|
||||
static int supported_rec_devices;
|
||||
static int supported_devices;
|
||||
static int recmask = 0;
|
||||
static int mixer_model;
|
||||
static int mixer_caps;
|
||||
static mixer_tab *iomap;
|
||||
|
||||
void
|
||||
sb_setmixer(u_int port, u_int value)
|
||||
{
|
||||
u_long flags;
|
||||
|
||||
flags = splhigh(); /* XXX ouch... */
|
||||
outb(MIXER_ADDR, (u_char) (port & 0xff)); /* Select register */
|
||||
DELAY(10);
|
||||
outb(MIXER_DATA, (u_char) (value & 0xff));
|
||||
DELAY(10);
|
||||
splx(flags);
|
||||
}
|
||||
|
||||
int
|
||||
sb_getmixer(u_int port)
|
||||
{
|
||||
int val;
|
||||
u_long flags;
|
||||
|
||||
flags = splhigh();
|
||||
outb(MIXER_ADDR, (u_char) (port & 0xff)); /* Select register */
|
||||
DELAY(10);
|
||||
val = inb(MIXER_DATA);
|
||||
DELAY(10);
|
||||
splx(flags);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void
|
||||
sb_mixer_set_stereo(int mode)
|
||||
{
|
||||
if (!mixer_initialized)
|
||||
return;
|
||||
|
||||
sb_setmixer(OUT_FILTER, ((sb_getmixer(OUT_FILTER) & ~STEREO_DAC)
|
||||
| (mode ? STEREO_DAC : MONO_DAC)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns:
|
||||
* 0 No mixer detected.
|
||||
* 1 Only a plain Sound Blaster Pro style mixer detected.
|
||||
* 2 The Sound Galaxy NX Pro mixer detected.
|
||||
*/
|
||||
static int
|
||||
detect_mixer(void)
|
||||
{
|
||||
|
||||
#ifdef __SGNXPRO__
|
||||
int oldbass, oldtreble;
|
||||
extern int sbc_major;
|
||||
#endif
|
||||
int retcode = 1;
|
||||
|
||||
/*
|
||||
* Detect the mixer by changing parameters of two volume channels. If
|
||||
* the values read back match with the values written, the mixer is
|
||||
* there (is it?)
|
||||
*/
|
||||
sb_setmixer(FM_VOL, 0xff);
|
||||
sb_setmixer(VOC_VOL, 0x33);
|
||||
|
||||
if (sb_getmixer(FM_VOL) != 0xff)
|
||||
return 0; /* No match */
|
||||
if (sb_getmixer(VOC_VOL) != 0x33)
|
||||
return 0;
|
||||
|
||||
#ifdef __SGNXPRO__
|
||||
/*
|
||||
* Attempt to detect the SG NX Pro by check for valid bass/treble
|
||||
* registers.
|
||||
*/
|
||||
oldbass = sb_getmixer(BASS_LVL);
|
||||
oldtreble = sb_getmixer(TREBLE_LVL);
|
||||
|
||||
sb_setmixer(BASS_LVL, 0xaa);
|
||||
sb_setmixer(TREBLE_LVL, 0x55);
|
||||
|
||||
if ((sb_getmixer(BASS_LVL) != 0xaa) ||
|
||||
(sb_getmixer(TREBLE_LVL) != 0x55)) {
|
||||
retcode = 1; /* 1 == Only SB Pro detected */
|
||||
} else
|
||||
retcode = 2; /* 2 == SG NX Pro detected */
|
||||
/*
|
||||
* Restore register in either case since SG NX Pro has EEPROM with
|
||||
* 'preferred' values stored.
|
||||
*/
|
||||
sb_setmixer(BASS_LVL, oldbass);
|
||||
sb_setmixer(TREBLE_LVL, oldtreble);
|
||||
|
||||
/*
|
||||
* If the SB version is 3.X (SB Pro), assume we have a SG NX Pro 16.
|
||||
* In this case it's good idea to disable the Disney Sound Source
|
||||
* compatibility mode. It's useless and just causes noise every time
|
||||
* the LPT-port is accessed.
|
||||
*
|
||||
* Also place the card into WSS mode.
|
||||
*/
|
||||
if (sbc_major == 3) {
|
||||
outb(sbc_base + 0x1c, 0x01);
|
||||
outb(sbc_base + 0x1a, 0x00);
|
||||
}
|
||||
#endif
|
||||
return retcode;
|
||||
}
|
||||
|
||||
static void
|
||||
change_bits(u_char *regval, int dev, int chn, int newval)
|
||||
{
|
||||
u_char mask;
|
||||
int shift;
|
||||
|
||||
mask = (1 << (*iomap)[dev][chn].nbits) - 1;
|
||||
newval = (int) ((newval * mask) + 50) / 100; /* Scale it */
|
||||
|
||||
shift = (*iomap)[dev][chn].bitoffs - (*iomap)[dev][LEFT_CHN].nbits + 1;
|
||||
|
||||
*regval &= ~(mask << shift); /* Filter out the previous value */
|
||||
*regval |= (newval & mask) << shift; /* Set the new value */
|
||||
}
|
||||
|
||||
static int
|
||||
sb_mixer_get(int dev)
|
||||
{
|
||||
if (!((1 << dev) & supported_devices))
|
||||
return -(EINVAL);
|
||||
|
||||
return levels[dev];
|
||||
}
|
||||
|
||||
#ifdef JAZZ16
|
||||
static char smw_mix_regs[] =/* Left mixer registers */
|
||||
{
|
||||
0x0b, /* SOUND_MIXER_VOLUME */
|
||||
0x0d, /* SOUND_MIXER_BASS */
|
||||
0x0d, /* SOUND_MIXER_TREBLE */
|
||||
0x05, /* SOUND_MIXER_SYNTH */
|
||||
0x09, /* SOUND_MIXER_PCM */
|
||||
0x00, /* SOUND_MIXER_SPEAKER */
|
||||
0x03, /* SOUND_MIXER_LINE */
|
||||
0x01, /* SOUND_MIXER_MIC */
|
||||
0x07, /* SOUND_MIXER_CD */
|
||||
0x00, /* SOUND_MIXER_IMIX */
|
||||
0x00, /* SOUND_MIXER_ALTPCM */
|
||||
0x00, /* SOUND_MIXER_RECLEV */
|
||||
0x00, /* SOUND_MIXER_IGAIN */
|
||||
0x00, /* SOUND_MIXER_OGAIN */
|
||||
0x00, /* SOUND_MIXER_LINE1 */
|
||||
0x00, /* SOUND_MIXER_LINE2 */
|
||||
0x00 /* SOUND_MIXER_LINE3 */
|
||||
};
|
||||
|
||||
static void
|
||||
smw_mixer_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
sb_setmixer(0x00, 0x18);/* Mute unused (Telephone) line */
|
||||
sb_setmixer(0x10, 0x38);/* Config register 2 */
|
||||
|
||||
supported_devices = 0;
|
||||
for (i = 0; i < sizeof(smw_mix_regs); i++)
|
||||
if (smw_mix_regs[i] != 0)
|
||||
supported_devices |= (1 << i);
|
||||
|
||||
supported_rec_devices = supported_devices &
|
||||
~(SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_PCM |
|
||||
SOUND_MASK_VOLUME);
|
||||
}
|
||||
|
||||
static int
|
||||
smw_mixer_set(int dev, int value)
|
||||
{
|
||||
int left = value & 0x000000ff;
|
||||
int right = (value & 0x0000ff00) >> 8;
|
||||
int reg, val;
|
||||
|
||||
if (left > 100)
|
||||
left = 100;
|
||||
if (right > 100)
|
||||
right = 100;
|
||||
|
||||
if (dev > 31)
|
||||
return -(EINVAL);
|
||||
|
||||
if (!(supported_devices & (1 << dev))) /* Not supported */
|
||||
return -(EINVAL);
|
||||
|
||||
switch (dev) {
|
||||
case SOUND_MIXER_VOLUME:
|
||||
sb_setmixer(0x0b, 96 - (96 * left / 100)); /* 96=mute, 0=max */
|
||||
sb_setmixer(0x0c, 96 - (96 * right / 100));
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_BASS:
|
||||
case SOUND_MIXER_TREBLE:
|
||||
levels[dev] = left | (right << 8);
|
||||
|
||||
/* Set left bass and treble values */
|
||||
val = ((levels[SOUND_MIXER_TREBLE] & 0xff) * 16 / 100) << 4;
|
||||
val |= ((levels[SOUND_MIXER_BASS] & 0xff) * 16 / 100) & 0x0f;
|
||||
sb_setmixer(0x0d, val);
|
||||
|
||||
/* Set right bass and treble values */
|
||||
val = (((levels[SOUND_MIXER_TREBLE] >> 8) & 0xff) * 16 / 100) << 4;
|
||||
val |= (((levels[SOUND_MIXER_BASS] >> 8) & 0xff) * 16 / 100) & 0x0f;
|
||||
sb_setmixer(0x0e, val);
|
||||
break;
|
||||
|
||||
default:
|
||||
reg = smw_mix_regs[dev];
|
||||
if (reg == 0)
|
||||
return -(EINVAL);
|
||||
sb_setmixer(reg, (24 - (24 * left / 100)) | 0x20); /* 24=mute, 0=max */
|
||||
sb_setmixer(reg + 1, (24 - (24 * right / 100)) | 0x40);
|
||||
}
|
||||
|
||||
levels[dev] = left | (right << 8);
|
||||
return left | (right << 8);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int
|
||||
sb_mixer_set(int dev, int value)
|
||||
{
|
||||
int left = value & 0x000000ff;
|
||||
int right = (value & 0x0000ff00) >> 8;
|
||||
|
||||
int regoffs;
|
||||
u_char val;
|
||||
|
||||
#ifdef JAZZ16
|
||||
if (Jazz16_detected == 2)
|
||||
return smw_mixer_set(dev, value);
|
||||
#endif
|
||||
|
||||
if (left > 100)
|
||||
left = 100;
|
||||
if (right > 100)
|
||||
right = 100;
|
||||
|
||||
if (dev > 31)
|
||||
return -(EINVAL);
|
||||
|
||||
if (!(supported_devices & (1 << dev))) /* Not supported */
|
||||
return -(EINVAL);
|
||||
|
||||
regoffs = (*iomap)[dev][LEFT_CHN].regno;
|
||||
|
||||
if (regoffs == 0)
|
||||
return -(EINVAL);
|
||||
|
||||
val = sb_getmixer(regoffs);
|
||||
change_bits(&val, dev, LEFT_CHN, left);
|
||||
|
||||
levels[dev] = left | (left << 8);
|
||||
|
||||
if ((*iomap)[dev][RIGHT_CHN].regno != regoffs) { /* Change register */
|
||||
sb_setmixer(regoffs, val); /* Save the old one */
|
||||
regoffs = (*iomap)[dev][RIGHT_CHN].regno;
|
||||
|
||||
if (regoffs == 0)
|
||||
return left | (left << 8); /* Just left channel present */
|
||||
|
||||
val = sb_getmixer(regoffs); /* Read the new one */
|
||||
}
|
||||
change_bits(&val, dev, RIGHT_CHN, right);
|
||||
|
||||
sb_setmixer(regoffs, val);
|
||||
|
||||
levels[dev] = left | (right << 8);
|
||||
return left | (right << 8);
|
||||
}
|
||||
|
||||
static void
|
||||
set_recsrc(int src)
|
||||
{
|
||||
sb_setmixer(RECORD_SRC, (sb_getmixer(RECORD_SRC) & ~7) | (src & 0x7));
|
||||
}
|
||||
|
||||
static int
|
||||
set_recmask(int mask)
|
||||
{
|
||||
int devmask, i;
|
||||
u_char regimageL, regimageR;
|
||||
|
||||
devmask = mask & supported_rec_devices;
|
||||
|
||||
switch (mixer_model) {
|
||||
case 3:
|
||||
|
||||
if (devmask != SOUND_MASK_MIC && devmask != SOUND_MASK_LINE &&
|
||||
devmask != SOUND_MASK_CD) {
|
||||
/*
|
||||
* More than one devices selected. Drop the previous
|
||||
* selection
|
||||
*/
|
||||
devmask &= ~recmask;
|
||||
}
|
||||
if (devmask != SOUND_MASK_MIC && devmask != SOUND_MASK_LINE &&
|
||||
devmask != SOUND_MASK_CD) {
|
||||
/* More than one devices selected. Default to mic */
|
||||
devmask = SOUND_MASK_MIC;
|
||||
}
|
||||
if (devmask ^ recmask) { /* Input source changed */
|
||||
switch (devmask) {
|
||||
|
||||
case SOUND_MASK_MIC:
|
||||
set_recsrc(SRC_MIC);
|
||||
break;
|
||||
|
||||
case SOUND_MASK_LINE:
|
||||
set_recsrc(SRC_LINE);
|
||||
break;
|
||||
|
||||
case SOUND_MASK_CD:
|
||||
set_recsrc(SRC_CD);
|
||||
break;
|
||||
|
||||
default:
|
||||
set_recsrc(SRC_MIC);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (!devmask)
|
||||
devmask = SOUND_MASK_MIC;
|
||||
|
||||
regimageL = regimageR = 0;
|
||||
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
|
||||
if ((1 << i) & devmask) {
|
||||
regimageL |= sb16_recmasks_L[i];
|
||||
regimageR |= sb16_recmasks_R[i];
|
||||
}
|
||||
sb_setmixer(SB16_IMASK_L, regimageL);
|
||||
sb_setmixer(SB16_IMASK_R, regimageR);
|
||||
break;
|
||||
}
|
||||
|
||||
recmask = devmask;
|
||||
return recmask;
|
||||
}
|
||||
|
||||
static int
|
||||
sb_mixer_ioctl(int dev, u_int cmd, ioctl_arg arg)
|
||||
{
|
||||
if (((cmd >> 8) & 0xff) == 'M') {
|
||||
if (cmd & IOC_IN)
|
||||
switch (cmd & 0xff) {
|
||||
case SOUND_MIXER_RECSRC:
|
||||
return *(int *) arg = set_recmask((*(int *) arg));
|
||||
break;
|
||||
|
||||
default:
|
||||
return *(int *) arg = sb_mixer_set(cmd & 0xff, (*(int *) arg));
|
||||
}
|
||||
else
|
||||
switch (cmd & 0xff) { /* Return parameters */
|
||||
|
||||
case SOUND_MIXER_RECSRC:
|
||||
return *(int *) arg = recmask;
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_DEVMASK:
|
||||
return *(int *) arg = supported_devices;
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_STEREODEVS:
|
||||
if (Jazz16_detected)
|
||||
return *(int *) arg = supported_devices;
|
||||
else
|
||||
return *(int *) arg = supported_devices & ~(SOUND_MASK_MIC | SOUND_MASK_SPEAKER);
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_RECMASK:
|
||||
return *(int *) arg = supported_rec_devices;
|
||||
break;
|
||||
|
||||
case SOUND_MIXER_CAPS:
|
||||
return *(int *) arg = mixer_caps;
|
||||
break;
|
||||
|
||||
default:
|
||||
return *(int *) arg = sb_mixer_get(cmd & 0xff);
|
||||
}
|
||||
} else
|
||||
return -(EINVAL);
|
||||
}
|
||||
|
||||
static struct mixer_operations sb_mixer_operations =
|
||||
{
|
||||
"SoundBlaster",
|
||||
sb_mixer_ioctl
|
||||
};
|
||||
|
||||
static void
|
||||
sb_mixer_reset(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
|
||||
sb_mixer_set(i, levels[i]);
|
||||
set_recmask(SOUND_MASK_MIC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a code depending on whether a SG NX Pro was detected. 1 == Plain
|
||||
* SB Pro 2 == SG NX Pro detected. 3 == SB16
|
||||
*
|
||||
* Used to update message.
|
||||
*/
|
||||
int
|
||||
sb_mixer_init(int major_model)
|
||||
{
|
||||
int mixer_type = 0;
|
||||
|
||||
sb_setmixer(0x00, 0); /* Reset mixer */
|
||||
|
||||
if (!(mixer_type = detect_mixer()))
|
||||
return 0; /* No mixer. Why? */
|
||||
|
||||
mixer_initialized = 1;
|
||||
mixer_model = major_model;
|
||||
|
||||
switch (major_model) {
|
||||
case 3:
|
||||
mixer_caps = SOUND_CAP_EXCL_INPUT;
|
||||
|
||||
#ifdef JAZZ16
|
||||
if (Jazz16_detected == 2) { /* SM Wave */
|
||||
supported_devices = 0;
|
||||
supported_rec_devices = 0;
|
||||
iomap = &sbpro_mix;
|
||||
smw_mixer_init();
|
||||
mixer_type = 1;
|
||||
} else
|
||||
#endif
|
||||
#ifdef __SGNXPRO__
|
||||
if (mixer_type == 2) { /* A SGNXPRO was detected */
|
||||
supported_devices = SGNXPRO_MIXER_DEVICES;
|
||||
supported_rec_devices = SGNXPRO_RECORDING_DEVICES;
|
||||
iomap = &sgnxpro_mix;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
supported_devices = SBPRO_MIXER_DEVICES;
|
||||
supported_rec_devices = SBPRO_RECORDING_DEVICES;
|
||||
iomap = &sbpro_mix;
|
||||
mixer_type = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
mixer_caps = 0;
|
||||
supported_devices = SB16_MIXER_DEVICES;
|
||||
supported_rec_devices = SB16_RECORDING_DEVICES;
|
||||
iomap = &sb16_mix;
|
||||
mixer_type = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("SB Warning: Unsupported mixer type\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (num_mixers < MAX_MIXER_DEV)
|
||||
mixer_devs[num_mixers++] = &sb_mixer_operations;
|
||||
sb_mixer_reset();
|
||||
return mixer_type;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,255 +0,0 @@
|
||||
/*
|
||||
* sound/sb_mixer.h
|
||||
*
|
||||
* Definitions for the SB Pro and SB16 mixers
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Modified: Hunyue Yau Jan 6 1994 Added defines for the Sound Galaxy NX Pro
|
||||
* mixer.
|
||||
*
|
||||
*/
|
||||
|
||||
#define SBPRO_RECORDING_DEVICES (SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD)
|
||||
|
||||
/* Same as SB Pro, unless I find otherwise */
|
||||
#define SGNXPRO_RECORDING_DEVICES SBPRO_RECORDING_DEVICES
|
||||
|
||||
#define SBPRO_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_LINE | SOUND_MASK_MIC | \
|
||||
SOUND_MASK_CD | SOUND_MASK_VOLUME)
|
||||
|
||||
/*
|
||||
* SG NX Pro has treble and bass settings on the mixer. The 'speaker' channel
|
||||
* is the COVOX/DisneySoundSource emulation volume control on the mixer. It
|
||||
* does NOT control speaker volume. Should have own mask eventually?
|
||||
*/
|
||||
#define SGNXPRO_MIXER_DEVICES (SBPRO_MIXER_DEVICES|SOUND_MASK_BASS| \
|
||||
SOUND_MASK_TREBLE|SOUND_MASK_SPEAKER )
|
||||
|
||||
#define SB16_RECORDING_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_LINE | SOUND_MASK_MIC | \
|
||||
SOUND_MASK_CD)
|
||||
|
||||
#define SB16_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | SOUND_MASK_MIC | \
|
||||
SOUND_MASK_CD | \
|
||||
SOUND_MASK_IGAIN | SOUND_MASK_OGAIN | \
|
||||
SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE)
|
||||
|
||||
/*
|
||||
* Mixer registers
|
||||
*
|
||||
* NOTE! RECORD_SRC == IN_FILTER
|
||||
*/
|
||||
|
||||
/*
|
||||
* Mixer registers of SB Pro
|
||||
*/
|
||||
#define VOC_VOL 0x04
|
||||
#define MIC_VOL 0x0A
|
||||
#define MIC_MIX 0x0A
|
||||
#define RECORD_SRC 0x0C
|
||||
#define IN_FILTER 0x0C
|
||||
#define OUT_FILTER 0x0E
|
||||
#define MASTER_VOL 0x22
|
||||
#define FM_VOL 0x26
|
||||
#define CD_VOL 0x28
|
||||
#define LINE_VOL 0x2E
|
||||
#define IRQ_NR 0x80
|
||||
#define DMA_NR 0x81
|
||||
#define IRQ_STAT 0x82
|
||||
#define OPSW 0x3c
|
||||
|
||||
/*
|
||||
* Additional registers on the SG NX Pro
|
||||
*/
|
||||
#define COVOX_VOL 0x42
|
||||
#define TREBLE_LVL 0x44
|
||||
#define BASS_LVL 0x46
|
||||
|
||||
#define FREQ_HI (1 << 3)/* Use High-frequency ANFI filters */
|
||||
#define FREQ_LOW 0 /* Use Low-frequency ANFI filters */
|
||||
#define FILT_ON 0 /* Yes, 0 to turn it on, 1 for off */
|
||||
#define FILT_OFF (1 << 5)
|
||||
|
||||
#define MONO_DAC 0x00
|
||||
#define STEREO_DAC 0x02
|
||||
|
||||
/*
|
||||
* Mixer registers of SB16
|
||||
*/
|
||||
#define SB16_IMASK_L 0x3d
|
||||
#define SB16_IMASK_R 0x3e
|
||||
|
||||
#define LEFT_CHN 0
|
||||
#define RIGHT_CHN 1
|
||||
|
||||
struct mixer_def {
|
||||
unsigned int regno:8;
|
||||
unsigned int bitoffs:4;
|
||||
unsigned int nbits:4;
|
||||
};
|
||||
|
||||
|
||||
typedef struct mixer_def mixer_tab[32][2];
|
||||
typedef struct mixer_def mixer_ent;
|
||||
|
||||
#define MIX_ENT(name, reg_l, bit_l, len_l, reg_r, bit_r, len_r) \
|
||||
{{reg_l, bit_l, len_l}, {reg_r, bit_r, len_r}}
|
||||
|
||||
#ifdef __SB_MIXER_C__
|
||||
mixer_tab sbpro_mix = {
|
||||
MIX_ENT(SOUND_MIXER_VOLUME, 0x22, 7, 4, 0x22, 3, 4),
|
||||
MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_SYNTH, 0x26, 7, 4, 0x26, 3, 4),
|
||||
MIX_ENT(SOUND_MIXER_PCM, 0x04, 7, 4, 0x04, 3, 4),
|
||||
MIX_ENT(SOUND_MIXER_SPEAKER, 0x00, 0, 0, 0x00, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_LINE, 0x2e, 7, 4, 0x2e, 3, 4),
|
||||
MIX_ENT(SOUND_MIXER_MIC, 0x0a, 2, 3, 0x00, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_CD, 0x28, 7, 4, 0x28, 3, 4),
|
||||
MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0)
|
||||
};
|
||||
|
||||
#ifdef __SGNXPRO__
|
||||
mixer_tab sgnxpro_mix = {
|
||||
MIX_ENT(SOUND_MIXER_VOLUME, 0x22, 7, 4, 0x22, 3, 4),
|
||||
MIX_ENT(SOUND_MIXER_BASS, 0x46, 2, 3, 0x00, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_TREBLE, 0x44, 2, 3, 0x00, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_SYNTH, 0x26, 7, 4, 0x26, 3, 4),
|
||||
MIX_ENT(SOUND_MIXER_PCM, 0x04, 7, 4, 0x04, 3, 4),
|
||||
MIX_ENT(SOUND_MIXER_SPEAKER, 0x42, 2, 3, 0x00, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_LINE, 0x2e, 7, 4, 0x2e, 3, 4),
|
||||
MIX_ENT(SOUND_MIXER_MIC, 0x0a, 2, 3, 0x00, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_CD, 0x28, 7, 4, 0x28, 3, 4),
|
||||
MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0)
|
||||
};
|
||||
#endif
|
||||
|
||||
mixer_tab sb16_mix = {
|
||||
MIX_ENT(SOUND_MIXER_VOLUME, 0x30, 7, 5, 0x31, 7, 5),
|
||||
MIX_ENT(SOUND_MIXER_BASS, 0x46, 7, 4, 0x47, 7, 4),
|
||||
MIX_ENT(SOUND_MIXER_TREBLE, 0x44, 7, 4, 0x45, 7, 4),
|
||||
MIX_ENT(SOUND_MIXER_SYNTH, 0x34, 7, 5, 0x35, 7, 5),
|
||||
MIX_ENT(SOUND_MIXER_PCM, 0x32, 7, 5, 0x33, 7, 5),
|
||||
MIX_ENT(SOUND_MIXER_SPEAKER, 0x3b, 7, 2, 0x00, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_LINE, 0x38, 7, 5, 0x39, 7, 5),
|
||||
MIX_ENT(SOUND_MIXER_MIC, 0x3a, 7, 5, 0x00, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_CD, 0x36, 7, 5, 0x37, 7, 5),
|
||||
MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
|
||||
MIX_ENT(SOUND_MIXER_RECLEV, 0x3f, 7, 2, 0x40, 7, 2), /* Obsolete. Use IGAIN */
|
||||
MIX_ENT(SOUND_MIXER_IGAIN, 0x3f, 7, 2, 0x40, 7, 2),
|
||||
MIX_ENT(SOUND_MIXER_OGAIN, 0x41, 7, 2, 0x42, 7, 2)
|
||||
};
|
||||
|
||||
#ifdef SM_GAMES /* Master volume is lower and PCM & FM
|
||||
* volumes higher than with SB Pro. This
|
||||
* improves the sound quality */
|
||||
|
||||
static unsigned short levels[SOUND_MIXER_NRDEVICES] =
|
||||
{
|
||||
0x2020, /* Master Volume */
|
||||
0x4b4b, /* Bass */
|
||||
0x4b4b, /* Treble */
|
||||
0x6464, /* FM */
|
||||
0x6464, /* PCM */
|
||||
0x4b4b, /* PC Speaker */
|
||||
0x4b4b, /* Ext Line */
|
||||
0x0000, /* Mic */
|
||||
0x4b4b, /* CD */
|
||||
0x4b4b, /* Recording monitor */
|
||||
0x4b4b, /* SB PCM */
|
||||
0x4b4b, /* Recording level */
|
||||
0x4b4b, /* Input gain */
|
||||
0x4b4b}; /* Output gain */
|
||||
|
||||
#else /* If the user selected just plain SB Pro */
|
||||
|
||||
static unsigned short levels[SOUND_MIXER_NRDEVICES] =
|
||||
{
|
||||
0x5a5a, /* Master Volume */
|
||||
0x4b4b, /* Bass */
|
||||
0x4b4b, /* Treble */
|
||||
0x4b4b, /* FM */
|
||||
0x4b4b, /* PCM */
|
||||
0x4b4b, /* PC Speaker */
|
||||
0x4b4b, /* Ext Line */
|
||||
0x1010, /* Mic */
|
||||
0x4b4b, /* CD */
|
||||
0x4b4b, /* Recording monitor */
|
||||
0x4b4b, /* SB PCM */
|
||||
0x4b4b, /* Recording level */
|
||||
0x4b4b, /* Input gain */
|
||||
0x4b4b}; /* Output gain */
|
||||
#endif /* SM_GAMES */
|
||||
|
||||
static unsigned char sb16_recmasks_L[SOUND_MIXER_NRDEVICES] =
|
||||
{
|
||||
0x00, /* SOUND_MIXER_VOLUME */
|
||||
0x00, /* SOUND_MIXER_BASS */
|
||||
0x00, /* SOUND_MIXER_TREBLE */
|
||||
0x40, /* SOUND_MIXER_SYNTH */
|
||||
0x00, /* SOUND_MIXER_PCM */
|
||||
0x00, /* SOUND_MIXER_SPEAKER */
|
||||
0x10, /* SOUND_MIXER_LINE */
|
||||
0x01, /* SOUND_MIXER_MIC */
|
||||
0x04, /* SOUND_MIXER_CD */
|
||||
0x00, /* SOUND_MIXER_IMIX */
|
||||
0x00, /* SOUND_MIXER_ALTPCM */
|
||||
0x00, /* SOUND_MIXER_RECLEV */
|
||||
0x00, /* SOUND_MIXER_IGAIN */
|
||||
0x00 /* SOUND_MIXER_OGAIN */
|
||||
};
|
||||
|
||||
static unsigned char sb16_recmasks_R[SOUND_MIXER_NRDEVICES] =
|
||||
{
|
||||
0x00, /* SOUND_MIXER_VOLUME */
|
||||
0x00, /* SOUND_MIXER_BASS */
|
||||
0x00, /* SOUND_MIXER_TREBLE */
|
||||
0x20, /* SOUND_MIXER_SYNTH */
|
||||
0x00, /* SOUND_MIXER_PCM */
|
||||
0x00, /* SOUND_MIXER_SPEAKER */
|
||||
0x08, /* SOUND_MIXER_LINE */
|
||||
0x01, /* SOUND_MIXER_MIC */
|
||||
0x02, /* SOUND_MIXER_CD */
|
||||
0x00, /* SOUND_MIXER_IMIX */
|
||||
0x00, /* SOUND_MIXER_ALTPCM */
|
||||
0x00, /* SOUND_MIXER_RECLEV */
|
||||
0x00, /* SOUND_MIXER_IGAIN */
|
||||
0x00 /* SOUND_MIXER_OGAIN */
|
||||
};
|
||||
|
||||
/*
|
||||
* Recording sources (SB Pro)
|
||||
*/
|
||||
|
||||
#define SRC_MIC 1 /* Select Microphone recording source */
|
||||
#define SRC_CD 3 /* Select CD recording source */
|
||||
#define SRC_LINE 7 /* Use Line-in for recording source */
|
||||
|
||||
#endif
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
* file: sbcard.h
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
|
||||
extern int sbc_major, sbc_minor ;
|
||||
/*
|
||||
* sound blaster registers
|
||||
*/
|
||||
|
||||
#ifdef PC98
|
||||
#define DSP_RESET (sbc_base + 0x600)
|
||||
#define DSP_READ (sbc_base + 0xA00)
|
||||
#define DSP_WRITE (sbc_base + 0xC00)
|
||||
#define DSP_COMMAND (sbc_base + 0xC00)
|
||||
#define DSP_STATUS (sbc_base + 0xC00)
|
||||
#define DSP_DATA_AVAIL (sbc_base + 0xE00)
|
||||
#define DSP_DATA_AVL16 (sbc_base + 0xF00)
|
||||
#define MIXER_ADDR (sbc_base + 0x400)
|
||||
#define MIXER_DATA (sbc_base + 0x500)
|
||||
#define OPL3_LEFT (sbc_base + 0x000)
|
||||
#define OPL3_RIGHT (sbc_base + 0x200)
|
||||
#define OPL3_BOTH (sbc_base + 0x800)
|
||||
#else
|
||||
#define DSP_RESET (sbc_base + 0x6)
|
||||
#define DSP_READ (sbc_base + 0xA)
|
||||
#define DSP_WRITE (sbc_base + 0xC)
|
||||
#define DSP_COMMAND (sbc_base + 0xC)
|
||||
#define DSP_STATUS (sbc_base + 0xC)
|
||||
#define DSP_DATA_AVAIL (sbc_base + 0xE)
|
||||
#define DSP_DATA_AVL16 (sbc_base + 0xF)
|
||||
#define MIXER_ADDR (sbc_base + 0x4)
|
||||
#define MIXER_DATA (sbc_base + 0x5)
|
||||
#define OPL3_LEFT (sbc_base + 0x0)
|
||||
#define OPL3_RIGHT (sbc_base + 0x2)
|
||||
#define OPL3_BOTH (sbc_base + 0x8)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* DSP Commands. There are many, and in many cases they are used explicitly
|
||||
*/
|
||||
|
||||
#define DSP_CMD_SPKON 0xD1
|
||||
#define DSP_CMD_SPKOFF 0xD3
|
||||
#define DSP_CMD_DMAON 0xD0 /* ??? the comment says Halt DMA */
|
||||
#define DSP_CMD_DMAOFF 0xD4 /* ??? comment says continue dma */
|
||||
|
||||
#define DSP_CMD_DMAHALT 0xD0
|
||||
#define DSP_CMD_TCONST 0x40 /* set time constant */
|
||||
#define DSP_CMD_HSSIZE 0x48 /* high speed dma count */
|
||||
#define DSP_CMD_HSDAC 0x91 /* high speed dac */
|
||||
#define DSP_CMD_HSADC 0x99 /* high speed adc */
|
||||
#define DSP_CMD_DAC8 0x14 /* 8-bit dac (dma count) */
|
||||
#define DSP_CMD_ADC8 0x24 /* 8-bit adc (dma count) */
|
||||
|
||||
#define DSP_CMD_GETVER 0xE1
|
||||
#define DSP_CMD_GETID 0xE7 /* return id bytes */
|
||||
|
||||
#if 0 /*** unknown ***/
|
||||
|
||||
#endif
|
||||
|
||||
#define IMODE_NONE 0
|
||||
#define IMODE_OUTPUT PCM_ENABLE_OUTPUT
|
||||
#define IMODE_INPUT PCM_ENABLE_INPUT
|
||||
#define IMODE_INIT 3
|
||||
#define IMODE_MIDI 4
|
||||
|
||||
#define NORMAL_MIDI 0
|
||||
#define UART_MIDI 1
|
File diff suppressed because it is too large
Load Diff
@ -1,120 +0,0 @@
|
||||
$FreeBSD$
|
||||
|
||||
Instructions on using audio on a FreeBSD 2.1 (or 2.0-current) system.
|
||||
See also /sys/i386/conf/LINT.
|
||||
|
||||
To enable sound driver support, the controller sound code must be included
|
||||
in your config file:
|
||||
|
||||
# SB = SoundBlaster; PAS = ProAudioSpectrum; GUS = Gravis UltraSound
|
||||
# Controls all sound devices
|
||||
controller snd0
|
||||
|
||||
Uncomment one or more of these device entries, depending on what type of
|
||||
sound card you have:
|
||||
|
||||
# ProAudioSpectrum PCM and Midi - for PAS
|
||||
#device pas0 at isa? port 0x388 irq 10 drq 6
|
||||
|
||||
# SoundBlaster DSP driver - for SB, SB Pro, SB16, PAS(emulating SB)
|
||||
#device sb0 at isa? port 0x220 irq 7 drq 1
|
||||
|
||||
# SoundBlaster 16 DSP driver - for SB16 - requires sb0 device
|
||||
#device sbxvi0 at isa? drq 5
|
||||
|
||||
# SoundBlaster 16 MIDI - for SB16 - requires sb0 device
|
||||
#device sbmidi0 at isa? port 0x300
|
||||
|
||||
# Gravis UltraSound - for GUS, GUS16, GUSMAX
|
||||
# For cards that use 2 DMA Channels:
|
||||
# drq = Write DMA Channel, flags = Read DMA Channel
|
||||
#device gus0 at isa? port 0x220 irq 11 drq 1 flags 0x3
|
||||
|
||||
# Gravis UltraSound 16 bit option - for GUS16 - requires gus0
|
||||
#device gusxvi0 at isa? port 0x530 irq 7 drq 3
|
||||
|
||||
# MS Sound System (AD1848 Based Boards)
|
||||
#device mss0 at isa? port 0x530 irq 10 drq 1
|
||||
|
||||
# Yamaha OPL-2/OPL-3 FM - for SB, SB Pro, SB16, PAS
|
||||
#device opl0 at isa? port 0x388
|
||||
|
||||
# MPU-401 - for MPU-401 standalone card
|
||||
#device mpu0 at isa? port 0x330 irq 6 drq 0
|
||||
|
||||
# 6850 UART Midi
|
||||
#device uart0 at isa? port 0x330 irq 5
|
||||
|
||||
You may add one or more of the following depending on what you do and don't
|
||||
want compiled into your kernel. Note: Excluding things with EXCLUDE_...
|
||||
is NOT recommended unless you really know what you're doing.
|
||||
|
||||
#options EXCLUDE_AUDIO # NO digital audio support
|
||||
#options EXCLUDE_SEQUENCER # NO sequencer support
|
||||
#options EXCLUDE_MIDI # NO MIDI support whatsoever
|
||||
#options EXCLUDE_SBPRO # EXCLUDE SB Pro support
|
||||
#options EXCLUDE_SB_EMULATION # NO PAS SB emulation support
|
||||
#options EXCLUDE_GUS_IODETECT # NO GUS io detection
|
||||
#options EXCLUDE_PRO_MIDI # NO PAS MIDI support
|
||||
|
||||
Other Options:
|
||||
|
||||
#options SYMPHONY_PAS
|
||||
Adds some code to make pas work with Symphony chipsets. Only use
|
||||
this if your pas doesn't work and you have a Symphony chipset.
|
||||
|
||||
#options BROKEN_BUS_CLOCK
|
||||
Some systems with the OPTI chipset and a PAS will require you to
|
||||
use this option. Symptoms are that you will hear a lot of clicking and
|
||||
popping sounds, like a geiger counter, coming out of the PAS even when
|
||||
it is not playing anything.
|
||||
|
||||
#options MOZART_PORT
|
||||
Adds support for Mozart (OAK OTI-601). (Part of the MSS driver)
|
||||
|
||||
#options OPTI_MAD16_PORT
|
||||
Adds support for the OPTI MAD16 Chip. (Part of the MSS driver)
|
||||
If your soundcard has a chip labeled "OPTi 82C929" then try this.
|
||||
|
||||
#options __SGNXPRO__
|
||||
Adds support for the SG NX Pro mixer. (Part of the SB driver)
|
||||
|
||||
#options JAZZ16
|
||||
Adds support for the MV Jazz16 (ProSonic etc). (Part of the SB Driver)
|
||||
|
||||
#options SM_WAVE
|
||||
Adds support for the SoundMan Wave (Part of the SB Driver)
|
||||
Note: You will need to do some work to get this to work.
|
||||
See i386/isa/sound/configure.c
|
||||
|
||||
#options SM_GAMES
|
||||
Adds support for the Logitech SoundMan Games (Part of the SB Driver)
|
||||
|
||||
#options PAS_JOYSTICK_ENABLE
|
||||
Enables the gameport on the ProAudio Spectrum
|
||||
|
||||
NOTE: The MPU-401 driver may or may not work, and is unfortunately
|
||||
unverifiable since no one I know has one. If you can test this,
|
||||
please let me know! Also note that you will have to change these
|
||||
settings if your soundcard is set for a non-standard address or IRQ.
|
||||
Please check your documentation (or verify with any provided DOS utilities
|
||||
that may have come with your card) and set the IRQ or address fields
|
||||
accordingly.
|
||||
|
||||
|
||||
Also: You can configure more then one card on a single DMA using
|
||||
the conflicts keyword in your configuration file. This is useful for boards
|
||||
with more then one type of emulation.
|
||||
|
||||
|
||||
Probing problems: Since the SB16 uses the same IRQ and addresses for
|
||||
the different drivers, some of the snd drivers will not be probed because
|
||||
the kernel thinks there is a conflict. This can be worked-around by
|
||||
using the "conflicts" keyword on the sb16's device line.
|
||||
|
||||
|
||||
For further information, contact multimedia@freebsd.org
|
||||
|
||||
- Jordan Hubbard (jkh@freefall.cdrom.com)
|
||||
- Steven Wallace (swallace@freefall.cdrom.com)
|
||||
- Sujal Patel (smpatel@wam.umd.edu)
|
@ -1,293 +0,0 @@
|
||||
/*
|
||||
* DMA buffer calls
|
||||
*/
|
||||
|
||||
int DMAbuf_open(int dev, int mode);
|
||||
int DMAbuf_release(int dev, int mode);
|
||||
int DMAbuf_getwrbuffer(int dev, char **buf, int *size, int dontblock);
|
||||
int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock);
|
||||
int DMAbuf_rmchars(int dev, int buff_no, int c);
|
||||
int DMAbuf_start_output(int dev, int buff_no, int l);
|
||||
int DMAbuf_ioctl(int dev, u_int cmd, ioctl_arg arg, int local);
|
||||
void DMAbuf_init(void);
|
||||
int DMAbuf_start_dma (int dev, u_long physaddr, int count, int dma_mode);
|
||||
int DMAbuf_open_dma (int dev);
|
||||
void DMAbuf_close_dma (int dev);
|
||||
void DMAbuf_reset_dma (int dev);
|
||||
void DMAbuf_inputintr(int dev);
|
||||
void DMAbuf_outputintr(int dev, int underflow_flag);
|
||||
void DMAbuf_start_devices(u_int devmask);
|
||||
#ifdef ALLOW_POLL
|
||||
int DMAbuf_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* System calls for /dev/dsp and /dev/audio
|
||||
*/
|
||||
|
||||
int audio_read (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
|
||||
int audio_write (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
|
||||
int audio_open (int dev, struct fileinfo *file);
|
||||
void audio_release (int dev, struct fileinfo *file);
|
||||
int audio_ioctl (int dev, struct fileinfo *file,
|
||||
u_int cmd, ioctl_arg arg);
|
||||
int audio_lseek (int dev, struct fileinfo *file, off_t offset, int orig);
|
||||
/* long audio_init (void); */
|
||||
|
||||
#ifdef ALLOW_SELECT
|
||||
int audio_poll(int dev, struct fileinfo *file, int events, select_table * wait);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* System calls for the /dev/sequencer
|
||||
*/
|
||||
|
||||
int sequencer_read (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
|
||||
int sequencer_write (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
|
||||
int sequencer_open (int dev, struct fileinfo *file);
|
||||
void sequencer_release (int dev, struct fileinfo *file);
|
||||
int sequencer_ioctl (int dev, struct fileinfo *file,
|
||||
u_int cmd, ioctl_arg arg);
|
||||
int sequencer_lseek (int dev, struct fileinfo *file, off_t offset, int orig);
|
||||
void sequencer_init (void);
|
||||
void sequencer_timer(void *dummy);
|
||||
int note_to_freq(int note_num);
|
||||
u_long compute_finetune(u_long base_freq, int bend, int range);
|
||||
void seq_input_event(u_char *event, int len);
|
||||
void seq_copy_to_input (u_char *event, int len);
|
||||
|
||||
|
||||
/*
|
||||
* System calls for the /dev/midi
|
||||
*/
|
||||
|
||||
int MIDIbuf_read (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
|
||||
int MIDIbuf_write (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
|
||||
int MIDIbuf_open (int dev, struct fileinfo *file);
|
||||
void MIDIbuf_release (int dev, struct fileinfo *file);
|
||||
int MIDIbuf_ioctl (int dev, struct fileinfo *file,
|
||||
u_int cmd, ioctl_arg arg);
|
||||
int MIDIbuf_lseek (int dev, struct fileinfo *file, off_t offset, int orig);
|
||||
void MIDIbuf_bytes_received(int dev, u_char *buf, int count);
|
||||
|
||||
/*
|
||||
*
|
||||
* Misc calls from various sources
|
||||
*/
|
||||
|
||||
/* From soundcard.c */
|
||||
void soundcard_init(void);
|
||||
void tenmicrosec(int);
|
||||
void request_sound_timer (int count);
|
||||
void sound_stop_timer(void);
|
||||
int snd_ioctl_return(int *addr, int value);
|
||||
int snd_set_irq_handler (int int_lvl, void(*hndlr)(int), sound_os_info *osp);
|
||||
void sound_dma_malloc(int dev);
|
||||
void sound_dma_free(int dev);
|
||||
void conf_printf(char *name, struct address_info *hw_config);
|
||||
void conf_printf2(char *name, int base, int irq, int dma, int dma2);
|
||||
|
||||
/* From sound_switch.c */
|
||||
int sound_read_sw (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
|
||||
int sound_write_sw (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
|
||||
int sound_open_sw (int dev, struct fileinfo *file);
|
||||
void sound_release_sw (int dev, struct fileinfo *file);
|
||||
int sound_ioctl_sw (int dev, struct fileinfo *file, u_int cmd, ioctl_arg arg);
|
||||
|
||||
/* From sb_dsp.c */
|
||||
int sb_dsp_detect (struct address_info *hw_config);
|
||||
void sb_dsp_init (struct address_info *hw_config);
|
||||
void sb_dsp_disable_midi(void);
|
||||
int sb_dsp_command (u_char val);
|
||||
ointhand2_t sbintr;
|
||||
int sb_reset_dsp (void);
|
||||
|
||||
/* From sb16_dsp.c */
|
||||
void sb16_dsp_interrupt (int irq);
|
||||
void sb16_dsp_init(struct address_info *hw_config);
|
||||
int sb16_dsp_detect(struct address_info *hw_config);
|
||||
|
||||
/* From sb16_midi.c */
|
||||
void sb16midiintr (int unit);
|
||||
void attach_sb16midi(struct address_info * hw_config);
|
||||
int probe_sb16midi(struct address_info *hw_config);
|
||||
void sb_midi_interrupt(int dummy);
|
||||
|
||||
/* From sb_midi.c */
|
||||
void sb_midi_init(int model);
|
||||
|
||||
/* From sb_mixer.c */
|
||||
void sb_setmixer (u_int port, u_int value);
|
||||
int sb_getmixer (u_int port);
|
||||
void sb_mixer_set_stereo(int mode);
|
||||
int sb_mixer_init(int major_model);
|
||||
|
||||
/* From opl3.c */
|
||||
int opl3_detect (int ioaddr, sound_os_info *osp);
|
||||
void opl3_init(int ioaddr, sound_os_info *osp);
|
||||
|
||||
/* From sb_card.c */
|
||||
void attach_sb_card(struct address_info *hw_config);
|
||||
int probe_sb(struct address_info *hw_config);
|
||||
|
||||
/* From awe_wave.c */
|
||||
void attach_awe(struct address_info *hw_config);
|
||||
int probe_awe(struct address_info *hw_config);
|
||||
|
||||
/* From adlib_card.c */
|
||||
void attach_adlib_card(struct address_info *hw_config);
|
||||
int probe_adlib(struct address_info *hw_config);
|
||||
|
||||
/* From pas_card.c */
|
||||
void attach_pas_card(struct address_info *hw_config);
|
||||
int probe_pas(struct address_info *hw_config);
|
||||
ointhand2_t pasintr;
|
||||
int pas_set_intr(int mask);
|
||||
int pas_remove_intr(int mask);
|
||||
u_char pas_read(int ioaddr);
|
||||
void pas_write(u_char data, int ioaddr);
|
||||
|
||||
/* From pas_audio.c */
|
||||
void pas_pcm_interrupt(u_char status, int cause);
|
||||
void pas_pcm_init(struct address_info *hw_config);
|
||||
|
||||
/* From pas_mixer.c */
|
||||
int pas_init_mixer(void);
|
||||
|
||||
/* From pas_midi.c */
|
||||
void pas_midi_init(void);
|
||||
void pas_midi_interrupt(void);
|
||||
|
||||
/* From gus_card.c */
|
||||
void attach_gus_card(struct address_info * hw_config);
|
||||
int probe_gus(struct address_info *hw_config);
|
||||
int gus_set_midi_irq(int num);
|
||||
ointhand2_t gusintr;
|
||||
void attach_gus_db16(struct address_info * hw_config);
|
||||
int probe_gus_db16(struct address_info *hw_config);
|
||||
|
||||
/* From gus_wave.c */
|
||||
int gus_wave_detect(int baseaddr);
|
||||
void gus_wave_init(struct address_info *hw_config);
|
||||
void gus_voice_irq(void);
|
||||
u_char gus_read8 (int reg);
|
||||
void gus_write8(int reg, u_int data);
|
||||
void guswave_dma_irq(void);
|
||||
void gus_delay(void);
|
||||
int gus_default_mixer_ioctl (int dev, u_int cmd, ioctl_arg arg);
|
||||
void gus_timer_command (u_int addr, u_int val);
|
||||
|
||||
/* From gus_midi.c */
|
||||
void gus_midi_init(void);
|
||||
void gus_midi_interrupt(int dummy);
|
||||
|
||||
/* From mpu401.c */
|
||||
void attach_mpu401(struct address_info * hw_config);
|
||||
int probe_mpu401(struct address_info *hw_config);
|
||||
ointhand2_t mpuintr;
|
||||
|
||||
/* From uart6850.c */
|
||||
void attach_uart6850(struct address_info * hw_config);
|
||||
ointhand2_t m6850intr;
|
||||
int probe_uart6850(struct address_info *hw_config);
|
||||
|
||||
/* From opl3.c */
|
||||
void enable_opl3_mode(int left, int right, int both);
|
||||
|
||||
/* From patmgr.c */
|
||||
int pmgr_open(int dev);
|
||||
void pmgr_release(int dev);
|
||||
int pmgr_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count);
|
||||
int pmgr_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count);
|
||||
int pmgr_access(int dev, struct patmgr_info *rec);
|
||||
int pmgr_inform(int dev, int event, u_long parm1, u_long parm2,
|
||||
u_long parm3, u_long parm4);
|
||||
|
||||
/* From ics2101.c */
|
||||
void ics2101_mixer_init(void);
|
||||
|
||||
/* From sound_timer.c */
|
||||
void sound_timer_interrupt(void);
|
||||
void sound_timer_syncinterval(u_int new_usecs);
|
||||
|
||||
/* From ad1848.c */
|
||||
void ad1848_init (char *name, int io_base, int irq, int dma_playback, int dma_capture, int share_dma, sound_os_info *osp);
|
||||
ointhand2_t adintr;
|
||||
|
||||
int ad1848_detect (int io_base, int *flags, sound_os_info *osp);
|
||||
#define AD_F_CS4231 0x0001 /* Returned if a CS4232 (or compatible) detected */
|
||||
#define AD_F_CS4248 0x0001 /* Returned if a CS4248 (or compatible) detected */
|
||||
|
||||
void ad1848_interrupt (int irq);
|
||||
void attach_mss(struct address_info * hw_config);
|
||||
int probe_mss(struct address_info *hw_config);
|
||||
void attach_pnp_ad1848(struct address_info * hw_config);
|
||||
int probe_pnp_ad1848(struct address_info *hw_config);
|
||||
|
||||
/* From pss.c */
|
||||
int probe_pss (struct address_info *hw_config);
|
||||
void attach_pss (struct address_info *hw_config);
|
||||
int probe_pss_mpu (struct address_info *hw_config);
|
||||
void attach_pss_mpu (struct address_info *hw_config);
|
||||
int probe_pss_mss (struct address_info *hw_config);
|
||||
void attach_pss_mss (struct address_info *hw_config);
|
||||
|
||||
/* From sscape.c */
|
||||
int probe_sscape (struct address_info *hw_config);
|
||||
void attach_sscape (struct address_info *hw_config);
|
||||
int probe_ss_mss(struct address_info *hw_config);
|
||||
void attach_ss_mss(struct address_info * hw_config);
|
||||
ointhand2_t sscapeintr;
|
||||
|
||||
int pss_read (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
|
||||
int pss_write (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
|
||||
int pss_open (int dev, struct fileinfo *file);
|
||||
void pss_release (int dev, struct fileinfo *file);
|
||||
int pss_ioctl (int dev, struct fileinfo *file,
|
||||
u_int cmd, ioctl_arg arg);
|
||||
int pss_lseek (int dev, struct fileinfo *file, off_t offset, int orig);
|
||||
void pss_init(void);
|
||||
|
||||
/* From aedsp16.c */
|
||||
int InitAEDSP16_SBPRO(struct address_info *hw_config);
|
||||
int InitAEDSP16_MSS(struct address_info *hw_config);
|
||||
int InitAEDSP16_MPU401(struct address_info *hw_config);
|
||||
|
||||
/* From midi_synth.c */
|
||||
void do_midi_msg (int synthno, u_char *msg, int mlen);
|
||||
|
||||
/* From trix.c */
|
||||
void attach_trix_wss (struct address_info *hw_config);
|
||||
int probe_trix_wss (struct address_info *hw_config);
|
||||
void attach_trix_sb (struct address_info *hw_config);
|
||||
int probe_trix_sb (struct address_info *hw_config);
|
||||
void attach_trix_mpu (struct address_info *hw_config);
|
||||
int probe_trix_mpu (struct address_info *hw_config);
|
||||
|
||||
/* From mad16.c */
|
||||
void attach_mad16 (struct address_info *hw_config);
|
||||
int probe_mad16 (struct address_info *hw_config);
|
||||
void attach_mad16_mpu (struct address_info *hw_config);
|
||||
int probe_mad16_mpu (struct address_info *hw_config);
|
||||
int mad16_sb_dsp_detect (struct address_info *hw_config);
|
||||
void mad16_sb_dsp_init (struct address_info *hw_config);
|
||||
|
||||
/* From cs4232.c */
|
||||
|
||||
int probe_cs4232 (struct address_info *hw_config);
|
||||
void attach_cs4232 (struct address_info *hw_config);
|
||||
int probe_cs4232_mpu (struct address_info *hw_config);
|
||||
void attach_cs4232_mpu (struct address_info *hw_config);
|
||||
|
||||
/* From maui.c */
|
||||
void attach_maui(struct address_info * hw_config);
|
||||
int probe_maui(struct address_info *hw_config);
|
||||
|
||||
/* From sound_pnp.c */
|
||||
void sound_pnp_init(void);
|
||||
void sound_pnp_disconnect(void);
|
||||
|
||||
/* From pcm86.c */
|
||||
void attach_nss(struct address_info * hw_config);
|
||||
int probe_nss(struct address_info *hw_config);
|
||||
ointhand2_t nssintr;
|
@ -1,211 +0,0 @@
|
||||
/* sound_config.h
|
||||
*
|
||||
* A driver for Soundcards, misc configuration parameters.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1995
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* many variables should be reduced to a range. Here define a macro
|
||||
*/
|
||||
|
||||
#define RANGE(var, low, high) (var) = \
|
||||
((var)<(low)?(low) : (var)>(high)?(high) : (var))
|
||||
|
||||
#undef CONFIGURE_SOUNDCARD
|
||||
#undef DYNAMIC_BUFFER
|
||||
|
||||
#include <i386/isa/sound/local.h>
|
||||
|
||||
#define CONFIGURE_SOUNDCARD
|
||||
#define DYNAMIC_BUFFER
|
||||
#undef LOADABLE_SOUNDCARD
|
||||
|
||||
#include <i386/isa/sound/os.h>
|
||||
#include <i386/isa/sound/soundvers.h>
|
||||
|
||||
#if defined(ISC) || defined(SCO) || defined(SVR42)
|
||||
#define GENERIC_SYSV
|
||||
#endif
|
||||
|
||||
#ifndef SND_DEFAULT_ENABLE
|
||||
#define SND_DEFAULT_ENABLE 1
|
||||
#endif
|
||||
|
||||
#ifdef CONFIGURE_SOUNDCARD
|
||||
|
||||
#ifndef MAX_REALTIME_FACTOR
|
||||
#define MAX_REALTIME_FACTOR 4
|
||||
#endif
|
||||
|
||||
/************* PCM DMA buffer sizes *******************/
|
||||
|
||||
/* If you are using high playback or recording speeds, the default buffersize
|
||||
is too small. DSP_BUFFSIZE must be 64k or less.
|
||||
|
||||
A rule of thumb is 64k for PAS16, 32k for PAS+, 16k for SB Pro and
|
||||
4k for SB.
|
||||
|
||||
If you change the DSP_BUFFSIZE, don't modify this file.
|
||||
Use the make config command instead. Seems to allow only 4K, 16K,
|
||||
32K, 64K.
|
||||
*/
|
||||
|
||||
#ifndef DSP_BUFFSIZE
|
||||
#define DSP_BUFFSIZE (32760)
|
||||
#endif
|
||||
|
||||
#ifndef DSP_BUFFCOUNT
|
||||
#define DSP_BUFFCOUNT 1 /* 1 is recommended. */
|
||||
#endif
|
||||
|
||||
#define DMA_AUTOINIT 0x10 /* XXX never used */
|
||||
|
||||
#ifdef PC98
|
||||
#define FM_MONO 0x28d2
|
||||
#else
|
||||
#define FM_MONO 0x388 /* This is the I/O address used by AdLib */
|
||||
#endif
|
||||
|
||||
#ifndef AWE32_BASE
|
||||
#define AWE32_BASE 0x620 /* Default = 0x620-3, 0xA20-3, 0xE20-3 */
|
||||
#endif
|
||||
|
||||
#ifndef PAS_BASE
|
||||
#define PAS_BASE 0x388
|
||||
#endif
|
||||
|
||||
#ifdef JAZZ16
|
||||
#ifndef JAZZ_DMA16
|
||||
#define JAZZ_DMA16 5
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* SEQ_MAX_QUEUE is the maximum number of sequencer events buffered by the
|
||||
driver. (There is no need to alter this) */
|
||||
#define SEQ_MAX_QUEUE 1024
|
||||
|
||||
#define SBFM_MAXINSTR (256) /* Size of the FM Instrument bank */
|
||||
/* 128 instruments for general MIDI setup and 16 unassigned */
|
||||
|
||||
/*
|
||||
* Minor numbers for the sound driver.
|
||||
*
|
||||
* Unfortunately Creative called the codec chip of SB as a DSP. For this
|
||||
* reason the /dev/dsp is reserved for digitized audio use. There is a
|
||||
* device for true DSP processors but it will be called something else.
|
||||
* In v3.0 it's /dev/sndproc but this could be a temporary solution.
|
||||
*/
|
||||
|
||||
#define SND_NDEVS 256 /* Number of supported devices */
|
||||
|
||||
#define SND_DEV_CTL 0 /* Control port /dev/mixer */
|
||||
#define SND_DEV_SEQ 1 /* Sequencer output /dev/sequencer (FM
|
||||
synthesizer and MIDI output) */
|
||||
#define SND_DEV_MIDIN 2 /* Raw midi access */
|
||||
#define SND_DEV_DSP 3 /* Digitized voice /dev/dsp */
|
||||
#define SND_DEV_AUDIO 4 /* Sparc compatible /dev/audio */
|
||||
#define SND_DEV_DSP16 5 /* Like /dev/dsp but 16 bits/sample */
|
||||
#define SND_DEV_STATUS 6 /* /dev/sndstat */
|
||||
/* #7 not in use now. Was in 2.4. Free for use after v3.0. */
|
||||
#define SND_DEV_SEQ2 8 /* /dev/sequencer, level 2 interface */
|
||||
#define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */
|
||||
#define SND_DEV_PSS SND_DEV_SNDPROC
|
||||
|
||||
#define DSP_DEFAULT_SPEED 8000
|
||||
|
||||
#define ON 1
|
||||
#define OFF 0
|
||||
|
||||
#define MAX_AUDIO_DEV 5
|
||||
#define MAX_MIXER_DEV 5
|
||||
#define MAX_SYNTH_DEV 3
|
||||
#define MAX_MIDI_DEV 6
|
||||
#define MAX_TIMER_DEV 3
|
||||
|
||||
struct fileinfo {
|
||||
int mode; /* Open mode */
|
||||
int flags;
|
||||
int dummy; /* Reference to file-flags. OS-dependent. */
|
||||
};
|
||||
|
||||
struct address_info {
|
||||
int io_base;
|
||||
int irq;
|
||||
int dma;
|
||||
int dma2;
|
||||
int always_detect; /* 1=Trust me, it's there */
|
||||
char *name;
|
||||
sound_os_info *osp; /* OS specific info */
|
||||
int card_subtype; /* Driver specific. Usually 0 */
|
||||
};
|
||||
|
||||
#define SYNTH_MAX_VOICES 32
|
||||
|
||||
struct voice_alloc_info {
|
||||
int max_voice;
|
||||
int used_voices;
|
||||
int ptr; /* For device specific use */
|
||||
unsigned short map[SYNTH_MAX_VOICES]; /* (ch << 8) | (note+1) */
|
||||
int timestamp;
|
||||
int alloc_times[SYNTH_MAX_VOICES];
|
||||
};
|
||||
|
||||
struct channel_info {
|
||||
int pgm_num;
|
||||
int bender_value;
|
||||
unsigned char controllers[128];
|
||||
};
|
||||
|
||||
/*
|
||||
* Process wakeup reasons
|
||||
*/
|
||||
#define WK_NONE 0x00
|
||||
#define WK_WAKEUP 0x01
|
||||
#define WK_TIMEOUT 0x02
|
||||
#define WK_SIGNAL 0x04
|
||||
#define WK_SLEEP 0x08
|
||||
|
||||
#define OPEN_READ PCM_ENABLE_INPUT
|
||||
#define OPEN_WRITE PCM_ENABLE_OUTPUT
|
||||
#define OPEN_READWRITE (OPEN_READ|OPEN_WRITE)
|
||||
|
||||
#include <i386/isa/sound/sound_calls.h>
|
||||
#include <i386/isa/sound/dev_table.h>
|
||||
|
||||
#ifndef DEB
|
||||
#define DEB(x)
|
||||
#endif
|
||||
#ifndef DDB
|
||||
/* #define DDB(x) x XXX */
|
||||
#define DDB(x)
|
||||
#endif
|
||||
|
||||
#define TIMER_ARMED 121234
|
||||
#define TIMER_NOT_ARMED 1
|
||||
|
||||
#endif
|
@ -1,186 +0,0 @@
|
||||
/*
|
||||
* sound/sound_pnp.c
|
||||
*
|
||||
* PnP soundcard support (Linux spesific)
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1995
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
/*
|
||||
* XXX check what to use in place of CONFIG_PNP
|
||||
*/
|
||||
#if (NSND > 0) && defined(CONFIG_PNP)
|
||||
|
||||
#include <linux/pnp.h>
|
||||
|
||||
static struct pnp_sounddev *pnp_devs[20] = { NULL };
|
||||
|
||||
static int max_pnpdevs = 20;
|
||||
static int nr_pnpdevs = 0;
|
||||
static int pnp_sig = 0;
|
||||
|
||||
void
|
||||
install_pnp_sounddrv(struct pnp_sounddev * drv)
|
||||
{
|
||||
if (nr_pnpdevs < max_pnpdevs) {
|
||||
pnp_devs[nr_pnpdevs++] = drv;
|
||||
} else
|
||||
printf("Sound: More than 20 PnP drivers defined\n");
|
||||
}
|
||||
|
||||
void
|
||||
cs4232_pnp(void *parm)
|
||||
{
|
||||
struct pnp_dev *dev = (struct pnp_dev *) parm;
|
||||
char *name;
|
||||
|
||||
int portmask = 0x00, irqmask = 0x01, dmamask = 0x03;
|
||||
int opl3_driver, wss_driver;
|
||||
|
||||
printf("CS4232 driver waking up\n");
|
||||
|
||||
if (dev->card && dev->card->name)
|
||||
name = dev->card->name;
|
||||
else
|
||||
name = "PnP WSS";
|
||||
|
||||
if ((wss_driver = sndtable_identify_card("AD1848")))
|
||||
portmask |= 0x01; /* MSS */
|
||||
else
|
||||
printf("Sound: MSS/WSS device detected but no driver enabled\n");
|
||||
|
||||
if ((opl3_driver = sndtable_identify_card("OPL3")))
|
||||
portmask |= 0x02; /* OPL3 */
|
||||
else
|
||||
printf("Sound: OPL3/4 device detected but no driver enabled\n");
|
||||
|
||||
printf("WSS driver %d, OPL3 driver %d\n", wss_driver, opl3_driver);
|
||||
|
||||
if (!portmask) /* No drivers available */
|
||||
return;
|
||||
|
||||
if (!pnp_allocate_device(pnp_sig, dev, portmask, irqmask, dmamask, 0x00))
|
||||
printf("Device activation failed\n");
|
||||
else {
|
||||
struct address_info hw_config;
|
||||
int wss_base, opl3_base;
|
||||
int irq;
|
||||
int dma1, dma2;
|
||||
|
||||
printf("Device activation OK\n");
|
||||
wss_base = pnp_get_port(dev, 0);
|
||||
opl3_base = pnp_get_port(dev, 1);
|
||||
irq = pnp_get_irq(dev, 0);
|
||||
dma1 = pnp_get_dma(dev, 0);
|
||||
dma2 = pnp_get_dma(dev, 1);
|
||||
|
||||
printf("I/O0 %03x\n", wss_base);
|
||||
printf("I/O1 %03x\n", opl3_base);
|
||||
printf("IRQ %d\n", irq);
|
||||
printf("DMA0 %d\n", dma1);
|
||||
printf("DMA1 %d\n", dma2);
|
||||
|
||||
if (opl3_base && opl3_driver) {
|
||||
hw_config.io_base = opl3_base;
|
||||
hw_config.irq = 0;
|
||||
hw_config.dma = -1;
|
||||
hw_config.dma2 = -1;
|
||||
hw_config.always_detect = 0;
|
||||
hw_config.name = "";
|
||||
hw_config.osp = NULL;
|
||||
hw_config.card_subtype = 0;
|
||||
|
||||
if (sndtable_probe(opl3_driver, &hw_config))
|
||||
sndtable_init_card(opl3_driver, &hw_config);
|
||||
|
||||
}
|
||||
if (wss_base && wss_driver) {
|
||||
hw_config.io_base = wss_base;
|
||||
hw_config.irq = irq;
|
||||
hw_config.dma = dma1;
|
||||
hw_config.dma2 = (dma2 == NO_DMA) ? dma1 : dma2;
|
||||
hw_config.always_detect = 0;
|
||||
hw_config.name = name;
|
||||
hw_config.osp = NULL;
|
||||
hw_config.card_subtype = 0;
|
||||
|
||||
if (sndtable_probe(wss_driver, &hw_config))
|
||||
sndtable_init_card(wss_driver, &hw_config);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
pnp_activate(int id, struct pnp_dev * dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nr_pnpdevs; i++)
|
||||
if (pnp_devs[i]->id == id) {
|
||||
|
||||
printf("PnP dev: %08x, %s\n", id, pnp_devid2asc(id));
|
||||
|
||||
pnp_devs[i]->setup((void *) dev);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
sound_pnp_init(void)
|
||||
{
|
||||
static struct pnp_sounddev cs4232_dev =
|
||||
{PNP_DEVID('C', 'S', 'C', 0x0000), cs4232_pnp, "CS4232"};
|
||||
|
||||
struct pnp_dev *dev;
|
||||
|
||||
install_pnp_sounddrv(&cs4232_dev);
|
||||
|
||||
dev = NULL;
|
||||
|
||||
if ((pnp_sig = pnp_connect("sound")) == -1) {
|
||||
printf("Sound: Can't connect to kernel PnP services.\n");
|
||||
return;
|
||||
}
|
||||
while ((dev = pnp_get_next_device(pnp_sig, dev)) != NULL) {
|
||||
if (!pnp_activate(dev->key, dev)) {
|
||||
/* Scan all compatible devices */
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dev->ncompat; i++)
|
||||
if (pnp_activate(dev->compat_keys[i], dev))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sound_pnp_disconnect(void)
|
||||
{
|
||||
pnp_disconnect(pnp_sig);
|
||||
}
|
||||
#endif
|
@ -1,499 +0,0 @@
|
||||
/*
|
||||
* sound/sound_switch.c
|
||||
*
|
||||
* The system call switch
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if NSND > 0
|
||||
|
||||
#define SNDSTAT_BUF_SIZE 4000
|
||||
|
||||
/*
|
||||
* /dev/sndstatus -device
|
||||
*/
|
||||
static char *status_buf = NULL;
|
||||
static int status_len, status_ptr;
|
||||
static int status_busy = 0;
|
||||
|
||||
static int
|
||||
put_status(char *s)
|
||||
{
|
||||
int l = strlen(s);
|
||||
|
||||
if (status_len + l >= SNDSTAT_BUF_SIZE)
|
||||
return 0;
|
||||
|
||||
bcopy(s, &status_buf[status_len], l);
|
||||
status_len += l;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* in principle, we never overflow the buffer. But... if radix=2 ...
|
||||
* and if smaller... lr970711
|
||||
*/
|
||||
|
||||
static int
|
||||
put_status_int(u_int val, int radix)
|
||||
{
|
||||
int l, v;
|
||||
static char hx[] = "0123456789abcdef";
|
||||
char buf[33]; /* int is 32 bit+null, in base 2 */
|
||||
|
||||
if (radix < 2 || radix > 16) /* better than panic */
|
||||
return put_status("???");
|
||||
|
||||
if (!val)
|
||||
return put_status("0");
|
||||
|
||||
l = 0;
|
||||
buf[10] = 0;
|
||||
|
||||
while (val) {
|
||||
v = val % radix;
|
||||
val = val / radix;
|
||||
|
||||
buf[9 - l] = hx[v];
|
||||
l++;
|
||||
}
|
||||
|
||||
if (status_len + l >= SNDSTAT_BUF_SIZE)
|
||||
return 0;
|
||||
|
||||
bcopy(&buf[10 - l], &status_buf[status_len], l);
|
||||
status_len += l;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
init_status(void)
|
||||
{
|
||||
/*
|
||||
* Write the status information to the status_buf and update
|
||||
* status_len. There is a limit of SNDSTAT_BUF_SIZE bytes for the data.
|
||||
* put_status handles this and returns 0 in case of failure. Since
|
||||
* it never oveflows the buffer, we do not care to check.
|
||||
*/
|
||||
|
||||
int i;
|
||||
|
||||
status_ptr = 0;
|
||||
|
||||
#ifdef SOUND_UNAME_A
|
||||
put_status("VoxWare Sound Driver:" SOUND_VERSION_STRING
|
||||
" (" SOUND_CONFIG_DATE " " SOUND_CONFIG_BY ",\n"
|
||||
SOUND_UNAME_A ")\n");
|
||||
#else
|
||||
put_status("VoxWare Sound Driver:" SOUND_VERSION_STRING
|
||||
" (" SOUND_CONFIG_DATE " " SOUND_CONFIG_BY "@"
|
||||
SOUND_CONFIG_HOST "." SOUND_CONFIG_DOMAIN ")\n");
|
||||
#endif
|
||||
|
||||
put_status("Config options: ") ;
|
||||
/* put_status_int(SELECTED_SOUND_OPTIONS, 16) ; */
|
||||
put_status("\n\nInstalled drivers: \n") ;
|
||||
|
||||
for (i = 0; i < num_sound_drivers; i++)
|
||||
if (sound_drivers[i].card_type != 0) {
|
||||
put_status("Type ") ;
|
||||
put_status_int(sound_drivers[i].card_type, 10);
|
||||
put_status(": ") ;
|
||||
put_status(sound_drivers[i].name) ;
|
||||
put_status("\n") ;
|
||||
}
|
||||
put_status("\n\nCard config: \n") ;
|
||||
|
||||
for (i = 0; i < num_sound_cards; i++)
|
||||
if (snd_installed_cards[i].card_type != 0) {
|
||||
int drv, tmp;
|
||||
|
||||
if (!snd_installed_cards[i].enabled)
|
||||
put_status("(") ;
|
||||
|
||||
if ((drv = snd_find_driver(snd_installed_cards[i].card_type)) != -1)
|
||||
put_status(sound_drivers[drv].name) ;
|
||||
|
||||
put_status(" at 0x") ;
|
||||
put_status_int(snd_installed_cards[i].config.io_base, 16);
|
||||
|
||||
put_status(" irq ") ;
|
||||
tmp = snd_installed_cards[i].config.irq;
|
||||
if (tmp < 0)
|
||||
tmp = -tmp;
|
||||
put_status_int(tmp, 10) ;
|
||||
|
||||
if (snd_installed_cards[i].config.dma != -1) {
|
||||
put_status(" drq ") ;
|
||||
put_status_int(snd_installed_cards[i].config.dma, 10) ;
|
||||
if (snd_installed_cards[i].config.dma2 != -1) {
|
||||
put_status(",") ;
|
||||
put_status_int(snd_installed_cards[i].config.dma2, 10) ;
|
||||
}
|
||||
}
|
||||
if (!snd_installed_cards[i].enabled)
|
||||
put_status(")") ;
|
||||
|
||||
put_status("\n") ;
|
||||
}
|
||||
if (!sound_started) {
|
||||
put_status("\n\n***** Sound driver not started *****\n\n");
|
||||
return;
|
||||
}
|
||||
#ifndef CONFIG_AUDIO
|
||||
put_status("\nAudio devices: NOT ENABLED IN CONFIG\n") ;
|
||||
#else
|
||||
put_status("\nAudio devices:\n") ;
|
||||
|
||||
for (i = 0; i < num_audiodevs; i++) {
|
||||
put_status_int(i, 10) ;
|
||||
put_status(": ") ;
|
||||
put_status(audio_devs[i]->name) ;
|
||||
|
||||
if (audio_devs[i]->flags & DMA_DUPLEX)
|
||||
put_status(" (DUPLEX)") ;
|
||||
|
||||
put_status("\n") ;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SEQUENCER
|
||||
put_status("\nSynth devices: NOT ENABLED IN CONFIG\n");
|
||||
#else
|
||||
put_status("\nSynth devices:\n") ;
|
||||
|
||||
for (i = 0; i < num_synths; i++) {
|
||||
put_status_int(i, 10) ;
|
||||
put_status(": ") ;
|
||||
put_status(synth_devs[i]->info->name) ;
|
||||
put_status("\n") ;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_MIDI
|
||||
put_status("\nMidi devices: NOT ENABLED IN CONFIG\n") ;
|
||||
#else
|
||||
put_status("\nMidi devices:\n") ;
|
||||
|
||||
for (i = 0; i < num_midis; i++) {
|
||||
put_status_int(i, 10) ;
|
||||
put_status(": ") ;
|
||||
put_status(midi_devs[i]->info.name) ;
|
||||
put_status("\n") ;
|
||||
}
|
||||
#endif
|
||||
|
||||
put_status("\nTimers:\n");
|
||||
|
||||
for (i = 0; i < num_sound_timers; i++) {
|
||||
put_status_int(i, 10);
|
||||
put_status(": ");
|
||||
put_status(sound_timer_devs[i]->info.name);
|
||||
put_status("\n");
|
||||
}
|
||||
|
||||
put_status("\nMixers:\n");
|
||||
|
||||
for (i = 0; i < num_mixers; i++) {
|
||||
put_status_int(i, 10);
|
||||
put_status(": ");
|
||||
put_status(mixer_devs[i]->name);
|
||||
put_status("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
read_status(snd_rw_buf * buf, int count)
|
||||
{
|
||||
/*
|
||||
* Return at most 'count' bytes from the status_buf.
|
||||
*/
|
||||
int l, c;
|
||||
|
||||
l = count;
|
||||
c = status_len - status_ptr;
|
||||
|
||||
if (l > c)
|
||||
l = c;
|
||||
if (l <= 0)
|
||||
return 0;
|
||||
|
||||
|
||||
if (uiomove(&status_buf[status_ptr], l, buf)) {
|
||||
printf("sb: Bad copyout()!\n");
|
||||
};
|
||||
status_ptr += l;
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
int
|
||||
sound_read_sw(int dev, struct fileinfo * file, snd_rw_buf * buf, int count)
|
||||
{
|
||||
DEB(printf("sound_read_sw(dev=%d, count=%d)\n", dev, count));
|
||||
|
||||
switch (dev & 0x0f) {
|
||||
case SND_DEV_STATUS:
|
||||
return read_status(buf, count);
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_AUDIO
|
||||
case SND_DEV_DSP:
|
||||
case SND_DEV_DSP16:
|
||||
case SND_DEV_AUDIO:
|
||||
return audio_read(dev, file, buf, count);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SEQUENCER
|
||||
case SND_DEV_SEQ:
|
||||
case SND_DEV_SEQ2:
|
||||
return sequencer_read(dev, file, buf, count);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MIDI
|
||||
case SND_DEV_MIDIN:
|
||||
return MIDIbuf_read(dev, file, buf, count);
|
||||
#endif
|
||||
|
||||
default:
|
||||
printf("Sound: Undefined minor device %d\n", dev);
|
||||
}
|
||||
|
||||
return -(EPERM);
|
||||
}
|
||||
|
||||
int
|
||||
sound_write_sw(int dev, struct fileinfo * file, snd_rw_buf * buf, int count)
|
||||
{
|
||||
|
||||
DEB(printf("sound_write_sw(dev=%d, count=%d)\n", dev, count));
|
||||
|
||||
switch (dev & 0x0f) {
|
||||
|
||||
#ifdef CONFIG_SEQUENCER
|
||||
case SND_DEV_SEQ:
|
||||
case SND_DEV_SEQ2:
|
||||
return sequencer_write(dev, file, buf, count);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AUDIO
|
||||
case SND_DEV_DSP:
|
||||
case SND_DEV_DSP16:
|
||||
case SND_DEV_AUDIO:
|
||||
return audio_write(dev, file, buf, count);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MIDI
|
||||
case SND_DEV_MIDIN:
|
||||
return MIDIbuf_write(dev, file, buf, count);
|
||||
#endif
|
||||
|
||||
default:
|
||||
return -(EPERM);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int
|
||||
sound_open_sw(int dev, struct fileinfo * file)
|
||||
{
|
||||
int retval;
|
||||
|
||||
DEB(printf("sound_open_sw(dev=%d)\n", dev));
|
||||
|
||||
if ((dev >= SND_NDEVS) || (dev < 0)) {
|
||||
printf("Invalid minor device %d\n", dev);
|
||||
return -(ENXIO);
|
||||
}
|
||||
switch (dev & 0x0f) {
|
||||
case SND_DEV_STATUS:
|
||||
if (status_busy)
|
||||
return -(EBUSY);
|
||||
status_busy = 1;
|
||||
if ((status_buf = (char *) malloc(SNDSTAT_BUF_SIZE, M_TEMP, M_WAITOK)) == NULL)
|
||||
return -(EIO);
|
||||
status_len = status_ptr = 0;
|
||||
init_status();
|
||||
break;
|
||||
|
||||
case SND_DEV_CTL:
|
||||
return 0;
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_SEQUENCER
|
||||
case SND_DEV_SEQ:
|
||||
case SND_DEV_SEQ2:
|
||||
if ((retval = sequencer_open(dev, file)) < 0)
|
||||
return retval;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MIDI
|
||||
case SND_DEV_MIDIN:
|
||||
if ((retval = MIDIbuf_open(dev, file)) < 0)
|
||||
return retval;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AUDIO
|
||||
case SND_DEV_DSP:
|
||||
case SND_DEV_DSP16:
|
||||
case SND_DEV_AUDIO:
|
||||
if ((retval = audio_open(dev, file)) < 0)
|
||||
return retval;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
printf("Invalid minor device %d\n", dev);
|
||||
return -(ENXIO);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
sound_release_sw(int dev, struct fileinfo * file)
|
||||
{
|
||||
|
||||
DEB(printf("sound_release_sw(dev=%d)\n", dev));
|
||||
|
||||
switch (dev & 0x0f) {
|
||||
case SND_DEV_STATUS:
|
||||
if (status_buf)
|
||||
free(status_buf, M_TEMP);
|
||||
status_buf = NULL;
|
||||
status_busy = 0;
|
||||
break;
|
||||
|
||||
case SND_DEV_CTL:
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_SEQUENCER
|
||||
case SND_DEV_SEQ:
|
||||
case SND_DEV_SEQ2:
|
||||
sequencer_release(dev, file);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MIDI
|
||||
case SND_DEV_MIDIN:
|
||||
MIDIbuf_release(dev, file);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AUDIO
|
||||
case SND_DEV_DSP:
|
||||
case SND_DEV_DSP16:
|
||||
case SND_DEV_AUDIO:
|
||||
audio_release(dev, file);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
printf("Sound error: Releasing unknown device 0x%02x\n", dev);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
sound_ioctl_sw(int dev, struct fileinfo * file, u_int cmd, ioctl_arg arg)
|
||||
{
|
||||
DEB(printf("sound_ioctl_sw(dev=%d, cmd=0x%x, arg=0x%x)\n", dev, cmd, arg));
|
||||
|
||||
if (((cmd >> 8) & 0xff) == 'M' && num_mixers > 0) /* Mixer ioctl */
|
||||
if ((dev & 0x0f) != SND_DEV_CTL) {
|
||||
int dtype = dev & 0x0f;
|
||||
int mixdev;
|
||||
|
||||
switch (dtype) {
|
||||
#ifdef CONFIG_AUDIO
|
||||
case SND_DEV_DSP:
|
||||
case SND_DEV_DSP16:
|
||||
case SND_DEV_AUDIO:
|
||||
mixdev = audio_devs[dev >> 4]->mixer_dev;
|
||||
if (mixdev < 0 || mixdev >= num_mixers)
|
||||
return -(ENXIO);
|
||||
return mixer_devs[mixdev]->ioctl(mixdev, cmd, arg);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return mixer_devs[0]->ioctl(0, cmd, arg);
|
||||
}
|
||||
}
|
||||
switch (dev & 0x0f) {
|
||||
|
||||
case SND_DEV_CTL:
|
||||
|
||||
if (!num_mixers)
|
||||
return -(ENXIO);
|
||||
|
||||
dev = dev >> 4;
|
||||
|
||||
if (dev >= num_mixers)
|
||||
return -(ENXIO);
|
||||
|
||||
return mixer_devs[dev]->ioctl(dev, cmd, arg);
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_SEQUENCER
|
||||
case SND_DEV_SEQ:
|
||||
case SND_DEV_SEQ2:
|
||||
return sequencer_ioctl(dev, file, cmd, arg);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AUDIO
|
||||
case SND_DEV_DSP:
|
||||
case SND_DEV_DSP16:
|
||||
case SND_DEV_AUDIO:
|
||||
return audio_ioctl(dev, file, cmd, arg);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MIDI
|
||||
case SND_DEV_MIDIN:
|
||||
return MIDIbuf_ioctl(dev, file, cmd, arg);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return -(EPERM);
|
||||
break;
|
||||
}
|
||||
|
||||
return -(EPERM);
|
||||
}
|
||||
|
||||
#endif
|
@ -1,344 +0,0 @@
|
||||
/*
|
||||
* sound/sound_timer.c
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#define SEQUENCER_C
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if NSND > 0
|
||||
|
||||
#if defined(CONFIG_SEQUENCER)
|
||||
|
||||
static volatile int initialized = 0, opened = 0, tmr_running = 0;
|
||||
static volatile time_t tmr_offs, tmr_ctr;
|
||||
static volatile u_long ticks_offs;
|
||||
static volatile int curr_tempo, curr_timebase;
|
||||
static volatile u_long curr_ticks;
|
||||
static volatile u_long next_event_time;
|
||||
static u_long prev_event_time;
|
||||
static volatile u_long usecs_per_tmr; /* Length of the current interval */
|
||||
|
||||
static struct sound_lowlev_timer *tmr = NULL;
|
||||
|
||||
static u_long
|
||||
tmr2ticks(int tmr_value)
|
||||
{
|
||||
/*
|
||||
* Convert timer ticks to MIDI ticks
|
||||
*/
|
||||
|
||||
u_long tmp;
|
||||
u_long scale;
|
||||
|
||||
tmp = tmr_value * usecs_per_tmr; /* Convert to usecs */
|
||||
|
||||
scale = (60 * 1000000) / (curr_tempo * curr_timebase); /* usecs per MIDI tick */
|
||||
|
||||
return (tmp + (scale / 2)) / scale;
|
||||
}
|
||||
|
||||
static void
|
||||
reprogram_timer(void)
|
||||
{
|
||||
u_long usecs_per_tick;
|
||||
|
||||
usecs_per_tick = (60 * 1000000) / (curr_tempo * curr_timebase);
|
||||
|
||||
/*
|
||||
* Don't kill the system by setting too high timer rate
|
||||
*/
|
||||
if (usecs_per_tick < 2000)
|
||||
usecs_per_tick = 2000;
|
||||
|
||||
usecs_per_tmr = tmr->tmr_start(tmr->dev, usecs_per_tick);
|
||||
}
|
||||
|
||||
void
|
||||
sound_timer_syncinterval(u_int new_usecs)
|
||||
{
|
||||
/*
|
||||
* This routine is called by the hardware level if the clock
|
||||
* frequency has changed for some reason.
|
||||
*/
|
||||
tmr_offs = tmr_ctr;
|
||||
ticks_offs += tmr2ticks(tmr_ctr);
|
||||
tmr_ctr = 0;
|
||||
|
||||
usecs_per_tmr = new_usecs;
|
||||
}
|
||||
|
||||
static void
|
||||
tmr_reset(void)
|
||||
{
|
||||
u_long flags;
|
||||
|
||||
flags = splhigh();
|
||||
tmr_offs = 0;
|
||||
ticks_offs = 0;
|
||||
tmr_ctr = 0;
|
||||
next_event_time = 0xffffffff;
|
||||
prev_event_time = 0;
|
||||
curr_ticks = 0;
|
||||
splx(flags);
|
||||
}
|
||||
|
||||
static int
|
||||
timer_open(int dev, int mode)
|
||||
{
|
||||
if (opened)
|
||||
return -(EBUSY);
|
||||
|
||||
tmr_reset();
|
||||
curr_tempo = 60;
|
||||
curr_timebase = hz;
|
||||
opened = 1;
|
||||
reprogram_timer();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
timer_close(int dev)
|
||||
{
|
||||
opened = tmr_running = 0;
|
||||
tmr->tmr_disable(tmr->dev);
|
||||
}
|
||||
|
||||
static int
|
||||
timer_event(int dev, u_char *event)
|
||||
{
|
||||
u_char cmd = event[1];
|
||||
u_long parm = *(int *) &event[4];
|
||||
|
||||
switch (cmd) {
|
||||
case TMR_WAIT_REL:
|
||||
parm += prev_event_time;
|
||||
case TMR_WAIT_ABS:
|
||||
if (parm > 0) {
|
||||
long time;
|
||||
|
||||
if (parm <= curr_ticks) /* It's the time */
|
||||
return TIMER_NOT_ARMED;
|
||||
|
||||
time = parm;
|
||||
next_event_time = prev_event_time = time;
|
||||
|
||||
return TIMER_ARMED;
|
||||
}
|
||||
break;
|
||||
|
||||
case TMR_START:
|
||||
tmr_reset();
|
||||
tmr_running = 1;
|
||||
reprogram_timer();
|
||||
break;
|
||||
|
||||
case TMR_STOP:
|
||||
tmr_running = 0;
|
||||
break;
|
||||
|
||||
case TMR_CONTINUE:
|
||||
tmr_running = 1;
|
||||
reprogram_timer();
|
||||
break;
|
||||
|
||||
case TMR_TEMPO:
|
||||
if (parm) {
|
||||
if (parm < 8)
|
||||
parm = 8;
|
||||
if (parm > 250)
|
||||
parm = 250;
|
||||
tmr_offs = tmr_ctr;
|
||||
ticks_offs += tmr2ticks(tmr_ctr);
|
||||
tmr_ctr = 0;
|
||||
curr_tempo = parm;
|
||||
reprogram_timer();
|
||||
}
|
||||
break;
|
||||
|
||||
case TMR_ECHO:
|
||||
seq_copy_to_input(event, 8);
|
||||
break;
|
||||
|
||||
default:;
|
||||
}
|
||||
|
||||
return TIMER_NOT_ARMED;
|
||||
}
|
||||
|
||||
static u_long
|
||||
timer_get_time(int dev)
|
||||
{
|
||||
if (!opened)
|
||||
return 0;
|
||||
|
||||
return curr_ticks;
|
||||
}
|
||||
|
||||
static int
|
||||
timer_ioctl(int dev, u_int cmd, ioctl_arg arg)
|
||||
{
|
||||
switch (cmd) {
|
||||
case SNDCTL_TMR_SOURCE:
|
||||
return *(int *) arg = TMR_INTERNAL;
|
||||
break;
|
||||
|
||||
case SNDCTL_TMR_START:
|
||||
tmr_reset();
|
||||
tmr_running = 1;
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SNDCTL_TMR_STOP:
|
||||
tmr_running = 0;
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SNDCTL_TMR_CONTINUE:
|
||||
tmr_running = 1;
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SNDCTL_TMR_TIMEBASE:
|
||||
{
|
||||
int val = (*(int *) arg);
|
||||
|
||||
if (val) {
|
||||
if (val < 1)
|
||||
val = 1;
|
||||
if (val > 1000)
|
||||
val = 1000;
|
||||
curr_timebase = val;
|
||||
}
|
||||
return *(int *) arg = curr_timebase;
|
||||
}
|
||||
break;
|
||||
|
||||
case SNDCTL_TMR_TEMPO:
|
||||
{
|
||||
int val = (*(int *) arg);
|
||||
|
||||
if (val) {
|
||||
if (val < 8)
|
||||
val = 8;
|
||||
if (val > 250)
|
||||
val = 250;
|
||||
tmr_offs = tmr_ctr;
|
||||
ticks_offs += tmr2ticks(tmr_ctr);
|
||||
tmr_ctr = 0;
|
||||
curr_tempo = val;
|
||||
reprogram_timer();
|
||||
}
|
||||
return *(int *) arg = curr_tempo;
|
||||
}
|
||||
break;
|
||||
|
||||
case SNDCTL_SEQ_CTRLRATE:
|
||||
if ((*(int *) arg) != 0) /* Can't change */
|
||||
return -(EINVAL);
|
||||
|
||||
return *(int *) arg = ((curr_tempo * curr_timebase) + 30) / 60;
|
||||
break;
|
||||
|
||||
case SNDCTL_TMR_METRONOME:
|
||||
/* NOP */
|
||||
break;
|
||||
|
||||
default:;
|
||||
}
|
||||
|
||||
return -(EINVAL);
|
||||
}
|
||||
|
||||
static void
|
||||
timer_arm(int dev, long time)
|
||||
{
|
||||
if (time < 0)
|
||||
time = curr_ticks + 1;
|
||||
else if (time <= curr_ticks) /* It's the time */
|
||||
return;
|
||||
|
||||
next_event_time = prev_event_time = time;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static struct sound_timer_operations sound_timer =
|
||||
{
|
||||
{"GUS Timer", 0},
|
||||
1, /* Priority */
|
||||
0, /* Local device link */
|
||||
timer_open,
|
||||
timer_close,
|
||||
timer_event,
|
||||
timer_get_time,
|
||||
timer_ioctl,
|
||||
timer_arm
|
||||
};
|
||||
|
||||
void
|
||||
sound_timer_interrupt(void)
|
||||
{
|
||||
if (!opened)
|
||||
return;
|
||||
|
||||
tmr->tmr_restart(tmr->dev);
|
||||
|
||||
if (!tmr_running)
|
||||
return;
|
||||
|
||||
tmr_ctr++;
|
||||
curr_ticks = ticks_offs + tmr2ticks(tmr_ctr);
|
||||
|
||||
if (curr_ticks >= next_event_time) {
|
||||
next_event_time = 0xffffffff;
|
||||
sequencer_timer(0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sound_timer_init(struct sound_lowlev_timer * t, char *name)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (initialized || t == NULL)
|
||||
return; /* There is already a similar timer */
|
||||
|
||||
initialized = 1;
|
||||
tmr = t;
|
||||
|
||||
if (num_sound_timers >= MAX_TIMER_DEV)
|
||||
n = 0; /* Overwrite the system timer */
|
||||
else
|
||||
n = num_sound_timers++;
|
||||
|
||||
snprintf(sound_timer.info.name, sizeof(sound_timer.info.name), "%s", name);
|
||||
|
||||
sound_timer_devs[n] = &sound_timer;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
@ -1,679 +0,0 @@
|
||||
/*
|
||||
* sound/386bsd/soundcard.c
|
||||
*
|
||||
* Soundcard driver for 386BSD.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
#if NSND > 0 /* from "snd.h" */
|
||||
#include "uart.h"
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <i386/isa/isa_device.h>
|
||||
|
||||
|
||||
/*
|
||||
** Register definitions for DMA controller 1 (channels 0..3):
|
||||
*/
|
||||
#define DMA1_CHN(c) (IO_DMA1 + 1*(2*(c))) /* addr reg for channel c */
|
||||
#define DMA1_SMSK (IO_DMA1 + 1*10) /* single mask register */
|
||||
#define DMA1_MODE (IO_DMA1 + 1*11) /* mode register */
|
||||
#define DMA1_FFC (IO_DMA1 + 1*12) /* clear first/last FF */
|
||||
|
||||
/*
|
||||
** Register definitions for DMA controller 2 (channels 4..7):
|
||||
*/
|
||||
#define DMA2_CHN(c) (IO_DMA2 + 2*(2*(c))) /* addr reg for channel c */
|
||||
#define DMA2_SMSK (IO_DMA2 + 2*10) /* single mask register */
|
||||
#define DMA2_MODE (IO_DMA2 + 2*11) /* mode register */
|
||||
#define DMA2_FFC (IO_DMA2 + 2*12) /* clear first/last FF */
|
||||
|
||||
|
||||
#define FIX_RETURN(ret) {if ((ret)<0) return -(ret); else return 0;}
|
||||
|
||||
static int soundcards_installed = 0; /* Number of installed soundcards */
|
||||
static int soundcard_configured = 0;
|
||||
|
||||
static struct fileinfo files[SND_NDEVS];
|
||||
struct selinfo selinfo[SND_NDEVS >> 4];
|
||||
|
||||
int
|
||||
MIDIbuf_poll (int dev, struct fileinfo *file, int events, select_table * wait);
|
||||
|
||||
int
|
||||
audio_poll(int dev, struct fileinfo * file, int events, select_table * wait);
|
||||
|
||||
int
|
||||
sequencer_poll (int dev, struct fileinfo *file, int events, select_table * wait);
|
||||
|
||||
static int sndprobe __P((struct isa_device *));
|
||||
static int sndattach __P((struct isa_device *));
|
||||
|
||||
static d_open_t sndopen;
|
||||
static d_close_t sndclose;
|
||||
static d_ioctl_t sndioctl;
|
||||
static d_read_t sndread;
|
||||
static d_write_t sndwrite;
|
||||
static d_poll_t sndpoll;
|
||||
static d_mmap_t sndmmap;
|
||||
|
||||
static char driver_name[] = "snd";
|
||||
|
||||
#define CDEV_MAJOR 30
|
||||
static struct cdevsw snd_cdevsw = {
|
||||
/* open */ sndopen,
|
||||
/* close */ sndclose,
|
||||
/* read */ sndread,
|
||||
/* write */ sndwrite,
|
||||
/* ioctl */ sndioctl,
|
||||
/* poll */ sndpoll,
|
||||
/* mmap */ sndmmap,
|
||||
/* strategy */ nostrategy,
|
||||
/* name */ driver_name,
|
||||
/* maj */ CDEV_MAJOR,
|
||||
/* dump */ nodump,
|
||||
/* psize */ nopsize,
|
||||
/* flags */ 0,
|
||||
/* bmaj */ -1
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
static void sound_mem_init(void);
|
||||
|
||||
/*
|
||||
* for each "device XXX" entry in the config file, we have
|
||||
* a struct isa_driver which is linked into isa_devtab_null[]
|
||||
*
|
||||
* XXX It is a bit stupid to call the generic routine so many times and
|
||||
* switch then to the specific one, but the alternative way would be
|
||||
* to replicate some code in the probe/attach routines.
|
||||
*/
|
||||
|
||||
struct isa_driver opldriver = {sndprobe, sndattach, "opl"};
|
||||
struct isa_driver trixdriver = {sndprobe, sndattach, "trix"};
|
||||
struct isa_driver trixsbdriver = {sndprobe, sndattach, "trixsb"};
|
||||
struct isa_driver sbdriver = {sndprobe, sndattach, "sb"};
|
||||
struct isa_driver sbxvidriver = {sndprobe, sndattach, "sbxvi"};
|
||||
struct isa_driver sbmididriver = {sndprobe, sndattach, "sbmidi"};
|
||||
struct isa_driver awedriver = {sndprobe, sndattach, "awe"};
|
||||
struct isa_driver pasdriver = {sndprobe, sndattach, "pas"};
|
||||
struct isa_driver mpudriver = {sndprobe, sndattach, "mpu"};
|
||||
struct isa_driver gusdriver = {sndprobe, sndattach, "gus"};
|
||||
struct isa_driver gusxvidriver = {sndprobe, sndattach, "gusxvi"};
|
||||
struct isa_driver gusmaxdriver = {sndprobe, sndattach, "gusmax"};
|
||||
struct isa_driver uartdriver = {sndprobe, sndattach, "uart"};
|
||||
struct isa_driver mssdriver = {sndprobe, sndattach, "mss"};
|
||||
struct isa_driver cssdriver = {sndprobe, sndattach, "css"};
|
||||
struct isa_driver sscapedriver = {sndprobe, sndattach, "sscape"};
|
||||
struct isa_driver sscape_mssdriver = {sndprobe, sndattach, "sscape_mss"};
|
||||
struct isa_driver nssdriver = {sndprobe, sndattach, "nss"};
|
||||
|
||||
short ipri_to_irq(u_short ipri);
|
||||
|
||||
static ointhand2_t sndintr;
|
||||
|
||||
u_long
|
||||
get_time(void)
|
||||
{
|
||||
struct timeval timecopy;
|
||||
|
||||
getmicrotime(&timecopy);
|
||||
return timecopy.tv_usec / (1000000 / hz) +
|
||||
(u_long) timecopy.tv_sec * hz;
|
||||
}
|
||||
|
||||
static int
|
||||
sndmmap( dev_t dev, vm_offset_t offset, int nprot )
|
||||
{
|
||||
struct dma_buffparms * dmap;
|
||||
u_int min = minor(dev) >> 4;
|
||||
|
||||
if (min > 0 ) return (-1);
|
||||
|
||||
dmap = audio_devs[min]->dmap_out;
|
||||
|
||||
if (nprot & PROT_EXEC)
|
||||
return( -1 );
|
||||
dmap->mapping_flags |= DMA_MAP_MAPPED ;
|
||||
return( i386_btop(vtophys(dmap->raw_buf) + offset) );
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sndread(dev_t dev, struct uio * buf, int flag)
|
||||
{
|
||||
int count = buf->uio_resid;
|
||||
u_int min = minor(dev);
|
||||
|
||||
FIX_RETURN(sound_read_sw(min, &files[min], buf, count));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sndwrite(dev_t dev, struct uio * buf, int flag)
|
||||
{
|
||||
int count = buf->uio_resid;
|
||||
u_int min = minor(dev);
|
||||
|
||||
FIX_RETURN(sound_write_sw(min, &files[min], buf, count));
|
||||
}
|
||||
|
||||
static int
|
||||
sndopen(dev_t dev, int flags, int mode, struct proc * p)
|
||||
{
|
||||
int retval;
|
||||
struct fileinfo tmp_file;
|
||||
u_int min = minor(dev);
|
||||
|
||||
if (!soundcard_configured && min) {
|
||||
printf("SoundCard Error: soundcard system has not been configured\n");
|
||||
return ENODEV ;
|
||||
}
|
||||
tmp_file.mode = 0;
|
||||
|
||||
if (flags & FREAD && flags & FWRITE)
|
||||
tmp_file.mode = OPEN_READWRITE;
|
||||
else if (flags & FREAD)
|
||||
tmp_file.mode = OPEN_READ;
|
||||
else if (flags & FWRITE)
|
||||
tmp_file.mode = OPEN_WRITE;
|
||||
|
||||
selinfo[min >> 4].si_pid = 0;
|
||||
selinfo[min >> 4].si_flags = 0;
|
||||
if ((retval = sound_open_sw(min, &tmp_file)) < 0)
|
||||
FIX_RETURN(retval);
|
||||
|
||||
bcopy((char *) &tmp_file, (char *) &files[min], sizeof(tmp_file));
|
||||
|
||||
FIX_RETURN(retval);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sndclose(dev_t dev, int flags, int mode, struct proc * p)
|
||||
{
|
||||
u_int min = minor(dev);
|
||||
|
||||
sound_release_sw(min, &files[min]);
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
static int
|
||||
sndioctl(dev_t dev, u_long cmd, caddr_t arg, int mode, struct proc * p)
|
||||
{
|
||||
u_int min = minor(dev);
|
||||
FIX_RETURN(sound_ioctl_sw(min, &files[min], cmd, arg));
|
||||
}
|
||||
|
||||
int
|
||||
sndpoll(dev_t dev, int events, struct proc * p)
|
||||
{
|
||||
u_int min = minor(dev);
|
||||
|
||||
/* printf ("snd_select(dev=%d, rw=%d, pid=%d)\n", min, rw, p->p_pid); */
|
||||
#ifdef ALLOW_POLL
|
||||
switch (min & 0x0f) {
|
||||
#ifdef CONFIG_SEQUENCER
|
||||
case SND_DEV_SEQ:
|
||||
case SND_DEV_SEQ2:
|
||||
return sequencer_poll(min, &files[min], events, p);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MIDI
|
||||
case SND_DEV_MIDIN:
|
||||
return MIDIbuf_poll(min, &files[min], events, p);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AUDIO
|
||||
case SND_DEV_DSP:
|
||||
case SND_DEV_DSP16:
|
||||
case SND_DEV_AUDIO:
|
||||
|
||||
return audio_poll(min, &files[min], events, p);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* ALLOW_POLL */
|
||||
DEB(printf("sound_ioctl(min=%d, cmd=0x%x, arg=0x%x)\n", min, cmd, arg));
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/* XXX this should become ffs(ipri), perhaps -1 lr 970705 */
|
||||
short
|
||||
ipri_to_irq(u_short ipri)
|
||||
{
|
||||
/*
|
||||
* Converts the ipri (bitmask) to the corresponding irq number
|
||||
*/
|
||||
int irq;
|
||||
|
||||
for (irq = 0; irq < 16; irq++)
|
||||
if (ipri == (1 << irq))
|
||||
return irq;
|
||||
|
||||
return -1; /* Invalid argument */
|
||||
}
|
||||
|
||||
static int
|
||||
driver_to_voxunit(struct isa_driver * driver)
|
||||
{
|
||||
/*
|
||||
* converts a sound driver pointer into the equivalent VoxWare device
|
||||
* unit number
|
||||
*/
|
||||
if (driver == &opldriver)
|
||||
return (SNDCARD_ADLIB);
|
||||
else if (driver == &sbdriver)
|
||||
return (SNDCARD_SB);
|
||||
else if (driver == &pasdriver)
|
||||
return (SNDCARD_PAS);
|
||||
else if (driver == &gusdriver)
|
||||
return (SNDCARD_GUS);
|
||||
else if (driver == &mpudriver)
|
||||
return (SNDCARD_MPU401);
|
||||
else if (driver == &sbxvidriver)
|
||||
return (SNDCARD_SB16);
|
||||
else if (driver == &sbmididriver)
|
||||
return (SNDCARD_SB16MIDI);
|
||||
else if(driver == &awedriver)
|
||||
return(SNDCARD_AWE32);
|
||||
else if (driver == &uartdriver)
|
||||
return (SNDCARD_UART6850);
|
||||
else if (driver == &gusdriver)
|
||||
return (SNDCARD_GUS16);
|
||||
else if (driver == &mssdriver)
|
||||
return (SNDCARD_MSS);
|
||||
else if (driver == &cssdriver)
|
||||
return (SNDCARD_CS4232);
|
||||
else if (driver == &sscapedriver)
|
||||
return(SNDCARD_SSCAPE);
|
||||
else if (driver == &sscape_mssdriver)
|
||||
return(SNDCARD_SSCAPE_MSS);
|
||||
else if (driver == &trixdriver)
|
||||
return (SNDCARD_TRXPRO);
|
||||
else if (driver == &trixsbdriver)
|
||||
return (SNDCARD_TRXPRO_SB);
|
||||
else if (driver == &nssdriver)
|
||||
return (SNDCARD_NSS);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* very dirty: tmp_osp is allocated in sndprobe, and used at the next
|
||||
* call in sndattach
|
||||
*/
|
||||
|
||||
static sound_os_info *temp_osp;
|
||||
|
||||
/*
|
||||
* sndprobe is called for each isa_device. From here, a voxware unit
|
||||
* number is determined, and the appropriate probe routine is selected.
|
||||
* The parameters from the config line are passed to the hw_config struct.
|
||||
*/
|
||||
|
||||
static int
|
||||
sndprobe(struct isa_device * dev)
|
||||
{
|
||||
struct address_info hw_config;
|
||||
int unit;
|
||||
|
||||
temp_osp = (sound_os_info *)malloc(sizeof(sound_os_info),
|
||||
M_DEVBUF, M_NOWAIT);
|
||||
if (!temp_osp)
|
||||
panic("SOUND: Cannot allocate memory\n");
|
||||
|
||||
/*
|
||||
* get config info from the kernel config. These may be overridden
|
||||
* by the local autoconfiguration routines though (e.g. pnp stuff).
|
||||
*/
|
||||
|
||||
hw_config.io_base = dev->id_iobase;
|
||||
hw_config.irq = ipri_to_irq(dev->id_irq);
|
||||
hw_config.dma = dev->id_drq;
|
||||
|
||||
/*
|
||||
* misuse the flags field for read dma. Note that, to use 0 as
|
||||
* read dma channel, one of the high bits should be set. lr970705 XXX
|
||||
*/
|
||||
|
||||
if (dev->id_flags != 0)
|
||||
hw_config.dma2 = dev->id_flags & 0x7;
|
||||
else
|
||||
hw_config.dma2 = -1;
|
||||
|
||||
hw_config.always_detect = 0;
|
||||
hw_config.name = NULL;
|
||||
hw_config.card_subtype = 0;
|
||||
|
||||
temp_osp->unit = dev->id_unit;
|
||||
hw_config.osp = temp_osp;
|
||||
unit = driver_to_voxunit(dev->id_driver);
|
||||
|
||||
if (sndtable_probe(unit, &hw_config)) {
|
||||
dev->id_iobase = hw_config.io_base;
|
||||
dev->id_irq = hw_config.irq == -1 ? 0 : (1 << hw_config.irq);
|
||||
dev->id_drq = hw_config.dma;
|
||||
|
||||
if (hw_config.dma != hw_config.dma2 && ( hw_config.dma2 != -1))
|
||||
dev->id_flags = hw_config.dma2 | 0x100; /* XXX lr */
|
||||
else
|
||||
dev->id_flags = 0;
|
||||
return TRUE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sndattach(struct isa_device * dev)
|
||||
{
|
||||
int unit;
|
||||
static int midi_initialized = 0;
|
||||
static int seq_initialized = 0;
|
||||
struct address_info hw_config;
|
||||
char *dname;
|
||||
|
||||
/*
|
||||
* Associate interrupt handlers with devices. XXX this may be incomplete.
|
||||
*/
|
||||
dname = dev->id_driver->name;
|
||||
#if defined(CONFIG_AD1848)
|
||||
if (strcmp(dname, "css") == 0 || strcmp(dname, "gusxvi") == 0 ||
|
||||
strcmp(dname, "mss") == 0)
|
||||
dev->id_ointr = adintr;
|
||||
#endif
|
||||
#ifdef CONFIG_GUS
|
||||
if (strcmp(dname, "gus") == 0)
|
||||
dev->id_ointr = gusintr;
|
||||
#endif
|
||||
#ifdef CONFIG_PAS
|
||||
if (strcmp(dname, "pas") == 0)
|
||||
dev->id_ointr = pasintr;
|
||||
#endif
|
||||
#if NSB > 0 && (defined(CONFIG_MIDI) || defined(CONFIG_AUDIO))
|
||||
if (strcmp(dname, "sb") == 0)
|
||||
dev->id_ointr = sbintr;
|
||||
#endif
|
||||
if (strcmp(dname, "sscape_mss") == 0)
|
||||
dev->id_ointr = sndintr;
|
||||
#if NSSCAPE > 0
|
||||
if (strcmp(dname, "sscape") == 0 || strcmp(dname, "trix") == 0)
|
||||
dev->id_ointr = sscapeintr;
|
||||
#endif
|
||||
#if NUART > 0
|
||||
if (strcmp(dname, "uart0") == 0)
|
||||
dev->id_ointr = m6850intr;
|
||||
#endif
|
||||
#if NMPU > 0 && defined(CONFIG_MIDI)
|
||||
if (strcmp(dname, "mpu") == 0)
|
||||
dev->id_ointr = mpuintr;
|
||||
#endif
|
||||
#if NNSS > 0
|
||||
if (strcmp(dname, "nss") == 0)
|
||||
dev->id_ointr = nssintr;
|
||||
#endif
|
||||
|
||||
unit = driver_to_voxunit(dev->id_driver);
|
||||
hw_config.io_base = dev->id_iobase;
|
||||
hw_config.irq = ipri_to_irq(dev->id_irq);
|
||||
hw_config.dma = dev->id_drq;
|
||||
|
||||
/* misuse the flags field for read dma */
|
||||
if (dev->id_flags != 0)
|
||||
hw_config.dma2 = dev->id_flags & 0x7;
|
||||
else
|
||||
hw_config.dma2 = -1;
|
||||
|
||||
hw_config.card_subtype = 0;
|
||||
hw_config.osp = temp_osp;
|
||||
|
||||
if (!unit)
|
||||
return FALSE;
|
||||
|
||||
if (!(sndtable_init_card(unit, &hw_config))) { /* init card */
|
||||
printf(" <Driver not configured>");
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* Init the high level sound driver
|
||||
*/
|
||||
|
||||
if (!(soundcards_installed = sndtable_get_cardcount())) {
|
||||
DDB(printf("No drivers actually installed\n"));
|
||||
return FALSE; /* No cards detected */
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
#ifdef CONFIG_AUDIO
|
||||
if (num_audiodevs) { /* Audio devices present */
|
||||
DMAbuf_init();
|
||||
sound_mem_init();
|
||||
}
|
||||
soundcard_configured = 1;
|
||||
#endif
|
||||
|
||||
if (num_midis && !midi_initialized)
|
||||
midi_initialized = 1;
|
||||
|
||||
if ((num_midis + num_synths) && !seq_initialized) {
|
||||
seq_initialized = 1;
|
||||
sequencer_init();
|
||||
}
|
||||
|
||||
cdevsw_add(&snd_cdevsw);
|
||||
#define GID_SND GID_GAMES
|
||||
#define UID_SND UID_ROOT
|
||||
#define PERM_SND 0660
|
||||
/*
|
||||
* make links to first successfully probed device, don't do it if
|
||||
* duplicate creation of same node failed (ie. bad cookie returned)
|
||||
*/
|
||||
if (dev->id_driver == &opldriver){
|
||||
make_dev(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_SEQ,
|
||||
UID_SND, GID_SND, PERM_SND, "sequencer%r", dev->id_unit);
|
||||
} else if (dev->id_driver == &mpudriver ||
|
||||
dev->id_driver == &sbmididriver ||
|
||||
dev->id_driver == &uartdriver){
|
||||
make_dev(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_MIDIN,
|
||||
UID_SND, GID_SND, PERM_SND, "midi%r", dev->id_unit);
|
||||
} else {
|
||||
make_dev(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_DSP,
|
||||
UID_SND, GID_SND, PERM_SND, "dsp%r", dev->id_unit);
|
||||
make_dev(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_DSP16,
|
||||
UID_SND, GID_SND, PERM_SND, "dspW%r", dev->id_unit);
|
||||
make_dev(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_AUDIO,
|
||||
UID_SND, GID_SND, PERM_SND, "audio%r", dev->id_unit);
|
||||
make_dev(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_CTL,
|
||||
UID_SND, GID_SND, PERM_SND, "mixer%r", dev->id_unit);
|
||||
make_dev(&snd_cdevsw, (dev->id_unit << 4) | SND_DEV_STATUS,
|
||||
UID_SND, GID_SND, PERM_SND, "sndstat%r", dev->id_unit);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_AUDIO
|
||||
|
||||
static void
|
||||
alloc_dmap(int dev, int chan, struct dma_buffparms * dmap)
|
||||
{
|
||||
char *tmpbuf;
|
||||
int i;
|
||||
|
||||
tmpbuf = contigmalloc(audio_devs[dev]->buffsize, M_DEVBUF, M_NOWAIT,
|
||||
0ul, 0xfffffful, 1ul, chan & 4 ? 0x20000ul : 0x10000ul);
|
||||
if (tmpbuf == NULL)
|
||||
printf("soundcard buffer alloc failed \n");
|
||||
|
||||
if (tmpbuf == NULL) {
|
||||
printf("snd: Unable to allocate %d bytes of buffer\n",
|
||||
2 * (int) audio_devs[dev]->buffsize);
|
||||
return;
|
||||
}
|
||||
dmap->raw_buf = tmpbuf;
|
||||
/*
|
||||
* Use virtual address as the physical address, since isa_dmastart
|
||||
* performs the phys address computation.
|
||||
*/
|
||||
|
||||
dmap->raw_buf_phys = (uintptr_t) tmpbuf;
|
||||
for (i = 0; i < audio_devs[dev]->buffsize; i++) *tmpbuf++ = 0x80;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
sound_mem_init(void)
|
||||
{
|
||||
int dev;
|
||||
static u_long dsp_init_mask = 0;
|
||||
|
||||
for (dev = 0; dev < num_audiodevs; dev++) /* Enumerate devices */
|
||||
if (!(dsp_init_mask & (1 << dev))) /* Not already done */
|
||||
if (audio_devs[dev]->dmachan1 >= 0) {
|
||||
dsp_init_mask |= (1 << dev);
|
||||
audio_devs[dev]->buffsize = DSP_BUFFSIZE;
|
||||
/* Now allocate the buffers */
|
||||
alloc_dmap(dev, audio_devs[dev]->dmachan1,
|
||||
audio_devs[dev]->dmap_out);
|
||||
if (audio_devs[dev]->flags & DMA_DUPLEX)
|
||||
alloc_dmap(dev, audio_devs[dev]->dmachan2,
|
||||
audio_devs[dev]->dmap_in);
|
||||
} /* for dev */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
snd_ioctl_return(int *addr, int value)
|
||||
{
|
||||
if (value < 0)
|
||||
return value; /* Error */
|
||||
suword(addr, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAX_UNIT 50
|
||||
typedef void (*irq_proc_t) (int irq);
|
||||
static irq_proc_t irq_proc[MAX_UNIT] = {NULL};
|
||||
static int irq_irq[MAX_UNIT] = {0};
|
||||
|
||||
int
|
||||
snd_set_irq_handler(int int_lvl, void (*hndlr) (int), sound_os_info * osp)
|
||||
{
|
||||
if (osp->unit >= MAX_UNIT) {
|
||||
printf("Sound error: Unit number too high (%d)\n", osp->unit);
|
||||
return 0;
|
||||
}
|
||||
irq_proc[osp->unit] = hndlr;
|
||||
irq_irq[osp->unit] = int_lvl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
sndintr(int unit)
|
||||
{
|
||||
if ( (unit >= MAX_UNIT) || (irq_proc[unit] == NULL) )
|
||||
return;
|
||||
|
||||
irq_proc[unit] (irq_irq[unit]); /* Call the installed handler */
|
||||
}
|
||||
|
||||
void
|
||||
conf_printf(char *name, struct address_info * hw_config)
|
||||
{
|
||||
if (!trace_init)
|
||||
return;
|
||||
|
||||
printf("snd0: <%s> ", name);
|
||||
#if 0
|
||||
if (hw_config->io_base != -1 )
|
||||
printf("at 0x%03x", hw_config->io_base);
|
||||
|
||||
if (hw_config->irq != -1 )
|
||||
printf(" irq %d", hw_config->irq);
|
||||
|
||||
if (hw_config->dma != -1 || hw_config->dma2 != -1) {
|
||||
printf(" dma %d", hw_config->dma);
|
||||
if (hw_config->dma2 != -1)
|
||||
printf(",%d", hw_config->dma2);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
conf_printf2(char *name, int base, int irq, int dma, int dma2)
|
||||
{
|
||||
if (!trace_init)
|
||||
return;
|
||||
|
||||
printf("snd0: <%s> ", name);
|
||||
#if 0
|
||||
if (hw_config->io_base != -1 )
|
||||
printf("at 0x%03x", hw_config->io_base);
|
||||
|
||||
if (irq)
|
||||
printf(" irq %d", irq);
|
||||
|
||||
if (dma != -1 || dma2 != -1) {
|
||||
printf(" dma %d", dma);
|
||||
if (dma2 != -1)
|
||||
printf(",%d", dma2);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
void tenmicrosec (int j)
|
||||
{
|
||||
int i, k;
|
||||
for (k = 0; k < j/10 ; k++) {
|
||||
for (i = 0; i < 16; i++)
|
||||
inb (0x80);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NSND > 0 */
|
||||
|
||||
|
||||
|
||||
|
@ -1,2 +0,0 @@
|
||||
#define SOUND_VERSION_STRING "3.5-alpha15-970902"
|
||||
#define SOUND_INTERNAL_VERSION 0x030518
|
@ -1,921 +0,0 @@
|
||||
/*
|
||||
* sound/sscape.c
|
||||
*
|
||||
* Low level driver for Ensoniq Soundscape
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1994
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if NSSCAPE > 0
|
||||
|
||||
#include <i386/isa/sound/coproc.h>
|
||||
|
||||
#define EXCLUDE_NATIVE_PCM
|
||||
|
||||
/*
|
||||
* I/O ports
|
||||
*/
|
||||
#define MIDI_DATA 0
|
||||
#define MIDI_CTRL 1
|
||||
#define HOST_CTRL 2
|
||||
#define TX_READY 0x02
|
||||
#define RX_READY 0x01
|
||||
#define HOST_DATA 3
|
||||
#define ODIE_ADDR 4
|
||||
#define ODIE_DATA 5
|
||||
|
||||
/*
|
||||
* Indirect registers
|
||||
*/
|
||||
#define GA_INTSTAT_REG 0
|
||||
#define GA_INTENA_REG 1
|
||||
#define GA_DMAA_REG 2
|
||||
#define GA_DMAB_REG 3
|
||||
#define GA_INTCFG_REG 4
|
||||
#define GA_DMACFG_REG 5
|
||||
#define GA_CDCFG_REG 6
|
||||
#define GA_SMCFGA_REG 7
|
||||
#define GA_SMCFGB_REG 8
|
||||
#define GA_HMCTL_REG 9
|
||||
|
||||
/*
|
||||
* DMA channel identifiers (A and B)
|
||||
*/
|
||||
#define SSCAPE_DMA_A 0
|
||||
#define SSCAPE_DMA_B 1
|
||||
|
||||
#define PORT(name) (devc->base+name)
|
||||
|
||||
/*
|
||||
* Host commands recognized by the OBP microcode
|
||||
*/
|
||||
#define CMD_GEN_HOST_ACK 0x80
|
||||
#define CMD_GEN_MPU_ACK 0x81
|
||||
#define CMD_GET_BOARD_TYPE 0x82
|
||||
#define CMD_SET_CONTROL 0x88
|
||||
#define CMD_GET_CONTROL 0x89
|
||||
#define CTL_MASTER_VOL 0
|
||||
#define CTL_MIC_MODE 2
|
||||
#define CTL_SYNTH_VOL 4
|
||||
#define CTL_WAVE_VOL 7
|
||||
#define CMD_SET_MT32 0x96
|
||||
#define CMD_GET_MT32 0x97
|
||||
#define CMD_SET_EXTMIDI 0x9b
|
||||
#define CMD_GET_EXTMIDI 0x9c
|
||||
|
||||
#define CMD_ACK 0x80
|
||||
|
||||
typedef struct sscape_info {
|
||||
int base, irq, dma;
|
||||
int ok; /* Properly detected */
|
||||
int failed;
|
||||
int dma_allocated;
|
||||
int my_audiodev;
|
||||
int opened;
|
||||
sound_os_info *osp;
|
||||
}
|
||||
|
||||
sscape_info;
|
||||
static struct sscape_info dev_info =
|
||||
{0};
|
||||
static struct sscape_info *devc = &dev_info;
|
||||
|
||||
static int *sscape_sleeper = NULL;
|
||||
static volatile struct snd_wait sscape_sleep_flag =
|
||||
{0};
|
||||
|
||||
/* Some older cards have assigned interrupt bits differently than new ones */
|
||||
static char valid_interrupts_old[] =
|
||||
{9, 7, 5, 15};
|
||||
|
||||
static char valid_interrupts_new[] =
|
||||
{9, 5, 7, 10};
|
||||
|
||||
static char *valid_interrupts = valid_interrupts_new;
|
||||
|
||||
#ifdef REVEAL_SPEA
|
||||
static char old_hardware = 1;
|
||||
|
||||
#else
|
||||
static char old_hardware = 0;
|
||||
|
||||
#endif
|
||||
|
||||
static u_char
|
||||
sscape_read(struct sscape_info * devc, int reg)
|
||||
{
|
||||
u_long flags;
|
||||
u_char val;
|
||||
|
||||
flags = splhigh();
|
||||
outb(PORT(ODIE_ADDR), reg);
|
||||
val = inb(PORT(ODIE_DATA));
|
||||
splx(flags);
|
||||
return val;
|
||||
}
|
||||
|
||||
static void
|
||||
sscape_write(struct sscape_info * devc, int reg, int data)
|
||||
{
|
||||
u_long flags;
|
||||
|
||||
flags = splhigh();
|
||||
outb(PORT(ODIE_ADDR), reg);
|
||||
outb(PORT(ODIE_DATA), data);
|
||||
splx(flags);
|
||||
}
|
||||
|
||||
static void
|
||||
host_open(struct sscape_info * devc)
|
||||
{
|
||||
outb(PORT(HOST_CTRL), 0x00); /* Put the board to the host mode */
|
||||
}
|
||||
|
||||
static void
|
||||
host_close(struct sscape_info * devc)
|
||||
{
|
||||
outb(PORT(HOST_CTRL), 0x03); /* Put the board to the MIDI mode */
|
||||
}
|
||||
|
||||
static int
|
||||
host_write(struct sscape_info * devc, u_char *data, int count)
|
||||
{
|
||||
u_long flags;
|
||||
int i, timeout_val;
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
/*
|
||||
* Send the command and data bytes
|
||||
*/
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
for (timeout_val = 10000; timeout_val > 0; timeout_val--)
|
||||
if (inb(PORT(HOST_CTRL)) & TX_READY)
|
||||
break;
|
||||
|
||||
if (timeout_val <= 0) {
|
||||
splx(flags);
|
||||
return 0;
|
||||
}
|
||||
outb(PORT(HOST_DATA), data[i]);
|
||||
}
|
||||
|
||||
|
||||
splx(flags);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
host_read(struct sscape_info * devc)
|
||||
{
|
||||
u_long flags;
|
||||
int timeout_val;
|
||||
u_char data;
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
/*
|
||||
* Read a byte
|
||||
*/
|
||||
|
||||
for (timeout_val = 10000; timeout_val > 0; timeout_val--)
|
||||
if (inb(PORT(HOST_CTRL)) & RX_READY)
|
||||
break;
|
||||
|
||||
if (timeout_val <= 0) {
|
||||
splx(flags);
|
||||
return -1;
|
||||
}
|
||||
data = inb(PORT(HOST_DATA));
|
||||
|
||||
splx(flags);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static int
|
||||
host_command1(struct sscape_info * devc, int cmd)
|
||||
{
|
||||
u_char buf[10];
|
||||
|
||||
buf[0] = (u_char) (cmd & 0xff);
|
||||
|
||||
return host_write(devc, buf, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
host_command2(struct sscape_info * devc, int cmd, int parm1)
|
||||
{
|
||||
u_char buf[10];
|
||||
|
||||
buf[0] = (u_char) (cmd & 0xff);
|
||||
buf[1] = (u_char) (parm1 & 0xff);
|
||||
|
||||
return host_write(devc, buf, 2);
|
||||
}
|
||||
|
||||
static int
|
||||
host_command3(struct sscape_info * devc, int cmd, int parm1, int parm2)
|
||||
{
|
||||
u_char buf[10];
|
||||
|
||||
buf[0] = (u_char) (cmd & 0xff);
|
||||
buf[1] = (u_char) (parm1 & 0xff);
|
||||
buf[2] = (u_char) (parm2 & 0xff);
|
||||
|
||||
return host_write(devc, buf, 3);
|
||||
}
|
||||
|
||||
static void
|
||||
set_mt32(struct sscape_info * devc, int value)
|
||||
{
|
||||
host_open(devc);
|
||||
host_command2(devc, CMD_SET_MT32,
|
||||
value ? 1 : 0);
|
||||
if (host_read(devc) != CMD_ACK) {
|
||||
printf("SNDSCAPE: Setting MT32 mode failed\n");
|
||||
}
|
||||
host_close(devc);
|
||||
}
|
||||
|
||||
static void
|
||||
set_control(struct sscape_info * devc, int ctrl, int value)
|
||||
{
|
||||
host_open(devc);
|
||||
host_command3(devc, CMD_SET_CONTROL, ctrl, value);
|
||||
if (host_read(devc) != CMD_ACK) {
|
||||
printf("SNDSCAPE: Setting control (%d) failed\n", ctrl);
|
||||
}
|
||||
host_close(devc);
|
||||
}
|
||||
|
||||
static int
|
||||
get_board_type(struct sscape_info * devc)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
host_open(devc);
|
||||
if (!host_command1(devc, CMD_GET_BOARD_TYPE))
|
||||
tmp = -1;
|
||||
else
|
||||
tmp = host_read(devc);
|
||||
host_close(devc);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void
|
||||
sscapeintr(int irq)
|
||||
{
|
||||
u_char bits, tmp;
|
||||
|
||||
bits = sscape_read(devc, GA_INTSTAT_REG);
|
||||
DEB(printf("sscapeintr(0x%02x)\n", bits));
|
||||
if ((sscape_sleep_flag.mode & WK_SLEEP)) {
|
||||
sscape_sleep_flag.mode = WK_WAKEUP;
|
||||
wakeup(sscape_sleeper);
|
||||
}
|
||||
if (bits & 0x02) { /* Host interface interrupt */
|
||||
printf("SSCAPE: Host interrupt, data=%02x\n", host_read(devc));
|
||||
}
|
||||
#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
|
||||
if (bits & 0x01) {
|
||||
static int debug = 0;
|
||||
|
||||
mpuintr(irq);
|
||||
if (debug++ > 10) { /* Temporary debugging hack */
|
||||
sscape_write(devc, GA_INTENA_REG, 0x00); /* Disable all interr. */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Acknowledge interrupts (toggle the interrupt bits)
|
||||
*/
|
||||
|
||||
tmp = sscape_read(devc, GA_INTENA_REG);
|
||||
sscape_write(devc, GA_INTENA_REG, (~bits & 0x0e) | (tmp & 0xf1));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_dma(struct sscape_info * devc, int dma_chan, u_long buf, int blk_size, int mode)
|
||||
{
|
||||
u_char temp;
|
||||
|
||||
if (dma_chan != SSCAPE_DMA_A) {
|
||||
printf("SSCAPE: Tried to use DMA channel != A. Why?\n");
|
||||
return;
|
||||
}
|
||||
DMAbuf_start_dma(devc->my_audiodev, buf, blk_size, mode);
|
||||
|
||||
temp = devc->dma << 4; /* Setup DMA channel select bits */
|
||||
if (devc->dma <= 3)
|
||||
temp |= 0x80; /* 8 bit DMA channel */
|
||||
|
||||
temp |= 1; /* Trigger DMA */
|
||||
sscape_write(devc, GA_DMAA_REG, temp);
|
||||
temp &= 0xfe; /* Clear DMA trigger */
|
||||
sscape_write(devc, GA_DMAA_REG, temp);
|
||||
}
|
||||
|
||||
static int
|
||||
verify_mpu(struct sscape_info * devc)
|
||||
{
|
||||
/*
|
||||
* The SoundScape board could be in three modes (MPU, 8250 and host).
|
||||
* If the card is not in the MPU mode, enabling the MPU driver will
|
||||
* cause infinite loop (the driver believes that there is always some
|
||||
* received data in the buffer.
|
||||
*
|
||||
* Detect this by looking if there are more than 10 received MIDI bytes
|
||||
* (0x00) in the buffer.
|
||||
*/
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (inb(devc->base + HOST_CTRL) & 0x80)
|
||||
return 1;
|
||||
|
||||
if (inb(devc->base) != 0x00)
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("SoundScape: The device is not in the MPU-401 mode\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sscape_coproc_open(void *dev_info, int sub_device)
|
||||
{
|
||||
if (sub_device == COPR_MIDI) {
|
||||
set_mt32(devc, 0);
|
||||
if (!verify_mpu(devc))
|
||||
return -(EIO);
|
||||
}
|
||||
sscape_sleep_flag.aborting = 0;
|
||||
sscape_sleep_flag.mode = WK_NONE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
sscape_coproc_close(void *dev_info, int sub_device)
|
||||
{
|
||||
struct sscape_info *devc = dev_info;
|
||||
u_long flags;
|
||||
|
||||
flags = splhigh();
|
||||
if (devc->dma_allocated) {
|
||||
sscape_write(devc, GA_DMAA_REG, 0x20); /* DMA channel disabled */
|
||||
#ifdef CONFIG_NATIVE_PCM
|
||||
#endif
|
||||
devc->dma_allocated = 0;
|
||||
}
|
||||
sscape_sleep_flag.aborting = 0;
|
||||
sscape_sleep_flag.mode = WK_NONE;
|
||||
splx(flags);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
sscape_coproc_reset(void *dev_info)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
sscape_download_boot(struct sscape_info * devc, u_char *block, int size, int flag)
|
||||
{
|
||||
u_long flags;
|
||||
u_char temp;
|
||||
int done, timeout_val;
|
||||
|
||||
if (flag & CPF_FIRST) {
|
||||
/*
|
||||
* First block. Have to allocate DMA and to reset the board
|
||||
* before continuing.
|
||||
*/
|
||||
|
||||
flags = splhigh();
|
||||
if (devc->dma_allocated == 0) {
|
||||
devc->dma_allocated = 1;
|
||||
}
|
||||
splx(flags);
|
||||
|
||||
sscape_write(devc, GA_HMCTL_REG,
|
||||
(temp = sscape_read(devc, GA_HMCTL_REG)) & 0x3f); /* Reset */
|
||||
|
||||
for (timeout_val = 10000; timeout_val > 0; timeout_val--)
|
||||
sscape_read(devc, GA_HMCTL_REG); /* Delay */
|
||||
|
||||
/* Take board out of reset */
|
||||
sscape_write(devc, GA_HMCTL_REG,
|
||||
(temp = sscape_read(devc, GA_HMCTL_REG)) | 0x80);
|
||||
}
|
||||
/*
|
||||
* Transfer one code block using DMA
|
||||
*/
|
||||
bcopy(block, audio_devs[devc->my_audiodev]->dmap_out->raw_buf, size);
|
||||
|
||||
flags = splhigh();
|
||||
/******** INTERRUPTS DISABLED NOW ********/
|
||||
do_dma(devc, SSCAPE_DMA_A,
|
||||
audio_devs[devc->my_audiodev]->dmap_out->raw_buf_phys,
|
||||
size, 1);
|
||||
|
||||
/*
|
||||
* Wait until transfer completes.
|
||||
*/
|
||||
sscape_sleep_flag.aborting = 0;
|
||||
sscape_sleep_flag.mode = WK_NONE;
|
||||
done = 0;
|
||||
timeout_val = 100;
|
||||
while (!done && timeout_val-- > 0) {
|
||||
int chn;
|
||||
sscape_sleeper = &chn;
|
||||
DO_SLEEP(chn, sscape_sleep_flag, 1);
|
||||
|
||||
done = 1;
|
||||
}
|
||||
|
||||
splx(flags);
|
||||
if (!done)
|
||||
return 0;
|
||||
|
||||
if (flag & CPF_LAST) {
|
||||
/*
|
||||
* Take the board out of reset
|
||||
*/
|
||||
outb(PORT(HOST_CTRL), 0x00);
|
||||
outb(PORT(MIDI_CTRL), 0x00);
|
||||
|
||||
temp = sscape_read(devc, GA_HMCTL_REG);
|
||||
temp |= 0x40;
|
||||
sscape_write(devc, GA_HMCTL_REG, temp); /* Kickstart the board */
|
||||
|
||||
/*
|
||||
* Wait until the ODB wakes up
|
||||
*/
|
||||
|
||||
flags = splhigh();
|
||||
done = 0;
|
||||
timeout_val = 5 * hz;
|
||||
while (!done && timeout_val-- > 0) {
|
||||
int chn;
|
||||
|
||||
sscape_sleeper = &chn;
|
||||
DO_SLEEP(chn, sscape_sleep_flag, 1);
|
||||
|
||||
if (inb(PORT(HOST_DATA)) == 0xff) /* OBP startup acknowledge */
|
||||
done = 1;
|
||||
}
|
||||
splx(flags);
|
||||
if (!done) {
|
||||
printf("SoundScape: The OBP didn't respond after code download\n");
|
||||
return 0;
|
||||
}
|
||||
flags = splhigh();
|
||||
done = 0;
|
||||
timeout_val = 5 * hz;
|
||||
while (!done && timeout_val-- > 0) {
|
||||
int chn;
|
||||
|
||||
sscape_sleeper = &chn;
|
||||
DO_SLEEP(chn, sscape_sleep_flag, 1);
|
||||
|
||||
if (inb(PORT(HOST_DATA)) == 0xfe) /* Host startup acknowledge */
|
||||
done = 1;
|
||||
}
|
||||
splx(flags);
|
||||
if (!done) {
|
||||
printf("SoundScape: OBP Initialization failed.\n");
|
||||
return 0;
|
||||
}
|
||||
printf("SoundScape board of type %d initialized OK\n",
|
||||
get_board_type(devc));
|
||||
|
||||
set_control(devc, CTL_MASTER_VOL, 100);
|
||||
set_control(devc, CTL_SYNTH_VOL, 100);
|
||||
|
||||
#ifdef SSCAPE_DEBUG3
|
||||
/*
|
||||
* Temporary debugging aid. Print contents of the registers
|
||||
* after downloading the code.
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 13; i++)
|
||||
printf("I%d = %02x (new value)\n", i, sscape_read(devc, i));
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
download_boot_block(void *dev_info, copr_buffer * buf)
|
||||
{
|
||||
if (buf->len <= 0 || buf->len > sizeof(buf->data))
|
||||
return -(EINVAL);
|
||||
|
||||
if (!sscape_download_boot(devc, buf->data, buf->len, buf->flags)) {
|
||||
printf("SSCAPE: Unable to load microcode block to the OBP.\n");
|
||||
return -(EIO);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sscape_coproc_ioctl(void *dev_info, u_int cmd, ioctl_arg arg, int local)
|
||||
{
|
||||
|
||||
switch (cmd) {
|
||||
case SNDCTL_COPR_RESET:
|
||||
sscape_coproc_reset(dev_info);
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SNDCTL_COPR_LOAD:
|
||||
{
|
||||
copr_buffer *buf;
|
||||
int err;
|
||||
|
||||
buf = (copr_buffer *) malloc(sizeof(copr_buffer), M_TEMP, M_WAITOK);
|
||||
if (buf == NULL)
|
||||
return -(ENOSPC);
|
||||
bcopy(&(((char *) arg)[0]), (char *) buf, sizeof(*buf));
|
||||
err = download_boot_block(dev_info, buf);
|
||||
free(buf, M_TEMP);
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return -(EINVAL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static coproc_operations sscape_coproc_operations =
|
||||
{
|
||||
"SoundScape M68K",
|
||||
sscape_coproc_open,
|
||||
sscape_coproc_close,
|
||||
sscape_coproc_ioctl,
|
||||
sscape_coproc_reset,
|
||||
&dev_info
|
||||
};
|
||||
|
||||
#if !defined(EXCLUDE_NATIVE_PCM) && defined(CONFIG_AUDIO)
|
||||
static struct audio_operations sscape_audio_operations =
|
||||
{
|
||||
"Not functional",
|
||||
0,
|
||||
AFMT_U8 | AFMT_S16_LE,
|
||||
NULL,
|
||||
sscape_audio_open,
|
||||
sscape_audio_close,
|
||||
sscape_audio_output_block,
|
||||
sscape_audio_start_input,
|
||||
sscape_audio_ioctl,
|
||||
sscape_audio_prepare_for_input,
|
||||
sscape_audio_prepare_for_output,
|
||||
sscape_audio_reset,
|
||||
sscape_audio_halt,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
#endif /* !defined(EXCLUDE_NATIVE_PCM) && defined(CONFIG_AUDIO) */
|
||||
|
||||
static int sscape_detected = 0;
|
||||
|
||||
void
|
||||
attach_sscape(struct address_info * hw_config)
|
||||
{
|
||||
#ifndef SSCAPE_REGS
|
||||
/*
|
||||
* Config register values for Spea/V7 Media FX and Ensoniq S-2000.
|
||||
* These values are card dependent. If you have another SoundScape
|
||||
* based card, you have to find the correct values. Do the following:
|
||||
* - Compile this driver with SSCAPE_DEBUG1 defined. - Shut down and
|
||||
* power off your machine. - Boot with DOS so that the SSINIT.EXE
|
||||
* program is run. - Warm boot to {Linux|SYSV|BSD} and write down the
|
||||
* lines displayed when detecting the SoundScape. - Modify the
|
||||
* following list to use the values printed during boot. Undefine the
|
||||
* SSCAPE_DEBUG1
|
||||
*/
|
||||
#define SSCAPE_REGS { \
|
||||
/* I0 */ 0x00, \
|
||||
0xf0, /* Note! Ignored. Set always to 0xf0 */ \
|
||||
0x20, /* Note! Ignored. Set always to 0x20 */ \
|
||||
0x20, /* Note! Ignored. Set always to 0x20 */ \
|
||||
0xf5, /* Ignored */ \
|
||||
0x10, \
|
||||
0x00, \
|
||||
0x2e, /* I7 MEM config A. Likely to vary between models */ \
|
||||
0x00, /* I8 MEM config B. Likely to vary between models */ \
|
||||
/* I9 */ 0x40 /* Ignored */ \
|
||||
}
|
||||
#endif
|
||||
|
||||
u_long flags;
|
||||
static u_char regs[10] = SSCAPE_REGS;
|
||||
|
||||
int i, irq_bits = 0xff;
|
||||
|
||||
if (sscape_detected != hw_config->io_base)
|
||||
return;
|
||||
|
||||
if (old_hardware) {
|
||||
valid_interrupts = valid_interrupts_old;
|
||||
conf_printf("Ensoniq Soundscape (old)", hw_config);
|
||||
} else
|
||||
conf_printf("Ensoniq Soundscape", hw_config);
|
||||
|
||||
for (i = 0; i < sizeof(valid_interrupts); i++)
|
||||
if (hw_config->irq == valid_interrupts[i]) {
|
||||
irq_bits = i;
|
||||
break;
|
||||
}
|
||||
if (hw_config->irq > 15 || (regs[4] = irq_bits == 0xff)) {
|
||||
printf("Invalid IRQ%d\n", hw_config->irq);
|
||||
return;
|
||||
}
|
||||
flags = splhigh();
|
||||
|
||||
for (i = 1; i < 10; i++)
|
||||
switch (i) {
|
||||
case 1: /* Host interrupt enable */
|
||||
sscape_write(devc, i, 0xf0); /* All interrupts enabled */
|
||||
break;
|
||||
|
||||
case 2: /* DMA A status/trigger register */
|
||||
case 3: /* DMA B status/trigger register */
|
||||
sscape_write(devc, i, 0x20); /* DMA channel disabled */
|
||||
break;
|
||||
|
||||
case 4: /* Host interrupt config reg */
|
||||
sscape_write(devc, i, 0xf0 | (irq_bits << 2) | irq_bits);
|
||||
break;
|
||||
|
||||
case 5: /* Don't destroy CD-ROM DMA config bits (0xc0) */
|
||||
sscape_write(devc, i, (regs[i] & 0x3f) |
|
||||
(sscape_read(devc, i) & 0xc0));
|
||||
break;
|
||||
|
||||
case 6: /* CD-ROM config. Don't touch. */
|
||||
break;
|
||||
|
||||
case 9: /* Master control reg. Don't modify CR-ROM
|
||||
* bits. Disable SB emul */
|
||||
sscape_write(devc, i, (sscape_read(devc, i) & 0xf0) | 0x00);
|
||||
break;
|
||||
|
||||
default:
|
||||
sscape_write(devc, i, regs[i]);
|
||||
}
|
||||
|
||||
splx(flags);
|
||||
|
||||
#ifdef SSCAPE_DEBUG2
|
||||
/*
|
||||
* Temporary debugging aid. Print contents of the registers after
|
||||
* changing them.
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 13; i++)
|
||||
printf("I%d = %02x (new value)\n", i, sscape_read(devc, i));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MIDI) && defined(CONFIG_MPU_EMU)
|
||||
if (probe_mpu401(hw_config))
|
||||
hw_config->always_detect = 1;
|
||||
{
|
||||
int prev_devs;
|
||||
|
||||
prev_devs = num_midis;
|
||||
attach_mpu401(hw_config);
|
||||
|
||||
if (num_midis == (prev_devs + 1)) /* The MPU driver
|
||||
* installed itself */
|
||||
midi_devs[prev_devs]->coproc = &sscape_coproc_operations;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef EXCLUDE_NATIVE_PCM
|
||||
/* Not supported yet */
|
||||
|
||||
#ifdef CONFIG_AUDIO
|
||||
if (num_audiodevs < MAX_AUDIO_DEV) {
|
||||
int my_dev;
|
||||
|
||||
audio_devs[my_dev = num_audiodevs++] = &sscape_audio_operations;
|
||||
audio_devs[my_dev]->dmachan1 = hw_config->dma;
|
||||
audio_devs[my_dev]->buffsize = DSP_BUFFSIZE;
|
||||
audio_devs[my_dev]->devc = devc;
|
||||
devc->my_audiodev = my_dev;
|
||||
devc->opened = 0;
|
||||
audio_devs[my_dev]->coproc = &sscape_coproc_operations;
|
||||
if (snd_set_irq_handler(hw_config->irq, sscapeintr, devc->osp) < 0)
|
||||
printf("Error: Can't allocate IRQ for SoundScape\n");
|
||||
sscape_write(devc, GA_INTENA_REG, 0x80); /* Master IRQ enable */
|
||||
} else
|
||||
printf("SoundScape: More than enough audio devices detected\n");
|
||||
#endif
|
||||
#endif
|
||||
devc->ok = 1;
|
||||
devc->failed = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
probe_sscape(struct address_info * hw_config)
|
||||
{
|
||||
u_char save;
|
||||
|
||||
devc->failed = 1;
|
||||
devc->base = hw_config->io_base;
|
||||
devc->irq = hw_config->irq;
|
||||
devc->dma = hw_config->dma;
|
||||
devc->osp = hw_config->osp;
|
||||
|
||||
if (sscape_detected != 0 && sscape_detected != hw_config->io_base)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* First check that the address register of "ODIE" is there and that
|
||||
* it has exactly 4 writeable bits. First 4 bits
|
||||
*/
|
||||
if ((save = inb(PORT(ODIE_ADDR))) & 0xf0)
|
||||
return 0;
|
||||
|
||||
outb(PORT(ODIE_ADDR), 0x00);
|
||||
if (inb(PORT(ODIE_ADDR)) != 0x00)
|
||||
return 0;
|
||||
|
||||
outb(PORT(ODIE_ADDR), 0xff);
|
||||
if (inb(PORT(ODIE_ADDR)) != 0x0f)
|
||||
return 0;
|
||||
|
||||
outb(PORT(ODIE_ADDR), save);
|
||||
|
||||
/*
|
||||
* Now verify that some indirect registers return zero on some bits.
|
||||
* This may break the driver with some future revisions of "ODIE"
|
||||
* but...
|
||||
*/
|
||||
|
||||
if (sscape_read(devc, 0) & 0x0c)
|
||||
return 0;
|
||||
|
||||
if (sscape_read(devc, 1) & 0x0f)
|
||||
return 0;
|
||||
|
||||
if (sscape_read(devc, 5) & 0x0f)
|
||||
return 0;
|
||||
|
||||
#ifdef SSCAPE_DEBUG1
|
||||
/*
|
||||
* Temporary debugging aid. Print contents of the registers before
|
||||
* changing them.
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 13; i++)
|
||||
printf("I%d = %02x (old value)\n", i, sscape_read(devc, i));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (old_hardware) { /* Check that it's really an old Spea/Reveal card. */
|
||||
u_char tmp;
|
||||
int cc;
|
||||
|
||||
if (!((tmp = sscape_read(devc, GA_HMCTL_REG)) & 0xc0)) {
|
||||
sscape_write(devc, GA_HMCTL_REG, tmp | 0x80);
|
||||
for (cc = 0; cc < 200000; ++cc)
|
||||
inb(devc->base + ODIE_ADDR);
|
||||
} else
|
||||
old_hardware = 0;
|
||||
}
|
||||
if (0) {
|
||||
printf("sscape.c: Can't allocate DMA channel\n");
|
||||
return 0;
|
||||
}
|
||||
sscape_detected = hw_config->io_base;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
probe_ss_mss(struct address_info * hw_config)
|
||||
{
|
||||
int i, irq_bits = 0xff;
|
||||
|
||||
if (devc->failed)
|
||||
return 0;
|
||||
|
||||
if (devc->ok == 0) {
|
||||
printf("SoundScape: Invalid initialization order.\n");
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < sizeof(valid_interrupts); i++)
|
||||
if (hw_config->irq == valid_interrupts[i]) {
|
||||
irq_bits = i;
|
||||
break;
|
||||
}
|
||||
if (hw_config->irq > 15 || irq_bits == 0xff) {
|
||||
printf("SoundScape: Invalid MSS IRQ%d\n", hw_config->irq);
|
||||
return 0;
|
||||
}
|
||||
return ad1848_detect(hw_config->io_base, NULL, hw_config->osp);
|
||||
}
|
||||
|
||||
void
|
||||
attach_ss_mss(struct address_info * hw_config)
|
||||
{
|
||||
/*
|
||||
* This routine configures the SoundScape card for use with the Win
|
||||
* Sound System driver. The AD1848 codec interface uses the CD-ROM
|
||||
* config registers of the "ODIE".
|
||||
*/
|
||||
|
||||
int i, irq_bits = 0xff;
|
||||
|
||||
#ifndef CONFIG_NATIVE_PCM
|
||||
int prev_devs = num_audiodevs;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Setup the DMA polarity.
|
||||
*/
|
||||
sscape_write(devc, GA_DMACFG_REG, 0x50);
|
||||
|
||||
/*
|
||||
* Take the gate-arry off of the DMA channel.
|
||||
*/
|
||||
sscape_write(devc, GA_DMAB_REG, 0x20);
|
||||
|
||||
/*
|
||||
* Init the AD1848 (CD-ROM) config reg.
|
||||
*/
|
||||
|
||||
for (i = 0; i < sizeof(valid_interrupts); i++)
|
||||
if (hw_config->irq == valid_interrupts[i]) {
|
||||
irq_bits = i;
|
||||
break;
|
||||
}
|
||||
sscape_write(devc, GA_CDCFG_REG, 0x89 | (hw_config->dma << 4) |
|
||||
(irq_bits << 1));
|
||||
|
||||
if (hw_config->irq == devc->irq)
|
||||
printf("SoundScape: Warning! WSS mode can't share IRQ with MIDI\n");
|
||||
|
||||
ad1848_init("SoundScape", hw_config->io_base,
|
||||
hw_config->irq,
|
||||
hw_config->dma,
|
||||
hw_config->dma,
|
||||
0,
|
||||
devc->osp);
|
||||
|
||||
#ifndef CONFIG_NATIVE_PCM
|
||||
/* Check if the AD1848 driver installed itself */
|
||||
if (num_audiodevs == (prev_devs + 1))
|
||||
audio_devs[prev_devs]->coproc = &sscape_coproc_operations;
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,276 +0,0 @@
|
||||
/*
|
||||
* sound/sys_timer.c
|
||||
*
|
||||
* The default timer for the Level 2 sequencer interface.
|
||||
* Uses the (100hz) timer of kernel.
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#define SEQUENCER_C
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if NSND > 0
|
||||
|
||||
#if defined(CONFIG_SEQUENCER)
|
||||
|
||||
static volatile int opened = 0, tmr_running = 0;
|
||||
static volatile time_t tmr_offs, tmr_ctr;
|
||||
static volatile u_long ticks_offs;
|
||||
static volatile int curr_tempo, curr_timebase;
|
||||
static volatile u_long curr_ticks;
|
||||
static volatile u_long next_event_time;
|
||||
static u_long prev_event_time;
|
||||
|
||||
static void poll_def_tmr(void *dummy);
|
||||
|
||||
static u_long
|
||||
tmr2ticks(int tmr_value)
|
||||
{
|
||||
/*
|
||||
* Convert system timer ticks (hz) to MIDI ticks (divide # of MIDI
|
||||
* ticks/minute by # of system ticks/minute).
|
||||
*/
|
||||
|
||||
return ((tmr_value * curr_tempo * curr_timebase) + (30 * hz)) / (60 * hz);
|
||||
}
|
||||
|
||||
static void
|
||||
poll_def_tmr(void *dummy)
|
||||
{
|
||||
|
||||
if (opened) {
|
||||
|
||||
timeout( poll_def_tmr, 0, 1);;
|
||||
|
||||
if (tmr_running) {
|
||||
tmr_ctr++;
|
||||
curr_ticks = ticks_offs + tmr2ticks(tmr_ctr);
|
||||
|
||||
if (curr_ticks >= next_event_time) {
|
||||
next_event_time = 0xffffffff;
|
||||
sequencer_timer(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tmr_reset(void)
|
||||
{
|
||||
u_long flags;
|
||||
|
||||
flags = splhigh();
|
||||
tmr_offs = 0;
|
||||
ticks_offs = 0;
|
||||
tmr_ctr = 0;
|
||||
next_event_time = 0xffffffff;
|
||||
prev_event_time = 0;
|
||||
curr_ticks = 0;
|
||||
splx(flags);
|
||||
}
|
||||
|
||||
static int
|
||||
def_tmr_open(int dev, int mode)
|
||||
{
|
||||
if (opened)
|
||||
return -(EBUSY);
|
||||
|
||||
tmr_reset();
|
||||
curr_tempo = 60;
|
||||
curr_timebase = hz;
|
||||
opened = 1;
|
||||
|
||||
timeout( poll_def_tmr, 0, 1);;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
def_tmr_close(int dev)
|
||||
{
|
||||
opened = tmr_running = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
def_tmr_event(int dev, u_char *event)
|
||||
{
|
||||
u_char cmd = event[1];
|
||||
u_long parm = *(int *) &event[4];
|
||||
|
||||
switch (cmd) {
|
||||
case TMR_WAIT_REL:
|
||||
parm += prev_event_time;
|
||||
case TMR_WAIT_ABS:
|
||||
if (parm > 0) {
|
||||
long time;
|
||||
|
||||
if (parm <= curr_ticks) /* It's the time */
|
||||
return TIMER_NOT_ARMED;
|
||||
|
||||
time = parm;
|
||||
next_event_time = prev_event_time = time;
|
||||
|
||||
return TIMER_ARMED;
|
||||
}
|
||||
break;
|
||||
|
||||
case TMR_START:
|
||||
tmr_reset();
|
||||
tmr_running = 1;
|
||||
break;
|
||||
|
||||
case TMR_STOP:
|
||||
tmr_running = 0;
|
||||
break;
|
||||
|
||||
case TMR_CONTINUE:
|
||||
tmr_running = 1;
|
||||
break;
|
||||
|
||||
case TMR_TEMPO:
|
||||
if (parm) {
|
||||
RANGE (parm, 8, 360) ;
|
||||
tmr_offs = tmr_ctr;
|
||||
ticks_offs += tmr2ticks(tmr_ctr);
|
||||
tmr_ctr = 0;
|
||||
curr_tempo = parm;
|
||||
}
|
||||
break;
|
||||
|
||||
case TMR_ECHO:
|
||||
seq_copy_to_input(event, 8);
|
||||
break;
|
||||
|
||||
default:;
|
||||
}
|
||||
|
||||
return TIMER_NOT_ARMED;
|
||||
}
|
||||
|
||||
static u_long
|
||||
def_tmr_get_time(int dev)
|
||||
{
|
||||
if (!opened)
|
||||
return 0;
|
||||
|
||||
return curr_ticks;
|
||||
}
|
||||
|
||||
static int
|
||||
def_tmr_ioctl(int dev, u_int cmd, ioctl_arg arg)
|
||||
{
|
||||
switch (cmd) {
|
||||
case SNDCTL_TMR_SOURCE:
|
||||
return *(int *) arg = TMR_INTERNAL;
|
||||
break;
|
||||
|
||||
case SNDCTL_TMR_START:
|
||||
tmr_reset();
|
||||
tmr_running = 1;
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SNDCTL_TMR_STOP:
|
||||
tmr_running = 0;
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SNDCTL_TMR_CONTINUE:
|
||||
tmr_running = 1;
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SNDCTL_TMR_TIMEBASE:
|
||||
{
|
||||
int val = (*(int *) arg);
|
||||
|
||||
if (val) {
|
||||
RANGE (val, 1, 1000) ;
|
||||
curr_timebase = val;
|
||||
}
|
||||
return *(int *) arg = curr_timebase;
|
||||
}
|
||||
break;
|
||||
|
||||
case SNDCTL_TMR_TEMPO:
|
||||
{
|
||||
int val = (*(int *) arg);
|
||||
|
||||
if (val) {
|
||||
RANGE (val, 8, 250) ;
|
||||
tmr_offs = tmr_ctr;
|
||||
ticks_offs += tmr2ticks(tmr_ctr);
|
||||
tmr_ctr = 0;
|
||||
curr_tempo = val;
|
||||
}
|
||||
return *(int *) arg = curr_tempo;
|
||||
}
|
||||
break;
|
||||
|
||||
case SNDCTL_SEQ_CTRLRATE:
|
||||
if ((*(int *) arg) != 0) /* Can't change */
|
||||
return -(EINVAL);
|
||||
|
||||
return *(int *) arg = ((curr_tempo * curr_timebase) + 30) / 60;
|
||||
break;
|
||||
|
||||
case SNDCTL_TMR_METRONOME:
|
||||
/* NOP */
|
||||
break;
|
||||
|
||||
default:;
|
||||
}
|
||||
|
||||
return -(EINVAL);
|
||||
}
|
||||
|
||||
static void
|
||||
def_tmr_arm(int dev, long time)
|
||||
{
|
||||
if (time < 0)
|
||||
time = curr_ticks + 1;
|
||||
else if (time <= curr_ticks) /* It's the time */
|
||||
return;
|
||||
|
||||
next_event_time = prev_event_time = time;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
struct sound_timer_operations default_sound_timer =
|
||||
{
|
||||
{"System clock", 0},
|
||||
0, /* Priority */
|
||||
0, /* Local device link */
|
||||
def_tmr_open,
|
||||
def_tmr_close,
|
||||
def_tmr_event,
|
||||
def_tmr_get_time,
|
||||
def_tmr_ioctl,
|
||||
def_tmr_arm
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* NSND > 0 */
|
@ -1,368 +0,0 @@
|
||||
/*
|
||||
* sound/trix.c
|
||||
*
|
||||
* Low level driver for the MediaTriX AudioTriX Pro (MT-0002-PC Control Chip)
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1995
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if NTRIX > 0
|
||||
|
||||
#ifdef INCLUDE_TRIX_BOOT
|
||||
#include <i386/isa/sound/trix_boot.h>
|
||||
#endif
|
||||
|
||||
#if (NSB > 0)
|
||||
extern int sb_no_recording;
|
||||
#endif
|
||||
|
||||
static int kilroy_was_here = 0; /* Don't detect twice */
|
||||
static int sb_initialized = 0;
|
||||
|
||||
static sound_os_info *trix_osp = NULL;
|
||||
|
||||
static u_char
|
||||
trix_read(int addr)
|
||||
{
|
||||
outb(0x390, (u_char) addr); /* MT-0002-PC ASIC address */
|
||||
return inb(0x391); /* MT-0002-PC ASIC data */
|
||||
}
|
||||
|
||||
static void
|
||||
trix_write(int addr, int data)
|
||||
{
|
||||
outb(0x390, (u_char) addr); /* MT-0002-PC ASIC address */
|
||||
outb(0x391, (u_char) data); /* MT-0002-PC ASIC data */
|
||||
}
|
||||
|
||||
static void
|
||||
download_boot(int base)
|
||||
{
|
||||
#ifdef INCLUDE_TRIX_BOOT
|
||||
int i = 0, n = sizeof(trix_boot);
|
||||
|
||||
trix_write(0xf8, 0x00); /* ??????? */
|
||||
outb(base + 6, 0x01); /* Clear the internal data pointer */
|
||||
outb(base + 6, 0x00); /* Restart */
|
||||
|
||||
/*
|
||||
* Write the boot code to the RAM upload/download register. Each
|
||||
* write increments the internal data pointer.
|
||||
*/
|
||||
outb(base + 6, 0x01); /* Clear the internal data pointer */
|
||||
outb(0x390, 0x1A); /* Select RAM download/upload port */
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
outb(0x391, trix_boot[i]);
|
||||
for (i = n; i < 10016; i++) /* Clear up to first 16 bytes of data RAM */
|
||||
outb(0x391, 0x00);
|
||||
outb(base + 6, 0x00); /* Reset */
|
||||
outb(0x390, 0x50); /* ?????? */
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
trix_set_wss_port(struct address_info * hw_config)
|
||||
{
|
||||
u_char addr_bits;
|
||||
|
||||
if (0) {
|
||||
printf("AudioTriX: Config port I/O conflict\n");
|
||||
return 0;
|
||||
}
|
||||
if (kilroy_was_here) /* Already initialized */
|
||||
return 0;
|
||||
|
||||
if (trix_read(0x15) != 0x71) { /* No asic signature */
|
||||
DDB(printf("No AudioTriX ASIC signature found\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
kilroy_was_here = 1;
|
||||
|
||||
/*
|
||||
* Reset some registers.
|
||||
*/
|
||||
|
||||
trix_write(0x13, 0);
|
||||
trix_write(0x14, 0);
|
||||
|
||||
/*
|
||||
* Configure the ASIC to place the codec to the proper I/O location
|
||||
*/
|
||||
|
||||
switch (hw_config->io_base) {
|
||||
case 0x530:
|
||||
addr_bits = 0;
|
||||
break;
|
||||
case 0x604:
|
||||
addr_bits = 1;
|
||||
break;
|
||||
case 0xE80:
|
||||
addr_bits = 2;
|
||||
break;
|
||||
case 0xF40:
|
||||
addr_bits = 3;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
trix_write(0x19, (trix_read(0x19) & 0x03) | addr_bits);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Probe and attach routines for the Windows Sound System mode of AudioTriX
|
||||
* Pro
|
||||
*/
|
||||
|
||||
int
|
||||
probe_trix_wss(struct address_info * hw_config)
|
||||
{
|
||||
/*
|
||||
* Check if the IO port returns valid signature. The original MS
|
||||
* Sound system returns 0x04 while some cards (AudioTriX Pro for
|
||||
* example) return 0x00.
|
||||
*/
|
||||
|
||||
if (0) {
|
||||
printf("AudioTriX: MSS I/O port conflict\n");
|
||||
return 0;
|
||||
}
|
||||
trix_osp = hw_config->osp;
|
||||
|
||||
if (!trix_set_wss_port(hw_config))
|
||||
return 0;
|
||||
|
||||
if ((inb(hw_config->io_base + 3) & 0x3f) != 0x00) {
|
||||
DDB(printf("No MSS signature detected on port 0x%x\n",
|
||||
hw_config->io_base));
|
||||
return 0;
|
||||
}
|
||||
if (hw_config->irq > 11) {
|
||||
printf("AudioTriX: Bad WSS IRQ %d\n", hw_config->irq);
|
||||
return 0;
|
||||
}
|
||||
if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3) {
|
||||
printf("AudioTriX: Bad WSS DMA %d\n", hw_config->dma);
|
||||
return 0;
|
||||
}
|
||||
if (hw_config->dma2 != -1)
|
||||
if (hw_config->dma2 != 0 && hw_config->dma2 != 1 && hw_config->dma2 != 3) {
|
||||
printf("AudioTriX: Bad capture DMA %d\n", hw_config->dma2);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Check that DMA0 is not in use with a 8 bit board.
|
||||
*/
|
||||
|
||||
if (hw_config->dma == 0 && inb(hw_config->io_base + 3) & 0x80) {
|
||||
printf("AudioTriX: Can't use DMA0 with a 8 bit card\n");
|
||||
return 0;
|
||||
}
|
||||
if (hw_config->irq > 7 && hw_config->irq != 9 && inb(hw_config->io_base + 3) & 0x80) {
|
||||
printf("AudioTriX: Can't use IRQ%d with a 8 bit card\n", hw_config->irq);
|
||||
return 0;
|
||||
}
|
||||
return ad1848_detect(hw_config->io_base + 4, NULL, hw_config->osp);
|
||||
}
|
||||
|
||||
void
|
||||
attach_trix_wss(struct address_info * hw_config)
|
||||
{
|
||||
static u_char interrupt_bits[12] =
|
||||
{-1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20};
|
||||
char bits;
|
||||
|
||||
static u_char dma_bits[4] =
|
||||
{1, 2, 0, 3};
|
||||
|
||||
int config_port = hw_config->io_base + 0,
|
||||
version_port = hw_config->io_base + 3;
|
||||
int dma1 = hw_config->dma, dma2 = hw_config->dma2;
|
||||
|
||||
trix_osp = hw_config->osp;
|
||||
|
||||
if (!kilroy_was_here) {
|
||||
DDB(printf("AudioTriX: Attach called but not probed yet???\n"));
|
||||
return ;
|
||||
}
|
||||
/*
|
||||
* Set the IRQ and DMA addresses.
|
||||
*/
|
||||
|
||||
bits = interrupt_bits[hw_config->irq];
|
||||
if (bits == -1) {
|
||||
printf("AudioTriX: Bad IRQ (%d)\n", hw_config->irq);
|
||||
return ;
|
||||
}
|
||||
outb(config_port, bits | 0x40);
|
||||
if ((inb(version_port) & 0x40) == 0)
|
||||
printf("[IRQ Conflict?]");
|
||||
|
||||
if (hw_config->dma2 == -1) { /* Single DMA mode */
|
||||
bits |= dma_bits[dma1];
|
||||
dma2 = dma1;
|
||||
} else {
|
||||
u_char tmp;
|
||||
|
||||
tmp = trix_read(0x13) & ~30;
|
||||
trix_write(0x13, tmp | 0x80 | (dma1 << 4));
|
||||
|
||||
tmp = trix_read(0x14) & ~30;
|
||||
trix_write(0x14, tmp | 0x80 | (dma2 << 4));
|
||||
}
|
||||
|
||||
outb(config_port, bits);/* Write IRQ+DMA setup */
|
||||
|
||||
ad1848_init("AudioTriX Pro", hw_config->io_base + 4,
|
||||
hw_config->irq,
|
||||
dma1,
|
||||
dma2,
|
||||
0,
|
||||
hw_config->osp);
|
||||
return ;
|
||||
}
|
||||
|
||||
int
|
||||
probe_trix_sb(struct address_info * hw_config)
|
||||
{
|
||||
int tmp;
|
||||
u_char conf;
|
||||
static char irq_translate[] = {-1, -1, -1, 0, 1, 2, -1, 3};
|
||||
|
||||
#ifndef INCLUDE_TRIX_BOOT
|
||||
return 0; /* No boot code -> no fun */
|
||||
#endif
|
||||
if (!kilroy_was_here)
|
||||
return 0; /* AudioTriX Pro has not been detected earlier */
|
||||
|
||||
if (sb_initialized)
|
||||
return 0;
|
||||
|
||||
if ((hw_config->io_base & 0xffffff8f) != 0x200)
|
||||
return 0;
|
||||
|
||||
tmp = hw_config->irq;
|
||||
if (tmp > 7)
|
||||
return 0;
|
||||
if (irq_translate[tmp] == -1)
|
||||
return 0;
|
||||
|
||||
tmp = hw_config->dma;
|
||||
if (tmp != 1 && tmp != 3)
|
||||
return 0;
|
||||
|
||||
conf = 0x84; /* DMA and IRQ enable */
|
||||
conf |= hw_config->io_base & 0x70; /* I/O address bits */
|
||||
conf |= irq_translate[hw_config->irq];
|
||||
if (hw_config->dma == 3)
|
||||
conf |= 0x08;
|
||||
trix_write(0x1b, conf);
|
||||
|
||||
download_boot(hw_config->io_base);
|
||||
sb_initialized = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
attach_trix_sb(struct address_info * hw_config)
|
||||
{
|
||||
#if (NSB > 0)
|
||||
sb_dsp_disable_midi();
|
||||
sb_no_recording = 1;
|
||||
#endif
|
||||
conf_printf("AudioTriX (SB)", hw_config);
|
||||
}
|
||||
|
||||
void
|
||||
attach_trix_mpu(struct address_info * hw_config)
|
||||
{
|
||||
#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
|
||||
attach_mpu401(hw_config);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
probe_trix_mpu(struct address_info * hw_config)
|
||||
{
|
||||
#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
|
||||
u_char conf;
|
||||
static char irq_bits[] = {-1, -1, -1, 1, 2, 3, -1, 4, -1, 5};
|
||||
|
||||
if (!kilroy_was_here) {
|
||||
DDB(printf("Trix: WSS and SB modes must be initialized before MPU\n"));
|
||||
return 0; /* AudioTriX Pro has not been detected earlier */
|
||||
}
|
||||
if (!sb_initialized) {
|
||||
DDB(printf("Trix: SB mode must be initialized before MPU\n"));
|
||||
return 0;
|
||||
}
|
||||
if (mpu_initialized) {
|
||||
DDB(printf("Trix: MPU mode already initialized\n"));
|
||||
return 0;
|
||||
}
|
||||
if (hw_config->irq > 9) {
|
||||
printf("AudioTriX: Bad MPU IRQ %d\n", hw_config->irq);
|
||||
return 0;
|
||||
}
|
||||
if (irq_bits[hw_config->irq] == -1) {
|
||||
printf("AudioTriX: Bad MPU IRQ %d\n", hw_config->irq);
|
||||
return 0;
|
||||
}
|
||||
switch (hw_config->io_base) {
|
||||
case 0x330:
|
||||
conf = 0x00;
|
||||
break;
|
||||
case 0x370:
|
||||
conf = 0x04;
|
||||
break;
|
||||
case 0x3b0:
|
||||
conf = 0x08;
|
||||
break;
|
||||
case 0x3f0:
|
||||
conf = 0x0c;
|
||||
break;
|
||||
default:
|
||||
return 0; /* Invalid port */
|
||||
}
|
||||
|
||||
conf |= irq_bits[hw_config->irq] << 4;
|
||||
|
||||
trix_write(0x19, (trix_read(0x19) & 0x83) | conf);
|
||||
|
||||
mpu_initialized = 1;
|
||||
|
||||
return probe_mpu401(hw_config);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,29 +0,0 @@
|
||||
#ifdef SEQUENCER_C
|
||||
|
||||
unsigned short semitone_tuning[24] =
|
||||
{
|
||||
/* 0 */ 10000, 10595, 11225, 11892, 12599, 13348, 14142, 14983,
|
||||
/* 8 */ 15874, 16818, 17818, 18877, 20000, 21189, 22449, 23784,
|
||||
/* 16 */ 25198, 26697, 28284, 29966, 31748, 33636, 35636, 37755
|
||||
};
|
||||
|
||||
unsigned short cent_tuning[100] =
|
||||
{
|
||||
/* 0 */ 10000, 10006, 10012, 10017, 10023, 10029, 10035, 10041,
|
||||
/* 8 */ 10046, 10052, 10058, 10064, 10070, 10075, 10081, 10087,
|
||||
/* 16 */ 10093, 10099, 10105, 10110, 10116, 10122, 10128, 10134,
|
||||
/* 24 */ 10140, 10145, 10151, 10157, 10163, 10169, 10175, 10181,
|
||||
/* 32 */ 10187, 10192, 10198, 10204, 10210, 10216, 10222, 10228,
|
||||
/* 40 */ 10234, 10240, 10246, 10251, 10257, 10263, 10269, 10275,
|
||||
/* 48 */ 10281, 10287, 10293, 10299, 10305, 10311, 10317, 10323,
|
||||
/* 56 */ 10329, 10335, 10341, 10347, 10353, 10359, 10365, 10371,
|
||||
/* 64 */ 10377, 10383, 10389, 10395, 10401, 10407, 10413, 10419,
|
||||
/* 72 */ 10425, 10431, 10437, 10443, 10449, 10455, 10461, 10467,
|
||||
/* 80 */ 10473, 10479, 10485, 10491, 10497, 10503, 10509, 10515,
|
||||
/* 88 */ 10521, 10528, 10534, 10540, 10546, 10552, 10558, 10564,
|
||||
/* 96 */ 10570, 10576, 10582, 10589
|
||||
};
|
||||
#else
|
||||
extern unsigned short semitone_tuning[24];
|
||||
extern unsigned short cent_tuning[100];
|
||||
#endif
|
@ -1,296 +0,0 @@
|
||||
/*
|
||||
* sound/uart6850.c
|
||||
*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Mon Nov 22 22:38:35 MET 1993 marco@driq.home.usn.nl: added 6850 support, used
|
||||
* with COVOX SoundMaster II and custom cards.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer. 2.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <i386/isa/sound/sound_config.h>
|
||||
|
||||
#if NSND > 0
|
||||
|
||||
#if 1
|
||||
/* #if defined(CONFIG_UART6850) && defined(CONFIG_MIDI) */
|
||||
|
||||
#define DATAPORT (uart6850_base) /* * * Midi6850 Data I/O Port on IBM */
|
||||
#define COMDPORT (uart6850_base+1) /* * * Midi6850 Command Port on IBM */
|
||||
#define STATPORT (uart6850_base+1) /* * * Midi6850 Status Port on IBM */
|
||||
|
||||
#define uart6850_status() inb( STATPORT)
|
||||
#define input_avail() (uart6850_status()&INPUT_AVAIL)
|
||||
#define output_ready() (uart6850_status()&OUTPUT_READY)
|
||||
#define uart6850_cmd(cmd) outb( COMDPORT, cmd)
|
||||
#define uart6850_read() inb( DATAPORT)
|
||||
#define uart6850_write(byte) outb( DATAPORT, byte)
|
||||
|
||||
#define OUTPUT_READY 0x02 /* * * Mask for Data Read Ready Bit */
|
||||
#define INPUT_AVAIL 0x01 /* * * Mask for Data Send Ready Bit */
|
||||
|
||||
#define UART_RESET 0x95 /* * * 6850 Total Reset Command */
|
||||
#define UART_MODE_ON 0x03 /* * * 6850 Send/Receive UART Mode */
|
||||
|
||||
static int uart6850_opened = 0;
|
||||
static int uart6850_base = 0x330;
|
||||
static int uart6850_irq;
|
||||
static int uart6850_detected = 0;
|
||||
static int my_dev;
|
||||
|
||||
static int reset_uart6850(void);
|
||||
static void (*midi_input_intr) (int dev, u_char data);
|
||||
static void poll_uart6850(void *dummy);
|
||||
|
||||
|
||||
static sound_os_info *uart6850_osp;
|
||||
|
||||
static void
|
||||
uart6850_input_loop(void)
|
||||
{
|
||||
int count;
|
||||
|
||||
count = 10;
|
||||
|
||||
while (count) /* Not timed out */
|
||||
if (input_avail()) {
|
||||
u_char c = uart6850_read();
|
||||
|
||||
count = 100;
|
||||
|
||||
if (uart6850_opened & OPEN_READ)
|
||||
midi_input_intr(my_dev, c);
|
||||
} else
|
||||
while (!input_avail() && count)
|
||||
count--;
|
||||
}
|
||||
|
||||
void
|
||||
m6850intr(int irq)
|
||||
{
|
||||
if (input_avail())
|
||||
uart6850_input_loop();
|
||||
}
|
||||
|
||||
/*
|
||||
* It looks like there is no input interrupts in the UART mode. Let's try
|
||||
* polling.
|
||||
*/
|
||||
|
||||
static void
|
||||
poll_uart6850(void * dummy)
|
||||
{
|
||||
u_long flags;
|
||||
|
||||
if (!(uart6850_opened & OPEN_READ))
|
||||
return; /* Device has been closed */
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
if (input_avail())
|
||||
uart6850_input_loop();
|
||||
|
||||
|
||||
timeout( poll_uart6850, 0, 1); /* Come back later */
|
||||
|
||||
splx(flags);
|
||||
}
|
||||
|
||||
static int
|
||||
uart6850_open(int dev, int mode,
|
||||
void (*input) (int dev, u_char data),
|
||||
void (*output) (int dev)
|
||||
)
|
||||
{
|
||||
if (uart6850_opened) {
|
||||
printf("Midi6850: Midi busy\n");
|
||||
return -(EBUSY);
|
||||
}
|
||||
uart6850_cmd(UART_RESET);
|
||||
|
||||
uart6850_input_loop();
|
||||
|
||||
midi_input_intr = input;
|
||||
uart6850_opened = mode;
|
||||
poll_uart6850(0); /* Enable input polling */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
uart6850_close(int dev)
|
||||
{
|
||||
uart6850_cmd(UART_MODE_ON);
|
||||
|
||||
uart6850_opened = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
uart6850_out(int dev, u_char midi_byte)
|
||||
{
|
||||
int timeout;
|
||||
u_long flags;
|
||||
|
||||
/*
|
||||
* Test for input since pending input seems to block the output.
|
||||
*/
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
if (input_avail())
|
||||
uart6850_input_loop();
|
||||
|
||||
splx(flags);
|
||||
|
||||
/*
|
||||
* Sometimes it takes about 13000 loops before the output becomes
|
||||
* ready (After reset). Normally it takes just about 10 loops.
|
||||
*/
|
||||
|
||||
for (timeout = 30000; timeout > 0 && !output_ready(); timeout--); /* Wait */
|
||||
|
||||
if (!output_ready()) {
|
||||
printf("Midi6850: Timeout\n");
|
||||
return 0;
|
||||
}
|
||||
uart6850_write(midi_byte);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
uart6850_command(int dev, u_char *midi_byte)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
uart6850_start_read(int dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
uart6850_end_read(int dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
uart6850_ioctl(int dev, u_int cmd, ioctl_arg arg)
|
||||
{
|
||||
return -(EINVAL);
|
||||
}
|
||||
|
||||
static void
|
||||
uart6850_kick(int dev)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
uart6850_buffer_status(int dev)
|
||||
{
|
||||
return 0; /* No data in buffers */
|
||||
}
|
||||
|
||||
#define MIDI_SYNTH_NAME "6850 UART Midi"
|
||||
#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
|
||||
#include <i386/isa/sound/midi_synth.h>
|
||||
|
||||
static struct midi_operations uart6850_operations =
|
||||
{
|
||||
{"6850 UART", 0, 0, SNDCARD_UART6850},
|
||||
&std_midi_synth,
|
||||
{0},
|
||||
uart6850_open,
|
||||
uart6850_close,
|
||||
uart6850_ioctl,
|
||||
uart6850_out,
|
||||
uart6850_start_read,
|
||||
uart6850_end_read,
|
||||
uart6850_kick,
|
||||
uart6850_command,
|
||||
uart6850_buffer_status
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
attach_uart6850(struct address_info * hw_config)
|
||||
{
|
||||
int ok, timeout;
|
||||
u_long flags;
|
||||
|
||||
if (num_midis >= MAX_MIDI_DEV) {
|
||||
printf("Sound: Too many midi devices detected\n");
|
||||
return ;
|
||||
}
|
||||
uart6850_base = hw_config->io_base;
|
||||
uart6850_osp = hw_config->osp;
|
||||
uart6850_irq = hw_config->irq;
|
||||
|
||||
if (!uart6850_detected)
|
||||
return ;
|
||||
|
||||
flags = splhigh();
|
||||
|
||||
for (timeout = 30000; timeout < 0 && !output_ready(); timeout--); /* Wait */
|
||||
uart6850_cmd(UART_MODE_ON);
|
||||
|
||||
ok = 1;
|
||||
|
||||
splx(flags);
|
||||
|
||||
conf_printf("6850 Midi Interface", hw_config);
|
||||
|
||||
std_midi_synth.midi_dev = my_dev = num_midis;
|
||||
midi_devs[num_midis++] = &uart6850_operations;
|
||||
return ;
|
||||
}
|
||||
|
||||
static int
|
||||
reset_uart6850(void)
|
||||
{
|
||||
uart6850_read();
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
probe_uart6850(struct address_info * hw_config)
|
||||
{
|
||||
int ok = 0;
|
||||
|
||||
uart6850_osp = hw_config->osp;
|
||||
uart6850_base = hw_config->io_base;
|
||||
uart6850_irq = hw_config->irq;
|
||||
|
||||
if (snd_set_irq_handler(uart6850_irq, m6850intr, uart6850_osp) < 0)
|
||||
return 0;
|
||||
|
||||
ok = reset_uart6850();
|
||||
|
||||
uart6850_detected = ok;
|
||||
return ok;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
@ -1,71 +0,0 @@
|
||||
static unsigned char ulaw_dsp[] = {
|
||||
3, 7, 11, 15, 19, 23, 27, 31,
|
||||
35, 39, 43, 47, 51, 55, 59, 63,
|
||||
66, 68, 70, 72, 74, 76, 78, 80,
|
||||
82, 84, 86, 88, 90, 92, 94, 96,
|
||||
98, 99, 100, 101, 102, 103, 104, 105,
|
||||
106, 107, 108, 109, 110, 111, 112, 113,
|
||||
113, 114, 114, 115, 115, 116, 116, 117,
|
||||
117, 118, 118, 119, 119, 120, 120, 121,
|
||||
121, 121, 122, 122, 122, 122, 123, 123,
|
||||
123, 123, 124, 124, 124, 124, 125, 125,
|
||||
125, 125, 125, 125, 126, 126, 126, 126,
|
||||
126, 126, 126, 126, 127, 127, 127, 127,
|
||||
127, 127, 127, 127, 127, 127, 127, 127,
|
||||
128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128,
|
||||
253, 249, 245, 241, 237, 233, 229, 225,
|
||||
221, 217, 213, 209, 205, 201, 197, 193,
|
||||
190, 188, 186, 184, 182, 180, 178, 176,
|
||||
174, 172, 170, 168, 166, 164, 162, 160,
|
||||
158, 157, 156, 155, 154, 153, 152, 151,
|
||||
150, 149, 148, 147, 146, 145, 144, 143,
|
||||
143, 142, 142, 141, 141, 140, 140, 139,
|
||||
139, 138, 138, 137, 137, 136, 136, 135,
|
||||
135, 135, 134, 134, 134, 134, 133, 133,
|
||||
133, 133, 132, 132, 132, 132, 131, 131,
|
||||
131, 131, 131, 131, 130, 130, 130, 130,
|
||||
130, 130, 130, 130, 129, 129, 129, 129,
|
||||
129, 129, 129, 129, 129, 129, 129, 129,
|
||||
128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128,
|
||||
};
|
||||
|
||||
#ifndef DSP_ULAW_NOT_WANTED
|
||||
static unsigned char dsp_ulaw[] = {
|
||||
0, 0, 0, 0, 0, 1, 1, 1,
|
||||
1, 2, 2, 2, 2, 3, 3, 3,
|
||||
3, 4, 4, 4, 4, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 7, 7, 7,
|
||||
7, 8, 8, 8, 8, 9, 9, 9,
|
||||
9, 10, 10, 10, 10, 11, 11, 11,
|
||||
11, 12, 12, 12, 12, 13, 13, 13,
|
||||
13, 14, 14, 14, 14, 15, 15, 15,
|
||||
15, 16, 16, 17, 17, 18, 18, 19,
|
||||
19, 20, 20, 21, 21, 22, 22, 23,
|
||||
23, 24, 24, 25, 25, 26, 26, 27,
|
||||
27, 28, 28, 29, 29, 30, 30, 31,
|
||||
31, 32, 33, 34, 35, 36, 37, 38,
|
||||
39, 40, 41, 42, 43, 44, 45, 46,
|
||||
47, 49, 51, 53, 55, 57, 59, 61,
|
||||
63, 66, 70, 74, 78, 84, 92, 104,
|
||||
254, 231, 219, 211, 205, 201, 197, 193,
|
||||
190, 188, 186, 184, 182, 180, 178, 176,
|
||||
175, 174, 173, 172, 171, 170, 169, 168,
|
||||
167, 166, 165, 164, 163, 162, 161, 160,
|
||||
159, 159, 158, 158, 157, 157, 156, 156,
|
||||
155, 155, 154, 154, 153, 153, 152, 152,
|
||||
151, 151, 150, 150, 149, 149, 148, 148,
|
||||
147, 147, 146, 146, 145, 145, 144, 144,
|
||||
143, 143, 143, 143, 142, 142, 142, 142,
|
||||
141, 141, 141, 141, 140, 140, 140, 140,
|
||||
139, 139, 139, 139, 138, 138, 138, 138,
|
||||
137, 137, 137, 137, 136, 136, 136, 136,
|
||||
135, 135, 135, 135, 134, 134, 134, 134,
|
||||
133, 133, 133, 133, 132, 132, 132, 132,
|
||||
131, 131, 131, 131, 130, 130, 130, 130,
|
||||
129, 129, 129, 129, 128, 128, 128, 128,
|
||||
};
|
||||
#endif /* !DSP_ULAW_NOT_WANTED */
|
@ -1,137 +0,0 @@
|
||||
#ifndef _ULTRASOUND_H_
|
||||
#define _ULTRASOUND_H_
|
||||
/*
|
||||
* Copyright by Hannu Savolainen 1993
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* ultrasound.h - Macros for programming the Gravis Ultrasound
|
||||
* These macros are extremely device dependent
|
||||
* and not portable.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Private events for Gravis Ultrasound (GUS)
|
||||
*
|
||||
* Format:
|
||||
* byte 0 - SEQ_PRIVATE (0xfe)
|
||||
* byte 1 - Synthesizer device number (0-N)
|
||||
* byte 2 - Command (see below)
|
||||
* byte 3 - Voice number (0-31)
|
||||
* bytes 4 and 5 - parameter P1 (u_short)
|
||||
* bytes 6 and 7 - parameter P2 (u_short)
|
||||
*
|
||||
* Commands:
|
||||
* Each command affects one voice defined in byte 3.
|
||||
* Unused parameters (P1 and/or P2 *MUST* be initialized to zero).
|
||||
* _GUS_NUMVOICES - Sets max. number of concurrent voices (P1=14-31, default 16)
|
||||
* _GUS_VOICESAMPLE- ************ OBSOLETE *************
|
||||
* _GUS_VOICEON - Starts voice (P1=voice mode)
|
||||
* _GUS_VOICEOFF - Stops voice (no parameters)
|
||||
* _GUS_VOICEFADE - Stops the voice smoothly.
|
||||
* _GUS_VOICEMODE - Alters the voice mode, don't start or stop voice (P1=voice mode)
|
||||
* _GUS_VOICEBALA - Sets voice balence (P1, 0=left, 7=middle and 15=right, default 7)
|
||||
* _GUS_VOICEFREQ - Sets voice (sample) playback frequency (P1=Hz)
|
||||
* _GUS_VOICEVOL - Sets voice volume (P1=volume, 0xfff=max, 0xeff=half, 0x000=off)
|
||||
* _GUS_VOICEVOL2 - Sets voice volume (P1=volume, 0xfff=max, 0xeff=half, 0x000=off)
|
||||
* (Like GUS_VOICEVOL but doesn't change the hw
|
||||
* volume. It just updates volume in the voice table).
|
||||
*
|
||||
* _GUS_RAMPRANGE - Sets limits for volume ramping (P1=low volume, P2=high volume)
|
||||
* _GUS_RAMPRATE - Sets the speed for volume ramping (P1=scale, P2=rate)
|
||||
* _GUS_RAMPMODE - Sets the volume ramping mode (P1=ramping mode)
|
||||
* _GUS_RAMPON - Starts volume ramping (no parameters)
|
||||
* _GUS_RAMPOFF - Stops volume ramping (no parameters)
|
||||
* _GUS_VOLUME_SCALE - Changes the volume calculation constants
|
||||
* for all voices.
|
||||
*/
|
||||
|
||||
#define _GUS_NUMVOICES 0x00
|
||||
#define _GUS_VOICESAMPLE 0x01 /* OBSOLETE */
|
||||
#define _GUS_VOICEON 0x02
|
||||
#define _GUS_VOICEOFF 0x03
|
||||
#define _GUS_VOICEMODE 0x04
|
||||
#define _GUS_VOICEBALA 0x05
|
||||
#define _GUS_VOICEFREQ 0x06
|
||||
#define _GUS_VOICEVOL 0x07
|
||||
#define _GUS_RAMPRANGE 0x08
|
||||
#define _GUS_RAMPRATE 0x09
|
||||
#define _GUS_RAMPMODE 0x0a
|
||||
#define _GUS_RAMPON 0x0b
|
||||
#define _GUS_RAMPOFF 0x0c
|
||||
#define _GUS_VOICEFADE 0x0d
|
||||
#define _GUS_VOLUME_SCALE 0x0e
|
||||
#define _GUS_VOICEVOL2 0x0f
|
||||
#define _GUS_VOICE_POS 0x10
|
||||
|
||||
/*
|
||||
* GUS API macros
|
||||
*/
|
||||
|
||||
#define _GUS_CMD(chn, voice, cmd, p1, p2) {\
|
||||
_SEQ_NEEDBUF(8); _seqbuf[_seqbufptr] = SEQ_PRIVATE;\
|
||||
_seqbuf[_seqbufptr+1] = (chn); _seqbuf[_seqbufptr+2] = cmd;\
|
||||
_seqbuf[_seqbufptr+3] = voice;\
|
||||
*(u_short*)&_seqbuf[_seqbufptr+4] = p1;\
|
||||
*(u_short*)&_seqbuf[_seqbufptr+6] = p2;\
|
||||
_SEQ_ADVBUF(8);}
|
||||
|
||||
#define GUS_NUMVOICES(chn, p1) _GUS_CMD(chn, 0, _GUS_NUMVOICES, (p1), 0)
|
||||
#define GUS_VOICESAMPLE(chn, voice, p1) \
|
||||
_GUS_CMD(chn, voice, _GUS_VOICESAMPLE, (p1), 0) /* OBSOLETE */
|
||||
#define GUS_VOICEON(chn, voice, p1) \
|
||||
_GUS_CMD(chn, voice, _GUS_VOICEON, (p1), 0)
|
||||
#define GUS_VOICEOFF(chn, voice) \
|
||||
_GUS_CMD(chn, voice, _GUS_VOICEOFF, 0, 0)
|
||||
#define GUS_VOICEFADE(chn, voice) \
|
||||
_GUS_CMD(chn, voice, _GUS_VOICEFADE, 0, 0)
|
||||
#define GUS_VOICEMODE(chn, voice, p1) \
|
||||
_GUS_CMD(chn, voice, _GUS_VOICEMODE, (p1), 0)
|
||||
#define GUS_VOICEBALA(chn, voice, p1) \
|
||||
_GUS_CMD(chn, voice, _GUS_VOICEBALA, (p1), 0)
|
||||
#define GUS_VOICEFREQ(chn, voice, p) \
|
||||
_GUS_CMD(chn, voice, _GUS_VOICEFREQ, \
|
||||
(p) & 0xffff, ((p) >> 16) & 0xffff)
|
||||
#define GUS_VOICEVOL(chn, voice, p1) \
|
||||
_GUS_CMD(chn, voice, _GUS_VOICEVOL, (p1), 0)
|
||||
#define GUS_VOICEVOL2(chn, voice, p1) \
|
||||
_GUS_CMD(chn, voice, _GUS_VOICEVOL2, (p1), 0)
|
||||
#define GUS_RAMPRANGE(chn, voice, low, high) \
|
||||
_GUS_CMD(chn, voice, _GUS_RAMPRANGE, (low), (high))
|
||||
#define GUS_RAMPRATE(chn, voice, p1, p2) \
|
||||
_GUS_CMD(chn, voice, _GUS_RAMPRATE, (p1), (p2))
|
||||
#define GUS_RAMPMODE(chn, voice, p1) \
|
||||
_GUS_CMD(chn, voice, _GUS_RAMPMODE, (p1), 0)
|
||||
#define GUS_RAMPON(chn, voice, p1) \
|
||||
_GUS_CMD(chn, voice, _GUS_RAMPON, (p1), 0)
|
||||
#define GUS_RAMPOFF(chn, voice) \
|
||||
_GUS_CMD(chn, voice, _GUS_RAMPOFF, 0, 0)
|
||||
#define GUS_VOLUME_SCALE(chn, voice, p1, p2) \
|
||||
_GUS_CMD(chn, voice, _GUS_VOLUME_SCALE, (p1), (p2))
|
||||
#define GUS_VOICE_POS(chn, voice, p) \
|
||||
_GUS_CMD(chn, voice, _GUS_VOICE_POS, \
|
||||
(p) & 0xffff, ((p) >> 16) & 0xffff)
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user