mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-08 00:21:46 +00:00
The spec does not mandate any way to read back the threshold settings
themselves, but when a threshold is crossed the AP needs a way to determine
which sensor(s) are responsible. Each reading of the EC_ACPI_MEM_TEMP_ID
register clears and returns one sensor ID that has crossed one of its
thresholds (in either direction) since the last read. A value of 0xFF means
"no new thresholds have tripped". Changing or enabling the thresholds for
any sensor will clear the unread event count for that sensor.
BUG=chrome-os-partner:23970
BRANCH=none
TEST=manual
On the host, set a couple of thresholds to low values so they trip
immediately (I'm testing on Link):
# dptf() {
[ "$#" -eq "2" ] || return;
iotools io_write8 0x66 0x81
iotools io_write8 0x62 $1
iotools io_write8 0x62 $2
}
#
# dptf 5 0
# dptf 6 10
# dptf 7 3
# dptf 5 2
# dptf 6 10
# dptf 7 2
On the EC console, see that two thresholds have triggered, and that there
are two bits set in the AP seen mask:
[45.755365 DPTF sensor 0, threshold -63 C, index 1, enabled]
[45.768940 DPTF sensor 2, threshold -63 C, index 0, enabled]
[46.169490 DPTF over threshold [0][1]
[46.169820 DPTF over threshold [2][0]
> dptftemp
sensor thresh0 thresh1
0 --- 210* I2C-USB C-Die
1 --- --- I2C-USB C-Object
2 210* --- I2C-PCH D-Die
3 --- --- I2C-PCH D-Object
4 --- --- I2C-Hinge C-Die
5 --- --- I2C-Hinge C-Object
6 --- --- I2C-Charger D-Die
7 --- --- I2C-Charger D-Object
8 --- --- ECInternal
9 --- --- PECI
AP seen mask: 0x00000005
>
Read the EC_ACPI_MEM_TEMP_ID register from the host, to get the two active
sensor IDs (0 and 2), then 0xff when those are seen.
# iotools io_write8 0x66 0x80; iotools io_write8 0x62 5; iotools io_read8 0x62
0x00
# iotools io_write8 0x66 0x80; iotools io_write8 0x62 5; iotools io_read8 0x62
0x02
# iotools io_write8 0x66 0x80; iotools io_write8 0x62 5; iotools io_read8 0x62
0xff
# iotools io_write8 0x66 0x80; iotools io_write8 0x62 5; iotools io_read8 0x62
0xff
#
Change-Id: I8f047a517357617f18ad59d21fa13409bc81821b
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/180224
Reviewed-by: Randall Spangler <rspangler@chromium.org>
146 lines
3.8 KiB
C
146 lines
3.8 KiB
C
/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "acpi.h"
|
|
#include "common.h"
|
|
#include "console.h"
|
|
#include "dptf.h"
|
|
#include "lpc.h"
|
|
#include "ec_commands.h"
|
|
#include "pwm.h"
|
|
|
|
/* Console output macros */
|
|
#define CPUTS(outstr) cputs(CC_LPC, outstr)
|
|
#define CPRINTF(format, args...) cprintf(CC_LPC, format, ## args)
|
|
|
|
static uint8_t acpi_cmd; /* Last received ACPI command */
|
|
static uint8_t acpi_addr; /* First byte of data after ACPI command */
|
|
static int acpi_data_count; /* Number of data writes after command */
|
|
static uint8_t acpi_mem_test; /* Test byte in ACPI memory space */
|
|
|
|
#ifdef CONFIG_TEMP_SENSOR
|
|
static int dptf_temp_sensor_id; /* last sensor ID written */
|
|
static int dptf_temp_threshold; /* last threshold written */
|
|
#endif
|
|
|
|
/* This handles AP writes to the EC via the ACPI I/O port. There are only a few
|
|
* ACPI commands (EC_CMD_ACPI_*), but they are all handled here.
|
|
*/
|
|
int acpi_ap_to_ec(int is_cmd, uint8_t value, uint8_t *resultptr)
|
|
{
|
|
int data = 0;
|
|
int retval = 0;
|
|
int result = 0xff; /* value for bogus read */
|
|
|
|
/* Read command/data; this clears the FRMH status bit. */
|
|
if (is_cmd) {
|
|
acpi_cmd = value;
|
|
acpi_data_count = 0;
|
|
} else {
|
|
data = value;
|
|
/*
|
|
* The first data byte is the ACPI memory address for
|
|
* read/write commands.
|
|
*/
|
|
if (!acpi_data_count++)
|
|
acpi_addr = data;
|
|
}
|
|
|
|
/* Process complete commands */
|
|
if (acpi_cmd == EC_CMD_ACPI_READ && acpi_data_count == 1) {
|
|
/* ACPI read cmd + addr */
|
|
switch (acpi_addr) {
|
|
case EC_ACPI_MEM_VERSION:
|
|
result = EC_ACPI_MEM_VERSION_CURRENT;
|
|
break;
|
|
case EC_ACPI_MEM_TEST:
|
|
result = acpi_mem_test;
|
|
break;
|
|
case EC_ACPI_MEM_TEST_COMPLIMENT:
|
|
result = 0xff - acpi_mem_test;
|
|
break;
|
|
#ifdef CONFIG_PWM_KBLIGHT
|
|
case EC_ACPI_MEM_KEYBOARD_BACKLIGHT:
|
|
result = pwm_get_duty(PWM_CH_KBLIGHT);
|
|
break;
|
|
#endif
|
|
#ifdef CONFIG_FANS
|
|
case EC_ACPI_MEM_FAN_DUTY:
|
|
result = dptf_get_fan_duty_target();
|
|
break;
|
|
#endif
|
|
#ifdef CONFIG_TEMP_SENSOR
|
|
case EC_ACPI_MEM_TEMP_ID:
|
|
result = dptf_query_next_sensor_event();
|
|
break;
|
|
#endif
|
|
default:
|
|
CPRINTF("[%T ACPI read 0x%02x (ignored)]\n", acpi_addr);
|
|
break;
|
|
}
|
|
|
|
/* Send the result byte */
|
|
*resultptr = result;
|
|
retval = 1;
|
|
|
|
} else if (acpi_cmd == EC_CMD_ACPI_WRITE && acpi_data_count == 2) {
|
|
/* ACPI write cmd + addr + data */
|
|
switch (acpi_addr) {
|
|
case EC_ACPI_MEM_TEST:
|
|
acpi_mem_test = data;
|
|
break;
|
|
#ifdef CONFIG_PWM_KBLIGHT
|
|
case EC_ACPI_MEM_KEYBOARD_BACKLIGHT:
|
|
/*
|
|
* Debug output with CR not newline, because the host
|
|
* does a lot of keyboard backlights and it scrolls the
|
|
* debug console.
|
|
*/
|
|
CPRINTF("\r[%T ACPI kblight %d]", data);
|
|
pwm_set_duty(PWM_CH_KBLIGHT, data);
|
|
break;
|
|
#endif
|
|
#ifdef CONFIG_FANS
|
|
case EC_ACPI_MEM_FAN_DUTY:
|
|
dptf_set_fan_duty_target(data);
|
|
break;
|
|
#endif
|
|
#ifdef CONFIG_TEMP_SENSOR
|
|
case EC_ACPI_MEM_TEMP_ID:
|
|
dptf_temp_sensor_id = data;
|
|
break;
|
|
case EC_ACPI_MEM_TEMP_THRESHOLD:
|
|
dptf_temp_threshold = data + EC_TEMP_SENSOR_OFFSET;
|
|
break;
|
|
case EC_ACPI_MEM_TEMP_COMMIT:
|
|
{
|
|
int idx = data & EC_ACPI_MEM_TEMP_COMMIT_SELECT_MASK;
|
|
int enable = data & EC_ACPI_MEM_TEMP_COMMIT_ENABLE_MASK;
|
|
dptf_set_temp_threshold(dptf_temp_sensor_id,
|
|
dptf_temp_threshold,
|
|
idx, enable);
|
|
break;
|
|
}
|
|
#endif
|
|
default:
|
|
CPRINTF("[%T ACPI write 0x%02x = 0x%02x (ignored)]\n",
|
|
acpi_addr, data);
|
|
break;
|
|
}
|
|
|
|
/* At the moment, ACPI implies LPC. */
|
|
#ifdef CONFIG_LPC
|
|
} else if (acpi_cmd == EC_CMD_ACPI_QUERY_EVENT && !acpi_data_count) {
|
|
/* Clear and return the lowest host event */
|
|
int evt_index = lpc_query_host_event_state();
|
|
CPRINTF("[%T ACPI query = %d]\n", evt_index);
|
|
*resultptr = evt_index;
|
|
retval = 1;
|
|
#endif
|
|
}
|
|
|
|
return retval;
|
|
}
|