Change debugging routines, add more ICH4 support, add tertiary codec support.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@769 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper 2002-08-15 21:33:17 +00:00
parent 6c3c3848cc
commit 15ea765d53
10 changed files with 221 additions and 174 deletions

View File

@ -26,6 +26,7 @@
*
*/
#include <OS.h>
#include <stdio.h>
#include <MediaDefs.h>
#include "ac97.h"

View File

@ -99,9 +99,9 @@ static status_t get_description(multi_description *data)
// channel, second, third, ..., followed by output bus
// channels and input bus channels and finally auxillary channels,
TRACE(("request_channel_count = %d\n",data->request_channel_count));
LOG(("request_channel_count = %d\n",data->request_channel_count));
if (data->request_channel_count >= (int)(sizeof(chans) / sizeof(chans[0]))) {
TRACE(("copying data\n"));
LOG(("copying data\n"));
memcpy(data->channels,&chans,sizeof(chans));
}
@ -154,19 +154,19 @@ static status_t get_global_format(multi_format_info *data)
static status_t get_buffers(multi_buffer_list *data)
{
TRACE(("flags = %#x\n",data->flags));
TRACE(("request_playback_buffers = %#x\n",data->request_playback_buffers));
TRACE(("request_playback_channels = %#x\n",data->request_playback_channels));
TRACE(("request_playback_buffer_size = %#x\n",data->request_playback_buffer_size));
TRACE(("request_record_buffers = %#x\n",data->request_record_buffers));
TRACE(("request_record_channels = %#x\n",data->request_record_channels));
TRACE(("request_record_buffer_size = %#x\n",data->request_record_buffer_size));
LOG(("flags = %#x\n",data->flags));
LOG(("request_playback_buffers = %#x\n",data->request_playback_buffers));
LOG(("request_playback_channels = %#x\n",data->request_playback_channels));
LOG(("request_playback_buffer_size = %#x\n",data->request_playback_buffer_size));
LOG(("request_record_buffers = %#x\n",data->request_record_buffers));
LOG(("request_record_channels = %#x\n",data->request_record_channels));
LOG(("request_record_buffer_size = %#x\n",data->request_record_buffer_size));
if (data->request_playback_buffers < 2 ||
data->request_playback_channels < 2 ||
data->request_record_buffers < 2 ||
data->request_record_channels < 2) {
TRACE(("not enough channels/buffers\n"));
LOG(("not enough channels/buffers\n"));
}
ASSERT(BUFFER_COUNT == 2);
@ -298,69 +298,69 @@ status_t multi_control(void *cookie, uint32 op, void *data, size_t length)
{
switch (op) {
case B_MULTI_GET_DESCRIPTION:
TRACE(("B_MULTI_GET_DESCRIPTION\n"));
LOG(("B_MULTI_GET_DESCRIPTION\n"));
return get_description((multi_description *)data);
case B_MULTI_GET_EVENT_INFO:
TRACE(("B_MULTI_GET_EVENT_INFO\n"));
LOG(("B_MULTI_GET_EVENT_INFO\n"));
return B_ERROR;
case B_MULTI_SET_EVENT_INFO:
TRACE(("B_MULTI_SET_EVENT_INFO\n"));
LOG(("B_MULTI_SET_EVENT_INFO\n"));
return B_ERROR;
case B_MULTI_GET_EVENT:
TRACE(("B_MULTI_GET_EVENT\n"));
LOG(("B_MULTI_GET_EVENT\n"));
return B_ERROR;
case B_MULTI_GET_ENABLED_CHANNELS:
TRACE(("B_MULTI_GET_ENABLED_CHANNELS\n"));
LOG(("B_MULTI_GET_ENABLED_CHANNELS\n"));
return get_enabled_channels((multi_channel_enable *)data);
case B_MULTI_SET_ENABLED_CHANNELS:
TRACE(("B_MULTI_SET_ENABLED_CHANNELS\n"));
LOG(("B_MULTI_SET_ENABLED_CHANNELS\n"));
return B_OK; break;
case B_MULTI_GET_GLOBAL_FORMAT:
TRACE(("B_MULTI_GET_GLOBAL_FORMAT\n"));
LOG(("B_MULTI_GET_GLOBAL_FORMAT\n"));
return get_global_format((multi_format_info *)data);
case B_MULTI_SET_GLOBAL_FORMAT:
TRACE(("B_MULTI_SET_GLOBAL_FORMAT\n"));
LOG(("B_MULTI_SET_GLOBAL_FORMAT\n"));
return B_OK; /* XXX BUG! we *MUST* return B_OK, returning B_ERROR will prevent
* BeOS to accept the format returned in B_MULTI_GET_GLOBAL_FORMAT
*/
case B_MULTI_GET_CHANNEL_FORMATS:
TRACE(("B_MULTI_GET_CHANNEL_FORMATS\n"));
LOG(("B_MULTI_GET_CHANNEL_FORMATS\n"));
return B_ERROR;
case B_MULTI_SET_CHANNEL_FORMATS: /* only implemented if possible */
TRACE(("B_MULTI_SET_CHANNEL_FORMATS\n"));
LOG(("B_MULTI_SET_CHANNEL_FORMATS\n"));
return B_ERROR;
case B_MULTI_GET_MIX:
TRACE(("B_MULTI_GET_MIX\n"));
LOG(("B_MULTI_GET_MIX\n"));
return B_ERROR;
case B_MULTI_SET_MIX:
TRACE(("B_MULTI_SET_MIX\n"));
LOG(("B_MULTI_SET_MIX\n"));
return B_ERROR;
case B_MULTI_LIST_MIX_CHANNELS:
TRACE(("B_MULTI_LIST_MIX_CHANNELS\n"));
LOG(("B_MULTI_LIST_MIX_CHANNELS\n"));
return list_mix_channels((multi_mix_channel_info *)data);
case B_MULTI_LIST_MIX_CONTROLS:
TRACE(("B_MULTI_LIST_MIX_CONTROLS\n"));
LOG(("B_MULTI_LIST_MIX_CONTROLS\n"));
return list_mix_controls((multi_mix_control_info *)data);
case B_MULTI_LIST_MIX_CONNECTIONS:
TRACE(("B_MULTI_LIST_MIX_CONNECTIONS\n"));
LOG(("B_MULTI_LIST_MIX_CONNECTIONS\n"));
return list_mix_connections((multi_mix_connection_info *)data);
case B_MULTI_GET_BUFFERS: /* Fill out the struct for the first time; doesn't start anything. */
TRACE(("B_MULTI_GET_BUFFERS\n"));
LOG(("B_MULTI_GET_BUFFERS\n"));
return get_buffers(data);
case B_MULTI_SET_BUFFERS: /* Set what buffers to use, if the driver supports soft buffers. */
TRACE(("B_MULTI_SET_BUFFERS\n"));
LOG(("B_MULTI_SET_BUFFERS\n"));
return B_ERROR; /* we do not support soft buffers */
case B_MULTI_SET_START_TIME: /* When to actually start */
TRACE(("B_MULTI_SET_START_TIME\n"));
LOG(("B_MULTI_SET_START_TIME\n"));
return B_ERROR;
case B_MULTI_BUFFER_EXCHANGE: /* stop and go are derived from this being called */
// dprintf("B_MULTI_BUFFER_EXCHANGE\n");
return buffer_exchange((multi_buffer_info *)data);
case B_MULTI_BUFFER_FORCE_STOP: /* force stop of playback */
TRACE(("B_MULTI_BUFFER_FORCE_STOP\n"));
LOG(("B_MULTI_BUFFER_FORCE_STOP\n"));
return buffer_force_stop();
}
TRACE(("ERROR: unknown multi_control %#x\n",op));
LOG(("ERROR: unknown multi_control %#x\n",op));
return B_ERROR;
}

View File

@ -59,12 +59,12 @@ status_t probe_device(void)
uint32 value;
if (get_module(B_CONFIG_MANAGER_FOR_DRIVER_MODULE_NAME,(module_info **)&configmodule) < 0) {
dprintf(DRIVER_NAME " ERROR: couldn't load config manager module\n");
PRINT(("ERROR: couldn't load config manager module\n"));
return B_ERROR;
}
if (get_module(B_PCI_MODULE_NAME,(module_info **)&pcimodule) < 0) {
dprintf(DRIVER_NAME " ERROR: couldn't load pci module\n");
PRINT(("ERROR: couldn't load pci module\n"));
put_module(B_CONFIG_MANAGER_FOR_DRIVER_MODULE_NAME);
return B_ERROR;
}
@ -128,29 +128,33 @@ status_t probe_device(void)
free(dinfo);
continue;
}
TRACE(("found %s\n",config->name));
TRACE(("revision = %d\n",pciinfo->revision));
LOG(("found %s\n",config->name));
LOG(("revision = %d\n",pciinfo->revision));
#if DEBUG
TRACE(("bus = %#x, device = %#x, function = %#x\n",pciinfo->bus, pciinfo->device, pciinfo->function));
LOG(("bus = %#x, device = %#x, function = %#x\n",pciinfo->bus, pciinfo->device, pciinfo->function));
value = pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, 0x00, 2);
TRACE(("VID = %#04x\n",value));
LOG(("VID = %#04x\n",value));
value = pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, 0x02, 2);
TRACE(("DID = %#04x\n",value));
LOG(("DID = %#04x\n",value));
value = pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, 0x08, 1);
TRACE(("RID = %#02x\n",value));
LOG(("RID = %#02x\n",value));
value = pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, 0x04, 2);
TRACE(("PCICMD = %#04x\n",value));
LOG(("PCICMD = %#04x\n",value));
value = pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, 0x06, 2);
TRACE(("PCISTS = %#04x\n",value));
LOG(("PCISTS = %#04x\n",value));
value = pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, 0x10, 4);
TRACE(("NAMBAR = %#08x\n",value));
LOG(("NAMBAR = %#08x\n",value));
value = pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, 0x14, 4);
TRACE(("NABMBAR = %#08x\n",value));
LOG(("NABMBAR = %#08x\n",value));
value = pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, 0x18, 4);
LOG(("MMBAR = %#08x\n",value));
value = pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, 0x1C, 4);
LOG(("MBBAR = %#08x\n",value));
value = pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, 0x3c, 1);
TRACE(("INTR_LN = %#02x\n",value));
LOG(("INTR_LN = %#02x\n",value));
value = pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, 0x3d, 1);
TRACE(("INTR_PN = %#02x\n",value));
LOG(("INTR_PN = %#02x\n",value));
#endif
/*
@ -162,11 +166,11 @@ status_t probe_device(void)
value |= PCI_PCICMD_MSE | PCI_PCICMD_BME;
else
value |= PCI_PCICMD_IOS | PCI_PCICMD_BME;
pcimodule->write_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, 0x04, 2, value);
pcimodule->write_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, PCI_PCICMD, 2, value);
#if DEBUG
value = pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, PCI_PCICMD, 2);
TRACE(("PCICMD = %#04x\n",value));
LOG(("PCICMD = %#04x\n",value));
#endif
config->irq = pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, 0x3C, 1);
@ -175,10 +179,10 @@ status_t probe_device(void)
uint8 pin;
uint8 irq;
pin = pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, 0x3d, 1);
TRACE(("IRQ not assigned to pin %d\n",pin));
TRACE(("Searching for IRQ...\n"));
LOG(("IRQ not assigned to pin %d\n",pin));
LOG(("Searching for IRQ...\n"));
if (B_OK == find_pci_pin_irq(pin, &irq)) {
TRACE(("Assigning IRQ %d to pin %d\n",irq,pin));
LOG(("Assigning IRQ %d to pin %d\n",irq,pin));
config->irq = irq;
} else {
config->irq = 0; // always 0, not 0xff if no irq assigned
@ -195,21 +199,21 @@ status_t probe_device(void)
config->nabmbar = 0xfffffffe & pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, 0x14, 4);
}
TRACE(("irq = %d\n",config->irq));
TRACE(("nambar = %#08x\n",config->nambar));
TRACE(("nabmbar = %#08x\n",config->nabmbar));
TRACE(("mmbar = %#08x\n",config->mmbar));
TRACE(("mbbar = %#08x\n",config->mbbar));
LOG(("irq = %d\n",config->irq));
LOG(("nambar = %#08x\n",config->nambar));
LOG(("nabmbar = %#08x\n",config->nabmbar));
LOG(("mmbar = %#08x\n",config->mmbar));
LOG(("mbbar = %#08x\n",config->mbbar));
free(dinfo);
result = B_OK;
}
if (result != B_OK)
TRACE(("probe_device() hardware not found\n"));
LOG(("probe_device() hardware not found\n"));
//config->irq = 0;
if (config->irq == 0) {
dprintf(DRIVER_NAME ": WARNING: no interrupt configured\n");
PRINT(("WARNING: no interrupt configured\n"));
/*
* we can continue without an interrupt, as another
* workaround to handle this is also implemented
@ -217,12 +221,12 @@ status_t probe_device(void)
}
/* the ICH4 uses memory mapped IO */
if ((config->type & TYPE_ICH4) != 0 && ((config->mmbar == 0) || (config->mbbar == 0))) {
dprintf(DRIVER_NAME " ERROR: memory mapped IO not configured\n");
PRINT(("ERROR: memory mapped IO not configured\n"));
result = B_ERROR;
}
/* all other ICHs use programmed IO */
if ((config->type & TYPE_ICH4) == 0 && ((config->nambar == 0) || (config->nabmbar == 0))) {
dprintf(DRIVER_NAME " ERROR: IO space not configured\n");
PRINT(("ERROR: IO space not configured\n"));
result = B_ERROR;
}
@ -245,7 +249,7 @@ status_t find_pci_pin_irq(uint8 pin, uint8 *irq)
long index;
if (get_module(B_PCI_MODULE_NAME,(module_info **)&module) < 0) {
dprintf(DRIVER_NAME " ERROR: couldn't load pci module\n");
PRINT(("ERROR: couldn't load pci module\n"));
return B_ERROR;
}
@ -253,7 +257,7 @@ status_t find_pci_pin_irq(uint8 pin, uint8 *irq)
for (index = 0; B_OK == module->get_nth_pci_info(index, &info); index++) {
uint8 pciirq = module->read_pci_config(info.bus, info.device, info.function, PCI_interrupt_line, 1);
uint8 pcipin = module->read_pci_config(info.bus, info.device, info.function, PCI_interrupt_pin, 1);
TRACE(("pin %d, irq %d\n",pcipin,pciirq));
LOG(("pin %d, irq %d\n",pcipin,pciirq));
if (pcipin == pin && pciirq != 0 && pciirq != 0xff) {
*irq = pciirq;
result = B_OK;
@ -263,7 +267,7 @@ status_t find_pci_pin_irq(uint8 pin, uint8 *irq)
#if DEBUG
if (result != B_OK) {
TRACE(("Couldn't find IRQ for pin %d\n",pin));
LOG(("Couldn't find IRQ for pin %d\n",pin));
}
#endif

View File

@ -42,7 +42,31 @@ void log_create();
void debug_printf(const char *text,...)
{
#if DEBUG != 5
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;
@ -52,35 +76,15 @@ void debug_printf(const char *text,...)
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
}
void log_create()
{
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);
}
void log_printf(const char *text,...)
{
int fd;
char buf[1024];
va_list ap;
acquire_sem(loglock);
fd = open(logfile, O_WRONLY | O_APPEND);
va_start(ap,text);
vsprintf(buf,text,ap);
va_end(ap);
write(fd,buf,strlen(buf));
/* fsync(fd); */
close(fd);
release_sem(loglock);
}

View File

@ -28,28 +28,35 @@
#ifndef _DEBUG_H_
#define _DEBUG_H_
/* DEBUG == 0, no debugging
* DEBUG == 1, dprintf & LOG
* DEBUG == 2, dprintf with snooze & LOG
* DEBUG == 5, only LOG
/*
* 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 5
#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 ASSERT(a) if (a) {} else TRACE(("ASSERT failed! file = %s, line = %d\n",__FILE__,__LINE__))
#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
#define PRINT(a) debug_printf a
#define TRACE(a) ((void)(0))
#define ASSERT(a) ((void)(0))
#define LOG(a) ((void)(0))

View File

@ -88,20 +88,26 @@ enum REG_GLOB_CNT_BITS
/* ICH_REG_GLOB_STA (Global Status Register) Bits */
enum REG_GLOB_STA_BITS
{
STA_GSCI = 0x00000001,
STA_MIINT = 0x00000002,
STA_MOINT = 0x00000004,
STA_PIINT = 0x00000020,
STA_POINT = 0x00000040,
STA_MINT = 0x00000080,
STA_PCR = 0x00000100,
STA_SCR = 0x00000200,
STA_PRI = 0x00000400,
STA_SRI = 0x00000800,
STA_RCS = 0x00008000,
STA_GSCI = 0x00000001, /* GPI Status Change Interrupt */
STA_MIINT = 0x00000002, /* Modem In Interrupt */
STA_MOINT = 0x00000004, /* Modem Out Interrupt */
STA_PIINT = 0x00000020, /* PCM In Interrupt */
STA_POINT = 0x00000040, /* PCM Out Interrupt */
STA_MINT = 0x00000080, /* Mic In Interrupt */
STA_PCR = 0x00000100, /* AC_SDIN0 Codec Ready */
STA_SCR = 0x00000200, /* AC_SDIN1 Codec Ready */
STA_PRI = 0x00000400, /* AC_SDIN0 Resume Interrupt */
STA_SRI = 0x00000800, /* AC_SDIN1 Resume Interrupt */
STA_RCS = 0x00008000, /* Read Completition Status */
STA_AD3 = 0x00010000,
STA_MD3 = 0x00020000,
STA_INTMASK = (STA_MIINT | STA_MOINT | STA_PIINT | STA_POINT | STA_MINT | STA_PRI | STA_SRI)
STA_M2INT = 0x01000000, /* Microphone 2 In Interrupt */
STA_P2INT = 0x02000000, /* PCM In 2 Interrupt */
STA_SPINT = 0x04000000, /* S/PDIF Interrupt */
STA_BCS = 0x08000000, /* Bit Clock Stopped */
STA_S2CR = 0x10000000, /* AC_SDIN2 Codec Ready */
STA_S2RI = 0x20000000, /* AC_SDIN2 Resume Interrupt */
STA_INTMASK = (STA_MIINT | STA_MOINT | STA_PIINT | STA_POINT | STA_MINT | STA_PRI | STA_SRI | STA_M2INT | STA_P2INT | STA_SPINT | STA_S2RI)
};
#define ICH_BD_COUNT 32

View File

@ -63,21 +63,21 @@ int32 int_thread(void *data);
void dump_chan(ich_chan *chan)
{
int i;
TRACE(("chan->regbase = %#08x\n",chan->regbase));
TRACE(("chan->buffer_ready_sem = %#08x\n",chan->buffer_ready_sem));
LOG(("chan->regbase = %#08x\n",chan->regbase));
LOG(("chan->buffer_ready_sem = %#08x\n",chan->buffer_ready_sem));
TRACE(("chan->buffer_log_base = %#08x\n",chan->buffer_log_base));
TRACE(("chan->buffer_phy_base = %#08x\n",chan->buffer_phy_base));
TRACE(("chan->bd_phy_base = %#08x\n",chan->bd_phy_base));
TRACE(("chan->bd_log_base = %#08x\n",chan->bd_log_base));
LOG(("chan->buffer_log_base = %#08x\n",chan->buffer_log_base));
LOG(("chan->buffer_phy_base = %#08x\n",chan->buffer_phy_base));
LOG(("chan->bd_phy_base = %#08x\n",chan->bd_phy_base));
LOG(("chan->bd_log_base = %#08x\n",chan->bd_log_base));
for (i = 0; i < ICH_BD_COUNT; i++) {
TRACE(("chan->buffer[%d] = %#08x\n",i,chan->buffer[i]));
LOG(("chan->buffer[%d] = %#08x\n",i,chan->buffer[i]));
}
for (i = 0; i < ICH_BD_COUNT; i++) {
TRACE(("chan->bd[%d] = %#08x\n",i,chan->bd[i]));
TRACE(("chan->bd[%d]->buffer = %#08x\n",i,chan->bd[i]->buffer));
TRACE(("chan->bd[%d]->length = %#08x\n",i,chan->bd[i]->length));
TRACE(("chan->bd[%d]->flags = %#08x\n",i,chan->bd[i]->flags));
LOG(("chan->bd[%d] = %#08x\n",i,chan->bd[i]));
LOG(("chan->bd[%d]->buffer = %#08x\n",i,chan->bd[i]->buffer));
LOG(("chan->bd[%d]->length = %#08x\n",i,chan->bd[i]->length));
LOG(("chan->bd[%d]->flags = %#08x\n",i,chan->bd[i]->flags));
}
}
#endif
@ -86,7 +86,7 @@ void init_chan(ich_chan *chan)
{
int i;
ASSERT(BUFFER_COUNT <= ICH_BD_COUNT);
TRACE(("init chan\n"));
LOG(("init chan\n"));
chan->lastindex = 0;
chan->played_frames_count = 0;
@ -107,7 +107,7 @@ void init_chan(ich_chan *chan)
// set physical buffer descriptor base address
ich_reg_write_32(chan->regbase, (uint32)chan->bd_phy_base);
TRACE(("init chan finished\n"));
LOG(("init chan finished\n"));
}
void start_chan(ich_chan *chan)
@ -150,12 +150,12 @@ void reset_chan(ich_chan *chan)
for (i = 0; i < 10000; i++) {
cr = ich_reg_read_8(chan->regbase + ICH_REG_X_CR);
if (cr == 0) {
TRACE(("channel reset finished, %d\n",i));
LOG(("channel reset finished, %d\n",i));
return;
}
snooze(1);
}
TRACE(("channel reset failed after 10ms\n"));
LOG(("channel reset failed after 10ms\n"));
}
bool interrupt_test(void)
@ -165,7 +165,7 @@ bool interrupt_test(void)
bigtime_t duration;
int i;
TRACE(("testing if interrupt is working\n"));
LOG(("testing if interrupt is working\n"));
// our stack is not mapped in interrupt context, we must use malloc
// to have a valid pointer inside the interrupt handler
@ -202,10 +202,8 @@ bool interrupt_test(void)
#if DEBUG
if (result) {
TRACE(("got interrupt after %Lu us\n",duration));
LOG(("got interrupt after %Lu us\n",duration));
} else {
TRACE(("no interrupt, timeout after %Lu us\n",duration));
LOG(("no interrupt, timeout after %Lu us\n",duration));
}
#endif
@ -262,14 +260,12 @@ status_t map_io_memory(void)
config->area_mmbar = map_physical_memory("ich_ac97 mmbar io",(void *)config->mmbar, B_PAGE_SIZE, B_ANY_KERNEL_BLOCK_ADDRESS, B_READ_AREA | B_WRITE_AREA, &config->log_mmbar);
if (config->area_mmbar <= B_OK) {
TRACE(("mapping of mmbar io failed\n"));
LOG(("mapping of mmbar io failed, error = %#x\n",config->area_mmbar));
return B_ERROR;
}
LOG(("mapping of mmbar: area %#x, phys %#x, log %#x\n", config->area_mmbar, config->mmbar, config->log_mmbar));
config->area_mbbar = map_physical_memory("ich_ac97 mbbar io",(void *)config->mbbar, B_PAGE_SIZE, B_ANY_KERNEL_BLOCK_ADDRESS, B_READ_AREA | B_WRITE_AREA, &config->log_mbbar);
if (config->area_mbbar <= B_OK) {
TRACE(("mapping of mbbar io failed\n"));
LOG(("mapping of mbbar io failed, error = %#x\n",config->area_mbbar));
delete_area(config->area_mmbar);
config->area_mmbar = -1;
@ -304,57 +300,77 @@ int32 int_thread(void *data)
status_t
init_hardware(void)
{
LOG_CREATE();
if (B_OK == probe_device()) {
dprintf("ALL YOUR BASE ARE BELONG TO US\n");
PRINT(("ALL YOUR BASE ARE BELONG TO US\n"));
return B_OK;
}
} else {
LOG(("hardware not found\n"));
return B_ERROR;
}
}
void
dump_hardware_regs()
{
LOG(("GLOB_CNT = %#08x\n",ich_reg_read_32(ICH_REG_GLOB_CNT)));
LOG(("GLOB_STA = %#08x\n",ich_reg_read_32(ICH_REG_GLOB_STA)));
LOG(("PI ICH_REG_X_BDBAR = %#x\n",ich_reg_read_32(ICH_REG_X_BDBAR + ICH_REG_PI_BASE)));
LOG(("PI ICH_REG_X_CIV = %#x\n",ich_reg_read_8(ICH_REG_X_CIV + ICH_REG_PI_BASE)));
LOG(("PI ICH_REG_X_LVI = %#x\n",ich_reg_read_8(ICH_REG_X_LVI + ICH_REG_PI_BASE)));
LOG(("PI ICH_REG_X_SR = %#x\n",ich_reg_read_16(ICH_REG_X_SR + ICH_REG_PI_BASE)));
LOG(("PI ICH_REG_X_PICB = %#x\n",ich_reg_read_16(ICH_REG_X_PICB + ICH_REG_PI_BASE)));
LOG(("PI ICH_REG_X_PIV = %#x\n",ich_reg_read_8(ICH_REG_X_PIV + ICH_REG_PI_BASE)));
LOG(("PI ICH_REG_X_CR = %#x\n",ich_reg_read_8(ICH_REG_X_CR + ICH_REG_PI_BASE)));
LOG(("PO ICH_REG_X_BDBAR = %#x\n",ich_reg_read_32(ICH_REG_X_BDBAR + ICH_REG_PO_BASE)));
LOG(("PO ICH_REG_X_CIV = %#x\n",ich_reg_read_8(ICH_REG_X_CIV + ICH_REG_PO_BASE)));
LOG(("PO ICH_REG_X_LVI = %#x\n",ich_reg_read_8(ICH_REG_X_LVI + ICH_REG_PO_BASE)));
LOG(("PO ICH_REG_X_SR = %#x\n",ich_reg_read_16(ICH_REG_X_SR + ICH_REG_PO_BASE)));
LOG(("PO ICH_REG_X_PICB = %#x\n",ich_reg_read_16(ICH_REG_X_PICB + ICH_REG_PO_BASE)));
LOG(("PO ICH_REG_X_PIV = %#x\n",ich_reg_read_8(ICH_REG_X_PIV + ICH_REG_PO_BASE)));
LOG(("PO ICH_REG_X_CR = %#x\n",ich_reg_read_8(ICH_REG_X_CR + ICH_REG_PO_BASE)));
}
status_t
init_driver(void)
{
status_t rv;
bigtime_t start;
TRACE(("init_driver\n"));
LOG_CREATE();
LOG(("init_driver\n"));
ASSERT(sizeof(ich_bd) == 8);
rv = probe_device();
if (rv != B_OK) {
LOG(("No supported audio hardware found.\n"));
TRACE(("hardware not found\n"));
return B_ERROR;
}
dprintf("ich-ac97: " VERSION "\n");
dprintf("ich-ac97: found %s, IRQ = %ld, NAMBAR = %#lX, NABMBAR = %#lX, MMBAR = %#lX, MBBAR = %#lX\n",config->name,config->irq,config->nambar,config->nabmbar,config->mmbar,config->mbbar);
LOG(("Found %s\nIRQ = %ld\nNAMBAR = %#lX\nNABMBAR = %#lX\nMMBAR = %#lX\nMBBAR = %#lX\n",config->name,config->irq,config->nambar,config->nabmbar,config->mmbar,config->mbbar));
PRINT((VERSION "\n"));
PRINT(("found %s\n", config->name));
PRINT(("IRQ = %ld, NAMBAR = %#lX, NABMBAR = %#lX, MMBAR = %#lX, MBBAR = %#lX\n",config->irq,config->nambar,config->nabmbar,config->mmbar,config->mbbar));
/* before doing anything else, map the IO memory */
rv = map_io_memory();
if (rv != B_OK) {
dprintf("ich-ac97: mapping of memory IO space failed\n");
LOG(("mapping of memory IO space failed\n"));
PRINT(("mapping of memory IO space failed\n"));
return B_ERROR;
}
TRACE(("GLOB_CNT = %#08x\n",ich_reg_read_32(ICH_REG_GLOB_CNT)));
TRACE(("GLOB_STA = %#08x\n",ich_reg_read_32(ICH_REG_GLOB_STA)));
TRACE(("PO ICH_REG_X_LVI = %d\n",ich_reg_read_8(ICH_REG_X_LVI)));
dump_hardware_regs();
/* do a cold reset */
TRACE(("cold reset\n"));
LOG(("cold reset\n"));
ich_reg_write_32(ICH_REG_GLOB_CNT, 0);
snooze(50000); // 50 ms
ich_reg_write_32(ICH_REG_GLOB_CNT, CNT_COLD | CNT_PRIE);
TRACE(("cold reset finished\n"));
LOG(("cold reset finished\n"));
rv = ich_reg_read_32(ICH_REG_GLOB_CNT);
if ((rv & CNT_COLD) == 0) {
TRACE(("cold reset failed\n"));
LOG(("cold reset failed\n"));
}
@ -367,10 +383,8 @@ init_driver(void)
snooze(50000);
}
if ((rv & STA_PCR)) {
TRACE(("primary codec ready after %Ld us\n",(system_time() - start)));
LOG(("primary codec ready after %Ld us\n",(system_time() - start)));
} else {
TRACE(("primary codec not ready after %Ld us\n",(system_time() - start)));
LOG(("primary codec not ready after %Ld us\n",(system_time() - start)));
}
while ((system_time() - start) < 1000000) {
@ -380,31 +394,48 @@ init_driver(void)
snooze(50000);
}
if ((rv & STA_SCR)) {
TRACE(("secondary codec ready after %Ld us\n",(system_time() - start)));
LOG(("secondary codec ready after %Ld us\n",(system_time() - start)));
} else {
TRACE(("secondary codec not ready after %Ld us\n",(system_time() - start)));
LOG(("secondary codec not ready after %Ld us\n",(system_time() - start)));
}
if ((rv & (STA_PCR | STA_SCR)) == 0) {
dprintf("ich-ac97: compatible chipset found, but no codec ready!\n");
while ((system_time() - start) < 1000000) {
rv = ich_reg_read_32(ICH_REG_GLOB_STA);
if ((rv & STA_S2CR) != 0)
break;
snooze(50000);
}
if ((rv & STA_S2CR)) {
LOG(("tertiary codec ready after %Ld us\n",(system_time() - start)));
} else {
LOG(("tertiary codec not ready after %Ld us\n",(system_time() - start)));
}
dump_hardware_regs();
if ((rv & (STA_PCR | STA_SCR | STA_S2CR)) == 0) {
PRINT(("compatible chipset found, but no codec ready!\n"));
unmap_io_memory();
return B_ERROR;
}
if ((rv & STA_PCR) == 0 && (rv & STA_SCR) != 0) {
TRACE(("using secondary codec!\n"));
if ((rv & STA_PCR) == 0 && (rv & STA_S2CR) != 0) {
LOG(("using tertiary codec!\n"));
config->nambar += 0x100;
config->log_mmbar += 0x100; /* ICH 4 */
} else if ((rv & STA_PCR) == 0 && (rv & STA_SCR) != 0) {
LOG(("using secondary codec!\n"));
config->nambar += 0x80;
config->log_mmbar += 0x80; /* ICH 4 */
}
dump_hardware_regs();
/* allocate memory for channel info struct */
chan_pi = (ich_chan *) malloc(sizeof(ich_chan));
chan_po = (ich_chan *) malloc(sizeof(ich_chan));
chan_mc = (ich_chan *) malloc(sizeof(ich_chan));
if (0 == chan_pi || 0 == chan_po || 0 == chan_mc) {
dprintf("ich-ac97: couldn't allocate memory for channel descriptors!\n");
LOG(("couldn't allocate memory for channel descriptors!\n"));
PRINT(("couldn't allocate memory for channel descriptors!\n"));
chan_free_resources();
unmap_io_memory();
return B_ERROR;
@ -426,8 +457,7 @@ init_driver(void)
if ( chan_po->bd_area < B_OK || chan_po->buffer_area < B_OK || chan_po->userbuffer_area < B_OK ||
chan_pi->bd_area < B_OK || chan_pi->buffer_area < B_OK || chan_pi->userbuffer_area < B_OK ||
chan_mc->bd_area < B_OK || chan_mc->buffer_area < B_OK || chan_mc->userbuffer_area < B_OK) {
dprintf("ich-ac97: couldn't allocate memory for DMA buffers!\n");
LOG(("ich-ac97: couldn't allocate memory for DMA buffers!\n"));
PRINT(("couldn't allocate memory for DMA buffers!\n"));
chan_free_resources();
unmap_io_memory();
return B_ERROR;
@ -439,8 +469,7 @@ init_driver(void)
chan_mc->buffer_ready_sem = create_sem(0,"mc buffer ready"); /* 0 available mic in buffers */
if (chan_po->buffer_ready_sem < B_OK || chan_pi->buffer_ready_sem < B_OK || chan_mc->buffer_ready_sem < B_OK) {
dprintf("ich-ac97: couldn't create semaphores!\n");
LOG(("ich-ac97: couldn't create semaphores!\n"));
PRINT(("couldn't create semaphores!\n"));
chan_free_resources();
unmap_io_memory();
return B_ERROR;
@ -452,7 +481,7 @@ init_driver(void)
chan_mc->regbase = ICH_REG_MC_BASE;
/* reset the (primary?) codec */
TRACE(("codec reset\n"));
LOG(("codec reset\n"));
ich_codec_write(0x00, 0x0000);
snooze(50000); // 50 ms
@ -475,7 +504,6 @@ init_driver(void)
/* first test if interrupts are working, on some Laptops they don't work :-( */
if (config->irq != 0 && false == interrupt_test()) {
TRACE(("interrupt not working, using a kernel thread for polling\n"));
LOG(("interrupt not working, using a kernel thread for polling\n"));
config->irq = 0; /* don't use interrupts */
}
@ -509,19 +537,16 @@ init_driver(void)
/* ich_codec_write(0x1E, 0x0000); */
#endif
TRACE(("init_driver finished!\n"));
LOG(("init_driver finished!\n"));
return B_OK;
}
void
uninit_driver(void)
{
TRACE(("uninit_driver()\n"));
LOG(("uninit_driver()\n"));
#if DEBUG
if (chan_po) TRACE(("chan_po frames_count = %Ld\n",chan_po->played_frames_count));
if (chan_pi) TRACE(("chan_pi frames_count = %Ld\n",chan_pi->played_frames_count));
if (chan_mc) TRACE(("chan_mc frames_count = %Ld\n",chan_mc->played_frames_count));
if (chan_po) LOG(("chan_po frames_count = %Ld\n",chan_po->played_frames_count));
if (chan_pi) LOG(("chan_pi frames_count = %Ld\n",chan_pi->played_frames_count));
if (chan_mc) LOG(("chan_mc frames_count = %Ld\n",chan_mc->played_frames_count));
@ -557,7 +582,7 @@ uninit_driver(void)
/* the very last thing to do is unmap the io memory */
unmap_io_memory();
TRACE(("uninit_driver() finished\n"));
LOG(("uninit_driver() finished\n"));
}
int32 ich_test_int(void *check)
@ -681,14 +706,14 @@ int32 ich_int(void *unused)
static status_t
ich_open(const char *name, uint32 flags, void** cookie)
{
TRACE(("open()\n"));
LOG(("open()\n"));
return B_OK;
}
static status_t
ich_close(void* cookie)
{
TRACE(("close()\n"));
LOG(("close()\n"));
return B_OK;
}

View File

@ -30,7 +30,7 @@
#include "hardware.h"
#define VERSION "Version 1.2, Copyright (c) 2002 Marcus Overhagen, compiled on " ## __DATE__ ## " " ## __TIME__
#define VERSION "Version 1.3, Copyright (c) 2002 Marcus Overhagen, compiled on " ## __DATE__ ## " " ## __TIME__
#define DRIVER_NAME "ich_ac97"
#define BUFFER_SIZE 2048

View File

@ -133,7 +133,7 @@ ich_codec_read(int regno)
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255);
rv = ich_codec_wait();
if (rv != B_OK)
dprintf(DRIVER_NAME " semaphore timeout reading register %#x\n",regno);
PRINT(("semaphore timeout reading register %#x\n",regno));
if (config->type & TYPE_ICH4)
return *(uint16 *)(((char *)config->log_mmbar) + regno);
else
@ -148,7 +148,7 @@ ich_codec_write(int regno, uint16 value)
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255);
rv = ich_codec_wait();
if (rv != B_OK)
dprintf(DRIVER_NAME " semaphore timeout writing register %#x\n",regno);
PRINT(("semaphore timeout writing register %#x\n",regno));
if (config->type & TYPE_ICH4)
*(uint16 *)(((char *)config->log_mmbar) + regno) = value;
else

View File

@ -63,18 +63,18 @@ area_id alloc_mem(void **phy, void **log, size_t size, const char *name)
area_id areaid;
status_t rv;
TRACE(("allocating %d bytes for %s\n",size,name));
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) {
TRACE(("couldn't allocate area %s\n",name));
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);
TRACE(("couldn't map %s\n",name));
PRINT(("couldn't map %s\n",name));
return B_ERROR;
}
memset(logadr,0,size);
@ -82,7 +82,7 @@ area_id alloc_mem(void **phy, void **log, size_t size, const char *name)
*log = logadr;
if (phy)
*phy = pe.address;
TRACE(("area = %d, size = %d, log = %#08X, phy = %#08X\n",areaid,size,logadr,pe.address));
LOG(("area = %d, size = %d, log = %#08X, phy = %#08X\n",areaid,size,logadr,pe.address));
return areaid;
}