Merge branch 'vendor/OPENSSL'
[dragonfly.git] / sys / dev / smbus / atmel_mxt / atmel_mxt.c
1 /*
2  * Copyright (c) 2014 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 /*
35  * ATMEL_MXT - Atmel MXT touchscreen driver
36  *
37  *      PRELIMINARY DRIVER PRELIMINARY DRIVER PRELIMINARY DRIVERE
38  *
39  * (everything is pretty much hardwired and we assume the device is already
40  *  operational, which it appears to be.  ONLY TESTED ON ACER C720).
41  *
42  * This driver attaches to Acer TouchScreen MXT chipsets and currently
43  * emulates the ELO touchscreen serial protocol "elographics" for X:
44  *
45  *      Section "InputDevice"
46  *              Identifier  "TouchScreen0"
47  *              Driver      "elographics"
48  *              Option      "Device" "/dev/atmel1-4a"
49  *      EndSection
50  *
51  * The MXT chipsets typically attach on haswell chromebooks on one of the I2C
52  * busses at address 0x4A.  On my Acer C720 it attaches to the ig4 driver's
53  * I2C bus #1 at 0x4A.  kldload ig4; kldload atmel_mxt.
54  *
55  * The kernel driver and test code is written from scratch, but some code has
56  * been snarfed (in separate files) from linux development as referenced
57  * here:
58  *
59  * www.atmel.com/products/touchsolutions/touchscreens/unlimited_touch.aspx
60  * git://github.com/atmel-maxtouch/obp-utils.git
61  *
62  * The linux driver was also consulted, but not used.  Note that the linux
63  * driver appears to be GPL'd but uses code from obp-utils.git on github
64  * which is (c)Copyright by Atmel and uses more of a BSD-like license.  The
65  * obp-* source files contain the snarfed code and include this license.
66  *
67  * The ELO touchscreen serial protocol uses 10-byte fixed-length packets:
68  *
69  *      Byte 0:     ELO_SYNC_BYTE ('U')
70  *      Byte 1-8:   Packet data
71  *      Byte 9:     checksum of bytes 0 to 8
72  *
73  * Our interface reads and writes only whole packets and does not do any
74  * buffer stitching.  It is compatible with Xorg.
75  *
76  * Control Commands sent from Userland (only an Ack packet is returned)
77  *
78  *      Byte 0:     ELO_SYNC_BYTE ('U')
79  *      Byte 1:     ELO_MODE ('m')
80  *      Byte 2:     Flags
81  *          0x80 -
82  *          0x40 Tracking mode
83  *          0x20 -
84  *          0x10 -
85  *          0x08 Scaling mode
86  *          0x04 Untouch mode
87  *          0x02 Streaming mode
88  *          0x01 Touch mode
89  *
90  *      Byte 0:     ELO_SYNC_BYTE ('U')
91  *      Byte 1:     ELO_REPORT ('r')
92  *
93  * Query Command sent from Userland: (expect response packet and Ack packet)
94  *
95  *      Byte 0:     ELO_SYNC_BYTE ('U')         Request ID
96  *      Byte 1:     ELO_ID ('i')
97  *
98  *      Byte 0:     ELO_SYNC_BYTE ('U')`        Request Owner
99  *      Byte 1:     ELO_OWNER ('o')
100  *
101  * Streaming packets sent from the driver to userland
102  *
103  *      Byte 0:     ELO_SYNC_BYTE ('U')
104  *      Byte 1:     ELO_TOUCH ('T')
105  *      Byte 2:     Packet type
106  *        Bit 2 : Pen Up        (Release)       0x04
107  *        Bit 1 : Position      (Stream)        0x02
108  *        Bit 0 : Pen Down      (Press)         0x01
109  *      Byte 3:     X coordinate lsb
110  *      Byte 4:     X coordinate msb
111  *      Byte 5:     Y coordinate lsb
112  *      Byte 6:     Y coordinate msb
113  *      Byte 7:     Z coordinate lsb
114  *      Byte 8:     Z coordinate msb
115  *
116  * Responses to commands: (one or two packets returned)
117  *
118  *      Byte 0:     ELO_SYNC_BYTE ('U')         (if in response to query)
119  *      Byte 1:     toupper(command_byte)       (control commands have no
120  *      Byte 2-8:   ... depends ....             response)
121  *
122  *      Byte 0:     ELO_SYNC_BYTE ('U')         (unconditional ack)
123  *      Byte 1:     'A'ck
124  *      Byte 2-8:   ... depends ....
125  *
126  * NOTE!  For the most part we ignore commands other than doing the handwaving
127  *        to send a dummied-up response and ack as assumed by the X driver.
128  *        Also, the read() and write() support only reads and writes whole
129  *        packets.  There is NO byte-partial buffering.  The X driver appears
130  *        to be compatible with these restrictions.
131  *
132  * figure out the bootstrapping and commands.
133  *
134  * Unable to locate any datasheet for the device.
135  *
136  *                                  FEATURES
137  *
138  * Currently no features.  Only one finger is supported by this attachment
139  * for now and I haven't written any de-jitter and finger-transfer code.
140  * This is good enough for moving and resizing windows (given big enough
141  * widgets), and hitting browser buttons and hotlinks.
142  *
143  * Currently no scrolling control or other features.  We would need to
144  * basically implement either the linux general input even infrastructure
145  * which is a LOT of code, or a mouse emulator to handle scrolling emulation.
146  */
147 #include <sys/kernel.h>
148 #include <sys/param.h>
149 #include <sys/systm.h>
150 #include <sys/device.h>
151 #include <sys/module.h>
152 #include <sys/bus.h>
153 #include <sys/conf.h>
154 #include <sys/uio.h>
155 #include <sys/fcntl.h>
156 /*#include <sys/input.h>*/
157 #include <sys/vnode.h>
158 #include <sys/sysctl.h>
159 #include <sys/event.h>
160 #include <sys/devfs.h>
161
162 #include <bus/smbus/smbconf.h>
163 #include <bus/smbus/smbus.h>
164 #include "atmel_mxt.h"
165
166 #include "smbus_if.h"
167 #include "bus_if.h"
168 #include "device_if.h"
169
170 struct elopacket {
171         uint8_t sync;
172         uint8_t cmd;
173         uint8_t byte2;
174         uint8_t byte3;
175         uint8_t byte4;
176         uint8_t byte5;
177         uint8_t byte6;
178         uint8_t byte7;
179         uint8_t byte8;
180         uint8_t csum;
181 } __packed;
182
183 typedef struct elopacket elopacket_t;
184
185 typedef struct atmel_track {
186         uint16_t x;
187         uint16_t y;
188         uint16_t pressure;
189         int     status;
190         int     report;         /* what we have to report */
191 } atmel_track_t;
192
193 #define ATMEL_TRACK_RELEASED            0
194 #define ATMEL_TRACK_PRESSED             1
195
196 #define ATMEL_REPORT_PRESS      0x0001
197 #define ATMEL_REPORT_MOVE       0x0002
198 #define ATMEL_REPORT_RELEASE    0x0004
199
200 #define ATMEL_MAXTRACK          10
201
202 struct atmel_mxt_softc {
203         device_t dev;
204         int     count;                  /* >0 if device opened */
205         int     unit;
206         int     addr;
207         cdev_t  devnode;
208         struct kqinfo kqinfo;
209         struct lock lk;
210
211         int     poll_flags;
212         thread_t poll_td;
213
214         /*
215          * Hardware state
216          */
217         struct mxt_rollup       core;
218         struct mxt_object       *msgprocobj;
219         struct mxt_object       *cmdprocobj;
220
221         /*
222          * Capabilities
223          */
224         short   cap_resx;
225         short   cap_resy;
226
227         /*
228          * Emulation
229          */
230         atmel_track_t track[ATMEL_MAXTRACK];
231         int     tracking;
232         int     track_fingers;
233
234         elopacket_t pend_rep;           /* pending reply to command */
235         int     pend_ack;               /* pending reply mode */
236
237         int     last_active_tick;
238         int     last_calibrate_tick;
239         int     data_signal;            /* something ready to read */
240         int     blocked;                /* someone is blocking */
241         int     reporting_mode;
242         int     sample_rate;            /* samples/sec */
243         int     poll_ticks;
244 };
245
246 typedef struct atmel_mxt_softc atmel_mxt_softc_t;
247
248 #define ATMEL_POLL_SHUTDOWN     0x0001
249
250 #define PEND_ACK_NONE           0       /* no reply to command pending */
251 #define PEND_ACK_RESPOND        1       /* reply w/response and ack */
252 #define PEND_ACK_ACK            2       /* reply w/ack only */
253
254 #define REPORT_NONE             0x0000
255 #define REPORT_ALL              0x0001
256
257 /*
258  * Async debug variable commands are executed by the poller and will
259  * auto-clear.
260  */
261 static int atmel_mxt_idle_freq = 1;
262 SYSCTL_INT(_debug, OID_AUTO, atmel_mxt_idle_freq, CTLFLAG_RW,
263                 &atmel_mxt_idle_freq, 0, "");
264 static int atmel_mxt_slow_freq = 20;
265 SYSCTL_INT(_debug, OID_AUTO, atmel_mxt_slow_freq, CTLFLAG_RW,
266                 &atmel_mxt_slow_freq, 0, "");
267 static int atmel_mxt_norm_freq = 100;
268 SYSCTL_INT(_debug, OID_AUTO, atmel_mxt_norm_freq, CTLFLAG_RW,
269                 &atmel_mxt_norm_freq, 0, "");
270 static int atmel_mxt_minpressure = 16;
271 SYSCTL_INT(_debug, OID_AUTO, atmel_mxt_minpressure, CTLFLAG_RW,
272                 &atmel_mxt_minpressure, 0, "");
273
274 /*
275  * Run a calibration command every N seconds only when idle.  0 to disable.
276  * Default every 30 seconds.
277  */
278 static int atmel_mxt_autocalibrate = 30;
279 SYSCTL_INT(_debug, OID_AUTO, atmel_mxt_autocalibrate, CTLFLAG_RW,
280                 &atmel_mxt_autocalibrate, 0, "");
281
282 /*
283  * run a calibration on module startup.
284  */
285 static int atmel_mxt_debug = 0;
286 SYSCTL_INT(_debug, OID_AUTO, atmel_mxt_debug, CTLFLAG_RW,
287                 &atmel_mxt_debug, 0, "");
288
289 static void atmel_mxt_poll_thread(void *arg);
290 static void atmel_find_active_state(atmel_mxt_softc_t *sc);
291 static int atmel_mxt_raw_input(atmel_mxt_softc_t *sc, mxt_message_t *msg);
292 static struct mxt_object *mxt_findobject(struct mxt_rollup *core, int type);
293 static int mxt_read_reg(atmel_mxt_softc_t *sc, uint16_t reg,
294                         void *rbuf, int bytes);
295 static int mxt_write_reg_buf(atmel_mxt_softc_t *sc, uint16_t reg,
296                         void *xbuf, int bytes);
297 static int mxt_write_reg(atmel_mxt_softc_t *sc, uint16_t reg, uint8_t val);
298 static int mxt_read_object(atmel_mxt_softc_t *sc, struct mxt_object *obj,
299                         void *rbuf, int rbytes);
300 static int mxt_write_object_off(atmel_mxt_softc_t *sc, struct mxt_object *obj,
301                         int offset, uint8_t val);
302
303 static
304 const char *
305 msgflagsstr(uint8_t flags)
306 {
307         static char buf[9];
308
309         buf[0] = (flags & MXT_MSGF_DETECT) ? 'D' : '.';
310         buf[1] = (flags & MXT_MSGF_PRESS) ? 'P' : '.';
311         buf[2] = (flags & MXT_MSGF_RELEASE) ? 'R' : '.';
312         buf[3] = (flags & MXT_MSGF_MOVE) ? 'M' : '.';
313         buf[4] = (flags & MXT_MSGF_VECTOR) ? 'V' : '.';
314         buf[5] = (flags & MXT_MSGF_AMP) ? 'A' : '.';
315         buf[6] = (flags & MXT_MSGF_SUPPRESS) ? 'S' : '.';
316         buf[7] = (flags & MXT_MSGF_UNGRIP) ? 'U' : '.';
317
318         return buf;
319 }
320
321 static
322 void
323 atmel_mxt_lock(atmel_mxt_softc_t *sc)
324 {
325         lockmgr(&sc->lk, LK_EXCLUSIVE);
326 }
327
328 static
329 void
330 atmel_mxt_unlock(atmel_mxt_softc_t *sc)
331 {
332         lockmgr(&sc->lk, LK_RELEASE);
333 }
334
335 /*
336  * Notify if possible receive data ready.  Must be called
337  * without the lock held to avoid deadlocking in kqueue.
338  */
339 static
340 void
341 atmel_mxt_notify(atmel_mxt_softc_t *sc)
342 {
343         if (sc->data_signal) {
344                 KNOTE(&sc->kqinfo.ki_note, 0);
345                 atmel_mxt_lock(sc);
346                 if (sc->blocked) {
347                         sc->blocked = 0;
348                         wakeup(&sc->blocked);
349                 }
350                 atmel_mxt_unlock(sc);
351         }
352 }
353
354 /*
355  * Initialize the device
356  */
357 static
358 int
359 init_device(atmel_mxt_softc_t *sc, int probe)
360 {
361         int blksize;
362         int totsize;
363         uint32_t crc;
364
365         if (mxt_read_reg(sc, 0, &sc->core.info, sizeof(sc->core.info))) {
366                 device_printf(sc->dev, "init_device read-reg failed\n");
367                 return ENXIO;
368         }
369         sc->core.nobjs = sc->core.info.num_objects;
370         if (!probe) {
371                 device_printf(sc->dev,
372                               "%d configuration objects\n",
373                               sc->core.info.num_objects);
374         }
375         if (sc->core.nobjs < 0 || sc->core.nobjs > 1024) {
376                 device_printf(sc->dev,
377                               "init_device nobjs (%d) out of bounds\n",
378                               sc->core.nobjs);
379                 return ENXIO;
380         }
381         blksize = sizeof(sc->core.info) +
382                   sc->core.nobjs * sizeof(struct mxt_object);
383         totsize = blksize + sizeof(struct mxt_raw_crc);
384
385         sc->core.buf = kmalloc(totsize, M_DEVBUF, M_WAITOK | M_ZERO);
386         if (mxt_read_reg(sc, 0, sc->core.buf, totsize)) {
387                 device_printf(sc->dev,
388                               "init_device cannot read configuration space\n");
389                 goto done;
390         }
391         kprintf("COREBUF %p %d\n", sc->core.buf, blksize);
392         crc = obp_convert_crc((void *)((uint8_t *)sc->core.buf + blksize));
393         if (obp_crc24(sc->core.buf, blksize) != crc) {
394                 device_printf(sc->dev,
395                               "init_device: configuration space "
396                               "crc mismatch %08x/%08x\n",
397                               crc, obp_crc24(sc->core.buf, blksize));
398                 /*goto done;*/
399         }
400         {
401                 int i;
402
403                 kprintf("info:   ");
404                 for (i = 0; i < sizeof(sc->core.info); ++i)
405                         kprintf(" %02x", sc->core.buf[i]);
406                 kprintf("\nconfig: ");
407                 while (i < blksize) {
408                         kprintf(" %02x", sc->core.buf[i]);
409                         ++i;
410                 }
411                 kprintf("\n");
412         }
413         sc->core.objs = (void *)((uint8_t *)sc->core.buf +
414                                  sizeof(sc->core.info));
415         sc->msgprocobj = mxt_findobject(&sc->core, MXT_GEN_MESSAGEPROCESSOR);
416         sc->cmdprocobj = mxt_findobject(&sc->core, MXT_GEN_COMMANDPROCESSOR);
417         if (sc->msgprocobj == NULL) {
418                 device_printf(sc->dev,
419                               "init_device: cannot find msgproc config\n");
420                 goto done;
421         }
422
423 done:
424         if (sc->msgprocobj == NULL) {
425                 if (sc->core.buf) {
426                         kfree(sc->core.buf, M_DEVBUF);
427                         sc->core.buf = NULL;
428                 }
429                 return ENXIO;
430         } else {
431                 if (probe) {
432                         kfree(sc->core.buf, M_DEVBUF);
433                         sc->core.buf = NULL;
434                 }
435                 return 0;
436         }
437 }
438
439 /*
440  * Device infrastructure
441  */
442 #define ATMEL_SOFTC(unit) \
443         ((atmel_mxt_softc_t *)devclass_get_softc(atmel_mxt_devclass, (unit)))
444
445 static void atmel_mxt_identify(driver_t *driver, device_t parent);
446 static int atmel_mxt_probe(device_t);
447 static int atmel_mxt_attach(device_t);
448 static int atmel_mxt_detach(device_t);
449
450 static devclass_t atmel_mxt_devclass;
451
452 static device_method_t atmel_mxt_methods[] = {
453         /* device interface */
454         DEVMETHOD(device_identify,      atmel_mxt_identify),
455         DEVMETHOD(device_probe,         atmel_mxt_probe),
456         DEVMETHOD(device_attach,        atmel_mxt_attach),
457         DEVMETHOD(device_detach,        atmel_mxt_detach),
458
459 #if 0
460         /* smbus interface */
461         DEVMETHOD(smbus_intr,           smbus_generic_intr),
462 #endif
463
464         DEVMETHOD_END
465 };
466
467 static driver_t atmel_mxt_driver = {
468         "atmel_mxt",
469         atmel_mxt_methods,
470         sizeof(atmel_mxt_softc_t),
471 };
472
473 static  d_open_t        atmel_mxtopen;
474 static  d_close_t       atmel_mxtclose;
475 static  d_ioctl_t       atmel_mxtioctl;
476 static  d_read_t        atmel_mxtread;
477 static  d_write_t       atmel_mxtwrite;
478 static  d_kqfilter_t    atmel_mxtkqfilter;
479
480 static struct dev_ops atmel_mxt_ops = {
481         { "atmel_mxt", 0, 0 },
482         .d_open =       atmel_mxtopen,
483         .d_close =      atmel_mxtclose,
484         .d_ioctl =      atmel_mxtioctl,
485         .d_read =       atmel_mxtread,
486         .d_write =      atmel_mxtwrite,
487         .d_kqfilter =   atmel_mxtkqfilter,
488 };
489
490 static void
491 atmel_mxt_identify(driver_t *driver, device_t parent)
492 {
493         if (device_find_child(parent, "atmel_mxt", -1) == NULL)
494                 BUS_ADD_CHILD(parent, parent, 0, "atmel_mxt", -1);
495 }
496
497 static int
498 atmel_mxt_probe(device_t dev)
499 {
500         atmel_mxt_softc_t sc;
501         int error;
502
503         bzero(&sc, sizeof(sc));
504         sc.dev = dev;
505         sc.unit = device_get_unit(dev);
506
507         /*
508          * Only match against specific addresses to avoid blowing up
509          * other I2C devices (?).  At least for now.
510          *
511          * 0x400 (from smbus) - means specific device address probe,
512          *                      rather than generic.
513          *
514          * 0x4A - cypress trackpad on the acer c720.
515          */
516         if ((sc.unit & 0x04FF) != (0x0400 | 0x04A))
517                 return ENXIO;
518         sc.addr = sc.unit & 0x3FF;
519         error = init_device(&sc, 1);
520         if (error)
521                 return ENXIO;
522
523         device_set_desc(dev, "Atmel MXT TouchScreen");
524
525         return (BUS_PROBE_VENDOR);
526 }
527
528 static int
529 atmel_mxt_attach(device_t dev)
530 {
531         atmel_mxt_softc_t *sc;
532
533         sc = (atmel_mxt_softc_t *)device_get_softc(dev);
534         if (!sc)
535                 return ENOMEM;
536
537         bzero(sc, sizeof(*sc));
538
539         lockinit(&sc->lk, "atmel_mxt", 0, 0);
540         sc->reporting_mode = 1;
541
542         sc->dev = dev;
543         sc->unit = device_get_unit(dev);
544         if ((sc->unit & 0x04FF) != (0x0400 | 0x04A))
545                 return ENXIO;
546         sc->addr = sc->unit & 0x3FF;
547         sc->last_active_tick = ticks;
548         sc->last_calibrate_tick = ticks - atmel_mxt_autocalibrate * hz;
549
550         if (init_device(sc, 0))
551                 return ENXIO;
552
553         if (sc->unit & 0x0400) {
554                 sc->devnode = make_dev(&atmel_mxt_ops, sc->unit,
555                                 UID_ROOT, GID_WHEEL, 0600,
556                                 "atmel%d-%02x",
557                                 sc->unit >> 11, sc->unit & 1023);
558         } else {
559                 sc->devnode = make_dev(&atmel_mxt_ops, sc->unit,
560                                 UID_ROOT, GID_WHEEL, 0600, "atmel%d", sc->unit);
561         }
562         device_printf(dev, "atmel mxt touchscreen driver attached\n");
563         /* device_printf(dev, "...."); */
564
565         /*
566          * Start the polling thread.
567          */
568         lwkt_create(atmel_mxt_poll_thread, sc,
569                     &sc->poll_td, NULL, 0, -1, "atmel_mxt-poll");
570
571         return (0);
572 }
573
574 static int
575 atmel_mxt_detach(device_t dev)
576 {
577         atmel_mxt_softc_t *sc;
578
579         sc = (atmel_mxt_softc_t *)device_get_softc(dev);
580
581         /*
582          * Cleanup our poller thread
583          */
584         atomic_set_int(&sc->poll_flags, ATMEL_POLL_SHUTDOWN);
585         while (sc->poll_td) {
586                 wakeup(&sc->poll_flags);
587                 tsleep(&sc->poll_td, 0, "atmel_mxtdet", hz);
588         }
589
590         if (sc->devnode)
591                 dev_ops_remove_minor(&atmel_mxt_ops, device_get_unit(dev));
592         if (sc->devnode)
593                 devfs_assume_knotes(sc->devnode, &sc->kqinfo);
594         if (sc->core.buf) {
595                 kfree(sc->core.buf, M_DEVBUF);
596                 sc->core.buf = NULL;
597         }
598         sc->msgprocobj = NULL;
599         sc->cmdprocobj = NULL;
600
601         return (0);
602 }
603
604 /*
605  * USER DEVICE I/O FUNCTIONS
606  */
607 static int
608 atmel_mxtopen (struct dev_open_args *ap)
609 {
610         cdev_t dev = ap->a_head.a_dev;
611         atmel_mxt_softc_t *sc = ATMEL_SOFTC(minor(dev));
612
613         if (sc == NULL)
614                 return (ENXIO);
615
616         if (sc->count != 0)
617                 return (EBUSY);
618
619         sc->count++;
620
621         return (0);
622 }
623
624 static int
625 atmel_mxtclose(struct dev_close_args *ap)
626 {
627         cdev_t dev = ap->a_head.a_dev;
628         atmel_mxt_softc_t *sc = ATMEL_SOFTC(minor(dev));
629
630         if (sc == NULL)
631                 return (ENXIO);
632
633         if (sc->count == 0) {
634                 /* This is not supposed to happen. */
635                 return (0);
636         }
637
638         if (sc->count-- == 0) {
639                 sc->reporting_mode = 0;
640         }
641
642         return (0);
643 }
644
645 static int
646 atmel_mxtread(struct dev_read_args *ap)
647 {
648         cdev_t dev = ap->a_head.a_dev;
649         atmel_mxt_softc_t *sc = ATMEL_SOFTC(minor(dev));
650         int error;
651         struct uio *uio = ap->a_uio;
652         int ioflag = ap->a_ioflag;
653         size_t n;
654         elopacket_t pkt;
655         atmel_track_t *track;
656
657         /*
658          * Load next ready event, block if necessary.
659          */
660         atmel_mxt_lock(sc);
661         for (;;) {
662                 error = 0;
663
664                 switch(sc->pend_ack) {
665                 case PEND_ACK_NONE:
666                         if (sc->tracking && sc->track[sc->tracking].report) {
667                                 /*
668                                  * Report ready
669                                  */
670                                 track = &sc->track[sc->tracking];
671                                 bzero(&pkt, sizeof(pkt));
672                                 pkt.cmd = 'T';
673                                 if (track->report & ATMEL_REPORT_PRESS) {
674                                         pkt.byte2 |= 0x01;
675                                         track->report &= ~ATMEL_REPORT_PRESS;
676                                 } else if (track->report & ATMEL_REPORT_MOVE) {
677                                         pkt.byte2 |= 0x02;
678                                         track->report &= ~ATMEL_REPORT_MOVE;
679                                 } else if (track->report &
680                                            ATMEL_REPORT_RELEASE) {
681                                         pkt.byte2 |= 0x04;
682                                         track->report &= ~ATMEL_REPORT_RELEASE;
683                                 }
684                                 pkt.byte3 = track->x & 0xFF;
685                                 pkt.byte4 = track->x >> 8;
686                                 pkt.byte5 = track->y & 0xFF;
687                                 pkt.byte6 = track->y >> 8;
688                                 pkt.byte7 = track->pressure & 0xFF;
689                                 pkt.byte8 = track->pressure >> 8;
690                         } else if (ioflag & IO_NDELAY) {
691                                 /*
692                                  * Non-blocking, nothing ready
693                                  */
694                                 error = EWOULDBLOCK;
695                         } else {
696                                 /*
697                                  * Blocking, nothing ready
698                                  */
699                                 sc->data_signal = 0;
700                                 sc->blocked = 1;
701                                 error = lksleep(&sc->blocked, &sc->lk,
702                                                 PCATCH, "atmelw", 0);
703                                 if (error == 0)
704                                         continue;
705                         }
706                         break;
707                 case PEND_ACK_RESPOND:
708                         pkt = sc->pend_rep;
709                         sc->pend_ack = PEND_ACK_ACK;
710                         break;
711                 case PEND_ACK_ACK:
712                         bzero(&pkt, sizeof(pkt));
713                         pkt.cmd = 'A';
714                         sc->pend_ack = PEND_ACK_NONE;
715                         break;
716                 }
717                 atmel_find_active_state(sc);
718                 break;
719         }
720         atmel_mxt_unlock(sc);
721
722         /*
723          * If no error we can return the event loaded into pkt.
724          */
725         if (error == 0) {
726                 uint8_t csum = 0xAA;
727                 int i;
728
729                 pkt.sync = 'U';
730                 for (i = 0; i < sizeof(pkt) - 1; ++i)
731                         csum += ((uint8_t *)&pkt)[i];
732                 pkt.csum = csum;
733                 n = uio->uio_resid;
734                 if (n > sizeof(pkt))
735                         n = sizeof(pkt);
736                 error = uiomove((void *)&pkt, n, uio);
737         }
738
739         return error;
740 }
741
742 static int
743 atmel_mxtwrite(struct dev_write_args *ap)
744 {
745         cdev_t dev = ap->a_head.a_dev;
746         atmel_mxt_softc_t *sc = ATMEL_SOFTC(minor(dev));
747         struct uio *uio = ap->a_uio;
748         elopacket_t pkt;
749         int error;
750         size_t n;
751
752         error = 0;
753
754         while (uio->uio_resid) {
755                 bzero(&pkt, sizeof(pkt));
756                 n = uio->uio_resid;
757                 if (n > sizeof(pkt))
758                         n = sizeof(pkt);
759                 error = uiomove((void *)&pkt, n, uio);
760                 if (error)
761                         break;
762                 atmel_mxt_lock(sc);
763                 switch(pkt.cmd) {
764                 case 'i':
765                         /*
766                          * ELO_ID request id
767                          */
768                         bzero(&sc->pend_rep, sizeof(sc->pend_rep));
769                         sc->pend_rep.cmd = 'I';
770                         sc->pend_ack = PEND_ACK_RESPOND;
771                         break;
772                 case 'o':
773                         /*
774                          * ELO_OWNER request owner
775                          */
776                         bzero(&sc->pend_rep, sizeof(sc->pend_rep));
777                         sc->pend_rep.cmd = 'O';
778                         sc->pend_ack = PEND_ACK_RESPOND;
779                         break;
780                 case 'm':
781                         /*
782                          * ELO_MODE control packet
783                          */
784                         sc->pend_ack = PEND_ACK_ACK;
785                         break;
786                 case 'r':
787                         /*
788                          * ELO_REPORT control packet
789                          */
790                         sc->pend_ack = PEND_ACK_ACK;
791                         break;
792                 }
793                 atmel_mxt_unlock(sc);
794         }
795         return error;
796 }
797
798 static void atmel_mxt_filt_detach(struct knote *);
799 static int atmel_mxt_filt(struct knote *, long);
800
801 static struct filterops atmel_mxt_filtops =
802         { FILTEROP_ISFD, NULL, atmel_mxt_filt_detach, atmel_mxt_filt };
803
804 static int
805 atmel_mxtkqfilter(struct dev_kqfilter_args *ap)
806 {
807         cdev_t dev = ap->a_head.a_dev;
808         atmel_mxt_softc_t *sc = ATMEL_SOFTC(minor(dev));
809         struct knote *kn = ap->a_kn;
810         struct klist *klist;
811
812         switch(kn->kn_filter) {
813         case EVFILT_READ:
814                 kn->kn_fop = &atmel_mxt_filtops;
815                 kn->kn_hook = (void *)sc;
816                 ap->a_result = 0;
817                 break;
818         default:
819                 ap->a_result = EOPNOTSUPP;
820                 return (0);
821         }
822         klist = &sc->kqinfo.ki_note;
823         knote_insert(klist, kn);
824
825         return (0);
826 }
827
828 static void
829 atmel_mxt_filt_detach(struct knote *kn)
830 {
831         atmel_mxt_softc_t *sc = (atmel_mxt_softc_t *)kn->kn_hook;
832         struct klist *klist;
833
834         klist = &sc->kqinfo.ki_note;
835         knote_remove(klist, kn);
836 }
837
838 static int
839 atmel_mxt_filt(struct knote *kn, long hint)
840 {
841         atmel_mxt_softc_t *sc = (atmel_mxt_softc_t *)kn->kn_hook;
842         int ready;
843
844         atmel_mxt_lock(sc);
845         if (sc->data_signal)
846                 ready = 1;
847         else
848                 ready = 0;
849         atmel_mxt_unlock(sc);
850
851         return (ready);
852 }
853
854 static int
855 atmel_mxtioctl(struct dev_ioctl_args *ap)
856 {
857         cdev_t dev = ap->a_head.a_dev;
858         device_t bus;           /* smbbus */
859         /*struct atmel_mxtcmd *s = (struct atmel_mxtcmd *)ap->a_data;*/
860         void *s = NULL;
861         atmel_mxt_softc_t *sc = ATMEL_SOFTC(minor(dev));
862         int error;
863
864         if (sc == NULL)
865                 return (ENXIO);
866         if (s == NULL)
867                 return (EINVAL);
868
869         /*
870          * NOTE: smbus_*() functions automatically recurse the parent to
871          *       get to the actual device driver.
872          */
873         bus = device_get_parent(sc->dev);       /* smbus */
874
875         /* Allocate the bus. */
876         if ((error = smbus_request_bus(bus, sc->dev,
877                         (ap->a_fflag & O_NONBLOCK) ?
878                         SMB_DONTWAIT : (SMB_WAIT | SMB_INTR))))
879                 return (error);
880
881         switch (ap->a_cmd) {
882         default:
883 #if 0
884                 error = inputev_ioctl(&sc->iev, ap->a_cmd, ap->a_data);
885 #endif
886                 error = ENOTTY;
887                 break;
888         }
889
890         smbus_release_bus(bus, sc->dev);
891
892         return (error);
893 }
894
895 /*
896  * MAJOR SUPPORT FUNCTIONS
897  */
898 static
899 void
900 atmel_mxt_poll_thread(void *arg)
901 {
902         atmel_mxt_softc_t *sc = arg;
903         int error;
904         int freq = atmel_mxt_norm_freq;
905         int isidle = 0;
906
907         while ((sc->poll_flags & ATMEL_POLL_SHUTDOWN) == 0) {
908                 if (sc->msgprocobj)
909                         error = 0;
910                 else
911                         error = ENXIO;
912                 if (error == 0) {
913                         mxt_message_t msg;
914
915                         error = mxt_read_object(sc, sc->msgprocobj,
916                                             &msg, sizeof(msg));
917                         if (error == 0)
918                                 isidle = atmel_mxt_raw_input(sc, &msg);
919                         else
920                                 isidle = 1;
921                 }
922
923                 /*
924                  * don't let the last_active_tick or last_calibrate_tick
925                  * delta calculation overflow.
926                  */
927                 if ((ticks - sc->last_active_tick) > 1000 * hz)
928                         sc->last_active_tick = ticks - 1000 * hz;
929                 if ((ticks - sc->last_calibrate_tick) > 1000 * hz)
930                         sc->last_calibrate_tick = ticks - 1000 * hz;
931
932                 /*
933                  * Automatically calibrate when the touchpad has been
934                  * idle atmel_mxt_autocalibrate seconds, and recalibrate
935                  * on the same interval while it remains idle.
936                  *
937                  * If we don't do this the touchscreen can get really out
938                  * of whack over time and basically stop functioning properly.
939                  * It's unclear why the device does not do this automatically.
940                  *
941                  * Response occurs in the message stream (which we just
942                  * ignore).
943                  */
944                 if (sc->cmdprocobj && atmel_mxt_autocalibrate &&
945                     ((ticks - sc->last_calibrate_tick) >
946                      atmel_mxt_autocalibrate * hz) &&
947                     ((ticks - sc->last_active_tick) >
948                      atmel_mxt_autocalibrate * hz)) {
949                         sc->last_calibrate_tick = ticks;
950                         mxt_write_object_off(sc, sc->cmdprocobj,
951                                          MXT_CMDPROC_CALIBRATE_OFF, 1);
952                 }
953                 tsleep(&sc->poll_flags, 0, "atmpol", (hz + freq - 1) / freq);
954                 ++sc->poll_ticks;
955                 if (sc->count == 0)
956                         freq = atmel_mxt_idle_freq;
957                 else if (isidle)
958                         freq = atmel_mxt_slow_freq;
959                 else
960                         freq = atmel_mxt_norm_freq;
961         }
962         sc->poll_td = NULL;
963         wakeup(&sc->poll_td);
964 }
965
966 /*
967  * Calculate currently active state, if any
968  */
969 static
970 void
971 atmel_find_active_state(atmel_mxt_softc_t *sc)
972 {
973         atmel_track_t *track;
974         int i;
975
976         track = &sc->track[sc->tracking];
977         if (track->report == 0) {
978                 for (i = 0; i < ATMEL_MAXTRACK; ++i) {
979                         track = &sc->track[i];
980                         if (track->report) {
981                                 sc->tracking = i;
982                                 break;
983                         }
984                 }
985         }
986         if (track->report == 0 && sc->pend_ack == PEND_ACK_NONE) {
987                 sc->data_signal = 0;
988         } else {
989                 sc->data_signal = 1;
990         }
991 }
992
993 /*
994  * Return non-zero if we are idle
995  */
996 static
997 int
998 atmel_mxt_raw_input(atmel_mxt_softc_t *sc, mxt_message_t *msg)
999 {
1000         atmel_track_t *track;
1001         int donotify = 0;
1002
1003         if (atmel_mxt_debug) {
1004                 kprintf("track=%02x f=%s x=%-4d y=%-4d p=%d amp=%d\n",
1005                         msg->any.reportid,
1006                         msgflagsstr(msg->touch.flags),
1007                         (msg->touch.pos[0] << 4) |
1008                                 ((msg->touch.pos[2] >> 4) & 0x0F),
1009                         (msg->touch.pos[1] << 4) |
1010                                 ((msg->touch.pos[2]) & 0x0F),
1011                         msg->touch.area,
1012                         msg->touch.amplitude);
1013         }
1014         atmel_mxt_lock(sc);
1015
1016         /*
1017          * If message buffer is empty and no fingers are currently pressed
1018          * return idle, else we are not idle.
1019          */
1020         if (msg->any.reportid == 0xFF)
1021                 goto done;
1022
1023         /*
1024          * Process message buffer.  For now ignore any messages with
1025          * reportids that we do not understand.
1026          *
1027          * note: reportid==1  typicallk acknowledges calibrations (?)
1028          */
1029         if (msg->any.reportid < 3 || msg->any.reportid >= ATMEL_MAXTRACK)
1030                 goto done;
1031
1032         sc->last_active_tick = ticks;
1033
1034         track = &sc->track[msg->any.reportid];
1035         track->x = (msg->touch.pos[0] << 4) |
1036                    ((msg->touch.pos[2] >> 4) & 0x0F);
1037         track->y = (msg->touch.pos[1] << 4) |
1038                    (msg->touch.pos[2] & 0x0F);
1039         track->pressure = msg->touch.amplitude;
1040
1041         track->x = track->x * 3000 / 1361;
1042         track->y = track->y * 3000 / 3064;
1043
1044         if (msg->touch.flags & MXT_MSGF_DETECT) {
1045                 track->status = ATMEL_TRACK_PRESSED;
1046                 if (msg->touch.flags & MXT_MSGF_PRESS) {
1047                         track->report |= ATMEL_REPORT_PRESS;
1048                 }
1049                 if (msg->touch.flags & MXT_MSGF_MOVE) {
1050                         track->report |= ATMEL_REPORT_MOVE;
1051                 }
1052         } else {
1053                 track->status = ATMEL_TRACK_RELEASED;
1054                 track->report |= ATMEL_REPORT_RELEASE;
1055         }
1056         atmel_find_active_state(sc);
1057         donotify = 1;
1058 done:
1059         atmel_mxt_unlock(sc);
1060         if (donotify)
1061                 atmel_mxt_notify(sc);
1062         if (sc->track_fingers)
1063                 return 0;
1064         else
1065                 return 1;
1066 }
1067
1068 /*
1069  * Support functions
1070  */
1071 static
1072 struct mxt_object *
1073 mxt_findobject(struct mxt_rollup *core, int type)
1074 {
1075         int i;
1076
1077         for (i = 0; i < core->nobjs; ++i) {
1078                 if (core->objs[i].type == type)
1079                         return(&core->objs[i]);
1080         }
1081         return NULL;
1082 }
1083
1084 static int
1085 mxt_read_reg(atmel_mxt_softc_t *sc, uint16_t reg, void *rbuf, int bytes)
1086 {
1087         uint8_t wreg[2];
1088         device_t bus;
1089         int error;
1090         int rbytes;
1091
1092         wreg[0] = reg & 255;
1093         wreg[1] = reg >> 8;
1094
1095         bus = device_get_parent(sc->dev);
1096         if ((error = smbus_request_bus(bus, sc->dev, SMB_WAIT | SMB_INTR)) != 0)
1097                 return error;
1098         error = smbus_trans(bus, sc->addr, 0,
1099                             SMB_TRANS_NOCNT |
1100                             SMB_TRANS_NOCMD |
1101                             SMB_TRANS_7BIT,
1102                             wreg, 2,
1103                             rbuf, bytes, &rbytes);
1104         smbus_release_bus(bus, sc->dev);
1105
1106         if (bytes != rbytes) {
1107                 device_printf(sc->dev,
1108                               "smbus_trans reg %d short read %d/%d\n",
1109                               reg, bytes, rbytes);
1110                 error = EINVAL;
1111         }
1112
1113         return error;
1114 }
1115
1116 static int
1117 mxt_write_reg_buf(atmel_mxt_softc_t *sc, uint16_t reg, void *xbuf, int bytes)
1118 {
1119         uint8_t wbuf[256];
1120         device_t bus;
1121         int error;
1122
1123         KKASSERT(bytes < sizeof(wbuf) - 2);
1124         wbuf[0] = reg & 255;
1125         wbuf[1] = reg >> 8;
1126         bcopy(xbuf, wbuf + 2, bytes);
1127
1128         bus = device_get_parent(sc->dev);
1129         if ((error = smbus_request_bus(bus, sc->dev, SMB_WAIT | SMB_INTR)) != 0)
1130                 return error;
1131         error = smbus_trans(bus, sc->addr, 0,
1132                             SMB_TRANS_NOCNT |
1133                             SMB_TRANS_NOCMD |
1134                             SMB_TRANS_7BIT,
1135                             wbuf, bytes + 2,
1136                             NULL, 0, NULL);
1137         smbus_release_bus(bus, sc->dev);
1138         return error;
1139 }
1140
1141 static int
1142 mxt_write_reg(atmel_mxt_softc_t *sc, uint16_t reg, uint8_t val)
1143 {
1144         return mxt_write_reg_buf(sc, reg, &val, 1);
1145 }
1146
1147 static int
1148 mxt_read_object(atmel_mxt_softc_t *sc, struct mxt_object *obj,
1149                 void *rbuf, int rbytes)
1150 {
1151         uint16_t reg = obj->start_pos_lsb + (obj->start_pos_msb << 8);
1152         int bytes = obj->size_minus_one + 1;
1153
1154         if (bytes > rbytes)
1155                 bytes = rbytes;
1156         return mxt_read_reg(sc, reg, rbuf, bytes);
1157 }
1158
1159 static int
1160 mxt_write_object_off(atmel_mxt_softc_t *sc, struct mxt_object *obj,
1161                  int offset, uint8_t val)
1162 {
1163         uint16_t reg = obj->start_pos_lsb + (obj->start_pos_msb << 8);
1164
1165         reg += offset;
1166         return mxt_write_reg(sc, reg, val);
1167 }
1168
1169 DRIVER_MODULE(atmel_mxt, smbus, atmel_mxt_driver, atmel_mxt_devclass,
1170               NULL, NULL);
1171 MODULE_DEPEND(atmel_mxt, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
1172 MODULE_VERSION(atmel_mxt, 1);