cookie is no longer a parameter for attach/detach
renamed drv_t to audio_drv_t added utility functions to framework added memory io memory mapping to driver added io access to driver git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7123 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
2b75cca8d2
commit
56494946b4
@ -6,6 +6,7 @@ SubDirHdrs [ FDirName $(OBOS_TOP) src add-ons media media-add-ons lala ] ;
|
|||||||
|
|
||||||
KernelMergeObject ichaudio_driver.o :
|
KernelMergeObject ichaudio_driver.o :
|
||||||
ichaudio.c
|
ichaudio.c
|
||||||
|
io.c
|
||||||
:
|
:
|
||||||
-fno-pic -Wno-unused -D_KERNEL_MODE
|
-fno-pic -Wno-unused -D_KERNEL_MODE
|
||||||
;
|
;
|
||||||
|
@ -122,7 +122,6 @@ typedef struct {
|
|||||||
|
|
||||||
/* PCI Configuration Space */
|
/* PCI Configuration Space */
|
||||||
|
|
||||||
#define PCI_PCICMD 0x04
|
|
||||||
#define PCI_PCICMD_IOS 0x01
|
#define PCI_PCICMD_IOS 0x01
|
||||||
#define PCI_PCICMD_MSE 0x02
|
#define PCI_PCICMD_MSE 0x02
|
||||||
#define PCI_PCICMD_BME 0x04
|
#define PCI_PCICMD_BME 0x04
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#include "lala/lala.h"
|
#include "lala/lala.h"
|
||||||
#include "ichaudio.h"
|
#include "ichaudio.h"
|
||||||
|
|
||||||
status_t ichaudio_attach(drv_t *drv, void *cookie);
|
status_t ichaudio_attach(audio_drv_t *drv);
|
||||||
status_t ichaudio_powerctl(drv_t *drv, void *cookie);
|
status_t ichaudio_powerctl(audio_drv_t *drv);
|
||||||
status_t ichaudio_detach(drv_t *drv, void *cookie);
|
status_t ichaudio_detach(audio_drv_t *drv);
|
||||||
|
|
||||||
id_table_t ichaudio_id_table[] = {
|
id_table_t ichaudio_id_table[] = {
|
||||||
{ 0x8086, 0x7195, -1, -1, -1, -1, -1, "Intel 82443MX AC97 audio" },
|
{ 0x8086, 0x7195, -1, -1, -1, -1, -1, "Intel 82443MX AC97 audio" },
|
||||||
@ -38,31 +38,78 @@ driver_info_t driver_info = {
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
ichaudio_attach(drv_t *drv, void *_cookie)
|
ichaudio_attach(audio_drv_t *drv)
|
||||||
{
|
{
|
||||||
ichaudio_cookie *cookie = (ichaudio_cookie *)_cookie;
|
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||||
|
uint32 value;
|
||||||
|
|
||||||
dprintf("ichaudio_attach\n");
|
dprintf("ichaudio_attach\n");
|
||||||
|
|
||||||
|
// For old ICHs enable programmed IO and busmaster access,
|
||||||
|
// for ICH4 and up enable memory mapped IO and busmaster access
|
||||||
|
value = drv->pci->read_pci_config(drv->bus, drv->device, drv->function, PCI_command, 2);
|
||||||
|
value |= PCI_PCICMD_BME | (drv->flags & TYPE_ICH4) ? PCI_PCICMD_MSE : PCI_PCICMD_IOS;
|
||||||
|
drv->pci->write_pci_config(drv->bus, drv->device, drv->function, PCI_command, 2, value);
|
||||||
|
|
||||||
|
// get IRQ, we can compensate it later if IRQ is not available (hack!)
|
||||||
|
cookie->irq = drv->pci->read_pci_config(drv->bus, drv->device, drv->function, PCI_interrupt_line, 1);
|
||||||
|
if (cookie->irq == 0xff) cookie->irq = 0;
|
||||||
|
if (cookie->irq == 0) dprintf("ichaudio_attach: no interrupt configured\n");
|
||||||
|
|
||||||
|
if (drv->flags & TYPE_ICH4) {
|
||||||
|
// memory mapped access
|
||||||
|
uint32 phy_mmbar = PCI_address_memory_32_mask & drv->pci->read_pci_config(drv->bus, drv->device, drv->function, 0x18, 4);
|
||||||
|
uint32 phy_mbbar = PCI_address_memory_32_mask & drv->pci->read_pci_config(drv->bus, drv->device, drv->function, 0x1C, 4);
|
||||||
|
if (!phy_mmbar || !phy_mbbar) {
|
||||||
|
dprintf("ichaudio_attach: memory mapped io unconfigured\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
// map into memory
|
||||||
|
cookie->area_mmbar = map_mem(&cookie->mmbar, (void *)phy_mmbar, ICH4_MMBAR_SIZE, 0, "ichaudio mmbar io");
|
||||||
|
cookie->area_mbbar = map_mem(&cookie->mbbar, (void *)phy_mbbar, ICH4_MBBAR_SIZE, 0, "ichaudio mbbar io");
|
||||||
|
if (cookie->area_mmbar < B_OK || cookie->area_mbbar < B_OK) {
|
||||||
|
dprintf("ichaudio_attach: mapping io into memory failed\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// pio access
|
||||||
|
cookie->nambar = PCI_address_io_mask & drv->pci->read_pci_config(drv->bus, drv->device, drv->function, 0x10, 4);
|
||||||
|
cookie->nabmbar = PCI_address_io_mask & drv->pci->read_pci_config(drv->bus, drv->device, drv->function, 0x14, 4);
|
||||||
|
if (!cookie->nambar || !cookie->nabmbar) {
|
||||||
|
dprintf("ichaudio_attach: io unconfiugured\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
|
err:
|
||||||
|
// unmap io memory
|
||||||
|
if (cookie->area_mmbar > 0) delete_area(cookie->area_mmbar);
|
||||||
|
if (cookie->area_mbbar > 0) delete_area(cookie->area_mbbar);
|
||||||
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
ichaudio_detach(drv_t *drv, void *_cookie)
|
ichaudio_detach(audio_drv_t *drv)
|
||||||
{
|
{
|
||||||
ichaudio_cookie *cookie = (ichaudio_cookie *)_cookie;
|
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||||
|
|
||||||
dprintf("ichaudio_detach\n");
|
dprintf("ichaudio_detach\n");
|
||||||
|
|
||||||
|
// unmap io memory
|
||||||
|
if (cookie->area_mmbar > 0) delete_area(cookie->area_mmbar);
|
||||||
|
if (cookie->area_mbbar > 0) delete_area(cookie->area_mbbar);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
ichaudio_powerctl(drv_t *drv, void *_cookie)
|
ichaudio_powerctl(audio_drv_t *drv)
|
||||||
{
|
{
|
||||||
ichaudio_cookie *cookie = (ichaudio_cookie *)_cookie;
|
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,23 @@
|
|||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
|
#include "hardware.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
const char *name;
|
uint32 irq;
|
||||||
uint32 nambar;
|
uint32 nambar;
|
||||||
uint32 nabmbar;
|
uint32 nabmbar;
|
||||||
uint32 irq;
|
|
||||||
uint32 type;
|
|
||||||
uint32 mmbar; // ich4
|
|
||||||
uint32 mbbar; // ich4
|
|
||||||
void * log_mmbar; // ich4
|
|
||||||
void * log_mbbar; // ich4
|
|
||||||
area_id area_mmbar; // ich4
|
area_id area_mmbar; // ich4
|
||||||
area_id area_mbbar; // ich4
|
area_id area_mbbar; // ich4
|
||||||
|
void * mmbar; // ich4
|
||||||
|
void * mbbar; // ich4
|
||||||
|
|
||||||
uint32 codecoffset;
|
uint32 codecoffset;
|
||||||
uint32 input_rate;
|
uint32 input_rate;
|
||||||
uint32 output_rate;
|
uint32 output_rate;
|
||||||
|
|
||||||
pci_module_info *pci;
|
|
||||||
|
|
||||||
} ichaudio_cookie;
|
} ichaudio_cookie;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define TYPE_ICH4 0x01
|
#define TYPE_ICH4 0x01
|
||||||
#define TYPE_SIS7012 0x02
|
#define TYPE_SIS7012 0x02
|
||||||
|
|
||||||
|
168
src/add-ons/kernel/drivers/audio/ac97/ichaudio/io.c
Normal file
168
src/add-ons/kernel/drivers/audio/ac97/ichaudio/io.c
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
* BeOS Driver for Intel ICH AC'97 Link interface
|
||||||
|
*
|
||||||
|
* Copyright (C) 2002-2004, Marcus Overhagen <marcus@overhagen.de>
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <KernelExport.h>
|
||||||
|
#include <OS.h>
|
||||||
|
#include "debug.h"
|
||||||
|
#include "hardware.h"
|
||||||
|
#include "ichaudio.h"
|
||||||
|
#include "io.h"
|
||||||
|
|
||||||
|
status_t ich_codec_wait(audio_drv_t *drv);
|
||||||
|
|
||||||
|
uint8
|
||||||
|
ich_reg_read_8(audio_drv_t *drv, int regno)
|
||||||
|
{
|
||||||
|
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||||
|
|
||||||
|
ASSERT(regno >= 0);
|
||||||
|
ASSERT(((drv->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||||
|
if (drv->flags & TYPE_ICH4)
|
||||||
|
return *(uint8 *)((char *)cookie->mbbar + regno);
|
||||||
|
else
|
||||||
|
return drv->pci->read_io_8(cookie->nabmbar + regno);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16
|
||||||
|
ich_reg_read_16(audio_drv_t *drv, int regno)
|
||||||
|
{
|
||||||
|
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||||
|
|
||||||
|
ASSERT(regno >= 0);
|
||||||
|
ASSERT(((drv->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||||
|
if (drv->flags & TYPE_ICH4)
|
||||||
|
return *(uint16 *)((char *)cookie->mbbar + regno);
|
||||||
|
else
|
||||||
|
return drv->pci->read_io_16(cookie->nabmbar + regno);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
ich_reg_read_32(audio_drv_t *drv, int regno)
|
||||||
|
{
|
||||||
|
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||||
|
|
||||||
|
ASSERT(regno >= 0);
|
||||||
|
ASSERT(((drv->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||||
|
|
||||||
|
if (drv->flags & TYPE_ICH4)
|
||||||
|
return *(uint32 *)((char *)cookie->mbbar + regno);
|
||||||
|
else
|
||||||
|
return drv->pci->read_io_32(cookie->nabmbar + regno);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ich_reg_write_8(audio_drv_t *drv, int regno, uint8 value)
|
||||||
|
{
|
||||||
|
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||||
|
|
||||||
|
ASSERT(regno >= 0);
|
||||||
|
ASSERT(((drv->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||||
|
|
||||||
|
if (drv->flags & TYPE_ICH4)
|
||||||
|
*(uint8 *)((char *)cookie->mbbar + regno) = value;
|
||||||
|
else
|
||||||
|
drv->pci->write_io_8(cookie->nabmbar + regno, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ich_reg_write_16(audio_drv_t *drv, int regno, uint16 value)
|
||||||
|
{
|
||||||
|
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||||
|
|
||||||
|
ASSERT(regno >= 0);
|
||||||
|
ASSERT(((drv->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||||
|
|
||||||
|
if (drv->flags & TYPE_ICH4)
|
||||||
|
*(uint16 *)((char *)cookie->mbbar + regno) = value;
|
||||||
|
else
|
||||||
|
drv->pci->write_io_16(cookie->nabmbar + regno, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ich_reg_write_32(audio_drv_t *drv, int regno, uint32 value)
|
||||||
|
{
|
||||||
|
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||||
|
|
||||||
|
ASSERT(regno >= 0);
|
||||||
|
ASSERT(((drv->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||||
|
|
||||||
|
if (drv->flags & TYPE_ICH4)
|
||||||
|
*(uint32 *)((char *)cookie->mbbar + regno) = value;
|
||||||
|
else
|
||||||
|
drv->pci->write_io_32(cookie->nabmbar + regno, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ich_codec_wait(audio_drv_t *drv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 1100; i++) {
|
||||||
|
if ((ich_reg_read_8(drv, ICH_REG_ACC_SEMA) & 0x01) == 0)
|
||||||
|
return B_OK;
|
||||||
|
if (i > 100)
|
||||||
|
snooze(1);
|
||||||
|
}
|
||||||
|
return B_TIMED_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16
|
||||||
|
ich_codec_read(audio_drv_t *drv, int regno)
|
||||||
|
{
|
||||||
|
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||||
|
|
||||||
|
ASSERT(regno >= 0);
|
||||||
|
ASSERT((regno & 1) == 0);
|
||||||
|
ASSERT(((drv->flags & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255);
|
||||||
|
|
||||||
|
if (regno == 0x54) // intel uses 0x54 for GPIO access, we filter it!
|
||||||
|
return 0;
|
||||||
|
if (B_OK != ich_codec_wait(drv))
|
||||||
|
PRINT(("semaphore timeout reading register %#x\n", regno));
|
||||||
|
if (drv->flags & TYPE_ICH4)
|
||||||
|
return *(uint16 *)(((char *)cookie->mmbar) + regno);
|
||||||
|
else
|
||||||
|
return drv->pci->read_io_16(cookie->nambar + regno);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ich_codec_write(audio_drv_t *drv, int regno, uint16 value)
|
||||||
|
{
|
||||||
|
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||||
|
|
||||||
|
ASSERT(regno >= 0);
|
||||||
|
ASSERT((regno & 1) == 0);
|
||||||
|
ASSERT(((drv->flags & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255);
|
||||||
|
|
||||||
|
if (regno == 0x54) // intel uses 0x54 for GPIO access, we filter it!
|
||||||
|
return;
|
||||||
|
if (B_OK != ich_codec_wait(drv))
|
||||||
|
PRINT(("semaphore timeout writing register %#x\n", regno));
|
||||||
|
if (drv->flags & TYPE_ICH4)
|
||||||
|
*(uint16 *)(((char *)cookie->mmbar) + regno) = value;
|
||||||
|
else
|
||||||
|
drv->pci->write_io_16(cookie->nambar + regno, value);
|
||||||
|
}
|
44
src/add-ons/kernel/drivers/audio/ac97/ichaudio/io.h
Normal file
44
src/add-ons/kernel/drivers/audio/ac97/ichaudio/io.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* BeOS Driver for Intel ICH AC'97 Link interface
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef _IO_H_
|
||||||
|
#define _IO_H_
|
||||||
|
|
||||||
|
#include "lala/lala.h"
|
||||||
|
|
||||||
|
uint8 ich_reg_read_8(audio_drv_t *drv, int regno);
|
||||||
|
uint16 ich_reg_read_16(audio_drv_t *drv, int regno);
|
||||||
|
uint32 ich_reg_read_32(audio_drv_t *drv, int regno);
|
||||||
|
|
||||||
|
void ich_reg_write_8(audio_drv_t *drv, int regno, uint8 value);
|
||||||
|
void ich_reg_write_16(audio_drv_t *drv, int regno, uint16 value);
|
||||||
|
void ich_reg_write_32(audio_drv_t *drv, int regno, uint32 value);
|
||||||
|
|
||||||
|
uint16 ich_codec_read(audio_drv_t *drv, int regno);
|
||||||
|
void ich_codec_write(audio_drv_t *drv, int regno, uint16 value);
|
||||||
|
|
||||||
|
#endif
|
@ -6,6 +6,7 @@ SubDir OBOS_TOP src add-ons kernel drivers audio ac97 ichaudio lala ;
|
|||||||
|
|
||||||
KernelMergeObject lala.o :
|
KernelMergeObject lala.o :
|
||||||
driver.c
|
driver.c
|
||||||
|
util.c
|
||||||
:
|
:
|
||||||
-fno-pic -D_KERNEL_MODE
|
-fno-pic -D_KERNEL_MODE
|
||||||
;
|
;
|
||||||
|
@ -9,13 +9,13 @@
|
|||||||
|
|
||||||
#include "lala.h"
|
#include "lala.h"
|
||||||
|
|
||||||
int32 api_version = B_CUR_DRIVER_API_VERSION;
|
|
||||||
|
|
||||||
#define MAX_DEVICES 8
|
#define MAX_DEVICES 8
|
||||||
|
|
||||||
|
int32 api_version = B_CUR_DRIVER_API_VERSION;
|
||||||
|
|
||||||
sem_id drv_sem;
|
sem_id drv_sem;
|
||||||
char * drv_path[MAX_DEVICES + 1];
|
char * drv_path[MAX_DEVICES + 1];
|
||||||
drv_t * drv_data[MAX_DEVICES];
|
audio_drv_t * drv_data[MAX_DEVICES];
|
||||||
int drv_count;
|
int drv_count;
|
||||||
|
|
||||||
pci_module_info *pcimodule;
|
pci_module_info *pcimodule;
|
||||||
@ -76,7 +76,7 @@ init_driver(void)
|
|||||||
drv_path[drv_count] = (char *) malloc(strlen(driver_info.basename) + 5);
|
drv_path[drv_count] = (char *) malloc(strlen(driver_info.basename) + 5);
|
||||||
sprintf(drv_path[drv_count], "%s/%d", driver_info.basename, drv_count + 1);
|
sprintf(drv_path[drv_count], "%s/%d", driver_info.basename, drv_count + 1);
|
||||||
|
|
||||||
drv_data[drv_count] = (drv_t *) malloc(sizeof(drv_t));
|
drv_data[drv_count] = (audio_drv_t *) malloc(sizeof(audio_drv_t));
|
||||||
drv_data[drv_count]->pci = pcimodule;
|
drv_data[drv_count]->pci = pcimodule;
|
||||||
drv_data[drv_count]->bus = pciinfo->bus;
|
drv_data[drv_count]->bus = pciinfo->bus;
|
||||||
drv_data[drv_count]->device = pciinfo->device;
|
drv_data[drv_count]->device = pciinfo->device;
|
||||||
@ -132,7 +132,7 @@ ich_open(const char *name, uint32 flags, void** cookie)
|
|||||||
|
|
||||||
if (drv_data[index]->open_count == 0) {
|
if (drv_data[index]->open_count == 0) {
|
||||||
memset(drv_data[index]->cookie, 0, driver_info.cookie_size);
|
memset(drv_data[index]->cookie, 0, driver_info.cookie_size);
|
||||||
res = driver_info.attach(drv_data[index], drv_data[index]->cookie);
|
res = driver_info.attach(drv_data[index]);
|
||||||
drv_data[index]->open_count = (res == B_OK) ? 1 : 0;
|
drv_data[index]->open_count = (res == B_OK) ? 1 : 0;
|
||||||
} else {
|
} else {
|
||||||
res = B_OK;
|
res = B_OK;
|
||||||
@ -166,7 +166,7 @@ ich_free(void* cookie)
|
|||||||
drv_data[index]->open_count--;
|
drv_data[index]->open_count--;
|
||||||
|
|
||||||
if (drv_data[index]->open_count == 0)
|
if (drv_data[index]->open_count == 0)
|
||||||
res = driver_info.detach(drv_data[index], drv_data[index]->cookie);
|
res = driver_info.detach(drv_data[index]);
|
||||||
else
|
else
|
||||||
res = B_OK;
|
res = B_OK;
|
||||||
|
|
||||||
|
@ -15,10 +15,11 @@ typedef struct
|
|||||||
const char * name;
|
const char * name;
|
||||||
uint32 flags;
|
uint32 flags;
|
||||||
|
|
||||||
|
void * cookie;
|
||||||
|
|
||||||
// private:
|
// private:
|
||||||
int32 open_count;
|
int32 open_count;
|
||||||
void * cookie;
|
} audio_drv_t;
|
||||||
} drv_t;
|
|
||||||
|
|
||||||
typedef void stream_id;
|
typedef void stream_id;
|
||||||
typedef void control_id;
|
typedef void control_id;
|
||||||
@ -35,9 +36,9 @@ typedef struct {
|
|||||||
uint32 flags;
|
uint32 flags;
|
||||||
} id_table_t;
|
} id_table_t;
|
||||||
|
|
||||||
typedef status_t (*drv_attach) (drv_t *drv, void *cookie);
|
typedef status_t (*drv_attach) (audio_drv_t *drv);
|
||||||
typedef status_t (*drv_powerctl) (drv_t *drv, void *cookie);
|
typedef status_t (*drv_powerctl) (audio_drv_t *drv);
|
||||||
typedef status_t (*drv_detach) (drv_t *drv, void *cookie);
|
typedef status_t (*drv_detach) (audio_drv_t *drv);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -55,10 +56,17 @@ typedef struct
|
|||||||
|
|
||||||
extern driver_info_t driver_info;
|
extern driver_info_t driver_info;
|
||||||
|
|
||||||
stream_id create_stream(drv_t *dev, stream_info_t *info);
|
// protection is 0 for kernel only access, or B_READ_AREA, B_WRITE_AREA for user space access
|
||||||
status_t control_stream(drv_t *dev, stream_info_t *info);
|
area_id alloc_mem(void **virt, void **phy, size_t size, uint32 protection, const char *name);
|
||||||
|
area_id map_mem(void **virt, void *phy, size_t size, uint32 protection, const char *name);
|
||||||
|
|
||||||
|
stream_id create_stream(audio_drv_t *dev, stream_info_t *info);
|
||||||
|
status_t control_stream(audio_drv_t *dev, stream_info_t *info);
|
||||||
status_t delete_stream(stream_id stream);
|
status_t delete_stream(stream_id stream);
|
||||||
|
|
||||||
control_id create_control_group(control_id parent, dev_t *dev);
|
control_id create_control_group(control_id parent, audio_drv_t *dev);
|
||||||
control_id create_control(control_id parent, uint32 flags, void *get, void *set, const char *name);
|
control_id create_control(control_id parent, uint32 flags, void *get, void *set, const char *name);
|
||||||
|
|
||||||
|
|
||||||
|
#define LOG(a) dprintf a
|
||||||
|
#define PRINT(a) dprintf a
|
||||||
|
99
src/add-ons/kernel/drivers/audio/ac97/ichaudio/lala/util.c
Normal file
99
src/add-ons/kernel/drivers/audio/ac97/ichaudio/lala/util.c
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* BeOS Driver for Intel ICH AC'97 Link interface
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <Errors.h>
|
||||||
|
#include <OS.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
//#define DEBUG 2
|
||||||
|
|
||||||
|
#include "lala.h"
|
||||||
|
|
||||||
|
uint32 round_to_pagesize(uint32 size);
|
||||||
|
|
||||||
|
uint32 round_to_pagesize(uint32 size)
|
||||||
|
{
|
||||||
|
return (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
area_id
|
||||||
|
alloc_mem(void **virt, void **phy, size_t size, uint32 protection, const char *name)
|
||||||
|
{
|
||||||
|
physical_entry pe;
|
||||||
|
void * virtadr;
|
||||||
|
area_id areaid;
|
||||||
|
status_t rv;
|
||||||
|
|
||||||
|
LOG(("allocating %ld bytes for %s\n", size, name));
|
||||||
|
|
||||||
|
size = round_to_pagesize(size);
|
||||||
|
areaid = create_area(name, &virtadr, B_ANY_KERNEL_ADDRESS, size, B_FULL_LOCK | B_CONTIGUOUS, protection);
|
||||||
|
if (areaid < B_OK) {
|
||||||
|
PRINT(("couldn't allocate area %s\n",name));
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
rv = get_memory_map(virtadr, size, &pe, 1);
|
||||||
|
if (rv < B_OK) {
|
||||||
|
delete_area(areaid);
|
||||||
|
PRINT(("couldn't map %s\n",name));
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
memset(virtadr, 0, size);
|
||||||
|
if (virt)
|
||||||
|
*virt = virtadr;
|
||||||
|
if (phy)
|
||||||
|
*phy = pe.address;
|
||||||
|
LOG(("area = %ld, size = %ld, virt = %p, phy = %p\n", areaid, size, virtadr, pe.address));
|
||||||
|
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 **virt, void *phy, size_t size, uint32 protection, const char *name)
|
||||||
|
{
|
||||||
|
uint32 offset;
|
||||||
|
void *phyadr;
|
||||||
|
void *mapadr;
|
||||||
|
area_id area;
|
||||||
|
|
||||||
|
LOG(("mapping physical address %p with %ld bytes for %s\n", phy, size, name));
|
||||||
|
|
||||||
|
offset = (uint32)phy & (B_PAGE_SIZE - 1);
|
||||||
|
phyadr = (char *)phy - offset;
|
||||||
|
size = round_to_pagesize(size + offset);
|
||||||
|
area = map_physical_memory(name, phyadr, size, B_ANY_KERNEL_BLOCK_ADDRESS, protection, &mapadr);
|
||||||
|
*virt = (char *)mapadr + offset;
|
||||||
|
|
||||||
|
LOG(("physical = %p, virtual = %p, offset = %ld, phyadr = %p, mapadr = %p, size = %ld, area = 0x%08lx\n",
|
||||||
|
phy, *virt, offset, phyadr, mapadr, size, area));
|
||||||
|
|
||||||
|
return area;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user