diff --git a/src/add-ons/kernel/drivers/audio/ac97/ali5451/Jamfile b/src/add-ons/kernel/drivers/audio/ac97/ali5451/Jamfile index 79c6288a99..c9dcff550b 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/ali5451/Jamfile +++ b/src/add-ons/kernel/drivers/audio/ac97/ali5451/Jamfile @@ -4,9 +4,13 @@ SetSubDirSupportedPlatformsBeOSCompatible ; UsePrivateHeaders media ; +SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) ] ; + KernelAddon ali5451 : driver.c ali_multi.c ali_hardware.c util.c + ac97.c ; diff --git a/src/add-ons/kernel/drivers/audio/ac97/ali5451/ali_hardware.c b/src/add-ons/kernel/drivers/audio/ac97/ali5451/ali_hardware.c index 09cf8b3ab1..25352f8be1 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/ali5451/ali_hardware.c +++ b/src/add-ons/kernel/drivers/audio/ac97/ali5451/ali_hardware.c @@ -11,6 +11,7 @@ #include #include +#include "ac97.h" #include "queue.h" #include "driver.h" #include "util.h" @@ -19,8 +20,6 @@ #define ALI_5451_V02 0x02 -#define ALI_AC97_CODEC_ID 0x41445374 -#define ALI_AC97_CAPS_HEAD 0x10 // ALI registers @@ -137,9 +136,10 @@ ac97_is_stimer_ready(ali_dev *card) } -uint16 -ac97_read(ali_dev *card, uint8 reg) +static uint16 +ac97_read(void *cookie, uint8 reg) { + ali_dev *card = (ali_dev *) cookie; uint32 ac_reg; ac_reg = (card->info.revision == ALI_5451_V02)?ALI_ACR0:ALI_ACR1; @@ -156,9 +156,10 @@ ac97_read(ali_dev *card, uint8 reg) } -void -ac97_write(ali_dev *card, uint8 reg, uint16 val) +static void +ac97_write(void *cookie, uint8 reg, uint16 val) { + ali_dev *card = (ali_dev *) cookie; uint32 dw_val; if (!ac97_is_ready(card, ALI_ACR0) || !ac97_is_stimer_ready(card)) @@ -172,46 +173,10 @@ ac97_write(ali_dev *card, uint8 reg, uint16 val) } -static bool -ac97_init(ali_dev *card) -{ - uint16 capabilities; - uint32 id; - - // ac97 reset - ac97_write(card, AC97_REG_POWER, 0); - ac97_write(card, AC97_REG_RESET, 0); - snooze(100000); - ac97_write(card, AC97_REG_POWER, 0); - ac97_write(card, AC97_REG_GEN, 0); - - capabilities = ac97_read(card, AC97_REG_RESET); - TRACE("ac97 capabilities: %04x\n", capabilities & 0x3ff); - - id = (uint32) ac97_read(card, AC97_REG_ID1) << 16 - | ac97_read(card, AC97_REG_ID2); - TRACE("ac97 id: %08x\n", (uint) id); - if (id != ALI_AC97_CODEC_ID) - return false; - - if ((capabilities & ALI_AC97_CAPS_HEAD) != 0) - ac97_write(card, AC97_JACK_SENSE, (uint16) 1 << 10); - // enable headphone jack sense - - // some sane default values - ac97_write(card, AC97_MIX_MASTER, 0x707); - ac97_write(card, AC97_MIX_PCM, 0x707); - ac97_write(card, AC97_MIX_HEADPHONE, 0x707); - - return true; -} - - static bool hardware_reset(ali_dev *card) { uint32 cmd_reg; - uint16 val; uint8 bval; // pci reset @@ -235,18 +200,6 @@ hardware_reset(ali_dev *card) io_write8(card, ALI_ACR2, bval); snooze(15000); - cmd_reg = 200; - while (cmd_reg--) { - val = ac97_read(card, AC97_REG_POWER); - if ((val & 0xf) == 0xf) - break; - snooze(5000); - } - if (cmd_reg == 0xffffffff) { - TRACE("hardware reset: not ready\n"); - return false; - } - return true; } @@ -271,8 +224,8 @@ hardware_init(ali_dev *card) UNLOCK(card->lock_hw); - if (!ac97_init(card)) - return B_ERROR; + ac97_attach(&card->codec, ac97_read, ac97_write, card, + card->info.u.h0.subsystem_vendor_id, card->info.u.h0.subsystem_id); TRACE("hardware init ok\n"); return B_OK; @@ -290,6 +243,8 @@ hardware_terminate(ali_dev *card) // clr voice interrupt flags UNLOCK(card->lock_hw); + + ac97_detach(card->codec); } diff --git a/src/add-ons/kernel/drivers/audio/ac97/ali5451/ali_hardware.h b/src/add-ons/kernel/drivers/audio/ac97/ali5451/ali_hardware.h index bf06a959d4..fa4ddbbaff 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/ali5451/ali_hardware.h +++ b/src/add-ons/kernel/drivers/audio/ac97/ali5451/ali_hardware.h @@ -8,32 +8,6 @@ #define _ALI_HARDWARE_H -// AC97 codec registers - -#define AC97_REG_RESET 0x00 -#define AC97_MIX_MASTER 0x02 -#define AC97_MIX_HEADPHONE 0x04 -#define AC97_MIX_MONO 0x06 -#define AC97_MIX_PHONE 0x0c -#define AC97_MIX_MIC 0x0e -#define AC97_MIX_LINEIN 0x10 -#define AC97_MIX_CD 0x12 -#define AC97_MIX_AUX 0x16 -#define AC97_MIX_PCM 0x18 -#define AC97_MIX_RECORDSELECT 0x1a -#define AC97_MIX_RECORDGAIN 0x1c -#define AC97_REG_GEN 0x20 -#define AC97_REG_POWER 0x26 -#define AC97_FRONT_DAC_SR 0x2c -#define AC97_ADC_RATE 0x32 -#define AC97_JACK_SENSE 0x72 -#define AC97_REG_ID1 0x7c -#define AC97_REG_ID2 0x7e - - -uint16 ac97_read(ali_dev *card, uint8 reg); -void ac97_write(ali_dev *card, uint8 reg, uint16 val); - status_t hardware_init(ali_dev *card); void hardware_terminate(ali_dev *card); diff --git a/src/add-ons/kernel/drivers/audio/ac97/ali5451/ali_multi.c b/src/add-ons/kernel/drivers/audio/ac97/ali5451/ali_multi.c index d7de416724..607cc5272e 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/ali5451/ali_multi.c +++ b/src/add-ons/kernel/drivers/audio/ac97/ali5451/ali_multi.c @@ -12,6 +12,7 @@ #include #include +#include "ac97.h" #include "queue.h" #include "driver.h" #include "util.h" @@ -63,14 +64,14 @@ typedef struct { #define ALI_ALL_MIXERS (ALI_OUTPUT_MIXERS + ALI_INPUT_MIXERS) static const ali_ac97_mixer_info ali_ac97_mixers[ALI_ALL_MIXERS] = { - {S_MASTER, NULL, AC97_MIX_MASTER, -46.5f, 0.0f, ALI_MIX_FT_STEREO | ALI_MIX_FT_MUTE}, - {S_WAVE, NULL, AC97_MIX_PCM, -34.5f, 12.0f, ALI_MIX_FT_STEREO | ALI_MIX_FT_MUTE}, - {S_HEADPHONE, NULL, AC97_MIX_HEADPHONE, -34.5f, 12.0f, ALI_MIX_FT_STEREO | ALI_MIX_FT_MUTE}, - {S_CD, NULL, AC97_MIX_CD, -34.5f, 12.0f, ALI_MIX_FT_STEREO | ALI_MIX_FT_MUTE}, - {S_LINE, NULL, AC97_MIX_LINEIN, -34.5f, 12.0f, ALI_MIX_FT_STEREO | ALI_MIX_FT_MUTE}, - {S_MIC, NULL, AC97_MIX_MIC, -34.5f, 12.0f, ALI_MIX_FT_MUTE | ALI_MIX_FT_MICBST}, - {S_AUX, NULL, AC97_MIX_AUX, -34.5f, 12.0f, ALI_MIX_FT_STEREO | ALI_MIX_FT_MUTE}, - {S_null, "Record", AC97_MIX_RECORDGAIN, 0.0f, 22.5f, + {S_MASTER, NULL, AC97_MASTER_VOLUME, -46.5f, 0.0f, ALI_MIX_FT_STEREO | ALI_MIX_FT_MUTE}, + {S_WAVE, NULL, AC97_PCM_OUT_VOLUME, -34.5f, 12.0f, ALI_MIX_FT_STEREO | ALI_MIX_FT_MUTE}, + {S_HEADPHONE, NULL, AC97_AUX_OUT_VOLUME, -34.5f, 12.0f, ALI_MIX_FT_STEREO | ALI_MIX_FT_MUTE}, + {S_CD, NULL, AC97_CD_VOLUME, -34.5f, 12.0f, ALI_MIX_FT_STEREO | ALI_MIX_FT_MUTE}, + {S_LINE, NULL, AC97_LINE_IN_VOLUME, -34.5f, 12.0f, ALI_MIX_FT_STEREO | ALI_MIX_FT_MUTE}, + {S_MIC, NULL, AC97_MIC_VOLUME, -34.5f, 12.0f, ALI_MIX_FT_MUTE | ALI_MIX_FT_MICBST}, + {S_AUX, NULL, AC97_AUX_IN_VOLUME, -34.5f, 12.0f, ALI_MIX_FT_STEREO | ALI_MIX_FT_MUTE}, + {S_null, "Record", AC97_RECORD_GAIN, 0.0f, 22.5f, ALI_MIX_FT_STEREO | ALI_MIX_FT_MUTE | ALI_MIX_FT_GAIN | ALI_MIX_FT_INSEL}, }; @@ -210,30 +211,32 @@ get_mix_mixer(ali_dev *card, multi_mix_value *mmv, int32 id) switch (gadget_id) { case ALI_MIX_MUTE_ID: - mmv->u.enable = ((ac97_read(card, mixer_info->reg) & 0x8000) - == 0x8000); + mmv->u.enable = ((ac97_reg_cached_read(card->codec, mixer_info->reg) + & 0x8000) == 0x8000); break; case ALI_MIX_LEFT_ID: case ALI_MIX_RIGHT_ID: { float val = (ALI_MIXER_GRANULARITY - * ((ac97_read(card, mixer_info->reg) >> - ((gadget_id==ALI_MIX_LEFT_ID)?8:0)) & 0x1f)); + * ((ac97_reg_cached_read(card->codec, mixer_info->reg) + >> ((gadget_id==ALI_MIX_LEFT_ID)?8:0)) & 0x1f)); mmv->u.gain = ((mixer_info->features&ALI_MIX_FT_GAIN) ? mixer_info->min_gain+val:mixer_info->max_gain-val); } break; case ALI_MIX_MIC_BOOST_ID: - mmv->u.enable = ((ac97_read(card, mixer_info->reg) & 0x40) == 0x40); + mmv->u.enable = ((ac97_reg_cached_read(card->codec, mixer_info->reg) + & 0x40) == 0x40); break; case ALI_MIX_INPUT_SELECTOR_ID: - mmv->u.mux = (ac97_read(card, AC97_MIX_RECORDSELECT) & 0x7); + mmv->u.mux = (ac97_reg_cached_read(card->codec, + AC97_RECORD_SELECT) & 0x7); if (ALI_MUX_INPUTS <= mmv->u.mux) { mmv->u.mux = 0x2; - ac97_write(card, AC97_MIX_RECORDSELECT, 0x202); + ac97_reg_cached_write(card->codec, AC97_RECORD_SELECT, 0x202); } break; } @@ -266,32 +269,32 @@ set_mix_mixer(ali_dev *card, multi_mix_value *mmv, int32 id) switch (gadget_id) { case ALI_MIX_MUTE_ID: - val = ac97_read(card, mixer_info->reg); + val = ac97_reg_cached_read(card->codec, mixer_info->reg); val = mmv->u.enable ? val | 0x8000 : val & 0x7fff; - ac97_write(card, mixer_info->reg, val); + ac97_reg_cached_write(card->codec, mixer_info->reg, val); break; case ALI_MIX_LEFT_ID: case ALI_MIX_RIGHT_ID: - val = ac97_read(card, mixer_info->reg); + val = ac97_reg_cached_read(card->codec, mixer_info->reg); val &= (gadget_id == ALI_MIX_LEFT_ID) ? 0x805f : 0x9f00; val |= (uint16) (((mixer_info->features&ALI_MIX_FT_GAIN) ? mixer_info->min_gain+mmv->u.gain : mixer_info->max_gain-mmv->u.gain) / ALI_MIXER_GRANULARITY) << ((gadget_id == ALI_MIX_LEFT_ID) ? 8 : 0); - ac97_write(card, mixer_info->reg, val); + ac97_reg_cached_write(card->codec, mixer_info->reg, val); break; case ALI_MIX_MIC_BOOST_ID: - val = ac97_read(card, mixer_info->reg); + val = ac97_reg_cached_read(card->codec, mixer_info->reg); val = mmv->u.enable ? val | 0x40 : val & 0xffbf; - ac97_write(card, mixer_info->reg, val); + ac97_reg_cached_write(card->codec, mixer_info->reg, val); break; case ALI_MIX_INPUT_SELECTOR_ID: val = (mmv->u.mux << 8) | mmv->u.mux; - ac97_write(card, AC97_MIX_RECORDSELECT, val); + ac97_reg_cached_write(card->codec, AC97_RECORD_SELECT, val); break; } } diff --git a/src/add-ons/kernel/drivers/audio/ac97/ali5451/driver.c b/src/add-ons/kernel/drivers/audio/ac97/ali5451/driver.c index db30a3ed88..1f7658cdd8 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/ali5451/driver.c +++ b/src/add-ons/kernel/drivers/audio/ac97/ali5451/driver.c @@ -13,6 +13,7 @@ #include #include +#include "ac97.h" #include "queue.h" #include "ali_multi.h" #include "driver.h" @@ -293,6 +294,7 @@ ali_setup(ali_dev *card) card->irq = card->info.u.h0.interrupt_line; TRACE("setup: irq is: %02x\n", card->irq); + card->codec = NULL; card->lock_hw = 0; card->lock_sts = 0; card->lock_voices = 0; diff --git a/src/add-ons/kernel/drivers/audio/ac97/ali5451/driver.h b/src/add-ons/kernel/drivers/audio/ac97/ali5451/driver.h index d86b2a90a9..108c1dc38b 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/ali5451/driver.h +++ b/src/add-ons/kernel/drivers/audio/ac97/ali5451/driver.h @@ -73,6 +73,8 @@ typedef struct _ali_dev ulong io_base; uint8 irq; + ac97_dev *codec; + spinlock lock_hw; spinlock lock_sts; spinlock lock_voices; diff --git a/src/add-ons/kernel/drivers/audio/ac97/ali5451/util.c b/src/add-ons/kernel/drivers/audio/ac97/ali5451/util.c index 58fa041cf6..eeeaa79fc4 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/ali5451/util.c +++ b/src/add-ons/kernel/drivers/audio/ac97/ali5451/util.c @@ -15,6 +15,7 @@ #include #include +#include "ac97.h" #include "queue.h" #include "driver.h" #include "util.h"