Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/macppc/dev add support for the CPU temperature sens...
details: https://anonhg.NetBSD.org/src/rev/1cf2f98110cd
branches: trunk
changeset: 953443:1cf2f98110cd
user: macallan <macallan%NetBSD.org@localhost>
date: Tue Mar 09 01:17:37 2021 +0000
description:
add support for the CPU temperature sensor found in iMac G5s
diffstat:
sys/arch/macppc/dev/smu.c | 70 ++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 66 insertions(+), 4 deletions(-)
diffs (143 lines):
diff -r e644f1e4d296 -r 1cf2f98110cd sys/arch/macppc/dev/smu.c
--- a/sys/arch/macppc/dev/smu.c Tue Mar 09 00:08:04 2021 +0000
+++ b/sys/arch/macppc/dev/smu.c Tue Mar 09 01:17:37 2021 +0000
@@ -80,7 +80,7 @@
#define SMU_MAX_FANS 8
#define SMU_MAX_IICBUS 3
-#define SMU_MAX_SME_SENSORS SMU_MAX_FANS
+#define SMU_MAX_SME_SENSORS (SMU_MAX_FANS + 8)
struct smu_zone {
bool (*filter)(const envsys_data_t *);
@@ -120,6 +120,8 @@
struct sysmon_envsys *sc_sme;
envsys_data_t sc_sme_sensors[SMU_MAX_SME_SENSORS];
+ uint32_t cpu_m;
+ int32_t cpu_b;
struct smu_zone sc_zones[SMU_ZONES];
lwp_t *sc_thread;
@@ -130,7 +132,7 @@
#define SMU_CMD_RTC 0x8e
#define SMU_CMD_I2C 0x9a
#define SMU_CMD_POWER 0xaa
-#define SMU_ADC 0xd8
+#define SMU_CMD_ADC 0xd8
#define SMU_MISC 0xee
#define SMU_MISC_GET_DATA 0x02
#define SMU_MISC_LED_CTRL 0x04
@@ -165,6 +167,8 @@
static int smu_fan_update_rpm(struct smu_fan *);
static int smu_fan_get_rpm(struct smu_fan *, int *);
static int smu_fan_set_rpm(struct smu_fan *, int);
+static int smu_read_adc(struct smu_softc *, int);
+
static int smu_iicbus_exec(void *, i2c_op_t, i2c_addr_t, const void *,
size_t, void *, size_t, int);
static int smu_sysctl_fan_rpm(SYSCTLFN_ARGS);
@@ -199,6 +203,7 @@
{
struct confargs *ca = aux;
struct smu_softc *sc = device_private(self);
+ uint16_t data[4];
sc->sc_dev = self;
sc->sc_node = ca->ca_node;
@@ -227,6 +232,13 @@
sc->sc_todr.cookie = sc;
todr_attach(&sc->sc_todr);
+ /* calibration data */
+ memset(data, 0, 8);
+ smu_get_datablock(SMU_CPUTEMP_CAL, (void *)data, 8);
+ DPRINTF("data %04x %04x %04x %04x\n", data[0], data[1], data[2], data[3]);
+ sc->cpu_m = data[2];
+ sc->cpu_b = (int16_t)data[3];
+
smu_setup_sme(sc);
smu_setup_zones(sc);
@@ -476,7 +488,8 @@
{
struct smu_fan *fan;
envsys_data_t *sme_sensor;
- int i;
+ int i, sensors, child, reg;
+ char loc[32], type[32];
sc->sc_sme = sysmon_envsys_create();
@@ -494,7 +507,26 @@
return;
}
}
-
+ sensors = OF_finddevice("/smu/sensors");
+ child = OF_child(sensors);
+ while (child != 0) {
+ sme_sensor = &sc->sc_sme_sensors[i];
+ if (OF_getprop(child, "location", loc, 32) == 0) goto next;
+ if (OF_getprop(child, "device_type", type, 32) == 0) goto next;
+ if (OF_getprop(child, "reg", ®, 4) == 0) goto next;
+ if (strcmp(type, "temp-sensor") == 0) {
+ sme_sensor->units = ENVSYS_STEMP;
+ sme_sensor->state = ENVSYS_SINVALID;
+ strncpy(sme_sensor->desc, loc, sizeof(sme_sensor->desc));
+ sme_sensor->private = reg;
+ sysmon_envsys_sensor_attach(sc->sc_sme, sme_sensor);
+ i++;
+ printf("%s: %s@%x\n", loc, type, reg);
+ }
+next:
+ child = OF_peer(child);
+ }
+
sc->sc_sme->sme_name = device_xname(sc->sc_dev);
sc->sc_sme->sme_cookie = sc;
sc->sc_sme->sme_refresh = smu_sme_refresh;
@@ -535,6 +567,19 @@
edata->value_cur = fan->current_rpm;
edata->state = ENVSYS_SVALID;
}
+ } else if (edata->private > 0) {
+ /* this works only for the CPU diode */
+ int64_t r = smu_read_adc(sc, edata->private);
+ if (r != -1) {
+ r = r * sc->cpu_m;
+ r >>= 3;
+ r += (int64_t)sc->cpu_b << 9;
+ r <<= 1;
+ r *= 15625;
+ r /= 1024;
+ edata->value_cur = r + 273150000;
+ edata->state = ENVSYS_SVALID;
+ }
}
}
@@ -771,6 +816,23 @@
}
static int
+smu_read_adc(struct smu_softc *sc, int id)
+{
+ struct smu_cmd cmd;
+ int ret;
+
+ cmd.cmd = SMU_CMD_ADC;
+ cmd.len = 1;
+ cmd.data[0] = id;
+
+ ret = smu_do_cmd(sc, &cmd, 800);
+ if (ret == 0) {
+ return cmd.data[0] << 8 | cmd.data[1];
+ }
+ return -1;
+}
+
+static int
smu_iicbus_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *send,
size_t send_len, void *recv, size_t recv_len, int flags)
{
Home |
Main Index |
Thread Index |
Old Index