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
This commit is contained in:
@@ -147,7 +147,7 @@ codec_table codecs[] =
|
|||||||
{ 0x41445360, 0xffffffff, &default_ops, "Analog Devices AD1885 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 },
|
{ 0x41445361, 0xffffffff, &ad1886_ops, "Analog Devices AD1886 SoundMAX"B_UTF8_REGISTERED },
|
||||||
{ 0x41445362, 0xffffffff, &default_ops, "Analog Devices AD1887 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 },
|
{ 0x41445371, 0xffffffff, &default_ops, "Analog Devices AD1981A SoundMAX"B_UTF8_REGISTERED },
|
||||||
{ 0x41445372, 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" },
|
{ 0x414c4320, 0xfffffff0, &default_ops, "Avance Logic (Realtek) ALC100/ALC100P, RL5383/RL5522" },
|
||||||
@@ -247,7 +247,30 @@ void default_init(void)
|
|||||||
void ad1886_init(void)
|
void ad1886_init(void)
|
||||||
{
|
{
|
||||||
LOG(("ad1886_init\n"));
|
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)
|
void default_amp_enable(bool yesno)
|
||||||
|
|||||||
@@ -130,4 +130,7 @@ typedef struct {
|
|||||||
#define PCI_CFG 0x41
|
#define PCI_CFG 0x41
|
||||||
#define PCI_CFG_IOSE 0x01
|
#define PCI_CFG_IOSE 0x01
|
||||||
|
|
||||||
|
#define ICH4_MMBAR_SIZE 512
|
||||||
|
#define ICH4_MBBAR_SIZE 256
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -248,6 +248,7 @@ void chan_free_resources(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t map_io_memory(void)
|
status_t map_io_memory(void)
|
||||||
{
|
{
|
||||||
if ((config->type & TYPE_ICH4) == 0)
|
if ((config->type & TYPE_ICH4) == 0)
|
||||||
@@ -258,13 +259,14 @@ status_t map_io_memory(void)
|
|||||||
ASSERT(config->mmbar != 0);
|
ASSERT(config->mmbar != 0);
|
||||||
ASSERT(config->mbbar != 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) {
|
if (config->area_mmbar <= B_OK) {
|
||||||
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_mem(&config->log_mbbar, (void *)config->mbbar, ICH4_MBBAR_SIZE, "ich_ac97 mbbar io");
|
||||||
if (config->area_mbbar <= B_OK) {
|
if (config->area_mbbar <= B_OK) {
|
||||||
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);
|
||||||
@@ -272,6 +274,7 @@ status_t map_io_memory(void)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
LOG(("mapping of mbbar: area %#x, phys %#x, log %#x\n", config->area_mbbar, config->mbbar, config->log_mbbar));
|
LOG(("mapping of mbbar: area %#x, phys %#x, log %#x\n", config->area_mbbar, config->mbbar, config->log_mbbar));
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,17 +476,17 @@ init_driver(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* allocate memory for buffer descriptors */
|
/* 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_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_phy_base, &chan_pi->bd_log_base, ICH_BD_COUNT * sizeof(ich_bd), "ich_ac97 pi 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_phy_base, &chan_mc->bd_log_base, ICH_BD_COUNT * sizeof(ich_bd), "ich_ac97 mc 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 */
|
/* 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_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_phy_base, &chan_pi->buffer_log_base, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 pi 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_phy_base, &chan_mc->buffer_log_base, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 mc 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 */
|
/* 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_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(NULL, &chan_pi->userbuffer_base, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 pi 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(NULL, &chan_mc->userbuffer_base, BUFFER_COUNT * BUFFER_SIZE, "ich_ac97 mc 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 ||
|
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 ||
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ uint32 round_to_pagesize(uint32 size)
|
|||||||
return (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
|
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;
|
physical_entry pe;
|
||||||
void * logadr;
|
void * logadr;
|
||||||
@@ -86,3 +86,28 @@ area_id alloc_mem(void **phy, void **log, size_t size, const char *name)
|
|||||||
return areaid;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,7 +30,8 @@
|
|||||||
|
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
|
|
||||||
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);
|
cpu_status lock(void);
|
||||||
void unlock(cpu_status status);
|
void unlock(cpu_status status);
|
||||||
|
|||||||
Reference in New Issue
Block a user