From 106c88e9d2365d7b488c2bf1a45cb1f0bc0b9878 Mon Sep 17 00:00:00 2001 From: beveloper Date: Thu, 26 Sep 2002 11:20:08 +0000 Subject: [PATCH] some fixes to get it working on Gateway Profile 4 (ICH 4 chipset) also experimental code for AD1886 (doesn't work) git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1192 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/drivers/audio/ac97/ich/ac97.c | 27 +++++++++++++++++-- .../kernel/drivers/audio/ac97/ich/hardware.h | 3 +++ .../kernel/drivers/audio/ac97/ich/ich.c | 25 +++++++++-------- .../kernel/drivers/audio/ac97/ich/util.c | 27 ++++++++++++++++++- .../kernel/drivers/audio/ac97/ich/util.h | 3 ++- 5 files changed, 70 insertions(+), 15 deletions(-) diff --git a/src/add-ons/kernel/drivers/audio/ac97/ich/ac97.c b/src/add-ons/kernel/drivers/audio/ac97/ich/ac97.c index 31ce83a28d..269c813bc6 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/ich/ac97.c +++ b/src/add-ons/kernel/drivers/audio/ac97/ich/ac97.c @@ -147,7 +147,7 @@ codec_table codecs[] = { 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 }, + { 0x41445363, 0xffffffff, &ad1886_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" }, @@ -247,7 +247,30 @@ void default_init(void) void ad1886_init(void) { LOG(("ad1886_init\n")); - ich_codec_write(config->codecoffset + 0x72, 0x0010); + + LOG(("===\n")); + LOG(("codecoffset = %d\n",config->codecoffset)); + LOG(("0x26 = %#04x\n",ich_codec_read(config->codecoffset + 0x26))); + LOG(("0x2A = %#04x\n",ich_codec_read(config->codecoffset + 0x2A))); + LOG(("0x3A = %#04x\n",ich_codec_read(config->codecoffset + 0x3A))); + LOG(("0x72 = %#04x\n",ich_codec_read(config->codecoffset + 0x72))); + LOG(("0x74 = %#04x\n",ich_codec_read(config->codecoffset + 0x74))); + LOG(("0x76 = %#04x\n",ich_codec_read(config->codecoffset + 0x76))); + +// ich_codec_write(config->codecoffset + 0x72, 0x0010); // enable software jack sense +// ich_codec_write(config->codecoffset + 0x72, 0x0110); // disable hardware line muting + + ich_codec_write(config->codecoffset + 0x72, 0x0230); + + LOG(("===\n")); + LOG(("0x26 = %#04x\n",ich_codec_read(config->codecoffset + 0x26))); + LOG(("0x2A = %#04x\n",ich_codec_read(config->codecoffset + 0x2A))); + LOG(("0x3A = %#04x\n",ich_codec_read(config->codecoffset + 0x3A))); + LOG(("0x72 = %#04x\n",ich_codec_read(config->codecoffset + 0x72))); + LOG(("0x74 = %#04x\n",ich_codec_read(config->codecoffset + 0x74))); + LOG(("0x76 = %#04x\n",ich_codec_read(config->codecoffset + 0x76))); + + LOG(("===\n")); } void default_amp_enable(bool yesno) diff --git a/src/add-ons/kernel/drivers/audio/ac97/ich/hardware.h b/src/add-ons/kernel/drivers/audio/ac97/ich/hardware.h index 1f18f523cb..e4a8dbefbb 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/ich/hardware.h +++ b/src/add-ons/kernel/drivers/audio/ac97/ich/hardware.h @@ -130,4 +130,7 @@ typedef struct { #define PCI_CFG 0x41 #define PCI_CFG_IOSE 0x01 +#define ICH4_MMBAR_SIZE 512 +#define ICH4_MBBAR_SIZE 256 + #endif diff --git a/src/add-ons/kernel/drivers/audio/ac97/ich/ich.c b/src/add-ons/kernel/drivers/audio/ac97/ich/ich.c index ff59dd9663..2c47402620 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/ich/ich.c +++ b/src/add-ons/kernel/drivers/audio/ac97/ich/ich.c @@ -248,6 +248,7 @@ void chan_free_resources(void) } } + status_t map_io_memory(void) { if ((config->type & TYPE_ICH4) == 0) @@ -258,13 +259,14 @@ status_t map_io_memory(void) ASSERT(config->mmbar != 0); ASSERT(config->mbbar != 0); - 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_mem(&config->log_mmbar, (void *)config->mmbar, ICH4_MMBAR_SIZE, "ich_ac97 mmbar io"); if (config->area_mmbar <= B_OK) { 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); + + config->area_mbbar = map_mem(&config->log_mbbar, (void *)config->mbbar, ICH4_MBBAR_SIZE, "ich_ac97 mbbar io"); if (config->area_mbbar <= B_OK) { LOG(("mapping of mbbar io failed, error = %#x\n",config->area_mbbar)); delete_area(config->area_mmbar); @@ -272,6 +274,7 @@ status_t map_io_memory(void) return B_ERROR; } LOG(("mapping of mbbar: area %#x, phys %#x, log %#x\n", config->area_mbbar, config->mbbar, config->log_mbbar)); + return B_OK; } @@ -473,17 +476,17 @@ init_driver(void) } /* allocate memory for buffer descriptors */ - chan_po->bd_area = alloc_mem(&chan_po->bd_phy_base, &chan_po->bd_log_base, ICH_BD_COUNT * sizeof(ich_bd), "ich_ac97 po buf desc"); - chan_pi->bd_area = alloc_mem(&chan_pi->bd_phy_base, &chan_pi->bd_log_base, ICH_BD_COUNT * sizeof(ich_bd), "ich_ac97 pi buf desc"); - chan_mc->bd_area = alloc_mem(&chan_mc->bd_phy_base, &chan_mc->bd_log_base, ICH_BD_COUNT * sizeof(ich_bd), "ich_ac97 mc buf desc"); + chan_po->bd_area = alloc_mem(&chan_po->bd_log_base, &chan_po->bd_phy_base, ICH_BD_COUNT * sizeof(ich_bd), "ich_ac97 po buf desc"); + chan_pi->bd_area = alloc_mem(&chan_pi->bd_log_base, &chan_pi->bd_phy_base, ICH_BD_COUNT * sizeof(ich_bd), "ich_ac97 pi buf desc"); + chan_mc->bd_area = alloc_mem(&chan_mc->bd_log_base, &chan_mc->bd_phy_base, ICH_BD_COUNT * sizeof(ich_bd), "ich_ac97 mc buf desc"); /* allocate memory buffers */ - chan_po->buffer_area = alloc_mem(&chan_po->buffer_phy_base, &chan_po->buffer_log_base, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 po buf"); - chan_pi->buffer_area = alloc_mem(&chan_pi->buffer_phy_base, &chan_pi->buffer_log_base, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 pi buf"); - chan_mc->buffer_area = alloc_mem(&chan_mc->buffer_phy_base, &chan_mc->buffer_log_base, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 mc buf"); + chan_po->buffer_area = alloc_mem(&chan_po->buffer_log_base, &chan_po->buffer_phy_base, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 po buf"); + chan_pi->buffer_area = alloc_mem(&chan_pi->buffer_log_base, &chan_pi->buffer_phy_base, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 pi buf"); + chan_mc->buffer_area = alloc_mem(&chan_mc->buffer_log_base, &chan_mc->buffer_phy_base, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 mc buf"); /* allocate memory exported userland buffers */ - chan_po->userbuffer_area = alloc_mem(NULL, &chan_po->userbuffer_base, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 po user buf"); - chan_pi->userbuffer_area = alloc_mem(NULL, &chan_pi->userbuffer_base, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 pi user buf"); - chan_mc->userbuffer_area = alloc_mem(NULL, &chan_mc->userbuffer_base, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 mc user buf"); + chan_po->userbuffer_area = alloc_mem(&chan_po->userbuffer_base, NULL, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 po user buf"); + chan_pi->userbuffer_area = alloc_mem(&chan_pi->userbuffer_base, NULL, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 pi user buf"); + chan_mc->userbuffer_area = alloc_mem(&chan_mc->userbuffer_base, NULL, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 mc user buf"); 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 || diff --git a/src/add-ons/kernel/drivers/audio/ac97/ich/util.c b/src/add-ons/kernel/drivers/audio/ac97/ich/util.c index d71521def3..d70754ee3c 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/ich/util.c +++ b/src/add-ons/kernel/drivers/audio/ac97/ich/util.c @@ -56,7 +56,7 @@ 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) +area_id alloc_mem(void **log, void **phy, size_t size, const char *name) { physical_entry pe; void * logadr; @@ -86,3 +86,28 @@ area_id alloc_mem(void **phy, void **log, size_t size, const char *name) return areaid; } +/* This is not the most advanced method to map physical memory for io access. + * Perhaps using B_ANY_KERNEL_ADDRESS instead of B_ANY_KERNEL_BLOCK_ADDRESS + * makes the whole offset calculation and relocation obsolete. But the code + * below does work, and I can't test if using B_ANY_KERNEL_ADDRESS also works. + */ +area_id map_mem(void **log, void *phy, size_t size, const char *name) +{ + uint32 offset; + void *phyadr; + void *mapadr; + area_id area; + + LOG(("mapping physical address %p with %#x bytes for %s\n",phy,size,name)); + + offset = (uint32)phy & (B_PAGE_SIZE - 1); + phyadr = phy - offset; + size = round_to_pagesize(size + offset); + area = map_physical_memory(name, phyadr, size, B_ANY_KERNEL_BLOCK_ADDRESS, B_READ_AREA | B_WRITE_AREA, &mapadr); + *log = mapadr + offset; + + LOG(("physical = %p, logical = %p, offset = %#x, phyadr = %p, mapadr = %p, size = %#x, area = %#x\n", + phy, *log, offset, phyadr, mapadr, size, area)); + + return area; +} diff --git a/src/add-ons/kernel/drivers/audio/ac97/ich/util.h b/src/add-ons/kernel/drivers/audio/ac97/ich/util.h index 7a367042ca..2bc87c062f 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/ich/util.h +++ b/src/add-ons/kernel/drivers/audio/ac97/ich/util.h @@ -30,7 +30,8 @@ #include -area_id alloc_mem(void **phy, void **log, size_t size, const char *name); +area_id alloc_mem(void **log, void **phy, size_t size, const char *name); +area_id map_mem(void **log, void *phy, size_t size, const char *name); cpu_status lock(void); void unlock(cpu_status status);