void acpi_ev_restore_acpi_state (void) { u32 index; FUNCTION_TRACE ("Ev_restore_acpi_state"); /* Restore the state of the chipset enable bits. */ if (acpi_gbl_restore_acpi_chipset == TRUE) { /* Restore the fixed events */ if (acpi_hw_register_read (ACPI_MTX_LOCK, PM1_EN) != acpi_gbl_pm1_enable_register_save) { acpi_hw_register_write (ACPI_MTX_LOCK, PM1_EN, acpi_gbl_pm1_enable_register_save); } /* Ensure that all status bits are clear */ acpi_hw_clear_acpi_status (); /* Now restore the GPEs */ for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe0blk_len); index++) { if (acpi_hw_register_read (ACPI_MTX_LOCK, GPE0_EN_BLOCK | index) != acpi_gbl_gpe0enable_register_save[index]) { acpi_hw_register_write (ACPI_MTX_LOCK, GPE0_EN_BLOCK | index, acpi_gbl_gpe0enable_register_save[index]); } } /* GPE 1 present? */ if (acpi_gbl_FADT->gpe1_blk_len) { for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe1_blk_len); index++) { if (acpi_hw_register_read (ACPI_MTX_LOCK, GPE1_EN_BLOCK | index) != acpi_gbl_gpe1_enable_register_save[index]) { acpi_hw_register_write (ACPI_MTX_LOCK, GPE1_EN_BLOCK | index, acpi_gbl_gpe1_enable_register_save[index]); } } } if (acpi_hw_get_mode() != acpi_gbl_original_mode) { acpi_hw_set_mode (acpi_gbl_original_mode); } } return_VOID; }
/* ********************************************************************** * Function: readTemp(void) * * Include: ADC.h * * Description: Reads the temperature from the TEMP sensor * * Arguments: None * * Returns: Temp (in deg celsius) as an unsigned char *************************************************************************/ unsigned char readTemp(void) { unsigned char temp; //Read the temperature from the x2 function temp = readTempx2(); //Divide the temp by two and return the result return DIV_2(temp); }
/* ********************************************************************** * Function: rawTemp(void) * * Include: Temp.h * * Description: Returns the raw (uncalibrated temperature) * * Arguments: None * * Returns: Temp (in deg celsius) as an unsigned char *************************************************************************/ unsigned char rawTemp(void) { return DIV_2(lastTempx2); }
/* ********************************************************************** * Function: calibrationTemp(unsigned char reference) * * Include: Temp.h * * Description: calibrates the temperature sensor by updating the calibration * offset variable * * Arguments: reference - Reference temperature in deg C * * Returns: None *************************************************************************/ void calibrateTemp(unsigned char reference) { calibration_offset = reference - DIV_2(lastTempx2); }
/*! ********************************************************************** * Function: fuseRange(unsigned int us, unsigned int ir) * * Include: Range.h * * Description: Fuses the IR and Ultrasonic ranges, and sets the target state * * Arguments: us - the Ultrasonic range (mm) * ir - the IR range (mm) * * Returns: the fused range * * Note: Also sets the current target state based on the reading from both * the IR and ultrsonic sensors *************************************************************************/ static unsigned int fuseRange(unsigned int us, unsigned int ir) { unsigned int range; //Store the range //Check which sensors have observed a target if (us && ir) { //Calibrate the sensors us += calibration_offset_US; ir += calibration_offset_IR; // CASE 1: Range: 150-450mm // Ignore US reading as it is inaccurate at these ranges if (us >= 150 && us <= 450) { range = ir; current_target_state = CLOSE_RANGE; } // CASE 2: Range: 1m - 1.5m // Don't trust the IR ranges much else if (us >= 1000 && ir >=1000) { /// @TODO Implement IR in here a little? range = us; current_target_state = OUT_OF_IR; } else { // CASE 3: Range: 450mm - 1m // Average the ultrasonic and IR ranges // TODO: Do we want to average these completely? range = DIV_2(us + ir); current_target_state = GOOD_TRACK; } } // CASE 4: Range: 1.5m+ // Rely on Ultrasound else if (us) { //Calibrate the ultrasonic range us += calibration_offset_US; range = us; //Check whether No IR is because out of IR range, or just bad direction if (range > 1500) current_target_state = OUT_OF_IR; else current_target_state = BAD_DIR; } else if (ir) { //Calibrate the IR range ir += calibration_offset_IR; range = ir; current_target_state = CLOSE_RANGE; } else { /// @TODO: Report Error? range = 0; current_target_state = NO_TARGET; } }
acpi_status acpi_hw_initialize ( void) { acpi_status status = AE_OK; u32 index; FUNCTION_TRACE ("Hw_initialize"); /* We must have the ACPI tables by the time we get here */ if (!acpi_gbl_FADT) { acpi_gbl_restore_acpi_chipset = FALSE; ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No FADT!\n")); return_ACPI_STATUS (AE_NO_ACPI_TABLES); } /* Identify current ACPI/legacy mode */ switch (acpi_gbl_system_flags & SYS_MODES_MASK) { case (SYS_MODE_ACPI): acpi_gbl_original_mode = SYS_MODE_ACPI; ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "System supports ACPI mode only.\n")); break; case (SYS_MODE_LEGACY): acpi_gbl_original_mode = SYS_MODE_LEGACY; ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Tables loaded from buffer, hardware assumed to support LEGACY mode only.\n")); break; case (SYS_MODE_ACPI | SYS_MODE_LEGACY): if (acpi_hw_get_mode () == SYS_MODE_ACPI) { acpi_gbl_original_mode = SYS_MODE_ACPI; } else { acpi_gbl_original_mode = SYS_MODE_LEGACY; } ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "System supports both ACPI and LEGACY modes.\n")); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "System is currently in %s mode.\n", (acpi_gbl_original_mode == SYS_MODE_ACPI) ? "ACPI" : "LEGACY")); break; } if (acpi_gbl_system_flags & SYS_MODE_ACPI) { /* Target system supports ACPI mode */ /* * The purpose of this code is to save the initial state * of the ACPI event enable registers. An exit function will be * registered which will restore this state when the application * exits. The exit function will also clear all of the ACPI event * status bits prior to restoring the original mode. * * The location of the PM1a_evt_blk enable registers is defined as the * base of PM1a_evt_blk + DIV_2(PM1a_evt_blk_length). Since the spec further * fully defines the PM1a_evt_blk to be a total of 4 bytes, the offset * for the enable registers is always 2 from the base. It is hard * coded here. If this changes in the spec, this code will need to * be modified. The PM1b_evt_blk behaves as expected. */ acpi_gbl_pm1_enable_register_save = (u16) acpi_hw_register_read ( ACPI_MTX_LOCK, PM1_EN); /* * The GPEs behave similarly, except that the length of the register * block is not fixed, so the buffer must be allocated with malloc */ if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) && acpi_gbl_FADT->gpe0blk_len) { /* GPE0 specified in FADT */ acpi_gbl_gpe0enable_register_save = ACPI_MEM_ALLOCATE ( DIV_2 (acpi_gbl_FADT->gpe0blk_len)); if (!acpi_gbl_gpe0enable_register_save) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Save state of GPE0 enable bits */ for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe0blk_len); index++) { acpi_gbl_gpe0enable_register_save[index] = (u8) acpi_hw_register_read (ACPI_MTX_LOCK, GPE0_EN_BLOCK | index); } } else { acpi_gbl_gpe0enable_register_save = NULL; } if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) && acpi_gbl_FADT->gpe1_blk_len) { /* GPE1 defined */ acpi_gbl_gpe1_enable_register_save = ACPI_MEM_ALLOCATE ( DIV_2 (acpi_gbl_FADT->gpe1_blk_len)); if (!acpi_gbl_gpe1_enable_register_save) { return_ACPI_STATUS (AE_NO_MEMORY); } /* save state of GPE1 enable bits */ for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe1_blk_len); index++) { acpi_gbl_gpe1_enable_register_save[index] = (u8) acpi_hw_register_read (ACPI_MTX_LOCK, GPE1_EN_BLOCK | index); } } else { acpi_gbl_gpe1_enable_register_save = NULL; } } return_ACPI_STATUS (status); }
acpi_status acpi_ev_gpe_initialize (void) { u32 i; u32 j; u32 register_index; u32 gpe_number; u16 gpe0register_count; u16 gpe1_register_count; FUNCTION_TRACE ("Ev_gpe_initialize"); /* * Set up various GPE counts * * You may ask,why are the GPE register block lengths divided by 2? * From the ACPI 2.0 Spec, section, 4.7.1.6 General-Purpose Event * Registers, we have, * * "Each register block contains two registers of equal length * GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the * GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN * The length of the GPE1_STS and GPE1_EN registers is equal to * half the GPE1_LEN. If a generic register block is not supported * then its respective block pointer and block length values in the * FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need * to be the same size." */ gpe0register_count = (u16) DIV_2 (acpi_gbl_FADT->gpe0blk_len); gpe1_register_count = (u16) DIV_2 (acpi_gbl_FADT->gpe1_blk_len); acpi_gbl_gpe_register_count = gpe0register_count + gpe1_register_count; if (!acpi_gbl_gpe_register_count) { REPORT_WARNING (("Zero GPEs are defined in the FADT\n")); return_ACPI_STATUS (AE_OK); } /* * Allocate the Gpe information block */ acpi_gbl_gpe_registers = ACPI_MEM_CALLOCATE (acpi_gbl_gpe_register_count * sizeof (acpi_gpe_registers)); if (!acpi_gbl_gpe_registers) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the Gpe_registers block\n")); return_ACPI_STATUS (AE_NO_MEMORY); } /* * Allocate the Gpe dispatch handler block * There are eight distinct GP events per register. * Initialization to zeros is sufficient */ acpi_gbl_gpe_info = ACPI_MEM_CALLOCATE (MUL_8 (acpi_gbl_gpe_register_count) * sizeof (acpi_gpe_level_info)); if (!acpi_gbl_gpe_info) { ACPI_MEM_FREE (acpi_gbl_gpe_registers); ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the Gpe_info block\n")); return_ACPI_STATUS (AE_NO_MEMORY); } /* Set the Gpe validation table to GPE_INVALID */ MEMSET (acpi_gbl_gpe_valid, (int) ACPI_GPE_INVALID, ACPI_NUM_GPE); /* * Initialize the Gpe information and validation blocks. A goal of these * blocks is to hide the fact that there are two separate GPE register sets * In a given block, the status registers occupy the first half, and * the enable registers occupy the second half. */ /* GPE Block 0 */ register_index = 0; for (i = 0; i < gpe0register_count; i++) { acpi_gbl_gpe_registers[register_index].status_addr = (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) + i); acpi_gbl_gpe_registers[register_index].enable_addr = (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) + i + gpe0register_count); acpi_gbl_gpe_registers[register_index].gpe_base = (u8) MUL_8 (i); for (j = 0; j < 8; j++) { gpe_number = acpi_gbl_gpe_registers[register_index].gpe_base + j; acpi_gbl_gpe_valid[gpe_number] = (u8) register_index; } /* * Clear the status/enable registers. Note that status registers * are cleared by writing a '1', while enable registers are cleared * by writing a '0'. */ acpi_os_write_port (acpi_gbl_gpe_registers[register_index].enable_addr, 0x00, 8); acpi_os_write_port (acpi_gbl_gpe_registers[register_index].status_addr, 0xFF, 8); register_index++; } /* GPE Block 1 */ for (i = 0; i < gpe1_register_count; i++) { acpi_gbl_gpe_registers[register_index].status_addr = (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) + i); acpi_gbl_gpe_registers[register_index].enable_addr = (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) + i + gpe1_register_count); acpi_gbl_gpe_registers[register_index].gpe_base = (u8) (acpi_gbl_FADT->gpe1_base + MUL_8 (i)); for (j = 0; j < 8; j++) { gpe_number = acpi_gbl_gpe_registers[register_index].gpe_base + j; acpi_gbl_gpe_valid[gpe_number] = (u8) register_index; } /* * Clear the status/enable registers. Note that status registers * are cleared by writing a '1', while enable registers are cleared * by writing a '0'. */ acpi_os_write_port (acpi_gbl_gpe_registers[register_index].enable_addr, 0x00, 8); acpi_os_write_port (acpi_gbl_gpe_registers[register_index].status_addr, 0xFF, 8); register_index++; } ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "GPE registers: %X@%8.8X%8.8X (Blk0) %X@%8.8X%8.8X (Blk1)\n", gpe0register_count, HIDWORD(acpi_gbl_FADT->Xgpe0blk.address), LODWORD(acpi_gbl_FADT->Xgpe0blk.address), gpe1_register_count, HIDWORD(acpi_gbl_FADT->Xgpe1_blk.address), LODWORD(acpi_gbl_FADT->Xgpe1_blk.address))); return_ACPI_STATUS (AE_OK); }