Revision: 41 Author: nboichat Date: 2006-08-16 19:11:17 -0700 (Wed, 16 Aug 2006) ViewCVS: http://svn.sourceforge.net/mactel-linux/?rev=41&view=rev
Log Message: ----------- Add SMC debug tools. Added Paths: ----------- trunk/tools/smc-tools/ trunk/tools/smc-tools/Makefile trunk/tools/smc-tools/README trunk/tools/smc-tools/applesmc.c trunk/tools/smc-tools/mbp.out.valid.2 Added: trunk/tools/smc-tools/Makefile =================================================================== --- trunk/tools/smc-tools/Makefile (rev 0) +++ trunk/tools/smc-tools/Makefile 2006-08-17 02:11:17 UTC (rev 41) @@ -0,0 +1,20 @@ +VERSION=0.1.1 + +all: applesmc + +applesmc: applesmc.c Makefile + gcc -DVERSION=\"$(VERSION)\" -Wall applesmc.c -o applesmc -g + +install: applesmc + install -s -m 4755 applesmc /usr/local/bin + +clean: + rm -f applesmc + rm -f *~ + +package: clean + rm -rf macbook-tools-$(VERSION) + rm -rf macbook-tools-$(VERSION).tar.bz2 + mkdir macbook-tools-$(VERSION) + cp *.c Makefile Changelog macbook-tools-$(VERSION) + tar cvfj macbook-tools-$(VERSION).tar.bz2 macbook-tools-$(VERSION) Added: trunk/tools/smc-tools/README =================================================================== --- trunk/tools/smc-tools/README (rev 0) +++ trunk/tools/smc-tools/README 2006-08-17 02:11:17 UTC (rev 41) @@ -0,0 +1 @@ +SMC debug tool. All non-debug things should go in the kernel. Added: trunk/tools/smc-tools/applesmc.c =================================================================== --- trunk/tools/smc-tools/applesmc.c (rev 0) +++ trunk/tools/smc-tools/applesmc.c 2006-08-17 02:11:17 UTC (rev 41) @@ -0,0 +1,303 @@ +/* + * Apple Macbook Pro SMC control + * + * Copyright (C) 2006 Nicolas Boichat <[EMAIL PROTECTED]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <stdio.h> +#include <sys/io.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/time.h> + +#define LIGHT_SENSOR_LEFT_KEY "ALV0" //0x414c5630, r-o length 6 +#define LIGHT_SENSOR_RIGHT_KEY "ALV1" //0x414c5631, r-o length 6 +#define BACKLIGHT_KEY "LKSB" //0x4c4b5342, w-o +#define CLAMSHELL_KEY "MSLD" //0x4d534c44, r-o length 1 (unused) +#define MOTION_SENSOR_X_KEY "MO_X" //0x4d4f5f58, r-o length 2 +#define MOTION_SENSOR_Y_KEY "MO_Y" //0x4d4f5f58, r-o length 2 +#define MOTION_SENSOR_Z_KEY "MO_Z" //0x4d4f5f58, r-o length 2 +#define MOTION_SENSOR_KEY "MOCN" //0x4d4f434e, r/w length 2 + + +static int debug = 0; + +static struct timeval lasttv; +static struct timeval newtv; + +void inline ssleep(const int usec) { + gettimeofday(&lasttv, NULL); + while (1) { + gettimeofday(&newtv, NULL); + if (((newtv.tv_usec - lasttv.tv_usec) + ((newtv.tv_sec - lasttv.tv_sec)*1000000)) > usec) { + break; + } + } +} + +unsigned char get_status() { + return inb(0x304); +} + +int waitfree(char num) { + char c, pc = -1; + int retry = 100; + while (((c = get_status())&0x0F) != num && retry) { + ssleep(10); + retry--; + if (pc != c) { + //printf("%x-%d:", c, retry); + pc = c; + } + } + if (retry == 0) { + printf("Waitfree failed %x != %x.\n", c, num); + return 0; + } + /*else + printf("Waitfree ok %x.\n", c);*/ + + return 1; +} + +int writekey(char* key, char len, unsigned char* buffer) { + int i; + + outb(0x11, 0x304); + if (!waitfree(0x0c)) return 0; + + for (i = 0; i < 4; i++) { + outb(key[i], 0x300); + if (!waitfree(0x04)) return 0; + } + if (debug) printf(">%s", key); + + outb(len, 0x300); + if (debug) printf(">%x", len); + + for (i = 0; i < len; i++) { + if (!waitfree(0x04)) return 0; + outb(buffer[i], 0x300); + if (debug) printf(">%x", buffer[i]); + } + if (debug) printf("\n"); + return 1; +} + +int readkey(char* key, char len, unsigned char* buffer) { + int i; unsigned char c; + + outb(0x10, 0x304); + if (!waitfree(0x0c)) return 0; + + for (i = 0; i < 4; i++) { + outb(key[i], 0x300); + if (!waitfree(0x04)) return 0; + } + if (debug) printf("<%s", key); + + outb(len, 0x300); + if (debug) printf(">%x", len); + + for (i = 0; i < len; i++) { + if (!waitfree(0x05)) return 0; + c = inb(0x300); + buffer[i] = c; + if (debug) printf("<%x", c); + } + if (debug) printf("\n"); + return 1; +} + +int read_light_sensor(int left) { + unsigned char buffer[6]; + if (readkey(left ? LIGHT_SENSOR_LEFT_KEY : LIGHT_SENSOR_RIGHT_KEY, 6, buffer)) + return buffer[2]; + else + return -1; +} + +int set_keyboard_backlight(char value) { + unsigned char buffer[2]; + buffer[0] = value; + buffer[1] = 0x00; + return writekey(BACKLIGHT_KEY, 2, buffer); +} + +int init_motion_sensor() { + unsigned char buffer[2]; + int retry = 50; + int ret; + + while (retry) { + ret = readkey(MOTION_SENSOR_KEY, 2, buffer); + if (ret) { + if (buffer[0] || buffer[1]) { + return 1; + } + } + else { + usleep(100000); + retry--; + continue; + } + buffer[0] = 0xe0; + buffer[1] = 0; + writekey(MOTION_SENSOR_KEY, 2, buffer); + retry--; + usleep(100000); + } + return 0; +} + +int read_motion_sensor(int index) { + unsigned char buffer[2]; + int ret; + + switch (index) { + case 0: + ret = readkey(MOTION_SENSOR_X_KEY, 2, buffer); + break; + case 1: + ret = readkey(MOTION_SENSOR_Y_KEY, 2, buffer); + break; + case 2: + ret = readkey(MOTION_SENSOR_Z_KEY, 2, buffer); + break; + } + //printf("%d %x %x\n", index, buffer[0], buffer[1]); + if (ret) { + return (short)(buffer[0] << 8 | buffer[1]); + } + else { + return 0x0FFFFFFF; + } +} + +/* Brute-force device probing, try to read size bytes */ +void probe(int size) { + char key[5]; + char chars[37]; + unsigned char buffer[size]; + int i, j, k, l; + + for (i = 0; i < 26; i++) { + chars[i] = 'A'+i; + } + for (i = 0; i < 10; i++) { + chars[i+26] = '0'+i; + } + chars[36] = '_'; + + key[4] = 0; + for (i = 0; i < 37; i++) { + key[0] = chars[i]; + for (j = 0; j < 37; j++) { + key[1] = chars[j]; + for (k = 0; k < 37; k++) { + key[2] = chars[k]; + for (l = 0; l < 37; l++) { + key[3] = chars[l]; + printf("key=%s\n", key); + readkey(key, size, buffer); + } + } + } + } +} + +void usage(char* argv0) { + printf("Apple Macbook (pro) SMC debug tool " VERSION); + printf("\n"); + printf("Usage:\n"); + printf("%s [-d]: read light/motion sensors values\n", argv0); + printf("%s [-d] value: write keyboard backlight value [0-255]\n", argv0); + printf("%s -r n XXXX: read n bytes at the following key\n", argv0); + printf("%s -p n: brute force probing of all addresses, try to read n bytes\n", argv0); +} + +int main(int argc, char** argv) { + int argi = 1; + if (argc > 5) { + usage(argv[0]); + return 1; + } + + if (ioperm(0x300, 0x304, 1) < 0) { + perror("ioperm failed (you should be root)."); + exit(1); + } + + if ((argc > 1) && !strcmp(argv[1], "-d")) { + debug = 1; + argi = 2; + } + + if (argc-argi >= 1) { + if (!strcmp(argv[argi], "-r")) { + debug = 1; + int size = atoi(argv[argi+1]); + unsigned char buffer[size]; + readkey(argv[argi+2], size, buffer); + } + else if (!strcmp(argv[argi], "-p")) { + debug = 1; + int size = atoi(argv[argi+1]); + probe(size); + } + return 0; + } + + if (argc-argi == 1) { + char* endptr; + long value = strtol(argv[argi], &endptr, 10); + if ((value < 0) || (value > 255) || (endptr[0])) { + printf("Invalid value \"%s\" (should be an integer between 0 and 255).\n", argv[1]); + usage(argv[0]); + return 1; + } + else { + set_keyboard_backlight(value); + } + } + else { + init_motion_sensor(); + printf("Light: Left: %d, Right: %d\n", read_light_sensor(1), read_light_sensor(0)); + printf("Motion: X: %d, Y: %d, Z: %d\n", read_motion_sensor(0), read_motion_sensor(1), read_motion_sensor(2)); + /*while (1) { + printf("Motion: X: %d, Y: %d, Z: %d\n", read_motion_sensor(0), read_motion_sensor(1), read_motion_sensor(2)); + sleep(1); + } + int x, y, z, ox, oy, oz; + ox = read_motion_sensor(0); + oy = read_motion_sensor(1); + oz = read_motion_sensor(2); + while (1) { + x = read_motion_sensor(0); + y = read_motion_sensor(1); + z = read_motion_sensor(2); + if ((x-ox)*(x-ox)+(y-oy)*(y-oy)+(z-oz)*(z-oz) > 50) + printf("Accel: X: %d, Y: %d, Z: %d (%d %d)\n", x-ox, y-oy, z-oz, z, oz); + usleep(1000000); + ox = x; oy = y; oz = z; + }*/ + } + + return 0; +} Added: trunk/tools/smc-tools/mbp.out.valid.2 =================================================================== --- trunk/tools/smc-tools/mbp.out.valid.2 (rev 0) +++ trunk/tools/smc-tools/mbp.out.valid.2 2006-08-17 02:11:17 UTC (rev 41) @@ -0,0 +1,159 @@ +key=ALSF +<15<7 (<7<50) +-- +key=ALSL +<0<1a (<0<8) +-- +key=ALST +<0<0 (<0<0) +-- +key=BRSC +<0<64 (<0<64) +-- +key=B0AC +<0<0 (<1<2) +-- +key=B0AV +<30<f3 (<31<4a) ***** +-- +key=B0LI +<f<3c (<f<3c) +-- +key=B0RI +<0<0 (<f<3c) +-- +key=EPCV +<0<1 +-- +key=EPUV +<0<1 +-- +key=EVCT +<1<1 (<7<7-><0<0) +-- +key=IC0C +<10<f9 (<1d<a3) ***** +-- +key=ID0R +<0<3 (<55<5f) **** +-- +key=IF0R +<0<33 (<0<31) **** +-- +key=IG0C +<9<b1 (<f<e6) **** +-- +key=IM0R +<3<b7 (<4<d1) **** +-- +key=IN0R +<3<57 (<3<5c) *** +-- +key=IP0R +<1e<f3 (<0<7) *** +-- +key=LSLB +<ff<ff +-- +key=LSLF +<0<0 +-- +key=LSLN +<11<0 +-- +key=LSPV +<0<0 +-- +key=MOCF +<85<0 +-- +key=MOCN +<e0<0 +-- +key=MOHT +<1<e0 +-- +key=MOLT +<0<20 +-- +key=MOST +<a0<3 +-- +key=MO_X +<ff<f4 +key=MO_Y +<0<8 +key=MO_Z +<1<22 +-- +key=MSBC +<6<57 (<0<0) +-- +key=MSBP +<17<68 (<18<2b) +-- +key=MSCP +<0<8 +-- +key=MSC0 +<0<0 +key=MSC1 +<0<0 +key=MSC2 +<0<0 +key=MSC3 +<0<0 +-- +key=MSPH +<0<0 +-- +key=PC0C +<4<89 (<d<8a) **** +-- +key=PD0R +<0<0 (<31<4e) *** +-- +key=PF0R +<0<24 (<0<26) +-- +key=PG0C +<4<be ***** +-- +key=PM0R +<1<63 ***** +-- +key=PN0R +<1<51 ***** +-- +key=PP0R +<19<47 (<0<6) **** +-- +key=TA0P +<1b<80 (<1e<0) +-- +key=TB0T +<27<0 (<25<99) +-- +key=TC0D +<3d<40 (<44<0) ****** +-- +key=TC0P +<38<0 (<3c<0) ***** +-- +key=TG0H +<3c<20 (<40<40) ***** +-- +key=TG0P +<39<e0 (<3b<09) ***** +-- +key=TG0T +<40<60 (<46<20) ***** +-- +key=VC0C +<3c<94 (<49<30) ***** +-- +key=VG0C +<3c<e5 (<3f<db) ***** +-- +key=VP0R +<b1<82 (<c9<fa) ***** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Mactel-linux-devel mailing list Mactel-linux-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mactel-linux-devel