* updated ac97 code with the one from Marcus' ich driver
* merged existing quirks (reversed amp enable and ad1981b) testing is welcome! git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25497 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
32f1d45867
commit
c27f3926a0
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Auich BeOS Driver for Intel Southbridge audio
|
* AC97 interface
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003, Jerome Duval (jerome.duval@free.fr)
|
|
||||||
*
|
|
||||||
* Original code : BeOS Driver for Intel ICH AC'97 Link interface
|
|
||||||
* Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
|
* Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
|
||||||
|
* Copyright (c) 2008, Jérôme Duval
|
||||||
*
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@ -31,9 +29,8 @@
|
|||||||
#ifndef _AC97_H_
|
#ifndef _AC97_H_
|
||||||
#define _AC97_H_
|
#define _AC97_H_
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
enum AC97_REGISTER {
|
enum AC97_REGISTER {
|
||||||
|
/* Baseline audio register set */
|
||||||
AC97_RESET = 0x00,
|
AC97_RESET = 0x00,
|
||||||
AC97_MASTER_VOLUME = 0x02,
|
AC97_MASTER_VOLUME = 0x02,
|
||||||
AC97_AUX_OUT_VOLUME = 0x04,
|
AC97_AUX_OUT_VOLUME = 0x04,
|
||||||
@ -54,27 +51,190 @@ enum AC97_REGISTER {
|
|||||||
AC97_3D_CONTROL = 0x22,
|
AC97_3D_CONTROL = 0x22,
|
||||||
AC97_PAGING = 0x24,
|
AC97_PAGING = 0x24,
|
||||||
AC97_POWERDOWN = 0x26,
|
AC97_POWERDOWN = 0x26,
|
||||||
AC97_EXTENDED_AUDIO_ID = 0x28,
|
|
||||||
AC97_EXTENDED_AUDIO_STATUS = 0x2A,
|
/* Extended audio register set */
|
||||||
AC97_PCM_FRONT_DAC_RATE = 0x2C,
|
AC97_EXTENDED_ID = 0x28,
|
||||||
|
AC97_EXTENDED_STAT_CTRL = 0x2A,
|
||||||
|
AC97_PCM_FRONT_DAC_RATE = 0x2C,
|
||||||
AC97_PCM_SURR_DAC_RATE = 0x2E,
|
AC97_PCM_SURR_DAC_RATE = 0x2E,
|
||||||
AC97_PCM_LFE_DAC_RATE = 0x30,
|
AC97_PCM_LFE_DAC_RATE = 0x30,
|
||||||
AC97_PCM_LR_ADC_RATE = 0x32,
|
AC97_PCM_L_R_ADC_RATE = 0x32,
|
||||||
AC97_MIC_ADC_RATE = 0x34,
|
AC97_MIC_ADC_RATE = 0x34,
|
||||||
AC97_CENTER_LFE_VOLUME = 0x36,
|
AC97_CENTER_LFE_VOLUME = 0x36,
|
||||||
AC97_SURROUND_VOLUME = 0x38,
|
AC97_SURR_VOLUME = 0x38,
|
||||||
AC97_SPDIF_CONTROL = 0x3A,
|
AC97_SPDIF_CONTROL = 0x3A,
|
||||||
AC97_AD_JACKSENSE = 0x72,
|
|
||||||
|
/* Vendor ID */
|
||||||
AC97_VENDOR_ID1 = 0x7C,
|
AC97_VENDOR_ID1 = 0x7C,
|
||||||
AC97_VENDOR_ID2 = 0x7E
|
AC97_VENDOR_ID2 = 0x7E,
|
||||||
|
|
||||||
|
/* Analog Devices */
|
||||||
|
AC97_AD_JACK_SENSE = 0x72,
|
||||||
|
AC97_AD_SERIAL_CONFIG = 0x74,
|
||||||
|
AC97_AD_MISC_CONTROL = 0x76,
|
||||||
|
AC97_AD_SAMPLE_RATE_0 = 0x78,
|
||||||
|
AC97_AD_SAMPLE_RATE_1 = 0x7a,
|
||||||
|
|
||||||
|
/* Realtek ALC650 */
|
||||||
|
AC97_ALC650_SPDIF_INPUT_CHAN_STATUS_LO = 0x60, /* only ALC650 Rev. E and later */
|
||||||
|
AC97_ALC650_SPDIF_INPUT_CHAN_STATUS_HI = 0x62, /* only ALC650 Rev. E and later */
|
||||||
|
AC97_ALC650_SURR_VOLUME = 0x64,
|
||||||
|
AC97_ALC650_CEN_LFE_VOLUME = 0x66,
|
||||||
|
AC97_ALC650_MULTI_CHAN_CTRL = 0x6A,
|
||||||
|
AC97_ALC650_MISC_CONTROL = 0x74,
|
||||||
|
AC97_ALC650_GPIO_SETUP = 0x76,
|
||||||
|
AC97_ALC650_GPIO_STATUS = 0x78,
|
||||||
|
AC97_ALC650_CLOCK_SOURCE = 0x7A
|
||||||
};
|
};
|
||||||
|
|
||||||
const char * ac97_get_3d_stereo_enhancement(device_config *config);
|
// AC97_EXTENDED_ID bits
|
||||||
const char * ac97_get_vendor_id_description(device_config *config);
|
enum {
|
||||||
uint32 ac97_get_vendor_id(device_config *config);
|
EXID_VRA = 0x0001,
|
||||||
void ac97_init(device_config *config);
|
EXID_DRA = 0x0002,
|
||||||
|
EXID_SPDIF = 0x0004,
|
||||||
|
EXID_VRM = 0x0008,
|
||||||
|
EXID_DSA0 = 0x0010,
|
||||||
|
EXID_DSA1 = 0x0020,
|
||||||
|
EXID_CDAC = 0x0040,
|
||||||
|
EXID_SDAC = 0x0080,
|
||||||
|
EXID_LDAC = 0x0100,
|
||||||
|
EXID_AMAP = 0x0200,
|
||||||
|
EXID_REV0 = 0x0400,
|
||||||
|
EXID_REV1 = 0x0800,
|
||||||
|
EXID_bit12 = 0x1000,
|
||||||
|
EXID_bit13 = 0x2000,
|
||||||
|
EXID_ID0 = 0x4000,
|
||||||
|
EXID_ID1 = 0x8000
|
||||||
|
};
|
||||||
|
|
||||||
void ac97_amp_enable(device_config *config, bool yesno);
|
// some codec_ids
|
||||||
|
enum {
|
||||||
|
CODEC_ID_ALC201A = 0x414c4710,
|
||||||
|
CODEC_ID_AK4540 = 0x414b4d00,
|
||||||
|
CODEC_ID_AK4542 = 0x414b4d01,
|
||||||
|
CODEC_ID_AK4543 = 0x414b4d02,
|
||||||
|
CODEC_ID_AD1819 = 0x41445303, // ok, AD1819A, AD1819B
|
||||||
|
CODEC_ID_AD1881 = 0x41445340, // ok, AD1881
|
||||||
|
CODEC_ID_AD1881A = 0x41445348, // ok, AD1881A
|
||||||
|
CODEC_ID_AD1885 = 0x41445360, // ok, AD1885
|
||||||
|
CODEC_ID_AD1886 = 0x41445361, // ok, AD1886
|
||||||
|
CODEC_ID_AD1886A = 0x41445363, // ok, AD1886A
|
||||||
|
CODEC_ID_AD1887 = 0x41445362, // ok, AD1887
|
||||||
|
CODEC_ID_AD1888 = 0x41445368, // ok, AD1888
|
||||||
|
CODEC_ID_AD1980 = 0x41445370, // ok, AD1980
|
||||||
|
CODEC_ID_AD1981B = 0x41445374, // ok, AD1981B
|
||||||
|
CODEC_ID_AD1985 = 0x41445375, // ok, AD1985
|
||||||
|
CODEC_ID_AD1986 = 0x41445378, // ok, AD1986
|
||||||
|
CODEC_ID_CS4299A = 0x43525931,
|
||||||
|
CODEC_ID_CS4299C = 0x43525933,
|
||||||
|
CODEC_ID_CS4299D = 0x43525934,
|
||||||
|
CODEC_ID_STAC9700 = 0x83847600, // ok, STAC9700
|
||||||
|
CODEC_ID_STAC9704 = 0x83847604, // STAC9701/03, STAC9704/07, STAC9705 (???)
|
||||||
|
CODEC_ID_STAC9705 = 0x83847605, // ???
|
||||||
|
CODEC_ID_STAC9708 = 0x83847608, // ok, STAC9708/11
|
||||||
|
CODEC_ID_STAC9721 = 0x83847609, // ok, STAC9721/23
|
||||||
|
CODEC_ID_STAC9744 = 0x83847644, // ok, STAC9744
|
||||||
|
CODEC_ID_STAC9752 = 0x83847652, // ok, STAC9752/53
|
||||||
|
CODEC_ID_STAC9756 = 0x83847656, // ok, STAC9756/57
|
||||||
|
CODEC_ID_STAC9766 = 0x83847666, // ok, STAC9766/67
|
||||||
|
};
|
||||||
|
|
||||||
|
// capabilities
|
||||||
|
enum ac97_capability {
|
||||||
|
CAP_PCM_MIC = 0x0000000000000001ULL, /* dedicated mic PCM channel */
|
||||||
|
CAP_BASS_TREBLE_CTRL = 0x0000000000000002ULL,
|
||||||
|
CAP_SIMULATED_STEREO = 0x0000000000000004ULL,
|
||||||
|
CAP_HEADPHONE_OUT = 0x0000000000000008ULL,
|
||||||
|
CAP_LAUDNESS = 0x0000000000000010ULL,
|
||||||
|
CAP_DAC_18BIT = 0x0000000000000020ULL,
|
||||||
|
CAP_DAC_20BIT = 0x0000000000000040ULL,
|
||||||
|
CAP_ADC_18BIT = 0x0000000000000080ULL,
|
||||||
|
CAP_ADC_20BIT = 0x0000000000000100ULL,
|
||||||
|
CAP_3D_ENHANCEMENT = 0x0000000000000200ULL,
|
||||||
|
CAP_VARIABLE_PCM = 0x0000000000000400ULL, /* variable rate PCM */
|
||||||
|
CAP_DOUBLE_PCM = 0x0000000000000800ULL, /* double rate PCM */
|
||||||
|
CAP_SPDIF = 0x0000000000001000ULL,
|
||||||
|
CAP_VARIABLE_MIC = 0x0000000000002000ULL, /* variable rate mic PCM */
|
||||||
|
CAP_CENTER_DAC = 0x0000000000004000ULL,
|
||||||
|
CAP_SURR_DAC = 0x0000000000008000ULL,
|
||||||
|
CAP_LFE_DAC = 0x0000000000010000ULL,
|
||||||
|
CAP_AMAP = 0x0000000000020000ULL,
|
||||||
|
CAP_REV21 = 0x0000000000040000ULL,
|
||||||
|
CAP_REV22 = 0x0000000000080000ULL,
|
||||||
|
CAP_REV23 = 0x0000000000100000ULL,
|
||||||
|
CAP_PCM_RATE_CONTINUOUS = 0x0000000000200000ULL,
|
||||||
|
CAP_PCM_RATE_8000 = 0x0000000000400000ULL,
|
||||||
|
CAP_PCM_RATE_11025 = 0x0000000000800000ULL,
|
||||||
|
CAP_PCM_RATE_12000 = 0x0000000001000000ULL,
|
||||||
|
CAP_PCM_RATE_16000 = 0x0000000002000000ULL,
|
||||||
|
CAP_PCM_RATE_22050 = 0x0000000004000000ULL,
|
||||||
|
CAP_PCM_RATE_24000 = 0x0000000008000000ULL,
|
||||||
|
CAP_PCM_RATE_32000 = 0x0000000010000000ULL,
|
||||||
|
CAP_PCM_RATE_44100 = 0x0000000020000000ULL,
|
||||||
|
CAP_PCM_RATE_48000 = 0x0000000040000000ULL,
|
||||||
|
CAP_PCM_RATE_88200 = 0x0000000080000000ULL,
|
||||||
|
CAP_PCM_RATE_96000 = 0x0000000100000000ULL,
|
||||||
|
CAP_PCM_RATE_MASK = ( CAP_PCM_RATE_CONTINUOUS | CAP_PCM_RATE_8000 | CAP_PCM_RATE_11025 |
|
||||||
|
CAP_PCM_RATE_12000 | CAP_PCM_RATE_16000 | CAP_PCM_RATE_22050 |
|
||||||
|
CAP_PCM_RATE_24000 | CAP_PCM_RATE_32000 | CAP_PCM_RATE_44100 |
|
||||||
|
CAP_PCM_RATE_48000 | CAP_PCM_RATE_88200 | CAP_PCM_RATE_96000)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ac97_dev;
|
||||||
|
typedef struct ac97_dev ac97_dev;
|
||||||
|
|
||||||
|
typedef void (* codec_init)(ac97_dev * dev);
|
||||||
|
typedef uint16 (* codec_reg_read)(void * cookie, uint8 reg);
|
||||||
|
typedef void (* codec_reg_write)(void * cookie, uint8 reg, uint16 value);
|
||||||
|
typedef bool (* codec_set_rate)(ac97_dev *dev, uint8 reg, uint32 rate);
|
||||||
|
typedef bool (* codec_get_rate)(ac97_dev *dev, uint8 reg, uint32 *rate);
|
||||||
|
|
||||||
|
struct ac97_dev {
|
||||||
|
uint16 reg_cache[0x7f];
|
||||||
|
|
||||||
|
void * cookie;
|
||||||
|
|
||||||
|
uint32 codec_id;
|
||||||
|
const char * codec_info;
|
||||||
|
const char * codec_3d_stereo_enhancement;
|
||||||
|
|
||||||
|
codec_init init;
|
||||||
|
codec_reg_read reg_read;
|
||||||
|
codec_reg_write reg_write;
|
||||||
|
codec_set_rate set_rate;
|
||||||
|
codec_get_rate get_rate;
|
||||||
|
|
||||||
|
uint32 max_vsr;
|
||||||
|
uint32 min_vsr;
|
||||||
|
uint32 clock;
|
||||||
|
uint64 capabilities;
|
||||||
|
bool reversed_eamp_polarity;
|
||||||
|
uint32 subsystem;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void ac97_attach(ac97_dev **dev, codec_reg_read reg_read, codec_reg_write reg_write, void *cookie,
|
||||||
|
ushort subvendor_id, ushort subsystem_id);
|
||||||
|
void ac97_detach(ac97_dev *dev);
|
||||||
|
void ac97_suspend(ac97_dev *dev);
|
||||||
|
void ac97_resume(ac97_dev *dev);
|
||||||
|
|
||||||
|
void ac97_reg_cached_write(ac97_dev *dev, uint8 reg, uint16 value);
|
||||||
|
uint16 ac97_reg_cached_read(ac97_dev *dev, uint8 reg);
|
||||||
|
void ac97_reg_uncached_write(ac97_dev *dev, uint8 reg, uint16 value);
|
||||||
|
uint16 ac97_reg_uncached_read(ac97_dev *dev, uint8 reg);
|
||||||
|
|
||||||
|
bool ac97_reg_update(ac97_dev *dev, uint8 reg, uint16 value);
|
||||||
|
bool ac97_reg_update_bits(ac97_dev *dev, uint8 reg, uint16 mask, uint16 value);
|
||||||
|
|
||||||
|
bool ac97_set_rate(ac97_dev *dev, uint8 reg, uint32 rate);
|
||||||
|
bool ac97_get_rate(ac97_dev *dev, uint8 reg, uint32 *rate);
|
||||||
|
|
||||||
|
bool ac97_has_capability(ac97_dev *dev, uint64 cap);
|
||||||
|
|
||||||
|
void ac97_set_clock(ac97_dev *dev, uint32 clock);
|
||||||
|
|
||||||
|
// multi support
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
B_MIX_GAIN = 1 << 0,
|
B_MIX_GAIN = 1 << 0,
|
||||||
|
@ -219,12 +219,12 @@ auich_stream_commit_parms(auich_stream *stream)
|
|||||||
(uint32)stream->dmaops_phy_base);
|
(uint32)stream->dmaops_phy_base);
|
||||||
|
|
||||||
if(stream->use & AUICH_USE_RECORD)
|
if(stream->use & AUICH_USE_RECORD)
|
||||||
auich_codec_write(&stream->card->config, AC97_PCM_LR_ADC_RATE, (uint16)stream->sample_rate);
|
auich_codec_write(&stream->card->config, AC97_PCM_L_R_ADC_RATE, (uint16)stream->sample_rate);
|
||||||
else
|
else
|
||||||
auich_codec_write(&stream->card->config, AC97_PCM_FRONT_DAC_RATE, (uint16)stream->sample_rate);
|
auich_codec_write(&stream->card->config, AC97_PCM_FRONT_DAC_RATE, (uint16)stream->sample_rate);
|
||||||
|
|
||||||
if(stream->use & AUICH_USE_RECORD)
|
if(stream->use & AUICH_USE_RECORD)
|
||||||
LOG(("rate : %d\n", auich_codec_read(&stream->card->config, AC97_PCM_LR_ADC_RATE)));
|
LOG(("rate : %d\n", auich_codec_read(&stream->card->config, AC97_PCM_L_R_ADC_RATE)));
|
||||||
else
|
else
|
||||||
LOG(("rate : %d\n", auich_codec_read(&stream->card->config, AC97_PCM_FRONT_DAC_RATE)));
|
LOG(("rate : %d\n", auich_codec_read(&stream->card->config, AC97_PCM_FRONT_DAC_RATE)));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@ -604,7 +604,7 @@ auich_setup(auich_dev * card)
|
|||||||
status_t err = B_OK;
|
status_t err = B_OK;
|
||||||
status_t rv;
|
status_t rv;
|
||||||
unsigned char cmd;
|
unsigned char cmd;
|
||||||
|
|
||||||
PRINT(("auich_setup(%p)\n", card));
|
PRINT(("auich_setup(%p)\n", card));
|
||||||
|
|
||||||
make_device_names(card);
|
make_device_names(card);
|
||||||
@ -664,12 +664,11 @@ auich_setup(auich_dev * card)
|
|||||||
LOG(("cold reset failed\n"));
|
LOG(("cold reset failed\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reset the codec */
|
/* attach the codec */
|
||||||
PRINT(("codec reset\n"));
|
PRINT(("codec attach\n"));
|
||||||
auich_codec_write(&card->config, 0x00, 0x0000);
|
ac97_attach(&card->config.ac97, (codec_reg_read)auich_codec_read,
|
||||||
snooze(50000); // 50 ms
|
(codec_reg_write)auich_codec_write, &card->config,
|
||||||
|
card->config.subvendor_id, card->config.subsystem_id);
|
||||||
ac97_init(&card->config);
|
|
||||||
|
|
||||||
rv = auich_reg_read_32(&card->config, AUICH_REG_GLOB_STA);
|
rv = auich_reg_read_32(&card->config, AUICH_REG_GLOB_STA);
|
||||||
if (!(rv & STA_S0CR)) { /* reset failure */
|
if (!(rv & STA_S0CR)) { /* reset failure */
|
||||||
@ -687,9 +686,9 @@ auich_setup(auich_dev * card)
|
|||||||
LOG(("6ch PCM output support\n"));
|
LOG(("6ch PCM output support\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
PRINT(("codec vendor id = %#08lx\n",ac97_get_vendor_id(&card->config)));
|
PRINT(("codec vendor id = %#08lx\n", card->config.ac97->codec_id));
|
||||||
PRINT(("codec description = %s\n",ac97_get_vendor_id_description(&card->config)));
|
PRINT(("codec description = %s\n", card->config.ac97->codec_info));
|
||||||
PRINT(("codec 3d enhancement = %s\n",ac97_get_3d_stereo_enhancement(&card->config)));
|
PRINT(("codec 3d enhancement = %s\n", card->config.ac97->codec_3d_stereo_enhancement));
|
||||||
|
|
||||||
if (current_settings.use_thread) {
|
if (current_settings.use_thread) {
|
||||||
int_thread_id = spawn_kernel_thread(auich_int_thread, "auich interrupt poller", B_REAL_TIME_PRIORITY, card);
|
int_thread_id = spawn_kernel_thread(auich_int_thread, "auich interrupt poller", B_REAL_TIME_PRIORITY, card);
|
||||||
@ -699,42 +698,6 @@ auich_setup(auich_dev * card)
|
|||||||
install_io_interrupt_handler(card->config.irq, auich_int, card, 0);
|
install_io_interrupt_handler(card->config.irq, auich_int, card, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*PRINT(("codec master output = %#04x\n",auich_codec_read(&card->config, 0x02)));
|
|
||||||
PRINT(("codec aux output = %#04x\n",auich_codec_read(&card->config, 0x04)));
|
|
||||||
PRINT(("codec mono output = %#04x\n",auich_codec_read(&card->config, 0x06)));
|
|
||||||
PRINT(("codec pcm output = %#04x\n",auich_codec_read(&card->config, 0x18)));
|
|
||||||
PRINT(("codec line in = %#04x\n",auich_codec_read(&card->config, 0x10)));
|
|
||||||
PRINT(("codec record line in= %#04x\n",auich_codec_read(&card->config, 0x1a)));
|
|
||||||
PRINT(("codec record gain = %#04x\n",auich_codec_read(&card->config, 0x1c)));*/
|
|
||||||
|
|
||||||
PRINT(("writing codec registers\n"));
|
|
||||||
|
|
||||||
// TODO : to move with AC97
|
|
||||||
/* enable master output */
|
|
||||||
auich_codec_write(&card->config, AC97_MASTER_VOLUME, 0x0000);
|
|
||||||
/* enable aux output */
|
|
||||||
auich_codec_write(&card->config, AC97_AUX_OUT_VOLUME, 0x0000);
|
|
||||||
/* enable mono output */
|
|
||||||
//auich_codec_write(&card->config, AC97_MONO_VOLUME, 0x0004);
|
|
||||||
/* enable pcm output */
|
|
||||||
auich_codec_write(&card->config, AC97_PCM_OUT_VOLUME, 0x0808);
|
|
||||||
/* enable line in */
|
|
||||||
//auich_codec_write(&card->config, AC97_LINE_IN_VOLUME, 0x8808);
|
|
||||||
/* set record line in */
|
|
||||||
auich_codec_write(&card->config, AC97_RECORD_SELECT, 0x0404);
|
|
||||||
/* set record gain */
|
|
||||||
//auich_codec_write(&card->config, AC97_RECORD_GAIN, 0x0000);
|
|
||||||
|
|
||||||
ac97_amp_enable(&card->config, true);
|
|
||||||
|
|
||||||
PRINT(("codec master output = %#04x\n",auich_codec_read(&card->config, AC97_MASTER_VOLUME)));
|
|
||||||
PRINT(("codec aux output = %#04x\n",auich_codec_read(&card->config, AC97_AUX_OUT_VOLUME)));
|
|
||||||
PRINT(("codec mono output = %#04x\n",auich_codec_read(&card->config, AC97_MONO_VOLUME)));
|
|
||||||
PRINT(("codec pcm output = %#04x\n",auich_codec_read(&card->config, AC97_PCM_OUT_VOLUME)));
|
|
||||||
PRINT(("codec line in = %#04x\n",auich_codec_read(&card->config, AC97_LINE_IN_VOLUME)));
|
|
||||||
PRINT(("codec record line in= %#04x\n",auich_codec_read(&card->config, AC97_RECORD_SELECT)));
|
|
||||||
PRINT(("codec record gain = %#04x\n",auich_codec_read(&card->config, AC97_RECORD_GAIN)));
|
|
||||||
|
|
||||||
if ((err = auich_init(card)))
|
if ((err = auich_init(card)))
|
||||||
return (err);
|
return (err);
|
||||||
|
|
||||||
@ -846,7 +809,8 @@ static void
|
|||||||
auich_shutdown(auich_dev *card)
|
auich_shutdown(auich_dev *card)
|
||||||
{
|
{
|
||||||
PRINT(("shutdown(%p)\n", card));
|
PRINT(("shutdown(%p)\n", card));
|
||||||
ac97_amp_enable(&card->config, false);
|
ac97_detach(card->config.ac97);
|
||||||
|
|
||||||
card->interrupt_mask = 0;
|
card->interrupt_mask = 0;
|
||||||
|
|
||||||
if (current_settings.use_thread) {
|
if (current_settings.use_thread) {
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
#ifndef _CONFIG_H_
|
#ifndef _CONFIG_H_
|
||||||
#define _CONFIG_H_
|
#define _CONFIG_H_
|
||||||
|
|
||||||
|
#include "ac97.h"
|
||||||
|
|
||||||
#define NUM_CARDS 3
|
#define NUM_CARDS 3
|
||||||
#define DEVNAME 32
|
#define DEVNAME 32
|
||||||
|
|
||||||
@ -49,6 +51,8 @@ typedef struct
|
|||||||
|
|
||||||
ushort subvendor_id;
|
ushort subvendor_id;
|
||||||
ushort subsystem_id;
|
ushort subsystem_id;
|
||||||
|
|
||||||
|
ac97_dev *ac97;
|
||||||
} device_config;
|
} device_config;
|
||||||
|
|
||||||
#define TYPE_ICH4 0x01
|
#define TYPE_ICH4 0x01
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
extern pci_module_info *pci;
|
extern pci_module_info *pci;
|
||||||
|
|
||||||
uint8
|
uint8
|
||||||
auich_reg_read_8(device_config *config, int regno)
|
auich_reg_read_8(device_config *config, uint8 regno)
|
||||||
{
|
{
|
||||||
ASSERT(regno >= 0);
|
ASSERT(regno >= 0);
|
||||||
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||||
@ -49,7 +49,7 @@ auich_reg_read_8(device_config *config, int regno)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint16
|
uint16
|
||||||
auich_reg_read_16(device_config *config, int regno)
|
auich_reg_read_16(device_config *config, uint8 regno)
|
||||||
{
|
{
|
||||||
ASSERT(regno >= 0);
|
ASSERT(regno >= 0);
|
||||||
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||||
@ -60,7 +60,7 @@ auich_reg_read_16(device_config *config, int regno)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
auich_reg_read_32(device_config *config, int regno)
|
auich_reg_read_32(device_config *config, uint8 regno)
|
||||||
{
|
{
|
||||||
ASSERT(regno >= 0);
|
ASSERT(regno >= 0);
|
||||||
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||||
@ -71,7 +71,7 @@ auich_reg_read_32(device_config *config, int regno)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
auich_reg_write_8(device_config *config, int regno, uint8 value)
|
auich_reg_write_8(device_config *config, uint8 regno, uint8 value)
|
||||||
{
|
{
|
||||||
ASSERT(regno >= 0);
|
ASSERT(regno >= 0);
|
||||||
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||||
@ -82,7 +82,7 @@ auich_reg_write_8(device_config *config, int regno, uint8 value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
auich_reg_write_16(device_config *config, int regno, uint16 value)
|
auich_reg_write_16(device_config *config, uint8 regno, uint16 value)
|
||||||
{
|
{
|
||||||
ASSERT(regno >= 0);
|
ASSERT(regno >= 0);
|
||||||
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||||
@ -93,7 +93,7 @@ auich_reg_write_16(device_config *config, int regno, uint16 value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
auich_reg_write_32(device_config *config, int regno, uint32 value)
|
auich_reg_write_32(device_config *config, uint8 regno, uint32 value)
|
||||||
{
|
{
|
||||||
ASSERT(regno >= 0);
|
ASSERT(regno >= 0);
|
||||||
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
|
||||||
@ -118,7 +118,7 @@ auich_codec_wait(device_config *config)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint16
|
uint16
|
||||||
auich_codec_read(device_config *config, int regno)
|
auich_codec_read(device_config *config, uint8 regno)
|
||||||
{
|
{
|
||||||
ASSERT(regno >= 0);
|
ASSERT(regno >= 0);
|
||||||
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255);
|
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255);
|
||||||
@ -134,7 +134,7 @@ auich_codec_read(device_config *config, int regno)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
auich_codec_write(device_config *config, int regno, uint16 value)
|
auich_codec_write(device_config *config, uint8 regno, uint16 value)
|
||||||
{
|
{
|
||||||
ASSERT(regno >= 0);
|
ASSERT(regno >= 0);
|
||||||
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255);
|
ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255);
|
||||||
|
@ -33,15 +33,15 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
uint8 auich_reg_read_8(device_config *config, int regno);
|
uint8 auich_reg_read_8(device_config *config, uint8 regno);
|
||||||
uint16 auich_reg_read_16(device_config *config, int regno);
|
uint16 auich_reg_read_16(device_config *config, uint8 regno);
|
||||||
uint32 auich_reg_read_32(device_config *config, int regno);
|
uint32 auich_reg_read_32(device_config *config, uint8 regno);
|
||||||
|
|
||||||
void auich_reg_write_8(device_config *config, int regno, uint8 value);
|
void auich_reg_write_8(device_config *config, uint8 regno, uint8 value);
|
||||||
void auich_reg_write_16(device_config *config, int regno, uint16 value);
|
void auich_reg_write_16(device_config *config, uint8 regno, uint16 value);
|
||||||
void auich_reg_write_32(device_config *config, int regno, uint32 value);
|
void auich_reg_write_32(device_config *config, uint8 regno, uint32 value);
|
||||||
|
|
||||||
|
uint16 auich_codec_read(device_config *config, uint8 regno);
|
||||||
|
void auich_codec_write(device_config *config, uint8 regno, uint16 value);
|
||||||
|
|
||||||
uint16 auich_codec_read(device_config *config, int regno);
|
|
||||||
void auich_codec_write(device_config *config, int regno, uint16 value);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -145,7 +145,7 @@ auich_ac97_set_mix(void *card, const void *cookie, int32 type, float *values) {
|
|||||||
value = auich_codec_read(&dev->config, info->reg);
|
value = auich_codec_read(&dev->config, info->reg);
|
||||||
value &= ~mask;
|
value &= ~mask;
|
||||||
value |= ((values[0] == 1.0 ? 1 : 0 ) << 15 & mask);
|
value |= ((values[0] == 1.0 ? 1 : 0 ) << 15 & mask);
|
||||||
if(info->reg == AC97_SURROUND_VOLUME) {
|
if(info->reg == AC97_SURR_VOLUME) {
|
||||||
// there is a independent mute for each channel
|
// there is a independent mute for each channel
|
||||||
mask = ((1 << 1) - 1) << 7;
|
mask = ((1 << 1) - 1) << 7;
|
||||||
value &= ~mask;
|
value &= ~mask;
|
||||||
|
Loading…
Reference in New Issue
Block a user