Emuxki BeOS Driver for Creative Labs SBLive!/Audigy series.
Written by Jerome Duval. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2936 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
SubDir OBOS_TOP src add-ons kernel drivers audio emuxki ;
|
||||
|
||||
R5KernelAddon emuxki : kernel drivers bin :
|
||||
ac97.c
|
||||
debug.c
|
||||
emuxki.c
|
||||
io.c
|
||||
midi.c
|
||||
multi.c
|
||||
util.c
|
||||
;
|
||||
|
||||
# Link to kernel/drivers/dev/audio/multi
|
||||
{
|
||||
local dir = [ FDirName $(OBOS_ADDON_DIR) kernel drivers dev audio multi ] ;
|
||||
local instDriver = <kernel!drivers!dev!audio!multi>emuxki ;
|
||||
MakeLocate $(instDriver) : $(dir) ;
|
||||
RelSymLink $(instDriver) : emuxki ;
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Emuxki BeOS Driver for Creative Labs SBLive!/Audigy series
|
||||
*
|
||||
* Copyright (c) 2002, Jerome Duval ([email protected])
|
||||
*
|
||||
* Original code : BeOS Driver for Intel ICH AC'97 Link interface
|
||||
* Copyright (c) 2002, Marcus Overhagen <[email protected]>
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 <OS.h>
|
||||
#include <stdio.h>
|
||||
#include <MediaDefs.h>
|
||||
#include "ac97.h"
|
||||
|
||||
#define REVERSE_EAMP_POLARITY 0
|
||||
|
||||
#include "debug.h"
|
||||
#include "io.h"
|
||||
|
||||
#define B_UTF8_REGISTERED "\xC2\xAE"
|
||||
|
||||
const char * stereo_enhancement_technique[] =
|
||||
{
|
||||
"No 3D Stereo Enhancement",
|
||||
"Analog Devices",
|
||||
"Creative Technology",
|
||||
"National Semiconductor",
|
||||
"Yamaha",
|
||||
"BBE Sound",
|
||||
"Crystal Semiconductor",
|
||||
"Qsound Labs",
|
||||
"Spatializer Audio Laboratories",
|
||||
"SRS Labs",
|
||||
"Platform Tech",
|
||||
"AKM Semiconductor",
|
||||
"Aureal",
|
||||
"Aztech Labs",
|
||||
"Binaura",
|
||||
"ESS Technology",
|
||||
"Harman International",
|
||||
"Nvidea",
|
||||
"Philips",
|
||||
"Texas Instruments",
|
||||
"VLSI Technology",
|
||||
"TriTech",
|
||||
"Realtek",
|
||||
"Samsung",
|
||||
"Wolfson Microelectronics",
|
||||
"Delta Integration",
|
||||
"SigmaTel",
|
||||
"KS Waves",
|
||||
"Rockwell",
|
||||
"Unknown (29)",
|
||||
"Unknown (30)",
|
||||
"Unknown (31)"
|
||||
};
|
||||
|
||||
typedef void (* codec_init)(device_config *);
|
||||
typedef void (* codec_amp_enable)(device_config *, bool);
|
||||
|
||||
typedef struct codec_ops_tag
|
||||
{
|
||||
codec_init init;
|
||||
codec_amp_enable amp_enable;
|
||||
} codec_ops;
|
||||
|
||||
typedef struct codec_table_tag
|
||||
{
|
||||
uint32 id;
|
||||
uint32 mask;
|
||||
codec_ops *ops;
|
||||
const char *info;
|
||||
} codec_table;
|
||||
|
||||
void default_init(device_config *);
|
||||
void ad1886_init(device_config *);
|
||||
|
||||
void default_amp_enable(device_config *, bool);
|
||||
void cs4299_amp_enable(device_config *, bool);
|
||||
|
||||
codec_ops default_ops = { default_init, default_amp_enable };
|
||||
codec_ops ad1886_ops = { ad1886_init, default_amp_enable };
|
||||
codec_ops cs4299_ops = { default_init, cs4299_amp_enable };
|
||||
|
||||
codec_table codecs[] =
|
||||
{
|
||||
/* Vendor ID and description imported from FreeBSD src/sys/dev/sound/pcm/ac97.c */
|
||||
{ 0x414b4d00, 0xffffffff, &default_ops, "Asahi Kasei AK4540" },
|
||||
{ 0x414b4d01, 0xffffffff, &default_ops, "Asahi Kasei AK4542" },
|
||||
{ 0x414b4d02, 0xffffffff, &default_ops, "Asahi Kasei AK4543" },
|
||||
{ 0x43525900, 0xffffffff, &default_ops, "Cirrus Logic CS4297" },
|
||||
{ 0x43525903, 0xffffffff, &default_ops, "Cirrus Logic CS4297" },
|
||||
{ 0x43525913, 0xffffffff, &default_ops, "Cirrus Logic CS4297A" },
|
||||
{ 0x43525914, 0xffffffff, &default_ops, "Cirrus Logic CS4297B" },
|
||||
{ 0x43525923, 0xffffffff, &default_ops, "Cirrus Logic CS4294C" },
|
||||
{ 0x4352592b, 0xffffffff, &default_ops, "Cirrus Logic CS4298C" },
|
||||
{ 0x43525931, 0xffffffff, &cs4299_ops, "Cirrus Logic CS4299A" },
|
||||
{ 0x43525933, 0xffffffff, &cs4299_ops, "Cirrus Logic CS4299C" },
|
||||
{ 0x43525934, 0xffffffff, &cs4299_ops, "Cirrus Logic CS4299D" },
|
||||
{ 0x43525941, 0xffffffff, &default_ops, "Cirrus Logic CS4201A" },
|
||||
{ 0x43525951, 0xffffffff, &default_ops, "Cirrus Logic CS4205A" },
|
||||
{ 0x43525961, 0xffffffff, &default_ops, "Cirrus Logic CS4291A" },
|
||||
{ 0x45838308, 0xffffffff, &default_ops, "ESS Technology ES1921" },
|
||||
{ 0x49434511, 0xffffffff, &default_ops, "ICEnsemble ICE1232" },
|
||||
{ 0x4e534331, 0xffffffff, &default_ops, "National Semiconductor LM4549" },
|
||||
{ 0x83847600, 0xffffffff, &default_ops, "SigmaTel STAC9700/9783/9784" },
|
||||
{ 0x83847604, 0xffffffff, &default_ops, "SigmaTel STAC9701/9703/9704/9705" },
|
||||
{ 0x83847605, 0xffffffff, &default_ops, "SigmaTel STAC9704" },
|
||||
{ 0x83847608, 0xffffffff, &default_ops, "SigmaTel STAC9708/9711" },
|
||||
{ 0x83847609, 0xffffffff, &default_ops, "SigmaTel STAC9721/9723" },
|
||||
{ 0x83847644, 0xffffffff, &default_ops, "SigmaTel STAC9744" },
|
||||
{ 0x83847656, 0xffffffff, &default_ops, "SigmaTel STAC9756/9757" },
|
||||
{ 0x53494c22, 0xffffffff, &default_ops, "Silicon Laboratory Si3036" },
|
||||
{ 0x53494c23, 0xffffffff, &default_ops, "Silicon Laboratory Si3038" },
|
||||
{ 0x54524103, 0xffffffff, &default_ops, "TriTech TR?????" },
|
||||
{ 0x54524106, 0xffffffff, &default_ops, "TriTech TR28026" },
|
||||
{ 0x54524108, 0xffffffff, &default_ops, "TriTech TR28028" },
|
||||
{ 0x54524123, 0xffffffff, &default_ops, "TriTech TR28602" },
|
||||
{ 0x574d4c00, 0xffffffff, &default_ops, "Wolfson WM9701A" },
|
||||
{ 0x574d4c03, 0xffffffff, &default_ops, "Wolfson WM9703/9704" },
|
||||
{ 0x574d4c04, 0xffffffff, &default_ops, "Wolfson WM9704 (quad)" },
|
||||
/* Assembled from datasheets: */
|
||||
{ 0x41445303, 0xffffffff, &default_ops, "Analog Devices AD1819B SoundPort"B_UTF8_REGISTERED },
|
||||
{ 0x41445340, 0xffffffff, &default_ops, "Analog Devices AD1881 SoundMAX"B_UTF8_REGISTERED },
|
||||
{ 0x41445348, 0xffffffff, &default_ops, "Analog Devices AD1881A SoundMAX"B_UTF8_REGISTERED },
|
||||
{ 0x41445360, 0xffffffff, &default_ops, "Analog Devices AD1885 SoundMAX"B_UTF8_REGISTERED },
|
||||
{ 0x41445361, 0xffffffff, &ad1886_ops, "Analog Devices AD1886 SoundMAX"B_UTF8_REGISTERED },
|
||||
{ 0x41445362, 0xffffffff, &default_ops, "Analog Devices AD1887 SoundMAX"B_UTF8_REGISTERED },
|
||||
{ 0x41445363, 0xffffffff, &default_ops, "Analog Devices AD1886A SoundMAX"B_UTF8_REGISTERED },
|
||||
{ 0x41445371, 0xffffffff, &default_ops, "Analog Devices AD1981A SoundMAX"B_UTF8_REGISTERED },
|
||||
{ 0x41445372, 0xffffffff, &default_ops, "Analog Devices AD1981A SoundMAX"B_UTF8_REGISTERED },
|
||||
{ 0x414c4320, 0xfffffff0, &default_ops, "Avance Logic (Realtek) ALC100/ALC100P, RL5383/RL5522" },
|
||||
{ 0x414c4730, 0xffffffff, &default_ops, "Avance Logic (Realtek) ALC101" },
|
||||
#if 0
|
||||
{ 0x414c4710, 0xffffffff, &default_ops, "Avance Logic (Realtek) ALC200/ALC200A" }, /* datasheet says id2 = 4710 */
|
||||
{ 0x414c4710, 0xffffffff, &default_ops, "Avance Logic (Realtek) ALC201/ALC201A" }, /* 4710 or 4720 */
|
||||
{ 0x414c4720, 0xffffffff, &default_ops, "Avance Logic (Realtek) ALC650" }, /* datasheet says id2 = 4720 */
|
||||
#else
|
||||
{ 0x414c4710, 0xffffffff, &default_ops, "Avance Logic (Realtek) ALC200/ALC200A or ALC201/ALC201A" },
|
||||
{ 0x414c4720, 0xffffffff, &default_ops, "Avance Logic (Realtek) ALC650 or ALC201/ALC201A" },
|
||||
#endif
|
||||
{ 0x414c4740, 0xffffffff, &default_ops, "Avance Logic (Realtek) ALC202/ALC202A" },
|
||||
/* Vendors only: */
|
||||
{ 0x41445300, 0xffffff00, &default_ops, "Analog Devices" },
|
||||
{ 0x414b4d00, 0xffffff00, &default_ops, "Asahi Kasei" },
|
||||
{ 0x414c4700, 0xffffff00, &default_ops, "Avance Logic (Realtek)" },
|
||||
{ 0x43525900, 0xffffff00, &default_ops, "Cirrus Logic" },
|
||||
{ 0x45838300, 0xffffff00, &default_ops, "ESS Technology" },
|
||||
{ 0x49434500, 0xffffff00, &default_ops, "ICEnsemble" },
|
||||
{ 0x4e534300, 0xffffff00, &default_ops, "National Semiconductor" },
|
||||
{ 0x83847600, 0xffffff00, &default_ops, "SigmaTel" },
|
||||
{ 0x53494c00, 0xffffff00, &default_ops, "Silicon Laboratory" },
|
||||
{ 0x54524100, 0xffffff00, &default_ops, "TriTech" },
|
||||
{ 0x574d4c00, 0xffffff00, &default_ops, "Wolfson" },
|
||||
{ 0x00000000, 0x00000000, &default_ops, "Unknown" } /* must be last one, matches every codec */
|
||||
};
|
||||
|
||||
codec_table *
|
||||
find_codec_table(uint32 codecid)
|
||||
{
|
||||
codec_table *codec;
|
||||
for (codec = codecs; codec->id; codec++)
|
||||
if ((codec->id & codec->mask) == (codecid & codec->mask))
|
||||
break;
|
||||
return codec;
|
||||
}
|
||||
|
||||
const char *
|
||||
ac97_get_3d_stereo_enhancement(device_config *config)
|
||||
{
|
||||
uint16 data;
|
||||
data = emuxki_codec_read(config, AC97_RESET);
|
||||
data = (data >> 10) & 31;
|
||||
return stereo_enhancement_technique[data];
|
||||
}
|
||||
|
||||
const char *
|
||||
ac97_get_vendor_id_description()
|
||||
{
|
||||
uint32 id = ac97_get_vendor_id();
|
||||
codec_table *codec = find_codec_table(id);
|
||||
char f = (id >> 24) & 0xff;
|
||||
char s = (id >> 16) & 0xff;
|
||||
char t = (id >> 8) & 0xff;
|
||||
if (f == 0) f = '?';
|
||||
if (s == 0) s = '?';
|
||||
if (t == 0) t = '?';
|
||||
LOG(("codec %c%c%c %u\n",f,s,t,id & 0xff));
|
||||
LOG(("info: %s\n",codec->info));
|
||||
return codec->info;
|
||||
}
|
||||
|
||||
uint32
|
||||
ac97_get_vendor_id(device_config *config)
|
||||
{
|
||||
uint16 data1;
|
||||
uint16 data2;
|
||||
data1 = emuxki_codec_read(config, AC97_VENDOR_ID1);
|
||||
data2 = emuxki_codec_read(config, AC97_VENDOR_ID2);
|
||||
return (((uint32)data1) << 16) | data2;
|
||||
}
|
||||
|
||||
void
|
||||
ac97_amp_enable(device_config *config, bool yesno)
|
||||
{
|
||||
codec_table *codec;
|
||||
LOG(("ac97_amp_enable\n"));
|
||||
codec = find_codec_table(ac97_get_vendor_id(config));
|
||||
codec->ops->amp_enable(config, yesno);
|
||||
}
|
||||
|
||||
void
|
||||
ac97_init(device_config *config)
|
||||
{
|
||||
codec_table *codec;
|
||||
LOG(("ac97_init\n"));
|
||||
codec = find_codec_table(ac97_get_vendor_id(config));
|
||||
codec->ops->init(config);
|
||||
}
|
||||
|
||||
void default_init(device_config *config)
|
||||
{
|
||||
LOG(("default_init\n"));
|
||||
}
|
||||
|
||||
void ad1886_init(device_config *config)
|
||||
{
|
||||
LOG(("ad1886_init\n"));
|
||||
emuxki_codec_write(config, 0x72, 0x0010);
|
||||
}
|
||||
|
||||
void default_amp_enable(device_config *config, bool yesno)
|
||||
{
|
||||
LOG(("default_amp_enable\n"));
|
||||
LOG(("powerdown register was = %#04x\n",emuxki_codec_read(config, AC97_POWERDOWN)));
|
||||
#if REVERSE_EAMP_POLARITY
|
||||
yesno = !yesno;
|
||||
LOG(("using reverse eamp polarity\n"));
|
||||
#endif
|
||||
if (yesno)
|
||||
emuxki_codec_write(config, AC97_POWERDOWN, emuxki_codec_read(config, AC97_POWERDOWN) & ~0x8000); /* switch on (low active) */
|
||||
else
|
||||
emuxki_codec_write(config, AC97_POWERDOWN, emuxki_codec_read(config, AC97_POWERDOWN) | 0x8000); /* switch off */
|
||||
LOG(("powerdown register is = %#04x\n", emuxki_codec_read(config, AC97_POWERDOWN)));
|
||||
}
|
||||
|
||||
void cs4299_amp_enable(device_config *config, bool yesno)
|
||||
{
|
||||
LOG(("cs4299_amp_enable\n"));
|
||||
if (yesno)
|
||||
emuxki_codec_write(config, 0x68, 0x8004);
|
||||
else
|
||||
emuxki_codec_write(config, 0x68, 0);
|
||||
}
|
||||
|
||||
const ac97_source_info source_info[] = {
|
||||
{ "Record", B_MIX_GAIN|B_MIX_MUTE|B_MIX_STEREO|B_MIX_RECORDMUX, 100, AC97_RECORD_GAIN, 0x8000, 4, 0, 1, 0, 0.0, 22.5, 1.5 },
|
||||
{ "Master", B_MIX_GAIN|B_MIX_MUTE|B_MIX_STEREO, 101, AC97_MASTER_VOLUME, 0x8000, 5, 0, 1, 1,-46.5, 0.0, 1.5 },
|
||||
//{ "Bass/Trebble", B_MIX_GAIN|B_MIX_STEREO, 102, AC97_MASTER_TONE, 0x0f0f, 4, 0, 1, 1,-12.0, 10.5, 1.5 },
|
||||
//{ "Aux Out", B_MIX_GAIN|B_MIX_MUTE|B_MIX_STEREO, 103, AC97_AUX_OUT_VOLUME, 0x8000, 5, 0, 1, 1,-46.5, 0.0, 1.5 },
|
||||
{ "PCM Out", B_MIX_GAIN|B_MIX_MUTE|B_MIX_STEREO, 104, AC97_PCM_OUT_VOLUME, 0x8808, 5, 0, 1, 1,-34.5, 12.0, 1.5 },
|
||||
{ "CD", B_MIX_GAIN|B_MIX_MUTE|B_MIX_STEREO, 105, AC97_CD_VOLUME, 0x8808, 5, 0, 1, 1,-34.5, 12.0, 1.5 },
|
||||
{ "Aux In", B_MIX_GAIN|B_MIX_MUTE|B_MIX_STEREO, 106, AC97_AUX_IN_VOLUME, 0x8808, 5, 0, 1, 1,-34.5, 12.0, 1.5 },
|
||||
{ "TAD", B_MIX_GAIN|B_MIX_MUTE|B_MIX_MONO, 107, AC97_PHONE_VOLUME, 0x8008, 5, 0, 1, 1,-34.5, 12.0, 1.5 },
|
||||
{ "Mic", B_MIX_GAIN|B_MIX_MUTE|B_MIX_MONO|B_MIX_MICBOOST, 108, AC97_MIC_VOLUME, 0x8008, 5, 0, 1, 1,-34.5, 12.0, 1.5 },
|
||||
{ "Line In", B_MIX_GAIN|B_MIX_MUTE|B_MIX_STEREO, 109, AC97_LINE_IN_VOLUME, 0x8808, 5, 0, 1, 1,-34.5, 12.0, 1.5 },
|
||||
//{ "Center/Lfe", B_MIX_GAIN|B_MIX_MUTE|B_MIX_STEREO, 111, AC97_CENTER_LFE_VOLUME, 0x8080, 5, 0, 1, 1,-46.5, 0.0, 1.5 },
|
||||
{ "Center/Lfe" /* should be "Surround" but no */, B_MIX_GAIN|B_MIX_MUTE|B_MIX_STEREO, 110, AC97_SURROUND_VOLUME, 0x8080, 5, 0, 1, 1,-46.5, 0.0, 1.5 }
|
||||
};
|
||||
|
||||
const int32 source_info_size = (sizeof(source_info)/sizeof(source_info[0]));
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Emuxki BeOS Driver for Creative Labs SBLive!/Audigy series
|
||||
*
|
||||
* Copyright (c) 2002, Jerome Duval ([email protected])
|
||||
*
|
||||
* Original code : BeOS Driver for Intel ICH AC'97 Link interface
|
||||
* Copyright (c) 2002, Marcus Overhagen <[email protected]>
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _AC97_H_
|
||||
#define _AC97_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
enum AC97_REGISTER {
|
||||
AC97_RESET = 0x00,
|
||||
AC97_MASTER_VOLUME = 0x02,
|
||||
AC97_AUX_OUT_VOLUME = 0x04,
|
||||
AC97_MONO_VOLUME = 0x06,
|
||||
AC97_MASTER_TONE = 0x08,
|
||||
AC97_PC_BEEP_VOLUME = 0x0A,
|
||||
AC97_PHONE_VOLUME = 0x0C,
|
||||
AC97_MIC_VOLUME = 0x0E,
|
||||
AC97_LINE_IN_VOLUME = 0x10,
|
||||
AC97_CD_VOLUME = 0x12,
|
||||
AC97_VIDEO_VOLUME = 0x14,
|
||||
AC97_AUX_IN_VOLUME = 0x16,
|
||||
AC97_PCM_OUT_VOLUME = 0x18,
|
||||
AC97_RECORD_SELECT = 0x1A,
|
||||
AC97_RECORD_GAIN = 0x1C,
|
||||
AC97_RECORD_GAIN_MIC = 0x1E,
|
||||
AC97_GENERAL_PURPOSE = 0x20,
|
||||
AC97_3D_CONTROL = 0x22,
|
||||
AC97_PAGING = 0x24,
|
||||
AC97_POWERDOWN = 0x26,
|
||||
AC97_EXTENDED_AUDIO_ID = 0x28,
|
||||
AC97_EXTENDED_AUDIO_STATUS = 0x2A,
|
||||
AC97_PCM_FRONT_DAC_RATE = 0x2C,
|
||||
AC97_PCM_SURR_DAC_RATE = 0x2E,
|
||||
AC97_PCM_LFE_DAC_RATE = 0x30,
|
||||
AC97_PCM_LR_ADC_RATE = 0x32,
|
||||
AC97_MIC_ADC_RATE = 0x34,
|
||||
AC97_CENTER_LFE_VOLUME = 0x36,
|
||||
AC97_SURROUND_VOLUME = 0x38,
|
||||
AC97_SPDIF_CONTROL = 0x3A,
|
||||
AC97_VENDOR_ID1 = 0x7C,
|
||||
AC97_VENDOR_ID2 = 0x7E
|
||||
};
|
||||
|
||||
const char * ac97_get_3d_stereo_enhancement();
|
||||
const char * ac97_get_vendor_id_description();
|
||||
uint32 ac97_get_vendor_id();
|
||||
void ac97_init();
|
||||
|
||||
void ac97_amp_enable(device_config *config, bool yesno);
|
||||
|
||||
typedef enum {
|
||||
B_MIX_GAIN = 1 << 0,
|
||||
B_MIX_MUTE = 1 << 1,
|
||||
B_MIX_MONO = 1 << 2,
|
||||
B_MIX_STEREO = 1 << 3,
|
||||
B_MIX_MUX = 1 << 4,
|
||||
B_MIX_MICBOOST = 1 << 5,
|
||||
B_MIX_RECORDMUX = 1 << 6
|
||||
} ac97_mixer_type;
|
||||
|
||||
typedef struct _ac97_source_info {
|
||||
const char *name;
|
||||
ac97_mixer_type type;
|
||||
|
||||
int32 id;
|
||||
uint8 reg;
|
||||
uint16 default_value;
|
||||
uint8 bits:3;
|
||||
uint8 ofs:4;
|
||||
uint8 mute:1;
|
||||
uint8 polarity:1; // max_gain -> 0
|
||||
float min_gain;
|
||||
float max_gain;
|
||||
float granularity;
|
||||
} ac97_source_info;
|
||||
|
||||
extern const ac97_source_info source_info[];
|
||||
extern const int32 source_info_size;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Emuxki BeOS Driver for Creative Labs SBLive!/Audigy series
|
||||
*
|
||||
* Copyright (c) 2002, Jerome Duval ([email protected])
|
||||
*
|
||||
* Original code : BeOS Driver for Intel ICH AC'97 Link interface
|
||||
* Copyright (c) 2002, Marcus Overhagen <[email protected]>
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _CONFIG_H_
|
||||
#define _CONFIG_H_
|
||||
|
||||
#include <PCI.h>
|
||||
|
||||
#define NUM_CARDS 3
|
||||
#define DEVNAME 32
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
uint32 nambar;
|
||||
uint32 nabmbar;
|
||||
uint32 irq;
|
||||
int sample_size;
|
||||
bool swap_reg;
|
||||
uint32 type;
|
||||
} device_config;
|
||||
|
||||
#define TYPE_AUDIGY 0x01
|
||||
#define TYPE_AUDIGY2 0x02
|
||||
#define TYPE_LIVE_5_1 0x04
|
||||
|
||||
#define IS_AUDIGY(x) ((x)->type & TYPE_AUDIGY)
|
||||
#define IS_AUDIGY2(x) ((x)->type & TYPE_AUDIGY2)
|
||||
#define IS_LIVE_5_1(x) ((x)->type & TYPE_LIVE_5_1)
|
||||
#endif
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Emuxki BeOS Driver for Creative Labs SBLive!/Audigy series
|
||||
*
|
||||
* Copyright (c) 2002, Jerome Duval ([email protected])
|
||||
*
|
||||
* Original code : BeOS Driver for Intel ICH AC'97 Link interface
|
||||
* Copyright (c) 2002, Marcus Overhagen <[email protected]>
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 <KernelExport.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <OS.h>
|
||||
#include "debug.h"
|
||||
#include "emuxki.h"
|
||||
|
||||
#if DEBUG > 0
|
||||
static const char * logfile="/boot/home/emuxki.log";
|
||||
static sem_id loglock;
|
||||
#endif
|
||||
|
||||
void debug_printf(const char *text,...);
|
||||
void log_printf(const char *text,...);
|
||||
void log_create();
|
||||
|
||||
void debug_printf(const char *text,...)
|
||||
{
|
||||
char buf[1024];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap,text);
|
||||
vsprintf(buf,text,ap);
|
||||
va_end(ap);
|
||||
|
||||
dprintf(DRIVER_NAME ": %s",buf);
|
||||
}
|
||||
|
||||
void log_create()
|
||||
{
|
||||
#if DEBUG > 0
|
||||
int fd = open(logfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
const char *text = DRIVER_NAME ", " VERSION "\n";
|
||||
loglock = create_sem(1,"logfile sem");
|
||||
write(fd,text,strlen(text));
|
||||
close(fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
void log_printf(const char *text,...)
|
||||
{
|
||||
#if DEBUG > 0
|
||||
int fd;
|
||||
char buf[1024];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap,text);
|
||||
vsprintf(buf,text,ap);
|
||||
va_end(ap);
|
||||
|
||||
dprintf(DRIVER_NAME ": %s",buf);
|
||||
|
||||
acquire_sem(loglock);
|
||||
fd = open(logfile, O_WRONLY | O_APPEND);
|
||||
write(fd,buf,strlen(buf));
|
||||
close(fd);
|
||||
release_sem(loglock);
|
||||
|
||||
#if DEBUG > 1
|
||||
snooze(150000);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Emuxki BeOS Driver for Creative Labs SBLive!/Audigy series
|
||||
*
|
||||
* Copyright (c) 2002, Jerome Duval ([email protected])
|
||||
*
|
||||
* Original code : BeOS Driver for Intel ICH AC'97 Link interface
|
||||
* Copyright (c) 2002, Marcus Overhagen <[email protected]>
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _DEBUG_H_
|
||||
#define _DEBUG_H_
|
||||
|
||||
/*
|
||||
* PRINT() executes dprintf if DEBUG = 0 (disabled), or expands to LOG() when DEBUG > 0
|
||||
* TRACE() executes dprintf if DEBUG > 0
|
||||
* LOG() executes dprintf and writes to the logfile if DEBUG > 0
|
||||
*/
|
||||
|
||||
/* DEBUG == 0, no debugging, PRINT writes to syslog
|
||||
* DEBUG == 1, TRACE & LOG, PRINT
|
||||
* DEBUG == 2, TRACE & LOG, PRINT with snooze()
|
||||
*/
|
||||
#ifndef DEBUG
|
||||
#define DEBUG 0
|
||||
#endif
|
||||
|
||||
#undef PRINT
|
||||
#undef TRACE
|
||||
#undef ASSERT
|
||||
|
||||
#if DEBUG > 0
|
||||
#define PRINT(a) log_printf a
|
||||
#define TRACE(a) debug_printf a
|
||||
#define LOG(a) log_printf a
|
||||
#define LOG_CREATE() log_create()
|
||||
#define ASSERT(a) if (a) {} else LOG(("ASSERT failed! file = %s, line = %d\n",__FILE__,__LINE__))
|
||||
void log_create();
|
||||
void log_printf(const char *text,...);
|
||||
void debug_printf(const char *text,...);
|
||||
#else
|
||||
void debug_printf(const char *text,...);
|
||||
#define PRINT(a) debug_printf a
|
||||
#define TRACE(a) ((void)(0))
|
||||
#define ASSERT(a) ((void)(0))
|
||||
#define LOG(a) ((void)(0))
|
||||
#define LOG_CREATE()
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,391 @@
|
||||
/*
|
||||
* Emuxki BeOS Driver for Creative Labs SBLive!/Audigy series
|
||||
*
|
||||
* Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr)
|
||||
*
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Yannick Montulet.
|
||||
*
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
|
||||
*/
|
||||
#if !defined(_EMUXKI_H)
|
||||
#define _EMUXKI_H
|
||||
|
||||
#include <Drivers.h>
|
||||
#include <SupportDefs.h>
|
||||
#include <OS.h>
|
||||
#include "emuxkireg.h"
|
||||
#include "config.h"
|
||||
#include "queue.h"
|
||||
#include "multi_audio.h"
|
||||
#include "multi.h"
|
||||
|
||||
|
||||
#define CREATIVELABS_VENDOR_ID 0x1102 /* Creative Labs */
|
||||
#define CREATIVELABS_SBLIVE_DEVICE_ID 0x0002 /* Creative Labs SoundBlaster Live */
|
||||
#define CREATIVELABS_AUDIGY_DEVICE_ID 0x0004 /* Creative Labs Audigy and Audigy 2 */
|
||||
|
||||
#define AUDIGY 1 // Audigy is not tested for now, but Audigy 2 is
|
||||
|
||||
#define VERSION "Version alpha 4, Copyright (c) 2002 Jérôme Duval, compiled on " ## __DATE__ ## " " ## __TIME__
|
||||
#define DRIVER_NAME "emuxki"
|
||||
#define FRIENDLY_NAME "Emuxki"
|
||||
#define FRIENDLY_NAME_LIVE FRIENDLY_NAME" SB Live"
|
||||
#define FRIENDLY_NAME_LIVE_5_1 FRIENDLY_NAME_LIVE" 5.1"
|
||||
#define FRIENDLY_NAME_AUDIGY FRIENDLY_NAME" Audigy"
|
||||
#define FRIENDLY_NAME_AUDIGY2 FRIENDLY_NAME_AUDIGY" 2"
|
||||
#define AUTHOR "Jérôme Duval"
|
||||
|
||||
/*
|
||||
* Emu10k1 midi
|
||||
*/
|
||||
|
||||
typedef struct _midi_dev {
|
||||
struct _emuxki_dev *
|
||||
card;
|
||||
void * driver;
|
||||
void * cookie;
|
||||
int32 count;
|
||||
char name[64];
|
||||
} midi_dev;
|
||||
|
||||
|
||||
/*
|
||||
* Emu10k1 hardware limits
|
||||
*/
|
||||
|
||||
#define EMU_PTESIZE 4096
|
||||
#define EMU_MAXPTE ((EMU_CHAN_PSST_LOOPSTARTADDR_MASK + 1) / \
|
||||
EMU_PTESIZE)
|
||||
#define EMU_NUMCHAN 64
|
||||
#define EMU_NUMRECSRCS 3
|
||||
|
||||
#define EMU_DMA_ALIGN 4096
|
||||
#define EMU_DMAMEM_NSEG 1
|
||||
|
||||
/*
|
||||
* Emu10k1 memory managment
|
||||
*/
|
||||
|
||||
typedef struct _emuxki_mem {
|
||||
LIST_ENTRY(_emuxki_mem) next;
|
||||
uint16 ptbidx;
|
||||
void *log_base;
|
||||
void *phy_base;
|
||||
area_id area;
|
||||
size_t size;
|
||||
#define EMU_RMEM 0xffff /* recording memory */
|
||||
} emuxki_mem;
|
||||
|
||||
/*
|
||||
* Emu10k1 play channel params
|
||||
*/
|
||||
|
||||
typedef struct _emuxki_chanparms_fxsend {
|
||||
struct {
|
||||
uint8 level, dest;
|
||||
} a, b, c, d, e, f, g, h;
|
||||
} emuxki_chanparms_fxsend;
|
||||
|
||||
typedef struct _emuxki_chanparms_pitch {
|
||||
uint16 intial; /* 4 bits of octave, 12 bits of fractional
|
||||
* octave */
|
||||
uint16 current;/* 0x4000 == unity pitch shift */
|
||||
uint16 target; /* 0x4000 == unity pitch shift */
|
||||
uint8 envelope_amount; /* Signed 2's complement, +/-
|
||||
* one octave peak extremes */
|
||||
} emuxki_chanparms_pitch;
|
||||
|
||||
typedef struct _emuxki_chanparms_envelope {
|
||||
uint16 current_state; /* 0x8000-n == 666*n usec delay */
|
||||
uint8 hold_time; /* 127-n == n*(volume ? 88.2 :
|
||||
* 42)msec */
|
||||
uint8 attack_time; /* 0 = infinite, 1 = (volume ? 11 :
|
||||
* 10.9) msec, 0x7f = 5.5msec */
|
||||
uint8 sustain_level; /* 127 = full, 0 = off, 0.75dB
|
||||
* increments */
|
||||
uint8 decay_time; /* 0 = 43.7msec, 1 = 21.8msec, 0x7f =
|
||||
* 22msec */
|
||||
} emuxki_chanparms_envelope;
|
||||
|
||||
typedef struct _emuxki_chanparms_volume {
|
||||
uint16 current;
|
||||
uint16 target;
|
||||
emuxki_chanparms_envelope envelope;
|
||||
} emuxki_chanparms_volume;
|
||||
|
||||
typedef struct _emuxki_chanparms_filter {
|
||||
uint16 initial_cutoff_frequency;
|
||||
/*
|
||||
* 6 most significant bits are semitones, 2 least significant bits
|
||||
* are fractions
|
||||
*/
|
||||
uint16 current_cutoff_frequency;
|
||||
uint16 target_cutoff_frequency;
|
||||
uint8 lowpass_resonance_height;
|
||||
uint8 interpolation_ROM; /* 1 = full band, 7 = low
|
||||
* pass */
|
||||
uint8 envelope_amount; /* Signed 2's complement, +/-
|
||||
* six octaves peak extremes */
|
||||
uint8 LFO_modulation_depth; /* Signed 2's complement, +/-
|
||||
* three octave extremes */
|
||||
} emuxki_chanparms_filter;
|
||||
|
||||
typedef struct _emuxki_chanparms_loop {
|
||||
uint32 start; /* index in the PTB (in samples) */
|
||||
uint32 end; /* index in the PTB (in samples) */
|
||||
} emuxki_chanparms_loop;
|
||||
|
||||
typedef struct _emuxki_chanparms_modulation {
|
||||
emuxki_chanparms_envelope envelope;
|
||||
uint16 LFO_state; /* 0x8000-n = 666*n usec delay */
|
||||
} emuxki_chanparms_modulation;
|
||||
|
||||
typedef struct _emuxki_chanparms_vibrato_LFO {
|
||||
uint16 state; /* 0x8000-n == 666*n usec delay */
|
||||
uint8 modulation_depth; /* Signed 2's complement, +/-
|
||||
* one octave extremes */
|
||||
uint8 vibrato_depth; /* Signed 2's complement, +/- one
|
||||
* octave extremes */
|
||||
uint8 frequency; /* 0.039Hz steps, maximum of 9.85 Hz */
|
||||
} emuxki_chanparms_vibrato_LFO;
|
||||
|
||||
typedef struct _emuxki_channel {
|
||||
uint8 num; /* voice number */
|
||||
struct _emuxki_voice *voice;
|
||||
emuxki_chanparms_fxsend fxsend;
|
||||
emuxki_chanparms_pitch pitch;
|
||||
uint16 initial_attenuation; /* 0.375dB steps */
|
||||
emuxki_chanparms_volume volume;
|
||||
emuxki_chanparms_filter filter;
|
||||
emuxki_chanparms_loop loop;
|
||||
emuxki_chanparms_modulation modulation;
|
||||
emuxki_chanparms_vibrato_LFO vibrato_LFO;
|
||||
uint8 tremolo_depth;
|
||||
} emuxki_channel;
|
||||
|
||||
typedef struct _emuxki_recparams {
|
||||
uint32 efx_voices[2];
|
||||
} emuxki_recparams;
|
||||
|
||||
|
||||
/*
|
||||
* Voices
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
EMU_RECSRC_MIC = 0,
|
||||
EMU_RECSRC_ADC,
|
||||
EMU_RECSRC_FX,
|
||||
EMU_RECSRC_NOTSET
|
||||
} emuxki_recsrc_t;
|
||||
|
||||
#define EMU_USE_PLAY (1 << 0)
|
||||
#define EMU_USE_RECORD (1 << 1)
|
||||
#define EMU_STATE_STARTED (1 << 0)
|
||||
#define EMU_STEREO_NOTSET 0xFF
|
||||
|
||||
typedef struct _emuxki_voice {
|
||||
struct _emuxki_stream *stream;
|
||||
uint8 use;
|
||||
uint8 voicenum;
|
||||
uint8 state;
|
||||
uint8 stereo;
|
||||
uint8 b16;
|
||||
uint32 sample_rate;
|
||||
union {
|
||||
emuxki_channel *chan[2];
|
||||
emuxki_recsrc_t source;
|
||||
} dataloc;
|
||||
emuxki_recparams recparams;
|
||||
emuxki_mem *buffer;
|
||||
uint16 blksize;/* in samples */
|
||||
uint16 trigblk;/* blk on which to trigger inth */
|
||||
uint16 blkmod; /* Modulo value to wrap trigblk */
|
||||
uint16 timerate;
|
||||
|
||||
LIST_ENTRY(_emuxki_voice) next;
|
||||
|
||||
} emuxki_voice;
|
||||
|
||||
/*
|
||||
* Streams
|
||||
*/
|
||||
|
||||
typedef struct _emuxki_stream {
|
||||
struct _emuxki_dev *card;
|
||||
uint8 use;
|
||||
uint8 state;
|
||||
uint8 stereo;
|
||||
uint8 b16;
|
||||
uint32 sample_rate;
|
||||
uint8 nmono;
|
||||
uint8 nstereo;
|
||||
uint32 bufframes;
|
||||
uint8 bufcount;
|
||||
LIST_HEAD(, _emuxki_voice) voices;
|
||||
emuxki_voice *first_voice;
|
||||
|
||||
LIST_ENTRY(_emuxki_stream) next;
|
||||
|
||||
void (*inth) (void *);
|
||||
void *inthparam;
|
||||
|
||||
/* multi_audio */
|
||||
volatile int64 frames_count; // for play or record
|
||||
volatile bigtime_t real_time; // for play or record
|
||||
volatile int32 buffer_cycle; // for play or record
|
||||
int32 first_channel;
|
||||
bool update_needed;
|
||||
} emuxki_stream;
|
||||
|
||||
/*
|
||||
* Mixer controls gpr
|
||||
*/
|
||||
#define EMU_GPR_FIRST_MIX 16
|
||||
|
||||
typedef enum {
|
||||
EMU_MIX_GAIN = 1 << 0,
|
||||
EMU_MIX_MONO = 1 << 1,
|
||||
EMU_MIX_STEREO = 1 << 2,
|
||||
EMU_MIX_TMP = 1 << 3,
|
||||
EMU_MIX_MUTE = 1 << 4,
|
||||
EMU_MIX_PLAYBACK = 1 << 5,
|
||||
EMU_MIX_RECORD = 1 << 6
|
||||
} emuxki_gpr_type;
|
||||
|
||||
typedef struct _emuxki_gpr {
|
||||
char name[32];
|
||||
emuxki_gpr_type type;
|
||||
uint16 gpr;
|
||||
float default_value;
|
||||
float min_gain;
|
||||
float max_gain;
|
||||
float granularity;
|
||||
float current[2];
|
||||
bool mute;
|
||||
} emuxki_gpr;
|
||||
|
||||
typedef enum {
|
||||
EMU_DIGITAL_MODE = 1 << 0,
|
||||
EMU_AUDIO_MODE = 1 << 1
|
||||
} emuxki_parameter_type;
|
||||
|
||||
/*
|
||||
* Devices
|
||||
*/
|
||||
|
||||
typedef struct _emuxki_dev {
|
||||
char name[DEVNAME]; /* used for resources */
|
||||
pci_info info;
|
||||
device_config config;
|
||||
|
||||
void *ptb_log_base;
|
||||
void *ptb_phy_base;
|
||||
area_id ptb_area;
|
||||
void *silentpage_log_base;
|
||||
void *silentpage_phy_base;
|
||||
area_id silentpage_area;
|
||||
|
||||
emuxki_channel *channel[EMU_NUMCHAN];
|
||||
emuxki_voice *recsrc[EMU_NUMRECSRCS];
|
||||
|
||||
LIST_HEAD(, _emuxki_mem) mem;
|
||||
|
||||
LIST_HEAD(, _emuxki_stream) streams;
|
||||
|
||||
uint8 timerstate;
|
||||
uint16 timerate;
|
||||
#define EMU_TIMER_STATE_ENABLED 1
|
||||
uint8 play_mode; // number of channels to be played : 2, 4, 6
|
||||
bool digital_enabled; // if digital is enabled and analog is disabled
|
||||
|
||||
emuxki_stream *pstream;
|
||||
emuxki_stream *pstream2;
|
||||
emuxki_stream *rstream;
|
||||
emuxki_stream *rstream2;
|
||||
|
||||
sem_id buffer_ready_sem;
|
||||
|
||||
midi_dev midi;
|
||||
|
||||
/* mixer controls */
|
||||
emuxki_gpr gpr[256];
|
||||
uint32 gpr_count;
|
||||
|
||||
/* multi_audio */
|
||||
multi_dev multi;
|
||||
} emuxki_dev;
|
||||
|
||||
extern int32 num_cards;
|
||||
extern emuxki_dev cards[NUM_CARDS];
|
||||
|
||||
void emuxki_mem_free(emuxki_dev *card, void *ptr);
|
||||
void * emuxki_pmem_alloc(emuxki_dev *card, size_t size);
|
||||
void * emuxki_rmem_alloc(emuxki_dev *card, size_t size);
|
||||
status_t emuxki_voice_commit_parms(emuxki_voice *voice);
|
||||
status_t emuxki_voice_set_audioparms(emuxki_voice *voice, uint8 stereo,
|
||||
uint8 b16, uint32 srate);
|
||||
status_t emuxki_voice_set_recparms(emuxki_voice *voice, emuxki_recsrc_t recsrc,
|
||||
emuxki_recparams *recparams);
|
||||
status_t emuxki_voice_set_bufparms(emuxki_voice *voice, void *ptr,
|
||||
uint32 bufsize, uint16 blksize);
|
||||
void emuxki_voice_start(emuxki_voice *voice);
|
||||
void emuxki_voice_halt(emuxki_voice *voice);
|
||||
emuxki_voice *emuxki_voice_new(emuxki_stream *stream, uint8 use, uint8 voicenum);
|
||||
void emuxki_voice_delete(emuxki_voice *voice);
|
||||
|
||||
status_t emuxki_stream_set_audioparms(emuxki_stream *stream, bool stereo, uint8 channels,
|
||||
uint8 b16, uint32 sample_rate);
|
||||
status_t emuxki_stream_set_recparms(emuxki_stream *stream, emuxki_recsrc_t recsrc,
|
||||
emuxki_recparams *recparams);
|
||||
status_t emuxki_stream_commit_parms(emuxki_stream *stream);
|
||||
status_t emuxki_stream_get_nth_buffer(emuxki_stream *stream, uint8 chan, uint8 buf,
|
||||
char** buffer, size_t *stride);
|
||||
void emuxki_stream_start(emuxki_stream *stream, void (*inth) (void *), void *inthparam);
|
||||
void emuxki_stream_halt(emuxki_stream *stream);
|
||||
emuxki_stream *emuxki_stream_new(emuxki_dev *card, uint8 use, uint32 bufframes, uint8 bufcount);
|
||||
void emuxki_stream_delete(emuxki_stream *stream);
|
||||
|
||||
void emuxki_dump_fx(emuxki_dev * card);
|
||||
void emuxki_gpr_dump(emuxki_dev * card, uint16 count);
|
||||
void emuxki_gpr_set(emuxki_dev *card, emuxki_gpr *gpr, int32 type, float *values);
|
||||
void emuxki_gpr_get(emuxki_dev *card, emuxki_gpr *gpr, int32 type, float *values);
|
||||
|
||||
void emuxki_parameter_set(emuxki_dev *card, const void*, int32 type, int32 *value);
|
||||
void emuxki_parameter_get(emuxki_dev *card, const void*, int32 type, int32 *value);
|
||||
|
||||
extern void midi_interrupt_op(int32 op, void * data);
|
||||
extern bool midi_interrupt(emuxki_dev *card);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,702 @@
|
||||
/*
|
||||
* Emuxki BeOS Driver for Creative Labs SBLive!/Audigy series
|
||||
*
|
||||
* Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr)
|
||||
*
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Yannick Montulet.
|
||||
*
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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_PCI_EMUXKIREG_H_
|
||||
#define _DEV_PCI_EMUXKIREG_H_
|
||||
|
||||
/*
|
||||
* Register values for Creative EMU10000. The register values have been
|
||||
* taken from GPLed SBLive! header file published by Creative. The comments
|
||||
* have been stripped to avoid GPL pollution in kernel. The Creative version
|
||||
* including comments is available in Linux 2.4.* kernel as file
|
||||
* drivers/sound/emu10k1/8010.h
|
||||
*/
|
||||
|
||||
// Audigy specific registers contain a 'A_'
|
||||
// Audigy(2) specific registers contain a 'A2_'
|
||||
|
||||
#define EMU_MKSUBREG(sz, idx, reg) (((sz) << 24) | ((idx) << 16) | (reg))
|
||||
|
||||
#define EMU_PTR 0x00
|
||||
#define EMU_PTR_CHNO_MASK 0x0000003f
|
||||
#define EMU_PTR_ADDR_MASK 0x07ff0000
|
||||
#define EMU_A_PTR_ADDR_MASK 0x0fff0000
|
||||
|
||||
#define EMU_DATA 0x04
|
||||
|
||||
#define EMU_IPR 0x08
|
||||
#define EMU_IPR_A_MIDITRANSBUFE2 0x10000000
|
||||
#define EMU_IPR_A_MIDIRECVBUFE2 0x08000000
|
||||
#define EMU_IPR_RATETRCHANGE 0x01000000
|
||||
#define EMU_IPR_FXDSP 0x00800000
|
||||
#define EMU_IPR_FORCEINT 0x00400000
|
||||
#define EMU_PCIERROR 0x00200000
|
||||
#define EMU_IPR_VOLINCR 0x00100000
|
||||
#define EMU_IPR_VOLDECR 0x00080000
|
||||
#define EMU_IPR_MUTE 0x00040000
|
||||
#define EMU_IPR_MICBUFFULL 0x00020000
|
||||
#define EMU_IPR_MICBUFHALFFULL 0x00010000
|
||||
#define EMU_IPR_ADCBUFFULL 0x00008000
|
||||
#define EMU_IPR_ADCBUFHALFFULL 0x00004000
|
||||
#define EMU_IPR_EFXBUFFULL 0x00002000
|
||||
#define EMU_IPR_EFXBUFHALFFULL 0x00001000
|
||||
#define EMU_IPR_GPSPDIFSTCHANGE 0x00000800
|
||||
#define EMU_IPR_CDROMSTCHANGE 0x00000400
|
||||
#define EMU_IPR_INTERVALTIMER 0x00000200
|
||||
#define EMU_IPR_MIDITRANSBUFE 0x00000100
|
||||
#define EMU_IPR_MIDIRECVBUFE 0x00000080
|
||||
#define EMU_IPR_CHANNELLOOP 0x00000040
|
||||
#define EMU_IPR_CHNOMASK 0x0000003f
|
||||
|
||||
#define EMU_INTE 0x0c
|
||||
|
||||
#define EMU_INTE_VSB_MASK 0xc0000000
|
||||
#define EMU_INTE_VSB_220 0x00000000
|
||||
#define EMU_INTE_VSB_240 0x40000000
|
||||
#define EMU_INTE_VSB_260 0x80000000
|
||||
#define EMU_INTE_VSB_280 0xc0000000
|
||||
|
||||
#define EMU_INTE_VMPU_MASK 0x30000000
|
||||
#define EMU_INTE_VMPU_300 0x00000000
|
||||
#define EMU_INTE_VMPU_310 0x10000000
|
||||
#define EMU_INTE_VMPU_320 0x20000000
|
||||
#define EMU_INTE_VMPU_330 0x30000000
|
||||
#define EMU_INTE_MDMAENABLE 0x08000000
|
||||
#define EMU_INTE_SDMAENABLE 0x04000000
|
||||
#define EMU_INTE_MPICENABLE 0x02000000
|
||||
#define EMU_INTE_SPICENABLE 0x01000000
|
||||
#define EMU_INTE_VSBENABLE 0x00800000
|
||||
#define EMU_INTE_ADLIBENABLE 0x00400000
|
||||
#define EMU_INTE_MPUENABLE 0x00200000
|
||||
#define EMU_INTE_FORCEINT 0x00100000
|
||||
#define EMU_INTE_MRHANDENABLE 0x00080000
|
||||
#define EMU_INTE_SAMPLERATER 0x00002000
|
||||
#define EMU_INTE_FXDSPENABLE 0x00001000
|
||||
#define EMU_INTE_PCIERRENABLE 0x00000800
|
||||
#define EMU_INTE_VOLINCRENABLE 0x00000400
|
||||
#define EMU_INTE_VOLDECRENABLE 0x00000200
|
||||
#define EMU_INTE_MUTEENABLE 0x00000100
|
||||
#define EMU_INTE_MICBUFENABLE 0x00000080
|
||||
#define EMU_INTE_ADCBUFENABLE 0x00000040
|
||||
#define EMU_INTE_EFXBUFENABLE 0x00000020
|
||||
#define EMU_INTE_GPSPDIFENABLE 0x00000010
|
||||
#define EMU_INTE_CDSPDIFENABLE 0x00000008
|
||||
#define EMU_INTE_INTERTIMERENB 0x00000004
|
||||
#define EMU_INTE_MIDITXENABLE 0x00000002
|
||||
#define EMU_INTE_MIDIRXENABLE 0x00000001
|
||||
#define EMU_INTE_A_MIDITXENABLE2 0x00020000
|
||||
#define EMU_INTE_A_MIDIRXENABLE2 0x00010000
|
||||
|
||||
#define EMU_WC 0x10
|
||||
#define EMU_WC_SAMPLECOUNTER_MASK 0x03FFFFC0
|
||||
#define EMU_WC_SAMPLECOUNTER EMU_MKSUBREG(20, 6, EMU_WC)
|
||||
#define EMU_WC_CURRENTCHANNEL 0x0000003F
|
||||
|
||||
#define EMU_HCFG 0x14
|
||||
#define EMU_HCFG_LEGACYFUNC_MASK 0xe0000000
|
||||
#define EMU_HCFG_LEGACYFUNC_MPU 0x00000000
|
||||
#define EMU_HCFG_LEGACYFUNC_SB 0x40000000
|
||||
#define EMU_HCFG_LEGACYFUNC_AD 0x60000000
|
||||
#define EMU_HCFG_LEGACYFUNC_MPIC 0x80000000
|
||||
#define EMU_HCFG_LEGACYFUNC_MDMA 0xa0000000
|
||||
#define EMU_HCFG_LEGACYFUNC_SPCI 0xc0000000
|
||||
#define EMU_HCFG_LEGACYFUNC_SDMA 0xe0000000
|
||||
#define EMU_HCFG_IOCAPTUREADDR 0x1f000000
|
||||
#define EMU_HCFG_LEGACYWRITE 0x00800000
|
||||
#define EMU_HCFG_LEGACYWORD 0x00400000
|
||||
#define EMU_HCFG_LEGACYINT 0x00200000
|
||||
|
||||
#define EMU_HCFG_CODECFMT_MASK 0x00070000
|
||||
#define EMU_HCFG_CODECFMT_AC97 0x00000000
|
||||
#define EMU_HCFG_CODECFMT_I2S 0x00010000
|
||||
#define EMU_HCFG_GPINPUT0 0x00004000
|
||||
#define EMU_HCFG_GPINPUT1 0x00002000
|
||||
#define EMU_HCFG_GPOUTPUT_MASK 0x00001c00
|
||||
#define EMU_HCFG_GPOUTPUT0 0x00001000
|
||||
#define EMU_HCFG_JOYENABLE 0x00000200
|
||||
#define EMU_HCFG_PHASETRACKENABLE 0x00000100
|
||||
#define EMU_HCFG_AC3ENABLE_MASK 0x000000e0
|
||||
#define EMU_HCFG_AC3ENABLE_ZVIDEO 0x00000080
|
||||
#define EMU_HCFG_AC3ENABLE_CDSPDIF 0x00000040
|
||||
#define EMU_HCFG_AC3ENABLE_GPSPDIF 0x00000020
|
||||
#define EMU_HCFG_AUTOMUTE 0x00000010
|
||||
#define EMU_HCFG_LOCKSOUNDCACHE 0x00000008
|
||||
#define EMU_HCFG_LOCKTANKCACHE_MASK 0x00000004
|
||||
#define EMU_HCFG_LOCKTANKCACHE EMU_MKSUBREG(1, 2, EMU_HCFG)
|
||||
#define EMU_HCFG_MUTEBUTTONENABLE 0x00000002
|
||||
#define EMU_HCFG_AUDIOENABLE 0x00000001
|
||||
|
||||
#define EMU_MUDATA 0x18
|
||||
#define EMU_MUCMD 0x19
|
||||
#define EMU_MUCMD_RESET 0xff
|
||||
#define EMU_MUCMD_ENTERUARTMODE 0x3f
|
||||
|
||||
#define EMU_MUSTAT EMU_MUCMD
|
||||
#define EMU_MUSTAT_IRDYN 0x80
|
||||
#define EMU_MUSTAT_ORDYN 0x40
|
||||
|
||||
#define EMU_A_IOCFG 0x18
|
||||
#define EMU_A_GPINPUT_MASK 0xff00
|
||||
#define EMU_A_GPOUTPUT_MASK 0x00ff
|
||||
#define EMU_A_IOCFG_GPOUT0 0x0040
|
||||
#define EMU_A_IOCFG_GPOUT1 0x0004
|
||||
|
||||
#define EMU_TIMER 0x1a
|
||||
#define EMU_TIMER_RATE_MASK 0x000003ff
|
||||
#define EMU_TIMER_RATE EMU_MKSUBREG(10, 0, EMU_TIMER)
|
||||
|
||||
#define EMU_AC97DATA 0x1c
|
||||
#define EMU_AC97ADDR 0x1e
|
||||
#define EMU_AC97ADDR_RDY 0x80
|
||||
#define EMU_AC97ADDR_ADDR 0x7f
|
||||
|
||||
#define EMU_A2_PTR 0x20
|
||||
#define EMU_A2_DATA 0x24
|
||||
|
||||
#define EMU_A2_SRCSEL 0x600000
|
||||
#define EMU_A2_SRCSEL_ENABLE_SPDIF 0x00000004
|
||||
#define EMU_A2_SRCSEL_ENABLE_SRCMULTI 0x00000010
|
||||
#define EMU_A2_SRCMULTI 0x6e0000
|
||||
#define EMU_A2_SRCMULTI_ENABLE_INPUT 0xff00ff00
|
||||
|
||||
|
||||
/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
|
||||
|
||||
#define EMU_CHAN_CPF 0x00
|
||||
|
||||
#define EMU_CHAN_CPF_PITCH_MASK 0xffff0000
|
||||
#define EMU_CHAN_CPF_PITCH EMU_MKSUBREG(16, 16, EMU_CHAN_CPF)
|
||||
#define EMU_CHAN_CPF_STEREO_MASK 0x00008000
|
||||
#define EMU_CHAN_CPF_STEREO EMU_MKSUBREG(1, 15, EMU_CHAN_CPF)
|
||||
#define EMU_CHAN_CPF_STOP_MASK 0x00004000
|
||||
#define EMU_CHAN_CPF_FRACADDRESS_MASK 0x00003fff
|
||||
|
||||
|
||||
#define EMU_CHAN_PTRX 0x01
|
||||
#define EMU_CHAN_PTRX_PITCHTARGET_MASK 0xffff0000
|
||||
#define EMU_CHAN_PTRX_PITCHTARGET EMU_MKSUBREG(16, 16, EMU_CHAN_PTRX)
|
||||
#define EMU_CHAN_PTRX_FXSENDAMOUNT_A_MASK 0x0000ff00
|
||||
#define EMU_CHAN_PTRX_FXSENDAMOUNT_A EMU_MKSUBREG(8, 8, EMU_CHAN_PTRX)
|
||||
#define EMU_CHAN_PTRX_FXSENDAMOUNT_B_MASK 0x000000ff
|
||||
#define EMU_CHAN_PTRX_FXSENDAMOUNT_B EMU_MKSUBREG(8, 0, EMU_CHAN_PTRX)
|
||||
|
||||
#define EMU_CHAN_CVCF 0x02
|
||||
#define EMU_CHAN_CVCF_CURRVOL_MASK 0xffff0000
|
||||
#define EMU_CHAN_CVCF_CURRVOL EMU_MKSUBREG(16, 16, EMU_CHAN_CVCF)
|
||||
#define EMU_CHAN_CVCF_CURRFILTER_MASK 0x0000ffff
|
||||
#define EMU_CHAN_CVCF_CURRFILTER EMU_MKSUBREG(16, 0, EMU_CHAN_CVCF)
|
||||
|
||||
#define EMU_CHAN_VTFT 0x03
|
||||
#define EMU_CHAN_VTFT_VOLUMETARGET_MASK 0xffff0000
|
||||
#define EMU_CHAN_VTFT_VOLUMETARGET EMU_MKSUBREG(16, 16, EMU_CHAN_VTFT)
|
||||
#define EMU_CHAN_VTFT_FILTERTARGET_MASK 0x0000ffff
|
||||
#define EMU_CHAN_VTFT_FILTERTARGET EMU_MKSUBREG(16, 0, EMU_CHAN_VTFT)
|
||||
|
||||
#define EMU_CHAN_Z1 0x05
|
||||
#define EMU_CHAN_Z2 0x04
|
||||
|
||||
#define EMU_CHAN_PSST 0x06
|
||||
#define EMU_CHAN_PSST_FXSENDAMOUNT_C_MASK 0xff000000
|
||||
#define EMU_CHAN_PSST_FXSENDAMOUNT_C EMU_MKSUBREG(8, 24, EMU_CHAN_PSST)
|
||||
#define EMU_CHAN_PSST_LOOPSTARTADDR_MASK 0x00ffffff
|
||||
#define EMU_CHAN_PSST_LOOPSTARTADDR EMU_MKSUBREG(24, 0, EMU_CHAN_PSST)
|
||||
|
||||
#define EMU_CHAN_DSL 0x07
|
||||
#define EMU_CHAN_DSL_FXSENDAMOUNT_D_MASK 0xff000000
|
||||
#define EMU_CHAN_DSL_FXSENDAMOUNT_D EMU_MKSUBREG(8, 24, EMU_CHAN_DSL)
|
||||
#define EMU_CHAN_DSL_LOOPENDADDR_MASK 0x00ffffff
|
||||
#define EMU_CHAN_DSL_LOOPENDADDR EMU_MKSUBREG(24, 0, EMU_CHAN_DSL)
|
||||
|
||||
#define EMU_CHAN_CCCA 0x08
|
||||
#define EMU_CHAN_CCCA_RESONANCE 0xf0000000
|
||||
#define EMU_CHAN_CCCA_INTERPROMMASK 0x0e000000
|
||||
#define EMU_CHAN_CCCA_INTERPROM_0 0x00000000
|
||||
#define EMU_CHAN_CCCA_INTERPROM_1 0x02000000
|
||||
#define EMU_CHAN_CCCA_INTERPROM_2 0x04000000
|
||||
#define EMU_CHAN_CCCA_INTERPROM_3 0x06000000
|
||||
#define EMU_CHAN_CCCA_INTERPROM_4 0x08000000
|
||||
#define EMU_CHAN_CCCA_INTERPROM_5 0x0a000000
|
||||
#define EMU_CHAN_CCCA_INTERPROM_6 0x0c000000
|
||||
#define EMU_CHAN_CCCA_INTERPROM_7 0x0e000000
|
||||
#define EMU_CHAN_CCCA_8BITSELECT 0x01000000
|
||||
#define EMU_CHAN_CCCA_CURRADDR_MASK 0x00ffffff
|
||||
#define EMU_CHAN_CCCA_CURRADDR EMU_MKSUBREG(24, 0, EMU_CHAN_CCCA)
|
||||
|
||||
#define EMU_CHAN_CCR 0x09
|
||||
#define EMU_CHAN_CCR_CACHEINVALIDSIZE_MASK 0xfe000000
|
||||
#define EMU_CHAN_CCR_CACHEINVALIDSIZE EMU_MKSUBREG(7, 25, EMU_CHAN_CCR)
|
||||
#define EMU_CHAN_CCR_CACHELOOPFLAG 0x01000000
|
||||
#define EMU_CHAN_CCR_INTERLEAVEDSAMPLES 0x00800000
|
||||
#define EMU_CHAN_CCR_WORDSIZEDSAMPLES 0x00400000
|
||||
#define EMU_CHAN_CCR_READADDRESS_MASK 0x003f0000
|
||||
#define EMU_CHAN_CCR_READADDRESS EMU_MKSUBREG(6, 16, EMU_CHAN_CCR)
|
||||
#define EMU_CHAN_CCR_LOOPINVALSIZE 0x0000fe00
|
||||
#define EMU_CHAN_CCR_LOOPFLAG 0x00000100
|
||||
#define EMU_CHAN_CCR_CACHELOOPADDRHI 0x000000ff
|
||||
|
||||
#define EMU_CHAN_CLP 0x0a
|
||||
#define EMU_CHAN_CLP_CACHELOOPADDR 0x0000ffff
|
||||
|
||||
#define EMU_CHAN_FXRT 0x0b
|
||||
#define EMU_CHAN_FXRT_CHANNELA 0x000f0000
|
||||
#define EMU_CHAN_FXRT_CHANNELB 0x00f00000
|
||||
#define EMU_CHAN_FXRT_CHANNELC 0x0f000000
|
||||
#define EMU_CHAN_FXRT_CHANNELD 0xf0000000
|
||||
|
||||
#define EMU_CHAN_MAPA 0x0c
|
||||
#define EMU_CHAN_MAPB 0x0d
|
||||
|
||||
#define EMU_CHAN_MAP_PTE_MASK 0xffffe000
|
||||
#define EMU_CHAN_MAP_PTI_MASK 0x00001fff
|
||||
|
||||
|
||||
#define EMU_CHAN_ENVVOL 0x10
|
||||
#define EMU_CHAN_ENVVOL_MASK 0x0000ffff
|
||||
|
||||
|
||||
#define EMU_CHAN_ATKHLDV 0x11
|
||||
#define EMU_CHAN_ATKHLDV_PHASE0 0x00008000
|
||||
#define EMU_CHAN_ATKHLDV_HOLDTIME_MASK 0x00007f00
|
||||
#define EMU_CHAN_ATKHLDV_ATTACKTIME_MASK 0x0000007f
|
||||
|
||||
|
||||
#define EMU_CHAN_DCYSUSV 0x12
|
||||
#define EMU_CHAN_DCYSUSV_PHASE1_MASK 0x00008000
|
||||
#define EMU_CHAN_DCYSUSV_SUSTAINLEVEL_MASK 0x00007f00
|
||||
#define EMU_CHAN_DCYSUSV_CHANNELENABLE_MASK 0x00000080
|
||||
#define EMU_CHAN_DCYSUSV_DECAYTIME_MASK 0x0000007f
|
||||
|
||||
|
||||
#define EMU_CHAN_LFOVAL1 0x13
|
||||
#define EMU_CHAN_LFOVAL_MASK 0x0000ffff
|
||||
|
||||
#define EMU_CHAN_ENVVAL 0x14
|
||||
#define EMU_CHAN_ENVVAL_MASK 0x0000ffff
|
||||
|
||||
#define EMU_CHAN_ATKHLDM 0x15
|
||||
#define EMU_CHAN_ATKHLDM_PHASE0 0x00008000
|
||||
#define EMU_CHAN_ATKHLDM_HOLDTIME 0x00007f00
|
||||
#define EMU_CHAN_ATKHLDM_ATTACKTIME 0x0000007f
|
||||
|
||||
#define EMU_CHAN_DCYSUSM 0x16
|
||||
#define EMU_CHAN_DCYSUSM_PHASE1_MASK 0x00008000
|
||||
#define EMU_CHAN_DCYSUSM_SUSTAINLEVEL_MASK 0x00007f00
|
||||
#define EMU_CHAN_DCYSUSM_DECAYTIME_MASK 0x0000007f
|
||||
|
||||
#define EMU_CHAN_LFOVAL2 0x17
|
||||
#define EMU_CHAN_LFOVAL2_MASK 0x0000ffff
|
||||
|
||||
#define EMU_CHAN_IP 0x18
|
||||
#define EMU_CHAN_IP_MASK 0x0000ffff
|
||||
#define EMU_CHAN_IP_UNITY 0x0000e000
|
||||
|
||||
#define EMU_CHAN_IFATN 0x19
|
||||
#define EMU_CHAN_IFATN_FILTERCUTOFF_MASK 0x0000ff00
|
||||
#define EMU_CHAN_IFATN_FILTERCUTOFF EMU_MKSUBREG(8, 8, EMU_CHAN_IFATN)
|
||||
#define EMU_CHAN_IFATN_ATTENUATION_MASK 0x000000ff
|
||||
#define EMU_CHAN_IFATN_ATTENUATION EMU_MKSUBREG(8, 0, EMU_CHAN_IFATN)
|
||||
|
||||
#define EMU_CHAN_PEFE 0x1a
|
||||
#define EMU_CHAN_PEFE_PITCHAMOUNT_MASK 0x0000ff00
|
||||
#define EMU_CHAN_PEFE_PITCHAMOUNT EMU_MKSUBREG(8, 8, EMU_CHAN_PEFE)
|
||||
#define EMU_CHAN_PEFE_FILTERAMOUNT_MASK 0x000000ff
|
||||
#define EMU_CHAN_PEFE_FILTERAMOUNT EMU_MKSUBREG(8, 0, EMU_CHAN_PEFE)
|
||||
|
||||
#define EMU_CHAN_FMMOD 0x1b
|
||||
#define EMU_CHAN_FMMOD_MODVIBRATO 0x0000ff00
|
||||
#define EMU_CHAN_FMMOD_MOFILTER 0x000000ff
|
||||
|
||||
#define EMU_CHAN_TREMFRQ 0x1c
|
||||
#define EMU_CHAN_TREMFRQ_DEPTH 0x0000ff00
|
||||
|
||||
#define EMU_CHAN_FM2FRQ2 0x1d
|
||||
#define EMU_CHAN_FM2FRQ2_DEPTH 0x0000ff00
|
||||
#define EMU_CHAN_FM2FRQ2_FREQUENCY 0x000000ff
|
||||
|
||||
#define EMU_CHAN_TEMPENV 0x1e
|
||||
#define EMU_CHAN_TEMPENV_MASK 0x0000ffff
|
||||
|
||||
#define EMU_CHAN_CD0 0x20
|
||||
#define EMU_CHAN_CD1 0x21
|
||||
#define EMU_CHAN_CD2 0x22
|
||||
#define EMU_CHAN_CD3 0x23
|
||||
#define EMU_CHAN_CD4 0x24
|
||||
#define EMU_CHAN_CD5 0x25
|
||||
#define EMU_CHAN_CD6 0x26
|
||||
#define EMU_CHAN_CD7 0x27
|
||||
#define EMU_CHAN_CD8 0x28
|
||||
#define EMU_CHAN_CD9 0x29
|
||||
#define EMU_CHAN_CDA 0x2a
|
||||
#define EMU_CHAN_CDB 0x2b
|
||||
#define EMU_CHAN_CDC 0x2c
|
||||
#define EMU_CHAN_CDD 0x2d
|
||||
#define EMU_CHAN_CDE 0x2e
|
||||
#define EMU_CHAN_CDF 0x2f
|
||||
|
||||
/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
|
||||
|
||||
#define EMU_PTB 0x40
|
||||
#define EMU_PTB_MASK 0xfffff000
|
||||
|
||||
#define EMU_TCB 0x41
|
||||
#define EMU_TCB_MASK 0xfffff000
|
||||
|
||||
#define EMU_ADCCR 0x42
|
||||
#define EMU_ADCCR_RCHANENABLE 0x00000010
|
||||
#define EMU_ADCCR_LCHANENABLE 0x00000008
|
||||
#define EMU_ADCCR_SAMPLERATE_MASK 0x00000007
|
||||
#define EMU_A_ADCCR_RCHANENABLE 0x00000020
|
||||
#define EMU_A_ADCCR_LCHANENABLE 0x00000010
|
||||
#define EMU_A_ADCCR_SAMPLERATE_MASK 0x0000000F
|
||||
#define EMU_ADCCR_SAMPLERATE_48 0x00000000
|
||||
#define EMU_ADCCR_SAMPLERATE_44 0x00000001
|
||||
#define EMU_ADCCR_SAMPLERATE_32 0x00000002
|
||||
#define EMU_ADCCR_SAMPLERATE_24 0x00000003
|
||||
#define EMU_ADCCR_SAMPLERATE_22 0x00000004
|
||||
#define EMU_ADCCR_SAMPLERATE_16 0x00000005
|
||||
#define EMU_ADCCR_SAMPLERATE_11 0x00000006
|
||||
#define EMU_ADCCR_SAMPLERATE_8 0x00000007
|
||||
#define EMU_A_ADCCR_SAMPLERATE_12 0x00000006
|
||||
#define EMU_A_ADCCR_SAMPLERATE_11 0x00000007
|
||||
#define EMU_A_ADCCR_SAMPLERATE_8 0x00000008
|
||||
|
||||
#define EMU_FXWC 0x43
|
||||
#define EMU_TCBS 0x44
|
||||
#define EMU_TCBS_MASK 0x00000007
|
||||
#define EMU_TCBS_BUFFSIZE_16K 0x00000000
|
||||
#define EMU_TCBS_BUFFSIZE_32K 0x00000001
|
||||
#define EMU_TCBS_BUFFSIZE_64K 0x00000002
|
||||
#define EMU_TCBS_BUFFSIZE_128K 0x00000003
|
||||
#define EMU_TCBS_BUFFSIZE_256K 0x00000004
|
||||
#define EMU_TCBS_BUFFSIZE_512K 0x00000005
|
||||
#define EMU_TCBS_BUFFSIZE_1024K 0x00000006
|
||||
#define EMU_TCBS_BUFFSIZE_2048K 0x00000007
|
||||
|
||||
#define EMU_MICBA 0x45
|
||||
#define EMU_ADCBA 0x46
|
||||
#define EMU_FXBA 0x47
|
||||
#define EMU_RECBA_MASK 0xfffff000
|
||||
|
||||
#define EMU_MICBS 0x49
|
||||
#define EMU_ADCBS 0x4a
|
||||
#define EMU_FXBS 0x4b
|
||||
#define EMU_RECBS_BUFSIZE_NONE 0x00000000
|
||||
#define EMU_RECBS_BUFSIZE_384 0x00000001
|
||||
#define EMU_RECBS_BUFSIZE_448 0x00000002
|
||||
#define EMU_RECBS_BUFSIZE_512 0x00000003
|
||||
#define EMU_RECBS_BUFSIZE_640 0x00000004
|
||||
#define EMU_RECBS_BUFSIZE_768 0x00000005
|
||||
#define EMU_RECBS_BUFSIZE_896 0x00000006
|
||||
#define EMU_RECBS_BUFSIZE_1024 0x00000007
|
||||
#define EMU_RECBS_BUFSIZE_1280 0x00000008
|
||||
#define EMU_RECBS_BUFSIZE_1536 0x00000009
|
||||
#define EMU_RECBS_BUFSIZE_1792 0x0000000a
|
||||
#define EMU_RECBS_BUFSIZE_2048 0x0000000b
|
||||
#define EMU_RECBS_BUFSIZE_2560 0x0000000c
|
||||
#define EMU_RECBS_BUFSIZE_3072 0x0000000d
|
||||
#define EMU_RECBS_BUFSIZE_3584 0x0000000e
|
||||
#define EMU_RECBS_BUFSIZE_4096 0x0000000f
|
||||
#define EMU_RECBS_BUFSIZE_5120 0x00000010
|
||||
#define EMU_RECBS_BUFSIZE_6144 0x00000011
|
||||
#define EMU_RECBS_BUFSIZE_7168 0x00000012
|
||||
#define EMU_RECBS_BUFSIZE_8192 0x00000013
|
||||
#define EMU_RECBS_BUFSIZE_10240 0x00000014
|
||||
#define EMU_RECBS_BUFSIZE_12288 0x00000015
|
||||
#define EMU_RECBS_BUFSIZE_14366 0x00000016
|
||||
#define EMU_RECBS_BUFSIZE_16384 0x00000017
|
||||
#define EMU_RECBS_BUFSIZE_20480 0x00000018
|
||||
#define EMU_RECBS_BUFSIZE_24576 0x00000019
|
||||
#define EMU_RECBS_BUFSIZE_28672 0x0000001a
|
||||
#define EMU_RECBS_BUFSIZE_32768 0x0000001b
|
||||
#define EMU_RECBS_BUFSIZE_40960 0x0000001c
|
||||
#define EMU_RECBS_BUFSIZE_49152 0x0000001d
|
||||
#define EMU_RECBS_BUFSIZE_57344 0x0000001e
|
||||
#define EMU_RECBS_BUFSIZE_65536 0x0000001f
|
||||
|
||||
#define EMU_CDCS 0x50
|
||||
#define EMU_GPSCS 0x51
|
||||
|
||||
#define EMU_DBG 0x52
|
||||
#define EMU_DBG_ZC 0x80000000
|
||||
#define EMU_DBG_SATURATION_OCCURED 0x02000000
|
||||
#define EMU_DBG_SATURATION_ADDR 0x01ff0000
|
||||
#define EMU_DBG_SINGLE_STEP 0x00008000
|
||||
#define EMU_DBG_STEP 0x00004000
|
||||
#define EMU_DBG_CONDITION_CODE 0x00003e00
|
||||
#define EMU_DBG_SINGLE_STEP_ADDR 0x000001ff
|
||||
#define EMU_REG53 0x53
|
||||
|
||||
#define EMU_A_DBG 0x53
|
||||
#define EMU_A_DBG_SINGLE_STEP 0x00020000
|
||||
#define EMU_A_DBG_ZC 0x40000000
|
||||
#define EMU_A_DBG_STEP_ADDR 0x000003ff
|
||||
#define EMU_A_DBG_SATURATION_OCCRD 0x20000000
|
||||
#define EMU_A_DBG_SATURATION_ADDR 0x0ffc0000
|
||||
|
||||
#define EMU_SPCS0 0x54
|
||||
#define EMU_SPCS1 0x55
|
||||
#define EMU_SPCS2 0x56
|
||||
#define EMU_SPCS_CLKACCYMASK 0x30000000
|
||||
#define EMU_SPCS_CLKACCY_1000PPM 0x00000000
|
||||
#define EMU_SPCS_CLKACCY_50PPM 0x10000000
|
||||
#define EMU_SPCS_CLKACCY_VARIABLE 0x20000000
|
||||
#define EMU_SPCS_SAMPLERATEMASK 0x0f000000
|
||||
#define EMU_SPCS_SAMPLERATE_44 0x00000000
|
||||
#define EMU_SPCS_SAMPLERATE_48 0x02000000
|
||||
#define EMU_SPCS_SAMPLERATE_32 0x03000000
|
||||
#define EMU_SPCS_CHANNELNUMMASK 0x00f00000
|
||||
#define EMU_SPCS_CHANNELNUM_UNSPEC 0x00000000
|
||||
#define EMU_SPCS_CHANNELNUM_LEFT 0x00100000
|
||||
#define EMU_SPCS_CHANNELNUM_RIGHT 0x00200000
|
||||
#define EMU_SPCS_SOURCENUMMASK 0x000f0000
|
||||
#define EMU_SPCS_SOURCENUM_UNSPEC 0x00000000
|
||||
#define EMU_SPCS_GENERATIONSTATUS 0x00008000
|
||||
#define EMU_SPCS_CATEGORYCODEMASK 0x00007f00
|
||||
#define EMU_SPCS_MODEMASK 0x000000c0
|
||||
#define EMU_SPCS_EMPHASISMASK 0x00000038
|
||||
#define EMU_SPCS_EMPHASIS_NONE 0x00000000
|
||||
#define EMU_SPCS_EMPHASIS_50_15 0x00000008
|
||||
#define EMU_SPCS_COPYRIGHT 0x00000004
|
||||
#define EMU_SPCS_NOTAUDIODATA 0x00000002
|
||||
#define EMU_SPCS_PROFESSIONAL 0x00000001
|
||||
|
||||
#define EMU_CLIEL 0x58
|
||||
#define EMU_CLIEH 0x59
|
||||
#define EMU_CLIPL 0x5a
|
||||
#define EMU_CLIPH 0x5b
|
||||
#define EMU_SOLEL 0x5c
|
||||
#define EMU_SOLEH 0x5d
|
||||
|
||||
#define EMU_SPBYPASS 0x5e
|
||||
#define EMU_SPBYPASS_ENABLE 0x00000001
|
||||
|
||||
#define EMU_AC97SLOT 0x5f
|
||||
#define EMU_AC97SLOT_CENTER 0x00000010
|
||||
#define EMU_AC97SLOT_LFE 0x00000020
|
||||
|
||||
#define EMU_CDSRCS 0x60
|
||||
#define EMU_GPSRCS 0x61
|
||||
#define EMU_ZVSRCS 0x62
|
||||
#define EMU_SRCS_SPDIFLOCKED 0x02000000
|
||||
#define EMU_SRCS_RATELOCKED 0x01000000
|
||||
#define EMU_SRCS_ESTSAMPLERATE 0x0007ffff
|
||||
|
||||
#define EMU_MICIDX 0x63
|
||||
#define EMU_A_MICIDX 0x64
|
||||
#define EMU_ADCIDX 0x64
|
||||
#define EMU_A_ADCIDX 0x63
|
||||
#define EMU_FXIDX 0x65
|
||||
#define EMU_RECIDX_MASK 0x0000ffff
|
||||
#define EMU_RECIDX(idxreg) (0x10000000|(idxreg))
|
||||
|
||||
#define EMU_A_MUDATA1 0x70
|
||||
#define EMU_A_MUCMD1 0x71
|
||||
#define EMU_A_MUSTAT1 EMU_A_MUCMD1
|
||||
|
||||
#define EMU_A_MUDATA2 0x72
|
||||
#define EMU_A_MUCMD2 0x73
|
||||
#define EMU_A_MUSTAT2 EMU_A_MUCMD2
|
||||
|
||||
#define EMU_A_FXWC1 0x74
|
||||
#define EMU_A_FXWC2 0x75
|
||||
|
||||
#define EMU_A_SPDIF_SAMPLERATE 0x76
|
||||
#define EMU_A_SPDIF_48000 0x00000080
|
||||
#define EMU_A_SPDIF_44100 0x00000000
|
||||
#define EMU_A_SPDIF_96000 0x00000040
|
||||
#define EMU_A2_SPDIF_SAMPLERATE EMU_MKSUBREG(3, 9, EMU_A_SPDIF_SAMPLERATE)
|
||||
#define EMU_A2_SPDIF_MASK 0x00000e00
|
||||
#define EMU_A2_SPDIF_UNKNOWN 0x2
|
||||
|
||||
#define EMU_A_CHAN_FXRT2 0x7c
|
||||
#define EMU_A_CHAN_FXRT_CHANNELE 0x0000003f
|
||||
#define EMU_A_CHAN_FXRT_CHANNELF 0x00003f00
|
||||
#define EMU_A_CHAN_FXRT_CHANNELG 0x003f0000
|
||||
#define EMU_A_CHAN_FXRT_CHANNELH 0x3f000000
|
||||
|
||||
#define EMU_A_CHAN_SENDAMOUNTS 0x7d
|
||||
#define EMU_A_CHAN_FXSENDAMOUNTS_E_MASK 0xff000000
|
||||
#define EMU_A_CHAN_FXSENDAMOUNTS_F_MASK 0x00ff0000
|
||||
#define EMU_A_CHAN_FXSENDAMOUNTS_G_MASK 0x0000ff00
|
||||
#define EMU_A_CHAN_FXSENDAMOUNTS_H_MASK 0x000000ff
|
||||
|
||||
#define EMU_A_CHAN_FXRT1 0x7e
|
||||
#define EMU_A_CHAN_FXRT_CHANNELA 0x0000003f
|
||||
#define EMU_A_CHAN_FXRT_CHANNELB 0x00003f00
|
||||
#define EMU_A_CHAN_FXRT_CHANNELC 0x003f0000
|
||||
#define EMU_A_CHAN_FXRT_CHANNELD 0x3f000000
|
||||
|
||||
#define EMU_FXGPREGBASE 0x100
|
||||
#define EMU_A_FXGPREGBASE 0x400
|
||||
|
||||
#define EMU_TANKMEMDATAREGBASE 0x200
|
||||
#define EMU_TANKMEMDATAREG_MASK 0x000fffff
|
||||
|
||||
#define EMU_TANKMEMADDRREGBASE 0x300
|
||||
#define EMU_TANKMEMADDRREG_ADDR_MASK 0x000fffff
|
||||
#define EMU_TANKMEMADDRREG_CLEAR 0x00800000
|
||||
#define EMU_TANKMEMADDRREG_ALIGN 0x00400000
|
||||
#define EMU_TANKMEMADDRREG_WRITE 0x00200000
|
||||
#define EMU_TANKMEMADDRREG_READ 0x00100000
|
||||
|
||||
#define EMU_MICROCODEBASE 0x400
|
||||
#define EMU_DSP_LOWORD_OPX_MASK 0x000ffc00
|
||||
#define EMU_DSP_LOWORD_OPY_MASK 0x000003ff
|
||||
#define EMU_DSP_HIWORD_OPCODE_MASK 0x00f00000
|
||||
#define EMU_DSP_HIWORD_RESULT_MASK 0x000ffc00
|
||||
#define EMU_DSP_HIWORD_OPA_MASK 0x000003ff
|
||||
|
||||
#define EMU_A_MICROCODEBASE 0x600
|
||||
#define EMU_A_DSP_LOWORD_OPX_MASK 0x007ff000
|
||||
#define EMU_A_DSP_LOWORD_OPY_MASK 0x000007ff
|
||||
#define EMU_A_DSP_HIWORD_OPCODE_MASK 0x0f000000
|
||||
#define EMU_A_DSP_HIWORD_RESULT_MASK 0x007ff000
|
||||
#define EMU_A_DSP_HIWORD_OPA_MASK 0x000007ff
|
||||
|
||||
#define EMU_DSP_OP_MACS 0x0
|
||||
#define EMU_DSP_OP_MACS1 0x1
|
||||
#define EMU_DSP_OP_MACW 0x2
|
||||
#define EMU_DSP_OP_MACW1 0x3
|
||||
#define EMU_DSP_OP_MACINTS 0x4
|
||||
#define EMU_DSP_OP_MACINTW 0x5
|
||||
#define EMU_DSP_OP_ACC3 0x6
|
||||
#define EMU_DSP_OP_MACMV 0x7
|
||||
#define EMU_DSP_OP_ANDXOR 0x8
|
||||
#define EMU_DSP_OP_TSTNEG 0x9
|
||||
#define EMU_DSP_OP_LIMIT 0xa
|
||||
#define EMU_DSP_OP_LIMIT1 0xb
|
||||
#define EMU_DSP_OP_LOG 0xc
|
||||
#define EMU_DSP_OP_EXP 0xd
|
||||
#define EMU_DSP_OP_INTERP 0xe
|
||||
#define EMU_DSP_OP_SKIP 0xf
|
||||
|
||||
|
||||
#define EMU_DSP_FX(num) (num)
|
||||
|
||||
#define EMU_DSP_IOL(base, num) (base + (num << 1))
|
||||
#define EMU_DSP_IOR(base, num) (EMU_DSP_IOL(base, num) + 1)
|
||||
|
||||
#define EMU_DSP_INL_BASE 0x010
|
||||
#define EMU_DSP_INL(num) (EMU_DSP_IOL(EMU_DSP_INL_BASE, num))
|
||||
#define EMU_DSP_INR(num) (EMU_DSP_IOR(EMU_DSP_INL_BASE, num))
|
||||
#define EMU_DSP_IN_AC97 0
|
||||
#define EMU_DSP_IN_CDSPDIF 1
|
||||
#define EMU_DSP_IN_ZOOM 2
|
||||
#define EMU_DSP_IN_TOSOPT 3
|
||||
#define EMU_DSP_IN_LVDLM1 4
|
||||
#define EMU_DSP_IN_LVDCOS 5
|
||||
#define EMU_DSP_IN_LVDLM2 6
|
||||
#define EMU_DSP_IN_UNKOWN 7
|
||||
|
||||
#define EMU_A_DSP_INL_BASE 0x040
|
||||
#define EMU_A_DSP_INL(num) (EMU_DSP_IOL(EMU_A_DSP_INL_BASE, num))
|
||||
#define EMU_A_DSP_INR(num) (EMU_DSP_IOR(EMU_A_DSP_INL_BASE, num))
|
||||
|
||||
#define EMU_DSP_OUTL_BASE 0x020
|
||||
#define EMU_DSP_OUTL(num) (EMU_DSP_IOL(EMU_DSP_OUTL_BASE, num))
|
||||
#define EMU_DSP_OUTR(num) (EMU_DSP_IOR(EMU_DSP_OUTL_BASE, num))
|
||||
#define EMU_DSP_OUT_A_FRONT 0
|
||||
#define EMU_DSP_OUT_D_FRONT 1 // not tested
|
||||
#define EMU_DSP_OUT_D_CENTER 2 // not tested
|
||||
#define EMU_DSP_OUT_DRIVE_HP 3 // not tested
|
||||
#define EMU_DSP_OUT_AD_REAR 4
|
||||
#define EMU_DSP_OUT_ADC 5
|
||||
#define EMU_DSP_OUTL_MIC 6
|
||||
#define EMU_DSP_OUT_A_CENTER (EMU_DSP_IOR(EMU_DSP_OUTL_BASE, 8)) // Live 5.1 only
|
||||
#define EMU_DSP_OUT_A_SUB (EMU_DSP_IOL(EMU_DSP_OUTL_BASE, 9)) // Live 5.1 only
|
||||
|
||||
#define EMU_A_DSP_OUTL_BASE 0x060
|
||||
#define EMU_A_DSP_OUTL(num) (EMU_DSP_IOL(EMU_A_DSP_OUTL_BASE, num))
|
||||
#define EMU_A_DSP_OUTR(num) (EMU_DSP_IOR(EMU_A_DSP_OUTL_BASE, num))
|
||||
#define EMU_A_DSP_OUT_D_FRONT 0 // not tested
|
||||
#define EMU_A_DSP_OUT_D_CENTER 1 // not tested
|
||||
#define EMU_A_DSP_OUT_DRIVE_HP 2 // not tested
|
||||
#define EMU_A_DSP_OUT_D_REAR 3 // not tested
|
||||
#define EMU_A_DSP_OUT_A_FRONT 4
|
||||
#define EMU_A_DSP_OUT_A_CENTER 5
|
||||
#define EMU_A_DSP_OUT_A_REAR 7
|
||||
#define EMU_A_DSP_OUT_ADC 11
|
||||
|
||||
|
||||
#define EMU_DSP_CST_BASE 0x40
|
||||
#define EMU_A_DSP_CST_BASE 0xc0
|
||||
#define EMU_DSP_CST(num) (EMU_DSP_CST_BASE + num)
|
||||
#define EMU_A_DSP_CST(num) (EMU_A_DSP_CST_BASE + num)
|
||||
/*
|
||||
00 = 0x00000000
|
||||
01 = 0x00000001
|
||||
02 = 0x00000002
|
||||
03 = 0x00000003
|
||||
04 = 0x00000004
|
||||
05 = 0x00000008
|
||||
06 = 0x00000010
|
||||
07 = 0x00000020
|
||||
08 = 0x00000100
|
||||
09 = 0x00010000
|
||||
0A = 0x00080000
|
||||
0B = 0x10000000
|
||||
0C = 0x20000000
|
||||
0D = 0x40000000
|
||||
0E = 0x80000000
|
||||
0F = 0x7FFFFFFF
|
||||
10 = 0xFFFFFFFF
|
||||
11 = 0xFFFFFFFE
|
||||
12 = 0xC0000000
|
||||
13 = 0x4F1BBCDC
|
||||
14 = 0x5A7EF9DB
|
||||
15 = 0x00100000
|
||||
*/
|
||||
|
||||
#define EMU_DSP_HWR_ACC 0x056
|
||||
#define EMU_DSP_HWR_CCR 0x057
|
||||
#define EMU_DSP_HWR_CCR_S 0x04
|
||||
#define EMU_DSP_HWR_CCR_Z 0x03
|
||||
#define EMU_DSP_HWR_CCR_M 0x02
|
||||
#define EMU_DSP_HWR_CCR_N 0x01
|
||||
#define EMU_DSP_HWR_CCR_B 0x00
|
||||
#define EMU_DSP_HWR_NOISE0 0x058
|
||||
#define EMU_DSP_HWR_NOISE1 0x059
|
||||
#define EMU_DSP_HWR_INTR 0x05A
|
||||
#define EMU_DSP_HWR_DBAC 0x05B
|
||||
|
||||
#define EMU_DSP_GPR(num) (EMU_FXGPREGBASE + num)
|
||||
#define EMU_A_DSP_GPR(num) (EMU_A_FXGPREGBASE + num)
|
||||
|
||||
#endif /* _DEV_PCI_EMUXKIREG_H_ */
|
||||
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Emuxki BeOS Driver for Creative Labs SBLive!/Audigy series
|
||||
*
|
||||
* Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr)
|
||||
*
|
||||
* Original code : BeOS Driver for Intel ICH AC'97 Link interface
|
||||
* Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 <KernelExport.h>
|
||||
#include <OS.h>
|
||||
#include "io.h"
|
||||
#include "emuxkireg.h"
|
||||
|
||||
/*
|
||||
* from BeOS R3 KernelExport.h
|
||||
* should be replaced by PCI bus manager functions
|
||||
*/
|
||||
uint8 read_io_8(int mapped_io_addr);
|
||||
void write_io_8(int mapped_io_addr, uint8 value);
|
||||
uint16 read_io_16(int mapped_io_addr);
|
||||
void write_io_16(int mapped_io_addr, uint16 value);
|
||||
uint32 read_io_32(int mapped_io_addr);
|
||||
void write_io_32(int mapped_io_addr, uint32 value);
|
||||
|
||||
uint8
|
||||
emuxki_reg_read_8(device_config *config, int regno)
|
||||
{
|
||||
return read_io_8(config->nabmbar + regno);
|
||||
}
|
||||
|
||||
uint16
|
||||
emuxki_reg_read_16(device_config *config, int regno)
|
||||
{
|
||||
return read_io_16(config->nabmbar + regno);
|
||||
}
|
||||
|
||||
uint32
|
||||
emuxki_reg_read_32(device_config *config, int regno)
|
||||
{
|
||||
return read_io_32(config->nabmbar + regno);
|
||||
}
|
||||
|
||||
void
|
||||
emuxki_reg_write_8(device_config *config, int regno, uint8 value)
|
||||
{
|
||||
write_io_8(config->nabmbar + regno, value);
|
||||
}
|
||||
|
||||
void
|
||||
emuxki_reg_write_16(device_config *config, int regno, uint16 value)
|
||||
{
|
||||
write_io_16(config->nabmbar + regno, value);
|
||||
}
|
||||
|
||||
void
|
||||
emuxki_reg_write_32(device_config *config, int regno, uint32 value)
|
||||
{
|
||||
write_io_32(config->nabmbar + regno, value);
|
||||
}
|
||||
|
||||
/* Emu10k1 Low level */
|
||||
|
||||
uint32
|
||||
emuxki_chan_read(device_config *config, uint16 chano, uint32 reg)
|
||||
{
|
||||
uint32 ptr, mask = 0xFFFFFFFF;
|
||||
uint8 size, offset = 0;
|
||||
|
||||
ptr = ((((uint32) reg) << 16) &
|
||||
(IS_AUDIGY(config) ? EMU_A_PTR_ADDR_MASK : EMU_PTR_ADDR_MASK)) |
|
||||
(chano & EMU_PTR_CHNO_MASK);
|
||||
if (reg & 0xff000000) {
|
||||
size = (reg >> 24) & 0x3f;
|
||||
offset = (reg >> 16) & 0x1f;
|
||||
mask = ((1 << size) - 1) << offset;
|
||||
}
|
||||
write_io_32(config->nabmbar + EMU_PTR, ptr);
|
||||
ptr = (read_io_32(config->nabmbar + EMU_DATA) & mask) >> offset;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void
|
||||
emuxki_chan_write(device_config *config, uint16 chano,
|
||||
uint32 reg, uint32 data)
|
||||
{
|
||||
uint32 ptr, mask;
|
||||
uint8 size, offset;
|
||||
|
||||
ptr = ((((uint32) reg) << 16) &
|
||||
(IS_AUDIGY(config) ? EMU_A_PTR_ADDR_MASK : EMU_PTR_ADDR_MASK)) |
|
||||
(chano & EMU_PTR_CHNO_MASK);
|
||||
if (reg & 0xff000000) {
|
||||
size = (reg >> 24) & 0x3f;
|
||||
offset = (reg >> 16) & 0x1f;
|
||||
mask = ((1 << size) - 1) << offset;
|
||||
data = ((data << offset) & mask) |
|
||||
(emuxki_chan_read(config, chano, reg & 0xFFFF) & ~mask);
|
||||
}
|
||||
write_io_32(config->nabmbar + EMU_PTR, ptr);
|
||||
write_io_32(config->nabmbar + EMU_DATA, data);
|
||||
}
|
||||
|
||||
/* Microcode */
|
||||
|
||||
void
|
||||
emuxki_write_micro(device_config *config, uint32 pc, uint32 data)
|
||||
{
|
||||
emuxki_chan_write(config, 0, (IS_AUDIGY(config) ? EMU_A_MICROCODEBASE :
|
||||
EMU_MICROCODEBASE ) + pc, data);
|
||||
}
|
||||
|
||||
uint32
|
||||
emuxki_read_micro(device_config *config, uint32 pc)
|
||||
{
|
||||
return emuxki_chan_read(config, 0, (IS_AUDIGY(config) ? EMU_A_MICROCODEBASE :
|
||||
EMU_MICROCODEBASE ) + pc);
|
||||
}
|
||||
|
||||
void
|
||||
emuxki_dsp_addop(device_config *config, uint16 *pc, uint8 op,
|
||||
uint16 r, uint16 a, uint16 x, uint16 y)
|
||||
{
|
||||
if(IS_AUDIGY(config)) {
|
||||
emuxki_write_micro(config, *pc << 1,
|
||||
((x << 12) & EMU_A_DSP_LOWORD_OPX_MASK) |
|
||||
(y & EMU_A_DSP_LOWORD_OPY_MASK));
|
||||
emuxki_write_micro(config, (*pc << 1) + 1,
|
||||
((op << 24) & EMU_A_DSP_HIWORD_OPCODE_MASK) |
|
||||
((r << 12) & EMU_A_DSP_HIWORD_RESULT_MASK) |
|
||||
(a & EMU_A_DSP_HIWORD_OPA_MASK));
|
||||
} else {
|
||||
emuxki_write_micro(config, *pc << 1,
|
||||
((x << 10) & EMU_DSP_LOWORD_OPX_MASK) |
|
||||
(y & EMU_DSP_LOWORD_OPY_MASK));
|
||||
emuxki_write_micro(config, (*pc << 1) + 1,
|
||||
((op << 20) & EMU_DSP_HIWORD_OPCODE_MASK) |
|
||||
((r << 10) & EMU_DSP_HIWORD_RESULT_MASK) |
|
||||
(a & EMU_DSP_HIWORD_OPA_MASK));
|
||||
}
|
||||
(*pc)++;
|
||||
}
|
||||
|
||||
void
|
||||
emuxki_dsp_getop(device_config *config, uint16 *pc, uint8 *op,
|
||||
uint16 *r, uint16 *a, uint16 *x, uint16 *y)
|
||||
{
|
||||
uint32 value;
|
||||
if(IS_AUDIGY(config)) {
|
||||
value = emuxki_read_micro(config, *pc << 1);
|
||||
*x = (value & EMU_A_DSP_LOWORD_OPX_MASK) >> 12;
|
||||
*y = value & EMU_A_DSP_LOWORD_OPY_MASK;
|
||||
value = emuxki_read_micro(config, (*pc << 1) + 1);
|
||||
*op = (value & EMU_A_DSP_HIWORD_OPCODE_MASK) >> 24;
|
||||
*r = (value & EMU_A_DSP_HIWORD_RESULT_MASK) >> 12;
|
||||
*a = value & EMU_A_DSP_HIWORD_OPA_MASK;
|
||||
} else {
|
||||
value = emuxki_read_micro(config, *pc << 1);
|
||||
*x = (value & EMU_DSP_LOWORD_OPX_MASK) >> 10;
|
||||
*y = value & EMU_DSP_LOWORD_OPY_MASK;
|
||||
value = emuxki_read_micro(config, (*pc << 1) + 1);
|
||||
*op = (value & EMU_DSP_HIWORD_OPCODE_MASK) >> 20;
|
||||
*r = (value & EMU_DSP_HIWORD_RESULT_MASK) >> 10;
|
||||
*a = value & EMU_DSP_HIWORD_OPA_MASK;
|
||||
}
|
||||
(*pc)++;
|
||||
}
|
||||
|
||||
/* Gpr */
|
||||
|
||||
void
|
||||
emuxki_write_gpr(device_config *config, uint32 pc, uint32 data)
|
||||
{
|
||||
emuxki_chan_write(config, 0, IS_AUDIGY(config) ? EMU_A_DSP_GPR(pc) :
|
||||
EMU_DSP_GPR(pc), data);
|
||||
}
|
||||
|
||||
uint32
|
||||
emuxki_read_gpr(device_config *config, uint32 pc)
|
||||
{
|
||||
return emuxki_chan_read(config, 0, IS_AUDIGY(config) ? EMU_A_DSP_GPR(pc) :
|
||||
EMU_DSP_GPR(pc));
|
||||
}
|
||||
|
||||
/* codec */
|
||||
|
||||
uint16
|
||||
emuxki_codec_read(device_config *config, int regno)
|
||||
{
|
||||
write_io_8(config->nabmbar + EMU_AC97ADDR, regno);
|
||||
return read_io_16(config->nabmbar + EMU_AC97DATA);
|
||||
}
|
||||
|
||||
void
|
||||
emuxki_codec_write(device_config *config, int regno, uint16 value)
|
||||
{
|
||||
write_io_8(config->nabmbar + EMU_AC97ADDR, regno);
|
||||
write_io_16(config->nabmbar + EMU_AC97DATA, value);
|
||||
}
|
||||
|
||||
/* inte */
|
||||
|
||||
void
|
||||
emuxki_inte_enable(device_config *config, uint32 value)
|
||||
{
|
||||
emuxki_reg_write_32(config, EMU_INTE,
|
||||
emuxki_reg_read_32(config, EMU_INTE) | value);
|
||||
}
|
||||
|
||||
void
|
||||
emuxki_inte_disable(device_config *config, uint32 value)
|
||||
{
|
||||
emuxki_reg_write_32(config, EMU_INTE,
|
||||
emuxki_reg_read_32(config, EMU_INTE) & ~value);
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Emuxki BeOS Driver for Creative Labs SBLive!/Audigy series
|
||||
*
|
||||
* Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr)
|
||||
*
|
||||
* Original code : BeOS Driver for Intel ICH AC'97 Link interface
|
||||
* Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _IO_H_
|
||||
#define _IO_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
uint8 emuxki_reg_read_8(device_config *config, int regno);
|
||||
uint16 emuxki_reg_read_16(device_config *config, int regno);
|
||||
uint32 emuxki_reg_read_32(device_config *config, int regno);
|
||||
|
||||
void emuxki_reg_write_8(device_config *config, int regno, uint8 value);
|
||||
void emuxki_reg_write_16(device_config *config, int regno, uint16 value);
|
||||
void emuxki_reg_write_32(device_config *config, int regno, uint32 value);
|
||||
|
||||
uint32 emuxki_chan_read(device_config *config, uint16 chano, uint32 reg);
|
||||
void emuxki_chan_write(device_config *config, uint16 chano, uint32 reg, uint32 data);
|
||||
|
||||
void emuxki_dsp_addop(device_config *config, uint16 *pc, uint8 op,
|
||||
uint16 r, uint16 a, uint16 x, uint16 y);
|
||||
void emuxki_dsp_getop(device_config *config, uint16 *pc, uint8 *op,
|
||||
uint16 *r, uint16 *a, uint16 *x, uint16 *y);
|
||||
|
||||
void emuxki_write_gpr(device_config *config, uint32 pc, uint32 data);
|
||||
uint32 emuxki_read_gpr(device_config *config, uint32 pc);
|
||||
|
||||
uint16 emuxki_codec_read(device_config *config, int regno);
|
||||
void emuxki_codec_write(device_config *config, int regno, uint16 value);
|
||||
|
||||
void emuxki_inte_enable(device_config *config, uint32 value);
|
||||
void emuxki_inte_disable(device_config *config, uint32 value);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Emuxki BeOS Driver for Creative Labs SBLive!/Audigy series
|
||||
*
|
||||
* Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr)
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
|
||||
*
|
||||
*
|
||||
* Original code : Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
* This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "emuxki.h"
|
||||
#include "io.h"
|
||||
#include "debug.h"
|
||||
#include "midi_driver.h"
|
||||
#include "util.h"
|
||||
|
||||
extern generic_mpu401_module * mpu401;
|
||||
|
||||
void
|
||||
midi_interrupt_op(
|
||||
int32 op,
|
||||
void * data)
|
||||
{
|
||||
// dprint seems to be disabled here, will have to enable it to trace
|
||||
|
||||
midi_dev * port = (midi_dev *)data;
|
||||
TRACE(("port = %p\n", port));
|
||||
if (op == B_MPU_401_ENABLE_CARD_INT) {
|
||||
// sample code
|
||||
/*cpu_status cp;
|
||||
ddprintf(("sonic_vibes: B_MPU_401_ENABLE_CARD_INT\n"));
|
||||
cp = disable_interrupts();
|
||||
acquire_spinlock(&port->card->hardware);
|
||||
increment_interrupt_handler(port->card);
|
||||
set_direct(port->card, 0x01, 0x00, 0x80);
|
||||
set_indirect(port->card, 0x2A, 0x04, 0xff);
|
||||
release_spinlock(&port->card->hardware);
|
||||
restore_interrupts(cp);*/
|
||||
|
||||
//real code
|
||||
cpu_status status;
|
||||
status = lock();
|
||||
emuxki_reg_write_32(&(port->card->config), EMU_INTE,
|
||||
emuxki_reg_read_32(&(port->card->config), EMU_INTE) |
|
||||
EMU_INTE_MIDITXENABLE | EMU_INTE_MIDIRXENABLE );
|
||||
unlock(status);
|
||||
}
|
||||
else if (op == B_MPU_401_DISABLE_CARD_INT) {
|
||||
// sample code
|
||||
/* turn off MPU interrupts */
|
||||
/*cpu_status cp;
|
||||
ddprintf(("sonic_vibes: B_MPU_401_DISABLE_CARD_INT\n"));
|
||||
cp = disable_interrupts();
|
||||
acquire_spinlock(&port->card->hardware);
|
||||
set_direct(port->card, 0x01, 0x80, 0x80);*/
|
||||
/* remove interrupt handler if necessary */
|
||||
/*decrement_interrupt_handler(port->card);
|
||||
release_spinlock(&port->card->hardware);
|
||||
restore_interrupts(cp);*/
|
||||
|
||||
//real code
|
||||
cpu_status status;
|
||||
status = lock();
|
||||
emuxki_reg_write_32(&port->card->config, EMU_INTE,
|
||||
emuxki_reg_read_32(&port->card->config, EMU_INTE) &
|
||||
~ (EMU_INTE_MIDITXENABLE | EMU_INTE_MIDIRXENABLE ) );
|
||||
unlock(status);
|
||||
}
|
||||
TRACE(("midi_interrupt_op() done\n"));
|
||||
}
|
||||
|
||||
static status_t midi_open(const char *name, uint32 flags, void **cookie);
|
||||
static status_t midi_close(void *cookie);
|
||||
static status_t midi_free(void *cookie);
|
||||
static status_t midi_control(void *cookie, uint32 op, void *data, size_t len);
|
||||
static status_t midi_read(void *cookie, off_t pos, void *data, size_t *len);
|
||||
static status_t midi_write(void *cookie, off_t pos, const void *data, size_t *len);
|
||||
|
||||
|
||||
device_hooks midi_hooks = {
|
||||
&midi_open,
|
||||
&midi_close,
|
||||
&midi_free,
|
||||
&midi_control,
|
||||
&midi_read,
|
||||
&midi_write,
|
||||
NULL, /* select */
|
||||
NULL, /* deselect */
|
||||
NULL, /* readv */
|
||||
NULL /* writev */
|
||||
};
|
||||
|
||||
static status_t
|
||||
midi_open(
|
||||
const char * name,
|
||||
uint32 flags,
|
||||
void ** cookie)
|
||||
{
|
||||
int ix;
|
||||
int ret;
|
||||
|
||||
LOG(("midi_open()\n"));
|
||||
|
||||
*cookie = NULL;
|
||||
for (ix=0; ix<num_cards; ix++) {
|
||||
if (!strcmp(name, cards[ix].midi.name)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ix >= num_cards) {
|
||||
LOG(("bad device\n"));
|
||||
return ENODEV;
|
||||
}
|
||||
|
||||
LOG(("mpu401: %p open(): %p driver: %p\n", mpu401, mpu401->open_hook, cards[ix].midi.driver));
|
||||
ret = (*mpu401->open_hook)(cards[ix].midi.driver, flags, cookie);
|
||||
if (ret >= B_OK) {
|
||||
cards[ix].midi.cookie = *cookie;
|
||||
atomic_add(&cards[ix].midi.count, 1);
|
||||
}
|
||||
LOG(("mpu401: open returns %x / %p\n", ret, *cookie));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
midi_close(
|
||||
void * cookie)
|
||||
{
|
||||
LOG(("midi_close()\n"));
|
||||
return (*mpu401->close_hook)(cookie);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
midi_free(
|
||||
void * cookie)
|
||||
{
|
||||
int ix;
|
||||
status_t f;
|
||||
LOG(("midi_free()\n"));
|
||||
f = (*mpu401->free_hook)(cookie);
|
||||
for (ix=0; ix<num_cards; ix++) {
|
||||
if (cards[ix].midi.cookie == cookie) {
|
||||
if (atomic_add(&cards[ix].midi.count, -1) == 1) {
|
||||
cards[ix].midi.cookie = NULL;
|
||||
LOG(("cleared %p card %d\n", cookie, ix));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
LOG(("midi_free() done\n"));
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
midi_control(
|
||||
void * cookie,
|
||||
uint32 iop,
|
||||
void * data,
|
||||
size_t len)
|
||||
{
|
||||
return (*mpu401->control_hook)(cookie, iop, data, len);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
midi_read(
|
||||
void * cookie,
|
||||
off_t pos,
|
||||
void * ptr,
|
||||
size_t * nread)
|
||||
{
|
||||
return (*mpu401->read_hook)(cookie, pos, ptr, nread);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
midi_write(
|
||||
void * cookie,
|
||||
off_t pos,
|
||||
const void * ptr,
|
||||
size_t * nwritten)
|
||||
{
|
||||
return (*mpu401->write_hook)(cookie, pos, ptr, nwritten);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
midi_interrupt(emuxki_dev *card)
|
||||
{
|
||||
TRACE(("midi_interrupt\n"));
|
||||
if (!card->midi.driver) {
|
||||
// kprintf("aiigh\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return (*mpu401->interrupt_hook)(card->midi.driver);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/* ++++++++++
|
||||
FILE: midi_driver.h
|
||||
REVS: $Revision: 1.1 $
|
||||
NAME: herold
|
||||
DATE: Tue Jun 4 15:23:29 PDT 1996
|
||||
|
||||
Interface to /dev/midi, the midi driver
|
||||
+++++ */
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#ifndef _MIDI_DRIVER_H
|
||||
#define _MIDI_DRIVER_H
|
||||
|
||||
#include <Drivers.h>
|
||||
#include <module.h>
|
||||
|
||||
/* -----
|
||||
ioctl codes
|
||||
----- */
|
||||
|
||||
/* the old opcodes are deprecated, and may or may not work
|
||||
in newer drivers */
|
||||
enum {
|
||||
B_MIDI_GET_READ_TIMEOUT = B_MIDI_DRIVER_BASE,
|
||||
B_MIDI_SET_READ_TIMEOUT,
|
||||
B_MIDI_TIMED_READ,
|
||||
B_MIDI_TIMED_WRITE,
|
||||
B_MIDI_WRITE_SYNC,
|
||||
B_MIDI_WRITE_CLEAR,
|
||||
B_MIDI_GET_READ_TIMEOUT_OLD = B_DEVICE_OP_CODES_END + 1,
|
||||
B_MIDI_SET_READ_TIMEOUT_OLD
|
||||
};
|
||||
|
||||
/* the default timeout when you open a midi driver */
|
||||
#define B_MIDI_DEFAULT_TIMEOUT 1000000000000000LL
|
||||
|
||||
/* Usage:
|
||||
To read, set "data" to a pointer to your buffer, and "size" to the
|
||||
maximum size of this buffer. On return, "when" will contain the time
|
||||
at which the data was received (first byte) and "size" will contain
|
||||
the actual amount of data read.
|
||||
Call ioctl(fd, B_MIDI_TIMED_READ, &midi_timed_data, sizeof(midi_timed_data));
|
||||
To write, set "when" to when you want the first byte to go out the
|
||||
wire, set "data" to point to your data, and set "size" to the size
|
||||
of your data.
|
||||
Call ioctl(fd, B_MIDI_TIMED_WRITE, &midi_timed_data, sizeof(midi_timed_data));
|
||||
*/
|
||||
typedef struct {
|
||||
bigtime_t when;
|
||||
size_t size;
|
||||
unsigned char * data;
|
||||
} midi_timed_data;
|
||||
|
||||
|
||||
/* The MIDI parser returns the number of bytes that a message contains, given the */
|
||||
/* initial byte. For some messages, this is not known until the second byte is seen. */
|
||||
/* For such messages, a state > 0 is returned as well as some count > 0. When state */
|
||||
/* is > 0, you should call (*parse) for the next byte as well, which might modify */
|
||||
/* the returned message size. Message size will always be returned with the current */
|
||||
/* byte being counted as byte 1. A return of 0 means that the byte initiates a new */
|
||||
/* message. SysX is handled by returning max_size until the end or next initial message */
|
||||
/* is seen. So your loop looks something like: */
|
||||
/*
|
||||
uint32 state = 0; // Only set this to 0 the first time you call the parser.
|
||||
// preserve the 'state' between invocations of your read() hook.
|
||||
int todo = 0;
|
||||
unsigned char * end = in_buf+buf_size
|
||||
unsigned char * out_buf = in_buf;
|
||||
while (true) {
|
||||
uchar byte = read_midi();
|
||||
if (!todo || state) {
|
||||
todo = (*parser->parse)(&state, byte, end-out_buf);
|
||||
}
|
||||
if (todo < 1) {
|
||||
unput_midi(byte);
|
||||
} else {
|
||||
*(out_buf++) = byte;
|
||||
todo--;
|
||||
}
|
||||
if (todo < 1 || out_buf >= end) {
|
||||
received_midi_message(in_buf, out_buf-in_buf);
|
||||
todo = 0;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#define B_MIDI_PARSER_MODULE_NAME "media/midiparser/v1"
|
||||
|
||||
typedef struct _midi_parser_module_info {
|
||||
module_info minfo;
|
||||
int (*parse)(uint32 * state, uchar byte, size_t max_size);
|
||||
int _reserved_;
|
||||
} midi_parser_module_info;
|
||||
|
||||
#define B_MPU_401_MODULE_NAME "generic/mpu401/v1"
|
||||
|
||||
enum {
|
||||
B_MPU_401_ENABLE_CARD_INT = 1,
|
||||
B_MPU_401_DISABLE_CARD_INT
|
||||
};
|
||||
typedef struct _generic_mpu401_module {
|
||||
module_info minfo;
|
||||
status_t (*create_device)(int port, void ** out_storage, uint32 workarounds, void (*interrupt_op)(int32 op, void * card), void * card);
|
||||
status_t (*delete_device)(void * storage);
|
||||
status_t (*open_hook)(void * storage, uint32 flags, void ** out_cookie);
|
||||
status_t (*close_hook)(void * cookie);
|
||||
status_t (*free_hook)(void * cookie);
|
||||
status_t (*control_hook)(void * cookie, uint32 op, void * data, size_t len);
|
||||
status_t (*read_hook)(void * cookie, off_t pos, void * data, size_t * len);
|
||||
status_t (*write_hook)(void * cookie, off_t pos, const void * data, size_t * len);
|
||||
bool (*interrupt_hook)(void * cookie);
|
||||
int _reserved_;
|
||||
} generic_mpu401_module;
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* BeOS Driver for Creative Labs SBLive! series
|
||||
*
|
||||
* Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr)
|
||||
*
|
||||
* Original code : BeOS Driver for Intel ICH AC'97 Link interface
|
||||
* Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _MULTI_H_
|
||||
#define _MULTI_H_
|
||||
|
||||
#define BUFFER_FRAMES 512
|
||||
//#define BUFFER_FRAMES 32 // this is the minimum which works
|
||||
#define BUFFER_COUNT 2
|
||||
|
||||
typedef struct _multi_mixer_control {
|
||||
struct _multi_dev *multi;
|
||||
void (*get) (void *card, const void *cookie, int32 type, float *values);
|
||||
void (*set) (void *card, const void *cookie, int32 type, float *values);
|
||||
const void *cookie;
|
||||
int32 type;
|
||||
multi_mix_control mix_control;
|
||||
} multi_mixer_control;
|
||||
|
||||
#define EMU_MULTI_CONTROL_FIRSTID 1024
|
||||
#define EMU_MULTI_CONTROL_MASTERID 0
|
||||
|
||||
typedef struct _multi_dev {
|
||||
void *card;
|
||||
#define EMU_MULTICONTROLSNUM 64
|
||||
multi_mixer_control controls[EMU_MULTICONTROLSNUM];
|
||||
uint32 control_count;
|
||||
|
||||
#define EMU_MULTICHANNUM 64
|
||||
multi_channel_info chans[EMU_MULTICHANNUM];
|
||||
uint32 output_channel_count;
|
||||
uint32 input_channel_count;
|
||||
uint32 output_bus_channel_count;
|
||||
uint32 input_bus_channel_count;
|
||||
uint32 aux_bus_channel_count;
|
||||
} multi_dev;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,699 @@
|
||||
/* multi_audio.h */
|
||||
|
||||
/* Interface description for drivers implementing studio-level audio I/O with */
|
||||
/* possible auxillary functions (transport, time code, etc). */
|
||||
/* Copyright © 1998-1999 Be Incorporated. All rights reserved. */
|
||||
|
||||
/* This is the first release candidate for the API. Unless we hear feedback that */
|
||||
/* forces a change before the end of August, we will try to stay binary compatible */
|
||||
/* with this interface. */
|
||||
/* Send feedback to [email protected] [1999-07-02] */
|
||||
|
||||
#if !defined(_MULTI_AUDIO_H)
|
||||
#define _MULTI_AUDIO_H
|
||||
|
||||
#include <Drivers.h>
|
||||
#include <Debug.h>
|
||||
|
||||
#define B_MULTI_DRIVER_BASE (B_AUDIO_DRIVER_BASE+20)
|
||||
|
||||
enum { /* open() modes */
|
||||
/* O_RDONLY is 0, O_WRONLY is 1, O_RDWR is 2 */
|
||||
B_MULTI_CONTROL = 3
|
||||
};
|
||||
|
||||
/* ioctl codes */
|
||||
enum {
|
||||
/* multi_description */
|
||||
B_MULTI_GET_DESCRIPTION = B_MULTI_DRIVER_BASE,
|
||||
/* multi_event_handling */
|
||||
B_MULTI_GET_EVENT_INFO,
|
||||
B_MULTI_SET_EVENT_INFO,
|
||||
B_MULTI_GET_EVENT,
|
||||
/* multi_channel_enable */
|
||||
B_MULTI_GET_ENABLED_CHANNELS,
|
||||
B_MULTI_SET_ENABLED_CHANNELS,
|
||||
/* multi_format_info */
|
||||
B_MULTI_GET_GLOBAL_FORMAT,
|
||||
B_MULTI_SET_GLOBAL_FORMAT, /* always sets for all channels, always implemented */
|
||||
/* multi_channel_formats */
|
||||
B_MULTI_GET_CHANNEL_FORMATS,
|
||||
B_MULTI_SET_CHANNEL_FORMATS, /* only implemented if possible */
|
||||
/* multi_mix_value_info */
|
||||
B_MULTI_GET_MIX,
|
||||
B_MULTI_SET_MIX,
|
||||
/* multi_mix_channel_info */
|
||||
B_MULTI_LIST_MIX_CHANNELS,
|
||||
/* multi_mix_control_info */
|
||||
B_MULTI_LIST_MIX_CONTROLS,
|
||||
/* multi_mix_connection_info */
|
||||
B_MULTI_LIST_MIX_CONNECTIONS,
|
||||
/* multi_buffer_list */
|
||||
B_MULTI_GET_BUFFERS, /* Fill out the struct for the first time; doesn't start anything. */
|
||||
B_MULTI_SET_BUFFERS, /* Set what buffers to use, if the driver supports soft buffers. */
|
||||
/* bigtime_t */
|
||||
B_MULTI_SET_START_TIME, /* When to actually start */
|
||||
/* multi_buffer_info */
|
||||
B_MULTI_BUFFER_EXCHANGE, /* stop and go are derived from this being called */
|
||||
B_MULTI_BUFFER_FORCE_STOP, /* force stop of playback */
|
||||
/* extension protocol */
|
||||
B_MULTI_LIST_EXTENSIONS, /* get a list of supported extensions */
|
||||
B_MULTI_GET_EXTENSION, /* get the value of an extension (or return error if not supported) */
|
||||
B_MULTI_SET_EXTENSION, /* set the value of an extension */
|
||||
/* multi_mode_list */
|
||||
B_MULTI_LIST_MODES, /* get a list of possible modes (multi_mode_list * arg) */
|
||||
B_MULTI_GET_MODE, /* get the current mode (int32 * arg) */
|
||||
B_MULTI_SET_MODE /* set a new mode (int32 * arg) */
|
||||
};
|
||||
|
||||
/* sample rate values */
|
||||
/* various fixed sample rates we support (for hard-sync clocked values) */
|
||||
#define B_SR_8000 0x1
|
||||
#define B_SR_11025 0x2
|
||||
#define B_SR_12000 0x4
|
||||
#define B_SR_16000 0x8
|
||||
#define B_SR_22050 0x10
|
||||
#define B_SR_24000 0x20
|
||||
#define B_SR_32000 0x40
|
||||
#define B_SR_44100 0x80
|
||||
#define B_SR_48000 0x100
|
||||
#define B_SR_64000 0x200
|
||||
#define B_SR_88200 0x400
|
||||
#define B_SR_96000 0x800
|
||||
#define B_SR_176400 0x1000
|
||||
#define B_SR_192000 0x2000
|
||||
#define B_SR_384000 0x4000
|
||||
#define B_SR_1536000 0x10000
|
||||
/* continuously variable sample rate (typically board-generated) */
|
||||
#define B_SR_CVSR 0x10000000UL
|
||||
/* sample rate parameter global to all channels (input and output rates respectively) */
|
||||
#define B_SR_IS_GLOBAL 0x80000000UL
|
||||
/* output sample rate locked to input sample rate (output_rates only; the common case!) */
|
||||
#define B_SR_SAME_AS_INPUT 0x40000000UL
|
||||
|
||||
|
||||
/* format values */
|
||||
/* signed char */
|
||||
#define B_FMT_8BIT_S 0x01
|
||||
/* unsigned char -- this is special case */
|
||||
#define B_FMT_8BIT_U 0x02
|
||||
/* traditional 16 bit signed format (host endian) */
|
||||
#define B_FMT_16BIT 0x10
|
||||
/* left-adjusted in 32 bit signed word */
|
||||
#define B_FMT_18BIT 0x20
|
||||
#define B_FMT_20BIT 0x40
|
||||
#define B_FMT_24BIT 0x100
|
||||
#define B_FMT_32BIT 0x1000
|
||||
/* 32-bit floating point, -1.0 to 1.0 */
|
||||
#define B_FMT_FLOAT 0x20000
|
||||
/* 64-bit floating point, -1.0 to 1.0 */
|
||||
#define B_FMT_DOUBLE 0x40000
|
||||
/* 80-bit floating point, -1.0 to 1.0 */
|
||||
#define B_FMT_EXTENDED 0x80000
|
||||
/* bit stream */
|
||||
#define B_FMT_BITSTREAM 0x1000000
|
||||
/* format parameter global to all channels (input and output formats respectively) */
|
||||
#define B_FMT_IS_GLOBAL 0x80000000UL
|
||||
/* output format locked to input format (output_formats) */
|
||||
#define B_FMT_SAME_AS_INPUT 0x40000000UL
|
||||
|
||||
/* possible sample lock sources */
|
||||
#define B_MULTI_LOCK_INPUT_CHANNEL 0x0 /* lock_source_data is channel id */
|
||||
#define B_MULTI_LOCK_INTERNAL 0x1
|
||||
#define B_MULTI_LOCK_WORDCLOCK 0x2
|
||||
#define B_MULTI_LOCK_SUPERCLOCK 0x4
|
||||
#define B_MULTI_LOCK_LIGHTPIPE 0x8
|
||||
#define B_MULTI_LOCK_VIDEO 0x10 /* or blackburst */
|
||||
#define B_MULTI_LOCK_FIRST_CARD 0x20 /* if you have more than one card */
|
||||
#define B_MULTI_LOCK_MTC 0x40
|
||||
#define B_MULTI_LOCK_SPDIF 0x80
|
||||
|
||||
/* possible timecode sources */
|
||||
#define B_MULTI_TIMECODE_MTC 0x1
|
||||
#define B_MULTI_TIMECODE_VTC 0x2
|
||||
#define B_MULTI_TIMECODE_SMPTE 0x4
|
||||
#define B_MULTI_TIMECODE_SUPERCLOCK 0x8
|
||||
#define B_MULTI_TIMECODE_FIREWIRE 0x10
|
||||
|
||||
/* interface_flags values */
|
||||
/* Available functions on this device. */
|
||||
#define B_MULTI_INTERFACE_PLAYBACK 0x1
|
||||
#define B_MULTI_INTERFACE_RECORD 0x2
|
||||
#define B_MULTI_INTERFACE_TRANSPORT 0x4
|
||||
#define B_MULTI_INTERFACE_TIMECODE 0x8
|
||||
/* "Soft" buffers means you can change the pointer values and the driver will still be happy. */
|
||||
#define B_MULTI_INTERFACE_SOFT_PLAY_BUFFERS 0x10000
|
||||
#define B_MULTI_INTERFACE_SOFT_REC_BUFFERS 0x20000
|
||||
/* Whether the data stream is interrupted when changing channel enables. */
|
||||
#define B_MULTI_INTERFACE_CLICKS_WHEN_ENABLING_OUTPUTS 0x40000
|
||||
#define B_MULTI_INTERFACE_CLICKS_WHEN_ENABLING_INPUTS 0x80000
|
||||
|
||||
#define B_CURRENT_INTERFACE_VERSION 0x4502
|
||||
#define B_MINIMUM_INTERFACE_VERSION 0x4502
|
||||
|
||||
typedef struct multi_description multi_description;
|
||||
typedef struct multi_channel_info multi_channel_info;
|
||||
struct multi_description {
|
||||
|
||||
size_t info_size; /* sizeof(multi_description) */
|
||||
uint32 interface_version; /* current version of interface that's implemented */
|
||||
uint32 interface_minimum; /* minimum version required to understand driver */
|
||||
|
||||
char friendly_name[32]; /* name displayed to user (C string) */
|
||||
char vendor_info[32]; /* name used internally by vendor (C string) */
|
||||
|
||||
int32 output_channel_count;
|
||||
int32 input_channel_count;
|
||||
int32 output_bus_channel_count;
|
||||
int32 input_bus_channel_count;
|
||||
int32 aux_bus_channel_count;
|
||||
|
||||
int32 request_channel_count; /* how many channel_infos are there */
|
||||
multi_channel_info *
|
||||
channels;
|
||||
|
||||
uint32 output_rates;
|
||||
uint32 input_rates;
|
||||
float min_cvsr_rate;
|
||||
float max_cvsr_rate;
|
||||
uint32 output_formats;
|
||||
uint32 input_formats;
|
||||
uint32 lock_sources;
|
||||
uint32 timecode_sources;
|
||||
|
||||
uint32 interface_flags;
|
||||
bigtime_t start_latency; /* how much in advance driver needs SET_START_TIME */
|
||||
|
||||
uint32 _reserved_[11];
|
||||
|
||||
char control_panel[64]; /* MIME type of control panel application */
|
||||
};
|
||||
|
||||
#if !defined(_MEDIA_DEFS_H) /* enum in MediaDefs.h */
|
||||
/* designation values */
|
||||
/* mono channels have no designation */
|
||||
#define B_CHANNEL_LEFT 0x1
|
||||
#define B_CHANNEL_RIGHT 0x2
|
||||
#define B_CHANNEL_CENTER 0x4 /* 5.1+ or fake surround */
|
||||
#define B_CHANNEL_SUB 0x8 /* 5.1+ */
|
||||
#define B_CHANNEL_REARLEFT 0x10 /* quad surround or 5.1+ */
|
||||
#define B_CHANNEL_REARRIGHT 0x20 /* quad surround or 5.1+ */
|
||||
#define B_CHANNEL_FRONT_LEFT_CENTER 0x40
|
||||
#define B_CHANNEL_FRONT_RIGHT_CENTER 0x80
|
||||
#define B_CHANNEL_BACK_CENTER 0x100 /* 6.1 or fake surround */
|
||||
#define B_CHANNEL_SIDE_LEFT 0x200
|
||||
#define B_CHANNEL_SIDE_RIGHT 0x400
|
||||
#define B_CHANNEL_TOP_CENTER 0x800
|
||||
#define B_CHANNEL_TOP_FRONT_LEFT 0x1000
|
||||
#define B_CHANNEL_TOP_FRONT_CENTER 0x2000
|
||||
#define B_CHANNEL_TOP_FRONT_RIGHT 0x4000
|
||||
#define B_CHANNEL_TOP_BACK_LEFT 0x8000
|
||||
#define B_CHANNEL_TOP_BACK_CENTER 0x10000
|
||||
#define B_CHANNEL_TOP_BACK_RIGHT 0x20000
|
||||
#endif
|
||||
|
||||
#define B_CHANNEL_MONO_BUS 0x4000000
|
||||
#define B_CHANNEL_STEREO_BUS 0x2000000 /* + left/right */
|
||||
#define B_CHANNEL_SURROUND_BUS 0x1000000 /* multichannel */
|
||||
|
||||
/* If you have interactions where some inputs can not be used when some */
|
||||
/* outputs are used, mark both inputs and outputs with this flag. */
|
||||
#define B_CHANNEL_INTERACTION 0x80000000UL
|
||||
/* If input channel #n is simplexed with output channel #n, they should both */
|
||||
/* have this flag set (different from the previous flag, which is more vague). */
|
||||
#define B_CHANNEL_SIMPLEX 0x40000000UL
|
||||
|
||||
/* connector values */
|
||||
/* analog connectors */
|
||||
#define B_CHANNEL_RCA 0x1
|
||||
#define B_CHANNEL_XLR 0x2
|
||||
#define B_CHANNEL_TRS 0x4
|
||||
#define B_CHANNEL_QUARTER_INCH_MONO 0x8
|
||||
#define B_CHANNEL_MINI_JACK_STEREO 0x10
|
||||
#define B_CHANNEL_QUARTER_INCH_STEREO 0x20
|
||||
#define B_CHANNEL_ANALOG_HEADER 0x100 /* internal on card */
|
||||
#define B_CHANNEL_SNAKE 0x200 /* or D-sub */
|
||||
/* digital connectors (stereo) */
|
||||
#define B_CHANNEL_OPTICAL_SPDIF 0x1000
|
||||
#define B_CHANNEL_COAX_SPDIF 0x2000
|
||||
#define B_CHANNEL_COAX_EBU 0x4000
|
||||
#define B_CHANNEL_XLR_EBU 0x8000
|
||||
#define B_CHANNEL_TRS_EBU 0x10000
|
||||
#define B_CHANNEL_SPDIF_HEADER 0x20000 /* internal on card */
|
||||
/* multi-channel digital connectors */
|
||||
#define B_CHANNEL_LIGHTPIPE 0x100000
|
||||
#define B_CHANNEL_TDIF 0x200000
|
||||
#define B_CHANNEL_FIREWIRE 0x400000
|
||||
#define B_CHANNEL_USB 0x800000
|
||||
/* If you have multiple output connectors, only one of which can */
|
||||
/* be active at a time. */
|
||||
#define B_CHANNEL_EXCLUSIVE_SELECTION 0x80000000UL
|
||||
|
||||
|
||||
typedef enum {
|
||||
B_MULTI_NO_CHANNEL_KIND,
|
||||
B_MULTI_OUTPUT_CHANNEL = 0x1,
|
||||
B_MULTI_INPUT_CHANNEL = 0x2,
|
||||
B_MULTI_OUTPUT_BUS = 0x4,
|
||||
B_MULTI_INPUT_BUS = 0x8,
|
||||
B_MULTI_AUX_BUS = 0x10
|
||||
} channel_kind;
|
||||
|
||||
struct multi_channel_info {
|
||||
int32 channel_id;
|
||||
channel_kind kind;
|
||||
uint32 designations;
|
||||
uint32 connectors;
|
||||
uint32 _reserved_[4];
|
||||
};
|
||||
|
||||
|
||||
/* Constants */
|
||||
#define B_MULTI_EVENT_MINMAX 16
|
||||
/* Event flags/masks */
|
||||
#define B_MULTI_EVENT_TRANSPORT 0x40000000UL
|
||||
#define B_MULTI_EVENT_HAS_TIMECODE 0x80000000UL
|
||||
|
||||
/* possible transport events */
|
||||
#define B_MULTI_EVENT_NONE 0x00000000UL
|
||||
#define B_MULTI_EVENT_START 0x40010000UL
|
||||
#define B_MULTI_EVENT_LOCATION 0x40020000UL /* location when shuttling or locating */
|
||||
#define B_MULTI_EVENT_SHUTTLING 0x40040000UL
|
||||
#define B_MULTI_EVENT_STOP 0x40080000UL
|
||||
#define B_MULTI_EVENT_RECORD 0x40100000UL
|
||||
#define B_MULTI_EVENT_PAUSE 0x40200000UL
|
||||
#define B_MULTI_EVENT_RUNNING 0x40400000UL /* location when running */
|
||||
/* possible device events */
|
||||
enum {
|
||||
B_MULTI_EVENT_STARTED = 0x1,
|
||||
B_MULTI_EVENT_STOPPED = 0x2,
|
||||
B_MULTI_EVENT_CHANNEL_FORMAT_CHANGED= 0x4,
|
||||
B_MULTI_EVENT_BUFFER_OVERRUN = 0x8,
|
||||
B_MULTI_EVENT_SIGNAL_LOST = 0x10,
|
||||
B_MULTI_EVENT_SIGNAL_DETECTED = 0x20,
|
||||
B_MULTI_EVENT_CLOCK_LOST = 0x40,
|
||||
B_MULTI_EVENT_CLOCK_DETECTED = 0x80,
|
||||
B_MULTI_EVENT_NEW_MODE = 0x100,
|
||||
B_MULTI_EVENT_CONTROL_CHANGED = 0x200
|
||||
};
|
||||
|
||||
typedef struct multi_get_event_info multi_get_event_info;
|
||||
struct multi_get_event_info {
|
||||
size_t info_size; /* sizeof(multi_get_event_info) */
|
||||
uint32 supported_mask; /* what events h/w supports */
|
||||
uint32 current_mask; /* current driver value */
|
||||
uint32 queue_size; /* current queue size */
|
||||
uint32 event_count; /* number of events currently in queue*/
|
||||
uint32 _reserved[3];
|
||||
};
|
||||
|
||||
typedef struct multi_set_event_info multi_set_event_info;
|
||||
struct multi_set_event_info {
|
||||
size_t info_size; /* sizeof(multi_set_event_info) */
|
||||
uint32 in_mask; /* what events to wait for */
|
||||
int32 semaphore; /* semaphore app will wait on */
|
||||
uint32 queue_size; /* minimum number of events to save */
|
||||
uint32 _reserved[4];
|
||||
};
|
||||
|
||||
typedef struct multi_get_event multi_get_event;
|
||||
struct multi_get_event {
|
||||
size_t info_size; /* sizeof(multi_get_event) */
|
||||
uint32 event;
|
||||
bigtime_t timestamp; /* real time at which event was received */
|
||||
int32 count; /* used for configuration events */
|
||||
union {
|
||||
int32 channels[100];
|
||||
uint32 clocks;
|
||||
int32 mode;
|
||||
int32 controls[100];
|
||||
struct { /* transport event */
|
||||
float out_rate; /* what rate it's now playing at */
|
||||
int32 out_hours; /* location at the time given */
|
||||
int32 out_minutes;
|
||||
int32 out_seconds;
|
||||
int32 out_frames;
|
||||
}transport;
|
||||
char _reserved_[400];
|
||||
#if defined(__cplusplus)
|
||||
};
|
||||
#else
|
||||
} u;
|
||||
#endif
|
||||
uint32 _reserved_1[10];
|
||||
};
|
||||
|
||||
typedef struct multi_channel_enable multi_channel_enable;
|
||||
struct multi_channel_enable {
|
||||
size_t info_size; /* sizeof(multi_channel_enable) */
|
||||
/* this must have bytes for all channels (see multi_description) */
|
||||
/* channel 0 is lowest bit of first byte */
|
||||
uchar * enable_bits;
|
||||
|
||||
uint32 lock_source;
|
||||
int32 lock_data;
|
||||
uint32 timecode_source;
|
||||
uint32 * connectors; /* which connector(s) is/are active, per channel */
|
||||
};
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
inline void B_SET_CHANNEL(void * bits, int channel, bool value)
|
||||
{
|
||||
ASSERT(channel>=0);
|
||||
(((uchar *)(bits))[((channel)&0x7fff)>>3] =
|
||||
(((uchar *)(bits))[((channel)&0x7fff)>>3] & ~(1<<((channel)&0x7))) |
|
||||
((value) ? (1<<((channel)&0x7)) : 0));
|
||||
}
|
||||
inline bool B_TEST_CHANNEL(const void * bits, int channel)
|
||||
{
|
||||
return ((((uchar *)(bits))[((channel)&0x7fff)>>3] >> ((channel)&0x7)) & 1);
|
||||
}
|
||||
#else
|
||||
#define B_SET_CHANNEL(bits, channel, value) \
|
||||
ASSERT(channel>=0); \
|
||||
(((uchar *)(bits))[((channel)&0x7fff)>>3] = \
|
||||
(((uchar *)(bits))[((channel)&0x7fff)>>3] & ~(1<<((channel)&0x7))) | \
|
||||
((value) ? (1<<((channel)&0x7)) : 0))
|
||||
#define B_TEST_CHANNEL(bits, channel) \
|
||||
((((uchar *)(bits))[((channel)&0x7fff)>>3] >> ((channel)&0x7)) & 1)
|
||||
#endif
|
||||
|
||||
typedef struct multi_channel_formats multi_channel_formats;
|
||||
typedef struct multi_format_info multi_format_info;
|
||||
typedef struct _multi_format _multi_format;
|
||||
|
||||
struct _multi_format {
|
||||
uint32 rate;
|
||||
float cvsr;
|
||||
uint32 format;
|
||||
uint32 _reserved_[3];
|
||||
};
|
||||
enum { /* timecode kinds */
|
||||
B_MULTI_NO_TIMECODE,
|
||||
B_MULTI_TIMECODE_30, /* MIDI */
|
||||
B_MULTI_TIMECODE_30_DROP_2, /* NTSC */
|
||||
B_MULTI_TIMECODE_30_DROP_4, /* Brazil */
|
||||
B_MULTI_TIMECODE_25, /* PAL */
|
||||
B_MULTI_TIMECODE_24 /* Film */
|
||||
};
|
||||
struct multi_format_info {
|
||||
size_t info_size; /* sizeof(multi_format_info) */
|
||||
bigtime_t output_latency;
|
||||
bigtime_t input_latency;
|
||||
int32 timecode_kind;
|
||||
uint32 _reserved_[7];
|
||||
_multi_format input;
|
||||
_multi_format output;
|
||||
};
|
||||
struct multi_channel_formats {
|
||||
size_t info_size; /* sizeof(multi_channel_formats) */
|
||||
int32 request_channel_count;
|
||||
int32 request_first_channel;
|
||||
int32 returned_channel_count;
|
||||
int32 timecode_kind;
|
||||
int32 _reserved_[4];
|
||||
_multi_format *
|
||||
channels;
|
||||
bigtime_t * latencies; /* DMA/hardware latencies; client calculates for buffers */
|
||||
};
|
||||
|
||||
|
||||
typedef struct multi_mix_value multi_mix_value;
|
||||
struct multi_mix_value {
|
||||
int32 id;
|
||||
union {
|
||||
float gain;
|
||||
uint32 mux; /* bitmask of mux points */
|
||||
bool enable;
|
||||
uint32 _reserved_[2];
|
||||
#if defined(__cplusplus)
|
||||
};
|
||||
#else
|
||||
} u;
|
||||
#endif
|
||||
int32 ramp;
|
||||
uint32 _reserved_2[2];
|
||||
};
|
||||
|
||||
typedef struct multi_mix_value_info multi_mix_value_info;
|
||||
struct multi_mix_value_info {
|
||||
size_t info_size; /* sizeof(multi_mix_value_info) */
|
||||
int32 item_count;
|
||||
multi_mix_value *
|
||||
values;
|
||||
int32 at_frame; /* time at which to start the change */
|
||||
};
|
||||
|
||||
// only one of these should be set
|
||||
#define B_MULTI_MIX_JUNCTION 0x1
|
||||
#define B_MULTI_MIX_GAIN 0x2
|
||||
#define B_MULTI_MIX_MUX 0x4
|
||||
#define B_MULTI_MIX_ENABLE 0x8
|
||||
#define B_MULTI_MIX_GROUP 0x10
|
||||
#define B_MULTI_MIX_KIND_MASK 0xffff
|
||||
|
||||
#define B_MULTI_MIX_MUX_VALUE 0x0104
|
||||
// any combination of these can be set
|
||||
#define B_MULTI_MIX_RAMP 0x10000
|
||||
|
||||
enum strind_id {
|
||||
S_null = 0, S_OUTPUT, S_INPUT, S_SETUP, S_TONE_CONTROL, S_EXTENDED_SETUP,
|
||||
S_ENHANDED_SETUP, S_MASTER, S_BEEP, S_PHONE, S_MIC, S_LINE, S_CD, S_VIDEO,
|
||||
S_AUX, S_WAVE, S_GAIN, S_LEVEL, S_VOLUME, S_MUTE, S_ENABLE, S_STEREO_MIX,
|
||||
S_MONO_MIX, S_OUTPUT_STEREO_MIX, S_OUTPUT_MONO_MIX, S_OUTPUT_BASS,
|
||||
S_OUTPUT_TREBLE, S_OUTPUT_3D_CENTER, S_OUTPUT_3D_DEPTH,
|
||||
S_USERID = 1000000
|
||||
};
|
||||
|
||||
typedef struct multi_mix_control multi_mix_control;
|
||||
struct multi_mix_control {
|
||||
int32 id; /* unique for device -- not same id as any channel/bus ! */
|
||||
uint32 flags; /* including kind */
|
||||
int32 master; /* or 0 if it's not slaved */
|
||||
union {
|
||||
struct {
|
||||
float min_gain; /* dB */
|
||||
float max_gain; /* dB */
|
||||
float granularity; /* dB */
|
||||
} gain;
|
||||
struct {
|
||||
uint32 _reserved;
|
||||
} mux;
|
||||
struct {
|
||||
uint32 _reserved;
|
||||
} enable;
|
||||
uint32 _reserved[12];
|
||||
#if defined(__cplusplus)
|
||||
};
|
||||
#else
|
||||
} u;
|
||||
#endif
|
||||
enum strind_id string; /* string id (S_null : use name) */
|
||||
int32 parent; /* parent id */
|
||||
char name[48];
|
||||
};
|
||||
|
||||
typedef struct multi_mix_channel_info multi_mix_channel_info;
|
||||
struct multi_mix_channel_info {
|
||||
size_t info_size; /* sizeof(multi_mix_channel_info) */
|
||||
int32 channel_count;
|
||||
int32 * channels; /* allocated by caller, lists requested channels */
|
||||
int32 max_count; /* in: control ids per channel */
|
||||
int32 actual_count; /* out: actual max # controls for any individual requested channel */
|
||||
int32 ** controls;
|
||||
};
|
||||
|
||||
typedef struct multi_mix_control_info multi_mix_control_info;
|
||||
struct multi_mix_control_info {
|
||||
size_t info_size; /* sizeof(multi_mix_control_info) */
|
||||
int32 control_count; /* in: number of controls */
|
||||
multi_mix_control *
|
||||
controls; /* allocated by caller, returns control description for each */
|
||||
};
|
||||
|
||||
typedef struct multi_mix_connection multi_mix_connection;
|
||||
struct multi_mix_connection {
|
||||
int32 from;
|
||||
int32 to;
|
||||
uint32 _reserved_[2];
|
||||
};
|
||||
|
||||
typedef struct multi_mix_connection_info multi_mix_connection_info;
|
||||
struct multi_mix_connection_info {
|
||||
size_t info_size;
|
||||
int32 max_count; /* in: available space */
|
||||
int32 actual_count; /* out: actual count */
|
||||
multi_mix_connection *
|
||||
connections; /* allocated by caller, returns connections */
|
||||
};
|
||||
|
||||
|
||||
/* possible flags values for what is available (in and out) */
|
||||
#define B_MULTI_BUFFER_PLAYBACK 0x1
|
||||
#define B_MULTI_BUFFER_RECORD 0x2
|
||||
#define B_MULTI_BUFFER_METERING 0x4
|
||||
#define B_MULTI_BUFFER_TIMECODE 0x40000
|
||||
|
||||
typedef struct multi_buffer_list multi_buffer_list;
|
||||
typedef struct buffer_desc buffer_desc;
|
||||
/* This struct is used to query the driver about what buffers it will use, */
|
||||
/* and to tell it what buffers to use if it supports soft buffers. */
|
||||
struct multi_buffer_list {
|
||||
|
||||
size_t info_size; /* sizeof(multi_buffer_list) */
|
||||
uint32 flags;
|
||||
|
||||
int32 request_playback_buffers;
|
||||
int32 request_playback_channels;
|
||||
uint32 request_playback_buffer_size; /* frames per buffer */
|
||||
int32 return_playback_buffers; /* playback_buffers[b][] */
|
||||
int32 return_playback_channels; /* playback_buffers[][c] */
|
||||
uint32 return_playback_buffer_size; /* frames */
|
||||
buffer_desc ** playback_buffers;
|
||||
void * _reserved_1;
|
||||
|
||||
int32 request_record_buffers;
|
||||
int32 request_record_channels;
|
||||
uint32 request_record_buffer_size; /* frames per buffer */
|
||||
int32 return_record_buffers;
|
||||
int32 return_record_channels;
|
||||
uint32 return_record_buffer_size; /* frames */
|
||||
buffer_desc ** record_buffers;
|
||||
void * _reserved_2;
|
||||
|
||||
};
|
||||
|
||||
struct buffer_desc {
|
||||
char * base; /* pointer to first sample for channel for buffer */
|
||||
size_t stride; /* offset to next sample */
|
||||
uint32 _reserved_[2];
|
||||
};
|
||||
|
||||
|
||||
/* This struct is used when actually queuing data to be played, and/or */
|
||||
/* receiving data from a recorder. */
|
||||
typedef struct multi_buffer_info multi_buffer_info;
|
||||
struct multi_buffer_info {
|
||||
|
||||
size_t info_size; /* sizeof(multi_buffer_info) */
|
||||
uint32 flags;
|
||||
|
||||
bigtime_t played_real_time;
|
||||
bigtime_t played_frames_count;
|
||||
int32 _reserved_0;
|
||||
int32 playback_buffer_cycle;
|
||||
|
||||
bigtime_t recorded_real_time;
|
||||
bigtime_t recorded_frames_count;
|
||||
int32 _reserved_1;
|
||||
int32 record_buffer_cycle;
|
||||
|
||||
int32 meter_channel_count;
|
||||
char * meters_peak; /* in the same format as the data; allocated by caller */
|
||||
char * meters_average; /* in the same format as the data; allocated by caller */
|
||||
|
||||
/* timecode sent and received at buffer swap */
|
||||
int32 hours;
|
||||
int32 minutes;
|
||||
int32 seconds;
|
||||
int32 tc_frames; /* for timecode frames as opposed to sample frames */
|
||||
int32 at_frame_delta; /* how far into buffer (or before buffer for negative) */
|
||||
|
||||
};
|
||||
|
||||
|
||||
typedef struct multi_mode_info multi_mode_info;
|
||||
typedef struct multi_mode_list multi_mode_list;
|
||||
|
||||
struct multi_mode_list {
|
||||
size_t info_size; /* sizeof(multi_mode_list) */
|
||||
int32 in_request_count;
|
||||
int32 out_actual_count;
|
||||
int32 out_current_mode;
|
||||
multi_mode_info *
|
||||
io_modes;
|
||||
};
|
||||
|
||||
struct multi_mode_info {
|
||||
int32 mode_id;
|
||||
uint32 flags;
|
||||
char mode_name[64];
|
||||
int32 input_channel_count;
|
||||
int32 output_channel_count;
|
||||
float best_frame_rate_in;
|
||||
float best_frame_rate_out;
|
||||
uint32 sample_formats_in;
|
||||
uint32 sample_formats_out;
|
||||
char _reserved[160];
|
||||
};
|
||||
|
||||
|
||||
/* This extension protocol can grow however much you want. */
|
||||
/* Good extensions should be put into this header; really */
|
||||
/* good extensions should become part of the regular API. */
|
||||
/* For developer-developed extensions, use all lowercase */
|
||||
/* and digits (no upper case). If we then bless a third- */
|
||||
/* party extension, we can just upper-case the selector. */
|
||||
|
||||
typedef struct multi_extension_list multi_extension_list;
|
||||
typedef struct multi_extension_info multi_extension_info;
|
||||
struct multi_extension_info {
|
||||
uint32 code;
|
||||
uint32 flags;
|
||||
char name[24];
|
||||
};
|
||||
|
||||
#define B_MULTI_MAX_EXTENSION_COUNT 31
|
||||
struct multi_extension_list { /* MULTI_LIST_EXTENSIONS */
|
||||
size_t info_size; /* sizeof(multi_extension_list) */
|
||||
uint32 max_count;
|
||||
int32 actual_count; /* return # of actual extensions */
|
||||
multi_extension_info *
|
||||
extensions; /* allocated by caller */
|
||||
};
|
||||
|
||||
typedef struct multi_extension_cmd multi_extension_cmd;
|
||||
struct multi_extension_cmd { /* MULTI_GET_EXTENSION and MULTI_SET_EXTENSION */
|
||||
size_t info_size; /* sizeof(multi_extension_cmd) */
|
||||
uint32 code;
|
||||
uint32 _reserved_1;
|
||||
void * in_data;
|
||||
size_t in_size;
|
||||
void * out_data;
|
||||
size_t out_size;
|
||||
};
|
||||
|
||||
enum {
|
||||
B_MULTI_EX_CLOCK_GENERATION = 'CLGE',
|
||||
B_MULTI_EX_DIGITAL_FORMAT = 'DIFO',
|
||||
B_MULTI_EX_OUTPUT_NOMINAL = 'OUNO',
|
||||
B_MULTI_EX_INPUT_NOMINAL = 'INNO'
|
||||
};
|
||||
|
||||
typedef struct multi_ex_clock_generation multi_ex_clock_generation;
|
||||
struct multi_ex_clock_generation {
|
||||
int32 channel; /* if specific, or -1 for all */
|
||||
uint32 clock; /* WORDCLOCK or SUPERCLOCK, typically */
|
||||
};
|
||||
|
||||
typedef struct multi_ex_digital_format multi_ex_digital_format;
|
||||
struct multi_ex_digital_format {
|
||||
int32 channel; /* if specific, or -1 for all */
|
||||
uint32 format; /* B_CHANNEL_*_SPDIF or B_CHANNEL_*_EBU */
|
||||
};
|
||||
|
||||
enum {
|
||||
B_MULTI_NOMINAL_MINUS_10 = 1,
|
||||
B_MULTI_NOMINAL_PLUS_4
|
||||
};
|
||||
|
||||
typedef struct multi_ex_nominal_level multi_ex_nominal_level;
|
||||
struct multi_ex_nominal_level {
|
||||
int32 channel; /* if specific, or -1 for all */
|
||||
int32 level;
|
||||
};
|
||||
|
||||
#endif /* _MULTI_AUDIO_H */
|
||||
|
||||
@@ -0,0 +1,529 @@
|
||||
/* $NetBSD: queue.h,v 1.31 2002/06/01 23:51:05 lukem Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
*
|
||||
* @(#)queue.h 8.5 (Berkeley) 8/20/94
|
||||
*/
|
||||
|
||||
#ifndef _SYS_QUEUE_H_
|
||||
#define _SYS_QUEUE_H_
|
||||
|
||||
/*
|
||||
* This file defines five types of data structures: singly-linked lists,
|
||||
* lists, simple queues, tail queues, and circular queues.
|
||||
*
|
||||
* A singly-linked list is headed by a single forward pointer. The
|
||||
* elements are singly linked for minimum space and pointer manipulation
|
||||
* overhead at the expense of O(n) removal for arbitrary elements. New
|
||||
* elements can be added to the list after an existing element or at the
|
||||
* head of the list. Elements being removed from the head of the list
|
||||
* should use the explicit macro for this purpose for optimum
|
||||
* efficiency. A singly-linked list may only be traversed in the forward
|
||||
* direction. Singly-linked lists are ideal for applications with large
|
||||
* datasets and few or no removals or for implementing a LIFO queue.
|
||||
*
|
||||
* A list is headed by a single forward pointer (or an array of forward
|
||||
* pointers for a hash table header). The elements are doubly linked
|
||||
* so that an arbitrary element can be removed without a need to
|
||||
* traverse the list. New elements can be added to the list before
|
||||
* or after an existing element or at the head of the list. A list
|
||||
* may only be traversed in the forward direction.
|
||||
*
|
||||
* A simple queue is headed by a pair of pointers, one the head of the
|
||||
* list and the other to the tail of the list. The elements are singly
|
||||
* linked to save space, so only elements can only be removed from the
|
||||
* head of the list. New elements can be added to the list after
|
||||
* an existing element, at the head of the list, or at the end of the
|
||||
* list. A simple queue may only be traversed in the forward direction.
|
||||
*
|
||||
* A tail queue is headed by a pair of pointers, one to the head of the
|
||||
* list and the other to the tail of the list. The elements are doubly
|
||||
* linked so that an arbitrary element can be removed without a need to
|
||||
* traverse the list. New elements can be added to the list before or
|
||||
* after an existing element, at the head of the list, or at the end of
|
||||
* the list. A tail queue may be traversed in either direction.
|
||||
*
|
||||
* A circle queue is headed by a pair of pointers, one to the head of the
|
||||
* list and the other to the tail of the list. The elements are doubly
|
||||
* linked so that an arbitrary element can be removed without a need to
|
||||
* traverse the list. New elements can be added to the list before or after
|
||||
* an existing element, at the head of the list, or at the end of the list.
|
||||
* A circle queue may be traversed in either direction, but has a more
|
||||
* complex end of list detection.
|
||||
*
|
||||
* For details on the use of these macros, see the queue(3) manual page.
|
||||
*/
|
||||
|
||||
/*
|
||||
* List definitions.
|
||||
*/
|
||||
#define LIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *lh_first; /* first element */ \
|
||||
}
|
||||
|
||||
#define LIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
|
||||
#define LIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *le_next; /* next element */ \
|
||||
struct type **le_prev; /* address of previous next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* List functions.
|
||||
*/
|
||||
#if defined(_KERNEL) && defined(QUEUEDEBUG)
|
||||
#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field) \
|
||||
if ((head)->lh_first && \
|
||||
(head)->lh_first->field.le_prev != &(head)->lh_first) \
|
||||
panic("LIST_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
|
||||
#define QUEUEDEBUG_LIST_OP(elm, field) \
|
||||
if ((elm)->field.le_next && \
|
||||
(elm)->field.le_next->field.le_prev != \
|
||||
&(elm)->field.le_next) \
|
||||
panic("LIST_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
|
||||
if (*(elm)->field.le_prev != (elm)) \
|
||||
panic("LIST_* back %p %s:%d", (elm), __FILE__, __LINE__);
|
||||
#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field) \
|
||||
(elm)->field.le_next = (void *)1L; \
|
||||
(elm)->field.le_prev = (void *)1L;
|
||||
#else
|
||||
#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)
|
||||
#define QUEUEDEBUG_LIST_OP(elm, field)
|
||||
#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field)
|
||||
#endif
|
||||
|
||||
#define LIST_INIT(head) do { \
|
||||
(head)->lh_first = NULL; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
|
||||
QUEUEDEBUG_LIST_OP((listelm), field) \
|
||||
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
|
||||
(listelm)->field.le_next->field.le_prev = \
|
||||
&(elm)->field.le_next; \
|
||||
(listelm)->field.le_next = (elm); \
|
||||
(elm)->field.le_prev = &(listelm)->field.le_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
|
||||
QUEUEDEBUG_LIST_OP((listelm), field) \
|
||||
(elm)->field.le_prev = (listelm)->field.le_prev; \
|
||||
(elm)->field.le_next = (listelm); \
|
||||
*(listelm)->field.le_prev = (elm); \
|
||||
(listelm)->field.le_prev = &(elm)->field.le_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define LIST_INSERT_HEAD(head, elm, field) do { \
|
||||
QUEUEDEBUG_LIST_INSERT_HEAD((head), (elm), field) \
|
||||
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
|
||||
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
|
||||
(head)->lh_first = (elm); \
|
||||
(elm)->field.le_prev = &(head)->lh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define LIST_REMOVE(elm, field) do { \
|
||||
QUEUEDEBUG_LIST_OP((elm), field) \
|
||||
if ((elm)->field.le_next != NULL) \
|
||||
(elm)->field.le_next->field.le_prev = \
|
||||
(elm)->field.le_prev; \
|
||||
*(elm)->field.le_prev = (elm)->field.le_next; \
|
||||
QUEUEDEBUG_LIST_POSTREMOVE((elm), field) \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define LIST_FOREACH(var, head, field) \
|
||||
for ((var) = ((head)->lh_first); \
|
||||
(var); \
|
||||
(var) = ((var)->field.le_next))
|
||||
|
||||
/*
|
||||
* List access methods.
|
||||
*/
|
||||
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
|
||||
#define LIST_FIRST(head) ((head)->lh_first)
|
||||
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
||||
|
||||
/*
|
||||
* Singly-linked List definitions.
|
||||
*/
|
||||
#define SLIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *slh_first; /* first element */ \
|
||||
}
|
||||
|
||||
#define SLIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
|
||||
#define SLIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *sle_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Singly-linked List functions.
|
||||
*/
|
||||
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
|
||||
#define SLIST_FIRST(head) ((head)->slh_first)
|
||||
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
||||
|
||||
#define SLIST_FOREACH(var, head, field) \
|
||||
for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
|
||||
|
||||
#define SLIST_INIT(head) do { \
|
||||
(head)->slh_first = NULL; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
|
||||
(elm)->field.sle_next = (slistelm)->field.sle_next; \
|
||||
(slistelm)->field.sle_next = (elm); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SLIST_INSERT_HEAD(head, elm, field) do { \
|
||||
(elm)->field.sle_next = (head)->slh_first; \
|
||||
(head)->slh_first = (elm); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
||||
|
||||
#define SLIST_REMOVE_HEAD(head, field) do { \
|
||||
(head)->slh_first = (head)->slh_first->field.sle_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SLIST_REMOVE(head, elm, type, field) do { \
|
||||
if ((head)->slh_first == (elm)) { \
|
||||
SLIST_REMOVE_HEAD((head), field); \
|
||||
} \
|
||||
else { \
|
||||
struct type *curelm = (head)->slh_first; \
|
||||
while(curelm->field.sle_next != (elm)) \
|
||||
curelm = curelm->field.sle_next; \
|
||||
curelm->field.sle_next = \
|
||||
curelm->field.sle_next->field.sle_next; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
/*
|
||||
* Simple queue definitions.
|
||||
*/
|
||||
#define SIMPLEQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *sqh_first; /* first element */ \
|
||||
struct type **sqh_last; /* addr of last next element */ \
|
||||
}
|
||||
|
||||
#define SIMPLEQ_HEAD_INITIALIZER(head) \
|
||||
{ NULL, &(head).sqh_first }
|
||||
|
||||
#define SIMPLEQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *sqe_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple queue functions.
|
||||
*/
|
||||
#define SIMPLEQ_INIT(head) do { \
|
||||
(head)->sqh_first = NULL; \
|
||||
(head)->sqh_last = &(head)->sqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
|
||||
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
|
||||
(head)->sqh_last = &(elm)->field.sqe_next; \
|
||||
(head)->sqh_first = (elm); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
|
||||
(elm)->field.sqe_next = NULL; \
|
||||
*(head)->sqh_last = (elm); \
|
||||
(head)->sqh_last = &(elm)->field.sqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
|
||||
(head)->sqh_last = &(elm)->field.sqe_next; \
|
||||
(listelm)->field.sqe_next = (elm); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
|
||||
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
|
||||
(head)->sqh_last = &(head)->sqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SIMPLEQ_REMOVE(head, elm, type, field) do { \
|
||||
if ((head)->sqh_first == (elm)) { \
|
||||
SIMPLEQ_REMOVE_HEAD((head), field); \
|
||||
} else { \
|
||||
struct type *curelm = (head)->sqh_first; \
|
||||
while (curelm->field.sqe_next != (elm)) \
|
||||
curelm = curelm->field.sqe_next; \
|
||||
if ((curelm->field.sqe_next = \
|
||||
curelm->field.sqe_next->field.sqe_next) == NULL) \
|
||||
(head)->sqh_last = &(curelm)->field.sqe_next; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SIMPLEQ_FOREACH(var, head, field) \
|
||||
for ((var) = ((head)->sqh_first); \
|
||||
(var); \
|
||||
(var) = ((var)->field.sqe_next))
|
||||
|
||||
/*
|
||||
* Simple queue access methods.
|
||||
*/
|
||||
#define SIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL)
|
||||
#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
|
||||
#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
|
||||
|
||||
/*
|
||||
* Tail queue definitions.
|
||||
*/
|
||||
#define TAILQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *tqh_first; /* first element */ \
|
||||
struct type **tqh_last; /* addr of last next element */ \
|
||||
}
|
||||
|
||||
#define TAILQ_HEAD_INITIALIZER(head) \
|
||||
{ NULL, &(head).tqh_first }
|
||||
|
||||
#define TAILQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *tqe_next; /* next element */ \
|
||||
struct type **tqe_prev; /* address of previous next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Tail queue functions.
|
||||
*/
|
||||
#if defined(_KERNEL) && defined(QUEUEDEBUG)
|
||||
#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field) \
|
||||
if ((head)->tqh_first && \
|
||||
(head)->tqh_first->field.tqe_prev != &(head)->tqh_first) \
|
||||
panic("TAILQ_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
|
||||
#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field) \
|
||||
if (*(head)->tqh_last != NULL) \
|
||||
panic("TAILQ_INSERT_TAIL %p %s:%d", (head), __FILE__, __LINE__);
|
||||
#define QUEUEDEBUG_TAILQ_OP(elm, field) \
|
||||
if ((elm)->field.tqe_next && \
|
||||
(elm)->field.tqe_next->field.tqe_prev != \
|
||||
&(elm)->field.tqe_next) \
|
||||
panic("TAILQ_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
|
||||
if (*(elm)->field.tqe_prev != (elm)) \
|
||||
panic("TAILQ_* back %p %s:%d", (elm), __FILE__, __LINE__);
|
||||
#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field) \
|
||||
(elm)->field.tqe_next = (void *)1L; \
|
||||
(elm)->field.tqe_prev = (void *)1L;
|
||||
#else
|
||||
#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)
|
||||
#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)
|
||||
#define QUEUEDEBUG_TAILQ_OP(elm, field)
|
||||
#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)
|
||||
#endif
|
||||
|
||||
#define TAILQ_INIT(head) do { \
|
||||
(head)->tqh_first = NULL; \
|
||||
(head)->tqh_last = &(head)->tqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||
QUEUEDEBUG_TAILQ_INSERT_HEAD((head), (elm), field) \
|
||||
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
|
||||
(head)->tqh_first->field.tqe_prev = \
|
||||
&(elm)->field.tqe_next; \
|
||||
else \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
(head)->tqh_first = (elm); \
|
||||
(elm)->field.tqe_prev = &(head)->tqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||
QUEUEDEBUG_TAILQ_INSERT_TAIL((head), (elm), field) \
|
||||
(elm)->field.tqe_next = NULL; \
|
||||
(elm)->field.tqe_prev = (head)->tqh_last; \
|
||||
*(head)->tqh_last = (elm); \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||
QUEUEDEBUG_TAILQ_OP((listelm), field) \
|
||||
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
|
||||
(elm)->field.tqe_next->field.tqe_prev = \
|
||||
&(elm)->field.tqe_next; \
|
||||
else \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
(listelm)->field.tqe_next = (elm); \
|
||||
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
|
||||
QUEUEDEBUG_TAILQ_OP((listelm), field) \
|
||||
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
|
||||
(elm)->field.tqe_next = (listelm); \
|
||||
*(listelm)->field.tqe_prev = (elm); \
|
||||
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define TAILQ_REMOVE(head, elm, field) do { \
|
||||
QUEUEDEBUG_TAILQ_OP((elm), field) \
|
||||
if (((elm)->field.tqe_next) != NULL) \
|
||||
(elm)->field.tqe_next->field.tqe_prev = \
|
||||
(elm)->field.tqe_prev; \
|
||||
else \
|
||||
(head)->tqh_last = (elm)->field.tqe_prev; \
|
||||
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
|
||||
QUEUEDEBUG_TAILQ_POSTREMOVE((elm), field); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
/*
|
||||
* Tail queue access methods.
|
||||
*/
|
||||
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
|
||||
#define TAILQ_FIRST(head) ((head)->tqh_first)
|
||||
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||
|
||||
#define TAILQ_LAST(head, headname) \
|
||||
(*(((struct headname *)((head)->tqh_last))->tqh_last))
|
||||
#define TAILQ_PREV(elm, headname, field) \
|
||||
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
||||
|
||||
#define TAILQ_FOREACH(var, head, field) \
|
||||
for ((var) = ((head)->tqh_first); \
|
||||
(var); \
|
||||
(var) = ((var)->field.tqe_next))
|
||||
|
||||
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
||||
for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
|
||||
(var); \
|
||||
(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
|
||||
|
||||
/*
|
||||
* Circular queue definitions.
|
||||
*/
|
||||
#define CIRCLEQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *cqh_first; /* first element */ \
|
||||
struct type *cqh_last; /* last element */ \
|
||||
}
|
||||
|
||||
#define CIRCLEQ_HEAD_INITIALIZER(head) \
|
||||
{ (void *)&head, (void *)&head }
|
||||
|
||||
#define CIRCLEQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *cqe_next; /* next element */ \
|
||||
struct type *cqe_prev; /* previous element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Circular queue functions.
|
||||
*/
|
||||
#define CIRCLEQ_INIT(head) do { \
|
||||
(head)->cqh_first = (void *)(head); \
|
||||
(head)->cqh_last = (void *)(head); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||
(elm)->field.cqe_next = (listelm)->field.cqe_next; \
|
||||
(elm)->field.cqe_prev = (listelm); \
|
||||
if ((listelm)->field.cqe_next == (void *)(head)) \
|
||||
(head)->cqh_last = (elm); \
|
||||
else \
|
||||
(listelm)->field.cqe_next->field.cqe_prev = (elm); \
|
||||
(listelm)->field.cqe_next = (elm); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
|
||||
(elm)->field.cqe_next = (listelm); \
|
||||
(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
|
||||
if ((listelm)->field.cqe_prev == (void *)(head)) \
|
||||
(head)->cqh_first = (elm); \
|
||||
else \
|
||||
(listelm)->field.cqe_prev->field.cqe_next = (elm); \
|
||||
(listelm)->field.cqe_prev = (elm); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
|
||||
(elm)->field.cqe_next = (head)->cqh_first; \
|
||||
(elm)->field.cqe_prev = (void *)(head); \
|
||||
if ((head)->cqh_last == (void *)(head)) \
|
||||
(head)->cqh_last = (elm); \
|
||||
else \
|
||||
(head)->cqh_first->field.cqe_prev = (elm); \
|
||||
(head)->cqh_first = (elm); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
|
||||
(elm)->field.cqe_next = (void *)(head); \
|
||||
(elm)->field.cqe_prev = (head)->cqh_last; \
|
||||
if ((head)->cqh_first == (void *)(head)) \
|
||||
(head)->cqh_first = (elm); \
|
||||
else \
|
||||
(head)->cqh_last->field.cqe_next = (elm); \
|
||||
(head)->cqh_last = (elm); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define CIRCLEQ_REMOVE(head, elm, field) do { \
|
||||
if ((elm)->field.cqe_next == (void *)(head)) \
|
||||
(head)->cqh_last = (elm)->field.cqe_prev; \
|
||||
else \
|
||||
(elm)->field.cqe_next->field.cqe_prev = \
|
||||
(elm)->field.cqe_prev; \
|
||||
if ((elm)->field.cqe_prev == (void *)(head)) \
|
||||
(head)->cqh_first = (elm)->field.cqe_next; \
|
||||
else \
|
||||
(elm)->field.cqe_prev->field.cqe_next = \
|
||||
(elm)->field.cqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define CIRCLEQ_FOREACH(var, head, field) \
|
||||
for ((var) = ((head)->cqh_first); \
|
||||
(var) != (void *)(head); \
|
||||
(var) = ((var)->field.cqe_next))
|
||||
|
||||
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
|
||||
for ((var) = ((head)->cqh_last); \
|
||||
(var) != (void *)(head); \
|
||||
(var) = ((var)->field.cqe_prev))
|
||||
|
||||
/*
|
||||
* Circular queue access methods.
|
||||
*/
|
||||
#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
|
||||
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
|
||||
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
|
||||
#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
|
||||
#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
|
||||
#endif /* !_SYS_QUEUE_H_ */
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* BeOS Driver for Intel ICH AC'97 Link interface
|
||||
*
|
||||
* Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 <Errors.h>
|
||||
#include <OS.h>
|
||||
#include <string.h>
|
||||
|
||||
//#define DEBUG 2
|
||||
|
||||
#include "debug.h"
|
||||
#include "util.h"
|
||||
|
||||
spinlock slock = 0;
|
||||
|
||||
uint32 round_to_pagesize(uint32 size);
|
||||
|
||||
cpu_status lock(void)
|
||||
{
|
||||
cpu_status status = disable_interrupts();
|
||||
acquire_spinlock(&slock);
|
||||
return status;
|
||||
}
|
||||
|
||||
void unlock(cpu_status status)
|
||||
{
|
||||
release_spinlock(&slock);
|
||||
restore_interrupts(status);
|
||||
}
|
||||
|
||||
uint32 round_to_pagesize(uint32 size)
|
||||
{
|
||||
return (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
|
||||
}
|
||||
|
||||
area_id alloc_mem(void **phy, void **log, size_t size, const char *name)
|
||||
{
|
||||
physical_entry pe;
|
||||
void * logadr;
|
||||
area_id areaid;
|
||||
status_t rv;
|
||||
|
||||
LOG(("allocating %d bytes for %s\n",size,name));
|
||||
|
||||
size = round_to_pagesize(size);
|
||||
areaid = create_area(name, &logadr, B_ANY_KERNEL_ADDRESS,size,B_FULL_LOCK | B_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA);
|
||||
if (areaid < B_OK) {
|
||||
PRINT(("couldn't allocate area %s\n",name));
|
||||
return B_ERROR;
|
||||
}
|
||||
rv = get_memory_map(logadr,size,&pe,1);
|
||||
if (rv < B_OK) {
|
||||
delete_area(areaid);
|
||||
PRINT(("couldn't map %s\n",name));
|
||||
return B_ERROR;
|
||||
}
|
||||
memset(logadr,0,size);
|
||||
if (log)
|
||||
*log = logadr;
|
||||
if (phy)
|
||||
*phy = pe.address;
|
||||
LOG(("area = %d, size = %d, log = %#08X, phy = %#08X\n",areaid,size,logadr,pe.address));
|
||||
return areaid;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* BeOS Driver for Intel ICH AC'97 Link interface
|
||||
*
|
||||
* Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _UTIL_H_
|
||||
#define _UTIL_H_
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
area_id alloc_mem(void **phy, void **log, size_t size, const char *name);
|
||||
|
||||
cpu_status lock(void);
|
||||
void unlock(cpu_status status);
|
||||
|
||||
extern spinlock slock;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user