This source file includes following definitions.
- pmsi_setintellimode
- pmsiprobe
- pmsiattach
- pmsi_enable
- pmsi_disable
- pmsi_ioctl
- pmsiinput
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 #include <sys/param.h>
28 #include <sys/systm.h>
29 #include <sys/device.h>
30 #include <sys/ioctl.h>
31
32 #include <machine/bus.h>
33
34 #include <dev/ic/pckbcvar.h>
35
36 #include <dev/pckbc/pmsreg.h>
37
38 #include <dev/wscons/wsconsio.h>
39 #include <dev/wscons/wsmousevar.h>
40
41 struct pmsi_softc {
42 struct device sc_dev;
43
44 pckbc_tag_t sc_kbctag;
45 int sc_kbcslot;
46
47 int sc_enabled;
48 int inputstate;
49 u_int buttons, oldbuttons;
50 signed char dx, dy;
51
52 struct device *sc_wsmousedev;
53 };
54
55 int pmsiprobe(struct device *, void *, void *);
56 void pmsiattach(struct device *, struct device *, void *);
57 void pmsiinput(void *, int);
58
59 struct cfattach pmsi_ca = {
60 sizeof(struct pmsi_softc), pmsiprobe, pmsiattach,
61 };
62
63 int pmsi_enable(void *);
64 int pmsi_ioctl(void *, u_long, caddr_t, int, struct proc *);
65 void pmsi_disable(void *);
66
67 const struct wsmouse_accessops pmsi_accessops = {
68 pmsi_enable,
69 pmsi_ioctl,
70 pmsi_disable,
71 };
72
73 static int pmsi_setintellimode(pckbc_tag_t, pckbc_slot_t);
74
75 static int
76 pmsi_setintellimode(tag, slot)
77 pckbc_tag_t tag;
78 pckbc_slot_t slot;
79 {
80 u_char cmd[2], resp[1];
81 int i, res;
82 static u_char rates[] = {200, 100, 80};
83
84 cmd[0] = PMS_SET_SAMPLE;
85 for (i = 0; i < 3; i++) {
86 cmd[1] = rates[i];
87 res = pckbc_poll_cmd(tag, slot, cmd, 2, 0, 0, 0);
88 if (res)
89 return (res);
90 }
91
92 cmd[0] = PMS_SEND_DEV_ID;
93 res = pckbc_poll_cmd(tag, slot, cmd, 1, 1, resp, 0);
94 if (res)
95 return (res);
96 if (resp[0] != 3)
97 return (ENXIO);
98
99 return (0);
100 }
101
102 int
103 pmsiprobe(parent, match, aux)
104 struct device *parent;
105 void *match;
106 void *aux;
107 {
108 struct pckbc_attach_args *pa = aux;
109 u_char cmd[1], resp[2];
110 int res;
111
112 if (pa->pa_slot != PCKBC_AUX_SLOT)
113 return (0);
114
115
116 pckbc_flush(pa->pa_tag, pa->pa_slot);
117
118
119 cmd[0] = PMS_RESET;
120 res = pckbc_poll_cmd(pa->pa_tag, pa->pa_slot, cmd, 1, 2, resp, 1);
121 if (res) {
122 #ifdef DEBUG
123 printf("pmsiprobe: reset error %d\n", res);
124 #endif
125 return (0);
126 }
127 if (resp[0] != PMS_RSTDONE) {
128 printf("pmsiprobe: reset response 0x%x\n", resp[0]);
129 return (0);
130 }
131
132
133 if (resp[1] != 0) {
134 #ifdef DEBUG
135 printf("pmsiprobe: type 0x%x\n", resp[1]);
136 #endif
137 return (0);
138 }
139
140 if ((res = pmsi_setintellimode(pa->pa_tag, pa->pa_slot))) {
141 #ifdef DEBUG
142 printf("pmsiprobe: intellimode -> %d\n", res);
143 #endif
144 return (0);
145 }
146
147 return (20);
148 }
149
150 void
151 pmsiattach(parent, self, aux)
152 struct device *parent, *self;
153 void *aux;
154 {
155 struct pmsi_softc *sc = (void *)self;
156 struct pckbc_attach_args *pa = aux;
157 struct wsmousedev_attach_args a;
158 u_char cmd[1], resp[2];
159 int res;
160
161 sc->sc_kbctag = pa->pa_tag;
162 sc->sc_kbcslot = pa->pa_slot;
163
164 printf("\n");
165
166
167 pckbc_flush(pa->pa_tag, pa->pa_slot);
168
169
170 cmd[0] = PMS_RESET;
171 res = pckbc_poll_cmd(pa->pa_tag, pa->pa_slot, cmd, 1, 2, resp, 1);
172 #ifdef DEBUG
173 if (res || resp[0] != PMS_RSTDONE || resp[1] != 0) {
174 printf("pmsiattach: reset error\n");
175 return;
176 }
177 #endif
178 res = pmsi_setintellimode(pa->pa_tag, pa->pa_slot);
179 #ifdef DEBUG
180 if (res) {
181 printf("pmsiattach: error setting intelli mode\n");
182 return;
183 }
184 #endif
185
186
187 sc->inputstate = 0;
188 sc->oldbuttons = 0;
189
190 pckbc_set_inputhandler(sc->sc_kbctag, sc->sc_kbcslot,
191 pmsiinput, sc, sc->sc_dev.dv_xname);
192
193 a.accessops = &pmsi_accessops;
194 a.accesscookie = sc;
195
196
197
198
199
200
201
202 sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
203
204
205 cmd[0] = PMS_DEV_DISABLE;
206 res = pckbc_poll_cmd(pa->pa_tag, pa->pa_slot, cmd, 1, 0, 0, 0);
207 if (res)
208 printf("pmsiattach: disable error\n");
209 pckbc_slot_enable(sc->sc_kbctag, sc->sc_kbcslot, 0);
210 }
211
212 int
213 pmsi_enable(v)
214 void *v;
215 {
216 struct pmsi_softc *sc = v;
217 u_char cmd[1];
218 int res;
219
220 if (sc->sc_enabled)
221 return EBUSY;
222
223 sc->sc_enabled = 1;
224 sc->inputstate = 0;
225 sc->oldbuttons = 0;
226
227 pckbc_slot_enable(sc->sc_kbctag, sc->sc_kbcslot, 1);
228
229 cmd[0] = PMS_DEV_ENABLE;
230 res = pckbc_enqueue_cmd(sc->sc_kbctag, sc->sc_kbcslot, cmd, 1, 0, 1, 0);
231 if (res)
232 printf("pmsi_enable: command error\n");
233
234 return 0;
235 }
236
237 void
238 pmsi_disable(v)
239 void *v;
240 {
241 struct pmsi_softc *sc = v;
242 u_char cmd[1];
243 int res;
244
245 cmd[0] = PMS_DEV_DISABLE;
246 res = pckbc_enqueue_cmd(sc->sc_kbctag, sc->sc_kbcslot, cmd, 1, 0, 1, 0);
247 if (res)
248 printf("pmsi_disable: command error\n");
249
250 pckbc_slot_enable(sc->sc_kbctag, sc->sc_kbcslot, 0);
251
252 sc->sc_enabled = 0;
253 }
254
255 int
256 pmsi_ioctl(v, cmd, data, flag, p)
257 void *v;
258 u_long cmd;
259 caddr_t data;
260 int flag;
261 struct proc *p;
262 {
263 struct pmsi_softc *sc = v;
264 u_char kbcmd[2];
265 int i;
266
267 switch (cmd) {
268 case WSMOUSEIO_GTYPE:
269 *(u_int *)data = WSMOUSE_TYPE_PS2;
270 break;
271
272 case WSMOUSEIO_SRES:
273 i = ((int) *(u_int *)data - 12) / 25;
274
275 if (i < 0)
276 i = 0;
277 if (i > 3)
278 i = 3;
279
280 kbcmd[0] = PMS_SET_RES;
281 kbcmd[1] = (unsigned char) i;
282 i = pckbc_enqueue_cmd(sc->sc_kbctag, sc->sc_kbcslot, kbcmd,
283 2, 0, 1, 0);
284
285 if (i)
286 printf("pms_ioctl: SET_RES command error\n");
287 break;
288
289 default:
290 return (-1);
291 }
292 return (0);
293 }
294
295
296 #define PS2LBUTMASK 0x01
297 #define PS2RBUTMASK 0x02
298 #define PS2MBUTMASK 0x04
299
300 void pmsiinput(vsc, data)
301 void *vsc;
302 int data;
303 {
304 struct pmsi_softc *sc = vsc;
305 signed char dz;
306 u_int changed;
307
308 if (!sc->sc_enabled) {
309
310 return;
311 }
312
313 switch (sc->inputstate) {
314
315 case 0:
316 if ((data & 0xc0) == 0) {
317 sc->buttons = ((data & PS2LBUTMASK) ? 0x1 : 0) |
318 ((data & PS2MBUTMASK) ? 0x2 : 0) |
319 ((data & PS2RBUTMASK) ? 0x4 : 0);
320 ++sc->inputstate;
321 }
322 break;
323
324 case 1:
325 sc->dx = data;
326
327 sc->dx = (sc->dx == -128) ? -127 : sc->dx;
328 ++sc->inputstate;
329 break;
330
331 case 2:
332 sc->dy = data;
333 sc->dy = (sc->dy == -128) ? -127 : sc->dy;
334 ++sc->inputstate;
335 break;
336
337 case 3:
338 dz = data;
339 dz = (dz == -128) ? -127 : dz;
340 sc->inputstate = 0;
341
342 changed = (sc->buttons ^ sc->oldbuttons);
343 sc->oldbuttons = sc->buttons;
344
345 if (sc->dx || sc->dy || dz || changed)
346 wsmouse_input(sc->sc_wsmousedev,
347 sc->buttons, sc->dx, sc->dy, dz, 0,
348 WSMOUSE_INPUT_DELTA);
349 break;
350 }
351
352 return;
353 }
354
355 struct cfdriver pmsi_cd = {
356 NULL, "pmsi", DV_DULL
357 };