1 2 /* 3 * 4 */ 5 #include <sys/types.h> 6 #include <sys/file.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <unistd.h> 10 #include <fcntl.h> 11 #include <string.h> 12 #include <bus/smbus/smb.h> 13 #include <bus/smbus/smbconf.h> 14 15 #define CYAPA_MAX_MT 5 16 17 struct cyapa_regs { 18 uint8_t stat; 19 uint8_t fngr; 20 21 struct { 22 uint8_t xy_high; /* 7:4 high 4 bits of x */ 23 uint8_t x_low; /* 3:0 high 4 bits of y */ 24 uint8_t y_low; 25 uint8_t pressure; 26 uint8_t id; /* 1-15 incremented each touch */ 27 } touch[CYAPA_MAX_MT]; 28 } __packed; 29 30 struct cyapa_cap { 31 uint8_t prod_ida[5]; /* 0x00 - 0x04 */ 32 uint8_t prod_idb[6]; /* 0x05 - 0x0A */ 33 uint8_t prod_idc[2]; /* 0x0B - 0x0C */ 34 uint8_t reserved[6]; /* 0x0D - 0x12 */ 35 uint8_t buttons; /* 0x13 */ 36 uint8_t gen; /* 0x14, low 4 bits */ 37 uint8_t max_abs_xy_high;/* 0x15 7:4 high x bits, 3:0 high y bits */ 38 uint8_t max_abs_x_low; /* 0x16 */ 39 uint8_t max_abs_y_low; /* 0x17 */ 40 uint8_t phy_siz_xy_high;/* 0x18 7:4 high x bits, 3:0 high y bits */ 41 uint8_t phy_siz_x_low; /* 0x19 */ 42 uint8_t phy_siz_y_low; /* 0x1A */ 43 } __packed; 44 45 #define CYAPA_STAT_INTR 0x80 46 #define CYAPA_STAT_PWR_MASK 0x0C 47 #define CYAPA_PWR_OFF 0x00 48 #define CYAPA_PWR_IDLE 0x08 49 #define CYAPA_PWR_ACTIVE 0x0C 50 51 #define CYAPA_STAT_DEV_MASK 0x03 52 #define CYAPA_DEV_NORMAL 0x03 53 #define CYAPA_DEV_BUSY 0x01 54 55 #define CYAPA_FNGR_DATA_VALID 0x08 56 #define CYAPA_FNGR_MIDDLE 0x04 57 #define CYAPA_FNGR_RIGHT 0x02 58 #define CYAPA_FNGR_LEFT 0x01 59 #define CYAPA_FNGR_NUMFINGERS(c) (((c) >> 4) & 0x0F) 60 61 #define CYAPA_TOUCH_X(regs, i) ((((regs)->touch[i].xy_high << 4) & 0x0F00) | \ 62 (regs)->touch[i].x_low) 63 #define CYAPA_TOUCH_Y(regs, i) ((((regs)->touch[i].xy_high << 8) & 0x0F00) | \ 64 (regs)->touch[i].y_low) 65 #define CYAPA_TOUCH_P(regs, i) ((regs)->touch[i].pressure) 66 67 #define CMD_DEV_STATUS 0x00 68 #define CMD_SOFT_RESET 0x28 69 #define CMD_POWER_MODE 0x29 70 #define CMD_QUERY_CAPABILITIES 0x2A 71 72 static char bl_exit[] = { 0x00, 0xff, 0xa5, 0x00, 0x01, 73 0x02, 0x03, 0x04, 0x05, 0x06, 74 0x07 }; 75 76 static char bl_deactivate[] = { 0x00, 0xff, 0x3b, 0x00, 0x01, 77 0x02, 0x03, 0x04, 0x05, 0x06, 78 0x07 }; 79 80 int 81 main(int ac, char **av) 82 { 83 struct smbcmd cmd; 84 char buf[256]; 85 int fd; 86 int r; 87 int i; 88 int len; 89 90 bzero(&cmd, sizeof(cmd)); 91 bzero(buf, sizeof(buf)); 92 93 fd = open("/dev/smb0-67", O_RDWR); 94 printf("fd = %d\n", fd); 95 96 cmd.slave = 0; 97 cmd.rbuf = buf; 98 99 cmd.cmd = CMD_DEV_STATUS; 100 cmd.op = SMB_TRANS_NOCNT | SMB_TRANS_7BIT; 101 cmd.rcount = 16; 102 r = ioctl(fd, SMB_TRANS, &cmd); 103 printf("status r = %d slave 0x%02x\n", r, cmd.slave); 104 for (i = 0; i < cmd.rcount; ++i) 105 printf(" %02x", (u_char)buf[i]); 106 printf("\n"); 107 cmd.rcount = 0; 108 109 /* 110 * bootloader idle 111 */ 112 #if 1 113 if ((buf[0] & 0x80) == 0) { 114 if (buf[1] & 0x80) { 115 printf("X2 BL BUSY\n"); 116 } else if (buf[2] & 0x20) { 117 printf("X2 BL ACTIVE\n"); 118 cmd.cmd = 0x00; 119 cmd.wbuf = bl_deactivate; 120 cmd.wcount = sizeof(bl_deactivate); 121 r = ioctl(fd, SMB_TRANS, &cmd); 122 printf("r=%d\n", r); 123 } else { 124 printf("X2 BL IDLE\n"); 125 cmd.cmd = 0x00; 126 cmd.wbuf = bl_exit; 127 cmd.wcount = sizeof(bl_exit); 128 r = ioctl(fd, SMB_TRANS, &cmd); 129 printf("r=%d\n", r); 130 } 131 exit(0); 132 } 133 #endif 134 #if 1 135 { 136 struct cyapa_cap *cap; 137 138 cmd.cmd = CMD_QUERY_CAPABILITIES; 139 cmd.wcount = 0; 140 cmd.rcount = sizeof(struct cyapa_cap); 141 r = ioctl(fd, SMB_TRANS, &cmd); 142 cap = (void *)buf; 143 144 printf("caps %5.5s-%6.6s-%2.2s left=%c midl=%c rght=%c\n", 145 cap->prod_ida, 146 cap->prod_idb, 147 cap->prod_idc, 148 ((cap->buttons & CYAPA_FNGR_LEFT) ? 'y' : 'n'), 149 ((cap->buttons & CYAPA_FNGR_MIDDLE) ? 'y' : 'n'), 150 ((cap->buttons & CYAPA_FNGR_RIGHT) ? 'y' : 'n') 151 ); 152 printf("caps pixx=%d pixy=%d\n", 153 (cap->max_abs_xy_high << 4 & 0x0F00) | 154 cap->max_abs_x_low, 155 (cap->max_abs_xy_high << 8 & 0x0F00) | 156 cap->max_abs_y_low); 157 } 158 #endif 159 #if 1 160 cmd.cmd = CMD_DEV_STATUS; 161 162 while (1) { 163 struct cyapa_regs *regs; 164 int i; 165 int nfingers; 166 167 cmd.rcount = sizeof(struct cyapa_regs); 168 r = ioctl(fd, SMB_TRANS, &cmd); 169 regs = (void *)buf; 170 171 nfingers = CYAPA_FNGR_NUMFINGERS(regs->fngr); 172 173 printf("stat %02x buttons %c%c%c nfngrs=%d ", 174 regs->stat, 175 ((regs->fngr & CYAPA_FNGR_LEFT) ? 'L' : '-'), 176 ((regs->fngr & CYAPA_FNGR_MIDDLE) ? 'L' : '-'), 177 ((regs->fngr & CYAPA_FNGR_RIGHT) ? 'L' : '-'), 178 nfingers 179 ); 180 fflush(stdout); 181 for (i = 0; i < nfingers; ++i) { 182 printf(" [x=%04d y=%04d p=%d]", 183 CYAPA_TOUCH_X(regs, i), 184 CYAPA_TOUCH_Y(regs, i), 185 CYAPA_TOUCH_P(regs, i)); 186 } 187 printf("\n"); 188 usleep(10000); 189 } 190 #endif 191 192 close(fd); 193 194 return 0; 195 } 196