another attempt, but still broken
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7141 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -2,9 +2,15 @@
|
||||
#include "ichaudio.h"
|
||||
#include "io.h"
|
||||
|
||||
status_t ichaudio_attach(audio_drv_t *drv);
|
||||
status_t ichaudio_powerctl(audio_drv_t *drv);
|
||||
status_t ichaudio_detach(audio_drv_t *drv);
|
||||
status_t ichaudio_attach(audio_drv_t *drv, void **cookie);
|
||||
status_t ichaudio_powerctl(audio_drv_t *drv, void *cookie);
|
||||
status_t ichaudio_detach(audio_drv_t *drv, void *cookie);
|
||||
status_t ichaudio_stream_attach(audio_drv_t *drv, void **cookie, void *param);
|
||||
status_t ichaudio_stream_detach(audio_drv_t *drv, void *cookie);
|
||||
status_t ichaudio_stream_control(audio_drv_t *drv, void *cookie, int op);
|
||||
status_t ichaudio_stream_set_buffers(audio_drv_t *drv, void *cookie, uint32 *buffer_size, stream_buffer_desc_t *desc);
|
||||
status_t ichaudio_stream_set_frame_rate(audio_drv_t *drv, void *cookie, uint32 *frame_rate);
|
||||
|
||||
|
||||
id_table_t ichaudio_id_table[] = {
|
||||
{ 0x8086, 0x7195, -1, -1, -1, -1, -1, "Intel 82443MX AC97 audio" },
|
||||
@@ -12,9 +18,9 @@ id_table_t ichaudio_id_table[] = {
|
||||
{ 0x8086, 0x2425, -1, -1, -1, -1, -1, "Intel 82801AB (ICH0) AC97 audio" },
|
||||
{ 0x8086, 0x2445, -1, -1, -1, -1, -1, "Intel 82801BA (ICH2) AC97 audio" },
|
||||
{ 0x8086, 0x2485, -1, -1, -1, -1, -1, "Intel 82801CA (ICH3) AC97 audio" },
|
||||
{ 0x8086, 0x24C5, -1, -1, -1, -1, -1, "Intel 82801DB (ICH4) AC97 audio", TYPE_ICH4 },
|
||||
{ 0x8086, 0x24D5, -1, -1, -1, -1, -1, "Intel 82801EB (ICH5) AC97 audio", TYPE_ICH4 },
|
||||
{ 0x1039, 0x7012, -1, -1, -1, -1, -1, "SiS SI7012 AC97 audio", TYPE_SIS7012 },
|
||||
{ 0x8086, 0x24C5, -1, -1, -1, -1, -1, "Intel 82801DB (ICH4) AC97 audio", (void *)TYPE_ICH4 },
|
||||
{ 0x8086, 0x24D5, -1, -1, -1, -1, -1, "Intel 82801EB (ICH5) AC97 audio", (void *)TYPE_ICH4 },
|
||||
{ 0x1039, 0x7012, -1, -1, -1, -1, -1, "SiS SI7012 AC97 audio", (void *)TYPE_SIS7012 },
|
||||
{ 0x10DE, 0x01B1, -1, -1, -1, -1, -1, "NVIDIA nForce (MCP) AC97 audio" },
|
||||
{ 0x10DE, 0x006A, -1, -1, -1, -1, -1, "NVIDIA nForce 2 (MCP2) AC97 audio" },
|
||||
{ 0x10DE, 0x00DA, -1, -1, -1, -1, -1, "NVIDIA nForce 3 (MCP3) AC97 audio" },
|
||||
@@ -29,30 +35,72 @@ id_table_t ichaudio_id_table[] = {
|
||||
|
||||
|
||||
driver_info_t driver_info = {
|
||||
.table = ichaudio_id_table,
|
||||
.id_table = ichaudio_id_table,
|
||||
.basename = "audio/lala/ichaudio",
|
||||
.cookie_size = sizeof(ichaudio_cookie),
|
||||
.attach = ichaudio_attach,
|
||||
.detach = ichaudio_detach,
|
||||
.powerctl = ichaudio_powerctl,
|
||||
};
|
||||
|
||||
|
||||
stream_info_t po_stream = {
|
||||
.flags = B_PLAYBACK_STREAM | B_BUFFER_SIZE_EXPONETIAL | B_SAMPLE_TYPE_INT16,
|
||||
.cookie_size = sizeof(ichaudio_stream_cookie),
|
||||
.sample_bits = 16,
|
||||
.channel_count = 2,
|
||||
.channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT,
|
||||
.frame_rate_min = 0, // is setup later after device probing
|
||||
.frame_rate_max = 0, // is setup later after device probing
|
||||
.frame_rate_mask = 0, // is setup later after device probing
|
||||
.buffer_size_min = 256,
|
||||
.buffer_size_max = 32768,
|
||||
.buffer_count = 2,
|
||||
.attach = ichaudio_stream_attach,
|
||||
.detach = ichaudio_stream_detach,
|
||||
.control = ichaudio_stream_control,
|
||||
.set_buffers = ichaudio_stream_set_buffers,
|
||||
.set_frame_rate = ichaudio_stream_set_frame_rate,
|
||||
};
|
||||
|
||||
|
||||
stream_info_t pi_stream = {
|
||||
.flags = B_RECORDING_STREAM | B_BUFFER_SIZE_EXPONETIAL | B_SAMPLE_TYPE_INT16,
|
||||
.sample_bits = 16,
|
||||
.channel_count = 2,
|
||||
.channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT,
|
||||
.frame_rate_min = 0, // is setup later after device probing
|
||||
.frame_rate_max = 0, // is setup later after device probing
|
||||
.frame_rate_mask = 0, // is setup later after device probing
|
||||
.buffer_size_min = 256,
|
||||
.buffer_size_max = 32768,
|
||||
.buffer_count = 2,
|
||||
.attach = ichaudio_stream_attach,
|
||||
.detach = ichaudio_stream_detach,
|
||||
.control = ichaudio_stream_control,
|
||||
.set_buffers = ichaudio_stream_set_buffers,
|
||||
.set_frame_rate = ichaudio_stream_set_frame_rate,
|
||||
};
|
||||
|
||||
status_t
|
||||
ichaudio_attach(audio_drv_t *drv)
|
||||
ichaudio_attach(audio_drv_t *drv, void **_cookie)
|
||||
{
|
||||
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||
ichaudio_cookie *cookie;
|
||||
uint32 value;
|
||||
int i;
|
||||
bigtime_t start;
|
||||
bool s0cr, s1cr, s2cr;
|
||||
|
||||
dprintf("ichaudio_attach\n");
|
||||
|
||||
*_cookie = cookie = (ichaudio_cookie *) malloc(sizeof(ichaudio_cookie));
|
||||
|
||||
cookie->pci = drv->pci;
|
||||
cookie->flags = (uint32)drv->param;
|
||||
|
||||
// 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;
|
||||
value |= PCI_PCICMD_BME | (cookie->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!)
|
||||
@@ -60,17 +108,17 @@ ichaudio_attach(audio_drv_t *drv)
|
||||
if (cookie->irq == 0xff) cookie->irq = 0;
|
||||
if (cookie->irq == 0) dprintf("ichaudio_attach: no interrupt configured\n");
|
||||
|
||||
if (drv->flags & TYPE_ICH4) {
|
||||
if (cookie->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) {
|
||||
uint32 phys_mmbar = PCI_address_memory_32_mask & drv->pci->read_pci_config(drv->bus, drv->device, drv->function, 0x18, 4);
|
||||
uint32 phys_mbbar = PCI_address_memory_32_mask & drv->pci->read_pci_config(drv->bus, drv->device, drv->function, 0x1C, 4);
|
||||
if (!phys_mmbar || !phys_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");
|
||||
cookie->area_mmbar = map_mem(&cookie->mmbar, (void *)phys_mmbar, ICH4_MMBAR_SIZE, 0, "ichaudio mmbar io");
|
||||
cookie->area_mbbar = map_mem(&cookie->mbbar, (void *)phys_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;
|
||||
@@ -97,34 +145,34 @@ ichaudio_attach(audio_drv_t *drv)
|
||||
* reset does also reset GPIO pins, but the ICH hardware does only execute
|
||||
* the reset request if BIT_CLOCK is not running and if it's really required.
|
||||
*/
|
||||
LOG(("reset starting, ICH_REG_GLOB_CNT = 0x%08x\n", ich_reg_read_32(drv, ICH_REG_GLOB_CNT)));
|
||||
DEBUG_ONLY(start = system_time());
|
||||
LOG(("reset starting, ICH_REG_GLOB_CNT = 0x%08lx\n", ich_reg_read_32(cookie, ICH_REG_GLOB_CNT)));
|
||||
start = system_time();
|
||||
// finish cold reset by writing a 1 and clear all other bits to 0
|
||||
ich_reg_write_32(drv, ICH_REG_GLOB_CNT, CNT_COLD);
|
||||
ich_reg_read_32(drv, ICH_REG_GLOB_CNT); // force PCI-to-PCI bridge cache flush
|
||||
ich_reg_write_32(cookie, ICH_REG_GLOB_CNT, CNT_COLD);
|
||||
ich_reg_read_32(cookie, ICH_REG_GLOB_CNT); // force PCI-to-PCI bridge cache flush
|
||||
snooze(20000);
|
||||
// request warm reset by setting the bit, it will clear when reset is done
|
||||
ich_reg_write_32(drv, ICH_REG_GLOB_CNT, ich_reg_read_32(drv, ICH_REG_GLOB_CNT) | CNT_WARM);
|
||||
ich_reg_read_32(drv, ICH_REG_GLOB_CNT); // force PCI-to-PCI bridge cache flush
|
||||
ich_reg_write_32(cookie, ICH_REG_GLOB_CNT, ich_reg_read_32(cookie, ICH_REG_GLOB_CNT) | CNT_WARM);
|
||||
ich_reg_read_32(cookie, ICH_REG_GLOB_CNT); // force PCI-to-PCI bridge cache flush
|
||||
snooze(20000);
|
||||
// wait up to 1 second for warm reset to be finished
|
||||
for (i = 0; i < 20; i++) {
|
||||
value = ich_reg_read_32(drv, ICH_REG_GLOB_CNT);
|
||||
value = ich_reg_read_32(cookie, ICH_REG_GLOB_CNT);
|
||||
if ((value & CNT_WARM) == 0 && (value & CNT_COLD) != 0)
|
||||
break;
|
||||
snooze(50000);
|
||||
}
|
||||
if (i == 20) {
|
||||
LOG(("reset failed, ICH_REG_GLOB_CNT = 0x%08x\n", value));
|
||||
LOG(("reset failed, ICH_REG_GLOB_CNT = 0x%08lx\n", value));
|
||||
goto err;
|
||||
}
|
||||
LOG(("reset finished after %Ld, ICH_REG_GLOB_CNT = 0x%08x\n", system_time() - start, value));
|
||||
LOG(("reset finished after %Ld, ICH_REG_GLOB_CNT = 0x%08lx\n", system_time() - start, value));
|
||||
|
||||
/* detect which codecs are ready */
|
||||
s0cr = s1cr = s2cr = false;
|
||||
start = system_time();
|
||||
do {
|
||||
value = ich_reg_read_32(drv, ICH_REG_GLOB_STA);
|
||||
value = ich_reg_read_32(cookie, ICH_REG_GLOB_STA);
|
||||
if (!s0cr && (value & STA_S0CR)) {
|
||||
s0cr = true;
|
||||
LOG(("AC_SDIN0 codec ready after %Ld us\n", system_time() - start));
|
||||
@@ -155,40 +203,40 @@ ichaudio_attach(audio_drv_t *drv)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (drv->flags & TYPE_ICH4) {
|
||||
if (cookie->flags & TYPE_ICH4) {
|
||||
/* we are using a ICH4 chipset, and assume that the codec beeing ready
|
||||
* is the primary one.
|
||||
*/
|
||||
uint8 sdin;
|
||||
uint16 reset;
|
||||
uint8 id;
|
||||
reset = ich_codec_read(drv, 0x00); /* access the primary codec */
|
||||
reset = ich_codec_read(cookie, 0x00); /* access the primary codec */
|
||||
if (reset == 0 || reset == 0xFFFF) {
|
||||
LOG(("primary codec not present\n"));
|
||||
} else {
|
||||
sdin = 0x02 & ich_reg_read_8(drv, ICH_REG_SDM);
|
||||
id = 0x02 & (ich_codec_read(drv, 0x00 + 0x28) >> 14);
|
||||
sdin = 0x02 & ich_reg_read_8(cookie, ICH_REG_SDM);
|
||||
id = 0x02 & (ich_codec_read(cookie, 0x00 + 0x28) >> 14);
|
||||
LOG(("primary codec id %d is connected to AC_SDIN%d\n", id, sdin));
|
||||
}
|
||||
reset = ich_codec_read(drv, 0x80); /* access the secondary codec */
|
||||
reset = ich_codec_read(cookie, 0x80); /* access the secondary codec */
|
||||
if (reset == 0 || reset == 0xFFFF) {
|
||||
LOG(("secondary codec not present\n"));
|
||||
} else {
|
||||
sdin = 0x02 & ich_reg_read_8(drv, ICH_REG_SDM);
|
||||
id = 0x02 & (ich_codec_read(drv, 0x80 + 0x28) >> 14);
|
||||
sdin = 0x02 & ich_reg_read_8(cookie, ICH_REG_SDM);
|
||||
id = 0x02 & (ich_codec_read(cookie, 0x80 + 0x28) >> 14);
|
||||
LOG(("secondary codec id %d is connected to AC_SDIN%d\n", id, sdin));
|
||||
}
|
||||
reset = ich_codec_read(drv, 0x100); /* access the tertiary codec */
|
||||
reset = ich_codec_read(cookie, 0x100); /* access the tertiary codec */
|
||||
if (reset == 0 || reset == 0xFFFF) {
|
||||
LOG(("tertiary codec not present\n"));
|
||||
} else {
|
||||
sdin = 0x02 & ich_reg_read_8(drv, ICH_REG_SDM);
|
||||
id = 0x02 & (ich_codec_read(drv, 0x100 + 0x28) >> 14);
|
||||
sdin = 0x02 & ich_reg_read_8(cookie, ICH_REG_SDM);
|
||||
id = 0x02 & (ich_codec_read(cookie, 0x100 + 0x28) >> 14);
|
||||
LOG(("tertiary codec id %d is connected to AC_SDIN%d\n", id, sdin));
|
||||
}
|
||||
|
||||
/* XXX this may be wrong */
|
||||
ich_reg_write_8(drv, ICH_REG_SDM, (ich_reg_read_8(drv, ICH_REG_SDM) & 0x0F) | 0x08 | 0x90);
|
||||
ich_reg_write_8(cookie, ICH_REG_SDM, (ich_reg_read_8(cookie, ICH_REG_SDM) & 0x0F) | 0x08 | 0x90);
|
||||
} else {
|
||||
/* we are using a pre-ICH4 chipset, that has a fixed mapping of
|
||||
* AC_SDIN0 = primary, AC_SDIN1 = secondary codec.
|
||||
@@ -200,36 +248,168 @@ ichaudio_attach(audio_drv_t *drv)
|
||||
}
|
||||
}
|
||||
|
||||
cookie->po_stream_id = create_stream(&po_stream, (void *)ICH_REG_PO_BASE);
|
||||
cookie->pi_stream_id = create_stream(&pi_stream, (void *)ICH_REG_PI_BASE);
|
||||
if (cookie->po_stream_id < 0 || cookie->pi_stream_id < 0)
|
||||
goto err;
|
||||
|
||||
return B_OK;
|
||||
|
||||
err:
|
||||
// delete streams
|
||||
if (cookie->po_stream_id > 0) delete_stream(cookie->po_stream_id);
|
||||
if (cookie->pi_stream_id > 0) delete_stream(cookie->pi_stream_id);
|
||||
// unmap io memory
|
||||
if (cookie->area_mmbar > 0) delete_area(cookie->area_mmbar);
|
||||
if (cookie->area_mbbar > 0) delete_area(cookie->area_mbbar);
|
||||
free(cookie);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ichaudio_detach(audio_drv_t *drv)
|
||||
ichaudio_detach(audio_drv_t *drv, void *_cookie)
|
||||
{
|
||||
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||
ichaudio_cookie *cookie = (ichaudio_cookie *)_cookie;
|
||||
|
||||
dprintf("ichaudio_detach\n");
|
||||
|
||||
// delete streams
|
||||
if (cookie->po_stream_id > 0) delete_stream(cookie->po_stream_id);
|
||||
if (cookie->pi_stream_id > 0) delete_stream(cookie->pi_stream_id);
|
||||
// unmap io memory
|
||||
if (cookie->area_mmbar > 0) delete_area(cookie->area_mmbar);
|
||||
if (cookie->area_mbbar > 0) delete_area(cookie->area_mbbar);
|
||||
free(cookie);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ichaudio_powerctl(audio_drv_t *drv)
|
||||
ichaudio_powerctl(audio_drv_t *drv, void *_cookie)
|
||||
{
|
||||
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||
ichaudio_cookie *cookie = (ichaudio_cookie *)_cookie;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
void
|
||||
stream_reset(ichaudio_stream_cookie *cookie)
|
||||
{
|
||||
int i;
|
||||
|
||||
ich_reg_write_8(cookie, cookie->regbase + ICH_REG_X_CR, 0);
|
||||
ich_reg_read_8(cookie, cookie->regbase + ICH_REG_X_CR); // force PCI-to-PCI bridge cache flush
|
||||
snooze(10000); // 10 ms
|
||||
ich_reg_write_8(cookie, cookie->regbase + ICH_REG_X_CR, CR_RR);
|
||||
for (i = 0; i < 100; i++) {
|
||||
uint8 cr = ich_reg_read_8(cookie, cookie->regbase + ICH_REG_X_CR);
|
||||
if (cr == 0) {
|
||||
LOG(("channel reset finished, %d\n",i));
|
||||
return;
|
||||
}
|
||||
snooze(100);
|
||||
}
|
||||
LOG(("channel reset failed after 10ms\n"));
|
||||
}
|
||||
|
||||
status_t
|
||||
ichaudio_stream_attach(audio_drv_t *drv, void **_cookie, void *param)
|
||||
{
|
||||
ichaudio_stream_cookie *cookie;
|
||||
void *bd_virt_base;
|
||||
void *bd_phys_base;
|
||||
int i;
|
||||
|
||||
*_cookie = cookie = (ichaudio_stream_cookie *) malloc(sizeof(ichaudio_stream_cookie));
|
||||
|
||||
cookie->regbase = (uint32) param;
|
||||
cookie->lastindex = 0;
|
||||
cookie->processed_samples = 0;
|
||||
|
||||
stream_reset(cookie);
|
||||
|
||||
// allocate memory for buffer descriptors
|
||||
cookie->bd_area = alloc_mem(&bd_virt_base, &bd_phys_base, ICH_BD_COUNT * sizeof(ich_bd), 0, "ich_ac97 buffer descriptor");
|
||||
if (cookie->bd_area < B_OK)
|
||||
goto err;
|
||||
|
||||
// set physical buffer descriptor base address
|
||||
ich_reg_write_32(cookie->regbase, (uint32)bd_phys_base);
|
||||
|
||||
// setup descriptor pointers
|
||||
for (i = 0; i < ICH_BD_COUNT; i++)
|
||||
cookie->bd[i] = (ich_bd *) ((char *)bd_virt_base + i * sizeof(ich_bd));
|
||||
|
||||
return B_OK;
|
||||
|
||||
err:
|
||||
free(cookie);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ichaudio_stream_detach(audio_drv_t *drv, void *_cookie)
|
||||
{
|
||||
ichaudio_stream_cookie *cookie = (ichaudio_stream_cookie *)_cookie;
|
||||
|
||||
stream_reset(cookie);
|
||||
|
||||
if (cookie->buffer_area > 0) delete_area(cookie->buffer_area);
|
||||
if (cookie->bd_area > 0) delete_area(cookie->bd_area);
|
||||
free(cookie);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ichaudio_stream_control(audio_drv_t *drv, void *_cookie, int op)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ichaudio_stream_set_buffers(audio_drv_t *drv, void *_cookie, uint32 *buffer_size, stream_buffer_desc_t *desc)
|
||||
{
|
||||
ichaudio_stream_cookie *cookie = (ichaudio_stream_cookie *)_cookie;
|
||||
|
||||
void *buffer_virt_base;
|
||||
void *buffer_phys_base;
|
||||
area_id buffer_area;
|
||||
int i;
|
||||
|
||||
// round down (could force another size here)
|
||||
*buffer_size &= ~3;
|
||||
|
||||
// allocate memory buffers
|
||||
buffer_area = alloc_mem(&buffer_virt_base, &buffer_phys_base, 2 * *buffer_size, B_READ_AREA | B_WRITE_AREA, "ich_ac97 buffers");
|
||||
|
||||
// report buffers
|
||||
desc[0].base = (char *)buffer_virt_base;
|
||||
desc[0].stride = 4;
|
||||
desc[1].base = (char *)buffer_virt_base + 2;
|
||||
desc[1].stride = 4;
|
||||
|
||||
// initalize buffer descriptors
|
||||
for (i = 0; i < ICH_BD_COUNT; i++) {
|
||||
cookie->bd[i].buffer = (uint32)buffer_phy_base + (i % 2) * *buffer_size;
|
||||
cookie->bd[i].length = *buffer_size / GET_HW_SAMPLE_SIZE(cookie);
|
||||
cookie->bd[i].flags = ICH_BDC_FLAG_IOC;
|
||||
}
|
||||
|
||||
// free old buffer memory
|
||||
if (cookie->buffer_area > 0)
|
||||
delete_area(cookie->buffer_area);
|
||||
|
||||
cookie->buffer_area = buffer_area;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ichaudio_stream_set_frame_rate(audio_drv_t *drv, void *_cookie, uint32 *frame_rate)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <SupportDefs.h>
|
||||
#include "hardware.h"
|
||||
#include "lala/lala.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -14,16 +15,37 @@ typedef struct
|
||||
uint32 codecoffset;
|
||||
uint32 input_rate;
|
||||
uint32 output_rate;
|
||||
|
||||
stream_id po_stream_id;
|
||||
stream_id pi_stream_id;
|
||||
|
||||
pci_module_info * pci;
|
||||
uint32 flags;
|
||||
|
||||
} ichaudio_cookie;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32 regbase;
|
||||
ich_bd * bd[ICH_BD_COUNT];
|
||||
void * buffer[ICH_BD_COUNT];
|
||||
|
||||
area_id bd_area;
|
||||
area_id buffer_area;
|
||||
|
||||
volatile int lastindex;
|
||||
volatile int64 processed_samples;
|
||||
|
||||
} ichaudio_stream_cookie;
|
||||
|
||||
|
||||
#define TYPE_ICH4 0x01
|
||||
#define TYPE_SIS7012 0x02
|
||||
|
||||
/* The SIS7012 chipset has SR and PICB registers swapped when compared to Intel */
|
||||
#define GET_REG_X_PICB(cfg) (((cfg)->type == TYPE_SIS7012) ? _ICH_REG_X_SR : _ICH_REG_X_PICB)
|
||||
#define GET_REG_X_SR(cfg) (((cfg)->type == TYPE_SIS7012) ? _ICH_REG_X_PICB : _ICH_REG_X_SR)
|
||||
#define GET_REG_X_PICB(cookie) (((cookie)->flags & TYPE_SIS7012) ? _ICH_REG_X_SR : _ICH_REG_X_PICB)
|
||||
#define GET_REG_X_SR(cookie) (((cookie)->flags & TYPE_SIS7012) ? _ICH_REG_X_PICB : _ICH_REG_X_SR)
|
||||
/* Each 16 bit sample is counted as 1 in SIS7012 chipsets, 2 in all others */
|
||||
#define GET_HW_SAMPLE_SIZE(cfg) (((cfg)->type == TYPE_SIS7012) ? 1 : 2)
|
||||
#define GET_HW_SAMPLE_SIZE(cookie) (((cookie)->flags & TYPE_SIS7012) ? 1 : 2)
|
||||
|
||||
|
||||
@@ -32,96 +32,84 @@
|
||||
#include "ichaudio.h"
|
||||
#include "io.h"
|
||||
|
||||
status_t ich_codec_wait(audio_drv_t *drv);
|
||||
status_t ich_codec_wait(ichaudio_cookie *cookie);
|
||||
|
||||
uint8
|
||||
ich_reg_read_8(audio_drv_t *drv, int regno)
|
||||
ich_reg_read_8(ichaudio_cookie *cookie, 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)
|
||||
ASSERT(((cookie->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||
if (cookie->flags & TYPE_ICH4)
|
||||
return *(uint8 *)((char *)cookie->mbbar + regno);
|
||||
else
|
||||
return drv->pci->read_io_8(cookie->nabmbar + regno);
|
||||
return cookie->pci->read_io_8(cookie->nabmbar + regno);
|
||||
}
|
||||
|
||||
uint16
|
||||
ich_reg_read_16(audio_drv_t *drv, int regno)
|
||||
ich_reg_read_16(ichaudio_cookie *cookie, 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)
|
||||
ASSERT(((cookie->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||
if (cookie->flags & TYPE_ICH4)
|
||||
return *(uint16 *)((char *)cookie->mbbar + regno);
|
||||
else
|
||||
return drv->pci->read_io_16(cookie->nabmbar + regno);
|
||||
return cookie->pci->read_io_16(cookie->nabmbar + regno);
|
||||
}
|
||||
|
||||
uint32
|
||||
ich_reg_read_32(audio_drv_t *drv, int regno)
|
||||
ich_reg_read_32(ichaudio_cookie *cookie, int regno)
|
||||
{
|
||||
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||
|
||||
ASSERT(regno >= 0);
|
||||
ASSERT(((drv->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||
ASSERT(((cookie->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||
|
||||
if (drv->flags & TYPE_ICH4)
|
||||
if (cookie->flags & TYPE_ICH4)
|
||||
return *(uint32 *)((char *)cookie->mbbar + regno);
|
||||
else
|
||||
return drv->pci->read_io_32(cookie->nabmbar + regno);
|
||||
return cookie->pci->read_io_32(cookie->nabmbar + regno);
|
||||
}
|
||||
|
||||
void
|
||||
ich_reg_write_8(audio_drv_t *drv, int regno, uint8 value)
|
||||
ich_reg_write_8(ichaudio_cookie *cookie, int regno, uint8 value)
|
||||
{
|
||||
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||
|
||||
ASSERT(regno >= 0);
|
||||
ASSERT(((drv->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||
ASSERT(((cookie->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||
|
||||
if (drv->flags & TYPE_ICH4)
|
||||
if (cookie->flags & TYPE_ICH4)
|
||||
*(uint8 *)((char *)cookie->mbbar + regno) = value;
|
||||
else
|
||||
drv->pci->write_io_8(cookie->nabmbar + regno, value);
|
||||
cookie->pci->write_io_8(cookie->nabmbar + regno, value);
|
||||
}
|
||||
|
||||
void
|
||||
ich_reg_write_16(audio_drv_t *drv, int regno, uint16 value)
|
||||
ich_reg_write_16(ichaudio_cookie *cookie, int regno, uint16 value)
|
||||
{
|
||||
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||
|
||||
ASSERT(regno >= 0);
|
||||
ASSERT(((drv->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||
ASSERT(((cookie->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||
|
||||
if (drv->flags & TYPE_ICH4)
|
||||
if (cookie->flags & TYPE_ICH4)
|
||||
*(uint16 *)((char *)cookie->mbbar + regno) = value;
|
||||
else
|
||||
drv->pci->write_io_16(cookie->nabmbar + regno, value);
|
||||
cookie->pci->write_io_16(cookie->nabmbar + regno, value);
|
||||
}
|
||||
|
||||
void
|
||||
ich_reg_write_32(audio_drv_t *drv, int regno, uint32 value)
|
||||
ich_reg_write_32(ichaudio_cookie *cookie, int regno, uint32 value)
|
||||
{
|
||||
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||
|
||||
ASSERT(regno >= 0);
|
||||
ASSERT(((drv->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||
ASSERT(((cookie->flags & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||
|
||||
if (drv->flags & TYPE_ICH4)
|
||||
if (cookie->flags & TYPE_ICH4)
|
||||
*(uint32 *)((char *)cookie->mbbar + regno) = value;
|
||||
else
|
||||
drv->pci->write_io_32(cookie->nabmbar + regno, value);
|
||||
cookie->pci->write_io_32(cookie->nabmbar + regno, value);
|
||||
}
|
||||
|
||||
status_t
|
||||
ich_codec_wait(audio_drv_t *drv)
|
||||
ich_codec_wait(ichaudio_cookie *cookie)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 1100; i++) {
|
||||
if ((ich_reg_read_8(drv, ICH_REG_ACC_SEMA) & 0x01) == 0)
|
||||
if ((ich_reg_read_8(cookie, ICH_REG_ACC_SEMA) & 0x01) == 0)
|
||||
return B_OK;
|
||||
if (i > 100)
|
||||
snooze(1);
|
||||
@@ -130,39 +118,39 @@ ich_codec_wait(audio_drv_t *drv)
|
||||
}
|
||||
|
||||
uint16
|
||||
ich_codec_read(audio_drv_t *drv, int regno)
|
||||
ich_codec_read(void *_cookie, int regno)
|
||||
{
|
||||
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||
ichaudio_cookie *cookie = (ichaudio_cookie *)_cookie;
|
||||
|
||||
ASSERT(regno >= 0);
|
||||
ASSERT((regno & 1) == 0);
|
||||
ASSERT(((drv->flags & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255);
|
||||
ASSERT(((cookie->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))
|
||||
if (B_OK != ich_codec_wait(cookie))
|
||||
PRINT(("semaphore timeout reading register %#x\n", regno));
|
||||
if (drv->flags & TYPE_ICH4)
|
||||
if (cookie->flags & TYPE_ICH4)
|
||||
return *(uint16 *)(((char *)cookie->mmbar) + regno);
|
||||
else
|
||||
return drv->pci->read_io_16(cookie->nambar + regno);
|
||||
return cookie->pci->read_io_16(cookie->nambar + regno);
|
||||
}
|
||||
|
||||
void
|
||||
ich_codec_write(audio_drv_t *drv, int regno, uint16 value)
|
||||
ich_codec_write(void *_cookie, int regno, uint16 value)
|
||||
{
|
||||
ichaudio_cookie *cookie = (ichaudio_cookie *)drv->cookie;
|
||||
ichaudio_cookie *cookie = (ichaudio_cookie *)_cookie;
|
||||
|
||||
ASSERT(regno >= 0);
|
||||
ASSERT((regno & 1) == 0);
|
||||
ASSERT(((drv->flags & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255);
|
||||
ASSERT(((cookie->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))
|
||||
if (B_OK != ich_codec_wait(cookie))
|
||||
PRINT(("semaphore timeout writing register %#x\n", regno));
|
||||
if (drv->flags & TYPE_ICH4)
|
||||
if (cookie->flags & TYPE_ICH4)
|
||||
*(uint16 *)(((char *)cookie->mmbar) + regno) = value;
|
||||
else
|
||||
drv->pci->write_io_16(cookie->nambar + regno, value);
|
||||
cookie->pci->write_io_16(cookie->nambar + regno, value);
|
||||
}
|
||||
|
||||
@@ -30,15 +30,15 @@
|
||||
|
||||
#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);
|
||||
uint8 ich_reg_read_8(ichaudio_cookie *cookie, int regno);
|
||||
uint16 ich_reg_read_16(ichaudio_cookie *cookie, int regno);
|
||||
uint32 ich_reg_read_32(ichaudio_cookie *cookie, 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);
|
||||
void ich_reg_write_8(ichaudio_cookie *cookie, int regno, uint8 value);
|
||||
void ich_reg_write_16(ichaudio_cookie *cookie, int regno, uint16 value);
|
||||
void ich_reg_write_32(ichaudio_cookie *cookie, 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);
|
||||
uint16 ich_codec_read(void *_cookie, int regno);
|
||||
void ich_codec_write(void *_cookie, int regno, uint16 value);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,10 +16,13 @@ int32 api_version = B_CUR_DRIVER_API_VERSION;
|
||||
sem_id drv_sem;
|
||||
char * drv_path[MAX_DEVICES + 1];
|
||||
audio_drv_t * drv_data[MAX_DEVICES];
|
||||
int drv_open_count[MAX_DEVICES];
|
||||
void * drv_cookie[MAX_DEVICES];
|
||||
int drv_count;
|
||||
|
||||
pci_module_info *pcimodule;
|
||||
|
||||
extern driver_info_t driver_info;
|
||||
|
||||
status_t
|
||||
init_hardware(void)
|
||||
@@ -53,25 +56,25 @@ init_driver(void)
|
||||
// pciinfo->vendor_id, pciinfo->device_id, pciinfo->bus, pciinfo->device, pciinfo->function,
|
||||
// pciinfo->revision, pciinfo->class_api, pciinfo->class_sub, pciinfo->class_base);
|
||||
|
||||
for (devindex = 0; driver_info.table[devindex].vendor != 0; devindex++) {
|
||||
if (driver_info.table[devindex].vendor != -1 && driver_info.table[devindex].vendor != pciinfo->vendor_id)
|
||||
for (devindex = 0; driver_info.id_table[devindex].vendor != 0; devindex++) {
|
||||
if (driver_info.id_table[devindex].vendor != -1 && driver_info.id_table[devindex].vendor != pciinfo->vendor_id)
|
||||
continue;
|
||||
if (driver_info.table[devindex].device != -1 && driver_info.table[devindex].device != pciinfo->device_id)
|
||||
if (driver_info.id_table[devindex].device != -1 && driver_info.id_table[devindex].device != pciinfo->device_id)
|
||||
continue;
|
||||
if (driver_info.table[devindex].revision != -1 && driver_info.table[devindex].revision != pciinfo->revision)
|
||||
if (driver_info.id_table[devindex].revision != -1 && driver_info.id_table[devindex].revision != pciinfo->revision)
|
||||
continue;
|
||||
if (driver_info.table[devindex].class != -1 && driver_info.table[devindex].class != pciinfo->class_base)
|
||||
if (driver_info.id_table[devindex].class != -1 && driver_info.id_table[devindex].class != pciinfo->class_base)
|
||||
continue;
|
||||
if (driver_info.table[devindex].subclass != -1 && driver_info.table[devindex].subclass != pciinfo->class_sub)
|
||||
if (driver_info.id_table[devindex].subclass != -1 && driver_info.id_table[devindex].subclass != pciinfo->class_sub)
|
||||
continue;
|
||||
if (pciinfo->header_type == 0) {
|
||||
if (driver_info.table[devindex].subsystem_vendor != -1 && driver_info.table[devindex].subsystem_vendor != pciinfo->u.h0.subsystem_vendor_id)
|
||||
if (driver_info.id_table[devindex].subsystem_vendor != -1 && driver_info.id_table[devindex].subsystem_vendor != pciinfo->u.h0.subsystem_vendor_id)
|
||||
continue;
|
||||
if (driver_info.table[devindex].subsystem_device != -1 && driver_info.table[devindex].subsystem_device != pciinfo->u.h0.subsystem_id)
|
||||
if (driver_info.id_table[devindex].subsystem_device != -1 && driver_info.id_table[devindex].subsystem_device != pciinfo->u.h0.subsystem_id)
|
||||
continue;
|
||||
}
|
||||
|
||||
dprintf("found device '%s'\n", driver_info.table[devindex].name);
|
||||
dprintf("found device '%s'\n", driver_info.id_table[devindex].name);
|
||||
|
||||
drv_path[drv_count] = (char *) malloc(strlen(driver_info.basename) + 5);
|
||||
sprintf(drv_path[drv_count], "%s/%d", driver_info.basename, drv_count + 1);
|
||||
@@ -81,10 +84,9 @@ init_driver(void)
|
||||
drv_data[drv_count]->bus = pciinfo->bus;
|
||||
drv_data[drv_count]->device = pciinfo->device;
|
||||
drv_data[drv_count]->function = pciinfo->function;
|
||||
drv_data[drv_count]->name = driver_info.table[devindex].name;
|
||||
drv_data[drv_count]->flags = driver_info.table[devindex].flags;
|
||||
drv_data[drv_count]->open_count = 0;
|
||||
drv_data[drv_count]->cookie = malloc(driver_info.cookie_size);
|
||||
drv_data[drv_count]->name = driver_info.id_table[devindex].name;
|
||||
drv_data[drv_count]->param = driver_info.id_table[devindex].param;
|
||||
drv_open_count[drv_count] = 0;
|
||||
|
||||
drv_count++;
|
||||
break;
|
||||
@@ -106,7 +108,6 @@ uninit_driver(void)
|
||||
|
||||
for (i = 0; i < drv_count; i++) {
|
||||
free(drv_path[i]);
|
||||
free(drv_data[i]->cookie);
|
||||
free(drv_data[i]);
|
||||
}
|
||||
delete_sem(drv_sem);
|
||||
@@ -130,13 +131,12 @@ ich_open(const char *name, uint32 flags, void** cookie)
|
||||
}
|
||||
*cookie = (void *) index;
|
||||
|
||||
if (drv_data[index]->open_count == 0) {
|
||||
memset(drv_data[index]->cookie, 0, driver_info.cookie_size);
|
||||
res = driver_info.attach(drv_data[index]);
|
||||
drv_data[index]->open_count = (res == B_OK) ? 1 : 0;
|
||||
if (drv_open_count[index] == 0) {
|
||||
res = driver_info.attach(drv_data[index], &drv_cookie[index]);
|
||||
drv_open_count[index] = (res == B_OK) ? 1 : 0;
|
||||
} else {
|
||||
res = B_OK;
|
||||
drv_data[index]->open_count++;
|
||||
drv_open_count[index]++;
|
||||
}
|
||||
|
||||
release_sem(drv_sem);
|
||||
@@ -163,10 +163,10 @@ ich_free(void* cookie)
|
||||
|
||||
acquire_sem(drv_sem);
|
||||
|
||||
drv_data[index]->open_count--;
|
||||
drv_open_count[index]--;
|
||||
|
||||
if (drv_data[index]->open_count == 0)
|
||||
res = driver_info.detach(drv_data[index]);
|
||||
if (drv_open_count[index] == 0)
|
||||
res = driver_info.detach(drv_data[index], drv_cookie[index]);
|
||||
else
|
||||
res = B_OK;
|
||||
|
||||
|
||||
@@ -16,40 +16,36 @@ typedef struct
|
||||
uint8 function;
|
||||
|
||||
const char * name;
|
||||
uint32 flags;
|
||||
|
||||
void * cookie;
|
||||
|
||||
// private:
|
||||
int32 open_count;
|
||||
void * param;
|
||||
} audio_drv_t;
|
||||
|
||||
typedef void stream_id;
|
||||
typedef void control_id;
|
||||
|
||||
typedef struct {
|
||||
int32 vendor;
|
||||
int32 device;
|
||||
int32 revision;
|
||||
int32 class;
|
||||
int32 subclass;
|
||||
int32 subsystem_vendor;
|
||||
int32 subsystem_device;
|
||||
const char *name;
|
||||
uint32 flags;
|
||||
typedef struct
|
||||
{
|
||||
int32 vendor;
|
||||
int32 device;
|
||||
int32 revision;
|
||||
int32 class;
|
||||
int32 subclass;
|
||||
int32 subsystem_vendor;
|
||||
int32 subsystem_device;
|
||||
const char * name;
|
||||
void * param;
|
||||
} id_table_t;
|
||||
|
||||
|
||||
typedef status_t (*drv_attach) (audio_drv_t *drv);
|
||||
typedef status_t (*drv_powerctl) (audio_drv_t *drv);
|
||||
typedef status_t (*drv_detach) (audio_drv_t *drv);
|
||||
typedef int32 stream_id;
|
||||
typedef int32 control_id;
|
||||
|
||||
|
||||
typedef status_t (*drv_attach) (audio_drv_t *drv, void **cookie);
|
||||
typedef status_t (*drv_powerctl) (audio_drv_t *drv, void *cookie);
|
||||
typedef status_t (*drv_detach) (audio_drv_t *drv, void *cookie);
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
id_table_t * table;
|
||||
id_table_t * id_table;
|
||||
const char * basename;
|
||||
size_t cookie_size;
|
||||
|
||||
uint32 _reserved1[16];
|
||||
|
||||
@@ -61,69 +57,81 @@ typedef struct
|
||||
} driver_info_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
char * base; /* pointer to first sample for channel for buffer */
|
||||
size_t stride; /* offset to next sample */
|
||||
uint32 _reserved[4];
|
||||
} stream_buffer_desc_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32 frame_rate;
|
||||
uint32 buffer_size;
|
||||
uint32 _reserved[16];
|
||||
} stream_config_t;
|
||||
typedef status_t (*stream_attach) (audio_drv_t *drv, void **cookie, void *param);
|
||||
typedef status_t (*stream_detach) (audio_drv_t *drv, void *cookie);
|
||||
typedef status_t (*stream_control) (audio_drv_t *drv, void *cookie, int op);
|
||||
typedef status_t (*stream_process) (audio_drv_t *drv, void *cookie, int buffer);
|
||||
typedef status_t (*stream_set_buffers) (audio_drv_t *drv, void *cookie, uint32 *buffer_size, stream_buffer_desc_t *desc);
|
||||
typedef status_t (*stream_set_frame_rate) (audio_drv_t *drv, void *cookie, uint32 *frame_rate);
|
||||
|
||||
enum {
|
||||
B_RECORDING_STREAM = 0x00000001,
|
||||
B_PLAYBACK_STREAM = 0x00000002,
|
||||
B_BUFFER_SIZE_LINEAR = 0x00001000,
|
||||
B_BUFFER_SIZE_EXPONETIAL = 0x00002000,
|
||||
B_SAMPLE_TYPE_INT16 = 0x00010000,
|
||||
B_SAMPLE_TYPE_INT32 = 0x00020000,
|
||||
B_SAMPLE_TYPE_FLOAT32 = 0x00040000,
|
||||
};
|
||||
|
||||
typedef status_t (*stream_attach) (audio_drv_t *drv, void *stream_cookie);
|
||||
typedef status_t (*stream_detach) (audio_drv_t *drv, void *stream_cookie);
|
||||
typedef status_t (*stream_control) (audio_drv_t *drv, void *stream_cookie, int op);
|
||||
typedef status_t (*stream_get_buffer_info) (audio_drv_t *drv, void *stream_cookie, stream_buffer_desc_t *desc);
|
||||
typedef status_t (*stream_set_config) (audio_drv_t *drv, void *stream_cookie, stream_config_t *config);
|
||||
enum {
|
||||
B_CHANNEL_LEFT = 0x0001,
|
||||
B_CHANNEL_RIGHT = 0x0002,
|
||||
};
|
||||
|
||||
enum {
|
||||
B_FRAME_RATE_32000 = 0x0100,
|
||||
B_FRAME_RATE_44100 = 0x0200,
|
||||
B_FRAME_RATE_48000 = 0x0400,
|
||||
B_FRAME_RATE_96000 = 0x0800,
|
||||
B_FRAME_RATE_VARIABLE = 0x20000000,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32 flags;
|
||||
uint32 cookie_size;
|
||||
uint32 user_param;
|
||||
uint32 user_cookie;
|
||||
uint32 sample_bits;
|
||||
uint32 sample_flags;
|
||||
uint32 channel_count;
|
||||
uint32 channel_flags;
|
||||
uint32 channel_mask;
|
||||
uint32 frame_rate_min;
|
||||
uint32 frame_rate_max;
|
||||
uint32 frame_rate_flags;
|
||||
uint32 frame_rate_mask;
|
||||
uint32 buffer_size_min;
|
||||
uint32 buffer_size_max;
|
||||
uint32 buffer_size_flags;
|
||||
uint32 buffer_count;
|
||||
|
||||
uint32 _reserved1[32];
|
||||
|
||||
stream_attach attach;
|
||||
stream_detach detach;
|
||||
stream_control control;
|
||||
stream_process process;
|
||||
|
||||
stream_get_buffer_info get_buffer_info;
|
||||
|
||||
stream_set_config set_config;
|
||||
stream_set_buffers set_buffers;
|
||||
stream_set_frame_rate set_frame_rate;
|
||||
|
||||
uint32 _reserved2[16];
|
||||
|
||||
} stream_info_t;
|
||||
|
||||
extern driver_info_t driver_info;
|
||||
|
||||
// protection is 0 for kernel only access, or B_READ_AREA, B_WRITE_AREA for user space access
|
||||
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, void *config);
|
||||
stream_id create_stream(stream_info_t *info, void *param);
|
||||
status_t delete_stream(stream_id stream);
|
||||
|
||||
void report_stream_event(stream_id stream, int );
|
||||
|
||||
void report_stream_buffer_ready(stream_id stream, int buffer, bigtime_t end_time, int64 total_frames);
|
||||
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user