Пример #1
0
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;
}
Пример #2
0
/* **********************************************************************
 * 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);
}
Пример #3
0
/* **********************************************************************
 * 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);
}
Пример #4
0
/* **********************************************************************
 * 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);
}
Пример #5
0
/*! **********************************************************************
 * 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;
    }
}
Пример #6
0
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);
}
Пример #7
0
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);
}