xref: /dragonfly/sys/dev/smbus/cyapa/test_cyapa.c (revision 0720b42f)
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