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
main(int ac,char ** av)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