1/*
2 *	Linux driver for the PC110 pad
3 */
4
5/**
6 * 	DOC: PC110 Digitizer Hardware
7 *
8 *	The pad provides triples of data. The first byte has
9 *	0x80=bit 8 X, 0x01=bit 7 X, 0x08=bit 8 Y, 0x01=still down
10 *	The second byte is bits 0-6 X
11 *	The third is bits 0-6 Y
12 *
13 *	This is read internally and used to synthesize a stream of
14 *	triples in the form expected from a PS/2 device. Specialist
15 *	applications can choose to obtain the pad data in other formats
16 *	including a debugging mode.
17 *
18 *	It would be good to add a joystick driver mode to this pad so
19 *	that doom and other game playing are better. One possible approach
20 *	would be to deactive the mouse mode while the joystick port is opened.
21 */
22
23/*
24 *	History
25 *
26 *	0.0 1997-05-16 Alan Cox <alan@redhat.com> - Pad reader
27 *	0.1 1997-05-19 Robin O'Leary <robin@acm.org> - PS/2 emulation
28 *	0.2 1997-06-03 Robin O'Leary <robin@acm.org> - tap gesture
29 *	0.3 1997-06-27 Alan Cox <alan@redhat.com> - 2.1 commit
30 *	0.4 1997-11-09 Alan Cox <alan@redhat.com> - Single Unix VFS API changes
31 *	0.5 2000-02-10 Alan Cox <alan@redhat.com> - 2.3.x cleanup, documentation
32 */
33
34#include <linux/module.h>
35#include <linux/kernel.h>
36#include <linux/signal.h>
37#include <linux/errno.h>
38#include <linux/mm.h>
39#include <linux/miscdevice.h>
40#include <linux/ptrace.h>
41#include <linux/poll.h>
42#include <linux/ioport.h>
43#include <linux/interrupt.h>
44#include <linux/smp_lock.h>
45#include <linux/init.h>
46
47#include <asm/signal.h>
48#include <asm/io.h>
49#include <asm/irq.h>
50#include <asm/semaphore.h>
51#include <linux/spinlock.h>
52#include <asm/uaccess.h>
53
54#include "pc110pad.h"
55
56
57static struct pc110pad_params default_params = {
58	mode:			PC110PAD_PS2,
59	bounce_interval:	50 MS,
60	tap_interval:		200 MS,
61	irq:			10,
62	io:			0x15E0,
63};
64
65static struct pc110pad_params current_params;
66
67
68/* driver/filesystem interface management */
69static wait_queue_head_t queue;
70static struct fasync_struct *asyncptr;
71static int active;	/* number of concurrent open()s */
72static struct semaphore reader_lock;
73
74/**
75 *	wake_readers:
76 *
77 *	Take care of letting any waiting processes know that
78 *	now would be a good time to do a read().  Called
79 *	whenever a state transition occurs, real or synthetic. Also
80 *	issue any SIGIO's to programs that use SIGIO on mice (eg
81 *	Executor)
82 */
83
84static void wake_readers(void)
85{
86	wake_up_interruptible(&queue);
87	kill_fasync(&asyncptr, SIGIO, POLL_IN);
88}
89
90
91/*****************************************************************************/
92/*
93 * Deal with the messy business of synthesizing button tap and drag
94 * events.
95 *
96 * Exports:
97 *	notify_pad_up_down()
98 *		Must be called whenever debounced pad up/down state changes.
99 *	button_pending
100 *		Flag is set whenever read_button() has new values
101 *		to return.
102 *	read_button()
103 *		Obtains the current synthetic mouse button state.
104 */
105
106/*
107 * These keep track of up/down transitions needed to generate the
108 * synthetic mouse button events.  While recent_transition is set,
109 * up/down events cause transition_count to increment.  tap_timer
110 * turns off the recent_transition flag and may cause some synthetic
111 * up/down mouse events to be created by incrementing synthesize_tap.
112 */
113
114static int button_pending;
115static int recent_transition;
116static int transition_count;
117static int synthesize_tap;
118static void tap_timeout(unsigned long data);
119static struct timer_list tap_timer = { function: tap_timeout };
120
121
122/**
123 * tap_timeout:
124 * @data: Unused
125 *
126 * This callback goes off a short time after an up/down transition;
127 * before it goes off, transitions will be considered part of a
128 * single PS/2 event and counted in transition_count.  Once the
129 * timeout occurs the recent_transition flag is cleared and
130 * any synthetic mouse up/down events are generated.
131 */
132
133static void tap_timeout(unsigned long data)
134{
135	if(!recent_transition)
136	{
137		printk(KERN_ERR "pc110pad: tap_timeout but no recent transition!\n");
138	}
139	if( transition_count==2 || transition_count==4 || transition_count==6 )
140	{
141		synthesize_tap+=transition_count;
142		button_pending = 1;
143		wake_readers();
144	}
145	recent_transition=0;
146}
147
148
149/**
150 * notify_pad_up_down:
151 *
152 * Called by the raw pad read routines when a (debounced) up/down
153 * transition is detected.
154 */
155
156void notify_pad_up_down(void)
157{
158	if(recent_transition)
159	{
160		transition_count++;
161	}
162	else
163	{
164		transition_count=1;
165		recent_transition=1;
166	}
167	mod_timer(&tap_timer, jiffies + current_params.tap_interval);
168
169	/* changes to transition_count can cause reported button to change */
170	button_pending = 1;
171	wake_readers();
172}
173
174/**
175 *	read_button:
176 *	@b: pointer to the button status.
177 *
178 *	The actual button state depends on what we are seeing. We have to check
179 *	for the tap gesture and also for dragging.
180 */
181
182static void read_button(int *b)
183{
184	if(synthesize_tap)
185	{
186		*b=--synthesize_tap & 1;
187	}
188	else
189	{
190		*b=(!recent_transition && transition_count==3);	/* drag */
191	}
192	button_pending=(synthesize_tap>0);
193}
194
195
196/*****************************************************************************/
197/*
198 * Read pad absolute co-ordinates and debounced up/down state.
199 *
200 * Exports:
201 *	pad_irq()
202 *		Function to be called whenever the pad signals
203 *		that it has new data available.
204 *	read_raw_pad()
205 *		Returns the most current pad state.
206 *	xy_pending
207 *		Flag is set whenever read_raw_pad() has new values
208 *		to return.
209 * Imports:
210 *	wake_readers()
211 *		Called when movement occurs.
212 *	notify_pad_up_down()
213 *		Called when debounced up/down status changes.
214 */
215
216/*
217 * These are up/down state and absolute co-ords read directly from pad
218 */
219
220static int raw_data[3];
221static int raw_data_count;
222static int raw_x, raw_y;	/* most recent absolute co-ords read */
223static int raw_down;		/* raw up/down state */
224static int debounced_down;	/* up/down state after debounce processing */
225static enum { NO_BOUNCE, JUST_GONE_UP, JUST_GONE_DOWN } bounce=NO_BOUNCE;
226				/* set just after an up/down transition */
227static int xy_pending;	/* set if new data have not yet been read */
228
229/*
230 * Timer goes off a short while after an up/down transition and copies
231 * the value of raw_down to debounced_down.
232 */
233
234static void bounce_timeout(unsigned long data);
235static struct timer_list bounce_timer = { function: bounce_timeout };
236
237
238
239/**
240 * bounce_timeout:
241 * @data: Unused
242 *
243 * No further up/down transitions happened within the
244 * bounce period, so treat this as a genuine transition.
245 */
246
247static void bounce_timeout(unsigned long data)
248{
249	switch(bounce)
250	{
251		case NO_BOUNCE:
252		{
253			/*
254			 * Strange; the timer callback should only go off if
255			 * we were expecting to do bounce processing!
256			 */
257			printk(KERN_WARNING "pc110pad, bounce_timeout: bounce flag not set!\n");
258			break;
259		}
260		case JUST_GONE_UP:
261		{
262			/*
263			 * The last up we spotted really was an up, so set
264			 * debounced state the same as raw state.
265			 */
266			bounce=NO_BOUNCE;
267			if(debounced_down==raw_down)
268			{
269				printk(KERN_WARNING "pc110pad, bounce_timeout: raw already debounced!\n");
270			}
271			debounced_down=raw_down;
272
273			notify_pad_up_down();
274			break;
275		}
276		case JUST_GONE_DOWN:
277		{
278			/*
279			 * We don't debounce down events, but we still time
280			 * out soon after one occurs so we can avoid the (x,y)
281			 * skittering that sometimes happens.
282			 */
283			bounce=NO_BOUNCE;
284			break;
285		}
286	}
287}
288
289
290/**
291 * pad_irq:
292 * @irq: Interrupt number
293 * @ptr: Unused
294 * @regs: Unused
295 *
296 * Callback when pad's irq goes off; copies values in to raw_* globals;
297 * initiates debounce processing. This isn't SMP safe however there are
298 * no SMP machines with a PC110 touchpad on them.
299 */
300
301static void pad_irq(int irq, void *ptr, struct pt_regs *regs)
302{
303
304	/* Obtain byte from pad and prime for next byte */
305	{
306		int value=inb_p(current_params.io);
307		int handshake=inb_p(current_params.io+2);
308		outb_p(handshake | 1, current_params.io+2);
309		outb_p(handshake &~1, current_params.io+2);
310		inb_p(0x64);
311
312		raw_data[raw_data_count++]=value;
313	}
314
315	if(raw_data_count==3)
316	{
317		int new_down=raw_data[0]&0x01;
318		int new_x=raw_data[1];
319		int new_y=raw_data[2];
320		if(raw_data[0]&0x10) new_x+=128;
321		if(raw_data[0]&0x80) new_x+=256;
322		if(raw_data[0]&0x08) new_y+=128;
323
324		if( (raw_x!=new_x) || (raw_y!=new_y) )
325		{
326			raw_x=new_x;
327			raw_y=new_y;
328			xy_pending=1;
329		}
330
331		if(new_down != raw_down)
332		{
333			/* Down state has changed.  raw_down always holds
334			 * the most recently observed state.
335			 */
336			raw_down=new_down;
337
338			/* Forget any earlier bounce processing */
339			if(bounce)
340			{
341				del_timer(&bounce_timer);
342				bounce=NO_BOUNCE;
343			}
344
345			if(new_down)
346			{
347				if(debounced_down)
348				{
349					/* pad gone down, but we were reporting
350					 * it down anyway because we suspected
351					 * (correctly) that the last up was just
352					 * a bounce
353					 */
354				}
355				else
356				{
357					bounce=JUST_GONE_DOWN;
358					mod_timer(&bounce_timer,
359						jiffies+current_params.bounce_interval);
360					/* start new stroke/tap */
361					debounced_down=new_down;
362					notify_pad_up_down();
363				}
364			}
365			else /* just gone up */
366			{
367				if(recent_transition)
368				{
369					/* early bounces are probably part of
370					 * a multi-tap gesture, so process
371					 * immediately
372					 */
373					debounced_down=new_down;
374					notify_pad_up_down();
375				}
376				else
377				{
378					/* don't trust it yet */
379					bounce=JUST_GONE_UP;
380					mod_timer(&bounce_timer,
381						jiffies+current_params.bounce_interval);
382				}
383			}
384		}
385		wake_readers();
386		raw_data_count=0;
387	}
388}
389
390
391static void read_raw_pad(int *down, int *debounced, int *x, int *y)
392{
393	disable_irq(current_params.irq);
394	{
395		*down=raw_down;
396		*debounced=debounced_down;
397		*x=raw_x;
398		*y=raw_y;
399		xy_pending = 0;
400	}
401	enable_irq(current_params.irq);
402}
403
404/*****************************************************************************/
405/*
406 * Filesystem interface
407 */
408
409/*
410 * Read returns byte triples, so we need to keep track of
411 * how much of a triple has been read.  This is shared across
412 * all processes which have this device open---not that anything
413 * will make much sense in that case.
414 */
415static int read_bytes[3];
416static int read_byte_count;
417
418/**
419 *	sample_raw:
420 *	@d: sample buffer
421 *
422 *	Retrieve a triple of sample data.
423 */
424
425
426static void sample_raw(int d[3])
427{
428	d[0]=raw_data[0];
429	d[1]=raw_data[1];
430	d[2]=raw_data[2];
431}
432
433/**
434 *	sample_rare:
435 *	@d: sample buffer
436 *
437 *	Retrieve a triple of sample data and sanitize it. We do the needed
438 *	scaling and masking to get the current status.
439 */
440
441
442static void sample_rare(int d[3])
443{
444	int thisd, thisdd, thisx, thisy;
445
446	read_raw_pad(&thisd, &thisdd, &thisx, &thisy);
447
448	d[0]=(thisd?0x80:0)
449	   | (thisx/256)<<4
450	   | (thisdd?0x08:0)
451	   | (thisy/256)
452	;
453	d[1]=thisx%256;
454	d[2]=thisy%256;
455}
456
457/**
458 *	sample_debug:
459 *	@d: sample buffer
460 *
461 *	Retrieve a triple of sample data and mix it up with the state
462 *	information in the gesture parser. Not useful for normal users but
463 *	handy when debugging
464 */
465
466static void sample_debug(int d[3])
467{
468	int thisd, thisdd, thisx, thisy;
469	int b;
470	unsigned long flags;
471
472	save_flags(flags);
473	cli();
474	read_raw_pad(&thisd, &thisdd, &thisx, &thisy);
475	d[0]=(thisd?0x80:0) | (thisdd?0x40:0) | bounce;
476	d[1]=(recent_transition?0x80:0)+transition_count;
477	read_button(&b);
478	d[2]=(synthesize_tap<<4) | (b?0x01:0);
479	restore_flags(flags);
480}
481
482/**
483 *	sample_ps2:
484 *	@d: sample buffer
485 *
486 *	Retrieve a triple of sample data and turn the debounced tap and
487 *	stroke information into what appears to be a PS/2 mouse. This means
488 *	the PC110 pad needs no funny application side support.
489 */
490
491
492static void sample_ps2(int d[3])
493{
494	static int lastx, lasty, lastd;
495
496	int thisd, thisdd, thisx, thisy;
497	int dx, dy, b;
498
499	/*
500	 * Obtain the current mouse parameters and limit as appropriate for
501	 * the return data format.  Interrupts are only disabled while
502	 * obtaining the parameters, NOT during the puts_fs_byte() calls,
503	 * so paging in put_user() does not affect mouse tracking.
504	 */
505	read_raw_pad(&thisd, &thisdd, &thisx, &thisy);
506	read_button(&b);
507
508	/* Now compare with previous readings.  Note that we use the
509	 * raw down flag rather than the debounced one.
510	 */
511	if( (thisd && !lastd) /* new stroke */
512	 || (bounce!=NO_BOUNCE) )
513	{
514		dx=0;
515		dy=0;
516	}
517	else
518	{
519		dx =  (thisx-lastx);
520		dy = -(thisy-lasty);
521	}
522	lastx=thisx;
523	lasty=thisy;
524	lastd=thisd;
525
526/*
527	d[0]= ((dy<0)?0x20:0)
528	    | ((dx<0)?0x10:0)
529	    | 0x08
530	    | (b? 0x01:0x00)
531	;
532*/
533	d[0]= ((dy<0)?0x20:0)
534	    | ((dx<0)?0x10:0)
535	    | (b? 0x00:0x08)
536	;
537	d[1]=dx;
538	d[2]=dy;
539}
540
541
542/**
543 *	fasync_pad:
544 *	@fd:	file number for the file
545 *	@filp:	file handle
546 *	@on:	1 to add, 0 to remove a notifier
547 *
548 *	Update the queue of asynchronous event notifiers. We can use the
549 *	same helper the mice do and that does almost everything we need.
550 */
551
552static int fasync_pad(int fd, struct file *filp, int on)
553{
554	int retval;
555
556	retval = fasync_helper(fd, filp, on, &asyncptr);
557	if (retval < 0)
558		return retval;
559	return 0;
560}
561
562
563/**
564 *	close_pad:
565 *	@inode: inode of pad
566 *	@file: file handle to pad
567 *
568 *	Close access to the pad. We turn the pad power off if this is the
569 *	last user of the pad. I've not actually measured the power draw but
570 *	the DOS driver is careful to do this so we follow suit.
571 */
572
573static int close_pad(struct inode * inode, struct file * file)
574{
575	lock_kernel();
576	fasync_pad(-1, file, 0);
577	if (!--active)
578		outb(0x30, current_params.io+2);  /* switch off digitiser */
579	unlock_kernel();
580	return 0;
581}
582
583
584/**
585 *	open_pad:
586 *	@inode: inode of pad
587 *	@file: file handle to pad
588 *
589 *	Open access to the pad. We turn the pad off first (we turned it off
590 *	on close but if this is the first open after a crash the state is
591 *	indeterminate). The device has a small fifo so we empty that before
592 *	we kick it back into action.
593 */
594
595static int open_pad(struct inode * inode, struct file * file)
596{
597	unsigned long flags;
598
599	if (active++)
600		return 0;
601
602	save_flags(flags);
603	cli();
604	outb(0x30, current_params.io+2);	/* switch off digitiser */
605	pad_irq(0,0,0);		/* read to flush any pending bytes */
606	pad_irq(0,0,0);		/* read to flush any pending bytes */
607	pad_irq(0,0,0);		/* read to flush any pending bytes */
608	outb(0x38, current_params.io+2);	/* switch on digitiser */
609	current_params = default_params;
610	raw_data_count=0;		/* re-sync input byte counter */
611	read_byte_count=0;		/* re-sync output byte counter */
612	button_pending=0;
613	recent_transition=0;
614	transition_count=0;
615	synthesize_tap=0;
616	del_timer(&bounce_timer);
617	del_timer(&tap_timer);
618	restore_flags(flags);
619
620	return 0;
621}
622
623
624/**
625 *	write_pad:
626 *	@file: File handle to the pad
627 *	@buffer: Unused
628 *	@count: Unused
629 *	@ppos: Unused
630 *
631 *	Writes are disallowed. A true PS/2 mouse lets you write stuff. Everyone
632 *	seems happy with this and not faking the write modes.
633 */
634
635static ssize_t write_pad(struct file * file, const char * buffer, size_t count, loff_t *ppos)
636{
637	return -EINVAL;
638}
639
640
641/*
642 *	new_sample:
643 *	@d: sample buffer
644 *
645 *	Fetch a new sample according the current mouse mode the pad is
646 *	using.
647 */
648
649void new_sample(int d[3])
650{
651	switch(current_params.mode)
652	{
653		case PC110PAD_RAW:	sample_raw(d);		break;
654		case PC110PAD_RARE:	sample_rare(d);		break;
655		case PC110PAD_DEBUG:	sample_debug(d);	break;
656		case PC110PAD_PS2:	sample_ps2(d);		break;
657	}
658}
659
660
661/**
662 * read_pad:
663 * @file: File handle to pad
664 * @buffer: Target for the mouse data
665 * @count: Buffer length
666 * @ppos: Offset (unused)
667 *
668 * Read data from the pad. We use the reader_lock to avoid mess when there are
669 * two readers. This shouldnt be happening anyway but we play safe.
670 */
671
672static ssize_t read_pad(struct file * file, char * buffer, size_t count, loff_t *ppos)
673{
674	int r;
675
676	down(&reader_lock);
677	for(r=0; r<count; r++)
678	{
679		if(!read_byte_count)
680			new_sample(read_bytes);
681		if(put_user(read_bytes[read_byte_count], buffer+r))
682		{
683			r = -EFAULT;
684			break;
685		}
686		read_byte_count = (read_byte_count+1)%3;
687	}
688	up(&reader_lock);
689	return r;
690}
691
692
693/**
694 * pad_poll:
695 * @file: File of the pad device
696 * @wait: Poll table
697 *
698 * The pad is ready to read if there is a button or any position change
699 * pending in the queue. The reading and interrupt routines maintain the
700 * required state for us and do needed wakeups.
701 */
702
703static unsigned int pad_poll(struct file *file, poll_table * wait)
704{
705	poll_wait(file, &queue, wait);
706    	if(button_pending || xy_pending)
707		return POLLIN | POLLRDNORM;
708	return 0;
709}
710
711
712/**
713 *	pad_ioctl;
714 *	@inode: Inode of the pad
715 *	@file: File handle to the pad
716 *	@cmd: Ioctl command
717 *	@arg: Argument pointer
718 *
719 *	The PC110 pad supports two ioctls both of which use the pc110pad_params
720 *	structure. GETP queries the current pad status. SETP changes the pad
721 *	configuration. Changing configuration during normal mouse operations
722 *	may give momentarily odd results as things like tap gesture state
723 *	may be lost.
724 */
725
726static int pad_ioctl(struct inode *inode, struct file * file,
727	unsigned int cmd, unsigned long arg)
728{
729	struct pc110pad_params new;
730
731	if (!inode)
732		return -EINVAL;
733
734	switch (cmd) {
735	case PC110PADIOCGETP:
736		new = current_params;
737		if(copy_to_user((void *)arg, &new, sizeof(new)))
738			return -EFAULT;
739		return 0;
740
741	case PC110PADIOCSETP:
742		if(copy_from_user(&new, (void *)arg, sizeof(new)))
743			return -EFAULT;
744
745		if( (new.mode<PC110PAD_RAW)
746		 || (new.mode>PC110PAD_PS2)
747		 || (new.bounce_interval<0)
748		 || (new.tap_interval<0)
749		)
750			return -EINVAL;
751
752		current_params.mode	= new.mode;
753		current_params.bounce_interval	= new.bounce_interval;
754		current_params.tap_interval	= new.tap_interval;
755		return 0;
756	}
757	return -ENOTTY;
758}
759
760
761static struct file_operations pad_fops = {
762	owner:		THIS_MODULE,
763	read:		read_pad,
764	write:		write_pad,
765	poll:		pad_poll,
766	ioctl:		pad_ioctl,
767	open:		open_pad,
768	release:	close_pad,
769	fasync:		fasync_pad,
770};
771
772
773static struct miscdevice pc110_pad = {
774	minor:		PC110PAD_MINOR,
775	name:		"pc110 pad",
776	fops:		&pad_fops,
777};
778
779
780/**
781 *	pc110pad_init_driver:
782 *
783 *	We configure the pad with the default parameters (that is PS/2
784 *	emulation mode. We then claim the needed I/O and interrupt resources.
785 *	Finally as a matter of paranoia we turn the pad off until we are
786 *	asked to open it by an application.
787 */
788
789static char banner[] __initdata = KERN_INFO "PC110 digitizer pad at 0x%X, irq %d.\n";
790
791static int __init pc110pad_init_driver(void)
792{
793	init_MUTEX(&reader_lock);
794	current_params = default_params;
795
796	if (request_irq(current_params.irq, pad_irq, 0, "pc110pad", 0)) {
797		printk(KERN_ERR "pc110pad: Unable to get IRQ.\n");
798		return -EBUSY;
799	}
800	if (!request_region(current_params.io, 4, "pc110pad"))	{
801		printk(KERN_ERR "pc110pad: I/O area in use.\n");
802		free_irq(current_params.irq,0);
803		return -EBUSY;
804	}
805	init_waitqueue_head(&queue);
806	printk(banner, current_params.io, current_params.irq);
807	misc_register(&pc110_pad);
808	outb(0x30, current_params.io+2);	/* switch off digitiser */
809	return 0;
810}
811
812/*
813 *	pc110pad_exit_driver:
814 *
815 *	Free the resources we acquired when the module was loaded. We also
816 *	turn the pad off to be sure we don't leave it using power.
817 */
818
819static void __exit pc110pad_exit_driver(void)
820{
821	outb(0x30, current_params.io+2);	/* switch off digitiser */
822	if (current_params.irq)
823		free_irq(current_params.irq, 0);
824	current_params.irq = 0;
825	release_region(current_params.io, 4);
826	misc_deregister(&pc110_pad);
827}
828
829module_init(pc110pad_init_driver);
830module_exit(pc110pad_exit_driver);
831
832MODULE_AUTHOR("Alan Cox, Robin O'Leary");
833MODULE_DESCRIPTION("Driver for the touchpad on the IBM PC110 palmtop");
834MODULE_LICENSE("GPL");
835
836EXPORT_NO_SYMBOLS;
837