changed reset handling, we no longer perform a cold reset, as this disabled audio output on some notebooks
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6911 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -461,6 +461,8 @@ ich_clock_calibrate()
|
|||||||
status_t
|
status_t
|
||||||
init_driver(void)
|
init_driver(void)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
uint32 val;
|
||||||
status_t rv;
|
status_t rv;
|
||||||
bigtime_t start;
|
bigtime_t start;
|
||||||
bool s0cr, s1cr, s2cr;
|
bool s0cr, s1cr, s2cr;
|
||||||
@@ -490,32 +492,58 @@ init_driver(void)
|
|||||||
|
|
||||||
dump_hardware_regs();
|
dump_hardware_regs();
|
||||||
|
|
||||||
/* do a cold reset */
|
/* We don't do a cold reset here, because this would reset general purpose
|
||||||
LOG(("cold reset\n"));
|
* IO pins of the controller. These pins can be used by the machine vendor
|
||||||
ich_reg_write_32(ICH_REG_GLOB_CNT, 0);
|
* to control external amplifiers, and resetting them prevents audio output
|
||||||
|
* on some notebooks, like "Compaq Presario 2700".
|
||||||
|
* If a cold reset is still in progress, we need to finish it.
|
||||||
|
* We perform a warm reset, this should be save to do, as it is required
|
||||||
|
* to leave some power down modes.
|
||||||
|
*/
|
||||||
|
val = ich_reg_read_32(ICH_REG_GLOB_CNT);
|
||||||
|
if ((val & CNT_COLD) == 0) {
|
||||||
|
LOG(("finishing cold reset\n"));
|
||||||
|
// need to write 1-bit to finish cold reset
|
||||||
|
val |= CNT_COLD;
|
||||||
|
} else {
|
||||||
|
LOG(("performing warm reset\n"));
|
||||||
|
// need to write 1-bit to start warm reset
|
||||||
|
val |= CNT_WARM;
|
||||||
|
}
|
||||||
|
val &= ~CNT_SHUT; // enable AC-link
|
||||||
|
ich_reg_write_32(ICH_REG_GLOB_CNT, val);
|
||||||
ich_reg_read_32(ICH_REG_GLOB_CNT); // force PCI-to-PCI bridge cache flush
|
ich_reg_read_32(ICH_REG_GLOB_CNT); // force PCI-to-PCI bridge cache flush
|
||||||
snooze(50000); // 50 ms
|
// wait up to 1 second for warm reset to be finished
|
||||||
ich_reg_write_32(ICH_REG_GLOB_CNT, CNT_COLD | CNT_PRIE);
|
for (i = 0; i < 20; i++) {
|
||||||
LOG(("cold reset finished\n"));
|
if ((ich_reg_read_32(ICH_REG_GLOB_CNT) & CNT_WARM) == 0)
|
||||||
rv = ich_reg_read_32(ICH_REG_GLOB_CNT);
|
break;
|
||||||
if ((rv & CNT_COLD) == 0) {
|
snooze(50000);
|
||||||
|
}
|
||||||
|
if ((ich_reg_read_32(ICH_REG_GLOB_CNT) & CNT_COLD) == 0) {
|
||||||
LOG(("cold reset failed\n"));
|
LOG(("cold reset failed\n"));
|
||||||
|
unmap_io_memory();
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
if ((ich_reg_read_32(ICH_REG_GLOB_CNT) & CNT_WARM) != 0) {
|
||||||
|
LOG(("warm reset failed\n"));
|
||||||
|
unmap_io_memory();
|
||||||
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* detect which codecs are ready */
|
/* detect which codecs are ready */
|
||||||
s0cr = s1cr = s2cr = false;
|
s0cr = s1cr = s2cr = false;
|
||||||
start = system_time();
|
start = system_time();
|
||||||
do {
|
do {
|
||||||
rv = ich_reg_read_32(ICH_REG_GLOB_STA);
|
val = ich_reg_read_32(ICH_REG_GLOB_STA);
|
||||||
if (!s0cr && (rv & STA_S0CR)) {
|
if (!s0cr && (val & STA_S0CR)) {
|
||||||
s0cr = true;
|
s0cr = true;
|
||||||
LOG(("AC_SDIN0 codec ready after %Ld us\n",(system_time() - start)));
|
LOG(("AC_SDIN0 codec ready after %Ld us\n",(system_time() - start)));
|
||||||
}
|
}
|
||||||
if (!s1cr && (rv & STA_S1CR)) {
|
if (!s1cr && (val & STA_S1CR)) {
|
||||||
s1cr = true;
|
s1cr = true;
|
||||||
LOG(("AC_SDIN1 codec ready after %Ld us\n",(system_time() - start)));
|
LOG(("AC_SDIN1 codec ready after %Ld us\n",(system_time() - start)));
|
||||||
}
|
}
|
||||||
if (!s2cr && (rv & STA_S2CR)) {
|
if (!s2cr && (val & STA_S2CR)) {
|
||||||
s2cr = true;
|
s2cr = true;
|
||||||
LOG(("AC_SDIN2 codec ready after %Ld us\n",(system_time() - start)));
|
LOG(("AC_SDIN2 codec ready after %Ld us\n",(system_time() - start)));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user