diff options
Diffstat (limited to 'sys/dev/asmc/asmc.c')
-rw-r--r-- | sys/dev/asmc/asmc.c | 127 |
1 files changed, 113 insertions, 14 deletions
diff --git a/sys/dev/asmc/asmc.c b/sys/dev/asmc/asmc.c index 099e7f1..5933307 100644 --- a/sys/dev/asmc/asmc.c +++ b/sys/dev/asmc/asmc.c @@ -77,6 +77,7 @@ static int asmc_key_read(device_t dev, const char *key, uint8_t *buf, uint8_t); static int asmc_fan_count(device_t dev); static int asmc_fan_getvalue(device_t dev, const char *key, int fan); +static int asmc_fan_setvalue(device_t dev, const char *key, int fan, int speed); static int asmc_temp_getvalue(device_t dev, const char *key); static int asmc_sms_read(device_t, const char *key, int16_t *val); static void asmc_sms_calibrate(device_t dev); @@ -94,6 +95,7 @@ static int asmc_key_dump(device_t, int); /* * Model functions. */ +static int asmc_mb_sysctl_fanid(SYSCTL_HANDLER_ARGS); static int asmc_mb_sysctl_fanspeed(SYSCTL_HANDLER_ARGS); static int asmc_mb_sysctl_fansafespeed(SYSCTL_HANDLER_ARGS); static int asmc_mb_sysctl_fanminspeed(SYSCTL_HANDLER_ARGS); @@ -115,6 +117,7 @@ struct asmc_model { int (*smc_sms_x)(SYSCTL_HANDLER_ARGS); int (*smc_sms_y)(SYSCTL_HANDLER_ARGS); int (*smc_sms_z)(SYSCTL_HANDLER_ARGS); + int (*smc_fan_id)(SYSCTL_HANDLER_ARGS); int (*smc_fan_speed)(SYSCTL_HANDLER_ARGS); int (*smc_fan_safespeed)(SYSCTL_HANDLER_ARGS); int (*smc_fan_minspeed)(SYSCTL_HANDLER_ARGS); @@ -134,7 +137,7 @@ static struct asmc_model *asmc_match(device_t dev); #define ASMC_SMS_FUNCS asmc_mb_sysctl_sms_x, asmc_mb_sysctl_sms_y, \ asmc_mb_sysctl_sms_z -#define ASMC_FAN_FUNCS asmc_mb_sysctl_fanspeed, asmc_mb_sysctl_fansafespeed, \ +#define ASMC_FAN_FUNCS asmc_mb_sysctl_fanid, asmc_mb_sysctl_fanspeed, asmc_mb_sysctl_fansafespeed, \ asmc_mb_sysctl_fanminspeed, \ asmc_mb_sysctl_fanmaxspeed, \ asmc_mb_sysctl_fantargetspeed @@ -196,6 +199,18 @@ struct asmc_model asmc_models[] = { ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, ASMC_LIGHT_FUNCS, ASMC_MBP4_TEMPS, ASMC_MBP4_TEMPNAMES, ASMC_MBP4_TEMPDESCS }, + + { + "MacBookPro8,2", "Apple SMC MacBook Pro (early 2011)", + ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, ASMC_LIGHT_FUNCS, + ASMC_MBP8_TEMPS, ASMC_MBP8_TEMPNAMES, ASMC_MBP8_TEMPDESCS + }, + + { + "MacBookPro11,3", "Apple SMC MacBook Pro Retina Core i7 (2013/2014)", + ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, ASMC_LIGHT_FUNCS, + ASMC_MBP11_TEMPS, ASMC_MBP11_TEMPNAMES, ASMC_MBP11_TEMPDESCS + }, /* The Mac Mini has no SMS */ { @@ -224,12 +239,27 @@ struct asmc_model asmc_models[] = { ASMC_MP_TEMPS, ASMC_MP_TEMPNAMES, ASMC_MP_TEMPDESCS }, + /* Idem for the MacPro 2010*/ + { + "MacPro5,1", "Apple SMC MacPro (2010)", + NULL, NULL, NULL, + ASMC_FAN_FUNCS, + NULL, NULL, NULL, + ASMC_MP5_TEMPS, ASMC_MP5_TEMPNAMES, ASMC_MP5_TEMPDESCS + }, + { "MacBookAir1,1", "Apple SMC MacBook Air", ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, NULL, NULL, NULL, ASMC_MBA_TEMPS, ASMC_MBA_TEMPNAMES, ASMC_MBA_TEMPDESCS }, + { + "MacBookAir3,1", "Apple SMC MacBook Air Core 2 Duo (Late 2010)", + ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, NULL, NULL, NULL, + ASMC_MBA3_TEMPS, ASMC_MBA3_TEMPNAMES, ASMC_MBA3_TEMPDESCS + }, + { NULL, NULL } }; @@ -361,6 +391,12 @@ asmc_attach(device_t dev) SYSCTL_ADD_PROC(sysctlctx, SYSCTL_CHILDREN(sc->sc_fan_tree[i]), + OID_AUTO, "id", CTLTYPE_STRING | CTLFLAG_RD, + dev, j, model->smc_fan_id, "I", + "Fan ID"); + + SYSCTL_ADD_PROC(sysctlctx, + SYSCTL_CHILDREN(sc->sc_fan_tree[i]), OID_AUTO, "speed", CTLTYPE_INT | CTLFLAG_RD, dev, j, model->smc_fan_speed, "I", "Fan speed in RPM"); @@ -375,21 +411,21 @@ asmc_attach(device_t dev) SYSCTL_ADD_PROC(sysctlctx, SYSCTL_CHILDREN(sc->sc_fan_tree[i]), OID_AUTO, "minspeed", - CTLTYPE_INT | CTLFLAG_RD, + CTLTYPE_INT | CTLFLAG_RW, dev, j, model->smc_fan_minspeed, "I", "Fan minimum speed in RPM"); SYSCTL_ADD_PROC(sysctlctx, SYSCTL_CHILDREN(sc->sc_fan_tree[i]), OID_AUTO, "maxspeed", - CTLTYPE_INT | CTLFLAG_RD, + CTLTYPE_INT | CTLFLAG_RW, dev, j, model->smc_fan_maxspeed, "I", "Fan maximum speed in RPM"); SYSCTL_ADD_PROC(sysctlctx, SYSCTL_CHILDREN(sc->sc_fan_tree[i]), OID_AUTO, "targetspeed", - CTLTYPE_INT | CTLFLAG_RD, + CTLTYPE_INT | CTLFLAG_RW, dev, j, model->smc_fan_targetspeed, "I", "Fan target speed in RPM"); } @@ -641,11 +677,10 @@ nosms: if (bootverbose) { /* - * XXX: The number of keys is a 32 bit buffer, but - * right now Apple only uses the last 8 bit. + * The number of keys is a 32 bit buffer */ asmc_key_read(dev, ASMC_NKEYS, buf, 4); - device_printf(dev, "number of keys: %d\n", buf[3]); + device_printf(dev, "number of keys: %d\n", ntohl(*(uint32_t*)buf)); } #ifdef DEBUG @@ -906,7 +941,7 @@ asmc_fan_count(device_t dev) { uint8_t buf[1]; - if (asmc_key_read(dev, ASMC_KEY_FANCOUNT, buf, 1) < 0) + if (asmc_key_read(dev, ASMC_KEY_FANCOUNT, buf, sizeof buf) < 0) return (-1); return (buf[0]); @@ -920,13 +955,46 @@ asmc_fan_getvalue(device_t dev, const char *key, int fan) char fankey[5]; snprintf(fankey, sizeof(fankey), key, fan); - if (asmc_key_read(dev, fankey, buf, 2) < 0) + if (asmc_key_read(dev, fankey, buf, sizeof buf) < 0) return (-1); speed = (buf[0] << 6) | (buf[1] >> 2); return (speed); } +static char* +asmc_fan_getstring(device_t dev, const char *key, int fan) +{ + uint8_t buf[16]; + char fankey[5]; + char* desc; + + snprintf(fankey, sizeof(fankey), key, fan); + if (asmc_key_read(dev, fankey, buf, sizeof buf) < 0) + return (NULL); + desc = buf+4; + + return (desc); +} + +static int +asmc_fan_setvalue(device_t dev, const char *key, int fan, int speed) +{ + uint8_t buf[2]; + char fankey[5]; + + speed *= 4; + + buf[0] = speed>>8; + buf[1] = speed; + + snprintf(fankey, sizeof(fankey), key, fan); + if (asmc_key_write(dev, fankey, buf, sizeof buf) < 0) + return (-1); + + return (0); +} + static int asmc_mb_sysctl_fanspeed(SYSCTL_HANDLER_ARGS) { @@ -942,6 +1010,22 @@ asmc_mb_sysctl_fanspeed(SYSCTL_HANDLER_ARGS) } static int +asmc_mb_sysctl_fanid(SYSCTL_HANDLER_ARGS) +{ + device_t dev = (device_t) arg1; + int fan = arg2; + int error = true; + char* desc; + + desc = asmc_fan_getstring(dev, ASMC_KEY_FANID, fan); + + if (desc != NULL) + error = sysctl_handle_string(oidp, desc, 0, req); + + return (error); +} + +static int asmc_mb_sysctl_fansafespeed(SYSCTL_HANDLER_ARGS) { device_t dev = (device_t) arg1; @@ -967,6 +1051,11 @@ asmc_mb_sysctl_fanminspeed(SYSCTL_HANDLER_ARGS) v = asmc_fan_getvalue(dev, ASMC_KEY_FANMINSPEED, fan); error = sysctl_handle_int(oidp, &v, 0, req); + if (error == 0 && req->newptr != NULL) { + unsigned int newspeed = *(unsigned int *)req->newptr; + asmc_fan_setvalue(dev, ASMC_KEY_FANMINSPEED, fan, newspeed); + } + return (error); } @@ -981,6 +1070,11 @@ asmc_mb_sysctl_fanmaxspeed(SYSCTL_HANDLER_ARGS) v = asmc_fan_getvalue(dev, ASMC_KEY_FANMAXSPEED, fan); error = sysctl_handle_int(oidp, &v, 0, req); + if (error == 0 && req->newptr != NULL) { + unsigned int newspeed = *(unsigned int *)req->newptr; + asmc_fan_setvalue(dev, ASMC_KEY_FANMAXSPEED, fan, newspeed); + } + return (error); } @@ -995,6 +1089,11 @@ asmc_mb_sysctl_fantargetspeed(SYSCTL_HANDLER_ARGS) v = asmc_fan_getvalue(dev, ASMC_KEY_FANTARGETSPEED, fan); error = sysctl_handle_int(oidp, &v, 0, req); + if (error == 0 && req->newptr != NULL) { + unsigned int newspeed = *(unsigned int *)req->newptr; + asmc_fan_setvalue(dev, ASMC_KEY_FANTARGETSPEED, fan, newspeed); + } + return (error); } @@ -1009,7 +1108,7 @@ asmc_temp_getvalue(device_t dev, const char *key) /* * Check for invalid temperatures. */ - if (asmc_key_read(dev, key, buf, 2) < 0) + if (asmc_key_read(dev, key, buf, sizeof buf) < 0) return (-1); return (buf[0]); @@ -1042,7 +1141,7 @@ asmc_sms_read(device_t dev, const char *key, int16_t *val) case 'X': case 'Y': case 'Z': - error = asmc_key_read(dev, key, buf, 2); + error = asmc_key_read(dev, key, buf, sizeof buf); break; default: device_printf(dev, "%s called with invalid argument %s\n", @@ -1197,7 +1296,7 @@ asmc_mbp_sysctl_light_left(SYSCTL_HANDLER_ARGS) int error; int32_t v; - asmc_key_read(dev, ASMC_KEY_LIGHTLEFT, buf, 6); + asmc_key_read(dev, ASMC_KEY_LIGHTLEFT, buf, sizeof buf); v = buf[2]; error = sysctl_handle_int(oidp, &v, sizeof(v), req); @@ -1212,7 +1311,7 @@ asmc_mbp_sysctl_light_right(SYSCTL_HANDLER_ARGS) int error; int32_t v; - asmc_key_read(dev, ASMC_KEY_LIGHTRIGHT, buf, 6); + asmc_key_read(dev, ASMC_KEY_LIGHTRIGHT, buf, sizeof buf); v = buf[2]; error = sysctl_handle_int(oidp, &v, sizeof(v), req); @@ -1236,7 +1335,7 @@ asmc_mbp_sysctl_light_control(SYSCTL_HANDLER_ARGS) v = level; buf[0] = level; buf[1] = 0x00; - asmc_key_write(dev, ASMC_KEY_LIGHTVALUE, buf, 2); + asmc_key_write(dev, ASMC_KEY_LIGHTVALUE, buf, sizeof buf); } return (error); |