xref: /dragonfly/sys/dev/smbus/atmel_mxt/test_atmel.c (revision 31524921)
1 
2 /*
3  * Atmel mxt probably mxt1188s-a or mxt1664s-a or mxt3432s or mxt143e
4  * I think its the mxt143e
5  *
6  * URL for original source material:
7  *	http://www.atmel.com/products/touchsolutions/touchscreens/unlimited_touch.aspx
8  * GIT for original source material:
9  *	git://github.com/atmel-maxtouch/obp-utils.git
10  *
11  * cc obp-utils.c test_atmel.c -o /tmp/test -I/usr/src/sys/
12  *
13  * kldload smb before running test program to get /dev/smb*
14  */
15 #include <sys/types.h>
16 #include <sys/file.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <fcntl.h>
21 #include <string.h>
22 #include <assert.h>
23 #include <dev/smbus/smb/smb.h>
24 #include <bus/smbus/smbconf.h>
25 
26 #include "obp-utils.h"
27 
28 static const char *
29 mxt_gettypestring(int type)
30 {
31 	static const struct mxt_strinfo strinfo[] = { MXT_INIT_STRINGS };
32 	int i;
33 
34 	for (i = 0; i < sizeof(strinfo) / sizeof(strinfo[0]); ++i) {
35 		if (strinfo[i].type == type)
36 			return(strinfo[i].id);
37 	}
38 	return("unknown");
39 }
40 
41 struct mxt_object *
42 mxt_findobject(struct mxt_rollup *rup, int type)
43 {
44 	int i;
45 
46 	for (i = 0; i < rup->nobjs; ++i) {
47 		if (rup->objs[i].type == type)
48 			return(&rup->objs[i]);
49 	}
50 	return NULL;
51 }
52 
53 static int
54 mxt_read_reg(int fd, uint16_t reg, void *rbuf, int bytes)
55 {
56 	struct smbcmd cmd;
57 	uint8_t wbuf[2];
58 	int r;
59 
60 	bzero(&cmd, sizeof(cmd));
61 	wbuf[0] = reg & 255;
62 	wbuf[1] = reg >> 8;
63 	cmd.slave = 0;
64 	cmd.rbuf = rbuf;
65 	cmd.wbuf = wbuf;
66 	cmd.wcount = 2;
67 	cmd.rcount = bytes;
68 	cmd.op = SMB_TRANS_NOCNT | SMB_TRANS_NOCMD | SMB_TRANS_7BIT;
69 
70 	r = ioctl(fd, SMB_TRANS, &cmd);
71 	if (r == 0) {
72 		return cmd.rcount;
73 	} else {
74 		printf("status r = %d slave 0x%02x\n", r, cmd.slave);
75 		return -1;
76 	}
77 }
78 
79 static int
80 mxt_write_reg_buf(int fd, uint16_t reg, void *xbuf, int bytes)
81 {
82 	struct smbcmd cmd;
83 	uint8_t wbuf[256];
84 	int r;
85 
86 	assert(bytes < sizeof(wbuf) - 2);
87 	wbuf[0] = reg & 0xff;
88 	wbuf[1] = reg >> 8;
89 	bcopy(xbuf, wbuf + 2, bytes);
90 
91 	cmd.slave = 0;
92 	cmd.rbuf = NULL;
93 	cmd.wbuf = wbuf;
94 	cmd.wcount = bytes + 2;
95 	cmd.rcount = 0;
96 	cmd.op = SMB_TRANS_NOCNT | SMB_TRANS_NOCMD | SMB_TRANS_7BIT;
97 
98 	r = ioctl(fd, SMB_TRANS, &cmd);
99 	if (r == 0) {
100 		return 0;
101 	} else {
102 		printf("status r = %d slave 0x%02x\n", r, cmd.slave);
103 		return -1;
104 	}
105 }
106 
107 static int
108 mxt_write_reg(int fd, uint16_t reg, uint8_t val)
109 {
110 	return mxt_write_reg_buf(fd, reg, &val, 1);
111 }
112 
113 static int
114 mxt_read_object(int fd, struct mxt_object *obj, void *rbuf, int rbytes)
115 {
116 	uint16_t reg = obj->start_pos_lsb + (obj->start_pos_msb << 8);
117 	int bytes = obj->size_minus_one + 1;
118 
119 	if (bytes > rbytes)
120 		bytes = rbytes;
121 	return mxt_read_reg(fd, reg, rbuf, bytes);
122 }
123 
124 
125 static int
126 mxt_t6_command(int fd, uint16_t t6cmd, uint8_t t6val, int waitforme)
127 {
128 	uint8_t status;
129 
130 	mxt_write_reg(fd, 6 + t6cmd, t6val);
131 
132 	while (waitforme) {
133 		if (mxt_read_reg(fd, 6 + t6cmd, &status, 1) != 1)
134 			break;
135 		if (status)
136 			return status;
137 	}
138 	return 0;
139 }
140 
141 static
142 const char *
143 msgflagsstr(uint8_t flags)
144 {
145 	static char buf[9];
146 
147 	buf[0] = (flags & MXT_MSGF_DETECT) ? 'D' : '.';
148 	buf[1] = (flags & MXT_MSGF_PRESS) ? 'P' : '.';
149 	buf[2] = (flags & MXT_MSGF_RELEASE) ? 'R' : '.';
150 	buf[3] = (flags & MXT_MSGF_MOVE) ? 'M' : '.';
151 	buf[4] = (flags & MXT_MSGF_VECTOR) ? 'V' : '.';
152 	buf[5] = (flags & MXT_MSGF_AMP) ? 'A' : '.';
153 	buf[6] = (flags & MXT_MSGF_SUPPRESS) ? 'S' : '.';
154 	buf[7] = (flags & MXT_MSGF_UNGRIP) ? 'U' : '.';
155 
156 	return buf;
157 }
158 
159 int
160 main(int ac, char **av)
161 {
162 	uint8_t rbuf[1024];
163 	struct mxt_rollup rup;
164 	struct mxt_object *obj;
165 	int fd;
166 	int i;
167 	int n;
168 	int r;
169 	size_t blksize;
170 	size_t totsize;
171 	uint32_t crc;
172 
173 	fd = open("/dev/smb1-4a", O_RDWR);
174 	printf("fd = %d\n", fd);
175 
176 	r = mxt_t6_command(fd, 0/*RESET*/, 0x01, 1);
177 	printf("reset result %d\n", r);
178 
179 	n = mxt_read_reg(fd, 0, &rup.info, sizeof(rup.info));
180 	for (i = 0; i < n; ++i)
181 		printf(" %02x", ((uint8_t *)&rup.info)[i]);
182 	printf("\n");
183 	rup.nobjs = rup.info.num_objects;
184 
185 	blksize = sizeof(rup.info) +
186 		  rup.nobjs * sizeof(struct mxt_object);
187 	totsize = blksize + sizeof(struct mxt_raw_crc);
188 	assert(totsize < sizeof(rbuf));
189 
190 	n = mxt_read_reg(fd, 0, rbuf, totsize);
191 	if (n != totsize) {
192 		printf("mxt_read_reg: config failed: %d/%d\n", n, totsize);
193 		exit(1);
194 	}
195 	crc = obp_convert_crc((struct mxt_raw_crc *)(rbuf + blksize));
196 	if (obp_crc24(rbuf, blksize) != crc) {
197 		printf("info: crc failed %08x/%08x\n",
198 			crc,
199 			obp_crc24(rbuf, blksize));
200 		exit(1);
201 	}
202 	rup.objs = (void *)(rbuf + sizeof(rup.info));
203 	for (i = 0; i < rup.nobjs; ++i) {
204 		obj = &rup.objs[i];
205 		printf("object %d (%s) {\n",
206 			obj->type,
207 			mxt_gettypestring(obj->type));
208 		printf("    position = %d\n",
209 			obj->start_pos_lsb + (obj->start_pos_msb << 8));
210 		printf("    size     = %d\n",
211 			obj->size_minus_one + 1);
212 		printf("    instances= %d\n",
213 			obj->instances_minus_one + 1);
214 		printf("    numids   = %d\n",
215 			obj->num_report_ids);
216 	}
217 	printf("\n");
218 	fflush(stdout);
219 
220 	obj = mxt_findobject(&rup, MXT_GEN_MESSAGEPROCESSOR);
221 	assert(obj != NULL);
222 
223 	for (;;) {
224 		mxt_message_t msg;
225 
226 		n = mxt_read_object(fd, obj, &msg, sizeof(msg));
227 		if (msg.any.reportid == 255)
228 			continue;
229 		for (i = 0; i < n; ++i)
230 			printf(" %02x", ((uint8_t *)&msg)[i]);
231 		printf("  trk=%02x f=%s x=%-4d y=%-4d p=%d amp=%d\n",
232 			msg.any.reportid,
233 			msgflagsstr(msg.touch.flags),
234 			(msg.touch.pos[0] << 4) |
235 				((msg.touch.pos[2] >> 4) & 0x0F),
236 			(msg.touch.pos[1] << 4) |
237 				((msg.touch.pos[2]) & 0x0F),
238 			msg.touch.area,
239 			msg.touch.amplitude);
240 		usleep(100000);
241 	}
242 }
243