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:
parent
6c3c3848cc
commit
15ea765d53
@ -26,6 +26,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <MediaDefs.h>
|
#include <MediaDefs.h>
|
||||||
#include "ac97.h"
|
#include "ac97.h"
|
||||||
|
|
||||||
|
@ -99,9 +99,9 @@ static status_t get_description(multi_description *data)
|
|||||||
// channel, second, third, ..., followed by output bus
|
// channel, second, third, ..., followed by output bus
|
||||||
// channels and input bus channels and finally auxillary channels,
|
// 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]))) {
|
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));
|
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)
|
static status_t get_buffers(multi_buffer_list *data)
|
||||||
{
|
{
|
||||||
TRACE(("flags = %#x\n",data->flags));
|
LOG(("flags = %#x\n",data->flags));
|
||||||
TRACE(("request_playback_buffers = %#x\n",data->request_playback_buffers));
|
LOG(("request_playback_buffers = %#x\n",data->request_playback_buffers));
|
||||||
TRACE(("request_playback_channels = %#x\n",data->request_playback_channels));
|
LOG(("request_playback_channels = %#x\n",data->request_playback_channels));
|
||||||
TRACE(("request_playback_buffer_size = %#x\n",data->request_playback_buffer_size));
|
LOG(("request_playback_buffer_size = %#x\n",data->request_playback_buffer_size));
|
||||||
TRACE(("request_record_buffers = %#x\n",data->request_record_buffers));
|
LOG(("request_record_buffers = %#x\n",data->request_record_buffers));
|
||||||
TRACE(("request_record_channels = %#x\n",data->request_record_channels));
|
LOG(("request_record_channels = %#x\n",data->request_record_channels));
|
||||||
TRACE(("request_record_buffer_size = %#x\n",data->request_record_buffer_size));
|
LOG(("request_record_buffer_size = %#x\n",data->request_record_buffer_size));
|
||||||
|
|
||||||
if (data->request_playback_buffers < 2 ||
|
if (data->request_playback_buffers < 2 ||
|
||||||
data->request_playback_channels < 2 ||
|
data->request_playback_channels < 2 ||
|
||||||
data->request_record_buffers < 2 ||
|
data->request_record_buffers < 2 ||
|
||||||
data->request_record_channels < 2) {
|
data->request_record_channels < 2) {
|
||||||
TRACE(("not enough channels/buffers\n"));
|
LOG(("not enough channels/buffers\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(BUFFER_COUNT == 2);
|
ASSERT(BUFFER_COUNT == 2);
|
||||||
@ -298,69 +298,69 @@ status_t multi_control(void *cookie, uint32 op, void *data, size_t length)
|
|||||||
{
|
{
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case B_MULTI_GET_DESCRIPTION:
|
case B_MULTI_GET_DESCRIPTION:
|
||||||
TRACE(("B_MULTI_GET_DESCRIPTION\n"));
|
LOG(("B_MULTI_GET_DESCRIPTION\n"));
|
||||||
return get_description((multi_description *)data);
|
return get_description((multi_description *)data);
|
||||||
case B_MULTI_GET_EVENT_INFO:
|
case B_MULTI_GET_EVENT_INFO:
|
||||||
TRACE(("B_MULTI_GET_EVENT_INFO\n"));
|
LOG(("B_MULTI_GET_EVENT_INFO\n"));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
case B_MULTI_SET_EVENT_INFO:
|
case B_MULTI_SET_EVENT_INFO:
|
||||||
TRACE(("B_MULTI_SET_EVENT_INFO\n"));
|
LOG(("B_MULTI_SET_EVENT_INFO\n"));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
case B_MULTI_GET_EVENT:
|
case B_MULTI_GET_EVENT:
|
||||||
TRACE(("B_MULTI_GET_EVENT\n"));
|
LOG(("B_MULTI_GET_EVENT\n"));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
case B_MULTI_GET_ENABLED_CHANNELS:
|
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);
|
return get_enabled_channels((multi_channel_enable *)data);
|
||||||
case B_MULTI_SET_ENABLED_CHANNELS:
|
case B_MULTI_SET_ENABLED_CHANNELS:
|
||||||
TRACE(("B_MULTI_SET_ENABLED_CHANNELS\n"));
|
LOG(("B_MULTI_SET_ENABLED_CHANNELS\n"));
|
||||||
return B_OK; break;
|
return B_OK; break;
|
||||||
case B_MULTI_GET_GLOBAL_FORMAT:
|
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);
|
return get_global_format((multi_format_info *)data);
|
||||||
case B_MULTI_SET_GLOBAL_FORMAT:
|
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
|
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
|
* BeOS to accept the format returned in B_MULTI_GET_GLOBAL_FORMAT
|
||||||
*/
|
*/
|
||||||
case B_MULTI_GET_CHANNEL_FORMATS:
|
case B_MULTI_GET_CHANNEL_FORMATS:
|
||||||
TRACE(("B_MULTI_GET_CHANNEL_FORMATS\n"));
|
LOG(("B_MULTI_GET_CHANNEL_FORMATS\n"));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
case B_MULTI_SET_CHANNEL_FORMATS: /* only implemented if possible */
|
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;
|
return B_ERROR;
|
||||||
case B_MULTI_GET_MIX:
|
case B_MULTI_GET_MIX:
|
||||||
TRACE(("B_MULTI_GET_MIX\n"));
|
LOG(("B_MULTI_GET_MIX\n"));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
case B_MULTI_SET_MIX:
|
case B_MULTI_SET_MIX:
|
||||||
TRACE(("B_MULTI_SET_MIX\n"));
|
LOG(("B_MULTI_SET_MIX\n"));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
case B_MULTI_LIST_MIX_CHANNELS:
|
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);
|
return list_mix_channels((multi_mix_channel_info *)data);
|
||||||
case B_MULTI_LIST_MIX_CONTROLS:
|
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);
|
return list_mix_controls((multi_mix_control_info *)data);
|
||||||
case B_MULTI_LIST_MIX_CONNECTIONS:
|
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);
|
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. */
|
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);
|
return get_buffers(data);
|
||||||
case B_MULTI_SET_BUFFERS: /* Set what buffers to use, if the driver supports soft buffers. */
|
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 */
|
return B_ERROR; /* we do not support soft buffers */
|
||||||
case B_MULTI_SET_START_TIME: /* When to actually start */
|
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;
|
return B_ERROR;
|
||||||
case B_MULTI_BUFFER_EXCHANGE: /* stop and go are derived from this being called */
|
case B_MULTI_BUFFER_EXCHANGE: /* stop and go are derived from this being called */
|
||||||
// dprintf("B_MULTI_BUFFER_EXCHANGE\n");
|
// dprintf("B_MULTI_BUFFER_EXCHANGE\n");
|
||||||
return buffer_exchange((multi_buffer_info *)data);
|
return buffer_exchange((multi_buffer_info *)data);
|
||||||
case B_MULTI_BUFFER_FORCE_STOP: /* force stop of playback */
|
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();
|
return buffer_force_stop();
|
||||||
}
|
}
|
||||||
TRACE(("ERROR: unknown multi_control %#x\n",op));
|
LOG(("ERROR: unknown multi_control %#x\n",op));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,12 +59,12 @@ status_t probe_device(void)
|
|||||||
uint32 value;
|
uint32 value;
|
||||||
|
|
||||||
if (get_module(B_CONFIG_MANAGER_FOR_DRIVER_MODULE_NAME,(module_info **)&configmodule) < 0) {
|
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;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_module(B_PCI_MODULE_NAME,(module_info **)&pcimodule) < 0) {
|
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);
|
put_module(B_CONFIG_MANAGER_FOR_DRIVER_MODULE_NAME);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
@ -128,29 +128,33 @@ status_t probe_device(void)
|
|||||||
free(dinfo);
|
free(dinfo);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
TRACE(("found %s\n",config->name));
|
LOG(("found %s\n",config->name));
|
||||||
TRACE(("revision = %d\n",pciinfo->revision));
|
LOG(("revision = %d\n",pciinfo->revision));
|
||||||
|
|
||||||
#if DEBUG
|
#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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -162,11 +166,11 @@ status_t probe_device(void)
|
|||||||
value |= PCI_PCICMD_MSE | PCI_PCICMD_BME;
|
value |= PCI_PCICMD_MSE | PCI_PCICMD_BME;
|
||||||
else
|
else
|
||||||
value |= PCI_PCICMD_IOS | PCI_PCICMD_BME;
|
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
|
#if DEBUG
|
||||||
value = pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, PCI_PCICMD, 2);
|
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
|
#endif
|
||||||
|
|
||||||
config->irq = pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, 0x3C, 1);
|
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 pin;
|
||||||
uint8 irq;
|
uint8 irq;
|
||||||
pin = pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, 0x3d, 1);
|
pin = pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, 0x3d, 1);
|
||||||
TRACE(("IRQ not assigned to pin %d\n",pin));
|
LOG(("IRQ not assigned to pin %d\n",pin));
|
||||||
TRACE(("Searching for IRQ...\n"));
|
LOG(("Searching for IRQ...\n"));
|
||||||
if (B_OK == find_pci_pin_irq(pin, &irq)) {
|
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;
|
config->irq = irq;
|
||||||
} else {
|
} else {
|
||||||
config->irq = 0; // always 0, not 0xff if no irq assigned
|
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);
|
config->nabmbar = 0xfffffffe & pcimodule->read_pci_config(pciinfo->bus, pciinfo->device, pciinfo->function, 0x14, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE(("irq = %d\n",config->irq));
|
LOG(("irq = %d\n",config->irq));
|
||||||
TRACE(("nambar = %#08x\n",config->nambar));
|
LOG(("nambar = %#08x\n",config->nambar));
|
||||||
TRACE(("nabmbar = %#08x\n",config->nabmbar));
|
LOG(("nabmbar = %#08x\n",config->nabmbar));
|
||||||
TRACE(("mmbar = %#08x\n",config->mmbar));
|
LOG(("mmbar = %#08x\n",config->mmbar));
|
||||||
TRACE(("mbbar = %#08x\n",config->mbbar));
|
LOG(("mbbar = %#08x\n",config->mbbar));
|
||||||
|
|
||||||
free(dinfo);
|
free(dinfo);
|
||||||
result = B_OK;
|
result = B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
TRACE(("probe_device() hardware not found\n"));
|
LOG(("probe_device() hardware not found\n"));
|
||||||
//config->irq = 0;
|
//config->irq = 0;
|
||||||
if (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
|
* we can continue without an interrupt, as another
|
||||||
* workaround to handle this is also implemented
|
* workaround to handle this is also implemented
|
||||||
@ -217,12 +221,12 @@ status_t probe_device(void)
|
|||||||
}
|
}
|
||||||
/* the ICH4 uses memory mapped IO */
|
/* the ICH4 uses memory mapped IO */
|
||||||
if ((config->type & TYPE_ICH4) != 0 && ((config->mmbar == 0) || (config->mbbar == 0))) {
|
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;
|
result = B_ERROR;
|
||||||
}
|
}
|
||||||
/* all other ICHs use programmed IO */
|
/* all other ICHs use programmed IO */
|
||||||
if ((config->type & TYPE_ICH4) == 0 && ((config->nambar == 0) || (config->nabmbar == 0))) {
|
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;
|
result = B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,7 +249,7 @@ status_t find_pci_pin_irq(uint8 pin, uint8 *irq)
|
|||||||
long index;
|
long index;
|
||||||
|
|
||||||
if (get_module(B_PCI_MODULE_NAME,(module_info **)&module) < 0) {
|
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;
|
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++) {
|
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 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);
|
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) {
|
if (pcipin == pin && pciirq != 0 && pciirq != 0xff) {
|
||||||
*irq = pciirq;
|
*irq = pciirq;
|
||||||
result = B_OK;
|
result = B_OK;
|
||||||
@ -263,7 +267,7 @@ status_t find_pci_pin_irq(uint8 pin, uint8 *irq)
|
|||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (result != B_OK) {
|
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
|
#endif
|
||||||
|
|
||||||
|
@ -42,7 +42,31 @@ void log_create();
|
|||||||
|
|
||||||
void debug_printf(const char *text,...)
|
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];
|
char buf[1024];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
@ -52,35 +76,15 @@ void debug_printf(const char *text,...)
|
|||||||
|
|
||||||
dprintf(DRIVER_NAME ": %s",buf);
|
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
|
#if DEBUG > 1
|
||||||
snooze(150000);
|
snooze(150000);
|
||||||
#endif
|
#endif
|
||||||
#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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -28,28 +28,35 @@
|
|||||||
#ifndef _DEBUG_H_
|
#ifndef _DEBUG_H_
|
||||||
#define _DEBUG_H_
|
#define _DEBUG_H_
|
||||||
|
|
||||||
/* DEBUG == 0, no debugging
|
/*
|
||||||
* DEBUG == 1, dprintf & LOG
|
* PRINT() executes dprintf if DEBUG = 0 (disabled), or expands to LOG() when DEBUG > 0
|
||||||
* DEBUG == 2, dprintf with snooze & LOG
|
* TRACE() executes dprintf if DEBUG > 0
|
||||||
* DEBUG == 5, only LOG
|
* 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
|
#ifndef DEBUG
|
||||||
#define DEBUG 5
|
#define DEBUG 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#undef PRINT
|
||||||
#undef TRACE
|
#undef TRACE
|
||||||
#undef ASSERT
|
#undef ASSERT
|
||||||
|
|
||||||
#if DEBUG > 0
|
#if DEBUG > 0
|
||||||
|
#define PRINT(a) log_printf a
|
||||||
#define TRACE(a) debug_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(a) log_printf a
|
||||||
#define LOG_CREATE() log_create()
|
#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_create();
|
||||||
void log_printf(const char *text,...);
|
void log_printf(const char *text,...);
|
||||||
void debug_printf(const char *text,...);
|
void debug_printf(const char *text,...);
|
||||||
#else
|
#else
|
||||||
|
#define PRINT(a) debug_printf a
|
||||||
#define TRACE(a) ((void)(0))
|
#define TRACE(a) ((void)(0))
|
||||||
#define ASSERT(a) ((void)(0))
|
#define ASSERT(a) ((void)(0))
|
||||||
#define LOG(a) ((void)(0))
|
#define LOG(a) ((void)(0))
|
||||||
|
@ -88,20 +88,26 @@ enum REG_GLOB_CNT_BITS
|
|||||||
/* ICH_REG_GLOB_STA (Global Status Register) Bits */
|
/* ICH_REG_GLOB_STA (Global Status Register) Bits */
|
||||||
enum REG_GLOB_STA_BITS
|
enum REG_GLOB_STA_BITS
|
||||||
{
|
{
|
||||||
STA_GSCI = 0x00000001,
|
STA_GSCI = 0x00000001, /* GPI Status Change Interrupt */
|
||||||
STA_MIINT = 0x00000002,
|
STA_MIINT = 0x00000002, /* Modem In Interrupt */
|
||||||
STA_MOINT = 0x00000004,
|
STA_MOINT = 0x00000004, /* Modem Out Interrupt */
|
||||||
STA_PIINT = 0x00000020,
|
STA_PIINT = 0x00000020, /* PCM In Interrupt */
|
||||||
STA_POINT = 0x00000040,
|
STA_POINT = 0x00000040, /* PCM Out Interrupt */
|
||||||
STA_MINT = 0x00000080,
|
STA_MINT = 0x00000080, /* Mic In Interrupt */
|
||||||
STA_PCR = 0x00000100,
|
STA_PCR = 0x00000100, /* AC_SDIN0 Codec Ready */
|
||||||
STA_SCR = 0x00000200,
|
STA_SCR = 0x00000200, /* AC_SDIN1 Codec Ready */
|
||||||
STA_PRI = 0x00000400,
|
STA_PRI = 0x00000400, /* AC_SDIN0 Resume Interrupt */
|
||||||
STA_SRI = 0x00000800,
|
STA_SRI = 0x00000800, /* AC_SDIN1 Resume Interrupt */
|
||||||
STA_RCS = 0x00008000,
|
STA_RCS = 0x00008000, /* Read Completition Status */
|
||||||
STA_AD3 = 0x00010000,
|
STA_AD3 = 0x00010000,
|
||||||
STA_MD3 = 0x00020000,
|
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
|
#define ICH_BD_COUNT 32
|
||||||
|
@ -63,21 +63,21 @@ int32 int_thread(void *data);
|
|||||||
void dump_chan(ich_chan *chan)
|
void dump_chan(ich_chan *chan)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
TRACE(("chan->regbase = %#08x\n",chan->regbase));
|
LOG(("chan->regbase = %#08x\n",chan->regbase));
|
||||||
TRACE(("chan->buffer_ready_sem = %#08x\n",chan->buffer_ready_sem));
|
LOG(("chan->buffer_ready_sem = %#08x\n",chan->buffer_ready_sem));
|
||||||
|
|
||||||
TRACE(("chan->buffer_log_base = %#08x\n",chan->buffer_log_base));
|
LOG(("chan->buffer_log_base = %#08x\n",chan->buffer_log_base));
|
||||||
TRACE(("chan->buffer_phy_base = %#08x\n",chan->buffer_phy_base));
|
LOG(("chan->buffer_phy_base = %#08x\n",chan->buffer_phy_base));
|
||||||
TRACE(("chan->bd_phy_base = %#08x\n",chan->bd_phy_base));
|
LOG(("chan->bd_phy_base = %#08x\n",chan->bd_phy_base));
|
||||||
TRACE(("chan->bd_log_base = %#08x\n",chan->bd_log_base));
|
LOG(("chan->bd_log_base = %#08x\n",chan->bd_log_base));
|
||||||
for (i = 0; i < ICH_BD_COUNT; i++) {
|
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++) {
|
for (i = 0; i < ICH_BD_COUNT; i++) {
|
||||||
TRACE(("chan->bd[%d] = %#08x\n",i,chan->bd[i]));
|
LOG(("chan->bd[%d] = %#08x\n",i,chan->bd[i]));
|
||||||
TRACE(("chan->bd[%d]->buffer = %#08x\n",i,chan->bd[i]->buffer));
|
LOG(("chan->bd[%d]->buffer = %#08x\n",i,chan->bd[i]->buffer));
|
||||||
TRACE(("chan->bd[%d]->length = %#08x\n",i,chan->bd[i]->length));
|
LOG(("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]->flags = %#08x\n",i,chan->bd[i]->flags));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -86,7 +86,7 @@ void init_chan(ich_chan *chan)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
ASSERT(BUFFER_COUNT <= ICH_BD_COUNT);
|
ASSERT(BUFFER_COUNT <= ICH_BD_COUNT);
|
||||||
TRACE(("init chan\n"));
|
LOG(("init chan\n"));
|
||||||
|
|
||||||
chan->lastindex = 0;
|
chan->lastindex = 0;
|
||||||
chan->played_frames_count = 0;
|
chan->played_frames_count = 0;
|
||||||
@ -107,7 +107,7 @@ void init_chan(ich_chan *chan)
|
|||||||
// set physical buffer descriptor base address
|
// set physical buffer descriptor base address
|
||||||
ich_reg_write_32(chan->regbase, (uint32)chan->bd_phy_base);
|
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)
|
void start_chan(ich_chan *chan)
|
||||||
@ -150,12 +150,12 @@ void reset_chan(ich_chan *chan)
|
|||||||
for (i = 0; i < 10000; i++) {
|
for (i = 0; i < 10000; i++) {
|
||||||
cr = ich_reg_read_8(chan->regbase + ICH_REG_X_CR);
|
cr = ich_reg_read_8(chan->regbase + ICH_REG_X_CR);
|
||||||
if (cr == 0) {
|
if (cr == 0) {
|
||||||
TRACE(("channel reset finished, %d\n",i));
|
LOG(("channel reset finished, %d\n",i));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
snooze(1);
|
snooze(1);
|
||||||
}
|
}
|
||||||
TRACE(("channel reset failed after 10ms\n"));
|
LOG(("channel reset failed after 10ms\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool interrupt_test(void)
|
bool interrupt_test(void)
|
||||||
@ -165,7 +165,7 @@ bool interrupt_test(void)
|
|||||||
bigtime_t duration;
|
bigtime_t duration;
|
||||||
int i;
|
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
|
// our stack is not mapped in interrupt context, we must use malloc
|
||||||
// to have a valid pointer inside the interrupt handler
|
// to have a valid pointer inside the interrupt handler
|
||||||
@ -202,10 +202,8 @@ bool interrupt_test(void)
|
|||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (result) {
|
if (result) {
|
||||||
TRACE(("got interrupt after %Lu us\n",duration));
|
|
||||||
LOG(("got interrupt after %Lu us\n",duration));
|
LOG(("got interrupt after %Lu us\n",duration));
|
||||||
} else {
|
} else {
|
||||||
TRACE(("no interrupt, timeout after %Lu us\n",duration));
|
|
||||||
LOG(("no interrupt, timeout after %Lu us\n",duration));
|
LOG(("no interrupt, timeout after %Lu us\n",duration));
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
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) {
|
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));
|
LOG(("mapping of mmbar io failed, error = %#x\n",config->area_mmbar));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
LOG(("mapping of mmbar: area %#x, phys %#x, log %#x\n", config->area_mmbar, config->mmbar, config->log_mmbar));
|
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);
|
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) {
|
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));
|
LOG(("mapping of mbbar io failed, error = %#x\n",config->area_mbbar));
|
||||||
delete_area(config->area_mmbar);
|
delete_area(config->area_mmbar);
|
||||||
config->area_mmbar = -1;
|
config->area_mmbar = -1;
|
||||||
@ -304,57 +300,77 @@ int32 int_thread(void *data)
|
|||||||
status_t
|
status_t
|
||||||
init_hardware(void)
|
init_hardware(void)
|
||||||
{
|
{
|
||||||
|
LOG_CREATE();
|
||||||
if (B_OK == probe_device()) {
|
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;
|
return B_OK;
|
||||||
|
} else {
|
||||||
|
LOG(("hardware not found\n"));
|
||||||
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
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
|
status_t
|
||||||
init_driver(void)
|
init_driver(void)
|
||||||
{
|
{
|
||||||
status_t rv;
|
status_t rv;
|
||||||
bigtime_t start;
|
bigtime_t start;
|
||||||
|
|
||||||
TRACE(("init_driver\n"));
|
|
||||||
LOG_CREATE();
|
LOG_CREATE();
|
||||||
|
|
||||||
|
LOG(("init_driver\n"));
|
||||||
|
|
||||||
ASSERT(sizeof(ich_bd) == 8);
|
ASSERT(sizeof(ich_bd) == 8);
|
||||||
|
|
||||||
rv = probe_device();
|
rv = probe_device();
|
||||||
if (rv != B_OK) {
|
if (rv != B_OK) {
|
||||||
LOG(("No supported audio hardware found.\n"));
|
LOG(("No supported audio hardware found.\n"));
|
||||||
TRACE(("hardware not found\n"));
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintf("ich-ac97: " VERSION "\n");
|
PRINT((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);
|
PRINT(("found %s\n", config->name));
|
||||||
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(("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 */
|
/* before doing anything else, map the IO memory */
|
||||||
rv = map_io_memory();
|
rv = map_io_memory();
|
||||||
if (rv != B_OK) {
|
if (rv != B_OK) {
|
||||||
dprintf("ich-ac97: mapping of memory IO space failed\n");
|
PRINT(("mapping of memory IO space failed\n"));
|
||||||
LOG(("mapping of memory IO space failed\n"));
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE(("GLOB_CNT = %#08x\n",ich_reg_read_32(ICH_REG_GLOB_CNT)));
|
dump_hardware_regs();
|
||||||
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)));
|
|
||||||
|
|
||||||
/* do a cold reset */
|
/* do a cold reset */
|
||||||
TRACE(("cold reset\n"));
|
LOG(("cold reset\n"));
|
||||||
ich_reg_write_32(ICH_REG_GLOB_CNT, 0);
|
ich_reg_write_32(ICH_REG_GLOB_CNT, 0);
|
||||||
snooze(50000); // 50 ms
|
snooze(50000); // 50 ms
|
||||||
ich_reg_write_32(ICH_REG_GLOB_CNT, CNT_COLD | CNT_PRIE);
|
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);
|
rv = ich_reg_read_32(ICH_REG_GLOB_CNT);
|
||||||
if ((rv & CNT_COLD) == 0) {
|
if ((rv & CNT_COLD) == 0) {
|
||||||
TRACE(("cold reset failed\n"));
|
|
||||||
LOG(("cold reset failed\n"));
|
LOG(("cold reset failed\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,10 +383,8 @@ init_driver(void)
|
|||||||
snooze(50000);
|
snooze(50000);
|
||||||
}
|
}
|
||||||
if ((rv & STA_PCR)) {
|
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)));
|
LOG(("primary codec ready after %Ld us\n",(system_time() - start)));
|
||||||
} else {
|
} 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)));
|
LOG(("primary codec not ready after %Ld us\n",(system_time() - start)));
|
||||||
}
|
}
|
||||||
while ((system_time() - start) < 1000000) {
|
while ((system_time() - start) < 1000000) {
|
||||||
@ -380,31 +394,48 @@ init_driver(void)
|
|||||||
snooze(50000);
|
snooze(50000);
|
||||||
}
|
}
|
||||||
if ((rv & STA_SCR)) {
|
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)));
|
LOG(("secondary codec ready after %Ld us\n",(system_time() - start)));
|
||||||
} else {
|
} 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)));
|
LOG(("secondary codec not ready after %Ld us\n",(system_time() - start)));
|
||||||
}
|
}
|
||||||
if ((rv & (STA_PCR | STA_SCR)) == 0) {
|
while ((system_time() - start) < 1000000) {
|
||||||
dprintf("ich-ac97: compatible chipset found, but no codec ready!\n");
|
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();
|
unmap_io_memory();
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
if ((rv & STA_PCR) == 0 && (rv & STA_SCR) != 0) {
|
if ((rv & STA_PCR) == 0 && (rv & STA_S2CR) != 0) {
|
||||||
TRACE(("using secondary codec!\n"));
|
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"));
|
LOG(("using secondary codec!\n"));
|
||||||
config->nambar += 0x80;
|
config->nambar += 0x80;
|
||||||
|
config->log_mmbar += 0x80; /* ICH 4 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dump_hardware_regs();
|
||||||
|
|
||||||
/* allocate memory for channel info struct */
|
/* allocate memory for channel info struct */
|
||||||
chan_pi = (ich_chan *) malloc(sizeof(ich_chan));
|
chan_pi = (ich_chan *) malloc(sizeof(ich_chan));
|
||||||
chan_po = (ich_chan *) malloc(sizeof(ich_chan));
|
chan_po = (ich_chan *) malloc(sizeof(ich_chan));
|
||||||
chan_mc = (ich_chan *) malloc(sizeof(ich_chan));
|
chan_mc = (ich_chan *) malloc(sizeof(ich_chan));
|
||||||
|
|
||||||
if (0 == chan_pi || 0 == chan_po || 0 == chan_mc) {
|
if (0 == chan_pi || 0 == chan_po || 0 == chan_mc) {
|
||||||
dprintf("ich-ac97: couldn't allocate memory for channel descriptors!\n");
|
PRINT(("couldn't allocate memory for channel descriptors!\n"));
|
||||||
LOG(("couldn't allocate memory for channel descriptors!\n"));
|
|
||||||
chan_free_resources();
|
chan_free_resources();
|
||||||
unmap_io_memory();
|
unmap_io_memory();
|
||||||
return B_ERROR;
|
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 ||
|
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_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) {
|
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");
|
PRINT(("couldn't allocate memory for DMA buffers!\n"));
|
||||||
LOG(("ich-ac97: couldn't allocate memory for DMA buffers!\n"));
|
|
||||||
chan_free_resources();
|
chan_free_resources();
|
||||||
unmap_io_memory();
|
unmap_io_memory();
|
||||||
return B_ERROR;
|
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 */
|
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) {
|
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");
|
PRINT(("couldn't create semaphores!\n"));
|
||||||
LOG(("ich-ac97: couldn't create semaphores!\n"));
|
|
||||||
chan_free_resources();
|
chan_free_resources();
|
||||||
unmap_io_memory();
|
unmap_io_memory();
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@ -452,7 +481,7 @@ init_driver(void)
|
|||||||
chan_mc->regbase = ICH_REG_MC_BASE;
|
chan_mc->regbase = ICH_REG_MC_BASE;
|
||||||
|
|
||||||
/* reset the (primary?) codec */
|
/* reset the (primary?) codec */
|
||||||
TRACE(("codec reset\n"));
|
LOG(("codec reset\n"));
|
||||||
ich_codec_write(0x00, 0x0000);
|
ich_codec_write(0x00, 0x0000);
|
||||||
snooze(50000); // 50 ms
|
snooze(50000); // 50 ms
|
||||||
|
|
||||||
@ -475,7 +504,6 @@ init_driver(void)
|
|||||||
|
|
||||||
/* first test if interrupts are working, on some Laptops they don't work :-( */
|
/* first test if interrupts are working, on some Laptops they don't work :-( */
|
||||||
if (config->irq != 0 && false == interrupt_test()) {
|
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"));
|
LOG(("interrupt not working, using a kernel thread for polling\n"));
|
||||||
config->irq = 0; /* don't use interrupts */
|
config->irq = 0; /* don't use interrupts */
|
||||||
}
|
}
|
||||||
@ -509,19 +537,16 @@ init_driver(void)
|
|||||||
/* ich_codec_write(0x1E, 0x0000); */
|
/* ich_codec_write(0x1E, 0x0000); */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TRACE(("init_driver finished!\n"));
|
LOG(("init_driver finished!\n"));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uninit_driver(void)
|
uninit_driver(void)
|
||||||
{
|
{
|
||||||
TRACE(("uninit_driver()\n"));
|
LOG(("uninit_driver()\n"));
|
||||||
|
|
||||||
#if DEBUG
|
#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_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_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));
|
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 */
|
/* the very last thing to do is unmap the io memory */
|
||||||
unmap_io_memory();
|
unmap_io_memory();
|
||||||
|
|
||||||
TRACE(("uninit_driver() finished\n"));
|
LOG(("uninit_driver() finished\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 ich_test_int(void *check)
|
int32 ich_test_int(void *check)
|
||||||
@ -681,14 +706,14 @@ int32 ich_int(void *unused)
|
|||||||
static status_t
|
static status_t
|
||||||
ich_open(const char *name, uint32 flags, void** cookie)
|
ich_open(const char *name, uint32 flags, void** cookie)
|
||||||
{
|
{
|
||||||
TRACE(("open()\n"));
|
LOG(("open()\n"));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
ich_close(void* cookie)
|
ich_close(void* cookie)
|
||||||
{
|
{
|
||||||
TRACE(("close()\n"));
|
LOG(("close()\n"));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#include "hardware.h"
|
#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 DRIVER_NAME "ich_ac97"
|
||||||
|
|
||||||
#define BUFFER_SIZE 2048
|
#define BUFFER_SIZE 2048
|
||||||
|
@ -133,7 +133,7 @@ ich_codec_read(int regno)
|
|||||||
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255);
|
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255);
|
||||||
rv = ich_codec_wait();
|
rv = ich_codec_wait();
|
||||||
if (rv != B_OK)
|
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)
|
if (config->type & TYPE_ICH4)
|
||||||
return *(uint16 *)(((char *)config->log_mmbar) + regno);
|
return *(uint16 *)(((char *)config->log_mmbar) + regno);
|
||||||
else
|
else
|
||||||
@ -148,7 +148,7 @@ ich_codec_write(int regno, uint16 value)
|
|||||||
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255);
|
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255);
|
||||||
rv = ich_codec_wait();
|
rv = ich_codec_wait();
|
||||||
if (rv != B_OK)
|
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)
|
if (config->type & TYPE_ICH4)
|
||||||
*(uint16 *)(((char *)config->log_mmbar) + regno) = value;
|
*(uint16 *)(((char *)config->log_mmbar) + regno) = value;
|
||||||
else
|
else
|
||||||
|
@ -63,18 +63,18 @@ area_id alloc_mem(void **phy, void **log, size_t size, const char *name)
|
|||||||
area_id areaid;
|
area_id areaid;
|
||||||
status_t rv;
|
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);
|
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);
|
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) {
|
if (areaid < B_OK) {
|
||||||
TRACE(("couldn't allocate area %s\n",name));
|
PRINT(("couldn't allocate area %s\n",name));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
rv = get_memory_map(logadr,size,&pe,1);
|
rv = get_memory_map(logadr,size,&pe,1);
|
||||||
if (rv < B_OK) {
|
if (rv < B_OK) {
|
||||||
delete_area(areaid);
|
delete_area(areaid);
|
||||||
TRACE(("couldn't map %s\n",name));
|
PRINT(("couldn't map %s\n",name));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
memset(logadr,0,size);
|
memset(logadr,0,size);
|
||||||
@ -82,7 +82,7 @@ area_id alloc_mem(void **phy, void **log, size_t size, const char *name)
|
|||||||
*log = logadr;
|
*log = logadr;
|
||||||
if (phy)
|
if (phy)
|
||||||
*phy = pe.address;
|
*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;
|
return areaid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user