diff --git a/src/add-ons/kernel/drivers/audio/ac97/ichaudio/Jamfile b/src/add-ons/kernel/drivers/audio/ac97/ichaudio/Jamfile new file mode 100644 index 0000000000..f394237fec --- /dev/null +++ b/src/add-ons/kernel/drivers/audio/ac97/ichaudio/Jamfile @@ -0,0 +1,25 @@ +SubDir OBOS_TOP src add-ons kernel drivers audio ac97 ichaudio ; + +# UsePrivateHeaders media ; + +SubDirHdrs [ FDirName $(OBOS_TOP) src add-ons media media-add-ons lala ] ; + +KernelMergeObject ichaudio_driver.o : + ichaudio.c + : + -fno-pic -Wno-unused -D_KERNEL_MODE + ; + +KernelLd ichaudio : + ichaudio_driver.o + lala.o + : + $(OBOS_TOP)/src/kernel/ldscripts/$(OBOS_ARCH)/add-on.ld + : + -Bdynamic -shared + : + : + add-ons/kernel/drivers/bin + ; + +SubInclude OBOS_TOP src add-ons kernel drivers audio ac97 ichaudio lala ; diff --git a/src/add-ons/kernel/drivers/audio/ac97/ichaudio/hardware.h b/src/add-ons/kernel/drivers/audio/ac97/ichaudio/hardware.h new file mode 100644 index 0000000000..98b56c8161 --- /dev/null +++ b/src/add-ons/kernel/drivers/audio/ac97/ichaudio/hardware.h @@ -0,0 +1,136 @@ +/* + * BeOS Driver for Intel ICH AC'97 Link interface + * + * Copyright (c) 2002, Marcus Overhagen + * + * 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 _HARDWARE_H_ +#define _HARDWARE_H_ + +/* Native Audio Bus Master Control Registers */ +enum ICH_GLOBAL_REGISTER +{ + ICH_REG_GLOB_CNT = 0x2C, + ICH_REG_GLOB_STA = 0x30, + ICH_REG_ACC_SEMA = 0x34, + ICH_REG_SDM = 0x80 +}; + +enum ICH_X_REGISTER_BASE /* base addresses for the following offsets */ +{ + ICH_REG_PI_BASE = 0x00, + ICH_REG_PO_BASE = 0x10, + ICH_REG_MC_BASE = 0x20 +}; + +enum ICH_X_REGISTER_OFFSETS /* add base address to get the PI, PO or MC reg */ +{ + ICH_REG_X_BDBAR = 0x00, + ICH_REG_X_CIV = 0x04, + ICH_REG_X_LVI = 0x05, + _ICH_REG_X_SR = 0x06, /* use GET_REG_X_SR() macro from config.h */ + _ICH_REG_X_PICB = 0x08, /* use GET_REG_X_PICB() macro from config.h */ + ICH_REG_X_PIV = 0x0A, + ICH_REG_X_CR = 0x0B +}; + +/* ICH_REG_X_SR (Status Register) Bits */ +enum REG_X_SR_BITS +{ + SR_DCH = 0x0001, + SR_CELV = 0x0002, + SR_LVBCI = 0x0004, + SR_BCIS = 0x0008, + SR_FIFOE = 0x0010 +}; + +/* ICH_REG_X_CR (Control Register) Bits */ +enum REG_X_CR_BITS +{ + CR_RPBM = 0x01, + CR_RR = 0x02, + CR_LVBIE = 0x04, + CR_FEIE = 0x08, + CR_IOCE = 0x10 +}; + +/* ICH_REG_GLOB_CNT (Global Control Register) Bits */ +enum REG_GLOB_CNT_BITS +{ + CNT_GIE = 0x01, + CNT_COLD = 0x02, + CNT_WARM = 0x04, + CNT_SHUT = 0x08, + CNT_PRIE = 0x10, + CNT_SRIE = 0x20 +}; + +/* ICH_REG_GLOB_STA (Global Status Register) Bits */ +enum REG_GLOB_STA_BITS +{ + STA_GSCI = 0x00000001, /* GPI Status Change Interrupt */ + STA_MIINT = 0x00000002, /* Modem In Interrupt */ + STA_MOINT = 0x00000004, /* Modem Out Interrupt */ + STA_PIINT = 0x00000020, /* PCM In Interrupt */ + STA_POINT = 0x00000040, /* PCM Out Interrupt */ + STA_MINT = 0x00000080, /* Mic In Interrupt */ + STA_S0CR = 0x00000100, /* AC_SDIN0 Codec Ready */ + STA_S1CR = 0x00000200, /* AC_SDIN1 Codec Ready */ + STA_S0RI = 0x00000400, /* AC_SDIN0 Resume Interrupt */ + STA_S1RI = 0x00000800, /* AC_SDIN1 Resume Interrupt */ + STA_RCS = 0x00008000, /* Read Completition Status */ + STA_AD3 = 0x00010000, + STA_MD3 = 0x00020000, + 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_S0RI | STA_S1RI | STA_M2INT | STA_P2INT | STA_SPINT | STA_S2RI) +}; + +#define ICH_BD_COUNT 32 +/* The Hardware Buffer Descriptor */ +typedef struct { + volatile uint32 buffer; + volatile uint16 length; + volatile uint16 flags; + #define ICH_BDC_FLAG_IOC 0x8000 +} ich_bd; + +/* PCI Configuration Space */ + +#define PCI_PCICMD 0x04 +#define PCI_PCICMD_IOS 0x01 +#define PCI_PCICMD_MSE 0x02 +#define PCI_PCICMD_BME 0x04 + +#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/ichaudio/ichaudio.c b/src/add-ons/kernel/drivers/audio/ac97/ichaudio/ichaudio.c new file mode 100644 index 0000000000..d396e8fecc --- /dev/null +++ b/src/add-ons/kernel/drivers/audio/ac97/ichaudio/ichaudio.c @@ -0,0 +1,75 @@ +#include "lala/lala.h" +#include "ichaudio.h" + +status_t ichaudio_attach(drv_t *dev, void **cookie, int id_table_index); +status_t ichaudio_powerctl(void *cookie); +status_t ichaudio_detach(void *cookie); + +id_table_t ichaudio_id_table[] = { + { 0x8086, 0x7195, -1, -1, -1, -1, -1, "Intel 82443MX AC97 audio" }, + { 0x8086, 0x2415, -1, -1, -1, -1, -1, "Intel 82801AA (ICH) AC97 audio" }, + { 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 }, + { 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" }, + { 0x1022, 0x764D, -1, -1, -1, -1, -1, "AMD AMD8111 AC97 audio" }, + { 0x1022, 0x7445, -1, -1, -1, -1, -1, "AMD AMD768 AC97 audio" }, + { 0x1003, 0x0004, -1, -1, -1, -1, -1, "Highpoint HPT372 RAID" }, + { 0x1095, 0x3112, -1, -1, -1, -1, -1, "Silicon Image SATA Si3112" }, + { 0x8086, 0x244b, -1, -1, -1, -1, -1, "Intel IDE Controller" }, + { 0x8979, 0x6456, -1, -1, -1, -1, -1, "does not exist" }, + { /* empty = end */} +}; + + +driver_info_t driver_info = { + ichaudio_id_table, + "audio/lala/ichaudio", + ichaudio_attach, + ichaudio_detach, + ichaudio_powerctl, +}; + + +status_t +ichaudio_attach(drv_t *dev, void **_cookie, int id_table_index) +{ + ichaudio_cookie *cookie = (ichaudio_cookie *) malloc(sizeof(ichaudio_cookie)); + if (!cookie) return B_ERROR; + *_cookie = cookie; + + if (get_module(B_PCI_MODULE_NAME,(module_info **)&cookie->pci) < 0) { + return B_ERROR; + } + + + return B_OK; +err: + free(cookie); + return B_OK; +} + + +status_t +ichaudio_detach(void *_cookie) +{ + ichaudio_cookie *cookie = (ichaudio_cookie *)_cookie; + + free(cookie); + return B_OK; +} + + +status_t +ichaudio_powerctl(void *_cookie) +{ + ichaudio_cookie *cookie = (ichaudio_cookie *)_cookie; + + return B_OK; +} + diff --git a/src/add-ons/kernel/drivers/audio/ac97/ichaudio/ichaudio.h b/src/add-ons/kernel/drivers/audio/ac97/ichaudio/ichaudio.h new file mode 100644 index 0000000000..72cfacdf2b --- /dev/null +++ b/src/add-ons/kernel/drivers/audio/ac97/ichaudio/ichaudio.h @@ -0,0 +1,35 @@ +#include + + +typedef struct +{ + const char *name; + uint32 nambar; + 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_mbbar; // ich4 + uint32 codecoffset; + uint32 input_rate; + uint32 output_rate; + + pci_module_info *pci; + +} ichaudio_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) +/* 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) + diff --git a/src/add-ons/kernel/drivers/audio/ac97/ichaudio/lala/Jamfile b/src/add-ons/kernel/drivers/audio/ac97/ichaudio/lala/Jamfile new file mode 100644 index 0000000000..0cf8768815 --- /dev/null +++ b/src/add-ons/kernel/drivers/audio/ac97/ichaudio/lala/Jamfile @@ -0,0 +1,11 @@ +SubDir OBOS_TOP src add-ons kernel drivers audio ac97 ichaudio lala ; + +# R5KernelStaticLibrary lala : +# driver.c +# ; + +KernelMergeObject lala.o : + driver.c + : + -fno-pic -D_KERNEL_MODE + ; diff --git a/src/add-ons/kernel/drivers/audio/ac97/ichaudio/lala/driver.c b/src/add-ons/kernel/drivers/audio/ac97/ichaudio/lala/driver.c new file mode 100644 index 0000000000..9e3d2c7444 --- /dev/null +++ b/src/add-ons/kernel/drivers/audio/ac97/ichaudio/lala/driver.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include + +int32 api_version = B_CUR_DRIVER_API_VERSION; + +#define MAX_DEVICES 8 + +char * device_names[MAX_DEVICES]; +int device_count = 0; + +status_t +init_hardware(void) +{ + dprintf("init_hardware\n"); + return B_OK; +} + +status_t +init_driver(void) +{ + dprintf("init_driver\n"); + return B_OK; +} + +void +uninit_driver(void) +{ + dprintf("uninit_driver\n"); +} + +static status_t +ich_open(const char *name, uint32 flags, void** cookie) +{ + return B_OK; +} + +static status_t +ich_close(void* cookie) +{ + return B_OK; +} + +static status_t +ich_free(void* cookie) +{ + return B_OK; +} + +static status_t +ich_control(void* cookie, uint32 op, void* arg, size_t len) +{ + return B_OK; +} + +static status_t +ich_read(void* cookie, off_t position, void *buf, size_t* num_bytes) +{ + *num_bytes = 0; + return B_IO_ERROR; +} + +static status_t +ich_write(void* cookie, off_t position, const void* buffer, size_t* num_bytes) +{ + *num_bytes = 0; + return B_IO_ERROR; +} + +static const char *ich_name[] = { + "audio/lala/ichaudio/1", + NULL +}; + +device_hooks ich_hooks = { + ich_open, + ich_close, + ich_free, + ich_control, + ich_read, + ich_write +}; + +const char** +publish_devices(void) +{ + dprintf("publish_devices\n"); + return ich_name; +} + +device_hooks* +find_device(const char* name) +{ + dprintf("find_device\n"); + return &ich_hooks; +} + diff --git a/src/add-ons/kernel/drivers/audio/ac97/ichaudio/lala/lala.h b/src/add-ons/kernel/drivers/audio/ac97/ichaudio/lala/lala.h new file mode 100644 index 0000000000..ceaad63ec5 --- /dev/null +++ b/src/add-ons/kernel/drivers/audio/ac97/ichaudio/lala/lala.h @@ -0,0 +1,48 @@ +#include +#include +#include +#include +#include + +typedef void 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; +} id_table_t; + +typedef status_t (*drv_attach) (drv_t *dev, void **cookie, int id_table_index); +typedef status_t (*drv_powerctl) (void *cookie); +typedef status_t (*drv_detach) (void *cookie); + +typedef struct +{ + id_table_t * table; + const char * basename; + drv_attach attach; + drv_detach detach; + drv_powerctl powerctl; +} driver_info_t; + +typedef struct +{ +} stream_info_t; + +extern driver_info_t driver_info; + +stream_id create_stream(drv_t *dev, stream_info_t *info); +status_t control_stream(drv_t *dev, stream_info_t *info); +status_t delete_stream(stream_id stream); + +control_id create_control_group(control_id parent, dev_t *dev); +control_id create_control(control_id parent, uint32 flags, void *get, void *set, const char *name); +