Date: Sun, 21 Feb 2010 21:03:37 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r204179 - head/sys/powerpc/powermac Message-ID: <201002212103.o1LL3b2o037994@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: nwhitehorn Date: Sun Feb 21 21:03:37 2010 New Revision: 204179 URL: http://svn.freebsd.org/changeset/base/204179 Log: Fix several mistakes in this file, in order to allow individual fan speeds to be read and set correctly. Modified: head/sys/powerpc/powermac/smu.c Modified: head/sys/powerpc/powermac/smu.c ============================================================================== --- head/sys/powerpc/powermac/smu.c Sun Feb 21 21:03:15 2010 (r204178) +++ head/sys/powerpc/powermac/smu.c Sun Feb 21 21:03:37 2010 (r204179) @@ -58,6 +58,7 @@ struct smu_fan { cell_t max_rpm; cell_t unmanaged_rpm; char location[32]; + int old_style; }; struct smu_sensor { @@ -115,6 +116,7 @@ static void smu_cpufreq_pre_change(devic static void smu_cpufreq_post_change(device_t, const struct cf_level *level); /* utility functions */ +static int smu_run_cmd(device_t dev, struct smu_cmd *cmd); static int smu_get_datablock(device_t dev, int8_t id, uint8_t *buf, size_t len); static void smu_attach_fans(device_t dev, phandle_t fanroot); @@ -148,11 +150,12 @@ MALLOC_DEFINE(M_SMU, "smu", "SMU Sensor #define SMU_ADC 0xd8 #define SMU_FAN 0x4a #define SMU_I2C 0x9a -#define SMU_I2C_SIMPLE 0x00 -#define SMU_I2C_NORMAL 0x01 -#define SMU_I2C_COMBINED 0x02 +#define SMU_I2C_SIMPLE 0x00 +#define SMU_I2C_NORMAL 0x01 +#define SMU_I2C_COMBINED 0x02 #define SMU_MISC 0xee -#define SMU_MISC_GET_DATA 0x02 +#define SMU_MISC_GET_DATA 0x02 +#define SMU_MISC_LED_CTRL 0x04 #define SMU_POWER 0xaa /* Data blocks */ @@ -306,6 +309,7 @@ smu_run_cmd(device_t dev, struct smu_cmd powerpc_pow_enabled = oldpow; memcpy(cmd->data, sc->sc_cmd->data, sizeof(cmd->data)); + cmd->len = sc->sc_cmd->len; mtx_unlock(&sc->sc_mtx); @@ -430,21 +434,43 @@ static int smu_fan_set_rpm(device_t smu, struct smu_fan *fan, int rpm) { struct smu_cmd cmd; + int error; cmd.cmd = SMU_FAN; - cmd.len = 14; - cmd.data[0] = 0; - cmd.data[1] = 1 << fan->reg; + error = EIO; + + /* Clamp to allowed range */ + rpm = max(fan->min_rpm, rpm); + rpm = min(fan->max_rpm, rpm); /* - * There are two locations used for the fan speed. - * Store it in both. + * Apple has two fan control mechanisms. We can't distinguish + * them except by seeing if the new one fails. If the new one + * fails, use the old one. */ + + if (!fan->old_style) { + cmd.len = 4; + cmd.data[0] = 0x30; + cmd.data[1] = fan->reg; + cmd.data[2] = (rpm >> 8) & 0xff; + cmd.data[3] = rpm & 0xff; + + error = smu_run_cmd(smu, &cmd); + if (error) + fan->old_style = 1; + } - cmd.data[2] = cmd.data[2 + 2*fan->reg] = (rpm >> 8) & 0xff; - cmd.data[3] = cmd.data[3 + 2*fan->reg] = rpm & 0xff; + if (fan->old_style) { + cmd.len = 14; + cmd.data[0] = 0; + cmd.data[1] = 1 << fan->reg; + cmd.data[2 + 2*fan->reg] = (rpm >> 8) & 0xff; + cmd.data[3 + 2*fan->reg] = rpm & 0xff; + error = smu_run_cmd(smu, &cmd); + } - return (smu_run_cmd(smu, &cmd)); + return (error); } static int @@ -453,13 +479,12 @@ smu_fan_read_rpm(device_t smu, struct sm struct smu_cmd cmd; cmd.cmd = SMU_FAN; - cmd.len = 2; + cmd.len = 1; cmd.data[0] = 1; - cmd.data[1] = 1 << fan->reg; smu_run_cmd(smu, &cmd); - return ((cmd.data[1] << 8) | cmd.data[2]); + return ((cmd.data[fan->reg*2+1] << 8) | cmd.data[fan->reg*2+2]); } static int @@ -522,11 +547,15 @@ smu_attach_fans(device_t dev, phandle_t if (strcmp(type, "fan-rpm-control") != 0) continue; + fan->old_style = 0; OF_getprop(child, "reg", &fan->reg, sizeof(cell_t)); OF_getprop(child, "min-value", &fan->min_rpm, sizeof(cell_t)); OF_getprop(child, "max-value", &fan->max_rpm, sizeof(cell_t)); - OF_getprop(child, "unmanaged-value", &fan->unmanaged_rpm, - sizeof(cell_t)); + + if (OF_getprop(child, "unmanaged-value", &fan->unmanaged_rpm, + sizeof(cell_t)) != sizeof(cell_t)) + fan->unmanaged_rpm = fan->max_rpm; + OF_getprop(child, "location", fan->location, sizeof(fan->location)); @@ -661,8 +690,8 @@ smu_attach_sensors(device_t dev, phandle return; } - sc->sc_fans = malloc(sc->sc_nsensors * sizeof(struct smu_sensor), M_SMU, - M_WAITOK | M_ZERO); + sc->sc_sensors = malloc(sc->sc_nsensors * sizeof(struct smu_sensor), + M_SMU, M_WAITOK | M_ZERO); sens = sc->sc_sensors; sc->sc_nsensors = 0;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201002212103.o1LL3b2o037994>