1) Improved detecting and handling AC97 VRA possibilites. Thanks to Maxim for testing;
2) Functionality of the handling the rate for AC97 Front PCM DAC added. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40327 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
38bda6536f
commit
a4f1824882
@ -175,7 +175,6 @@ Device::Open(uint32 flags)
|
||||
ERROR("Error of starting playback stream:%#010x\n", status);
|
||||
}
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,8 @@ public:
|
||||
static int32 InterruptHandler(void *interruptParam);
|
||||
void SignalReadyBuffers();
|
||||
|
||||
class Mixer& Mixer() { return fMixer; }
|
||||
|
||||
cpu_status Lock();
|
||||
void Unlock(cpu_status st);
|
||||
|
||||
@ -90,7 +92,7 @@ private:
|
||||
int32 fInterruptsNest;
|
||||
sem_id fBuffersReadySem;
|
||||
|
||||
Mixer fMixer;
|
||||
class Mixer fMixer;
|
||||
Stream fPlaybackStream;
|
||||
Stream fRecordStream;
|
||||
};
|
||||
|
@ -16,7 +16,7 @@
|
||||
#define MAX_DEVICES 3
|
||||
|
||||
|
||||
const char* const kVersion = "ver.2.0.0";
|
||||
const char* const kVersion = "2.0.2";
|
||||
|
||||
extern pci_module_info *gPCI;
|
||||
|
||||
|
@ -26,6 +26,7 @@ Mixer::Mixer(Device *device)
|
||||
fMaskRW(1 << 15),
|
||||
fMaskRD(1 << 15),
|
||||
fMaskWD(1 << 15),
|
||||
fHasVRA(false),
|
||||
fInputRates(0),
|
||||
fOutputRates(0),
|
||||
fInputFormats(0),
|
||||
@ -69,6 +70,25 @@ Mixer::Init()
|
||||
void
|
||||
Mixer::_ReadSupportedFormats()
|
||||
{
|
||||
fInputRates = B_SR_48000;
|
||||
fOutputRates = 0;
|
||||
fInputFormats = B_FMT_16BIT;
|
||||
fOutputFormats = B_FMT_16BIT;
|
||||
|
||||
uint16 extId = ac97_reg_cached_read(fAC97Dev, AC97_EXTENDED_ID);
|
||||
uint16 extCtrl = ac97_reg_cached_read(fAC97Dev, AC97_EXTENDED_STAT_CTRL);
|
||||
TRACE("Ext.ID:%#010x %#010x\n", extId, extCtrl);
|
||||
|
||||
fHasVRA = ((extId & EXID_VRA) == EXID_VRA);
|
||||
if (!fHasVRA) {
|
||||
fOutputRates = B_SR_8000 | B_SR_11025 | B_SR_12000
|
||||
| B_SR_16000 | B_SR_22050 | B_SR_24000
|
||||
| B_SR_32000 | B_SR_44100 | B_SR_48000;
|
||||
TRACE("VRA is not supported. Assume all rates are ok:%#010x\n",
|
||||
fOutputRates);
|
||||
return;
|
||||
}
|
||||
|
||||
struct _Cap {
|
||||
ac97_capability fCap;
|
||||
uint32 fRate;
|
||||
@ -89,9 +109,12 @@ Mixer::_ReadSupportedFormats()
|
||||
fOutputRates |= caps[i].fRate;
|
||||
}
|
||||
|
||||
fInputRates = B_SR_48000;
|
||||
fInputFormats = B_FMT_16BIT;
|
||||
fOutputFormats = B_FMT_16BIT;
|
||||
if(fOutputRates == 0) {
|
||||
ERROR("Output rates are not guessed. Force to 48 kHz.\n");
|
||||
fOutputRates = B_SR_48000;
|
||||
}
|
||||
|
||||
TRACE("Output rates are:%#010x\n", fOutputRates);
|
||||
}
|
||||
|
||||
|
||||
@ -195,6 +218,28 @@ Mixer::_WriteAC97(uint8 reg, uint16 data)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Mixer::SetOutputRate(uint32 outputRate)
|
||||
{
|
||||
if (!fHasVRA)
|
||||
return;
|
||||
|
||||
uint32 rate = 0;
|
||||
if (!ac97_get_rate(fAC97Dev, AC97_PCM_FRONT_DAC_RATE, &rate)) {
|
||||
ERROR("Failed to read PCM Front DAC Rate. Force to %d.\n", outputRate);
|
||||
} else
|
||||
if (rate == outputRate) {
|
||||
TRACE("AC97 PCM Front DAC rate not set to %d\n", outputRate);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ac97_set_rate(fAC97Dev, AC97_PCM_FRONT_DAC_RATE, rate))
|
||||
ERROR("Failed to set AC97 PCM Front DAC rate\n");
|
||||
else
|
||||
TRACE("AC97 PCM Front DAC rate set to %d\n", outputRate);
|
||||
}
|
||||
|
||||
|
||||
// Control ids are encoded in the following way:
|
||||
// GGBBRRTT --
|
||||
// GG - in gain controls: 10th of granularity. Signed!
|
||||
|
@ -35,6 +35,8 @@ public:
|
||||
uint32 InputFormats() { return fInputFormats; }
|
||||
uint32 OutputFormats() { return fOutputFormats; }
|
||||
|
||||
void SetOutputRate(uint32 rate);
|
||||
|
||||
private:
|
||||
void _ReadSupportedFormats();
|
||||
bool _WaitPortReady(uint8 reg, uint32 mask, uint32* result = NULL);
|
||||
@ -57,6 +59,7 @@ static void _WriteAC97(void* cookie, uint8 reg, uint16 data);
|
||||
uint32 fMaskRD;
|
||||
uint32 fMaskWD;
|
||||
|
||||
bool fHasVRA;
|
||||
uint32 fInputRates;
|
||||
uint32 fOutputRates;
|
||||
uint32 fInputFormats;
|
||||
|
@ -213,6 +213,9 @@ Stream::GetBuffers(uint32& Flags, int32& BuffersCount, int32& ChannelsCount,
|
||||
status_t
|
||||
Stream::Start()
|
||||
{
|
||||
if (!fIsInput)
|
||||
fDevice->Mixer().SetOutputRate(fFormat.cvsr);
|
||||
|
||||
uint32 CSO = 0;
|
||||
uint32 LBA = uint32(fBuffersPhysAddress) & 0x3fffffff;
|
||||
uint32 ESO = ((fBufferSamplesCount * 2) - 1) & 0xffff;
|
||||
@ -290,6 +293,7 @@ Stream::Start()
|
||||
|
||||
// start current channel
|
||||
fDevice->WritePCI32(_UseBankB() ? RegStartB : RegStartA, 1 << _HWVoice());
|
||||
fIsActive = true;
|
||||
|
||||
fDevice->Unlock(cst);
|
||||
|
||||
@ -297,8 +301,6 @@ Stream::Start()
|
||||
fIsInput ? "Rec" : "Play", CSO, LBA, ESO, Delta, FMControlEtc,
|
||||
ControlEtc, ChIntReg);
|
||||
|
||||
fIsActive = true;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -306,11 +308,15 @@ Stream::Start()
|
||||
status_t
|
||||
Stream::Stop()
|
||||
{
|
||||
if (!fIsActive)
|
||||
return B_OK;
|
||||
|
||||
cpu_status cst = fDevice->Lock();
|
||||
|
||||
// stop current channel
|
||||
fDevice->WritePCI32(_UseBankB() ? RegStopB : RegStopA, 1 << _HWVoice());
|
||||
|
||||
fIsActive = false;
|
||||
|
||||
if (_HWId() == ALi5451 && fIsInput) {
|
||||
uint32 reg = fDevice->ReadPCI32(RegALiDigiMixer);
|
||||
fDevice->WritePCI32(RegALiDigiMixer, reg & ~(1 << _HWVoice()));
|
||||
@ -320,8 +326,6 @@ Stream::Stop()
|
||||
|
||||
TRACE("%s:OK\n", fIsInput ? "Rec" : "Play");
|
||||
|
||||
fIsActive = false;
|
||||
|
||||
fBufferCycle = fIsInput ? 1 : 0;
|
||||
|
||||
return B_OK;
|
||||
|
@ -35,6 +35,7 @@ public:
|
||||
void ExchangeBuffers(bigtime_t& RealTime,
|
||||
bigtime_t& FramesCount,
|
||||
int32& BufferCycle);
|
||||
|
||||
void GetFormat(multi_format_info *Format);
|
||||
status_t SetFormat(_multi_format& format,
|
||||
uint32 formats, uint32 rates);
|
||||
|
Loading…
Reference in New Issue
Block a user