#include #include #include #include #include unsigned char* inbuffer; unsigned char* outbuffer; // wait for up to 0.1seconds for an acknowledgement int getack(int fd) { fd_set set; timeval timeout; FD_ZERO(&set); FD_SET(fd,&set); timeout.tv_sec=0; timeout.tv_usec=100000; if (select(FD_SETSIZE,&set,NULL,NULL,&timeout)) { int b=read(fd,inbuffer,1); if(b==1) { if(inbuffer[0]==0xfa) { //printf("<< Acknowledged\r\n"); return 1; } else if (inbuffer[0]=0xfe) printf("<- PS/2: Error\r\n"); else printf("<- Not an acknowledgement:%02x\r\n",inbuffer[0]); }; }; return 0; }; // Try to receive n bytes int receive(int fd,int n) { int a=0,b; while(a TP: Send extended ID\r\n"); command(fd,0xe1); if (! getack(fd)) { if(inbuffer[0]==0xfe) { // give it a second try command(fd,0xe1); if(getack(fd)) goto ack; } printf("No trackpoint controller detected\r\n"); return 0; } ack: int a=0; while(select(FD_SETSIZE,&set,NULL,NULL,&timeout)) { read(fd,inbuffer+a,1); a++; } char * version; if(inbuffer[0]==0x01) { switch(inbuffer[1]) { case 0x01: version = "8E/98"; break; case 0x02: version = "A4"; break; case 0x03: version = "AB"; break; case 0x04: version = "03"; break; case 0x05: version = "B2/B4"; break; case 0x06: version = "B1/B3/B5/B8/2B"; break; case 0x07: version = "?"; break; case 0x08: version = "?"; break; case 0x09: version = "?"; break; case 0x0A: version = "35"; break; case 0x0B: version = "3A/3B"; break; case 0x0C: version = "3C"; break; case 0x0D: version = "3D"; break; case 0x0E: version = "3E"; break; default: printf("Unrecognized ID: %02x\n",inbuffer[1]); return 0; } printf("IBM Trackpoint controller detected. Version %s \r\n",version); return 1; } else { printf("No IBM trackpoint controller detected\r\n"); printf("Extended ID: %02x %02x\r\n",inbuffer[0],inbuffer[1]); return 0; } } // Reset PS/2 device int reset(int fd) { command(fd,0xff); printf("-> PS/2: Reset\r\n"); getack(fd); receive(fd,2); if(inbuffer[0]==0xaa && inbuffer[1]==0x00) { printf("<- PS/2: Succesfull initialization\r\n"); return 1; } else return 0; } // Get PS/2 ID int getdeviceid(int fd) { command(fd,0xf2); getack(fd); printf("-> PS/2: Get device ID\r\n"); if(receive(fd,1)==1) { printf("<- PS/2: Device ID: %02x\n",inbuffer[0]); return inbuffer[0]; } } void enabledatareport(int fd) { command(fd, 0xf4); printf("-> PS/2: (re)Enable data-reporting\r\n"); getack(fd); } void disabledatareport(int fd) { command(fd, 0xf5); printf("-> PS/2: Disable data-reporting\r\n"); getack(fd); } void setsamplerate(int fd, int rate) { command(fd,0xf3); printf("-> PS/2: Set sample rate: %u\r\n",rate); getack(fd); command(fd,rate); getack(fd); } void setresolution(int fd, int res) { command(fd,0xe8); printf("-> PS/2: Set resolution: %u\r\n",res); getack(fd); command(fd,res); getack(fd); } void getstatus(int fd) { command(fd,0xe9); printf("-> Send status\r\n"); receive(fd,3); printf("<- Status is: 0x%02x,0x%02x,0x%02x\n",inbuffer[0],inbuffer[1],inbuffer[2]); } void getlogiid(int fd) { receive(fd,3); unsigned char a = inbuffer[0]; unsigned char id = ((a >> 4) & 0x07) | ((a<<3) & 0x78); printf("Logi-id: %d\r\n", id); }; // Put trackpoint device into transparent mode void enabletransparent(int fd) { command(fd,0xe2); getack(fd); command(fd,0x4e); getack(fd); printf("-> TP: Set soft-transparent\r\n"); } // Get trackpoint device out of transparent mode // Notice the command gives not-ack because its in transparent mode, // just ignore these. After the command finishes to acknowledges are sent. void disabletransparent(int fd) { command(fd,0xe2); //getack(fd); command(fd,0xb9); getack(fd); printf("-> TP: Cancel soft-transparent\r\n"); } // Detect external device on trackpoint controller bool detectExternal(int fd) { command(fd,0xe2); getack(fd); command(fd,0x21); getack(fd); receive(fd,1); if(inbuffer[0] && 8) { printf("<- TP: External device present\r\n"); return true; } else { printf("<- TP: No external device\r\n"); return false; } } // IMPS/2 magic-initialization and detection bool detectIMPS(int fd) { setsamplerate(fd,200); setsamplerate(fd,100); setsamplerate(fd,80); if(getdeviceid(fd)==3) { printf("IMPS/2 mouse detected\r\n"); } } int main() { inbuffer = new unsigned char[200]; outbuffer = new unsigned char[200]; int fd = open("/dev/psaux", O_RDWR); reset(fd); // If kernel<2.4.9 remember to disable datareport, // in later kernels reset is enough disabledatareport(fd); sleep(1); // make sure we dont get any more confusing datareports. if(detectTP(fd)) { if(detectExternal(fd)) { enabletransparent(fd); if(! detectIMPS(fd)) disabletransparent(fd); setsamplerate(fd,200); } } else detectIMPS(fd); enabledatareport(fd); close(fd); }